aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--.gitignore251
-rw-r--r--.mailmap3
l---------INSTALL-CROSS.md1
-rw-r--r--INSTALL-WIN32.md781
-rw-r--r--INSTALL.md738
-rw-r--r--Makefile.in397
-rw-r--r--README472
-rw-r--r--README.md76
-rw-r--r--README.win32749
-rw-r--r--TAR.include9
l---------aclocal.m41
-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 -> 31480 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 -> 31800 bytes
-rw-r--r--bootstrap/lib/compiler/ebin/compiler.app12
-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 -> 7608 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 -> 14052 bytes
-rw-r--r--bootstrap/lib/compiler/ebin/v3_codegen.beambin48336 -> 48016 bytes
-rw-r--r--bootstrap/lib/compiler/ebin/v3_core.beambin45812 -> 45504 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.erl12
-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 -> 5744 bytes
-rw-r--r--bootstrap/lib/kernel/ebin/code_server.beambin22412 -> 23856 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 -> 3144 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 -> 11428 bytes
-rw-r--r--bootstrap/lib/kernel/ebin/inet.beambin18208 -> 18228 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 -> 24836 bytes
-rw-r--r--bootstrap/lib/kernel/ebin/inet_dns.beambin18988 -> 18484 bytes
-rw-r--r--bootstrap/lib/kernel/ebin/inet_gethost_native.beambin9748 -> 9748 bytes
-rw-r--r--bootstrap/lib/kernel/ebin/inet_hosts.beambin2236 -> 2016 bytes
-rw-r--r--bootstrap/lib/kernel/ebin/inet_parse.beambin11284 -> 11980 bytes
-rw-r--r--bootstrap/lib/kernel/ebin/inet_res.beambin14616 -> 14260 bytes
-rw-r--r--bootstrap/lib/kernel/ebin/inet_sctp.beambin1904 -> 1728 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.app12
-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 -> 6948 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 -> 11356 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/kernel/include/file.hrl10
-rw-r--r--bootstrap/lib/kernel/include/inet.hrl10
-rw-r--r--bootstrap/lib/kernel/include/inet_sctp.hrl10
-rw-r--r--bootstrap/lib/orber/include/Makefile10
-rw-r--r--bootstrap/lib/orber/include/corba.hrl10
-rw-r--r--bootstrap/lib/orber/include/ifr_types.hrl10
-rw-r--r--bootstrap/lib/orber/include/orber_pi.hrl10
-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 -> 25388 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 -> 7296 bytes
-rw-r--r--bootstrap/lib/stdlib/ebin/edlin_expand.beambin2916 -> 2816 bytes
-rw-r--r--bootstrap/lib/stdlib/ebin/epp.beambin20988 -> 21644 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 -> 73276 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 -> 12092 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 -> 28356 bytes
-rw-r--r--bootstrap/lib/stdlib/ebin/filelib.beambin6592 -> 6376 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 -> 7192 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 -> 64404 bytes
-rw-r--r--bootstrap/lib/stdlib/ebin/qlc_pt.beambin66412 -> 66008 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 -> 11312 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 -> 28144 bytes
-rw-r--r--bootstrap/lib/stdlib/ebin/shell_default.beambin3800 -> 3552 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.app12
-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 -> 15184 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.erl12
-rw-r--r--bootstrap/lib/stdlib/include/erl_bits.hrl10
-rw-r--r--bootstrap/lib/stdlib/include/erl_compile.hrl10
-rw-r--r--bootstrap/lib/stdlib/include/ms_transform.hrl10
-rw-r--r--bootstrap/lib/stdlib/include/qlc.hrl10
-rw-r--r--bootstrap/lib/stdlib/include/zip.hrl10
-rw-r--r--configure.in119
-rw-r--r--erl-build-tool-vars.sh28
-rw-r--r--erts/.gitignore22
-rw-r--r--erts/aclocal.m4532
-rw-r--r--erts/autoconf/vxworks/sed.vxworks_cpu3215
-rw-r--r--erts/autoconf/vxworks/sed.vxworks_ppc3216
-rw-r--r--erts/autoconf/vxworks/sed.vxworks_ppc60315
-rw-r--r--erts/autoconf/vxworks/sed.vxworks_ppc603_nolongcall15
-rw-r--r--erts/autoconf/vxworks/sed.vxworks_ppc86015
-rw-r--r--erts/autoconf/vxworks/sed.vxworks_simlinux14
-rw-r--r--erts/autoconf/vxworks/sed.vxworks_simso14
-rwxr-xr-xerts/autoconf/win32.config.cache4
-rw-r--r--erts/configure.in891
-rw-r--r--erts/doc/src/alt_dist.xml22
-rw-r--r--erts/doc/src/crash_dump.xml8
-rw-r--r--erts/doc/src/driver.xml142
-rw-r--r--erts/doc/src/driver_entry.xml8
-rw-r--r--erts/doc/src/erl.xml63
-rw-r--r--erts/doc/src/erl_dist_protocol.xml12
-rw-r--r--erts/doc/src/erl_driver.xml24
-rw-r--r--erts/doc/src/erl_nif.xml767
-rw-r--r--erts/doc/src/erlang.xml353
-rw-r--r--erts/doc/src/erlc.xml10
-rw-r--r--erts/doc/src/erlsrv.xml22
-rw-r--r--erts/doc/src/erts_alloc.xml164
-rw-r--r--erts/doc/src/escript.xml20
-rw-r--r--erts/doc/src/inet_cfg.xml13
-rw-r--r--erts/doc/src/match_spec.xml40
-rw-r--r--erts/doc/src/notes.xml522
-rw-r--r--erts/doc/src/tty.xml8
-rw-r--r--erts/doc/src/zlib.xml24
-rw-r--r--erts/emulator/Makefile.in37
-rw-r--r--erts/emulator/beam/atom.c12
-rw-r--r--erts/emulator/beam/atom.h21
-rw-r--r--erts/emulator/beam/atom.names12
-rw-r--r--erts/emulator/beam/beam_bif_load.c31
-rw-r--r--erts/emulator/beam/beam_emu.c133
-rw-r--r--erts/emulator/beam/beam_load.c1
-rw-r--r--erts/emulator/beam/bif.c81
-rw-r--r--erts/emulator/beam/bif.tab15
-rw-r--r--erts/emulator/beam/binary.c18
-rw-r--r--erts/emulator/beam/break.c2
-rw-r--r--erts/emulator/beam/erl_arith.c43
-rw-r--r--erts/emulator/beam/erl_bif_guard.c14
-rw-r--r--erts/emulator/beam/erl_bif_info.c183
-rw-r--r--erts/emulator/beam/erl_bif_re.c15
-rw-r--r--erts/emulator/beam/erl_binary.h45
-rw-r--r--erts/emulator/beam/erl_db.c23
-rw-r--r--erts/emulator/beam/erl_db_hash.c16
-rw-r--r--erts/emulator/beam/erl_db_tree.c14
-rw-r--r--erts/emulator/beam/erl_debug.c14
-rw-r--r--erts/emulator/beam/erl_driver.h33
-rw-r--r--erts/emulator/beam/erl_drv_nif.h48
-rw-r--r--erts/emulator/beam/erl_gc.c252
-rw-r--r--erts/emulator/beam/erl_init.c155
-rw-r--r--erts/emulator/beam/erl_lock_check.c13
-rw-r--r--erts/emulator/beam/erl_lock_count.c68
-rw-r--r--erts/emulator/beam/erl_lock_count.h25
-rw-r--r--erts/emulator/beam/erl_message.c24
-rw-r--r--erts/emulator/beam/erl_message.h23
-rw-r--r--erts/emulator/beam/erl_nif.c901
-rw-r--r--erts/emulator/beam/erl_nif.h58
-rw-r--r--erts/emulator/beam/erl_nif_api_funcs.h173
-rw-r--r--erts/emulator/beam/erl_port_task.c70
-rw-r--r--erts/emulator/beam/erl_process.c109
-rw-r--r--erts/emulator/beam/erl_process.h43
-rw-r--r--erts/emulator/beam/erl_term.h108
-rw-r--r--erts/emulator/beam/erl_time_sup.c14
-rw-r--r--erts/emulator/beam/erl_trace.c29
-rw-r--r--erts/emulator/beam/erl_vm.h80
-rw-r--r--erts/emulator/beam/external.c284
-rw-r--r--erts/emulator/beam/external.h26
-rw-r--r--erts/emulator/beam/global.h102
-rw-r--r--erts/emulator/beam/io.c58
-rw-r--r--erts/emulator/beam/module.c18
-rw-r--r--erts/emulator/beam/module.h19
-rw-r--r--erts/emulator/beam/register.c19
-rw-r--r--erts/emulator/beam/sys.h5
-rw-r--r--erts/emulator/beam/utils.c88
-rw-r--r--erts/emulator/drivers/common/inet_drv.c15
-rw-r--r--erts/emulator/drivers/common/ram_file_drv.c14
-rw-r--r--erts/emulator/drivers/unix/ttsl_drv.c17
-rw-r--r--erts/emulator/hipe/hipe_amd64_asm.m433
-rw-r--r--erts/emulator/hipe/hipe_amd64_bifs.m4226
-rw-r--r--erts/emulator/hipe/hipe_amd64_glue.S116
-rw-r--r--erts/emulator/hipe/hipe_bif0.c125
-rw-r--r--erts/emulator/pcre/pcre_compile.c21
-rw-r--r--erts/emulator/sys/common/erl_mseg.c30
-rw-r--r--erts/emulator/sys/common/erl_poll.c17
-rw-r--r--erts/emulator/sys/unix/sys.c17
-rw-r--r--erts/emulator/sys/unix/sys_float.c13
-rw-r--r--erts/emulator/test/binary_SUITE.erl46
-rw-r--r--erts/emulator/test/driver_SUITE_data/ioq_exit_drv.c46
-rw-r--r--erts/emulator/test/fun_SUITE.erl18
-rw-r--r--erts/emulator/test/nif_SUITE.erl665
-rw-r--r--erts/emulator/test/nif_SUITE_data/Makefile.src13
-rw-r--r--erts/emulator/test/nif_SUITE_data/head.txt5
-rw-r--r--erts/emulator/test/nif_SUITE_data/nif_SUITE.c533
-rw-r--r--erts/emulator/test/nif_SUITE_data/nif_mod.c205
-rw-r--r--erts/emulator/test/nif_SUITE_data/nif_mod.erl10
-rw-r--r--erts/emulator/test/nif_SUITE_data/nif_mod.h5
-rw-r--r--erts/emulator/test/nif_SUITE_data/tail.txt5
-rw-r--r--erts/emulator/test/nif_SUITE_data/testcase_driver.h59
-rw-r--r--erts/emulator/test/nif_SUITE_data/tester.c73
-rw-r--r--erts/emulator/test/nif_SUITE_data/tester.erl13
-rw-r--r--erts/emulator/test/port_SUITE.erl20
-rw-r--r--erts/emulator/test/process_SUITE.erl54
-rw-r--r--erts/emulator/test/scheduler_SUITE.erl110
-rw-r--r--erts/emulator/test/statistics_SUITE.erl75
-rw-r--r--erts/emulator/test/system_info_SUITE.erl27
-rw-r--r--erts/emulator/test/trace_SUITE.erl77
-rw-r--r--erts/emulator/test/trace_nif_SUITE_data/trace_nif.c6
-rwxr-xr-xerts/emulator/utils/beam_makeops4
-rw-r--r--erts/emulator/zlib/Makefile.in26
-rw-r--r--erts/epmd/src/epmd_int.h11
-rw-r--r--erts/epmd/src/epmd_srv.c28
-rw-r--r--erts/epmd/test/Makefile24
-rw-r--r--erts/epmd/test/epmd_SUITE.erl160
-rw-r--r--erts/etc/common/Makefile.in20
-rw-r--r--erts/etc/common/dialyzer.c9
-rw-r--r--erts/etc/common/erlc.c13
-rw-r--r--erts/etc/common/erlexec.c36
-rw-r--r--erts/etc/common/escript.c36
-rw-r--r--erts/etc/common/heart.c38
-rw-r--r--erts/etc/unix/Install.src59
-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/example/matrix_nif.c210
-rw-r--r--erts/example/matrix_nif.erl44
-rw-r--r--erts/include/internal/tile/atomic.h14
-rw-r--r--erts/lib_src/Makefile.in12
-rw-r--r--erts/preloaded/ebin/erl_prim_loader.beambin48420 -> 50808 bytes
-rw-r--r--erts/preloaded/ebin/erlang.beambin23232 -> 23800 bytes
-rw-r--r--erts/preloaded/ebin/init.beambin44460 -> 44488 bytes
-rw-r--r--erts/preloaded/ebin/otp_ring0.beambin1392 -> 1436 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 -> 21756 bytes
-rw-r--r--erts/preloaded/ebin/zlib.beambin10624 -> 10612 bytes
-rw-r--r--erts/preloaded/src/erl_prim_loader.erl269
-rw-r--r--erts/preloaded/src/erlang.erl62
-rw-r--r--erts/preloaded/src/init.erl19
-rw-r--r--erts/preloaded/src/otp_ring0.erl11
-rw-r--r--erts/preloaded/src/prim_zip.erl57
-rw-r--r--erts/preloaded/src/zlib.erl11
-rw-r--r--erts/start_scripts/Makefile14
-rw-r--r--erts/test/Makefile21
-rw-r--r--erts/test/erl_print_SUITE.erl12
-rw-r--r--erts/test/erlc_SUITE.erl21
-rw-r--r--erts/test/erlexec_SUITE.erl12
-rw-r--r--erts/test/ethread_SUITE.erl12
-rw-r--r--erts/test/ignore_cores.erl12
-rw-r--r--erts/test/install_SUITE.erl727
-rwxr-xr-xerts/test/install_SUITE_data/dirname2
-rw-r--r--erts/test/nt_SUITE.erl13
-rw-r--r--erts/test/otp_SUITE.erl13
-rw-r--r--erts/test/run_erl_SUITE.erl12
-rw-r--r--erts/test/z_SUITE.erl12
-rw-r--r--erts/vsn.mk14
-rw-r--r--lib/.gitignore556
-rw-r--r--lib/Makefile16
-rw-r--r--lib/appmon/doc/src/Makefile13
-rw-r--r--lib/appmon/doc/src/notes.xml37
-rw-r--r--lib/appmon/vsn.mk20
-rw-r--r--lib/asn1/c_src/Makefile124
-rw-r--r--lib/asn1/c_src/Makefile.in139
-rw-r--r--lib/asn1/c_src/asn1_erl_driver.c16
-rw-r--r--lib/asn1/doc/src/Makefile4
-rw-r--r--lib/asn1/doc/src/asn1ct.xml22
-rw-r--r--lib/asn1/doc/src/note.gifbin1539 -> 0 bytes
-rw-r--r--lib/asn1/doc/src/notes.xml141
-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/asn1/src/Restrictions.txt12
-rw-r--r--lib/asn1/src/asn1.appup.src108
-rw-r--r--lib/asn1/src/asn1_records.hrl13
-rw-r--r--lib/asn1/src/asn1ct_check.erl315
-rw-r--r--lib/asn1/src/asn1ct_constructed_ber.erl41
-rw-r--r--lib/asn1/src/asn1ct_constructed_ber_bin_v2.erl31
-rw-r--r--lib/asn1/src/asn1ct_constructed_per.erl369
-rw-r--r--lib/asn1/src/asn1ct_gen.erl49
-rw-r--r--lib/asn1/src/asn1ct_gen_ber.erl23
-rw-r--r--lib/asn1/src/asn1ct_gen_ber_bin_v2.erl24
-rw-r--r--lib/asn1/src/asn1ct_gen_per.erl33
-rw-r--r--lib/asn1/src/asn1ct_gen_per_rt2ct.erl33
-rw-r--r--lib/asn1/src/asn1ct_parser2.erl687
-rw-r--r--lib/asn1/src/asn1ct_tok.erl200
-rw-r--r--lib/asn1/src/asn1rt_ber_bin.erl157
-rw-r--r--lib/asn1/test/External.hrl42
-rw-r--r--lib/asn1/test/Makefile205
-rw-r--r--lib/asn1/test/asn1.spec3
-rw-r--r--lib/asn1/test/asn1_SUITE.erl.src2377
-rw-r--r--lib/asn1/test/asn1_SUITE_data/AA1.asn13
-rw-r--r--lib/asn1/test/asn1_SUITE_data/AA2.asn1dbbin0 -> 5910 bytes
-rw-r--r--lib/asn1/test/asn1_SUITE_data/BadEnumValue1.asn8
-rw-r--r--lib/asn1/test/asn1_SUITE_data/BadTypeEnding.asn6
-rw-r--r--lib/asn1/test/asn1_SUITE_data/BadValueAssignment1.asn18
-rw-r--r--lib/asn1/test/asn1_SUITE_data/BadValueAssignment2.asn18
-rw-r--r--lib/asn1/test/asn1_SUITE_data/BadValueSet.asn19
-rw-r--r--lib/asn1/test/asn1_SUITE_data/BitStr.py56
-rw-r--r--lib/asn1/test/asn1_SUITE_data/CCSNARG3.asn345
-rw-r--r--lib/asn1/test/asn1_SUITE_data/Certificate.asn (renamed from system/doc/images/.gitignore)0
-rw-r--r--lib/asn1/test/asn1_SUITE_data/Cho.py27
-rw-r--r--lib/asn1/test/asn1_SUITE_data/ChoExtension.asn144
-rw-r--r--lib/asn1/test/asn1_SUITE_data/ChoExternal.asn140
-rw-r--r--lib/asn1/test/asn1_SUITE_data/ChoOptional.asn135
-rw-r--r--lib/asn1/test/asn1_SUITE_data/ChoOptionalImplicitTag.asn135
-rw-r--r--lib/asn1/test/asn1_SUITE_data/ChoPrim.asn120
-rw-r--r--lib/asn1/test/asn1_SUITE_data/ChoRecursive.asn130
-rw-r--r--lib/asn1/test/asn1_SUITE_data/ChoTypeRefCho.asn144
-rw-r--r--lib/asn1/test/asn1_SUITE_data/ChoTypeRefPrim.asn134
-rw-r--r--lib/asn1/test/asn1_SUITE_data/ChoTypeRefSeq.asn137
-rw-r--r--lib/asn1/test/asn1_SUITE_data/ChoTypeRefSet.asn137
-rw-r--r--lib/asn1/test/asn1_SUITE_data/ChoiceBadExtension.asn127
-rw-r--r--lib/asn1/test/asn1_SUITE_data/ChoiceInSeq.asn22
-rw-r--r--lib/asn1/test/asn1_SUITE_data/ChoiceIndef.asn24
-rw-r--r--lib/asn1/test/asn1_SUITE_data/Comment.asn21
-rw-r--r--lib/asn1/test/asn1_SUITE_data/CommonDataTypes.py4360
-rw-r--r--lib/asn1/test/asn1_SUITE_data/Constraints.py84
-rw-r--r--lib/asn1/test/asn1_SUITE_data/Constructed.asn23
-rw-r--r--lib/asn1/test/asn1_SUITE_data/ContextSwitchingTypes.asn153
-rw-r--r--lib/asn1/test/asn1_SUITE_data/DERSpec.asn38
-rw-r--r--lib/asn1/test/asn1_SUITE_data/DS-EquipmentUser-CommonFunctionOrig-TransmissionPath.py150
-rw-r--r--lib/asn1/test/asn1_SUITE_data/Def.asn131
-rw-r--r--lib/asn1/test/asn1_SUITE_data/Def.py31
-rw-r--r--lib/asn1/test/asn1_SUITE_data/Default.asn158
-rwxr-xr-xlib/asn1/test/asn1_SUITE_data/DirectoryAbstractService.asn710
-rw-r--r--lib/asn1/test/asn1_SUITE_data/DoubleEllipses.asn99
-rw-r--r--lib/asn1/test/asn1_SUITE_data/ELDAPv3.asn291
-rw-r--r--lib/asn1/test/asn1_SUITE_data/EUTRA-InterNodeDefinitions.asn123
-rw-r--r--lib/asn1/test/asn1_SUITE_data/EUTRA-RRC-Definitions.asn3155
-rw-r--r--lib/asn1/test/asn1_SUITE_data/EUTRA-UE-Variables.asn49
-rw-r--r--lib/asn1/test/asn1_SUITE_data/EUTRA-extract-55.asn47
-rw-r--r--lib/asn1/test/asn1_SUITE_data/EUTRA-extract-7407.asn1109
-rw-r--r--lib/asn1/test/asn1_SUITE_data/Enum.py46
-rw-r--r--lib/asn1/test/asn1_SUITE_data/EnumExt.asn128
-rw-r--r--lib/asn1/test/asn1_SUITE_data/EnumerationBadExtension.asn120
-rw-r--r--lib/asn1/test/asn1_SUITE_data/ErrorClass.asn15
-rw-r--r--lib/asn1/test/asn1_SUITE_data/Example.asn120
-rw-r--r--lib/asn1/test/asn1_SUITE_data/Export1.asn7
-rw-r--r--lib/asn1/test/asn1_SUITE_data/Extension-Addition-Group.asn82
-rw-r--r--lib/asn1/test/asn1_SUITE_data/External.asn1132
-rw-r--r--lib/asn1/test/asn1_SUITE_data/From.py15
-rw-r--r--lib/asn1/test/asn1_SUITE_data/H235-SECURITY-MESSAGES.asn170
-rw-r--r--lib/asn1/test/asn1_SUITE_data/H323-MESSAGES.asn1341
-rw-r--r--lib/asn1/test/asn1_SUITE_data/IMP.asn17
-rw-r--r--lib/asn1/test/asn1_SUITE_data/IN-CS-1-Datatypes.asn1630
-rw-r--r--lib/asn1/test/asn1_SUITE_data/INAPv2extract.asn112
-rw-r--r--lib/asn1/test/asn1_SUITE_data/INSTANCEOF.asn134
-rw-r--r--lib/asn1/test/asn1_SUITE_data/IllegalExport.asn17
-rw-r--r--lib/asn1/test/asn1_SUITE_data/Import.py14
-rw-r--r--lib/asn1/test/asn1_SUITE_data/ImportsFrom.asn117
-rw-r--r--lib/asn1/test/asn1_SUITE_data/InfClass.asn56
-rw-r--r--lib/asn1/test/asn1_SUITE_data/InfObj.asn153
-rw-r--r--lib/asn1/test/asn1_SUITE_data/InfObj2.asn156
-rwxr-xr-xlib/asn1/test/asn1_SUITE_data/InformationFramework.asn868
-rw-r--r--lib/asn1/test/asn1_SUITE_data/Int.py12
-rwxr-xr-xlib/asn1/test/asn1_SUITE_data/LDAP.asn1283
-rw-r--r--lib/asn1/test/asn1_SUITE_data/M1.asn24
-rw-r--r--lib/asn1/test/asn1_SUITE_data/M2.asn29
-rw-r--r--lib/asn1/test/asn1_SUITE_data/MAP-ExtensionDataTypes.asn37
-rw-r--r--lib/asn1/test/asn1_SUITE_data/MAP-commonDataTypes.py31
-rw-r--r--lib/asn1/test/asn1_SUITE_data/MAP-insertSubscriberData-def.py102
-rw-r--r--lib/asn1/test/asn1_SUITE_data/MEDIA-GATEWAY-CONTROL.asn975
-rw-r--r--lib/asn1/test/asn1_SUITE_data/MEDIA-GATEWAY-CONTROL.asn1config7
-rw-r--r--lib/asn1/test/asn1_SUITE_data/MS.set.asn2
-rw-r--r--lib/asn1/test/asn1_SUITE_data/MULTIMEDIA-SYSTEM-CONTROL.asn3084
-rw-r--r--lib/asn1/test/asn1_SUITE_data/MissingEnd.asn15
-rw-r--r--lib/asn1/test/asn1_SUITE_data/Mod.set.asn5
-rw-r--r--lib/asn1/test/asn1_SUITE_data/Mod1.asn18
-rw-r--r--lib/asn1/test/asn1_SUITE_data/Mod2.asn43
-rw-r--r--lib/asn1/test/asn1_SUITE_data/Mod3.asn33
-rw-r--r--lib/asn1/test/asn1_SUITE_data/Mod4.asn33
-rw-r--r--lib/asn1/test/asn1_SUITE_data/Mod5.asn37
-rw-r--r--lib/asn1/test/asn1_SUITE_data/Mvrasn-11-4.asn675
-rw-r--r--lib/asn1/test/asn1_SUITE_data/Mvrasn-11-6.asn1776
-rw-r--r--lib/asn1/test/asn1_SUITE_data/Mvrasn-14-4.asn66
-rw-r--r--lib/asn1/test/asn1_SUITE_data/Mvrasn-14-6.asn352
-rw-r--r--lib/asn1/test/asn1_SUITE_data/Mvrasn-15-4.asn42
-rw-r--r--lib/asn1/test/asn1_SUITE_data/Mvrasn-15-6.asn202
-rw-r--r--lib/asn1/test/asn1_SUITE_data/Mvrasn-17-4.asn100
-rw-r--r--lib/asn1/test/asn1_SUITE_data/Mvrasn-18-4.asn215
-rw-r--r--lib/asn1/test/asn1_SUITE_data/Mvrasn-18-6.asn515
-rw-r--r--lib/asn1/test/asn1_SUITE_data/Mvrasn-19-4.asn53
-rw-r--r--lib/asn1/test/asn1_SUITE_data/Mvrasn-19-6.asn109
-rw-r--r--lib/asn1/test/asn1_SUITE_data/Mvrasn-20-4.asn54
-rw-r--r--lib/asn1/test/asn1_SUITE_data/Mvrasn-20-6.asn147
-rw-r--r--lib/asn1/test/asn1_SUITE_data/Mvrasn-21-4.asn66
-rw-r--r--lib/asn1/test/asn1_SUITE_data/Mvrasn-Constants-1.asn85
-rw-r--r--lib/asn1/test/asn1_SUITE_data/Mvrasn-DataTypes-1.asn454
-rw-r--r--lib/asn1/test/asn1_SUITE_data/Mvrasn.set.asn7
-rw-r--r--lib/asn1/test/asn1_SUITE_data/Mvrasn4.set.asn10
-rw-r--r--lib/asn1/test/asn1_SUITE_data/Mvrasn6.set.asn7
-rw-r--r--lib/asn1/test/asn1_SUITE_data/MyMerge.set.asn2
-rw-r--r--lib/asn1/test/asn1_SUITE_data/NoImport.asn14
-rwxr-xr-xlib/asn1/test/asn1_SUITE_data/Nortel.asn592
-rw-r--r--lib/asn1/test/asn1_SUITE_data/Null.py22
-rw-r--r--lib/asn1/test/asn1_SUITE_data/OLD-MEDIA-GATEWAY-CONTROL.asn950
-rw-r--r--lib/asn1/test/asn1_SUITE_data/OTP-PKIX.asn1config2
-rw-r--r--lib/asn1/test/asn1_SUITE_data/OTP-PKIX.set.asn5
-rw-r--r--lib/asn1/test/asn1_SUITE_data/ObjIdValues.asn166
-rw-r--r--lib/asn1/test/asn1_SUITE_data/Objects.asn61
-rw-r--r--lib/asn1/test/asn1_SUITE_data/Octetstr.py15
-rw-r--r--lib/asn1/test/asn1_SUITE_data/One.py52
-rw-r--r--lib/asn1/test/asn1_SUITE_data/OpenType.asn112
-rw-r--r--lib/asn1/test/asn1_SUITE_data/OpenTypeImplicitTag.asn19
-rw-r--r--lib/asn1/test/asn1_SUITE_data/Opt.asn131
-rw-r--r--lib/asn1/test/asn1_SUITE_data/Opt.py31
-rw-r--r--lib/asn1/test/asn1_SUITE_data/P-Record.asn1config1
-rw-r--r--lib/asn1/test/asn1_SUITE_data/P-Record.asn1dbbin0 -> 3128 bytes
-rw-r--r--lib/asn1/test/asn1_SUITE_data/P-Record.erl244
-rw-r--r--lib/asn1/test/asn1_SUITE_data/P-Record.hrl17
-rw-r--r--lib/asn1/test/asn1_SUITE_data/P-Record.py59
-rw-r--r--lib/asn1/test/asn1_SUITE_data/P-RecordA1.asn29
-rw-r--r--lib/asn1/test/asn1_SUITE_data/P-RecordA2.asn33
-rw-r--r--lib/asn1/test/asn1_SUITE_data/P-RecordA3.asn40
-rw-r--r--lib/asn1/test/asn1_SUITE_data/P.py19
-rw-r--r--lib/asn1/test/asn1_SUITE_data/PDUs.py325
-rw-r--r--lib/asn1/test/asn1_SUITE_data/PKIX1Algorithms88.asn1274
-rw-r--r--lib/asn1/test/asn1_SUITE_data/PKIX1Explicit88.asn1619
-rw-r--r--lib/asn1/test/asn1_SUITE_data/PKIX1Explicit93.asn1779
-rw-r--r--lib/asn1/test/asn1_SUITE_data/PKIX1Implicit88.asn1349
-rw-r--r--lib/asn1/test/asn1_SUITE_data/PKIX1Implicit93.asn1357
-rw-r--r--lib/asn1/test/asn1_SUITE_data/PKIXAttributeCertificate.asn1189
-rw-r--r--lib/asn1/test/asn1_SUITE_data/Param.asn193
-rw-r--r--lib/asn1/test/asn1_SUITE_data/ParamBasic.asn123
-rw-r--r--lib/asn1/test/asn1_SUITE_data/PartialDecMyHTTP.asn19
-rw-r--r--lib/asn1/test/asn1_SUITE_data/PartialDecMyHTTP.asn1config3
-rw-r--r--lib/asn1/test/asn1_SUITE_data/PartialDecSeq.asn34
-rw-r--r--lib/asn1/test/asn1_SUITE_data/PartialDecSeq.asn1config22
-rw-r--r--lib/asn1/test/asn1_SUITE_data/PartialDecSeq2.asn29
-rw-r--r--lib/asn1/test/asn1_SUITE_data/PartialDecSeq2.asn1config4
-rw-r--r--lib/asn1/test/asn1_SUITE_data/PartialDecSeq3.asn45
-rw-r--r--lib/asn1/test/asn1_SUITE_data/PartialDecSeq3.asn1config2
-rw-r--r--lib/asn1/test/asn1_SUITE_data/Pattern.asn8
-rw-r--r--lib/asn1/test/asn1_SUITE_data/Person.py10
-rw-r--r--lib/asn1/test/asn1_SUITE_data/Prim.asn132
-rw-r--r--lib/asn1/test/asn1_SUITE_data/PrimExternal.asn139
-rw-r--r--lib/asn1/test/asn1_SUITE_data/PrimStrings.asn197
-rw-r--r--lib/asn1/test/asn1_SUITE_data/RANAP-CommonDataTypes.asn145
-rw-r--r--lib/asn1/test/asn1_SUITE_data/RANAP-Constants.asn1355
-rw-r--r--lib/asn1/test/asn1_SUITE_data/RANAP-Containers.asn1206
-rw-r--r--lib/asn1/test/asn1_SUITE_data/RANAP-IEs.asn12081
-rw-r--r--lib/asn1/test/asn1_SUITE_data/RANAP-PDU-Contents.asn13383
-rw-r--r--lib/asn1/test/asn1_SUITE_data/RANAP-PDU-Descriptions.asn1619
-rw-r--r--lib/asn1/test/asn1_SUITE_data/RANAP.asn13237
-rw-r--r--lib/asn1/test/asn1_SUITE_data/RANAPSET.set.asn16
-rw-r--r--lib/asn1/test/asn1_SUITE_data/RANAPextract1.asn142
-rw-r--r--lib/asn1/test/asn1_SUITE_data/ROSE.asn1449
-rw-r--r--lib/asn1/test/asn1_SUITE_data/Real.py31
-rw-r--r--lib/asn1/test/asn1_SUITE_data/Remote-Operations-Generic-ROS-PDUs.asn1203
-rw-r--r--lib/asn1/test/asn1_SUITE_data/Remote-Operations-Information-Objects.asn1130
-rw-r--r--lib/asn1/test/asn1_SUITE_data/Remote-Operations-Merged.set.asn13
-rw-r--r--lib/asn1/test/asn1_SUITE_data/Remote-Operations-Useful-Definitions.asn1149
-rw-r--r--lib/asn1/test/asn1_SUITE_data/S1AP-CommonDataTypes.asn35
-rw-r--r--lib/asn1/test/asn1_SUITE_data/S1AP-Constants.asn251
-rw-r--r--lib/asn1/test/asn1_SUITE_data/S1AP-Containers.asn201
-rw-r--r--lib/asn1/test/asn1_SUITE_data/S1AP-IEs.asn1178
-rw-r--r--lib/asn1/test/asn1_SUITE_data/S1AP-PDU-Contents.asn2083
-rw-r--r--lib/asn1/test/asn1_SUITE_data/S1AP-PDU-Descriptions.asn548
-rw-r--r--lib/asn1/test/asn1_SUITE_data/SOpttest.asn30
-rw-r--r--lib/asn1/test/asn1_SUITE_data/SSL-PKIX.asn1704
-rw-r--r--lib/asn1/test/asn1_SUITE_data/SelectedAttributeTypes.asn1466
-rw-r--r--lib/asn1/test/asn1_SUITE_data/SelectionType.asn59
-rw-r--r--lib/asn1/test/asn1_SUITE_data/Seq.py152
-rw-r--r--lib/asn1/test/asn1_SUITE_data/Seq2738.asn137
-rw-r--r--lib/asn1/test/asn1_SUITE_data/SeqBadComma.asn10
-rw-r--r--lib/asn1/test/asn1_SUITE_data/SeqDefault.asn177
-rw-r--r--lib/asn1/test/asn1_SUITE_data/SeqExtension.asn137
-rw-r--r--lib/asn1/test/asn1_SUITE_data/SeqExternal.asn168
-rw-r--r--lib/asn1/test/asn1_SUITE_data/SeqOf.asn165
-rw-r--r--lib/asn1/test/asn1_SUITE_data/SeqOf.py45
-rw-r--r--lib/asn1/test/asn1_SUITE_data/SeqOfCho.asn173
-rw-r--r--lib/asn1/test/asn1_SUITE_data/SeqOfEnum.asn111
-rw-r--r--lib/asn1/test/asn1_SUITE_data/SeqOfExternal.asn142
-rw-r--r--lib/asn1/test/asn1_SUITE_data/SeqOfTag.asn165
-rw-r--r--lib/asn1/test/asn1_SUITE_data/SeqOptional.asn186
-rw-r--r--lib/asn1/test/asn1_SUITE_data/SeqOptional2.asn90
-rw-r--r--lib/asn1/test/asn1_SUITE_data/SeqPrim.asn119
-rw-r--r--lib/asn1/test/asn1_SUITE_data/SeqSetIndefinite.asn41
-rw-r--r--lib/asn1/test/asn1_SUITE_data/SeqSetLib.py32
-rw-r--r--lib/asn1/test/asn1_SUITE_data/SeqTag.asn148
-rw-r--r--lib/asn1/test/asn1_SUITE_data/SeqTypeRefCho.asn128
-rw-r--r--lib/asn1/test/asn1_SUITE_data/SeqTypeRefPrim.asn148
-rw-r--r--lib/asn1/test/asn1_SUITE_data/SeqTypeRefSeq.asn1113
-rw-r--r--lib/asn1/test/asn1_SUITE_data/SeqTypeRefSet.asn139
-rw-r--r--lib/asn1/test/asn1_SUITE_data/SequenceBadComma.asn10
-rw-r--r--lib/asn1/test/asn1_SUITE_data/SequenceBadComponentName.asn110
-rw-r--r--lib/asn1/test/asn1_SUITE_data/SequenceBadComponentType.asn110
-rw-r--r--lib/asn1/test/asn1_SUITE_data/Set.py141
-rw-r--r--lib/asn1/test/asn1_SUITE_data/SetDefault.asn133
-rw-r--r--lib/asn1/test/asn1_SUITE_data/SetExtension.asn137
-rw-r--r--lib/asn1/test/asn1_SUITE_data/SetExternal.asn168
-rw-r--r--lib/asn1/test/asn1_SUITE_data/SetOf.asn161
-rw-r--r--lib/asn1/test/asn1_SUITE_data/SetOf.py42
-rw-r--r--lib/asn1/test/asn1_SUITE_data/SetOfCho.asn173
-rw-r--r--lib/asn1/test/asn1_SUITE_data/SetOfExternal.asn142
-rw-r--r--lib/asn1/test/asn1_SUITE_data/SetOfTag.asn165
-rw-r--r--lib/asn1/test/asn1_SUITE_data/SetOptional.asn177
-rw-r--r--lib/asn1/test/asn1_SUITE_data/SetPrim.asn120
-rw-r--r--lib/asn1/test/asn1_SUITE_data/SetTag.asn147
-rw-r--r--lib/asn1/test/asn1_SUITE_data/SetTypeRefCho.asn127
-rw-r--r--lib/asn1/test/asn1_SUITE_data/SetTypeRefPrim.asn129
-rw-r--r--lib/asn1/test/asn1_SUITE_data/SetTypeRefSeq.asn138
-rw-r--r--lib/asn1/test/asn1_SUITE_data/SetTypeRefSet.asn1110
-rw-r--r--lib/asn1/test/asn1_SUITE_data/String.py7
-rw-r--r--lib/asn1/test/asn1_SUITE_data/SwCDR.py213
-rw-r--r--lib/asn1/test/asn1_SUITE_data/Syntax.py10
-rw-r--r--lib/asn1/test/asn1_SUITE_data/TCAPMessages-simple.asn206
-rw-r--r--lib/asn1/test/asn1_SUITE_data/TCAPMessages.asn98
-rw-r--r--lib/asn1/test/asn1_SUITE_data/TCAPPackage.asn271
-rw-r--r--lib/asn1/test/asn1_SUITE_data/TCAPPackage.asn1config12
-rw-r--r--lib/asn1/test/asn1_SUITE_data/TCAPPackage_msg.erl141
-rw-r--r--lib/asn1/test/asn1_SUITE_data/TConstr.asn195
-rw-r--r--lib/asn1/test/asn1_SUITE_data/TConstrChoice.asn1175
-rw-r--r--lib/asn1/test/asn1_SUITE_data/Time.py7
-rw-r--r--lib/asn1/test/asn1_SUITE_data/Tst.py153
-rw-r--r--lib/asn1/test/asn1_SUITE_data/Two.py34
-rw-r--r--lib/asn1/test/asn1_SUITE_data/UPERDefault.asn18
-rw-r--r--lib/asn1/test/asn1_SUITE_data/UndefType.py14
-rwxr-xr-xlib/asn1/test/asn1_SUITE_data/UpperBounds.asn89
-rwxr-xr-xlib/asn1/test/asn1_SUITE_data/UsefulDefinitions.asn238
-rw-r--r--lib/asn1/test/asn1_SUITE_data/ValueTest.asn53
-rw-r--r--lib/asn1/test/asn1_SUITE_data/XSeq.py42
-rw-r--r--lib/asn1/test/asn1_SUITE_data/XSeqOf.py19
-rw-r--r--lib/asn1/test/asn1_SUITE_data/XSet.py47
-rw-r--r--lib/asn1/test/asn1_SUITE_data/XSetOf.py12
-rw-r--r--lib/asn1/test/asn1_SUITE_data/a_SeqIn.erl31
-rw-r--r--lib/asn1/test/asn1_SUITE_data/b_SeqIn.erl29
-rw-r--r--lib/asn1/test/asn1_SUITE_data/extensionAdditionGroup.erl131
-rw-r--r--lib/asn1/test/asn1_SUITE_data/megacomessages/Msg1.valbin0 -> 1032 bytes
-rw-r--r--lib/asn1/test/asn1_SUITE_data/megacomessages/Msg10.valbin0 -> 893 bytes
-rw-r--r--lib/asn1/test/asn1_SUITE_data/megacomessages/Msg11.valbin0 -> 854 bytes
-rw-r--r--lib/asn1/test/asn1_SUITE_data/megacomessages/Msg12.valbin0 -> 538 bytes
-rw-r--r--lib/asn1/test/asn1_SUITE_data/megacomessages/Msg13.valbin0 -> 1156 bytes
-rw-r--r--lib/asn1/test/asn1_SUITE_data/megacomessages/Msg14.valbin0 -> 878 bytes
-rw-r--r--lib/asn1/test/asn1_SUITE_data/megacomessages/Msg15.valbin0 -> 1542 bytes
-rw-r--r--lib/asn1/test/asn1_SUITE_data/megacomessages/Msg16.valbin0 -> 691 bytes
-rw-r--r--lib/asn1/test/asn1_SUITE_data/megacomessages/Msg17.valbin0 -> 957 bytes
-rw-r--r--lib/asn1/test/asn1_SUITE_data/megacomessages/Msg18.valbin0 -> 402 bytes
-rw-r--r--lib/asn1/test/asn1_SUITE_data/megacomessages/Msg19.valbin0 -> 476 bytes
-rw-r--r--lib/asn1/test/asn1_SUITE_data/megacomessages/Msg2.valbin0 -> 1032 bytes
-rw-r--r--lib/asn1/test/asn1_SUITE_data/megacomessages/Msg20.valbin0 -> 331 bytes
-rw-r--r--lib/asn1/test/asn1_SUITE_data/megacomessages/Msg21.valbin0 -> 474 bytes
-rw-r--r--lib/asn1/test/asn1_SUITE_data/megacomessages/Msg22.valbin0 -> 329 bytes
-rw-r--r--lib/asn1/test/asn1_SUITE_data/megacomessages/Msg23.valbin0 -> 691 bytes
-rw-r--r--lib/asn1/test/asn1_SUITE_data/megacomessages/Msg24.valbin0 -> 452 bytes
-rw-r--r--lib/asn1/test/asn1_SUITE_data/megacomessages/Msg25.valbin0 -> 1552 bytes
-rw-r--r--lib/asn1/test/asn1_SUITE_data/megacomessages/Msg3.valbin0 -> 1090 bytes
-rw-r--r--lib/asn1/test/asn1_SUITE_data/megacomessages/Msg4.valbin0 -> 473 bytes
-rw-r--r--lib/asn1/test/asn1_SUITE_data/megacomessages/Msg5.valbin0 -> 550 bytes
-rw-r--r--lib/asn1/test/asn1_SUITE_data/megacomessages/Msg6.valbin0 -> 483 bytes
-rw-r--r--lib/asn1/test/asn1_SUITE_data/megacomessages/Msg7.valbin0 -> 326 bytes
-rw-r--r--lib/asn1/test/asn1_SUITE_data/megacomessages/Msg8.valbin0 -> 326 bytes
-rw-r--r--lib/asn1/test/asn1_SUITE_data/megacomessages/Msg9.valbin0 -> 331 bytes
-rw-r--r--lib/asn1/test/asn1_SUITE_data/modified_x420/AuthenticationFramework.asn290
-rw-r--r--lib/asn1/test/asn1_SUITE_data/modified_x420/BasicAccessControl.asn184
-rw-r--r--lib/asn1/test/asn1_SUITE_data/modified_x420/CertificateExtensions.asn498
-rw-r--r--lib/asn1/test/asn1_SUITE_data/modified_x420/InformationFramework.asn868
-rw-r--r--lib/asn1/test/asn1_SUITE_data/modified_x420/MTSAbstractService.asn2366
-rw-r--r--lib/asn1/test/asn1_SUITE_data/modified_x420/MTSUpperBounds.asn146
-rw-r--r--lib/asn1/test/asn1_SUITE_data/modified_x420/PKCS7.asn343
-rw-r--r--lib/asn1/test/asn1_SUITE_data/modified_x420/SelectedAttributeTypes.asn1466
-rw-r--r--lib/asn1/test/asn1_SUITE_data/modified_x420/UpperBounds.asn89
-rw-r--r--lib/asn1/test/asn1_SUITE_data/modified_x420/UsefulDefinitions.asn238
-rw-r--r--lib/asn1/test/asn1_SUITE_data/modified_x420/p7_signed_data.pem23
-rwxr-xr-xlib/asn1/test/asn1_SUITE_data/nbapsystem/NBAP-CommonDataTypes.asn58
-rwxr-xr-xlib/asn1/test/asn1_SUITE_data/nbapsystem/NBAP-Constants.asn688
-rwxr-xr-xlib/asn1/test/asn1_SUITE_data/nbapsystem/NBAP-Containers.asn197
-rwxr-xr-xlib/asn1/test/asn1_SUITE_data/nbapsystem/NBAP-IEs.asn4127
-rwxr-xr-xlib/asn1/test/asn1_SUITE_data/nbapsystem/NBAP-PDU-Contents.asn9234
-rwxr-xr-xlib/asn1/test/asn1_SUITE_data/nbapsystem/NBAP-PDU-Discriptions.asn916
-rw-r--r--lib/asn1/test/asn1_SUITE_data/p_record.asn1config1
-rw-r--r--lib/asn1/test/asn1_SUITE_data/p_record.set.asn1
-rw-r--r--lib/asn1/test/asn1_SUITE_data/subdir/MySO.asn14
-rw-r--r--lib/asn1/test/asn1_SUITE_data/subdir/subsubdir/.gitignore0
-rw-r--r--lib/asn1/test/asn1_SUITE_data/tcapsystem/DialoguePDUs.asn80
-rw-r--r--lib/asn1/test/asn1_SUITE_data/tcapsystem/MAP-ApplicationContexts.asn186
-rw-r--r--lib/asn1/test/asn1_SUITE_data/tcapsystem/MAP-BS-Code.asn126
-rw-r--r--lib/asn1/test/asn1_SUITE_data/tcapsystem/MAP-CH-DataTypes.asn438
-rw-r--r--lib/asn1/test/asn1_SUITE_data/tcapsystem/MAP-CallHandlingOperations.asn198
-rw-r--r--lib/asn1/test/asn1_SUITE_data/tcapsystem/MAP-CommonDataTypes.asn612
-rw-r--r--lib/asn1/test/asn1_SUITE_data/tcapsystem/MAP-DialogueInformation.asn149
-rw-r--r--lib/asn1/test/asn1_SUITE_data/tcapsystem/MAP-ER-DataTypes.asn405
-rw-r--r--lib/asn1/test/asn1_SUITE_data/tcapsystem/MAP-Errors.asn507
-rw-r--r--lib/asn1/test/asn1_SUITE_data/tcapsystem/MAP-ExtensionDataTypes.asn65
-rw-r--r--lib/asn1/test/asn1_SUITE_data/tcapsystem/MAP-GR-DataTypes.asn122
-rw-r--r--lib/asn1/test/asn1_SUITE_data/tcapsystem/MAP-Group-Call-Operations.asn72
-rw-r--r--lib/asn1/test/asn1_SUITE_data/tcapsystem/MAP-LCS-DataTypes.asn533
-rw-r--r--lib/asn1/test/asn1_SUITE_data/tcapsystem/MAP-LocationServiceOperations.asn103
-rw-r--r--lib/asn1/test/asn1_SUITE_data/tcapsystem/MAP-MS-DataTypes.asn2458
-rw-r--r--lib/asn1/test/asn1_SUITE_data/tcapsystem/MAP-MobileServiceOperations.asn506
-rw-r--r--lib/asn1/test/asn1_SUITE_data/tcapsystem/MAP-OM-DataTypes.asn62
-rw-r--r--lib/asn1/test/asn1_SUITE_data/tcapsystem/MAP-OperationAndMaintenanceOperations.asn91
-rw-r--r--lib/asn1/test/asn1_SUITE_data/tcapsystem/MAP-Protocol.asn176
-rw-r--r--lib/asn1/test/asn1_SUITE_data/tcapsystem/MAP-SM-DataTypes.asn217
-rw-r--r--lib/asn1/test/asn1_SUITE_data/tcapsystem/MAP-SS-Code.asn183
-rw-r--r--lib/asn1/test/asn1_SUITE_data/tcapsystem/MAP-SS-DataTypes.asn337
-rw-r--r--lib/asn1/test/asn1_SUITE_data/tcapsystem/MAP-ST-DataTypes.asn98
-rw-r--r--lib/asn1/test/asn1_SUITE_data/tcapsystem/MAP-SecureTransportOperations.asn78
-rw-r--r--lib/asn1/test/asn1_SUITE_data/tcapsystem/MAP-ShortMessageServiceOperations.asn155
-rw-r--r--lib/asn1/test/asn1_SUITE_data/tcapsystem/MAP-SupplementaryServiceOperations.asn295
-rw-r--r--lib/asn1/test/asn1_SUITE_data/tcapsystem/MAP-TS-Code.asn87
-rw-r--r--lib/asn1/test/asn1_SUITE_data/tcapsystem/MobileDomainDefinitions.asn38
-rw-r--r--lib/asn1/test/asn1_SUITE_data/tcapsystem/Remote-Operations-Generic-ROS-PDUs.asn167
-rw-r--r--lib/asn1/test/asn1_SUITE_data/tcapsystem/Remote-Operations-Information-Objects.asn127
-rw-r--r--lib/asn1/test/asn1_SUITE_data/tcapsystem/Remote-Operations-Useful-Definitions.asn99
-rw-r--r--lib/asn1/test/asn1_SUITE_data/tcapsystem/TC-Notation-Extensions.asn87
-rw-r--r--lib/asn1/test/asn1_SUITE_data/tcapsystem/TCAP-Examples.asn72
-rw-r--r--lib/asn1/test/asn1_SUITE_data/tcapsystem/TCAP-Tools.asn47
-rw-r--r--lib/asn1/test/asn1_SUITE_data/tcapsystem/TCAPMessages.asn149
-rw-r--r--lib/asn1/test/asn1_SUITE_data/tcapsystem/UnidialoguePDUs.asn26
-rw-r--r--lib/asn1/test/asn1_SUITE_data/test_records.erl87
-rw-r--r--lib/asn1/test/asn1_SUITE_data/testobj.erl1443
-rw-r--r--lib/asn1/test/asn1_SUITE_data/x420/ACSE-1.asn253
-rw-r--r--lib/asn1/test/asn1_SUITE_data/x420/AuthenticationFramework.asn290
-rw-r--r--lib/asn1/test/asn1_SUITE_data/x420/BasicAccessControl.asn184
-rw-r--r--lib/asn1/test/asn1_SUITE_data/x420/CertificateExtensions.asn498
-rw-r--r--lib/asn1/test/asn1_SUITE_data/x420/Character-Coding-Attributes.asn17
-rw-r--r--lib/asn1/test/asn1_SUITE_data/x420/Character-Presentation-Attributes.asn125
-rw-r--r--lib/asn1/test/asn1_SUITE_data/x420/Character-Profile-Attributes.asn54
-rw-r--r--lib/asn1/test/asn1_SUITE_data/x420/Colour-Attributes.asn192
-rw-r--r--lib/asn1/test/asn1_SUITE_data/x420/DOR-definition.asn134
-rw-r--r--lib/asn1/test/asn1_SUITE_data/x420/DSAOperationalAttributeTypes.asn186
-rw-r--r--lib/asn1/test/asn1_SUITE_data/x420/Default-Value-Lists.asn143
-rw-r--r--lib/asn1/test/asn1_SUITE_data/x420/DirectoryAbstractService.asn710
-rw-r--r--lib/asn1/test/asn1_SUITE_data/x420/DirectoryAccessProtocol.asn162
-rw-r--r--lib/asn1/test/asn1_SUITE_data/x420/DirectoryInformationShadowProtocol.asn246
-rw-r--r--lib/asn1/test/asn1_SUITE_data/x420/DirectoryOperationalBindingManagementProtocol.asn117
-rw-r--r--lib/asn1/test/asn1_SUITE_data/x420/DirectoryOperationalBindingTypes.asn26
-rw-r--r--lib/asn1/test/asn1_SUITE_data/x420/DirectoryProtectionMappings.asn70
-rw-r--r--lib/asn1/test/asn1_SUITE_data/x420/DirectoryShadowAbstractService.asn324
-rw-r--r--lib/asn1/test/asn1_SUITE_data/x420/DirectorySystemProtocol.asn118
-rw-r--r--lib/asn1/test/asn1_SUITE_data/x420/DistributedOperations.asn181
-rw-r--r--lib/asn1/test/asn1_SUITE_data/x420/Document-Profile-Descriptor.asn464
-rw-r--r--lib/asn1/test/asn1_SUITE_data/x420/EnhancedSecurity.asn363
-rw-r--r--lib/asn1/test/asn1_SUITE_data/x420/External-References.asn49
-rw-r--r--lib/asn1/test/asn1_SUITE_data/x420/GULSProtectionMappings.asn71
-rw-r--r--lib/asn1/test/asn1_SUITE_data/x420/GenericProtectingTransferSyntax.asn66
-rw-r--r--lib/asn1/test/asn1_SUITE_data/x420/Geo-Gr-Coding-Attributes.asn16
-rw-r--r--lib/asn1/test/asn1_SUITE_data/x420/Geo-Gr-Presentation-Attributes.asn265
-rw-r--r--lib/asn1/test/asn1_SUITE_data/x420/Geo-Gr-Profile-Attributes.asn44
-rw-r--r--lib/asn1/test/asn1_SUITE_data/x420/GulsSecurityExchanges.asn79
-rw-r--r--lib/asn1/test/asn1_SUITE_data/x420/GulsSecurityTransformations.asn212
-rw-r--r--lib/asn1/test/asn1_SUITE_data/x420/HierarchicalOperationalBindings.asn123
-rw-r--r--lib/asn1/test/asn1_SUITE_data/x420/IPMSAbstractService.asn148
-rw-r--r--lib/asn1/test/asn1_SUITE_data/x420/IPMSAutoActionTypes.asn234
-rw-r--r--lib/asn1/test/asn1_SUITE_data/x420/IPMSExtendedBodyPartTypes.asn102
-rw-r--r--lib/asn1/test/asn1_SUITE_data/x420/IPMSExtendedBodyPartTypes2.asn37
-rw-r--r--lib/asn1/test/asn1_SUITE_data/x420/IPMSExtendedVoiceBodyPartType.asn39
-rw-r--r--lib/asn1/test/asn1_SUITE_data/x420/IPMSFileTransferBodyPartType.asn253
-rw-r--r--lib/asn1/test/asn1_SUITE_data/x420/IPMSForwardedContentBodyPartType.asn53
-rw-r--r--lib/asn1/test/asn1_SUITE_data/x420/IPMSForwardedReportBodyPartType.asn41
-rw-r--r--lib/asn1/test/asn1_SUITE_data/x420/IPMSFunctionalObjects.asn47
-rw-r--r--lib/asn1/test/asn1_SUITE_data/x420/IPMSHeadingExtensions.asn246
-rw-r--r--lib/asn1/test/asn1_SUITE_data/x420/IPMSInformationObjects.asn626
-rw-r--r--lib/asn1/test/asn1_SUITE_data/x420/IPMSMessageStoreAttributes.asn1120
-rw-r--r--lib/asn1/test/asn1_SUITE_data/x420/IPMSObjectIdentifiers.asn507
-rw-r--r--lib/asn1/test/asn1_SUITE_data/x420/IPMSObjectIdentifiers2.asn33
-rw-r--r--lib/asn1/test/asn1_SUITE_data/x420/IPMSSecurityExtensions.asn143
-rw-r--r--lib/asn1/test/asn1_SUITE_data/x420/IPMSUpperBounds.asn46
-rw-r--r--lib/asn1/test/asn1_SUITE_data/x420/ISO-STANDARD-9541-FONT-ATTRIBUTE-SET.asn459
-rw-r--r--lib/asn1/test/asn1_SUITE_data/x420/ISO8571-FTAM.asn1453
-rw-r--r--lib/asn1/test/asn1_SUITE_data/x420/ISO9541-SN.asn51
-rw-r--r--lib/asn1/test/asn1_SUITE_data/x420/Identifiers-and-Expressions.asn126
-rw-r--r--lib/asn1/test/asn1_SUITE_data/x420/InformationFramework.asn868
-rw-r--r--lib/asn1/test/asn1_SUITE_data/x420/Interchange-Data-Elements.asn57
-rw-r--r--lib/asn1/test/asn1_SUITE_data/x420/Layout-Descriptors.asn268
-rw-r--r--lib/asn1/test/asn1_SUITE_data/x420/Link-Descriptors.asn80
-rw-r--r--lib/asn1/test/asn1_SUITE_data/x420/Location-Expressions.asn338
-rw-r--r--lib/asn1/test/asn1_SUITE_data/x420/Logical-Descriptors.asn95
-rw-r--r--lib/asn1/test/asn1_SUITE_data/x420/MHSObjectIdentifiers.asn187
-rw-r--r--lib/asn1/test/asn1_SUITE_data/x420/MHSProtocolObjectIdentifiers.asn112
-rw-r--r--lib/asn1/test/asn1_SUITE_data/x420/MSAbstractService.asn1085
-rw-r--r--lib/asn1/test/asn1_SUITE_data/x420/MSAccessProtocol.asn259
-rw-r--r--lib/asn1/test/asn1_SUITE_data/x420/MSGeneralAttributeTypes.asn830
-rw-r--r--lib/asn1/test/asn1_SUITE_data/x420/MSGeneralAutoActionTypes.asn118
-rw-r--r--lib/asn1/test/asn1_SUITE_data/x420/MSMatchingRules.asn225
-rw-r--r--lib/asn1/test/asn1_SUITE_data/x420/MSObjectIdentifiers.asn322
-rw-r--r--lib/asn1/test/asn1_SUITE_data/x420/MSUpperBounds.asn77
-rw-r--r--lib/asn1/test/asn1_SUITE_data/x420/MTAAbstractService.asn481
-rw-r--r--lib/asn1/test/asn1_SUITE_data/x420/MTSAbstractService.asn2366
-rw-r--r--lib/asn1/test/asn1_SUITE_data/x420/MTSAbstractService88.asn150
-rw-r--r--lib/asn1/test/asn1_SUITE_data/x420/MTSAccessProtocol.asn321
-rw-r--r--lib/asn1/test/asn1_SUITE_data/x420/MTSObjectIdentifiers.asn116
-rw-r--r--lib/asn1/test/asn1_SUITE_data/x420/MTSUpperBounds.asn146
-rw-r--r--lib/asn1/test/asn1_SUITE_data/x420/Notation.asn244
-rw-r--r--lib/asn1/test/asn1_SUITE_data/x420/ObjectIdentifiers.asn46
-rw-r--r--lib/asn1/test/asn1_SUITE_data/x420/OperationalBindingManagement.asn263
-rw-r--r--lib/asn1/test/asn1_SUITE_data/x420/PKCS7.asn342
-rw-r--r--lib/asn1/test/asn1_SUITE_data/x420/PKCS7BodyPartType.asn31
-rw-r--r--lib/asn1/test/asn1_SUITE_data/x420/Protected-Part-Descriptors.asn74
-rw-r--r--lib/asn1/test/asn1_SUITE_data/x420/ProtocolObjectIdentifiers.asn140
-rw-r--r--lib/asn1/test/asn1_SUITE_data/x420/Raster-Gr-Coding-Attributes.asn75
-rw-r--r--lib/asn1/test/asn1_SUITE_data/x420/Raster-Gr-Presentation-Attributes.asn92
-rw-r--r--lib/asn1/test/asn1_SUITE_data/x420/Raster-Gr-Profile-Attributes.asn76
-rw-r--r--lib/asn1/test/asn1_SUITE_data/x420/Reliable-Transfer-APDU.asn132
-rw-r--r--lib/asn1/test/asn1_SUITE_data/x420/Remote-Operations-Abstract-Syntaxes.asn103
-rw-r--r--lib/asn1/test/asn1_SUITE_data/x420/Remote-Operations-Generic-ROS-PDUs.asn163
-rw-r--r--lib/asn1/test/asn1_SUITE_data/x420/Remote-Operations-Information-Objects-extensions.asn36
-rw-r--r--lib/asn1/test/asn1_SUITE_data/x420/Remote-Operations-Information-Objects.asn123
-rw-r--r--lib/asn1/test/asn1_SUITE_data/x420/Remote-Operations-Realizations.asn81
-rw-r--r--lib/asn1/test/asn1_SUITE_data/x420/Remote-Operations-Useful-Definitions.asn95
-rw-r--r--lib/asn1/test/asn1_SUITE_data/x420/SelectedAttributeTypes.asn1466
-rw-r--r--lib/asn1/test/asn1_SUITE_data/x420/SeseAPDUs.asn116
-rw-r--r--lib/asn1/test/asn1_SUITE_data/x420/SpkmGssTokens.asn257
-rw-r--r--lib/asn1/test/asn1_SUITE_data/x420/Style-Descriptors.asn190
-rw-r--r--lib/asn1/test/asn1_SUITE_data/x420/Subprofiles.asn96
-rw-r--r--lib/asn1/test/asn1_SUITE_data/x420/Temporal-Relationships.asn92
-rw-r--r--lib/asn1/test/asn1_SUITE_data/x420/Text-Units.asn72
-rw-r--r--lib/asn1/test/asn1_SUITE_data/x420/UpperBounds.asn89
-rw-r--r--lib/asn1/test/asn1_SUITE_data/x420/UsefulDefinitions.asn238
-rw-r--r--lib/asn1/test/asn1_SUITE_data/x420/Videotex-Coding-Attributes.asn30
-rw-r--r--lib/asn1/test/asn1_app_test.erl253
-rw-r--r--lib/asn1/test/asn1_appup_test.erl418
-rw-r--r--lib/asn1/test/asn1_bin_particular_SUITE.erl.src2
-rw-r--r--lib/asn1/test/asn1_bin_v2_particular_SUITE.erl.src95
-rw-r--r--lib/asn1/test/asn1_common_SUITE.erl.src98
-rw-r--r--lib/asn1/test/asn1_particular_SUITE.erl.src10
-rw-r--r--lib/asn1/test/asn1_test_lib.erl151
-rw-r--r--lib/asn1/test/asn1_wrapper.erl74
-rw-r--r--lib/asn1/test/bench/README109
-rw-r--r--lib/asn1/test/bench/RanapASN1.asn3146
-rw-r--r--lib/asn1/test/bench/all.erl98
-rw-r--r--lib/asn1/test/bench/bench.erl454
-rw-r--r--lib/asn1/test/bench/bench.hrl24
-rw-r--r--lib/asn1/test/bench/per_bm.erl650
-rw-r--r--lib/asn1/test/ber_decode_error.erl56
-rw-r--r--lib/asn1/test/choice_extension.erl37
-rw-r--r--lib/asn1/test/h323test.erl172
-rw-r--r--lib/asn1/test/testChoExtension.erl76
-rw-r--r--lib/asn1/test/testChoExternal.erl99
-rw-r--r--lib/asn1/test/testChoOptional.erl113
-rw-r--r--lib/asn1/test/testChoOptionalImplicitTag.erl113
-rw-r--r--lib/asn1/test/testChoPrim.erl115
-rw-r--r--lib/asn1/test/testChoRecursive.erl76
-rw-r--r--lib/asn1/test/testChoTypeRefCho.erl78
-rw-r--r--lib/asn1/test/testChoTypeRefPrim.erl95
-rw-r--r--lib/asn1/test/testChoTypeRefSeq.erl115
-rw-r--r--lib/asn1/test/testChoTypeRefSet.erl116
-rw-r--r--lib/asn1/test/testChoiceIndefinite.erl55
-rw-r--r--lib/asn1/test/testCompactBitString.erl279
-rw-r--r--lib/asn1/test/testConstraints.erl159
-rw-r--r--lib/asn1/test/testContextSwitchingTypes.erl83
-rw-r--r--lib/asn1/test/testDER.erl59
-rw-r--r--lib/asn1/test/testDeepTConstr.erl107
-rw-r--r--lib/asn1/test/testDef.erl128
-rw-r--r--lib/asn1/test/testDoubleEllipses.erl112
-rw-r--r--lib/asn1/test/testEnumExt.erl95
-rw-r--r--lib/asn1/test/testExternal.erl35
-rw-r--r--lib/asn1/test/testINSTANCE_OF.erl89
-rw-r--r--lib/asn1/test/testInfObj.erl104
-rw-r--r--lib/asn1/test/testInfObjectClass.erl67
-rw-r--r--lib/asn1/test/testMegaco.erl191
-rw-r--r--lib/asn1/test/testMergeCompile.erl184
-rw-r--r--lib/asn1/test/testMvrasn6.erl44
-rw-r--r--lib/asn1/test/testNBAPsystem.erl357
-rw-r--r--lib/asn1/test/testOpenTypeImplicitTag.erl52
-rw-r--r--lib/asn1/test/testOpt.erl130
-rw-r--r--lib/asn1/test/testParamBasic.erl99
-rw-r--r--lib/asn1/test/testParameterizedInfObj.erl114
-rw-r--r--lib/asn1/test/testPrim.erl695
-rw-r--r--lib/asn1/test/testPrimExternal.erl118
-rw-r--r--lib/asn1/test/testPrimStrings.erl936
-rw-r--r--lib/asn1/test/testRANAP.erl52
-rw-r--r--lib/asn1/test/testROSE.erl36
-rw-r--r--lib/asn1/test/testSSLspecs.erl179
-rw-r--r--lib/asn1/test/testSelectionTypes.erl45
-rw-r--r--lib/asn1/test/testSeq2738.erl53
-rw-r--r--lib/asn1/test/testSeqDefault.erl190
-rw-r--r--lib/asn1/test/testSeqExtension.erl108
-rw-r--r--lib/asn1/test/testSeqExternal.erl140
-rw-r--r--lib/asn1/test/testSeqIndefinite.erl63
-rw-r--r--lib/asn1/test/testSeqOf.erl242
-rw-r--r--lib/asn1/test/testSeqOfCho.erl159
-rw-r--r--lib/asn1/test/testSeqOfExternal.erl171
-rw-r--r--lib/asn1/test/testSeqOfIndefinite.erl329
-rw-r--r--lib/asn1/test/testSeqOfTag.erl201
-rw-r--r--lib/asn1/test/testSeqOptional.erl206
-rw-r--r--lib/asn1/test/testSeqPrim.erl94
-rw-r--r--lib/asn1/test/testSeqSetDefaultVal.erl345
-rw-r--r--lib/asn1/test/testSeqTag.erl114
-rw-r--r--lib/asn1/test/testSeqTypeRefCho.erl54
-rw-r--r--lib/asn1/test/testSeqTypeRefPrim.erl57
-rw-r--r--lib/asn1/test/testSeqTypeRefSeq.erl186
-rw-r--r--lib/asn1/test/testSeqTypeRefSet.erl76
-rw-r--r--lib/asn1/test/testSetDefault.erl94
-rw-r--r--lib/asn1/test/testSetExtension.erl106
-rw-r--r--lib/asn1/test/testSetExternal.erl140
-rw-r--r--lib/asn1/test/testSetIndefinite.erl55
-rw-r--r--lib/asn1/test/testSetOf.erl235
-rw-r--r--lib/asn1/test/testSetOfCho.erl159
-rw-r--r--lib/asn1/test/testSetOfExternal.erl171
-rw-r--r--lib/asn1/test/testSetOfTag.erl201
-rw-r--r--lib/asn1/test/testSetOptional.erl218
-rw-r--r--lib/asn1/test/testSetPrim.erl95
-rw-r--r--lib/asn1/test/testSetTag.erl114
-rw-r--r--lib/asn1/test/testSetTypeRefCho.erl54
-rw-r--r--lib/asn1/test/testSetTypeRefPrim.erl57
-rw-r--r--lib/asn1/test/testSetTypeRefSeq.erl76
-rw-r--r--lib/asn1/test/testSetTypeRefSet.erl186
-rw-r--r--lib/asn1/test/testTCAP.erl103
-rw-r--r--lib/asn1/test/testTcapsystem.erl72
-rw-r--r--lib/asn1/test/testTimer.erl222
-rw-r--r--lib/asn1/test/testTypeValueNotation.erl78
-rw-r--r--lib/asn1/test/testX420.erl114
-rw-r--r--lib/asn1/test/test_bad_values.erl29
-rw-r--r--lib/asn1/test/test_compile_options.erl169
-rw-r--r--lib/asn1/test/test_driver_load.erl58
-rw-r--r--lib/asn1/test/test_inline.erl285
-rw-r--r--lib/asn1/test/test_modified_x420.erl67
-rw-r--r--lib/asn1/test/test_partial_incomplete_decode.erl253
-rw-r--r--lib/asn1/test/test_selective_decode.erl65
-rw-r--r--lib/asn1/test/test_special_decode_performance.erl165
-rw-r--r--lib/asn1/test/test_undecoded_rest.erl65
-rw-r--r--lib/asn1/test/test_x691.erl227
-rw-r--r--lib/asn1/vsn.mk9
-rw-r--r--lib/common_test/doc/src/Makefile20
-rw-r--r--lib/common_test/doc/src/example_chapter.xml12
-rw-r--r--lib/common_test/doc/src/notes.xml85
-rw-r--r--lib/common_test/include/ct.hrl12
-rw-r--r--lib/common_test/info2
-rw-r--r--lib/common_test/src/ct_framework.erl36
-rw-r--r--lib/common_test/src/ct_run.erl12
-rw-r--r--lib/common_test/src/ct_telnet.erl59
-rw-r--r--lib/common_test/src/ct_telnet_client.erl179
-rw-r--r--lib/common_test/src/ct_testspec.erl76
-rw-r--r--lib/common_test/src/ct_util.hrl13
-rw-r--r--lib/common_test/src/unix_telnet.erl39
-rw-r--r--lib/common_test/test/Makefile94
-rw-r--r--lib/common_test/test/common_test.spec1
-rw-r--r--lib/common_test/test/ct_error_SUITE.erl558
-rw-r--r--lib/common_test/test/ct_error_SUITE_data/error/test/cfg_error_1_SUITE.erl116
-rw-r--r--lib/common_test/test/ct_error_SUITE_data/error/test/cfg_error_2_SUITE.erl117
-rw-r--r--lib/common_test/test/ct_error_SUITE_data/error/test/cfg_error_3_SUITE.erl116
-rw-r--r--lib/common_test/test/ct_error_SUITE_data/error/test/cfg_error_4_SUITE.erl115
-rw-r--r--lib/common_test/test/ct_error_SUITE_data/error/test/cfg_error_5_SUITE.erl115
-rw-r--r--lib/common_test/test/ct_error_SUITE_data/error/test/cfg_error_6_SUITE.erl116
-rw-r--r--lib/common_test/test/ct_error_SUITE_data/error/test/cfg_error_7_SUITE.erl116
-rw-r--r--lib/common_test/test/ct_error_SUITE_data/error/test/cfg_error_8_SUITE.erl152
-rw-r--r--lib/common_test/test/ct_error_SUITE_data/error/test/cfg_error_9_SUITE.erl185
-rw-r--r--lib/common_test/test/ct_error_SUITE_data/error/test/lib_error_1_SUITE.erl188
-rw-r--r--lib/common_test/test/ct_error_SUITE_data/error/test/lib_lines.erl25
-rw-r--r--lib/common_test/test/ct_error_SUITE_data/error/test/lib_no_lines.erl23
-rw-r--r--lib/common_test/test/ct_error_SUITE_data/error/test/no_compile_SUITE.erl115
-rw-r--r--lib/common_test/test/ct_event_handler_SUITE.erl170
-rw-r--r--lib/common_test/test/ct_event_handler_SUITE_data/eh_A.erl127
-rw-r--r--lib/common_test/test/ct_event_handler_SUITE_data/event_handling_1/test/eh_11_SUITE.erl141
-rw-r--r--lib/common_test/test/ct_groups_test_1_SUITE.erl1226
-rw-r--r--lib/common_test/test/ct_groups_test_1_SUITE_data/groups_1/test/groups_11_SUITE.erl280
-rw-r--r--lib/common_test/test/ct_groups_test_1_SUITE_data/groups_1/test/groups_12_SUITE.erl310
-rw-r--r--lib/common_test/test/ct_groups_test_1_SUITE_data/groups_2/test/groups_21_SUITE.erl280
-rw-r--r--lib/common_test/test/ct_groups_test_1_SUITE_data/groups_2/test/groups_22_SUITE.erl310
-rw-r--r--lib/common_test/test/ct_groups_test_2_SUITE.erl110
-rw-r--r--lib/common_test/test/ct_groups_test_2_SUITE_data/groups_1/missing_conf_SUITE.erl62
-rw-r--r--lib/common_test/test/ct_skip_SUITE.erl565
-rw-r--r--lib/common_test/test/ct_skip_SUITE_data/skip/test/auto_skip_10_SUITE.erl130
-rw-r--r--lib/common_test/test/ct_skip_SUITE_data/skip/test/auto_skip_11_SUITE.erl136
-rw-r--r--lib/common_test/test/ct_skip_SUITE_data/skip/test/auto_skip_1_SUITE.erl130
-rw-r--r--lib/common_test/test/ct_skip_SUITE_data/skip/test/auto_skip_2_SUITE.erl127
-rw-r--r--lib/common_test/test/ct_skip_SUITE_data/skip/test/auto_skip_3_SUITE.erl132
-rw-r--r--lib/common_test/test/ct_skip_SUITE_data/skip/test/auto_skip_4_SUITE.erl126
-rw-r--r--lib/common_test/test/ct_skip_SUITE_data/skip/test/auto_skip_5_SUITE.erl123
-rw-r--r--lib/common_test/test/ct_skip_SUITE_data/skip/test/auto_skip_6_SUITE.erl136
-rw-r--r--lib/common_test/test/ct_skip_SUITE_data/skip/test/auto_skip_7_SUITE.erl130
-rw-r--r--lib/common_test/test/ct_skip_SUITE_data/skip/test/auto_skip_8_SUITE.erl130
-rw-r--r--lib/common_test/test/ct_skip_SUITE_data/skip/test/auto_skip_9_SUITE.erl166
-rw-r--r--lib/common_test/test/ct_skip_SUITE_data/skip/test/user_skip_1_SUITE.erl131
-rw-r--r--lib/common_test/test/ct_skip_SUITE_data/skip/test/user_skip_2_SUITE.erl135
-rw-r--r--lib/common_test/test/ct_skip_SUITE_data/skip/test/user_skip_3_SUITE.erl132
-rw-r--r--lib/common_test/test/ct_skip_SUITE_data/skip/test/user_skip_4_SUITE.erl152
-rw-r--r--lib/common_test/test/ct_skip_SUITE_data/skip/test/user_skip_5_SUITE.erl131
-rw-r--r--lib/common_test/test/ct_smoke_test_SUITE.erl569
-rw-r--r--lib/common_test/test/ct_smoke_test_SUITE_data/happy_1/cfg/config1.cfg5
-rw-r--r--lib/common_test/test/ct_smoke_test_SUITE_data/happy_1/test/happy_11_SUITE.erl196
-rw-r--r--lib/common_test/test/ct_smoke_test_SUITE_data/happy_2_cfg/config1.cfg5
-rw-r--r--lib/common_test/test/ct_smoke_test_SUITE_data/happy_2_test/happy_21_SUITE.erl196
-rw-r--r--lib/common_test/test/ct_test_server_if_1_SUITE.erl253
-rw-r--r--lib/common_test/test/ct_test_server_if_1_SUITE_data/test_server_if/test/skipped_by_spec_1_SUITE.erl127
-rw-r--r--lib/common_test/test/ct_test_server_if_1_SUITE_data/test_server_if/test/skipped_by_spec_2_SUITE.erl127
-rw-r--r--lib/common_test/test/ct_test_server_if_1_SUITE_data/test_server_if/test/ts_if_1_SUITE.erl191
-rw-r--r--lib/common_test/test/ct_test_server_if_1_SUITE_data/test_server_if/test/ts_if_2_SUITE.erl127
-rw-r--r--lib/common_test/test/ct_test_server_if_1_SUITE_data/test_server_if/test/ts_if_3_SUITE.erl128
-rw-r--r--lib/common_test/test/ct_test_server_if_1_SUITE_data/test_server_if/test/ts_if_4_SUITE.erl127
-rw-r--r--lib/common_test/test/ct_test_server_if_1_SUITE_data/test_server_if/test/ts_if_5_SUITE.erl128
-rw-r--r--lib/common_test/test/ct_test_server_if_1_SUITE_data/test_server_if/test/ts_if_6_SUITE.erl111
-rw-r--r--lib/common_test/test/ct_test_server_if_1_SUITE_data/test_server_if/test/ts_if_7_SUITE.erl93
-rw-r--r--lib/common_test/test/ct_test_server_if_1_SUITE_data/test_server_if/test/ts_if_8_SUITE.erl52
-rw-r--r--lib/common_test/test/ct_test_support.erl976
-rw-r--r--lib/common_test/test/ct_test_support_eh.erl127
-rw-r--r--lib/common_test/vsn.mk2
-rw-r--r--lib/compiler/doc/src/compile.xml14
-rw-r--r--lib/compiler/doc/src/notes.xml69
-rw-r--r--lib/compiler/src/Makefile69
-rw-r--r--lib/compiler/src/beam_asm.erl2
-rw-r--r--lib/compiler/src/beam_bool.erl27
-rw-r--r--lib/compiler/src/beam_validator.erl16
-rw-r--r--lib/compiler/src/compile.erl113
-rw-r--r--lib/compiler/src/sys_expand_pmod.erl30
-rw-r--r--lib/compiler/src/sys_pre_expand.erl60
-rw-r--r--lib/compiler/src/v3_core.erl14
-rw-r--r--lib/compiler/test/andor_SUITE.erl66
-rw-r--r--lib/compiler/test/beam_validator_SUITE.erl46
-rw-r--r--lib/compiler/test/compilation_SUITE_data/on_load.erl2
-rw-r--r--lib/compiler/test/error_SUITE.erl30
-rw-r--r--lib/compiler/test/pmod_SUITE.erl24
-rw-r--r--lib/compiler/test/pmod_SUITE_data/pmod_basic.erl17
-rw-r--r--lib/compiler/vsn.mk2
-rw-r--r--lib/configure.in37
-rw-r--r--lib/configure.in.src61
-rw-r--r--lib/cosEvent/doc/src/CosEventChannelAdmin.xml26
-rw-r--r--lib/cosEvent/doc/src/Makefile3
-rw-r--r--lib/cosEvent/doc/src/notes.xml32
-rw-r--r--lib/cosEvent/test/Makefile154
-rw-r--r--lib/cosEvent/test/cosEvent.spec19
-rw-r--r--lib/cosEvent/test/event_channel_SUITE.erl316
-rw-r--r--lib/cosEvent/test/event_test_PullC_impl.erl43
-rw-r--r--lib/cosEvent/test/event_test_PullS_impl.erl57
-rw-r--r--lib/cosEvent/test/event_test_PushC_impl.erl46
-rw-r--r--lib/cosEvent/test/event_test_PushS_impl.erl41
-rw-r--r--lib/cosEvent/test/event_test_server.idl47
-rw-r--r--lib/cosEvent/test/generated_SUITE.erl487
-rw-r--r--lib/cosEvent/test/idl_output/.gitignore0
-rw-r--r--lib/cosEvent/vsn.mk7
-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/test/Makefile104
-rw-r--r--lib/cosEventDomain/test/cosEventDomain.spec19
-rw-r--r--lib/cosEventDomain/test/event_domain_SUITE.erl456
-rw-r--r--lib/cosEventDomain/test/generated_SUITE.erl390
-rw-r--r--lib/cosEventDomain/vsn.mk7
-rw-r--r--lib/cosFileTransfer/doc/src/Makefile3
-rw-r--r--lib/cosFileTransfer/doc/src/notes.xml32
-rw-r--r--lib/cosFileTransfer/test/Makefile132
-rw-r--r--lib/cosFileTransfer/test/cosFileTransfer.spec1
-rw-r--r--lib/cosFileTransfer/test/fileTransfer_SUITE.erl954
-rw-r--r--lib/cosFileTransfer/vsn.mk7
-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.xml88
-rw-r--r--lib/cosNotification/src/CosNotification_Definitions.hrl4
-rw-r--r--lib/cosNotification/src/cosNotification_Filter.erl32
-rw-r--r--lib/cosNotification/test/Makefile190
-rw-r--r--lib/cosNotification/test/cosNotification.spec19
-rw-r--r--lib/cosNotification/test/eventDB_SUITE.erl902
-rw-r--r--lib/cosNotification/test/generated_SUITE.erl2042
-rw-r--r--lib/cosNotification/test/grammar_SUITE.erl1094
-rw-r--r--lib/cosNotification/test/notification_SUITE.erl2185
-rw-r--r--lib/cosNotification/test/notify_test_impl.erl299
-rw-r--r--lib/cosNotification/test/notify_test_server.cfg54
-rw-r--r--lib/cosNotification/test/notify_test_server.idl113
-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/test/Makefile129
-rw-r--r--lib/cosProperty/test/cosProperty.spec20
-rw-r--r--lib/cosProperty/test/generated_SUITE.erl571
-rw-r--r--lib/cosProperty/test/property_SUITE.erl747
-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/test/Makefile135
-rw-r--r--lib/cosTime/test/cosTime.spec19
-rw-r--r--lib/cosTime/test/generated_SUITE.erl288
-rw-r--r--lib/cosTime/test/time_SUITE.erl295
-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/test/Makefile150
-rw-r--r--lib/cosTransactions/test/cosTransactions.spec19
-rw-r--r--lib/cosTransactions/test/etrap_test.cfg20
-rw-r--r--lib/cosTransactions/test/etrap_test.idl38
-rw-r--r--lib/cosTransactions/test/etrap_test_lib.erl125
-rw-r--r--lib/cosTransactions/test/etrap_test_lib.hrl100
-rw-r--r--lib/cosTransactions/test/etrap_test_server_impl.erl210
-rw-r--r--lib/cosTransactions/test/generated_SUITE.erl564
-rw-r--r--lib/cosTransactions/test/transactions_SUITE.erl395
-rw-r--r--lib/cosTransactions/vsn.mk6
-rw-r--r--lib/crypto/c_src/Makefile.in30
-rw-r--r--lib/crypto/c_src/crypto_drv.c78
-rw-r--r--lib/crypto/doc/src/Makefile3
-rw-r--r--lib/crypto/doc/src/crypto.xml64
-rw-r--r--lib/crypto/doc/src/notes.xml98
-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/crypto/vsn.mk2
-rw-r--r--lib/debugger/doc/src/Makefile2
-rw-r--r--lib/debugger/doc/src/notes.xml34
-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_ieval.erl57
-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/debugger/test/Makefile106
-rw-r--r--lib/debugger/test/andor_SUITE.erl305
-rw-r--r--lib/debugger/test/bs_bincomp_SUITE.erl106
-rw-r--r--lib/debugger/test/bs_construct_SUITE.erl432
-rw-r--r--lib/debugger/test/bs_match_bin_SUITE.erl114
-rw-r--r--lib/debugger/test/bs_match_int_SUITE.erl230
-rw-r--r--lib/debugger/test/bs_match_misc_SUITE.erl152
-rw-r--r--lib/debugger/test/bs_match_tail_SUITE.erl106
-rw-r--r--lib/debugger/test/bs_utf_SUITE.erl292
-rw-r--r--lib/debugger/test/bug_SUITE.erl79
-rw-r--r--lib/debugger/test/bug_SUITE_data/Makefile.src25
-rw-r--r--lib/debugger/test/bug_SUITE_data/otp2163.erl60
-rw-r--r--lib/debugger/test/bug_SUITE_data/otp4845.erl52
-rw-r--r--lib/debugger/test/cleanup.erl45
-rw-r--r--lib/debugger/test/dbg_ui_SUITE.erl288
-rw-r--r--lib/debugger/test/dbg_ui_SUITE_data/manual_data/src/lists1.erl469
-rw-r--r--lib/debugger/test/dbg_ui_SUITE_data/manual_data/src/ordsets1.erl188
-rw-r--r--lib/debugger/test/dbg_ui_SUITE_data/manual_data/src/test.erl157
-rw-r--r--lib/debugger/test/debugger.spec1
-rw-r--r--lib/debugger/test/debugger_SUITE.erl123
-rw-r--r--lib/debugger/test/debugger_test.erl154
-rw-r--r--lib/debugger/test/debugger_testdoc.fm5bin0 -> 28672 bytes
-rw-r--r--lib/debugger/test/erl_eval_SUITE.erl1388
-rw-r--r--lib/debugger/test/exception_SUITE.erl256
-rw-r--r--lib/debugger/test/fun_SUITE.erl233
-rw-r--r--lib/debugger/test/guard_SUITE.erl1479
-rw-r--r--lib/debugger/test/int_SUITE.erl277
-rw-r--r--lib/debugger/test/int_SUITE_data/Makefile.src39
-rw-r--r--lib/debugger/test/int_SUITE_data/guards.erl108
-rw-r--r--lib/debugger/test/int_SUITE_data/lists1.erl469
-rw-r--r--lib/debugger/test/int_SUITE_data/my_lists.erl5681
-rw-r--r--lib/debugger/test/int_SUITE_data/ordsets1.erl191
-rw-r--r--lib/debugger/test/int_SUITE_data/test.erl152
-rw-r--r--lib/debugger/test/int_SUITE_data/test1.erl34
-rw-r--r--lib/debugger/test/int_break_SUITE.erl92
-rw-r--r--lib/debugger/test/int_break_SUITE_data/Makefile.src25
-rw-r--r--lib/debugger/test/int_break_SUITE_data/ordsets1.erl188
-rw-r--r--lib/debugger/test/int_eval_SUITE.erl277
-rw-r--r--lib/debugger/test/int_eval_SUITE_data/Makefile.src26
-rw-r--r--lib/debugger/test/int_eval_SUITE_data/my_int_eval_module.erl245
-rw-r--r--lib/debugger/test/lc_SUITE.erl74
-rw-r--r--lib/debugger/test/record_SUITE.erl252
-rw-r--r--lib/debugger/test/test_lib.erl29
-rw-r--r--lib/debugger/test/trycatch_SUITE.erl796
-rw-r--r--lib/debugger/vsn.mk2
-rw-r--r--lib/dialyzer/README4
-rw-r--r--lib/dialyzer/RELEASE_NOTES18
-rw-r--r--lib/dialyzer/doc/manual.txt82
-rwxr-xr-xlib/dialyzer/doc/src/Makefile3
-rwxr-xr-xlib/dialyzer/doc/src/notes.xml35
-rw-r--r--lib/dialyzer/doc/warnings.txt2
-rw-r--r--lib/dialyzer/src/Makefile12
-rw-r--r--lib/dialyzer/src/dialyzer.app.src15
-rw-r--r--lib/dialyzer/src/dialyzer.erl71
-rw-r--r--lib/dialyzer/src/dialyzer.hrl15
-rw-r--r--lib/dialyzer/src/dialyzer_analysis_callgraph.erl61
-rw-r--r--lib/dialyzer/src/dialyzer_behaviours.erl324
-rw-r--r--lib/dialyzer/src/dialyzer_callgraph.erl58
-rw-r--r--lib/dialyzer/src/dialyzer_cl.erl60
-rw-r--r--lib/dialyzer/src/dialyzer_cl_parse.erl56
-rw-r--r--lib/dialyzer/src/dialyzer_codeserver.erl87
-rw-r--r--lib/dialyzer/src/dialyzer_contracts.erl46
-rw-r--r--lib/dialyzer/src/dialyzer_dataflow.erl197
-rw-r--r--lib/dialyzer/src/dialyzer_dep.erl12
-rw-r--r--lib/dialyzer/src/dialyzer_gui_wx.erl71
-rw-r--r--lib/dialyzer/src/dialyzer_options.erl12
-rw-r--r--lib/dialyzer/src/dialyzer_plt.erl148
-rw-r--r--lib/dialyzer/src/dialyzer_races.erl175
-rw-r--r--lib/dialyzer/src/dialyzer_succ_typings.erl33
-rw-r--r--lib/dialyzer/src/dialyzer_typesig.erl74
-rw-r--r--lib/dialyzer/src/dialyzer_utils.erl138
-rw-r--r--lib/dialyzer/vsn.mk2
-rw-r--r--lib/docbuilder/doc/src/inline_tags.xml8
-rw-r--r--lib/docbuilder/doc/src/notes.xml37
-rw-r--r--lib/docbuilder/info2
-rw-r--r--lib/docbuilder/vsn.mk6
-rw-r--r--lib/edoc/Makefile6
-rw-r--r--lib/edoc/doc/src/Makefile5
-rw-r--r--lib/edoc/doc/src/notes.xml37
-rw-r--r--lib/edoc/info2
-rw-r--r--lib/edoc/src/Makefile2
-rw-r--r--lib/edoc/vsn.mk2
-rw-r--r--lib/erl_docgen/doc/src/notes.xml40
-rw-r--r--lib/erl_docgen/priv/bin/Makefile13
-rwxr-xr-xlib/erl_docgen/priv/bin/codeline_preprocessing.escript17
-rwxr-xr-xlib/erl_docgen/priv/bin/xml_from_edoc.escript149
-rw-r--r--lib/erl_docgen/priv/xsl/db_eix.xsl256
-rw-r--r--lib/erl_docgen/priv/xsl/db_html.xsl255
-rw-r--r--lib/erl_docgen/priv/xsl/db_man.xsl248
-rw-r--r--lib/erl_docgen/priv/xsl/db_pdf.xsl99
-rw-r--r--lib/erl_docgen/priv/xsl/db_pdf_params.xsl26
-rw-r--r--lib/erl_docgen/vsn.mk21
-rw-r--r--lib/erl_interface/configure.in174
-rw-r--r--lib/erl_interface/doc/src/ei_connect.xml21
-rw-r--r--lib/erl_interface/doc/src/erl_eterm.xml2
-rw-r--r--lib/erl_interface/doc/src/notes.xml98
-rw-r--r--lib/erl_interface/include/ei.h6
-rw-r--r--lib/erl_interface/src/Makefile.in14
-rw-r--r--lib/erl_interface/src/auxdir/config.h.in277
-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/legacy/erl_eterm.c16
-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/erl_interface/vsn.mk2
-rw-r--r--lib/et/doc/src/Makefile24
-rw-r--r--lib/et/doc/src/book.gifbin1081 -> 0 bytes
-rw-r--r--lib/et/doc/src/coffee_order.pngbin0 -> 23692 bytes
-rw-r--r--lib/et/doc/src/et.xml67
-rw-r--r--lib/et/doc/src/et_architecture.xml554
-rw-r--r--lib/et/doc/src/et_collector.xml19
-rw-r--r--lib/et/doc/src/et_desc.xmlsrc683
-rw-r--r--lib/et/doc/src/et_examples.xml311
-rw-r--r--lib/et/doc/src/et_examples.xmlsrc383
-rw-r--r--lib/et/doc/src/et_intro.xml82
-rw-r--r--lib/et/doc/src/et_selector.xml112
-rw-r--r--lib/et/doc/src/et_tutorial.xmlsrc273
-rw-r--r--lib/et/doc/src/et_viewer.xml9
-rw-r--r--lib/et/doc/src/fascicules.xml18
-rw-r--r--lib/et/doc/src/files.mk45
-rw-r--r--lib/et/doc/src/live_trans.gifbin8691 -> 0 bytes
-rw-r--r--lib/et/doc/src/live_trans.pngbin0 -> 19999 bytes
-rw-r--r--lib/et/doc/src/live_trans.ps1559
-rw-r--r--lib/et/doc/src/make.dep53
-rw-r--r--lib/et/doc/src/megaco_collector.gifbin68430 -> 0 bytes
-rw-r--r--lib/et/doc/src/megaco_collector.pngbin0 -> 37915 bytes
-rw-r--r--lib/et/doc/src/megaco_collector.ps3247
-rw-r--r--lib/et/doc/src/megaco_filter.gifbin8827 -> 0 bytes
-rw-r--r--lib/et/doc/src/megaco_filter.pngbin0 -> 19067 bytes
-rw-r--r--lib/et/doc/src/megaco_filter.ps1733
-rw-r--r--lib/et/doc/src/megaco_tracer.gifbin12400 -> 0 bytes
-rw-r--r--lib/et/doc/src/megaco_tracer.pngbin0 -> 46696 bytes
-rw-r--r--lib/et/doc/src/megaco_tracer.ps2508
-rw-r--r--lib/et/doc/src/note.gifbin1539 -> 0 bytes
-rw-r--r--lib/et/doc/src/notes.gifbin2005 -> 0 bytes
-rw-r--r--lib/et/doc/src/notes.xml60
-rw-r--r--lib/et/doc/src/part.xml9
-rw-r--r--lib/et/doc/src/part_notes.xml36
-rw-r--r--lib/et/doc/src/ref_man.gifbin1530 -> 0 bytes
-rw-r--r--lib/et/doc/src/sim_trans.gifbin20208 -> 0 bytes
-rw-r--r--lib/et/doc/src/sim_trans.pngbin0 -> 19026 bytes
-rw-r--r--lib/et/doc/src/sim_trans.ps6595
-rw-r--r--lib/et/doc/src/sim_trans_contents_viewer_collector.gifbin11607 -> 0 bytes
-rw-r--r--lib/et/doc/src/sim_trans_contents_viewer_collector.pngbin0 -> 13361 bytes
-rw-r--r--lib/et/doc/src/sim_trans_contents_viewer_collector.ps1407
-rw-r--r--lib/et/doc/src/sim_trans_contents_viewer_mgr_actors.gifbin7531 -> 0 bytes
-rw-r--r--lib/et/doc/src/sim_trans_contents_viewer_mgr_actors.pngbin0 -> 15235 bytes
-rw-r--r--lib/et/doc/src/sim_trans_contents_viewer_mgr_actors.ps1371
-rw-r--r--lib/et/doc/src/sim_trans_mgr_actors.gifbin9118 -> 0 bytes
-rw-r--r--lib/et/doc/src/sim_trans_mgr_actors.pngbin0 -> 18936 bytes
-rw-r--r--lib/et/doc/src/sim_trans_mgr_actors.ps1705
-rw-r--r--lib/et/doc/src/sim_trans_move_actor.gifbin8965 -> 0 bytes
-rw-r--r--lib/et/doc/src/sim_trans_move_actor.pngbin0 -> 19026 bytes
-rw-r--r--lib/et/doc/src/sim_trans_move_actor.ps6403
-rw-r--r--lib/et/doc/src/sim_trans_write_lock.gifbin10871 -> 0 bytes
-rw-r--r--lib/et/doc/src/sim_trans_write_lock.pngbin0 -> 13425 bytes
-rw-r--r--lib/et/doc/src/sim_trans_write_lock.ps1287
-rw-r--r--lib/et/doc/src/user_guide.gifbin1581 -> 0 bytes
-rw-r--r--lib/et/doc/src/warning.gifbin1498 -> 0 bytes
-rw-r--r--lib/et/examples/Makefile14
-rw-r--r--lib/et/examples/et_demo.erl103
-rw-r--r--lib/et/examples/et_display_demo.erl32
-rw-r--r--lib/et/examples/et_trace_demo.erl38
-rw-r--r--lib/et/src/Makefile17
-rw-r--r--lib/et/src/et.app.src17
-rw-r--r--lib/et/src/et.erl38
-rw-r--r--lib/et/src/et_collector.erl352
-rw-r--r--lib/et/src/et_contents_viewer.erl591
-rw-r--r--lib/et/src/et_gs_contents_viewer.erl591
-rw-r--r--lib/et/src/et_gs_viewer.erl1481
-rw-r--r--lib/et/src/et_internal.hrl16
-rw-r--r--lib/et/src/et_selector.erl78
-rw-r--r--lib/et/src/et_viewer.erl1492
-rw-r--r--lib/et/src/et_wx_contents_viewer.erl700
-rw-r--r--lib/et/src/et_wx_viewer.erl2122
-rw-r--r--lib/et/src/modules.mk17
-rw-r--r--lib/et/test/Makefile81
-rw-r--r--lib/et/test/README30
-rw-r--r--lib/et/test/et.spec2
-rw-r--r--lib/et/test/et_test_lib.erl329
-rw-r--r--lib/et/test/et_test_lib.hrl90
-rw-r--r--lib/et/test/et_wx_SUITE.erl100
-rwxr-xr-xlib/et/test/ett55
-rw-r--r--lib/et/test/ett.erl154
-rw-r--r--lib/et/vsn.mk23
-rw-r--r--lib/eunit/doc/src/Makefile5
-rw-r--r--lib/eunit/doc/src/notes.xml31
-rw-r--r--lib/eunit/info2
-rw-r--r--lib/eunit/test/Makefile12
-rw-r--r--lib/eunit/vsn.mk2
-rw-r--r--lib/hipe/Makefile22
-rw-r--r--lib/hipe/amd64/Makefile15
-rw-r--r--lib/hipe/arm/Makefile15
-rw-r--r--lib/hipe/cerl/Makefile15
-rw-r--r--lib/hipe/cerl/erl_bif_types.erl103
-rw-r--r--lib/hipe/cerl/erl_types.erl800
-rw-r--r--lib/hipe/doc/Makefile17
-rw-r--r--lib/hipe/doc/src/Makefile21
-rw-r--r--lib/hipe/doc/src/book.xml9
-rw-r--r--lib/hipe/doc/src/hipe_app.xml58
-rw-r--r--lib/hipe/doc/src/notes.xml37
-rw-r--r--lib/hipe/doc/src/ref_man.xml35
-rw-r--r--lib/hipe/flow/Makefile16
-rw-r--r--lib/hipe/icode/Makefile15
-rw-r--r--lib/hipe/info2
-rw-r--r--lib/hipe/main/Makefile16
-rw-r--r--lib/hipe/misc/Makefile15
-rw-r--r--lib/hipe/opt/Makefile15
-rw-r--r--lib/hipe/ppc/Makefile15
-rw-r--r--lib/hipe/regalloc/Makefile16
-rw-r--r--lib/hipe/rtl/Makefile15
-rw-r--r--lib/hipe/sparc/Makefile15
-rw-r--r--lib/hipe/tools/Makefile15
-rw-r--r--lib/hipe/tools/hipe_tool.erl14
-rw-r--r--lib/hipe/util/Makefile15
-rw-r--r--lib/hipe/vsn.mk2
-rw-r--r--lib/hipe/x86/Makefile15
-rw-r--r--lib/ic/doc/src/Makefile17
-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.xml32
-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.xml64
-rw-r--r--lib/ic/doc/src/old_notes.xml1565
-rw-r--r--lib/ic/src/ic_forms.erl6
-rw-r--r--lib/ic/src/ic_pragma.erl12
-rw-r--r--lib/ic/src/ic_symtab.erl4
-rw-r--r--lib/ic/src/icforms.hrl3
-rw-r--r--lib/ic/src/icparse.yrl22
-rw-r--r--lib/ic/src/ictype.erl41
-rw-r--r--lib/ic/test/Makefile277
-rw-r--r--lib/ic/test/c_client_erl_server_SUITE.erl315
-rw-r--r--lib/ic/test/c_client_erl_server_SUITE_data/Makefile.src145
-rw-r--r--lib/ic/test/c_client_erl_server_SUITE_data/c_client.c1760
-rw-r--r--lib/ic/test/c_client_erl_server_SUITE_data/c_erl_test.idl174
-rw-r--r--lib/ic/test/c_client_erl_server_SUITE_data/erl_server.erl28
-rw-r--r--lib/ic/test/c_client_erl_server_SUITE_data/m_i_impl.erl161
-rw-r--r--lib/ic/test/c_client_erl_server_proto_SUITE.erl315
-rw-r--r--lib/ic/test/c_client_erl_server_proto_SUITE_data/Makefile.src146
-rw-r--r--lib/ic/test/c_client_erl_server_proto_SUITE_data/c_client.c1763
-rw-r--r--lib/ic/test/c_client_erl_server_proto_SUITE_data/c_erl_test.idl173
-rw-r--r--lib/ic/test/c_client_erl_server_proto_SUITE_data/erl_server.erl28
-rw-r--r--lib/ic/test/c_client_erl_server_proto_SUITE_data/m_i_impl.erl161
-rw-r--r--lib/ic/test/c_client_erl_server_proto_SUITE_data/my.c50
-rw-r--r--lib/ic/test/c_client_erl_server_proto_tmo_SUITE.erl315
-rw-r--r--lib/ic/test/c_client_erl_server_proto_tmo_SUITE_data/Makefile.src146
-rw-r--r--lib/ic/test/c_client_erl_server_proto_tmo_SUITE_data/c_client.c1763
-rw-r--r--lib/ic/test/c_client_erl_server_proto_tmo_SUITE_data/c_erl_test.idl173
-rw-r--r--lib/ic/test/c_client_erl_server_proto_tmo_SUITE_data/erl_server.erl28
-rw-r--r--lib/ic/test/c_client_erl_server_proto_tmo_SUITE_data/m_i_impl.erl161
-rw-r--r--lib/ic/test/c_client_erl_server_proto_tmo_SUITE_data/my.c51
-rw-r--r--lib/ic/test/erl_client_c_server_SUITE.erl350
-rw-r--r--lib/ic/test/erl_client_c_server_SUITE_data/Makefile.src150
-rw-r--r--lib/ic/test/erl_client_c_server_SUITE_data/c_server.c299
-rw-r--r--lib/ic/test/erl_client_c_server_SUITE_data/callbacks.c610
-rw-r--r--lib/ic/test/erl_client_c_server_SUITE_data/erl_c_test.idl174
-rw-r--r--lib/ic/test/erl_client_c_server_SUITE_data/erl_client.erl331
-rw-r--r--lib/ic/test/erl_client_c_server_proto_SUITE.erl350
-rw-r--r--lib/ic/test/erl_client_c_server_proto_SUITE_data/Makefile.src150
-rw-r--r--lib/ic/test/erl_client_c_server_proto_SUITE_data/c_server.c299
-rw-r--r--lib/ic/test/erl_client_c_server_proto_SUITE_data/callbacks.c610
-rw-r--r--lib/ic/test/erl_client_c_server_proto_SUITE_data/erl_c_test.idl174
-rw-r--r--lib/ic/test/erl_client_c_server_proto_SUITE_data/erl_client.erl331
-rw-r--r--lib/ic/test/erl_client_c_server_proto_SUITE_data/my.c34
-rw-r--r--lib/ic/test/ic.spec1
-rw-r--r--lib/ic/test/ic.spec.vxworks2
-rw-r--r--lib/ic/test/ic_SUITE.erl973
-rw-r--r--lib/ic/test/ic_SUITE_data/Corba.idl1013
-rw-r--r--lib/ic/test/ic_SUITE_data/Coss.idl1537
-rw-r--r--lib/ic/test/ic_SUITE_data/attr.idl29
-rw-r--r--lib/ic/test/ic_SUITE_data/c_err1.idl63
-rw-r--r--lib/ic/test/ic_SUITE_data/c_err2.idl30
-rw-r--r--lib/ic/test/ic_SUITE_data/c_err3.idl28
-rw-r--r--lib/ic/test/ic_SUITE_data/c_norm.idl163
-rw-r--r--lib/ic/test/ic_SUITE_data/enum.idl32
-rw-r--r--lib/ic/test/ic_SUITE_data/forward.idl34
-rw-r--r--lib/ic/test/ic_SUITE_data/include.idl30
-rw-r--r--lib/ic/test/ic_SUITE_data/include2.idl26
-rw-r--r--lib/ic/test/ic_SUITE_data/include3.idl25
-rw-r--r--lib/ic/test/ic_SUITE_data/inherit.idl68
-rw-r--r--lib/ic/test/ic_SUITE_data/inherit_err.idl71
-rw-r--r--lib/ic/test/ic_SUITE_data/inherit_warn.idl64
-rw-r--r--lib/ic/test/ic_SUITE_data/mult_ids.idl92
-rw-r--r--lib/ic/test/ic_SUITE_data/nasty.idl60
-rw-r--r--lib/ic/test/ic_SUITE_data/one.idl29
-rw-r--r--lib/ic/test/ic_SUITE_data/one_followed.idl54
-rw-r--r--lib/ic/test/ic_SUITE_data/one_out.idl28
-rw-r--r--lib/ic/test/ic_SUITE_data/one_raises.idl32
-rw-r--r--lib/ic/test/ic_SUITE_data/one_void.idl30
-rw-r--r--lib/ic/test/ic_SUITE_data/raises_reg.idl52
-rw-r--r--lib/ic/test/ic_SUITE_data/struct.idl53
-rw-r--r--lib/ic/test/ic_SUITE_data/syntax1.idl28
-rw-r--r--lib/ic/test/ic_SUITE_data/syntax2.idl27
-rw-r--r--lib/ic/test/ic_SUITE_data/syntax3.idl20
-rw-r--r--lib/ic/test/ic_SUITE_data/syntax4.idl23
-rw-r--r--lib/ic/test/ic_SUITE_data/syntax5.idl22
-rw-r--r--lib/ic/test/ic_SUITE_data/syntax6.idl20
-rw-r--r--lib/ic/test/ic_SUITE_data/type.idl190
-rw-r--r--lib/ic/test/ic_SUITE_data/typeid.idl28
-rw-r--r--lib/ic/test/ic_SUITE_data/u_case_mult.idl54
-rw-r--r--lib/ic/test/ic_SUITE_data/u_default.idl51
-rw-r--r--lib/ic/test/ic_SUITE_data/u_mult.idl61
-rw-r--r--lib/ic/test/ic_SUITE_data/u_norm.idl63
-rw-r--r--lib/ic/test/ic_SUITE_data/u_type.idl82
-rw-r--r--lib/ic/test/ic_SUITE_data/undef_id.idl63
-rw-r--r--lib/ic/test/ic_be_SUITE.erl69
-rw-r--r--lib/ic/test/ic_be_SUITE_data/plain.idl33
-rw-r--r--lib/ic/test/ic_pp_SUITE.erl647
-rw-r--r--lib/ic/test/ic_pp_SUITE_data/arg.idl38
-rw-r--r--lib/ic/test/ic_pp_SUITE_data/cascade.idl29
-rw-r--r--lib/ic/test/ic_pp_SUITE_data/comment.idl72
-rw-r--r--lib/ic/test/ic_pp_SUITE_data/concat.idl60
-rw-r--r--lib/ic/test/ic_pp_SUITE_data/define.idl41
-rw-r--r--lib/ic/test/ic_pp_SUITE_data/if.idl32
-rw-r--r--lib/ic/test/ic_pp_SUITE_data/if_zero.idl31
-rw-r--r--lib/ic/test/ic_pp_SUITE_data/improp_nest_constr.idl30
-rw-r--r--lib/ic/test/ic_pp_SUITE_data/inc.idl68
-rw-r--r--lib/ic/test/ic_pp_SUITE_data/included1.idl35
-rw-r--r--lib/ic/test/ic_pp_SUITE_data/included2.idl41
-rw-r--r--lib/ic/test/ic_pp_SUITE_data/includer.idl45
-rw-r--r--lib/ic/test/ic_pp_SUITE_data/line.idl45
-rw-r--r--lib/ic/test/ic_pp_SUITE_data/misc.idl44
-rw-r--r--lib/ic/test/ic_pp_SUITE_data/nopara.idl35
-rw-r--r--lib/ic/test/ic_pp_SUITE_data/predef.idl33
-rw-r--r--lib/ic/test/ic_pp_SUITE_data/predef_time.idl24
-rw-r--r--lib/ic/test/ic_pp_SUITE_data/self_ref.idl26
-rw-r--r--lib/ic/test/ic_pp_SUITE_data/separate.idl37
-rw-r--r--lib/ic/test/ic_pp_SUITE_data/swallow_sc.idl37
-rw-r--r--lib/ic/test/ic_pp_SUITE_data/unintended_grp.idl29
-rw-r--r--lib/ic/test/ic_pragma_SUITE.erl295
-rw-r--r--lib/ic/test/ic_pragma_SUITE_data/reg_m0.idl77
-rw-r--r--lib/ic/test/ic_pragma_SUITE_data/reg_m1.idl75
-rw-r--r--lib/ic/test/ic_pragma_SUITE_data/reg_m2.idl40
-rw-r--r--lib/ic/test/ic_pragma_SUITE_data/reg_m3.idl38
-rw-r--r--lib/ic/test/ic_pragma_SUITE_data/reg_m4.idl64
-rw-r--r--lib/ic/test/ic_pragma_SUITE_data/reg_m5.idl28
-rw-r--r--lib/ic/test/ic_pragma_SUITE_data/reg_m6.idl38
-rw-r--r--lib/ic/test/ic_pragma_SUITE_data/reg_m7.idl62
-rw-r--r--lib/ic/test/ic_pragma_SUITE_data/uggly.idl204
-rw-r--r--lib/ic/test/ic_register_SUITE.erl425
-rw-r--r--lib/ic/test/ic_register_SUITE_data/reg_m10.idl37
-rw-r--r--lib/ic/test/ic_register_SUITE_data/reg_m11.idl32
-rw-r--r--lib/ic/test/ic_register_SUITE_data/reg_m12.idl40
-rw-r--r--lib/ic/test/ic_register_SUITE_data/reg_m8.idl32
-rw-r--r--lib/ic/test/ic_register_SUITE_data/reg_m9.idl32
-rw-r--r--lib/ic/test/java_client_erl_server_SUITE.erl330
-rw-r--r--lib/ic/test/java_client_erl_server_SUITE_data/JavaClient.java759
-rw-r--r--lib/ic/test/java_client_erl_server_SUITE_data/Makefile.src88
-rw-r--r--lib/ic/test/java_client_erl_server_SUITE_data/java_erl_test.idl68
-rw-r--r--lib/ic/test/java_client_erl_server_SUITE_data/m_i_impl.erl169
-rw-r--r--lib/ic/vsn.mk14
-rw-r--r--lib/inets/Makefile20
-rw-r--r--lib/inets/doc/src/Makefile58
-rw-r--r--lib/inets/doc/src/ftp.xml16
-rw-r--r--lib/inets/doc/src/http.xml491
-rw-r--r--lib/inets/doc/src/http_client.xml31
-rw-r--r--lib/inets/doc/src/http_server.xml101
-rw-r--r--lib/inets/doc/src/httpc.xml618
-rw-r--r--lib/inets/doc/src/httpd.xml48
-rw-r--r--lib/inets/doc/src/httpd_util.xml15
-rw-r--r--lib/inets/doc/src/inets.xml22
-rw-r--r--lib/inets/doc/src/make.dep22
-rw-r--r--lib/inets/doc/src/mod_esi.xml8
-rw-r--r--lib/inets/doc/src/mod_security.xml17
-rw-r--r--lib/inets/doc/src/notes.xml430
-rw-r--r--lib/inets/doc/src/notes_history.xml24
-rw-r--r--lib/inets/doc/src/ref_man.xml8
-rw-r--r--lib/inets/src/ftp/Makefile18
-rw-r--r--lib/inets/src/http_client/Makefile30
-rw-r--r--lib/inets/src/http_client/http.erl772
-rw-r--r--lib/inets/src/http_client/http_cookie.erl391
-rw-r--r--lib/inets/src/http_client/http_uri.erl116
-rw-r--r--lib/inets/src/http_client/httpc.erl1096
-rw-r--r--lib/inets/src/http_client/httpc_cookie.erl495
-rw-r--r--lib/inets/src/http_client/httpc_handler.erl1031
-rw-r--r--lib/inets/src/http_client/httpc_handler_sup.erl31
-rw-r--r--lib/inets/src/http_client/httpc_internal.hrl84
-rw-r--r--lib/inets/src/http_client/httpc_manager.erl879
-rw-r--r--lib/inets/src/http_client/httpc_profile_sup.erl20
-rw-r--r--lib/inets/src/http_client/httpc_request.erl68
-rw-r--r--lib/inets/src/http_client/httpc_response.erl19
-rw-r--r--lib/inets/src/http_lib/Makefile25
-rw-r--r--lib/inets/src/http_lib/http_chunk.erl21
-rw-r--r--lib/inets/src/http_lib/http_transport.erl171
-rw-r--r--lib/inets/src/http_lib/http_uri.erl147
-rw-r--r--lib/inets/src/http_lib/http_util.erl156
-rw-r--r--lib/inets/src/http_server/Makefile29
-rw-r--r--lib/inets/src/http_server/httpd.erl18
-rw-r--r--lib/inets/src/http_server/httpd_acceptor.erl3
-rw-r--r--lib/inets/src/http_server/httpd_conf.erl24
-rw-r--r--lib/inets/src/http_server/httpd_file.erl7
-rw-r--r--lib/inets/src/http_server/httpd_instance_sup.erl22
-rw-r--r--lib/inets/src/http_server/httpd_request.erl29
-rw-r--r--lib/inets/src/http_server/httpd_request_handler.erl4
-rw-r--r--lib/inets/src/http_server/httpd_response.erl17
-rw-r--r--lib/inets/src/http_server/httpd_sup.erl23
-rw-r--r--lib/inets/src/http_server/httpd_util.erl114
-rw-r--r--lib/inets/src/http_server/mod_alias.erl112
-rw-r--r--lib/inets/src/http_server/mod_auth.erl3
-rw-r--r--lib/inets/src/http_server/mod_auth_dets.erl3
-rw-r--r--lib/inets/src/http_server/mod_auth_plain.erl3
-rw-r--r--lib/inets/src/http_server/mod_auth_server.erl3
-rw-r--r--lib/inets/src/http_server/mod_cgi.erl12
-rw-r--r--lib/inets/src/http_server/mod_dir.erl6
-rw-r--r--lib/inets/src/http_server/mod_esi.erl78
-rw-r--r--lib/inets/src/http_server/mod_include.erl6
-rw-r--r--lib/inets/src/http_server/mod_responsecontrol.erl55
-rw-r--r--lib/inets/src/http_server/mod_security.erl3
-rw-r--r--lib/inets/src/http_server/mod_security_server.erl3
-rw-r--r--lib/inets/src/inets_app/Makefile24
-rw-r--r--lib/inets/src/inets_app/inets.app.src15
-rw-r--r--lib/inets/src/inets_app/inets.appup.src92
-rw-r--r--lib/inets/src/inets_app/inets.erl23
-rw-r--r--lib/inets/src/tftp/Makefile20
-rw-r--r--lib/inets/test/Makefile343
-rw-r--r--lib/inets/test/ftp_SUITE.erl143
-rw-r--r--lib/inets/test/ftp_SUITE_data/ftpd_hosts.skel18
-rw-r--r--lib/inets/test/ftp_format_SUITE.erl341
-rw-r--r--lib/inets/test/ftp_freebsd_x86_test.erl153
l---------lib/inets/test/ftp_internal.hrl1
-rw-r--r--lib/inets/test/ftp_linux_ppc_test.erl151
-rw-r--r--lib/inets/test/ftp_linux_x86_test.erl160
-rw-r--r--lib/inets/test/ftp_macosx_ppc_test.erl152
-rw-r--r--lib/inets/test/ftp_macosx_x86_test.erl152
-rw-r--r--lib/inets/test/ftp_netbsd_x86_test.erl152
-rw-r--r--lib/inets/test/ftp_openbsd_x86_test.erl151
-rw-r--r--lib/inets/test/ftp_solaris10_sparc_test.erl154
-rw-r--r--lib/inets/test/ftp_solaris10_x86_test.erl155
-rw-r--r--lib/inets/test/ftp_solaris8_sparc_test.erl152
-rw-r--r--lib/inets/test/ftp_solaris9_sparc_test.erl151
-rw-r--r--lib/inets/test/ftp_suite_lib.erl1599
-rw-r--r--lib/inets/test/ftp_ticket_test.erl51
-rw-r--r--lib/inets/test/ftp_windows_2003_server_test.erl152
-rw-r--r--lib/inets/test/ftp_windows_xp_test.erl150
-rw-r--r--lib/inets/test/http_format_SUITE.erl591
l---------lib/inets/test/http_internal.hrl1
-rw-r--r--lib/inets/test/httpc_SUITE.erl3163
l---------lib/inets/test/httpc_SUITE_data/Makefile.src1
l---------lib/inets/test/httpc_SUITE_data/cgi_echo.c1
-rw-r--r--lib/inets/test/httpc_SUITE_data/dummy.html12
-rw-r--r--lib/inets/test/httpc_SUITE_data/empty.html0
-rw-r--r--lib/inets/test/httpc_SUITE_data/mime.types465
-rw-r--r--lib/inets/test/httpc_SUITE_data/redirect.html10
-rw-r--r--lib/inets/test/httpc_SUITE_data/ssl_client_cert.pem22
-rw-r--r--lib/inets/test/httpc_SUITE_data/ssl_server_cert.pem22
-rw-r--r--lib/inets/test/httpc_cookie_SUITE.erl451
l---------lib/inets/test/httpc_internal.hrl1
-rw-r--r--lib/inets/test/httpd_1_1.erl502
-rw-r--r--lib/inets/test/httpd_SUITE.erl2081
-rw-r--r--lib/inets/test/httpd_SUITE_data/Makefile.src14
-rw-r--r--lib/inets/test/httpd_SUITE_data/cgi_echo.c97
-rw-r--r--lib/inets/test/httpd_SUITE_data/server_root/auth/group3
-rw-r--r--lib/inets/test/httpd_SUITE_data/server_root/auth/passwd4
-rw-r--r--lib/inets/test/httpd_SUITE_data/server_root/cgi-bin/printenv.bat9
-rwxr-xr-xlib/inets/test/httpd_SUITE_data/server_root/cgi-bin/printenv.sh6
-rw-r--r--lib/inets/test/httpd_SUITE_data/server_root/conf/8080.conf79
-rw-r--r--lib/inets/test/httpd_SUITE_data/server_root/conf/8888.conf63
-rw-r--r--lib/inets/test/httpd_SUITE_data/server_root/conf/httpd.conf268
-rw-r--r--lib/inets/test/httpd_SUITE_data/server_root/conf/mime.types465
-rw-r--r--lib/inets/test/httpd_SUITE_data/server_root/conf/ssl.conf66
-rw-r--r--lib/inets/test/httpd_SUITE_data/server_root/htdocs/config.shtml70
-rw-r--r--lib/inets/test/httpd_SUITE_data/server_root/htdocs/dets_open/dummy.html10
-rw-r--r--lib/inets/test/httpd_SUITE_data/server_root/htdocs/dets_secret/dummy.html10
-rw-r--r--lib/inets/test/httpd_SUITE_data/server_root/htdocs/dets_secret/top_secret/index.html9
-rw-r--r--lib/inets/test/httpd_SUITE_data/server_root/htdocs/echo.shtml35
-rw-r--r--lib/inets/test/httpd_SUITE_data/server_root/htdocs/exec.shtml30
-rw-r--r--lib/inets/test/httpd_SUITE_data/server_root/htdocs/flastmod.shtml29
-rw-r--r--lib/inets/test/httpd_SUITE_data/server_root/htdocs/fsize.shtml29
-rw-r--r--lib/inets/test/httpd_SUITE_data/server_root/htdocs/include.shtml33
-rw-r--r--lib/inets/test/httpd_SUITE_data/server_root/htdocs/index.html25
-rw-r--r--lib/inets/test/httpd_SUITE_data/server_root/htdocs/last_modified.html22
-rw-r--r--lib/inets/test/httpd_SUITE_data/server_root/htdocs/misc/friedrich.html7
-rw-r--r--lib/inets/test/httpd_SUITE_data/server_root/htdocs/misc/oech.html4
-rw-r--r--lib/inets/test/httpd_SUITE_data/server_root/htdocs/misc/welcome.html1
-rw-r--r--lib/inets/test/httpd_SUITE_data/server_root/htdocs/mnesia_open/dummy.html10
-rw-r--r--lib/inets/test/httpd_SUITE_data/server_root/htdocs/mnesia_secret/dummy.html10
-rw-r--r--lib/inets/test/httpd_SUITE_data/server_root/htdocs/mnesia_secret/top_secret/index.html9
-rw-r--r--lib/inets/test/httpd_SUITE_data/server_root/htdocs/open/dummy.html10
-rw-r--r--lib/inets/test/httpd_SUITE_data/server_root/htdocs/secret/dummy.html10
-rw-r--r--lib/inets/test/httpd_SUITE_data/server_root/htdocs/secret/top_secret/index.html9
-rw-r--r--lib/inets/test/httpd_SUITE_data/server_root/icons/README161
-rw-r--r--lib/inets/test/httpd_SUITE_data/server_root/icons/a.gifbin0 -> 246 bytes
-rw-r--r--lib/inets/test/httpd_SUITE_data/server_root/icons/alert.black.gifbin0 -> 242 bytes
-rw-r--r--lib/inets/test/httpd_SUITE_data/server_root/icons/alert.red.gifbin0 -> 247 bytes
-rw-r--r--lib/inets/test/httpd_SUITE_data/server_root/icons/apache_pb.gifbin0 -> 2326 bytes
-rw-r--r--lib/inets/test/httpd_SUITE_data/server_root/icons/back.gifbin0 -> 216 bytes
-rw-r--r--lib/inets/test/httpd_SUITE_data/server_root/icons/ball.gray.gifbin0 -> 233 bytes
-rw-r--r--lib/inets/test/httpd_SUITE_data/server_root/icons/ball.red.gifbin0 -> 205 bytes
-rw-r--r--lib/inets/test/httpd_SUITE_data/server_root/icons/binary.gifbin0 -> 246 bytes
-rw-r--r--lib/inets/test/httpd_SUITE_data/server_root/icons/binhex.gifbin0 -> 246 bytes
-rw-r--r--lib/inets/test/httpd_SUITE_data/server_root/icons/blank.gifbin0 -> 148 bytes
-rw-r--r--lib/inets/test/httpd_SUITE_data/server_root/icons/bomb.gifbin0 -> 308 bytes
-rw-r--r--lib/inets/test/httpd_SUITE_data/server_root/icons/box1.gifbin0 -> 251 bytes
-rw-r--r--lib/inets/test/httpd_SUITE_data/server_root/icons/box2.gifbin0 -> 268 bytes
-rw-r--r--lib/inets/test/httpd_SUITE_data/server_root/icons/broken.gifbin0 -> 247 bytes
-rw-r--r--lib/inets/test/httpd_SUITE_data/server_root/icons/burst.gifbin0 -> 235 bytes
-rw-r--r--lib/inets/test/httpd_SUITE_data/server_root/icons/button1.gifbin0 -> 755 bytes
-rw-r--r--lib/inets/test/httpd_SUITE_data/server_root/icons/button10.gifbin0 -> 781 bytes
-rw-r--r--lib/inets/test/httpd_SUITE_data/server_root/icons/button2.gifbin0 -> 785 bytes
-rw-r--r--lib/inets/test/httpd_SUITE_data/server_root/icons/button3.gifbin0 -> 745 bytes
-rw-r--r--lib/inets/test/httpd_SUITE_data/server_root/icons/button4.gifbin0 -> 786 bytes
-rw-r--r--lib/inets/test/httpd_SUITE_data/server_root/icons/button5.gifbin0 -> 780 bytes
-rw-r--r--lib/inets/test/httpd_SUITE_data/server_root/icons/button6.gifbin0 -> 791 bytes
-rw-r--r--lib/inets/test/httpd_SUITE_data/server_root/icons/button7.gifbin0 -> 796 bytes
-rw-r--r--lib/inets/test/httpd_SUITE_data/server_root/icons/button8.gifbin0 -> 784 bytes
-rw-r--r--lib/inets/test/httpd_SUITE_data/server_root/icons/button9.gifbin0 -> 784 bytes
-rw-r--r--lib/inets/test/httpd_SUITE_data/server_root/icons/buttonl.gifbin0 -> 587 bytes
-rw-r--r--lib/inets/test/httpd_SUITE_data/server_root/icons/buttonr.gifbin0 -> 576 bytes
-rw-r--r--lib/inets/test/httpd_SUITE_data/server_root/icons/c.gifbin0 -> 242 bytes
-rw-r--r--lib/inets/test/httpd_SUITE_data/server_root/icons/comp.blue.gifbin0 -> 251 bytes
-rw-r--r--lib/inets/test/httpd_SUITE_data/server_root/icons/comp.gray.gifbin0 -> 246 bytes
-rw-r--r--lib/inets/test/httpd_SUITE_data/server_root/icons/compressed.gifbin0 -> 1038 bytes
-rw-r--r--lib/inets/test/httpd_SUITE_data/server_root/icons/continued.gifbin0 -> 214 bytes
-rw-r--r--lib/inets/test/httpd_SUITE_data/server_root/icons/dir.gifbin0 -> 225 bytes
-rw-r--r--lib/inets/test/httpd_SUITE_data/server_root/icons/down.gifbin0 -> 163 bytes
-rw-r--r--lib/inets/test/httpd_SUITE_data/server_root/icons/dvi.gifbin0 -> 238 bytes
-rw-r--r--lib/inets/test/httpd_SUITE_data/server_root/icons/f.gifbin0 -> 236 bytes
-rw-r--r--lib/inets/test/httpd_SUITE_data/server_root/icons/folder.gifbin0 -> 225 bytes
-rw-r--r--lib/inets/test/httpd_SUITE_data/server_root/icons/folder.open.gifbin0 -> 242 bytes
-rw-r--r--lib/inets/test/httpd_SUITE_data/server_root/icons/folder.sec.gifbin0 -> 243 bytes
-rw-r--r--lib/inets/test/httpd_SUITE_data/server_root/icons/forward.gifbin0 -> 219 bytes
-rw-r--r--lib/inets/test/httpd_SUITE_data/server_root/icons/generic.gifbin0 -> 221 bytes
-rw-r--r--lib/inets/test/httpd_SUITE_data/server_root/icons/generic.red.gifbin0 -> 220 bytes
-rw-r--r--lib/inets/test/httpd_SUITE_data/server_root/icons/generic.sec.gifbin0 -> 249 bytes
-rw-r--r--lib/inets/test/httpd_SUITE_data/server_root/icons/hand.right.gifbin0 -> 217 bytes
-rw-r--r--lib/inets/test/httpd_SUITE_data/server_root/icons/hand.up.gifbin0 -> 223 bytes
-rw-r--r--lib/inets/test/httpd_SUITE_data/server_root/icons/htdig.gifbin0 -> 1822 bytes
-rw-r--r--lib/inets/test/httpd_SUITE_data/server_root/icons/icon.sheet.gifbin0 -> 11977 bytes
-rw-r--r--lib/inets/test/httpd_SUITE_data/server_root/icons/image1.gifbin0 -> 274 bytes
-rw-r--r--lib/inets/test/httpd_SUITE_data/server_root/icons/image2.gifbin0 -> 309 bytes
-rw-r--r--lib/inets/test/httpd_SUITE_data/server_root/icons/image3.gifbin0 -> 286 bytes
-rw-r--r--lib/inets/test/httpd_SUITE_data/server_root/icons/index.gifbin0 -> 268 bytes
-rw-r--r--lib/inets/test/httpd_SUITE_data/server_root/icons/layout.gifbin0 -> 276 bytes
-rw-r--r--lib/inets/test/httpd_SUITE_data/server_root/icons/left.gifbin0 -> 172 bytes
-rw-r--r--lib/inets/test/httpd_SUITE_data/server_root/icons/link.gifbin0 -> 249 bytes
-rw-r--r--lib/inets/test/httpd_SUITE_data/server_root/icons/movie.gifbin0 -> 243 bytes
-rw-r--r--lib/inets/test/httpd_SUITE_data/server_root/icons/p.gifbin0 -> 237 bytes
-rw-r--r--lib/inets/test/httpd_SUITE_data/server_root/icons/patch.gifbin0 -> 251 bytes
-rw-r--r--lib/inets/test/httpd_SUITE_data/server_root/icons/pdf.gifbin0 -> 249 bytes
-rw-r--r--lib/inets/test/httpd_SUITE_data/server_root/icons/pie0.gifbin0 -> 188 bytes
-rw-r--r--lib/inets/test/httpd_SUITE_data/server_root/icons/pie1.gifbin0 -> 198 bytes
-rw-r--r--lib/inets/test/httpd_SUITE_data/server_root/icons/pie2.gifbin0 -> 198 bytes
-rw-r--r--lib/inets/test/httpd_SUITE_data/server_root/icons/pie3.gifbin0 -> 191 bytes
-rw-r--r--lib/inets/test/httpd_SUITE_data/server_root/icons/pie4.gifbin0 -> 193 bytes
-rw-r--r--lib/inets/test/httpd_SUITE_data/server_root/icons/pie5.gifbin0 -> 189 bytes
-rw-r--r--lib/inets/test/httpd_SUITE_data/server_root/icons/pie6.gifbin0 -> 186 bytes
-rw-r--r--lib/inets/test/httpd_SUITE_data/server_root/icons/pie7.gifbin0 -> 185 bytes
-rw-r--r--lib/inets/test/httpd_SUITE_data/server_root/icons/pie8.gifbin0 -> 173 bytes
-rw-r--r--lib/inets/test/httpd_SUITE_data/server_root/icons/portal.gifbin0 -> 254 bytes
-rw-r--r--lib/inets/test/httpd_SUITE_data/server_root/icons/poweredby.gifbin0 -> 2748 bytes
-rw-r--r--lib/inets/test/httpd_SUITE_data/server_root/icons/ps.gifbin0 -> 244 bytes
-rw-r--r--lib/inets/test/httpd_SUITE_data/server_root/icons/quill.gifbin0 -> 267 bytes
-rw-r--r--lib/inets/test/httpd_SUITE_data/server_root/icons/right.gifbin0 -> 172 bytes
-rw-r--r--lib/inets/test/httpd_SUITE_data/server_root/icons/screw1.gifbin0 -> 258 bytes
-rw-r--r--lib/inets/test/httpd_SUITE_data/server_root/icons/screw2.gifbin0 -> 263 bytes
-rw-r--r--lib/inets/test/httpd_SUITE_data/server_root/icons/script.gifbin0 -> 242 bytes
-rw-r--r--lib/inets/test/httpd_SUITE_data/server_root/icons/sound1.gifbin0 -> 248 bytes
-rw-r--r--lib/inets/test/httpd_SUITE_data/server_root/icons/sound2.gifbin0 -> 221 bytes
-rw-r--r--lib/inets/test/httpd_SUITE_data/server_root/icons/sphere1.gifbin0 -> 285 bytes
-rw-r--r--lib/inets/test/httpd_SUITE_data/server_root/icons/sphere2.gifbin0 -> 264 bytes
-rw-r--r--lib/inets/test/httpd_SUITE_data/server_root/icons/star.gifbin0 -> 89 bytes
-rw-r--r--lib/inets/test/httpd_SUITE_data/server_root/icons/star_blank.gifbin0 -> 53 bytes
-rw-r--r--lib/inets/test/httpd_SUITE_data/server_root/icons/tar.gifbin0 -> 243 bytes
-rw-r--r--lib/inets/test/httpd_SUITE_data/server_root/icons/tex.gifbin0 -> 251 bytes
-rw-r--r--lib/inets/test/httpd_SUITE_data/server_root/icons/text.gifbin0 -> 229 bytes
-rw-r--r--lib/inets/test/httpd_SUITE_data/server_root/icons/transfer.gifbin0 -> 242 bytes
-rw-r--r--lib/inets/test/httpd_SUITE_data/server_root/icons/unknown.gifbin0 -> 245 bytes
-rw-r--r--lib/inets/test/httpd_SUITE_data/server_root/icons/up.gifbin0 -> 164 bytes
-rw-r--r--lib/inets/test/httpd_SUITE_data/server_root/icons/uu.gifbin0 -> 236 bytes
-rw-r--r--lib/inets/test/httpd_SUITE_data/server_root/icons/uuencoded.gifbin0 -> 236 bytes
-rw-r--r--lib/inets/test/httpd_SUITE_data/server_root/icons/world1.gifbin0 -> 228 bytes
-rw-r--r--lib/inets/test/httpd_SUITE_data/server_root/icons/world2.gifbin0 -> 261 bytes
-rw-r--r--lib/inets/test/httpd_SUITE_data/server_root/logs/Dummy_File_Needed_By_WinZip1
-rw-r--r--lib/inets/test/httpd_SUITE_data/server_root/ssl/ssl_client.pem22
-rw-r--r--lib/inets/test/httpd_SUITE_data/server_root/ssl/ssl_server.pem22
-rw-r--r--lib/inets/test/httpd_basic_SUITE.erl281
-rw-r--r--lib/inets/test/httpd_block.erl299
-rw-r--r--lib/inets/test/httpd_load.erl99
-rw-r--r--lib/inets/test/httpd_mod.erl947
-rw-r--r--lib/inets/test/httpd_poll.erl496
-rw-r--r--lib/inets/test/httpd_test_data/server_root/auth/group3
-rw-r--r--lib/inets/test/httpd_test_data/server_root/auth/passwd4
-rw-r--r--lib/inets/test/httpd_test_data/server_root/cgi-bin/printenv.bat9
-rwxr-xr-xlib/inets/test/httpd_test_data/server_root/cgi-bin/printenv.sh6
-rw-r--r--lib/inets/test/httpd_test_data/server_root/conf/8080.conf79
-rw-r--r--lib/inets/test/httpd_test_data/server_root/conf/8888.conf63
-rw-r--r--lib/inets/test/httpd_test_data/server_root/conf/httpd.conf268
-rw-r--r--lib/inets/test/httpd_test_data/server_root/conf/mime.types465
-rw-r--r--lib/inets/test/httpd_test_data/server_root/conf/ssl.conf66
-rw-r--r--lib/inets/test/httpd_test_data/server_root/htdocs/config.shtml70
-rw-r--r--lib/inets/test/httpd_test_data/server_root/htdocs/dets_open/dummy.html10
-rw-r--r--lib/inets/test/httpd_test_data/server_root/htdocs/dets_secret/dummy.html10
-rw-r--r--lib/inets/test/httpd_test_data/server_root/htdocs/dets_secret/top_secret/index.html9
-rw-r--r--lib/inets/test/httpd_test_data/server_root/htdocs/echo.shtml35
-rw-r--r--lib/inets/test/httpd_test_data/server_root/htdocs/exec.shtml30
-rw-r--r--lib/inets/test/httpd_test_data/server_root/htdocs/flastmod.shtml29
-rw-r--r--lib/inets/test/httpd_test_data/server_root/htdocs/fsize.shtml29
-rw-r--r--lib/inets/test/httpd_test_data/server_root/htdocs/include.shtml33
-rw-r--r--lib/inets/test/httpd_test_data/server_root/htdocs/index.html25
-rw-r--r--lib/inets/test/httpd_test_data/server_root/htdocs/last_modified.html22
-rw-r--r--lib/inets/test/httpd_test_data/server_root/htdocs/misc/friedrich.html7
-rw-r--r--lib/inets/test/httpd_test_data/server_root/htdocs/misc/oech.html4
-rw-r--r--lib/inets/test/httpd_test_data/server_root/htdocs/misc/welcome.html1
-rw-r--r--lib/inets/test/httpd_test_data/server_root/htdocs/mnesia_open/dummy.html10
-rw-r--r--lib/inets/test/httpd_test_data/server_root/htdocs/mnesia_secret/dummy.html10
-rw-r--r--lib/inets/test/httpd_test_data/server_root/htdocs/mnesia_secret/top_secret/index.html9
-rw-r--r--lib/inets/test/httpd_test_data/server_root/htdocs/open/dummy.html10
-rw-r--r--lib/inets/test/httpd_test_data/server_root/htdocs/secret/dummy.html10
-rw-r--r--lib/inets/test/httpd_test_data/server_root/htdocs/secret/top_secret/index.html9
-rw-r--r--lib/inets/test/httpd_test_data/server_root/icons/README161
-rw-r--r--lib/inets/test/httpd_test_data/server_root/icons/a.gifbin0 -> 246 bytes
-rw-r--r--lib/inets/test/httpd_test_data/server_root/icons/alert.black.gifbin0 -> 242 bytes
-rw-r--r--lib/inets/test/httpd_test_data/server_root/icons/alert.red.gifbin0 -> 247 bytes
-rw-r--r--lib/inets/test/httpd_test_data/server_root/icons/apache_pb.gifbin0 -> 2326 bytes
-rw-r--r--lib/inets/test/httpd_test_data/server_root/icons/back.gifbin0 -> 216 bytes
-rw-r--r--lib/inets/test/httpd_test_data/server_root/icons/ball.gray.gifbin0 -> 233 bytes
-rw-r--r--lib/inets/test/httpd_test_data/server_root/icons/ball.red.gifbin0 -> 205 bytes
-rw-r--r--lib/inets/test/httpd_test_data/server_root/icons/binary.gifbin0 -> 246 bytes
-rw-r--r--lib/inets/test/httpd_test_data/server_root/icons/binhex.gifbin0 -> 246 bytes
-rw-r--r--lib/inets/test/httpd_test_data/server_root/icons/blank.gifbin0 -> 148 bytes
-rw-r--r--lib/inets/test/httpd_test_data/server_root/icons/bomb.gifbin0 -> 308 bytes
-rw-r--r--lib/inets/test/httpd_test_data/server_root/icons/box1.gifbin0 -> 251 bytes
-rw-r--r--lib/inets/test/httpd_test_data/server_root/icons/box2.gifbin0 -> 268 bytes
-rw-r--r--lib/inets/test/httpd_test_data/server_root/icons/broken.gifbin0 -> 247 bytes
-rw-r--r--lib/inets/test/httpd_test_data/server_root/icons/burst.gifbin0 -> 235 bytes
-rw-r--r--lib/inets/test/httpd_test_data/server_root/icons/button1.gifbin0 -> 755 bytes
-rw-r--r--lib/inets/test/httpd_test_data/server_root/icons/button10.gifbin0 -> 781 bytes
-rw-r--r--lib/inets/test/httpd_test_data/server_root/icons/button2.gifbin0 -> 785 bytes
-rw-r--r--lib/inets/test/httpd_test_data/server_root/icons/button3.gifbin0 -> 745 bytes
-rw-r--r--lib/inets/test/httpd_test_data/server_root/icons/button4.gifbin0 -> 786 bytes
-rw-r--r--lib/inets/test/httpd_test_data/server_root/icons/button5.gifbin0 -> 780 bytes
-rw-r--r--lib/inets/test/httpd_test_data/server_root/icons/button6.gifbin0 -> 791 bytes
-rw-r--r--lib/inets/test/httpd_test_data/server_root/icons/button7.gifbin0 -> 796 bytes
-rw-r--r--lib/inets/test/httpd_test_data/server_root/icons/button8.gifbin0 -> 784 bytes
-rw-r--r--lib/inets/test/httpd_test_data/server_root/icons/button9.gifbin0 -> 784 bytes
-rw-r--r--lib/inets/test/httpd_test_data/server_root/icons/buttonl.gifbin0 -> 587 bytes
-rw-r--r--lib/inets/test/httpd_test_data/server_root/icons/buttonr.gifbin0 -> 576 bytes
-rw-r--r--lib/inets/test/httpd_test_data/server_root/icons/c.gifbin0 -> 242 bytes
-rw-r--r--lib/inets/test/httpd_test_data/server_root/icons/comp.blue.gifbin0 -> 251 bytes
-rw-r--r--lib/inets/test/httpd_test_data/server_root/icons/comp.gray.gifbin0 -> 246 bytes
-rw-r--r--lib/inets/test/httpd_test_data/server_root/icons/compressed.gifbin0 -> 1038 bytes
-rw-r--r--lib/inets/test/httpd_test_data/server_root/icons/continued.gifbin0 -> 214 bytes
-rw-r--r--lib/inets/test/httpd_test_data/server_root/icons/dir.gifbin0 -> 225 bytes
-rw-r--r--lib/inets/test/httpd_test_data/server_root/icons/down.gifbin0 -> 163 bytes
-rw-r--r--lib/inets/test/httpd_test_data/server_root/icons/dvi.gifbin0 -> 238 bytes
-rw-r--r--lib/inets/test/httpd_test_data/server_root/icons/f.gifbin0 -> 236 bytes
-rw-r--r--lib/inets/test/httpd_test_data/server_root/icons/folder.gifbin0 -> 225 bytes
-rw-r--r--lib/inets/test/httpd_test_data/server_root/icons/folder.open.gifbin0 -> 242 bytes
-rw-r--r--lib/inets/test/httpd_test_data/server_root/icons/folder.sec.gifbin0 -> 243 bytes
-rw-r--r--lib/inets/test/httpd_test_data/server_root/icons/forward.gifbin0 -> 219 bytes
-rw-r--r--lib/inets/test/httpd_test_data/server_root/icons/generic.gifbin0 -> 221 bytes
-rw-r--r--lib/inets/test/httpd_test_data/server_root/icons/generic.red.gifbin0 -> 220 bytes
-rw-r--r--lib/inets/test/httpd_test_data/server_root/icons/generic.sec.gifbin0 -> 249 bytes
-rw-r--r--lib/inets/test/httpd_test_data/server_root/icons/hand.right.gifbin0 -> 217 bytes
-rw-r--r--lib/inets/test/httpd_test_data/server_root/icons/hand.up.gifbin0 -> 223 bytes
-rw-r--r--lib/inets/test/httpd_test_data/server_root/icons/htdig.gifbin0 -> 1822 bytes
-rw-r--r--lib/inets/test/httpd_test_data/server_root/icons/icon.sheet.gifbin0 -> 11977 bytes
-rw-r--r--lib/inets/test/httpd_test_data/server_root/icons/image1.gifbin0 -> 274 bytes
-rw-r--r--lib/inets/test/httpd_test_data/server_root/icons/image2.gifbin0 -> 309 bytes
-rw-r--r--lib/inets/test/httpd_test_data/server_root/icons/image3.gifbin0 -> 286 bytes
-rw-r--r--lib/inets/test/httpd_test_data/server_root/icons/index.gifbin0 -> 268 bytes
-rw-r--r--lib/inets/test/httpd_test_data/server_root/icons/layout.gifbin0 -> 276 bytes
-rw-r--r--lib/inets/test/httpd_test_data/server_root/icons/left.gifbin0 -> 172 bytes
-rw-r--r--lib/inets/test/httpd_test_data/server_root/icons/link.gifbin0 -> 249 bytes
-rw-r--r--lib/inets/test/httpd_test_data/server_root/icons/movie.gifbin0 -> 243 bytes
-rw-r--r--lib/inets/test/httpd_test_data/server_root/icons/p.gifbin0 -> 237 bytes
-rw-r--r--lib/inets/test/httpd_test_data/server_root/icons/patch.gifbin0 -> 251 bytes
-rw-r--r--lib/inets/test/httpd_test_data/server_root/icons/pdf.gifbin0 -> 249 bytes
-rw-r--r--lib/inets/test/httpd_test_data/server_root/icons/pie0.gifbin0 -> 188 bytes
-rw-r--r--lib/inets/test/httpd_test_data/server_root/icons/pie1.gifbin0 -> 198 bytes
-rw-r--r--lib/inets/test/httpd_test_data/server_root/icons/pie2.gifbin0 -> 198 bytes
-rw-r--r--lib/inets/test/httpd_test_data/server_root/icons/pie3.gifbin0 -> 191 bytes
-rw-r--r--lib/inets/test/httpd_test_data/server_root/icons/pie4.gifbin0 -> 193 bytes
-rw-r--r--lib/inets/test/httpd_test_data/server_root/icons/pie5.gifbin0 -> 189 bytes
-rw-r--r--lib/inets/test/httpd_test_data/server_root/icons/pie6.gifbin0 -> 186 bytes
-rw-r--r--lib/inets/test/httpd_test_data/server_root/icons/pie7.gifbin0 -> 185 bytes
-rw-r--r--lib/inets/test/httpd_test_data/server_root/icons/pie8.gifbin0 -> 173 bytes
-rw-r--r--lib/inets/test/httpd_test_data/server_root/icons/portal.gifbin0 -> 254 bytes
-rw-r--r--lib/inets/test/httpd_test_data/server_root/icons/poweredby.gifbin0 -> 2748 bytes
-rw-r--r--lib/inets/test/httpd_test_data/server_root/icons/ps.gifbin0 -> 244 bytes
-rw-r--r--lib/inets/test/httpd_test_data/server_root/icons/quill.gifbin0 -> 267 bytes
-rw-r--r--lib/inets/test/httpd_test_data/server_root/icons/right.gifbin0 -> 172 bytes
-rw-r--r--lib/inets/test/httpd_test_data/server_root/icons/screw1.gifbin0 -> 258 bytes
-rw-r--r--lib/inets/test/httpd_test_data/server_root/icons/screw2.gifbin0 -> 263 bytes
-rw-r--r--lib/inets/test/httpd_test_data/server_root/icons/script.gifbin0 -> 242 bytes
-rw-r--r--lib/inets/test/httpd_test_data/server_root/icons/sound1.gifbin0 -> 248 bytes
-rw-r--r--lib/inets/test/httpd_test_data/server_root/icons/sound2.gifbin0 -> 221 bytes
-rw-r--r--lib/inets/test/httpd_test_data/server_root/icons/sphere1.gifbin0 -> 285 bytes
-rw-r--r--lib/inets/test/httpd_test_data/server_root/icons/sphere2.gifbin0 -> 264 bytes
-rw-r--r--lib/inets/test/httpd_test_data/server_root/icons/star.gifbin0 -> 89 bytes
-rw-r--r--lib/inets/test/httpd_test_data/server_root/icons/star_blank.gifbin0 -> 53 bytes
-rw-r--r--lib/inets/test/httpd_test_data/server_root/icons/tar.gifbin0 -> 243 bytes
-rw-r--r--lib/inets/test/httpd_test_data/server_root/icons/tex.gifbin0 -> 251 bytes
-rw-r--r--lib/inets/test/httpd_test_data/server_root/icons/text.gifbin0 -> 229 bytes
-rw-r--r--lib/inets/test/httpd_test_data/server_root/icons/transfer.gifbin0 -> 242 bytes
-rw-r--r--lib/inets/test/httpd_test_data/server_root/icons/unknown.gifbin0 -> 245 bytes
-rw-r--r--lib/inets/test/httpd_test_data/server_root/icons/up.gifbin0 -> 164 bytes
-rw-r--r--lib/inets/test/httpd_test_data/server_root/icons/uu.gifbin0 -> 236 bytes
-rw-r--r--lib/inets/test/httpd_test_data/server_root/icons/uuencoded.gifbin0 -> 236 bytes
-rw-r--r--lib/inets/test/httpd_test_data/server_root/icons/world1.gifbin0 -> 228 bytes
-rw-r--r--lib/inets/test/httpd_test_data/server_root/icons/world2.gifbin0 -> 261 bytes
-rw-r--r--lib/inets/test/httpd_test_data/server_root/logs/Dummy_File_Needed_By_WinZip1
-rw-r--r--lib/inets/test/httpd_test_data/server_root/ssl/ssl_client.pem22
-rw-r--r--lib/inets/test/httpd_test_data/server_root/ssl/ssl_server.pem22
-rw-r--r--lib/inets/test/httpd_test_lib.erl379
-rw-r--r--lib/inets/test/httpd_time_test.erl500
-rw-r--r--lib/inets/test/inets.config1
-rw-r--r--lib/inets/test/inets.spec2
-rw-r--r--lib/inets/test/inets.spec.vxworks5
-rw-r--r--lib/inets/test/inets_SUITE.erl583
-rw-r--r--lib/inets/test/inets_SUITE_data/.gitignore0
-rw-r--r--lib/inets/test/inets_app_test.erl296
-rw-r--r--lib/inets/test/inets_appup_test.erl336
l---------lib/inets/test/inets_internal.hrl1
-rw-r--r--lib/inets/test/inets_sup_SUITE.erl414
-rw-r--r--lib/inets/test/inets_sup_SUITE_data/mime.types3
-rw-r--r--lib/inets/test/inets_sup_SUITE_data/simple.conf6
-rw-r--r--lib/inets/test/inets_test_lib.erl355
-rw-r--r--lib/inets/test/inets_test_lib.hrl104
-rw-r--r--lib/inets/test/rules.mk59
-rw-r--r--lib/inets/test/tftp_SUITE.erl903
-rw-r--r--lib/inets/test/tftp_test_lib.erl307
-rw-r--r--lib/inets/test/tftp_test_lib.hrl43
-rw-r--r--lib/inets/vsn.mk131
-rw-r--r--lib/jinterface/doc/src/Makefile13
-rw-r--r--lib/jinterface/doc/src/notes.xml37
-rw-r--r--lib/jinterface/test/Makefile84
-rw-r--r--lib/jinterface/test/jinterface.dynspec32
-rw-r--r--lib/jinterface/test/jinterface_SUITE.erl761
-rw-r--r--lib/jinterface/test/jinterface_SUITE_data/BooleanAtom.java46
-rw-r--r--lib/jinterface/test/jinterface_SUITE_data/GetNames.java68
-rw-r--r--lib/jinterface/test/jinterface_SUITE_data/Makefile.src62
-rw-r--r--lib/jinterface/test/jinterface_SUITE_data/MboxLinkUnlink.java201
-rw-r--r--lib/jinterface/test/jinterface_SUITE_data/MboxPing.java50
-rw-r--r--lib/jinterface/test/jinterface_SUITE_data/MboxSendReceive.java229
-rw-r--r--lib/jinterface/test/jinterface_SUITE_data/NodePing.java83
-rw-r--r--lib/jinterface/test/jinterface_SUITE_data/NodeStatusHandler.java168
-rw-r--r--lib/jinterface/test/jinterface_SUITE_data/Nodename.java54
-rw-r--r--lib/jinterface/test/jinterface_SUITE_data/RegisterAndWhereis.java79
-rw-r--r--lib/jinterface/test/jitu.erl156
-rw-r--r--lib/jinterface/test/nc_SUITE.erl736
-rw-r--r--lib/jinterface/test/nc_SUITE_data/Makefile.src53
-rw-r--r--lib/jinterface/test/nc_SUITE_data/connection_server.java96
-rw-r--r--lib/jinterface/test/nc_SUITE_data/echo_server.java261
-rw-r--r--lib/jinterface/vsn.mk20
-rw-r--r--lib/kernel/doc/src/file.xml2
-rw-r--r--lib/kernel/doc/src/gen_sctp.xml119
-rw-r--r--lib/kernel/doc/src/inet.xml4
-rw-r--r--lib/kernel/doc/src/notes.xml173
-rw-r--r--lib/kernel/src/Makefile15
-rw-r--r--lib/kernel/src/code.erl27
-rw-r--r--lib/kernel/src/code_server.erl41
-rw-r--r--lib/kernel/src/file.erl11
-rw-r--r--lib/kernel/src/gen_sctp.erl46
-rw-r--r--lib/kernel/src/hipe_unified_loader.erl42
-rw-r--r--lib/kernel/src/inet.erl147
-rw-r--r--lib/kernel/src/inet_config.erl32
-rw-r--r--lib/kernel/src/inet_db.erl107
-rw-r--r--lib/kernel/src/inet_gethost_native.erl72
-rw-r--r--lib/kernel/src/inet_parse.erl285
-rw-r--r--lib/kernel/src/inet_sctp.erl30
-rw-r--r--lib/kernel/src/net_kernel.erl112
-rw-r--r--lib/kernel/src/os.erl59
-rw-r--r--lib/kernel/src/pg2.erl17
-rw-r--r--lib/kernel/src/user.erl16
-rw-r--r--lib/kernel/test/Makefile12
-rw-r--r--lib/kernel/test/bif_SUITE.erl44
-rw-r--r--lib/kernel/test/cleanup.erl12
-rw-r--r--lib/kernel/test/code_SUITE.erl137
-rw-r--r--lib/kernel/test/code_SUITE_data/clash/foobar-0.1.ezbin0 -> 505 bytes
-rw-r--r--lib/kernel/test/code_SUITE_data/clash/foobar-0.1/ebin/baz.beam1
-rw-r--r--lib/kernel/test/code_SUITE_data/clash/foobar-0.1/ebin/blarg.beam1
-rw-r--r--lib/kernel/test/code_SUITE_data/clash/zork-0.8.ezbin0 -> 492 bytes
-rw-r--r--lib/kernel/test/code_SUITE_data/clash/zork-0.8/ebin/bork.beam1
-rw-r--r--lib/kernel/test/code_SUITE_data/clash/zork-0.8/ebin/flarp.beam1
-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/kernel/test/erl_distribution_SUITE.erl48
-rw-r--r--lib/kernel/test/erl_prim_loader_SUITE.erl74
-rw-r--r--lib/kernel/test/error_logger_SUITE.erl32
-rw-r--r--lib/kernel/test/file_SUITE.erl12
-rw-r--r--lib/kernel/test/gen_sctp_SUITE.erl111
-rw-r--r--lib/kernel/test/global_group_SUITE.erl30
-rw-r--r--lib/kernel/test/heart_SUITE.erl16
-rw-r--r--lib/kernel/test/inet_SUITE.erl198
-rw-r--r--lib/kernel/test/inet_res_SUITE.erl88
-rw-r--r--lib/kernel/test/init_SUITE.erl14
-rw-r--r--lib/kernel/test/kernel_SUITE.erl12
-rw-r--r--lib/kernel/test/kernel_config_SUITE.erl12
-rw-r--r--lib/kernel/test/loose_node.erl27
-rw-r--r--lib/kernel/test/os_SUITE.erl70
-rw-r--r--lib/kernel/test/pdict_SUITE.erl14
-rw-r--r--lib/kernel/test/ram_file_SUITE.erl37
-rw-r--r--lib/kernel/test/rpc_SUITE.erl14
-rw-r--r--lib/kernel/test/seq_trace_SUITE.erl16
-rw-r--r--lib/kernel/test/wrap_log_reader_SUITE.erl30
-rw-r--r--lib/kernel/vsn.mk2
-rw-r--r--lib/megaco/configure.in113
-rw-r--r--lib/megaco/doc/src/Makefile19
-rw-r--r--lib/megaco/doc/src/megaco.xml16
-rw-r--r--lib/megaco/doc/src/megaco_codec_transform.xml27
-rw-r--r--lib/megaco/doc/src/megaco_debug.xml28
-rw-r--r--lib/megaco/doc/src/megaco_mib.xml12
-rw-r--r--lib/megaco/doc/src/megaco_performance.xml18
-rw-r--r--lib/megaco/doc/src/megaco_run.xml8
-rw-r--r--lib/megaco/doc/src/megaco_user.xml11
-rw-r--r--lib/megaco/doc/src/notes.xml133
-rw-r--r--lib/megaco/doc/src/notes_history.xml10
-rw-r--r--lib/megaco/doc/standard/H.248.1-Corr1-200403.docbin296448 -> 0 bytes
-rw-r--r--lib/megaco/doc/standard/rfc2327.txt2355
-rw-r--r--lib/megaco/doc/standard/rfc3266.txt283
-rw-r--r--lib/megaco/examples/meas/meas.sh.skel12
-rw-r--r--lib/megaco/include/megaco.hrl19
-rw-r--r--lib/megaco/src/app/megaco.appup.src69
-rw-r--r--lib/megaco/src/app/megaco_internal.hrl26
-rw-r--r--lib/megaco/src/engine/megaco_config.erl439
-rw-r--r--lib/megaco/src/engine/megaco_filter.erl286
-rw-r--r--lib/megaco/src/engine/megaco_messenger.erl542
-rw-r--r--lib/megaco/src/engine/megaco_monitor.erl33
-rw-r--r--lib/megaco/src/flex/Makefile.in82
-rw-r--r--lib/megaco/src/flex/megaco_flex_scanner_drv.flex.src7
-rw-r--r--lib/megaco/src/flex/megaco_flex_scanner_handler.erl45
-rw-r--r--lib/megaco/test/Makefile175
-rw-r--r--lib/megaco/test/megaco_app_test.erl14
-rw-r--r--lib/megaco/test/megaco_config_test.erl362
-rw-r--r--lib/megaco/test/modules.mk12
-rw-r--r--lib/megaco/vsn.mk30
-rw-r--r--lib/mnesia/doc/src/mnesia.xml23
-rw-r--r--lib/mnesia/doc/src/notes.xml35
-rw-r--r--lib/mnesia/src/mnesia.appup.src32
-rw-r--r--lib/mnesia/src/mnesia.erl12
-rw-r--r--lib/mnesia/src/mnesia_loader.erl45
-rw-r--r--lib/mnesia/src/mnesia_monitor.erl22
-rw-r--r--lib/mnesia/src/mnesia_tm.erl11
-rw-r--r--lib/mnesia/test/Makefile118
-rw-r--r--lib/mnesia/test/README107
-rw-r--r--lib/mnesia/test/mnesia.spec23
-rw-r--r--lib/mnesia/test/mnesia.spec.vxworks362
-rw-r--r--lib/mnesia/test/mnesia_SUITE.erl203
-rw-r--r--lib/mnesia/test/mnesia_atomicity_test.erl839
-rw-r--r--lib/mnesia/test/mnesia_config_backup.erl105
-rw-r--r--lib/mnesia/test/mnesia_config_event.erl74
-rw-r--r--lib/mnesia/test/mnesia_config_test.erl1466
-rw-r--r--lib/mnesia/test/mnesia_consistency_test.erl1612
-rw-r--r--lib/mnesia/test/mnesia_cost.erl222
-rw-r--r--lib/mnesia/test/mnesia_dbn_meters.erl242
-rw-r--r--lib/mnesia/test/mnesia_dirty_access_test.erl927
-rw-r--r--lib/mnesia/test/mnesia_durability_test.erl1470
-rw-r--r--lib/mnesia/test/mnesia_evil_backup.erl750
-rw-r--r--lib/mnesia/test/mnesia_evil_coverage_test.erl2167
-rw-r--r--lib/mnesia/test/mnesia_examples_test.erl160
-rw-r--r--lib/mnesia/test/mnesia_frag_test.erl875
-rw-r--r--lib/mnesia/test/mnesia_inconsistent_database_test.erl74
-rw-r--r--lib/mnesia/test/mnesia_install_test.erl342
-rw-r--r--lib/mnesia/test/mnesia_isolation_test.erl2419
-rw-r--r--lib/mnesia/test/mnesia_measure_test.erl203
-rw-r--r--lib/mnesia/test/mnesia_meter.erl465
-rw-r--r--lib/mnesia/test/mnesia_nice_coverage_test.erl227
-rw-r--r--lib/mnesia/test/mnesia_qlc_test.erl475
-rw-r--r--lib/mnesia/test/mnesia_recovery_test.erl1701
-rw-r--r--lib/mnesia/test/mnesia_registry_test.erl137
-rw-r--r--lib/mnesia/test/mnesia_schema_recovery_test.erl787
-rw-r--r--lib/mnesia/test/mnesia_test_lib.erl1058
-rw-r--r--lib/mnesia/test/mnesia_test_lib.hrl132
-rw-r--r--lib/mnesia/test/mnesia_tpcb.erl1268
-rw-r--r--lib/mnesia/test/mnesia_trans_access_test.erl1254
-rwxr-xr-xlib/mnesia/test/mt60
-rw-r--r--lib/mnesia/test/mt.erl262
-rw-r--r--lib/mnesia/vsn.mk5
-rw-r--r--lib/observer/doc/src/notes.xml21
-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/observer/vsn.mk2
l---------lib/odbc/aclocal.m41
-rw-r--r--lib/odbc/c_src/Makefile.in22
-rw-r--r--lib/odbc/c_src/odbcserver.c37
-rw-r--r--lib/odbc/configure.in160
-rw-r--r--lib/odbc/doc/src/Makefile13
-rw-r--r--lib/odbc/doc/src/notes.xml128
-rw-r--r--lib/odbc/vsn.mk4
-rw-r--r--lib/orber/COSS/CosNaming/orber_cosnaming_utils.erl13
-rw-r--r--lib/orber/doc/src/CosNaming.xml26
-rw-r--r--lib/orber/doc/src/Makefile17
-rw-r--r--lib/orber/doc/src/ch_contents.xml4
-rw-r--r--lib/orber/doc/src/ch_example.xml170
-rw-r--r--lib/orber/doc/src/ch_idl_to_erlang_mapping.xml93
-rw-r--r--lib/orber/doc/src/ch_install.xml29
-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/example_part.xml25
-rw-r--r--lib/orber/doc/src/make.dep9
-rw-r--r--lib/orber/doc/src/notes.xml151
-rw-r--r--lib/orber/doc/src/notes_history.xml1523
-rw-r--r--lib/orber/doc/src/orber.xml32
-rw-r--r--lib/orber/doc/src/part.xml7
-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/src/cdr_decode.erl78
-rw-r--r--lib/orber/src/cdr_encode.erl30
-rw-r--r--lib/orber/src/orber.erl19
-rw-r--r--lib/orber/src/orber_env.erl42
-rw-r--r--lib/orber/src/orber_socket.erl74
-rw-r--r--lib/orber/test/Makefile232
-rw-r--r--lib/orber/test/cdrcoding_10_SUITE.erl616
-rw-r--r--lib/orber/test/cdrcoding_11_SUITE.erl615
-rw-r--r--lib/orber/test/cdrcoding_12_SUITE.erl603
-rw-r--r--lib/orber/test/cdrlib_SUITE.erl487
-rw-r--r--lib/orber/test/corba_SUITE.erl909
-rw-r--r--lib/orber/test/csiv2_SUITE.erl940
-rw-r--r--lib/orber/test/data_types_SUITE.erl173
-rw-r--r--lib/orber/test/generated_SUITE.erl385
-rw-r--r--lib/orber/test/idl_output/.gitignore0
-rw-r--r--lib/orber/test/iiop_module_do_test_impl.erl112
-rw-r--r--lib/orber/test/iiop_module_test_impl.erl128
-rw-r--r--lib/orber/test/iiop_test.idl111
-rw-r--r--lib/orber/test/iiop_test_impl.erl34
-rw-r--r--lib/orber/test/interceptors_SUITE.erl338
-rw-r--r--lib/orber/test/iop_ior_10_SUITE.erl167
-rw-r--r--lib/orber/test/iop_ior_11_SUITE.erl186
-rw-r--r--lib/orber/test/iop_ior_12_SUITE.erl187
-rw-r--r--lib/orber/test/lname_SUITE.erl198
-rw-r--r--lib/orber/test/multi_ORB_SUITE.erl2352
-rw-r--r--lib/orber/test/naming_context_SUITE.erl385
-rw-r--r--lib/orber/test/orber.spec19
-rw-r--r--lib/orber/test/orber_SUITE.erl179
-rw-r--r--lib/orber/test/orber_acl_SUITE.erl303
-rw-r--r--lib/orber/test/orber_firewall_ipv4_in_SUITE.erl280
-rw-r--r--lib/orber/test/orber_firewall_ipv4_out_SUITE.erl224
-rw-r--r--lib/orber/test/orber_firewall_ipv6_in_SUITE.erl311
-rw-r--r--lib/orber/test/orber_firewall_ipv6_out_SUITE.erl231
-rw-r--r--lib/orber/test/orber_nat_SUITE.erl372
-rw-r--r--lib/orber/test/orber_test.idl95
-rw-r--r--lib/orber/test/orber_test_lib.erl1514
-rw-r--r--lib/orber/test/orber_test_server.cfg27
-rw-r--r--lib/orber/test/orber_test_server.idl176
-rw-r--r--lib/orber/test/orber_test_server_impl.erl275
-rw-r--r--lib/orber/test/orber_test_timeout_server_impl.erl65
-rw-r--r--lib/orber/test/orber_web_SUITE.erl443
-rw-r--r--lib/orber/test/tc_SUITE.erl661
-rw-r--r--lib/orber/vsn.mk11
-rw-r--r--lib/os_mon/doc/src/notes.xml22
-rw-r--r--lib/os_mon/src/cpu_sup.erl37
-rw-r--r--lib/os_mon/test/Makefile92
-rw-r--r--lib/os_mon/test/cpu_sup_SUITE.erl282
-rw-r--r--lib/os_mon/test/disksup_SUITE.erl426
-rw-r--r--lib/os_mon/test/memsup_SUITE.erl782
-rw-r--r--lib/os_mon/test/os_mon.spec1
-rw-r--r--lib/os_mon/test/os_mon_SUITE.erl89
-rw-r--r--lib/os_mon/test/os_mon_conf.erl28
-rw-r--r--lib/os_mon/test/os_mon_mib_SUITE.erl746
-rw-r--r--lib/os_mon/test/os_sup_SUITE.erl189
-rw-r--r--lib/os_mon/vsn.mk2
-rw-r--r--lib/parsetools/doc/src/leex.xml38
-rw-r--r--lib/parsetools/doc/src/notes.xml22
-rw-r--r--lib/parsetools/include/yeccpre.hrl39
-rw-r--r--lib/parsetools/src/yecc.erl49
-rw-r--r--lib/parsetools/src/yeccparser.erl39
-rw-r--r--lib/parsetools/test/Makefile78
-rw-r--r--lib/parsetools/test/leex_SUITE.erl909
-rw-r--r--lib/parsetools/test/parsetools.spec1
-rw-r--r--lib/parsetools/test/yecc_SUITE.erl1795
-rw-r--r--lib/parsetools/vsn.mk2
-rw-r--r--lib/percept/doc/src/Makefile14
-rw-r--r--lib/percept/doc/src/notes.xml54
-rw-r--r--lib/percept/src/egd.erl42
-rw-r--r--lib/percept/src/egd.hrl16
-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.erl198
-rw-r--r--lib/percept/src/percept.erl56
-rw-r--r--lib/percept/src/percept.hrl21
-rw-r--r--lib/percept/src/percept_db.erl31
-rw-r--r--lib/percept/src/percept_html.erl52
-rw-r--r--lib/percept/test/egd_SUITE.erl57
-rw-r--r--lib/percept/vsn.mk2
-rw-r--r--lib/public_key/asn1/Makefile14
-rw-r--r--lib/public_key/asn1/OTP-PUB-KEY.set.asn1
-rw-r--r--lib/public_key/asn1/PKCS-3.asn121
-rw-r--r--lib/public_key/doc/src/Makefile13
-rw-r--r--lib/public_key/doc/src/cert_records.xml34
-rw-r--r--lib/public_key/doc/src/notes.xml36
-rw-r--r--lib/public_key/src/pubkey_cert.erl35
-rw-r--r--lib/public_key/src/pubkey_cert_records.erl12
-rw-r--r--lib/public_key/src/pubkey_crypto.erl59
-rw-r--r--lib/public_key/src/pubkey_pem.erl12
-rw-r--r--lib/public_key/src/public_key.appup.src34
-rw-r--r--lib/public_key/src/public_key.erl73
-rw-r--r--lib/public_key/test/Makefile12
-rw-r--r--lib/public_key/test/public_key_SUITE.erl15
-rw-r--r--lib/public_key/vsn.mk8
-rw-r--r--lib/reltool/doc/src/Makefile30
-rw-r--r--lib/reltool/doc/src/book.gifbin1081 -> 0 bytes
-rw-r--r--lib/reltool/doc/src/fascicules.xml17
-rw-r--r--lib/reltool/doc/src/files.mk21
-rw-r--r--lib/reltool/doc/src/note.gifbin1539 -> 0 bytes
-rw-r--r--lib/reltool/doc/src/notes.gifbin2005 -> 0 bytes
-rw-r--r--lib/reltool/doc/src/notes.xml15
-rw-r--r--lib/reltool/doc/src/part_notes.xml41
-rw-r--r--lib/reltool/doc/src/ref_man.gifbin1530 -> 0 bytes
-rw-r--r--lib/reltool/doc/src/reltool_examples.xml32
-rw-r--r--lib/reltool/doc/src/user_guide.gifbin1581 -> 0 bytes
-rw-r--r--lib/reltool/doc/src/warning.gifbin1498 -> 0 bytes
-rw-r--r--lib/reltool/src/reltool_target.erl25
-rw-r--r--lib/reltool/test/Makefile82
-rw-r--r--lib/reltool/test/README30
-rw-r--r--lib/reltool/test/reltool.spec2
-rw-r--r--lib/reltool/test/reltool_server_SUITE.erl494
-rw-r--r--lib/reltool/test/reltool_test_lib.erl329
-rw-r--r--lib/reltool/test/reltool_test_lib.hrl91
-rw-r--r--lib/reltool/test/reltool_wx_SUITE.erl62
-rwxr-xr-xlib/reltool/test/rtt55
-rw-r--r--lib/reltool/test/rtt.erl154
-rw-r--r--lib/reltool/vsn.mk23
-rw-r--r--lib/runtime_tools/c_src/Makefile.in31
-rw-r--r--lib/runtime_tools/doc/src/notes.xml76
-rw-r--r--lib/runtime_tools/src/percept_profile.erl35
-rw-r--r--lib/runtime_tools/test/Makefile65
-rw-r--r--lib/runtime_tools/test/dbg_SUITE.erl901
-rw-r--r--lib/runtime_tools/test/dbg_SUITE_data/dbg_test.erl87
-rw-r--r--lib/runtime_tools/test/dbg_SUITE_data/exref_td.erl50
-rw-r--r--lib/runtime_tools/test/erts_alloc_config_SUITE.erl206
-rw-r--r--lib/runtime_tools/test/inviso_SUITE.erl2840
-rw-r--r--lib/runtime_tools/test/inviso_testmodule1_foo.erl9
-rw-r--r--lib/runtime_tools/test/runtime_tools.cover1
-rw-r--r--lib/runtime_tools/test/runtime_tools.spec1
-rw-r--r--lib/runtime_tools/test/runtime_tools_SUITE.erl50
-rw-r--r--lib/runtime_tools/vsn.mk2
-rw-r--r--lib/sasl/doc/src/notes.xml86
-rw-r--r--lib/sasl/doc/src/rb.xml86
-rw-r--r--lib/sasl/src/overload.erl22
-rw-r--r--lib/sasl/src/rb.erl259
-rw-r--r--lib/sasl/src/release_handler.erl47
-rw-r--r--lib/sasl/src/release_handler_1.erl18
-rw-r--r--lib/sasl/src/sasl.app.src12
-rw-r--r--lib/sasl/src/sasl.erl14
-rw-r--r--lib/sasl/src/sasl_report.erl50
-rw-r--r--lib/sasl/src/si_sasl_supp.erl24
-rw-r--r--lib/sasl/vsn.mk2
-rw-r--r--lib/snmp/doc/src/Makefile4
-rw-r--r--lib/snmp/doc/src/notes.xml486
-rw-r--r--lib/snmp/doc/src/notes_history.xml14
-rw-r--r--lib/snmp/doc/src/snmp_app.xml131
-rw-r--r--lib/snmp/doc/src/snmp_config.xml125
-rw-r--r--lib/snmp/doc/src/snmpa.xml58
-rw-r--r--lib/snmp/doc/src/snmpa_conf.xml6
-rw-r--r--lib/snmp/doc/src/snmpa_mpd.xml42
-rw-r--r--lib/snmp/doc/src/snmpa_network_interface_filter.xml8
-rw-r--r--lib/snmp/doc/src/snmpc.xml152
-rw-r--r--lib/snmp/doc/src/snmpm.xml261
-rw-r--r--lib/snmp/src/agent/depend.mk2
-rw-r--r--lib/snmp/src/agent/snmp_target_mib.erl16
-rw-r--r--lib/snmp/src/agent/snmpa.erl42
-rw-r--r--lib/snmp/src/agent/snmpa_agent.erl909
-rw-r--r--lib/snmp/src/agent/snmpa_general_db.erl19
-rw-r--r--lib/snmp/src/agent/snmpa_internal.hrl21
-rw-r--r--lib/snmp/src/agent/snmpa_local_db.erl10
-rw-r--r--lib/snmp/src/agent/snmpa_mib.erl24
-rw-r--r--lib/snmp/src/agent/snmpa_mib_lib.erl20
-rw-r--r--lib/snmp/src/agent/snmpa_mpd.erl238
-rw-r--r--lib/snmp/src/agent/snmpa_net_if.erl112
-rw-r--r--lib/snmp/src/agent/snmpa_supervisor.erl40
-rw-r--r--lib/snmp/src/agent/snmpa_trap.erl111
-rw-r--r--lib/snmp/src/agent/snmpa_usm.erl100
-rw-r--r--lib/snmp/src/agent/snmpa_vacm.erl18
-rw-r--r--lib/snmp/src/app/snmp.appup.src278
-rw-r--r--lib/snmp/src/compile/snmpc.erl187
-rw-r--r--lib/snmp/src/compile/snmpc_lib.erl13
-rw-r--r--lib/snmp/src/manager/snmpm.erl707
-rw-r--r--lib/snmp/src/manager/snmpm_config.erl65
-rw-r--r--lib/snmp/src/manager/snmpm_mpd.erl24
-rw-r--r--lib/snmp/src/manager/snmpm_net_if.erl113
-rw-r--r--lib/snmp/src/manager/snmpm_server.erl247
-rw-r--r--lib/snmp/src/misc/snmp_config.erl146
-rw-r--r--lib/snmp/src/misc/snmp_log.erl503
-rw-r--r--lib/snmp/src/misc/snmp_pdus.erl51
-rw-r--r--lib/snmp/src/misc/snmp_usm.erl34
-rw-r--r--lib/snmp/test/modules.mk14
-rw-r--r--lib/snmp/test/snmp_agent_test.erl755
-rw-r--r--lib/snmp/test/snmp_agent_test_lib.erl191
-rw-r--r--lib/snmp/test/snmp_compiler_test.erl70
-rw-r--r--lib/snmp/test/snmp_log_test.erl299
-rw-r--r--lib/snmp/test/snmp_manager_config_test.erl274
-rw-r--r--lib/snmp/test/snmp_manager_test.erl125
-rw-r--r--lib/snmp/test/snmp_manager_user_test.erl43
-rw-r--r--lib/snmp/test/snmp_pdus_test.erl64
-rw-r--r--lib/snmp/test/snmp_test_data/OLD-SNMPEA-MIB.mib18
-rw-r--r--lib/snmp/test/snmp_test_data/OTP8574-MIB.mib77
-rw-r--r--lib/snmp/test/snmp_test_data/OTP8595-MIB.mib45
-rw-r--r--lib/snmp/test/snmp_test_lib.erl22
-rw-r--r--lib/snmp/test/snmp_test_mgr.erl10
-rw-r--r--lib/snmp/test/snmp_test_mgr_misc.erl14
-rw-r--r--lib/snmp/vsn.mk178
-rw-r--r--lib/ssh/doc/src/Makefile19
-rw-r--r--lib/ssh/doc/src/notes.xml154
-rw-r--r--lib/ssh/doc/src/notes_history.xml737
-rw-r--r--lib/ssh/doc/src/part_notes.xml9
-rw-r--r--lib/ssh/doc/src/part_notes_history.xml36
-rw-r--r--lib/ssh/doc/src/ssh.xml17
-rw-r--r--lib/ssh/examples/ssh_sample_cli.erl66
-rw-r--r--lib/ssh/src/ssh.appup.src14
-rw-r--r--lib/ssh/src/ssh.erl18
-rw-r--r--lib/ssh/src/ssh_acceptor.erl14
-rw-r--r--lib/ssh/src/ssh_channel.erl24
-rw-r--r--lib/ssh/src/ssh_cli.erl40
-rwxr-xr-xlib/ssh/src/ssh_connect.hrl13
-rw-r--r--lib/ssh/src/ssh_connection.erl32
-rw-r--r--lib/ssh/src/ssh_connection_controler.erl18
-rw-r--r--lib/ssh/src/ssh_connection_handler.erl30
-rw-r--r--lib/ssh/src/ssh_connection_manager.erl36
-rw-r--r--lib/ssh/src/ssh_sftpd.erl19
-rw-r--r--lib/ssh/src/ssh_system_sup.erl22
-rw-r--r--lib/ssh/vsn.mk23
-rw-r--r--lib/ssl/c_src/Makefile.in22
-rw-r--r--lib/ssl/doc/src/Makefile13
-rw-r--r--lib/ssl/doc/src/create_certs.xml14
-rw-r--r--lib/ssl/doc/src/new_ssl.xml53
-rw-r--r--lib/ssl/doc/src/notes.xml124
-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/ssl/src/ssl.appup.src9
-rw-r--r--lib/ssl/src/ssl.erl95
-rw-r--r--lib/ssl/src/ssl_broker.erl16
-rw-r--r--lib/ssl/src/ssl_certificate.erl53
-rw-r--r--lib/ssl/src/ssl_certificate_db.erl53
-rw-r--r--lib/ssl/src/ssl_connection.erl932
-rw-r--r--lib/ssl/src/ssl_handshake.erl231
-rw-r--r--lib/ssl/src/ssl_handshake.hrl13
-rw-r--r--lib/ssl/src/ssl_internal.hrl14
-rw-r--r--lib/ssl/src/ssl_manager.erl37
-rw-r--r--lib/ssl/src/ssl_record.erl64
-rw-r--r--lib/ssl/src/ssl_record.hrl17
-rw-r--r--lib/ssl/src/ssl_ssl3.erl18
-rw-r--r--lib/ssl/src/ssl_tls1.erl20
-rw-r--r--lib/ssl/test/Makefile137
-rw-r--r--lib/ssl/test/make_certs.erl288
-rw-r--r--lib/ssl/test/old_ssl_active_SUITE.erl387
-rw-r--r--lib/ssl/test/old_ssl_active_once_SUITE.erl409
-rw-r--r--lib/ssl/test/old_ssl_dist_SUITE.erl595
-rw-r--r--lib/ssl/test/old_ssl_misc_SUITE.erl105
-rw-r--r--lib/ssl/test/old_ssl_passive_SUITE.erl374
-rw-r--r--lib/ssl/test/old_ssl_peer_cert_SUITE.erl180
-rw-r--r--lib/ssl/test/old_ssl_protocol_SUITE.erl169
-rw-r--r--lib/ssl/test/old_ssl_verify_SUITE.erl141
-rw-r--r--lib/ssl/test/old_transport_accept_SUITE.erl238
-rw-r--r--lib/ssl/test/ssl.cover7
-rw-r--r--lib/ssl/test/ssl.spec1
-rw-r--r--lib/ssl/test/ssl_basic_SUITE.erl2538
-rw-r--r--lib/ssl/test/ssl_basic_SUITE_data/RANDbin0 -> 512 bytes
-rw-r--r--lib/ssl/test/ssl_basic_SUITE_data/dHParam.pem5
-rw-r--r--lib/ssl/test/ssl_packet_SUITE.erl1746
-rw-r--r--lib/ssl/test/ssl_payload_SUITE.erl726
-rw-r--r--lib/ssl/test/ssl_test_MACHINE.erl935
-rw-r--r--lib/ssl/test/ssl_test_MACHINE.hrl39
-rw-r--r--lib/ssl/test/ssl_test_lib.erl496
-rw-r--r--lib/ssl/test/ssl_to_openssl_SUITE.erl1070
-rw-r--r--lib/ssl/vsn.mk35
-rw-r--r--lib/stdlib/doc/src/beam_lib.xml152
-rw-r--r--lib/stdlib/doc/src/epp.xml26
-rw-r--r--lib/stdlib/doc/src/erl_lint.xml8
-rw-r--r--lib/stdlib/doc/src/erl_parse.xml26
-rw-r--r--lib/stdlib/doc/src/file_sorter.xml14
-rw-r--r--lib/stdlib/doc/src/filename.xml10
-rw-r--r--lib/stdlib/doc/src/gb_sets.xml8
-rw-r--r--lib/stdlib/doc/src/gb_trees.xml8
-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/io.xml11
-rw-r--r--lib/stdlib/doc/src/io_protocol.xml2
-rw-r--r--lib/stdlib/doc/src/lists.xml17
-rw-r--r--lib/stdlib/doc/src/notes.xml170
-rw-r--r--lib/stdlib/doc/src/proplists.xml9
-rw-r--r--lib/stdlib/doc/src/re.xml426
-rw-r--r--lib/stdlib/doc/src/regexp.xml44
-rw-r--r--lib/stdlib/doc/src/shell.xml49
-rw-r--r--lib/stdlib/doc/src/sofs.xml17
-rw-r--r--lib/stdlib/doc/src/stdlib_app.xml34
-rw-r--r--lib/stdlib/doc/src/string.xml4
-rw-r--r--lib/stdlib/doc/src/supervisor.xml44
-rw-r--r--lib/stdlib/doc/src/sys.xml39
-rw-r--r--lib/stdlib/doc/src/unicode.xml4
-rw-r--r--lib/stdlib/doc/src/unicode_usage.xml6
-rw-r--r--lib/stdlib/doc/src/win32reg.xml6
-rw-r--r--lib/stdlib/src/Makefile17
-rw-r--r--lib/stdlib/src/array.erl16
-rw-r--r--lib/stdlib/src/c.erl4
-rw-r--r--lib/stdlib/src/dets_v8.erl40
-rw-r--r--lib/stdlib/src/edlin.erl46
-rw-r--r--lib/stdlib/src/edlin_expand.erl49
-rw-r--r--lib/stdlib/src/epp.erl265
-rw-r--r--lib/stdlib/src/erl_lint.erl114
-rw-r--r--lib/stdlib/src/escript.erl90
-rw-r--r--lib/stdlib/src/file_sorter.erl34
-rw-r--r--lib/stdlib/src/filelib.erl22
-rw-r--r--lib/stdlib/src/gen_fsm.erl7
-rw-r--r--lib/stdlib/src/io_lib.erl14
-rw-r--r--lib/stdlib/src/otp_internal.erl4
-rw-r--r--lib/stdlib/src/qlc.erl159
-rw-r--r--lib/stdlib/src/qlc_pt.erl32
-rw-r--r--lib/stdlib/src/re.erl71
-rw-r--r--lib/stdlib/src/shell.erl104
-rw-r--r--lib/stdlib/src/shell_default.erl11
-rw-r--r--lib/stdlib/src/supervisor.erl59
-rw-r--r--lib/stdlib/src/sys.erl11
-rw-r--r--lib/stdlib/test/ExpandTestCaps.erl32
-rw-r--r--lib/stdlib/test/ExpandTestCaps1.erl44
-rw-r--r--lib/stdlib/test/Makefile7
-rw-r--r--lib/stdlib/test/array_SUITE.erl16
-rw-r--r--lib/stdlib/test/c_SUITE.erl69
-rw-r--r--lib/stdlib/test/calendar_SUITE.erl26
-rw-r--r--lib/stdlib/test/edlin_expand_SUITE.erl156
-rw-r--r--lib/stdlib/test/epp_SUITE.erl143
-rw-r--r--lib/stdlib/test/erl_lint_SUITE.erl12
-rw-r--r--lib/stdlib/test/ets_SUITE.erl18
-rw-r--r--lib/stdlib/test/ets_tough_SUITE.erl18
-rw-r--r--lib/stdlib/test/expand_test.erl32
-rw-r--r--lib/stdlib/test/expand_test1.erl44
-rw-r--r--lib/stdlib/test/filelib_SUITE.erl30
-rw-r--r--lib/stdlib/test/fixtable_SUITE.erl26
-rw-r--r--lib/stdlib/test/format_SUITE.erl12
-rw-r--r--lib/stdlib/test/gen_event_SUITE.erl30
-rw-r--r--lib/stdlib/test/gen_fsm_SUITE.erl16
-rw-r--r--lib/stdlib/test/gen_server_SUITE.erl29
-rw-r--r--lib/stdlib/test/io_proto_SUITE.erl90
-rw-r--r--lib/stdlib/test/ms_transform_SUITE.erl36
-rw-r--r--lib/stdlib/test/queue_SUITE.erl22
-rw-r--r--lib/stdlib/test/re_SUITE.erl36
-rw-r--r--lib/stdlib/test/re_SUITE_data/mod_testoutput8877
-rw-r--r--lib/stdlib/test/re_testoutput1_replacement_test.erl11
-rw-r--r--lib/stdlib/test/re_testoutput1_split_test.erl11
-rw-r--r--lib/stdlib/test/run_pcre_tests.erl52
-rw-r--r--lib/stdlib/test/select_SUITE.erl16
-rw-r--r--lib/stdlib/test/shell_SUITE.erl115
-rw-r--r--lib/stdlib/test/slave_SUITE.erl18
-rw-r--r--lib/stdlib/test/sofs_SUITE.erl132
-rw-r--r--lib/stdlib/test/supervisor_SUITE.erl243
-rw-r--r--lib/stdlib/test/tar_SUITE.erl18
-rw-r--r--lib/stdlib/test/timer_SUITE.erl12
-rw-r--r--lib/stdlib/test/unicode_SUITE.erl82
-rw-r--r--lib/stdlib/test/win32reg_SUITE.erl14
-rw-r--r--lib/stdlib/test/zip_SUITE.erl20
-rw-r--r--lib/stdlib/vsn.mk2
-rw-r--r--lib/syntax_tools/Makefile6
-rw-r--r--lib/syntax_tools/doc/Makefile2
-rw-r--r--lib/syntax_tools/doc/src/Makefile14
-rw-r--r--lib/syntax_tools/doc/src/notes.xml37
-rw-r--r--lib/syntax_tools/examples/Makefile2
-rw-r--r--lib/syntax_tools/src/Makefile17
-rw-r--r--lib/syntax_tools/src/epp_dodger.erl71
-rw-r--r--lib/syntax_tools/src/erl_comment_scan.erl18
-rw-r--r--lib/syntax_tools/src/erl_prettypr.erl55
-rw-r--r--lib/syntax_tools/src/erl_recomment.erl45
-rw-r--r--lib/syntax_tools/src/erl_syntax.erl582
-rw-r--r--lib/syntax_tools/src/erl_syntax_lib.erl150
-rw-r--r--lib/syntax_tools/src/erl_tidy.erl32
-rw-r--r--lib/syntax_tools/src/igor.erl162
-rw-r--r--lib/syntax_tools/src/prettypr.erl74
-rw-r--r--lib/syntax_tools/vsn.mk2
-rw-r--r--lib/test_server/doc/src/Makefile13
-rw-r--r--lib/test_server/doc/src/notes.xml59
-rw-r--r--lib/test_server/doc/src/test_server_ctrl.xml111
-rw-r--r--lib/test_server/doc/src/write_framework_chapter.xml2
-rw-r--r--lib/test_server/info2
-rw-r--r--lib/test_server/src/Makefile12
-rw-r--r--lib/test_server/src/test_server.erl30
-rw-r--r--lib/test_server/src/test_server_ctrl.erl10
-rw-r--r--lib/test_server/src/test_server_line.erl17
-rw-r--r--lib/test_server/src/test_server_sup.erl23
-rw-r--r--lib/test_server/test/Makefile95
-rw-r--r--lib/test_server/test/test_server.cover20
-rw-r--r--lib/test_server/test/test_server.spec2
-rw-r--r--lib/test_server/test/test_server_SUITE.erl554
-rw-r--r--lib/test_server/test/test_server_SUITE_data/dummy_file1
-rw-r--r--lib/test_server/test/test_server_conf01_SUITE.erl187
-rw-r--r--lib/test_server/test/test_server_conf02_SUITE.erl294
-rw-r--r--lib/test_server/test/test_server_line_SUITE.erl122
-rw-r--r--lib/test_server/test/test_server_line_SUITE_data/Makefile.src6
-rw-r--r--lib/test_server/test/test_server_line_SUITE_data/parse_transform_test.erl59
-rw-r--r--lib/test_server/test/test_server_parallel01_SUITE.erl518
-rw-r--r--lib/test_server/test/test_server_shuffle01_SUITE.erl471
-rw-r--r--lib/test_server/test/test_server_skip_SUITE.erl43
-rw-r--r--lib/test_server/vsn.mk2
-rw-r--r--lib/tools/doc/src/Makefile12
-rw-r--r--lib/tools/doc/src/erlang_mode.xml2
-rw-r--r--lib/tools/doc/src/erlang_mode_chapter.xml6
-rw-r--r--lib/tools/doc/src/lcnt.xml465
-rw-r--r--lib/tools/doc/src/lcnt_chapter.xml301
-rw-r--r--lib/tools/doc/src/notes.xml55
-rw-r--r--lib/tools/doc/src/notes_history.xml30
-rw-r--r--lib/tools/doc/src/part.xml9
-rw-r--r--lib/tools/doc/src/ref_man.xml12
-rw-r--r--lib/tools/doc/src/xref.xml2
-rw-r--r--lib/tools/emacs/erlang-skels-old.el1267
-rw-r--r--lib/tools/emacs/erlang-skels.el1553
-rw-r--r--lib/tools/emacs/erlang.el1379
-rw-r--r--lib/tools/emacs/test.erl.indented56
-rw-r--r--lib/tools/emacs/test.erl.orig50
-rw-r--r--lib/tools/src/Makefile14
-rw-r--r--lib/tools/src/cover.erl4
-rw-r--r--lib/tools/src/lcnt.erl840
-rw-r--r--lib/tools/src/xref_utils.erl13
-rw-r--r--lib/tools/test/Makefile93
-rw-r--r--lib/tools/test/cover_SUITE.erl1198
-rw-r--r--lib/tools/test/cover_SUITE_data/a.erl55
-rw-r--r--lib/tools/test/cover_SUITE_data/b.erl14
-rw-r--r--lib/tools/test/cover_SUITE_data/cc.erl88
-rw-r--r--lib/tools/test/cover_SUITE_data/compile_beam/crypt.erl6
-rw-r--r--lib/tools/test/cover_SUITE_data/compile_beam/d/y.erl6
-rw-r--r--lib/tools/test/cover_SUITE_data/compile_beam/v.erl6
-rw-r--r--lib/tools/test/cover_SUITE_data/compile_beam/w.erl6
-rw-r--r--lib/tools/test/cover_SUITE_data/compile_beam/x.erl6
-rw-r--r--lib/tools/test/cover_SUITE_data/d.erl156
-rw-r--r--lib/tools/test/cover_SUITE_data/d1/e.erl127
-rw-r--r--lib/tools/test/cover_SUITE_data/f.erl10
-rw-r--r--lib/tools/test/cover_SUITE_data/included_functions/cover_inc.erl8
-rw-r--r--lib/tools/test/cover_SUITE_data/included_functions/cover_inc.hrl7
-rw-r--r--lib/tools/test/cover_SUITE_data/otp_6115/f1.erl12
-rw-r--r--lib/tools/test/cover_SUITE_data/otp_6115/f2.erl13
-rw-r--r--lib/tools/test/cprof_SUITE.erl309
-rw-r--r--lib/tools/test/cprof_SUITE_data/cprof_SUITE_test.erl25
-rw-r--r--lib/tools/test/emem_SUITE.erl713
-rw-r--r--lib/tools/test/eprof_SUITE.erl97
-rw-r--r--lib/tools/test/eprof_SUITE_data/ed.script8
-rw-r--r--lib/tools/test/eprof_SUITE_data/eed.erl815
-rw-r--r--lib/tools/test/eprof_SUITE_data/eprof_suite_test.erl74
-rw-r--r--lib/tools/test/fprof_SUITE.erl1191
-rw-r--r--lib/tools/test/fprof_SUITE_data/foo.erl41
l---------lib/tools/test/ignore_cores.erl1
-rw-r--r--lib/tools/test/instrument_SUITE.erl129
-rw-r--r--lib/tools/test/lcnt_SUITE.erl154
-rw-r--r--lib/tools/test/lcnt_SUITE_data/big_bang_40.lcntbin0 -> 226100 bytes
-rw-r--r--lib/tools/test/make_SUITE.erl295
-rw-r--r--lib/tools/test/make_SUITE_data/Emakefile20
-rw-r--r--lib/tools/test/make_SUITE_data/test1.erl10
-rw-r--r--lib/tools/test/make_SUITE_data/test2.erl10
-rw-r--r--lib/tools/test/make_SUITE_data/test3.erl10
-rw-r--r--lib/tools/test/make_SUITE_data/test4.erl10
-rw-r--r--lib/tools/test/make_SUITE_data/test5.erl10
-rw-r--r--lib/tools/test/tools.spec1
-rw-r--r--lib/tools/test/tools.spec.win2
-rw-r--r--lib/tools/test/tools_SUITE.erl56
-rw-r--r--lib/tools/test/xref_SUITE.erl2747
-rw-r--r--lib/tools/test/xref_SUITE_data/depr_r9c.beambin0 -> 1664 bytes
-rw-r--r--lib/tools/test/xref_SUITE_data/dir/dir/dummy2
-rw-r--r--lib/tools/test/xref_SUITE_data/dir/jam/x.jam0
-rw-r--r--lib/tools/test/xref_SUITE_data/lib_test/cp.erl6
-rw-r--r--lib/tools/test/xref_SUITE_data/lib_test/lib1.erl6
-rw-r--r--lib/tools/test/xref_SUITE_data/lib_test/lib2.erl14
-rw-r--r--lib/tools/test/xref_SUITE_data/lib_test/lib3.erl11
-rw-r--r--lib/tools/test/xref_SUITE_data/lib_test/t.erl14
-rw-r--r--lib/tools/test/xref_SUITE_data/md/x__x.erl7
-rw-r--r--lib/tools/test/xref_SUITE_data/md/y__y.erl12
-rw-r--r--lib/tools/test/xref_SUITE_data/read/read.beam.v1bin0 -> 7160 bytes
-rw-r--r--lib/tools/test/xref_SUITE_data/read/read.erl175
-rw-r--r--lib/tools/test/xref_SUITE_data/rel2/lib/app1-1.0/ebin/dummy2
-rw-r--r--lib/tools/test/xref_SUITE_data/rel2/lib/app1-1.1/ebin/dummy2
-rw-r--r--lib/tools/test/xref_SUITE_data/rel2/lib/app2-1.1/ebin/dummy2
-rw-r--r--lib/tools/test/xref_SUITE_data/rel2/x.erl16
-rw-r--r--lib/tools/test/xref_SUITE_data/rel2/y.erl6
-rw-r--r--lib/tools/test/xref_SUITE_data/update/x.erl.16
-rw-r--r--lib/tools/test/xref_SUITE_data/update/x.erl.26
-rw-r--r--lib/tools/vsn.mk20
-rw-r--r--lib/tv/vsn.mk19
-rw-r--r--lib/typer/src/typer_annotator.erl14
-rw-r--r--lib/typer/vsn.mk2
-rw-r--r--lib/webtool/doc/src/notes.xml21
-rw-r--r--lib/webtool/doc/src/webtool_chapter.xml7
-rw-r--r--lib/webtool/vsn.mk3
-rw-r--r--lib/wx/api_gen/gen_util.erl55
-rw-r--r--lib/wx/api_gen/gl_gen_c.erl34
-rw-r--r--lib/wx/api_gen/gl_gen_erl.erl34
-rw-r--r--lib/wx/api_gen/wx_gen.erl52
-rw-r--r--lib/wx/api_gen/wx_gen_cpp.erl118
-rw-r--r--lib/wx/api_gen/wx_gen_erl.erl59
-rw-r--r--lib/wx/api_gen/wxapi.conf27
-rw-r--r--lib/wx/c_src/Makefile.in23
-rw-r--r--lib/wx/c_src/gen/gl_fdefs.h10
-rw-r--r--lib/wx/c_src/gen/gl_finit.h10
-rw-r--r--lib/wx/c_src/gen/gl_funcs.cpp10
-rw-r--r--lib/wx/c_src/gen/glu_finit.h10
-rw-r--r--lib/wx/c_src/gen/wxe_derived_dest.h702
-rw-r--r--lib/wx/c_src/gen/wxe_events.cpp64
-rw-r--r--lib/wx/c_src/gen/wxe_funcs.cpp14688
-rw-r--r--lib/wx/c_src/gen/wxe_init.cpp10
-rw-r--r--lib/wx/c_src/gen/wxe_macros.h3522
-rw-r--r--lib/wx/c_src/wxe_impl.cpp57
-rw-r--r--lib/wx/c_src/wxe_return.cpp12
-rwxr-xr-xlib/wx/configure.in31
-rw-r--r--lib/wx/doc/src/Makefile28
-rw-r--r--lib/wx/doc/src/notes.xml58
-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/examples/demo/demo_html_tagger.erl12
-rw-r--r--lib/wx/include/gl.hrl10
-rw-r--r--lib/wx/include/glu.hrl10
-rw-r--r--lib/wx/include/wx.hrl436
-rw-r--r--lib/wx/src/gen/gl.erl10
-rw-r--r--lib/wx/src/gen/gl_debug.hrl10
-rw-r--r--lib/wx/src/gen/glu.erl10
-rw-r--r--lib/wx/src/gen/wxAcceleratorEntry.erl14
-rw-r--r--lib/wx/src/gen/wxAcceleratorTable.erl12
-rw-r--r--lib/wx/src/gen/wxArtProvider.erl10
-rw-r--r--lib/wx/src/gen/wxAuiDockArt.erl10
-rw-r--r--lib/wx/src/gen/wxAuiManager.erl20
-rw-r--r--lib/wx/src/gen/wxAuiManagerEvent.erl14
-rw-r--r--lib/wx/src/gen/wxAuiNotebook.erl20
-rw-r--r--lib/wx/src/gen/wxAuiNotebookEvent.erl18
-rw-r--r--lib/wx/src/gen/wxAuiPaneInfo.erl12
-rw-r--r--lib/wx/src/gen/wxAuiTabArt.erl10
-rw-r--r--lib/wx/src/gen/wxBitmap.erl18
-rw-r--r--lib/wx/src/gen/wxBitmapButton.erl22
-rw-r--r--lib/wx/src/gen/wxBitmapDataObject.erl18
-rw-r--r--lib/wx/src/gen/wxBoxSizer.erl16
-rw-r--r--lib/wx/src/gen/wxBrush.erl14
-rw-r--r--lib/wx/src/gen/wxBufferedDC.erl22
-rw-r--r--lib/wx/src/gen/wxBufferedPaintDC.erl22
-rw-r--r--lib/wx/src/gen/wxButton.erl20
-rw-r--r--lib/wx/src/gen/wxCalendarCtrl.erl20
-rw-r--r--lib/wx/src/gen/wxCalendarDateAttr.erl16
-rw-r--r--lib/wx/src/gen/wxCalendarEvent.erl18
-rw-r--r--lib/wx/src/gen/wxCaret.erl12
-rw-r--r--lib/wx/src/gen/wxCheckBox.erl20
-rw-r--r--lib/wx/src/gen/wxCheckListBox.erl24
-rw-r--r--lib/wx/src/gen/wxChildFocusEvent.erl16
-rw-r--r--lib/wx/src/gen/wxChoice.erl22
-rw-r--r--lib/wx/src/gen/wxChoicebook.erl20
-rw-r--r--lib/wx/src/gen/wxClientDC.erl18
-rw-r--r--lib/wx/src/gen/wxClipboard.erl12
-rw-r--r--lib/wx/src/gen/wxCloseEvent.erl14
-rw-r--r--lib/wx/src/gen/wxColourData.erl12
-rw-r--r--lib/wx/src/gen/wxColourDialog.erl22
-rw-r--r--lib/wx/src/gen/wxColourPickerCtrl.erl24
-rw-r--r--lib/wx/src/gen/wxColourPickerEvent.erl16
-rw-r--r--lib/wx/src/gen/wxComboBox.erl22
-rw-r--r--lib/wx/src/gen/wxCommandEvent.erl14
-rw-r--r--lib/wx/src/gen/wxContextMenuEvent.erl16
-rw-r--r--lib/wx/src/gen/wxControl.erl16
-rw-r--r--lib/wx/src/gen/wxControlWithItems.erl18
-rw-r--r--lib/wx/src/gen/wxCursor.erl18
-rw-r--r--lib/wx/src/gen/wxDC.erl12
-rw-r--r--lib/wx/src/gen/wxDataObject.erl10
-rw-r--r--lib/wx/src/gen/wxDateEvent.erl16
-rw-r--r--lib/wx/src/gen/wxDatePickerCtrl.erl22
-rw-r--r--lib/wx/src/gen/wxDialog.erl20
-rw-r--r--lib/wx/src/gen/wxDirDialog.erl22
-rw-r--r--lib/wx/src/gen/wxDirPickerCtrl.erl22
-rw-r--r--lib/wx/src/gen/wxDisplayChangedEvent.erl14
-rw-r--r--lib/wx/src/gen/wxEraseEvent.erl14
-rw-r--r--lib/wx/src/gen/wxEvent.erl10
-rw-r--r--lib/wx/src/gen/wxEvtHandler.erl10
-rw-r--r--lib/wx/src/gen/wxFileDataObject.erl16
-rw-r--r--lib/wx/src/gen/wxFileDialog.erl35
-rw-r--r--lib/wx/src/gen/wxFileDirPickerEvent.erl16
-rw-r--r--lib/wx/src/gen/wxFilePickerCtrl.erl22
-rw-r--r--lib/wx/src/gen/wxFindReplaceData.erl12
-rw-r--r--lib/wx/src/gen/wxFindReplaceDialog.erl22
-rw-r--r--lib/wx/src/gen/wxFlexGridSizer.erl18
-rw-r--r--lib/wx/src/gen/wxFocusEvent.erl14
-rw-r--r--lib/wx/src/gen/wxFont.erl12
-rw-r--r--lib/wx/src/gen/wxFontData.erl12
-rw-r--r--lib/wx/src/gen/wxFontDialog.erl22
-rw-r--r--lib/wx/src/gen/wxFontPickerCtrl.erl22
-rw-r--r--lib/wx/src/gen/wxFontPickerEvent.erl16
-rw-r--r--lib/wx/src/gen/wxFrame.erl20
-rw-r--r--lib/wx/src/gen/wxGBSizerItem.erl14
-rw-r--r--lib/wx/src/gen/wxGLCanvas.erl20
-rw-r--r--lib/wx/src/gen/wxGauge.erl20
-rw-r--r--lib/wx/src/gen/wxGenericDirCtrl.erl22
-rw-r--r--lib/wx/src/gen/wxGraphicsBrush.erl14
-rw-r--r--lib/wx/src/gen/wxGraphicsContext.erl16
-rw-r--r--lib/wx/src/gen/wxGraphicsFont.erl14
-rw-r--r--lib/wx/src/gen/wxGraphicsMatrix.erl14
-rw-r--r--lib/wx/src/gen/wxGraphicsObject.erl10
-rw-r--r--lib/wx/src/gen/wxGraphicsPath.erl16
-rw-r--r--lib/wx/src/gen/wxGraphicsPen.erl14
-rw-r--r--lib/wx/src/gen/wxGraphicsRenderer.erl10
-rw-r--r--lib/wx/src/gen/wxGrid.erl32
-rw-r--r--lib/wx/src/gen/wxGridBagSizer.erl34
-rw-r--r--lib/wx/src/gen/wxGridCellAttr.erl10
-rw-r--r--lib/wx/src/gen/wxGridCellBoolEditor.erl16
-rw-r--r--lib/wx/src/gen/wxGridCellBoolRenderer.erl16
-rw-r--r--lib/wx/src/gen/wxGridCellChoiceEditor.erl16
-rw-r--r--lib/wx/src/gen/wxGridCellEditor.erl10
-rw-r--r--lib/wx/src/gen/wxGridCellFloatEditor.erl16
-rw-r--r--lib/wx/src/gen/wxGridCellFloatRenderer.erl18
-rw-r--r--lib/wx/src/gen/wxGridCellNumberEditor.erl18
-rw-r--r--lib/wx/src/gen/wxGridCellNumberRenderer.erl18
-rw-r--r--lib/wx/src/gen/wxGridCellRenderer.erl10
-rw-r--r--lib/wx/src/gen/wxGridCellStringRenderer.erl16
-rw-r--r--lib/wx/src/gen/wxGridCellTextEditor.erl16
-rw-r--r--lib/wx/src/gen/wxGridEvent.erl18
-rw-r--r--lib/wx/src/gen/wxGridSizer.erl16
-rw-r--r--lib/wx/src/gen/wxHelpEvent.erl14
-rw-r--r--lib/wx/src/gen/wxHtmlEasyPrinting.erl12
-rw-r--r--lib/wx/src/gen/wxHtmlLinkEvent.erl16
-rw-r--r--lib/wx/src/gen/wxHtmlWindow.erl22
-rw-r--r--lib/wx/src/gen/wxIcon.erl18
-rw-r--r--lib/wx/src/gen/wxIconBundle.erl14
-rw-r--r--lib/wx/src/gen/wxIconizeEvent.erl14
-rw-r--r--lib/wx/src/gen/wxIdleEvent.erl14
-rw-r--r--lib/wx/src/gen/wxImage.erl26
-rw-r--r--lib/wx/src/gen/wxImageList.erl14
-rw-r--r--lib/wx/src/gen/wxJoystickEvent.erl14
-rw-r--r--lib/wx/src/gen/wxKeyEvent.erl14
-rw-r--r--lib/wx/src/gen/wxLayoutAlgorithm.erl12
-rw-r--r--lib/wx/src/gen/wxListBox.erl24
-rw-r--r--lib/wx/src/gen/wxListCtrl.erl54
-rw-r--r--lib/wx/src/gen/wxListEvent.erl18
-rw-r--r--lib/wx/src/gen/wxListItem.erl12
-rw-r--r--lib/wx/src/gen/wxListView.erl18
-rw-r--r--lib/wx/src/gen/wxListbook.erl20
-rw-r--r--lib/wx/src/gen/wxLogNull.erl12
-rw-r--r--lib/wx/src/gen/wxMDIChildFrame.erl22
-rw-r--r--lib/wx/src/gen/wxMDIClientWindow.erl18
-rw-r--r--lib/wx/src/gen/wxMDIParentFrame.erl22
-rw-r--r--lib/wx/src/gen/wxMask.erl16
-rw-r--r--lib/wx/src/gen/wxMaximizeEvent.erl14
-rw-r--r--lib/wx/src/gen/wxMemoryDC.erl16
-rw-r--r--lib/wx/src/gen/wxMenu.erl36
-rw-r--r--lib/wx/src/gen/wxMenuBar.erl18
-rw-r--r--lib/wx/src/gen/wxMenuEvent.erl14
-rw-r--r--lib/wx/src/gen/wxMenuItem.erl12
-rw-r--r--lib/wx/src/gen/wxMessageDialog.erl22
-rw-r--r--lib/wx/src/gen/wxMiniFrame.erl22
-rw-r--r--lib/wx/src/gen/wxMirrorDC.erl16
-rw-r--r--lib/wx/src/gen/wxMouseCaptureChangedEvent.erl14
-rw-r--r--lib/wx/src/gen/wxMouseEvent.erl14
-rw-r--r--lib/wx/src/gen/wxMoveEvent.erl14
-rw-r--r--lib/wx/src/gen/wxMultiChoiceDialog.erl22
-rw-r--r--lib/wx/src/gen/wxNavigationKeyEvent.erl14
-rw-r--r--lib/wx/src/gen/wxNcPaintEvent.erl14
-rw-r--r--lib/wx/src/gen/wxNotebook.erl20
-rw-r--r--lib/wx/src/gen/wxNotebookEvent.erl18
-rw-r--r--lib/wx/src/gen/wxNotifyEvent.erl16
-rw-r--r--lib/wx/src/gen/wxPageSetupDialog.erl12
-rw-r--r--lib/wx/src/gen/wxPageSetupDialogData.erl14
-rw-r--r--lib/wx/src/gen/wxPaintDC.erl18
-rw-r--r--lib/wx/src/gen/wxPaintEvent.erl14
-rw-r--r--lib/wx/src/gen/wxPalette.erl12
-rw-r--r--lib/wx/src/gen/wxPaletteChangedEvent.erl14
-rw-r--r--lib/wx/src/gen/wxPanel.erl18
-rw-r--r--lib/wx/src/gen/wxPasswordEntryDialog.erl24
-rw-r--r--lib/wx/src/gen/wxPen.erl12
-rw-r--r--lib/wx/src/gen/wxPickerBase.erl18
-rw-r--r--lib/wx/src/gen/wxPostScriptDC.erl16
-rw-r--r--lib/wx/src/gen/wxPreviewCanvas.erl20
-rw-r--r--lib/wx/src/gen/wxPreviewControlBar.erl20
-rw-r--r--lib/wx/src/gen/wxPreviewFrame.erl22
-rw-r--r--lib/wx/src/gen/wxPrintData.erl12
-rw-r--r--lib/wx/src/gen/wxPrintDialog.erl24
-rw-r--r--lib/wx/src/gen/wxPrintDialogData.erl12
-rw-r--r--lib/wx/src/gen/wxPrintPreview.erl12
-rw-r--r--lib/wx/src/gen/wxPrinter.erl12
-rw-r--r--lib/wx/src/gen/wxPrintout.erl12
-rw-r--r--lib/wx/src/gen/wxProgressDialog.erl22
-rw-r--r--lib/wx/src/gen/wxQueryNewPaletteEvent.erl14
-rw-r--r--lib/wx/src/gen/wxRadioBox.erl24
-rw-r--r--lib/wx/src/gen/wxRadioButton.erl20
-rw-r--r--lib/wx/src/gen/wxRegion.erl24
-rw-r--r--lib/wx/src/gen/wxSashEvent.erl16
-rw-r--r--lib/wx/src/gen/wxSashLayoutWindow.erl20
-rw-r--r--lib/wx/src/gen/wxSashWindow.erl18
-rw-r--r--lib/wx/src/gen/wxScreenDC.erl16
-rw-r--r--lib/wx/src/gen/wxScrollBar.erl20
-rw-r--r--lib/wx/src/gen/wxScrollEvent.erl16
-rw-r--r--lib/wx/src/gen/wxScrollWinEvent.erl14
-rw-r--r--lib/wx/src/gen/wxScrolledWindow.erl20
-rw-r--r--lib/wx/src/gen/wxSetCursorEvent.erl14
-rw-r--r--lib/wx/src/gen/wxShowEvent.erl14
-rw-r--r--lib/wx/src/gen/wxSingleChoiceDialog.erl22
-rw-r--r--lib/wx/src/gen/wxSizeEvent.erl14
-rw-r--r--lib/wx/src/gen/wxSizer.erl40
-rw-r--r--lib/wx/src/gen/wxSizerFlags.erl12
-rw-r--r--lib/wx/src/gen/wxSizerItem.erl14
-rw-r--r--lib/wx/src/gen/wxSlider.erl20
-rw-r--r--lib/wx/src/gen/wxSpinButton.erl20
-rw-r--r--lib/wx/src/gen/wxSpinCtrl.erl22
-rw-r--r--lib/wx/src/gen/wxSpinEvent.erl18
-rw-r--r--lib/wx/src/gen/wxSplashScreen.erl22
-rw-r--r--lib/wx/src/gen/wxSplitterEvent.erl18
-rw-r--r--lib/wx/src/gen/wxSplitterWindow.erl18
-rw-r--r--lib/wx/src/gen/wxStaticBitmap.erl20
-rw-r--r--lib/wx/src/gen/wxStaticBox.erl20
-rw-r--r--lib/wx/src/gen/wxStaticBoxSizer.erl20
-rw-r--r--lib/wx/src/gen/wxStaticLine.erl20
-rw-r--r--lib/wx/src/gen/wxStaticText.erl20
-rw-r--r--lib/wx/src/gen/wxStatusBar.erl18
-rw-r--r--lib/wx/src/gen/wxStdDialogButtonSizer.erl18
-rw-r--r--lib/wx/src/gen/wxStyledTextCtrl.erl20
-rw-r--r--lib/wx/src/gen/wxStyledTextEvent.erl16
-rw-r--r--lib/wx/src/gen/wxSysColourChangedEvent.erl14
-rw-r--r--lib/wx/src/gen/wxTextAttr.erl12
-rw-r--r--lib/wx/src/gen/wxTextCtrl.erl20
-rw-r--r--lib/wx/src/gen/wxTextDataObject.erl16
-rw-r--r--lib/wx/src/gen/wxTextEntryDialog.erl22
-rw-r--r--lib/wx/src/gen/wxToggleButton.erl20
-rw-r--r--lib/wx/src/gen/wxToolBar.erl26
-rw-r--r--lib/wx/src/gen/wxToolTip.erl12
-rw-r--r--lib/wx/src/gen/wxToolbook.erl20
-rw-r--r--lib/wx/src/gen/wxTopLevelWindow.erl16
-rw-r--r--lib/wx/src/gen/wxTreeCtrl.erl468
-rw-r--r--lib/wx/src/gen/wxTreeEvent.erl22
-rw-r--r--lib/wx/src/gen/wxTreebook.erl20
-rw-r--r--lib/wx/src/gen/wxUpdateUIEvent.erl16
-rw-r--r--lib/wx/src/gen/wxWindow.erl34
-rw-r--r--lib/wx/src/gen/wxWindowCreateEvent.erl16
-rw-r--r--lib/wx/src/gen/wxWindowDC.erl16
-rw-r--r--lib/wx/src/gen/wxWindowDestroyEvent.erl16
-rw-r--r--lib/wx/src/gen/wxXmlResource.erl12
-rw-r--r--lib/wx/src/gen/wx_misc.erl10
-rw-r--r--lib/wx/src/gen/wxe_debug.hrl3524
-rw-r--r--lib/wx/src/gen/wxe_funcs.hrl3522
-rw-r--r--lib/wx/test/wx_class_SUITE.erl34
-rw-r--r--lib/wx/test/wx_xtra_SUITE.erl72
-rw-r--r--lib/wx/test/wxt.erl18
-rw-r--r--lib/wx/vsn.mk5
-rw-r--r--lib/xmerl/doc/src/Makefile12
-rw-r--r--lib/xmerl/doc/src/notes.xml35
-rw-r--r--lib/xmerl/src/xmerl_xsd.erl19
-rw-r--r--lib/xmerl/vsn.mk29
-rwxr-xr-xmake/cross_check_erl147
-rwxr-xr-xmake/install_bin702
-rw-r--r--make/otp.mk.in36
-rw-r--r--make/otp_ded.mk.in44
-rw-r--r--make/otp_release_targets.mk55
-rw-r--r--make/otp_subdir.mk20
-rwxr-xr-xmake/unexpected_use29
-rwxr-xr-xotp_build710
-rw-r--r--prebuild.skip1
-rw-r--r--system/AD.html307
-rw-r--r--system/AD.sgml367
-rw-r--r--system/ADbeam.html261
-rw-r--r--system/ADbeam.sgml246
-rw-r--r--system/COPYRIGHT121
-rw-r--r--system/README10
-rw-r--r--system/README.unixware201
-rw-r--r--system/doc/book.xml52
-rw-r--r--system/doc/embedded/embedded_solaris.xml8
-rw-r--r--system/doc/embedded/starting.xml2
-rw-r--r--system/doc/extensions/Makefile142
-rw-r--r--system/doc/extensions/bit_syntax.xml403
-rw-r--r--system/doc/extensions/book.xml45
-rw-r--r--system/doc/extensions/fun_test.erl17
-rw-r--r--system/doc/extensions/funparse.erl74
-rw-r--r--system/doc/extensions/funs.xml486
-rw-r--r--system/doc/extensions/funs1.erl125
-rw-r--r--system/doc/extensions/include.xml81
-rw-r--r--system/doc/extensions/list_comprehensions.erl118
-rw-r--r--system/doc/extensions/list_comprehensions.xml205
-rw-r--r--system/doc/extensions/list_comrehensions.erl75
-rw-r--r--system/doc/extensions/macros.xml177
-rw-r--r--system/doc/extensions/make.dep21
-rw-r--r--system/doc/extensions/mexpand.erl16
-rw-r--r--system/doc/extensions/misc.xml310
-rw-r--r--system/doc/extensions/part.xml57
-rw-r--r--system/doc/extensions/records.xml284
-rw-r--r--system/doc/extensions/warning.gifbin1498 -> 0 bytes
-rw-r--r--system/doc/installation_guide/Makefile24
-rw-r--r--system/doc/installation_guide/install.xml23
-rw-r--r--system/doc/pics/Makefile58
-rw-r--r--system/doc/pics/app.gifbin285 -> 0 bytes
-rw-r--r--system/doc/pics/ede.gifbin13644 -> 0 bytes
-rw-r--r--system/doc/pics/ede_logo.gifbin757 -> 0 bytes
-rw-r--r--system/doc/pics/min_head.gifbin2652 -> 0 bytes
-rw-r--r--system/doc/pics/notes.gifbin2005 -> 0 bytes
-rw-r--r--system/doc/pics/otp.gifbin13737 -> 0 bytes
-rw-r--r--system/doc/pics/otp_logo.gifbin1660 -> 0 bytes
-rw-r--r--system/doc/pics/ps.gifbin618 -> 0 bytes
-rw-r--r--system/doc/pics/ref_man.gifbin1530 -> 0 bytes
-rw-r--r--system/doc/pics/user_guide.gifbin1581 -> 0 bytes
-rw-r--r--system/doc/reference_manual/code_loading.xml35
-rw-r--r--system/doc/reference_manual/data_types.xml36
-rw-r--r--system/doc/reference_manual/macros.xml38
-rw-r--r--system/doc/reference_manual/modules.xml25
-rw-r--r--system/doc/reference_manual/part.xml7
-rwxr-xr-xsystem/doc/reference_manual/typespec.xml464
-rw-r--r--system/doc/system_principles/create_target.xml45
-rw-r--r--system/doc/top/Makefile52
-rw-r--r--system/doc/top/bin/.gitignore0
l---------system/doc/top/bin/otp_man_index1
-rw-r--r--[l---------]system/doc/top/src/erl_html_tools.erl687
-rw-r--r--[l---------]system/doc/top/src/erlresolvelinks.erl185
-rw-r--r--system/doc/top/src/otp_man_index.erl199
l---------system/doc/top/src/permuted_index.erl1
-rw-r--r--system/doc/top/templates/applications.html.src21
-rw-r--r--system/doc/top/templates/erlang.gifbin2162 -> 0 bytes
-rw-r--r--system/doc/top/templates/first.html.src104
-rwxr-xr-xsystem/doc/top/templates/flip_closed.gifbin82 -> 0 bytes
-rwxr-xr-xsystem/doc/top/templates/flip_google.gifbin257 -> 0 bytes
-rwxr-xr-xsystem/doc/top/templates/flip_open.gifbin86 -> 0 bytes
-rwxr-xr-xsystem/doc/top/templates/flip_static.gifbin109 -> 0 bytes
-rwxr-xr-xsystem/doc/top/templates/flipmenu.js342
-rw-r--r--system/doc/top/templates/index.html.src14
-rw-r--r--system/doc/top/templates/otp_top.css53
-rw-r--r--system/doc/top/templates/system.html.src281
-rw-r--r--system/doc/top/templates/toc_.html.src105
-rw-r--r--xcomp/README.md506
-rw-r--r--xcomp/README.xcomp25
-rw-r--r--xcomp/erl-xcomp-TileraMDE2.0-tilepro.conf394
-rw-r--r--xcomp/erl-xcomp-avr32-atmel-linux-gnu.conf261
-rw-r--r--xcomp/erl-xcomp-vars.sh29
-rw-r--r--xcomp/erl-xcomp-vxworks_ppc32.conf419
-rw-r--r--xcomp/erl-xcomp-x86_64-saf-linux-gnu.conf258
-rw-r--r--xcomp/erl-xcomp.conf.template428
2915 files changed, 378308 insertions, 81117 deletions
diff --git a/.gitignore b/.gitignore
index 0207d07dfe..1a68d55eff 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,13 +1,41 @@
# 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
+
+# Compiler derivatives
+#
+# Do not use too creative wildcards.
+# Those might ignore files that should not be ignored.
+
+i686-pc-linux-gnu
+x86_64-unknown-linux-gnu
+i386-apple-darwin[0-9]*.[0-9]*.[0-9]*
+sparc-sun-solaris[0-9]*.[0-9]*
+i386-pc-solaris[0-9]*.[0-9]*
+i386-unknown-freebsd[0-9]*.[0-9]*
+tile-tilera-linux-gnu
+powerpc-unknown-linux-gnu
+
+# Mac OS X
+a.out.dSYM/
# 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
@@ -15,9 +43,228 @@ autom4te.cache
/bootstrap/lib/sasl
/bootstrap/lib/snmp
/bootstrap/lib/syntax_tools
+/bootstrap/lib/test_server
/bootstrap/lib/wx
/Makefile
/configure
/release
+
+
+# Created by "out_build update_primary"
+/bootstrap/primary_compiler/
+
+# 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/*/SKIP
+
+/lib/*/doc/html/*.html
+/lib/*/doc/html/*.gif
+/lib/*/doc/html/*.eix
+/lib/*/doc/man[0-9]/*.[0-9]
+/lib/*/doc/pdf/*.fo
+/lib/*/doc/pdf/*.pdf
+
+
+/lib/configure
+/lib/config.log
+/lib/config.status
+
+#
+# Files generated by configure.
+#
+
+/lib/*/configure
+/lib/*/config.log
+/lib/*/config.status
+
+#
+# Files generated when building/running tests (especially if
+# a directory in $ERL_TOP/release/tests has been symlinked to
+# a test directory in lib).
+#
+
+/lib/*/test/*_SUITE_make.erl
+/lib/*/test/*_SUITE_data/Makefile
+/erts/emulator/test/*_SUITE_make.erl
+/erts/emulator/test/*_SUITE_data/Makefile
+
+# asn1
+
+/lib/asn1/doc/src/asn1_spec.xml
+
+# 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
+
+# debugger
+
+/lib/debugger/doc/html/images/*.gif
+
+# edoc
+
+/lib/edoc/priv/edoc_generate
+/lib/edoc/src/edoc_parser.erl
+
+# erts
+
+/erts/info
+/erts/doc/html/*.html
+/erts/doc/html/*.gif
+/erts/doc/html/*.eix
+/erts/doc/pdf/*.fo
+/erts/doc/pdf/*.pdf
+/erts/doc/man[0-9]/*.[0-9]
+
+# gs
+
+/lib/gs/src/gstk_generic.hrl
+/lib/gs/contribs/ebin/*.gif
+/lib/gs/contribs/ebin/*.tool
+/lib/gs/doc/html/images/*.gif
+/lib/gs/tcl/win32/Makefile
+
+# hipe
+
+/lib/hipe/main/hipe.hrl
+/lib/hipe/rtl/hipe_literals.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
+/lib/ic/doc/html/java
+
+# jinterface
+
+/lib/jinterface/priv/OtpErlang.jar
+/lib/jinterface/priv/com/
+/lib/jinterface/doc/html/java
+
+# 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
+
+# stdlib
+
+/lib/stdlib/src/erl_parse.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
+/lib/snmp/test/snmp_test_data/[A-Z]*.bin
+/lib/snmp/test/snmp_test_data/[A-Z]*.hrl
+
+# system
+
+/system/doc/pdf/*.pdf
+/system/doc/pdf/*.fo
+/system/doc/html/*/*.html
+/system/doc/html/*/*.gif
+/system/doc/html/*/*.eix
+/system/doc/programming_examples/funs.xml
+/system/doc/tutorial/c_port.xml
+/system/doc/tutorial/c_portdriver.xml
+/system/doc/tutorial/cnode.xml
+/system/doc/tutorial/erl_interface.xml
+/system/doc/tutorial/example.xml
+
+# test_server
+
+/lib/test_server/src/configure
+
+# tools
+
+/lib/tools/src/xref_parser.erl
+
+# 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
+/lib/wx/CONF_INFO
+/lib/wx/doc/src/wx*.xml
+
+# xmerl
+
+/lib/xmerl/src/xmerl_sax_parser_*.erl
+/lib/xmerl/src/xmerl_b64Bin.erl
+/lib/xmerl/src/xmerl_xpath_parse.erl
+/lib/erl_interface/config.h.in
+/lib/configure.in
diff --git a/.mailmap b/.mailmap
new file mode 100644
index 0000000000..66d5af2f6a
--- /dev/null
+++ b/.mailmap
@@ -0,0 +1,3 @@
diff --git a/INSTALL-CROSS.md b/INSTALL-CROSS.md
new file mode 120000
index 0000000000..9e7743b9de
--- /dev/null
+++ b/INSTALL-CROSS.md
@@ -0,0 +1 @@
+xcomp/README.md \ No newline at end of file
diff --git a/INSTALL-WIN32.md b/INSTALL-WIN32.md
new file mode 100644
index 0000000000..f59a8ece67
--- /dev/null
+++ b/INSTALL-WIN32.md
@@ -0,0 +1,781 @@
+How to Build Erlang/OTP on Windows
+==================================
+
+Table of Contents
+-----------------
+
+1. Introduction
+2. Frequently Asked Questions
+3. Tools you Need and Their Environment
+4. The Shell Environment
+5. Building and Installing
+6. Development
+7. Final Words
+8. Copyright and License
+
+Introduction
+------------
+
+This file describes how to build the Erlang emulator and the OTP
+libraries on Windows. The instructions apply to versions of Windows
+supporting the Cygwin emulated gnuish environment for Windows. We've
+built on the following platforms: Windows 2000 Professional, Windows
+2003 server, Windows XP Home/Professional, and Windows Vista. Any
+Windows95'ish platform will surely get you into trouble, what I'm not
+sure of, but it certainly will...
+
+The procedure described uses Cygwin as a build environment, you run
+the bash shell in Cygwin and uses gnu make/configure/autoconf etc to
+do the build. The emulator C-source code is, however, mostly compiled
+with Microsoft Visual C++(tm), producing a native Windows binary. This
+is the same procedure as we use to build the pre-built binaries. The
+fact that we use VC++ and not gcc is explained further in the FAQ
+section.
+
+I describe the build procedure to make it possible for open source
+customers to build the emulator, given that they have the needed
+tools. The binary Windows releases is still a preferred alternative if
+one does not have Microsoft's development tools and/or don't want to
+install Cygwin.
+
+To use Cygwin, one needs basic experience from a Unix environment, if
+one does not know how to set environment variables, run programs etc
+in a Unix environment, one will be quite lost in the Cygwin
+ditto. I can unfortunately not teach all the world how to use
+Cygwin and bash, neither how to install Cygwin nor perform basic tasks
+on a computer. Please refer to other documentation on the net for
+help, or use the binary release instead if you have problems using the
+tools.
+
+However, if you feel comfortable with the environment and build
+system, and have all the necessary tools, you have a great opportunity
+to make the Erlang/OTP distribution for Windows better. Please submit
+any suggestions and patches to the appropriate [mailing lists] [1] to let
+them find their way into the next version of Erlang. If making changes
+to the build system (like makefiles etc) please bear in mind that the
+same makefiles are used on Unix/VxWorks/OSEDelta, so that your changes
+don't break other platforms. That of course goes for C-code too, system
+specific code resides in the `$ERL_TOP/erts/emulator/sys/win32` and
+`$ERL_TOP/erts/etc/win32` directories mostly. The
+`$ERL_TOP/erts/emulator/beam directory` is for common code.
+
+Before the R9C release of Erlang/OTP, the Windows release was built
+partly on a Unix (Solaris) box and partly on a Windows box, using Perl
+hacks to communicate and sync between the two machines. R9C was the
+first release ever built solely on Windows, where no Unix machine is
+needed at all. Now we've used this build procedure for a couple of
+releases, and it has worked fine for us. Still, there might be all
+sorts of troubles on different machines and with different
+setups. I'll try to give hints wherever I've encountered difficulties,
+but please share your experiences by using the [`erlang-questions`] [1]
+mailing list. I cannot of course help everyone with all
+their problems, please try to solve the problems and submit
+solutions/workarounds. Remember, it's all about sharing, not about
+demanding...
+
+Lets go then, I'll start with a little FAQ, based on in house questions
+and misunderstandings.
+
+
+Frequently Asked Questions
+--------------------------
+
+* Q: So, now I can build Erlang using GCC on Windows?
+
+ A: No, unfortunately not. You'll need Microsoft's Visual C++ still, a
+ Bourne-shell script (cc.sh) wraps the Visual C++ compiler and runs it
+ from within the Cygwin environment. All other tools needed to build
+ Erlang are free-ware/open source, but not the C compiler.
+
+* Q: Why haven't you got rid of VC++ then, you `******`?
+
+ A: Well, partly because it's a good compiler - really! Actually it's
+ been possible in late R11-releases to build using mingw instead of
+ visual C++ (you might see the remnants of that in some scripts and
+ directories). Unfortunately the development of the SMP version for
+ Windows broke the mingw build and we chose to focus on the VC++ build
+ as the performance has been much better in the VC++ versions. The
+ mingw build will be back, but as long as VC++ gives better
+ performance, the commercial build will be a VC++ one.
+
+* Q: OK, VC++ you need, but now you've started to demand a very recent
+ (and expensive) version of Visual studio, not the old and stable VC++
+ 6.0 that was used in earlier versions. Why?
+
+ A: The SMP version of Erlang needs features in the Visual Studio 2005.
+ Can't live without them. Besides the new compiler gives the Erlang
+ emulator a ~40% performance boost(!)
+
+* Q: Can/will I build a Cygwin binary with the procedure you describe?
+
+ A: No, the result will be a pure Windows binary, and as far as I know,
+ it's not possible to make a Cygwin binary yet. That is of course
+ something desirable, but there are still some problems with the
+ dynamic linking (dynamic Erlang driver loading) as well as the TCP/IP
+ emulation in Cygwin, which, I'm sure of, will improve, but still has
+ some problems. Fixing those problems might be easy or might be hard.
+ I suggest you try yourself and share your experience. No one would be
+ happier if a simple ./configure && make would produce a fully fledged
+ Cygwin binary. Ericsson does however not pay me to do a Cygwin port, so
+ such a port would have to happen in spare time, which is a limited
+ resource...
+
+* Q: Hah, I saw you, you used GCC even though you said you didn't!
+
+ A: OK, I admit, one of the files is compiled using Cygwin's GCC and
+ the resulting object code is then converted to MS VC++ compatible coff
+ using a small C hack. It's because that particular file, `beam_emu.c`
+ benefits immensely from being able to use the GCC labels-as-values
+ extension, which boosts emulator performance by up to 50%. That does
+ unfortunately not (yet) mean that all of OTP could be compiled using
+ GCC, that particular source code does not do anything system specific
+ and actually is adopted to the fact that GCC is used to compile it on
+ Windows.
+
+* Q: So now there's a MS VC++ project file somewhere and I can build OTP
+ using the nifty VC++ GUI?
+
+ A: No, never. The hassle of keeping the project files up to date and
+ do all the steps that constitute an OTP build from within the VC++ GUI
+ is simply not worth it, maybe even impossible. A VC++ project
+ file for Erlang/OTP will never happen, at least I will never make
+ one. Clicking around in super-multi-tab'd dialogs to add a file or
+ compiler option when it's so much easier in a makefile is simply not
+ my style.
+
+* Q: So how does it all work then?
+
+ A: Cygwin is the environment, which closely resembles the environments
+ found on any Unix machine. It's almost like you had a virtual Unix
+ machine inside Windows. Configure, given certain parameters, then
+ creates makefiles that are used by the Cygwin gnu-make to built the
+ system. Most of the actual compilers etc are not, however, Cygwin
+ tools, so I've written a couple of wrappers (Bourne-shell scripts),
+ which reside in `$ERL_TOP/etc/win32/cygwin_tools` and they all do
+ conversion of parameters and switches common in the Unix environment
+ to fit the native Windows tools. Most notable is of course the paths,
+ which in Cygwin are Unix-like paths with "forward slashes" (/) and no
+ drive letters, the Cygwin specific command `cygpath` is used for most
+ of the path conversions. Luckily most compilers accept forward slashes
+ instead of backslashes as path separators, one still have to get the
+ drive letters etc right, though. The wrapper scripts are not general
+ in the sense that, for example, cc.sh would understand and translates
+ every possible gcc option and passes correct options to cl.exe. The
+ principle is that the scripts are powerful enough to allow building of
+ Erlang/OTP, no more, no less. They might need extensions to cope with
+ changes during the development of Erlang, that's one of the reasons I
+ made them into shell-scripts and not Perl-scripts, I believe they are
+ easier to understand and change that way. I might be wrong though,
+ cause another reason I didn't write them in Perl is because I've never
+ liked Perl and my Perl code is no pleasant reading...
+
+ In `$ERL_TOP`, there is a script called `otp_build`, that script handles
+ the hassle of giving all the right parameters to `configure`/`make` and
+ also helps you set up the correct environment variables to work with
+ the Erlang source under Cygwin.
+
+* Q: You use and need Cygwin, but then you haven't taken the time to
+ port Erlang to the Cygwin environment but instead focus on your
+ commercial release, is that really ethical?
+
+ A: No, not really, but see this as a step in the right direction. I'm
+ aiming at GCC compiled emulators and a Cygwin version, but I really
+ need to do other things as well... In time, but don't hold your
+ breath...
+
+* Q: Can I build something that looks exactly as the commercial release?
+
+ A: Yes, we use the exactly same build procedure.
+
+* Q: Which version of Cygwin and other tools do you use then?
+
+ A: For Cygwin we try to use the latest releases available when
+ building. What versions you use shouldn't really matter, I try to
+ include workarounds for the bugs I've found in different Cygwin
+ releases, please help me to add workarounds for new Cygwin-related
+ bugs as soon as you encounter them. Also please do submit bug reports
+ to the appropriate Cygwin developers. The Cygwin GCC we used for R13B
+ was version 3.4.4. We used VC++ 8.0 (i.e. Visual studio 2005 SP1),
+ Sun's JDK 1.5.0\_17, NSIS 2.37, and Win32 OpenSSL 0.9.8e. Please read
+ the next section for details on what you need.
+
+* Q: Can you help me setup X in Cygwin?
+
+ A: No, unfortunately I haven't got time to help with Cygwin related
+ user problems, please read Cygwin related web sites, newsgroups and
+ mailing lists.
+
+* Q: Why is the instruction so long? Is it really that complicated?
+
+ A: Partly it's long because I babble too much, partly because I've
+ described as much as I could about the installation of the needed
+ tools. Once the tools are installed, building is quite easy. I also
+ have tried to make this instruction understandable for people with
+ limited Unix experience. Cygwin is a whole new environment to some
+ Windows users, why careful explanation of environment variables etc
+ seemed to be in place. The short story, for the experienced and
+ impatient is:
+
+ * Get and install complete Cygwin (latest)
+
+ * (Buy and) Install Microsoft Visual studio 2005 and SP1 (or higher)
+
+ * Get and install Sun's JDK 1.4.2
+
+ * Get and install NSIS 2.01 or higher (up to 2.30 tried and working)
+
+ * Get and install OpenSSL 0.9.7c or higher
+
+ * Get and unpack wxWidgets-2.8.9 or higher to `/opt/local/pgm` inside
+ cygwin.
+ * Open `/cygwin/opt/local/pgm/wxWidgets-2.8.9/build/msw/wx.dsw`
+ * Enable `wxUSE_GLCANVAS`, `wxUSE_POSTSCRIPT` and
+ `wxUSE_GRAPHICS_CONTEXT` in `include/wx/msw/setup.h`
+ * Build all unicode release (and unicode debug) packages
+ * Open `/cygwin/opt/local/pgm/wxWidgets-2.8.9/contrib/build/stc/stc.dsw`
+ * Build the unicode release (and unicode debug) packages
+
+ * Get the Erlang source distribution (from
+ <http://www.erlang.org/download.html>) and unpack with Cygwin's `tar`.
+
+ * Set `ERL_TOP` to where you unpacked the source distribution
+
+ * `$ cd $ERL_TOP`
+
+ * Get (from <http://www.erlang.org/download/tcltk85_win32_bin.tar.gz>)
+ and unpack the prebuilt TCL/TK binaries for windows with cygwin tar,
+ standing in `$ERL_TOP`
+
+ * Modify PATH and other environment variables so that all these tools
+ are runnable from a bash shell. Still standing in `$ERL_TOP`, issue
+ the following commands:
+
+ $ eval `./otp_build env_win32`
+ $ ./otp_build autoconf
+ $ ./otp_build configure
+ $ ./otp_build boot -a
+ $ ./otp_build release -a
+ $ ./otp_build installer_win32
+ $ release/win32/otp_win32_<OTP version> /S
+
+ Voila! `Start->Programs->Erlang OTP <OTP version>->Erlang` starts the Erlang
+ Windows shell.
+
+
+Tools you Need and Their Environment
+------------------------------------
+
+You need some tools to be able to build Erlang/OTP on Windows. Most
+notably you'll need Cygwin and Microsoft VC++, but you also might want
+a Java compiler, the NSIS install system and OpenSSL. Only VC++ costs
+money, but then again it costs a lot of money, I know...
+Well' here's the list:
+
+* Cygwin, the very latest is usually best. Get all the development
+ tools and of course all the basic ditto. In fact getting the complete
+ package might be a good idea, as you'll start to love Cygwin after a
+ while if you're accustomed to Unix. Make sure to get jar and also make
+ sure *not* to install a Cygwin'ish Java... The Cygwin jar command is
+ used but Sun's Java compiler and virtual machine...
+
+ URL: <http://www.cygwin.com>
+
+ Get the installer from the web site and use that to install
+ Cygwin. Be sure to have fair privileges. If you're on a NT domain you
+ should consider running `mkpasswd -d` and `mkgroup -d` after the
+ installation to get the user databases correct. See their respective
+ manual pages.
+
+ When you start you first bash shell, you will get an awful prompt. You
+ might also have a `PATH` environment variable that contains backslashes
+ and such. Edit `$HOME/.profile` and `$HOME/.bashrc` to set fair prompts
+ and set a correct PATH. Also do a `export SHELL` in `.profile`. For some
+ non-obvious reason the environment variable `$SHELL` is not exported in
+ bash. Also note that `.profile` is run at login time and `.bashrc` when
+ sub shells are created. You'll need to explicitly source `.bashrc` from
+ `.profile` if you want the commands there to be run at login time (like
+ setting up aliases, shell functions and the like). I personally
+ usually do like this at the end of `.profile`:
+
+ ENV=$HOME/.bashrc
+ export ENV
+ . $ENV
+
+ You might also, if you're a hard core type of person at least, want to
+ setup X-windows (XFree86), that might be as easy as running startx
+ from the command prompt and it might be much harder. Use Google to
+ find help...
+
+ If you don't use X-windows, you might want to setup the Windows
+ console window by selecting properties in the console system menu
+ (upper left corner of the window, the Cygwin icon in the title
+ bar). Especially setting a larger screen buffer size (lines) is useful
+ as it gets you a scrollbar so you can see whatever error messages
+ that might appear...
+
+ If you want to use (t)csh instead of bash you're on your own, I
+ haven't tried and know of no one that has. I expect
+ that you use bash in all shell examples.
+
+* Microsoft Visual Studio 2005 SP1. Please don't skip the service
+ pack! The installer might update your environment so that you can run
+ the `cl` command from the bash prompt, then again it might
+ not... There is always a BAT file in VC\Bin under the installation
+ directory (default `C:\Program Files\Microsoft Visual Studio 8`) called
+ `VCVARS32.BAT`. Either add the environment settings in that file to the
+ global environment settings in Windows or add the corresponding BASH
+ environment settings to your `.profile`/`.bashrc`. For example, in my case
+ I could add the following to `.profile`
+
+ #Visual C++ Root directory as Cygwin style pathname
+ VCROOT=/cygdrive/c/Program\ Files/Microsoft\ Visual\ Studio 8
+
+ # Visual C++ Root directory as Windows style pathname
+ WIN_VCROOT="C:\\Program Files\\Microsoft Visual Studio 8"
+
+ # The PATH variable should be Cygwin'ish
+ PATH=$VCROOT/Common7/IDE:$VCROOT/VC/BIN:$VCROOT/Common7/Tools:\
+ $VCROOT/Common7/Tools/bin:$VCROOT/VC/PlatformSDK/bin:$VCROOT/SDK/v2.0/bin:\
+ $VCROOT/VC/VCPackages:$PATH
+
+ # Lib and INCLUDE should be Windows'ish
+ # Note that semicolon (;) is used to separate Windows style paths but
+ # colon (:) to separate Cygwin ditto!
+
+ LIBPATH=$WIN_VCROOT\\VC\\ATLMFC\\LIB
+
+ LIB=$WIN_VCROOT\\VC\\ATLMFC\\LIB\;$WIN_VCROOT\\VC\\LIB\;\
+ $WIN_VCROOT\\VC\\PlatformSDK\\lib\;$WIN_VCROOT\\SDK\\v2.0\\lib
+
+ INCLUDE=$WIN_VCROOT\\VC\\ATLMFC\\INCLUDE\;$WIN_VCROOT\\VC\\INCLUDE\;\
+ $WIN_VCROOT\\VC\\PlatformSDK\\include
+
+ export PATH LIB INCLUDE
+
+ Make a simple hello world and try to compile it with the `cl` command
+ from within bash. If that does not work, your environment needs
+ fixing. Also remember to fix up the PATH environment, especially old
+ Erlang installations might have inserted quoted paths that Cygwin does
+ not understand. Remove or correct such paths. There should be no
+ 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
+ result will be that jinterface is not built.
+
+ URL: <http://java.sun.com>
+
+ Add javac *LAST* to your path environment in bash, in my case this means:
+
+ PATH="$PATH:/cygdrive/c/Program Files/Java/jdk1.5.0_17/bin"
+
+ No `CLASSPATH` or anything is needed. Type `javac` at the bash prompt
+ and you should get a list of available Java options. Make sure by
+ typing `which java` that you use the Java you installed. Note however that
+ Cygwin's `jar.exe` is used, that's why the JDK bin-directory should be
+ added last in the `PATH`.
+
+* Nullsoft NSIS installer system. You need this to build the self
+ installing package. It's a free open source installer that's much
+ nicer to use than the commercial Wise and Install shield
+ installers. This is the installer we use for commercial releases as
+ well from R9C an on.
+
+ URL: <http://www.nullsoft.com/free/nsis>
+
+ Install the lot, especially the modern user interface components, as
+ it's definitely needed. Put `makensis` in your path, in my case:
+
+ PATH=/cygdrive/c/Program\ Files/NSIS:$PATH
+
+ type makensis at the bash prompt and you should get a list of options
+ if everything is OK.
+
+* OpenSSL for Windows. This is if you want the SSL and crypto
+ applications to compile (and run). Go to <http://www.openssl.org>, click
+ on the `Related` link and then on the `Binaries` link (upper right
+ corner of the page last time I looked), you can then reach the
+ "Shining Lights Productions" Web site for Windows binaries
+ distributions. Get the latest or 0.9.7c if you get trouble with the
+ latest. It's a nifty installer. The rest should be handled by
+ `configure`, you needn't put anything in the path or anything.
+
+ If you want to build openssl for windows yourself (which might be
+ possible, as you wouldn't be reading this if you weren't a
+ compile-it-yourself person), you either have to put the resulting
+ DLL's in your path or in the windows system directory and either
+ specify where you put the includes etc with the configure-parameter
+ `--with-ssl=<cygwin path to the root>` or put your installation directly
+ under `c:\OpenSSL`. The directory structure under the installation root
+ for OpenSSL is expected to be one with subdirectories named `include`,
+ `bin` and `lib`, possibly with a `VC` subdirectory of `lib` containing
+ the actual `.lib` files. Note that the cygwin distributed OpenSSL cannot be
+ used, it results in cygwin depending binaries and it has unix style
+ archives (`.a`, not `.lib`).
+
+* Building with wxWidgets. Download wxWidgets-2.8.9 or higher patch
+ release (2.9.* is a developer release which currently does not work
+ with wxErlang).
+
+ Install or unpack it to `DRIVE:/PATH/cygwin/opt/local/pgm`
+ Open from explorer (i.e. by double clicking the file)
+ `C:\cygwin\opt\local\pgm\wxMSW-2.8.10\build\msw\wx.dsw`
+ In Microsoft Visual Studio, click File/Open/File, locate and
+ open: `C:\cygwin\opt\local\pgm\wxMSW-2.8.10\include\wx\msw\setup.h`
+ enable `wxUSE_GLCANVAS`, `wxUSE_POSTSCRIPT` and `wxUSE_GRAPHICS_CONTEXT`
+ Build it by clicking Build/Batch Build and select all unicode release
+ (and unicode debug) packages.
+
+ Open `C:\cygwin\opt\local\pgm\wxMSW-2.8.10\contrib/build/stc/stc.dsw`
+ and batch build all unicode packages.
+
+* The Erlang source distribution (from <http://www.erlang.org/download.html>).
+ The same as for Unix platforms. Preferably use tar from within Cygwin to
+ unpack the source tar.gz (`tar zxf otp_src_R13B04.tar.gz`).
+
+ set the environment ERL_TOP to point to the root directory of the
+ source distribution. Let's say I stood in `$HOME/src` and unpacked
+ `otp_src_R13B04.tar.gz`, I then add the following to `.profile`:
+
+ ERL_TOP=$HOME/src/otp_src_R13B04
+ export $ERL_TOP
+
+* The TCL/TK binaries. You could compile Tcl/Tk for windows yourself,
+ but you can get a stripped down version from our website which is
+ suitable to include in the final binary package. If you want to supply
+ tcl/tk yourself, read the instructions about how the tcl/tk tar file
+ used in the build is constructed under `$ERL_TOP/lib/gs/tcl`. The easy
+ way is to download <http://www.erlang.org/download/tcltk85_win32_bin.tar.gz>
+ and unpack it standing in the `$ERL_TOP` directory. This will create the
+ file `win32.tar.gz` in `$ERL_TOP/lib/gs/tcl/binaries`.
+
+ One last alternative is to create a file named `SKIP` in the
+ `$ERL_TOP/lib/gs/` after configure is run, but that will give you an
+ erlang system without gs (which might be okay as you probably will use
+ wx anyway).
+
+The Shell Environment
+---------------------
+
+So, if you have followed the instructions above, when you start a bash
+shell, you should have an INCLUDE environment with a Windows style
+path, a LIB environment variable also in Windows style, and finally a
+PATH that let's you reach cl, makensis, javac etc from the
+command prompt (use `which cl` etc to verify from bash).
+
+You should also have an `ERL_TOP` environment variable that is *Cygwin
+style*, and points to a directory containing, among other files, the
+script `otp_build`.
+
+A final massage of the environment is needed, and that is done by
+the script `$ERL_TOP/otp_build`. Start bash and do the following, note
+the "back-ticks" (\`), can be quite hard to get on some keyboards, but
+pressing the back-tick key followed by the space bar might do it...
+
+ $ cd $ERL_TOP
+ $ eval `./otp_build env_win32`
+
+If you're unable to produce back-ticks on your keyboard, you can use
+the ksh variant:
+
+ $ cd $ERL_TOP
+ $ eval $(./otp_build env_win32)
+
+This should do the final touch to the environment and building should
+be easy after this. You could run `./otp_build env_win32` without
+`eval` just to see what it does, and to see that the environment it
+sets seems OK. The path is cleaned of spaces if possible (using DOS
+style short names instead), the variables `OVERRIDE_TARGET`, `CC`, `CXX`,
+`AR` and `RANLIB` are set to their respective wrappers and the directories
+`$ERL_TOP/erts/etc/win32/cygwin_tools/vc` and
+`$ERL_TOP/erts/etc/win32/cygwin_tool` are added first in the PATH.
+
+Try now a `which erlc`. That should result in the erlc wrapper script
+(which does not have the .sh extension, for reasons best kept
+untold...). It should reside in `$ERL_TOP/erts/etc/win32/cygwin_tools`.
+You could also try `which cc.sh`, which `ar.sh` etc.
+
+Now you're ready to build...
+
+
+Building and Installing
+-----------------------
+
+Now it's assumed that you have executed `` eval `./otp_build env_win32` ``
+for this particular shell...
+
+Building is easiest using the `otp_build` script. That script takes care
+of running configure, bootstrapping etc on Windows in a simple
+way. The `otp_build` script is the utility we use ourselves to build on
+different platforms and it therefore contains code for all sorts of
+platforms. The principle is, however, that for non-Unix platforms, one
+uses `./otp_build env_<target>` to set up environment and then the
+script knows how to build on the platform "by itself". You've already
+run `./otp_build env_win32` in the step above, so now it's mostly like
+we build on any platform. OK, here are then steps; Assuming you will
+want to build a full installation executable with NSIS, you can omit
+`<installation directory>` and the release will be copied to
+`$ERL_TOP/release/win32`: and there is where the packed self installing
+executable will reside too.
+
+ $ ./otp_build autoconf # Ignore the warning blob about versions of autoconf
+ $ ./otp_build configure <optional configure options>
+ $ ./otp_build boot -a
+ $ ./otp_build release -a <installation directory>
+ $ ./otp_build installer_win32 <installation directory> # optional
+
+Now you will have a file called `otp_win32_R12B.exe` in the
+`<installation directory>`, i.e. `$ERL_TOP/release/win32`.
+
+Lets get into more detail:
+
+`$ ./otp_build autoconf` - This step rebuilds the configure scripts to
+work correctly in the cygwin environment. In an ideal world, this
+would not be needed, but alas, we have encountered several
+incompatibilities between our distributed configure scripts (generated
+on a Linux platform) and the cygwin environment over the
+years. Running autoconf on cygwin ensures that the configure scripts
+are generated in a cygwin-compatible way and that they will work well
+in the next step.
+
+`$ ./otp_build configure` - This runs the newly generated configure scripts
+with options making configure behave nicely. The target machine type is
+plainly `win32`, so a lot of the configure-scripts recognize this
+awkward target name and behave accordingly. The CC variable also makes
+the compiler be cc.sh, which wraps MSVC++, so all configure tests
+regarding the C compiler gets to run the right compiler. A lot of the
+tests are not needed on Windows, but I thought it best to run the
+whole configure anyway. The only configure option you might want to
+supply is `--with-ssl`, which might be needed if you have built your own
+openssl distribution. The Shining Lights distribution should be found
+automatically by configure, if that fails, add a `--with-ssl=<dir>` that
+specifies the root directory of your OpenSSL installation.
+
+`$ ./otp_build boot -a` - This uses the bootstrap directory (shipped
+with the source, `$ERL_TOP/bootstrap`) to build a complete OTP
+system. It first builds an emulator and sets up a minimal OTP system
+under `$ERL_TOP/bootstrap`, then starts to compile the different OTP
+compilers to make the `$ERL_TOP/bootstrap` system potent enough to be
+able to compile all Erlang code in OTP. Then, all Erlang and C code
+under `$ERL_TOP/lib` is built using the bootstrap system, giving a
+complete OTP system (although not installed). When this is done, one
+can run Erlang from within the source tree, just type `$ERL_TOP/bin/erl`
+and you should have a prompt. If you omit the -a flag, you'll get a
+smaller system, that might be useful during development. Now
+exit from Erlang and start making a release of the thing:
+
+`$ ./otp_build release -a` - Builds a commercial release tree from the
+source tree, default is to put it in `$ERL_TOP/release/win32`, you can
+give any directory as parameter (Cygwin style), but it doesn't really matter
+if you're going to build a self extracting installer too. You could of
+course build release to the final directory and then run `./Install.exe`
+standing in the directory where the release was put, that will create
+a fully functional OTP installation. But let's make the nifty
+installer:
+
+`$ ./otp_build installer_win32` - Create the self extracting installer
+executable. The executable `otp_win32_<OTP version>.exe` will be placed
+in the top directory of the release created in the previous step. If
+no release directory is specified, the release is expected to have
+been built to `$ERL_TOP/release/win32`, which also will be the place
+where the installer executable will be placed. If you specified some
+other directory for the release (i.e.
+`./otp_build release -a /tmp/erl_release`), you're expected to give the
+same parameter here, (i.e. `./otp_build installer_win32 /tmp/erl_release`).
+You need to have a full NSIS installation and `makensis.exe` in your
+path for this to work of course. Once you have created the installer,
+you can run it to install Erlang/OTP in the regular way, just run the
+executable and follow the steps in the installation wizard. To get all
+default settings in the installation without any questions asked, you
+run the executable with the parameter `/S` (capital S). like in:
+
+ $ cd $ERL_TOP
+ $ release/win32/otp_win32_R13B04 /S
+ ...
+
+and after a while Erlang will have been installed in
+`C:\Program Files\erl5.7.5`, with shortcuts in the menu etc.
+
+*NOTE* Beginning with R9C, the Windows installer does *not* add Erlang
+to the system wide path. If one wants to have Erlang in the path, one
+has to add it by hand.
+
+The necessary setup of an Erlang installation is actually done by the
+program `Install.exe`, which resides in the release top. That program
+creates `.ini`-files and copies the correct boot scripts. If one has
+the correct directory tree (like after a `./otp_build release -a`), only
+the running of Install.exe is necessary to get a fully functional
+OTP. What the self extracting installer adds is (of course) the
+possibility to distribute the binary easily, together with adding
+shortcuts to the Windows start menu. There is also some adding of
+entries in the registry, to associate `.erl` and `.beam` files with Erlang
+and get nifty icons, but that's not something you'll really need to
+run Erlang. The registry is also used to store uninstall information,
+but if one has not used the self extracting installer, one cannot
+(need not) do any uninstall, one just scratches the release directory
+and everything is gone. Erlang/OTP does not *need* to put anything
+in the Windows registry at all, and does not if you don't use the self
+extracting installer. In other words the installer is pure cosmetics.
+
+
+Development
+-----------
+
+Once the system is built, you might want to change it. Having a test
+release in some nice directory might be useful, but you also can run
+Erlang from within the source tree. The target `local_setup`, makes
+the program `$ERL_TOP/bin/erl.exe` usable and it also uses all the OTP
+libraries in the source tree.
+
+If you hack the emulator, you can then build the emulator executable
+by standing in `$ERL_TOP/erts/emulator` and do a simple
+
+ $ make opt
+
+Note that you need to have run ``(cd $ERL_TOP && eval `./otp_build env_win32`)``
+in the particular shell before building anything on Windows. After
+doing a make opt you can test your result by running `$ERL_TOP/bin/erl`.
+If you want to copy the result to a release directory (say
+`/tmp/erl_release`), you do this (still in `$ERL_TOP/erts/emulator`)
+
+ $ make TESTROOT=/tmp/erl_release release
+
+That will copy the emulator executables.
+
+To make a debug build of the emulator, you need to recompile both
+`beam.dll` (the actual runtime system) and `erlexec.dll`. Do like this
+
+ $ cd $ERL_TOP
+ $ rm bin/win32/erlexec.dll
+ $ cd erts/emulator
+ $ make debug
+ $ cd ../etc
+ $ make debug
+
+and sometimes
+
+ $ cd $ERL_TOP
+ $ make local_setup
+
+So now when you run `$ERL_TOP/erl.exe`, you should have a debug compiled
+emulator, which you will see if you do a:
+
+ 1> erlang:system_info(system_version).
+
+in the erlang shell. If the returned string contains `[debug]`, you
+got a debug compiled emulator.
+
+To hack the erlang libraries, you simply do a `make opt` in the
+specific "applications" directory, like:
+
+ $ cd $ERL_TOP/lib/stdlib
+ $ make opt
+
+or even in the source directory...
+
+ $ cd $ERL_TOP/lib/stdlib/src
+ $ make opt
+
+Note that you're expected o have a fresh Erlang in your path when
+doing this, preferably the plain R13B04 you have built in the previous
+steps. You could also add `$ERL_TOP/bootstrap/bin` to your `PATH` before
+rebuilding specific libraries, that would give you a good enough
+Erlang system to compile any OTP erlang code. Setting up the path
+correctly is a little bit tricky, you still need to have
+`$ERL_TOP/erts/etc/win32/cygwin_tools/vc` and
+`$ERL_TOP/erts/etc/win32/cygwin_tools` *before* the actual emulator
+in the path. A typical setting of the path for using the bootstrap
+compiler would be:
+
+ $ export PATH=$ERL_TOP/erts/etc/win32/cygwin_tools/vc:$ERL_TOP/erts/etc/win32/cygwin_tools:$ERL_TOP/bootstrap/bin:$PATH
+
+That should make it possible to rebuild any library without hassle...
+
+If you want to copy a library (an application) newly built, to a
+release area, you do like with the emulator:
+
+ $ cd $ERL_TOP/lib/stdlib
+ $ make TESTROOT=/tmp/erlang_release release
+
+Remember that:
+
+* Windows specific C-code goes in the `$ERL_TOP/erts/emulator/sys/win32`,
+ `$ERL_TOP/erts/emulator/drivers/win32` or `$ERL_TOP/erts/etc/win32`.
+
+* Windows specific erlang code should be used conditionally and the
+ host OS tested in *runtime*, the exactly same beam files should be
+ distributed for every platform! So write code like:
+
+ case os:type() of
+ {win32,_} ->
+ do_windows_specific();
+ Other ->
+ do_fallback_or_exit()
+ end,
+
+That's basically all you need to get going.
+
+Final Words
+-----------
+My hope is that the possibility to build the whole system on Windows
+will open up for free development on this platform too. There are many
+things one might want to do better in the Windows version, like the
+window-style command prompt as well as pure Cygwin porting. Although i
+realize it's a much larger step to start building on Windows (with all
+the software you need) than for instance on Linux, I sincerely hope
+that some of you will make the effort and start submitting Windows
+friendly patches.
+
+The first build system for Erlang using Cygwin on Windows was created
+by Per Bergkvist. I haven't used his build system, but it's rumored to
+be good. The idea to do this came from his work, so credit is well
+deserved.
+
+Of course this would have been completely impossible without the
+excellent Cygwin package. The guys at Cygnus solutions and Redhat
+deserves a huge THANKS! as well as all the other people in the free
+software community who have helped in creating the magnificent
+software that constitutes Cygwin.
+
+Good luck and Happy Hacking,
+Patrik, OTP
+
+Copyright and License
+---------------------
+
+> %CopyrightBegin%
+>
+> Copyright Ericsson AB 2003-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%
+
+
+ [1]: http://www.erlang.org/faq.html "mailing lists"
diff --git a/INSTALL.md b/INSTALL.md
new file mode 100644
index 0000000000..452b0ff252
--- /dev/null
+++ b/INSTALL.md
@@ -0,0 +1,738 @@
+Building and Installing Erlang/OTP
+==================================
+
+Please read the whole file before attempting to build and install Erlang/OTP.
+You can find more information about Open Source Erlang/OTP at:
+
+ <http://www.erlang.org/>
+
+The source code for Erlang/OTP can also be found in a Git repository:
+
+ <http://github.com/erlang/otp>
+
+Portability
+-----------
+
+Erlang/OTP should be possible to build from source on any Unix system,
+including Mac OS X. This document describes how to native compile Erlang/OTP
+on Unix. For detailed instructions on how to
+
+* cross compile Erlang/OTP, see the [`$ERL_TOP/INSTALL-CROSS.md`] [1]
+ document.
+
+* build Erlang/OTP on Windows, see the [`$ERL_TOP/INSTALL-WIN32.md`] [2]
+ document.
+
+ Binary releases for Windows can be found at
+ <http://www.erlang.org/download.html>.
+
+However, you are in any case advised to read this document first, since it
+covers building Erlang/OTP in general as well as other important information.
+
+Daily Build and Test
+--------------------
+At Ericsson we have a "Daily Build and Test" that runs on:
+
+* Solaris 8, 9
+ * Sparc32
+ * Sparc64
+* Solaris 10
+ * Sparc32
+ * Sparc64
+ * x86
+* SuSE Linux/GNU 9.4, 10.1
+ * x86
+* SuSE Linux/GNU 10.0, 10.1
+ * x86
+ * x86_64
+* SuSE Linux/GNU 11.0
+ * x86_64
+* Gentoo Linux/GNU 1.12.11.1
+ * x86
+* MontaVista Linux/GNU 4.0.1
+ * PowerPC
+* FreeBSD 7.1
+ * x86
+* Mac OS X 10.4.11 (Tiger), 10.5.8 (Leopard), 10.6.0 (Snow Leopard)
+ * x86
+* Windows XP SP3, 2003, Vista, 7
+ * x86
+
+We also have the following "Daily Cross Builds":
+
+* SuSE Linux/GNU 10.1 x86 -> SuSE Linux/GNU 10.1 x86_64
+* SuSE Linux/GNU 10.1 x86_64 -> Linux/GNU TILEPro64
+
+and the following "Daily Cross Build Tests":
+
+* SuSE Linux/GNU 10.1 x86_64
+
+Versions Known *not* to Work
+----------------------------
+
+* Suse linux 9.1 is shipped with a patched GCC version 3.3.3, having the
+ rpm named `gcc-3.3.3-41`. That version has a serious optimization bug
+ that makes it unusable for building the Erlang emulator. Please
+ upgrade GCC to a newer version before building on Suse 9.1. Suse Linux
+ Enterprise edition 9 (SLES9) has `gcc-3.3.3-43` and is not affected.
+
+* `gcc-4.3.0` has a serious optimizer bug. It produces an Erlang emulator
+ that will crash immediately. The bug is supposed to be fixed in
+ `gcc-4.3.1`.
+
+* FreeBSD had a bug which caused `kqueue`/`poll`/`select` to fail to detect
+ that a `writev()` on a pipe has been made. This bug should have been fixed
+ in FreeBSD 6.3 and FreeBSD 7.0. NetBSD and DragonFlyBSD probably have or
+ have had the same bug. More information can be found at:
+
+ * <http://www.freebsd.org/cgi/cvsweb.cgi/src/sys/kern/sys_pipe.c>
+ * <http://lists.freebsd.org/pipermail/freebsd-arch/2007-September/006790.html>
+
+* `getcwd()` on Solaris 9 can cause an emulator crash. If you have
+ async-threads enabled you can increase the stack size of the
+ async-threads as a temporary workaround. See the `+a` command-line
+ argument in the documentation of `erl(1)`. Without async-threads the
+ emulator is not as vulnerable to this bug, but if you hit it without
+ async-threads the only workaround available is to enable async-threads
+ and increase the stack size of the async-threads. Sun has however
+ released patches that fixes the issue:
+
+ > Problem Description: 6448300 large mnttab can cause stack overrun
+ > during Solaris 9 getcwd
+
+ More information can be found at:
+
+ * <http://sunsolve.sun.com/search/document.do?assetkey=1-21-112874-40-1&searchclause=6448300>
+ * <http://sunsolve.sun.com/search/document.do?assetkey=1-21-114432-29-1&searchclause=6448300>
+
+Required Utilities
+------------------
+
+These are the tools you will need in order to unpack and build Erlang/OTP.
+
+### Unpacking ###
+
+* GNU unzip, or a modern uncompress.
+* A TAR program that understands the GNU TAR format for long filenames
+ (such as GNU TAR).
+
+### Building ###
+
+* GNU make
+* GNU C compiler
+* Perl 5
+* GNU m4 -- If hipe (native code) support is enabled.
+* ncurses (or termcap or termlib) -- The development headers and libraries
+ are needed, often known as ncurses-devel. (Use --without-termcap to build
+ without any of these libraries. Only the old shell (without any line
+ editing) can be used.)
+* OpenSSL -- Optional, but needed for building the Erlang/OTP applications
+ `ssl` and `crypto`. You need the "development package" of OpenSSL, i.e.
+ including the header files. For building the application `ssl` the OpenSSL
+ binary command program `openssl` is also needed. At least version 0.9.7
+ of OpenSSL is required. Can be downloaded from <http://www.openssl.org>.
+* Sun Java jdk-1.5.0 or higher -- Optional but needed for building the
+ Erlang/OTP application `jinterface` and parts of `ic` and `orber`. Can
+ be downloaded from <http://java.sun.com>. We have also tested IBM's
+ JDK 1.5.0.
+* X Windows -- Optional, but development headers and libraries are needed
+ to build the Erlang/OTP application `gs` on Unix/Linux.
+* `sed` -- There seem to be some problems with some of the `sed` version on
+ Solaris. Make sure `/bin/sed` or `/usr/bin/sed` is used on the Solaris
+ platform.
+* Flex -- Optional, headers and libraries are needed to build the flex
+ scanner for the `megaco` application on Unix/Linux.
+
+If you are building in a Git working directory you also have to have a GNU
+`autoconf` of at least version 2.59. Autoconf is however not needed if you
+build an unmodified version of the released source.
+
+#### Building Documentation ####
+
+* `xsltproc` -- XSLT processor. A tool for applying XSLT stylesheets
+ to XML documents. Can be downloaded from
+ <http://xmlsoft.org/XSLT/xsltproc2.html>.
+* `fop` -- Apache FOP print formatter (requires Java). Can be downloaded from
+ <http://xmlgraphics.apache.org/fop>.
+* `Markdown.pl` -- Optional. This is a `perl` script that generates an
+ HTML version of a document written in Markdown notation. Can be
+ downloaded at <http://daringfireball.net/projects/markdown>.
+
+### Installing ###
+
+* An `install` program that can take multiple file names.
+
+How to Build and Install Erlang/OTP
+-----------------------------------
+
+The following instructions are for building using the source tar ball.
+
+The variable `$ERL_TOP` will be mentioned a lot of times. It refers to
+the top directory in the source tree. More information about `$ERL_TOP`
+can be found in the "`make` and `$ERL_TOP`" section below. If you are
+building in git you probably want to take a look at the "Building in Git"
+section below before proceeding.
+
+### Unpacking ###
+
+Step 1: Start by unpacking the Erlang/OTP distribution file with your GNU
+compatible TAR program.
+
+ $ gunzip -c otp_src_R13B04.tar.gz | tar xf -
+ $ zcat otp_src_R13B04.tar.gz | tar xf -
+
+
+Step 2: Now cd into the base directory (`$ERL_TOP`).
+
+ $ cd otp_src_R13B04
+
+### Configuring ###
+
+Step 3: On some platforms Perl may behave strangely if certain locales are
+set, so optionally you may need to set the LANG variable:
+
+ # Bourne shell
+ $ LANG=C; export LANG
+
+or
+
+ # C-Shell
+ $ setenv LANG C
+
+Step 4: Run the following commands to configure the build:
+
+ $ ./configure [ options ]
+
+By default, Erlang/OTP will be installed in `/usr/local/{bin,lib/erlang}`.
+To instead install in `<BaseDir>/{bin,lib/erlang}`, use the
+`--prefix=<BaseDir>` option.
+
+If you upgraded the source with some patch you may need to clean up
+from previous builds before the new build. Do a `make clean`; see
+"Caveats" below.
+
+### Building ###
+
+Step 5: Build the Erlang/OTP package.
+
+ $ make
+
+### Installing ###
+
+Step 6: Install then Erlang/OTP package
+
+ $ make install
+
+### A Closer Look at the individual Steps ###
+
+Let us go through them in some detail.
+
+#### Configuring ####
+
+Step 4 runs a configuration script created by the GNU autoconf utility, which
+checks for system specific features and then creates a number of makefiles.
+
+The configure script allows you to customize a number of parameters;
+type `./configure --help` or `./configure --help=recursive` for details.
+`./configure --help=recursive` will give help for all `configure` scripts in
+all applications.
+
+One of the things you can specify is where Erlang/OTP should be installed: by
+default Erlang/OTP will be installed in `/usr/local/{bin,lib/erlang}`;
+to keep the same structure but install in a different place, `<Dir>` say,
+use the `--prefix` argument like this: `./configure --prefix=<Dir>`.
+
+Some of the available `configure` options are:
+
+ * `--prefix=PATH`: Specify installation prefix.
+ * `--{enable,disable}-threads`: Thread support (enabled by default if
+ possible)
+ * `--{enable,disable}-smp-support`: SMP support (enabled by default if
+ possible)
+ * `--{enable,disable}-kernel-poll`: Kernel poll support (enabled by default
+ if possible)
+ * `--{enable,disable}-hipe`: HiPE support (enabled by default on supported
+ platforms)
+ * `--enable-darwin-universal`: Build universal binaries on darwin i386.
+ * `--enable-darwin-64bit`: Build 64bit binaries on darwin
+ * `--enable-m64-build`: Build 64bit binaries using the -m64 flag to (g)cc
+ * `--enable-m32-build`: Build 32bit binaries using the -m32 flag to (g)cc
+ * `--{with,without}-termcap`: termcap (without implies that only the old
+ Erlang shell can be used)
+ * `--with-javac=JAVAC`: Specify Java compiler to use
+ * `--{with,without}-javac`: Java compiler (without implies that the
+ `jinterface` application won't be built).
+ * `--{enable,disable}-dynamic-ssl-lib`: Dynamic OpenSSL libraries
+ * `--{enable,disable}-shared-zlib`: Shared zlib library
+ * `--with-ssl=PATH`: Specify location of OpenSSL include and lib
+ * `--{with,without}-ssl`: OpenSSL (without implies that the `crypto`, `ssh`,
+ and `ssl` won't be built)
+
+If you or your system has special requirements please read the
+Makefile for additional configuration information.
+
+#### Building ####
+
+Step 5 builds the Erlang/OTP system. On a fast computer, this will take about
+5 minutes. After completion of this step, you should have a working
+Erlang/OTP system which you can try by typing `bin/erl`. This should start
+up Erlang/OTP and give you a prompt.
+
+#### Installing ####
+
+Step 6 is optional. It installs Erlang/OTP at a standardized location (if you
+change your mind about where you wish to install you can rerun step 4,
+without having to do step 5 again).
+
+##### Alternative Installation Procedures #####
+
+* Staged install using [`DESTDIR`] [3]. You can perform the install
+ phase in a temporary directory and later move the installation into
+ its correct location by use of the `DESTDIR` variable:
+
+ $ make DESTDIR=<tmp install dir> install
+
+ The installation will be created in a location prefixed by `$DESTDIR`.
+ It can, however, not be run from there. It needs to be moved into the
+ correct location before it can be run. If `DESTDIR` have not been set
+ but `INSTALL_PREFIX` has been set, `DESTDIR` will be set to
+ `INSTALL_PREFIX`. Note that `INSTALL_PREFIX` in pre R13B04 was buggy
+ and behaved as `EXTRA_PREFIX` (see below). There are lots of areas of
+ use for an installation procedure using `DESTDIR`, e.g. when creating
+ a package, cross compiling, etc. Here is an example where the
+ installation should be located under `/opt/local`:
+
+ $ ./configure --prefix=/opt/local
+ $ make
+ $ make DESTDIR=/tmp/erlang-build install
+ $ cd /tmp/erlang-build/opt/local
+ $ # gnu-tar is used in this example
+ $ tar -zcf /home/me/my-erlang-build.tgz *
+ $ su -
+ Password: *****
+ $ cd /opt/local
+ $ tar -zxf /home/me/my-erlang-build.tgz
+
+* Install using the `release` target. Instead of doing `make install` you
+ can create the installation in whatever directory you like using the
+ `release` target and run the `Install` script yourself. `RELEASE_ROOT`
+ is used for specifying the directory where the installation should be
+ created. This is what by default ends up under `/usr/local/lib/erlang`
+ if you do the install using `make install`. All installation paths
+ provided in the `configure` phase are ignored, as well as `DESTDIR`,
+ and `INSTALL_PREFIX`. If you want links from a specific `bin` directory
+ to the installation you have to set those up yourself. An example where
+ Erlang/OTP should be located at `/home/me/OTP`:
+
+ $ ./configure
+ $ make
+ $ make RELEASE_ROOT=/home/me/OTP release
+ $ cd /home/me/OTP
+ $ ./Install -minimal /home/me/OTP
+ $ mkdir -p /home/me/bin
+ $ cd /home/me/bin
+ $ ln -s /home/me/OTP/bin/erl erl
+ $ ln -s /home/me/OTP/bin/erlc erlc
+ $ ln -s /home/me/OTP/bin/escript escript
+ ...
+
+ The `Install` script should currently be invoked as follows in the
+ directory where it resides (the top directory):
+
+ $ ./Install [-cross] [-minimal|-sasl] <ERL_ROOT>
+
+ where:
+
+ * `-minimal` Creates an installation that starts up a minimal amount
+ of applications, i.e., only `kernel` and `stdlib` are started. The
+ minimal system is normally enough, and is what `make install` uses.
+ * `-sasl` Creates an installation that also starts up the `sasl`
+ application.
+ * `-cross` For cross compilation. Informs the install script that it
+ is run on the build machine.
+ * `<ERL_ROOT>` - The absolute path to the Erlang installation to use
+ at run time. This is often the same as the current working directory,
+ but does not have to be. It can follow any other path through the
+ file system to the same directory.
+
+ If neither `-minimal`, nor `-sasl` is passed as argument you will be
+ prompted.
+
+* Test install using `EXTRA_PREFIX`. The content of the `EXTRA_PREFIX`
+ variable will prefix all installation paths when doing `make install`.
+ Note that `EXTRA_PREFIX` is similar to `DESTDIR`, but it does *not* have
+ the same effect as `DESTDIR`. The installation can and have to be run
+ from the location specified by `EXTRA_PREFIX`. That is, it can be useful
+ if you want to try the system out, running test suites, etc, before doing
+ the real install without `EXTRA_PREFIX`.
+
+### Symbolic Links in `--bindir` ###
+
+When doing `make install` and the default installation prefix is used,
+relative symbolic links will be created from `/usr/local/bin` to all public
+Erlang/OTP executables in `/usr/local/lib/erlang/bin`. The installation phase
+will try to create relative symbolic links as long as `--bindir` and the
+Erlang bin directory, located under `--libdir`, both have `--exec-prefix` as
+prefix. Where `--exec-prefix` defaults to `--prefix`. `--prefix`,
+`--exec-prefix`, `--bindir`, and `--libdir` are all arguments that can be
+passed to `configure`. One can force relative, or absolute links by passing
+`BINDIR_SYMLINKS=relative|absolute` as arguments to `make` during the install
+phase. Note that such a request might cause a failure if the request cannot
+be satisfied.
+
+### Building in Git ###
+
+When building in a Git working directory you also have to have a GNU `autoconf`
+of at least version 2.59 on your system. This since you need to generate the
+`configure` scripts before you can start building.
+
+The `configure` scripts are generated by invoking `./otp_build autoconf` in
+the `$ERL_TOP` directory. The `configure` scripts also have to be regenerated
+when a `configure.in` or `aclocal.m4` file has been modified. Note that when
+checking out a branch a `configure.in` or `aclocal.m4` file may change
+content, and you may therefore have to regenerate the `configure` scripts
+when checking out a branch. Regenerated `configure` scripts imply that you
+have to run `configure` and build again.
+
+Note that running `./otp_build autoconf` is **not** needed when building an
+unmodified version the released source.
+
+Other useful information can be found at our github wiki:
+<http://wiki.github.com/erlang/otp>
+
+Pre-built Source Tree
+---------------------
+
+The source tree is delivered with a lot of platform independent
+build results already pre-built. If you want to remove these pre-built
+files, invoke `./otp_build remove_prebuilt_files` from the `$ERL_TOP`
+directory. After you have done this, you can build exactly the same way
+as before, but the build process will take a much longer time.
+
+*NOTE*: Doing `make clean` in an arbitrary directory of the source tree,
+may remove files needed for bootstrapping the build. Doing
+`./otp_build save_bootstrap` from the `$ERL_TOP` directory before
+doing `make clean` will ensure that it will be possible to build after
+doing `make clean`. `./otp_build save_bootstrap` will be invoked
+automatically when `make` is invoked from `$ERL_TOP` with either the
+`clean` target, or the default target. It is also automatically invoked
+if `./otp_build remove_prebuilt_files` is invoked.
+
+`make` and `$ERL_TOP`
+---------------------
+
+All the makefiles in the entire directory tree use the environment
+variable `ERL_TOP` to find the absolute path of the installation. The
+`configure` script will figure this out and set it in the top level
+Makefile (which, when building, it will pass on). However, when
+developing it is sometimes convenient to be able to run make in a
+subdirectory. To do this you must set the `ERL_TOP` variable
+before you run make.
+
+For example, assume your GNU make program is called `make` and you
+want to rebuild the application `STDLIB`, then you could do:
+
+ $ cd lib/stdlib; env ERL_TOP=<Dir> make
+
+where `<Dir>` would be what you find `ERL_TOP` is set to in the top level
+Makefile.
+
+How to Build the Erlang/OTP Documentation
+-----------------------------------------
+
+ $ cd $ERL_TOP
+
+If you have just built Erlang/OTP in the current source tree, you have
+already ran `configure` and do not need to do this again; otherwise, run
+`configure`.
+
+ $ ./configure [Configure Args]
+
+When building the documentation you need a full Erlang/OTP-R13B04 system in
+the `$PATH`.
+
+ $ export PATH=<Erlang/OTP-R13B04 bin dir>:$PATH # Assuming bash/sh
+
+This document as well as some other documents have been written using
+Markdown notation. HTML versions of these documents are created and included
+in the HTML documentation if the environment variable `MD2HTML` is set to a
+command that generates HTML on `stdout` for a Markdown document passed as
+argument. This is a last minute hack, which will be handled in a better way
+in the future. We currently set `MD2HTML` as follows.
+
+ $ export MD2HTML="perl <path to script>/Markdown.pl --html4tags"
+
+Build the documentation.
+
+ $ make docs
+
+The documentation can be installed either using the `install-docs` target,
+or using the `release_docs` target.
+
+* If you have installed Erlang/OTP using the `install` target, install
+ the documentation using the `install-docs` target. Install locations
+ determined by `configure` will be used. `$DESTDIR` can be used the
+ same way as when doing `make install`.
+
+ $ make install-docs
+
+* If you have installed Erlang/OTP using the `release` target, install
+ the documentation using the `release_docs` target. You typically want
+ to use the same RELEASE_ROOT as when invoking `make release`.
+
+ $ make release_docs RELEASE_ROOT=<release dir>
+
+### Build Issues ###
+
+We have sometimes experienced problems with suns `java` running out of
+memory when running `fop`. Increasing the amount of memory available
+as follows has in our case solved the problem.
+
+ $ export FOP_OPTS="-Xmx<Installed amount of RAM in MB>m"
+
+More information can be found at
+<http://xmlgraphics.apache.org/fop/0.95/running.html#memory>.
+
+How to Install the Pre-formatted Erlang/OTP Documentation
+---------------------------------------------------------
+
+Pre-formatted documentation can be downloaded at
+<http://www.erlang.org/download.html>.
+
+For some graphical tools to find the on-line help you have to install
+the HTML documentation on top of the installed OTP applications, i.e.
+
+ $ cd <ReleaseDir>
+ $ gunzip -c otp_html_R13B04.tar.gz | tar xf -
+
+For `erl -man <page>` to work the Unix manual pages have to be
+installed in the same way, i.e.
+
+ $ cd <ReleaseDir>
+ $ gunzip -c otp_man_R13B04.tar.gz | tar xf -
+
+Where `<ReleaseDir>` is
+
+* `<PrefixDir>/lib/erlang` if you have installed Erlang/OTP using
+ `make install`.
+* `$DESTDIR<PrefixDir>/lib/erlang` if you have installed Erlang/OTP
+ using `make install DESTDIR=<TmpInstallDir>`.
+* `RELEASE_ROOT` if you have installed using
+ `make release RELEASE_ROOT=<ReleaseDir>`.
+
+Support for SMP (Symmetric Multi Processing)
+--------------------------------------------
+
+An emulator with SMP support will be built by default on most platforms
+if a usable POSIX thread library or native Windows threads is found.
+
+You can force building of an SMP emulator, by using
+`./configure --enable-smp-support`. However, if configure does not
+automatically enable SMP support, the build is very likely to fail.
+
+Use `./configure --disable-smp-support` if you for some reason do not
+want to have the emulator with SMP support built.
+
+If SMP support is enabled, support for threaded I/O will also be turned on
+(also in the emulator without SMP support).
+
+The `erl` command will automatically start the SMP emulator if the
+computer has more than one logical processor. You can force a start
+of the emulator with SMP support by passing `-smp enable` as
+command line arguments to erl, and you can force a start of the
+emulator without SMP support by passing `-smp disable`.
+
+GS (Graphic System)
+-------------------
+
+GS now Tcl/Tk 8.4. It will be searched for when starting GS.
+
+Using HiPE
+----------
+
+HiPE supports the following system configurations:
+
+* x86: All 32-bit and 64-bit mode processors should work.
+
+ * Linux: Fedora Core is supported. Both 32-bit and 64-bit modes are
+ supported.
+
+ NPTL glibc is strongly preferred, or a LinuxThreads
+ glibc configured for "floating stacks". Old non-floating
+ stacks glibcs have a fundamental problem that makes HiPE
+ support and threads support mutually exclusive.
+
+ * Solaris: Solaris 10 (32-bit and 64-bit) and 9 (32-bit) are supported.
+ The build requires a version of the GNU C compiler (gcc)
+ that has been configured to use the GNU assembler (gas).
+ Sun's x86 assembler is emphatically **not** supported.
+
+ * FreeBSD: FreeBSD 6.1 and 6.2 in 32-bit and 64-bit modes should work.
+
+ * MacOSX/Darwin: Darwin 9.8.0 in 32-bit mode should work.
+
+* PowerPC: All 32-bit 6xx/7xx(G3)/74xx(G4) processors should work. 32-bit
+ mode on 970 (G5) and POWER5 processors should work.
+
+ * Linux (Yellow Dog) and Mac OSX 10.4 are supported.
+
+* SPARC: All UltraSPARC processors running 32-bit user code should work.
+
+ * Solaris 9 is supported. The build requires a `gcc` that has been
+ configured to use Sun's assembler and linker. Using the GNU assembler
+ but Sun's linker has been known to cause problems.
+
+ * Linux (Aurora) is supported.
+
+* ARM: ARMv5TE (i.e. XScale) processors should work. Both big-endian and
+ little-endian modes are supported.
+
+ * Linux is supported.
+
+HiPE is automatically enabled on the following systems:
+
+* x86 in 32-bit mode: Linux, Solaris, FreeBSD
+* x86 in 64-bit mode: Linux, Solaris, FreeBSD
+* PowerPC: Linux, MacOSX
+* SPARC: Linux
+* ARM: Linux
+
+On other supported systems you need to `./configure --enable-hipe`.
+
+If you are running on a platform supporting HiPE and if you have not disabled
+HiPE, you can compile a module into native code like this from the Erlang
+shell:
+
+ 1> c(Module, native).
+
+or
+
+ 1> c(Module, [native|OtherOptions]).
+
+Using the erlc program, write like this:
+
+ $ erlc +native Module.erl
+
+The native code will be placed into the beam file and automatically loaded
+when the beam file is loaded.
+
+To add hipe options, write like this from the Erlang shell:
+
+ 1> c(Module, [native,{hipe,HipeOptions}|MoreOptions]).
+
+Use hipe:help_options/0 to print out the available options.
+
+ 1> hipe:help_options().
+
+Mac OS X (Darwin)
+-----------------
+
+We test Mac OS X 10.4.11 (Tiger) and Mac OS X 10.5.x (Leopard) in our daily
+builds (but only on Intel processors).
+
+Make sure that the command `hostname` returns a valid fully qualified host
+name (this is configured in `/etc/hostconfig`).
+
+If you develop linked-in drivers (shared library) you need to link using
+`gcc` and the flags `-bundle -flat_namespace -undefined suppress`. You also
+include `-fno-common` in `CFLAGS` when compiling. Use `.so` as the library
+suffix.
+
+Universal 32bit binaries can be built on an Intel Mac using the
+`--enable-darwin-universal` configure option. There still may occur
+problems with certain applications using this option, but the base
+system should run smoothly.
+
+When building universal binaries on a PowerPC Mac (at least on Tiger),
+you must point out a suitable SDK that contains universal binaries.
+For instance, to build universal binaries for Tiger (10.4):
+
+ $ CFLAGS="-isysroot /Developer/SDKs/MacOSX10.4u.sdk" \
+ LDFLAGS="-isysroot /Developer/SDKs/MacOSX10.4u.sdk" \
+ ./configure --enable-darwin-universal
+
+Also, if you run Leopard, but want to build for Tiger, you must do by
+setting the `MACOSX_DEPLOYMENT_TARGET` environmental variable.
+
+ $ export MACOSX_DEPLOYMENT_TARGET=10.4
+
+Experimental support for 64bit x86 darwin binaries can be enabled
+using the `--enable-darwin-64bit` configure flag. The 64bit binaries are
+best built and run on Leopard, but most of the system also works on
+Tiger (Tiger's 64bit libraries are, however, limited; therefore e.g. `odbc`,
+`crypto`, `ssl` etc. are not supported in Tiger). 64bit PPC binaries are not
+supported and we have no plans to add such support (no machines to
+test on).
+
+Universal binaries and 64bit binaries are mutually exclusive options.
+
+How to Build a Debug Enabled Erlang RunTime System
+--------------------------------------------------
+
+After completing all the normal building steps described above a debug
+enabled runtime system can be built. To do this you have to change
+directory to `$ERL_TOP/erts/emulator`.
+
+In this directory execute:
+
+ $ make debug FLAVOR=$FLAVOR
+
+where `$FLAVOR` is either `plain` or `smp`. The flavor options will
+produce a beam.debug and beam.smp.debug executable respectively. The
+files are installed along side with the normal (opt) versions `beam.smp`
+and `beam`.
+
+To start the debug enabled runtime system execute:
+
+ $ $ERL_TOP/bin/cerl -debug
+
+The debug enabled runtime system features lock violation checking,
+assert checking and various sanity checks to help a developer ensure
+correctness. Some of these features can be enabled on a normal beam
+using appropriate configure options.
+
+There are other types of runtime systems that can be built as well
+using the similar steps just described.
+
+ $ make $TYPE FLAVOR=$FLAVOR
+
+where `$TYPE` is `opt`, `gcov`, `gprof`, `debug`, `valgrind`, or `lcnt`.
+These different beam types are useful for debugging and profiling
+purposes.
+
+Authors
+-------
+Authors are mostly listed in the application's `AUTHORS` files,
+that is `$ERL_TOP/lib/*/AUTHORS` and `$ERL_TOP/erts/AUTHORS`,
+not in the individual source files.
+
+Copyright and License
+---------------------
+
+> %CopyrightBegin%
+>
+> 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%
+
+More Information
+----------------
+
+More information can be found at <http://www.erlang.org>.
+
+
+
+ [1]: INSTALL-CROSS.html "$ERL_TOP/INSTALL-CROSS.md"
+ [2]: INSTALL-WIN32.html "$ERL_TOP/INSTALL-WIN32.md"
+ [3]: http://www.gnu.org/prep/standards/html_node/DESTDIR.html "DESTDIR"
diff --git a/Makefile.in b/Makefile.in
index 107bf80bb5..12e485754f 100644
--- a/Makefile.in
+++ b/Makefile.in
@@ -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%
# Toplevel makefile for building the Erlang system
@@ -27,6 +27,9 @@ SHELL = /bin/sh
# The top directory in which Erlang is unpacked
ERL_TOP = @ERL_TOP@
+# OTP release
+OTP = @OTP@
+
# erts (Erlang RunTime System) version
ERTS = @ERTS@
@@ -41,49 +44,111 @@ ERTS = @ERTS@
# configure.
#
-# prefix from autoconf, default is /usr/local (must be an absolute path)
-prefix = @prefix@
-exec_prefix = @exec_prefix@
+# prefix from configure, default is /usr/local (must be an absolute path)
+prefix = @prefix@
+exec_prefix = @exec_prefix@
+
+# Locations where we should install according to configure. These location
+# may be prefixed by $(DESTDIR) and/or $(EXTRA_PREFIX) (see below).
+bindir = @bindir@
+libdir = @libdir@
-# The following can be set in case you install Erlang in a different
-# location from where you have configured it to run. This can be
-# useful e.g. when installing on a server that stores the files with a
-# different path from where the clients access them. Or when building
-# rpms.
-#INSTALL_PREFIX =
-# Naah...override `prefix' instead.
+# Where Erlang/OTP is located
+libdir_suffix = /erlang
+erlang_libdir = $(libdir)$(libdir_suffix)
+erlang_bindir = $(erlang_libdir)/bin
+
+#
+# By default we install relative symbolic links for $(ERL_BASE_PUB_FILES)
+# from $(bindir) to $(erlang_bindir) as long as they are both prefixed
+# by $(exec_prefix) (and are otherwise reasonable). This behavior can be
+# overridden by passing BINDIR_SYMLINKS=<HOW>, where <HOW> is either
+# absolute or relative.
+#
+
+# $ make DESTDIR=<...> install
+#
+# DESTDIR can be set in case you want to install Erlang in a different
+# location than where you have configured it to run. This can be
+# useful, e.g. when installing on a server that stores the files with a
+# different path than where the clients access them, when building
+# rpms, or cross compiling, etc. DESTDIR will prefix the actual
+# installation which will only be able to run once the DESTDIR prefix
+# has disappeard, e.g. the part after DESTDIR has been packed and
+# unpacked without DESTDIR. The name DESTDIR have been chosen since it
+# is the GNU coding standard way of doing it.
+#
+# If INSTALL_PREFIX is set but not DESTDIR, DESTDIR will be set to
+# INSTALL_PREFIX. INSTALL_PREFIX has been buggy for a long time. It was
+# initially intended to have the same effect as DESTDIR. This effect was,
+# however, lost even before it was first released :-( In all released OTP
+# versions up to R13B03, INSTALL_PREFIX has behaved as EXTRA_PREFIX do
+# today (see below).
+
+ifeq ($(DESTDIR),)
+ifneq ($(INSTALL_PREFIX),)
+DESTDIR=$(INSTALL_PREFIX)
+endif
+else
+ifneq ($(INSTALL_PREFIX),)
+ifneq ($(DESTDIR),$(INSTALL_PREFIX))
+$(error Both DESTDIR="$(DESTDIR)" and INSTALL_PREFIX="$(INSTALL_PREFIX)" have been set and have been set differently! Please, only set one of them)
+endif
+endif
+endif
-# The directory in which user executables (ERL_BASE_PUB_FILES) are put
-BINDIR = $(INSTALL_PREFIX)@bindir@
+# $ make EXTRA_PREFIX=<...> install
+#
+# EXTRA_PREFIX behaves exactly as the buggy INSTALL_PREFIX behaved in
+# pre R13B04 releases. It adds a prefix to all installation paths which
+# will be used by the actuall installation. That is, the installation
+# needs to be located at this location when run. This is useful if you
+# want to try out the system, running test suites, etc, before doing the
+# real install using the configuration you have set up using `configure'.
+# A similar thing can be done by overriding `prefix' if only default
+# installation directories are used. However, the installation can get
+# sprawled out all over the place if the user use `--bindir', `--libdir',
+# etc, and it is possible that `prefix' wont have any effect at all. That
+# is, it is not at all the same thing as using EXTRA_PREFIX in the
+# general case. It is also nice to be able to supply this feature if
+# someone should have relied on the old buggy INSTALL_PREFIX.
+
+# The directory in which user executables (ERL_BASE_PUB_FILES) are installed
+BINDIR = $(DESTDIR)$(EXTRA_PREFIX)$(bindir)
#
# Erlang base public files
#
ERL_BASE_PUB_FILES=erl erlc epmd run_erl to_erl dialyzer typer escript
-# The directory which will contain installed Erlang version.
-# (ILIBDIR is supposed to be LIBDIR *without* the install prefix)
-ERLANG_LIBDIR = $(INSTALL_PREFIX)@libdir@/erlang
-ERLANG_ILIBDIR = @libdir@/erlang
-
-# You can *not* change these two, they have to stay this way for now.
-ERLANG_BINDIR = $(ERLANG_LIBDIR)/bin
-ERLANG_ERTSBINDIR = $(ERLANG_LIBDIR)/$(ERTS)/bin
-
-# The directory in which man pages for above executables are put
-ERL_MAN1DIR = $(INSTALL_PREFIX)@mandir@/man1
-ERL_MAN1EXT = 1
-
-# The directory in which Erlang private man pages are put. In order
-# not to clutter up the man namespace these are by default put in the
-# Erlang private directory $(ERLANG_ILIBDIR)/man. If you want to
-# install the man pages together with the rest give the argument
-# "--disable-erlang-mandir" when you run configure, which will set
-# MAN_DIR to @mandir@.
-# If you want a special suffix on the manpages set ERL_MANEXT to
-# this suffix, e.g. "erl"
-ERL_MANDIR = $(INSTALL_PREFIX)@erl_mandir@
-ERL_MANEXT =
+# ERLANG_INST_LIBDIR is the top directory where the Erlang installation
+# will be located when running.
+ERLANG_INST_LIBDIR=$(EXTRA_PREFIX)$(erlang_libdir)
+ERLANG_INST_BINDIR= $(ERLANG_INST_LIBDIR)/bin
+
+# ERLANG_LIBDIR is the top directory where the Erlang installation is copied
+# during installation. If DESTDIR != "", it cannot be run from this location.
+ERLANG_LIBDIR = $(DESTDIR)$(ERLANG_INST_LIBDIR)
+
+# ----------------------------------------------------------------------
+# This functionality has been lost along the way... :(
+# It could perhaps be nice to reintroduce some day; therefore,
+# it is not removed just commented out.
+
+## # The directory in which man pages for above executables are put
+## ERL_MAN1DIR = $(DESTDIR)$(EXTRA_PREFIX)@mandir@/man1
+## ERL_MAN1EXT = 1
+
+## # The directory in which Erlang private man pages are put. In order
+## # not to clutter up the man namespace these are by default put in the
+## # Erlang private directory $(ERLANG_LIBDIR)/man (\@erl_mandir\@ is set
+## # to $(erlang_libdir)/man). If you want to install the man pages
+## # together with the rest give the argument "--disable-erlang-mandir"
+## # when you run configure, which will set \@erl_mandir\@ to \@mandir\@.
+## # If you want a special suffix on the manpages set ERL_MANEXT to
+## # this suffix, e.g. "erl"
+## ERL_MANDIR = $(DESTDIR)$(EXTRA_PREFIX)@erl_mandir@
+## ERL_MANEXT =
# ----------------------------------------------------------------------
@@ -93,6 +158,19 @@ MAKE = @MAKE_PROG@
# This should be set to the target "arch-vendor-os"
export TARGET = @TARGET@
+BOOTSTRAP_ONLY = @BOOTSTRAP_ONLY@
+
+CROSS_COMPILING = @CROSS_COMPILING@
+ifeq ($(CROSS_COMPILING),yes)
+INSTALL_CROSS = -cross
+else
+ifneq ($(DESTDIR),)
+INSTALL_CROSS = -cross
+else
+INSTALL_CROSS =
+endif
+endif
+
# A BSD compatible install program
INSTALL = @INSTALL@
INSTALL_PROGRAM = @INSTALL_PROGRAM@
@@ -107,6 +185,12 @@ RANLIB = @RANLIB@
# ----------------------------------------------------------------------
+# By default we require an Erlang/OTP of the same release as the one
+# we cross compile.
+ERL_XCOMP_FORCE_DIFFERENT_OTP = no
+
+# ----------------------------------------------------------------------
+
#
# The directory where at least the primary bootstrap is placed under.
#
@@ -136,6 +220,57 @@ BOOT_PREFIX=$(WIN32_WRAPPER_PATH):$(BOOTSTRAP_ROOT)/bootstrap/bin:
else
BOOT_PREFIX=$(BOOTSTRAP_ROOT)/bootstrap/bin:
endif
+
+# ----------------------------------------------------------------------
+
+# The following is currently only used for determining what to prevent
+# usage of during strict install or release.
+include $(ERL_TOP)/make/$(TARGET)/otp_ded.mk
+CC = @CC@
+LD = @LD@
+CXX = @CXX@
+
+IBIN_DIR = $(ERL_TOP)/ibin
+#
+# If $(OTP_STRICT_INSTALL) equals `yes' we prefix the PATH with $(IBIN_DIR)
+# when doing `release' or `install'. This directory contains `erlc', `gcc',
+# `ld' etc, that unconditionally will fail if used. This is used during the
+# daily builds in order to pick up on things being erroneously built during
+# the `release' and `install' phases.
+#
+INST_FORBID = gcc g++ cc c++ cxx cl gcc.sh cc.sh ld ld.sh
+INST_FORBID += javac.sh javac guavac gcj jikes bock
+INST_FORBID += $(notdir $(CC)) $(notdir $(LD)) $(notdir $(CXX))
+INST_FORBID += $(notdir $(DED_CC)) $(notdir $(DED_LD))
+INST_FORBID += $(ERL_BASE_PUB_FILES)
+IBIN_FILES = $(addprefix $(IBIN_DIR)/,$(sort $(INST_FORBID))) # sort will
+ # remove
+ # duplicates
+
+ifeq ($(OTP_STRICT_INSTALL),yes)
+
+INST_PATH_PREFIX=$(IBIN_DIR):
+INST_DEP = strict_install
+ifneq ($(CROSS_COMPILING),yes)
+INST_DEP += strict_install_all_bootstraps
+endif
+
+else # --- Normal case, i.e., not strict install ---
+
+#
+# By default we allow build during install and release phase; therefore,
+# make sure that the bootstrap system is available in the path.
+#
+INST_PATH_PREFIX=$(BOOT_PREFIX)
+# If cross compiling `erlc', in path might have be used; therefore,
+# avoid triggering a bootstrap build...
+INST_DEP =
+ifneq ($(CROSS_COMPILING),yes)
+INST_DEP += all_bootstraps
+endif
+
+endif # --- Normal case, i.e., not strict install ---
+
# ----------------------------------------------------------------------
# Fix up RELEASE_ROOT/TESTROOT havoc
ifeq ($(RELEASE_ROOT),)
@@ -164,13 +299,54 @@ endif
# * build additional compilers and copy them into bootstrap/lib
# * use the bootstrap erl and erlc to build all the libs
#
-all: all_bootstraps \
- libs local_setup dialyzer
+
+.PHONY: all bootstrap all_bootstraps
+
+ifneq ($(CROSS_COMPILING),yes)
+# Not cross compiling
+
+ifeq ($(BOOTSTRAP_ONLY),yes)
+all: bootstrap
+else
+# The normal case; not cross compiling, and not bootstrap only build.
+all: bootstrap libs local_setup dialyzer
+endif
+
+else
+# Cross compiling
+
+all: cross_check_erl depend emulator libs start_scripts dialyzer
+
+endif
+
+cross_check_erl:
+ @PATH=$(BOOT_PREFIX)$${PATH} $(ERL_TOP)/make/cross_check_erl \
+ -target $(TARGET) -otp $(OTP) -erl_top $(ERL_TOP) \
+ -force $(ERL_XCOMP_FORCE_DIFFERENT_OTP)
+
+is_cross_configured:
+ @echo @CROSS_COMPILING@
+
+target_configured:
+ @echo @TARGET@
+
+bootstrap: depend all_bootstraps
+
+
+
+ifeq ($(OTP_STRICT_INSTALL),yes)
+
+.PHONY: strict_install_all_bootstraps
+
+strict_install_all_bootstraps:
+ $(MAKE) BOOT_PREFIX=$(INST_PATH_PREFIX) OTP_STRICT_INSTALL=$(OTP_STRICT_INSTALL) all_bootstraps
+
+endif
# With all bootstraps we mean all bootstrapping that is done when
# the system is delivered in open source, the primary
# bootstrap is not included, it requires a pre built emulator...
-all_bootstraps: depend emulator \
+all_bootstraps: emulator \
bootstrap_setup \
secondary_bootstrap_build secondary_bootstrap_copy \
tertiary_bootstrap_build tertiary_bootstrap_copy \
@@ -193,11 +369,15 @@ noboot_install:
.PHONY: release release_docs
-release:
+release: $(INST_DEP)
ifeq ($(OTP_SMALL_BUILD),true)
- cd $(ERL_TOP)/lib && $(MAKE) TESTROOT=$(RELEASE_ROOT) release
+ cd $(ERL_TOP)/lib && \
+ ERL_TOP=$(ERL_TOP) PATH=$(INST_PATH_PREFIX)$${PATH} \
+ $(MAKE) TESTROOT=$(RELEASE_ROOT) release
else
- cd $(ERL_TOP)/lib && $(MAKE) BUILD_ALL=1 TESTROOT=$(RELEASE_ROOT) release
+ cd $(ERL_TOP)/lib && \
+ ERL_TOP=$(ERL_TOP) PATH=$(INST_PATH_PREFIX)$${PATH} \
+ $(MAKE) BUILD_ALL=1 TESTROOT=$(RELEASE_ROOT) release
ifneq ($(findstring vxworks,$(TARGET)),vxworks)
@if test -f lib/dialyzer/SKIP ; then \
echo "=== Skipping dialyzer, reason:" ; \
@@ -205,24 +385,67 @@ ifneq ($(findstring vxworks,$(TARGET)),vxworks)
echo "===" ; \
else \
cd $(ERL_TOP)/lib/dialyzer && \
- $(MAKE) BUILD_ALL=1 TESTROOT=$(RELEASE_ROOT) release ; \
+ ERL_TOP=$(ERL_TOP) PATH=$(INST_PATH_PREFIX)$${PATH} \
+ $(MAKE) BUILD_ALL=1 TESTROOT=$(RELEASE_ROOT) release ; \
fi
endif
endif
- cd $(ERL_TOP)/erts && $(MAKE) BUILD_ALL=1 TESTROOT=$(RELEASE_ROOT) release
+ cd $(ERL_TOP)/erts && \
+ ERL_TOP=$(ERL_TOP) PATH=$(INST_PATH_PREFIX)$${PATH} \
+ $(MAKE) BUILD_ALL=1 TESTROOT=$(RELEASE_ROOT) release
# ---------------------------------------------------------------
# Target only used when building commercial ERTS patches
# ---------------------------------------------------------------
-release_docs:
+release_docs docs: html_readmes
ifeq ($(OTP_SMALL_BUILD),true)
- cd $(ERL_TOP)/lib && $(MAKE) TESTROOT=$(RELEASE_ROOT) release_docs
+ cd $(ERL_TOP)/lib && \
+ ERL_TOP=$(ERL_TOP) $(MAKE) TESTROOT=$(RELEASE_ROOT) $@
else
- cd $(ERL_TOP)/lib && $(MAKE) BUILD_ALL=1 TESTROOT=$(RELEASE_ROOT) release_docs
- cd $(ERL_TOP)/lib/dialyzer && $(MAKE) BUILD_ALL=1 TESTROOT=$(RELEASE_ROOT) release_docs
+ cd $(ERL_TOP)/lib && \
+ ERL_TOP=$(ERL_TOP) $(MAKE) BUILD_ALL=1 TESTROOT=$(RELEASE_ROOT) $@
+ cd $(ERL_TOP)/lib/dialyzer && \
+ ERL_TOP=$(ERL_TOP) $(MAKE) BUILD_ALL=1 TESTROOT=$(RELEASE_ROOT) $@
endif
- cd $(ERL_TOP)/erts && $(MAKE) BUILD_ALL=1 TESTROOT=$(RELEASE_ROOT) release_docs
-
+ cd $(ERL_TOP)/erts && \
+ ERL_TOP=$(ERL_TOP) $(MAKE) BUILD_ALL=1 TESTROOT=$(RELEASE_ROOT) $@
+ cd $(ERL_TOP)/system/doc && \
+ ERL_TOP=$(ERL_TOP) $(MAKE) TESTROOT=$(RELEASE_ROOT) $@
+
+.PHONY: html_readmes clean_html_readmes
+
+HTML_READMES = INSTALL.html INSTALL-WIN32.html INSTALL-CROSS.html
+
+html_readmes: $(HTML_READMES)
+
+clean_html_readmes:
+ rm -f $(HTML_READMES)
+
+%.html: %.md
+ echo "<!DOCTYPE html PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\">" > $@
+ echo "<html xmlns:fn=\"http://www.w3.org/2005/02/xpath-functions\"><head>" >> $@
+ echo "<meta http-equiv=\"Content-Type\" content=\"text/html; charset=UTF-8\">" >> $@
+ echo "<style type=\"text/css\">" >> $@
+ echo "body {" >> $@
+ echo " margin: 4em 4em 4em 4em;" >> $@
+ echo " background: white;" >> $@
+ echo " font-family: Verdana, Arial, Helvetica, sans-serif;" >> $@
+ echo "}" >> $@
+ echo "code { font-family: courier;font-weight: normal}" >> $@
+ echo "a:link { color: blue; text-decoration: none }" >> $@
+ echo "a:active { color: blue; text-decoration: none }" >> $@
+ echo "a:visited { color: blue; text-decoration: none }" >> $@
+ echo "</style><title>" >> $@
+ cat $< | sed -n "s/[ ]*\([^ ].*[^ ]\)[ ]*/\1/p;/[ ]*[^ ][ ]*/q" >> $@
+ echo "</title></head><body>" >> $@
+ifneq ($(MD2HTML),)
+ $(MD2HTML) $< >> $@
+else
+ echo "<pre>" >> $@
+ cat $< | sed "s|\&|\&amp\;|g;s|\"|\&quot\;|g;s|<|\&lt\;|g;s|>|\&gt\;|g" >> $@
+ echo "</pre>" >> $@
+endif
+ echo "</body></html>" >> $@
# ----------------------------------------------------------------------
ERLANG_EARS=$(BOOTSTRAP_ROOT)/bootstrap/erts
@@ -352,7 +575,6 @@ secondary_bootstrap_copy:
cp $$x $$TF; \
true; \
done
- rm -f lib/hipe/ebin/*.beam
# if test -f lib/hipe/ebin/hipe.beam ; then cp lib/hipe/ebin/*.beam $(BOOTSTRAP_ROOT)/bootstrap/lib/hipe/ebin; fi
if test ! -d $(BOOTSTRAP_ROOT)/bootstrap/lib/parsetools ; then mkdir $(BOOTSTRAP_ROOT)/bootstrap/lib/parsetools ; fi
if test ! -d $(BOOTSTRAP_ROOT)/bootstrap/lib/parsetools/ebin ; then mkdir $(BOOTSTRAP_ROOT)/bootstrap/lib/parsetools/ebin ; fi
@@ -441,6 +663,8 @@ fourth_bootstrap_copy:
if test ! -d $(BOOTSTRAP_ROOT)/bootstrap/lib/wx ; then mkdir $(BOOTSTRAP_ROOT)/bootstrap/lib/wx ; fi
if test ! -d $(BOOTSTRAP_ROOT)/bootstrap/lib/wx/ebin ; then mkdir $(BOOTSTRAP_ROOT)/bootstrap/lib/wx/ebin ; fi
if test ! -d $(BOOTSTRAP_ROOT)/bootstrap/lib/wx/include ; then mkdir $(BOOTSTRAP_ROOT)/bootstrap/lib/wx/include ; fi
+ if test ! -d $(BOOTSTRAP_ROOT)/bootstrap/lib/test_server ; then mkdir $(BOOTSTRAP_ROOT)/bootstrap/lib/test_server ; fi
+ if test ! -d $(BOOTSTRAP_ROOT)/bootstrap/lib/test_server/include ; then mkdir $(BOOTSTRAP_ROOT)/bootstrap/lib/test_server/include ; fi
for x in lib/ic/ebin/*.beam; do \
BN=`basename $$x`; \
TF=$(BOOTSTRAP_ROOT)/bootstrap/lib/ic/ebin/$$BN; \
@@ -506,6 +730,16 @@ fourth_bootstrap_copy:
cp $$x $$TF; \
true; \
done
+ for x in lib/test_server/include/*.hrl; do \
+ BN=`basename $$x`; \
+ TF=$(BOOTSTRAP_ROOT)/bootstrap/lib/test_server/include/$$BN; \
+ test -f $$TF && \
+ test '!' -z "`find $$x -newer $$TF -print`" && \
+ cp $$x $$TF; \
+ test '!' -f $$TF && \
+ cp $$x $$TF; \
+ true; \
+ done
# cp lib/syntax_tools/ebin/*.beam $(BOOTSTRAP_ROOT)/bootstrap/lib/syntax_tools/ebin
@@ -641,9 +875,13 @@ primary_bootstrap_copy:
KERNEL_PRELOAD = otp_ring0 init erl_prim_loader prim_inet prim_file zlib prim_zip erlang
KERNEL_PRELOAD_BEAMS=$(KERNEL_PRELOAD:%=$(BOOTSTRAP_TOP)/lib/kernel/ebin/%.beam)
+start_scripts:
+ @cd erts/start_scripts \
+ && ERL_TOP=$(ERL_TOP) PATH=$(BOOT_PREFIX)$${PATH} $(MAKE) script
+
# Creates "erl" and "erlc" scripts in bin/erl which uses the libraries in lib
local_setup:
- @rm -f erts/bin/erl erts/bin/erlc erts/bin/cerl
+ @rm -f bin/erl bin/erlc bin/cerl
@cd erts && \
ERL_TOP=$(ERL_TOP) PATH=$(BOOT_PREFIX)$${PATH} \
$(MAKE) local_setup
@@ -716,21 +954,28 @@ bootstrap_nc_for_ne_no_debug_sym:
#
# Order is important here, don't change it!
#
-install: install.dirs install.emulator install.libs install.Install install.bin
+INST_DEP += install.dirs install.emulator install.libs install.Install install.bin
+
+install: $(INST_DEP)
+
+install-docs:
+ ERL_TOP=$(ERL_TOP) INSTALLROOT=$(ERLANG_LIBDIR) PATH=$(BOOT_PREFIX)$${PATH} \
+ $(MAKE) RELEASE_ROOT=$(ERLANG_LIBDIR) release_docs
+
install.emulator:
cd erts && \
- ERL_TOP=$(ERL_TOP) PATH=$(BOOT_PREFIX)$${PATH} \
+ ERL_TOP=$(ERL_TOP) PATH=$(INST_PATH_PREFIX)$${PATH} \
$(MAKE) TESTROOT=$(ERLANG_LIBDIR) release
install.libs:
ifeq ($(OTP_SMALL_BUILD),true)
cd lib && \
- ERL_TOP=$(ERL_TOP) PATH=$(BOOT_PREFIX)$${PATH} \
+ ERL_TOP=$(ERL_TOP) PATH=$(INST_PATH_PREFIX)$${PATH} \
$(MAKE) TESTROOT=$(ERLANG_LIBDIR) release
else
cd lib && \
- ERL_TOP=$(ERL_TOP) PATH=$(BOOT_PREFIX)$${PATH} \
+ ERL_TOP=$(ERL_TOP) PATH=$(INST_PATH_PREFIX)$${PATH} \
$(MAKE) TESTROOT=$(ERLANG_LIBDIR) BUILD_ALL=true release
@if test -f lib/dialyzer/SKIP ; then \
echo "=== Skipping dialyzer, reason:" ; \
@@ -738,22 +983,27 @@ else
echo "===" ; \
else \
cd lib/dialyzer && \
- ERL_TOP=$(ERL_TOP) PATH=$(BOOT_PREFIX)$${PATH} \
+ ERL_TOP=$(ERL_TOP) PATH=$(INST_PATH_PREFIX)$${PATH} \
$(MAKE) TESTROOT=$(ERLANG_LIBDIR) BUILD_ALL=true release ; \
fi
endif
install.Install:
- cd $(ERLANG_LIBDIR) && ./Install -minimal $(ERLANG_LIBDIR)
+ (cd $(ERLANG_LIBDIR) \
+ && ./Install $(INSTALL_CROSS) -minimal $(ERLANG_INST_LIBDIR))
#
# Install erlang base public files
#
+
install.bin:
- for file in $(ERL_BASE_PUB_FILES); do \
- rm -f $(BINDIR)/$$file; \
- ${LN_S} $(ERLANG_BINDIR)/$$file $(BINDIR)/$$file; \
- done
+ @ DESTDIR="$(DESTDIR)" EXTRA_PREFIX="$(EXTRA_PREFIX)" \
+ LN_S="$(LN_S)" BINDIR_SYMLINKS="$(BINDIR_SYMLINKS)" \
+ $(ERL_TOP)/make/install_bin \
+ --bindir "$(bindir)" \
+ --erlang-bindir "$(erlang_bindir)" \
+ --exec-prefix "$(exec_prefix)" \
+ $(ERL_BASE_PUB_FILES)
#
# Directories needed before we can install
@@ -763,6 +1013,17 @@ install.dirs:
${MKSUBDIRS} $(ERLANG_LIBDIR)
${MKSUBDIRS} $(ERLANG_LIBDIR)/usr/lib
+.PHONY: strict_install
+
+strict_install: $(IBIN_DIR) $(IBIN_FILES)
+
+$(IBIN_FILES): $(ERL_TOP)/make/unexpected_use
+ rm -f $@
+ (cd $(dir $@) && $(LN_S) $(ERL_TOP)/make/unexpected_use $(notdir $@))
+
+$(IBIN_DIR):
+ $(MKSUBDIRS) $@
+
# ----------------------------------------------------------------------
.PHONY: clean eclean bootstrap_root_clean bootstrap_clean
@@ -771,8 +1032,8 @@ install.dirs:
# Clean targets
#
-clean: check_recreate_primary_bootstrap
- rm -f *~ *.bak config.log config.status prebuilt.files
+clean: check_recreate_primary_bootstrap clean_html_readmes
+ rm -f *~ *.bak config.log config.status prebuilt.files ibin/*
find . -type f -name SKIP -print | xargs $(RM)
cd erts && ERL_TOP=$(ERL_TOP) $(MAKE) clean
cd lib && ERL_TOP=$(ERL_TOP) $(MAKE) clean BUILD_ALL=true
diff --git a/README b/README
deleted file mode 100644
index 50280169a0..0000000000
--- a/README
+++ /dev/null
@@ -1,472 +0,0 @@
-===========================================================================
- OpenSource Erlang/OTP
-===========================================================================
-
-
-Please read the whole file before attempting to build and install Erlang.
-You can find more information about OpenSource Erlang at
-
- http://www.erlang.org/
-
-The source code for Erlang/OTP can also be found in a Git
-repository at
-
- http://github.com/erlang/otp
-
-%CopyrightBegin%
-
-Copyright Ericsson AB 1998-2009. All Rights Reserved.
-
-The contents of this file are subject to the Erlang Public License,
-Version 1.1, (the "License"); you may not use this file except in
-compliance with the License. You should have received a copy of the
-Erlang Public License along with this software. If not, it can be
-retrieved online at http://www.erlang.org/.
-
-Software distributed under the License is distributed on an "AS IS"
-basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-the License for the specific language governing rights and limitations
-under the License.
-
-%CopyrightEnd%
-
-
-Portability
------------
-
-Erlang/OTP should be possible to build from source on any Unix
-system, including Mac OS X.
-
-Instructions for building from source on Windows are in the file README.win32.
-Binary releases for Windows can be found at http://www.erlang.org/
-
-At Ericsson we have a "Daily Build and Test" that runs on:
-
- Operating system Versions
- -----------------------------------------------------------
- Solaris/Sparc32 8, 9, 10
- Solaris/Sparc64 10
- Solaris/x86 10
- Linux/Suse x86 9.4, 10.1
- Linux/Suse x86_64 10.0, 10.1, 11.0
- FreeBSD x86 7.1
- Mac OS X/Intel 10.4.11 (Tiger), 10.5.8 (Leopard)
- Windows XP SP3, 2003, Vista
-
-We have also done some testing on Mac OS 10.6.0 (Snow Leopard).
-
-
-Versions known *not* to work
--------------------------------------
-
-Suse linux 9.1 is shipped with a patched GCC version 3.3.3, having the
-rpm named gcc-3.3.3-41. That version has a serious optimization bug
-that makes it unusable for building the Erlang emulator. Please
-upgrade GCC to a newer version before building on Suse 9.1. Suse Linux
-EnterpriSe edition 9 (SLES9) has gcc-3.3.3-43 and is not affected.
-
-gcc-4.3.0 has a serious optimizer bug. It produces an Erlang emulator
-that will crash immediately. The bug is supposed to be fixed in gcc-4.3.1.
-
-FreeBSD had a bug which caused kqueue/poll/select to fail to detect
-that a writev() on a pipe has been made. This bug should have been fixed
-in FreeBSD 6.3 and FreeBSD 7.0. More information can be found at:
-* http://www.freebsd.org/cgi/cvsweb.cgi/src/sys/kern/sys_pipe.c
-* http://lists.freebsd.org/pipermail/freebsd-arch/2007-September/006790.html
-NetBSD and DragonFlyBSD probably have or have had the same bug.
-
-getcwd() on Solaris 9 can cause an emulator crash. If you have async-threads
-enabled you can increase the stack size of the async-threads as a temporary
-workaround. See the +a command-line argument in the documentation of erl(1).
-Without async-threads the emulator isn't as vulnerable to this bug, but if
-you hit it without async-threads the only workaround available is to enable
-async-threads and increase the stack size of the async-threads.
-Sun has however released patches that fixes the issue:
-Problem Description: 6448300 large mnttab can cause stack overrun during
- Solaris 9 getcwd
-* http://sunsolve.sun.com/search/document.do?assetkey=1-21-112874-40-1&searchclause=6448300
-* http://sunsolve.sun.com/search/document.do?assetkey=1-21-114432-29-1&searchclause=6448300
-
-Required utilities
-------------------
-
-These are the tools you will need in order to unpack and build Erlang/OTP.
-
- Unpacking
- ---------
-
- GNU unzip, or a modern uncompress.
-
- A TAR program that understands the GNU TAR format for long
- filenames (such as GNU TAR).
-
-
- Compiling
- ---------
-
- GNU make
-
- GNU C compiler
-
- Perl 5
-
- GNU m4 If hipe (native code) support is enabled.
-
- ncurses (Or termcap or termlib.) The development headers and
- libraries are needed, often known as ncurses-devel.
- (Use --without-termcap to build without any of these
- libraries. Only the old shell (without any line
- editing) can be used.)
-
- OpenSSL Optional, but needed for building the Erlang/OTP
- applications 'ssl' and 'crypto'. You need the
- "development package" of OpenSSL, i.e. including
- the header files. For building the application 'ssl'
- the OpenSSL binary command program 'openssl' is also
- needed.
-
- At least version 0.9.7 of OpenSSL is required.
-
- Sun Java jdk-1.5.0 Or higher. Optional but needed for building
- the Erlang/OTP application 'jinterface' and parts
- of 'ic' and 'orber'. We have also tested
- IBM's JDK 1.5.0.
-
- X Windows Optional, but development headers and libraries
- are needed to build the Erlang/OTP application 'gs'
- on Unix/Linux.
-
- sed There seem to be some problems with some of the
- 'sed' version on Solaris. Make sure "/bin/sed"
- or "/usr/bin/sed" is used on the Solaris platform.
-
- Flex Optional, headers and libraries are needed to
- build the flex scanner for the megaco application
- on Unix/Linux.
-
-
- Installing
- ----------
-
- An 'install' program that can take multiple file names.
-
-
-How to build and install Erlang/OTP
------------------------------------
-
-If you are building in a Git reposistory, see
-
- http://wiki.github.com/erlang/otp
-
-The following instructions are for building using the
-source tar ball.
-
-Start by unpacking the Erlang/OTP distribution file with your
-GNU compatible TAR
-
- 1) gunzip -c otp_src_R13B03.tar.gz | tar xf -
- 1) zcat otp_src_R13B03.tar.gz | tar xf -
-
-Now cd into the base directory
-
- 2) cd otp_src_R13B03
-
-On some platforms Perl may behave strangely if certain locales are set,
-so optionally you may need to set the LANG variable:
-
- 3a) LANG=C; export LANG #Bourne shell
-or
- 3b) setenv LANG C #C-shell
-
-Run the following commands
-
- 4a) ./configure [ options ]
-or
- 4b) ./configure --prefix=<BaseDir> [ other options ]
-
-By default, Erlang/OTP will be installed in /usr/local/{bin,lib/erlang,man/man1}.
-To instead install in <BaseDir>/{bin,lib/erlang,man/man1}, use the --prefix=<BaseDir>
-option.
-
-If you upgraded the source with some patch you may need to clean up
-from previous builds before the new build. Do a "make clean"; see
-"Caveats" below.
-
- 5) make
- 6) make install
-
-Let's go through them in some detail:
-
-Step 4 runs a configuration script created by the GNU autoconf
-utility, which checks for system specific features and then creates a
-number of makefiles.
-
-The configure script allows you to customize a number of parameters;
-type "./configure --help" for details.
-
-One of the things you can specify is where Erlang/OTP should be installed: by
-default Erlang/OTP will be installed in /usr/local/{bin,lib/erlang,man/man1};
-to keep the same structure but install in a different place, <Dir> say,
-use the --prefix argument like this:
-"./configure --prefix=<Dir>".
-
-This step will also configure any additional libraries unpacked in step 3
-(if you didn't add any of the extra libraries configure will issue a warning
-saying that there is no configuration information in lib; this warning can
-safely be ignored).
-
-You can also specify where the OpenSSL include and library files are
-located, or alternatively disable the use of SSL and Crypto.
-(The details can be found by typing './configure --help'.)
-
-Other options are:
-
- --enable-smp-support See the next section.
-
- --disable-smp-support See the next section.
-
- --disable-threads Disable support for threaded I/O;
- this option also disables building
- of the SMP emulator. (See the next section.)
-
- --enable-threads Enable support for threaded I/O.
- (This is the default if SMP support is enabled.
- See the next section.)
-
- --disable-hipe Disable HiPE (High-Performance Erlang).
- HiPE will automatically be enabled on
- supported platforms.
-
-
- Step 5 builds the Erlang/OTP system. On a fast computer,
-this will take about 5 minutes. After completion of this step,
-you should have a working Erlang/OTP system which you can
-try by typing "bin/erl". This should start up Erlang/OTP and give you
-a prompt.
-
- Step 6 is optional. It installs Erlang/OTP (if you change your
-mind about where you wish to install you can rerun step 4, without
-having to do step 5 again).
-
-The source tree is delivered with a lot of platform independent
-build results already pre-built. If you want to remove these pre-built
-files, invoke './otp_build remove_prebuilt_files' from the $ERL_TOP
-directory. After you have done this, you can build exactly the same way
-as before, but the build process will take a much longer time.
-
-NOTE: Doing 'make clean' in an arbitrary directory of the source tree,
-may remove files needed for bootstrapping the build. Doing
-'./otp_build save_bootstrap' from the $ERL_TOP directory before
-doing 'make clean' will ensure that it will be possible to build after
-doing 'make clean'. './otp_build save_bootstrap' will be invoked
-automatically when 'make' is invoked from ERL_TOP with either the
-clean target, or the default target. It is also automatically invoked
-if './otp_build remove_prebuilt_files' is invoked.
-
-If you or your system has special requirements please read the
-Makefile for additional configuration information.
-
-Support for SMP (Symmetric Multi Processing)
---------------------------------------------
-
-An emulator with SMP support will be built by default on most platforms
-if a usable POSIX thread library or native Windows threads is found.
-
-You can force building of an SMP emulator, by using
-"./configure --enable-smp-support". However, if configure doesn't
-automatically enable SMP support, the build is very likely to fail.
-
-Use "./configure --disable-smp-support" if you for some reason don't
-want to have the emulator with SMP support built.
-
-If SMP support is enabled, support for threaded I/O will also be turned on
-(also in the emulator without SMP support).
-
-The 'erl' command will automatically start the SMP emulator if the
-computer has more than one logical processor. You can force a start
-of the emulator with SMP support by passing '-smp enable' as
-command line arguments to erl, and you can force a start of the
-emulator without SMP support by passing '-smp disable'.
-
-How to install the Erlang/OTP documentation
--------------------------------------------
-
-For some graphical tools to find the on-line help you have to install
-the HTML documentation on top of the installed OTP applications, i.e.
-
- cd <PrefixDir>/lib/erlang
- gunzip -c otp_html_R<XY>B-<Z>.tar.gz | tar xf -
-
-For "erl -man <page>" to work the Unix manual pages have to be
-installed in the same way, i.e.
-
- cd <PrefixDir>/lib/erlang
- gunzip -c otp_man_R<XY>B-<Z>.tar.gz | tar xf -
-
-
-GS (Graphic System)
--------------------
-
-GS now Tcl/Tk 8.4. It will be searched for when starting GS.
-
-
-Using HiPE
-----------
-
-HiPE supports the following system configurations:
-
-x86:
- All 32-bit and 64-bit mode processors should work.
-
- The following systems are supported:
-
- Linux:
- Fedora Core is supported.
- Both 32-bit and 64-bit modes are supported.
-
- NPTL glibc is strongly preferred, or a LinuxThreads
- glibc configured for "floating stacks". Old non-floating
- stacks glibcs have a fundamental problem that makes HiPE
- support and threads support mutually exclusive.
- Solaris:
- Solaris 10 (32-bit and 64-bit) and 9 (32-bit) are
- supported.
-
- The build requires a version of the GNU C compiler (gcc)
- that has been configured to use the GNU assembler (gas).
- Sun's x86 assembler is emphatically /not/ supported.
- FreeBSD:
- FreeBSD 6.1 and 6.2 in 32-bit and 64-bit modes should work.
- MacOSX/Darwin:
- Darwin 9.8.0 in 32-bit mode should work.
-
-PowerPC:
- All 32-bit 6xx/7xx(G3)/74xx(G4) processors should work.
- 32-bit mode on 970 (G5) and POWER5 processors should work.
-
- Linux (Yellow Dog) and Mac OSX 10.4 are supported.
-
-SPARC:
- All UltraSPARC processors running 32-bit user code should work.
-
- Solaris 9 and Linux (Aurora) are supported.
-
- On Solaris the build requires a gcc that has been configured
- to use Sun's assembler and linker. Using the GNU assembler but
- Sun's linker has been known to cause problems.
-ARM:
- ARMv5TE (i.e. XScale) processors should work.
- Both big-endian and little-endian modes are supported.
-
- Linux is supported.
-
-HiPE is automatically enabled on the following systems:
- x86 in 32-bit mode: Linux, Solaris, FreeBSD
- x86 in 64-bit mode: Linux, Solaris, FreeBSD
- PowerPC: Linux, MacOSX
- SPARC: Linux
- ARM: Linux
-On other supported systems you need to "./configure --enable-hipe".
-
-
-If you are running on a platform supporting HiPE and if
-you have not disabled HiPE, you can compile a module into
-native code like this from the Erlang shell:
-
- c(Module, native).
-
-or
-
- c(Module, [native|OtherOptions]).
-
-Using the erlc program, write like this:
-
- erlc +native Module.erl
-
-The native code will be placed into the beam file and automatically
-loaded when the beam file is loaded.
-
-To add hipe options, write like this from the Erlang shell:
-
- c(Module, [native,{hipe,HipeOptions}|MoreOptions]).
-
-Use
-
- hipe:help_options().
-
-to print out the available options.
-
-
-Mac OS X (Darwin)
------------------
-
-We test Mac OS X 10.4.11 (Tiger) and Mac OS X 10.5.x (Leopard)
-in our daily builds (but only on Intel processors).
-
-Make sure that the command "hostname" returns a valid fully qualified
-host name (this is configured in "/etc/hostconfig").
-
-If you develop linked-in drivers (shared library) you need to link
-using "gcc" and the flags "-bundle -flat_namespace -undefined
-suppress". You also include "-fno-common" in CFLAGS when
-compiling. Use ".so" as the library suffix.
-
-Universal 32bit binaries can be built on an Intel Mac using the
---enable-darwin-universal configure option. There still may occur
-problems with certain applications using this option, but the base
-system should run smoothly.
-
-When building universal binaries on a PowerPC Mac (at least on Tiger),
-you must point out a suitable SDK that contains universal binaries.
-For instance, to build universal binaries for Tiger (10.4):
-
-CFLAGS="-isysroot /Developer/SDKs/MacOSX10.4u.sdk" LDFLAGS="-isysroot /Developer/SDKs/MacOSX10.4u.sdk" ./configure --enable-darwin-universal
-
-Also, if you run Leopard, but want to build for Tiger, you must do
-
-export MACOSX_DEPLOYMENT_TARGET=10.4
-
-before running the above configure command.
-
-Experimental support for 64bit x86 darwin binaries can be enabled
-using the --enable-darwin-64bit configure flag. The 64bit binaries are
-best built and run on Leopard, but most of the system also works on
-Tiger (Tiger's 64bit libraries are, however, limited; therefore e.g. odbc,
-crypto, ssl etc. are not supported in Tiger). 64bit PPC binaries are not
-supported and we have no plans to add such support (no machines to
-test on).
-
-Universal binaries and 64bit binaries are mutually exclusive options.
-
-
-Make and the variable "ERL_TOP"
--------------------------------
-
-All the makefiles in the entire directory tree use the environment
-variable ERL_TOP to find the absolute path of the installation. The
-configure script will figure this out and set it in the top level
-Makefile (which, when building, it will pass on). However, when
-developing it is sometimes convenient to be able to run make in a
-subdirectory. To do this you must set the ERL_TOP variable
-before you run make.
-
-For example, assume your GNU make program is called "make" and you
-want to rebuild the application STDLIB, then you could do:
-
- cd lib/stdlib; env ERL_TOP=<Dir> make
-
-where <Dir> would be what you find ERL_TOP is set to in the top level
-Makefile.
-
-
-Authors
--------
-Authors are mostly listed in the application's AUTHORS files,
-that is $ERL_TOP/lib/*/AUTHORS and $ERL_TOP/erts/AUTHORS,
-not in the individual source files.
-
-
-More Information
-----------------
-
-More information can be found at http://www.erlang.org.
diff --git a/README.md b/README.md
new file mode 100644
index 0000000000..c38f097b0f
--- /dev/null
+++ b/README.md
@@ -0,0 +1,76 @@
+Erlang/OTP
+==========
+
+**Erlang** is a programming language used to build massively scalable soft
+real-time systems with requirements on high availability. Some of its
+uses are in telecom, banking, e-commerce, computer telephony and
+instant messaging. Erlang's runtime system has built-in support for
+concurrency, distribution and fault tolerance.
+
+**OTP** is set of Erlang libraries and design principles providing
+middle-ware to develop these systems. It includes its own distributed
+database, applications to interface towards other languages, debugging
+and release handling tools.
+
+More information can be found at [erlang.org] [1].
+
+Building and Installing
+-----------------------
+
+Information on building and installing Erlang/OTP can be found
+in the `INSTALL.md` document.
+
+Contributing to Erlang/OTP
+--------------------------
+
+Here are the [instructions for submitting patches] [2].
+
+In short:
+
+* We prefer to receive proposed updates via email on the
+ [`erlang-patches`] [3] mailing list rather than through a pull request.
+ Pull requests are not practical because we have a strict policy never to
+ merge any untested changes to the development branch (the only exception
+ being **obviously** correct changes, such as corrections of typos).
+
+* We merge all proposed updates to the `pu` (*proposed updates*) branch,
+ typically within one working day.
+
+* At least once a day, the contents of the `pu` branch will be built on
+ several platforms (Linux, Solaris, Mac OS X, Windows, and so on) and
+ automatic test suites will be run. We will email you if any problems are
+ found.
+
+* If a proposed change builds and passes the tests, it will be reviewed
+ by one or more members of the Erlang/OTP team at Ericsson. The reviewer
+ may suggest improvements that are needed before the change can be accepted
+ and merged.
+
+* Once or twice a week, a status email called "What's cooking in Erlang/OTP"
+ will be sent to the [`erlang-patches`] [3] mailing list.
+
+Copyright and License
+---------------------
+
+> %CopyrightBegin%
+>
+> Copyright Ericsson AB 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%
+
+
+
+ [1]: http://www.erlang.org
+ [2]: http://wiki.github.com/erlang/otp/submitting-patches
+ [3]: http://www.erlang.org/faq.html
diff --git a/README.win32 b/README.win32
deleted file mode 100644
index a6d2609aae..0000000000
--- a/README.win32
+++ /dev/null
@@ -1,749 +0,0 @@
-How to build Erlang/OTP on Windows.
------------------------------------
-Table of contents
-
-1. Introduction
-2. Answers to some "frequently asked questions"
-3. Tools you need and their environment
-4. The shell environment
-5. Building and installing
-6. Development
-7. Final words
-
-%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%
-
-
-
-Introduction
-------------
-
-This file describes how to build the Erlang emulator and the OTP
-libraries on Windows. The instructions apply to versions of Windows
-supporting the Cygwin emulated gnuish environment for Windows. We've
-built on the following platforms: Windows 2000 Professional, Windows
-2003 server, Windows XP Home/Professional, and Windows Vista. Any
-Windows95'ish platform will surely get you into trouble, what I'm not
-sure of, but it certainly will...
-
-The procedure described uses Cygwin as a build environment, you run
-the bash shell in Cygwin and uses gnu make/configure/autoconf etc to
-do the build. The emulator C-source code is, however, mostly compiled
-with Microsoft Visual C++(tm), producing a native Windows binary. This
-is the same procedure as we use to build the pre-built binaries. The
-fact that we use VC++ and not gcc is explained further in the FAQ
-section.
-
-I describe the build procedure to make it possible for open source
-customers to build the emulator, given that they have the needed
-tools. The binary Windows releases is still a preferred alternative if
-one does not have Microsoft's development tools and/or don't want to
-install Cygwin.
-
-To use Cygwin, one needs basic experience from a Unix environment, if
-one does not know how to set environment variables, run programs etc
-in a Unix environment, one will be quite lost in the Cygwin
-ditto. I can unfortunately not teach all the world how to use
-Cygwin and bash, neither how to install Cygwin nor perform basic tasks
-on a computer. Please refer to other documentation on the net for
-help, or use the binary release instead if you have problems using the
-tools.
-
-However, if you feel comfortable with the environment and build
-system, and have all the necessary tools, you have a great opportunity
-to make the Erlang/OTP distribution for Windows better. Please submit
-any suggestions and patches to the appropriate mailing lists (see
-http://www.erlang.org) to let them find their way into the next
-version of Erlang. If making changes to the build system (like
-makefiles etc) please bear in mind that the same makefiles are used on
-Unix/VxWorks/OSEDelta, so that your changes don't break other
-platforms. That of course goes for C-code too, system specific code
-resides in the $ERL_TOP/erts/emulator/sys/win32 and $ERL_TOP/erts/etc/win32
-directories mostly. The $ERL_TOP/erts/emulator/beam directory is for
-common code.
-
-Before the R9C release of Erlang/OTP, the Windows release was built
-partly on a Unix (Solaris) box and partly on a Windows box, using Perl
-hacks to communicate and sync between the two machines. R9C was the
-first release ever built solely on Windows, where no Unix machine is
-needed at all. Now we've used this build procedure for a couple of
-releases, and it has worked fine for us. Still, there might be all
-sorts of troubles on different machines and with different
-setups. I'll try to give hints wherever I've encountered difficulties,
-but please share your experiences by using the mailing list
[email protected]. I cannot of course help everyone with all
-their problems, please try to solve the problems and submit
-solutions/workarounds. Remember, it's all about sharing, not about
-demanding...
-
-Lets go then, I'll start with a little FAQ, based on in house questions
-and misunderstandings.
-
-
-Answers to "frequently asked questions"
----------------------------------------
-
-Q: So, now I can build Erlang using GCC on Windows?
-
-A: No, unfortunately not. You'll need Microsoft's Visual C++ still, a
-Bourne-shell script (cc.sh) wraps the Visual C++ compiler and runs it
-from within the Cygwin environment. All other tools needed to build
-Erlang are free-ware/open source, but not the C compiler.
-
-Q: Why haven't you got rid of VC++ then, you ******
-
-A: Well, partly because it's a good compiler - really! Actually it's
-been possible in late R11-releases to build using mingw instead of
-visual C++ (you might see the remnants of that in some scripts and
-directories). Unfortunately the development of the SMP version for
-Windows broke the mingw build and we chose to focus on the VC++ build
-as the performance has been much better in the VC++ versions. The
-mingw build will be back, but as long as VC++ gives better
-performance, the commercial build will be a VC++ one.
-
-Q: OK, VC++ you need, but now you've started to demand a very recent
-(and expensive) version of Visual studio, not the old and stable VC++
-6.0 that was used in earlier versions. Why?
-
-A: The SMP version of Erlang needs features in the Visual Studio
-2005. Can't live without them. Besides the new compiler gives the
-Erlang emulator a ~40% performance boost(!)
-
-Q: Can/will I build a Cygwin binary with the procedure you describe?
-
-A: No, the result will be a pure Windows binary, and as far as I know,
-it's not possible to make a Cygwin binary yet. That is of course
-something desirable, but there are still some problems with the
-dynamic linking (dynamic Erlang driver loading) as well as the TCP/IP
-emulation in Cygwin, which, I'm sure of, will improve, but still has
-some problems. Fixing those problems might be easy or might be hard.
-I suggest you try yourself and share your experience. No one would be
-happier if a simple ./configure && make would produce a fully fledged
-Cygwin binary. Ericsson does however not pay me to do a Cygwin port, so
-such a port would have to happen in spare time, which is a limited resource...
-
-Q: Hah, I saw you, you used GCC even though you said you didn't!
-
-A: OK, I admit, one of the files is compiled using Cygwin's GCC and
-the resulting object code is then converted to MS VC++ compatible coff
-using a small C hack. It's because that particular file, beam_emu.c
-benefits immensely from being able to use the GCC labels-as-values
-extension, which boosts emulator performance by up to 50%. That does
-unfortunately not (yet) mean that all of OTP could be compiled using
-GCC, that particular source code does not do anything system specific
-and actually is adopted to the fact that GCC is used to compile it on
-Windows.
-
-Q: So now there's a MS VC++ project file somewhere and I can build OTP
-using the nifty VC++ GUI!
-
-A: No, never. The hassle of keeping the project files up to date and
-do all the steps that constitute an OTP build from within the VC++ GUI
-is simply not worth it, maybe even impossible. A VC++ project
-file for Erlang/OTP will never happen, at least I will never make
-one. Clicking around in super-multi-tab'd dialogs to add a file or
-compiler option when it's so much easier in a makefile is simply not
-my style.
-
-Q: So how does it all work then?
-
-A: Cygwin is the environment, which closely resembles the environments
-found on any Unix machine. It's almost like you had a virtual Unix
-machine inside Windows. Configure, given certain parameters, then
-creates makefiles that are used by the Cygwin gnu-make to built the
-system. Most of the actual compilers etc are not, however, Cygwin
-tools, so I've written a couple of wrappers (Bourne-shell scripts),
-which reside in $ERL_TOP/etc/win32/cygwin_tools and they all do
-conversion of parameters and switches common in the Unix environment
-to fit the native Windows tools. Most notable is of course the paths,
-which in Cygwin are Unix-like paths with "forward slashes" (/) and no
-drive letters, the Cygwin specific command 'cygpath' is used for most
-of the path conversions. Luckily most compilers accept forward slashes
-instead of backslashes as path separators, one still have to get the
-drive letters etc right, though. The wrapper scripts are not general
-in the sense that, for example, cc.sh would understand and translates
-every possible gcc option and passes correct options to cl.exe. The
-principle is that the scripts are powerful enough to allow building of
-Erlang/OTP, no more, no less. They might need extensions to cope with
-changes during the development of Erlang, that's one of the reasons I
-made them into shell-scripts and not Perl-scripts, I believe they are
-easier to understand and change that way. I might be wrong though,
-cause another reason I didn't write them in Perl is because I've never
-liked Perl and my Perl code is no pleasant reading...
-
-In $ERL_TOP, there is a script called otp_build, that script handles
-the hassle of giving all the right parameters to configure/make and
-also helps you set up the correct environment variables to work with
-the Erlang source under Cygwin.
-
-Q: You use and need Cygwin, but then you haven't taken the time to
-port Erlang to the Cygwin environment but instead focus on your
-commercial release, is that really ethical?
-
-A: No, not really, but see this as a step in the right direction. I'm
-aiming at GCC compiled emulators and a Cygwin version, but I really
-need to do other things as well... In time, but don't hold your
-breath...
-
-Q: Can I build something that looks exactly as the commercial release.
-
-A: Yes, we use the exactly same build procedure.
-
-Q: Which version of Cygwin and other tools do you use then?
-
-A: For Cygwin we try to use the latest releases available when
-building. What versions you use shouldn't really matter, I try to
-include workarounds for the bugs I've found in different Cygwin
-releases, please help me to add workarounds for new Cygwin-related
-bugs as soon as you encounter them. Also please do submit bug reports
-to the appropriate Cygwin developers. The Cygwin GCC we used for R13B
-was version 3.4.4. We used VC++ 8.0 (i.e. Visual studio 2005 SP1),
-Sun's JDK 1.5.0_17, NSIS 2.37, and Win32 OpenSSL 0.9.8e. Please read
-the next section for details on what you need.
-
-Q: Can you help me setup X in Cygwin?
-
-A: No, unfortunately I haven't got time to help with Cygwin related
-user problems, please read Cygwin related web sites, newsgroups and
-mailing lists.
-
-Q: Why is the instruction so long? Is it really that complicated?
-
-A: Partly it's long because I babble too much, partly because I've
-described as much as I could about the installation of the needed
-tools. Once the tools are installed, building is quite easy. I also
-have tried to make this instruction understandable for people with
-limited Unix experience. Cygwin is a whole new environment to some
-Windows users, why careful explanation of environment variables etc
-seemed to be in place. The short story, for the experienced and
-impatient is:
-
-* Get and install complete Cygwin (latest)
-* (Buy and) Install Microsoft Visual studio 2005 and SP1 (or higher)
-* Get and install Sun's JDK 1.4.2
-* Get and install NSIS 2.01 or higher (up to 2.30 tried and working)
-* Get and install OpenSSL 0.9.7c or higher
-* Get and unpack wxWidgets-2.8.9 or higher to /opt/local/pgm inside cygwin
- - open /cygwin/opt/local/pgm/wxWidgets-2.8.9/build/msw/wx.dsw
- - enable wxUSE_GLCANVAS, wxUSE_POSTSCRIPT and wxUSE_GRAPHICS_CONTEXT
- in include/wx/msw/setup.h
- - build all unicode release (and unicode debug) packages
- - open /cygwin/opt/local/pgm/wxWidgets-2.8.9/contrib/build/stc/stc.dsw
- - build the unicode release (and unicode debug) packages
-* Get and unpack the erlang source distribution with Cygwin's tar.
-* set ERL_TOP to where you unpacked the source distribution
-* $ cd $ERL_TOP
-* Get (from http://www.erlang.org/download/tcltk85_win32_bin.tar.gz)
-and unpack the prebuilt TCL/TK binaries for windows with cygwin tar,
-standing in $ERL_TOP
-* Modify PATH and other environment variables so that all these tools
-are runnable from a bash shell. Still standing in $ERL_TOP, issue the following
-commands:
-$ eval `./otp_build env_win32`
-$ ./otp_build autoconf
-$ ./otp_build configure
-$ ./otp_build boot -a
-$ ./otp_build release -a
-$ ./otp_build installer_win32
-$ release/win32/otp_win32_<OTP version> /S
-
-Voila! "Start->Programs->Erlang OTP <OTP version>->Erlang" starts the Erlang
-Windows shell.
-
-
-Tools you need and their environment
-------------------------------------
-
-You need some tools to be able to build Erlang/OTP on Windows. Most
-notably you'll need Cygwin and Microsoft VC++, but you also might want
-a Java compiler, the NSIS install system and OpenSSL. Only VC++ costs
-money, but then again it costs a lot of money, I know...
-Well' here's the list:
-
-* Cygwin, the very latest is usually best. Get all the development
-tools and of course all the basic ditto. In fact getting the complete
-package might be a good idea, as you'll start to love Cygwin after a
-while if you're accustomed to Unix. Make sure to get jar and also make
-sure *not* to install a Cygwin'ish Java... The Cygwin jar command is
-used but Sun's Java compiler and virtual machine...
-
-URL: http://www.cygwin.com
-
-- get the installer from the web site and use that to install
-Cygwin. Be sure to have fair privileges. If you're on a NT domain you
-should consider running "mkpasswd -d" and "mkgroup -d" after the
-installation to get the user databases correct. See their respective
-manual pages.
-
-When you start you first bash shell, you will get an awful prompt. You
-might also have a PATH environment variable that contains backslashes
-and such. Edit $HOME/.profile and $HOME/.bashrc to set fair prompts
-and set a correct PATH. Also do a "export SHELL" in .profile. For some
-non-obvious reason the environment variable $SHELL is not exported in
-bash. Also note that .profile is run at login time and .bashrc when
-sub shells are created. You'll need to explicitly source .bashrc from
-.profile if you want the commands there to be run at login time (like
-setting up aliases, shell functions and the like). I personally
-usually do like this at the end of .profile:
-------------------
-ENV=$HOME/.bashrc
-export ENV
-. $ENV
-----------------
-
-You might also, if you're a hard core type of person at least, want to
-setup X-windows (XFree86), that might be as easy as running startx
-from the command prompt and it might be much harder. Use Google to
-find help...
-
-If you don't use X-windows, you might want to setup the Windows
-console window by selecting properties in the console system menu
-(upper left corner of the window, the Cygwin icon in the title
-bar). Especially setting a larger screen buffer size (lines) is useful
-as it gets you a scrollbar so you can see whatever error messages
-that might appear...
-
-If you want to use (t)csh instead of bash you're on your own, I
-haven't tried and know of no one that has. I expect
-that you use bash in all shell examples.
-
-* Microsoft Visual Studio 2005 SP1. Please don't skip the service
-pack! The installer might update your environment so that you can run
-the 'cl' command from the bash prompt, then again it might
-not... There is always a BAT file in VC\Bin under the installation
-directory (default C:\Program Files\Microsoft Visual Studio 8) called
-VCVARS32.BAT. Either add the environment settings in that file to the
-global environment settings in Windows or add the corresponding BASH
-environment settings to your .profile/.bashrc. For example, in my case
-I could add the following to .profile
-------------------------------------------------------------
-#Visual C++ Root directory as Cygwin style pathname
-VCROOT=/cygdrive/c/Program\ Files/Microsoft\ Visual\ Studio 8
-
-# Visual C++ Root directory as Windows style pathname
-WIN_VCROOT="C:\\Program Files\\Microsoft Visual Studio 8"
-
-# The PATH variable should be Cygwin'ish
-PATH=$VCROOT/Common7/IDE:$VCROOT/VC/BIN:$VCROOT/Common7/Tools:\
-$VCROOT/Common7/Tools/bin:$VCROOT/VC/PlatformSDK/bin:$VCROOT/SDK/v2.0/bin:\
-$VCROOT/VC/VCPackages:$PATH
-
-# Lib and INCLUDE should be Windows'ish
-# Note that semicolon (;) is used to separate Windows style paths but
-# colon (:) to separate Cygwin ditto!
-
-LIBPATH=$WIN_VCROOT\\VC\\ATLMFC\\LIB
-
-LIB=$WIN_VCROOT\\VC\\ATLMFC\\LIB\;$WIN_VCROOT\\VC\\LIB\;\
-$WIN_VCROOT\\VC\\PlatformSDK\\lib\;$WIN_VCROOT\\SDK\\v2.0\\lib
-
-INCLUDE=$WIN_VCROOT\\VC\\ATLMFC\\INCLUDE\;$WIN_VCROOT\\VC\\INCLUDE\;\
-$WIN_VCROOT\\VC\\PlatformSDK\\include
-
-export PATH LIB INCLUDE
---------------------------------------------------------------
-
-Make a simple hello world and try to compile it with the 'cl' command
-from within bash. If that does not work, your environment needs
-fixing. Also remember to fix up the PATH environment, especially old
-Erlang installations might have inserted quoted paths that Cygwin does
-not understand. Remove or correct such paths. There should be no
-backslashes in your path environment variable in Cygwin bash, but LIB
-and INCLUDE should contain Windows style paths with semicolon,
-drive letters and backslashes.
-
-* 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
-result will be that jinterface is not built.
-
-URL: http://java.sun.com
-
-Add javac *LAST* to your path environment in bash, in my case this means:
---------------------------------------------------------------
-PATH="$PATH:/cygdrive/c/Program Files/Java/jdk1.5.0_17/bin"
---------------------------------------------------------------
-No CLASSPATH or anything is needed. Type "javac" at the bash prompt
-and you should get a list of available Java options. Make sure by
-typing "which java" that you use the Java you installed. Note however that
-Cygwin's jar.exe is used, that's why the JDK bin-directory should be
-added last in the PATH.
-
-* Nullsoft NSIS installer system. You need this to build the self
-installing package. It's a free open source installer that's much
-nicer to use than the commercial Wise and Install shield
-installers. This is the installer we use for commercial releases as
-well from R9C an on.
-URL: http://www.nullsoft.com/free/nsis
-Install the lot, especially the modern user interface components, as
-it's definitely needed. Put "makensis" in your path, in my case:
---------------------------------------------------------------
-PATH=/cygdrive/c/Program\ Files/NSIS:$PATH
---------------------------------------------------------------
-type makensis at the bash prompt and you should get a list of options
-if everything is OK.
-
-* OpenSSL for Windows. This is if you want the SSL and crypto
-applications to compile (and run). Go to http://www.openssl.org, click
-on the "Related" link and then on the "Binaries" link (upper right
-corner of the page last time I looked), you can then reach the
-"Shining Lights Productions" Web site for Windows binaries
-distributions. Get the latest or 0.9.7c if you get trouble with the
-latest. It's a nifty installer. The rest should be handled by
-configure, you needn't put anything in the path or anything.
-
-If you want to build openssl for windows yourself (which might be
-possible, as you wouldn't be reading this if you weren't a
-compile-it-yourself person), you either have to put the resulting
-DLL's in your path or in the windows system directory and either
-specify where you put the includes etc with the configure-parameter
---with-ssl=<cygwin path to the root> or put your installation directly
-under c:\OpenSSL. The directory structure under the installation root
-for OpenSSL is expected to be one with subdirectories named "include",
-"bin" and "lib", possibly with a "VC" subdirectory of "lib" containing
-the actual .lib files. Note that the cygwin distributed OpenSSL cannot be
-used, it results in cygwin depending binaries and it has unix style
-archives (.a, not .lib).
-
-* Building with wxWidgets. Download wxWidgets-2.8.9 or higher patch
-release (2.9.* is a developer release which currently does not work
-with wxErlang).
-Install or unpack it to DRIVE:/PATH/cygwin/opt/local/pgm
-Open from explorer (i.e. by double clicking the file)
-C:\cygwin\opt\local\pgm\wxMSW-2.8.10\build\msw\wx.dsw
-In Microsoft Visual Studio, click File/Open/File, locate and
-open: C:\cygwin\opt\local\pgm\wxMSW-2.8.10\include\wx\msw\setup.h
-enable wxUSE_GLCANVAS, wxUSE_POSTSCRIPT and wxUSE_GRAPHICS_CONTEXT
-Build it by clicking Build/Batch Build and select all unicode release
-(and unicode debug) packages.
-Open C:\cygwin\opt\local\pgm\wxMSW-2.8.10\contrib/build/stc/stc.dsw
-and batch build all unicode packages.
-
-* The Erlang source distribution. The same as for Unix
-platforms. Preferably use tar from within Cygwin to unpack the source
-tar.gz (tar zxf otp_src_R13B03.tar.gz).
-
-set the environment ERL_TOP to point to the root directory of the
-source distribution. Let's say I stood in $HOME/src and unpacked
-otp_src_R13B03.tar.gz, I then add the following to .profile:
---------------------------------------------------------
-ERL_TOP=$HOME/src/otp_src_R13B03
-export $ERL_TOP
---------------------------------------------------------
-
-* The TCL/TK binaries. You could compile Tcl/Tk for windows yourself,
-but you can get a stripped down version from our website which is
-suitable to include in the final binary package. If you want to supply
-tcl/tk yourself, read the instructions about how the tcl/tk tar file
-used in the build is constructed under $ERL_TOP/lib/gs/tcl. The easy
-way is to download
-http://www.erlang.org/download/tcltk85_win32_bin.tar.gz and unpack it
-standing in the $ERL_TOP directory. This will create the file
-win32.tar.gz in $ERL_TOP/lib/gs/tcl/binaries.
-
-One last alternative is to create a file named 'SKIP' in the
-$ERL_TOP/lib/gs/ after configure is run, but that will give you an
-erlang system without gs (which might be okay as you probably will use
-wx anyway).
-
-The shell environment
----------------------
-
-So, if you have followed the instructions above, when you start a bash
-shell, you should have an INCLUDE environment with a Windows style
-path, a LIB environment variable also in Windows style, and finally a
-PATH that let's you reach cl, makensis, javac etc from the
-command prompt (use "which cl" etc to verify from bash).
-
-You should also have an ERL_TOP environment variable that is *Cygwin
-style*, and points to a directory containing, among other files, the
-script "otp_build".
-
-A final massage of the environment is needed, and that is done by
-the script $ERL_TOP/otp_build. Start bash and do the following, note
-the "back-ticks" (`), can be quite hard to get on some keyboards, but
-pressing the back-tick key followed by the space bar might do it...
-
-------------------------
-$ cd $ERL_TOP
-$ eval `./otp_build env_win32`
-------------------------
-If you're unable to produce back-ticks on your keyboard, you can use
-the ksh variant:
-------------------------
-$ cd $ERL_TOP
-$ eval $(./otp_build env_win32)
-------------------------
-
-This should do the final touch to the environment and building should
-be easy after this. You could run "./otp_build env_win32" without
-"eval" just to see what it does, and to see that the environment it
-sets seems OK. The path is cleaned of spaces if possible (using DOS
-style short names instead), the variables OVERRIDE_TARGET, CC, CXX, AR
-and RANLIB are set to their respective wrappers and the directories
-$ERL_TOP/erts/etc/win32/cygwin_tools/vc and
-$ERL_TOP/erts/etc/win32/cygwin_tool are added first in the PATH.
-
-Try now a "which erlc". That should result in the erlc wrapper script
-(which does not have the .sh extension, for reasons best kept
-untold...). It should reside in $ERL_TOP/erts/etc/win32/cygwin_tools.
-You could also try "which cc.sh", which "ar.sh" etc.
-
-Now you're ready to build...
-
-
-Building and installing
------------------------
-Now it's assumed that you have executed "eval `./otp_build env_win32`"
-for this particular shell...
-
-Building is easiest using the otp_build script. That script takes care
-of running configure, bootstrapping etc on Windows in a simple
-way. The otp_build script is the utility we use ourselves to build on
-different platforms and it therefore contains code for all sorts of
-platforms. The principle is, however, that for non-Unix platforms, one
-uses "./otp_build env_<target>" to set up environment and then the
-script knows how to build on the platform "by itself". You've already
-run "./otp_build env_win32" in the step above, so now it's mostly like
-we build on any platform. OK, here are then steps; Assuming you will
-want to build a full installation executable with NSIS, you can omit
-<installation directory> and the release will be copied to
-$ERL_TOP/release/win32: and there is where the packed self installing
-executable will reside too.
-
-$ ./otp_build autoconf # Ignore the warning blob about versions of autoconf
-$ ./otp_build configure <optional configure options>
-$ ./otp_build boot -a
-$ ./otp_build release -a <installation directory>
-$ ./otp_build installer_win32 <installation directory> # optional
-
-Now you will have a file called otp_win32_R12B.exe in the <installation
-directory>, i.e. $ERL_TOP/release/win32.
-
-Lets get into more detail:
-
-$ ./otp_build autoconf - This step rebuilds the configure scripts to
-work correctly in the cygwin environment. In an ideal world, this
-would not be needed, but alas, we have encountered several
-incompatibilities between our distributed configure scripts (generated
-on a Linux platform) and the cygwin environment over the
-years. Running autoconf on cygwin ensures that the configure scripts
-are generated in a cygwin-compatible way and that they will work well
-in the next step.
-
-$ ./otp_build configure - This runs the newly generated configure scripts
-with options making configure behave nicely. The target machine type is
-plainly "win32", so a lot of the configure-scripts recognize this
-awkward target name and behave accordingly. The CC variable also makes
-the compiler be cc.sh, which wraps MSVC++, so all configure tests
-regarding the C compiler gets to run the right compiler. A lot of the
-tests are not needed on Windows, but I thought it best to run the
-whole configure anyway. The only configure option you might want to
-supply is --with-ssl, which might be needed if you have built your own
-openssl distribution. The Shining Lights distribution should be found
-automatically by configure, if that fails, add a --with-ssl=<dir> that
-specifies the root directory of your OpenSSL installation.
-
-$ ./otp_build boot -a - This uses the bootstrap directory (shipped
-with the source, $ERL_TOP/bootstrap) to build a complete OTP
-system. It first builds an emulator and sets up a minimal OTP system
-under $ERL_TOP/bootstrap, then starts to compile the different OTP
-compilers to make the $ERL_TOP/bootstrap system potent enough to be
-able to compile all Erlang code in OTP. Then, all Erlang and C code
-under $ERL_TOP/lib is built using the bootstrap system, giving a
-complete OTP system (although not installed). When this is done, one
-can run Erlang from within the source tree, just type $ERL_TOP/bin/erl
-and you should have a prompt. If you omit the -a flag, you'll get a
-smaller system, that might be useful during development. Now
-exit from Erlang and start making a release of the thing:
-
-$ ./otp_build release -a - Builds a commercial release tree from the
-source tree, default is to put it in $ERL_TOP/release/win32, you can
-give any directory as parameter (Cygwin style), but it doesn't really matter
-if you're going to build a self extracting installer too. You could of
-course build release to the final directory and then run ./Install.exe
-standing in the directory where the release was put, that will create
-a fully functional OTP installation. But let's make the nifty
-installer:
-
-$ ./otp_build installer_win32 - Create the self extracting installer
-executable. The executable otp_win32_<OTP version>.exe will be placed
-in the top directory of the release created in the previous step. If
-no release directory is specified, the release is expected to have
-been built to $ERL_TOP/release/win32, which also will be the place
-where the installer executable will be placed. If you specified some
-other directory for the release (i.e.
-./otp_build release -a /tmp/erl_release), you're expected to give the
-same parameter here, (i.e. ./otp_build installer_win32 /tmp/erl_release).
-You need to have a full NSIS installation and makensis.exe in your
-path for this to work of course. Once you have created the installer,
-you can run it to install Erlang/OTP in the regular way, just run the
-executable and follow the steps in the installation wizard. To get all
-default settings in the installation without any questions asked, you
-run the executable with the parameter "/S" (capital S). like in:
-------------------------------------------------------
-$ cd $ERL_TOP
-$ release/win32/otp_win32_R13B03 /S
-.....
-------------------------------------------------------
-- and after a while Erlang will have been installed in
-C:\Program Files\erl5.7.4, with shortcuts in the menu etc.
-
-*NOTE* Beginning with R9C, the Windows installer does *not* add Erlang
-to the system wide path. If one wants to have Erlang in the path, one
-has to add it by hand.
-
-The necessary setup of an Erlang installation is actually done by the
-program Install.exe, which resides in the release top. That program
-creates ".ini-files" and copies the correct boot scripts. If one has
-the correct directory tree (like after a ./otp_build release -a), only
-the running of Install.exe is necessary to get a fully functional
-OTP. What the self extracting installer adds is (of course) the
-possibility to distribute the binary easily, together with adding
-shortcuts to the Windows start menu. There is also some adding of
-entries in the registry, to associate .erl and .beam files with Erlang
-and get nifty icons, but that's not something you'll really need to
-run Erlang. The registry is also used to store uninstall information,
-but if one has not used the self extracting installer, one cannot
-(need not) do any uninstall, one just scratches the release directory
-and everything is gone. Erlang/OTP does not *need* to put anything
-in the Windows registry at all, and does not if you don't use the self
-extracting installer. In other words the installer is pure cosmetics.
-
-
-Development
------------
-
-Once the system is built, you might want to change it. Having a test
-release in some nice directory might be useful, but you also can run
-Erlang from within the source tree. The target 'local_setup', makes
-the program $ERL_TOP/bin/erl.exe usable and it also uses all the OTP
-libraries in the source tree.
-
-If you hack the emulator, you can then build the emulator executable
-by standing in $ERL_TOP/erts/emulator and do a simple
-
-$ make opt
-
-Note that you need to have run (cd $ERL_TOP && eval `./otp_build env_win32`)
-in the particular shell before building anything on Windows. After
-doing a make opt you can test your result by running $ERL_TOP/bin/erl.
-If you want to copy the result to a release directory (say
-/tmp/erl_release), you do this (still in $ERL_TOP/erts/emulator)
-
-$ make TESTROOT=/tmp/erl_release release
-
-That will copy the emulator executables.
-
-To make a debug build of the emulator, you need to recompile both
-beam.dll (the actual runtime system) and erlexec.dll. Do like this
-
-$ cd $ERL_TOP
-$ rm bin/win32/erlexec.dll
-$ cd erts/emulator
-$ make debug
-$ cd ../etc
-$ make debug
-
-- and sometimes
-
-$ cd $ERL_TOP
-$ make local_setup
-
-So now when you run $ERL_TOP/erl.exe, you should have a debug compiled
-emulator, which you will see if you do a:
-
-1> erlang:system_info(system_version).
-
-- in the erlang shell. If the returned string contains "[debug]", you
-got a debug compiled emulator.
-
-To hack the erlang libraries, you simply do a "make opt" in the
-specific "applications" directory, like:
-
-$ cd $ERL_TOP/lib/stdlib
-$ make opt
-
-- or even in the source directory...
-
-$ cd $ERL_TOP/lib/stdlib/src
-$ make opt
-
-Note that you're expected o have a fresh Erlang in your path when
-doing this, preferably the plain R13B03 you have built in the previous
-steps. You could also add $ERL_TOP/bootstrap/bin to your PATH before
-rebuilding specific libraries, that would give you a good enough
-Erlang system to compile any OTP erlang code. Setting up the path
-correctly is a little bit tricky, you still need to have
-$ERL_TOP/erts/etc/win32/cygwin_tools/vc and
-$ERL_TOP/erts/etc/win32/cygwin_tools *before* the actual emulator
-in the path. A typical setting of the path for using the bootstrap
-compiler would be:
-
-$ export PATH=$ERL_TOP/erts/etc/win32/cygwin_tools/vc:$ERL_TOP/erts/etc/win32/cygwin_tools:$ERL_TOP/bootstrap/bin:$PATH
-
-That should make it possible to rebuild any library without hassle...
-
-If you want to copy a library (an application) newly built, to a
-release area, you do like with the emulator:
-
-$ cd $ERL_TOP/lib/stdlib
-$ make TESTROOT=/tmp/erlang_release release
-
-Remember that:
-
-- Windows specific C-code goes in the
-$ERL_TOP/erts/emulator/sys/win32, $ERL_TOP/erts/emulator/drivers/win32
-or $ERL_TOP/erts/etc/win32.
-
-- Windows specific erlang code should be used conditionally and the
-host OS tested in *runtime*, the exactly same beam files should be
-distributed for every platform! So write code like:
-
-case os:type() of
- {win32,_} ->
- do_windows_specific();
- Other ->
- do_fallback_or_exit()
-end,
-
-That's basically all you need to get going.
-
-Final words
------------
-My hope is that the possibility to build the whole system on Windows
-will open up for free development on this platform too. There are many
-things one might want to do better in the Windows version, like the
-window-style command prompt as well as pure Cygwin porting. Although i
-realize it's a much larger step to start building on Windows (with all
-the software you need) than for instance on Linux, I sincerely hope
-that some of you will make the effort and start submitting Windows
-friendly patches.
-
-The first build system for Erlang using Cygwin on Windows was created
-by Per Bergkvist. I haven't used his build system, but it's rumored to
-be good. The idea to do this came from his work, so credit is well
-deserved.
-
-Of course this would have been completely impossible without the
-excellent Cygwin package. The guys at Cygnus solutions and Redhat
-deserves a huge THANKS! as well as all the other people in the free
-software community who have helped in creating the magnificent
-software that constitutes Cygwin.
-
-Good luck and Happy Hacking,
-Patrik, OTP
diff --git a/TAR.include b/TAR.include
index 6446b5de94..27b10d6243 100644
--- a/TAR.include
+++ b/TAR.include
@@ -1,15 +1,20 @@
AUTHORS
EPLICENCE
Makefile.in
-README
-README.win32
+README.md
+INSTALL.md
+INSTALL-CROSS.md
+INSTALL-WIN32.md
configure.in
+aclocal.m4
otp_build
lib/Makefile
lib/configure
lib/configure.in
+lib/configure.in.src
prebuild.skip
prebuild.delete
+erl-build-tool-vars.sh
bootstrap/lib/*/ebin
bootstrap/lib/*/include
bootstrap/bin/start*.script
diff --git a/aclocal.m4 b/aclocal.m4
new file mode 120000
index 0000000000..32ceb26f5a
--- /dev/null
+++ b/aclocal.m4
@@ -0,0 +1 @@
+erts/aclocal.m4 \ No newline at end of file
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..edcd4ffc99 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 {2010,2,18} {13,24,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..edcd4ffc99 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 {2010,2,18} {13,24,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..6908d2c296 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..2edf5f226e 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..864d76b526 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..497d1873d8 100644
--- a/bootstrap/lib/compiler/ebin/compiler.app
+++ b/bootstrap/lib/compiler/ebin/compiler.app
@@ -1,24 +1,24 @@
% This is an -*- erlang -*- file.
%% %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%
{application, compiler,
[{description, "ERTS CXC 138 10"},
- {vsn, "4.6.3"},
+ {vsn, "4.6.5"},
{modules, [
beam_asm,
beam_block,
diff --git a/bootstrap/lib/compiler/ebin/compiler.appup b/bootstrap/lib/compiler/ebin/compiler.appup
index aa81bde536..99b234c847 100644
--- a/bootstrap/lib/compiler/ebin/compiler.appup
+++ b/bootstrap/lib/compiler/ebin/compiler.appup
@@ -1 +1 @@
-{"4.6.3",[],[]}.
+{"4.6.5",[],[]}.
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..c0b1ebd802 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..a2766d3048 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..2b5efad43f 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..e93877a690 100644
--- a/bootstrap/lib/compiler/egen/core_parse.erl
+++ b/bootstrap/lib/compiler/egen/core_parse.erl
@@ -13,23 +13,23 @@
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%
-%%
-%% 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%
%%
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..1392a018ab 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..e6ad873c82 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..f66b4635a2 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..d06aba7fe9 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..a8983e79c1 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..ad3f46010e 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..ee4a8633d6 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..1f9241a378 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..926f21e99c 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..a4d234911d 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..83a01d75cb 100644
--- a/bootstrap/lib/kernel/ebin/kernel.app
+++ b/bootstrap/lib/kernel/ebin/kernel.app
@@ -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%
%%
%% This is an -*- erlang -*- file.
@@ -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..38870b0f43 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..07a86f04c2 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/kernel/include/file.hrl b/bootstrap/lib/kernel/include/file.hrl
index b8ad6c8464..2273b0c5a6 100644
--- a/bootstrap/lib/kernel/include/file.hrl
+++ b/bootstrap/lib/kernel/include/file.hrl
@@ -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%
%%
diff --git a/bootstrap/lib/kernel/include/inet.hrl b/bootstrap/lib/kernel/include/inet.hrl
index a62c8b0878..94dd269f7e 100644
--- a/bootstrap/lib/kernel/include/inet.hrl
+++ b/bootstrap/lib/kernel/include/inet.hrl
@@ -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%
%%
%% This record is returned by inet:gethostbyaddr/2 and inet:gethostbyname/2.
diff --git a/bootstrap/lib/kernel/include/inet_sctp.hrl b/bootstrap/lib/kernel/include/inet_sctp.hrl
index 34c46fee1e..83f95e05af 100644
--- a/bootstrap/lib/kernel/include/inet_sctp.hrl
+++ b/bootstrap/lib/kernel/include/inet_sctp.hrl
@@ -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%
%%
%% SCTP protocol contribution by Leonid Timochouk and Serge Aleynikov.
diff --git a/bootstrap/lib/orber/include/Makefile b/bootstrap/lib/orber/include/Makefile
index cc02fbf5b3..08745e5727 100644
--- a/bootstrap/lib/orber/include/Makefile
+++ b/bootstrap/lib/orber/include/Makefile
@@ -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%
#
#
diff --git a/bootstrap/lib/orber/include/corba.hrl b/bootstrap/lib/orber/include/corba.hrl
index 99fe498d2e..c5d2d50ea0 100644
--- a/bootstrap/lib/orber/include/corba.hrl
+++ b/bootstrap/lib/orber/include/corba.hrl
@@ -1,20 +1,20 @@
%%--------------------------------------------------------------------
%%
%% %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%
%%
%%
diff --git a/bootstrap/lib/orber/include/ifr_types.hrl b/bootstrap/lib/orber/include/ifr_types.hrl
index 7e67da9781..035142d802 100644
--- a/bootstrap/lib/orber/include/ifr_types.hrl
+++ b/bootstrap/lib/orber/include/ifr_types.hrl
@@ -1,20 +1,20 @@
%%--------------------------------------------------------------------
%%
%% %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%
%%
%%
diff --git a/bootstrap/lib/orber/include/orber_pi.hrl b/bootstrap/lib/orber/include/orber_pi.hrl
index d2fb33197e..2b846bc814 100644
--- a/bootstrap/lib/orber/include/orber_pi.hrl
+++ b/bootstrap/lib/orber/include/orber_pi.hrl
@@ -1,20 +1,20 @@
%%----------------------------------------------------------------------
%%
%% %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%
%%
%%
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..6537f0e44d 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..fe51f7f417 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..0ca05e1bc3 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..66a84e41df 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..79ed469508 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..b27a37b50d 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..f03cd21072 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..e03b753c09 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..af10b8d0e9 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..974377cdd4 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..27dd5d5be0 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..10349ebd1a 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..06c02fc10c 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..a537d0936e 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..57ac5f2046 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..8a6e9cf514 100644
--- a/bootstrap/lib/stdlib/ebin/stdlib.app
+++ b/bootstrap/lib/stdlib/ebin/stdlib.app
@@ -1,25 +1,25 @@
%% This is an -*- erlang -*- file.
%%
%% %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%
%%
{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..0526384a20 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..d3e63c1aec 100644
--- a/bootstrap/lib/stdlib/egen/erl_parse.erl
+++ b/bootstrap/lib/stdlib/egen/erl_parse.erl
@@ -529,23 +529,23 @@ 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%
-%%
-%% 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%
%%
diff --git a/bootstrap/lib/stdlib/include/erl_bits.hrl b/bootstrap/lib/stdlib/include/erl_bits.hrl
index 3ca71af3a0..06bc1a75fc 100644
--- a/bootstrap/lib/stdlib/include/erl_bits.hrl
+++ b/bootstrap/lib/stdlib/include/erl_bits.hrl
@@ -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%
%%
%% This is an -*- erlang -*- file.
diff --git a/bootstrap/lib/stdlib/include/erl_compile.hrl b/bootstrap/lib/stdlib/include/erl_compile.hrl
index 48aadbcc5e..b49b0c3970 100644
--- a/bootstrap/lib/stdlib/include/erl_compile.hrl
+++ b/bootstrap/lib/stdlib/include/erl_compile.hrl
@@ -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%
%%
diff --git a/bootstrap/lib/stdlib/include/ms_transform.hrl b/bootstrap/lib/stdlib/include/ms_transform.hrl
index fed832fa66..81a624b075 100644
--- a/bootstrap/lib/stdlib/include/ms_transform.hrl
+++ b/bootstrap/lib/stdlib/include/ms_transform.hrl
@@ -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%
%%
-compile({parse_transform,ms_transform}).
diff --git a/bootstrap/lib/stdlib/include/qlc.hrl b/bootstrap/lib/stdlib/include/qlc.hrl
index edb1e7ef57..54df6168e4 100644
--- a/bootstrap/lib/stdlib/include/qlc.hrl
+++ b/bootstrap/lib/stdlib/include/qlc.hrl
@@ -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%
%%
-compile({parse_transform,qlc}).
diff --git a/bootstrap/lib/stdlib/include/zip.hrl b/bootstrap/lib/stdlib/include/zip.hrl
index 7336b760cd..47b06a1cc3 100644
--- a/bootstrap/lib/stdlib/include/zip.hrl
+++ b/bootstrap/lib/stdlib/include/zip.hrl
@@ -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%
%%
diff --git a/configure.in b/configure.in
index 7ddffd85ad..21f9a640ff 100644
--- a/configure.in
+++ b/configure.in
@@ -1,8 +1,28 @@
dnl Process this file with autoconf to produce a configure script.
+
+dnl %CopyrightBegin%
+dnl
+dnl Copyright Ericsson AB 1998-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 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_PREREQ(2.8)dnl
AC_INIT()
+LM_PRECIOUS_VARS
+
default_cache_file=./config.cache
if test "x$no_recursion" != "xyes" -a "x$OVERRIDE_CONFIG_CACHE" = "x"; then
@@ -19,6 +39,18 @@ if test "x$no_recursion" != "xyes" -a "x$OVERRIDE_CONFIG_CACHE" = "x"; then
cache_file=/dev/null
fi
+case "X$ERL_TOP" in
+ X)
+ ;;
+ X/*)
+ test -f $ERL_TOP/erts/emulator/beam/beam_emu.c || {
+ AC_MSG_ERROR([Invalid \$ERL_TOP])
+ }
+ srcdir="$ERL_TOP";;
+ *)
+ AC_MSG_ERROR([\$ERL_TOP needs to be absolute]);;
+esac
+
dnl How to set srcdir absolute is taken from the GNU Emacs distribution
#### Make srcdir absolute, if it isn't already. It's important to
#### avoid running the path through pwd unnecessary, since pwd can
@@ -43,7 +75,7 @@ esac
#
# Now srcdir is absolute and also the top of Erlang distribution, ERL_TOP.
#
-ERL_TOP=${srcdir}
+test "X$ERL_TOP" != "X" || ERL_TOP="$srcdir"
AC_SUBST(ERL_TOP)
dnl
@@ -65,11 +97,35 @@ fi
TARGET=$host
AC_SUBST(TARGET)
+if test X$cross_compiling = Xyes; then
+ CROSS_COMPILING=yes
+else
+ CROSS_COMPILING=no
+fi
+AC_SUBST(CROSS_COMPILING)
+
+
+AC_ARG_ENABLE(bootstrap-only,
+[ --enable-bootstrap-only enable bootstrap only configuration],
+[ if test "X$enableval" = "Xyes"; then
+ BOOTSTRAP_ONLY=yes
+ else
+ BOOTSTRAP_ONLY=no
+ fi
+],
+BOOTSTRAP_ONLY=no)
+
+AC_SUBST(BOOTSTRAP_ONLY)
+
+if test $CROSS_COMPILING = yes -a $BOOTSTRAP_ONLY = yes; then
+ AC_MSG_ERROR([Cannot both cross compile and build a bootstrap system])
+fi
dnl Checks for programs.
AC_PROG_CC
-
+AC_PROG_CXX
+AC_CHECK_TOOL(LD, [ld])
#
# We need GNU make, complain if we can't find it
@@ -123,11 +179,17 @@ AC_PROG_LN_S
AC_PROG_RANLIB
#
-# Get erts version from erts/vsn.mk
+# Get erts version and otp release from erts/vsn.mk
#
-[ERTS=erts-`sed -n 's/^VSN[ ]*=[ ]*\([0-9.]\)/\1/p' < erts/vsn.mk`]
+AC_MSG_CHECKING([ERTS version])
+[ERTS=erts-`sed -n "s/^VSN[ ]*=[ ]*\(.*\)/\1/p" < $ERL_TOP/erts/vsn.mk`]
+AC_MSG_RESULT([$ERTS])
AC_SUBST(ERTS)
+AC_MSG_CHECKING([OTP release])
+[OTP=OTP-`sed -n "s/^SYSTEM_VSN[ ]*=[ ]*\(.*\)/\1/p" < $ERL_TOP/erts/vsn.mk`]
+AC_MSG_RESULT([$OTP])
+AC_SUBST(OTP)
AC_ARG_ENABLE(threads,
[ --enable-threads enable async thread support
@@ -147,6 +209,11 @@ AC_ARG_ENABLE(kernel-poll,
AC_ARG_ENABLE(hipe,
[ --enable-hipe enable hipe support
--disable-hipe disable hipe support])
+
+AC_ARG_WITH(javac,
+[ --with-javac=JAVAC specify Java compiler to use
+ --with-javac use a Java compiler if found (default)
+ --without-javac don't use any Java compiler])
AC_ARG_ENABLE(megaco_flex_scanner_lineno,
[ --enable-megaco-flex-scanner-lineno enable megaco flex scanner lineno
@@ -169,16 +236,20 @@ AC_ARG_ENABLE(shared-zlib,
[ --enable-shared-zlib enable using shared zlib library
--disable-shared-zlib disable shared zlib, compile own zlib source (default)])
-#
-# Set Erlang man page directory
-#
-AC_ARG_ENABLE(erlang-mandir,
-[ --disable-erlang-mandir do not install Erlang man pages in a private directory],
-[ case "$enableval" in
- no) erl_mandir=$mandir ;;
- *) erl_mandir='$(ERLANG_ILIBDIR)/man' ;;
- esac ], erl_mandir='$(ERLANG_ILIBDIR)/man')
-AC_SUBST(erl_mandir)
+dnl This functionality has been lost along the way... :(
+dnl It could perhaps be nice to reintroduce some day; therefore,
+dnl it is not removed just commented out.
+dnl
+dnl #
+dnl # Set Erlang man page directory
+dnl #
+dnl AC_ARG_ENABLE(erlang-mandir,
+dnl [ --disable-erlang-mandir do not install Erlang man pages in a private directory],
+dnl [ case "$enableval" in
+dnl no) erl_mandir=$mandir ;;
+dnl *) erl_mandir='$(erlang_libdir)/man' ;;
+dnl esac ], erl_mandir='$(erlang_libdir)/man')
+dnl AC_SUBST(erl_mandir)
AC_ARG_ENABLE(darwin-universal,
[ --enable-darwin-universal build universal binaries on darwin i386],
@@ -205,6 +276,19 @@ AC_ARG_ENABLE(m64-build,
esac
],enable_m64_build=no)
+AC_ARG_ENABLE(m32-build,
+[ --enable-m32-build build 32bit binaries using the -m32 flag to (g)cc],
+[ case "$enableval" in
+ no) enable_m32_build=no ;;
+ *)
+ if test X${enable_darwin_64bit} = Xyes -o X${enable_m64_build} = Xyes;
+ then
+ AC_MSG_ERROR([(--enable-darwin-64bit or --enable-m64-build) and --enable-m32-build are mutually exclusive]) ;
+ fi ;
+ enable_m32_build=yes ;;
+ esac
+],enable_m32_build=no)
+
dnl OK, we might have darwin switches off different kinds, lets
dnl check it all before continuing.
TMPSYS=`uname -s`-`uname -m`
@@ -248,6 +332,13 @@ if test X${enable_m64_build} = Xyes; then
LDFLAGS="-m64 $LDFLAGS"
export LDFLAGS
fi
+if test X${enable_m32_build} = Xyes; then
+ enable_hipe=no
+ CFLAGS="-m32 $CFLAGS"
+ export CFLAGS
+ LDFLAGS="-m32 $LDFLAGS"
+ export LDFLAGS
+fi
export ERL_TOP
AC_CONFIG_SUBDIRS(lib erts)
diff --git a/erl-build-tool-vars.sh b/erl-build-tool-vars.sh
new file mode 100644
index 0000000000..f66dc2d286
--- /dev/null
+++ b/erl-build-tool-vars.sh
@@ -0,0 +1,28 @@
+#
+# %CopyrightBegin%
+#
+# Copyright Ericsson AB 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%
+#
+
+#
+# erl_build_tool_vars - Build tool configuration variables currently
+# reqognized by `configure' scripts in OTP.
+#
+# NOTE:
+# When updating, also update $ERL_TOP/xcomp/{README,erl-xcomp.conf.template},
+# and precious variables in $ERL_TOP/erts/aclocal.m4.
+#
+erl_build_tool_vars="CC CFLAGS STATIC_CFLAGS CFLAG_RUNTIME_LIBRARY_PATH CPP CPPFLAGS CXX CXXFLAGS LD LDFLAGS LIBS DED_LD DED_LDFLAGS DED_LD_FLAG_RUNTIME_LIBRARY_PATH LFS_CFLAGS LFS_LDFLAGS LFS_LIBS RANLIB AR GETCONF"
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..3d935b7295 100644
--- a/erts/aclocal.m4
+++ b/erts/aclocal.m4
@@ -1,20 +1,21 @@
-
+dnl
dnl %CopyrightBegin%
-dnl
-dnl Copyright Ericsson AB 1998-2009. All Rights Reserved.
-dnl
+dnl
+dnl Copyright Ericsson AB 1998-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
dnl
dnl aclocal.m4
@@ -24,6 +25,91 @@ dnl could/should be part of autoconf are prefixed LM_, macros specific
dnl to the Erlang system are prefixed ERL_.
dnl
+AC_DEFUN(LM_PRECIOUS_VARS,
+[
+
+dnl ERL_TOP
+AC_ARG_VAR(ERL_TOP, [Erlang/OTP top source directory])
+
+dnl Tools
+AC_ARG_VAR(CC, [C compiler])
+AC_ARG_VAR(CFLAGS, [C compiler flags])
+AC_ARG_VAR(STATIC_CFLAGS, [C compiler static flags])
+AC_ARG_VAR(CFLAG_RUNTIME_LIBRARY_PATH, [runtime library path linker flag passed via C compiler])
+AC_ARG_VAR(CPP, [C/C++ preprocessor])
+AC_ARG_VAR(CPPFLAGS, [C/C++ preprocessor flags])
+AC_ARG_VAR(CXX, [C++ compiler])
+AC_ARG_VAR(CXXFLAGS, [C++ compiler flags])
+AC_ARG_VAR(LD, [linker (is often overridden by configure)])
+AC_ARG_VAR(LDFLAGS, [linker flags (can be risky to set since LD may be overriden by configure)])
+AC_ARG_VAR(LIBS, [libraries])
+AC_ARG_VAR(DED_LD, [linker for Dynamic Erlang Drivers (set all DED_LD* variables or none)])
+AC_ARG_VAR(DED_LDFLAGS, [linker flags for Dynamic Erlang Drivers (set all DED_LD* variables or none)])
+AC_ARG_VAR(DED_LD_FLAG_RUNTIME_LIBRARY_PATH, [runtime library path linker flag for Dynamic Erlang Drivers (set all DED_LD* variables or none)])
+AC_ARG_VAR(LFS_CFLAGS, [large file support C compiler flags (set all LFS_* variables or none)])
+AC_ARG_VAR(LFS_LDFLAGS, [large file support linker flags (set all LFS_* variables or none)])
+AC_ARG_VAR(LFS_LIBS, [large file support libraries (set all LFS_* variables or none)])
+AC_ARG_VAR(RANLIB, [ranlib])
+AC_ARG_VAR(AR, [ar])
+AC_ARG_VAR(GETCONF, [getconf])
+
+dnl Cross system root
+AC_ARG_VAR(erl_xcomp_sysroot, [Absolute cross system root path (only used when cross compiling)])
+AC_ARG_VAR(erl_xcomp_isysroot, [Absolute cross system root include path (only used when cross compiling)])
+
+dnl Cross compilation variables
+AC_ARG_VAR(erl_xcomp_bigendian, [big endian system: yes|no (only used when cross compiling)])
+AC_ARG_VAR(erl_xcomp_linux_clock_gettime_correction, [clock_gettime() can be used for time correction: yes|no (only used when cross compiling)])
+AC_ARG_VAR(erl_xcomp_linux_nptl, [have Native POSIX Thread Library: yes|no (only used when cross compiling)])
+AC_ARG_VAR(erl_xcomp_linux_usable_sigusrx, [SIGUSR1 and SIGUSR2 can be used: yes|no (only used when cross compiling)])
+AC_ARG_VAR(erl_xcomp_linux_usable_sigaltstack, [have working sigaltstack(): yes|no (only used when cross compiling)])
+AC_ARG_VAR(erl_xcomp_poll, [have working poll(): yes|no (only used when cross compiling)])
+AC_ARG_VAR(erl_xcomp_kqueue, [have working kqueue(): yes|no (only used when cross compiling)])
+AC_ARG_VAR(erl_xcomp_putenv_copy, [putenv() stores key-value copy: yes|no (only used when cross compiling)])
+AC_ARG_VAR(erl_xcomp_reliable_fpe, [have reliable floating point exceptions: yes|no (only used when cross compiling)])
+AC_ARG_VAR(erl_xcomp_getaddrinfo, [have working getaddrinfo() for both IPv4 and IPv6: yes|no (only used when cross compiling)])
+AC_ARG_VAR(erl_xcomp_gethrvtime_procfs_ioctl, [have working gethrvtime() which can be used with procfs ioctl(): yes|no (only used when cross compiling)])
+AC_ARG_VAR(erl_xcomp_clock_gettime_cpu_time, [clock_gettime() can be used for retrieving process CPU time: yes|no (only used when cross compiling)])
+AC_ARG_VAR(erl_xcomp_after_morecore_hook, [__after_morecore_hook can track malloc()s core memory usage: yes|no (only used when cross compiling)])
+AC_ARG_VAR(erl_xcomp_dlsym_brk_wrappers, [dlsym(RTLD_NEXT, _) brk wrappers can track malloc()s core memory usage: yes|no (only used when cross compiling)])
+
+])
+
+AC_DEFUN(ERL_XCOMP_SYSROOT_INIT,
+[
+erl_xcomp_without_sysroot=no
+if test "$cross_compiling" = "yes"; then
+ test "$erl_xcomp_sysroot" != "" || erl_xcomp_without_sysroot=yes
+ test "$erl_xcomp_isysroot" != "" || erl_xcomp_isysroot="$erl_xcomp_sysroot"
+else
+ erl_xcomp_sysroot=
+ erl_xcomp_isysroot=
+fi
+])
+
+AC_DEFUN(LM_CHECK_GETCONF,
+[
+if test "$cross_compiling" != "yes"; then
+ AC_CHECK_PROG([GETCONF], [getconf], [getconf], [false])
+else
+ dnl First check if we got a `<HOST>-getconf' in $PATH
+ host_getconf="$host_alias-getconf"
+ AC_CHECK_PROG([GETCONF], [$host_getconf], [$host_getconf], [false])
+ if test "$GETCONF" = "false" && test "$erl_xcomp_sysroot" != ""; then
+ dnl We should perhaps give up if we have'nt found it by now, but at
+ dnl least in one Tilera MDE `getconf' under sysroot is a bourne
+ dnl shell script which we can use. We try to find `<HOST>-getconf'
+ dnl or `getconf' under sysconf, but only under sysconf since
+ dnl `getconf' in $PATH is almost guaranteed to be for the build
+ dnl machine.
+ GETCONF=
+ prfx="$erl_xcomp_sysroot"
+ AC_PATH_TOOL([GETCONF], [getconf], [false],
+ ["$prfx/usr/bin:$prfx/bin:$prfx/usr/local/bin"])
+ fi
+fi
+])
+
dnl ----------------------------------------------------------------------
dnl
dnl LM_FIND_EMU_CC
@@ -112,11 +198,15 @@ dnl ----------------------------------------------------------------------
dnl
dnl LM_PROG_INSTALL_DIR
dnl
+dnl This macro may be used by any OTP application.
+dnl
dnl Figure out how to create directories with parents.
dnl (In my opinion INSTALL_DIR is a bad name, MKSUBDIRS or something is better)
dnl
dnl We prefer 'install -d', but use 'mkdir -p' if it exists.
dnl If none of these methods works, we give up.
+dnl
+
AC_DEFUN(LM_PROG_INSTALL_DIR,
[AC_CACHE_CHECK(how to create a directory including parents,
@@ -411,163 +501,102 @@ fi
dnl ----------------------------------------------------------------------
dnl
-dnl ERL_FIND_ETHR_LIB
+dnl LM_CHECK_THR_LIB
dnl
-dnl Find a thread library to use. Sets ETHR_LIBS to libraries to link
-dnl with, ETHR_X_LIBS to extra libraries to link with (same as ETHR_LIBS
-dnl except that the ethread lib itself is not included), ETHR_DEFS to
-dnl defines to compile with, ETHR_THR_LIB_BASE to the name of the
-dnl thread library which the ethread library is based on, and ETHR_LIB_NAME
-dnl to the name of the library where the ethread implementation is located.
-dnl ERL_FIND_ETHR_LIB currently searches for 'pthreads', and
-dnl 'win32_threads'. If no thread library was found ETHR_LIBS, ETHR_X_LIBS,
-dnl ETHR_DEFS, ETHR_THR_LIB_BASE, and ETHR_LIB_NAME are all set to the
-dnl empty string.
+dnl This macro may be used by any OTP application.
+dnl
+dnl LM_CHECK_THR_LIB sets THR_LIBS, THR_DEFS, and THR_LIB_NAME. It also
+dnl checks for some pthread headers which will appear in DEFS or config.h.
dnl
-AC_DEFUN(ERL_FIND_ETHR_LIB,
+AC_DEFUN(LM_CHECK_THR_LIB,
[
-ethr_modified_default_stack_size=
-
-dnl Name of lib where ethread implementation is located
-ethr_lib_name=ethread
-
-ETHR_THR_LIB_BASE=
-ETHR_THR_LIB_BASE_NAME=
-ETHR_X_LIBS=
-ETHR_LIBS=
-ETHR_LIB_NAME=
-ETHR_DEFS=
-
-dnl if test "x$host_os" = "x"; then
-dnl AC_CANONICAL_HOST
-dnl fi
-
dnl win32?
AC_MSG_CHECKING([for native win32 threads])
if test "X$host_os" = "Xwin32"; then
AC_MSG_RESULT(yes)
- # * _WIN32_WINNT >= 0x0400 is needed for
- # TryEnterCriticalSection
- # * _WIN32_WINNT >= 0x0403 is needed for
- # InitializeCriticalSectionAndSpinCount
- # The ethread lib will refuse to build if _WIN32_WINNT < 0x0403.
- #
- # -D_WIN32_WINNT should have been defined in $CPPFLAGS; fetch it
- # and save it in ETHR_DEFS.
- found_win32_winnt=no
- for cppflag in $CPPFLAGS; do
- case $cppflag in
- -DWINVER*)
- ETHR_DEFS="$ETHR_DEFS $cppflag"
- ;;
- -D_WIN32_WINNT*)
- ETHR_DEFS="$ETHR_DEFS $cppflag"
- found_win32_winnt=yes
- ;;
- *)
- ;;
- esac
- done
- if test $found_win32_winnt = no; then
- AC_MSG_ERROR([-D_WIN32_WINNT missing in CPPFLAGS])
- fi
- ETHR_X_LIBS=
- ETHR_THR_LIB_BASE=win32_threads
- AC_DEFINE(ETHR_WIN32_THREADS, 1, [Define if you have win32 threads])
+ THR_DEFS="-DWIN32_THREADS"
+ THR_LIBS=
+ THR_LIB_NAME=win32_threads
else
AC_MSG_RESULT(no)
+ THR_DEFS=
+ THR_LIBS=
+ THR_LIB_NAME=
dnl Try to find POSIX threads
dnl The usual pthread lib...
- AC_CHECK_LIB(pthread, pthread_create, ETHR_X_LIBS="-lpthread")
+ AC_CHECK_LIB(pthread, pthread_create, THR_LIBS="-lpthread")
dnl FreeBSD has pthreads in special c library, c_r...
- if test "x$ETHR_X_LIBS" = "x"; then
- AC_CHECK_LIB(c_r, pthread_create, ETHR_X_LIBS="-lc_r")
+ if test "x$THR_LIBS" = "x"; then
+ AC_CHECK_LIB(c_r, pthread_create, THR_LIBS="-lc_r")
fi
dnl On ofs1 the '-pthread' switch should be used
- if test "x$ETHR_X_LIBS" = "x"; then
+ if test "x$THR_LIBS" = "x"; then
AC_MSG_CHECKING([if the '-pthread' switch can be used])
saved_cflags=$CFLAGS
CFLAGS="$CFLAGS -pthread"
AC_TRY_LINK([#include <pthread.h>],
pthread_create((void*)0,(void*)0,(void*)0,(void*)0);,
- [ETHR_DEFS="-pthread"
- ETHR_X_LIBS="-pthread"])
+ [THR_DEFS="-pthread"
+ THR_LIBS="-pthread"])
CFLAGS=$saved_cflags
- if test "x$ETHR_X_LIBS" != "x"; then
+ if test "x$THR_LIBS" != "x"; then
AC_MSG_RESULT(yes)
else
AC_MSG_RESULT(no)
fi
fi
- if test "x$ETHR_X_LIBS" != "x"; then
- ETHR_DEFS="$ETHR_DEFS -D_THREAD_SAFE -D_REENTRANT"
- ETHR_THR_LIB_BASE=pthread
- AC_DEFINE(ETHR_PTHREADS, 1, [Define if you have pthreads])
+ if test "x$THR_LIBS" != "x"; then
+ THR_DEFS="$THR_DEFS -D_THREAD_SAFE -D_REENTRANT -DPOSIX_THREADS"
+ THR_LIB_NAME=pthread
case $host_os in
- openbsd*)
- # The default stack size is insufficient for our needs
- # on OpenBSD. We increase it to 256 kilo words.
- ethr_modified_default_stack_size=256;;
solaris*)
- ETHR_DEFS="$ETHR_DEFS -D_POSIX_PTHREAD_SEMANTICS" ;;
+ THR_DEFS="$THR_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
- ;;
- *)
- usable_sigusrx=yes
- usable_sigaltstack=yes
- ;;
- esac
-
- AC_MSG_CHECKING(if SIGUSR1 and SIGUSR2 can be used)
- AC_MSG_RESULT($usable_sigusrx)
- 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 = no; then
- ETHR_DEFS="$ETHR_DEFS -DETHR_UNUSABLE_SIGALTSTACK"
- fi
+ THR_DEFS="$THR_DEFS -D_POSIX_THREAD_SAFE_FUNCTIONS"
+ LM_CHECK_GETCONF
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
+ libpthr_vsn=`$GETCONF GNU_LIBPTHREAD_VERSION 2>/dev/null`
+ if test $? -eq 0; then
+ case "$libpthr_vsn" in
+ *nptl*|*NPTL*) nptl=yes;;
+ *) nptl=no;;
+ esac
+ elif test "$cross_compiling" = "yes"; then
+ case "$erl_xcomp_linux_nptl" in
+ "") nptl=cross;;
+ yes|no) nptl=$erl_xcomp_linux_nptl;;
+ *) AC_MSG_ERROR([Bad erl_xcomp_linux_nptl value: $erl_xcomp_linux_nptl]);;
+ esac
+ else
+ nptl=no
+ fi
AC_MSG_RESULT($nptl)
- if test $nptl = yes; then
- ETHR_THR_LIB_BASE_NAME=nptl
+ if test $nptl = cross; then
+ nptl=yes
+ AC_MSG_WARN([result yes guessed because of cross compilation])
fi
if test $nptl = yes; then
need_nptl_incldir=no
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"
+ else
+ IROOT="$erl_xcomp_isysroot"
+ test "$IROOT" != "" || IROOT="$erl_xcomp_sysroot"
+ test "$IROOT" != "" || AC_MSG_ERROR([Don't know where to search for includes! Please set erl_xcomp_isysroot])
+ nptl_path="$nptl_path:$IROOT/usr/local/include:$IROOT/usr/include"
+ fi
nptl_ws_path=
save_ifs="$IFS"; IFS=":"
for dir in $nptl_path; do
@@ -581,7 +610,7 @@ dnl On ofs1 the '-pthread' switch should be used
AC_CHECK_HEADER($dir/nptl/pthread.h,
nptl_incldir=$dir/nptl)
if test "x$nptl_incldir" != "x"; then
- ETHR_DEFS="$ETHR_DEFS -isystem $nptl_incldir"
+ THR_DEFS="$THR_DEFS -isystem $nptl_incldir"
break
fi
done
@@ -590,6 +619,158 @@ dnl On ofs1 the '-pthread' switch should be used
fi
fi
fi
+ ;;
+ *) ;;
+ esac
+
+ dnl We sometimes need THR_DEFS in order to find certain headers
+ dnl (at least for pthread.h on osf1).
+ saved_cppflags=$CPPFLAGS
+ CPPFLAGS="$CPPFLAGS $THR_DEFS"
+
+ dnl
+ dnl Check for headers
+ dnl
+
+ AC_CHECK_HEADER(pthread.h,
+ AC_DEFINE(HAVE_PTHREAD_H, 1, \
+[Define if you have the <pthread.h> header file.]))
+
+ dnl Some Linuxes have <pthread/mit/pthread.h> instead of <pthread.h>
+ AC_CHECK_HEADER(pthread/mit/pthread.h, \
+ AC_DEFINE(HAVE_MIT_PTHREAD_H, 1, \
+[Define if the pthread.h header file is in pthread/mit directory.]))
+
+ dnl restore CPPFLAGS
+ CPPFLAGS=$saved_cppflags
+
+ fi
+fi
+
+])
+
+dnl ----------------------------------------------------------------------
+dnl
+dnl ERL_FIND_ETHR_LIB
+dnl
+dnl NOTE! This macro may be changed at any time! Should *only* be used by
+dnl ERTS!
+dnl
+dnl Find a thread library to use. Sets ETHR_LIBS to libraries to link
+dnl with, ETHR_X_LIBS to extra libraries to link with (same as ETHR_LIBS
+dnl except that the ethread lib itself is not included), ETHR_DEFS to
+dnl defines to compile with, ETHR_THR_LIB_BASE to the name of the
+dnl thread library which the ethread library is based on, and ETHR_LIB_NAME
+dnl to the name of the library where the ethread implementation is located.
+dnl ERL_FIND_ETHR_LIB currently searches for 'pthreads', and
+dnl 'win32_threads'. If no thread library was found ETHR_LIBS, ETHR_X_LIBS,
+dnl ETHR_DEFS, ETHR_THR_LIB_BASE, and ETHR_LIB_NAME are all set to the
+dnl empty string.
+dnl
+
+AC_DEFUN(ERL_FIND_ETHR_LIB,
+[
+
+LM_CHECK_THR_LIB
+
+ETHR_THR_LIB_BASE="$THR_LIB_NAME"
+ETHR_DEFS="$THR_DEFS"
+ETHR_X_LIBS="$THR_LIBS"
+ETHR_LIBS=
+ETHR_LIB_NAME=
+
+ethr_modified_default_stack_size=
+
+dnl Name of lib where ethread implementation is located
+ethr_lib_name=ethread
+
+case "$THR_LIB_NAME" in
+
+ win32_threads)
+ # * _WIN32_WINNT >= 0x0400 is needed for
+ # TryEnterCriticalSection
+ # * _WIN32_WINNT >= 0x0403 is needed for
+ # InitializeCriticalSectionAndSpinCount
+ # The ethread lib will refuse to build if _WIN32_WINNT < 0x0403.
+ #
+ # -D_WIN32_WINNT should have been defined in $CPPFLAGS; fetch it
+ # and save it in ETHR_DEFS.
+ found_win32_winnt=no
+ for cppflag in $CPPFLAGS; do
+ case $cppflag in
+ -DWINVER*)
+ ETHR_DEFS="$ETHR_DEFS $cppflag"
+ ;;
+ -D_WIN32_WINNT*)
+ ETHR_DEFS="$ETHR_DEFS $cppflag"
+ found_win32_winnt=yes
+ ;;
+ *)
+ ;;
+ esac
+ done
+ if test $found_win32_winnt = no; then
+ AC_MSG_ERROR([-D_WIN32_WINNT missing in CPPFLAGS])
+ fi
+ AC_DEFINE(ETHR_WIN32_THREADS, 1, [Define if you have win32 threads])
+ ;;
+
+ pthread)
+ AC_DEFINE(ETHR_PTHREADS, 1, [Define if you have pthreads])
+ case $host_os in
+ openbsd*)
+ # The default stack size is insufficient for our needs
+ # on OpenBSD. We increase it to 256 kilo words.
+ ethr_modified_default_stack_size=256;;
+ linux*)
+ ETHR_DEFS="$ETHR_DEFS -D_GNU_SOURCE"
+
+ if test X$cross_compiling = Xyes; then
+ case X$erl_xcomp_linux_usable_sigusrx in
+ X) usable_sigusrx=cross;;
+ Xyes|Xno) usable_sigusrx=$erl_xcomp_linux_usable_sigusrx;;
+ *) AC_MSG_ERROR([Bad erl_xcomp_linux_usable_sigusrx value: $erl_xcomp_linux_usable_sigusrx]);;
+ esac
+ case X$erl_xcomp_linux_usable_sigaltstack in
+ X) usable_sigaltstack=cross;;
+ Xyes|Xno) usable_sigaltstack=$erl_xcomp_linux_usable_sigaltstack;;
+ *) AC_MSG_ERROR([Bad erl_xcomp_linux_usable_sigaltstack value: $erl_xcomp_linux_usable_sigaltstack]);;
+ esac
+ else
+ # FIXME: Test for actual problems instead of kernel versions
+ linux_kernel_vsn_=`uname -r`
+ case $linux_kernel_vsn_ in
+ [[0-1]].*|2.[[0-1]]|2.[[0-1]].*)
+ usable_sigusrx=no
+ usable_sigaltstack=no;;
+ 2.[[2-3]]|2.[[2-3]].*)
+ usable_sigusrx=yes
+ usable_sigaltstack=no;;
+ *)
+ usable_sigusrx=yes
+ usable_sigaltstack=yes;;
+ esac
+ fi
+
+ AC_MSG_CHECKING(if SIGUSR1 and SIGUSR2 can be used)
+ AC_MSG_RESULT($usable_sigusrx)
+ if test $usable_sigusrx = cross; then
+ usable_sigusrx=yes
+ AC_MSG_WARN([result yes guessed because of cross compilation])
+ fi
+ if test $usable_sigusrx = no; then
+ ETHR_DEFS="$ETHR_DEFS -DETHR_UNUSABLE_SIGUSRX"
+ fi
+
+ AC_MSG_CHECKING(if sigaltstack can be used)
+ AC_MSG_RESULT($usable_sigaltstack)
+ if test $usable_sigaltstack = cross; then
+ usable_sigaltstack=yes
+ AC_MSG_WARN([result yes guessed because of cross compilation])
+ fi
+ if test $usable_sigaltstack = no; then
+ ETHR_DEFS="$ETHR_DEFS -DETHR_UNUSABLE_SIGALTSTACK"
+ fi
AC_DEFINE(ETHR_INIT_MUTEX_IN_CHILD_AT_FORK, 1, \
[Define if mutexes should be reinitialized (instead of unlocked) in child at fork.]) ;;
@@ -598,20 +779,18 @@ dnl On ofs1 the '-pthread' switch should be used
dnl We sometimes need ETHR_DEFS in order to find certain headers
dnl (at least for pthread.h on osf1).
- saved_cppflags=$CPPFLAGS
+ saved_cppflags="$CPPFLAGS"
CPPFLAGS="$CPPFLAGS $ETHR_DEFS"
dnl We need the thread library in order to find some functions
- saved_libs=$LIBS
+ saved_libs="$LIBS"
LIBS="$LIBS $ETHR_X_LIBS"
-
-
dnl
dnl Check for headers
dnl
- AC_CHECK_HEADER(pthread.h,
+ AC_CHECK_HEADER(pthread.h, \
AC_DEFINE(ETHR_HAVE_PTHREAD_H, 1, \
[Define if you have the <pthread.h> header file.]))
@@ -647,8 +826,11 @@ dnl On ofs1 the '-pthread' switch should be used
AC_CHECK_FUNC(pthread_spin_lock, \
AC_DEFINE(ETHR_HAVE_PTHREAD_SPIN_LOCK, 1, \
[Define if you have the pthread_spin_lock function.]))
- case $host_os in
- linux*) # Writers may get starved
+ test "$force_linux_pthread_rwlocks" = "yes" || {
+ force_linux_pthread_rwlocks=no
+ }
+ case "$force_linux_pthread_rwlocks-$host_os" in
+ no-linux*) # Writers may get starved
# TODO: write a test that tests the implementation
;;
*)
@@ -665,9 +847,10 @@ dnl On ofs1 the '-pthread' switch should be used
LIBS=$saved_libs
dnl restore CPPFLAGS
CPPFLAGS=$saved_cppflags
-
- fi
-fi
+ ;;
+ *)
+ ;;
+esac
AC_MSG_CHECKING([whether default stack size should be modified])
if test "x$ethr_modified_default_stack_size" != "x"; then
@@ -683,7 +866,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
@@ -698,7 +881,6 @@ AC_SUBST(ETHR_LIBS)
AC_SUBST(ETHR_LIB_NAME)
AC_SUBST(ETHR_DEFS)
AC_SUBST(ETHR_THR_LIB_BASE)
-AC_SUBST(ETHR_THR_LIB_BASE_NAME)
])
@@ -751,13 +933,28 @@ 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
+ linux_kernel_vsn_=`uname -r`
+ case $linux_kernel_vsn_ in
+ [[0-1]].*|2.[[0-5]]|2.[[0-5]].*)
+ erl_cv_time_correction=times ;;
+ *)
+ erl_cv_time_correction=clock_gettime;;
+ esac
+ else
+ case X$erl_xcomp_linux_clock_gettime_correction in
+ X)
+ erl_cv_time_correction=cross;;
+ Xyes|Xno)
+ if test $erl_xcomp_linux_clock_gettime_correction = yes; then
+ erl_cv_time_correction=clock_gettime
+ else
+ erl_cv_time_correction=times
+ fi;;
+ *)
+ AC_MSG_ERROR([Bad erl_xcomp_linux_clock_gettime_correction value: $erl_xcomp_linux_clock_gettime_correction]);;
+ esac
+ fi
else
erl_cv_time_correction=times
fi
@@ -774,13 +971,18 @@ case $clock_gettime_correction in
;;
esac
])
+
xrtlib=""
case $erl_cv_time_correction in
times)
AC_DEFINE(CORRECT_USING_TIMES,[],
[Define if you do not have a high-res. timer & want to use times() instead])
;;
- clock_gettime)
+ clock_gettime|cross)
+ if test $erl_cv_time_correction = cross; then
+ erl_cv_time_correction=clock_gettime
+ AC_MSG_WARN([result clock_gettime guessed because of cross compilation])
+ fi
xrtlib="-lrt"
AC_DEFINE(GETHRTIME_WITH_CLOCK_GETTIME,[1],
[Define if you want to use clock_gettime to simulate gethrtime])
@@ -840,7 +1042,24 @@ 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,
+[
+case X$erl_xcomp_gethrvtime_procfs_ioctl in
+ X)
+ erl_gethrvtime=cross;;
+ Xyes|Xno)
+ if test $erl_xcomp_gethrvtime_procfs_ioctl = yes; then
+ erl_gethrvtime=procfs_ioctl
+ else
+ erl_gethrvtime=false
+ fi;;
+ *)
+ AC_MSG_ERROR([Bad erl_xcomp_gethrvtime_procfs_ioctl value: $erl_xcomp_gethrvtime_procfs_ioctl]);;
+esac
+])
+
case $erl_gethrvtime in
procfs_ioctl)
AC_DEFINE(HAVE_GETHRVTIME_PROCFS_IOCTL,[1],
@@ -848,7 +1067,13 @@ case $erl_gethrvtime in
AC_MSG_RESULT(uses ioctl to procfs)
;;
*)
- AC_MSG_RESULT(not working)
+ if test $erl_gethrvtime = cross; then
+ erl_gethrvtime=false
+ AC_MSG_RESULT(cross)
+ AC_MSG_WARN([result 'not working' guessed because of cross compilation])
+ else
+ AC_MSG_RESULT(not working)
+ fi
dnl
dnl Check if clock_gettime (linux) is working
@@ -880,23 +1105,36 @@ 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=yes,
+ erl_clock_gettime=no,
+ [
+ case X$erl_xcomp_clock_gettime_cpu_time in
+ X) erl_clock_gettime=cross;;
+ Xyes|Xno) erl_clock_gettime=$erl_xcomp_clock_gettime_cpu_time;;
+ *) AC_MSG_ERROR([Bad erl_xcomp_clock_gettime_cpu_time value: $erl_xcomp_clock_gettime_cpu_time]);;
+ esac
+ ])
LIBS=$save_libs
case $host_os in
linux*)
- AC_MSG_RESULT([not stable, disabled])
+ AC_MSG_RESULT([no; not stable])
LIBRT=$xrtlib
;;
*)
+ AC_MSG_RESULT($erl_clock_gettime)
case $erl_clock_gettime in
- true)
+ yes)
AC_DEFINE(HAVE_CLOCK_GETTIME,[],
[define if clock_gettime() works for getting process time])
- AC_MSG_RESULT(using clock_gettime)
LIBRT=-lrt
;;
+ cross)
+ erl_clock_gettime=no
+ AC_MSG_WARN([result no guessed because of cross compilation])
+ LIBRT=$xrtlib
+ ;;
*)
- AC_MSG_RESULT(not working)
LIBRT=$xrtlib
;;
esac
diff --git a/erts/autoconf/vxworks/sed.vxworks_cpu32 b/erts/autoconf/vxworks/sed.vxworks_cpu32
index 171341db63..163dd78897 100644
--- a/erts/autoconf/vxworks/sed.vxworks_cpu32
+++ b/erts/autoconf/vxworks/sed.vxworks_cpu32
@@ -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%
#
# Author: Patrik Winroth
@@ -38,5 +38,8 @@ s|@AR@|@TTPREFIX@ar68k|
s|@STRIP@|@TTPREFIX@strip68k|
s|@SYMPREFIX@|_|
s|@GCCLIBFLAGS@|-L@WIND_BASE@/host/@HOST_TYPE@/lib/gcc-lib/m68k-wrs-vxworks/cygnus-2.7.2-960126/m68000/msoft-float -lgcc|
+
+s|@LIB_CFLAGS@|@CFLAGS@|
+
s|@CFLAGS@|@GENERAL_CFLAGS@ -DCPU=CPU32 -mnobitfield -DWANT_NONBLOCKING -DHAVE_MEMMOVE -DVXWORKS -I@WIND_BASE@/target/h -fno-builtin -nostdinc -fvolatile -msoft-float|
-s|@LIB_CFLAGS@|@GENERAL_CFLAGS@ -DCPU=CPU32 -mnobitfield -DWANT_NONBLOCKING -DHAVE_MEMMOVE -DVXWORKS -I@WIND_BASE@/target/h -fno-builtin -nostdinc -fvolatile -msoft-float|
+#s|@LIB_CFLAGS@|@GENERAL_CFLAGS@ -DCPU=CPU32 -mnobitfield -DWANT_NONBLOCKING -DHAVE_MEMMOVE -DVXWORKS -I@WIND_BASE@/target/h -fno-builtin -nostdinc -fvolatile -msoft-float|
diff --git a/erts/autoconf/vxworks/sed.vxworks_ppc32 b/erts/autoconf/vxworks/sed.vxworks_ppc32
index a1067ea575..5db28337c0 100644
--- a/erts/autoconf/vxworks/sed.vxworks_ppc32
+++ b/erts/autoconf/vxworks/sed.vxworks_ppc32
@@ -1,19 +1,19 @@
#
# %CopyrightBegin%
-#
-# Copyright Ericsson AB 2006-2009. All Rights Reserved.
-#
+#
+# Copyright Ericsson AB 2006-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%
#
# Author: Peter Andersson
@@ -44,5 +44,9 @@ s|@GCCLIB_PATH@|@WIND_BASE@/vxworks-6.3/target/lib/ppc/PPC32/common/libgcc.a|
s|@RANLIB@|GCC_EXEC_PREFIX=@WIND_BASE@/gnu/3.4.4-vxworks-6.3/@HOST_TYPE@/lib/gcc-lib/ @WIND_BASE@/gnu/3.4.4-vxworks-6.3/@HOST_TYPE@/bin/ranlibppc|
s|@AR@|GCC_EXEC_PREFIX=@WIND_BASE@/gnu/3.4.4-vxworks-6.3/@HOST_TYPE@/lib/gcc-lib/ @WIND_BASE@/gnu/3.4.4-vxworks-6.3/@HOST_TYPE@/bin/arppc|
# -Dasm(X)= is for beam
+
+s|@LIB_CFLAGS@|@CFLAGS@|
+
s|@CFLAGS@|@GENERAL_CFLAGS@ -DCPU=PPC32 -DTOOL_FAMILY=gnu -DTOOL=gnu -DWANT_NONBLOCKING -DHAVE_SENS -DHAVE_MEMMOVE -DVXWORKS -I@WIND_BASE@/vxworks-6.3/target/h -I@WIND_BASE@/gnu/3.4.4-vxworks-6.3/@HOST_TYPE@/lib/gcc/powerpc-wrs-vxworks/3.4.4/include -I@WIND_BASE@/vxworks-6.3/target/h/wrn/coreip -mstrict-align -fvolatile -fno-builtin |
-s|@LIB_CFLAGS@|@GENERAL_CFLAGS@ -DCPU=PPC32 -DTOOL_FAMILY=gnu -DTOOL=gnu -DWANT_NONBLOCKING -DHAVE_SENS -DHAVE_MEMMOVE -DVXWORKS -I@WIND_BASE@/vxworks-6.3/target/h/wrn/coreip -I@WIND_BASE@/vxworks-6.3/target/h -mstrict-align -fvolatile -fno-builtin |
+
+#s|@LIB_CFLAGS@|@GENERAL_CFLAGS@ -DCPU=PPC32 -DTOOL_FAMILY=gnu -DTOOL=gnu -DWANT_NONBLOCKING -DHAVE_SENS -DHAVE_MEMMOVE -DVXWORKS -I@WIND_BASE@/vxworks-6.3/target/h/wrn/coreip -I@WIND_BASE@/vxworks-6.3/target/h -mstrict-align -fvolatile -fno-builtin |
diff --git a/erts/autoconf/vxworks/sed.vxworks_ppc603 b/erts/autoconf/vxworks/sed.vxworks_ppc603
index 97f0429847..40296b8f07 100644
--- a/erts/autoconf/vxworks/sed.vxworks_ppc603
+++ b/erts/autoconf/vxworks/sed.vxworks_ppc603
@@ -1,19 +1,19 @@
#
# %CopyrightBegin%
-#
-# Copyright Ericsson AB 2000-2009. All Rights Reserved.
-#
+#
+# Copyright Ericsson AB 2000-2010. All Rights Reserved.
+#
# The contents of this file are subject to the Erlang Public License,
# Version 1.1, (the "License"); you may not use this file except in
# compliance with the License. You should have received a copy of the
# Erlang Public License along with this software. If not, it can be
# retrieved online at http://www.erlang.org/.
-#
+#
# Software distributed under the License is distributed on an "AS IS"
# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
# the License for the specific language governing rights and limitations
# under the License.
-#
+#
# %CopyrightEnd%
#
# Author: Patrik Winroth
@@ -44,5 +44,8 @@ s|@GCCLIB_PATH@|@WIND_BASE@/host/@HOST_TYPE@/lib/gcc-lib/powerpc-wrs-vxworks/cyg
s|@RANLIB@|@TTPREFIX@ranlibppc|
s|@AR@|@TTPREFIX@arppc|
# -Dasm(X)= is for beam
+
+s|@LIB_CFLAGS@|@CFLAGS@|
+
s|@CFLAGS@|@GENERAL_CFLAGS@ -DCPU=PPC603 -DWANT_NONBLOCKING -DHAVE_MEMMOVE -DVXWORKS -I@WIND_BASE@/target/h -mstrict-align -fvolatile -fno-builtin -fno-for-scope -D_GNU_TOOL|
-s|@LIB_CFLAGS@|@GENERAL_CFLAGS@ -DCPU=PPC603 -DWANT_NONBLOCKING -DHAVE_MEMMOVE -DVXWORKS -I@WIND_BASE@/target/h -mstrict-align -fvolatile -fno-builtin -fno-for-scope -D_GNU_TOOL|
+#s|@LIB_CFLAGS@|@GENERAL_CFLAGS@ -DCPU=PPC603 -DWANT_NONBLOCKING -DHAVE_MEMMOVE -DVXWORKS -I@WIND_BASE@/target/h -mstrict-align -fvolatile -fno-builtin -fno-for-scope -D_GNU_TOOL|
diff --git a/erts/autoconf/vxworks/sed.vxworks_ppc603_nolongcall b/erts/autoconf/vxworks/sed.vxworks_ppc603_nolongcall
index 8968498c44..2550432d1e 100644
--- a/erts/autoconf/vxworks/sed.vxworks_ppc603_nolongcall
+++ b/erts/autoconf/vxworks/sed.vxworks_ppc603_nolongcall
@@ -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%
#
# Author: Patrik Winroth
@@ -43,6 +43,9 @@ s|@GCCLIB_PATH@|@WIND_BASE@/host/@HOST_TYPE@/lib/gcc-lib/powerpc-wrs-vxworks/cyg
s|@RANLIB@|@TTPREFIX@ranlibppc|
s|@AR@|@TTPREFIX@arppc|
# -Dasm(X)= is for beam
+
+s|@LIB_CFLAGS@|@CFLAGS@|
+
s|@CFLAGS@|@GENERAL_CFLAGS@ -DCPU=PPC603 -DWANT_NONBLOCKING -DHAVE_MEMMOVE -DVXWORKS -I@WIND_BASE@/target/h -mstrict-align -fvolatile -fno-builtin -fno-for-scope -D_GNU_TOOL|
-s|@LIB_CFLAGS@|@GENERAL_CFLAGS@ -DCPU=PPC603 -DWANT_NONBLOCKING -DHAVE_MEMMOVE -DVXWORKS -I@WIND_BASE@/target/h -mstrict-align -fvolatile -fno-builtin -fno-for-scope -D_GNU_TOOL|
+#s|@LIB_CFLAGS@|@GENERAL_CFLAGS@ -DCPU=PPC603 -DWANT_NONBLOCKING -DHAVE_MEMMOVE -DVXWORKS -I@WIND_BASE@/target/h -mstrict-align -fvolatile -fno-builtin -fno-for-scope -D_GNU_TOOL|
diff --git a/erts/autoconf/vxworks/sed.vxworks_ppc860 b/erts/autoconf/vxworks/sed.vxworks_ppc860
index 35771335a3..cd7c9ff797 100644
--- a/erts/autoconf/vxworks/sed.vxworks_ppc860
+++ b/erts/autoconf/vxworks/sed.vxworks_ppc860
@@ -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%
#
# Author: Patrik Winroth
@@ -43,5 +43,8 @@ s|TYPE_FLAGS = -g |TYPE_FLAGS = |
s|@GCCLIB_PATH@|@WIND_BASE@/host/@HOST_TYPE@/lib/gcc-lib/powerpc-wrs-vxworks/cygnus-2.7.2-960126/soft-float/libgcc.a|
s|@RANLIB@|@TTPREFIX@ranlibppc|
s|@AR@|@TTPREFIX@arppc|
+
+s|@LIB_CFLAGS@|@CFLAGS@|
+
s|@CFLAGS@|@GENERAL_CFLAGS@ -DCPU=PPC860 -DWANT_NONBLOCKING -DHAVE_MEMMOVE -DVXWORKS -I@WIND_BASE@/target/h -mcpu=860 -fvolatile -fno-builtin -fno-for-scope -msoft-float -D_GNU_TOOL -nostdinc|
-s|@LIB_CFLAGS@|@GENERAL_CFLAGS@ -DCPU=PPC860 -DWANT_NONBLOCKING -DHAVE_MEMMOVE -DVXWORKS -I@WIND_BASE@/target/h -mcpu=powerpc -fvolatile -fno-builtin -fno-for-scope -msoft-float -D_GNU_TOOL -nostdinc|
+#s|@LIB_CFLAGS@|@GENERAL_CFLAGS@ -DCPU=PPC860 -DWANT_NONBLOCKING -DHAVE_MEMMOVE -DVXWORKS -I@WIND_BASE@/target/h -mcpu=powerpc -fvolatile -fno-builtin -fno-for-scope -msoft-float -D_GNU_TOOL -nostdinc|
diff --git a/erts/autoconf/vxworks/sed.vxworks_simlinux b/erts/autoconf/vxworks/sed.vxworks_simlinux
index b629296caa..6eb6f8ea92 100644
--- a/erts/autoconf/vxworks/sed.vxworks_simlinux
+++ b/erts/autoconf/vxworks/sed.vxworks_simlinux
@@ -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%
#
# Author: Peter Andersson
@@ -53,5 +53,7 @@ s|@RANLIB@|GCC_EXEC_PREFIX=@WIND_BASE@/gnu/3.4.4-vxworks-6.3/@HOST_TYPE@/lib/gcc
s|@AR@|GCC_EXEC_PREFIX=@WIND_BASE@/gnu/3.4.4-vxworks-6.3/@HOST_TYPE@/lib/gcc-lib/ @WIND_BASE@/gnu/3.4.4-vxworks-6.3/@HOST_TYPE@/bin/arpentium|
# -Dasm(X)= is for beam
+s|@LIB_CFLAGS@|@CFLAGS@|
+
s|@CFLAGS@|@GENERAL_CFLAGS@ -DCPU=SIMLINUX -DTOOL_FAMILY=gnu -DTOOL=gnu -DWANT_NONBLOCKING -DHAVE_SENS -DHAVE_MEMMOVE -DVXWORKS -DDEBUG -I@WIND_BASE@/vxworks-6.3/target/h -I@WIND_BASE@/gnu/3.4.4-vxworks-6.3/@HOST_TYPE@/lib/gcc/i586-wrs-vxworks/3.4.4/include -I@WIND_BASE@/vxworks-6.3/target/h/wrn/coreip -fvolatile -fno-builtin |
-s|@LIB_CFLAGS@|@GENERAL_CFLAGS@ -DCPU=SIMLINUX -DTOOL_FAMILY=gnu -DTOOL=gnu -DWANT_NONBLOCKING -DHAVE_SENS -DHAVE_MEMMOVE -DVXWORKS -DDEBUG -I@WIND_BASE@/vxworks-6.3/target/h -I@WIND_BASE@/vxworks-6.3/target/h/wrn/coreip -mstrict-align -fvolatile -fno-builtin |
+#s|@LIB_CFLAGS@|@GENERAL_CFLAGS@ -DCPU=SIMLINUX -DTOOL_FAMILY=gnu -DTOOL=gnu -DWANT_NONBLOCKING -DHAVE_SENS -DHAVE_MEMMOVE -DVXWORKS -DDEBUG -I@WIND_BASE@/vxworks-6.3/target/h -I@WIND_BASE@/vxworks-6.3/target/h/wrn/coreip -mstrict-align -fvolatile -fno-builtin |
diff --git a/erts/autoconf/vxworks/sed.vxworks_simso b/erts/autoconf/vxworks/sed.vxworks_simso
index e67abd3be1..1d7413b484 100644
--- a/erts/autoconf/vxworks/sed.vxworks_simso
+++ b/erts/autoconf/vxworks/sed.vxworks_simso
@@ -1,19 +1,19 @@
#
# %CopyrightBegin%
-#
-# Copyright Ericsson AB 2005-2009. All Rights Reserved.
-#
+#
+# Copyright Ericsson AB 2005-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%
#
# Author: Peter Andersson
@@ -58,5 +58,7 @@ s|@RANLIB@|GCC_EXEC_PREFIX=@WIND_BASE@/gnu/3.4.4-vxworks-6.3/@HOST_TYPE@/lib/gcc
s|@AR@|GCC_EXEC_PREFIX=@WIND_BASE@/gnu/3.4.4-vxworks-6.3/@HOST_TYPE@/lib/gcc-lib/ @WIND_BASE@/gnu/3.4.4-vxworks-6.3/@HOST_TYPE@/bin/arsparc|
# -Dasm(X)= is for beam
+s|@LIB_CFLAGS@|@CFLAGS@|
+
s|@CFLAGS@|@GENERAL_CFLAGS@ -DCPU=SIMSPARCSOLARIS -DTOOL_FAMILY=gnu -DTOOL=gnu -DWANT_NONBLOCKING -DHAVE_SENS -DHAVE_MEMMOVE -DVXWORKS -DDEBUG -I@WIND_BASE@/vxworks-6.3/target/h -I@WIND_BASE@/gnu/3.4.4-vxworks-6.3/@HOST_TYPE@/lib/gcc/sparc-wrs-vxworks/3.4.4/include -I@WIND_BASE@/vxworks-6.3/target/h/wrn/coreip -fvolatile -fno-builtin |
-s|@LIB_CFLAGS@|@GENERAL_CFLAGS@ -DCPU=SIMSPARCSOLARIS -DTOOL_FAMILY=gnu -DTOOL=gnu -DWANT_NONBLOCKING -DHAVE_SENS -DHAVE_MEMMOVE -DVXWORKS -DDEBUG -I@WIND_BASE@/vxworks-6.3/target/h -I@WIND_BASE@/vxworks-6.3/target/h/wrn/coreip -mstrict-align -fvolatile -fno-builtin |
+#s|@LIB_CFLAGS@|@GENERAL_CFLAGS@ -DCPU=SIMSPARCSOLARIS -DTOOL_FAMILY=gnu -DTOOL=gnu -DWANT_NONBLOCKING -DHAVE_SENS -DHAVE_MEMMOVE -DVXWORKS -DDEBUG -I@WIND_BASE@/vxworks-6.3/target/h -I@WIND_BASE@/vxworks-6.3/target/h/wrn/coreip -mstrict-align -fvolatile -fno-builtin |
diff --git a/erts/autoconf/win32.config.cache b/erts/autoconf/win32.config.cache
index 51cfa13785..31dfe510cd 100755
--- a/erts/autoconf/win32.config.cache
+++ b/erts/autoconf/win32.config.cache
@@ -186,10 +186,12 @@ ac_cv_prog_CC=${ac_cv_prog_CC=cc.sh}
ac_cv_prog_CPP=${ac_cv_prog_CPP='cc.sh -E'}
ac_cv_prog_CXX=${ac_cv_prog_CXX=cc.sh}
ac_cv_prog_DED_LD=${ac_cv_prog_DED_LD=ld.sh}
+ac_cv_prog_ac_ct_DED_LD=${ac_cv_prog_ac_ct_DED_LD=ld.sh}
ac_cv_prog_M4=${ac_cv_prog_M4=m4}
ac_cv_prog_PERL=${ac_cv_prog_PERL=perl}
ac_cv_prog_RANLIB=${ac_cv_prog_RANLIB=true}
-ac_cv_prog_ac_ct_LD=${ac_cv_prog_ac_ct_LD=ld}
+ac_cv_prog_LD=${ac_cv_prog_LD=ld.sh}
+ac_cv_prog_ac_ct_LD=${ac_cv_prog_ac_ct_LD=ld.sh}
ac_cv_prog_cc_g=${ac_cv_prog_cc_g=yes}
ac_cv_prog_cc_stdc=${ac_cv_prog_cc_stdc=}
ac_cv_prog_cxx_g=${ac_cv_prog_cxx_g=no}
diff --git a/erts/configure.in b/erts/configure.in
index 895a357023..5fa1245b13 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
@@ -23,6 +23,8 @@ dnl autoconf convention that should be cleaned up.
AC_INIT(vsn.mk)
AC_PREREQ(2.59)
+LM_PRECIOUS_VARS
+
if test "x$no_recursion" != "xyes" -a "x$OVERRIDE_CONFIG_CACHE" = "x"; then
# We do not want to use a common cache!
cache_file=/dev/null
@@ -84,6 +86,9 @@ if test "X$host" != "Xfree_source" -a "X$host" != "Xwin32"; then
else
host_os=$host
fi
+
+ERL_XCOMP_SYSROOT_INIT
+
AC_ISC_POSIX
AC_CONFIG_HEADER($host/config.h:config.h.in include/internal/$host/ethread_header_config.h:include/internal/ethread_header_config.h.in include/$host/erl_int_sizes_config.h:include/erl_int_sizes_config.h.in)
@@ -94,12 +99,21 @@ 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(bootstrap-only,
+[ --enable-bootstrap-only enable bootstrap only configuration],
+[ if test "X$enableval" = "Xyes"; then
+ # Disable stuff not necessary in a bootstrap only system in order
+ # to speed up things by reducing the amount of stuff needing to be
+ # built...
+ enable_threads=no
+ enable_smp_support=no
+ with_termcap=no
+ with_ssl=no
+ with_ssl_zlib=no
+ enable_hipe=no
+ enable_sctp=no
+ fi
+])
AC_ARG_ENABLE(threads,
[ --enable-threads enable async thread support
@@ -212,6 +226,19 @@ AC_ARG_ENABLE(m64-build,
esac
],enable_m64_build=no)
+AC_ARG_ENABLE(m32-build,
+[ --enable-m32-build build 32bit binaries using the -m32 flag to (g)cc],
+[ case "$enableval" in
+ no) enable_m32_build=no ;;
+ *)
+ if test X${enable_darwin_64bit} = Xyes -o X${enable_m64_build} = Xyes;
+ then
+ AC_MSG_ERROR([(--enable-darwin-64bit or --enable-m64-build) and --enable-m32-build are mutually exclusive]) ;
+ fi ;
+ enable_m32_build=yes ;;
+ esac
+],enable_m32_build=no)
+
AC_ARG_ENABLE(fixalloc,
[ --disable-fixalloc disable the use of fix_alloc])
if test x${enable_fixalloc} = xno ; then
@@ -302,7 +329,6 @@ if test X${enable_darwin_64bit} = Xyes; then
esac
fi
if test X${enable_darwin_64bit} = Xyes -o X${enable_m64_build} = Xyes; then
- enable_hipe=no
case $CFLAGS in
*-m64*)
;;
@@ -322,6 +348,17 @@ else
esac
;;
*)
+ if test X${enable_m32_build} = Xyes;
+ then
+ enable_hipe=no;
+ case $CFLAGS in
+ *-m32*)
+ ;;
+ *)
+ CFLAGS="-m32 $CFLAGS"
+ ;;
+ esac ;
+ fi
;;
esac
fi
@@ -332,6 +369,7 @@ dnl Checks for programs.
dnl ----------------------------------------------------------------------
AC_PROG_CC
+AC_SUBST(GCC)
dnl ---------------------------------------------------------------------
dnl Special stuff regarding CFLAGS and details in the environment...
@@ -351,6 +389,9 @@ case $host_os in
AC_MSG_WARN([Reverting to 32-bit time_t])
CPPFLAGS="$CPPFLAGS -D_USE_32BIT_TIME_T"
;;
+ darwin*)
+ CPPFLAGS="$CPPFLAGS -D_XOPEN_SOURCE"
+ ;;
*)
;;
esac
@@ -415,6 +456,35 @@ CFLAGS="$CFLAGS $extra_flags"
DEBUG_CFLAGS="-g $CPPFLAGS $extra_flags"
DEBUG_FLAGS=-g
+dnl
+dnl Adjust DEBUG_CFLAGS to match CFLAGS in terms of -m
+dnl
+
+case $CFLAGS in
+ *-m64*)
+ case $DEBUG_CFLAGS in
+ *-m64*)
+ ;;
+ *)
+ DEBUG_CFLAGS="-m64 $DEBUG_CFLAGS"
+ ;;
+ esac
+ ;;
+ *-m32*)
+ case $DEBUG_CFLAGS in
+ *-m32*)
+ ;;
+ *)
+ DEBUG_CFLAGS="-m32 $DEBUG_CFLAGS"
+ ;;
+ esac
+ ;;
+ *)
+ ;;
+esac
+
+
+
CFLAG_RUNTIME_LIBRARY_PATH="-Wl,-R"
case $host_os in
darwin*)
@@ -431,22 +501,59 @@ case $host_os in
;;
esac
+lfs_conf=ok
+lfs_source=none
+if test "${LFS_CFLAGS+set}" = "set" || \
+ test "${LFS_LDFLAGS+set}" = "set" || \
+ test "${LFS_LIBS+set}" = "set"; then
+ lfs_source=user
+else
+ LM_CHECK_GETCONF
+ test "$GETCONF" = "false" || lfs_source=getconf
+fi
-dnl
-dnl Use the getconf utility if it exists
-dnl to find large file support flags.
-dnl
-if type getconf >/dev/null 2>&1; then
- CFLAGS="$CFLAGS `getconf LFS_CFLAGS 2>/dev/null`"
- DEBUG_CFLAGS="$DEBUG_CFLAGS `getconf LFS_CFLAGS 2>/dev/null`"
- LDFLAGS="$LDFLAGS `getconf LFS_LDFLAGS 2>/dev/null`"
- LIBS="$LIBS `getconf LFS_LIBS 2>/dev/null`"
+if test "$lfs_source" = "none"; then
+ AC_MSG_WARN([Do not know how to check for large file support flags; no getconf is available])
+else
+ for var in CFLAGS LDFLAGS LIBS; do
+ AC_MSG_CHECKING([for large file support $var])
+ if test $lfs_source = user; then
+ eval "lfs_val=\"\$LFS_$var\""
+ else
+ eval "lfs_var=LFS_$var"
+ lfs_val=`$GETCONF $lfs_var 2>/dev/null` || lfs_conf=failed
+ if test $lfs_conf = failed; then
+ AC_MSG_RESULT([failed])
+ break
+ fi
+ eval "$lfs_var=\"$lfs_val\""
+ fi
+ test "$lfs_val" != "" || lfs_val=none
+ AC_MSG_RESULT([$lfs_val])
+ done
+ if test $lfs_conf = failed; then
+ AC_MSG_WARN([Check for large file support flags failed; $GETCONF failed])
+ else
+ CFLAGS="$CFLAGS $LFS_CFLAGS"
+ DEBUG_CFLAGS="$DEBUG_CFLAGS $LFS_CFLAGS"
+ LDFLAGS="$LDFLAGS $LFS_LDFLAGS"
+ LIBS="$LIBS $LFS_LIBS"
+ fi
fi
if test "x$GCC" = xyes; then
# until the emulator can handle this, I suggest we turn it off!
#WFLAGS="-Wall -Wshadow -Wcast-qual -Wmissing-declarations"
- WFLAGS="-Wall -Wstrict-prototypes -Wmissing-prototypes"
+ WFLAGS="-Wall -Wstrict-prototypes"
+
+ case "$host_cpu" in
+ tile*)
+ # tile-gcc is a bit stricter with -Wmissing-prototypes than other gccs,
+ # and too strict for our taste.
+ ;;
+ *)
+ WFLAGS="$WFLAGS -Wmissing-prototypes";;
+ esac
saved_CFLAGS=$CFLAGS
CFLAGS="$CFLAGS -Wdeclaration-after-statement"
@@ -464,22 +571,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
@@ -491,11 +594,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;;
@@ -613,6 +717,16 @@ case $ARCH-$OPSYS in
LDFLAGS="-m64 $LDFLAGS"
;;
esac
+ fi;
+ if test X${enable_m32_build} = Xyes; then
+ AC_MSG_NOTICE([Adjusting LDFLAGS to use -m32]) ;
+ case $LDFLAGS in
+ *-m32*)
+ ;;
+ *)
+ LDFLAGS="-m32 $LDFLAGS"
+ ;;
+ esac ;
fi
;;
esac
@@ -649,7 +763,7 @@ fi
AC_PROG_LN_S
-AC_CHECK_PROG(AR, ar, ar, false)
+AC_CHECK_TOOL([AR], [ar], [false])
if test "$ac_cv_prog_AR" = false; then
AC_MSG_ERROR([No 'ar' command found in PATH])
fi
@@ -740,8 +854,17 @@ HCC='$(CC)' AC_SUBST(HCC)
HCFLAGS="" AC_SUBST(HCFLAGS)
HCFLAGS="$HCFLAGS -I${ERL_TOP}/erts/$host"
vxworks_reclaim="" AC_SUBST(vxworks_reclaim)
-LD='$(CC)' AC_SUBST(LD)
+dnl We want to use $(CC) as linker for the emulator regardless of
+dnl what the user say. This might not be the right way to do it, but
+dnl for now that is the way we do it.
+USER_LD=$LD
+USER_LDFLAGS="$LDFLAGS"
+LD='$(CC)'
+AC_SUBST(LD)
+
+LDFLAG_RUNTIME_LIBRARY_PATH="$CFLAG_RUNTIME_LIBRARY_PATH"
+AC_SUBST(LDFLAG_RUNTIME_LIBRARY_PATH)
dnl Check for cygwin and object/exe files extension
dnl AC_CYGWIN is deprecated
@@ -1296,11 +1419,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,
@@ -1318,7 +1441,7 @@ AC_CHECK_HEADER(sys/devpoll.h, have_kernel_poll=/dev/poll)
dnl Check for kernel SCTP support
AC_SUBST(LIBSCTP)
-if test "x$enable_sctp" == "xyes" ; then
+if test "x$enable_sctp" = "xyes" ; then
AC_CHECK_HEADER(netinet/sctp.h,
[LIBSCTP=libsctp.so.1
AC_DEFINE(HAVE_SCTP_H, [1],
@@ -1389,11 +1512,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=
@@ -1457,76 +1582,33 @@ 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])
-
-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])
+], 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
-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))
+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
-if test "x$erl_xcomp_bigendian" != "x"; then
- ac_cv_c_bigendian=$erl_xcomp_bigendian
fi
+case X$erl_xcomp_bigendian in
+ X) ;;
+ Xyes|Xno) ac_cv_c_bigendian=$erl_xcomp_bigendian;;
+ *) AC_MSG_ERROR([Bad erl_xcomp_bigendian value: $erl_xcomp_bigendian]);;
+esac
+
AC_C_BIGENDIAN
dnl ----------------------------------------------------------------------
@@ -1563,18 +1645,22 @@ int main(int argc, char **argv) {
}
}
],, have_getaddrinfo=no,
- if test "x$erl_xcomp_getaddrinfo" != "x"; then
- have_getaddrinfo=$erl_xcomp_getaddrinfo
- else
- have_getaddrinfo=no
- fi)
- if test $have_getaddrinfo = yes; then
- AC_MSG_RESULT(yes)
+ [
+ case X$erl_xcomp_getaddrinfo in
+ X) have_getaddrinfo=cross;;
+ Xyes|Xno) have_getaddrinfo=$erl_xcomp_getaddrinfo;;
+ *) AC_MSG_ERROR([Bad erl_xcomp_getaddrinfo value: $erl_xcomp_getaddrinfo]);;
+ esac
+ ])
+ AC_MSG_RESULT($have_getaddrinfo)
+ case $have_getaddrinfo in
+ yes)
AC_DEFINE(HAVE_GETADDRINFO, [1],
- [Define to 1 if you have a good `getaddrinfo' function.])
- else
- AC_MSG_RESULT(no)
- fi
+ [Define to 1 if you have a good `getaddrinfo' function.]);;
+ cross)
+ AC_MSG_WARN([result no guessed because of cross compilation]);;
+ *) ;;
+ esac
fi
AC_CHECK_FUNCS([getnameinfo getipnodebyname getipnodebyaddr gethostbyname2])
@@ -1582,7 +1668,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
@@ -1856,14 +1942,21 @@ int main(void)
],
erts_cv___after_morecore_hook_can_track_malloc=yes,
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
- fi)])
+ [
+ case X$erl_xcomp_after_morecore_hook in
+ X) erts_cv___after_morecore_hook_can_track_malloc=cross;;
+ Xyes|Xno) erts_cv___after_morecore_hook_can_track_malloc=$erl_xcomp_after_morecore_hook;;
+ *) AC_MSG_ERROR([Bad erl_xcomp_after_morecore_hook value: $erl_xcomp_after_morecore_hook]);;
+ esac
+ ]
+ )])
-if test "x$erts_cv___after_morecore_hook_can_track_malloc" = "xyes"; then
- AC_DEFINE(ERTS___AFTER_MORECORE_HOOK_CAN_TRACK_MALLOC, 1, \
-[Define if __after_morecore_hook can track malloc()s core memory use.])
-fi
+case $erts_cv___after_morecore_hook_can_track_malloc in
+ yes) AC_DEFINE(ERTS___AFTER_MORECORE_HOOK_CAN_TRACK_MALLOC, 1, \
+[Define if __after_morecore_hook can track malloc()s core memory use.]);;
+ cross) AC_MSG_WARN([result no guessed because of cross compilation]);;
+ *) ;;
+esac
if test "x$ac_cv_func_sbrk" = "xyes"; then
AC_CACHE_CHECK([types of sbrk()s return value and argument],
@@ -2116,11 +2209,21 @@ 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 $erts_cv_brk_wrappers_can_track_malloc = yes; then
+ [
+ case X$erl_xcomp_dlsym_brk_wrappers in
+ X) erts_cv_brk_wrappers_can_track_malloc=cross;;
+ Xyes|Xno) erts_cv_brk_wrappers_can_track_malloc=$erl_xcomp_dlsym_brk_wrappers;;
+ *) AC_MSG_ERROR([Bad erl_xcomp_dlsym_brk_wrappers value: $erl_xcomp_dlsym_brk_wrappers]);;
+ esac
+ ])])
+ case $erts_cv_brk_wrappers_can_track_malloc in
+ yes)
AC_DEFINE(ERTS_BRK_WRAPPERS_CAN_TRACK_MALLOC, 1, \
-[Define if sbrk()/brk() wrappers can track malloc()s core memory use])
- fi
+[Define if sbrk()/brk() wrappers can track malloc()s core memory use]);;
+ cross)
+ AC_MSG_WARN([result no guessed because of cross compilation]);;
+ *) ;;
+ esac
fi
dnl Restore LIBS
@@ -2133,18 +2236,56 @@ LM_SYS_MULTICAST
ERL_TIME_CORRECTION
AC_CHECK_PROG(M4, m4, m4)
dnl check to auto-enable hipe here...
-if test X${enable_hipe} != Xno; then
+if test "$cross_compiling" != "yes" && test X${enable_hipe} != Xno; then
if test -z "$M4"; then
enable_hipe=no
AC_MSG_NOTICE([HiPE disabled as no valid m4 is found in PATH])
else
case "$ARCH-$OPSYS" in
- x86-linux|amd64-linux|ppc-linux|ppc-darwin|arm-linux|amd64-freebsd|x86-freebsd|x86-sol2|amd64-sol2|ultrasparc-linux)
+ x86-linux|amd64-linux|x86-darwin*|amd64-darwin*|ppc-linux|ppc-darwin|arm-linux|amd64-freebsd|x86-freebsd|x86-sol2|amd64-sol2|ultrasparc-linux)
enable_hipe=yes
;;
esac
fi
fi
+
+case $ARCH-$OPSYS in
+ amd64-darwin*|x86-darwin*)
+ AC_MSG_CHECKING([For modern (leopard) style mcontext_t])
+ AC_TRY_COMPILE([
+ #include <stdlib.h>
+ #include <sys/types.h>
+ #include <unistd.h>
+ #include <mach/mach.h>
+ #include <pthread.h>
+ #include <machine/signal.h>
+ #include <ucontext.h>
+ ],[
+ #if defined(__APPLE__) && defined(__MACH__) && !defined(__DARWIN__)
+ #define __DARWIN__ 1
+ #endif
+
+ #ifndef __DARWIN__
+ #error inpossible
+ #else
+
+ mcontext_t mc = NULL;
+ int x = mc->__fs.__fpu_mxcsr;
+
+ #endif
+ ],darwin_mcontext_leopard=yes,
+ darwin_mcontext_leopard=no)
+ if test X"$darwin_mcontext_leopard" = X"yes"; then
+ AC_DEFINE(DARWIN_MODERN_MCONTEXT,[],[Modern style mcontext_t in MacOSX])
+ AC_MSG_RESULT(yes)
+ else
+ AC_MSG_RESULT(no)
+ fi
+ ;;
+ *)
+ darwin_mcontext_leopard=no
+ ;;
+esac
if test X${enable_fp_exceptions} = Xauto ; then
if test X${enable_hipe} = Xyes; then
enable_fp_exceptions=yes
@@ -2534,6 +2675,7 @@ static void fpe_sig_action(int sig, siginfo_t *si, void *puc)
regs[PT_FPSCR] = 0x80|0x40|0x10; /* VE, OE, ZE; not UE or XE */
#endif
#elif defined(__DARWIN__)
+#if defined(DARWIN_MODERN_MCONTEXT)
#if defined(__x86_64__)
mcontext_t mc = uc->uc_mcontext;
struct __darwin_x86_float_state64 *fpstate = &mc->__fs;
@@ -2549,6 +2691,23 @@ static void fpe_sig_action(int sig, siginfo_t *si, void *puc)
mc->ss.srr0 += 4;
mc->fs.fpscr = 0x80|0x40|0x10;
#endif
+#else
+#if defined(__x86_64__)
+ mcontext_t mc = uc->uc_mcontext;
+ struct x86_float_state64_t *fpstate = &mc->fs;
+ fpstate->fpu_mxcsr = 0x1F80;
+ *(unsigned short *)&fpstate->fpu_fsw &= ~0xFF;
+#elif defined(__i386__)
+ mcontext_t mc = uc->uc_mcontext;
+ x86_float_state32_t *fpstate = &mc->fs;
+ fpstate->fpu_mxcsr = 0x1F80;
+ *(unsigned short *)&fpstate->fpu_fsw &= ~0xFF;
+#elif defined(__ppc__)
+ mcontext_t mc = uc->uc_mcontext;
+ mc->ss.srr0 += 4;
+ mc->fs.fpscr = 0x80|0x40|0x10;
+#endif
+#endif
#elif defined(__FreeBSD__) && defined(__x86_64__)
mcontext_t *mc = &uc->uc_mcontext;
struct savefpu *savefpu = (struct savefpu*)&mc->mc_fpstate;
@@ -2643,55 +2802,30 @@ int main(int argc, const char **argv)
do_fmul();
return do_check();
}
-], erl_ok=reliable, erl_ok=unreliable, erl_ok=unreliable)
- if test $erl_ok = unreliable; then
- AC_DEFINE(NO_FPE_SIGNALS,[],
- [Define if floating points exceptions are non-existing/not reliable])
- AC_MSG_RESULT([unreliable; testing in software instead])
- FPE=unreliable
- else
+],
+erl_ok=yes,
+erl_ok=no,
+[
+case X$erl_xcomp_reliable_fpe in
+ X) erl_ok=cross;;
+ Xyes|Xno) erl_ok=$erl_xcomp_reliable_fpe;;
+ *) AC_MSG_ERROR([Bad erl_xcomp_reliable_fpe value: $erl_xcomp_reliable_fpe]);;
+esac
+])
+
+ if test $erl_ok = yes; then
+ FPE=reliable
AC_MSG_RESULT(reliable)
- FPE=reliable
+ else
+ FPE=unreliable
+ AC_MSG_RESULT([unreliable; testing in software instead])
+ AC_DEFINE(NO_FPE_SIGNALS,[],[Define if floating points exceptions are non-existing/not reliable])
+ if test $erl_ok = cross; then
+ AC_MSG_WARN([result unreliable guessed because of cross compilation])
+ fi
fi
fi
-case $ARCH-$OPSYS in
- amd64-darwin*|x86-darwin*)
- AC_MSG_CHECKING([For modern (leopard) style mcontext_t])
- AC_TRY_COMPILE([
- #include <stdlib.h>
- #include <sys/types.h>
- #include <unistd.h>
- #include <mach/mach.h>
- #include <pthread.h>
- #include <machine/signal.h>
- #include <ucontext.h>
- ],[
- #if defined(__APPLE__) && defined(__MACH__) && !defined(__DARWIN__)
- #define __DARWIN__ 1
- #endif
-
- #ifndef __DARWIN__
- #error inpossible
- #else
-
- mcontext_t mc = NULL;
- int x = mc->__fs.__fpu_mxcsr;
-
- #endif
- ],darwin_mcontext_leopard=yes,
- darwin_mcontext_leopard=no)
- if test X"$darwin_mcontext_leopard" = X"yes"; then
- AC_DEFINE(DARWIN_MODERN_MCONTEXT,[],[Modern style mcontext_t in MacOSX])
- AC_MSG_RESULT(yes)
- else
- AC_MSG_RESULT(no)
- fi
- ;;
- *)
- darwin_mcontext_leopard=no
- ;;
-esac
@@ -2826,9 +2960,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()
@@ -2848,28 +2985,49 @@ main()
exit(0);
#endif
}
-], poll_works=true, poll_works=false, poll_works=false)
+],
+poll_works=yes,
+poll_works=no,
+[
+case X$erl_xcomp_poll in
+ X) poll_works=cross;;
+ Xyes|Xno) poll_works=$erl_xcomp_poll;;
+ *) AC_MSG_ERROR([Bad erl_xcomp_poll value: $erl_xcomp_poll]);;
+esac
+])
+
fi
-case $poll_works in
-true)
- AC_DEFINE(ERTS_USE_POLL, 1, [Define if poll() should be used instead of select()])
- AC_MSG_RESULT(ok)
- ;;
-*)
+
+case $poll_works-$host_os in
+ no-*|cross-darwin*)
#
# The USE_SELECT define is used by the ssl application (should not
# be used by erts).
#
AC_DEFINE(USE_SELECT, 1, [Define if select() should be used instead of poll()])
- AC_MSG_RESULT(broken or based on select())
- ;;
+ if test $poll_works = cross; then
+ AC_MSG_RESULT(cross)
+ AC_MSG_WARN([result no guessed based on OS ($host_os) because of cross compilation])
+ else
+ AC_MSG_RESULT([no; non-existing, broken, or based on select()])
+ fi
+ poll_works=no;;
+ yes-*|cross-*)
+ AC_DEFINE(ERTS_USE_POLL, 1, [Define if poll() should be used instead of select()])
+ if test $poll_works = cross; then
+ AC_MSG_RESULT(cross)
+ AC_MSG_WARN([result yes guessed based on OS ($host_os) because of cross compilation])
+ else
+ AC_MSG_RESULT(yes)
+ fi
+ poll_works=yes;;
esac
#
# If kqueue() found, check that it can be selected or polled on...
#
if test $have_kernel_poll = kqueue; then
- if test $poll_works = true; then
+ if test $poll_works = yes; then
kqueue_with=poll
else
kqueue_with=select
@@ -2900,13 +3058,26 @@ int main(void) {
}
return 0;
}
- ], ok_kqueue=true, ok_kqueue=false, ok_kqueue=false)
- if test $ok_kqueue = true; then
- AC_MSG_RESULT(yes);
- else
- AC_MSG_RESULT(no);
+ ],
+ ok_kqueue=yes,
+ ok_kqueue=no,
+ [
+ case X$erl_xcomp_kqueue in
+ X) ok_kqueue=cross;;
+ Xyes|Xno) ok_kqueue=$erl_xcomp_kqueue;;
+ *) AC_MSG_ERROR([Bad erl_xcomp_kqueue value: $erl_xcomp_kqueue]);;
+ esac
+ ])
+ AC_MSG_RESULT($ok_kqueue);
+ case $ok_kqueue in
+ yes)
+ ;;
+ cross)
have_kernel_poll=no
- fi
+ AC_MSG_WARN([result no guessed because of cross compilation]);;
+ *)
+ have_kernel_poll=no;;
+ esac
fi
#
@@ -2990,11 +3161,26 @@ int main(void) {
return 5;
return 0;
}
-], copying_putenv=yes, copying_putenv=no, copying_putenv=no)
-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
+],
+copying_putenv=yes,
+copying_putenv=no,
+[
+case X$erl_xcomp_putenv_copy in
+ X) copying_putenv=cross;;
+ Xyes|Xno) copying_putenv=$erl_xcomp_putenv_copy;;
+ *) AC_MSG_ERROR([Bad erl_xcomp_putenv_copy value: $erl_xcomp_putenv_copy]);;
+esac
+])
+
AC_MSG_RESULT($copying_putenv)
+case $copying_putenv in
+ yes)
+ AC_DEFINE(HAVE_COPYING_PUTENV,[1],\
+[Define if you have a putenv() that stores a copy of the key-value pair]);;
+ cross)
+ AC_MSG_WARN([result no guessed because of cross compilation]);;
+ *) ;;
+esac
dnl ----------------------------------------------------------------------
dnl Stuff that should be moved into their respective application
@@ -3022,29 +3208,39 @@ dnl crypto
#
#--------------------------------------------------------------------
-DED_INCLUDE="-I${ERL_TOP}/erts/emulator/beam -I${ERL_TOP}/erts/include -I${ERL_TOP}/erts/include/$host"
+DED_SYS_INCLUDE="-I${ERL_TOP}/erts/emulator/beam -I${ERL_TOP}/erts/include -I${ERL_TOP}/erts/include/$host -I${ERL_TOP}/erts/include/internal -I${ERL_TOP}/erts/include/internal/$host -I${ERL_TOP}/erts/emulator/sys/$ERLANG_OSTYPE"
-DED_CFLAGS="$DED_INCLUDE $CFLAGS $CPPFLAGS $EMU_THR_DEFS"
+if test "X$ETHR_DEFS" = "X"; then
+ DED_THR_DEFS="-D_THREAD_SAFE -D_REENTRANT"
+else
+ DED_THR_DEFS="$ETHR_DEFS"
+fi
+DED_EMU_THR_DEFS=$EMU_THR_DEFS
+DED_CFLAGS="$CFLAGS $CPPFLAGS"
if test "x$GCC" = xyes; then
DED_CFLAGS="$DED_CFLAGS -fPIC"
fi
-STATIC_CFLAGS=""
+DED_EXT=so
+case $host_os in
+ win32) DED_EXT=dll;;
+ darwin*)
+ DED_CFLAGS="$DED_CFLAGS -fno-common"
+ if test "X$STATIC_CFLAGS" = "X"; then
+ STATIC_CFLAGS="-mdynamic-no-pic"
+ fi;;
+ *)
+ ;;
+esac
-# If DED_LD is set in environment, we expect all DED variables to be specified
-# (cross compiling)
+# If DED_LD is set in environment, we expect all DED_LD* variables
+# to be specified (cross compiling)
if test "x$DED_LD" = "x"; then
-if test "x$LD" = "x"; then
- DED_LD=ld
-else
- DED_LD=$LD
-fi
DED_LD_FLAG_RUNTIME_LIBRARY_PATH="-R"
-
case $host_os in
win32)
- DED_LD=ld.sh
+ DED_LD="ld.sh"
DED_LDFLAGS="-dll"
DED_LD_FLAG_RUNTIME_LIBRARY_PATH=
;;
@@ -3078,24 +3274,29 @@ case $host_os in
if test X${enable_darwin_universal} = Xyes; then
DED_LDFLAGS="-arch ppc -arch i386 $DED_LDFLAGS"
fi
- DED_CFLAGS="$DED_CFLAGS -fno-common"
DED_LD="$CC"
- DED_LD_FLAG_RUNTIME_LIBRARY_PATH=
- STATIC_CFLAGS="-mdynamic-no-pic"
+ DED_LD_FLAG_RUNTIME_LIBRARY_PATH="$CFLAG_RUNTIME_LIBRARY_PATH"
;;
linux*)
DED_LD="$CC"
+ DED_LD_FLAG_RUNTIME_LIBRARY_PATH="$CFLAG_RUNTIME_LIBRARY_PATH"
DED_LDFLAGS="-shared -Wl,-Bsymbolic"
- DED_LD_FLAG_RUNTIME_LIBRARY_PATH=
if test X${enable_m64_build} = Xyes; then
DED_LDFLAGS="-m64 $DED_LDFLAGS"
+ fi;
+ if test X${enable_m32_build} = Xyes; then
+ DED_LDFLAGS="-m32 $DED_LDFLAGS"
fi
;;
freebsd*)
DED_LD="$CC"
+ DED_LD_FLAG_RUNTIME_LIBRARY_PATH="$CFLAG_RUNTIME_LIBRARY_PATH"
DED_LDFLAGS="-shared"
if test X${enable_m64_build} = Xyes; then
DED_LDFLAGS="-m64 $DED_LDFLAGS"
+ fi;
+ if test X${enable_m32_build} = Xyes; then
+ DED_LDFLAGS="-m32 $DED_LDFLAGS"
fi
;;
osf*)
@@ -3110,8 +3311,16 @@ case $host_os in
;;
esac
+if test "$DED_LD" = "" && test "$USER_LD" != ""; then
+ DED_LD="$USER_LD"
+ DED_LDFLAGS="$USER_LDFLAGS $DED_LDFLAGS"
fi
+fi # "x$DED_LD" = "x"
+
+AC_CHECK_TOOL(DED_LD, ld, false)
+test "$DED_LD" != "false" || AC_MSG_ERROR([No linker found])
+
AC_MSG_CHECKING(for compiler flags for loadable drivers)
AC_MSG_RESULT([$DED_CFLAGS])
AC_MSG_CHECKING(for linker for loadable drivers)
@@ -3125,10 +3334,14 @@ else
AC_MSG_RESULT([not found])
fi
+AC_SUBST(DED_EXT)
+AC_SUBST(DED_SYS_INCLUDE)
AC_SUBST(DED_CFLAGS)
AC_SUBST(DED_LD)
AC_SUBST(DED_LDFLAGS)
AC_SUBST(DED_LD_FLAG_RUNTIME_LIBRARY_PATH)
+AC_SUBST(DED_THR_DEFS)
+AC_SUBST(DED_EMU_THR_DEFS)
AC_SUBST(STATIC_CFLAGS)
dnl
@@ -3151,6 +3364,9 @@ dnl use "PATH/include" and "PATH/lib".
AC_SUBST(SSL_INCLUDE)
AC_SUBST(SSL_ROOT)
AC_SUBST(SSL_LIBDIR)
+AC_SUBST(SSL_CC_RUNTIME_LIBRARY_PATH)
+AC_SUBST(SSL_LD_RUNTIME_LIBRARY_PATH)
+AC_SUBST(SSL_DED_LD_RUNTIME_LIBRARY_PATH)
AC_SUBST(SSL_DYNAMIC_ONLY)
AC_SUBST(SSL_LINK_WITH_KERBEROS)
AC_SUBST(STATIC_KERBEROS_LIBS)
@@ -3158,6 +3374,8 @@ AC_SUBST(SSL_LINK_WITH_ZLIB)
AC_SUBST(STATIC_ZLIB_LIBS)
AC_SUBST(OPENSSL_CMD)
+std_ssl_locations="/usr/local /usr/sfw /opt/local /usr /usr/pkg /usr/local/openssl /usr/lib/openssl /usr/openssl /usr/local/ssl /usr/lib/ssl /usr/ssl"
+
AC_ARG_WITH(ssl-zlib,
[ --with-ssl-zlib=PATH specify location of ZLib to be used by OpenSSL
--with-ssl-zlib link SSL with Zlib (default if found)
@@ -3167,18 +3385,20 @@ AC_ARG_WITH(ssl-zlib,
if test "x$with_ssl_zlib" = "xno"; then
SSL_LINK_WITH_ZLIB=no
STATIC_ZLIB_LIBS=
-elif test "x$with_ssl_zlib" = "xyes" -o "x$with_ssl_zlib" = "x" ;then
- if test "x$MIXED_CYGWIN" = "xyes"; then
+elif test "x$with_ssl_zlib" = "xyes" || test "x$with_ssl_zlib" = "x"; then
+ if test $erl_xcomp_without_sysroot = yes; then
+ AC_MSG_WARN([Cannot search for zlib; missing cross system root (erl_xcomp_sysroot).])
+ SSL_LINK_WITH_ZLIB=no
+ STATIC_ZLIB_LIBS=
+ elif test "x$MIXED_CYGWIN" = "xyes"; then
SSL_LINK_WITH_ZLIB=no
STATIC_ZLIB_LIBS=
else
SSL_LINK_WITH_ZLIB=no
STATIC_ZLIB_LIBS=
AC_MSG_CHECKING(for static ZLib to be used by SSL in standard locations)
- for dir in /usr/local /usr/sfw /usr /usr/pkg \
- /usr/local/openssl /usr/lib/openssl /usr/openssl \
- /usr/local/ssl /usr/lib/ssl /usr/ssl
- do
+ for rdir in $std_ssl_locations; do
+ dir="$erl_xcomp_sysroot$rdir"
if test "x$ac_cv_sizeof_void_p" = "x8"; then
if test -f "$dir/lib64/libz.a"; then
SSL_LINK_WITH_ZLIB=yes
@@ -3259,14 +3479,21 @@ done
SSL_DYNAMIC_ONLY=$enable_dynamic_ssl
-if test "x$with_ssl" = "xno"; then
+case "$erl_xcomp_without_sysroot-$with_ssl" in
+ yes-* | no-no)
SSL_APP=
CRYPTO_APP=
SSH_APP=
+ if test "$with_ssl" = "no"; then
+ skip="User gave --without-ssl option"
+ else
+ skip="Cannot search for ssl; missing cross system root (erl_xcomp_sysroot)."
+ fi
for a in ssl crypto ssh; do
- echo "User gave --without-ssl option" > $ERL_TOP/lib/$a/SKIP
+ echo "$skip" > $ERL_TOP/lib/$a/SKIP
done
-elif test "x$with_ssl" = "xyes" -o "x$with_ssl" = "x" ;then
+ ;;
+ no-yes | no- )
# On windows, we could try to find the installation
# of Shining Light OpenSSL, which can be found by poking in
# the uninstall section in the registry, it's worth a try...
@@ -3293,20 +3520,19 @@ elif test "x$with_ssl" = "xyes" -o "x$with_ssl" = "x" ;then
SSH_APP=ssh
AC_MSG_CHECKING(for OpenSSL >= 0.9.7 in standard locations)
- for dir in $extra_dir /cygdrive/c/OpenSSL \
- /usr/local /usr/sfw /opt/local /usr /usr/pkg \
- /usr/local/openssl /usr/lib/openssl /usr/openssl \
- /usr/local/ssl /usr/lib/ssl /usr/ssl
- do
- if test -f $dir/include/openssl/opensslv.h; then
+ for rdir in $extra_dir /cygdrive/c/OpenSSL $std_ssl_locations; do
+ dir="$erl_xcomp_sysroot$rdir"
+ if test -f "$erl_xcomp_isysroot$rdir/include/openssl/opensslv.h"; then
is_real_ssl=yes
SSL_ROOT="$dir"
if test "x$MIXED_CYGWIN" = "xyes" ; then
- if test -f "$dir/lib/VC/ssleay32.lib" -o \
- -f "$dir/lib/VC/openssl.lib"; then
+ if test -f "$dir/lib/VC/ssleay32.lib" || \
+ test -f "$dir/lib/VC/openssl.lib"; then
+ SSL_RUNTIME_LIBDIR="$rdir/lib/VC"
SSL_LIBDIR="$dir/lib/VC"
- elif test -f "$dir/lib/ssleay32.lib" -o \
- -f "$dir/lib/openssl.lib"; then
+ elif test -f "$dir/lib/ssleay32.lib" || \
+ test -f "$dir/lib/openssl.lib"; then
+ SSL_RUNTIME_LIBDIR="$rdir/lib"
SSL_LIBDIR="$dir/lib"
else
is_real_ssl=no
@@ -3314,31 +3540,42 @@ elif test "x$with_ssl" = "xyes" -o "x$with_ssl" = "x" ;then
else
if test "x$ac_cv_sizeof_void_p" = "x8"; then
if test -f "$dir/lib64/libcrypto.a"; then
+ SSL_RUNTIME_LIBDIR="$rdir/lib64"
SSL_LIBDIR="$dir/lib64"
elif test -f "$dir/lib/64/libcrypto.a"; then
+ SSL_RUNTIME_LIBDIR="$rdir/lib/64"
SSL_LIBDIR="$dir/lib/64"
elif test -f "$dir/lib64/libcrypto.so"; then
+ SSL_RUNTIME_LIBDIR="$rdir/lib64"
SSL_LIBDIR="$dir/lib64"
elif test -f "$dir/lib/64/libcrypto.so"; then
+ SSL_RUNTIME_LIBDIR="$rdir/lib/64"
SSL_LIBDIR="$dir/lib/64"
else
+ SSL_RUNTIME_LIBDIR="$rdir/lib"
SSL_LIBDIR="$dir/lib"
fi
else
+ SSL_RUNTIME_LIBDIR="$rdir/lib"
SSL_LIBDIR="$dir/lib"
fi
fi
if test '!' -f $SSL_LIBDIR/libcrypto.a; then
SSL_DYNAMIC_ONLY=yes
fi
- SSL_BINDIR="$dir/bin"
+ SSL_BINDIR="$rdir/bin"
dnl Should one use EXEEXT or ac_exeext?
- if test -f "$SSL_BINDIR/openssl$EXEEXT"; then
+ if test -f "$erl_xcomp_sysroot$SSL_BINDIR/openssl$EXEEXT"; then
+ if test "$cross_compiling" = "yes"; then
+ dnl Cannot test it; hope it is working...
+ OPENSSL_CMD="$SSL_BINDIR/openssl"
+ else
if "$SSL_BINDIR/openssl" version > /dev/null 2>&1; then
OPENSSL_CMD="$SSL_BINDIR/openssl"
else
is_real_ssl=no
fi
+ fi
else
is_real_ssl=no
fi
@@ -3382,7 +3619,7 @@ dnl Should one use EXEEXT or ac_exeext?
LIBS="$saveLIBS"
fi
fi
- if test "x$ssl_found" = "xyes" -a "x$ssl_linkable" = "xyes" ; then
+ if test "x$ssl_found" = "xyes" && test "x$ssl_linkable" = "xyes"; then
AC_MSG_RESULT([$dir])
break;
fi
@@ -3396,13 +3633,14 @@ dnl Should one use EXEEXT or ac_exeext?
dnl
case $host_os in
openbsd*)
- if test -f /usr/include/openssl/opensslv.h; then
+ if test -f "$erl_xcomp_isysroot/usr/include/openssl/opensslv.h"; then
# Trust OpenBSD to have everything the in the correct locations.
ssl_found=yes
ssl_linkable=yes
- SSL_ROOT="/usr/sbin"
+ SSL_ROOT="$erl_xcomp_sysroot/usr"
AC_MSG_RESULT([$SSL_ROOT])
- SSL_LIB="/usr/lib"
+ SSL_RUNTIME_LIB="/usr/lib"
+ SSL_LIB="$erl_xcomp_sysroot/usr/lib"
SSL_BINDIR="/usr/sbin"
OPENSSL_CMD="$SSL_BINDIR/openssl"
dnl OpenBSD requires us to link with -L and -l
@@ -3415,7 +3653,7 @@ dnl Now, certain linuxes have a 64bit libcrypto
dnl that cannot build shared libraries (i.e. not PIC)
dnl One could argue that this is wrong, but
dnl so it is - be adoptable
- if test "x$ssl_found" = "xyes" -a "x$ssl_linkable" = "xyes" -a "x$SSL_DYNAMIC_ONLY" != "xyes" ; then
+ if test "$ssl_found" = "yes" && test "$ssl_linkable" = "yes" && test "$SSL_DYNAMIC_ONLY" != "yes"; then
case $host_os in
linux*)
saveCFLAGS="$CFLAGS"
@@ -3447,7 +3685,7 @@ dnl so it is - be adoptable
- if test "x$ssl_found" != "xyes" -o "x$ssl_linkable" != "xyes"; then
+ if test "x$ssl_found" != "xyes" || test "x$ssl_linkable" != "xyes"; then
if test "x$ssl_found" = "xyes"; then
AC_MSG_RESULT([found; but not usable])
else
@@ -3462,13 +3700,21 @@ dnl so it is - be adoptable
echo "No usable OpenSSL found" > $ERL_TOP/lib/$a/SKIP
done
fi
-else
+ ;;
+ *)
+ if test "$cross_compiling" = "yes"; then
+ case "$with_ssl" in
+ "$erl_xcomp_sysroot"*) ;;
+ *) AC_MSG_ERROR([Invalid path to option --with-ssl=PATH (not a subdirectory to cross system root)]);;
+ esac
+ fi
+
# Option given with PATH to package
if test ! -d "$with_ssl" ; then
AC_MSG_ERROR(Invalid path to option --with-ssl=PATH)
fi
SSL_ROOT="$with_ssl"
- if test "x$MIXED_CYGWIN" = "xyes" -a -d "$with_ssl/lib/VC"; then
+ if test "x$MIXED_CYGWIN" = "xyes" && test -d "$with_ssl/lib/VC"; then
SSL_LIBDIR="$with_ssl/lib/VC"
elif test "x$ac_cv_sizeof_void_p" = "x8"; then
if test -f "$with_ssl/lib64/libcrypto.a"; then
@@ -3493,7 +3739,12 @@ else
SSL_APP=ssl
CRYPTO_APP=crypto
SSH_APP=ssh
-fi
+ if test "$cross_compiling" = "yes"; then
+ SSL_RUNTIME_LIBDIR=`echo "$SSL_LIBDIR" | sed -n "s|^$erl_xcomp_sysroot\(.*\)\$|\1|p"`
+ else
+ SSL_RUNTIME_LIBDIR="$SSL_LIBDIR"
+ fi
+esac
if test "x$SSL_APP" != "x" ; then
dnl We found openssl, now check if we use kerberos 5 support
@@ -3509,19 +3760,19 @@ if test "x$SSL_APP" != "x" ; then
AC_MSG_RESULT([yes])
ssl_krb5_enabled=yes
if test "x$SSL_DYNAMIC_ONLY" != "xyes"; then
- if test -f $SSL_LIBDIR/libkrb5.a; then
+ if test -f "$SSL_LIBDIR/libkrb5.a"; then
SSL_LINK_WITH_KERBEROS=yes
STATIC_KERBEROS_LIBS="$SSL_LIBDIR/libkrb5.a"
- if test -f $SSL_LIBDIR/libkrb5support.a; then
+ if test -f "$SSL_LIBDIR/libkrb5support.a"; then
STATIC_KERBEROS_LIBS="$STATIC_KERBEROS_LIBS $SSL_LIBDIR/libkrb5support.a"
fi
- if test -f $SSL_LIBDIR/libk5crypto.a; then
+ if test -f "$SSL_LIBDIR/libk5crypto.a"; then
STATIC_KERBEROS_LIBS="$STATIC_KERBEROS_LIBS $SSL_LIBDIR/libk5crypto.a"
fi
- if test -f $SSL_LIBDIR/libresolv.a; then
+ if test -f "$SSL_LIBDIR/libresolv.a"; then
STATIC_KERBEROS_LIBS="$STATIC_KERBEROS_LIBS $SSL_LIBDIR/libresolv.a"
fi
- if test -f $SSL_LIBDIR/libcom_err.a; then
+ if test -f "$SSL_LIBDIR/libcom_err.a"; then
STATIC_KERBEROS_LIBS="$STATIC_KERBEROS_LIBS $SSL_LIBDIR/libcom_err.a"
fi
else
@@ -3547,10 +3798,12 @@ if test "x$SSL_APP" != "x" ; then
SSL_KRB5_INCLUDE=
if test "x$ssl_krb5_enabled" = "xyes" ; then
AC_MSG_CHECKING(for krb5.h in standard locations)
- for dir in $extra_dir $SSL_ROOT/include $SSL_ROOT/include/openssl \
- $SSL_ROOT/include/kerberos /cygdrive/c/kerberos/include \
- /usr/local/kerberos/include /usr/kerberos/include \
- /usr/include
+ for dir in $extra_dir "$SSL_ROOT/include" "$SSL_ROOT/include/openssl" \
+ "$SSL_ROOT/include/kerberos" \
+ "$erl_xcomp_isysroot/cygdrive/c/kerberos/include" \
+ "$erl_xcomp_isysroot/usr/local/kerberos/include" \
+ "$erl_xcomp_isysroot/usr/kerberos/include" \
+ "$erl_xcomp_isysroot/usr/include"
do
if test -f "$dir/krb5.h" ; then
SSL_KRB5_INCLUDE="$dir"
@@ -3575,6 +3828,99 @@ fi
done # while test ssl_done != yes
+SSL_CC_RUNTIME_LIBRARY_PATH=
+SSL_LD_RUNTIME_LIBRARY_PATH=
+SSL_DED_LD_RUNTIME_LIBRARY_PATH=
+cc_rflg="$CFLAG_RUNTIME_LIBRARY_PATH"
+ld_rflg="$LDFLAG_RUNTIME_LIBRARY_PATH"
+ded_ld_rflg="$DED_LD_FLAG_RUNTIME_LIBRARY_PATH"
+
+if test "$SSL_APP" != "" && test "$SSL_DYNAMIC_ONLY" = "yes" && \
+ { test "$cc_rflg" != "" || test "$ld_rflg" != "" || test "$ded_ld_rflg" != ""; } ; then
+
+ AC_MSG_CHECKING(for ssl runtime library path to use)
+
+ libdirs="/lib"
+
+ if test "$ac_cv_sizeof_void_p" = "8"; then
+ dir_lib64=no
+ dir_lib_64=no
+
+ case "$SSL_RUNTIME_LIBDIR" in
+ */lib/64 | */lib/64/ ) dir_lib_64=yes;;
+ */lib64 | */lib64/ ) dir_lib64=yes;;
+ *) ;;
+ esac
+
+ for dir in $std_ssl_locations; do
+ test $dir_lib_64 = no &&
+ test -d "$erl_xcomp_sysroot$dir/lib/64" &&
+ dir_lib_64=yes
+ test $dir_lib64 = no &&
+ test -d "$erl_xcomp_sysroot$dir/lib64" &&
+ dir_lib64=yes
+ done
+
+ test $dir_lib_64 = yes && libdirs="/lib/64 $libdirs"
+ test $dir_lib64 = yes && libdirs="/lib64 $libdirs"
+ fi
+
+ for type in std x_std curr; do
+
+ cc_rpath="$cc_rflg$SSL_RUNTIME_LIBDIR"
+ ld_rpath="$ld_rflg$SSL_RUNTIME_LIBDIR"
+ ded_ld_rpath="$ded_ld_rflg$SSL_RUNTIME_LIBDIR"
+ rpath="$SSL_RUNTIME_LIBDIR"
+
+ if test $type != curr; then
+ for ldir in $libdirs; do
+ for dir in $std_ssl_locations; do
+ test "$SSL_LIBDIR" != "$dir$ldir" || continue
+ test $type != x_std || test -d "$dir$ldir" || continue
+ test "$cc_rflg" = "" ||
+ cc_rpath="$cc_rpath $cc_rflg$dir$ldir"
+ test "$ld_rflg" = "" ||
+ ld_rpath="$ld_rpath $ld_rflg$dir$ldir"
+ test "$ded_ld_rflg" = "" ||
+ ded_ld_rpath="$ded_ld_rpath $ded_ld_rflg$dir$ldir"
+ rpath="$rpath:$dir$ldir"
+ done
+ done
+ fi
+
+ saveCFLAGS="$CFLAGS"
+ saveLDFLAGS="$LDFLAGS"
+ saveLIBS="$LIBS"
+ CFLAGS="$CFLAGS $SSL_INCLUDE"
+ LDFLAGS="$LDFLAGS $ld_rpath -L$SSL_LIBDIR"
+ LIBS="-lcrypto"
+ AC_TRY_LINK([
+ #include <stdio.h>
+ #include <openssl/hmac.h>
+ ],
+ [
+ HMAC_CTX hc;
+ HMAC_CTX_init(&hc);
+ ],
+ [rpath_success=yes],
+ [rpath_success=no])
+ CFLAGS="$saveCFLAGS"
+ LDFLAGS="$saveLDFLAGS"
+ LIBS="$saveLIBS"
+
+ test "$rpath_success" = "yes" && break
+ done
+
+ test "$rpath_success" = "yes" || { cc_rpath=; ld_rpath=; ded_ld_rpath=; rpath=; }
+
+ SSL_CC_RUNTIME_LIBRARY_PATH="$cc_rpath"
+ SSL_LD_RUNTIME_LIBRARY_PATH="$ld_rpath"
+ SSL_DED_LD_RUNTIME_LIBRARY_PATH="$ded_ld_rpath"
+
+ AC_MSG_RESULT([$rpath])
+ test "$rpath" != "" || AC_MSG_WARN([Cannot set run path during linking])
+fi
+
#--------------------------------------------------------------------
# Os mon stuff.
#--------------------------------------------------------------------
@@ -3593,6 +3939,11 @@ case $host_os in
os_mon_programs="$os_mon_programs cpu_sup" ;;
esac
+
+AC_ARG_WITH(javac,
+[ --with-javac=JAVAC specify Java compiler to use
+ --with-javac use a Java compiler if found (default)
+ --without-javac don't use any Java compiler])
dnl
dnl Then there are a number of apps which needs a java compiler...
@@ -3604,7 +3955,20 @@ for a in $need_java ; do
/bin/rm -f $ERL_TOP/lib/$a/SKIP
done
-AC_CHECK_PROGS(JAVAC, javac.sh javac guavac gcj jikes bock)
+if test "X$with_javac" = "Xno"; then
+ for a in $need_java ; do
+ echo "Java compiler disabled by user" > $ERL_TOP/lib/$a/SKIP
+ done
+
+else # begin - try to find javac
+
+if test "X$with_javac" != "Xyes" -a "X$with_javac" != "X"; then
+ check_javac=$with_javac
+else
+ check_javac="javac.sh javac guavac gcj jikes bock"
+fi
+
+AC_CHECK_PROGS(JAVAC, $check_javac)
if test -n "$JAVAC"; then
dnl Make sure it's at least JDK 1.5
AC_CACHE_CHECK(for JDK version 1.5,
@@ -3616,6 +3980,11 @@ if test -n "$JAVAC"; then
fi
fi
if test -z "$JAVAC"; then
+
+ if test "X$with_javac" != "X"; then
+ AC_MSG_ERROR([No java compiler found in PATH (checked for $check_javac)])
+ fi
+
AC_MSG_WARN([Could not find any usable java compiler, will skip: jinterface])
for a in $need_java ; do
@@ -3623,14 +3992,15 @@ if test -z "$JAVAC"; then
done
fi
+fi # end - try to find javac
+
dnl
dnl Orber has a c++ example, this isn't the right way to check for
dnl it, but....
dnl
-CXXFLAGS=
AC_SUBST(CXXFLAGS)
dnl this deliberately does not believe that 'gcc' is a C++ compiler
-AC_CHECK_PROGS(CXX, $CCC c++ g++ CC cxx cc++ cl, false)
+AC_CHECK_TOOLS(CXX, [$CCC c++ g++ CC cxx cc++ cl], false)
# Remove SKIP file from previous run
/bin/rm -f $ERL_TOP/lib/orber/SKIP
@@ -3767,6 +4137,5 @@ dnl
../lib/orber/c_src/$host/Makefile:../lib/orber/c_src/Makefile.in
../lib/runtime_tools/c_src/$host/Makefile:../lib/runtime_tools/c_src/Makefile.in
../lib/tools/c_src/$host/Makefile:../lib/tools/c_src/Makefile.in
- ../lib/asn1/c_src/$host/Makefile:../lib/asn1/c_src/Makefile.in
)
diff --git a/erts/doc/src/alt_dist.xml b/erts/doc/src/alt_dist.xml
index 9a68b3cf40..a929aec97f 100644
--- a/erts/doc/src/alt_dist.xml
+++ b/erts/doc/src/alt_dist.xml
@@ -4,7 +4,7 @@
<chapter>
<header>
<copyright>
- <year>2000</year><year>2009</year>
+ <year>2000</year><year>2010</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
@@ -13,12 +13,12 @@
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>How to implement an alternative carrier for the Erlang distribution</title>
@@ -939,7 +939,7 @@
connection that is not functioning.</item>
<item>'R': Get creation number of listen socket, which is used to
dig out the number stored in the lock file to differentiate
- between invocations of Erlang nodes with the same name.\011 </item>
+ between invocations of Erlang nodes with the same name.</item>
</list>
<p>The control interface gets a buffer to return its value in,
but is free to allocate it's own buffer is the provided one is
@@ -949,11 +949,11 @@
( 2) char* buf, int count, char** res, int res_size)
( 3) {
( 4) /* Local macro to ensure large enough buffer. */
-( 5) #define ENSURE(N) \\
-( 6) do { \\
-( 7) if (res_size < N) { \\
-( 8) *res = ALLOC(N); \\
-( 9) } \\
+( 5) #define ENSURE(N) \
+( 6) do { \
+( 7) if (res_size < N) { \
+( 8) *res = ALLOC(N); \
+( 9) } \
(10) } while(0)
(11) UdsData *ud = (UdsData *) handle;
@@ -1075,7 +1075,7 @@ Eshell V5.0 (abort with ^G)
(bing@hador)2></pre>
<p>...</p>
<pre>
-$ <input>erl -pa $ERL_TOP/lib/kernel/examples/uds_dist/ebin -proto_dist uds \\ </input>
+$ <input>erl -pa $ERL_TOP/lib/kernel/examples/uds_dist/ebin -proto_dist uds \ </input>
<input> -no_epmd -sname bong</input>
Erlang (BEAM) emulator version 5.0
@@ -1084,7 +1084,7 @@ Eshell V5.0 (abort with ^G)
<p>One can utilize the ERL_FLAGS environment variable to store the
complicated parameters in:</p>
<pre>
-$ <input>ERL_FLAGS=-pa $ERL_TOP/lib/kernel/examples/uds_dist/ebin \\ </input>
+$ <input>ERL_FLAGS=-pa $ERL_TOP/lib/kernel/examples/uds_dist/ebin \ </input>
<input> -proto_dist uds -no_epmd</input>
$ <input>export ERL_FLAGS</input>
$ <input>erl -sname bang</input>
diff --git a/erts/doc/src/crash_dump.xml b/erts/doc/src/crash_dump.xml
index 5182929358..b3c4671c3d 100644
--- a/erts/doc/src/crash_dump.xml
+++ b/erts/doc/src/crash_dump.xml
@@ -4,7 +4,7 @@
<chapter>
<header>
<copyright>
- <year>1999</year><year>2009</year>
+ <year>1999</year><year>2010</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
@@ -13,12 +13,12 @@
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>How to interpret the Erlang crash dumps</title>
@@ -96,7 +96,7 @@
allocators see
<seealso marker="erts_alloc">erts_alloc(3)</seealso>.</item>
<item>"<em>&lt;A&gt;</em>: Cannot reallocate <em>&lt;N&gt;</em>
- bytes of memory\011(of type "<em>&lt;T&gt;</em>")." - Same as
+ bytes of memory (of type "<em>&lt;T&gt;</em>")." - Same as
above with the exception that memory was being reallocated
instead of being allocated when the system ran out of memory.</item>
<item>"Unexpected op code <em>N</em>" - Error in compiled
diff --git a/erts/doc/src/driver.xml b/erts/doc/src/driver.xml
index c396ee0b90..12c79aee90 100644
--- a/erts/doc/src/driver.xml
+++ b/erts/doc/src/driver.xml
@@ -4,7 +4,7 @@
<chapter>
<header>
<copyright>
- <year>2001</year><year>2009</year>
+ <year>2001</year><year>2010</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
@@ -13,12 +13,12 @@
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>How to implement a driver</title>
@@ -510,11 +510,11 @@ static int do_select(const char* s, our_data_t* data)
PGconn* conn = data->conn;
/* if there's an error return it now */
if (PQsendQuery(conn, s) == 0) {
-\011ei_x_buff x;
-\011ei_x_new_with_version(&x);
-\011encode_error(&x, conn);
-\011driver_output(data->port, x.buff, x.index);
-\011ei_x_free(&x);
+ ei_x_buff x;
+ ei_x_new_with_version(&x);
+ encode_error(&x, conn);
+ driver_output(data->port, x.buff, x.index);
+ ei_x_free(&x);
}
/* else wait for ready_output to get results */
return 0;
@@ -532,31 +532,31 @@ static void ready_io(ErlDrvData drv_data, ErlDrvEvent event)
ei_x_buff x;
ei_x_new_with_version(&x);
if (data->connecting) {
-\011ConnStatusType status;
-\011PQconnectPoll(conn);
-\011status = PQstatus(conn);
-\011if (status == CONNECTION_OK)
-\011 encode_ok(&x);
-\011else if (status == CONNECTION_BAD)
-\011 encode_error(&x, conn);
+ ConnStatusType status;
+ PQconnectPoll(conn);
+ status = PQstatus(conn);
+ if (status == CONNECTION_OK)
+ encode_ok(&x);
+ else if (status == CONNECTION_BAD)
+ encode_error(&x, conn);
} else {
-\011PQconsumeInput(conn);
-\011if (PQisBusy(conn))
-\011 return;
-\011res = PQgetResult(conn);
-\011encode_result(&x, res, conn);
-\011PQclear(res);
-\011for (;;) {
-\011 res = PQgetResult(conn);
-\011 if (res == NULL)
-\011\011break;
-\011 PQclear(res);
-\011}
+ PQconsumeInput(conn);
+ if (PQisBusy(conn))
+ return;
+ res = PQgetResult(conn);
+ encode_result(&x, res, conn);
+ PQclear(res);
+ for (;;) {
+ res = PQgetResult(conn);
+ if (res == NULL)
+ break;
+ PQclear(res);
+ }
}
if (x.index > 1) {
-\011driver_output(data->port, x.buff, x.index);
-\011if (data->connecting)
-\011 driver_select(data->port, (ErlDrvEvent)data->socket, DO_WRITE, 0);
+ driver_output(data->port, x.buff, x.index);
+ if (data->connecting)
+ driver_select(data->port, (ErlDrvEvent)data->socket, DO_WRITE, 0);
}
ei_x_free(&x);
}
@@ -592,17 +592,17 @@ static void ready_io(ErlDrvData drv_data, ErlDrvEvent event)
connect(ConnectStr) ->
case erl_ddll:load_driver(".", "pg_async") of
-\011ok -> ok;
-\011{error, already_loaded} -> ok;
-\011_ -> exit({error, could_not_load_driver})
+ ok -> ok;
+ {error, already_loaded} -> ok;
+ _ -> exit({error, could_not_load_driver})
end,
Port = open_port({spawn, ?MODULE}, [binary]),
port_control(Port, ?DRV_CONNECT, ConnectStr),
case return_port_data(Port) of
-\011ok ->
-\011 {ok, Port};
-\011Error ->
-\011 Error
+ ok ->
+ {ok, Port};
+ Error ->
+ Error
end.
disconnect(Port) ->
@@ -617,8 +617,8 @@ select(Port, Query) ->
return_port_data(Port) ->
receive
-\011{Port, {data, Data}} ->
-\011 binary_to_term(Data)
+ {Port, {data, Data}} ->
+ binary_to_term(Data)
end.
]]></code>
<p>The Erlang code is slightly different, this is because we
@@ -662,22 +662,22 @@ return_port_data(Port) ->
call-back <c><![CDATA[ready_async]]></c>.</p>
<code type="none"><![CDATA[
static ErlDrvEntry next_perm_driver_entry = {
- NULL,\011\011\011/* init */
+ NULL, /* init */
start,
- NULL, \011\011\011/* stop */
- output,\011\011\011
- NULL,\011\011\011/* ready_input */
- NULL,\011\011\011/* ready_output */
- "next_perm", /* the name of the driver */
- NULL,\011\011\011/* finish */
- NULL,\011\011\011/* handle */
- NULL,\011\011\011/* control */
- NULL,\011\011\011/* timeout */
- NULL,\011\011\011/* outputv */
+ NULL, /* stop */
+ output,
+ NULL, /* ready_input */
+ NULL, /* ready_output */
+ "next_perm", /* the name of the driver */
+ NULL, /* finish */
+ NULL, /* handle */
+ NULL, /* control */
+ NULL, /* timeout */
+ NULL, /* outputv */
ready_async,
- NULL,\011\011\011/* flush */
- NULL,\011\011\011/* call */
- NULL\011\011\011/* event */
+ NULL, /* flush */
+ NULL, /* call */
+ NULL /* event */
};
]]></code>
<p>The <c><![CDATA[output]]></c> function allocates the work-area of the
@@ -699,7 +699,7 @@ struct our_async_data {
};
our_async_data::our_async_data(ErlDrvPort p, int command,
-\011\011\011 const char* buf, int len)
+ const char* buf, int len)
: prev(command == 2),
data((int*)buf, (int*)buf + len / sizeof(int))
{
@@ -722,9 +722,9 @@ static void do_perm(void* async_data)
{
our_async_data* d = reinterpret_cast<our_async_data*>(async_data);
if (d->prev)
-\011prev_permutation(d->data.begin(), d->data.end());
+ prev_permutation(d->data.begin(), d->data.end());
else
-\011next_permutation(d->data.begin(), d->data.end());
+ next_permutation(d->data.begin(), d->data.end());
}
]]></code>
<p>In the <c><![CDATA[ready_async]]></c> function, the output is sent back to the
@@ -742,9 +742,9 @@ static void ready_async(ErlDrvData drv_data, ErlDrvThreadData async_data)
int n = d->data.size(), result_n = n*2 + 3;
ErlDrvTermData* result = new ErlDrvTermData[result_n], * rp = result;
for (vector<int>::iterator i = d->data.begin();
-\011 i != d->data.end(); ++i) {
-\011*rp++ = ERL_DRV_INT;
-\011*rp++ = *i;
+ i != d->data.end(); ++i) {
+ *rp++ = ERL_DRV_INT;
+ *rp++ = *i;
}
*rp++ = ERL_DRV_NIL;
*rp++ = ERL_DRV_LIST;
@@ -767,16 +767,16 @@ static void ready_async(ErlDrvData drv_data, ErlDrvThreadData async_data)
load() ->
case whereis(next_perm) of
-\011undefined ->
-\011 case erl_ddll:load_driver(".", "next_perm") of
-\011\011ok -> ok;
-\011\011{error, already_loaded} -> ok;
-\011\011E -> exit(E)
-\011 end,
-\011 Port = open_port({spawn, "next_perm"}, []),
-\011 register(next_perm, Port);
-\011_ ->
-\011 ok
+ undefined ->
+ case erl_ddll:load_driver(".", "next_perm") of
+ ok -> ok;
+ {error, already_loaded} -> ok;
+ E -> exit(E)
+ end,
+ Port = open_port({spawn, "next_perm"}, []),
+ register(next_perm, Port);
+ _ ->
+ ok
end.
list_to_integer_binaries(L) ->
@@ -793,8 +793,8 @@ next_perm(L, Nxt) ->
B = list_to_integer_binaries(L),
port_control(next_perm, Nxt, B),
receive
-\011Result ->
-\011 Result
+ Result ->
+ Result
end.
all_perm(L) ->
diff --git a/erts/doc/src/driver_entry.xml b/erts/doc/src/driver_entry.xml
index 6b7d2acf24..e71b48bd92 100644
--- a/erts/doc/src/driver_entry.xml
+++ b/erts/doc/src/driver_entry.xml
@@ -4,7 +4,7 @@
<cref>
<header>
<copyright>
- <year>2001</year><year>2009</year>
+ <year>2001</year><year>2010</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
@@ -13,12 +13,12 @@
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>driver_entry</title>
@@ -188,7 +188,7 @@ typedef struct erl_drv_entry {
<p>This is called when the port is closed, with
<c>port_close/1</c> or <c>Port ! {self(), close}</c>. Note
that terminating the port owner process also closes the
- p\011 port.</p>
+ port.</p>
</item>
<tag><marker id="output"/>void (*output)(ErlDrvData drv_data, char *buf, int len)</tag>
<item>
diff --git a/erts/doc/src/erl.xml b/erts/doc/src/erl.xml
index 90a3c53a37..bb741c7836 100644
--- a/erts/doc/src/erl.xml
+++ b/erts/doc/src/erl.xml
@@ -4,7 +4,7 @@
<comref>
<header>
<copyright>
- <year>1996</year><year>2009</year>
+ <year>1996</year><year>2010</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
@@ -13,12 +13,12 @@
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>erl</title>
@@ -131,9 +131,8 @@
see <seealso marker="kernel:app">app(4)</seealso> and
<seealso marker="kernel:application">application(3)</seealso>.</p>
</item>
- <tag><c><![CDATA[-args_file FileName]]></c></tag>
+ <tag><marker id="args_file"><c><![CDATA[-args_file FileName]]></c></marker></tag>
<item>
- <marker id="args_file"></marker>
<p>Command line arguments are read from the file <c><![CDATA[FileName]]></c>.
The arguments read from the file replace the
'<c><![CDATA[-args_file FileName]]></c>' flag on the resulting command line.</p>
@@ -197,9 +196,8 @@
<seealso marker="kernel:app">app(4)</seealso> and
<seealso marker="kernel:application">application(3)</seealso>.</p>
</item>
- <tag><c><![CDATA[-connect_all false]]></c></tag>
+ <tag><marker id="connect_all"><c><![CDATA[-connect_all false]]></c></marker></tag>
<item>
- <marker id="connect_all"></marker>
<p>If this flag is present, <c><![CDATA[global]]></c> will not maintain a
fully connected network of distributed Erlang nodes, and then
global name registration cannot be used. See
@@ -252,7 +250,7 @@
run as a distributed node. Hidden nodes always establish
hidden connections to all other nodes except for nodes in the
same global group. Hidden connections are not published on
- neither of the connected nodes, i.e. neither of the connected
+ either of the connected nodes, i.e. neither of the connected
nodes are part of the result from <c><![CDATA[nodes/0]]></c> on the other
node. See also hidden global groups,
<seealso marker="kernel:global_group">global_group(3)</seealso>.</p>
@@ -282,9 +280,8 @@
<p>Makes <c><![CDATA[init]]></c> write some debug information while
interpreting the boot script.</p>
</item>
- <tag><c><![CDATA[-instr]]></c>(emulator flag)</tag>
+ <tag><marker id="instr"><c><![CDATA[-instr]]></c>(emulator flag)</marker></tag>
<item>
- <marker id="instr"></marker>
<p>Selects an instrumented Erlang runtime system (virtual
machine) to run, instead of the ordinary one. When running an
instrumented runtime system, some resource usage data can be
@@ -410,7 +407,7 @@
<tag><c><![CDATA[-setcookie Cookie]]></c></tag>
<item>
<p>Sets the magic cookie of the node to <c><![CDATA[Cookie]]></c>, see
- <seealso marker="erlang#erlang:set_cookie/2">erlang:set_cookie/2</seealso>.</p>
+ <seealso marker="erlang#set_cookie/2">erlang:set_cookie/2</seealso>.</p>
</item>
<tag><c><![CDATA[-shutdown_time Time]]></c></tag>
<item>
@@ -431,9 +428,8 @@
flag and those running with the <c><![CDATA[-name]]></c> flag, as node
names must be unique in distributed Erlang systems.</p>
</item>
- <tag><c><![CDATA[-smp [enable|auto|disable]]]></c></tag>
+ <tag><marker id="smp"><c><![CDATA[-smp [enable|auto|disable]]]></c></marker></tag>
<item>
- <marker id="smp"></marker>
<p><c>-smp enable</c> and <c>-smp</c> starts the Erlang runtime
system with SMP support enabled. This may fail if no runtime
system with SMP support is available. <c>-smp auto</c> starts
@@ -462,9 +458,8 @@
<p><c><![CDATA[erl]]></c> invokes the code for the Erlang emulator (virtual
machine), which supports the following flags:</p>
<taglist>
- <tag><c><![CDATA[+a size]]></c></tag>
+ <tag><marker id="async_thread_stack_size"><c><![CDATA[+a size]]></c></marker></tag>
<item>
- <marker id="async_thread_stack_size"></marker>
<p>Suggested stack size, in kilowords, for threads in the
async-thread pool. Valid range is 16-8192 kilowords. The
default suggested stack size is 16 kilowords, i.e, 64
@@ -478,9 +473,8 @@
suggestion, and it might even be ignored on some
platforms.</p>
</item>
- <tag><c><![CDATA[+A size]]></c></tag>
+ <tag><marker id="async_thread_pool_size"><c><![CDATA[+A size]]></c></marker></tag>
<item>
- <marker id="async_thread_pool_size"></marker>
<p>Sets the number of threads in async thread pool, valid range
is 0-1024. Default is 0.</p>
</item>
@@ -527,11 +521,16 @@
<p>Calling <c>erlang:halt/1</c> with a string argument will still
produce a crash dump.</p>
</item>
- <tag><c><![CDATA[+h Size]]></c></tag>
+ <tag><c><![CDATA[+hms Size]]></c></tag>
<item>
<p>Sets the default heap size of processes to the size
<c><![CDATA[Size]]></c>.</p>
</item>
+ <tag><c><![CDATA[+hmbs Size]]></c></tag>
+ <item>
+ <p>Sets the default binary virtual heap size of processes to the size
+ <c><![CDATA[Size]]></c>.</p>
+ </item>
<tag><c><![CDATA[+K true | false]]></c></tag>
<item>
<p>Enables or disables the kernel poll functionality if
@@ -545,23 +544,20 @@
<p>Enables auto load tracing, displaying info while loading
code.</p>
</item>
- <tag><c><![CDATA[+MFlag Value]]></c></tag>
+ <tag><marker id="erts_alloc"><c><![CDATA[+MFlag Value]]></c></marker></tag>
<item>
- <marker id="erts_alloc"></marker>
<p>Memory allocator specific flags, see
<seealso marker="erts_alloc">erts_alloc(3)</seealso> for
further information.</p>
</item>
- <tag><c><![CDATA[+P Number]]></c></tag>
+ <tag><marker id="max_processes"><c><![CDATA[+P Number]]></c></marker></tag>
<item>
- <marker id="max_processes"></marker>
<p>Sets the maximum number of concurrent processes for this
system. <c><![CDATA[Number]]></c> must be in the range 16..134217727.
Default is 32768.</p>
</item>
- <tag><c><![CDATA[+R ReleaseNumber]]></c></tag>
+ <tag><marker id="compat_rel"><c><![CDATA[+R ReleaseNumber]]></c></marker></tag>
<item>
- <marker id="compat_rel"></marker>
<p>Sets the compatibility mode.</p>
<p>The distribution mechanism is not backwards compatible by
default. This flags sets the emulator in compatibility mode
@@ -587,9 +583,8 @@
<item>
<p>Force ets memory block to be moved on realloc.</p>
</item>
- <tag><c><![CDATA[+S Schedulers:SchedulerOnline]]></c></tag>
+ <tag><marker id="+S"><c><![CDATA[+S Schedulers:SchedulerOnline]]></c></marker></tag>
<item>
- <marker id="+S"></marker>
<p>Sets the amount of scheduler threads to create and scheduler
threads to set online when SMP support has been enabled.
Valid range for both values are 1-1024. If the
@@ -610,9 +605,8 @@
<item>
<p>Scheduling specific flags.</p>
<taglist>
- <tag>+sbt BindType</tag>
+ <tag><marker id="+sbt"><c>+sbt BindType</c></marker></tag>
<item>
- <marker id="+sbt"></marker>
<p>Set scheduler bind type. Currently valid <c>BindType</c>s:
</p>
<taglist>
@@ -667,9 +661,8 @@
<seealso marker="erlang#system_flag_scheduler_bind_type">erlang:system_flag(scheduler_bind_type, SchedulerBindType)</seealso>.
</p>
</item>
- <tag><c>+sct CpuTopology</c></tag>
+ <tag><marker id="+sct"><c>+sct CpuTopology</c></marker></tag>
<item>
- <marker id="+sct"></marker>
<list type="bulleted">
<item><c><![CDATA[<Id> = integer(); when 0 =< <Id> =< 65535]]></c></item>
<item><c><![CDATA[<IdRange> = <Id>-<Id>]]></c></item>
@@ -786,16 +779,18 @@
</item>
</taglist>
</item>
- <tag><c><![CDATA[+sss size]]></c></tag>
+ <tag><marker id="sched_thread_stack_size"><c><![CDATA[+sss size]]></c></marker></tag>
<item>
- <marker id="sched_thread_stack_size"></marker>
<p>Suggested stack size, in kilowords, for scheduler threads.
Valid range is 4-8192 kilowords. The default stack size
is OS dependent.</p>
</item>
- <tag><c><![CDATA[+T Level]]></c></tag>
+ <tag><marker id="+t"><c><![CDATA[+t size]]></c></marker></tag>
+ <item>
+ <p>Set the maximum number of atoms the VM can handle. Default is 1048576.</p>
+ </item>
+ <tag><marker id="+T"><c><![CDATA[+T Level]]></c></marker></tag>
<item>
- <marker id="+T"></marker>
<p>Enables modified timing and sets the modified timing level.
Currently valid range is 0-9. The timing of the runtime system
will change. A high level usually means a greater change than
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_driver.xml b/erts/doc/src/erl_driver.xml
index 0b11f4bbcb..5061230a33 100644
--- a/erts/doc/src/erl_driver.xml
+++ b/erts/doc/src/erl_driver.xml
@@ -4,7 +4,7 @@
<cref>
<header>
<copyright>
- <year>2001</year><year>2009</year>
+ <year>2001</year><year>2010</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
@@ -13,12 +13,12 @@
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>erl_driver</title>
@@ -171,8 +171,8 @@
asynchronous function calls, using a thread pool provided by
Erlang. There is also a select call, that can be used for
asynchronous drivers.</item>
- <tag>Multi-threading</tag>
- <item><marker id="multi_threading"></marker>
+ <tag><marker id="multi_threading">Multi-threading</marker></tag>
+ <item>
<p>A POSIX thread like API for multi-threading is provided. The
Erlang driver thread API only provide a subset of the functionality
provided by the POSIX thread API. The subset provided is
@@ -245,9 +245,8 @@
<item>A driver can add and later remove drivers.</item>
<tag>Monitoring processes</tag>
<item>A driver can monitor a process that does not own a port.</item>
- <tag>Version management</tag>
+ <tag><marker id="version_management">Version management</marker></tag>
<item>
- <marker id="version_management"></marker>
<p>Version management is enabled for drivers that have set the
<seealso marker="driver_entry#extended_marker">extended_marker</seealso>
field of their
@@ -299,6 +298,8 @@ typedef struct ErlDrvSysInfo {
int smp_support;
int async_threads;
int scheduler_threads;
+ int nif_major_version;
+ int nif_minor_version;
} ErlDrvSysInfo;
</code>
@@ -365,9 +366,14 @@ typedef struct ErlDrvSysInfo {
(the same as returned by
<seealso marker="erts:erlang#system_info_schedulers">erlang:system_info(schedulers)</seealso>).
</item>
+ <tag><c>nif_major_version</c></tag>
+ <item>The value of <c>ERL_NIF_MAJOR_VERSION</c> when the runtime system was compiled.
+ </item>
+ <tag><c>nif_minor_version</c></tag>
+ <item>The value of <c>ERL_NIF_MINOR_VERSION</c> when the runtime system was compiled.
+ </item>
</taglist>
</item>
-
<tag><marker id="ErlDrvBinary"/>ErlDrvBinary</tag>
<item>
<p/>
@@ -1292,7 +1298,7 @@ typedef struct ErlIOVec {
has been set in the
<seealso marker="driver_entry">driver_entry</seealso>,
data can be forced into the driver via
- <seealso marker="erlang#erlang:port_command/3">port_command(Port, Data, [force])</seealso>
+ <seealso marker="erlang#port_command/3">port_command(Port, Data, [force])</seealso>
even though the driver has signaled that it is busy.
</p>
</desc>
diff --git a/erts/doc/src/erl_nif.xml b/erts/doc/src/erl_nif.xml
index c636d65ef3..0dd46a951a 100644
--- a/erts/doc/src/erl_nif.xml
+++ b/erts/doc/src/erl_nif.xml
@@ -34,31 +34,37 @@
<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 plan is however to lift the experimental label and
+ maintain interface backward compatibility from R14B.</p>
+ <p>Incompatible changes in <em>R13B04</em>:</p>
+ <list>
+ <item>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.</item>
+ <item><c>enif_get_data</c> renamed as <c>enif_priv_data</c>.</item>
+ <item><c>enif_make_string</c> got a third argument for character encoding.</item>
+ </list>
+ </warning>
<p>A NIF library contains native implementation of some functions
- of an erlang module. The native implemented functions (NIFs) are
+ of an Erlang module. The native implemented functions (NIFs) are
called like any other functions without any difference to the
caller. Each NIF must also have an implementation in Erlang that
will be invoked if the function is called before the NIF library
has been successfully loaded. A typical such stub implementation
is to throw an exception. But it can also be used as a fallback
implementation if the NIF library is not implemented for some
- architecture.</p>
+ architecture.</p>
<p>A minimal example of a NIF library can look like this:</p>
<p/>
<code type="none">
/* 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!");
+ return enif_make_string(env, "Hello world!", ERL_NIF_LATIN1);
}
static ErlNifFunc nif_funcs[] =
@@ -69,7 +75,7 @@ static ErlNifFunc nif_funcs[] =
ERL_NIF_INIT(niftest,nif_funcs,NULL,NULL,NULL,NULL)
</code>
- <p>and the erlang module would have to look something like
+ <p>and the Erlang module would have to look something like
this:</p>
<p/>
<code type="none">
@@ -100,26 +106,140 @@ 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>
+ <note><p>A NIF must be exported or used locally by the module (or both).
+ An unused local stub function will be optimized away by the compiler
+ causing loading of the NIF library to fail.</p>
+ </note>
<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
+ new Erlang code will have to load its own NIF library (or maybe choose not
to). The new code version can however choose to load the exact
same NIF library as the old code if it wants to. Sharing the same
dynamic library will mean that static data defined by the library
will be shared as well. To avoid unintentionally shared static
data, each Erlang module code can keep its own private data. This
- global private data can be set when the NIF library is loaded and
- then retrieved by calling <seealso marker="erl_nif#enif_get_data">enif_get_data()</seealso>.</p>
- <p>There is currently no way to explicitly unload a NIF
- library. A library will be automatically unloaded when the module
- code that it belongs to is purged by the code server. A NIF
- library will can also be unloaded by replacing it with another
- version of the library by a second call to
+ private data can be set when the NIF library is loaded and
+ then retrieved by calling <seealso marker="#enif_priv_data">enif_priv_data()</seealso>.</p>
+ <p>There is no way to explicitly unload a NIF library. A library will be
+ automatically unloaded when the module code that it belongs to is purged
+ by the code server. A NIF library will also be unloaded if it is replaced
+ by another version of the library by a second call to
<c>erlang:load_nif/2</c> from the same module code.</p>
</description>
+ <section>
+ <title>FUNCTIONALITY</title>
+ <p>All functions that a NIF library needs to do with Erlang are
+ performed through the NIF API functions. There are functions
+ for the following functionality:</p>
+ <taglist>
+ <tag>Read and write Erlang terms</tag>
+ <item><p>Any Erlang terms can be passed to a NIF as function arguments and
+ be returned as function return values. The terms are of C-type <c>ERL_NIF_TERM</c>
+ and can only be read or written using API functions. Most functions to read
+ the content of a term are prefixed <c>enif_get_</c> and usually return
+ true (or false) if the term was of the expected type (or not).
+ The functions to write terms are all prefixed <c>enif_make_</c> and usually
+ return the created <c>ERL_NIF_TERM</c>. There are also some functions
+ to query terms, like <c>enif_is_atom</c>, <c>enif_is_identical</c> and
+ <c>enif_compare</c>.</p></item>
+ <tag>Binaries</tag>
+ <item><p>Terms of type binary are accessed with the help of the struct type
+ <seealso marker="#ErlNifBinary">ErlNifBinary</seealso>
+ that contains a pointer (<c>data</c>) to the raw binary data and the length
+ (<c>size</c>) of the data in bytes. Both <c>data</c> and <c>size</c> are
+ read-only and should only be written using calls to API functions.
+ Instances of <c>ErlNifBinary</c> are however always allocated by the user
+ (usually as local variables).</p>
+ <p>The raw data pointed to by <c>data</c> is only mutable after a call to
+ <seealso marker="#enif_alloc_binary">enif_alloc_binary</seealso> or
+ <seealso marker="#enif_realloc_binary">enif_realloc_binary</seealso>.
+ All other functions that operates on a binary will leave the data as read-only.
+ A mutable binary must in the end either be freed with
+ <seealso marker="#enif_release_binary">enif_release_binary</seealso>
+ or made read-only by transferring it to an Erlang term with
+ <seealso marker="#enif_make_binary">enif_make_binary</seealso>.
+ But it does not have do happen in the same NIF call. Read-only binaries
+ does not have to be released.</p>
+ <p>Binaries are sequences of whole bytes. Bitstrings with an arbitrary
+ bit length have no support yet.</p>
+ </item>
+ <tag>Resource objects</tag>
+ <item><p>The use of resource objects is a way to return pointers to
+ native data structures from a NIF in a safe way. A resource object is
+ just a block of memory allocated with
+ <seealso marker="#enif_alloc_resource">enif_alloc_resource()</seealso>.
+ A handle ("safe pointer") to this memory block can then be returned to Erlang by the use of
+ <seealso marker="#enif_make_resource">enif_make_resource()</seealso>.
+ The term returned by <c>enif_make_resource</c>
+ is totally opaque in nature. It can be stored and passed between processses
+ on the same node, but the only real end usage is to pass it back as argument to a NIF.
+ The NIF can then do <seealso marker="#enif_get_resource">enif_get_resource()</seealso>
+ and get back a pointer to the memory block that is guaranteed to still be
+ valid. A resource object will not be deallocated until the last handle term
+ has been garbage collected by the VM and the resource has been
+ released with <seealso marker="#enif_release_resource">enif_release_resource()</seealso>
+ (not necessarily in that order).</p>
+ <p>All resource objects are created as instances of some <em>resource type</em>.
+ This makes resources from different modules to be distinguishable.
+ A resource type is created by calling
+ <seealso marker="#enif_open_resource_type">enif_open_resource_type()</seealso>
+ when a library is loaded. Objects of that resource type can then later be allocated
+ and <c>enif_get_resource</c> verifies that the resource is of the expected type.
+ A resource type can have a user supplied destructor function that is
+ automatically called when resources of that type are released (by either
+ the garbage collector or <c>enif_release_resource</c>). Resource types
+ are uniquely identified by a supplied name string.</p>
+ <p>Resource types support upgrade in runtime by allowing a loaded NIF
+ library to takeover an already existing resource type and thereby
+ "inherit" all existing objects of that type. The destructor of the new
+ library will thereafter be called for the inherited objects and the
+ library with the old destructor function can be safely unloaded. Existing
+ resource objects, of a module that is upgraded, must either be deleted
+ or taken over by the new NIF library. The unloading of a library will be
+ postponed as long as it exists resource objects with a destructor
+ function in the library.
+ </p>
+ <p>Here is a template example of how to create and return a resource object.</p>
+ <p/>
+ <code type="none">
+ ERL_NIF_TERM term;
+ MyStruct* ptr = enif_alloc_resource(env, my_resource_type, sizeof(MyStruct));
+
+ /* initialize struct ... */
+ term = enif_make_resource(env, ptr);
+
+ if (keep_a_reference_of_our_own) {
+ /* store 'ptr' in static variable, private data or other resource object */
+ }
+ else {
+ enif_release_resource(env, obj);
+ /* resource now only owned by "Erlang" */
+ }
+ return term;
+}
+</code>
+
+ </item>
+ <tag>Threads and concurrency</tag>
+ <item><p>A NIF is thread-safe without any explicit synchronization as
+ long as it acts as a pure function and only reads the supplied
+ arguments. As soon as you write towards a shared state either through
+ static variables or <seealso marker="#enif_priv_data">enif_priv_data</seealso>
+ you need to supply your own explicit synchronization. Resource objects
+ will also require synchronization if you treat them as mutable.</p>
+ <p>The library initialization callbacks <c>load</c>, <c>reload</c> and
+ <c>upgrade</c> are all thread-safe even for shared state data.</p>
+ <p>Avoid doing lengthy work in NIF calls as that may degrade the
+ responsiveness of the VM. NIFs are called directly by the same scheduler
+ thread that executed the calling Erlang code. The calling scheduler will thus
+ be blocked from doing any other work until the NIF returns.</p>
+ </item>
+ </taglist>
+ </section>
<section>
<title>INITIALIZATION</title>
<taglist>
@@ -143,9 +263,11 @@ ok
and there is no previously loaded library for this module.</p>
<p><c>*priv_data</c> can be set to point to some private data
that the library needs in able to keep a state between NIF
- calls. <c>enif_get_data()</c> will return this pointer.</p>
+ calls. <c>enif_priv_data()</c> will return this pointer.
+ <c>*priv_data</c> will be initialized to NULL when <c>load</c> is
+ called.</p>
<p><c>load_info</c> is the second argument to <seealso
- marker="erlang#erlang:load_nif-2">erlang:load_nif/2</seealso>.</p>
+ marker="erlang#load_nif-2">erlang:load_nif/2</seealso>.</p>
<p>The library will fail to load if <c>load</c> returns
anything other than 0. <c>load</c> can be NULL in case no
initialization is needed.</p>
@@ -165,13 +287,12 @@ ok
<tag><marker id="upgrade"/>int (*upgrade)(ErlNifEnv* env, void** priv_data, void** old_priv_data, ERL_NIF_TERM load_info)</tag>
<item><p><c>upgrade</c> is called when the NIF library is loaded
and there is no previously loaded library for this module
- code, BUT there is old code of this module with a
- loaded NIF library.</p>
+ code, BUT there is old code of this module with a loaded NIF library.</p>
<p>Works the same as <c>load</c>. The only difference is that
<c>*old_priv_data</c> already contains the value set by the
last call to <c>load</c> or <c>reload</c> for the old module
- code. It is allowed to write to both *priv_data and
- *old_priv_data.</p>
+ code. <c>*priv_data</c> will be initialized to NULL when <c>upgrade</c>
+ is called. It is allowed to write to both *priv_data and *old_priv_data.</p>
<p>The library will fail to load if <c>upgrade</c> returns
anything other than 0 or if <c>upgrade</c> is NULL.</p>
</item>
@@ -179,10 +300,10 @@ ok
<tag><marker id="unload"/>void (*unload)(ErlNifEnv* env, void* priv_data)</tag>
<item><p><c>unload</c> is called when the module code that
the NIF library belongs to is purged as old. New code
- of the same module may or may not exist.</p>
+ of the same module may or may not exist. Note that <c>unload</c> is not
+ called for a replaced library as a consequence of <c>reload</c>.</p>
</item>
-
</taglist>
</section>
@@ -190,7 +311,15 @@ ok
<title>DATA TYPES</title>
<taglist>
- <tag><marker id="ErlDrvEnv"/>ErlDrvEnv</tag>
+ <tag><marker id="ERL_NIF_TERM"/>ERL_NIF_TERM</tag>
+ <item>
+ <p>Variables of type <c>ERL_NIF_TERM</c> can refer to any Erlang term.
+ This is an opaque type and values of it can only by used either as
+ arguments to API functions or as return values from NIFs. A variable of
+ type <c>ERL_NIF_TERM</c> is only valid until the NIF call, where it was
+ obtained, returns.</p>
+ </item>
+ <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,81 +334,151 @@ 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
inspected binary term. <c>data</c> is a pointer to a buffer
of <c>size</c> bytes with the raw content of the binary.</p>
</item>
- <tag><marker id="ERL_NIF_TERM"/>ERL_NIF_TERM</tag>
+ <tag><marker id="ErlNifResourceType"/>ErlNifResourceType</tag>
<item>
- <p>Variables of type <c>ERL_NIF_TERM</c> can refere to any
- Erlang term. This is an opaque type and values of it can only
- by used either as arguments to API functions or as return
- values from NIFs. A variable of type <c>ERL_NIF_TERM</c> is
- only valid until the NIF call, where it was obtained,
- returns.</p>
- </item>
+ <p>Each instance of <c>ErlNifResourceType</c> represent a class of
+ memory managed resource objects that can be garbage collected.
+ Each resource type has a unique name and a destructor function that
+ is called when objects of its type are released.</p>
+ </item>
+ <tag><marker id="ErlNifResourceDtor"/>ErlNifResourceDtor</tag>
+ <item>
+ <p/>
+ <code type="none">
+typedef void ErlNifResourceDtor(ErlNifEnv* env, void* obj);
+</code>
+ <p>The function prototype of a resource destructor function.
+ A destructor function is not allowed to call any term-making functions.</p>
+ </item>
+ <tag><marker id="ErlNifCharEncoding"/>ErlNifCharEncoding</tag>
+ <item>
+ <p/>
+ <code type="none">
+typedef enum {
+ ERL_NIF_LATIN1
+}ErlNifCharEncoding;
+</code>
+ <p>The character encoding used in strings. The only supported
+ encoding is currently <c>ERL_NIF_LATIN1</c> for iso-latin-1
+ (8-bit ascii).</p>
+ </item>
+ <tag><marker id="ErlNifSysInfo"/>ErlNifSysInfo</tag>
+ <item>
+ <p>Used by <seealso marker="#enif_system_info">enif_system_info</seealso>
+ to return information about the runtime system. Contains currently
+ the exact same content as <seealso marker="erl_driver#ErlDrvSysInfo">ErlDrvSysInfo</seealso>.</p>
+ </item>
+
</taglist>
</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. The binary must either be released by
+ <seealso marker="#enif_release_binary">enif_release_binary()</seealso>
+ or ownership transferred to an Erlang term with
+ <seealso marker="#enif_make_binary">enif_make_binary()</seealso>.
+ An allocated (and owned) <c>ErlNifBinary</c> can be kept between NIF
+ calls.</p>
+ <p>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>void*</ret><nametext>enif_alloc_resource(ErlNifEnv* env, ErlNifResourceType* type, unsigned size)</nametext></name>
+ <fsummary>Allocate a memory managed resource object</fsummary>
+ <desc><p>Allocate a memory managed resource object of type <c>type</c> and size <c>size</c> bytes.</p></desc>
+ </func>
+ <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_cond_broadcast(ErlNifCond *cnd)</nametext></name>
+ <fsummary></fsummary>
+ <desc><p>Same as <seealso marker="erl_driver#erl_drv_cond_broadcast">erl_drv_cond_broadcast()</seealso>.
+ </p></desc>
+ </func>
+ <func><name><ret>ErlNifCond*</ret><nametext>enif_cond_create(char *name)</nametext></name>
+ <fsummary></fsummary>
+ <desc><p>Same as <seealso marker="erl_driver#erl_drv_cond_create">erl_drv_cond_create()</seealso>.
+ </p></desc>
+ </func>
+ <func><name><ret>void</ret><nametext>enif_cond_destroy(ErlNifCond *cnd)</nametext></name>
+ <fsummary></fsummary>
+ <desc><p>Same as <seealso marker="erl_driver#erl_drv_cond_destroy">erl_drv_cond_destroy()</seealso>.
+ </p></desc>
+ </func>
+ <func><name><ret>void</ret><nametext>enif_cond_signal(ErlNifCond *cnd)</nametext></name>
+ <fsummary></fsummary>
+ <desc><p>Same as <seealso marker="erl_driver#erl_drv_cond_signal">erl_drv_cond_signal()</seealso>.
+ </p></desc>
+ </func>
+ <func><name><ret>void</ret><nametext>enif_cond_wait(ErlNifCond *cnd, ErlNifMutex *mtx)</nametext></name>
+ <fsummary></fsummary>
+ <desc><p>Same as <seealso marker="erl_driver#erl_drv_cond_wait">erl_drv_cond_wait()</seealso>.
+ </p></desc>
+ </func>
+ <func><name><ret>int</ret><nametext>enif_equal_tids(ErlNifTid tid1, ErlNifTid tid2)</nametext></name>
+ <fsummary></fsummary>
+ <desc><p>Same as <seealso marker="erl_driver#erl_drv_equal_tids">erl_drv_equal_tids()</seealso>.
+ </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_get_atom(ErlNifEnv* env,
+ ERL_NIF_TERM term, char* buf, unsigned size)
+ </nametext></name>
+ <fsummary>Get the text representation of an atom term</fsummary>
+ <desc><p>Write a null-terminated string, in the buffer pointed to by
+ <c>buf</c> of size <c>size</c>, consisting of the string
+ representation of the atom <c>term</c>. Return the number of bytes
+ written (including terminating null character) or 0 if
+ <c>term</c> is not an atom with maximum length of
+ <c>size-1</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 +486,145 @@ 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_long(ErlNifEnv* env, ERL_NIF_TERM term, long int* ip)</nametext></name>
+ <fsummary>Read an long integer term.</fsummary>
+ <desc><p>Set <c>*ip</c> to the long integer value of
+ <c>term</c> or return false if <c>term</c> is not an integer or is
+ outside the bounds of type <c>long int</c>.</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_resource(ErlNifEnv* env, ERL_NIF_TERM term, ErlNifResourceType* type, void** objp)</nametext></name>
+ <fsummary>Get the pointer to a resource object</fsummary>
+ <desc><p>Set <c>*objp</c> to point to the resource object referred to by <c>term</c>.
+ The pointer is valid until the calling NIF returns and should not be released.</p>
+ <p>Return false if <c>term</c> is not a handle to a resource object
+ of type <c>type</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_get_string(ErlNifEnv* env,
+ ERL_NIF_TERM list, char* buf, unsigned size,
+ ErlNifCharEncoding encode)</nametext></name>
+ <fsummary>Get a C-string from a list.</fsummary>
+ <desc><p>Write a null-terminated string, in the buffer pointed to by
+ <c>buf</c> with size <c>size</c>, consisting of the characters
+ in the string <c>list</c>. The characters are written using encoding
+ <seealso marker="#ErlNifCharEncoding">encode</seealso>.
+ Return the number of bytes written (including terminating null
+ character), or <c>-size</c> if the string was truncated due to
+ buffer space, or 0 if <c>list</c> is not a string that can be
+ encoded with <c>encode</c> or if <c>size</c> was less than 1.
+ The written string is always null-terminated unless buffer
+ <c>size</c> is less than 1.</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_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 and <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>int</ret><nametext>enif_get_uint(ErlNifEnv* env, ERL_NIF_TERM term, unsigned int* ip)</nametext></name>
+ <fsummary>Read an unsigned integer term.</fsummary>
+ <desc><p>Set <c>*ip</c> to the unsigned 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 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 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>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
+ 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>int</ret><nametext>enif_inspect_iolist_as_binary(ErlNifEnv*
+ env, ERL_NIF_TERM term, ErlNifBinary* bin)
+ </nametext></name>
+ <fsummary>Inspect the content of an iolist</fsummary>
+ <desc><p>Initialize the structure pointed to by <c>bin</c> with one
+ continuous buffer with the same byte content as <c>iolist</c>. As with
+ inspect_binary, the data pointed to by <c>bin</c> is transient and does
+ not need to be released. Return false if <c>iolist</c> is not an
+ iolist.</p>
+ </desc>
+ </func>
+ <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_empty_list(ErlNifEnv* env, ERL_NIF_TERM term)</nametext></name>
+ <fsummary>Determine if a term is an empty list</fsummary>
+ <desc><p>Return true if <c>term</c> is an empty list.</p></desc>
+ </func>
+ <func><name><ret>int</ret><nametext>enif_is_fun(ErlNifEnv* env, ERL_NIF_TERM term)</nametext></name>
+ <fsummary>Determine if a term is a fun</fsummary>
+ <desc><p>Return true if <c>term</c> is a fun.</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 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_pid(ErlNifEnv* env, ERL_NIF_TERM term)</nametext></name>
+ <fsummary>Determine if a term is a pid</fsummary>
+ <desc><p>Return true if <c>term</c> is a pid.</p></desc>
+ </func>
+ <func><name><ret>int</ret><nametext>enif_is_port(ErlNifEnv* env, ERL_NIF_TERM term)</nametext></name>
+ <fsummary>Determine if a term is a port</fsummary>
+ <desc><p>Return true if <c>term</c> is a port.</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
+ <desc><p>Create an atom term from the C-string <c>name</c>. Unlike other terms, 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>. Any ownership of
+ the binary data will be transferred to the created term and
+ <c>bin</c> should be considered read-only for the rest of the NIF
+ call and then as released.</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>
@@ -333,19 +632,279 @@ typedef struct {
<c>cnt</c> number of arguments (after <c>cnt</c>) of type ERL_NIF_TERM as the
elements of the list. An empty list is returned if <c>cnt</c> is 0.</p></desc>
</func>
+ <func><name><ret>ERL_NIF_TERM</ret><nametext>enif_make_list1(ErlNifEnv* env, ERL_NIF_TERM e1)</nametext></name>
+ <name><ret>ERL_NIF_TERM</ret><nametext>enif_make_list2(ErlNifEnv* env, ERL_NIF_TERM e1, ERL_NIF_TERM e2)</nametext></name>
+ <name><ret>ERL_NIF_TERM</ret><nametext>enif_make_list3(ErlNifEnv* env, ERL_NIF_TERM e1, ERL_NIF_TERM e2, ERL_NIF_TERM e3)</nametext></name>
+ <name><ret>ERL_NIF_TERM</ret><nametext>enif_make_list4(ErlNifEnv* env, ERL_NIF_TERM e1, ..., ERL_NIF_TERM e4)</nametext></name>
+ <name><ret>ERL_NIF_TERM</ret><nametext>enif_make_list5(ErlNifEnv* env, ERL_NIF_TERM e1, ..., ERL_NIF_TERM e5)</nametext></name>
+ <name><ret>ERL_NIF_TERM</ret><nametext>enif_make_list6(ErlNifEnv* env, ERL_NIF_TERM e1, ..., ERL_NIF_TERM e6)</nametext></name>
+ <name><ret>ERL_NIF_TERM</ret><nametext>enif_make_list7(ErlNifEnv* env, ERL_NIF_TERM e1, ..., ERL_NIF_TERM e7)</nametext></name>
+ <name><ret>ERL_NIF_TERM</ret><nametext>enif_make_list8(ErlNifEnv* env, ERL_NIF_TERM e1, ..., ERL_NIF_TERM e8)</nametext></name>
+ <name><ret>ERL_NIF_TERM</ret><nametext>enif_make_list9(ErlNifEnv* env, ERL_NIF_TERM e1, ..., ERL_NIF_TERM e9)</nametext></name>
+ <fsummary>Create a list term.</fsummary>
+ <desc><p>Create an ordinary list term with length indicated by the
+ function name. Prefer these functions (macros) over the variadic
+ <c>enif_make_list</c> to get compile time error if the number of
+ arguments does not match.</p></desc>
+ </func>
<func><name><ret>ERL_NIF_TERM</ret><nametext>enif_make_list_cell(ErlNifEnv* env, ERL_NIF_TERM head, ERL_NIF_TERM tail)</nametext></name>
<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_string(ErlNifEnv* env, const char* string)</nametext></name>
+ <func><name><ret>ERL_NIF_TERM</ret><nametext>enif_make_list_from_array(ErlNifEnv* env, const ERL_NIF_TERM arr[], unsigned cnt)</nametext></name>
+ <fsummary>Create a list term from an array.</fsummary>
+ <desc><p>Create an ordinary list containing the elements of array <c>arr</c>
+ of length <c>cnt</c>. An empty list is returned if <c>cnt</c> is 0.</p></desc>
+ </func>
+ <func><name><ret>ERL_NIF_TERM</ret><nametext>enif_make_long(ErlNifEnv* env, long int i)</nametext></name>
+ <fsummary>Create an integer term from a long int</fsummary>
+ <desc><p>Create an integer term from a <c>long int</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_resource(ErlNifEnv* env, void* obj)</nametext></name>
+ <fsummary>Create an opaque handle to a resource object</fsummary>
+ <desc><p>Create an opaque handle to a memory managed resource object
+ obtained by <seealso marker="#enif_alloc_resource">enif_alloc_resource</seealso>.
+ No ownership transfer is done, the resource object still needs to be released by
+ <seealso marker="#enif_release_resource">enif_release_resource</seealso>.</p>
+ <p>Note that the only defined behaviour when using of a resource term in
+ an Erlang program is to store it and send it between processes on the
+ same node. Other operations such as matching or <c>term_to_binary</c>
+ will have unpredictable (but harmless) results.</p></desc>
+ </func>
+ <func><name><ret>ERL_NIF_TERM</ret><nametext>enif_make_string(ErlNifEnv* env, const char* string, ErlNifCharEncoding encoding)</nametext></name>
<fsummary>Create a string.</fsummary>
- <desc><p>Creates a list containing the characters of the
- C-string <c>string</c>.</p></desc>
+ <desc><p>Create a list containing the characters of the
+ null-terminated string <c>string</c> with encoding <seealso marker="#ErlNifCharEncoding">encoding</seealso>.</p></desc>
+ </func>
+ <func><name><ret>ERL_NIF_TERM</ret><nametext>enif_make_sub_binary(ErlNifEnv*
+ env, ERL_NIF_TERM bin_term, unsigned pos, unsigned size)</nametext></name>
+ <fsummary>Make a subbinary term.</fsummary>
+ <desc><p>Make a subbinary of binary <c>bin_term</c>, starting at
+ zero-based position <c>pos</c> with a length of <c>size</c> bytes.
+ <c>bin_term</c> must be a binary or bitstring and
+ <c>pos+size</c> must be less or equal to the number of whole
+ bytes in <c>bin_term</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_tuple1(ErlNifEnv* env, ERL_NIF_TERM e1)</nametext></name>
+ <name><ret>ERL_NIF_TERM</ret><nametext>enif_make_tuple2(ErlNifEnv* env, ERL_NIF_TERM e1, ERL_NIF_TERM e2)</nametext></name>
+ <name><ret>ERL_NIF_TERM</ret><nametext>enif_make_tuple3(ErlNifEnv* env, ERL_NIF_TERM e1, ERL_NIF_TERM e2, ERL_NIF_TERM e3)</nametext></name>
+ <name><ret>ERL_NIF_TERM</ret><nametext>enif_make_tuple4(ErlNifEnv* env, ERL_NIF_TERM e1, ..., ERL_NIF_TERM e4)</nametext></name>
+ <name><ret>ERL_NIF_TERM</ret><nametext>enif_make_tuple5(ErlNifEnv* env, ERL_NIF_TERM e1, ..., ERL_NIF_TERM e5)</nametext></name>
+ <name><ret>ERL_NIF_TERM</ret><nametext>enif_make_tuple6(ErlNifEnv* env, ERL_NIF_TERM e1, ..., ERL_NIF_TERM e6)</nametext></name>
+ <name><ret>ERL_NIF_TERM</ret><nametext>enif_make_tuple7(ErlNifEnv* env, ERL_NIF_TERM e1, ..., ERL_NIF_TERM e7)</nametext></name>
+ <name><ret>ERL_NIF_TERM</ret><nametext>enif_make_tuple8(ErlNifEnv* env, ERL_NIF_TERM e1, ..., ERL_NIF_TERM e8)</nametext></name>
+ <name><ret>ERL_NIF_TERM</ret><nametext>enif_make_tuple9(ErlNifEnv* env, ERL_NIF_TERM e1, ..., ERL_NIF_TERM e9)</nametext></name>
+ <fsummary>Create a tuple term.</fsummary>
+ <desc><p>Create a tuple term with length indicated by the
+ function name. Prefer these functions (macros) over the variadic
+ <c>enif_make_tuple</c> to get compile time error if the number of
+ arguments does not match.</p></desc>
+ </func>
+ <func><name><ret>ERL_NIF_TERM</ret><nametext>enif_make_tuple_from_array(ErlNifEnv* env, const ERL_NIF_TERM arr[], unsigned cnt)</nametext></name>
+ <fsummary>Create a tuple term from an array.</fsummary>
+ <desc><p>Create a tuple containing the elements of array <c>arr</c>
+ of length <c>cnt</c>.</p></desc>
+ </func>
+ <func><name><ret>ERL_NIF_TERM</ret><nametext>enif_make_uint(ErlNifEnv* env, unsigned int i)</nametext></name>
+ <fsummary>Create an unsigned integer term</fsummary>
+ <desc><p>Create an integer term from an <c>unsigned int</c>.</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>ErlNifMutex*</ret><nametext>enif_mutex_create(char *name)</nametext></name>
+ <fsummary></fsummary>
+ <desc><p>Same as <seealso marker="erl_driver#erl_drv_mutex_create">erl_drv_mutex_create()</seealso>.
+ </p></desc>
+ </func>
+ <func><name><ret>void</ret><nametext>enif_mutex_destroy(ErlNifMutex *mtx)</nametext></name>
+ <fsummary></fsummary>
+ <desc><p>Same as <seealso marker="erl_driver#erl_drv_mutex_destroy">erl_drv_mutex_destroy()</seealso>.
+ </p></desc>
+ </func>
+ <func><name><ret>void</ret><nametext>enif_mutex_lock(ErlNifMutex *mtx)</nametext></name>
+ <fsummary></fsummary>
+ <desc><p>Same as <seealso marker="erl_driver#erl_drv_mutex_lock">erl_drv_mutex_lock()</seealso>.
+ </p></desc>
+ </func>
+ <func><name><ret>int</ret><nametext>enif_mutex_trylock(ErlNifMutex *mtx)</nametext></name>
+ <fsummary></fsummary>
+ <desc><p>Same as <seealso marker="erl_driver#erl_drv_mutex_trylock">erl_drv_mutex_trylock()</seealso>.
+ </p></desc>
+ </func>
+ <func><name><ret>void</ret><nametext>enif_mutex_unlock(ErlNifMutex *mtx)</nametext></name>
+ <fsummary></fsummary>
+ <desc><p>Same as <seealso marker="erl_driver#erl_drv_mutex_unlock">erl_drv_mutex_unlock()</seealso>.
+ </p></desc>
+ </func>
+ <func><name><ret>ErlNifResourceType*</ret><nametext>enif_open_resource_type(ErlNifEnv* env, const char* name,
+ ErlNifResourceDtor* dtor, ErlNifResourceFlags flags, ErlNifResourceFlags* tried)</nametext></name>
+ <fsummary>Create or takeover a resource type</fsummary>
+ <desc><p>Create or takeover a resource type identified by the string
+ <c>name</c> and give it the destructor function pointed to by <seealso marker="#ErlNifResourceDtor">dtor</seealso>.
+ Argument <c>flags</c> can have the following values:</p>
+ <taglist>
+ <tag><c>ERL_NIF_RT_CREATE</c></tag>
+ <item>Create a new resource type that does not already exist.</item>
+ <tag><c>ERL_NIF_RT_TAKEOVER</c></tag>
+ <item>Open an existing resource type and take over ownership of all its instances.
+ The supplied destructor <c>dtor</c> will be called both for existing instances
+ as well as new instances not yet created by the calling NIF library.</item>
+ </taglist>
+ <p>The two flag values can be combined with bitwise-or. To avoid unintentionally
+ name clashes a good practice is to include the module name as part of the
+ type <c>name</c>. The <c>dtor</c> may be <c>NULL</c> in case no destructor
+ is needed.</p>
+ <p>On success, return a pointer to the resource type and <c>*tried</c>
+ will be set to either <c>ERL_NIF_RT_CREATE</c> or
+ <c>ERL_NIF_RT_TAKEOVER</c> to indicate what was actually done.
+ On failure, return <c>NULL</c> and set <c>*tried</c> to <c>flags</c>.
+ It is allowed to set <c>tried</c> to <c>NULL</c>.</p>
+ <p>Note that <c>enif_open_resource_type</c> is only allowed to be called in the three callbacks
+ <seealso marker="#load">load</seealso>, <seealso marker="#reload">reload</seealso>
+ and <seealso marker="#upgrade">upgrade</seealso>.</p>
+ </desc>
+ </func>
+ <func><name><ret>void*</ret><nametext>enif_priv_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>
+ <p>Was previously named <c>enif_get_data</c>.</p></desc>
+ </func>
+ <func><name><ret>void</ret><nametext>enif_realloc_binary(ErlNifEnv* env, ErlNifBinary* bin, unsigned size)</nametext></name>
+ <fsummary>Change the size of a binary.</fsummary>
+ <desc><p>Change the size of a binary <c>bin</c>. The source binary
+ may be read-only, in which case it will be left untouched and
+ a mutable copy is allocated and assigned to <c>*bin</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>.</p></desc>
+ </func>
+ <func><name><ret>void</ret><nametext>enif_release_resource(ErlNifEnv* env, void* obj)</nametext></name>
+ <fsummary>Release a resource object.</fsummary>
+ <desc><p>Release a resource objects obtained from <c>enif_alloc_resource</c>.
+ The object may still be alive if it is referred to by Erlang terms. Each call to
+ <c>enif_release_resource</c> must correspond to a previous call to <c>enif_alloc_resource</c>.
+ References made by <c>enif_make_resource</c> can only be released by the garbage collector.</p></desc>
+ </func>
+ <func><name><ret>ErlNifRWLock*</ret><nametext>enif_rwlock_create(char *name)</nametext></name>
+ <fsummary></fsummary>
+ <desc><p>Same as <seealso marker="erl_driver#erl_drv_rwlock_create">erl_drv_rwlock_create()</seealso>.
+ </p></desc>
+ </func>
+ <func><name><ret>void</ret><nametext>enif_rwlock_destroy(ErlNifRWLock *rwlck)</nametext></name>
+ <fsummary></fsummary>
+ <desc><p>Same as <seealso marker="erl_driver#erl_drv_rwlock_destroy">erl_drv_rwlock_destroy()</seealso>.
+ </p></desc>
+ </func>
+ <func><name><ret>void</ret><nametext>enif_rwlock_rlock(ErlNifRWLock *rwlck)</nametext></name>
+ <fsummary></fsummary>
+ <desc><p>Same as <seealso marker="erl_driver#erl_drv_rwlock_rlock">erl_drv_rwlock_rlock()</seealso>.
+ </p></desc>
+ </func>
+ <func><name><ret>void</ret><nametext>enif_rwlock_runlock(ErlNifRWLock *rwlck)</nametext></name>
+ <fsummary></fsummary>
+ <desc><p>Same as <seealso marker="erl_driver#erl_drv_rwlock_runlock">erl_drv_rwlock_runlock()</seealso>.
+ </p></desc>
+ </func>
+ <func><name><ret>void</ret><nametext>enif_rwlock_rwlock(ErlNifRWLock *rwlck)</nametext></name>
+ <fsummary></fsummary>
+ <desc><p>Same as <seealso marker="erl_driver#erl_drv_rwlock_rwlock">erl_drv_rwlock_rwlock()</seealso>.
+ </p></desc>
+ </func>
+ <func><name><ret>void</ret><nametext>enif_rwlock_rwunlock(ErlNifRWLock *rwlck)</nametext></name>
+ <fsummary></fsummary>
+ <desc><p>Same as <seealso marker="erl_driver#erl_drv_rwlock_rwunlock">erl_drv_rwlock_rwunlock()</seealso>.
+ </p></desc>
+ </func>
+ <func><name><ret>int</ret><nametext>enif_rwlock_tryrlock(ErlNifRWLock *rwlck)</nametext></name>
+ <fsummary></fsummary>
+ <desc><p>Same as <seealso marker="erl_driver#erl_drv_rwlock_tryrlock">erl_drv_rwlock_tryrlock()</seealso>.
+ </p></desc>
+ </func>
+ <func><name><ret>int</ret><nametext>enif_rwlock_tryrwlock(ErlNifRWLock *rwlck)</nametext></name>
+ <fsummary></fsummary>
+ <desc><p>Same as <seealso marker="erl_driver#erl_drv_rwlock_tryrwlock">erl_drv_rwlock_tryrwlock()</seealso>.
+ </p></desc>
+ </func>
+ <func><name><ret>unsigned</ret><nametext>enif_sizeof_resource(ErlNifEnv* env, void* obj)</nametext></name>
+ <fsummary>Get the byte size of a resource object</fsummary>
+ <desc><p>Get the byte size of a resource object <c>obj</c> obtained by
+ <c>enif_alloc_resource</c>.</p></desc>
+ </func>
+ <func>
+ <name><ret>void</ret><nametext>enif_system_info(ErlNifSysInfo *sys_info_ptr, size_t size)</nametext></name>
+ <fsummary>Get information about the Erlang runtime system</fsummary>
+ <desc><p>Same as <seealso marker="erl_driver#driver_system_info">driver_system_info()</seealso>.
+ </p></desc>
+ </func>
+ <func><name><ret>int</ret><nametext>enif_thread_create(char *name,ErlNifTid *tid,void * (*func)(void *),void *args,ErlNifThreadOpts *opts)</nametext></name>
+ <fsummary></fsummary>
+ <desc><p>Same as <seealso marker="erl_driver#erl_drv_thread_create">erl_drv_thread_create()</seealso>.
+ </p></desc>
+ </func>
+ <func><name><ret>void</ret><nametext>enif_thread_exit(void *resp)</nametext></name>
+ <fsummary></fsummary>
+ <desc><p>Same as <seealso marker="erl_driver#erl_drv_thread_exit">erl_drv_thread_exit()</seealso>.
+ </p></desc>
+ </func>
+ <func><name><ret>int</ret><nametext>enif_thread_join(ErlNifTid, void **respp)</nametext></name>
+ <fsummary></fsummary>
+ <desc><p>Same as <seealso marker="erl_driver#erl_drv_thread_join">erl_drv_thread_join ()</seealso>.
+ </p></desc>
+ </func>
+ <func><name><ret>ErlNifThreadOpts*</ret><nametext>enif_thread_opts_create(char *name)</nametext></name>
+ <fsummary></fsummary>
+ <desc><p>Same as <seealso marker="erl_driver#erl_drv_thread_opts_create">erl_drv_thread_opts_create()</seealso>.
+ </p></desc>
+ </func>
+ <func><name><ret>void</ret><nametext>enif_thread_opts_destroy(ErlNifThreadOpts *opts)</nametext></name>
+ <fsummary></fsummary>
+ <desc><p>Same as <seealso marker="erl_driver#erl_drv_thread_opts_destroy">erl_drv_thread_opts_destroy()</seealso>.
+ </p></desc>
+ </func>
+ <func><name><ret>ErlNifTid</ret><nametext>enif_thread_self(void)</nametext></name>
+ <fsummary></fsummary>
+ <desc><p>Same as <seealso marker="erl_driver#erl_drv_thread_self">erl_drv_thread_self()</seealso>.
+ </p></desc>
+ </func>
+ <func><name><ret>int</ret><nametext>enif_tsd_key_create(char *name, ErlNifTSDKey *key)</nametext></name>
+ <fsummary></fsummary>
+ <desc><p>Same as <seealso marker="erl_driver#erl_drv_tsd_key_create">erl_drv_tsd_key_create()</seealso>.
+ </p></desc>
+ </func>
+ <func><name><ret>void</ret><nametext>enif_tsd_key_destroy(ErlNifTSDKey key)</nametext></name>
+ <fsummary></fsummary>
+ <desc><p>Same as <seealso marker="erl_driver#erl_drv_tsd_key_destroy">erl_drv_tsd_key_destroy()</seealso>.
+ </p></desc>
+ </func>
+ <func><name><ret>void*</ret><nametext>enif_tsd_get(ErlNifTSDKey key)</nametext></name>
+ <fsummary></fsummary>
+ <desc><p>Same as <seealso marker="erl_driver#erl_drv_tsd_get">erl_drv_tsd_get()</seealso>.
+ </p></desc>
+ </func>
+ <func><name><ret>void</ret><nametext>enif_tsd_set(ErlNifTSDKey key, void *data)</nametext></name>
+ <fsummary></fsummary>
+ <desc><p>Same as <seealso marker="erl_driver#erl_drv_tsd_set">erl_drv_tsd_set()</seealso>.
+ </p></desc>
</func>
</funcs>
<section>
<title>SEE ALSO</title>
- <p><seealso marker="erlang#erlang:load_nif-2">load_nif(3)</seealso></p>
+ <p><seealso marker="erlang#load_nif-2">load_nif(3)</seealso></p>
</section>
</cref>
diff --git a/erts/doc/src/erlang.xml b/erts/doc/src/erlang.xml
index fd4447009a..46f8df4683 100644
--- a/erts/doc/src/erlang.xml
+++ b/erts/doc/src/erlang.xml
@@ -4,7 +4,7 @@
<erlref>
<header>
<copyright>
- <year>1996</year><year>2009</year>
+ <year>1996</year><year>2010</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
@@ -13,12 +13,12 @@
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>erlang</title>
@@ -342,8 +342,50 @@ iolist() = [char() | binary() | iolist()]
<desc>
<p>Returns an Erlang term which is the result of decoding
the binary object <c>Binary</c>, which must be encoded
- according to the Erlang external term format. See also
- <seealso marker="#term_to_binary/1">term_to_binary/1</seealso>.</p>
+ according to the Erlang external term format.</p>
+ <warning>
+ <p>When decoding binaries from untrusted sources, consider using
+ <c>binary_to_term/2</c> to prevent denial of service attacks.</p>
+ </warning>
+ <p>See also
+ <seealso marker="#term_to_binary/1">term_to_binary/1</seealso>
+ and
+ <seealso marker="#binary_to_term/2">binary_to_term/2</seealso>.</p>
+ </desc>
+ </func>
+ <func>
+ <name>erlang:binary_to_term(Binary, Opts) -> term()</name>
+ <fsummary>Decode an Erlang external term format binary</fsummary>
+ <type>
+ <v>Opts = [safe]</v>
+ <v>Binary = ext_binary()</v>
+ </type>
+ <desc>
+ <p>As <c>binary_to_term/1</c>, but takes options that affect decoding
+ of the binary.</p>
+ <taglist>
+ <tag><c>safe</c></tag>
+ <item>
+ <p>Use this option when receiving binaries from an untrusted
+ source.</p>
+ <p>When enabled, it prevents decoding data that may be used to
+ attack the Erlang system. In the event of receiving unsafe
+ data, decoding fails with a badarg error.</p>
+ <p>Currently, this prevents creation of new atoms directly,
+ creation of new atoms indirectly (as they are embedded in
+ certain structures like pids, refs, funs, etc.), and creation of
+ new external function references. None of those resources are
+ currently garbage collected, so unchecked creation of them can
+ exhaust available memory.</p>
+ </item>
+ </taglist>
+ <p>Failure: <c>badarg</c> if <c>safe</c> is specified and unsafe data
+ is decoded.</p>
+ <p>See also
+ <seealso marker="#term_to_binary/1">term_to_binary/1</seealso>,
+ <seealso marker="#binary_to_term/1">binary_to_term/1</seealso>,
+ and <seealso marker="#list_to_existing_atom/1">
+ list_to_existing_atom/1</seealso>.</p>
</desc>
</func>
<func>
@@ -410,19 +452,19 @@ iolist() = [char() | binary() | iolist()]
<desc>
<p>Cancels a timer, where <c>TimerRef</c> was returned by
either
- <seealso marker="#erlang:send_after/3">erlang:send_after/3</seealso>
+ <seealso marker="#send_after/3">erlang:send_after/3</seealso>
or
- <seealso marker="#erlang:start_timer/3">erlang:start_timer/3</seealso>.
+ <seealso marker="#start_timer/3">erlang:start_timer/3</seealso>.
If the timer is there to be removed, the function returns
the time in milliseconds left until the timer would have expired,
otherwise <c>false</c> (which means that <c>TimerRef</c> was
never a timer, that it has already been cancelled, or that it
has already delivered its message).</p>
<p>See also
- <seealso marker="#erlang:send_after/3">erlang:send_after/3</seealso>,
- <seealso marker="#erlang:start_timer/3">erlang:start_timer/3</seealso>,
+ <seealso marker="#send_after/3">erlang:send_after/3</seealso>,
+ <seealso marker="#start_timer/3">erlang:start_timer/3</seealso>,
and
- <seealso marker="#erlang:read_timer/1">erlang:read_timer/1</seealso>.</p>
+ <seealso marker="#read_timer/1">erlang:read_timer/1</seealso>.</p>
<p>Note: Cancelling a timer does not guarantee that the message
has not already been delivered to the message queue.</p>
</desc>
@@ -673,7 +715,7 @@ false</pre>
<desc>
<p>If <c>MonitorRef</c> is a reference which the calling process
obtained by calling
- <seealso marker="#erlang:monitor/2">erlang:monitor/2</seealso>,
+ <seealso marker="#monitor/2">erlang:monitor/2</seealso>,
this monitoring is turned off. If the monitoring is already
turned off, nothing happens.</p>
<p>Once <c>erlang:demonitor(MonitorRef)</c> has returned it is
@@ -684,7 +726,7 @@ false</pre>
the call, though. Therefore, in most cases, it is advisable
to remove such a <c>'DOWN'</c> message from the message queue
after monitoring has been stopped.
- <seealso marker="#erlang:demonitor/2">erlang:demonitor(MonitorRef, [flush])</seealso> can be used instead of
+ <seealso marker="#demonitor/2">erlang:demonitor(MonitorRef, [flush])</seealso> can be used instead of
<c>erlang:demonitor(MonitorRef)</c> if this cleanup is wanted.</p>
<note>
<p>Prior to OTP release R11B (erts version 5.5) <c>erlang:demonitor/1</c>
@@ -718,7 +760,7 @@ false</pre>
of <c>OptionList</c>.
</p>
<p><c>erlang:demonitor(MonitorRef, [])</c> is equivalent to
- <seealso marker="#erlang:demonitor/1">erlang:demonitor(MonitorRef)</seealso>.</p>
+ <seealso marker="#demonitor/1">erlang:demonitor(MonitorRef)</seealso>.</p>
<p>Currently the following <c>Option</c>s are valid:</p>
<taglist>
<tag><c>flush</c></tag>
@@ -732,10 +774,10 @@ false</pre>
erlang:demonitor(MonitorRef),
receive
-\011{_, MonitorRef, _, _, _} ->
-\011 true
+ {_, MonitorRef, _, _, _} ->
+ true
after 0 ->
-\011 true
+ true
end</code>
</item>
<tag><c>info</c></tag>
@@ -768,7 +810,7 @@ false</pre>
</note>
<p>Failure: <c>badarg</c> if <c>OptionList</c> is not a list, or
if <c>Option</c> is not a valid option, or the same failure as for
- <seealso marker="#erlang:demonitor/1">erlang:demonitor/1</seealso></p>
+ <seealso marker="#demonitor/1">erlang:demonitor/1</seealso></p>
</desc>
</func>
<func>
@@ -1087,7 +1129,7 @@ b</pre>
<c>uniq</c>, and <c>pid</c>. For an external fun, the value
of any of these items is always the atom <c>undefined</c>.</p>
<p>See
- <seealso marker="#erlang:fun_info/1">erlang:fun_info/1</seealso>.</p>
+ <seealso marker="#fun_info/1">erlang:fun_info/1</seealso>.</p>
</desc>
</func>
<func>
@@ -1233,8 +1275,8 @@ b</pre>
returns, for example:</p>
<p><c>{'EXIT',{badarg,Stacktrace}} = catch abs(x)</c></p>
<p>See also
- <seealso marker="#erlang:error/1">erlang:error/1</seealso> and
- <seealso marker="#erlang:error/2">erlang:error/2</seealso>.</p>
+ <seealso marker="#error/1">erlang:error/1</seealso> and
+ <seealso marker="#error/2">erlang:error/2</seealso>.</p>
</desc>
</func>
<func>
@@ -1929,7 +1971,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 +1982,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 +2000,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>
@@ -2282,13 +2325,13 @@ os_prompt%</pre>
other. Values beginning with an uppercase letter is not part
of the result.</p>
<code type="none">
-\011total = processes + system
-\011processes = processes_used + ProcessesNotUsed
-\011system = atom + binary + code + ets + OtherSystem
-\011atom = atom_used + AtomNotUsed
+ total = processes + system
+ processes = processes_used + ProcessesNotUsed
+ system = atom + binary + code + ets + OtherSystem
+ atom = atom_used + AtomNotUsed
-\011RealTotal = processes + RealSystem
-\011RealSystem = system + MissedSystem</code>
+ RealTotal = processes + RealSystem
+ RealSystem = system + MissedSystem</code>
<p>More tuples in the returned list may be added in the future.</p>
<note>
<p>The <c>total</c> value is supposed to be the total amount
@@ -2344,7 +2387,7 @@ os_prompt%</pre>
<item>
If <c>Type</c> is not one of the memory types listed in the
documentation of
- <seealso marker="#erlang:memory/0">erlang:memory/0</seealso>.
+ <seealso marker="#memory/0">erlang:memory/0</seealso>.
</item>
<tag><c>badarg</c></tag>
<item>
@@ -2358,7 +2401,7 @@ os_prompt%</pre>
</item>
</taglist>
<p>See also
- <seealso marker="#erlang:memory/0">erlang:memory/0</seealso>.</p>
+ <seealso marker="#memory/0">erlang:memory/0</seealso>.</p>
</desc>
</func>
<func>
@@ -2467,7 +2510,7 @@ os_prompt%</pre>
</note>
<p>The monitoring is turned off either when the <c>'DOWN'</c>
message is sent, or when
- <seealso marker="#erlang:demonitor/1">erlang:demonitor/1</seealso>
+ <seealso marker="#demonitor/1">erlang:demonitor/1</seealso>
is called.</p>
<p>If an attempt is made to monitor a process on an older node
(where remote process monitoring is not implemented or one
@@ -3336,7 +3379,7 @@ os_prompt%</pre>
registered name, [] is returned.</p>
<p>For valid values of <c>Item</c>, and corresponding
values of <c>Info</c>, see
- <seealso marker="#erlang:port_info/1">erlang:port_info/1</seealso>.</p>
+ <seealso marker="#port_info/1">erlang:port_info/1</seealso>.</p>
<p>Failure: <c>badarg</c> if <c>Port</c> is not a local port.</p>
</desc>
</func>
@@ -3426,9 +3469,13 @@ os_prompt%</pre>
<p>This changes the minimum heap size for the calling
process.</p>
</item>
- <tag><c>process_flag(priority, Level)</c></tag>
+ <tag><c>process_flag(min_bin_vheap_size, MinBinVHeapSize)</c></tag>
+ <item>
+ <p>This changes the minimum binary virtual heap size for the calling
+ process.</p>
+ </item>
+ <tag><marker id="process_flag_priority"><c>process_flag(priority, Level)</c></marker></tag>
<item>
- <marker id="process_flag_priority"></marker>
<p>This sets the process priority. <c>Level</c> is an atom.
There are currently four priority levels: <c>low</c>,
<c>normal</c>, <c>high</c>, and <c>max</c>. The default
@@ -3757,6 +3804,14 @@ os_prompt%</pre>
<p><c>MessageQueue</c> is a list of the messages to
the process, which have not yet been processed.</p>
</item>
+ <tag><c>{min_heap_size, MinHeapSize}</c></tag>
+ <item>
+ <p><c>MinHeapSize</c> is the minimum heap size for the process.</p>
+ </item>
+ <tag><c>{min_bin_vheap_size, MinBinVHeapSize}</c></tag>
+ <item>
+ <p><c>MinBinVHeapSize</c> is the minimum binary virtual heap size for the process.</p>
+ </item>
<tag><c>{monitored_by, Pids}</c></tag>
<item>
<p>A list of pids that are monitoring the process (with
@@ -3812,9 +3867,9 @@ os_prompt%</pre>
ActiveSuspendCount, OutstandingSuspendCount}</c> tuples.
<c>Suspendee</c> is the pid of a process that have been or is to
be suspended by the process identified by <c>Pid</c> via the
- <seealso marker="#erlang:suspend_process/2">erlang:suspend_process/2</seealso>
+ <seealso marker="#suspend_process/2">erlang:suspend_process/2</seealso>
BIF, or the
- <seealso marker="#erlang:suspend_process/1">erlang:suspend_process/1</seealso>
+ <seealso marker="#suspend_process/1">erlang:suspend_process/1</seealso>
BIF. <c>ActiveSuspendCount</c> is the number of times the
<c>Suspendee</c> has been suspended by <c>Pid</c>.
<c>OutstandingSuspendCount</c> is the number of not yet
@@ -3965,19 +4020,19 @@ os_prompt%</pre>
</type>
<desc>
<p><c>TimerRef</c> is a timer reference returned by
- <seealso marker="#erlang:send_after/3">erlang:send_after/3</seealso>
+ <seealso marker="#send_after/3">erlang:send_after/3</seealso>
or
- <seealso marker="#erlang:start_timer/3">erlang:start_timer/3</seealso>.
+ <seealso marker="#start_timer/3">erlang:start_timer/3</seealso>.
If the timer is active, the function returns the time in
milliseconds left until the timer will expire, otherwise
<c>false</c> (which means that <c>TimerRef</c> was never a
timer, that it has been cancelled, or that it has already
delivered its message).</p>
<p>See also
- <seealso marker="#erlang:send_after/3">erlang:send_after/3</seealso>,
- <seealso marker="#erlang:start_timer/3">erlang:start_timer/3</seealso>,
+ <seealso marker="#send_after/3">erlang:send_after/3</seealso>,
+ <seealso marker="#start_timer/3">erlang:start_timer/3</seealso>,
and
- <seealso marker="#erlang:cancel_timer/1">erlang:cancel_timer/1</seealso>.</p>
+ <seealso marker="#cancel_timer/1">erlang:cancel_timer/1</seealso>.</p>
</desc>
</func>
<func>
@@ -4042,9 +4097,9 @@ true</pre>
<p>Decreases the suspend count on the process identified by
<c>Suspendee</c>. <c>Suspendee</c> should previously have been
suspended via
- <seealso marker="#erlang:suspend_process/2">erlang:suspend_process/2</seealso>,
+ <seealso marker="#suspend_process/2">erlang:suspend_process/2</seealso>,
or
- <seealso marker="#erlang:suspend_process/1">erlang:suspend_process/1</seealso>
+ <seealso marker="#suspend_process/1">erlang:suspend_process/1</seealso>
by the process calling <c>erlang:resume_process(Suspendee)</c>. When
the suspend count on <c>Suspendee</c> reach zero, <c>Suspendee</c>
will be resumed, i.e., the state of the <c>Suspendee</c> is changed
@@ -4130,9 +4185,9 @@ true</pre>
<p>Sends a message and returns <c>ok</c>, or does not send
the message but returns something else (see below). Otherwise
the same as
- <seealso marker="#erlang:send/2">erlang:send/2</seealso>. See
+ <seealso marker="#send/2">erlang:send/2</seealso>. See
also
- <seealso marker="#erlang:send_nosuspend/2">erlang:send_nosuspend/2,3</seealso>.
+ <seealso marker="#send_nosuspend/2">erlang:send_nosuspend/2,3</seealso>.
for more detailed explanation and warnings.</p>
<p>The possible options are:</p>
<taglist>
@@ -4178,10 +4233,10 @@ true</pre>
erts version 5.4.11. Note that timers will not be
automatically canceled when <c>Dest</c> is an atom.</p>
<p>See also
- <seealso marker="#erlang:start_timer/3">erlang:start_timer/3</seealso>,
- <seealso marker="#erlang:cancel_timer/1">erlang:cancel_timer/1</seealso>,
+ <seealso marker="#start_timer/3">erlang:start_timer/3</seealso>,
+ <seealso marker="#cancel_timer/1">erlang:cancel_timer/1</seealso>,
and
- <seealso marker="#erlang:read_timer/1">erlang:read_timer/1</seealso>.</p>
+ <seealso marker="#read_timer/1">erlang:read_timer/1</seealso>.</p>
<p>Failure: <c>badarg</c> if the arguments does not satisfy
the requirements specified above.</p>
</desc>
@@ -4197,7 +4252,7 @@ true</pre>
</type>
<desc>
<p>The same as
- <seealso marker="#erlang:send/3">erlang:send(Dest, Msg, [nosuspend])</seealso>, but returns <c>true</c> if
+ <seealso marker="#send/3">erlang:send(Dest, Msg, [nosuspend])</seealso>, but returns <c>true</c> if
the message was sent and <c>false</c> if the message was not
sent because the sender would have had to be suspended.</p>
<p>This function is intended for send operations towards an
@@ -4249,10 +4304,10 @@ true</pre>
</type>
<desc>
<p>The same as
- <seealso marker="#erlang:send/3">erlang:send(Dest, Msg, [nosuspend | Options])</seealso>,
+ <seealso marker="#send/3">erlang:send(Dest, Msg, [nosuspend | Options])</seealso>,
but with boolean return value.</p>
<p>This function behaves like
- <seealso marker="#erlang:send_nosuspend/2">erlang:send_nosuspend/2)</seealso>,
+ <seealso marker="#send_nosuspend/2">erlang:send_nosuspend/2)</seealso>,
but takes a third parameter, a list of options. The only
currently implemented option is <c>noconnect</c>. The option
<c>noconnect</c> makes the function return <c>false</c> if
@@ -4406,7 +4461,7 @@ true</pre>
</desc>
</func>
<func>
- <name>spawn_link(Node, Fun) -></name>
+ <name>spawn_link(Node, Fun) -> pid()</name>
<fsummary>Create and link to a new process with a fun as entry point on a specified node</fsummary>
<type>
<v>Node = node()</v>
@@ -4490,10 +4545,11 @@ true</pre>
<fsummary>Create a new process with a fun as entry point</fsummary>
<type>
<v>Fun = fun()</v>
- <v>Option = link | monitor | {priority, Level} | {fullsweep_after, Number} | {min_heap_size, Size}</v>
+ <v>Option = link | monitor | {priority, Level} | {fullsweep_after, Number} | {min_heap_size, Size} | {min_bin_vheap_size, VSize}</v>
<v>&nbsp;Level = low | normal | high</v>
<v>&nbsp;Number = int()</v>
<v>&nbsp;Size = int()</v>
+ <v>&nbsp;VSize = int()</v>
</type>
<desc>
<p>Returns the pid of a new process started by the application
@@ -4511,10 +4567,11 @@ true</pre>
<type>
<v>Node = node()</v>
<v>Fun = fun()</v>
- <v>Option = link | {priority, Level} | {fullsweep_after, Number} | {min_heap_size, Size}</v>
+ <v>Option = link | {priority, Level} | {fullsweep_after, Number} | {min_heap_size, Size} | {min_bin_vheap_size, VSize}</v>
<v>&nbsp;Level = low | normal | high</v>
<v>&nbsp;Number = int()</v>
<v>&nbsp;Size = int()</v>
+ <v>&nbsp;VSize = int()</v>
</type>
<desc>
<p>Returns the pid of a new process started by the application
@@ -4530,10 +4587,11 @@ true</pre>
<type>
<v>Module = Function = atom()</v>
<v>Args = [term()]</v>
- <v>Option = link | monitor | {priority, Level} | {fullsweep_after, Number} | {min_heap_size, Size}</v>
+ <v>Option = link | monitor | {priority, Level} | {fullsweep_after, Number} | {min_heap_size, Size} | {min_bin_vheap_size, VSize}</v>
<v>&nbsp;Level = low | normal | high</v>
<v>&nbsp;Number = int()</v>
<v>&nbsp;Size = int()</v>
+ <v>&nbsp;VSize = int()</v>
</type>
<desc>
<p>Works exactly like
@@ -4551,7 +4609,7 @@ true</pre>
<tag><c>monitor</c></tag>
<item>
<p>Monitor the new process (just like
- <seealso marker="#erlang:monitor/2">erlang:monitor/2</seealso> does).</p>
+ <seealso marker="#monitor/2">erlang:monitor/2</seealso> does).</p>
</item>
<tag><c>{priority, Level}</c></tag>
<item>
@@ -4594,7 +4652,7 @@ true</pre>
and no virtual memory, one might want to preserve memory
by setting <c>Number</c> to zero. (The value may be set
globally, see
- <seealso marker="#erlang:system_flag/2">erlang:system_flag/2</seealso>.)</p>
+ <seealso marker="#system_flag/2">erlang:system_flag/2</seealso>.)</p>
</item>
<tag><c>{min_heap_size, Size}</c></tag>
<item>
@@ -4613,6 +4671,23 @@ true</pre>
fine-tuning an application and to measure the execution
time with various <c>Size</c> values.</p>
</item>
+ <tag><c>{min_bin_vheap_size, VSize}</c></tag>
+ <item>
+ <p>This option is only useful for performance tuning.
+ In general, you should not use this option unless you
+ know that there is problem with execution times and/or
+ memory consumption, and you should measure to make sure
+ that the option improved matters.
+ </p>
+ <p>Gives a minimum binary virtual heap size in words. Setting this value
+ higher than the system default might speed up some
+ processes because less garbage collection is done.
+ Setting too high value, however, might waste memory.
+ Therefore, it is recommended to use this option only for
+ fine-tuning an application and to measure the execution
+ time with various <c>VSize</c> values.</p>
+ </item>
+
</taglist>
</desc>
</func>
@@ -4623,10 +4698,11 @@ true</pre>
<v>Node = node()</v>
<v>Module = Function = atom()</v>
<v>Args = [term()]</v>
- <v>Option = link | {priority, Level} | {fullsweep_after, Number} | {min_heap_size, Size}</v>
+ <v>Option = link | {priority, Level} | {fullsweep_after, Number} | {min_heap_size, Size} | {min_bin_vheap_size, VSize}</v>
<v>&nbsp;Level = low | normal | high</v>
<v>&nbsp;Number = int()</v>
<v>&nbsp;Size = int()</v>
+ <v>&nbsp;VSize = int()</v>
</type>
<desc>
<p>Returns the pid of a new process started by the application
@@ -4641,7 +4717,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
@@ -4687,10 +4763,10 @@ true</pre>
erts version 5.4.11. Note that timers will not be
automatically canceled when <c>Dest</c> is an atom.</p>
<p>See also
- <seealso marker="#erlang:send_after/3">erlang:send_after/3</seealso>,
- <seealso marker="#erlang:cancel_timer/1">erlang:cancel_timer/1</seealso>,
+ <seealso marker="#send_after/3">erlang:send_after/3</seealso>,
+ <seealso marker="#cancel_timer/1">erlang:cancel_timer/1</seealso>,
and
- <seealso marker="#erlang:read_timer/1">erlang:read_timer/1</seealso>.</p>
+ <seealso marker="#read_timer/1">erlang:read_timer/1</seealso>.</p>
<p>Failure: <c>badarg</c> if the arguments does not satisfy
the requirements specified above.</p>
</desc>
@@ -4711,9 +4787,8 @@ true</pre>
<c>ContextSwitches</c> is the total number of context
switches since the system started.</p>
</item>
- <tag><c>exact_reductions</c></tag>
+ <tag><marker id="statistics_exact_reductions"><c>exact_reductions</c></marker></tag>
<item>
- <marker id="statistics_exact_reductions"></marker>
<p>Returns
<c>{Total_Exact_Reductions, Exact_Reductions_Since_Last_Call}</c>.</p>
<p><em>NOTE:</em><c>statistics(exact_reductions)</c> is
@@ -4733,9 +4808,8 @@ true</pre>
through ports, and <c>Output</c> is the total number of
bytes output to ports.</p>
</item>
- <tag><c>reductions</c></tag>
+ <tag><marker id="statistics_reductions"><c>reductions</c></marker></tag>
<item>
- <marker id="statistics_reductions"></marker>
<p>Returns
<c>{Total_Reductions, Reductions_Since_Last_Call}</c>.</p>
<p><em>NOTE:</em> From erts version 5.5 (OTP release R11B)
@@ -4795,7 +4869,7 @@ true</pre>
process will not leave the suspended state until its suspend
count reach zero. The suspend count of <c>Suspendee</c> is
decreased when
- <seealso marker="#erlang:resume_process/1">erlang:resume_process(Suspendee)</seealso>
+ <seealso marker="#resume_process/1">erlang:resume_process(Suspendee)</seealso>
is called by the same process that called
<c>erlang:suspend_process(Suspendee)</c>. All increased suspend
counts on other processes acquired by a process will automatically be
@@ -4884,7 +4958,7 @@ true</pre>
<desc>
<p>Suspends the process identified by <c>Suspendee</c>. The
same as calling
- <seealso marker="#erlang:suspend_process/2">erlang:suspend_process(Suspendee, [])</seealso>. For more information see the documentation of <seealso marker="#erlang:suspend_process/2">erlang:suspend_process/2</seealso>.
+ <seealso marker="#suspend_process/2">erlang:suspend_process(Suspendee, [])</seealso>. For more information see the documentation of <seealso marker="#suspend_process/2">erlang:suspend_process/2</seealso>.
</p>
<warning>
<p>This BIF is intended for debugging only.</p>
@@ -4906,9 +4980,8 @@ true</pre>
<p>Sets the maximum depth of call stack back-traces in the
exit reason element of <c>'EXIT'</c> tuples.</p>
</item>
- <tag><c>erlang:system_flag(cpu_topology, CpuTopology)</c></tag>
+ <tag><marker id="system_flag_cpu_topology"><c>erlang:system_flag(cpu_topology, CpuTopology)</c></marker></tag>
<item>
- <marker id="system_flag_cpu_topology"></marker>
<p>Sets the user defined <c>CpuTopology</c>. The user defined
CPU topology will override any automatically detected
CPU topology. By passing <c>undefined</c> as <c>CpuTopology</c>
@@ -4959,9 +5032,19 @@ true</pre>
<seealso marker="#spawn_opt/4">spawn_opt/N</seealso> or
<seealso marker="#process_flag/2">process_flag/2</seealso>. </p>
</item>
- <tag><c>erlang:system_flag(multi_scheduling, BlockState)</c></tag>
+ <tag><c>erlang:system_flag(min_bin_vheap_size, MinBinVHeapSize)</c></tag>
+ <item>
+ <p>Sets the default minimum binary virtual heap size for processes. The
+ size is given in words. The new <c>min_bin_vhheap_size</c> only
+ effects processes spawned after the change of
+ <c>min_bin_vhheap_size</c> has been made.
+ The <c>min_bin_vheap_size</c> can be set for individual
+ processes by use of
+ <seealso marker="#spawn_opt/4">spawn_opt/N</seealso> or
+ <seealso marker="#process_flag/2">process_flag/2</seealso>. </p>
+ </item>
+ <tag><marker id="system_flag_multi_scheduling"><c>erlang:system_flag(multi_scheduling, BlockState)</c></marker></tag>
<item>
- <marker id="system_flag_multi_scheduling"></marker>
<p><c>BlockState = block | unblock</c></p>
<p>If multi-scheduling is enabled, more than one scheduler
thread is used by the emulator. Multi-scheduling can be
@@ -4995,9 +5078,8 @@ true</pre>
<seealso marker="#system_info_multi_scheduling_blockers">erlang:system_info(multi_scheduling_blockers)</seealso>, and
<seealso marker="#system_info_schedulers">erlang:system_info(schedulers)</seealso>.</p>
</item>
- <tag><c>erlang:system_flag(scheduler_bind_type, How)</c></tag>
+ <tag><marker id="system_flag_scheduler_bind_type"><c>erlang:system_flag(scheduler_bind_type, How)</c></marker></tag>
<item>
- <marker id="system_flag_scheduler_bind_type"></marker>
<p>Controls if and how schedulers are bound to logical
processors.</p>
<p>When <c>erlang:system_flag(scheduler_bind_type, How)</c> is
@@ -5124,9 +5206,8 @@ true</pre>
<seealso marker="#system_flag_cpu_topology">erlang:system_flag(cpu_topology, CpuTopology)</seealso>.
</p>
</item>
- <tag><c>erlang:system_flag(schedulers_online, SchedulersOnline)</c></tag>
+ <tag><marker id="system_flag_schedulers_online"><c>erlang:system_flag(schedulers_online, SchedulersOnline)</c></marker></tag>
<item>
- <marker id="system_flag_schedulers_online"></marker>
<p>Sets the amount of schedulers online. Valid range is
<![CDATA[1 <= SchedulerId <= erlang:system_info(schedulers)]]>.
</p>
@@ -5164,9 +5245,8 @@ true</pre>
<p>Returns various information about the current system
(emulator) as specified by <c>Type</c>:</p>
<taglist>
- <tag><c>allocated_areas</c></tag>
+ <tag><marker id="system_info_allocated_areas"><c>allocated_areas</c></marker></tag>
<item>
- <marker id="system_info_allocated_areas"></marker>
<p>Returns a list of tuples with information about
miscellaneous allocated memory areas.</p>
<p>Each tuple contains an atom describing type of memory as
@@ -5184,11 +5264,10 @@ true</pre>
Some values are part of other values, and some memory
areas are not part of the result. If you are interested
in the total amount of memory allocated by the emulator
- see <seealso marker="#erlang:memory/0">erlang:memory/0,1</seealso>.</p>
+ see <seealso marker="#memory/0">erlang:memory/0,1</seealso>.</p>
</item>
- <tag><c>allocator</c></tag>
+ <tag><marker id="system_info_allocator"><c>allocator</c></marker></tag>
<item>
- <marker id="system_info_allocator"></marker>
<p>Returns <c>{Allocator, Version, Features, Settings}.</c></p>
<p>Types:</p>
<list type="bulleted">
@@ -5229,9 +5308,8 @@ true</pre>
<p>See also "System Flags Effecting erts_alloc" in
<seealso marker="erts:erts_alloc#flags">erts_alloc(3)</seealso>.</p>
</item>
- <tag><c>alloc_util_allocators</c></tag>
+ <tag><marker id="system_info_alloc_util_allocators"><c>alloc_util_allocators</c></marker></tag>
<item>
- <marker id="system_info_alloc_util_allocators"></marker>
<p>Returns a list of the names of all allocators
using the ERTS internal <c>alloc_util</c> framework
as atoms. For more information see the
@@ -5240,9 +5318,8 @@ true</pre>
erts_alloc(3)</seealso> documentation.
</p>
</item>
- <tag><c>{allocator, Alloc}</c></tag>
+ <tag><marker id="system_info_allocator_tuple"><c>{allocator, Alloc}</c></marker></tag>
<item>
- <marker id="system_info_allocator_tuple"></marker>
<p>Returns information about the specified allocator.
As of erts version 5.6.1 the return value is a list
of <c>{instance, InstanceNo, InstanceInfo}</c> tuples
@@ -5278,9 +5355,8 @@ true</pre>
values. The first value is memory pool size and
the second value used memory size.</p>
</item>
- <tag><c>{allocator_sizes, Alloc}</c></tag>
+ <tag><marker id="system_info_allocator_sizes"><c>{allocator_sizes, Alloc}</c></marker></tag>
<item>
- <marker id="system_info_allocator_sizes"></marker>
<p>Returns various size information for the specified
allocator. The information returned is a subset of the
information returned by
@@ -5314,9 +5390,8 @@ true</pre>
line flag <c>+R</c>, see
<seealso marker="erts:erl#compat_rel">erl(1)</seealso>.</p>
</item>
- <tag><c>cpu_topology</c></tag>
+ <tag><marker id="system_info_cpu_topology"><c>cpu_topology</c></marker></tag>
<item>
- <marker id="system_info_cpu_topology"></marker>
<p>Returns the <c>CpuTopology</c> which currently is used by the
emulator. The CPU topology is used when binding schedulers
to logical processors. The CPU topology used is the user defined
@@ -5499,7 +5574,7 @@ true</pre>
<c>spawn</c> or <c>spawn_link</c> will use these
garbage collection settings. The default settings can be
changed by use of
- <seealso marker="#erlang:system_flag/2">system_flag/2</seealso>.
+ <seealso marker="#system_flag/2">system_flag/2</seealso>.
<seealso marker="#spawn_opt/4">spawn_opt/4</seealso>
can spawn a process that does not use the default
settings.</p>
@@ -5570,6 +5645,16 @@ true</pre>
<item>
<p>Returns a string containing the Erlang machine name.</p>
</item>
+ <tag><c>min_heap_size</c></tag>
+ <item>
+ <p>Returns <c>{min_heap_size, MinHeapSize}</c> where <c>MinHeapSize</c> is the current system wide
+ minimum heap size for spawned processes.</p>
+ </item>
+ <tag><c>min_bin_vheap_size</c></tag>
+ <item>
+ <p>Returns <c>{min_bin_vheap_size, MinBinVHeapSize}</c> where <c>MinBinVHeapSize</c> is the current system wide
+ minimum binary virtual heap size for spawned processes.</p>
+ </item>
<tag><c>modified_timing_level</c></tag>
<item>
<p>Returns the modified timing level (an integer) if
@@ -5579,9 +5664,8 @@ true</pre>
<seealso marker="erts:erl#+T">erl(1)</seealso>
command for more information on modified timing.</p>
</item>
- <tag><c>multi_scheduling</c></tag>
+ <tag><marker id="system_info_multi_scheduling"><c>multi_scheduling</c></marker></tag>
<item>
- <marker id="system_info_multi_scheduling"></marker>
<p>Returns <c>disabled</c>, <c>blocked</c>, or <c>enabled</c>.
A description of the return values:</p>
<taglist>
@@ -5610,9 +5694,8 @@ true</pre>
<seealso marker="#system_info_multi_scheduling_blockers">erlang:system_info(multi_scheduling_blockers)</seealso>, and
<seealso marker="#system_info_schedulers">erlang:system_info(schedulers)</seealso>.</p>
</item>
- <tag><c>multi_scheduling_blockers</c></tag>
+ <tag><marker id="system_info_multi_scheduling_blockers"><c>multi_scheduling_blockers</c></marker></tag>
<item>
- <marker id="system_info_multi_scheduling_blockers"></marker>
<p>Returns a list of <c>PID</c>s when multi-scheduling
is blocked; otherwise, the empty list. The <c>PID</c>s
in the list is <c>PID</c>s of the processes currently
@@ -5623,9 +5706,8 @@ true</pre>
<seealso marker="#system_info_multi_scheduling">erlang:system_info(multi_scheduling)</seealso>, and
<seealso marker="#system_info_schedulers">erlang:system_info(schedulers)</seealso>.</p>
</item>
- <tag><c>otp_release</c></tag>
+ <tag><marker id="system_info_otp_release"><c>otp_release</c></marker></tag>
<item>
- <marker id="system_info_otp_release"></marker>
<p>Returns a string containing the OTP release number.</p>
</item>
<tag><c>process_count</c></tag>
@@ -5649,9 +5731,8 @@ true</pre>
information see the <seealso marker="erts:crash_dump">"How to interpret the Erlang crash dumps"</seealso> chapter
in the ERTS User's Guide.</p>
</item>
- <tag><c>scheduler_bind_type</c></tag>
+ <tag><marker id="system_info_scheduler_bind_type"><c>scheduler_bind_type</c></marker></tag>
<item>
- <marker id="system_info_scheduler_bind_type"></marker>
<p>Returns information on how user has requested
schedulers to be bound or not bound.</p>
<p><em>NOTE:</em> Even though user has requested
@@ -5666,9 +5747,8 @@ true</pre>
<seealso marker="#system_info_scheduler_bindings">erlang:system_info(scheduler_bindings)</seealso>.
</p>
</item>
- <tag><c>scheduler_bindings</c></tag>
+ <tag><marker id="system_info_scheduler_bindings"><c>scheduler_bindings</c></marker></tag>
<item>
- <marker id="system_info_scheduler_bindings"></marker>
<p>Returns information on currently used scheduler
bindings.</p>
<p>A tuple of a size equal to
@@ -5690,18 +5770,16 @@ true</pre>
<seealso marker="#system_info_schedulers_online">erlang:system_info(schedulers_online)</seealso>.
</p>
</item>
- <tag><c>scheduler_id</c></tag>
+ <tag><marker id="system_info_scheduler_id"><c>scheduler_id</c></marker></tag>
<item>
- <marker id="system_info_scheduler_id"></marker>
<p>Returns the scheduler id (<c>SchedulerId</c>) of the
scheduler thread that the calling process is executing
on. <c>SchedulerId</c> is a positive integer; where
<c><![CDATA[1 <= SchedulerId <= erlang:system_info(schedulers)]]></c>. See also
<seealso marker="#system_info_schedulers">erlang:system_info(schedulers)</seealso>.</p>
</item>
- <tag><c>schedulers</c></tag>
+ <tag><marker id="system_info_schedulers"><c>schedulers</c></marker></tag>
<item>
- <marker id="system_info_schedulers"></marker>
<p>Returns the number of scheduler threads used by
the emulator. Scheduler threads online schedules Erlang
processes and Erlang ports, and execute Erlang code
@@ -5717,9 +5795,8 @@ true</pre>
<seealso marker="#system_info_multi_scheduling">erlang:system_info(multi_scheduling)</seealso>, and
and <seealso marker="#system_info_multi_scheduling_blockers">erlang:system_info(multi_scheduling_blockers)</seealso>.</p>
</item>
- <tag><c>schedulers_online</c></tag>
+ <tag><marker id="system_info_schedulers_online"><c>schedulers_online</c></marker></tag>
<item>
- <marker id="system_info_schedulers_online"></marker>
<p>Returns the amount of schedulers online. The scheduler
identifiers of schedulers online satisfy the following
relationship:
@@ -5752,9 +5829,8 @@ true</pre>
with thread support; otherwise, <c>false</c> is
returned.</p>
</item>
- <tag><c>thread_pool_size</c></tag>
+ <tag><marker id="system_info_thread_pool_size"><c>thread_pool_size</c></marker></tag>
<item>
- <marker id="system_info_thread_pool_size"></marker>
<p>Returns the number of async threads in the async thread
pool used for asynchronous driver calls
(<seealso marker="erts:erl_driver#driver_async">driver_async()</seealso>)
@@ -5767,9 +5843,8 @@ true</pre>
<c>get_tcw</c> in "Match Specifications in Erlang",
<seealso marker="erts:match_spec#get_tcw">ERTS User's Guide</seealso>.</p>
</item>
- <tag><c>version</c></tag>
+ <tag><marker id="system_info_version"><c>version</c></marker></tag>
<item>
- <marker id="system_info_version"></marker>
<p>Returns a string containing the version number of the
emulator.</p>
</item>
@@ -5802,7 +5877,7 @@ true</pre>
</type>
<desc>
<p>Returns the current system monitoring settings set by
- <seealso marker="#erlang:system_monitor/2">erlang:system_monitor/2</seealso>
+ <seealso marker="#system_monitor/2">erlang:system_monitor/2</seealso>
as <c>{MonitorPid, Options}</c>, or <c>undefined</c> if there
are no settings. The order of the options may be different
from the one that was set.</p>
@@ -5820,9 +5895,9 @@ true</pre>
system performance monitoring settings are cleared.</p>
<p>Calling the function with <c>{MonitorPid, Options}</c> as
argument, is the same as calling
- <seealso marker="#erlang:system_monitor/2">erlang:system_monitor(MonitorPid, Options)</seealso>.</p>
+ <seealso marker="#system_monitor/2">erlang:system_monitor(MonitorPid, Options)</seealso>.</p>
<p>Returns the previous system monitor settings just like
- <seealso marker="#erlang:system_monitor/0">erlang:system_monitor/0</seealso>.</p>
+ <seealso marker="#system_monitor/0">erlang:system_monitor/0</seealso>.</p>
</desc>
</func>
@@ -5858,7 +5933,7 @@ true</pre>
explained in the documentation of the
<seealso marker="#gc_start">gc_start</seealso>
trace message (see
- <seealso marker="#erlang:trace/3">erlang:trace/3</seealso>).
+ <seealso marker="#trace/3">erlang:trace/3</seealso>).
New tuples may be added, and the order of the tuples in
the <c>Info</c> list may be changed at any time without prior
notice.
@@ -5900,7 +5975,7 @@ true</pre>
</item>
</taglist>
<p>Returns the previous system monitor settings just like
- <seealso marker="#erlang:system_monitor/0">erlang:system_monitor/0</seealso>.</p>
+ <seealso marker="#system_monitor/0">erlang:system_monitor/0</seealso>.</p>
<note>
<p>If a monitoring process gets so large that it itself
starts to cause system monitor messages when garbage
@@ -5924,7 +5999,7 @@ true</pre>
</type>
<desc>
<p>Returns the current system profiling settings set by
- <seealso marker="#erlang:system_profile/2">erlang:system_profile/2</seealso>
+ <seealso marker="#system_profile/2">erlang:system_profile/2</seealso>
as <c>{ProfilerPid, Options}</c>, or <c>undefined</c> if there
are no settings. The order of the options may be different
from the one that was set.</p>
@@ -6152,7 +6227,7 @@ true</pre>
<item>
<p>Trace certain function calls. Specify which function
calls to trace by calling
- <seealso marker="#erlang:trace_pattern/3">erlang:trace_pattern/3</seealso>.</p>
+ <seealso marker="#trace_pattern/3">erlang:trace_pattern/3</seealso>.</p>
<p>Message tags: <c>call</c>, <c>return_from</c>.</p>
</item>
<tag><c>silent</c></tag>
@@ -6181,7 +6256,7 @@ true</pre>
Trace the actual return from a traced function back to
its caller. Only works for functions traced with
the <c>local</c> option to
- <seealso marker="#erlang:trace_pattern/3">erlang:trace_pattern/3</seealso>.</p>
+ <seealso marker="#trace_pattern/3">erlang:trace_pattern/3</seealso>.</p>
<p>The semantics is that a trace message is sent when a
call traced function actually returns, that is, when a
chain of tail recursive calls is ended. There will be
@@ -6379,9 +6454,8 @@ true</pre>
the current function cannot be determined, then the last
element <c>Arity</c> is 0.</p>
</item>
- <tag><c>{trace, Pid, gc_start, Info}</c></tag>
+ <tag><marker id="gc_start"><c>{trace, Pid, gc_start, Info}</c></marker></tag>
<item>
- <marker id="gc_start"></marker>
<p>Sent when garbage collection is about to be started.
<c>Info</c> is a list of two-element tuples, where
the first element is a key, and the second is the value.
@@ -6406,6 +6480,19 @@ true</pre>
<tag><c>mbuf_size</c></tag>
<item>The combined size of message buffers associated with
the process.</item>
+
+ <tag><c>bin_vheap_size</c></tag>
+ <item>The total size of unique off-heap binaries referenced from the process heap.</item>
+ <tag><c>bin_vheap_block_size</c></tag>
+ <item>The total size of binaries, in words, allowed in the virtual
+ heap in the process before doing a garbage collection. </item>
+ <tag><c>bin_old_vheap_size</c></tag>
+ <item>The total size of unique off-heap binaries referenced from the process old heap.</item>
+ <tag><c>bin_vheap_block_size</c></tag>
+ <item>The total size of binaries, in words, allowed in the virtual
+ old heap in the process before doing a garbage collection. </item>
+
+
</taglist>
<p>All sizes are in words.</p>
</item>
@@ -6556,7 +6643,7 @@ true</pre>
<c>true</c> for the pseudo function <c>on_load</c> if call
count tracing is active. Return <c>false</c> otherwise.
See also
- <seealso marker="#erlang:trace_pattern/3">erlang:trace_pattern/3</seealso>.</p>
+ <seealso marker="#trace_pattern/3">erlang:trace_pattern/3</seealso>.</p>
</item>
<tag><c>all</c></tag>
<item>
@@ -6579,7 +6666,7 @@ true</pre>
<fsummary>Set trace patterns for global call tracing</fsummary>
<desc>
<p>The same as
- <seealso marker="#erlang:trace_pattern/3">erlang:trace_pattern(MFA, MatchSpec, [])</seealso>,
+ <seealso marker="#trace_pattern/3">erlang:trace_pattern(MFA, MatchSpec, [])</seealso>,
retained for backward compatibility.</p>
</desc>
</func>
@@ -6592,7 +6679,7 @@ true</pre>
<desc>
<p>This BIF is used to enable or disable call tracing for
exported functions. It must be combined with
- <seealso marker="#erlang:trace/3">erlang:trace/3</seealso>
+ <seealso marker="#trace/3">erlang:trace/3</seealso>
to set the <c>call</c> trace flag for one or more processes.</p>
<p>Conceptually, call tracing works like this: Inside
the Erlang virtual machine there is a set of processes to be
@@ -6602,7 +6689,7 @@ true</pre>
in the traced function set, the trace action will be taken.
Otherwise, nothing will happen.</p>
<p>Use
- <seealso marker="#erlang:trace/3">erlang:trace/3</seealso> to
+ <seealso marker="#trace/3">erlang:trace/3</seealso> to
add or remove one or more processes to the set of traced
processes. Use <c>erlang:trace_pattern/2</c> to add or remove
exported functions to the set of traced functions.</p>
@@ -6719,7 +6806,7 @@ true</pre>
counters can be restarted from zero with
<c>MatchSpec == restart</c>.</p>
<p>The counter value can be read with
- <seealso marker="#erlang:trace_info/2">erlang:trace_info/2</seealso>.</p>
+ <seealso marker="#trace_info/2">erlang:trace_info/2</seealso>.</p>
</item>
</taglist>
<p>The <c>global</c> and <c>local</c> options are mutually
@@ -6739,7 +6826,7 @@ true</pre>
specification list. If a function has a match specification,
you can replace it with a completely new one. If you need to
change an existing match specification, use the
- <seealso marker="#erlang:trace_info/2">erlang:trace_info/2</seealso>
+ <seealso marker="#trace_info/2">erlang:trace_info/2</seealso>
BIF to retrieve the existing match specification.</p>
<p>Returns the number of exported functions that matched
the <c>MFA</c> argument. This will be zero if none matched at
@@ -6854,10 +6941,10 @@ true</pre>
unlink(Id),
receive
-\011{'EXIT', Id, _} ->
-\011 true
+ {'EXIT', Id, _} ->
+ true
after 0 ->
-\011 true
+ true
end</code>
<note>
<p>Prior to OTP release R11B (erts version 5.5) <c>unlink/1</c>
diff --git a/erts/doc/src/erlc.xml b/erts/doc/src/erlc.xml
index 3859ac8365..1e8960c22c 100644
--- a/erts/doc/src/erlc.xml
+++ b/erts/doc/src/erlc.xml
@@ -4,7 +4,7 @@
<comref>
<header>
<copyright>
- <year>1997</year><year>2009</year>
+ <year>1997</year><year>2010</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
@@ -13,12 +13,12 @@
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>erlc</title>
@@ -104,6 +104,10 @@
must be quoted. Terms which contain spaces
must be quoted on all platforms.</p>
</item>
+ <tag>-W<em>error</em></tag>
+ <item>
+ <p>Makes all warnings into errors.</p>
+ </item>
<tag>-W<em>number</em></tag>
<item>
<p>Sets warning level to <em>number</em>. Default is <c><![CDATA[1]]></c>.
diff --git a/erts/doc/src/erlsrv.xml b/erts/doc/src/erlsrv.xml
index 93db56fc7c..0dfad2a112 100644
--- a/erts/doc/src/erlsrv.xml
+++ b/erts/doc/src/erlsrv.xml
@@ -4,7 +4,7 @@
<comref>
<header>
<copyright>
- <year>1998</year><year>2009</year>
+ <year>1998</year><year>2010</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
@@ -13,12 +13,12 @@
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>erlsrv</title>
@@ -251,7 +251,7 @@
necessarily the same as the interactive users. The service
runs as the local administrator. All arguments should be given
together in one string, use double quotes (") to give an
- argument string containing spaces and use quoted quotes (\\")
+ argument string containing spaces and use quoted quotes (\")
to give an quote within the argument string if
necessary.</item>
<tag>-i[nternalservicename] [&lt;internal name&gt;]</tag>
@@ -356,7 +356,7 @@ The environment of an Erlang machine started
*/
BOOL WINAPI service_aware_handler(DWORD ctrl){
if(ctrl == CTRL_LOGOFF_EVENT)
-\011return TRUE;
+ return TRUE;
return FALSE;
}
@@ -368,10 +368,10 @@ void initialize_handler(void){
*/
if(GetEnvironmentVariable("ERLSRV_SERVICE_NAME",buffer,
(DWORD) 2)){
-\011/*
-\011** Actually set the control handler
-\011*/
-\011SetConsoleCtrlHandler(&service_aware_handler, TRUE);
+ /*
+ ** Actually set the control handler
+ */
+ SetConsoleCtrlHandler(&service_aware_handler, TRUE);
}
} ]]></code>
</section>
@@ -388,8 +388,8 @@ void initialize_handler(void){
the runtime system should not need to overwrite existing (and probably
used) executables.</p>
<p>To easily manipulate the Erlang services, put
- the <c><![CDATA[<erlang_root>\\erts-<version>\\bin]]></c> directory in
- the path instead of <c><![CDATA[<erlang_root>\\bin]]></c>. The erlsrv program
+ the <c><![CDATA[<erlang_root>\erts-<version>\bin]]></c> directory in
+ the path instead of <c><![CDATA[<erlang_root>\bin]]></c>. The erlsrv program
can be found from inside Erlang by using the
<c><![CDATA[os:find_executable/1]]></c> Erlang function.</p>
<p>For release handling to work, use <c><![CDATA[start_erl]]></c> as the Erlang
diff --git a/erts/doc/src/erts_alloc.xml b/erts/doc/src/erts_alloc.xml
index d51e5b3ea4..51a4a2bca0 100644
--- a/erts/doc/src/erts_alloc.xml
+++ b/erts/doc/src/erts_alloc.xml
@@ -4,7 +4,7 @@
<cref>
<header>
<copyright>
- <year>2002</year><year>2009</year>
+ <year>2002</year><year>2010</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
@@ -13,12 +13,12 @@
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>erts_alloc</title>
@@ -122,7 +122,7 @@
size (<seealso marker="#M_lmbcs">lmbcs</seealso>), the smallest
multiblock carrier size (<seealso marker="#M_smbcs">smbcs</seealso>),
and the multiblock carrier growth stages
- (<seealso marker="#M_smbcs">mbcgs</seealso>) parameters. If
+ (<seealso marker="#M_mbcgs">mbcgs</seealso>) parameters. If
<c>nc</c> is the current number of multiblock carriers (the main
multiblock carrier excluded) managed by an allocator, the size
of the next <c>mseg_alloc</c> multiblock carrier allocated by
@@ -229,29 +229,25 @@
<p>The following flags are available for configuration of
<c>mseg_alloc</c>:</p>
<taglist>
- <tag><c><![CDATA[+MMamcbf <size>]]></c></tag>
- <item> <marker id="MMamcbf"></marker>
-
+ <tag><marker id="MMamcbf"><c><![CDATA[+MMamcbf <size>]]></c></marker></tag>
+ <item>
Absolute max cache bad fit (in kilobytes). A segment in the
memory segment cache is not reused if its size exceeds the
requested size with more than the value of this
parameter. Default value is 4096. </item>
- <tag><c><![CDATA[+MMrmcbf <ratio>]]></c></tag>
- <item> <marker id="MMrmcbf"></marker>
-
+ <tag><marker id="MMrmcbf"><c><![CDATA[+MMrmcbf <ratio>]]></c></marker></tag>
+ <item>
Relative max cache bad fit (in percent). A segment in the
memory segment cache is not reused if its size exceeds the
requested size with more than relative max cache bad fit
percent of the requested size. Default value is 20.</item>
- <tag><c><![CDATA[+MMmcs <amount>]]></c></tag>
- <item> <marker id="MMmcs"></marker>
-
+ <tag><marker id="MMmcs"><c><![CDATA[+MMmcs <amount>]]></c></marker></tag>
+ <item>
Max cached segments. The maximum number of memory segments
stored in the memory segment cache. Valid range is
0-30. Default value is 5.</item>
- <tag><c><![CDATA[+MMcci <time>]]></c></tag>
- <item> <marker id="MMcci"></marker>
-
+ <tag><marker id="MMcci"><c><![CDATA[+MMcci <time>]]></c></marker></tag>
+ <item>
Cache check interval (in milliseconds). The memory segment
cache is checked for segments to destroy at an interval
determined by this parameter. Default value is 1000.</item>
@@ -259,26 +255,23 @@
<p>The following flags are available for configuration of
<c>fix_alloc</c>:</p>
<taglist>
- <tag><c>+MFe true</c></tag>
- <item> <marker id="MFe"></marker>
-
+ <tag><marker id="MFe"><c>+MFe true</c></marker></tag>
+ <item>
Enable <c>fix_alloc</c>. Note: <c>fix_alloc</c> cannot be disabled.</item>
</taglist>
<p>The following flags are available for configuration of
<c>sys_alloc</c>:</p>
<taglist>
- <tag><c>+MYe true</c></tag>
- <item> <marker id="MYe"></marker>
-
+ <tag><marker id="MYe"><c>+MYe true</c></marker></tag>
+ <item>
Enable <c>sys_alloc</c>. Note: <c>sys_alloc</c> cannot be disabled.</item>
- <tag><c>+MYm libc</c></tag>
- <item> <marker id="MYm"></marker>
-<c>malloc</c> library to use. Currently only
+ <tag><marker id="MYm"><c>+MYm libc</c></marker></tag>
+ <item>
+ <c>malloc</c> library to use. Currently only
<c>libc</c> is available. <c>libc</c> enables the standard
<c>libc</c> malloc implementation. By default <c>libc</c> is used.</item>
- <tag><c><![CDATA[+MYtt <size>]]></c></tag>
- <item> <marker id="MYtt"></marker>
-
+ <tag><marker id="MYtt"><c><![CDATA[+MYtt <size>]]></c></marker></tag>
+ <item>
Trim threshold size (in kilobytes). This is the maximum amount
of free memory at the top of the heap (allocated by
<c>sbrk</c>) that will be kept by <c>malloc</c> (not
@@ -289,9 +282,8 @@
trim threshold is 128. <em>Note:</em> This flag will
only have any effect when the emulator has been linked with
the GNU C library, and uses its <c>malloc</c> implementation.</item>
- <tag><c><![CDATA[+MYtp <size>]]></c></tag>
- <item> <marker id="MYtp"></marker>
-
+ <tag><marker id="MYtp"><c><![CDATA[+MYtp <size>]]></c></marker></tag>
+ <item>
Top pad size (in kilobytes). This is the amount of extra
memory that will be allocated by <c>malloc</c> when
<c>sbrk</c> is called to get more memory from the operating
@@ -308,43 +300,37 @@
subsystem identifier, only the specific allocator identified will be
effected:</p>
<taglist>
- <tag><c><![CDATA[+M<S>as bf|aobf|gf|af]]></c></tag>
- <item> <marker id="M_as"></marker>
-
+ <tag><marker id="M_as"><c><![CDATA[+M<S>as bf|aobf|gf|af]]></c></marker></tag>
+ <item>
Allocation strategy. Valid strategies are <c>bf</c> (best fit),
<c>aobf</c> (address order best fit), <c>gf</c> (good fit),
and <c>af</c> (a fit). See
<seealso marker="#strategy">the description of allocation strategies</seealso> in "the <c>alloc_util</c> framework" section.</item>
- <tag><c><![CDATA[+M<S>asbcst <size>]]></c></tag>
- <item> <marker id="M_asbcst"></marker>
-
+ <tag><marker id="M_asbcst"><c><![CDATA[+M<S>asbcst <size>]]></c></marker></tag>
+ <item>
Absolute singleblock carrier shrink threshold (in
kilobytes). When a block located in an
<c>mseg_alloc</c> singleblock carrier is shrunk, the carrier
will be left unchanged if the amount of unused memory is less
than this threshold; otherwise, the carrier will be shrunk.
See also <seealso marker="#M_rsbcst">rsbcst</seealso>.</item>
- <tag><c><![CDATA[+M<S>e true|false]]></c></tag>
- <item> <marker id="M_e"></marker>
-
+ <tag><marker id="M_e"><c><![CDATA[+M<S>e true|false]]></c></marker></tag>
+ <item>
Enable allocator <c><![CDATA[<S>]]></c>.</item>
- <tag><c><![CDATA[+M<S>lmbcs <size>]]></c></tag>
- <item> <marker id="M_lmbcs"></marker>
-
+ <tag><marker id="M_lmbcs"><c><![CDATA[+M<S>lmbcs <size>]]></c></marker></tag>
+ <item>
Largest (<c>mseg_alloc</c>) multiblock carrier size (in
kilobytes). See <seealso marker="#mseg_mbc_sizes">the description
on how sizes for mseg_alloc multiblock carriers are decided</seealso>
in "the <c>alloc_util</c> framework" section.</item>
- <tag><c><![CDATA[+M<S>mbcgs <ratio>]]></c></tag>
- <item> <marker id="M_mbcgs"></marker>
-
+ <tag><marker id="M_mbcgs"><c><![CDATA[+M<S>mbcgs <ratio>]]></c></marker></tag>
+ <item>
(<c>mseg_alloc</c>) multiblock carrier growth stages. See
<seealso marker="#mseg_mbc_sizes">the description on how sizes for
mseg_alloc multiblock carriers are decided</seealso>
in "the <c>alloc_util</c> framework" section.</item>
- <tag><c><![CDATA[+M<S>mbsd <depth>]]></c></tag>
- <item> <marker id="M_mbsd"></marker>
-
+ <tag><marker id="M_mbsd"><c><![CDATA[+M<S>mbsd <depth>]]></c></marker></tag>
+ <item>
Max block search depth. This flag has effect only if the
good fit strategy has been selected for allocator
<c><![CDATA[<S>]]></c>. When the good fit strategy is used, free
@@ -353,47 +339,41 @@
search depth sets a limit on the maximum number of blocks to
inspect in a free list during a search for suitable block
satisfying the request.</item>
- <tag><c><![CDATA[+M<S>mmbcs <size>]]></c></tag>
- <item> <marker id="M_mmbcs"></marker>
-
+ <tag><marker id="M_mmbcs"><c><![CDATA[+M<S>mmbcs <size>]]></c></marker></tag>
+ <item>
Main multiblock carrier size. Sets the size of the main
multiblock carrier for allocator <c><![CDATA[<S>]]></c>. The main
multiblock carrier is allocated via <c><![CDATA[sys_alloc]]></c> and is
never deallocated.</item>
- <tag><c><![CDATA[+M<S>mmmbc <amount>]]></c></tag>
- <item> <marker id="M_mmmbc"></marker>
-
+ <tag><marker id="M_mmmbc"><c><![CDATA[+M<S>mmmbc <amount>]]></c></marker></tag>
+ <item>
Max <c>mseg_alloc</c> multiblock carriers. Maximum number of
multiblock carriers allocated via <c>mseg_alloc</c> by
allocator <c><![CDATA[<S>]]></c>. When this limit has been reached,
new multiblock carriers will be allocated via
<c>sys_alloc</c>.</item>
- <tag><c><![CDATA[+M<S>mmsbc <amount>]]></c></tag>
- <item> <marker id="M_mmsbc"></marker>
-
+ <tag><marker id="M_mmsbc"><c><![CDATA[+M<S>mmsbc <amount>]]></c></marker></tag>
+ <item>
Max <c>mseg_alloc</c> singleblock carriers. Maximum number of
singleblock carriers allocated via <c>mseg_alloc</c> by
allocator <c><![CDATA[<S>]]></c>. When this limit has been reached,
new singleblock carriers will be allocated via
<c>sys_alloc</c>.</item>
- <tag><c><![CDATA[+M<S>ramv <bool>]]></c></tag>
- <item> <marker id="M_ramv"></marker>
-
+ <tag><marker id="M_ramv"><c><![CDATA[+M<S>ramv <bool>]]></c></marker></tag>
+ <item>
Realloc always moves. When enabled, reallocate operations will
more or less be translated into an allocate, copy, free sequence.
This often reduce memory fragmentation, but costs performance.
</item>
- <tag><c><![CDATA[+M<S>rmbcmt <ratio>]]></c></tag>
- <item> <marker id="M_rmbcmt"></marker>
-
+ <tag><marker id="M_rmbcmt"><c><![CDATA[+M<S>rmbcmt <ratio>]]></c></marker></tag>
+ <item>
Relative multiblock carrier move threshold (in percent). When
a block located in a multiblock carrier is shrunk,
the block will be moved if the ratio of the size of the returned
memory compared to the previous size is more than this threshold;
otherwise, the block will be shrunk at current location.</item>
- <tag><c><![CDATA[+M<S>rsbcmt <ratio>]]></c></tag>
- <item> <marker id="M_rsbcmt"></marker>
-
+ <tag><marker id="M_rsbcmt"><c><![CDATA[+M<S>rsbcmt <ratio>]]></c></marker></tag>
+ <item>
Relative singleblock carrier move threshold (in percent). When
a block located in a singleblock carrier is shrunk to
a size smaller than the value of the
@@ -401,32 +381,28 @@
the block will be left unchanged in the singleblock carrier if
the ratio of unused memory is less than this threshold;
otherwise, it will be moved into a multiblock carrier. </item>
- <tag><c><![CDATA[+M<S>rsbcst <ratio>]]></c></tag>
- <item> <marker id="M_rsbcst"></marker>
-
+ <tag><marker id="M_rsbcst"><c><![CDATA[+M<S>rsbcst <ratio>]]></c></marker></tag>
+ <item>
Relative singleblock carrier shrink threshold (in
percent). When a block located in an <c>mseg_alloc</c>
singleblock carrier is shrunk, the carrier will be left
unchanged if the ratio of unused memory is less than this
threshold; otherwise, the carrier will be shrunk.
See also <seealso marker="#M_asbcst">asbcst</seealso>.</item>
- <tag><c><![CDATA[+M<S>sbct <size>]]></c></tag>
- <item> <marker id="M_sbct"></marker>
-
+ <tag><marker id="M_sbct"><c><![CDATA[+M<S>sbct <size>]]></c></marker></tag>
+ <item>
Singleblock carrier threshold. Blocks larger than this
threshold will be placed in singleblock carriers. Blocks
smaller than this threshold will be placed in multiblock
carriers.</item>
- <tag><c><![CDATA[+M<S>smbcs <size>]]></c></tag>
- <item> <marker id="M_smbcs"></marker>
-
+ <tag><marker id="M_smbcs"><c><![CDATA[+M<S>smbcs <size>]]></c></marker></tag>
+ <item>
Smallest (<c>mseg_alloc</c>) multiblock carrier size (in
kilobytes). See <seealso marker="#mseg_mbc_sizes">the description
on how sizes for mseg_alloc multiblock carriers are decided</seealso>
in "the <c>alloc_util</c> framework" section.</item>
- <tag><c><![CDATA[+M<S>t true|false|<amount>]]></c></tag>
- <item> <marker id="M_t"></marker>
-
+ <tag><marker id="M_t"><c><![CDATA[+M<S>t true|false|<amount>]]></c></marker></tag>
+ <item>
Multiple, thread specific instances of the allocator.
This option will only have any effect on the runtime system
with SMP support. Default behaviour on the runtime system with
@@ -451,16 +427,15 @@
<c>alloc_util</c>, i.e. all allocators based on <c>alloc_util</c>
will be effected:</p>
<taglist>
- <tag><c><![CDATA[+Muycs <size>]]></c></tag>
- <item> <marker id="Muycs"></marker>
-<c>sys_alloc</c> carrier size. Carriers allocated via
+ <tag><marker id="Muycs"><c><![CDATA[+Muycs <size>]]></c></marker></tag>
+ <item>
+ <c>sys_alloc</c> carrier size. Carriers allocated via
<c>sys_alloc</c> will be allocated in sizes which are
multiples of the <c>sys_alloc</c> carrier size. This is not
true for main multiblock carriers and carriers allocated
during a memory shortage, though.</item>
- <tag><c><![CDATA[+Mummc <amount>]]></c></tag>
- <item> <marker id="Mummc"></marker>
-
+ <tag><marker id="Mummc"><c><![CDATA[+Mummc <amount>]]></c></marker></tag>
+ <item>
Max <c>mseg_alloc</c> carriers. Maximum number of carriers
placed in separate memory segments. When this limit has been
reached, new carriers will be placed in memory retrieved from
@@ -468,23 +443,20 @@
</taglist>
<p>Instrumentation flags:</p>
<taglist>
- <tag><c>+Mim true|false</c></tag>
- <item> <marker id="Mim"></marker>
-
+ <tag><marker id="Mim"><c>+Mim true|false</c></marker></tag>
+ <item>
A map over current allocations is kept by the emulator. The
allocation map can be retrieved via the <c>instrument</c>
module. <c>+Mim true</c> implies <c>+Mis true</c>.
<c>+Mim true</c> is the same as
<seealso marker="erl#instr">-instr</seealso>.</item>
- <tag><c>+Mis true|false</c></tag>
- <item> <marker id="Mis"></marker>
-
+ <tag><marker id="Mis"><c>+Mis true|false</c></marker></tag>
+ <item>
Status over allocated memory is kept by the emulator. The
allocation status can be retrieved via the <c>instrument</c>
module.</item>
- <tag><c>+Mit X</c></tag>
- <item> <marker id="Mit"></marker>
-
+ <tag><marker id="Mit"><c>+Mit X</c></marker></tag>
+ <item>
Reserved for future use. Do <em>not</em> use this flag.</item>
</taglist>
<note>
@@ -493,8 +465,8 @@
</note>
<p>Other flags:</p>
<taglist>
- <tag><c>+Mea min|max|r9c|r10b|r11b|config</c></tag>
- <item> <marker id="Mea"></marker>
+ <tag><marker id="Mea"><c>+Mea min|max|r9c|r10b|r11b|config</c></marker></tag>
+ <item>
<taglist>
<tag><c>min</c></tag>
<item>
diff --git a/erts/doc/src/escript.xml b/erts/doc/src/escript.xml
index 8df179b3e2..a89449df23 100644
--- a/erts/doc/src/escript.xml
+++ b/erts/doc/src/escript.xml
@@ -4,7 +4,7 @@
<comref>
<header>
<copyright>
- <year>2007</year><year>2009</year>
+ <year>2007</year><year>2010</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
@@ -13,12 +13,12 @@
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>escript</title>
@@ -50,20 +50,18 @@ $ <input>cat factorial</input>
%%! -smp enable -sname factorial -mnesia debug verbose
main([String]) ->
try
-\011N = list_to_integer(String),
-\011F = fac(N),
-\011io:format("factorial ~w = ~w\
-", [N,F])
+ N = list_to_integer(String),
+ F = fac(N),
+ io:format("factorial ~w = ~w\n", [N,F])
catch
-\011_:_ ->
-\011 usage()
+ _:_ ->
+ usage()
end;
main(_) ->
usage().
usage() ->
- io:format("usage: factorial integer\
-"),
+ io:format("usage: factorial integer\n"),
halt(1).
fac(0) -> 1;
diff --git a/erts/doc/src/inet_cfg.xml b/erts/doc/src/inet_cfg.xml
index 18cf65759a..2a033c037c 100644
--- a/erts/doc/src/inet_cfg.xml
+++ b/erts/doc/src/inet_cfg.xml
@@ -4,7 +4,7 @@
<chapter>
<header>
<copyright>
- <year>2004</year><year>2009</year>
+ <year>2004</year><year>2010</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
@@ -13,12 +13,12 @@
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>Inet configuration</title>
@@ -230,6 +230,13 @@
(use the Erlang DNS client
<seealso marker="kernel:inet_res">inet_res</seealso>
for nameserver queries).</p>
+ <p>The lookup method <c><![CDATA[string]]></c> tries to
+ parse the hostname as a IPv4 or IPv6 string and return
+ the resulting IP address. It is automatically tried
+ first when <c><![CDATA[native]]></c> is <em>not</em>
+ in the <c><![CDATA[Methods]]></c> list. To skip it in this case
+ the pseudo lookup method <c><![CDATA[nostring]]></c> can be
+ inserted anywhere in the <c><![CDATA[Methods]]></c> list.</p>
<p></p>
</item>
<tag><em><c><![CDATA[{cache_size, Size}.]]></c></em></tag>
diff --git a/erts/doc/src/match_spec.xml b/erts/doc/src/match_spec.xml
index 26480473d2..b9f955e4db 100644
--- a/erts/doc/src/match_spec.xml
+++ b/erts/doc/src/match_spec.xml
@@ -4,7 +4,7 @@
<chapter>
<header>
<copyright>
- <year>1999</year><year>2009</year>
+ <year>1999</year><year>2010</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
@@ -13,12 +13,12 @@
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>Match specifications in Erlang</title>
@@ -360,52 +360,52 @@
</p>
<table>
<row>
- <cell align="left" valign="middle">Expression\011\011</cell>
- <cell align="left" valign="middle">Variable bindings\011\011</cell>
- <cell align="left" valign="middle">Result\011</cell>
+ <cell align="left" valign="middle">Expression </cell>
+ <cell align="left" valign="middle">Variable bindings </cell>
+ <cell align="left" valign="middle">Result </cell>
</row>
<row>
- <cell align="left" valign="middle">{{'$1','$2'}}\011\011</cell>
+ <cell align="left" valign="middle">{{'$1','$2'}} </cell>
<cell align="left" valign="middle">'$1' = a, '$2' = b</cell>
<cell align="left" valign="middle">{a,b}</cell>
</row>
<row>
- <cell align="left" valign="middle">{const, {'$1', '$2'}}\011</cell>
+ <cell align="left" valign="middle">{const, {'$1', '$2'}} </cell>
<cell align="left" valign="middle">doesn't matter</cell>
<cell align="left" valign="middle">{'$1', '$2'}</cell>
</row>
<row>
- <cell align="left" valign="middle">a\011\011\011</cell>
- <cell align="left" valign="middle">doesn't matter\011\011\011</cell>
+ <cell align="left" valign="middle">a </cell>
+ <cell align="left" valign="middle">doesn't matter </cell>
<cell align="left" valign="middle">a</cell>
</row>
<row>
- <cell align="left" valign="middle">'$1'\011\011\011</cell>
- <cell align="left" valign="middle">'$1' = []\011\011\011</cell>
+ <cell align="left" valign="middle">'$1' </cell>
+ <cell align="left" valign="middle">'$1' = [] </cell>
<cell align="left" valign="middle">[]</cell>
</row>
<row>
- <cell align="left" valign="middle">['$1']\011\011\011</cell>
- <cell align="left" valign="middle">'$1' = []\011\011\011</cell>
+ <cell align="left" valign="middle">['$1'] </cell>
+ <cell align="left" valign="middle">'$1' = [] </cell>
<cell align="left" valign="middle">[[]]</cell>
</row>
<row>
- <cell align="left" valign="middle">[{{a}}]\011\011\011</cell>
+ <cell align="left" valign="middle">[{{a}}] </cell>
<cell align="left" valign="middle">doesn't matter</cell>
<cell align="left" valign="middle">[{a}]</cell>
</row>
<row>
- <cell align="left" valign="middle">42\011\011\011</cell>
+ <cell align="left" valign="middle">42 </cell>
<cell align="left" valign="middle">doesn't matter</cell>
<cell align="left" valign="middle">42</cell>
</row>
<row>
- <cell align="left" valign="middle">"hello"\011\011\011</cell>
+ <cell align="left" valign="middle">"hello" </cell>
<cell align="left" valign="middle">doesn't matter</cell>
<cell align="left" valign="middle">"hello"</cell>
</row>
<row>
- <cell align="left" valign="middle">$1\011\011\011</cell>
+ <cell align="left" valign="middle">$1 </cell>
<cell align="left" valign="middle">doesn't matter</cell>
<cell align="left" valign="middle">49 (the ASCII value for the character '1')</cell>
</row>
@@ -507,8 +507,8 @@
a list which in turn begins with the second argument times
two (i. e. [{[4,x],y},2] or [{[8], y, z},4])</p>
<code type="none"><![CDATA[
-[{['$1', '$2'],\011[{'=:=', {'*', 2, '$2'}, {hd, {element, 1, '$1'}}}],
- []}]\011
+[{['$1', '$2'],[{'=:=', {'*', 2, '$2'}, {hd, {element, 1, '$1'}}}],
+ []}]
]]></code>
<p>Match three arguments. When all three are equal and are
numbers, append the process dump to the trace message, else
diff --git a/erts/doc/src/notes.xml b/erts/doc/src/notes.xml
index 2252358e0d..8ff3f50348 100644
--- a/erts/doc/src/notes.xml
+++ b/erts/doc/src/notes.xml
@@ -4,7 +4,7 @@
<chapter>
<header>
<copyright>
- <year>2004</year><year>2009</year>
+ <year>2004</year><year>2010</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
@@ -13,12 +13,12 @@
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>ERTS Release Notes</title>
@@ -30,6 +30,500 @@
</header>
<p>This document describes the changes made to the ERTS application.</p>
+<section><title>Erts 5.7.5.3</title>
+
+ <section><title>Fixed Bugs and Malfunctions</title>
+ <list>
+ <item>
+ <p>
+ On Linux systems using heart (erl -heart) and a
+ HEAR_BEAT_TIMEOUT less than default, heart could fire
+ even though Erlang was running fine after approx 298 to
+ 497 days (depending on kernel config). This was due to
+ the behaviour of the times(2) system call. Usage of
+ times(2) is now replaced with clock_gettime(2) and the
+ CLOCK_MONOTONIC clock, resulting in a more stable
+ solution. The Erlang VM itself has used clock_gettime(2)
+ on linux since before R12B, so this only affects the
+ heart program.</p>
+ <p>
+ Own Id: OTP-10111 Aux Id: seq12075 </p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
+<section><title>Erts 5.7.5.2</title>
+
+ <section><title>Known Bugs and Problems</title>
+ <list>
+ <item>
+ <p>
+ Two bugs in gen_sctp has been corrected: getopts/setopts
+ hence also send could only be called from socket owner,
+ and options 'linger', 'rcvbuf' and 'sndbuf' was read from
+ wrong protocol layer hence read wrong values by getopts.</p>
+ <p>
+ Own Id: OTP-9544</p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
+<section><title>Erts 5.7.5.1</title>
+
+ <section><title>Fixed Bugs and Malfunctions</title>
+ <list>
+ <item>
+ <p>
+ Driver threads, such as async threads, using <seealso
+ marker="erl_driver#ErlDrvPDL">port data locks</seealso>
+ peeked at the port status field without proper locking
+ when looking up the driver queue.</p>
+ <p>
+ Own Id: OTP-8475</p>
+ </item>
+ <item>
+ <p>
+ A call to the BIF <c>unregister(RegName)</c> when a port
+ had the name <c>RegName</c> registered in the runtime
+ system without SMP support caused a runtime system crash.
+ (Thanks to Per Hedeland for the bugfix and test case.)</p>
+ <p>
+ Own Id: OTP-8487</p>
+ </item>
+ <item>
+ <p>
+ Fix memory management bug causing crash of non-SMP
+ emulator with async threads enabled. The bug did first
+ appear in R13B03.</p>
+ <p>
+ Own Id: OTP-8591 Aux Id: seq11554 </p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
+<section><title>Erts 5.7.5</title>
+
+ <section><title>Fixed Bugs and Malfunctions</title>
+ <list>
+ <item>
+ <p>
+ Fix <c>binary_to_term</c> crash on compressed term with
+ corrupt size field.</p>
+ <p>
+ Own Id: OTP-8336</p>
+ </item>
+ <item>
+ <p>
+ Processes and/or ports could get stuck on a blocked
+ scheduler when <c>erlang:system_flag(multi_scheduling,
+ block)</c> was used.</p>
+ <p>
+ Processes and/or ports could get stuck on an offline
+ scheduler when schedulers online were reduced using
+ <c>erlang:system_flag(schedulers_online,
+ SchedulersOnline)</c>.</p>
+ <p>
+ Own Id: OTP-8342</p>
+ </item>
+ <item>
+ <p>Building on Windows will now work if the paths to
+ <c>mc.exe</c> and <c>rc.exe</c> contain spaces. The
+ README.win32 file has been updated with some information
+ about building using Visual Studio 2008. (Thanks to
+ Andrew Thompson.)</p>
+ <p>
+ Own Id: OTP-8345</p>
+ </item>
+ <item>
+ <p>
+ EPMD now correctly handles the extra data field which can
+ be given in the ALIVE2_REQ request and retrieved in the
+ PORT2_RESP response. (Thanks to Klas Johansson.)</p>
+ <p>
+ Own Id: OTP-8361</p>
+ </item>
+ <item>
+ <p>
+ The configure test for reliable floating point exceptions
+ has been update to work on modern versions of Mac OS X.
+ (Thanks to Trannie Carter.)</p>
+ <p>
+ Own Id: OTP-8368</p>
+ </item>
+ <item>
+ <p>
+ ERTS makefiles used to detect the use of a gcc C compiler
+ by checking if CC equaled gcc. That is, the makefiles
+ failed to detect gcc C compilers with other command line
+ names than gcc. `configure' now substitute GCC into the
+ makefiles. If CC is a gcc C compiler, GCC will have the
+ value yes. (Thanks to Jean-S�bastien P�dron)</p>
+ <p>
+ Own Id: OTP-8373</p>
+ </item>
+ <item>
+ <p>
+ ETS bug causing the <c>memory</c> counter from
+ <c>ets:info</c> for ordered_set's to sometimes get out of
+ synch and absurdly high.</p>
+ <p>
+ Own Id: OTP-8377 Aux Id: seq11442 </p>
+ </item>
+ <item>
+ <p>
+ Immediately repeated multi-scheduling block/unblock
+ cycles using <c>erlang:system_flag(multi_scheduling,
+ block | unblock)</c> could deadlock the runtime system.</p>
+ <p>
+ Own Id: OTP-8386</p>
+ </item>
+ <item>
+ <p>A number of bugs concerning re and unicode are
+ corrected:</p>
+ <p>re:compile no longer looses unicode option, which also
+ fixes bug in re:split.</p>
+ <p>re:replace now handles unicode charlist replacement
+ argument</p>
+ <p>re:replace now handles unicode RE charlist argument
+ correctly</p>
+ <p>re:replace now handles binary unicode output correctly
+ when nothing is replaced.</p>
+ <p>Most code, testcases and error isolation done by Rory
+ Byrne.</p>
+ <p>
+ Own Id: OTP-8394</p>
+ </item>
+ <item>
+ <p>
+ The loading of native code was not properly atomic in the
+ SMP emulator, which could cause crashes. Also a per-MFA
+ information table for the native code has now been
+ protected with a lock since it turns that it could be
+ accessed concurrently in the SMP emulator. (Thanks to
+ Mikael Pettersson.)</p>
+ <p>
+ Own Id: OTP-8397</p>
+ </item>
+ <item>
+ <p>
+ Fix processes in exiting status that are about to be
+ scheduled, to not be allowed to garbage collect.</p>
+ <p>
+ Own Id: OTP-8420</p>
+ </item>
+ <item>
+ <p>Removed bogus "\011" character sequence in
+ documentation.</p>
+ <p>
+ Own Id: OTP-8422</p>
+ </item>
+ <item>
+ <p>
+ The resolver routines failed to look up the own node name
+ as hostname, if the OS native resolver was erroneously
+ configured, bug reported by Yogish Baliga, now fixed.</p>
+ <p>
+ The resolver routines now tries to parse the hostname as
+ an IP string as most OS resolvers do, unless the native
+ resolver is used.</p>
+ <p>
+ The DNS resolver inet_res and file resolver inet_hosts
+ now do not read OS configuration files until they are
+ needed. Since the native resolver is default, in most
+ cases they are never needed.</p>
+ <p>
+ The DNS resolver's automatic updating of OS configuration
+ file data (/etc/resolv.conf) now uses the 'domain'
+ keyword as default search domain if there is no 'search'
+ keyword.</p>
+ <p>
+ Own Id: OTP-8426 Aux Id: OTP-8381 </p>
+ </item>
+ <item>
+ <p>
+ The re module: A regular expression with an option change
+ at the start of a pattern that had top-level alternatives
+ could cause overwriting and/or a crash. (Thanks to
+ Michael Santos.)</p>
+ <p>
+ Own Id: OTP-8438</p>
+ </item>
+ <item>
+ <p>
+ Harmless buffer overflow by one byte in asn1 and
+ ram_file_drv.</p>
+ <p>
+ Own Id: OTP-8451</p>
+ </item>
+ </list>
+ </section>
+
+
+ <section><title>Improvements and New Features</title>
+ <list>
+ <item>
+ <p>
+ Improved GC performance after BIF/NIF call when a lot of
+ heap fragments was created. This will mainly benefit NIFs
+ that return large compound terms.</p>
+ <p>
+ Own Id: OTP-8240</p>
+ </item>
+ <item>
+ <p>Incompatible changes in the experimental NIF
+ feature.</p> <list><item> Changed the NIF function
+ prototypes in order to allow more than 3 function
+ arguments. </item><item> <c>enif_get_data</c> renamed as
+ <c>enif_priv_data</c>. </item><item>
+ <c>enif_make_string</c> got a third argument for
+ character encoding. </item><item> The return value of
+ <c>erlang:load_nif/2</c> on error changed. </item></list>
+ <p>Read more in the documentation of <c>erl_nif</c> and
+ <c>erlang:load_nif/2</c></p>.
+ <p>
+ *** POTENTIAL INCOMPATIBILITY ***</p>
+ <p>
+ Own Id: OTP-8304</p>
+ </item>
+ <item>
+ <p>Cross compilation improvements and other build system
+ improvements.</p>
+ <p>Most notable:</p> <list><item> Lots of cross
+ compilation improvements. The old cross compilation
+ support was more or less non-existing as well as broken.
+ Please, note that the cross compilation support should
+ still be considered as experimental. Also note that old
+ cross compilation configurations cannot be used without
+ modifications. For more information on cross compiling
+ Erlang/OTP see the <c>$ERL_TOP/INSTALL-CROSS.md</c> file.
+ </item><item> Support for staged install using <url
+ href="http://www.gnu.org/prep/standards/html_node/DESTDIR.html">DESTDIR</url>.
+ The old broken <c>INSTALL_PREFIX</c> has also been fixed.
+ For more information see the <c>$ERL_TOP/INSTALL.md</c>
+ file. </item><item> Documentation of the <c>release</c>
+ target of the top <c>Makefile</c>. For more information
+ see the <c>$ERL_TOP/INSTALL.md</c> file. </item><item>
+ <c>make install</c> now by default creates relative
+ symbolic links instead of absolute ones. For more
+ information see the <c>$ERL_TOP/INSTALL.md</c> file.
+ </item><item> <c>$ERL_TOP/configure --help=recursive</c>
+ now works and prints help for all applications with
+ <c>configure</c> scripts. </item><item> Doing <c>make
+ install</c>, or <c>make release</c> directly after
+ <c>make all</c> no longer triggers miscellaneous
+ rebuilds. </item><item> Existing bootstrap system is now
+ used when doing <c>make install</c>, or <c>make
+ release</c> without a preceding <c>make all</c>.
+ </item><item> The <c>crypto</c> and <c>ssl</c>
+ applications use the same runtime library path when
+ dynamically linking against <c>libssl.so</c> and
+ <c>libcrypto.so</c>. The runtime library search path has
+ also been extended. </item><item> The <c>configure</c>
+ scripts of <c>erl_interface</c> and <c>odbc</c> now
+ search for thread libraries and thread library quirks the
+ same way as <c>erts</c> do. </item><item> The
+ <c>configure</c> script of the <c>odbc</c> application
+ now also looks for odbc libraries in <c>lib64</c> and
+ <c>lib/64</c> directories when building on a 64-bit
+ system. </item><item> The <c>config.h.in</c> file in the
+ <c>erl_interface</c> application is now automatically
+ generated in instead of statically updated which reduces
+ the risk of <c>configure</c> tests without any effect.
+ </item></list>
+ <p>(Thanks to Henrik Riomar for suggestions and
+ testing)</p>
+ <p>(Thanks to Winston Smith for the AVR32-Linux cross
+ configuration and testing)</p>
+ <p>
+ *** POTENTIAL INCOMPATIBILITY ***</p>
+ <p>
+ Own Id: OTP-8323</p>
+ </item>
+ <item>
+ <p>NIF improvements:</p> <list><item> Driver API for
+ multi-threading made available for NIFs. </item><item>
+ Support for mempory managed (garbage collected) resource
+ objects. A way to pass "pointers" to native data
+ structures between C and Erlang in a safe way.
+ </item><item> Support for references, floats and term
+ comparison. </item><item> Various new functions, like
+ <c>enif_inspect_iolist_as_binary</c>,
+ <c>enif_make_sub_binary</c>, <c>enif_get_string</c>,
+ <c>enif_get_atom</c>, <c>enif_make_tuple_from_array</c>,
+ <c>enif_make_list_from_array</c>,
+ <c>enif_make_existing_atom</c>. </item></list>
+ <p>
+ Own Id: OTP-8335</p>
+ </item>
+ <item>
+ <p>
+ Minor alignment adjustments of scheduler specific data.</p>
+ <p>
+ Own Id: OTP-8341</p>
+ </item>
+ <item>
+ <p>The documentation is now possible to build in an open
+ source environment after a number of bugs are fixed and
+ some features are added in the documentation build
+ process. </p>
+ <p>- The arity calculation is updated.</p>
+ <p>- The module prefix used in the function names for
+ bif's are removed in the generated links so the links
+ will look like
+ "http://www.erlang.org/doc/man/erlang.html#append_element-2"
+ instead of
+ "http://www.erlang.org/doc/man/erlang.html#erlang:append_element-2".</p>
+ <p>- Enhanced the menu positioning in the html
+ documentation when a new page is loaded.</p>
+ <p>- A number of corrections in the generation of man
+ pages (thanks to Sergei Golovan)</p>
+ <p>- The legal notice is taken from the xml book file so
+ OTP's build process can be used for non OTP
+ applications.</p>
+ <p>
+ Own Id: OTP-8343</p>
+ </item>
+ <item>
+ <p>
+ There is new <c>erlang:binary_to_term/2</c> BIF that
+ takes an option list. The option <c>safe</c> can be used
+ to prevent creation of resources that are not garbage
+ collected (such as atoms). (Thanks to Jayson Vantuyl.)</p>
+ <p>
+ Own Id: OTP-8367</p>
+ </item>
+ <item>
+ <p>
+ The default settings for garbage collection of binaries
+ has been adjusted to be less aggressive than in R13B03.
+ It is now also possible configure the settings for binary
+ GC. See the documentation for <c>spawn_opt/2-5</c>,
+ <c>erlang:system_info/1</c>, <c>erlang:system_flag/2</c>,
+ <c>process_flag/2-3</c>, <c>erlang:trace/3</c>, and the
+ documenation for <c>erl</c> for the new command line
+ options <c>+hms</c> and <c>+hmbs</c>.</p>
+ <p>
+ Own Id: OTP-8370</p>
+ </item>
+ <item>
+ <p>
+ A bug causing memory corruption in re:run() has been
+ corrected. (Thanks to Yamashina Hio.)</p>
+ <p>
+ Own Id: OTP-8375</p>
+ </item>
+ <item>
+ <p>
+ The <c>-Werror</c> option for <c>erlc</c> and the
+ compiler option <c>warnings_as_errors</c> will cause
+ warnings to be treated as errors. (Thanks to Christopher
+ Faulet.)</p>
+ <p>
+ Own Id: OTP-8382</p>
+ </item>
+ <item>
+ <p>
+ Explicit top directories in archive files are now
+ optional.</p>
+ <p>
+ For example, if an archive (app-vsn.ez) just contains an
+ app-vsn/ebin/mod.beam file, the file info for the app-vsn
+ and app-vsn/ebin directories are faked using the file
+ info from the archive file as origin. The virtual
+ direcories can also be listed. For short, the top
+ directories are virtual if they does not exist.</p>
+ <p>
+ Own Id: OTP-8387</p>
+ </item>
+ <item>
+ <p>
+ An unnecessary lock operation in os:timestamp/0 has been
+ eliminated, making it slightly more efficient. (Thanks to
+ Jonas Falkevik and Tuncer Ayaz.)</p>
+ <p>
+ Own Id: OTP-8390</p>
+ </item>
+ <item>
+ <p>
+ There is a new <c>+t</c> emulator option for changing the
+ maximum number of atoms. (Thanks to Julien Barbot.)</p>
+ <p>
+ Own Id: OTP-8405</p>
+ </item>
+ <item>
+ <p>
+ Fixed numerous compiler warnings generated by gcc 4.4.1
+ and tile-cc 2.0.1.78377 when compiling the runtime
+ system.</p>
+ <p>
+ Own Id: OTP-8412</p>
+ </item>
+ <item>
+ <p>
+ <c>configure</c> learned the option
+ <c>--enable-m32-build</c> to force the building of a
+ 32-bit run-time on systems where the default C compiler
+ generates 64-bit executables by default.</p>
+ <p>
+ Own Id: OTP-8415</p>
+ </item>
+ <item>
+ <p>
+ HiPE now works in the 64-bit emulator on Mac OS X.
+ (Thanks to Geoff Cant.)</p>
+ <p>
+ Own Id: OTP-8416</p>
+ </item>
+ <item>
+ <p>
+ Improved handling of symbolic links to escripts</p>
+ <p>
+ Own Id: OTP-8417</p>
+ </item>
+ <item>
+ <p>
+ Add lock profiling tool.</p>
+ <p>
+ The Lock profiling tool, lcnt, can make use of the
+ internal lock statistics when the runtime system is built
+ with this feature enabled.</p>
+ <p>
+ This provides a mechanism to examine potential lock
+ bottlenecks within the runtime itself.</p>
+ <p>
+ - Add erts_debug:lock_counters({copy_save, bool()}). This
+ option enables or disables statistics saving for
+ destroyed processes and ets-tables. Enabling this might
+ consume a lot of memory.</p>
+ <p>
+ - Add id-numbering for lock classes which is otherwise
+ undefined.</p>
+ <p>
+ Own Id: OTP-8424</p>
+ </item>
+ <item>
+ <p>
+ Removed spurious options to the emulator from escript.</p>
+ <p>
+ Own Id: OTP-8427</p>
+ </item>
+ <item>
+ <p>
+ Minor documentation fixes. Mainly anchor adjustments.</p>
+ <p>
+ Own Id: OTP-8457</p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
<section><title>Erts 5.7.4</title>
<section><title>Fixed Bugs and Malfunctions</title>
@@ -242,7 +736,7 @@
<item>
<p>
The <seealso
- marker="erlang#erlang:port_command/3">erlang:port_command/3</seealso>
+ marker="erlang#port_command/3">erlang:port_command/3</seealso>
BIF has been added. <c>erlang:port_command/3</c> is
currently not auto imported, but it is planned to be auto
imported in OTP R14. For more information see the
@@ -4371,16 +4865,16 @@
following code might hang:</p>
<code type="none"><![CDATA[
Mon = erlang:monitor(process, Pid),
-\011 %% ...
-\011 exit(Pid, bang),
+ %% ...
+ exit(Pid, bang),
erlang:demonitor(Mon),
-\011 receive
-\011 {'DOWN', Mon , process, Pid, _} -> ok
-\011 %% We were previously guaranteed to get a down message
-\011 %% (since we exited the process ourself), so we could
-\011 %% in this case leave out:
-\011 %% after 0 -> ok
-\011 end,
+ receive
+ {'DOWN', Mon , process, Pid, _} -> ok
+ %% We were previously guaranteed to get a down message
+ %% (since we exited the process ourself), so we could
+ %% in this case leave out:
+ %% after 0 -> ok
+ end,
]]></code>
<p>*** POTENTIAL INCOMPATIBILITY ***</p>
<p>Own Id: OTP-5772</p>
@@ -5342,7 +5836,7 @@
<list type="bulleted">
<item>
<p>If Erlang/OTP was installed in a short directory name,
- such as <c><![CDATA[C:\\Program\\erl5.4.2]]></c>, the emulator would not
+ such as <c><![CDATA[C:\Program\erl5.4.2]]></c>, the emulator would not
start.</p>
<p>Own Id: OTP-5254</p>
</item>
diff --git a/erts/doc/src/tty.xml b/erts/doc/src/tty.xml
index 23694e5965..7d662a2849 100644
--- a/erts/doc/src/tty.xml
+++ b/erts/doc/src/tty.xml
@@ -4,7 +4,7 @@
<chapter>
<header>
<copyright>
- <year>1996</year><year>2009</year>
+ <year>1996</year><year>2010</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
@@ -13,12 +13,12 @@
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>tty - A command line interface</title>
@@ -47,7 +47,7 @@
<section>
<title>Normal Mode</title>
<p>In normal mode keystrokes from the user are collected and interpreted by <c><![CDATA[tty]]></c>. Most of the <em>emacs</em> line editing commands are supported. The following is a complete list of the supported line editing commands.<br></br></p>
- <p><em>Note:</em>\011The notation <c><![CDATA[C-a]]></c> means pressing the control key and the letter <c><![CDATA[a]]></c> simultaneously. <c><![CDATA[M-f]]></c> means pressing the <c><![CDATA[ESC]]></c> key followed by the letter <c><![CDATA[f]]></c>.
+ <p><em>Note:</em> The notation <c><![CDATA[C-a]]></c> means pressing the control key and the letter <c><![CDATA[a]]></c> simultaneously. <c><![CDATA[M-f]]></c> means pressing the <c><![CDATA[ESC]]></c> key followed by the letter <c><![CDATA[f]]></c>.
</p>
<table>
<row>
diff --git a/erts/doc/src/zlib.xml b/erts/doc/src/zlib.xml
index 9f39ac657a..b1e768bce9 100644
--- a/erts/doc/src/zlib.xml
+++ b/erts/doc/src/zlib.xml
@@ -4,7 +4,7 @@
<erlref>
<header>
<copyright>
- <year>2005</year><year>2009</year>
+ <year>2005</year><year>2010</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
@@ -13,12 +13,12 @@
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>zlib</title>
@@ -372,11 +372,11 @@ list_to_binary([B1,B2])</pre>
<pre>
unpack(Z, Compressed, Dict) ->
case catch zlib:inflate(Z, Compressed) of
-\011 {'EXIT',{{need_dictionary,DictID},_}} ->
- \011 zlib:inflateSetDictionary(Z, Dict),
-\011 Uncompressed = zlib:inflate(Z, []);
-\011 Uncompressed ->
-\011 Uncompressed
+ {'EXIT',{{need_dictionary,DictID},_}} ->
+ zlib:inflateSetDictionary(Z, Dict),
+ Uncompressed = zlib:inflate(Z, []);
+ Uncompressed ->
+ Uncompressed
end.</pre>
</desc>
</func>
@@ -466,8 +466,8 @@ unpack(Z, Compressed, Dict) ->
the required initial value for the crc.</p>
<pre>
Crc = lists:foldl(fun(Bin,Crc0) ->
-\011 zlib:crc32(Z, Crc0, Bin),
-\011 end, zlib:crc32(Z,&lt;&lt; &gt;&gt;), Bins)</pre>
+ zlib:crc32(Z, Crc0, Bin),
+ end, zlib:crc32(Z,&lt;&lt; &gt;&gt;), Bins)</pre>
</desc>
</func>
<func>
@@ -517,8 +517,8 @@ Crc = lists:foldl(fun(Bin,Crc0) ->
the required initial value for the checksum.</p>
<pre>
Crc = lists:foldl(fun(Bin,Crc0) ->
-\011 zlib:adler32(Z, Crc0, Bin),
-\011 end, zlib:adler32(Z,&lt;&lt; &gt;&gt;), Bins)</pre>
+ zlib:adler32(Z, Crc0, Bin),
+ end, zlib:adler32(Z,&lt;&lt; &gt;&gt;), Bins)</pre>
</desc>
</func>
<func>
diff --git a/erts/emulator/Makefile.in b/erts/emulator/Makefile.in
index a2061134a5..a81ab28847 100644
--- a/erts/emulator/Makefile.in
+++ b/erts/emulator/Makefile.in
@@ -1,24 +1,25 @@
#
# %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
# 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 ../vsn.mk
+include $(ERL_TOP)/make/$(TARGET)/otp.mk
ENABLE_ALLOC_TYPE_VARS = @ENABLE_ALLOC_TYPE_VARS@
HIPE_ENABLED=@HIPE_ENABLED@
@@ -166,6 +167,9 @@ ifeq ($(OPSYS),linux)
ppcBEAMLDFLAGS=-Wl,-m,elf32ppc
ppc64BEAMLDFLAGS=-Wl,-m,elf64ppc,-T,hipe/elf64ppc.x
endif
+ifeq ($(OPSYS),darwin)
+amd64BEAMLDFLAGS=-pagezero_size 0x10000000
+endif
HIPEBEAMLDFLAGS=$($(ARCH)BEAMLDFLAGS)
endif
@@ -213,7 +217,7 @@ else
OPT_LEVEL = -O3
endif
-ifeq ($(CC), gcc)
+ifeq ($(GCC),yes)
ifeq ($(NO_INLINE_FUNCTIONS),true)
GEN_OPT_FLGS = $(OPT_LEVEL) -fno-inline-functions
else
@@ -252,7 +256,7 @@ CS_TYPE_FLAGS = $(subst QUANTIFY,FAKE_QUANTIFY, \
$(subst PURIFY,FAKE_PURIFY, $(TYPE_FLAGS)))
endif
CS_CFLAGS_ = $(CS_TYPE_FLAGS) @DEFS@ $(WFLAGS)
-ifeq ($(CC), gcc)
+ifeq ($(GCC),yes)
CS_CFLAGS = $(subst -O2, $(GEN_OPT_FLGS) $(UNROLL_FLG), $(CS_CFLAGS_))
else
CS_CFLAGS = $(CS_CFLAGS_)
@@ -351,7 +355,6 @@ endif
CS_EXECUTABLE = child_setup$(TYPEMARKER)
# ----------------------------------------------------------------------
-include $(ERL_TOP)/make/$(TARGET)/otp.mk
ifeq ($(ERLANG_OSTYPE), unix)
UNIX_ONLY_BUILDS = $(BINDIR)/$(CS_EXECUTABLE)
@@ -402,7 +405,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
@@ -416,7 +419,7 @@ include $(ERL_TOP)/make/otp_release_targets.mk
RELSYSDIR = $(RELEASE_PATH)/erts-$(VSN)
-RELEASE_INCLUDES = beam/erl_driver.h sys/$(ERLANG_OSTYPE)/driver_int.h beam/erl_nif.h beam/erl_nif_api_funcs.h
+RELEASE_INCLUDES = beam/erl_driver.h sys/$(ERLANG_OSTYPE)/driver_int.h beam/erl_nif.h beam/erl_nif_api_funcs.h beam/erl_drv_nif.h
ifeq ($(TARGET),win32)
RELEASE_INCLUDES += sys/$(ERLANG_OSTYPE)/erl_win_dyn_driver.h
endif
@@ -606,7 +609,7 @@ endif
ifneq ($(filter tile-%,$(TARGET)),)
$(OBJDIR)/beam_emu.o: beam/beam_emu.c
- $(CC) $(subst -O2, $(GEN_OPT_FLGS), $(CFLAGS)) \
+ $(CC) $(subst -O2, $(GEN_OPT_FLGS), $(CFLAGS)) \
-OPT:Olimit=0 -WOPT:lpre=off:spre=off:epre=off \
$(INCLUDES) -c $< -o $@
endif
@@ -692,7 +695,7 @@ $(OBJDIR)/%.kp.o: sys/common/%.c
$(OBJDIR)/%.nkp.o: sys/common/%.c
$(CC) -DERTS_NO_KERNEL_POLL_VERSION $(subst -O2, $(GEN_OPT_FLGS), $(CFLAGS)) $(INCLUDES) -c $< -o $@
-ifeq ($(CC), gcc)
+ifeq ($(GCC),yes)
$(OBJDIR)/erl_obsolete.o: beam/erl_obsolete.c
$(CC) $(subst -Wstrict-prototypes, , $(subst -O2, $(GEN_OPT_FLGS), $(CFLAGS))) $(INCLUDES) -c $< -o $@
@@ -1086,8 +1089,16 @@ DEP_FLAGS=-MM $(subst -O2,,$(CFLAGS)) $(INCLUDES) -I../etc/win32 -Idrivers/comm
# SYS_SRC=$(subst sys/common/erl_poll.c,,$(ALL_SYS_SRC))
else # !win32
+
+ifeq ($(findstring tile,$(TARGET)),tile)
+# tile-gcc doesn't like -MG
+MG_FLAG=
+else
+MG_FLAG=-MG
+endif
+
DEP_CC=$(CC)
-DEP_FLAGS=-MM -MG $(CFLAGS) $(INCLUDES) -Idrivers/common
+DEP_FLAGS=-MM $(MG_FLAG) $(CFLAGS) $(INCLUDES) -Idrivers/common
SYS_SRC=$(ALL_SYS_SRC)
endif
diff --git a/erts/emulator/beam/atom.c b/erts/emulator/beam/atom.c
index dfc3cde6a7..e2a79d6e4f 100644
--- a/erts/emulator/beam/atom.c
+++ b/erts/emulator/beam/atom.c
@@ -1,19 +1,19 @@
/*
* %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
* 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%
*/
@@ -322,7 +322,7 @@ init_atom_table(void)
text_list = NULL;
erts_index_init(ERTS_ALC_T_ATOM_TABLE, &erts_atom_table,
- "atom_tab", ATOM_SIZE, ATOM_LIMIT, f);
+ "atom_tab", ATOM_SIZE, erts_atom_table_size, f);
more_atom_space();
/* Ordinary atoms */
diff --git a/erts/emulator/beam/atom.h b/erts/emulator/beam/atom.h
index e7e0dc440d..cb245a87b1 100644
--- a/erts/emulator/beam/atom.h
+++ b/erts/emulator/beam/atom.h
@@ -1,19 +1,19 @@
/*
* %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
* 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%
*/
@@ -28,6 +28,17 @@
#define MAX_ATOM_LENGTH 255
#define ATOM_LIMIT (1024*1024)
+#define MIN_ATOM_TABLE_SIZE 8192
+
+#ifndef ARCH_32
+/* Internal atom cache needs MAX_ATOM_TABLE_SIZE to be less than an
+ unsigned 32 bit integer. See external.c(erts_encode_ext_dist_header_setup)
+ for more details. */
+#define MAX_ATOM_TABLE_SIZE ((MAX_ATOM_INDEX + 1 < (1UL << 32)) ? MAX_ATOM_INDEX + 1 : (1UL << 32))
+#else
+#define MAX_ATOM_TABLE_SIZE (MAX_ATOM_INDEX + 1)
+#endif
+
/*
* Atom entry.
diff --git a/erts/emulator/beam/atom.names b/erts/emulator/beam/atom.names
index 04eac2d807..57c8b08223 100644
--- a/erts/emulator/beam/atom.names
+++ b/erts/emulator/beam/atom.names
@@ -1,19 +1,19 @@
#
# %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
# 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%
#
@@ -303,6 +303,7 @@ atom messages
atom meta
atom meta_match_spec
atom min_heap_size
+atom min_bin_vheap_size
atom minor_version
atom Minus='-'
atom module
@@ -446,6 +447,7 @@ atom running
atom running_ports
atom running_procs
atom runtime
+atom safe
atom save_calls
atom scheduler
atom scheduler_id
diff --git a/erts/emulator/beam/beam_bif_load.c b/erts/emulator/beam/beam_bif_load.c
index d3a1ed4e7d..b1feec7074 100644
--- a/erts/emulator/beam/beam_bif_load.c
+++ b/erts/emulator/beam/beam_bif_load.c
@@ -1,19 +1,19 @@
/*
* %CopyrightBegin%
- *
- * Copyright Ericsson AB 1999-2009. All Rights Reserved.
- *
+ *
+ * Copyright Ericsson AB 1999-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%
*/
@@ -642,21 +642,9 @@ purge_module(int module)
/*
* Unload any NIF library
*/
- if (modp->old_nif.handle != NULL) {
- if (modp->old_nif.entry->unload != NULL) {
- ErlNifEnv env;
- env.nif_data = modp->old_nif.data;
- env.proc = NULL; /* BUGBUG: unlink can not access calling process */
- env.hp = NULL;
- env.hp_end = NULL;
- env.heap_frag_sz = 0;
- env.fpe_was_unmasked = erts_block_fpe();
- modp->old_nif.entry->unload(NULL, modp->old_nif.data);
- erts_unblock_fpe(env.fpe_was_unmasked);
- }
- erts_sys_ddll_close(modp->old_nif.handle);
- modp->old_nif.handle = NULL;
- modp->old_nif.entry = NULL;
+ if (modp->old_nif != NULL) {
+ erts_unload_nif(modp->old_nif);
+ modp->old_nif = NULL;
}
/*
@@ -732,8 +720,7 @@ delete_code(Process *c_p, ErtsProcLocks c_p_locks, Module* modp)
modp->code = NULL;
modp->code_length = 0;
modp->catches = BEAM_CATCHES_NIL;
- modp->nif.handle = NULL;
- modp->nif.entry = NULL;
+ modp->nif = NULL;
}
diff --git a/erts/emulator/beam/beam_emu.c b/erts/emulator/beam/beam_emu.c
index dcaa43b51c..2f7f48193d 100644
--- a/erts/emulator/beam/beam_emu.c
+++ b/erts/emulator/beam/beam_emu.c
@@ -1,19 +1,19 @@
/*
* %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
* 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%
*/
@@ -286,6 +286,15 @@ extern int count_instructions;
#endif
+#ifdef FORCE_HEAP_FRAGS
+# define HEAP_SPACE_VERIFIED(Words) do { \
+ c_p->space_verified = (Words); \
+ c_p->space_verified_from = HTOP; \
+ }while(0)
+#else
+# define HEAP_SPACE_VERIFIED(Words) ((void)0)
+#endif
+
#define PRE_BIF_SWAPOUT(P) \
HEAP_TOP((P)) = HTOP; \
(P)->stop = E; \
@@ -411,6 +420,7 @@ extern int count_instructions;
r(0) = reg[0]; \
SWAPIN; \
} \
+ HEAP_SPACE_VERIFIED(need); \
} while (0)
@@ -432,6 +442,7 @@ extern int count_instructions;
r(0) = reg[0]; \
SWAPIN; \
} \
+ HEAP_SPACE_VERIFIED(need); \
} while (0)
/*
@@ -456,6 +467,7 @@ extern int count_instructions;
Extra = reg[Live]; \
SWAPIN; \
} \
+ HEAP_SPACE_VERIFIED(need); \
} while (0)
#ifdef HYBRID
@@ -832,6 +844,7 @@ extern int count_instructions;
LIGHT_SWAPOUT; \
_result = erts_bs_get_float_2(c_p, _size, (Flags), _mb); \
LIGHT_SWAPIN; \
+ HEAP_SPACE_VERIFIED(0); \
if (is_non_value(_result)) { Fail; } \
else { Store(_result, Dst); } \
} while (0)
@@ -845,6 +858,7 @@ extern int count_instructions;
LIGHT_SWAPOUT; \
_result = erts_bs_get_binary_2(c_p, (Sz), (Flags), _mb); \
LIGHT_SWAPIN; \
+ HEAP_SPACE_VERIFIED(0); \
if (is_non_value(_result)) { Fail; } \
else { Store(_result, Dst); } \
} while (0)
@@ -859,6 +873,7 @@ extern int count_instructions;
LIGHT_SWAPOUT; \
_result = erts_bs_get_binary_2(c_p, _size, (Flags), _mb); \
LIGHT_SWAPIN; \
+ HEAP_SPACE_VERIFIED(0); \
if (is_non_value(_result)) { Fail; } \
else { Store(_result, Dst); } \
} while (0)
@@ -873,9 +888,12 @@ extern int count_instructions;
LIGHT_SWAPOUT; \
_result = erts_bs_get_binary_all_2(c_p, _mb); \
LIGHT_SWAPIN; \
+ HEAP_SPACE_VERIFIED(0); \
ASSERT(is_value(_result)); \
Store(_result, Dst); \
- } else { Fail; } \
+ } else { \
+ HEAP_SPACE_VERIFIED(0); \
+ Fail; } \
} while (0)
#define BsSkipBits2(Ms, Bits, Unit, Fail) \
@@ -974,10 +992,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;
@@ -1364,6 +1378,7 @@ void process_main(void)
*/
c_p->cp = 0;
CHECK_TERM(r(0));
+ HEAP_SPACE_VERIFIED(0);
Goto(*I);
}
@@ -2383,6 +2398,7 @@ void process_main(void)
if (is_big(tmp_arg1)) {
HTOP += bignum_header_arity(*HTOP) + 1;
}
+ HEAP_SPACE_VERIFIED(0);
if (is_nil(tmp_arg1)) {
/*
* This result must have been only slight larger
@@ -2949,11 +2965,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]: Pointer to erl_module_nif
+ */
+ 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, (struct erl_module_nif*)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 +3009,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 +3060,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) {
@@ -3203,6 +3245,7 @@ void process_main(void)
sb->orig = new_binary;
new_binary = make_binary(sb);
}
+ HEAP_SPACE_VERIFIED(0);
StoreBifResult(2, new_binary);
} else {
Binary* bptr;
@@ -3690,6 +3733,7 @@ void process_main(void)
*dst = *ms;
*HTOP = HEADER_BIN_MATCHSTATE(slots);
HTOP += wordsneeded;
+ HEAP_SPACE_VERIFIED(0);
StoreResult(make_matchstate(dst), Arg(3));
}
} else if (is_binary_header(header)) {
@@ -3703,6 +3747,7 @@ void process_main(void)
#endif
result = erts_bs_start_match_2(c_p, tmp_arg1, slots);
HTOP = HEAP_TOP(c_p);
+ HEAP_SPACE_VERIFIED(0);
if (is_non_value(result)) {
ClauseFail();
} else {
@@ -3895,6 +3940,7 @@ void process_main(void)
TestHeap(BIG_UINT_HEAP_SIZE, Arg(1));
_result = uint_to_big((Uint) _integer, HTOP);
HTOP += BIG_UINT_HEAP_SIZE;
+ HEAP_SPACE_VERIFIED(0);
}
#endif
StoreBifResult(2, _result);
@@ -3960,6 +4006,7 @@ void process_main(void)
LIGHT_SWAPOUT;
result = erts_bs_get_integer_2(c_p, tmp_arg2, Arg(1), mb);
LIGHT_SWAPIN;
+ HEAP_SPACE_VERIFIED(0);
if (is_non_value(result)) {
ClauseFail();
}
@@ -3987,6 +4034,7 @@ void process_main(void)
LIGHT_SWAPOUT;
result = erts_bs_get_integer_2(c_p, size, flags, mb);
LIGHT_SWAPIN;
+ HEAP_SPACE_VERIFIED(0);
if (is_non_value(result)) {
ClauseFail();
}
@@ -5245,6 +5293,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 +6197,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/beam_load.c b/erts/emulator/beam/beam_load.c
index 47dd98117d..99fab28dce 100644
--- a/erts/emulator/beam/beam_load.c
+++ b/erts/emulator/beam/beam_load.c
@@ -5090,6 +5090,7 @@ erts_make_stub_module(Process* p, Eterm Mod, Eterm Beam, Eterm Info)
code[MI_COMPILE_PTR] = 0;
code[MI_COMPILE_SIZE_ON_HEAP] = 0;
code[MI_NUM_BREAKPOINTS] = 0;
+ code[MI_ON_LOAD_FUNCTION_PTR] = 0;
ci = MI_FUNCTIONS + n + 1;
/*
diff --git a/erts/emulator/beam/bif.c b/erts/emulator/beam/bif.c
index 74b231d56d..1b670585a7 100644
--- a/erts/emulator/beam/bif.c
+++ b/erts/emulator/beam/bif.c
@@ -1,19 +1,19 @@
/*
* %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
* 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%
*/
@@ -807,11 +807,12 @@ BIF_RETTYPE spawn_opt_1(BIF_ALIST_1)
/*
* Store default values for options.
*/
- so.flags = SPO_USE_ARGS;
- so.min_heap_size = H_MIN_SIZE;
- so.priority = PRIORITY_NORMAL;
- so.max_gen_gcs = (Uint16) erts_smp_atomic_read(&erts_max_gen_gcs);
- so.scheduler = 0;
+ so.flags = SPO_USE_ARGS;
+ so.min_heap_size = H_MIN_SIZE;
+ so.min_vheap_size = BIN_VH_MIN_SIZE;
+ so.priority = PRIORITY_NORMAL;
+ so.max_gen_gcs = (Uint16) erts_smp_atomic_read(&erts_max_gen_gcs);
+ so.scheduler = 0;
/*
* Walk through the option list.
@@ -850,6 +851,15 @@ BIF_RETTYPE spawn_opt_1(BIF_ALIST_1)
} else {
so.min_heap_size = erts_next_heap_size(min_heap_size, 0);
}
+ } else if (arg == am_min_bin_vheap_size && is_small(val)) {
+ Sint min_vheap_size = signed_val(val);
+ if (min_vheap_size < 0) {
+ goto error;
+ } else if (min_vheap_size < BIN_VH_MIN_SIZE) {
+ so.min_vheap_size = BIN_VH_MIN_SIZE;
+ } else {
+ so.min_vheap_size = erts_next_heap_size(min_vheap_size, 0);
+ }
} else if (arg == am_fullsweep_after && is_small(val)) {
Sint max_gen_gcs = signed_val(val);
if (max_gen_gcs < 0) {
@@ -1485,6 +1495,23 @@ BIF_RETTYPE process_flag_2(BIF_ALIST_2)
}
BIF_RET(old_value);
}
+ else if (BIF_ARG_1 == am_min_bin_vheap_size) {
+ Sint i;
+ if (!is_small(BIF_ARG_2)) {
+ goto error;
+ }
+ i = signed_val(BIF_ARG_2);
+ if (i < 0) {
+ goto error;
+ }
+ old_value = make_small(BIF_P->min_vheap_size);
+ if (i < BIN_VH_MIN_SIZE) {
+ BIF_P->min_vheap_size = BIN_VH_MIN_SIZE;
+ } else {
+ BIF_P->min_vheap_size = erts_next_heap_size(i, 0);
+ }
+ BIF_RET(old_value);
+ }
else if (BIF_ARG_1 == am_sensitive) {
Uint is_sensitive;
if (BIF_ARG_2 == am_true) {
@@ -3736,10 +3763,35 @@ BIF_RETTYPE system_flag_2(BIF_ALIST_2)
BIF_RET(make_small(oval));
} else if (BIF_ARG_1 == am_min_heap_size) {
int oval = H_MIN_SIZE;
+
if (!is_small(BIF_ARG_2) || (n = signed_val(BIF_ARG_2)) < 0) {
goto error;
}
+
+ erts_smp_proc_unlock(BIF_P, ERTS_PROC_LOCK_MAIN);
+ erts_smp_block_system(0);
+
H_MIN_SIZE = erts_next_heap_size(n, 0);
+
+ erts_smp_release_system();
+ erts_smp_proc_lock(BIF_P, ERTS_PROC_LOCK_MAIN);
+
+ BIF_RET(make_small(oval));
+ } else if (BIF_ARG_1 == am_min_bin_vheap_size) {
+ int oval = BIN_VH_MIN_SIZE;
+
+ if (!is_small(BIF_ARG_2) || (n = signed_val(BIF_ARG_2)) < 0) {
+ goto error;
+ }
+
+ erts_smp_proc_unlock(BIF_P, ERTS_PROC_LOCK_MAIN);
+ erts_smp_block_system(0);
+
+ BIN_VH_MIN_SIZE = erts_next_heap_size(n, 0);
+
+ erts_smp_release_system();
+ erts_smp_proc_lock(BIF_P, ERTS_PROC_LOCK_MAIN);
+
BIF_RET(make_small(oval));
} else if (BIF_ARG_1 == am_display_items) {
int oval = display_items;
@@ -4091,6 +4143,7 @@ BIF_RETTYPE blocking_read_file_1(BIF_ALIST_1)
FILE *file;
struct stat file_info;
char *filename = NULL;
+ size_t size;
i = list_length(BIF_ARG_1);
if (i < 0) {
@@ -4118,9 +4171,13 @@ BIF_RETTYPE blocking_read_file_1(BIF_ALIST_1)
fclose(file);
BIF_RET(TUPLE2(hp, am_error, am_allocator));
}
- fread(buff, 1, buff_size, file);
+ size = fread(buff, 1, buff_size, file);
fclose(file);
- bin = new_binary(BIF_P, buff, buff_size);
+ if (size < 0)
+ size = 0;
+ else if (size > buff_size)
+ size = (size_t) buff_size;
+ bin = new_binary(BIF_P, buff, (int) size);
erts_free(ERTS_ALC_T_TMP, (void *) buff);
BIF_RET(TUPLE2(hp, am_ok, bin));
diff --git a/erts/emulator/beam/bif.tab b/erts/emulator/beam/bif.tab
index 85a729208f..b6fa06354a 100644
--- a/erts/emulator/beam/bif.tab
+++ b/erts/emulator/beam/bif.tab
@@ -1,19 +1,19 @@
#
# %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
# 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%
#
@@ -755,6 +755,11 @@ bif erlang:call_on_load_function/1
bif erlang:finish_after_on_load/2
#
+# New Bifs in R13B4
+#
+bif erlang:binary_to_term/2
+
+#
# Obsolete
#
diff --git a/erts/emulator/beam/binary.c b/erts/emulator/beam/binary.c
index 49bc0d6457..08c64610a2 100644
--- a/erts/emulator/beam/binary.c
+++ b/erts/emulator/beam/binary.c
@@ -1,19 +1,19 @@
/*
* %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
* 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%
*/
@@ -180,7 +180,7 @@ erts_realloc_binary(Eterm bin, size_t size)
}
byte*
-erts_get_aligned_binary_bytes(Eterm bin, byte** base_ptr)
+erts_get_aligned_binary_bytes_extra(Eterm bin, byte** base_ptr, unsigned extra)
{
byte* bytes;
Eterm* real_bin;
@@ -208,10 +208,10 @@ erts_get_aligned_binary_bytes(Eterm bin, byte** base_ptr)
bytes = (byte *)(&(((ErlHeapBin *) real_bin)->data)) + offs;
}
if (bit_offs) {
- byte* buf = (byte *) erts_alloc(ERTS_ALC_T_TMP, byte_size);
-
- erts_copy_bits(bytes, bit_offs, 1, buf, 0, 1, byte_size*8);
+ byte* buf = (byte *) erts_alloc(ERTS_ALC_T_TMP, byte_size + extra);
*base_ptr = buf;
+ buf += extra;
+ erts_copy_bits(bytes, bit_offs, 1, buf, 0, 1, byte_size*8);
bytes = buf;
}
return bytes;
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_arith.c b/erts/emulator/beam/erl_arith.c
index b692832677..126ec7cc73 100644
--- a/erts/emulator/beam/erl_arith.c
+++ b/erts/emulator/beam/erl_arith.c
@@ -1,19 +1,19 @@
/*
* %CopyrightBegin%
- *
- * Copyright Ericsson AB 1999-2009. All Rights Reserved.
- *
+ *
+ * Copyright Ericsson AB 1999-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%
*/
@@ -50,18 +50,16 @@ static ERTS_INLINE void maybe_shrink(Process* p, Eterm* hp, Eterm res, Uint allo
if (is_immed(res)) {
if (p->heap <= hp && hp < p->htop) {
p->htop = hp;
-#if defined(CHECK_FOR_HOLES)
- } else {
- erts_arith_shrink(p, hp);
-#endif
+ }
+ else {
+ erts_heap_frag_shrink(p, hp);
}
} else if ((actual = bignum_header_arity(*hp)+1) < alloc) {
if (p->heap <= hp && hp < p->htop) {
p->htop = hp+actual;
-#if defined(CHECK_FOR_HOLES)
- } else {
- erts_arith_shrink(p, hp+actual);
-#endif
+ }
+ else {
+ erts_heap_frag_shrink(p, hp+actual);
}
}
}
@@ -397,12 +395,11 @@ erts_mixed_plus(Process* p, Eterm arg1, Eterm arg2)
need_heap = BIG_NEED_SIZE(sz);
hp = HAlloc(p, need_heap);
res = big_plus(arg1, arg2, hp);
+ maybe_shrink(p, hp, res, need_heap);
if (is_nil(res)) {
- erts_arith_shrink(p, hp);
p->freason = SYSTEM_LIMIT;
return THE_NON_VALUE;
}
- maybe_shrink(p, hp, res, need_heap);
return res;
case (_TAG_HEADER_FLOAT >> _TAG_PRIMARY_SIZE):
if (big_to_double(arg1, &f1.fd) < 0) {
@@ -533,12 +530,11 @@ erts_mixed_minus(Process* p, Eterm arg1, Eterm arg2)
need_heap = BIG_NEED_SIZE(sz);
hp = HAlloc(p, need_heap);
res = big_minus(arg1, arg2, hp);
+ maybe_shrink(p, hp, res, need_heap);
if (is_nil(res)) {
- erts_arith_shrink(p, hp);
p->freason = SYSTEM_LIMIT;
return THE_NON_VALUE;
}
- maybe_shrink(p, hp, res, need_heap);
return res;
default:
goto badarith;
@@ -731,12 +727,11 @@ erts_mixed_times(Process* p, Eterm arg1, Eterm arg2)
* the absolute value of the other is > 1.
*/
+ maybe_shrink(p, hp, res, need_heap);
if (is_nil(res)) {
- erts_arith_shrink(p, hp);
p->freason = SYSTEM_LIMIT;
return THE_NON_VALUE;
- }
- maybe_shrink(p, hp, res, need_heap);
+ }
return res;
case (_TAG_HEADER_FLOAT >> _TAG_PRIMARY_SIZE):
if (big_to_double(arg1, &f1.fd) < 0) {
@@ -956,12 +951,11 @@ erts_int_div(Process* p, Eterm arg1, Eterm arg2)
need = BIG_NEED_SIZE(i-ires+1) + BIG_NEED_SIZE(i);
hp = HAlloc(p, need);
arg1 = big_div(arg1, arg2, hp);
+ maybe_shrink(p, hp, arg1, need);
if (is_nil(arg1)) {
- erts_arith_shrink(p, hp);
p->freason = SYSTEM_LIMIT;
return THE_NON_VALUE;
}
- maybe_shrink(p, hp, arg1, need);
}
return arg1;
default:
@@ -1004,12 +998,11 @@ erts_int_rem(Process* p, Eterm arg1, Eterm arg2)
Eterm* hp = HAlloc(p, need);
arg1 = big_rem(arg1, arg2, hp);
+ maybe_shrink(p, hp, arg1, need);
if (is_nil(arg1)) {
- erts_arith_shrink(p, hp);
p->freason = SYSTEM_LIMIT;
return THE_NON_VALUE;
}
- maybe_shrink(p, hp, arg1, need);
}
return arg1;
default:
@@ -1147,7 +1140,7 @@ trim_heap(Process* p, Eterm* hp, Eterm res)
* a garbage collection if there is insufficient heap space.
*/
-#define erts_arith_shrink horrible error
+#define erts_heap_frag_shrink horrible error
#define maybe_shrink horrible error
Eterm
diff --git a/erts/emulator/beam/erl_bif_guard.c b/erts/emulator/beam/erl_bif_guard.c
index 8b47db10dd..440b0b4f14 100644
--- a/erts/emulator/beam/erl_bif_guard.c
+++ b/erts/emulator/beam/erl_bif_guard.c
@@ -1,19 +1,19 @@
/*
* %CopyrightBegin%
- *
- * Copyright Ericsson AB 2006-2009. All Rights Reserved.
- *
+ *
+ * Copyright Ericsson AB 2006-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%
*/
@@ -318,6 +318,10 @@ double_to_integer(Process* p, double x)
* The following code is used when a guard that may build on the
* heap is called directly. They must not use HAlloc(), but must
* do a garbage collection if there is insufficient heap space.
+ *
+ * Important note: All error checking MUST be done before doing
+ * a garbage collection. The compiler assumes that all registers
+ * are still valid if a guard BIF generates an exception.
*/
#define ERTS_NEED_GC(p, need) ((HEAP_LIMIT((p)) - HEAP_TOP((p))) <= (need))
diff --git a/erts/emulator/beam/erl_bif_info.c b/erts/emulator/beam/erl_bif_info.c
index 60216aa8e4..a34d400ed8 100644
--- a/erts/emulator/beam/erl_bif_info.c
+++ b/erts/emulator/beam/erl_bif_info.c
@@ -1,19 +1,19 @@
/*
* %CopyrightBegin%
- *
- * Copyright Ericsson AB 1999-2009. All Rights Reserved.
- *
+ *
+ * Copyright Ericsson AB 1999-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%
*/
@@ -543,6 +543,8 @@ static Eterm pi_args[] = {
am_last_calls,
am_total_heap_size,
am_suspending,
+ am_min_heap_size,
+ am_min_bin_vheap_size,
#ifdef HYBRID
am_message_binary
#endif
@@ -589,8 +591,10 @@ pi_arg2ix(Eterm arg)
case am_last_calls: return 24;
case am_total_heap_size: return 25;
case am_suspending: return 26;
+ case am_min_heap_size: return 27;
+ case am_min_bin_vheap_size: return 28;
#ifdef HYBRID
- case am_message_binary: return 27;
+ case am_message_binary: return 29;
#endif
default: return -1;
}
@@ -1355,6 +1359,30 @@ process_info_aux(Process *BIF_P,
break;
}
+ case am_fullsweep_after: {
+ Uint hsz = 3;
+ (void) erts_bld_uint(NULL, &hsz, MAX_GEN_GCS(rp));
+ hp = HAlloc(BIF_P, hsz);
+ res = erts_bld_uint(&hp, NULL, MAX_GEN_GCS(rp));
+ break;
+ }
+
+ case am_min_heap_size: {
+ Uint hsz = 3;
+ (void) erts_bld_uint(NULL, &hsz, MIN_HEAP_SIZE(rp));
+ hp = HAlloc(BIF_P, hsz);
+ res = erts_bld_uint(&hp, NULL, MIN_HEAP_SIZE(rp));
+ break;
+ }
+
+ case am_min_bin_vheap_size: {
+ Uint hsz = 3;
+ (void) erts_bld_uint(NULL, &hsz, MIN_VHEAP_SIZE(rp));
+ hp = HAlloc(BIF_P, hsz);
+ res = erts_bld_uint(&hp, NULL, MIN_VHEAP_SIZE(rp));
+ break;
+ }
+
case am_total_heap_size: {
ErlMessage *mp;
Uint total_heap_size;
@@ -1433,15 +1461,17 @@ process_info_aux(Process *BIF_P,
DECL_AM(minor_gcs);
Eterm t;
- hp = HAlloc(BIF_P, 3+2+3+2+3);
- t = TUPLE2(hp, AM_minor_gcs, make_small(GEN_GCS(rp)));
- hp += 3;
- res = CONS(hp, t, NIL);
- hp += 2;
- t = TUPLE2(hp, am_fullsweep_after, make_small(MAX_GEN_GCS(rp)));
- hp += 3;
- res = CONS(hp, t, res);
- hp += 2;
+ hp = HAlloc(BIF_P, 3+2 + 3+2 + 3+2 + 3+2 + 3); /* last "3" is for outside tuple */
+
+ t = TUPLE2(hp, AM_minor_gcs, make_small(GEN_GCS(rp))); hp += 3;
+ res = CONS(hp, t, NIL); hp += 2;
+ t = TUPLE2(hp, am_fullsweep_after, make_small(MAX_GEN_GCS(rp))); hp += 3;
+ res = CONS(hp, t, res); hp += 2;
+
+ t = TUPLE2(hp, am_min_heap_size, make_small(MIN_HEAP_SIZE(rp))); hp += 3;
+ res = CONS(hp, t, res); hp += 2;
+ t = TUPLE2(hp, am_min_bin_vheap_size, make_small(MIN_VHEAP_SIZE(rp))); hp += 3;
+ res = CONS(hp, t, res); hp += 2;
break;
}
@@ -1897,16 +1927,32 @@ BIF_RETTYPE system_info_1(BIF_ALIST_1)
BIF_RET(res);
} else if (BIF_ARG_1 == am_garbage_collection){
Uint val = (Uint) erts_smp_atomic_read(&erts_max_gen_gcs);
- hp = HAlloc(BIF_P, 3+2);
- res = TUPLE2(hp, am_fullsweep_after, make_small(val));
- hp += 3;
- res = CONS(hp, res, NIL);
+ Eterm tup;
+ hp = HAlloc(BIF_P, 3+2 + 3+2 + 3+2);
+
+ tup = TUPLE2(hp, am_fullsweep_after, make_small(val)); hp += 3;
+ res = CONS(hp, tup, NIL); hp += 2;
+
+ tup = TUPLE2(hp, am_min_heap_size, make_small(H_MIN_SIZE)); hp += 3;
+ res = CONS(hp, tup, res); hp += 2;
+
+ tup = TUPLE2(hp, am_min_bin_vheap_size, make_small(BIN_VH_MIN_SIZE)); hp += 3;
+ res = CONS(hp, tup, res); hp += 2;
+
BIF_RET(res);
} else if (BIF_ARG_1 == am_fullsweep_after){
Uint val = (Uint) erts_smp_atomic_read(&erts_max_gen_gcs);
hp = HAlloc(BIF_P, 3);
res = TUPLE2(hp, am_fullsweep_after, make_small(val));
BIF_RET(res);
+ } else if (BIF_ARG_1 == am_min_heap_size) {
+ hp = HAlloc(BIF_P, 3);
+ res = TUPLE2(hp, am_min_heap_size,make_small(H_MIN_SIZE));
+ BIF_RET(res);
+ } else if (BIF_ARG_1 == am_min_bin_vheap_size) {
+ hp = HAlloc(BIF_P, 3);
+ res = TUPLE2(hp, am_min_bin_vheap_size,make_small(BIN_VH_MIN_SIZE));
+ BIF_RET(res);
} else if (BIF_ARG_1 == am_process_count) {
BIF_RET(make_small(erts_process_count()));
} else if (BIF_ARG_1 == am_process_limit) {
@@ -3131,6 +3177,13 @@ BIF_RETTYPE erts_debug_get_internal_state_1(BIF_ALIST_1)
else if (ERTS_IS_ATOM_STR("available_internal_state", BIF_ARG_1)) {
BIF_RET(am_true);
}
+ else if (ERTS_IS_ATOM_STR("force_heap_frags", BIF_ARG_1)) {
+#ifdef FORCE_HEAP_FRAGS
+ BIF_RET(am_true);
+#else
+ BIF_RET(am_false);
+#endif
+ }
}
else if (is_tuple(BIF_ARG_1)) {
Eterm* tp = tuple_val(BIF_ARG_1);
@@ -3651,12 +3704,11 @@ static Eterm lcnt_build_lock_term(Eterm **hpp, Uint *szp, erts_lcnt_lock_t *lock
ASSERT(ltype);
type = am_atom_put(ltype, strlen(ltype));
-
name = am_atom_put(lock->name, strlen(lock->name));
if (lock->flag & ERTS_LCNT_LT_ALLOC) {
/* use allocator types names as id's for allocator locks */
- ltype = ERTS_ALC_A2AD(signed_val(lock->id));
+ ltype = (char *) ERTS_ALC_A2AD(signed_val(lock->id));
id = am_atom_put(ltype, strlen(ltype));
} else if (lock->flag & ERTS_LCNT_LT_PROCLOCK) {
/* use registered names as id's for process locks if available */
@@ -3725,17 +3777,28 @@ BIF_RETTYPE erts_debug_lock_counters_1(BIF_ALIST_1)
{
#ifdef ERTS_ENABLE_LOCK_COUNT
Eterm res = NIL;
- erts_smp_proc_unlock(BIF_P, ERTS_PROC_LOCK_MAIN);
- erts_smp_block_system(0);
+#endif
+
+
+ if (BIF_ARG_1 == am_enabled) {
+#ifdef ERTS_ENABLE_LOCK_COUNT
+ BIF_RET(am_true);
+#else
+ BIF_RET(am_false);
+#endif
+ }
+#ifdef ERTS_ENABLE_LOCK_COUNT
- if (BIF_ARG_1 == am_info) {
+ else if (BIF_ARG_1 == am_info) {
erts_lcnt_data_t *data;
Uint hsize = 0;
Uint *szp;
Eterm* hp;
- erts_lcnt_set_rt_opt(ERTS_LCNT_OPT_SUSPEND);
+ erts_smp_proc_unlock(BIF_P, ERTS_PROC_LOCK_MAIN);
+ erts_smp_block_system(0);
+ erts_lcnt_set_rt_opt(ERTS_LCNT_OPT_SUSPEND);
data = erts_lcnt_get_data();
/* calculate size */
@@ -3750,29 +3813,65 @@ BIF_RETTYPE erts_debug_lock_counters_1(BIF_ALIST_1)
res = lcnt_build_result_term(&hp, NULL, data, res);
erts_lcnt_clear_rt_opt(ERTS_LCNT_OPT_SUSPEND);
+
+ erts_smp_release_system();
+ erts_smp_proc_lock(BIF_P, ERTS_PROC_LOCK_MAIN);
- goto done;
+ BIF_RET(res);
} else if (BIF_ARG_1 == am_clear) {
+ erts_smp_proc_unlock(BIF_P, ERTS_PROC_LOCK_MAIN);
+ erts_smp_block_system(0);
+
erts_lcnt_clear_counters();
- res = am_ok;
- goto done;
+
+ erts_smp_release_system();
+ erts_smp_proc_lock(BIF_P, ERTS_PROC_LOCK_MAIN);
+
+ BIF_RET(am_ok);
} else if (is_tuple(BIF_ARG_1)) {
- Uint prev = 0;
Eterm* tp = tuple_val(BIF_ARG_1);
+
switch (arityval(tp[0])) {
case 2:
- if (ERTS_IS_ATOM_STR("process_locks", tp[1])) {
+ if (ERTS_IS_ATOM_STR("copy_save", tp[1])) {
+ erts_smp_proc_unlock(BIF_P, ERTS_PROC_LOCK_MAIN);
+ erts_smp_block_system(0);
if (tp[2] == am_true) {
- prev = erts_lcnt_set_rt_opt(ERTS_LCNT_OPT_PROCLOCK);
- if (prev) res = am_true;
- else res = am_false;
- goto done;
+
+ res = erts_lcnt_set_rt_opt(ERTS_LCNT_OPT_COPYSAVE) ? am_true : am_false;
+
} else if (tp[2] == am_false) {
- prev = erts_lcnt_clear_rt_opt(ERTS_LCNT_OPT_PROCLOCK);
- if (prev) res = am_true;
- else res = am_false;
- goto done;
+
+ res = erts_lcnt_clear_rt_opt(ERTS_LCNT_OPT_COPYSAVE) ? am_true : am_false;
+
+ } else {
+ erts_smp_release_system();
+ erts_smp_proc_lock(BIF_P, ERTS_PROC_LOCK_MAIN);
+ BIF_ERROR(BIF_P, BADARG);
+ }
+ erts_smp_release_system();
+ erts_smp_proc_lock(BIF_P, ERTS_PROC_LOCK_MAIN);
+ BIF_RET(res);
+
+ } else if (ERTS_IS_ATOM_STR("process_locks", tp[1])) {
+ erts_smp_proc_unlock(BIF_P, ERTS_PROC_LOCK_MAIN);
+ erts_smp_block_system(0);
+ if (tp[2] == am_true) {
+
+ res = erts_lcnt_set_rt_opt(ERTS_LCNT_OPT_PROCLOCK) ? am_true : am_false;
+
+ } else if (tp[2] == am_false) {
+
+ res = erts_lcnt_set_rt_opt(ERTS_LCNT_OPT_PROCLOCK) ? am_true : am_false;
+
+ } else {
+ erts_smp_release_system();
+ erts_smp_proc_lock(BIF_P, ERTS_PROC_LOCK_MAIN);
+ BIF_ERROR(BIF_P, BADARG);
}
+ erts_smp_release_system();
+ erts_smp_proc_lock(BIF_P, ERTS_PROC_LOCK_MAIN);
+ BIF_RET(res);
}
break;
@@ -3781,16 +3880,8 @@ BIF_RETTYPE erts_debug_lock_counters_1(BIF_ALIST_1)
}
}
- erts_smp_release_system();
- erts_smp_proc_lock(BIF_P, ERTS_PROC_LOCK_MAIN);
#endif
BIF_ERROR(BIF_P, BADARG);
-#ifdef ERTS_ENABLE_LOCK_COUNT
-done:
- erts_smp_release_system();
- erts_smp_proc_lock(BIF_P, ERTS_PROC_LOCK_MAIN);
- BIF_RET(res);
-#endif
}
void
diff --git a/erts/emulator/beam/erl_bif_re.c b/erts/emulator/beam/erl_bif_re.c
index 16abab65b0..c027cd5984 100644
--- a/erts/emulator/beam/erl_bif_re.c
+++ b/erts/emulator/beam/erl_bif_re.c
@@ -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%
*/
@@ -884,7 +884,7 @@ re_run_3(BIF_ALIST_3)
int capture_count;
if (pflags & PARSE_FLAG_UNICODE &&
- (!is_binary(BIF_ARG_1) ||
+ (!is_binary(BIF_ARG_2) || !is_binary(BIF_ARG_1) ||
(is_list_cap && !(pflags & PARSE_FLAG_GLOBAL)))) {
BIF_TRAP3(urun_trap_exportp, BIF_P, BIF_ARG_1, BIF_ARG_2, BIF_ARG_3);
}
@@ -1020,6 +1020,9 @@ re_run_3(BIF_ALIST_3)
goto handle_iolist;
}
pb = (ProcBin *) bptr;
+ if (pb->flags) {
+ erts_emasculate_writable_binary(pb);
+ }
restart.subject = (char *) (pb->bytes+offset);
restart.flags |= RESTART_FLAG_SUBJECT_IN_BINARY;
} else {
diff --git a/erts/emulator/beam/erl_binary.h b/erts/emulator/beam/erl_binary.h
index dc5539faad..1f948a9684 100644
--- a/erts/emulator/beam/erl_binary.h
+++ b/erts/emulator/beam/erl_binary.h
@@ -1,19 +1,19 @@
/*
* %CopyrightBegin%
- *
- * Copyright Ericsson AB 2000-2009. All Rights Reserved.
- *
+ *
+ * Copyright Ericsson AB 2000-2010. All Rights Reserved.
+ *
* The contents of this file are subject to the Erlang Public License,
* Version 1.1, (the "License"); you may not use this file except in
* compliance with the License. You should have received a copy of the
* Erlang Public License along with this software. If not, it can be
* retrieved online at http://www.erlang.org/.
- *
+ *
* Software distributed under the License is distributed on an "AS IS"
* basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
* the License for the specific language governing rights and limitations
* under the License.
- *
+ *
* %CopyrightEnd%
*/
@@ -150,7 +150,7 @@ do { \
void erts_init_binary(void);
-byte* erts_get_aligned_binary_bytes(Eterm, byte**);
+byte* erts_get_aligned_binary_bytes_extra(Eterm, byte**, unsigned extra);
#if defined(__i386__) || !defined(__GNUC__)
/*
@@ -166,6 +166,7 @@ byte* erts_get_aligned_binary_bytes(Eterm, byte**);
#define ERTS_CHK_BIN_ALIGNMENT(B) \
do { ASSERT(!(B) || (((Uint) &((Binary *)(B))->orig_bytes[0]) & ERTS_BIN_ALIGNMENT_MASK) == ((Uint) 0)) } while(0)
+ERTS_GLB_INLINE byte* erts_get_aligned_binary_bytes(Eterm bin, byte** base_ptr);
ERTS_GLB_INLINE void erts_free_aligned_binary_bytes(byte* buf);
ERTS_GLB_INLINE Binary *erts_bin_drv_alloc_fnf(Uint size);
ERTS_GLB_INLINE Binary *erts_bin_drv_alloc(Uint size);
@@ -178,6 +179,14 @@ ERTS_GLB_INLINE Binary *erts_create_magic_binary(Uint size,
#if ERTS_GLB_INLINE_INCL_FUNC_DEF
+#include <stddef.h> /* offsetof */
+
+ERTS_GLB_INLINE byte*
+erts_get_aligned_binary_bytes(Eterm bin, byte** base_ptr)
+{
+ return erts_get_aligned_binary_bytes_extra(bin, base_ptr, 0);
+}
+
ERTS_GLB_INLINE void
erts_free_aligned_binary_bytes(byte* buf)
{
@@ -186,10 +195,20 @@ erts_free_aligned_binary_bytes(byte* buf)
}
}
+/* Explicit extra bytes allocated to counter buggy drivers.
+** These extra bytes where earlier (< R13B04) added by an alignment-bug
+** in this code. Do we dare remove this in some major release (R14?) maybe?
+*/
+#ifdef DEBUG
+# define CHICKEN_PAD 0
+#else
+# define CHICKEN_PAD (sizeof(void*) - 1)
+#endif
+
ERTS_GLB_INLINE Binary *
erts_bin_drv_alloc_fnf(Uint size)
{
- Uint bsize = sizeof(Binary) - 1 + size;
+ Uint bsize = ERTS_SIZEOF_Binary(size) + CHICKEN_PAD;
void *res;
res = erts_alloc_fnf(ERTS_ALC_T_DRV_BINARY, bsize);
ERTS_CHK_BIN_ALIGNMENT(res);
@@ -199,7 +218,7 @@ erts_bin_drv_alloc_fnf(Uint size)
ERTS_GLB_INLINE Binary *
erts_bin_drv_alloc(Uint size)
{
- Uint bsize = sizeof(Binary) - 1 + size;
+ Uint bsize = ERTS_SIZEOF_Binary(size) + CHICKEN_PAD;
void *res;
res = erts_alloc(ERTS_ALC_T_DRV_BINARY, bsize);
ERTS_CHK_BIN_ALIGNMENT(res);
@@ -210,7 +229,7 @@ erts_bin_drv_alloc(Uint size)
ERTS_GLB_INLINE Binary *
erts_bin_nrml_alloc(Uint size)
{
- Uint bsize = sizeof(Binary) - 1 + size;
+ Uint bsize = ERTS_SIZEOF_Binary(size) + CHICKEN_PAD;
void *res;
res = erts_alloc(ERTS_ALC_T_BINARY, bsize);
ERTS_CHK_BIN_ALIGNMENT(res);
@@ -221,7 +240,7 @@ ERTS_GLB_INLINE Binary *
erts_bin_realloc_fnf(Binary *bp, Uint size)
{
Binary *nbp;
- Uint bsize = sizeof(Binary) - 1 + size;
+ Uint bsize = ERTS_SIZEOF_Binary(size) + CHICKEN_PAD;
ASSERT((bp->flags & BIN_FLAG_MAGIC) == 0);
if (bp->flags & BIN_FLAG_DRV)
nbp = erts_realloc_fnf(ERTS_ALC_T_DRV_BINARY, (void *) bp, bsize);
@@ -235,7 +254,7 @@ ERTS_GLB_INLINE Binary *
erts_bin_realloc(Binary *bp, Uint size)
{
Binary *nbp;
- Uint bsize = sizeof(Binary) - 1 + size;
+ Uint bsize = ERTS_SIZEOF_Binary(size) + CHICKEN_PAD;
ASSERT((bp->flags & BIN_FLAG_MAGIC) == 0);
if (bp->flags & BIN_FLAG_DRV)
nbp = erts_realloc_fnf(ERTS_ALC_T_DRV_BINARY, (void *) bp, bsize);
@@ -265,13 +284,13 @@ erts_bin_free(Binary *bp)
ERTS_GLB_INLINE Binary *
erts_create_magic_binary(Uint size, void (*destructor)(Binary *))
{
- Uint bsize = sizeof(Binary) - 1 + sizeof(ErtsBinaryMagicPart) - 1 + size;
+ Uint bsize = ERTS_MAGIC_BIN_SIZE(size);
Binary* bptr = erts_alloc_fnf(ERTS_ALC_T_BINARY, bsize);
if (!bptr)
erts_alloc_n_enomem(ERTS_ALC_T2N(ERTS_ALC_T_BINARY), bsize);
ERTS_CHK_BIN_ALIGNMENT(bptr);
bptr->flags = BIN_FLAG_MAGIC;
- bptr->orig_size = sizeof(ErtsBinaryMagicPart) - 1 + size;
+ bptr->orig_size = ERTS_MAGIC_BIN_ORIG_SIZE(size);
erts_refc_init(&bptr->refc, 0);
ERTS_MAGIC_BIN_DESTRUCTOR(bptr) = destructor;
return bptr;
diff --git a/erts/emulator/beam/erl_db.c b/erts/emulator/beam/erl_db.c
index b02150008f..15b1c6bb56 100644
--- a/erts/emulator/beam/erl_db.c
+++ b/erts/emulator/beam/erl_db.c
@@ -1,19 +1,19 @@
/*
* %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
* 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%
*/
@@ -261,13 +261,8 @@ static ERTS_INLINE void db_init_lock(DbTable* tb, char *rwname, char* fixname)
erts_refc_init(&tb->common.ref, 1);
erts_refc_init(&tb->common.fixref, 0);
#ifdef ERTS_SMP
-# ifdef ERTS_ENABLE_LOCK_COUNT
erts_smp_rwmtx_init_x(&tb->common.rwlock, rwname, tb->common.the_name);
erts_smp_mtx_init_x(&tb->common.fixlock, fixname, tb->common.the_name);
-# else
- erts_smp_rwmtx_init(&tb->common.rwlock, rwname);
- erts_smp_mtx_init(&tb->common.fixlock, fixname);
-# endif
tb->common.is_thread_safe = !(tb->common.status & DB_FINE_LOCKED);
#endif
}
@@ -2597,19 +2592,11 @@ void init_db(void)
#ifdef ERTS_SMP
for (i=0; i<META_MAIN_TAB_LOCK_CNT; i++) {
-#ifdef ERTS_ENABLE_LOCK_COUNT
erts_smp_spinlock_init_x(&meta_main_tab_locks[i].lck, "meta_main_tab_slot", make_small(i));
-#else
- erts_smp_spinlock_init(&meta_main_tab_locks[i].lck, "meta_main_tab_slot");
-#endif
}
erts_smp_spinlock_init(&meta_main_tab_main_lock, "meta_main_tab_main");
for (i=0; i<META_NAME_TAB_LOCK_CNT; i++) {
-#ifdef ERTS_ENABLE_LOCK_COUNT
erts_smp_rwmtx_init_x(&meta_name_tab_rwlocks[i].lck, "meta_name_tab", make_small(i));
-#else
- erts_smp_rwmtx_init(&meta_name_tab_rwlocks[i].lck, "meta_name_tab");
-#endif
}
#endif
diff --git a/erts/emulator/beam/erl_db_hash.c b/erts/emulator/beam/erl_db_hash.c
index dea45053df..4141f9766b 100644
--- a/erts/emulator/beam/erl_db_hash.c
+++ b/erts/emulator/beam/erl_db_hash.c
@@ -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%
*/
@@ -628,11 +628,7 @@ int db_create_hash(Process *p, DbTable *tbl)
(DbTable *) tb,
sizeof(DbTableHashFineLocks));
for (i=0; i<DB_HASH_LOCK_CNT; ++i) {
- #ifdef ERTS_ENABLE_LOCK_COUNT
- erts_rwmtx_init_x(&tb->locks->lck_vec[i].lck, "db_hash_slot", tb->common.the_name);
- #else
- erts_rwmtx_init(&tb->locks->lck_vec[i].lck, "db_hash_slot");
- #endif
+ erts_rwmtx_init_x(&tb->locks->lck_vec[i].lck, "db_hash_slot", make_small(i));
}
/* This important property is needed to guarantee that the buckets
* involved in a grow/shrink operation it protected by the same lock:
diff --git a/erts/emulator/beam/erl_db_tree.c b/erts/emulator/beam/erl_db_tree.c
index d3a916d2d9..b421da591b 100644
--- a/erts/emulator/beam/erl_db_tree.c
+++ b/erts/emulator/beam/erl_db_tree.c
@@ -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%
*/
@@ -2529,7 +2529,9 @@ static TreeDbTerm *find_node(DbTableTree *tb, Eterm key)
this = this->right;
}
}
- release_stack(tb,stack);
+ if (stack) {
+ release_stack(tb,stack);
+ }
return this;
}
diff --git a/erts/emulator/beam/erl_debug.c b/erts/emulator/beam/erl_debug.c
index 34ce87bc5d..e5c3c76fdd 100644
--- a/erts/emulator/beam/erl_debug.c
+++ b/erts/emulator/beam/erl_debug.c
@@ -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%
*/
@@ -344,7 +344,7 @@ void erts_check_for_holes(Process* p)
if (hf == p->last_mbuf) {
break;
}
- check_memory(hf->mem, hf->mem+hf->size);
+ check_memory(hf->mem, hf->mem+hf->used_size);
}
p->last_mbuf = MBUF(p);
}
@@ -386,7 +386,7 @@ void erts_check_heap(Process *p)
}
while (bp) {
- erts_check_memory(p,bp->mem,bp->mem + bp->size);
+ erts_check_memory(p,bp->mem,bp->mem + bp->used_size);
bp = bp->next;
}
}
diff --git a/erts/emulator/beam/erl_driver.h b/erts/emulator/beam/erl_driver.h
index cdb584b282..489e74d960 100644
--- a/erts/emulator/beam/erl_driver.h
+++ b/erts/emulator/beam/erl_driver.h
@@ -1,19 +1,19 @@
/*
* %CopyrightBegin%
- *
- * Copyright Ericsson AB 1999-2009. All Rights Reserved.
- *
+ *
+ * Copyright Ericsson AB 1999-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%
*/
@@ -65,6 +65,8 @@
# error SIZEOF_LONG_LONG mismatch
#endif
+#include "erl_drv_nif.h"
+
#include <stdlib.h>
#if defined(VXWORKS)
@@ -116,7 +118,7 @@ typedef struct {
#define ERL_DRV_EXTENDED_MARKER (0xfeeeeeed)
#define ERL_DRV_EXTENDED_MAJOR_VERSION 1
-#define ERL_DRV_EXTENDED_MINOR_VERSION 4
+#define ERL_DRV_EXTENDED_MINOR_VERSION 5
/*
* The emulator will refuse to load a driver with different major
@@ -195,22 +197,6 @@ typedef struct {
unsigned char data[sizeof(void *)*4];
} ErlDrvMonitor;
-
-/*
- * System info
- */
-
-typedef struct {
- int driver_major_version;
- int driver_minor_version;
- char *erts_version;
- char *otp_release;
- int thread_support;
- int smp_support;
- int async_threads;
- int scheduler_threads;
-} ErlDrvSysInfo;
-
typedef struct {
unsigned long megasecs;
unsigned long secs;
@@ -255,9 +241,6 @@ typedef struct ErlDrvCond_ ErlDrvCond;
typedef struct ErlDrvRWLock_ ErlDrvRWLock;
typedef int ErlDrvTSDKey;
-typedef struct {
- int suggested_stack_size;
-} ErlDrvThreadOpts;
/*
*
diff --git a/erts/emulator/beam/erl_drv_nif.h b/erts/emulator/beam/erl_drv_nif.h
new file mode 100644
index 0000000000..ea013a49a3
--- /dev/null
+++ b/erts/emulator/beam/erl_drv_nif.h
@@ -0,0 +1,48 @@
+/*
+ * %CopyrightBegin%
+ *
+ * Copyright Ericsson AB 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%
+ */
+
+/*
+ * Common structures for both erl_driver.h and erl_nif.h
+ */
+
+#ifndef __ERL_DRV_NIF_H__
+#define __ERL_DRV_NIF_H__
+
+typedef struct {
+ int driver_major_version;
+ int driver_minor_version;
+ char *erts_version;
+ char *otp_release;
+ int thread_support;
+ int smp_support;
+ int async_threads;
+ int scheduler_threads;
+ int nif_major_version;
+ int nif_minor_version;
+} ErlDrvSysInfo;
+
+typedef struct {
+ int suggested_stack_size;
+} ErlDrvThreadOpts;
+
+#endif /* __ERL_DRV_NIF_H__ */
+
+
+
+
diff --git a/erts/emulator/beam/erl_gc.c b/erts/emulator/beam/erl_gc.c
index 6945317e65..e9bf37a173 100644
--- a/erts/emulator/beam/erl_gc.c
+++ b/erts/emulator/beam/erl_gc.c
@@ -1,19 +1,19 @@
/*
* %CopyrightBegin%
- *
- * Copyright Ericsson AB 2002-2009. All Rights Reserved.
- *
+ *
+ * Copyright Ericsson AB 2002-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%
*/
#ifdef HAVE_CONFIG_H
@@ -961,12 +961,13 @@ do_minor(Process *p, int new_sz, Eterm* objv, int nobj)
n_htop = sweep_one_area(n_heap, n_htop, heap, heap_size);
} else {
Eterm* n_hp = n_heap;
+ Eterm* ptr;
+ Eterm val;
+ Eterm gval;
while (n_hp != n_htop) {
- Eterm* ptr;
- Eterm val;
- Eterm gval = *n_hp;
-
+ ASSERT(n_hp < n_htop);
+ gval = *n_hp;
switch (primary_tag(gval)) {
case TAG_PRIMARY_BOXED: {
ptr = boxed_val(gval);
@@ -1402,68 +1403,6 @@ remove_message_buffers(Process* p)
}
}
-/*
- * Go through one root set array, move everything that it is one of the
- * heap fragments to our new heap.
- */
-static Eterm*
-collect_root_array(Process* p, Eterm* n_htop, Eterm* objv, int nobj)
-{
- ErlHeapFragment* qb;
- Eterm gval;
- Eterm* ptr;
- Eterm val;
-
- ASSERT(p->htop != NULL);
- while (nobj--) {
- gval = *objv;
-
- switch (primary_tag(gval)) {
-
- case TAG_PRIMARY_BOXED: {
- ptr = boxed_val(gval);
- val = *ptr;
- if (IS_MOVED(val)) {
- ASSERT(is_boxed(val));
- *objv++ = val;
- } else {
- for (qb = MBUF(p); qb != NULL; qb = qb->next) {
- if (in_area(ptr, qb->mem, qb->size*sizeof(Eterm))) {
- MOVE_BOXED(ptr,val,n_htop,objv);
- break;
- }
- }
- objv++;
- }
- break;
- }
-
- case TAG_PRIMARY_LIST: {
- ptr = list_val(gval);
- val = *ptr;
- if (is_non_value(val)) {
- *objv++ = ptr[1];
- } else {
- for (qb = MBUF(p); qb != NULL; qb = qb->next) {
- if (in_area(ptr, qb->mem, qb->size*sizeof(Eterm))) {
- MOVE_CONS(ptr,val,n_htop,objv);
- break;
- }
- }
- objv++;
- }
- break;
- }
-
- default: {
- objv++;
- break;
- }
- }
- }
- return n_htop;
-}
-
#ifdef HARDDEBUG
/*
@@ -1707,11 +1646,13 @@ sweep_rootset(Rootset* rootset, Eterm* htop, char* src, Uint src_size)
static Eterm*
sweep_one_area(Eterm* n_hp, Eterm* n_htop, char* src, Uint src_size)
{
- while (n_hp != n_htop) {
- Eterm* ptr;
- Eterm val;
- Eterm gval = *n_hp;
+ Eterm* ptr;
+ Eterm val;
+ Eterm gval;
+ while (n_hp != n_htop) {
+ ASSERT(n_hp < n_htop);
+ gval = *n_hp;
switch (primary_tag(gval)) {
case TAG_PRIMARY_BOXED: {
ptr = boxed_val(gval);
@@ -1820,6 +1761,35 @@ sweep_one_heap(Eterm* heap_ptr, Eterm* heap_end, Eterm* htop, char* src, Uint sr
}
/*
+ * Move an area (heap fragment) by sweeping over it and set move markers.
+ */
+static Eterm*
+move_one_area(Eterm* n_htop, char* src, Uint src_size)
+{
+ Eterm* ptr = (Eterm*) src;
+ Eterm* end = ptr + src_size/sizeof(Eterm);
+ Eterm dummy_ref;
+
+ while (ptr != end) {
+ Eterm val;
+ ASSERT(ptr < end);
+ val = *ptr;
+ ASSERT(val != ERTS_HOLE_MARKER);
+ if (is_header(val)) {
+ ASSERT(ptr + header_arity(val) < end);
+ MOVE_BOXED(ptr, val, n_htop, &dummy_ref);
+ }
+ else { /* must be a cons cell */
+ ASSERT(ptr+1 < end);
+ MOVE_CONS(ptr, val, n_htop, &dummy_ref);
+ ptr += 2;
+ }
+ }
+
+ return n_htop;
+}
+
+/*
* Collect heap fragments and check that they point in the correct direction.
*/
@@ -1830,7 +1800,6 @@ collect_heap_frags(Process* p, Eterm* n_hstart, Eterm* n_htop,
ErlHeapFragment* qb;
char* frag_begin;
Uint frag_size;
- ErlMessage* mp;
/*
* We don't allow references to a heap fragments from the stack, heap,
@@ -1845,65 +1814,44 @@ collect_heap_frags(Process* p, Eterm* n_hstart, Eterm* n_htop,
#endif
/*
- * Go through the subset of the root set that is allowed to
- * reference data in heap fragments and move data from heap fragments
- * to our new heap.
- */
-
- if (nobj != 0) {
- n_htop = collect_root_array(p, n_htop, objv, nobj);
- }
- if (is_not_immed(p->fvalue)) {
- n_htop = collect_root_array(p, n_htop, &p->fvalue, 1);
- }
- if (is_not_immed(p->ftrace)) {
- n_htop = collect_root_array(p, n_htop, &p->ftrace, 1);
- }
- if (is_not_immed(p->seq_trace_token)) {
- n_htop = collect_root_array(p, n_htop, &p->seq_trace_token, 1);
- }
- if (is_not_immed(p->group_leader)) {
- n_htop = collect_root_array(p, n_htop, &p->group_leader, 1);
- }
-
- /*
- * Go through the message queue, move everything that is in one of the
- * heap fragments to our new heap.
- */
-
- for (mp = p->msg.first; mp != NULL; mp = mp->next) {
- /*
- * In most cases, mp->data.attached points to a heap fragment which is
- * self-contained and we will copy it to the heap at the
- * end of the GC to avoid scanning it.
- *
- * In a few cases, however, such as in process_info(Pid, messages)
- * and trace_delivered/1, a new message points to a term that has
- * been allocated by HAlloc() and mp->data.attached is NULL. Therefore
- * we need this loop.
- */
- if (mp->data.attached == NULL) {
- n_htop = collect_root_array(p, n_htop, mp->m, 2);
- }
- }
-
- /*
- * Now all references in the root set point to the new heap. However,
- * many references on the new heap point to heap fragments.
- */
-
+ * Move the heap fragments to the new heap. Note that no GC is done on
+ * the heap fragments. Any garbage will thus be moved as well and survive
+ * until next GC.
+ */
qb = MBUF(p);
- while (qb != NULL) {
- frag_begin = (char *) qb->mem;
- frag_size = qb->size * sizeof(Eterm);
+ while (qb != NULL) {
+ frag_size = qb->used_size * sizeof(Eterm);
if (frag_size != 0) {
- n_htop = sweep_one_area(n_hstart, n_htop, frag_begin, frag_size);
+ frag_begin = (char *) qb->mem;
+ n_htop = move_one_area(n_htop, frag_begin, frag_size);
}
qb = qb->next;
}
return n_htop;
}
+#ifdef DEBUG
+static Eterm follow_moved(Eterm term)
+{
+ Eterm* ptr;
+ switch (primary_tag(term)) {
+ case TAG_PRIMARY_IMMED1:
+ break;
+ case TAG_PRIMARY_BOXED:
+ ptr = boxed_val(term);
+ if (IS_MOVED(*ptr)) term = *ptr;
+ break;
+ case TAG_PRIMARY_LIST:
+ ptr = list_val(term);
+ if (is_non_value(ptr[0])) term = ptr[1];
+ break;
+ default:
+ abort();
+ }
+ return term;
+}
+#endif
+
static Uint
setup_rootset(Process *p, Eterm *objv, int nobj, Rootset *rootset)
{
@@ -1932,7 +1880,7 @@ setup_rootset(Process *p, Eterm *objv, int nobj, Rootset *rootset)
}
ASSERT((is_nil(p->seq_trace_token) ||
- is_tuple(p->seq_trace_token) ||
+ is_tuple(follow_moved(p->seq_trace_token)) ||
is_atom(p->seq_trace_token)));
if (is_not_immed(p->seq_trace_token)) {
roots[n].v = &p->seq_trace_token;
@@ -1944,7 +1892,7 @@ setup_rootset(Process *p, Eterm *objv, int nobj, Rootset *rootset)
is_internal_pid(p->tracer_proc) ||
is_internal_port(p->tracer_proc));
- ASSERT(is_pid(p->group_leader));
+ ASSERT(is_pid(follow_moved(p->group_leader)));
if (is_not_immed(p->group_leader)) {
roots[n].v = &p->group_leader;
roots[n].sz = 1;
@@ -2083,23 +2031,45 @@ shrink_new_heap(Process *p, Uint new_sz, Eterm *objv, int nobj)
}
static Uint
-next_vheap_size(Uint vheap, Uint vheap_sz) {
- if (vheap < H_MIN_SIZE) {
- return H_MIN_SIZE;
- }
+do_next_vheap_size(Uint vheap, Uint vheap_sz) {
+
+ /* grow
+ *
+ * vheap_sz ======================
+ *
+ * vheap 75% + grow
+ * ----------------------
+ *
+ * vheap 25 - 75% same
+ * ----------------------
+ *
+ * vheap ~ - 25% shrink
+ *
+ * ----------------------
+ */
+
+ if (vheap > (Uint) (vheap_sz*3/4)) {
+
+ while(vheap > (Uint) (vheap_sz*3/4)) {
+ vheap_sz = vheap_sz*2;
+ }
- /* grow */
- if (vheap > vheap_sz) {
- return erts_next_heap_size(2*vheap, 0);
+ return erts_next_heap_size(vheap_sz, 0);
}
- /* shrink */
- if ( vheap < vheap_sz/2) {
- return (Uint)vheap_sz*3/4;
+
+ if (vheap < (Uint) (vheap_sz/4)) {
+ return erts_next_heap_size((Uint) (vheap_sz / 2), 0);
}
return vheap_sz;
+
}
+static Uint
+next_vheap_size(Process* p, Uint vheap, Uint vheap_sz) {
+ vheap_sz = do_next_vheap_size(vheap, vheap_sz);
+ return vheap_sz < p->min_vheap_size ? p->min_vheap_size : vheap_sz;
+}
static void
sweep_proc_externals(Process *p, int fullsweep)
@@ -2302,8 +2272,8 @@ sweep_proc_bins(Process *p, int fullsweep)
FLAGS(p) |= F_NEED_FULLSWEEP;
}
- BIN_VHEAP_SZ(p) = next_vheap_size(bin_vheap, BIN_VHEAP_SZ(p));
- BIN_OLD_VHEAP_SZ(p) = next_vheap_size(BIN_OLD_VHEAP(p), BIN_OLD_VHEAP_SZ(p));
+ BIN_VHEAP_SZ(p) = next_vheap_size(p, bin_vheap, BIN_VHEAP_SZ(p));
+ BIN_OLD_VHEAP_SZ(p) = next_vheap_size(p, BIN_OLD_VHEAP(p), BIN_OLD_VHEAP_SZ(p));
MSO(p).overhead = bin_vheap;
/*
diff --git a/erts/emulator/beam/erl_init.c b/erts/emulator/beam/erl_init.c
index 8afd349b85..e97ab328cd 100644
--- a/erts/emulator/beam/erl_init.c
+++ b/erts/emulator/beam/erl_init.c
@@ -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%
*/
@@ -84,9 +84,10 @@ int erts_use_sender_punish;
* Configurable parameters.
*/
-Uint display_items; /* no of items to display in traces etc */
+Uint display_items; /* no of items to display in traces etc */
Uint display_loads; /* print info about loaded modules */
int H_MIN_SIZE; /* The minimum heap grain */
+int BIN_VH_MIN_SIZE; /* The minimum binary virtual*/
Uint32 erts_debug_flags; /* Debug flags. */
#ifdef ERTS_OPCODE_COUNTER_SUPPORT
@@ -118,6 +119,8 @@ int erts_disable_tolerant_timeofday; /* Time correction can be disabled it is
* not and/or it is too slow.
*/
+int erts_atom_table_size = ATOM_LIMIT; /* Maximum number of atoms */
+
int erts_modified_timing_level;
int erts_no_crash_dump = 0; /* Use -d to suppress crash dump. */
@@ -252,7 +255,8 @@ erl_init(void)
no_schedulers,
no_schedulers_online);
- H_MIN_SIZE = erts_next_heap_size(H_MIN_SIZE, 0);
+ H_MIN_SIZE = erts_next_heap_size(H_MIN_SIZE, 0);
+ BIN_VH_MIN_SIZE = erts_next_heap_size(BIN_VH_MIN_SIZE, 0);
erts_init_trace();
erts_init_binary();
@@ -292,6 +296,7 @@ erl_init(void)
erl_sys_init_final();
#endif
packet_parser_init();
+ erl_nif_init();
}
static void
@@ -513,67 +518,73 @@ void erts_usage(void)
/* erts_fprintf(stderr, "-# number set the number of items to be used in traces etc\n"); */
- erts_fprintf(stderr, "-a size suggested stack size in kilo words for threads\n");
- erts_fprintf(stderr, " in the async-thread pool, valid range is [%d-%d]\n",
+ erts_fprintf(stderr, "-a size suggested stack size in kilo words for threads\n");
+ erts_fprintf(stderr, " in the async-thread pool, valid range is [%d-%d]\n",
ERTS_ASYNC_THREAD_MIN_STACK_SIZE,
ERTS_ASYNC_THREAD_MAX_STACK_SIZE);
- erts_fprintf(stderr, "-A number set number of threads in async thread pool,\n");
- erts_fprintf(stderr, " valid range is [0-%d]\n",
+ erts_fprintf(stderr, "-A number set number of threads in async thread pool,\n");
+ erts_fprintf(stderr, " valid range is [0-%d]\n",
ERTS_MAX_NO_OF_ASYNC_THREADS);
- erts_fprintf(stderr, "-B[c|d|i] c to have Ctrl-c interrupt the Erlang shell,\n");
- erts_fprintf(stderr, " d (or no extra option) to disable the break\n");
- erts_fprintf(stderr, " handler, i to ignore break signals\n");
+ erts_fprintf(stderr, "-B[c|d|i] c to have Ctrl-c interrupt the Erlang shell,\n");
+ erts_fprintf(stderr, " d (or no extra option) to disable the break\n");
+ erts_fprintf(stderr, " handler, i to ignore break signals\n");
/* erts_fprintf(stderr, "-b func set the boot function (default boot)\n"); */
- erts_fprintf(stderr, "-c disable continuous date/time correction with\n");
- erts_fprintf(stderr, " respect to uptime\n");
+ erts_fprintf(stderr, "-c disable continuous date/time correction with\n");
+ erts_fprintf(stderr, " respect to uptime\n");
- erts_fprintf(stderr, "-d don't write a crash dump for internally detected errors\n");
- erts_fprintf(stderr, " (halt(String) will still produce a crash dump)\n");
+ erts_fprintf(stderr, "-d don't write a crash dump for internally detected errors\n");
+ erts_fprintf(stderr, " (halt(String) will still produce a crash dump)\n");
- erts_fprintf(stderr, "-h number set minimum heap size in words (default %d)\n",
+ erts_fprintf(stderr, "-hms size set minimum heap size in words (default %d)\n",
H_DEFAULT_SIZE);
+ erts_fprintf(stderr, "-hmbs size set minimum binary virtual heap size in words (default %d)\n",
+ VH_DEFAULT_SIZE);
/* erts_fprintf(stderr, "-i module set the boot module (default init)\n"); */
- erts_fprintf(stderr, "-K boolean enable or disable kernel poll\n");
+ erts_fprintf(stderr, "-K boolean enable or disable kernel poll\n");
- erts_fprintf(stderr, "-l turn on auto load tracing\n");
+ erts_fprintf(stderr, "-l turn on auto load tracing\n");
- erts_fprintf(stderr, "-M<X> <Y> memory allocator switches,\n");
- erts_fprintf(stderr, " see the erts_alloc(3) documentation for more info.\n");
+ erts_fprintf(stderr, "-M<X> <Y> memory allocator switches,\n");
+ erts_fprintf(stderr, " see the erts_alloc(3) documentation for more info.\n");
- erts_fprintf(stderr, "-P number set maximum number of processes on this node,\n");
- erts_fprintf(stderr, " valid range is [%d-%d]\n",
+ erts_fprintf(stderr, "-P number set maximum number of processes on this node,\n");
+ erts_fprintf(stderr, " valid range is [%d-%d]\n",
ERTS_MIN_PROCESSES, ERTS_MAX_PROCESSES);
- erts_fprintf(stderr, "-R number set compatibility release number,\n");
- erts_fprintf(stderr, " valid range [%d-%d]\n",
+ erts_fprintf(stderr, "-R number set compatibility release number,\n");
+ erts_fprintf(stderr, " valid range [%d-%d]\n",
ERTS_MIN_COMPAT_REL, this_rel_num());
- erts_fprintf(stderr, "-r force ets memory block to be moved on realloc\n");
- erts_fprintf(stderr, "-sbt type set scheduler bind type, valid types are:\n");
- erts_fprintf(stderr, " u|ns|ts|ps|s|nnts|nnps|tnnps|db\n");
- erts_fprintf(stderr, "-sct cput set cpu topology,\n");
- erts_fprintf(stderr, " see the erl(1) documentation for more info.\n");
- erts_fprintf(stderr, "-sss size suggested stack size in kilo words for scheduler threads,\n");
- erts_fprintf(stderr, " valid range is [%d-%d]\n",
+ erts_fprintf(stderr, "-r force ets memory block to be moved on realloc\n");
+ erts_fprintf(stderr, "-sbt type set scheduler bind type, valid types are:\n");
+ erts_fprintf(stderr, " u|ns|ts|ps|s|nnts|nnps|tnnps|db\n");
+ erts_fprintf(stderr, "-sct cput set cpu topology,\n");
+ erts_fprintf(stderr, " see the erl(1) documentation for more info.\n");
+ erts_fprintf(stderr, "-sss size suggested stack size in kilo words for scheduler threads,\n");
+ erts_fprintf(stderr, " valid range is [%d-%d]\n",
ERTS_SCHED_THREAD_MIN_STACK_SIZE,
ERTS_SCHED_THREAD_MAX_STACK_SIZE);
- erts_fprintf(stderr, "-S n1:n2 set number of schedulers (n1), and number of\n");
- erts_fprintf(stderr, " schedulers online (n2), valid range for both\n");
- erts_fprintf(stderr, " numbers are [1-%d]\n",
+ erts_fprintf(stderr, "-S n1:n2 set number of schedulers (n1), and number of\n");
+ erts_fprintf(stderr, " schedulers online (n2), valid range for both\n");
+ erts_fprintf(stderr, " numbers are [1-%d]\n",
ERTS_MAX_NO_OF_SCHEDULERS);
- erts_fprintf(stderr, "-T number set modified timing level,\n");
- erts_fprintf(stderr, " valid range is [0-%d]\n",
+ erts_fprintf(stderr, "-t size set the maximum number of atoms the "
+ "emulator can handle\n");
+ erts_fprintf(stderr, " valid range is [%d-%d]\n",
+ MIN_ATOM_TABLE_SIZE, MAX_ATOM_TABLE_SIZE);
+ erts_fprintf(stderr, "-T number set modified timing level,\n");
+ erts_fprintf(stderr, " valid range is [0-%d]\n",
ERTS_MODIFIED_TIMING_LEVELS-1);
- erts_fprintf(stderr, "-V print Erlang version\n");
+ erts_fprintf(stderr, "-V print Erlang version\n");
- erts_fprintf(stderr, "-v turn on chatty mode (GCs will be reported etc)\n");
+ erts_fprintf(stderr, "-v turn on chatty mode (GCs will be reported etc)\n");
- erts_fprintf(stderr, "-W<i|w> set error logger warnings mapping,\n");
- erts_fprintf(stderr, " see error_logger documentation for details\n");
+ erts_fprintf(stderr, "-W<i|w> set error logger warnings mapping,\n");
+ erts_fprintf(stderr, " see error_logger documentation for details\n");
erts_fprintf(stderr, "\n");
erts_fprintf(stderr, "Note that if the emulator is started with erlexec (typically\n");
@@ -604,6 +615,7 @@ early_init(int *argc, char **argv) /*
erts_async_max_threads = 0;
erts_async_thread_suggested_stack_size = ERTS_ASYNC_THREAD_MIN_STACK_SIZE;
H_MIN_SIZE = H_DEFAULT_SIZE;
+ BIN_VH_MIN_SIZE = VH_DEFAULT_SIZE;
erts_initialized = 0;
@@ -922,17 +934,40 @@ erl_start(int argc, char **argv)
fprintf(stderr, "The undocumented +H option has been removed (R10B-6).\n\n");
break;
- case 'h':
- /* set default heap size */
- arg = get_arg(argv[i]+2, argv[i+1], &i);
- if ((H_MIN_SIZE = atoi(arg)) <= 0) {
- erts_fprintf(stderr, "bad heap size %s\n", arg);
- erts_usage();
+ case 'h': {
+ char *sub_param = argv[i]+2;
+ /* set default heap size
+ *
+ * h|ms - min_heap_size
+ * h|mbs - min_bin_vheap_size
+ *
+ */
+ if (has_prefix("mbs", sub_param)) {
+ arg = get_arg(sub_param+3, argv[i+1], &i);
+ if ((BIN_VH_MIN_SIZE = atoi(arg)) <= 0) {
+ erts_fprintf(stderr, "bad heap size %s\n", arg);
+ erts_usage();
+ }
+ VERBOSE(DEBUG_SYSTEM, ("using minimum binary virtual heap size %d\n", BIN_VH_MIN_SIZE));
+
+ } else if (has_prefix("ms", sub_param)) {
+ arg = get_arg(sub_param+2, argv[i+1], &i);
+ if ((H_MIN_SIZE = atoi(arg)) <= 0) {
+ erts_fprintf(stderr, "bad heap size %s\n", arg);
+ erts_usage();
+ }
+ VERBOSE(DEBUG_SYSTEM, ("using minimum heap size %d\n", H_MIN_SIZE));
+ } else {
+ /* backward compatibility */
+ arg = get_arg(argv[i]+2, argv[i+1], &i);
+ if ((H_MIN_SIZE = atoi(arg)) <= 0) {
+ erts_fprintf(stderr, "bad heap size %s\n", arg);
+ erts_usage();
+ }
+ VERBOSE(DEBUG_SYSTEM, ("using minimum heap size %d\n", H_MIN_SIZE));
}
- VERBOSE(DEBUG_SYSTEM,
- ("using minimum heap size %d\n",H_MIN_SIZE));
break;
-
+ }
case 'd':
/*
* Never produce crash dumps for internally detected
@@ -1112,6 +1147,22 @@ erl_start(int argc, char **argv)
}
break;
}
+ case 't':
+ /* set atom table size */
+ arg = get_arg(argv[i]+2, argv[i+1], &i);
+ errno = 0;
+ erts_atom_table_size = strtol(arg, NULL, 10);
+ if (errno != 0 ||
+ erts_atom_table_size < MIN_ATOM_TABLE_SIZE ||
+ erts_atom_table_size > MAX_ATOM_TABLE_SIZE) {
+ erts_fprintf(stderr, "bad atom table size %s\n", arg);
+ erts_usage();
+ }
+ VERBOSE(DEBUG_SYSTEM,
+ ("setting maximum number of atoms to %d\n",
+ erts_atom_table_size));
+ break;
+
case 'T' :
arg = get_arg(argv[i]+2, argv[i+1], &i);
errno = 0;
diff --git a/erts/emulator/beam/erl_lock_check.c b/erts/emulator/beam/erl_lock_check.c
index 25f1d420d1..074b08ea57 100644
--- a/erts/emulator/beam/erl_lock_check.c
+++ b/erts/emulator/beam/erl_lock_check.c
@@ -1,19 +1,19 @@
/*
* %CopyrightBegin%
- *
- * Copyright Ericsson AB 2005-2009. All Rights Reserved.
- *
+ *
+ * Copyright Ericsson AB 2005-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%
*/
@@ -84,6 +84,9 @@ static erts_lc_lock_order_t erts_lock_order[] = {
{ "reg_tab", NULL },
{ "migration_info_update", NULL },
{ "proc_main", "pid" },
+#ifdef HIPE
+ { "hipe_mfait_lock", NULL },
+#endif
{ "nodes_monitors", NULL },
{ "driver_list", NULL },
{ "proc_link", "pid" },
diff --git a/erts/emulator/beam/erl_lock_count.c b/erts/emulator/beam/erl_lock_count.c
index 6211983f4b..0d7e1335c1 100644
--- a/erts/emulator/beam/erl_lock_count.c
+++ b/erts/emulator/beam/erl_lock_count.c
@@ -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%
*/
@@ -162,7 +162,6 @@ static void print_lock_x(erts_lcnt_lock_t *lock, Uint16 flag, char *action, char
long int colls, tries, w_state, r_state;
erts_lcnt_lock_stats_t *stats = NULL;
- float rate;
char *type;
int i;
@@ -170,8 +169,6 @@ static void print_lock_x(erts_lcnt_lock_t *lock, Uint16 flag, char *action, char
ethr_atomic_read(&lock->r_state, &r_state);
ethr_atomic_read(&lock->w_state, &w_state);
- if (tries > 0) rate = (float)(colls/(float)tries)*100;
- else rate = 0.0f;
if (lock->flag & flag) {
erts_printf("%20s [%30s] [r/w state %4ld/%4ld] id %T %s\r\n",
@@ -181,26 +178,13 @@ static void print_lock_x(erts_lcnt_lock_t *lock, Uint16 flag, char *action, char
w_state,
lock->id,
extra);
-
- for(i = 0; i < lock->n_stats; i++) {
- stats = &(lock->stats[i]);
- ethr_atomic_read(&stats->tries, &tries);
- ethr_atomic_read(&stats->colls, &colls);
- fprintf(stderr, "%69s:%5d [tries %9ld] [colls %9ld] [timer_n %8ld] [timer %4ld s %6ld us]\r\n",
- stats->file,
- stats->line,
- tries,
- colls,
- stats->timer_n,
- stats->timer.s,
- (unsigned long)stats->timer.ns/1000);
- }
- fprintf(stderr, "\r\n");
}
}
static void print_lock(erts_lcnt_lock_t *lock, char *action) {
- print_lock_x(lock, ERTS_LCNT_LT_ALL, action, "");
+ if (strcmp(lock->name, "proc_main") == 0) {
+ print_lock_x(lock, ERTS_LCNT_LT_ALL, action, "");
+ }
}
#endif
@@ -230,8 +214,8 @@ static void lcnt_update_stats(erts_lcnt_lock_stats_t *stats, int lock_in_conflic
ethr_atomic_inc(&stats->tries);
- /* beware of trylock */
- if (lock_in_conflict) ethr_atomic_inc(&stats->colls);
+ if (lock_in_conflict)
+ ethr_atomic_inc(&stats->colls);
if (time_wait) {
lcnt_time_add(&(stats->timer), time_wait);
@@ -366,6 +350,7 @@ void erts_lcnt_init_lock_x(erts_lcnt_lock_t *lock, char *name, Uint16 flag, Eter
for (i = 0; i < ERTS_LCNT_MAX_LOCK_LOCATIONS; i++) {
lcnt_clear_stats(&lock->stats[i]);
}
+
erts_lcnt_list_insert(erts_lcnt_data->current_locks, lock);
lcnt_unlock();
@@ -373,18 +358,20 @@ void erts_lcnt_init_lock_x(erts_lcnt_lock_t *lock, char *name, Uint16 flag, Eter
void erts_lcnt_destroy_lock(erts_lcnt_lock_t *lock) {
erts_lcnt_lock_t *deleted_lock;
-
- /* copy structure and insert the copy */
- deleted_lock = (erts_lcnt_lock_t*)malloc(sizeof(erts_lcnt_lock_t));
lcnt_lock();
- memcpy(deleted_lock, lock, sizeof(erts_lcnt_lock_t));
- deleted_lock->next = NULL;
- deleted_lock->prev = NULL;
+ if (erts_lcnt_rt_options & ERTS_LCNT_OPT_COPYSAVE) {
+ /* copy structure and insert the copy */
- erts_lcnt_list_insert(erts_lcnt_data->deleted_locks, deleted_lock);
+ deleted_lock = (erts_lcnt_lock_t*)malloc(sizeof(erts_lcnt_lock_t));
+ memcpy(deleted_lock, lock, sizeof(erts_lcnt_lock_t));
+ deleted_lock->next = NULL;
+ deleted_lock->prev = NULL;
+
+ erts_lcnt_list_insert(erts_lcnt_data->deleted_locks, deleted_lock);
+ }
/* delete original */
erts_lcnt_list_delete(erts_lcnt_data->current_locks, lock);
@@ -416,9 +403,10 @@ void erts_lcnt_lock_opt(erts_lcnt_lock_t *lock, Uint16 option) {
/* we cannot acquire w_lock if either w or r are taken */
/* we cannot acquire r_lock if w_lock is taken */
- if ((w_state > 0) || (r_state > 0)){
+ if ((w_state > 0) || (r_state > 0)) {
eltd->lock_in_conflict = 1;
- if (eltd->timer_set == 0) lcnt_time(&eltd->timer);
+ if (eltd->timer_set == 0)
+ lcnt_time(&eltd->timer);
eltd->timer_set++;
} else {
eltd->lock_in_conflict = 0;
@@ -445,7 +433,8 @@ void erts_lcnt_lock(erts_lcnt_lock_t *lock) {
* 'atomicly'. All other locks will block the thread if w_state > 0
* i.e. locked.
*/
- if (eltd->timer_set == 0) lcnt_time(&eltd->timer);
+ if (eltd->timer_set == 0)
+ lcnt_time(&eltd->timer);
eltd->timer_set++;
} else {
@@ -494,24 +483,23 @@ void erts_lcnt_lock_post_x(erts_lcnt_lock_t *lock, char *file, unsigned int line
eltd = lcnt_get_thread_data();
ASSERT(eltd);
-
+
/* if lock was in conflict, time it */
stats = lcnt_get_lock_stats(lock, file, line);
if (eltd->timer_set) {
lcnt_time(&timer);
-
- eltd->timer_set--;
lcnt_time_diff(&time_wait, &timer, &(eltd->timer));
lcnt_update_stats(stats, eltd->lock_in_conflict, &time_wait);
+ eltd->timer_set--;
ASSERT(eltd->timer_set >= 0);
} else {
lcnt_update_stats(stats, eltd->lock_in_conflict, NULL);
}
-
+
}
/* unlock */
diff --git a/erts/emulator/beam/erl_lock_count.h b/erts/emulator/beam/erl_lock_count.h
index 8564c36203..e3044c371f 100644
--- a/erts/emulator/beam/erl_lock_count.h
+++ b/erts/emulator/beam/erl_lock_count.h
@@ -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%
*/
@@ -39,6 +39,20 @@
* Each instance of a lock is the unique lock, i.e. set and id in that set.
* For each lock there is a set of statistics with where and what impact
* the lock aqusition had.
+ *
+ * Runtime options
+ * - suspend, used when internal lock-counting can't be applied. For instance
+ * when allocating a term for the outside and halloc needs to be used.
+ * Default: off.
+ * - location, reserved and not used.
+ * - proclock, disable proclock counting. Used when performance might be an
+ * issue. Accessible from erts_debug:lock_counters({process_locks, bool()}).
+ * Default: off.
+ * - copysave, enable saving of destroyed locks (and thereby its statistics).
+ * If memory constraints is an issue this need to be disabled.
+ * Accessible from erts_debug:lock_counters({copy_save, bool()}).
+ * Default: off.
+ *
*/
#include "sys.h"
@@ -74,6 +88,7 @@
#define ERTS_LCNT_OPT_SUSPEND (((Uint16) 1) << 0)
#define ERTS_LCNT_OPT_LOCATION (((Uint16) 1) << 1)
#define ERTS_LCNT_OPT_PROCLOCK (((Uint16) 1) << 2)
+#define ERTS_LCNT_OPT_COPYSAVE (((Uint16) 1) << 3)
typedef struct {
unsigned long s;
diff --git a/erts/emulator/beam/erl_message.c b/erts/emulator/beam/erl_message.c
index 81fbdfbd5a..a056fce0c5 100644
--- a/erts/emulator/beam/erl_message.c
+++ b/erts/emulator/beam/erl_message.c
@@ -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%
*/
/*
@@ -114,12 +114,8 @@ erts_resize_message_buffer(ErlHeapFragment *bp, Uint size,
nbp = (ErlHeapFragment*) ERTS_HEAP_REALLOC(ERTS_ALC_T_HEAP_FRAG,
(void *) bp,
- (sizeof(ErlHeapFragment)
- - sizeof(Eterm)
- + bp->size*sizeof(Eterm)),
- (sizeof(ErlHeapFragment)
- - sizeof(Eterm)
- + size*sizeof(Eterm)));
+ ERTS_HEAP_FRAG_SIZE(bp->size),
+ ERTS_HEAP_FRAG_SIZE(size));
if (bp != nbp) {
Uint off_sz = size < nbp->size ? size : nbp->size;
Eterm *sp = &bp->mem[0];
@@ -140,7 +136,7 @@ erts_resize_message_buffer(ErlHeapFragment *bp, Uint size,
#endif
}
nbp->size = size;
-
+ nbp->used_size = size;
#ifdef HARD_DEBUG
for (i = 0; i < brefs_size; i++)
@@ -175,9 +171,7 @@ free_message_buffer(ErlHeapFragment* bp)
erts_cleanup_offheap(&bp->off_heap);
ERTS_HEAP_FREE(ERTS_ALC_T_HEAP_FRAG,
(void *) bp,
- (sizeof(ErlHeapFragment)
- - sizeof(Eterm)
- + bp->size*sizeof(Eterm)));
+ ERTS_HEAP_FRAG_SIZE(bp->size));
}
static ERTS_INLINE void
diff --git a/erts/emulator/beam/erl_message.h b/erts/emulator/beam/erl_message.h
index f14f14a586..5cf7c209bd 100644
--- a/erts/emulator/beam/erl_message.h
+++ b/erts/emulator/beam/erl_message.h
@@ -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%
*/
@@ -50,19 +50,10 @@ struct erl_heap_fragment {
ErlHeapFragment* next; /* Next heap fragment */
ErlOffHeap off_heap; /* Offset heap data. */
unsigned size; /* Size in words of mem */
+ unsigned used_size; /* With terms to be moved to heap by GC */
Eterm mem[1]; /* Data */
};
-#define ERTS_SET_MBUF_HEAP_END(BP, HENDP) \
-do { \
- unsigned real_size__ = (BP)->size; \
- ASSERT((BP)->mem <= (HENDP) && (HENDP) <= (BP)->mem + real_size__); \
- (BP)->size = (HENDP) - (BP)->mem; \
- /* We do not reallocate since buffer *might* be moved. */ \
- /* FIXME: Memory count is wrong, but at least it's almost */ \
- /* right... */ \
-} while (0)
-
typedef struct erl_mesg {
struct erl_mesg* next; /* Next message */
union {
@@ -196,10 +187,12 @@ do { \
#define ERTS_HEAP_FRAG_SIZE(DATA_WORDS) \
(sizeof(ErlHeapFragment) - sizeof(Eterm) + (DATA_WORDS)*sizeof(Eterm))
+
#define ERTS_INIT_HEAP_FRAG(HEAP_FRAG_P, DATA_WORDS) \
do { \
(HEAP_FRAG_P)->next = NULL; \
(HEAP_FRAG_P)->size = (DATA_WORDS); \
+ (HEAP_FRAG_P)->used_size = (DATA_WORDS); \
(HEAP_FRAG_P)->off_heap.mso = NULL; \
(HEAP_FRAG_P)->off_heap.funs = NULL; \
(HEAP_FRAG_P)->off_heap.externals = NULL; \
diff --git a/erts/emulator/beam/erl_nif.c b/erts/emulator/beam/erl_nif.c
index fa4454a3f3..585a6c1fdf 100644
--- a/erts/emulator/beam/erl_nif.c
+++ b/erts/emulator/beam/erl_nif.c
@@ -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%
*/
/* Erlang Native InterFace
@@ -34,16 +34,26 @@
#include "beam_bp.h"
#include <limits.h>
+#include <stddef.h> /* offsetof */
+
+
+/* Information about a loaded nif library.
+ * Each successful call to erlang:load_nif will allocate an instance of
+ * erl_module_nif. Two calls opening the same library will thus have the same
+ * 'handle'.
+ */
+struct erl_module_nif {
+ void* priv_data;
+ void* handle; /* "dlopen" */
+ struct enif_entry_t* entry;
+ erts_refc_t rt_cnt; /* number of resource types */
+ erts_refc_t rt_dtor_cnt; /* number of resource types with destructors */
+ int is_orphan; /* if erlang module has been purged */
+};
-/*
-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);
+static Eterm* alloc_heap_heavy(ErlNifEnv* env, unsigned need, Eterm* hp);
static ERTS_INLINE Eterm* alloc_heap(ErlNifEnv* env, unsigned need)
{
@@ -52,43 +62,63 @@ static ERTS_INLINE Eterm* alloc_heap(ErlNifEnv* env, unsigned need)
if (env->hp <= env->hp_end) {
return hp;
}
- env->hp = hp;
- return alloc_heap_heavy(env,need);
+ return alloc_heap_heavy(env, need, hp);
}
-static Eterm* alloc_heap_heavy(ErlNifEnv* env, unsigned need)
-{
- Eterm* hp;
-
- if (env->heap_frag_sz == 0) {
+static Eterm* alloc_heap_heavy(ErlNifEnv* env, unsigned need, Eterm* hp)
+{
+ unsigned frag_sz;
+ env->hp = hp;
+ if (env->heap_frag == NULL) {
ASSERT(HEAP_LIMIT(env->proc) == env->hp_end);
HEAP_TOP(env->proc) = env->hp;
- env->heap_frag_sz = need + MIN_HEAP_FRAG_SZ;
}
else {
HRelease(env->proc, env->hp_end, env->hp);
- env->heap_frag_sz *= 2;
}
- hp = erts_heap_alloc(env->proc, env->heap_frag_sz);
+ frag_sz = need + MIN_HEAP_FRAG_SZ;
+ hp = erts_heap_alloc(env->proc, frag_sz);
env->hp = hp + need;
- env->hp_end = hp + env->heap_frag_sz;
+ env->hp_end = hp + frag_sz;
+ env->heap_frag = MBUF(env->proc);
return hp;
}
-void erts_pre_nif(ErlNifEnv* env, Process* p, void* nif_data)
+void erts_pre_nif(ErlNifEnv* env, Process* p, struct erl_module_nif* mod_nif)
{
- env->nif_data = nif_data;
+ env->mod_nif = mod_nif;
env->proc = p;
env->hp = HEAP_TOP(p);
env->hp_end = HEAP_LIMIT(p);
- env->heap_frag_sz = 0;
+ env->heap_frag = NULL;
+ env->fpe_was_unmasked = erts_block_fpe();
+ env->tmp_obj_list = NULL;
+}
+
+static void pre_nif_noproc(ErlNifEnv* env, struct erl_module_nif* mod_nif)
+{
+ env->mod_nif = mod_nif;
+ env->proc = NULL;
+ env->hp = NULL;
+ env->hp_end = NULL;
+ env->heap_frag = NULL;
env->fpe_was_unmasked = erts_block_fpe();
+ env->tmp_obj_list = NULL;
+}
+
+static ERTS_INLINE void free_tmp_objs(ErlNifEnv* env)
+{
+ while (env->tmp_obj_list != NULL) {
+ struct enif_tmp_obj_t* free_me = env->tmp_obj_list;
+ env->tmp_obj_list = free_me->next;
+ free_me->dtor(free_me);
+ }
}
void erts_post_nif(ErlNifEnv* env)
{
erts_unblock_fpe(env->fpe_was_unmasked);
- if (env->heap_frag_sz == 0) {
+ if (env->heap_frag == NULL) {
ASSERT(env->hp_end == HEAP_LIMIT(env->proc));
ASSERT(env->hp >= HEAP_TOP(env->proc));
ASSERT(env->hp <= HEAP_LIMIT(env->proc));
@@ -96,14 +126,60 @@ void erts_post_nif(ErlNifEnv* env)
}
else {
ASSERT(env->hp_end != HEAP_LIMIT(env->proc));
- ASSERT(env->hp_end - env->hp <= env->heap_frag_sz);
+ ASSERT(env->hp_end - env->hp <= env->heap_frag->size);
HRelease(env->proc, env->hp_end, env->hp);
}
+ free_tmp_objs(env);
+}
+
+static void post_nif_noproc(ErlNifEnv* env)
+{
+ erts_unblock_fpe(env->fpe_was_unmasked);
+ free_tmp_objs(env);
}
-void* enif_get_data(ErlNifEnv* env)
+
+/* Flush out our cached heap pointers to allow an ordinary HAlloc
+*/
+static void enable_halloc(ErlNifEnv* env)
{
- return env->nif_data;
+ if (env->heap_frag == NULL) {
+ ASSERT(env->hp_end == HEAP_LIMIT(env->proc));
+ ASSERT(env->hp >= HEAP_TOP(env->proc));
+ ASSERT(env->hp <= HEAP_LIMIT(env->proc));
+ HEAP_TOP(env->proc) = env->hp;
+ }
+ else {
+ ASSERT(env->hp_end != HEAP_LIMIT(env->proc));
+ ASSERT(env->hp_end - env->hp <= env->heap_frag->size);
+ HRelease(env->proc, env->hp_end, env->hp);
+ }
+}
+
+/* Restore cached heap pointers
+*/
+static void disable_halloc(ErlNifEnv* env)
+{
+ if (env->heap_frag == NULL) {
+ ASSERT(env->hp_end == HEAP_LIMIT(env->proc));
+ ASSERT(env->hp <= HEAP_TOP(env->proc));
+ ASSERT(env->hp <= HEAP_LIMIT(env->proc));
+ env->hp = HEAP_TOP(env->proc);
+ }
+ else {
+ ASSERT(env->hp_end != HEAP_LIMIT(env->proc));
+ ASSERT(env->hp_end - env->hp <= env->heap_frag->size);
+ env->heap_frag = MBUF(env->proc);
+ ASSERT(env->heap_frag != NULL);
+ env->hp = env->heap_frag->mem + env->heap_frag->used_size;
+ env->hp_end = env->heap_frag->mem + env->heap_frag->size;
+ }
+}
+
+
+void* enif_priv_data(ErlNifEnv* env)
+{
+ return env->mod_nif->priv_data;
}
void* enif_alloc(ErlNifEnv* env, size_t size)
@@ -111,31 +187,114 @@ void* enif_alloc(ErlNifEnv* env, size_t size)
return erts_alloc_fnf(ERTS_ALC_T_NIF, (Uint) size);
}
+void* enif_realloc(ErlNifEnv* env, void* ptr, size_t size)
+{
+ return erts_realloc_fnf(ERTS_ALC_T_NIF, ptr, size);
+}
+
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_empty_list(ErlNifEnv* env, ERL_NIF_TERM term)
+{
+ return is_nil(term);
+}
+
+int enif_is_fun(ErlNifEnv* env, ERL_NIF_TERM term)
+{
+ return is_fun(term);
+}
+
+int enif_is_pid(ErlNifEnv* env, ERL_NIF_TERM term)
+{
+ return is_pid(term);
+}
+
+int enif_is_port(ErlNifEnv* env, ERL_NIF_TERM term)
+{
+ return is_port(term);
+}
+
+int enif_is_ref(ErlNifEnv* env, ERL_NIF_TERM term)
+{
+ return is_ref(term);
+}
+
+static void aligned_binary_dtor(struct enif_tmp_obj_t* obj)
+{
+ erts_free_aligned_binary_bytes((byte*)obj);
+}
int enif_inspect_binary(ErlNifEnv* env, Eterm bin_term, ErlNifBinary* bin)
{
- bin->tmp_alloc = NULL;
- bin->data = erts_get_aligned_binary_bytes(bin_term, &bin->tmp_alloc);
+ union {
+ struct enif_tmp_obj_t* tmp;
+ byte* raw_ptr;
+ }u;
+ u.tmp = NULL;
+ bin->data = erts_get_aligned_binary_bytes_extra(bin_term, &u.raw_ptr,
+ sizeof(struct enif_tmp_obj_t));
if (bin->data == NULL) {
return 0;
}
+ if (u.tmp != NULL) {
+ u.tmp->next = env->tmp_obj_list;
+ u.tmp->dtor = &aligned_binary_dtor;
+ env->tmp_obj_list = u.tmp;
+ }
bin->bin_term = bin_term;
bin->size = binary_size(bin_term);
bin->ref_bin = NULL;
return 1;
}
+static void tmp_alloc_dtor(struct enif_tmp_obj_t* obj)
+{
+ erts_free(ERTS_ALC_T_TMP, obj);
+}
+
+int enif_inspect_iolist_as_binary(ErlNifEnv* env, Eterm term, ErlNifBinary* bin)
+{
+ struct enif_tmp_obj_t* tobj;
+ int sz;
+ if (is_binary(term)) {
+ return enif_inspect_binary(env,term,bin);
+ }
+ if (is_nil(term)) {
+ bin->data = (unsigned char*) &bin->data; /* dummy non-NULL */
+ bin->size = 0;
+ bin->bin_term = THE_NON_VALUE;
+ bin->ref_bin = NULL;
+ return 1;
+ }
+ if ((sz = io_list_len(term)) < 0) {
+ return 0;
+ }
+
+ tobj = erts_alloc(ERTS_ALC_T_TMP, sz + sizeof(struct enif_tmp_obj_t));
+ tobj->next = env->tmp_obj_list;
+ tobj->dtor = &tmp_alloc_dtor;
+ env->tmp_obj_list = tobj;
+
+ bin->data = (unsigned char*) &tobj[1];
+ bin->size = sz;
+ bin->bin_term = THE_NON_VALUE;
+ bin->ref_bin = NULL;
+ io_list_to_buf(term, (char*) bin->data, sz);
+ return 1;
+}
int enif_alloc_binary(ErlNifEnv* env, unsigned size, ErlNifBinary* bin)
{
@@ -152,41 +311,115 @@ int enif_alloc_binary(ErlNifEnv* env, unsigned size, ErlNifBinary* bin)
bin->size = size;
bin->data = (unsigned char*) refbin->orig_bytes;
bin->bin_term = THE_NON_VALUE;
- bin->tmp_alloc = NULL;
bin->ref_bin = refbin;
return 1;
}
-void enif_release_binary(ErlNifEnv* env, ErlNifBinary* bin)
+int enif_realloc_binary(ErlNifEnv* env, ErlNifBinary* bin, unsigned size)
{
- if (bin->ref_bin == NULL) {
- erts_free_aligned_binary_bytes(bin->tmp_alloc);
+ if (bin->ref_bin != NULL) {
+ Binary* oldbin;
+ Binary* newbin;
+
+ 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;
}
else {
+ unsigned char* old_data = bin->data;
+ unsigned cpy_sz = (size < bin->size ? size : bin->size);
+ enif_alloc_binary(env, size, bin);
+ sys_memcpy(bin->data, old_data, cpy_sz);
+ }
+ return 1;
+}
+
+
+void enif_release_binary(ErlNifEnv* env, ErlNifBinary* bin)
+{
+ if (bin->ref_bin != NULL) {
Binary* refbin = bin->ref_bin;
- ASSERT(bin->tmp_alloc == NULL);
ASSERT(bin->bin_term == THE_NON_VALUE);
if (erts_refc_dectest(&refbin->refc, 0) == 0) {
erts_bin_free(refbin);
}
}
#ifdef DEBUG
+ bin->data = NULL;
bin->bin_term = THE_NON_VALUE;
- bin->tmp_alloc = NULL;
bin->ref_bin = NULL;
#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, const Eterm** array)
+{
+ Eterm* ptr;
+ if (is_not_tuple(tpl)) {
+ return 0;
+ }
+ ptr = tuple_val(tpl);
+ *arity = arityval(*ptr);
+ *array = ptr+1;
+ return 1;
+}
+
+int enif_get_string(ErlNifEnv *env, ERL_NIF_TERM list, char* buf, unsigned len,
+ ErlNifCharEncoding encoding)
+{
+ Eterm* listptr;
+ int n = 0;
+
+ ASSERT(encoding == ERL_NIF_LATIN1);
+ if (len < 1) {
+ return 0;
+ }
+ while (is_not_nil(list)) {
+ if (is_not_list(list)) {
+ buf[n] = '\0';
+ return 0;
+ }
+ listptr = list_val(list);
+
+ if (!is_byte(*listptr)) {
+ buf[n] = '\0';
+ return 0;
+ }
+ buf[n++] = unsigned_val(*listptr);
+ if (n >= len) {
+ buf[n-1] = '\0'; /* truncate */
+ return -len;
+ }
+ list = CDR(listptr);
+ }
+ buf[n] = '\0';
+ return n + 1;
+}
+
Eterm enif_make_binary(ErlNifEnv* env, ErlNifBinary* bin)
{
- if (bin->ref_bin == NULL) {
- erts_free_aligned_binary_bytes(bin->tmp_alloc);
+ if (bin->bin_term != THE_NON_VALUE) {
return bin->bin_term;
}
- else {
+ else if (bin->ref_bin != NULL) {
Binary* bptr = bin->ref_bin;
ProcBin* pb;
- ASSERT(bin->tmp_alloc == NULL);
+ Eterm bin_term;
/* !! Copy-paste from new_binary() !! */
pb = (ProcBin *) alloc_heap(env, PROC_BIN_SIZE);
@@ -199,20 +432,72 @@ Eterm enif_make_binary(ErlNifEnv* env, ErlNifBinary* bin)
pb->flags = 0;
MSO(env->proc).overhead += pb->size / sizeof(Eterm);
- return make_binary(pb);
+ bin_term = make_binary(pb);
+ if (erts_refc_read(&bptr->refc, 1) == 1) {
+ /* Total ownership transfer */
+ bin->ref_bin = NULL;
+ bin->bin_term = bin_term;
+ }
+ return bin_term;
+ }
+ else {
+ enable_halloc(env);
+ bin->bin_term = new_binary(env->proc, bin->data, bin->size);
+ disable_halloc(env);
+ return bin->bin_term;
}
}
-ERL_NIF_TERM enif_make_badarg(ErlNifEnv* env)
+Eterm enif_make_sub_binary(ErlNifEnv* env, ERL_NIF_TERM bin_term,
+ unsigned pos, unsigned size)
+{
+ ErlSubBin* sb;
+ Eterm orig;
+ Uint offset, bit_offset, bit_size;
+ unsigned src_size;
+
+ ASSERT(is_binary(bin_term));
+ src_size = binary_size(bin_term);
+ ASSERT(pos <= src_size);
+ ASSERT(size <= src_size);
+ ASSERT(pos + size <= src_size);
+ sb = (ErlSubBin*) alloc_heap(env, ERL_SUB_BIN_SIZE);
+ ERTS_GET_REAL_BIN(bin_term, orig, offset, bit_offset, bit_size);
+ sb->thing_word = HEADER_SUB_BIN;
+ sb->size = size;
+ sb->offs = offset + pos;
+ sb->orig = orig;
+ sb->bitoffs = bit_offset;
+ sb->bitsize = 0;
+ sb->is_writable = 0;
+ return make_binary(sb);
+}
+
+
+Eterm enif_make_badarg(ErlNifEnv* env)
{
BIF_ERROR(env->proc, BADARG);
}
+int enif_get_atom(ErlNifEnv* env, Eterm atom, char* buf, unsigned len)
+{
+ Atom* ap;
+ if (is_not_atom(atom)) {
+ return 0;
+ }
+ ap = atom_tab(atom_val(atom));
+ if (ap->len+1 > len) {
+ return 0;
+ }
+ sys_memcpy(buf, ap->name, ap->len);
+ buf[ap->len] = '\0';
+ return ap->len + 1;
+}
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) {
@@ -225,6 +510,29 @@ int enif_get_int(ErlNifEnv* env, Eterm term, int* ip)
#endif
}
+int enif_get_uint(ErlNifEnv* env, Eterm term, unsigned* ip)
+{
+#if SIZEOF_INT == SIZEOF_VOID_P
+ return term_to_Uint(term, (Uint*)ip);
+#elif SIZEOF_LONG == SIZEOF_VOID_P
+ Uint i;
+ if (!term_to_Uint(term, &i) || i > UINT_MAX) {
+ return 0;
+ }
+ *ip = (unsigned) i;
+ return 1;
+#endif
+}
+
+int enif_get_long(ErlNifEnv* env, Eterm term, long* ip)
+{
+#if SIZEOF_LONG == SIZEOF_VOID_P
+ return term_to_Sint(term, ip);
+#else
+# error Unknown long word size
+#endif
+}
+
int enif_get_ulong(ErlNifEnv* env, Eterm term, unsigned long* ip)
{
#if SIZEOF_LONG == SIZEOF_VOID_P
@@ -234,6 +542,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;
@@ -253,26 +572,46 @@ ERL_NIF_TERM enif_make_int(ErlNifEnv* env, int i)
#endif
}
-ERL_NIF_TERM enif_make_ulong(ErlNifEnv* env, unsigned long i)
+ERL_NIF_TERM enif_make_uint(ErlNifEnv* env, unsigned i)
{
-#if SIZEOF_LONG == SIZEOF_VOID_P
- Eterm* hp;
- Uint sz = 0;
- erts_bld_uint(NULL, &sz, i);
- hp = alloc_heap(env,sz);
- return erts_bld_uint(&hp, NULL, i);
-#else
+#if SIZEOF_INT == SIZEOF_VOID_P
+ return IS_USMALL(0,i) ? make_small(i) : uint_to_big(i,alloc_heap(env,2));
+#elif SIZEOF_LONG == SIZEOF_VOID_P
+ return make_small(i);
+#endif
+}
+
+ERL_NIF_TERM enif_make_long(ErlNifEnv* env, long i)
+{
+#if SIZEOF_LONG != SIZEOF_VOID_P
# error Unknown long word size
#endif
+ return IS_SSMALL(i) ? make_small(i) : small_to_big(i, alloc_heap(env,2));
+}
+ERL_NIF_TERM enif_make_ulong(ErlNifEnv* env, unsigned long i)
+{
+ return IS_USMALL(0,i) ? make_small(i) : uint_to_big(i,alloc_heap(env,2));
}
+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, ...)
{
@@ -289,6 +628,19 @@ ERL_NIF_TERM enif_make_tuple(ErlNifEnv* env, unsigned cnt, ...)
return ret;
}
+ERL_NIF_TERM enif_make_tuple_from_array(ErlNifEnv* env, const ERL_NIF_TERM arr[], unsigned cnt)
+{
+ Eterm* hp = alloc_heap(env,cnt+1);
+ Eterm ret = make_tuple(hp);
+ const Eterm* src = arr;
+
+ *hp++ = make_arityval(cnt);
+ while (cnt--) {
+ *hp++ = *src++;
+ }
+ return ret;
+}
+
ERL_NIF_TERM enif_make_list_cell(ErlNifEnv* env, Eterm car, Eterm cdr)
{
Eterm* hp = alloc_heap(env,2);
@@ -318,15 +670,297 @@ ERL_NIF_TERM enif_make_list(ErlNifEnv* env, unsigned cnt, ...)
return ret;
}
-ERL_NIF_TERM enif_make_string(ErlNifEnv* env, const char* string)
+ERL_NIF_TERM enif_make_list_from_array(ErlNifEnv* env, const ERL_NIF_TERM arr[], unsigned cnt)
+{
+ Eterm* hp = alloc_heap(env,cnt*2);
+ Eterm ret = make_list(hp);
+ Eterm* last = &ret;
+ const Eterm* src = arr;
+
+ while (cnt--) {
+ *last = make_list(hp);
+ *hp = *src++;
+ last = ++hp;
+ ++hp;
+ }
+ *last = NIL;
+ return ret;
+}
+
+ERL_NIF_TERM enif_make_string(ErlNifEnv* env, const char* string,
+ ErlNifCharEncoding encoding)
{
- Sint n = strlen(string);
+ Sint n = sys_strlen(string);
Eterm* hp = alloc_heap(env,n*2);
+ ASSERT(encoding == ERL_NIF_LATIN1);
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);
+}
+
+void enif_system_info(ErlNifSysInfo *sip, size_t si_size)
+{
+ driver_system_info(sip, si_size);
+}
+
+
+ErlNifMutex* enif_mutex_create(char *name) { return erl_drv_mutex_create(name); }
+void enif_mutex_destroy(ErlNifMutex *mtx) { erl_drv_mutex_destroy(mtx); }
+int enif_mutex_trylock(ErlNifMutex *mtx) { return erl_drv_mutex_trylock(mtx); }
+void enif_mutex_lock(ErlNifMutex *mtx) { erl_drv_mutex_lock(mtx); }
+void enif_mutex_unlock(ErlNifMutex *mtx) { erl_drv_mutex_unlock(mtx); }
+ErlNifCond* enif_cond_create(char *name) { return erl_drv_cond_create(name); }
+void enif_cond_destroy(ErlNifCond *cnd) { erl_drv_cond_destroy(cnd); }
+void enif_cond_signal(ErlNifCond *cnd) { erl_drv_cond_signal(cnd); }
+void enif_cond_broadcast(ErlNifCond *cnd) { erl_drv_cond_broadcast(cnd); }
+void enif_cond_wait(ErlNifCond *cnd, ErlNifMutex *mtx) { erl_drv_cond_wait(cnd,mtx); }
+ErlNifRWLock* enif_rwlock_create(char *name) { return erl_drv_rwlock_create(name); }
+void enif_rwlock_destroy(ErlNifRWLock *rwlck) { erl_drv_rwlock_destroy(rwlck); }
+int enif_rwlock_tryrlock(ErlNifRWLock *rwlck) { return erl_drv_rwlock_tryrlock(rwlck); }
+void enif_rwlock_rlock(ErlNifRWLock *rwlck) { erl_drv_rwlock_rlock(rwlck); }
+void enif_rwlock_runlock(ErlNifRWLock *rwlck) { erl_drv_rwlock_runlock(rwlck); }
+int enif_rwlock_tryrwlock(ErlNifRWLock *rwlck) { return erl_drv_rwlock_tryrwlock(rwlck); }
+void enif_rwlock_rwlock(ErlNifRWLock *rwlck) { erl_drv_rwlock_rwlock(rwlck); }
+void enif_rwlock_rwunlock(ErlNifRWLock *rwlck) { erl_drv_rwlock_rwunlock(rwlck); }
+int enif_tsd_key_create(char *name, ErlNifTSDKey *key) { return erl_drv_tsd_key_create(name,key); }
+void enif_tsd_key_destroy(ErlNifTSDKey key) { erl_drv_tsd_key_destroy(key); }
+void enif_tsd_set(ErlNifTSDKey key, void *data) { erl_drv_tsd_set(key,data); }
+void* enif_tsd_get(ErlNifTSDKey key) { return erl_drv_tsd_get(key); }
+ErlNifThreadOpts* enif_thread_opts_create(char *name) { return (ErlNifThreadOpts*) erl_drv_thread_opts_create(name); }
+void enif_thread_opts_destroy(ErlNifThreadOpts *opts) { erl_drv_thread_opts_destroy((ErlDrvThreadOpts*)opts); }
+int enif_thread_create(char *name, ErlNifTid *tid, void* (*func)(void *),
+ void *args, ErlNifThreadOpts *opts) {
+ return erl_drv_thread_create(name,tid,func,args,(ErlDrvThreadOpts*)opts);
+}
+ErlNifTid enif_thread_self(void) { return erl_drv_thread_self(); }
+int enif_equal_tids(ErlNifTid tid1, ErlNifTid tid2) { return erl_drv_equal_tids(tid1,tid2); }
+void enif_thread_exit(void *resp) { erl_drv_thread_exit(resp); }
+int enif_thread_join(ErlNifTid tid, void **respp) { return erl_drv_thread_join(tid,respp); }
+
+int enif_fprintf(void* filep, const char* format, ...)
+{
+ int ret;
+ va_list arglist;
+ va_start(arglist, format);
+ ret = erts_vfprintf((FILE*)filep, format, arglist);
+ va_end(arglist);
+ return ret;
+}
+
+/***********************************************************
+ ** Memory managed (GC'ed) "resource" objects **
+ ***********************************************************/
+
+
+struct enif_resource_type_t
+{
+ struct enif_resource_type_t* next; /* list of all resource types */
+ struct enif_resource_type_t* prev;
+ struct erl_module_nif* owner; /* that created this type and thus implements the destructor*/
+ ErlNifResourceDtor* dtor; /* user destructor function */
+ erts_refc_t refc; /* num of resources of this type (HOTSPOT warning)
+ +1 for active erl_module_nif */
+ char name[1];
+};
+
+/* dummy node in circular list */
+struct enif_resource_type_t resource_type_list;
+
+typedef struct enif_resource_t
+{
+ struct enif_resource_type_t* type;
+#ifdef DEBUG
+ erts_refc_t nif_refc;
+#endif
+ char data[1];
+}ErlNifResource;
+
+#define SIZEOF_ErlNifResource(SIZE) (offsetof(ErlNifResource,data) + (SIZE))
+#define DATA_TO_RESOURCE(PTR) ((ErlNifResource*)((char*)(PTR) - offsetof(ErlNifResource,data)))
+
+static ErlNifResourceType* find_resource_type(const char* name)
+{
+ ErlNifResourceType* type;
+ for (type = resource_type_list.next;
+ type != &resource_type_list;
+ type = type->next) {
+
+ if (sys_strcmp(type->name, name) == 0) {
+ return type;
+ }
+ }
+ return NULL;
+}
+
+#define in_area(ptr,start,nbytes) \
+ ((unsigned long)((char*)(ptr) - (char*)(start)) < (nbytes))
+
+
+static void close_lib(struct erl_module_nif* lib)
+{
+ ASSERT(lib != NULL);
+ ASSERT(lib->handle != NULL);
+ ASSERT(erts_refc_read(&lib->rt_dtor_cnt,0) == 0);
+
+ if (lib->entry != NULL && lib->entry->unload != NULL) {
+ ErlNifEnv env;
+ pre_nif_noproc(&env, lib);
+ lib->entry->unload(&env, lib->priv_data);
+ post_nif_noproc(&env);
+ }
+ erts_sys_ddll_close(lib->handle);
+ lib->handle = NULL;
+}
+static void steal_resource_type(ErlNifResourceType* type)
+{
+ struct erl_module_nif* lib = type->owner;
+ if (type->dtor != NULL
+ && erts_refc_dectest(&lib->rt_dtor_cnt, 0) == 0
+ && lib->is_orphan) {
+ /* last type with destructor gone, close orphan lib */
+
+ close_lib(lib);
+ }
+ if (erts_refc_dectest(&lib->rt_cnt, 0) == 0
+ && lib->is_orphan) {
+ erts_free(ERTS_ALC_T_NIF, lib);
+ }
+}
+
+ErlNifResourceType*
+enif_open_resource_type(ErlNifEnv* env, const char* type_name,
+ ErlNifResourceDtor* dtor,
+ enum ErlNifResourceFlags flags,
+ enum ErlNifResourceFlags* tried)
+{
+ ErlNifResourceType* type = find_resource_type(type_name);
+ enum ErlNifResourceFlags op = flags;
+ ASSERT(erts_smp_is_system_blocked(0));
+ if (type == NULL) {
+ if (flags & ERL_NIF_RT_CREATE) {
+ type = erts_alloc(ERTS_ALC_T_NIF,
+ sizeof(struct enif_resource_type_t)
+ + sys_strlen(type_name));
+ type->dtor = dtor;
+ sys_strcpy(type->name, type_name);
+ erts_refc_init(&type->refc, 1);
+ type->owner = env->mod_nif;
+ type->prev = &resource_type_list;
+ type->next = resource_type_list.next;
+ type->next->prev = type;
+ type->prev->next = type;
+ op = ERL_NIF_RT_CREATE;
+ }
+ }
+ else {
+ if (flags & ERL_NIF_RT_TAKEOVER) {
+ steal_resource_type(type);
+ op = ERL_NIF_RT_TAKEOVER;
+ }
+ else {
+ type = NULL;
+ }
+ }
+ if (type != NULL) {
+ type->owner = env->mod_nif;
+ type->dtor = dtor;
+ if (type->dtor != NULL) {
+ erts_refc_inc(&type->owner->rt_dtor_cnt, 1);
+ }
+ erts_refc_inc(&type->owner->rt_cnt, 1);
+ }
+ if (tried != NULL) {
+ *tried = op;
+ }
+ return type;
+}
+
+static void nif_resource_dtor(Binary* bin)
+{
+ ErlNifResource* resource = (ErlNifResource*) ERTS_MAGIC_BIN_DATA(bin);
+ ErlNifResourceType* type = resource->type;
+ ASSERT(ERTS_MAGIC_BIN_DESTRUCTOR(bin) == &nif_resource_dtor);
+
+ if (type->dtor != NULL) {
+ ErlNifEnv env;
+ pre_nif_noproc(&env, type->owner);
+ type->dtor(&env,resource->data);
+ post_nif_noproc(&env);
+ }
+ if (erts_refc_dectest(&type->refc, 0) == 0) {
+ ASSERT(type->next == NULL);
+ ASSERT(type->owner != NULL);
+ ASSERT(type->owner->is_orphan);
+ steal_resource_type(type);
+ erts_free(ERTS_ALC_T_NIF, type);
+ }
+}
+
+void* enif_alloc_resource(ErlNifEnv* env, ErlNifResourceType* type, unsigned size)
+{
+ Binary* bin = erts_create_magic_binary(SIZEOF_ErlNifResource(size), &nif_resource_dtor);
+ ErlNifResource* resource = ERTS_MAGIC_BIN_DATA(bin);
+ resource->type = type;
+ erts_refc_inc(&bin->refc, 1);
+#ifdef DEBUG
+ erts_refc_init(&resource->nif_refc, 1);
+#endif
+ erts_refc_inc(&resource->type->refc, 2);
+ return resource->data;
+}
+
+void enif_release_resource(ErlNifEnv* env, void* obj)
+{
+ ErlNifResource* resource = DATA_TO_RESOURCE(obj);
+ ErtsBinary* bin = ERTS_MAGIC_BIN_FROM_DATA(resource);
+
+ ASSERT(ERTS_MAGIC_BIN_DESTRUCTOR(bin) == &nif_resource_dtor);
+#ifdef DEBUG
+ erts_refc_dec(&resource->nif_refc, 0);
+#endif
+ if (erts_refc_dectest(&bin->binary.refc, 0) == 0) {
+ erts_bin_free(&bin->binary);
+ }
+}
+
+ERL_NIF_TERM enif_make_resource(ErlNifEnv* env, void* obj)
+{
+ ErlNifResource* resource = DATA_TO_RESOURCE(obj);
+ ErtsBinary* bin = ERTS_MAGIC_BIN_FROM_DATA(resource);
+ Eterm* hp = alloc_heap(env,PROC_BIN_SIZE);
+ return erts_mk_magic_binary_term(&hp, &MSO(env->proc), &bin->binary);
+}
+
+int enif_get_resource(ErlNifEnv* env, ERL_NIF_TERM term, ErlNifResourceType* type,
+ void** objp)
+{
+ Binary* mbin;
+ ErlNifResource* resource;
+ if (!ERTS_TERM_IS_MAGIC_BINARY(term)) {
+ return 0;
+ }
+ mbin = ((ProcBin*) binary_val(term))->val;
+ resource = (ErlNifResource*) ERTS_MAGIC_BIN_DATA(mbin);
+ if (ERTS_MAGIC_BIN_DESTRUCTOR(mbin) != &nif_resource_dtor
+ || resource->type != type) {
+ return 0;
+ }
+ *objp = resource->data;
+ return 1;
+}
+
+unsigned enif_sizeof_resource(ErlNifEnv* env, void* obj)
+{
+ ErlNifResource* resource = DATA_TO_RESOURCE(obj);
+ Binary* bin = &ERTS_MAGIC_BIN_FROM_DATA(resource)->binary;
+ return ERTS_MAGIC_BIN_DATA_SIZE(bin) - offsetof(ErlNifResource,data);
+}
/***************************************************************************
** load_nif/2 **
@@ -349,10 +983,7 @@ static Uint** get_func_pp(Eterm* mod_code, Eterm f_atom, unsigned arity)
return NULL;
}
-#define in_area(ptr,start,nbytes) \
- ((unsigned long)((char*)(ptr) - (char*)(start)) < (nbytes))
-
-static void refresh_cached_nif_data(Eterm* mod_code,
+/*static void refresh_cached_nif_data(Eterm* mod_code,
struct erl_module_nif* mod_nif)
{
int i;
@@ -361,11 +992,11 @@ 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;
+ code_ptr[5+2] = (Uint) mod_nif->priv_data;
}
-}
+}*/
static Eterm mkatom(const char *str)
{
@@ -411,6 +1042,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 +1071,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;
}
@@ -458,6 +1102,7 @@ BIF_RETTYPE load_nif_2(BIF_ALIST_2)
ErtsSysDdllError errdesc = ERTS_SYS_DDLL_ERROR_INIT;
Eterm ret = am_ok;
int veto;
+ struct erl_module_nif* lib = NULL;
len = intlist_to_buf(BIF_ARG_1, lib_name, sizeof(lib_name)-1);
if (len < 1) {
@@ -489,8 +1134,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 +1167,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);
}
@@ -542,16 +1188,27 @@ BIF_RETTYPE load_nif_2(BIF_ALIST_2)
/* Call load, reload or upgrade:
*/
- if (mod->nif.handle != NULL) { /* Reload */
+
+
+ lib = erts_alloc(ERTS_ALC_T_NIF, sizeof(struct erl_module_nif));
+ lib->handle = handle;
+ lib->entry = entry;
+ erts_refc_init(&lib->rt_cnt, 0);
+ erts_refc_init(&lib->rt_dtor_cnt, 0);
+ lib->is_orphan = 0;
+ env.mod_nif = lib;
+ if (mod->nif != NULL) { /* Reload */
int k;
- ASSERT(mod->nif.entry != NULL);
+ lib->priv_data = mod->nif->priv_data;
+
+ ASSERT(mod->nif->entry != NULL);
if (entry->reload == NULL) {
ret = load_nif_error(BIF_P,reload,"Reload not supported by this NIF library.");
goto error;
}
/* Check that no NIF is removed */
- for (k=0; k < mod->nif.entry->num_of_funcs; k++) {
- ErlNifFunc* old_func = &mod->nif.entry->funcs[k];
+ for (k=0; k < mod->nif->entry->num_of_funcs; k++) {
+ ErlNifFunc* old_func = &mod->nif->entry->funcs[k];
for (i=0; i < entry->num_of_funcs; i++) {
if (old_func->arity == entry->funcs[i].arity
&& sys_strcmp(old_func->name, entry->funcs[i].name) == 0) {
@@ -565,37 +1222,39 @@ BIF_RETTYPE load_nif_2(BIF_ALIST_2)
goto error;
}
}
- erts_pre_nif(&env, BIF_P, mod->nif.data);
- veto = entry->reload(&env, &env.nif_data, BIF_ARG_2);
+ erts_pre_nif(&env, BIF_P, lib);
+ veto = entry->reload(&env, &lib->priv_data, BIF_ARG_2);
erts_post_nif(&env);
if (veto) {
ret = load_nif_error(BIF_P, reload, "Library reload-call unsuccessful.");
}
else {
- erts_sys_ddll_close(mod->nif.handle);
+ mod->nif->entry = NULL; /* to prevent 'unload' callback */
+ erts_unload_nif(mod->nif);
}
}
else {
- if (mod->old_nif.handle != NULL) { /* Upgrade */
- void* prev_old_data = mod->old_nif.data;
+ lib->priv_data = NULL;
+ if (mod->old_nif != NULL) { /* Upgrade */
+ void* prev_old_data = mod->old_nif->priv_data;
if (entry->upgrade == NULL) {
ret = load_nif_error(BIF_P, upgrade, "Upgrade not supported by this NIF library.");
goto error;
}
- erts_pre_nif(&env, BIF_P, NULL);
- veto = entry->upgrade(&env, &env.nif_data, &mod->old_nif.data, BIF_ARG_2);
+ erts_pre_nif(&env, BIF_P, lib);
+ veto = entry->upgrade(&env, &lib->priv_data, &mod->old_nif->priv_data, BIF_ARG_2);
erts_post_nif(&env);
if (veto) {
- mod->old_nif.data = prev_old_data;
+ mod->old_nif->priv_data = prev_old_data;
ret = load_nif_error(BIF_P, upgrade, "Library upgrade-call unsuccessful.");
}
- else if (mod->old_nif.data != prev_old_data) {
- refresh_cached_nif_data(mod->old_code, &mod->old_nif);
- }
+ /*else if (mod->old_nif->priv_data != prev_old_data) {
+ refresh_cached_nif_data(mod->old_code, mod->old_nif);
+ }*/
}
else if (entry->load != NULL) { /* Initial load */
- erts_pre_nif(&env, BIF_P, NULL);
- veto = entry->load(&env, &env.nif_data, BIF_ARG_2);
+ erts_pre_nif(&env, BIF_P, lib);
+ veto = entry->load(&env, &lib->priv_data, BIF_ARG_2);
erts_post_nif(&env);
if (veto) {
ret = load_nif_error(BIF_P, "load", "Library load-call unsuccessful.");
@@ -606,28 +1265,30 @@ BIF_RETTYPE load_nif_2(BIF_ALIST_2)
/*
** Everything ok, patch the beam code with op_call_nif
*/
- mod->nif.data = env.nif_data;
- mod->nif.handle = handle;
- mod->nif.entry = entry;
+ mod->nif = lib;
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) {
code_ptr[5+0] = (Uint) BeamOp(op_call_nif);
- } else { /* Function traced, patch the original instruction word */
+ }
+ else { /* Function traced, patch the original instruction word */
BpData* bp = (BpData*) code_ptr[1];
bp->orig_instr = (Uint) BeamOp(op_call_nif);
}
code_ptr[5+1] = (Uint) entry->funcs[i].fptr;
- code_ptr[5+2] = (Uint) mod->nif.data;
+ code_ptr[5+2] = (Uint) lib;
}
}
else {
error:
ASSERT(ret != am_ok);
+ if (lib != NULL) {
+ erts_free(ERTS_ALC_T_NIF, lib);
+ }
if (handle != NULL) {
erts_sys_ddll_close(handle);
}
@@ -639,3 +1300,53 @@ BIF_RETTYPE load_nif_2(BIF_ALIST_2)
BIF_RET(ret);
}
+
+void
+erts_unload_nif(struct erl_module_nif* lib)
+{
+ ErlNifResourceType* rt;
+ ErlNifResourceType* next;
+ ASSERT(erts_smp_is_system_blocked(0));
+ ASSERT(lib != NULL);
+ ASSERT(!lib->is_orphan);
+ for (rt = resource_type_list.next;
+ rt != &resource_type_list;
+ rt = next) {
+
+ next = rt->next;
+ if (rt->owner == lib) {
+ rt->next->prev = rt->prev;
+ rt->prev->next = rt->next;
+ rt->next = NULL;
+ rt->prev = NULL;
+ if (erts_refc_dectest(&rt->refc, 0) == 0) {
+ if (rt->dtor != NULL) {
+ erts_refc_dec(&lib->rt_dtor_cnt, 0);
+ }
+ erts_refc_dec(&lib->rt_cnt, 0);
+ erts_free(ERTS_ALC_T_NIF, rt);
+ }
+ }
+ }
+ if (erts_refc_read(&lib->rt_dtor_cnt, 0) == 0) {
+ close_lib(lib);
+ if (erts_refc_read(&lib->rt_cnt, 0) == 0) {
+ erts_free(ERTS_ALC_T_NIF, lib);
+ return;
+ }
+ }
+ else {
+ ASSERT(erts_refc_read(&lib->rt_cnt, 1) > 0);
+ }
+ lib->is_orphan = 1;
+}
+
+void erl_nif_init()
+{
+ resource_type_list.next = &resource_type_list;
+ resource_type_list.prev = &resource_type_list;
+ resource_type_list.dtor = NULL;
+ resource_type_list.owner = NULL;
+ resource_type_list.name[0] = '\0';
+}
+
diff --git a/erts/emulator/beam/erl_nif.h b/erts/emulator/beam/erl_nif.h
index 8650b7ce47..1ccf00293e 100644
--- a/erts/emulator/beam/erl_nif.h
+++ b/erts/emulator/beam/erl_nif.h
@@ -1,42 +1,51 @@
/*
* %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%
*/
/* Include file for writers of Native Implemented Functions.
*/
-#define ERL_NIF_MAJOR_VERSION 0
-#define ERL_NIF_MINOR_VERSION 1
+#ifndef __ERL_NIF_H__
+#define __ERL_NIF_H__
+
+#include "erl_drv_nif.h"
+
+/* 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;
@@ -59,11 +68,32 @@ typedef struct
/* Internals (avert your eyes) */
ERL_NIF_TERM bin_term;
- unsigned char* tmp_alloc;
void* ref_bin;
-
}ErlNifBinary;
+typedef struct enif_resource_type_t ErlNifResourceType;
+typedef void ErlNifResourceDtor(ErlNifEnv*, void*);
+enum ErlNifResourceFlags
+{
+ ERL_NIF_RT_CREATE = 1,
+ ERL_NIF_RT_TAKEOVER = 2
+};
+
+typedef enum
+{
+ ERL_NIF_LATIN1 = 1
+}ErlNifCharEncoding;
+
+typedef ErlDrvSysInfo ErlNifSysInfo;
+
+typedef struct ErlDrvTid_ *ErlNifTid;
+typedef struct ErlDrvMutex_ ErlNifMutex;
+typedef struct ErlDrvCond_ ErlNifCond;
+typedef struct ErlDrvRWLock_ ErlNifRWLock;
+typedef int ErlNifTSDKey;
+
+typedef ErlDrvThreadOpts ErlNifThreadOpts;
+
#if (defined(__WIN32__) || defined(_WIN32) || defined(_WIN32_))
# define ERL_NIF_API_FUNC_DECL(RET_TYPE, NAME, ARGS) RET_TYPE (*NAME) ARGS
typedef struct {
@@ -120,3 +150,5 @@ ERL_NIF_INIT_DECL(NAME) \
return &entry; \
}
+#endif /* __ERL_NIF_H__ */
+
diff --git a/erts/emulator/beam/erl_nif_api_funcs.h b/erts/emulator/beam/erl_nif_api_funcs.h
index 400c1822cc..ec07a976b2 100644
--- a/erts/emulator/beam/erl_nif_api_funcs.h
+++ b/erts/emulator/beam/erl_nif_api_funcs.h
@@ -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%
*/
@@ -22,47 +22,204 @@
#endif
#ifdef ERL_NIF_API_FUNC_DECL
-ERL_NIF_API_FUNC_DECL(void*,enif_get_data,(ErlNifEnv*));
+ERL_NIF_API_FUNC_DECL(void*,enif_priv_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, const 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_string,(ErlNifEnv* env, const char* string, ErlNifCharEncoding));
+ERL_NIF_API_FUNC_DECL(ERL_NIF_TERM,enif_make_ref,(ErlNifEnv* env));
+
+ERL_NIF_API_FUNC_DECL(ErlNifMutex*,enif_mutex_create,(char *name));
+ERL_NIF_API_FUNC_DECL(void,enif_mutex_destroy,(ErlNifMutex *mtx));
+ERL_NIF_API_FUNC_DECL(int,enif_mutex_trylock,(ErlNifMutex *mtx));
+ERL_NIF_API_FUNC_DECL(void,enif_mutex_lock,(ErlNifMutex *mtx));
+ERL_NIF_API_FUNC_DECL(void,enif_mutex_unlock,(ErlNifMutex *mtx));
+ERL_NIF_API_FUNC_DECL(ErlNifCond*,enif_cond_create,(char *name));
+ERL_NIF_API_FUNC_DECL(void,enif_cond_destroy,(ErlNifCond *cnd));
+ERL_NIF_API_FUNC_DECL(void,enif_cond_signal,(ErlNifCond *cnd));
+ERL_NIF_API_FUNC_DECL(void,enif_cond_broadcast,(ErlNifCond *cnd));
+ERL_NIF_API_FUNC_DECL(void,enif_cond_wait,(ErlNifCond *cnd, ErlNifMutex *mtx));
+ERL_NIF_API_FUNC_DECL(ErlNifRWLock*,enif_rwlock_create,(char *name));
+ERL_NIF_API_FUNC_DECL(void,enif_rwlock_destroy,(ErlNifRWLock *rwlck));
+ERL_NIF_API_FUNC_DECL(int,enif_rwlock_tryrlock,(ErlNifRWLock *rwlck));
+ERL_NIF_API_FUNC_DECL(void,enif_rwlock_rlock,(ErlNifRWLock *rwlck));
+ERL_NIF_API_FUNC_DECL(void,enif_rwlock_runlock,(ErlNifRWLock *rwlck));
+ERL_NIF_API_FUNC_DECL(int,enif_rwlock_tryrwlock,(ErlNifRWLock *rwlck));
+ERL_NIF_API_FUNC_DECL(void,enif_rwlock_rwlock,(ErlNifRWLock *rwlck));
+ERL_NIF_API_FUNC_DECL(void,enif_rwlock_rwunlock,(ErlNifRWLock *rwlck));
+ERL_NIF_API_FUNC_DECL(int,enif_tsd_key_create,(char *name, ErlNifTSDKey *key));
+ERL_NIF_API_FUNC_DECL(void,enif_tsd_key_destroy,(ErlNifTSDKey key));
+ERL_NIF_API_FUNC_DECL(void,enif_tsd_set,(ErlNifTSDKey key, void *data));
+ERL_NIF_API_FUNC_DECL(void*,enif_tsd_get,(ErlNifTSDKey key));
+ERL_NIF_API_FUNC_DECL(ErlNifThreadOpts*,enif_thread_opts_create,(char *name));
+ERL_NIF_API_FUNC_DECL(void,enif_thread_opts_destroy,(ErlNifThreadOpts *opts));
+ERL_NIF_API_FUNC_DECL(int,enif_thread_create,(char *name,ErlNifTid *tid,void * (*func)(void *),void *args,ErlNifThreadOpts *opts));
+ERL_NIF_API_FUNC_DECL(ErlNifTid,enif_thread_self,(void));
+ERL_NIF_API_FUNC_DECL(int,enif_equal_tids,(ErlNifTid tid1, ErlNifTid tid2));
+ERL_NIF_API_FUNC_DECL(void,enif_thread_exit,(void *resp));
+ERL_NIF_API_FUNC_DECL(int,enif_thread_join,(ErlNifTid, void **respp));
+
+ERL_NIF_API_FUNC_DECL(void*,enif_realloc,(ErlNifEnv*, void* ptr, size_t size));
+ERL_NIF_API_FUNC_DECL(void,enif_system_info,(ErlNifSysInfo *sip, size_t si_size));
+ERL_NIF_API_FUNC_DECL(int,enif_fprintf,(void/* FILE* */ *filep, const char *format, ...));
+ERL_NIF_API_FUNC_DECL(int,enif_inspect_iolist_as_binary,(ErlNifEnv*, ERL_NIF_TERM term, ErlNifBinary* bin));
+ERL_NIF_API_FUNC_DECL(ERL_NIF_TERM,enif_make_sub_binary,(ErlNifEnv*, ERL_NIF_TERM bin_term, unsigned pos, unsigned size));
+ERL_NIF_API_FUNC_DECL(int,enif_get_string,(ErlNifEnv*, ERL_NIF_TERM list, char* buf, unsigned len, ErlNifCharEncoding));
+ERL_NIF_API_FUNC_DECL(int,enif_get_atom,(ErlNifEnv*, ERL_NIF_TERM atom, char* buf, unsigned len));
+ERL_NIF_API_FUNC_DECL(int,enif_is_fun,(ErlNifEnv*, ERL_NIF_TERM term));
+ERL_NIF_API_FUNC_DECL(int,enif_is_pid,(ErlNifEnv*, ERL_NIF_TERM term));
+ERL_NIF_API_FUNC_DECL(int,enif_is_port,(ErlNifEnv*, ERL_NIF_TERM term));
+ERL_NIF_API_FUNC_DECL(int,enif_get_uint,(ErlNifEnv*, ERL_NIF_TERM term, unsigned* ip));
+ERL_NIF_API_FUNC_DECL(int,enif_get_long,(ErlNifEnv*, ERL_NIF_TERM term, long* ip));
+ERL_NIF_API_FUNC_DECL(ERL_NIF_TERM,enif_make_uint,(ErlNifEnv*, unsigned i));
+ERL_NIF_API_FUNC_DECL(ERL_NIF_TERM,enif_make_long,(ErlNifEnv*, long i));
+ERL_NIF_API_FUNC_DECL(ERL_NIF_TERM,enif_make_tuple_from_array,(ErlNifEnv*, const ERL_NIF_TERM arr[], unsigned cnt));
+ERL_NIF_API_FUNC_DECL(ERL_NIF_TERM,enif_make_list_from_array,(ErlNifEnv*, const ERL_NIF_TERM arr[], unsigned cnt));
+ERL_NIF_API_FUNC_DECL(int,enif_is_empty_list,(ErlNifEnv*, ERL_NIF_TERM term));
+ERL_NIF_API_FUNC_DECL(ErlNifResourceType*,enif_open_resource_type,(ErlNifEnv*, const char* type_name, void (*dtor)(ErlNifEnv*,void *), enum ErlNifResourceFlags flags, enum ErlNifResourceFlags* tried));
+ERL_NIF_API_FUNC_DECL(void*,enif_alloc_resource,(ErlNifEnv*, ErlNifResourceType* type, unsigned size));
+ERL_NIF_API_FUNC_DECL(void,enif_release_resource,(ErlNifEnv*, void* obj));
+ERL_NIF_API_FUNC_DECL(ERL_NIF_TERM,enif_make_resource,(ErlNifEnv*, void* obj));
+ERL_NIF_API_FUNC_DECL(int,enif_get_resource,(ErlNifEnv*, ERL_NIF_TERM term, ErlNifResourceType* type, void** objp));
+ERL_NIF_API_FUNC_DECL(unsigned,enif_sizeof_resource,(ErlNifEnv*, void* obj));
+/*
+** 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_priv_data ERL_NIF_API_FUNC_MACRO(enif_priv_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)
+
+# define enif_mutex_create ERL_NIF_API_FUNC_MACRO(enif_mutex_create)
+# define enif_mutex_destroy ERL_NIF_API_FUNC_MACRO(enif_mutex_destroy)
+# define enif_mutex_trylock ERL_NIF_API_FUNC_MACRO(enif_mutex_trylock)
+# define enif_mutex_lock ERL_NIF_API_FUNC_MACRO(enif_mutex_lock)
+# define enif_mutex_unlock ERL_NIF_API_FUNC_MACRO(enif_mutex_unlock)
+# define enif_cond_create ERL_NIF_API_FUNC_MACRO(enif_cond_create)
+# define enif_cond_destroy ERL_NIF_API_FUNC_MACRO(enif_cond_destroy)
+# define enif_cond_signal ERL_NIF_API_FUNC_MACRO(enif_cond_signal)
+# define enif_cond_broadcast ERL_NIF_API_FUNC_MACRO(enif_cond_broadcast)
+# define enif_cond_wait ERL_NIF_API_FUNC_MACRO(enif_cond_wait)
+# define enif_rwlock_create ERL_NIF_API_FUNC_MACRO(enif_rwlock_create)
+# define enif_rwlock_destroy ERL_NIF_API_FUNC_MACRO(enif_rwlock_destroy)
+# define enif_rwlock_tryrlock ERL_NIF_API_FUNC_MACRO(enif_rwlock_tryrlock)
+# define enif_rwlock_rlock ERL_NIF_API_FUNC_MACRO(enif_rwlock_rlock)
+# define enif_rwlock_runlock ERL_NIF_API_FUNC_MACRO(enif_rwlock_runlock)
+# define enif_rwlock_tryrwlock ERL_NIF_API_FUNC_MACRO(enif_rwlock_tryrwlock)
+# define enif_rwlock_rwlock ERL_NIF_API_FUNC_MACRO(enif_rwlock_rwlock)
+# define enif_rwlock_rwunlock ERL_NIF_API_FUNC_MACRO(enif_rwlock_rwunlock)
+# define enif_tsd_key_create ERL_NIF_API_FUNC_MACRO(enif_tsd_key_create)
+# define enif_tsd_key_destroy ERL_NIF_API_FUNC_MACRO(enif_tsd_key_destroy)
+# define enif_tsd_set ERL_NIF_API_FUNC_MACRO(enif_tsd_set)
+# define enif_tsd_get ERL_NIF_API_FUNC_MACRO(enif_tsd_get)
+# define enif_thread_opts_create ERL_NIF_API_FUNC_MACRO(enif_thread_opts_create)
+# define enif_thread_opts_destroy ERL_NIF_API_FUNC_MACRO(enif_thread_opts_destroy)
+# define enif_thread_create ERL_NIF_API_FUNC_MACRO(enif_thread_create)
+# define enif_thread_self ERL_NIF_API_FUNC_MACRO(enif_thread_self)
+# define enif_equal_tids ERL_NIF_API_FUNC_MACRO(enif_equal_tids)
+# define enif_thread_exit ERL_NIF_API_FUNC_MACRO(enif_thread_exit)
+# define enif_thread_join ERL_NIF_API_FUNC_MACRO(enif_thread_join)
+
+# define enif_realloc ERL_NIF_API_FUNC_MACRO(enif_realloc)
+# define enif_system_info ERL_NIF_API_FUNC_MACRO(enif_system_info)
+# define enif_fprintf ERL_NIF_API_FUNC_MACRO(enif_fprintf)
+# define enif_inspect_iolist_as_binary ERL_NIF_API_FUNC_MACRO(enif_inspect_iolist_as_binary)
+# define enif_make_sub_binary ERL_NIF_API_FUNC_MACRO(enif_make_sub_binary)
+# define enif_get_string ERL_NIF_API_FUNC_MACRO(enif_get_string)
+# define enif_get_atom ERL_NIF_API_FUNC_MACRO(enif_get_atom)
+# define enif_is_fun ERL_NIF_API_FUNC_MACRO(enif_is_fun)
+# define enif_is_pid ERL_NIF_API_FUNC_MACRO(enif_is_pid)
+# define enif_is_port ERL_NIF_API_FUNC_MACRO(enif_is_port)
+# define enif_get_uint ERL_NIF_API_FUNC_MACRO(enif_get_uint)
+# define enif_get_long ERL_NIF_API_FUNC_MACRO(enif_get_long)
+# define enif_make_uint ERL_NIF_API_FUNC_MACRO(enif_make_uint)
+# define enif_make_long ERL_NIF_API_FUNC_MACRO(enif_make_long)
+# define enif_make_tuple_from_array ERL_NIF_API_FUNC_MACRO(enif_make_tuple_from_array)
+# define enif_make_list_from_array ERL_NIF_API_FUNC_MACRO(enif_make_list_from_array)
+# define enif_is_empty_list ERL_NIF_API_FUNC_MACRO(enif_is_empty_list)
+# define enif_open_resource_type ERL_NIF_API_FUNC_MACRO(enif_open_resource_type)
+# define enif_alloc_resource ERL_NIF_API_FUNC_MACRO(enif_alloc_resource)
+# define enif_release_resource ERL_NIF_API_FUNC_MACRO(enif_release_resource)
+# define enif_make_resource ERL_NIF_API_FUNC_MACRO(enif_make_resource)
+# define enif_get_resource ERL_NIF_API_FUNC_MACRO(enif_get_resource)
+# define enif_sizeof_resource ERL_NIF_API_FUNC_MACRO(enif_sizeof_resource)
+
+#endif
+
+#ifndef enif_make_list1
+# define enif_make_list1(ENV,E1) enif_make_list(ENV,1,E1)
+# define enif_make_list2(ENV,E1,E2) enif_make_list(ENV,2,E1,E2)
+# define enif_make_list3(ENV,E1,E2,E3) enif_make_list(ENV,3,E1,E2,E3)
+# define enif_make_list4(ENV,E1,E2,E3,E4) enif_make_list(ENV,4,E1,E2,E3,E4)
+# define enif_make_list5(ENV,E1,E2,E3,E4,E5) enif_make_list(ENV,5,E1,E2,E3,E4,E5)
+# define enif_make_list6(ENV,E1,E2,E3,E4,E5,E6) enif_make_list(ENV,6,E1,E2,E3,E4,E5,E6)
+# define enif_make_list7(ENV,E1,E2,E3,E4,E5,E6,E7) enif_make_list(ENV,7,E1,E2,E3,E4,E5,E6,E7)
+# define enif_make_list8(ENV,E1,E2,E3,E4,E5,E6,E7,E8) enif_make_list(ENV,8,E1,E2,E3,E4,E5,E6,E7,E8)
+# define enif_make_list9(ENV,E1,E2,E3,E4,E5,E6,E7,E8,E9) enif_make_list(ENV,9,E1,E2,E3,E4,E5,E6,E7,E8,E9)
+# define enif_make_tuple1(ENV,E1) enif_make_tuple(ENV,1,E1)
+# define enif_make_tuple2(ENV,E1,E2) enif_make_tuple(ENV,2,E1,E2)
+# define enif_make_tuple3(ENV,E1,E2,E3) enif_make_tuple(ENV,3,E1,E2,E3)
+# define enif_make_tuple4(ENV,E1,E2,E3,E4) enif_make_tuple(ENV,4,E1,E2,E3,E4)
+# define enif_make_tuple5(ENV,E1,E2,E3,E4,E5) enif_make_tuple(ENV,5,E1,E2,E3,E4,E5)
+# define enif_make_tuple6(ENV,E1,E2,E3,E4,E5,E6) enif_make_tuple(ENV,6,E1,E2,E3,E4,E5,E6)
+# define enif_make_tuple7(ENV,E1,E2,E3,E4,E5,E6,E7) enif_make_tuple(ENV,7,E1,E2,E3,E4,E5,E6,E7)
+# define enif_make_tuple8(ENV,E1,E2,E3,E4,E5,E6,E7,E8) enif_make_tuple(ENV,8,E1,E2,E3,E4,E5,E6,E7,E8)
+# define enif_make_tuple9(ENV,E1,E2,E3,E4,E5,E6,E7,E8,E9) enif_make_tuple(ENV,9,E1,E2,E3,E4,E5,E6,E7,E8,E9)
+#endif
+
+#ifndef enif_get_data
+# define enif_get_data enif_priv_data /* deprecated */
#endif
diff --git a/erts/emulator/beam/erl_port_task.c b/erts/emulator/beam/erl_port_task.c
index 0fb264a53c..0b6bb0d8e9 100644
--- a/erts/emulator/beam/erl_port_task.c
+++ b/erts/emulator/beam/erl_port_task.c
@@ -1,19 +1,19 @@
/*
* %CopyrightBegin%
- *
- * Copyright Ericsson AB 2006-2009. All Rights Reserved.
- *
+ *
+ * Copyright Ericsson AB 2006-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%
*/
@@ -575,7 +575,7 @@ erts_port_task_schedule(Eterm id,
}
#endif
- ASSERT(!(runq->flags & ERTS_RUNQ_FLG_SUSPENDED));
+ ASSERT(!enq_port || !(runq->flags & ERTS_RUNQ_FLG_SUSPENDED));
ASSERT(pp->sched.taskq);
ASSERT(ptp);
@@ -601,6 +601,15 @@ erts_port_task_schedule(Eterm id,
break;
}
+#ifndef ERTS_SMP
+ /*
+ * When (!enq_port && !pp->sched.exe_taskq) is true in the smp case,
+ * the port might not be in the run queue. If this is the case, another
+ * thread is in the process of enqueueing the port. This very seldom
+ * occur, but do occur and is a valid scenario. Debug info showing this
+ * enqueue in progress must be introduced before we can enable (modified
+ * versions of these) assertions in the smp case again.
+ */
#if defined(HARD_DEBUG)
if (pp->sched.exe_taskq || enq_port)
ERTS_PT_CHK_NOT_IN_PORTQ(runq, pp);
@@ -612,6 +621,7 @@ erts_port_task_schedule(Eterm id,
ASSERT(pp->sched.prev || runq->ports.start == pp);
}
#endif
+#endif
if (!enq_port) {
ERTS_PT_CHK_PRES_PORTQ(runq, pp);
@@ -902,25 +912,45 @@ erts_port_task_execute(ErtsRunQueue *runq, Port **curr_port_pp)
*curr_port_pp = NULL;
- if (pp->sched.taskq) {
+#ifdef ERTS_SMP
+ ASSERT(runq == (ErtsRunQueue *) erts_smp_atomic_read(&pp->run_queue));
+#endif
+
+ if (!pp->sched.taskq) {
+ ASSERT(pp->sched.exe_taskq);
+ pp->sched.exe_taskq = NULL;
+ }
+ else {
+#ifdef ERTS_SMP
+ ErtsRunQueue *xrunq;
+#endif
+
ASSERT(!(pp->status & ERTS_PORT_SFLGS_DEAD));
ASSERT(pp->sched.taskq->first);
- enqueue_port(runq, pp);
- port_was_enqueued = 1;
-
- /*
- erts_smp_notify_inc_runq();
- * No need to notify schedulers about the increase in run
- * queue length since at least this thread, which is a
- * scheduler, will discover that the port run queue isn't
- * empty before trying to go to sleep.
- */
+#ifdef ERTS_SMP
+ xrunq = erts_check_emigration_need(runq, ERTS_PORT_PRIO_LEVEL);
+ if (!xrunq) {
+#endif
+ enqueue_port(runq, pp);
+ ASSERT(pp->sched.exe_taskq);
+ pp->sched.exe_taskq = NULL;
+ /* No need to notify ourselves about inc in runq. */
+#ifdef ERTS_SMP
+ }
+ else {
+ /* Port emigrated ... */
+ erts_smp_atomic_set(&pp->run_queue, (long) xrunq);
+ enqueue_port(xrunq, pp);
+ ASSERT(pp->sched.exe_taskq);
+ pp->sched.exe_taskq = NULL;
+ erts_smp_notify_inc_runq(xrunq);
+ erts_smp_runq_unlock(xrunq);
+ }
+#endif
+ port_was_enqueued = 1;
}
- ASSERT(pp->sched.exe_taskq);
- pp->sched.exe_taskq = NULL;
-
res = erts_smp_atomic_read(&erts_port_task_outstanding_io_tasks) != (long) 0;
ERTS_PT_CHK_PRES_PORTQ(runq, pp);
diff --git a/erts/emulator/beam/erl_process.c b/erts/emulator/beam/erl_process.c
index 9960172366..996806fc75 100644
--- a/erts/emulator/beam/erl_process.c
+++ b/erts/emulator/beam/erl_process.c
@@ -1,19 +1,19 @@
/*
* %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
* 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%
*/
@@ -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;
@@ -2095,7 +2095,11 @@ erts_init_scheduling(int mrq, int no_schedulers, int no_schedulers_online)
rq->ix = ix;
erts_smp_atomic_init(&rq->info_flags, ERTS_RUNQ_IFLG_NONEMPTY);
- erts_smp_mtx_init(&rq->mtx, "run_queue");
+ /* make sure that the "extra" id correponds to the schedulers
+ * id if the esdp->no <-> ix+1 mapping change.
+ */
+
+ erts_smp_mtx_init_x(&rq->mtx, "run_queue", make_small(ix + 1));
erts_smp_cnd_init(&rq->cnd);
erts_smp_atomic_init(&rq->spin_waiter, 0);
@@ -2522,8 +2526,11 @@ suspend_scheduler(ErtsSchedulerData *esdp)
NULL);
}
- erts_smp_atomic_inc(&schdlr_sspnd.active);
-
+ active_schedulers = erts_smp_atomic_inctest(&schdlr_sspnd.active);
+ if (schdlr_sspnd.changing == ERTS_SCHED_CHANGING_MULTI_SCHED
+ && schdlr_sspnd.online == active_schedulers) {
+ schdlr_sspnd.changing = 0;
+ }
erts_smp_mtx_unlock(&schdlr_sspnd.mtx);
if (erts_system_profile_flags.scheduler)
@@ -2750,18 +2757,19 @@ erts_block_multi_scheduling(Process *p, ErtsProcLocks plocks, int on, int all)
ErtsProcList *plp;
erts_smp_mtx_lock(&schdlr_sspnd.mtx);
- if (on) {
- if (schdlr_sspnd.changing) {
- res = ERTS_SCHDLR_SSPND_YIELD_RESTART; /* Yield */
- }
- else if (erts_is_multi_scheduling_blocked()) {
+
+ if (schdlr_sspnd.changing) {
+ res = ERTS_SCHDLR_SSPND_YIELD_RESTART; /* Yield */
+ }
+ else if (on) { /* ------ BLOCK ------ */
+ if (erts_is_multi_scheduling_blocked()) {
plp = proclist_create(p);
plp->next = schdlr_sspnd.msb.procs;
schdlr_sspnd.msb.procs = plp;
p->flags |= F_HAVE_BLCKD_MSCHED;
ASSERT(erts_smp_atomic_read(&schdlr_sspnd.active) == 1);
ASSERT(p->scheduler_data->no == 1);
- res = 1;
+ res = ERTS_SCHDLR_SSPND_DONE_MSCHED_BLOCKED;
}
else {
p->flags |= F_HAVE_BLCKD_MSCHED;
@@ -2842,10 +2850,11 @@ erts_block_multi_scheduling(Process *p, ErtsProcLocks plocks, int on, int all)
}
}
else if (!ongoing_multi_scheduling_block()) {
+ /* unblock not ongoing */
ASSERT(!schdlr_sspnd.msb.procs);
res = ERTS_SCHDLR_SSPND_DONE;
}
- else {
+ else { /* ------ UNBLOCK ------ */
if (p->flags & F_HAVE_BLCKD_MSCHED) {
ErtsProcList **plpp = &schdlr_sspnd.msb.procs;
plp = schdlr_sspnd.msb.procs;
@@ -2891,12 +2900,16 @@ erts_block_multi_scheduling(Process *p, ErtsProcLocks plocks, int on, int all)
#endif
p->flags &= ~F_HAVE_BLCKD_MSCHED;
erts_smp_atomic_set(&schdlr_sspnd.msb.ongoing, 0);
- if (schdlr_sspnd.online == 1)
- /* No schedulers to resume */;
+ if (schdlr_sspnd.online == 1) {
+ /* No schedulers to resume */
+ ASSERT(erts_smp_atomic_read(&schdlr_sspnd.active) == 1);
+ schdlr_sspnd.changing = 0;
+ }
else if (erts_common_run_queue) {
for (ix = 1; ix < schdlr_sspnd.online; ix++)
erts_smp_atomic_set(&ERTS_SCHEDULER_IX(ix)->suspended, 0);
wake_all_schedulers();
+ erts_smp_cnd_broadcast(&schdlr_sspnd.cnd);
}
else {
int online = schdlr_sspnd.online;
@@ -2928,9 +2941,8 @@ erts_block_multi_scheduling(Process *p, ErtsProcLocks plocks, int on, int all)
erts_smp_runq_unlock(ERTS_RUNQ_IX(0));
erts_smp_mtx_unlock(&balance_info.update_mtx);
erts_smp_mtx_lock(&schdlr_sspnd.mtx);
+ erts_smp_cnd_broadcast(&schdlr_sspnd.cnd);
}
- erts_smp_cnd_broadcast(&schdlr_sspnd.cnd);
- schdlr_sspnd.changing = 0;
res = ERTS_SCHDLR_SSPND_DONE;
}
}
@@ -5517,6 +5529,8 @@ erts_proc_migrate(Process *p, ErtsProcLocks *plcks,
p->run_queue = to_rq;
enqueue_process(to_rq, p);
+ smp_notify_inc_runq(to_rq);
+
return ERTS_MIGRATE_SUCCESS;
}
#endif /* ERTS_SMP */
@@ -6272,7 +6286,9 @@ Process *schedule(Process *p, int calls)
erts_check_my_tracer_proc(p);
#endif
- if ((FLAGS(p) & F_FORCE_GC) || (MSO(p).overhead >= BIN_VHEAP_SZ(p))) {
+ if (!ERTS_PROC_IS_EXITING(p)
+ && ((FLAGS(p) & F_FORCE_GC)
+ || (MSO(p).overhead > BIN_VHEAP_SZ(p)))) {
reds -= erts_garbage_collect(p, 0, p->arg_reg, p->arity);
if (reds < 0) {
reds = 1;
@@ -6683,13 +6699,15 @@ erl_create_process(Process* parent, /* Parent of process (default group leader).
* noone except us has access to the process.
*/
if (so->flags & SPO_USE_ARGS) {
- p->min_heap_size = so->min_heap_size;
- p->prio = so->priority;
- p->max_gen_gcs = so->max_gen_gcs;
+ p->min_heap_size = so->min_heap_size;
+ p->min_vheap_size = so->min_vheap_size;
+ p->prio = so->priority;
+ p->max_gen_gcs = so->max_gen_gcs;
} else {
- p->min_heap_size = H_MIN_SIZE;
- p->prio = PRIORITY_NORMAL;
- p->max_gen_gcs = (Uint16) erts_smp_atomic_read(&erts_max_gen_gcs);
+ p->min_heap_size = H_MIN_SIZE;
+ p->min_vheap_size = BIN_VH_MIN_SIZE;
+ p->prio = PRIORITY_NORMAL;
+ p->max_gen_gcs = (Uint16) erts_smp_atomic_read(&erts_max_gen_gcs);
}
p->skipped = 0;
ASSERT(p->min_heap_size == erts_next_heap_size(p->min_heap_size, 0));
@@ -6736,9 +6754,9 @@ erl_create_process(Process* parent, /* Parent of process (default group leader).
p->heap_sz = sz;
p->catches = 0;
- p->bin_vheap_sz = H_MIN_SIZE;
- p->bin_old_vheap_sz = H_MIN_SIZE;
- p->bin_old_vheap = 0;
+ p->bin_vheap_sz = p->min_vheap_size;
+ p->bin_old_vheap_sz = p->min_vheap_size;
+ p->bin_old_vheap = 0;
/* No need to initialize p->fcalls. */
@@ -6969,6 +6987,7 @@ void erts_init_empty_process(Process *p)
p->gen_gcs = 0;
p->max_gen_gcs = 0;
p->min_heap_size = 0;
+ p->min_vheap_size = 0;
p->status = P_RUNABLE;
p->gcstatus = P_RUNABLE;
p->rstatus = P_RUNABLE;
@@ -6985,8 +7004,8 @@ void erts_init_empty_process(Process *p)
p->ftrace = NIL;
p->fcalls = 0;
- p->bin_vheap_sz=H_MIN_SIZE;
- p->bin_old_vheap_sz=H_MIN_SIZE;
+ p->bin_vheap_sz = BIN_VH_MIN_SIZE;
+ p->bin_old_vheap_sz = BIN_VH_MIN_SIZE;
p->bin_old_vheap = 0;
#ifdef ERTS_SMP
p->u.ptimer = NULL;
@@ -8024,11 +8043,6 @@ erts_do_exit_process(Process* p, Eterm reason)
if (p->bif_timers)
erts_cancel_bif_timers(p, ERTS_PROC_LOCKS_ALL);
-#ifdef ERTS_SMP
- if (p->flags & F_HAVE_BLCKD_MSCHED)
- erts_block_multi_scheduling(p, ERTS_PROC_LOCKS_ALL, 0, 1);
-#endif
-
erts_smp_proc_unlock(p, ERTS_PROC_LOCKS_ALL_MINOR);
#ifdef ERTS_SMP
@@ -8073,6 +8087,27 @@ continue_exit_process(Process *p
erts_smp_proc_unlock(p, ERTS_PROC_LOCK_STATUS);
#endif
+#ifdef ERTS_SMP
+ if (p->flags & F_HAVE_BLCKD_MSCHED) {
+ ErtsSchedSuspendResult ssr;
+ ssr = erts_block_multi_scheduling(p, ERTS_PROC_LOCK_MAIN, 0, 1);
+ switch (ssr) {
+ case ERTS_SCHDLR_SSPND_YIELD_RESTART:
+ goto yield;
+ case ERTS_SCHDLR_SSPND_DONE_MSCHED_BLOCKED:
+ case ERTS_SCHDLR_SSPND_YIELD_DONE_MSCHED_BLOCKED:
+ case ERTS_SCHDLR_SSPND_DONE:
+ case ERTS_SCHDLR_SSPND_YIELD_DONE:
+ p->flags &= ~F_HAVE_BLCKD_MSCHED;
+ break;
+ case ERTS_SCHDLR_SSPND_EINVAL:
+ default:
+ erl_exit(ERTS_ABORT_EXIT, "%s:%d: Internal error: %d\n",
+ __FILE__, __LINE__, (int) ssr);
+ }
+ }
+#endif
+
if (p->flags & F_USING_DB) {
if (erts_db_process_exiting(p, ERTS_PROC_LOCK_MAIN))
goto yield;
diff --git a/erts/emulator/beam/erl_process.h b/erts/emulator/beam/erl_process.h
index 7bae1e4efc..f58b6932b3 100644
--- a/erts/emulator/beam/erl_process.h
+++ b/erts/emulator/beam/erl_process.h
@@ -1,19 +1,19 @@
/*
* %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
* 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%
*/
@@ -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;
@@ -472,6 +477,7 @@ struct ErtsPendingSuspend_ {
# define MSO(p) (p)->off_heap
# define MIN_HEAP_SIZE(p) (p)->min_heap_size
+# define MIN_VHEAP_SIZE(p) (p)->min_vheap_size
# define BIN_VHEAP_SZ(p) (p)->bin_vheap_sz
# define BIN_OLD_VHEAP_SZ(p) (p)->bin_old_vheap_sz
# define BIN_OLD_VHEAP(p) (p)->bin_old_vheap
@@ -490,6 +496,7 @@ struct process {
Eterm* hend; /* Heap end */
Uint heap_sz; /* Size of heap in words */
Uint min_heap_size; /* Minimum size of heap (in words). */
+ Uint min_vheap_size; /* Minimum size of virtual heap (in words). */
#if !defined(NO_FPE_SIGNALS)
volatile unsigned long fp_exception;
@@ -649,6 +656,11 @@ struct process {
* heap fragments.
*/
#endif
+
+#ifdef FORCE_HEAP_FRAGS
+ Uint space_verified; /* Avoid HAlloc forcing heap fragments when */
+ Eterm* space_verified_from; /* we rely on available heap space (TestHeap) */
+#endif
};
#ifdef CHECK_FOR_HOLES
@@ -720,8 +732,8 @@ typedef struct {
* The following items are only initialized if the SPO_USE_ARGS flag is set.
*/
Uint min_heap_size; /* Minimum heap size (must be a valued returned
- * from next_heap_size()).
- */
+ * from next_heap_size()). */
+ Uint min_vheap_size; /* Minimum virtual heap size */
int priority; /* Priority for process. */
Uint16 max_gen_gcs; /* Maximum number of gen GCs before fullsweep. */
int scheduler;
@@ -733,7 +745,20 @@ typedef struct {
#define KILL_CATCHES(p) (p)->catches = -1
-void erts_arith_shrink(Process* p, Eterm* hp);
+/* Shrink heap fragment from _last_ HAlloc.
+*/
+ERTS_GLB_INLINE void erts_heap_frag_shrink(Process* p, Eterm* hp);
+#if ERTS_GLB_INLINE_INCL_FUNC_DEF
+ERTS_GLB_INLINE void erts_heap_frag_shrink(Process* p, Eterm* hp)
+{
+ ErlHeapFragment* hf = MBUF(p);
+
+ ASSERT(hf!=NULL && (hp - hf->mem < (unsigned long)hf->size));
+
+ hf->used_size = hp - hf->mem;
+}
+#endif /* inline */
+
Eterm* erts_heap_alloc(Process* p, Uint need);
#ifdef CHECK_FOR_HOLES
Eterm* erts_set_hole_marker(Eterm* ptr, Uint sz);
diff --git a/erts/emulator/beam/erl_term.h b/erts/emulator/beam/erl_term.h
index b0a57a3ebe..a6596558fa 100644
--- a/erts/emulator/beam/erl_term.h
+++ b/erts/emulator/beam/erl_term.h
@@ -1,19 +1,19 @@
/*
* %CopyrightBegin%
- *
- * Copyright Ericsson AB 2000-2009. All Rights Reserved.
- *
+ *
+ * Copyright Ericsson AB 2000-2010. All Rights Reserved.
+ *
* The contents of this file are subject to the Erlang Public License,
* Version 1.1, (the "License"); you may not use this file except in
* compliance with the License. You should have received a copy of the
* Erlang Public License along with this software. If not, it can be
* retrieved online at http://www.erlang.org/.
- *
+ *
* Software distributed under the License is distributed on an "AS IS"
* basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
* the License for the specific language governing rights and limitations
* under the License.
- *
+ *
* %CopyrightEnd%
*/
@@ -38,7 +38,7 @@ struct erl_node_; /* Declared in erl_node_tables.h */
#endif
#if ET_DEBUG
-#define _ET_DECLARE_CHECKED(TF,F,TX) extern TF checked_##F(TX,const char*,unsigned)
+#define _ET_DECLARE_CHECKED(TF,F,TX) extern TF checked_##F(TX,const char*,unsigned);
#define _ET_APPLY(F,X) checked_##F(X,__FILE__,__LINE__)
#else
#define _ET_DECLARE_CHECKED(TF,F,TX)
@@ -160,27 +160,27 @@ struct erl_node_; /* Declared in erl_node_tables.h */
/* boxed object access methods */
#define _is_aligned(x) (((Uint)(x) & 0x3) == 0)
#define _unchecked_make_boxed(x) ((Uint)(x) + TAG_PRIMARY_BOXED)
-_ET_DECLARE_CHECKED(Eterm,make_boxed,Eterm*);
+_ET_DECLARE_CHECKED(Eterm,make_boxed,Eterm*)
#define make_boxed(x) _ET_APPLY(make_boxed,(x))
#if 1
#define _is_not_boxed(x) ((x) & (_TAG_PRIMARY_MASK-TAG_PRIMARY_BOXED))
#define _unchecked_is_boxed(x) (!_is_not_boxed((x)))
-_ET_DECLARE_CHECKED(int,is_boxed,Eterm);
+_ET_DECLARE_CHECKED(int,is_boxed,Eterm)
#define is_boxed(x) _ET_APPLY(is_boxed,(x))
#else
#define is_boxed(x) (((x) & _TAG_PRIMARY_MASK) == TAG_PRIMARY_BOXED)
#endif
#define _unchecked_boxed_val(x) ((Eterm*)((x) - TAG_PRIMARY_BOXED))
-_ET_DECLARE_CHECKED(Eterm*,boxed_val,Eterm);
+_ET_DECLARE_CHECKED(Eterm*,boxed_val,Eterm)
#define boxed_val(x) _ET_APPLY(boxed_val,(x))
/* cons cell ("list") access methods */
#define _unchecked_make_list(x) ((Uint)(x) + TAG_PRIMARY_LIST)
-_ET_DECLARE_CHECKED(Eterm,make_list,Eterm*);
+_ET_DECLARE_CHECKED(Eterm,make_list,Eterm*)
#define make_list(x) _ET_APPLY(make_list,(x))
#if 1
#define _unchecked_is_not_list(x) ((x) & (_TAG_PRIMARY_MASK-TAG_PRIMARY_LIST))
-_ET_DECLARE_CHECKED(int,is_not_list,Eterm);
+_ET_DECLARE_CHECKED(int,is_not_list,Eterm)
#define is_not_list(x) _ET_APPLY(is_not_list,(x))
#define is_list(x) (!is_not_list((x)))
#else
@@ -188,7 +188,7 @@ _ET_DECLARE_CHECKED(int,is_not_list,Eterm);
#define is_not_list(x) (!is_list((x)))
#endif
#define _unchecked_list_val(x) ((Eterm*)((x) - TAG_PRIMARY_LIST))
-_ET_DECLARE_CHECKED(Eterm*,list_val,Eterm);
+_ET_DECLARE_CHECKED(Eterm*,list_val,Eterm)
#define list_val(x) _ET_APPLY(list_val,(x))
#define CONS(hp, car, cdr) \
@@ -221,10 +221,10 @@ _ET_DECLARE_CHECKED(Eterm*,list_val,Eterm);
#define is_not_valid_bit_size(x) (!is_valid_bit_size((x)))
#define MY_IS_SSMALL(x) (((Uint) (((x) >> (SMALL_BITS-1)) + 1)) < 2)
#define _unchecked_unsigned_val(x) ((x) >> _TAG_IMMED1_SIZE)
-_ET_DECLARE_CHECKED(Uint,unsigned_val,Eterm);
+_ET_DECLARE_CHECKED(Uint,unsigned_val,Eterm)
#define unsigned_val(x) _ET_APPLY(unsigned_val,(x))
#define _unchecked_signed_val(x) ((Sint)(x) >> _TAG_IMMED1_SIZE)
-_ET_DECLARE_CHECKED(Sint,signed_val,Eterm);
+_ET_DECLARE_CHECKED(Sint,signed_val,Eterm)
#define signed_val(x) _ET_APPLY(signed_val,(x))
#if _TAG_IMMED1_SMALL == 0x0F
@@ -247,14 +247,14 @@ _ET_DECLARE_CHECKED(Sint,signed_val,Eterm);
#define is_atom(x) (((x) & _TAG_IMMED2_MASK) == _TAG_IMMED2_ATOM)
#define is_not_atom(x) (!is_atom(x))
#define _unchecked_atom_val(x) ((x) >> _TAG_IMMED2_SIZE)
-_ET_DECLARE_CHECKED(Uint,atom_val,Eterm);
+_ET_DECLARE_CHECKED(Uint,atom_val,Eterm)
#define atom_val(x) _ET_APPLY(atom_val,(x))
/* header (arityval or thing) access methods */
#define _make_header(sz,tag) ((Uint)(((sz) << _HEADER_ARITY_OFFS) + (tag)))
#define is_header(x) (((x) & _TAG_PRIMARY_MASK) == TAG_PRIMARY_HEADER)
#define _unchecked_header_arity(x) ((x) >> _HEADER_ARITY_OFFS)
-_ET_DECLARE_CHECKED(Uint,header_arity,Eterm);
+_ET_DECLARE_CHECKED(Uint,header_arity,Eterm)
#define header_arity(x) _ET_APPLY(header_arity,(x))
/* arityval access methods */
@@ -262,16 +262,16 @@ _ET_DECLARE_CHECKED(Uint,header_arity,Eterm);
#define is_arity_value(x) (((x) & _TAG_HEADER_MASK) == _TAG_HEADER_ARITYVAL)
#define is_not_arity_value(x) (!is_arity_value((x)))
#define _unchecked_arityval(x) _unchecked_header_arity((x))
-_ET_DECLARE_CHECKED(Uint,arityval,Eterm);
+_ET_DECLARE_CHECKED(Uint,arityval,Eterm)
#define arityval(x) _ET_APPLY(arityval,(x))
/* thing access methods */
#define is_thing(x) (is_header((x)) && header_is_thing((x)))
#define _unchecked_thing_arityval(x) _unchecked_header_arity((x))
-_ET_DECLARE_CHECKED(Uint,thing_arityval,Eterm);
+_ET_DECLARE_CHECKED(Uint,thing_arityval,Eterm)
#define thing_arityval(x) _ET_APPLY(thing_arityval,(x))
#define _unchecked_thing_subtag(x) ((x) & _HEADER_SUBTAG_MASK)
-_ET_DECLARE_CHECKED(Uint,thing_subtag,Eterm);
+_ET_DECLARE_CHECKED(Uint,thing_subtag,Eterm)
#define thing_subtag(x) _ET_APPLY(thing_subtag,(x))
/*
@@ -301,7 +301,7 @@ _ET_DECLARE_CHECKED(Uint,thing_subtag,Eterm);
#define is_binary(x) (is_boxed((x)) && is_binary_header(*boxed_val((x))))
#define is_not_binary(x) (!is_binary((x)))
#define _unchecked_binary_val(x) _unchecked_boxed_val((x))
-_ET_DECLARE_CHECKED(Eterm*,binary_val,Eterm);
+_ET_DECLARE_CHECKED(Eterm*,binary_val,Eterm)
#define binary_val(x) _ET_APPLY(binary_val,(x))
/* process binaries stuff (special case of binaries) */
@@ -318,7 +318,7 @@ _ET_DECLARE_CHECKED(Eterm*,binary_val,Eterm);
#define is_fun(x) (is_boxed((x)) && is_fun_header(*boxed_val((x))))
#define is_not_fun(x) (!is_fun((x)))
#define _unchecked_fun_val(x) _unchecked_boxed_val((x))
-_ET_DECLARE_CHECKED(Eterm*,fun_val,Eterm);
+_ET_DECLARE_CHECKED(Eterm*,fun_val,Eterm)
#define fun_val(x) _ET_APPLY(fun_val,(x))
/* export access methods */
@@ -326,7 +326,7 @@ _ET_DECLARE_CHECKED(Eterm*,fun_val,Eterm);
#define is_export(x) (is_boxed((x)) && is_export_header(*boxed_val((x))))
#define is_not_export(x) (!is_export((x)))
#define _unchecked_export_val(x) _unchecked_boxed_val(x)
-_ET_DECLARE_CHECKED(Eterm*,export_val,Eterm);
+_ET_DECLARE_CHECKED(Eterm*,export_val,Eterm)
#define export_val(x) _ET_APPLY(export_val,(x))
#define is_export_header(x) ((x) == HEADER_EXPORT)
#define HEADER_EXPORT _make_header(1,_TAG_HEADER_EXPORT)
@@ -336,20 +336,20 @@ _ET_DECLARE_CHECKED(Eterm*,export_val,Eterm);
#define make_neg_bignum_header(sz) _make_header((sz),_TAG_HEADER_NEG_BIG)
#define _is_bignum_header(x) (((x) & (_TAG_HEADER_MASK-_BIG_SIGN_BIT)) == _TAG_HEADER_POS_BIG)
#define _unchecked_bignum_header_is_neg(x) ((x) & _BIG_SIGN_BIT)
-_ET_DECLARE_CHECKED(int,bignum_header_is_neg,Eterm);
+_ET_DECLARE_CHECKED(int,bignum_header_is_neg,Eterm)
#define bignum_header_is_neg(x) _ET_APPLY(bignum_header_is_neg,(x))
#define _unchecked_bignum_header_neg(x) ((x) | _BIG_SIGN_BIT)
-_ET_DECLARE_CHECKED(Eterm,bignum_header_neg,Eterm);
+_ET_DECLARE_CHECKED(Eterm,bignum_header_neg,Eterm)
#define bignum_header_neg(x) _ET_APPLY(bignum_header_neg,(x))
#define _unchecked_bignum_header_arity(x) _unchecked_header_arity((x))
-_ET_DECLARE_CHECKED(Uint,bignum_header_arity,Eterm);
+_ET_DECLARE_CHECKED(Uint,bignum_header_arity,Eterm)
#define bignum_header_arity(x) _ET_APPLY(bignum_header_arity,(x))
#define BIG_ARITY_MAX ((1 << 19)-1)
#define make_big(x) make_boxed((x))
#define is_big(x) (is_boxed((x)) && _is_bignum_header(*boxed_val((x))))
#define is_not_big(x) (!is_big((x)))
#define _unchecked_big_val(x) _unchecked_boxed_val((x))
-_ET_DECLARE_CHECKED(Eterm*,big_val,Eterm);
+_ET_DECLARE_CHECKED(Eterm*,big_val,Eterm)
#define big_val(x) _ET_APPLY(big_val,(x))
/* flonum ("float") access methods */
@@ -362,7 +362,7 @@ _ET_DECLARE_CHECKED(Eterm*,big_val,Eterm);
#define is_float(x) (is_boxed((x)) && *boxed_val((x)) == HEADER_FLONUM)
#define is_not_float(x) (!is_float(x))
#define _unchecked_float_val(x) _unchecked_boxed_val((x))
-_ET_DECLARE_CHECKED(Eterm*,float_val,Eterm);
+_ET_DECLARE_CHECKED(Eterm*,float_val,Eterm)
#define float_val(x) _ET_APPLY(float_val,(x))
/* Float definition for byte and word access */
@@ -409,7 +409,7 @@ typedef union float_def
(is_boxed((x)) && *boxed_val((x)) == make_arityval((a)))
#define is_not_tuple_arity(x, a) (!is_tuple_arity((x),(a)))
#define _unchecked_tuple_val(x) _unchecked_boxed_val(x)
-_ET_DECLARE_CHECKED(Eterm*,tuple_val,Eterm);
+_ET_DECLARE_CHECKED(Eterm*,tuple_val,Eterm)
#define tuple_val(x) _ET_APPLY(tuple_val,(x))
#define TUPLE0(t) \
@@ -548,11 +548,11 @@ _ET_DECLARE_CHECKED(Eterm*,tuple_val,Eterm);
#define is_not_internal_pid(x) (!is_internal_pid((x)))
#define _unchecked_internal_pid_data(x) _GET_PID_DATA((x))
-_ET_DECLARE_CHECKED(Uint,internal_pid_data,Eterm);
+_ET_DECLARE_CHECKED(Uint,internal_pid_data,Eterm)
#define internal_pid_data(x) _ET_APPLY(internal_pid_data,(x))
#define _unchecked_internal_pid_node(x) erts_this_node
-_ET_DECLARE_CHECKED(struct erl_node_*,internal_pid_node,Eterm);
+_ET_DECLARE_CHECKED(struct erl_node_*,internal_pid_node,Eterm)
#define internal_pid_node(x) _ET_APPLY(internal_pid_node,(x))
#define internal_pid_number(x) _GET_PID_NUM(internal_pid_data((x)))
@@ -604,13 +604,13 @@ _ET_DECLARE_CHECKED(struct erl_node_*,internal_pid_node,Eterm);
#define is_not_internal_port(x) (!is_internal_port(x))
#define _unchecked_internal_port_data(x) _GET_PORT_DATA((x))
-_ET_DECLARE_CHECKED(Uint,internal_port_data,Eterm);
+_ET_DECLARE_CHECKED(Uint,internal_port_data,Eterm)
#define internal_port_data(x) _ET_APPLY(internal_port_data,(x))
#define internal_port_number(x) _GET_PORT_NUM(internal_port_data((x)))
#define _unchecked_internal_port_node(x) erts_this_node
-_ET_DECLARE_CHECKED(struct erl_node_*,internal_port_node,Eterm);
+_ET_DECLARE_CHECKED(struct erl_node_*,internal_port_node,Eterm)
#define internal_port_node(x) _ET_APPLY(internal_port_node,(x))
#define internal_port_data_words(x) (1)
@@ -753,20 +753,20 @@ do { \
(!is_internal_ref((x)))
#define _unchecked_internal_ref_val(x) _unchecked_boxed_val((x))
-_ET_DECLARE_CHECKED(Eterm*,internal_ref_val,Eterm);
+_ET_DECLARE_CHECKED(Eterm*,internal_ref_val,Eterm)
#define internal_ref_val(x) _ET_APPLY(internal_ref_val,(x))
#define _unchecked_internal_ref_data_words(x) \
(_unchecked_thing_arityval(*_unchecked_internal_ref_val(x)))
-_ET_DECLARE_CHECKED(Uint,internal_ref_data_words,Eterm);
+_ET_DECLARE_CHECKED(Uint,internal_ref_data_words,Eterm)
#define internal_ref_data_words(x) _ET_APPLY(internal_ref_data_words,(x))
#define _unchecked_internal_ref_data(x) (_unchecked_ref_thing_ptr(x)->data.ui32)
-_ET_DECLARE_CHECKED(Uint32*,internal_ref_data,Eterm);
+_ET_DECLARE_CHECKED(Uint32*,internal_ref_data,Eterm)
#define internal_ref_data(x) _ET_APPLY(internal_ref_data,(x))
#define _unchecked_internal_ref_node(x) erts_this_node
-_ET_DECLARE_CHECKED(struct erl_node_*,internal_ref_node,Eterm);
+_ET_DECLARE_CHECKED(struct erl_node_*,internal_ref_node,Eterm)
#define internal_ref_node(x) _ET_APPLY(internal_ref_node,(x))
/*
@@ -864,7 +864,7 @@ typedef struct external_thing_ {
#define make_external_ref make_external
#define _unchecked_external_val(x) _unchecked_boxed_val((x))
-_ET_DECLARE_CHECKED(Eterm*,external_val,Eterm);
+_ET_DECLARE_CHECKED(Eterm*,external_val,Eterm)
#define external_val(x) _ET_APPLY(external_val,(x))
#define external_thing_ptr(x) ((ExternalThing *) external_val((x)))
@@ -874,7 +874,7 @@ _ET_DECLARE_CHECKED(Eterm*,external_val,Eterm);
#define _unchecked_external_data_words(x) \
(_unchecked_thing_arityval(_unchecked_external_thing_ptr((x))->header) \
+ (1 - EXTERNAL_THING_HEAD_SIZE))
-_ET_DECLARE_CHECKED(Uint,external_data_words,Eterm);
+_ET_DECLARE_CHECKED(Uint,external_data_words,Eterm)
#define external_data_words(x) _ET_APPLY(external_data_words,(x))
#define _unchecked_external_data(x) (_unchecked_external_thing_ptr((x))->data.ui)
@@ -885,15 +885,15 @@ _ET_DECLARE_CHECKED(Uint,external_data_words,Eterm);
#define _unchecked_external_pid_data_words(x) \
_unchecked_external_data_words((x))
-_ET_DECLARE_CHECKED(Uint,external_pid_data_words,Eterm);
+_ET_DECLARE_CHECKED(Uint,external_pid_data_words,Eterm)
#define external_pid_data_words(x) _ET_APPLY(external_pid_data_words,(x))
#define _unchecked_external_pid_data(x) _unchecked_external_data((x))[0]
-_ET_DECLARE_CHECKED(Uint,external_pid_data,Eterm);
+_ET_DECLARE_CHECKED(Uint,external_pid_data,Eterm)
#define external_pid_data(x) _ET_APPLY(external_pid_data,(x))
#define _unchecked_external_pid_node(x) _unchecked_external_node((x))
-_ET_DECLARE_CHECKED(struct erl_node_*,external_pid_node,Eterm);
+_ET_DECLARE_CHECKED(struct erl_node_*,external_pid_node,Eterm)
#define external_pid_node(x) _ET_APPLY(external_pid_node,(x))
#define external_pid_number(x) _GET_PID_NUM(external_pid_data((x)))
@@ -901,30 +901,30 @@ _ET_DECLARE_CHECKED(struct erl_node_*,external_pid_node,Eterm);
#define _unchecked_external_port_data_words(x) \
_unchecked_external_data_words((x))
-_ET_DECLARE_CHECKED(Uint,external_port_data_words,Eterm);
+_ET_DECLARE_CHECKED(Uint,external_port_data_words,Eterm)
#define external_port_data_words(x) _ET_APPLY(external_port_data_words,(x))
#define _unchecked_external_port_data(x) _unchecked_external_data((x))[0]
-_ET_DECLARE_CHECKED(Uint,external_port_data,Eterm);
+_ET_DECLARE_CHECKED(Uint,external_port_data,Eterm)
#define external_port_data(x) _ET_APPLY(external_port_data,(x))
#define _unchecked_external_port_node(x) _unchecked_external_node((x))
-_ET_DECLARE_CHECKED(struct erl_node_*,external_port_node,Eterm);
+_ET_DECLARE_CHECKED(struct erl_node_*,external_port_node,Eterm)
#define external_port_node(x) _ET_APPLY(external_port_node,(x))
#define external_port_number(x) _GET_PORT_NUM(external_port_data((x)))
#define _unchecked_external_ref_data_words(x) \
_unchecked_external_data_words((x))
-_ET_DECLARE_CHECKED(Uint,external_ref_data_words,Eterm);
+_ET_DECLARE_CHECKED(Uint,external_ref_data_words,Eterm)
#define external_ref_data_words(x) _ET_APPLY(external_ref_data_words,(x))
#define _unchecked_external_ref_data(x) (_unchecked_external_thing_ptr((x))->data.ui32)
-_ET_DECLARE_CHECKED(Uint32*,external_ref_data,Eterm);
+_ET_DECLARE_CHECKED(Uint32*,external_ref_data,Eterm)
#define external_ref_data(x) _ET_APPLY(external_ref_data,(x))
#define _unchecked_external_ref_node(x) _unchecked_external_node((x))
-_ET_DECLARE_CHECKED(struct erl_node_*,external_ref_node,Eterm);
+_ET_DECLARE_CHECKED(struct erl_node_*,external_ref_node,Eterm)
#define external_ref_node(x) _ET_APPLY(external_ref_node,(x))
/* number tests */
@@ -945,21 +945,21 @@ _ET_DECLARE_CHECKED(struct erl_node_*,external_ref_node,Eterm);
#endif
#define _unchecked_make_cp(x) ((Eterm)(x))
-_ET_DECLARE_CHECKED(Eterm,make_cp,Uint*);
+_ET_DECLARE_CHECKED(Eterm,make_cp,Uint*)
#define make_cp(x) _ET_APPLY(make_cp,(x))
#define is_not_CP(x) ((x) & _CPMASK)
#define is_CP(x) (!is_not_CP(x))
#define _unchecked_cp_val(x) ((Uint*)(x))
-_ET_DECLARE_CHECKED(Uint*,cp_val,Eterm);
+_ET_DECLARE_CHECKED(Uint*,cp_val,Eterm)
#define cp_val(x) _ET_APPLY(cp_val,(x))
#define make_catch(x) (((x) << _TAG_IMMED2_SIZE) | _TAG_IMMED2_CATCH)
#define is_catch(x) (((x) & _TAG_IMMED2_MASK) == _TAG_IMMED2_CATCH)
#define is_not_catch(x) (!is_catch(x))
#define _unchecked_catch_val(x) ((x) >> _TAG_IMMED2_SIZE)
-_ET_DECLARE_CHECKED(Uint,catch_val,Eterm);
+_ET_DECLARE_CHECKED(Uint,catch_val,Eterm)
#define catch_val(x) _ET_APPLY(catch_val,(x))
#define make_blank(X) ((X) = NIL)
@@ -989,21 +989,21 @@ _ET_DECLARE_CHECKED(Uint,catch_val,Eterm);
#define _is_yreg(x) (beam_reg_tag(x) == Y_REG_DEF)
#define _unchecked_x_reg_offset(R) ((R) - X_REG_DEF)
-_ET_DECLARE_CHECKED(Uint,x_reg_offset,Uint);
+_ET_DECLARE_CHECKED(Uint,x_reg_offset,Uint)
#define x_reg_offset(R) _ET_APPLY(x_reg_offset,(R))
#define _unchecked_y_reg_offset(R) ((R) - Y_REG_DEF)
-_ET_DECLARE_CHECKED(Uint,y_reg_offset,Uint);
+_ET_DECLARE_CHECKED(Uint,y_reg_offset,Uint)
#define y_reg_offset(R) _ET_APPLY(y_reg_offset,(R))
#define reg_index(R) ((R) / sizeof(Eterm))
#define _unchecked_x_reg_index(R) ((R) >> 2)
-_ET_DECLARE_CHECKED(Uint,x_reg_index,Uint);
+_ET_DECLARE_CHECKED(Uint,x_reg_index,Uint)
#define x_reg_index(R) _ET_APPLY(x_reg_index,(R))
#define _unchecked_y_reg_index(R) ((R) >> 2)
-_ET_DECLARE_CHECKED(Uint,y_reg_index,Uint);
+_ET_DECLARE_CHECKED(Uint,y_reg_index,Uint)
#define y_reg_index(R) _ET_APPLY(y_reg_index,(R))
/*
diff --git a/erts/emulator/beam/erl_time_sup.c b/erts/emulator/beam/erl_time_sup.c
index 76bfdecd9f..c15f85f8f1 100644
--- a/erts/emulator/beam/erl_time_sup.c
+++ b/erts/emulator/beam/erl_time_sup.c
@@ -1,19 +1,19 @@
/*
* %CopyrightBegin%
- *
- * Copyright Ericsson AB 1999-2009. All Rights Reserved.
- *
+ *
+ * Copyright Ericsson AB 1999-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%
*/
@@ -754,12 +754,8 @@ get_sys_now(Uint* megasec, Uint* sec, Uint* microsec)
{
SysTimeval now;
- erts_smp_mtx_lock(&erts_timeofday_mtx);
-
sys_gettimeofday(&now);
- erts_smp_mtx_unlock(&erts_timeofday_mtx);
-
*megasec = (Uint) (now.tv_sec / 1000000);
*sec = (Uint) (now.tv_sec % 1000000);
*microsec = (Uint) (now.tv_usec);
diff --git a/erts/emulator/beam/erl_trace.c b/erts/emulator/beam/erl_trace.c
index 2afb16fc52..2842c2361a 100644
--- a/erts/emulator/beam/erl_trace.c
+++ b/erts/emulator/beam/erl_trace.c
@@ -1,19 +1,19 @@
/*
* %CopyrightBegin%
- *
- * Copyright Ericsson AB 1999-2009. All Rights Reserved.
- *
+ *
+ * Copyright Ericsson AB 1999-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%
*/
@@ -2171,6 +2171,11 @@ erts_bif_trace(int bif_index, Process* p,
void
trace_gc(Process *p, Eterm what)
{
+ ERTS_DECL_AM(bin_vheap_size);
+ ERTS_DECL_AM(bin_vheap_block_size);
+ ERTS_DECL_AM(bin_old_vheap_size);
+ ERTS_DECL_AM(bin_old_vheap_block_size);
+
ErlHeapFragment *bp = NULL;
ErlOffHeap *off_heap;
ERTS_TRACER_REF_TYPE tracer_ref = ERTS_NULL_TRACER_REF; /* Initialized
@@ -2180,6 +2185,7 @@ trace_gc(Process *p, Eterm what)
Eterm* hp;
Eterm msg = NIL;
Uint size;
+
Eterm tags[] = {
am_old_heap_block_size,
am_heap_block_size,
@@ -2187,8 +2193,13 @@ trace_gc(Process *p, Eterm what)
am_recent_size,
am_stack_size,
am_old_heap_size,
- am_heap_size
+ am_heap_size,
+ AM_bin_vheap_size,
+ AM_bin_vheap_block_size,
+ AM_bin_old_vheap_size,
+ AM_bin_old_vheap_block_size
};
+
Uint values[] = {
OLD_HEAP(p) ? OLD_HEND(p) - OLD_HEAP(p) : 0,
HEAP_SIZE(p),
@@ -2196,7 +2207,11 @@ trace_gc(Process *p, Eterm what)
HIGH_WATER(p) - HEAP_START(p),
STACK_START(p) - p->stop,
OLD_HEAP(p) ? OLD_HTOP(p) - OLD_HEAP(p) : 0,
- HEAP_TOP(p) - HEAP_START(p)
+ HEAP_TOP(p) - HEAP_START(p),
+ MSO(p).overhead,
+ BIN_VHEAP_SZ(p),
+ BIN_OLD_VHEAP(p),
+ BIN_OLD_VHEAP_SZ(p)
};
Eterm local_heap[(sizeof(values)/sizeof(Uint))
*(2/*cons*/ + 3/*2-tuple*/ + BIG_UINT_HEAP_SIZE)
diff --git a/erts/emulator/beam/erl_vm.h b/erts/emulator/beam/erl_vm.h
index 4d8315ab95..50b3e5b61c 100644
--- a/erts/emulator/beam/erl_vm.h
+++ b/erts/emulator/beam/erl_vm.h
@@ -1,19 +1,19 @@
/*
* %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
* 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%
*/
@@ -22,6 +22,13 @@
/* #define ERTS_OPCODE_COUNTER_SUPPORT */
+/* FORCE_HEAP_FRAGS:
+ * Debug provocation to make HAlloc always create heap fragments (if allowed)
+ * even if there is room on heap.
+ */
+/* #define FORCE_HEAP_FRAGS */
+
+
#if defined(HYBRID)
/* # define CHECK_FOR_HOLES */
#endif
@@ -50,7 +57,8 @@
#define INPUT_REDUCTIONS (2 * CONTEXT_REDS)
-#define H_DEFAULT_SIZE 233 /* default (heap + stack) min size */
+#define H_DEFAULT_SIZE 233 /* default (heap + stack) min size */
+#define VH_DEFAULT_SIZE 32768 /* default virtual (bin) heap min size (words) */
#ifdef HYBRID
# define SH_DEFAULT_SIZE 2629425 /* default message area min size */
@@ -70,6 +78,7 @@
&& (P) == (P)->scheduler_data->match_pseudo_process) \
|| erts_is_system_blocked(0))
+
#ifdef DEBUG
/*
* Debug HAlloc that initialize all memory to bad things.
@@ -80,55 +89,43 @@
VERBOSE(DEBUG_ALLOCATION,("HAlloc @ 0x%08lx (%d) %s:%d\n", \
(unsigned long)HEAP_TOP(p),(sz),__FILE__,__LINE__)), \
*/
-#ifdef CHECK_FOR_HOLES
-#define HAlloc(p, sz) \
- (ASSERT_EXPR((sz) >= 0), \
- ErtsHAllocLockCheck(p), \
- ((((HEAP_LIMIT(p) - HEAP_TOP(p)) < (sz))) \
- ? erts_heap_alloc((p),(sz)) \
- : (erts_set_hole_marker(HEAP_TOP(p), (sz)), \
- HEAP_TOP(p) = HEAP_TOP(p) + (sz), HEAP_TOP(p) - (sz))))
+# ifdef CHECK_FOR_HOLES
+# define INIT_HEAP_MEM(p,sz) erts_set_hole_marker(HEAP_TOP(p), (sz))
+# else
+# define INIT_HEAP_MEM(p,sz) memset(HEAP_TOP(p),DEBUG_BAD_BYTE,(sz)*sizeof(Eterm*))
+# endif
#else
-#define HAlloc(p, sz) \
- (ASSERT_EXPR((sz) >= 0), \
- ErtsHAllocLockCheck(p), \
- ((((HEAP_LIMIT(p) - HEAP_TOP(p)) < (sz))) \
- ? erts_heap_alloc((p),(sz)) \
- : (memset(HEAP_TOP(p),DEBUG_BAD_BYTE,(sz)*sizeof(Eterm*)), \
- HEAP_TOP(p) = HEAP_TOP(p) + (sz), HEAP_TOP(p) - (sz))))
-#endif
+# define INIT_HEAP_MEM(p,sz) ((void)0)
+#endif /* DEBUG */
+
+
+#ifdef FORCE_HEAP_FRAGS
+# define IS_FORCE_HEAP_FRAGS 1
#else
+# define IS_FORCE_HEAP_FRAGS 0
+#endif
/*
* Allocate heap memory, first on the ordinary heap;
* failing that, in a heap fragment.
*/
-#define HAlloc(p, sz) \
- (ASSERT_EXPR((sz) >= 0), \
- ErtsHAllocLockCheck(p), \
- ((((HEAP_LIMIT(p) - HEAP_TOP(p)) < (sz))) \
- ? erts_heap_alloc((p),(sz)) \
- : (HEAP_TOP(p) = HEAP_TOP(p) + (sz), HEAP_TOP(p) - (sz))))
+#define HAlloc(p, sz) \
+ (ASSERT_EXPR((sz) >= 0), \
+ ErtsHAllocLockCheck(p), \
+ (IS_FORCE_HEAP_FRAGS || (((HEAP_LIMIT(p) - HEAP_TOP(p)) < (sz))) \
+ ? erts_heap_alloc((p),(sz)) \
+ : (INIT_HEAP_MEM(p,sz), \
+ HEAP_TOP(p) = HEAP_TOP(p) + (sz), HEAP_TOP(p) - (sz))))
-#endif /* DEBUG */
-#if defined(CHECK_FOR_HOLES)
-# define HRelease(p, endp, ptr) \
+#define HRelease(p, endp, ptr) \
if ((ptr) == (endp)) { \
; \
} else if (HEAP_START(p) <= (ptr) && (ptr) < HEAP_TOP(p)) { \
HEAP_TOP(p) = (ptr); \
} else { \
- erts_arith_shrink(p, ptr); \
+ erts_heap_frag_shrink(p, ptr); \
}
-#else
-# define HRelease(p, endp, ptr) \
- if ((ptr) == (endp)) { \
- ; \
- } else if (HEAP_START(p) <= (ptr) && (ptr) < HEAP_TOP(p)) { \
- HEAP_TOP(p) = (ptr); \
- }
-#endif
#define HeapWordsLeft(p) (HEAP_LIMIT(p) - HEAP_TOP(p))
@@ -182,6 +179,9 @@ extern int num_instructions; /* Number of instruction in opc[]. */
#define MAX_PORT_LINK 8 /* Maximum number of links to a port */
extern int H_MIN_SIZE; /* minimum (heap + stack) */
+extern int BIN_VH_MIN_SIZE; /* minimum virtual (bin) heap */
+
+extern int erts_atom_table_size;/* Atom table size */
#define ORIG_CREATION 0
diff --git a/erts/emulator/beam/external.c b/erts/emulator/beam/external.c
index f856cce18f..099eddd195 100644
--- a/erts/emulator/beam/external.c
+++ b/erts/emulator/beam/external.c
@@ -1,19 +1,19 @@
/*
* %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
* 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%
*/
@@ -271,11 +271,8 @@ erts_encode_ext_dist_header_size(ErtsAtomCacheMap *acmp)
byte *erts_encode_ext_dist_header_setup(byte *ctl_ext, ErtsAtomCacheMap *acmp)
{
-#ifndef ARCH_32
-#if ATOM_LIMIT >= (1UL << 32)
-#error "ATOM_LIMIT too large for interal atom cache update instructions. New instructions needed."
-#endif
-#endif
+ /* Maximum number of atom must be less than the maximum of a 32 bits
+ unsigned integer. Check is done in erl_init.c, erl_start function. */
if (!acmp)
return ctl_ext;
else {
@@ -1013,6 +1010,35 @@ term_to_binary_2(Process* p, Eterm Term, Eterm Flags)
return erts_term_to_binary(p, Term, level, flags);
}
+static uLongf binary2term_uncomp_size(byte* data, Sint size)
+{
+ z_stream stream;
+ int err;
+ const uInt chunk_size = 64*1024; /* Ask tmp-alloc about a suitable size? */
+ void* tmp_buf = erts_alloc(ERTS_ALC_T_TMP, chunk_size);
+ uLongf uncomp_size = 0;
+
+ stream.next_in = (Bytef*)data;
+ stream.avail_in = (uInt)size;
+ stream.next_out = tmp_buf;
+ stream.avail_out = (uInt)chunk_size;
+
+ erl_zlib_alloc_init(&stream);
+
+ err = inflateInit(&stream);
+ if (err == Z_OK) {
+ do {
+ stream.next_out = tmp_buf;
+ stream.avail_out = chunk_size;
+ err = inflate(&stream, Z_NO_FLUSH);
+ uncomp_size += chunk_size - stream.avail_out;
+ }while (err == Z_OK);
+ inflateEnd(&stream);
+ }
+ erts_free(ERTS_ALC_T_TMP, tmp_buf);
+ return err == Z_STREAM_END ? uncomp_size : 0;
+}
+
static ERTS_INLINE Sint
binary2term_prepare(ErtsBinary2TermState *state, byte *data, Sint data_size)
{
@@ -1036,10 +1062,18 @@ binary2term_prepare(ErtsBinary2TermState *state, byte *data, Sint data_size)
state->extp = bytes;
}
else {
- uLongf dest_len = get_int32(bytes+1);
- state->extp = erts_alloc(ERTS_ALC_T_TMP, dest_len);
+ uLongf dest_len = (Uint32) get_int32(bytes+1);
+ bytes += 5;
+ size -= 5;
+ if (dest_len > 32*1024*1024
+ || (state->extp = erts_alloc_fnf(ERTS_ALC_T_TMP, dest_len)) == NULL) {
+ if (dest_len != binary2term_uncomp_size(bytes, size)) {
+ goto error;
+ }
+ state->extp = erts_alloc(ERTS_ALC_T_TMP, dest_len);
+ }
state->exttmp = 1;
- if (erl_zlib_uncompress(state->extp, &dest_len, bytes+5, size-5) != Z_OK)
+ if (erl_zlib_uncompress(state->extp, &dest_len, bytes, size) != Z_OK)
goto error;
size = (Sint) dest_len;
}
@@ -1059,10 +1093,10 @@ binary2term_abort(ErtsBinary2TermState *state)
}
static ERTS_INLINE Eterm
-binary2term_create(ErtsBinary2TermState *state, Eterm **hpp, ErlOffHeap *ohp)
+binary2term_create(ErtsDistExternal *edep, ErtsBinary2TermState *state, Eterm **hpp, ErlOffHeap *ohp)
{
Eterm res;
- if (!dec_term(NULL, hpp, state->extp, ohp, &res))
+ if (!dec_term(edep, hpp, state->extp, ohp, &res))
res = THE_NON_VALUE;
if (state->exttmp) {
state->exttmp = 0;
@@ -1086,7 +1120,7 @@ erts_binary2term_abort(ErtsBinary2TermState *state)
Eterm
erts_binary2term_create(ErtsBinary2TermState *state, Eterm **hpp, ErlOffHeap *ohp)
{
- return binary2term_create(state, hpp, ohp);
+ return binary2term_create(NULL,state, hpp, ohp);
}
BIF_RETTYPE binary_to_term_1(BIF_ALIST_1)
@@ -1114,7 +1148,67 @@ BIF_RETTYPE binary_to_term_1(BIF_ALIST_1)
hp = HAlloc(BIF_P, heap_size);
endp = hp + heap_size;
- res = binary2term_create(&b2ts, &hp, &MSO(BIF_P));
+ res = binary2term_create(NULL, &b2ts, &hp, &MSO(BIF_P));
+
+ erts_free_aligned_binary_bytes(temp_alloc);
+
+ if (hp > endp) {
+ erl_exit(1, ":%s, line %d: heap overrun by %d words(s)\n",
+ __FILE__, __LINE__, hp-endp);
+ }
+
+ HRelease(BIF_P, endp, hp);
+
+ if (res == THE_NON_VALUE)
+ goto error;
+
+ return res;
+}
+
+BIF_RETTYPE binary_to_term_2(BIF_ALIST_2)
+{
+ Sint heap_size;
+ Eterm res;
+ Eterm opts;
+ Eterm opt;
+ Eterm* hp;
+ Eterm* endp;
+ Sint size;
+ byte* bytes;
+ byte* temp_alloc = NULL;
+ ErtsBinary2TermState b2ts;
+ ErtsDistExternal fakedep;
+
+ fakedep.flags = 0;
+ opts = BIF_ARG_2;
+ while (is_list(opts)) {
+ opt = CAR(list_val(opts));
+ if (opt == am_safe) {
+ fakedep.flags |= ERTS_DIST_EXT_BTT_SAFE;
+ } else {
+ goto error;
+ }
+ opts = CDR(list_val(opts));
+ }
+
+ if (is_not_nil(opts))
+ goto error;
+
+ if ((bytes = erts_get_aligned_binary_bytes(BIF_ARG_1, &temp_alloc)) == NULL) {
+ error:
+ erts_free_aligned_binary_bytes(temp_alloc);
+ BIF_ERROR(BIF_P, BADARG);
+ }
+ size = binary_size(BIF_ARG_1);
+
+ heap_size = binary2term_prepare(&b2ts, bytes, size);
+ if (heap_size < 0)
+ goto error;
+
+ hp = HAlloc(BIF_P, heap_size);
+ endp = hp + heap_size;
+
+ res = binary2term_create(&fakedep, &b2ts, &hp, &MSO(BIF_P));
erts_free_aligned_binary_bytes(temp_alloc);
@@ -1300,7 +1394,7 @@ dec_atom(ErtsDistExternal *edep, byte* ep, Eterm* objp)
switch (*ep++) {
case ATOM_CACHE_REF:
- if (!(edep->flags & ERTS_DIST_EXT_ATOM_TRANS_TAB))
+ if (!(edep && (edep->flags & ERTS_DIST_EXT_ATOM_TRANS_TAB)))
goto error;
n = get_int8(ep);
ep++;
@@ -1312,13 +1406,18 @@ dec_atom(ErtsDistExternal *edep, byte* ep, Eterm* objp)
case ATOM_EXT:
len = get_int16(ep),
ep += 2;
- *objp = am_atom_put((char*)ep, len);
- ep += len;
- break;
+ goto dec_atom_common;
case SMALL_ATOM_EXT:
len = get_int8(ep);
ep++;
- *objp = am_atom_put((char*)ep, len);
+ dec_atom_common:
+ if (edep && (edep->flags & ERTS_DIST_EXT_BTT_SAFE)) {
+ if (!erts_atom_get((char*)ep, len, objp)) {
+ goto error;
+ }
+ } else {
+ *objp = am_atom_put((char*)ep, len);
+ }
ep += len;
break;
default:
@@ -1775,9 +1874,80 @@ is_external_string(Eterm list, int* p_is_string)
return len;
}
+/* Assumes that the ones to undo are preluding the lists. */
+static void
+undo_offheap_in_area(ErlOffHeap* off_heap, Eterm* start, Eterm* end)
+{
+ const Uint area_sz = (end - start) * sizeof(Eterm);
+ struct proc_bin* mso;
+ struct proc_bin** mso_nextp = NULL;
+#ifndef HYBRID /* FIND ME! */
+ struct erl_fun_thing* funs;
+ struct erl_fun_thing** funs_nextp = NULL;
+#endif
+ struct external_thing_* ext;
+ struct external_thing_** ext_nextp = NULL;
+
+ for (mso = off_heap->mso; ; mso=mso->next) {
+ if (!in_area(mso, start, area_sz)) {
+ if (mso_nextp != NULL) {
+ *mso_nextp = NULL;
+ erts_cleanup_mso(off_heap->mso);
+ off_heap->mso = mso;
+ }
+ break;
+ }
+ mso_nextp = &mso->next;
+ }
+
+#ifndef HYBRID /* FIND ME! */
+ for (funs = off_heap->funs; ; funs=funs->next) {
+ if (!in_area(funs, start, area_sz)) {
+ if (funs_nextp != NULL) {
+ *funs_nextp = NULL;
+ erts_cleanup_funs(off_heap->funs);
+ off_heap->funs = funs;
+ }
+ break;
+ }
+ funs_nextp = &funs->next;
+ }
+#endif
+ for (ext = off_heap->externals; ; ext=ext->next) {
+ if (!in_area(ext, start, area_sz)) {
+ if (ext_nextp != NULL) {
+ *ext_nextp = NULL;
+ erts_cleanup_externals(off_heap->externals);
+ off_heap->externals = ext;
+ }
+ break;
+ }
+ ext_nextp = &ext->next;
+ }
+
+ /* Assert that the ones to undo were indeed preluding the lists. */
+#ifdef DEBUG
+ for (mso = off_heap->mso; mso != NULL; mso=mso->next) {
+ ASSERT(!in_area(mso, start, area_sz));
+ }
+# ifndef HYBRID /* FIND ME! */
+ for (funs = off_heap->funs; funs != NULL; funs=funs->next) {
+ ASSERT(!in_area(funs, start, area_sz));
+ }
+# endif
+ for (ext = off_heap->externals; ext != NULL; ext=ext->next) {
+ ASSERT(!in_area(ext, start, area_sz));
+ }
+#endif /* DEBUG */
+}
+
+/* Decode term from external format into *objp.
+** On failure return NULL and (R13B04) *hpp will be unchanged.
+*/
static byte*
dec_term(ErtsDistExternal *edep, Eterm** hpp, byte* ep, ErlOffHeap* off_heap, Eterm* objp)
{
+ Eterm* hp_saved = *hpp;
int n;
register Eterm* hp = *hpp; /* Please don't take the address of hp */
Eterm* next = objp;
@@ -1864,13 +2034,18 @@ dec_term(ErtsDistExternal *edep, Eterm** hpp, byte* ep, ErlOffHeap* off_heap, Et
case ATOM_EXT:
n = get_int16(ep);
ep += 2;
- *objp = am_atom_put((char*)ep, n);
- ep += n;
- break;
+ goto dec_term_atom_common;
case SMALL_ATOM_EXT:
n = get_int8(ep);
ep++;
- *objp = am_atom_put((char*)ep, n);
+dec_term_atom_common:
+ if (edep && (edep->flags & ERTS_DIST_EXT_BTT_SAFE)) {
+ if (!erts_atom_get((char*)ep, n, objp)) {
+ goto error;
+ }
+ } else {
+ *objp = am_atom_put((char*)ep, n);
+ }
ep += n;
break;
case LARGE_TUPLE_EXT:
@@ -1973,7 +2148,7 @@ dec_term(ErtsDistExternal *edep, Eterm** hpp, byte* ep, ErlOffHeap* off_heap, Et
ep = dec_pid(edep, hpp, ep, off_heap, objp);
hp = *hpp;
if (ep == NULL) {
- return NULL;
+ goto error;
}
break;
case PORT_EXT:
@@ -2039,7 +2214,6 @@ dec_term(ErtsDistExternal *edep, Eterm** hpp, byte* ep, ErlOffHeap* off_heap, Et
goto ref_ext_common;
case NEW_REFERENCE_EXT:
-
ref_words = get_int16(ep);
ep += 2;
@@ -2209,7 +2383,7 @@ dec_term(ErtsDistExternal *edep, Eterm** hpp, byte* ep, ErlOffHeap* off_heap, Et
ep = dec_term(edep, hpp, ep, off_heap, &temp);
hp = *hpp;
if (ep == NULL) {
- return NULL;
+ goto error;
}
if (!is_small(temp)) {
goto error;
@@ -2218,6 +2392,10 @@ dec_term(ErtsDistExternal *edep, Eterm** hpp, byte* ep, ErlOffHeap* off_heap, Et
if (arity < 0) {
goto error;
}
+ if (edep && (edep->flags & ERTS_DIST_EXT_BTT_SAFE)) {
+ if (!erts_find_export_entry(mod, name, arity))
+ goto error;
+ }
*objp = make_export(hp);
*hp++ = HEADER_EXPORT;
*hp++ = (Eterm) erts_export_get_or_make_stub(mod, name, arity);
@@ -2235,8 +2413,6 @@ dec_term(ErtsDistExternal *edep, Eterm** hpp, byte* ep, ErlOffHeap* off_heap, Et
Sint old_index;
unsigned num_free;
int i;
- Eterm* temp_hp;
- Eterm** hpp = &temp_hp;
Eterm temp;
ep += 4; /* Skip total size in bytes */
@@ -2248,23 +2424,16 @@ dec_term(ErtsDistExternal *edep, Eterm** hpp, byte* ep, ErlOffHeap* off_heap, Et
num_free = get_int32(ep);
ep += 4;
hp += ERL_FUN_SIZE;
- if (num_free > 0) {
- /* Don't leave a hole in case we fail */
- *hp = make_pos_bignum_header(num_free-1);
- }
hp += num_free;
- *hpp = hp;
funp->thing_word = HEADER_FUN;
funp->num_free = num_free;
- funp->creator = NIL; /* Don't leave a hole in case we fail */
*objp = make_fun(funp);
/* Module */
- if ((ep = dec_atom(edep, ep, &temp)) == NULL) {
+ if ((ep = dec_atom(edep, ep, &module)) == NULL) {
goto error;
}
- module = temp;
-
+ *hpp = hp;
/* Index */
if ((ep = dec_term(edep, hpp, ep, off_heap, &temp)) == NULL) {
goto error;
@@ -2321,17 +2490,11 @@ dec_term(ErtsDistExternal *edep, Eterm** hpp, byte* ep, ErlOffHeap* off_heap, Et
Sint old_index;
unsigned num_free;
int i;
- Eterm* temp_hp;
- Eterm** hpp = &temp_hp;
Eterm temp;
num_free = get_int32(ep);
ep += 4;
hp += ERL_FUN_SIZE;
- if (num_free > 0) {
- /* Don't leave a hole in the heap in case we fail. */
- *hp = make_pos_bignum_header(num_free-1);
- }
hp += num_free;
*hpp = hp;
funp->thing_word = HEADER_FUN;
@@ -2339,23 +2502,16 @@ dec_term(ErtsDistExternal *edep, Eterm** hpp, byte* ep, ErlOffHeap* off_heap, Et
*objp = make_fun(funp);
/* Creator pid */
- switch(*ep) {
- case PID_EXT:
- ep = dec_pid(edep, hpp, ++ep, off_heap, &funp->creator);
- if (ep == NULL) {
- funp->creator = NIL; /* Don't leave a hole in the heap */
- goto error;
- }
- break;
- default:
+ if (*ep != PID_EXT
+ || (ep = dec_pid(edep, hpp, ++ep, off_heap,
+ &funp->creator))==NULL) {
goto error;
}
/* Module */
- if ((ep = dec_atom(edep, ep, &temp)) == NULL) {
+ if ((ep = dec_atom(edep, ep, &module)) == NULL) {
goto error;
}
- module = temp;
/* Index */
if ((ep = dec_term(edep, hpp, ep, off_heap, &temp)) == NULL) {
@@ -2382,7 +2538,6 @@ dec_term(ErtsDistExternal *edep, Eterm** hpp, byte* ep, ErlOffHeap* off_heap, Et
funp->next = off_heap->funs;
off_heap->funs = funp;
#endif
-
old_uniq = unsigned_val(temp);
funp->fe = erts_put_fun_entry(module, old_uniq, old_index);
@@ -2401,12 +2556,15 @@ dec_term(ErtsDistExternal *edep, Eterm** hpp, byte* ep, ErlOffHeap* off_heap, Et
}
default:
error:
- /*
- * Be careful to return the updated heap pointer, to avoid
- * that the caller wipes out binaries or other off-heap objects
- * that may have been linked into the process.
+ /* UNDO:
+ * Must unlink all off-heap objects that may have been
+ * linked into the process.
*/
- *hpp = hp;
+ if (hp < *hpp) { /* Sometimes we used hp and sometimes *hpp */
+ hp = *hpp; /* the largest must be the freshest */
+ }
+ undo_offheap_in_area(off_heap, hp_saved, hp);
+ *hpp = hp_saved;
return NULL;
}
}
diff --git a/erts/emulator/beam/external.h b/erts/emulator/beam/external.h
index f308680f89..eada6d4f27 100644
--- a/erts/emulator/beam/external.h
+++ b/erts/emulator/beam/external.h
@@ -1,19 +1,19 @@
/*
* %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
* 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%
*/
@@ -98,9 +98,19 @@ typedef struct {
Eterm atom[ERTS_ATOM_CACHE_SIZE];
} ErtsAtomTranslationTable;
-#define ERTS_DIST_EXT_DFLAG_HDR (((Uint32) 1) << 31)
-#define ERTS_DIST_EXT_ATOM_TRANS_TAB (((Uint32) 1) << 30)
-#define ERTS_DIST_EXT_CON_ID_MASK ((Uint32) 0x3fffffff)
+/*
+ * These flags are tagged onto the high bits of a connection ID and stored in
+ * the ErtsDistExternal structure's flags field. They are used to indicate
+ * various bits of state necessary to decode binaries in a variety of
+ * scenarios. The mask ERTS_DIST_EXT_CON_ID_MASK is used later to separate the
+ * connection ID from the flags. Be careful to ensure that the mask does not
+ * overlap any of the bits used for flags, or ERTS will leak flags bits into
+ * connection IDs and leak connection ID bits into the flags.
+ */
+#define ERTS_DIST_EXT_DFLAG_HDR ((Uint32) 0x80000000)
+#define ERTS_DIST_EXT_ATOM_TRANS_TAB ((Uint32) 0x40000000)
+#define ERTS_DIST_EXT_BTT_SAFE ((Uint32) 0x20000000)
+#define ERTS_DIST_EXT_CON_ID_MASK ((Uint32) 0x1fffffff)
#define ERTS_DIST_EXT_CON_ID(DIST_EXTP) \
((DIST_EXTP)->flags & ERTS_DIST_EXT_CON_ID_MASK)
diff --git a/erts/emulator/beam/global.h b/erts/emulator/beam/global.h
index 1b64e23174..cab249a53f 100644
--- a/erts/emulator/beam/global.h
+++ b/erts/emulator/beam/global.h
@@ -1,19 +1,19 @@
/*
* %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
* 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%
*/
@@ -21,6 +21,7 @@
#define __GLOBAL_H__
#include "sys.h"
+#include <stddef.h> /* offsetof() */
#include "erl_alloc.h"
#include "erl_vm.h"
#include "erl_node_container_utils.h"
@@ -75,18 +76,29 @@ typedef struct line_buf { /* Buffer used in line oriented I/O */
The rest is the overflow buffer. */
} LineBuf;
+/* Temporary object header, auto-deallocated when NIF returns. */
+struct enif_tmp_obj_t {
+ struct enif_tmp_obj_t* next;
+ void (*dtor)(struct enif_tmp_obj_t*);
+ /*char data[];*/
+};
struct enif_environment_t /* ErlNifEnv */
{
- void* nif_data;
+ struct erl_module_nif* mod_nif;
Process* proc;
Eterm* hp;
Eterm* hp_end;
- unsigned heap_frag_sz;
+ ErlHeapFragment* heap_frag;
int fpe_was_unmasked;
+ struct enif_tmp_obj_t* tmp_obj_list;
};
-extern void erts_pre_nif(struct enif_environment_t*, Process*, void* nif_data);
+extern void erts_pre_nif(struct enif_environment_t*, Process*,
+ struct erl_module_nif*);
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);
+void erts_unload_nif(struct erl_module_nif* nif);
+extern void erl_nif_init(void);
/*
* Port Specific Data.
@@ -381,17 +393,45 @@ extern Eterm erts_ddll_monitor_driver(Process *p,
** and Binary, the macros below can convert one type to the other, as they both
** in reality are equal.
*/
-typedef struct binary {
- Uint flags;
- erts_refc_t refc;
+
#ifdef ARCH_32
- Uint32 align__; /* *DO NOT USE* only for alignment. */
+ /* *DO NOT USE* only for alignment. */
+#define ERTS_BINARY_STRUCT_ALIGNMENT Uint32 align__;
+#else
+#define ERTS_BINARY_STRUCT_ALIGNMENT
#endif
- /* Add fields BEFORE this, otherwise the drivers crash */
+
+/* Add fields in ERTS_INTERNAL_BINARY_FIELDS, otherwise the drivers crash */
+#define ERTS_INTERNAL_BINARY_FIELDS \
+ Uint flags; \
+ erts_refc_t refc; \
+ ERTS_BINARY_STRUCT_ALIGNMENT
+
+typedef struct binary {
+ ERTS_INTERNAL_BINARY_FIELDS
long orig_size;
char orig_bytes[1]; /* to be continued */
} Binary;
+#define ERTS_SIZEOF_Binary(Sz) \
+ (offsetof(Binary,orig_bytes) + (Sz))
+
+typedef struct {
+ ERTS_INTERNAL_BINARY_FIELDS
+ long orig_size;
+ void (*destructor)(Binary *);
+ char magic_bin_data[1];
+} ErtsMagicBinary;
+
+typedef union {
+ Binary binary;
+ ErtsMagicBinary magic_binary;
+ struct {
+ ERTS_INTERNAL_BINARY_FIELDS
+ ErlDrvBinary binary;
+ } driver;
+} ErtsBinary;
+
/*
* 'Binary' alignment:
* Address of orig_bytes[0] of a Binary should always be 8-byte aligned.
@@ -399,25 +439,23 @@ typedef struct binary {
* 32-bits architectures and 8 bytes on 64-bits architectures.
*/
-/*
- * "magic" binary.
- */
-typedef struct {
- void (*destructor)(Binary *);
- char magic_bin_data[1];
-} ErtsBinaryMagicPart;
-
#define ERTS_MAGIC_BIN_DESTRUCTOR(BP) \
- (((ErtsBinaryMagicPart *) (BP)->orig_bytes)->destructor)
+ ((ErtsBinary *) (BP))->magic_binary.destructor
#define ERTS_MAGIC_BIN_DATA(BP) \
- ((void *) (((ErtsBinaryMagicPart *) (BP)->orig_bytes)->magic_bin_data))
+ ((void *) ((ErtsBinary *) (BP))->magic_binary.magic_bin_data)
#define ERTS_MAGIC_BIN_DATA_SIZE(BP) \
- ((BP)->orig_size - (sizeof(ErtsBinaryMagicPart) - 1))
-
-#define Binary2ErlDrvBinary(B) ((ErlDrvBinary *) (&((B)->orig_size)))
+ ((BP)->orig_size - sizeof(void (*)(Binary *)))
+#define ERTS_MAGIC_BIN_ORIG_SIZE(Sz) \
+ (sizeof(void (*)(Binary *)) + (Sz))
+#define ERTS_MAGIC_BIN_SIZE(Sz) \
+ (offsetof(ErtsMagicBinary,magic_bin_data) + (Sz))
+#define ERTS_MAGIC_BIN_FROM_DATA(DATA) \
+ ((ErtsBinary*)((char*)(DATA) - offsetof(ErtsMagicBinary,magic_bin_data)))
+
+#define Binary2ErlDrvBinary(B) (&((ErtsBinary *) (B))->driver.binary)
#define ErlDrvBinary2Binary(D) ((Binary *) \
- (((char *) (D)) - \
- ((char *) &(((Binary *) 0)->orig_size))))
+ (((char *) (D)) \
+ - offsetof(ErtsBinary, driver.binary)))
/* A "magic" binary flag */
#define BIN_FLAG_MAGIC 1
@@ -1405,6 +1443,11 @@ void p_slpq(_VOID_);
/* utils.c */
+/*
+ * To be used to silence unused result warnings, but do not abuse it.
+ */
+void erts_silence_warn_unused_result(long unused);
+
void erts_cleanup_offheap(ErlOffHeap *offheap);
void erts_cleanup_externals(ExternalThing *);
@@ -1657,7 +1700,6 @@ void erts_bif_trace_init(void);
/*
** Call_trace uses this API for the parameter matching functions
*/
- struct erl_heap_fragment* saved_program_buf;
#define MatchSetRef(MPSP) \
do { \
diff --git a/erts/emulator/beam/io.c b/erts/emulator/beam/io.c
index 61985271e6..3309b77086 100644
--- a/erts/emulator/beam/io.c
+++ b/erts/emulator/beam/io.c
@@ -1,19 +1,19 @@
/*
* %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
* 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%
*/
@@ -31,6 +31,7 @@
/* must be included BEFORE global.h (since it includes erl_driver.h) */
#include "erl_sys_driver.h"
+#include "erl_nif.h"
#include "erl_vm.h"
#include "global.h"
@@ -76,15 +77,35 @@ static ERTS_INLINE ErlIOQueue*
drvport2ioq(ErlDrvPort drvport)
{
int ix = (int) drvport;
+ Uint32 status;
+
if (ix < 0 || erts_max_ports <= ix)
return NULL;
- if (erts_port[ix].status & ERTS_PORT_SFLGS_INVALID_DRIVER_LOOKUP)
- return NULL;
- ERTS_LC_ASSERT(!erts_port[ix].port_data_lock
- || erts_lc_mtx_is_locked(&erts_port[ix].port_data_lock->mtx));
- ERTS_SMP_LC_ASSERT(erts_port[ix].port_data_lock
- || erts_lc_is_port_locked(&erts_port[ix]));
- return &erts_port[ix].ioq;
+
+ if (erts_get_scheduler_data()) {
+ ERTS_SMP_LC_ASSERT(erts_lc_is_port_locked(&erts_port[ix]));
+ ERTS_LC_ASSERT(!erts_port[ix].port_data_lock
+ || erts_lc_mtx_is_locked(
+ &erts_port[ix].port_data_lock->mtx));
+
+ status = erts_port[ix].status;
+ }
+ else {
+ erts_smp_port_state_lock(&erts_port[ix]);
+ status = erts_port[ix].status;
+ erts_smp_port_state_unlock(&erts_port[ix]);
+
+ ERTS_LC_ASSERT((status & ERTS_PORT_SFLGS_INVALID_DRIVER_LOOKUP)
+ || erts_port[ix].port_data_lock);
+ ERTS_LC_ASSERT(!erts_port[ix].port_data_lock
+ || erts_lc_mtx_is_locked(
+ &erts_port[ix].port_data_lock->mtx));
+
+ }
+
+ return ((status & ERTS_PORT_SFLGS_INVALID_DRIVER_LOOKUP)
+ ? NULL
+ : &erts_port[ix].ioq);
}
static ERTS_INLINE int
@@ -1078,7 +1099,7 @@ int erts_write_to_port(Eterm caller_id, Port *p, Eterm list)
}
cbin = driver_alloc_binary(csize);
if (!cbin)
- erts_alloc_enomem(ERTS_ALC_T_DRV_BINARY, sizeof(Binary) + csize);
+ erts_alloc_enomem(ERTS_ALC_T_DRV_BINARY, ERTS_SIZEOF_Binary(csize));
/* Element 0 is for driver usage to add header block */
ivp[0].iov_base = NULL;
@@ -1227,7 +1248,7 @@ void init_io(void)
erts_smp_atomic_init(&erts_port[i].refc, 0);
erts_port[i].lock = NULL;
erts_port[i].xports = NULL;
- erts_smp_spinlock_init(&erts_port[i].state_lck, "port_state");
+ erts_smp_spinlock_init_x(&erts_port[i].state_lck, "port_state", make_small(i));
#endif
erts_port[i].tracer_proc = NIL;
erts_port[i].trace_flags = 0;
@@ -4473,7 +4494,14 @@ driver_system_info(ErlDrvSysInfo *sip, size_t si_size)
sip->async_threads = erts_async_max_threads;
sip->scheduler_threads = erts_no_schedulers;
}
-
+ /*
+ * 'nif_minor_version' is the last field in the third version
+ * (driver version 1.5, NIF version 1.0)
+ */
+ if (si_size >= ERL_DRV_SYS_INFO_SIZE(nif_minor_version)) {
+ sip->nif_major_version = ERL_NIF_MAJOR_VERSION;
+ sip->nif_minor_version = ERL_NIF_MINOR_VERSION;
+ }
}
diff --git a/erts/emulator/beam/module.c b/erts/emulator/beam/module.c
index 57a43c89f4..91e4ccce70 100644
--- a/erts/emulator/beam/module.c
+++ b/erts/emulator/beam/module.c
@@ -1,19 +1,19 @@
/*
* %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
* 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%
*/
@@ -66,12 +66,8 @@ static Module* module_alloc(Module* tmpl)
obj->code_length = 0;
obj->old_code_length = 0;
obj->slot.index = -1;
- obj->nif.handle = NULL;
- obj->old_nif.handle = NULL;
- obj->nif.entry = NULL;
- obj->old_nif.entry = NULL;
- obj->nif.data = NULL;
- obj->old_nif.data = NULL;
+ obj->nif = NULL;
+ obj->old_nif = NULL;
return obj;
}
diff --git a/erts/emulator/beam/module.h b/erts/emulator/beam/module.h
index 314be8e2ee..87d13b3607 100644
--- a/erts/emulator/beam/module.h
+++ b/erts/emulator/beam/module.h
@@ -1,19 +1,19 @@
/*
* %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
* 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%
*/
@@ -24,11 +24,6 @@
#include "index.h"
#endif
-struct erl_module_nif {
- void* handle;
- struct enif_entry_t* entry;
- void* data;
-};
typedef struct erl_module {
IndexSlot slot; /* Must be located at top of struct! */
@@ -39,8 +34,8 @@ typedef struct erl_module {
int code_length; /* Length of loaded code in bytes. */
int old_code_length; /* Length of old loaded code in bytes */
unsigned catches, old_catches;
- struct erl_module_nif nif;
- struct erl_module_nif old_nif;
+ struct erl_module_nif* nif;
+ struct erl_module_nif* old_nif;
} Module;
Module* erts_get_module(Eterm mod);
diff --git a/erts/emulator/beam/register.c b/erts/emulator/beam/register.c
index 7ba097382a..964c10a380 100644
--- a/erts/emulator/beam/register.c
+++ b/erts/emulator/beam/register.c
@@ -1,19 +1,19 @@
/*
* %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
* 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%
*/
@@ -500,8 +500,8 @@ int erts_unregister_name(Process *c_p,
if ((rp = (RegProc*) hash_get(&process_reg, (void*) &r)) != NULL) {
if (rp->pt) {
-#ifdef ERTS_SMP
if (port != rp->pt) {
+#ifdef ERTS_SMP
if (port) {
ERTS_SMP_LC_ASSERT(port != c_prt);
erts_smp_port_unlock(port);
@@ -519,10 +519,13 @@ int erts_unregister_name(Process *c_p,
port = erts_id2port(id, NULL, 0);
goto restart;
}
+#endif
port = rp->pt;
}
-#endif
- ERTS_SMP_LC_ASSERT(rp->pt == port && erts_lc_is_port_locked(port));
+
+ ASSERT(rp->pt == port);
+ ERTS_SMP_LC_ASSERT(erts_lc_is_port_locked(port));
+
rp->pt->reg = NULL;
if (IS_TRACED_FL(port, F_TRACE_PORTS)) {
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/beam/utils.c b/erts/emulator/beam/utils.c
index be442fa480..31efddc0f2 100644
--- a/erts/emulator/beam/utils.c
+++ b/erts/emulator/beam/utils.c
@@ -1,19 +1,19 @@
/*
* %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
* 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%
*/
@@ -95,6 +95,7 @@ dispatch_profile_msg_q(profile_sched_msg_q *psmq)
#endif
+
Eterm*
erts_heap_alloc(Process* p, Uint need)
{
@@ -105,28 +106,46 @@ erts_heap_alloc(Process* p, Uint need)
Uint i;
#endif
+#ifdef FORCE_HEAP_FRAGS
+ if (p->space_verified && p->space_verified_from!=NULL
+ && HEAP_TOP(p) >= p->space_verified_from
+ && HEAP_TOP(p) + need <= p->space_verified_from + p->space_verified
+ && HEAP_LIMIT(p) - HEAP_TOP(p) >= need) {
+
+ Uint consumed = need + (HEAP_TOP(p) - p->space_verified_from);
+ ASSERT(consumed <= p->space_verified);
+ p->space_verified -= consumed;
+ p->space_verified_from += consumed;
+ HEAP_TOP(p) = p->space_verified_from;
+ return HEAP_TOP(p) - need;
+ }
+ p->space_verified = 0;
+ p->space_verified_from = NULL;
+#endif /* FORCE_HEAP_FRAGS */
+
n = need;
+ bp = MBUF(p);
+ if (bp != NULL && need <= (bp->size - bp->used_size)) {
+ Eterm* ret = bp->mem + bp->used_size;
+ bp->used_size += need;
+ return ret;
+ }
#ifdef DEBUG
n++;
#endif
bp = (ErlHeapFragment*)
- ERTS_HEAP_ALLOC(ERTS_ALC_T_HEAP_FRAG,
- sizeof(ErlHeapFragment) + ((n-1)*sizeof(Eterm)));
+ ERTS_HEAP_ALLOC(ERTS_ALC_T_HEAP_FRAG, ERTS_HEAP_FRAG_SIZE(n));
-#ifdef DEBUG
- n--;
-#endif
-
-#if defined(DEBUG)
- for (i = 0; i <= n; i++) {
- bp->mem[i] = ERTS_HOLE_MARKER;
- }
-#elif defined(CHECK_FOR_HOLES)
+#if defined(DEBUG) || defined(CHECK_FOR_HOLES)
for (i = 0; i < n; i++) {
bp->mem[i] = ERTS_HOLE_MARKER;
}
#endif
+#ifdef DEBUG
+ n--;
+#endif
+
/*
* When we have created a heap fragment, we are no longer allowed
* to store anything more on the heap.
@@ -140,6 +159,7 @@ erts_heap_alloc(Process* p, Uint need)
bp->next = MBUF(p);
MBUF(p) = bp;
bp->size = n;
+ bp->used_size = n;
MBUF_SIZE(p) += n;
bp->off_heap.mso = NULL;
#ifndef HYBRID /* FIND ME! */
@@ -151,34 +171,6 @@ erts_heap_alloc(Process* p, Uint need)
return bp->mem;
}
-void erts_arith_shrink(Process* p, Eterm* hp)
-{
-#if defined(CHECK_FOR_HOLES)
- ErlHeapFragment* hf;
-
- /*
- * We must find the heap fragment that hp points into.
- * If we are unlucky, we might have to search through
- * a large part of the list. We'll hope that will not
- * happen too often.
- */
- for (hf = MBUF(p); hf != 0; hf = hf->next) {
- if (hp - hf->mem < (unsigned long)hf->size) {
- /*
- * We are not allowed to changed hf->size (because the
- * size must be correct when deallocating). Therefore,
- * clear out the uninitialized part of the heap fragment.
- */
- Eterm* to = hf->mem + hf->size;
- while (hp < to) {
- *hp++ = NIL;
- }
- break;
- }
- }
-#endif
-}
-
#ifdef CHECK_FOR_HOLES
Eterm*
erts_set_hole_marker(Eterm* ptr, Uint sz)
@@ -3992,6 +3984,14 @@ erts_write_env(char *key, char *value)
return res;
}
+/*
+ * To be used to silence unused result warnings, but do not abuse it.
+ */
+void erts_silence_warn_unused_result(long unused)
+{
+
+}
+
#ifdef DEBUG
/*
* Handy functions when using a debugger - don't use in the code!
diff --git a/erts/emulator/drivers/common/inet_drv.c b/erts/emulator/drivers/common/inet_drv.c
index b7b577da5b..2bff5bd4f7 100644
--- a/erts/emulator/drivers/common/inet_drv.c
+++ b/erts/emulator/drivers/common/inet_drv.c
@@ -1,7 +1,7 @@
/*
* %CopyrightBegin%
*
- * Copyright Ericsson AB 1997-2009. All Rights Reserved.
+ * Copyright Ericsson AB 1997-2011. All Rights Reserved.
*
* The contents of this file are subject to the Erlang Public License,
* Version 1.1, (the "License"); you may not use this file except in
@@ -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
@@ -5941,7 +5941,7 @@ static int sctp_fill_opts(inet_descriptor* desc, char* buf, int buflen,
struct linger lg;
unsigned int sz = sizeof(lg);
- if (sock_getopt(desc->s, IPPROTO_SCTP, SO_LINGER,
+ if (sock_getopt(desc->s, SOL_SOCKET, SO_LINGER,
&lg, &sz) < 0) continue;
/* Fill in the response: */
PLACE_FOR(spec, i,
@@ -5977,7 +5977,7 @@ static int sctp_fill_opts(inet_descriptor* desc, char* buf, int buflen,
{
case INET_OPT_RCVBUF :
{
- proto = IPPROTO_SCTP;
+ proto = SOL_SOCKET;
type = SO_RCVBUF;
is_int = 1;
tag = am_recbuf;
@@ -5985,7 +5985,7 @@ static int sctp_fill_opts(inet_descriptor* desc, char* buf, int buflen,
}
case INET_OPT_SNDBUF :
{
- proto = IPPROTO_SCTP;
+ proto = SOL_SOCKET;
type = SO_SNDBUF;
is_int = 1;
tag = am_sndbuf;
@@ -6425,8 +6425,7 @@ static int sctp_fill_opts(inet_descriptor* desc, char* buf, int buflen,
i = LOAD_TUPLE(spec, i, 3);
/* Now, convert "spec" into the returnable term: */
- /* desc->caller = 0; What does it mean? */
- driver_output_term(desc->port, spec, i);
+ driver_send_term(desc->port, driver_caller(desc->port), spec, i);
FREE(spec);
(*dest)[0] = INET_REP_SCTP;
diff --git a/erts/emulator/drivers/common/ram_file_drv.c b/erts/emulator/drivers/common/ram_file_drv.c
index 2e3aeb981e..4a39a156e6 100644
--- a/erts/emulator/drivers/common/ram_file_drv.c
+++ b/erts/emulator/drivers/common/ram_file_drv.c
@@ -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%
*/
/*
@@ -388,7 +388,7 @@ static int ram_file_uuencode(RamFile *f)
{
int code_len = UULINE(UNIX_LINE);
int len = f->end;
- int usize = (len*4+2)/3 + 2*(len/code_len+1) + 2 + 1;
+ int usize = 4*((len+2)/3) + 2*((len+code_len-1)/code_len) + 2;
ErlDrvBinary* bin;
uchar* inp;
uchar* outp;
@@ -433,7 +433,7 @@ static int ram_file_uuencode(RamFile *f)
*outp++ = ' '; /* this end of file 0 length !!! */
*outp++ = '\n';
count += 2;
-
+ ASSERT(count == usize);
driver_free_binary(f->bin);
ram_file_set(f, bin, usize, count);
return numeric_reply(f, count);
diff --git a/erts/emulator/drivers/unix/ttsl_drv.c b/erts/emulator/drivers/unix/ttsl_drv.c
index 4c2514669b..4cd54c073f 100644
--- a/erts/emulator/drivers/unix/ttsl_drv.c
+++ b/erts/emulator/drivers/unix/ttsl_drv.c
@@ -1,19 +1,19 @@
/*
* %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
* 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%
*/
/*
@@ -142,7 +142,9 @@ static int tty_init(int,int,int,int);
static int tty_set(int);
static int tty_reset(int);
static int ttysl_control(ErlDrvData, unsigned int, char *, int, char **, int);
+#ifdef ERTS_NOT_USED
static RETSIGTYPE suspend(int);
+#endif
static RETSIGTYPE cont(int);
static RETSIGTYPE winch(int);
@@ -1265,6 +1267,9 @@ static int tty_reset(int fd) /* of terminal device */
* to the orignal settings
*/
+#ifdef ERTS_NOT_USED
+/* XXX: A mistake that it isn't used, or should it be removed? */
+
static RETSIGTYPE suspend(int sig)
{
if (tty_reset(ttysl_fd) < 0) {
@@ -1284,6 +1289,8 @@ static RETSIGTYPE suspend(int sig)
}
}
+#endif
+
static RETSIGTYPE cont(int sig)
{
if (tty_set(ttysl_fd) < 0) {
diff --git a/erts/emulator/hipe/hipe_amd64_asm.m4 b/erts/emulator/hipe/hipe_amd64_asm.m4
index 9ce9b4fc5b..7f563c35d8 100644
--- a/erts/emulator/hipe/hipe_amd64_asm.m4
+++ b/erts/emulator/hipe/hipe_amd64_asm.m4
@@ -1,20 +1,20 @@
changecom(`/*', `*/')dnl
/*
* %CopyrightBegin%
- *
- * Copyright Ericsson AB 2004-2009. All Rights Reserved.
- *
+ *
+ * Copyright Ericsson AB 2004-2010. All Rights Reserved.
+ *
* The contents of this file are subject to the Erlang Public License,
* Version 1.1, (the "License"); you may not use this file except in
* compliance with the License. You should have received a copy of the
* Erlang Public License along with this software. If not, it can be
* retrieved online at http://www.erlang.org/.
- *
+ *
* Software distributed under the License is distributed on an "AS IS"
* basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
* the License for the specific language governing rights and limitations
* under the License.
- *
+ *
* %CopyrightEnd%
*/
/*
@@ -37,6 +37,29 @@ define(SIMULATE_NSP,0)dnl change to 1 to simulate call/ret insns
`#define LEAF_WORDS 'LEAF_WORDS
/*
+ * Workarounds for Darwin.
+ */
+ifelse(OPSYS,darwin,``
+/* Darwin */
+#define TEXT .text
+#define JOIN(X,Y) X##Y
+#define CSYM(NAME) JOIN(_,NAME)
+#define ASYM(NAME) CSYM(NAME)
+#define GLOBAL(NAME) .globl NAME
+#define SET_SIZE(NAME) /*empty*/
+#define TYPE_FUNCTION(NAME) /*empty*/
+'',``
+/* Not Darwin */
+#define TEXT .section ".text"
+#define CSYM(NAME) NAME
+#define ASYM(NAME) NAME
+#define GLOBAL(NAME) .global NAME
+#define SET_SIZE(NAME) .size NAME,.-NAME
+#define TYPE_FUNCTION(NAME) .type NAME,@function
+'')dnl
+
+
+/*
* Reserved registers.
*/
`#define P %rbp'
diff --git a/erts/emulator/hipe/hipe_amd64_bifs.m4 b/erts/emulator/hipe/hipe_amd64_bifs.m4
index 66fd167f47..f7c9604e2b 100644
--- a/erts/emulator/hipe/hipe_amd64_bifs.m4
+++ b/erts/emulator/hipe/hipe_amd64_bifs.m4
@@ -1,20 +1,20 @@
changecom(`/*', `*/')dnl
/*
* %CopyrightBegin%
- *
- * Copyright Ericsson AB 2004-2009. All Rights Reserved.
- *
+ *
+ * Copyright Ericsson AB 2004-2010. All Rights Reserved.
+ *
* The contents of this file are subject to the Erlang Public License,
* Version 1.1, (the "License"); you may not use this file except in
* compliance with the License. You should have received a copy of the
* Erlang Public License along with this software. If not, it can be
* retrieved online at http://www.erlang.org/.
- *
+ *
* Software distributed under the License is distributed on an "AS IS"
* basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
* the License for the specific language governing rights and limitations
* under the License.
- *
+ *
* %CopyrightEnd%
*/
/*
@@ -46,17 +46,17 @@ define(standard_bif_interface_1,
`
#ifndef HAVE_$1
#`define' HAVE_$1
- .section ".text"
+ TEXT
.align 4
- .global $1
-$1:
+ GLOBAL(ASYM($1))
+ASYM($1):
/* set up the parameters */
movq P, %rdi
NBIF_ARG(%rsi,1,0)
/* make the call on the C stack */
SWITCH_ERLANG_TO_C
- call $2
+ call CSYM($2)
TEST_GOT_MBUF
SWITCH_C_TO_ERLANG
@@ -65,18 +65,18 @@ $1:
jz nbif_1_simple_exception
NBIF_RET(1)
HANDLE_GOT_MBUF(1)
- .size $1,.-$1
- .type $1,@function
+ SET_SIZE(ASYM($1))
+ TYPE_FUNCTION(ASYM($1))
#endif')
define(standard_bif_interface_2,
`
#ifndef HAVE_$1
#`define' HAVE_$1
- .section ".text"
+ TEXT
.align 4
- .global $1
-$1:
+ GLOBAL(ASYM($1))
+ASYM($1):
/* set up the parameters */
movq P, %rdi
NBIF_ARG(%rsi,2,0)
@@ -84,7 +84,7 @@ $1:
/* make the call on the C stack */
SWITCH_ERLANG_TO_C
- call $2
+ call CSYM($2)
TEST_GOT_MBUF
SWITCH_C_TO_ERLANG
@@ -93,18 +93,18 @@ $1:
jz nbif_2_simple_exception
NBIF_RET(2)
HANDLE_GOT_MBUF(2)
- .size $1,.-$1
- .type $1,@function
+ SET_SIZE(ASYM($1))
+ TYPE_FUNCTION(ASYM($1))
#endif')
define(standard_bif_interface_3,
`
#ifndef HAVE_$1
#`define' HAVE_$1
- .section ".text"
+ TEXT
.align 4
- .global $1
-$1:
+ GLOBAL(ASYM($1))
+ASYM($1):
/* set up the parameters */
movq P, %rdi
NBIF_ARG(%rsi,3,0)
@@ -113,7 +113,7 @@ $1:
/* make the call on the C stack */
SWITCH_ERLANG_TO_C
- call $2
+ call CSYM($2)
TEST_GOT_MBUF
SWITCH_C_TO_ERLANG
@@ -122,8 +122,8 @@ $1:
jz nbif_3_simple_exception
NBIF_RET(3)
HANDLE_GOT_MBUF(3)
- .size $1,.-$1
- .type $1,@function
+ SET_SIZE(ASYM($1))
+ TYPE_FUNCTION(ASYM($1))
#endif')
/*
@@ -136,16 +136,16 @@ define(fail_bif_interface_0,
`
#ifndef HAVE_$1
#`define' HAVE_$1
- .section ".text"
+ TEXT
.align 4
- .global $1
-$1:
+ GLOBAL(ASYM($1))
+ASYM($1):
/* set up the parameters */
movq P, %rdi
/* make the call on the C stack */
SWITCH_ERLANG_TO_C
- call $2
+ call CSYM($2)
TEST_GOT_MBUF
SWITCH_C_TO_ERLANG
@@ -154,8 +154,8 @@ $1:
jz nbif_0_simple_exception
NBIF_RET(0)
HANDLE_GOT_MBUF(0)
- .size $1,.-$1
- .type $1,@function
+ SET_SIZE(ASYM($1))
+ TYPE_FUNCTION(ASYM($1))
#endif')
/*
@@ -172,59 +172,59 @@ define(nofail_primop_interface_0,
`
#ifndef HAVE_$1
#`define' HAVE_$1
- .section ".text"
+ TEXT
.align 4
- .global $1
-$1:
+ GLOBAL(ASYM($1))
+ASYM($1):
/* set up the parameters */
movq P, %rdi
/* make the call on the C stack */
SWITCH_ERLANG_TO_C
- call $2
+ call CSYM($2)
TEST_GOT_MBUF
SWITCH_C_TO_ERLANG
/* return */
NBIF_RET(0)
HANDLE_GOT_MBUF(0)
- .size $1,.-$1
- .type $1,@function
+ SET_SIZE(ASYM($1))
+ TYPE_FUNCTION(ASYM($1))
#endif')
define(nofail_primop_interface_1,
`
#ifndef HAVE_$1
#`define' HAVE_$1
- .section ".text"
+ TEXT
.align 4
- .global $1
-$1:
+ GLOBAL(ASYM($1))
+ASYM($1):
/* set up the parameters */
movq P, %rdi
NBIF_ARG(%rsi,1,0)
/* make the call on the C stack */
SWITCH_ERLANG_TO_C
- call $2
+ call CSYM($2)
TEST_GOT_MBUF
SWITCH_C_TO_ERLANG
/* return */
NBIF_RET(1)
HANDLE_GOT_MBUF(1)
- .size $1,.-$1
- .type $1,@function
+ SET_SIZE(ASYM($1))
+ TYPE_FUNCTION(ASYM($1))
#endif')
define(nofail_primop_interface_2,
`
#ifndef HAVE_$1
#`define' HAVE_$1
- .section ".text"
+ TEXT
.align 4
- .global $1
-$1:
+ GLOBAL(ASYM($1))
+ASYM($1):
/* set up the parameters */
movq P, %rdi
NBIF_ARG(%rsi,2,0)
@@ -232,25 +232,25 @@ $1:
/* make the call on the C stack */
SWITCH_ERLANG_TO_C
- call $2
+ call CSYM($2)
TEST_GOT_MBUF
SWITCH_C_TO_ERLANG
/* return */
NBIF_RET(2)
HANDLE_GOT_MBUF(2)
- .size $1,.-$1
- .type $1,@function
+ SET_SIZE(ASYM($1))
+ TYPE_FUNCTION(ASYM($1))
#endif')
define(nofail_primop_interface_3,
`
#ifndef HAVE_$1
#`define' HAVE_$1
- .section ".text"
+ TEXT
.align 4
- .global $1
-$1:
+ GLOBAL(ASYM($1))
+ASYM($1):
/* set up the parameters */
movq P, %rdi
NBIF_ARG(%rsi,3,0)
@@ -259,15 +259,15 @@ $1:
/* make the call on the C stack */
SWITCH_ERLANG_TO_C
- call $2
+ call CSYM($2)
TEST_GOT_MBUF
SWITCH_C_TO_ERLANG
/* return */
NBIF_RET(3)
HANDLE_GOT_MBUF(3)
- .size $1,.-$1
- .type $1,@function
+ SET_SIZE(ASYM($1))
+ TYPE_FUNCTION(ASYM($1))
#endif')
/*
@@ -285,55 +285,55 @@ define(nocons_nofail_primop_interface_0,
`
#ifndef HAVE_$1
#`define' HAVE_$1
- .section ".text"
+ TEXT
.align 4
- .global $1
-$1:
+ GLOBAL(ASYM($1))
+ASYM($1):
/* set up the parameters */
movq P, %rdi
/* make the call on the C stack */
SWITCH_ERLANG_TO_C_QUICK
- call $2
+ call CSYM($2)
SWITCH_C_TO_ERLANG_QUICK
/* return */
NBIF_RET(0)
- .size $1,.-$1
- .type $1,@function
+ SET_SIZE(ASYM($1))
+ TYPE_FUNCTION(ASYM($1))
#endif')
define(nocons_nofail_primop_interface_1,
`
#ifndef HAVE_$1
#`define' HAVE_$1
- .section ".text"
+ TEXT
.align 4
- .global $1
-$1:
+ GLOBAL(ASYM($1))
+ASYM($1):
/* set up the parameters */
movq P, %rdi
NBIF_ARG(%rsi,1,0)
/* make the call on the C stack */
SWITCH_ERLANG_TO_C_QUICK
- call $2
+ call CSYM($2)
SWITCH_C_TO_ERLANG_QUICK
/* return */
NBIF_RET(1)
- .size $1,.-$1
- .type $1,@function
+ SET_SIZE(ASYM($1))
+ TYPE_FUNCTION(ASYM($1))
#endif')
define(nocons_nofail_primop_interface_2,
`
#ifndef HAVE_$1
#`define' HAVE_$1
- .section ".text"
+ TEXT
.align 4
- .global $1
-$1:
+ GLOBAL(ASYM($1))
+ASYM($1):
/* set up the parameters */
movq P, %rdi
NBIF_ARG(%rsi,2,0)
@@ -341,23 +341,23 @@ $1:
/* make the call on the C stack */
SWITCH_ERLANG_TO_C_QUICK
- call $2
+ call CSYM($2)
SWITCH_C_TO_ERLANG_QUICK
/* return */
NBIF_RET(2)
- .size $1,.-$1
- .type $1,@function
+ SET_SIZE(ASYM($1))
+ TYPE_FUNCTION(ASYM($1))
#endif')
define(nocons_nofail_primop_interface_3,
`
#ifndef HAVE_$1
#`define' HAVE_$1
- .section ".text"
+ TEXT
.align 4
- .global $1
-$1:
+ GLOBAL(ASYM($1))
+ASYM($1):
/* set up the parameters */
movq P, %rdi
NBIF_ARG(%rsi,3,0)
@@ -366,23 +366,23 @@ $1:
/* make the call on the C stack */
SWITCH_ERLANG_TO_C_QUICK
- call $2
+ call CSYM($2)
SWITCH_C_TO_ERLANG_QUICK
/* return */
NBIF_RET(3)
- .size $1,.-$1
- .type $1,@function
+ SET_SIZE(ASYM($1))
+ TYPE_FUNCTION(ASYM($1))
#endif')
define(nocons_nofail_primop_interface_5,
`
#ifndef HAVE_$1
#`define' HAVE_$1
- .section ".text"
+ TEXT
.align 4
- .global $1
-$1:
+ GLOBAL(ASYM($1))
+ASYM($1):
/* set up the parameters */
movq P, %rdi
NBIF_ARG(%rsi,5,0)
@@ -393,13 +393,13 @@ $1:
/* make the call on the C stack */
SWITCH_ERLANG_TO_C_QUICK
- call $2
+ call CSYM($2)
SWITCH_C_TO_ERLANG_QUICK
/* return */
NBIF_RET(5)
- .size $1,.-$1
- .type $1,@function
+ SET_SIZE(ASYM($1))
+ TYPE_FUNCTION(ASYM($1))
#endif')
/*
@@ -417,74 +417,74 @@ define(noproc_primop_interface_0,
`
#ifndef HAVE_$1
#`define' HAVE_$1
- .section ".text"
+ TEXT
.align 4
- .global $1
-$1:
+ GLOBAL(ASYM($1))
+ASYM($1):
/* make the call on the C stack */
SWITCH_ERLANG_TO_C_QUICK
- call $2
+ call CSYM($2)
SWITCH_C_TO_ERLANG_QUICK
/* return */
NBIF_RET(0)
- .size $1,.-$1
- .type $1,@function
+ SET_SIZE(ASYM($1))
+ TYPE_FUNCTION(ASYM($1))
#endif')
define(noproc_primop_interface_1,
`
#ifndef HAVE_$1
#`define' HAVE_$1
- .section ".text"
+ TEXT
.align 4
- .global $1
-$1:
+ GLOBAL(ASYM($1))
+ASYM($1):
/* set up the parameters */
NBIF_ARG(%rdi,1,0)
/* make the call on the C stack */
SWITCH_ERLANG_TO_C_QUICK
- call $2
+ call CSYM($2)
SWITCH_C_TO_ERLANG_QUICK
/* return */
NBIF_RET(1)
- .size $1,.-$1
- .type $1,@function
+ SET_SIZE(ASYM($1))
+ TYPE_FUNCTION(ASYM($1))
#endif')
define(noproc_primop_interface_2,
`
#ifndef HAVE_$1
#`define' HAVE_$1
- .section ".text"
+ TEXT
.align 4
- .global $1
-$1:
+ GLOBAL(ASYM($1))
+ASYM($1):
/* set up the parameters */
NBIF_ARG(%rdi,2,0)
NBIF_ARG(%rsi,2,1)
/* make the call on the C stack */
SWITCH_ERLANG_TO_C_QUICK
- call $2
+ call CSYM($2)
SWITCH_C_TO_ERLANG_QUICK
/* return */
NBIF_RET(2)
- .size $1,.-$1
- .type $1,@function
+ SET_SIZE(ASYM($1))
+ TYPE_FUNCTION(ASYM($1))
#endif')
define(noproc_primop_interface_3,
`
#ifndef HAVE_$1
#`define' HAVE_$1
- .section ".text"
+ TEXT
.align 4
- .global $1
-$1:
+ GLOBAL(ASYM($1))
+ASYM($1):
/* set up the parameters */
NBIF_ARG(%rdi,3,0)
NBIF_ARG(%rsi,3,1)
@@ -492,23 +492,23 @@ $1:
/* make the call on the C stack */
SWITCH_ERLANG_TO_C_QUICK
- call $2
+ call CSYM($2)
SWITCH_C_TO_ERLANG_QUICK
/* return */
NBIF_RET(3)
- .size $1,.-$1
- .type $1,@function
+ SET_SIZE(ASYM($1))
+ TYPE_FUNCTION(ASYM($1))
#endif')
define(noproc_primop_interface_5,
`
#ifndef HAVE_$1
#`define' HAVE_$1
- .section ".text"
+ TEXT
.align 4
- .global $1
-$1:
+ GLOBAL(ASYM($1))
+ASYM($1):
/* set up the parameters */
NBIF_ARG(%rdi,5,0)
NBIF_ARG(%rsi,5,1)
@@ -518,13 +518,13 @@ $1:
/* make the call on the C stack */
SWITCH_ERLANG_TO_C_QUICK
- call $2
+ call CSYM($2)
SWITCH_C_TO_ERLANG_QUICK
/* return */
NBIF_RET(5)
- .size $1,.-$1
- .type $1,@function
+ SET_SIZE(ASYM($1))
+ TYPE_FUNCTION(ASYM($1))
#endif')
/*
diff --git a/erts/emulator/hipe/hipe_amd64_glue.S b/erts/emulator/hipe/hipe_amd64_glue.S
index 872c5dc9e3..83b7b0397b 100644
--- a/erts/emulator/hipe/hipe_amd64_glue.S
+++ b/erts/emulator/hipe/hipe_amd64_glue.S
@@ -1,19 +1,19 @@
/*
* %CopyrightBegin%
- *
- * Copyright Ericsson AB 2004-2009. All Rights Reserved.
- *
+ *
+ * Copyright Ericsson AB 2004-2010. All Rights Reserved.
+ *
* The contents of this file are subject to the Erlang Public License,
* Version 1.1, (the "License"); you may not use this file except in
* compliance with the License. You should have received a copy of the
* Erlang Public License along with this software. If not, it can be
* retrieved online at http://www.erlang.org/.
- *
+ *
* Software distributed under the License is distributed on an "AS IS"
* basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
* the License for the specific language governing rights and limitations
* under the License.
- *
+ *
* %CopyrightEnd%
*/
/*
@@ -56,16 +56,16 @@
/* switch to native stack */ \
SWITCH_C_TO_ERLANG
- .section ".text"
+ TEXT
/*
* int x86_call_to_native(Process *p);
* Emulated code recursively calls native code.
*/
.align 4
- .global x86_call_to_native
- .global nbif_return
-x86_call_to_native:
+ GLOBAL(CSYM(x86_call_to_native))
+ GLOBAL(ASYM(nbif_return))
+CSYM(x86_call_to_native):
ENTER_FROM_C
/* get argument registers */
LOAD_ARG_REGS
@@ -77,7 +77,7 @@ x86_call_to_native:
*
* This is where native code returns to emulated code.
*/
-nbif_return:
+ASYM(nbif_return):
movq %rax, P_ARG0(P) # save retval
movl $HIPE_MODE_SWITCH_RES_RETURN, %eax
/* FALLTHROUGH to .flush_exit
@@ -118,8 +118,8 @@ nbif_return:
* XXX: Different stubs for different number of register parameters?
*/
.align 4
- .global nbif_callemu
-nbif_callemu:
+ GLOBAL(ASYM(nbif_callemu))
+ASYM(nbif_callemu):
STORE_ARG_REGS
movl $HIPE_MODE_SWITCH_RES_CALL, %eax
jmp .suspend_exit
@@ -128,8 +128,8 @@ nbif_callemu:
* nbif_apply
*/
.align 4
- .global nbif_apply
-nbif_apply:
+ GLOBAL(ASYM(nbif_apply))
+ASYM(nbif_apply):
STORE_ARG_REGS
movl $HIPE_MODE_SWITCH_RES_APPLY, %eax
jmp .suspend_exit
@@ -145,8 +145,8 @@ nbif_apply:
*/
#if NR_ARG_REGS >= 6
.align 4
- .global nbif_ccallemu6
-nbif_ccallemu6:
+ GLOBAL(ASYM(nbif_ccallemu6))
+ASYM(nbif_ccallemu6):
movq ARG5, P_ARG5(P)
#if NR_ARG_REGS > 6
movq ARG6, ARG5
@@ -158,8 +158,8 @@ nbif_ccallemu6:
#if NR_ARG_REGS >= 5
.align 4
- .global nbif_ccallemu5
-nbif_ccallemu5:
+ GLOBAL(ASYM(nbif_ccallemu5))
+ASYM(nbif_ccallemu5):
movq ARG4, P_ARG4(P)
#if NR_ARG_REGS > 5
movq ARG5, ARG4
@@ -171,8 +171,8 @@ nbif_ccallemu5:
#if NR_ARG_REGS >= 4
.align 4
- .global nbif_ccallemu4
-nbif_ccallemu4:
+ GLOBAL(ASYM(nbif_ccallemu4))
+ASYM(nbif_ccallemu4):
movq ARG3, P_ARG3(P)
#if NR_ARG_REGS > 4
movq ARG4, ARG3
@@ -184,8 +184,8 @@ nbif_ccallemu4:
#if NR_ARG_REGS >= 3
.align 4
- .global nbif_ccallemu3
-nbif_ccallemu3:
+ GLOBAL(ASYM(nbif_ccallemu3))
+ASYM(nbif_ccallemu3):
movq ARG2, P_ARG2(P)
#if NR_ARG_REGS > 3
movq ARG3, ARG2
@@ -197,8 +197,8 @@ nbif_ccallemu3:
#if NR_ARG_REGS >= 2
.align 4
- .global nbif_ccallemu2
-nbif_ccallemu2:
+ GLOBAL(ASYM(nbif_ccallemu2))
+ASYM(nbif_ccallemu2):
movq ARG1, P_ARG1(P)
#if NR_ARG_REGS > 2
movq ARG2, ARG1
@@ -210,8 +210,8 @@ nbif_ccallemu2:
#if NR_ARG_REGS >= 1
.align 4
- .global nbif_ccallemu1
-nbif_ccallemu1:
+ GLOBAL(ASYM(nbif_ccallemu1))
+ASYM(nbif_ccallemu1):
movq ARG0, P_ARG0(P)
#if NR_ARG_REGS > 1
movq ARG1, ARG0
@@ -222,8 +222,8 @@ nbif_ccallemu1:
#endif
.align 4
- .global nbif_ccallemu0
-nbif_ccallemu0:
+ GLOBAL(ASYM(nbif_ccallemu0))
+ASYM(nbif_ccallemu0):
/* We use %rsi not ARG0 here because ARG0 is not
defined when NR_ARG_REGS == 0. */
#if NR_ARG_REGS == 0
@@ -237,8 +237,8 @@ nbif_ccallemu0:
* This is where native code suspends.
*/
.align 4
- .global nbif_suspend_0
-nbif_suspend_0:
+ GLOBAL(ASYM(nbif_suspend_0))
+ASYM(nbif_suspend_0):
movl $HIPE_MODE_SWITCH_RES_SUSPEND, %eax
jmp .suspend_exit
@@ -246,8 +246,8 @@ nbif_suspend_0:
* Suspend from a receive (waiting for a message)
*/
.align 4
- .global nbif_suspend_msg
-nbif_suspend_msg:
+ GLOBAL(ASYM(nbif_suspend_msg))
+ASYM(nbif_suspend_msg):
movl $HIPE_MODE_SWITCH_RES_WAIT, %eax
jmp .suspend_exit
@@ -257,8 +257,8 @@ nbif_suspend_msg:
* else { return 0; }
*/
.align 4
- .global nbif_suspend_msg_timeout
-nbif_suspend_msg_timeout:
+ GLOBAL(ASYM(nbif_suspend_msg_timeout))
+ASYM(nbif_suspend_msg_timeout):
movq P_FLAGS(P), %rax
/* this relies on F_TIMO (1<<2) fitting in a byte */
testb $F_TIMO, %al # F_TIMO set?
@@ -275,8 +275,8 @@ nbif_suspend_msg_timeout:
* Emulated code returns to its native code caller.
*/
.align 4
- .global x86_return_to_native
-x86_return_to_native:
+ GLOBAL(CSYM(x86_return_to_native))
+CSYM(x86_return_to_native):
ENTER_FROM_C
/* get return value */
movq P_ARG0(P), %rax
@@ -292,8 +292,8 @@ x86_return_to_native:
* Emulated code tailcalls native code.
*/
.align 4
- .global x86_tailcall_to_native
-x86_tailcall_to_native:
+ GLOBAL(CSYM(x86_tailcall_to_native))
+CSYM(x86_tailcall_to_native):
ENTER_FROM_C
/* get argument registers */
LOAD_ARG_REGS
@@ -305,8 +305,8 @@ x86_tailcall_to_native:
* Emulated code throws an exception to its native code caller.
*/
.align 4
- .global x86_throw_to_native
-x86_throw_to_native:
+ GLOBAL(CSYM(x86_throw_to_native))
+CSYM(x86_throw_to_native):
ENTER_FROM_C
/* invoke the handler */
jmp *P_NCALLEE(P) # set by hipe_find_handler()
@@ -315,15 +315,15 @@ x86_throw_to_native:
* This is the default exception handler for native code.
*/
.align 4
- .global nbif_fail
-nbif_fail:
+ GLOBAL(ASYM(nbif_fail))
+ASYM(nbif_fail):
movl $HIPE_MODE_SWITCH_RES_THROW, %eax
jmp .flush_exit
- .global nbif_0_gc_after_bif
- .global nbif_1_gc_after_bif
- .global nbif_2_gc_after_bif
- .global nbif_3_gc_after_bif
+ GLOBAL(nbif_0_gc_after_bif)
+ GLOBAL(nbif_1_gc_after_bif)
+ GLOBAL(nbif_2_gc_after_bif)
+ GLOBAL(nbif_3_gc_after_bif)
.align 4
nbif_0_gc_after_bif:
xorl %edx, %edx
@@ -346,7 +346,7 @@ nbif_3_gc_after_bif:
subq $(16-8), %rsp
movq P, %rdi
movq %rax, %rsi
- call erts_gc_after_bif_call
+ call CSYM(erts_gc_after_bif_call)
addq $(16-8), %rsp
movl $0, P_NARITY(P) # Note: narity is a 32-bit field
ret
@@ -356,10 +356,10 @@ nbif_3_gc_after_bif:
* exceptional condition.
* The stack/heap registers were just read from P.
*/
- .global nbif_0_simple_exception
- .global nbif_1_simple_exception
- .global nbif_2_simple_exception
- .global nbif_3_simple_exception
+ GLOBAL(nbif_0_simple_exception)
+ GLOBAL(nbif_1_simple_exception)
+ GLOBAL(nbif_2_simple_exception)
+ GLOBAL(nbif_3_simple_exception)
.align 4
nbif_0_simple_exception:
xorl %eax, %eax
@@ -389,7 +389,7 @@ nbif_3_simple_exception:
/* find and prepare to invoke the handler */
SWITCH_ERLANG_TO_C_QUICK # The cached state is clean and need not be saved.
movq P, %rdi
- call hipe_handle_exception # Note: hipe_handle_exception() conses
+ call CSYM(hipe_handle_exception) # Note: hipe_handle_exception() conses
SWITCH_C_TO_ERLANG # %rsp updated by hipe_find_handler()
/* now invoke the handler */
jmp *P_NCALLEE(P) # set by hipe_find_handler()
@@ -408,15 +408,15 @@ nbif_3_simple_exception:
* nbif_stack_trap_ra: trap return address for maintaining
* the gray/white stack boundary
*/
- .global nbif_stack_trap_ra
+ GLOBAL(ASYM(nbif_stack_trap_ra))
.align 4
-nbif_stack_trap_ra: # a return address, not a function
+ASYM(nbif_stack_trap_ra): # a return address, not a function
# This only handles a single return value.
# If we have more, we need to save them in the PCB.
movq %rax, TEMP_RV # save retval
SWITCH_ERLANG_TO_C_QUICK
movq P, %rdi
- call hipe_handle_stack_trap # must not cons; preserves TEMP_RV
+ call CSYM(hipe_handle_stack_trap) # must not cons; preserves TEMP_RV
movq %rax, %rdx # original RA
SWITCH_C_TO_ERLANG_QUICK
movq TEMP_RV, %rax # restore retval
@@ -425,15 +425,15 @@ nbif_stack_trap_ra: # a return address, not a function
/*
* nbif_inc_stack_0
*/
- .global nbif_inc_stack_0
+ GLOBAL(ASYM(nbif_inc_stack_0))
.align 4
-nbif_inc_stack_0:
+ASYM(nbif_inc_stack_0):
SWITCH_ERLANG_TO_C_QUICK
STORE_ARG_REGS
movq P, %rdi
# hipe_inc_nstack reads and writes NSP and NSP_LIMIT,
# but does not access HP or FCALLS (or the non-amd64 NRA).
- call hipe_inc_nstack
+ call CSYM(hipe_inc_nstack)
LOAD_ARG_REGS
SWITCH_C_TO_ERLANG_QUICK
NSP_RET0
diff --git a/erts/emulator/hipe/hipe_bif0.c b/erts/emulator/hipe/hipe_bif0.c
index 032bf2e896..b0abfd2310 100644
--- a/erts/emulator/hipe/hipe_bif0.c
+++ b/erts/emulator/hipe/hipe_bif0.c
@@ -1,22 +1,22 @@
/*
* %CopyrightBegin%
- *
- * Copyright Ericsson AB 2001-2009. All Rights Reserved.
- *
+ *
+ * Copyright Ericsson AB 2001-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%
*/
-/* $Id$
+/*
* hipe_bif0.c
*
* Compiler and linker support.
@@ -656,6 +656,7 @@ static void *hipe_get_emu_address(Eterm m, Eterm f, unsigned int arity, int is_r
address = hipe_find_emu_address(m, f, arity);
if (!address) {
/* if not found, stub it via the export entry */
+ /* no lock needed around erts_export_get_or_make_stub() */
Export *export_entry = erts_export_get_or_make_stub(m, f, arity);
address = export_entry->address;
}
@@ -1188,8 +1189,31 @@ static struct {
unsigned int mask; /* INV: mask == (1 << log2size)-1 */
unsigned int used;
struct hipe_mfa_info **bucket;
+ /*
+ * The mfa info table is normally updated by the loader,
+ * which runs in non-concurrent mode. Unfortunately runtime
+ * apply operations (get_na_nofail) update the table if
+ * they create a new stub for the mfa, which forces locking.
+ * XXX: Redesign apply et al to avoid those updates.
+ */
+ erts_smp_mtx_t lock;
} hipe_mfa_info_table;
+static inline void hipe_mfa_info_table_init_lock(void)
+{
+ erts_smp_mtx_init(&hipe_mfa_info_table.lock, "hipe_mfait_lock");
+}
+
+static inline void hipe_mfa_info_table_lock(void)
+{
+ erts_smp_mtx_lock(&hipe_mfa_info_table.lock);
+}
+
+static inline void hipe_mfa_info_table_unlock(void)
+{
+ erts_smp_mtx_unlock(&hipe_mfa_info_table.lock);
+}
+
#define HIPE_MFA_HASH(M,F,A) ((M) * (F) + (A))
static struct hipe_mfa_info **hipe_mfa_info_table_alloc_bucket(unsigned int size)
@@ -1258,9 +1282,11 @@ void hipe_mfa_info_table_init(void)
hipe_mfa_info_table.mask = size - 1;
hipe_mfa_info_table.used = 0;
hipe_mfa_info_table.bucket = hipe_mfa_info_table_alloc_bucket(size);
+
+ hipe_mfa_info_table_init_lock();
}
-static inline struct hipe_mfa_info *hipe_mfa_info_table_get(Eterm m, Eterm f, unsigned int arity)
+static inline struct hipe_mfa_info *hipe_mfa_info_table_get_locked(Eterm m, Eterm f, unsigned int arity)
{
unsigned long h;
unsigned int i;
@@ -1286,7 +1312,7 @@ void *hipe_mfa_find_na(Eterm m, Eterm f, unsigned int arity)
}
#endif
-static struct hipe_mfa_info *hipe_mfa_info_table_put(Eterm m, Eterm f, unsigned int arity)
+static struct hipe_mfa_info *hipe_mfa_info_table_put_locked(Eterm m, Eterm f, unsigned int arity)
{
unsigned long h;
unsigned int i;
@@ -1313,7 +1339,10 @@ static struct hipe_mfa_info *hipe_mfa_info_table_put(Eterm m, Eterm f, unsigned
static void hipe_mfa_set_na(Eterm m, Eterm f, unsigned int arity, void *address, int is_exported)
{
- struct hipe_mfa_info *p = hipe_mfa_info_table_put(m, f, arity);
+ struct hipe_mfa_info *p;
+
+ hipe_mfa_info_table_lock();
+ p = hipe_mfa_info_table_put_locked(m, f, arity);
#ifdef DEBUG_LINKER
printf("%s: ", __FUNCTION__);
print_mfa(m, f, arity);
@@ -1322,19 +1351,30 @@ static void hipe_mfa_set_na(Eterm m, Eterm f, unsigned int arity, void *address,
p->local_address = address;
if (is_exported)
p->remote_address = address;
+ hipe_mfa_info_table_unlock();
}
#if defined(__powerpc__) || defined(__ppc__) || defined(__powerpc64__) || defined(__arm__)
void *hipe_mfa_get_trampoline(Eterm m, Eterm f, unsigned int arity)
{
- struct hipe_mfa_info *p = hipe_mfa_info_table_put(m, f, arity);
- return p->trampoline;
+ struct hipe_mfa_info *p;
+ void *trampoline;
+
+ hipe_mfa_info_table_lock();
+ p = hipe_mfa_info_table_put_locked(m, f, arity);
+ trampoline = p->trampoline;
+ hipe_mfa_info_table_unlock();
+ return trampoline;
}
void hipe_mfa_set_trampoline(Eterm m, Eterm f, unsigned int arity, void *trampoline)
{
- struct hipe_mfa_info *p = hipe_mfa_info_table_put(m, f, arity);
+ struct hipe_mfa_info *p;
+
+ hipe_mfa_info_table_lock();
+ p = hipe_mfa_info_table_put_locked(m, f, arity);
p->trampoline = trampoline;
+ hipe_mfa_info_table_unlock();
}
#endif
@@ -1365,12 +1405,13 @@ BIF_RETTYPE hipe_bifs_invalidate_funinfo_native_addresses_1(BIF_ALIST_1)
struct mfa mfa;
struct hipe_mfa_info *p;
+ hipe_mfa_info_table_lock();
lst = BIF_ARG_1;
while (is_list(lst)) {
if (!term_to_mfa(CAR(list_val(lst)), &mfa))
- BIF_ERROR(BIF_P, BADARG);
+ break;
lst = CDR(list_val(lst));
- p = hipe_mfa_info_table_get(mfa.mod, mfa.fun, mfa.ari);
+ p = hipe_mfa_info_table_get_locked(mfa.mod, mfa.fun, mfa.ari);
if (p) {
p->remote_address = NULL;
p->local_address = NULL;
@@ -1393,6 +1434,7 @@ BIF_RETTYPE hipe_bifs_invalidate_funinfo_native_addresses_1(BIF_ALIST_1)
}
}
}
+ hipe_mfa_info_table_unlock();
if (is_not_nil(lst))
BIF_ERROR(BIF_P, BADARG);
BIF_RET(NIL);
@@ -1406,7 +1448,8 @@ void hipe_mfa_save_orig_beam_op(Eterm mod, Eterm fun, unsigned int ari, Eterm *p
orig_beam_op = pc[0];
if (orig_beam_op != BeamOpCode(op_hipe_trap_call_closure) &&
orig_beam_op != BeamOpCode(op_hipe_trap_call)) {
- p = hipe_mfa_info_table_put(mod, fun, ari);
+ hipe_mfa_info_table_lock();
+ p = hipe_mfa_info_table_put_locked(mod, fun, ari);
#ifdef DEBUG_LINKER
printf("%s: ", __FUNCTION__);
print_mfa(mod, fun, ari);
@@ -1414,6 +1457,7 @@ void hipe_mfa_save_orig_beam_op(Eterm mod, Eterm fun, unsigned int ari, Eterm *p
#endif
p->beam_code = pc;
p->orig_beam_op = orig_beam_op;
+ hipe_mfa_info_table_unlock();
} else {
#ifdef DEBUG_LINKER
printf("%s: ", __FUNCTION__);
@@ -1440,12 +1484,12 @@ static void *hipe_make_stub(Eterm m, Eterm f, unsigned int arity, int is_remote)
return StubAddress;
}
-static void *hipe_get_na_nofail(Eterm m, Eterm f, unsigned int a, int is_remote)
+static void *hipe_get_na_nofail_locked(Eterm m, Eterm f, unsigned int a, int is_remote)
{
struct hipe_mfa_info *p;
void *address;
- p = hipe_mfa_info_table_get(m, f, a);
+ p = hipe_mfa_info_table_get_locked(m, f, a);
if (p) {
/* find address, predicting for a runtime apply call */
address = p->remote_address;
@@ -1459,13 +1503,23 @@ static void *hipe_get_na_nofail(Eterm m, Eterm f, unsigned int a, int is_remote)
if (address)
return address;
} else
- p = hipe_mfa_info_table_put(m, f, a);
+ p = hipe_mfa_info_table_put_locked(m, f, a);
address = hipe_make_stub(m, f, a, is_remote);
/* XXX: how to tell if a BEAM MFA is exported or not? */
p->remote_address = address;
return address;
}
+static void *hipe_get_na_nofail(Eterm m, Eterm f, unsigned int a, int is_remote)
+{
+ void *p;
+
+ hipe_mfa_info_table_lock();
+ p = hipe_get_na_nofail_locked(m, f, a, is_remote);
+ hipe_mfa_info_table_unlock();
+ return p;
+}
+
/* used for apply/3 in hipe_mode_switch */
void *hipe_get_remote_na(Eterm m, Eterm f, unsigned int a)
{
@@ -1549,6 +1603,8 @@ int hipe_find_mfa_from_ra(const void *ra, Eterm *m, Eterm *f, unsigned int *a)
/* Note about locking: the table is only updated from the
loader, which runs with the rest of the system suspended. */
+ /* XXX: alas not true; see comment at hipe_mfa_info_table.lock */
+ hipe_mfa_info_table_lock();
bucket = hipe_mfa_info_table.bucket;
nrbuckets = 1 << hipe_mfa_info_table.log2size;
mfa = NULL;
@@ -1564,12 +1620,13 @@ int hipe_find_mfa_from_ra(const void *ra, Eterm *m, Eterm *f, unsigned int *a)
b = b->bucket.next;
}
}
- if (!mfa)
- return 0;
- *m = mfa->m;
- *f = mfa->f;
- *a = mfa->a;
- return 1;
+ if (mfa) {
+ *m = mfa->m;
+ *f = mfa->f;
+ *a = mfa->a;
+ }
+ hipe_mfa_info_table_unlock();
+ return mfa ? 1 : 0;
}
/*
@@ -1645,8 +1702,9 @@ BIF_RETTYPE hipe_bifs_add_ref_2(BIF_ALIST_2)
default:
goto badarg;
}
- callee_mfa = hipe_mfa_info_table_put(callee.mod, callee.fun, callee.ari);
- caller_mfa = hipe_mfa_info_table_put(caller.mod, caller.fun, caller.ari);
+ hipe_mfa_info_table_lock();
+ callee_mfa = hipe_mfa_info_table_put_locked(callee.mod, callee.fun, callee.ari);
+ caller_mfa = hipe_mfa_info_table_put_locked(caller.mod, caller.fun, caller.ari);
refers_to = erts_alloc(ERTS_ALC_T_HIPE, sizeof(*refers_to));
refers_to->mfa = callee_mfa;
@@ -1660,6 +1718,7 @@ BIF_RETTYPE hipe_bifs_add_ref_2(BIF_ALIST_2)
ref->flags = flags;
ref->next = callee_mfa->referred_from;
callee_mfa->referred_from = ref;
+ hipe_mfa_info_table_unlock();
BIF_RET(NIL);
@@ -1679,10 +1738,12 @@ BIF_RETTYPE hipe_bifs_mark_referred_from_1(BIF_ALIST_1) /* get_refs_from */
if (!term_to_mfa(BIF_ARG_1, &mfa))
BIF_ERROR(BIF_P, BADARG);
- p = hipe_mfa_info_table_get(mfa.mod, mfa.fun, mfa.ari);
+ hipe_mfa_info_table_lock();
+ p = hipe_mfa_info_table_get_locked(mfa.mod, mfa.fun, mfa.ari);
if (p)
for (ref = p->referred_from; ref != NULL; ref = ref->next)
ref->flags |= REF_FLAG_PENDING_REDIRECT;
+ hipe_mfa_info_table_unlock();
BIF_RET(NIL);
}
@@ -1695,7 +1756,8 @@ BIF_RETTYPE hipe_bifs_remove_refs_from_1(BIF_ALIST_1)
if (!term_to_mfa(BIF_ARG_1, &mfa))
BIF_ERROR(BIF_P, BADARG);
- caller_mfa = hipe_mfa_info_table_get(mfa.mod, mfa.fun, mfa.ari);
+ hipe_mfa_info_table_lock();
+ caller_mfa = hipe_mfa_info_table_get_locked(mfa.mod, mfa.fun, mfa.ari);
if (caller_mfa) {
refers_to = caller_mfa->refers_to;
while (refers_to) {
@@ -1725,6 +1787,7 @@ BIF_RETTYPE hipe_bifs_remove_refs_from_1(BIF_ALIST_1)
}
caller_mfa->refers_to = NULL;
}
+ hipe_mfa_info_table_unlock();
BIF_RET(NIL);
}
@@ -1742,14 +1805,15 @@ BIF_RETTYPE hipe_bifs_redirect_referred_from_1(BIF_ALIST_1)
if (!term_to_mfa(BIF_ARG_1, &mfa))
BIF_ERROR(BIF_P, BADARG);
- p = hipe_mfa_info_table_get(mfa.mod, mfa.fun, mfa.ari);
+ hipe_mfa_info_table_lock();
+ p = hipe_mfa_info_table_get_locked(mfa.mod, mfa.fun, mfa.ari);
if (p) {
prev = &p->referred_from;
ref = *prev;
while (ref) {
if (ref->flags & REF_FLAG_PENDING_REDIRECT) {
is_remote = ref->flags & REF_FLAG_IS_REMOTE;
- new_address = hipe_get_na_nofail(p->m, p->f, p->a, is_remote);
+ new_address = hipe_get_na_nofail_locked(p->m, p->f, p->a, is_remote);
if (ref->flags & REF_FLAG_IS_LOAD_MFA)
res = hipe_patch_insn(ref->address, (Uint)new_address, am_load_mfa);
else
@@ -1772,6 +1836,7 @@ BIF_RETTYPE hipe_bifs_redirect_referred_from_1(BIF_ALIST_1)
}
}
}
+ hipe_mfa_info_table_unlock();
BIF_RET(NIL);
}
diff --git a/erts/emulator/pcre/pcre_compile.c b/erts/emulator/pcre/pcre_compile.c
index 235617fc06..29743362d4 100644
--- a/erts/emulator/pcre/pcre_compile.c
+++ b/erts/emulator/pcre/pcre_compile.c
@@ -4820,10 +4820,8 @@ we set the flag only if there is a literal "\r" or "\n" in the class. */
both phases.
If we are not at the pattern start, compile code to change the ims
- options if this setting actually changes any of them. We also pass the
- new setting back so that it can be put at the start of any following
- branches, and when this group ends (if we are in a group), a resetting
- item can be compiled. */
+ options if this setting actually changes any of them, and reset the
+ greedy defaults and the case value for firstbyte and reqbyte. */
if (*ptr == ')')
{
@@ -4831,7 +4829,6 @@ we set the flag only if there is a literal "\r" or "\n" in the class. */
(lengthptr == NULL || *lengthptr == 2 + 2*LINK_SIZE))
{
cd->external_options = newoptions;
- options = newoptions;
}
else
{
@@ -4840,17 +4837,17 @@ we set the flag only if there is a literal "\r" or "\n" in the class. */
*code++ = OP_OPT;
*code++ = newoptions & PCRE_IMS;
}
-
- /* Change options at this level, and pass them back for use
- in subsequent branches. Reset the greedy defaults and the case
- value for firstbyte and reqbyte. */
-
- *optionsptr = options = newoptions;
greedy_default = ((newoptions & PCRE_UNGREEDY) != 0);
greedy_non_default = greedy_default ^ 1;
- req_caseopt = ((options & PCRE_CASELESS) != 0)? REQ_CASELESS : 0;
+ req_caseopt = ((newoptions & PCRE_CASELESS) != 0)? REQ_CASELESS : 0;
}
+ /* Change options at this level, and pass them back for use
+ in subsequent branches. When not at the start of the pattern, this
+ information is also necessary so that a resetting item can be
+ compiled at the end of a group (if we are in a group). */
+
+ *optionsptr = options = newoptions;
previous = NULL; /* This item can't be repeated */
continue; /* It is complete */
}
diff --git a/erts/emulator/sys/common/erl_mseg.c b/erts/emulator/sys/common/erl_mseg.c
index f4e21bc05f..5dfd66bd7c 100644
--- a/erts/emulator/sys/common/erl_mseg.c
+++ b/erts/emulator/sys/common/erl_mseg.c
@@ -1,19 +1,19 @@
/*
* %CopyrightBegin%
- *
- * Copyright Ericsson AB 2002-2009. All Rights Reserved.
- *
+ *
+ * Copyright Ericsson AB 2002-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%
*/
@@ -287,13 +287,9 @@ check_schedule_cache_check(void)
static void
mseg_shutdown(void)
{
-#ifdef ERTS_SMP
erts_mtx_lock(&mseg_mutex);
-#endif
mseg_clear_cache();
-#ifdef ERTS_SMP
erts_mtx_unlock(&mseg_mutex);
-#endif
}
static ERTS_INLINE void *
@@ -375,8 +371,9 @@ mseg_recreate(void *old_seg, Uint old_size, Uint new_size)
static ERTS_INLINE cache_desc_t *
alloc_cd(void)
-{
+{
cache_desc_t *cd = free_cache_descs;
+ ERTS_LC_ASSERT(erts_lc_mtx_is_locked(&mseg_mutex));
if (cd)
free_cache_descs = cd->next;
return cd;
@@ -385,6 +382,7 @@ alloc_cd(void)
static ERTS_INLINE void
free_cd(cache_desc_t *cd)
{
+ ERTS_LC_ASSERT(erts_lc_mtx_is_locked(&mseg_mutex));
cd->next = free_cache_descs;
free_cache_descs = cd;
}
@@ -393,6 +391,7 @@ free_cd(cache_desc_t *cd)
static ERTS_INLINE void
link_cd(cache_desc_t *cd)
{
+ ERTS_LC_ASSERT(erts_lc_mtx_is_locked(&mseg_mutex));
if (cache)
cache->prev = cd;
cd->next = cache;
@@ -410,6 +409,7 @@ link_cd(cache_desc_t *cd)
static ERTS_INLINE void
end_link_cd(cache_desc_t *cd)
{
+ ERTS_LC_ASSERT(erts_lc_mtx_is_locked(&mseg_mutex));
if (cache_end)
cache_end->next = cd;
cd->next = NULL;
@@ -427,7 +427,7 @@ end_link_cd(cache_desc_t *cd)
static ERTS_INLINE void
unlink_cd(cache_desc_t *cd)
{
-
+ ERTS_LC_ASSERT(erts_lc_mtx_is_locked(&mseg_mutex));
if (cd->next)
cd->next->prev = cd->prev;
else
@@ -445,6 +445,7 @@ static ERTS_INLINE void
check_cache_limits(void)
{
cache_desc_t *cd;
+ ERTS_LC_ASSERT(erts_lc_mtx_is_locked(&mseg_mutex));
max_cached_seg_size = 0;
min_cached_seg_size = ~((Uint) 0);
for (cd = cache; cd; cd = cd->next) {
@@ -463,7 +464,7 @@ adjust_cache_size(int force_check_limits)
int check_limits = force_check_limits;
Sint max_cached = ((Sint) segments.current.watermark
- (Sint) segments.current.no);
-
+ ERTS_LC_ASSERT(erts_lc_mtx_is_locked(&mseg_mutex));
while (((Sint) cache_size) > max_cached && ((Sint) cache_size) > 0) {
ASSERT(cache_end);
cd = cache_end;
@@ -487,9 +488,7 @@ adjust_cache_size(int force_check_limits)
static void
check_cache(void *unused)
{
-#ifdef ERTS_SMP
erts_mtx_lock(&mseg_mutex);
-#endif
is_cache_check_scheduled = 0;
@@ -502,10 +501,7 @@ check_cache(void *unused)
INC_CC(check_cache);
-#ifdef ERTS_SMP
erts_mtx_unlock(&mseg_mutex);
-#endif
-
}
static void
diff --git a/erts/emulator/sys/common/erl_poll.c b/erts/emulator/sys/common/erl_poll.c
index 169d4579a2..5cca33d7eb 100644
--- a/erts/emulator/sys/common/erl_poll.c
+++ b/erts/emulator/sys/common/erl_poll.c
@@ -1,19 +1,19 @@
/*
* %CopyrightBegin%
- *
- * Copyright Ericsson AB 2006-2009. All Rights Reserved.
- *
+ *
+ * Copyright Ericsson AB 2006-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%
*/
@@ -350,6 +350,7 @@ unset_interrupted_chk(ErtsPollSet ps)
#endif
+void erts_silence_warn_unused_result(long unused);
static void fatal_error(char *format, ...);
static void fatal_error_async_signal_safe(char *error_str);
@@ -2554,8 +2555,10 @@ fatal_error_async_signal_safe(char *error_str)
int len = 0;
while (error_str[len])
len++;
- if (len)
- (void) write(2, error_str, len); /* async signal safe */
+ if (len) {
+ /* async signal safe */
+ erts_silence_warn_unused_result(write(2, error_str, len));
+ }
}
abort();
}
diff --git a/erts/emulator/sys/unix/sys.c b/erts/emulator/sys/unix/sys.c
index 183525b222..31ab5d03de 100644
--- a/erts/emulator/sys/unix/sys.c
+++ b/erts/emulator/sys/unix/sys.c
@@ -1,19 +1,19 @@
/*
* %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
* 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%
*/
@@ -709,7 +709,7 @@ prepare_crash_dump(void)
if (nice_val > 39) {
nice_val = 39;
}
- nice(nice_val);
+ erts_silence_warn_unused_result(nice(nice_val));
}
envsz = sizeof(env);
@@ -2332,7 +2332,7 @@ sys_async_ready_failed(int fd, int r, int err)
char buf[120];
sprintf(buf, "sys_async_ready(): Fatal error: fd=%d, r=%d, errno=%d\n",
fd, r, err);
- (void) write(2, buf, strlen(buf));
+ erts_silence_warn_unused_result(write(2, buf, strlen(buf)));
abort();
}
@@ -2891,7 +2891,7 @@ smp_sig_notify(char c)
char msg[] =
"smp_sig_notify(): Failed to notify signal-dispatcher thread "
"about received signal";
- (void) write(2, msg, sizeof(msg));
+ erts_silence_warn_unused_result(write(2, msg, sizeof(msg)));
abort();
}
}
@@ -3121,7 +3121,6 @@ erl_sys_args(int* argc, char** argv)
*argc = j;
}
-
#ifdef ERTS_TIMER_THREAD
/*
diff --git a/erts/emulator/sys/unix/sys_float.c b/erts/emulator/sys/unix/sys_float.c
index 15da6ab45c..c59c99f65e 100644
--- a/erts/emulator/sys/unix/sys_float.c
+++ b/erts/emulator/sys/unix/sys_float.c
@@ -1,19 +1,19 @@
/*
* %CopyrightBegin%
- *
- * Copyright Ericsson AB 2001-2009. All Rights Reserved.
- *
+ *
+ * Copyright Ericsson AB 2001-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%
*/
@@ -93,7 +93,8 @@ void erts_fp_check_init_error(volatile unsigned long *fpexnp)
char buf[64];
snprintf(buf, sizeof buf, "ERTS_FP_CHECK_INIT at %p: detected unhandled FPE at %p\r\n",
__builtin_return_address(0), (void*)*fpexnp);
- write(2, buf, strlen(buf));
+ if (write(2, buf, strlen(buf)) <= 0)
+ erl_exit(ERTS_ABORT_EXIT, "%s", buf);
*fpexnp = 0;
#if defined(__i386__) || defined(__x86_64__)
erts_restore_fpu();
diff --git a/erts/emulator/test/binary_SUITE.erl b/erts/emulator/test/binary_SUITE.erl
index e47dfa18f7..db2b3e10db 100644
--- a/erts/emulator/test/binary_SUITE.erl
+++ b/erts/emulator/test/binary_SUITE.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%
%%
@@ -27,6 +27,7 @@
%% binary_to_list/1
%% binary_to_list/3
%% binary_to_term/1
+%% binary_to_term/2
%% bitstr_to_list/1
%% term_to_binary/1
%% erlang:external_size/1
@@ -49,7 +50,7 @@
t_hash/1,
bad_size/1,
bad_term_to_binary/1,
- bad_binary_to_term_2/1,
+ bad_binary_to_term_2/1,safe_binary_to_term2/1,
bad_binary_to_term/1, bad_terms/1, more_bad_terms/1,
otp_5484/1,otp_5933/1,
ordering/1,unaligned_order/1,gc_test/1,
@@ -66,7 +67,7 @@ all(suite) ->
t_split_binary, bad_split, t_concat_binary,
bad_list_to_binary, bad_binary_to_list, terms, terms_float,
external_size, t_iolist_size,
- bad_binary_to_term_2,
+ bad_binary_to_term_2,safe_binary_to_term2,
bad_binary_to_term, bad_terms, t_hash, bad_size, bad_term_to_binary,
more_bad_terms, otp_5484, otp_5933, ordering, unaligned_order,
gc_test, bit_sized_binary_sizes, bitlevel_roundtrip, otp_6817, otp_8117,
@@ -438,8 +439,11 @@ terms(Config) when is_list(Config) ->
ok
end,
Term = binary_to_term(Bin),
+ Term = erlang:binary_to_term(Bin, [safe]),
Unaligned = make_unaligned_sub_binary(Bin),
Term = binary_to_term(Unaligned),
+ Term = erlang:binary_to_term(Unaligned, []),
+ Term = erlang:binary_to_term(Bin, [safe]),
BinC = erlang:term_to_binary(Term, [compressed]),
Term = binary_to_term(BinC),
true = size(BinC) =< size(Bin),
@@ -538,6 +542,23 @@ bad_binary_to_term(Config) when is_list(Config) ->
bad_bin_to_term(BadBin) ->
{'EXIT',{badarg,_}} = (catch binary_to_term(BadBin)).
+bad_bin_to_term(BadBin,Opts) ->
+ {'EXIT',{badarg,_}} = (catch erlang:binary_to_term(BadBin,Opts)).
+
+safe_binary_to_term2(doc) -> "Test safety options for binary_to_term/2";
+safe_binary_to_term2(Config) when is_list(Config) ->
+ ?line bad_bin_to_term(<<131,100,0,14,"undefined_atom">>, [safe]),
+ ?line bad_bin_to_term(<<131,100,0,14,"other_bad_atom">>, [safe]),
+ BadHostAtom = <<100,0,14,"badguy@badhost">>,
+ Empty = <<0,0,0,0>>,
+ BadRef = <<131,114,0,3,BadHostAtom/binary,0,<<0,0,0,255>>/binary,
+ Empty/binary,Empty/binary>>,
+ ?line bad_bin_to_term(BadRef, [safe]), % good ref, with a bad atom
+ ?line fullsweep_after = erlang:binary_to_term(<<131,100,0,15,"fullsweep_after">>, [safe]), % should be a good atom
+ BadExtFun = <<131,113,100,0,4,98,108,117,101,100,0,4,109,111,111,110,97,3>>,
+ ?line bad_bin_to_term(BadExtFun, [safe]),
+ ok.
+
%% Tests bad input to binary_to_term/1.
bad_terms(suite) -> [];
@@ -559,11 +580,18 @@ corrupter(Term) ->
?line corrupter(CompressedBin, size(CompressedBin)-1).
corrupter(Bin, Pos) when Pos >= 0 ->
- ?line {ShorterBin, _} = split_binary(Bin, Pos),
+ ?line {ShorterBin, Rest} = split_binary(Bin, Pos),
?line catch binary_to_term(ShorterBin), %% emulator shouldn't crash
?line MovedBin = list_to_binary([ShorterBin]),
?line catch binary_to_term(MovedBin), %% emulator shouldn't crash
- ?line corrupter(MovedBin, Pos-1);
+
+ %% Bit faults, shouldn't crash
+ <<Byte,Tail/binary>> = Rest,
+ Fun = fun(M) -> FaultyByte = Byte bxor M,
+ catch binary_to_term(<<ShorterBin/binary,
+ FaultyByte, Tail/binary>>) end,
+ ?line lists:foreach(Fun,[1,2,4,8,16,32,64,128,255]),
+ ?line corrupter(Bin, Pos-1);
corrupter(_Bin, _) ->
ok.
diff --git a/erts/emulator/test/driver_SUITE_data/ioq_exit_drv.c b/erts/emulator/test/driver_SUITE_data/ioq_exit_drv.c
index 2048d06123..c7a42aa687 100644
--- a/erts/emulator/test/driver_SUITE_data/ioq_exit_drv.c
+++ b/erts/emulator/test/driver_SUITE_data/ioq_exit_drv.c
@@ -1,19 +1,20 @@
-/* ``The contents of this file are subject to the Erlang Public License,
+/*
+ * %CopyrightBegin%
+ *
+ * Copyright Ericsson AB 2007-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 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%
*/
/*
@@ -77,6 +78,7 @@ typedef struct {
int ofd;
int outstanding_async_task;
long async_task;
+ ErlDrvPDL pdl;
#ifdef HAVE_POLL_H
struct erl_drv_event_data event_data;
#endif
@@ -144,6 +146,7 @@ start(ErlDrvPort port, char *command)
ddp->ofd = -1;
ddp->outstanding_async_task = 0;
ddp->async_task = -1;
+ ddp->pdl = driver_pdl_create(port);
#ifdef HAVE_POLL_H
ddp->event_data.events = (short) 0;
ddp->event_data.revents = (short) 0;
@@ -217,8 +220,9 @@ static int control(ErlDrvData drv_data,
res_str = "error: command not supported";
goto done;
}
-
+ driver_pdl_lock(ddp->pdl);
driver_enq(ddp->port, "!", 1);
+ driver_pdl_unlock(ddp->pdl);
ddp->test = (IOQExitTest) command;
res_str = "ok";
@@ -333,8 +337,11 @@ static void ready_input(ErlDrvData drv_data, ErlDrvEvent event)
ddp->ifd = -1;
if (ddp->test == IOQ_EXIT_READY_INPUT_ASYNC)
do_driver_async(ddp);
- else
+ else {
+ driver_pdl_lock(ddp->pdl);
driver_deq(ddp->port, 1);
+ driver_pdl_unlock(ddp->pdl);
+ }
}
#endif
}
@@ -352,8 +359,11 @@ static void ready_output(ErlDrvData drv_data, ErlDrvEvent event)
ddp->ofd = -1;
if (ddp->test == IOQ_EXIT_READY_OUTPUT_ASYNC)
do_driver_async(ddp);
- else
+ else {
+ driver_pdl_lock(ddp->pdl);
driver_deq(ddp->port, 1);
+ driver_pdl_unlock(ddp->pdl);
+ }
}
#endif
}
@@ -366,8 +376,11 @@ static void timeout(ErlDrvData drv_data)
if (ddp->test == IOQ_EXIT_TIMEOUT_ASYNC)
do_driver_async(ddp);
- else
+ else {
+ driver_pdl_lock(ddp->pdl);
driver_deq(ddp->port, 1);
+ driver_pdl_unlock(ddp->pdl);
+ }
}
static void ready_async(ErlDrvData drv_data, ErlDrvThreadData thread_data)
@@ -377,7 +390,9 @@ static void ready_async(ErlDrvData drv_data, ErlDrvThreadData thread_data)
PRINTF(("ready_async(%p, %p) called\r\n", drv_data, thread_data));
if (drv_data == (ErlDrvData) thread_data) {
+ driver_pdl_lock(ddp->pdl);
driver_deq(ddp->port, 1);
+ driver_pdl_unlock(ddp->pdl);
ddp->outstanding_async_task = 0;
}
}
@@ -397,8 +412,11 @@ static void event(ErlDrvData drv_data,
ddp->ofd = -1;
if (ddp->test == IOQ_EXIT_EVENT_ASYNC)
do_driver_async(ddp);
- else
+ else {
+ driver_pdl_lock(ddp->pdl);
driver_deq(ddp->port, 1);
+ driver_pdl_unlock(ddp->pdl);
+ }
}
#endif
}
diff --git a/erts/emulator/test/fun_SUITE.erl b/erts/emulator/test/fun_SUITE.erl
index 716ee3707d..a7889dfe90 100644
--- a/erts/emulator/test/fun_SUITE.erl
+++ b/erts/emulator/test/fun_SUITE.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 1999-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 1999-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%
%%
@@ -627,7 +627,13 @@ refc_dist_1() ->
%% Fun is passed in an exit signal. Wait until it is gone.
?line wait_until(fun () -> 4 =/= fun_refc(F2) end),
?line 3 = fun_refc(F2),
- ?line 3 = fun_refc(F),
+ erts_debug:set_internal_state(available_internal_state, true),
+ ?line F_refc = case erts_debug:get_internal_state(force_heap_frags) of
+ false -> 3;
+ true -> 2 % GC after bif already decreased it
+ end,
+ ?line F_refc = fun_refc(F),
+ erts_debug:set_internal_state(available_internal_state, false),
refc_dist_send(Node, F).
refc_dist_send(Node, F) ->
diff --git a/erts/emulator/test/nif_SUITE.erl b/erts/emulator/test/nif_SUITE.erl
index 213ff6637a..522caec8f1 100644
--- a/erts/emulator/test/nif_SUITE.erl
+++ b/erts/emulator/test/nif_SUITE.erl
@@ -1,37 +1,50 @@
%%
%% %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(nif_SUITE).
%%-define(line_trace,true).
+%%-define(CHECK(Exp,Got), ?line check(Exp,Got,?LINE)).
+-define(CHECK(Exp,Got), ?line Exp = Got).
-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, binaries/1, get_string/1, get_atom/1, api_macros/1,
+ from_array/1, iolist_as_binary/1, resource/1, resource_takeover/1,
+ threading/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, binaries, get_string,
+ get_atom, api_macros, from_array, iolist_as_binary, resource,
+ resource_takeover, threading, neg].
+
+%%init_per_testcase(_Case, Config) ->
+%% ?line Dog = ?t:timetrap(?t:seconds(60*60*24)),
+%% [{watchdog, Dog}|Config].
fin_per_testcase(_Func, _Config) ->
+ %%Dog = ?config(watchdog, Config),
+ %%?t:timetrap_cancel(Dog),
P1 = code:purge(nif_mod),
Del = code:delete(nif_mod),
P2 = code:purge(nif_mod),
@@ -50,6 +63,7 @@ basic(Config) when is_list(Config) ->
reload(doc) -> ["Test reload callback in nif lib"];
reload(suite) -> [];
reload(Config) when is_list(Config) ->
+ TmpMem = tmpmem(),
ensure_lib_loaded(Config),
?line Data = ?config(data_dir, Config),
@@ -57,16 +71,16 @@ reload(Config) when is_list(Config) ->
?line {ok,nif_mod,Bin} = compile:file(File, [binary,return_errors]),
?line {module,nif_mod} = erlang:load_module(nif_mod,Bin),
- ?line nif_mod:load_nif_lib(Config, 1),
+ ?line ok = nif_mod:load_nif_lib(Config, 1),
?line hold_nif_mod_priv_data(nif_mod:get_priv_data_ptr()),
?line [{load,1,1,101},{get_priv_data_ptr,1,2,102}] = nif_mod_call_history(),
- ?line nif_mod:load_nif_lib(Config, 2),
+ ?line ok = nif_mod:load_nif_lib(Config, 2),
?line 2 = nif_mod:lib_version(),
?line [{reload,2,1,201},{lib_version,2,2,202}] = nif_mod_call_history(),
- ?line nif_mod:load_nif_lib(Config, 1),
+ ?line ok = nif_mod:load_nif_lib(Config, 1),
?line 1 = nif_mod:lib_version(),
?line [{reload,1,1,101},{lib_version,1,2,102}] = nif_mod_call_history(),
@@ -78,11 +92,13 @@ reload(Config) when is_list(Config) ->
?line [{unload,1,3,103}] = nif_mod_call_history(),
?line [?MODULE, nif_mod] = erlang:system_info(taints),
+ ?line verify_tmpmem(TmpMem),
ok.
upgrade(doc) -> ["Test upgrade callback in nif lib"];
upgrade(suite) -> [];
upgrade(Config) when is_list(Config) ->
+ TmpMem = tmpmem(),
ensure_lib_loaded(Config),
?line Data = ?config(data_dir, Config),
@@ -90,7 +106,7 @@ upgrade(Config) when is_list(Config) ->
?line {ok,nif_mod,Bin} = compile:file(File, [binary,return_errors]),
?line {module,nif_mod} = erlang:load_module(nif_mod,Bin),
- ?line nif_mod:load_nif_lib(Config, 1),
+ ?line ok = nif_mod:load_nif_lib(Config, 1),
?line {Pid,MRef} = nif_mod:start(),
?line 1 = call(Pid,lib_version),
@@ -103,7 +119,7 @@ upgrade(Config) when is_list(Config) ->
?line 1 = call(Pid,lib_version),
?line [{lib_version,1,4,104}] = nif_mod_call_history(),
- ?line nif_mod:load_nif_lib(Config, 1),
+ ?line ok = nif_mod:load_nif_lib(Config, 1),
?line 1 = nif_mod:lib_version(),
?line [{upgrade,1,5,105},{lib_version,1,6,106}] = nif_mod_call_history(),
@@ -130,7 +146,7 @@ upgrade(Config) when is_list(Config) ->
?line {Pid2,MRef2} = nif_mod:start(),
?line undefined = call(Pid2,lib_version),
- ?line nif_mod:load_nif_lib(Config, 1),
+ ?line ok = nif_mod:load_nif_lib(Config, 1),
?line hold_nif_mod_priv_data(nif_mod:get_priv_data_ptr()),
?line 1 = call(Pid2,lib_version),
?line [{load,1,1,101},{get_priv_data_ptr,1,2,102},{lib_version,1,3,103}] = nif_mod_call_history(),
@@ -141,7 +157,7 @@ upgrade(Config) when is_list(Config) ->
?line 1 = call(Pid2,lib_version),
?line [{lib_version,1,4,104}] = nif_mod_call_history(),
- ?line nif_mod:load_nif_lib(Config, 2),
+ ?line ok = nif_mod:load_nif_lib(Config, 2),
?line 2 = nif_mod:lib_version(),
?line [{upgrade,2,1,201},{lib_version,2,2,202}] = nif_mod_call_history(),
@@ -166,14 +182,17 @@ upgrade(Config) when is_list(Config) ->
?line [{unload,2,4,204}] = nif_mod_call_history(),
?line [?MODULE, nif_mod] = erlang:system_info(taints),
+ ?line verify_tmpmem(TmpMem),
ok.
heap_frag(doc) -> ["Test NIF building heap fragments"];
heap_frag(suite) -> [];
heap_frag(Config) when is_list(Config) ->
+ TmpMem = tmpmem(),
ensure_lib_loaded(Config),
heap_frag_do(1,1000000),
+ ?line verify_tmpmem(TmpMem),
ok.
heap_frag_do(N, Max) when N > Max ->
@@ -184,36 +203,614 @@ 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) ->
+ TmpMem = tmpmem(),
+ 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],
+ ?line verify_tmpmem(TmpMem),
+ 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) ->
+ TmpMem = tmpmem(),
+ ?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),
+ ?line verify_tmpmem(TmpMem),
+ ok.
+
+binaries(doc) -> ["Test NIF binary handling."];
+binaries(suite) -> [];
+binaries(Config) when is_list(Config) ->
+ TmpMem = tmpmem(),
+ ?line ensure_lib_loaded(Config, 1),
+ ?line RefcBin = list_to_binary(lists:seq(1,255)),
+ ?line RefcBin = clone_bin(RefcBin),
+ ?line HeapBin = list_to_binary(lists:seq(1,20)),
+ ?line HeapBin = clone_bin(HeapBin),
+ ?line <<_:8,Sub1:6/binary,_/binary>> = RefcBin,
+ ?line <<_:8,Sub2:6/binary,_/binary>> = HeapBin,
+ ?line Sub1 = Sub2,
+ ?line Sub1 = clone_bin(Sub1),
+ ?line Sub2 = clone_bin(Sub2),
+ ?line <<_:9,Sub3:6/binary,_/bitstring>> = RefcBin,
+ ?line <<_:9,Sub4:6/binary,_/bitstring>> = HeapBin,
+ ?line Sub3 = Sub4,
+ ?line Sub3 = clone_bin(Sub3),
+ ?line Sub4 = clone_bin(Sub4),
+ %% When NIFs get bitstring support
+ %%?line <<_:8,Sub5:27/bitstring,_/bitstring>> = RefcBin,
+ %%?line <<_:8,Sub6:27/bitstring,_/bitstring>> = HeapBin,
+ %%?line Sub5 = Sub6,
+ %%?line Sub5 = clone_bin(Sub5),
+ %%?line Sub6 = clone_bin(Sub6),
+ %%?line <<_:9,Sub7:27/bitstring,_/bitstring>> = RefcBin,
+ %%?line <<_:9,Sub8:27/bitstring,_/bitstring>> = HeapBin,
+ %%?line Sub7 = Sub8,
+ %%?line Sub7 = clone_bin(Sub7),
+ %%?line Sub8 = clone_bin(Sub8),
+ %%?line <<>> = clone_bin(<<>>),
+
+ <<_:8,SubBinA:200/binary,_/binary>> = RefcBin,
+ <<_:9,SubBinB:200/binary,_/bitstring>> = RefcBin,
+ <<_:8,SubBinC:17/binary,_/binary>> = HeapBin,
+ <<_:9,SubBinD:17/binary,_/bitstring>> = HeapBin,
+ test_make_sub_bin(RefcBin),
+ test_make_sub_bin(HeapBin),
+ test_make_sub_bin(SubBinA),
+ test_make_sub_bin(SubBinB),
+ test_make_sub_bin(SubBinC),
+ test_make_sub_bin(SubBinD),
+
+ ?line verify_tmpmem(TmpMem),
+ ok.
+
+test_make_sub_bin(Bin) ->
+ Size = byte_size(Bin),
+ Rest10 = Size - 10,
+ Rest1 = Size - 1,
+ ?line Bin = make_sub_bin(Bin, 0, Size),
+ <<_:10/binary,Sub0:Rest10/binary>> = Bin,
+ ?line Sub0 = make_sub_bin(Bin, 10, Rest10),
+ <<Sub1:10/binary,_/binary>> = Bin,
+ ?line Sub1 = make_sub_bin(Bin, 0, 10),
+ <<_:7/binary,Sub2:10/binary,_/binary>> = Bin,
+ ?line Sub2 = make_sub_bin(Bin, 7, 10),
+ ?line <<>> = make_sub_bin(Bin, 0, 0),
+ ?line <<>> = make_sub_bin(Bin, 10, 0),
+ ?line <<>> = make_sub_bin(Bin, Rest1, 0),
+ ?line <<>> = make_sub_bin(Bin, Size, 0),
+ ok.
+
+get_string(doc) -> ["Test enif_get_string"];
+get_string(suite) -> [];
+get_string(Config) when is_list(Config) ->
+ ?line ensure_lib_loaded(Config, 1),
+ ?line {7, <<"hejsan",0,_:3/binary>>} = string_to_bin("hejsan",10),
+ ?line {7, <<"hejsan",0,_>>} = string_to_bin("hejsan",8),
+ ?line {7, <<"hejsan",0>>} = string_to_bin("hejsan",7),
+ ?line {-6, <<"hejsa",0>>} = string_to_bin("hejsan",6),
+ ?line {-5, <<"hejs",0>>} = string_to_bin("hejsan",5),
+ ?line {-1, <<0>>} = string_to_bin("hejsan",1),
+ ?line {0, <<>>} = string_to_bin("hejsan",0),
+ ?line {1, <<0>>} = string_to_bin("",1),
+ ?line {0, <<>>} = string_to_bin("",0),
+ ok.
+
+get_atom(doc) -> ["Test enif_get_atom"];
+get_atom(suite) -> [];
+get_atom(Config) when is_list(Config) ->
+ ?line ensure_lib_loaded(Config, 1),
+ ?line {7, <<"hejsan",0,_:3/binary>>} = atom_to_bin(hejsan,10),
+ ?line {7, <<"hejsan",0,_>>} = atom_to_bin(hejsan,8),
+ ?line {7, <<"hejsan",0>>} = atom_to_bin(hejsan,7),
+ ?line {0, <<_:6/binary>>} = atom_to_bin(hejsan,6),
+ ?line {0, <<>>} = atom_to_bin(hejsan,0),
+ ?line {1, <<0>>} = atom_to_bin('',1),
+ ?line {0, <<>>} = atom_to_bin('',0),
+ ok.
+
+api_macros(doc) -> ["Test macros enif_make_list<N> and enif_make_tuple<N>"];
+api_macros(suite) -> [];
+api_macros(Config) when is_list(Config) ->
+ ?line ensure_lib_loaded(Config, 1),
+ Expected = {[lists:seq(1,N) || N <- lists:seq(1,9)],
+ [list_to_tuple(lists:seq(1,N)) || N <- lists:seq(1,9)]
+ },
+ ?line Expected = macros(list_to_tuple(lists:seq(1,9))),
+ ok.
+
+from_array(doc) -> ["enif_make_[tuple|list]_from_array"];
+from_array(suite) -> [];
+from_array(Config) when is_list(Config) ->
+ ?line ensure_lib_loaded(Config, 1),
+ lists:foreach(fun(Tpl) ->
+ Lst = tuple_to_list(Tpl),
+ ?line {Lst,Tpl} = tuple_2_list_and_tuple(Tpl)
+ end,
+ [{}, {1,2,3}, {[4,5],[],{},{6,7}}, {{}}, {[]}]),
+ ok.
+
+iolist_as_binary(doc) -> ["enif_inspect_iolist_as_binary"];
+iolist_as_binary(suite) -> [];
+iolist_as_binary(Config) when is_list(Config) ->
+ ?line ensure_lib_loaded(Config, 1),
+ TmpMem = tmpmem(),
+ List = [<<"hejsan">>, <<>>, [], [17], [<<>>],
+ [127,128,255,0],
+ [1, 2, 3, <<"abc">>, [<<"def">>,4], 5, <<"ghi">>],
+ [1, 2, 3, <<"abc">>, [<<"def">>,4], 5 | <<"ghi">>]],
+
+ lists:foreach(fun(IoL) ->
+ B1 = erlang:iolist_to_binary(IoL),
+ ?line B2 = iolist_2_bin(IoL),
+ ?line B1 = B2
+ end,
+ List),
+ ?line verify_tmpmem(TmpMem),
+ ok.
+
+resource(doc) -> ["Test memory managed objects, aka 'resources'"];
+resource(suite) -> [];
+resource(Config) when is_list(Config) ->
+ ?line ensure_lib_loaded(Config, 1),
+ ?line Type = get_resource_type(0),
+ resource_hugo(Type),
+ resource_otto(Type),
+ resource_new(Type),
+ resource_neg(Type),
+ ok.
+
+resource_hugo(Type) ->
+ DtorCall = resource_hugo_do(Type),
+ erlang:garbage_collect(),
+ ?line DtorCall = last_resource_dtor_call(),
+ ok.
+
+resource_hugo_do(Type) ->
+ HugoBin = <<"Hugo Hacker">>,
+ ?line HugoPtr = alloc_resource(Type, HugoBin),
+ ?line Hugo = make_resource(HugoPtr),
+ ?line <<>> = Hugo,
+ release_resource(HugoPtr),
+ erlang:garbage_collect(),
+ ?line {HugoPtr,HugoBin} = get_resource(Type,Hugo),
+ Pid = spawn_link(fun() ->
+ receive {Pid, Type, Resource, Ptr, Bin} ->
+ Pid ! {self(), got_it},
+ receive {Pid, check_it} ->
+ ?line {Ptr,Bin} = get_resource(Type,Resource),
+ Pid ! {self(), ok}
+ end
+ end
+ end),
+ Pid ! {self(), Type, Hugo, HugoPtr, HugoBin},
+ ?line {Pid, got_it} = receive_any(),
+ erlang:garbage_collect(), % just to make our ProcBin move in memory
+ Pid ! {self(), check_it},
+ ?line {Pid, ok} = receive_any(),
+ ?line [] = last_resource_dtor_call(),
+ ?line {HugoPtr,HugoBin} = get_resource(Type,Hugo),
+ {HugoPtr, HugoBin, 1}.
+
+resource_otto(Type) ->
+ {OttoPtr, OttoBin} = resource_otto_do(Type),
+ erlang:garbage_collect(),
+ ?line [] = last_resource_dtor_call(),
+ release_resource(OttoPtr),
+ ?line {OttoPtr,OttoBin,1} = last_resource_dtor_call(),
+ ok.
+
+resource_otto_do(Type) ->
+ OttoBin = <<"Otto Ordonnans">>,
+ ?line OttoPtr = alloc_resource(Type, OttoBin),
+ ?line Otto = make_resource(OttoPtr),
+ ?line <<>> = Otto,
+ %% forget resource term but keep referenced by NIF
+ {OttoPtr, OttoBin}.
+
+resource_new(Type) ->
+ ?line {PtrB,BinB} = resource_new_do1(Type),
+ erlang:garbage_collect(),
+ ?line {PtrB,BinB,1} = last_resource_dtor_call(),
+ ok.
+
+resource_new_do1(Type) ->
+ ?line {{PtrA,BinA}, {ResB,PtrB,BinB}} = resource_new_do2(Type),
+ erlang:garbage_collect(),
+ ?line {PtrA,BinA,1} = last_resource_dtor_call(),
+ ?line {PtrB,BinB} = get_resource(Type, ResB),
+ %% forget ResB and make it garbage
+ {PtrB,BinB}.
+
+resource_new_do2(Type) ->
+ BinA = <<"NewA">>,
+ BinB = <<"NewB">>,
+ ?line ResA = make_new_resource(Type, BinA),
+ ?line ResB = make_new_resource(Type, BinB),
+ ?line <<>> = ResA,
+ ?line <<>> = ResB,
+ ?line {PtrA,BinA} = get_resource(Type, ResA),
+ ?line {PtrB,BinB} = get_resource(Type, ResB),
+ ?line true = (PtrA =/= PtrB),
+ ?line [] = last_resource_dtor_call(),
+ %% forget ResA and make it garbage
+ {{PtrA,BinA}, {ResB,PtrB,BinB}}.
+
+resource_neg(TypeA) ->
+ TypeB = get_resource_type(1),
+ Aptr = alloc_resource(TypeA, <<"Arnold">>),
+ Bptr = alloc_resource(TypeB, <<"Bobo">>),
+ ?line {'EXIT',{badarg,_}} = (catch get_resource(TypeA, Bptr)),
+ ?line {'EXIT',{badarg,_}} = (catch get_resource(TypeB, Aptr)),
+ ok.
+
+-define(RT_CREATE,1).
+-define(RT_TAKEOVER,2).
+
+resource_takeover(doc) -> ["Test resource takeover by module reload and upgrade"];
+resource_takeover(suite) -> [];
+resource_takeover(Config) when is_list(Config) ->
+ TmpMem = tmpmem(),
+ ensure_lib_loaded(Config),
+
+ ?line Data = ?config(data_dir, Config),
+ ?line File = filename:join(Data, "nif_mod"),
+ ?line {ok,nif_mod,ModBin} = compile:file(File, [binary,return_errors]),
+ ?line {module,nif_mod} = erlang:load_module(nif_mod,ModBin),
+
+ ?line ok = nif_mod:load_nif_lib(Config, 1,
+ [{resource_type, 0, ?RT_CREATE, "resource_type_A",resource_dtor_A,
+ ?RT_CREATE},
+ {resource_type, 1, ?RT_CREATE, "resource_type_null_A",null,
+ ?RT_CREATE},
+ {resource_type, 2, ?RT_CREATE bor ?RT_TAKEOVER, "resource_type_A_null",resource_dtor_A,
+ ?RT_CREATE},
+ {resource_type, 3, ?RT_CREATE, "resource_type_B_goneX",resource_dtor_B,
+ ?RT_CREATE},
+ {resource_type, 4, ?RT_CREATE, "resource_type_null_goneX",null,
+ ?RT_CREATE},
+ {resource_type, null, ?RT_TAKEOVER, "Pink unicorn", resource_dtor_A,
+ ?RT_TAKEOVER}
+ ]),
+
+ ?line hold_nif_mod_priv_data(nif_mod:get_priv_data_ptr()),
+ ?line [{load,1,1,101},{get_priv_data_ptr,1,2,102}] = nif_mod_call_history(),
+
+ ?line {Holder, _MRef} = spawn_opt(fun resource_holder/0, [link, monitor]),
+
+ {A1,BinA1} = make_resource(0,Holder,"A1"),
+ {A2,BinA2} = make_resource(0,Holder,"A2"),
+ {A3,BinA3} = make_resource(0,Holder,"A3"),
+
+ {NA1,_BinNA1} = make_resource(1,Holder,"NA1"),
+ {NA2,BinNA2} = make_resource(1,Holder,"NA2"),
+ {NA3,_BinNA3} = make_resource(1,Holder,"NA3"),
+
+ {AN1,BinAN1} = make_resource(2,Holder,"AN1"),
+ {AN2,_BinAN2} = make_resource(2,Holder,"AN2"),
+ {AN3,BinAN3} = make_resource(2,Holder,"AN3"),
+
+ {BGX1,BinBGX1} = make_resource(3,Holder,"BGX1"),
+ {BGX2,BinBGX2} = make_resource(3,Holder,"BGX2"),
+
+ {NGX1,_BinNGX1} = make_resource(4,Holder,"NGX1"),
+ {NGX2,_BinNGX2} = make_resource(4,Holder,"NGX2"),
+
+ ?line [] = nif_mod_call_history(),
+
+ ?line ok = forget_resource(A1),
+ ?line [{{resource_dtor_A_v1,BinA1},1,3,103}] = nif_mod_call_history(),
+
+ ?line ok = forget_resource(NA1),
+ ?line [] = nif_mod_call_history(), % no dtor
+
+ ?line ok = forget_resource(AN1),
+ ?CHECK([{{resource_dtor_A_v1,BinAN1},1,4,104}] , nif_mod_call_history()),
+
+ ?line ok = forget_resource(BGX1),
+ ?CHECK([{{resource_dtor_B_v1,BinBGX1},1,5,105}], nif_mod_call_history()),
+
+ ?line ok = forget_resource(NGX1),
+ ?CHECK([], nif_mod_call_history()), % no dtor
+
+ ?line ok = nif_mod:load_nif_lib(Config, 2,
+ [{resource_type, 0, ?RT_TAKEOVER, "resource_type_A",resource_dtor_A,
+ ?RT_TAKEOVER},
+ {resource_type, 1, ?RT_TAKEOVER bor ?RT_CREATE, "resource_type_null_A",resource_dtor_A,
+ ?RT_TAKEOVER},
+ {resource_type, 2, ?RT_TAKEOVER, "resource_type_A_null",null,
+ ?RT_TAKEOVER},
+ {resource_type, null, ?RT_TAKEOVER, "Pink unicorn", resource_dtor_A,
+ ?RT_TAKEOVER},
+ {resource_type, null, ?RT_CREATE, "resource_type_B_goneX",resource_dtor_B,
+ ?RT_CREATE},
+ {resource_type, null, ?RT_CREATE, "resource_type_null_goneX",null,
+ ?RT_CREATE},
+ {resource_type, 3, ?RT_CREATE, "resource_type_B_goneY",resource_dtor_B,
+ ?RT_CREATE},
+ {resource_type, 4, ?RT_CREATE, "resource_type_null_goneY",null,
+ ?RT_CREATE}
+ ]),
+ ?CHECK([{reload,2,1,201}], nif_mod_call_history()),
+
+ ?line BinA2 = read_resource(0,A2),
+ ?line ok = forget_resource(A2),
+ ?CHECK([{{resource_dtor_A_v2,BinA2},2,2,202}], nif_mod_call_history()),
+
+ ?line ok = forget_resource(NA2),
+ ?CHECK([{{resource_dtor_A_v2,BinNA2},2,3,203}], nif_mod_call_history()),
+
+ ?line ok = forget_resource(AN2),
+ ?CHECK([], nif_mod_call_history()), % no dtor
+
+ ?line ok = forget_resource(BGX2), % calling dtor in orphan library v1 still loaded
+ ?CHECK([{{resource_dtor_B_v1,BinBGX2},1,6,106}], nif_mod_call_history()),
+ % How to test that lib v1 is closed here?
+
+ ?line ok = forget_resource(NGX2),
+ ?CHECK([], nif_mod_call_history()), % no dtor
+
+ {BGY1,BinBGY1} = make_resource(3,Holder,"BGY1"),
+ {NGY1,_BinNGY1} = make_resource(4,Holder,"NGY1"),
+ %% Module upgrade with same lib-version
+ ?line {module,nif_mod} = erlang:load_module(nif_mod,ModBin),
+ ?line undefined = nif_mod:lib_version(),
+ ?line ok = nif_mod:load_nif_lib(Config, 2,
+ [{resource_type, 2, ?RT_TAKEOVER, "resource_type_A",resource_dtor_B,
+ ?RT_TAKEOVER},
+ {resource_type, 0, ?RT_TAKEOVER bor ?RT_CREATE, "resource_type_null_A",null,
+ ?RT_TAKEOVER},
+ {resource_type, 1, ?RT_TAKEOVER, "resource_type_A_null",resource_dtor_A,
+ ?RT_TAKEOVER},
+ {resource_type, null, ?RT_TAKEOVER, "Pink elephant", resource_dtor_A,
+ ?RT_TAKEOVER},
+ {resource_type, 3, ?RT_CREATE, "resource_type_B_goneZ",resource_dtor_B,
+ ?RT_CREATE},
+ {resource_type, 4, ?RT_CREATE, "resource_type_null_goneZ",null,
+ ?RT_CREATE}
+ ]),
+
+ ?line 2 = nif_mod:lib_version(),
+ ?CHECK([{upgrade,2,4,204},{lib_version,2,5,205}], nif_mod_call_history()),
+
+ ?line ok = forget_resource(A3),
+ ?CHECK([{{resource_dtor_B_v2,BinA3},2,6,206}], nif_mod_call_history()),
+
+ ?line ok = forget_resource(NA3),
+ ?CHECK([], nif_mod_call_history()),
+
+ ?line ok = forget_resource(AN3),
+ ?CHECK([{{resource_dtor_A_v2,BinAN3},2,7,207}], nif_mod_call_history()),
+
+ {A4,BinA4} = make_resource(2,Holder, "A4"),
+ {NA4,BinNA4} = make_resource(0,Holder, "NA4"),
+ {AN4,_BinAN4} = make_resource(1,Holder, "AN4"),
+
+ {BGZ1,BinBGZ1} = make_resource(3,Holder,"BGZ1"),
+ {NGZ1,_BinNGZ1} = make_resource(4,Holder,"NGZ1"),
+
+ ?line false = code:purge(nif_mod),
+ ?line [] = nif_mod_call_history(),
+
+ ?line ok = forget_resource(NGY1),
+ ?line [] = nif_mod_call_history(),
+
+ ?line ok = forget_resource(BGY1), % calling dtor in orphan library v2 still loaded
+ ?line [{{resource_dtor_B_v2,BinBGY1},2,8,208},{unload,2,9,209}] = nif_mod_call_history(),
+
+ %% Module upgrade with other lib-version
+ ?line {module,nif_mod} = erlang:load_module(nif_mod,ModBin),
+ ?line undefined = nif_mod:lib_version(),
+ ?line ok = nif_mod:load_nif_lib(Config, 1,
+ [{resource_type, 2, ?RT_TAKEOVER, "resource_type_A",resource_dtor_A,
+ ?RT_TAKEOVER},
+ {resource_type, 0, ?RT_TAKEOVER bor ?RT_CREATE, "resource_type_null_A",resource_dtor_A,
+ ?RT_TAKEOVER},
+ {resource_type, 1, ?RT_TAKEOVER, "resource_type_A_null",null,
+ ?RT_TAKEOVER},
+ {resource_type, null, ?RT_TAKEOVER, "Mr Pink", resource_dtor_A,
+ ?RT_TAKEOVER}
+ ]),
+
+ ?line 1 = nif_mod:lib_version(),
+ ?line [{upgrade,1,1,101},{lib_version,1,2,102}] = nif_mod_call_history(),
+
+ %%?line false= check_process_code(Pid, nif_mod),
+ ?line false = code:purge(nif_mod),
+ %% no unload here as we still have instances with destructors
+ ?line [] = nif_mod_call_history(),
+
+ ?line ok = forget_resource(BGZ1), % calling dtor in orphan library v2 still loaded
+ ?line [{{resource_dtor_B_v2,BinBGZ1},2,10,210},{unload,2,11,211}] = nif_mod_call_history(),
+
+ ?line ok = forget_resource(NGZ1),
+ ?line [] = nif_mod_call_history(),
+
+ ?line ok = forget_resource(A4),
+ ?line [{{resource_dtor_A_v1,BinA4},1,3,103}] = nif_mod_call_history(),
+
+ ?line ok = forget_resource(NA4),
+ ?line [{{resource_dtor_A_v1,BinNA4},1,4,104}] = nif_mod_call_history(),
+
+ ?line ok = forget_resource(AN4),
+ ?line [] = nif_mod_call_history(),
+
+ ?line [?MODULE, nif_mod] = erlang:system_info(taints),
+ ?line verify_tmpmem(TmpMem),
+ ok.
+
+make_resource(Type,Holder,Str) when is_list(Str) ->
+ Bin = list_to_binary(Str),
+ A1 = make_resource_do(Type,Holder,Bin),
+ ?line Bin = read_resource(Type,A1),
+ {A1,Bin}.
+
+make_resource_do(Type, Holder, Bin) ->
+ Holder ! {self(), make, Type, Bin},
+ {Holder, make_ok, Id} = receive_any(),
+ {Holder,Id}.
+
+read_resource(Type, {Holder,Id}) ->
+ Holder ! {self(), get, Type, Id},
+ {Holder, get_ok, Bin} = receive_any(),
+ Bin.
+
+forget_resource({Holder,Id}) ->
+ Holder ! {self(), forget, Id},
+ {Holder, forget_ok, Id} = receive_any(),
+ ok.
+
+
+resource_holder() ->
+ resource_holder([]).
+resource_holder(List) ->
+ %%io:format("resource_holder waiting for msg\n", []),
+ Msg = receive_any(),
+ %%io:format("resource_holder got ~p with list = ~p\n", [Msg,List]),
+ case Msg of
+ {Pid, make, Type, Bin} ->
+ ?line Resource = nif_mod:make_new_resource(Type, Bin),
+ Id = {make_ref(),Bin},
+ Pid ! {self(), make_ok, Id},
+ resource_holder([{Id,Resource} | List]);
+ {Pid, get, Type, Id} ->
+ {Id,Resource} = lists:keyfind(Id, 1, List),
+ Pid ! {self(), get_ok, nif_mod:get_resource(Type, Resource)},
+ resource_holder(List);
+
+ {Pid, forget, Id} ->
+ NewList = lists:keydelete(Id, 1, List),
+ %%io:format("resource_holder forget: NewList = ~p\n", [NewList]),
+ resource_holder(Pid, {self(),forget_ok,Id}, NewList)
+ end.
+
+resource_holder(Pid,Reply,List) ->
+ erlang:garbage_collect(),
+ %%io:format("resource_holder GC'ed, now send ~p to ~p\n", [Reply,Pid]),
+ Pid ! Reply,
+ resource_holder(List).
+
+
+threading(doc) -> ["Test the threading API functions (reuse tests from driver API)"];
+threading(Config) when is_list(Config) ->
+ ?line Data = ?config(data_dir, Config),
+ ?line File = filename:join(Data, "tester"),
+ ?line {ok,tester,ModBin} = compile:file(File, [binary,return_errors]),
+ ?line {module,tester} = erlang:load_module(tester,ModBin),
+
+ ?line ok = tester:load_nif_lib(Config, "basic"),
+ ?line ok = tester:run(),
+
+ ?line ok = tester:load_nif_lib(Config, "rwlock"),
+ ?line ok = tester:run(),
+
+ ?line ok = tester:load_nif_lib(Config, "tsd"),
+ ?line ok = tester:run().
+
neg(doc) -> ["Negative testing of load_nif"];
-neg(suite) -> [];
neg(Config) when is_list(Config) ->
+ TmpMem = tmpmem(),
?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 verify_tmpmem(TmpMem),
?line ok.
ensure_lib_loaded(Config) ->
ensure_lib_loaded(Config, 1).
-
ensure_lib_loaded(Config, Ver) ->
?line case lib_version() of
undefined ->
?line Path = ?config(data_dir, Config),
?line Lib = "nif_SUITE." ++ integer_to_list(Ver),
- ?line ok = erlang:load_nif(filename:join(Path,Lib), 0);
+ ?line ok = erlang:load_nif(filename:join(Path,Lib), []);
Ver when is_integer(Ver) ->
ok
end.
+tmpmem() ->
+ case erlang:system_info({allocator,temp_alloc}) of
+ false -> undefined;
+ MemInfo ->
+ MSBCS = lists:foldl(
+ fun ({instance, _, L}, Acc) ->
+ {value,{_,MBCS}} = lists:keysearch(mbcs, 1, L),
+ {value,{_,SBCS}} = lists:keysearch(sbcs, 1, L),
+ [MBCS,SBCS | Acc]
+ end,
+ [],
+ MemInfo),
+ lists:foldl(
+ fun(L, {Bl0,BlSz0}) ->
+ {value,{_,Bl,_,_}} = lists:keysearch(blocks, 1, L),
+ {value,{_,BlSz,_,_}} = lists:keysearch(blocks_size, 1, L),
+ {Bl0+Bl,BlSz0+BlSz}
+ end, {0,0}, MSBCS)
+ end.
+
+verify_tmpmem(MemInfo) ->
+ %%wait_for_test_procs(),
+ case tmpmem() of
+ MemInfo ->
+ io:format("Tmp mem info: ~p", [MemInfo]),
+ case MemInfo of
+ {notsup,undefined} ->
+ %% Use 'erl +Mea max' to do more complete memory leak testing.
+ {comment,"Incomplete or no mem leak testing"};
+ _ ->
+ ok
+ end;
+ Other ->
+ io:format("Expected: ~p", [MemInfo]),
+ io:format("Actual: ~p", [Other]),
+ ?t:fail()
+ end.
+
call(Pid,Cmd) ->
%%io:format("~p calling ~p with ~p\n",[self(), Pid, Cmd]),
Pid ! {self(), Cmd},
@@ -224,12 +821,40 @@ call(Pid,Cmd) ->
receive_any() ->
receive M -> M end.
+%% check(Exp,Got,Line) ->
+%% case Got of
+%% Exp -> Exp;
+%% _ ->
+%% io:format("CHECK at ~p: Expected ~p but got ~p\n",[Line,Exp,Got]),
+%% Got
+%% end.
+
+
%% The NIFs:
lib_version() -> undefined.
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.
+clone_bin(_) -> ?nif_stub.
+make_sub_bin(_,_,_) -> ?nif_stub.
+string_to_bin(_,_) -> ?nif_stub.
+atom_to_bin(_,_) -> ?nif_stub.
+macros(_) -> ?nif_stub.
+tuple_2_list_and_tuple(_) -> ?nif_stub.
+iolist_2_bin(_) -> ?nif_stub.
+get_resource_type(_) -> ?nif_stub.
+alloc_resource(_,_) -> ?nif_stub.
+make_resource(_) -> ?nif_stub.
+get_resource(_,_) -> ?nif_stub.
+release_resource(_) -> ?nif_stub.
+last_resource_dtor_call() -> ?nif_stub.
+make_new_resource(_,_) -> ?nif_stub.
+
nif_stub_error(Line) ->
exit({nif_not_loaded,module,?MODULE,line,Line}).
diff --git a/erts/emulator/test/nif_SUITE_data/Makefile.src b/erts/emulator/test/nif_SUITE_data/Makefile.src
index 6a8b4f1245..ab4ff77add 100644
--- a/erts/emulator/test/nif_SUITE_data/Makefile.src
+++ b/erts/emulator/test/nif_SUITE_data/Makefile.src
@@ -4,11 +4,22 @@ NIF_LIBS = nif_SUITE.1@dll@ \
nif_mod.2@dll@ \
nif_mod.3@dll@
-all: $(NIF_LIBS)
+all: $(NIF_LIBS) basic@dll@ rwlock@dll@ tsd@dll@
@SHLIB_RULES@
$(NIF_LIBS): nif_SUITE.c nif_mod.c nif_mod.h
+basic@dll@: tester.c testcase_driver.h
+rwlock@dll@: tester.c testcase_driver.h
+
+tsd@dll@: tester.c testcase_driver.h
+
+DRIVER_DIR = ../erl_drv_thread_SUITE_data
+
+basic.c rwlock.c tsd.c: $(DRIVER_DIR)/$@
+ cat head.txt > $@
+ cat $(DRIVER_DIR)/$@ | sed -e 's/erl_drv_/enif_/g' -e 's/driver_/enif_/g' -e 's/ErlDrv/ErlNif/g' >> $@
+ cat tail.txt >> $@
diff --git a/erts/emulator/test/nif_SUITE_data/head.txt b/erts/emulator/test/nif_SUITE_data/head.txt
new file mode 100644
index 0000000000..4b9b44276f
--- /dev/null
+++ b/erts/emulator/test/nif_SUITE_data/head.txt
@@ -0,0 +1,5 @@
+/* Do NOT edit this file!!!
+**
+** This is a NIF'ified COPY of the original in ../erl_drv_thread_SUITE_data/
+*/
+
diff --git a/erts/emulator/test/nif_SUITE_data/nif_SUITE.c b/erts/emulator/test/nif_SUITE_data/nif_SUITE.c
index 852495e234..7d05a9a880 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"
@@ -12,6 +15,7 @@ typedef struct
int ref_cnt;
CallInfo* call_history;
NifModPrivData* nif_mod;
+ union { ErlNifResourceType* t; long l; } rt_arr[2];
}PrivData;
void add_call(ErlNifEnv* env, PrivData* data, const char* func_name)
@@ -23,12 +27,29 @@ void add_call(ErlNifEnv* env, PrivData* data, const char* func_name)
call->static_cntA = ++static_cntA;
call->static_cntB = ++static_cntB;
data->call_history = call;
+ call->arg = NULL;
+ call->arg_sz = 0;
}
#define ADD_CALL(FUNC_NAME) add_call(env, enif_get_data(env),FUNC_NAME)
+static void* resource_dtor_last = NULL;
+static unsigned resource_dtor_last_sz = 0;
+static char resource_dtor_last_data[20];
+static int resource_dtor_cnt = 0;
+
+static void resource_dtor(ErlNifEnv* env, void* obj)
+{
+ resource_dtor_last = obj;
+ resource_dtor_cnt++;
+ resource_dtor_last_sz = enif_sizeof_resource(env, obj);
+ assert(resource_dtor_last_sz <= sizeof(resource_dtor_last_data));
+ memcpy(resource_dtor_last_data, obj, resource_dtor_last_sz);
+}
+
static int load(ErlNifEnv* env, void** priv_data, ERL_NIF_TERM load_info)
{
+ /*ERL_NIF_TERM head, tail;*/
PrivData* data = enif_alloc(env, sizeof(PrivData));
assert(data != NULL);
data->ref_cnt = 1;
@@ -36,7 +57,26 @@ static int load(ErlNifEnv* env, void** priv_data, ERL_NIF_TERM load_info)
data->nif_mod = NULL;
add_call(env, data, "load");
-
+
+ /*
+ head = load_info;
+ data->rt_cnt = 0;
+ for (head=load_info; enif_get_list_cell(env,load_info,&head,&tail);
+ head=tail) {
+ char buf[20];
+ int n = enif_get_string(env,head,buf,sizeof(buf));
+ assert(n > 0);
+ assert(i < sizeof(data->rt_arr)/sizeof(*data->rt_arr));
+ data->rt_arr[data->rt_cnt++].t = enif_create_resource_type(env,buf,resource_dtor,
+ ERL_NIF_RT_CREATE,NULL);
+ }
+ assert(enif_is_empty_list(env,head));
+ */
+ data->rt_arr[0].t = enif_open_resource_type(env,"Gold",resource_dtor,
+ ERL_NIF_RT_CREATE,NULL);
+ data->rt_arr[1].t = enif_open_resource_type(env,"Silver",resource_dtor,
+ ERL_NIF_RT_CREATE,NULL);
+
*priv_data = data;
return 0;
}
@@ -65,7 +105,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);
@@ -77,11 +117,19 @@ static ERL_NIF_TERM make_call_history(ErlNifEnv* env, CallInfo** headp)
while (*headp != NULL) {
CallInfo* call = *headp;
- ERL_NIF_TERM tpl = enif_make_tuple(env, 4,
- enif_make_atom(env,call->func_name),
- enif_make_int(env,call->lib_ver),
- enif_make_int(env,call->static_cntA),
- enif_make_int(env,call->static_cntB));
+ ERL_NIF_TERM func_term = enif_make_atom(env,call->func_name);
+ ERL_NIF_TERM tpl;
+ if (call->arg != NULL) {
+ ErlNifBinary arg_bin;
+ enif_alloc_binary(env, call->arg_sz, &arg_bin);
+ memcpy(arg_bin.data, call->arg, call->arg_sz);
+ func_term = enif_make_tuple2(env, func_term,
+ enif_make_binary(env, &arg_bin));
+ }
+ tpl = enif_make_tuple4(env, func_term,
+ enif_make_int(env,call->lib_ver),
+ enif_make_int(env,call->static_cntA),
+ enif_make_int(env,call->static_cntB));
list = enif_make_list_cell(env, tpl, list);
*headp = call->next;
enif_free(env,call);
@@ -89,19 +137,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,21 +159,24 @@ 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);
-
+ ERL_NIF_TERM ret;
if (data->nif_mod == NULL) {
- return enif_make_string(env,"nif_mod pointer is NULL");
+ return enif_make_string(env,"nif_mod pointer is NULL", ERL_NIF_LATIN1);
}
- return make_call_history(env,&data->nif_mod->call_history);
+ enif_mutex_lock(data->nif_mod->mtx);
+ ret = make_call_history(env, &data->nif_mod->call_history);
+ enif_mutex_unlock(data->nif_mod->mtx);
+ return ret;
}
-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 +187,461 @@ 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_uint(ErlNifEnv* env, unsigned i1)
+{
+ unsigned i2 = 0;
+ ERL_NIF_TERM int_term = enif_make_uint(env, i1);
+ if (!enif_get_uint(env,int_term, &i2) || i1 != i2) {
+ fprintf(stderr, "test_uint(%u) ...FAILED i2=%u\r\n", i1, i2);
+ return 0;
+ }
+ return 1;
+}
+
+static int test_long(ErlNifEnv* env, long i1)
+{
+ long i2 = 0;
+ ERL_NIF_TERM int_term = enif_make_long(env, i1);
+ if (!enif_get_long(env,int_term, &i2) || i1 != i2) {
+ fprintf(stderr, "test_long(%ld) ...FAILED i2=%ld\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, "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, "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;
+ int sint;
+ unsigned uint;
+ long slong;
+ unsigned long ulong;
+ double d;
+ ERL_NIF_TERM atom, ref1, ref2;
+
+ sint = INT_MIN;
+ do {
+ if (!test_int(env,sint)) {
+ goto error;
+ }
+ sint += ~sint / 3 + 1;
+ } while (sint < 0);
+ sint = INT_MAX;
+ do {
+ if (!test_int(env,sint)) {
+ goto error;
+ }
+ sint -= sint / 3 + 1;
+ } while (sint >= 0);
+
+ slong = LONG_MIN;
+ do {
+ if (!test_long(env,slong)) {
+ goto error;
+ }
+ slong += ~slong / 3 + 1;
+ } while (slong < 0);
+ slong = LONG_MAX;
+ do {
+ if (!test_long(env,slong)) {
+ goto error;
+ }
+ slong -= slong / 3 + 1;
+ } while (slong >= 0);
+
+
+ uint = UINT_MAX;
+ for (;;) {
+ if (!test_uint(env,uint)) {
+
+ }
+ if (uint == 0) break;
+ uint -= uint / 3 + 1;
+ }
+ ulong = ULONG_MAX;
+ for (;;) {
+ if (!test_ulong(env,ulong)) {
+
+ }
+ if (ulong == 0) break;
+ ulong -= ulong / 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;
+ }
+ }
+ for (i=-10 ; i <= 10; i++) {
+ if (!test_uint(env,MAX_SMALL+i)) {
+ goto error;
+ }
+ }
+ }
+ assert((MAX_SMALL < INT_MAX) == (MIN_SMALL > INT_MIN));
+
+ for (i=-10 ; i < 10; i++) {
+ if (!test_long(env,MAX_SMALL+i) || !test_ulong(env,MAX_SMALL+i) ||
+ !test_long(env,MIN_SMALL+i)) {
+ 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, "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, "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, "strange refs?\r\n");
+ goto error;
+ }
+ 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;
+ const 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 ERL_NIF_TERM clone_bin(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
+{
+ ErlNifBinary ibin;
+ if (enif_inspect_binary(env,argv[0],&ibin)) {
+ ErlNifBinary obin;
+ enif_alloc_binary(env,ibin.size,&obin);
+ memcpy(obin.data,ibin.data,ibin.size);
+ /*enif_release_binary(env,&ibin);*/
+ return enif_make_binary(env,&obin);
+ }
+ else {
+ return enif_make_badarg(env);
+ }
+}
+
+static ERL_NIF_TERM make_sub_bin(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
+{
+ int pos, size;
+ if (!enif_get_int(env,argv[1],&pos) || !enif_get_int(env,argv[2],&size)) {
+ return enif_make_badarg(env);
+ }
+ return enif_make_sub_binary(env,argv[0],pos,size);
+}
+
+static ERL_NIF_TERM string_to_bin(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
+{
+ ErlNifBinary obin;
+ unsigned size;
+ int n;
+ if (!enif_get_int(env,argv[1],(int*)&size)
+ || !enif_alloc_binary(env,size,&obin)) {
+ return enif_make_badarg(env);
+ }
+ n = enif_get_string(env, argv[0], (char*)obin.data, size, ERL_NIF_LATIN1);
+ return enif_make_tuple(env, 2, enif_make_int(env,n),
+ enif_make_binary(env,&obin));
+}
+
+static ERL_NIF_TERM atom_to_bin(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
+{
+ ErlNifBinary obin;
+ unsigned size;
+ int n;
+ if (!enif_get_int(env,argv[1],(int*)&size)
+ || !enif_alloc_binary(env,size,&obin)) {
+ return enif_make_badarg(env);
+ }
+ n = enif_get_atom(env, argv[0], (char*)obin.data, size);
+ return enif_make_tuple(env, 2, enif_make_int(env,n),
+ enif_make_binary(env,&obin));
+}
+
+static ERL_NIF_TERM macros(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
+{
+ const ERL_NIF_TERM* a;
+ ERL_NIF_TERM lists, tuples;
+ int arity;
+ if (!enif_get_tuple(env, argv[0], &arity, &a) || arity != 9) {
+ return enif_make_badarg(env);
+ }
+
+ lists = enif_make_list(env,9,
+ enif_make_list1(env,a[0]),
+ enif_make_list2(env,a[0],a[1]),
+ enif_make_list3(env,a[0],a[1],a[2]),
+ enif_make_list4(env,a[0],a[1],a[2],a[3]),
+ enif_make_list5(env,a[0],a[1],a[2],a[3],a[4]),
+ enif_make_list6(env,a[0],a[1],a[2],a[3],a[4],a[5]),
+ enif_make_list7(env,a[0],a[1],a[2],a[3],a[4],a[5],a[6]),
+ enif_make_list8(env,a[0],a[1],a[2],a[3],a[4],a[5],a[6],a[7]),
+ enif_make_list9(env,a[0],a[1],a[2],a[3],a[4],a[5],a[6],a[7],a[8]));
+ tuples = enif_make_list(env,9,
+ enif_make_tuple1(env,a[0]),
+ enif_make_tuple2(env,a[0],a[1]),
+ enif_make_tuple3(env,a[0],a[1],a[2]),
+ enif_make_tuple4(env,a[0],a[1],a[2],a[3]),
+ enif_make_tuple5(env,a[0],a[1],a[2],a[3],a[4]),
+ enif_make_tuple6(env,a[0],a[1],a[2],a[3],a[4],a[5]),
+ enif_make_tuple7(env,a[0],a[1],a[2],a[3],a[4],a[5],a[6]),
+ enif_make_tuple8(env,a[0],a[1],a[2],a[3],a[4],a[5],a[6],a[7]),
+ enif_make_tuple9(env,a[0],a[1],a[2],a[3],a[4],a[5],a[6],a[7],a[8]));
+ return enif_make_tuple2(env,lists,tuples);
+}
+
+static ERL_NIF_TERM tuple_2_list_and_tuple(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
+{
+ const ERL_NIF_TERM* arr;
+ int arity;
+ if (!enif_get_tuple(env,argv[0],&arity,&arr)) {
+ return enif_make_badarg(env);
+ }
+ return enif_make_tuple2(env,
+ enif_make_list_from_array(env, arr, arity),
+ enif_make_tuple_from_array(env, arr, arity));
+}
+
+static ERL_NIF_TERM iolist_2_bin(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
+{
+ ErlNifBinary obin;
+ if (!enif_inspect_iolist_as_binary(env, argv[0], &obin)) {
+ return enif_make_badarg(env);
+ }
+ return enif_make_binary(env,&obin);
+}
+
+static ERL_NIF_TERM last_resource_dtor_call(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
+{
+ ErlNifBinary bin;
+ ERL_NIF_TERM ret;
+ if (resource_dtor_last != NULL) {
+ enif_alloc_binary(env, resource_dtor_last_sz, &bin);
+ memcpy(bin.data, resource_dtor_last_data, resource_dtor_last_sz);
+ ret = enif_make_tuple3(env,
+ enif_make_long(env, (long)resource_dtor_last),
+ enif_make_binary(env, &bin),
+ enif_make_int(env, resource_dtor_cnt));
+ }
+ else {
+ ret = enif_make_list(env,0);
+ }
+ resource_dtor_last = NULL;
+ resource_dtor_last_sz = 0;
+ resource_dtor_cnt = 0;
+ return ret;
+}
+
+static ERL_NIF_TERM get_resource_type(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
+{
+ PrivData* data = (PrivData*) enif_get_data(env);
+ int ix;
+
+ if (!enif_get_int(env, argv[0], &ix) || ix >= 2) {
+ return enif_make_badarg(env);
+ }
+ return enif_make_long(env, data->rt_arr[ix].l);
+}
+
+static ERL_NIF_TERM alloc_resource(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
+{
+ ErlNifBinary data_bin;
+ union { ErlNifResourceType* t; long l;} type;
+ union { void* p; long l;} data;
+ if (!enif_get_long(env, argv[0], &type.l)
+ || !enif_inspect_binary(env, argv[1], &data_bin)
+ || (data.p = enif_alloc_resource(env, type.t, data_bin.size))==NULL) {
+
+ return enif_make_badarg(env);
+ }
+ memcpy(data.p, data_bin.data, data_bin.size);
+ return enif_make_long(env, data.l);
+}
+
+static ERL_NIF_TERM make_resource(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
+{
+ union { void* p; long l; } data;
+ if (!enif_get_long(env, argv[0], &data.l)) {
+ return enif_make_badarg(env);
+ }
+ return enif_make_resource(env, data.p);
+}
+
+static ERL_NIF_TERM make_new_resource(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
+{
+ ErlNifBinary data_bin;
+ union { ErlNifResourceType* t; long l;} type;
+ void* data;
+ ERL_NIF_TERM ret;
+ if (!enif_get_long(env, argv[0], &type.l)
+ || !enif_inspect_binary(env, argv[1], &data_bin)
+ || (data = enif_alloc_resource(env, type.t, data_bin.size))==NULL) {
+
+ return enif_make_badarg(env);
+ }
+ ret = enif_make_resource(env, data);
+ memcpy(data, data_bin.data, data_bin.size);
+ enif_release_resource(env, data);
+ return ret;
+}
+
+static ERL_NIF_TERM get_resource(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
+{
+ ErlNifBinary data_bin;
+ union { ErlNifResourceType* t; long l; } type;
+ union { void* p; long l; } data;
+
+ if (!enif_get_long(env, argv[0], &type.l)
+ || !enif_get_resource(env, argv[1], type.t, &data.p)) {
+ return enif_make_badarg(env);
+ }
+
+ enif_alloc_binary(env, enif_sizeof_resource(env,data.p), &data_bin);
+ memcpy(data_bin.data, data.p, data_bin.size);
+ return enif_make_tuple2(env, enif_make_long(env,data.l),
+ enif_make_binary(env, &data_bin));
+}
+
+static ERL_NIF_TERM release_resource(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
+{
+ union { void* p; long l; } data;
+ if (!enif_get_long(env, argv[0], &data.l)) {
+ return enif_make_badarg(env);
+ }
+ enif_release_resource(env, data.p);
+ return enif_make_atom(env,"ok");
+}
+
+
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},
+ {"clone_bin", 1, clone_bin},
+ {"make_sub_bin", 3, make_sub_bin},
+ {"string_to_bin", 2, string_to_bin},
+ {"atom_to_bin", 2, atom_to_bin},
+ {"macros", 1, macros},
+ {"tuple_2_list_and_tuple",1,tuple_2_list_and_tuple},
+ {"iolist_2_bin", 1, iolist_2_bin},
+ {"get_resource_type", 1, get_resource_type},
+ {"alloc_resource", 2, alloc_resource},
+ {"make_resource", 1, make_resource},
+ {"get_resource", 2, get_resource},
+ {"release_resource", 1, release_resource},
+ {"last_resource_dtor_call", 0, last_resource_dtor_call},
+ {"make_new_resource", 2, make_new_resource}
+
};
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..c075b74c57 100644
--- a/erts/emulator/test/nif_SUITE_data/nif_mod.c
+++ b/erts/emulator/test/nif_SUITE_data/nif_mod.c
@@ -1,51 +1,182 @@
#include "erl_nif.h"
#include <string.h>
-#include <assert.h>
+#include <stdio.h>
#include "nif_mod.h"
+#define CHECK(X) ((void)((X) || (check_abort(__LINE__),1)))
+#ifdef __GNUC__
+static void check_abort(unsigned line) __attribute__((noreturn));
+#endif
+static void check_abort(unsigned line)
+{
+ enif_fprintf(stderr, "Test CHECK failed at %s:%u\r\n",
+ __FILE__, line);
+ abort();
+}
static int static_cntA; /* zero by default */
static int static_cntB = NIF_LIB_VER * 100;
-static void add_call(ErlNifEnv* env, NifModPrivData* data, const char* func_name)
+static ERL_NIF_TERM am_true;
+static ERL_NIF_TERM am_null;
+static ERL_NIF_TERM am_resource_type;
+static ERL_NIF_TERM am_resource_dtor_A;
+static ERL_NIF_TERM am_resource_dtor_B;
+
+static void init(ErlNifEnv* env)
+{
+ am_true = enif_make_atom(env, "true");
+ am_null = enif_make_atom(env, "null");
+ am_resource_type = enif_make_atom(env, "resource_type");
+ am_resource_dtor_A = enif_make_atom(env, "resource_dtor_A");
+ am_resource_dtor_B = enif_make_atom(env, "resource_dtor_B");
+}
+
+static void add_call_with_arg(ErlNifEnv* env, NifModPrivData* data, const char* func_name,
+ const char* arg, int arg_sz)
{
- CallInfo* call = enif_alloc(env, sizeof(CallInfo)+strlen(func_name));
+ CallInfo* call = enif_alloc(env, sizeof(CallInfo)+strlen(func_name) + arg_sz);
strcpy(call->func_name, func_name);
call->lib_ver = NIF_LIB_VER;
call->static_cntA = ++static_cntA;
call->static_cntB = ++static_cntB;
+ call->arg_sz = arg_sz;
+ if (arg != NULL) {
+ call->arg = call->func_name + strlen(func_name) + 1;
+ memcpy(call->arg, arg, arg_sz);
+ }
+ else {
+ call->arg = NULL;
+ }
+ enif_mutex_lock(data->mtx);
call->next = data->call_history;
data->call_history = call;
+ enif_mutex_unlock(data->mtx);
+}
+
+static void add_call(ErlNifEnv* env, NifModPrivData* data,const char* func_name)
+{
+ add_call_with_arg(env, data, func_name, NULL, 0);
+}
+
+#define ADD_CALL(FUNC_NAME) add_call(env, enif_priv_data(env),FUNC_NAME)
+
+#define STRINGIFY_(X) #X
+#define STRINGIFY(X) STRINGIFY_(X)
+
+static void resource_dtor_A(ErlNifEnv* env, void* a)
+{
+ const char dtor_name[] = "resource_dtor_A_v" STRINGIFY(NIF_LIB_VER);
+
+ add_call_with_arg(env, enif_priv_data(env), dtor_name,
+ a, enif_sizeof_resource(env, a));
+}
+
+static void resource_dtor_B(ErlNifEnv* env, void* a)
+{
+ const char dtor_name[] = "resource_dtor_B_v" STRINGIFY(NIF_LIB_VER);
+
+ add_call_with_arg(env, enif_priv_data(env), dtor_name,
+ a, enif_sizeof_resource(env, a));
+}
+
+/* {resource_type, Ix|null, ErlNifResourceFlags in, "TypeName", dtor(A|B|null), ErlNifResourceFlags out}*/
+static void open_resource_type(ErlNifEnv* env, ERL_NIF_TERM op_tpl)
+{
+ NifModPrivData* data = enif_priv_data(env);
+ const ERL_NIF_TERM* arr;
+ int arity;
+ char rt_name[30];
+ union { enum ErlNifResourceFlags e; int i; } flags, exp_res, got_res;
+ unsigned ix;
+ ErlNifResourceDtor* dtor;
+ ErlNifResourceType* got_ptr;
+
+ CHECK(enif_get_tuple(env, op_tpl, &arity, &arr));
+ CHECK(arity == 6);
+ CHECK(enif_is_identical(env, arr[0], am_resource_type));
+ CHECK(enif_get_int(env, arr[2], &flags.i));
+ CHECK(enif_get_string(env, arr[3], rt_name, sizeof(rt_name), ERL_NIF_LATIN1) > 0);
+ CHECK(enif_get_int(env, arr[5], &exp_res.i));
+
+ if (enif_is_identical(env, arr[4], am_null)) {
+ dtor = NULL;
+ }
+ else if (enif_is_identical(env, arr[4], am_resource_dtor_A)) {
+ dtor = resource_dtor_A;
+ }
+ else {
+ CHECK(enif_is_identical(env, arr[4], am_resource_dtor_B));
+ dtor = resource_dtor_B;
+ }
+
+ got_ptr = enif_open_resource_type(env, rt_name, dtor,
+ flags.e, &got_res.e);
+
+ if (enif_get_uint(env, arr[1], &ix) && ix < RT_MAX && got_ptr != NULL) {
+ data->rt_arr[ix] = got_ptr;
+ }
+ else {
+ CHECK(enif_is_identical(env, arr[1], am_null));
+ CHECK(got_ptr == NULL);
+ }
+ CHECK(got_res.e == exp_res.e);
}
-#define ADD_CALL(FUNC_NAME) add_call(env, enif_get_data(env),FUNC_NAME)
+static void do_load_info(ErlNifEnv* env, ERL_NIF_TERM load_info)
+{
+ NifModPrivData* data = enif_priv_data(env);
+ ERL_NIF_TERM head, tail;
+ unsigned ix;
+ for (ix=0; ix<RT_MAX; ix++) {
+ data->rt_arr[ix] = NULL;
+ }
+ for (head = load_info; enif_get_list_cell(env, head, &head, &tail);
+ head = tail) {
+
+ open_resource_type(env, head);
+ }
+ CHECK(enif_is_empty_list(env, head));
+}
static int load(ErlNifEnv* env, void** priv_data, ERL_NIF_TERM load_info)
{
- NifModPrivData* data = enif_alloc(env, sizeof(NifModPrivData));
- assert(data != NULL);
+ NifModPrivData* data;
+
+ init(env);
+ data = enif_alloc(env, sizeof(NifModPrivData));
+ CHECK(data != NULL);
+ *priv_data = data;
+ data->mtx = enif_mutex_create("nif_mod_priv_data");
data->ref_cnt = 1;
data->call_history = NULL;
add_call(env, data, "load");
- data->calls = 0;
- *priv_data = data;
+ do_load_info(env, load_info);
+ data->calls = 0;
return 0;
}
static int reload(ErlNifEnv* env, void** priv_data, ERL_NIF_TERM load_info)
{
+ init(env);
add_call(env, *priv_data, "reload");
+
+ do_load_info(env, load_info);
return 0;
}
static int upgrade(ErlNifEnv* env, void** priv_data, void** old_priv_data, ERL_NIF_TERM load_info)
{
NifModPrivData* data = *old_priv_data;
+ init(env);
add_call(env, data, "upgrade");
data->ref_cnt++;
+
*priv_data = *old_priv_data;
+ do_load_info(env, load_info);
+
return 0;
}
@@ -53,46 +184,66 @@ static void unload(ErlNifEnv* env, void* priv_data)
{
NifModPrivData* data = priv_data;
add_call(env, data, "unload");
+ enif_mutex_lock(data->mtx);
if (--data->ref_cnt == 0) {
+ enif_mutex_unlock(data->mtx);
+ enif_mutex_destroy(data->mtx);
enif_free(env, data);
}
+ enif_mutex_unlock(data->mtx);
}
-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 get_priv_data_ptr(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 */
+ ADD_CALL("get_priv_data_ptr");
+ return enif_make_ulong(env, (unsigned long)enif_priv_data(env));
+}
- while (data->call_history != NULL) {
- CallInfo* call = data->call_history;
- ERL_NIF_TERM tpl = enif_make_tuple(env, 2,
- enif_make_atom(env,call->func_name),
- enif_make_int(env,call->lib_ver));
- list = enif_make_list_cell(env, tpl, list);
- data->call_history = call->next;
- enif_free(env,call);
+static ERL_NIF_TERM make_new_resource(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
+{
+ NifModPrivData* data = (NifModPrivData*) enif_priv_data(env);
+ ErlNifBinary ibin;
+ char* a;
+ ERL_NIF_TERM ret;
+ unsigned ix;
+ if (!enif_get_uint(env, argv[0], &ix) || ix >= RT_MAX
+ || !enif_inspect_binary(env, argv[1], &ibin)) {
+ return enif_make_badarg(env);
}
- return list;
+ a = enif_alloc_resource(env, data->rt_arr[ix], ibin.size);
+ memcpy(a, ibin.data, ibin.size);
+ ret = enif_make_resource(env, a);
+ enif_release_resource(env, a);
+ return ret;
}
-static ERL_NIF_TERM get_priv_data_ptr(ErlNifEnv* env)
+static ERL_NIF_TERM get_resource(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));
+ NifModPrivData* data = (NifModPrivData*) enif_priv_data(env);
+ ErlNifBinary obin;
+ unsigned ix;
+ void* a;
+ if (!enif_get_uint(env, argv[0], &ix) || ix >= RT_MAX
+ || !enif_get_resource(env, argv[1], data->rt_arr[ix], &a)
+ || !enif_alloc_binary(env, enif_sizeof_resource(env, a), &obin)) {
+ return enif_make_badarg(env);
+ }
+ memcpy(obin.data, a, obin.size);
+ return enif_make_binary(env, &obin);
}
-
static ErlNifFunc nif_funcs[] =
{
{"lib_version", 0, lib_version},
- {"call_history", 0, call_history},
- {"get_priv_data_ptr", 0, get_priv_data_ptr}
+ {"get_priv_data_ptr", 0, get_priv_data_ptr},
+ {"make_new_resource", 2, make_new_resource},
+ {"get_resource", 2, get_resource}
};
#if NIF_LIB_VER != 3
diff --git a/erts/emulator/test/nif_SUITE_data/nif_mod.erl b/erts/emulator/test/nif_SUITE_data/nif_mod.erl
index 93da6590a0..7888a589e7 100644
--- a/erts/emulator/test/nif_SUITE_data/nif_mod.erl
+++ b/erts/emulator/test/nif_SUITE_data/nif_mod.erl
@@ -21,15 +21,19 @@
-include("test_server.hrl").
--export([load_nif_lib/2, start/0, lib_version/0, call_history/0, get_priv_data_ptr/0]).
+-export([load_nif_lib/2, load_nif_lib/3, start/0, lib_version/0, call_history/0,
+ get_priv_data_ptr/0, make_new_resource/2, get_resource/2]).
-export([loop/0, upgrade/1]).
-define(nif_stub,nif_stub_error(?LINE)).
load_nif_lib(Config, Ver) ->
+ load_nif_lib(Config, Ver, []).
+
+load_nif_lib(Config, Ver, LoadInfo) ->
?line Path = ?config(data_dir, Config),
- erlang:load_nif(filename:join(Path,libname(Ver)), 0).
+ erlang:load_nif(filename:join(Path,libname(Ver)), LoadInfo).
libname(no_init) -> libname(3);
libname(Ver) when is_integer(Ver) ->
@@ -59,6 +63,8 @@ lib_version() -> % NIF
call_history() -> ?nif_stub.
get_priv_data_ptr() -> ?nif_stub.
+make_new_resource(_,_) -> ?nif_stub.
+get_resource(_,_) -> ?nif_stub.
nif_stub_error(Line) ->
exit({nif_not_loaded,module,?MODULE,line,Line}).
diff --git a/erts/emulator/test/nif_SUITE_data/nif_mod.h b/erts/emulator/test/nif_SUITE_data/nif_mod.h
index 2dfdc75176..0eaf91d6e1 100644
--- a/erts/emulator/test/nif_SUITE_data/nif_mod.h
+++ b/erts/emulator/test/nif_SUITE_data/nif_mod.h
@@ -4,14 +4,19 @@ typedef struct call_info_t
unsigned lib_ver;
int static_cntA;
int static_cntB;
+ char* arg;
+ int arg_sz;
char func_name[1]; /* must be last */
}CallInfo;
+#define RT_MAX 5
typedef struct
{
+ ErlNifMutex* mtx;
int calls;
int ref_cnt;
CallInfo* call_history;
+ ErlNifResourceType* rt_arr[RT_MAX];
}NifModPrivData;
diff --git a/erts/emulator/test/nif_SUITE_data/tail.txt b/erts/emulator/test/nif_SUITE_data/tail.txt
new file mode 100644
index 0000000000..7f06c118c1
--- /dev/null
+++ b/erts/emulator/test/nif_SUITE_data/tail.txt
@@ -0,0 +1,5 @@
+
+
+#include "tester.c" /* poor mans linker */
+
+
diff --git a/erts/emulator/test/nif_SUITE_data/testcase_driver.h b/erts/emulator/test/nif_SUITE_data/testcase_driver.h
new file mode 100644
index 0000000000..98339e4746
--- /dev/null
+++ b/erts/emulator/test/nif_SUITE_data/testcase_driver.h
@@ -0,0 +1,59 @@
+/* ``The contents of this file are subject to the Erlang Public License,
+ * Version 1.1, (the "License"); you may not use this file except in
+ * compliance with the License. You should have received a copy of the
+ * Erlang Public License along with this software. If not, it can be
+ * retrieved via the world wide web at http://www.erlang.org/.
+ *
+ * Software distributed under the License is distributed on an "AS IS"
+ * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+ * the License for the specific language governing rights and limitations
+ * under the License.
+ *
+ * The Initial Developer of the Original Code is Ericsson Utvecklings AB.
+ * Portions created by Ericsson are Copyright 1999, Ericsson Utvecklings
+ * AB. All Rights Reserved.''
+ *
+ * $Id$
+ */
+
+#ifndef TESTCASE_DRIVER_H__
+#define TESTCASE_DRIVER_H__
+
+#include "erl_nif.h"
+#include <stdlib.h>
+#include <stdio.h>
+
+typedef struct {
+ char *testcase_name;
+ char *command;
+ int command_len;
+ void *extra;
+} TestCaseState_t;
+
+#define ASSERT_CLNUP(TCS, B, CLN) \
+do { \
+ if (!(B)) { \
+ CLN; \
+ testcase_assertion_failed((TCS), __FILE__, __LINE__, #B); \
+ } \
+} while (0)
+
+#define ASSERT(TCS, B) ASSERT_CLNUP(TCS, B, (void) 0)
+
+
+void testcase_printf(TestCaseState_t *tcs, char *frmt, ...);
+void testcase_succeeded(TestCaseState_t *tcs, char *frmt, ...);
+void testcase_skipped(TestCaseState_t *tcs, char *frmt, ...);
+void testcase_failed(TestCaseState_t *tcs, char *frmt, ...);
+int testcase_assertion_failed(TestCaseState_t *tcs, char *file, int line,
+ char *assertion);
+void *testcase_alloc(size_t size);
+void *testcase_realloc(void *ptr, size_t size);
+void testcase_free(void *ptr);
+
+
+char *testcase_name(void);
+void testcase_run(TestCaseState_t *tcs);
+void testcase_cleanup(TestCaseState_t *tcs);
+
+#endif
diff --git a/erts/emulator/test/nif_SUITE_data/tester.c b/erts/emulator/test/nif_SUITE_data/tester.c
new file mode 100644
index 0000000000..08466d0f18
--- /dev/null
+++ b/erts/emulator/test/nif_SUITE_data/tester.c
@@ -0,0 +1,73 @@
+#include "erl_nif.h"
+
+#include <stdio.h>
+#include <stdarg.h>
+
+void testcase_printf(TestCaseState_t *tcs, char *frmt, ...)
+{
+ va_list va;
+ va_start(va, frmt);
+ vfprintf(stderr, frmt, va);
+ va_end(va);
+ fprintf(stderr, "\r");
+}
+
+void testcase_succeeded(TestCaseState_t *tcs, char *frmt, ...)
+{
+}
+
+void testcase_skipped(TestCaseState_t *tcs, char *frmt, ...)
+{
+}
+
+void testcase_failed(TestCaseState_t *tcs, char *frmt, ...)
+{
+ va_list va;
+ va_start(va, frmt);
+ vfprintf(stderr, frmt, va);
+ va_end(va);
+ abort();
+}
+
+int testcase_assertion_failed(TestCaseState_t *tcs, char *file, int line,
+ char *assertion)
+{
+ testcase_failed(tcs, "ASSERTION '%s' FAILED at %s:%d\r\n",
+ assertion, file, line);
+ abort();
+ return 0; /*?*/
+}
+
+void *testcase_alloc(size_t size)
+{
+ return malloc(size);
+}
+void *testcase_realloc(void *ptr, size_t size)
+{
+ return realloc(ptr, size);
+}
+void testcase_free(void *ptr)
+{
+ free(ptr);
+}
+
+void testcase_run(TestCaseState_t *tcs);
+
+static int reload(ErlNifEnv* env, void** priv_data, ERL_NIF_TERM load_info)
+{
+ return 0;
+}
+
+static ERL_NIF_TERM run(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
+{
+ testcase_run(NULL);
+ return enif_make_atom(env, "ok");
+}
+
+static ErlNifFunc nif_funcs[] =
+{
+ {"run", 0, run}
+};
+
+ERL_NIF_INIT(tester,nif_funcs,NULL,reload,NULL,NULL)
+
diff --git a/erts/emulator/test/nif_SUITE_data/tester.erl b/erts/emulator/test/nif_SUITE_data/tester.erl
new file mode 100644
index 0000000000..9df2158200
--- /dev/null
+++ b/erts/emulator/test/nif_SUITE_data/tester.erl
@@ -0,0 +1,13 @@
+-module(tester).
+
+-include("test_server.hrl").
+
+-export([load_nif_lib/2, run/0]).
+
+
+load_nif_lib(Config, LibName) ->
+ ?line Path = ?config(data_dir, Config),
+ erlang:load_nif(filename:join(Path,LibName), []).
+
+run() ->
+ exit({nif_not_loaded,?MODULE,?LINE}).
diff --git a/erts/emulator/test/port_SUITE.erl b/erts/emulator/test/port_SUITE.erl
index 9a09d20eab..b9100738e4 100644
--- a/erts/emulator/test/port_SUITE.erl
+++ b/erts/emulator/test/port_SUITE.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%
%%
@@ -88,7 +88,8 @@
otp_3906/1, otp_4389/1, win_massive/1, win_massive_client/1,
mix_up_ports/1, otp_5112/1, otp_5119/1, otp_6224/1,
exit_status_multi_scheduling_block/1, ports/1,
- spawn_driver/1,spawn_executable/1]).
+ spawn_driver/1,spawn_executable/1,
+ unregister_name/1]).
-export([]).
@@ -112,7 +113,8 @@ all(suite) ->
otp_3906, otp_4389, win_massive, mix_up_ports,
otp_5112, otp_5119,
exit_status_multi_scheduling_block,
- ports, spawn_driver, spawn_executable
+ ports, spawn_driver, spawn_executable,
+ unregister_name
].
-define(DEFAULT_TIMEOUT, ?t:minutes(5)).
@@ -1434,6 +1436,10 @@ spawn_executable(Config) when is_list(Config) ->
?line test_server:timetrap_cancel(Dog),
ok.
+unregister_name(Config) when is_list(Config) ->
+ ?line true = register(crash, open_port({spawn, "sleep 100"}, [])),
+ ?line true = unregister(crash).
+
test_bat_file(Dir) ->
FN = "tf.bat",
Full = filename:join([Dir,FN]),
diff --git a/erts/emulator/test/process_SUITE.erl b/erts/emulator/test/process_SUITE.erl
index fdedf30e78..77f850d0fb 100644
--- a/erts/emulator/test/process_SUITE.erl
+++ b/erts/emulator/test/process_SUITE.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%
%%
@@ -41,7 +41,8 @@
bump_reductions/1, low_prio/1, binary_owner/1, yield/1, yield2/1,
process_status_exiting/1,
otp_4725/1, bad_register/1, garbage_collect/1, otp_6237/1,
- process_info_messages/1, process_flag_badarg/1,
+ process_info_messages/1, process_flag_badarg/1, process_flag_heap_size/1,
+ spawn_opt_heap_size/1,
processes_large_tab/1, processes_default_tab/1, processes_small_tab/1,
processes_this_tab/1, processes_apply_trap/1,
processes_last_call_trap/1, processes_gc_trap/1,
@@ -63,9 +64,8 @@ all(suite) ->
process_info_lock_reschedule, process_info_lock_reschedule2,
process_status_exiting,
bump_reductions, low_prio, yield, yield2, otp_4725, bad_register,
- garbage_collect, process_info_messages, process_flag_badarg, otp_6237,
- processes_bif,
- otp_7738].
+ garbage_collect, process_info_messages, process_flag_badarg, process_flag_heap_size,
+ spawn_opt_heap_size, otp_6237, processes_bif, otp_7738].
init_per_testcase(Func, Config) when is_atom(Func), is_list(Config) ->
Dog=?t:timetrap(?t:minutes(10)),
@@ -388,6 +388,8 @@ t_process_info(Config) when is_list(Config) ->
?line register(my_name, self()),
?line {registered_name, my_name} = process_info(self(), registered_name),
?line {status, running} = process_info(self(), status),
+ ?line {min_heap_size, 233} = process_info(self(), min_heap_size),
+ ?line {min_bin_vheap_size, 46368} = process_info(self(), min_bin_vheap_size),
?line {current_function, {?MODULE, t_process_info, 1}} =
process_info(self(), current_function),
?line Gleader = group_leader(),
@@ -437,6 +439,10 @@ process_info_other_msg(Config) when is_list(Config) ->
empty -> ok
end,
?line {messages,[]} = process_info(Pid, messages),
+
+ ?line {min_heap_size, 233} = process_info(Pid, min_heap_size),
+ ?line {min_bin_vheap_size, 46368} = process_info(Pid, min_bin_vheap_size),
+
?line Pid ! stop,
ok.
@@ -1148,6 +1154,8 @@ process_flag_badarg(Config) when is_list(Config) ->
?line chk_badarg(fun () -> process_flag(trap_exit, gurka) end),
?line chk_badarg(fun () -> process_flag(error_handler, 1) end),
?line chk_badarg(fun () -> process_flag(min_heap_size, gurka) end),
+ ?line chk_badarg(fun () -> process_flag(min_bin_vheap_size, gurka) end),
+ ?line chk_badarg(fun () -> process_flag(min_bin_vheap_size, -1) end),
?line chk_badarg(fun () -> process_flag(priority, 4711) end),
?line chk_badarg(fun () -> process_flag(save_calls, hmmm) end),
?line P= spawn_link(fun () -> receive die -> ok end end),
@@ -1774,6 +1782,34 @@ processes_gc_trap(Config) when is_list(Config) ->
?line exit(Suspendee, bang),
?line ok.
+process_flag_heap_size(doc) ->
+ [];
+process_flag_heap_size(suite) ->
+ [];
+process_flag_heap_size(Config) when is_list(Config) ->
+ HSize = 2584, % must be gc fib number
+ VHSize = 317811, % must be gc fib number
+ ?line OldHmin = erlang:process_flag(min_heap_size, HSize),
+ ?line {min_heap_size, HSize} = erlang:process_info(self(), min_heap_size),
+ ?line OldVHmin = erlang:process_flag(min_bin_vheap_size, VHSize),
+ ?line {min_bin_vheap_size, VHSize} = erlang:process_info(self(), min_bin_vheap_size),
+ ?line HSize = erlang:process_flag(min_heap_size, OldHmin),
+ ?line VHSize = erlang:process_flag(min_bin_vheap_size, OldVHmin),
+ ?line ok.
+
+spawn_opt_heap_size(doc) ->
+ [];
+spawn_opt_heap_size(suite) ->
+ [];
+spawn_opt_heap_size(Config) when is_list(Config) ->
+ HSize = 987, % must be gc fib number
+ VHSize = 46368, % must be gc fib number
+ ?line Pid = spawn_opt(fun () -> receive stop -> ok end end,
+ [{min_heap_size, HSize},{ min_bin_vheap_size, VHSize}]),
+ ?line {min_heap_size, HSize} = process_info(Pid, min_heap_size),
+ ?line {min_bin_vheap_size, VHSize} = process_info(Pid, min_bin_vheap_size),
+ ?line Pid ! stop,
+ ?line ok.
processes_term_proc_list(doc) ->
[];
diff --git a/erts/emulator/test/scheduler_SUITE.erl b/erts/emulator/test/scheduler_SUITE.erl
index e644ad4dc8..c9101b77c2 100644
--- a/erts/emulator/test/scheduler_SUITE.erl
+++ b/erts/emulator/test/scheduler_SUITE.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%
%%
@@ -48,7 +48,8 @@
scheduler_bind_types/1,
cpu_topology/1,
sct_cmd/1,
- sbt_cmd/1]).
+ sbt_cmd/1,
+ scheduler_suspend/1]).
-define(DEFAULT_TIMEOUT, ?t:minutes(10)).
@@ -65,7 +66,8 @@ all(suite) ->
equal_with_high,
equal_with_high_max,
bound_process,
- scheduler_bind].
+ scheduler_bind,
+ scheduler_suspend].
init_per_testcase(Case, Config) when is_list(Config) ->
Dog = ?t:timetrap(?DEFAULT_TIMEOUT),
@@ -882,11 +884,103 @@ sbt_test(Config, CpuTCmd, ClBt, Bt, LP) ->
?line stop_node(Node),
?line ok.
+scheduler_suspend(Config) when is_list(Config) ->
+ ?line Dog = ?t:timetrap(?t:minutes(2)),
+ ?line lists:foreach(fun (S) -> scheduler_suspend_test(Config, S) end,
+ [64, 32, 16, default]),
+ ?line ?t:timetrap_cancel(Dog),
+ ?line ok.
+scheduler_suspend_test(Config, Schedulers) ->
+ ?line Cmd = case Schedulers of
+ default ->
+ "";
+ _ ->
+ S = integer_to_list(Schedulers),
+ "+S"++S++":"++S
+ end,
+ ?line {ok, Node} = start_node(Config, Cmd),
+ ?line [SState] = mcall(Node, [fun () ->
+ erlang:system_info(schedulers_state)
+ end]),
+ ?line {Sched, _, _} = SState,
+ ?line true = is_integer(Sched),
+ ?line [ok] = mcall(Node, [fun () -> sst0_loop(300) end]),
+ ?line [ok] = mcall(Node, [fun () -> sst1_loop(300) end]),
+ ?line [ok] = mcall(Node, [fun () -> sst2_loop(300) end]),
+ ?line [ok, ok, ok, ok, ok] = mcall(Node,
+ [fun () -> sst0_loop(200) end,
+ fun () -> sst1_loop(200) end,
+ fun () -> sst2_loop(200) end,
+ fun () -> sst2_loop(200) end,
+ fun () -> sst3_loop(Sched, 200) end]),
+ ?line [SState] = mcall(Node, [fun () ->
+ erlang:system_info(schedulers_state)
+ end]),
+ ?line stop_node(Node),
+ ?line ok.
+
+
+sst0_loop(0) ->
+ ok;
+sst0_loop(N) ->
+ erlang:system_flag(multi_scheduling, block),
+ erlang:system_flag(multi_scheduling, unblock),
+ erlang:yield(),
+ sst0_loop(N-1).
+
+sst1_loop(0) ->
+ ok;
+sst1_loop(N) ->
+ erlang:system_flag(multi_scheduling, block),
+ erlang:system_flag(multi_scheduling, unblock),
+ sst1_loop(N-1).
+
+sst2_loop(0) ->
+ ok;
+sst2_loop(N) ->
+ erlang:system_flag(multi_scheduling, block),
+ erlang:system_flag(multi_scheduling, block),
+ erlang:system_flag(multi_scheduling, block),
+ erlang:system_flag(multi_scheduling, unblock),
+ erlang:system_flag(multi_scheduling, unblock),
+ erlang:system_flag(multi_scheduling, unblock),
+ sst2_loop(N-1).
+
+sst3_loop(_S, 0) ->
+ ok;
+sst3_loop(S, N) ->
+ erlang:system_flag(schedulers_online, (S div 2)+1),
+ erlang:system_flag(schedulers_online, 1),
+ erlang:system_flag(schedulers_online, (S div 2)+1),
+ erlang:system_flag(schedulers_online, S),
+ erlang:system_flag(schedulers_online, 1),
+ erlang:system_flag(schedulers_online, S),
+ sst3_loop(S, N-1).
+
-%
+%%
%% Utils
%%
+mcall(Node, Funs) ->
+ Parent = self(),
+ Refs = lists:map(fun (Fun) ->
+ Ref = make_ref(),
+ spawn_link(Node,
+ fun () ->
+ Res = Fun(),
+ unlink(Parent),
+ Parent ! {Ref, Res}
+ end),
+ Ref
+ end, Funs),
+ lists:map(fun (Ref) ->
+ receive
+ {Ref, Res} ->
+ Res
+ end
+ end, Refs).
+
erl_rel_flag_var() ->
"ERL_"++erlang:system_info(otp_release)++"_FLAGS".
diff --git a/erts/emulator/test/statistics_SUITE.erl b/erts/emulator/test/statistics_SUITE.erl
index bc12821887..898908c40f 100644
--- a/erts/emulator/test/statistics_SUITE.erl
+++ b/erts/emulator/test/statistics_SUITE.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%
%%
@@ -25,7 +25,7 @@
init_per_testcase/2,
fin_per_testcase/2,
wall_clock/1, wall_clock_zero_diff/1, wall_clock_update/1,
- runtime/1, runtime_zero_diff/1, runtime_zero_update/1,
+ runtime/1, runtime_zero_diff/1,
runtime_update/1, runtime_diff/1,
run_queue/1, run_queue_one/1,
reductions/1, reductions_big/1, garbage_collection/1, io/1,
@@ -99,8 +99,7 @@ wall_clock_update1(0) ->
%%% Test statistics(runtime).
-runtime(suite) -> [runtime_zero_diff, runtime_zero_update, runtime_update,
- runtime_diff].
+runtime(suite) -> [runtime_zero_diff, runtime_update, runtime_diff].
runtime_zero_diff(doc) ->
"Tests that the difference between the times returned from two consectuitive "
@@ -117,55 +116,32 @@ runtime_zero_diff1(N) when N > 0 ->
runtime_zero_diff1(0) ->
?line test_server:fail("statistics(runtime) never returned zero difference").
-runtime_zero_update(doc) ->
- "Test that the time differences returned by two calls to "
- "statistics(runtime) several seconds apart is zero.";
-runtime_zero_update(Config) when is_list(Config) ->
- case ?t:is_debug() of
- false -> ?line runtime_zero_update1(6);
- true -> {skip,"Unreliable in DEBUG build"}
- end.
-
-runtime_zero_update1(N) when N > 0 ->
- ?line {T1, _} = statistics(runtime),
- ?line receive after 7000 -> ok end,
- ?line case statistics(runtime) of
- {T, Td} when Td =< 80 ->
- test_server:format("ok, Runtime before: {~p, _} after: {~p, ~p}",
- [T1, T, Td]),
- ok;
- {T, R} ->
- test_server:format("nok, Runtime before: {~p, _} after: {~p, ~p}",
- [T1, T, R]),
- runtime_zero_update1(N-1)
- end;
-runtime_zero_update1(0) ->
- ?line test_server:fail("statistics(runtime) never returned zero difference").
-
runtime_update(doc) ->
- "Test that the statistics(runtime) returns a substanstially updated difference "
- "after running a process that takes all CPU power of the Erlang process "
- "for a second.";
+ "Test that the statistics(runtime) returns a substanstially "
+ "updated difference after running a process that takes all CPU "
+ " power of the Erlang process for a second.";
runtime_update(Config) when is_list(Config) ->
case ?t:is_cover() of
false ->
?line process_flag(priority, high),
- ?line test_server:m_out_of_n(1, 10, fun runtime_update/0);
+ do_runtime_update(10);
true ->
{skip,"Cover-compiled"}
end.
-runtime_update() ->
- ?line {T1,_} = statistics(runtime),
+do_runtime_update(0) ->
+ {comment,"Never close enough"};
+do_runtime_update(N) ->
+ ?line {T1,Diff0} = statistics(runtime),
?line spawn_link(fun cpu_heavy/0),
receive after 1000 -> ok end,
?line {T2,Diff} = statistics(runtime),
- ?line Delta = abs(Diff-1000),
- ?line test_server:format("T1 = ~p, T2 = ~p, Diff = ~p, abs(Diff-1000) = ~p",
- [T1,T2,Diff,Delta]),
+ ?line true = is_integer(T1+T2+Diff0+Diff),
+ ?line test_server:format("T1 = ~p, T2 = ~p, Diff = ~p, T2-T1 = ~p",
+ [T1,T2,Diff,T2-T1]),
?line if
- abs(Diff-1000) =:= Delta, Delta =< 100 ->
- ok
+ T2 - T1 =:= Diff, 900 =< Diff, Diff =< 1500 -> ok;
+ true -> do_runtime_update(N-1)
end.
cpu_heavy() ->
@@ -212,17 +188,18 @@ reductions(Config) when is_list(Config) ->
%% 300 * 4 is more than CONTEXT_REDS (1000). Thus, there will be one or
%% more context switches.
- reductions(300, Reductions).
+ Mask = (1 bsl erlang:system_info(wordsize)*8) - 1,
+ reductions(300, Reductions, Mask).
-reductions(N, Previous) when N > 0 ->
+reductions(N, Previous, Mask) when N > 0 ->
?line {Reductions, Diff} = statistics(reductions),
?line build_some_garbage(),
?line if Reductions > 0 -> ok end,
?line if Diff >= 0 -> ok end,
io:format("Previous = ~p, Reductions = ~p, Diff = ~p, DiffShouldBe = ~p",
- [Previous, Reductions, Diff, Reductions-Previous]),
- ?line if Reductions == Previous+Diff -> reductions(N-1, Reductions) end;
-reductions(0, _) ->
+ [Previous, Reductions, Diff, (Reductions-Previous) band Mask]),
+ ?line if Reductions == ((Previous+Diff) band Mask) -> reductions(N-1, Reductions, Mask) end;
+reductions(0, _, _) ->
ok.
build_some_garbage() ->
diff --git a/erts/emulator/test/system_info_SUITE.erl b/erts/emulator/test/system_info_SUITE.erl
index 2c7124839a..e782d2f293 100644
--- a/erts/emulator/test/system_info_SUITE.erl
+++ b/erts/emulator/test/system_info_SUITE.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2005-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 2005-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%
%%
@@ -35,12 +35,12 @@
%-compile(export_all).
-export([all/1, init_per_testcase/2, fin_per_testcase/2]).
--export([process_count/1, system_version/1, misc_smoke_tests/1]).
+-export([process_count/1, system_version/1, misc_smoke_tests/1, heap_size/1]).
-define(DEFAULT_TIMEOUT, ?t:minutes(2)).
all(doc) -> [];
-all(suite) -> [process_count, system_version, misc_smoke_tests].
+all(suite) -> [process_count, system_version, misc_smoke_tests, heap_size].
init_per_testcase(_Case, Config) when is_list(Config) ->
Dog = ?t:timetrap(?DEFAULT_TIMEOUT),
@@ -135,8 +135,13 @@ misc_smoke_tests(Config) when is_list(Config) ->
?line ok.
-
-
-
-
+heap_size(doc) -> [];
+heap_size(suite) -> [];
+heap_size(Config) when is_list(Config) ->
+ ?line {min_bin_vheap_size, VHmin} = erlang:system_info(min_bin_vheap_size),
+ ?line {min_heap_size, Hmin} = erlang:system_info(min_heap_size),
+ ?line GCinf = erlang:system_info(garbage_collection),
+ ?line VHmin = proplists:get_value(min_bin_vheap_size, GCinf),
+ ?line Hmin = proplists:get_value(min_heap_size, GCinf),
+ ok.
diff --git a/erts/emulator/test/trace_SUITE.erl b/erts/emulator/test/trace_SUITE.erl
index 2c60ba6838..e9713fcf0f 100644
--- a/erts/emulator/test/trace_SUITE.erl
+++ b/erts/emulator/test/trace_SUITE.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%
%%
@@ -498,19 +498,23 @@ system_monitor_long_gc_1(doc) ->
["Tests erlang:system_monitor(Pid, [{long_gc,Time}])"];
system_monitor_long_gc_1(Config) when is_list(Config) ->
erts_debug:set_internal_state(available_internal_state, true),
- try
- %% Add ?LONG_GC_SLEEP ms to all gc
- ?line erts_debug:set_internal_state(test_long_gc_sleep,
- ?LONG_GC_SLEEP),
- ?line LoadFun =
- fun () ->
- garbage_collect(),
- self()
- end,
- ?line long_gc(LoadFun, false)
+ try
+ case erts_debug:get_internal_state(force_heap_frags) of
+ true ->
+ {skip,"emulator with FORCE_HEAP_FRAGS defined"};
+ false ->
+ %% Add ?LONG_GC_SLEEP ms to all gc
+ ?line erts_debug:set_internal_state(test_long_gc_sleep,
+ ?LONG_GC_SLEEP),
+ ?line LoadFun = fun () ->
+ garbage_collect(),
+ self()
+ end,
+ ?line long_gc(LoadFun, false)
+ end
after
erts_debug:set_internal_state(test_long_gc_sleep, 0),
- erts_debug:set_internal_state(available_internal_state, false)
+ erts_debug:set_internal_state(available_internal_state, false)
end.
system_monitor_long_gc_2(suite) ->
@@ -520,24 +524,29 @@ system_monitor_long_gc_2(doc) ->
system_monitor_long_gc_2(Config) when is_list(Config) ->
erts_debug:set_internal_state(available_internal_state, true),
try
- %% Add ?LONG_GC_SLEEP ms to all gc
- ?line erts_debug:set_internal_state(test_long_gc_sleep,
- ?LONG_GC_SLEEP),
- ?line Parent = self(),
- ?line LoadFun =
- fun () ->
- Ref = make_ref(),
- Pid =
- spawn_link(
- fun () ->
- garbage_collect(),
- Parent ! {Ref, self()}
- end),
- receive {Ref, Pid} -> Pid end
- end,
- ?line long_gc(LoadFun, true),
- ?line long_gc(LoadFun, true),
- ?line long_gc(LoadFun, true)
+ case erts_debug:get_internal_state(force_heap_frags) of
+ true ->
+ {skip,"emulator with FORCE_HEAP_FRAGS defined"};
+ false ->
+ %% Add ?LONG_GC_SLEEP ms to all gc
+ ?line erts_debug:set_internal_state(test_long_gc_sleep,
+ ?LONG_GC_SLEEP),
+ ?line Parent = self(),
+ ?line LoadFun =
+ fun () ->
+ Ref = make_ref(),
+ Pid =
+ spawn_link(
+ fun () ->
+ garbage_collect(),
+ Parent ! {Ref, self()}
+ end),
+ receive {Ref, Pid} -> Pid end
+ end,
+ ?line long_gc(LoadFun, true),
+ ?line long_gc(LoadFun, true),
+ ?line long_gc(LoadFun, true)
+ end
after
erts_debug:set_internal_state(test_long_gc_sleep, 0),
erts_debug:set_internal_state(available_internal_state, false)
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/emulator/zlib/Makefile.in b/erts/emulator/zlib/Makefile.in
index 5c99b460c1..b44a87551d 100644
--- a/erts/emulator/zlib/Makefile.in
+++ b/erts/emulator/zlib/Makefile.in
@@ -14,12 +14,7 @@
# make install prefix=$HOME
ARFLAGS = rc
-ifeq ($(findstring ose,$(TARGET)),ose)
- TYPE_FLAGS =
-else
- TYPE_FLAGS = -O3
-endif
-CFLAGS = @CFLAGS@ @DEFS@ @EMU_THR_DEFS@ $(TYPE_FLAGS)
+CFLAGS = $(subst -O2, -O3, @CFLAGS@ @DEFS@ @EMU_THR_DEFS@)
#CFLAGS=-O -DMAX_WBITS=14 -DMAX_MEM_LEVEL=7
#CFLAGS=-g -DDEBUG
#CFLAGS=-O3 -Wall -Wwrite-strings -Wpointer-arith -Wconversion \
@@ -36,24 +31,15 @@ OBJS = $(O:%=$(OBJDIR)/%)
include $(ERL_TOP)/make/target.mk
-# On windows we need a separate zlib during debug build
-ifeq ($(TARGET),win32)
-
-ifeq ($(TYPE),debug)
-CFLAGS = $(subst -O2, -g, @CFLAGS@ @DEFS@ @DEBUG_FLAGS@)
-endif # debug
-
-else # win32
-
ifeq ($(TYPE),gcov)
-CFLAGS = $(subst -O2, -g, -O0 -fprofile-arcs -ftest-coverage @CFLAGS@ @DEFS@ @DEBUG_FLAGS@)
-TYPE_FLAGS=
+CFLAGS = -O0 -fprofile-arcs -ftest-coverage @DEBUG_CFLAGS@ @DEFS@ @EMU_THR_DEFS@
else # gcov
-# On other platforms we use no special debug version of zlib
+ifeq ($(TYPE),debug)
+CFLAGS = @DEBUG_CFLAGS@ @DEFS@ @EMU_THR_DEFS@
+endif # debug
endif # gcov
-endif # win32
-
+# On windows we *need* a separate zlib during debug build
OBJDIR= $(ERL_TOP)/erts/emulator/zlib/obj/$(TARGET)/$(TYPE)
include $(ERL_TOP)/make/$(TARGET)/otp.mk
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/epmd/test/Makefile b/erts/epmd/test/Makefile
index c1d62f0f93..13dad09ae3 100644
--- a/erts/epmd/test/Makefile
+++ b/erts/epmd/test/Makefile
@@ -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%
#
include $(ERL_TOP)/make/target.mk
@@ -34,6 +34,8 @@ ERL_FILES= $(MODULES:%=%.erl)
TARGET_FILES = $(MODULES:%=$(EBIN)/%.$(EMULATOR))
+EMAKEFILE=Emakefile
+
# ----------------------------------------------------
# Release directory specification
# ----------------------------------------------------
@@ -43,15 +45,17 @@ RELEPMDDIR = $(RELEASE_PATH)/epmd_test
# FLAGS
# ----------------------------------------------------
-ERL_COMPILE_FLAGS += -I$(ERL_TOP)/lib/test_server/include \
- -I$(ERL_TOP)/lib/kernel/src/ \
- $(EPMD_FLAGS)
+ERL_COMPILE_FLAGS += $(EPMD_FLAGS)
# ----------------------------------------------------
# Targets
# ----------------------------------------------------
-tests debug opt: $(TARGET_FILES)
+tests debug opt: $(EMAKEFILE)
+
+$(EMAKEFILE): Makefile $(ERL_FILES)
+ $(ERL_TOP)/make/make_emakefile $(ERL_COMPILE_FLAGS) \
+ -o$(EBIN) $(MODULES) > $(EMAKEFILE)
clean:
rm -f $(TARGET_FILES)
@@ -69,7 +73,7 @@ release_spec:
release_tests_spec: opt
$(INSTALL_DIR) $(RELEPMDDIR)
$(INSTALL_DATA) epmd.spec epmd.spec.vxworks $(ERL_FILES) \
- $(TARGET_FILES) $(RELEPMDDIR)
+ $(EMAKEFILE) $(RELEPMDDIR)
chmod -f -R u+w $(RELEPMDDIR)
release_docs_spec:
diff --git a/erts/epmd/test/epmd_SUITE.erl b/erts/epmd/test/epmd_SUITE.erl
index 513c87a13e..91e09faf75 100644
--- a/erts/epmd/test/epmd_SUITE.erl
+++ b/erts/epmd/test/epmd_SUITE.erl
@@ -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%
%%
-module(epmd_SUITE).
@@ -31,6 +31,9 @@
-define(MEDIUM_PAUSE, ?t:seconds(1)).
-define(LONG_PAUSE, ?t:seconds(5)).
+% Information about nodes
+-record(node_info, {port, node_type, prot, lvsn, hvsn, node_name, extra}).
+
% Test server specific exports
-export([all/1, init_per_testcase/2, fin_per_testcase/2]).
@@ -57,7 +60,10 @@
too_large/1,
alive_req_too_small_1/1,
alive_req_too_small_2/1,
- alive_req_too_large/1
+ alive_req_too_large/1,
+
+ returns_valid_empty_extra/1,
+ returns_valid_populated_extra_with_nulls/1
]).
@@ -76,9 +82,13 @@
-define(REG_REPEAT_LIM,1000).
% Message codes in epmd protocol
--define(EPMD_ALIVE_REQ, $a).
--define(EPMD_ALIVE_OK_RESP, $Y).
--define(EPMD_PORT_REQ, $p).
+-define(EPMD_ALIVE_REQ, $a).
+-define(EPMD_ALIVE2_REQ, $x).
+-define(EPMD_ALIVE_OK_RESP, $Y).
+-define(EPMD_ALIVE2_RESP, $y).
+-define(EPMD_PORT_REQ, $p).
+-define(EPMD_PORT_PLEASE2_REQ, $z).
+-define(EPMD_PORT2_RESP, $w).
-define(EPMD_NAMES_REQ, $n).
-define(EPMD_DUMP_REQ, $d).
-define(EPMD_KILL_REQ, $k).
@@ -111,7 +121,10 @@ all(suite) ->
too_large,
alive_req_too_small_1,
alive_req_too_small_2,
- alive_req_too_large
+ alive_req_too_large,
+
+ returns_valid_empty_extra,
+ returns_valid_populated_extra_with_nulls
].
%%
@@ -182,29 +195,70 @@ register_node(Name) ->
register_node(Name,?DUMMY_PORT).
register_node(Name, Port) ->
- case connect() of
+ case send_req([?EPMD_ALIVE_REQ, put16(Port), Name]) of
{ok,Sock} ->
- M = [?EPMD_ALIVE_REQ, put16(Port), Name],
- case send(Sock, [size16(M), M]) of
- ok ->
- case recv(Sock,3) of
- {ok, [?EPMD_ALIVE_OK_RESP,_D1,_D0]} ->
- {ok,Sock};
- Other ->
- test_server:format("recv on sock ~w: ~p~n",
- [Sock,Other]),
- error
- end;
+ case recv(Sock,3) of
+ {ok, [?EPMD_ALIVE_OK_RESP,_D1,_D0]} ->
+ {ok,Sock};
Other ->
- test_server:format("send on sock ~w: ~w~n",[Sock,Other]),
+ test_server:format("recv on sock ~w: ~p~n",
+ [Sock,Other]),
error
end;
- Other ->
- test_server:format("Connect on port ~w: ~p~n",[Port,Other]),
+ error ->
+ error
+ end.
+
+register_node_v2(Port, NodeType, Prot, HVsn, LVsn, Name, Extra) ->
+ Req = [?EPMD_ALIVE2_REQ, put16(Port), NodeType, Prot,
+ put16(HVsn), put16(LVsn),
+ size16(Name), Name,
+ size16(Extra), Extra],
+ case send_req(Req) of
+ {ok,Sock} ->
+ case recv(Sock,4) of
+ {ok, [?EPMD_ALIVE2_RESP,_Res=0,_C0,_C1]} ->
+ {ok,Sock};
+ Other ->
+ test_server:format("recv on sock ~w: ~p~n",
+ [Sock,Other]),
+ error
+ end;
+ error ->
error
end.
+% Internal function to fetch information about a node
+
+port_please_v2(Name) ->
+ case send_req([?EPMD_PORT_PLEASE2_REQ, Name]) of
+ {ok,Sock} ->
+ case recv_until_sock_closes(Sock) of
+ {ok, Resp} ->
+ parse_port2_resp(Resp);
+ Other ->
+ test_server:format("recv on sock ~w: ~p~n",
+ [Sock,Other]),
+ error
+ end;
+ error ->
+ error
+ end.
+parse_port2_resp(Resp) ->
+ case list_to_binary(Resp) of
+ <<?EPMD_PORT2_RESP,Res,Port:16,NodeType,Prot,HVsn:16,LVsn:16,
+ NLen:16,NodeName:NLen/binary,
+ ELen:16,Extra:ELen/binary>> when Res =:= 0 ->
+ {ok, #node_info{port=Port,node_type=NodeType,prot=Prot,
+ hvsn=HVsn,lvsn=LVsn,
+ node_name=binary_to_list(NodeName),
+ extra=binary_to_list(Extra)}};
+ Other ->
+ test_server:format("invalid port2 resp: ~p~n",
+ [Resp]),
+ error
+ end.
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
@@ -631,6 +685,32 @@ alive_req_too_large(Config) when list(Config) ->
ok.
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+returns_valid_empty_extra(doc) ->
+ ["Check that an empty extra is prefixed by a two byte length"];
+returns_valid_empty_extra(suite) ->
+ [];
+returns_valid_empty_extra(Config) when list(Config) ->
+ ?line ok = epmdrun(),
+ ?line {ok,Sock} = register_node_v2(4711, 72, 0, 5, 5, "foo", []),
+ ?line {ok,#node_info{extra=[]}} = port_please_v2("foo"),
+ ?line ok = close(Sock),
+ ok.
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+returns_valid_populated_extra_with_nulls(doc) ->
+ ["Check a populated extra with embedded null characters"];
+returns_valid_populated_extra_with_nulls(suite) ->
+ [];
+returns_valid_populated_extra_with_nulls(Config) when list(Config) ->
+ ?line ok = epmdrun(),
+ ?line {ok,Sock} = register_node_v2(4711, 72, 0, 5, 5, "foo", "ABC\000\000"),
+ ?line {ok,#node_info{extra="ABC\000\000"}} = port_please_v2("foo"),
+ ?line ok = close(Sock),
+ ok.
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Terminate all tests with killing epmd.
cleanup() ->
@@ -813,6 +893,36 @@ send_direct(Sock, Bytes) ->
Any
end.
+send_req(Req) ->
+ case connect() of
+ {ok,Sock} ->
+ case send(Sock, [size16(Req), Req]) of
+ ok ->
+ {ok,Sock};
+ Other ->
+ test_server:format("Failed to send ~w on sock ~w: ~w~n",
+ [Req,Sock,Other]),
+ error
+ end;
+ Other ->
+ test_server:format("Connect failed when sending ~w: ~p~n",
+ [Req, Other]),
+ error
+ end.
+
+recv_until_sock_closes(Sock) ->
+ recv_until_sock_closes_2(Sock,[]).
+
+recv_until_sock_closes_2(Sock,AccData) ->
+ case recv(Sock,0) of
+ {ok,Data} ->
+ recv_until_sock_closes_2(Sock,AccData++Data);
+ closed ->
+ {ok,AccData};
+ Other ->
+ Other
+ end.
+
sleep(MilliSeconds) ->
timer:sleep(MilliSeconds).
diff --git a/erts/etc/common/Makefile.in b/erts/etc/common/Makefile.in
index a9acab640e..20c4c3c2b1 100644
--- a/erts/etc/common/Makefile.in
+++ b/erts/etc/common/Makefile.in
@@ -1,19 +1,19 @@
#
# %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
# 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%
#
@@ -61,6 +61,9 @@ LD = @LD@
LIBS = @LIBS@
LDFLAGS = @LDFLAGS@
+# For clock_gettime in heart
+RTLIBS = @LIBRT@
+
ifeq ($(TARGET),win32)
ifeq ($(TYPE),debug)
CFLAGS = $(subst -O2,-g,@CFLAGS@ @DEFS@ $(TYPE_FLAGS) @WFLAGS@ -I$(SYSDIR) \
@@ -359,12 +362,9 @@ $(OBJDIR)/escript.o: escript.c
ifeq ($(TARGET),win32)
-$(BINDIR)/$(ERLEXEC): $(OBJDIR)/erlexec.o $(OBJDIR)/win_erlexec.o $(OBJDIR)/init_file.o $(OBJDIR)/$(ERLRES_OBJ) dbg
+$(BINDIR)/$(ERLEXEC): $(OBJDIR)/erlexec.o $(OBJDIR)/win_erlexec.o $(OBJDIR)/init_file.o $(OBJDIR)/$(ERLRES_OBJ)
$(LD) -dll $(LDFLAGS) -o $@ $(OBJDIR)/erlexec.o $(OBJDIR)/win_erlexec.o $(OBJDIR)/init_file.o $(OBJDIR)/$(ERLRES_OBJ) $(ERLEXEC_XLIBS)
-dbg:
- echo DBG
-
$(BINDIR)/erl@EXEEXT@: $(OBJDIR)/erl.o $(OBJDIR)/init_file.o $(OBJDIR)/$(ERLRES_OBJ)
$(LD) $(LDFLAGS) -o $@ $(OBJDIR)/erl.o $(OBJDIR)/init_file.o $(OBJDIR)/$(ERLRES_OBJ)
@@ -462,7 +462,7 @@ else
$(BINDIR)/heart@EXEEXT@: $(OBJDIR)/heart.o $(ENTRY_OBJ)
$(LD) $(LDFLAGS) $(ENTRY_LDFLAGS) -o $@ $(OBJDIR)/heart.o \
- $(ENTRY_OBJ) $(WINDSOCK)
+ $(RTLIBS) $(ENTRY_OBJ) $(WINDSOCK)
$(OBJDIR)/heart.o: heart.c
$(CC) $(CFLAGS) -o $@ -c heart.c
diff --git a/erts/etc/common/dialyzer.c b/erts/etc/common/dialyzer.c
index 9c66be7f0f..4b4c1124f1 100644
--- a/erts/etc/common/dialyzer.c
+++ b/erts/etc/common/dialyzer.c
@@ -141,6 +141,7 @@ main(int argc, char** argv)
int eargc_base; /* How many arguments in the base of eargv. */
char* emulator;
char *env;
+ int i;
int need_shell = 0;
env = get_env("DIALYZER_EMULATOR");
@@ -167,9 +168,11 @@ main(int argc, char** argv)
* Push initial arguments.
*/
- if (argc > 1 && strcmp(argv[1], "--wx") == 0) {
- PUSH2("-smp", "--wx"); /* wx currently requires SMP enabled */
- argc--, argv++;
+ for (i = 1; i < argc; i++) {
+ if (strcmp(argv[i], "--wx") == 0) {
+ PUSH("-smp"); /* wx currently requires SMP enabled */
+ break;
+ }
}
if (argc > 1 && strcmp(argv[1], "-smp") == 0) {
diff --git a/erts/etc/common/erlc.c b/erts/etc/common/erlc.c
index c958fed741..09aca19e6c 100644
--- a/erts/etc/common/erlc.c
+++ b/erts/etc/common/erlc.c
@@ -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%
*/
/*
@@ -310,6 +310,8 @@ main(int argc, char** argv)
case 'W': /* Enable warnings. */
if (strcmp(argv[1]+2, "all") == 0) {
PUSH2("@warn", "999");
+ } else if (strcmp(argv[1]+2, "error") == 0) {
+ PUSH2("@option", "warnings_as_errors");
} else if (isdigit((int)argv[1][2])) {
PUSH2("@warn", argv[1]+2);
} else {
@@ -566,6 +568,7 @@ usage(void)
{"-pz path", "add path to the end of Erlang's code path"},
{"-smp", "compile using SMP emulator"},
{"-v", "verbose compiler output"},
+ {"-Werror", "make all warnings into errors"},
{"-W0", "disable warnings"},
{"-Wnumber", "set warning level to number"},
{"-Wall", "enable all warnings"},
diff --git a/erts/etc/common/erlexec.c b/erts/etc/common/erlexec.c
index 4325418e7c..f79f5cc978 100644
--- a/erts/etc/common/erlexec.c
+++ b/erts/etc/common/erlexec.c
@@ -1,19 +1,19 @@
/*
* %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
* 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%
*/
@@ -123,6 +123,14 @@ static char *pluss_val_switches[] = {
"ss",
NULL
};
+/* +h arguments with values */
+static char *plush_val_switches[] = {
+ "ms",
+ "mbs",
+ "",
+ NULL
+};
+
/*
* Define sleep(seconds) in terms of Sleep() on Windows.
@@ -783,10 +791,10 @@ int main(int argc, char **argv)
case 'a':
case 'A':
case 'b':
- case 'h':
case 'i':
case 'P':
case 'S':
+ case 't':
case 'T':
case 'R':
case 'W':
@@ -850,6 +858,20 @@ int main(int argc, char **argv)
goto the_default;
break;
}
+ case 'h':
+ if (!is_one_of_strings(&argv[i][2], plush_val_switches)) {
+ goto the_default;
+ } else {
+ if (i+1 >= argc
+ || argv[i+1][0] == '-'
+ || argv[i+1][0] == '+')
+ usage(argv[i]);
+ argv[i][0] = '-';
+ add_Eargs(argv[i]);
+ add_Eargs(argv[i+1]);
+ i++;
+ }
+ break;
case 's':
if (!is_one_of_strings(&argv[i][2],
pluss_val_switches))
@@ -1048,7 +1070,7 @@ usage_aux(void)
#endif
"[-make] [-man [manopts] MANPAGE] [-x] [-emu_args] "
"[-args_file FILENAME] "
- "[+A THREADS] [+a SIZE] [+B[c|d|i]] [+c] [+h HEAP_SIZE] [+K BOOLEAN] "
+ "[+A THREADS] [+a SIZE] [+B[c|d|i]] [+c] [+h HEAP_SIZE_OPTION] [+K BOOLEAN] "
"[+l] [+M<SUBSWITCH> <ARGUMENT>] [+P MAX_PROCS] [+R COMPAT_REL] "
"[+r] [+s SCHEDULER_OPTION] [+S NO_SCHEDULERS:NO_SCHEDULERS_ONLINE] [+T LEVEL] [+V] [+v] [+W<i|w>] "
"[args ...]\n");
diff --git a/erts/etc/common/escript.c b/erts/etc/common/escript.c
index ab37d4af46..1bc5eb7651 100644
--- a/erts/etc/common/escript.c
+++ b/erts/etc/common/escript.c
@@ -1,19 +1,19 @@
/*
* %CopyrightBegin%
- *
- * Copyright Ericsson AB 2007-2009. All Rights Reserved.
- *
+ *
+ * Copyright Ericsson AB 2007-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%
*/
/*
@@ -199,9 +199,10 @@ find_prog(char *origpath)
continue;
} else {
/* Wow we found the executable. */
- strcpy(abspath, wildcard);
+ strcpy(relpath, wildcard);
FindClose(dir_handle);
- return strsave(abspath);
+ look_for_sep = FALSE;
+ break;
}
#else
dp = opendir(dir);
@@ -216,11 +217,12 @@ find_prog(char *origpath)
if (strcmp(origpath, dirp->d_name) == 0) {
/* Wow we found the executable. */
- strcpy(abspath, dir);
- strcat(abspath, DIRSEPSTR);
- strcat(abspath, dirp->d_name);
+ strcpy(relpath, dir);
+ strcat(relpath, DIRSEPSTR);
+ strcat(relpath, dirp->d_name);
closedir(dp);
- return strsave(abspath);
+ look_for_sep = FALSE;
+ break;
}
}
}
@@ -239,8 +241,8 @@ find_prog(char *origpath)
#else
if (!realpath(relpath, abspath)) {
#endif /* __WIN32__ */
- /* Cannot determine absolute path to escript. Try the relative. */
- return strsave(relpath);
+ /* Cannot determine absolute path to escript. Try the origin. */
+ return strsave(origpath);
} else {
return strsave(abspath);
}
@@ -373,11 +375,10 @@ main(int argc, char** argv)
if (strcmp(basename, "escript") == 0) {
#endif
/*
- * Push all options (without the hyphen) before the script name.
+ * Locate all options before the script name.
*/
while (argc > 1 && argv[1][0] == '-') {
- PUSH(argv[1]+1);
argc--;
argv++;
last_opt = argv;
@@ -402,6 +403,7 @@ main(int argc, char** argv)
scriptname[len-4] = '\0';
}
#endif
+
strcat(scriptname, ".escript");
}
@@ -418,7 +420,7 @@ main(int argc, char** argv)
PUSH3("-run", "escript", "start");
/*
- * Push all options (without the hyphen) before the script name.
+ * Push all options before the script name. But omit the leading hyphens.
*/
while (first_opt != last_opt) {
@@ -500,7 +502,7 @@ char *make_commandline(char **argv)
*(--p) = '\0';
if (debug) {
- printf("Processed commandline:%s\n",buff);
+ printf("Processed command line:%s\n",buff);
}
return buff;
}
diff --git a/erts/etc/common/heart.c b/erts/etc/common/heart.c
index 4f738947b7..c1f6551d21 100644
--- a/erts/etc/common/heart.c
+++ b/erts/etc/common/heart.c
@@ -102,9 +102,6 @@
* that can simulate gethrtime with clock_gettime, no use implementing
* a phony gethrtime in this file as the time questions are so infrequent.
*/
-#if defined(CORRET_USING_TIMES) || defined(GETHRTIME_WITH_CLOCK_GETTIME)
-# define HEART_CORRECT_USING_TIMES 1
-#endif
#include <stdio.h>
#include <stddef.h>
@@ -134,7 +131,7 @@
# include <sys/time.h>
# include <unistd.h>
# include <signal.h>
-# if defined(HEART_CORRECT_USING_TIMES)
+# if defined(CORRECT_USING_TIMES)
# include <sys/times.h>
# include <limits.h>
# endif
@@ -446,7 +443,8 @@ message_loop(erlin_fd, erlout_fd)
*/
timestamp(&now);
if (now > last_received + heart_beat_timeout) {
- print_error("heart-beat time-out.");
+ print_error("heart-beat time-out, no activity for %lu seconds",
+ (unsigned long) (now - last_received));
return R_TIMEOUT;
}
/*
@@ -1072,7 +1070,31 @@ time_t timestamp(time_t *res)
return r;
}
-#elif defined(HAVE_GETHRTIME)
+#elif defined(HAVE_GETHRTIME) || defined(GETHRTIME_WITH_CLOCK_GETTIME)
+
+#if defined(GETHRTIME_WITH_CLOCK_GETTIME)
+typedef long long SysHrTime;
+
+SysHrTime sys_gethrtime(void);
+
+SysHrTime sys_gethrtime(void)
+{
+ struct timespec ts;
+ long long result;
+ if (clock_gettime(CLOCK_MONOTONIC,&ts) != 0) {
+ print_error("Fatal, could not get clock_monotonic value, terminating! "
+ "errno = %d\n", errno);
+ exit(1);
+ }
+ result = ((long long) ts.tv_sec) * 1000000000LL +
+ ((long long) ts.tv_nsec);
+ return (SysHrTime) result;
+}
+#else
+typedef hrtime_t SysHrTime;
+#define sys_gethrtime() gethrtime()
+#endif
+
void init_timestamp(void)
{
@@ -1080,14 +1102,14 @@ void init_timestamp(void)
time_t timestamp(time_t *res)
{
- hrtime_t ht = gethrtime();
+ SysHrTime ht = sys_gethrtime();
time_t r = (time_t) (ht / 1000000000);
if (res != NULL)
*res = r;
return r;
}
-#elif defined(HEART_CORRECT_USING_TIMES)
+#elif defined(CORRECT_USING_TIMES)
# ifdef NO_SYSCONF
# include <sys/param.h>
diff --git a/erts/etc/unix/Install.src b/erts/etc/unix/Install.src
index 410a77d91c..83f9690782 100644
--- a/erts/etc/unix/Install.src
+++ b/erts/etc/unix/Install.src
@@ -1,25 +1,26 @@
#!/bin/sh
#
# %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
# 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%
-#
-# Patch $ERL_ROOT/emulator/obj/Makefile.dist & make
#
+# %CopyrightEnd%
#
+usage="
+Usage:
+ Install [-cross] [-minimal|-sasl] <ERL_ROOT>
+"
start_option=query
unset cross
while [ $# -ne 0 ]; do
@@ -42,7 +43,8 @@ fi
if [ -z "$ERL_ROOT" -o ! -d "$ERL_ROOT" ]
then
- echo "Install: need ERL_ROOT directory as argument"
+ echo "Install: need <ERL_ROOT> directory as argument" >&2
+ echo $usage >&2
exit 1
fi
@@ -50,15 +52,17 @@ case ":$ERL_ROOT" in
:/*)
;;
*)
- echo "Install: need an absolute path to ERL_ROOT"
+ echo "Install: need an absolute path to <ERL_ROOT>" >&2
+ echo $usage >&2
exit 1
;;
esac
if [ ! -d "$ERL_ROOT/erts-%I_VSN%/bin" ]
then
- echo "Install: The directory $ERL_ROOT/erts-%I_VSN%/bin does not exist"
- echo " Bad location or erts module not un-tared"
+ echo "Install: The directory $ERL_ROOT/erts-%I_VSN%/bin does not exist" >&2
+ echo " Bad location or erts module not un-tared" >&2
+ echo $usage >&2
exit 1
fi
@@ -67,20 +71,6 @@ then
mkdir $ERL_ROOT/bin
fi
-#
-# Fetch target system.
-#
-SYS=`(uname -s) 2>/dev/null` || SYS=unknown
-REL=`(uname -r) 2>/dev/null` || REL=unknown
-case $SYS:$REL in
- SunOS:5.*)
- TARGET=sunos5 ;;
- Linux:*)
- TARGET=linux ;;
- *)
- TARGET="" ;;
-esac
-
cd $ERL_ROOT/erts-%I_VSN%/bin
sed -e "s;%FINAL_ROOTDIR%;$TARGET_ERL_ROOT;" erl.src > erl
@@ -111,7 +101,7 @@ if [ -h epmd ]; then
/bin/rm -f epmd
fi
-ln -s $TARGET_ERL_ROOT/erts-%I_VSN%/bin/epmd epmd
+ln -s ../erts-%I_VSN%/bin/epmd epmd
cp -p $ERL_ROOT/erts-%I_VSN%/bin/run_erl .
cp -p $ERL_ROOT/erts-%I_VSN%/bin/to_erl .
@@ -150,19 +140,6 @@ cp -p $Name.boot start.boot
cp -p ../releases/%I_SYSTEM_VSN%/$Name.script start.script
#
-# We always run ranlib unless Solaris/SunOS 5
-# but ignore failures.
-#
-if [ "X$TARGET" != "Xsunos5" -a -d $ERL_ROOT/usr/lib ]; then
- cd $ERL_ROOT/usr/lib
- for library in lib*.a
- do
- (ranlib $library) > /dev/null 2>&1
- done
-fi
-
-
-#
# Fixing the man pages
#
@@ -172,4 +149,4 @@ then
./misc/format_man_pages $ERL_ROOT
fi
-
+exit 0
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/example/matrix_nif.c b/erts/example/matrix_nif.c
new file mode 100644
index 0000000000..c5e01dade5
--- /dev/null
+++ b/erts/example/matrix_nif.c
@@ -0,0 +1,210 @@
+/*
+ * %CopyrightBegin%
+ *
+ * Copyright Ericsson AB 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%
+ */
+/*
+ * Purpose: Simple example of NIFs using resource objects to implement functions
+ * for matrix calculations.
+ */
+
+#include "erl_nif.h"
+
+#include <stddef.h>
+#include <assert.h>
+
+typedef struct
+{
+ unsigned nrows;
+ unsigned ncols;
+ double* data;
+}Matrix;
+
+#define POS(MX, ROW, COL) ((MX)->data[(ROW)* (MX)->ncols + (COL)])
+
+static int get_number(ErlNifEnv* env, ERL_NIF_TERM term, double* dp);
+static Matrix* alloc_matrix(ErlNifEnv* env, unsigned nrows, unsigned ncols);
+static void matrix_dtor(ErlNifEnv* env, void* obj);
+
+
+static ErlNifResourceType* resource_type = NULL;
+
+static int load(ErlNifEnv* env, void** priv_data, ERL_NIF_TERM load_info)
+{
+ ErlNifResourceType* rt = enif_open_resource_type(env, "matrix_nif_example",
+ matrix_dtor,
+ ERL_NIF_RT_CREATE, NULL);
+ if (rt == NULL) {
+ return -1;
+ }
+ assert(resource_type == NULL);
+ resource_type = rt;
+ return 0;
+}
+
+static ERL_NIF_TERM create(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
+{
+ /* create(Nrows, Ncolumns, [[first row],[second row],...,[last row]]) -> Matrix */
+ unsigned nrows, ncols;
+ unsigned i, j;
+ ERL_NIF_TERM list, row, ret;
+ Matrix* mx = NULL;
+
+ if (!enif_get_uint(env, argv[0], &nrows) || nrows < 1 ||
+ !enif_get_uint(env, argv[1], &ncols) || ncols < 1) {
+
+ goto badarg;
+ }
+ mx = alloc_matrix(env, nrows, ncols);
+ list = argv[2];
+ for (i = 0; i<nrows; i++) {
+ if (!enif_get_list_cell(env, list, &row, &list)) {
+ goto badarg;
+ }
+ for (j = 0; j<ncols; j++) {
+ ERL_NIF_TERM v;
+ if (!enif_get_list_cell(env, row, &v, &row) ||
+ !get_number(env, v, &POS(mx,i,j))) {
+ goto badarg;
+ }
+ }
+ if (!enif_is_empty_list(env, row)) {
+ goto badarg;
+ }
+ }
+ if (!enif_is_empty_list(env, list)) {
+ goto badarg;
+ }
+
+ ret = enif_make_resource(env, mx);
+ enif_release_resource(env, mx);
+ return ret;
+
+badarg:
+ if (mx != NULL) {
+ enif_release_resource(env,mx);
+ }
+ return enif_make_badarg(env);
+}
+
+
+static ERL_NIF_TERM pos(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
+{
+ /* pos(Matrix, Row, Column) -> float() */
+ Matrix* mx;
+ unsigned i, j;
+ if (!enif_get_resource(env, argv[0], resource_type, (void**)&mx) ||
+ !enif_get_uint(env, argv[1], &i) || (--i >= mx->nrows) ||
+ !enif_get_uint(env, argv[2], &j) || (--j >= mx->ncols)) {
+ return enif_make_badarg(env);
+ }
+ return enif_make_double(env, POS(mx, i,j));
+}
+
+static ERL_NIF_TERM add(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
+{
+ /* add(Matrix_A, Matrix_B) -> Matrix_Sum */
+ unsigned i, j;
+ ERL_NIF_TERM ret;
+ Matrix* mxA = NULL;
+ Matrix* mxB = NULL;
+ Matrix* mxS = NULL;
+
+ if (!enif_get_resource(env, argv[0], resource_type, (void**)&mxA) ||
+ !enif_get_resource(env, argv[1], resource_type, (void**)&mxB) ||
+ mxA->nrows != mxB->nrows ||
+ mxB->ncols != mxB->ncols) {
+
+ return enif_make_badarg(env);
+ }
+ mxS = alloc_matrix(env, mxA->nrows, mxA->ncols);
+ for (i = 0; i < mxA->nrows; i++) {
+ for (j = 0; j < mxA->ncols; j++) {
+ POS(mxS, i, j) = POS(mxA, i, j) + POS(mxB, i, j);
+ }
+ }
+ ret = enif_make_resource(env, mxS);
+ enif_release_resource(env, mxS);
+ return ret;
+}
+
+static ERL_NIF_TERM size_of(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
+{
+ /* size(Matrix) -> {Nrows, Ncols} */
+ Matrix* mx;
+ if (!enif_get_resource(env, argv[0], resource_type, (void**)&mx)) {
+ return enif_make_badarg(env);
+ }
+ return enif_make_tuple2(env, enif_make_uint(env, mx->nrows),
+ enif_make_uint(env, mx->ncols));
+}
+
+static ERL_NIF_TERM to_term(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
+{
+ /* to_term(Matrix) -> [[first row], [second row], ...,[last row]] */
+ unsigned i, j;
+ ERL_NIF_TERM res;
+ Matrix* mx = NULL;
+
+ if (!enif_get_resource(env, argv[0], resource_type, (void**)&mx)) {
+ return enif_make_badarg(env);
+ }
+ res = enif_make_list(env, 0);
+ for (i = mx->nrows; i-- > 0; ) {
+ ERL_NIF_TERM row = enif_make_list(env, 0);
+ for (j = mx->ncols; j-- > 0; ) {
+ row = enif_make_list_cell(env, enif_make_double(env, POS(mx,i,j)),
+ row);
+ }
+ res = enif_make_list_cell(env, row, res);
+ }
+ return res;
+}
+
+static int get_number(ErlNifEnv* env, ERL_NIF_TERM term, double* dp)
+{
+ long i;
+ return enif_get_double(env, term, dp) ||
+ (enif_get_long(env, term, &i) && (*dp=(double)i, 1));
+}
+
+static Matrix* alloc_matrix(ErlNifEnv* env, unsigned nrows, unsigned ncols)
+{
+ Matrix* mx = enif_alloc_resource(env, resource_type, sizeof(Matrix));
+ mx->nrows = nrows;
+ mx->ncols = ncols;
+ mx->data = enif_alloc(env, nrows*ncols*sizeof(double));
+ return mx;
+}
+
+static void matrix_dtor(ErlNifEnv* env, void* obj)
+{
+ Matrix* mx = (Matrix*) obj;
+ enif_free(env, mx->data);
+ mx->data = NULL;
+}
+
+static ErlNifFunc nif_funcs[] =
+{
+ {"create", 3, create},
+ {"pos", 3, pos},
+ {"add", 2, add},
+ {"size_of", 1, size_of},
+ {"to_term", 1, to_term}
+};
+
+ERL_NIF_INIT(matrix_nif,nif_funcs,load,NULL,NULL,NULL);
+
diff --git a/erts/example/matrix_nif.erl b/erts/example/matrix_nif.erl
new file mode 100644
index 0000000000..9008977e01
--- /dev/null
+++ b/erts/example/matrix_nif.erl
@@ -0,0 +1,44 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 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%
+%%
+
+%%
+%% Purpose: Simple example of NIFs using resource objects to implement functions
+%% for matrix calculations.
+
+-module(matrix_nif).
+
+-export([create/3, pos/3, add/2, size_of/1, to_term/1]).
+
+-define(nif, nif_error(?LINE)).
+
+-on_load(on_load/0).
+
+on_load() ->
+ erlang:load_nif("./matrix_nif", 0).
+
+%% NIFs
+create(_Rows, _Cols, _RowList) -> ?nif.
+pos(_Mx, _Row, _Col) -> ?nif.
+add(_MxA, _MxB) -> ?nif.
+size_of(_Mx) -> ?nif.
+to_term(_Mx) -> ?nif.
+
+nif_error(Line) ->
+ erlang:error({"NIF not implemented in matrix_nif at line", Line}).
+
diff --git a/erts/include/internal/tile/atomic.h b/erts/include/internal/tile/atomic.h
index 0622b53729..59a9250e7c 100644
--- a/erts/include/internal/tile/atomic.h
+++ b/erts/include/internal/tile/atomic.h
@@ -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%
*/
@@ -84,13 +84,13 @@ ethr_native_atomic_add_return(ethr_native_atomic_t *var, long incr)
static ETHR_INLINE long
ethr_native_atomic_inc_return(ethr_native_atomic_t *var)
{
- return ethr_native_atomic_add_return(&var->counter, 1);
+ return ethr_native_atomic_add_return(var, 1);
}
static ETHR_INLINE long
ethr_native_atomic_dec_return(ethr_native_atomic_t *var)
{
- return ethr_native_atomic_add_return(&var->counter, -1);
+ return ethr_native_atomic_add_return(var, -1);
}
static ETHR_INLINE long
diff --git a/erts/lib_src/Makefile.in b/erts/lib_src/Makefile.in
index ce5c846677..49f5b1f048 100644
--- a/erts/lib_src/Makefile.in
+++ b/erts/lib_src/Makefile.in
@@ -1,19 +1,19 @@
#
# %CopyrightBegin%
-#
-# Copyright Ericsson AB 2004-2009. All Rights Reserved.
-#
+#
+# Copyright Ericsson AB 2004-2010. All Rights Reserved.
+#
# The contents of this file are subject to the Erlang Public License,
# Version 1.1, (the "License"); you may not use this file except in
# compliance with the License. You should have received a copy of the
# Erlang Public License along with this software. If not, it can be
# retrieved online at http://www.erlang.org/.
-#
+#
# Software distributed under the License is distributed on an "AS IS"
# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
# the License for the specific language governing rights and limitations
# under the License.
-#
+#
# %CopyrightEnd%
#
@@ -483,6 +483,8 @@ ifneq ($(strip $(INTERNAL_RELEASE_LIBS)),)
$(INSTALL_DATA) $(INTERNAL_RELEASE_LIBS) $(RELSYSDIR)/lib/internal
endif
+docs:
+
release_docs_spec:
diff --git a/erts/preloaded/ebin/erl_prim_loader.beam b/erts/preloaded/ebin/erl_prim_loader.beam
index a031c90188..304ac41dce 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..21e5525b2f 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..8ccc553c13 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..8ae73ea9a7 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..3acda843fd 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..9457b6d360 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..6837cb4661 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..4e4f85d312 100644
--- a/erts/preloaded/ebin/zlib.beam
+++ b/erts/preloaded/ebin/zlib.beam
Binary files differ
diff --git a/erts/preloaded/src/erl_prim_loader.erl b/erts/preloaded/src/erl_prim_loader.erl
index 399c2bb55d..a13292d5ab 100644
--- a/erts/preloaded/src/erl_prim_loader.erl
+++ b/erts/preloaded/src/erl_prim_loader.erl
@@ -1,19 +1,19 @@
%%
%% %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
%% 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%
%%
@@ -49,24 +49,27 @@
prim_read_file_info/2, prim_get_cwd/2]).
%% Used by escript and code
--export([set_primary_archive/2, release_archives/0]).
-
-%% Internal function. Exported to avoid dialyzer warnings
--export([concat/1]).
+-export([set_primary_archive/3, release_archives/0]).
-include_lib("kernel/include/file.hrl").
-type host() :: atom().
+-record(prim_state, {debug :: boolean(),
+ cache,
+ primary_archive}).
+-type prim_state() :: #prim_state{}.
+
-record(state,
- {loader :: 'efile' | 'inet',
- hosts = [] :: [host()], % hosts list (to boot from)
+ {loader :: 'efile' | 'inet',
+ hosts = [] :: [host()], % hosts list (to boot from)
id, % not used any more?
- data, % data port etc
- timeout, % idle timeout
- n_timeouts, % Number of timeouts before archives are released
- multi_get = false :: boolean(),
- prim_state}). % state for efile code loader
+ data :: 'noport' | port(), % data port etc
+ timeout :: timeout(), % idle timeout
+ %% Number of timeouts before archives are released
+ n_timeouts :: non_neg_integer(),
+ multi_get = false :: boolean(),
+ prim_state :: prim_state()}). % state for efile code loader
-define(IDLE_TIMEOUT, 60000). %% tear inet connection after 1 minutes
-define(N_TIMEOUTS, 6). %% release efile archive after 6 minutes
@@ -89,8 +92,6 @@
end
end()).
--record(prim_state, {debug, cache, primary_archive}).
-
debug(#prim_state{debug = Deb}, Term) ->
case Deb of
false -> ok;
@@ -124,7 +125,7 @@ start(Id, Pgm0, Hosts) ->
start_it("ose_inet"=Cmd, Id, Pid, Hosts) ->
%% Setup reserved port for ose_inet driver (only OSE)
- case catch erlang:open_port({spawn,Cmd},[binary]) of
+ case catch erlang:open_port({spawn,Cmd}, [binary]) of
{'EXIT',Why} ->
?dbg(ose_inet_port_open_fail, Why),
Why;
@@ -220,14 +221,15 @@ get_cwd(Drive) ->
check_file_result(get_cwd, Drive, request({get_cwd,[Drive]})).
-spec set_primary_archive(File :: string() | 'undefined',
- ArchiveBin :: binary() | 'undefined')
- -> {ok, [string()]} | {error,_}.
+ ArchiveBin :: binary() | 'undefined',
+ FileInfo :: #file_info{} | 'undefined')
+ -> {ok, [string()]} | {error,_}.
-set_primary_archive(undefined, undefined) ->
- request({set_primary_archive, undefined, undefined});
-set_primary_archive(File, ArchiveBin)
- when is_list(File), is_binary(ArchiveBin) ->
- request({set_primary_archive, File, ArchiveBin}).
+set_primary_archive(undefined, undefined, undefined) ->
+ request({set_primary_archive, undefined, undefined, undefined});
+set_primary_archive(File, ArchiveBin, FileInfo)
+ when is_list(File), is_binary(ArchiveBin), is_record(FileInfo, file_info) ->
+ request({set_primary_archive, File, ArchiveBin, FileInfo}).
-spec release_archives() -> 'ok' | {'error', _}.
@@ -315,8 +317,8 @@ loop(State, Parent, Paths) ->
{get_cwd,[_]=Args} ->
{Res,State1} = handle_get_cwd(State, Args),
{Res,State1,Paths};
- {set_primary_archive,File,Bin} ->
- {Res,State1} = handle_set_primary_archive(State, File, Bin),
+ {set_primary_archive,File,Bin,FileInfo} ->
+ {Res,State1} = handle_set_primary_archive(State, File, Bin, FileInfo),
{Res,State1,Paths};
release_archives ->
{Res,State1} = handle_release_archives(State),
@@ -325,7 +327,7 @@ loop(State, Parent, Paths) ->
{ignore,State,Paths}
end,
if Resp =:= ignore -> ok;
- true -> Pid ! {self(),Resp}
+ true -> Pid ! {self(),Resp}, ok
end,
if
is_record(State2, state) ->
@@ -334,7 +336,7 @@ loop(State, Parent, Paths) ->
exit({bad_state, Req, State2})
end;
{'EXIT',Parent,W} ->
- handle_stop(State),
+ _State1 = handle_stop(State),
exit(W);
{'EXIT',P,W} ->
State1 = handle_exit(State, P, W),
@@ -356,8 +358,8 @@ handle_get_file(State = #state{loader = efile}, Paths, File) ->
handle_get_file(State = #state{loader = inet}, Paths, File) ->
?SAFE2(inet_get_file_from_port(State, File, Paths), State).
-handle_set_primary_archive(State= #state{loader = efile}, File, Bin) ->
- ?SAFE2(efile_set_primary_archive(State, File, Bin), State).
+handle_set_primary_archive(State= #state{loader = efile}, File, Bin, FileInfo) ->
+ ?SAFE2(efile_set_primary_archive(State, File, Bin, FileInfo), State).
handle_release_archives(State= #state{loader = efile}) ->
?SAFE2(efile_release_archives(State), State).
@@ -481,8 +483,8 @@ efile_get_file_from_port3(State, File, [P | Paths]) ->
efile_get_file_from_port3(State, _File, []) ->
{{error,enoent},State}.
-efile_set_primary_archive(#state{prim_state = PS} = State, File, Bin) ->
- {Res, PS2} = prim_set_primary_archive(PS, File, Bin),
+efile_set_primary_archive(#state{prim_state = PS} = State, File, Bin, FileInfo) ->
+ {Res, PS2} = prim_set_primary_archive(PS, File, Bin, FileInfo),
{Res,State#state{prim_state = PS2}}.
efile_release_archives(#state{prim_state = PS} = State) ->
@@ -572,13 +574,14 @@ find_loop(U, Retry, AL, ReqDelay, SReSleep, Ignore, Tries, LReSleep) ->
case find_loop(U, Retry, AL, ReqDelay, []) of
[] -> % no response from any server
erlang:display({erl_prim_loader,'no server found'}), % lifesign
- Tries1 = if Tries > 0 ->
- sleep(SReSleep),
- Tries - 1;
- true ->
- sleep(LReSleep),
- 0
- end,
+ Tries1 =
+ if Tries > 0 ->
+ sleep(SReSleep),
+ Tries - 1;
+ true ->
+ sleep(LReSleep),
+ 0
+ end,
find_loop(U, Retry, AL, ReqDelay, SReSleep, Ignore, Tries1, LReSleep);
Servers ->
keysort(1, Servers -- Ignore)
@@ -603,7 +606,6 @@ find_collect(U,Retry,AL,Delay,Acc) ->
_Garbage ->
?dbg(collect_garbage, _Garbage),
find_collect(U, Retry, AL, Delay, Acc)
-
after Delay ->
?dbg(collected, Acc),
case keymember(0, 1, Acc) of %% got high priority server?
@@ -617,7 +619,7 @@ sleep(Time) ->
receive after Time -> ok end.
inet_exit_port(State, Port, _Reason) when State#state.data =:= Port ->
- State#state { data = noport, timeout = infinity };
+ State#state{data = noport, timeout = infinity};
inet_exit_port(State, _, _) ->
State.
@@ -627,7 +629,7 @@ inet_timeout_handler(State, _Parent) ->
if is_port(Tcp) -> ll_close(Tcp);
true -> ok
end,
- State#state { timeout = infinity, data = noport }.
+ State#state{timeout = infinity, data = noport}.
%% -> {{ok,BinFile,Tag},State} | {{error,Reason},State}
inet_get_file_from_port(State, File, Paths) ->
@@ -657,9 +659,9 @@ inet_get_file_from_port1(_File, [], State) ->
inet_send_and_rcv(Msg, Tag, State) when State#state.data =:= noport ->
{ok,Tcp} = find_master(State#state.hosts), %% reconnect
- inet_send_and_rcv(Msg, Tag, State#state { data = Tcp,
- timeout = ?IDLE_TIMEOUT });
-inet_send_and_rcv(Msg, Tag, #state{data=Tcp,timeout=Timeout}=State) ->
+ inet_send_and_rcv(Msg, Tag, State#state{data = Tcp,
+ timeout = ?IDLE_TIMEOUT});
+inet_send_and_rcv(Msg, Tag, #state{data = Tcp, timeout = Timeout} = State) ->
prim_inet:send(Tcp, term_to_binary(Msg)),
receive
{tcp,Tcp,BinMsg} ->
@@ -677,13 +679,13 @@ inet_send_and_rcv(Msg, Tag, #state{data=Tcp,timeout=Timeout}=State) ->
end;
{tcp_closed,Tcp} ->
%% Ok we must reconnect
- inet_send_and_rcv(Msg, Tag, State#state { data = noport });
+ inet_send_and_rcv(Msg, Tag, State#state{data = noport});
{tcp_error,Tcp,_Reason} ->
%% Ok we must reconnect
inet_send_and_rcv(Msg, Tag, inet_stop_port(State));
{'EXIT', Tcp, _} ->
%% Ok we must reconnect
- inet_send_and_rcv(Msg, Tag, State#state { data = noport })
+ inet_send_and_rcv(Msg, Tag, State#state{data = noport})
after Timeout ->
%% Ok we must reconnect
inet_send_and_rcv(Msg, Tag, inet_stop_port(State))
@@ -770,6 +772,7 @@ port_error(S, Error) ->
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+-spec prim_init() -> prim_state().
prim_init() ->
Deb =
case init:get_argument(loader_debug) of
@@ -777,19 +780,19 @@ prim_init() ->
error -> false
end,
cache_new(#prim_state{debug = Deb}).
-
+
prim_release_archives(PS) ->
debug(PS, release_archives),
- {Res, PS2}= prim_do_release_archives(PS, get(), []),
+ {Res, PS2} = prim_do_release_archives(PS, get(), []),
debug(PS2, {return, Res}),
{Res, PS2}.
prim_do_release_archives(PS, [{ArchiveFile, DictVal} | KeyVals], Acc) ->
Res =
case DictVal of
- {primary, _PrimZip} ->
+ {primary, _PrimZip, _FI} ->
ok; % Keep primary archive
- {_Mtime, Cache} ->
+ {Cache, _FI} ->
debug(PS, {release, cache, ArchiveFile}),
erase(ArchiveFile),
clear_cache(ArchiveFile, Cache)
@@ -805,7 +808,7 @@ prim_do_release_archives(PS, [], []) ->
prim_do_release_archives(PS, [], Errors) ->
{{error, Errors}, PS#prim_state{primary_archive = undefined}}.
-prim_set_primary_archive(PS, undefined, undefined) ->
+prim_set_primary_archive(PS, undefined, undefined, undefined) ->
debug(PS, {set_primary_archive, clean}),
case PS#prim_state.primary_archive of
undefined ->
@@ -813,14 +816,14 @@ prim_set_primary_archive(PS, undefined, undefined) ->
debug(PS, {return, Res}),
{Res, PS};
ArchiveFile ->
- {primary, PrimZip} = erase(ArchiveFile),
+ {primary, PrimZip, _FI} = erase(ArchiveFile),
ok = prim_zip:close(PrimZip),
PS2 = PS#prim_state{primary_archive = undefined},
Res = {ok, []},
debug(PS2, {return, Res}),
{Res, PS2}
end;
-prim_set_primary_archive(PS, ArchiveFile, ArchiveBin)
+prim_set_primary_archive(PS, ArchiveFile, ArchiveBin, #file_info{} = FileInfo)
when is_list(ArchiveFile), is_binary(ArchiveBin) ->
%% Try the archive file
debug(PS, {set_primary_archive, ArchiveFile, byte_size(ArchiveBin)}),
@@ -833,17 +836,17 @@ prim_set_primary_archive(PS, ArchiveFile, ArchiveBin)
["", "nibe", RevApp] -> % Reverse ebin
%% Collect ebin directories in archive
Ebin = reverse(RevApp) ++ "/ebin",
- {true, [Ebin | A]};
+ {true, [Ebin | A]};
_ ->
{true, A}
end
end,
Ebins0 = [ArchiveFile],
- case open_archive({ArchiveFile, ArchiveBin}, Ebins0, Fun) of
- {ok, PrimZip, RevEbins} ->
+ case open_archive({ArchiveFile, ArchiveBin}, FileInfo, Ebins0, Fun) of
+ {ok, PrimZip, {RevEbins, FI, _}} ->
Ebins = reverse(RevEbins),
debug(PS, {set_primary_archive, Ebins}),
- put(ArchiveFile, {primary, PrimZip}),
+ put(ArchiveFile, {primary, PrimZip, FI}),
{{ok, Ebins}, PS#prim_state{primary_archive = ArchiveFile}};
Error ->
debug(PS, {set_primary_archive, Error}),
@@ -851,14 +854,15 @@ prim_set_primary_archive(PS, ArchiveFile, ArchiveBin)
end;
OldArchiveFile ->
debug(PS, {set_primary_archive, clean}),
- PrimZip = erase(OldArchiveFile),
+ {primary, PrimZip, _FI} = erase(OldArchiveFile),
ok = prim_zip:close(PrimZip),
PS2 = PS#prim_state{primary_archive = undefined},
- prim_set_primary_archive(PS2, ArchiveFile, ArchiveBin)
+ prim_set_primary_archive(PS2, ArchiveFile, ArchiveBin, FileInfo)
end,
debug(PS3, {return, Res3}),
{Res3, PS3}.
+-spec prim_get_file(prim_state(), file:filename()) -> {_, prim_state()}.
prim_get_file(PS, File) ->
debug(PS, {get_file, File}),
{Res2, PS2} =
@@ -883,7 +887,9 @@ prim_get_file(PS, File) ->
debug(PS, {return, Res2}),
{Res2, PS2}.
-%% -> {{ok,List},State} | {{error,Reason},State}
+-spec prim_list_dir(prim_state(), file:filename()) ->
+ {{'ok', [file:filename()]}, prim_state()}
+ | {{'error', term()}, prim_state()}.
prim_list_dir(PS, Dir) ->
debug(PS, {list_dir, Dir}),
{Res2, PS3} =
@@ -934,7 +940,9 @@ prim_list_dir(PS, Dir) ->
debug(PS, {return, Res2}),
{Res2, PS3}.
-%% -> {{ok,Info},State} | {{error,Reason},State}
+-spec prim_read_file_info(prim_state(), file:filename()) ->
+ {{'ok', #file_info{}}, prim_state()}
+ | {{'error', term()}, prim_state()}.
prim_read_file_info(PS, File) ->
debug(PS, {read_file_info, File}),
{Res2, PS2} =
@@ -956,15 +964,15 @@ prim_read_file_info(PS, File) ->
FunnyFile = funny_split(FileInArchive, $/),
Fun =
fun({Funny, GetInfo, _GetBin}, Acc) ->
- if
- hd(Funny) =:= "",
- tl(Funny) =:= FunnyFile ->
+ case Funny of
+ [H | T] when H =:= "",
+ T =:= FunnyFile ->
%% Directory
{false, {ok, GetInfo()}};
- Funny =:= FunnyFile ->
+ F when F =:= FunnyFile ->
%% Plain file
{false, {ok, GetInfo()}};
- true ->
+ _ ->
%% No match
{true, Acc}
end
@@ -974,6 +982,8 @@ prim_read_file_info(PS, File) ->
debug(PS2, {return, Res2}),
{Res2, PS2}.
+-spec prim_get_cwd(prim_state(), [file:filename()]) ->
+ {{'error', term()} | {'ok', _}, prim_state()}.
prim_get_cwd(PS, []) ->
debug(PS, {get_cwd, []}),
Res = prim_file:get_cwd(),
@@ -990,33 +1000,36 @@ prim_get_cwd(PS, [Drive]) ->
apply_archive(PS, Fun, Acc, Archive) ->
case get(Archive) of
undefined ->
+ case open_archive(Archive, Acc, Fun) of
+ {ok, PrimZip, {Acc2, FI, _}} ->
+ debug(PS, {cache, ok}),
+ put(Archive, {{ok, PrimZip}, FI}),
+ {Acc2, PS};
+ Error ->
+ debug(PS, {cache, Error}),
+ %% put(Archive, {Error, FI}),
+ {Error, PS}
+ end;
+ {primary, PrimZip, FI} ->
+ case prim_file:read_file_info(Archive) of
+ {ok, FI2}
+ when FI#file_info.mtime =:= FI2#file_info.mtime ->
+ case foldl_archive(PrimZip, Acc, Fun) of
+ {ok, _PrimZip2, Acc2} ->
+ {Acc2, PS};
+ Error ->
+ debug(PS, {primary, Error}),
+ {Error, PS}
+ end;
+ Error ->
+ debug(PS, {cache, {clear, Error}}),
+ clear_cache(Archive, {ok, PrimZip}),
+ apply_archive(PS, Fun, Acc, Archive)
+ end;
+ {Cache, FI} ->
case prim_file:read_file_info(Archive) of
- {ok, #file_info{mtime = Mtime}} ->
- case open_archive(Archive, Acc, Fun) of
- {ok, PrimZip, Acc2} ->
- debug(PS, {cache, ok}),
- put(Archive, {Mtime, {ok, PrimZip}}),
- {Acc2, PS};
- Error ->
- debug(PS, {cache, Error}),
- put(Archive, {Mtime, Error}),
- {Error, PS}
- end;
- Error ->
- debug(PS, {cache, Error}),
- {Error, PS}
- end;
- {primary, PrimZip} ->
- case foldl_archive(PrimZip, Acc, Fun) of
- {ok, _PrimZip2, Acc2} ->
- {Acc2, PS};
- Error ->
- debug(PS, {primary, Error}),
- {Error, PS}
- end;
- {Mtime, Cache} ->
- case prim_file:read_file_info(Archive) of
- {ok, #file_info{mtime = Mtime2}} when Mtime2 =:= Mtime ->
+ {ok, FI2}
+ when FI#file_info.mtime =:= FI2#file_info.mtime ->
case Cache of
{ok, PrimZip} ->
case foldl_archive(PrimZip, Acc, Fun) of
@@ -1024,9 +1037,10 @@ apply_archive(PS, Fun, Acc, Archive) ->
{Acc2, PS};
Error ->
debug(PS, {cache, {clear, Error}}),
- clear_cache(Archive, Cache),
+ ok = clear_cache(Archive, Cache),
debug(PS, {cache, Error}),
- put(Archive, {Mtime, Error}),
+ erase(Archive),
+ %% put(Archive, {Error, FI}),
{Error, PS}
end;
Error ->
@@ -1035,26 +1049,63 @@ apply_archive(PS, Fun, Acc, Archive) ->
end;
Error ->
debug(PS, {cache, {clear, Error}}),
- clear_cache(Archive, Cache),
+ ok = clear_cache(Archive, Cache),
apply_archive(PS, Fun, Acc, Archive)
end
end.
open_archive(Archive, Acc, Fun) ->
+ case prim_file:read_file_info(Archive) of
+ {ok, FileInfo} ->
+ open_archive(Archive, FileInfo, Acc, Fun);
+ {error, Reason} ->
+ {error, Reason}
+ end.
+
+open_archive(Archive, FileInfo, Acc, Fun) ->
+ FakeFI = FileInfo#file_info{type = directory},
Wrapper =
- fun({N, GI, GB}, A) ->
- %% Ensure full iteration at open
- Funny = funny_split(N, $/),
- {_Continue, A2} = Fun({Funny, GI, GB}, A),
- {true, {true, Funny}, A2}
- end,
- prim_zip:open(Wrapper, Acc, Archive).
+ fun({N, GI, GB}, {A, I, FunnyDirs}) -> % Full iteration at open
+ Funny = funny_split(N, $/),
+ FunnyDirs2 =
+ case Funny of
+ ["" | FunnyDir] ->
+ [FunnyDir | FunnyDirs];
+ _ ->
+ FunnyDirs
+ end,
+ {Includes, FunnyDirs3, A2} =
+ ensure_virtual_dirs(Funny, Fun, FakeFI, [{true, Funny}], FunnyDirs2, A),
+ {_Continue, A3} = Fun({Funny, GI, GB}, A2),
+ {true, Includes, {A3, I, FunnyDirs3}}
+ end,
+ prim_zip:open(Wrapper, {Acc, FakeFI, []}, Archive).
+
+ensure_virtual_dirs(Funny, Fun, FakeFI, Includes, FunnyDirs, Acc) ->
+ case Funny of
+ [_ | FunnyDir] ->
+ case lists:member(FunnyDir, FunnyDirs) of % BIF
+ false ->
+ GetInfo = fun() -> FakeFI end,
+ GetBin = fun() -> <<>> end,
+ VirtualDir = ["" | FunnyDir],
+ Includes2 = [{true, VirtualDir, GetInfo, GetBin} | Includes],
+ FunnyDirs2 = [FunnyDir | FunnyDirs],
+ {I, F, Acc2} = ensure_virtual_dirs(FunnyDir, Fun, FakeFI, Includes2, FunnyDirs2, Acc),
+ {_Continue, Acc3} = Fun({VirtualDir, GetInfo, GetBin}, Acc2),
+ {I, F, Acc3};
+ true ->
+ {reverse(Includes), FunnyDirs, Acc}
+ end;
+ [] ->
+ {reverse(Includes), FunnyDirs, Acc}
+ end.
foldl_archive(PrimZip, Acc, Fun) ->
Wrapper =
- fun({N, GI, GB}, A) ->
+ fun({Funny, GI, GB}, A) ->
%% Allow partial iteration at foldl
- {Continue, A2} = Fun({N, GI, GB}, A),
+ {Continue, A2} = Fun({Funny, GI, GB}, A),
{Continue, true, A2}
end,
prim_zip:foldl(Wrapper, Acc, PrimZip).
@@ -1100,8 +1151,8 @@ send_all(U, [IP | AL], Cmd) ->
send_all(U, AL, Cmd);
send_all(_U, [], _) -> ok.
-concat([A|T]) when is_atom(A) -> %Atom
- atom_to_list(A) ++ concat(T);
+%%concat([A|T]) when is_atom(A) -> %Atom
+%% atom_to_list(A) ++ concat(T);
concat([C|T]) when C >= 0, C =< 255 ->
[C|concat(T)];
concat([S|T]) -> %String
diff --git a/erts/preloaded/src/erlang.erl b/erts/preloaded/src/erlang.erl
index 6f92b319b7..1edb5e72db 100644
--- a/erts/preloaded/src/erlang.erl
+++ b/erts/preloaded/src/erlang.erl
@@ -1,19 +1,19 @@
%%
%% %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
%% 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(erlang).
@@ -29,39 +29,39 @@
-export([send_nosuspend/2, send_nosuspend/3]).
-export([localtime_to_universaltime/1]).
-export([suspend_process/1]).
--export([min/2,max/2]).
-
+-export([min/2, max/2]).
-export([dlink/1, dunlink/1, dsend/2, dsend/3, dgroup_leader/2,
dexit/2, dmonitor_node/3, dmonitor_p/2]).
-
-export([delay_trap/2]).
-
-export([set_cookie/2, get_cookie/0]).
-
-export([nodes/0]).
-
-export([concat_binary/1]).
-
-export([list_to_integer/2,integer_to_list/2]).
-
-export([flush_monitor_message/2]).
-
-export([set_cpu_topology/1, format_cpu_topology/1]).
-
-export([await_proc_exit/3]).
-deprecated([hash/2]).
+-deprecated([concat_binary/1]).
-compile(nowarn_bif_clash).
+%%--------------------------------------------------------------------------
+
+-type date() :: {pos_integer(), pos_integer(), pos_integer()}.
+-type time() :: {non_neg_integer(), non_neg_integer(), non_neg_integer()}.
+-type date_time() :: {date(), time()}.
+
+%%--------------------------------------------------------------------------
+
apply(Fun, Args) ->
apply(Fun, Args).
apply(Mod, Name, Args) ->
apply(Mod, Name, Args).
+%% Spawns with a fun
-% Spawns with a fun
spawn(F) when is_function(F) ->
spawn(erlang, apply, [F, []]);
spawn({M,F}=MF) when is_atom(M), is_atom(F) ->
@@ -124,7 +124,7 @@ spawn_opt(N, {M,F}=MF, O) when is_atom(M), is_atom(F) ->
spawn_opt(N, F, O) ->
erlang:error(badarg, [N, F, O]).
-% Spawns with MFA
+%% Spawns with MFA
spawn(N,M,F,A) when N =:= node(), is_atom(M), is_atom(F), is_list(A) ->
spawn(M,F,A);
@@ -253,12 +253,17 @@ crasher(Node,Mod,Fun,Args,Opts,Reason) ->
[Mod,Fun,Args,Opts,Node]),
exit(Reason).
+-spec yield() -> 'true'.
yield() ->
erlang:yield().
-nodes() -> erlang:nodes(visible).
+-spec nodes() -> [node()].
+nodes() ->
+ erlang:nodes(visible).
-disconnect_node(Node) -> net_kernel:disconnect(Node).
+-spec disconnect_node(node()) -> boolean().
+disconnect_node(Node) ->
+ net_kernel:disconnect(Node).
fun_info(Fun) when is_function(Fun) ->
Keys = [type,env,arity,name,uniq,index,new_uniq,new_index,module,pid],
@@ -284,9 +289,11 @@ send_nosuspend(Pid, Msg, Opts) ->
_ -> false
end.
+-spec localtime_to_universaltime(date_time()) -> date_time().
localtime_to_universaltime(Localtime) ->
erlang:localtime_to_universaltime(Localtime, undefined).
+-spec suspend_process(pid()) -> 'true'.
suspend_process(P) ->
case catch erlang:suspend_process(P, []) of
{'EXIT', {Reason, _}} -> erlang:error(Reason, [P]);
@@ -297,10 +304,11 @@ suspend_process(P) ->
%%
%% If the emulator wants to perform a distributed command and
%% a connection is not established to the actual node the following
-%% functions is called in order to set up the connection and then
+%% functions are called in order to set up the connection and then
%% reactivate the command.
%%
+-spec dlink(pid() | port()) -> 'true'.
dlink(Pid) ->
case net_kernel:connect(node(Pid)) of
true -> link(Pid);
@@ -308,6 +316,7 @@ dlink(Pid) ->
end.
%% Can this ever happen?
+-spec dunlink(identifier()) -> 'true'.
dunlink(Pid) ->
case net_kernel:connect(node(Pid)) of
true -> unlink(Pid);
@@ -321,7 +330,7 @@ dmonitor_node(Node, Flag, []) ->
end;
dmonitor_node(Node, Flag, Opts) ->
- case lists:member(allow_passive_connect,Opts) of
+ case lists:member(allow_passive_connect, Opts) of
true ->
case net_kernel:passive_cnct(Node) of
true -> erlang:monitor_node(Node, Flag, Opts);
@@ -377,11 +386,11 @@ dsend({Name, Node}, Msg, Opts) ->
ignored -> ok % Not distributed.
end.
+-spec dmonitor_p('process', pid() | {atom(),atom()}) -> reference().
dmonitor_p(process, ProcSpec) ->
%% ProcSpec = pid() | {atom(),atom()}
%% ProcSpec CANNOT be an atom because a locally registered process
%% is never handled here.
-
Node = case ProcSpec of
{S,N} when is_atom(S), is_atom(N), N =/= node() -> N;
_ when is_pid(ProcSpec) -> node(ProcSpec)
@@ -399,6 +408,7 @@ dmonitor_p(process, ProcSpec) ->
%% Trap function used when modified timing has been enabled.
%%
+-spec delay_trap(Result, timeout()) -> Result.
delay_trap(Result, 0) -> erlang:yield(), Result;
delay_trap(Result, Timeout) -> receive after Timeout -> Result end.
@@ -422,13 +432,15 @@ set_cookie(Node, C) when Node =/= nonode@nohost, is_atom(Node) ->
error -> exit(badarg);
Other -> Other
end.
-
+
+-spec get_cookie() -> atom().
get_cookie() ->
auth:get_cookie().
concat_binary(List) ->
list_to_binary(List).
+-spec integer_to_list(integer(), 1..255) -> string().
integer_to_list(I, 10) ->
erlang:integer_to_list(I);
integer_to_list(I, Base)
@@ -456,7 +468,6 @@ integer_to_list(I0, Base, R0) ->
end.
-
list_to_integer(L, 10) ->
erlang:list_to_integer(L);
list_to_integer(L, Base)
@@ -661,6 +672,7 @@ rvrs([X|Xs],Ys) -> rvrs(Xs, [X|Ys]).
%% functions in bif.c. Do not make
%% any changes to it without reading
%% the comment about them in bif.c!
+-spec await_proc_exit(dst(), 'apply' | 'data' | 'reason', term()) -> term().
await_proc_exit(Proc, Op, Data) ->
Mon = erlang:monitor(process, Proc),
receive
@@ -676,8 +688,10 @@ await_proc_exit(Proc, Op, Data) ->
end
end.
+-spec min(term(), term()) -> term().
min(A, B) when A > B -> B;
min(A, _) -> A.
+-spec max(term(), term()) -> term().
max(A, B) when A < B -> B;
max(A, _) -> A.
diff --git a/erts/preloaded/src/init.erl b/erts/preloaded/src/init.erl
index c6f4c62f63..3b98b9cddc 100644
--- a/erts/preloaded/src/init.erl
+++ b/erts/preloaded/src/init.erl
@@ -1,19 +1,19 @@
%%
%% %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
%% 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%
%%
%%
@@ -51,7 +51,7 @@
get_status/0,boot/1,get_arguments/0,get_plain_arguments/0,
get_argument/1,script_id/0]).
-% internal exports
+%% internal exports
-export([fetch_loaded/0,ensure_loaded/1,make_permanent/2,
notify_when_started/1,wait_until_started/0,
objfile_extension/0, archive_extension/0,code_path_choice/0]).
@@ -115,6 +115,8 @@ fetch_loaded() ->
ensure_loaded(Module) ->
request({ensure_loaded, Module}).
+-spec make_permanent(file:filename(), 'false' | file:filename()) ->
+ 'ok' | {'error', term()}.
make_permanent(Boot,Config) ->
request({make_permanent,Boot,Config}).
@@ -1357,10 +1359,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/erts/preloaded/src/otp_ring0.erl b/erts/preloaded/src/otp_ring0.erl
index 3b0d562d1f..2ccf142f30 100644
--- a/erts/preloaded/src/otp_ring0.erl
+++ b/erts/preloaded/src/otp_ring0.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2000-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 2000-2010. All Rights Reserved.
+%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
-%%
+%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
-%%
+%%
%% %CopyrightEnd%
%%
-module(otp_ring0).
@@ -22,6 +22,7 @@
-export([start/2]).
+-spec start(_, term()) -> term().
start(_Env, Argv) ->
run(init, boot, Argv).
diff --git a/erts/preloaded/src/prim_zip.erl b/erts/preloaded/src/prim_zip.erl
index 17ef8c6c43..3f5a5b9721 100644
--- a/erts/preloaded/src/prim_zip.erl
+++ b/erts/preloaded/src/prim_zip.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%
%%
@@ -94,12 +94,7 @@ do_foldl(FilterFun, FilterAcc, [PF | Tail], Acc0, PrimZip, PrimZipOrig) ->
#primzip_file{name = F, get_info = GetInfo, get_bin = GetBin} = PF,
case FilterFun({F, GetInfo, GetBin}, FilterAcc) of
{Continue, Include, FilterAcc2} ->
- Acc1 =
- case Include of
- false -> Acc0;
- true -> [PF | Acc0];
- {true, Nick} -> [PF#primzip_file{name = Nick} | Acc0]
- end,
+ Acc1 = include_acc(Include, PF, Acc0),
case Continue of
true ->
do_foldl(FilterFun, FilterAcc2, Tail, Acc1, PrimZip, PrimZipOrig);
@@ -112,6 +107,28 @@ do_foldl(FilterFun, FilterAcc, [PF | Tail], Acc0, PrimZip, PrimZipOrig) ->
do_foldl(_FilterFun, FilterAcc, [], Acc, PrimZip, _PrimZipOrig) ->
{ok, FilterAcc, PrimZip#primzip{files = reverse(Acc)}}.
+include_acc(Include, PF, Acc) ->
+ case Include of
+ false ->
+ Acc;
+ true ->
+ [PF | Acc];
+ {true, Nick} ->
+ [PF#primzip_file{name = Nick} | Acc];
+ {true, Nick, GetInfo, GetBin} ->
+ PF2 = #primzip_file{name = Nick, get_info = GetInfo, get_bin = GetBin},
+ [PF2 | Acc];
+ List when is_list(List) ->
+ %% Add new entries
+ Fun = fun(I, A) -> include_acc(I, PF, A) end,
+ lists_foldl(Fun, Acc, List)
+ end.
+
+lists_foldl(F, Accu, [Hd|Tail]) ->
+ lists_foldl(F, F(Hd, Accu), Tail);
+lists_foldl(F, Accu, []) when is_function(F, 2) ->
+ Accu.
+
%% close a zip archive
close(#primzip{in = In0, input = Input, zlib = Z}) ->
Input(close, In0),
@@ -199,15 +216,25 @@ get_cd_loop(N, BCD, Acc0, PrimZip, FileName, Offset, CFH, EndOffset, FilterFun,
end,
%% erlang:display({FileName, N, Offset, Size, NextPF}),
GetInfo = fun() -> cd_file_header_to_file_info(FileName, CFH, <<>>) end,
- GetBin = fun() -> get_z_file(FileName, Offset, Size, PrimZip) end,
+ GetBin = fun() -> get_z_file(FileName, Offset, Size, PrimZip) end,
PF = #primzip_file{name = FileName, get_info = GetInfo, get_bin = GetBin},
case FilterFun({FileName, GetInfo, GetBin}, FilterAcc) of
{Continue, Include, FilterAcc2} ->
Acc1 =
case Include of
- false -> Acc0;
- true -> [PF | Acc0];
- {true, Nick} -> [PF#primzip_file{name = Nick} | Acc0]
+ false ->
+ Acc0;
+ true ->
+ [PF | Acc0];
+ {true, Nick} ->
+ [PF#primzip_file{name = Nick} | Acc0];
+ {true, Nick, GI, GB} ->
+ PF2 = #primzip_file{name = Nick, get_info = GI, get_bin = GB},
+ [PF2 | Acc0];
+ List when is_list(List) ->
+ %% Add new entries
+ Fun = fun(I, A) -> include_acc(I, PF, A) end,
+ lists_foldl(Fun, Acc0, List)
end,
case Continue of
true when N > 1 ->
diff --git a/erts/preloaded/src/zlib.erl b/erts/preloaded/src/zlib.erl
index 21971a75cf..51d6cd0a0b 100644
--- a/erts/preloaded/src/zlib.erl
+++ b/erts/preloaded/src/zlib.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2003-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 2003-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%
%%
@@ -115,7 +115,6 @@
%%------------------------------------------------------------------------
%% Main data types of the file
--type(iodata() :: iolist() | binary()). %XXX To be removed in R13B.
-type zstream() :: port().
%% Auxiliary data types of the file
diff --git a/erts/start_scripts/Makefile b/erts/start_scripts/Makefile
index 862f7285bc..4df7568484 100644
--- a/erts/start_scripts/Makefile
+++ b/erts/start_scripts/Makefile
@@ -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%
#
include $(ERL_TOP)/make/target.mk
@@ -74,13 +74,13 @@ $(SS_ROOT)/start_clean.script \
$(SS_ROOT)/start_clean.boot: $(SS_ROOT)/start_clean.rel
$(INSTALL_DIR) $(SS_TMP)
( cd $(SS_TMP) && \
- $(ERLC) $(SASL_FLAGS) $(SCRIPT_PATH) -o $@ $< )
+ $(ERLC) $(SASL_FLAGS) $(SCRIPT_PATH) -o $(SS_ROOT) $< )
$(SS_ROOT)/start_sasl.script \
$(SS_ROOT)/start_sasl.boot: $(SS_ROOT)/start_sasl.rel
$(INSTALL_DIR) $(SS_TMP)
( cd $(SS_TMP) && \
- $(ERLC) $(SASL_FLAGS) $(SCRIPT_PATH) -o $@ $< )
+ $(ERLC) $(SASL_FLAGS) $(SCRIPT_PATH) -o $(SS_ROOT) $< )
$(SS_ROOT)/start_clean.rel: $(SS_ROOT)/start_clean.rel.src \
../vsn.mk \
diff --git a/erts/test/Makefile b/erts/test/Makefile
index 47e41a3625..796403e182 100644
--- a/erts/test/Makefile
+++ b/erts/test/Makefile
@@ -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%
#
@@ -29,6 +29,7 @@ EBIN = .
MODULES= \
erlc_SUITE \
+ install_SUITE \
nt_SUITE \
otp_SUITE \
ethread_SUITE \
@@ -42,6 +43,8 @@ ERL_FILES= $(MODULES:%=%.erl)
TARGET_FILES = $(MODULES:%=$(EBIN)/%.$(EMULATOR))
+EXTRA_FILES = install_SUITE_data/install_bin
+
# ----------------------------------------------------
# Release directory specification
# ----------------------------------------------------
@@ -56,10 +59,14 @@ ERL_COMPILE_FLAGS += -I$(ERL_TOP)/lib/test_server/include
# Targets
# ----------------------------------------------------
-tests debug opt: $(TARGET_FILES)
+tests debug opt: $(TARGET_FILES) $(EXTRA_FILES)
+
+install_SUITE_data/install_bin: ../../make/install_bin
+ rm -f $@
+ cp -p $< $@
clean:
- rm -f $(TARGET_FILES)
+ rm -f $(TARGET_FILES) $(EXTRA_FILES)
rm -f core *~
docs:
diff --git a/erts/test/erl_print_SUITE.erl b/erts/test/erl_print_SUITE.erl
index b1458d84d0..3bb7d4d016 100644
--- a/erts/test/erl_print_SUITE.erl
+++ b/erts/test/erl_print_SUITE.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2005-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 2005-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%
%%
@@ -36,7 +36,7 @@
-export([erlang_display/1, integer/1, float/1, string/1, character/1, snprintf/1, quote/1]).
--include("test_server.hrl").
+-include_lib("test_server/include/test_server.hrl").
all(doc) -> [];
all(suite) -> test_cases().
diff --git a/erts/test/erlc_SUITE.erl b/erts/test/erlc_SUITE.erl
index ce64ef1a75..437f020f99 100644
--- a/erts/test/erlc_SUITE.erl
+++ b/erts/test/erlc_SUITE.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(erlc_SUITE).
@@ -23,7 +23,7 @@
-export([all/1, compile_erl/1, compile_yecc/1, compile_script/1,
compile_mib/1, good_citizen/1, deep_cwd/1]).
--include("test_server.hrl").
+-include_lib("test_server/include/test_server.hrl").
all(suite) ->
[compile_erl, compile_yecc, compile_script, compile_mib,
@@ -56,6 +56,13 @@ compile_erl(Config) when is_list(Config) ->
?line run(Config, Cmd, FileName, "-W0", ["_OK_"]),
+ %% Try treating warnings as errors.
+
+ ?line run(Config, Cmd, FileName, "-Werror",
+ ["compile: warnings being treated as errors\$",
+ "Warning: function foo/0 is unused\$",
+ "_ERROR_"]),
+
%% Check a bad file.
?line BadFile = filename:join(SrcDir, "erl_test_bad.erl"),
@@ -117,7 +124,7 @@ compile_mib(Config) when is_list(Config) ->
?line case test_server:os_type() of
{unix,_} ->
?line run(Config, Cmd, FileName, "-W +'{verbosity,info}'",
- ["GOOD-MIB.mib: Info. No accessfunction for 'sysDescr'",
+ ["\\[GOOD-MIB[.]mib\\]\\[INF\\]: No accessfunction for 'sysDescr' => using default",
"_OK_"]),
?line true = exists(Output),
?line ok = file:delete(Output);
diff --git a/erts/test/erlexec_SUITE.erl b/erts/test/erlexec_SUITE.erl
index fcf1e67e9e..164ce9faaf 100644
--- a/erts/test/erlexec_SUITE.erl
+++ b/erts/test/erlexec_SUITE.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2007-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 2007-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%
%%
@@ -35,7 +35,7 @@
-export([args_file/1, evil_args_file/1, env/1, args_file_env/1, otp_7461/1, otp_7461_remote/1, otp_8209/1]).
--include("test_server.hrl").
+-include_lib("test_server/include/test_server.hrl").
init_per_testcase(Case, Config) ->
diff --git a/erts/test/ethread_SUITE.erl b/erts/test/ethread_SUITE.erl
index a8f4f5e90c..bbc79e9381 100644
--- a/erts/test/ethread_SUITE.erl
+++ b/erts/test/ethread_SUITE.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2004-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 2004-2010. All Rights Reserved.
+%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
-%%
+%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
-%%
+%%
%% %CopyrightEnd%
%%
@@ -53,7 +53,7 @@
atomic/1,
gate/1]).
--include("test_server.hrl").
+-include_lib("test_server/include/test_server.hrl").
tests() ->
[create_join_thread,
diff --git a/erts/test/ignore_cores.erl b/erts/test/ignore_cores.erl
index 7ec2cac706..8b1ac0fe6c 100644
--- a/erts/test/ignore_cores.erl
+++ b/erts/test/ignore_cores.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%
%%
@@ -27,7 +27,7 @@
-module(ignore_cores).
--include("test_server.hrl").
+-include_lib("test_server/include/test_server.hrl").
-export([init/1, fini/1, setup/3, setup/4, restore/1, dir/1]).
diff --git a/erts/test/install_SUITE.erl b/erts/test/install_SUITE.erl
new file mode 100644
index 0000000000..e14790bc1b
--- /dev/null
+++ b/erts/test/install_SUITE.erl
@@ -0,0 +1,727 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 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%
+%%
+
+
+%%%-------------------------------------------------------------------
+%%% File : install_SUITE.erl
+%%% Author : Rickard Green
+%%% Description :
+%%%
+%%% Created : 12 Jan 2010 by Rickard Green
+%%%-------------------------------------------------------------------
+-module(install_SUITE).
+
+%-define(line_trace, 1).
+
+-export([all/1, init_per_suite/1, end_per_suite/1,
+ init_per_testcase/2, fin_per_testcase/2]).
+
+-export([bin_default/1,
+ bin_default_dirty/1,
+ bin_outside_eprfx/1,
+ bin_outside_eprfx_dirty/1,
+ bin_unreasonable_path/1,
+ bin_not_abs/1,
+ 'bin white space'/1,
+ bin_no_srcfile/1,
+ bin_unreachable_absolute/1,
+ bin_unreachable_relative/1,
+ bin_same_dir/1,
+ bin_ok_symlink/1,
+ bin_dirname_fail/1,
+ bin_no_use_dirname_fail/1]).
+
+-define(DEFAULT_TIMEOUT, ?t:minutes(1)).
+-define(JOIN(A,B,C), filename:join(A, B, C)).
+
+-include_lib("test_server/include/test_server.hrl").
+
+-record(inst, {mkdirs = true,
+ symlinks = true,
+ cmd_prefix = "",
+ ln_s = "ln -s",
+ test_prefix = "",
+ destdir = "",
+ extra_prefix = "",
+ exec_prefix = "",
+ bindir = "",
+ erlang_bindir = "",
+ bindir_symlinks = ""}).
+
+need_symlink_cases() ->
+ [bin_unreachable_absolute,
+ bin_unreachable_relative,
+ bin_same_dir,
+ bin_ok_symlink,
+ bin_dirname_fail,
+ bin_no_use_dirname_fail].
+
+dont_need_symlink_cases() ->
+ [bin_default,
+ bin_default_dirty,
+ bin_outside_eprfx,
+ bin_outside_eprfx_dirty,
+ bin_not_abs,
+ bin_unreasonable_path,
+ 'bin white space',
+ bin_no_srcfile].
+
+all(suite) ->
+ dont_need_symlink_cases() ++ need_symlink_cases().
+
+%%
+%% The test cases
+%%
+
+bin_default(Config) when is_list(Config) ->
+ ?line E = "/usr/local",
+ ?line Bs = "/usr/local/bin",
+ ?line Be = Bs,
+ ?line EBs = "/usr/local/lib/erlang/bin",
+ ?line EBe = EBs,
+ ?line RP = "../lib/erlang/bin",
+ ChkRes = fun (Res, #inst{test_prefix = TP,
+ destdir = D,
+ extra_prefix = EP,
+ bindir_symlinks = BSL,
+ symlinks = SL}) ->
+ ?line B = join([TP, D, EP, Be]),
+ Expct = case {SL, BSL} of
+ {false, _} when BSL == "relative";
+ BSL == "absolute" ->
+ ?line {error, no_ln_s};
+ {false, _} ->
+ ?line {ok,{absolute,
+ B,join([TP,D,EP,EBe])}};
+ {true, "absolute"} ->
+ ?line {ok,{absolute,B,join([TP,EP,EBe])}};
+ {true, _} ->
+ ?line {ok,{relative,B,RP}}
+ end,
+ expect(Expct, Res)
+ end,
+ install_bin(Config, #inst{exec_prefix = E,
+ bindir = Bs,
+ erlang_bindir = EBs}, ChkRes).
+
+bin_default_dirty(Config) when is_list(Config) ->
+ ?line E = "/usr/./local/lib/..",
+ ?line Bs = "/usr/local//lib/../lib/erlang/../../bin",
+ ?line Be = "/usr/local/lib/../lib/erlang/../../bin",
+ ?line EBs = "/usr/local/lib/../lib/erlang/../erlang/bin/x/y/../..//",
+ ?line EBe = "/usr/local/lib/../lib/erlang/../erlang/bin/x/y/../..",
+ ?line RP = "../lib/erlang/bin",
+ ChkRes = fun (Res, #inst{test_prefix = TP,
+ destdir = D,
+ extra_prefix = EP,
+ bindir_symlinks = BSL,
+ symlinks = SL}) ->
+ ?line B = join([TP, D, EP, Be]),
+ Expct = case {SL, BSL} of
+ {false, _} when BSL == "relative";
+ BSL == "absolute" ->
+ ?line {error, no_ln_s};
+ {false, _} ->
+ ?line {ok,{absolute,
+ B,join([TP,D,EP,EBe])}};
+ {true, "absolute"} ->
+ ?line {ok,{absolute,
+ B,join([TP,EP,EBe])}};
+ {true, _} ->
+ ?line {ok,{relative,B,RP}}
+ end,
+ expect(Expct, Res)
+ end,
+ install_bin(Config, #inst{exec_prefix = E,
+ bindir = Bs,
+ erlang_bindir = EBs}, ChkRes).
+
+
+bin_outside_eprfx(Config) when is_list(Config) ->
+ ?line E = "/usr/local",
+ ?line Bs = "/usr/bin",
+ ?line Be = Bs,
+ ?line EBs = "/usr/local/lib/erlang/bin",
+ ?line EBe = EBs,
+ ?line RP = "../local/lib/erlang/bin",
+ ChkRes = fun (Res, #inst{test_prefix = TP,
+ destdir = D,
+ extra_prefix = EP,
+ bindir_symlinks = BSL,
+ symlinks = SL}) ->
+ ?line B = join([TP, D, EP, Be]),
+ Expct = case {SL, BSL} of
+ {false, _} when BSL == "relative";
+ BSL == "absolute" ->
+ ?line {error, no_ln_s};
+ {false, _} ->
+ ?line {ok,{absolute,
+ B,join([TP,D,EP,EBe])}};
+ {true, "relative"} ->
+ ?line {ok,{relative,B,RP}};
+ {true, _} ->
+ ?line {ok,{absolute,B,join([TP,EP,EBe])}}
+ end,
+ expect(Expct, Res)
+ end,
+ install_bin(Config, #inst{exec_prefix = E,
+ bindir = Bs,
+ erlang_bindir = EBs}, ChkRes).
+
+
+bin_outside_eprfx_dirty(Config) when is_list(Config) ->
+ ?line E = "/usr/local/lib/..",
+ ?line Bs = "/usr/local/lib/../../bin",
+ ?line Be = Bs,
+ ?line EBs = "/usr/local/lib/erlang/bin",
+ ?line EBe = EBs,
+ ?line RP = "../local/lib/erlang/bin",
+ ChkRes = fun (Res, #inst{test_prefix = TP,
+ destdir = D,
+ extra_prefix = EP,
+ bindir_symlinks = BSL,
+ symlinks = SL}) ->
+ ?line B = join([TP, D, EP, Be]),
+ Expct = case {SL, BSL} of
+ {false, _} when BSL == "relative";
+ BSL == "absolute" ->
+ ?line {error, no_ln_s};
+ {false, _} ->
+ ?line {ok,{absolute,
+ B,join([TP,D,EP,EBe])}};
+ {true, "relative"} ->
+ ?line {ok,{relative,B,RP}};
+ {true, _} ->
+ ?line {ok,{absolute,B,join([TP,EP,EBe])}}
+ end,
+ expect(Expct, Res)
+ end,
+ install_bin(Config, #inst{exec_prefix = E,
+ bindir = Bs,
+ erlang_bindir = EBs}, ChkRes).
+
+bin_unreasonable_path(Config) when is_list(Config) ->
+ ?line E = "/usr/local/../../..",
+ ?line Bs = "/usr/local/../../../bin",
+ ?line Be = Bs,
+ ?line EBs = "/usr/local/../../../bin_unreasonable_path/usr/local/lib/erlang/bin",
+ ?line EBe = EBs,
+ ?line RP = "../bin_unreasonable_path/usr/local/lib/erlang/bin",
+ ChkRes = fun (Res, #inst{test_prefix = TP,
+ destdir = D,
+ extra_prefix = EP,
+ bindir_symlinks = BSL,
+ symlinks = SL}) ->
+ ?line B = join([TP, D, EP, Be]),
+ Expct = case {TP, SL, BSL} of
+ {_, false, _} when BSL == "relative";
+ BSL == "absolute" ->
+ ?line {error, no_ln_s};
+ {_, false, _} ->
+ ?line {ok,{absolute,
+ B,join([TP,D,EP,EBe])}};
+ {"", true, "relative"} ->
+ {error, unreasonable_path};
+ {"", true, _} ->
+ ?line {ok,{absolute,B,join([TP,EP,EBe])}};
+ {_, true, "absolute"} ->
+ ?line {ok,{absolute,B,join([TP,EP,EBe])}};
+ _ ->
+ ?line {ok,{relative,B,RP}}
+ end,
+ expect(Expct, Res)
+ end,
+ install_bin(Config, #inst{exec_prefix = E,
+ bindir = Bs,
+ erlang_bindir = EBs}, ChkRes).
+
+bin_unreachable_absolute(Config) when is_list(Config) ->
+ TDir = ?config(test_dir, Config),
+ make_dirs(TDir, "/opt/local/lib/erlang/usr/bin"),
+ make_dirs(TDir, "/opt/local/lib/erlang/bin"),
+ Erl = join([TDir, "/opt/local/lib/erlang/bin/erl"]),
+ Erlc = join([TDir, "/opt/local/lib/erlang/bin/erlc"]),
+ make_dirs(TDir, "/usr/local/lib"),
+ make_dirs(TDir, "/usr/local/bin"),
+ ok = file:write_file(Erl, "erl"),
+ ok = file:write_file(Erlc, "erlc"),
+ ok = file:make_symlink("../../../opt/local/lib/erlang/usr",
+ join([TDir, "/usr/local/lib/erlang"])),
+ ?line E = "/usr/local",
+ ?line Bs = "/usr/local/bin",
+ ?line Be = Bs,
+ ?line EBs = "/usr/local/lib/erlang/../bin",
+ ?line EBe = EBs,
+ ChkRes = fun (Res, #inst{test_prefix = TP,
+ destdir = D,
+ extra_prefix = EP,
+ bindir_symlinks = BSL,
+ symlinks = SL}) ->
+ ?line B = join([TP, D, EP, Be]),
+ Expct = case {SL, BSL} of
+ {false, _} when BSL == "relative";
+ BSL == "absolute" ->
+ ?line {error, no_ln_s};
+ {false, _} ->
+ ?line {ok,{absolute,
+ B,join([TP,D,EP,EBe])}};
+ {true, "relative"} ->
+ {error, unreachable_absolute};
+ {true, _} ->
+ ?line {ok,{absolute,B,join([TP,EP,EBe])}}
+ end,
+ expect(Expct, Res)
+ end,
+ install_bin(Config, #inst{exec_prefix = E,
+ bindir = Bs,
+ erlang_bindir = EBs}, ChkRes).
+
+bin_unreachable_relative(Config) when is_list(Config) ->
+ TDir = ?config(test_dir, Config),
+ make_dirs(TDir, "/opt/local/lib/erlang/bin"),
+ make_dirs(TDir, "/opt/local/bin"),
+ make_dirs(TDir, "/usr/local/lib/erlang/bin"),
+ Erl = join([TDir, "/usr/local/lib/erlang/bin/erl"]),
+ Erlc = join([TDir, "/usr/local/lib/erlang/bin/erlc"]),
+ ok = file:write_file(Erl, "erl"),
+ ok = file:write_file(Erlc, "erlc"),
+ ok = file:make_symlink("../../opt/local/bin",
+ join([TDir, "/usr/local/bin"])),
+
+ ?line E = "/usr/local",
+ ?line Bs = "/usr/local/bin",
+ ?line Be = Bs,
+ ?line EBs = "/usr/local/lib/erlang/bin",
+ ?line EBe = EBs,
+ ChkRes = fun (Res, #inst{test_prefix = TP,
+ destdir = D,
+ extra_prefix = EP,
+ bindir_symlinks = BSL,
+ symlinks = SL}) ->
+ ?line B = join([TP, D, EP, Be]),
+ Expct = case {SL, BSL} of
+ {false, _} when BSL == "relative";
+ BSL == "absolute" ->
+ ?line {error, no_ln_s};
+ {false, _} ->
+ ?line {ok,{absolute,
+ B,join([TP,D,EP,EBe])}};
+ {true, "relative"} ->
+ {error, unreachable_relative};
+ {true, _} ->
+ ?line {ok,{absolute,B,join([TP,EP,EBe])}}
+ end,
+ expect(Expct, Res)
+ end,
+ install_bin(Config, #inst{exec_prefix = E,
+ bindir = Bs,
+ erlang_bindir = EBs}, ChkRes).
+
+bin_ok_symlink(Config) when is_list(Config) ->
+ TDir = ?config(test_dir, Config),
+ make_dirs(TDir, "/usr/local/bin"),
+ make_dirs(TDir, "/opt/local/lib/erlang/bin"),
+ Erl = join([TDir, "/opt/local/lib/erlang/bin/erl"]),
+ Erlc = join([TDir, "/opt/local/lib/erlang/bin/erlc"]),
+ ok = file:write_file(Erl, "erl"),
+ ok = file:write_file(Erlc, "erlc"),
+ ok = file:make_symlink("../../opt/local/lib",
+ join([TDir, "/usr/local/lib"])),
+ ?line E = "/usr/local",
+ ?line Bs = "/usr/local/bin",
+ ?line Be = Bs,
+ ?line EBs = "/usr/local/lib/erlang/bin",
+ ?line EBe = EBs,
+ ?line RP = "../lib/erlang/bin",
+ ChkRes = fun (Res, #inst{test_prefix = TP,
+ destdir = D,
+ extra_prefix = EP,
+ bindir_symlinks = BSL,
+ symlinks = SL}) ->
+ ?line B = join([TP, D, EP, Be]),
+ Expct = case {SL, BSL} of
+ {false, _} when BSL == "relative";
+ BSL == "absolute" ->
+ ?line {error, no_ln_s};
+ {false, _} ->
+ ?line {ok,{absolute,
+ B,join([TP,D,EP,EBe])}};
+ {true, "absolute"} ->
+ ?line {ok,{absolute,B,join([TP,EP,EBe])}};
+ {true, _} ->
+ ?line {ok,{relative,B,RP}}
+ end,
+ expect(Expct, Res)
+ end,
+ install_bin(Config, #inst{exec_prefix = E,
+ bindir = Bs,
+ erlang_bindir = EBs}, ChkRes).
+
+bin_same_dir(Config) when is_list(Config) ->
+ TDir = ?config(test_dir, Config),
+ make_dirs(TDir, "/usr/local/bin"),
+ make_dirs(TDir, "/usr/local/lib"),
+ ok = file:make_symlink("..", join([TDir, "/usr/local/lib/erlang"])),
+ Erl = join([TDir, "/usr/local/lib/erlang/bin/erl"]),
+ Erlc = join([TDir, "/usr/local/lib/erlang/bin/erlc"]),
+ ok = file:write_file(Erl, "erl"),
+ ok = file:write_file(Erlc, "erlc"),
+ ChkRes = fun (Res, _) ->
+ expect({error, target_and_source_same_dir}, Res)
+ end,
+ install_bin(Config,
+ #inst{mkdirs = false,
+ exec_prefix = "/usr/local",
+ bindir = "/usr/local/bin",
+ erlang_bindir = "/usr/local/lib/erlang/bin"},
+ ChkRes).
+
+bin_not_abs(Config) when is_list(Config) ->
+ ChkRes = fun (Res, #inst{test_prefix = TP}) ->
+ case TP of
+ "" ->
+ expect({error, {not_abs, 'bindir'}}, Res);
+ _ ->
+ B = join([TP, "/usr/local/bin"]),
+ {ok, {relative, B, "../lib/erlang/bin"}}
+ end
+ end,
+ install_bin(Config,
+ #inst{exec_prefix = "/usr/local",
+ bindir = "usr/local/bin",
+ erlang_bindir = "/usr/local/lib/erlang/bin"},
+ ChkRes).
+
+
+'bin white space'(Config) when is_list(Config) ->
+ ?line E = "/u s r/local",
+ ?line Bs = "/u s r/local/b i n",
+ ?line Be = Bs,
+ ?line EBs = "/u s r/local/lib/erl ang/bin",
+ ?line EBe = EBs,
+ ?line RP = "../lib/erl ang/bin",
+ ChkRes = fun (Res, #inst{test_prefix = TP,
+ destdir = D,
+ extra_prefix = EP,
+ bindir_symlinks = BSL,
+ symlinks = SL}) ->
+ ?line B = join([TP, D, EP, Be]),
+ Expct = case {SL, BSL} of
+ {false, _} when BSL == "relative";
+ BSL == "absolute" ->
+ ?line {error, no_ln_s};
+ {false, _} ->
+ ?line {ok,{absolute,
+ B,join([TP,D,EP,EBe])}};
+ {true, "absolute"} ->
+ ?line {ok,{absolute,B,join([TP,EP,EBe])}};
+ {true, _} ->
+ ?line {ok,{relative,B,RP}}
+ end,
+ expect(Expct, Res)
+ end,
+ install_bin(Config, #inst{exec_prefix = E,
+ bindir = Bs,
+ erlang_bindir = EBs}, ChkRes).
+
+bin_dirname_fail(Config) when is_list(Config) ->
+ ?line E = "/opt",
+ ?line Bs = "/opt/lib/../bin",
+ ?line Be = Bs,
+ ?line EBs = "/opt/lib/erlang/otp/bin",
+ ?line EBe = EBs,
+ ?line CMDPRFX = "PATH="++?config(data_dir,Config)++":"++os:getenv("PATH"),
+ ChkRes = fun (Res, #inst{test_prefix = TP,
+ destdir = D,
+ extra_prefix = EP,
+ bindir_symlinks = BSL,
+ symlinks = SL}) ->
+ ?line B = join([TP, D, EP, Be]),
+ Expct = case {SL, BSL} of
+ {false, _} when BSL == "relative";
+ BSL == "absolute" ->
+ ?line {error, no_ln_s};
+ {false, _} ->
+ ?line {ok,{absolute,
+ B,join([TP,D,EP,EBe])}};
+ {true, "relative"} ->
+ ?line {error, dirname_failed};
+ {true, _} ->
+ ?line {ok,{absolute,B,join([TP,EP,EBe])}}
+ end,
+ expect(Expct, Res)
+ end,
+ install_bin(Config, #inst{cmd_prefix = CMDPRFX,
+ exec_prefix = E,
+ bindir = Bs,
+ erlang_bindir = EBs}, ChkRes).
+
+bin_no_use_dirname_fail(Config) when is_list(Config) ->
+ ?line E = "/opt",
+ ?line Bs = "/opt/bin",
+ ?line Be = Bs,
+ ?line EBs = "/opt/lib/erlang/otp/bin",
+ ?line EBe = EBs,
+ ?line RP = "../lib/erlang/otp/bin",
+ ?line CMDPRFX = "PATH="++?config(data_dir,Config)++":"++os:getenv("PATH"),
+ ChkRes = fun (Res, #inst{test_prefix = TP,
+ destdir = D,
+ extra_prefix = EP,
+ bindir_symlinks = BSL,
+ symlinks = SL}) ->
+ ?line B = join([TP, D, EP, Be]),
+ Expct = case {SL, BSL} of
+ {false, _} when BSL == "relative";
+ BSL == "absolute" ->
+ ?line {error, no_ln_s};
+ {false, _} ->
+ ?line {ok,{absolute,
+ B,join([TP,D,EP,EBe])}};
+ {true, "absolute"} ->
+ ?line {ok,{absolute,B,join([TP,EP,EBe])}};
+ {true, _} ->
+ ?line {ok,{relative,B,RP}}
+ end,
+ expect(Expct, Res)
+ end,
+ install_bin(Config, #inst{cmd_prefix = CMDPRFX,
+ exec_prefix = E,
+ bindir = Bs,
+ erlang_bindir = EBs}, ChkRes).
+
+bin_no_srcfile(Config) when is_list(Config) ->
+ TDir = ?config(test_dir, Config),
+ make_dirs(TDir, "/opt/local/bin"),
+ make_dirs(TDir, "/opt/local/lib/erlang/bin"),
+ Erl = join([TDir, "/opt/local/lib/erlang/bin/erl"]),
+ ok = file:write_file(Erl, "erl"),
+ Erlc = join([TDir, "/opt/local/lib/erlang/bin/erlc"]),
+ RP_Erlc = "../lib/erlang/bin/erlc",
+ ChkRes = fun (Res, #inst{bindir_symlinks = BSL,
+ symlinks = SL}) ->
+ Expct = case {SL, BSL} of
+ {false, _} when BSL == "relative";
+ BSL == "absolute" ->
+ ?line {error, no_ln_s};
+ {false,_} ->
+ ?line {error,{no_srcfile, Erlc}};
+ {true, "absolute"} ->
+ ?line {error,{no_srcfile, Erlc}};
+ {true, _} ->
+ ?line {error,{no_srcfile, RP_Erlc}}
+ end,
+ expect(Expct, Res)
+ end,
+ install_bin(Config,
+ #inst{mkdirs = false,
+ exec_prefix = "/opt/local",
+ bindir = "/opt/local/bin",
+ erlang_bindir = "/opt/local/lib/erlang/bin"},
+ ChkRes).
+
+%%
+%%
+%% Auxiliary functions
+%%
+%%
+
+expect(X, X) ->
+ ?t:format("result: ~p~n", [X]),
+ ?t:format("-----------------------------------------------~n", []),
+ ok;
+expect(X, Y) ->
+ ?t:format("expected: ~p~n", [X]),
+ ?t:format("got : ~p~n", [Y]),
+ ?t:format("-----------------------------------------------~n", []),
+ ?t:fail({X,Y}).
+
+init_per_suite(Config) ->
+ PD = ?config(priv_dir, Config),
+ SymLinks = case ?t:os_type() of
+ {win32, _} -> false;
+ _ ->
+ case file:make_symlink("nothing",
+ filename:join(PD,
+ "symlink_test")) of
+ ok -> true;
+ _ -> false
+ end
+ end,
+ [{symlinks, SymLinks} | Config].
+
+end_per_suite(_Config) ->
+ ok.
+
+init_per_testcase(Case, Config) ->
+ init_per_testcase_aux(?config(symlinks,Config),?t:os_type(),Case,Config).
+
+init_per_testcase_aux(_, {win32, _}, _Case, _Config) ->
+ {skip, "Not on windows"};
+init_per_testcase_aux(false, OsType, Case, Config) ->
+ case lists:member(Case, need_symlink_cases()) of
+ false -> init_per_testcase_aux(true, OsType, Case, Config);
+ true -> {skip, "Cannot create symbolic links"}
+ end;
+init_per_testcase_aux(true, _OsType, Case, Config) ->
+ Dog = ?t:timetrap(?DEFAULT_TIMEOUT),
+ [{watchdog, Dog},
+ {testcase, Case},
+ {test_dir, make_dirs(?config(priv_dir, Config), atom_to_list(Case))}
+ | Config].
+
+fin_per_testcase(_Case, Config) ->
+ Dog = ?config(watchdog, Config),
+ ?t:timetrap_cancel(Dog),
+ ok.
+
+
+make_dirs(Root, Suffix) ->
+ do_make_dirs(Root, string:tokens(Suffix, [$/])).
+
+do_make_dirs(_Root, []) ->
+ "";
+do_make_dirs(Root, [D|Ds]) ->
+ Dir = filename:join(Root, D),
+ case file:make_dir(Dir) of
+ {error, eexist} -> ok;
+ ok -> ok;
+ Err -> exit({make_dir, Err})
+ end,
+ filename:join(Dir, do_make_dirs(Dir, Ds)).
+
+install_bin(Config, #inst{mkdirs = MkDirs,
+ exec_prefix = EXEC_PREFIX,
+ bindir = BINDIR,
+ erlang_bindir = ERLANG_BINDIR} = Inst, ChkRes) ->
+ PDir = ?config(priv_dir, Config),
+ TDir = ?config(test_dir, Config),
+ TD = atom_to_list(?config(testcase, Config)),
+ case MkDirs of
+ false -> ok;
+ true ->
+ make_dirs(TDir, EXEC_PREFIX),
+ make_dirs(TDir, BINDIR),
+ make_dirs(TDir, ERLANG_BINDIR),
+ Erl = join([TDir, ERLANG_BINDIR, "/erl"]),
+ Erlc = join([TDir, ERLANG_BINDIR, "/erlc"]),
+ ok = file:write_file(Erl, "erl"),
+ ok = file:write_file(Erlc, "erlc")
+ end,
+
+ install_bin2(Config, Inst#inst{destdir = TDir}, ChkRes),
+ install_bin2(Config, Inst#inst{extra_prefix = TDir}, ChkRes),
+ install_bin2(Config, Inst#inst{destdir = PDir,
+ extra_prefix = "/"++TD}, ChkRes),
+ install_bin2(Config,
+ Inst#inst{test_prefix = TDir,
+ exec_prefix = join([TDir, EXEC_PREFIX]),
+ bindir = join([TDir, BINDIR]),
+ erlang_bindir = join([TDir, ERLANG_BINDIR])},
+ ChkRes),
+ case ?config(symlinks, Config) of
+ true -> ok;
+ false -> {comment, "No symlink tests run, since symlinks not working"}
+ end.
+
+
+install_bin2(Config, Inst, ChkRes) ->
+ install_bin3(Config, Inst#inst{symlinks = false,
+ ln_s = "ln"}, ChkRes),
+ install_bin3(Config, Inst#inst{symlinks = false,
+ ln_s = "ln",
+ bindir_symlinks = "relative"}, ChkRes),
+ install_bin3(Config, Inst#inst{symlinks = false,
+ ln_s = "ln",
+ bindir_symlinks = "absolute"}, ChkRes),
+ install_bin3(Config, Inst#inst{symlinks = false,
+ ln_s = "cp -p"}, ChkRes),
+ install_bin3(Config, Inst#inst{symlinks = false,
+ ln_s = "cp -p",
+ bindir_symlinks = "relative"}, ChkRes),
+ install_bin3(Config, Inst#inst{symlinks = false,
+ ln_s = "cp -p",
+ bindir_symlinks = "absolute"}, ChkRes),
+ case ?config(symlinks, Config) of
+ true ->
+ install_bin3(Config, Inst#inst{symlinks = true,
+ ln_s = "ln -s"}, ChkRes),
+ install_bin3(Config, Inst#inst{symlinks = true,
+ ln_s = "ln -s",
+ bindir_symlinks = "relative"}, ChkRes),
+ install_bin3(Config, Inst#inst{symlinks = true,
+ ln_s = "ln -s",
+ bindir_symlinks = "absolute"}, ChkRes);
+ false ->
+ ok
+ end.
+
+
+
+install_bin3(Config,
+ #inst{cmd_prefix = CMD_PRFX,
+ ln_s = LN_S,
+ destdir = DESTDIR,
+ extra_prefix = EXTRA_PREFIX,
+ exec_prefix = EXEC_PREFIX,
+ bindir = BINDIR,
+ erlang_bindir = ERLANG_BINDIR,
+ bindir_symlinks = BINDIR_SYMLINKS} = Inst,
+ ChkRes) ->
+ Test = ?config(testcase, Config),
+ DDir = ?config(data_dir, Config),
+ TDir = ?config(test_dir, Config),
+ InstallBin = filename:join(DDir, "install_bin"),
+ ResFile = filename:join(TDir, atom_to_list(Test) ++ "-result.txt"),
+ Cmd = CMD_PRFX ++ " "
+ ++ InstallBin ++ " --ln_s \"" ++ LN_S
+ ++ "\" --destdir \"" ++ DESTDIR
+ ++ "\" --extra-prefix \"" ++ EXTRA_PREFIX
+ ++ "\" --bindir-symlinks \"" ++ BINDIR_SYMLINKS
+ ++ "\" --bindir \"" ++ BINDIR
+ ++ "\" --erlang-bindir \"" ++ ERLANG_BINDIR
+ ++ "\" --exec-prefix \"" ++ EXEC_PREFIX
+ ++ "\" --test-file \"" ++ ResFile ++ "\" erl erlc",
+
+ ?t:format("CMD_PRFX = \"~s\"~n"
+ "LN_S = \"~s\"~n"
+ "BINDIR_SYMLINKS = \"~s\"~n"
+ "exec_prefix = \"~s\"~n"
+ "bindir = \"~s\"~n"
+ "erlang_bindir = \"~s\"~n"
+ "EXTRA_PREFIX = \"~s\"~n"
+ "DESTDIR = \"~s\"~n",
+ [CMD_PRFX, LN_S, BINDIR_SYMLINKS, EXEC_PREFIX, BINDIR,
+ ERLANG_BINDIR, EXTRA_PREFIX, DESTDIR]),
+
+ ?t:format("$ ~s~n", [Cmd]),
+ CmdOutput = os:cmd(Cmd),
+ ?t:format("~s~n", [CmdOutput]),
+ ChkRes(case file:consult(ResFile) of
+ {ok, [Res]} -> Res;
+ Err -> exit({result, Err})
+ end,
+ Inst).
+
+join("") ->
+ "";
+join([""|Ds]) ->
+ join(Ds);
+join([D|Ds]) ->
+ "/" ++ string:strip(D, both, $/) ++ join(Ds).
+
diff --git a/erts/test/install_SUITE_data/dirname b/erts/test/install_SUITE_data/dirname
new file mode 100755
index 0000000000..ecdbef95dd
--- /dev/null
+++ b/erts/test/install_SUITE_data/dirname
@@ -0,0 +1,2 @@
+#!/bin/sh
+exit 1
diff --git a/erts/test/nt_SUITE.erl b/erts/test/nt_SUITE.erl
index 7ff5c908e6..530fb55270 100644
--- a/erts/test/nt_SUITE.erl
+++ b/erts/test/nt_SUITE.erl
@@ -1,24 +1,25 @@
%%
%% %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%
%%
%%% Purpose: Test NT specific utilities
-module(nt_SUITE).
--include("test_server.hrl").
+
+-include_lib("test_server/include/test_server.hrl").
-include_lib("kernel/include/file.hrl").
-export([all/1,init_per_testcase/2,fin_per_testcase/2,nt/1,handle_eventlog/2,
diff --git a/erts/test/otp_SUITE.erl b/erts/test/otp_SUITE.erl
index c6769743dd..425ad31782 100644
--- a/erts/test/otp_SUITE.erl
+++ b/erts/test/otp_SUITE.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2000-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 2000-2010. All Rights Reserved.
+%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
-%%
+%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
-%%
+%%
%% %CopyrightEnd%
%%
@@ -24,7 +24,8 @@
obsolete_but_not_deprecated/1,call_to_deprecated/1,
call_to_size_1/1,strong_components/1]).
--include("test_server.hrl").
+-include_lib("test_server/include/test_server.hrl").
+
-import(lists, [filter/2,foldl/3,foreach/2]).
all(suite) ->
diff --git a/erts/test/run_erl_SUITE.erl b/erts/test/run_erl_SUITE.erl
index afff4120d4..efeafbad8c 100644
--- a/erts/test/run_erl_SUITE.erl
+++ b/erts/test/run_erl_SUITE.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2005-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 2005-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%
%%
@@ -23,7 +23,7 @@
basic/1,heavy/1,heavier/1,defunct/1]).
-export([ping_me_back/1]).
--include("test_server.hrl").
+-include_lib("test_server/include/test_server.hrl").
init_per_testcase(_Case, Config) ->
Dog = ?t:timetrap(?t:minutes(2)),
diff --git a/erts/test/z_SUITE.erl b/erts/test/z_SUITE.erl
index 0e37af1ca2..8faddeb0d3 100644
--- a/erts/test/z_SUITE.erl
+++ b/erts/test/z_SUITE.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%
%%
@@ -39,7 +39,7 @@
-export([search_for_core_files/1, core_files/1]).
--include("test_server.hrl").
+-include_lib("test_server/include/test_server.hrl").
init_per_testcase(Case, Config) ->
diff --git a/erts/vsn.mk b/erts/vsn.mk
index 199b1cbf22..2e830150d8 100644
--- a/erts/vsn.mk
+++ b/erts/vsn.mk
@@ -1,24 +1,24 @@
#
# %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%
#
-VSN = 5.7.4
-SYSTEM_VSN = R13B03
+VSN = 5.7.5.3
+SYSTEM_VSN = R13B04
# Port number 4365 in 4.2
# Port number 4366 in 4.3
diff --git a/lib/.gitignore b/lib/.gitignore
new file mode 100644
index 0000000000..fc8a1c5568
--- /dev/null
+++ b/lib/.gitignore
@@ -0,0 +1,556 @@
+# common test
+
+/common_test/doc/src/ct.xml
+/common_test/doc/src/ct_cover.xml
+/common_test/doc/src/ct_ftp.xml
+/common_test/doc/src/ct_master.xml
+/common_test/doc/src/ct_rpc.xml
+/common_test/doc/src/ct_snmp.xml
+/common_test/doc/src/ct_ssh.xml
+/common_test/doc/src/ct_telnet.xml
+/common_test/doc/src/unix_telnet.xml
+
+# edoc
+
+/edoc/doc/src/chapter.xml
+/edoc/doc/src/edoc.xml
+/edoc/doc/src/edoc_doclet.xml
+/edoc/doc/src/edoc_extract.xml
+/edoc/doc/src/edoc_layout.xml
+/edoc/doc/src/edoc_lib.xml
+/edoc/doc/src/edoc_run.xml
+
+# eunit
+
+/eunit/doc/src/chapter.xml
+/eunit/doc/src/eunit.xml
+/eunit/doc/src/eunit_surefire.xml
+
+# erl_interface
+
+/erl_interface/bin
+/erl_interface/obj.mt
+/erl_interface/obj.st
+/erl_interface/obj
+
+# gs
+
+/gs/doc/src/gs_chapter2.xml
+/gs/doc/src/gs_chapter4.xml
+/gs/doc/src/gs_chapter5.xml
+/gs/doc/src/gs_chapter6.xml
+/gs/doc/src/gs_chapter7.xml
+/gs/doc/src/gs_chapter8.xml
+
+# 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
+
+# mnesia
+
+/mnesia/doc/src/Mnesia_App_B.xml
+/mnesia/doc/src/Mnesia_App_C.xml
+/mnesia/doc/src/Mnesia_App_D.xml
+/mnesia/doc/src/Mnesia_chap2.xml
+/mnesia/doc/src/Mnesia_chap4.xml
+/mnesia/doc/src/Mnesia_chap5.xml
+/mnesia/doc/src/Mnesia_chap7.xml
+
+# 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
+
+# percept
+
+/percept/doc/src/egd.xml
+/percept/doc/src/egd_ug.xml
+/percept/doc/src/percept.xml
+/percept/doc/src/percept_profile.xml
+/percept/doc/src/percept_ug.xml
+
+# syntax_tools
+
+/syntax_tools/doc/src/chapter.xml
+/syntax_tools/doc/src/epp_dodger.xml
+/syntax_tools/doc/src/erl_comment_scan.xml
+/syntax_tools/doc/src/erl_prettypr.xml
+/syntax_tools/doc/src/erl_recomment.xml
+/syntax_tools/doc/src/erl_syntax.xml
+/syntax_tools/doc/src/erl_syntax_lib.xml
+/syntax_tools/doc/src/erl_tidy.xml
+/syntax_tools/doc/src/igor.xml
+/syntax_tools/doc/src/prettypr.xml
+
+# wx
+
+/wx/doc/src/chapter.xml
+/wx/doc/src/gl.xml
+/wx/doc/src/glu.xml
+/wx/doc/src/ref_man.xml
+
+# xmerl
+
+/xmerl/doc/src/xmerl.xml
+/xmerl/doc/src/xmerl_eventp.xml
+/xmerl/doc/src/xmerl_scan.xml
+/xmerl/doc/src/xmerl_ug.xml
+/xmerl/doc/src/xmerl_xpath.xml
+/xmerl/doc/src/xmerl_xs.xml
+/xmerl/doc/src/xmerl_xsd.xml
diff --git a/lib/Makefile b/lib/Makefile
index 66062068b2..f5ffc6f166 100644
--- a/lib/Makefile
+++ b/lib/Makefile
@@ -1,19 +1,19 @@
#
# %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
# 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
@@ -51,7 +51,7 @@ else
# --------------
#
ERTS_SUB_DIRECTORIES = stdlib sasl kernel compiler
- OTHER_SUB_DIRECTORIES = tools
+ OTHER_SUB_DIRECTORIES = tools test_server
ifdef BUILD_ALL
ifeq ($(findstring win32,$(TARGET)),win32) # BUILD_ALL on win32
OTHER_SUB_DIRECTORIES += \
@@ -60,7 +60,7 @@ else
public_key ssl toolbar tv observer debugger reltool odbc runtime_tools \
cosTransactions cosEvent cosTime cosNotification cosProperty \
cosFileTransfer cosEventDomain et megaco webtool \
- xmerl edoc eunit ssh inviso typer docbuilder erl_docgen test_server common_test percept
+ xmerl edoc eunit ssh inviso typer docbuilder erl_docgen common_test percept
# dialyzer
OTHER_SUB_DIRECTORIES += hipe
else # BUILD_ALL on unix
@@ -70,7 +70,7 @@ else
pman public_key ssl toolbar tv observer odbc \
runtime_tools cosTransactions cosEvent cosTime cosNotification \
cosProperty cosFileTransfer cosEventDomain et megaco webtool \
- xmerl edoc eunit ssh inviso typer docbuilder erl_docgen test_server common_test percept
+ xmerl edoc eunit ssh inviso typer docbuilder erl_docgen common_test percept
# dialyzer
OTHER_SUB_DIRECTORIES += hipe $(TSP_APP)
endif
diff --git a/lib/appmon/doc/src/Makefile b/lib/appmon/doc/src/Makefile
index ece0977810..743f123c06 100644
--- a/lib/appmon/doc/src/Makefile
+++ b/lib/appmon/doc/src/Makefile
@@ -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%
include $(ERL_TOP)/make/target.mk
include $(ERL_TOP)/make/$(TARGET)/otp.mk
@@ -46,6 +46,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 = \
app_win.gif \
listbox_win.gif \
diff --git a/lib/appmon/doc/src/notes.xml b/lib/appmon/doc/src/notes.xml
index f624ce993b..219b5671a4 100644
--- a/lib/appmon/doc/src/notes.xml
+++ b/lib/appmon/doc/src/notes.xml
@@ -4,7 +4,7 @@
<chapter>
<header>
<copyright>
- <year>2004</year><year>2009</year>
+ <year>2004</year><year>2010</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
@@ -13,12 +13,12 @@
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>Appmon Release Notes</title>
@@ -30,6 +30,37 @@
</header>
<p>This document describes the changes made to the Appmon application.</p>
+<section><title>Appmon 2.1.11</title>
+
+ <section><title>Improvements and New Features</title>
+ <list>
+ <item>
+ <p>The documentation is now possible to build in an open
+ source environment after a number of bugs are fixed and
+ some features are added in the documentation build
+ process. </p>
+ <p>- The arity calculation is updated.</p>
+ <p>- The module prefix used in the function names for
+ bif's are removed in the generated links so the links
+ will look like
+ "http://www.erlang.org/doc/man/erlang.html#append_element-2"
+ instead of
+ "http://www.erlang.org/doc/man/erlang.html#erlang:append_element-2".</p>
+ <p>- Enhanced the menu positioning in the html
+ documentation when a new page is loaded.</p>
+ <p>- A number of corrections in the generation of man
+ pages (thanks to Sergei Golovan)</p>
+ <p>- The legal notice is taken from the xml book file so
+ OTP's build process can be used for non OTP
+ applications.</p>
+ <p>
+ Own Id: OTP-8343</p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
<section><title>Appmon 2.1.10.2</title>
<section><title>Improvements and New Features</title>
diff --git a/lib/appmon/vsn.mk b/lib/appmon/vsn.mk
index cbf0a88737..e6c2b13877 100644
--- a/lib/appmon/vsn.mk
+++ b/lib/appmon/vsn.mk
@@ -1,19 +1 @@
-#
-# %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%
-
-APPMON_VSN = 2.1.10.2
+APPMON_VSN = 2.1.11
diff --git a/lib/asn1/c_src/Makefile b/lib/asn1/c_src/Makefile
index 53da8fd035..906c513fad 100644
--- a/lib/asn1/c_src/Makefile
+++ b/lib/asn1/c_src/Makefile
@@ -1,20 +1,132 @@
#
# %CopyrightBegin%
-#
-# Copyright Ericsson AB 2002-2009. All Rights Reserved.
-#
+#
+# Copyright Ericsson AB 2002-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%
#
#
-include $(ERL_TOP)/make/run_make.mk
+include $(ERL_TOP)/make/target.mk
+include $(ERL_TOP)/make/$(TARGET)/otp.mk
+include $(ERL_TOP)/make/$(TARGET)/otp_ded.mk
+
+CC = $(DED_CC)
+LD = $(DED_LD)
+LIBS = $(DED_LIBS)
+
+# ----------------------------------------------------
+# Application version
+# ----------------------------------------------------
+include ../vsn.mk
+VSN=$(ASN1_VSN)
+
+# ----------------------------------------------------
+# Release directory specification
+# ----------------------------------------------------
+RELSYSDIR = $(RELEASE_PATH)/lib/asn1-$(VSN)
+
+
+# ----------------------------------------------------
+# FLAGS misc
+# ----------------------------------------------------
+ifeq ($(TYPE),debug)
+TYPEMARKER = .debug
+else
+TYPEMARKER =
+endif
+
+EI_LIBDIR = $(ERL_TOP)/lib/erl_interface/obj$(TYPEMARKER)/$(TARGET)
+
+# ----------------------------------------------------
+# FLAGS
+# ----------------------------------------------------
+EI_INCLUDES = -I$(ERL_TOP)/lib/erl_interface/include
+CFLAGS = $(DED_INCLUDES) $(EI_INCLUDES) $(DED_CFLAGS)
+LDFLAGS += $(DED_LDFLAGS)
+
+LD_INCL_EI = -L$(EI_LIBDIR)
+
+# ----------------------------------------------------
+# Target Specs
+# ----------------------------------------------------
+
+C_FILES = asn1_erl_driver.c
+
+
+ifeq ($(TARGET),win32)
+LD_EI = -lei_md
+SHARED_OBJ_FILES = $(LIBDIR)/asn1_erl_drv.dll
+OBJ_FILES = $(OBJDIR)/asn1_erl_drv.o
+CLIB_FLAGS =
+LN=cp
+else
+LD_EI = -lei
+OBJ_FILES = $(OBJDIR)/asn1_erl_drv.o
+ifeq ($(findstring vxworks,$(TARGET)),vxworks)
+SHARED_OBJ_FILES = $(LIBDIR)/asn1_erl_drv.eld
+CLIB_FLAGS =
+else
+SHARED_OBJ_FILES = $(LIBDIR)/asn1_erl_drv.so
+CLIB_FLAGS = -lc
+endif
+LN= ln -s
+endif
+
+# ----------------------------------------------------
+# Targets
+# ----------------------------------------------------
+
+opt: $(OBJDIR) $(LIBDIR) $(SHARED_OBJ_FILES)
+
+debug: opt
+
+clean:
+ rm -f core *~
+ rm -f $(LIBDIR)/*
+ rm -f $(OBJDIR)/*
+
+docs:
+
+# ----------------------------------------------------
+# Special Build Targets
+# ----------------------------------------------------
+
+
+$(OBJ_FILES): $(C_FILES)
+ $(CC) -c $(CFLAGS) -o $(OBJ_FILES) $(C_FILES)
+
+$(SHARED_OBJ_FILES): $(OBJ_FILES)
+ $(LD) $(LDFLAGS) $(LD_INCL_EI) -o $(SHARED_OBJ_FILES) $(OBJ_FILES) $(LD_EI) $(CLIB_FLAGS) $(LIBS)
+
+$(LIBDIR):
+ -mkdir -p $(LIBDIR)
+
+$(OBJDIR):
+ -mkdir -p $(OBJDIR)
+
+
+
+# ----------------------------------------------------
+# Release Target
+# ----------------------------------------------------
+include $(ERL_TOP)/make/otp_release_targets.mk
+
+release_spec: opt
+ $(INSTALL_DIR) $(RELSYSDIR)/priv/lib
+ $(INSTALL_DATA) $(SHARED_OBJ_FILES) $(RELSYSDIR)/priv/lib
+ $(INSTALL_DIR) $(RELSYSDIR)/c_src
+ $(INSTALL_DATA) $(C_FILES) $(RELSYSDIR)/c_src
+
+release_docs_spec:
+
diff --git a/lib/asn1/c_src/Makefile.in b/lib/asn1/c_src/Makefile.in
deleted file mode 100644
index b4a0cddba1..0000000000
--- a/lib/asn1/c_src/Makefile.in
+++ /dev/null
@@ -1,139 +0,0 @@
-#
-# %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_TOP)/make/target.mk
-include $(ERL_TOP)/make/$(TARGET)/otp.mk
-
-ERLANG_OSTYPE = @ERLANG_OSTYPE@
-
-CC = @CC@
-
-LD = @DED_LD@
-LIBS = @LIBS@
-
-LIBDIR = $(ERL_TOP)/lib/asn1/priv/lib/$(TARGET)
-OBJDIR = $(ERL_TOP)/lib/asn1/priv/obj/$(TARGET)
-
-# ----------------------------------------------------
-# Application version
-# ----------------------------------------------------
-include ../vsn.mk
-VSN=$(ASN1_VSN)
-
-# ----------------------------------------------------
-# Release directory specification
-# ----------------------------------------------------
-RELSYSDIR = $(RELEASE_PATH)/lib/asn1-$(VSN)
-
-
-# ----------------------------------------------------
-# FLAGS misc
-# ----------------------------------------------------
-ifeq ($(TYPE),debug)
-TYPEMARKER = .debug
-else
-TYPEMARKER =
-endif
-
-EI_LIBDIR = $(ERL_TOP)/lib/erl_interface/obj$(TYPEMARKER)/$(TARGET)
-
-# ----------------------------------------------------
-# FLAGS
-# ----------------------------------------------------
-EI_INCLUDES = -I$(ERL_TOP)/lib/erl_interface/include
-DRIVER_INCLUDES = -I$(ERL_TOP)/erts/emulator/beam \
- -I$(ERL_TOP)/erts/emulator/sys/$(ERLANG_OSTYPE)
-CFLAGS = $(DRIVER_INCLUDES) $(EI_INCLUDES) @DED_CFLAGS@
-LDFLAGS += @DED_LDFLAGS@
-
-LD_INCL_EI = -L$(EI_LIBDIR)
-
-# ----------------------------------------------------
-# Target Specs
-# ----------------------------------------------------
-
-C_FILES = asn1_erl_driver.c
-
-
-ifeq ($(TARGET),win32)
-LD_EI = -lei_md
-SHARED_OBJ_FILES = $(LIBDIR)/asn1_erl_drv.dll
-OBJ_FILES = $(OBJDIR)/asn1_erl_drv.o
-CLIB_FLAGS =
-LN=cp
-else
-LD_EI = -lei
-OBJ_FILES = $(OBJDIR)/asn1_erl_drv.o
-ifeq ($(findstring vxworks,$(TARGET)),vxworks)
-SHARED_OBJ_FILES = $(LIBDIR)/asn1_erl_drv.eld
-CLIB_FLAGS =
-else
-SHARED_OBJ_FILES = $(LIBDIR)/asn1_erl_drv.so
-CLIB_FLAGS = -lc
-endif
-LN= ln -s
-endif
-
-# ----------------------------------------------------
-# Targets
-# ----------------------------------------------------
-
-opt: $(OBJDIR) $(LIBDIR) $(SHARED_OBJ_FILES)
-
-debug: opt
-
-clean:
- rm -f core *~
- rm -f $(LIBDIR)/*
- rm -f $(OBJDIR)/*
-
-docs:
-
-# ----------------------------------------------------
-# Special Build Targets
-# ----------------------------------------------------
-
-
-$(OBJ_FILES): $(C_FILES) $(OBJDIR)
- $(CC) -c $(CFLAGS) -o $(OBJ_FILES) $(C_FILES)
-
-$(SHARED_OBJ_FILES): $(OBJ_FILES) $(LIBDIR)
- $(LD) $(LDFLAGS) $(LD_INCL_EI) -o $(SHARED_OBJ_FILES) $(OBJ_FILES) $(LD_EI) $(CLIB_FLAGS) $(LIBS)
-
-$(LIBDIR):
- -mkdir -p $(LIBDIR)
-
-$(OBJDIR):
- -mkdir -p $(OBJDIR)
-
-
-
-# ----------------------------------------------------
-# Release Target
-# ----------------------------------------------------
-include $(ERL_TOP)/make/otp_release_targets.mk
-
-release_spec: opt
- $(INSTALL_DIR) $(RELSYSDIR)/priv/lib
- $(INSTALL_DATA) $(SHARED_OBJ_FILES) $(RELSYSDIR)/priv/lib
- $(INSTALL_DIR) $(RELSYSDIR)/c_src
- $(INSTALL_DATA) $(C_FILES) $(RELSYSDIR)/c_src
-
-release_docs_spec:
-
diff --git a/lib/asn1/c_src/asn1_erl_driver.c b/lib/asn1/c_src/asn1_erl_driver.c
index cd2e63a363..fd284e5800 100644
--- a/lib/asn1/c_src/asn1_erl_driver.c
+++ b/lib/asn1/c_src/asn1_erl_driver.c
@@ -1,19 +1,19 @@
/*
* %CopyrightBegin%
- *
- * Copyright Ericsson AB 2002-2009. All Rights Reserved.
- *
+ *
+ * Copyright Ericsson AB 2002-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%
*
*/
@@ -206,7 +206,11 @@ int asn1_drv_control(ErlDrvData handle,
set_port_control_flags(a_data->port, PORT_CONTROL_FLAG_BINARY);
if (command == ASN1_COMPLETE)
- { /* Do the PER complete encode step */
+ {
+ if (buf_len==0) {
+ return 0; /* Avoid binary buffer overwrite (OTP-8451) */
+ }
+ /* Do the PER complete encode step */
if ((drv_binary = driver_alloc_binary(buf_len))==NULL) {
/* error handling */
set_port_control_flags(a_data->port, 0);
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/asn1ct.xml b/lib/asn1/doc/src/asn1ct.xml
index 9c04956e86..8a0ae52c39 100644
--- a/lib/asn1/doc/src/asn1ct.xml
+++ b/lib/asn1/doc/src/asn1ct.xml
@@ -4,7 +4,7 @@
<erlref>
<header>
<copyright>
- <year>1997</year><year>2009</year>
+ <year>1997</year><year>2010</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
@@ -13,12 +13,12 @@
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>asn1ct</title>
@@ -52,9 +52,11 @@
<v>Options = [Option| OldOption]</v>
<v>Option = ber_bin | per_bin | uper_bin | der | compact_bit_string |
noobj | {n2n,EnumTypeName} |{outdir,Dir} | {i,IncludeDir} | optimize |
- driver | asn1config | undec_rest | {inline,OutputName} | inline</v>
+ driver | asn1config | undec_rest | {inline,OutputName} | inline |
+ {macro_name_prefix, Prefix} | {record_name_prefix, Prefix}</v>
<v>OldOption = ber | per</v>
<v>Reason = term()</v>
+ <v>Prefix = string()</v>
</type>
<desc>
<p>Compiles the ASN.1 module <c>Asn1module</c> and generates an
@@ -270,6 +272,18 @@ Binary = binary()
It is as <c>{inline,OutputName}</c>, but the output file gets the
default name of the source <c>.set.asn</c> file.</p>
</item>
+ <tag><c>{macro_name_prefix, Prefix}</c></tag>
+ <item>
+ <p>All macro names generated by the compiler are prefixed with
+ <c>Prefix</c>. This is useful when multiple protocols that contains
+ macros with identical names are included in a single module.</p>
+ </item>
+ <tag><c>{record_name_prefix, Prefix}</c></tag>
+ <item>
+ <p>All record names generated by the compiler are prefixed with
+ <c>Prefix</c>. This is useful when multiple protocols that contains
+ records with identical names are included in a single module.</p>
+ </item>
</taglist>
<p>Any additional option that is applied will be passed to
the final step when the generated .erl file is compiled.
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.xml b/lib/asn1/doc/src/notes.xml
index 861de05a59..714902e63f 100644
--- a/lib/asn1/doc/src/notes.xml
+++ b/lib/asn1/doc/src/notes.xml
@@ -4,7 +4,7 @@
<chapter>
<header>
<copyright>
- <year>2004</year><year>2009</year>
+ <year>2004</year><year>2010</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
@@ -13,12 +13,12 @@
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>
@@ -30,6 +30,141 @@
</header>
<p>This document describes the changes made to the asn1 application.</p>
+<section><title>Asn1 1.6.13.2</title>
+
+ <section><title>Fixed Bugs and Malfunctions</title>
+ <list>
+ <item>
+ <p>
+ The encoding of ExtensionAdditionGroup (for PER and UPER)
+ is corrected.</p>
+ <p>
+ Own Id: OTP-8866 Aux Id: OTP-8797, SEQ-11557 </p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
+<section><title>Asn1 1.6.13.1</title>
+
+ <section><title>Fixed Bugs and Malfunctions</title>
+ <list>
+ <item>
+ <p>
+ Extension Addition Groups are now supported by the parser
+ and in all backends.</p>
+ <p>
+ Own Id: OTP-8598</p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
+<section><title>Asn1 1.6.13</title>
+
+ <section><title>Fixed Bugs and Malfunctions</title>
+ <list>
+ <item>
+ <p>
+ Harmless buffer overflow by one byte in asn1 and
+ ram_file_drv.</p>
+ <p>
+ Own Id: OTP-8451</p>
+ </item>
+ </list>
+ </section>
+
+
+ <section><title>Improvements and New Features</title>
+ <list>
+ <item>
+ <p>Cross compilation improvements and other build system
+ improvements.</p>
+ <p>Most notable:</p> <list><item> Lots of cross
+ compilation improvements. The old cross compilation
+ support was more or less non-existing as well as broken.
+ Please, note that the cross compilation support should
+ still be considered as experimental. Also note that old
+ cross compilation configurations cannot be used without
+ modifications. For more information on cross compiling
+ Erlang/OTP see the <c>$ERL_TOP/INSTALL-CROSS.md</c> file.
+ </item><item> Support for staged install using <url
+ href="http://www.gnu.org/prep/standards/html_node/DESTDIR.html">DESTDIR</url>.
+ The old broken <c>INSTALL_PREFIX</c> has also been fixed.
+ For more information see the <c>$ERL_TOP/INSTALL.md</c>
+ file. </item><item> Documentation of the <c>release</c>
+ target of the top <c>Makefile</c>. For more information
+ see the <c>$ERL_TOP/INSTALL.md</c> file. </item><item>
+ <c>make install</c> now by default creates relative
+ symbolic links instead of absolute ones. For more
+ information see the <c>$ERL_TOP/INSTALL.md</c> file.
+ </item><item> <c>$ERL_TOP/configure --help=recursive</c>
+ now works and prints help for all applications with
+ <c>configure</c> scripts. </item><item> Doing <c>make
+ install</c>, or <c>make release</c> directly after
+ <c>make all</c> no longer triggers miscellaneous
+ rebuilds. </item><item> Existing bootstrap system is now
+ used when doing <c>make install</c>, or <c>make
+ release</c> without a preceding <c>make all</c>.
+ </item><item> The <c>crypto</c> and <c>ssl</c>
+ applications use the same runtime library path when
+ dynamically linking against <c>libssl.so</c> and
+ <c>libcrypto.so</c>. The runtime library search path has
+ also been extended. </item><item> The <c>configure</c>
+ scripts of <c>erl_interface</c> and <c>odbc</c> now
+ search for thread libraries and thread library quirks the
+ same way as <c>erts</c> do. </item><item> The
+ <c>configure</c> script of the <c>odbc</c> application
+ now also looks for odbc libraries in <c>lib64</c> and
+ <c>lib/64</c> directories when building on a 64-bit
+ system. </item><item> The <c>config.h.in</c> file in the
+ <c>erl_interface</c> application is now automatically
+ generated in instead of statically updated which reduces
+ the risk of <c>configure</c> tests without any effect.
+ </item></list>
+ <p>(Thanks to Henrik Riomar for suggestions and
+ testing)</p>
+ <p>(Thanks to Winston Smith for the AVR32-Linux cross
+ configuration and testing)</p>
+ <p>
+ *** POTENTIAL INCOMPATIBILITY ***</p>
+ <p>
+ Own Id: OTP-8323</p>
+ </item>
+ <item>
+ <p>
+ Add support for prefixing macro names generated by the
+ compiler</p>
+ <p>
+ This is useful when multiple protocols that contains
+ macros with identical names are included in a single
+ module.</p>
+ <p>
+ Add the missing <c>record_name_prefix</c> compiler option
+ to the documentation.</p>
+ <p>
+ Own Id: OTP-8453</p>
+ </item>
+ <item>
+ <p>
+ Cleanups suggested by tidier and modernization of types
+ and specs.</p>
+ <p>
+ Own Id: OTP-8455</p>
+ </item>
+ <item>
+ <p>
+ Support for <c>EXTENSIBILITY IMPLIED</c> and <c>SET/SEQ
+ OF NamedType</c> is added.</p>
+ <p>
+ Own Id: OTP-8463</p>
+ </item>
+ </list>
+ </section>
+
+</section>
<section><title>Asn1 1.6.12</title>
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/asn1/src/Restrictions.txt b/lib/asn1/src/Restrictions.txt
index 73b725245d..ed5ac6181e 100644
--- a/lib/asn1/src/Restrictions.txt
+++ b/lib/asn1/src/Restrictions.txt
@@ -1,10 +1,12 @@
The following restrictions apply to this implementation of the ASN.1 compiler:
-Supported encoding rules are:
-BER
-PER (aligned)
+The ASN.1 2002 standard is not fully supported because there has been no need for that.
+It seems as if most ASN.1 specifications are still using the 1998 standard or older.
-PER (unaligned) IS NOT SUPPORTED
+Supported encoding rules are:
+BER, DER
+PER ALIGNED
+PER UNALIGNED
Supported types are:
@@ -49,7 +51,7 @@ Files with ASN.1 source must have a suffix .asn1 the suffix .py used by the
old ASN.1 compiler is supported in this version but will not be supported in the future.
Generated files:
-X.asn1db % the intermediate format of a compiled ASN.1 module
+X.asn1db % the intermediate format of a compiled ASN.1 module ,only used by the ASN.1 compiler.
X.hrl % generated Erlang include file for module X
X.erl % generated Erlang module with encode decode functions for
% ASN.1 module X
diff --git a/lib/asn1/src/asn1.appup.src b/lib/asn1/src/asn1.appup.src
index 753d308684..2d11eddfbf 100644
--- a/lib/asn1/src/asn1.appup.src
+++ b/lib/asn1/src/asn1.appup.src
@@ -1,111 +1,9 @@
{"%VSN%",
- [
- {"1.6.8",
- [
- {load_module, asn1rt, soft_purge, soft_purge, []},
- {load_module, asn1rt_per_bin, soft_purge, soft_purge, []},
- {load_module, asn1rt_per_bin_rt2ct, soft_purge, soft_purge, []},
- {load_module, asn1rt_uper_bin, soft_purge, soft_purge, []},
- {load_module, asn1rt_ber_bin, soft_purge, soft_purge, []},
- {load_module, asn1rt_ber_bin_v2, soft_purge, soft_purge, []},
- {load_module, asn1rt_check, soft_purge, soft_purge, []},
- {load_module, asn1rt_driver_handler, soft_purge, soft_purge, []},
- {apply, {asn1rt_driver_handler,unload_driver,[]}}
- ]
- },
- {"1.6.8.1",
- [
- {load_module, asn1rt, soft_purge, soft_purge, []},
- {load_module, asn1rt_per_bin, soft_purge, soft_purge, []},
- {load_module, asn1rt_per_bin_rt2ct, soft_purge, soft_purge, []},
- {load_module, asn1rt_uper_bin, soft_purge, soft_purge, []},
- {load_module, asn1rt_ber_bin, soft_purge, soft_purge, []},
- {load_module, asn1rt_ber_bin_v2, soft_purge, soft_purge, []},
- {load_module, asn1rt_check, soft_purge, soft_purge, []},
- {load_module, asn1rt_driver_handler, soft_purge, soft_purge, []},
- {apply, {asn1rt_driver_handler,unload_driver,[]}}
- ]
- },
- {"1.6.9",
- [
- {load_module, asn1rt, soft_purge, soft_purge, []},
- {load_module, asn1rt_per_bin, soft_purge, soft_purge, []},
- {load_module, asn1rt_per_bin_rt2ct, soft_purge, soft_purge, []},
- {load_module, asn1rt_uper_bin, soft_purge, soft_purge, []},
- {load_module, asn1rt_ber_bin, soft_purge, soft_purge, []},
- {load_module, asn1rt_ber_bin_v2, soft_purge, soft_purge, []},
- {load_module, asn1rt_check, soft_purge, soft_purge, []},
- {load_module, asn1rt_driver_handler, soft_purge, soft_purge, []},
- {apply, {asn1rt_driver_handler,unload_driver,[]}}
- ]
- },
- {"1.6.10",
- [
- {load_module, asn1rt, soft_purge, soft_purge, []},
- {load_module, asn1rt_per_bin, soft_purge, soft_purge, []},
- {load_module, asn1rt_per_bin_rt2ct, soft_purge, soft_purge, []},
- {load_module, asn1rt_uper_bin, soft_purge, soft_purge, []},
- {load_module, asn1rt_ber_bin, soft_purge, soft_purge, []},
- {load_module, asn1rt_ber_bin_v2, soft_purge, soft_purge, []},
- {load_module, asn1rt_check, soft_purge, soft_purge, []},
- {load_module, asn1rt_driver_handler, soft_purge, soft_purge, []},
- {apply, {asn1rt_driver_handler,unload_driver,[]}}
- ]
- }
+% This version does not change anything of the runtime modules
+% Only changes in compile time modules and thus no need for upgrade on target
+[
],
[
- {"1.6.8",
- [
- {load_module, asn1rt, soft_purge, soft_purge, []},
- {load_module, asn1rt_per_bin, soft_purge, soft_purge, []},
- {load_module, asn1rt_per_bin_rt2ct, soft_purge, soft_purge, []},
- {load_module, asn1rt_uper_bin, soft_purge, soft_purge, []},
- {load_module, asn1rt_ber_bin, soft_purge, soft_purge, []},
- {load_module, asn1rt_ber_bin_v2, soft_purge, soft_purge, []},
- {load_module, asn1rt_check, soft_purge, soft_purge, []},
- {load_module, asn1rt_driver_handler, soft_purge, soft_purge, []},
- {apply, {asn1rt_driver_handler,unload_driver,[]}}
- ]
- },
- {"1.6.8.1",
- [
- {load_module, asn1rt, soft_purge, soft_purge, []},
- {load_module, asn1rt_per_bin, soft_purge, soft_purge, []},
- {load_module, asn1rt_per_bin_rt2ct, soft_purge, soft_purge, []},
- {load_module, asn1rt_uper_bin, soft_purge, soft_purge, []},
- {load_module, asn1rt_ber_bin, soft_purge, soft_purge, []},
- {load_module, asn1rt_ber_bin_v2, soft_purge, soft_purge, []},
- {load_module, asn1rt_check, soft_purge, soft_purge, []},
- {load_module, asn1rt_driver_handler, soft_purge, soft_purge, []},
- {apply, {asn1rt_driver_handler,unload_driver,[]}}
- ]
- },
- {"1.6.9",
- [
- {load_module, asn1rt, soft_purge, soft_purge, []},
- {load_module, asn1rt_per_bin, soft_purge, soft_purge, []},
- {load_module, asn1rt_per_bin_rt2ct, soft_purge, soft_purge, []},
- {load_module, asn1rt_uper_bin, soft_purge, soft_purge, []},
- {load_module, asn1rt_ber_bin, soft_purge, soft_purge, []},
- {load_module, asn1rt_ber_bin_v2, soft_purge, soft_purge, []},
- {load_module, asn1rt_check, soft_purge, soft_purge, []},
- {load_module, asn1rt_driver_handler, soft_purge, soft_purge, []},
- {apply, {asn1rt_driver_handler,unload_driver,[]}}
- ]
- },
- {"1.6.10",
- [
- {load_module, asn1rt, soft_purge, soft_purge, []},
- {load_module, asn1rt_per_bin, soft_purge, soft_purge, []},
- {load_module, asn1rt_per_bin_rt2ct, soft_purge, soft_purge, []},
- {load_module, asn1rt_uper_bin, soft_purge, soft_purge, []},
- {load_module, asn1rt_ber_bin, soft_purge, soft_purge, []},
- {load_module, asn1rt_ber_bin_v2, soft_purge, soft_purge, []},
- {load_module, asn1rt_check, soft_purge, soft_purge, []},
- {load_module, asn1rt_driver_handler, soft_purge, soft_purge, []},
- {apply, {asn1rt_driver_handler,unload_driver,[]}}
- ]
- }
]}.
diff --git a/lib/asn1/src/asn1_records.hrl b/lib/asn1/src/asn1_records.hrl
index 8a428b744c..59a9acb7e7 100644
--- a/lib/asn1/src/asn1_records.hrl
+++ b/lib/asn1/src/asn1_records.hrl
@@ -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%
%%
%%
@@ -36,7 +36,8 @@
-record(module,{pos,name,defid,tagdefault='EXPLICIT',exports={exports,[]},imports={imports,[]}, extensiondefault=empty,typeorval}).
--record('SEQUENCE',{pname=false,tablecinf=false,components=[]}).
+-record('ExtensionAdditionGroup',{number}).
+-record('SEQUENCE',{pname=false,tablecinf=false,extaddgroup,components=[]}).
-record('SET',{pname=false,sorted=false,tablecinf=false,components=[]}).
-record('ComponentType',{pos,name,typespec,prop,tags,textual_order}).
-record('ObjectClassFieldType',{classname,class,fieldname,type}).
diff --git a/lib/asn1/src/asn1ct_check.erl b/lib/asn1/src/asn1ct_check.erl
index f0a48a086b..7cd29623c1 100644
--- a/lib/asn1/src/asn1ct_check.erl
+++ b/lib/asn1/src/asn1ct_check.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%
%%
%%
@@ -3227,7 +3227,7 @@ check_ptype(_S,_PTDef,Ts) when is_record(Ts,objectclass) ->
% check_type(S,Type,ObjSpec={{objectclassname,_},_}) ->
-% check_class(S,ObjSpec);
+ % check_class(S,ObjSpec);
check_type(_S,Type,Ts) when is_record(Type,typedef),
(Type#typedef.checked==true) ->
Ts;
@@ -3357,6 +3357,7 @@ check_type(S=#state{recordtopname=TopName},Type,Ts) when is_record(Ts,type) ->
merge_tags(Tag,?TAG_PRIMITIVE(?N_INTEGER))};
'REAL' ->
check_real(S,Constr),
+
TempNewDef#newt{tag=merge_tags(Tag,?TAG_PRIMITIVE(?N_REAL))};
{'BIT STRING',NamedNumberList} ->
NewL = check_bitstring(S,NamedNumberList,Constr),
@@ -5416,9 +5417,12 @@ instance_of_constraints(S,#constraint{c={simpletable,Type}}) ->
%% assign values to un-numbered identifiers
%% check that the constraints are allowed and correct
%% put the updated info back into database
-check_enumerated(_S,[{Name,Number}|Rest],_Constr) when is_atom(Name), is_integer(Number)->
+check_enumerated(_S,[{Name,Number}|_Rest]= NNList,_Constr) when is_atom(Name), is_integer(Number)->
%% already checked , just return the same list
- [{Name,Number}|Rest];
+ NNList;
+check_enumerated(_S,{[{Name,Number}|_Rest],L}= NNList,_Constr) when is_atom(Name), is_integer(Number), is_list(L)->
+ %% already checked , contains extension marker, just return the same lists
+ NNList;
check_enumerated(S,NamedNumberList,_Constr) ->
check_enum(S,NamedNumberList,[],[],[]).
@@ -5519,24 +5523,9 @@ check_sequence(S,Type,Comps) ->
Components2 = maybe_automatic_tags(S,Components),
%% check the table constraints from here. The outermost type
%% is Type, the innermost is Comps (the list of components)
- NewComps =
- case check_each_component(S,Type,Components2) of
- NewComponents when is_list(NewComponents) ->
- check_unique_sequence_tags(S,NewComponents),
- NewComponents;
- Ret = {NewComponents,NewEcomps} ->
- TagComps = NewComponents ++
- [Comp#'ComponentType'{prop='OPTIONAL'}|| Comp <- NewEcomps],
- %% extension components are like optionals when it comes to tagging
- check_unique_sequence_tags(S,TagComps),
- Ret;
- Ret = {Root1,NewE,Root2} ->
- TagComps = Root1 ++ [Comp#'ComponentType'{prop='OPTIONAL'}|| Comp <- NewE]++Root2,
- %% This is not correct handling if Extension
- %% contains ExtensionAdditionGroups
- check_unique_sequence_tags(S,TagComps),
- Ret
- end,
+ NewComps = check_each_component2(S,Type,Components2),
+ check_unique_sequence_tags(S,NewComps),
+
%% CRelInf is the "leading attribute" information
%% necessary for code generating of the look up in the
%% object set table,
@@ -5550,12 +5539,45 @@ check_sequence(S,Type,Comps) ->
%% the involved class removed, as the class of the object
%% set.
CompListWithTblInf = get_tableconstraint_info(S,Type,NewComps2),
-
- {CRelInf,CompListWithTblInf};
+ %% If encoding rule is in the PER family the Root Components
+ %% after the second extension mark should be encoded before
+ %% all extensions i.e together with the first Root components
+
+ NewComps3 = textual_order(CompListWithTblInf),
+ CompListTuple =
+ complist_as_tuple(is_erule_per(S#state.erule),NewComps3),
+ {CRelInf,CompListTuple};
Dupl ->
- throw({error,{asn1,{duplicate_components,Dupl}}})
+ throw({error,{asn1,{duplicate_components,Dupl}}})
end.
+complist_as_tuple(Per,CompList) ->
+ complist_as_tuple(Per,CompList,[],[],[],root).
+
+complist_as_tuple(Per,[#'EXTENSIONMARK'{}|T],Acc,Ext,Acc2,root) ->
+ complist_as_tuple(Per,T,Acc,Ext,Acc2,ext);
+complist_as_tuple(Per,[#'EXTENSIONMARK'{}|T],Acc,Ext,Acc2,ext) ->
+ complist_as_tuple(Per,T,Acc,Ext,Acc2,root2);
+complist_as_tuple(_Per,[#'EXTENSIONMARK'{}|_T],_Acc,_Ext,_Acc2,root2) ->
+ throw({error,{asn1,{too_many_extension_marks}}});
+complist_as_tuple(Per,[C|T],Acc,Ext,Acc2,root) ->
+ complist_as_tuple(Per,T,[C|Acc],Ext,Acc2,root);
+complist_as_tuple(Per,[C|T],Acc,Ext,Acc2,ext) ->
+ complist_as_tuple(Per,T,Acc,[C|Ext],Acc2,ext);
+complist_as_tuple(Per,[C|T],Acc,Ext,Acc2,root2) ->
+ complist_as_tuple(Per,T,Acc,Ext,[C|Acc2],root2);
+complist_as_tuple(_Per,[],Acc,_Ext,_Acc2,root) ->
+ lists:reverse(Acc);
+complist_as_tuple(_Per,[],Acc,Ext,_Acc2,ext) ->
+ {lists:reverse(Acc),lists:reverse(Ext)};
+%%complist_as_tuple(_Per = true,[],Acc,Ext,Acc2,root2) ->
+%% {lists:reverse(Acc)++lists:reverse(Acc2),lists:reverse(Ext)};
+complist_as_tuple(_Per,[],Acc,Ext,Acc2,root2) ->
+ {lists:reverse(Acc),lists:reverse(Ext),lists:reverse(Acc2)}.
+
+is_erule_per(Erule) ->
+ lists:member(Erule,[per,per_bin,uper_bin]).
+
expand_components(S, [{'COMPONENTS OF',Type}|T]) ->
CompList = expand_components2(S,get_referenced_type(S,Type#type.def)),
expand_components(S,CompList) ++ expand_components(S,T);
@@ -5568,14 +5590,14 @@ expand_components2(_S,{_,#typedef{typespec=#type{def=Seq}}})
case Seq#'SEQUENCE'.components of
{R1,_Ext,R2} -> R1 ++ R2;
{Root,_Ext} -> Root;
- Root -> Root
+ Root -> take_only_rootset(Root)
end;
expand_components2(_S,{_,#typedef{typespec=#type{def=Set}}})
when is_record(Set,'SET') ->
case Set#'SET'.components of
{R1,_Ext,R2} -> R1 ++ R2;
{Root,_Ext} -> Root;
- Root -> Root
+ Root -> take_only_rootset(Root)
end;
expand_components2(_S,{_,#typedef{typespec=RefType=#type{def=#'Externaltypereference'{}}}}) ->
[{'COMPONENTS OF',RefType}];
@@ -5591,14 +5613,33 @@ expand_components2(S,{_,ERef}) when is_record(ERef,'Externaltypereference') ->
expand_components2(_S,Err) ->
throw({error,{asn1,{illegal_COMPONENTS_OF,Err}}}).
+take_only_rootset([])->
+ [];
+take_only_rootset([#'EXTENSIONMARK'{}|_T])->
+ [];
+take_only_rootset([H|T]) ->
+ [H|take_only_rootset(T)].
+
+check_unique_sequence_tags(S,CompList) ->
+ TagComps = case complist_as_tuple(false,CompList) of
+ {R1,Ext,R2} ->
+ R1 ++ [C#'ComponentType'{prop='OPTIONAL'}||
+ C = #'ComponentType'{} <- Ext]++R2;
+ {R1,Ext} ->
+ R1 ++ [C#'ComponentType'{prop='OPTIONAL'}||
+ C = #'ComponentType'{} <- Ext];
+ _ ->
+ CompList
+ end,
+ check_unique_sequence_tags0(S,TagComps).
-check_unique_sequence_tags(S,[#'ComponentType'{prop=mandatory}|Rest]) ->
- check_unique_sequence_tags(S,Rest);
-check_unique_sequence_tags(S,[C|Rest]) when is_record(C,'ComponentType') ->
+check_unique_sequence_tags0(S,[#'ComponentType'{prop=mandatory}|Rest]) ->
+ check_unique_sequence_tags0(S,Rest);
+check_unique_sequence_tags0(S,[C=#'ComponentType'{}|Rest]) ->
check_unique_sequence_tags1(S,Rest,[C]);% optional or default
-check_unique_sequence_tags(S,[_ExtensionMarker|Rest]) ->
- check_unique_sequence_tags(S,Rest);
-check_unique_sequence_tags(_S,[]) ->
+check_unique_sequence_tags0(S,[_ExtensionMarker|Rest]) ->
+ check_unique_sequence_tags0(S,Rest);
+check_unique_sequence_tags0(_S,[]) ->
true.
check_unique_sequence_tags1(S,[C|Rest],Acc) when is_record(C,'ComponentType') ->
@@ -5798,8 +5839,10 @@ get_least_tag(TagList) ->
%% adds the textual order to the components to keep right order of
%% components in the asn1-value.
textual_order(Cs) ->
- Fun = fun(C,Index) ->
- {C#'ComponentType'{textual_order=Index},Index+1}
+ Fun = fun(C=#'ComponentType'{},Index) ->
+ {C#'ComponentType'{textual_order=Index},Index+1};
+ (Other,Index) ->
+ {Other,Index}
end,
{NewCs,_} = textual_order(Cs,Fun,1),
NewCs.
@@ -5870,7 +5913,6 @@ check_selectiontype2(S,Name,TypeDef) ->
error({type,Msg,S})
end.
-
check_restrictedstring(_S,_Def,_Constr) ->
ok.
@@ -5885,21 +5927,21 @@ check_relative_oid(_S,_Constr) ->
% - that each alternative is of a valid type
% - that the extension marks are valid
check_choice(S,Type,Components) when is_list(Components) ->
- case check_unique([C||C <- Components,
- is_record(C,'ComponentType')],#'ComponentType'.name) of
+ Components1 = [C||C = #'ComponentType'{} <- Components],
+ case check_unique(Components1,#'ComponentType'.name) of
[] ->
%% sort_canonical(Components),
Components2 = maybe_automatic_tags(S,Components),
- %NewComps =
- case check_each_alternative(S,Type,Components2) of
- {NewComponents,NewEcomps} ->
- check_unique_tags(S,NewComponents ++ NewEcomps),
- {NewComponents,NewEcomps};
- NewComponents ->
- check_unique_tags(S,NewComponents),
- NewComponents
- end;
-
+ NewComps = check_each_alternative2(S,Type,Components2),
+ %% ExtensionAdditionGroup markers i.e '[[' ']]' are not
+ %% significant for encoding/decoding a choice
+ %% therefore we remove them here
+ NewComps2 = lists:filter(fun(#'ExtensionAdditionGroup'{}) -> false;
+ ('ExtensionAdditionGroupEnd') -> false;
+ (_) -> true
+ end,NewComps),
+ check_unique_tags(S,NewComps2),
+ complist_as_tuple(is_erule_per(S#state.erule),NewComps2);
Dupl ->
throw({error,{asn1,{duplicate_choice_alternatives,Dupl}}})
end;
@@ -5927,13 +5969,13 @@ maybe_automatic_tags(S,C) ->
%% Pos == 1 for Root1, 2 for Ext, 3 for Root2
tag_nums(Cl) ->
tag_nums(Cl,0,0).
-tag_nums([{'EXTENSIONMARK',_,_}|Rest],Ext,Root2) ->
+tag_nums([#'EXTENSIONMARK'{}|Rest],Ext,Root2) ->
tag_nums_ext(Rest,Ext,Root2);
tag_nums([_|Rest],Ext,Root2) ->
tag_nums(Rest,Ext+1,Root2+1);
tag_nums([],Ext,Root2) ->
[0,Ext,Root2].
-tag_nums_ext([{'EXTENSIONMARK',_,_}|Rest],Ext,Root2) ->
+tag_nums_ext([#'EXTENSIONMARK'{}|Rest],Ext,Root2) ->
tag_nums_root2(Rest,Ext,Root2);
tag_nums_ext([_|Rest],Ext,Root2) ->
tag_nums_ext(Rest,Ext,Root2);
@@ -5983,7 +6025,7 @@ generate_automatic_tags1([],_) ->
any_manual_tag([#'ComponentType'{typespec=#type{tag=[]}}|Rest]) ->
any_manual_tag(Rest);
-any_manual_tag([{'EXTENSIONMARK',_,_}|Rest]) ->
+any_manual_tag([#'EXTENSIONMARK'{}|Rest]) ->
any_manual_tag(Rest);
any_manual_tag([_|_Rest]) ->
true;
@@ -6027,12 +6069,17 @@ check_unique2([_|T],Pos,Acc) ->
check_unique2([],_,Acc) ->
lists:reverse(Acc).
-check_each_component(S,Type,Components) ->
- check_each_component(S,Type,Components,[],[],[],root1).
-check_each_component(S = #state{abscomppath=Path,recordtopname=TopName},Type,
- [C|Ct],Acc,Extacc,Acc2,Ext) when is_record(C,'ComponentType') ->
- #'ComponentType'{name=Cname,typespec=Ts,prop=Prop} = C,
+%% Replaces check_each_component and does the same work except that
+%% it keeps the complist as a flat list and does not create a tuple with root and
+%% extensions separated
+check_each_component2(S,Type,Components) ->
+ check_each_component2(S,Type,Components,[]).
+
+check_each_component2(S = #state{abscomppath=Path,recordtopname=TopName},
+ Type,
+ [C = #'ComponentType'{name=Cname,typespec=Ts,prop=Prop}|Ct],
+ Acc) ->
NewAbsCPath =
case Ts#type.def of
#'Externaltypereference'{} -> [];
@@ -6049,75 +6096,48 @@ check_each_component(S = #state{abscomppath=Path,recordtopname=TopName},Type,
DefaultValue -> {'DEFAULT',DefaultValue}
end,
NewC = C#'ComponentType'{typespec=CheckedTs,prop=NewProp,tags=NewTags},
- case Ext of
- root1 ->
- check_each_component(S,Type,Ct,[NewC|Acc],Extacc,Acc2,Ext);
- ext ->
- check_each_component(S,Type,Ct,Acc,[NewC|Extacc],Acc2,Ext);
- root2 ->
- check_each_component(S,Type,Ct,Acc,Extacc,[NewC|Acc2],Ext)
- end;
-check_each_component(S,Type,[_|Ct],Acc,Extacc,Acc2,root1) -> % skip 'EXTENSIONMARK'
- check_each_component(S,Type,Ct,Acc,Extacc,Acc2,ext);
-check_each_component(S,Type,[_|Ct],Acc,Extacc,Acc2,ext) -> % skip 'EXTENSIONMARK'
- check_each_component(S,Type,Ct,Acc,Extacc,Acc2,root2);
-check_each_component(_S,_,[_C|_Ct],_,_,_,root2) -> % 'EXTENSIONMARK'
- throw({error,{asn1,{too_many_extension_marks}}});
-check_each_component(_S,_,[],Acc,Extacc,_,ext) ->
- {lists:reverse(Acc),lists:reverse(Extacc)};
-check_each_component(_S,_,[],Acc1,ExtAcc,Acc2,root2) ->
- {lists:reverse(Acc1),lists:reverse(ExtAcc),lists:reverse(Acc2)};
-check_each_component(_S,_,[],Acc,_,_,root1) ->
+ check_each_component2(S,Type,Ct,[NewC|Acc]);
+
+check_each_component2(S,Type,[OtherMarker|Ct],Acc) ->
+ %% let 'EXTENSIONMARK' and 'ExtensionAdditionGroup' markers pass through as is
+ check_each_component2(S,Type,Ct,[OtherMarker|Acc]);
+check_each_component2(_S,_,[],Acc) ->
lists:reverse(Acc).
-%% check_each_alternative(S,Type,{Rlist,ExtList}) ->
+
+%% check_each_alternative2(S,Type,{Rlist,ExtList}) ->
%% {check_each_alternative(S,Type,Rlist),
%% check_each_alternative(S,Type,ExtList)};
-check_each_alternative(S,Type,[C|Ct]) ->
- check_each_alternative(S,Type,[C|Ct],[],[],noext).
+check_each_alternative2(S,Type,[C|Ct]) ->
+ check_each_alternative2(S,Type,[C|Ct],[]).
-check_each_alternative(S=#state{abscomppath=Path,recordtopname=TopName},Type,[C|Ct],
- Acc,Extacc,Ext) when is_record(C,'ComponentType') ->
- #'ComponentType'{name=Cname,typespec=Ts,prop=_Prop} = C,
+check_each_alternative2(S=#state{abscomppath=Path,recordtopname=TopName},
+ Type,
+ [C = #'ComponentType'{name=Cname,typespec=Ts}|Ct],
+ Acc) ->
NewAbsCPath =
case Ts#type.def of
#'Externaltypereference'{} -> [];
_ -> [Cname|Path]
end,
- NewState =
- S#state{abscomppath=NewAbsCPath,recordtopname=[Cname|TopName]},
- CheckedTs = check_type(NewState,Type,Ts),
+ CheckedTs = check_type(S#state{abscomppath=NewAbsCPath,
+ recordtopname=[Cname|TopName]},Type,Ts),
NewTags = get_taglist(S,CheckedTs),
+
NewC = C#'ComponentType'{typespec=CheckedTs,tags=NewTags},
- case Ext of
- noext ->
- check_each_alternative(S,Type,Ct,[NewC|Acc],Extacc,Ext);
- ext ->
- check_each_alternative(S,Type,Ct,Acc,[NewC|Extacc],Ext)
- end;
+ check_each_alternative2(S,Type,Ct,[NewC|Acc]);
-check_each_alternative(S,Type,[_|Ct],Acc,Extacc,noext) -> % skip 'EXTENSIONMARK'
- check_each_alternative(S,Type,Ct,Acc,Extacc,ext);
-check_each_alternative(_S,_,[_C|_Ct],_,_,ext) -> % skip 'EXTENSIONMARK'
- throw({error,{asn1,{too_many_extension_marks}}});
-check_each_alternative(_S,_,[],Acc,Extacc,ext) ->
- {lists:reverse(Acc),lists:reverse(Extacc)};
-check_each_alternative(_S,_,[],Acc,_,noext) ->
+check_each_alternative2(S,Type,[OtherMarker|Ct],Acc) ->
+ %% let 'EXTENSIONMARK' and 'ExtensionAdditionGroup' markers pass through as is
+ check_each_alternative2(S,Type,Ct,[OtherMarker|Acc]);
+check_each_alternative2(_S,_,[],Acc) ->
lists:reverse(Acc).
+
%% componentrelation_leadingattr/2 searches the structure for table
%% constraints, if any is found componentrelation_leadingattr/5 is
%% called.
componentrelation_leadingattr(S,CompList) ->
- Cs =
- case CompList of
- {Comp1, EComps, Comp2} ->
- Comp1++EComps++Comp2;
- {Components,EComponents} when is_list(Components) ->
- Components ++ EComponents;
- CompList when is_list(CompList) ->
- CompList
- end,
%% get_simple_table_if_used/2 should find out whether there are any
%% component relation constraints in the entire tree of Cs1 that
@@ -6126,12 +6146,22 @@ componentrelation_leadingattr(S,CompList) ->
%% componentrelation_leadingattr/6. The step when the leading
%% attribute and the syntax tree is modified to support the code
%% generating.
- case get_simple_table_if_used(S,Cs) of
+ case get_simple_table_if_used(S,CompList) of
[] -> {false,CompList};
- STList ->
- componentrelation_leadingattr(S,Cs,Cs,STList,[],[])
+ _ ->
+ componentrelation_leadingattr(S,CompList,CompList,[],[])
end.
+
+%%FIXME expand_ExtAddGroups([C#'ExtensionAdditionGroup'{components=ExtAdds}|T],
+%% CurrPos,PosAcc,CompAcc) ->
+%% expand_ExtAddGroups(T,CurrPos+ L = lenght(ExtAdds),[{CurrPos,L}|PosAcc],ExtAdds++CompAcc);
+%% expand_ExtAddGroups([C|T],CurrPos,PosAcc,CompAcc) ->
+%% expand_ExtAddGroups(T,CurrPos+ 1,PosAcc,[C|CompAcc]);
+%% expand_ExtAddGroups([],_CurrPos,PosAcc,CompAcc) ->
+%% {lists:reverse(PosAcc),lists:reverse(CompAcc)}.
+
+
%% componentrelation_leadingattr/6 when all components are searched
%% the new modified components are returned together with the "leading
%% attribute" information, which later is stored in the tablecinf
@@ -6141,11 +6171,12 @@ componentrelation_leadingattr(S,CompList) ->
%% is used in code generating phase too, to recognice the proper
%% components for "open type" encoding and to propagate the result of
%% the object set lookup when needed.
-componentrelation_leadingattr(_,[],_CompList,_,[],NewCompList) ->
+componentrelation_leadingattr(_,[],_CompList,[],NewCompList) ->
{false,lists:reverse(NewCompList)};
-componentrelation_leadingattr(_,[],_CompList,_,LeadingAttr,NewCompList) ->
+componentrelation_leadingattr(_,[],_CompList,LeadingAttr,NewCompList) ->
{lists:last(LeadingAttr),lists:reverse(NewCompList)}; %send all info in Ts later
-componentrelation_leadingattr(S,[C|Cs],CompList,STList,Acc,CompAcc) ->
+
+componentrelation_leadingattr(S,[C= #'ComponentType'{}|Cs],CompList,Acc,CompAcc) ->
{LAAcc,NewC} =
case catch componentrelation1(S,C#'ComponentType'.typespec,
[C#'ComponentType'.name]) of
@@ -6196,7 +6227,7 @@ componentrelation_leadingattr(S,[C|Cs],CompList,STList,Acc,CompAcc) ->
%% no constraint was found
{[],C}
end,
- componentrelation_leadingattr(S,Cs,CompList,STList,LAAcc++Acc,
+ componentrelation_leadingattr(S,Cs,CompList,LAAcc++Acc,
[NewC|CompAcc]).
object_set_mod_name(_S,ObjSet) when is_atom(ObjSet) ->
@@ -6219,11 +6250,9 @@ object_set_mod_name(S,#'Externaltypereference'{module=M,type=T}) ->
%% generation of the look up functionality in the object set table are
%% returned.
get_simple_table_if_used(S,Cs) ->
- CNames = lists:map(fun(#'ComponentType'{name=Name}) -> Name;
- (_) -> [] %% in case of extension marks
- end,
- Cs),
- RefedSimpleTable=any_component_relation(S,Cs,CNames,[],[]),
+ CNames = [Name||#'ComponentType'{name=Name}<-Cs],
+ JustComponents = [C || C = #'ComponentType'{}<-Cs],
+ RefedSimpleTable=any_component_relation(S,JustComponents,CNames,[],[]),
get_simple_table_info(S,Cs,remove_doubles(RefedSimpleTable)).
remove_doubles(L) ->
@@ -6327,9 +6356,7 @@ simple_table_info(S,Type,_) ->
%% beginning of the search. CNames holds the names of all components
%% of the start level, this info is used if an outermost at-notation
%% is found to check the validity of the at-list.
-any_component_relation(S,[C|Cs],CNames,NamePath,Acc) ->
- CName = C#'ComponentType'.name,
- Type = C#'ComponentType'.typespec,
+any_component_relation(S,[#'ComponentType'{name=CName,typespec=Type}|Cs],CNames,NamePath,Acc) ->
CRelPath =
case constraint_member(componentrelation,Type#type.constraint) of
%% [{componentrelation,_,AtNotation}] ->
@@ -6349,9 +6376,9 @@ any_component_relation(S,[C|Cs],CNames,NamePath,Acc) ->
case {Type#type.inlined,
asn1ct_gen:type(asn1ct_gen:get_inner(Type#type.def))} of
{no,{constructed,bif}} ->
+
{InnerCs,NewNamePath} =
case get_components(Type#type.def) of
- {IC1,_IC2} -> {IC1 ++ IC1,[CName|NamePath]};
T when is_record(T,type) -> {T,NamePath};
IC -> {IC,[CName|NamePath]}
end,
@@ -6375,16 +6402,18 @@ any_component_relation(S,Type,CNames,NamePath,Acc) when is_record(Type,type) ->
case {Type#type.inlined,
asn1ct_gen:type(asn1ct_gen:get_inner(Type#type.def))} of
{no,{constructed,bif}} ->
- InnerCs =
- case get_components(Type#type.def) of
- {IC1,_IC2} -> IC1 ++ IC1;
- IC -> IC
- end,
+ InnerCs = get_components(Type#type.def),
any_component_relation(S,InnerCs,CNames,NamePath,[]);
_ ->
[]
end,
InnerAcc ++ CRelPath ++ Acc;
+%% Just skip the markers for ExtensionAdditionGroup start and end
+%% in this function
+any_component_relation(S,[#'ExtensionAdditionGroup'{}|Cs],CNames,NamePath,Acc) ->
+ any_component_relation(S,Cs,CNames,NamePath,Acc);
+any_component_relation(S,['ExtensionAdditionGroupEnd'|Cs],CNames,NamePath,Acc) ->
+ any_component_relation(S,Cs,CNames,NamePath,Acc);
any_component_relation(_,[],_,_,Acc) ->
Acc.
@@ -6447,11 +6476,11 @@ get_components(Def) ->
get_components(any,Def).
get_components(_,#'SEQUENCE'{components=Cs}) ->
- Cs;
+ tuple2complist(Cs);
get_components(_,#'SET'{components=Cs}) ->
- Cs;
+ tuple2complist(Cs);
get_components(_,{'CHOICE',Cs}) ->
- Cs;
+ tuple2complist(Cs);
%do not step in inlined structures
get_components(any,{'SEQUENCE OF',T = #type{def=_Def,inlined=no}}) ->
% get_components(any,Def);
@@ -6462,6 +6491,13 @@ get_components(any,{'SET OF',T = #type{def=_Def,inlined=no}}) ->
get_components(_,_) ->
[].
+tuple2complist({R,E}) ->
+ R ++ E;
+tuple2complist({R1,E,R2}) ->
+ R1 ++ E ++ R2;
+tuple2complist(List) when is_list(List) ->
+ List.
+
get_choice_components(_S,{'CHOICE',Components}) when is_list(Components)->
Components;
get_choice_components(_S,{'CHOICE',{C1,C2}}) when is_list(C1),is_list(C2) ->
@@ -6722,8 +6758,7 @@ get_tableconstraint_info(S,Type,CheckedTs) ->
get_tableconstraint_info(_S,_Type,[],Acc) ->
lists:reverse(Acc);
-get_tableconstraint_info(S,Type,[C|Cs],Acc) ->
- CheckedTs = C#'ComponentType'.typespec,
+get_tableconstraint_info(S,Type,[C=#'ComponentType'{typespec=CheckedTs}|Cs],Acc) ->
AccComp =
case CheckedTs#type.def of
%% ObjectClassFieldType
@@ -6759,7 +6794,9 @@ get_tableconstraint_info(S,Type,[C|Cs],Acc) ->
_ ->
C
end,
- get_tableconstraint_info(S,Type,Cs,[AccComp|Acc]).
+ get_tableconstraint_info(S,Type,Cs,[AccComp|Acc]);
+get_tableconstraint_info(S,Type,[C|Cs],Acc) ->
+ get_tableconstraint_info(S,Type,Cs,[C|Acc]).
get_referenced_fieldname([{_,FirstFieldname}]) ->
{FirstFieldname,[]};
@@ -6841,7 +6878,9 @@ get_taglist(S,Type) when is_record(Type,type) ->
[asn1ct_gen:def_to_tag(Tag)]
end;
get_taglist(S,{'CHOICE',{Rc,Ec}}) ->
- get_taglist(S,{'CHOICE',Rc ++ Ec});
+ get_taglist1(S,Rc ++ Ec);
+get_taglist(S,{'CHOICE',{R1,E,R2}}) ->
+ get_taglist1(S,R1 ++ E ++ R2);
get_taglist(S,{'CHOICE',Components}) ->
get_taglist1(S,Components);
%% ObjectClassFieldType OTP-4390
diff --git a/lib/asn1/src/asn1ct_constructed_ber.erl b/lib/asn1/src/asn1ct_constructed_ber.erl
index 51a241ffbd..77b78dcac7 100644
--- a/lib/asn1/src/asn1ct_constructed_ber.erl
+++ b/lib/asn1/src/asn1ct_constructed_ber.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%
%%
%%
@@ -71,13 +71,15 @@ gen_encode_sequence(Erules,Typename,D) when is_record(D,type) ->
ok
end,
- {SeqOrSet,TableConsInfo,CompList} =
+ {SeqOrSet,TableConsInfo,CompList0} =
case D#type.def of
#'SEQUENCE'{tablecinf=TCI,components=CL} ->
{'SEQUENCE',TCI,CL};
#'SET'{tablecinf=TCI,components=CL} ->
{'SET',TCI,CL}
end,
+ %% filter away extensionAdditiongroup markers
+ CompList = filter_complist(CompList0),
Ext = extensible(CompList),
CompList1 = case CompList of
{Rl1,El,Rl2} -> Rl1 ++ El ++ Rl2;
@@ -189,7 +191,11 @@ gen_encode_sequence(Erules,Typename,D) when is_record(D,type) ->
gen_decode_sequence(Erules,Typename,D) when is_record(D,type) ->
asn1ct_name:start(),
asn1ct_name:new(tag),
- #'SEQUENCE'{tablecinf=TableConsInfo,components=CList} = D#type.def,
+ #'SEQUENCE'{tablecinf=TableConsInfo,components=CList0} = D#type.def,
+
+ %% filter away extensionAdditiongroup markers
+ CList = filter_complist(CList0),
+
Ext = extensible(CList),
{CompList,CompList2} = case CList of
{Rl1,El,Rl2} -> {Rl1 ++ El ++ Rl2,CList};
@@ -369,7 +375,10 @@ gen_decode_set(Erules,Typename,D) when is_record(D,type) ->
asn1ct_name:clear(),
asn1ct_name:new(term),
asn1ct_name:new(tag),
- #'SET'{components=TCompList} = D#type.def,
+ #'SET'{components=TCompList0} = D#type.def,
+
+ %% filter away extensionAdditiongroup markers
+ TCompList = filter_complist(TCompList0),
Ext = extensible(TCompList),
ToOptional = fun(mandatory) ->
'OPTIONAL';
@@ -1473,6 +1482,22 @@ extensible({RootList,ExtList}) ->
{ext,length(RootList)+1,length(ExtList)};
extensible({_Rl1,_ExtL,_Rl2}) ->
extensible.
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%% filter away ExtensionAdditionGroup start and end marks since these
+%% have no significance for the BER encoding
+%%
+filter_complist(CompList) when is_list(CompList) ->
+ lists:filter(fun(#'ExtensionAdditionGroup'{}) ->
+ false;
+ ('ExtensionAdditionGroupEnd') ->
+ false;
+ (_) ->
+ true
+ end, CompList);
+filter_complist({Root,Ext}) ->
+ {Root,filter_complist(Ext)};
+filter_complist({Root1,Ext,Root2}) ->
+ {Root1,filter_complist(Ext),Root2}.
print_attribute_comment(InnerType,Pos,Prop) ->
CommentLine = "%%-------------------------------------------------",
diff --git a/lib/asn1/src/asn1ct_constructed_ber_bin_v2.erl b/lib/asn1/src/asn1ct_constructed_ber_bin_v2.erl
index a55ac9db8e..e3be914af4 100644
--- a/lib/asn1/src/asn1ct_constructed_ber_bin_v2.erl
+++ b/lib/asn1/src/asn1ct_constructed_ber_bin_v2.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2002-2009. All Rights Reserved.
+%% Copyright Ericsson AB 2002-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
@@ -75,13 +75,15 @@ gen_encode_sequence(Erules,Typename,D) when is_record(D,type) ->
"Val"
end,
- {SeqOrSet,TableConsInfo,CompList} =
+ {SeqOrSet,TableConsInfo,CompList0} =
case D#type.def of
#'SEQUENCE'{tablecinf=TCI,components=CL} ->
{'SEQUENCE',TCI,CL};
#'SET'{tablecinf=TCI,components=CL} ->
{'SET',TCI,CL}
end,
+ %% filter away extensionAdditiongroup markers
+ CompList = filter_complist(CompList0),
Ext = extensible(CompList),
CompList1 = case CompList of
{Rl1,El,Rl2} -> Rl1 ++ El ++ Rl2;
@@ -183,7 +185,10 @@ gen_decode_sequence(Erules,Typename,D) when is_record(D,type) ->
asn1ct_name:start(),
asn1ct_name:clear(),
asn1ct_name:new(tag),
- #'SEQUENCE'{tablecinf=TableConsInfo,components=CList} = D#type.def,
+ #'SEQUENCE'{tablecinf=TableConsInfo,components=CList0} = D#type.def,
+
+ %% filter away extensionAdditiongroup markers
+ CList = filter_complist(CList0),
Ext = extensible(CList),
{CompList,CompList2} =
case CList of
@@ -345,7 +350,9 @@ gen_decode_set(Erules,Typename,D) when is_record(D,type) ->
asn1ct_name:clear(),
%% asn1ct_name:new(term),
asn1ct_name:new(tag),
- #'SET'{tablecinf=TableConsInfo,components=TCompList} = D#type.def,
+ #'SET'{tablecinf=TableConsInfo,components=TCompList0} = D#type.def,
+ %% filter away extensionAdditiongroup markers
+ TCompList = filter_complist(TCompList0),
Ext = extensible(TCompList),
ToOptional = fun(mandatory) ->
'OPTIONAL';
@@ -1426,6 +1433,22 @@ extensible({RootList,ExtList}) ->
{ext,length(RootList)+1,length(ExtList)};
extensible({_Rl1,_Ext,_Rl2}) ->
extensible.
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%% filter away ExtensionAdditionGroup start and end marks since these
+%% have no significance for the BER encoding
+%%
+filter_complist(CompList) when is_list(CompList) ->
+ lists:filter(fun(#'ExtensionAdditionGroup'{}) ->
+ false;
+ ('ExtensionAdditionGroupEnd') ->
+ false;
+ (_) ->
+ true
+ end, CompList);
+filter_complist({Root,Ext}) ->
+ {Root,filter_complist(Ext)};
+filter_complist({Root1,Ext,Root2}) ->
+ {Root1,filter_complist(Ext),Root2}.
print_attribute_comment(InnerType,Pos,Cname,Prop) ->
diff --git a/lib/asn1/src/asn1ct_constructed_per.erl b/lib/asn1/src/asn1ct_constructed_per.erl
index 2a1c0ebc6b..cce6eb9831 100644
--- a/lib/asn1/src/asn1ct_constructed_per.erl
+++ b/lib/asn1/src/asn1ct_constructed_per.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%
%%
%%
@@ -46,18 +46,29 @@ gen_encode_constructed(Erule,Typename,D) when is_record(D,type) ->
asn1ct_name:start(),
asn1ct_name:new(term),
asn1ct_name:new(bytes),
- {CompList,TableConsInfo} =
+ {ExtAddGroup,TmpCompList,TableConsInfo} =
case D#type.def of
- #'SEQUENCE'{tablecinf=TCI,components=CL} ->
- {CL,TCI};
+ #'SEQUENCE'{tablecinf=TCI,components=CL,extaddgroup=ExtAddGroup0} ->
+ {ExtAddGroup0,CL,TCI};
#'SET'{tablecinf=TCI,components=CL} ->
- {CL,TCI}
+ {undefined,CL,TCI}
end,
+
+ CompList = case ExtAddGroup of
+ undefined ->
+ TmpCompList;
+ _ when is_integer(ExtAddGroup) ->
+ %% This is a fake SEQUENCE representing an ExtensionAdditionGroup
+ %% Reset the textual order so we get the right
+ %% index of the components
+ [Comp#'ComponentType'{textual_order=undefined}||
+ Comp<-TmpCompList]
+ end,
case Typename of
['EXTERNAL'] ->
- emit({{var,asn1ct_name:next(val)},
+ emit({{next,val},
" = asn1rt_check:transform_to_EXTERNAL1990(",
- {var,asn1ct_name:curr(val)},"),",nl}),
+ {curr,val},"),",nl}),
asn1ct_name:new(val);
_ ->
ok
@@ -66,23 +77,40 @@ gen_encode_constructed(Erule,Typename,D) when is_record(D,type) ->
{[],EmptyCL} when EmptyCL == {[],[],[]};EmptyCL == {[],[]};EmptyCL == [] ->
emit(["%%Variable setting just to eliminate ",
"compiler warning for unused vars!",nl,
- "_Val = ",{var,asn1ct_name:curr(val)},",",nl]);
+ "_Val = ",{curr,val},",",nl]);
{[],_} ->
- emit([{var,asn1ct_name:next(val)}," = ?RT_PER:list_to_record("]),
+ emit([{next,val}," = ?RT_PER:list_to_record("]),
emit(["'",asn1ct_gen:list2rname(Typename),"'"]),
- emit([", ",{var,asn1ct_name:curr(val)},"),",nl]);
+ emit([", ",{curr,val},"),",nl]);
_ ->
Fixoptcall = ",Opt} = ?RT_PER:fixoptionals(",
- emit({"{",{var,asn1ct_name:next(val)},Fixoptcall,
+ emit({"{",{next,val},Fixoptcall,
{asis,Optionals},",",length(Optionals),
- ",",{var,asn1ct_name:curr(val)},"),",nl})
+ ",",{curr,val},"),",nl})
end,
asn1ct_name:new(val),
- Ext = extensible(CompList),
+ Ext = extensible_enc(CompList),
case Ext of
{ext,_,NumExt} when NumExt > 0 ->
- emit(["Extensions = ?RT_PER:fixextensions(",{asis,Ext},
- ", ",{curr,val},"),",nl]);
+ case extgroup_pos_and_length(CompList) of
+ {extgrouppos,ExtGroupPos,ExtGroupLen} ->
+ Elements = make_elements(ExtGroupPos+1,
+ "Val1",lists:seq(1,ExtGroupLen)),
+ emit([
+ {next,val}," = case [X || X <- [",Elements,
+ "],X =/= asn1_NOVALUE] of",nl,
+ "[] -> ",{curr,val},";",nl,
+ "_ -> setelement(",{asis,ExtGroupPos+1},",",
+ {curr,val},",",
+ "{extaddgroup,", Elements,"})",nl,
+ "end,",nl]),
+ asn1ct_name:new(val);
+ _ -> % no extensionAdditionGroup
+ ok
+ end,
+ asn1ct_name:new(tmpval),
+ emit(["Extensions = ?RT_PER:fixextensions(",{asis,Ext},",",
+ {curr,val},"),",nl]);
_ -> true
end,
EncObj =
@@ -188,9 +216,10 @@ gen_decode_constructed(Erules,Typename,D) when is_record(D,type) ->
#'SEQUENCE'{tablecinf=TCI,components=CL} ->
{add_textual_order(CL),TCI};
#'SET'{tablecinf=TCI,components=CL} ->
- {add_textual_order(CL),TCI}
+%% {add_textual_order(CL),TCI}
+ {CL,TCI} % the textual order is already taken care of
end,
- Ext = extensible(CompList),
+ Ext = extensible_dec(CompList),
MaybeComma1 = case Ext of
{ext,_Pos,_NumExt} ->
gen_dec_extension_value("Bytes"),
@@ -243,8 +272,9 @@ gen_decode_constructed(Erules,Typename,D) when is_record(D,type) ->
{false,false,false}
end
end,
+ NewCompList = wrap_compList(CompList),
{AccTerm,AccBytes} =
- gen_dec_components_call(Erules,Typename,CompList,MaybeComma2,DecObjInf,Ext,length(Optionals)),
+ gen_dec_components_call(Erules,Typename,NewCompList,MaybeComma2,DecObjInf,Ext,length(Optionals)),
case asn1ct_name:all(term) of
[] -> emit(MaybeComma2); % no components at all
_ -> emit({com,nl})
@@ -284,26 +314,24 @@ gen_decode_constructed(Erules,Typename,D) when is_record(D,type) ->
emit(" {ASN11994Format,");
_ ->
emit(["{{'",RecordName,"'"]),
- mkvlist(textual_order(CompList,asn1ct_name:all(term))),
+ %% CompList is used here because we don't want
+ %% ExtensionAdditionGroups to be wrapped in SEQUENCES when
+ %% we are ordering the fields according to textual order
+ mkvlist(textual_order(to_encoding_order(CompList),asn1ct_name:all(term))),
emit("},")
end,
- emit({{var,asn1ct_name:curr(bytes)},"}"}),
+ emit({{curr,bytes},"}"}),
emit({".",nl,nl}).
textual_order([#'ComponentType'{textual_order=undefined}|_],TermList) ->
TermList;
textual_order(CompList,TermList) when is_list(CompList) ->
- TermTuple = list_to_tuple(TermList), %% ['Term1','Term2',...'TermN']
- %% OrderList is ordered by canonical order of tags
- TmpTuple = TermTuple,
- OrderList = [Ix||#'ComponentType'{textual_order=Ix} <- CompList],
- Fun = fun(X,{Tpl,Ix}) ->
-
- {setelement(X,Tpl,element(Ix,TermTuple)),Ix+1}
- end,
- {Ret,_} = lists:foldl(Fun,{TmpTuple,1},OrderList),
-%% io:format("TermTuple: ~p~nOrderList: ~p~nRet: ~p~n",[TermTuple,OrderList,tuple_to_list(Ret)]),
- tuple_to_list(Ret);
+ OrderList = [Ix||#'ComponentType'{textual_order=Ix} <- CompList],
+ [Term||{_,Term}<-
+ lists:sort(lists:zip(OrderList,
+ lists:sublist(TermList,length(OrderList))))];
+ %% sublist is just because Termlist can sometimes be longer than
+ %% OrderList, which it really shouldn't
textual_order({Root,Ext},TermList) ->
textual_order(Root ++ Ext,TermList);
textual_order({Root1,Ext,Root2},TermList) ->
@@ -379,7 +407,7 @@ emit_opt_or_mand_check(Val,Term) ->
gen_encode_choice(Erule,Typename,D) when is_record(D,type) ->
{'CHOICE',CompList} = D#type.def,
emit({"[",nl}),
- Ext = extensible(CompList),
+ Ext = extensible_enc(CompList),
gen_enc_choice(Erule,Typename,CompList,Ext),
emit({nl,"].",nl}).
@@ -388,7 +416,7 @@ gen_decode_choice(Erules,Typename,D) when is_record(D,type) ->
asn1ct_name:clear(),
asn1ct_name:new(bytes),
{'CHOICE',CompList} = D#type.def,
- Ext = extensible(CompList),
+ Ext = extensible_enc(CompList),
gen_dec_choice(Erules,Typename,CompList,Ext),
emit({".",nl}).
@@ -558,12 +586,53 @@ mkvlist2([H|T]) ->
mkvlist2([]) ->
true.
-extensible(CompList) when is_list(CompList) ->
+
+extensible_dec(CompList) when is_list(CompList) ->
noext;
-extensible({RootList,ExtList}) ->
- {ext,length(RootList)+1,length(ExtList)};
-extensible({Rl1,Ext,_Rl2}) ->
- {ext,length(Rl1)+1,length(Ext)}.
+extensible_dec({RootList,ExtList}) ->
+ {ext,length(RootList)+1,ext_length(ExtList)};
+extensible_dec({Rl1,Ext,Rl2}) ->
+ {ext,length(Rl1)+length(Rl2)+1,ext_length(Ext)}.
+
+extensible_enc(CompList) when is_list(CompList) ->
+ noext;
+extensible_enc({RootList,ExtList}) ->
+ {ext,length(RootList)+1,ext_length(ExtList)};
+extensible_enc({Rl1,Ext,_Rl2}) ->
+ {ext,length(Rl1)+1,ext_length(Ext)}.
+
+ext_length(ExtList) -> ext_length(ExtList,normal,0).
+ext_length([{'ExtensionAdditionGroup',_Num}|T],_,Acc)->
+ ext_length(T,group,Acc);
+ext_length(['ExtensionAdditionGroupEnd'|T],group,Acc) ->
+ ext_length(T,normal,Acc+1);
+ext_length([#'ComponentType'{}|T],State=group,Acc) ->
+ ext_length(T,State,Acc);
+ext_length([#'ComponentType'{}|T],State=normal,Acc) ->
+ ext_length(T,State,Acc+1);
+ext_length([],_,Acc) ->
+ Acc.
+
+extgroup_pos_and_length(CompList) when is_list(CompList) ->
+ noextgroup;
+extgroup_pos_and_length({RootList,ExtList}) ->
+ extgrouppos(ExtList,length(RootList)+1);
+extgroup_pos_and_length({Rl1,Ext,_Rl2}) ->
+ extgrouppos(Ext,length(Rl1)+1).
+
+extgrouppos([{'ExtensionAdditionGroup',_Num}|T],Pos) ->
+ extgrouppos(T,Pos,0);
+extgrouppos([_|T],Pos) ->
+ extgrouppos(T,Pos+1);
+extgrouppos([],_) ->
+ noextgroup.
+
+extgrouppos(['ExtensionAdditionGroupEnd'|_T],Pos,Len) ->
+ {extgrouppos,Pos,Len};
+extgrouppos([_|T],Pos,Len) ->
+ extgrouppos(T,Pos,Len+1).
+
+
gen_dec_extension_value(_) ->
emit({"{Ext,",{next,bytes},"} = ?RT_PER:getext(",{curr,bytes},")"}),
@@ -574,7 +643,11 @@ gen_dec_extension_value(_) ->
%% there are optional components, start with 2 because first element
%% is the record name
-optionals({L1,_Ext,L2}) -> optionals(L1++L2,[],2);
+optionals({L1,Ext,L2}) ->
+ Opt1 = optionals(L1,[],2),
+ ExtComps = length([C||C = #'ComponentType'{}<-Ext]),
+ Opt2 = optionals(L2,[],2+length(L1)+ExtComps),
+ Opt1 ++ Opt2;
optionals({L,_Ext}) -> optionals(L,[],2);
optionals(L) -> optionals(L,[],2).
@@ -617,6 +690,13 @@ get_optionality_pos(TextPos,OptTable) ->
no_num
end.
+to_encoding_order(Cs) when is_list(Cs) ->
+ Cs;
+to_encoding_order(Cs = {_Root,_Ext}) ->
+ Cs;
+to_encoding_order({R1,Ext,R2}) ->
+ {R1++R2,Ext}.
+
add_textual_order(Cs) when is_list(Cs) ->
{NewCs,_} = add_textual_order1(Cs,1),
NewCs;
@@ -629,26 +709,20 @@ add_textual_order({R1,Ext,R2}) ->
{NewExt,Num2} = add_textual_order1(Ext,Num1),
{NewR2,_} = add_textual_order1(R2,Num2),
{NewR1,NewExt,NewR2}.
-add_textual_order1(Cs=[#'ComponentType'{textual_order=Int}|_],I)
- when is_integer(Int) ->
- {Cs,I};
+%%add_textual_order1(Cs=[#'ComponentType'{textual_order=Int}|_],I)
+%% when is_integer(Int) ->
+%% {Cs,I};
add_textual_order1(Cs,NumIn) ->
- lists:mapfoldl(fun(C,Num) ->
+ lists:mapfoldl(fun(C=#'ComponentType'{},Num) ->
{C#'ComponentType'{textual_order=Num},
- Num+1}
+ Num+1};
+ (OtherMarker,Num) ->
+ {OtherMarker,Num}
end,
NumIn,Cs).
gen_enc_components_call(Erule,TopType,{Root1,ExtList,Root2},MaybeComma,DynamicEnc,Ext) ->
- Rpos = gen_enc_components_call1(Erule,TopType,Root1,1,MaybeComma,DynamicEnc,noext),
- case Ext of
- {ext,_,ExtNum} when ExtNum > 0 ->
- emit([nl,
- ",Extensions",nl]);
- _ -> true
- end,
- Rpos2 = gen_enc_components_call1(Erule,TopType,ExtList,Rpos,MaybeComma,DynamicEnc,Ext),
- gen_enc_components_call1(Erule,TopType,Root2,Rpos2,MaybeComma,DynamicEnc,noext);
+ gen_enc_components_call(Erule,TopType,{Root1++Root2,ExtList},MaybeComma,DynamicEnc,Ext);
gen_enc_components_call(Erule,TopType,{CompList,ExtList},MaybeComma,DynamicEnc,Ext) ->
%% The type has extensionmarker
Rpos = gen_enc_components_call1(Erule,TopType,CompList,1,MaybeComma,DynamicEnc,noext),
@@ -659,7 +733,8 @@ gen_enc_components_call(Erule,TopType,{CompList,ExtList},MaybeComma,DynamicEnc,E
_ -> true
end,
%handle extensions
- gen_enc_components_call1(Erule,TopType,ExtList,Rpos,MaybeComma,DynamicEnc,Ext);
+ NewExtList = wrap_extensionAdditionGroups(ExtList),
+ gen_enc_components_call1(Erule,TopType,NewExtList,Rpos,MaybeComma,DynamicEnc,Ext);
gen_enc_components_call(Erule,TopType, CompList, MaybeComma, DynamicEnc, Ext) ->
%% The type has no extensionmarker
gen_enc_components_call1(Erule,TopType,CompList,1,MaybeComma,DynamicEnc,Ext).
@@ -706,7 +781,7 @@ gen_enc_components_call1(_Erule,_TopType,[],Pos,_,_,_) ->
Pos.
gen_enc_component_default(Erule,TopType,Cname,Type,Pos,DynamicEnc,Ext,DefaultVal) ->
- Element = make_element(Pos+1,"Val1",Cname),
+ Element = make_element(Pos+1,asn1ct_gen:mk_var(asn1ct_name:curr(val)),Cname),
emit({"case ",Element," of",nl}),
% emit({"asn1_DEFAULT -> [];",nl}),
emit({"DFLT when DFLT == asn1_DEFAULT; DFLT == ",{asis,DefaultVal}," -> [];",nl}),
@@ -719,8 +794,27 @@ gen_enc_component_default(Erule,TopType,Cname,Type,Pos,DynamicEnc,Ext,DefaultVal
NextElement = asn1ct_gen:mk_var(asn1ct_name:curr(tmpval)),
gen_enc_line(Erule,TopType,Cname,Type,NextElement, Pos,DynamicEnc,Ext),
emit({nl,"end"}).
+
+gen_enc_component_optional(Erule,TopType,Cname,
+ Type=#type{def=#'SEQUENCE'{
+ extaddgroup=Number,
+ components=_ExtGroupCompList}},
+ Pos,DynamicEnc,Ext) when is_integer(Number) ->
+
+ Element = make_element(Pos+1,asn1ct_gen:mk_var(asn1ct_name:curr(val)),Cname),
+ emit({"case ",Element," of",nl}),
+
+ emit({"asn1_NOVALUE -> [];",nl}),
+ asn1ct_name:new(tmpval),
+ emit({{curr,tmpval}," ->",nl}),
+ InnerType = asn1ct_gen:get_inner(Type#type.def),
+ emit({nl,"%% attribute number ",Pos," with type ",
+ InnerType,nl}),
+ NextElement = asn1ct_gen:mk_var(asn1ct_name:curr(tmpval)),
+ gen_enc_line(Erule,TopType,Cname,Type,NextElement, Pos,DynamicEnc,Ext),
+ emit({nl,"end"});
gen_enc_component_optional(Erule,TopType,Cname,Type,Pos,DynamicEnc,Ext) ->
- Element = make_element(Pos+1,"Val1",Cname),
+ Element = make_element(Pos+1,asn1ct_gen:mk_var(asn1ct_name:curr(val)),Cname),
emit({"case ",Element," of",nl}),
emit({"asn1_NOVALUE -> [];",nl}),
@@ -834,29 +928,7 @@ gen_enc_line(Erule,TopType,Cname,Type,Element, _Pos,DynamicEnc,Ext) ->
_ -> true
end.
gen_dec_components_call(Erule,TopType,{Root1,ExtList,Root2},MaybeComma,DecInfObj,Ext,NumberOfOptionals) ->
- %% The type has extensionmarker
- OptTable = create_optionality_table(Root1 ++ Root2),
- {Rpos,AccTerm,AccBytes} =
- gen_dec_components_call1(Erule,TopType, Root1, 1, OptTable,
- MaybeComma,DecInfObj, noext,[],[],
- NumberOfOptionals),
- emit([",",nl,"{Extensions,",{next,bytes},"} = "]),
- emit(["?RT_PER:getextension(Ext,",{curr,bytes},"),",nl]),
- asn1ct_name:new(bytes),
- {Epos,AccTermE,AccBytesE} =
- gen_dec_components_call1(Erule,TopType,ExtList,Rpos, OptTable, "",
- DecInfObj,Ext,[],[],NumberOfOptionals),
- case ExtList of
- [] -> true;
- _ -> emit([",",nl])
- end,
- emit([{next,bytes},"= ?RT_PER:skipextensions(",{curr,bytes},",",
- length(ExtList)+1,",Extensions),",nl]),
- asn1ct_name:new(bytes),
- {_RPos2,AccTerm2,AccBytes2} =
- gen_dec_components_call1(Erule,TopType,Root2,Epos,OptTable,
- "",DecInfObj,noext,[],[],NumberOfOptionals),
- {AccTerm++AccTermE++AccTerm2,AccBytes++AccBytesE++AccBytes2};
+ gen_dec_components_call(Erule,TopType,{Root1++Root2,ExtList},MaybeComma,DecInfObj,Ext,NumberOfOptionals);
gen_dec_components_call(Erule,TopType,{CompList,ExtList},MaybeComma,
DecInfObj,Ext,NumberOfOptionals) ->
%% The type has extensionmarker
@@ -868,8 +940,9 @@ gen_dec_components_call(Erule,TopType,{CompList,ExtList},MaybeComma,
emit([",",nl,"{Extensions,",{next,bytes},"} = "]),
emit(["?RT_PER:getextension(Ext,",{curr,bytes},"),",nl]),
asn1ct_name:new(bytes),
+ NewExtList = wrap_extensionAdditionGroups(ExtList),
{_Epos,AccTermE,AccBytesE} =
- gen_dec_components_call1(Erule,TopType,ExtList,Rpos, OptTable,
+ gen_dec_components_call1(Erule,TopType,NewExtList,Rpos, OptTable,
"",DecInfObj,Ext,[],[],NumberOfOptionals),
case ExtList of
[] -> true;
@@ -942,8 +1015,18 @@ gen_dec_components_call1(Erule,TopType,
asn1ct_name:new(tmpterm),
emit({"{",{curr,tmpterm},", ",{next,bytes},"} = "});
_ ->
- asn1ct_name:new(term),
- emit({"{",{curr,term},",",{next,bytes},"} = "})
+ case Type of
+ #type{def=#'SEQUENCE'{
+ extaddgroup=Number1,
+ components=ExtGroupCompList1}} when is_integer(Number1)->
+ emit({"{{_,"}),
+ emit_extaddgroupTerms(term,ExtGroupCompList1),
+ emit({"}"});
+ _ ->
+ asn1ct_name:new(term),
+ emit({"{",{curr,term}})
+ end,
+ emit({",",{next,bytes},"} = "})
end,
case {Ext,Prop,is_optimized(Erule)} of
@@ -967,11 +1050,24 @@ gen_dec_components_call1(Erule,TopType,
{noext,mandatory} -> true; % generate nothing
{noext,_} ->
emit([";",nl,"0 ->"]),
- gen_dec_component_no_val(TopType,Cname,Type,Prop,Tpos,Ext),
+ emit(["{"]),
+ gen_dec_component_no_val(Ext,Prop),
+ emit({",",{curr,bytes},"}",nl}),
emit([nl,"end"]);
_ ->
emit([";",nl,"_ ->",nl]),
- gen_dec_component_no_val(TopType,Cname,Type,Prop,Tpos,Ext),
+ emit(["{"]),
+ case Type of
+ #type{def=#'SEQUENCE'{
+ extaddgroup=Number2,
+ components=ExtGroupCompList2}} when is_integer(Number2)->
+ emit({"{extAddGroup,"}),
+ gen_dec_extaddGroup_no_val(Ext,ExtGroupCompList2),
+ emit({"}"});
+ _ ->
+ gen_dec_component_no_val(Ext,Prop)
+ end,
+ emit({",",{curr,bytes},"}",nl}),
emit([nl,"end"])
end,
asn1ct_name:new(bytes),
@@ -988,13 +1084,22 @@ gen_dec_components_call1(Erule,TopType,
gen_dec_components_call1(_,_TopType,[],Pos,_OptTable,_,_,_,AccTerm,AccBytes,_NumberOfOptionals) ->
{Pos,AccTerm,AccBytes}.
-
-gen_dec_component_no_val(_,_,_,{'DEFAULT',DefVal},_,_) ->
- emit(["{",{asis,DefVal},",",{curr,bytes},"}",nl]);
-gen_dec_component_no_val(_,_,_,'OPTIONAL',_,_) ->
- emit({"{asn1_NOVALUE,",{curr,bytes},"}",nl});
-gen_dec_component_no_val(_,_,_,mandatory,_,{ext,_,_}) ->
- emit({"{asn1_NOVALUE,",{curr,bytes},"}",nl}).
+gen_dec_extaddGroup_no_val(Ext,[#'ComponentType'{prop=Prop}])->
+ gen_dec_component_no_val(Ext,Prop),
+ ok;
+gen_dec_extaddGroup_no_val(Ext,[#'ComponentType'{prop=Prop}|Rest])->
+ gen_dec_component_no_val(Ext,Prop),
+ emit({","}),
+ gen_dec_extaddGroup_no_val(Ext,Rest);
+gen_dec_extaddGroup_no_val(_, []) ->
+ ok.
+
+gen_dec_component_no_val(_,{'DEFAULT',DefVal}) ->
+ emit([{asis,DefVal}]);
+gen_dec_component_no_val(_,'OPTIONAL') ->
+ emit({"asn1_NOVALUE"});
+gen_dec_component_no_val({ext,_,_},mandatory) ->
+ emit({"asn1_NOVALUE"}).
gen_dec_line(Erule,TopType,Cname,Type,Pos,DecInfObj,Ext,Prop) ->
@@ -1192,6 +1297,14 @@ gen_enc_choice_tag({C1,C2},_,_) ->
N2 = get_name_list(C2),
emit(["?RT_PER:set_choice(element(1,Val),",
{asis,{N1,N2}},", ",{asis,{length(N1),length(N2)}},")"]);
+
+gen_enc_choice_tag({C1,C2,C3},_,_) ->
+ N1 = get_name_list(C1),
+ N2 = get_name_list(C2),
+ N3 = get_name_list(C3),
+ Root = N1 ++ N3,
+ emit(["?RT_PER:set_choice(element(1,Val),",
+ {asis,{Root,N2}},", ",{asis,{length(Root),length(N2)}},")"]);
gen_enc_choice_tag(C,_,_) ->
N = get_name_list(C),
emit(["?RT_PER:set_choice(element(1,Val),",
@@ -1208,6 +1321,8 @@ get_name_list([], Acc) ->
gen_enc_choice2(Erule,TopType, {L1,L2}, Ext) ->
gen_enc_choice2(Erule,TopType, L1 ++ L2, 0, Ext);
+gen_enc_choice2(Erule,TopType, {L1,L2,L3}, Ext) ->
+ gen_enc_choice2(Erule,TopType, L1 ++ L3 ++ L2, 0, Ext);
gen_enc_choice2(Erule,TopType, L, Ext) ->
gen_enc_choice2(Erule,TopType, L, 0, Ext).
@@ -1279,6 +1394,9 @@ gen_dec_choice1(Erule,TopType,CompList,noext) ->
gen_dec_choice1(Erule,TopType,{RootList,ExtList},Ext) ->
NewList = RootList ++ ExtList,
gen_dec_choice1(Erule,TopType, NewList, Ext);
+gen_dec_choice1(Erule,TopType,{RootList,ExtList,RootList2},Ext) ->
+ NewList = RootList ++ RootList2 ++ ExtList,
+ gen_dec_choice1(Erule,TopType, NewList, Ext);
gen_dec_choice1(Erule,TopType,CompList,{ext,ExtPos,ExtNum}) ->
emit({"{Choice,",{curr,bytes},
"} = ?RT_PER:getchoice(",{prev,bytes},",",
@@ -1347,6 +1465,18 @@ gen_encode_prim_wrapper(CtgenMod,Erule,Cont,DoTag,Value) ->
CtgenMod:gen_encode_prim(Erule,Cont,DoTag,Value).
% erase(component_type).
+make_elements(I,Val,ExtCnames) ->
+ make_elements(I,Val,ExtCnames,[]).
+
+make_elements(I,Val,[ExtCname],Acc)-> % the last one, no comma needed
+ Element = make_element(I,Val,ExtCname),
+ make_elements(I+1,Val,[],[Element|Acc]);
+make_elements(I,Val,[ExtCname|Rest],Acc)->
+ Element = make_element(I,Val,ExtCname),
+ make_elements(I+1,Val,Rest,[", ",Element|Acc]);
+make_elements(_I,_,[],Acc) ->
+ lists:reverse(Acc).
+
make_element(I,Val,Cname) ->
case tuple_notation_allowed() of
true ->
@@ -1355,6 +1485,55 @@ make_element(I,Val,Cname) ->
io_lib:format("element(~w,~s)",[I,Val])
end.
+emit_extaddgroupTerms(VarSeries,[_]) ->
+ asn1ct_name:new(VarSeries),
+ emit({curr,VarSeries}),
+ ok;
+emit_extaddgroupTerms(VarSeries,[_|Rest]) ->
+ asn1ct_name:new(VarSeries),
+ emit({{curr,VarSeries},","}),
+ emit_extaddgroupTerms(VarSeries,Rest);
+emit_extaddgroupTerms(_,[]) ->
+ ok.
+wrap_compList({Root1,Ext,Root2}) ->
+ {Root1,wrap_extensionAdditionGroups(Ext),Root2};
+wrap_compList({Root1,Ext}) ->
+ {Root1,wrap_extensionAdditionGroups(Ext)};
+wrap_compList(CompList) ->
+ CompList.
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%% Will convert all componentTypes following 'ExtensionAdditionGroup'
+%% up to the matching 'ExtensionAdditionGroupEnd' into one componentType
+%% of type SEQUENCE with the componentTypes as components
+%%
+wrap_extensionAdditionGroups(ExtCompList) ->
+ wrap_extensionAdditionGroups(ExtCompList,[],0).
+
+wrap_extensionAdditionGroups([{'ExtensionAdditionGroup',_Number}|Rest],Acc,0) ->
+ {ExtGroupCompList=
+ [#'ComponentType'{textual_order=TextPos}|_],
+ ['ExtensionAdditionGroupEnd'|Rest2]} =
+ lists:splitwith(fun(#'ComponentType'{}) -> true;
+ (_) -> false
+ end,
+ Rest),
+ wrap_extensionAdditionGroups(Rest2,
+ [#'ComponentType'{
+ name='ExtAddGroup', % FIXME: handles ony one ExtAddGroup
+ typespec=#type{def=#'SEQUENCE'{
+ extaddgroup=1,% FIXME: handles only one
+ components=ExtGroupCompList}},
+ textual_order = TextPos,
+ prop='OPTIONAL'}|Acc],length(ExtGroupCompList)-1);
+wrap_extensionAdditionGroups([H=#'ComponentType'{textual_order=Tord}|T],Acc,ExtAddGroupDiff) when is_integer(Tord) ->
+ wrap_extensionAdditionGroups(T,[H#'ComponentType'{
+ textual_order=Tord - ExtAddGroupDiff}|Acc],ExtAddGroupDiff);
+wrap_extensionAdditionGroups([H|T],Acc,ExtAddGroupDiff) ->
+ wrap_extensionAdditionGroups(T,[H|Acc],ExtAddGroupDiff);
+wrap_extensionAdditionGroups([],Acc,_) ->
+ lists:reverse(Acc).
+
+
tuple_notation_allowed() ->
Options = get(encoding_options),
not (lists:member(optimize,Options) orelse lists:member(uper_bin,Options)).
diff --git a/lib/asn1/src/asn1ct_gen.erl b/lib/asn1/src/asn1ct_gen.erl
index fefb92bb34..7a28a16877 100644
--- a/lib/asn1/src/asn1ct_gen.erl
+++ b/lib/asn1/src/asn1ct_gen.erl
@@ -1,26 +1,26 @@
%%
%% %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(asn1ct_gen).
-include("asn1_records.hrl").
-%%-compile(export_all).
+
-export([pgen_exports/3,
pgen_hrl/4,
gen_head/3,
@@ -535,14 +535,19 @@ gen_part_decode_funcs({primitive,bif},_TypeName,
gen_part_decode_funcs(WhatKind,_TypeName,{_,Directive,_,_}) ->
throw({error,{asn1,{"Not implemented yet",WhatKind," partial incomplete directive:",Directive}}}).
+
gen_types(Erules,Tname,{RootL1,ExtList,RootL2})
when is_list(RootL1), is_list(RootL2) ->
gen_types(Erules,Tname,RootL1),
- gen_types(Erules,Tname,ExtList),
+ Rtmod = list_to_atom(lists:concat(["asn1ct_gen_",erule(Erules),
+ rt2ct_suffix(Erules)])),
+ gen_types(Erules,Tname,Rtmod:extaddgroup2sequence(ExtList)),
gen_types(Erules,Tname,RootL2);
gen_types(Erules,Tname,{RootList,ExtList}) when is_list(RootList) ->
gen_types(Erules,Tname,RootList),
- gen_types(Erules,Tname,ExtList);
+ Rtmod = list_to_atom(lists:concat(["asn1ct_gen_",erule(Erules),
+ rt2ct_suffix(Erules)])),
+ gen_types(Erules,Tname,Rtmod:extaddgroup2sequence(ExtList));
gen_types(Erules,Tname,[{'EXTENSIONMARK',_,_}|Rest]) ->
gen_types(Erules,Tname,Rest);
gen_types(Erules,Tname,[ComponentType|Rest]) ->
@@ -1301,8 +1306,8 @@ put_chars(undefined,X) ->
put_chars(Y,X) ->
io:put_chars(Y,X).
-fopen(F, Mode) ->
- case file:open(F, Mode) of
+fopen(F, ModeList) ->
+ case file:open(F, ModeList) of
{ok, Fd} ->
Fd;
{error, Reason} ->
@@ -1357,7 +1362,8 @@ pgen_hrltypes(Erules,Module,[H|T],NumRecords) ->
%% Generates a macro for value Value defined in the ASN.1 module
gen_macro(Value) when is_record(Value,valuedef) ->
- emit({"-define('",Value#valuedef.name,"', ",
+ Prefix = get_macro_name_prefix(),
+ emit({"-define('",Prefix,Value#valuedef.name,"', ",
{asis,Value#valuedef.value},").",nl}).
%% Generate record functions **************
@@ -1540,19 +1546,18 @@ gen_record2(Name,SeqOrSet,Comps) ->
gen_record2(_Name,_SeqOrSet,[],_Com,_Extension) ->
true;
-gen_record2(Name,SeqOrSet,[{'EXTENSIONMARK',_,_}|T],Com,Extension) ->
- gen_record2(Name,SeqOrSet,T,Com,Extension);
-gen_record2(_Name,_SeqOrSet,[H],Com,Extension) ->
- #'ComponentType'{name=Cname} = H,
+gen_record2(_Name,_SeqOrSet,[H = #'ComponentType'{name=Cname}],Com,Extension) ->
emit(Com),
emit({asis,Cname}),
gen_record_default(H, Extension);
-gen_record2(Name,SeqOrSet,[H|T],Com, Extension) ->
- #'ComponentType'{name=Cname} = H,
+gen_record2(Name,SeqOrSet,[H = #'ComponentType'{name=Cname}|T],Com, Extension) ->
emit(Com),
emit({asis,Cname}),
gen_record_default(H, Extension),
- gen_record2(Name,SeqOrSet,T,", ", Extension).
+ gen_record2(Name,SeqOrSet,T,", ", Extension);
+gen_record2(Name,SeqOrSet,[_|T],Com,Extension) ->
+ %% skip EXTENSIONMARK, ExtensionAdditionGroup and other markers
+ gen_record2(Name,SeqOrSet,T,Com,Extension).
gen_record_default(#'ComponentType'{prop='OPTIONAL'}, _)->
emit(" = asn1_NOVALUE");
@@ -2064,3 +2069,11 @@ get_record_name_prefix() ->
{value,{_,Prefix}} ->
Prefix
end.
+
+get_macro_name_prefix() ->
+ case lists:keysearch(macro_name_prefix,1,get(encoding_options)) of
+ false ->
+ "";
+ {value,{_,Prefix}} ->
+ Prefix
+ end.
diff --git a/lib/asn1/src/asn1ct_gen_ber.erl b/lib/asn1/src/asn1ct_gen_ber.erl
index 7c432f29c3..8943541303 100644
--- a/lib/asn1/src/asn1ct_gen_ber.erl
+++ b/lib/asn1/src/asn1ct_gen_ber.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%
%%
%%
@@ -33,6 +33,7 @@
-export([gen_objectset_code/2, gen_obj_code/3]).
-export([re_wrap_erule/1]).
-export([unused_var/2]).
+-export([extaddgroup2sequence/1]).
-import(asn1ct_gen, [emit/1,demit/1]).
@@ -1734,3 +1735,15 @@ get_object_field(Name,ObjectFields) ->
{value,Field} -> Field;
false -> false
end.
+
+%% For BER the ExtensionAdditionGroup notation has no impact on the encoding/decoding
+%% and therefore we only filter away the ExtensionAdditionGroup start and end markers
+%%
+extaddgroup2sequence(ExtList) when is_list(ExtList) ->
+ lists:filter(fun(#'ExtensionAdditionGroup'{}) ->
+ false;
+ ('ExtensionAdditionGroupEnd') ->
+ false;
+ (_) ->
+ true
+ end, ExtList).
diff --git a/lib/asn1/src/asn1ct_gen_ber_bin_v2.erl b/lib/asn1/src/asn1ct_gen_ber_bin_v2.erl
index b7ac0f407c..ac232ea710 100644
--- a/lib/asn1/src/asn1ct_gen_ber_bin_v2.erl
+++ b/lib/asn1/src/asn1ct_gen_ber_bin_v2.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2002-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 2002-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%
%%
%%
@@ -33,6 +33,7 @@
-export([gen_objectset_code/2, gen_obj_code/3]).
-export([encode_tag_val/3]).
-export([gen_inc_decode/2,gen_decode_selected/3]).
+-export([extaddgroup2sequence/1]).
-import(asn1ct_gen, [emit/1,demit/1]).
@@ -1826,8 +1827,15 @@ mk_object_val(Val, Ack, Len) ->
add_func(F={_Func,_Arity}) ->
ets:insert(asn1_functab,{F}).
-
-
-
+%% For BER the ExtensionAdditionGroup notation has no impact on the encoding/decoding
+%% and therefore we only filter away the ExtensionAdditionGroup start and end markers
+extaddgroup2sequence(ExtList) when is_list(ExtList) ->
+ lists:filter(fun(#'ExtensionAdditionGroup'{}) ->
+ false;
+ ('ExtensionAdditionGroupEnd') ->
+ false;
+ (_) ->
+ true
+ end, ExtList).
diff --git a/lib/asn1/src/asn1ct_gen_per.erl b/lib/asn1/src/asn1ct_gen_per.erl
index 06d2489748..a8908db7e4 100644
--- a/lib/asn1/src/asn1ct_gen_per.erl
+++ b/lib/asn1/src/asn1ct_gen_per.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%
%%
%%
@@ -31,6 +31,7 @@
-export([gen_encode/2, gen_encode/3]).
-export([is_already_generated/2,more_genfields/1,get_class_fields/1,
get_object_field/2]).
+-export([extaddgroup2sequence/1]).
-import(asn1ct_gen, [emit/1,demit/1]).
@@ -1393,3 +1394,25 @@ get_object_field(Name,ObjectFields) ->
false -> false
end.
+
+%% For PER the ExtensionAdditionGroup notation has significance for the encoding and decoding
+%% the components within the ExtensionAdditionGroup is treated in a similar way as if they
+%% have been specified within a SEQUENCE, therefore we construct a fake sequence type here
+%% so that we can generate code for it
+extaddgroup2sequence(ExtList) ->
+ extaddgroup2sequence(ExtList,[]).
+
+extaddgroup2sequence([{'ExtensionAdditionGroup',Number0}|T],Acc) ->
+ Number = case Number0 of undefined -> 1; _ -> Number0 end,
+ {ExtGroupComps,['ExtensionAdditionGroupEnd'|T2]} =
+ lists:splitwith(fun(Elem) -> is_record(Elem,'ComponentType') end,T),
+ extaddgroup2sequence(T2,[#'ComponentType'{
+ name='ExtAddGroup',
+ typespec=#type{def=#'SEQUENCE'{
+ extaddgroup=Number,
+ components=ExtGroupComps}},
+ prop='OPTIONAL'}|Acc]);
+extaddgroup2sequence([C|T],Acc) ->
+ extaddgroup2sequence(T,[C|Acc]);
+extaddgroup2sequence([],Acc) ->
+ lists:reverse(Acc).
diff --git a/lib/asn1/src/asn1ct_gen_per_rt2ct.erl b/lib/asn1/src/asn1ct_gen_per_rt2ct.erl
index 56f895828a..cd05701965 100644
--- a/lib/asn1/src/asn1ct_gen_per_rt2ct.erl
+++ b/lib/asn1/src/asn1ct_gen_per_rt2ct.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2002-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 2002-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%
%%
%%
@@ -29,6 +29,7 @@
-export([gen_obj_code/3,gen_objectset_code/2]).
-export([gen_decode/2, gen_decode/3]).
-export([gen_encode/2, gen_encode/3]).
+-export([extaddgroup2sequence/1]).
-import(asn1ct_gen, [emit/1,demit/1]).
-import(asn1ct_gen_per, [is_already_generated/2,more_genfields/1,
@@ -1796,3 +1797,25 @@ dec_enumerated_cases([Name|Rest],Tmpremain,No) ->
dec_enumerated_cases(Rest,Tmpremain,No+1);
dec_enumerated_cases([],_,_) ->
"".
+
+%% For PER the ExtensionAdditionGroup notation has significance for the encoding and decoding
+%% the components within the ExtensionAdditionGroup is treated in a similar way as if they
+%% have been specified within a SEQUENCE, therefore we construct a fake sequence type here
+%% so that we can generate code for it
+extaddgroup2sequence(ExtList) ->
+ extaddgroup2sequence(ExtList,[]).
+
+extaddgroup2sequence([{'ExtensionAdditionGroup',Number0}|T],Acc) ->
+ Number = case Number0 of undefined -> 1; _ -> Number0 end,
+ {ExtGroupComps,['ExtensionAdditionGroupEnd'|T2]} =
+ lists:splitwith(fun(Elem) -> is_record(Elem,'ComponentType') end,T),
+ extaddgroup2sequence(T2,[#'ComponentType'{
+ name='ExtAddGroup',
+ typespec=#type{def=#'SEQUENCE'{
+ extaddgroup=Number,
+ components=ExtGroupComps}},
+ prop='OPTIONAL'}|Acc]);
+extaddgroup2sequence([C|T],Acc) ->
+ extaddgroup2sequence(T,[C|Acc]);
+extaddgroup2sequence([],Acc) ->
+ lists:reverse(Acc).
diff --git a/lib/asn1/src/asn1ct_parser2.erl b/lib/asn1/src/asn1ct_parser2.erl
index 9d2df72f5b..224a535e87 100644
--- a/lib/asn1/src/asn1ct_parser2.erl
+++ b/lib/asn1/src/asn1ct_parser2.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2000-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 2000-2010. All Rights Reserved.
+%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
-%%
+%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
-%%
+%%
%% %CopyrightEnd%
%%
%%
@@ -74,8 +74,9 @@ parse_ModuleDefinition([{typereference,L1,ModuleIdentifier}|Rest0]) ->
{ExtensionDefault,Rest3} =
case Rest2 of
[{'EXTENSIBILITY',_L5}, {'IMPLIED',_L6}|Rest21] ->
- {'IMPLIED',Rest21};
- _ -> {false,Rest2}
+ put(extensiondefault,'IMPLIED'),{'IMPLIED',Rest21};
+ _ ->
+ put(extensiondefault,undefined),{undefined,Rest2}
end,
case Rest3 of
[{'::=',_L7}, {'BEGIN',_L8}|Rest4] ->
@@ -417,9 +418,21 @@ parse_BuiltinType([{'CHARACTER',_},{'STRING',_}|Rest]) ->
parse_BuiltinType([{'CHOICE',_},{'{',_}|Rest]) ->
{AlternativeTypeLists,Rest2} = parse_AlternativeTypeLists(Rest),
+ AlternativeTypeLists1 =
+ lists:filter(fun(#'ExtensionAdditionGroup'{}) -> false;
+ ('ExtensionAdditionGroupEnd') -> false;
+ (_) -> true
+ end,AlternativeTypeLists),
case Rest2 of
[{'}',_}|Rest3] ->
- {#type{def={'CHOICE',AlternativeTypeLists}},Rest3};
+ AlternativeTypeLists2 =
+ case {[Ext||Ext = #'EXTENSIONMARK'{} <- AlternativeTypeLists1],
+ get(extensiondefault)} of
+ {[],'IMPLIED'} -> AlternativeTypeLists1 ++ [#'EXTENSIONMARK'{}];
+ _ -> AlternativeTypeLists1
+ end,
+
+ {#type{def={'CHOICE',AlternativeTypeLists2}},Rest3};
_ ->
throw({asn1_error,{get_line(hd(Rest2)),get(asn1_module),
[got,get_token(hd(Rest2)),expected,'}']}})
@@ -427,7 +440,7 @@ parse_BuiltinType([{'CHOICE',_},{'{',_}|Rest]) ->
parse_BuiltinType([{'EMBEDDED',_},{'PDV',_}|Rest]) ->
{#type{def='EMBEDDED PDV'},Rest};
parse_BuiltinType([{'ENUMERATED',_},{'{',_}|Rest]) ->
- {Enumerations,Rest2} = parse_Enumerations(Rest),
+ {Enumerations,Rest2} = parse_Enumerations(Rest,get(extensiondefault)),
case Rest2 of
[{'}',_}|Rest3] ->
{#type{def={'ENUMERATED',Enumerations}},Rest3};
@@ -478,19 +491,23 @@ parse_BuiltinType([{'REAL',_}|Rest]) ->
{#type{def='REAL'},Rest};
parse_BuiltinType([{'RELATIVE-OID',_}|Rest]) ->
{#type{def='RELATIVE-OID'},Rest};
-parse_BuiltinType([{'SEQUENCE',_},{'{',_},{'...',Line},{'}',_}|Rest]) ->
- {#type{def=#'SEQUENCE'{components=[{'EXTENSIONMARK',Line,undefined}]}},
+parse_BuiltinType([{'SEQUENCE',_},{'{',_},{'}',_}|Rest]) ->
+ {#type{def=#'SEQUENCE'{components=[]}},
Rest};
+parse_BuiltinType([{'SEQUENCE',_},{'{',_},{'...',Line},{'}',_}|Rest]) ->
+ {#type{def=#'SEQUENCE'{components=[#'EXTENSIONMARK'{pos = Line}]}},Rest};
parse_BuiltinType([{'SEQUENCE',_},{'{',_},{'...',Line},{'!',_}|Rest]) ->
{ExceptionIdentification,Rest2} = parse_ExceptionIdentification(Rest),
case Rest2 of
[{'}',_}|Rest3] ->
- {#type{def=#'SEQUENCE'{components=[{'EXTENSIONMARK',
- Line,
- ExceptionIdentification}]}},
+ {#type{def=#'SEQUENCE'{
+ components=[#'EXTENSIONMARK'{
+ pos = Line,
+ val = ExceptionIdentification}]}},
Rest3};
_ ->
- {ComponentTypeLists,Rest3}=parse_ComponentTypeLists2(Rest2,[#'EXTENSIONMARK'{pos=Line}]),
+ {ComponentTypeLists,Rest3}=
+ parse_ComponentTypeLists2(Rest2,[#'EXTENSIONMARK'{pos=Line}]),
case Rest3 of
[{'}',_}|Rest4] ->
{#type{def=#'SEQUENCE'{components=ComponentTypeLists}},Rest4};
@@ -506,24 +523,43 @@ parse_BuiltinType([{'SEQUENCE',_},{'{',_}|Rest]) ->
{ComponentTypeLists,Rest2} = parse_ComponentTypeLists(Rest),
case Rest2 of
[{'}',_}|Rest3] ->
- {#type{def=#'SEQUENCE'{components=ComponentTypeLists}},Rest3};
+ ComponentTypeLists2 =
+ case {[Ext||Ext = #'EXTENSIONMARK'{} <- ComponentTypeLists],
+ get(extensiondefault)} of
+ {[],'IMPLIED'} -> ComponentTypeLists ++ [#'EXTENSIONMARK'{}];
+ _ -> ComponentTypeLists
+ end,
+ {#type{def=#'SEQUENCE'{components = ComponentTypeLists2}},
+ Rest3};
_ ->
throw({asn1_error,{get_line(hd(Rest2)),get(asn1_module),
[got,get_token(hd(Rest2)),expected,'}']}})
end;
+
+parse_BuiltinType([{'SEQUENCE',_},{'OF',_},Id={identifier,_,_},Lt={'<',_}|Rest]) ->
+%% TODO: take care of the identifier for something useful
+ {Type,Rest2} = parse_SelectionType([Id,Lt|Rest]),
+ {#type{def={'SEQUENCE OF',#type{def=Type,tag=[]}}},Rest2};
+
+parse_BuiltinType([{'SEQUENCE',_},{'OF',_},{identifier,_,_} |Rest]) ->
+%% TODO: take care of the identifier for something useful
+ {Type,Rest2} = parse_Type(Rest),
+ {#type{def={'SEQUENCE OF',Type}},Rest2};
+
parse_BuiltinType([{'SEQUENCE',_},{'OF',_}|Rest]) ->
{Type,Rest2} = parse_Type(Rest),
{#type{def={'SEQUENCE OF',Type}},Rest2};
parse_BuiltinType([{'SET',_},{'{',_},{'...',Line},{'}',_}|Rest]) ->
- {#type{def=#'SET'{components=[{'EXTENSIONMARK',Line,undefined}]}},Rest};
+ {#type{def=#'SET'{components=[#'EXTENSIONMARK'{pos = Line}]}},Rest};
parse_BuiltinType([{'SET',_},{'{',_},{'...',Line},{'!',_}|Rest]) ->
{ExceptionIdentification,Rest2} = parse_ExceptionIdentification(Rest),
case Rest2 of
[{'}',_}|Rest3] ->
{#type{def=#'SET'{components=
- [{'EXTENSIONMARK',Line,ExceptionIdentification}]}},
+ [#'EXTENSIONMARK'{pos = Line,
+ val = ExceptionIdentification}]}},
Rest3};
_ ->
throw({asn1_error,{get_line(hd(Rest2)),get(asn1_module),
@@ -533,11 +569,30 @@ parse_BuiltinType([{'SET',_},{'{',_}|Rest]) ->
{ComponentTypeLists,Rest2} = parse_ComponentTypeLists(Rest),
case Rest2 of
[{'}',_}|Rest3] ->
- {#type{def=#'SET'{components=ComponentTypeLists}},Rest3};
+ ComponentTypeLists2 =
+ case {[Ext||Ext = #'EXTENSIONMARK'{} <- ComponentTypeLists],
+ get(extensiondefault)} of
+ {[],'IMPLIED'} -> ComponentTypeLists ++ [#'EXTENSIONMARK'{}];
+ _ -> ComponentTypeLists
+ end,
+ {#type{def=#'SET'{components = ComponentTypeLists2}},
+ Rest3};
_ ->
throw({asn1_error,{get_line(hd(Rest2)),get(asn1_module),
[got,get_token(hd(Rest2)),expected,'}']}})
end;
+
+parse_BuiltinType([{'SET',_},{'OF',_},Id={identifier,_,_},Lt={'<',_}|Rest]) ->
+%% TODO: take care of the identifier for something useful
+ {Type,Rest2} = parse_SelectionType([Id,Lt|Rest]),
+ {#type{def={'SET OF',#type{def=Type,tag=[]}}},Rest2};
+
+
+parse_BuiltinType([{'SET',_},{'OF',_},{identifier,_,_}|Rest]) ->
+%%TODO: take care of the identifier for something useful
+ {Type,Rest2} = parse_Type(Rest),
+ {#type{def={'SET OF',Type}},Rest2};
+
parse_BuiltinType([{'SET',_},{'OF',_}|Rest]) ->
{Type,Rest2} = parse_Type(Rest),
{#type{def={'SET OF',Type}},Rest2};
@@ -563,48 +618,74 @@ parse_BuiltinType(Tokens) ->
parse_TypeWithConstraint([{'SEQUENCE',_},Lpar = {'(',_}|Rest]) ->
{Constraint,Rest2} = parse_Constraint([Lpar|Rest]),
- case Rest2 of
- [{'OF',_}|Rest3] ->
- {Type,Rest4} = parse_Type(Rest3),
- {#type{def = {'SEQUENCE OF',Type}, constraint = merge_constraints([Constraint])},Rest4};
- _ ->
- throw({asn1_error,{get_line(hd(Rest2)),get(asn1_module),
- [got,get_token(hd(Rest2)),expected,'OF']}})
- end;
+ Rest4 = case Rest2 of
+ [{'OF',_}, {identifier,_,_Id}|Rest3] ->
+%%% TODO: make some use of the identifier, maybe useful in the XML mapping
+ Rest3;
+ [{'OF',_}|Rest3] ->
+ Rest3;
+ _ ->
+ throw({asn1_error,
+ {get_line(hd(Rest2)),get(asn1_module),
+ [got,get_token(hd(Rest2)),expected,'OF']}})
+ end,
+ {Type,Rest5} = parse_Type(Rest4),
+ {#type{def = {'SEQUENCE OF',Type},
+ constraint = merge_constraints([Constraint])},Rest5};
+
parse_TypeWithConstraint([{'SEQUENCE',_},{'SIZE',_},Lpar = {'(',_}|Rest]) ->
{Constraint,Rest2} = parse_Constraint([Lpar|Rest]),
#constraint{c=C} = Constraint,
Constraint2 = Constraint#constraint{c={'SizeConstraint',C}},
- case Rest2 of
- [{'OF',_}|Rest3] ->
- {Type,Rest4} = parse_Type(Rest3),
- {#type{def = {'SEQUENCE OF',Type}, constraint = merge_constraints([Constraint2])},Rest4};
- _ ->
- throw({asn1_error,{get_line(hd(Rest2)),get(asn1_module),
- [got,get_token(hd(Rest2)),expected,'OF']}})
- end;
+ Rest4 = case Rest2 of
+ [{'OF',_}, {identifier,_,_Id}|Rest3] ->
+%%% TODO: make some use of the identifier, maybe useful in the XML mapping
+ Rest3;
+ [{'OF',_}|Rest3] ->
+ Rest3;
+ _ ->
+ throw({asn1_error,{get_line(hd(Rest2)),get(asn1_module),
+ [got,get_token(hd(Rest2)),expected,'OF']}})
+ end,
+ {Type,Rest5} = parse_Type(Rest4),
+ {#type{def = {'SEQUENCE OF',Type}, constraint = merge_constraints([Constraint2])},Rest5};
+
parse_TypeWithConstraint([{'SET',_},Lpar = {'(',_}|Rest]) ->
{Constraint,Rest2} = parse_Constraint([Lpar|Rest]),
- case Rest2 of
- [{'OF',_}|Rest3] ->
- {Type,Rest4} = parse_Type(Rest3),
- {#type{def = {'SET OF',Type}, constraint = merge_constraints([Constraint])},Rest4};
- _ ->
- throw({asn1_error,{get_line(hd(Rest2)),get(asn1_module),
- [got,get_token(hd(Rest2)),expected,'OF']}})
- end;
+ Rest4 = case Rest2 of
+ [{'OF',_}, {identifier,_,_Id}|Rest3] ->
+%%% TODO: make some use of the identifier, maybe useful in the XML mapping
+ Rest3;
+ [{'OF',_}|Rest3] ->
+ Rest3;
+ _ ->
+ throw({asn1_error,
+ {get_line(hd(Rest2)),get(asn1_module),
+ [got,get_token(hd(Rest2)),expected,'OF']}})
+ end,
+ {Type,Rest5} = parse_Type(Rest4),
+ {#type{def = {'SET OF',Type},
+ constraint = merge_constraints([Constraint])},Rest5};
+
parse_TypeWithConstraint([{'SET',_},{'SIZE',_},Lpar = {'(',_}|Rest]) ->
{Constraint,Rest2} = parse_Constraint([Lpar|Rest]),
#constraint{c=C} = Constraint,
Constraint2 = Constraint#constraint{c={'SizeConstraint',C}},
- case Rest2 of
- [{'OF',_}|Rest3] ->
- {Type,Rest4} = parse_Type(Rest3),
- {#type{def = {'SET OF',Type}, constraint = merge_constraints([Constraint2])},Rest4};
- _ ->
- throw({asn1_error,{get_line(hd(Rest2)),get(asn1_module),
- [got,get_token(hd(Rest2)),expected,'OF']}})
- end;
+ Rest4 = case Rest2 of
+ [{'OF',_}, {identifier,_,_Id}|Rest3] ->
+%%% TODO: make some use of the identifier, maybe useful in the XML mapping
+ Rest3;
+ [{'OF',_}|Rest3] ->
+ Rest3;
+ _ ->
+ throw({asn1_error,
+ {get_line(hd(Rest2)),get(asn1_module),
+ [got,get_token(hd(Rest2)),expected,'OF']}})
+ end,
+ {Type,Rest5} = parse_Type(Rest4),
+ {#type{def = {'SET OF',Type},
+ constraint = merge_constraints([Constraint2])},Rest5};
+
parse_TypeWithConstraint(Tokens) ->
throw({asn1_error,{get_line(hd(Tokens)),get(asn1_module),
[got,get_token(hd(Tokens)),expected,
@@ -2258,91 +2339,197 @@ to_set(V) when is_list(V) ->
to_set(V) ->
ordsets:from_list([V]).
-
parse_AlternativeTypeLists(Tokens) ->
- {AlternativeTypeList,Rest1} = parse_AlternativeTypeList(Tokens),
- {ExtensionAndException,Rest2} =
- case Rest1 of
- [{',',_},{'...',L1},{'!',_}|Rest12] ->
- {_,Rest13} = parse_ExceptionIdentification(Rest12),
- %% Exception info is currently thrown away
- {[#'EXTENSIONMARK'{pos=L1}],Rest13};
- [{',',_},{'...',L1}|Rest12] ->
- {[#'EXTENSIONMARK'{pos=L1}],Rest12};
- _ ->
- {[],Rest1}
- end,
- case ExtensionAndException of
- [] ->
- {AlternativeTypeList,Rest2};
+ parse_AlternativeTypeLists(Tokens,[]).
+
+parse_AlternativeTypeLists(Tokens = [{identifier,_,_}|_Rest0],Clist) ->
+ {CompList,Rest1} = parse_AlternativeTypeList(Tokens,[]),
+ parse_AlternativeTypeLists(Rest1,Clist++CompList);
+parse_AlternativeTypeLists([{'...',L1},{'!',_}|Rest02],Clist0) ->
+ {_,Rest03} = parse_ExceptionIdentification(Rest02),
+ %% Exception info is currently thrown away
+ parse_AlternativeTypeLists2(Rest03,Clist0++[#'EXTENSIONMARK'{pos=L1}]);
+parse_AlternativeTypeLists([{',',L1},{'...',_},{'!',_}|Rest02],Clist0) when Clist0 =/= []->
+ {_,Rest03} = parse_ExceptionIdentification(Rest02),
+ %% Exception info is currently thrown away
+ parse_AlternativeTypeLists2(Rest03,Clist0++[#'EXTENSIONMARK'{pos=L1}]);
+
+parse_AlternativeTypeLists([{',',_},{'...',L1}|Rest02],Clist0) when Clist0 =/= []->
+ parse_AlternativeTypeLists2(Rest02,Clist0++[#'EXTENSIONMARK'{pos=L1}]);
+parse_AlternativeTypeLists([{'...',L1}|Rest02],Clist0) ->
+ parse_AlternativeTypeLists2(Rest02,Clist0++[#'EXTENSIONMARK'{pos=L1}]);
+parse_AlternativeTypeLists(Tokens = [{'}',_L1}|_Rest02],Clist0) ->
+ {Clist0,Tokens}.
+
+parse_AlternativeTypeLists2(Tokens,Clist) ->
+ {ExtAdd,Rest} = parse_ExtensionAdditionAlternatives(Tokens,Clist),
+ {Clist2,Rest2} = parse_OptionalExtensionMarker(Rest,lists:flatten(ExtAdd)),
+ case Rest2 of
+ [{',',_}|Rest3] ->
+ {CompList,Rest4} = parse_AlternativeTypeList(Rest3,[]),
+ {Clist2 ++ CompList,Rest4};
_ ->
- {ExtensionAddition,Rest3} =
- case Rest2 of
- [{',',_}|Rest23] ->
- parse_ExtensionAdditionAlternativeList(Rest23);
- _ ->
- {[],Rest2}
- end,
- {OptionalExtensionMarker,Rest4} =
- case Rest3 of
- [{',',_},{'...',L3}|Rest31] ->
- {[#'EXTENSIONMARK'{pos=L3}],Rest31};
- _ ->
- {[],Rest3}
- end,
- {AlternativeTypeList ++ ExtensionAndException ++ ExtensionAddition ++ OptionalExtensionMarker, Rest4}
+ {Clist2,Rest2}
end.
-
-parse_AlternativeTypeList(Tokens) ->
- parse_AlternativeTypeList(Tokens,[]).
-parse_AlternativeTypeList(Tokens,Acc) ->
- {NamedType,Rest} = parse_NamedType(Tokens),
+
+parse_AlternativeTypeList([{',',_},Id = {identifier,_,_}|Rest],Acc) when Acc =/= [] ->
+ {AlternativeType,Rest2} = parse_NamedType([Id|Rest]),
+ parse_AlternativeTypeList(Rest2,[AlternativeType|Acc]);
+parse_AlternativeTypeList(Tokens = [{'}',_}|_],Acc) ->
+ {lists:reverse(Acc),Tokens};
+parse_AlternativeTypeList(Tokens = [{']',_},{']',_}|_],Acc) ->
+ {lists:reverse(Acc),Tokens};
+parse_AlternativeTypeList(Tokens = [{',',_},{'...',_}|_],Acc) ->
+ {lists:reverse(Acc),Tokens};
+parse_AlternativeTypeList(Tokens,[]) ->
+ {AlternativeType,Rest} = parse_NamedType(Tokens),
+ parse_AlternativeTypeList(Rest,[AlternativeType]);
+parse_AlternativeTypeList(Tokens,_) ->
+ throw({asn1_error,
+ {get_line(hd(Tokens)),get(asn1_module),
+ [got,[get_token(hd(Tokens)),get_token(hd(tl(Tokens)))],
+ expected,['}',', identifier']]}}).
+
+parse_ExtensionAdditionAlternatives(Tokens =[{',',_}|_],Clist) ->
+ {ExtAddList,Rest2} = parse_ExtensionAdditionAlternativesList(Tokens,[]),
+ {Clist++lists:flatten(ExtAddList),Rest2};
+parse_ExtensionAdditionAlternatives(Tokens,Clist) ->
+ %% Empty
+ {Clist,Tokens}.
+
+parse_ExtensionAdditionAlternativesList([{',',_},Id = {identifier,_,_}|Rest],Acc) ->
+ {AlternativeType,Rest2} = parse_NamedType([Id|Rest]),
+ parse_ExtensionAdditionAlternativesList(Rest2,[AlternativeType|Acc]);
+parse_ExtensionAdditionAlternativesList([{',',_},C1 = {'[',_},C2 = {'[',_}|Rest],Acc) ->
+ {ExtAddGroup,Rest2} = parse_ExtensionAdditionAlternativesGroup([C1,C2|Rest],[]),
+ parse_ExtensionAdditionAlternativesList(Rest2,[ExtAddGroup|Acc]);
+parse_ExtensionAdditionAlternativesList(Tokens = [{'}',_}|_],Acc) ->
+ {lists:reverse(Acc),Tokens};
+parse_ExtensionAdditionAlternativesList(Tokens = [{',',_},{'...',_}|_],Acc) ->
+ {lists:reverse(Acc),Tokens};
+parse_ExtensionAdditionAlternativesList(Tokens,_) ->
+ throw({asn1_error,
+ {get_line(hd(Tokens)),get(asn1_module),
+ [got,[get_token(hd(Tokens)),get_token(hd(tl(Tokens)))],
+ expected,['}',', identifier']]}}).
+
+
+parse_ExtensionAdditionAlternativesGroup([ {'[',_},{'[',_},_VsnNr = {number,_,Num},{':',_}|Rest],[]) ->
+ parse_ExtensionAdditionAlternativesGroup2(Rest,Num);
+parse_ExtensionAdditionAlternativesGroup([ {'[',_},{'[',_}|Rest],[]) ->
+ parse_ExtensionAdditionAlternativesGroup2(Rest,undefined);
+parse_ExtensionAdditionAlternativesGroup(Tokens,_) ->
+ throw({asn1_error,
+ {get_line(hd(Tokens)),get(asn1_module),
+ [got,[get_token(hd(Tokens)),get_token(hd(tl(Tokens)))],
+ expected,['[[']]}}).
+
+
+parse_ExtensionAdditionAlternativesGroup2(Tokens,Num) ->
+ {CompTypeList,Rest} = parse_AlternativeTypeList(Tokens,[]),
case Rest of
- [{',',_},Id = {identifier,_,_}|Rest2] ->
- parse_AlternativeTypeList([Id|Rest2],[NamedType|Acc]);
+ [{']',_},{']',_}|Rest2] ->
+ {[{'ExtensionAdditionGroup',Num}|CompTypeList] ++
+ ['ExtensionAdditionGroupEnd'],Rest2};
_ ->
- {lists:reverse([NamedType|Acc]),Rest}
- end.
-
+ throw({asn1_error,{get_line(hd(Rest)),get(asn1_module),
+ [got,get_token(hd(Rest)),expected,[']]']]}})
+ end.
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+%% parse_AlternativeTypeLists(Tokens,ExtensionDefault) ->
+%% {AltTypeList,Rest1} = parse_AlternativeTypeList(Tokens),
+%% {ExtensionAndException,Rest2} =
+%% case Rest1 of
+%% [{',',_},{'...',L1},{'!',_}|Rest12] ->
+%% {_,Rest13} = parse_ExceptionIdentification(Rest12),
+%% %% Exception info is currently thrown away
+%% {[#'EXTENSIONMARK'{pos=L1}],Rest13};
+%% [{',',_},{'...',L1}|Rest12] ->
+%% {[#'EXTENSIONMARK'{pos=L1}],Rest12};
+%% _ ->
+%% {[],Rest1}
+%% end,
+%% {AltTypeList2,Rest5} =
+%% case ExtensionAndException of
+%% [] ->
+%% {AltTypeList,Rest2};
+%% _ ->
+%% {ExtensionAddition,Rest3} =
+%% case Rest2 of
+%% [{',',_}|Rest23] ->
+%% parse_ExtensionAdditionAlternativeList(Rest23);
+%% _ ->
+%% {[],Rest2}
+%% end,
+%% {OptionalExtensionMarker,Rest4} =
+%% case Rest3 of
+%% [{',',_},{'...',L3}|Rest31] ->
+%% {[#'EXTENSIONMARK'{pos=L3}],Rest31};
+%% _ ->
+%% {[],Rest3}
+%% end,
+%% {AltTypeList ++ ExtensionAndException ++
+%% ExtensionAddition ++ OptionalExtensionMarker, Rest4}
+%% end,
+%% AltTypeList3 =
+%% case [X || X=#'EXTENSIONMARK'{} <- AltTypeList2] of
+%% [] when ExtensionDefault == 'IMPLIED' ->
+%% AltTypeList2 ++ [#'EXTENSIONMARK'{}];
+%% _ ->
+%% AltTypeList2
+%% end,
+%% {AltTypeList3,Rest5}.
-parse_ExtensionAdditionAlternativeList(Tokens) ->
- parse_ExtensionAdditionAlternativeList(Tokens,[]).
+%% parse_AlternativeTypeList(Tokens) ->
+%% parse_AlternativeTypeList(Tokens,[]).
+
+%% parse_AlternativeTypeList(Tokens,Acc) ->
+%% {NamedType,Rest} = parse_NamedType(Tokens),
+%% case Rest of
+%% [{',',_},Id = {identifier,_,_}|Rest2] ->
+%% parse_AlternativeTypeList([Id|Rest2],[NamedType|Acc]);
+%% _ ->
+%% {lists:reverse([NamedType|Acc]),Rest}
+%% end.
+
-parse_ExtensionAdditionAlternativeList(Tokens,Acc) ->
- {Element,Rest0} =
- case Tokens of
- [{identifier,_,_}|_Rest] ->
- parse_NamedType(Tokens);
- [{'[',_},{'[',_}|_] ->
- parse_ExtensionAdditionAlternatives(Tokens)
- end,
- case Rest0 of
- [{',',_}|Rest01] ->
- parse_ExtensionAdditionAlternativeList(Rest01,[Element|Acc]);
- _ ->
- {lists:reverse([Element|Acc]),Rest0}
- end.
-parse_ExtensionAdditionAlternatives([{'[',_},{'[',_}|Rest]) ->
- parse_ExtensionAdditionAlternatives(Rest,[]);
-parse_ExtensionAdditionAlternatives(Tokens) ->
- throw({asn1_error,{get_line(hd(Tokens)),get(asn1_module),
- [got,get_token(hd(Tokens)),expected,'[[']}}).
+%% parse_ExtensionAdditionAlternativeList(Tokens) ->
+%% parse_ExtensionAdditionAlternativeList(Tokens,[]).
+
+%% parse_ExtensionAdditionAlternativeList([{'[[',_}|Rest],Acc) ->
+%% parse_ExtensionAdditionAlternativeList(Rest,Acc);
+%% parse_ExtensionAdditionAlternativeList(Tokens = [{identifier,_,_}|_Rest],Acc) ->
+%% {Element,Rest0} = parse_NamedType(Tokens);
+%% case Rest0 of
+%% [{',',_}|Rest01] ->
+%% parse_ExtensionAdditionAlternativeList(Rest01,[Element|Acc]);
+%% _ ->
+%% {lists:reverse([Element|Acc]),Rest0}
+%% end.
-parse_ExtensionAdditionAlternatives([Id = {identifier,_,_}|Rest],Acc) ->
- {NamedType, Rest2} = parse_NamedType([Id|Rest]),
- case Rest2 of
- [{',',_}|Rest21] ->
- parse_ExtensionAdditionAlternatives(Rest21,[NamedType|Acc]);
- [{']',_},{']',_}|Rest21] ->
- {lists:reverse(Acc),Rest21};
- _ ->
- throw({asn1_error,{get_line(hd(Rest2)),get(asn1_module),
- [got,get_token(hd(Rest2)),expected,[',',']]']]}})
- end.
+%% parse_ExtensionAdditionAlternatives([{'[[',_}|Rest]) ->
+%% parse_ExtensionAdditionAlternatives(Rest,[]);
+%% parse_ExtensionAdditionAlternatives(Tokens) ->
+%% throw({asn1_error,{get_line(hd(Tokens)),get(asn1_module),
+%% [got,get_token(hd(Tokens)),expected,'[[']}}).
+
+%% parse_ExtensionAdditionAlternatives([Id = {identifier,_,_}|Rest],Acc) ->
+%% {NamedType, Rest2} = parse_NamedType([Id|Rest]),
+%% case Rest2 of
+%% [{',',_}|Rest21] ->
+%% parse_ExtensionAdditionAlternatives(Rest21,[NamedType|Acc]);
+%% [{']]',_}|Rest21] ->
+%% {lists:reverse(Acc),Rest21};
+%% _ ->
+%% throw({asn1_error,{get_line(hd(Rest2)),get(asn1_module),
+%% [got,get_token(hd(Rest2)),expected,[',',']]']]}})
+%% end.
parse_NamedType([{identifier,L1,Idname}|Rest]) ->
{Type,Rest2} = parse_Type(Rest),
@@ -2353,144 +2540,123 @@ parse_NamedType(Tokens) ->
parse_ComponentTypeLists(Tokens) ->
-% Resulting tuple {ComponentTypeList,Rest1} is returned
- case Tokens of
- [{identifier,_,_}|_Rest0] ->
- {Clist,Rest01} = parse_ComponentTypeList(Tokens),
- case Rest01 of
- [{',',_}|Rest02] ->
- parse_ComponentTypeLists(Rest02,Clist); % 5 - 13
- _ ->
- {Clist,Rest01}
- end;
- [{'COMPONENTS',_},{'OF',_}|_Rest] ->
- {Clist,Rest01} = parse_ComponentTypeList(Tokens),
- case Rest01 of
- [{',',_}|Rest02] ->
- parse_ComponentTypeLists(Rest02,Clist);
- _ ->
- {Clist,Rest01}
- end;
+ parse_ComponentTypeLists(Tokens,[]).
+
+parse_ComponentTypeLists(Tokens = [{identifier,_,_}|_Rest0],Clist) ->
+ {CompList,Rest1} = parse_ComponentTypeList(Tokens,[]),
+ parse_ComponentTypeLists(Rest1,Clist++CompList);
+parse_ComponentTypeLists(Tokens = [{'COMPONENTS',_},{'OF',_}|_Rest],Clist) ->
+ {CompList,Rest1} = parse_ComponentTypeList(Tokens,[]),
+ parse_ComponentTypeLists(Rest1,Clist++CompList);
+parse_ComponentTypeLists([{'...',L1},{'!',_}|Rest02],Clist0) ->
+ {_,Rest03} = parse_ExceptionIdentification(Rest02),
+ %% Exception info is currently thrown away
+ parse_ComponentTypeLists2(Rest03,Clist0++[#'EXTENSIONMARK'{pos=L1}]);
+parse_ComponentTypeLists([{',',L1},{'...',_},{'!',_}|Rest02],Clist0) when Clist0 =/= []->
+ {_,Rest03} = parse_ExceptionIdentification(Rest02),
+ %% Exception info is currently thrown away
+ parse_ComponentTypeLists2(Rest03,Clist0++[#'EXTENSIONMARK'{pos=L1}]);
+
+ parse_ComponentTypeLists([{',',_},{'...',L1}|Rest02],Clist0) when Clist0 =/= []->
+ parse_ComponentTypeLists2(Rest02,Clist0++[#'EXTENSIONMARK'{pos=L1}]);
+parse_ComponentTypeLists([{'...',L1}|Rest02],Clist0) ->
+ parse_ComponentTypeLists2(Rest02,Clist0++[#'EXTENSIONMARK'{pos=L1}]);
+parse_ComponentTypeLists(Tokens = [{'}',_L1}|_Rest02],Clist0) ->
+ {Clist0,Tokens}.
+
+parse_ComponentTypeLists2(Tokens,Clist) ->
+ {ExtAdd,Rest} = parse_ExtensionAdditions(Tokens,Clist),
+ {Clist2,Rest2} = parse_OptionalExtensionMarker(Rest,lists:flatten(ExtAdd)),
+ case Rest2 of
+ [{',',_}|Rest3] ->
+ {CompList,Rest4} = parse_ComponentTypeList(Rest3,[]),
+ {Clist2 ++ CompList,Rest4};
_ ->
- parse_ComponentTypeLists(Tokens,[])
+ {Clist2,Rest2}
end.
-parse_ComponentTypeLists([{'...',L1},{'!',_}|Rest],Clist1) ->
- {_,Rest2} = parse_ExceptionIdentification(Rest),
- %% Exception info is currently thrown away
- parse_ComponentTypeLists2(Rest2,Clist1++[#'EXTENSIONMARK'{pos=L1}]);
-parse_ComponentTypeLists([{'...',L1}|Rest],Clist1) -> %% first Extensionmark
- parse_ComponentTypeLists2(Rest,Clist1++[#'EXTENSIONMARK'{pos=L1}]);
-parse_ComponentTypeLists(Tokens,Clist1) ->
- {Clist1,Tokens}.
-
-
-parse_ComponentTypeLists2(Tokens,Clist1) ->
- {ExtensionAddition,Rest2} =
- case Tokens of
- [{',',_}|Rest1] ->
- parse_ExtensionAdditionList(Rest1);
- _ ->
- {[],Tokens}
- end,
- {OptionalExtensionMarker,Rest3} =
- case Rest2 of
- [{',',_},{'...',L2}|Rest21] ->
- {[#'EXTENSIONMARK'{pos=L2}],Rest21};
- _ ->
- {[],Rest2}
- end,
- {RootComponentTypeList,Rest4} =
- case Rest3 of
- [{',',_}|Rest31] ->
- parse_ComponentTypeList(Rest31);
- _ ->
- {[],Rest3}
- end,
- {Clist1 ++ ExtensionAddition ++ OptionalExtensionMarker ++ RootComponentTypeList, Rest4}.
-
+parse_OptionalExtensionMarker([{',',_},{'...',L1}|Rest],Clist)->
+ {Clist++[#'EXTENSIONMARK'{pos=L1}],Rest};
+parse_OptionalExtensionMarker(Tokens,Clist) ->
+ {Clist,Tokens}.
-parse_ComponentTypeList(Tokens) ->
- parse_ComponentTypeList(Tokens,[]).
-parse_ComponentTypeList(Tokens,Acc) ->
+parse_ComponentTypeList([{',',_},Id = {identifier,_,_}|Rest],Acc) when Acc =/= [] ->
+ {ComponentType,Rest2} = parse_ComponentType([Id|Rest]),
+ parse_ComponentTypeList(Rest2,[ComponentType|Acc]);
+parse_ComponentTypeList([{',',_},C1={'COMPONENTS',_},C2={'OF',_}|Rest],Acc) when Acc =/= [] ->
+ {ComponentType,Rest2} = parse_ComponentType([C1,C2|Rest]),
+ parse_ComponentTypeList(Rest2,[ComponentType|Acc]);
+parse_ComponentTypeList(Tokens = [{'}',_}|_],Acc) ->
+ {lists:reverse(Acc),Tokens};
+parse_ComponentTypeList(Tokens = [{']',_},{']',_}|_],Acc) ->
+ {lists:reverse(Acc),Tokens};
+parse_ComponentTypeList(Tokens = [{',',_},{'...',_}|_],Acc) ->
+ {lists:reverse(Acc),Tokens};
+parse_ComponentTypeList(Tokens,[]) ->
{ComponentType,Rest} = parse_ComponentType(Tokens),
+ parse_ComponentTypeList(Rest,[ComponentType]);
+parse_ComponentTypeList(Tokens,_) ->
+ throw({asn1_error,
+ {get_line(hd(Tokens)),get(asn1_module),
+ [got,[get_token(hd(Tokens)),get_token(hd(tl(Tokens)))],
+ expected,['}',', identifier']]}}).
+
+parse_ExtensionAdditions(Tokens=[{',',_}|_],Clist) ->
+ {ExtAddList,Rest2} = parse_ExtensionAdditionList(Tokens,[]),
+ {Clist++ExtAddList,Rest2};
+parse_ExtensionAdditions(Tokens,Clist) ->
+ %% Empty
+ {Clist,Tokens}.
+
+parse_ExtensionAdditionList([{',',_},Id = {identifier,_,_}|Rest],Acc) ->
+ {ComponentType,Rest2} = parse_ComponentType([Id|Rest]),
+ parse_ExtensionAdditionList(Rest2,[ComponentType|Acc]);
+parse_ExtensionAdditionList([{',',_},C1={'COMPONENTS',_},C2={'OF',_}|Rest],Acc) ->
+ {ComponentType,Rest2} = parse_ComponentType([C1,C2|Rest]),
+ parse_ExtensionAdditionList(Rest2,[ComponentType|Acc]);
+parse_ExtensionAdditionList([{',',_},C1 = {'[',_},C2 = {'[',_}|Rest],Acc) ->
+ {ExtAddGroup,Rest2} = parse_ExtensionAdditionGroup([C1,C2|Rest],[]),
+ parse_ExtensionAdditionList(Rest2,[ExtAddGroup|Acc]);
+parse_ExtensionAdditionList(Tokens = [{'}',_}|_],Acc) ->
+ {lists:reverse(Acc),Tokens};
+parse_ExtensionAdditionList(Tokens = [{',',_},{'...',_}|_],Acc) ->
+ {lists:reverse(Acc),Tokens};
+parse_ExtensionAdditionList(Tokens,_) ->
+ throw({asn1_error,
+ {get_line(hd(Tokens)),get(asn1_module),
+ [got,[get_token(hd(Tokens)),get_token(hd(tl(Tokens)))],
+ expected,['}',', identifier']]}}).
+
+
+parse_ExtensionAdditionGroup([ {'[',_},{'[',_},_VsnNr = {number,_,Num},{':',_}|Rest],[]) ->
+ parse_ExtensionAdditionGroup2(Rest,Num);
+parse_ExtensionAdditionGroup([ {'[',_},{'[',_}|Rest],[]) ->
+ parse_ExtensionAdditionGroup2(Rest,undefined);
+parse_ExtensionAdditionGroup(Tokens,_) ->
+ throw({asn1_error,
+ {get_line(hd(Tokens)),get(asn1_module),
+ [got,[get_token(hd(Tokens)),get_token(hd(tl(Tokens)))],
+ expected,['[[']]}}).
+
+
+parse_ExtensionAdditionGroup2(Tokens,Num) ->
+ {CompTypeList,Rest} = parse_ComponentTypeList(Tokens,[]),
case Rest of
- [{',',_},Id = {identifier,_,_}|Rest2] ->
- parse_ComponentTypeList([Id|Rest2],[ComponentType|Acc]);
- [{',',_},C1={'COMPONENTS',_},C2={'OF',_}|Rest2] ->
- parse_ComponentTypeList([C1,C2|Rest2],[ComponentType|Acc]);
-% _ ->
-% {lists:reverse([ComponentType|Acc]),Rest}
- [{'}',_}|_] ->
- {lists:reverse([ComponentType|Acc]),Rest};
-% [{',',_},{'...',_},{'}',_}|_] ->
-% {lists:reverse([ComponentType|Acc]),Rest};
- [{',',_},{'...',_}|_] ->%% here comes the dubble ellipse
- {lists:reverse([ComponentType|Acc]),Rest};
+ [{']',_},{']',_}|Rest2] ->
+ {[{'ExtensionAdditionGroup',Num}|CompTypeList] ++
+ ['ExtensionAdditionGroupEnd'],Rest2};
_ ->
- throw({asn1_error,
- {get_line(hd(Tokens)),get(asn1_module),
- [got,[get_token(hd(Rest)),get_token(hd(tl(Rest)))],
- expected,['}',', identifier']]}})
- end.
-
-
-parse_ExtensionAdditionList(Tokens) ->
- parse_ExtensionAdditionList(Tokens,[]).
-
-parse_ExtensionAdditionList(Tokens,Acc) ->
- {Element,Rest0} =
- case Tokens of
- [{identifier,_,_}|_Rest] ->
- parse_ComponentType(Tokens);
- [{'[',_},{'[',_}|_] ->
- parse_ExtensionAdditions(Tokens);
- [{'...',L1}|_Rest] ->
- {#'EXTENSIONMARK'{pos=L1},Tokens};
- _ ->
- throw({asn1_error,{get_line(hd(Tokens)),get(asn1_module),
- [got,get_token(hd(Tokens)),expected,
- [identifier,'[[']]}})
- end,
- case Rest0 of
- [{',',_}|Rest01] ->
- parse_ExtensionAdditionList(Rest01,[Element|Acc]);
- [{'...',_}|Rest01] ->
- {lists:reverse([Element|Acc]),Rest01};
- _ ->
- {lists:reverse([Element|Acc]),Rest0}
+ throw({asn1_error,{get_line(hd(Rest)),get(asn1_module),
+ [got,get_token(hd(Rest)),expected,[']]']]}})
end.
-parse_ExtensionAdditions([{'[',_},{'[',_}|Rest]) ->
- parse_ExtensionAdditions(Rest,[]);
-parse_ExtensionAdditions(Tokens) ->
- throw({asn1_error,{get_line(hd(Tokens)),get(asn1_module),
- [got,get_token(hd(Tokens)),expected,'[[']}}).
-
-parse_ExtensionAdditions([_VsnNr = {number,_,_},{':',_}|Rest],Acc) ->
- %% ignor version number for now
- parse_ExtensionAdditions(Rest,Acc);
-parse_ExtensionAdditions([Id = {identifier,_,_}|Rest],Acc) ->
- {ComponentType, Rest2} = parse_ComponentType([Id|Rest]),
- case Rest2 of
- [{',',_}|Rest21] ->
- parse_ExtensionAdditions(Rest21,[ComponentType|Acc]);
- [{']',_},{']',_}|Rest21] ->
- {lists:reverse(Acc),Rest21};
- _ ->
- throw({asn1_error,{get_line(hd(Rest2)),get(asn1_module),
- [got,get_token(hd(Rest2)),expected,[',',']]']]}})
- end;
-parse_ExtensionAdditions(Tokens,_) ->
- throw({asn1_error,{get_line(hd(Tokens)),get(asn1_module),
- [got,get_token(hd(Tokens)),expected,identifier]}}).
parse_ComponentType([{'COMPONENTS',_},{'OF',_}|Rest]) ->
{Type,Rest2} = parse_Type(Rest),
{{'COMPONENTS OF',Type},Rest2};
parse_ComponentType(Tokens) ->
- {NamedType,Rest} = parse_NamedType(Tokens),
+ Result = {NamedType,Rest} = parse_NamedType(Tokens),
case Rest of
[{'OPTIONAL',_}|Rest2] ->
{NamedType#'ComponentType'{prop='OPTIONAL'},Rest2};
@@ -2498,7 +2664,7 @@ parse_ComponentType(Tokens) ->
{Value,Rest21} = parse_Value(Rest2),
{NamedType#'ComponentType'{prop={'DEFAULT',Value}},Rest21};
_ ->
- {NamedType,Rest}
+ Result
end.
@@ -2512,35 +2678,39 @@ parse_SignedNumber(Tokens) ->
[got,get_token(hd(Tokens)),expected,
[number,'-number']]}}).
-parse_Enumerations(Tokens=[{identifier,_,_}|_Rest]) ->
- parse_Enumerations(Tokens,[]);
-parse_Enumerations([H|_T]) ->
+parse_Enumerations(Tokens=[{identifier,_,_}|_Rest],ExtensionDefault) ->
+ parse_Enumerations(Tokens,[],ExtensionDefault);
+parse_Enumerations([H|_T],_) ->
throw({asn1_error,{get_line(H),get(asn1_module),
[got,get_token(H),expected,identifier]}}).
-parse_Enumerations(Tokens = [{identifier,_,_},{'(',_}|_Rest], Acc) ->
+parse_Enumerations(Tokens = [{identifier,_,_},{'(',_}|_Rest], Acc, ExtensionDefault) ->
{NamedNumber,Rest2} = parse_NamedNumber(Tokens),
case Rest2 of
[{',',_}|Rest3] ->
- parse_Enumerations(Rest3,[NamedNumber|Acc]);
+ parse_Enumerations(Rest3,[NamedNumber|Acc], ExtensionDefault);
+ _ when ExtensionDefault == 'IMPLIED'->
+ {lists:reverse(['EXTENSIONMARK',NamedNumber|Acc]),Rest2};
_ ->
{lists:reverse([NamedNumber|Acc]),Rest2}
end;
-parse_Enumerations([{identifier,_,Id}|Rest], Acc) ->
+parse_Enumerations([{identifier,_,Id}|Rest], Acc, ExtensionDefault) ->
case Rest of
[{',',_}|Rest2] ->
- parse_Enumerations(Rest2,[Id|Acc]);
+ parse_Enumerations(Rest2,[Id|Acc], ExtensionDefault);
+ _ when ExtensionDefault == 'IMPLIED' ->
+ {lists:reverse(['EXTENSIONMARK', Id |Acc]),Rest};
_ ->
{lists:reverse([Id|Acc]),Rest}
end;
-parse_Enumerations([{'...',_}|Rest], Acc) ->
+parse_Enumerations([{'...',_}|Rest], Acc, _ExtensionDefault) ->
case Rest of
[{',',_}|Rest2] ->
- parse_Enumerations(Rest2,['EXTENSIONMARK'|Acc]);
+ parse_Enumerations(Rest2,['EXTENSIONMARK'|Acc],undefined);
_ ->
{lists:reverse(['EXTENSIONMARK'|Acc]),Rest}
end;
-parse_Enumerations([H|_T],_) ->
+parse_Enumerations([H|_T],_,_) ->
throw({asn1_error,{get_line(H),get(asn1_module),
[got,get_token(H),expected,identifier]}}).
@@ -2915,6 +3085,7 @@ merge_constraints([],Cacc,Eacc) ->
%% lists:flatten(Cacc) ++ [{'Errors',Eacc}].
lists:reverse(Cacc) ++ [{'Errors',Eacc}].
+
fixup_constraint(C) ->
case C of
{'SingleValue',SubType} when element(1,SubType) == 'ContainedSubtype' ->
diff --git a/lib/asn1/src/asn1ct_tok.erl b/lib/asn1/src/asn1ct_tok.erl
index 27116c46c5..85199c65ec 100644
--- a/lib/asn1/src/asn1ct_tok.erl
+++ b/lib/asn1/src/asn1ct_tok.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%
%%
%%
@@ -21,7 +21,7 @@
%% Tokenize ASN.1 code (input to parser generated with yecc)
--export([get_name/2,tokenise/2, file/1]).
+-export([get_name/2,tokenise/4, file/1]).
file(File) ->
@@ -29,12 +29,9 @@ file(File) ->
{error, Reason} ->
{error,{File,file:format_error(Reason)}};
{ok,Stream} ->
- process0(Stream)
+ process(Stream,0,[])
end.
-process0(Stream) ->
- process(Stream,0,[]).
-
process(Stream,Lno,R) ->
process(io:get_line(Stream, ''), Stream,Lno+1,R).
@@ -45,131 +42,128 @@ process(eof, Stream,Lno,R) ->
process(L, Stream,Lno,R) when is_list(L) ->
%%io:format('read:~s',[L]),
- case catch tokenise(L,Lno) of
+ case catch tokenise(Stream,L,Lno,[]) of
{'ERR',Reason} ->
io:format("Tokeniser error on line: ~w ~w~n",[Lno,Reason]),
exit(0);
- {multiline_comment,NestingLevel} ->
- {RestL,Lno2} = process_skip_multiline_comment(Stream,Lno,NestingLevel),
- process(RestL,Stream,Lno2,R);
- T ->
+ {NewLno,T} ->
%%io:format('toks:~w~n',[T]),
- process(Stream,Lno,[T|R])
+ process(Stream,NewLno,[T|R])
end.
-process_skip_multiline_comment(Stream,Lno,NestingLevel) ->
- process_skip_multiline_comment(io:get_line(Stream, ''),
- Stream, Lno + 1, NestingLevel).
-process_skip_multiline_comment(eof,_Stream,Lno,_NestingLevel) ->
- io:format("Tokeniser error on line: ~w, premature end of multiline comment~n",[Lno]),
- exit(0);
-process_skip_multiline_comment(Line,Stream,Lno,NestingLevel) ->
- case catch skip_multiline_comment(Line,NestingLevel) of
- {multiline_comment,NestingLevel2} ->
- process_skip_multiline_comment(Stream,Lno,NestingLevel2);
- T ->
- {T,Lno}
- end.
-
-tokenise([H|T],Lno) when $a =< H , H =< $z ->
+tokenise(Stream,[H|T],Lno,R) when $a =< H , H =< $z ->
{X, T1} = get_name(T, [H]),
- [{identifier,Lno, list_to_atom(X)}|tokenise(T1,Lno)];
+ tokenise(Stream,T1,Lno,[{identifier,Lno, list_to_atom(X)}|R]);
-tokenise([$&,H|T],Lno) when $A =< H , H =< $Z ->
+tokenise(Stream,[$&,H|T],Lno,R) when $A =< H , H =< $Z ->
{Y, T1} = get_name(T, [H]),
X = list_to_atom(Y),
- [{typefieldreference, Lno, X} | tokenise(T1, Lno)];
+ tokenise(Stream,T1,Lno,[{typefieldreference, Lno, X} | R]);
-tokenise([$&,H|T],Lno) when $a =< H , H =< $z ->
+tokenise(Stream,[$&,H|T],Lno,R) when $a =< H , H =< $z ->
{Y, T1} = get_name(T, [H]),
X = list_to_atom(Y),
- [{valuefieldreference, Lno, X} | tokenise(T1, Lno)];
+ tokenise(Stream,T1,Lno,[{valuefieldreference, Lno, X} | R]);
-tokenise([H|T],Lno) when $A =< H , H =< $Z ->
+tokenise(Stream,[H|T],Lno,R) when $A =< H , H =< $Z ->
{Y, T1} = get_name(T, [H]),
X = list_to_atom(Y),
case reserved_word(X) of
true ->
- [{X,Lno}|tokenise(T1,Lno)];
+ tokenise(Stream,T1,Lno,[{X,Lno}|R]);
false ->
- [{typereference,Lno,X}|tokenise(T1,Lno)];
+ tokenise(Stream,T1,Lno,[{typereference,Lno,X}|R]);
rstrtype ->
- [{restrictedcharacterstringtype,Lno,X}|tokenise(T1,Lno)]
+ tokenise(Stream,T1,Lno,[{restrictedcharacterstringtype,Lno,X}|R])
end;
-tokenise([$-,H|T],Lno) when $0 =< H , H =< $9 ->
+tokenise(Stream,[$-,H|T],Lno,R) when $0 =< H , H =< $9 ->
{X, T1} = get_number(T, [H]),
- [{number,Lno,-1 * list_to_integer(X)}|tokenise(T1,Lno)];
+ tokenise(Stream,T1,Lno,[{number,Lno,-1 * list_to_integer(X)}|R]);
-tokenise([H|T],Lno) when $0 =< H , H =< $9 ->
+tokenise(Stream,[H|T],Lno,R) when $0 =< H , H =< $9 ->
{X, T1} = get_number(T, [H]),
- [{number,Lno,list_to_integer(X)}|tokenise(T1,Lno)];
+ tokenise(Stream,T1,Lno,[{number,Lno,list_to_integer(X)}|R]);
-tokenise([$-,$-|T],Lno) ->
- tokenise(skip_comment(T),Lno);
+tokenise(Stream,[$-,$-|T],Lno,R) ->
+ tokenise(Stream,skip_comment(T),Lno,R);
-tokenise([$/,$*|T],Lno) ->
- tokenise(skip_multiline_comment(T,0),Lno);
+tokenise(Stream,[$/,$*|T],Lno,R) ->
+ {NewLno,T1} = skip_multiline_comment(Stream,T,Lno,0),
+ tokenise(Stream,T1,NewLno,R);
-tokenise([$:,$:,$=|T],Lno) ->
- [{'::=',Lno}|tokenise(T,Lno)];
+tokenise(Stream,[$:,$:,$=|T],Lno,R) ->
+ tokenise(Stream,T,Lno,[{'::=',Lno}|R]);
-tokenise([$'|T],Lno) ->
+tokenise(Stream,[$'|T],Lno,R) ->
case catch collect_quoted(T,Lno,[]) of
{'ERR',_} ->
throw({'ERR','bad_quote'});
{Thing, T1} ->
- [Thing|tokenise(T1,Lno)]
+ tokenise(Stream,T1,Lno,[Thing|R])
end;
-tokenise([$"|T],Lno) ->
- collect_string(T,Lno);
+tokenise(Stream,[$"|T],Lno,R) ->
+ {Str,T1} = collect_string(T,Lno),
+ tokenise(Stream,T1,Lno,[Str|R]);
-tokenise([${|T],Lno) ->
- [{'{',Lno}|tokenise(T,Lno)];
+tokenise(Stream,[${|T],Lno,R) ->
+ tokenise(Stream,T,Lno,[{'{',Lno}|R]);
-tokenise([$}|T],Lno) ->
- [{'}',Lno}|tokenise(T,Lno)];
+tokenise(Stream,[$}|T],Lno,R) ->
+ tokenise(Stream,T,Lno,[{'}',Lno}|R]);
-tokenise([$]|T],Lno) ->
- [{']',Lno}|tokenise(T,Lno)];
+%% tokenise(Stream,[$],$]|T],Lno,R) ->
+%% tokenise(Stream,T,Lno,[{']]',Lno}|R]);
-tokenise([$[|T],Lno) ->
- [{'[',Lno}|tokenise(T,Lno)];
+%% Even though x.680 specify '[[' and ']]' as lexical items
+%% it does not work to have them as such since the single [ and ] can
+%% be used beside each other in the SYNTAX OF in x.681
+%% the solution chosen here , i.e. to have them as separate lexical items
+%% will not detect the cases where there is white space between them
+%% which would be an error in the use in ExtensionAdditionGroups
-tokenise([$,|T],Lno) ->
- [{',',Lno}|tokenise(T,Lno)];
+%% tokenise(Stream,[$[,$[|T],Lno,R) ->
+%% tokenise(Stream,T,Lno,[{'[[',Lno}|R]);
-tokenise([$(|T],Lno) ->
- [{'(',Lno}|tokenise(T,Lno)];
-tokenise([$)|T],Lno) ->
- [{')',Lno}|tokenise(T,Lno)];
+tokenise(Stream,[$]|T],Lno,R) ->
+ tokenise(Stream,T,Lno,[{']',Lno}|R]);
-tokenise([$.,$.,$.|T],Lno) ->
- [{'...',Lno}|tokenise(T,Lno)];
+tokenise(Stream,[$[|T],Lno,R) ->
+ tokenise(Stream,T,Lno,[{'[',Lno}|R]);
-tokenise([$.,$.|T],Lno) ->
- [{'..',Lno}|tokenise(T,Lno)];
+tokenise(Stream,[$,|T],Lno,R) ->
+ tokenise(Stream,T,Lno,[{',',Lno}|R]);
-tokenise([$.|T],Lno) ->
- [{'.',Lno}|tokenise(T,Lno)];
-tokenise([$^|T],Lno) ->
- [{'^',Lno}|tokenise(T,Lno)];
-tokenise([$!|T],Lno) ->
- [{'!',Lno}|tokenise(T,Lno)];
-tokenise([$||T],Lno) ->
- [{'|',Lno}|tokenise(T,Lno)];
+tokenise(Stream,[$(|T],Lno,R) ->
+ tokenise(Stream,T,Lno,[{'(',Lno}|R]);
+tokenise(Stream,[$)|T],Lno,R) ->
+ tokenise(Stream,T,Lno,[{')',Lno}|R]);
+tokenise(Stream,[$.,$.,$.|T],Lno,R) ->
+ tokenise(Stream,T,Lno,[{'...',Lno}|R]);
-tokenise([H|T],Lno) ->
+tokenise(Stream,[$.,$.|T],Lno,R) ->
+ tokenise(Stream,T,Lno,[{'..',Lno}|R]);
+
+tokenise(Stream,[$.|T],Lno,R) ->
+ tokenise(Stream,T,Lno,[{'.',Lno}|R]);
+tokenise(Stream,[$^|T],Lno,R) ->
+ tokenise(Stream,T,Lno,[{'^',Lno}|R]);
+tokenise(Stream,[$!|T],Lno,R) ->
+ tokenise(Stream,T,Lno,[{'!',Lno}|R]);
+tokenise(Stream,[$||T],Lno,R) ->
+ tokenise(Stream,T,Lno,[{'|',Lno}|R]);
+
+tokenise(Stream,[H|T],Lno,R) ->
case white_space(H) of
true ->
- tokenise(T,Lno);
+ tokenise(Stream,T,Lno,R);
false ->
- [{list_to_atom([H]),Lno}|tokenise(T,Lno)]
+ tokenise(Stream,T,Lno,[{list_to_atom([H]),Lno}|R])
end;
-tokenise([],_) ->
- [].
+tokenise(_Stream,[],Lno,R) ->
+ {Lno,lists:reverse(R)}.
collect_string(L,Lno) ->
@@ -181,7 +175,7 @@ collect_string([],_,_) ->
collect_string([H|T],Lno,Str) ->
case H of
$" ->
- [{cstring,1,lists:reverse(Str)}|tokenise(T,Lno)];
+ {{cstring,1,lists:reverse(Str)},T};
Ch ->
collect_string(T,Lno,[Ch|Str])
end.
@@ -252,17 +246,23 @@ skip_comment([_|T]) ->
skip_comment(T).
-skip_multiline_comment([],L) ->
- throw({multiline_comment,L});
-skip_multiline_comment([$*,$/|T],0) ->
- T;
-skip_multiline_comment([$*,$/|T],Level) ->
- skip_multiline_comment(T,Level - 1);
-skip_multiline_comment([$/,$*|T],Level) ->
- skip_multiline_comment(T,Level + 1);
-skip_multiline_comment([_|T],Level) ->
- skip_multiline_comment(T,Level).
-
+skip_multiline_comment(Stream,[],Lno,Level) ->
+ case io:get_line(Stream,'') of
+ eof ->
+ io:format("Tokeniser error on line: ~w~n"
+ "premature end of multiline comment~n",[Lno]),
+ exit(0);
+ Line ->
+ skip_multiline_comment(Stream,Line,Lno+1,Level)
+ end;
+skip_multiline_comment(_Stream,[$*,$/|T],Lno,0) ->
+ {Lno,T};
+skip_multiline_comment(Stream,[$*,$/|T],Lno,Level) ->
+ skip_multiline_comment(Stream,T,Lno,Level - 1);
+skip_multiline_comment(Stream,[$/,$*|T],Lno,Level) ->
+ skip_multiline_comment(Stream,T,Lno,Level + 1);
+skip_multiline_comment(Stream,[_|T],Lno,Level) ->
+ skip_multiline_comment(Stream,T,Lno,Level).
collect_quoted([$',$B|T],Lno, L) ->
case check_bin(L) of
@@ -327,7 +327,7 @@ reserved_word('COMPONENTS') -> true;
reserved_word('CONSTRAINED') -> true;
reserved_word('CONTAINING') -> true;
reserved_word('DEFAULT') -> true;
-reserved_word('DEFINED') -> true;
+reserved_word('DEFINED') -> true; % not present in X.680 07/2002
reserved_word('DEFINITIONS') -> true;
reserved_word('EMBEDDED') -> true;
reserved_word('ENCODED') -> true;
@@ -336,6 +336,7 @@ reserved_word('ENUMERATED') -> true;
reserved_word('EXCEPT') -> true;
reserved_word('EXPLICIT') -> true;
reserved_word('EXPORTS') -> true;
+reserved_word('EXTENSIBILITY') -> true;
reserved_word('EXTERNAL') -> true;
reserved_word('FALSE') -> true;
reserved_word('FROM') -> true;
@@ -343,9 +344,9 @@ reserved_word('GeneralizedTime') -> true;
reserved_word('GeneralString') -> rstrtype;
reserved_word('GraphicString') -> rstrtype;
reserved_word('IA5String') -> rstrtype;
-% reserved_word('TYPE-IDENTIFIER') -> true; % impl as predef item
reserved_word('IDENTIFIER') -> true;
reserved_word('IMPLICIT') -> true;
+reserved_word('IMPLIED') -> true;
reserved_word('IMPORTS') -> true;
reserved_word('INCLUDES') -> true;
reserved_word('INSTANCE') -> true;
@@ -379,6 +380,7 @@ reserved_word('T61String') -> rstrtype;
reserved_word('TAGS') -> true;
reserved_word('TeletexString') -> rstrtype;
reserved_word('TRUE') -> true;
+%% reserved_word('TYPE-IDENTIFIER') -> true; % impl as predef item
reserved_word('UNION') -> true;
reserved_word('UNIQUE') -> true;
reserved_word('UNIVERSAL') -> true;
diff --git a/lib/asn1/src/asn1rt_ber_bin.erl b/lib/asn1/src/asn1rt_ber_bin.erl
index 71d78377d4..ab04d981b0 100644
--- a/lib/asn1/src/asn1rt_ber_bin.erl
+++ b/lib/asn1/src/asn1rt_ber_bin.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2000-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 2000-2010. All Rights Reserved.
+%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
-%%
+%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
-%%
+%%
%% %CopyrightEnd%
%%
%%
@@ -179,7 +179,7 @@ restbytes2(_RemBytes,Bytes,noext) ->
exit({error,{asn1, {unexpected,Bytes}}});
restbytes2(RemBytes,Bytes,ext) ->
%% {RemBytes,0}.
- {RemBytes,size(Bytes)}.
+ {RemBytes,byte_size(Bytes)}.
@@ -256,8 +256,6 @@ skip_ExtensionAdditions(Bytes,Tags,RmB) ->
end
end.
-
-
%%===============================================================================
%%===============================================================================
%%===============================================================================
@@ -339,7 +337,7 @@ peek_tag(<<PartialTag,Buffer/binary>>, TagAck) ->
peek_tag(Buffer,<<TagAck/binary,PartialTag>>);
peek_tag(_,TagAck) ->
exit({error,{asn1, {invalid_tag,TagAck}}}).
-%%peek_tag([Tag|Buffer]) when (Tag band 31) == 31 ->
+%%peek_tag([Tag|Buffer]) when (Tag band 31) =:= 31 ->
%% [Tag band 2#11011111 | peek_tag(Buffer,[])];
%%%% single tag (tagno < 31)
%%peek_tag([Tag|Buffer]) ->
@@ -474,8 +472,7 @@ encode_tags2([Tag|Trest], BytesSoFar, LenSoFar) ->
encode_tags2([], BytesSoFar, LenSoFar) ->
{BytesSoFar,LenSoFar}.
-encode_tags1([Tag1, Tag2| Trest], Acc)
- when Tag1#tag.type == 'IMPLICIT' ->
+encode_tags1([Tag1, Tag2| Trest], Acc) when Tag1#tag.type =:= 'IMPLICIT' ->
encode_tags1([Tag1#tag{type=Tag2#tag.type,form=Tag2#tag.form}|Trest],Acc);
encode_tags1([Tag1 | Trest], Acc) ->
encode_tags1(Trest, [Tag1|Acc]);
@@ -483,7 +480,7 @@ encode_tags1([], Acc) ->
Acc. % the resulting tags are returned in reverse order
encode_one_tag(Bin) when is_binary(Bin) ->
- {Bin,size(Bin)};
+ {Bin,byte_size(Bin)};
encode_one_tag(#tag{class=Class,number=No,type=Type, form = Form}) ->
NewForm = case Type of
'EXPLICIT' ->
@@ -506,11 +503,6 @@ encode_one_tag(#tag{class=Class,number=No,type=Type, form = Form}) ->
% [encode_tag_val({NewClass, OldForm, NewTagNr}) | Buffer1].
-
-
-
-
-
%%===============================================================================
%%
%% This comment is valid for all the encode/decode functions
@@ -533,20 +525,19 @@ encode_one_tag(#tag{class=Class,number=No,type=Type, form = Form}) ->
%% This version does not consider Explicit tagging of the open type. It
%% is only left because of backward compatibility.
encode_open_type(Val) when is_list(Val) ->
- {Val,size(list_to_binary(Val))};
+ {Val, byte_size(list_to_binary(Val))};
encode_open_type(Val) ->
- {Val, size(Val)}.
+ {Val, byte_size(Val)}.
%%
encode_open_type(Val, []) when is_list(Val) ->
- {Val,size(list_to_binary(Val))};
-encode_open_type(Val,[]) ->
- {Val, size(Val)};
+ {Val, byte_size(list_to_binary(Val))};
+encode_open_type(Val, []) ->
+ {Val, byte_size(Val)};
encode_open_type(Val, Tag) when is_list(Val) ->
- encode_tags(Tag,Val,size(list_to_binary(Val)));
-encode_open_type(Val,Tag) ->
- encode_tags(Tag,Val, size(Val)).
-
+ encode_tags(Tag, Val, byte_size(list_to_binary(Val)));
+encode_open_type(Val, Tag) ->
+ encode_tags(Tag, Val, byte_size(Val)).
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
@@ -652,8 +643,6 @@ decode_boolean2(Buffer, _) ->
exit({error,{asn1, {decode_boolean, Buffer}}}).
-
-
%%===========================================================================
%% Integer, ITU_T X.690 Chapter 8.3
@@ -664,7 +653,7 @@ decode_boolean2(Buffer, _) ->
%%===========================================================================
encode_integer(C, Val, []) when is_integer(Val) ->
- {EncVal,Len}=encode_integer(C, Val),
+ {EncVal,Len} = encode_integer(C, Val),
dotag_universal(?N_INTEGER,EncVal,Len);
encode_integer(C, Val, Tag) when is_integer(Val) ->
dotag(Tag, ?N_INTEGER, encode_integer(C, Val));
@@ -674,10 +663,9 @@ encode_integer(_, Val, _) ->
exit({error,{asn1, {encode_integer, Val}}}).
-
encode_integer(C, Val, NamedNumberList, Tag) when is_atom(Val) ->
- case lists:keysearch(Val, 1, NamedNumberList) of
- {value,{_, NewVal}} ->
+ case lists:keyfind(Val, 1, NamedNumberList) of
+ {_, NewVal} ->
dotag(Tag, ?N_INTEGER, encode_integer(C, NewVal));
_ ->
exit({error,{asn1, {encode_integer_namednumber, Val}}})
@@ -688,8 +676,6 @@ encode_integer(C, Val, _NamedNumberList, Tag) ->
dotag(Tag, ?N_INTEGER, encode_integer(C, Val)).
-
-
encode_integer(_C, Val) ->
Bytes =
if
@@ -716,7 +702,6 @@ encode_integer_neg(N, Acc) ->
%% (Buffer, Range, NamedNumberList, HasTag, TotalLen) -> {Integer, Remain, RemovedBytes}
%%===============================================================================
-
decode_integer(Buffer, Range, Tags, OptOrMand) ->
NewTags = new_tags(Tags,#tag{class=?UNIVERSAL,number=?N_INTEGER}),
decode_integer_notag(Buffer, Range, [], NewTags, OptOrMand).
@@ -748,8 +733,8 @@ resolve_named_value(Result={Val,Buffer,RemBytes},NamedNumberList) ->
case NamedNumberList of
[] -> Result;
_ ->
- NewVal = case lists:keysearch(Val, 2, NamedNumberList) of
- {value,{NamedVal, _}} ->
+ NewVal = case lists:keyfind(Val, 2, NamedNumberList) of
+ {NamedVal, _} ->
NamedVal;
_ ->
Val
@@ -778,10 +763,10 @@ check_integer_constraint(Result={Val, _Buffer,_},Range) ->
%% encode enumerated value
%%============================================================================
-encode_enumerated(Val, []) when is_integer(Val)->
+encode_enumerated(Val, []) when is_integer(Val) ->
{EncVal,Len} = encode_integer(false,Val),
dotag_universal(?N_ENUMERATED,EncVal,Len);
-encode_enumerated(Val, DoTag) when is_integer(Val)->
+encode_enumerated(Val, DoTag) when is_integer(Val) ->
dotag(DoTag, ?N_ENUMERATED, encode_integer(false,Val));
encode_enumerated({Name,Val}, DoTag) when is_atom(Name) ->
encode_enumerated(Val, DoTag).
@@ -797,11 +782,11 @@ encode_enumerated(C, Val, {NamedNumberList,ExtList}, DoTag) when is_atom(Val) ->
end;
encode_enumerated(C, Val, NamedNumberList, DoTag) when is_atom(Val) ->
- case lists:keysearch(Val, 1, NamedNumberList) of
- {value, {_, NewVal}} when DoTag == []->
+ case lists:keyfind(Val, 1, NamedNumberList) of
+ {_, NewVal} when DoTag =:= [] ->
{EncVal,Len} = encode_integer(C,NewVal),
dotag_universal(?N_ENUMERATED,EncVal,Len);
- {value, {_, NewVal}} ->
+ {_, NewVal} ->
dotag(DoTag, ?N_ENUMERATED, encode_integer(C, NewVal));
_ ->
exit({error,{asn1, {enumerated_not_in_range, Val}}})
@@ -874,8 +859,8 @@ decode_enumerated_notag(Buffer, Range, NNList, Tags, OptOrMand) ->
decode_enumerated1(Val, NamedNumberList) ->
%% it must be a named integer
- case lists:keysearch(Val, 2, NamedNumberList) of
- {value,{NamedVal, _}} ->
+ case lists:keyfind(Val, 2, NamedNumberList) of
+ {NamedVal, _} ->
NamedVal;
_ ->
{asn1_enum,Val}
@@ -1220,32 +1205,32 @@ encode_bin_bit_string(C,{Unused,BinBits},_NamedBitList,DoTag)->
remove_unused_then_dotag(DoTag,StringType,Unused,BinBits) ->
case Unused of
- 0 when (size(BinBits) == 0),DoTag==[] ->
+ 0 when (byte_size(BinBits) =:= 0), DoTag =:= [] ->
%% time optimization of next case
{[StringType,1,0],3};
- 0 when (size(BinBits) == 0) ->
+ 0 when (byte_size(BinBits) =:= 0) ->
dotag(DoTag,StringType,{<<0>>,1});
- 0 when DoTag==[]-> % time optimization of next case
+ 0 when DoTag =:= [] -> % time optimization of next case
dotag_universal(StringType,[Unused|[BinBits]],size(BinBits)+1);
% {LenEnc,Len} = encode_legth(size(BinBits)+1),
% {[StringType,LenEnc,[Unused|BinBits]],size(BinBits)+1+Len+1};
0 ->
dotag(DoTag,StringType,<<Unused,BinBits/binary>>);
- Num when DoTag == [] -> % time optimization of next case
- N = (size(BinBits)-1),
+ Num when DoTag =:= [] -> % time optimization of next case
+ N = byte_size(BinBits) - 1,
<<BBits:N/binary,LastByte>> = BinBits,
dotag_universal(StringType,
[Unused,BBits,(LastByte bsr Num) bsl Num],
- size(BinBits)+1);
+ byte_size(BinBits) + 1);
% {LenEnc,Len} = encode_legth(size(BinBits)+1),
% {[StringType,LenEnc,[Unused,BBits,(LastByte bsr Num) bsl Num],
% 1+Len+size(BinBits)+1};
Num ->
- N = (size(BinBits)-1),
+ N = byte_size(BinBits) - 1,
<<BBits:N/binary,LastByte>> = BinBits,
dotag(DoTag,StringType,{[Unused,binary_to_list(BBits) ++
[(LastByte bsr Num) bsl Num]],
- 1+size(BinBits)})
+ byte_size(BinBits) + 1})
end.
@@ -1291,8 +1276,8 @@ encode_bit_string_named(C, [FirstVal | RestVal], NamedBitList, DoTag) ->
get_all_bitposes([{bit,ValPos}|Rest], NamedBitList, Ack) ->
get_all_bitposes(Rest, NamedBitList, [ValPos | Ack ]);
get_all_bitposes([Val | Rest], NamedBitList, Ack) when is_atom(Val) ->
- case lists:keysearch(Val, 1, NamedBitList) of
- {value, {_ValName, ValPos}} ->
+ case lists:keyfind(Val, 1, NamedBitList) of
+ {_ValName, ValPos} ->
get_all_bitposes(Rest, NamedBitList, [ValPos | Ack]);
_ ->
exit({error,{asn1, {bitstring_namedbit, Val}}})
@@ -1320,10 +1305,6 @@ make_and_set_list(Len, [], XPos) ->
[0 | make_and_set_list(Len - 1, [], XPos + 1)].
-
-
-
-
%%=================================================================
%% Encode bit string for lists of ones and zeroes
%%=================================================================
@@ -1342,7 +1323,7 @@ encode_bit_string_bits(C, BitListVal, _NamedBitList, DoTag) when is_list(BitList
encode_constr_bit_str_bits(Constr,BitListVal,DoTag);
Size ->
case length(BitListVal) of
- BitSize when BitSize == Size ->
+ BitSize when BitSize =:= Size ->
encode_bitstring(BitListVal);
BitSize when BitSize < Size ->
PaddedList =
@@ -1399,7 +1380,7 @@ encode_constr_bit_str_bits({Min,Max},BitListVal,_DoTag) ->
%% as the most significant elements followed by padded zero elements
pad_bit_list(Size,BitListVal) ->
Tail = lists:duplicate(Size,0),
- lists:append(BitListVal,Tail).
+ BitListVal ++ Tail.
%%=================================================================
%% Do the actual encoding
@@ -1513,7 +1494,6 @@ decode_bitstring2(Len, Unused,
%% Decode the bitlist to names
%%----------------------------------------
-
decode_bitstring_NNL(BitList,NamedNumberList) ->
decode_bitstring_NNL(BitList,NamedNumberList,0,[]).
@@ -1523,15 +1503,15 @@ decode_bitstring_NNL([],_,_No,Result) ->
decode_bitstring_NNL([B|BitList],[{Name,No}|NamedNumberList],No,Result) ->
if
- B == 0 ->
+ B =:= 0 ->
decode_bitstring_NNL(BitList,NamedNumberList,No+1,Result);
true ->
decode_bitstring_NNL(BitList,NamedNumberList,No+1,[Name|Result])
end;
decode_bitstring_NNL([1|BitList],NamedNumberList,No,Result) ->
- decode_bitstring_NNL(BitList,NamedNumberList,No+1,[{bit,No}|Result]);
+ decode_bitstring_NNL(BitList,NamedNumberList,No+1,[{bit,No}|Result]);
decode_bitstring_NNL([0|BitList],NamedNumberList,No,Result) ->
- decode_bitstring_NNL(BitList,NamedNumberList,No+1,Result).
+ decode_bitstring_NNL(BitList,NamedNumberList,No+1,Result).
%%============================================================================
@@ -1542,18 +1522,18 @@ decode_bitstring_NNL([0|BitList],NamedNumberList,No,Result) ->
%% the function does not check this because it takes to much time
%%============================================================================
encode_octet_string(_C, OctetList, []) when is_binary(OctetList) ->
- dotag_universal(?N_OCTET_STRING,OctetList,size(OctetList));
+ dotag_universal(?N_OCTET_STRING,OctetList,byte_size(OctetList));
encode_octet_string(_C, OctetList, DoTag) when is_binary(OctetList) ->
- dotag(DoTag, ?N_OCTET_STRING, {OctetList,size(OctetList)});
+ dotag(DoTag, ?N_OCTET_STRING, {OctetList,byte_size(OctetList)});
encode_octet_string(_C, OctetList, DoTag) when is_list(OctetList) ->
case length(OctetList) of
- Len when DoTag == [] ->
+ Len when DoTag =:= [] ->
dotag_universal(?N_OCTET_STRING,OctetList,Len);
Len ->
dotag(DoTag, ?N_OCTET_STRING, {OctetList,Len})
end;
-% encode_octet_string(C, OctetList, DoTag) when is_list(OctetList) ->
-% dotag(DoTag, ?N_OCTET_STRING, {OctetList,length(OctetList)});
+%% encode_octet_string(C, OctetList, DoTag) when is_list(OctetList) ->
+%% dotag(DoTag, ?N_OCTET_STRING, {OctetList,length(OctetList)});
encode_octet_string(C, {Name,OctetList}, DoTag) when is_atom(Name) ->
encode_octet_string(C, OctetList, DoTag).
@@ -1565,7 +1545,7 @@ encode_octet_string(C, {Name,OctetList}, DoTag) when is_atom(Name) ->
%% Octet string is decoded as a restricted string
%%============================================================================
decode_octet_string(Buffer, Range, Tags, TotalLen, OptOrMand) ->
-% NewTags = new_tags(HasTag,#tag{class=?UNIVERSAL,number=?N_OCTET_STRING}),
+%% NewTags = new_tags(HasTag,#tag{class=?UNIVERSAL,number=?N_OCTET_STRING}),
decode_restricted_string(Buffer, Range, ?N_OCTET_STRING,
Tags, TotalLen, [], OptOrMand,old).
@@ -1753,17 +1733,17 @@ decode_relative_oid_notag(Buffer, Tags, OptOrMand) ->
%%============================================================================
encode_restricted_string(_C, OctetList, StringType, [])
when is_binary(OctetList) ->
- dotag_universal(StringType,OctetList,size(OctetList));
+ dotag_universal(StringType, OctetList, byte_size(OctetList));
encode_restricted_string(_C, OctetList, StringType, DoTag)
when is_binary(OctetList) ->
- dotag(DoTag, StringType, {OctetList, size(OctetList)});
+ dotag(DoTag, StringType, {OctetList, byte_size(OctetList)});
encode_restricted_string(_C, OctetList, StringType, [])
when is_list(OctetList) ->
- dotag_universal(StringType,OctetList,length(OctetList));
+ dotag_universal(StringType, OctetList, length(OctetList));
encode_restricted_string(_C, OctetList, StringType, DoTag)
when is_list(OctetList) ->
dotag(DoTag, StringType, {OctetList, length(OctetList)});
-encode_restricted_string(C,{Name,OctetL},StringType,DoTag) when is_atom(Name)->
+encode_restricted_string(C,{Name,OctetL},StringType,DoTag) when is_atom(Name) ->
encode_restricted_string(C, OctetL, StringType, DoTag).
%%============================================================================
@@ -1793,23 +1773,21 @@ decode_restricted_string_tag(Buffer, Range, StringType, TagsIn, LenIn, NNList, O
LenIn, NNList, OptOrMand, BinOrOld).
-
-
check_and_convert_restricted_string(Val,StringType,Range,NamedNumberList,_BinOrOld) ->
{StrLen,NewVal} = case StringType of
- ?N_BIT_STRING when NamedNumberList /= [] ->
+ ?N_BIT_STRING when NamedNumberList =/= [] ->
{no_check,Val};
?N_BIT_STRING when is_list(Val) ->
{length(Val),Val};
?N_BIT_STRING when is_tuple(Val) ->
{(size(element(2,Val))*8) - element(1,Val),Val};
_ when is_binary(Val) ->
- {size(Val),binary_to_list(Val)};
+ {byte_size(Val),binary_to_list(Val)};
_ when is_list(Val) ->
{length(Val), Val}
end,
case Range of
- _ when StrLen == no_check ->
+ _ when StrLen =:= no_check ->
NewVal;
[] -> % No length constraint
NewVal;
@@ -1832,7 +1810,6 @@ check_and_convert_restricted_string(Val,StringType,Range,NamedNumberList,_BinOrO
NewVal
end.
-
%%=============================================================================
%% Common routines for several string types including bit string
%% handles indefinite length
@@ -1840,7 +1817,7 @@ check_and_convert_restricted_string(Val,StringType,Range,NamedNumberList,_BinOrO
decode_restricted_string_notag(Buffer, _Range, StringType, TagsIn,
- _, NamedNumberList, OptOrMand,BinOrOld) ->
+ _, NamedNumberList, OptOrMand, BinOrOld) ->
%%-----------------------------------------------------------
%% Get inner (the implicit tag or no tag) and
%% outer (the explicit tag) lengths.
@@ -1891,7 +1868,7 @@ decode_restricted_parts(Buffer, RestBytes, [], StringType, RestTags, Len, NNList
{concat_bit_binaries(AccVal, Val), AccRb+Rb};
_ when is_binary(Val),is_binary(AccVal) ->
{<<AccVal/binary,Val/binary>>,AccRb+Rb};
- _ when is_binary(Val), AccVal==[] ->
+ _ when is_binary(Val), AccVal =:= [] ->
{Val,AccRb+Rb};
_ ->
{AccVal++Val, AccRb+Rb}
@@ -1977,16 +1954,14 @@ mk_universal_string([A,B,C,D|T],Acc) ->
%% encode UTF8 string
%%============================================================================
encode_UTF8_string(_,UTF8String,[]) when is_binary(UTF8String) ->
- dotag_universal(?N_UTF8String,UTF8String,size(UTF8String));
+ dotag_universal(?N_UTF8String,UTF8String,byte_size(UTF8String));
encode_UTF8_string(_,UTF8String,DoTag) when is_binary(UTF8String) ->
- dotag(DoTag,?N_UTF8String,{UTF8String,size(UTF8String)});
+ dotag(DoTag,?N_UTF8String,{UTF8String,byte_size(UTF8String)});
encode_UTF8_string(_,UTF8String,[]) ->
dotag_universal(?N_UTF8String,UTF8String,length(UTF8String));
encode_UTF8_string(_,UTF8String,DoTag) ->
dotag(DoTag,?N_UTF8String,{UTF8String,length(UTF8String)}).
-
-
%%============================================================================
%% decode UTF8 string
%%============================================================================
@@ -2016,7 +1991,7 @@ decode_UTF8_string_notag(Buffer, Tags, OptOrMand) ->
%% encode BMP string
%%============================================================================
-encode_BMP_string(C, {Name,BMPString}, DoTag) when is_atom(Name)->
+encode_BMP_string(C, {Name,BMPString}, DoTag) when is_atom(Name) ->
encode_BMP_string(C, BMPString, DoTag);
encode_BMP_string(_C, BMPString, []) ->
OctetList = mk_BMP_list(BMPString),
@@ -2464,16 +2439,16 @@ concat_bit_binaries({U1,B1},{U2,B2}) ->
S2 = (size(B2) * 8) - U2,
PadBits = 8 - ((S1+S2) rem 8),
{PadBits, <<B1:S1/binary-unit:1,B2:S2/binary-unit:1,0:PadBits>>};
-concat_bit_binaries(L1,L2) when is_list(L1),is_list(L2) ->
+concat_bit_binaries(L1,L2) when is_list(L1), is_list(L2) ->
%% this case occur when decoding with NNL
L1 ++ L2.
get_constraint(C,Key) ->
- case lists:keysearch(Key,1,C) of
+ case lists:keyfind(Key,1,C) of
false ->
no;
- {value,{_,V}} ->
+ {_, V} ->
V
end.
@@ -2484,7 +2459,7 @@ get_constraint(C,Key) ->
new_tags([],LastTag) ->
[LastTag];
-new_tags(Tags=[#tag{type='IMPLICIT'}],_LastTag) ->
+new_tags(Tags = [#tag{type='IMPLICIT'}],_LastTag) ->
Tags;
new_tags([T1 = #tag{type='IMPLICIT'},#tag{type=T2Type}|Rest],LastTag) ->
new_tags([T1#tag{type=T2Type}|Rest],LastTag);
diff --git a/lib/asn1/test/External.hrl b/lib/asn1/test/External.hrl
new file mode 100644
index 0000000000..8818fac488
--- /dev/null
+++ b/lib/asn1/test/External.hrl
@@ -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%
+%%
+%%
+%% Generated by the Erlang ASN.1 compiler version:0.8.1
+%% Purpose: Erlang record definitions for each named and unnamed
+%% SEQUENCE and SET in module External
+
+-record('XSeq1',{bool1, int1, seq1}).
+-record('XSeqIn',{boolIn, intIn}).
+-record('XSet1',{bool1, int1, set1}).
+-record('XSetIn',{boolIn, intIn}).
+-record('XSetExt1',{asn1_EXT}).
+-record('XSetExt2',{bool, int, asn1_EXT}).
+-record('XSetExt3',{asn1_EXT, bool, int}).
+-record('XSetExt4',{bool, asn1_EXT, int}).
+-record('XSeqExt1',{asn1_EXT}).
+-record('XSeqExt2',{bool, int, asn1_EXT}).
+-record('XSeqExt3',{asn1_EXT, bool, int}).
+-record('XSeqExt4',{bool, asn1_EXT, int}).
+-record('XSetNT',{os, bool}).
+-record('XSetImp',{os, bool}).
+-record('XSetExp',{os, bool}).
+-record('XSeqNT',{os, bool}).
+-record('XSeqImp',{os, bool}).
+-record('XSeqExp',{os, bool}).
+
diff --git a/lib/asn1/test/Makefile b/lib/asn1/test/Makefile
new file mode 100644
index 0000000000..b065db7de8
--- /dev/null
+++ b/lib/asn1/test/Makefile
@@ -0,0 +1,205 @@
+#
+# %CopyrightBegin%
+#
+# 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%
+#
+#
+include $(ERL_TOP)/make/target.mk
+include $(ERL_TOP)/make/$(TARGET)/otp.mk
+
+# ----------------------------------------------------
+# Target Specs
+# ----------------------------------------------------
+
+MODULES= \
+ h323test \
+ choice_extension \
+ ber_decode_error \
+ testExternal \
+ testPrim \
+ testPrimStrings \
+ testCompactBitString \
+ testPrimExternal \
+ testChoPrim \
+ testChoExtension \
+ testChoExternal \
+ testChoOptional \
+ testChoOptionalImplicitTag \
+ testChoRecursive \
+ testChoTypeRefCho \
+ testChoTypeRefPrim \
+ testChoTypeRefSeq \
+ testChoTypeRefSet \
+ testConstraints \
+ testDef \
+ testOpt \
+ testSeqDefault \
+ testSeqExtension \
+ testSeqExternal \
+ testSeqOptional \
+ testSeq2738 \
+ testSeqPrim \
+ testSeqTag \
+ testSeqTypeRefCho \
+ testSeqTypeRefPrim \
+ testSeqTypeRefSeq \
+ testSeqTypeRefSet \
+ testSeqIndefinite \
+ testSeqOf \
+ testSeqOfIndefinite \
+ testSeqOfCho \
+ testSeqOfExternal \
+ testSeqOfTag \
+ testSetDefault \
+ testSetExtension \
+ testSetExternal \
+ testSetOptional \
+ testSetPrim \
+ testSetTag \
+ testSetTypeRefCho \
+ testSetTypeRefPrim \
+ testSetTypeRefSeq \
+ testSetTypeRefSet \
+ testSetIndefinite \
+ testChoiceIndefinite \
+ testSetOf \
+ testSetOfCho \
+ testSetOfExternal \
+ testSetOfTag \
+ testEnumExt \
+ testInfObjectClass \
+ testInfObj \
+ testParameterizedInfObj \
+ testMergeCompile \
+ testDeepTConstr \
+ testTimer \
+ testRANAP \
+ testMegaco \
+ testMvrasn6 \
+ testSeqSetDefaultVal \
+ testParamBasic \
+ testContextSwitchingTypes \
+ testTypeValueNotation \
+ testOpenTypeImplicitTag \
+ testROSE \
+ testINSTANCE_OF \
+ test_partial_incomplete_decode \
+ testDER \
+ test_selective_decode \
+ test_special_decode_performance \
+ testTCAP \
+ testSSLspecs \
+ test_driver_load \
+ testSelectionTypes \
+ test_undecoded_rest \
+ test_inline \
+ testTcapsystem \
+ testNBAPsystem \
+ test_bad_values \
+ test_compile_options \
+ testDoubleEllipses \
+ test_modified_x420 \
+ testX420 \
+ test_x691 \
+ asn1_test_lib \
+ asn1_app_test \
+ asn1_appup_test \
+ asn1_wrapper \
+ asn1_SUITE \
+ asn1_bin_SUITE \
+ asn1_bin_v2_SUITE
+
+SUITE= asn1_SUITE.erl
+SUITE_BIN= asn1_bin_SUITE.erl
+SUITE_BIN_V2= asn1_bin_v2_SUITE.erl
+SUITE_SRC= asn1_SUITE.erl.src
+SUITE_BIN_SRC= asn1_bin_SUITE.erl.src
+SUITE_BIN_V2_SRC= asn1_bin_SUITE.erl.src
+
+ERL_FILES= $(MODULES:%=%.erl)
+
+HRL_FILES= External.hrl
+
+TARGET_FILES= $(MODULES:%=$(EBIN)/%.$(EMULATOR))
+
+INSTALL_PROGS= $(TARGET_FILES)
+
+# ----------------------------------------------------
+# Release directory specification
+# ----------------------------------------------------
+RELSYSDIR = $(RELEASE_PATH)/asn1_test
+
+# ----------------------------------------------------
+# FLAGS
+# ----------------------------------------------------
+ERL_COMPILE_FLAGS += -I$(ERL_TOP)/lib/test_server/include \
+ -I$(ERL_TOP)/lib/kernel/include
+
+EBIN = .
+
+# ----------------------------------------------------
+# Targets
+# ----------------------------------------------------
+
+tests debug opt: $(TARGET_FILES) $(SUITE) $(SUITE_BIN) $(SUITE_BIN_V2)
+
+clean:
+ rm -f $(TARGET_FILES) $(SUITE) $(SUITE_BIN) $(SUITE_BIN_V2)
+ rm -f core
+
+docs:
+
+#-----------------------------------------------------
+# Special Targets
+#-----------------------------------------------------
+$(SUITE): $(SUITE_SRC)
+ sed -e 's;%BIN%;;' -e 's;%PER%;per;' -e 's;%BER%;ber;' $< > $@
+ cat asn1_common_SUITE.erl.src >> $@
+ cat asn1_particular_SUITE.erl.src >> $@
+
+
+$(SUITE_BIN): $(SUITE_SRC)
+ sed -e 's;%BIN%;bin_;' -e 's;%PER%;per_bin;' -e 's;%BER%;ber_bin;' $< > $@
+ echo "common() -> []." >> $@
+ cat asn1_bin_particular_SUITE.erl.src >> $@
+
+$(SUITE_BIN_V2): $(SUITE_SRC)
+ sed -e 's;%BIN%;bin_v2_;' -e 's;%PER%;per_bin;' -e 's;%BER%;ber_bin_v2;' $< > $@
+ echo "common() -> []." >> $@
+ cat asn1_bin_v2_particular_SUITE.erl.src >> $@
+
+# ----------------------------------------------------
+# Release Target
+# ----------------------------------------------------
+include $(ERL_TOP)/make/otp_release_targets.mk
+
+release_spec: opt
+
+release_tests_spec: opt
+ $(INSTALL_DIR) $(RELSYSDIR)
+ $(INSTALL_DIR) $(RELSYSDIR)/asn1_SUITE_data
+ $(INSTALL_DIR) $(RELSYSDIR)/asn1_bin_SUITE_data
+ $(INSTALL_DIR) $(RELSYSDIR)/asn1_bin_v2_SUITE_data
+ $(INSTALL_DATA) $(ERL_FILES) $(HRL_FILES) $(RELSYSDIR)
+ $(INSTALL_DATA) asn1.spec $(INSTALL_PROGS) $(RELSYSDIR)
+ chmod -f -R u+w $(RELSYSDIR)
+ cd asn1_SUITE_data; tar cfh $(RELSYSDIR)/asn1_SUITE_data.tar *
+ cd $(RELSYSDIR)/asn1_SUITE_data; tar xf $(RELSYSDIR)/asn1_SUITE_data.tar
+ cd $(RELSYSDIR)/asn1_bin_SUITE_data; tar xf $(RELSYSDIR)/asn1_SUITE_data.tar
+ cd $(RELSYSDIR)/asn1_bin_v2_SUITE_data; tar xf $(RELSYSDIR)/asn1_SUITE_data.tar
+ rm $(RELSYSDIR)/asn1_SUITE_data.tar
+
+release_docs_spec:
diff --git a/lib/asn1/test/asn1.spec b/lib/asn1/test/asn1.spec
new file mode 100644
index 0000000000..6d9ae924fa
--- /dev/null
+++ b/lib/asn1/test/asn1.spec
@@ -0,0 +1,3 @@
+{topcase, {dir, "../asn1_test"}}.
+
+
diff --git a/lib/asn1/test/asn1_SUITE.erl.src b/lib/asn1/test/asn1_SUITE.erl.src
new file mode 100644
index 0000000000..2cb059fa4e
--- /dev/null
+++ b/lib/asn1/test/asn1_SUITE.erl.src
@@ -0,0 +1,2377 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 2001-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%
+%%
+%%
+%%% Purpose : Test suite for the ASN.1 application
+
+-module(asn1_%BIN%SUITE).
+-define(PER,'%PER%').
+-define(BER,'%BER%').
+-define(ber_driver(Erule,Func),
+ case Erule of
+ ber_bin_v2 ->
+ Func;
+ _ -> ok
+ end).
+-define(per_optimize(Erule),
+ case Erule of
+ ber_bin_v2 ->[optimize];
+ _ -> []
+ end).
+-define(per_bit_opt(FuncCall),
+ case ?BER of
+ ber_bin_v2 -> FuncCall;
+% _ -> {skip,"only for bit optimized per_bin"}
+ _ -> ok
+ end).
+-define(uper_bin(FuncCall),
+ case ?PER of
+ per -> FuncCall;
+ _ -> ok
+ end).
+
+-compile(export_all).
+%%-export([Function/Arity, ...]).
+
+-include("test_server.hrl").
+
+%% records used by test-case default
+-record('Def1',{
+bool0, bool1 = asn1_DEFAULT, bool2 = asn1_DEFAULT, bool3 = asn1_DEFAULT}).
+
+%-record('Def2',{
+%bool10, bool11 = asn1_DEFAULT, bool12 = asn1_DEFAULT, bool13}).
+
+%-record('Def3',{
+%bool30 = asn1_DEFAULT, bool31 = asn1_DEFAULT, bool32 = asn1_DEFAULT, bool33 = asn1_DEFAULT}).
+
+
+
+all(suite) -> [compile,parse,default_per,default_ber,default_per_opt,per,
+ ber,testPrim,
+ testPrimStrings, testPrimExternal, testChoPrim,
+ testChoExtension, testChoExternal, testChoOptional,
+ testChoOptionalImplicitTag, testChoRecursive,
+ testChoTypeRefCho, testChoTypeRefPrim, testChoTypeRefSeq,
+ testChoTypeRefSet, testDef, testOpt, testSeqDefault,
+ testSeqExtension, testSeqExternal, testSeqOptional,
+ testSeqPrim, testSeqTag, testSeqTypeRefCho,
+ testSeqTypeRefPrim, testSeqTypeRefSeq, testSeqTypeRefSet,
+ testSeqOf, testSeqOfIndefinite, testSeqOfCho,
+ testSeqOfExternal, testSetDefault, testSetExtension,
+ testExtensionAdditionGroup,
+ testSetExternal, testSeqOfTag, testSetOptional, testSetPrim,
+ testSetTag, testSetTypeRefCho, testSetTypeRefPrim,
+ testSetTypeRefSeq, testSetTypeRefSet, testSetOf, testSetOfCho,
+ testSetOfExternal, testSetOfTag, testEnumExt, value_test,
+ testSeq2738, constructed, ber_decode_error,
+ h323test, testSeqIndefinite, testSetIndefinite,
+ testChoiceIndefinite,
+ per_GeneralString, per_open_type, testInfObjectClass,
+ testParameterizedInfObj, testMergeCompile, testobj,
+ testDeepTConstr, testConstraints,
+ testInvokeMod, testExport, testImport, testCompactBitString,
+ testMegaco, testParamBasic, testMvrasn6,
+ testContextSwitchingTypes, testTypeValueNotation,
+ testOpenTypeImplicitTag,duplicate_tags,rtUI,testROSE,
+ testINSTANCE_OF,testTCAP,testDER,specialized_decodes,
+ special_decode_performance,test_driver_load,
+ test_ParamTypeInfObj, test_WS_ParamClass,
+ test_Defed_ObjectIdentifier, testSelectionType,
+ testSSLspecs, testNortel,test_undecoded_rest,
+ test_inline, testTcapsystem, testNBAPsystem,
+ test_compile_options,testDoubleEllipses, test_modified_x420,
+ testX420, test_x691,ticket_6143, testExtensionAdditionGroup
+ ] ++ common() ++ particular().
+
+%all(suite) -> [test_inline,testNBAPsystem,test_compile_options,ticket_6143].
+
+option_tests(suite) ->
+ [test_compile_options,ticket_6143].
+
+infobj(suite) ->
+ [testInfObjectClass, testParameterizedInfObj, testMergeCompile,
+ testobj, testDeepTConstr].
+
+performance(suite) ->
+ [testTimer_ber, testTimer_ber_opt_driver,
+ testTimer_per, testTimer_per_opt, testTimer_uper_bin].
+
+bugs(suite) ->
+ [test_ParamTypeInfObj, test_WS_ParamClass,test_Defed_ObjectIdentifier].
+
+init_per_testcase(Func,Config) ->
+ %%?line test_server:format("Func: ~p~n",[Func]),
+ ?line {ok, _} = file:read_file_info(filename:join([?config(priv_dir,Config)])),
+ ?line code:add_patha(?config(priv_dir,Config)),
+ Dog=
+ case Func of
+ testX420 ->
+ test_server:timetrap({minutes,60}); % 60 minutes
+ _ ->
+ test_server:timetrap({minutes,30}) % 60 minutes
+ end,
+%% Dog=test_server:timetrap(1800000), % 30 minutes
+ [{watchdog, Dog}|Config].
+
+fin_per_testcase(_Func,Config) ->
+ Dog=?config(watchdog, Config),
+ test_server:timetrap_cancel(Dog).
+
+
+testPrim(suite) -> [];
+testPrim(Config) ->
+ ?line testPrim:compile(Config,?BER,[]),
+ ?line testPrim_cases(?BER),
+ ?line ?ber_driver(?BER,testPrim:compile(Config,?BER,[driver])),
+ ?line ?ber_driver(?BER,testPrim_cases(?BER)),
+ ?line testPrim:compile(Config,?PER,[]),
+ ?line testPrim_cases(?PER),
+ ?line ?per_bit_opt(testPrim:compile(Config,?PER,[optimize])),
+ ?line ?per_bit_opt(testPrim_cases(?PER)),
+ ?line ?uper_bin(testPrim:compile(Config,uper_bin,[])),
+ ?line ?uper_bin(testPrim_cases(uper_bin)),
+ ?line testPrim:compile(Config,?PER,[optimize]),
+ ?line testPrim_cases(?PER).
+
+testPrim_cases(Rules) ->
+ ?line testPrim:bool(Rules),
+ ?line testPrim:int(Rules),
+ ?line testPrim:enum(Rules),
+ ?line testPrim:obj_id(Rules),
+ ?line testPrim:rel_oid(Rules),
+ ?line testPrim:null(Rules),
+ ?line testPrim:real(Rules).
+
+
+testCompactBitString(suite) -> [];
+testCompactBitString(Config) ->
+
+ ?line testCompactBitString:compile(Config,?BER,[compact_bit_string]),
+ ?line testCompactBitString:compact_bit_string(?BER),
+
+ ?line ?ber_driver(?BER,testCompactBitString:compile(Config,?BER,[compact_bit_string,driver])),
+ ?line ?ber_driver(?BER,testCompactBitString:compact_bit_string(?BER)),
+
+ ?line testCompactBitString:compile(Config,?PER,[compact_bit_string]),
+ ?line testCompactBitString:compact_bit_string(?PER),
+ ?line testCompactBitString:bit_string_unnamed(?PER),
+
+ ?line ?per_bit_opt(testCompactBitString:compile(Config,?PER,
+ [compact_bit_string,optimize])),
+ ?line ?per_bit_opt(testCompactBitString:compact_bit_string(?PER)),
+ ?line ?per_bit_opt(testCompactBitString:bit_string_unnamed(?PER)),
+ ?line ?per_bit_opt(testCompactBitString:ticket_7734(?PER)),
+
+ ?line ?uper_bin(testCompactBitString:compile(Config,uper_bin,
+ [compact_bit_string])),
+ ?line ?uper_bin(testCompactBitString:compact_bit_string(uper_bin)),
+ ?line ?uper_bin(testCompactBitString:bit_string_unnamed(uper_bin)),
+
+ ?line testCompactBitString:compile(Config,?PER,[optimize,compact_bit_string]),
+ ?line testCompactBitString:compact_bit_string(?PER),
+ ?line testCompactBitString:bit_string_unnamed(?PER),
+
+ ?line testCompactBitString:otp_4869(?PER).
+
+
+testPrimStrings(suite) -> [];
+testPrimStrings(Config) ->
+
+ ?line testPrimStrings:compile(Config,?BER,[]),
+ ?line testPrimStrings_cases(?BER),
+ ?line testPrimStrings:more_strings(?BER), %% these are not implemented in per yet
+ ?line ?ber_driver(?BER,testPrimStrings:compile(Config,?BER,[driver])),
+ ?line ?ber_driver(?BER,testPrimStrings_cases(?BER)),
+ ?line ?ber_driver(?BER,testPrimStrings:more_strings(?BER)),
+
+ ?line testPrimStrings:compile(Config,?PER,[]),
+ ?line testPrimStrings_cases(?PER),
+
+ ?line ?per_bit_opt(testPrimStrings:compile(Config,?PER,[optimize])),
+ ?line ?per_bit_opt(testPrimStrings_cases(?PER)),
+
+ ?line ?uper_bin(testPrimStrings:compile(Config,uper_bin,[])),
+ ?line ?uper_bin(testPrimStrings_cases(uper_bin)),
+
+ ?line testPrimStrings:compile(Config,?PER,[optimize]),
+ ?line testPrimStrings_cases(?PER).
+
+testPrimStrings_cases(Rules) ->
+ ?line testPrimStrings:bit_string(Rules),
+ ?line testPrimStrings:bit_string_unnamed(Rules),
+ ?line testPrimStrings:octet_string(Rules),
+ ?line testPrimStrings:numeric_string(Rules),
+ ?line testPrimStrings:other_strings(Rules),
+ ?line testPrimStrings:universal_string(Rules),
+ ?line testPrimStrings:bmp_string(Rules),
+ ?line testPrimStrings:times(Rules),
+ ?line testPrimStrings:utf8_string(Rules).
+
+
+
+testPrimExternal(suite) -> [];
+testPrimExternal(Config) ->
+
+ ?line testExternal:compile(Config,?BER,[]),
+ ?line testPrimExternal:compile(Config,?BER,[]),
+ ?line testPrimExternal_cases(?BER),
+
+ ?line ?ber_driver(?BER,testExternal:compile(Config,?BER,[driver])),
+ ?line ?ber_driver(?BER,testPrimExternal:compile(Config,?BER,[driver])),
+ ?line ?ber_driver(?BER,testPrimExternal_cases(?BER)),
+
+ ?line testExternal:compile(Config,?PER,[]),
+ ?line testPrimExternal:compile(Config,?PER,[]),
+ ?line testPrimExternal_cases(?PER),
+
+ ?line ?per_bit_opt(testExternal:compile(Config,?PER,[optimize])),
+ ?line ?per_bit_opt(testPrimExternal:compile(Config,?PER,[optimize])),
+ ?line ?per_bit_opt(testPrimExternal_cases(?PER)),
+
+ ?line ?uper_bin(testExternal:compile(Config,uper_bin,[])),
+ ?line ?uper_bin(testPrimExternal:compile(Config,uper_bin,[])),
+ ?line ?uper_bin(testPrimExternal_cases(uper_bin)),
+
+ ?line testExternal:compile(Config,?PER,[optimize]),
+ ?line testPrimExternal:compile(Config,?PER,[optimize]),
+ ?line testPrimExternal_cases(?PER).
+
+testPrimExternal_cases(Rules) ->
+ ?line testPrimExternal:external(Rules).
+
+
+
+
+testChoPrim(suite) -> [];
+testChoPrim(Config) ->
+
+ ?line testChoPrim:compile(Config,?BER,[]),
+ ?line testChoPrim_cases(?BER),
+
+ ?line ?ber_driver(?BER,testChoPrim:compile(Config,?BER,[driver])),
+ ?line ?ber_driver(?BER,testChoPrim_cases(?BER)),
+
+ ?line testChoPrim:compile(Config,?PER,[]),
+ ?line testChoPrim_cases(?PER),
+
+ ?line ?per_bit_opt(testChoPrim:compile(Config,?PER,[optimize])),
+ ?line ?per_bit_opt(testChoPrim_cases(?PER)),
+
+ ?line ?uper_bin(testChoPrim:compile(Config,uper_bin,[])),
+ ?line ?uper_bin(testChoPrim_cases(uper_bin)),
+
+ ?line testChoPrim:compile(Config,?PER,[optimize]),
+ ?line testChoPrim_cases(?PER).
+
+testChoPrim_cases(Rules) ->
+ ?line testChoPrim:bool(Rules),
+ ?line testChoPrim:int(Rules).
+
+
+
+testChoExtension(suite) -> [];
+testChoExtension(Config) ->
+
+ ?line testChoExtension:compile(Config,?BER,[]),
+ ?line testChoExtension_cases(?BER),
+
+ ?line ?ber_driver(?BER,testChoExtension:compile(Config,?BER,[driver])),
+ ?line ?ber_driver(?BER,testChoExtension_cases(?BER)),
+
+ ?line testChoExtension:compile(Config,?PER,[]),
+ ?line testChoExtension_cases(?PER),
+
+ ?line ?per_bit_opt(testChoExtension:compile(Config,?PER,[optimize])),
+ ?line ?per_bit_opt(testChoExtension_cases(?PER)),
+
+ ?line ?uper_bin(testChoExtension:compile(Config,uper_bin,[])),
+ ?line ?uper_bin(testChoExtension_cases(uper_bin)),
+
+ ?line testChoExtension:compile(Config,?PER,[optimize]),
+ ?line testChoExtension_cases(?PER).
+
+testChoExtension_cases(Rules) ->
+ ?line testChoExtension:extension(Rules).
+
+
+
+testChoExternal(suite) -> [];
+testChoExternal(Config) ->
+
+ ?line testExternal:compile(Config,?BER,[]),
+ ?line testChoExternal:compile(Config,?BER,[]),
+ ?line testChoExternal_cases(?BER),
+
+ ?line ?ber_driver(?BER,testExternal:compile(Config,?BER,[driver])),
+ ?line ?ber_driver(?BER,testChoExternal:compile(Config,?BER,[driver])),
+ ?line ?ber_driver(?BER,testChoExternal_cases(?BER)),
+
+ ?line testExternal:compile(Config,?PER,[]),
+ ?line testChoExternal:compile(Config,?PER,[]),
+ ?line testChoExternal_cases(?PER),
+
+ ?line ?per_bit_opt(testExternal:compile(Config,?PER,[optimize])),
+ ?line ?per_bit_opt(testChoExternal:compile(Config,?PER,[optimize])),
+ ?line ?per_bit_opt(testChoExternal_cases(?PER)),
+
+ ?line ?uper_bin(testExternal:compile(Config,uper_bin,[])),
+ ?line ?uper_bin(testChoExternal:compile(Config,uper_bin,[])),
+ ?line ?uper_bin(testChoExternal_cases(uper_bin)),
+
+ ?line testExternal:compile(Config,?PER,[optimize]),
+ ?line testChoExternal:compile(Config,?PER,[optimize]),
+ ?line testChoExternal_cases(?PER).
+
+
+testChoExternal_cases(Rules) ->
+ ?line testChoExternal:external(Rules).
+
+
+
+testChoOptional(suite) -> [];
+testChoOptional(Config) ->
+
+ ?line testChoOptional:compile(Config,?BER,[]),
+ ?line testChoOptional_cases(?BER),
+
+ ?line ?ber_driver(?BER,testChoOptional:compile(Config,?BER,[driver])),
+ ?line ?ber_driver(?BER,testChoOptional_cases(?BER)),
+
+ ?line testChoOptional:compile(Config,?PER,[]),
+ ?line testChoOptional_cases(?PER),
+
+ ?line ?per_bit_opt(testChoOptional:compile(Config,?PER,[optimize])),
+ ?line ?per_bit_opt(testChoOptional_cases(?PER)),
+
+ ?line ?uper_bin(testChoOptional:compile(Config,uper_bin,[])),
+ ?line ?uper_bin(testChoOptional_cases(uper_bin)),
+
+ ?line testChoOptional:compile(Config,?PER,[optimize]),
+ ?line testChoOptional_cases(?PER).
+
+testChoOptional_cases(Rules) ->
+ ?line testChoOptional:optional(Rules).
+
+testChoOptionalImplicitTag(suite) -> [];
+testChoOptionalImplicitTag(Config) ->
+ %% Only meaningful for ?BER
+ ?line testChoOptionalImplicitTag:compile(Config,?BER),
+ ?line testChoOptionalImplicitTag:optional(?BER).
+
+
+testChoRecursive(suite) -> [];
+testChoRecursive(Config) ->
+
+ ?line testChoRecursive:compile(Config,?BER,[]),
+ ?line testChoRecursive_cases(?BER),
+
+ ?line ?ber_driver(?BER,testChoRecursive:compile(Config,?BER,[driver])),
+ ?line ?ber_driver(?BER,testChoRecursive_cases(?BER)),
+
+ ?line testChoRecursive:compile(Config,?PER,[]),
+ ?line testChoRecursive_cases(?PER),
+
+ ?line ?per_bit_opt(testChoRecursive:compile(Config,?PER,[optimize])),
+ ?line ?per_bit_opt(testChoRecursive_cases(?PER)),
+
+ ?line ?uper_bin(testChoRecursive:compile(Config,uper_bin,[])),
+ ?line ?uper_bin(testChoRecursive_cases(uper_bin)),
+
+ ?line testChoRecursive:compile(Config,?PER,[optimize]),
+ ?line testChoRecursive_cases(?PER).
+
+testChoRecursive_cases(Rules) ->
+ ?line testChoRecursive:recursive(Rules).
+
+
+
+testChoTypeRefCho(suite) -> [];
+testChoTypeRefCho(Config) ->
+
+ ?line testChoTypeRefCho:compile(Config,?BER,[]),
+ ?line testChoTypeRefCho_cases(?BER),
+
+ ?line ?ber_driver(?BER,testChoTypeRefCho:compile(Config,?BER,[driver])),
+ ?line ?ber_driver(?BER,testChoTypeRefCho_cases(?BER)),
+
+ ?line testChoTypeRefCho:compile(Config,?PER,[]),
+ ?line testChoTypeRefCho_cases(?PER),
+
+ ?line ?per_bit_opt(testChoTypeRefCho:compile(Config,?PER,[optimize])),
+ ?line ?per_bit_opt(testChoTypeRefCho_cases(?PER)),
+
+ ?line ?uper_bin(testChoTypeRefCho:compile(Config,uper_bin,[])),
+ ?line ?uper_bin(testChoTypeRefCho_cases(uper_bin)),
+
+ ?line testChoTypeRefCho:compile(Config,?PER,[optimize]),
+ ?line testChoTypeRefCho_cases(?PER).
+
+testChoTypeRefCho_cases(Rules) ->
+ ?line testChoTypeRefCho:choice(Rules).
+
+
+
+testChoTypeRefPrim(suite) -> [];
+testChoTypeRefPrim(Config) ->
+
+ ?line testChoTypeRefPrim:compile(Config,?BER,[]),
+ ?line testChoTypeRefPrim_cases(?BER),
+
+ ?line ?ber_driver(?BER,testChoTypeRefPrim:compile(Config,?BER,[driver])),
+ ?line ?ber_driver(?BER,testChoTypeRefPrim_cases(?BER)),
+
+ ?line testChoTypeRefPrim:compile(Config,?PER,[]),
+ ?line testChoTypeRefPrim_cases(?PER),
+
+ ?line ?per_bit_opt(testChoTypeRefPrim:compile(Config,?PER,[optimize])),
+ ?line ?per_bit_opt(testChoTypeRefPrim_cases(?PER)),
+
+ ?line ?uper_bin(testChoTypeRefPrim:compile(Config,uper_bin,[])),
+ ?line ?uper_bin(testChoTypeRefPrim_cases(uper_bin)),
+
+ ?line testChoTypeRefPrim:compile(Config,?PER,[optimize]),
+ ?line testChoTypeRefPrim_cases(?PER).
+
+testChoTypeRefPrim_cases(Rules) ->
+ ?line testChoTypeRefPrim:prim(Rules).
+
+
+
+testChoTypeRefSeq(suite) -> [];
+testChoTypeRefSeq(Config) ->
+
+ ?line testChoTypeRefSeq:compile(Config,?BER,[]),
+ ?line testChoTypeRefSeq_cases(?BER),
+
+ ?line ?ber_driver(?BER,testChoTypeRefSeq:compile(Config,?BER,[driver])),
+ ?line ?ber_driver(?BER,testChoTypeRefSeq_cases(?BER)),
+
+ ?line testChoTypeRefSeq:compile(Config,?PER,[]),
+ ?line testChoTypeRefSeq_cases(?PER),
+
+ ?line ?per_bit_opt(testChoTypeRefSeq:compile(Config,?PER,[optimize])),
+ ?line ?per_bit_opt(testChoTypeRefSeq_cases(?PER)),
+
+ ?line ?uper_bin(testChoTypeRefSeq:compile(Config,uper_bin,[])),
+ ?line ?uper_bin(testChoTypeRefSeq_cases(uper_bin)),
+
+ ?line testChoTypeRefSeq:compile(Config,?PER,[optimize]),
+ ?line testChoTypeRefSeq_cases(?PER).
+
+testChoTypeRefSeq_cases(Rules) ->
+ ?line testChoTypeRefSeq:seq(Rules).
+
+
+
+testChoTypeRefSet(suite) -> [];
+testChoTypeRefSet(Config) ->
+
+ ?line testChoTypeRefSet:compile(Config,?BER,[]),
+ ?line testChoTypeRefSet_cases(?BER),
+
+ ?line ?ber_driver(?BER,testChoTypeRefSet:compile(Config,?BER,[driver])),
+ ?line ?ber_driver(?BER,testChoTypeRefSet_cases(?BER)),
+
+ ?line testChoTypeRefSet:compile(Config,?PER,[]),
+ ?line testChoTypeRefSet_cases(?PER),
+
+ ?line ?per_bit_opt(testChoTypeRefSet:compile(Config,?PER,[optimize])),
+ ?line ?per_bit_opt(testChoTypeRefSet_cases(?PER)),
+
+ ?line ?uper_bin(testChoTypeRefSet:compile(Config,uper_bin,[])),
+ ?line ?uper_bin(testChoTypeRefSet_cases(uper_bin)),
+
+ ?line testChoTypeRefSet:compile(Config,?PER,[optimize]),
+ ?line testChoTypeRefSet_cases(?PER).
+
+testChoTypeRefSet_cases(Rules) ->
+ ?line testChoTypeRefSet:set(Rules).
+
+
+
+testDef(suite) -> [];
+testDef(Config) ->
+
+ ?line testDef:compile(Config,?BER,[]),
+ ?line testDef_cases(?BER),
+
+ ?line ?ber_driver(?BER,testDef:compile(Config,?BER,[driver])),
+ ?line ?ber_driver(?BER,testDef_cases(?BER)),
+
+ ?line testDef:compile(Config,?PER,[]),
+ ?line testDef_cases(?PER),
+
+ ?line ?per_bit_opt(testDef:compile(Config,?PER,[optimize])),
+ ?line ?per_bit_opt(testDef_cases(?PER)),
+
+ ?line ?uper_bin(testDef:compile(Config,uper_bin,[])),
+ ?line ?uper_bin(testDef_cases(uper_bin)),
+
+ ?line testDef:compile(Config,?PER,[optimize]),
+ ?line testDef_cases(?PER).
+
+testDef_cases(Rules) ->
+ ?line testDef:main(Rules).
+
+
+
+testOpt(suite) -> [];
+testOpt(Config) ->
+
+ ?line testOpt:compile(Config,?BER),
+ ?line testOpt_cases(?BER),
+
+ ?line testOpt:compile(Config,?PER),
+ ?line testOpt_cases(?PER).
+
+testOpt_cases(Rules) ->
+ ?line testOpt:main(Rules).
+
+
+testEnumExt(suite) -> [];
+testEnumExt(Config) ->
+
+ ?line testEnumExt:compile(Config,?BER,[]),
+ ?line testEnumExt:main(?BER),
+
+ ?line ?ber_driver(?BER,testEnumExt:compile(Config,?BER,[driver])),
+ ?line ?ber_driver(?BER,testEnumExt:main(?BER)),
+
+ ?line testEnumExt:compile(Config,?PER,[]),
+ ?line testEnumExt:main(?PER),
+
+ ?line ?per_bit_opt(testEnumExt:compile(Config,?PER,[optimize])),
+ ?line ?per_bit_opt(testEnumExt:main(?PER)),
+
+ ?line ?uper_bin(testEnumExt:compile(Config,uper_bin,[])),
+ ?line ?uper_bin(testEnumExt:main(uper_bin)),
+
+ ?line testEnumExt:compile(Config,?PER,[optimize]),
+ ?line testEnumExt:main(?PER).
+
+testSeqDefault(doc) -> ["Test of OTP-2523 ENUMERATED with extensionmark."];
+testSeqDefault(suite) -> [];
+testSeqDefault(Config) ->
+
+ ?line testSeqDefault:compile(Config,?BER,[]),
+ ?line testSeqDefault_cases(?BER),
+
+ ?line ?ber_driver(?BER,testSeqDefault:compile(Config,?BER,[driver])),
+ ?line ?ber_driver(?BER,testSeqDefault_cases(?BER)),
+
+ ?line testSeqDefault:compile(Config,?PER,[]),
+ ?line testSeqDefault_cases(?PER),
+
+ ?line ?per_bit_opt(testSeqDefault:compile(Config,?PER,[optimize])),
+ ?line ?per_bit_opt(testSeqDefault_cases(?PER)),
+
+ ?line ?uper_bin(testSeqDefault:compile(Config,uper_bin,[])),
+ ?line ?uper_bin(testSeqDefault_cases(uper_bin)),
+
+ ?line testSeqDefault:compile(Config,?PER,[optimize]),
+ ?line testSeqDefault_cases(?PER).
+
+testSeqDefault_cases(Rules) ->
+ ?line testSeqDefault:main(Rules).
+
+
+
+testSeqExtension(suite) -> [];
+testSeqExtension(Config) ->
+
+ ?line testExternal:compile(Config,?BER,[]),
+ ?line testSeqExtension:compile(Config,?BER,[]),
+ ?line testSeqExtension_cases(?BER),
+
+ ?line ?ber_driver(?BER,testExternal:compile(Config,?BER,[driver])),
+ ?line ?ber_driver(?BER,testSeqExtension:compile(Config,?BER,[driver])),
+ ?line ?ber_driver(?BER,testSeqExtension_cases(?BER)).
+
+testSeqExtension_cases(Rules) ->
+ ?line testSeqExtension:main(Rules).
+
+
+
+testSeqExternal(suite) -> [];
+testSeqExternal(Config) ->
+
+ ?line testExternal:compile(Config,?BER,[]),
+ ?line testSeqExternal:compile(Config,?BER,[]),
+ ?line testSeqExternal_cases(?BER),
+
+ ?line ?ber_driver(?BER,testExternal:compile(Config,?BER,[driver])),
+ ?line ?ber_driver(?BER,testSeqExternal:compile(Config,?BER,[driver])),
+ ?line ?ber_driver(?BER,testSeqExternal_cases(?BER)).
+
+testSeqExternal_cases(Rules) ->
+ ?line testSeqExternal:main(Rules).
+
+
+testSeqOptional(suite) -> [];
+testSeqOptional(Config) ->
+
+ ?line testSeqOptional:compile(Config,?BER,[]),
+ ?line testSeqOptional_cases(?BER),
+
+ ?line ?ber_driver(?BER,testSeqOptional:compile(Config,?BER,[driver])),
+ ?line ?ber_driver(?BER,testSeqOptional_cases(?BER)),
+
+ ?line testSeqOptional:compile(Config,?PER,[]),
+ ?line testSeqOptional_cases(?PER),
+
+ ?line ?per_bit_opt(testSeqOptional:compile(Config,?PER,[optimize])),
+ ?line ?per_bit_opt(testSeqOptional_cases(?PER)),
+
+ ?line ?uper_bin(testSeqOptional:compile(Config,uper_bin,[])),
+ ?line ?uper_bin(testSeqOptional_cases(uper_bin)),
+
+ ?line testSeqOptional:compile(Config,?PER,[optimize]),
+ ?line testSeqOptional_cases(?PER).
+
+testSeqOptional_cases(Rules) ->
+ ?line testSeqOptional:main(Rules).
+
+
+
+testSeqPrim(suite) -> [];
+testSeqPrim(Config) ->
+
+ ?line testSeqPrim:compile(Config,?BER,[]),
+ ?line testSeqPrim_cases(?BER),
+
+ ?line ?ber_driver(?BER,testSeqPrim:compile(Config,?BER,[driver])),
+ ?line ?ber_driver(?BER,testSeqPrim_cases(?BER)),
+
+ ?line testSeqPrim:compile(Config,?PER,[]),
+ ?line testSeqPrim_cases(?PER),
+
+ ?line ?per_bit_opt(testSeqPrim:compile(Config,?PER,[optimize])),
+ ?line ?per_bit_opt(testSeqPrim_cases(?PER)),
+
+ ?line ?uper_bin(testSeqPrim:compile(Config,uper_bin,[])),
+ ?line ?uper_bin(testSeqPrim_cases(uper_bin)),
+
+ ?line testSeqPrim:compile(Config,?PER,[optimize]),
+ ?line testSeqPrim_cases(?PER).
+
+testSeqPrim_cases(Rules) ->
+ ?line testSeqPrim:main(Rules).
+
+
+testSeq2738(doc) -> ["Test of OTP-2738 Detect corrupt optional component."];
+testSeq2738(suite) -> [];
+testSeq2738(Config) ->
+
+ ?line testSeq2738:compile(Config,?BER,[]),
+ ?line testSeq2738_cases(?BER),
+
+ ?line ?ber_driver(?BER,testSeq2738:compile(Config,?BER,[driver])),
+ ?line ?ber_driver(?BER,testSeq2738_cases(?BER)),
+
+ ?line testSeq2738:compile(Config,?PER,[]),
+ ?line testSeq2738_cases(?PER),
+
+ ?line ?per_bit_opt(testSeq2738:compile(Config,?PER,[optimize])),
+ ?line ?per_bit_opt(testSeq2738_cases(?PER)),
+
+ ?line ?uper_bin(testSeq2738:compile(Config,uper_bin,[])),
+ ?line ?uper_bin(testSeq2738_cases(uper_bin)),
+
+ ?line testSeq2738:compile(Config,?PER,[optimize]),
+ ?line testSeq2738_cases(?PER).
+
+testSeq2738_cases(Rules) ->
+ ?line testSeq2738:main(Rules).
+
+
+testSeqTag(suite) -> [];
+testSeqTag(Config) ->
+
+ ?line testExternal:compile(Config,?BER,[]),
+ ?line testSeqTag:compile(Config,?BER,[]),
+ ?line testSeqTag_cases(?BER),
+
+ ?line ?ber_driver(?BER,testExternal:compile(Config,?BER,[driver])),
+ ?line ?ber_driver(?BER,testSeqTag:compile(Config,?BER,[driver])),
+ ?line ?ber_driver(?BER,testSeqTag_cases(?BER)),
+
+ ?line testExternal:compile(Config,?PER,[]),
+ ?line testSeqTag:compile(Config,?PER,[]),
+ ?line testSeqTag_cases(?PER),
+
+ ?line ?per_bit_opt(testExternal:compile(Config,?PER,[optimize])),
+ ?line ?per_bit_opt(testSeqTag:compile(Config,?PER,[optimize])),
+ ?line ?per_bit_opt(testSeqTag_cases(?PER)),
+
+ ?line ?uper_bin(testExternal:compile(Config,uper_bin,[])),
+ ?line ?uper_bin(testSeqTag:compile(Config,uper_bin,[])),
+ ?line ?uper_bin(testSeqTag_cases(uper_bin)),
+
+ ?line testExternal:compile(Config,?PER,[optimize]),
+ ?line testSeqTag:compile(Config,?PER,[optimize]),
+ ?line testSeqTag_cases(?PER).
+
+testSeqTag_cases(Rules) ->
+ ?line testSeqTag:main(Rules).
+
+
+
+
+testSeqTypeRefCho(suite) -> [];
+testSeqTypeRefCho(Config) ->
+
+ ?line testSeqTypeRefCho:compile(Config,?BER,[]),
+ ?line testSeqTypeRefCho_cases(?BER),
+
+ ?line ?ber_driver(?BER,testSeqTypeRefCho:compile(Config,?BER,[driver])),
+ ?line ?ber_driver(?BER,testSeqTypeRefCho_cases(?BER)),
+
+ ?line testSeqTypeRefCho:compile(Config,?PER,[]),
+ ?line testSeqTypeRefCho_cases(?PER),
+
+ ?line ?per_bit_opt(testSeqTypeRefCho:compile(Config,?PER,[optimize])),
+ ?line ?per_bit_opt(testSeqTypeRefCho_cases(?PER)),
+
+ ?line ?uper_bin(testSeqTypeRefCho:compile(Config,uper_bin,[])),
+ ?line ?uper_bin(testSeqTypeRefCho_cases(uper_bin)),
+
+ ?line testSeqTypeRefCho:compile(Config,?PER,[optimize]),
+ ?line testSeqTypeRefCho_cases(?PER).
+
+testSeqTypeRefCho_cases(Rules) ->
+ ?line testSeqTypeRefCho:main(Rules).
+
+
+
+testSeqTypeRefPrim(suite) -> [];
+testSeqTypeRefPrim(Config) ->
+
+ ?line testSeqTypeRefPrim:compile(Config,?BER,[]),
+ ?line testSeqTypeRefPrim_cases(?BER),
+
+ ?line ?ber_driver(?BER,testSeqTypeRefPrim:compile(Config,?BER,[driver])),
+ ?line ?ber_driver(?BER,testSeqTypeRefPrim_cases(?BER)),
+
+ ?line testSeqTypeRefPrim:compile(Config,?PER,[]),
+ ?line testSeqTypeRefPrim_cases(?PER),
+
+ ?line ?per_bit_opt(testSeqTypeRefPrim:compile(Config,?PER,[optimize])),
+ ?line ?per_bit_opt(testSeqTypeRefPrim_cases(?PER)),
+
+ ?line ?uper_bin(testSeqTypeRefPrim:compile(Config,uper_bin,[])),
+ ?line ?uper_bin(testSeqTypeRefPrim_cases(uper_bin)),
+
+ ?line testSeqTypeRefPrim:compile(Config,?PER,[optimize]),
+ ?line testSeqTypeRefPrim_cases(?PER).
+
+testSeqTypeRefPrim_cases(Rules) ->
+ ?line testSeqTypeRefPrim:main(Rules).
+
+
+
+testSeqTypeRefSeq(suite) -> [];
+testSeqTypeRefSeq(Config) ->
+
+ ?line testSeqTypeRefSeq:compile(Config,?BER,[]),
+ ?line testSeqTypeRefSeq_cases(?BER),
+
+ ?line ?ber_driver(?BER,testSeqTypeRefSeq:compile(Config,?BER,[driver])),
+ ?line ?ber_driver(?BER,testSeqTypeRefSeq_cases(?BER)),
+
+ ?line testSeqTypeRefSeq:compile(Config,?PER,[]),
+ ?line testSeqTypeRefSeq_cases(?PER),
+
+ ?line ?per_bit_opt(testSeqTypeRefSeq:compile(Config,?PER,[optimize])),
+ ?line ?per_bit_opt(testSeqTypeRefSeq_cases(?PER)),
+
+ ?line ?uper_bin(testSeqTypeRefSeq:compile(Config,uper_bin,[])),
+ ?line ?uper_bin(testSeqTypeRefSeq_cases(uper_bin)),
+
+ ?line testSeqTypeRefSeq:compile(Config,?PER,[optimize]),
+ ?line testSeqTypeRefSeq_cases(?PER).
+
+testSeqTypeRefSeq_cases(Rules) ->
+ ?line testSeqTypeRefSeq:main(Rules).
+
+
+
+testSeqTypeRefSet(suite) -> [];
+testSeqTypeRefSet(Config) ->
+
+ ?line testSeqTypeRefSet:compile(Config,?BER,[]),
+ ?line testSeqTypeRefSet_cases(?BER),
+
+ ?line ?ber_driver(?BER,testSeqTypeRefSet:compile(Config,?BER,[driver])),
+ ?line ?ber_driver(?BER,testSeqTypeRefSet_cases(?BER)),
+
+ ?line testSeqTypeRefSet:compile(Config,?PER,[]),
+ ?line testSeqTypeRefSet_cases(?PER),
+
+ ?line ?per_bit_opt(testSeqTypeRefSet:compile(Config,?PER,[optimize])),
+ ?line ?per_bit_opt(testSeqTypeRefSet_cases(?PER)),
+
+ ?line ?uper_bin(testSeqTypeRefSet:compile(Config,uper_bin,[])),
+ ?line ?uper_bin(testSeqTypeRefSet_cases(uper_bin)),
+
+ ?line testSeqTypeRefSet:compile(Config,?PER,[optimize]),
+ ?line testSeqTypeRefSet_cases(?PER).
+
+testSeqTypeRefSet_cases(Rules) ->
+ ?line testSeqTypeRefSet:main(Rules).
+
+
+
+
+testSeqOf(suite) -> [];
+testSeqOf(Config) ->
+ ?line true = code:add_patha(?config(priv_dir,Config)),
+
+ ?line testSeqOf:compile(Config,?BER,[]),
+ ?line testSeqOf_cases(?BER),
+
+ ?line ?ber_driver(?BER,testSeqOf:compile(Config,?BER,[driver])),
+ ?line ?ber_driver(?BER,testSeqOf_cases(?BER)),
+
+ ?line testSeqOf:compile(Config,?PER,[]),
+ ?line testSeqOf_cases(?PER),
+
+ ?line ?per_bit_opt(testSeqOf:compile(Config,?PER,[optimize])),
+ ?line ?per_bit_opt(testSeqOf_cases(?PER)),
+
+ ?line ?uper_bin(testSeqOf:compile(Config,uper_bin,[])),
+ ?line ?uper_bin(testSeqOf_cases(uper_bin)),
+
+ ?line testSeqOf:compile(Config,?PER,[optimize]),
+ ?line testSeqOf_cases(?PER).
+
+testSeqOf_cases(Rules) ->
+ ?line testSeqOf:main(Rules).
+
+
+
+
+testSeqOfCho(suite) -> [];
+testSeqOfCho(Config) ->
+ ?line true = code:add_patha(?config(priv_dir,Config)),
+
+ ?line testSeqOfCho:compile(Config,?BER,[]),
+ ?line testSeqOfCho_cases(?BER),
+
+ ?line ?ber_driver(?BER,testSeqOfCho:compile(Config,?BER,[driver])),
+ ?line ?ber_driver(?BER,testSeqOfCho_cases(?BER)),
+
+ ?line testSeqOfCho:compile(Config,?PER,[]),
+ ?line testSeqOfCho_cases(?PER),
+
+ ?line ?per_bit_opt(testSeqOfCho:compile(Config,?PER,[optimize])),
+ ?line ?per_bit_opt(testSeqOfCho_cases(?PER)),
+
+ ?line ?uper_bin(testSeqOfCho:compile(Config,uper_bin,[])),
+ ?line ?uper_bin(testSeqOfCho_cases(uper_bin)),
+
+ ?line testSeqOfCho:compile(Config,?PER,[optimize]),
+ ?line testSeqOfCho_cases(?PER).
+
+testSeqOfIndefinite(suite) -> [];
+testSeqOfIndefinite(Config) ->
+ ?line true = code:add_patha(?config(priv_dir,Config)),
+
+ ?line testSeqOfIndefinite:compile(Config,?BER,[]),
+ ?line testSeqOfIndefinite:main(),
+
+ ?line ?ber_driver(?BER,testSeqOfIndefinite:compile(Config,?BER,[driver])),
+ ?line ?ber_driver(?BER,testSeqOfIndefinite:main()).
+
+testSeqOfCho_cases(Rules) ->
+ ?line testSeqOfCho:main(Rules).
+
+
+testSeqOfExternal(suite) -> [];
+testSeqOfExternal(Config) ->
+ ?line true = code:add_patha(?config(priv_dir,Config)),
+
+ ?line testExternal:compile(Config,?BER,[]),
+ ?line testSeqOfExternal:compile(Config,?BER,[]),
+ ?line testSeqOfExternal_cases(?BER),
+
+ ?line ?ber_driver(?BER,testExternal:compile(Config,?BER,[driver])),
+ ?line ?ber_driver(?BER,testSeqOfExternal:compile(Config,?BER,[driver])),
+ ?line ?ber_driver(?BER,testSeqOfExternal_cases(?BER)),
+
+ ?line testExternal:compile(Config,?PER,[]),
+ ?line testSeqOfExternal:compile(Config,?PER,[]),
+ ?line testSeqOfExternal_cases(?PER),
+
+ ?line ?per_bit_opt(testExternal:compile(Config,?PER,[optimize])),
+ ?line ?per_bit_opt(testSeqOfExternal:compile(Config,?PER,[optimize])),
+ ?line ?per_bit_opt(testSeqOfExternal_cases(?PER)),
+
+ ?line ?uper_bin(testExternal:compile(Config,uper_bin,[])),
+ ?line ?uper_bin(testSeqOfExternal:compile(Config,uper_bin,[])),
+ ?line ?uper_bin(testSeqOfExternal_cases(uper_bin)),
+
+ ?line testExternal:compile(Config,?PER,[optimize]),
+ ?line testSeqOfExternal:compile(Config,?PER,[optimize]),
+ ?line testSeqOfExternal_cases(?PER).
+
+testSeqOfExternal_cases(Rules) ->
+ ?line testSeqOfExternal:main(Rules).
+
+
+
+testSeqOfTag(suite) -> [];
+testSeqOfTag(Config) ->
+ ?line true = code:add_patha(?config(priv_dir,Config)),
+
+ ?line testExternal:compile(Config,?BER,[]),
+ ?line testSeqOfTag:compile(Config,?BER,[]),
+ ?line testSeqOfTag_cases(?BER),
+
+ ?line ?ber_driver(?BER,testExternal:compile(Config,?BER,[driver])),
+ ?line ?ber_driver(?BER,testSeqOfTag:compile(Config,?BER,[driver])),
+ ?line ?ber_driver(?BER,testSeqOfTag_cases(?BER)),
+
+ ?line testExternal:compile(Config,?PER,[]),
+ ?line testSeqOfTag:compile(Config,?PER,[]),
+ ?line testSeqOfTag_cases(?PER),
+
+ ?line ?per_bit_opt(testExternal:compile(Config,?PER,[optimize])),
+ ?line ?per_bit_opt(testSeqOfTag:compile(Config,?PER,[optimize])),
+ ?line ?per_bit_opt(testSeqOfTag_cases(?PER)),
+
+ ?line ?uper_bin(testExternal:compile(Config,uper_bin,[])),
+ ?line ?uper_bin(testSeqOfTag:compile(Config,uper_bin,[])),
+ ?line ?uper_bin(testSeqOfTag_cases(uper_bin)),
+
+ ?line testExternal:compile(Config,?PER,[optimize]),
+ ?line testSeqOfTag:compile(Config,?PER,[optimize]),
+ ?line testSeqOfTag_cases(?PER).
+
+testSeqOfTag_cases(Rules) ->
+ ?line testSeqOfTag:main(Rules).
+
+
+
+
+testSetDefault(suite) -> [];
+testSetDefault(Config) ->
+ ?line true = code:add_patha(?config(priv_dir,Config)),
+
+ ?line testSetDefault:compile(Config,?BER,[]),
+ ?line testSetDefault_cases(?BER),
+
+ ?line ?ber_driver(?BER,testSetDefault:compile(Config,?BER,[driver])),
+ ?line ?ber_driver(?BER,testSetDefault_cases(?BER)),
+
+ ?line testSetDefault:compile(Config,?PER,[]),
+ ?line testSetDefault_cases(?PER),
+
+ ?line ?per_bit_opt(testSetDefault:compile(Config,?PER,[optimize])),
+ ?line ?per_bit_opt(testSetDefault_cases(?PER)),
+
+ ?line ?uper_bin(testSetDefault:compile(Config,uper_bin,[])),
+ ?line ?uper_bin(testSetDefault_cases(uper_bin)),
+
+ ?line testSetDefault:compile(Config,?PER,[optimize]),
+ ?line testSetDefault_cases(?PER).
+
+testSetDefault_cases(Rules) ->
+ ?line testSetDefault:main(Rules).
+
+
+testParamBasic(suite) -> [];
+testParamBasic(Config) ->
+ ?line true = code:add_patha(?config(priv_dir,Config)),
+
+ ?line testParamBasic:compile(Config,?BER,[]),
+ ?line testParamBasic_cases(?BER),
+
+ ?line ?ber_driver(?BER,testParamBasic:compile(Config,?BER,[driver])),
+ ?line ?ber_driver(?BER,testParamBasic_cases(?BER)),
+
+ ?line testParamBasic:compile(Config,?PER,[]),
+ ?line testParamBasic_cases(?PER),
+
+ ?line ?per_bit_opt(testParamBasic:compile(Config,?PER,[optimize])),
+ ?line ?per_bit_opt(testParamBasic_cases(?PER)),
+
+ ?line ?uper_bin(testParamBasic:compile(Config,uper_bin,[])),
+ ?line ?uper_bin(testParamBasic_cases(uper_bin)),
+
+ ?line testParamBasic:compile(Config,?PER,[optimize]),
+ ?line testParamBasic_cases(?PER).
+
+
+testParamBasic_cases(Rules) ->
+ ?line testParamBasic:main(Rules).
+
+testSetExtension(suite) -> [];
+testSetExtension(Config) ->
+ ?line true = code:add_patha(?config(priv_dir,Config)),
+
+ ?line testExternal:compile(Config,?BER,[]),
+ ?line testSetExtension:compile(Config,?BER,[]),
+ ?line testSetExtension_cases(?BER),
+
+ ?line ?ber_driver(?BER,testExternal:compile(Config,?BER,[driver])),
+ ?line ?ber_driver(?BER,testSetExtension:compile(Config,?BER,[driver])),
+ ?line ?ber_driver(?BER,testSetExtension_cases(?BER)).
+
+testSetExtension_cases(Rules) ->
+ ?line testSetExtension:main(Rules).
+
+
+testSetExternal(suite) -> [];
+testSetExternal(Config) ->
+ ?line true = code:add_patha(?config(priv_dir,Config)),
+
+ ?line testExternal:compile(Config,?BER,[]),
+ ?line testSetExternal:compile(Config,?BER,[]),
+ ?line testSetExternal_cases(?BER),
+
+ ?line ?ber_driver(?BER,testExternal:compile(Config,?BER,[driver])),
+ ?line ?ber_driver(?BER,testSetExternal:compile(Config,?BER,[driver])),
+ ?line ?ber_driver(?BER,testSetExternal_cases(?BER)).
+
+testSetExternal_cases(Rules) ->
+ ?line testSetExternal:main(Rules).
+
+
+testSetOptional(suite) -> [];
+testSetOptional(Config) ->
+ ?line true = code:add_patha(?config(priv_dir,Config)),
+
+ ?line testSetOptional:compile(Config,?BER,[]),
+ ?line testSetOptional_cases(?BER),
+
+ ?line ?ber_driver(?BER,testSetOptional:compile(Config,?BER,[driver])),
+ ?line ?ber_driver(?BER,testSetOptional_cases(?BER)),
+
+ ?line testSetOptional:compile(Config,?PER,[]),
+ ?line testSetOptional_cases(?PER),
+
+ ?line ?per_bit_opt(testSetOptional:compile(Config,?PER,[optimize])),
+ ?line ?per_bit_opt(testSetOptional_cases(?PER)),
+
+ ?line ?uper_bin(testSetOptional:compile(Config,uper_bin,[])),
+ ?line ?uper_bin(testSetOptional_cases(uper_bin)),
+
+ ?line testSetOptional:compile(Config,?PER,[optimize]),
+ ?line testSetOptional_cases(?PER).
+
+testSetOptional_cases(Rules) ->
+ ?line ok = testSetOptional:ticket_7533(Rules),
+ ?line ok = testSetOptional:main(Rules).
+
+
+
+
+testSetPrim(suite) -> [];
+testSetPrim(Config) ->
+ ?line true = code:add_patha(?config(priv_dir,Config)),
+
+ ?line testSetPrim:compile(Config,?BER,[]),
+ ?line testSetPrim_cases(?BER),
+
+ ?line ?ber_driver(?BER,testSetPrim:compile(Config,?BER,[driver])),
+ ?line ?ber_driver(?BER,testSetPrim_cases(?BER)),
+
+ ?line testSetPrim:compile(Config,?PER,[]),
+ ?line testSetPrim_cases(?PER),
+
+ ?line ?per_bit_opt(testSetPrim:compile(Config,?PER,[optimize])),
+ ?line ?per_bit_opt(testSetPrim_cases(?PER)),
+
+ ?line ?uper_bin(testSetPrim:compile(Config,uper_bin,[])),
+ ?line ?uper_bin(testSetPrim_cases(uper_bin)),
+
+ ?line testSetPrim:compile(Config,?PER,[optimize]),
+ ?line testSetPrim_cases(?PER).
+
+testSetPrim_cases(Rules) ->
+ ?line testSetPrim:main(Rules).
+
+
+
+testSetTag(suite) -> [];
+testSetTag(Config) ->
+ ?line true = code:add_patha(?config(priv_dir,Config)),
+
+ ?line testExternal:compile(Config,?BER,[]),
+ ?line testSetTag:compile(Config,?BER,[]),
+ ?line testSetTag_cases(?BER),
+
+ ?line ?ber_driver(?BER,testExternal:compile(Config,?BER,[driver])),
+ ?line ?ber_driver(?BER,testSetTag:compile(Config,?BER,[driver])),
+ ?line ?ber_driver(?BER,testSetTag_cases(?BER)),
+
+ ?line testExternal:compile(Config,?PER,[]),
+ ?line testSetTag:compile(Config,?PER,[]),
+ ?line testSetTag_cases(?PER),
+
+ ?line ?per_bit_opt(testExternal:compile(Config,?PER,[optimize])),
+ ?line ?per_bit_opt(testSetTag:compile(Config,?PER,[optimize])),
+ ?line ?per_bit_opt(testSetTag_cases(?PER)),
+
+ ?line ?uper_bin(testExternal:compile(Config,uper_bin,[])),
+ ?line ?uper_bin(testSetTag:compile(Config,uper_bin,[])),
+ ?line ?uper_bin(testSetTag_cases(uper_bin)),
+
+ ?line testExternal:compile(Config,?PER,[optimize]),
+ ?line testSetTag:compile(Config,?PER,[optimize]),
+ ?line testSetTag_cases(?PER).
+
+testSetTag_cases(Rules) ->
+ ?line testSetTag:main(Rules).
+
+
+
+testSetTypeRefCho(suite) -> [];
+testSetTypeRefCho(Config) ->
+ ?line true = code:add_patha(?config(priv_dir,Config)),
+
+ ?line testSetTypeRefCho:compile(Config,?BER,[]),
+ ?line testSetTypeRefCho_cases(?BER),
+
+ ?line ?ber_driver(?BER,testSetTypeRefCho:compile(Config,?BER,[driver])),
+ ?line ?ber_driver(?BER,testSetTypeRefCho_cases(?BER)),
+
+ ?line testSetTypeRefCho:compile(Config,?PER,[]),
+ ?line testSetTypeRefCho_cases(?PER),
+
+ ?line ?per_bit_opt(testSetTypeRefCho:compile(Config,?PER,[optimize])),
+ ?line ?per_bit_opt(testSetTypeRefCho_cases(?PER)),
+
+ ?line ?uper_bin(testSetTypeRefCho:compile(Config,uper_bin,[])),
+ ?line ?uper_bin(testSetTypeRefCho_cases(uper_bin)),
+
+ ?line testSetTypeRefCho:compile(Config,?PER,[optimize]),
+ ?line testSetTypeRefCho_cases(?PER).
+
+testSetTypeRefCho_cases(Rules) ->
+ ?line testSetTypeRefCho:main(Rules).
+
+
+
+testSetTypeRefPrim(suite) -> [];
+testSetTypeRefPrim(Config) ->
+ ?line true = code:add_patha(?config(priv_dir,Config)),
+
+ ?line testSetTypeRefPrim:compile(Config,?BER,[]),
+ ?line testSetTypeRefPrim_cases(?BER),
+
+ ?line ?ber_driver(?BER,testSetTypeRefPrim:compile(Config,?BER,[driver])),
+ ?line ?ber_driver(?BER,testSetTypeRefPrim_cases(?BER)),
+
+ ?line testSetTypeRefPrim:compile(Config,?PER,[]),
+ ?line testSetTypeRefPrim_cases(?PER),
+
+ ?line ?per_bit_opt(testSetTypeRefPrim:compile(Config,?PER,[optimize])),
+ ?line ?per_bit_opt(testSetTypeRefPrim_cases(?PER)),
+
+ ?line ?uper_bin(testSetTypeRefPrim:compile(Config,uper_bin,[])),
+ ?line ?uper_bin(testSetTypeRefPrim_cases(uper_bin)),
+
+ ?line testSetTypeRefPrim:compile(Config,?PER,[optimize]),
+ ?line testSetTypeRefPrim_cases(?PER).
+
+testSetTypeRefPrim_cases(Rules) ->
+ ?line testSetTypeRefPrim:main(Rules).
+
+
+
+testSetTypeRefSeq(suite) -> [];
+testSetTypeRefSeq(Config) ->
+ ?line true = code:add_patha(?config(priv_dir,Config)),
+
+ ?line testSetTypeRefSeq:compile(Config,?BER,[]),
+ ?line testSetTypeRefSeq_cases(?BER),
+
+ ?line ?ber_driver(?BER,testSetTypeRefSeq:compile(Config,?BER,[driver])),
+ ?line ?ber_driver(?BER,testSetTypeRefSeq_cases(?BER)),
+
+ ?line testSetTypeRefSeq:compile(Config,?PER,[]),
+ ?line testSetTypeRefSeq_cases(?PER),
+
+ ?line ?per_bit_opt(testSetTypeRefSeq:compile(Config,?PER,[optimize])),
+ ?line ?per_bit_opt(testSetTypeRefSeq_cases(?PER)),
+
+ ?line ?uper_bin(testSetTypeRefSeq:compile(Config,uper_bin,[])),
+ ?line ?uper_bin(testSetTypeRefSeq_cases(uper_bin)),
+
+ ?line testSetTypeRefSeq:compile(Config,?PER,[optimize]),
+ ?line testSetTypeRefSeq_cases(?PER).
+
+testSetTypeRefSeq_cases(Rules) ->
+ ?line testSetTypeRefSeq:main(Rules).
+
+
+
+testSetTypeRefSet(suite) -> [];
+testSetTypeRefSet(Config) ->
+ ?line true = code:add_patha(?config(priv_dir,Config)),
+
+ ?line testSetTypeRefSet:compile(Config,?BER,[]),
+ ?line testSetTypeRefSet_cases(?BER),
+
+ ?line ?ber_driver(?BER,testSetTypeRefSet:compile(Config,?BER,[driver])),
+ ?line ?ber_driver(?BER,testSetTypeRefSet_cases(?BER)),
+
+ ?line testSetTypeRefSet:compile(Config,?PER,[]),
+ ?line testSetTypeRefSet_cases(?PER),
+
+ ?line ?per_bit_opt(testSetTypeRefSet:compile(Config,?PER,[optimize])),
+ ?line ?per_bit_opt(testSetTypeRefSet_cases(?PER)),
+
+ ?line ?uper_bin(testSetTypeRefSet:compile(Config,uper_bin,[])),
+ ?line ?uper_bin(testSetTypeRefSet_cases(uper_bin)),
+
+ ?line testSetTypeRefSet:compile(Config,?PER,[optimize]),
+ ?line testSetTypeRefSet_cases(?PER).
+
+testSetTypeRefSet_cases(Rules) ->
+ ?line testSetTypeRefSet:main(Rules).
+
+
+
+testSetOf(suite) -> [];
+testSetOf(Config) ->
+ ?line true = code:add_patha(?config(priv_dir,Config)),
+
+ ?line testSetOf:compile(Config,?BER,[]),
+ ?line testSetOf_cases(?BER),
+
+ ?line ?ber_driver(?BER,testSetOf:compile(Config,?BER,[driver])),
+ ?line ?ber_driver(?BER,testSetOf_cases(?BER)),
+
+ ?line testSetOf:compile(Config,?PER,[]),
+ ?line testSetOf_cases(?PER),
+
+ ?line ?per_bit_opt(testSetOf:compile(Config,?PER,[optimize])),
+ ?line ?per_bit_opt(testSetOf_cases(?PER)),
+
+ ?line ?uper_bin(testSetOf:compile(Config,uper_bin,[])),
+ ?line ?uper_bin(testSetOf_cases(uper_bin)),
+
+ ?line testSetOf:compile(Config,?PER,[optimize]),
+ ?line testSetOf_cases(?PER).
+
+testSetOf_cases(Rules) ->
+ ?line testSetOf:main(Rules).
+
+
+
+testSetOfCho(suite) -> [];
+testSetOfCho(Config) ->
+ ?line true = code:add_patha(?config(priv_dir,Config)),
+
+ ?line testSetOfCho:compile(Config,?BER,[]),
+ ?line testSetOfCho_cases(?BER),
+
+ ?line ?ber_driver(?BER,testSetOfCho:compile(Config,?BER,[driver])),
+ ?line ?ber_driver(?BER,testSetOfCho_cases(?BER)),
+
+ ?line testSetOfCho:compile(Config,?PER,[]),
+ ?line testSetOfCho_cases(?PER),
+
+ ?line ?per_bit_opt(testSetOfCho:compile(Config,?PER,[optimize])),
+ ?line ?per_bit_opt(testSetOfCho_cases(?PER)),
+
+ ?line ?uper_bin(testSetOfCho:compile(Config,uper_bin,[])),
+ ?line ?uper_bin(testSetOfCho_cases(uper_bin)),
+
+ ?line testSetOfCho:compile(Config,?PER,[optimize]),
+ ?line testSetOfCho_cases(?PER).
+
+testSetOfCho_cases(Rules) ->
+ ?line testSetOfCho:main(Rules).
+
+
+testSetOfExternal(suite) -> [];
+testSetOfExternal(Config) ->
+ ?line true = code:add_patha(?config(priv_dir,Config)),
+
+ ?line testExternal:compile(Config,?BER,[]),
+ ?line testSetOfExternal:compile(Config,?BER,[]),
+ ?line testSetOfExternal_cases(?BER),
+
+ ?line ?ber_driver(?BER,testExternal:compile(Config,?BER,[driver])),
+ ?line ?ber_driver(?BER,testSetOfExternal:compile(Config,?BER,[driver])),
+ ?line ?ber_driver(?BER,testSetOfExternal_cases(?BER)),
+
+ ?line testExternal:compile(Config,?PER,[]),
+ ?line testSetOfExternal:compile(Config,?PER,[]),
+ ?line testSetOfExternal_cases(?PER),
+
+ ?line ?per_bit_opt(testExternal:compile(Config,?PER,[optimize])),
+ ?line ?per_bit_opt(testSetOfExternal:compile(Config,?PER,[optimize])),
+ ?line ?per_bit_opt(testSetOfExternal_cases(?PER)),
+
+ ?line ?uper_bin(testExternal:compile(Config,uper_bin,[])),
+ ?line ?uper_bin(testSetOfExternal:compile(Config,uper_bin,[])),
+ ?line ?uper_bin(testSetOfExternal_cases(uper_bin)),
+
+ ?line testExternal:compile(Config,?PER,[optimize]),
+ ?line testSetOfExternal:compile(Config,?PER,[optimize]),
+ ?line testSetOfExternal_cases(?PER).
+
+testSetOfExternal_cases(Rules) ->
+ ?line testSetOfExternal:main(Rules).
+
+
+
+
+testSetOfTag(suite) -> [];
+testSetOfTag(Config) ->
+ ?line true = code:add_patha(?config(priv_dir,Config)),
+
+ ?line testExternal:compile(Config,?BER,[]),
+ ?line testSetOfTag:compile(Config,?BER,[]),
+ ?line testSetOfTag_cases(?BER),
+
+ ?line ?ber_driver(?BER,testExternal:compile(Config,?BER,[driver])),
+ ?line ?ber_driver(?BER,testSetOfTag:compile(Config,?BER,[driver])),
+ ?line ?ber_driver(?BER,testSetOfTag_cases(?BER)),
+
+ ?line testExternal:compile(Config,?PER,[]),
+ ?line testSetOfTag:compile(Config,?PER,[]),
+ ?line testSetOfTag_cases(?PER),
+
+ ?line ?per_bit_opt(testExternal:compile(Config,?PER,[optimize])),
+ ?line ?per_bit_opt(testSetOfTag:compile(Config,?PER,[optimize])),
+ ?line ?per_bit_opt(testSetOfTag_cases(?PER)),
+
+ ?line ?uper_bin(testExternal:compile(Config,uper_bin,[])),
+ ?line ?uper_bin(testSetOfTag:compile(Config,uper_bin,[])),
+ ?line ?uper_bin(testSetOfTag_cases(uper_bin)),
+
+ ?line testExternal:compile(Config,?PER,[optimize]),
+ ?line testSetOfTag:compile(Config,?PER,[optimize]),
+ ?line testSetOfTag_cases(?PER).
+
+testSetOfTag_cases(Rules) ->
+ ?line testSetOfTag:main(Rules).
+
+
+sequence(suite) -> [{sequence,all}].
+
+compile(suite) -> [c_syntax,c_string_per,c_string_ber,c_implicit_before_choice];
+compile(Config) ->
+ ?line DataDir = ?config(data_dir,Config),
+ ?line TempDir = ?config(priv_dir,Config),
+ ?line True = lists:member(TempDir,code:get_path()),
+ ?line test_server:format("~p~n",[True]),
+ ?line test_server:format("~p~n",[code:get_path()]),
+ ?line true = code:add_patha(?config(priv_dir,Config)),
+ ?line {error,_R1} = asn1ct:compile(filename:join(DataDir,"Syntax")),
+ ?line ok = asn1ct:compile(filename:join(DataDir,"String"),[?PER,{outdir,TempDir}]),
+ test_server:format("first String ok~n"),
+ ?line ok = asn1ct:compile(filename:join(DataDir,"String"),[?BER,{outdir,TempDir}]),
+ ?line {error,_R2} = asn1ct:compile(filename:join(DataDir,"CCSNARG3"),[?BER,{outdir,TempDir}]),
+ ?line {error,_} = asn1ct:compile(filename:join(DataDir,"ImportsFrom"),[?BER,{outdir,TempDir}]),
+ ok.
+
+c_syntax(suite) -> [];
+c_syntax(Config) ->
+ ?line DataDir% ?line testExternal:compile(Config,?PER),
+% ?line testPrimExternal:compile(Config,?PER),
+% ?line testPrimExternal_cases(?PER).
+ = ?config(data_dir,Config),
+ ?line _TempDir = ?config(priv_dir,Config),
+ ?line true = code:add_patha(?config(priv_dir,Config)),
+ ?line {error,_R1} = asn1ct:compile(filename:join(DataDir,"Syntax")),
+ ?line {error,_R2} = asn1ct:compile(filename:join(DataDir,"BadTypeEnding")),
+ ?line {error,_R3} = asn1ct:compile(filename:join(DataDir,
+ "BadValueAssignment1")),
+ ?line {error,_R4} = asn1ct:compile(filename:join(DataDir,
+ "BadValueAssignment2")),
+ ?line {error,_R5} = asn1ct:compile(filename:join(DataDir,
+ "BadValueSet")),
+ ?line {error,_R6} = asn1ct:compile(filename:join(DataDir,
+ "ChoiceBadExtension")),
+ ?line {error,_R7} = asn1ct:compile(filename:join(DataDir,
+ "EnumerationBadExtension")),
+ ?line {error,_R8} = asn1ct:compile(filename:join(DataDir,
+ "Example")),
+ ?line {error,_R9} = asn1ct:compile(filename:join(DataDir,
+ "Export1")),
+ ?line {error,_R10} = asn1ct:compile(filename:join(DataDir,
+ "MissingEnd")),
+ ?line {error,_R11} = asn1ct:compile(filename:join(DataDir,
+ "SequenceBadComma")),
+ ?line {error,_R12} = asn1ct:compile(filename:join(DataDir,
+ "SequenceBadComponentName")),
+ ?line {error,_R13} = asn1ct:compile(filename:join(DataDir,
+ "SequenceBadComponentType")),
+ ?line {error,_R14} = asn1ct:compile(filename:join(DataDir,
+ "SeqBadComma")).
+
+
+c_string_per(suite) -> [];
+c_string_per(Config) ->
+ ?line DataDir = ?config(data_dir,Config),
+ ?line TempDir = ?config(priv_dir,Config),
+ ?line true = code:add_patha(?config(priv_dir,Config)),
+ ?line ok = asn1ct:compile(filename:join(DataDir,"String"),[?PER,{outdir,TempDir}]).
+
+c_string_ber(suite) -> [];
+c_string_ber(Config) ->
+ ?line DataDir = ?config(data_dir,Config),
+ ?line TempDir = ?config(priv_dir,Config),
+ ?line true = code:add_patha(?config(priv_dir,Config)),
+ ?line ok = asn1ct:compile(filename:join(DataDir,"String"),[?BER,{outdir,TempDir}]).
+
+
+c_implicit_before_choice(suite) -> [];
+c_implicit_before_choice(Config) ->
+ ?line DataDir = ?config(data_dir,Config),
+ ?line TempDir = ?config(priv_dir,Config),
+ ?line {error,_R2} = asn1ct:compile(filename:join(DataDir,"CCSNARG3"),[?BER,{outdir,TempDir}]).
+
+parse(suite) -> [];
+parse(Config) ->
+ ?line DataDir = ?config(data_dir,Config),
+ ?line OutDir = ?config(priv_dir,Config),
+ ?line true = code:add_patha(?config(priv_dir,Config)),
+ M1 = test_modules(),
+% M2 = parse_modules(),
+ ?line ok = parse1(M1,DataDir,OutDir).
+
+parse1([M|T],DataDir,OutDir) ->
+ ?line ok = asn1ct:compile(DataDir ++ M,[abs,{outdir,OutDir}]),
+ parse1(T,DataDir,OutDir);
+parse1([],_,_) ->
+ ok.
+
+per(suite) -> [];
+per(Config) ->
+ ?line DataDir = ?config(data_dir,Config),
+ ?line OutDir = ?config(priv_dir,Config),
+ ?line true = code:add_patha(?config(priv_dir,Config)),
+ ?line ok = per1(per_modules(),DataDir,OutDir),
+ ?line ?per_bit_opt(per1_bit_opt(per_modules(),DataDir,OutDir)),
+ ?line ok = per1_opt(per_modules(),DataDir,OutDir).
+
+
+per1([M|T],DataDir,OutDir) ->
+ ?line ok = asn1ct:compile(DataDir ++ M,[?PER,{outdir,OutDir}]),
+ ?line ok = asn1ct:test(list_to_atom(M)),
+ per1(T,DataDir,OutDir);
+per1([],_,_) ->
+ ok.
+
+per1_bit_opt([M|T],DataDir,OutDir) ->
+ ?line ok = asn1ct:compile(DataDir ++ M,[?PER,optimize,{outdir,OutDir}]),
+ ?line ok = asn1ct:test(list_to_atom(M)),
+ per1_bit_opt(T,DataDir,OutDir);
+per1_bit_opt([],_,_) ->
+ ok.
+
+per1_opt([M|T],DataDir,OutDir) ->
+ ?line ok = asn1ct:compile(DataDir ++ M,[?PER,optimized,{outdir,OutDir}]),
+ ?line ok = asn1ct:test(list_to_atom(M)),
+ per1_opt(T,DataDir,OutDir);
+per1_opt([],_,_) ->
+ ok.
+
+ber(suite) -> [ber_choiceinseq,ber_optional,ber_optional_keyed_list,ber_other].
+
+ber_choiceinseq(suite) ->[];
+ber_choiceinseq(Config) ->
+ ?line DataDir = ?config(data_dir,Config),
+ ?line OutDir = ?config(priv_dir,Config),
+ ?line true = code:add_patha(?config(priv_dir,Config)),
+ ?line ok = asn1ct:compile(filename:join(DataDir,"ChoiceInSeq"),[?BER,{outdir,OutDir}]).
+
+ber_optional(suite) ->[];
+ber_optional(Config) ->
+ ?line DataDir = ?config(data_dir,Config),
+ ?line OutDir = ?config(priv_dir,Config),
+ ?line true = code:add_patha(?config(priv_dir,Config)),
+ ?line ok = asn1ct:compile(filename:join(DataDir,"SOpttest"),[?BER,{outdir,OutDir}]),
+ ?line V = {'S',{'A',10,asn1_NOVALUE,asn1_NOVALUE},
+ {'B',asn1_NOVALUE,asn1_NOVALUE,asn1_NOVALUE},
+ {'C',asn1_NOVALUE,111,asn1_NOVALUE}},
+ ?line {ok,B} = asn1_wrapper:encode('SOpttest','S',V),
+ ?line Bytes = lists:flatten(B),
+ ?line V2 = asn1_wrapper:decode('SOpttest','S',Bytes),
+ ?line ok = eq(V,element(2,V2)).
+
+ber_optional_keyed_list(suite) ->[];
+ber_optional_keyed_list(Config) ->
+ case ?BER of
+ ber_bin_v2 -> ok;
+ _ ->
+ ?line DataDir = ?config(data_dir,Config),
+ ?line OutDir = ?config(priv_dir,Config),
+ ?line true = code:add_patha(?config(priv_dir,Config)),
+ ?line ok = asn1ct:compile(filename:join(DataDir,"SOpttest"),
+ [?BER,keyed_list,{outdir,OutDir}]),
+ ?line Vrecord = {'S',{'A',10,asn1_NOVALUE,asn1_NOVALUE},
+ {'B',asn1_NOVALUE,asn1_NOVALUE,asn1_NOVALUE},
+ {'C',asn1_NOVALUE,111,asn1_NOVALUE}},
+ ?line V = [ {a,[{scriptKey,10}]},
+ {b,[]},
+ {c,[{callingPartysCategory,111}]} ],
+ ?line {ok,B} = asn1_wrapper:encode('SOpttest','S',V),
+ ?line Bytes = lists:flatten(B),
+ ?line V2 = asn1_wrapper:decode('SOpttest','S',Bytes),
+ ?line ok = eq(Vrecord,element(2,V2))
+ end.
+
+
+eq(V,V) ->
+ ok.
+
+
+ber_other(suite) ->[];
+ber_other(Config) ->
+ ?line DataDir = ?config(data_dir,Config),
+ ?line OutDir = ?config(priv_dir,Config),
+ ?line true = code:add_patha(?config(priv_dir,Config)),
+ ?line ok = ber1(ber_modules(),DataDir,OutDir).
+
+
+ber1([M|T],DataDir,OutDir) ->
+ ?line ok = asn1ct:compile(DataDir ++ M,[?BER,{outdir,OutDir}]),
+ ?line ok = asn1ct:test(list_to_atom(M)),
+ ber1(T,DataDir,OutDir);
+ber1([],_,_) ->
+ ok.
+
+default_per(suite) ->[];
+default_per(Config) ->
+ default1(?PER,Config,[]).
+
+default_per_opt(suite) -> [];
+default_per_opt(Config) ->
+ ?per_bit_opt(default1(?PER,Config,[optimize])),
+ default1(?PER,Config,[optimize]).
+
+default_ber(suite) ->[];
+default_ber(Config) ->
+ default1(?BER,Config,[]).
+
+default1(Rule,Config,Options) ->
+ ?line DataDir = ?config(data_dir,Config),
+ ?line OutDir = ?config(priv_dir,Config),
+ ?line true = code:add_patha(?config(priv_dir,Config)),
+ ?line ok = asn1ct:compile(DataDir ++ "Def",[Rule,{outdir,OutDir}]++Options),
+ ?line {ok,Bytes1} = asn1_wrapper:encode('Def','Def1',#'Def1'{bool0 = true,
+ bool1 = true,
+ bool2 = true,
+ bool3 = true}),
+ ?line {ok,{'Def1',true,true,true,true}} = asn1_wrapper:decode('Def','Def1',lists:flatten(Bytes1)),
+
+ ?line {ok,Bytes2} = asn1_wrapper:encode('Def','Def1',#'Def1'{bool0 = true}),
+ ?line {ok,{'Def1',true,false,false,false}} = asn1_wrapper:decode('Def','Def1',lists:flatten(Bytes2)),
+
+ ?line {ok,Bytes3} = asn1_wrapper:encode('Def','Def1',#'Def1'{bool0 = true,bool2=false}),
+ ?line {ok,{'Def1',true,false,false,false}} = asn1_wrapper:decode('Def','Def1',lists:flatten(Bytes3)).
+
+
+value_test(suite) ->[];
+value_test(Config) ->
+ ?line DataDir = ?config(data_dir,Config),
+ ?line OutDir = ?config(priv_dir,Config),
+ ?line true = code:add_patha(?config(priv_dir,Config)),
+ ?line ok = asn1ct:compile(DataDir ++ "ObjIdValues",[?BER,{outdir,OutDir}]),
+ ?line {ok,_} = asn1_wrapper:encode('ObjIdValues','ObjIdType','ObjIdValues':'mobileDomainId'()),
+ ?line ok = asn1ct:compile(DataDir ++ "ObjIdValues",[?PER,{outdir,OutDir}]),
+ ?line {ok,_} = asn1_wrapper:encode('ObjIdValues','ObjIdType','ObjIdValues':'mobileDomainId'()),
+ ?line ok = test_bad_values:tests(Config),
+ ok.
+
+
+constructed(suite) ->
+ [];
+constructed(Config) ->
+ ?line DataDir = ?config(data_dir,Config),
+ ?line OutDir = ?config(priv_dir,Config),
+ ?line true = code:add_patha(?config(priv_dir,Config)),
+ ?line ok = asn1ct:compile(DataDir ++ "Constructed",[?BER,{outdir,OutDir}]),
+ ?line {ok,B} = asn1_wrapper:encode('Constructed','S',{'S',false}),
+ ?line [40,3,1,1,0] = lists:flatten(B),
+ ?line {ok,B1} = asn1_wrapper:encode('Constructed','S2',{'S2',false}),
+ ?line [40,5,48,3,1,1,0] = lists:flatten(B1),
+ ?line {ok,B2} = asn1_wrapper:encode('Constructed','I',10),
+ ?line [136,1,10] = lists:flatten(B2),
+ ok.
+
+ber_decode_error(suite) -> [];
+ber_decode_error(Config) ->
+ ?line ok = ber_decode_error:compile(Config,?BER,[]),
+ ?line ok = ber_decode_error:run([]),
+
+ ?line ok = ?ber_driver(?BER,ber_decode_error:compile(Config,?BER,[driver])),
+ ?line ok = ?ber_driver(?BER,ber_decode_error:run([driver])),
+ ok.
+
+h323test(suite) ->
+ [];
+h323test(Config) ->
+ ?line ok = h323test:compile(Config,?PER,[]),
+ ?line ok = h323test:run(?PER),
+ ?line ?per_bit_opt(h323test:compile(Config,?PER,[optimize])),
+ ?line ?per_bit_opt(h323test:run(?PER)),
+ ?line ?uper_bin(h323test:compile(Config,uper_bin,[])),
+ ?line ?uper_bin(h323test:run(uper_bin)),
+ ?line ok = h323test:compile(Config,?PER,[optimize]),
+ ?line ok = h323test:run(?PER),
+ ok.
+
+per_GeneralString(suite) ->
+ [];
+per_GeneralString(Config) ->
+ case erlang:module_loaded('MULTIMEDIA-SYSTEM-CONTROL') of
+ true ->
+ ok;
+ false ->
+ h323test:compile(Config,?PER,[])
+ end,
+ UI = [109,64,1,57],
+ ?line {ok,_V} = asn1_wrapper:decode('MULTIMEDIA-SYSTEM-CONTROL',
+ 'MultimediaSystemControlMessage',UI).
+
+per_open_type(suite) ->
+ [];
+per_open_type(Config) ->
+ ?line DataDir = ?config(data_dir,Config),
+ ?line OutDir = ?config(priv_dir,Config),
+ ?line ok = asn1ct:compile(DataDir ++ "OpenType",[?PER,{outdir,OutDir}]),
+ Stype = {'Stype',10,true},
+ ?line {ok,Bytes} = asn1_wrapper:encode('OpenType','Ot',Stype),
+ ?line {ok,Stype} = asn1_wrapper:decode('OpenType','Ot',Bytes),
+
+ ?line ?per_bit_opt(ok = asn1ct:compile(DataDir ++ "OpenType",
+ [?PER,optimize,{outdir,OutDir}])),
+ ?line ?per_bit_opt({ok,Bytes}=asn1_wrapper:encode('OpenType','Ot',Stype)),
+ ?line ?per_bit_opt({ok,Stype}=asn1_wrapper:decode('OpenType','Ot',Bytes)),
+
+ ?line ?uper_bin(ok = asn1ct:compile(DataDir ++ "OpenType",
+ [uper_bin,{outdir,OutDir}])),
+ ?line ?uper_bin({ok,Bytes}=asn1_wrapper:encode('OpenType','Ot',Stype)),
+ ?line ?uper_bin({ok,Stype}=asn1_wrapper:decode('OpenType','Ot',Bytes)),
+
+ ?line ok = asn1ct:compile(DataDir ++ "OpenType",
+ [?PER,optimize,{outdir,OutDir}]),
+ ?line {ok,Bytes} = asn1_wrapper:encode('OpenType','Ot',Stype),
+ ?line {ok,Stype} = asn1_wrapper:decode('OpenType','Ot',Bytes).
+
+testConstraints(suite) ->
+ [];
+testConstraints(Config) ->
+ ?line true = code:add_patha(?config(priv_dir,Config)),
+
+ ?line testConstraints:compile(Config,?BER,[]),
+ ?line testConstraints:int_constraints(?BER),
+
+ ?line ?ber_driver(?BER,testConstraints:compile(Config,?BER,[driver])),
+ ?line ?ber_driver(?BER,testConstraints:int_constraints(?BER)),
+
+ ?line testConstraints:compile(Config,?PER,[]),
+ ?line testConstraints:int_constraints(?PER),
+ ?line testConstraints:refed_NNL_name(?PER),
+
+ ?line ?per_bit_opt(testConstraints:compile(Config,?PER,[optimize])),
+ ?line ?per_bit_opt(testConstraints:int_constraints(?PER)),
+ ?line ?per_bit_opt(testConstraints:refed_NNL_name(?PER)),
+
+ ?line ?uper_bin(testConstraints:compile(Config,uper_bin,[])),
+ ?line ?uper_bin(testConstraints:int_constraints(uper_bin)),
+ ?line ?uper_bin(testConstraints:refed_NNL_name(uper_bin)),
+
+ ?line testConstraints:compile(Config,?PER,[optimize]),
+ ?line testConstraints:int_constraints(?PER),
+ ?line testConstraints:refed_NNL_name(?PER).
+
+testSeqIndefinite(suite) -> [];
+testSeqIndefinite(Config) ->
+ ?line true = code:add_patha(?config(priv_dir,Config)),
+
+ ?line testSeqIndefinite:compile(Config,?BER,[]),
+ ?line testSeqIndefinite:main(?BER),
+
+ ?line ?ber_driver(?BER,testSeqIndefinite:compile(Config,?BER,[driver])),
+ ?line ?ber_driver(?BER,testSeqIndefinite:main(?BER)).
+
+testSetIndefinite(suite) -> [];
+testSetIndefinite(Config) ->
+ ?line true = code:add_patha(?config(priv_dir,Config)),
+
+ ?line testSetIndefinite:compile(Config,?BER,[]),
+ ?line testSetIndefinite:main(?BER),
+
+ ?line ?ber_driver(?BER,testSetIndefinite:compile(Config,?BER,[driver])),
+ ?line ?ber_driver(?BER,testSetIndefinite:main(?BER)).
+
+testChoiceIndefinite(suite) -> [];
+testChoiceIndefinite(Config) ->
+ ?line true = code:add_patha(?config(priv_dir,Config)),
+
+ ?line testChoiceIndefinite:compile(Config,?BER,[]),
+ ?line testChoiceIndefinite:main(?BER),
+
+ ?line ?ber_driver(?BER,testChoiceIndefinite:compile(Config,?BER,[driver])),
+ ?line ?ber_driver(?BER,testChoiceIndefinite:main(?BER)).
+
+testInfObjectClass(suite) ->
+ [];
+testInfObjectClass(Config) ->
+ ?line true = code:add_patha(?config(priv_dir,Config)),
+
+ ?line testInfObjectClass:compile(Config,?PER,[]),
+ ?line testInfObjectClass:main(?PER),
+ ?line testInfObj:compile(Config,?PER,[]),
+ ?line testInfObj:main(?PER),
+
+ ?line ?per_bit_opt(testInfObjectClass:compile(Config,?PER,[optimize])),
+ ?line ?per_bit_opt(testInfObjectClass:main(?PER)),
+ ?line ?per_bit_opt(testInfObj:compile(Config,?PER,[optimize])),
+ ?line ?per_bit_opt(testInfObj:main(?PER)),
+
+ ?line ?uper_bin(testInfObjectClass:compile(Config,uper_bin,[])),
+ ?line ?uper_bin(testInfObjectClass:main(uper_bin)),
+ ?line ?uper_bin(testInfObj:compile(Config,uper_bin,[])),
+ ?line ?uper_bin(testInfObj:main(uper_bin)),
+
+ ?line testInfObjectClass:compile(Config,?PER,[optimize]),
+ ?line testInfObjectClass:main(?PER),
+ ?line testInfObj:compile(Config,?PER,[optimize]),
+ ?line testInfObj:main(?PER),
+
+ ?line testInfObjectClass:compile(Config,?BER,[]),
+ ?line testInfObjectClass:main(?BER),
+ ?line testInfObj:compile(Config,?BER,[]),
+ ?line testInfObj:main(?BER),
+
+ ?line ?ber_driver(?BER,testInfObjectClass:compile(Config,?BER,[driver])),
+ ?line ?ber_driver(?BER,testInfObjectClass:main(?BER)),
+ ?line ?ber_driver(?BER,testInfObj:compile(Config,?BER,[driver])),
+ ?line ?ber_driver(?BER,testInfObj:main(?BER)),
+
+ ?line testInfObj:compile_RANAPfiles(Config,?PER,[]),
+
+ ?line ?per_bit_opt(testInfObj:compile_RANAPfiles(Config,?PER,[optimize])),
+
+ ?line ?uper_bin(testInfObj:compile_RANAPfiles(Config,uper_bin,[])),
+
+ ?line testInfObj:compile_RANAPfiles(Config,?PER,[optimize]),
+
+ ?line testInfObj:compile_RANAPfiles(Config,?BER,[]).
+
+testParameterizedInfObj(suite) ->
+ [];
+testParameterizedInfObj(Config) ->
+ ?line true = code:add_patha(?config(priv_dir,Config)),
+
+ ?line testParameterizedInfObj:compile(Config,?PER,[]),
+ ?line testParameterizedInfObj:main(?PER),
+
+ ?line ?per_bit_opt(testParameterizedInfObj:compile(Config,?PER,[optimize])),
+ ?line ?per_bit_opt(testParameterizedInfObj:main(?PER)),
+
+ ?line ?uper_bin(testParameterizedInfObj:compile(Config,uper_bin,[])),
+ ?line ?uper_bin(testParameterizedInfObj:main(uper_bin)),
+
+ ?line testParameterizedInfObj:compile(Config,?PER,[optimize]),
+ ?line testParameterizedInfObj:main(?PER),
+
+ ?line testParameterizedInfObj:compile(Config,?BER,[]),
+ ?line testParameterizedInfObj:main(?BER),
+
+ ?line ?ber_driver(?BER,testParameterizedInfObj:compile(Config,?BER,[driver])),
+ ?line ?ber_driver(?BER,testParameterizedInfObj:main(?BER)).
+
+testMergeCompile(suite) ->
+ [];
+testMergeCompile(Config) ->
+ ?line true = code:add_patha(?config(priv_dir,Config)),
+
+ ?line testMergeCompile:compile(Config,?PER,[]),
+ ?line testMergeCompile:main(?PER),
+ ?line testMergeCompile:mvrasn(?PER),
+
+ ?line ?per_bit_opt(testMergeCompile:compile(Config,?PER,[optimize])),
+ ?line ?per_bit_opt(testMergeCompile:main(?PER)),
+ ?line ?per_bit_opt(testMergeCompile:mvrasn(?PER)),
+
+ ?line ?uper_bin(testMergeCompile:compile(Config,uper_bin,[])),
+ ?line ?uper_bin(testMergeCompile:main(uper_bin)),
+ ?line ?uper_bin(testMergeCompile:mvrasn(uper_bin)),
+
+ ?line testMergeCompile:compile(Config,?BER,[]),
+ ?line testMergeCompile:main(?BER),
+ ?line testMergeCompile:mvrasn(?BER),
+
+ ?line ?ber_driver(?BER,testMergeCompile:compile(Config,?BER,[driver])),
+ ?line ?ber_driver(?BER,testMergeCompile:main(?BER)),
+ ?line ?ber_driver(?BER,testMergeCompile:mvrasn(?BER)).
+
+testobj(suite) ->
+ [];
+testobj(Config) ->
+ ?line true = code:add_patha(?config(priv_dir,Config)),
+
+ ?line ok = testRANAP:compile(Config,?PER,[]),
+ ?line ok = testRANAP:testobj(?PER),
+ ?line ok = testParameterizedInfObj:ranap(?PER),
+
+ ?line ?per_bit_opt(ok = testRANAP:compile(Config,?PER,[optimize])),
+ ?line ?per_bit_opt(ok = testRANAP:testobj(?PER)),
+ ?line ?per_bit_opt(ok = testParameterizedInfObj:ranap(?PER)),
+
+ ?line ?uper_bin(ok = testRANAP:compile(Config,uper_bin,[])),
+ ?line ?uper_bin(ok = testRANAP:testobj(uper_bin)),
+ ?line ?uper_bin(ok = testParameterizedInfObj:ranap(uper_bin)),
+
+ ?line ok = testRANAP:compile(Config,?PER,[optimize]),
+ ?line ok = testRANAP:testobj(?PER),
+ ?line ok = testParameterizedInfObj:ranap(?PER),
+
+ ?line ok = testRANAP:compile(Config,?BER,[]),
+ ?line ok = testRANAP:testobj(?BER),
+ ?line ok = testParameterizedInfObj:ranap(?BER),
+
+ ?line ?ber_driver(?BER,testRANAP:compile(Config,?BER,[driver])),
+ ?line ?ber_driver(?BER,testRANAP:testobj(?BER)),
+ ?line ?ber_driver(?BER,testParameterizedInfObj:ranap(?BER)).
+
+
+testDeepTConstr(suite) ->
+ [];
+testDeepTConstr(Config) ->
+ ?line true = code:add_patha(?config(priv_dir,Config)),
+
+ ?line testDeepTConstr:compile(Config,?PER,[]),
+ ?line testDeepTConstr:main(?PER),
+
+ ?line ?per_bit_opt(testDeepTConstr:compile(Config,?PER,[optimize])),
+ ?line ?per_bit_opt(testDeepTConstr:main(?PER)),
+
+ ?line ?uper_bin(testDeepTConstr:compile(Config,uper_bin,[])),
+ ?line ?uper_bin(testDeepTConstr:main(uper_bin)),
+
+ ?line testDeepTConstr:compile(Config,?PER,[optimize]),
+ ?line testDeepTConstr:main(?PER),
+
+ ?line testDeepTConstr:compile(Config,?BER,[]),
+ ?line testDeepTConstr:main(?BER),
+
+ ?line ?ber_driver(?BER,testDeepTConstr:compile(Config,?BER,[driver])),
+ ?line ?ber_driver(?BER,testDeepTConstr:main(?BER)).
+
+testInvokeMod(suite) ->
+ [];
+testInvokeMod(Config) ->
+ ?line DataDir = ?config(data_dir,Config),
+ ?line OutDir = ?config(priv_dir,Config),
+ ?line true = code:add_patha(?config(priv_dir,Config)),
+
+ ?line ok = asn1ct:compile(filename:join(DataDir,"PrimStrings"),[{outdir,OutDir}]),
+ ?line {ok,_Result1} = 'PrimStrings':encode('Bs1',[1,0,1,0]),
+ ?line ok = asn1ct:compile(filename:join(DataDir,"PrimStrings"),[?PER,{outdir,OutDir}]),
+ ?line {ok,_Result2} = 'PrimStrings':encode('Bs1',[1,0,1,0]).
+
+testExport(suite) ->
+ [];
+testExport(Config) ->
+ ?line DataDir = ?config(data_dir,Config),
+ ?line OutDir = ?config(priv_dir,Config),
+ ?line true = code:add_patha(?config(priv_dir,Config)),
+
+ ?line {error,{asn1,_Reason}} = asn1ct:compile(filename:join(DataDir,"IllegalExport"),[{outdir,OutDir}]).
+
+testImport(suite) ->
+ [];
+testImport(Config) ->
+ ?line DataDir = ?config(data_dir,Config),
+ ?line _OutDir = ?config(priv_dir,Config),
+ ?line {error,_} = asn1ct:compile(filename:join(DataDir,"ImportsFrom"),[?BER]),
+ ok.
+
+testMegaco(suite) ->
+ [];
+testMegaco(Config) ->
+ ?line true = code:add_patha(?config(priv_dir,Config)),
+ io:format("Config: ~p~n",[Config]),
+ ?line {ok,ModuleName1,ModuleName2} = testMegaco:compile(Config,?BER,[]),
+ ?line ok = testMegaco:main(ModuleName1,Config),
+ ?line ok = testMegaco:main(ModuleName2,Config),
+
+ case ?BER of
+ ber_bin_v2 ->
+ ?line {ok,ModuleName3,ModuleName4} = testMegaco:compile(Config,?BER,[driver]),
+ ?line ok = testMegaco:main(ModuleName3,Config),
+ ?line ok = testMegaco:main(ModuleName4,Config);
+ _-> ok
+ end,
+
+ ?line {ok,ModuleName5,ModuleName6} = testMegaco:compile(Config,?PER,[]),
+ ?line ok = testMegaco:main(ModuleName5,Config),
+ ?line ok = testMegaco:main(ModuleName6,Config),
+
+ ?line ?per_bit_opt({ok,ModuleName5,ModuleName6} = testMegaco:compile(Config,?PER,[optimize])),
+ ?line ?per_bit_opt(ok = testMegaco:main(ModuleName5,Config)),
+ ?line ?per_bit_opt(ok = testMegaco:main(ModuleName6,Config)),
+
+ ?line ?uper_bin({ok,ModuleName5,ModuleName6} = testMegaco:compile(Config,uper_bin,[])),
+ ?line ?uper_bin(ok = testMegaco:main(ModuleName5,Config)),
+ ?line ?uper_bin(ok = testMegaco:main(ModuleName6,Config)),
+
+ ?line {ok,ModuleName7,ModuleName8} = testMegaco:compile(Config,?PER,[optimize]),
+ ?line ok = testMegaco:main(ModuleName7,Config),
+ ?line ok = testMegaco:main(ModuleName8,Config).
+
+
+testMvrasn6(suite) -> [];
+testMvrasn6(Config) ->
+ ?line true = code:add_patha(?config(priv_dir,Config)),
+
+ ?line testMvrasn6:compile(Config,?BER),
+ ?line testMvrasn6:main().
+
+testContextSwitchingTypes(suite) -> [];
+testContextSwitchingTypes(Config) ->
+ ?line true = code:add_patha(?config(priv_dir,Config)),
+
+ ?line testContextSwitchingTypes:compile(Config,?BER,[]),
+ ?line testContextSwitchingTypes:test(),
+
+ ?line ?ber_driver(?BER,testContextSwitchingTypes:compile(Config,?BER,[driver])),
+ ?line ?ber_driver(?BER,testContextSwitchingTypes:test()),
+
+ ?line testContextSwitchingTypes:compile(Config,?PER,[]),
+ ?line testContextSwitchingTypes:test(),
+
+ ?line ?per_bit_opt(testContextSwitchingTypes:compile(Config,?PER,[optimize])),
+ ?line ?per_bit_opt(testContextSwitchingTypes:test()),
+
+ ?line ?uper_bin(testContextSwitchingTypes:compile(Config,uper_bin,[])),
+ ?line ?uper_bin(testContextSwitchingTypes:test()),
+
+ ?line testContextSwitchingTypes:compile(Config,?PER,[optimize]),
+ ?line testContextSwitchingTypes:test().
+
+testTypeValueNotation(suite) -> [];
+testTypeValueNotation(Config) ->
+ ?line true = code:add_patha(?config(priv_dir,Config)),
+
+ case ?BER of
+ Ber when Ber == ber; Ber == ber_bin ->
+ ?line testTypeValueNotation:compile(Config,?BER,[]),
+ ?line testTypeValueNotation:main(?BER,dummy);
+ _ ->
+ ok
+ end,
+
+ ?line ?ber_driver(?BER,testTypeValueNotation:compile(Config,?BER,[driver])),
+ ?line ?ber_driver(?BER,testTypeValueNotation:main(?BER,optimize)),
+
+ case ?BER of
+ Ber2 when Ber2 == ber; Ber2 == ber_bin ->
+ ?line testTypeValueNotation:compile(Config,?PER,[]),
+ ?line testTypeValueNotation:main(?PER,dummy);
+ _ ->
+ ok
+ end,
+
+ ?line ?per_bit_opt(testTypeValueNotation:compile(Config,?PER,[optimize])),
+ ?line ?per_bit_opt(testTypeValueNotation:main(?PER,optimize)),
+
+ ?line ?uper_bin(testTypeValueNotation:compile(Config,uper_bin,[])),
+ ?line ?uper_bin(testTypeValueNotation:main(uper_bin,optimize)),
+ case ?BER of
+ Ber3 when Ber3 == ber; Ber3 == ber_bin ->
+ ?line testTypeValueNotation:compile(Config,?PER,[optimize]),
+ ?line testTypeValueNotation:main(?PER,optimize);
+ _ ->
+ ok
+ end.
+
+testOpenTypeImplicitTag(suite) -> [];
+testOpenTypeImplicitTag(Config) ->
+ ?line true = code:add_patha(?config(priv_dir,Config)),
+
+ ?line testOpenTypeImplicitTag:compile(Config,?BER,[]),
+ ?line testOpenTypeImplicitTag:main(?BER),
+
+ ?line ?ber_driver(?BER,testOpenTypeImplicitTag:compile(Config,?BER,[driver])),
+ ?line ?ber_driver(?BER,testOpenTypeImplicitTag:main(?BER)),
+
+ ?line testOpenTypeImplicitTag:compile(Config,?PER,[]),
+ ?line testOpenTypeImplicitTag:main(?PER),
+
+ ?line ?per_bit_opt(testOpenTypeImplicitTag:compile(Config,?PER,[optimize])),
+ ?line ?per_bit_opt(testOpenTypeImplicitTag:main(?PER)),
+
+ ?line ?uper_bin(testOpenTypeImplicitTag:compile(Config,uper_bin,[])),
+ ?line ?uper_bin(testOpenTypeImplicitTag:main(uper_bin)),
+
+ ?line testOpenTypeImplicitTag:compile(Config,?PER,[optimize]),
+ ?line testOpenTypeImplicitTag:main(?PER).
+
+duplicate_tags(suite) -> [];
+duplicate_tags(Config) ->
+ ?line DataDir = ?config(data_dir,Config),
+ {error,{asn1,[{error,{type,_,_,'SeqOpt1Imp',{asn1,{duplicates_of_the_tags,_}}}}]}} =
+ asn1ct:compile(filename:join(DataDir,"SeqOptional2"),[abs]),
+ ok.
+
+rtUI(suite) -> [];
+rtUI(Config) ->
+ ?line DataDir = ?config(data_dir,Config),
+ ?line ok = asn1ct:compile(filename:join(DataDir,"Prim"),[?BER]),
+ ?line {ok,_} = asn1rt:info('Prim'),
+
+ ?line ok = asn1ct:compile(filename:join(DataDir,"Prim"),[?PER]),
+ ?line {ok,_} = asn1rt:info('Prim'),
+
+ ?line ok = asn1rt:load_driver(),
+ ?line ok = asn1rt:load_driver(),
+ ?line ok = asn1rt:unload_driver().
+
+testROSE(suite) -> [];
+testROSE(Config) ->
+ ?line true = code:add_patha(?config(priv_dir,Config)),
+
+ ?line testROSE:compile(Config,?BER,[]),
+
+ ?line testROSE:compile(Config,?PER,[]),
+ ?line ?per_bit_opt(testROSE:compile(Config,?PER,[optimize])),
+ ?line ?uper_bin(testROSE:compile(Config,uper_bin,[])),
+ ?line testROSE:compile(Config,?PER,[optimize]).
+
+testINSTANCE_OF(suite) -> [];
+testINSTANCE_OF(Config) ->
+ ?line testINSTANCE_OF:compile(Config,?BER,[]),
+ ?line testINSTANCE_OF:main(?BER),
+
+ ?line ?ber_driver(?BER,testINSTANCE_OF:compile(Config,?BER,[driver])),
+ ?line ?ber_driver(?BER,testINSTANCE_OF:main(?BER)),
+
+ ?line testINSTANCE_OF:compile(Config,?PER,[]),
+ ?line testINSTANCE_OF:main(?PER),
+
+ ?line ?per_bit_opt(testINSTANCE_OF:compile(Config,?PER,[optimize])),
+ ?line ?per_bit_opt(testINSTANCE_OF:main(?PER)),
+
+ ?line ?uper_bin(testINSTANCE_OF:compile(Config,uper_bin,[])),
+ ?line ?uper_bin(testINSTANCE_OF:main(uper_bin)),
+
+ ?line testINSTANCE_OF:compile(Config,?PER,[optimize]),
+ ?line testINSTANCE_OF:main(?PER).
+
+testTCAP(suite) -> [];
+testTCAP(Config) ->
+ ?line true = code:add_patha(?config(priv_dir,Config)),
+
+ ?line testTCAP:compile(Config,?BER,[]),
+ ?line testTCAP:test(?BER,Config),
+
+ ?line ?ber_driver(?BER,testTCAP:compile(Config,?BER,[driver])),
+ ?line ?ber_driver(?BER,testTCAP:test(?BER,Config)),
+
+ ?line ?ber_driver(?BER,testTCAP:compile_asn1config(Config,?BER,[asn1config])),
+ ?line ?ber_driver(?BER,testTCAP:test_asn1config()).
+
+testDER(suite) ->[];
+testDER(Config) ->
+ ?line true = code:add_patha(?config(priv_dir,Config)),
+
+ ?line testDER:compile(Config,?BER,[]),
+ ?line testDER:test(),
+
+ ?line ?ber_driver(?BER,testDER:compile(Config,?BER,[driver])),
+ ?line ?ber_driver(?BER,testDER:test()),
+
+ ?line testParamBasic:compile_der(Config,?BER),
+ ?line testParamBasic_cases(der),
+
+
+ ?line testSeqSetDefaultVal:compile(Config,?BER),
+ ?line testSeqSetDefaultVal_cases(?BER).
+
+testSeqSetDefaultVal_cases(?BER) ->
+ ?line testSeqSetDefaultVal:main(?BER).
+
+
+specialized_decodes(suite) -> [];
+specialized_decodes(Config) ->
+ ?line test_partial_incomplete_decode:compile(Config,?BER,[optimize]),
+ ?line test_partial_incomplete_decode:test(?BER,Config),
+ ?line test_selective_decode:test(?BER,Config).
+
+special_decode_performance(suite) ->[];
+special_decode_performance(Config) ->
+ ?line ?ber_driver(?BER,test_special_decode_performance:compile(Config,?BER)),
+ ?line ?ber_driver(?BER,test_special_decode_performance:go(all)).
+
+
+test_driver_load(suite) -> [];
+test_driver_load(Config) ->
+ ?line test_driver_load:compile(Config,?PER),
+ ?line test_driver_load:test(?PER,5).
+
+test_ParamTypeInfObj(suite) -> [];
+test_ParamTypeInfObj(Config) ->
+ ?line DataDir = ?config(data_dir,Config),
+ ?line ok = asn1ct:compile(filename:join(DataDir,"IN-CS-1-Datatypes"),[ber_bin]).
+
+test_WS_ParamClass(suite) -> [];
+test_WS_ParamClass(Config) ->
+ ?line DataDir = ?config(data_dir,Config),
+ ?line ok = asn1ct:compile(filename:join(DataDir,"InformationFramework"),
+ [ber_bin]).
+
+test_Defed_ObjectIdentifier(suite) -> [];
+test_Defed_ObjectIdentifier(Config) ->
+ ?line DataDir = ?config(data_dir,Config),
+ ?line ok = asn1ct:compile(filename:join(DataDir,"UsefulDefinitions"),
+ [ber_bin]).
+
+testSelectionType(suite) -> [];
+testSelectionType(Config) ->
+
+ ?line ok = testSelectionTypes:compile(Config,?BER,[]),
+ ?line {ok,_} = testSelectionTypes:test(),
+
+ ?line ok = testSelectionTypes:compile(Config,?PER,[]),
+ ?line {ok,_} = testSelectionTypes:test().
+
+testSSLspecs(suite) -> [];
+testSSLspecs(Config) ->
+
+ ?line ok = testSSLspecs:compile(Config,?BER,
+ [optimize,compact_bit_string,der]),
+ ?line testSSLspecs:run(?BER),
+
+ case code:which(asn1ct) of
+ cover_compiled ->
+ ok;
+ _ ->
+ ?line ok = testSSLspecs:compile_inline(Config,?BER),
+ ?line ok = testSSLspecs:run_inline(?BER)
+ end.
+
+testNortel(suite) -> [];
+testNortel(Config) ->
+ ?line DataDir = ?config(data_dir,Config),
+
+ ?line ok = asn1ct:compile(filename:join(DataDir,"Nortel"),[?BER]),
+ ?line ok = asn1ct:compile(filename:join(DataDir,"Nortel"),
+ [?BER,optimize]),
+ ?line ok = asn1ct:compile(filename:join(DataDir,"Nortel"),
+ [?BER,optimize,driver]),
+ ?line ok = asn1ct:compile(filename:join(DataDir,"Nortel"),[?PER]),
+ ?line ?per_bit_opt(ok = asn1ct:compile(filename:join(DataDir,"Nortel"),
+ [?PER,optimize])),
+ ?line ?uper_bin(ok = asn1ct:compile(filename:join(DataDir,"Nortel"),[uper_bin])),
+ ?line ok = asn1ct:compile(filename:join(DataDir,"Nortel"),
+ [?PER,optimize]).
+test_undecoded_rest(suite) -> [];
+test_undecoded_rest(Config) ->
+
+ ?line ok = test_undecoded_rest:compile(Config,?BER,[]),
+ ?line ok = test_undecoded_rest:test([]),
+
+ ?line ok = test_undecoded_rest:compile(Config,?BER,[undec_rest]),
+ ?line ok = test_undecoded_rest:test(undec_rest),
+
+ ?line ok = test_undecoded_rest:compile(Config,?PER,[]),
+ ?line ok = test_undecoded_rest:test([]),
+
+ ?line ?per_bit_opt(ok = test_undecoded_rest:compile(Config,?PER,[optimize,undec_rest])),
+ ?line ?per_bit_opt(ok = test_undecoded_rest:test(undec_rest)),
+
+ ?line ?uper_bin(ok = test_undecoded_rest:compile(Config,uper_bin,[undec_rest])),
+ ?line ?uper_bin(ok = test_undecoded_rest:test(undec_rest)),
+
+ ?line ok = test_undecoded_rest:compile(Config,?PER,[undec_rest]),
+ ?line ok = test_undecoded_rest:test(undec_rest).
+
+test_inline(suite) -> [];
+test_inline(Config) ->
+ case code:which(asn1ct) of
+ cover_compiled ->
+ {skip,"Not runnable when cover compiled"};
+ _ ->
+ ?line ok=test_inline:compile(Config,?BER,[]),
+ ?line test_inline:main(?BER),
+ ?line test_inline:inline1(Config,?BER,[]),
+ ?line test_inline:performance2()
+ end.
+
+%test_inline_prf(suite) -> [];
+%test_inline_prf(Config) ->
+% ?line test_inline:performance(Config).
+
+testTcapsystem(suite) -> [];
+testTcapsystem(Config) ->
+ ?line ok=testTcapsystem:compile(Config,?BER,[]).
+
+testNBAPsystem(suite) -> [];
+testNBAPsystem(Config) ->
+ ?line ok=testNBAPsystem:compile(Config,?PER,?per_optimize(?BER)),
+ ?line ok=testNBAPsystem:test(?PER,Config).
+
+test_compile_options(suite) -> [];
+test_compile_options(Config) ->
+ case code:which(asn1ct) of
+ cover_compiled ->
+ {skip,"Not runnable when cover compiled"};
+ _ ->
+ ?line ok = test_compile_options:wrong_path(Config),
+ ?line ok = test_compile_options:path(Config),
+ ?line ok = test_compile_options:noobj(Config),
+ ?line ok = test_compile_options:record_name_prefix(Config)
+ end.
+testDoubleEllipses(suite) -> [];
+testDoubleEllipses(Config) ->
+ ?line testDoubleEllipses:compile(Config,?BER,[]),
+ ?line testDoubleEllipses:main(?BER),
+ ?line ?ber_driver(?BER,testDoubleEllipses:compile(Config,?BER,[driver])),
+ ?line ?ber_driver(?BER,testDoubleEllipses:main(?BER)),
+ ?line ?per_bit_opt(testDoubleEllipses:compile(Config,?PER,[optimize])),
+ ?line ?per_bit_opt(testDoubleEllipses:main(?PER)),
+ ?line ?uper_bin(testDoubleEllipses:compile(Config,uper_bin,[])),
+ ?line ?uper_bin(testDoubleEllipses:main(uper_bin)),
+ ?line testDoubleEllipses:compile(Config,?PER,?per_optimize(?BER)),
+ ?line testDoubleEllipses:main(?PER).
+
+test_modified_x420(suite) -> [];
+test_modified_x420(Config) ->
+ ?line test_modified_x420:compile(Config),
+ ?line test_modified_x420:test_io(Config).
+
+testX420(suite) -> [];
+testX420(Config) ->
+ ?line testX420:compile(?BER,[der],Config),
+ ?line ok = testX420:ticket7759(?BER,Config),
+ ?line testX420:compile(?PER,[],Config).
+
+test_x691(suite) -> [];
+test_x691(Config) ->
+ case ?PER of
+ per ->
+ ?line ok = test_x691:compile(Config,uper_bin,[]),
+ ?line true = test_x691:cases(uper_bin,unaligned),
+ ?line ok = test_x691:compile(Config,?PER,[]),
+ ?line true = test_x691:cases(?PER,aligned),
+%% ?line ok = asn1_test_lib:ticket_7678(Config,[]),
+ ?line ok = asn1_test_lib:ticket_7708(Config,[]),
+ ?line ok = asn1_test_lib:ticket_7763(Config);
+ _ ->
+ ?line ok = test_x691:compile(Config,?PER,?per_optimize(?BER)),
+ ?line true = test_x691:cases(?PER,aligned)
+ end.
+%% ?line ok = asn1_test_lib:ticket_7876(Config,?PER,[]),
+%% ?line ok = asn1_test_lib:ticket_7876(Config,?PER,[compact_bit_string]),
+%% ?line ok = asn1_test_lib:ticket_7876(Config,?PER,[optimize]),
+%% ?line ok = asn1_test_lib:ticket_7876(Config,?PER,[optimize,compact_bit_string]).
+
+
+ticket_6143(suite) -> [];
+ticket_6143(Config) ->
+ ?line ok = test_compile_options:ticket_6143(Config).
+
+testExtensionAdditionGroup(suite) -> [];
+testExtensionAdditionGroup(Config) ->
+ ?line DataDir = ?config(data_dir,Config),
+ ?line PrivDir = ?config(priv_dir,Config),
+ ?line Path = code:get_path(),
+ ?line code:add_patha(PrivDir),
+ DoIt = fun(Erule) ->
+ ?line ok = asn1ct:compile(filename:join(DataDir,"Extension-Addition-Group"),Erule ++ [{outdir,PrivDir}]),
+ ?line {ok,_M} = compile:file(filename:join(DataDir,"extensionAdditionGroup"),[{i,PrivDir},{outdir,PrivDir},debug_info]),
+ ?line ok = extensionAdditionGroup:run(Erule),
+ ?line ok = extensionAdditionGroup:run2(Erule),
+ ?line ok = asn1ct:compile(filename:join(DataDir,"EUTRA-RRC-Definitions"),Erule ++ [{record_name_prefix,"RRC-"},{outdir,PrivDir}]),
+ ?line ok = extensionAdditionGroup:run3(Erule)
+ end,
+ ?line [DoIt(Rule)|| Rule <- [[per_bin],[per_bin,optimize],[uper_bin]]],
+ %% FIXME problems with automatic tags [ber_bin],[ber_bin,optimize]
+ ?line code:set_path(Path).
+
+
+
+% parse_modules() ->
+% ["ImportsFrom"].
+
+per_modules() ->
+ [X || X <- test_modules()].
+ber_modules() ->
+ [X || X <- test_modules(),
+ X =/= "CommonDataTypes",
+ X =/= "DS-EquipmentUser-CommonFunctionOrig-TransmissionPath",
+ X =/= "H323-MESSAGES",
+ X =/= "H235-SECURITY-MESSAGES",
+ X =/= "MULTIMEDIA-SYSTEM-CONTROL"].
+test_modules() ->
+ _Modules = [
+ "BitStr",
+ "CommonDataTypes",
+ "Constraints",
+ "ContextSwitchingTypes",
+ "DS-EquipmentUser-CommonFunctionOrig-TransmissionPath",
+ "Enum",
+ "From",
+ "H235-SECURITY-MESSAGES",
+ "H323-MESSAGES",
+ %%"MULTIMEDIA-SYSTEM-CONTROL", recursive type , problem for asn1ct:value
+ "Import",
+ "Int",
+ "MAP-commonDataTypes",
+% ambigous tags "MAP-insertSubscriberData-def",
+ "Null",
+ "Octetstr",
+ "One",
+ "P-Record",
+ "P",
+% "PDUs",
+ "Person",
+ "PrimStrings",
+ "Real",
+ "XSeq",
+ "XSeqOf",
+ "XSet",
+ "XSetOf",
+ "String",
+ "SwCDR",
+% "Syntax",
+ "Time"
+% ANY "Tst",
+% "Two",
+% errors that should be detected "UndefType"
+] ++
+ [
+ "SeqSetLib", % must be compiled before Seq and Set
+ "Seq",
+ "Set",
+ "SetOf",
+ "SeqOf",
+ "Prim",
+ "Cho",
+ "Def",
+ "Opt",
+ "ELDAPv3",
+ "LDAP"
+ ].
+
+
diff --git a/lib/asn1/test/asn1_SUITE_data/AA1.asn b/lib/asn1/test/asn1_SUITE_data/AA1.asn
new file mode 100644
index 0000000000..c2c20f17a1
--- /dev/null
+++ b/lib/asn1/test/asn1_SUITE_data/AA1.asn
@@ -0,0 +1,13 @@
+AA1 DEFINITIONS AUTOMATIC TAGS ::=
+
+BEGIN
+
+IMPORTS
+ B
+ FROM AA2;
+
+T1 ::= SEQUENCE (SIZE (1..10)) OF B
+T2 ::= SEQUENCE (SIZE (1..10)) OF B
+T3 ::= SEQUENCE (SIZE (1..10)) OF INTEGER
+
+END \ No newline at end of file
diff --git a/lib/asn1/test/asn1_SUITE_data/AA2.asn1db b/lib/asn1/test/asn1_SUITE_data/AA2.asn1db
new file mode 100644
index 0000000000..163dbb032d
--- /dev/null
+++ b/lib/asn1/test/asn1_SUITE_data/AA2.asn1db
Binary files differ
diff --git a/lib/asn1/test/asn1_SUITE_data/BadEnumValue1.asn b/lib/asn1/test/asn1_SUITE_data/BadEnumValue1.asn
new file mode 100644
index 0000000000..dbc224a74b
--- /dev/null
+++ b/lib/asn1/test/asn1_SUITE_data/BadEnumValue1.asn
@@ -0,0 +1,8 @@
+BadEnumValue1 DEFINITIONS AUTOMATIC TAGS ::=
+
+BEGIN
+
+E3 ::= ENUMERATED {monday,thuesday(0)}
+enumWrongVal E3 ::= sunday
+
+END
diff --git a/lib/asn1/test/asn1_SUITE_data/BadTypeEnding.asn b/lib/asn1/test/asn1_SUITE_data/BadTypeEnding.asn
new file mode 100644
index 0000000000..3ccd838ac0
--- /dev/null
+++ b/lib/asn1/test/asn1_SUITE_data/BadTypeEnding.asn
@@ -0,0 +1,6 @@
+BadTypeEnding DEFINITIONS ::=
+BEGIN
+
+T ::= Typ;
+
+END
diff --git a/lib/asn1/test/asn1_SUITE_data/BadValueAssignment1.asn1 b/lib/asn1/test/asn1_SUITE_data/BadValueAssignment1.asn1
new file mode 100644
index 0000000000..a5d4984e60
--- /dev/null
+++ b/lib/asn1/test/asn1_SUITE_data/BadValueAssignment1.asn1
@@ -0,0 +1,8 @@
+BadValueAssignment1 DEFINITIONS ::=
+BEGIN
+
+int INTEGER ::= 3
+
+int2 integer ::= 3
+
+END
diff --git a/lib/asn1/test/asn1_SUITE_data/BadValueAssignment2.asn1 b/lib/asn1/test/asn1_SUITE_data/BadValueAssignment2.asn1
new file mode 100644
index 0000000000..7a96406001
--- /dev/null
+++ b/lib/asn1/test/asn1_SUITE_data/BadValueAssignment2.asn1
@@ -0,0 +1,8 @@
+BadValueAssignment2 DEFINITIONS ::=
+BEGIN
+
+int INTEGER ::= 3
+
+int2 ::= 3
+
+END
diff --git a/lib/asn1/test/asn1_SUITE_data/BadValueSet.asn1 b/lib/asn1/test/asn1_SUITE_data/BadValueSet.asn1
new file mode 100644
index 0000000000..68bd4380b7
--- /dev/null
+++ b/lib/asn1/test/asn1_SUITE_data/BadValueSet.asn1
@@ -0,0 +1,9 @@
+BadValueSet DEFINITIONS ::=
+BEGIN
+
+Int INTEGER ::= {1|2|3}
+
+Int2 INTEGER ::= {
+ 1,2,3}
+
+END
diff --git a/lib/asn1/test/asn1_SUITE_data/BitStr.py b/lib/asn1/test/asn1_SUITE_data/BitStr.py
new file mode 100644
index 0000000000..1d5bc21fda
--- /dev/null
+++ b/lib/asn1/test/asn1_SUITE_data/BitStr.py
@@ -0,0 +1,56 @@
+BitStr DEFINITIONS ::=
+BEGIN
+
+-- F.2.5.1
+-- Use a bit string type to model binary data whose format and
+-- length are unspecified,
+-- or specified elsewhere, and whose length in bits is not necessarily
+-- a multiple of eight.
+-- EXAMPLE
+
+G3FacsimilePage ::= BIT STRING
+-- a sequence of bits conforming to Recommendation T.4.
+
+image G3FacsimilePage ::= '100110100100001110110'B
+trailer BIT STRING ::= '0123456789ABCDEF'H
+body1 G3FacsimilePage ::= '1101'B
+body2 G3FacsimilePage ::= '1101000'B
+
+-- F.2.5.2
+-- Use a bit string type with a size constraint to model the
+-- values of a fixed sized bit field.
+-- EXAMPLE
+
+BitField ::= BIT STRING (SIZE (12))
+map1 BitField ::= '100110100100'B
+map2 BitField ::= '9A4'H
+map3 BitField ::= '1001101001'B -- Illegal - violates size constraint
+
+-- F.2.5.3
+-- Use a bit string type to model the values of a bit map, an
+-- ordered collection of logical variables
+-- indicating whether a particular condition holds for each of a
+-- correspondingly ordered collection of objects.
+
+DaysOfTheWeek ::= BIT STRING {
+ sunday(0), monday (1), tuesday(2),
+ wednesday(3), thursday(4), friday(5),
+ saturday(6) } (SIZE (0..7))
+
+sunnyDaysLastWeek1 DaysOfTheWeek ::= {sunday, monday, wednesday}
+sunnyDaysLastWeek2 DaysOfTheWeek ::= '1101'B
+sunnyDaysLastWeek3 DaysOfTheWeek ::= '1101000'B
+sunnyDaysLastWeek4 DaysOfTheWeek ::= '11010000'B -- Illegal - violates size constraint
+
+-- F.2.5.5
+-- Use a bit string type with named bits to model the values of a
+-- collection of related logical variables.
+-- EXAMPLE
+
+PersonalStatus ::= BIT STRING
+ {married(0), employed(1), veteran(2), collegeGraduate(3)}
+
+billClinton PersonalStatus ::= {married, employed, collegeGraduate}
+hillaryClinton PersonalStatus ::= '110100'B
+
+END
diff --git a/lib/asn1/test/asn1_SUITE_data/CCSNARG3.asn b/lib/asn1/test/asn1_SUITE_data/CCSNARG3.asn
new file mode 100644
index 0000000000..23c1f32ceb
--- /dev/null
+++ b/lib/asn1/test/asn1_SUITE_data/CCSNARG3.asn
@@ -0,0 +1,345 @@
+CCSNARG3 DEFINITIONS IMPLICIT TAGS ::=
+BEGIN
+
+CallCentreServiceNotificationArg ::= SEQUENCE {
+ scriptInformation [0] ScriptToScriptInformation,
+ eventInformation [1] IMPLICIT EventInformation OPTIONAL
+
+
+}
+
+EventInformation ::=
+ CHOICE
+ { callEvent [0] CallEvent,
+ billingReport [1] BillingInformation
+ }
+
+
+ScriptToScriptInformation ::= SEQUENCE {
+ scriptKey [0] INTEGER (0..214783647),
+ scriptAttribute1 [1] Attribute1 OPTIONAL,
+ scriptAttribute2 [2] Attribute2 OPTIONAL,
+ scriptAttribute3 [3] Attribute3 OPTIONAL,
+ scriptAttribute4 [4] Attribute4 OPTIONAL,
+ scriptAttribute5 [5] Attribute5 OPTIONAL,
+ scriptAttribute6 [6] Attribute6 OPTIONAL,
+ scriptAttribute7 [7] Attribute7 OPTIONAL,
+ scriptAttribute8 [8] Attribute8 OPTIONAL,
+ scriptAttribute9 [9] Attribute9 OPTIONAL,
+ scriptAttribute10 [10] Attribute10 OPTIONAL,
+ scriptAttribute11 [11] Attribute11 OPTIONAL,
+ scriptAttribute12 [12] Attribute12 OPTIONAL,
+ scriptAttribute13 [13] Attribute13 OPTIONAL,
+ scriptAttribute14 [14] Attribute14 OPTIONAL,
+ scriptAttribute15 [15] Attribute15 OPTIONAL,
+ scriptAttribute16 [16] Attribute16 OPTIONAL,
+ scriptAttribute17 [17] Attribute17 OPTIONAL,
+ scriptAttribute18 [18] Attribute18 OPTIONAL,
+ scriptAttribute19 [19] Attribute19 OPTIONAL,
+ scriptAttribute20 [20] Attribute20 OPTIONAL,
+ scriptAttribute21 [21] Attribute21 OPTIONAL,
+ scriptAttribute22 [22] Attribute22 OPTIONAL,
+ scriptAttribute23 [23] Attribute23 OPTIONAL,
+ scriptAttribute24 [24] Attribute24 OPTIONAL,
+ scriptAttribute25 [25] Attribute25 OPTIONAL,
+ scriptAttribute26 [26] Attribute26 OPTIONAL,
+ scriptAttribute27 [27] Attribute27 OPTIONAL,
+ scriptAttribute28 [28] Attribute28 OPTIONAL,
+ scriptAttribute29 [29] Attribute29 OPTIONAL,
+ scriptAttribute30 [30] Attribute30 OPTIONAL
+ }
+
+
+CallEvent ::= SEQUENCE {
+ eventTypeBCSM [0] EventTypeBCSM OPTIONAL,
+
+ miscCallInfo [1] MiscCallInfo OPTIONAL,
+ iNlegID [2] LegType OPTIONAL,
+ announcementInfo [3] INTEGER
+ { announcementstarted(0), announcementcompleted(1) } (0..1) OPTIONAL,
+ callAttemptElapsedTimeValue [4] INTEGER (0..255) OPTIONAL,
+ callStopTimeValue [5] DateAndTime OPTIONAL,
+ callConnectedElapsedTimeValue [6] INTEGER (0..4294967295) OPTIONAL,
+ calledAddressValue [7] GenericNumber OPTIONAL,
+ releaseCause [8] Cause OPTIONAL
+ }
+
+EventTypeBCSM ::= INTEGER {
+ origAttemptauthorized(1),
+ collectedInfo(2),
+ analyzedInformation(3),
+ routeSelectFailure(4),
+ oCalledPartyBusy(5),
+ oAlerting(255),
+ oCalledPartyNotReachable(254),
+ oNoAnswer(6),
+ oAnswer(7),
+ oMidCall(8),
+ oSuspended(253),
+ oReAnswer(252),
+ oDisconnect(9),
+ oAbandon(10),
+ termAttemptauthorized(12)
+ } (0..255)
+
+
+BackwardCallIndicators ::= OCTET STRING (SIZE (2))
+
+BackwardGVNSIndicator ::= OCTET STRING(SIZE(1))
+
+
+MiscCallInfo::= INTEGER {
+ request (0),
+ notification (1)
+ } (0..1)
+
+LegType ::= INTEGER (1..30)
+
+DateAndTime ::= OCTET STRING (SIZE(6))
+
+GenericNumber ::= OCTET STRING (SIZE(1..16))
+
+GenericDigits ::= OCTET STRING (SIZE(1..16))
+
+Number ::= OCTET STRING (SIZE(1..16))
+
+Cause::= OCTET STRING (SIZE(2))
+
+
+BillingInformation ::= SEQUENCE {
+ billingKey [0] INTEGER (0..214783647),
+ billingAttribute1 [1] Attribute1 OPTIONAL,
+ billingAttribute2 [2] Attribute2 OPTIONAL,
+ billingAttribute3 [3] Attribute3 OPTIONAL,
+ billingAttribute4 [4] Attribute4 OPTIONAL,
+ billingAttribute5 [5] Attribute5 OPTIONAL,
+ billingAttribute6 [6] Attribute6 OPTIONAL,
+ billingAttribute7 [7] Attribute7 OPTIONAL,
+ billingAttribute8 [8] Attribute8 OPTIONAL,
+ billingAttribute9 [9] Attribute9 OPTIONAL,
+ billingAttribute10 [10] Attribute10 OPTIONAL,
+ billingAttribute11 [11] Attribute11 OPTIONAL,
+ billingAttribute12 [12] Attribute12 OPTIONAL,
+ billingAttribute13 [13] Attribute13 OPTIONAL,
+ billingAttribute14 [14] Attribute14 OPTIONAL,
+ billingAttribute15 [15] Attribute15 OPTIONAL,
+ billingAttribute16 [16] Attribute16 OPTIONAL,
+ billingAttribute17 [17] Attribute17 OPTIONAL,
+ billingAttribute18 [18] Attribute18 OPTIONAL,
+ billingAttribute19 [19] Attribute19 OPTIONAL,
+ billingAttribute20 [20] Attribute20 OPTIONAL
+}
+
+
+Attribute1 ::= CHOICE {
+ integerValue [0] INTEGER (0..65535),
+ longIntValue [1] INTEGER (0..4294967295),
+ numberValue [2] Number,
+ genDigitValue [3] GenericDigits
+ }
+
+Attribute2 ::= CHOICE {
+ integerValue [0] INTEGER (0..65535),
+ longIntValue [1] INTEGER (0..4294967295),
+ numberValue [2] Number,
+ genDigitValue [3] GenericDigits
+ }
+
+Attribute3 ::= CHOICE {
+ integerValue [0] INTEGER (0..65535),
+ longIntValue [1] INTEGER (0..4294967295),
+ numberValue [2] Number,
+ genDigitValue [3] GenericDigits
+ }
+
+Attribute4 ::= CHOICE {
+ integerValue [0] INTEGER (0..65535),
+ longIntValue [1] INTEGER (0..4294967295),
+ numberValue [2] Number,
+ genDigitValue [3] GenericDigits
+ }
+
+Attribute5 ::= CHOICE {
+ integerValue [0] INTEGER (0..65535),
+ longIntValue [1] INTEGER (0..4294967295),
+ numberValue [2] Number,
+ genDigitValue [3] GenericDigits
+ }
+
+Attribute6 ::= CHOICE {
+ integerValue [0] INTEGER (0..65535),
+ longIntValue [1] INTEGER (0..4294967295),
+ numberValue [2] Number,
+ genDigitValue [3] GenericDigits
+ }
+
+Attribute7 ::= CHOICE {
+ integerValue [0] INTEGER (0..65535),
+ longIntValue [1] INTEGER (0..4294967295),
+ numberValue [2] Number,
+ genDigitValue [3] GenericDigits
+ }
+
+Attribute8 ::= CHOICE {
+ integerValue [0] INTEGER (0..65535),
+ longIntValue [1] INTEGER (0..4294967295),
+ numberValue [2] Number,
+ genDigitValue [3] GenericDigits
+ }
+
+Attribute9 ::= CHOICE {
+ integerValue [0] INTEGER (0..65535),
+ longIntValue [1] INTEGER (0..4294967295),
+ numberValue [2] Number,
+ genDigitValue [3] GenericDigits
+ }
+
+Attribute10 ::= CHOICE {
+ integerValue [0] INTEGER (0..65535),
+ longIntValue [1] INTEGER (0..4294967295),
+ numberValue [2] Number,
+ genDigitValue [3] GenericDigits
+ }
+
+Attribute11 ::= CHOICE {
+ integerValue [0] INTEGER (0..65535),
+ longIntValue [1] INTEGER (0..4294967295),
+ numberValue [2] Number,
+ genDigitValue [3] GenericDigits
+ }
+
+Attribute12 ::= CHOICE {
+ integerValue [0] INTEGER (0..65535),
+ longIntValue [1] INTEGER (0..4294967295),
+ numberValue [2] Number,
+ genDigitValue [3] GenericDigits
+ }
+
+Attribute13::= CHOICE {
+ integerValue [0] INTEGER (0..65535),
+ longIntValue [1] INTEGER (0..4294967295),
+ numberValue [2] Number,
+ genDigitValue [3] GenericDigits
+ }
+
+Attribute14 ::= CHOICE {
+ integerValue [0] INTEGER (0..65535),
+ longIntValue [1] INTEGER (0..4294967295),
+ numberValue [2] Number,
+ genDigitValue [3] GenericDigits
+ }
+
+Attribute15 ::= CHOICE {
+ integerValue [0] INTEGER (0..65535),
+ longIntValue [1] INTEGER (0..4294967295),
+ numberValue [2] Number,
+ genDigitValue [3] GenericDigits
+ }
+
+Attribute16 ::= CHOICE {
+ integerValue [0] INTEGER (0..65535),
+ longIntValue [1] INTEGER (0..4294967295),
+ numberValue [2] Number,
+ genDigitValue [3] GenericDigits
+ }
+
+Attribute17 ::= CHOICE {
+ integerValue [0] INTEGER (0..65535),
+ longIntValue [1] INTEGER (0..4294967295),
+ numberValue [2] Number,
+ genDigitValue [3] GenericDigits
+ }
+
+Attribute18 ::= CHOICE {
+ integerValue [0] INTEGER (0..65535),
+ longIntValue [1] INTEGER (0..4294967295),
+ numberValue [2] Number,
+ genDigitValue [3] GenericDigits
+ }
+
+Attribute19::= CHOICE {
+ integerValue [0] INTEGER (0..65535),
+ longIntValue [1] INTEGER (0..4294967295),
+ numberValue [2] Number,
+ genDigitValue [3] GenericDigits
+ }
+
+Attribute20 ::= CHOICE {
+ integerValue [0] INTEGER (0..65535),
+ longIntValue [1] INTEGER (0..4294967295),
+ numberValue [2] Number,
+ genDigitValue [3] GenericDigits
+ }
+
+Attribute21 ::= CHOICE {
+ integerValue [0] INTEGER (0..65535),
+ longIntValue [1] INTEGER (0..4294967295),
+ numberValue [2] Number,
+ genDigitValue [3] GenericDigits
+ }
+
+Attribute22 ::= CHOICE {
+ integerValue [0] INTEGER (0..65535),
+ longIntValue [1] INTEGER (0..4294967295),
+ numberValue [2] Number,
+ genDigitValue [3] GenericDigits
+ }
+
+Attribute23 ::= CHOICE {
+ integerValue [0] INTEGER (0..65535),
+ longIntValue [1] INTEGER (0..4294967295),
+ numberValue [2] Number,
+ genDigitValue [3] GenericDigits
+ }
+
+Attribute24 ::= CHOICE {
+ integerValue [0] INTEGER (0..65535),
+ longIntValue [1] INTEGER (0..4294967295),
+ numberValue [2] Number,
+ genDigitValue [3] GenericDigits
+ }
+
+Attribute25 ::= CHOICE {
+ integerValue [0] INTEGER (0..65535),
+ longIntValue [1] INTEGER (0..4294967295),
+ numberValue [2] Number,
+ genDigitValue [3] GenericDigits
+ }
+
+Attribute26 ::= CHOICE {
+ integerValue [0] INTEGER (0..65535),
+ longIntValue [1] INTEGER (0..4294967295),
+ numberValue [2] Number,
+ genDigitValue [3] GenericDigits
+ }
+
+Attribute27::= CHOICE {
+ integerValue [0] INTEGER (0..65535),
+ longIntValue [1] INTEGER (0..4294967295),
+ numberValue [2] Number,
+ genDigitValue [3] GenericDigits
+ }
+
+Attribute28 ::= CHOICE {
+ integerValue [0] INTEGER (0..65535),
+ longIntValue [1] INTEGER (0..4294967295),
+ numberValue [2] Number,
+ genDigitValue [3] GenericDigits
+ }
+
+Attribute29 ::= CHOICE {
+ integerValue [0] INTEGER (0..65535),
+ longIntValue [1] INTEGER (0..4294967295),
+ numberValue [2] Number,
+ genDigitValue [3] GenericDigits
+ }
+
+Attribute30 ::= CHOICE {
+ integerValue [0] INTEGER (0..65535),
+ longIntValue [1] INTEGER (0..4294967295),
+ numberValue [2] Number,
+ genDigitValue [3] GenericDigits
+ }
+
+
+END
diff --git a/system/doc/images/.gitignore b/lib/asn1/test/asn1_SUITE_data/Certificate.asn
index e69de29bb2..e69de29bb2 100644
--- a/system/doc/images/.gitignore
+++ b/lib/asn1/test/asn1_SUITE_data/Certificate.asn
diff --git a/lib/asn1/test/asn1_SUITE_data/Cho.py b/lib/asn1/test/asn1_SUITE_data/Cho.py
new file mode 100644
index 0000000000..c390eed2ba
--- /dev/null
+++ b/lib/asn1/test/asn1_SUITE_data/Cho.py
@@ -0,0 +1,27 @@
+Cho DEFINITIONS IMPLICIT TAGS ::=
+
+BEGIN
+
+ChoCon ::= CHOICE
+{
+ nested Cho2,
+ bool0 [0] BOOLEAN,
+ bool1 [1] BOOLEAN,
+ int2 [2] INTEGER
+}
+
+ChoExp ::= CHOICE
+{
+ int10 [APPLICATION 10] EXPLICIT INTEGER {first(1),last(31)},
+ bool11 [APPLICATION 11] EXPLICIT BOOLEAN,
+ enum12 [APPLICATION 12] EXPLICIT ENUMERATED {one(1),two(2),three(3)}
+}
+
+Cho2 ::= CHOICE
+{
+ i INTEGER,
+ b BOOLEAN
+}
+
+
+END
diff --git a/lib/asn1/test/asn1_SUITE_data/ChoExtension.asn1 b/lib/asn1/test/asn1_SUITE_data/ChoExtension.asn1
new file mode 100644
index 0000000000..18473bae30
--- /dev/null
+++ b/lib/asn1/test/asn1_SUITE_data/ChoExtension.asn1
@@ -0,0 +1,44 @@
+ChoExtension DEFINITIONS IMPLICIT TAGS ::=
+
+BEGIN
+
+
+ChoExt1 ::= CHOICE
+{
+ bool BOOLEAN,
+ int INTEGER,
+ ...
+}
+
+ChoExt1x ::= CHOICE
+{
+ bool BOOLEAN,
+ int INTEGER,
+ ...,
+ str OCTET STRING
+}
+
+ChoExt2 ::= CHOICE
+{
+ bool BOOLEAN,
+ ...,
+ int INTEGER
+}
+
+ChoExt3 ::= CHOICE
+{
+ str OCTET STRING,
+-- ...,
+ bool BOOLEAN,
+ int INTEGER
+}
+
+ChoExt4 ::= CHOICE
+{
+ bool BOOLEAN,
+ int INTEGER,
+ ...,
+ str OCTET STRING
+}
+
+END
diff --git a/lib/asn1/test/asn1_SUITE_data/ChoExternal.asn1 b/lib/asn1/test/asn1_SUITE_data/ChoExternal.asn1
new file mode 100644
index 0000000000..950579a620
--- /dev/null
+++ b/lib/asn1/test/asn1_SUITE_data/ChoExternal.asn1
@@ -0,0 +1,40 @@
+ChoExternal DEFINITIONS IMPLICIT TAGS ::=
+
+BEGIN
+
+IMPORTS XSeq1, XCho, XBool, XBoolImp, XBoolExp, XChoNT, XChoExp FROM External;
+
+
+
+ChoXCho ::= XCho
+
+ChoXBool ::= CHOICE
+{
+ xbool XBool,
+ xboolImp XBoolImp,
+ xboolExp XBoolExp
+}
+
+
+
+NT ::= CHOICE {
+ os OCTET STRING,
+ bool BOOLEAN}
+Exp ::= [2] EXPLICIT CHOICE {
+ os OCTET STRING,
+ bool BOOLEAN}
+
+NTNT ::= NT
+ExpNT ::= [4] EXPLICIT NT
+
+NTExp ::= Exp
+ExpExp ::= [8] EXPLICIT Exp
+
+XNTNT ::= XChoNT
+XExpNT ::= [4] EXPLICIT XChoNT
+
+XNTExp ::= XChoExp
+XExpExp ::= [8] EXPLICIT XChoExp
+
+
+END
diff --git a/lib/asn1/test/asn1_SUITE_data/ChoOptional.asn1 b/lib/asn1/test/asn1_SUITE_data/ChoOptional.asn1
new file mode 100644
index 0000000000..18f45b645c
--- /dev/null
+++ b/lib/asn1/test/asn1_SUITE_data/ChoOptional.asn1
@@ -0,0 +1,35 @@
+ChoOptional DEFINITIONS IMPLICIT TAGS ::=
+
+BEGIN
+
+
+Seq1 ::= SEQUENCE
+{
+ bool BOOLEAN,
+ int INTEGER OPTIONAL,
+ cho ChoOpt OPTIONAL
+}
+
+Seq2 ::= SEQUENCE
+{
+ int INTEGER OPTIONAL,
+ cho ChoOpt OPTIONAL,
+ bool BOOLEAN
+}
+
+Seq3 ::= SEQUENCE
+{
+ cho ChoOpt OPTIONAL,
+ int INTEGER OPTIONAL,
+ bool BOOLEAN
+}
+
+
+ChoOpt ::= CHOICE
+{
+ vsCho VisibleString,
+ ocStrCho OCTET STRING
+}
+
+
+END
diff --git a/lib/asn1/test/asn1_SUITE_data/ChoOptionalImplicitTag.asn1 b/lib/asn1/test/asn1_SUITE_data/ChoOptionalImplicitTag.asn1
new file mode 100644
index 0000000000..251f682ddc
--- /dev/null
+++ b/lib/asn1/test/asn1_SUITE_data/ChoOptionalImplicitTag.asn1
@@ -0,0 +1,35 @@
+ChoOptionalImplicitTag DEFINITIONS IMPLICIT TAGS ::=
+
+BEGIN
+
+
+Seq1 ::= SEQUENCE
+{
+ bool [0] BOOLEAN,
+ int [1] INTEGER OPTIONAL,
+ cho [7] ChoOpt OPTIONAL
+}
+
+Seq2 ::= SEQUENCE
+{
+ int INTEGER OPTIONAL,
+ cho ChoOpt OPTIONAL,
+ bool BOOLEAN
+}
+
+Seq3 ::= SEQUENCE
+{
+ cho ChoOpt OPTIONAL,
+ int INTEGER OPTIONAL,
+ bool BOOLEAN
+}
+
+
+ChoOpt ::= CHOICE
+{
+ vsCho [2] VisibleString,
+ ocStrCho [3] OCTET STRING
+}
+
+
+END
diff --git a/lib/asn1/test/asn1_SUITE_data/ChoPrim.asn1 b/lib/asn1/test/asn1_SUITE_data/ChoPrim.asn1
new file mode 100644
index 0000000000..984694ced8
--- /dev/null
+++ b/lib/asn1/test/asn1_SUITE_data/ChoPrim.asn1
@@ -0,0 +1,20 @@
+ChoPrim DEFINITIONS IMPLICIT TAGS ::=
+
+BEGIN
+
+
+ChoCon ::= CHOICE
+{
+ bool0 [0] BOOLEAN,
+ bool1 [1] BOOLEAN,
+ int2 [2] INTEGER
+}
+
+ChoExp ::= CHOICE
+{
+ int10 [APPLICATION 10] EXPLICIT INTEGER {first(1),last(31)},
+ bool11 [APPLICATION 11] EXPLICIT BOOLEAN,
+ enum12 [APPLICATION 12] EXPLICIT ENUMERATED {one(1),two(2),three(3)}
+}
+
+END
diff --git a/lib/asn1/test/asn1_SUITE_data/ChoRecursive.asn1 b/lib/asn1/test/asn1_SUITE_data/ChoRecursive.asn1
new file mode 100644
index 0000000000..f0fe2f629c
--- /dev/null
+++ b/lib/asn1/test/asn1_SUITE_data/ChoRecursive.asn1
@@ -0,0 +1,30 @@
+ChoRecursive DEFINITIONS IMPLICIT TAGS ::=
+
+BEGIN
+
+
+ChoRec ::= CHOICE
+{
+ nothing [0] NULL,
+ something SEQUENCE
+ {
+ a INTEGER,
+ b OCTET STRING,
+ c ChoRec
+ }
+}
+
+ChoRec2 ::= CHOICE
+{
+ something SEQUENCE
+ {
+ a INTEGER,
+ b OCTET STRING,
+ c ChoRec2
+ },
+ nothing [0] NULL
+}
+
+
+
+END
diff --git a/lib/asn1/test/asn1_SUITE_data/ChoTypeRefCho.asn1 b/lib/asn1/test/asn1_SUITE_data/ChoTypeRefCho.asn1
new file mode 100644
index 0000000000..bcbf5045cd
--- /dev/null
+++ b/lib/asn1/test/asn1_SUITE_data/ChoTypeRefCho.asn1
@@ -0,0 +1,44 @@
+ChoTypeRefCho DEFINITIONS IMPLICIT TAGS ::=
+
+BEGIN
+
+
+
+ChoTRcho ::= CHOICE
+{
+ choCho ChoChoNT,
+ choChoE [145] EXPLICIT ChoChoNT,
+
+ choCho-E ChoChoExp,
+ choChoE-E [345] EXPLICIT ChoChoExp
+
+}
+
+ChoChoNT ::= CHOICE {
+ choInt INTEGER,
+ choOs OCTET STRING
+ }
+
+ChoChoExp ::= [75] EXPLICIT CHOICE {
+ choInt INTEGER,
+ choOs OCTET STRING
+ }
+
+
+
+ChoChoInline ::= CHOICE
+{
+ bool1 [0] BOOLEAN,
+ choCho CHOICE
+ {
+ bool BOOLEAN,
+ octStr OctStr,
+ int INTEGER
+ }
+}
+
+OctStr ::= OCTET STRING
+
+
+
+END
diff --git a/lib/asn1/test/asn1_SUITE_data/ChoTypeRefPrim.asn1 b/lib/asn1/test/asn1_SUITE_data/ChoTypeRefPrim.asn1
new file mode 100644
index 0000000000..ed6095f769
--- /dev/null
+++ b/lib/asn1/test/asn1_SUITE_data/ChoTypeRefPrim.asn1
@@ -0,0 +1,34 @@
+ChoTypeRefPrim DEFINITIONS IMPLICIT TAGS ::=
+
+BEGIN
+
+ChoTR ::= CHOICE
+{
+ bool BOOLEAN,
+ octStr OctStr,
+ int INTEGER
+}
+
+
+ChoTR2 ::= CHOICE
+{
+ octStr OctStr,
+ octStrI [114] OctStr,
+ octStrE [115] EXPLICIT OctStr,
+
+ octStr-I OctStrImp,
+ octStrI-I [214] OctStrImp,
+ octStrE-I [215] EXPLICIT OctStrImp,
+
+ octStr-E OctStrExp,
+ octStrI-E [314] OctStrExp,
+ octStrE-E [315] EXPLICIT OctStrExp
+
+}
+
+OctStr ::= OCTET STRING
+OctStrImp ::= [14] OCTET STRING
+OctStrExp ::= [15] EXPLICIT OCTET STRING
+
+END
+
diff --git a/lib/asn1/test/asn1_SUITE_data/ChoTypeRefSeq.asn1 b/lib/asn1/test/asn1_SUITE_data/ChoTypeRefSeq.asn1
new file mode 100644
index 0000000000..f9b5cbf85f
--- /dev/null
+++ b/lib/asn1/test/asn1_SUITE_data/ChoTypeRefSeq.asn1
@@ -0,0 +1,37 @@
+ChoTypeRefSeq DEFINITIONS IMPLICIT TAGS ::=
+
+BEGIN
+
+
+ChoTRseq ::= CHOICE
+{
+ choSeq ChoSeq,
+ choSeqI [134] ChoSeq,
+ choSeqE [135] EXPLICIT ChoSeq,
+
+ choSeq-I ChoSeqImp,
+ choSeqI-I [234] ChoSeqImp,
+ choSeqE-I [235] EXPLICIT ChoSeqImp,
+
+ choSeq-E ChoSeqExp,
+ choSeqI-E [334] ChoSeqExp,
+ choSeqE-E [335] EXPLICIT ChoSeqExp
+
+}
+
+ChoSeq ::= SEQUENCE {
+ seqInt INTEGER,
+ seqOs OCTET STRING
+ }
+
+ChoSeqImp ::= [64] SEQUENCE {
+ seqInt INTEGER,
+ seqOs OCTET STRING
+ }
+
+ChoSeqExp ::= [65] EXPLICIT SEQUENCE {
+ seqInt INTEGER,
+ seqOs OCTET STRING
+ }
+
+END
diff --git a/lib/asn1/test/asn1_SUITE_data/ChoTypeRefSet.asn1 b/lib/asn1/test/asn1_SUITE_data/ChoTypeRefSet.asn1
new file mode 100644
index 0000000000..7d8da3f90d
--- /dev/null
+++ b/lib/asn1/test/asn1_SUITE_data/ChoTypeRefSet.asn1
@@ -0,0 +1,37 @@
+ChoTypeRefSet DEFINITIONS IMPLICIT TAGS ::=
+
+BEGIN
+
+ChoTRset ::= CHOICE
+{
+ choSet ChoSet,
+ choSetI [124] ChoSet,
+ choSetE [125] EXPLICIT ChoSet,
+
+ choSet-I ChoSetImp,
+ choSetI-I [224] ChoSetImp,
+ choSetE-I [225] EXPLICIT ChoSetImp,
+
+ choSet-E ChoSetExp,
+ choSetI-E [324] ChoSetExp,
+ choSetE-E [325] EXPLICIT ChoSetExp
+
+}
+
+ChoSet ::= SET {
+ setInt INTEGER,
+ setOs OCTET STRING
+ }
+
+ChoSetImp ::= [54] SET {
+ setInt INTEGER,
+ setOs OCTET STRING
+ }
+
+ChoSetExp ::= [55] EXPLICIT SET {
+ setInt INTEGER,
+ setOs OCTET STRING
+ }
+
+
+END
diff --git a/lib/asn1/test/asn1_SUITE_data/ChoiceBadExtension.asn1 b/lib/asn1/test/asn1_SUITE_data/ChoiceBadExtension.asn1
new file mode 100644
index 0000000000..d0789d7414
--- /dev/null
+++ b/lib/asn1/test/asn1_SUITE_data/ChoiceBadExtension.asn1
@@ -0,0 +1,27 @@
+ChoiceBadExtension DEFINITIONS ::=
+BEGIN
+
+Seq ::= SEQUENCE {
+ ...,
+ name PrintableString,
+ location INTEGER {home(0),field(1),roving(2)},
+ age INTEGER
+ }
+
+Cho1 ::= CHOICE {
+ name PrintableString,
+ ...,
+ location INTEGER {home(0),field(1),roving(2)},
+ age INTEGER
+ }
+
+Cho2 ::= CHOICE {
+ ...,
+ name PrintableString,
+ location INTEGER {home(0),field(1),roving(2)},
+ age INTEGER
+ }
+
+END
+
+
diff --git a/lib/asn1/test/asn1_SUITE_data/ChoiceInSeq.asn b/lib/asn1/test/asn1_SUITE_data/ChoiceInSeq.asn
new file mode 100644
index 0000000000..ac93226a1b
--- /dev/null
+++ b/lib/asn1/test/asn1_SUITE_data/ChoiceInSeq.asn
@@ -0,0 +1,22 @@
+ChoiceInSeq DEFINITIONS ::=
+BEGIN
+CallCentreServiceNotificationArg ::= SEQUENCE {
+ scriptInformation [0] ScriptToScriptInformation,
+ eventInformation
+ CHOICE
+ { callEvent [1] CallEvent,
+ billingReport [2] BillingInformation
+ } OPTIONAL
+}
+
+ScriptToScriptInformation ::= INTEGER
+CallEvent ::= INTEGER
+BillingInformation ::= INTEGER
+EventInformation ::=
+ CHOICE
+ { callEvent [1] CallEvent,
+ billingReport [2] BillingInformation
+ }
+
+
+END
diff --git a/lib/asn1/test/asn1_SUITE_data/ChoiceIndef.asn b/lib/asn1/test/asn1_SUITE_data/ChoiceIndef.asn
new file mode 100644
index 0000000000..71b717b621
--- /dev/null
+++ b/lib/asn1/test/asn1_SUITE_data/ChoiceIndef.asn
@@ -0,0 +1,24 @@
+ChoiceIndef DEFINITIONS IMPLICIT TAGS ::=
+
+BEGIN
+
+I ::= INTEGER
+
+Cho ::= CHOICE {
+ ca [0] I,
+ cb [1] INTEGER
+}
+
+Seq ::= SEQUENCE {
+ sa [0] Cho,
+ sb [1] INTEGER
+}
+
+-- detta varde funkar ej. fixat i OTP-4358
+-- Val4 = {'Seq',{ca,11},12}
+-- val4 = <<48,128,160,128,128,1,11,0,0,129,1,12,0,0>>
+
+
+END
+
+
diff --git a/lib/asn1/test/asn1_SUITE_data/Comment.asn b/lib/asn1/test/asn1_SUITE_data/Comment.asn
new file mode 100644
index 0000000000..c2a5abd633
--- /dev/null
+++ b/lib/asn1/test/asn1_SUITE_data/Comment.asn
@@ -0,0 +1,21 @@
+Comment DEFINITIONS AUTOMATIC TAGS ::=
+
+BEGIN
+
+/* comments as to the 2002 standard
+
+this is the new added way of commenting multile lines */
+
+/* it is also allowed to have -- old kind of comment signs inside
+this new variant. The two dashes will lose their meaning as a comment
+inside a multiline comment, /* the new type of comment may also be
+nested */ */
+
+Seq ::= SEQUENCE {
+ a INTEGER,
+ b BOOLEAN
+}
+
+/* another multiline comment, bu t on one line. */
+
+END \ No newline at end of file
diff --git a/lib/asn1/test/asn1_SUITE_data/CommonDataTypes.py b/lib/asn1/test/asn1_SUITE_data/CommonDataTypes.py
new file mode 100644
index 0000000000..2c25f81235
--- /dev/null
+++ b/lib/asn1/test/asn1_SUITE_data/CommonDataTypes.py
@@ -0,0 +1,4360 @@
+CommonDataTypes DEFINITIONS AUTOMATIC TAGS ::=
+BEGIN
+-- @prop dataType
+-- @descr This types only purpose is to avoid OSS compiler warning : Duplicate PDU tag
+-- @
+CommonDataTypeWrapper ::= CHOICE
+{
+ wrapAddAnalysisRejectReason AddAnalysisRejectReason,
+ wrapAddServiceToServiceProfileRejectReason AddServiceToServiceProfileRejectReason,
+ wrapAddUserIdentifiersRejectReason AddUserIdentifiersRejectReason,
+ wrapAdmissionRejectReason AdmissionRejectReason,
+ wrapAlertingUUIE AlertingUUIE,
+ wrapAllocateTransmissionPathRejectReason AllocateTransmissionPathRejectReason,
+ wrapAnalyseRejectReason AnalyseRejectReason,
+ wrapAvailabilityOfEquipment AvailabilityOfEquipment,
+ wrapBandwidth Bandwidth,
+ wrapBandwidthReducedInformation BandwidthReducedInformation,
+ wrapBandwidthReducedReason BandwidthReducedReason,
+ wrapBandwidthRejectReason BandwidthRejectReason,
+ wrapBasicCallCategories BasicCallCategories,
+ wrapBearerCapability BearerCapability,
+ wrapCallInformation CallInformation,
+ wrapCallModel CallModel,
+ wrapCallProceedingUUIE CallProceedingUUIE,
+ wrapCallReference CallReference,
+ wrapCallServices CallServices,
+ wrapCallState CallState,
+ wrapCallType CallType,
+ wrapCause Cause,
+ wrapCauseValue CauseValue,
+ wrapChangeServiceAndStatusRejectReason ChangeServiceAndStatusRejectReason,
+ wrapCheckServiceRejectReason CheckServiceRejectReason,
+ wrapCoding Coding,
+ wrapConferenceGoal ConferenceGoal,
+ wrapConferenceIdentifier ConferenceIdentifier,
+ wrapConnectTransmissionPathRejectReason ConnectTransmissionPathRejectReason,
+ wrapConnectUUIE ConnectUUIE,
+ wrapConnectionData ConnectionData,
+ wrapConnectionIdentifier ConnectionIdentifier,
+ wrapConnectionInformation ConnectionInformation,
+ wrapConnectionInformationOriginatingSide ConnectionInformationOriginatingSide,
+ wrapConnectionInformationTerminatingSide ConnectionInformationTerminatingSide,
+ wrapConnectionType ConnectionType,
+ wrapCreateEquipmentRepresentationRejectReason CreateEquipmentRepresentationRejectReason,
+ wrapCreateServiceAndStatusRejectReason CreateServiceAndStatusRejectReason,
+ wrapCreateServiceIdentifierRejectReason CreateServiceIdentifierRejectReason,
+ wrapDeallocateTransmissionPathRejectReason DeallocateTransmissionPathRejectReason,
+ wrapDetailedReasonAtom DetailedReasonAtom,
+ wrapDiagnostics Diagnostics,
+ wrapDisconnectTransmissionPathRejectReason DisconnectTransmissionPathRejectReason,
+ wrapDisengageReason DisengageReason,
+ wrapDisengageRejectReason DisengageRejectReason,
+ wrapDisplay Display,
+ wrapE164Identifier E164Identifier,
+ wrapEndToEndEndpointInformationServiceCallAcknowledge EndToEndEndpointInformationServiceCallAcknowledge,
+ wrapEndToEndEndpointInformationServiceCallActive EndToEndEndpointInformationServiceCallActive,
+ wrapEndToEndEndpointInformationServiceCallProgress EndToEndEndpointInformationServiceCallProgress,
+ wrapEndToEndEndpointInformationServiceCallSetup EndToEndEndpointInformationServiceCallSetup,
+ wrapEndToEndEndpointInformationServiceCallTermination EndToEndEndpointInformationServiceCallTermination,
+ wrapEndpointIdentifier EndpointIdentifier,
+ wrapEndpointRegistrationCategories EndpointRegistrationCategories,
+ wrapEndpointRegistrationRejectReason EndpointRegistrationRejectReason,
+ wrapEndpointType EndpointType,
+ wrapEndpointUnregistrationCategories EndpointUnregistrationCategories,
+ wrapEndpointUnregistrationRejectReason EndpointUnregistrationRejectReason,
+ wrapEquipmentAddressAN EquipmentAddressAN,
+ wrapEquipmentAddressLAN EquipmentAddressLAN,
+ wrapEquipmentRelatedInformation EquipmentRelatedInformation,
+ wrapEquipmentRelatedInformationIdentifier EquipmentRelatedInformationIdentifier,
+ wrapFacilityReason FacilityReason,
+ wrapFacilityUUIE FacilityUUIE,
+ wrapGatekeeperIdentifier GatekeeperIdentifier,
+ wrapGatekeeperInformation GatekeeperInformation,
+ wrapGatekeeperRejectReason GatekeeperRejectReason,
+ wrapGatewayInformation GatewayInformation,
+ wrapGetAnalysisRejectReason GetAnalysisRejectReason,
+ wrapGetEquipmentInformationRejectReason GetEquipmentInformationRejectReason,
+ wrapGetLANDataRejectReason GetLANDataRejectReason,
+ wrapGetPartyInformationRejectReason GetPartyInformationRejectReason,
+ wrapGetRejectReasonUser GetRejectReasonUser,
+ wrapGetServiceFromServiceProfileRejectReason GetServiceFromServiceProfileRejectReason,
+ wrapGetServiceProfileRejectReason GetServiceProfileRejectReason,
+ wrapGetServicesAndStatusRejectReason GetServicesAndStatusRejectReason,
+ wrapGetUserServiceInformationAndStatusRejectReason GetUserServiceInformationAndStatusRejectReason,
+ wrapH221NonStandard H221NonStandard,
+ wrapH310Information H310Information,
+ wrapH320Information H320Information,
+ wrapH321Information H321Information,
+ wrapH322Information H322Information,
+ wrapH323Information H323Information,
+ wrapH323InterfaceAddCallReferenceRejectReason H323InterfaceAddCallReferenceRejectReason,
+ wrapH323InterfaceAddCallRelatedDataRejectReason H323InterfaceAddCallRelatedDataRejectReason,
+ wrapH323InterfaceAddFixedTransportAddressDataRejectReason H323InterfaceAddFixedTransportAddressDataRejectReason,
+ wrapH323InterfaceAddKeysAndSetAttributesRejectReason H323InterfaceAddKeysAndSetAttributesRejectReason,
+ wrapH323InterfaceAdditionalKeys H323InterfaceAdditionalKeys,
+ wrapH323InterfaceAllocateResourceRejectReason H323InterfaceAllocateResourceRejectReason,
+ wrapH323InterfaceChangeKeysAndRelationsToUsersReject H323InterfaceChangeKeysAndRelationsToUsersReject,
+ wrapH323InterfaceCommonAttribute H323InterfaceCommonAttribute,
+ wrapH323InterfaceCommonAttributeIdentifier H323InterfaceCommonAttributeIdentifier,
+ wrapH323InterfaceCreateCallReferenceRejectReason H323InterfaceCreateCallReferenceRejectReason,
+ wrapH323InterfaceCreateRejectReason H323InterfaceCreateRejectReason,
+ wrapH323InterfaceDeallocateResourceRejectReason H323InterfaceDeallocateResourceRejectReason,
+ wrapH323InterfaceGetFixedTransportAddressDataRejectReason H323InterfaceGetFixedTransportAddressDataRejectReason,
+ wrapH323InterfaceGetOrRemoveCallRelatedDataRejectReason H323InterfaceGetOrRemoveCallRelatedDataRejectReason,
+ wrapH323InterfaceGetOrSetCommonRejectReason H323InterfaceGetOrSetCommonRejectReason,
+ wrapH323InterfaceGetOrSetInstanceRejectReason H323InterfaceGetOrSetInstanceRejectReason,
+ wrapH323InterfaceInstanceAttribute H323InterfaceInstanceAttribute,
+ wrapH323InterfaceInstanceAttributeIdentifier H323InterfaceInstanceAttributeIdentifier,
+ wrapH323InterfaceKey H323InterfaceKey,
+ wrapH323InterfaceKeyEndpointIdentifier H323InterfaceKeyEndpointIdentifier,
+ wrapH323InterfaceReduceBandwidthRejectReason H323InterfaceReduceBandwidthRejectReason,
+ wrapH323InterfaceRemoveCallReferenceRejectReason H323InterfaceRemoveCallReferenceRejectReason,
+ wrapH323InterfaceRemoveFixedTransportAddressDataRejectReason H323InterfaceRemoveFixedTransportAddressDataRejectReason,
+ wrapH323InterfaceRemoveKeysAndSetAttributesRejectReason H323InterfaceRemoveKeysAndSetAttributesRejectReason,
+ wrapH323InterfaceRemoveRejectReason H323InterfaceRemoveRejectReason,
+ wrapH324Information H324Information,
+ wrapHighLayerCompatibility HighLayerCompatibility,
+ wrapInterfaceRegistrationInformation InterfaceRegistrationInformation,
+ wrapLANAttribute LANAttribute,
+ wrapLANAttributeIdentifier LANAttributeIdentifier,
+ wrapLayer1ProtUserInfo Layer1ProtUserInfo,
+ wrapLocation Location,
+ wrapLocationRejectReason LocationRejectReason,
+ wrapLogicalConnectionPointIdentifier LogicalConnectionPointIdentifier,
+ wrapLowLayerCompatibility LowLayerCompatibility,
+ wrapMaximumNumberOfAllowedConnections MaximumNumberOfAllowedConnections,
+ wrapMaximumTotalBandwidth MaximumTotalBandwidth,
+ wrapMcuInformation McuInformation,
+ wrapNonStandardIdentifier NonStandardIdentifier,
+ wrapNonStandardMessage NonStandardMessage,
+ wrapNonStandardParameter NonStandardParameter,
+ wrapNumber Number,
+ wrapNumberOfTimesLANWasCrowded NumberOfTimesLANWasCrowded,
+ wrapNumberType NumberType,
+ wrapNumberingPlan NumberingPlan,
+ wrapObjectIdentifier ObjectIdentifier,
+ wrapPhysicalConnectionPointIdentifier PhysicalConnectionPointIdentifier,
+ wrapPid Pid,
+ wrapPreStringToRemoveInDestinationAddress PreStringToRemoveInDestinationAddress,
+ wrapProgressIndicator ProgressIndicator,
+ wrapProtocolIdentifier ProtocolIdentifier,
+ wrapQ931Timer301Value Q931Timer301Value,
+ wrapQ931Timer303Value Q931Timer303Value,
+ wrapQ954Details Q954Details,
+ wrapQseriesOptions QseriesOptions,
+ wrapRASMessageTimerValue RASMessageTimerValue,
+ wrapRTPSession RTPSession,
+ wrapRegistrationRejectReason RegistrationRejectReason,
+ wrapRegistrationStatus RegistrationStatus,
+ wrapRelationToEquipment RelationToEquipment,
+ wrapRelationToUser RelationToUser,
+ wrapReleaseCompleteReason ReleaseCompleteReason,
+ wrapReleaseCompleteUUIE ReleaseCompleteUUIE,
+ wrapReleaseInformation ReleaseInformation,
+ wrapRemoveAnalysisRejectReason RemoveAnalysisRejectReason,
+ wrapRemoveEquipmentRepresentationRejectReason RemoveEquipmentRepresentationRejectReason,
+ wrapRemoveServiceAndStatusRejectReason RemoveServiceAndStatusRejectReason,
+ wrapRemoveServiceFromServiceProfileRejectReason RemoveServiceFromServiceProfileRejectReason,
+ wrapRemoveServiceIdentifierRejectReason RemoveServiceIdentifierRejectReason,
+ wrapRepeatIndicator RepeatIndicator,
+ wrapRequestSeqNum RequestSeqNum,
+ wrapRequestedUserAndLinkedUserAreIdentical RequestedUserAndLinkedUserAreIdentical,
+ wrapServiceAndStatus ServiceAndStatus,
+ wrapServiceCallSetupRejectionInformation ServiceCallSetupRejectionInformation,
+ wrapServiceCallSetupRejectionReason ServiceCallSetupRejectionReason,
+ wrapServiceCallTerminationInformation ServiceCallTerminationInformation,
+ wrapServiceCallTerminationReason ServiceCallTerminationReason,
+ wrapServiceData ServiceData,
+ wrapServiceIdentifier ServiceIdentifier,
+ wrapServiceProfile ServiceProfile,
+ wrapSetEquipmentStatusRejectReason SetEquipmentStatusRejectReason,
+ wrapSetLANDataRejectReason SetLANDataRejectReason,
+ wrapSetUserAttributeData SetUserAttributeData,
+ wrapSetupUUIE SetupUUIE,
+ wrapStateOfEquipment StateOfEquipment,
+ wrapStateOfUser StateOfUser,
+ wrapStatusOfService StatusOfService,
+ wrapSubaddress Subaddress,
+ wrapSubaddressInformation SubaddressInformation,
+ wrapSubaddressType SubaddressType,
+ wrapSupportedProtocols SupportedProtocols,
+ wrapT120Information T120Information,
+ wrapTerminalInformation TerminalInformation,
+ wrapTerminationInitiatior TerminationInitiatior,
+ wrapTimeSlot TimeSlot,
+ wrapTransferCapability TransferCapability,
+ wrapTransferRate TransferRate,
+ wrapTransportAddress TransportAddress,
+ wrapTransportAddressInformation TransportAddressInformation,
+ wrapTransportChannelInformation TransportChannelInformation,
+ wrapTypeOfEquipment TypeOfEquipment,
+ wrapTypeOfFlowControl TypeOfFlowControl,
+ wrapTypeOfLAN TypeOfLAN,
+ wrapTypeOfRegistration TypeOfRegistration,
+ wrapTypeOfService TypeOfService,
+ wrapTypeOfUser TypeOfUser,
+ wrapUnknownMessageResponse UnknownMessageResponse,
+ wrapUnregistrationRejectReason UnregistrationRejectReason,
+ wrapUserAllocateResourceRejectReason UserAllocateResourceRejectReason,
+ wrapUserAttributeData UserAttributeData,
+ wrapUserAttributeIdentifier UserAttributeIdentifier,
+ wrapUserCreateRejectReason UserCreateRejectReason,
+ wrapUserDeallocateResourceRejectReason UserDeallocateResourceRejectReason,
+ wrapUserIdentifier UserIdentifier,
+ wrapUserIdentifierInformation UserIdentifierInformation,
+ wrapUserInformation UserInformation,
+ wrapUserInformationUUIE UserInformationUUIE,
+ wrapUserKey UserKey,
+ wrapUserOrEquipmentRelatedInformation UserOrEquipmentRelatedInformation,
+ wrapUserOrEquipmentRelatedInformationIdentifier UserOrEquipmentRelatedInformationIdentifier,
+ wrapUserRelatedInformation UserRelatedInformation,
+ wrapUserRelatedInformationIdentifier UserRelatedInformationIdentifier,
+ wrapUserRemoveRejectReason UserRemoveRejectReason,
+ wrapUserSetRejectReason UserSetRejectReason,
+ wrapUserSpecificInformation UserSpecificInformation,
+ wrapVendorIdentifier VendorIdentifier,
+ wrapVoiceInformation VoiceInformation,
+ ...
+}
+
+
+-- ---------------------------------
+--
+-- AddAnalysisRejectReason
+--
+-- @prop dataType
+--
+-- @descr This parameter states the reason for the rejection.
+--
+-- @
+--
+-- ---------------------------------
+
+AddAnalysisRejectReason ::= CHOICE
+{
+ analysisTableEntryAlreadyExist NULL,
+ undefined NULL,
+ ...
+}
+
+
+
+-- ---------------------------------
+--
+-- AddServiceToServiceProfileRejectReason
+--
+-- @prop dataType
+--
+-- @descr This parameter states the reason for the rejection.
+--
+-- @
+--
+-- ---------------------------------
+
+AddServiceToServiceProfileRejectReason ::= CHOICE
+{
+ keyNotValid NULL,
+ serviceAlreadyExist NULL,
+ undefined NULL,
+ ...
+}
+
+
+
+-- ---------------------------------
+--
+-- AddUserIdentifiersRejectReason
+--
+-- @prop dataType
+--
+-- @descr This parameter states the reason for the rejection.
+--
+-- @
+--
+-- ---------------------------------
+
+AddUserIdentifiersRejectReason ::= CHOICE
+{
+ userIdentifierExist NULL,
+ undefined NULL,
+ ...
+}
+
+
+
+-- ---------------------------------
+--
+-- AdmissionRejectReason
+--
+-- @prop dataType
+--
+-- @descr
+--
+-- @
+--
+-- ---------------------------------
+
+AdmissionRejectReason ::= CHOICE
+{
+ calledPartyNotRegistered NULL,
+ invalidPermission NULL,
+ requestDenied NULL,
+ undefinedReason NULL,
+ callerNotRegistered NULL,
+ routeCallToGatekeeper NULL,
+ invalidEndpointIdentifier NULL,
+ resourceUnavailable NULL,
+ ...
+}
+
+
+-- ---------------------------------
+--
+-- AlertingUUIE
+--
+-- @prop dataType
+--
+-- @descr
+--
+-- @
+--
+-- ---------------------------------
+
+AlertingUUIE ::= SEQUENCE
+{
+ protocolIdentifier ProtocolIdentifier,
+ destinationEndpointType EndpointType, -- destinationInfo
+ destinationH245Address TransportAddress OPTIONAL, -- h245Address
+ ...
+}
+
+
+-- ---------------------------------
+--
+-- AllocateTransmissionPathRejectReason
+--
+-- @prop dataType
+--
+-- @descr Reason for the rejection.
+--
+-- @
+--
+-- ---------------------------------
+
+AllocateTransmissionPathRejectReason ::= CHOICE
+{
+ calledUserNotAvailable NULL,
+ calledUserUnknown NULL,
+ permissionDenied NULL,
+ resourcesNotAvailable NULL,
+ undefined NULL,
+ ...
+}
+
+
+
+-- ---------------------------------
+--
+-- AnalyseRejectReason
+--
+-- @prop dataType
+--
+-- @descr This parameter states the reason for the rejection.
+--
+-- @
+--
+-- ---------------------------------
+
+AnalyseRejectReason ::= CHOICE
+{
+ noMatchingEntryFound NULL,
+ undefined NULL,
+ ...
+}
+
+
+
+-- ---------------------------------
+--
+-- AvailabilityOfEquipment
+--
+-- @prop dataType
+--
+-- @descr
+--
+-- @
+--
+-- ---------------------------------
+
+AvailabilityOfEquipment ::= CHOICE
+{
+ available NULL,
+ notAvailable NULL,
+ ...
+}
+
+
+
+-- ---------------------------------
+--
+-- Bandwidth
+--
+-- @prop dataType
+--
+-- @descr States the bandwidth to be used in 100 bps.
+--
+-- @
+--
+-- ---------------------------------
+
+Bandwidth ::= INTEGER ( 1.. 4294967295 )
+
+
+
+-- ---------------------------------
+--
+-- BandwidthReducedInformation
+--
+-- @prop dataType
+--
+-- @descr States information related to the recuction of the bandwidth.
+--
+-- @
+--
+-- ---------------------------------
+
+BandwidthReducedInformation ::= SEQUENCE
+{
+ allocatedBandwidth Bandwidth,
+ bandwidthReducedReason BandwidthReducedReason,
+ ...
+}
+
+
+
+-- ---------------------------------
+--
+-- BandwidthReducedReason
+-- @prop dataType
+-- @descr Reason for the rejection.
+-- @
+--
+-- ---------------------------------
+
+BandwidthReducedReason ::= CHOICE
+{
+ bandwidthLimited NULL,
+ bandwidthAdaptedToOriginatingEndpoint NULL,
+ originBandwidthBarredDueToCategories NULL,
+ undefined NULL,
+ ...
+}
+
+
+-- ---------------------------------
+--
+-- BandwidthRejectReason
+--
+-- @prop dataType
+--
+-- @descr
+--
+-- @
+--
+-- ---------------------------------
+
+BandwidthRejectReason ::= CHOICE
+{
+ notBound NULL,
+ invalidConferenceID NULL,
+ invalidPermission NULL,
+ insufficientResources NULL,
+ invalidRevision NULL,
+ undefinedReason NULL,
+ ...
+}
+
+
+-- ---------------------------------
+--
+-- BasicCallCategories
+--
+-- @prop dataType
+--
+-- @descr Categories for the service basic call.
+--
+-- @
+-- ---------------------------------
+
+BasicCallCategories ::= SEQUENCE
+{
+ ... -- So far, no specific categories identified
+}
+
+-- ---------------------------------
+--
+-- BearerCapability
+--
+-- @prop dataType
+--
+-- @descr Origin: Q931
+--
+-- @
+--
+-- ---------------------------------
+
+BearerCapability ::= SEQUENCE
+{
+ transferCapability TransferCapability,
+ transferRate TransferRate,
+ layer1ProtUserInfo Layer1ProtUserInfo,
+ rateMultiplier INTEGER (0..127),
+ ...
+}
+
+
+
+-- ---------------------------------
+--
+-- CallInformation
+--
+-- @prop dataType
+--
+-- @descr
+--
+-- @
+--
+-- ---------------------------------
+
+CallInformation ::= SEQUENCE
+{
+ nonStandardData NonStandardParameter OPTIONAL,
+ callReference CallReference, -- callReferenceValue
+ conferenceID ConferenceIdentifier,
+ originator BOOLEAN OPTIONAL,
+ audio SEQUENCE OF RTPSession OPTIONAL,
+ video SEQUENCE OF RTPSession OPTIONAL,
+ data SEQUENCE OF TransportChannelInformation OPTIONAL,
+ h245 TransportChannelInformation,
+ callSignaling TransportChannelInformation,
+ callType CallType,
+ bandwidth Bandwidth, -- bandWidth
+ callModel CallModel,
+ ...
+}
+
+-- ---------------------------------
+--
+-- CallModel
+--
+-- @prop dataType
+--
+-- @descr Type of callmodel used i.e routed via gatekeeper or not
+--
+-- @
+--
+-- ---------------------------------
+
+CallModel ::= CHOICE
+{
+ gatekeeperRouted NULL,
+ direct NULL,
+ ...
+}
+
+
+-- ---------------------------------
+--
+-- CallProceedingUUIE
+--
+-- @prop dataType
+--
+-- @descr
+--
+-- @
+--
+-- ---------------------------------
+
+
+CallProceedingUUIE ::= SEQUENCE
+{
+ protocolIdentifier ProtocolIdentifier,
+ destinationEndpointType EndpointType, -- destinationInfo
+ destinationH245Address TransportAddress OPTIONAL, -- h245Address
+ ...
+}
+
+-- ---------------------------------
+--
+-- PreStringToRemoveInDestinationAddress
+--
+-- @prop dataType
+--
+-- @descr states the call reference that identifies a specific call.
+-- Origin: H.225.0 CallReferenceValue.
+--
+-- @
+--
+-- ---------------------------------
+
+CallReference ::= INTEGER (0..65535)
+
+
+-- ---------------------------------
+--
+-- CallServices
+--
+-- @prop dataType
+--
+-- @descr
+--
+-- @
+--
+-- ---------------------------------
+
+CallServices ::= SEQUENCE
+{
+ q932Full BOOLEAN,
+ q951Full BOOLEAN,
+ q952Full BOOLEAN,
+ q953Full BOOLEAN,
+ q955Full BOOLEAN,
+ q956Full BOOLEAN,
+ q957Full BOOLEAN,
+ q954Info Q954Details,
+ ...
+}
+
+
+-- ---------------------------------
+--
+-- CallType
+--
+-- @prop dataType
+--
+-- @descr
+--
+-- @
+--
+-- ---------------------------------
+
+CallState ::= CHOICE
+{
+ null NULL,
+ callInit NULL,
+ overlapSending NULL,
+ outgoingCallProceeding NULL,
+ callDelivered NULL,
+ callPresent NULL,
+ callReceived NULL,
+ connectRequest NULL,
+ incomingCallProceeding NULL,
+ active NULL,
+ disconnectRequest NULL,
+ disconnectIndication NULL,
+ releaseRequest NULL,
+ facilityRequest NULL,
+ overlapReceiving NULL,
+ restartRequest NULL,
+ restart NULL,
+ ...
+}
+
+
+-- ---------------------------------
+--
+-- CallType
+--
+-- @prop dataType
+--
+-- @descr
+--
+-- @
+--
+-- ---------------------------------
+
+CallType ::= CHOICE
+{
+ pointToPoint NULL,
+ oneToN NULL,
+ nToOne NULL,
+ nToN NULL,
+ ...
+}
+
+-- ---------------------------------
+--
+-- Cause
+--
+-- @prop dataType
+--
+-- @descr Origin: Q931
+--
+-- @
+--
+-- ---------------------------------
+
+Cause ::= SEQUENCE
+{
+ coding Coding,
+ location Location,
+ value CauseValue,
+ diagnostics Diagnostics,
+ ...
+}
+
+
+-- ---------------------------------
+--
+-- CauseValue
+--
+-- @prop dataType
+--
+-- @descr Origin: Q931
+--
+-- @
+--
+-- ---------------------------------
+
+CauseValue ::= CHOICE
+{
+ unassignedNumber NULL, -- 1
+ noRouteToSpecifiedTransitNetwork NULL, -- 2
+ noRouteToDestination NULL, -- 3
+ channelUnacceptable NULL, -- 6
+ normalClearing NULL, -- 16
+ userBusy NULL, -- 17
+ noUserResponding NULL, -- 18
+ noAnswereFromUser NULL, -- 19
+ portableNotAvailable NULL, -- 20
+ callRejected NULL, -- 21
+ numberChanged NULL, -- 22
+ destinationOutOfOrder NULL, -- 27
+ invalidNumberFormat NULL, -- 28
+ facilityRequestRejected NULL, -- 29
+ responseToStatusEnquiry NULL, -- 30
+ normalUnspecified NULL, -- 31
+ noCircuitChannelAvailable NULL, -- 34
+ networkOutOfOrder NULL, -- 38
+ temporaryFailure NULL, -- 41
+ switchingEquipmentCongestion NULL, -- 42
+ accessInformationDiscarded NULL, -- 43
+ requestedCircuitChannelNotAvailable NULL, -- 44
+ resourceUnavailableUnspecified NULL, -- 47
+ qualityOfServiceUnavailable NULL, -- 49
+ notSubscribedToRequestedFacility NULL, -- 50
+ bearerCapabilityNotAuthorized NULL, -- 57
+ bearerCapabilityNotPresentlyAvailable NULL, -- 58
+ serviceOrOptionNotAvailableUnspecified NULL, -- 63, 79
+ bearerCapabilityNotImplemented NULL, -- 65
+ channelTypeNotImplemented NULL, -- 66
+ requestedFacilityNotImplemented NULL, -- 69
+ onlyRestrictedDigitalInformationBcIsAvailable NULL, -- 70
+ invalidCallReferenceValue NULL, -- 81
+ incompatibleDestination NULL, -- 88
+ invalidTransitNetworkSelection NULL, -- 91
+ invalidMessageUnspecified NULL, -- 95
+ mandatoryInformationElementIsMissing NULL, -- 96
+ messageTypeNonexistingOrNotimplemented NULL, -- 97
+ messageNotCompatibleOrImplemented NULL, -- 98
+ informationElementNonExisting NULL, -- 99
+ invalidInformationElementContents NULL, -- 100
+ messageNotCompatibleWithCallState NULL, -- 101
+ recoveryOnTimerExpiry NULL, -- 102
+ protocolErrorUnspecified NULL, -- 111
+ interworkingUnspecified NULL, -- 127
+ ...
+}
+
+
+-- ---------------------------------
+--
+-- ChangeServiceAndStatusRejectReason
+--
+-- @prop dataType
+--
+-- @descr Reason for the rejection.
+--
+-- @
+--
+-- ---------------------------------
+
+ChangeServiceAndStatusRejectReason ::= CHOICE
+{
+ identifierOfServiceNotKnown NULL,
+ userNotKnown NULL,
+ undefined NULL,
+ ...
+}
+
+
+
+-- ---------------------------------
+--
+-- CheckServiceRejectReason
+--
+-- @prop dataType
+--
+-- @descr Reason for the rejection.
+--
+-- @
+--
+-- ---------------------------------
+
+CheckServiceRejectReason ::= CHOICE
+{
+ deniedDueToInteraction NULL,
+ deniedDueToCategories NULL,
+ undefined NULL,
+ userNotKnown NULL,
+ ...
+}
+
+
+-- ---------------------------------
+--
+-- Coding
+--
+-- @prop dataType
+--
+-- @descr Origin: Q931
+--
+-- @
+--
+-- ---------------------------------
+
+Coding ::= CHOICE
+{
+ ccitt NULL,
+ ecma NULL,
+ national NULL,
+ network NULL,
+ ...
+}
+
+
+-- ---------------------------------
+--
+-- ConferenceGoal
+--
+-- @prop dataType
+--
+-- @descr Type of call setup desire
+--
+-- @
+--
+-- ---------------------------------
+
+ConferenceGoal ::= CHOICE
+{
+ create NULL,
+ join NULL,
+ invite NULL,
+ ...
+}
+
+
+
+-- ---------------------------------
+--
+-- ConferenceIdentifier
+--
+-- @prop dataType
+--
+--
+--
+-- @
+--
+-- ---------------------------------
+
+ConferenceIdentifier ::= OCTET STRING (SIZE (16))
+
+
+-- ---------------------------------
+--
+-- ConnectTransmissionPathRejectReason
+--
+-- @prop dataType
+--
+-- @descr Reason for the rejection.
+--
+-- @
+--
+-- ---------------------------------
+
+ConnectTransmissionPathRejectReason ::= CHOICE
+{
+ resourcesNotAllocated NULL,
+ switchFailure NULL,
+ undefined NULL,
+ ...
+}
+
+
+
+-- ---------------------------------
+--
+-- ConnectUUIE
+--
+-- @prop dataType
+--
+-- @descr
+--
+-- @
+--
+-- ---------------------------------
+
+ConnectUUIE ::= SEQUENCE
+{
+ protocolIdentifier ProtocolIdentifier,
+ destinationH245Address TransportAddress OPTIONAL, -- h245Address
+ destinationEndpointType EndpointType, -- destinationInfo
+ conferenceIdentifier ConferenceIdentifier, -- conferenceID
+ ...
+}
+
+
+
+-- ---------------------------------
+--
+-- ConnectionData
+--
+-- @prop dataType
+--
+-- @descr This parameter holds connection data that are specific for
+-- certain types of Equipments.
+-- @
+--
+-- ---------------------------------
+
+ConnectionData ::= CHOICE
+{
+ timeSlotInformation SEQUENCE OF TimeSlot,
+ ...
+}
+
+
+
+-- ---------------------------------
+--
+-- ConnectionIdentifier
+--
+-- @prop dataType
+--
+-- @descr Identifier to the connection handler instance.
+--
+-- @
+--
+-- ---------------------------------
+
+ConnectionIdentifier ::= ObjectIdentifier
+
+
+-- ---------------------------------
+--
+-- ConnectionInformation
+--
+-- @prop dataType
+--
+-- @descr This parameter specifies information that are of interest for
+-- the functionallity handled by component Connection Handler.
+-- @
+--
+-- ---------------------------------
+
+ConnectionInformation ::= SEQUENCE
+{
+ logicalConnectionPointIdentifier LogicalConnectionPointIdentifier,
+ connectionData ConnectionData OPTIONAL,
+ ...
+}
+
+
+
+-- ---------------------------------
+--
+-- ConnectionInformationOriginatingSide
+--
+-- @prop dataType
+--
+-- @descr Contains connection information that shall be used for the originating side of the connection.
+--
+-- @
+--
+-- ---------------------------------
+
+ConnectionInformationOriginatingSide ::= SEQUENCE
+{
+ bandwidth Bandwidth,
+ callType CallType,
+ originatorConnectionInformation ConnectionInformation,
+ terminatorConnectionInformation ConnectionInformation,
+ ...
+}
+
+
+
+-- ---------------------------------
+--
+-- ConnectionInformationTerminatingSide
+--
+-- @prop dataType
+--
+-- @descr Contains connection information that shall be used for the terminating side of the connection.
+--
+-- @
+--
+-- ---------------------------------
+
+ConnectionInformationTerminatingSide ::= SEQUENCE
+{
+ connectionIdentifier ConnectionIdentifier,
+ originatorConnectionInformation ConnectionInformation,
+ ...
+}
+
+
+
+-- ---------------------------------
+--
+-- ConnectionType
+--
+-- @prop dataType
+--
+-- @descr States the type of connection.
+--
+-- @
+--
+-- ---------------------------------
+
+ConnectionType ::= CHOICE
+{
+ pointToPoint NULL,
+ oneToN NULL,
+ nToOne NULL,
+ nToN NULL,
+ ...
+}
+
+
+
+-- ---------------------------------
+--
+-- CreateEquipmentRepresentationRejectReason
+--
+-- @prop dataType
+--
+-- @descr This reason for rejection.
+--
+-- @
+--
+-- ---------------------------------
+
+CreateEquipmentRepresentationRejectReason ::= CHOICE
+{
+ equipmentRepresentationAlreadyExist NULL,
+ undefined NULL,
+ ...
+}
+
+
+
+-- ---------------------------------
+--
+-- CreateServiceAndStatusRejectReason
+--
+-- @prop dataType
+--
+-- @descr Reason for the rejection.
+--
+-- @
+--
+-- ---------------------------------
+
+CreateServiceAndStatusRejectReason ::= CHOICE
+{
+ undefined NULL,
+ ...
+}
+
+
+
+-- ---------------------------------
+--
+-- CreateServiceIdentifierRejectReason
+--
+-- @prop dataType
+--
+-- @descr Reason for the rejection.
+--
+-- @
+--
+-- ---------------------------------
+
+CreateServiceIdentifierRejectReason ::= CHOICE
+{
+ keyNotKnown NULL,
+ undefined NULL,
+ ...
+}
+
+
+
+-- ---------------------------------
+--
+-- DeallocateTransmissionPathRejectReason
+--
+-- @prop dataType
+--
+-- @descr Reason for the rejection.
+--
+-- @
+--
+-- ---------------------------------
+
+DeallocateTransmissionPathRejectReason ::= CHOICE
+{
+ resourcesNotAllocated NULL,
+ undefined NULL,
+ ...
+}
+
+
+
+-- ---------------------------------
+--
+-- DetailedReasonAtom
+--
+-- @prop dataType
+-- @descr This data type indicates the release information of a forced drop
+-- during a call.
+-- @
+--
+-- ---------------------------------
+
+DetailedReasonAtom ::= CHOICE
+{
+ internalDataMissmatch NULL,
+ destinationUserIdentifierNotKnown NULL,
+ rejectedDueToCategories NULL,
+ rejectedDueToResources NULL,
+ failedToOpenDestinationCallSignallingPort NULL,
+ theRequestedServiceIsNotSupported NULL,
+ undefined NULL,
+ ...
+}
+
+-- ---------------------------------
+--
+-- Diagnostics
+--
+-- @prop dataType
+--
+-- @descr Origin: Q931
+--
+-- @
+--
+-- ---------------------------------
+
+Diagnostics ::= INTEGER(1..127)
+
+
+-- ---------------------------------
+--
+-- DisconnectTransmissionPathRejectReason
+--
+-- @prop dataType
+--
+-- @descr Reason for the rejection.
+--
+-- @
+--
+-- ---------------------------------
+
+DisconnectTransmissionPathRejectReason ::= CHOICE
+{
+ resourcesNotAllocated NULL,
+ switchFailure NULL,
+ switchNotConnected NULL,
+ undefined NULL,
+ ...
+}
+
+
+-- ---------------------------------
+--
+-- DisengageReason
+--
+-- @prop dataType
+-- @descr the reason why a change was requested by the gatekeeper or the terminal.
+-- @
+-- ---------------------------------
+
+DisengageReason ::= CHOICE
+{
+ forcedDrop NULL,
+ normalDrop NULL,
+ undefinedReason NULL,
+ ...
+}
+
+
+-- ---------------------------------
+--
+-- DisengageRejectReason
+--
+-- @prop dataType
+--
+-- @descr
+--
+-- @
+--
+-- ---------------------------------
+
+DisengageRejectReason ::= CHOICE
+{
+ notRegistered NULL,
+ requestToDropOther NULL,
+ ...
+}
+-- ---------------------------------
+--
+-- Display
+--
+-- @prop dataType
+--
+-- @descr Origin: Q931
+--
+-- @
+--
+-- ---------------------------------
+
+Display ::= OCTET STRING (SIZE(1..82))
+
+
+
+-- ---------------------------------
+--
+-- E164Identifier
+--
+-- @prop dataType
+--
+-- @descr Identifier for the user identifier of the type E.164.
+--
+-- @
+--
+-- ---------------------------------
+
+E164Identifier ::= IA5String (SIZE (1..128)) (FROM ("0123456789#*,"))
+
+
+-- ---------------------------------
+--
+-- EndToEndEndpointInformationServiceCallAcknowledge
+--
+-- @prop dataType
+--
+-- @descr Information that shall be sent end to end.
+--
+-- @
+--
+-- ---------------------------------
+
+EndToEndEndpointInformationServiceCallAcknowledge ::= SEQUENCE
+{
+ bearerCapability BearerCapability OPTIONAL,
+ highLayerCompatibility HighLayerCompatibility OPTIONAL,
+ progressIndicator ProgressIndicator OPTIONAL,
+ userToUserQ931Information UserInformation OPTIONAL,
+ userToUserH323AcknowledgeInformation AlertingUUIE OPTIONAL,
+ ...
+}
+
+
+
+-- ---------------------------------
+--
+-- EndToEndEndpointInformationServiceCallActive
+--
+-- @prop dataType
+--
+-- @descr Information that shall be sent end to end.
+--
+-- @
+--
+-- ---------------------------------
+
+EndToEndEndpointInformationServiceCallActive ::= SEQUENCE
+{
+ bearerCapability BearerCapability OPTIONAL,
+ highLayerCompatibility HighLayerCompatibility OPTIONAL,
+ lowLayerCompatibility LowLayerCompatibility OPTIONAL,
+ progressIndicator ProgressIndicator OPTIONAL,
+ userToUserQ931Information UserInformation OPTIONAL,
+ userToUserH323ActiveInformation ConnectUUIE OPTIONAL,
+ ...
+}
+
+
+
+-- ---------------------------------
+--
+-- EndToEndEndpointInformationServiceCallProgress
+--
+-- @prop dataType
+--
+-- @descr Information that shall be sent end to end.
+--
+-- @
+--
+-- ---------------------------------
+
+EndToEndEndpointInformationServiceCallProgress ::=SEQUENCE
+{
+ cause Cause OPTIONAL,
+ highLayerCompatibility HighLayerCompatibility OPTIONAL,
+ progressIndicator ProgressIndicator OPTIONAL,
+ userToUserQ931Information UserInformation OPTIONAL,
+ ...
+}
+
+
+
+
+-- ---------------------------------
+--
+-- EndToEndEndpointInformationServiceCallSetup
+--
+-- @prop dataType
+--
+-- @descr Information that shall be sent end to end.
+--
+-- @
+--
+-- ---------------------------------
+
+EndToEndEndpointInformationServiceCallSetup ::=SEQUENCE
+{
+ bearerCapability BearerCapability OPTIONAL,
+ calledNumber Number OPTIONAL,
+ calledSubaddress Subaddress OPTIONAL,
+ callingNumber Number OPTIONAL,
+ callingSubaddress Subaddress OPTIONAL,
+ highLayerCompatibility HighLayerCompatibility OPTIONAL,
+ lowLayerCompatibility LowLayerCompatibility OPTIONAL,
+ progressIndicator ProgressIndicator OPTIONAL,
+ repeatIndicator RepeatIndicator OPTIONAL,
+ userToUserQ931Information UserInformation OPTIONAL,
+ userToUserH323SetupInformation SetupUUIE OPTIONAL,
+ ...
+}
+
+
+
+-- ---------------------------------
+--
+-- EndToEndEndpointInformationServiceCallTermination
+--
+-- @prop dataType
+--
+-- @descr Information that shall be sent end to end.
+--
+-- @
+--
+-- ---------------------------------
+
+EndToEndEndpointInformationServiceCallTermination ::=SEQUENCE
+{
+ cause Cause OPTIONAL,
+ progressIndicator ProgressIndicator OPTIONAL,
+ userToUserQ931Information UserInformation OPTIONAL,
+ userToUserH323TerminationInformation ReleaseCompleteUUIE OPTIONAL,
+ ...
+}
+
+
+
+-- ---------------------------------
+--
+-- EndpointIdentifier
+--
+-- @prop dataType
+--
+--
+-- @
+--
+-- ---------------------------------
+
+EndpointIdentifier ::= BMPString (SIZE(1..128)) -- change from SIZE(128)
+
+
+-- ---------------------------------
+--
+-- EndpointRegistrationCategories
+--
+-- @prop dataType
+--
+-- @descr Categories for the service endpoint registration.
+--
+-- @
+-- ---------------------------------
+
+EndpointRegistrationCategories ::= SEQUENCE
+{
+ ... -- So far, no specific categories identified
+}
+
+
+
+-- ---------------------------------
+--
+-- EndpointRegistrationRejectReason
+--
+-- @prop dataType
+--
+--
+-- @
+--
+-- ---------------------------------
+
+EndpointRegistrationRejectReason ::= CHOICE
+{
+ attemptToChangeEndpoint NULL,
+ requestedUserNotKnown NULL,
+ endpointTypeNotKnown NULL,
+ undefined NULL,
+ ...
+}
+
+
+
+-- ---------------------------------
+--
+-- EndpointType
+--
+-- @prop dataType
+--
+-- @descr
+--
+-- @
+--
+-- ---------------------------------
+
+EndpointType ::= SEQUENCE
+{
+ nonStandardData NonStandardParameter OPTIONAL,
+ vendor VendorIdentifier OPTIONAL,
+ gatekeeper GatekeeperInformation OPTIONAL,
+ gateway GatewayInformation OPTIONAL,
+ mcu McuInformation OPTIONAL,
+ terminal TerminalInformation OPTIONAL,
+ mc BOOLEAN,
+ undefinedNode BOOLEAN,
+ ...
+}
+
+
+-- ---------------------------------
+--
+-- EndpointUnregistrationCategories
+--
+-- @prop dataType
+--
+-- @descr Categories for the service endpoint unregistration.
+--
+-- @
+-- ---------------------------------
+
+EndpointUnregistrationCategories ::= SEQUENCE
+{
+ ... -- So far, no specific categories identified
+}
+
+
+
+-- ---------------------------------
+--
+-- EndpointUnregistrationRejectReason
+--
+-- @prop dataType
+--
+-- @descr
+--
+-- @
+--
+-- ---------------------------------
+
+EndpointUnregistrationRejectReason ::= CHOICE
+{
+ permissionDenied NULL,
+ userNotKnown NULL,
+ undefined NULL,
+ ...
+}
+
+
+
+-- ---------------------------------
+--
+-- EquipmentAddressAN
+--
+-- @prop dataType
+--
+-- @descr States the address for a certain equipment connected
+-- to the Access Node.
+-- @
+--
+-- ---------------------------------
+
+EquipmentAddressAN ::= SEQUENCE
+{
+ --TBD by SEA,
+ ...
+}
+
+
+
+-- ---------------------------------
+--
+-- EquipmentAddressLAN
+--
+-- @prop dataType
+--
+-- @descr States the transport address for a certain equipment
+--
+-- @
+--
+-- ---------------------------------
+
+EquipmentAddressLAN ::= SEQUENCE
+{
+ transportAddresses SEQUENCE OF TransportAddress,
+ ...
+}
+
+
+
+-- ---------------------------------
+--
+-- EquipmentRelatedInformation
+--
+-- @prop dataType
+--
+-- @descr Contains the retreived data.
+--
+-- @
+--
+-- ---------------------------------
+
+EquipmentRelatedInformation ::= CHOICE
+{
+ logicalConnectionPointIdentifier LogicalConnectionPointIdentifier,
+ registrationStatus RegistrationStatus,
+ stateOfEquipment StateOfEquipment,
+ typeOfEquipment TypeOfEquipment,
+ ...
+}
+
+
+
+-- ---------------------------------
+--
+-- EquipmentRelatedInformationIdentifier
+--
+--
+-- @prop dataType
+--
+-- @descr This parameter specifies different types of data
+-- that are specific to a certain equipment.
+--
+-- @
+-- ---------------------------------
+
+EquipmentRelatedInformationIdentifier ::= CHOICE
+{
+ logicalConnectionPointIdentifier NULL,
+ registrationStatus NULL,
+ stateOfEquipment NULL,
+ typeOfEquipment NULL,
+ ...
+}
+
+
+
+-- ---------------------------------
+--
+-- FacilityReason
+--
+-- @prop dataType
+--
+--
+-- @
+--
+-- ---------------------------------
+
+FacilityReason ::= CHOICE
+{
+ routeCallToGatekeeper NULL,
+ callForwarded NULL,
+ routeCallToMC NULL,
+ undefinedReason NULL,
+ ...
+}
+
+
+-- ---------------------------------
+--
+-- FacilityUUIE
+--
+-- @prop dataType
+--
+--
+-- @
+--
+-- ---------------------------------
+
+FacilityUUIE ::= SEQUENCE
+{
+ protocolIdentifier ProtocolIdentifier,
+ alternativeH245Address TransportAddress OPTIONAL, -- alternativeAddress
+ alternativeUserIdentifierInformation UserIdentifierInformation OPTIONAL, -- alternativeAliasAddress
+ conferenceIdentifier ConferenceIdentifier OPTIONAL, -- conferenceID
+ facilityReason FacilityReason, -- reason
+ ...
+}
+
+
+-- ---------------------------------
+--
+-- GatekeeperIdentifier
+--
+-- @prop dataType
+--
+-- @descr
+--
+-- @
+--
+-- ---------------------------------
+
+GatekeeperIdentifier ::= BMPString (SIZE(1..128))
+
+
+-- ---------------------------------
+--
+-- GatekeeperInformation
+--
+-- @prop dataType
+--
+-- @descr
+--
+-- @
+--
+-- ---------------------------------
+
+GatekeeperInformation ::= SEQUENCE
+{
+ nonStandardData NonStandardParameter OPTIONAL,
+ ...
+}
+
+
+-- ---------------------------------
+--
+-- GatekeeperRejectReason
+--
+-- @prop dataType
+--
+-- @descr
+--
+-- @
+--
+-- ---------------------------------
+
+GatekeeperRejectReason ::= CHOICE
+{
+ resourceUnavailable NULL,
+ terminalExcluded NULL,
+ invalidRevision NULL,
+ undefinedReason NULL,
+ ...
+}
+
+
+-- ---------------------------------
+--
+-- GatewayInformation
+--
+-- @prop dataType
+--
+-- @descr
+--
+-- @
+--
+-- ---------------------------------
+
+GatewayInformation ::= SEQUENCE
+{
+ protocol SEQUENCE OF SupportedProtocols OPTIONAL,
+ nonStandardData NonStandardParameter OPTIONAL,
+ ...
+}
+
+
+-- ---------------------------------
+--
+-- GetAnalysisRejectReason
+--
+-- @prop dataType
+--
+-- @descr This parameter states the reason for the rejection.
+--
+-- @
+--
+-- ---------------------------------
+
+GetAnalysisRejectReason ::= CHOICE
+{
+ noDataStored NULL,
+ undefined NULL,
+ ...
+}
+
+
+
+-- ---------------------------------
+--
+-- GetEquipmentInformationRejectReason
+--
+-- @prop dataType
+--
+-- @descr Reason for the rejection.
+--
+-- @
+--
+-- ---------------------------------
+
+GetEquipmentInformationRejectReason ::= CHOICE
+{
+ equipmentUnknown NULL,
+ undefined NULL,
+ ...
+}
+
+
+
+-- ---------------------------------
+--
+-- GetLANDataRejectReason
+--
+-- @prop dataType
+--
+-- @descr This reason for rejection.
+--
+-- @
+--
+-- ---------------------------------
+
+GetLANDataRejectReason ::= CHOICE
+{
+ noDataStored NULL,
+ undefined NULL,
+ ...
+}
+
+
+
+-- ---------------------------------
+--
+-- GetPartyInformationRejectReason
+--
+-- @prop dataType
+--
+-- @descr Reason for the rejection.
+--
+-- @
+--
+-- ---------------------------------
+
+GetPartyInformationRejectReason ::= CHOICE
+{
+ noEquipmentAvailable NULL,
+ userNotKnown NULL,
+ undefined NULL,
+ ...
+}
+
+
+
+-- ---------------------------------
+--
+-- GetRejectReasonUser
+--
+-- @prop dataType
+--
+-- @descr This parameter states the reason for the rejection.
+--
+-- @
+--
+-- ---------------------------------
+
+GetRejectReasonUser ::= CHOICE
+{
+ keyNotKnown NULL,
+ undefined NULL,
+ ...
+}
+
+
+
+-- ---------------------------------
+--
+-- GetServiceFromServiceProfileRejectReason
+--
+-- @prop dataType
+--
+-- @descr This parameter states the reason for the rejection.
+--
+-- @
+--
+-- ---------------------------------
+
+GetServiceFromServiceProfileRejectReason ::= CHOICE
+{
+ keyNotValid NULL,
+ serviceDoNotExist NULL,
+ undefined NULL,
+ ...
+}
+
+
+
+-- ---------------------------------
+--
+-- GetServiceProfileRejectReason
+--
+-- @prop dataType
+--
+-- @descr
+--
+-- @
+--
+-- ---------------------------------
+
+GetServiceProfileRejectReason ::= CHOICE
+{
+ userNotKnown NULL,
+ undefined NULL,
+ ...
+}
+
+
+
+-- ---------------------------------
+--
+-- GetServicesAndStatusRejectReason
+--
+-- @prop dataType
+--
+-- @descr Reason for the rejection.
+--
+-- @
+--
+-- ---------------------------------
+
+GetServicesAndStatusRejectReason ::= CHOICE
+{
+ userNotKnown NULL,
+ undefined NULL,
+ ...
+}
+
+
+
+-- ---------------------------------
+--
+-- GetUserServiceInformationAndStatusRejectReason
+--
+-- @prop dataType
+--
+-- @descr Reason for the rejection.
+--
+-- @
+--
+-- ---------------------------------
+
+GetUserServiceInformationAndStatusRejectReason ::= CHOICE
+{
+ undefined NULL,
+ userNotKnown NULL,
+ ...
+}
+
+
+
+-- ---------------------------------
+--
+-- H221NonStandard
+-- @prop dataType
+--
+-- @descr Gives non standard information about the standard protocol H.221.
+-- @
+--
+-- ---------------------------------
+
+H221NonStandard ::= SEQUENCE
+{ t35CountryCode INTEGER(0..255),
+ t35Extension INTEGER(0..255),
+ manufacturerCode INTEGER(0..65535),
+ ...
+}
+
+
+-- ---------------------------------
+--
+-- H310Information
+-- @prop dataType
+-- @descr Gives detailed information about the standard protocol H.310.
+-- @
+--
+-- ---------------------------------
+
+H310Information ::= SEQUENCE
+{
+ nonStandardData NonStandardParameter OPTIONAL,
+ ...
+}
+
+
+-- ---------------------------------
+--
+-- H320Information
+-- @prop dataType
+--
+-- @descr Gives detailed information about the standard protocol H.320.
+-- @
+--
+-- ---------------------------------
+
+H320Information ::= SEQUENCE
+{
+ nonStandardData NonStandardParameter OPTIONAL,
+ ...
+}
+
+
+-- ---------------------------------
+--
+-- H321Information
+--
+-- @prop dataType
+-- @descr Gives detailed information about the standard protocol H.321.
+-- @
+--
+-- ---------------------------------
+
+H321Information ::= SEQUENCE
+{
+ nonStandardData NonStandardParameter OPTIONAL,
+ ...
+}
+
+
+-- ---------------------------------
+--
+-- H322Information
+--
+-- @prop dataType
+-- @descr Gives detailed information about the standard protocol H.322.
+-- @
+--
+-- ---------------------------------
+
+H322Information ::= SEQUENCE
+{
+ nonStandardData NonStandardParameter OPTIONAL,
+ ...
+}
+
+
+-- ---------------------------------
+--
+-- H323Information
+--
+-- @prop dataType
+-- @descr Gives detailed information about the standard protocol H.323.
+-- @
+--
+-- ---------------------------------
+
+H323Information ::= SEQUENCE
+{
+ nonStandardData NonStandardParameter OPTIONAL,
+ ...
+}
+
+
+-- ---------------------------------
+--
+-- H323InterfaceAddCallReferenceRejectReason
+--
+-- @prop dataType
+-- @descr Reason for the rejection.
+-- @
+--
+-- ---------------------------------
+
+H323InterfaceAddCallReferenceRejectReason ::= CHOICE
+{
+ keyNotValid NULL,
+ requestedCallReferenceAlreadyInUse NULL,
+ undefined NULL,
+ ...
+}
+
+
+
+-- ---------------------------------
+--
+-- H323InterfaceAddCallRelatedDataRejectReason
+--
+-- @prop dataType
+-- @descr Reason for the rejection.
+-- @
+--
+-- ---------------------------------
+
+H323InterfaceAddCallRelatedDataRejectReason ::= CHOICE
+{
+ callReferenceNotValid NULL,
+ keyNotValid NULL,
+ callRelatedDataAlredyStored NULL,
+ undefined NULL,
+ ...
+}
+
+
+
+-- ---------------------------------
+--
+-- H323InterfaceAddFixedTransportAddressDataRejectReason
+--
+-- @prop dataType
+-- @descr Reason for the rejection.
+-- @
+--
+-- ---------------------------------
+
+H323InterfaceAddFixedTransportAddressDataRejectReason ::= CHOICE
+{
+ fixedTransportAddressDataAlredyStored NULL,
+ undefined NULL,
+ ...
+}
+
+
+
+-- ---------------------------------
+--
+-- H323InterfaceAddKeysAndSetAttributesRejectReason
+--
+-- @prop dataType
+--
+-- @descr This parameter states the reason for the rejection.
+--
+-- @
+--
+-- ---------------------------------
+
+H323InterfaceAddKeysAndSetAttributesRejectReason ::= CHOICE
+{
+ existingKeyNotValid NULL,
+ newKeyAlreadyExists NULL,
+ newKeyNotValid NULL,
+ undefined NULL,
+ ...
+}
+
+
+
+-- ---------------------------------
+--
+-- H323InterfaceAdditionalKeys
+--
+-- @prop dataType
+-- @descr Additional keys for an instance of the type H.323Interface.
+-- @
+-- ---------------------------------
+
+H323InterfaceAdditionalKeys ::= SEQUENCE
+{
+ endpointCallSignallingAddresses SEQUENCE OF TransportAddress,
+ endpointRASAddresses SEQUENCE OF TransportAddress,
+ ...
+}
+
+
+-- ---------------------------------
+--
+-- H323InterfaceAllocateResourceRejectReason
+--
+-- @prop dataType
+-- @descr Reason for the rejection.
+-- @
+--
+-- ---------------------------------
+
+H323InterfaceAllocateResourceRejectReason ::= CHOICE
+{
+ callReferenceNotValid NULL,
+ keyNotValid NULL,
+ resourceNotAvailable NULL,
+ undefined NULL,
+ ...
+}
+
+
+
+-- ---------------------------------
+--
+-- H323InterfaceChangeKeysAndRelationsToUsersReject
+--
+-- @prop dataType
+--
+-- @descr This parameter states the reason for the rejection.
+--
+-- @
+--
+-- ---------------------------------
+
+H323InterfaceChangeKeysAndRelationsToUsersReject ::= CHOICE
+{
+ firstKeyNotValid NULL,
+ secondKeyNotValid NULL,
+ undefined NULL,
+ ...
+}
+
+
+
+-- ---------------------------------
+--
+-- H323InterfaceCommonAttribute
+--
+-- @prop dataType
+--
+-- @descr This parameter contains the attributes which holds data
+-- that are common for all objects of the type H.323Interface.
+--
+-- @
+--
+-- ---------------------------------
+
+H323InterfaceCommonAttribute ::= CHOICE
+{
+ gatekeeperCallSignallingAddressData CHOICE
+ {
+ gatekeeperCallSignallingAddresses SEQUENCE OF TransportAddress,
+ undefined NULL,
+ ...
+ },
+ gatekeeperRASAddressInformation CHOICE
+ {
+ gatekeeperRASAddressData SEQUENCE
+ {
+ multicastRASAddress TransportAddress,
+ gatekeeperRASAddress TransportAddress,
+ ...
+ },
+ undefined NULL,
+ ...
+ },
+ q931Timer301Value Q931Timer301Value,
+ q931Timer303Value Q931Timer303Value,
+ rasMessageTimerValue RASMessageTimerValue,
+ ...
+}
+
+
+
+-- ---------------------------------
+--
+-- H323InterfaceCommonAttributeIdentifier
+--
+-- @prop dataType
+--
+-- @descr This parameter contains the attribute identifiers of the
+-- attributes which holds data that are common for all objects
+-- of the type H.323Interface.
+--
+-- @
+--
+-- ---------------------------------
+
+H323InterfaceCommonAttributeIdentifier ::= CHOICE
+{
+ gatekeeperCallSignallingAddresses NULL,
+ gatekeeperRASAddress NULL,
+ q931Timer301Value NULL,
+ q931Timer303Value NULL,
+ rasMessageTimerValue NULL,
+ ...
+}
+
+
+
+-- ---------------------------------
+--
+-- H323InterfaceCreateCallReferenceRejectReason
+--
+-- @prop dataType
+-- @descr Reason for the rejection.
+-- @
+-- ---------------------------------
+
+H323InterfaceCreateCallReferenceRejectReason ::= CHOICE
+{
+ keyNotValid NULL,
+ noCallReferenceAvailable NULL,
+ undefined NULL,
+ ...
+}
+
+
+
+-- ---------------------------------
+--
+-- H323InterfaceCreateRejectReason
+--
+-- @prop dataType
+--
+-- @descr This parameter states the reason for the rejection.
+--
+-- @
+--
+-- ---------------------------------
+
+H323InterfaceCreateRejectReason ::= CHOICE
+{
+ keyAlreadyInUse NULL,
+ undefined NULL,
+ ...
+}
+
+
+
+-- ---------------------------------
+--
+-- H323InterfaceDeallocateResourceRejectReason
+--
+-- @prop dataType
+-- @descr Reason for the rejection.
+-- @
+-- ---------------------------------
+
+H323InterfaceDeallocateResourceRejectReason ::= CHOICE
+{
+ resourceNotAllocated NULL,
+ callReferenceNotValid NULL,
+ keyNotValid NULL,
+ undefined NULL,
+ ...
+}
+
+
+
+-- ---------------------------------
+--
+-- H323InterfaceGetFixedTransportAddressDataRejectReason
+--
+-- @prop dataType
+-- @descr Reason for the rejection.
+-- @
+-- ---------------------------------
+
+H323InterfaceGetFixedTransportAddressDataRejectReason ::= CHOICE
+{
+ noDataStoredForThisTransportAddress NULL,
+ noFixedTransportAddressDataStored NULL,
+ undefined NULL,
+ ...
+}
+
+
+
+-- ---------------------------------
+--
+-- H323InterfaceGetOrRemoveCallRelatedDataRejectReason
+--
+-- @prop dataType
+-- @descr Reason for the rejection.
+-- @
+--
+-- ---------------------------------
+
+H323InterfaceGetOrRemoveCallRelatedDataRejectReason ::= CHOICE
+{
+ callReferenceNotValid NULL,
+ keyNotValid NULL,
+ noCallRelatedDataStored NULL,
+ undefined NULL,
+ ...
+}
+
+
+
+-- ---------------------------------
+--
+-- H323InterfaceGetOrSetCommonRejectReason
+--
+-- @prop dataType
+--
+-- @descr This parameter states the reason for the rejection.
+--
+-- @
+--
+-- ---------------------------------
+
+H323InterfaceGetOrSetCommonRejectReason ::= CHOICE
+{
+ undefined NULL,
+ ...
+}
+
+
+
+-- ---------------------------------
+--
+-- H323InterfaceGetOrSetInstanceRejectReason
+--
+-- @prop dataType
+--
+-- @descr This parameter states the reason for the rejection.
+--
+-- @
+--
+-- ---------------------------------
+
+H323InterfaceGetOrSetInstanceRejectReason ::= CHOICE
+{
+ keyNotValid NULL,
+ undefined NULL,
+ ...
+}
+
+
+
+-- ---------------------------------
+--
+-- H323InterfaceInstanceAttribute
+--
+-- @prop dataType
+--
+-- @descr This parameter contains the attributes which holds data
+-- that are specific for a h323Interface object.
+--
+-- @
+--
+-- ---------------------------------
+
+H323InterfaceInstanceAttribute ::= CHOICE
+{
+ endpointCallSignallingAddresses SEQUENCE OF TransportAddress,
+ endpointRasAddresses SEQUENCE OF TransportAddress,
+ registrationStatus RegistrationStatus,
+ gatekeeperCallSignallingAddress TransportAddress,
+ maximumTotalBandwidthForInterface Bandwidth,
+ preStringsToRemoveInDestinationAddress SEQUENCE OF PreStringToRemoveInDestinationAddress,
+ relationToH2250CallSignalling Pid,
+ relationToUser RelationToUser,
+ typeOfEquipment TypeOfEquipment,
+ ...
+}
+
+
+
+-- ---------------------------------
+--
+-- H323InterfaceInstanceAttributeIdentifier
+--
+-- @prop dataType
+--
+-- @descr This parameter contains the attribute identifiers of the
+-- attributes which holds data that are specific for a
+-- h323Interface object.
+--
+-- @
+--
+-- ---------------------------------
+
+H323InterfaceInstanceAttributeIdentifier ::= CHOICE
+{
+ endpointCallSignallingAddresses NULL,
+ endpointRASAddresses NULL,
+ registrationStatus NULL,
+ gatekeeperCallSignallingAddress NULL,
+ maximumTotalBandwidthForInterface NULL,
+ preStringsToRemoveInDestinationAddress NULL,
+ relationToH2250CallSignalling NULL,
+ relationToUser NULL,
+ typeOfEquipment NULL,
+ ...
+}
+
+
+
+-- ---------------------------------
+--
+-- H323InterfaceKey
+--
+-- @prop dataType
+-- @descr Allowed keys for an instance of the type H.323Interface.
+-- @
+-- ---------------------------------
+
+H323InterfaceKey ::= CHOICE
+{
+ endpointIdentifier EndpointIdentifier,
+ endpointCallSignallingAddresses SEQUENCE OF TransportAddress,
+ endpointRASAddresses SEQUENCE OF TransportAddress,
+ ...
+}
+
+
+-- ---------------------------------
+--
+-- H323InterfaceKeyEndpointIdentifier
+--
+-- @descr Allowed keys for an instance of the type H.323Interface.
+--
+-- ---------------------------------
+
+H323InterfaceKeyEndpointIdentifier ::= SEQUENCE
+{
+ endpointIdentifier EndpointIdentifier,
+ ...
+}
+
+
+-- ---------------------------------
+--
+-- H323InterfaceReduceBandwidthRejectReason
+--
+-- @prop dataType
+-- @descr Reason for the rejection.
+-- @
+--
+-- ---------------------------------
+
+H323InterfaceReduceBandwidthRejectReason ::= CHOICE
+{
+ bandwidthNotAllocated NULL,
+ callReferenceNotValid NULL,
+ keyNotValid NULL,
+ newBandwidthHigherThanAllocatedBandwidth NULL,
+ undefined NULL,
+ ...
+}
+
+
+
+-- ---------------------------------
+--
+-- H323InterfaceRemoveCallReferenceRejectReason
+--
+-- @prop dataType
+-- @descr Reason for the rejection.
+-- @
+--
+-- ---------------------------------
+
+H323InterfaceRemoveCallReferenceRejectReason ::= CHOICE
+{
+ callReferenceNotStored NULL,
+ keyNotValid NULL,
+ undefined NULL,
+ ...
+}
+
+
+
+-- ---------------------------------
+--
+-- H323InterfaceRemoveFixedTransportAddressDataRejectReason
+-- @prop dataType
+-- @descr Reason for the rejection.
+-- @
+-- ---------------------------------
+
+H323InterfaceRemoveFixedTransportAddressDataRejectReason ::= CHOICE
+{
+ noDataStoredForThisTransportAddress NULL,
+ undefined NULL,
+ ...
+}
+
+
+
+-- ---------------------------------
+--
+-- H323InterfaceRemoveKeysAndSetAttributesRejectReason
+--
+-- @prop dataType
+--
+-- @descr This parameter states the reason for the rejection.
+--
+-- @
+--
+-- ---------------------------------
+
+H323InterfaceRemoveKeysAndSetAttributesRejectReason ::= CHOICE
+{
+ keysNotValid NULL,
+ undefined NULL,
+ ...
+}
+
+
+
+-- ---------------------------------
+--
+-- H323InterfaceRemoveRejectReason
+--
+-- @prop dataType
+--
+-- @descr This parameter states the reason for the rejection.
+--
+-- @
+--
+-- ---------------------------------
+
+H323InterfaceRemoveRejectReason ::= CHOICE
+{
+ keyNotValid NULL,
+ serviceInProgress NULL,
+ undefined NULL,
+ ...
+}
+
+
+
+-- ---------------------------------
+--
+-- H324Information
+-- @prop dataType
+--
+-- @descr Gives detailed information about the standard protocol H.324.
+-- @
+--
+-- ---------------------------------
+
+H324Information ::= SEQUENCE
+{
+ nonStandardData NonStandardParameter OPTIONAL,
+ ...
+}
+-- @prop dataType
+-- @descr Origin: Q931
+-- @
+
+HighLayerCompatibility ::= SEQUENCE
+{
+ ...
+}
+-- ---------------------------------
+--
+-- InterfaceRegistrationInformation
+-- @prop dataType
+--
+-- @descr This parameter specifies the current registration status of an
+-- endpoints registration request.
+-- @
+--
+-- ---------------------------------
+
+InterfaceRegistrationInformation ::= SEQUENCE
+{
+ isInterfaceRegistered BOOLEAN,
+ relationToH323User EndpointIdentifier OPTIONAL,
+ ...
+}
+
+
+-- ---------------------------------
+--
+-- LANAttribute
+--
+-- @prop dataType
+-- @descr This parameter contains a LAN attribute value.
+-- @
+--
+-- ---------------------------------
+
+LANAttribute ::= CHOICE
+{
+ maximumTotalBandwidth MaximumTotalBandwidth,
+ maximumNumberOfAllowedConnections MaximumNumberOfAllowedConnections,
+ numberOfTimesLANWasCrowded NumberOfTimesLANWasCrowded,
+ typeOfFlowControl TypeOfFlowControl,
+ typeOfLAN TypeOfLAN,
+ ...
+}
+
+
+
+-- ---------------------------------
+--
+-- LANAttributeIdentifier
+--
+-- @prop dataType
+-- @descr This parameter contains a LAN attribute identifier.
+-- @
+--
+-- ---------------------------------
+
+LANAttributeIdentifier ::= CHOICE
+{
+ maximumTotalBandwidth NULL,
+ maximumNumberOfAllowedConnections NULL,
+ numberOfTimesLANWasCrowded NULL,
+ typeOfFlowControl NULL,
+ typeOfLAN NULL,
+ ...
+}
+
+-- @prop dataType
+-- @descr Origin: Q931
+-- @
+
+ Layer1ProtUserInfo ::= CHOICE
+ {
+ g711u-law NULL,
+ g711a-law NULL,
+ h323VidephoneCall NULL, -- the meaning of "5" in H323
+ h221Andh242 NULL, -- the meaning of "5" in Q931
+ ...
+ }-- @prop dataType
+-- @descr Origin: Q931
+-- @
+
+ Location ::= CHOICE
+ {
+ user NULL,
+ localPrivateNetwork NULL,
+ localPublicNetwork NULL,
+ transitNetwork NULL,
+ remotePublicNetwork NULL,
+ remotePrivateNetwork NULL,
+ internationalNetwork NULL,
+ beyondInterworkingPoint NULL,
+ ...
+ }
+
+-- ---------------------------------
+--
+-- LocationRejectReason
+-- @prop dataType
+--
+-- @descr
+-- @
+-- ---------------------------------
+
+LocationRejectReason ::= CHOICE
+{
+ notRegistered NULL,
+ invalidPermission NULL,
+ requestDenied NULL,
+ undefinedReason NULL,
+ ...
+}
+
+
+-- ---------------------------------
+--
+-- LogicalConnectionPointIdentifier
+--
+-- @prop dataType
+-- @descr Identifier of the logical connection point.
+-- @
+--
+-- ---------------------------------
+
+LogicalConnectionPointIdentifier ::= INTEGER (0..65535)
+--
+-- Created by :
+-- Creation date :
+-- Modified by :
+-- Modification date :
+-- Version :
+--
+-- @prop dataType
+-- @descr origin Q931
+-- @
+
+ LowLayerCompatibility ::= SEQUENCE
+ {
+ }
+
+-- ---------------------------------
+--
+-- MaximumNumberOfAllowedConnections
+--
+-- @prop dataType
+-- @descr States the maximum number of allowed connections.
+-- @
+--
+-- ---------------------------------
+
+MaximumNumberOfAllowedConnections ::= CHOICE
+{
+ maximumNumberOfAllowedConnectionsValue INTEGER ( 0.. 999999999),
+ undefined NULL,
+ ...
+}
+
+
+
+-- ---------------------------------
+--
+-- MaximumTotalBandwidth
+-- @prop dataType
+-- @descr States the maximum total bandwidth.
+-- @
+-- ---------------------------------
+
+MaximumTotalBandwidth ::= CHOICE
+{
+ maximumTotalBandwidthValue Bandwidth,
+ undefined NULL,
+ ...
+}
+
+
+
+-- ---------------------------------
+--
+-- McuInformation
+-- @prop dataType
+--
+-- @descr Gives detailed information about the endpoint type, MCU.
+-- @
+-- ---------------------------------
+
+McuInformation ::= SEQUENCE
+{
+ nonStandardData NonStandardParameter OPTIONAL,
+ ...
+}
+
+
+-- ---------------------------------
+--
+-- NonStandardIdentifier
+-- @prop dataType
+--
+-- @descr
+-- @
+--
+-- ---------------------------------
+
+NonStandardIdentifier ::= CHOICE
+{
+ object OBJECT IDENTIFIER,
+ h221NonStandard H221NonStandard,
+ ...
+}
+
+
+-- ---------------------------------
+--
+-- NonStandardMessage
+-- @prop dataType
+--
+-- @descr
+-- @
+--
+-- ---------------------------------
+
+NonStandardMessage ::= SEQUENCE
+{
+ requestSeqNum RequestSeqNum,
+ nonStandardData NonStandardParameter,
+ ...
+}
+
+-- ---------------------------------
+--
+-- NonStandardParameter
+--
+-- @prop dataType
+-- @
+-- ---------------------------------
+
+NonStandardParameter ::= SEQUENCE
+{
+ nonStandardIdentifier NonStandardIdentifier,
+ data OCTET STRING,
+ ...
+}
+
+
+
+-- @prop dataType
+-- @descr Origin: Q931
+-- @
+
+ Number ::= SEQUENCE
+ {
+ type NumberType,
+ indicator NumberingPlan,
+ number IA5String (FROM ("0123456789#*")),
+ ...
+ }
+
+-- ---------------------------------
+--
+-- NumberOfTimesLANWasCrowded
+-- @prop dataType
+--
+-- @descr States the number of times the Lan has been crowded,
+-- i.e. the endpoints has released the initiated call due to
+-- heavy load in the LAN.
+-- @
+--
+-- ---------------------------------
+
+NumberOfTimesLANWasCrowded ::= CHOICE
+{
+ numberOfTimesLANWasCrowdedValue INTEGER ( 0.. 999999999),
+ undefined NULL,
+ ...
+}
+
+-- @prop dataType
+-- @descr Origin: Q931
+-- @
+
+ NumberType ::= CHOICE
+ {
+ unknown NULL,
+ international NULL,
+ national NULL,
+ network NULL,
+ local NULL,
+ abbreviated NULL,
+ ...
+ }
+
+-- @prop dataType
+-- @descr Origin: Q931
+-- @
+
+ NumberingPlan ::= CHOICE
+ {
+ unknown NULL,
+ e164 NULL,
+ data NULL,
+ telex NULL,
+ national NULL,
+ private NULL,
+ ...
+ }
+
+
+
+-- ---------------------------------
+--
+-- ObjectIdentifier
+--
+-- @prop dataType
+-- @descr An identifier to a certain instance of an object.
+-- @
+--
+-- ---------------------------------
+
+ObjectIdentifier ::= OCTET STRING
+
+
+
+-- ---------------------------------
+--
+-- PhysicalConnectionPointIdentifier
+--
+-- @prop dataType
+-- @descr Contains data that identifies a specific equipment instance.
+-- @
+--
+-- ---------------------------------
+
+PhysicalConnectionPointIdentifier ::= CHOICE
+{
+ equipmentAN EquipmentAddressAN, -- Equipment connected to the Access Node.
+ equipmentLAN EquipmentAddressLAN, -- Equipment connected to the LAN.
+ ...
+}
+
+
+-- ---------------------------------
+--
+-- Pid
+-- @prop dataType
+--
+-- @descr A process identifier.
+-- @
+--
+-- ---------------------------------
+
+Pid ::= ObjectIdentifier
+
+
+
+-- ---------------------------------
+--
+-- PreStringToRemoveInDestinationAddress
+--
+-- @prop dataType
+--
+-- @descr A pre-string that shall be removed when sending the destination address.
+--
+-- @
+--
+-- ---------------------------------
+
+PreStringToRemoveInDestinationAddress ::= CHOICE
+{
+ e164 IA5String (SIZE (1..128)) (FROM ("0123456789,")),
+ h323 BMPString (SIZE (1..256)),
+ -- h323 is Basic ISO/IEC 10646-1 (Unicode)
+ ...
+}
+
+-- @prop dataType
+-- @descr Origin: Q931
+-- @
+
+ ProgressIndicator ::= SEQUENCE
+ {
+ }
+
+-- ---------------------------------
+--
+-- ProtocolIdentifier
+--
+-- @prop dataType
+-- @descr
+-- @
+--
+-- ---------------------------------
+
+ProtocolIdentifier ::= OBJECT IDENTIFIER
+
+
+-- ---------------------------------
+--
+-- Q931Timer301Value
+-- @prop dataType
+--
+-- @descr States the Q931 timer 301 value to be used in milli seconds.
+-- @
+--
+-- ---------------------------------
+
+Q931Timer301Value ::= INTEGER ( 180000.. 360000 )
+
+
+
+-- ---------------------------------
+--
+-- Q931Timer303Value
+--
+-- @prop dataType
+-- @descr States the Q931 timer 303 value to be used in milli seconds.
+-- @
+--
+-- ---------------------------------
+
+Q931Timer303Value ::= INTEGER ( 1000.. 10000 )
+
+
+
+-- ---------------------------------
+--
+-- Q954Details
+--
+-- @prop dataType
+-- @descr
+-- @
+--
+-- ---------------------------------
+
+Q954Details ::= SEQUENCE
+{
+ conferenceCalling BOOLEAN,
+ threePartyService BOOLEAN,
+ ...
+}
+
+
+-- ---------------------------------
+--
+-- QseriesOptions
+--
+-- @prop dataType
+-- @
+--
+-- ---------------------------------
+
+QseriesOptions ::=SEQUENCE
+{
+ q932Full BOOLEAN,
+ q951Full BOOLEAN,
+ q952Full BOOLEAN,
+ q953Full BOOLEAN,
+ q955Full BOOLEAN,
+ q956Full BOOLEAN,
+ q957Full BOOLEAN,
+ q954Info Q954Details,
+ ...
+}
+
+
+-- ---------------------------------
+--
+-- RASMessageTimerValue
+--
+-- @prop dataType
+-- @descr States the RAS message timer value to be used in milli seconds.
+-- @
+--
+-- ---------------------------------
+
+RASMessageTimerValue ::= INTEGER ( 1000.. 10000 )
+
+
+
+-- ---------------------------------
+--
+-- RTPSession
+--
+-- @prop dataType
+-- @
+--
+-- ---------------------------------
+
+RTPSession ::= SEQUENCE
+{
+ rtpAddress TransportChannelInformation,
+ rtcpAddress TransportChannelInformation,
+ cname PrintableString,
+ ssrc INTEGER (1.. 134217727), -- change from 4294967295 for erl 4.2
+ sessionId INTEGER (1..255),
+ associatedSessionIds SEQUENCE OF INTEGER (1..255),
+ ...
+}
+
+
+-- ---------------------------------
+--
+-- RegistrationRejectReason
+--
+-- @prop dataType
+-- @descr Specifies the registration reject reason that are valid
+-- in the H.225.0 message RegistartionReject
+-- @ --
+-- ---------------------------------
+
+RegistrationRejectReason ::= CHOICE
+{
+ discoveryRequired NULL,
+ invalidRevision NULL,
+ invalidCallSignalAddress NULL,
+ invalidRasAddress NULL,
+ duplicateAlias UserIdentifierInformation,
+ invalidTerminalType NULL,
+ undefinedReason NULL,
+ transportNotSupported NULL,
+ ...
+}
+
+
+-- ---------------------------------
+--
+-- RegistrationStatus
+--
+-- @prop dataType
+-- @
+--
+-- ---------------------------------
+
+RegistrationStatus ::= CHOICE
+{
+ notRegistered NULL,
+ registered NULL,
+ ...
+}
+
+
+
+-- ---------------------------------
+--
+-- RelationToEquipment
+--
+-- @prop dataType
+-- @descr Relation to the architecture component Equipment.
+-- @
+--
+-- ---------------------------------
+
+RelationToEquipment ::= SEQUENCE
+{
+ relationToUser RelationToUser,
+ typeOfEquipment TypeOfEquipment,
+ ...
+}
+
+
+-- ---------------------------------
+--
+-- RelationToUser
+--
+-- @prop dataType
+-- @descr Relation to the architecture component User.
+-- @
+--
+-- ---------------------------------
+
+RelationToUser ::= BMPString (SIZE(1..128))
+
+
+
+-- ---------------------------------
+--
+-- ReleaseCompleteReason
+--
+-- @prop dataType
+-- @descr
+-- @
+--
+-- ---------------------------------
+
+ReleaseCompleteReason ::= CHOICE
+{
+ noBandwidth NULL,
+ gatekeeperResources NULL,
+ unreachableDestination NULL,
+ destinationRejection NULL,
+ invalidRevision NULL,
+ noPermission NULL,
+ unreachableGatekeeper NULL,
+ gatewayResources NULL,
+ badFormatAddress NULL,
+ adaptiveBusy NULL,
+ inConf NULL,
+ undefinedReason NULL,
+ ...
+}
+
+
+
+
+
+
+-- ---------------------------------
+--
+-- ReleaseCompleteUUIE
+-- @prop dataType
+--
+-- @
+-- ---------------------------------
+
+ReleaseCompleteUUIE ::= SEQUENCE
+{
+ protocolIdentifier ProtocolIdentifier,
+ releaseCompleteReason ReleaseCompleteReason OPTIONAL, -- reason
+ ...
+}
+
+
+-- ---------------------------------
+--
+-- ReleaseInformation
+--
+-- @prop dataType
+-- @descr This data type is used to transfer the reason for the
+-- rejection or release.
+-- @
+--
+-- ---------------------------------
+
+ReleaseInformation ::= CHOICE
+{
+ forcedDrop DetailedReasonAtom,
+ normalDrop NULL,
+ ...
+}
+
+
+-- ---------------------------------
+--
+-- RemoveAnalysisRejectReason
+--
+-- @prop dataType
+--
+-- @descr This parameter states the reason for the rejection.
+--
+-- @
+--
+-- ---------------------------------
+
+RemoveAnalysisRejectReason ::= CHOICE
+{
+ analysisTableEntryNotFound NULL,
+ undefined NULL,
+ ...
+}
+
+
+
+-- ---------------------------------
+--
+-- RemoveEquipmentRepresentationRejectReason
+--
+-- @prop dataType
+-- @descr This reason for rejection.
+-- @
+--
+-- ---------------------------------
+
+RemoveEquipmentRepresentationRejectReason ::= CHOICE
+{
+ invalidInputData NULL,
+ equipmentRepresentationDoesNotExist NULL,
+ other NULL,
+ ...
+}
+
+
+
+-- ---------------------------------
+--
+-- RemoveServiceAndStatusRejectReason
+--
+-- @prop dataType
+-- @descr Reason for the rejection.
+-- @
+--
+-- ---------------------------------
+
+RemoveServiceAndStatusRejectReason ::= CHOICE
+{
+ identifierOfServiceNotKnown NULL,
+ undefined NULL,
+ ...
+}
+
+
+
+-- ---------------------------------
+--
+-- RemoveServiceFromServiceProfileRejectReason
+--
+-- @prop dataType
+--
+-- @descr This parameter states the service and its categories that
+-- shall be added to a service profile.
+--
+-- @
+--
+-- ---------------------------------
+
+RemoveServiceFromServiceProfileRejectReason ::= CHOICE
+{
+ keyNotValid NULL,
+ serviceDoNotExist NULL,
+ undefined NULL,
+ ...
+}
+
+
+
+-- ---------------------------------
+--
+-- RemoveServiceIdentifierRejectReason
+--
+-- @prop dataType
+-- @descr Reason for the rejection.
+-- @
+-- ---------------------------------
+
+RemoveServiceIdentifierRejectReason ::= CHOICE
+{
+ keyNotKnown NULL,
+ serviceIdentifierDoNotExist NULL,
+ undefined NULL,
+ ...
+}
+
+--
+-- Created by :
+-- Creation date :
+-- Modified by :
+-- Modification date :
+-- Version :
+--
+-- @prop dataType
+-- @
+
+ RepeatIndicator ::= SEQUENCE
+ {
+ }
+
+-- ---------------------------------
+--
+-- RequestSeqNum
+--
+-- @prop dataType
+-- @descr
+-- @
+-- ---------------------------------
+
+RequestSeqNum ::= INTEGER (1..65535)
+
+
+
+-- ---------------------------------
+--
+-- RequestedUserAndLinkedUserAreIdentical
+--
+-- @prop dataType
+-- @descr This parameter indicates if the requested user and the user
+-- linked to the requested endpoint are identical, not identical
+-- or if this is undefined.
+-- @
+--
+-- ---------------------------------
+
+RequestedUserAndLinkedUserAreIdentical ::= CHOICE
+{
+ yes NULL,
+ no NULL,
+ undefined NULL,
+ ...
+}
+
+
+
+-- ---------------------------------
+--
+-- ServiceAndStatus
+-- @prop dataType
+--
+-- @descr Information of a service and its state.
+-- @
+--
+-- ---------------------------------
+
+ServiceAndStatus ::= SEQUENCE
+{
+ typeOfService TypeOfService,
+ status StatusOfService,
+ ...
+}
+
+
+
+-- ---------------------------------
+--
+-- ServiceCallSetupRejectionInformation
+--
+-- @prop dataType
+-- @descr Information related to the call setup rejection.
+-- @
+--
+-- ---------------------------------
+
+ServiceCallSetupRejectionInformation ::= SEQUENCE
+{
+ terminationInitiatior TerminationInitiatior,
+ terminationReason ServiceCallSetupRejectionReason,
+ ...
+}
+
+
+
+-- ---------------------------------
+--
+-- ServiceCallSetupRejectionReason
+--
+-- @prop dataType
+-- @descr Reason for rejection.
+-- @
+-- ---------------------------------
+
+ServiceCallSetupRejectionReason ::= CHOICE
+{
+ calledUserBusy NULL,
+ calledUserNotAvailable NULL,
+ destinationOutOfOrder NULL,
+ requestedServiceBarred NULL,
+ requestedServiceNotAvailable NULL,
+ requestedServiceNotSubscribed NULL,
+ resourceUnavailable NULL,
+ temporaryFailure NULL,
+ unassignedUserIdentifier NULL,
+ undefined NULL,
+ ...
+}
+
+
+
+-- ---------------------------------
+--
+-- ServiceCallTerminationInformation
+-- @prop dataType
+--
+-- @descr States information related to the termination.
+-- @
+--
+-- ---------------------------------
+
+ServiceCallTerminationInformation ::= SEQUENCE
+{
+ terminationInitiation TerminationInitiatior,
+ terminationReason ServiceCallTerminationReason,
+ ...
+}
+
+
+-- ---------------------------------
+--
+-- ServiceCallTerminationReason
+--
+-- @prop dataType
+-- @descr Reason for termination.
+-- @
+--
+-- ---------------------------------
+
+ServiceCallTerminationReason ::= CHOICE
+{
+ noAnswerFromCalledUser NULL,
+ normalTermination NULL,
+ resourceUnavailable NULL,
+ temporaryFailure NULL,
+ undefined NULL,
+ ...
+}
+
+
+
+-- ---------------------------------
+--
+-- ServiceData
+--
+-- @prop dataType
+-- @descr Contains the identified services and theirs categories
+-- @
+-- ---------------------------------
+
+ServiceData ::= CHOICE
+{
+ basicCall BasicCallCategories,
+ endpointRegistration EndpointRegistrationCategories,
+ endpointUnregistration EndpointUnregistrationCategories,
+ ...
+}
+
+-- @prop dataType
+-- @descr
+-- @
+--
+
+ ServiceIdentifier ::= INTEGER
+
+
+-- ---------------------------------
+--
+-- ServiceProfile
+--
+-- @prop dataType
+-- @descr Contains services and data related to the services.
+-- @
+-- ---------------------------------
+
+ServiceProfile ::= SEQUENCE
+{
+ serviceDataInformation SEQUENCE OF ServiceData OPTIONAL,
+ ...
+}
+
+
+
+-- ---------------------------------
+--
+-- SetEquipmentStatusRejectReason
+--
+-- @prop dataType
+--
+--
+-- @
+--
+-- ---------------------------------
+
+SetEquipmentStatusRejectReason ::= CHOICE
+{
+ userNotKnown NULL,
+ undefined NULL,
+ ...
+}
+
+
+-- ---------------------------------
+--
+-- SetLANDataRejectReason
+--
+-- @prop dataType
+-- @descr This reason for rejection.
+-- @
+--
+-- ---------------------------------
+
+SetLANDataRejectReason ::= CHOICE
+{
+ invalidInputData NULL,
+ other NULL,
+ ...
+}
+
+
+
+-- ---------------------------------
+--
+-- SetUserAttributeData
+--
+-- @prop dataType
+--
+-- @descr This parameter contains an User attribute value.
+--
+-- @
+--
+-- ---------------------------------
+
+SetUserAttributeData ::= CHOICE
+{
+ maximumTotalBandwidth Bandwidth,
+ maximumBandwidthPerService Bandwidth,
+ stateOfUser StateOfUser,
+ typeOfUser TypeOfUser,
+ ...
+}
+
+
+
+-- ---------------------------------
+--
+-- SetupUUIE
+-- @prop dataType
+-- @
+--
+-- ---------------------------------
+
+SetupUUIE ::= SEQUENCE
+{
+ protocolIdentifier ProtocolIdentifier,
+ sourceH245Address TransportAddress OPTIONAL, -- h245Address
+ sourceUserIdentifierInformation UserIdentifierInformation OPTIONAL, -- sourceAddress
+ sourceEndpointType EndpointType, -- sourceInfo
+ destinationUserIdentifierInformation UserIdentifierInformation OPTIONAL, -- destinationAddress
+ destinationCallSignallingAddress TransportAddress OPTIONAL, -- destCallSignalAddress
+ destinationExtraUserIdentifierInformation UserIdentifierInformation OPTIONAL, -- destExtraCallInfo
+ destinationExtraCallReference SEQUENCE OF CallReference OPTIONAL, -- destExtraCRV
+ activeMC BOOLEAN,
+ conferenceIdentifier ConferenceIdentifier, -- conferenceID
+ conferenceGoal ConferenceGoal,
+ callServices CallServices OPTIONAL,
+ callType CallType,
+ ...
+}
+
+
+-- ---------------------------------
+--
+-- StateOfEquipment
+--
+-- @prop dataType
+-- @descr States the state of the equipment.
+-- @
+--
+-- ---------------------------------
+
+StateOfEquipment ::= CHOICE
+{
+ blocked NULL, -- Equipment is blocked
+ busy NULL, -- Equipment is busy, no more calls possible for moment
+ available NULL, -- Equipment has reported itself as present and is ready for actions
+ unregistered NULL, -- Equipment is not present
+ ...
+}
+
+
+
+-- ---------------------------------
+--
+-- StateOfUser
+--
+-- @prop dataType
+-- @descr This parameter specifies the state of the user.
+-- @
+-- ---------------------------------
+
+StateOfUser ::= CHOICE
+{
+ absent NULL,
+ present NULL,
+ ...
+}
+
+
+
+-- ---------------------------------
+--
+-- StatusOfService
+--
+-- @prop dataType
+-- @descr States the state of the service.
+-- @
+--
+-- ---------------------------------
+
+StatusOfService ::= CHOICE
+{
+ acknowledge NULL,
+ active NULL,
+ initiatied NULL,
+ ...
+}
+
+-- @prop dataType
+-- @descr Origin: Q931
+-- @
+
+ Subaddress ::= SEQUENCE
+ {
+ type SubaddressType,
+ indicator BOOLEAN,
+ address SubaddressInformation,
+ ...
+ }
+-- @prop dataType
+-- @descr Origin: Q931
+-- @
+
+ SubaddressInformation ::= OCTET STRING (SIZE(1..23))
+-- @prop dataType
+-- @descr Origin: Q931
+-- @
+
+ SubaddressType ::= CHOICE
+ {
+ nsap NULL,
+ user NULL,
+ ...
+ }
+
+-- ---------------------------------
+--
+-- SupportedProtocols
+--
+-- @prop dataType
+-- @descr Gives detailed information about protocols that are
+-- supported by the stated endpoint.
+-- @
+-- ---------------------------------
+
+SupportedProtocols ::= CHOICE
+{
+ nonStandardData NonStandardParameter,
+ h310 H310Information,
+ h320 H320Information,
+ h321 H321Information,
+ h322 H322Information,
+ h323 H323Information,
+ h324 H324Information,
+ voice VoiceInformation,
+ t120Only T120Information,
+ ...
+}
+
+
+-- ---------------------------------
+--
+-- T120Information
+--
+-- @prop dataType
+-- @descr Gives detailed information about the standard protocol T.120
+-- @
+-- ---------------------------------
+
+T120Information ::= SEQUENCE
+{
+ nonStandardData NonStandardParameter OPTIONAL,
+ ...
+}
+
+
+-- ---------------------------------
+--
+-- TerminalInformation
+-- @prop dataType
+--
+-- @
+--
+-- ---------------------------------
+
+TerminalInformation ::= SEQUENCE
+{
+ nonStandardData NonStandardParameter OPTIONAL,
+ ...
+}
+
+
+-- ---------------------------------
+--
+-- TerminationInitiatior
+--
+-- @prop dataType
+-- @descr States who initiated the termination.
+-- @
+--
+-- ---------------------------------
+
+TerminationInitiatior ::= CHOICE
+{
+ endpoint NULL,
+ serviceNode NULL,
+ ...
+}
+
+
+
+-- ---------------------------------
+--
+-- TimeSlot
+--
+-- @prop dataType
+-- @descr This parameter contains the identity of the time slot used
+-- for the connection.
+-- @
+--
+-- ---------------------------------
+
+TimeSlot ::= INTEGER
+
+-- @prop dataType
+-- @descr Origin: Q931
+-- @
+
+ TransferCapability ::= CHOICE
+ {
+ speech NULL,
+ unrestrictedDigital NULL,
+ restrictedDigital NULL,
+ audio3point1kHz NULL,
+ unrestrictedWithTonesAndAnnouncements NULL,
+ video NULL,
+ ...
+ }
+
+-- @prop dataType
+-- @descr Origin: Q931
+-- @
+
+ TransferRate ::= CHOICE
+ {
+ packedMode NULL,
+ r64kbps NULL,
+ r2x64kbps NULL,
+ r384kbps NULL,
+ r1536kbps NULL,
+ r1920kbps NULL,
+ multirate NULL,
+ ...
+ }
+
+-- ---------------------------------
+--
+-- TransportAddress
+--
+-- @prop dataType
+-- @descr The transport address.
+-- @
+--
+-- ---------------------------------
+
+TransportAddress ::= CHOICE
+{
+ ipV4Address SEQUENCE
+ {
+ ip OCTET STRING ( SIZE (4) ),
+ port INTEGER ( 0..65535 )
+ },
+
+ ipV6Address SEQUENCE
+ {
+ ip OCTET STRING ( SIZE (16) ),
+ port INTEGER ( 0..65535 ),
+ ...
+ },
+ ...
+}
+
+
+-- ---------------------------------
+--
+-- TransportAddressInformation
+--
+-- @prop dataType
+-- @descr sequence of TransportAdress
+-- @
+-- ---------------------------------
+
+TransportAddressInformation ::= SEQUENCE OF TransportAddress
+
+
+-- ---------------------------------
+--
+-- TransportChannelInformation
+--
+-- @prop dataType
+-- @
+--
+-- ---------------------------------
+
+TransportChannelInformation ::= SEQUENCE
+{
+ sendAddress TransportAddress OPTIONAL,
+ recvAddress TransportAddress OPTIONAL,
+ ...
+}
+
+
+-- ---------------------------------
+--
+-- TypeOfEquipment
+--
+-- @prop dataType
+-- @descr Type of equipment.
+-- @
+--
+-- ---------------------------------
+
+TypeOfEquipment ::= CHOICE
+{
+ cordlessTerminal NULL,
+ h323Terminal NULL,
+ h323Gateway NULL,
+ isdnTerminal NULL,
+ ...
+}
+
+
+
+-- ---------------------------------
+--
+-- TypeOfFlowControl
+--
+-- @prop dataType
+-- @descr This parameter specifies the type of flow control used in the LAN.
+-- @
+--
+-- ---------------------------------
+
+TypeOfFlowControl ::= CHOICE
+{
+ isa NULL,
+ priorityOutputRouting NULL,
+ other NULL,
+ undefined NULL,
+ ...
+}
+
+
+
+-- ---------------------------------
+--
+-- TypeOfLAN
+--
+-- @prop dataType
+-- @descr This parameter specifies the type of LAN.
+-- @
+--
+-- ---------------------------------
+
+TypeOfLAN ::= CHOICE
+{
+ ethernet NULL,
+ tokenRing NULL,
+ other NULL,
+ undefined NULL,
+ ...
+}
+
+
+
+-- ---------------------------------
+--
+-- TypeOfRegistration
+--
+-- @prop dataType
+-- @descr Type of service.
+-- @
+--
+-- ---------------------------------
+
+TypeOfRegistration ::= CHOICE
+{
+ changeOfUser NULL,
+ noChangeOfUser NULL,
+ ...
+}
+
+
+
+-- ---------------------------------
+--
+-- TypeOfService
+--
+-- @prop dataType
+-- @descr Type of service.
+-- @
+--
+-- ---------------------------------
+
+TypeOfService ::= CHOICE
+{
+ basicCall NULL,
+ endpointRegistration NULL,
+ endpointUnregistration NULL,
+ ...
+}
+
+
+
+-- ---------------------------------
+--
+-- TypeOfUser
+--
+-- @prop dataType
+-- @descr Type of user.
+-- @
+--
+-- ---------------------------------
+
+TypeOfUser ::= CHOICE
+{
+ human NULL,
+ network NULL,
+ ...
+}
+
+
+
+-- ---------------------------------
+--
+-- UnknownMessageResponse
+--
+-- @prop dataType
+-- @descr
+-- @
+--
+-- ---------------------------------
+
+UnknownMessageResponse ::= SEQUENCE
+{
+ requestSeqNum RequestSeqNum,
+ ...
+}
+
+-- ---------------------------------
+--
+-- UnregistrationRejectReason
+--
+-- @prop dataType
+-- @descr
+-- @
+--
+-- ---------------------------------
+
+UnregistrationRejectReason ::= CHOICE
+{
+ notCurrentlyRegistered NULL,
+ callInProgress NULL,
+ undefinedReason NULL,
+ ...
+}
+
+-- ---------------------------------
+--
+-- UserAllocateResourceRejectReason
+--
+-- @prop dataType
+-- @descr Reason for the rejection.
+-- @
+--
+-- ---------------------------------
+
+UserAllocateResourceRejectReason ::= CHOICE
+{
+ keyNotValid NULL,
+ resourceNotAvailable NULL,
+ serviceIdentifierExist NULL,
+ undefined NULL,
+ ...
+}
+
+
+
+-- ---------------------------------
+--
+-- UserAttributeData
+--
+-- @prop dataType
+--
+-- @descr This parameter contains an User attribute value.
+--
+-- @
+--
+-- ---------------------------------
+
+UserAttributeData ::= CHOICE
+{
+ maximumTotalBandwidth Bandwidth,
+ maximumBandwidthPerService Bandwidth,
+ relationToEquipment SEQUENCE OF RelationToEquipment,
+ stateOfUser StateOfUser,
+ typeOfUser TypeOfUser,
+ userIdentifierInformation SEQUENCE OF UserIdentifier,
+ ...
+}
+
+
+
+-- ---------------------------------
+--
+-- UserAttributeIdentifier
+--
+-- @prop dataType
+--
+-- @descr This parameter contains User attribute identifiers.
+--
+-- @
+--
+-- ---------------------------------
+
+UserAttributeIdentifier ::= CHOICE
+{
+ maximumTotalBandwidth NULL,
+ maximumBandwidthPerService NULL,
+ relationToEquipment NULL,
+ stateOfUser NULL,
+ typeOfUser NULL,
+ userIdentifierInformation NULL,
+ ...
+}
+
+
+
+-- ---------------------------------
+--
+-- UserCreateRejectReason
+--
+-- @prop dataType
+--
+-- @descr This parameter states the reason for the rejection.
+--
+-- @
+--
+-- ---------------------------------
+
+UserCreateRejectReason ::= CHOICE
+{
+ userIdentifierAlreadyExist NULL,
+ undefined NULL,
+ ...
+}
+
+
+
+-- ---------------------------------
+--
+-- UserDeallocateResourceRejectReason
+-- @prop dataType
+--
+-- @descr Reason for the rejection.
+-- @
+--
+-- ---------------------------------
+
+UserDeallocateResourceRejectReason ::= CHOICE
+{
+ resourceNotAllocated NULL,
+ serviceIdentifierNotValid NULL,
+ userNotExist NULL,
+ undefined NULL,
+ ...
+}
+
+
+
+-- ---------------------------------
+--
+-- UserIdentifier
+--
+-- @prop dataType
+-- @descr The identifier of the User.
+-- @
+--
+-- ---------------------------------
+
+UserIdentifier ::= CHOICE
+{
+ e164 E164Identifier,
+ h323 BMPString (SIZE (1..256)),
+ -- h323 is Basic ISO/IEC 10646-1 (Unicode)
+ ...
+}
+
+
+-- ---------------------------------
+--
+-- UserIdentifierInformation
+--
+-- @prop dataType
+-- @descr sequence of UserIdentifier
+-- @
+--
+-- ---------------------------------
+
+UserIdentifierInformation ::= SEQUENCE OF UserIdentifier--
+-- Created by :
+-- Creation date :
+-- Modified by :
+-- Modification date :
+-- Version :
+--
+-- @prop dataType
+-- @
+
+UserInformation ::= OCTET STRING (SIZE(1..131))
+
+
+
+
+-- ---------------------------------
+--
+-- UserInformationUUIE
+--
+-- @prop dataType
+-- @ --
+-- ---------------------------------
+
+UserInformationUUIE ::= SEQUENCE
+{
+ protocolIdentifier ProtocolIdentifier,
+ ...
+}
+
+
+-- ---------------------------------
+--
+-- UserKey
+--
+-- @prop dataType
+-- @descr Unique key for a certain user.
+-- @
+-- ---------------------------------
+
+UserKey ::= CHOICE
+{
+ relationToUser RelationToUser,
+ userIdentifierInformation SEQUENCE OF UserIdentifier,
+ ...
+}
+
+
+-- ---------------------------------
+--
+-- UserOrEquipmentRelatedInformation
+--
+-- @prop dataType
+-- @descr This parameter specifies the type of information.
+-- @
+-- ---------------------------------
+
+UserOrEquipmentRelatedInformation ::= CHOICE
+{
+ userRelatedInformation SEQUENCE OF UserRelatedInformation,
+ equipmentRelatedInformation SEQUENCE OF EquipmentRelatedInformation,
+ ...
+}
+
+
+
+-- ---------------------------------
+--
+-- UserOrEquipmentRelatedInformationIdentifier
+--
+-- @prop dataType
+-- @descr This parameter specifies the type of information identifiers.
+-- @
+-- ---------------------------------
+
+UserOrEquipmentRelatedInformationIdentifier ::= CHOICE
+{
+ userRelatedInformationIdentifiers SEQUENCE OF UserRelatedInformationIdentifier,
+ equipmentRelatedInformationIdentifiers SEQUENCE OF EquipmentRelatedInformationIdentifier,
+ ...
+}
+
+
+
+-- ---------------------------------
+--
+-- UserRelatedInformation
+--
+-- @prop dataType
+-- @descr This parameter specifies different types of data
+-- that are related to the user.
+-- @
+--
+-- ---------------------------------
+
+UserRelatedInformation ::= CHOICE
+{
+ numberOfEquipments INTEGER,
+ stateOfUser StateOfUser,
+ typeOfUser TypeOfUser,
+ ...
+}
+
+
+
+-- ---------------------------------
+--
+-- UserRelatedInformationIdentifier
+--
+--
+-- @prop dataType
+--
+-- @descr This parameter specifies different types of data
+-- that are specific to a certain user.
+--
+-- @
+-- ---------------------------------
+
+UserRelatedInformationIdentifier ::= CHOICE
+{
+ numberOfEquipments NULL,
+ stateOfUser NULL,
+ typeOfUser NULL,
+ ...
+}
+
+
+
+-- ---------------------------------
+--
+-- UserRemoveRejectReason
+--
+-- @prop dataType
+--
+-- @descr This parameter states the reason for the rejection.
+--
+-- @
+--
+-- ---------------------------------
+
+UserRemoveRejectReason ::= CHOICE
+{
+ keyNotValid NULL,
+ serviceInProgress NULL,
+ undefined NULL,
+ ...
+}
+
+
+
+-- ---------------------------------
+--
+-- UserSetRejectReason
+--
+-- @prop dataType
+--
+-- @descr This parameter states the reason for the rejection.
+--
+-- @
+--
+-- ---------------------------------
+
+UserSetRejectReason ::= CHOICE
+{
+ keyNotValid NULL,
+ undefined NULL,
+ ...
+}
+
+
+
+-- ---------------------------------
+--
+-- UserSpecificInformation
+--
+-- @descr This parameter specifies different types of data
+-- that are specific to the user.
+-- @
+--
+-- ---------------------------------
+
+UserSpecificInformation ::= CHOICE
+{
+ userRelatedInformation SEQUENCE OF UserRelatedInformation,
+ equipmentRelatedInformation SEQUENCE OF EquipmentRelatedInformation,
+ ...
+}
+
+
+
+-- ---------------------------------
+--
+-- VendorIdentifier
+--
+-- @prop dataType
+-- @
+--
+-- ---------------------------------
+
+VendorIdentifier ::= SEQUENCE
+{
+ vendor H221NonStandard,
+ productId OCTET STRING (SIZE(1..256)) OPTIONAL,
+ versionId OCTET STRING (SIZE(1..256)) OPTIONAL,
+ ...
+}
+
+
+-- ---------------------------------
+--
+-- VoiceInformation
+--
+-- @prop dataType
+-- @descr
+-- @
+--
+-- ---------------------------------
+
+VoiceInformation ::= SEQUENCE
+{
+ nonStandardData NonStandardParameter OPTIONAL,
+ ...
+}
+END
diff --git a/lib/asn1/test/asn1_SUITE_data/Constraints.py b/lib/asn1/test/asn1_SUITE_data/Constraints.py
new file mode 100644
index 0000000000..b18c29bd89
--- /dev/null
+++ b/lib/asn1/test/asn1_SUITE_data/Constraints.py
@@ -0,0 +1,84 @@
+Constraints DEFINITIONS ::=
+BEGIN
+
+-- Single Value
+SingleValue ::= INTEGER (1)
+SingleValue2 ::= INTEGER (1..20)
+Range2to19 ::= INTEGER (1<..<20)
+Range10to20 ::= INTEGER (10..20)
+ContainedSubtype ::= INTEGER (INCLUDES Range10to20)
+FixedSize ::= OCTET STRING (SIZE(10))
+FixedSize2 ::= OCTET STRING (SIZE(10|20))
+VariableSize ::= OCTET STRING (SIZE(1..10))
+PemittedAlphabet ::= PrintableString (FROM ("a"|"yx"))
+AliasAddress ::=CHOICE
+{
+ e164 IA5String (SIZE (1..128) ^ FROM ("0123456789#*,")),
+ h323-ID BMPString (SIZE (1..256)),
+ ...
+}
+Obj ::= OBJECT IDENTIFIER
+
+
+-- OTP-4559: a referenced type that has a permitted alphabet constraint
+-- Example from H323-MESSAGES ver (11/2000)
+TBCD-STRING ::= IA5String (FROM ("0123456789#*abc"))
+
+ANSI-41-UIM ::= SEQUENCE {
+ imsi [0] TBCD-STRING(SIZE (3..16)) OPTIONAL,
+ esn [1] TBCD-STRING(SIZE (16)) OPTIONAL
+}
+
+-- OTP-4869: a BIT STRING constrained by SIZE(C) was encoded wrong
+-- when C was larger than 16. There was also an error when encodeing
+-- in compact_bit_string mode.
+
+IP ::= SEQUENCE {
+ perm SEQUENCE OF INTEGER (0..15),
+ key BIT STRING (SIZE (128)),
+ bool BOOLEAN OPTIONAL
+}
+
+-- add for OTP-3558 and OTP-4917
+Day ::= ENUMERATED{monday(0),tuesday(1),wednesday(2),thursday(3),friday(4),saturday(5),sunday(6)}
+
+Wednesday ::= Day(wednesday)
+
+
+Thing ::= INTEGER {fred (0),fred2 (1),fred3 (2)}
+
+
+AnotherThing ::= Thing (fred | fred2)
+
+I ::= INTEGER (0|15..269) -- OTP-5457
+
+-- OTP-5511
+
+maxNrOfCellPortionsPerCell-1 INTEGER ::= 35
+CellPortionID ::= INTEGER (0..maxNrOfCellPortionsPerCell-1,...)
+
+-- OTP-6763
+T ::= IA5String (SIZE (1|2, ..., SIZE (1|2|3))) -- Dubuisson 268
+T2 ::= IA5String (SIZE (1|2, ..., 3)) -- equal with T
+
+-- OTP-8046
+DateAndTime ::= VisibleString (PATTERN "\d#2/\d#2/\d#4-\d#2:\d#2")
+-- DD/MM/YYYY-HH:MM
+
+
+-- OTP-6828
+HandoverCommand-r8-IEs ::= SEQUENCE {
+ handoverCommandMessage OCTET STRING (CONTAINING MyType),
+ ...
+}
+
+MoreCompact ::= OCTET STRING (CONTAINING MyType ENCODED BY {joint-iso-itu-t asn1 packed-encoding(3) basic(0) unaligned(1)})
+
+MyType ::= SEQUENCE {a INTEGER, b INTEGER}
+
+Document ::= OCTET STRING (ENCODED BY pdf)
+
+pdf OBJECT IDENTIFIER ::= {1,2,3,4,5}
+
+
+END
diff --git a/lib/asn1/test/asn1_SUITE_data/Constructed.asn b/lib/asn1/test/asn1_SUITE_data/Constructed.asn
new file mode 100644
index 0000000000..09a66d0c0d
--- /dev/null
+++ b/lib/asn1/test/asn1_SUITE_data/Constructed.asn
@@ -0,0 +1,23 @@
+
+
+
+Constructed DEFINITIONS ::=
+BEGIN
+
+S ::= [UNIVERSAL 8] IMPLICIT SEQUENCE {
+ b BOOLEAN
+ }
+
+I ::= [8] IMPLICIT INTEGER
+
+S2 ::= [UNIVERSAL 8] SEQUENCE { b BOOLEAN}
+
+C ::= CHOICE {
+ a S,
+ b S3
+}
+
+S3 ::= SEQUENCE {i INTEGER}
+
+S3ext ::= SEQUENCE {i INTEGER, ...}
+END
diff --git a/lib/asn1/test/asn1_SUITE_data/ContextSwitchingTypes.asn1 b/lib/asn1/test/asn1_SUITE_data/ContextSwitchingTypes.asn1
new file mode 100644
index 0000000000..c8145bad63
--- /dev/null
+++ b/lib/asn1/test/asn1_SUITE_data/ContextSwitchingTypes.asn1
@@ -0,0 +1,53 @@
+ContextSwitchingTypes DEFINITIONS AUTOMATIC TAGS ::=
+
+BEGIN
+
+-- EXTERNAL type
+
+T ::= EXTERNAL
+
+Seq ::= SEQUENCE {
+ a INTEGER,
+ b T
+}
+
+int INTEGER ::= 12
+
+val1-T T ::= {indirect-reference int, encoding octet-aligned:'123'H}
+
+val2-T T ::= {identification syntax:{1 2 3}, data-value '123'H}
+
+val3-T T ::= {identification context-negotiation:{presentation-context-id 12,
+ transfer-syntax {1 2 3}},
+ data-value '123'H}
+
+-- EMBEDDED PDV type
+
+EP ::= EMBEDDED PDV
+
+Seq2 ::= SEQUENCE {
+ a BOOLEAN,
+ b EP
+}
+
+val1-EP EP ::= {identification syntaxes:{abstract {1 2 3 4},
+ transfer {1 2 3 5}},
+ data-value '12345'H}
+
+val2-EP EP ::= {identification syntax:{1 2 3}, data-value '123'H}
+
+-- CHARACTER STRING type and value
+
+CS ::= CHARACTER STRING
+
+Seq3 ::= SEQUENCE {
+ a INTEGER,
+ b CS
+}
+
+val1-CS CS ::= {identification syntaxes:{abstract {1 2 3 4},
+ transfer {1 2 3 5}},
+ string-value '12345'H}
+
+
+END
diff --git a/lib/asn1/test/asn1_SUITE_data/DERSpec.asn b/lib/asn1/test/asn1_SUITE_data/DERSpec.asn
new file mode 100644
index 0000000000..93e6180d42
--- /dev/null
+++ b/lib/asn1/test/asn1_SUITE_data/DERSpec.asn
@@ -0,0 +1,38 @@
+DERSpec DEFINITIONS ::=
+
+BEGIN
+
+Seq ::= SEQUENCE {
+ int [1] INTEGER,
+ choice C,
+ bool BOOLEAN
+}
+
+C ::= CHOICE {
+ version INTEGER,
+ message PrintableString
+}
+
+Set ::= SET {
+ int [1] INTEGER,
+ choice C,
+ bool BOOLEAN
+}
+
+
+SetOf ::= SET OF C
+
+-- This type compiled with ber_bin, optimize, der
+-- will test the fix in OTP-4866
+Set2 ::= SET {
+ int INTEGER,
+ bool BOOLEAN}
+
+-- OTP-5602
+SO ::= SEQUENCE OF Seq2
+
+Seq2 ::= SEQUENCE {
+ a INTEGER,
+ b BOOLEAN}
+
+END \ No newline at end of file
diff --git a/lib/asn1/test/asn1_SUITE_data/DS-EquipmentUser-CommonFunctionOrig-TransmissionPath.py b/lib/asn1/test/asn1_SUITE_data/DS-EquipmentUser-CommonFunctionOrig-TransmissionPath.py
new file mode 100644
index 0000000000..a17fb001d3
--- /dev/null
+++ b/lib/asn1/test/asn1_SUITE_data/DS-EquipmentUser-CommonFunctionOrig-TransmissionPath.py
@@ -0,0 +1,150 @@
+DS-EquipmentUser-CommonFunctionOrig-TransmissionPath DEFINITIONS AUTOMATIC TAGS ::=
+BEGIN
+
+IMPORTS AllocateTransmissionPathRejectReason,
+ Bandwidth,
+ BandwidthReducedInformation,
+ CallType,
+ ConnectionIdentifier,
+ ConnectionInformation,
+ ConnectTransmissionPathRejectReason,
+ DeallocateTransmissionPathRejectReason,
+ DisconnectTransmissionPathRejectReason,
+ RelationToUser,
+ UserIdentifier FROM CommonDataTypes ;
+
+EquipmentUserCommonFunctionOrigTransmissionPathMessages ::= CHOICE
+{
+ allocateTransmissionPathEU AllocateTransmissionPathEU,
+ allocateTransmissionPathConfirmedUE AllocateTransmissionPathConfirmedUE, -- Reply
+ allocateTransmissionPathRejectedUE AllocateTransmissionPathRejectedUE, -- Reply
+ connectTransmissionPathEU ConnectTransmissionPathEU,
+ connectTransmissionPathConfirmedUE ConnectTransmissionPathConfirmedUE, -- Reply
+ connectTransmissionPathRejectedUE ConnectTransmissionPathRejectedUE, -- Reply
+ deallocateTransmissionPathEU DeallocateTransmissionPathEU,
+ deallocateTransmissionPathConfirmedUE DeallocateTransmissionPathConfirmedUE, -- Reply
+ deallocateTransmissionPathRejectedUE DeallocateTransmissionPathRejectedUE, -- Reply
+ disconnectTransmissionPathEU DisconnectTransmissionPathEU,
+ disconnectTransmissionPathConfirmedUE DisconnectTransmissionPathConfirmedUE, -- Reply
+ disconnectTransmissionPathRejectedUE DisconnectTransmissionPathRejectedUE, -- Reply
+ ...
+}
+
+
+
+-- ----------------------------------
+--
+-- Allocate transmission path
+--
+--
+-- ----------------------------------
+
+AllocateTransmissionPathEU ::= SEQUENCE
+{
+ callType CallType,
+ bandwidth Bandwidth,
+ destinationUserIdentifiers SEQUENCE OF UserIdentifier,
+ sourceConnectionInformation ConnectionInformation,
+ relationToSourceUser RelationToUser,
+ ...
+}
+
+
+--
+-- @param bandwidthReducedInformation Mandatory if bandwidth has been reduced.
+--
+--
+
+AllocateTransmissionPathConfirmedUE ::= SEQUENCE
+{
+ connectionIdentifier ConnectionIdentifier,
+ bandwidthReducedInformation BandwidthReducedInformation OPTIONAL,
+ ...
+}
+
+
+AllocateTransmissionPathRejectedUE ::= SEQUENCE
+{
+ allocateTransmissionPathRejectReason AllocateTransmissionPathRejectReason,
+ ...
+}
+
+
+-- ----------------------------------
+--
+-- Connect transmission path
+--
+-- ----------------------------------
+
+ConnectTransmissionPathEU ::= SEQUENCE
+{
+ connectionIdentifier ConnectionIdentifier,
+ ...
+}
+
+ConnectTransmissionPathConfirmedUE ::= SEQUENCE
+{
+ ...
+}
+
+
+ConnectTransmissionPathRejectedUE ::= SEQUENCE
+{
+ connectTransmissionPathRejectReason ConnectTransmissionPathRejectReason,
+ ...
+}
+
+
+-- ----------------------------------
+--
+-- Deallocate transmission path
+--
+-- ----------------------------------
+
+DeallocateTransmissionPathEU ::= SEQUENCE
+{
+ connectionIdentifier ConnectionIdentifier,
+ ...
+}
+
+
+DeallocateTransmissionPathConfirmedUE ::= SEQUENCE
+{
+ ...
+}
+
+
+DeallocateTransmissionPathRejectedUE ::= SEQUENCE
+{
+ deallocateTransmissionPathRejectReason DeallocateTransmissionPathRejectReason,
+ ...
+}
+
+
+-- ----------------------------------
+--
+-- Disconnect transmission path
+--
+-- ----------------------------------
+
+DisconnectTransmissionPathEU ::= SEQUENCE
+{
+ connectionIdentifier ConnectionIdentifier,
+ ...
+}
+
+
+DisconnectTransmissionPathConfirmedUE ::= SEQUENCE
+{
+ ...
+}
+
+
+DisconnectTransmissionPathRejectedUE ::= SEQUENCE
+{
+ disconnectTransmissionPathRejectReason DisconnectTransmissionPathRejectReason,
+ ...
+}
+
+END
+
diff --git a/lib/asn1/test/asn1_SUITE_data/Def.asn1 b/lib/asn1/test/asn1_SUITE_data/Def.asn1
new file mode 100644
index 0000000000..8dd5b383e3
--- /dev/null
+++ b/lib/asn1/test/asn1_SUITE_data/Def.asn1
@@ -0,0 +1,31 @@
+Def DEFINITIONS IMPLICIT TAGS ::=
+
+BEGIN
+
+Def1 ::= SEQUENCE
+{
+ bool0 [0] BOOLEAN,
+ bool1 [1] BOOLEAN DEFAULT FALSE,
+ bool2 [2] BOOLEAN DEFAULT FALSE,
+ bool3 [3] BOOLEAN DEFAULT FALSE
+}
+
+
+Def2 ::= SEQUENCE
+{
+ bool10 [10] BOOLEAN,
+ bool11 [11] BOOLEAN DEFAULT FALSE,
+ bool12 [12] BOOLEAN DEFAULT FALSE,
+ bool13 [13] BOOLEAN
+}
+
+
+Def3 ::= SEQUENCE
+{
+ bool30 [30] BOOLEAN DEFAULT FALSE,
+ bool31 [31] BOOLEAN DEFAULT FALSE,
+ bool32 [32] BOOLEAN DEFAULT FALSE,
+ bool33 [33] BOOLEAN DEFAULT FALSE
+}
+
+END
diff --git a/lib/asn1/test/asn1_SUITE_data/Def.py b/lib/asn1/test/asn1_SUITE_data/Def.py
new file mode 100644
index 0000000000..ff08ed6386
--- /dev/null
+++ b/lib/asn1/test/asn1_SUITE_data/Def.py
@@ -0,0 +1,31 @@
+Def DEFINITIONS IMPLICIT TAGS ::=
+
+BEGIN
+
+Def1 ::= SEQUENCE
+{
+ bool0 [0] BOOLEAN,
+ bool1 [1] BOOLEAN DEFAULT false,
+ bool2 [2] BOOLEAN DEFAULT false,
+ bool3 [3] BOOLEAN DEFAULT false
+}
+
+
+Def2 ::= SEQUENCE
+{
+ bool10 [10] BOOLEAN,
+ bool11 [11] BOOLEAN DEFAULT false,
+ bool12 [12] BOOLEAN DEFAULT false,
+ bool13 [13] BOOLEAN
+}
+
+
+Def3 ::= SEQUENCE
+{
+ bool30 [30] BOOLEAN DEFAULT false,
+ bool31 [31] BOOLEAN DEFAULT false,
+ bool32 [32] BOOLEAN DEFAULT false,
+ bool33 [33] BOOLEAN DEFAULT false
+}
+
+END
diff --git a/lib/asn1/test/asn1_SUITE_data/Default.asn b/lib/asn1/test/asn1_SUITE_data/Default.asn
new file mode 100644
index 0000000000..6604953c1f
--- /dev/null
+++ b/lib/asn1/test/asn1_SUITE_data/Default.asn
@@ -0,0 +1,158 @@
+Default DEFINITIONS AUTOMATIC TAGS ::=
+
+BEGIN
+
+SeqInts ::= SEQUENCE {
+ a INTEGER DEFAULT 1,
+ b INTEGER DEFAULT -1,
+ c INTEGER {one(1),two(2),three(3)} DEFAULT three,
+ d INTEGER DEFAULT one
+}
+
+SetInts ::= SET {
+ a INTEGER DEFAULT 1,
+ b INTEGER DEFAULT -1,
+ c INTEGER {one(1),two(2),three(3)} DEFAULT three,
+ d INTEGER DEFAULT one
+}
+
+
+SeqBS ::= SEQUENCE {
+ a BIT STRING DEFAULT '1010110'B,
+ b BIT STRING DEFAULT 'A8A'H,
+ c BIT STRING {first(0),second(1),third(2)} DEFAULT {second},
+ d BIT STRING DEFAULT onelist
+}
+
+SetBS ::= SET {
+ a BIT STRING DEFAULT '1010110'B,
+ b BIT STRING DEFAULT 'A8A'H,
+ c BIT STRING {first(0),second(1),third(2)} DEFAULT {second},
+ d BIT STRING DEFAULT onelist
+}
+
+onelist BIT STRING ::= '1001'B
+
+SeqOS ::= SEQUENCE {
+ a OCTET STRING DEFAULT '1010110'B,
+ b OCTET STRING DEFAULT 'A8A'H,
+ c NULL DEFAULT NULL
+}
+
+SetOS ::= SET {
+ a OCTET STRING DEFAULT '1010110'B,
+ b OCTET STRING DEFAULT 'A8A'H,
+ c NULL DEFAULT NULL
+}
+
+E ::= ENUMERATED {b1,b2,b3}
+
+SeqOI ::= SEQUENCE {
+ a OBJECT IDENTIFIER DEFAULT {1 2 14 15},
+ b OBJECT IDENTIFIER DEFAULT {iso member-body f(250) 3 4},
+ c OBJECT IDENTIFIER DEFAULT {ftam 2 f(250) 4}--,
+}
+
+SetOI ::= SET {
+ a OBJECT IDENTIFIER DEFAULT {1 2 14 15},
+ b OBJECT IDENTIFIER DEFAULT {iso member-body f(250) 3 4},
+ c OBJECT IDENTIFIER DEFAULT {ftam 2 f(250) 4}--,
+}
+
+SeqEnum ::= SEQUENCE {
+ a ENUMERATED {b1,b2,b3,b4,b5} DEFAULT b4,
+ b F DEFAULT b2
+}
+
+SetEnum ::= SET {
+ a ENUMERATED {b1,b2,b3,b4,b5} DEFAULT b4,
+ b F DEFAULT b2
+}
+
+ftam OBJECT IDENTIFIER ::= {iso standard 8571}
+
+F ::= E
+
+SeqIntBool ::= SEQUENCE {
+ a SEQUENCE{
+ aa INTEGER,
+ ab INTEGER} DEFAULT {aa 12, ab 13},
+ b S2 DEFAULT {a 14, b TRUE},
+ c S2 DEFAULT s
+}
+
+SetIntBool ::= SET {
+ a SET{
+ aa INTEGER,
+ ab INTEGER} DEFAULT {aa 12, ab 13},
+ b S2 DEFAULT {a 14, b TRUE},
+ c S2 DEFAULT s
+}
+
+SeqStrings ::= SEQUENCE {
+ a NumericString DEFAULT "123456789",
+ b1 IA5String DEFAULT "abcdef",
+ b2 IA5String DEFAULT {0,13},
+ b3 IA5String DEFAULT {"First line",cr,"Second line"},
+ c PrintableString DEFAULT "Printable string",
+ d UniversalString DEFAULT {0,0,1,14}
+}
+
+SetStrings ::= SET {
+ a NumericString DEFAULT "123456789",
+ b1 IA5String DEFAULT "abcdef",
+ b2 IA5String DEFAULT {0,13},
+ b3 IA5String DEFAULT {"First line",cr,"Second line"},
+ c PrintableString DEFAULT "Printable string",
+ d UniversalString DEFAULT {0,0,1,14}
+}
+
+S1 ::= SEQUENCE {
+ a SEQUENCE {aa INTEGER, ab S2} DEFAULT {aa 1, ab {a two, b TRUE}},
+ b S4 DEFAULT s4
+}
+
+S2 ::= SEQUENCE {
+ a INTEGER DEFAULT one,
+ b BOOLEAN OPTIONAL
+}
+
+S3 ::= SEQUENCE {
+ a SEQUENCE OF INTEGER DEFAULT {11,12,13},
+ b SEQUENCE OF C DEFAULT {a:11,b:TRUE,c:13},
+ c SO DEFAULT so,
+ d SEQUENCE OF S2 DEFAULT {{a 20,b TRUE},{a 30, b FALSE}}
+}
+
+S3set ::= SET {
+ a SET OF CHOICE {a BOOLEAN,b INTEGER,c S2} DEFAULT {c:{a 3,b TRUE},b:17,a:FALSE},
+ b SO DEFAULT so
+}
+
+S4 ::= SEQUENCE {
+ a S2 DEFAULT {},
+ b SEQUENCE {ba BOOLEAN,bb INTEGER} DEFAULT {ba TRUE,bb 0}
+}
+
+s4 S4 ::= {a {a 2,b TRUE}, b {ba TRUE, bb 5}}
+
+C ::= CHOICE{
+ a INTEGER,
+ b BOOLEAN,
+ c INTEGER
+}
+
+SO ::= SEQUENCE OF INTEGER
+
+so SEQUENCE OF INTEGER ::= {1,2,3,4}
+
+s S2 ::= {a 15,b FALSE}
+
+one INTEGER ::= 1
+two INTEGER ::= 2
+three INTEGER ::= 3
+four INTEGER ::= 4
+
+cr IA5String ::= {0,13}
+
+END
diff --git a/lib/asn1/test/asn1_SUITE_data/DirectoryAbstractService.asn b/lib/asn1/test/asn1_SUITE_data/DirectoryAbstractService.asn
new file mode 100755
index 0000000000..5a5d310729
--- /dev/null
+++ b/lib/asn1/test/asn1_SUITE_data/DirectoryAbstractService.asn
@@ -0,0 +1,710 @@
+-- Module DirectoryAbstractService (X.511:08/1997)
+DirectoryAbstractService {joint-iso-itu-t ds(5) module(1)
+ directoryAbstractService(2) 3} DEFINITIONS ::=
+BEGIN
+
+-- EXPORTS All
+-- The types and values defined in this module are exported for use in the other ASN.1 modules contained
+-- within the Directory Specifications, and for the use of other applications which will use them to access
+-- Directory services. Other applications may use them for their own purposes, but this will not constrain
+-- extensions and modifications needed to maintain or improve the Directory service.
+IMPORTS
+ informationFramework, distributedOperations, authenticationFramework,
+ dap, directoryShadowAbstractService, basicAccessControl, enhancedSecurity,
+ id-at
+ FROM UsefulDefinitions {joint-iso-itu-t ds(5) module(1)
+ usefulDefinitions(0) 3}
+ AttributeTypeAndValue
+ FROM BasicAccessControl basicAccessControl
+ AgreementID
+ FROM DirectoryShadowAbstractService directoryShadowAbstractService
+ Attribute, AttributeType, AttributeValue, AttributeValueAssertion,
+ DistinguishedName, Name, RelativeDistinguishedName, SupportedAttributes,
+ ATTRIBUTE, MATCHING-RULE, ContextAssertion, AttributeTypeAssertion,
+ OBJECT-CLASS, RelaxationPolicy
+ FROM InformationFramework informationFramework
+ OperationProgress, ReferenceType, Exclusions, AccessPoint,
+ ContinuationReference
+ FROM DistributedOperations distributedOperations
+ CertificationPath, SIGNED{}, SIGNATURE{}, ENCRYPTED{}, AlgorithmIdentifier,
+ AttributeCertificationPath
+ FROM AuthenticationFramework authenticationFramework
+ OPTIONALLY-PROTECTED{}, OPTIONALLY-PROTECTED-SEQ{}
+ FROM EnhancedSecurity enhancedSecurity
+ id-opcode-read, id-opcode-compare, id-opcode-abandon, id-opcode-list,
+ id-opcode-search, id-opcode-addEntry, id-opcode-removeEntry,
+ id-opcode-modifyEntry, id-opcode-modifyDN, id-errcode-abandoned,
+ id-errcode-abandonFailed, id-errcode-attributeError, id-errcode-nameError,
+ id-errcode-referral, id-errcode-securityError, id-errcode-serviceError,
+ id-errcode-updateError
+ FROM DirectoryAccessProtocol dap
+ OPERATION, ERROR, Code
+ FROM Remote-Operations-Information-Objects {joint-iso-itu-t
+ remote-operations(4) informationObjects(5) version1(0)}
+ emptyUnbind
+ FROM Remote-Operations-Useful-Definitions {joint-iso-itu-t
+ remote-operations(4) useful-definitions(7) version1(0)}
+ InvokeId
+ FROM Remote-Operations-Generic-ROS-PDUs {joint-iso-itu-t
+ remote-operations(4) generic-ROS-PDUs(6) version1(0)}
+ --PROTECTED
+ -- FROM Notation { joint-iso-itu-t genericULS (20) modules (1) notation (1) }
+ SPKM-REQ, SPKM-REP-TI, SPKM-ERROR
+ FROM SpkmGssTokens {iso(1) identified-organization(3) dod(6) internet(1)
+ security(5) mechanisms(5) spkm(1) spkmGssTokens(10)};
+
+-- Common data types
+-- Parameterized type for representing optional signing
+OPTIONALLY-SIGNED{Type} ::= CHOICE {unsigned Type,
+ signed SIGNED{Type}
+}
+
+CommonArguments ::= SET {
+ serviceControls [30] ServiceControls DEFAULT {},
+ securityParameters [29] SecurityParameters OPTIONAL,
+ requestor [28] DistinguishedName OPTIONAL,
+ operationProgress
+ [27] OperationProgress DEFAULT {nameResolutionPhase notStarted},
+ aliasedRDNs [26] INTEGER OPTIONAL,
+ criticalExtensions [25] BIT STRING OPTIONAL,
+ referenceType [24] ReferenceType OPTIONAL,
+ entryOnly [23] BOOLEAN DEFAULT TRUE,
+ nameResolveOnMaste [21] BOOLEAN DEFAULT FALSE,
+ operationContexts [20] ContextSelection OPTIONAL,
+ familyGrouping [19] FamilyGrouping DEFAULT entryOnly
+}
+
+FamilyGrouping ::= ENUMERATED {
+ entryOnly(1), compoundEntry(2), strands(3), multiStrand(4)}
+
+CommonResults ::= SET {
+ securityParameters [30] SecurityParameters OPTIONAL,
+ performer [29] DistinguishedName OPTIONAL,
+ aliasDereferenced [28] BOOLEAN DEFAULT FALSE,
+ notification [27] SEQUENCE SIZE (1..MAX) OF Attribute OPTIONAL
+}
+
+CommonResultsSeq ::= SEQUENCE {
+ securityParameters [30] SecurityParameters OPTIONAL,
+ performer [29] DistinguishedName OPTIONAL,
+ aliasDereferenced [28] BOOLEAN DEFAULT FALSE
+}
+
+ServiceControls ::= SET {
+ options [0] ServiceControlOptions DEFAULT {},
+ priority [1] INTEGER {low(0), medium(1), high(2)} DEFAULT medium,
+ timeLimit [2] INTEGER OPTIONAL,
+ sizeLimit [3] INTEGER OPTIONAL,
+ scopeOfReferral [4] INTEGER {dmd(0), country(1)} OPTIONAL,
+ attributeSizeLimit [5] INTEGER OPTIONAL,
+ manageDSAITPlaneRef
+ [6] SEQUENCE {dsaName Name,
+ agreementID AgreementID} OPTIONAL,
+ serviceType [7] OBJECT IDENTIFIER OPTIONAL,
+ userClass [8] INTEGER OPTIONAL
+}
+
+ServiceControlOptions ::= BIT STRING {
+ preferChaining(0), chainingProhibited(1), localScope(2), dontUseCopy(3),
+ dontDereferenceAliases(4), subentries(5), copyShallDo(6),
+ partialNameResolution(7), manageDSAIT(8), noSubtypeMatch(9),
+ noSubtypeSelection(10), countFamily(11)}
+
+EntryInformationSelection ::= SET {
+ attributes
+ CHOICE {allUserAttributes [0] NULL,
+ select [1] SET OF AttributeType
+ -- empty set implies no attributes are requested
+ } DEFAULT allUserAttributes:NULL,
+ infoTypes
+ [2] INTEGER {attributeTypesOnly(0), attributeTypesAndValues(1)}
+ DEFAULT attributeTypesAndValues,
+ extraAttributes
+ CHOICE {allOperationalAttributes [3] NULL,
+ select [4] SET OF AttributeType} OPTIONAL,
+ contextSelection ContextSelection OPTIONAL,
+ returnContexts BOOLEAN DEFAULT FALSE,
+ familyReturn FamilyReturn DEFAULT {memberSelect contributingEntriesOnly}
+}
+
+ContextSelection ::= CHOICE {
+ allContexts NULL,
+ selectedContexts SET OF TypeAndContextAssertion
+}
+
+TypeAndContextAssertion ::= SEQUENCE {
+ type AttributeType,
+ contextAssertions
+ CHOICE {preference SEQUENCE OF ContextAssertion,
+ all SET OF ContextAssertion}
+}
+
+FamilyReturn ::= SEQUENCE {
+ memberSelect
+ ENUMERATED {contributingEntriesOnly(1), participatingEntriesOnly(2),
+ compoundEntry(3)},
+ familySelect SEQUENCE SIZE (1..MAX) OF OBJECT-CLASS.&id OPTIONAL
+}
+
+family-information ATTRIBUTE ::= {
+ WITH SYNTAX FamilyEntries
+ USAGE directoryOperation
+ ID id-at-family-information
+}
+
+FamilyEntries ::= SEQUENCE {
+ family-class OBJECT-CLASS.&id, -- structural object class value
+ familyEntries SEQUENCE OF FamilyEntry
+}
+
+FamilyEntry ::= SEQUENCE {
+ rdn RelativeDistinguishedName,
+ information
+ SEQUENCE OF CHOICE {attributeType AttributeType,
+ attribute Attribute},
+ family-info SEQUENCE SIZE (1..MAX) OF FamilyEntries OPTIONAL
+}
+
+EntryInformation ::= SEQUENCE {
+ name Name,
+ fromEntry BOOLEAN DEFAULT TRUE,
+ information
+ SET SIZE (1..MAX) OF
+ CHOICE {attributeType AttributeType,
+ attribute Attribute} OPTIONAL,
+ incompleteEntry [3] BOOLEAN DEFAULT FALSE, -- not in 1988-edition systems
+ partialNameResolution
+ [4] BOOLEAN DEFAULT FALSE -- not in 1988 or 1993 edition systems --
+}
+
+Filter ::= CHOICE {
+ item [0] FilterItem,
+ and [1] SET OF Filter,
+ or [2] SET OF Filter,
+ not [3] Filter
+}
+
+FilterItem ::= CHOICE {
+ equality [0] AttributeValueAssertion,
+ substrings
+ [1] SEQUENCE {type ATTRIBUTE.&id({SupportedAttributes}),
+ strings
+ SEQUENCE OF
+ CHOICE {initial
+ [0] ATTRIBUTE.&Type
+ ({SupportedAttributes}
+ {@substrings.type}),
+ any
+ [1] ATTRIBUTE.&Type
+ ({SupportedAttributes}
+ {@substrings.type}),
+ final
+ [2] ATTRIBUTE.&Type
+ ({SupportedAttributes}
+ {@substrings.type}),
+ control Attribute -- Used to specify interpretation of following items
+ }},
+ greaterOrEqual [2] AttributeValueAssertion,
+ lessOrEqual [3] AttributeValueAssertion,
+ present [4] AttributeType,
+ approximateMatch [5] AttributeValueAssertion,
+ extensibleMatch [6] MatchingRuleAssertion,
+ contextPresent [7] AttributeTypeAssertion
+}
+
+MatchingRuleAssertion ::= SEQUENCE {
+ matchingRule [1] SET SIZE (1..MAX) OF MATCHING-RULE.&id,
+ type [2] AttributeType OPTIONAL,
+ matchValue
+ [3] MATCHING-RULE.&AssertionType
+ (CONSTRAINED BY {
+ -- matchValue must be a value of type specified by the &AssertionType field of
+ -- one of the MATCHING-RULE information objects identified by matchingRule -- }),
+ dnAttributes [4] BOOLEAN DEFAULT FALSE
+}
+
+PagedResultsRequest ::= CHOICE {
+ newRequest
+ SEQUENCE {pageSize INTEGER,
+ sortKeys SEQUENCE SIZE (1..MAX) OF SortKey OPTIONAL,
+ reverse [1] BOOLEAN DEFAULT FALSE,
+ unmerged [2] BOOLEAN DEFAULT FALSE},
+ queryReference OCTET STRING
+}
+
+SortKey ::= SEQUENCE {
+ type AttributeType,
+ orderingRule MATCHING-RULE.&id OPTIONAL
+}
+
+SecurityParameters ::= SET {
+ certification-path [0] CertificationPath OPTIONAL,
+ name [1] DistinguishedName OPTIONAL,
+ time [2] Time OPTIONAL,
+ random [3] BIT STRING OPTIONAL,
+ target [4] ProtectionRequest OPTIONAL,
+ response [5] BIT STRING OPTIONAL,
+ operationCode [6] Code OPTIONAL,
+ attributeCertificationPath [7] AttributeCertificationPath OPTIONAL,
+ errorProtection [8] ErrorProtectionRequest OPTIONAL,
+ errorCode [9] Code OPTIONAL
+}
+
+ProtectionRequest ::= INTEGER {
+ none(0), signed(1), encrypted(2), signed-encrypted(3)}
+
+Time ::= CHOICE {utcTime UTCTime,
+ generalizedTime GeneralizedTime
+}
+
+ErrorProtectionRequest ::= INTEGER {
+ none(0), signed(1), encrypted(2), signed-encrypted(3)}
+
+-- Bind and unbind operations
+directoryBind OPERATION ::= {
+ ARGUMENT DirectoryBindArgument
+ RESULT DirectoryBindResult
+ ERRORS {directoryBindError}
+}
+
+DirectoryBindArgument ::= SET {
+ credentials [0] Credentials OPTIONAL,
+ versions [1] Versions DEFAULT {v1}
+}
+
+Credentials ::= CHOICE {
+ simple [0] SimpleCredentials,
+ strong [1] StrongCredentials,
+ externalProcedure [2] EXTERNAL,
+ spkm [3] SpkmCredentials
+}
+
+SimpleCredentials ::= SEQUENCE {
+ name [0] DistinguishedName,
+ validity
+ [1] SET {time1 [0] CHOICE {utc UTCTime,
+ gt GeneralizedTime} OPTIONAL,
+ time2 [1] CHOICE {utc UTCTime,
+ gt GeneralizedTime} OPTIONAL,
+ random1 [2] BIT STRING OPTIONAL,
+ random2 [3] BIT STRING OPTIONAL},
+ password
+ [2] CHOICE {unprotected OCTET STRING,
+ protected SIGNATURE{OCTET STRING}} OPTIONAL
+}
+
+StrongCredentials ::= SET {
+ certification-path [0] CertificationPath OPTIONAL,
+ bind-token [1] Token,
+ name [2] DistinguishedName OPTIONAL,
+ attributeCertificationPath [3] AttributeCertificationPath OPTIONAL
+}
+
+SpkmCredentials ::= CHOICE {req [0] SPKM-REQ,
+ rep [1] SPKM-REP-TI
+}
+
+Token ::=
+ SIGNED
+ {SEQUENCE {algorithm [0] AlgorithmIdentifier,
+ name [1] DistinguishedName,
+ time [2] Time,
+ random [3] BIT STRING,
+ response [4] BIT STRING OPTIONAL,
+ bindIntAlgorithm
+ [5] SEQUENCE SIZE (1..MAX) OF AlgorithmIdentifier OPTIONAL,
+ bindIntKeyInfo [6] BindKeyInfo OPTIONAL,
+ bindConfAlgorithm
+ [7] SEQUENCE SIZE (1..MAX) OF AlgorithmIdentifier OPTIONAL,
+ bindConfKeyInfo [8] BindKeyInfo OPTIONAL}}
+
+Versions ::= BIT STRING {v1(0), v2(1)}
+
+DirectoryBindResult ::= DirectoryBindArgument
+
+directoryBindError ERROR ::= {
+ PARAMETER OPTIONALLY-PROTECTED
+ {SET {versions [0] Versions DEFAULT {v1},
+ error
+ CHOICE {serviceError [1] ServiceProblem,
+ securityError [2] SecurityProblem}}}
+}
+
+BindKeyInfo ::= ENCRYPTED{BIT STRING}
+
+directoryUnbind OPERATION ::= emptyUnbind
+
+-- Operations, arguments, and results
+read OPERATION ::= {
+ ARGUMENT ReadArgument
+ RESULT ReadResult
+ ERRORS
+ {attributeError | nameError | serviceError | referral | abandoned |
+ securityError}
+ CODE id-opcode-read
+}
+
+ReadArgument ::=
+ OPTIONALLY-PROTECTED
+ {SET {object [0] Name,
+ selection [1] EntryInformationSelection DEFAULT {},
+ modifyRightsRequest [2] BOOLEAN DEFAULT FALSE,
+ COMPONENTS OF CommonArguments}}
+
+ReadResult ::=
+ OPTIONALLY-PROTECTED
+ {SET {entry [0] EntryInformation,
+ modifyRights [1] ModifyRights OPTIONAL,
+ COMPONENTS OF CommonResults}}
+
+ModifyRights ::=
+ SET OF
+ SEQUENCE {item
+ CHOICE {entry [0] NULL,
+ attribute [1] AttributeType,
+ value [2] AttributeValueAssertion},
+ permission
+ [3] BIT STRING {add(0), remove(1), rename(2), move(3)}
+ }
+
+compare OPERATION ::= {
+ ARGUMENT CompareArgument
+ RESULT CompareResult
+ ERRORS
+ {attributeError | nameError | serviceError | referral | abandoned |
+ securityError}
+ CODE id-opcode-compare
+}
+
+CompareArgument ::=
+ OPTIONALLY-PROTECTED
+ {SET {object [0] Name,
+ purported [1] AttributeValueAssertion,
+ COMPONENTS OF CommonArguments}}
+
+CompareResult ::=
+ OPTIONALLY-PROTECTED
+ {SET {name Name OPTIONAL,
+ matched [0] BOOLEAN,
+ fromEntry [1] BOOLEAN DEFAULT TRUE,
+ matchedSubtype [2] AttributeType OPTIONAL,
+ COMPONENTS OF CommonResults}}
+
+abandon OPERATION ::= {
+ ARGUMENT AbandonArgument
+ RESULT AbandonResult
+ ERRORS {abandonFailed}
+ CODE id-opcode-abandon
+}
+
+AbandonArgument ::=
+ OPTIONALLY-PROTECTED-SEQ{SEQUENCE {invokeID [0] InvokeId}}
+
+AbandonResult ::= CHOICE {
+ null NULL,
+ information
+ OPTIONALLY-PROTECTED-SEQ{SEQUENCE {invokeID InvokeId,
+ COMPONENTS OF CommonResultsSeq
+ }}
+}
+
+list OPERATION ::= {
+ ARGUMENT ListArgument
+ RESULT ListResult
+ ERRORS {nameError | serviceError | referral | abandoned | securityError}
+ CODE id-opcode-list
+}
+
+ListArgument ::=
+ OPTIONALLY-PROTECTED
+ {SET {object [0] Name,
+ pagedResults [1] PagedResultsRequest OPTIONAL,
+ listFamily [2] BOOLEAN DEFAULT FALSE,
+ COMPONENTS OF CommonArguments}}
+
+ListResult ::=
+ OPTIONALLY-PROTECTED
+ {CHOICE {listInfo
+ SET {name Name OPTIONAL,
+ subordinates
+ [1] SET OF
+ SEQUENCE {rdn RelativeDistinguishedName,
+ aliasEntry [0] BOOLEAN DEFAULT FALSE,
+ fromEntry [1] BOOLEAN DEFAULT TRUE
+ },
+ partialOutcomeQualifier
+ [2] PartialOutcomeQualifier OPTIONAL,
+ COMPONENTS OF CommonResults},
+ uncorrelatedListInfo [0] SET OF ListResult}}
+
+PartialOutcomeQualifier ::= SET {
+ limitProblem [0] LimitProblem OPTIONAL,
+ unexplored
+ [1] SET SIZE (1..MAX) OF ContinuationReference OPTIONAL,
+ unavailableCriticalExtensions [2] BOOLEAN DEFAULT FALSE,
+ unknownErrors
+ [3] SET SIZE (1..MAX) OF ABSTRACT-SYNTAX.&Type OPTIONAL,
+ queryReference [4] OCTET STRING OPTIONAL,
+ overspecFilter [5] Filter OPTIONAL,
+ notification
+ [6] SEQUENCE SIZE (1..MAX) OF Attribute OPTIONAL,
+ entryCount
+ CHOICE {bestEstimate [7] INTEGER,
+ lowEstimate [8] INTEGER} OPTIONAL
+}
+
+LimitProblem ::= INTEGER {
+ timeLimitExceeded(0), sizeLimitExceeded(1), administrativeLimitExceeded(2)
+}
+
+search OPERATION ::= {
+ ARGUMENT SearchArgument
+ RESULT SearchResult
+ ERRORS
+ {attributeError | nameError | serviceError | referral | abandoned |
+ securityError}
+ CODE id-opcode-search
+}
+
+SearchArgument ::=
+ OPTIONALLY-PROTECTED
+ {SET {baseObject [0] Name,
+ subset
+ [1] INTEGER {baseObject(0), oneLevel(1), wholeSubtree(2)}
+ DEFAULT baseObject,
+ filter [2] Filter DEFAULT and:{},
+ searchAliases [3] BOOLEAN DEFAULT TRUE,
+ selection [4] EntryInformationSelection DEFAULT {},
+ pagedResults [5] PagedResultsRequest OPTIONAL,
+ matchedValuesOnly [6] BOOLEAN DEFAULT FALSE,
+ extendedFilter [7] Filter OPTIONAL,
+ checkOverspecified [8] BOOLEAN DEFAULT FALSE,
+ relaxation [9] RelaxationPolicy OPTIONAL,
+ extendedArea [10] INTEGER OPTIONAL,
+ hierarchySelections [11] HierarchySelections DEFAULT {self},
+ searchControlOptions
+ [12] SearchControlOptions DEFAULT {searchAliases},
+ COMPONENTS OF CommonArguments}}
+
+HierarchySelections ::= BIT STRING {
+ self(0), children(1), parent(2), hierarchy(3), top(4), subtree(5),
+ siblings(6), siblingChildren(7), siblingSubtree(8), all(9)}
+
+SearchControlOptions ::= BIT STRING {
+ searchAliases(0), matchedValuesOnly(1), checkOverspecified(2),
+ performExactly(3), includeAllAreas(4), noSystemRelaxation(5), dnAttribute(6),
+ matchOnResidualName(7), entryCount(8), useSubset(9),
+ separateFamilyMembers(10), searchFamily(11)}
+
+SearchResult ::=
+ OPTIONALLY-PROTECTED
+ {CHOICE {searchInfo
+ SET {name Name OPTIONAL,
+ entries [0] SET OF EntryInformation,
+ partialOutcomeQualifier
+ [2] PartialOutcomeQualifier OPTIONAL,
+ altMatching [3] BOOLEAN DEFAULT FALSE,
+ COMPONENTS OF CommonResults},
+ uncorrelatedSearchInfo [0] SET OF SearchResult}}
+
+addEntry OPERATION ::= {
+ ARGUMENT AddEntryArgument
+ RESULT AddEntryResult
+ ERRORS
+ {attributeError | nameError | serviceError | referral | securityError |
+ updateError}
+ CODE id-opcode-addEntry
+}
+
+AddEntryArgument ::=
+ OPTIONALLY-PROTECTED
+ {SET {object [0] Name,
+ entry [1] SET OF Attribute,
+ targetSystem [2] AccessPoint OPTIONAL,
+ COMPONENTS OF CommonArguments}}
+
+AddEntryResult ::= CHOICE {
+ null NULL,
+ information
+ OPTIONALLY-PROTECTED-SEQ{SEQUENCE {COMPONENTS OF CommonResultsSeq}}
+}
+
+removeEntry OPERATION ::= {
+ ARGUMENT RemoveEntryArgument
+ RESULT RemoveEntryResult
+ ERRORS {nameError | serviceError | referral | securityError | updateError}
+ CODE id-opcode-removeEntry
+}
+
+RemoveEntryArgument ::=
+ OPTIONALLY-PROTECTED{SET {object [0] Name,
+ COMPONENTS OF CommonArguments}}
+
+RemoveEntryResult ::= CHOICE {
+ null NULL,
+ information
+ OPTIONALLY-PROTECTED-SEQ{SEQUENCE {COMPONENTS OF CommonResultsSeq}}
+}
+
+modifyEntry OPERATION ::= {
+ ARGUMENT ModifyEntryArgument
+ RESULT ModifyEntryResult
+ ERRORS
+ {attributeError | nameError | serviceError | referral | securityError |
+ updateError}
+ CODE id-opcode-modifyEntry
+}
+
+ModifyEntryArgument ::=
+ OPTIONALLY-PROTECTED
+ {SET {object [0] Name,
+ changes [1] SEQUENCE OF EntryModification,
+ selection [2] EntryInformationSelection OPTIONAL,
+ COMPONENTS OF CommonArguments}}
+
+ModifyEntryResult ::= CHOICE {
+ null NULL,
+ information
+ OPTIONALLY-PROTECTED-SEQ{SEQUENCE {entry [0] EntryInformation OPTIONAL,
+ COMPONENTS OF CommonResultsSeq
+ }}
+}
+
+EntryModification ::= CHOICE {
+ addAttribute [0] Attribute,
+ removeAttribute [1] AttributeType,
+ addValues [2] Attribute,
+ removeValues [3] Attribute,
+ alterValues [4] AttributeTypeAndValue,
+ resetValue [5] AttributeType
+}
+
+modifyDN OPERATION ::= {
+ ARGUMENT ModifyDNArgument
+ RESULT ModifyDNResult
+ ERRORS {nameError | serviceError | referral | securityError | updateError}
+ CODE id-opcode-modifyDN
+}
+
+ModifyDNArgument ::=
+ OPTIONALLY-PROTECTED
+ {SET {object [0] DistinguishedName,
+ newRDN [1] RelativeDistinguishedName,
+ deleteOldRDN [2] BOOLEAN DEFAULT FALSE,
+ newSuperior [3] DistinguishedName OPTIONAL,
+ COMPONENTS OF CommonArguments}}
+
+ModifyDNResult ::= CHOICE {
+ null NULL,
+ information
+ OPTIONALLY-PROTECTED-SEQ{SEQUENCE {newRDN RelativeDistinguishedName,
+ COMPONENTS OF CommonResultsSeq
+ }}
+}
+
+-- Errors and parameters
+abandoned ERROR ::= { -- not literally an "error"
+ PARAMETER OPTIONALLY-PROTECTED {SET {COMPONENTS OF CommonResults}}
+ CODE id-errcode-abandoned
+}
+
+abandonFailed ERROR ::= {
+ PARAMETER OPTIONALLY-PROTECTED
+ {SET {problem [0] AbandonProblem,
+ operation [1] InvokeId,
+ COMPONENTS OF CommonResults}}
+ CODE id-errcode-abandonFailed
+}
+
+AbandonProblem ::= INTEGER {noSuchOperation(1), tooLate(2), cannotAbandon(3)}
+
+attributeError ERROR ::= {
+ PARAMETER OPTIONALLY-PROTECTED
+ {SET {object [0] Name,
+ problems
+ [1] SET OF
+ SEQUENCE {problem [0] AttributeProblem,
+ type [1] AttributeType,
+ value [2] AttributeValue OPTIONAL},
+ COMPONENTS OF CommonResults}}
+ CODE id-errcode-attributeError
+}
+
+AttributeProblem ::= INTEGER {
+ noSuchAttributeOrValue(1), invalidAttributeSyntax(2),
+ undefinedAttributeType(3), inappropriateMatching(4), constraintViolation(5),
+ attributeOrValueAlreadyExists(6), contextViolation(7)}
+
+nameError ERROR ::= {
+ PARAMETER OPTIONALLY-PROTECTED
+ {SET {problem [0] NameProblem,
+ matched [1] Name,
+ COMPONENTS OF CommonResults}}
+ CODE id-errcode-nameError
+}
+
+NameProblem ::= INTEGER {
+ noSuchObject(1), aliasProblem(2), invalidAttributeSyntax(3),
+ aliasDereferencingProblem(4), contextProblem(5)}
+
+referral ERROR ::= { -- not literally an "error"
+ PARAMETER OPTIONALLY-PROTECTED
+ {SET {candidate [0] ContinuationReference,
+ COMPONENTS OF CommonResults}}
+ CODE id-errcode-referral
+}
+
+securityError ERROR ::= {
+ PARAMETER OPTIONALLY-PROTECTED
+ {SET {problem [0] SecurityProblem,
+ spkmInfo [1] SPKM-ERROR,
+ COMPONENTS OF CommonResults}}
+ CODE id-errcode-securityError
+}
+
+SecurityProblem ::= INTEGER {
+ inappropriateAuthentication(1), invalidCredentials(2),
+ insufficientAccessRights(3), invalidSignature(4), protectionRequired(5),
+ noInformation(6), blockedCredentials(7), invalidQOPMatch(8), spkmError(9)
+}
+
+serviceError ERROR ::= {
+ PARAMETER OPTIONALLY-PROTECTED
+ {SET {problem [0] ServiceProblem,
+ COMPONENTS OF CommonResults}}
+ CODE id-errcode-serviceError
+}
+
+ServiceProblem ::= INTEGER {
+ busy(1), unavailable(2), unwillingToPerform(3), chainingRequired(4),
+ unableToProceed(5), invalidReference(6), timeLimitExceeded(7),
+ administrativeLimitExceeded(8), loopDetected(9),
+ unavailableCriticalExtension(10), outOfScope(11), ditError(12),
+ invalidQueryReference(13), requestedServiceNotAvailable(14),
+ relaxationNotSupported(15), unavailableRelaxationLevel(16),
+ unsupportedMatchingUse(17), unmatchedKeyAttributes(18),
+ ambiguousKeyAttributes(19)}
+
+updateError ERROR ::= {
+ PARAMETER OPTIONALLY-PROTECTED
+ {SET {problem [0] UpdateProblem,
+ attributeInfo
+ [1] SET SIZE (1..MAX) OF
+ CHOICE {attributeType AttributeType,
+ attribute Attribute} OPTIONAL,
+ COMPONENTS OF CommonResults}}
+ CODE id-errcode-updateError
+}
+
+UpdateProblem ::= INTEGER {
+ namingViolation(1), objectClassViolation(2), notAllowedOnNonLeaf(3),
+ notAllowedOnRDN(4), entryAlreadyExists(5), affectsMultipleDSAs(6),
+ objectClassModificationProhibited(7), notAncestor(8), parentNotAncestor(9),
+ hierarchyRuleViolation(10), familyRuleViolation(11)}
+
+id-at-family-information OBJECT IDENTIFIER ::= {id-at 64}
+
+END -- DirectoryAbstractService
+
+-- Generated by Asnp, the ASN.1 pretty-printer of France Telecom R&D
+
diff --git a/lib/asn1/test/asn1_SUITE_data/DoubleEllipses.asn b/lib/asn1/test/asn1_SUITE_data/DoubleEllipses.asn
new file mode 100644
index 0000000000..e90cf55d61
--- /dev/null
+++ b/lib/asn1/test/asn1_SUITE_data/DoubleEllipses.asn
@@ -0,0 +1,99 @@
+DoubleEllipses DEFINITIONS AUTOMATIC TAGS ::=
+
+
+BEGIN
+
+
+Seq ::= SEQUENCE
+ {
+ a INTEGER,
+ ...,
+ ...,
+ c BOOLEAN
+ }
+
+SeqV2 ::= SEQUENCE
+ {
+ a INTEGER,
+ ...,
+ b BOOLEAN,
+ ...,
+ c BOOLEAN
+ }
+
+
+SeqAlt ::= SEQUENCE
+ {
+ a INTEGER,
+ d INTEGER,
+ ...,
+ b BIT STRING,
+ e BOOLEAN,
+ ...,
+ c BOOLEAN,
+ f INTEGER,
+ g INTEGER
+ }
+
+SeqAltV2 ::= SEQUENCE
+ {
+ a INTEGER,
+ d INTEGER,
+ ...,
+ b BIT STRING,
+ e BOOLEAN,
+ h PrintableString,
+ i INTEGER,
+ ...,
+ c BOOLEAN,
+ f INTEGER,
+ g INTEGER
+ }
+
+Set ::= SET {
+ a INTEGER,
+ ...,
+ ...,
+ c BOOLEAN
+ }
+
+SetV2 ::= SET
+ {
+ a INTEGER,
+ ...,
+ b BOOLEAN,
+ ...,
+ c BOOLEAN
+ }
+
+
+SetAlt ::= SET
+ {
+ a INTEGER,
+ d INTEGER,
+ ...,
+ b BIT STRING,
+ e BOOLEAN,
+ ...,
+ c BOOLEAN,
+ f INTEGER,
+ g INTEGER
+ }
+
+SetAltV2 ::= SET
+ {
+ a INTEGER,
+ d INTEGER,
+ ...,
+ b BIT STRING,
+ e BOOLEAN,
+ h PrintableString,
+ i INTEGER,
+ ...,
+ c BOOLEAN,
+ f INTEGER,
+ g INTEGER
+ }
+
+
+END \ No newline at end of file
diff --git a/lib/asn1/test/asn1_SUITE_data/ELDAPv3.asn b/lib/asn1/test/asn1_SUITE_data/ELDAPv3.asn
new file mode 100644
index 0000000000..0cfac48c37
--- /dev/null
+++ b/lib/asn1/test/asn1_SUITE_data/ELDAPv3.asn
@@ -0,0 +1,291 @@
+-- LDAPv3 ASN.1 specification, taken from RFC 2251
+
+-- Lightweight-Directory-Access-Protocol-V3 DEFINITIONS
+ELDAPv3 DEFINITIONS
+IMPLICIT TAGS ::=
+
+BEGIN
+
+LDAPMessage ::= SEQUENCE {
+ messageID MessageID,
+ protocolOp CHOICE {
+ bindRequest BindRequest,
+ bindResponse BindResponse,
+ unbindRequest UnbindRequest,
+ searchRequest SearchRequest,
+ searchResEntry SearchResultEntry,
+ searchResDone SearchResultDone,
+ searchResRef SearchResultReference,
+ modifyRequest ModifyRequest,
+ modifyResponse ModifyResponse,
+ addRequest AddRequest,
+ addResponse AddResponse,
+ delRequest DelRequest,
+ delResponse DelResponse,
+ modDNRequest ModifyDNRequest,
+ modDNResponse ModifyDNResponse,
+ compareRequest CompareRequest,
+ compareResponse CompareResponse,
+ abandonRequest AbandonRequest,
+ extendedReq ExtendedRequest,
+ extendedResp ExtendedResponse },
+ controls [0] Controls OPTIONAL }
+
+MessageID ::= INTEGER (0 .. maxInt)
+
+maxInt INTEGER ::= 2147483647 -- (2^^31 - 1) --
+
+LDAPString ::= OCTET STRING
+
+LDAPOID ::= OCTET STRING
+
+LDAPDN ::= LDAPString
+
+RelativeLDAPDN ::= LDAPString
+
+AttributeType ::= LDAPString
+
+AttributeDescription ::= LDAPString
+
+
+
+
+-- Wahl, et. al. Standards Track [Page 44]
+--
+-- RFC 2251 LDAPv3 December 1997
+
+
+AttributeDescriptionList ::= SEQUENCE OF
+ AttributeDescription
+
+AttributeValue ::= OCTET STRING
+
+AttributeValueAssertion ::= SEQUENCE {
+ attributeDesc AttributeDescription,
+ assertionValue AssertionValue }
+
+AssertionValue ::= OCTET STRING
+
+Attribute ::= SEQUENCE {
+ type AttributeDescription,
+ vals SET OF AttributeValue }
+
+MatchingRuleId ::= LDAPString
+
+LDAPResult ::= SEQUENCE {
+ resultCode ENUMERATED {
+ success (0),
+ operationsError (1),
+ protocolError (2),
+ timeLimitExceeded (3),
+ sizeLimitExceeded (4),
+ compareFalse (5),
+ compareTrue (6),
+ authMethodNotSupported (7),
+ strongAuthRequired (8),
+ -- 9 reserved --
+ referral (10), -- new
+ adminLimitExceeded (11), -- new
+ unavailableCriticalExtension (12), -- new
+ confidentialityRequired (13), -- new
+ saslBindInProgress (14), -- new
+ noSuchAttribute (16),
+ undefinedAttributeType (17),
+ inappropriateMatching (18),
+ constraintViolation (19),
+ attributeOrValueExists (20),
+ invalidAttributeSyntax (21),
+ -- 22-31 unused --
+ noSuchObject (32),
+ aliasProblem (33),
+ invalidDNSyntax (34),
+ -- 35 reserved for undefined isLeaf --
+ aliasDereferencingProblem (36),
+ -- 37-47 unused --
+ inappropriateAuthentication (48),
+
+-- Wahl, et. al. Standards Track [Page 45]
+--
+-- RFC 2251 LDAPv3 December 1997
+
+
+ invalidCredentials (49),
+ insufficientAccessRights (50),
+ busy (51),
+ unavailable (52),
+ unwillingToPerform (53),
+ loopDetect (54),
+ -- 55-63 unused --
+ namingViolation (64),
+ objectClassViolation (65),
+ notAllowedOnNonLeaf (66),
+ notAllowedOnRDN (67),
+ entryAlreadyExists (68),
+ objectClassModsProhibited (69),
+ -- 70 reserved for CLDAP --
+ affectsMultipleDSAs (71), -- new
+ -- 72-79 unused --
+ other (80) },
+ -- 81-90 reserved for APIs --
+ matchedDN LDAPDN,
+ errorMessage LDAPString,
+ referral [3] Referral OPTIONAL }
+
+Referral ::= SEQUENCE OF LDAPURL
+
+LDAPURL ::= LDAPString -- limited to characters permitted in URLs
+
+Controls ::= SEQUENCE OF Control
+
+Control ::= SEQUENCE {
+ controlType LDAPOID,
+ criticality BOOLEAN DEFAULT FALSE,
+ controlValue OCTET STRING OPTIONAL }
+
+BindRequest ::= [APPLICATION 0] SEQUENCE {
+ version INTEGER (1 .. 127),
+ name LDAPDN,
+ authentication AuthenticationChoice }
+
+AuthenticationChoice ::= CHOICE {
+ simple [0] OCTET STRING,
+ -- 1 and 2 reserved
+ sasl [3] SaslCredentials }
+
+SaslCredentials ::= SEQUENCE {
+ mechanism LDAPString,
+ credentials OCTET STRING OPTIONAL }
+
+BindResponse ::= [APPLICATION 1] SEQUENCE {
+
+-- Wahl, et. al. Standards Track [Page 46]
+--
+-- RFC 2251 LDAPv3 December 1997
+
+
+ COMPONENTS OF LDAPResult,
+ serverSaslCreds [7] OCTET STRING OPTIONAL }
+
+UnbindRequest ::= [APPLICATION 2] NULL
+
+SearchRequest ::= [APPLICATION 3] SEQUENCE {
+ baseObject LDAPDN,
+ scope ENUMERATED {
+ baseObject (0),
+ singleLevel (1),
+ wholeSubtree (2) },
+ derefAliases ENUMERATED {
+ neverDerefAliases (0),
+ derefInSearching (1),
+ derefFindingBaseObj (2),
+ derefAlways (3) },
+ sizeLimit INTEGER (0 .. maxInt),
+ timeLimit INTEGER (0 .. maxInt),
+ typesOnly BOOLEAN,
+ filter Filter,
+ attributes AttributeDescriptionList }
+
+Filter ::= CHOICE {
+ and [0] SET OF Filter,
+ or [1] SET OF Filter,
+ not [2] Filter,
+ equalityMatch [3] AttributeValueAssertion,
+ substrings [4] SubstringFilter,
+ greaterOrEqual [5] AttributeValueAssertion,
+ lessOrEqual [6] AttributeValueAssertion,
+ present [7] AttributeDescription,
+ approxMatch [8] AttributeValueAssertion,
+ extensibleMatch [9] MatchingRuleAssertion }
+
+SubstringFilter ::= SEQUENCE {
+ type AttributeDescription,
+ -- at least one must be present
+ substrings SEQUENCE OF CHOICE {
+ initial [0] LDAPString,
+ any [1] LDAPString,
+ final [2] LDAPString } }
+
+MatchingRuleAssertion ::= SEQUENCE {
+ matchingRule [1] MatchingRuleId OPTIONAL,
+ type [2] AttributeDescription OPTIONAL,
+ matchValue [3] AssertionValue,
+ dnAttributes [4] BOOLEAN DEFAULT FALSE }
+
+-- Wahl, et. al. Standards Track [Page 47]
+--
+-- RFC 2251 LDAPv3 December 1997
+
+SearchResultEntry ::= [APPLICATION 4] SEQUENCE {
+ objectName LDAPDN,
+ attributes PartialAttributeList }
+
+PartialAttributeList ::= SEQUENCE OF SEQUENCE {
+ type AttributeDescription,
+ vals SET OF AttributeValue }
+
+SearchResultReference ::= [APPLICATION 19] SEQUENCE OF LDAPURL
+
+SearchResultDone ::= [APPLICATION 5] LDAPResult
+
+ModifyRequest ::= [APPLICATION 6] SEQUENCE {
+ object LDAPDN,
+ modification SEQUENCE OF SEQUENCE {
+ operation ENUMERATED {
+ add (0),
+ delete (1),
+ replace (2) },
+ modification AttributeTypeAndValues } }
+
+AttributeTypeAndValues ::= SEQUENCE {
+ type AttributeDescription,
+ vals SET OF AttributeValue }
+
+ModifyResponse ::= [APPLICATION 7] LDAPResult
+
+AddRequest ::= [APPLICATION 8] SEQUENCE {
+ entry LDAPDN,
+ attributes AttributeList }
+
+AttributeList ::= SEQUENCE OF SEQUENCE {
+ type AttributeDescription,
+ vals SET OF AttributeValue }
+
+AddResponse ::= [APPLICATION 9] LDAPResult
+
+DelRequest ::= [APPLICATION 10] LDAPDN
+
+DelResponse ::= [APPLICATION 11] LDAPResult
+
+ModifyDNRequest ::= [APPLICATION 12] SEQUENCE {
+ entry LDAPDN,
+ newrdn RelativeLDAPDN,
+ deleteoldrdn BOOLEAN,
+ newSuperior [0] LDAPDN OPTIONAL }
+
+ModifyDNResponse ::= [APPLICATION 13] LDAPResult
+
+-- Wahl, et. al. Standards Track [Page 48]
+--
+-- RFC 2251 LDAPv3 December 1997
+
+
+CompareRequest ::= [APPLICATION 14] SEQUENCE {
+ entry LDAPDN,
+ ava AttributeValueAssertion }
+
+CompareResponse ::= [APPLICATION 15] LDAPResult
+
+AbandonRequest ::= [APPLICATION 16] MessageID
+
+ExtendedRequest ::= [APPLICATION 23] SEQUENCE {
+ requestName [0] LDAPOID,
+ requestValue [1] OCTET STRING OPTIONAL }
+
+ExtendedResponse ::= [APPLICATION 24] SEQUENCE {
+ COMPONENTS OF LDAPResult,
+ responseName [10] LDAPOID OPTIONAL,
+ response [11] OCTET STRING OPTIONAL }
+
+END
+
+
diff --git a/lib/asn1/test/asn1_SUITE_data/EUTRA-InterNodeDefinitions.asn b/lib/asn1/test/asn1_SUITE_data/EUTRA-InterNodeDefinitions.asn
new file mode 100644
index 0000000000..5e6313dc02
--- /dev/null
+++ b/lib/asn1/test/asn1_SUITE_data/EUTRA-InterNodeDefinitions.asn
@@ -0,0 +1,123 @@
+-- 3GPP TS 36.331 V8.8.0 (2009-12)
+-- $Id$
+--
+EUTRA-InterNodeDefinitions DEFINITIONS AUTOMATIC TAGS ::=
+
+BEGIN
+
+
+HandoverCommand ::= SEQUENCE {
+ criticalExtensions CHOICE {
+ c1 CHOICE{
+ handoverCommand-r8 HandoverCommand-r8-IEs,
+ spare7 NULL,
+ spare6 NULL, spare5 NULL, spare4 NULL,
+ spare3 NULL, spare2 NULL, spare1 NULL
+ },
+ criticalExtensionsFuture SEQUENCE {}
+ }
+}
+
+HandoverCommand-r8-IEs ::= SEQUENCE {
+ handoverCommandMessage OCTET STRING (CONTAINING DL-DCCH-Message),
+ nonCriticalExtension SEQUENCE {} OPTIONAL
+}
+
+
+HandoverPreparationInformation ::= SEQUENCE {
+ criticalExtensions CHOICE {
+ c1 CHOICE{
+ handoverPreparationInformation-r8 HandoverPreparationInformation-r8-IEs,
+ spare7 NULL,
+ spare6 NULL, spare5 NULL, spare4 NULL,
+ spare3 NULL, spare2 NULL, spare1 NULL
+ },
+ criticalExtensionsFuture SEQUENCE {}
+ }
+}
+
+HandoverPreparationInformation-r8-IEs ::= SEQUENCE {
+ ue-RadioAccessCapabilityInfo UE-CapabilityRAT-ContainerList,
+ as-Config AS-Config OPTIONAL, -- Cond HO
+ rrm-Config RRM-Config OPTIONAL,
+ as-Context AS-Context OPTIONAL, -- Cond HO
+ nonCriticalExtension SEQUENCE {} OPTIONAL
+}
+
+
+UERadioAccessCapabilityInformation ::= SEQUENCE {
+ criticalExtensions CHOICE {
+ c1 CHOICE{
+ ueRadioAccessCapabilityInformation-r8
+ UERadioAccessCapabilityInformation-r8-IEs,
+ spare7 NULL,
+ spare6 NULL, spare5 NULL, spare4 NULL,
+ spare3 NULL, spare2 NULL, spare1 NULL
+ },
+ criticalExtensionsFuture SEQUENCE {}
+ }
+}
+
+UERadioAccessCapabilityInformation-r8-IEs ::= SEQUENCE {
+ ue-RadioAccessCapabilityInfo OCTET STRING (CONTAINING UECapabilityInformation),
+ nonCriticalExtension SEQUENCE {} OPTIONAL
+}
+
+
+AS-Config ::= SEQUENCE {
+ sourceMeasConfig MeasConfig,
+ sourceRadioResourceConfig RadioResourceConfigDedicated,
+ sourceSecurityAlgorithmConfig SecurityAlgorithmConfig,
+ sourceUE-Identity C-RNTI,
+ sourceMasterInformationBlock MasterInformationBlock,
+ sourceSystemInformationBlockType1 SystemInformationBlockType1,
+ sourceSystemInformationBlockType2 SystemInformationBlockType2,
+ antennaInfoCommon AntennaInfoCommon,
+ sourceDl-CarrierFreq ARFCN-ValueEUTRA,
+ ...
+}
+
+
+AS-Context ::= SEQUENCE {
+ reestablishmentInfo ReestablishmentInfo OPTIONAL -- Cond HO
+}
+
+
+ReestablishmentInfo ::= SEQUENCE {
+ sourcePhysCellId PhysCellId,
+ targetCellShortMAC-I ShortMAC-I,
+ additionalReestabInfoList AdditionalReestabInfoList OPTIONAL,
+ ...
+}
+
+AdditionalReestabInfoList ::= SEQUENCE ( SIZE (1..maxReestabInfo) ) OF AdditionalReestabInfo
+
+AdditionalReestabInfo ::= SEQUENCE{
+ cellIdentity CellIdentity,
+ key-eNodeB-Star Key-eNodeB-Star,
+ shortMAC-I ShortMAC-I
+}
+
+Key-eNodeB-Star ::= BIT STRING (SIZE (256))
+
+
+RRM-Config ::= SEQUENCE {
+ ue-InactiveTime ENUMERATED {
+ s1, s2, s3, s5, s7, s10, s15, s20,
+ s25, s30, s40, s50, min1, min1s20c, min1s40,
+ min2, min2s30, min3, min3s30, min4, min5, min6,
+ min7, min8, min9, min10, min12, min14, min17, min20,
+ min24, min28, min33, min38, min44, min50, hr1,
+ hr1min30, hr2, hr2min30, hr3, hr3min30, hr4, hr5, hr6,
+ hr8, hr10, hr13, hr16, hr20, day1, day1hr12, day2,
+ day2hr12, day3, day4, day5, day7, day10, day14, day19,
+ day24, day30, dayMoreThan30} OPTIONAL,
+ ...
+}
+
+
+maxReestabInfo INTEGER ::= 32 -- Maximum number of KeNB* and shortMAC-I forwarded
+ -- at handover for re-establishment preparation
+
+
+END
diff --git a/lib/asn1/test/asn1_SUITE_data/EUTRA-RRC-Definitions.asn b/lib/asn1/test/asn1_SUITE_data/EUTRA-RRC-Definitions.asn
new file mode 100644
index 0000000000..3b811dafe6
--- /dev/null
+++ b/lib/asn1/test/asn1_SUITE_data/EUTRA-RRC-Definitions.asn
@@ -0,0 +1,3155 @@
+-- 3GPP TS 36.331 v9.2.0
+-- http://cdmweb.ericsson.se/TeamCenter/controller/ViewDocs?DocumentName=51%2F15519-10%2FFCP1039669%2F11&Revision=A
+
+EUTRA-RRC-Definitions DEFINITIONS AUTOMATIC TAGS ::=
+
+BEGIN
+
+
+BCCH-BCH-Message ::= SEQUENCE {
+ message BCCH-BCH-MessageType
+}
+
+BCCH-BCH-MessageType ::= MasterInformationBlock
+
+
+BCCH-DL-SCH-Message ::= SEQUENCE {
+ message BCCH-DL-SCH-MessageType
+}
+
+BCCH-DL-SCH-MessageType ::= CHOICE {
+ c1 CHOICE {
+ systemInformation SystemInformation,
+ systemInformationBlockType1 SystemInformationBlockType1
+ },
+ messageClassExtension SEQUENCE {}
+}
+
+
+MCCH-Message ::= SEQUENCE {
+ message MCCH-MessageType
+}
+
+MCCH-MessageType ::= CHOICE {
+ c1 CHOICE {
+ mbsfnAreaConfiguration-r9 MBSFNAreaConfiguration-r9
+ },
+ messageClassExtension SEQUENCE {}
+}
+
+
+PCCH-Message ::= SEQUENCE {
+ message PCCH-MessageType
+}
+
+PCCH-MessageType ::= CHOICE {
+ c1 CHOICE {
+ paging Paging
+ },
+ messageClassExtension SEQUENCE {}
+}
+
+
+DL-CCCH-Message ::= SEQUENCE {
+ message DL-CCCH-MessageType
+}
+
+DL-CCCH-MessageType ::= CHOICE {
+ c1 CHOICE {
+ rrcConnectionReestablishment RRCConnectionReestablishment,
+ rrcConnectionReestablishmentReject RRCConnectionReestablishmentReject,
+ rrcConnectionReject RRCConnectionReject,
+ rrcConnectionSetup RRCConnectionSetup
+ },
+ messageClassExtension SEQUENCE {}
+}
+
+
+DL-DCCH-Message ::= SEQUENCE {
+ message DL-DCCH-MessageType
+}
+
+DL-DCCH-MessageType ::= CHOICE {
+ c1 CHOICE {
+ csfbParametersResponseCDMA2000 CSFBParametersResponseCDMA2000,
+ dlInformationTransfer DLInformationTransfer,
+ handoverFromEUTRAPreparationRequest HandoverFromEUTRAPreparationRequest,
+ mobilityFromEUTRACommand MobilityFromEUTRACommand,
+ rrcConnectionReconfiguration RRCConnectionReconfiguration,
+ rrcConnectionRelease RRCConnectionRelease,
+ securityModeCommand SecurityModeCommand,
+ ueCapabilityEnquiry UECapabilityEnquiry,
+ counterCheck CounterCheck,
+ ueInformationRequest-r9 UEInformationRequest-r9,
+ spare6 NULL, spare5 NULL, spare4 NULL,
+ spare3 NULL, spare2 NULL, spare1 NULL
+ },
+ messageClassExtension SEQUENCE {}
+}
+
+
+UL-CCCH-Message ::= SEQUENCE {
+ message UL-CCCH-MessageType
+}
+
+UL-CCCH-MessageType ::= CHOICE {
+ c1 CHOICE {
+ rrcConnectionReestablishmentRequest RRCConnectionReestablishmentRequest,
+ rrcConnectionRequest RRCConnectionRequest
+ },
+ messageClassExtension SEQUENCE {}
+}
+
+
+UL-DCCH-Message ::= SEQUENCE {
+ message UL-DCCH-MessageType
+}
+
+UL-DCCH-MessageType ::= CHOICE {
+ c1 CHOICE {
+ csfbParametersRequestCDMA2000 CSFBParametersRequestCDMA2000,
+ measurementReport MeasurementReport,
+ rrcConnectionReconfigurationComplete RRCConnectionReconfigurationComplete,
+ rrcConnectionReestablishmentComplete RRCConnectionReestablishmentComplete,
+ rrcConnectionSetupComplete RRCConnectionSetupComplete,
+ securityModeComplete SecurityModeComplete,
+ securityModeFailure SecurityModeFailure,
+ ueCapabilityInformation UECapabilityInformation,
+ulHandoverPreparationTransfer ULHandoverPreparationTransfer,
+ ulInformationTransfer ULInformationTransfer,
+ counterCheckResponse CounterCheckResponse,
+ ueInformationResponse-r9 UEInformationResponse-r9,
+ proximityIndication-r9 ProximityIndication-r9,
+ spare3 NULL, spare2 NULL, spare1 NULL
+ },
+ messageClassExtension SEQUENCE {}
+}
+
+
+CounterCheck ::= SEQUENCE {
+ rrc-TransactionIdentifier RRC-TransactionIdentifier,
+ criticalExtensions CHOICE {
+ c1 CHOICE {
+ counterCheck-r8 CounterCheck-r8-IEs,
+ spare3 NULL, spare2 NULL, spare1 NULL
+ },
+ criticalExtensionsFuture SEQUENCE {}
+ }
+}
+
+CounterCheck-r8-IEs ::= SEQUENCE {
+ drb-CountMSB-InfoList DRB-CountMSB-InfoList,
+ nonCriticalExtension SEQUENCE {} OPTIONAL --Need OP
+}
+
+DRB-CountMSB-InfoList ::= SEQUENCE (SIZE (1..maxDRB)) OF DRB-CountMSB-Info
+
+DRB-CountMSB-Info ::= SEQUENCE {
+ drb-Identity DRB-Identity,
+ countMSB-Uplink INTEGER(0..33554431),
+ countMSB-Downlink INTEGER(0..33554431)
+}
+
+
+CounterCheckResponse ::= SEQUENCE {
+ rrc-TransactionIdentifier RRC-TransactionIdentifier,
+ criticalExtensions CHOICE {
+ counterCheckResponse-r8 CounterCheckResponse-r8-IEs,
+ criticalExtensionsFuture SEQUENCE {}
+ }
+}
+
+CounterCheckResponse-r8-IEs ::= SEQUENCE {
+ drb-CountInfoList DRB-CountInfoList,
+ nonCriticalExtension SEQUENCE {} OPTIONAL
+}
+
+DRB-CountInfoList ::= SEQUENCE (SIZE (0..maxDRB)) OF DRB-CountInfo
+
+DRB-CountInfo ::= SEQUENCE {
+ drb-Identity DRB-Identity,
+ count-Uplink INTEGER(0..4294967295),
+ count-Downlink INTEGER(0..4294967295)
+}
+
+
+CSFBParametersRequestCDMA2000 ::= SEQUENCE {
+ criticalExtensions CHOICE {
+ csfbParametersRequestCDMA2000-r8 CSFBParametersRequestCDMA2000-r8-IEs,
+ criticalExtensionsFuture SEQUENCE {}
+ }
+}
+
+CSFBParametersRequestCDMA2000-r8-IEs ::= SEQUENCE {
+ nonCriticalExtension SEQUENCE {} OPTIONAL
+}
+
+CSFBParametersResponseCDMA2000 ::= SEQUENCE {
+ rrc-TransactionIdentifier RRC-TransactionIdentifier,
+ criticalExtensions CHOICE {
+ csfbParametersResponseCDMA2000-r8 CSFBParametersResponseCDMA2000-r8-IEs,
+ criticalExtensionsFuture SEQUENCE {}
+ }
+}
+
+CSFBParametersResponseCDMA2000-r8-IEs ::= SEQUENCE {
+ rand RAND-CDMA2000,
+ mobilityParameters MobilityParametersCDMA2000,
+ nonCriticalExtension SEQUENCE {} OPTIONAL --Need OP
+}
+
+
+DLInformationTransfer ::= SEQUENCE {
+ rrc-TransactionIdentifier RRC-TransactionIdentifier,
+ criticalExtensions CHOICE {
+ c1 CHOICE {
+ dlInformationTransfer-r8 DLInformationTransfer-r8-IEs,
+ spare3 NULL, spare2 NULL, spare1 NULL
+ },
+ criticalExtensionsFuture SEQUENCE {}
+ }
+}
+
+DLInformationTransfer-r8-IEs ::= SEQUENCE {
+ dedicatedInfoType CHOICE {
+ dedicatedInfoNAS DedicatedInfoNAS,
+ dedicatedInfoCDMA2000-1XRTT DedicatedInfoCDMA2000,
+ dedicatedInfoCDMA2000-HRPD DedicatedInfoCDMA2000
+ },
+ nonCriticalExtension SEQUENCE {} OPTIONAL --Need OP
+}
+
+
+HandoverFromEUTRAPreparationRequest ::= SEQUENCE {
+ rrc-TransactionIdentifier RRC-TransactionIdentifier,
+ criticalExtensions CHOICE {
+ c1 CHOICE {
+ handoverFromEUTRAPreparationRequest-r8
+ HandoverFromEUTRAPreparationRequest-r8-IEs,
+ spare3 NULL, spare2 NULL, spare1 NULL
+ },
+ criticalExtensionsFuture SEQUENCE {}
+ }
+}
+
+HandoverFromEUTRAPreparationRequest-r8-IEs ::= SEQUENCE {
+ cdma2000-Type CDMA2000-Type,
+ rand RAND-CDMA2000 OPTIONAL, -- Cond cdma2000-Type
+ mobilityParameters MobilityParametersCDMA2000 OPTIONAL, -- Cond cdma2000-Type
+ nonCriticalExtension HandoverFromEUTRAPreparationRequest-v890-IEs OPTIONAL
+}
+
+HandoverFromEUTRAPreparationRequest-v890-IEs ::= SEQUENCE {
+ lateR8NonCriticalExtension OCTET STRING OPTIONAL, -- Need OP
+ nonCriticalExtension HandoverFromEUTRAPreparationRequest-v920-IEs OPTIONAL
+}
+
+HandoverFromEUTRAPreparationRequest-v920-IEs ::= SEQUENCE {
+ concurrPrepCDMA2000-HRPD-r9 BOOLEAN OPTIONAL, -- Cond PSHO
+ nonCriticalExtension SEQUENCE {} OPTIONAL -- Need OP
+}
+
+
+MasterInformationBlock ::= SEQUENCE {
+ dl-Bandwidth ENUMERATED {
+ n6, n15, n25, n50, n75, n100},
+ phich-Config PHICH-Config,
+ systemFrameNumber BIT STRING (SIZE (8)),
+ spare BIT STRING (SIZE (10))
+}
+
+
+
+MBSFNAreaConfiguration-r9 ::= SEQUENCE {
+ commonSF-Alloc-r9 CommonSF-AllocPatternList-r9,
+ commonSF-AllocPeriod-r9 ENUMERATED {
+ rf4, rf8, rf16, rf32, rf64, rf128, rf256},
+ pmch-InfoList-r9 PMCH-InfoList-r9,
+ nonCriticalExtension SEQUENCE {} OPTIONAL -- Need OP
+}
+
+CommonSF-AllocPatternList-r9 ::= SEQUENCE (SIZE (1..maxMBSFN-Allocations)) OF MBSFN-SubframeConfig
+
+
+MeasurementReport ::= SEQUENCE {
+ criticalExtensions CHOICE {
+ c1 CHOICE{
+ measurementReport-r8 MeasurementReport-r8-IEs,
+ spare7 NULL,
+ spare6 NULL, spare5 NULL, spare4 NULL,
+ spare3 NULL, spare2 NULL, spare1 NULL
+ },
+ criticalExtensionsFuture SEQUENCE {}
+ }
+}
+
+MeasurementReport-r8-IEs ::= SEQUENCE {
+ measResults MeasResults,
+ nonCriticalExtension SEQUENCE {} OPTIONAL
+}
+
+
+MobilityFromEUTRACommand ::= SEQUENCE {
+ rrc-TransactionIdentifier RRC-TransactionIdentifier,
+ criticalExtensions CHOICE {
+ c1 CHOICE{
+ mobilityFromEUTRACommand-r8 MobilityFromEUTRACommand-r8-IEs,
+ mobilityFromEUTRACommand-r9 MobilityFromEUTRACommand-r9-IEs,
+ spare2 NULL, spare1 NULL
+ },
+ criticalExtensionsFuture SEQUENCE {}
+ }
+}
+
+MobilityFromEUTRACommand-r8-IEs ::= SEQUENCE {
+ cs-FallbackIndicator BOOLEAN,
+ purpose CHOICE{
+ handover Handover,
+ cellChangeOrder CellChangeOrder
+ },
+ nonCriticalExtension SEQUENCE {} OPTIONAL -- Need OP
+}
+
+MobilityFromEUTRACommand-r9-IEs ::= SEQUENCE {
+ cs-FallbackIndicator BOOLEAN,
+ purpose CHOICE{
+ handover Handover,
+ cellChangeOrder CellChangeOrder,
+ e-CSFB-r9 E-CSFB-r9,
+ ...
+ },
+ nonCriticalExtension SEQUENCE {} OPTIONAL -- Need OP
+}
+
+Handover ::= SEQUENCE {
+ targetRAT-Type ENUMERATED {
+ utra, geran, cdma2000-1XRTT, cdma2000-HRPD,
+ spare4, spare3, spare2, spare1, ...},
+ targetRAT-MessageContainer OCTET STRING,
+ nas-SecurityParamFromEUTRA OCTET STRING (SIZE (1)) OPTIONAL, -- Cond UTRAGERAN
+ systemInformation SI-OrPSI-GERAN OPTIONAL -- Cond PSHO
+}
+
+CellChangeOrder ::= SEQUENCE {
+ t304 ENUMERATED {
+ ms100, ms200, ms500, ms1000,
+ ms2000, ms4000, ms8000, spare1},
+ targetRAT-Type CHOICE {
+ geran SEQUENCE {
+ physCellId PhysCellIdGERAN,
+ carrierFreq CarrierFreqGERAN,
+ networkControlOrder BIT STRING (SIZE (2)) OPTIONAL, -- Need OP
+ systemInformation SI-OrPSI-GERAN OPTIONAL -- Need OP
+ },
+ ...
+ }
+}
+
+SI-OrPSI-GERAN ::= CHOICE {
+ si SystemInfoListGERAN,
+ psi SystemInfoListGERAN
+}
+
+E-CSFB-r9 ::= SEQUENCE {
+ messageContCDMA2000-1XRTT-r9 OCTET STRING OPTIONAL, -- Need ON
+ mobilityCDMA2000-HRPD-r9 ENUMERATED {
+ handover, redirection
+ } OPTIONAL, -- Need OP
+ messageContCDMA2000-HRPD-r9 OCTET STRING OPTIONAL, -- Cond concHO
+ redirectCarrierCDMA2000-HRPD-r9 CarrierFreqCDMA2000 OPTIONAL -- Cond concRedir
+}
+
+
+Paging ::= SEQUENCE {
+ pagingRecordList PagingRecordList OPTIONAL, -- Need ON
+ systemInfoModification ENUMERATED {true} OPTIONAL, -- Need ON
+ etws-Indication ENUMERATED {true} OPTIONAL, -- Need ON
+ nonCriticalExtension Paging-v890-IEs OPTIONAL
+}
+
+Paging-v890-IEs ::= SEQUENCE {
+ lateR8NonCriticalExtension OCTET STRING OPTIONAL, -- Need OP
+ nonCriticalExtension Paging-v920-IEs OPTIONAL
+}
+
+Paging-v920-IEs ::= SEQUENCE {
+ cmas-Indication-r9 ENUMERATED {true} OPTIONAL, -- Need ON
+ nonCriticalExtension SEQUENCE {} OPTIONAL -- Need OP
+}
+
+PagingRecordList ::= SEQUENCE (SIZE (1..maxPageRec)) OF PagingRecord
+
+PagingRecord ::= SEQUENCE {
+ ue-Identity PagingUE-Identity,
+ cn-Domain ENUMERATED {ps, cs},
+ ...
+}
+
+PagingUE-Identity ::= CHOICE {
+ s-TMSI S-TMSI,
+ imsi IMSI,
+ ...
+}
+
+IMSI ::= SEQUENCE (SIZE (6..21)) OF IMSI-Digit
+
+IMSI-Digit ::= INTEGER (0..9)
+
+
+ProximityIndication-r9 ::= SEQUENCE {
+ criticalExtensions CHOICE {
+ c1 CHOICE {
+ proximityIndication-r9 ProximityIndication-r9-IEs,
+ spare3 NULL, spare2 NULL, spare1 NULL
+ },
+ criticalExtensionsFuture SEQUENCE {}
+ }
+}
+
+ProximityIndication-r9-IEs ::= SEQUENCE {
+ type-r9 ENUMERATED {entering, leaving},
+ carrierFreq-r9 CHOICE {
+ eutra-r9 ARFCN-ValueEUTRA,
+ utra-r9 ARFCN-ValueUTRA,
+ ...
+ },
+ nonCriticalExtension SEQUENCE {} OPTIONAL
+}
+
+
+RRCConnectionReconfiguration ::= SEQUENCE {
+ rrc-TransactionIdentifier RRC-TransactionIdentifier,
+ criticalExtensions CHOICE {
+ c1 CHOICE{
+ rrcConnectionReconfiguration-r8 RRCConnectionReconfiguration-r8-IEs,
+ spare7 NULL,
+ spare6 NULL, spare5 NULL, spare4 NULL,
+ spare3 NULL, spare2 NULL, spare1 NULL
+ },
+ criticalExtensionsFuture SEQUENCE {}
+ }
+}
+
+RRCConnectionReconfiguration-r8-IEs ::= SEQUENCE {
+ measConfig MeasConfig OPTIONAL, -- Need ON
+ mobilityControlInfo MobilityControlInfo OPTIONAL, -- Cond HO
+ dedicatedInfoNASList SEQUENCE (SIZE(1..maxDRB)) OF
+ DedicatedInfoNAS OPTIONAL, -- Cond nonHO
+ radioResourceConfigDedicated RadioResourceConfigDedicated OPTIONAL, -- Cond HO-toEUTRA
+ securityConfigHO SecurityConfigHO OPTIONAL, -- Cond HO
+ nonCriticalExtension RRCConnectionReconfiguration-v890-IEs OPTIONAL
+}
+
+RRCConnectionReconfiguration-v890-IEs ::= SEQUENCE {
+ lateR8NonCriticalExtension OCTET STRING OPTIONAL, -- Need OP
+ nonCriticalExtension RRCConnectionReconfiguration-v920-IEs OPTIONAL
+}
+
+RRCConnectionReconfiguration-v920-IEs ::= SEQUENCE {
+ otherConfig-r9 OtherConfig-r9 OPTIONAL, -- Need ON
+ fullConfig-r9 ENUMERATED {true} OPTIONAL, -- Cond HO-Reestab
+ nonCriticalExtension SEQUENCE {} OPTIONAL -- Need OP
+}
+
+SecurityConfigHO ::= SEQUENCE {
+ handoverType CHOICE {
+ intraLTE SEQUENCE {
+ securityAlgorithmConfig SecurityAlgorithmConfig OPTIONAL, -- Cond fullConfig
+ keyChangeIndicator BOOLEAN,
+ nextHopChainingCount NextHopChainingCount
+ },
+ interRAT SEQUENCE {
+ securityAlgorithmConfig SecurityAlgorithmConfig,
+ nas-SecurityParamToEUTRA OCTET STRING (SIZE(6))
+ }
+ },
+ ...
+}
+
+
+
+RRCConnectionReconfigurationComplete ::= SEQUENCE {
+ rrc-TransactionIdentifier RRC-TransactionIdentifier,
+ criticalExtensions CHOICE {
+ rrcConnectionReconfigurationComplete-r8
+ RRCConnectionReconfigurationComplete-r8-IEs,
+ criticalExtensionsFuture SEQUENCE {}
+ }
+}
+
+RRCConnectionReconfigurationComplete-r8-IEs ::= SEQUENCE {
+ nonCriticalExtension SEQUENCE {} OPTIONAL
+}
+
+
+RRCConnectionReestablishment ::= SEQUENCE {
+ rrc-TransactionIdentifier RRC-TransactionIdentifier,
+ criticalExtensions CHOICE {
+ c1 CHOICE{
+ rrcConnectionReestablishment-r8 RRCConnectionReestablishment-r8-IEs,
+ spare7 NULL,
+ spare6 NULL, spare5 NULL, spare4 NULL,
+ spare3 NULL, spare2 NULL, spare1 NULL
+ },
+ criticalExtensionsFuture SEQUENCE {}
+ }
+}
+
+RRCConnectionReestablishment-r8-IEs ::= SEQUENCE {
+ radioResourceConfigDedicated RadioResourceConfigDedicated,
+ nextHopChainingCount NextHopChainingCount,
+ nonCriticalExtension SEQUENCE {} OPTIONAL -- Need OP
+}
+
+
+RRCConnectionReestablishmentComplete ::= SEQUENCE {
+ rrc-TransactionIdentifier RRC-TransactionIdentifier,
+ criticalExtensions CHOICE {
+ rrcConnectionReestablishmentComplete-r8
+ RRCConnectionReestablishmentComplete-r8-IEs,
+ criticalExtensionsFuture SEQUENCE {}
+ }
+}
+
+RRCConnectionReestablishmentComplete-r8-IEs ::= SEQUENCE {
+ nonCriticalExtension RRCConnectionReestablishmentComplete-v920-IEs OPTIONAL
+}
+
+RRCConnectionReestablishmentComplete-v920-IEs ::= SEQUENCE {
+ rlf-InfoAvailable-r9 ENUMERATED {true} OPTIONAL,
+ nonCriticalExtension SEQUENCE {} OPTIONAL
+}
+
+
+RRCConnectionReestablishmentReject ::= SEQUENCE {
+ criticalExtensions CHOICE {
+ rrcConnectionReestablishmentReject-r8
+ RRCConnectionReestablishmentReject-r8-IEs,
+ criticalExtensionsFuture SEQUENCE {}
+ }
+}
+
+RRCConnectionReestablishmentReject-r8-IEs ::= SEQUENCE {
+ nonCriticalExtension SEQUENCE {} OPTIONAL -- Need OP
+}
+
+
+RRCConnectionReestablishmentRequest ::= SEQUENCE {
+ criticalExtensions CHOICE {
+ rrcConnectionReestablishmentRequest-r8
+ RRCConnectionReestablishmentRequest-r8-IEs,
+ criticalExtensionsFuture SEQUENCE {}
+ }
+}
+
+RRCConnectionReestablishmentRequest-r8-IEs ::= SEQUENCE {
+ ue-Identity ReestabUE-Identity,
+ reestablishmentCause ReestablishmentCause,
+ spare BIT STRING (SIZE (2))
+}
+
+ReestabUE-Identity ::= SEQUENCE {
+ c-RNTI C-RNTI,
+ physCellId PhysCellId,
+ shortMAC-I ShortMAC-I
+}
+
+ReestablishmentCause ::= ENUMERATED {
+ reconfigurationFailure, handoverFailure,
+ otherFailure, spare1}
+
+
+RRCConnectionReject ::= SEQUENCE {
+ criticalExtensions CHOICE {
+ c1 CHOICE {
+ rrcConnectionReject-r8 RRCConnectionReject-r8-IEs,
+ spare3 NULL, spare2 NULL, spare1 NULL
+ },
+ criticalExtensionsFuture SEQUENCE {}
+ }
+}
+
+RRCConnectionReject-r8-IEs ::= SEQUENCE {
+ waitTime INTEGER (1..16),
+ nonCriticalExtension SEQUENCE {} OPTIONAL -- Need OP
+}
+
+
+RRCConnectionRelease ::= SEQUENCE {
+ rrc-TransactionIdentifier RRC-TransactionIdentifier,
+ criticalExtensions CHOICE {
+ c1 CHOICE {
+ rrcConnectionRelease-r8 RRCConnectionRelease-r8-IEs,
+ spare3 NULL, spare2 NULL, spare1 NULL
+ },
+ criticalExtensionsFuture SEQUENCE {}
+ }
+}
+
+RRCConnectionRelease-r8-IEs ::= SEQUENCE {
+ releaseCause ReleaseCause,
+ redirectedCarrierInfo RedirectedCarrierInfo OPTIONAL, -- Need ON
+ idleModeMobilityControlInfo IdleModeMobilityControlInfo OPTIONAL, -- Need OP
+ nonCriticalExtension RRCConnectionRelease-v890-IEs OPTIONAL
+}
+
+RRCConnectionRelease-v890-IEs ::= SEQUENCE {
+ lateR8NonCriticalExtension OCTET STRING OPTIONAL, -- Need OP
+ nonCriticalExtension RRCConnectionRelease-v920-IEs OPTIONAL
+}
+
+RRCConnectionRelease-v920-IEs ::= SEQUENCE {
+ cellInfoList-r9 CHOICE {
+ geran-r9 CellInfoListGERAN-r9,
+ utra-FDD-r9 CellInfoListUTRA-FDD-r9,
+ utra-TDD-r9 CellInfoListUTRA-TDD-r9,
+ ...
+ } OPTIONAL, -- Cond Redirection
+ nonCriticalExtension SEQUENCE {} OPTIONAL -- Need OP
+}
+
+ReleaseCause ::= ENUMERATED {loadBalancingTAUrequired,
+ other,spare2,spare1}
+
+RedirectedCarrierInfo ::= CHOICE {
+ eutra ARFCN-ValueEUTRA,
+ geran CarrierFreqsGERAN,
+ utra-FDD ARFCN-ValueUTRA,
+ utra-TDD ARFCN-ValueUTRA,
+ cdma2000-HRPD CarrierFreqCDMA2000,
+ cdma2000-1xRTT CarrierFreqCDMA2000,
+ ...
+}
+
+IdleModeMobilityControlInfo ::= SEQUENCE {
+ freqPriorityListEUTRA FreqPriorityListEUTRA OPTIONAL, -- Need ON
+ freqPriorityListGERAN FreqsPriorityListGERAN OPTIONAL, -- Need ON
+ freqPriorityListUTRA-FDD FreqPriorityListUTRA-FDD OPTIONAL, -- Need ON
+ freqPriorityListUTRA-TDD FreqPriorityListUTRA-TDD OPTIONAL, -- Need ON
+ bandClassPriorityListHRPD BandClassPriorityListHRPD OPTIONAL, -- Need ON
+ bandClassPriorityList1XRTT BandClassPriorityList1XRTT OPTIONAL, -- Need ON
+ t320 ENUMERATED {
+ min5, min10, min20, min30, min60, min120, min180,
+ spare1} OPTIONAL, -- Need OR
+ ...
+}
+
+FreqPriorityListEUTRA ::= SEQUENCE (SIZE (1..maxFreq)) OF FreqPriorityEUTRA
+
+FreqPriorityEUTRA ::= SEQUENCE {
+ carrierFreq ARFCN-ValueEUTRA,
+ cellReselectionPriority CellReselectionPriority
+}
+
+FreqsPriorityListGERAN ::= SEQUENCE (SIZE (1..maxGNFG)) OF FreqsPriorityGERAN
+
+FreqsPriorityGERAN ::= SEQUENCE {
+ carrierFreqs CarrierFreqsGERAN,
+ cellReselectionPriority CellReselectionPriority
+}
+
+FreqPriorityListUTRA-FDD ::= SEQUENCE (SIZE (1..maxUTRA-FDD-Carrier)) OF FreqPriorityUTRA-FDD
+
+FreqPriorityUTRA-FDD ::= SEQUENCE {
+ carrierFreq ARFCN-ValueUTRA,
+ cellReselectionPriority CellReselectionPriority
+}
+
+FreqPriorityListUTRA-TDD ::= SEQUENCE (SIZE (1..maxUTRA-TDD-Carrier)) OF FreqPriorityUTRA-TDD
+
+FreqPriorityUTRA-TDD ::= SEQUENCE {
+ carrierFreq ARFCN-ValueUTRA,
+ cellReselectionPriority CellReselectionPriority
+}
+
+BandClassPriorityListHRPD ::= SEQUENCE (SIZE (1..maxCDMA-BandClass)) OF BandClassPriorityHRPD
+
+BandClassPriorityHRPD ::= SEQUENCE {
+ bandClass BandclassCDMA2000,
+ cellReselectionPriority CellReselectionPriority
+}
+
+BandClassPriorityList1XRTT ::= SEQUENCE (SIZE (1..maxCDMA-BandClass)) OF BandClassPriority1XRTT
+
+BandClassPriority1XRTT ::= SEQUENCE {
+ bandClass BandclassCDMA2000,
+ cellReselectionPriority CellReselectionPriority
+}
+
+CellInfoListGERAN-r9 ::= SEQUENCE (SIZE (1..maxCellInfo-GERAN-r9 )) OF CellInfoGERAN-r9
+
+CellInfoGERAN-r9 ::= SEQUENCE {
+ physCellId-r9 PhysCellIdGERAN,
+ carrierFreq-r9 CarrierFreqGERAN,
+ systemInformation-r9 SystemInfoListGERAN
+}
+
+CellInfoListUTRA-FDD-r9 ::= SEQUENCE (SIZE (1..maxUTRA-CellInfo-r9)) OF CellInfoUTRA-FDD-r9
+
+CellInfoUTRA-FDD-r9 ::= SEQUENCE {
+ physCellId-r9 PhysCellIdUTRA-FDD,
+ utra-BCCH-Container-r9 OCTET STRING
+}
+
+CellInfoListUTRA-TDD-r9 ::= SEQUENCE (SIZE (1..maxUTRA-CellInfo-r9)) OF CellInfoUTRA-TDD-r9
+
+CellInfoUTRA-TDD-r9 ::= SEQUENCE {
+ physCellId-r9 PhysCellIdUTRA-TDD,
+ utra-BCCH-Container-r9 OCTET STRING
+}
+
+
+RRCConnectionRequest ::= SEQUENCE {
+ criticalExtensions CHOICE {
+ rrcConnectionRequest-r8 RRCConnectionRequest-r8-IEs,
+ criticalExtensionsFuture SEQUENCE {}
+ }
+}
+
+RRCConnectionRequest-r8-IEs ::= SEQUENCE {
+ ue-Identity InitialUE-Identity,
+ establishmentCause EstablishmentCause,
+ spare BIT STRING (SIZE (1))
+}
+
+InitialUE-Identity ::= CHOICE {
+ s-TMSI S-TMSI,
+ randomValue BIT STRING (SIZE (40))
+}
+
+EstablishmentCause ::= ENUMERATED {
+ emergency, highPriorityAccess, mt-Access, mo-Signalling,
+ mo-Data, spare3, spare2, spare1}
+
+
+RRCConnectionSetup ::= SEQUENCE {
+ rrc-TransactionIdentifier RRC-TransactionIdentifier,
+ criticalExtensions CHOICE {
+ c1 CHOICE {
+ rrcConnectionSetup-r8 RRCConnectionSetup-r8-IEs,
+ spare7 NULL,
+ spare6 NULL, spare5 NULL, spare4 NULL,
+ spare3 NULL, spare2 NULL, spare1 NULL
+ },
+ criticalExtensionsFuture SEQUENCE {}
+ }
+}
+
+RRCConnectionSetup-r8-IEs ::= SEQUENCE {
+ radioResourceConfigDedicated RadioResourceConfigDedicated,
+ nonCriticalExtension SEQUENCE {} OPTIONAL -- Need OP
+}
+
+
+RRCConnectionSetupComplete ::= SEQUENCE {
+ rrc-TransactionIdentifier RRC-TransactionIdentifier,
+ criticalExtensions CHOICE {
+ c1 CHOICE{
+ rrcConnectionSetupComplete-r8 RRCConnectionSetupComplete-r8-IEs,
+ spare3 NULL, spare2 NULL, spare1 NULL
+ },
+ criticalExtensionsFuture SEQUENCE {}
+ }
+}
+
+RRCConnectionSetupComplete-r8-IEs ::= SEQUENCE {
+ selectedPLMN-Identity INTEGER (1..6),
+ registeredMME RegisteredMME OPTIONAL,
+ dedicatedInfoNAS DedicatedInfoNAS,
+ nonCriticalExtension SEQUENCE {} OPTIONAL
+}
+
+RegisteredMME ::= SEQUENCE {
+ plmn-Identity PLMN-Identity OPTIONAL,
+ mmegi BIT STRING (SIZE (16)),
+ mmec MMEC
+}
+
+
+SecurityModeCommand ::= SEQUENCE {
+ rrc-TransactionIdentifier RRC-TransactionIdentifier,
+ criticalExtensions CHOICE {
+ c1 CHOICE{
+ securityModeCommand-r8 SecurityModeCommand-r8-IEs,
+ spare3 NULL, spare2 NULL, spare1 NULL
+ },
+ criticalExtensionsFuture SEQUENCE {}
+ }
+}
+
+SecurityModeCommand-r8-IEs ::= SEQUENCE {
+ securityConfigSMC SecurityConfigSMC,
+ nonCriticalExtension SEQUENCE {} OPTIONAL -- Need OP
+}
+
+SecurityConfigSMC ::= SEQUENCE {
+ securityAlgorithmConfig SecurityAlgorithmConfig,
+ ...
+}
+
+
+SecurityModeComplete ::= SEQUENCE {
+ rrc-TransactionIdentifier RRC-TransactionIdentifier,
+ criticalExtensions CHOICE {
+ securityModeComplete-r8 SecurityModeComplete-r8-IEs,
+ criticalExtensionsFuture SEQUENCE {}
+ }
+}
+
+SecurityModeComplete-r8-IEs ::= SEQUENCE {
+ nonCriticalExtension SEQUENCE {} OPTIONAL
+}
+
+
+SecurityModeFailure ::= SEQUENCE {
+ rrc-TransactionIdentifier RRC-TransactionIdentifier,
+ criticalExtensions CHOICE {
+ securityModeFailure-r8 SecurityModeFailure-r8-IEs,
+ criticalExtensionsFuture SEQUENCE {}
+ }
+}
+
+SecurityModeFailure-r8-IEs ::= SEQUENCE {
+ nonCriticalExtension SEQUENCE {} OPTIONAL
+}
+
+
+SystemInformation ::= SEQUENCE {
+ criticalExtensions CHOICE {
+ systemInformation-r8 SystemInformation-r8-IEs,
+ criticalExtensionsFuture SEQUENCE {}
+ }
+}
+SystemInformation-r8-IEs ::= SEQUENCE {
+ sib-TypeAndInfo SEQUENCE (SIZE (1..maxSIB)) OF CHOICE {
+ sib2 SystemInformationBlockType2,
+ sib3 SystemInformationBlockType3,
+ sib4 SystemInformationBlockType4,
+ sib5 SystemInformationBlockType5,
+ sib6 SystemInformationBlockType6,
+ sib7 SystemInformationBlockType7,
+ sib8 SystemInformationBlockType8,
+ sib9 SystemInformationBlockType9,
+ sib10 SystemInformationBlockType10,
+ sib11 SystemInformationBlockType11,
+ ...,
+ sib12-v920 SystemInformationBlockType12-r9,
+ sib13-v920 SystemInformationBlockType13-r9
+ },
+ nonCriticalExtension SEQUENCE {} OPTIONAL -- Need OP
+}
+
+
+SystemInformationBlockType1 ::= SEQUENCE {
+ cellAccessRelatedInfo SEQUENCE {
+ plmn-IdentityList PLMN-IdentityList,
+ trackingAreaCode TrackingAreaCode,
+ cellIdentity CellIdentity,
+ cellBarred ENUMERATED {barred, notBarred},
+ intraFreqReselection ENUMERATED {allowed, notAllowed},
+ csg-Indication BOOLEAN,
+ csg-Identity CSG-Identity OPTIONAL -- Need OR
+ },
+ cellSelectionInfo SEQUENCE {
+ q-RxLevMin Q-RxLevMin,
+ q-RxLevMinOffset INTEGER (1..8) OPTIONAL -- Need OP
+ },
+ p-Max P-Max OPTIONAL, -- Need OP
+ freqBandIndicator INTEGER (1..64),
+ schedulingInfoList SchedulingInfoList,
+ tdd-Config TDD-Config OPTIONAL, -- Cond TDD
+ si-WindowLength ENUMERATED {
+ ms1, ms2, ms5, ms10, ms15, ms20,
+ ms40},
+ systemInfoValueTag INTEGER (0..31),
+ nonCriticalExtension SystemInformationBlockType1-v890-IEs OPTIONAL
+}
+
+SystemInformationBlockType1-v890-IEs::= SEQUENCE {
+ lateR8NonCriticalExtension OCTET STRING OPTIONAL, -- Need OP
+ nonCriticalExtension SystemInformationBlockType1-v920-IEs OPTIONAL
+}
+
+SystemInformationBlockType1-v920-IEs ::= SEQUENCE {
+ ims-EmergencySupport-r9 ENUMERATED {true} OPTIONAL, -- Need OR
+ cellSelectionInfo-v920 CellSelectionInfo-v920 OPTIONAL, -- Need OP
+ nonCriticalExtension SEQUENCE {} OPTIONAL -- Need OP
+}
+
+PLMN-IdentityList ::= SEQUENCE (SIZE (1..6)) OF PLMN-IdentityInfo
+
+PLMN-IdentityInfo ::= SEQUENCE {
+ plmn-Identity PLMN-Identity,
+ cellReservedForOperatorUse ENUMERATED {reserved, notReserved}
+}
+
+SchedulingInfoList ::= SEQUENCE (SIZE (1..maxSI-Message)) OF SchedulingInfo
+
+SchedulingInfo ::= SEQUENCE {
+ si-Periodicity ENUMERATED {
+ rf8, rf16, rf32, rf64, rf128, rf256, rf512},
+ sib-MappingInfo SIB-MappingInfo
+}
+
+SIB-MappingInfo ::= SEQUENCE (SIZE (0..maxSIB-1)) OF SIB-Type
+
+SIB-Type ::= ENUMERATED {
+ sibType3, sibType4, sibType5, sibType6,
+ sibType7, sibType8, sibType9, sibType10,
+ sibType11, sibType12-v920, sibType13-v920, spare5,
+ spare4, spare3, spare2, spare1, ...}
+
+CellSelectionInfo-v920 ::= SEQUENCE {
+ q-QualMin-r9 Q-QualMin-r9,
+ q-QualMinOffset-r9 INTEGER (1..8) OPTIONAL -- Need OP
+}
+
+
+UECapabilityEnquiry ::= SEQUENCE {
+ rrc-TransactionIdentifier RRC-TransactionIdentifier,
+ criticalExtensions CHOICE {
+ c1 CHOICE {
+ ueCapabilityEnquiry-r8 UECapabilityEnquiry-r8-IEs,
+ spare3 NULL, spare2 NULL, spare1 NULL
+ },
+ criticalExtensionsFuture SEQUENCE {}
+ }
+}
+
+UECapabilityEnquiry-r8-IEs ::= SEQUENCE {
+ ue-CapabilityRequest UE-CapabilityRequest,
+ nonCriticalExtension SEQUENCE {} OPTIONAL -- Need OP
+}
+
+UE-CapabilityRequest ::= SEQUENCE (SIZE (1..maxRAT-Capabilities)) OF RAT-Type
+
+
+UECapabilityInformation ::= SEQUENCE {
+ rrc-TransactionIdentifier RRC-TransactionIdentifier,
+ criticalExtensions CHOICE {
+ c1 CHOICE{
+ ueCapabilityInformation-r8 UECapabilityInformation-r8-IEs,
+ spare7 NULL,
+ spare6 NULL, spare5 NULL, spare4 NULL,
+ spare3 NULL, spare2 NULL, spare1 NULL
+ },
+ criticalExtensionsFuture SEQUENCE {}
+ }
+}
+
+UECapabilityInformation-r8-IEs ::= SEQUENCE {
+ ue-CapabilityRAT-ContainerList UE-CapabilityRAT-ContainerList,
+ nonCriticalExtension SEQUENCE {} OPTIONAL
+}
+
+
+UEInformationRequest-r9 ::= SEQUENCE {
+ rrc-TransactionIdentifier RRC-TransactionIdentifier,
+ criticalExtensions CHOICE {
+ c1 CHOICE {
+ ueInformationRequest-r9 UEInformationRequest-r9-IEs,
+ spare3 NULL, spare2 NULL, spare1 NULL
+ },
+ criticalExtensionsFuture SEQUENCE {}
+ }
+}
+
+UEInformationRequest-r9-IEs ::= SEQUENCE {
+ rach-ReportReq-r9 BOOLEAN,
+ rlf-ReportReq-r9 BOOLEAN,
+ nonCriticalExtension SEQUENCE {} OPTIONAL -- Need OP
+}
+
+
+UEInformationResponse-r9 ::= SEQUENCE {
+ rrc-TransactionIdentifier RRC-TransactionIdentifier,
+ criticalExtensions CHOICE {
+ c1 CHOICE {
+ ueInformationResponse-r9 UEInformationResponse-r9-IEs,
+ spare3 NULL, spare2 NULL, spare1 NULL
+ },
+ criticalExtensionsFuture SEQUENCE {}
+ }
+}
+
+UEInformationResponse-r9-IEs ::= SEQUENCE {
+ rach-Report-r9 SEQUENCE {
+ numberOfPreamblesSent-r9 INTEGER (1..200),
+ contentionDetected-r9 BOOLEAN
+ } OPTIONAL,
+ rlfReport-r9 RLF-Report-r9 OPTIONAL,
+ nonCriticalExtension SEQUENCE {} OPTIONAL
+}
+
+RLF-Report-r9 ::= SEQUENCE {
+ measResultLastServCell SEQUENCE {
+ rsrpResult RSRP-Range,
+ rsrqResult RSRQ-Range OPTIONAL
+ },
+ measResultNeighCells SEQUENCE {
+ measResultListEUTRA MeasResultList2EUTRA OPTIONAL,
+ measResultListUTRA MeasResultList2UTRA OPTIONAL,
+ measResultListGERAN MeasResultListGERAN OPTIONAL,
+ measResultsCDMA2000 MeasResultList2CDMA2000 OPTIONAL
+ } OPTIONAL,
+ ...
+}
+
+MeasResultList2EUTRA ::= SEQUENCE (SIZE (1..maxFreq)) OF SEQUENCE {
+ carrierFreq ARFCN-ValueEUTRA,
+ measResultList MeasResultListEUTRA
+}
+
+MeasResultList2UTRA ::= SEQUENCE (SIZE (1..maxCellReport)) OF SEQUENCE {
+ carrierFreq ARFCN-ValueUTRA,
+ measResultList MeasResultListUTRA
+}
+
+MeasResultList2CDMA2000 ::= SEQUENCE (SIZE (1..maxCellReport)) OF SEQUENCE {
+ carrierFreq CarrierFreqCDMA2000,
+ measResultList MeasResultsCDMA2000
+}
+
+
+ULHandoverPreparationTransfer ::= SEQUENCE {
+ criticalExtensions CHOICE {
+ c1 CHOICE {
+ ulHandoverPreparationTransfer-r8 ULHandoverPreparationTransfer-r8-IEs,
+ spare3 NULL, spare2 NULL, spare1 NULL
+ },
+ criticalExtensionsFuture SEQUENCE {}
+ }
+}
+
+ULHandoverPreparationTransfer-r8-IEs ::= SEQUENCE {
+ cdma2000-Type CDMA2000-Type,
+ meid BIT STRING (SIZE (56)) OPTIONAL,
+ dedicatedInfo DedicatedInfoCDMA2000,
+ nonCriticalExtension SEQUENCE {} OPTIONAL
+}
+
+
+ULInformationTransfer ::= SEQUENCE {
+ criticalExtensions CHOICE {
+ c1 CHOICE {
+ ulInformationTransfer-r8 ULInformationTransfer-r8-IEs,
+ spare3 NULL, spare2 NULL, spare1 NULL
+ },
+ criticalExtensionsFuture SEQUENCE {}
+ }
+}
+
+ULInformationTransfer-r8-IEs ::= SEQUENCE {
+ dedicatedInfoType CHOICE {
+ dedicatedInfoNAS DedicatedInfoNAS,
+ dedicatedInfoCDMA2000-1XRTT DedicatedInfoCDMA2000,
+ dedicatedInfoCDMA2000-HRPD DedicatedInfoCDMA2000
+ },
+ nonCriticalExtension SEQUENCE {} OPTIONAL
+}
+
+
+SystemInformationBlockType2 ::= SEQUENCE {
+ ac-BarringInfo SEQUENCE {
+ ac-BarringForEmergency BOOLEAN,
+ ac-BarringForMO-Signalling AC-BarringConfig OPTIONAL, -- Need OP
+ ac-BarringForMO-Data AC-BarringConfig OPTIONAL -- Need OP
+ } OPTIONAL, -- Need OP
+ radioResourceConfigCommon RadioResourceConfigCommonSIB,
+ ue-TimersAndConstants UE-TimersAndConstants,
+ freqInfo SEQUENCE {
+ ul-CarrierFreq ARFCN-ValueEUTRA OPTIONAL, -- Need OP
+ ul-Bandwidth ENUMERATED {n6, n15, n25, n50, n75, n100}
+ OPTIONAL, -- Need OP
+ additionalSpectrumEmission AdditionalSpectrumEmission
+ },
+ mbsfn-SubframeConfigList MBSFN-SubframeConfigList OPTIONAL, -- Need OR
+ timeAlignmentTimerCommon TimeAlignmentTimer,
+ ...,
+ lateR8NonCriticalExtension OCTET STRING OPTIONAL, -- Need OP
+ [[ ssac-BarringForMMTEL-Voice-r9 AC-BarringConfig OPTIONAL, -- Need OP
+ ssac-BarringForMMTEL-Video-r9 AC-BarringConfig OPTIONAL -- Need OP
+ ]]
+}
+
+AC-BarringConfig ::= SEQUENCE {
+ ac-BarringFactor ENUMERATED {
+ p00, p05, p10, p15, p20, p25, p30, p40,
+ p50, p60, p70, p75, p80, p85, p90, p95},
+ ac-BarringTime ENUMERATED {s4, s8, s16, s32, s64, s128, s256, s512},
+ ac-BarringForSpecialAC BIT STRING (SIZE(5))
+}
+
+MBSFN-SubframeConfigList ::= SEQUENCE (SIZE (1..maxMBSFN-Allocations)) OF MBSFN-SubframeConfig
+
+
+SystemInformationBlockType3 ::= SEQUENCE {
+ cellReselectionInfoCommon SEQUENCE {
+ q-Hyst ENUMERATED {
+ dB0, dB1, dB2, dB3, dB4, dB5, dB6, dB8, dB10,
+ dB12, dB14, dB16, dB18, dB20, dB22, dB24},
+ speedStateReselectionPars SEQUENCE {
+ mobilityStateParameters MobilityStateParameters,
+ q-HystSF SEQUENCE {
+ sf-Medium ENUMERATED {
+ dB-6, dB-4, dB-2, dB0},
+ sf-High ENUMERATED {
+ dB-6, dB-4, dB-2, dB0}
+ }
+ } OPTIONAL -- Need OP
+ },
+ cellReselectionServingFreqInfo SEQUENCE {
+ s-NonIntraSearch ReselectionThreshold OPTIONAL, -- Need OP
+ threshServingLow ReselectionThreshold,
+ cellReselectionPriority CellReselectionPriority
+ },
+ intraFreqCellReselectionInfo SEQUENCE {
+ q-RxLevMin Q-RxLevMin,
+ p-Max P-Max OPTIONAL, -- Need OP
+ s-IntraSearch ReselectionThreshold OPTIONAL, -- Need OP
+ allowedMeasBandwidth AllowedMeasBandwidth OPTIONAL, -- Need OP
+ presenceAntennaPort1 PresenceAntennaPort1,
+ neighCellConfig NeighCellConfig,
+ t-ReselectionEUTRA T-Reselection,
+ t-ReselectionEUTRA-SF SpeedStateScaleFactors OPTIONAL -- Need OP
+ },
+ ...,
+ lateR8NonCriticalExtension OCTET STRING OPTIONAL, -- Need OP
+ [[ s-IntraSearch-v920 SEQUENCE {
+ s-IntraSearchP-r9 ReselectionThreshold,
+ s-IntraSearchQ-r9 ReselectionThresholdQ-r9
+ } OPTIONAL, -- Need OP
+ s-NonIntraSearch-v920 SEQUENCE {
+ s-NonIntraSearchP-r9 ReselectionThreshold,
+ s-NonIntraSearchQ-r9 ReselectionThresholdQ-r9
+ } OPTIONAL, -- Need OP
+ q-QualMin-r9 Q-QualMin-r9 OPTIONAL, -- Need OP
+ threshServingLowQ-r9 ReselectionThresholdQ-r9 OPTIONAL -- Need OP
+ ]]
+}
+
+
+SystemInformationBlockType4 ::= SEQUENCE {
+ intraFreqNeighCellList IntraFreqNeighCellList OPTIONAL, -- Need OR
+ intraFreqBlackCellList IntraFreqBlackCellList OPTIONAL, -- Need OR
+ csg-PhysCellIdRange PhysCellIdRange OPTIONAL, -- Cond CSG
+ ...
+}
+
+IntraFreqNeighCellList ::= SEQUENCE (SIZE (1..maxCellIntra)) OF IntraFreqNeighCellInfo
+
+IntraFreqNeighCellInfo ::= SEQUENCE {
+ physCellId PhysCellId,
+ q-OffsetCell Q-OffsetRange,
+ ...
+}
+
+IntraFreqBlackCellList ::= SEQUENCE (SIZE (1..maxCellBlack)) OF PhysCellIdRange
+
+
+SystemInformationBlockType5 ::= SEQUENCE {
+ interFreqCarrierFreqList InterFreqCarrierFreqList,
+ ...,
+ lateR8NonCriticalExtension OCTET STRING OPTIONAL -- Need OP
+}
+
+InterFreqCarrierFreqList ::= SEQUENCE (SIZE (1..maxFreq)) OF InterFreqCarrierFreqInfo
+
+InterFreqCarrierFreqInfo ::= SEQUENCE {
+ dl-CarrierFreq ARFCN-ValueEUTRA,
+ q-RxLevMin Q-RxLevMin,
+ p-Max P-Max OPTIONAL, -- Need OP
+ t-ReselectionEUTRA T-Reselection,
+ t-ReselectionEUTRA-SF SpeedStateScaleFactors OPTIONAL, -- Need OP
+ threshX-High ReselectionThreshold,
+ threshX-Low ReselectionThreshold,
+ allowedMeasBandwidth AllowedMeasBandwidth,
+ presenceAntennaPort1 PresenceAntennaPort1,
+ cellReselectionPriority CellReselectionPriority OPTIONAL, -- Need OP
+ neighCellConfig NeighCellConfig,
+ q-OffsetFreq Q-OffsetRange DEFAULT dB0,
+ interFreqNeighCellList InterFreqNeighCellList OPTIONAL, -- Need OR
+ interFreqBlackCellList InterFreqBlackCellList OPTIONAL, -- Need OR
+ ...,
+ [[ q-QualMin-r9 Q-QualMin-r9 OPTIONAL, -- Need OP
+ threshX-Q-r9 SEQUENCE {
+ threshX-HighQ-r9 ReselectionThresholdQ-r9,
+ threshX-LowQ-r9 ReselectionThresholdQ-r9
+ } OPTIONAL -- Cond RSRQ
+ ]]
+}
+
+InterFreqNeighCellList ::= SEQUENCE (SIZE (1..maxCellInter)) OF InterFreqNeighCellInfo
+
+InterFreqNeighCellInfo ::= SEQUENCE {
+ physCellId PhysCellId,
+ q-OffsetCell Q-OffsetRange
+}
+
+InterFreqBlackCellList ::= SEQUENCE (SIZE (1..maxCellBlack)) OF PhysCellIdRange
+
+
+SystemInformationBlockType6 ::= SEQUENCE {
+ carrierFreqListUTRA-FDD CarrierFreqListUTRA-FDD OPTIONAL, -- Need OR
+ carrierFreqListUTRA-TDD CarrierFreqListUTRA-TDD OPTIONAL, -- Need OR
+ t-ReselectionUTRA T-Reselection,
+ t-ReselectionUTRA-SF SpeedStateScaleFactors OPTIONAL, -- Need OP
+ ...,
+ lateR8NonCriticalExtension OCTET STRING OPTIONAL -- Need OP
+}
+
+CarrierFreqListUTRA-FDD ::= SEQUENCE (SIZE (1..maxUTRA-FDD-Carrier)) OF CarrierFreqUTRA-FDD
+
+CarrierFreqUTRA-FDD ::= SEQUENCE {
+ carrierFreq ARFCN-ValueUTRA,
+ cellReselectionPriority CellReselectionPriority OPTIONAL, -- Need OP
+ threshX-High ReselectionThreshold,
+ threshX-Low ReselectionThreshold,
+ q-RxLevMin INTEGER (-60..-13),
+ p-MaxUTRA INTEGER (-50..33),
+ q-QualMin INTEGER (-24..0),
+ ...,
+ [[ threshX-Q-r9 SEQUENCE {
+ threshX-HighQ-r9 ReselectionThresholdQ-r9,
+ threshX-LowQ-r9 ReselectionThresholdQ-r9
+ } OPTIONAL -- Cond RSRQ
+ ]]
+}
+
+CarrierFreqListUTRA-TDD ::= SEQUENCE (SIZE (1..maxUTRA-TDD-Carrier)) OF CarrierFreqUTRA-TDD
+
+CarrierFreqUTRA-TDD ::= SEQUENCE {
+ carrierFreq ARFCN-ValueUTRA,
+ cellReselectionPriority CellReselectionPriority OPTIONAL, -- Need OP
+ threshX-High ReselectionThreshold,
+ threshX-Low ReselectionThreshold,
+ q-RxLevMin INTEGER (-60..-13),
+ p-MaxUTRA INTEGER (-50..33),
+ ...
+}
+
+
+SystemInformationBlockType7 ::= SEQUENCE {
+ t-ReselectionGERAN T-Reselection,
+ t-ReselectionGERAN-SF SpeedStateScaleFactors OPTIONAL, -- Need OR
+ carrierFreqsInfoList CarrierFreqsInfoListGERAN OPTIONAL, -- Need OR
+ ...
+}
+
+CarrierFreqsInfoListGERAN ::= SEQUENCE (SIZE (1..maxGNFG)) OF CarrierFreqsInfoGERAN
+
+CarrierFreqsInfoGERAN ::= SEQUENCE {
+ carrierFreqs CarrierFreqsGERAN,
+ commonInfo SEQUENCE {
+ cellReselectionPriority CellReselectionPriority OPTIONAL, -- Need OP
+ ncc-Permitted BIT STRING (SIZE (8)),
+ q-RxLevMin INTEGER (0..45),
+ p-MaxGERAN INTEGER (0..39) OPTIONAL, -- Need OP
+ threshX-High ReselectionThreshold,
+ threshX-Low ReselectionThreshold
+ },
+ ...
+}
+
+
+SystemInformationBlockType8 ::= SEQUENCE {
+ systemTimeInfo SystemTimeInfoCDMA2000 OPTIONAL, -- Need OR
+ searchWindowSize INTEGER (0..15) OPTIONAL, -- Need OR
+ parametersHRPD SEQUENCE {
+ preRegistrationInfoHRPD PreRegistrationInfoHRPD,
+ cellReselectionParametersHRPD CellReselectionParametersCDMA2000 OPTIONAL -- Need OR
+ } OPTIONAL, -- Need OR
+ parameters1XRTT SEQUENCE {
+ csfb-RegistrationParam1XRTT CSFB-RegistrationParam1XRTT OPTIONAL, -- Need OP
+ longCodeState1XRTT BIT STRING (SIZE (42)) OPTIONAL, -- Need OR
+ cellReselectionParameters1XRTT CellReselectionParametersCDMA2000 OPTIONAL -- Need OR
+ } OPTIONAL, -- Need OR
+ ...,
+ lateR8NonCriticalExtension OCTET STRING OPTIONAL, -- Need OP
+ [[ csfb-SupportForDualRxUEs-r9 BOOLEAN OPTIONAL, -- Need OR
+ cellReselectionParametersHRPD-v920 CellReselectionParametersCDMA2000-v920 OPTIONAL, -- Cond NCL-HRPD
+ cellReselectionParameters1XRTT-v920 CellReselectionParametersCDMA2000-v920 OPTIONAL, -- Cond NCL-1XRTT
+ csfb-RegistrationParam1XRTT-v920 CSFB-RegistrationParam1XRTT-v920 OPTIONAL, -- Cond REG-1XRTT
+ ac-BarringConfig1XRTT-r9 AC-BarringConfig1XRTT-r9 OPTIONAL -- Cond REG-1XRTT
+ ]]
+}
+
+CellReselectionParametersCDMA2000 ::= SEQUENCE {
+ bandClassList BandClassListCDMA2000,
+ neighCellList NeighCellListCDMA2000,
+ t-ReselectionCDMA2000 T-Reselection,
+ t-ReselectionCDMA2000-SF SpeedStateScaleFactors OPTIONAL -- Need OP
+}
+
+CellReselectionParametersCDMA2000-v920 ::= SEQUENCE {
+ neighCellList-v920 NeighCellListCDMA2000-v920
+}
+
+NeighCellListCDMA2000 ::= SEQUENCE (SIZE (1..16)) OF NeighCellCDMA2000
+
+NeighCellCDMA2000 ::= SEQUENCE {
+ bandClass BandclassCDMA2000,
+ neighCellsPerFreqList NeighCellsPerBandclassListCDMA2000
+}
+
+NeighCellsPerBandclassListCDMA2000 ::= SEQUENCE (SIZE (1..16)) OF NeighCellsPerBandclassCDMA2000
+
+NeighCellsPerBandclassCDMA2000 ::= SEQUENCE {
+ arfcn ARFCN-ValueCDMA2000,
+ physCellIdList PhysCellIdListCDMA2000
+}
+
+NeighCellListCDMA2000-v920 ::= SEQUENCE (SIZE (1..16)) OF NeighCellCDMA2000-v920
+
+NeighCellCDMA2000-v920 ::= SEQUENCE {
+ neighCellsPerFreqList-v920 NeighCellsPerBandclassListCDMA2000-v920
+}
+
+NeighCellsPerBandclassListCDMA2000-v920 ::= SEQUENCE (SIZE (1..16)) OF NeighCellsPerBandclassCDMA2000-v920
+
+NeighCellsPerBandclassCDMA2000-v920 ::= SEQUENCE {
+ physCellIdList-v920 PhysCellIdListCDMA2000-v920
+}
+
+PhysCellIdListCDMA2000 ::= SEQUENCE (SIZE (1..16)) OF PhysCellIdCDMA2000
+
+PhysCellIdListCDMA2000-v920 ::= SEQUENCE (SIZE (0..24)) OF PhysCellIdCDMA2000
+
+BandClassListCDMA2000 ::= SEQUENCE (SIZE (1..maxCDMA-BandClass)) OF BandClassInfoCDMA2000
+
+BandClassInfoCDMA2000 ::= SEQUENCE {
+ bandClass BandclassCDMA2000,
+ cellReselectionPriority CellReselectionPriority OPTIONAL, -- Need OP
+ threshX-High INTEGER (0..63),
+ threshX-Low INTEGER (0..63),
+ ...
+}
+
+AC-BarringConfig1XRTT-r9 ::= SEQUENCE {
+ ac-Barring0to9-r9 INTEGER (0..63),
+ ac-Barring10-r9 INTEGER (0..7),
+ ac-Barring11-r9 INTEGER (0..7),
+ ac-Barring12-r9 INTEGER (0..7),
+ ac-Barring13-r9 INTEGER (0..7),
+ ac-Barring14-r9 INTEGER (0..7),
+ ac-Barring15-r9 INTEGER (0..7),
+ ac-BarringMsg-r9 INTEGER (0..7),
+ ac-BarringReg-r9 INTEGER (0..7),
+ ac-BarringEmg-r9 INTEGER (0..7)
+}
+
+
+SystemInformationBlockType9 ::= SEQUENCE {
+ hnb-Name OCTET STRING (SIZE(1..48)) OPTIONAL, -- Need OR
+ ...
+}
+
+
+SystemInformationBlockType10 ::= SEQUENCE {
+ messageIdentifier BIT STRING (SIZE (16)),
+ serialNumber BIT STRING (SIZE (16)),
+ warningType OCTET STRING (SIZE (2)),
+ warningSecurityInfo OCTET STRING (SIZE (50)) OPTIONAL, -- Need OP
+ ...
+}
+
+
+SystemInformationBlockType11 ::= SEQUENCE {
+ messageIdentifier BIT STRING (SIZE (16)),
+ serialNumber BIT STRING (SIZE (16)),
+ warningMessageSegmentType ENUMERATED {notLastSegment, lastSegment},
+ warningMessageSegmentNumber INTEGER (0..63),
+ warningMessageSegment OCTET STRING,
+ dataCodingScheme OCTET STRING (SIZE (1)) OPTIONAL, -- Cond Segment1
+ ...
+}
+
+
+SystemInformationBlockType12-r9 ::= SEQUENCE {
+ messageIdentifier-r9 BIT STRING (SIZE (16)),
+ serialNumber-r9 BIT STRING (SIZE (16)),
+ warningMessageSegmentType-r9 ENUMERATED {notLastSegment, lastSegment},
+ warningMessageSegmentNumber-r9 INTEGER (0..63),
+ warningMessageSegment-r9 OCTET STRING,
+ dataCodingScheme-r9 OCTET STRING (SIZE (1)) OPTIONAL, -- Cond Segment1
+ lateR9NonCriticalExtension OCTET STRING OPTIONAL, -- Need OP
+ ...
+}
+
+
+SystemInformationBlockType13-r9 ::= SEQUENCE {
+ mbsfn-AreaInfoList-r9 MBSFN-AreaInfoList-r9,
+ notificationConfig-r9 MBMS-NotificationConfig-r9,
+ lateR9NonCriticalExtension OCTET STRING OPTIONAL, -- Need OP
+ ...
+}
+
+
+AntennaInfoCommon ::= SEQUENCE {
+ antennaPortsCount ENUMERATED {an1, an2, an4, spare1}
+}
+
+AntennaInfoDedicated ::= SEQUENCE {
+ transmissionMode ENUMERATED {
+ tm1, tm2, tm3, tm4, tm5, tm6,
+ tm7, tm8-v920},
+ codebookSubsetRestriction CHOICE {
+ n2TxAntenna-tm3 BIT STRING (SIZE (2)),
+ n4TxAntenna-tm3 BIT STRING (SIZE (4)),
+ n2TxAntenna-tm4 BIT STRING (SIZE (6)),
+ n4TxAntenna-tm4 BIT STRING (SIZE (64)),
+ n2TxAntenna-tm5 BIT STRING (SIZE (4)),
+ n4TxAntenna-tm5 BIT STRING (SIZE (16)),
+ n2TxAntenna-tm6 BIT STRING (SIZE (4)),
+ n4TxAntenna-tm6 BIT STRING (SIZE (16))
+ } OPTIONAL, -- Cond TM
+ ue-TransmitAntennaSelection CHOICE{
+ release NULL,
+ setup ENUMERATED {closedLoop, openLoop}
+ }
+}
+
+AntennaInfoDedicated-v920 ::= SEQUENCE {
+ codebookSubsetRestriction-v920 CHOICE {
+ n2TxAntenna-tm8-r9 BIT STRING (SIZE (6)),
+ n4TxAntenna-tm8-r9 BIT STRING (SIZE (32))
+ } OPTIONAL -- Cond TM8
+}
+
+
+CQI-ReportConfig ::= SEQUENCE {
+ cqi-ReportModeAperiodic ENUMERATED {
+ rm12, rm20, rm22, rm30, rm31,
+ spare3, spare2, spare1} OPTIONAL, -- Need OR
+ nomPDSCH-RS-EPRE-Offset INTEGER (-1..6),
+ cqi-ReportPeriodic CQI-ReportPeriodic OPTIONAL -- Need ON
+}
+
+CQI-ReportConfig-v920 ::= SEQUENCE {
+ cqi-Mask-r9 ENUMERATED {setup} OPTIONAL, -- Cond cqi-Setup
+ pmi-RI-Report-r9 ENUMERATED {setup} OPTIONAL -- Cond PMIRI
+}
+
+CQI-ReportPeriodic ::= CHOICE {
+ release NULL,
+ setup SEQUENCE {
+ cqi-PUCCH-ResourceIndex INTEGER (0.. 1185),
+ cqi-pmi-ConfigIndex INTEGER (0..1023),
+ cqi-FormatIndicatorPeriodic CHOICE {
+ widebandCQI NULL,
+ subbandCQI SEQUENCE {
+ k INTEGER (1..4)
+ }
+ },
+ ri-ConfigIndex INTEGER (0..1023) OPTIONAL, -- Need OR
+ simultaneousAckNackAndCQI BOOLEAN
+ }
+}
+
+
+DRB-Identity ::= INTEGER (1..32)
+
+
+LogicalChannelConfig ::= SEQUENCE {
+ ul-SpecificParameters SEQUENCE {
+ priority INTEGER (1..16),
+ prioritisedBitRate ENUMERATED {
+ kBps0, kBps8, kBps16, kBps32, kBps64, kBps128,
+ kBps256, infinity, spare8, spare7, spare6,
+ spare5, spare4, spare3, spare2, spare1},
+ bucketSizeDuration ENUMERATED {
+ ms50, ms100, ms150, ms300, ms500, ms1000, spare2,
+ spare1},
+ logicalChannelGroup INTEGER (0..3) OPTIONAL -- Need OR
+ } OPTIONAL, -- Cond UL
+ ...,
+ [[ logicalChannelSR-Mask-r9 ENUMERATED {setup} OPTIONAL -- Cond SRmask
+ ]]
+}
+
+
+MAC-MainConfig ::= SEQUENCE {
+ ul-SCH-Config SEQUENCE {
+ maxHARQ-Tx ENUMERATED {
+ n1, n2, n3, n4, n5, n6, n7, n8,
+ n10, n12, n16, n20, n24, n28,
+ spare2, spare1} OPTIONAL, -- Need ON
+ periodicBSR-Timer ENUMERATED {
+ sf5, sf10, sf16, sf20, sf32, sf40, sf64, sf80,
+ sf128, sf160, sf320, sf640, sf1280, sf2560,
+ infinity, spare1} OPTIONAL, -- Need ON
+ retxBSR-Timer ENUMERATED {
+ sf320, sf640, sf1280, sf2560, sf5120,
+ sf10240, spare2, spare1},
+ ttiBundling BOOLEAN
+ } OPTIONAL, -- Need ON
+ drx-Config DRX-Config OPTIONAL, -- Need ON
+ timeAlignmentTimerDedicated TimeAlignmentTimer,
+ phr-Config CHOICE {
+ release NULL,
+ setup SEQUENCE {
+ periodicPHR-Timer ENUMERATED {sf10, sf20, sf50, sf100, sf200,
+ sf500, sf1000, infinity},
+ prohibitPHR-Timer ENUMERATED {sf0, sf10, sf20, sf50, sf100,
+ sf200, sf500, sf1000},
+ dl-PathlossChange ENUMERATED {dB1, dB3, dB6, infinity}
+ }
+ } OPTIONAL, -- Need ON
+ ...,
+ [[ sr-ProhibitTimer-r9 INTEGER (0..7) OPTIONAL -- Need ON
+ ]]
+}
+
+DRX-Config ::= CHOICE {
+ release NULL,
+ setup SEQUENCE {
+ onDurationTimer ENUMERATED {
+ psf1, psf2, psf3, psf4, psf5, psf6,
+ psf8, psf10, psf20, psf30, psf40,
+ psf50, psf60, psf80, psf100,
+ psf200},
+ drx-InactivityTimer ENUMERATED {
+ psf1, psf2, psf3, psf4, psf5, psf6,
+ psf8, psf10, psf20, psf30, psf40,
+ psf50, psf60, psf80, psf100,
+ psf200, psf300, psf500, psf750,
+ psf1280, psf1920, psf2560, spare10,
+ spare9, spare8, spare7, spare6,
+ spare5, spare4, spare3, spare2,
+ spare1},
+ drx-RetransmissionTimer ENUMERATED {
+ psf1, psf2, psf4, psf6, psf8, psf16,
+ psf24, psf33},
+ longDRX-CycleStartOffset CHOICE {
+ sf10 INTEGER(0..9),
+ sf20 INTEGER(0..19),
+ sf32 INTEGER(0..31),
+ sf40 INTEGER(0..39),
+ sf64 INTEGER(0..63),
+ sf80 INTEGER(0..79),
+ sf128 INTEGER(0..127),
+ sf160 INTEGER(0..159),
+ sf256 INTEGER(0..255),
+ sf320 INTEGER(0..319),
+ sf512 INTEGER(0..511),
+ sf640 INTEGER(0..639),
+ sf1024 INTEGER(0..1023),
+ sf1280 INTEGER(0..1279),
+ sf2048 INTEGER(0..2047),
+ sf2560 INTEGER(0..2559)
+ },
+ shortDRX SEQUENCE {
+ shortDRX-Cycle ENUMERATED {
+ sf2, sf5, sf8, sf10, sf16, sf20,
+ sf32, sf40, sf64, sf80, sf128, sf160,
+ sf256, sf320, sf512, sf640},
+ drxShortCycleTimer INTEGER (1..16)
+ } OPTIONAL -- Need OR
+ }
+}
+
+
+PDCP-Config ::= SEQUENCE {
+ discardTimer ENUMERATED {
+ ms50, ms100, ms150, ms300, ms500,
+ ms750, ms1500, infinity
+ } OPTIONAL, -- Cond Setup
+ rlc-AM SEQUENCE {
+ statusReportRequired BOOLEAN
+ } OPTIONAL, -- Cond Rlc-AM
+ rlc-UM SEQUENCE {
+ pdcp-SN-Size ENUMERATED {len7bits, len12bits}
+ } OPTIONAL, -- Cond Rlc-UM
+ headerCompression CHOICE {
+ notUsed NULL,
+ rohc SEQUENCE {
+ maxCID INTEGER (1..16383) DEFAULT 15,
+ profiles SEQUENCE {
+ profile0x0001 BOOLEAN,
+ profile0x0002 BOOLEAN,
+ profile0x0003 BOOLEAN,
+ profile0x0004 BOOLEAN,
+ profile0x0006 BOOLEAN,
+ profile0x0101 BOOLEAN,
+ profile0x0102 BOOLEAN,
+ profile0x0103 BOOLEAN,
+ profile0x0104 BOOLEAN
+ },
+ ...
+ }
+ },
+ ...
+}
+
+
+PDSCH-ConfigCommon ::= SEQUENCE {
+ referenceSignalPower INTEGER (-60..50),
+ p-b INTEGER (0..3)
+}
+
+PDSCH-ConfigDedicated::= SEQUENCE {
+ p-a ENUMERATED {
+ dB-6, dB-4dot77, dB-3, dB-1dot77,
+ dB0, dB1, dB2, dB3}
+}
+
+
+PHICH-Config ::= SEQUENCE {
+ phich-Duration ENUMERATED {normal, extended},
+ phich-Resource ENUMERATED {oneSixth, half, one, two}
+}
+
+
+PhysicalConfigDedicated ::= SEQUENCE {
+ pdsch-ConfigDedicated PDSCH-ConfigDedicated OPTIONAL, -- Need ON
+ pucch-ConfigDedicated PUCCH-ConfigDedicated OPTIONAL, -- Need ON
+ pusch-ConfigDedicated PUSCH-ConfigDedicated OPTIONAL, -- Need ON
+ uplinkPowerControlDedicated UplinkPowerControlDedicated OPTIONAL, -- Need ON
+ tpc-PDCCH-ConfigPUCCH TPC-PDCCH-Config OPTIONAL, -- Need ON
+ tpc-PDCCH-ConfigPUSCH TPC-PDCCH-Config OPTIONAL, -- Need ON
+ cqi-ReportConfig CQI-ReportConfig OPTIONAL, -- Need ON
+ soundingRS-UL-ConfigDedicated SoundingRS-UL-ConfigDedicated OPTIONAL, -- Need ON
+ antennaInfo CHOICE {
+ explicitValue AntennaInfoDedicated,
+ defaultValue NULL
+ } OPTIONAL, -- Need ON
+ schedulingRequestConfig SchedulingRequestConfig OPTIONAL, -- Need ON
+ ...,
+ [[ cqi-ReportConfig-v920 CQI-ReportConfig-v920 OPTIONAL, -- Need ON
+ antennaInfo-v920 AntennaInfoDedicated-v920 OPTIONAL -- Need ON
+ ]]
+}
+
+
+P-Max ::= INTEGER (-30..33)
+
+
+PRACH-ConfigSIB ::= SEQUENCE {
+ rootSequenceIndex INTEGER (0..837),
+ prach-ConfigInfo PRACH-ConfigInfo
+}
+
+PRACH-Config ::= SEQUENCE {
+ rootSequenceIndex INTEGER (0..837),
+ prach-ConfigInfo PRACH-ConfigInfo OPTIONAL -- Need ON
+}
+
+PRACH-ConfigInfo ::= SEQUENCE {
+ prach-ConfigIndex INTEGER (0..63),
+ highSpeedFlag BOOLEAN,
+ zeroCorrelationZoneConfig INTEGER (0..15),
+ prach-FreqOffset INTEGER (0..94)
+}
+
+
+PresenceAntennaPort1 ::= BOOLEAN
+
+
+PUCCH-ConfigCommon ::= SEQUENCE {
+ deltaPUCCH-Shift ENUMERATED {ds1, ds2, ds3},
+ nRB-CQI INTEGER (0..98),
+ nCS-AN INTEGER (0..7),
+ n1PUCCH-AN INTEGER (0..2047)
+}
+
+PUCCH-ConfigDedicated ::= SEQUENCE {
+ ackNackRepetition CHOICE{
+ release NULL,
+ setup SEQUENCE {
+ repetitionFactor ENUMERATED {n2, n4, n6, spare1},
+ n1PUCCH-AN-Rep INTEGER (0..2047)
+ }
+ },
+ tdd-AckNackFeedbackMode ENUMERATED {bundling, multiplexing} OPTIONAL -- Cond TDD
+}
+
+
+PUSCH-ConfigCommon ::= SEQUENCE {
+ pusch-ConfigBasic SEQUENCE {
+ n-SB INTEGER (1..4),
+ hoppingMode ENUMERATED {interSubFrame, intraAndInterSubFrame},
+ pusch-HoppingOffset INTEGER (0..98),
+ enable64QAM BOOLEAN
+ },
+ ul-ReferenceSignalsPUSCH UL-ReferenceSignalsPUSCH
+}
+
+PUSCH-ConfigDedicated ::= SEQUENCE {
+ betaOffset-ACK-Index INTEGER (0..15),
+ betaOffset-RI-Index INTEGER (0..15),
+ betaOffset-CQI-Index INTEGER (0..15)
+}
+
+UL-ReferenceSignalsPUSCH ::= SEQUENCE {
+ groupHoppingEnabled BOOLEAN,
+ groupAssignmentPUSCH INTEGER (0..29),
+ sequenceHoppingEnabled BOOLEAN,
+ cyclicShift INTEGER (0..7)
+}
+
+
+RACH-ConfigCommon ::= SEQUENCE {
+ preambleInfo SEQUENCE {
+ numberOfRA-Preambles ENUMERATED {
+ n4, n8, n12, n16 ,n20, n24, n28,
+ n32, n36, n40, n44, n48, n52, n56,
+ n60, n64},
+ preamblesGroupAConfig SEQUENCE {
+ sizeOfRA-PreamblesGroupA ENUMERATED {
+ n4, n8, n12, n16 ,n20, n24, n28,
+ n32, n36, n40, n44, n48, n52, n56,
+ n60},
+ messageSizeGroupA ENUMERATED {b56, b144, b208, b256},
+ messagePowerOffsetGroupB ENUMERATED {
+ minusinfinity, dB0, dB5, dB8, dB10, dB12,
+ dB15, dB18},
+ ...
+ } OPTIONAL -- Need OP
+ },
+ powerRampingParameters SEQUENCE {
+ powerRampingStep ENUMERATED {dB0, dB2,dB4, dB6},
+ preambleInitialReceivedTargetPower ENUMERATED {
+ dBm-120, dBm-118, dBm-116, dBm-114, dBm-112,
+ dBm-110, dBm-108, dBm-106, dBm-104, dBm-102,
+ dBm-100, dBm-98, dBm-96, dBm-94,
+ dBm-92, dBm-90}
+ },
+ ra-SupervisionInfo SEQUENCE {
+ preambleTransMax ENUMERATED {
+ n3, n4, n5, n6, n7, n8, n10, n20, n50,
+ n100, n200},
+ ra-ResponseWindowSize ENUMERATED {
+ sf2, sf3, sf4, sf5, sf6, sf7,
+ sf8, sf10},
+ mac-ContentionResolutionTimer ENUMERATED {
+ sf8, sf16, sf24, sf32, sf40, sf48,
+ sf56, sf64}
+ },
+ maxHARQ-Msg3Tx INTEGER (1..8),
+ ...
+}
+
+
+RACH-ConfigDedicated ::= SEQUENCE {
+ ra-PreambleIndex INTEGER (0..63),
+ ra-PRACH-MaskIndex INTEGER (0..15)
+}
+
+
+RadioResourceConfigCommonSIB ::= SEQUENCE {
+ rach-ConfigCommon RACH-ConfigCommon,
+ bcch-Config BCCH-Config,
+ pcch-Config PCCH-Config,
+ prach-Config PRACH-ConfigSIB,
+ pdsch-ConfigCommon PDSCH-ConfigCommon,
+ pusch-ConfigCommon PUSCH-ConfigCommon,
+ pucch-ConfigCommon PUCCH-ConfigCommon,
+ soundingRS-UL-ConfigCommon SoundingRS-UL-ConfigCommon,
+ uplinkPowerControlCommon UplinkPowerControlCommon,
+ ul-CyclicPrefixLength UL-CyclicPrefixLength,
+ ...
+}
+
+RadioResourceConfigCommon ::= SEQUENCE {
+ rach-ConfigCommon RACH-ConfigCommon OPTIONAL, -- Need ON
+ prach-Config PRACH-Config,
+ pdsch-ConfigCommon PDSCH-ConfigCommon OPTIONAL, -- Need ON
+ pusch-ConfigCommon PUSCH-ConfigCommon,
+ phich-Config PHICH-Config OPTIONAL, -- Need ON
+ pucch-ConfigCommon PUCCH-ConfigCommon OPTIONAL, -- Need ON
+ soundingRS-UL-ConfigCommon SoundingRS-UL-ConfigCommon OPTIONAL, -- Need ON
+ uplinkPowerControlCommon UplinkPowerControlCommon OPTIONAL, -- Need ON
+ antennaInfoCommon AntennaInfoCommon OPTIONAL, -- Need ON
+ p-Max P-Max OPTIONAL, -- Need OP
+ tdd-Config TDD-Config OPTIONAL, -- Cond TDD
+ ul-CyclicPrefixLength UL-CyclicPrefixLength,
+ ...
+}
+
+BCCH-Config ::= SEQUENCE {
+ modificationPeriodCoeff ENUMERATED {n2, n4, n8, n16}
+}
+
+PCCH-Config ::= SEQUENCE {
+ defaultPagingCycle ENUMERATED {
+ rf32, rf64, rf128, rf256},
+ nB ENUMERATED {
+ fourT, twoT, oneT, halfT, quarterT, oneEighthT,
+ oneSixteenthT, oneThirtySecondT}
+}
+
+UL-CyclicPrefixLength ::= ENUMERATED {len1, len2}
+
+
+RadioResourceConfigDedicated ::= SEQUENCE {
+ srb-ToAddModList SRB-ToAddModList OPTIONAL, -- Cond HO-Conn
+ drb-ToAddModList DRB-ToAddModList OPTIONAL, -- Cond HO-toEUTRA
+ drb-ToReleaseList DRB-ToReleaseList OPTIONAL, -- Need ON
+ mac-MainConfig CHOICE {
+ explicitValue MAC-MainConfig,
+ defaultValue NULL
+ } OPTIONAL, -- Cond HO-toEUTRA2
+ sps-Config SPS-Config OPTIONAL, -- Need ON
+ physicalConfigDedicated PhysicalConfigDedicated OPTIONAL, -- Need ON
+ ...,
+ [[ rlf-TimersAndConstants-r9 RLF-TimersAndConstants-r9 OPTIONAL -- Need ON
+ ]]
+}
+
+SRB-ToAddModList ::= SEQUENCE (SIZE (1..2)) OF SRB-ToAddMod
+
+SRB-ToAddMod ::= SEQUENCE {
+ srb-Identity INTEGER (1..2),
+ rlc-Config CHOICE {
+ explicitValue RLC-Config,
+ defaultValue NULL
+ } OPTIONAL, -- Cond Setup
+ logicalChannelConfig CHOICE {
+ explicitValue LogicalChannelConfig,
+ defaultValue NULL
+ } OPTIONAL, -- Cond Setup
+ ...
+}
+
+DRB-ToAddModList ::= SEQUENCE (SIZE (1..maxDRB)) OF DRB-ToAddMod
+
+DRB-ToAddMod ::= SEQUENCE {
+ eps-BearerIdentity INTEGER (0..15) OPTIONAL, -- Cond DRB-Setup
+ drb-Identity DRB-Identity,
+ pdcp-Config PDCP-Config OPTIONAL, -- Cond PDCP
+ rlc-Config RLC-Config OPTIONAL, -- Cond Setup
+ logicalChannelIdentity INTEGER (3..10) OPTIONAL, -- Cond DRB-Setup
+ logicalChannelConfig LogicalChannelConfig OPTIONAL, -- Cond Setup
+ ...
+}
+
+DRB-ToReleaseList ::= SEQUENCE (SIZE (1..maxDRB)) OF DRB-Identity
+
+
+RLC-Config ::= CHOICE {
+ am SEQUENCE {
+ ul-AM-RLC UL-AM-RLC,
+ dl-AM-RLC DL-AM-RLC
+ },
+ um-Bi-Directional SEQUENCE {
+ ul-UM-RLC UL-UM-RLC,
+ dl-UM-RLC DL-UM-RLC
+ },
+ um-Uni-Directional-UL SEQUENCE {
+ ul-UM-RLC UL-UM-RLC
+ },
+ um-Uni-Directional-DL SEQUENCE {
+ dl-UM-RLC DL-UM-RLC
+ },
+ ...
+}
+
+UL-AM-RLC ::= SEQUENCE {
+ t-PollRetransmit T-PollRetransmit,
+ pollPDU PollPDU,
+ pollByte PollByte,
+ maxRetxThreshold ENUMERATED {
+ t1, t2, t3, t4, t6, t8, t16, t32}
+}
+
+DL-AM-RLC ::= SEQUENCE {
+ t-Reordering T-Reordering,
+ t-StatusProhibit T-StatusProhibit
+}
+
+UL-UM-RLC ::= SEQUENCE {
+ sn-FieldLength SN-FieldLength
+}
+
+DL-UM-RLC ::= SEQUENCE {
+ sn-FieldLength SN-FieldLength,
+ t-Reordering T-Reordering
+}
+
+SN-FieldLength ::= ENUMERATED {size5, size10}
+
+T-PollRetransmit ::= ENUMERATED {
+ ms5, ms10, ms15, ms20, ms25, ms30, ms35,
+ ms40, ms45, ms50, ms55, ms60, ms65, ms70,
+ ms75, ms80, ms85, ms90, ms95, ms100, ms105,
+ ms110, ms115, ms120, ms125, ms130, ms135,
+ ms140, ms145, ms150, ms155, ms160, ms165,
+ ms170, ms175, ms180, ms185, ms190, ms195,
+ ms200, ms205, ms210, ms215, ms220, ms225,
+ ms230, ms235, ms240, ms245, ms250, ms300,
+ ms350, ms400, ms450, ms500, spare9, spare8,
+ spare7, spare6, spare5, spare4, spare3,
+ spare2, spare1}
+
+PollPDU ::= ENUMERATED {
+ p4, p8, p16, p32, p64, p128, p256, pInfinity}
+
+PollByte ::= ENUMERATED {
+ kB25, kB50, kB75, kB100, kB125, kB250, kB375,
+ kB500, kB750, kB1000, kB1250, kB1500, kB2000,
+ kB3000, kBinfinity, spare1}
+
+T-Reordering ::= ENUMERATED {
+ ms0, ms5, ms10, ms15, ms20, ms25, ms30, ms35,
+ ms40, ms45, ms50, ms55, ms60, ms65, ms70,
+ ms75, ms80, ms85, ms90, ms95, ms100, ms110,
+ ms120, ms130, ms140, ms150, ms160, ms170,
+ ms180, ms190, ms200, spare1}
+
+T-StatusProhibit ::= ENUMERATED {
+ ms0, ms5, ms10, ms15, ms20, ms25, ms30, ms35,
+ ms40, ms45, ms50, ms55, ms60, ms65, ms70,
+ ms75, ms80, ms85, ms90, ms95, ms100, ms105,
+ ms110, ms115, ms120, ms125, ms130, ms135,
+ ms140, ms145, ms150, ms155, ms160, ms165,
+ ms170, ms175, ms180, ms185, ms190, ms195,
+ ms200, ms205, ms210, ms215, ms220, ms225,
+ ms230, ms235, ms240, ms245, ms250, ms300,
+ ms350, ms400, ms450, ms500, spare8, spare7,
+ spare6, spare5, spare4, spare3, spare2,
+ spare1}
+
+
+RLF-TimersAndConstants-r9 ::= CHOICE {
+ release NULL,
+ setup SEQUENCE {
+ t301-r9 ENUMERATED {
+ ms100, ms200, ms300, ms400, ms600, ms1000, ms1500,
+ ms2000},
+ t310-r9 ENUMERATED {
+ ms0, ms50, ms100, ms200, ms500, ms1000, ms2000},
+ n310-r9 ENUMERATED {
+ n1, n2, n3, n4, n6, n8, n10, n20},
+ t311-r9 ENUMERATED {
+ ms1000, ms3000, ms5000, ms10000, ms15000,
+ ms20000, ms30000},
+ n311-r9 ENUMERATED {
+ n1, n2, n3, n4, n5, n6, n8, n10},
+ ...
+ }
+}
+
+
+SchedulingRequestConfig ::= CHOICE {
+ release NULL,
+ setup SEQUENCE {
+ sr-PUCCH-ResourceIndex INTEGER (0..2047),
+ sr-ConfigIndex INTEGER (0..157),
+ dsr-TransMax ENUMERATED {
+ n4, n8, n16, n32, n64, spare3, spare2, spare1}
+ }
+}
+
+
+SoundingRS-UL-ConfigCommon ::= CHOICE {
+ release NULL,
+ setup SEQUENCE {
+ srs-BandwidthConfig ENUMERATED {bw0, bw1, bw2, bw3, bw4, bw5, bw6, bw7},
+ srs-SubframeConfig ENUMERATED {
+ sc0, sc1, sc2, sc3, sc4, sc5, sc6, sc7,
+ sc8, sc9, sc10, sc11, sc12, sc13, sc14, sc15},
+ ackNackSRS-SimultaneousTransmission BOOLEAN,
+ srs-MaxUpPts ENUMERATED {true} OPTIONAL -- Cond TDD
+ }
+}
+
+SoundingRS-UL-ConfigDedicated ::= CHOICE{
+ release NULL,
+ setup SEQUENCE {
+ srs-Bandwidth ENUMERATED {bw0, bw1, bw2, bw3},
+ srs-HoppingBandwidth ENUMERATED {hbw0, hbw1, hbw2, hbw3},
+ freqDomainPosition INTEGER (0..23),
+ duration BOOLEAN,
+ srs-ConfigIndex INTEGER (0..1023),
+ transmissionComb INTEGER (0..1),
+ cyclicShift ENUMERATED {cs0, cs1, cs2, cs3, cs4, cs5, cs6, cs7}
+ }
+}
+
+
+
+SPS-Config ::= SEQUENCE {
+ semiPersistSchedC-RNTI C-RNTI OPTIONAL, -- Need OR
+ sps-ConfigDL SPS-ConfigDL OPTIONAL, -- Need ON
+ sps-ConfigUL SPS-ConfigUL OPTIONAL -- Need ON
+}
+
+SPS-ConfigDL ::= CHOICE{
+ release NULL,
+ setup SEQUENCE {
+ semiPersistSchedIntervalDL ENUMERATED {
+ sf10, sf20, sf32, sf40, sf64, sf80,
+ sf128, sf160, sf320, sf640, spare6,
+ spare5, spare4, spare3, spare2,
+ spare1},
+ numberOfConfSPS-Processes INTEGER (1..8),
+ n1-PUCCH-AN-PersistentList N1-PUCCH-AN-PersistentList,
+ ...
+ }
+}
+
+SPS-ConfigUL ::= CHOICE {
+ release NULL,
+ setup SEQUENCE {
+ semiPersistSchedIntervalUL ENUMERATED {
+ sf10, sf20, sf32, sf40, sf64, sf80,
+ sf128, sf160, sf320, sf640, spare6,
+ spare5, spare4, spare3, spare2,
+ spare1},
+ implicitReleaseAfter ENUMERATED {e2, e3, e4, e8},
+ p0-Persistent SEQUENCE {
+ p0-NominalPUSCH-Persistent INTEGER (-126..24),
+ p0-UE-PUSCH-Persistent INTEGER (-8..7)
+ } OPTIONAL, -- Need OP
+ twoIntervalsConfig ENUMERATED {true} OPTIONAL, -- Cond TDD
+ ...
+ }
+}
+
+N1-PUCCH-AN-PersistentList ::= SEQUENCE (SIZE (1..4)) OF INTEGER (0..2047)
+
+
+TDD-Config ::= SEQUENCE {
+ subframeAssignment ENUMERATED {
+ sa0, sa1, sa2, sa3, sa4, sa5, sa6},
+ specialSubframePatterns ENUMERATED {
+ ssp0, ssp1, ssp2, ssp3, ssp4,ssp5, ssp6, ssp7,
+ ssp8}
+}
+
+
+TimeAlignmentTimer ::= ENUMERATED {
+ sf500, sf750, sf1280, sf1920, sf2560, sf5120,
+ sf10240, infinity}
+
+TPC-PDCCH-Config ::= CHOICE {
+ release NULL,
+ setup SEQUENCE {
+ tpc-RNTI BIT STRING (SIZE (16)),
+ tpc-Index TPC-Index
+ }
+}
+
+TPC-Index ::= CHOICE {
+ indexOfFormat3 INTEGER (1..15),
+ indexOfFormat3A INTEGER (1..31)
+}
+
+
+UplinkPowerControlCommon ::= SEQUENCE {
+ p0-NominalPUSCH INTEGER (-126..24),
+ alpha ENUMERATED {al0, al04, al05, al06, al07, al08, al09, al1},
+ p0-NominalPUCCH INTEGER (-127..-96),
+ deltaFList-PUCCH DeltaFList-PUCCH,
+ deltaPreambleMsg3 INTEGER (-1..6)
+}
+
+UplinkPowerControlDedicated ::= SEQUENCE {
+ p0-UE-PUSCH INTEGER (-8..7),
+ deltaMCS-Enabled ENUMERATED {en0, en1},
+ accumulationEnabled BOOLEAN,
+ p0-UE-PUCCH INTEGER (-8..7),
+ pSRS-Offset INTEGER (0..15),
+ filterCoefficient FilterCoefficient DEFAULT fc4
+}
+
+DeltaFList-PUCCH ::= SEQUENCE {
+ deltaF-PUCCH-Format1 ENUMERATED {deltaF-2, deltaF0, deltaF2},
+ deltaF-PUCCH-Format1b ENUMERATED {deltaF1, deltaF3, deltaF5},
+ deltaF-PUCCH-Format2 ENUMERATED {deltaF-2, deltaF0, deltaF1, deltaF2},
+ deltaF-PUCCH-Format2a ENUMERATED {deltaF-2, deltaF0, deltaF2},
+ deltaF-PUCCH-Format2b ENUMERATED {deltaF-2, deltaF0, deltaF2}
+}
+
+
+NextHopChainingCount ::= INTEGER (0..7)
+
+
+SecurityAlgorithmConfig ::= SEQUENCE {
+ cipheringAlgorithm ENUMERATED {
+ eea0, eea1, eea2, spare5, spare4, spare3,
+ spare2, spare1, ...},
+ integrityProtAlgorithm ENUMERATED {
+ eia0-v920, eia1, eia2, spare5, spare4, spare3,
+ spare2, spare1, ...}
+}
+
+
+ShortMAC-I ::= BIT STRING (SIZE (16))
+
+
+AdditionalSpectrumEmission ::= INTEGER (1..32)
+
+
+ARFCN-ValueCDMA2000 ::= INTEGER (0..2047)
+
+
+ARFCN-ValueEUTRA ::= INTEGER (0..maxEARFCN)
+
+
+ARFCN-ValueGERAN ::= INTEGER (0..1023)
+
+
+ARFCN-ValueUTRA ::= INTEGER (0..16383)
+
+
+BandclassCDMA2000 ::= ENUMERATED {
+ bc0, bc1, bc2, bc3, bc4, bc5, bc6, bc7, bc8,
+ bc9, bc10, bc11, bc12, bc13, bc14, bc15, bc16,
+ bc17, spare14, spare13, spare12, spare11, spare10,
+ spare9, spare8, spare7, spare6, spare5, spare4,
+ spare3, spare2, spare1, ...}
+
+
+BandIndicatorGERAN ::= ENUMERATED {dcs1800, pcs1900}
+
+
+CarrierFreqCDMA2000 ::= SEQUENCE {
+ bandClass BandclassCDMA2000,
+ arfcn ARFCN-ValueCDMA2000
+}
+
+
+CarrierFreqGERAN ::= SEQUENCE {
+ arfcn ARFCN-ValueGERAN,
+ bandIndicator BandIndicatorGERAN
+}
+
+
+CarrierFreqsGERAN ::= SEQUENCE {
+ startingARFCN ARFCN-ValueGERAN,
+ bandIndicator BandIndicatorGERAN,
+ followingARFCNs CHOICE {
+ explicitListOfARFCNs ExplicitListOfARFCNs,
+ equallySpacedARFCNs SEQUENCE {
+ arfcn-Spacing INTEGER (1..8),
+ numberOfFollowingARFCNs INTEGER (0..31)
+ },
+ variableBitMapOfARFCNs OCTET STRING (SIZE (1..16))
+ }
+}
+
+ExplicitListOfARFCNs ::= SEQUENCE (SIZE (0..31)) OF ARFCN-ValueGERAN
+
+
+CDMA2000-Type ::= ENUMERATED {type1XRTT, typeHRPD}
+
+
+CellIdentity ::= BIT STRING (SIZE (28))
+
+
+CellIndexList ::= SEQUENCE (SIZE (1..maxCellMeas)) OF CellIndex
+
+CellIndex ::= INTEGER (1..maxCellMeas)
+
+
+CellReselectionPriority ::= INTEGER (0..7)
+
+
+CSFB-RegistrationParam1XRTT ::= SEQUENCE {
+ sid BIT STRING (SIZE (15)),
+ nid BIT STRING (SIZE (16)),
+ multipleSID BOOLEAN,
+ multipleNID BOOLEAN,
+ homeReg BOOLEAN,
+ foreignSIDReg BOOLEAN,
+ foreignNIDReg BOOLEAN,
+ parameterReg BOOLEAN,
+ powerUpReg BOOLEAN,
+ registrationPeriod BIT STRING (SIZE (7)),
+ registrationZone BIT STRING (SIZE (12)),
+ totalZone BIT STRING (SIZE (3)),
+ zoneTimer BIT STRING (SIZE (3))
+}
+
+CSFB-RegistrationParam1XRTT-v920 ::= SEQUENCE {
+ powerDownReg-r9 ENUMERATED {true}
+}
+
+
+CellGlobalIdEUTRA ::= SEQUENCE {
+ plmn-Identity PLMN-Identity,
+ cellIdentity CellIdentity
+}
+
+
+CellGlobalIdUTRA ::= SEQUENCE {
+ plmn-Identity PLMN-Identity,
+ cellIdentity BIT STRING (SIZE (28))
+}
+
+
+CellGlobalIdGERAN ::= SEQUENCE {
+ plmn-Identity PLMN-Identity,
+ locationAreaCode BIT STRING (SIZE (16)),
+ cellIdentity BIT STRING (SIZE (16))
+}
+
+
+CellGlobalIdCDMA2000 ::= CHOICE {
+ cellGlobalId1XRTT BIT STRING (SIZE (47)),
+ cellGlobalIdHRPD BIT STRING (SIZE (128))
+}
+
+
+CSG-Identity ::= BIT STRING (SIZE (27))
+
+
+MobilityControlInfo ::= SEQUENCE {
+ targetPhysCellId PhysCellId,
+ carrierFreq CarrierFreqEUTRA OPTIONAL, -- Cond HO-toEUTRA
+ carrierBandwidth CarrierBandwidthEUTRA OPTIONAL, -- Cond HO-toEUTRA
+ additionalSpectrumEmission AdditionalSpectrumEmission OPTIONAL, -- Cond HO-toEUTRA
+ t304 ENUMERATED {
+ ms50, ms100, ms150, ms200, ms500, ms1000,
+ ms2000, spare1},
+ newUE-Identity C-RNTI,
+ radioResourceConfigCommon RadioResourceConfigCommon,
+ rach-ConfigDedicated RACH-ConfigDedicated OPTIONAL, -- Need OP
+ ...
+}
+
+CarrierBandwidthEUTRA ::= SEQUENCE {
+ dl-Bandwidth ENUMERATED {
+ n6, n15, n25, n50, n75, n100, spare10,
+ spare9, spare8, spare7, spare6, spare5,
+ spare4, spare3, spare2, spare1},
+ ul-Bandwidth ENUMERATED {
+ n6, n15, n25, n50, n75, n100, spare10,
+ spare9, spare8, spare7, spare6, spare5,
+ spare4, spare3, spare2, spare1} OPTIONAL -- Need OP
+}
+
+CarrierFreqEUTRA ::= SEQUENCE {
+ dl-CarrierFreq ARFCN-ValueEUTRA,
+ ul-CarrierFreq ARFCN-ValueEUTRA OPTIONAL -- Cond FDD
+}
+
+
+MobilityParametersCDMA2000 ::= OCTET STRING
+
+
+MobilityStateParameters ::= SEQUENCE {
+ t-Evaluation ENUMERATED {
+ s30, s60, s120, s180, s240, spare3, spare2, spare1},
+ t-HystNormal ENUMERATED {
+ s30, s60, s120, s180, s240, spare3, spare2, spare1},
+ n-CellChangeMedium INTEGER (1..16),
+ n-CellChangeHigh INTEGER (1..16)
+}
+
+
+PhysCellId ::= INTEGER (0..503)
+
+
+PhysCellIdRange ::= SEQUENCE {
+ start PhysCellId,
+ range ENUMERATED {
+ n4, n8, n12, n16, n24, n32, n48, n64, n84,
+ n96, n128, n168, n252, n504, spare2,
+ spare1} OPTIONAL -- Need OP
+}
+
+
+PhysCellIdCDMA2000 ::= INTEGER (0..maxPNOffset)
+
+
+PhysCellIdGERAN ::= SEQUENCE {
+ networkColourCode BIT STRING (SIZE (3)),
+ baseStationColourCode BIT STRING (SIZE (3))
+}
+
+
+PhysCellIdUTRA-FDD ::= INTEGER (0..511)
+
+
+PhysCellIdUTRA-TDD ::= INTEGER (0..127)
+
+
+PLMN-Identity ::= SEQUENCE {
+ mcc MCC OPTIONAL, -- Cond MCC
+ mnc MNC
+}
+
+MCC ::= SEQUENCE (SIZE (3)) OF
+ MCC-MNC-Digit
+
+MNC ::= SEQUENCE (SIZE (2..3)) OF
+ MCC-MNC-Digit
+
+MCC-MNC-Digit ::= INTEGER (0..9)
+
+
+
+PreRegistrationInfoHRPD ::= SEQUENCE {
+ preRegistrationAllowed BOOLEAN,
+ preRegistrationZoneId PreRegistrationZoneIdHRPD OPTIONAL, -- cond PreRegAllowed
+ secondaryPreRegistrationZoneIdList SecondaryPreRegistrationZoneIdListHRPD OPTIONAL -- Need OR
+}
+
+SecondaryPreRegistrationZoneIdListHRPD ::= SEQUENCE (SIZE (1..2)) OF PreRegistrationZoneIdHRPD
+
+PreRegistrationZoneIdHRPD ::= INTEGER (0..255)
+
+
+Q-QualMin-r9 ::= INTEGER (-34..-3)
+
+
+Q-RxLevMin ::= INTEGER (-70..-22)
+
+
+Q-OffsetRange ::= ENUMERATED {
+ dB-24, dB-22, dB-20, dB-18, dB-16, dB-14,
+ dB-12, dB-10, dB-8, dB-6, dB-5, dB-4, dB-3,
+ dB-2, dB-1, dB0, dB1, dB2, dB3, dB4, dB5,
+ dB6, dB8, dB10, dB12, dB14, dB16, dB18,
+ dB20, dB22, dB24}
+
+
+Q-OffsetRangeInterRAT ::= INTEGER (-15..15)
+
+
+ReselectionThreshold ::= INTEGER (0..31)
+
+
+ReselectionThresholdQ-r9 ::= INTEGER (0..31)
+
+
+SpeedStateScaleFactors ::= SEQUENCE {
+ sf-Medium ENUMERATED {oDot25, oDot5, oDot75, lDot0},
+ sf-High ENUMERATED {oDot25, oDot5, oDot75, lDot0}
+}
+
+SystemInfoListGERAN ::= SEQUENCE (SIZE (1..maxGERAN-SI)) OF
+ OCTET STRING (SIZE (1..23))
+
+
+SystemTimeInfoCDMA2000 ::= SEQUENCE {
+ cdma-EUTRA-Synchronisation BOOLEAN,
+ cdma-SystemTime CHOICE {
+ synchronousSystemTime BIT STRING (SIZE (39)),
+ asynchronousSystemTime BIT STRING (SIZE (49))
+ }
+}
+
+
+TrackingAreaCode ::= BIT STRING (SIZE (16))
+
+
+T-Reselection ::= INTEGER (0..7)
+
+
+AllowedMeasBandwidth ::= ENUMERATED {mbw6, mbw15, mbw25, mbw50, mbw75, mbw100}
+
+
+Hysteresis ::= INTEGER (0..30)
+
+
+MeasConfig ::= SEQUENCE {
+ -- Measurement objects
+ measObjectToRemoveList MeasObjectToRemoveList OPTIONAL, -- Need ON
+ measObjectToAddModList MeasObjectToAddModList OPTIONAL, -- Need ON
+ -- Reporting configurations
+ reportConfigToRemoveList ReportConfigToRemoveList OPTIONAL, -- Need ON
+ reportConfigToAddModList ReportConfigToAddModList OPTIONAL, -- Need ON
+ -- Measurement identities
+ measIdToRemoveList MeasIdToRemoveList OPTIONAL, -- Need ON
+ measIdToAddModList MeasIdToAddModList OPTIONAL, -- Need ON
+ -- Other parameters
+ quantityConfig QuantityConfig OPTIONAL, -- Need ON
+ measGapConfig MeasGapConfig OPTIONAL, -- Need ON
+ s-Measure RSRP-Range OPTIONAL, -- Need ON
+ preRegistrationInfoHRPD PreRegistrationInfoHRPD OPTIONAL, -- Need OP
+ speedStatePars CHOICE {
+ release NULL,
+ setup SEQUENCE {
+ mobilityStateParameters MobilityStateParameters,
+ timeToTrigger-SF SpeedStateScaleFactors
+ }
+ } OPTIONAL, -- Need ON
+ ...
+}
+
+MeasIdToRemoveList ::= SEQUENCE (SIZE (1..maxMeasId)) OF MeasId
+
+MeasObjectToRemoveList ::= SEQUENCE (SIZE (1..maxObjectId)) OF MeasObjectId
+
+ReportConfigToRemoveList ::= SEQUENCE (SIZE (1..maxReportConfigId)) OF ReportConfigId
+
+
+MeasGapConfig ::= CHOICE {
+ release NULL,
+ setup SEQUENCE {
+ gapOffset CHOICE {
+ gp0 INTEGER (0..39),
+ gp1 INTEGER (0..79),
+ ...
+ }
+ }
+}
+
+
+MeasId ::= INTEGER (1..maxMeasId)
+
+
+MeasIdToAddModList ::= SEQUENCE (SIZE (1..maxMeasId)) OF MeasIdToAddMod
+
+MeasIdToAddMod ::= SEQUENCE {
+ measId MeasId,
+ measObjectId MeasObjectId,
+ reportConfigId ReportConfigId
+}
+
+
+MeasObjectCDMA2000 ::= SEQUENCE {
+ cdma2000-Type CDMA2000-Type,
+ carrierFreq CarrierFreqCDMA2000,
+ searchWindowSize INTEGER (0..15) OPTIONAL, -- Need ON
+ offsetFreq Q-OffsetRangeInterRAT DEFAULT 0,
+ cellsToRemoveList CellIndexList OPTIONAL, -- Need ON
+ cellsToAddModList CellsToAddModListCDMA2000 OPTIONAL, -- Need ON
+ cellForWhichToReportCGI PhysCellIdCDMA2000 OPTIONAL, -- Need ON
+ ...
+}
+
+CellsToAddModListCDMA2000 ::= SEQUENCE (SIZE (1..maxCellMeas)) OF CellsToAddModCDMA2000
+
+CellsToAddModCDMA2000 ::= SEQUENCE {
+ cellIndex INTEGER (1..maxCellMeas),
+ physCellId PhysCellIdCDMA2000
+}
+
+
+MeasObjectEUTRA ::= SEQUENCE {
+ carrierFreq ARFCN-ValueEUTRA,
+ allowedMeasBandwidth AllowedMeasBandwidth,
+ presenceAntennaPort1 PresenceAntennaPort1,
+ neighCellConfig NeighCellConfig,
+ offsetFreq Q-OffsetRange DEFAULT dB0,
+ -- Neighbour cell list
+ cellsToRemoveList CellIndexList OPTIONAL, -- Need ON
+ cellsToAddModList CellsToAddModList OPTIONAL, -- Need ON
+ -- Black list
+ blackCellsToRemoveList CellIndexList OPTIONAL, -- Need ON
+ blackCellsToAddModList BlackCellsToAddModList OPTIONAL, -- Need ON
+ cellForWhichToReportCGI PhysCellId OPTIONAL, -- Need ON
+ ...
+}
+
+CellsToAddModList ::= SEQUENCE (SIZE (1..maxCellMeas)) OF CellsToAddMod
+
+CellsToAddMod ::= SEQUENCE {
+ cellIndex INTEGER (1..maxCellMeas),
+ physCellId PhysCellId,
+ cellIndividualOffset Q-OffsetRange
+}
+
+BlackCellsToAddModList ::= SEQUENCE (SIZE (1..maxCellMeas)) OF BlackCellsToAddMod
+
+BlackCellsToAddMod ::= SEQUENCE {
+ cellIndex INTEGER (1..maxCellMeas),
+ physCellIdRange PhysCellIdRange
+}
+
+
+MeasObjectGERAN ::= SEQUENCE {
+ carrierFreqs CarrierFreqsGERAN,
+ offsetFreq Q-OffsetRangeInterRAT DEFAULT 0,
+ ncc-Permitted BIT STRING(SIZE (8)) DEFAULT '11111111'B,
+ cellForWhichToReportCGI PhysCellIdGERAN OPTIONAL, -- Need ON
+ ...
+}
+
+
+MeasObjectId ::= INTEGER (1..maxObjectId)
+
+
+MeasObjectToAddModList ::= SEQUENCE (SIZE (1..maxObjectId)) OF MeasObjectToAddMod
+
+MeasObjectToAddMod ::= SEQUENCE {
+ measObjectId MeasObjectId,
+ measObject CHOICE {
+ measObjectEUTRA MeasObjectEUTRA,
+ measObjectUTRA MeasObjectUTRA,
+ measObjectGERAN MeasObjectGERAN,
+ measObjectCDMA2000 MeasObjectCDMA2000,
+ ...
+ }
+}
+
+
+MeasObjectUTRA ::= SEQUENCE {
+ carrierFreq ARFCN-ValueUTRA,
+ offsetFreq Q-OffsetRangeInterRAT DEFAULT 0,
+ cellsToRemoveList CellIndexList OPTIONAL, -- Need ON
+ cellsToAddModList CHOICE {
+ cellsToAddModListUTRA-FDD CellsToAddModListUTRA-FDD,
+ cellsToAddModListUTRA-TDD CellsToAddModListUTRA-TDD
+ } OPTIONAL, -- Need ON
+ cellForWhichToReportCGI CHOICE {
+ utra-FDD PhysCellIdUTRA-FDD,
+ utra-TDD PhysCellIdUTRA-TDD
+ } OPTIONAL, -- Need ON
+ ...
+}
+
+CellsToAddModListUTRA-FDD ::= SEQUENCE (SIZE (1..maxCellMeas)) OF CellsToAddModUTRA-FDD
+
+CellsToAddModUTRA-FDD ::= SEQUENCE {
+ cellIndex INTEGER (1..maxCellMeas),
+ physCellId PhysCellIdUTRA-FDD
+}
+
+CellsToAddModListUTRA-TDD ::= SEQUENCE (SIZE (1..maxCellMeas)) OF CellsToAddModUTRA-TDD
+
+CellsToAddModUTRA-TDD ::= SEQUENCE {
+ cellIndex INTEGER (1..maxCellMeas),
+ physCellId PhysCellIdUTRA-TDD
+}
+
+
+MeasResults ::= SEQUENCE {
+ measId MeasId,
+ measResultServCell SEQUENCE {
+ rsrpResult RSRP-Range,
+ rsrqResult RSRQ-Range
+ },
+ measResultNeighCells CHOICE {
+ measResultListEUTRA MeasResultListEUTRA,
+ measResultListUTRA MeasResultListUTRA,
+ measResultListGERAN MeasResultListGERAN,
+ measResultsCDMA2000 MeasResultsCDMA2000,
+ ...
+ } OPTIONAL,
+ ...,
+ [[ measResultForECID-r9 MeasResultForECID-r9 OPTIONAL
+ ]]
+}
+
+MeasResultListEUTRA ::= SEQUENCE (SIZE (1..maxCellReport)) OF MeasResultEUTRA
+
+MeasResultEUTRA ::= SEQUENCE {
+ physCellId PhysCellId,
+ cgi-Info SEQUENCE {
+ cellGlobalId CellGlobalIdEUTRA,
+ trackingAreaCode TrackingAreaCode,
+ plmn-IdentityList PLMN-IdentityList2 OPTIONAL
+ } OPTIONAL,
+ measResult SEQUENCE {
+ rsrpResult RSRP-Range OPTIONAL,
+ rsrqResult RSRQ-Range OPTIONAL,
+ ...,
+ [[ additionalSI-Info-r9 AdditionalSI-Info-r9 OPTIONAL
+ ]]
+ }
+}
+
+MeasResultListUTRA ::= SEQUENCE (SIZE (1..maxCellReport)) OF MeasResultUTRA
+
+MeasResultUTRA ::= SEQUENCE {
+ physCellId CHOICE {
+ fdd PhysCellIdUTRA-FDD,
+ tdd PhysCellIdUTRA-TDD
+ },
+ cgi-Info SEQUENCE {
+ cellGlobalId CellGlobalIdUTRA,
+ locationAreaCode BIT STRING (SIZE (16)) OPTIONAL,
+ routingAreaCode BIT STRING (SIZE (8)) OPTIONAL,
+ plmn-IdentityList PLMN-IdentityList2 OPTIONAL
+ } OPTIONAL,
+ measResult SEQUENCE {
+ utra-RSCP INTEGER (-5..91) OPTIONAL,
+ utra-EcN0 INTEGER (0..49) OPTIONAL,
+ ...,
+ [[ additionalSI-Info-r9 AdditionalSI-Info-r9 OPTIONAL
+ ]]
+ }
+}
+
+MeasResultListGERAN ::= SEQUENCE (SIZE (1..maxCellReport)) OF MeasResultGERAN
+
+MeasResultGERAN ::= SEQUENCE {
+ carrierFreq CarrierFreqGERAN,
+ physCellId PhysCellIdGERAN,
+ cgi-Info SEQUENCE {
+ cellGlobalId CellGlobalIdGERAN,
+ routingAreaCode BIT STRING (SIZE (8)) OPTIONAL
+ } OPTIONAL,
+ measResult SEQUENCE {
+ rssi INTEGER (0..63),
+ ...
+ }
+}
+
+MeasResultsCDMA2000 ::= SEQUENCE {
+ preRegistrationStatusHRPD BOOLEAN,
+ measResultListCDMA2000 MeasResultListCDMA2000
+}
+
+MeasResultListCDMA2000 ::= SEQUENCE (SIZE (1..maxCellReport)) OF MeasResultCDMA2000
+
+MeasResultCDMA2000 ::= SEQUENCE {
+ physCellId PhysCellIdCDMA2000,
+ cgi-Info CellGlobalIdCDMA2000 OPTIONAL,
+ measResult SEQUENCE {
+ pilotPnPhase INTEGER (0..32767) OPTIONAL,
+ pilotStrength INTEGER (0..63),
+ ...
+ }
+}
+
+MeasResultForECID-r9 ::= SEQUENCE {
+ ue-RxTxTimeDiffResult-r9 INTEGER (0..4095),
+ currentSFN-r9 BIT STRING (SIZE (10))
+}
+
+PLMN-IdentityList2 ::= SEQUENCE (SIZE (1..5)) OF PLMN-Identity
+
+AdditionalSI-Info-r9 ::= SEQUENCE {
+ csg-MemberStatus-r9 ENUMERATED {member} OPTIONAL,
+ csg-Identity-r9 CSG-Identity OPTIONAL
+}
+
+
+QuantityConfig ::= SEQUENCE {
+ quantityConfigEUTRA QuantityConfigEUTRA OPTIONAL, -- Need ON
+ quantityConfigUTRA QuantityConfigUTRA OPTIONAL, -- Need ON
+ quantityConfigGERAN QuantityConfigGERAN OPTIONAL, -- Need ON
+ quantityConfigCDMA2000 QuantityConfigCDMA2000 OPTIONAL, -- Need ON
+ ...
+}
+
+QuantityConfigEUTRA ::= SEQUENCE {
+ filterCoefficientRSRP FilterCoefficient DEFAULT fc4,
+ filterCoefficientRSRQ FilterCoefficient DEFAULT fc4
+}
+
+QuantityConfigUTRA ::= SEQUENCE {
+ measQuantityUTRA-FDD ENUMERATED {cpich-RSCP, cpich-EcN0},
+ measQuantityUTRA-TDD ENUMERATED {pccpch-RSCP},
+ filterCoefficient FilterCoefficient DEFAULT fc4
+}
+
+QuantityConfigGERAN ::= SEQUENCE {
+ measQuantityGERAN ENUMERATED {rssi},
+ filterCoefficient FilterCoefficient DEFAULT fc2
+}
+
+QuantityConfigCDMA2000 ::= SEQUENCE {
+ measQuantityCDMA2000 ENUMERATED {pilotStrength, pilotPnPhaseAndPilotStrength}
+}
+
+
+ReportConfigEUTRA ::= SEQUENCE {
+ triggerType CHOICE {
+ event SEQUENCE {
+ eventId CHOICE {
+ eventA1 SEQUENCE {
+ a1-Threshold ThresholdEUTRA
+ },
+ eventA2 SEQUENCE {
+ a2-Threshold ThresholdEUTRA
+ },
+ eventA3 SEQUENCE {
+ a3-Offset INTEGER (-30..30),
+ reportOnLeave BOOLEAN
+ },
+ eventA4 SEQUENCE {
+ a4-Threshold ThresholdEUTRA
+ },
+ eventA5 SEQUENCE {
+ a5-Threshold1 ThresholdEUTRA,
+ a5-Threshold2 ThresholdEUTRA
+ },
+ ...
+ },
+ hysteresis Hysteresis,
+ timeToTrigger TimeToTrigger
+ },
+ periodical SEQUENCE {
+ purpose ENUMERATED {
+ reportStrongestCells, reportCGI}
+ }
+ },
+ triggerQuantity ENUMERATED {rsrp, rsrq},
+ reportQuantity ENUMERATED {sameAsTriggerQuantity, both},
+ maxReportCells INTEGER (1..maxCellReport),
+ reportInterval ReportInterval,
+ reportAmount ENUMERATED {r1, r2, r4, r8, r16, r32, r64, infinity},
+ ...,
+ [[ si-RequestForHO-r9 ENUMERATED {setup} OPTIONAL, -- Cond reportCGI
+ ue-RxTxTimeDiffPeriodical-r9 ENUMERATED {setup} OPTIONAL -- Need OR
+ ]]
+}
+
+ThresholdEUTRA ::= CHOICE{
+ threshold-RSRP RSRP-Range,
+ threshold-RSRQ RSRQ-Range
+}
+
+
+ReportConfigId ::= INTEGER (1..maxReportConfigId)
+
+
+ReportConfigInterRAT ::= SEQUENCE {
+ triggerType CHOICE {
+ event SEQUENCE {
+ eventId CHOICE {
+ eventB1 SEQUENCE {
+ b1-Threshold CHOICE {
+ b1-ThresholdUTRA ThresholdUTRA,
+ b1-ThresholdGERAN ThresholdGERAN,
+ b1-ThresholdCDMA2000 ThresholdCDMA2000
+ }
+ },
+ eventB2 SEQUENCE {
+ b2-Threshold1 ThresholdEUTRA,
+ b2-Threshold2 CHOICE {
+ b2-Threshold2UTRA ThresholdUTRA,
+ b2-Threshold2GERAN ThresholdGERAN,
+ b2-Threshold2CDMA2000 ThresholdCDMA2000
+ }
+ },
+ ...
+ },
+ hysteresis Hysteresis,
+ timeToTrigger TimeToTrigger
+ },
+ periodical SEQUENCE {
+ purpose ENUMERATED {
+ reportStrongestCells,
+ reportStrongestCellsForSON,
+ reportCGI}
+ }
+ },
+ maxReportCells INTEGER (1..maxCellReport),
+ reportInterval ReportInterval,
+ reportAmount ENUMERATED {r1, r2, r4, r8, r16, r32, r64, infinity},
+ ...,
+ [[ si-RequestForHO-r9 ENUMERATED {setup} OPTIONAL -- Cond reportCGI
+ ]]
+}
+
+ThresholdUTRA ::= CHOICE{
+ utra-RSCP INTEGER (-5..91),
+ utra-EcN0 INTEGER (0..49)
+}
+
+ThresholdGERAN ::= INTEGER (0..63)
+
+ThresholdCDMA2000 ::= INTEGER (0..63)
+
+
+ReportConfigToAddModList ::= SEQUENCE (SIZE (1..maxReportConfigId)) OF ReportConfigToAddMod
+
+ReportConfigToAddMod ::= SEQUENCE {
+ reportConfigId ReportConfigId,
+ reportConfig CHOICE {
+ reportConfigEUTRA ReportConfigEUTRA,
+ reportConfigInterRAT ReportConfigInterRAT
+ }
+}
+
+
+
+ReportInterval ::= ENUMERATED {
+ ms120, ms240, ms480, ms640, ms1024, ms2048, ms5120, ms10240,
+ min1, min6, min12, min30, min60, spare3, spare2, spare1}
+
+
+RSRP-Range ::= INTEGER(0..97)
+
+
+RSRQ-Range ::= INTEGER(0..34)
+
+
+TimeToTrigger ::= ENUMERATED {
+ ms0, ms40, ms64, ms80, ms100, ms128, ms160, ms256,
+ ms320, ms480, ms512, ms640, ms1024, ms1280, ms2560,
+ ms5120}
+
+
+C-RNTI ::= BIT STRING (SIZE (16))
+
+
+DedicatedInfoCDMA2000 ::= OCTET STRING
+
+
+DedicatedInfoNAS ::= OCTET STRING
+
+
+FilterCoefficient ::= ENUMERATED {
+ fc0, fc1, fc2, fc3, fc4, fc5,
+ fc6, fc7, fc8, fc9, fc11, fc13,
+ fc15, fc17, fc19, spare1, ...}
+
+
+MMEC ::= BIT STRING (SIZE (8))
+
+
+NeighCellConfig ::= BIT STRING (SIZE (2))
+
+
+OtherConfig-r9 ::= SEQUENCE {
+ reportProximityConfig-r9 ReportProximityConfig-r9 OPTIONAL, -- Need ON
+ ...
+}
+
+ReportProximityConfig-r9 ::= SEQUENCE {
+ proximityIndicationEUTRA-r9 ENUMERATED {enabled} OPTIONAL, -- Need OR
+ proximityIndicationUTRA-r9 ENUMERATED {enabled} OPTIONAL -- Need OR
+}
+
+
+RAND-CDMA2000 ::= BIT STRING (SIZE (32))
+
+
+RAT-Type ::= ENUMERATED {
+ eutra, utra, geran-cs, geran-ps, cdma2000-1XRTT,
+ spare3, spare2, spare1, ...}
+
+
+RRC-TransactionIdentifier ::= INTEGER (0..3)
+
+
+S-TMSI ::= SEQUENCE {
+ mmec MMEC,
+ m-TMSI BIT STRING (SIZE (32))
+}
+
+
+UE-CapabilityRAT-ContainerList ::=SEQUENCE (SIZE (0..maxRAT-Capabilities)) OF UE-CapabilityRAT-Container
+
+UE-CapabilityRAT-Container ::= SEQUENCE {
+ rat-Type RAT-Type,
+ ueCapabilityRAT-Container OCTET STRING
+}
+
+
+UE-EUTRA-Capability ::= SEQUENCE {
+ accessStratumRelease AccessStratumRelease,
+ ue-Category INTEGER (1..5),
+ pdcp-Parameters PDCP-Parameters,
+ phyLayerParameters PhyLayerParameters,
+ rf-Parameters RF-Parameters,
+ measParameters MeasParameters,
+ featureGroupIndicators BIT STRING (SIZE (32)) OPTIONAL,
+ interRAT-Parameters SEQUENCE {
+ utraFDD IRAT-ParametersUTRA-FDD OPTIONAL,
+ utraTDD128 IRAT-ParametersUTRA-TDD128 OPTIONAL,
+ utraTDD384 IRAT-ParametersUTRA-TDD384 OPTIONAL,
+ utraTDD768 IRAT-ParametersUTRA-TDD768 OPTIONAL,
+ geran IRAT-ParametersGERAN OPTIONAL,
+ cdma2000-HRPD IRAT-ParametersCDMA2000-HRPD OPTIONAL,
+ cdma2000-1xRTT IRAT-ParametersCDMA2000-1XRTT OPTIONAL
+ },
+ nonCriticalExtension UE-EUTRA-Capability-v920-IEs OPTIONAL
+}
+
+UE-EUTRA-Capability-v920-IEs ::= SEQUENCE {
+ phyLayerParameters-v920 PhyLayerParameters-v920,
+ interRAT-ParametersGERAN-v920 IRAT-ParametersGERAN-v920,
+ interRAT-ParametersUTRA-v920 IRAT-ParametersUTRA-v920 OPTIONAL,
+ interRAT-Parameters-v920 IRAT-ParametersCDMA2000-1XRTT-v920 OPTIONAL,
+ deviceType-r9 ENUMERATED {noBenFromBatConsumpOpt} OPTIONAL,
+ csg-ProximityIndicationParameters-r9 CSG-ProximityIndicationParameters-r9,
+ neighCellSI-AcquisitionParameters-r9 NeighCellSI-AcquisitionParameters-r9,
+ son-Parameters-r9 SON-Parameters-r9,
+ nonCriticalExtension SEQUENCE {} OPTIONAL
+}
+
+AccessStratumRelease ::= ENUMERATED {
+ rel8, rel9, spare6, spare5, spare4, spare3,
+ spare2, spare1, ...}
+
+PDCP-Parameters ::= SEQUENCE {
+ supportedROHC-Profiles SEQUENCE {
+ profile0x0001 BOOLEAN,
+ profile0x0002 BOOLEAN,
+ profile0x0003 BOOLEAN,
+ profile0x0004 BOOLEAN,
+ profile0x0006 BOOLEAN,
+ profile0x0101 BOOLEAN,
+ profile0x0102 BOOLEAN,
+ profile0x0103 BOOLEAN,
+ profile0x0104 BOOLEAN
+ },
+ maxNumberROHC-ContextSessions ENUMERATED {
+ cs2, cs4, cs8, cs12, cs16, cs24, cs32,
+ cs48, cs64, cs128, cs256, cs512, cs1024,
+ cs16384, spare2, spare1} DEFAULT cs16,
+ ...
+}
+
+PhyLayerParameters ::= SEQUENCE {
+ ue-TxAntennaSelectionSupported BOOLEAN,
+ ue-SpecificRefSigsSupported BOOLEAN
+}
+
+PhyLayerParameters-v920 ::= SEQUENCE {
+ enhancedDualLayerFDD-Supported-r9 BOOLEAN,
+ enhancedDualLayerTDD-Supported-r9 BOOLEAN
+}
+
+RF-Parameters ::= SEQUENCE {
+ supportedBandListEUTRA SupportedBandListEUTRA
+}
+
+SupportedBandListEUTRA ::= SEQUENCE (SIZE (1..maxBands)) OF SupportedBandEUTRA
+
+SupportedBandEUTRA ::= SEQUENCE {
+ bandEUTRA INTEGER (1..64),
+ halfDuplex BOOLEAN
+}
+
+MeasParameters ::= SEQUENCE {
+ bandListEUTRA BandListEUTRA
+}
+
+BandListEUTRA ::= SEQUENCE (SIZE (1..maxBands)) OF BandInfoEUTRA
+
+BandInfoEUTRA ::= SEQUENCE {
+ interFreqBandList InterFreqBandList,
+ interRAT-BandList InterRAT-BandList OPTIONAL
+}
+
+InterFreqBandList ::= SEQUENCE (SIZE (1..maxBands)) OF InterFreqBandInfo
+
+InterFreqBandInfo ::= SEQUENCE {
+ interFreqNeedForGaps BOOLEAN
+}
+
+InterRAT-BandList ::= SEQUENCE (SIZE (1..maxBands)) OF InterRAT-BandInfo
+
+InterRAT-BandInfo ::= SEQUENCE {
+ interRAT-NeedForGaps BOOLEAN
+}
+
+IRAT-ParametersUTRA-FDD ::= SEQUENCE {
+ supportedBandListUTRA-FDD SupportedBandListUTRA-FDD
+}
+
+IRAT-ParametersUTRA-v920 ::= SEQUENCE {
+ e-Redirection-r9 ENUMERATED {supported}
+}
+
+SupportedBandListUTRA-FDD ::= SEQUENCE (SIZE (1..maxBands)) OF SupportedBandUTRA-FDD
+
+SupportedBandUTRA-FDD ::= ENUMERATED {
+ bandI, bandII, bandIII, bandIV, bandV, bandVI,
+ bandVII, bandVIII, bandIX, bandX, bandXI,
+ bandXII, bandXIII, bandXIV, bandXV, bandXVI, ...}
+
+IRAT-ParametersUTRA-TDD128 ::= SEQUENCE {
+ supportedBandListUTRA-TDD128 SupportedBandListUTRA-TDD128
+}
+
+SupportedBandListUTRA-TDD128 ::= SEQUENCE (SIZE (1..maxBands)) OF SupportedBandUTRA-TDD128
+
+SupportedBandUTRA-TDD128 ::= ENUMERATED {
+ a, b, c, d, e, f, g, h, i, j, k, l, m, n,
+ o, p, ...}
+
+IRAT-ParametersUTRA-TDD384 ::= SEQUENCE {
+ supportedBandListUTRA-TDD384 SupportedBandListUTRA-TDD384
+}
+
+SupportedBandListUTRA-TDD384 ::= SEQUENCE (SIZE (1..maxBands)) OF SupportedBandUTRA-TDD384
+
+SupportedBandUTRA-TDD384 ::= ENUMERATED {
+ a, b, c, d, e, f, g, h, i, j, k, l, m, n,
+ o, p, ...}
+
+IRAT-ParametersUTRA-TDD768 ::= SEQUENCE {
+ supportedBandListUTRA-TDD768 SupportedBandListUTRA-TDD768
+}
+
+SupportedBandListUTRA-TDD768 ::= SEQUENCE (SIZE (1..maxBands)) OF SupportedBandUTRA-TDD768
+
+SupportedBandUTRA-TDD768 ::= ENUMERATED {
+ a, b, c, d, e, f, g, h, i, j, k, l, m, n,
+ o, p, ...}
+
+IRAT-ParametersGERAN ::= SEQUENCE {
+ supportedBandListGERAN SupportedBandListGERAN,
+ interRAT-PS-HO-ToGERAN BOOLEAN
+}
+
+IRAT-ParametersGERAN-v920 ::= SEQUENCE {
+ dtm-r9 ENUMERATED {supported} OPTIONAL,
+ e-RedirectionGERAN-r9 ENUMERATED {supported} OPTIONAL
+}
+
+SupportedBandListGERAN ::= SEQUENCE (SIZE (1..maxBands)) OF SupportedBandGERAN
+
+SupportedBandGERAN ::= ENUMERATED {
+ gsm450, gsm480, gsm710, gsm750, gsm810, gsm850,
+ gsm900P, gsm900E, gsm900R, gsm1800, gsm1900,
+ spare5, spare4, spare3, spare2, spare1, ...}
+
+IRAT-ParametersCDMA2000-HRPD ::= SEQUENCE {
+ supportedBandListHRPD SupportedBandListHRPD,
+ tx-ConfigHRPD ENUMERATED {single, dual},
+ rx-ConfigHRPD ENUMERATED {single, dual}
+}
+
+SupportedBandListHRPD ::= SEQUENCE (SIZE (1..maxCDMA-BandClass)) OF BandclassCDMA2000
+
+IRAT-ParametersCDMA2000-1XRTT ::= SEQUENCE {
+ supportedBandList1XRTT SupportedBandList1XRTT,
+ tx-Config1XRTT ENUMERATED {single, dual},
+ rx-Config1XRTT ENUMERATED {single, dual}
+}
+
+IRAT-ParametersCDMA2000-1XRTT-v920 ::= SEQUENCE {
+ e-CSFB-r9 ENUMERATED {supported},
+ e-CSFB-ConcPS-Mob-r9 ENUMERATED {notSupported, supported}
+}
+
+SupportedBandList1XRTT ::= SEQUENCE (SIZE (1..maxCDMA-BandClass)) OF BandclassCDMA2000
+
+CSG-ProximityIndicationParameters-r9 ::= SEQUENCE {
+ intraFreqProximityIndicationSupported-r9 BOOLEAN,
+ interFreqProximityIndicationSupported-r9 BOOLEAN,
+ utran-ProximityIndicationSupported-r9 BOOLEAN
+}
+
+NeighCellSI-AcquisitionParameters-r9 ::= SEQUENCE {
+ intraFreqSI-AcquisitionForHO-Supported-r9 BOOLEAN,
+ interFreqSI-AcquisitionForHO-Supported-r9 BOOLEAN,
+ utran-SI-AcquisitionForHO-Supported-r9 BOOLEAN
+}
+
+SON-Parameters-r9 ::= SEQUENCE {
+ rach-ReportSupported-r9 BOOLEAN
+}
+
+
+UE-TimersAndConstants ::= SEQUENCE {
+ t300 ENUMERATED {
+ ms100, ms200, ms300, ms400, ms600, ms1000, ms1500,
+ ms2000},
+ t301 ENUMERATED {
+ ms100, ms200, ms300, ms400, ms600, ms1000, ms1500,
+ ms2000},
+ t310 ENUMERATED {
+ ms0, ms50, ms100, ms200, ms500, ms1000, ms2000},
+ n310 ENUMERATED {
+ n1, n2, n3, n4, n6, n8, n10, n20},
+ t311 ENUMERATED {
+ ms1000, ms3000, ms5000, ms10000, ms15000,
+ ms20000, ms30000},
+ n311 ENUMERATED {
+ n1, n2, n3, n4, n5, n6, n8, n10},
+ ...
+}
+
+
+MBMS-NotificationConfig-r9 ::= SEQUENCE {
+ notificationRepetitionCoeff-r9 ENUMERATED {n2, n4},
+ notificationOffset-r9 INTEGER (0..10),
+ notificationSF-Index-r9 INTEGER (1..6)
+}
+
+
+MBSFN-AreaInfoList-r9 ::= SEQUENCE (SIZE(1..maxMBSFN-Area)) OF MBSFN-AreaInfo-r9
+
+MBSFN-AreaInfo-r9 ::= SEQUENCE {
+ mbsfn-AreaId-r9 INTEGER (0..255),
+ non-MBSFNregionLength ENUMERATED {s1, s2},
+ notificationIndicator-r9 INTEGER (0..7),
+ mcch-Config-r9 SEQUENCE {
+ mcch-RepetitionPeriod-r9 ENUMERATED {rf32, rf64, rf128, rf256},
+ mcch-Offset-r9 INTEGER (0..10),
+ mcch-ModificationPeriod-r9 ENUMERATED {rf512, rf1024},
+ sf-AllocInfo-r9 BIT STRING (SIZE(6)),
+ signallingMCS-r9 ENUMERATED {n2, n7, n13, n19}
+ },
+ ...
+}
+
+
+MBSFN-SubframeConfig ::= SEQUENCE {
+ radioframeAllocationPeriod ENUMERATED {n1, n2, n4, n8, n16, n32},
+ radioframeAllocationOffset INTEGER (0..7),
+ subframeAllocation CHOICE {
+ oneFrame BIT STRING (SIZE(6)),
+ fourFrames BIT STRING (SIZE(24))
+ }
+}
+
+PMCH-InfoList-r9 ::= SEQUENCE (SIZE (0..maxPMCH-PerMBSFN)) OF PMCH-Info-r9
+
+PMCH-Info-r9 ::= SEQUENCE {
+ pmch-Config-r9 PMCH-Config-r9,
+ mbms-SessionInfoList-r9 MBMS-SessionInfoList-r9,
+ ...
+}
+
+MBMS-SessionInfoList-r9 ::= SEQUENCE (SIZE (0..maxSessionPerPMCH)) OF MBMS-SessionInfo-r9
+
+MBMS-SessionInfo-r9 ::= SEQUENCE {
+ tmgi-r9 TMGI-r9,
+ sessionId-r9 OCTET STRING (SIZE (1)) OPTIONAL, -- Need OR
+ logicalChannelIdentity-r9 INTEGER (0..maxSessionPerPMCH-1),
+ ...
+}
+
+PMCH-Config-r9 ::= SEQUENCE {
+ sf-AllocEnd-r9 INTEGER (0..1535),
+ dataMCS-r9 INTEGER (0..28),
+ mch-SchedulingPeriod-r9 ENUMERATED {
+ rf8, rf16, rf32, rf64, rf128, rf256, rf512, rf1024},
+ ...
+}
+
+TMGI-r9 ::= SEQUENCE {
+ plmn-Id-r9 CHOICE {
+ plmn-Index-r9 INTEGER (1..6),
+ explicitValue-r9 PLMN-Identity
+ },
+ serviceId-r9 OCTET STRING (SIZE (3))
+}
+
+
+maxBands INTEGER ::= 64 -- Maximum number of bands listed in EUTRA UE caps
+maxCDMA-BandClass INTEGER ::= 32 -- Maximum value of the CDMA band classes
+maxCellBlack INTEGER ::= 16 -- Maximum number of blacklisted cells
+ -- listed in SIB type 4 and 5
+maxCellInter INTEGER ::= 16 -- Maximum number of neighbouring inter-frequency
+ -- cells listed in SIB type 5
+maxCellIntra INTEGER ::= 16 -- Maximum number of neighbouring intra-frequency
+ -- cells listed in SIB type 4
+maxCellMeas INTEGER ::= 32 -- Maximum number of entries in each of the neighbour
+ -- cell lists in a measurement object
+maxCellReport INTEGER ::= 8 -- Maximum number of reported cells
+maxDRB INTEGER ::= 11 -- Maximum number of Data Radio Bearers
+maxEARFCN INTEGER ::= 65535 -- Maximum value of EUTRA carrier fequency
+maxFreq INTEGER ::= 8 -- Maximum number of EUTRA carrier frequencies
+maxCellInfo-GERAN-r9 INTEGER ::= 32 -- Maximum number of GERAN cells for which system in-
+ -- formation can be provided as redirection assistance
+maxGERAN-SI INTEGER ::= 10 -- Maximum number of GERAN SI blocks that can be
+ -- provided as part of NACC information
+maxGNFG INTEGER ::= 16 -- Maximum number of GERAN neighbour freq groups
+maxMBSFN-Allocations INTEGER ::= 8 -- Maximum number of MBSFN frame allocations with
+ -- different offset
+maxMBSFN-Area INTEGER ::= 8
+maxSessionPerPMCH INTEGER ::= 29
+maxSessionPerPMCH-1 INTEGER ::= 28
+maxPMCH-PerMBSFN INTEGER ::= 15
+maxMeasId INTEGER ::= 32
+maxObjectId INTEGER ::= 32
+maxPageRec INTEGER ::= 16 --
+maxPNOffset INTEGER ::= 511 -- Maximum number of CDMA2000 PNOffsets
+maxRAT-Capabilities INTEGER ::= 8 -- Maximum number of interworking RATs (incl EUTRA)
+maxReportConfigId INTEGER ::= 32
+maxSIB INTEGER ::= 32 -- Maximum number of SIBs
+maxSIB-1 INTEGER ::= 31
+maxSI-Message INTEGER ::= 32 -- Maximum number of SI messages
+maxUTRA-FDD-Carrier INTEGER ::= 16 -- Maximum number of UTRA FDD carrier frequencies
+maxUTRA-TDD-Carrier INTEGER ::= 16 -- Maximum number of UTRA TDD carrier frequencies
+maxUTRA-CellInfo-r9 INTEGER ::= 16 -- Maximum number of cells for which system information
+ -- can be provided as redirection assistance
+
+
+END
diff --git a/lib/asn1/test/asn1_SUITE_data/EUTRA-UE-Variables.asn b/lib/asn1/test/asn1_SUITE_data/EUTRA-UE-Variables.asn
new file mode 100644
index 0000000000..414140a6fb
--- /dev/null
+++ b/lib/asn1/test/asn1_SUITE_data/EUTRA-UE-Variables.asn
@@ -0,0 +1,49 @@
+-- 3GPP TS 36.331 V8.8.0 (2009-12)
+-- $Id$
+--
+EUTRA-UE-Variables DEFINITIONS AUTOMATIC TAGS ::=
+
+BEGIN
+
+
+VarMeasConfig ::= SEQUENCE {
+ -- Measurement identities
+ measIdList MeasIdToAddModList OPTIONAL,
+ -- Measurement objects
+ measObjectList MeasObjectToAddModList OPTIONAL,
+ -- Reporting configurations
+ reportConfigList ReportConfigToAddModList OPTIONAL,
+ -- Other parameters
+ quantityConfig QuantityConfig OPTIONAL,
+ s-Measure RSRP-Range OPTIONAL,
+ speedStatePars CHOICE {
+ release NULL,
+ setup SEQUENCE {
+ mobilityStateParameters MobilityStateParameters,
+ timeToTrigger-SF SpeedStateScaleFactors
+ }
+ } OPTIONAL
+}
+
+
+VarMeasReportList ::= SEQUENCE (SIZE (1..maxMeasId)) OF VarMeasReport
+
+VarMeasReport ::= SEQUENCE {
+ -- List of measurement that have been triggered
+ measId MeasId,
+ cellsTriggeredList CellsTriggeredList OPTIONAL,
+ numberOfReportsSent INTEGER
+}
+
+CellsTriggeredList ::= SEQUENCE (SIZE (1..maxCellMeas)) OF PhysCellId
+
+
+VarShortMAC-Input ::= SEQUENCE {
+ cellIdentity CellIdentity,
+ physCellId PhysCellId,
+ c-RNTI C-RNTI
+}
+
+
+
+END \ No newline at end of file
diff --git a/lib/asn1/test/asn1_SUITE_data/EUTRA-extract-55.asn b/lib/asn1/test/asn1_SUITE_data/EUTRA-extract-55.asn
new file mode 100644
index 0000000000..248e6963c9
--- /dev/null
+++ b/lib/asn1/test/asn1_SUITE_data/EUTRA-extract-55.asn
@@ -0,0 +1,47 @@
+EUTRA-extract-55 DEFINITIONS AUTOMATIC TAGS ::=
+
+BEGIN
+
+
+SystemInformation-r8-IEs ::= SEQUENCE {
+ sib-TypeAndInfo SEQUENCE (SIZE (1..5)) OF CHOICE {
+ sib2 SystemInformationBlockType2,
+ sib3 SystemInformationBlockType3,
+ sib4 SystemInformationBlockType4,
+ sib5 SystemInformationBlockType5,
+ sib6 SystemInformationBlockType6,
+ sib7 SystemInformationBlockType7,
+ sib8 SystemInformationBlockType8,
+ sib9 SystemInformationBlockType9,
+ sib10 SystemInformationBlockType10,
+ sib11 SystemInformationBlockType11,
+ ...
+ },
+ nonCriticalExtension SEQUENCE {} OPTIONAL
+}
+
+SystemInformationBlockType2 ::= INTEGER
+SystemInformationBlockType3 ::= INTEGER
+SystemInformationBlockType4 ::= INTEGER
+SystemInformationBlockType5 ::= INTEGER
+SystemInformationBlockType6 ::= INTEGER
+SystemInformationBlockType7 ::= INTEGER
+SystemInformationBlockType8 ::= INTEGER
+SystemInformationBlockType9 ::= INTEGER
+SystemInformationBlockType10 ::= INTEGER
+SystemInformationBlockType11 ::= INTEGER
+
+-- OTP-7763
+CellIdentity ::= BIT STRING (SIZE (28))
+
+Seq ::= SEQUENCE {
+ a INTEGER,
+ b1 BIT STRING (SIZE (8)),
+ b2 BIT STRING (SIZE (1)),
+ b CellIdentity,
+ c INTEGER,
+ d BOOLEAN
+}
+
+
+END \ No newline at end of file
diff --git a/lib/asn1/test/asn1_SUITE_data/EUTRA-extract-7407.asn1 b/lib/asn1/test/asn1_SUITE_data/EUTRA-extract-7407.asn1
new file mode 100644
index 0000000000..fb81c42251
--- /dev/null
+++ b/lib/asn1/test/asn1_SUITE_data/EUTRA-extract-7407.asn1
@@ -0,0 +1,109 @@
+-- 3GPP TS 36.331 V8.8.0 (2009-12) modified
+-- $Id$
+--
+EUTRA-extract-7407 DEFINITIONS AUTOMATIC TAGS ::=
+
+BEGIN
+
+
+BCCH-BCH-Message ::= SEQUENCE {
+ message BCCH-BCH-MessageType
+}
+
+BCCH-BCH-MessageType ::= MasterInformationBlock
+
+
+BCCH-DL-SCH-Message ::= SEQUENCE {
+ message BCCH-DL-SCH-MessageType
+}
+
+BCCH-DL-SCH-MessageType ::= CHOICE {
+ c1 CHOICE {
+ systemInformation SystemInformation,
+ systemInformation1 SystemInformation1
+ },
+ messageClassExtension SEQUENCE {}
+}
+
+SystemInformation ::= SEQUENCE {
+ criticalExtensions CHOICE {
+ systemInformation-r8 SystemInformation-r8-IEs,
+ criticalExtensions SEQUENCE {}
+ }
+}
+
+maxSIB INTEGER ::= 1
+maxSI-Message INTEGER ::= 1
+
+SystemInformation-r8-IEs ::= SEQUENCE (SIZE (1..maxSIB)) OF SEQUENCE
+ { -- Size is FFS
+ sib-Type SIB-Type, -- FFS
+ sib-Info OCTET STRING, -- FFS
+ ...
+ }
+
+SIB-Type ::= ENUMERATED {
+ sibType1, -- FFS if SIB1 need explicit indication
+ sibType2, sibType3, sibType4, sibType5,
+ sibType6, sibType7, sibType8,
+ spare8, spare7, spare6, spare5,
+ spare4, spare3, spare2, spare1}
+
+
+SystemInformationMaster ::= MasterInformationBlock
+
+
+SystemInformation1 ::= SystemInformationBlockType1
+
+SystemInformationBlockType1 ::= SEQUENCE {
+ cellAccessRelatedInformation SEQUENCE {
+ plmn-IdentityList SEQUENCE (SIZE (1..6)) OF SEQUENCE {
+ plmn-Identity PLMN-Identity,
+ cellReservedForOperatorUse BOOLEAN
+ },
+ trackingAreaCode TrackingAreaCode,
+ cellIdentity CellIdentity,
+ cellBarred BOOLEAN,
+ intraFrequencyCellReselection BOOLEAN OPTIONAL, -- Cond CellBarred
+ cellReservationExtension BOOLEAN,
+ csg-Indication BOOLEAN
+ },
+ cellSelectionInfo SEQUENCE {
+ q-Rxlevmin INTEGER (-60..-28) -- value range FFS
+ }, -- need FFS
+ frequencyBandIndicator INTEGER (1..64),
+ schedulinInformation SEQUENCE (SIZE (1..maxSI-Message)) OF SEQUENCE {
+ si-MessageType SEQUENCE {}, -- FFS
+ si-Periodicity ENUMERATED {
+ ms80, ms160, ms320, ms640}, -- value range FFS
+ sib-MappingInfo SEQUENCE {} -- FFS
+ },
+ systemInformationValueTag INTEGER (0), -- value is 3..5 bits FFS
+ ...
+}
+
+PLMN-Identity ::= SEQUENCE {
+ -- Enter other IEs here.
+}
+TrackingAreaCode ::= SEQUENCE {
+ -- Enter other IEs here.
+}
+CellIdentity ::= SEQUENCE {
+ -- Enter the IEs here.
+}
+
+MasterInformationBlock ::= SEQUENCE {
+ dl-SystemBandwidth BIT STRING (SIZE (4)),
+ numberOfTransmitAntennas BIT STRING (SIZE (4)),
+ phich-Configuration PHICH-Configuration,
+ systemFrameNumber BIT STRING (SIZE (8))
+}
+
+PHICH-Configuration ::= SEQUENCE {
+ phich-Duration ENUMERATED {short, long},
+ phich-Resource ENUMERATED {ffs} -- 2-bit field FFS
+}
+
+
+
+END
diff --git a/lib/asn1/test/asn1_SUITE_data/Enum.py b/lib/asn1/test/asn1_SUITE_data/Enum.py
new file mode 100644
index 0000000000..3fb0ee3297
--- /dev/null
+++ b/lib/asn1/test/asn1_SUITE_data/Enum.py
@@ -0,0 +1,46 @@
+Enum DEFINITIONS IMPLICIT TAGS ::=
+BEGIN
+-- EXPORTS P1, P2;
+
+-- F.2.3.1
+-- Use an enumerated type to model the values of a variable
+-- with three or more states.
+-- Assign values starting with zero if their only
+-- constraint is distinctness.
+-- EXAMPLE
+
+DayOfTheWeek ::= ENUMERATED {sunday(0), monday(1), tuesday(2),
+ wednesday(3), thursday(4), friday(5), saturday(6)}
+
+firstDay DayOfTheWeek ::= sunday
+
+-- F.2.3.2
+-- Use an enumerated type to model the values of a variable that
+-- has just two states now,
+-- but that may have additional states in a future version of the protocol.
+-- EXAMPLE
+
+MaritalStatus ::= ENUMERATED {single(0), married(1)}
+
+-- in anticipation of
+
+MaritalStatus2 ::= ENUMERATED {single(0), married(1), widowed(2)}
+
+
+E1 ::= ENUMERATED {blue,green,yellow}
+
+E2 ::= ENUMERATED {monday(0),thuesday(1),wednesday(2),thursday(3),friday(4)}
+
+E3 ::= ENUMERATED {monday,thuesday(0)}
+
+S ::= SEQUENCE {
+ e1 ENUMERATED {hej,hopp},
+ e2 [2] EXPLICIT ENUMERATED {san,sa}
+ }
+
+enumVal E3 ::= monday
+--enumWrongVal E3 ::= sunday
+
+END
+
+
diff --git a/lib/asn1/test/asn1_SUITE_data/EnumExt.asn1 b/lib/asn1/test/asn1_SUITE_data/EnumExt.asn1
new file mode 100644
index 0000000000..9ad1f6299e
--- /dev/null
+++ b/lib/asn1/test/asn1_SUITE_data/EnumExt.asn1
@@ -0,0 +1,28 @@
+EnumExt DEFINITIONS AUTOMATIC TAGS ::=
+BEGIN
+
+Ext ::= ENUMERATED {
+ blue(0),
+ red(1),
+ green(2),
+ ...
+}
+
+Ext1 ::= ENUMERATED {
+ blue(0),
+ red(1),
+ green(2),
+ ...,
+ orange(7)
+}
+
+Noext ::= ENUMERATED {
+ blue(0),
+ red(1),
+ green(2)
+}
+
+Globalstate ::= ENUMERATED {def(1),com(2),preop(3),oper(4),noop(5),fail(6)}
+
+END
+
diff --git a/lib/asn1/test/asn1_SUITE_data/EnumerationBadExtension.asn1 b/lib/asn1/test/asn1_SUITE_data/EnumerationBadExtension.asn1
new file mode 100644
index 0000000000..471f92d7b6
--- /dev/null
+++ b/lib/asn1/test/asn1_SUITE_data/EnumerationBadExtension.asn1
@@ -0,0 +1,20 @@
+EnumerationBadExtension DEFINITIONS ::=
+BEGIN
+
+Enum1 ::= ENUMERATED {
+ first,
+ second}
+
+Enum2 ::= ENUMERATED {
+ first,
+ ...,
+ second}
+
+Enum3 ::= ENUMERATED {
+ first,
+ second,
+ ...}
+
+ENum3 ::= ENUMERATED {...,first,second}
+
+END
diff --git a/lib/asn1/test/asn1_SUITE_data/ErrorClass.asn b/lib/asn1/test/asn1_SUITE_data/ErrorClass.asn
new file mode 100644
index 0000000000..ab0f25ae4f
--- /dev/null
+++ b/lib/asn1/test/asn1_SUITE_data/ErrorClass.asn
@@ -0,0 +1,15 @@
+ErrorClass DEFINITIONS ::=
+BEGIN
+
+EXPORTS
+ERROR;
+
+
+ERROR ::= CLASS {
+ &errorCode INTEGER UNIQUE,
+ &ParameterType OPTIONAL
+ }
+
+END
+
+
diff --git a/lib/asn1/test/asn1_SUITE_data/Example.asn1 b/lib/asn1/test/asn1_SUITE_data/Example.asn1
new file mode 100644
index 0000000000..2639f63940
--- /dev/null
+++ b/lib/asn1/test/asn1_SUITE_data/Example.asn1
@@ -0,0 +1,20 @@
+Example DEFINITIONS ::=
+BEGIN
+
+T ::= Typ
+
+Typ ::= SEQUENCE {
+ a b,
+ c Typ}
+--ECLASS ::= CLASS {
+-- &num INTEGER UNIQUE,
+-- &Typo
+-- } WITH SYNTAX {
+-- &Typo DETERMINED BY &num
+-- }
+
+--v1 ECLASS ::= {INTEGER DETERMINED BY 12}
+
+--v2 INTEGER ::= 13
+
+END
diff --git a/lib/asn1/test/asn1_SUITE_data/Export1.asn b/lib/asn1/test/asn1_SUITE_data/Export1.asn
new file mode 100644
index 0000000000..78ead8f4d2
--- /dev/null
+++ b/lib/asn1/test/asn1_SUITE_data/Export1.asn
@@ -0,0 +1,7 @@
+Export1 DEFINITIONS ::=
+BEGIN
+EXPORTS T
+
+T ::= Typ
+
+END
diff --git a/lib/asn1/test/asn1_SUITE_data/Extension-Addition-Group.asn b/lib/asn1/test/asn1_SUITE_data/Extension-Addition-Group.asn
new file mode 100644
index 0000000000..fc244c30a2
--- /dev/null
+++ b/lib/asn1/test/asn1_SUITE_data/Extension-Addition-Group.asn
@@ -0,0 +1,82 @@
+--
+-- %CopyrightBegin%
+--
+-- Copyright Ericsson AB 2001-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%
+
+Extension-Addition-Group DEFINITIONS AUTOMATIC TAGS ::=
+
+BEGIN
+
+-- fetched from ITU-T Rec. X691 (07/2002)
+
+Ax ::= SEQUENCE {
+ a INTEGER (250..253),
+ b BOOLEAN,
+ c CHOICE {
+ d INTEGER,
+ ...,
+
+ [[
+ e BOOLEAN,
+ f IA5String
+ ]],
+ ...
+ },
+ ...,
+ [[
+ g NumericString (SIZE(3)),
+ h BOOLEAN OPTIONAL
+ ]]
+,
+ ...,
+ i BMPString OPTIONAL,
+ j PrintableString OPTIONAL
+
+}
+
+-- valAx Ax ::= { a 253, b TRUE, c e: TRUE, g "123", h TRUE }
+
+Ax2 ::= SEQUENCE {
+ a INTEGER (250..253),
+ b BOOLEAN,
+ ...,
+ ug NumericString
+
+}
+
+-- The value { a 253, b TRUE, c e: TRUE, g "123", h TRUE }
+-- is encoded in PER as
+-- Hexadecimal view
+-- 9E000180 010291A4
+
+-- is encoded in Unaligned PER as
+-- 9E000600 040A4690
+
+Ax3 ::= SEQUENCE {
+ a INTEGER (250..253),
+ b BOOLEAN,
+ s SEQUENCE {
+ sa INTEGER,
+ sb BOOLEAN,
+ ...,
+ [[
+ sextaddgroup INTEGER OPTIONAL
+ ]]
+ }
+}
+
+-- { a 253, b TRUE, s {sa 17, sb TRUE, sextaddgroup 11}}
+END
diff --git a/lib/asn1/test/asn1_SUITE_data/External.asn1 b/lib/asn1/test/asn1_SUITE_data/External.asn1
new file mode 100644
index 0000000000..07b2c6aced
--- /dev/null
+++ b/lib/asn1/test/asn1_SUITE_data/External.asn1
@@ -0,0 +1,132 @@
+External DEFINITIONS IMPLICIT TAGS ::=
+
+BEGIN
+
+XSeq1 ::= SEQUENCE
+{
+ bool1 BOOLEAN,
+ int1 INTEGER,
+ seq1 XSeqIn
+}
+
+XSeqIn ::= SEQUENCE
+{
+ boolIn BOOLEAN,
+ intIn INTEGER
+}
+
+XSet1 ::= SET
+{
+ bool1 BOOLEAN,
+ int1 INTEGER,
+ set1 XSetIn
+}
+
+XSetIn ::= SET
+{
+ boolIn BOOLEAN,
+ intIn INTEGER
+}
+
+XBool ::= BOOLEAN
+XBoolImp ::= [22] BOOLEAN
+XBoolExp ::= [23] EXPLICIT BOOLEAN
+
+XCho ::= CHOICE
+{
+ boolCho [44] BOOLEAN,
+ intCho [45] INTEGER
+}
+
+
+XSetExt1 ::= SET
+{
+ ...
+}
+
+XSetExt2 ::= SET
+{
+ bool BOOLEAN,
+ int INTEGER,
+ ...
+}
+
+-- XSetExt3 ::= SET
+-- {
+-- ...,
+-- bool BOOLEAN,
+-- int INTEGER
+-- }
+
+-- XSetExt4 ::= SET
+-- {
+-- bool BOOLEAN,
+-- ...,
+-- int INTEGER
+-- }
+
+
+XSeqExt1 ::= SEQUENCE
+{
+ ...
+}
+
+XSeqExt2 ::= SEQUENCE
+{
+ bool BOOLEAN,
+ int INTEGER,
+ ...
+}
+
+-- XSeqExt3 ::= SEQUENCE
+-- {
+-- ...,
+-- bool BOOLEAN,
+-- int INTEGER
+-- }
+
+-- XSeqExt4 ::= SEQUENCE
+-- {
+-- bool BOOLEAN,
+-- ...,
+-- int INTEGER
+-- }
+
+
+
+XNT ::= OCTET STRING
+XImp ::= [1] OCTET STRING
+XExp ::= [2] EXPLICIT OCTET STRING
+
+XChoNT ::= CHOICE {
+ os OCTET STRING,
+ bool BOOLEAN}
+XChoExp ::= [2] EXPLICIT CHOICE {
+ os OCTET STRING,
+ bool BOOLEAN}
+
+
+XSetNT ::= SET {
+ os OCTET STRING,
+ bool BOOLEAN}
+XSetImp ::= [1] SET {
+ os OCTET STRING,
+ bool BOOLEAN}
+XSetExp ::= [2] EXPLICIT SET {
+ os OCTET STRING,
+ bool BOOLEAN}
+
+
+XSeqNT ::= SEQUENCE {
+ os OCTET STRING,
+ bool BOOLEAN}
+XSeqImp ::= [1] SEQUENCE {
+ os OCTET STRING,
+ bool BOOLEAN}
+XSeqExp ::= [2] EXPLICIT SEQUENCE {
+ os OCTET STRING,
+ bool BOOLEAN}
+
+
+
+END
diff --git a/lib/asn1/test/asn1_SUITE_data/From.py b/lib/asn1/test/asn1_SUITE_data/From.py
new file mode 100644
index 0000000000..882d0b20be
--- /dev/null
+++ b/lib/asn1/test/asn1_SUITE_data/From.py
@@ -0,0 +1,15 @@
+From DEFINITIONS IMPLICIT TAGS ::=
+
+BEGIN
+
+AreaCode ::= SEQUENCE
+{
+
+ firstDigit IA5String
+ (FROM ( "2" | "3" ) ),
+ secondDigit IA5String
+ (FROM ( "3" | "4" ) )
+}
+
+END
+
diff --git a/lib/asn1/test/asn1_SUITE_data/H235-SECURITY-MESSAGES.asn b/lib/asn1/test/asn1_SUITE_data/H235-SECURITY-MESSAGES.asn
new file mode 100644
index 0000000000..3401f9599f
--- /dev/null
+++ b/lib/asn1/test/asn1_SUITE_data/H235-SECURITY-MESSAGES.asn
@@ -0,0 +1,170 @@
+H235-SECURITY-MESSAGES DEFINITIONS AUTOMATIC TAGS ::=
+BEGIN
+
+-- EXPORTS All
+
+ChallengeString ::= OCTET STRING (SIZE(8..128))
+TimeStamp ::= INTEGER(1..4294967295) -- seconds since 00:00 1/1/1970 UTC
+RandomVal ::= INTEGER
+Password ::= BMPString (SIZE (1..128))
+Identifier ::= BMPString (SIZE (1..128))
+KeyMaterial ::= BIT STRING(SIZE(1..2048))
+
+NonStandardParameter ::= SEQUENCE
+{
+ nonStandardIdentifier OBJECT IDENTIFIER,
+ data OCTET STRING
+}
+
+-- if local octet representations of these bit strings are used they shall
+-- utilize standard Network Octet ordering (e.g. Big Endian)
+DHset ::= SEQUENCE
+{
+ halfkey BIT STRING (SIZE(0..2048)), -- = g^x mod n
+ modSize BIT STRING (SIZE(0..2048)), -- n
+ generator BIT STRING (SIZE(0..2048)), -- g
+ ...
+}
+
+TypedCertificate ::= SEQUENCE
+{
+ type OBJECT IDENTIFIER,
+ certificate OCTET STRING,
+ ...
+}
+
+AuthenticationMechanism ::=CHOICE
+{
+ dhExch NULL, -- Diffe-Hellman
+ pwdSymEnc NULL, -- password with symmetric encryption
+ pwdHash NULL, -- password with hashing
+ certSign NULL, -- Certificate with signature
+ ipsec NULL, -- IPSEC based connection
+ tls NULL,
+ nonStandard NonStandardParameter, -- something else.
+ ...
+}
+
+ClearToken ::= SEQUENCE -- a `token' may contain multiple value types.
+{
+ timeStamp TimeStamp OPTIONAL,
+ password Password OPTIONAL,
+ dhkey DHset OPTIONAL,
+ challenge ChallengeString OPTIONAL,
+ random RandomVal OPTIONAL,
+ certificate TypedCertificate OPTIONAL,
+ generalID Identifier OPTIONAL,
+ nonStandard NonStandardParameter OPTIONAL,
+ ...
+}
+
+--
+-- Start all the cryptographic parameterized types here....
+--
+
+
+SIGNED { ToBeSigned } ::= SEQUENCE {
+ toBeSigned ToBeSigned,
+ algorithmOID OBJECT IDENTIFIER,
+ paramS Params, -- any 'runtime' parameters
+ signature BIT STRING
+} ( CONSTRAINED BY { -- Verify or Sign Certificate -- } )
+
+
+ENCRYPTED { ToBeEncrypted } ::= SEQUENCE {
+ algorithmOID OBJECT IDENTIFIER,
+ paramS Params, -- any 'runtime' parameters
+ encryptedData OCTET STRING
+} ( CONSTRAINED BY { -- Encrypt or Decrypt -- ToBeEncrypted } )
+
+HASHED { ToBeHashed } ::= SEQUENCE {
+ algorithmOID OBJECT IDENTIFIER,
+ paramS Params, -- any 'runtime' parameters
+ hash BIT STRING
+} ( CONSTRAINED BY { -- Hash -- ToBeHashed } )
+
+IV8 ::= OCTET STRING (SIZE(8))
+
+-- signing algorithm used must select one of these types of parameters
+-- needed by receiving end of signature.
+
+Params ::= SEQUENCE {
+ ranInt INTEGER OPTIONAL, -- some integer value
+ iv8 IV8 OPTIONAL, -- 8 octet initialization vector
+ ...
+}
+
+EncodedGeneralToken ::= TYPE-IDENTIFIER.&Type (ClearToken -- general usage token -- )
+PwdCertToken ::= ClearToken (WITH COMPONENTS {..., timeStamp PRESENT, generalID PRESENT})
+EncodedPwdCertToken ::= TYPE-IDENTIFIER.&Type (PwdCertToken)
+
+CryptoToken::= CHOICE
+{
+
+ cryptoEncryptedToken SEQUENCE -- General purpose/application specific token
+ {
+ tokenOID OBJECT IDENTIFIER,
+ token ENCRYPTED { EncodedGeneralToken }
+ },
+ cryptoSignedToken SEQUENCE -- General purpose/application specific token
+ {
+ tokenOID OBJECT IDENTIFIER,
+ token SIGNED { EncodedGeneralToken }
+ },
+ cryptoHashedToken SEQUENCE -- General purpose/application specific token
+ {
+ tokenOID OBJECT IDENTIFIER,
+ hashedVals ClearToken,
+ token HASHED { EncodedGeneralToken }
+ },
+ cryptoPwdEncr ENCRYPTED { EncodedPwdCertToken },
+ ...
+}
+
+-- These allow the passing of session keys within the H.245 OLC structure.
+-- They are encoded as standalone ASN.1 and based as an OCTET STRING within H.245
+H235Key ::=CHOICE -- this is used with the H.245 'h235Key' field
+{
+ secureChannel KeyMaterial,
+ sharedSecret ENCRYPTED {EncodedKeySyncMaterial},
+ certProtectedKey SIGNED { EncodedKeySignedMaterial },
+ ...
+}
+
+KeySignedMaterial ::= SEQUENCE {
+ generalId Identifier, -- slave's alias
+ mrandom RandomVal, -- master's random value
+ srandom RandomVal OPTIONAL, -- slave's random value
+ timeStamp TimeStamp OPTIONAL, -- master's timestamp for unsolicted EU
+ encrptval ENCRYPTED {EncodedKeySyncMaterial }
+}
+EncodedKeySignedMaterial ::= TYPE-IDENTIFIER.&Type (KeySignedMaterial)
+
+KeySyncMaterial ::=SEQUENCE
+{
+ generalID Identifier,
+ keyMaterial KeyMaterial,
+ ...
+}
+EncodedKeySyncMaterial ::=TYPE-IDENTIFIER.&Type (KeySyncMaterial)
+
+H235CertificateSignature ::=SEQUENCE
+{
+ certificate TypedCertificate,
+ responseRandom RandomVal,
+ requesterRandom RandomVal OPTIONAL,
+ signature SIGNED { EncodedReturnSig },
+ ...
+}
+
+ReturnSig ::= SEQUENCE {
+ generalId Identifier, -- slave's alias
+ responseRandom RandomVal,
+ requestRandom RandomVal OPTIONAL,
+ certificate TypedCertificate OPTIONAL -- requested certificate
+}
+
+EncodedReturnSig ::= TYPE-IDENTIFIER.&Type (ReturnSig)
+
+
+END -- End of H235-SECURITY-MESSAGES DEFINITIONS
diff --git a/lib/asn1/test/asn1_SUITE_data/H323-MESSAGES.asn b/lib/asn1/test/asn1_SUITE_data/H323-MESSAGES.asn
new file mode 100644
index 0000000000..ba6802f122
--- /dev/null
+++ b/lib/asn1/test/asn1_SUITE_data/H323-MESSAGES.asn
@@ -0,0 +1,1341 @@
+H323-MESSAGES DEFINITIONS AUTOMATIC TAGS ::=
+BEGIN
+
+
+IMPORTS
+ SIGNED{},
+ ENCRYPTED{},
+ HASHED{},
+ ChallengeString,
+ TimeStamp,
+ RandomVal,
+ Password,
+ EncodedPwdCertToken,
+ ClearToken,
+ CryptoToken,
+ AuthenticationMechanism
+ FROM H235-SECURITY-MESSAGES;
+
+H323-UserInformation ::= SEQUENCE -- root for all Q.931 related ASN.1
+{
+ h323-uu-pdu H323-UU-PDU,
+ user-data SEQUENCE
+ {
+ protocol-discriminator INTEGER (0..255),
+ user-information OCTET STRING (SIZE(1..131)),
+ ...
+ } OPTIONAL,
+ ...
+}
+
+H323-UU-PDU ::= SEQUENCE
+{
+ h323-message-body CHOICE
+ {
+ setup Setup-UUIE,
+ callProceeding CallProceeding-UUIE,
+ connect Connect-UUIE,
+ alerting Alerting-UUIE,
+ userInformation UI-UUIE,
+ releaseComplete ReleaseComplete-UUIE,
+ facility Facility-UUIE,
+ ...,
+ progress Progress-UUIE,
+ empty NULL -- used when a FACILITY message is sent,
+-- but the Facility-UUIE is not to be invoked
+-- (possible when transporting supplementary
+-- services messages)
+ },
+ nonStandardData NonStandardParameter OPTIONAL,
+ ...,
+ h4501SupplementaryService SEQUENCE OF OCTET STRING OPTIONAL,
+ -- each sequence of octet string is defined as one
+ -- H4501SupplementaryService APDU as defined in
+ -- Table 3/H.450.1
+ h245Tunneling BOOLEAN,
+ -- if TRUE, tunneling of H.245 messages is enabled
+ h245Control SEQUENCE OF OCTET STRING OPTIONAL,
+ -- each octet string may contain exactly
+ -- one H.245 PDU
+ nonStandardControl SEQUENCE OF NonStandardParameter OPTIONAL
+}
+
+Alerting-UUIE ::= SEQUENCE
+{
+ protocolIdentifier ProtocolIdentifier,
+ destinationInfo EndpointType,
+ h245Address TransportAddress OPTIONAL,
+ ...,
+ callIdentifier CallIdentifier,
+ h245SecurityMode H245Security OPTIONAL,
+ tokens SEQUENCE OF ClearToken OPTIONAL,
+ cryptoTokens SEQUENCE OF CryptoH323Token OPTIONAL,
+ fastStart SEQUENCE OF OCTET STRING OPTIONAL
+}
+
+CallProceeding-UUIE ::= SEQUENCE
+{
+ protocolIdentifier ProtocolIdentifier,
+ destinationInfo EndpointType,
+ h245Address TransportAddress OPTIONAL,
+ ...,
+ callIdentifier CallIdentifier,
+ h245SecurityMode H245Security OPTIONAL,
+ tokens SEQUENCE OF ClearToken OPTIONAL,
+ cryptoTokens SEQUENCE OF CryptoH323Token OPTIONAL,
+ fastStart SEQUENCE OF OCTET STRING OPTIONAL
+}
+
+Connect-UUIE ::= SEQUENCE
+{
+ protocolIdentifier ProtocolIdentifier,
+ h245Address TransportAddress OPTIONAL,
+ destinationInfo EndpointType,
+ conferenceID ConferenceIdentifier,
+ ...,
+ callIdentifier CallIdentifier,
+ h245SecurityMode H245Security OPTIONAL,
+ tokens SEQUENCE OF ClearToken OPTIONAL,
+ cryptoTokens SEQUENCE OF CryptoH323Token OPTIONAL,
+ fastStart SEQUENCE OF OCTET STRING OPTIONAL
+}
+
+UI-UUIE ::=SEQUENCE
+{
+ protocolIdentifier ProtocolIdentifier,
+ ...,
+ callIdentifier CallIdentifier
+}
+
+ReleaseComplete-UUIE ::= SEQUENCE
+{
+ protocolIdentifier ProtocolIdentifier,
+ reason ReleaseCompleteReason OPTIONAL,
+ ...,
+ callIdentifier CallIdentifier
+}
+
+ReleaseCompleteReason ::= CHOICE
+{
+ noBandwidth NULL, -- bandwidth taken away or ARQ denied
+ gatekeeperResources NULL, -- exhausted
+ unreachableDestination NULL, -- no transport path to the destination
+ destinationRejection NULL, -- rejected at destination
+ invalidRevision NULL,
+ noPermission NULL, -- called party's gatekeeper rejects
+ unreachableGatekeeper NULL, -- terminal cannot reach gatekeeper for ARQ
+ gatewayResources NULL,
+ badFormatAddress NULL,
+ adaptiveBusy NULL, -- call is dropping due to LAN crowding
+ inConf NULL, -- no address in AlternativeAddress
+ undefinedReason NULL,
+ ...,
+ facilityCallDeflection NULL, -- call was deflected using a Facility message
+ securityDenied NULL, -- incompatible security settings
+ calledPartyNotRegistered NULL, -- used by gatekeeper when endpoint has
+ -- preGrantedARQ to bypass ARQ/ACF
+ callerNotregistered NULL -- used by gatekeeper when endpoint has
+ -- preGrantedArq to bypass ARQ/ACF
+}
+
+Setup-UUIE ::= SEQUENCE
+{
+ protocolIdentifier ProtocolIdentifier,
+ h245Address TransportAddress OPTIONAL,
+ sourceAddress SEQUENCE OF AliasAddress OPTIONAL,
+ sourceInfo EndpointType,
+ destinationAddress SEQUENCE OF AliasAddress OPTIONAL,
+ destCallSignalAddress TransportAddress OPTIONAL,
+ destExtraCallInfo SEQUENCE OF AliasAddress OPTIONAL, -- Note(1)
+ destExtraCRV SEQUENCE OF CallReferenceValue OPTIONAL,-- Note(1)
+ activeMC BOOLEAN,
+ conferenceID ConferenceIdentifier,
+ conferenceGoal CHOICE
+ {
+ create NULL,
+ join NULL,
+ invite NULL,
+ ...,
+ capability-negotiation NULL,
+ callIndependentSupplementaryService NULL
+ },
+ callServices QseriesOptions OPTIONAL,
+ callType CallType,
+ ...,
+ sourceCallSignalAddress TransportAddress OPTIONAL,
+ remoteExtensionAddress AliasAddress OPTIONAL,
+ callIdentifier CallIdentifier,
+ h245SecurityCapability SEQUENCE OF H245Security OPTIONAL,
+ tokens SEQUENCE OF ClearToken OPTIONAL,
+ cryptoTokens SEQUENCE OF CryptoH323Token OPTIONAL,
+ fastStart SEQUENCE OF OCTET STRING OPTIONAL,
+ mediaWaitForConnect BOOLEAN,
+ canOverlapSend BOOLEAN
+}
+
+Facility-UUIE ::= SEQUENCE
+{
+ protocolIdentifier ProtocolIdentifier,
+ alternativeAddress TransportAddress OPTIONAL,
+ alternativeAliasAddress SEQUENCE OF AliasAddress OPTIONAL,
+ conferenceID ConferenceIdentifier OPTIONAL,
+ reason FacilityReason,
+ ...,
+ callIdentifier CallIdentifier,
+ destExtraCallInfo SEQUENCE OF AliasAddress OPTIONAL,
+ remoteExtensionAddress AliasAddress OPTIONAL,
+ tokens SEQUENCE OF ClearToken OPTIONAL,
+ cryptoTokens SEQUENCE OF CryptoH323Token OPTIONAL,
+ conferences SEQUENCE OF ConferenceList OPTIONAL,
+ h245Address TransportAddress OPTIONAL
+}
+
+ConferenceList ::= SEQUENCE
+{
+ conferenceID ConferenceIdentifier OPTIONAL,
+ conferenceAlias AliasAddress OPTIONAL,
+ nonStandardData NonStandardParameter OPTIONAL,
+ ...
+}
+
+FacilityReason ::= CHOICE
+{
+ routeCallToGatekeeper NULL, -- call must use gatekeeper model
+ -- gatekeeper is alternativeAddress
+ callForwarded NULL,
+ routeCallToMC NULL,
+ undefinedReason NULL,
+ ...,
+ conferenceListChoice NULL,
+ startH245 NULL -- recipient should connect to h245Address
+}
+
+Progress-UUIE ::= SEQUENCE
+{
+ protocolIdentifier ProtocolIdentifier,
+ destinationInfo EndpointType,
+ h245Address TransportAddress OPTIONAL,
+ callIdentifier CallIdentifier,
+ h245SecurityMode H245Security OPTIONAL,
+ ...,
+ tokens SEQUENCE OF ClearToken OPTIONAL,
+ cryptoTokens SEQUENCE OF CryptoH323Token OPTIONAL,
+ fastStart SEQUENCE OF OCTET STRING OPTIONAL
+}
+
+TransportAddress ::= CHOICE
+{
+ ipAddress SEQUENCE
+ {
+ ip OCTET STRING (SIZE(4)),
+ port INTEGER(0..65535)
+ },
+ ipSourceRoute SEQUENCE
+ {
+ ip OCTET STRING (SIZE(4)),
+ port INTEGER(0..65535),
+ route SEQUENCE OF OCTET STRING(SIZE(4)),
+ routing CHOICE
+ {
+ strict NULL,
+ loose NULL,
+ ...
+ },
+ ...
+ },
+ ipxAddress SEQUENCE
+ {
+ node OCTET STRING (SIZE(6)),
+ netnum OCTET STRING (SIZE(4)),
+ port OCTET STRING (SIZE(2))
+ },
+ ip6Address SEQUENCE
+ {
+ ip OCTET STRING (SIZE(16)),
+ port INTEGER(0..65535),
+ ...
+ },
+ netBios OCTET STRING (SIZE(16)),
+ nsap OCTET STRING (SIZE(1..20)),
+ nonStandardAddress NonStandardParameter,
+ ...
+}
+
+EndpointType ::= SEQUENCE
+{
+ nonStandardData NonStandardParameter OPTIONAL,
+ vendor VendorIdentifier OPTIONAL,
+ gatekeeper GatekeeperInfo OPTIONAL,
+ gateway GatewayInfo OPTIONAL,
+ mcu McuInfo OPTIONAL, -- mc must be set as well
+ terminal TerminalInfo OPTIONAL,
+ mc BOOLEAN, -- shall not be set by itself
+ undefinedNode BOOLEAN,
+ ...
+}
+
+GatewayInfo ::= SEQUENCE
+{
+ protocol SEQUENCE OF SupportedProtocols OPTIONAL,
+ nonStandardData NonStandardParameter OPTIONAL,
+ ...
+}
+
+SupportedProtocols ::= CHOICE
+{
+ nonStandardData NonStandardParameter,
+ h310 H310Caps,
+ h320 H320Caps,
+ h321 H321Caps,
+ h322 H322Caps,
+ h323 H323Caps,
+ h324 H324Caps,
+ voice VoiceCaps,
+ t120-only T120OnlyCaps,
+ ...,
+ nonStandardProtocol NonStandardProtocol
+}
+
+H310Caps ::= SEQUENCE
+{
+ nonStandardData NonStandardParameter OPTIONAL,
+ ...,
+ dataRatesSupported SEQUENCE OF DataRate OPTIONAL,
+ supportedPrefixes SEQUENCE OF SupportedPrefix
+}
+
+H320Caps ::= SEQUENCE
+{
+ nonStandardData NonStandardParameter OPTIONAL,
+ ...,
+ dataRatesSupported SEQUENCE OF DataRate OPTIONAL,
+ supportedPrefixes SEQUENCE OF SupportedPrefix
+}
+
+H321Caps ::= SEQUENCE
+{
+ nonStandardData NonStandardParameter OPTIONAL,
+ ...,
+ dataRatesSupported SEQUENCE OF DataRate OPTIONAL,
+ supportedPrefixes SEQUENCE OF SupportedPrefix
+}
+
+H322Caps ::= SEQUENCE
+{
+ nonStandardData NonStandardParameter OPTIONAL,
+ ...,
+ dataRatesSupported SEQUENCE OF DataRate OPTIONAL,
+ supportedPrefixes SEQUENCE OF SupportedPrefix
+}
+
+H323Caps ::= SEQUENCE
+{
+ nonStandardData NonStandardParameter OPTIONAL,
+ ...,
+ dataRatesSupported SEQUENCE OF DataRate OPTIONAL,
+ supportedPrefixes SEQUENCE OF SupportedPrefix
+}
+
+H324Caps ::= SEQUENCE
+{
+ nonStandardData NonStandardParameter OPTIONAL,
+ ...,
+ dataRatesSupported SEQUENCE OF DataRate OPTIONAL,
+ supportedPrefixes SEQUENCE OF SupportedPrefix
+}
+
+VoiceCaps ::= SEQUENCE
+{
+ nonStandardData NonStandardParameter OPTIONAL,
+ ...,
+ dataRatesSupported SEQUENCE OF DataRate OPTIONAL,
+ supportedPrefixes SEQUENCE OF SupportedPrefix
+}
+
+T120OnlyCaps ::= SEQUENCE
+{
+ nonStandardData NonStandardParameter OPTIONAL,
+ ...,
+ dataRatesSupported SEQUENCE OF DataRate OPTIONAL,
+ supportedPrefixes SEQUENCE OF SupportedPrefix
+}
+
+NonStandardProtocol ::= SEQUENCE
+{
+ nonStandardData NonStandardParameter OPTIONAL,
+ dataRatesSupported SEQUENCE OF DataRate OPTIONAL,
+ supportedPrefixes SEQUENCE OF SupportedPrefix,
+ ...
+}
+
+McuInfo ::=SEQUENCE
+{
+ nonStandardData NonStandardParameter OPTIONAL,
+ ...
+}
+
+TerminalInfo ::=SEQUENCE
+{
+ nonStandardData NonStandardParameter OPTIONAL,
+ ...
+}
+
+GatekeeperInfo ::=SEQUENCE
+{
+ nonStandardData NonStandardParameter OPTIONAL,
+ ...
+}
+
+VendorIdentifier ::= SEQUENCE
+{
+ vendor H221NonStandard,
+ productId OCTET STRING (SIZE(1..256)) OPTIONAL, -- per vendor
+ versionId OCTET STRING (SIZE(1..256)) OPTIONAL, -- per product
+ ...
+}
+
+H221NonStandard ::= SEQUENCE
+{ t35CountryCode INTEGER(0..255), -- country, as per T.35
+ t35Extension INTEGER(0..255), -- assigned nationally
+ manufacturerCode INTEGER(0..65535), -- assigned nationally
+ ...
+}
+
+NonStandardParameter ::= SEQUENCE
+{
+ nonStandardIdentifier NonStandardIdentifier,
+ data OCTET STRING
+}
+
+NonStandardIdentifier ::=CHOICE
+{
+ object OBJECT IDENTIFIER,
+ h221NonStandard H221NonStandard,
+ ...
+}
+
+AliasAddress ::= CHOICE
+{
+ e164 IA5String (SIZE (1..128)) (FROM ("0123456789#*,")),
+ h323-ID BMPString (SIZE (1..256)), -- Basic ISO/IEC 10646-1 (Unicode)
+ ...,
+ url-ID IA5String (SIZE(1..512)), -- URL style address
+ transportID TransportAddress,
+ email-ID IA5String (SIZE(1..512)), -- rfc822-compliant email address
+ partyNumber PartyNumber
+}
+
+PartyNumber ::= CHOICE
+{
+ publicNumber PublicPartyNumber,
+ -- the numbering plan is according to
+ -- Recommendations E.163 and E.164.
+ dataPartyNumber NumberDigits,
+ -- not used, value reserved.
+ telexPartyNumber NumberDigits,
+ -- not used, value reserved.
+ privateNumber PrivatePartyNumber,
+ nationalStandardPartyNumber NumberDigits,
+ -- not used, value reserved.
+ ...
+}
+
+PublicPartyNumber ::= SEQUENCE
+{
+ publicTypeOfNumber PublicTypeOfNumber,
+ publicNumberDigits NumberDigits
+}
+
+PrivatePartyNumber ::= SEQUENCE
+{
+ privateTypeOfNumber PrivateTypeOfNumber,
+ privateNumberDigits NumberDigits
+}
+
+NumberDigits ::= IA5String (SIZE (1..128)) (FROM ("0123456789#*,"))
+
+PublicTypeOfNumber ::= CHOICE
+{
+ unknown NULL,
+ -- if used number digits carry prefix indicating type
+ -- of number according to national recommendations.
+ internationalNumber NULL,
+ nationalNumber NULL,
+ networkSpecificNumber NULL,
+ -- not used, value reserved
+ subscriberNumber NULL,
+ abbreviatedNumber NULL,
+ -- valid only for called party number at the outgoing
+ -- access, network substitutes appropriate number.
+...
+}
+
+PrivateTypeOfNumber ::= CHOICE
+{
+ unknown NULL,
+ level2RegionalNumber NULL,
+ level1RegionalNumber NULL,
+ pISNSpecificNumber NULL,
+ localNumber NULL,
+ abbreviatedNumber NULL,
+ ...
+}
+
+Endpoint ::= SEQUENCE
+{
+ nonStandardData NonStandardParameter OPTIONAL,
+ aliasAddress SEQUENCE OF AliasAddress OPTIONAL,
+ callSignalAddress SEQUENCE OF TransportAddress OPTIONAL,
+ rasAddress SEQUENCE OF TransportAddress OPTIONAL,
+ endpointType EndpointType OPTIONAL,
+ tokens SEQUENCE OF ClearToken OPTIONAL,
+ cryptoTokens SEQUENCE OF CryptoH323Token OPTIONAL,
+ priority INTEGER(0..127) OPTIONAL,
+ remoteExtensionAddress SEQUENCE OF AliasAddress OPTIONAL,
+ destExtraCallInfo SEQUENCE OF AliasAddress OPTIONAL,
+ ...
+}
+
+AlternateGK ::= SEQUENCE
+{
+ rasAddress TransportAddress,
+ gatekeeperIdentifier GatekeeperIdentifier OPTIONAL,
+ needToRegister BOOLEAN,
+ priority INTEGER (0..127),
+ ...
+}
+
+AltGKInfo ::= SEQUENCE
+{
+ alternateGatekeeper SEQUENCE OF AlternateGK,
+ altGKisPermanent BOOLEAN,
+ ...
+}
+
+SecurityServiceMode ::= CHOICE
+{
+nonStandard NonStandardParameter,
+none NULL,
+default NULL,
+... -- can be extended with other specific modes
+}
+
+SecurityCapabilities ::= SEQUENCE
+{
+ nonStandard NonStandardParameter OPTIONAL,
+ encryption SecurityServiceMode,
+ authenticaton SecurityServiceMode,
+ integrity SecurityServiceMode,
+...
+}
+
+H245Security ::= CHOICE
+{
+ nonStandard NonStandardParameter,
+ noSecurity NULL,
+ tls SecurityCapabilities,
+ ipsec SecurityCapabilities,
+ ...
+}
+
+QseriesOptions ::= SEQUENCE
+{
+ q932Full BOOLEAN, -- if true, indicates full support for Q.932
+ q951Full BOOLEAN, -- if true, indicates full support for Q.951
+ q952Full BOOLEAN, -- if true, indicates full support for Q.952
+ q953Full BOOLEAN, -- if true, indicates full support for Q.953
+ q955Full BOOLEAN, -- if true, indicates full support for Q.955
+ q956Full BOOLEAN, -- if true, indicates full support for Q.956
+ q957Full BOOLEAN, -- if true, indicates full support for Q.957
+ q954Info Q954Details,
+ ...
+}
+
+Q954Details ::= SEQUENCE
+{
+ conferenceCalling BOOLEAN,
+ threePartyService BOOLEAN,
+ ...
+}
+
+GloballyUniqueID ::= OCTET STRING (SIZE(16))
+ConferenceIdentifier ::= GloballyUniqueID
+RequestSeqNum ::= INTEGER (1..65535)
+GatekeeperIdentifier ::= BMPString (SIZE(1..128))
+BandWidth ::= INTEGER (0.. 4294967295) -- in 100s of bits
+CallReferenceValue ::= INTEGER (0..65535)
+EndpointIdentifier ::= BMPString (SIZE(1..128))
+ProtocolIdentifier ::= OBJECT IDENTIFIER
+ -- shall be set to
+ -- {itu-t (0) recommendation (0) h (8) 2250 version (0) 2}
+TimeToLive ::= INTEGER (1..4294967295) --in seconds
+
+CallIdentifier ::= SEQUENCE
+{
+ guid GloballyUniqueID,
+ ...
+}
+
+
+EncryptIntAlg ::= CHOICE
+{ -- core encryption algorithms for RAS message integrity
+ nonStandard NonStandardParameter,
+ isoAlgorithm OBJECT IDENTIFIER, -- defined in ISO/IEC 9979
+ ...
+}
+NonIsoIntegrityMechanism ::= CHOICE
+{ -- HMAC mechanism used, no truncation, tagging may be necessary!
+ hMAC-MD5 NULL,
+ hMAC-iso10118-2-s EncryptIntAlg, -- according to ISO/IEC 10118-2 using
+ -- EncryptIntAlg as core block encryption algorithm
+ -- (short MAC)
+ hMAC-iso10118-2-l EncryptIntAlg, -- according to ISO/IEC 10118-2 using
+ -- EncryptIntAlg as core block encryption algorithm
+ -- (long MAC)
+ hMAC-iso10118-3 OBJECT IDENTIFIER, -- according to ISO/IEC 10118-3 using
+ -- OID as hash function (OID is SHA-1, RIPE-MD160,
+ -- RIPE-MD128)
+ ...
+}
+
+IntegrityMechanism ::= CHOICE
+{ -- for RAS message integrity
+ nonStandard NonStandardParameter,
+ digSig NULL, -- indicates to apply a digital signature
+ iso9797 OBJECT IDENTIFIER, -- according to ISO/IEC 9797 using OID as
+ -- core encryption algorithm (X-CBC MAC)
+ nonIsoIM NonIsoIntegrityMechanism,
+ ...
+}
+
+ICV ::= SEQUENCE
+{
+ algorithmOID OBJECT IDENTIFIER, -- the algorithm used to compute the signature
+ icv BIT STRING -- the computed cryptographic integrity check value
+-- or signature
+}
+
+FastStartToken ::= ClearToken (WITH COMPONENTS {..., timeStamp, dhkey, generalID -- set to 'alias' -- })
+EncodedFastStartToken ::= TYPE-IDENTIFIER.&Type (FastStartToken)
+CryptoH323Token::= CHOICE
+{
+ cryptoEPPwdHash SEQUENCE
+{
+ alias AliasAddress, -- alias of entity generating hash
+ timeStamp TimeStamp, -- timestamp used in hash
+token HASHED { EncodedPwdCertToken -- generalID set to 'alias' -- }
+ },
+ cryptoGKPwdHash SEQUENCE
+{
+gatekeeperId GatekeeperIdentifier, -- GatekeeperID of GK generating hash
+ timeStamp TimeStamp, -- timestamp used in hash
+token HASHED { EncodedPwdCertToken -- generalID set to Gatekeeperid -- }
+ },
+ cryptoEPPwdEncr ENCRYPTED
+{ EncodedPwdCertToken -- generalID set to Gatekeeperid --},
+ cryptoGKPwdEncr ENCRYPTED
+{ EncodedPwdCertToken -- generalID set to Gatekeeperid --},
+ cryptoEPCert SIGNED { EncodedPwdCertToken -- generalID set to Gatekeeperid -- },
+ cryptoGKCert SIGNED { EncodedPwdCertToken -- generalID set to alias -- },
+ cryptoFastStart SIGNED { EncodedFastStartToken },
+ nestedcryptoToken CryptoH323Token,
+ ...
+}
+
+
+DataRate ::= SEQUENCE
+{
+ nonStandardData NonStandardParameter OPTIONAL,
+ channelRate BandWidth,
+ channelMultiplier INTEGER (1..256) OPTIONAL,
+ ...
+}
+
+SupportedPrefix ::= SEQUENCE
+{
+ nonStandardData NonStandardParameter OPTIONAL,
+ prefix AliasAddress,
+ ...
+}
+
+
+RasMessage ::= CHOICE
+{
+ gatekeeperRequest GatekeeperRequest,
+ gatekeeperConfirm GatekeeperConfirm,
+ gatekeeperReject GatekeeperReject,
+ registrationRequest RegistrationRequest,
+ registrationConfirm RegistrationConfirm,
+ registrationReject RegistrationReject,
+ unregistrationRequest UnregistrationRequest,
+ unregistrationConfirm UnregistrationConfirm,
+ unregistrationReject UnregistrationReject,
+ admissionRequest AdmissionRequest,
+ admissionConfirm AdmissionConfirm,
+ admissionReject AdmissionReject,
+ bandwidthRequest BandwidthRequest,
+ bandwidthConfirm BandwidthConfirm,
+ bandwidthReject BandwidthReject,
+ disengageRequest DisengageRequest,
+ disengageConfirm DisengageConfirm,
+ disengageReject DisengageReject,
+ locationRequest LocationRequest,
+ locationConfirm LocationConfirm,
+ locationReject LocationReject,
+ infoRequest InfoRequest,
+ infoRequestResponse InfoRequestResponse,
+ nonStandardMessage NonStandardMessage,
+ unknownMessageResponse UnknownMessageResponse,
+ ...,
+ requestInProgress RequestInProgress,
+ resourcesAvailableIndicate ResourcesAvailableIndicate,
+ resourcesAvailableConfirm ResourcesAvailableConfirm,
+ infoRequestAck InfoRequestAck,
+ infoRequestNak InfoRequestNak
+}
+
+GatekeeperRequest ::= SEQUENCE --(GRQ)
+{
+
+ requestSeqNum RequestSeqNum,
+ protocolIdentifier ProtocolIdentifier,
+ nonStandardData NonStandardParameter OPTIONAL,
+ rasAddress TransportAddress,
+ endpointType EndpointType,
+ gatekeeperIdentifier GatekeeperIdentifier OPTIONAL,
+ callServices QseriesOptions OPTIONAL,
+ endpointAlias SEQUENCE OF AliasAddress OPTIONAL,
+ ...,
+ alternateEndpoints SEQUENCE OF Endpoint OPTIONAL,
+ tokens SEQUENCE OF ClearToken OPTIONAL,
+ cryptoTokens SEQUENCE OF CryptoH323Token OPTIONAL,
+ authenticationCapability SEQUENCE OF AuthenticationMechanism OPTIONAL,
+ algorithmOIDs SEQUENCE OF OBJECT IDENTIFIER OPTIONAL,
+ integrity SEQUENCE OF IntegrityMechanism OPTIONAL,
+ integrityCheckValue ICV OPTIONAL
+}
+
+GatekeeperConfirm ::= SEQUENCE --(GCF)
+{
+ requestSeqNum RequestSeqNum,
+ protocolIdentifier ProtocolIdentifier,
+ nonStandardData NonStandardParameter OPTIONAL,
+ gatekeeperIdentifier GatekeeperIdentifier OPTIONAL,
+ rasAddress TransportAddress,
+ ...,
+ alternateGatekeeper SEQUENCE OF AlternateGK OPTIONAL,
+ authenticationMode AuthenticationMechanism OPTIONAL,
+ tokens SEQUENCE OF ClearToken OPTIONAL,
+ cryptoTokens SEQUENCE OF CryptoH323Token OPTIONAL,
+ algorithmOID OBJECT IDENTIFIER OPTIONAL,
+ integrity SEQUENCE OF IntegrityMechanism OPTIONAL,
+ integrityCheckValue ICV OPTIONAL
+}
+
+GatekeeperReject ::= SEQUENCE --(GRJ)
+{
+ requestSeqNum RequestSeqNum,
+ protocolIdentifier ProtocolIdentifier,
+ nonStandardData NonStandardParameter OPTIONAL,
+ gatekeeperIdentifier GatekeeperIdentifier OPTIONAL,
+ rejectReason GatekeeperRejectReason,
+ ...,
+ altGKInfo AltGKInfo OPTIONAL,
+ tokens SEQUENCE OF ClearToken OPTIONAL,
+ cryptoTokens SEQUENCE OF CryptoH323Token OPTIONAL,
+ integrityCheckValue ICV OPTIONAL
+}
+
+GatekeeperRejectReason ::= CHOICE
+{
+ resourceUnavailable NULL,
+ terminalExcluded NULL, -- permission failure, not a resource failure
+ invalidRevision NULL,
+ undefinedReason NULL,
+ ...,
+ securityDenial NULL
+}
+
+RegistrationRequest ::= SEQUENCE --(RRQ)
+{
+ requestSeqNum RequestSeqNum,
+ protocolIdentifier ProtocolIdentifier,
+ nonStandardData NonStandardParameter OPTIONAL,
+ discoveryComplete BOOLEAN,
+ callSignalAddress SEQUENCE OF TransportAddress,
+ rasAddress SEQUENCE OF TransportAddress,
+ terminalType EndpointType,
+ terminalAlias SEQUENCE OF AliasAddress OPTIONAL,
+ gatekeeperIdentifier GatekeeperIdentifier OPTIONAL,
+ endpointVendor VendorIdentifier,
+ ...,
+ alternateEndpoints SEQUENCE OF Endpoint OPTIONAL,
+ timeToLive TimeToLive OPTIONAL,
+ tokens SEQUENCE OF ClearToken OPTIONAL,
+ cryptoTokens SEQUENCE OF CryptoH323Token OPTIONAL,
+ integrityCheckValue ICV OPTIONAL,
+ keepAlive BOOLEAN,
+ endpointIdentifier EndpointIdentifier OPTIONAL,
+ willSupplyUUIEs BOOLEAN
+}
+
+RegistrationConfirm ::= SEQUENCE --(RCF)
+{
+ requestSeqNum RequestSeqNum,
+ protocolIdentifier ProtocolIdentifier,
+ nonStandardData NonStandardParameter OPTIONAL,
+ callSignalAddress SEQUENCE OF TransportAddress,
+ terminalAlias SEQUENCE OF AliasAddress OPTIONAL,
+ gatekeeperIdentifier GatekeeperIdentifier OPTIONAL,
+ endpointIdentifier EndpointIdentifier,
+ ...,
+ alternateGatekeeper SEQUENCE OF AlternateGK OPTIONAL,
+ timeToLive TimeToLive OPTIONAL,
+ tokens SEQUENCE OF ClearToken OPTIONAL,
+ cryptoTokens SEQUENCE OF CryptoH323Token OPTIONAL,
+ integrityCheckValue ICV OPTIONAL,
+ willRespondToIRR BOOLEAN,
+ preGrantedARQ SEQUENCE
+ {
+ makeCall BOOLEAN,
+ useGKCallSignalAddressToMakeCall BOOLEAN,
+ answerCall BOOLEAN,
+ useGKCallSignalAddressToAnswer BOOLEAN,
+ ...
+ } OPTIONAL
+}
+
+RegistrationReject ::= SEQUENCE --(RRJ)
+{
+ requestSeqNum RequestSeqNum,
+ protocolIdentifier ProtocolIdentifier,
+ nonStandardData NonStandardParameter OPTIONAL,
+ rejectReason RegistrationRejectReason,
+ gatekeeperIdentifier GatekeeperIdentifier OPTIONAL,
+ ...,
+ altGKInfo AltGKInfo OPTIONAL,
+ tokens SEQUENCE OF ClearToken OPTIONAL,
+ cryptoTokens SEQUENCE OF CryptoH323Token OPTIONAL,
+ integrityCheckValue ICV OPTIONAL
+}
+
+RegistrationRejectReason ::= CHOICE
+{
+ discoveryRequired NULL, -- registration permission has aged
+ invalidRevision NULL,
+ invalidCallSignalAddress NULL,
+ invalidRASAddress NULL, -- supplied address is invalid
+ duplicateAlias SEQUENCE OF AliasAddress,
+ -- alias registered to another endpoint
+ invalidTerminalType NULL,
+ undefinedReason NULL,
+ transportNotSupported NULL, -- one or more of the transports
+ ...,
+ transportQOSNotSupported NULL, -- endpoint QoS not supported
+ resourceUnavailable NULL, -- gatekeeper resources exhausted
+ invalidAlias NULL, -- alias not consistent with gatekeeper rules
+ securityDenial NULL
+}
+
+UnregistrationRequest ::= SEQUENCE --(URQ)
+{
+ requestSeqNum RequestSeqNum,
+ callSignalAddress SEQUENCE OF TransportAddress,
+ endpointAlias SEQUENCE OF AliasAddress OPTIONAL,
+ nonStandardData NonStandardParameter OPTIONAL,
+ endpointIdentifier EndpointIdentifier OPTIONAL,
+ ...,
+ alternateEndpoints SEQUENCE OF Endpoint OPTIONAL,
+ gatekeeperIdentifier GatekeeperIdentifier OPTIONAL,
+ tokens SEQUENCE OF ClearToken OPTIONAL,
+ cryptoTokens SEQUENCE OF CryptoH323Token OPTIONAL,
+ integrityCheckValue ICV OPTIONAL,
+ reason UnregRequestReason OPTIONAL
+}
+
+UnregRequestReason ::= CHOICE
+{
+ reregistrationRequired NULL,
+ ttlExpired NULL,
+ securityDenial NULL,
+ undefinedReason NULL,
+ ...
+}
+
+UnregistrationConfirm ::= SEQUENCE --(UCF)
+{
+ requestSeqNum RequestSeqNum,
+ nonStandardData NonStandardParameter OPTIONAL,
+ ...,
+ tokens SEQUENCE OF ClearToken OPTIONAL,
+ cryptoTokens SEQUENCE OF CryptoH323Token OPTIONAL,
+ integrityCheckValue ICV OPTIONAL
+}
+
+UnregistrationReject ::= SEQUENCE --(URJ)
+{
+
+ requestSeqNum RequestSeqNum,
+ rejectReason UnregRejectReason,
+ nonStandardData NonStandardParameter OPTIONAL,
+ ...,
+ altGKInfo AltGKInfo OPTIONAL,
+ tokens SEQUENCE OF ClearToken OPTIONAL,
+ cryptoTokens SEQUENCE OF CryptoH323Token OPTIONAL,
+ integrityCheckValue ICV OPTIONAL
+}
+
+UnregRejectReason ::= CHOICE
+{
+ notCurrentlyRegistered NULL,
+ callInProgress NULL,
+ undefinedReason NULL,
+ ...,
+ permissionDenied NULL, -- requesting user not allowed to unregister
+ -- specified user
+ securityDenial NULL
+}
+
+AdmissionRequest ::= SEQUENCE --(ARQ)
+{
+ requestSeqNum RequestSeqNum,
+ callType CallType,
+ callModel CallModel OPTIONAL,
+ endpointIdentifier EndpointIdentifier,
+ destinationInfo SEQUENCE OF AliasAddress OPTIONAL, --Note 1
+ destCallSignalAddress TransportAddress OPTIONAL, --Note 1
+ destExtraCallInfo SEQUENCE OF AliasAddress OPTIONAL,
+ srcInfo SEQUENCE OF AliasAddress,
+ srcCallSignalAddress TransportAddress OPTIONAL,
+ bandWidth BandWidth,
+ callReferenceValue CallReferenceValue,
+ nonStandardData NonStandardParameter OPTIONAL,
+ callServices QseriesOptions OPTIONAL,
+ conferenceID ConferenceIdentifier,
+ activeMC BOOLEAN,
+ answerCall BOOLEAN, -- answering a call
+ ...,
+ canMapAlias BOOLEAN, -- can handle alias address
+ callIdentifier CallIdentifier,
+ srcAlternatives SEQUENCE OF Endpoint OPTIONAL,
+ destAlternatives SEQUENCE OF Endpoint OPTIONAL,
+ gatekeeperIdentifier GatekeeperIdentifier OPTIONAL,
+ tokens SEQUENCE OF ClearToken OPTIONAL,
+ cryptoTokens SEQUENCE OF CryptoH323Token OPTIONAL,
+ integrityCheckValue ICV OPTIONAL,
+ transportQOS TransportQOS OPTIONAL,
+ willSupplyUUIEs BOOLEAN
+}
+
+CallType ::= CHOICE
+{
+ pointToPoint NULL, -- Point to point
+ oneToN NULL, -- no interaction (FFS)
+ nToOne NULL, -- no interaction (FFS)
+ nToN NULL, -- interactive (multipoint)
+ ...
+}
+
+CallModel ::= CHOICE
+{
+ direct NULL,
+ gatekeeperRouted NULL,
+ ...
+}
+
+TransportQOS ::= CHOICE
+{
+ endpointControlled NULL,
+ gatekeeperControlled NULL,
+ noControl NULL,
+ ...
+}
+
+AdmissionConfirm ::= SEQUENCE --(ACF)
+{
+ requestSeqNum RequestSeqNum,
+ bandWidth BandWidth,
+ callModel CallModel,
+ destCallSignalAddress TransportAddress,
+ irrFrequency INTEGER (1..65535) OPTIONAL,
+ nonStandardData NonStandardParameter OPTIONAL,
+ ...,
+ destinationInfo SEQUENCE OF AliasAddress OPTIONAL,
+ destExtraCallInfo SEQUENCE OF AliasAddress OPTIONAL,
+ destinationType EndpointType OPTIONAL,
+ remoteExtensionAddress SEQUENCE OF AliasAddress OPTIONAL,
+ alternateEndpoints SEQUENCE OF Endpoint OPTIONAL,
+ tokens SEQUENCE OF ClearToken OPTIONAL,
+ cryptoTokens SEQUENCE OF CryptoH323Token OPTIONAL,
+ integrityCheckValue ICV OPTIONAL,
+ transportQOS TransportQOS OPTIONAL,
+ willRespondToIRR BOOLEAN,
+ uuiesRequested UUIEsRequested
+}
+
+UUIEsRequested ::= SEQUENCE
+{
+ setup BOOLEAN,
+ callProceeding BOOLEAN,
+ connect BOOLEAN,
+ alerting BOOLEAN,
+ userInformation BOOLEAN,
+ releaseComplete BOOLEAN,
+ facility BOOLEAN,
+ progress BOOLEAN,
+ empty BOOLEAN,
+ ...
+}
+
+AdmissionReject ::= SEQUENCE --(ARJ)
+{
+ requestSeqNum RequestSeqNum,
+ rejectReason AdmissionRejectReason,
+ nonStandardData NonStandardParameter OPTIONAL,
+ ...,
+ altGKInfo AltGKInfo OPTIONAL,
+ tokens SEQUENCE OF ClearToken OPTIONAL,
+ cryptoTokens SEQUENCE OF CryptoH323Token OPTIONAL,
+ callSignalAddress SEQUENCE OF TransportAddress OPTIONAL,
+ integrityCheckValue ICV OPTIONAL
+}
+
+AdmissionRejectReason ::= CHOICE
+{
+ calledPartyNotRegistered NULL, -- can't translate address
+ invalidPermission NULL, -- permission has expired
+ requestDenied NULL, -- no bandwidth available
+ undefinedReason NULL,
+ callerNotRegistered NULL,
+ routeCallToGatekeeper NULL,
+ invalidEndpointIdentifier NULL,
+ resourceUnavailable NULL,
+ ...,
+ securityDenial NULL,
+ qosControlNotSupported NULL,
+ incompleteAddress NULL
+}
+
+BandwidthRequest ::= SEQUENCE --(BRQ)
+{
+ requestSeqNum RequestSeqNum,
+ endpointIdentifier EndpointIdentifier,
+ conferenceID ConferenceIdentifier,
+ callReferenceValue CallReferenceValue,
+ callType CallType OPTIONAL,
+ bandWidth BandWidth,
+ nonStandardData NonStandardParameter OPTIONAL,
+ ...,
+ callIdentifier CallIdentifier,
+ gatekeeperIdentifier GatekeeperIdentifier OPTIONAL,
+ tokens SEQUENCE OF ClearToken OPTIONAL,
+ cryptoTokens SEQUENCE OF CryptoH323Token OPTIONAL,
+ integrityCheckValue ICV OPTIONAL,
+ answeredCall BOOLEAN
+}
+
+BandwidthConfirm ::= SEQUENCE --(BCF)
+{
+ requestSeqNum RequestSeqNum,
+ bandWidth BandWidth,
+ nonStandardData NonStandardParameter OPTIONAL,
+ ...,
+ tokens SEQUENCE OF ClearToken OPTIONAL,
+ cryptoTokens SEQUENCE OF CryptoH323Token OPTIONAL,
+ integrityCheckValue ICV OPTIONAL
+}
+
+BandwidthReject ::= SEQUENCE --(BRJ)
+{
+ requestSeqNum RequestSeqNum,
+ rejectReason BandRejectReason,
+ allowedBandWidth BandWidth,
+ nonStandardData NonStandardParameter OPTIONAL,
+ ...,
+ altGKInfo AltGKInfo OPTIONAL,
+ tokens SEQUENCE OF ClearToken OPTIONAL,
+ cryptoTokens SEQUENCE OF CryptoH323Token OPTIONAL,
+ integrityCheckValue ICV OPTIONAL
+}
+
+BandRejectReason ::= CHOICE
+{
+ notBound NULL, -- discovery permission has aged
+ invalidConferenceID NULL, -- possible revision
+ invalidPermission NULL, -- true permission violation
+ insufficientResources NULL,
+ invalidRevision NULL,
+ undefinedReason NULL,
+ ...,
+ securityDenial NULL
+}
+
+LocationRequest ::= SEQUENCE --(LRQ)
+{
+ requestSeqNum RequestSeqNum,
+ endpointIdentifier EndpointIdentifier OPTIONAL,
+ destinationInfo SEQUENCE OF AliasAddress,
+ nonStandardData NonStandardParameter OPTIONAL,
+ replyAddress TransportAddress,
+ ...,
+ sourceInfo SEQUENCE OF AliasAddress OPTIONAL,
+ canMapAlias BOOLEAN, -- can handle alias address
+ gatekeeperIdentifier GatekeeperIdentifier OPTIONAL,
+ tokens SEQUENCE OF ClearToken OPTIONAL,
+ cryptoTokens SEQUENCE OF CryptoH323Token OPTIONAL,
+ integrityCheckValue ICV OPTIONAL
+}
+
+LocationConfirm ::= SEQUENCE --(LCF)
+{
+ requestSeqNum RequestSeqNum,
+ callSignalAddress TransportAddress,
+ rasAddress TransportAddress,
+ nonStandardData NonStandardParameter OPTIONAL,
+ ...,
+ destinationInfo SEQUENCE OF AliasAddress OPTIONAL,
+ destExtraCallInfo SEQUENCE OF AliasAddress OPTIONAL,
+ destinationType EndpointType OPTIONAL,
+ remoteExtensionAddress SEQUENCE OF AliasAddress OPTIONAL,
+ alternateEndpoints SEQUENCE OF Endpoint OPTIONAL,
+ tokens SEQUENCE OF ClearToken OPTIONAL,
+ cryptoTokens SEQUENCE OF CryptoH323Token OPTIONAL,
+ integrityCheckValue ICV OPTIONAL
+}
+
+LocationReject ::= SEQUENCE --(LRJ)
+{
+ requestSeqNum RequestSeqNum,
+ rejectReason LocationRejectReason,
+ nonStandardData NonStandardParameter OPTIONAL,
+ ...,
+ altGKInfo AltGKInfo OPTIONAL,
+ tokens SEQUENCE OF ClearToken OPTIONAL,
+ cryptoTokens SEQUENCE OF CryptoH323Token OPTIONAL,
+ integrityCheckValue ICV OPTIONAL
+}
+
+
+LocationRejectReason ::= CHOICE
+{
+ notRegistered NULL,
+ invalidPermission NULL, -- exclusion by administrator or feature
+ requestDenied NULL, -- can't find location
+ undefinedReason NULL,
+ ...,
+ securityDenial NULL
+}
+
+DisengageRequest ::= SEQUENCE --(DRQ)
+{
+ requestSeqNum RequestSeqNum,
+ endpointIdentifier EndpointIdentifier,
+ conferenceID ConferenceIdentifier,
+ callReferenceValue CallReferenceValue,
+ disengageReason DisengageReason,
+ nonStandardData NonStandardParameter OPTIONAL,
+ ...,
+ callIdentifier CallIdentifier,
+ gatekeeperIdentifier GatekeeperIdentifier OPTIONAL,
+ tokens SEQUENCE OF ClearToken OPTIONAL,
+ cryptoTokens SEQUENCE OF CryptoH323Token OPTIONAL,
+ integrityCheckValue ICV OPTIONAL,
+ answeredCall BOOLEAN
+}
+
+DisengageReason ::= CHOICE
+{
+ forcedDrop NULL, -- gatekeeper is forcing the drop
+ normalDrop NULL, -- associated with normal drop
+ undefinedReason NULL,
+ ...
+}
+
+DisengageConfirm ::= SEQUENCE --(DCF)
+{
+ requestSeqNum RequestSeqNum,
+ nonStandardData NonStandardParameter OPTIONAL,
+ ...,
+ tokens SEQUENCE OF ClearToken OPTIONAL,
+ cryptoTokens SEQUENCE OF CryptoH323Token OPTIONAL,
+ integrityCheckValue ICV OPTIONAL
+}
+
+DisengageReject ::= SEQUENCE --(DRJ)
+{
+ requestSeqNum RequestSeqNum,
+ rejectReason DisengageRejectReason,
+ nonStandardData NonStandardParameter OPTIONAL,
+ ...,
+ altGKInfo AltGKInfo OPTIONAL,
+ tokens SEQUENCE OF ClearToken OPTIONAL,
+ cryptoTokens SEQUENCE OF CryptoH323Token OPTIONAL,
+ integrityCheckValue ICV OPTIONAL
+}
+
+DisengageRejectReason ::= CHOICE
+{
+ notRegistered NULL, -- not registered with gatekeeper
+ requestToDropOther NULL, -- can't request drop for others
+ ...,
+ securityDenial NULL
+}
+
+InfoRequest ::= SEQUENCE --(IRQ)
+{
+ requestSeqNum RequestSeqNum,
+ callReferenceValue CallReferenceValue,
+ nonStandardData NonStandardParameter OPTIONAL,
+ replyAddress TransportAddress OPTIONAL,
+ ...,
+ callIdentifier CallIdentifier,
+ tokens SEQUENCE OF ClearToken OPTIONAL,
+ cryptoTokens SEQUENCE OF CryptoH323Token OPTIONAL,
+ integrityCheckValue ICV OPTIONAL,
+ uuiesRequested UUIEsRequested OPTIONAL
+}
+InfoRequestResponse ::= SEQUENCE --(IRR)
+{
+ nonStandardData NonStandardParameter OPTIONAL,
+ requestSeqNum RequestSeqNum,
+ endpointType EndpointType,
+ endpointIdentifier EndpointIdentifier,
+ rasAddress TransportAddress,
+ callSignalAddress SEQUENCE OF TransportAddress,
+ endpointAlias SEQUENCE OF AliasAddress OPTIONAL,
+ perCallInfo SEQUENCE OF SEQUENCE
+ {
+ nonStandardData NonStandardParameter OPTIONAL,
+ callReferenceValue CallReferenceValue,
+ conferenceID ConferenceIdentifier,
+ originator BOOLEAN OPTIONAL,
+ audio SEQUENCE OF RTPSession OPTIONAL,
+ video SEQUENCE OF RTPSession OPTIONAL,
+ data SEQUENCE OF TransportChannelInfo OPTIONAL,
+ h245 TransportChannelInfo,
+ callSignaling TransportChannelInfo,
+ callType CallType,
+ bandWidth BandWidth,
+ callModel CallModel,
+ ...,
+ callIdentifier CallIdentifier,
+ tokens SEQUENCE OF ClearToken OPTIONAL,
+ cryptoTokens SEQUENCE OF CryptoH323Token OPTIONAL,
+ substituteConfIDs SEQUENCE OF ConferenceIdentifier,
+ pdu SEQUENCE OF SEQUENCE
+ {
+ h323pdu H323-UU-PDU,
+ sent BOOLEAN -- TRUE is sent, FALSE is received
+ } OPTIONAL
+ } OPTIONAL,
+ ...,
+ tokens SEQUENCE OF ClearToken OPTIONAL,
+ cryptoTokens SEQUENCE OF CryptoH323Token OPTIONAL,
+ integrityCheckValue ICV OPTIONAL,
+ needResponse BOOLEAN
+}
+
+TransportChannelInfo ::= SEQUENCE
+{
+ sendAddress TransportAddress OPTIONAL,
+ recvAddress TransportAddress OPTIONAL,
+ ...
+}
+
+RTPSession ::= SEQUENCE
+{
+ rtpAddress TransportChannelInfo,
+ rtcpAddress TransportChannelInfo,
+ cname PrintableString,
+ ssrc INTEGER (1..4294967295),
+ sessionId INTEGER (1..255),
+ associatedSessionIds SEQUENCE OF INTEGER (1..255),
+ ...
+}
+
+InfoRequestAck ::= SEQUENCE --(IACK)
+{
+ requestSeqNum RequestSeqNum,
+ nonStandardData NonStandardParameter OPTIONAL,
+ tokens SEQUENCE OF ClearToken OPTIONAL,
+ cryptoTokens SEQUENCE OF CryptoH323Token OPTIONAL,
+ integrityCheckValue ICV OPTIONAL,
+ ...
+}
+
+InfoRequestNak ::= SEQUENCE --(INAK)
+{
+ requestSeqNum RequestSeqNum,
+ nonStandardData NonStandardParameter OPTIONAL,
+ nakReason InfoRequestNakReason,
+ altGKInfo AltGKInfo OPTIONAL,
+ tokens SEQUENCE OF ClearToken OPTIONAL,
+ cryptoTokens SEQUENCE OF CryptoH323Token OPTIONAL,
+ integrityCheckValue ICV OPTIONAL,
+ ...
+}
+
+InfoRequestNakReason ::= CHOICE
+{
+ notRegistered NULL, -- not registered with gatekeeper
+ securityDenial NULL,
+ undefinedReason NULL,
+ ...
+}
+
+NonStandardMessage ::= SEQUENCE
+{
+ requestSeqNum RequestSeqNum,
+ nonStandardData NonStandardParameter,
+ ...,
+ tokens SEQUENCE OF ClearToken OPTIONAL,
+ cryptoTokens SEQUENCE OF CryptoH323Token OPTIONAL,
+ integrityCheckValue ICV OPTIONAL
+}
+
+UnknownMessageResponse ::= SEQUENCE -- (XRS)
+{
+ requestSeqNum RequestSeqNum,
+ ...,
+ tokens SEQUENCE OF ClearToken OPTIONAL,
+ cryptoTokens SEQUENCE OF CryptoH323Token OPTIONAL,
+ integrityCheckValue ICV OPTIONAL
+}
+
+RequestInProgress ::= SEQUENCE -- (RIP)
+{
+ requestSeqNum RequestSeqNum,
+ nonStandardData NonStandardParameter OPTIONAL,
+ tokens SEQUENCE OF ClearToken OPTIONAL,
+ cryptoTokens SEQUENCE OF CryptoH323Token OPTIONAL,
+ integrityCheckValue ICV OPTIONAL,
+ delay INTEGER(1..65535),
+ ...
+}
+
+ResourcesAvailableIndicate ::= SEQUENCE --(RAI)
+{
+ requestSeqNum RequestSeqNum,
+ protocolIdentifier ProtocolIdentifier,
+ nonStandardData NonStandardParameter OPTIONAL,
+ endpointIdentifier EndpointIdentifier,
+ protocols SEQUENCE OF SupportedProtocols,
+ almostOutOfResources BOOLEAN,
+ tokens SEQUENCE OF ClearToken OPTIONAL,
+ cryptoTokens SEQUENCE OF CryptoH323Token OPTIONAL,
+ integrityCheckValue ICV OPTIONAL,
+ ...
+}
+
+ResourcesAvailableConfirm ::= SEQUENCE --(RAC)
+{
+ requestSeqNum RequestSeqNum,
+ protocolIdentifier ProtocolIdentifier,
+ nonStandardData NonStandardParameter OPTIONAL,
+ tokens SEQUENCE OF ClearToken OPTIONAL,
+ cryptoTokens SEQUENCE OF CryptoH323Token OPTIONAL,
+ integrityCheckValue ICV OPTIONAL,
+ ...
+}
+
+END -- of ASN.1
diff --git a/lib/asn1/test/asn1_SUITE_data/IMP.asn1 b/lib/asn1/test/asn1_SUITE_data/IMP.asn1
new file mode 100644
index 0000000000..8d7546fa15
--- /dev/null
+++ b/lib/asn1/test/asn1_SUITE_data/IMP.asn1
@@ -0,0 +1,7 @@
+IMP DEFINITIONS AUTOMATIC TAGS ::=
+
+BEGIN
+
+T ::= INTEGER
+
+END \ No newline at end of file
diff --git a/lib/asn1/test/asn1_SUITE_data/IN-CS-1-Datatypes.asn b/lib/asn1/test/asn1_SUITE_data/IN-CS-1-Datatypes.asn
new file mode 100644
index 0000000000..ff0361f5c5
--- /dev/null
+++ b/lib/asn1/test/asn1_SUITE_data/IN-CS-1-Datatypes.asn
@@ -0,0 +1,1630 @@
+-- Module IN-CS-1-Datatypes (Q.1218:10/1995)
+-- Example of addition of an extension named 'Some Network Specific Indicator' of type
+-- BOOLEAN, with criticality 'abort' and to be identified as extension number 1.
+-- Example of definition using the above macro:
+--
+-- SomeNetworkSpecificIndicator ::= EXTENSION {
+-- EXTENSION-SYNTAX BOOLEAN
+-- CRITICALITY abort
+-- IDENTIFIED BY 1
+-- }
+--
+--
+-- Example of transfer syntax, using the ExtensionField datatype as specified in the module
+-- below. Assuming the value of the extension is set to TRUE, the extensions parameter
+-- becomes a Sequence of type INTEGER ::= 1, criticality ENUMERATED ::= 1 and value [1]
+-- EXPLICIT BOOLEAN ::= TRUE.
+--
+-- Use of Q.1400 defined Extension is ffs.
+-- In addition the extension mechanism marker is used to identify the future minor additions to INAP.
+IN-CS-1-Datatypes {itu-t recommendation q 1218 modules(0) cs-1-datatypes(2)
+ version1(0)}
+-- This module contains the type definitions for the IN CS-1 data types.
+-- Where a parameter of type CHOICE is tagged with a specific tag value, the tag is automatically
+-- replaced with an EXPLICIT tag of the same value.
+-- The following parameters map onto bearer protocol (i.e. Q.931, case 2 and ISUP) parameters:
+-- CallingPartySubaddress, CalledPartyNumber,
+-- Prefix (derived from dialled digits), DestinationRoutingAddress,
+-- DialledDigits, ISDNAccessRelatedInformation, CallingPartysCategory, LocationNumber,
+-- TravellingClassMark, AssistingSSPIPRoutingAddress, AlertingPattern (Q.931 only),
+-- ReleaseCause (and other Cause parameters), ServiceProfileIdentifier (Q.932 only),
+-- BearerCapability, CallingPartyNumber, HighLayerCompatibility, OriginalCalledPartyID,
+-- RedirectingPartyID, and RedirectionInformation.
+-- The procedures for mapping of parameters onto bearer protocol are ffs.
+-- The following SSF parameters do not map onto bearer protocol (i.e. Q.931, case 2 and ISUP)
+-- parameters and therefore are assumed to be local to the switching system: CallingPartyBusinessGroupID
+-- FacilityGroup, FacilityGroupMember, RouteList, LegID, IPSSPCapabilities, IPAvailable, CGEncountered,
+-- ForwardingCondition, CorrelationID, ApplicationTimer, TerminalType, MiscCallInfo, TriggerType and
+-- ServiceKey.
+-- Where possible, Administrations should specify the maximum size within their network of
+-- parameters specified in this Recommendation that are of an indeterminate length.
+DEFINITIONS IMPLICIT TAGS ::=
+BEGIN
+
+-- TYPE DEFINITIONS FOR IN CS-1 DATA TYPES FOLLOWS
+-- Argument data types
+InvokeIdType ::= INTEGER(-128..127)
+
+-- The ordering of parameters in the argument sequences has been arbitrary. Further study may be
+-- required to order arguments in a manner which will facilitate efficient encoding and decoding.
+ActivateServiceFilteringArg ::= SEQUENCE {
+ filteredCallTreatment [0] FilteredCallTreatment,
+ filteringCharacteristics [1] FilteringCharacteristics,
+ filteringTimeOut [2] FilteringTimeOut,
+ filteringCriteria [3] FilteringCriteria,
+ startTime [4] DateAndTime OPTIONAL,
+ extensions
+ [5] SEQUENCE SIZE (1..numOfExtensions) OF
+ ExtensionField{{SupportedExtensions}},
+ ...
+}
+
+AnalysedInformationArg ::= SEQUENCE {
+ dpSpecificCommonParameters [0] DpSpecificCommonParameters,
+ dialledDigits [1] CalledPartyNumber OPTIONAL,
+ callingPartyBusinessGroupID [2] CallingPartyBusinessGroupID OPTIONAL,
+ callingPartySubaddress [3] CallingPartySubaddress OPTIONAL,
+ callingFacilityGroup [4] FacilityGroup OPTIONAL,
+ callingFacilityGroupMember [5] FacilityGroupMember OPTIONAL,
+ originalCalledPartyID [6] OriginalCalledPartyID OPTIONAL,
+ prefix [7] Digits OPTIONAL,
+ redirectingPartyID [8] RedirectingPartyID OPTIONAL,
+ redirectionInformation [9] RedirectionInformation OPTIONAL,
+ routeList [10] RouteList OPTIONAL,
+ travellingClassMark [11] TravellingClassMark OPTIONAL,
+ extensions
+ [12] SEQUENCE SIZE (1..numOfExtensions) OF
+ ExtensionField{{SupportedExtensions}},
+ featureCode [13] FeatureCode OPTIONAL,
+ accessCode [14] AccessCode OPTIONAL,
+ carrier [15] Carrier OPTIONAL,
+ ...
+}
+
+-- For the OPTIONAL parameters, refer to clause 3 for the trigger detection point processing rules
+-- to specify when these parameters are included in the message.
+AnalyseInformationArg ::= SEQUENCE {
+ destinationRoutingAddress [0] DestinationRoutingAddress,
+ alertingPattern [1] AlertingPattern OPTIONAL,
+ iSDNAccessRelatedInformation [2] ISDNAccessRelatedInformation OPTIONAL,
+ originalCalledPartyID [3] OriginalCalledPartyID OPTIONAL,
+ extensions
+ [4] SEQUENCE SIZE (1..numOfExtensions) OF
+ ExtensionField{{SupportedExtensions}},
+ callingPartyNumber [5] CallingPartyNumber OPTIONAL,
+ callingPartysCategory [6] CallingPartysCategory OPTIONAL,
+ calledPartyNumber [7] CalledPartyNumber OPTIONAL,
+ chargeNumber [8] ChargeNumber OPTIONAL,
+ travellingClassMark [9] TravellingClassMark OPTIONAL,
+ carrier [10] Carrier OPTIONAL,
+ ...
+}
+
+ApplyChargingArg ::= SEQUENCE {
+ aChBillingChargingCharacteristics [0] AChBillingChargingCharacteristics,
+ partyToCharge [2] LegID OPTIONAL,
+ extensions
+ [3] SEQUENCE SIZE (1..numOfExtensions) OF
+ ExtensionField{{SupportedExtensions}},
+ ...
+}
+
+-- The partyToCharge parameter indicates the party in the call to which the ApplyCharging operation
+-- should be applied. If it is not present, then it is applied to the A-party.
+ApplyChargingReportArg ::=
+ CallResult
+
+AssistRequestInstructionsArg ::= SEQUENCE {
+ correlationID [0] CorrelationID,
+ iPAvailable [1] IPAvailable OPTIONAL,
+ iPSSPCapabilities [2] IPSSPCapabilities OPTIONAL,
+ extensions
+ [3] SEQUENCE SIZE (1..numOfExtensions) OF
+ ExtensionField{{SupportedExtensions}},
+ ...
+}
+
+-- OPTIONAL denotes network operator specific use. The value of the correlationID may be the
+-- Called Party Number supplied by the initiating SSF.
+CallGapArg ::= SEQUENCE {
+ gapCriteria [0] GapCriteria,
+ gapIndicators [1] GapIndicators,
+ controlType [2] ControlType OPTIONAL,
+ gapTreatment [3] GapTreatment OPTIONAL,
+ extensions
+ [4] SEQUENCE SIZE (1..numOfExtensions) OF
+ ExtensionField{{SupportedExtensions}},
+ ...
+}
+
+-- OPTIONAL denotes network operator optional. If gapTreatment is not present, the SSF will use
+-- a default treatment depending on network operator implementation.
+CallInformationReportArg ::= SEQUENCE {
+ requestedInformationList [0] RequestedInformationList,
+ correlationID [1] CorrelationID OPTIONAL,
+ extensions
+ [2] SEQUENCE SIZE (1..numOfExtensions) OF
+ ExtensionField{{SupportedExtensions}},
+ ...
+}
+
+-- OPTIONAL denotes network operator optional.
+CallInformationRequestArg ::= SEQUENCE {
+ requestedInformationTypeList [0] RequestedInformationTypeList,
+ correlationID [1] CorrelationID OPTIONAL,
+ extensions
+ [2] SEQUENCE SIZE (1..numOfExtensions) OF
+ ExtensionField{{SupportedExtensions}},
+ ...
+}
+
+-- OPTIONAL denotes network operator optional.
+CancelArg ::= CHOICE {invokeID [0] InvokeID,
+ allRequests [1] NULL
+}
+
+-- The InvokeID has the same value as that which was used for the operation to be cancelled.
+CancelStatusReportRequestArg ::= SEQUENCE {
+ resourceID [0] ResourceID OPTIONAL,
+ extensions
+ [1] SEQUENCE SIZE (1..numOfExtensions) OF
+ ExtensionField{{SupportedExtensions}},
+ ...
+}
+
+CollectedInformationArg ::= SEQUENCE {
+ dpSpecificCommonParameters [0] DpSpecificCommonParameters,
+ dialledDigits [1] CalledPartyNumber OPTIONAL,
+ callingPartyBusinessGroupID [2] CallingPartyBusinessGroupID OPTIONAL,
+ callingPartySubaddress [3] CallingPartySubaddress OPTIONAL,
+ callingFacilityGroup [4] FacilityGroup OPTIONAL,
+ callingFacilityGroupMember [5] FacilityGroupMember OPTIONAL,
+ originalCalledPartyID [6] OriginalCalledPartyID OPTIONAL,
+ prefix [7] Digits OPTIONAL,
+ redirectingPartyID [8] RedirectingPartyID OPTIONAL,
+ redirectionInformation [9] RedirectionInformation OPTIONAL,
+ travellingClassMark [10] TravellingClassMark OPTIONAL,
+ extensions
+ [11] SEQUENCE SIZE (1..numOfExtensions) OF
+ [11] ExtensionField{{SupportedExtensions}},
+ featureCode [12] FeatureCode OPTIONAL,
+ accessCode [13] AccessCode OPTIONAL,
+ carrier [14] Carrier OPTIONAL,
+ ...
+}
+
+-- For the OPTIONAL parameters, refer to clause 3 for the trigger detection point processing rules
+-- to specify when these parameters are included in the message.
+CollectInformationArg ::= SEQUENCE {
+ alertingPattern [0] AlertingPattern OPTIONAL,
+ numberingPlan [1] NumberingPlan OPTIONAL,
+ originalCalledPartyID [2] OriginalCalledPartyID OPTIONAL,
+ travellingClassMark [3] TravellingClassMark OPTIONAL,
+ extensions
+ [4] SEQUENCE SIZE (1..numOfExtensions) OF
+ ExtensionField{{SupportedExtensions}},
+ callingPartyNumber [5] CallingPartyNumber OPTIONAL,
+ dialledDigits [6] CalledPartyNumber OPTIONAL,
+ ...
+}
+
+ConnectArg ::= SEQUENCE {
+ destinationRoutingAddress [0] DestinationRoutingAddress,
+ alertingPattern [1] AlertingPattern OPTIONAL,
+ correlationID [2] CorrelationID OPTIONAL,
+ cutAndPaste [3] CutAndPaste OPTIONAL,
+ forwardingCondition [4] ForwardingCondition OPTIONAL,
+ iSDNAccessRelatedInformation [5] ISDNAccessRelatedInformation OPTIONAL,
+ originalCalledPartyID [6] OriginalCalledPartyID OPTIONAL,
+ routeList [7] RouteList OPTIONAL,
+ scfID [8] ScfID OPTIONAL,
+ travellingClassMark [9] TravellingClassMark OPTIONAL,
+ extensions
+ [10] SEQUENCE SIZE (1..numOfExtensions) OF
+ ExtensionField{{SupportedExtensions}},
+ carrier [11] Carrier OPTIONAL,
+ serviceInteractionIndicators [26] ServiceInteractionIndicators OPTIONAL,
+ callingPartyNumber [27] CallingPartyNumber OPTIONAL,
+ callingPartysCategory [28] CallingPartysCategory OPTIONAL,
+ redirectingPartyID [29] RedirectingPartyID OPTIONAL,
+ redirectionInformation [30] RedirectionInformation OPTIONAL,
+ ...
+}
+
+-- For alerting pattern, OPTIONAL denotes that this parameter only applies if SSF is the terminating
+-- local exchange for the subscriber.
+ConnectToResourceArg ::= SEQUENCE {
+ resourceAddress
+ CHOICE {ipRoutingAddress [0] IPRoutingAddress,
+ legID [1] LegID,
+ both
+ [2] SEQUENCE {ipRoutingAddress [0] IPRoutingAddress,
+ legID [1] LegID},
+ none [3] NULL},
+ extensions
+ [4] SEQUENCE SIZE (1..numOfExtensions) OF
+ ExtensionField{{SupportedExtensions}},
+ serviceInteractionIndicators [30] ServiceInteractionIndicators OPTIONAL,
+ ...
+}
+
+DpSpecificCommonParameters ::= SEQUENCE {
+ serviceAddressInformation [0] ServiceAddressInformation,
+ bearerCapability [1] BearerCapability OPTIONAL,
+ calledPartyNumber [2] CalledPartyNumber OPTIONAL,
+ callingPartyNumber [3] CallingPartyNumber OPTIONAL,
+ callingPartysCategory [4] CallingPartysCategory OPTIONAL,
+ iPSSPCapabilities [5] IPSSPCapabilities OPTIONAL,
+ iPAvailable [6] IPAvailable OPTIONAL,
+ iSDNAccessRelatedInformation [7] ISDNAccessRelatedInformation OPTIONAL,
+ cGEncountered [8] CGEncountered OPTIONAL,
+ locationNumber [9] LocationNumber OPTIONAL,
+ serviceProfileIdentifier [10] ServiceProfileIdentifier OPTIONAL,
+ terminalType [11] TerminalType OPTIONAL,
+ extensions
+ [12] SEQUENCE SIZE (1..numOfExtensions) OF
+ [12] ExtensionField{{SupportedExtensions}},
+ chargeNumber [13] ChargeNumber OPTIONAL,
+ servingAreaID [14] ServingAreaID OPTIONAL,
+ ...
+}
+
+-- OPTIONAL for iPSSPCapabilities, iPAvailable, and cGEncountered denotes network operator
+-- specific use. OPTIONAL for callingPartyNumber, and callingPartysCategory refer to clause 3 for
+-- the trigger detection point processing rules to specify when these parameters are included in the
+-- message. bearerCapability should be appropriately coded as speech.
+EstablishTemporaryConnectionArg ::= SEQUENCE {
+ assistingSSPIPRoutingAddress [0] AssistingSSPIPRoutingAddress,
+ correlationID [1] CorrelationID OPTIONAL,
+ legID [2] LegID OPTIONAL,
+ scfID [3] ScfID OPTIONAL,
+ extensions
+ [4] SEQUENCE SIZE (1..numOfExtensions) OF
+ [4] ExtensionField{{SupportedExtensions}},
+ carrier [5] Carrier OPTIONAL,
+ serviceInteractionIndicators [30] ServiceInteractionIndicators OPTIONAL,
+ ...
+}
+
+EventNotificationChargingArg ::= SEQUENCE {
+ eventTypeCharging [0] EventTypeCharging,
+ eventSpecificInformationCharging
+ [1] EventSpecificInformationCharging OPTIONAL,
+ legID [2] LegID OPTIONAL,
+ extensions
+ [3] SEQUENCE SIZE (1..numOfExtensions) OF
+ ExtensionField{{SupportedExtensions}},
+ monitorMode [30] MonitorMode DEFAULT notifyAndContinue,
+ ...
+}
+
+-- OPTIONAL denotes network operator specific use.
+EventReportBCSMArg ::= SEQUENCE {
+ eventTypeBCSM [0] EventTypeBCSM,
+ bcsmEventCorrelationID [1] CorrelationID OPTIONAL,
+ eventSpecificInformationBCSM [2] EventSpecificInformationBCSM OPTIONAL,
+ legID [3] LegID OPTIONAL,
+ miscCallInfo [4] MiscCallInfo DEFAULT {messageType request},
+ extensions
+ [5] SEQUENCE SIZE (1..numOfExtensions) OF
+ ExtensionField{{SupportedExtensions}},
+ ...
+}
+
+FurnishChargingInformationArg ::= FCIBillingChargingCharacteristics
+
+HoldCallInNetworkArg ::= CHOICE {
+ holdcause [0] HoldCause,
+ empty [1] NULL
+}
+
+-- holdcause is optional and denotes network operator specific use.
+InitialDPArg ::= SEQUENCE {
+ serviceKey [0] ServiceKey OPTIONAL,
+ dialledDigits [1] CalledPartyNumber OPTIONAL,
+ calledPartyNumber [2] CalledPartyNumber OPTIONAL,
+ callingPartyNumber [3] CallingPartyNumber OPTIONAL,
+ callingPartyBusinessGroupID [4] CallingPartyBusinessGroupID OPTIONAL,
+ callingPartysCategory [5] CallingPartysCategory OPTIONAL,
+ callingPartySubaddress [6] CallingPartySubaddress OPTIONAL,
+ cGEncountered [7] CGEncountered OPTIONAL,
+ iPSSPCapabilities [8] IPSSPCapabilities OPTIONAL,
+ iPAvailable [9] IPAvailable OPTIONAL,
+ locationNumber [10] LocationNumber OPTIONAL,
+ miscCallInfo [11] MiscCallInfo OPTIONAL,
+ originalCalledPartyID [12] OriginalCalledPartyID OPTIONAL,
+ serviceProfileIdentifier [13] ServiceProfileIdentifier OPTIONAL,
+ terminalType [14] TerminalType OPTIONAL,
+ extensions
+ [15] SEQUENCE SIZE (1..numOfExtensions) OF
+ ExtensionField{{SupportedExtensions}},
+ triggerType [16] TriggerType OPTIONAL,
+ highLayerCompatibility [23] HighLayerCompatibility OPTIONAL,
+ serviceInteractionIndicators [24] ServiceInteractionIndicators OPTIONAL,
+ additionalCallingPartyNumber [25] AdditionalCallingPartyNumber OPTIONAL,
+ forwardCallIndicators [26] ForwardCallIndicators OPTIONAL,
+ bearerCapability [27] BearerCapability OPTIONAL,
+ eventTypeBCSM [28] EventTypeBCSM OPTIONAL,
+ redirectingPartyID [29] RedirectingPartyID OPTIONAL,
+ redirectionInformation [30] RedirectionInformation OPTIONAL,
+ ...
+}
+
+-- OPTIONAL for iPSSPCapabilities, iPAvailable, cGEncountered, and miscCallInfo denotes network
+-- operator specific use.
+-- OPTIONAL for dialledDigits, callingPartyNumber, and callingPartysCategory refer to clause 3 for the
+-- trigger detection point processing rules to specify when these parameters are included in the message.
+-- OPTIONAL for terminalType indicates that this parameter applies only at originating or terminating
+-- local exchanges if the SSF has this information.
+InitiateCallAttemptArg ::= SEQUENCE {
+ destinationRoutingAddress [0] DestinationRoutingAddress,
+ alertingPattern [1] AlertingPattern OPTIONAL,
+ iSDNAccessRelatedInformation [2] ISDNAccessRelatedInformation OPTIONAL,
+ travellingClassMark [3] TravellingClassMark OPTIONAL,
+ extensions
+ [4] SEQUENCE SIZE (1..numOfExtensions) OF
+ [5] ExtensionField{{SupportedExtensions}},
+ serviceInteractionIndicators [29] ServiceInteractionIndicators OPTIONAL,
+ callingPartyNumber [30] CallingPartyNumber OPTIONAL,
+ ...
+}
+
+MidCallArg ::= SEQUENCE {
+ dpSpecificCommonParameters [0] DpSpecificCommonParameters,
+ calledPartyBusinessGroupID [1] CalledPartyBusinessGroupID OPTIONAL,
+ calledPartySubaddress [2] CalledPartySubaddress OPTIONAL,
+ callingPartyBusinessGroupID [3] CallingPartyBusinessGroupID OPTIONAL,
+ callingPartySubaddress [4] CallingPartySubaddress OPTIONAL,
+ featureRequestIndicator [5] FeatureRequestIndicator OPTIONAL,
+ extensions
+ [6] SEQUENCE SIZE (1..numOfExtensions) OF
+ ExtensionField{{SupportedExtensions}},
+ carrier [7] Carrier OPTIONAL,
+ ...
+}
+
+-- For the OPTIONAL parameters, refer to clause 3 for the trigger detection point processing rules
+-- to specify when these parameters are included in the message.
+OAnswerArg ::= SEQUENCE {
+ dpSpecificCommonParameters [0] DpSpecificCommonParameters,
+ callingPartyBusinessGroupID [1] CallingPartyBusinessGroupID OPTIONAL,
+ callingPartySubaddress [2] CallingPartySubaddress OPTIONAL,
+ callingFacilityGroup [3] FacilityGroup OPTIONAL,
+ callingFacilityGroupMember [4] FacilityGroupMember OPTIONAL,
+ originalCalledPartyID [5] OriginalCalledPartyID OPTIONAL,
+ redirectingPartyID [6] RedirectingPartyID OPTIONAL,
+ redirectionInformation [7] RedirectionInformation OPTIONAL,
+ routeList [8] RouteList OPTIONAL,
+ travellingClassMark [9] TravellingClassMark OPTIONAL,
+ extensions
+ [10] SEQUENCE SIZE (1..numOfExtensions) OF
+ [5] ExtensionField{{SupportedExtensions}},
+ ...
+}
+
+-- For the OPTIONAL parameters, refer to clause 3 for the trigger detection point processing rules
+-- to specify when these parameters are included in the message.
+OCalledPartyBusyArg ::= SEQUENCE {
+ dpSpecificCommonParameters [0] DpSpecificCommonParameters,
+ busyCause [1] Cause OPTIONAL,
+ callingPartyBusinessGroupID [2] CallingPartyBusinessGroupID OPTIONAL,
+ callingPartySubaddress [3] CallingPartySubaddress OPTIONAL,
+ callingFacilityGroup [4] FacilityGroup OPTIONAL,
+ callingFacilityGroupMember [5] FacilityGroupMember OPTIONAL,
+ originalCalledPartyID [6] OriginalCalledPartyID OPTIONAL,
+ prefix [7] Digits OPTIONAL,
+ redirectingPartyID [8] RedirectingPartyID OPTIONAL,
+ redirectionInformation [9] RedirectionInformation OPTIONAL,
+ routeList [10] RouteList OPTIONAL,
+ travellingClassMark [11] TravellingClassMark OPTIONAL,
+ extensions
+ [12] SEQUENCE SIZE (1..numOfExtensions) OF
+ ExtensionField{{SupportedExtensions}},
+ carrier [13] Carrier OPTIONAL,
+ ...
+}
+
+-- For the OPTIONAL parameters, refer to clause 3 for the trigger detection point processing rules
+-- to specify when these parameters are included in the message.
+ODisconnectArg ::= SEQUENCE {
+ dpSpecificCommonParameters [0] DpSpecificCommonParameters,
+ callingPartyBusinessGroupID [1] CallingPartyBusinessGroupID OPTIONAL,
+ callingPartySubaddress [2] CallingPartySubaddress OPTIONAL,
+ callingFacilityGroup [3] FacilityGroup OPTIONAL,
+ callingFacilityGroupMember [4] FacilityGroupMember OPTIONAL,
+ releaseCause [5] Cause OPTIONAL,
+ routeList [6] RouteList OPTIONAL,
+ extensions
+ [7] SEQUENCE SIZE (1..numOfExtensions) OF
+ ExtensionField{{SupportedExtensions}},
+ carrier [8] Carrier OPTIONAL,
+ connectTime [9] Integer4 OPTIONAL,
+ ...
+}
+
+-- For the OPTIONAL parameters, refer to clause 3 for the trigger detection point processing rules
+-- to specify when these parameters are included in the message.
+ONoAnswerArg ::= SEQUENCE {
+ dpSpecificCommonParameters [0] DpSpecificCommonParameters,
+ callingPartyBusinessGroupID [1] CallingPartyBusinessGroupID OPTIONAL,
+ callingPartySubaddress [2] CallingPartySubaddress OPTIONAL,
+ callingFacilityGroup [3] FacilityGroup OPTIONAL,
+ callingFacilityGroupMember [4] FacilityGroupMember OPTIONAL,
+ originalCalledPartyID [5] OriginalCalledPartyID OPTIONAL,
+ prefix [6] Digits OPTIONAL,
+ redirectingPartyID [7] RedirectingPartyID OPTIONAL,
+ redirectionInformation [8] RedirectionInformation OPTIONAL,
+ routeList [9] RouteList OPTIONAL,
+ travellingClassMark [10] TravellingClassMark OPTIONAL,
+ extensions
+ [11] SEQUENCE SIZE (1..numOfExtensions) OF
+ ExtensionField{{SupportedExtensions}},
+ carrier [12] Carrier OPTIONAL,
+ ...
+}
+
+-- For the OPTIONAL parameters, refer to clause 3 for the trigger detection point processing rules
+-- to specify when these parameters are included in the message.
+OriginationAttemptAuthorizedArg ::= SEQUENCE {
+ dpSpecificCommonParameters [0] DpSpecificCommonParameters,
+ dialledDigits [1] CalledPartyNumber OPTIONAL,
+ callingPartyBusinessGroupID [2] CallingPartyBusinessGroupID OPTIONAL,
+ callingPartySubaddress [3] CallingPartySubaddress OPTIONAL,
+ callingFacilityGroup [4] FacilityGroup OPTIONAL,
+ callingFacilityGroupMember [5] FacilityGroupMember OPTIONAL,
+ travellingClassMark [6] TravellingClassMark OPTIONAL,
+ extensions
+ [7] SEQUENCE SIZE (1..numOfExtensions) OF
+ ExtensionField{{SupportedExtensions}},
+ carrier [8] Carrier OPTIONAL,
+ ...
+}
+
+-- For the OPTIONAL parameters, refer to clause 3 for the trigger detection point processing rules
+-- to specify when these parameters are included in the message.
+PlayAnnouncementArg ::= SEQUENCE {
+ informationToSend [0] InformationToSend,
+ disconnectFromIPForbidden [1] BOOLEAN DEFAULT TRUE,
+ requestAnnouncementComplete [2] BOOLEAN DEFAULT TRUE,
+ extensions
+ [3] SEQUENCE SIZE (1..numOfExtensions) OF
+ ExtensionField{{SupportedExtensions}},
+ ...
+}
+
+PromptAndCollectUserInformationArg ::= SEQUENCE {
+ collectedInfo [0] CollectedInfo,
+ disconnectFromIPForbidden [1] BOOLEAN DEFAULT TRUE,
+ informationToSend [2] InformationToSend OPTIONAL,
+ extensions
+ [3] SEQUENCE SIZE (1..numOfExtensions) OF
+ ExtensionField{{SupportedExtensions}},
+ ...
+}
+
+ReceivedInformationArg ::= CHOICE {
+ digitsResponse [0] Digits,
+ iA5Response [1] IA5String
+}
+
+ReleaseCallArg ::= Cause
+
+-- A default value of decimal 31 (normal unspecified) should be coded appropriately.
+RequestCurrentStatusReportArg ::=
+ ResourceID
+
+RequestCurrentStatusReportResultArg ::= SEQUENCE {
+ resourceStatus [0] ResourceStatus,
+ resourceID [1] ResourceID OPTIONAL,
+ extensions
+ [2] SEQUENCE SIZE (1..numOfExtensions) OF
+ ExtensionField{{SupportedExtensions}},
+ ...
+}
+
+RequestEveryStatusChangeReportArg ::= SEQUENCE {
+ resourceID [0] ResourceID,
+ correlationID [1] CorrelationID OPTIONAL,
+ monitorDuration [2] Duration OPTIONAL,
+ extensions
+ [3] SEQUENCE SIZE (1..numOfExtensions) OF
+ ExtensionField{{SupportedExtensions}},
+ ...
+}
+
+-- For correlationID OPTIONAL denotes network operator optional.
+-- monitorDuration is required if outside the context of a call. It is not expected if we are in the context
+-- of a call, because in that case the end of the call implicitly means the end of the monitoring.
+RequestFirstStatusMatchReportArg ::= SEQUENCE {
+ resourceID [0] ResourceID OPTIONAL,
+ resourceStatus [1] ResourceStatus OPTIONAL,
+ correlationID [2] CorrelationID OPTIONAL,
+ monitorDuration [3] Duration OPTIONAL,
+ extensions
+ [4] SEQUENCE SIZE (1..numOfExtensions) OF
+ ExtensionField{{SupportedExtensions}},
+ bearerCapability [5] BearerCapability OPTIONAL,
+ ...
+}
+
+-- For correlationID OPTIONAL denotes network operator optional.
+-- monitorDuration is required if outside the context of a call. It is not expected if we are in the context
+-- of a call, because in that case the end of the call implicitly means the end of the monitoring.
+RequestNotificationChargingEventArg ::=
+ SEQUENCE SIZE (1..numOfChargingEvents) OF ChargingEvent
+
+RequestReportBCSMEventArg ::= SEQUENCE {
+ bcsmEvents [0] SEQUENCE SIZE (1..numOfBCSMEvents) OF BCSMEvent,
+ bcsmEventCorrelationID [1] CorrelationID OPTIONAL,
+ extensions
+ [2] SEQUENCE SIZE (1..numOfExtensions) OF
+ ExtensionField{{SupportedExtensions}},
+ ...
+}
+
+-- Indicates the BCSM related events for notification.
+-- For correlationID OPTIONAL denotes network operator optional.
+ResetTimerArg ::= SEQUENCE {
+ timerID [0] TimerID DEFAULT tssf,
+ timervalue [1] TimerValue,
+ extensions
+ [2] SEQUENCE SIZE (1..numOfExtensions) OF
+ ExtensionField{{SupportedExtensions}},
+ ...
+}
+
+RouteSelectFailureArg ::= SEQUENCE {
+ dpSpecificCommonParameters [0] DpSpecificCommonParameters,
+ dialledDigits [1] CalledPartyNumber OPTIONAL,
+ callingPartyBusinessGroupID [2] CallingPartyBusinessGroupID OPTIONAL,
+ callingPartySubaddress [3] CallingPartySubaddress OPTIONAL,
+ callingFacilityGroup [4] FacilityGroup OPTIONAL,
+ callingFacilityGroupMember [5] FacilityGroupMember OPTIONAL,
+ failureCause [6] Cause OPTIONAL,
+ originalCalledPartyID [7] OriginalCalledPartyID OPTIONAL,
+ prefix [8] Digits OPTIONAL,
+ redirectingPartyID [9] RedirectingPartyID OPTIONAL,
+ redirectionInformation [10] RedirectionInformation OPTIONAL,
+ routeList [11] RouteList OPTIONAL,
+ travellingClassMark [12] TravellingClassMark OPTIONAL,
+ extensions
+ [13] SEQUENCE SIZE (1..numOfExtensions) OF
+ ExtensionField{{SupportedExtensions}},
+ carrier [14] Carrier OPTIONAL,
+ ...
+}
+
+-- For the OPTIONAL parameters, refer to clause 3 for the trigger detection point processing
+-- rules to specify when these parameters are included in the message.
+SelectFacilityArg ::= SEQUENCE {
+ alertingPattern [0] AlertingPattern OPTIONAL,
+ destinationNumberRoutingAddress [1] CalledPartyNumber OPTIONAL,
+ iSDNAccessRelatedInformation [2] ISDNAccessRelatedInformation OPTIONAL,
+ calledFacilityGroup [3] FacilityGroup OPTIONAL,
+ calledFacilityGroupMember [4] FacilityGroupMember OPTIONAL,
+ originalCalledPartyID [5] OriginalCalledPartyID OPTIONAL,
+ extensions
+ [6] SEQUENCE SIZE (1..numOfExtensions) OF
+ ExtensionField{{SupportedExtensions}},
+ ...
+}
+
+-- OPTIONAL parameters are only provided if modifications desired to basic call processing values.
+SelectRouteArg ::= SEQUENCE {
+ destinationRoutingAddress [0] DestinationRoutingAddress,
+ alertingPattern [1] AlertingPattern OPTIONAL,
+ correlationID [2] CorrelationID OPTIONAL,
+ iSDNAccessRelatedInformation [3] ISDNAccessRelatedInformation OPTIONAL,
+ originalCalledPartyID [4] OriginalCalledPartyID OPTIONAL,
+ routeList [5] RouteList OPTIONAL,
+ scfID [6] ScfID OPTIONAL,
+ travellingClassMark [7] TravellingClassMark OPTIONAL,
+ extensions
+ [8] SEQUENCE SIZE (1..numOfExtensions) OF
+ ExtensionField{{SupportedExtensions}},
+ carrier [9] Carrier OPTIONAL,
+ ...
+}
+
+-- OPTIONAL parameters are only provided if modifications desired to basic call processing values.
+SendChargingInformationArg ::= SEQUENCE {
+ sCIBillingChargingCharacteristics [0] SCIBillingChargingCharacteristics,
+ partyToCharge [1] LegID,
+ extensions
+ [2] SEQUENCE SIZE (1..numOfExtensions) OF
+ ExtensionField{{SupportedExtensions}},
+ ...
+}
+
+ServiceFilteringResponseArg ::= SEQUENCE {
+ countersValue [0] CountersValue,
+ filteringCriteria [1] FilteringCriteria,
+ extensions
+ [2] SEQUENCE SIZE (1..numOfExtensions) OF
+ ExtensionField{{SupportedExtensions}},
+ responseCondition [3] ResponseCondition OPTIONAL,
+ ...
+}
+
+SpecializedResourceReportArg ::= NULL
+
+StatusReportArg ::= SEQUENCE {
+ resourceStatus [0] ResourceStatus OPTIONAL,
+ correlationID [1] CorrelationID OPTIONAL,
+ resourceID [2] ResourceID OPTIONAL,
+ extensions
+ [3] SEQUENCE SIZE (1..numOfExtensions) OF
+ ExtensionField{{SupportedExtensions}},
+ reportCondition [4] ReportCondition OPTIONAL,
+ ...
+}
+
+-- For correlationID, OPTIONAL denotes network operator optional.
+-- resourceID is required when the SSF sends a report as an answer to a previous request when the
+-- correlationID was present.
+TAnswerArg ::= SEQUENCE {
+ dpSpecificCommonParameters [0] DpSpecificCommonParameters,
+ calledPartyBusinessGroupID [1] CalledPartyBusinessGroupID OPTIONAL,
+ calledPartySubaddress [2] CalledPartySubaddress OPTIONAL,
+ calledFacilityGroup [3] FacilityGroup OPTIONAL,
+ calledFacilityGroupMember [4] FacilityGroupMember OPTIONAL,
+ extensions
+ [5] SEQUENCE SIZE (1..numOfExtensions) OF
+ ExtensionField{{SupportedExtensions}},
+ ...
+}
+
+TBusyArg ::= SEQUENCE {
+ dpSpecificCommonParameters [0] DpSpecificCommonParameters,
+ busyCause [1] Cause OPTIONAL,
+ calledPartyBusinessGroupID [2] CalledPartyBusinessGroupID OPTIONAL,
+ calledPartySubaddress [3] CalledPartySubaddress OPTIONAL,
+ originalCalledPartyID [4] OriginalCalledPartyID OPTIONAL,
+ redirectingPartyID [5] RedirectingPartyID OPTIONAL,
+ redirectionInformation [6] RedirectionInformation OPTIONAL,
+ routeList [7] RouteList OPTIONAL,
+ travellingClassMark [8] TravellingClassMark OPTIONAL,
+ extensions
+ [9] SEQUENCE SIZE (1..numOfExtensions) OF
+ ExtensionField{{SupportedExtensions}},
+ ...
+}
+
+-- For the OPTIONAL parameters, refer to clause 3 for the trigger detection point processing rules
+-- to specify when these parameters are included in the message.
+TDisconnectArg ::= SEQUENCE {
+ dpSpecificCommonParameters [0] DpSpecificCommonParameters,
+ calledPartyBusinessGroupID [1] CalledPartyBusinessGroupID OPTIONAL,
+ calledPartySubaddress [2] CalledPartySubaddress OPTIONAL,
+ calledFacilityGroup [3] FacilityGroup OPTIONAL,
+ calledFacilityGroupMember [4] FacilityGroupMember OPTIONAL,
+ releaseCause [5] Cause OPTIONAL,
+ extensions
+ [6] SEQUENCE SIZE (1..numOfExtensions) OF
+ ExtensionField{{SupportedExtensions}},
+ connectTime [7] Integer4 OPTIONAL,
+ ...
+}
+
+TermAttemptAuthorizedArg ::= SEQUENCE {
+ dpSpecificCommonParameters [0] DpSpecificCommonParameters,
+ calledPartyBusinessGroupID [1] CalledPartyBusinessGroupID OPTIONAL,
+ calledPartySubaddress [2] CalledPartySubaddress OPTIONAL,
+ callingPartyBusinessGroupID [3] CallingPartyBusinessGroupID OPTIONAL,
+ originalCalledPartyID [4] OriginalCalledPartyID OPTIONAL,
+ redirectingPartyID [5] RedirectingPartyID OPTIONAL,
+ redirectionInformation [6] RedirectionInformation OPTIONAL,
+ routeList [7] RouteList OPTIONAL,
+ travellingClassMark [8] TravellingClassMark OPTIONAL,
+ extensions
+ [9] SEQUENCE SIZE (1..numOfExtensions) OF
+ ExtensionField{{SupportedExtensions}},
+ ...
+}
+
+TNoAnswerArg ::= SEQUENCE {
+ dpSpecificCommonParameters [0] DpSpecificCommonParameters,
+ calledPartyBusinessGroupID [1] CalledPartyBusinessGroupID OPTIONAL,
+ calledPartySubaddress [2] CalledPartySubaddress OPTIONAL,
+ calledFacilityGroup [3] FacilityGroup OPTIONAL,
+ calledFacilityGroupMember [4] FacilityGroupMember OPTIONAL,
+ originalCalledPartyID [5] OriginalCalledPartyID OPTIONAL,
+ redirectingPartyID [6] RedirectingPartyID OPTIONAL,
+ redirectionInformation [7] RedirectionInformation OPTIONAL,
+ travellingClassMark [8] TravellingClassMark OPTIONAL,
+ extensions
+ [9] SEQUENCE SIZE (1..numOfExtensions) OF
+ [3] ExtensionField{{SupportedExtensions}},
+ ...
+}
+
+-- The Definition of Common Data Types
+AccessCode ::= LocationNumber
+
+-- An access code from a business group dialling plan attendant access codes, access codes to escape
+-- to the public network, access code to access a private facility/network, and feature access codes.
+-- Uses the LocationNumber format which is based on the Q.763 Location Number format.
+-- The Nature of Address indicator field shall be set to "Spare" (value 00000000).
+-- The Numbering Plan Indicator field shall be set to "Spare" (value 000).
+-- Of local significance.
+AChBillingChargingCharacteristics ::=
+ OCTET STRING(SIZE (minAChBillingChargingLength..maxAChBillingChargingLength))
+
+-- The AChBillingChargingCharacteristics parameter specifies the charging related information
+-- to be provided by the SSF and the conditions on which this information has to be reported
+-- back to the SCF with the ApplyChargingReport operation.
+-- Examples of charging related information to be provided by the SSF may be: bulk counter
+-- values, costs, tariff change and time of charge, time stamps, durations, etc.
+-- Examples of conditions on which the charging related information are to be reported may be:
+-- threshold value reached, timer expiration, tariff change, end of connection configuration, etc.
+AdditionalCallingPartyNumber ::=
+ Digits
+
+-- Indicates the Additional Calling Party Number. Refer to Recommendation Q.763 for encoding.
+AlertingPattern ::= OCTET STRING(SIZE (3))
+
+-- Indicates a specific pattern that is used to alert a subscriber (e.g. distinctive ringing, tones, etc.).
+-- Only applies if SSF is the terminating local exchange for the subscriber. Refer to the Q.931
+-- Signal parameter for encoding.
+ApplicationTimer ::= INTEGER(0..2047)
+
+-- Used by the SCF to set a timer in the SSF. The timer is in seconds.
+AssistingSSPIPRoutingAddress ::=
+ Digits
+
+-- Indicates the destination address of the SRF for the assist procedure.
+BCSMEvent ::= SEQUENCE {
+ eventTypeBCSM [0] EventTypeBCSM,
+ monitorMode [1] MonitorMode,
+ legID [2] LegID OPTIONAL,
+ dpSpecificCriteria [30] DpSpecificCriteria OPTIONAL
+}
+
+-- Indicates the BCSM Event information for monitoring.
+BearerCapability ::= CHOICE {
+ bearerCap [0] OCTET STRING(SIZE (2..maxBearerCapabilityLength)),
+ tmr [1] OCTET STRING(SIZE (1))
+}
+
+-- Indicates the type of bearer capability connection to the user. For bearerCapability, either
+-- DSS 1 (Q.931) or the ISUP User Service Information (Q.763) encoding can be used. Refer
+-- to the Q.763 Transmission Medium Requirement parameter for tmr encoding.
+CalledPartyBusinessGroupID ::= OCTET STRING
+
+-- Indicates the business group of the called party. The value of this octet string is network
+-- operator specific.
+CalledPartyNumber ::=
+ OCTET STRING(SIZE (minCalledPartyNumberLength..maxCalledPartyNumberLength))
+
+-- Indicates the Called Party Number. Refer to Recommendation Q.763 for encoding.
+CalledPartySubaddress ::= OCTET STRING
+
+-- Indicates the Called Party Subaddress. Refer to Recommendation Q.931 for encoding.
+CallingPartyBusinessGroupID ::= OCTET STRING
+
+-- Indicates the business group of the calling party. The value of this octet string is network
+-- operator specific.
+CallingPartyNumber ::=
+ OCTET STRING(SIZE (minCallingPartyNumberLength..maxCallingPartyNumberLength))
+
+-- Indicates the Calling Party Number. Refer to Recommendation Q.763 for encoding.
+CallingPartySubaddress ::= OCTET STRING
+
+-- Indicates the Calling Party Subaddress. Refer to Recommendation Q.931 for encoding.
+CallingPartysCategory ::= OCTET STRING(SIZE (1))
+
+-- Indicates the type of calling party (e.g. operator, payphone, ordinary subscriber).
+-- Refer to Recommendation Q.763 for encoding.
+CallResult ::= OCTET STRING(SIZE (minCallResultLength..maxCallResultLength))
+
+-- This parameter provides the SCF with the charging related information previously requested
+-- using the ApplyCharging operation. This shall include the partyToCharge parameter as
+-- received in the related ApplyCharging operation to correlate the result to the request.
+-- The remaining content is network operator specific.
+-- Examples of charging related information to be provided by the SSF may be: bulk counter values,
+-- costs, tariff change and time of change, time stamps, durations, etc.
+-- Examples of conditions on which the charging related information are to be reported may be:
+-- threshold value reached, timer expiration, tariff change, end of connection configuration, etc.
+Carrier ::= OCTET STRING
+
+-- Contains the carrier selection and carrier ID fields.
+-- Carrier selection is one octet and is encoded as:
+-- 00000000 No indication
+-- 00000001 Selected carrier code pre subscribed and not input by calling party
+-- 00000010 Selected carrier identification code pre subscribed and input by calling party
+-- 00000011 Selected carrier identification code pre subscribed, no indication of whether input by calling party
+-- 00000100 Selected carrier identification code not pre subscribed and input by calling party
+-- 00000101
+-- to Spare
+-- 11111110
+-- 11111111 Reserved
+--
+-- Carrier ID has a one octet field indicating the number of digits followed by the digits encoded using BCD.
+-- Detailed coding is for further study. It is of local significance and carrying it through the ISUP is for further
+-- study.
+Cause ::= OCTET STRING(SIZE (minCauseLength..maxCauseLength))
+
+-- Indicates the cause for interface related information. Refer to the Q.763 Cause parameter for
+-- encoding.
+-- For the use of cause and location values refer to Recommendation Q.850.
+CGEncountered ::= ENUMERATED {
+ noCGencountered(0), manualCGencountered(1), scpOverload(2)}
+
+-- Indicates the type of automatic call gapping encountered, if any.
+ChargeNumber ::=
+ LocationNumber
+
+-- Information sent in either direction indicating the chargeable number for the call and consisting
+-- of the odd/even indicator, nature of address indicator, numbering plan indicator, and address signals.
+-- Uses the LocationNumber format which is based on the Q.763 Location Number format.
+-- For example, the ChargeNumber may be a third party number to which a call is billed for the 3rd party
+-- billing service. In this case, the calling party may request operator assistance to charge the call to,
+-- for example, their home number.
+ChargingEvent ::= SEQUENCE {
+ eventTypeCharging [0] EventTypeCharging,
+ monitorMode [1] MonitorMode,
+ legID [2] LegID OPTIONAL
+}
+
+-- This parameter indicates the charging event type and corresponding
+-- monitor mode and LedID.
+CollectedDigits ::= SEQUENCE {
+ minimumNbOfDigits [0] INTEGER(1..127) DEFAULT 1,
+ maximumNbOfDigits [1] INTEGER(1..127),
+ endOfReplyDigit [2] OCTET STRING(SIZE (1..2)) OPTIONAL,
+ cancelDigit [3] OCTET STRING(SIZE (1..2)) OPTIONAL,
+ startDigit [4] OCTET STRING(SIZE (1..2)) OPTIONAL,
+ firstDigitTimeOut [5] INTEGER(1..127) OPTIONAL,
+ interDigitTimeOut [6] INTEGER(1..127) OPTIONAL,
+ errorTreatment [7] ErrorTreatment DEFAULT reportErrorToScf,
+ interruptableAnnInd [8] BOOLEAN DEFAULT TRUE,
+ voiceInformation [9] BOOLEAN DEFAULT FALSE,
+ voiceBack [10] BOOLEAN DEFAULT FALSE
+}
+
+-- The use of voiceBack is network operator specific.
+-- The endOfReplyDigit, cancelDigit, and startDigit parameters have been designated as OCTET STRING,
+-- and are to be encoded as BCD, one digit per octet only, contained
+-- in the four least significant bits of each OCTET. The usage is service dependent.
+CollectedInfo ::= CHOICE {
+ collectedDigits [0] CollectedDigits,
+ iA5Information [1] BOOLEAN
+}
+
+ControlType ::= ENUMERATED {
+ sCPOverloaded(0), manuallyInitiated(1), destinationOverload(2)
+ -- other values FFS
+ }
+
+CorrelationID ::= Digits
+
+-- used by SCF for correlation with a previous operation. Refer to clause 3 for a description of the
+-- procedures associated with this parameter.
+CounterAndValue ::= SEQUENCE {
+ counterID [0] CounterID,
+ counterValue [1] Integer4
+}
+
+CounterID ::= INTEGER(0..99)
+
+-- Indicates the counters to be incremented.
+-- The counterIDs can be addressed by using the last digits of the dialled number.
+CountersValue ::= SEQUENCE SIZE (0..numOfCounters) OF CounterAndValue
+
+CutAndPaste ::= INTEGER(0..22)
+
+-- Indicates the number of digits to be deleted. Refer to 6.4.2.16/Q.1214 for additional information.
+DateAndTime ::= OCTET STRING(SIZE (6))
+
+-- Indicates, amongst others, the start time for activate service filtering. Coded as YYMMDDHHMMSS
+-- with each digit coded BCD.
+-- The first octet contains YY and the remaining items are sequenced following.
+-- For example, 1993 September 30th, 12:15:01 would be encoded as:
+-- Bits HGFE DCBA
+-- leading octet 3 9
+-- 9 0
+-- 0 3
+-- 2 1
+-- 5 1
+-- 1 0
+DestinationRoutingAddress ::= SEQUENCE SIZE (1..3) OF CalledPartyNumber
+
+-- Indicates the list of Called Party Numbers (primary and alternates).
+Digits ::= OCTET STRING(SIZE (minDigitsLength..maxDigitsLength))
+
+-- Indicates the address signalling digits. Refer to the Q.763 Generic Number and Generic Digits parameters
+-- for encoding. The coding of the subfields 'NumberQualifier' in Generic Number and 'TypeOfDigits' in
+-- Generic Digits are irrelevant to the INAP, the ASN.1 tags are sufficient to identify the parameter.
+-- The ISUP format does not allow to exclude these subfields, therefore the value is network operator specific.
+-- The following parameters should use Generic Number:
+-- CorrelationID for AssistRequestInstructions, AssistingSSPIPRoutingAddress for
+-- EstablishTemporaryConnection, calledAddressValue for all occurrences, callingAddressValue for all
+-- occurrences. The following parameters should use Generic Digits: prefix, all
+-- other CorrelationID occurrences, dialledNumber filtering criteria, callingLineID filtering criteria, lineID
+-- for ResourceID type, digitResponse for ReceivedInformationArg.
+DisplayInformation ::=
+ IA5String(SIZE (minDisplayInformationLength..maxDisplayInformationLength))
+
+-- Indicates the display information.
+DpSpecificCriteria ::= CHOICE {
+ numberOfDigits [0] NumberOfDigits,
+ applicationTimer [1] ApplicationTimer
+}
+
+-- The SCF may specify the number of digits to be collected by the SSF for the CollectedInfo event.
+-- When all digits are collected, the SSF reports the event to the SCF.
+-- The SCF may set a timer in the SSF for the No Answer event. If the user does not answer the call
+-- within the allotted time, the SSF reports the event to the SCF.
+Duration ::= INTEGER(-2..86400)
+
+-- Values are seconds.
+ErrorTreatment ::= ENUMERATED {reportErrorToScf(0), help(1), repeatPrompt(2)
+}
+
+-- reportErrorToScf means returning the "ImproperCallerResponse" error in the event of an error
+-- condition during collection of user info.
+EventSpecificInformationBCSM ::= CHOICE {
+ collectedInfoSpecificInfo
+ [0] SEQUENCE {calledPartynumber [0] CalledPartyNumber,
+ ...},
+ analyzedInfoSpecificInfo
+ [1] SEQUENCE {calledPartynumber [0] CalledPartyNumber,
+ ...},
+ routeSelectFailureSpecificInfo
+ [2] SEQUENCE {failureCause [0] Cause OPTIONAL,
+ ...},
+ oCalledPartyBusySpecificInfo
+ [3] SEQUENCE {busyCause [0] Cause OPTIONAL,
+ ...},
+ oNoAnswerSpecificInfo
+ [4] SEQUENCE {-- no specific info defined
+ ...},
+ oAnswerSpecificInfo
+ [5] SEQUENCE {-- no specific info defined
+ ...},
+ oMidCallSpecificInfo
+ [6] SEQUENCE {connectTime [0] Integer4 OPTIONAL,
+ ...},
+ oDisconnectSpecificInfo
+ [7] SEQUENCE {releaseCause [0] Cause OPTIONAL,
+ connectTime [1] Integer4 OPTIONAL,
+ ...},
+ tBusySpecificInfo
+ [8] SEQUENCE {busyCause [0] Cause OPTIONAL,
+ ...},
+ tNoAnswerSpecificInfo
+ [9] SEQUENCE {-- no specific info defined
+ ...},
+ tAnswerSpecificInfo
+ [10] SEQUENCE {-- no specific info defined
+ ...},
+ tMidCallSpecificInfo
+ [11] SEQUENCE {connectTime [0] Integer4 OPTIONAL,
+ ...},
+ tDisconnectSpecificInfo
+ [12] SEQUENCE {releaseCause [0] Cause OPTIONAL,
+ connectTime [1] Integer4 OPTIONAL,
+ ...}
+}
+
+-- Indicates the call related information specific to the event.
+-- The connectTime indicates the duration between the received answer indication from the called party side
+-- and the release of the connection for ODisconnect, OException, TDisconnect, or TException events.
+-- The unit for the connectTime is 100 milliseconds.
+EventSpecificInformationCharging ::=
+ OCTET STRING
+ (SIZE (minEventSpecificInformationChargingLength..
+ maxEventSpecificInformationChargingLength))
+
+-- defined by network operator.
+-- Indicates the charging related information specific to the event.
+-- An example data type definition for this parameter is given below:
+-- chargePulses [0] Integer4,
+-- chargeMessages [1] OCTET STRING (SIZE (min..max))
+EventTypeBCSM ::= ENUMERATED {
+ origAttemptAuthorized(1), collectedInfo(2), analysedInformation(3),
+ routeSelectFailure(4), oCalledPartyBusy(5), oNoAnswer(6), oAnswer(7),
+ oMidCall(8), oDisconnect(9), oAbandon(10), termAttemptAuthorized(12),
+ tBusy(13), tNoAnswer(14), tAnswer(15), tMidCall(16), tDisconnect(17),
+ tAbandon(18)}
+
+-- Indicates the BCSM detection point event. Refer to 4.2.2.2/Q.1214 for additional information on the
+-- events. Values origAttemptAuthorized and termAttemptAuthorized can only be used for TDPs.
+EventTypeCharging ::=
+ OCTET STRING(SIZE (minEventTypeChargingLength..maxEventTypeChargingLength))
+
+-- This parameter indicates the charging event type. Its content is network operator specific.
+--
+-- An example data type definition for this parameter is given below:
+-- EventTypeCharging ::= ENUMERATED {
+-- chargePulses (0),
+-- chargeMessages (1)
+-- }
+EXTENSION ::= CLASS {
+ &id ExtensionType UNIQUE,
+ &Type OPTIONAL,
+ &absent &Type OPTIONAL,
+ &criticality Criticality DEFAULT ignored
+}
+WITH SYNTAX {
+ [EXTENSION-SYNTAX &Type
+ [IF ABSENT &absent]]
+ [CRITICALITY &criticality]
+ IDENTIFIED BY &id
+}
+
+ExtensionType ::= INTEGER(0..MAX)
+
+Criticality ::= ENUMERATED {ignored(0), abort(1)}
+
+ExtensionField{EXTENSION:ChosenFrom} ::= SEQUENCE {
+ type EXTENSION.&id({ChosenFrom}),
+ criticality Criticality DEFAULT ignored,
+ value [1] EXTENSION.&Type({ChosenFrom}{@type})
+}
+
+-- This parameter indicates an extension of an argument data type. Its content is network operator specific.
+SupportedExtensions EXTENSION ::=
+ {...}
+
+FacilityGroup ::= CHOICE {
+ trunkGroupID [0] INTEGER,
+ privateFacilityID [1] INTEGER,
+ huntGroup [2] OCTET STRING,
+ routeIndex [3] OCTET STRING
+}
+
+-- Indicates the particular group of facilities to route the call. huntGroup and routeIndex are encoded as
+-- network operator specific.
+FacilityGroupMember ::= INTEGER
+
+-- Indicates the specific member of a trunk group or multi-line hunt group.
+FCIBillingChargingCharacteristics ::=
+ OCTET STRING(SIZE (minFCIBillingChargingLength..maxFCIBillingChargingLength))
+
+-- This parameter indicates the billing and/or charging characteristics. Its content is network operator
+-- specific. An example datatype definition for this parameter is given below:
+-- FCIBillingChargingCharacteristics ::= CHOICE {
+-- completeChargingrecord [0] OCTET STRING (SIZE (min..max)),
+-- correlationID [1] CorrelationID,
+-- scenario2Dot3 [2] SEQUENCE {
+-- chargeParty [0] LegID OPTIONAL,
+-- chargeLevel [1] OCTET STRING (SIZE (min..max))
+-- OPTIONAL,
+-- chargeItems [2] SET OF Attribute OPTIONAL
+-- }
+-- }
+-- Depending on the applied charging scenario, the following information elements can be included
+-- (refer to Q.1214 Appendix II):
+-- complete charging record (scenario 2.2)
+-- charge party (scenario 2.3)
+-- charge level (scenario 2.3)
+-- charge items (scenario 2.3)
+-- correlationID (scenario 2.4)
+FeatureCode ::=
+ LocationNumber
+
+-- The two-digit feature code preceded by "*" or "11".
+-- Uses the LocationNumber format which is based on the Q.763 Location Number format.
+-- The Nature of Address indicator field shall be set to "Spare" (value 00000000).
+-- The Numbering Plan Indicator field shall be set to "Spare" (value 000).
+-- Used for stimulus signalling (Q.932).
+FeatureRequestIndicator ::= ENUMERATED {
+ hold(0), retrieve(1), featureActivation(2), spare1(3), sparen(127)}
+
+-- Indicates the feature activated (e.g. a switch-hook flash, feature activation). Spare values reserved
+-- for future use.
+FilteredCallTreatment ::= SEQUENCE {
+ sFBillingChargingCharacteristics [0] SFBillingChargingCharacteristics,
+ informationToSend [1] InformationToSend OPTIONAL,
+ maximumNumberOfCounters [2] MaximumNumberOfCounters OPTIONAL,
+ releaseCause [3] Cause OPTIONAL
+}
+
+-- If releaseCause is not present, the default value is the same as the ISUP cause value decimal 31.
+-- If informationToSend is present, the call will be released after the end of the announcement
+-- with the indicated or default releaseCause.
+-- If maximumNumberOfCounters is not present, ServiceFilteringResponse will be sent with
+-- CountersValue::= SEQUENCE SIZE (0) OF CountersAndValue.
+FilteringCharacteristics ::= CHOICE {
+ interval [0] INTEGER(-1..32000),
+ numberOfCalls [1] Integer4
+}
+
+-- Indicates the severity of the filtering and the point in time when the ServiceFilteringResponse is to be sent.
+-- If = interval, every interval of time the next call leads to an InitialDP and a ServiceFilteringResponse is
+-- sent to the SCF. The interval is specified in seconds.
+-- If = NumberOfCalls, every N calls the Nth call leads to an InitialDP and a ServiceFilteringResponse
+-- is sent to the SCF.
+-- If ActivateServiceFiltering implies several counters - filtering on several dialled numbers -,
+-- the numberOfCalls would include calls to all the dialled numbers.
+FilteringCriteria ::= CHOICE {
+ dialledNumber [0] Digits,
+ callingLineID [1] Digits,
+ serviceKey [2] ServiceKey,
+ addressAndService
+ [30] SEQUENCE {calledAddressValue [0] Digits,
+ serviceKey [1] ServiceKey,
+ callingAddressValue [2] Digits OPTIONAL,
+ locationNumber [3] LocationNumber OPTIONAL
+ }
+}
+
+-- In case calledAddressValue is specified, the numbers to be filtered are from calledAddressValue
+-- up to and including calledAddressValue + maximumNumberOfCounters-1.
+-- The last two digits of calledAddressvalue can not exceed 100-maximumNumberOfCounters.
+FilteringTimeOut ::= CHOICE {
+ duration [0] Duration,
+ stopTime [1] DateAndTime
+}
+
+-- Indicates the maximum duration of the filtering. When the timer expires, a ServiceFilteringResponse
+-- is sent to the SCF.
+ForwardCallIndicators ::= OCTET STRING(SIZE (2))
+
+-- Indicates the Forward Call Indicators. Refer to Recommendation Q.763 for encoding.
+ForwardingCondition ::= ENUMERATED {busy(0), noanswer(1), any(2)}
+
+-- Indicates the condition that must be met to complete the connect.
+GapCriteria ::= CHOICE {
+ calledAddressValue [0] Digits,
+ gapOnService [2] GapOnService,
+ calledAddressAndService
+ [29] SEQUENCE {calledAddressValue [0] Digits,
+ serviceKey [1] ServiceKey},
+ callingAddressAndService
+ [30] SEQUENCE {callingAddressValue [0] Digits,
+ serviceKey [1] ServiceKey,
+ locationNumber [2] LocationNumber OPTIONAL
+ }
+}
+
+-- Both calledAddressValue and callingAddressValue can be
+-- incomplete numbers, in the sense that a limited amount of digits can be given.
+--
+-- For the handling of numbers starting with the same digit string, refer to the detailed procedure
+-- of the CallGap operation in 3.3.
+GapOnService ::= SEQUENCE {
+ serviceKey [0] ServiceKey,
+ dpCriteria [1] EventTypeBCSM OPTIONAL
+}
+
+--Recommendation Q.1218 (10/95)
+GapIndicators ::= SEQUENCE {
+ duration [0] Duration,
+ gapInterval [1] Interval
+}
+
+-- Indicates the gapping characteristics. No gapping when gapInterval equals 0, and gap all calls when
+-- gapInterval equals 1.
+GapTreatment ::= CHOICE {
+ informationToSend [0] InformationToSend,
+ releaseCause [1] Cause,
+ both
+ [2] SEQUENCE {informationToSend [0] InformationToSend,
+ releaseCause [1] Cause}
+}
+
+-- The default value for Cause is the same as in ISUP.
+HighLayerCompatibility ::= OCTET STRING(SIZE (highLayerCompatibilityLength))
+
+-- Indicates the teleservice. For encoding, DSS 1 (Q.931) is used.
+HoldCause ::= OCTET STRING -- defined by network operator.
+
+-- Indicates the cause for holding the call.
+InbandInfo ::= SEQUENCE {
+ messageID [0] MessageID,
+ numberOfRepetitions [1] INTEGER(1..127) OPTIONAL,
+ duration [2] INTEGER(0..32767) OPTIONAL,
+ interval [3] INTEGER(0..32767) OPTIONAL
+}
+
+-- Interval is the time in seconds between each repeated announcement. Duration is the total
+-- amount of time in seconds, including repetitions and intervals.
+-- The end of announcement is either the end of duration or numberOfRepetitions, whatever comes first.
+-- Duration with value 0 indicates infinite duration.
+InformationToSend ::= CHOICE {
+ inbandInfo [0] InbandInfo,
+ tone [1] Tone,
+ displayInformation [2] DisplayInformation
+}
+
+Integer4 ::= INTEGER(0..2147483647)
+
+Interval ::= INTEGER(-1..60000)
+
+-- Units are milliseconds. A -1 value denotes infinite.
+InvokeID ::=
+ InvokeIdType
+
+-- Operation invoke identifier.
+IPAvailable ::= OCTET STRING(SIZE (minIPAvailableLength..maxIPAvailableLength))
+
+-- defined by network operator.
+-- Indicates that the resource is available.
+IPRoutingAddress ::=
+ CalledPartyNumber
+
+-- Indicates the routing address for the IP.
+IPSSPCapabilities ::=
+ OCTET STRING(SIZE (minIPSSPCapabilitiesLength..maxIPSSPCapabilitiesLength))
+
+-- defined by network operator.
+-- Indicates the SRF resources available at the SSP.
+ISDNAccessRelatedInformation ::= OCTET STRING
+
+-- Indicates the destination user network interface related information. Refer to the Q.763 Access
+-- Transport parameter for encoding.
+LegID ::= CHOICE {sendingSideID [0] LegType,
+ receivingSideID [1] LegType
+}
+
+-- Indicates a reference to a specific party in a call. OPTIONAL denotes network operator specific use
+-- with a choice of unilateral ID assignment or bilateral ID assignment.
+-- OPTIONAL for LegID also denotes the following:
+-- - when only one party exists in the call, this parameter is not needed (as no ambiguity exists);
+-- - when more than one party exists in the call, one of the following alternatives applies:
+-- 1. LegID is present and indicates which party is concerned.
+-- 2. LegID is not present and a default value is assumed (e.g. calling party in the case of the
+-- ApplyCharging operation).
+-- Choice between these two alternatives is kept a network operator option.
+LegType ::= OCTET STRING(SIZE (1))
+
+leg1 LegType ::= '01'H
+
+leg2 LegType ::= '02'H
+
+LocationNumber ::=
+ OCTET STRING(SIZE (minLocationNumberLength..maxLocationNumberLength))
+
+-- Indicates the Location Number for the calling party. Refer to Recommendation Q.763 (White book) for encoding.
+MaximumNumberOfCounters ::= INTEGER(1..numOfCounters)
+
+MessageID ::= CHOICE {
+ elementaryMessageID [0] Integer4,
+ text
+ [1] SEQUENCE {messageContent
+ [0] IA5String
+ (SIZE (minMessageContentLength..
+ maxMessageContentLength)),
+ attributes
+ [1] OCTET STRING
+ (SIZE (minAttributesLength..maxAttributesLength))
+ OPTIONAL},
+ elementaryMessageIDs [29] SEQUENCE SIZE (1..numOfMessageIDs) OF Integer4,
+ variableMessage
+ [30] SEQUENCE {elementaryMessageID [0] Integer4,
+ variableParts
+ [1] SEQUENCE SIZE (1..5) OF VariablePart}
+}
+
+-- OPTIONAL denotes network operator specific use.
+MiscCallInfo ::= SEQUENCE {
+ messageType [0] ENUMERATED {request(0), notification(1)},
+ dpAssignment
+ [1] ENUMERATED {individualLine(0), groupBased(1), officeBased(2)} OPTIONAL
+}
+
+-- Indicates detection point related information.
+MonitorMode ::= ENUMERATED {
+ interrupted(0), notifyAndContinue(1), transparent(2)}
+
+-- Indicates the event is relayed and/or processed by the SSP.
+-- If this parameter is used in the context of charging events, the following definitions apply for the
+-- handling of charging events:
+-- Interrupted means that the SSF notifies the SCF of the charging event using
+-- EventNotificationCharging, does not process the event but discard it.
+-- NotifyAndContinue means that SSF notifies the SCF of the charging event using
+-- EventNotificationCharging, and continues processing the event or signal without waiting for SCF
+-- instructions. Transparent means that the SSF does not notify the SCF of the event. This value is used to
+-- end the monitoring of a previously requested charging event. Previously requested charging events are
+-- monitored until ended by a transparent monitor mode, or until the end of the connection configuration.
+-- For the use of this parameter in the context of BCSM events refer to 3.3.39.
+NumberingPlan ::= OCTET STRING(SIZE (1))
+
+-- Indicates the numbering plan for collecting the user information. Refer to the Q.763 Numbering Plan.
+-- Indicator field for encoding.
+NumberOfDigits ::= INTEGER(1..255)
+
+-- Indicates the number of digits to be collected
+OriginalCalledPartyID ::=
+ OCTET STRING
+ (SIZE (minOriginalCalledPartyIDLength..maxOriginalCalledPartyIDLength))
+
+-- Indicates the original called number. Refer to the Q.763 Original Called Number for encoding.
+RedirectingPartyID ::=
+ OCTET STRING(SIZE (minRedirectingPartyIDLength..maxRedirectingPartyIDLength))
+
+-- Indicates redirecting number. Refer to the Q.763 Redirecting number for encoding.
+RedirectionInformation ::= OCTET STRING(SIZE (2))
+
+-- Indicates redirection information. Refer to the Q.763 Redirection Information for encoding.
+ReportCondition ::= ENUMERATED {statusReport(0), timerExpired(1), canceled(2)
+}
+
+-- ReportCondition specifies the cause of sending "StatusReport" operation to the SCF.
+RequestedInformationList ::=
+ SEQUENCE SIZE (1..numOfInfoItems) OF RequestedInformation
+
+RequestedInformationTypeList ::=
+ SEQUENCE SIZE (1..numOfInfoItems) OF RequestedInformationType
+
+RequestedInformation ::= SEQUENCE {
+ requestedInformationType [0] RequestedInformationType,
+ requestedInformationValue [1] RequestedInformationValue
+}
+
+RequestedInformationType ::= ENUMERATED {
+ callAttemptElapsedTime(0), callStopTime(1), callConnectedElapsedTime(2),
+ calledAddress(3), releaseCause(30)}
+
+RequestedInformationValue ::= CHOICE {
+ callAttemptElapsedTimeValue [0] INTEGER(0..255),
+ callStopTimeValue [1] DateAndTime,
+ callConnectedElapsedTimeValue [2] Integer4,
+ calledAddressValue [3] Digits,
+ releaseCauseValue [30] Cause
+}
+
+-- The callAttemptElapsedTimeValue is specified in seconds. The unit for the
+-- callConnectedElapsedTimeValue is 100 milliseconds.
+ResourceID ::= CHOICE {
+ lineID [0] Digits,
+ facilityGroupID [1] FacilityGroup,
+ facilityGroupMemberID [2] INTEGER,
+ trunkGroupID [3] INTEGER
+}
+
+-- Indicates a logical identifier for the physical termination resource.
+ResourceStatus ::= ENUMERATED {busy(0), idle(1)}
+
+ResponseCondition ::= ENUMERATED {intermediateResponse(0), lastResponse(1)
+
+-- additional values are for further study.
+}
+
+-- ResponseCondition is used to identify the reason why ServiceFilteringResponse operation is sent.
+-- intermediateresponse identifies that service filtering is running and the interval time is expired and
+-- a call is received, or that service filtering is running and the threshold value is reached.
+-- lastResponse identifies that the duration time is expired and service filtering has been finished or
+-- that the stop time is met and service filtering has been finished.
+RouteList ::=
+ SEQUENCE SIZE (1..3) OF
+ OCTET STRING(SIZE (minRouteListLength..maxRouteListLength))
+
+-- Indicates a list of trunk groups or a route index. See Recommendation Q.1214 for additional information on this item.
+ScfID ::= OCTET STRING(SIZE (minScfIDLength..maxScfIDLength))
+
+-- defined by network operator.
+-- Indicates the SCF identifier.
+SCIBillingChargingCharacteristics ::=
+ OCTET STRING(SIZE (minSCIBillingChargingLength..maxSCIBillingChargingLength))
+
+-- This parameter indicates the billing and/or charging characteristics. Its content is network operator
+-- specific. An example datatype definition for this parameter is given below:
+-- SCIBillingChargingCharacteristics ::= CHOICE {
+-- chargeLevel [0] OCTET STRING (SIZE (min..max),
+-- chargePulses [1] Integer4,
+-- chargeMessages [2] OCTET STRING (SIZE (min..max)
+-- }
+-- Depending on the applied charging scenario the following information elements
+-- can be included (refer to Appendix II/Q.1214):
+-- chargeLevel (scenario 3.2)
+-- chargePulses (scenario 3.2)
+-- chargeMessages (scenario 3.2)
+ServiceAddressInformation ::= SEQUENCE {
+ serviceKey [0] ServiceKey OPTIONAL,
+ miscCallInfo [1] MiscCallInfo,
+ triggerType [2] TriggerType OPTIONAL
+}
+
+-- Information that represents the result of trigger analysis and allows the SCF to choose the appropriate
+-- service logic.
+ServiceInteractionIndicators ::=
+ OCTET STRING
+ (SIZE (minServiceInteractionIndicatorsLength..
+ maxServiceInteractionIndicatorsLength))
+
+-- Indicators which are exchanged between SSP and SCP to resolve interactions between IN based services
+-- and network based services, respectively between different IN based services.
+-- The contents are network specific and identified as a subject for further study with respect to INAP.
+-- The following example is listed to illustrate the use of this parameter:
+-- CallToBeDiverted Allowed/NotAllowed Indicator
+-- If the CallToBeDiverted indicator is set to NotAllowed, the destination exchange shall not allow any
+-- divertion on the subjected call. By this, each service can pass the applicable indicators to inform the
+-- destination exchange of how specific services are to be handled.
+ServiceKey ::=
+ Integer4
+
+-- Information that allows the SCF to choose the appropriate service logic.
+ServiceProfileIdentifier ::= OCTET STRING
+
+-- Indicates a particular ISDN terminal. Refer to Recommendation Q.932 for encoding.
+ServingAreaID ::=
+ LocationNumber
+
+-- Identifies the local serving area where a network provider operates. Uses the LocationNumber
+-- format which is based on the Q.763 Location Number format.
+-- The Nature of Address indicator field shall be set to "Spare" (value 00000000).
+-- The Numbering Plan Indicator field shall be set to "Spare" (value 000).
+-- Defined by the network operator.
+SFBillingChargingCharacteristics ::=
+ OCTET STRING(SIZE (minSFBillingChargingLength..maxSFBillingChargingLength))
+
+-- This parameter indicates the billing and/or charging characteristics for filtered calls.
+-- Its content is network operator specific.
+TerminalType ::= ENUMERATED {
+ unknown(0), dialPulse(1), dtmf(2), isdn(3), isdnNoDtmf(4), spare(16)
+}
+
+-- Identifies the terminal type so that the SCF can specify, to the SRF, the appropriate type of capability
+-- (voice recognition, DTMF, display capability, etc.). Since present signalling systems do not convey
+-- terminal type, this parameter applies only at originating or terminating local exchanges.
+TimerID ::= ENUMERATED {tssf(0)
+ -- others ffs
+ }
+
+-- Indicates the timer to be reset.
+TimerValue ::= Integer4
+
+-- Indicates the timer value (in seconds).
+Tone ::= SEQUENCE {toneID [0] Integer4,
+ duration [1] Integer4 OPTIONAL
+}
+
+-- The duration specifies the length of the tone in seconds, value 0 indicates infinite duration.
+TravellingClassMark ::=
+ LocationNumber
+
+-- Indicates travelling class mark information.
+-- Uses the LocationNumber format which is based on the Q.763 Location Number format.
+-- The Nature of Address indicator field shall be set to "Spare" (value 00000000).
+-- The Numbering Plan Indicator field shall be set to "Spare" (value 000).
+-- Maximum 2 digits.
+TriggerType ::= ENUMERATED {
+ featureActivation(0), verticalServiceCode(1), customizedAccess(2),
+ customizedIntercom(3), emergencyService(12), aFR(13), sharedIOTrunk(14),
+ offHookDelay(17), channelSetupPRI(18), tNoAnswer(25), tBusy(26),
+ oCalledPartyBusy(27), oNoAnswer(29), originationAttemptAuthorized(30),
+ oAnswer(31), oDisconnect(32), termAttemptAuthorized(33), tAnswer(34),
+ tDisconnect(35)
+ -- Private (ffs)
+ }
+
+-- The type of trigger which caused call suspension
+-- 4-11: Reserved; 15,16: Reserved; 19-24: Reserved
+UnavailableNetworkResource ::= ENUMERATED {
+ unavailableResources(0), componentFailure(1),
+ basicCallProcessingException(2), resourceStatusFailure(3), endUserFailure(4)
+}
+
+-- Indicates the network resource that failed.
+VariablePart ::= CHOICE {
+ integer [0] Integer4,
+ number [1] Digits, -- Generic digits
+ time [2] OCTET STRING(SIZE (2)), -- HH:MM, BCD coded
+ date [3] OCTET STRING(SIZE (3)), -- YYMMDD, BCD coded
+ price [4] OCTET STRING(SIZE (4))
+}
+
+-- Indicates the variable part of the message.
+-- BCD coded variable parts are encoded as described in the examples below.
+-- For example, time = 12:15 would be encoded as:
+-- Bits HGFE DCBA
+-- leading octet 2 1
+-- 5 1
+-- date = 1993 September 30th would be encoded as:
+-- Bits HGFE DCBA
+-- leading octet 3 9
+-- 9 0
+-- 0 3
+-- The Definition of range of constants Follows
+highLayerCompatibilityLength INTEGER ::=
+ 2
+
+minAChBillingChargingLength INTEGER ::= 0 -- network specific
+
+maxAChBillingChargingLength INTEGER ::= 1 -- network specific
+
+minAttributesLength INTEGER ::= 0 -- network specific
+
+maxAttributesLength INTEGER ::= 1 -- network specific
+
+maxBearerCapabilityLength INTEGER ::= 2 -- network specific
+
+minCalledPartyNumberLength INTEGER ::= 0 -- network specific
+
+maxCalledPartyNumberLength INTEGER ::= 1 -- network specific
+
+minCallingPartyNumberLength INTEGER ::= 0 -- network specific
+
+maxCallingPartyNumberLength INTEGER ::= 1 -- network specific
+
+minCallResultLength INTEGER ::= 0 -- network specific
+
+maxCallResultLength INTEGER ::= 1 -- network specific
+
+minCauseLength INTEGER ::= 2
+
+maxCauseLength INTEGER ::= 2 -- network specific
+
+minDigitsLength INTEGER ::= 0 -- network specific
+
+maxDigitsLength INTEGER ::= 1 -- network specific
+
+minDisplayInformationLength INTEGER ::= 0 -- network specific
+
+maxDisplayInformationLength INTEGER ::= 1 -- network specific
+
+minEventSpecificInformationChargingLength INTEGER ::= 0 -- network specific
+
+maxEventSpecificInformationChargingLength INTEGER ::= 1 -- network specific
+
+minEventTypeChargingLength INTEGER ::= 0 -- network specific
+
+maxEventTypeChargingLength INTEGER ::= 1 -- network specific
+
+minFCIBillingChargingLength INTEGER ::= 0 -- network specific
+
+maxFCIBillingChargingLength INTEGER ::= 1 -- network specific
+
+minIPAvailableLength INTEGER ::= 0 -- network specific
+
+maxIPAvailableLength INTEGER ::= 1 -- network specific
+
+minIPSSPCapabilitiesLength INTEGER ::= 0 -- network specific
+
+maxIPSSPCapabilitiesLength INTEGER ::= 1 -- network specific
+
+minLocationNumberLength INTEGER ::= 0 -- network specific
+
+maxLocationNumberLength INTEGER ::= 1 -- network specific
+
+minMessageContentLength INTEGER ::= 0 -- network specific
+
+maxMessageContentLength INTEGER ::= 1 -- network specific
+
+minOriginalCalledPartyIDLength INTEGER ::= 0 -- network specific
+
+maxOriginalCalledPartyIDLength INTEGER ::= 1 -- network specific
+
+minRedirectingPartyIDLength INTEGER ::= 0 -- network specific
+
+maxRedirectingPartyIDLength INTEGER ::= 1 -- network specific
+
+minRouteListLength INTEGER ::= 0 -- network specific
+
+maxRouteListLength INTEGER ::= 1 -- network specific
+
+minScfIDLength INTEGER ::= 0 -- network specific
+
+maxScfIDLength INTEGER ::= 1 -- network specific
+
+minSCIBillingChargingLength INTEGER ::= 0 -- network specific
+
+maxSCIBillingChargingLength INTEGER ::= 1 -- network specific
+
+minServiceInteractionIndicatorsLength INTEGER ::= 0 -- network specific
+
+maxServiceInteractionIndicatorsLength INTEGER ::= 1 -- network specific
+
+minSFBillingChargingLength INTEGER ::= 0 -- network specific
+
+maxSFBillingChargingLength INTEGER ::= 1 -- network specific
+
+numOfBCSMEvents INTEGER ::= 1 -- network specific
+
+numOfChargingEvents INTEGER ::= 1 -- network specific
+
+numOfCounters INTEGER ::= 100
+
+numOfExtensions INTEGER ::= 1 -- network specific
+
+numOfInfoItems INTEGER ::= 5
+
+numOfMessageIDs INTEGER ::= 1 -- network specific
+
+END
+
+-- Generated by Asnp, the ASN.1 pretty-printer of France Telecom R&D
+
diff --git a/lib/asn1/test/asn1_SUITE_data/INAPv2extract.asn b/lib/asn1/test/asn1_SUITE_data/INAPv2extract.asn
new file mode 100644
index 0000000000..8eaecbd0a7
--- /dev/null
+++ b/lib/asn1/test/asn1_SUITE_data/INAPv2extract.asn
@@ -0,0 +1,112 @@
+INAPv2extract DEFINITIONS
+
+EXPLICIT TAGS
+
+::=
+
+BEGIN
+
+EXTENSION ::= CLASS {
+ &ExtensionType ,
+ &criticality CriticalityType DEFAULT ignore,
+ &id Code
+}
+WITH SYNTAX {
+ EXTENSION-SYNTAX &ExtensionType
+ [CRITICALITY &criticality]
+ IDENTIFIED BY &id
+}
+
+CriticalityType ::= ENUMERATED {ignore(0), abort(1)}
+
+Code ::= CHOICE {local INTEGER,
+ global OBJECT IDENTIFIER
+}
+
+--3b parameteriserad object set
+SupportedExtensions{PARAMETERS-BOUND:bound} EXTENSION ::=
+{firstExtension |
+ boundedExtension {bound}, --4a instans av parameteriserat object
+ ...
+}
+
+firstExtension EXTENSION ::= {
+ EXTENSION-SYNTAX NULL
+ CRITICALITY ignore
+ IDENTIFIED BY local:1
+}
+
+--4b parameteriserat object
+boundedExtension{PARAMETERS-BOUND:bound} EXTENSION ::= {
+ EXTENSION-SYNTAX BoundedExtensionSyntax {bound} --5a instans av parameteriserad typ
+ CRITICALITY ignore
+ IDENTIFIED BY local:2
+}
+
+--1b parameteriserad typ
+InitialDPArg{PARAMETERS-BOUND:bound} ::= SEQUENCE {
+ dialledDigits [1] CalledPartyNumber{bound} OPTIONAL, --2a instans av parameteriserad typ
+ extensions [15] SEQUENCE SIZE (1..bound.&numOfExtensions) OF ExtensionField{ {SupportedExtensions {bound}}} OPTIONAL --3a instans av parameteriserad objectset
+}
+
+ExtensionField{EXTENSION:SupportedExtensions} ::= SEQUENCE {
+ type EXTENSION.&id({SupportedExtensions}),
+ -- shall identify the value of an EXTENSION type
+ criticality CriticalityType DEFAULT ignore,
+ value [1] EXTENSION.&ExtensionType({SupportedExtensions}{@type})
+}
+
+--2b parameteriserad typ
+CalledPartyNumber{PARAMETERS-BOUND:bound} ::=
+ OCTET STRING
+ (SIZE (bound.&minCalledPartyNumberLength..bound.&maxCalledPartyNumberLength))
+
+--5b parameteriserad typ
+BoundedExtensionSyntax{PARAMETERS-BOUND:bound} ::= SEQUENCE { --5
+ digits OCTET STRING(SIZE (bound.&minDigitsLength..bound.&maxDigitsLength))
+}
+
+PARAMETERS-BOUND ::= CLASS {
+ &minAChBillingChargingLength INTEGER,
+ &maxAChBillingChargingLength INTEGER,
+ &minAttributesLength INTEGER,
+ &maxAttributesLength INTEGER,
+ &minBackwardGVNSLength INTEGER,
+ &minDigitsLength INTEGER,
+ &maxDigitsLength INTEGER,
+ &minCalledPartyNumberLength INTEGER,
+ &maxCalledPartyNumberLength INTEGER,
+ &numOfExtensions INTEGER
+}
+WITH SYNTAX {
+ MINIMUM-FOR-ACH-BILLING-CHARGING &minAChBillingChargingLength
+ MAXIMUM-FOR-ACH-BILLING-CHARGING &maxAChBillingChargingLength
+ MINIMUM-FOR-ATTRIBUTES &minAttributesLength
+ MAXIMUM-FOR-ATTRIBUTES &maxAttributesLength
+ MINIMUM-FOR-BACKWARD-GVNS &minBackwardGVNSLength
+ MINIMUM-FOR-DIGITS &minDigitsLength
+ MAXIMUM-FOR-DIGITS &maxDigitsLength
+ MINIMUM-FOR-CALLED-PARTY-NUMBER &minCalledPartyNumberLength
+ MAXIMUM-FOR-CALLED-PARTY-NUMBER &maxCalledPartyNumberLength
+ NUM-OF-EXTENSIONS &numOfExtensions
+ }
+
+--1a instans av parameteriserad typ
+ActivityTest2 ::= InitialDPArg{networkSpecificBoundSet}
+
+networkSpecificBoundSet PARAMETERS-BOUND ::= {
+ MINIMUM-FOR-ACH-BILLING-CHARGING 1 -- example value
+ MAXIMUM-FOR-ACH-BILLING-CHARGING 5 -- example value
+ MINIMUM-FOR-ATTRIBUTES 1 -- example value
+ MAXIMUM-FOR-ATTRIBUTES 5 -- example value
+ MINIMUM-FOR-BACKWARD-GVNS 1
+ MINIMUM-FOR-DIGITS 1
+ MAXIMUM-FOR-DIGITS 5
+ MINIMUM-FOR-CALLED-PARTY-NUMBER 1 -- example value
+ MAXIMUM-FOR-CALLED-PARTY-NUMBER 5 -- example value
+ NUM-OF-EXTENSIONS 1 -- example value
+}
+
+
+
+END \ No newline at end of file
diff --git a/lib/asn1/test/asn1_SUITE_data/INSTANCEOF.asn1 b/lib/asn1/test/asn1_SUITE_data/INSTANCEOF.asn1
new file mode 100644
index 0000000000..8c4f3a8f7e
--- /dev/null
+++ b/lib/asn1/test/asn1_SUITE_data/INSTANCEOF.asn1
@@ -0,0 +1,34 @@
+INSTANCEOF DEFINITIONS AUTOMATIC TAGS ::=
+
+
+BEGIN
+
+GeneralName ::= CHOICE {
+ otherName [0] INSTANCE OF OTHER-NAME,
+ rfc822Name [1] IA5String,
+ dNSName [2] IA5String,
+ lastName [3] INSTANCE OF OTHER-NAME ({TI})
+}
+
+Names ::= SEQUENCE {
+ firstName [0] INSTANCE OF OTHER-NAME,
+ secondName [1] PrintableString,
+ thirdName [2] INSTANCE OF OTHER-NAME ({TI})
+}
+
+OTHER-NAME ::= TYPE-IDENTIFIER
+
+TI OTHER-NAME ::= {{INTEGER IDENTIFIED BY {2 4}} |
+ {Seq IDENTIFIED BY {2 3 4}} |
+ {SEQUENCE{a INTEGER,b ENUMERATED{a,b,c}} IDENTIFIED BY {2 3 4 5}} }
+
+Int ::= INTEGER
+
+Seq ::= SEQUENCE {
+ a INTEGER,
+ b BOOLEAN
+}
+
+
+
+END
diff --git a/lib/asn1/test/asn1_SUITE_data/IllegalExport.asn1 b/lib/asn1/test/asn1_SUITE_data/IllegalExport.asn1
new file mode 100644
index 0000000000..1b5e42ad3c
--- /dev/null
+++ b/lib/asn1/test/asn1_SUITE_data/IllegalExport.asn1
@@ -0,0 +1,7 @@
+IllegalExport DEFINITIONS ::=
+BEGIN
+EXPORTS T, KalleAnka;
+
+T ::= INTEGER
+
+END
diff --git a/lib/asn1/test/asn1_SUITE_data/Import.py b/lib/asn1/test/asn1_SUITE_data/Import.py
new file mode 100644
index 0000000000..91841c1c9f
--- /dev/null
+++ b/lib/asn1/test/asn1_SUITE_data/Import.py
@@ -0,0 +1,14 @@
+Import DEFINITIONS IMPLICIT TAGS ::=
+BEGIN
+EXPORTS Person;
+--IMPORTS
+-- OPERATION, ERROR FROM Remote-Operations-Notation
+-- {joint-iso-ccitt(2) remote-operations(4) notation(0)};
+-- {joint-iso-ccitt remote-operations notation};
+
+Person ::= [PRIVATE 19] SEQUENCE {
+ name PrintableString,
+ location INTEGER {home(0),field(1),roving(2)},
+ age INTEGER OPTIONAL
+ }
+END
diff --git a/lib/asn1/test/asn1_SUITE_data/ImportsFrom.asn1 b/lib/asn1/test/asn1_SUITE_data/ImportsFrom.asn1
new file mode 100644
index 0000000000..896a35d627
--- /dev/null
+++ b/lib/asn1/test/asn1_SUITE_data/ImportsFrom.asn1
@@ -0,0 +1,17 @@
+ImportsFrom DEFINITIONS ::=
+
+BEGIN
+
+IMPORTS
+Type1, Type2, Type3
+FROM RemoteFile1 objid
+val1, val2, val3
+FROM RemoteFile2;
+
+objid OBJECT IDENTIFIER ::= {joint-iso-ccitt(2) remote-operations(4) notation(0)}
+
+LocalType ::= INTEGER
+
+END
+
+
diff --git a/lib/asn1/test/asn1_SUITE_data/InfClass.asn b/lib/asn1/test/asn1_SUITE_data/InfClass.asn
new file mode 100644
index 0000000000..ecc6764402
--- /dev/null
+++ b/lib/asn1/test/asn1_SUITE_data/InfClass.asn
@@ -0,0 +1,56 @@
+InfClass DEFINITIONS ::=
+BEGIN
+
+IMPORTS
+ ERROR
+FROM ErrorClass;
+
+FUNCTION ::= CLASS {
+ &ArgumentType,
+ &ResultType DEFAULT NULL,
+ &error ERROR OPTIONAL,
+ &code INTEGER UNIQUE
+ }
+
+OTHER-FUNCTION ::= CLASS {
+ &code INTEGER UNIQUE,
+ &Alphabet DEFAULT NULL,
+ &ArgumentType,
+ &SupportedArguments &ArgumentType OPTIONAL,
+ &ResultType DEFAULT NULL,
+ &result-if-error &ResultType DEFAULT NULL,
+ &associated-function OTHER-FUNCTION OPTIONAL,
+ &NumberSet INTEGER,
+ &ObjectSet OTHER-FUNCTION
+ }
+
+ObjSet1 FUNCTION ::= { ... }
+
+val1 FUNCTION ::= {
+ &ArgumentType INTEGER,
+ &ResultType INTEGER,
+ &code 3
+ }
+
+val2 FUNCTION ::= {
+ &ArgumentType INTEGER,
+ &ResultType INTEGER,
+ &code 2
+ }
+
+int1 INTEGER ::= 3
+
+ObjSet2 FUNCTION ::= {
+ val1 | val2 }
+
+
+-- added for OTP-4591
+
+Seq ::= SEQUENCE {
+ arg FUNCTION.&ArgumentType ({ObjSet2}{@val1}),
+ res FUNCTION.&ResultType ({ObjSet2}{@val1}),
+ val1 FUNCTION.&code ({ObjSet2})
+ }
+
+
+END
diff --git a/lib/asn1/test/asn1_SUITE_data/InfObj.asn b/lib/asn1/test/asn1_SUITE_data/InfObj.asn
new file mode 100644
index 0000000000..0a437e12df
--- /dev/null
+++ b/lib/asn1/test/asn1_SUITE_data/InfObj.asn
@@ -0,0 +1,153 @@
+InfObj DEFINITIONS ::=
+BEGIN
+
+
+RANAP-ELEMENTARY-PROCEDURE ::= CLASS {
+ &InitiatingMessage ,
+ &SuccessfulOutcome OPTIONAL,
+ &Outcome DEFAULT NULL,
+ &vartypvalue &Outcome OPTIONAL,
+ &FixTypeValSet PrintableString OPTIONAL,
+ &VarTypeValSet &InitiatingMessage OPTIONAL,
+ &infoObject RANAP-ELEMENTARY-PROCEDURE OPTIONAL,
+ &InfObjectSet CLASS2 OPTIONAL,
+ &UnsuccessfulOutcome OPTIONAL,
+ &procedureCode ProcedureCode UNIQUE,
+ &criticality Criticality DEFAULT ignore
+}
+WITH SYNTAX {
+ INITIATING MESSAGE &InitiatingMessage
+ [SUCCESSFUL OUTCOME &SuccessfulOutcome]
+ [UNSUCCESSFUL OUTCOME &UnsuccessfulOutcome]
+ [OUTCOME &Outcome]
+ PROCEDURE CODE &procedureCode
+ [CRITICALITY &criticality]
+ [VARTYPEVALUE &vartypvalue]
+ [FIXT &FixTypeValSet]
+ [VART &VarTypeValSet]
+ [INFOOBJECT &infoObject]
+ [INFOOBJECTSET &InfObjectSet]
+}
+
+RANAP-PDU ::= CHOICE {
+ initiatingMessage InitiatingMessage,
+-- successfulOutcome SuccessfulOutcome,
+-- unsuccessfulOutcome UnsuccessfulOutcome,
+-- outcome Outcome,
+ ...
+}
+
+CLASS2 ::= RANAP-ELEMENTARY-PROCEDURE
+
+MY-CLASS ::= CLASS {
+ &integerValue INTEGER UNIQUE,
+ &booleanValue BOOLEAN,
+ &stringValue PrintableString
+ }
+
+myobject MY-CLASS ::= {
+ &integerValue 12,
+ &booleanValue TRUE,
+ &stringValue "hejsan"
+ }
+MyObjectSet MY-CLASS ::= {
+ myobject
+ }
+
+InitiatingMessage ::= SEQUENCE {
+ procedureCode RANAP-ELEMENTARY-PROCEDURE.&procedureCode ({RANAP-ELEMENTARY-PROCEDURES}),
+ criticality RANAP-ELEMENTARY-PROCEDURE.&criticality ({RANAP-ELEMENTARY-PROCEDURES}{@procedureCode}),
+ value RANAP-ELEMENTARY-PROCEDURE.&InitiatingMessage ({RANAP-ELEMENTARY-PROCEDURES}{@procedureCode})
+ }
+
+iu-Release RANAP-ELEMENTARY-PROCEDURE ::= {
+ INITIATING MESSAGE Iu-ReleaseCommand
+ SUCCESSFUL OUTCOME Iu-ReleaseComplete
+ PROCEDURE CODE id-Iu-Release1
+ CRITICALITY ignore
+ }
+
+relocationPreparation RANAP-ELEMENTARY-PROCEDURE ::= {
+ INITIATING MESSAGE INTEGER --Iu-ReleaseCommand
+ SUCCESSFUL OUTCOME Iu-ReleaseComplete
+ PROCEDURE CODE id-Iu-Release2
+ CRITICALITY notify
+ }
+
+object3 RANAP-ELEMENTARY-PROCEDURE ::= {
+ &InitiatingMessage Iu-ReleaseCommand,
+ &SuccessfulOutcome Iu-ReleaseComplete,
+ &procedureCode id-Iu-Release3,
+ &criticality reject
+ }
+
+object4 RANAP-ELEMENTARY-PROCEDURE ::= {
+ &InitiatingMessage INTEGER,
+ &SuccessfulOutcome PrintableString,
+ &procedureCode id-Iu-Release4,
+ &criticality reject
+ }
+
+object5 RANAP-ELEMENTARY-PROCEDURE ::= {
+ &InitiatingMessage INTEGER,
+ &SuccessfulOutcome PrintableString,
+ &Outcome ProcedureCode,
+ &vartypvalue 12,
+ &infoObject object4,
+ &InfObjectSet MyObjectSet,
+ &procedureCode id-Iu-Release5,
+ &criticality reject
+ }
+
+
+RANAP-ELEMENTARY-PROCEDURES RANAP-ELEMENTARY-PROCEDURE ::= {
+ iu-Release |
+ relocationPreparation ,
+ ...
+ }
+
+RANAP-ELEMENTARY-PROCEDURES2 RANAP-ELEMENTARY-PROCEDURE ::= {
+ iu-Release |
+ relocationPreparation
+ }
+
+
+OBJECTSET1 RANAP-ELEMENTARY-PROCEDURE ::= {
+ {INITIATING MESSAGE Iu-ReleaseCommand SUCCESSFUL OUTCOME Iu-ReleaseComplete PROCEDURE CODE id-Iu-Release1 CRITICALITY ignore} | {INITIATING MESSAGE Iu-ReleaseCommand PROCEDURE CODE id-Iu-Release2}
+ }
+
+OBJECTSET2 RANAP-ELEMENTARY-PROCEDURE ::= {
+ iu-Release |
+ {INITIATING MESSAGE Iu-ReleaseCommand SUCCESSFUL OUTCOME Iu-ReleaseComplete PROCEDURE CODE id-Iu-Release4 CRITICALITY ignore} |
+ relocationPreparation |
+ {INITIATING MESSAGE Iu-ReleaseCommand PROCEDURE CODE id-Iu-Release5} ,
+ ...
+ }
+
+OBJECTSET3 RANAP-ELEMENTARY-PROCEDURE ::= {
+ iu-Release,
+ ...
+ }
+
+OBJECTSET4 RANAP-ELEMENTARY-PROCEDURE ::= {
+ iu-Release
+ }
+
+Iu-ReleaseCommand ::= SEQUENCE {
+ first INTEGER,
+ second BOOLEAN
+ }
+
+Iu-ReleaseComplete ::= INTEGER (1..510)
+
+ProcedureCode ::= INTEGER (0..255)
+Criticality ::= ENUMERATED { reject, ignore, notify }
+id-Iu-Release1 INTEGER ::= 1
+id-Iu-Release2 INTEGER ::= 2
+id-Iu-Release3 INTEGER ::= 3
+id-Iu-Release4 INTEGER ::= 4
+id-Iu-Release5 INTEGER ::= 5
+
+END
+
+
diff --git a/lib/asn1/test/asn1_SUITE_data/InfObj2.asn b/lib/asn1/test/asn1_SUITE_data/InfObj2.asn
new file mode 100644
index 0000000000..faba7371a4
--- /dev/null
+++ b/lib/asn1/test/asn1_SUITE_data/InfObj2.asn
@@ -0,0 +1,156 @@
+InfObj2 DEFINITIONS ::=
+BEGIN
+
+
+RANAP-ELEMENTARY-PROCEDURE ::= CLASS {
+ &InitiatingMessage ,
+ &SuccessfulOutcome OPTIONAL,
+ &Outcome DEFAULT NULL,
+ &vartypvalue &Outcome,
+ &FixTypeValSet PrintableString,
+ &VarTypeValSet &InitiatingMessage,
+ &infoObject RANAP-ELEMENTARY-PROCEDURE,
+ &InfObjectSet CLASS2,
+ &UnsuccessfulOutcome OPTIONAL,
+ &procedureCode ProcedureCode UNIQUE,
+ &criticality Criticality DEFAULT ignore
+}
+WITH SYNTAX {
+ INITIATING MESSAGE &InitiatingMessage
+ [SUCCESSFUL OUTCOME &SuccessfulOutcome]
+ [UNSUCCESSFUL OUTCOME &UnsuccessfulOutcome]
+ [OUTCOME &Outcome]
+ PROCEDURE CODE &procedureCode
+ [CRITICALITY &criticality]
+}
+
+RANAP-PDU ::= CHOICE {
+ initiatingMessage [0] InitiatingMessage,
+ substrings [1] SEQUENCE {
+ type RANAP-ELEMENTARY-PROCEDURE.&procedureCode({RANAP-ELEMENTARY-PROCEDURES}),
+ strings SEQUENCE OF CHOICE {
+ initial [0] RANAP-ELEMENTARY-PROCEDURE.&Outcome({
+ RANAP-ELEMENTARY-PROCEDURES}{@substrings.type}),
+ final [1] RANAP-ELEMENTARY-PROCEDURE.&Outcome({RANAP-ELEMENTARY-PROCEDURES}{@substrings.type})
+ }
+ },
+-- successfulOutcome SuccessfulOutcome,
+-- unsuccessfulOutcome UnsuccessfulOutcome,
+-- outcome Outcome,
+ ...
+ }
+
+CLASS2 ::= RANAP-ELEMENTARY-PROCEDURE
+
+MY-CLASS ::= CLASS {
+ &integerValue INTEGER UNIQUE,
+ &booleanValue BOOLEAN,
+ &stringValue PrintableString
+ }
+
+myobject MY-CLASS ::= {
+ &integerValue 12,
+ &booleanValue TRUE,
+ &stringValue "hejsan"
+ }
+MyObjectSet MY-CLASS ::= {
+ myobject
+ }
+
+InitiatingMessage ::= SEQUENCE {
+ procedureCode RANAP-ELEMENTARY-PROCEDURE.&procedureCode ({RANAP-ELEMENTARY-PROCEDURES}),
+ criticality RANAP-ELEMENTARY-PROCEDURE.&criticality ({RANAP-ELEMENTARY-PROCEDURES}{@procedureCode}),
+ value RANAP-ELEMENTARY-PROCEDURE.&InitiatingMessage ({RANAP-ELEMENTARY-PROCEDURES}{@procedureCode})
+ }
+
+iu-Release RANAP-ELEMENTARY-PROCEDURE ::= {
+ INITIATING MESSAGE Iu-ReleaseCommand
+ SUCCESSFUL OUTCOME Iu-ReleaseComplete
+ PROCEDURE CODE id-Iu-Release1
+ CRITICALITY ignore
+ }
+
+relocationPreparation RANAP-ELEMENTARY-PROCEDURE ::= {
+ INITIATING MESSAGE INTEGER --Iu-ReleaseCommand
+ SUCCESSFUL OUTCOME Iu-ReleaseComplete
+ PROCEDURE CODE id-Iu-Release2
+ CRITICALITY notify
+ }
+
+object3 RANAP-ELEMENTARY-PROCEDURE ::= {
+ &InitiatingMessage Iu-ReleaseCommand,
+ &SuccessfulOutcome Iu-ReleaseComplete,
+ &procedureCode id-Iu-Release3,
+ &criticality reject
+ }
+
+object4 RANAP-ELEMENTARY-PROCEDURE ::= {
+ &InitiatingMessage INTEGER,
+ &SuccessfulOutcome PrintableString,
+ &procedureCode id-Iu-Release4,
+ &criticality reject
+ }
+
+object5 RANAP-ELEMENTARY-PROCEDURE ::= {
+ &InitiatingMessage INTEGER,
+ &SuccessfulOutcome PrintableString,
+ &Outcome ProcedureCode,
+ &vartypvalue 12,
+ &infoObject object4,
+ &InfObjectSet MyObjectSet,
+ &procedureCode id-Iu-Release5,
+ &criticality reject
+ }
+
+
+RANAP-ELEMENTARY-PROCEDURES RANAP-ELEMENTARY-PROCEDURE ::= {
+ iu-Release |
+ relocationPreparation ,
+ ...
+ }
+
+RANAP-ELEMENTARY-PROCEDURES2 RANAP-ELEMENTARY-PROCEDURE ::= {
+ iu-Release |
+ relocationPreparation
+ }
+
+
+OBJECTSET1 RANAP-ELEMENTARY-PROCEDURE ::= {
+ {INITIATING MESSAGE Iu-ReleaseCommand SUCCESSFUL OUTCOME Iu-ReleaseComplete PROCEDURE CODE id-Iu-Release1 CRITICALITY ignore} | {INITIATING MESSAGE Iu-ReleaseCommand PROCEDURE CODE id-Iu-Release2}
+ }
+
+OBJECTSET2 RANAP-ELEMENTARY-PROCEDURE ::= {
+ iu-Release |
+ {INITIATING MESSAGE Iu-ReleaseCommand SUCCESSFUL OUTCOME Iu-ReleaseComplete PROCEDURE CODE id-Iu-Release4 CRITICALITY ignore} |
+ relocationPreparation |
+ {INITIATING MESSAGE Iu-ReleaseCommand PROCEDURE CODE id-Iu-Release5} ,
+ ...
+ }
+
+OBJECTSET3 RANAP-ELEMENTARY-PROCEDURE ::= {
+ iu-Release,
+ ...
+ }
+
+OBJECTSET4 RANAP-ELEMENTARY-PROCEDURE ::= {
+ iu-Release
+ }
+
+Iu-ReleaseCommand ::= SEQUENCE {
+ first INTEGER,
+ second BOOLEAN
+ }
+
+Iu-ReleaseComplete ::= INTEGER (1..510)
+
+ProcedureCode ::= INTEGER (0..255)
+Criticality ::= ENUMERATED { reject, ignore, notify }
+id-Iu-Release1 INTEGER ::= 1
+id-Iu-Release2 INTEGER ::= 2
+id-Iu-Release3 INTEGER ::= 3
+id-Iu-Release4 INTEGER ::= 4
+id-Iu-Release5 INTEGER ::= 5
+
+END
+
+
diff --git a/lib/asn1/test/asn1_SUITE_data/InformationFramework.asn b/lib/asn1/test/asn1_SUITE_data/InformationFramework.asn
new file mode 100755
index 0000000000..ef236e98a9
--- /dev/null
+++ b/lib/asn1/test/asn1_SUITE_data/InformationFramework.asn
@@ -0,0 +1,868 @@
+-- Module InformationFramework (X.501:08/1997)
+InformationFramework {joint-iso-itu-t ds(5) module(1) informationFramework(1)
+ 3} DEFINITIONS ::=
+BEGIN
+
+-- EXPORTS All -
+-- The types and values defined in this module are exported for use in the other ASN.1 modules contained
+-- within the Directory Specifications, and for the use of other applications which will use them to access
+-- Directory services. Other applications may use them for their own purposes, but this will not constrain
+-- extensions and modifications needed to maintain or improve the Directory service.
+IMPORTS
+ id-oc, id-at, id-mr, id-oa, id-sc, id-ar, id-nf, selectedAttributeTypes,
+ directoryAbstractService, upperBounds
+ FROM UsefulDefinitions {joint-iso-itu-t ds(5) module(1)
+ usefulDefinitions(0) 3}
+ commonName, generalizedTimeMatch, generalizedTimeOrderingMatch, booleanMatch,
+ integerMatch, integerOrderingMatch, objectIdentifierFirstComponentMatch,
+ integerFirstComponentMatch, DirectoryString{}
+ FROM SelectedAttributeTypes selectedAttributeTypes
+ TypeAndContextAssertion, ServiceControlOptions, SearchControlOptions,
+ HierarchySelections, FamilyGrouping, FamilyReturn
+ FROM DirectoryAbstractService directoryAbstractService
+ ub-search
+ FROM UpperBounds upperBounds;
+
+-- attribute data types
+Attribute ::= SEQUENCE {
+ type ATTRIBUTE.&id({SupportedAttributes}),
+ values
+ SET SIZE (0..MAX) OF ATTRIBUTE.&Type({SupportedAttributes}{@type}),
+ valuesWithContext
+ SET SIZE (1..MAX) OF
+ SEQUENCE {value ATTRIBUTE.&Type({SupportedAttributes}{@type}),
+ contextList SET SIZE (1..MAX) OF Context} OPTIONAL
+}
+
+AttributeType ::= ATTRIBUTE.&id
+
+AttributeValue ::= ATTRIBUTE.&Type
+
+Context ::= SEQUENCE {
+ contextType CONTEXT.&id({SupportedContexts}),
+ contextValues
+ SET SIZE (1..MAX) OF CONTEXT.&Type({SupportedContexts}{@contextType}),
+ fallback BOOLEAN DEFAULT FALSE
+}
+
+AttributeValueAssertion ::= SEQUENCE {
+ type ATTRIBUTE.&id({SupportedAttributes}),
+ assertion
+ ATTRIBUTE.&equality-match.&AssertionType({SupportedAttributes}{@type}),
+ assertedContexts
+ CHOICE {allContexts [0] NULL,
+ selectedContexts [1] SET SIZE (1..MAX) OF ContextAssertion
+ } OPTIONAL
+}
+
+ContextAssertion ::= SEQUENCE {
+ contextType CONTEXT.&id({SupportedContexts}),
+ contextValues
+ SET SIZE (1..MAX) OF CONTEXT.&Assertion({SupportedContexts}{@contextType})
+}
+
+AttributeTypeAssertion ::= SEQUENCE {
+ type ATTRIBUTE.&id({SupportedAttributes}),
+ assertedContexts SEQUENCE SIZE (1..MAX) OF ContextAssertion OPTIONAL
+}
+
+-- Definition of the following information object set is deferred, perhaps to standardized
+-- profiles or to protocol implementation conformance statements. The set is required to
+-- specify a table constraint on the values component of Attribute, the value component
+-- of AttributeTypeAndValue, and the assertion component of AttributeValueAssertion.
+SupportedAttributes ATTRIBUTE ::=
+ {objectClass | aliasedEntryName, ...}
+
+-- Definition of the following information object set is deferred, perhaps to standardized
+-- profiles or to protocol implementation conformance statements. The set is required to
+-- specify a table constraint on the context specifications
+SupportedContexts CONTEXT ::=
+ {...}
+
+-- naming data types
+Name ::= CHOICE { -- only one possibility for now --rdnSequence RDNSequence
+}
+
+RDNSequence ::= SEQUENCE OF RelativeDistinguishedName
+
+DistinguishedName ::= RDNSequence
+
+RelativeDistinguishedName ::=
+ SET SIZE (1..MAX) OF AttributeTypeAndDistinguishedValue
+
+AttributeTypeAndDistinguishedValue ::= SEQUENCE {
+ type ATTRIBUTE.&id({SupportedAttributes}),
+ value ATTRIBUTE.&Type({SupportedAttributes}{@type}),
+ primaryDistinguished BOOLEAN DEFAULT TRUE,
+ valuesWithContext
+ SET SIZE (1..MAX) OF
+ SEQUENCE {distingAttrValue
+ [0] ATTRIBUTE.&Type({SupportedAttributes}{@type}) OPTIONAL,
+ contextList SET SIZE (1..MAX) OF Context} OPTIONAL
+}
+
+-- subtree data types
+SubtreeSpecification ::= SEQUENCE {
+ base [0] LocalName DEFAULT {},
+ COMPONENTS OF ChopSpecification,
+ specificationFilter [4] Refinement OPTIONAL
+}
+
+-- empty sequence specifies whole administrative area
+LocalName ::= RDNSequence
+
+ChopSpecification ::= SEQUENCE {
+ specificExclusions
+ [1] SET SIZE (1..MAX) OF
+ CHOICE {chopBefore [0] LocalName,
+ chopAfter [1] LocalName} OPTIONAL,
+ minimum [2] BaseDistance DEFAULT 0,
+ maximum [3] BaseDistance OPTIONAL
+}
+
+BaseDistance ::= INTEGER(0..MAX)
+
+Refinement ::= CHOICE {
+ item [0] OBJECT-CLASS.&id,
+ and [1] SET OF Refinement,
+ or [2] SET OF Refinement,
+ not [3] Refinement
+}
+
+-- OBJECT-CLASS information object class specification
+OBJECT-CLASS ::= CLASS {
+ &Superclasses OBJECT-CLASS OPTIONAL,
+ &kind ObjectClassKind DEFAULT structural,
+ &MandatoryAttributes ATTRIBUTE OPTIONAL,
+ &OptionalAttributes ATTRIBUTE OPTIONAL,
+ &id OBJECT IDENTIFIER UNIQUE
+}
+WITH SYNTAX {
+ [SUBCLASS OF &Superclasses]
+ [KIND &kind]
+ [MUST CONTAIN &MandatoryAttributes]
+ [MAY CONTAIN &OptionalAttributes]
+ ID &id
+}
+
+ObjectClassKind ::= ENUMERATED {abstract(0), structural(1), auxiliary(2)}
+
+-- object classes
+top OBJECT-CLASS ::= {
+ KIND abstract
+ MUST CONTAIN {objectClass}
+ ID id-oc-top
+}
+
+alias OBJECT-CLASS ::= {
+ SUBCLASS OF {top}
+ MUST CONTAIN {aliasedEntryName}
+ ID id-oc-alias
+}
+
+parent OBJECT-CLASS ::= {KIND abstract
+ ID id-oc-parent
+}
+
+child OBJECT-CLASS ::= {KIND auxiliary
+ ID id-oc-child
+}
+
+-- ATTRIBUTE information object class specification
+ATTRIBUTE ::= CLASS {
+ &derivation ATTRIBUTE OPTIONAL,
+ &Type OPTIONAL, -- either &Type or &derivation required
+ &equality-match MATCHING-RULE OPTIONAL,
+ &ordering-match MATCHING-RULE OPTIONAL,
+ &substrings-match MATCHING-RULE OPTIONAL,
+ &single-valued BOOLEAN DEFAULT FALSE,
+ &collective BOOLEAN DEFAULT FALSE,
+ -- operational extensions
+ &no-user-modification BOOLEAN DEFAULT FALSE,
+ &usage AttributeUsage DEFAULT userApplications,
+ &id OBJECT IDENTIFIER UNIQUE
+}
+WITH SYNTAX {
+ [SUBTYPE OF &derivation]
+ [WITH SYNTAX &Type]
+ [EQUALITY MATCHING RULE &equality-match]
+ [ORDERING MATCHING RULE &ordering-match]
+ [SUBSTRINGS MATCHING RULE &substrings-match]
+ [SINGLE VALUE &single-valued]
+ [COLLECTIVE &collective]
+ [NO USER MODIFICATION &no-user-modification]
+ [USAGE &usage]
+ ID &id
+}
+
+AttributeUsage ::= ENUMERATED {
+ userApplications(0), directoryOperation(1), distributedOperation(2),
+ dSAOperation(3)}
+
+-- attributes
+objectClass ATTRIBUTE ::= {
+ WITH SYNTAX OBJECT IDENTIFIER
+ EQUALITY MATCHING RULE objectIdentifierMatch
+ ID id-at-objectClass
+}
+
+aliasedEntryName ATTRIBUTE ::= {
+ WITH SYNTAX DistinguishedName
+ EQUALITY MATCHING RULE distinguishedNameMatch
+ SINGLE VALUE TRUE
+ ID id-at-aliasedEntryName
+}
+
+-- MATCHING-RULE information object class specification
+MATCHING-RULE ::= CLASS {
+ &ParentMatchingRules MATCHING-RULE.&id OPTIONAL,
+ &AssertionType OPTIONAL,
+ &uniqueMatchIndicator ATTRIBUTE.&id OPTIONAL,
+ &id OBJECT IDENTIFIER UNIQUE
+}
+WITH SYNTAX {
+ [PARENT &ParentMatchingRules]
+ [SYNTAX &AssertionType]
+ [UNIQUE-MATCH-INDICATOR &uniqueMatchIndicator]
+ ID &id
+}
+
+-- matching rules
+objectIdentifierMatch MATCHING-RULE ::= {
+ SYNTAX OBJECT IDENTIFIER
+ ID id-mr-objectIdentifierMatch
+}
+
+distinguishedNameMatch MATCHING-RULE ::= {
+ SYNTAX DistinguishedName
+ ID id-mr-distinguishedNameMatch
+}
+
+MAPPING-BASED-MATCHING{SelectedBy, BOOLEAN:combinable, MappingResult,
+ OBJECT IDENTIFIER:matchingRule} ::= CLASS {
+ &selectBy SelectedBy OPTIONAL,
+ &ApplicableTo ATTRIBUTE,
+ &subtypesIncluded BOOLEAN DEFAULT TRUE,
+ &combinable BOOLEAN(combinable),
+ &mappingResults MappingResult OPTIONAL,
+ &userControl BOOLEAN DEFAULT FALSE,
+ &exclusive BOOLEAN DEFAULT TRUE,
+ &matching-rule MATCHING-RULE.&id(matchingRule),
+ &id OBJECT IDENTIFIER UNIQUE
+}
+WITH SYNTAX {
+ [SELECT BY &selectBy]
+ APPLICABLE TO &ApplicableTo
+ [SUBTYPES INCLUDED &subtypesIncluded]
+ COMBINABLE &combinable
+ [MAPPING RESULTS &mappingResults]
+ [USER CONTROL &userControl]
+ [EXCLUSIVE &exclusive]
+ MATCHING RULE &matching-rule
+ ID &id
+}
+
+-- NAME-FORM information object class specification
+NAME-FORM ::= CLASS {
+ &namedObjectClass OBJECT-CLASS,
+ &MandatoryAttributes ATTRIBUTE,
+ &OptionalAttributes ATTRIBUTE OPTIONAL,
+ &id OBJECT IDENTIFIER UNIQUE
+}
+WITH SYNTAX {
+ NAMES &namedObjectClass
+ WITH ATTRIBUTES &MandatoryAttributes
+ [AND OPTIONALLY &OptionalAttributes]
+ ID &id
+}
+
+-- STRUCTURE-RULE class and DIT structure rule data types
+STRUCTURE-RULE ::= CLASS {
+ &nameForm NAME-FORM,
+ &SuperiorStructureRules STRUCTURE-RULE OPTIONAL,
+ &id RuleIdentifier
+}
+WITH SYNTAX {
+ NAME FORM &nameForm
+ [SUPERIOR RULES &SuperiorStructureRules]
+ ID &id
+}
+
+DITStructureRule ::= SEQUENCE {
+ ruleIdentifier RuleIdentifier,
+ -- must be unique within the scope of the subschema
+ nameForm NAME-FORM.&id,
+ superiorStructureRules SET SIZE (1..MAX) OF RuleIdentifier OPTIONAL
+}
+
+RuleIdentifier ::= INTEGER
+
+-- CONTENT-RULE class and DIT content rule data types
+CONTENT-RULE ::= CLASS {
+ &structuralClass OBJECT-CLASS.&id UNIQUE,
+ &Auxiliaries OBJECT-CLASS OPTIONAL,
+ &Mandatory ATTRIBUTE OPTIONAL,
+ &Optional ATTRIBUTE OPTIONAL,
+ &Precluded ATTRIBUTE OPTIONAL
+}
+WITH SYNTAX {
+ STRUCTURAL OBJECT-CLASS &structuralClass
+ [AUXILIARY OBJECT-CLASSES &Auxiliaries]
+ [MUST CONTAIN &Mandatory]
+ [MAY CONTAIN &Optional]
+ [MUST-NOT CONTAIN &Precluded]
+}
+
+DITContentRule ::= SEQUENCE {
+ structuralObjectClass OBJECT-CLASS.&id,
+ auxiliaries SET SIZE (1..MAX) OF OBJECT-CLASS.&id OPTIONAL,
+ mandatory [1] SET SIZE (1..MAX) OF ATTRIBUTE.&id OPTIONAL,
+ optional [2] SET SIZE (1..MAX) OF ATTRIBUTE.&id OPTIONAL,
+ precluded [3] SET SIZE (1..MAX) OF ATTRIBUTE.&id OPTIONAL
+}
+
+CONTEXT ::= CLASS {
+ &Type ,
+ &Assertion OPTIONAL,
+ &id OBJECT IDENTIFIER UNIQUE
+}WITH SYNTAX {WITH SYNTAX &Type
+ [ASSERTED AS &Assertion]
+ ID &id
+}
+
+DITContextUse ::= SEQUENCE {
+ attributeType ATTRIBUTE.&id,
+ mandatoryContexts [1] SET SIZE (1..MAX) OF CONTEXT.&id OPTIONAL,
+ optionalContexts [2] SET SIZE (1..MAX) OF CONTEXT.&id OPTIONAL
+}
+
+DIT-CONTEXT-USE-RULE ::= CLASS {
+ &attributeType ATTRIBUTE.&id UNIQUE,
+ &Mandatory CONTEXT OPTIONAL,
+ &Optional CONTEXT OPTIONAL
+}
+WITH SYNTAX {
+ ATTRIBUTE TYPE &attributeType
+ [MANDATORY CONTEXTS &Mandatory]
+ [OPTIONAL CONTEXTS &Optional]
+}
+
+-- system schema information objects
+-- object classes
+subentry OBJECT-CLASS ::= {
+ SUBCLASS OF {top}
+ KIND structural
+ MUST CONTAIN {commonName | subtreeSpecification}
+ ID id-sc-subentry
+}
+
+subentryNameForm NAME-FORM ::= {
+ NAMES subentry
+ WITH ATTRIBUTES {commonName}
+ ID id-nf-subentryNameForm
+}
+
+accessControlSubentry OBJECT-CLASS ::= {
+ KIND auxiliary
+ ID id-sc-accessControlSubentry
+}
+
+collectiveAttributeSubentry OBJECT-CLASS ::= {
+ KIND auxiliary
+ ID id-sc-collectiveAttributeSubentry
+}
+
+contextAssertionSubentry OBJECT-CLASS ::= {
+ KIND auxiliary
+ MUST CONTAIN {contextAssertionDefaults}
+ ID id-sc-contextAssertionSubentry
+}
+
+serviceAdminSubentry OBJECT-CLASS ::= {
+ KIND auxiliary
+ MUST CONTAIN {searchRules}
+ ID id-sc-serviceAdminSubentry
+}
+
+-- attributes
+createTimestamp ATTRIBUTE ::= {
+ WITH SYNTAX GeneralizedTime
+ -- as per 41.3 b) or c) of ITU-T Rec. X.680 | ISO/IEC 8824-1
+ EQUALITY MATCHING RULE generalizedTimeMatch
+ ORDERING MATCHING RULE generalizedTimeOrderingMatch
+ SINGLE VALUE TRUE
+ NO USER MODIFICATION TRUE
+ USAGE directoryOperation
+ ID id-oa-createTimestamp
+}
+
+modifyTimestamp ATTRIBUTE ::= {
+ WITH SYNTAX GeneralizedTime
+ -- as per 41.3 b) or c) of ITU-T Rec. X.680 | ISO/IEC 8824-1
+ EQUALITY MATCHING RULE generalizedTimeMatch
+ ORDERING MATCHING RULE generalizedTimeOrderingMatch
+ SINGLE VALUE TRUE
+ NO USER MODIFICATION TRUE
+ USAGE directoryOperation
+ ID id-oa-modifyTimestamp
+}
+
+subschemaTimestamp ATTRIBUTE ::= {
+ WITH SYNTAX GeneralizedTime
+ -- as per 41.3 b) or c) of ITU-T Rec.X. 680 | ISO/IEC 8824-1
+ EQUALITY MATCHING RULE generalizedTimeMatch
+ ORDERING MATCHING RULE generalizedTimeOrderingMatch
+ SINGLE VALUE TRUE
+ NO USER MODIFICATION TRUE
+ USAGE directoryOperation
+ ID id-oa-subschemaTimestamp
+}
+
+creatorsName ATTRIBUTE ::= {
+ WITH SYNTAX DistinguishedName
+ EQUALITY MATCHING RULE distinguishedNameMatch
+ SINGLE VALUE TRUE
+ NO USER MODIFICATION TRUE
+ USAGE directoryOperation
+ ID id-oa-creatorsName
+}
+
+modifiersName ATTRIBUTE ::= {
+ WITH SYNTAX DistinguishedName
+ EQUALITY MATCHING RULE distinguishedNameMatch
+ SINGLE VALUE TRUE
+ NO USER MODIFICATION TRUE
+ USAGE directoryOperation
+ ID id-oa-modifiersName
+}
+
+subschemaSubentryList ATTRIBUTE ::= {
+ WITH SYNTAX DistinguishedName
+ EQUALITY MATCHING RULE distinguishedNameMatch
+ SINGLE VALUE TRUE
+ NO USER MODIFICATION TRUE
+ USAGE directoryOperation
+ ID id-oa-subschemaSubentryList
+}
+
+accessControlSubentryList ATTRIBUTE ::= {
+ WITH SYNTAX DistinguishedName
+ EQUALITY MATCHING RULE distinguishedNameMatch
+ NO USER MODIFICATION TRUE
+ USAGE directoryOperation
+ ID id-oa-accessControlSubentryList
+}
+
+collectiveAttributeSubentryList ATTRIBUTE ::= {
+ WITH SYNTAX DistinguishedName
+ EQUALITY MATCHING RULE distinguishedNameMatch
+ NO USER MODIFICATION TRUE
+ USAGE directoryOperation
+ ID id-oa-collectiveAttributeSubentryList
+}
+
+contextDefaultSubentryList ATTRIBUTE ::= {
+ WITH SYNTAX DistinguishedName
+ EQUALITY MATCHING RULE distinguishedNameMatch
+ NO USER MODIFICATION TRUE
+ USAGE directoryOperation
+ ID id-oa-contextDefaultSubentryList
+}
+
+serviceAdminSubentryList ATTRIBUTE ::= {
+ WITH SYNTAX DistinguishedName
+ EQUALITY MATCHING RULE distinguishedNameMatch
+ NO USER MODIFICATION TRUE
+ USAGE directoryOperation
+ ID id-oa-serviceAdminSubentryList
+}
+
+hasSubordinates ATTRIBUTE ::= {
+ WITH SYNTAX BOOLEAN
+ EQUALITY MATCHING RULE booleanMatch
+ SINGLE VALUE TRUE
+ NO USER MODIFICATION TRUE
+ USAGE directoryOperation
+ ID id-oa-hasSubordinates
+}
+
+administrativeRole ATTRIBUTE ::= {
+ WITH SYNTAX OBJECT-CLASS.&id -- OBJECT IDENTIFIER
+ EQUALITY MATCHING RULE objectIdentifierMatch
+ USAGE directoryOperation
+ ID id-oa-administrativeRole
+}
+
+subtreeSpecification ATTRIBUTE ::= {
+ WITH SYNTAX SubtreeSpecification
+ USAGE directoryOperation
+ ID id-oa-subtreeSpecification
+}
+
+collectiveExclusions ATTRIBUTE ::= {
+ WITH SYNTAX OBJECT IDENTIFIER
+ EQUALITY MATCHING RULE objectIdentifierMatch
+ USAGE directoryOperation
+ ID id-oa-collectiveExclusions
+}
+
+contextAssertionDefaults ATTRIBUTE ::= {
+ WITH SYNTAX TypeAndContextAssertion
+ EQUALITY MATCHING RULE objectIdentifierFirstComponentMatch
+ USAGE directoryOperation
+ ID id-oa-contextAssertionDefault
+}
+
+searchRules ATTRIBUTE ::= {
+ WITH SYNTAX SearchRuleDescription
+ EQUALITY MATCHING RULE integerFirstComponentMatch
+ USAGE directoryOperation
+ ID id-oa-searchRules
+}
+
+SearchRuleDescription ::= SEQUENCE {
+ COMPONENTS OF SearchRule,
+ name [28] SET SIZE (1..MAX) OF DirectoryString{ub-search} OPTIONAL,
+ description [29] DirectoryString{ub-search} OPTIONAL,
+ obsolete [30] BOOLEAN DEFAULT FALSE
+}
+
+hierarchyLevel ATTRIBUTE ::= {
+ WITH SYNTAX INTEGER
+ EQUALITY MATCHING RULE integerMatch
+ ORDERING MATCHING RULE integerOrderingMatch
+ SINGLE VALUE TRUE
+ NO USER MODIFICATION TRUE
+ USAGE directoryOperation
+ ID id-oa-hierarchyLevel
+}
+
+hierarchyBelow ATTRIBUTE ::= {
+ WITH SYNTAX BOOLEAN
+ EQUALITY MATCHING RULE booleanMatch
+ SINGLE VALUE TRUE
+ NO USER MODIFICATION TRUE
+ USAGE directoryOperation
+ ID id-oa-hierarchyBelow
+}
+
+hierarchyParent ATTRIBUTE ::= {
+ WITH SYNTAX DistinguishedName
+ EQUALITY MATCHING RULE distinguishedNameMatch
+ SINGLE VALUE TRUE
+ USAGE directoryOperation
+ ID id-oa-hierarchyParent
+}
+
+SearchRule ::= SEQUENCE {
+ COMPONENTS OF SearchRuleId,
+ serviceType [1] OBJECT IDENTIFIER OPTIONAL,
+ userClass [2] INTEGER OPTIONAL,
+ inputAttributeTypes
+ [3] SEQUENCE SIZE (1..MAX) OF RequestAttribute OPTIONAL,
+ attributeCombination [4] AttributeCombination DEFAULT and:{},
+ outputAttributeTypes [5] SEQUENCE SIZE (1..MAX) OF ResultAttribute OPTIONAL,
+ defaultControls [6] ControlOptions OPTIONAL,
+ mandatoryControls [7] ControlOptions OPTIONAL,
+ searchRuleControls [8] ControlOptions OPTIONAL,
+ familyGrouping [9] FamilyGrouping OPTIONAL,
+ familyReturn [10] FamilyReturn OPTIONAL,
+ relaxation [11] RelaxationPolicy OPTIONAL,
+ additionalControl [12] SEQUENCE SIZE (1..MAX) OF AttributeType OPTIONAL,
+ allowedSubset [13] AllowedSubset DEFAULT '111'B,
+ imposedSubset [14] ImposedSubset OPTIONAL,
+ entryLimit [15] EntryLimit OPTIONAL
+}
+
+SearchRuleId ::= SEQUENCE {id INTEGER,
+ dmdId [0] OBJECT IDENTIFIER
+}
+
+AllowedSubset ::= BIT STRING {baseObject(0), oneLevel(1), wholeSubtree(2)}
+
+ImposedSubset ::= ENUMERATED {baseObject(0), oneLevel(1), wholeSubtree(2)}
+
+RequestAttribute ::= SEQUENCE {
+ attributeType ATTRIBUTE.&id({SupportedAttributes}),
+ includeSubtypes [0] BOOLEAN DEFAULT FALSE,
+ selectedValues
+ [1] SEQUENCE SIZE (0..MAX) OF
+ ATTRIBUTE.&Type({SupportedAttributes}{@attributeType}) OPTIONAL,
+ defaultValues
+ [2] SEQUENCE SIZE (0..MAX) OF
+ SEQUENCE {entryType OBJECT-CLASS.&id OPTIONAL,
+ values
+ SEQUENCE OF
+ ATTRIBUTE.&Type({SupportedAttributes}{@attributeType})
+ } OPTIONAL,
+ contexts [3] SEQUENCE SIZE (0..MAX) OF ContextProfile OPTIONAL,
+ contextCombination [4] ContextCombination DEFAULT and:{},
+ matchingUse [5] SEQUENCE SIZE (1..MAX) OF MatchingUse OPTIONAL
+}
+
+ContextProfile ::= SEQUENCE {
+ contextType CONTEXT.&id({SupportedContexts}),
+ contextValue
+ SEQUENCE SIZE (1..MAX) OF
+ CONTEXT.&Assertion({SupportedContexts}{@contextType}) OPTIONAL
+}
+
+ContextCombination ::= CHOICE {
+ context [0] CONTEXT.&id,
+ and [1] SEQUENCE OF ContextCombination,
+ or [2] SEQUENCE OF ContextCombination,
+ not [3] ContextCombination
+}
+
+MatchingUse ::= SEQUENCE {
+ restrictionType MATCHING-RESTRICTION.&id({SupportedMatchingRestrictions}),
+ restrictionValue
+ MATCHING-RESTRICTION.&Restriction
+ ({SupportedMatchingRestrictions}{@restrictionType})
+}
+
+-- Definition of the following information object set is deferred, perhaps to standardized
+-- profiles or to protocol implementation conformance statements. The set is required to
+-- specify a table constraint on the components of SupportedMatchingRestrictions
+SupportedMatchingRestrictions MATCHING-RESTRICTION ::=
+ {...}
+
+AttributeCombination ::= CHOICE {
+ attribute [0] AttributeType,
+ and [1] SEQUENCE OF AttributeCombination,
+ or [2] SEQUENCE OF AttributeCombination,
+ not [3] AttributeCombination
+}
+
+ResultAttribute ::= SEQUENCE {
+ attributeType ATTRIBUTE.&id({SupportedAttributes}),
+ outputValues
+ CHOICE {selectedValues
+ SEQUENCE SIZE (1..MAX) OF
+ ATTRIBUTE.&Type({SupportedAttributes}{@attributeType}),
+ matchedValuesOnly NULL} OPTIONAL,
+ contexts [0] SEQUENCE SIZE (1..MAX) OF ContextProfile OPTIONAL
+}
+
+OutputValues ::= CHOICE {
+ selectedValues
+ SEQUENCE SIZE (1..MAX) OF ATTRIBUTE.&Type({SupportedAttributes}),
+ matchedValuesOnly NULL
+}
+
+ControlOptions ::= SEQUENCE {
+ serviceControls [0] ServiceControlOptions DEFAULT {},
+ searchOptions [1] SearchControlOptions DEFAULT {searchAliases},
+ hierarchyOptions [2] HierarchySelections OPTIONAL
+}
+
+EntryLimit ::= SEQUENCE {default INTEGER,
+ max INTEGER
+}
+
+RelaxationPolicy ::= SEQUENCE {
+ basic [0] MRMapping DEFAULT {},
+ tightenings [1] SEQUENCE SIZE (1..MAX) OF MRMapping OPTIONAL,
+ relaxations [2] SEQUENCE SIZE (1..MAX) OF MRMapping OPTIONAL,
+ maximum [3] INTEGER OPTIONAL, -- mandatory if tightenings is present
+ minimum [4] INTEGER DEFAULT 1
+}
+
+MRMapping ::= SEQUENCE {
+ mapping [0] SEQUENCE SIZE (1..MAX) OF Mapping OPTIONAL,
+ substitution [1] SEQUENCE SIZE (1..MAX) OF MRSubstitution OPTIONAL
+}
+
+Mapping ::= SEQUENCE {
+ mappingFunction
+ OBJECT IDENTIFIER
+ (CONSTRAINED BY {-- shall be an--
+
+ -- object identifier of a mapping-based matching algorithm -- }),
+ level INTEGER DEFAULT 0
+}
+
+MRSubstitution ::= SEQUENCE {
+ attribute AttributeType,
+ oldMatchingRule [0] MATCHING-RULE.&id OPTIONAL,
+ newMatchingRule [1] MATCHING-RULE.&id OPTIONAL
+}
+
+SEARCH-RULE ::= CLASS {
+ &dmdId OBJECT IDENTIFIER,
+ &serviceType OBJECT IDENTIFIER OPTIONAL,
+ &userClass INTEGER OPTIONAL,
+ &InputAttributeTypes REQUEST-ATTRIBUTE OPTIONAL,
+ &combination AttributeCombination OPTIONAL,
+ &OutputAttributeTypes RESULT-ATTRIBUTE OPTIONAL,
+ &defaultControls ControlOptions OPTIONAL,
+ &mandatoryControls ControlOptions OPTIONAL,
+ &searchRuleControls ControlOptions OPTIONAL,
+ &familyGrouping FamilyGrouping OPTIONAL,
+ &familyReturn FamilyReturn OPTIONAL,
+ &additionalControl AttributeType OPTIONAL,
+ &relaxation RelaxationPolicy OPTIONAL,
+ &entryLimit EntryLimit OPTIONAL,
+ &allowedSubset AllowedSubset DEFAULT '111'B,
+ &imposedSubset ImposedSubset OPTIONAL,
+ &id INTEGER UNIQUE
+}
+WITH SYNTAX {
+ DMD ID &dmdId
+ [SERVICE-TYPE &serviceType]
+ [USER-CLASS &userClass]
+ [INPUT ATTRIBUTES &InputAttributeTypes]
+ [COMBINATION &combination]
+ [OUTPUT ATTRIBUTES &OutputAttributeTypes]
+ [DEFAULT CONTROL &defaultControls]
+ [MANDATORY CONTROL &mandatoryControls]
+ [SEARCH-RULE CONTROL &searchRuleControls]
+ [FAMILY-GROUPING &familyGrouping]
+ [FAMILY-RETURN &familyReturn]
+ [ADDITIONAL CONTROL &additionalControl]
+ [RELAXATION &relaxation]
+ [ALLOWED SUBSET &allowedSubset]
+ [IMPOSED SUBSET &imposedSubset]
+ [ENTRY LIMIT &entryLimit]
+ ID &id
+}
+
+REQUEST-ATTRIBUTE ::= CLASS {
+ &attributeType ATTRIBUTE.&id,
+ &SelectedValues ATTRIBUTE.&Type OPTIONAL,
+ &DefaultValues SEQUENCE {entryType OBJECT-CLASS.&id OPTIONAL,
+ values SEQUENCE OF ATTRIBUTE.&Type
+ } OPTIONAL,
+ &contexts SEQUENCE OF ContextProfile OPTIONAL,
+ &contextCombination ContextCombination OPTIONAL,
+ &MatchingUse MatchingUse OPTIONAL,
+ &includeSubtypes BOOLEAN DEFAULT FALSE
+}
+WITH SYNTAX {
+ ATTRIBUTE TYPE &attributeType
+ [SELECTED VALUES &SelectedValues]
+ [DEFAULT VALUES &DefaultValues]
+ [CONTEXTS &contexts]
+ [CONTEXT COMBINATION &contextCombination]
+ [MATCHING USE &MatchingUse]
+ [INCLUDE SUBTYPES &includeSubtypes]
+}
+
+RESULT-ATTRIBUTE ::= CLASS {
+ &attributeType ATTRIBUTE.&id,
+ &outputValues OutputValues OPTIONAL,
+ &contexts ContextProfile OPTIONAL
+}
+WITH SYNTAX {
+ ATTRIBUTE TYPE &attributeType
+ [OUTPUT VALUES &outputValues]
+ [CONTEXTS &contexts]
+}
+
+MATCHING-RESTRICTION ::= CLASS {
+ &Restriction ,
+ &Rules MATCHING-RULE.&id,
+ &id OBJECT IDENTIFIER UNIQUE
+}WITH SYNTAX {RESTRICTION &Restriction
+ RULES &Rules
+ ID &id
+}
+
+-- object identifier assignments
+-- object classes
+id-oc-top OBJECT IDENTIFIER ::=
+ {id-oc 0}
+
+id-oc-alias OBJECT IDENTIFIER ::= {id-oc 1}
+
+id-oc-parent OBJECT IDENTIFIER ::= {id-oc 28}
+
+id-oc-child OBJECT IDENTIFIER ::= {id-oc 29}
+
+-- attributes
+id-at-objectClass OBJECT IDENTIFIER ::= {id-at 0}
+
+id-at-aliasedEntryName OBJECT IDENTIFIER ::= {id-at 1}
+
+-- matching rules
+id-mr-objectIdentifierMatch OBJECT IDENTIFIER ::= {id-mr 0}
+
+id-mr-distinguishedNameMatch OBJECT IDENTIFIER ::= {id-mr 1}
+
+-- operational attributes
+id-oa-excludeAllCollectiveAttributes OBJECT IDENTIFIER ::=
+ {id-oa 0}
+
+id-oa-createTimestamp OBJECT IDENTIFIER ::= {id-oa 1}
+
+id-oa-modifyTimestamp OBJECT IDENTIFIER ::= {id-oa 2}
+
+id-oa-creatorsName OBJECT IDENTIFIER ::= {id-oa 3}
+
+id-oa-modifiersName OBJECT IDENTIFIER ::= {id-oa 4}
+
+id-oa-administrativeRole OBJECT IDENTIFIER ::= {id-oa 5}
+
+id-oa-subtreeSpecification OBJECT IDENTIFIER ::= {id-oa 6}
+
+id-oa-collectiveExclusions OBJECT IDENTIFIER ::= {id-oa 7}
+
+id-oa-subschemaTimestamp OBJECT IDENTIFIER ::= {id-oa 8}
+
+id-oa-hasSubordinates OBJECT IDENTIFIER ::= {id-oa 9}
+
+id-oa-subschemaSubentryList OBJECT IDENTIFIER ::= {id-oa 10}
+
+id-oa-accessControlSubentryList OBJECT IDENTIFIER ::= {id-oa 11}
+
+id-oa-collectiveAttributeSubentryList OBJECT IDENTIFIER ::= {id-oa 12}
+
+id-oa-contextDefaultSubentryList OBJECT IDENTIFIER ::= {id-oa 13}
+
+id-oa-contextAssertionDefault OBJECT IDENTIFIER ::= {id-oa 14}
+
+id-oa-serviceAdminSubentryList OBJECT IDENTIFIER ::= {id-oa 15}
+
+id-oa-searchRules OBJECT IDENTIFIER ::= {id-oa 16}
+
+id-oa-hierarchyLevel OBJECT IDENTIFIER ::= {id-oa 17}
+
+id-oa-hierarchyBelow OBJECT IDENTIFIER ::= {id-oa 18}
+
+id-oa-hierarchyParent OBJECT IDENTIFIER ::= {id-oa 19}
+
+-- subentry classes
+id-sc-subentry OBJECT IDENTIFIER ::= {id-sc 0}
+
+id-sc-accessControlSubentry OBJECT IDENTIFIER ::= {id-sc 1}
+
+id-sc-collectiveAttributeSubentry OBJECT IDENTIFIER ::= {id-sc 2}
+
+id-sc-contextAssertionSubentry OBJECT IDENTIFIER ::= {id-sc 3}
+
+id-sc-serviceAdminSubentry OBJECT IDENTIFIER ::= {id-sc 4}
+
+-- Name forms
+id-nf-subentryNameForm OBJECT IDENTIFIER ::= {id-nf 16}
+
+-- administrative roles
+id-ar-autonomousArea OBJECT IDENTIFIER ::= {id-ar 1}
+
+id-ar-accessControlSpecificArea OBJECT IDENTIFIER ::= {id-ar 2}
+
+id-ar-accessControlInnerArea OBJECT IDENTIFIER ::= {id-ar 3}
+
+id-ar-subschemaAdminSpecificArea OBJECT IDENTIFIER ::= {id-ar 4}
+
+id-ar-collectiveAttributeSpecificArea OBJECT IDENTIFIER ::= {id-ar 5}
+
+id-ar-collectiveAttributeInnerArea OBJECT IDENTIFIER ::= {id-ar 6}
+
+id-ar-contextDefaultSpecificArea OBJECT IDENTIFIER ::= {id-ar 7}
+
+id-ar-serviceSpecificArea OBJECT IDENTIFIER ::= {id-ar 8}
+
+END -- InformationFramework
+
+-- Generated by Asnp, the ASN.1 pretty-printer of France Telecom R&D
+
diff --git a/lib/asn1/test/asn1_SUITE_data/Int.py b/lib/asn1/test/asn1_SUITE_data/Int.py
new file mode 100644
index 0000000000..dd218b8dbd
--- /dev/null
+++ b/lib/asn1/test/asn1_SUITE_data/Int.py
@@ -0,0 +1,12 @@
+Int DEFINITIONS IMPLICIT TAGS ::=
+BEGIN
+EXPORTS;
+
+Int ::= INTEGER
+Int2 ::= INTEGER (1..10)
+
+-- OTP-5457
+int11 INTEGER ::= 11
+int11-2 INTEGER ::= int11 --correct should not cause crash or warning
+
+END
diff --git a/lib/asn1/test/asn1_SUITE_data/LDAP.asn1 b/lib/asn1/test/asn1_SUITE_data/LDAP.asn1
new file mode 100755
index 0000000000..4d845942e1
--- /dev/null
+++ b/lib/asn1/test/asn1_SUITE_data/LDAP.asn1
@@ -0,0 +1,283 @@
+ --Lightweight-Directory-Access-Protocol-V3 {1 3 6 1 1 18}
+ -- Copyright (C) The Internet Society (2006). This version of
+ -- this ASN.1 module is part of RFC 4511; see the RFC itself
+ -- for full legal notices.
+ LDAP
+ DEFINITIONS
+ IMPLICIT TAGS
+ EXTENSIBILITY IMPLIED
+ ::=
+
+ BEGIN
+
+ LDAPMessage ::= SEQUENCE {
+ messageID MessageID,
+ protocolOp CHOICE {
+ bindRequest BindRequest,
+ bindResponse BindResponse,
+ unbindRequest UnbindRequest,
+ searchRequest SearchRequest,
+ searchResEntry SearchResultEntry,
+ searchResDone SearchResultDone,
+ searchResRef SearchResultReference,
+ modifyRequest ModifyRequest,
+ modifyResponse ModifyResponse,
+ addRequest AddRequest,
+ addResponse AddResponse,
+ delRequest DelRequest,
+ delResponse DelResponse,
+ modDNRequest ModifyDNRequest,
+ modDNResponse ModifyDNResponse,
+ compareRequest CompareRequest,
+ compareResponse CompareResponse,
+ abandonRequest AbandonRequest,
+ extendedReq ExtendedRequest,
+ extendedResp ExtendedResponse,
+ ...,
+ intermediateResponse IntermediateResponse },
+ controls [0] Controls OPTIONAL }
+
+ MessageID ::= INTEGER (0 .. maxInt)
+
+ maxInt INTEGER ::= 2147483647 -- (2^^31 - 1) --
+
+ LDAPString ::= OCTET STRING -- UTF-8 encoded,
+ -- [ISO10646] characters
+
+ LDAPOID ::= OCTET STRING -- Constrained to <numericoid>
+ -- [RFC4512]
+
+
+ LDAPDN ::= LDAPString -- Constrained to <distinguishedName>
+ -- [RFC4514]
+
+ RelativeLDAPDN ::= LDAPString -- Constrained to <name-component>
+ -- [RFC4514]
+
+ AttributeDescription ::= LDAPString
+ -- Constrained to <attributedescription>
+ -- [RFC4512]
+
+ AttributeValue ::= OCTET STRING
+
+ AttributeValueAssertion ::= SEQUENCE {
+ attributeDesc AttributeDescription,
+ assertionValue AssertionValue }
+
+ AssertionValue ::= OCTET STRING
+
+ PartialAttribute ::= SEQUENCE {
+ type AttributeDescription,
+ vals SET OF value AttributeValue }
+
+ Attribute ::= PartialAttribute(WITH COMPONENTS {
+ ...,
+ vals (SIZE(1..MAX))})
+
+ MatchingRuleId ::= LDAPString
+
+ LDAPResult ::= SEQUENCE {
+ resultCode ENUMERATED {
+ success (0),
+ operationsError (1),
+ protocolError (2),
+ timeLimitExceeded (3),
+ sizeLimitExceeded (4),
+ compareFalse (5),
+ compareTrue (6),
+ authMethodNotSupported (7),
+ strongerAuthRequired (8),
+ -- 9 reserved --
+ referral (10),
+ adminLimitExceeded (11),
+ unavailableCriticalExtension (12),
+ confidentialityRequired (13),
+ saslBindInProgress (14),
+
+ noSuchAttribute (16),
+ undefinedAttributeType (17),
+ inappropriateMatching (18),
+ constraintViolation (19),
+ attributeOrValueExists (20),
+ invalidAttributeSyntax (21),
+ -- 22-31 unused --
+ noSuchObject (32),
+ aliasProblem (33),
+ invalidDNSyntax (34),
+ -- 35 reserved for undefined isLeaf --
+ aliasDereferencingProblem (36),
+ -- 37-47 unused --
+ inappropriateAuthentication (48),
+ invalidCredentials (49),
+ insufficientAccessRights (50),
+ busy (51),
+ unavailable (52),
+ unwillingToPerform (53),
+ loopDetect (54),
+ -- 55-63 unused --
+ namingViolation (64),
+ objectClassViolation (65),
+ notAllowedOnNonLeaf (66),
+ notAllowedOnRDN (67),
+ entryAlreadyExists (68),
+ objectClassModsProhibited (69),
+ -- 70 reserved for CLDAP --
+ affectsMultipleDSAs (71),
+ -- 72-79 unused --
+ other (80),
+ ... },
+ matchedDN LDAPDN,
+ diagnosticMessage LDAPString,
+ referral [3] Referral OPTIONAL }
+
+ Referral ::= SEQUENCE SIZE (1..MAX) OF uri URI
+
+ URI ::= LDAPString -- limited to characters permitted in
+ -- URIs
+
+ Controls ::= SEQUENCE OF control Control
+
+ Control ::= SEQUENCE {
+ controlType LDAPOID,
+ criticality BOOLEAN DEFAULT FALSE,
+ controlValue OCTET STRING OPTIONAL }
+
+
+ BindRequest ::= [APPLICATION 0] SEQUENCE {
+ version INTEGER (1 .. 127),
+ name LDAPDN,
+ authentication AuthenticationChoice }
+
+ AuthenticationChoice ::= CHOICE {
+ simple [0] OCTET STRING,
+ -- 1 and 2 reserved
+ sasl [3] SaslCredentials,
+ ... }
+
+ SaslCredentials ::= SEQUENCE {
+ mechanism LDAPString,
+ credentials OCTET STRING OPTIONAL }
+
+ BindResponse ::= [APPLICATION 1] SEQUENCE {
+ COMPONENTS OF LDAPResult,
+ serverSaslCreds [7] OCTET STRING OPTIONAL }
+
+ UnbindRequest ::= [APPLICATION 2] NULL
+
+ SearchRequest ::= [APPLICATION 3] SEQUENCE {
+ baseObject LDAPDN,
+ scope ENUMERATED {
+ baseObject (0),
+ singleLevel (1),
+ wholeSubtree (2),
+ ... },
+ derefAliases ENUMERATED {
+ neverDerefAliases (0),
+ derefInSearching (1),
+ derefFindingBaseObj (2),
+ derefAlways (3) },
+ sizeLimit INTEGER (0 .. maxInt),
+ timeLimit INTEGER (0 .. maxInt),
+ typesOnly BOOLEAN,
+ filter Filter,
+ attributes AttributeSelection }
+
+ AttributeSelection ::= SEQUENCE OF selector LDAPString
+ -- The LDAPString is constrained to
+ -- <attributeSelector> in Section 4.5.1.8
+
+ Filter ::= CHOICE {
+ and [0] SET SIZE (1..MAX) OF filter Filter,
+ or [1] SET SIZE (1..MAX) OF filter Filter,
+ not [2] Filter,
+ equalityMatch [3] AttributeValueAssertion,
+ substrings [4] SubstringFilter,
+ greaterOrEqual [5] AttributeValueAssertion,
+ lessOrEqual [6] AttributeValueAssertion,
+ present [7] AttributeDescription,
+ approxMatch [8] AttributeValueAssertion,
+ extensibleMatch [9] MatchingRuleAssertion,
+ ... }
+
+ SubstringFilter ::= SEQUENCE {
+ type AttributeDescription,
+ substrings SEQUENCE SIZE (1..MAX) OF substring CHOICE {
+ initial [0] AssertionValue, -- can occur at most once
+ any [1] AssertionValue,
+ final [2] AssertionValue } -- can occur at most once
+ }
+
+ MatchingRuleAssertion ::= SEQUENCE {
+ matchingRule [1] MatchingRuleId OPTIONAL,
+ type [2] AttributeDescription OPTIONAL,
+ matchValue [3] AssertionValue,
+ dnAttributes [4] BOOLEAN DEFAULT FALSE }
+
+ SearchResultEntry ::= [APPLICATION 4] SEQUENCE {
+ objectName LDAPDN,
+ attributes PartialAttributeList }
+
+ PartialAttributeList ::= SEQUENCE OF
+ partialAttribute PartialAttribute
+
+ SearchResultReference ::= [APPLICATION 19] SEQUENCE
+ SIZE (1..MAX) OF uri URI
+
+ SearchResultDone ::= [APPLICATION 5] LDAPResult
+
+ ModifyRequest ::= [APPLICATION 6] SEQUENCE {
+ object LDAPDN,
+ changes SEQUENCE OF change SEQUENCE {
+ operation ENUMERATED {
+ add (0),
+ delete (1),
+ replace (2),
+ ... },
+ modification PartialAttribute } }
+
+ ModifyResponse ::= [APPLICATION 7] LDAPResult
+
+ AddRequest ::= [APPLICATION 8] SEQUENCE {
+ entry LDAPDN,
+ attributes AttributeList }
+
+ AttributeList ::= SEQUENCE OF attribute Attribute
+
+ AddResponse ::= [APPLICATION 9] LDAPResult
+
+ DelRequest ::= [APPLICATION 10] LDAPDN
+
+ DelResponse ::= [APPLICATION 11] LDAPResult
+
+ ModifyDNRequest ::= [APPLICATION 12] SEQUENCE {
+ entry LDAPDN,
+ newrdn RelativeLDAPDN,
+ deleteoldrdn BOOLEAN,
+ newSuperior [0] LDAPDN OPTIONAL }
+
+ ModifyDNResponse ::= [APPLICATION 13] LDAPResult
+
+ CompareRequest ::= [APPLICATION 14] SEQUENCE {
+ entry LDAPDN,
+ ava AttributeValueAssertion }
+
+ CompareResponse ::= [APPLICATION 15] LDAPResult
+
+ AbandonRequest ::= [APPLICATION 16] MessageID
+
+ ExtendedRequest ::= [APPLICATION 23] SEQUENCE {
+ requestName [0] LDAPOID,
+ requestValue [1] OCTET STRING OPTIONAL }
+
+ ExtendedResponse ::= [APPLICATION 24] SEQUENCE {
+ COMPONENTS OF LDAPResult,
+ responseName [10] LDAPOID OPTIONAL,
+ responseValue [11] OCTET STRING OPTIONAL }
+
+ IntermediateResponse ::= [APPLICATION 25] SEQUENCE {
+ responseName [0] LDAPOID OPTIONAL,
+ responseValue [1] OCTET STRING OPTIONAL }
+
+ END
+
+
diff --git a/lib/asn1/test/asn1_SUITE_data/M1.asn b/lib/asn1/test/asn1_SUITE_data/M1.asn
new file mode 100644
index 0000000000..f0575fb25f
--- /dev/null
+++ b/lib/asn1/test/asn1_SUITE_data/M1.asn
@@ -0,0 +1,24 @@
+M1 DEFINITIONS AUTOMATIC TAGS ::=
+
+BEGIN
+
+IMPORTS
+
+ Type6
+ FROM M2
+ ;
+
+Type1 ::= INTEGER (1..3)
+
+Type2 ::= ENUMERATED {one,two}
+
+Type3 ::= BOOLEAN
+
+Type4 ::= SEQUENCE {
+ a Type1,
+ b BOOLEAN
+}
+
+Type5 ::= OCTET STRING
+
+END
diff --git a/lib/asn1/test/asn1_SUITE_data/M2.asn b/lib/asn1/test/asn1_SUITE_data/M2.asn
new file mode 100644
index 0000000000..22d7fed6f1
--- /dev/null
+++ b/lib/asn1/test/asn1_SUITE_data/M2.asn
@@ -0,0 +1,29 @@
+M2 DEFINITIONS ::=
+
+BEGIN
+
+IMPORTS
+
+ Type5
+ FROM M1
+ ;
+
+Type1 ::= INTEGER (1..8)
+
+Type2 ::= ENUMERATED {one,two,three}
+
+Type3 ::= BOOLEAN
+
+Type4 ::= SEQUENCE {
+ a Type1,
+ b BOOLEAN,
+ c Type2,
+ d Type5
+}
+
+Type6 ::= SET {
+ a Type1,
+ b Type5
+}
+
+END
diff --git a/lib/asn1/test/asn1_SUITE_data/MAP-ExtensionDataTypes.asn b/lib/asn1/test/asn1_SUITE_data/MAP-ExtensionDataTypes.asn
new file mode 100644
index 0000000000..2a90c4265a
--- /dev/null
+++ b/lib/asn1/test/asn1_SUITE_data/MAP-ExtensionDataTypes.asn
@@ -0,0 +1,37 @@
+MAP-ExtensionDataTypes {
+ ccitt identified-organization (4) etsi (0) mobileDomain (0)
+ gsm-Network (1) modules (3) map-ExtensionDataTypes (21) version6 (6)}
+DEFINITIONS
+IMPLICIT TAGS
+::=
+BEGIN
+EXPORTS
+ PrivateExtension,
+ ExtensionContainer;
+-- IOC for private MAP extensions
+MAP-EXTENSION ::= CLASS {
+ &ExtensionType OPTIONAL,
+ &extensionId OBJECT IDENTIFIER }
+ -- The length of the Object Identifier shall not exceed 16 octets and the
+ -- number of components of the Object Identifier shall not exceed 16
+-- data types
+ExtensionContainer ::= SEQUENCE {
+ privateExtensionList [0]PrivateExtensionList OPTIONAL,
+ pcs-Extensions [1]PCS-Extensions OPTIONAL,
+ ...}
+PrivateExtensionList ::= SEQUENCE SIZE (1..maxNumOfPrivateExtensions) OF
+ PrivateExtension
+PrivateExtension ::= SEQUENCE {
+ extId MAP-EXTENSION.&extensionId
+ ({ExtensionSet}),
+ extType MAP-EXTENSION.&ExtensionType
+ ({ExtensionSet}{@extId}) OPTIONAL}
+maxNumOfPrivateExtensions INTEGER ::= 10
+ExtensionSet MAP-EXTENSION ::=
+ {...
+ -- ExtensionSet is the set of all defined private extensions
+ }
+ -- Unsupported private extensions shall be discarded if received.
+PCS-Extensions ::= SEQUENCE {
+ ...}
+END
diff --git a/lib/asn1/test/asn1_SUITE_data/MAP-commonDataTypes.py b/lib/asn1/test/asn1_SUITE_data/MAP-commonDataTypes.py
new file mode 100644
index 0000000000..694abefa6a
--- /dev/null
+++ b/lib/asn1/test/asn1_SUITE_data/MAP-commonDataTypes.py
@@ -0,0 +1,31 @@
+MAP-commonDataTypes
+ { iso (1) identified-organization (4) etsi (0) mobileDomain (0)
+ gsm-Network (1) modules (3) map-CommonDataTypes (18) version2 (2) }
+DEFINITIONS ::=
+BEGIN
+
+EXPORTS
+ TBCD-STRING,
+ AddressString,
+ ISDN-AddressString,
+ LMSI,
+ IMSI,
+ TMSI,
+-- IMSIBCD,
+ SubscriberID;
+
+
+ TBCD-STRING ::= OCTET STRING (SIZE(3..8))
+ AddressString ::= OCTET STRING (SIZE(1..20))
+ ISDN-AddressString ::= AddressString
+ LMSI ::= OCTET STRING (SIZE(4))
+ -- IMSIBCD ::= BCD-STRING
+ IMSI ::= TBCD-STRING
+ TMSI ::= OCTET STRING (SIZE(1..4))
+ SubscriberID ::= CHOICE{
+ imsi [0] IMSI,
+ tmsi [1] TMSI}
+
+
+END -- of MAP-commonDataTypes
+
diff --git a/lib/asn1/test/asn1_SUITE_data/MAP-insertSubscriberData-def.py b/lib/asn1/test/asn1_SUITE_data/MAP-insertSubscriberData-def.py
new file mode 100644
index 0000000000..298319b0ed
--- /dev/null
+++ b/lib/asn1/test/asn1_SUITE_data/MAP-insertSubscriberData-def.py
@@ -0,0 +1,102 @@
+MAP-insertSubscriberData-def
+ { ccitt (0) identified-organization( 4) etsi( 0) mobileDomain(0)
+ gsm-Network( 1) modules( 3) map-Protocol( 4) version2(2) }
+DEFINITIONS ::=
+
+BEGIN
+
+EXPORTS
+InsertSubsDataArg, InsertSubsDatRes;
+IMPORTS
+IMSI, ISDN-AddressString, LMSI FROM MAP-commonDataTypes;
+
+InsertSubsDataArg ::= SEQUENCE{
+ imsi [0] IMPLICIT IMSI OPTIONAL,
+ msisdn [1] IMPLICIT ISDN-AddressString OPTIONAL,
+ category [2] IMPLICIT OCTET STRING (SIZE(1)) OPTIONAL,
+ subscriberStatus [3] IMPLICIT SubscriberStatus OPTIONAL,
+ bearerServiceList [4] IMPLICIT SEQUENCE OF
+ OCTET STRING(SIZE(1)) OPTIONAL,
+ teleServiceList [6] IMPLICIT SEQUENCE OF
+ OCTET STRING(SIZE(1)) OPTIONAL,
+ provisionedSS [7] IMPLICIT SEQUENCE OF SS-Information OPTIONAL
+ }
+
+SS-Information ::= CHOICE{
+ forwardingInfo [0] IMPLICIT ForwardingInfo,
+ callBarringInfoInfo [1] IMPLICIT CallBarringInfoInfo,
+ ss-Data [3] IMPLICIT SS-Data }
+
+SS-Data ::= SEQUENCE {
+ ss-Code OCTET STRING (SIZE(1)),
+ ss-Status [4] IMPLICIT OCTET STRING (SIZE(1))
+ }
+
+
+ForwardingInfo ::= SEQUENCE {
+ ss-Code OCTET STRING(SIZE(1)) OPTIONAL,
+ forwardingFeatureList ForwardingFeatureList
+ }
+
+CallBarringInfoInfo ::= SEQUENCE {
+ ss-Code OCTET STRING(SIZE(1)) OPTIONAL,
+ callBarringFeatureList CallBarringFeatureList}
+
+CallBarringFeatureList ::= SEQUENCE OF CallBarringFeature
+
+CallBarringFeature ::= SEQUENCE{
+ basicService BasicServiceCode OPTIONAL,
+ ss-Status [2] IMPLICIT OCTET STRING(SIZE(1)) OPTIONAL
+ }
+
+InsertSubsDatRes ::=
+ SEQUENCE {
+ teleServiceList [1] IMPLICIT SEQUENCE OF
+ OCTET STRING (SIZE(1)) OPTIONAL,
+ bearerServiceList [2] IMPLICIT SEQUENCE OF
+ OCTET STRING (SIZE(1)) OPTIONAL,
+ ss-List [3] IMPLICIT SEQUENCE OF
+ OCTET STRING (SIZE(1)) OPTIONAL,
+ odb-GeneralData [4] IMPLICIT BIT STRING {
+ allOG-CallsBarred (0),
+ internationalOGCallsBarred (1),
+ internationalOGCallsNotToHPLMN-CountryBarred (2),
+ premiumRateInformationOGCallsBarred (3),
+ premiumRateEntertainementOGCallsBarred (4),
+ ss-AccessBarred (5) } (SIZE(6)) OPTIONAL,
+ regionalSubscriptionResponse [5] IMPLICIT ENUMERATED{
+ msc-AreaRestricted (0),
+ tooManyZoneCodes (1),
+ zoneCodeConflict (2),
+ regionalSubscNotSupported (3) } OPTIONAL
+ }
+
+
+ForwardingFeatureList ::= SEQUENCE OF ForwardingFeature
+
+ForwardingFeature ::= SEQUENCE{
+ basicService BasicServiceCode OPTIONAL,
+ ss-Status [4] IMPLICIT OCTET STRING(SIZE(1)) OPTIONAL,
+ forwardedToNumber [5] ISDN-AddressString OPTIONAL,
+ forwardingOptions [6] IMPLICIT OCTET STRING(SIZE(1)) OPTIONAL,
+ noReplyConditionTime [7] IMPLICIT INTEGER(5..30) OPTIONAL
+ }
+
+
+BasicServiceCode ::= CHOICE {
+ bearerService [2] IMPLICIT OCTET STRING(SIZE(1)),
+ teleService [3] IMPLICIT OCTET STRING(SIZE(1))
+ }
+
+
+BasicServiceGroupList ::= SEQUENCE OF
+ BasicServiceCode
+
+
+SubscriberStatus ::= ENUMERATED {
+ serviceGranted (0),
+ operatorDeterminedBarring (1)
+ }
+
+END -- of MAP-insertSubscriberData-def
+
diff --git a/lib/asn1/test/asn1_SUITE_data/MEDIA-GATEWAY-CONTROL.asn b/lib/asn1/test/asn1_SUITE_data/MEDIA-GATEWAY-CONTROL.asn
new file mode 100644
index 0000000000..71b765f71d
--- /dev/null
+++ b/lib/asn1/test/asn1_SUITE_data/MEDIA-GATEWAY-CONTROL.asn
@@ -0,0 +1,975 @@
+-- This ASN.1 spec has been extracted from the Megaco/H.248 spec
+-- http://www.ietf.org/internet-drafts/draft-ietf-megaco-merged-01.txt
+--
+-- o Removed stuff named nonStandard
+-- o Major enhancements of the indentation has been performed.
+--
+-- Hakan Mattsson <[email protected]>
+--
+-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
+-- ANNEX A: BINARY ENCODING OF THE PROTOCOL (NORMATIVE)
+-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
+--
+-- This Annex specifies the syntax of messages using the notation
+-- defined in ASN.1 [ITU-T Recommendation X.680 (1997): Information
+-- Technology - Abstract Syntax Notation One (ASN.1) - Specification of
+-- basic notation.]. Messages shall be encoded for transmission by
+-- applying the basic encoding rules specified in [ITU-T Recommendation
+-- X.690(1994) Information Technology - ASN.1 Encoding Rules:
+-- Specification of Basic Encoding Rules (BER)].
+--
+-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
+-- A.1 Coding of wildcards
+-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
+--
+-- The use of wildcards ALL and CHOOSE is allowed in the protocol.
+-- This allows a MGC to partially specify Termination IDs and let the
+-- MG choose from the values that conform to the partial specification.
+-- Termination IDs may encode a hierarchy of names. This hierarchy is
+-- provisioned. For instance, a TerminationID may consist of a trunk
+-- group, a trunk within the group and a circuit. Wildcarding must be
+-- possible at all levels. The following paragraphs explain how this
+-- is achieved.
+--
+-- The ASN.1 description uses octet strings of up to 8 octets in length
+-- for Termination IDs. This means that Termination IDs consist of at
+-- most 64 bits. A fully specified Termination ID may be preceded by a
+-- sequence of wildcarding fields. A wildcarding field is one octet in
+-- length. Bit 7 (the most significant bit) of this octet specifies
+-- what type of wildcarding is invoked: if the bit value equals 1,
+-- then the ALL wildcard is used; if the bit value if 0, then the
+-- CHOOSE wildcard is used. Bit 6 of the wildcarding field specifies
+-- whether the wildcarding pertains to one level in the hierarchical
+-- naming scheme (bit value 0) or to the level of the hierarchy
+-- specified in the wildcarding field plus all lower levels (bit value
+-- 1). Bits 0 through 5 of the wildcarding field specify the bit
+-- position in the Termination ID at which the starts.
+--
+-- We illustrate this scheme with some examples. In these examples,
+-- the most significant bit in a string of bits appears on the left
+-- hand side.
+--
+-- Assume that Termination IDs are three octets long and that each
+-- octet represents a level in a hierarchical naming scheme. A valid
+-- Termination ID is
+-- 00000001 00011110 01010101.
+--
+-- Addressing ALL names with prefix 00000001 00011110 is done as
+-- follows:
+-- wildcarding field: 10000111
+-- Termination ID: 00000001 00011110 xxxxxxxx.
+--
+-- The values of the bits labeled "x" is irrelevant and shall be
+-- ignored by the receiver.
+--
+-- Indicating to the receiver that is must choose a name with 00011110
+-- as the second octet is done as follows:
+-- wildcarding fields: 00010111 followed by 00000111
+-- Termination ID: xxxxxxxx 00011110 xxxxxxxx.
+--
+-- The first wildcard field indicates a CHOOSE wildcard for the level
+-- in the naming hierarchy starting at bit 23, the highest level in our
+-- assumed naming scheme. The second wildcard field indicates a CHOOSE
+-- wildcard for the level in the naming hierarchy starting at bit 7,
+-- the lowest level in our assumed naming scheme.
+--
+-- Finally, a CHOOSE-wildcarded name with the highest level of the name
+-- equal to 00000001 is specified as follows:
+-- wildcard field: 01001111
+-- Termination ID: 0000001 xxxxxxxx xxxxxxxx .
+--
+-- Bit value 1 at bit position 6 of the first octet of the wildcard
+-- field indicates that the wildcarding pertains to the specified level
+-- in the naming hierarchy and all lower levels.
+--
+-- Context IDs may also be wildcarded. In the case of Context IDs,
+-- however, specifying partial names is not allowed. Context ID 0x0
+-- SHALL be used to indicate the NULL Context, Context ID 0xFFFFFFFE
+-- SHALL be used to indicate a CHOOSE wildcard, and Context ID
+-- 0xFFFFFFFF SHALL be used to indicate an ALL wildcard.
+--
+-- TerminationID 0xFFFFFFFFFFFFFFFF SHALL be used to indicate the ROOT
+-- Termination.
+--
+-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
+-- Digit maps and path names
+-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
+--
+-- From a syntactic viewpoint, digit maps are strings with syntactic
+-- restrictions imposed upon them. The syntax of valid digit maps is
+-- specified in ABNF [RFC 2234]. The syntax for digit maps presented
+-- in this section is for illustrative purposes only. The definition of
+-- digitMap in Annex B takes precedence in the case of differences
+-- between the two.
+--
+-- digitMap = (digitString / LWSP "(" LWSP digitStringList LWSP ")"
+-- LWSP)
+-- digitStringList = digitString *( LWSP "/" LWSP digitString )
+-- digitString = 1*(digitStringElement)
+-- digitStringElement = digitPosition [DOT]
+-- digitPosition = digitMapLetter / digitMapRange
+-- digitMapRange = ("x" / LWSP "[" LWSP digitLetter LWSP "]" LWSP)
+-- digitLetter = *((DIGIT "-" DIGIT) /digitMapLetter)
+-- digitMapLetter = DIGIT ;digits 0-9
+-- / %x41-4B / %x61-6B ;a-k and A-K
+-- / "L" / "S" ;Inter-event timers
+-- ;(long, short)
+-- / "Z" ;Long duration event
+-- DOT = %x2E ; "."
+-- LWSP = *(WSP / COMMENT / EOL)
+-- WSP = SP / HTAB
+-- COMMENT = ";" *(SafeChar / RestChar / WSP) EOL
+-- EOL = (CR [LF]) / LF
+-- SP = %x20
+-- HTAB = %x09
+-- CR = %x0D
+-- LF = %x0A
+-- SafeChar = DIGIT / ALPHA / "+" / "-" / "&" / "!" / "_" / "/" /
+-- "'" / "?" / "@" / "^" / "`" / "~" / "*" / "$" / "\" /
+-- "(" / ")" / "%" / "."
+-- RestChar = ";" / "[" / "]" / "{" / "}" / ":" / "," / "#" /
+-- "<" / ">" / "=" / %x22
+-- DIGIT = %x30-39 ; digits 0 through 9
+-- ALPHA = %x41-5A / %x61-7A ; A-Z, a-z
+-- A path name is also a string with syntactic restrictions imposed
+-- upon it. The ABNF production defining it is copied from Annex B.
+--
+-- PathName = NAME *(["/"] ["*"] ["@"] (ALPHA / DIGIT)) ["*"]
+-- NAME = ALPHA *63(ALPHA / DIGIT / "_" )
+--
+-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
+-- A.2 ASN.1 syntax specification
+-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
+--
+-- This section contains the ASN.1 specification of the H.248 protocol
+-- syntax.
+--
+-- NOTE - In case a transport mechanism is used that employs
+-- application level framing, the definition of Transaction below
+-- changes. Refer to the annex defining the transport mechanism for
+-- the definition that applies in that case.
+--
+-- NOTE - The ASN.1 specification below contains a clause defining
+-- TerminationIDList as a sequence of TerminationIDs. The length of
+-- this sequence SHALL be one, except possibly when used in
+-- contextAuditResult.
+-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
+
+MEDIA-GATEWAY-CONTROL DEFINITIONS AUTOMATIC TAGS::=
+BEGIN
+
+MegacoMessage ::= SEQUENCE
+{
+ authHeader AuthenticationHeader OPTIONAL,
+ mess Message
+}
+
+AuthenticationHeader ::= SEQUENCE
+{
+ secParmIndex SecurityParmIndex,
+ seqNum SequenceNum,
+ ad AuthData
+}
+
+SecurityParmIndex ::= OCTET STRING(SIZE(4))
+
+SequenceNum ::= OCTET STRING(SIZE(4))
+
+AuthData ::= OCTET STRING (SIZE (12..32))
+
+Message ::= SEQUENCE
+{
+ version INTEGER(0..99),
+ -- The version of the protocol defined here is equal to 1.
+ mId MId, -- Name/address of message originator
+ messageBody CHOICE
+ {
+ messageError ErrorDescriptor,
+ transactions SEQUENCE OF Transaction
+ },
+ ...
+}
+
+MId ::= CHOICE
+{
+ ip4Address IP4Address,
+ ip6Address IP6Address,
+ domainName DomainName,
+ deviceName PathName,
+ mtpAddress OCTET STRING(SIZE(2..4)),
+ -- Addressing structure of mtpAddress:
+ -- 15 0
+ -- | PC | NI |
+ -- 14 bits 2 bits
+ ...
+}
+
+DomainName ::= SEQUENCE
+{
+ name IA5String,
+ -- The name starts with an alphanumeric digit followed by a
+ -- sequence of alphanumeric digits, hyphens and dots. No two
+ -- dots shall occur consecutively.
+ portNumber INTEGER(0..65535) OPTIONAL
+}
+
+IP4Address ::= SEQUENCE
+{
+ address OCTET STRING (SIZE(4)),
+ portNumber INTEGER(0..65535) OPTIONAL
+}
+
+IP6Address ::= SEQUENCE
+{
+ address OCTET STRING (SIZE(16)),
+ portNumber INTEGER(0..65535) OPTIONAL
+}
+
+PathName ::= IA5String(SIZE (1..64))
+-- See section A.3
+
+Transaction ::= CHOICE
+{
+ transactionRequest TransactionRequest,
+ transactionPending TransactionPending,
+ transactionReply TransactionReply,
+ transactionResponseAck TransactionResponseAck,
+ -- use of response acks is dependent on underlying transport
+ ...
+}
+
+TransactionId ::= INTEGER(0..4294967295) -- 32 bit unsigned integer
+
+TransactionRequest ::= SEQUENCE
+{
+ transactionId TransactionId,
+ actions SEQUENCE OF ActionRequest,
+ ...
+}
+
+TransactionPending ::= SEQUENCE
+{
+ transactionId TransactionId,
+ ...
+}
+
+TransactionReply ::= SEQUENCE
+{
+ transactionId TransactionId,
+ immAckRequired NULL OPTIONAL,
+ transactionResult CHOICE
+ {
+ transactionError ErrorDescriptor,
+ actionReplies SEQUENCE OF ActionReply
+ },
+ ...
+}
+
+TransactionResponseAck ::= SEQUENCE OF TransactionAck
+
+TransactionAck ::= SEQUENCE
+{
+ firstAck TransactionId,
+ lastAck TransactionId OPTIONAL
+}
+
+ErrorDescriptor ::= SEQUENCE
+{
+ errorCode ErrorCode,
+ errorText ErrorText OPTIONAL
+}
+
+ErrorCode ::= INTEGER(0..65535)
+-- See section 13 for IANA considerations w.r.t. error codes
+
+ErrorText ::= IA5String
+
+ContextID ::= INTEGER(0..4294967295)
+
+-- Context NULL Value: 0
+-- Context CHOOSE Value: 4294967294 (0xFFFFFFFE)
+-- Context ALL Value: 4294967295 (0xFFFFFFFF)
+
+
+ActionRequest ::= SEQUENCE
+{
+ contextId ContextID,
+ contextRequest ContextRequest OPTIONAL,
+ contextAttrAuditReq ContextAttrAuditRequest OPTIONAL,
+ commandRequests SEQUENCE OF CommandRequest
+}
+
+ActionReply ::= SEQUENCE
+{
+ contextId ContextID,
+ errorDescriptor ErrorDescriptor OPTIONAL,
+ contextReply ContextRequest OPTIONAL,
+ commandReply SEQUENCE OF CommandReply
+}
+
+ContextRequest ::= SEQUENCE
+{
+ priority INTEGER(0..15) OPTIONAL,
+ emergency BOOLEAN OPTIONAL,
+ topologyReq SEQUENCE OF TopologyRequest OPTIONAL,
+ ...
+}
+
+ContextAttrAuditRequest ::= SEQUENCE
+{
+ topology NULL OPTIONAL,
+ emergency NULL OPTIONAL,
+ priority NULL OPTIONAL,
+ ...
+}
+
+CommandRequest ::= SEQUENCE
+{
+ command Command,
+ optional NULL OPTIONAL,
+ wildcardReturn NULL OPTIONAL,
+ ...
+}
+
+Command ::= CHOICE
+{
+ addReq AmmRequest,
+ moveReq AmmRequest,
+ modReq AmmRequest,
+ -- Add, Move, Modify requests have the same parameters
+ subtractReq SubtractRequest,
+ auditCapRequest AuditRequest,
+ auditValueRequest AuditRequest,
+ notifyReq NotifyRequest,
+ serviceChangeReq ServiceChangeRequest,
+ ...
+}
+
+CommandReply ::= CHOICE
+{
+ addReply AmmsReply,
+ moveReply AmmsReply,
+ modReply AmmsReply,
+ subtractReply AmmsReply,
+ -- Add, Move, Modify, Subtract replies have the same parameters
+ auditCapReply AuditReply,
+ auditValueReply AuditReply,
+ notifyReply NotifyReply,
+ serviceChangeReply ServiceChangeReply,
+ ...
+}
+
+TopologyRequest ::= SEQUENCE
+{
+ terminationFrom TerminationID,
+ terminationTo TerminationID,
+ topologyDirection ENUMERATED
+ {
+ bothway(0),
+ isolate(1),
+ oneway(2)
+ }
+}
+
+AmmRequest ::= SEQUENCE
+{
+ terminationID TerminationIDList,
+ descriptors SEQUENCE OF AmmDescriptor,
+ -- At most one descriptor of each type (see AmmDescriptor)
+ -- allowed in the sequence.
+ ...
+}
+
+AmmDescriptor ::= CHOICE
+{
+ mediaDescriptor MediaDescriptor,
+ modemDescriptor ModemDescriptor,
+ muxDescriptor MuxDescriptor,
+ eventsDescriptor EventsDescriptor,
+ eventBufferDescriptor EventBufferDescriptor,
+ signalsDescriptor SignalsDescriptor,
+ digitMapDescriptor DigitMapDescriptor,
+ auditDescriptor AuditDescriptor,
+...
+}
+
+AmmsReply ::= SEQUENCE
+{
+ terminationID TerminationIDList,
+ terminationAudit TerminationAudit OPTIONAL,
+ ...
+}
+
+SubtractRequest ::= SEQUENCE
+{
+ terminationID TerminationIDList,
+ auditDescriptor AuditDescriptor OPTIONAL,
+ ...
+}
+
+AuditRequest ::= SEQUENCE
+{
+ terminationID TerminationID,
+ auditDescriptor AuditDescriptor,
+ ...
+}
+
+AuditReply ::= CHOICE
+{
+ contextAuditResult TerminationIDList,
+ error ErrorDescriptor,
+ auditResult AuditResult,
+ ...
+}
+
+AuditResult ::= SEQUENCE
+{
+ terminationID TerminationID,
+ terminationAuditResult TerminationAudit
+}
+
+TerminationAudit ::= SEQUENCE OF AuditReturnParameter
+
+AuditReturnParameter ::= CHOICE
+{
+ errorDescriptor ErrorDescriptor,
+ mediaDescriptor MediaDescriptor,
+ modemDescriptor ModemDescriptor,
+ muxDescriptor MuxDescriptor,
+ eventsDescriptor EventsDescriptor,
+ eventBufferDescriptor EventBufferDescriptor,
+ signalsDescriptor SignalsDescriptor,
+ digitMapDescriptor DigitMapDescriptor,
+ observedEventsDescriptor ObservedEventsDescriptor,
+ statisticsDescriptor StatisticsDescriptor,
+ packagesDescriptor PackagesDescriptor,
+ emptyDescriptors AuditDescriptor,
+ ...
+}
+
+AuditDescriptor ::= SEQUENCE
+{
+ auditToken BIT STRING
+ {
+ muxToken(0),
+ modemToken(1),
+ mediaToken(2),
+ eventsToken(3),
+ signalsToken(4),
+ digitMapToken(5),
+ statsToken(6),
+ observedEventsToken(7),
+ packagesToken(8),
+ eventBufferToken(9)
+ } OPTIONAL,
+ ...
+}
+
+NotifyRequest ::= SEQUENCE
+{
+ terminationID TerminationIDList,
+ observedEventsDescriptor ObservedEventsDescriptor,
+ errorDescriptor ErrorDescriptor OPTIONAL,
+ ...
+}
+
+NotifyReply ::= SEQUENCE
+{
+ terminationID TerminationIDList,
+ errorDescriptor ErrorDescriptor OPTIONAL,
+ ...
+}
+
+ObservedEventsDescriptor ::= SEQUENCE
+{
+ requestId RequestID,
+ observedEventLst SEQUENCE OF ObservedEvent
+}
+
+ObservedEvent ::= SEQUENCE
+{
+ eventName EventName,
+ streamID StreamID OPTIONAL,
+ eventParList SEQUENCE OF EventParameter,
+ timeNotation TimeNotation OPTIONAL,
+ ...
+}
+
+EventName ::= PkgdName
+
+EventParameter ::= SEQUENCE
+{
+ eventParameterName Name,
+ value Value,
+ -- For use of extraInfo see the comment related to propertyParm
+ extraInfo CHOICE
+ {
+ relation Relation,
+ range BOOLEAN,
+ sublist BOOLEAN
+ } OPTIONAL,
+ ...
+}
+
+ServiceChangeRequest ::= SEQUENCE
+{
+ terminationID TerminationIDList,
+ serviceChangeParms ServiceChangeParm,
+ ...
+}
+
+ServiceChangeReply ::= SEQUENCE
+{
+ terminationID TerminationIDList,
+ serviceChangeResult ServiceChangeResult,
+ ...
+}
+
+-- For ServiceChangeResult, no parameters are mandatory. Hence the
+-- distinction between ServiceChangeParm and ServiceChangeResParm.
+
+ServiceChangeResult ::= CHOICE
+{
+ errorDescriptor ErrorDescriptor,
+ serviceChangeResParms ServiceChangeResParm
+}
+
+WildcardField ::= OCTET STRING(SIZE(1))
+
+TerminationID ::= SEQUENCE
+{
+ wildcard SEQUENCE OF WildcardField,
+ id OCTET STRING(SIZE(1..8)),
+ ...
+}
+-- See Section A.1 for explanation of wildcarding mechanism.
+-- Termination ID 0xFFFFFFFFFFFFFFFF indicates the ROOT Termination.
+
+TerminationIDList ::= SEQUENCE OF TerminationID
+
+MediaDescriptor ::= SEQUENCE
+{
+
+ termStateDescr TerminationStateDescriptor OPTIONAL,
+ streams CHOICE
+ {
+ oneStream StreamParms,
+ multiStream SEQUENCE OF StreamDescriptor
+ } OPTIONAL,
+ ...
+}
+
+StreamDescriptor ::= SEQUENCE
+{
+ streamID StreamID,
+ streamParms StreamParms
+}
+
+StreamParms ::= SEQUENCE
+{
+ localControlDescriptor LocalControlDescriptor OPTIONAL,
+ localDescriptor LocalRemoteDescriptor OPTIONAL,
+ remoteDescriptor LocalRemoteDescriptor OPTIONAL,
+ ...
+}
+
+LocalControlDescriptor ::= SEQUENCE
+{
+ streamMode StreamMode OPTIONAL,
+ reserveValue BOOLEAN OPTIONAL,
+ reserveGroup BOOLEAN OPTIONAL,
+ propertyParms SEQUENCE OF PropertyParm,
+ ...
+}
+
+StreamMode ::= ENUMERATED
+{
+ sendOnly(0),
+ recvOnly(1),
+ sendRecv(2),
+ inactive(3),
+ loopBack(4),
+ ...
+}
+
+-- In PropertyParm, value is a SEQUENCE OF octet string. When sent
+-- by an MGC the interpretation is as follows:
+-- empty sequence means CHOOSE
+-- one element sequence specifies value
+-- If the sublist field is not selected, a longer sequence means
+-- "choose one of the values" (i.e. value1 OR value2 OR ...)
+-- If the sublist field is selected,
+-- a sequence with more than one element encodes the value of a
+-- list-valued property (i.e. value1 AND value2 AND ...).
+-- The relation field may only be selected if the value sequence
+-- has length 1. It indicates that the MG has to choose a value
+-- for the property. E.g., x > 3 (using the greaterThan
+-- value for relation) instructs the MG to choose any value larger
+-- than 3 for property x.
+-- The range field may only be selected if the value sequence
+-- has length 2. It indicates that the MG has to choose a value
+-- in the range between the first octet in the value sequence and
+-- the trailing octet in the value sequence, including the
+-- boundary values.
+-- When sent by the MG, only responses to an AuditCapability request
+-- may contain multiple values, a range, or a relation field.
+
+PropertyParm ::= SEQUENCE
+{
+ name PkgdName,
+ value SEQUENCE OF OCTET STRING,
+ extraInfo CHOICE
+ {
+ relation Relation,
+ range BOOLEAN,
+ sublist BOOLEAN
+ } OPTIONAL,
+ ...
+}
+
+Name ::= OCTET STRING(SIZE(2))
+
+PkgdName ::= OCTET STRING(SIZE(4))
+-- represents Package Name (2 octets) plus Property Name (2 octets)
+-- To wildcard a package use 0xFFFF for first two octets, choose
+-- is not allowed. To reference native property tag specified in
+-- Annex C, use 0x0000 as first two octets.
+-- Wildcarding of Package Name is permitted only if Property Name is
+-- also wildcarded.
+
+Relation ::= ENUMERATED
+{
+ greaterThan(0),
+ smallerThan(1),
+ unequalTo(2),
+ ...
+}
+
+LocalRemoteDescriptor ::= SEQUENCE
+{
+ propGrps SEQUENCE OF PropertyGroup,
+ ...
+}
+
+PropertyGroup ::= SEQUENCE OF PropertyParm
+
+TerminationStateDescriptor ::= SEQUENCE
+{
+ propertyParms SEQUENCE OF PropertyParm,
+ eventBufferControl EventBufferControl OPTIONAL,
+ serviceState ServiceState OPTIONAL,
+ ...
+}
+
+EventBufferControl ::= ENUMERATED
+{
+ off(0),
+ lockStep(1),
+ ...
+}
+
+ServiceState ::= ENUMERATED
+{
+ test(0),
+ outOfSvc(1),
+ inSvc(2),
+ ...
+}
+
+MuxDescriptor ::= SEQUENCE
+{
+ muxType MuxType,
+ termList SEQUENCE OF TerminationID,
+ nonStandardData NonStandardData OPTIONAL,
+ ...
+}
+
+MuxType ::= ENUMERATED
+{
+ h221(0),
+ h223(1),
+ h226(2),
+ v76(3),
+ ...
+}
+
+StreamID ::= INTEGER(0..65535) -- 16 bit unsigned integer
+
+EventsDescriptor ::= SEQUENCE
+{
+ requestID RequestID,
+ -- IG 6.82 was withdrawn
+ -- requestID RequestID OPTIONAL,
+ -- RequestID must be present if eventList is non empty
+ eventList SEQUENCE OF RequestedEvent,
+ ...
+}
+
+RequestedEvent ::= SEQUENCE
+{
+ pkgdName PkgdName,
+ streamID StreamID OPTIONAL,
+ eventAction RequestedActions OPTIONAL,
+ evParList SEQUENCE OF EventParameter,
+ ...
+}
+
+RequestedActions ::= SEQUENCE
+{
+ keepActive BOOLEAN OPTIONAL,
+ eventDM EventDM OPTIONAL,
+ secondEvent SecondEventsDescriptor OPTIONAL,
+ signalsDescriptor SignalsDescriptor OPTIONAL,
+ ...
+}
+
+
+EventDM ::= CHOICE
+{
+ digitMapName DigitMapName,
+ digitMapValue DigitMapValue
+}
+
+SecondEventsDescriptor ::= SEQUENCE
+{
+ requestID RequestID,
+ -- IG 6.82 was withdrawn
+ -- requestID RequestID OPTIONAL,
+ -- RequestID must be present if eventList is non empty
+ eventList SEQUENCE OF SecondRequestedEvent,
+ ...
+}
+
+SecondRequestedEvent ::= SEQUENCE
+{
+ pkgdName PkgdName,
+ streamID StreamID OPTIONAL,
+ eventAction SecondRequestedActions OPTIONAL,
+ evParList SEQUENCE OF EventParameter,
+ ...
+}
+
+SecondRequestedActions ::= SEQUENCE
+{
+ keepActive BOOLEAN OPTIONAL,
+ eventDM EventDM OPTIONAL,
+ signalsDescriptor SignalsDescriptor OPTIONAL,
+ ...
+}
+
+EventBufferDescriptor ::= SEQUENCE OF EventSpec
+
+EventSpec ::= SEQUENCE
+{
+ eventName EventName,
+ streamID StreamID OPTIONAL,
+ eventParList SEQUENCE OF EventParameter,
+ ...
+}
+
+SignalsDescriptor ::= SEQUENCE OF SignalRequest
+
+SignalRequest ::= CHOICE
+{
+ signal Signal,
+ seqSigList SeqSigList,
+ ...
+}
+
+SeqSigList ::= SEQUENCE
+{
+ id INTEGER(0..65535),
+ signalList SEQUENCE OF Signal
+}
+
+Signal ::= SEQUENCE
+{
+ signalName SignalName,
+ streamID StreamID OPTIONAL,
+ sigType SignalType OPTIONAL,
+ duration INTEGER (0..65535) OPTIONAL,
+ notifyCompletion NotifyCompletion OPTIONAL,
+ keepActive BOOLEAN OPTIONAL,
+ sigParList SEQUENCE OF SigParameter,
+ ...
+}
+
+SignalType ::= ENUMERATED
+{
+ brief(0),
+ onOff(1),
+ timeOut(2),
+ ...
+}
+
+SignalName ::= PkgdName
+
+NotifyCompletion ::= BIT STRING
+{
+ onTimeOut(0),
+ onInterruptByEvent(1),
+ onInterruptByNewSignalDescr(2),
+ otherReason(3)
+}
+
+SigParameter ::= SEQUENCE
+{
+ sigParameterName Name,
+ value Value,
+ -- For use of extraInfo see the comment related to propertyParm
+ extraInfo CHOICE
+ {
+ relation Relation,
+ range BOOLEAN,
+ sublist BOOLEAN
+ } OPTIONAL,
+ ...
+}
+
+RequestID ::= INTEGER(0..4294967295) -- 32 bit unsigned integer
+-- Request ALL Value: 4294967295 (0xFFFFFFFF)
+
+ModemDescriptor ::= SEQUENCE
+{
+ mtl SEQUENCE OF ModemType,
+ mpl SEQUENCE OF PropertyParm,
+ nonStandardData NonStandardData OPTIONAL
+}
+
+ModemType ::= ENUMERATED
+{
+ v18(0),
+ v22(1),
+ v22bis(2),
+ v32(3),
+ v32bis(4),
+ v34(5),
+ v90(6),
+ v91(7),
+ synchISDN(8),
+ ...
+}
+
+DigitMapDescriptor ::= SEQUENCE
+{
+ digitMapName DigitMapName OPTIONAL,
+ digitMapValue DigitMapValue OPTIONAL
+}
+
+DigitMapName ::= Name
+
+DigitMapValue ::= SEQUENCE
+{
+ startTimer INTEGER(0..99) OPTIONAL,
+ shortTimer INTEGER(0..99) OPTIONAL,
+ longTimer INTEGER(0..99) OPTIONAL,
+ digitMapBody IA5String,
+ -- See Section A.3 for explanation of digit map syntax
+ ...
+}
+
+ServiceChangeParm ::= SEQUENCE
+{
+ serviceChangeMethod ServiceChangeMethod,
+ serviceChangeAddress ServiceChangeAddress OPTIONAL,
+ serviceChangeVersion INTEGER(0..99) OPTIONAL,
+ serviceChangeProfile ServiceChangeProfile OPTIONAL,
+ serviceChangeReason Value,
+ serviceChangeDelay INTEGER(0..4294967295) OPTIONAL,
+ -- 32 bit unsigned integer
+ serviceChangeMgcId MId OPTIONAL,
+ timeStamp TimeNotation OPTIONAL,
+ nonStandardData NonStandardData OPTIONAL,
+ ...
+}
+
+ServiceChangeAddress ::= CHOICE
+{
+ portNumber INTEGER(0..65535), -- TCP/UDP port number
+ ip4Address IP4Address,
+ ip6Address IP6Address,
+ domainName DomainName,
+ deviceName PathName,
+ mtpAddress OCTET STRING(SIZE(2..4)),
+ ...
+}
+
+ServiceChangeResParm ::= SEQUENCE
+{
+ serviceChangeMgcId MId OPTIONAL,
+ serviceChangeAddress ServiceChangeAddress OPTIONAL,
+ serviceChangeVersion INTEGER(0..99) OPTIONAL,
+ serviceChangeProfile ServiceChangeProfile OPTIONAL,
+ timeStamp TimeNotation OPTIONAL,
+ ...
+}
+
+ServiceChangeMethod ::= ENUMERATED
+{
+ failover(0),
+ forced(1),
+ graceful(2),
+ restart(3),
+ disconnected(4),
+ handOff(5),
+ ...
+}
+
+ServiceChangeProfile ::= SEQUENCE
+{
+ profileName Name,
+ version INTEGER(0..99)
+}
+
+PackagesDescriptor ::= SEQUENCE OF PackagesItem
+
+PackagesItem ::= SEQUENCE
+{
+ packageName Name,
+ packageVersion INTEGER(0..99),
+ ...
+}
+
+StatisticsDescriptor ::= SEQUENCE OF StatisticsParameter
+
+StatisticsParameter ::= SEQUENCE
+{
+ statName PkgdName,
+ statValue Value OPTIONAL
+}
+
+NonStandardData ::= SEQUENCE
+{
+ nonStandardIdentifier NonStandardIdentifier,
+ data OCTET STRING
+}
+
+NonStandardIdentifier ::= CHOICE
+{
+ object OBJECT IDENTIFIER,
+ h221NonStandard H221NonStandard,
+ experimental IA5String(SIZE(8)),
+ -- first two characters should be "X-" or "X+"
+ ...
+}
+
+H221NonStandard ::= SEQUENCE
+{
+ t35CountryCode1 INTEGER(0..255),
+ t35CountryCode2 INTEGER(0..255), -- country, as per T.35
+ t35Extension INTEGER(0..255), -- assigned nationally
+ manufacturerCode INTEGER(0..65535), -- assigned nationally
+ ...
+}
+
+TimeNotation ::= SEQUENCE
+{
+ date IA5String(SIZE(8)), -- yyyymmdd format
+ time IA5String(SIZE(8)) -- hhmmssss format
+}
+
+Value ::= SEQUENCE OF OCTET STRING
+
+
+END
+
diff --git a/lib/asn1/test/asn1_SUITE_data/MEDIA-GATEWAY-CONTROL.asn1config b/lib/asn1/test/asn1_SUITE_data/MEDIA-GATEWAY-CONTROL.asn1config
new file mode 100644
index 0000000000..b7dba3c95c
--- /dev/null
+++ b/lib/asn1/test/asn1_SUITE_data/MEDIA-GATEWAY-CONTROL.asn1config
@@ -0,0 +1,7 @@
+{exclusive_decode,
+ {'MEDIA-GATEWAY-CONTROL',
+ [{decode_MegacoMessage_exclusive,['MegacoMessage',[{authHeader,undecoded},{mess,[{mId,undecoded},{messageBody,undecoded}]}]]},
+ {decode_Message_version,['Message',[{mId,undecoded},{messageBody,undecoded}]]}]}}.
+{selective_decode,
+ {'MEDIA-GATEWAY-CONTROL',
+ [{decode_MegacoMessage_selective,['MegacoMessage',mess,version]}]}}.
diff --git a/lib/asn1/test/asn1_SUITE_data/MS.set.asn b/lib/asn1/test/asn1_SUITE_data/MS.set.asn
new file mode 100644
index 0000000000..bcc74b2a96
--- /dev/null
+++ b/lib/asn1/test/asn1_SUITE_data/MS.set.asn
@@ -0,0 +1,2 @@
+M1.asn
+M2.asn
diff --git a/lib/asn1/test/asn1_SUITE_data/MULTIMEDIA-SYSTEM-CONTROL.asn b/lib/asn1/test/asn1_SUITE_data/MULTIMEDIA-SYSTEM-CONTROL.asn
new file mode 100644
index 0000000000..afbc7dc5ef
--- /dev/null
+++ b/lib/asn1/test/asn1_SUITE_data/MULTIMEDIA-SYSTEM-CONTROL.asn
@@ -0,0 +1,3084 @@
+MULTIMEDIA-SYSTEM-CONTROL DEFINITIONS AUTOMATIC TAGS ::=
+BEGIN
+
+-- Export all symbols
+
+-- ===================================================================================
+-- Top level Messages
+-- ===================================================================================
+
+MultimediaSystemControlMessage ::=CHOICE
+{
+ request RequestMessage,
+ response ResponseMessage,
+ command CommandMessage,
+ indication IndicationMessage,
+ ...
+}
+
+-- A RequestMessage results in action and requires an immediate response
+
+RequestMessage ::=CHOICE
+{
+ nonStandard NonStandardMessage,
+
+ masterSlaveDetermination MasterSlaveDetermination,
+
+ terminalCapabilitySet TerminalCapabilitySet,
+
+ openLogicalChannel OpenLogicalChannel,
+ closeLogicalChannel CloseLogicalChannel,
+
+ requestChannelClose RequestChannelClose,
+
+ multiplexEntrySend MultiplexEntrySend,
+
+ requestMultiplexEntry RequestMultiplexEntry,
+
+ requestMode RequestMode,
+
+ roundTripDelayRequest RoundTripDelayRequest,
+
+ maintenanceLoopRequest MaintenanceLoopRequest,
+
+ ...,
+ communicationModeRequest CommunicationModeRequest,
+ conferenceRequest ConferenceRequest
+}
+
+-- A ResponseMessage is the response to a request Message
+
+ResponseMessage ::=CHOICE
+{
+ nonStandard NonStandardMessage,
+
+ masterSlaveDeterminationAck MasterSlaveDeterminationAck,
+ masterSlaveDeterminationReject MasterSlaveDeterminationReject,
+
+ terminalCapabilitySetAck TerminalCapabilitySetAck,
+ terminalCapabilitySetReject TerminalCapabilitySetReject,
+
+ openLogicalChannelAck OpenLogicalChannelAck,
+ openLogicalChannelReject OpenLogicalChannelReject,
+ closeLogicalChannelAck CloseLogicalChannelAck,
+
+ requestChannelCloseAck RequestChannelCloseAck,
+ requestChannelCloseReject RequestChannelCloseReject,
+
+ multiplexEntrySendAck MultiplexEntrySendAck,
+ multiplexEntrySendReject MultiplexEntrySendReject,
+
+ requestMultiplexEntryAck RequestMultiplexEntryAck,
+ requestMultiplexEntryReject RequestMultiplexEntryReject,
+
+ requestModeAck RequestModeAck,
+ requestModeReject RequestModeReject,
+
+ roundTripDelayResponse RoundTripDelayResponse,
+
+ maintenanceLoopAck MaintenanceLoopAck,
+ maintenanceLoopReject MaintenanceLoopReject,
+
+ ...,
+ communicationModeResponse CommunicationModeResponse,
+
+ conferenceResponse ConferenceResponse
+
+
+}
+
+-- A CommandMessage requires action, but no explicit response
+
+CommandMessage ::=CHOICE
+{
+ nonStandard NonStandardMessage,
+
+ maintenanceLoopOffCommand MaintenanceLoopOffCommand,
+
+ sendTerminalCapabilitySet SendTerminalCapabilitySet,
+
+ encryptionCommand EncryptionCommand,
+
+ flowControlCommand FlowControlCommand,
+
+ endSessionCommand EndSessionCommand,
+
+ miscellaneousCommand MiscellaneousCommand,
+
+ ...,
+ communicationModeCommand CommunicationModeCommand,
+
+ conferenceCommand ConferenceCommand,
+
+ h223MultiplexReconfiguration H223MultiplexReconfiguration
+
+}
+
+-- An IndicationMessage is information that does not require action or response
+
+IndicationMessage ::=CHOICE
+{
+ nonStandard NonStandardMessage,
+
+ functionNotUnderstood FunctionNotUnderstood,
+
+ masterSlaveDeterminationRelease MasterSlaveDeterminationRelease,
+
+ terminalCapabilitySetRelease TerminalCapabilitySetRelease,
+
+ openLogicalChannelConfirm OpenLogicalChannelConfirm,
+
+ requestChannelCloseRelease RequestChannelCloseRelease,
+
+ multiplexEntrySendRelease MultiplexEntrySendRelease,
+
+ requestMultiplexEntryRelease RequestMultiplexEntryRelease,
+
+ requestModeRelease RequestModeRelease,
+
+ miscellaneousIndication MiscellaneousIndication,
+
+ jitterIndication JitterIndication,
+
+ h223SkewIndication H223SkewIndication,
+
+ newATMVCIndication NewATMVCIndication,
+
+ userInput UserInputIndication,
+ ...,
+ h2250MaximumSkewIndication H2250MaximumSkewIndication,
+
+ mcLocationIndication MCLocationIndication,
+
+ conferenceIndication ConferenceIndication,
+
+ vendorIdentification VendorIdentification,
+
+ functionNotSupported FunctionNotSupported
+
+}
+
+-- SequenceNumber is defined here as it is used in a number of Messages
+SequenceNumber ::=INTEGER (0..255)
+
+-- ===================================================================================
+-- Non standard Message definitions
+-- ===================================================================================
+
+NonStandardMessage ::=SEQUENCE
+{
+ nonStandardData NonStandardParameter,
+ ...
+}
+
+NonStandardParameter ::=SEQUENCE
+{
+ nonStandardIdentifier NonStandardIdentifier,
+ data OCTET STRING
+}
+
+NonStandardIdentifier ::=CHOICE
+{
+ object OBJECT IDENTIFIER,
+ h221NonStandard SEQUENCE
+ {
+ t35CountryCode INTEGER (0..255), -- country, per T.35
+ t35Extension INTEGER (0..255), -- assigned nationally
+ manufacturerCode INTEGER (0..65535) -- assigned nationally
+ }
+}
+
+-- ===================================================================================
+-- Master-slave determination definitions
+-- ===================================================================================
+
+MasterSlaveDetermination ::=SEQUENCE
+{
+ terminalType INTEGER (0..255),
+ statusDeterminationNumber INTEGER (0..16777215),
+ ...
+}
+
+MasterSlaveDeterminationAck ::=SEQUENCE
+{
+ decision CHOICE
+ {
+ master NULL,
+ slave NULL
+ },
+ ...
+}
+
+MasterSlaveDeterminationReject ::=SEQUENCE
+{
+ cause CHOICE
+ {
+ identicalNumbers NULL,
+ ...
+ },
+ ...
+}
+
+MasterSlaveDeterminationRelease ::=SEQUENCE
+{
+ ...
+}
+
+ -- ===================================================================================
+-- Capability exchange definitions
+-- ===================================================================================
+
+TerminalCapabilitySet ::=SEQUENCE
+{
+ sequenceNumber SequenceNumber,
+
+ protocolIdentifier OBJECT IDENTIFIER,
+ -- shall be set to the value
+ -- {itu-t (0) recommendation (0) h (8) 245 version (0) 3}
+
+
+ multiplexCapability MultiplexCapability OPTIONAL,
+
+ capabilityTable SET SIZE (1..256) OF CapabilityTableEntry OPTIONAL,
+
+ capabilityDescriptors SET SIZE (1..256) OF CapabilityDescriptor OPTIONAL,
+
+ ...
+}
+
+CapabilityTableEntry ::=SEQUENCE
+{
+ capabilityTableEntryNumber CapabilityTableEntryNumber,
+ capability Capability OPTIONAL
+}
+
+CapabilityDescriptor ::=SEQUENCE
+{
+ capabilityDescriptorNumber CapabilityDescriptorNumber,
+ simultaneousCapabilities SET SIZE (1..256) OF AlternativeCapabilitySet OPTIONAL
+}
+
+AlternativeCapabilitySet ::=SEQUENCE SIZE (1..256) OF CapabilityTableEntryNumber
+
+CapabilityTableEntryNumber ::=INTEGER (1..65535)
+
+CapabilityDescriptorNumber ::=INTEGER (0..255)
+
+TerminalCapabilitySetAck ::=SEQUENCE
+{
+ sequenceNumber SequenceNumber,
+ ...
+}
+
+TerminalCapabilitySetReject ::=SEQUENCE
+{
+ sequenceNumber SequenceNumber,
+ cause CHOICE
+ {
+ unspecified NULL,
+ undefinedTableEntryUsed NULL,
+ descriptorCapacityExceeded NULL,
+ tableEntryCapacityExceeded CHOICE
+ {
+ highestEntryNumberProcessed CapabilityTableEntryNumber,
+ noneProcessed NULL
+ },
+ ...
+ },
+ ...
+}
+
+TerminalCapabilitySetRelease ::=SEQUENCE
+{
+ ...
+}
+
+-- ===================================================================================
+-- Capability exchange definitions: top level capability description
+-- ===================================================================================
+
+Capability ::=CHOICE
+{
+ nonStandard NonStandardParameter,
+
+ receiveVideoCapability VideoCapability,
+ transmitVideoCapability VideoCapability,
+ receiveAndTransmitVideoCapability VideoCapability,
+
+ receiveAudioCapability AudioCapability,
+ transmitAudioCapability AudioCapability,
+ receiveAndTransmitAudioCapability AudioCapability,
+
+ receiveDataApplicationCapability DataApplicationCapability,
+ transmitDataApplicationCapability DataApplicationCapability,
+ receiveAndTransmitDataApplicationCapability DataApplicationCapability,
+
+ h233EncryptionTransmitCapability BOOLEAN,
+ h233EncryptionReceiveCapability SEQUENCE
+ {
+ h233IVResponseTime INTEGER (0..255), -- units milliseconds
+ ...
+ },
+ ...,
+ conferenceCapability ConferenceCapability,
+ h235SecurityCapability H235SecurityCapability,
+ maxPendingReplacementFor INTEGER (0..255),
+ receiveUserInputCapability UserInputCapability,
+ transmitUserInputCapability UserInputCapability,
+ receiveAndTransmitUserInputCapability UserInputCapability
+
+}
+
+H235SecurityCapability ::=SEQUENCE
+{
+ encryptionAuthenticationAndIntegrity EncryptionAuthenticationAndIntegrity,
+
+ mediaCapability CapabilityTableEntryNumber,
+ -- Note: the mediaCapability shall refer to Capability Table Entries that do contain a transmit,
+ -- receive, or receiveAndTransmit AudioCapability, VideoCapability,
+ -- DataApplicationCapability, or similar capability indicated by a NonStandardParameter only
+
+ ...
+}
+
+-- ===================================================================================
+-- Capability exchange definitions: Multiplex capabilities
+-- ===================================================================================
+
+MultiplexCapability ::=CHOICE
+{
+ nonStandard NonStandardParameter,
+ h222Capability H222Capability,
+ h223Capability H223Capability,
+ v76Capability V76Capability,
+ ...,
+ h2250Capability H2250Capability
+
+}
+
+H222Capability ::= SEQUENCE
+{
+ numberOfVCs INTEGER (1..256),
+ vcCapability SET OF VCCapability,
+ ...
+}
+
+VCCapability ::=SEQUENCE
+{
+ aal1 SEQUENCE
+ {
+ nullClockRecovery BOOLEAN,
+ srtsClockRecovery BOOLEAN,
+ adaptiveClockRecovery BOOLEAN,
+ nullErrorCorrection BOOLEAN,
+ longInterleaver BOOLEAN,
+ shortInterleaver BOOLEAN,
+ errorCorrectionOnly BOOLEAN,
+ structuredDataTransfer BOOLEAN,
+ partiallyFilledCells BOOLEAN,
+ ...
+ } OPTIONAL,
+ aal5 SEQUENCE
+ {
+ forwardMaximumSDUSize INTEGER (0..65535), -- units octets
+ backwardMaximumSDUSize INTEGER (0..65535), -- units octets
+ ...
+ } OPTIONAL,
+ transportStream BOOLEAN,
+ programStream BOOLEAN,
+ availableBitRates SEQUENCE
+ {
+ type CHOICE
+ {
+ singleBitRate INTEGER (1..65535), -- units 64 kbit/s
+ rangeOfBitRates SEQUENCE
+ {
+ lowerBitRate INTEGER (1..65535), -- units 64 kbit/s
+ higherBitRate INTEGER (1..65535) -- units 64 kbit/s
+ }
+ },
+ ...
+ },
+ ...
+}
+
+H223Capability ::=SEQUENCE
+{
+ transportWithI-frames BOOLEAN, -- I-frame transport of H.245
+
+ videoWithAL1 BOOLEAN,
+ videoWithAL2 BOOLEAN,
+ videoWithAL3 BOOLEAN,
+ audioWithAL1 BOOLEAN,
+ audioWithAL2 BOOLEAN,
+ audioWithAL3 BOOLEAN,
+ dataWithAL1 BOOLEAN,
+ dataWithAL2 BOOLEAN,
+ dataWithAL3 BOOLEAN,
+
+ maximumAl2SDUSize INTEGER (0..65535), -- units octets
+ maximumAl3SDUSize INTEGER (0..65535), -- units octets
+
+ maximumDelayJitter INTEGER (0..1023), -- units milliseconds
+
+ h223MultiplexTableCapability CHOICE
+ {
+ basic NULL,
+ enhanced SEQUENCE
+ {
+ maximumNestingDepth INTEGER (1..15),
+ maximumElementListSize INTEGER (2..255),
+ maximumSubElementListSize INTEGER (2..255),
+ ...
+ }
+ },
+ ...,
+ maxMUXPDUSizeCapability BOOLEAN,
+ nsrpSupport BOOLEAN,
+ mobileOperationTransmitCapability SEQUENCE
+ {
+ modeChangeCapability BOOLEAN,
+ h223AnnexA BOOLEAN,
+ h223AnnexADoubleFlag BOOLEAN,
+ h223AnnexB BOOLEAN,
+ h223AnnexBwithHeader BOOLEAN,
+ ...
+ } OPTIONAL,
+ h223AnnexCCapability H223AnnexCCapability OPTIONAL
+
+}
+
+H223AnnexCCapability ::= SEQUENCE
+{
+ videoWithAL1M BOOLEAN,
+ videoWithAL2M BOOLEAN,
+ videoWithAL3M BOOLEAN,
+ audioWithAL1M BOOLEAN,
+ audioWithAL2M BOOLEAN,
+ audioWithAL3M BOOLEAN,
+ dataWithAL1M BOOLEAN,
+ dataWithAL2M BOOLEAN,
+ dataWithAL3M BOOLEAN,
+ alpduInterleaving BOOLEAN,
+
+ maximumAL1MPDUSize INTEGER (0..65535), -- units octets
+ maximumAL2MSDUSize INTEGER (0..65535), -- units octets
+ maximumAL3MSDUSize INTEGER (0..65535), -- units octets
+ ...
+}
+
+V76Capability ::=SEQUENCE
+{
+ suspendResumeCapabilitywAddress BOOLEAN,
+ suspendResumeCapabilitywoAddress BOOLEAN,
+ rejCapability BOOLEAN,
+ sREJCapability BOOLEAN,
+ mREJCapability BOOLEAN,
+ crc8bitCapability BOOLEAN,
+ crc16bitCapability BOOLEAN,
+ crc32bitCapability BOOLEAN,
+ uihCapability BOOLEAN,
+ numOfDLCS INTEGER (2..8191),
+ twoOctetAddressFieldCapability BOOLEAN,
+ loopBackTestCapability BOOLEAN,
+ n401Capability INTEGER (1..4095),
+ maxWindowSizeCapability INTEGER (1..127),
+ v75Capability V75Capability,
+ ...
+}
+
+V75Capability ::=SEQUENCE
+{
+ audioHeader BOOLEAN,
+ ...
+}
+
+H2250Capability ::=SEQUENCE
+{
+ maximumAudioDelayJitter INTEGER(0..1023), -- units in milliseconds
+ receiveMultipointCapability MultipointCapability,
+ transmitMultipointCapability MultipointCapability,
+ receiveAndTransmitMultipointCapability MultipointCapability,
+ mcCapability SEQUENCE
+ {
+ centralizedConferenceMC BOOLEAN,
+ decentralizedConferenceMC BOOLEAN,
+ ...
+ },
+ rtcpVideoControlCapability BOOLEAN, -- FIR and NACK
+ mediaPacketizationCapability MediaPacketizationCapability,
+ ...,
+ transportCapability TransportCapability OPTIONAL,
+ redundancyEncodingCapability SEQUENCE SIZE(1..256) OF RedundancyEncodingCapability OPTIONAL,
+ logicalChannelSwitchingCapability BOOLEAN,
+ t120DynamicPortCapability BOOLEAN
+
+}
+
+MediaPacketizationCapability ::=SEQUENCE
+{
+ h261aVideoPacketization BOOLEAN,
+ ...,
+ rtpPayloadType SEQUENCE SIZE(1..256) OF RTPPayloadType OPTIONAL
+}
+
+RSVPParameters ::=SEQUENCE
+{
+ qosMode QOSMode OPTIONAL,
+ tokenRate INTEGER (1..4294967295) OPTIONAL,
+ -- rate in bytes/sec
+ bucketSize INTEGER (1..4294967295) OPTIONAL, -- size in bytes
+ peakRate INTEGER (1..4294967295) OPTIONAL,
+ -- peak bandwidth bytes/sec
+ minPoliced INTEGER (1..4294967295) OPTIONAL, --
+ maxPktSize INTEGER (1..4294967295) OPTIONAL, -- size in bytes
+ ...
+}
+
+QOSMode ::=CHOICE
+{
+ guaranteedQOS NULL,
+ controlledLoad NULL,
+ ...
+}
+
+-- Ed. Replace with ITU-T ATM Transfer Capability Types
+ATMParameters ::=SEQUENCE
+{
+ maxNTUSize INTEGER(0..65535), --units in octets
+ atmUBR BOOLEAN, --unspecified bit rate
+ atmrtVBR BOOLEAN, --real time variable bit rate
+ atmnrtVBR BOOLEAN, --non real time variable bit rate
+ atmABR BOOLEAN, --available bit rate
+ atmCBR BOOLEAN, --constant bit rate
+ ...
+}
+
+QOSCapability ::=SEQUENCE
+{
+ nonStandardData NonStandardParameter OPTIONAL,
+ rsvpParameters RSVPParameters OPTIONAL,
+ atmParameters ATMParameters OPTIONAL,
+ ...
+}
+
+MediaTransportType ::=CHOICE
+{
+ ip-UDP NULL,
+ ip-TCP NULL,
+ atm-AAL5-UNIDIR NULL, -- virtual circuits used as unidirectional
+ atm-AAL5-BIDIR NULL, -- virtual circuits used as bidirectional
+ ...
+}
+
+MediaChannelCapability ::=SEQUENCE
+{
+ mediaTransport MediaTransportType OPTIONAL,
+ ...
+}
+
+TransportCapability ::=SEQUENCE
+{
+ nonStandard NonStandardParameter OPTIONAL,
+ qOSCapabilities SEQUENCE SIZE(1..256) OF QOSCapability OPTIONAL,
+ mediaChannelCapabilities SEQUENCE SIZE(1..256) OF MediaChannelCapability OPTIONAL,
+ ...
+}
+
+RedundancyEncodingCapability ::=SEQUENCE
+{
+ redundancyEncodingMethod RedundancyEncodingMethod,
+ primaryEncoding CapabilityTableEntryNumber,
+ secondaryEncoding SEQUENCE SIZE(1..256) OF CapabilityTableEntryNumber OPTIONAL,
+ ...
+}
+
+RedundancyEncodingMethod ::=CHOICE
+{
+ nonStandard NonStandardParameter,
+ rtpAudioRedundancyEncoding NULL,
+ ...,
+ rtpH263VideoRedundancyEncoding RTPH263VideoRedundancyEncoding
+}
+
+RTPH263VideoRedundancyEncoding ::= SEQUENCE
+{
+ numberOfThreads INTEGER (1..16),
+ framesBetweenSyncPoints INTEGER (1..256),
+ frameToThreadMapping CHOICE
+ {
+ roundrobin NULL,
+ custom SEQUENCE SIZE(1..256) OF
+ RTPH263VideoRedundancyFrameMapping,
+-- empty SEQUENCE for capability negotiation
+-- meaningful contents only OpenLogicalChannel
+ ...
+ },
+ containedThreads SEQUENCE SIZE(1..256) OF INTEGER (0..15) OPTIONAL,
+ -- only used for opening of logical channels
+ ...
+}
+
+RTPH263VideoRedundancyFrameMapping ::= SEQUENCE
+{
+ threadNumber INTEGER (0..15),
+ frameSequence SEQUENCE SIZE(1..256) OF INTEGER (0..255),
+ ...
+}
+
+MultipointCapability ::=SEQUENCE
+{
+ multicastCapability BOOLEAN,
+ multiUniCastConference BOOLEAN,
+ mediaDistributionCapability SEQUENCE OF MediaDistributionCapability,
+ ...
+}
+
+MediaDistributionCapability ::=SEQUENCE
+{
+ centralizedControl BOOLEAN,
+ distributedControl BOOLEAN, -- for further study in H.323
+ centralizedAudio BOOLEAN,
+ distributedAudio BOOLEAN,
+ centralizedVideo BOOLEAN,
+ distributedVideo BOOLEAN,
+ centralizedData SEQUENCE OF DataApplicationCapability OPTIONAL,
+ distributedData SEQUENCE OF DataApplicationCapability OPTIONAL,
+ -- for further study in H.323
+ ...
+}
+
+
+
+-- ===================================================================================
+-- Capability exchange definitions: Video capabilities
+-- ===================================================================================
+
+VideoCapability ::=CHOICE
+{
+ nonStandard NonStandardParameter ,
+ h261VideoCapability H261VideoCapability,
+ h262VideoCapability H262VideoCapability,
+ h263VideoCapability H263VideoCapability,
+ is11172VideoCapability IS11172VideoCapability,
+ ...
+}
+
+H261VideoCapability ::=SEQUENCE
+{
+ qcifMPI INTEGER (1..4) OPTIONAL, -- units 1/29.97 Hz
+ cifMPI INTEGER (1..4) OPTIONAL, -- units 1/29.97 Hz
+ temporalSpatialTradeOffCapability BOOLEAN,
+ maxBitRate INTEGER (1..19200), -- units of 100 bit/s
+ stillImageTransmission BOOLEAN, -- Annex D of H.261
+ ...
+}
+
+H262VideoCapability ::=SEQUENCE
+{
+ profileAndLevel-SPatML BOOLEAN,
+ profileAndLevel-MPatLL BOOLEAN,
+ profileAndLevel-MPatML BOOLEAN,
+ profileAndLevel-MPatH-14 BOOLEAN,
+ profileAndLevel-MPatHL BOOLEAN,
+ profileAndLevel-SNRatLL BOOLEAN,
+ profileAndLevel-SNRatML BOOLEAN,
+ profileAndLevel-SpatialatH-14 BOOLEAN,
+ profileAndLevel-HPatML BOOLEAN,
+ profileAndLevel-HPatH-14 BOOLEAN,
+ profileAndLevel-HPatHL BOOLEAN,
+ videoBitRate INTEGER (0.. 1073741823) OPTIONAL, -- units 400 bit/s
+ vbvBufferSize INTEGER (0.. 262143) OPTIONAL, -- units 16384 bits
+ samplesPerLine INTEGER (0..16383) OPTIONAL, -- units samples/line
+ linesPerFrame INTEGER (0..16383) OPTIONAL, -- units lines/frame
+ framesPerSecond INTEGER (0..15) OPTIONAL, -- frame_rate_code
+ luminanceSampleRate INTEGER (0..4294967295) OPTIONAL, -- units samples/sec
+ ...
+}
+
+H263VideoCapability ::=SEQUENCE
+{
+ sqcifMPI INTEGER (1..32) OPTIONAL, -- units 1/29.97 Hz
+ qcifMPI INTEGER (1..32) OPTIONAL, -- units 1/29.97 Hz
+ cifMPI INTEGER (1..32) OPTIONAL, -- units 1/29.97 Hz
+ cif4MPI INTEGER (1..32) OPTIONAL, -- units 1/29.97 Hz
+ cif16MPI INTEGER (1..32) OPTIONAL, -- units 1/29.97 Hz
+ maxBitRate INTEGER (1..192400), -- units 100 bit/s
+ unrestrictedVector BOOLEAN,
+ arithmeticCoding BOOLEAN,
+ advancedPrediction BOOLEAN,
+ pbFrames BOOLEAN,
+ temporalSpatialTradeOffCapability BOOLEAN,
+ hrd-B INTEGER (0..524287) OPTIONAL, -- units 128 bits
+ bppMaxKb INTEGER (0..65535) OPTIONAL, -- units 1024 bits
+ ...,
+
+ slowSqcifMPI INTEGER (1..3600) OPTIONAL, -- units seconds/frame
+ slowQcifMPI INTEGER (1..3600) OPTIONAL, --units seconds/frame
+ slowCifMPI INTEGER (1..3600) OPTIONAL, --units seconds/frame
+ slowCif4MPI INTEGER (1..3600) OPTIONAL, --units seconds/frame
+ slowCif16MPI INTEGER (1..3600) OPTIONAL, --units seconds/frame
+ errorCompensation BOOLEAN,
+
+ enhancementLayerInfo EnhancementLayerInfo OPTIONAL,
+ h263Options H263Options OPTIONAL
+
+}
+
+EnhancementLayerInfo ::=SEQUENCE
+{
+ baseBitRateConstrained BOOLEAN,
+ snrEnhancement SET SIZE(1..14) OF EnhancementOptions OPTIONAL,
+ spatialEnhancement SET SIZE(1..14) OF EnhancementOptions OPTIONAL,
+ bPictureEnhancement SET SIZE(1..14) OF BEnhancementParameters OPTIONAL,
+ ...
+}
+
+BEnhancementParameters ::=SEQUENCE
+{
+ enhancementOptions EnhancementOptions,
+ numberOfBPictures INTEGER (1..64),
+ ...
+}
+
+EnhancementOptions ::=SEQUENCE
+{
+ sqcifMPI INTEGER (1..32) OPTIONAL, -- units 1/29.97 Hz
+ qcifMPI INTEGER (1..32) OPTIONAL, -- units 1/29.97 Hz
+ cifMPI INTEGER (1..32) OPTIONAL, -- units 1/29.97 Hz
+ cif4MPI INTEGER (1..32) OPTIONAL, -- units 1/29.97 Hz
+ cif16MPI INTEGER (1..32) OPTIONAL, -- units 1/29.97 Hz
+ maxBitRate INTEGER (1..192400), -- units 100 bit/s
+ unrestrictedVector BOOLEAN,
+ arithmeticCoding BOOLEAN,
+ temporalSpatialTradeOffCapability BOOLEAN,
+ slowSqcifMPI INTEGER (1..3600) OPTIONAL, -- units econds/frame
+ slowQcifMPI INTEGER (1..3600) OPTIONAL, --units seconds/frame
+ slowCifMPI INTEGER (1..3600) OPTIONAL, --units seconds/frame
+ slowCif4MPI INTEGER (1..3600) OPTIONAL, --units seconds/frame
+ slowCif16MPI INTEGER (1..3600) OPTIONAL, --units seconds/frame
+ errorCompensation BOOLEAN,
+ h263Options H263Options OPTIONAL,
+ ...
+}
+
+H263Options ::= SEQUENCE
+{
+ advancedIntraCodingMode BOOLEAN,
+ deblockingFilterMode BOOLEAN,
+ improvedPBFramesMode BOOLEAN,
+
+ unlimitedMotionVectors BOOLEAN,
+
+ fullPictureFreeze BOOLEAN,
+ partialPictureFreezeAndRelease BOOLEAN,
+ resizingPartPicFreezeAndRelease BOOLEAN,
+ fullPictureSnapshot BOOLEAN,
+ partialPictureSnapshot BOOLEAN,
+ videoSegmentTagging BOOLEAN,
+ progressiveRefinement BOOLEAN,
+
+ dynamicPictureResizingByFour BOOLEAN,
+ dynamicPictureResizingSixteenthPel BOOLEAN,
+ dynamicWarpingHalfPel BOOLEAN,
+ dynamicWarpingSixteenthPel BOOLEAN,
+
+ independentSegmentDecoding BOOLEAN,
+
+ slicesInOrder-NonRect BOOLEAN,
+ slicesInOrder-Rect BOOLEAN,
+ slicesNoOrder-NonRect BOOLEAN,
+ slicesNoOrder-Rect BOOLEAN,
+
+ alternateInterVLCMode BOOLEAN,
+ modifiedQuantizationMode BOOLEAN,
+ reducedResolutionUpdate BOOLEAN,
+
+ transparencyParameters TransparencyParameters OPTIONAL,
+ separateVideoBackChannel BOOLEAN,
+ refPictureSelection RefPictureSelection OPTIONAL,
+ customPictureClockFrequency SET SIZE (1..16) OF CustomPictureClockFrequency OPTIONAL,
+ customPictureFormat SET SIZE (1..16) OF CustomPictureFormat OPTIONAL,
+ modeCombos SET SIZE (1..16) OF H263VideoModeCombos OPTIONAL,
+ ...
+}
+
+TransparencyParameters ::= SEQUENCE
+{
+ presentationOrder INTEGER(1..256),
+ offset-x INTEGER(-262144..262143), -- 1/8 pixels
+ offset-y INTEGER(-262144..262143), -- 1/8 pixels
+ scale-x INTEGER(1..255),
+ scale-y INTEGER(1..255),
+ ...
+}
+
+RefPictureSelection ::=SEQUENCE
+{
+ additionalPictureMemory SEQUENCE
+ {
+ sqcifAdditionalPictureMemory INTEGER (1..256) OPTIONAL, -- units frame
+ qcifAdditionalPictureMemory INTEGER (1..256) OPTIONAL, -- units frame
+ cifAdditionalPictureMemory INTEGER (1..256) OPTIONAL, -- units frame
+ cif4AdditionalPictureMemory INTEGER (1..256) OPTIONAL, -- units frame
+ cif16AdditionalPictureMemory INTEGER (1..256) OPTIONAL, -- units frame
+ bigCpfAdditionalPictureMemory INTEGER (1..256) OPTIONAL, -- units frame
+ ...
+ } OPTIONAL,
+ videoMux BOOLEAN,
+ videoBackChannelSend CHOICE
+ {
+ none NULL,
+ ackMessageOnly NULL,
+ nackMessageOnly NULL,
+ ackOrNackMessageOnly NULL,
+ ackAndNackMessage NULL,
+ ...
+ },
+ ...
+}
+
+CustomPictureClockFrequency ::=SEQUENCE
+{
+ clockConversionCode INTEGER(1000..1001),
+ clockDivisor INTEGER(1..127),
+ sqcifMPI INTEGER (1..2048) OPTIONAL,
+ qcifMPI INTEGER (1..2048) OPTIONAL,
+ cifMPI INTEGER (1..2048) OPTIONAL,
+ cif4MPI INTEGER (1..2048) OPTIONAL,
+ cif16MPI INTEGER (1..2048) OPTIONAL,
+ ...
+}
+
+CustomPictureFormat ::=SEQUENCE
+{
+ maxCustomPictureWidth INTEGER(1..2048), -- units 4 pixels
+ maxCustomPictureHeight INTEGER(1..2048), -- units 4 pixels
+ minCustomPictureWidth INTEGER(1..2048), -- units 4 pixels
+ minCustomPictureHeight INTEGER(1..2048), -- units 4 pixels
+ mPI SEQUENCE
+ {
+ standardMPI INTEGER (1..31) OPTIONAL,
+ customPCF SET SIZE (1..16) OF SEQUENCE
+ {
+ clockConversionCode INTEGER (1000..1001),
+ clockDivisor INTEGER (1..127),
+ customMPI INTEGER (1..2048),
+ ...
+ } OPTIONAL,
+ ...
+ },
+
+ pixelAspectInformation CHOICE
+ {
+ anyPixelAspectRatio BOOLEAN,
+ pixelAspectCode SET SIZE (1..14) OF INTEGER(1..14),
+ extendedPAR SET SIZE (1..256) OF SEQUENCE
+ {
+ width INTEGER(1..255),
+ height INTEGER(1..255),
+ ...
+ },
+ ...
+ } ,
+ ...
+}
+
+H263VideoModeCombos ::= SEQUENCE
+{
+ h263VideoUncoupledModes H263ModeComboFlags,
+ h263VideoCoupledModes SET SIZE (1..16) OF H263ModeComboFlags,
+ ...
+}
+
+H263ModeComboFlags ::= SEQUENCE
+{
+ unrestrictedVector BOOLEAN,
+ arithmeticCoding BOOLEAN,
+ advancedPrediction BOOLEAN,
+ pbFrames BOOLEAN,
+ advancedIntraCodingMode BOOLEAN,
+ deblockingFilterMode BOOLEAN,
+ unlimitedMotionVectors BOOLEAN,
+ slicesInOrder-NonRect BOOLEAN,
+ slicesInOrder-Rect BOOLEAN,
+ slicesNoOrder-NonRect BOOLEAN,
+ slicesNoOrder-Rect BOOLEAN,
+ improvedPBFramesMode BOOLEAN,
+ referencePicSelect BOOLEAN,
+ dynamicPictureResizingByFour BOOLEAN,
+ dynamicPictureResizingSixteenthPel BOOLEAN,
+ dynamicWarpingHalfPel BOOLEAN,
+ dynamicWarpingSixteenthPel BOOLEAN,
+ reducedResolutionUpdate BOOLEAN,
+ independentSegmentDecoding BOOLEAN,
+ alternateInterVLCMode BOOLEAN,
+ modifiedQuantizationMode BOOLEAN,
+ ...
+}
+
+IS11172VideoCapability ::=SEQUENCE
+{
+ constrainedBitstream BOOLEAN,
+ videoBitRate INTEGER (0.. 1073741823) OPTIONAL, -- units 400 bit/s
+ vbvBufferSize INTEGER (0.. 262143) OPTIONAL, -- units 16384 bits
+ samplesPerLine INTEGER (0..16383) OPTIONAL, -- units samples/line
+ linesPerFrame INTEGER (0..16383) OPTIONAL, -- units lines/frame
+ pictureRate INTEGER (0..15) OPTIONAL,
+ luminanceSampleRate INTEGER (0..4294967295) OPTIONAL, -- units samples/sec
+ ...
+}
+
+-- ===================================================================================
+-- Capability exchange definitions: Audio capabilities
+-- ===================================================================================
+
+-- For an H.222 multiplex, the integers indicate the size of the STD buffer in units of 256 octets
+-- For an H.223 multiplex, the integers indicate the maximum number of audio frames per AL-SDU
+-- For an H.225.0 multiplex, the integers indicate the maximum number of audio frames per packet
+
+AudioCapability ::=CHOICE
+{
+ nonStandard NonStandardParameter,
+ g711Alaw64k INTEGER (1..256),
+ g711Alaw56k INTEGER (1..256),
+ g711Ulaw64k INTEGER (1..256),
+ g711Ulaw56k INTEGER (1..256),
+
+ g722-64k INTEGER (1..256),
+ g722-56k INTEGER (1..256),
+ g722-48k INTEGER (1..256),
+
+ g7231 SEQUENCE
+ {
+ maxAl-sduAudioFrames INTEGER (1..256),
+ silenceSuppression BOOLEAN
+ },
+
+ g728 INTEGER (1..256),
+ g729 INTEGER (1..256),
+ g729AnnexA INTEGER (1..256),
+ is11172AudioCapability IS11172AudioCapability,
+ is13818AudioCapability IS13818AudioCapability,
+ ...,
+ g729wAnnexB INTEGER(1..256),
+ g729AnnexAwAnnexB INTEGER(1..256),
+ g7231AnnexCCapability G7231AnnexCCapability,
+ gsmFullRate GSMAudioCapability,
+ gsmHalfRate GSMAudioCapability,
+ gsmEnhancedFullRate GSMAudioCapability
+}
+
+G7231AnnexCCapability ::= SEQUENCE
+{
+ maxAl-sduAudioFrames INTEGER (1..256),
+ silenceSuppression BOOLEAN,
+ g723AnnexCAudioMode SEQUENCE
+ {
+ highRateMode0 INTEGER (27..78), -- units octets
+ highRateMode1 INTEGER (27..78), -- units octets
+ lowRateMode0 INTEGER (23..66), -- units octets
+ lowRateMode1 INTEGER (23..66), -- units octets
+ sidMode0 INTEGER (6..17), -- units octets
+ sidMode1 INTEGER (6..17), -- units octets
+ ...
+ } OPTIONAL,
+ ...
+}
+
+IS11172AudioCapability ::=SEQUENCE
+{
+ audioLayer1 BOOLEAN,
+ audioLayer2 BOOLEAN,
+ audioLayer3 BOOLEAN,
+
+ audioSampling32k BOOLEAN,
+ audioSampling44k1 BOOLEAN,
+ audioSampling48k BOOLEAN,
+
+ singleChannel BOOLEAN,
+ twoChannels BOOLEAN,
+
+ bitRate INTEGER (1..448), -- units kbit/s
+ ...
+}
+
+IS13818AudioCapability ::=SEQUENCE
+{
+ audioLayer1 BOOLEAN,
+ audioLayer2 BOOLEAN,
+ audioLayer3 BOOLEAN,
+
+ audioSampling16k BOOLEAN,
+ audioSampling22k05 BOOLEAN,
+ audioSampling24k BOOLEAN,
+ audioSampling32k BOOLEAN,
+ audioSampling44k1 BOOLEAN,
+ audioSampling48k BOOLEAN,
+
+ singleChannel BOOLEAN,
+ twoChannels BOOLEAN,
+ threeChannels2-1 BOOLEAN,
+ threeChannels3-0 BOOLEAN,
+ fourChannels2-0-2-0 BOOLEAN,
+ fourChannels2-2 BOOLEAN,
+ fourChannels3-1 BOOLEAN,
+ fiveChannels3-0-2-0 BOOLEAN,
+ fiveChannels3-2 BOOLEAN,
+
+ lowFrequencyEnhancement BOOLEAN,
+
+ multilingual BOOLEAN,
+
+ bitRate INTEGER (1..1130), -- units kbit/s
+ ...
+}
+
+GSMAudioCapability ::= SEQUENCE
+{
+ audioUnitSize INTEGER (1..256),
+ comfortNoise BOOLEAN,
+ scrambled BOOLEAN,
+ ...
+}
+
+-- ===================================================================================
+-- Capability exchange definitions: Data capabilities
+-- ===================================================================================
+
+DataApplicationCapability ::=SEQUENCE
+{
+ application CHOICE
+ {
+ nonStandard NonStandardParameter,
+ t120 DataProtocolCapability,
+ dsm-cc DataProtocolCapability,
+ userData DataProtocolCapability,
+ t84 SEQUENCE
+ {
+ t84Protocol DataProtocolCapability,
+ t84Profile T84Profile
+ },
+ t434 DataProtocolCapability,
+ h224 DataProtocolCapability,
+ nlpid SEQUENCE
+ {
+ nlpidProtocol DataProtocolCapability,
+ nlpidData OCTET STRING
+ },
+ dsvdControl NULL,
+ h222DataPartitioning DataProtocolCapability,
+ ...,
+ t30fax DataProtocolCapability,
+ t140 DataProtocolCapability
+ },
+ maxBitRate INTEGER (0..4294967295), -- units 100 bit/s
+ ...
+}
+
+DataProtocolCapability ::=CHOICE
+{
+ nonStandard NonStandardParameter,
+ v14buffered NULL,
+ v42lapm NULL, -- may negotiate to V.42bis
+ hdlcFrameTunnelling NULL,
+ h310SeparateVCStack NULL,
+ h310SingleVCStack NULL,
+ transparent NULL,
+ ...,
+ segmentationAndReassembly NULL,
+ hdlcFrameTunnelingwSAR NULL,
+ v120 NULL, -- as in H.230
+ separateLANStack NULL,
+ v76wCompression CHOICE
+ {
+ transmitCompression CompressionType,
+ receiveCompression CompressionType,
+ transmitAndReceiveCompression CompressionType,
+ ...
+ }
+}
+
+CompressionType ::=CHOICE
+{
+ v42bis V42bis,
+ ...
+}
+
+V42bis ::=SEQUENCE
+{
+ numberOfCodewords INTEGER (1..65536),
+ maximumStringLength INTEGER (1..256),
+ ...
+}
+
+T84Profile ::=CHOICE
+{
+ t84Unrestricted NULL,
+ t84Restricted SEQUENCE
+ {
+ qcif BOOLEAN,
+ cif BOOLEAN,
+ ccir601Seq BOOLEAN,
+ ccir601Prog BOOLEAN,
+ hdtvSeq BOOLEAN,
+ hdtvProg BOOLEAN,
+
+ g3FacsMH200x100 BOOLEAN,
+ g3FacsMH200x200 BOOLEAN,
+ g4FacsMMR200x100 BOOLEAN,
+ g4FacsMMR200x200 BOOLEAN,
+ jbig200x200Seq BOOLEAN,
+ jbig200x200Prog BOOLEAN,
+ jbig300x300Seq BOOLEAN,
+ jbig300x300Prog BOOLEAN,
+
+ digPhotoLow BOOLEAN,
+ digPhotoMedSeq BOOLEAN,
+ digPhotoMedProg BOOLEAN,
+ digPhotoHighSeq BOOLEAN,
+ digPhotoHighProg BOOLEAN,
+
+ ...
+ }
+}
+
+-- ===================================================================================
+-- Encryption Capability Definitions:
+-- ===================================================================================
+
+EncryptionAuthenticationAndIntegrity ::=SEQUENCE
+{
+ encryptionCapability EncryptionCapability OPTIONAL,
+ authenticationCapability AuthenticationCapability OPTIONAL,
+ integrityCapability IntegrityCapability OPTIONAL,
+ ...
+}
+
+EncryptionCapability ::=SEQUENCE SIZE(1..256) OF MediaEncryptionAlgorithm
+
+MediaEncryptionAlgorithm ::=CHOICE
+{
+ nonStandard NonStandardParameter,
+ algorithm OBJECT IDENTIFIER, -- many defined in ISO/IEC 9979
+ ...
+}
+
+AuthenticationCapability ::=SEQUENCE
+{
+ nonStandard NonStandardParameter OPTIONAL,
+ ...
+}
+
+IntegrityCapability ::=SEQUENCE
+{
+ nonStandard NonStandardParameter OPTIONAL,
+ ...
+}
+
+-- ================================================================================
+-- Capability Exchange Definitions: UserInput
+-- ================================================================================
+
+UserInputCapability ::= CHOICE
+{
+ nonStandard SEQUENCE SIZE(1..16) OF NonStandardParameter,
+ basicString NULL, -- alphanumeric
+ iA5String NULL, -- alphanumeric
+ generalString NULL, -- alphanumeric
+ dtmf NULL, -- supports dtmf using signal and signalUpdate
+ hookflash NULL, -- supports hookflash using signal
+ ...
+}
+
+-- ===================================================================================
+-- Capability Exchange Definitions: Conference
+-- ===================================================================================
+
+ConferenceCapability ::=SEQUENCE
+{
+ nonStandardData SEQUENCE OF NonStandardParameter OPTIONAL,
+ chairControlCapability BOOLEAN,
+ ...
+}
+ -- ===================================================================================
+-- Logical channel signalling definitions
+-- ===================================================================================
+
+-- "Forward" is used to refer to transmission in the direction from the terminal making the
+-- original request for a logical channel to the other terminal, and "reverse" is used to refer
+-- to the opposite direction of transmission, in the case of a bi-directional channel request.
+
+OpenLogicalChannel ::=SEQUENCE
+{
+ forwardLogicalChannelNumber LogicalChannelNumber,
+
+ forwardLogicalChannelParameters SEQUENCE
+ {
+ portNumber INTEGER (0..65535) OPTIONAL,
+ dataType DataType,
+ multiplexParameters CHOICE
+ {
+ h222LogicalChannelParameters H222LogicalChannelParameters,
+ h223LogicalChannelParameters H223LogicalChannelParameters,
+ v76LogicalChannelParameters V76LogicalChannelParameters,
+ ...,
+ h2250LogicalChannelParameters H2250LogicalChannelParameters,
+ none NULL -- for use with Separate Stack when
+ -- multiplexParameters are not required
+ -- or appropriate
+
+ },
+ ...,
+ forwardLogicalChannelDependency LogicalChannelNumber OPTIONAL,
+ -- also used to refer to the primary logical channel when using video redundancy coding
+ replacementFor LogicalChannelNumber OPTIONAL
+
+ },
+
+ -- Used to specify the reverse channel for bi-directional open request
+
+ reverseLogicalChannelParameters SEQUENCE
+ {
+ dataType DataType,
+ multiplexParameters CHOICE
+ {
+ -- H.222 parameters are never present in reverse direction
+ h223LogicalChannelParameters H223LogicalChannelParameters,
+ v76LogicalChannelParameters V76LogicalChannelParameters,
+ ...,
+ h2250LogicalChannelParameters H2250LogicalChannelParameters
+
+ } OPTIONAL, -- Not present for H.222
+ ...,
+ reverseLogicalChannelDependency LogicalChannelNumber OPTIONAL,
+ -- also used to refer to the primary logical channel when using video redundancy coding
+ replacementFor LogicalChannelNumber OPTIONAL
+
+ } OPTIONAL, -- Not present for uni-directional channel request
+ ...,
+ separateStack NetworkAccessParameters OPTIONAL,
+ -- for Open responder to establish the stack
+ encryptionSync EncryptionSync OPTIONAL -- used only by Master
+
+
+}
+
+LogicalChannelNumber ::=INTEGER (1..65535)
+
+NetworkAccessParameters ::=SEQUENCE
+{
+ distribution CHOICE
+ {
+ unicast NULL,
+ multicast NULL, -- For Further Study in T.120
+ ...
+ } OPTIONAL,
+
+ networkAddress CHOICE
+ {
+ q2931Address Q2931Address,
+ e164Address IA5String(SIZE(1..128)) (FROM ("0123456789#*,")),
+ localAreaAddress TransportAddress,
+ ...
+ },
+ associateConference BOOLEAN,
+ externalReference OCTET STRING(SIZE(1..255)) OPTIONAL,
+ ...,
+ t120SetupProcedure CHOICE
+ {
+
+ originateCall NULL,
+ waitForCall NULL,
+ issueQuery NULL,
+ ...
+ } OPTIONAL
+}
+
+Q2931Address ::=SEQUENCE
+{
+ address CHOICE
+ {
+ internationalNumber NumericString(SIZE(1..16)),
+ nsapAddress OCTET STRING (SIZE(1..20)),
+ ...
+ },
+ subaddress OCTET STRING (SIZE(1..20)) OPTIONAL,
+ ...
+}
+
+V75Parameters ::= SEQUENCE
+{
+ audioHeaderPresent BOOLEAN,
+ ...
+}
+
+
+DataType ::=CHOICE
+{
+ nonStandard NonStandardParameter,
+ nullData NULL,
+ videoData VideoCapability,
+ audioData AudioCapability,
+ data DataApplicationCapability,
+ encryptionData EncryptionMode,
+ ...,
+ h235Control NonStandardParameter,
+ h235Media H235Media
+}
+
+H235Media ::=SEQUENCE
+{
+ encryptionAuthenticationAndIntegrity EncryptionAuthenticationAndIntegrity,
+
+ mediaType CHOICE
+ {
+ nonStandard NonStandardParameter,
+ videoData VideoCapability,
+ audioData AudioCapability,
+ data DataApplicationCapability,
+ ...
+ },
+
+ ...
+}
+
+H222LogicalChannelParameters ::=SEQUENCE
+{
+ resourceID INTEGER (0..65535),
+ subChannelID INTEGER (0..8191),
+ pcr-pid INTEGER (0..8191) OPTIONAL,
+ programDescriptors OCTET STRING OPTIONAL,
+ streamDescriptors OCTET STRING OPTIONAL,
+ ...
+}
+
+H223LogicalChannelParameters ::=SEQUENCE
+{
+ adaptationLayerType CHOICE
+ {
+ nonStandard NonStandardParameter,
+ al1Framed NULL,
+ al1NotFramed NULL,
+ al2WithoutSequenceNumbers NULL,
+ al2WithSequenceNumbers NULL,
+ al3 SEQUENCE
+ {
+ controlFieldOctets INTEGER (0..2),
+ sendBufferSize INTEGER (0..16777215) -- units octets
+ },
+ ...,
+ al1M H223AL1MParameters,
+ al2M H223AL2MParameters,
+ al3M H223AL3MParameters
+ },
+
+ segmentableFlag BOOLEAN,
+ ...
+}
+
+H223AL1MParameters ::=SEQUENCE
+{
+ transferMode CHOICE
+ {
+ framed NULL,
+ unframed NULL,
+ ...
+ },
+ headerFEC CHOICE
+ {
+ sebch16-7 NULL,
+ golay24-12 NULL,
+ ...
+ },
+ crcLength CHOICE
+ {
+ crc4bit NULL,
+ crc12bit NULL,
+ crc20bit NULL,
+ crc28bit NULL,
+ ...
+ },
+
+ rcpcCodeRate INTEGER (8..32),
+
+ arqType CHOICE
+ {
+ noArq NULL,
+ typeIArq H223AnnexCArqParameters,
+ typeIIArq H223AnnexCArqParameters,
+ ...
+ },
+ alpduInterleaving BOOLEAN,
+ alsduSplitting BOOLEAN,
+ ...
+}
+
+H223AL2MParameters ::=SEQUENCE
+{
+ headerFEC CHOICE
+ {
+ sebch16-5 NULL,
+ golay24-12 NULL,
+ ...
+ },
+ alpduInterleaving BOOLEAN,
+ ...
+}
+
+H223AL3MParameters ::=SEQUENCE
+{
+ headerFormat CHOICE
+ {
+ sebch16-7 NULL,
+ golay24-12 NULL,
+ ...
+ },
+ crcLength CHOICE
+ {
+ crc4bit NULL,
+ crc12bit NULL,
+ crc20bit NULL,
+ crc28bit NULL,
+ ...
+ },
+
+ rcpcCodeRate INTEGER (8..32),
+
+ arqType CHOICE
+ {
+ noArq NULL,
+ typeIArq H223AnnexCArqParameters,
+ typeIIArq H223AnnexCArqParameters,
+ ...
+ },
+
+ alpduInterleaving BOOLEAN,
+ ...
+}
+
+
+H223AnnexCArqParameters ::=SEQUENCE
+{
+ numberOfRetransmissions CHOICE
+ {
+ finite INTEGER (0..16),
+ infinite NULL,
+ ...
+ },
+ sendBufferSize INTEGER (0..16777215), -- units octets
+ ...
+}
+
+V76LogicalChannelParameters ::=SEQUENCE
+{
+ hdlcParameters V76HDLCParameters,
+ suspendResume CHOICE
+ {
+ noSuspendResume NULL,
+ suspendResumewAddress NULL,
+ suspendResumewoAddress NULL,
+ ...
+ },
+ uIH BOOLEAN,
+ mode CHOICE
+ {
+ eRM SEQUENCE
+ {
+ windowSize INTEGER (1..127) ,
+ recovery CHOICE
+ {
+ rej NULL,
+ sREJ NULL,
+ mSREJ NULL,
+ ...
+ },
+ ...
+ },
+ uNERM NULL,
+ ...
+ },
+ v75Parameters V75Parameters,
+ ...
+}
+
+
+
+V76HDLCParameters ::=SEQUENCE
+{
+ crcLength CRCLength,
+ n401 INTEGER (1..4095),
+ loopbackTestProcedure BOOLEAN,
+ ...
+}
+
+
+CRCLength ::=CHOICE
+{
+ crc8bit NULL,
+ crc16bit NULL,
+ crc32bit NULL,
+ ...
+}
+
+H2250LogicalChannelParameters ::=SEQUENCE
+{
+ nonStandard SEQUENCE OF NonStandardParameter OPTIONAL,
+ sessionID INTEGER(0..255),
+ associatedSessionID INTEGER(1..255) OPTIONAL,
+ mediaChannel TransportAddress OPTIONAL,
+ mediaGuaranteedDelivery BOOLEAN OPTIONAL,
+ mediaControlChannel TransportAddress OPTIONAL, -- reverse RTCP channel
+ mediaControlGuaranteedDelivery BOOLEAN OPTIONAL,
+ silenceSuppression BOOLEAN OPTIONAL,
+ destination TerminalLabel OPTIONAL,
+
+ dynamicRTPPayloadType INTEGER(96..127) OPTIONAL,
+ mediaPacketization CHOICE
+ {
+ h261aVideoPacketization NULL,
+ ...,
+ rtpPayloadType RTPPayloadType
+ } OPTIONAL,
+ ...,
+ transportCapability TransportCapability OPTIONAL,
+ redundancyEncoding RedundancyEncoding OPTIONAL,
+ source TerminalLabel OPTIONAL
+}
+
+RTPPayloadType ::= SEQUENCE
+{
+ payloadDescriptor CHOICE
+ {
+ nonStandardIdentifier NonStandardParameter,
+ rfc-number INTEGER (1..32768, ...),
+ oid OBJECT IDENTIFIER,
+ ...
+ },
+ payloadType INTEGER (0..127) OPTIONAL,
+ ...
+}
+
+RedundancyEncoding ::=SEQUENCE
+{
+ redundancyEncodingMethod RedundancyEncodingMethod,
+ secondaryEncoding DataType OPTIONAL, -- depends on method
+ ...
+}
+
+TransportAddress ::=CHOICE
+{
+ unicastAddress UnicastAddress,
+ multicastAddress MulticastAddress,
+ ...
+}
+
+UnicastAddress ::=CHOICE
+{
+ iPAddress SEQUENCE
+ {
+ network OCTET STRING (SIZE(4)),
+ tsapIdentifier INTEGER(0..65535),
+ ...
+ },
+ iPXAddress SEQUENCE
+ {
+ node OCTET STRING (SIZE(6)),
+ netnum OCTET STRING (SIZE(4)),
+ tsapIdentifier OCTET STRING (SIZE(2)),
+ ...
+ },
+ iP6Address SEQUENCE
+ {
+ network OCTET STRING (SIZE(16)),
+ tsapIdentifier INTEGER(0..65535),
+ ...
+ },
+ netBios OCTET STRING (SIZE(16)),
+ iPSourceRouteAddress SEQUENCE
+ {
+ routing CHOICE
+ {
+ strict NULL,
+ loose NULL
+ },
+ network OCTET STRING (SIZE(4)),
+ tsapIdentifier INTEGER(0..65535),
+ route SEQUENCE OF OCTET STRING (SIZE(4)),
+ ...
+ },
+ ...,
+ nsap OCTET STRING (SIZE(1..20)),
+ nonStandardAddress NonStandardParameter
+}
+
+MulticastAddress ::=CHOICE
+{
+ iPAddress SEQUENCE
+ {
+ network OCTET STRING (SIZE(4)),
+ tsapIdentifier INTEGER(0..65535),
+ ...
+ },
+ iP6Address SEQUENCE
+ {
+ network OCTET STRING (SIZE(16)),
+ tsapIdentifier INTEGER(0..65535),
+ ...
+ },
+ ...,
+ nsap OCTET STRING (SIZE(1..20)),
+ nonStandardAddress NonStandardParameter
+}
+
+EncryptionSync ::=SEQUENCE
+ -- used to supply new key and synchronization point
+{
+ nonStandard NonStandardParameter OPTIONAL,
+ synchFlag INTEGER(0..255) , -- may need to be larger for H.324, etc
+ -- shall be the Dynamic Payload# for H.323
+ h235Key OCTET STRING (SIZE(1..65535)), -- H.235 encoded value
+ escrowentry SEQUENCE SIZE(1..256) OF EscrowData OPTIONAL,
+ ...
+}
+
+EscrowData ::=SEQUENCE
+{
+ escrowID OBJECT IDENTIFIER,
+ escrowValue BIT STRING (SIZE(1..65535)),
+ ...
+}
+
+OpenLogicalChannelAck ::=SEQUENCE
+{
+ forwardLogicalChannelNumber LogicalChannelNumber,
+
+ reverseLogicalChannelParameters SEQUENCE
+ {
+ reverseLogicalChannelNumber LogicalChannelNumber,
+ portNumber INTEGER (0..65535) OPTIONAL,
+ multiplexParameters CHOICE
+ {
+ h222LogicalChannelParameters H222LogicalChannelParameters,
+ -- H.223 parameters are never present in reverse direction
+ ...,
+ h2250LogicalChannelParameters H2250LogicalChannelParameters
+
+ } OPTIONAL, -- Not present for H.223
+ ...,
+ replacementFor LogicalChannelNumber OPTIONAL
+
+ } OPTIONAL, -- Not present for uni-directional channel request
+ ...,
+ separateStack NetworkAccessParameters OPTIONAL,
+ -- for Open requester to establish the stack
+ forwardMultiplexAckParameters CHOICE
+ {
+ -- H.222 parameters are never present in the Ack
+ -- H.223 parameters are never present in the Ack
+ --V.76 parameters are never present in the Ack
+ h2250LogicalChannelAckParameters H2250LogicalChannelAckParameters,
+ ...
+ } OPTIONAL,
+ encryptionSync EncryptionSync OPTIONAL -- used only by Master
+}
+
+OpenLogicalChannelReject ::=SEQUENCE
+{
+ forwardLogicalChannelNumber LogicalChannelNumber,
+ cause CHOICE
+ {
+ unspecified NULL,
+ unsuitableReverseParameters NULL,
+ dataTypeNotSupported NULL,
+ dataTypeNotAvailable NULL,
+ unknownDataType NULL,
+ dataTypeALCombinationNotSupported NULL,
+ ...,
+ multicastChannelNotAllowed NULL,
+ insufficientBandwidth NULL,
+ separateStackEstablishmentFailed NULL,
+ invalidSessionID NULL,
+ masterSlaveConflict NULL,
+ waitForCommunicationMode NULL,
+ invalidDependentChannel NULL,
+ replacementForRejected NULL
+ },
+ ...
+}
+
+OpenLogicalChannelConfirm ::=SEQUENCE
+{
+ forwardLogicalChannelNumber LogicalChannelNumber,
+ ...
+}
+
+H2250LogicalChannelAckParameters ::=SEQUENCE
+{
+ nonStandard SEQUENCE OF NonStandardParameter OPTIONAL,
+ sessionID INTEGER(1..255) OPTIONAL,
+ mediaChannel TransportAddress OPTIONAL,
+ mediaControlChannel TransportAddress OPTIONAL, -- forward RTCP channel
+ dynamicRTPPayloadType INTEGER(96..127) OPTIONAL, -- used only by the master or MC
+ ...,
+ flowControlToZero BOOLEAN
+}
+
+
+
+CloseLogicalChannel ::=SEQUENCE
+{
+ forwardLogicalChannelNumber LogicalChannelNumber,
+ source CHOICE
+ {
+ user NULL,
+ lcse NULL
+ },
+ ...,
+ reason CHOICE
+ {
+ unknown NULL,
+ reopen NULL,
+ reservationFailure NULL,
+ ...
+ }
+}
+
+CloseLogicalChannelAck ::=SEQUENCE
+{
+ forwardLogicalChannelNumber LogicalChannelNumber,
+ ...
+}
+
+RequestChannelClose ::=SEQUENCE
+{
+ forwardLogicalChannelNumber LogicalChannelNumber,
+ ...,
+ qosCapability QOSCapability OPTIONAL,
+ reason CHOICE
+ {
+ unknown NULL,
+ normal NULL,
+ reopen NULL,
+ reservationFailure NULL,
+ ...
+ }
+}
+
+RequestChannelCloseAck ::=SEQUENCE
+{
+ forwardLogicalChannelNumber LogicalChannelNumber,
+ ...
+}
+
+RequestChannelCloseReject ::=SEQUENCE
+{
+ forwardLogicalChannelNumber LogicalChannelNumber,
+ cause CHOICE
+ {
+ unspecified NULL,
+ ...
+ },
+ ...
+}
+
+RequestChannelCloseRelease ::=SEQUENCE
+{
+ forwardLogicalChannelNumber LogicalChannelNumber,
+ ...
+}
+
+ -- ===================================================================================
+-- H.223 multiplex table definitions
+-- ===================================================================================
+
+MultiplexEntrySend ::=SEQUENCE
+{
+ sequenceNumber SequenceNumber,
+ multiplexEntryDescriptors SET SIZE (1..15) OF MultiplexEntryDescriptor,
+ ...
+}
+
+MultiplexEntryDescriptor ::=SEQUENCE
+{
+ multiplexTableEntryNumber MultiplexTableEntryNumber,
+ elementList SEQUENCE SIZE (1..256) OF MultiplexElement OPTIONAL
+}
+
+MultiplexElement ::=SEQUENCE
+{
+ type CHOICE
+ {
+ logicalChannelNumber INTEGER(0..65535),
+ subElementList SEQUENCE SIZE (2..255) OF MultiplexElement
+ },
+ repeatCount CHOICE
+ {
+ finite INTEGER (1..65535), -- repeats of type
+ untilClosingFlag NULL -- used for last element
+ }
+}
+
+MultiplexTableEntryNumber ::=INTEGER (1..15)
+
+MultiplexEntrySendAck ::=SEQUENCE
+{
+ sequenceNumber SequenceNumber,
+ multiplexTableEntryNumber SET SIZE (1..15) OF MultiplexTableEntryNumber,
+ ...
+}
+
+MultiplexEntrySendReject ::=SEQUENCE
+{
+ sequenceNumber SequenceNumber,
+ rejectionDescriptions SET SIZE (1..15) OF MultiplexEntryRejectionDescriptions,
+ ...
+}
+
+MultiplexEntryRejectionDescriptions ::=SEQUENCE
+{
+ multiplexTableEntryNumber MultiplexTableEntryNumber,
+ cause CHOICE
+ {
+ unspecifiedCause NULL,
+ descriptorTooComplex NULL,
+ ...
+ },
+ ...
+}
+
+MultiplexEntrySendRelease ::=SEQUENCE
+{
+ multiplexTableEntryNumber SET SIZE (1..15) OF MultiplexTableEntryNumber,
+ ...
+}
+
+RequestMultiplexEntry ::=SEQUENCE
+{
+ entryNumbers SET SIZE (1..15) OF MultiplexTableEntryNumber,
+ ...
+}
+
+RequestMultiplexEntryAck ::=SEQUENCE
+{
+ entryNumbers SET SIZE (1..15) OF MultiplexTableEntryNumber,
+ ...
+}
+
+RequestMultiplexEntryReject ::=SEQUENCE
+{
+ entryNumbers SET SIZE (1..15) OF MultiplexTableEntryNumber,
+ rejectionDescriptions SET SIZE (1..15) OF RequestMultiplexEntryRejectionDescriptions,
+ ...
+}
+
+RequestMultiplexEntryRejectionDescriptions ::=SEQUENCE
+{
+ multiplexTableEntryNumber MultiplexTableEntryNumber,
+ cause CHOICE
+ {
+ unspecifiedCause NULL,
+ ...
+ },
+ ...
+}
+
+RequestMultiplexEntryRelease ::=SEQUENCE
+{
+ entryNumbers SET SIZE (1..15) OF MultiplexTableEntryNumber,
+ ...
+}
+
+ -- ===================================================================================
+-- Request mode definitions
+-- ===================================================================================
+
+-- RequestMode is a list, in order or preference, of modes that a terminal would like
+-- to have transmitted to it.
+
+RequestMode ::=SEQUENCE
+{
+ sequenceNumber SequenceNumber,
+ requestedModes SEQUENCE SIZE (1..256) OF ModeDescription,
+ ...
+}
+
+RequestModeAck ::=SEQUENCE
+{
+ sequenceNumber SequenceNumber,
+ response CHOICE
+ {
+ willTransmitMostPreferredMode NULL,
+ willTransmitLessPreferredMode NULL,
+ ...
+ },
+ ...
+}
+
+RequestModeReject ::=SEQUENCE
+{
+ sequenceNumber SequenceNumber,
+ cause CHOICE
+ {
+ modeUnavailable NULL,
+ multipointConstraint NULL,
+ requestDenied NULL,
+ ...
+ },
+ ...
+}
+
+RequestModeRelease ::=SEQUENCE
+{
+ ...
+}
+
+-- ===================================================================================
+-- Request mode definitions: Mode description
+-- ===================================================================================
+
+ModeDescription ::=SET SIZE (1..256) OF ModeElement
+
+ModeElement ::= SEQUENCE
+{
+ type CHOICE
+ {
+ nonStandard NonStandardParameter,
+ videoMode VideoMode,
+ audioMode AudioMode,
+ dataMode DataMode,
+ encryptionMode EncryptionMode,
+ ...,
+ h235Mode H235Mode
+ },
+
+ h223ModeParameters H223ModeParameters OPTIONAL,
+ ...,
+ v76ModeParameters V76ModeParameters OPTIONAL,
+ h2250ModeParameters H2250ModeParameters OPTIONAL
+
+
+}
+
+H235Mode ::=SEQUENCE
+{
+ encryptionAuthenticationAndIntegrity EncryptionAuthenticationAndIntegrity,
+
+ mediaMode CHOICE
+ {
+ nonStandard NonStandardParameter,
+ videoMode VideoMode,
+ audioMode AudioMode,
+ dataMode DataMode,
+ ...
+ },
+ ...
+}
+
+H223ModeParameters ::=SEQUENCE
+{
+ adaptationLayerType CHOICE
+ {
+ nonStandard NonStandardParameter,
+ al1Framed NULL,
+ al1NotFramed NULL,
+ al2WithoutSequenceNumbers NULL,
+ al2WithSequenceNumbers NULL,
+ al3 SEQUENCE
+ {
+ controlFieldOctets INTEGER(0..2),
+ sendBufferSize INTEGER(0..16777215) -- units octets
+ },
+ ...,
+ al1M H223AL1MParameters,
+ al2M H223AL2MParameters,
+ al3M H223AL3MParameters
+
+ },
+
+ segmentableFlag BOOLEAN,
+ ...
+}
+
+V76ModeParameters ::=CHOICE
+{
+ suspendResumewAddress NULL,
+ suspendResumewoAddress NULL,
+ ...
+}
+
+H2250ModeParameters ::=SEQUENCE
+{
+ redundancyEncodingMode RedundancyEncodingMode OPTIONAL,
+ ...
+}
+
+RedundancyEncodingMode ::=SEQUENCE
+{
+ redundancyEncodingMethod RedundancyEncodingMethod,
+ secondaryEncoding CHOICE
+ {
+ nonStandard NonStandardParameter,
+ audioData AudioMode,
+ ...
+ } OPTIONAL,
+ ...
+}
+
+-- ===================================================================================
+-- Request mode definitions: Video modes
+-- ===================================================================================
+
+VideoMode ::=CHOICE
+{
+ nonStandard NonStandardParameter,
+ h261VideoMode H261VideoMode,
+ h262VideoMode H262VideoMode,
+ h263VideoMode H263VideoMode,
+ is11172VideoMode IS11172VideoMode,
+ ...
+}
+
+H261VideoMode ::=SEQUENCE
+{
+ resolution CHOICE
+ {
+ qcif NULL,
+ cif NULL
+ },
+ bitRate INTEGER (1..19200), -- units 100 bit/s
+ stillImageTransmission BOOLEAN,
+ ...
+}
+
+H262VideoMode ::=SEQUENCE
+{
+ profileAndLevel CHOICE
+ {
+ profileAndLevel-SPatML NULL,
+ profileAndLevel-MPatLL NULL,
+ profileAndLevel-MPatML NULL,
+ profileAndLevel-MPatH-14 NULL,
+ profileAndLevel-MPatHL NULL,
+ profileAndLevel-SNRatLL NULL,
+ profileAndLevel-SNRatML NULL,
+ profileAndLevel-SpatialatH-14 NULL,
+ profileAndLevel-HPatML NULL,
+ profileAndLevel-HPatH-14 NULL,
+ profileAndLevel-HPatHL NULL,
+ ...
+ },
+ videoBitRate INTEGER(0..1073741823) OPTIONAL, -- units 400bit/s
+ vbvBufferSize INTEGER(0..262143) OPTIONAL, -- units 16384bits
+ samplesPerLine INTEGER(0..16383) OPTIONAL, -- units samples/line
+ linesPerFrame INTEGER(0..16383) OPTIONAL, -- units lines/frame
+ framesPerSecond INTEGER(0..15) OPTIONAL, -- frame_rate_code
+ luminanceSampleRate INTEGER(0..4294967295) OPTIONAL, -- units samples/sec
+ ...
+}
+
+H263VideoMode ::=SEQUENCE
+{
+ resolution CHOICE
+ {
+ sqcif NULL,
+ qcif NULL,
+ cif NULL,
+ cif4 NULL,
+ cif16 NULL,
+ ...
+ },
+ bitRate INTEGER (1..19200), -- units 100 bit/s
+ unrestrictedVector BOOLEAN,
+ arithmeticCoding BOOLEAN,
+ advancedPrediction BOOLEAN,
+ pbFrames BOOLEAN,
+ ...,
+
+ errorCompensation BOOLEAN,
+ enhancementLayerInfo EnhancementLayerInfo OPTIONAL,
+ h263Options H263Options OPTIONAL
+}
+
+IS11172VideoMode ::=SEQUENCE
+{
+ constrainedBitstream BOOLEAN,
+ videoBitRate INTEGER(0..1073741823) OPTIONAL, -- units 400bit/s
+ vbvBufferSize INTEGER(0..262143) OPTIONAL, -- units 16384bits
+ samplesPerLine INTEGER(0..16383) OPTIONAL, -- units samples/line
+ linesPerFrame INTEGER(0..16383) OPTIONAL, -- units lines/frame
+ pictureRate INTEGER(0..15) OPTIONAL,
+ luminanceSampleRate INTEGER(0..4294967295) OPTIONAL, -- units samples/sec
+ ...
+}
+
+-- ===================================================================================
+-- Request mode definitions: Audio modes
+-- ===================================================================================
+
+AudioMode ::=CHOICE
+{
+ nonStandard NonStandardParameter,
+ g711Alaw64k NULL,
+ g711Alaw56k NULL,
+ g711Ulaw64k NULL,
+ g711Ulaw56k NULL,
+
+ g722-64k NULL,
+ g722-56k NULL,
+ g722-48k NULL,
+
+ g728 NULL,
+ g729 NULL,
+ g729AnnexA NULL,
+
+ g7231 CHOICE
+ {
+ noSilenceSuppressionLowRate NULL,
+ noSilenceSuppressionHighRate NULL,
+ silenceSuppressionLowRate NULL,
+ silenceSuppressionHighRate NULL
+ },
+
+ is11172AudioMode IS11172AudioMode,
+ is13818AudioMode IS13818AudioMode,
+
+ ...,
+ g729wAnnexB INTEGER(1..256),
+ g729AnnexAwAnnexB INTEGER(1..256),
+ g7231AnnexCMode G7231AnnexCMode,
+ gsmFullRate GSMAudioCapability,
+ gsmHalfRate GSMAudioCapability,
+ gsmEnhancedFullRate GSMAudioCapability
+
+}
+
+IS11172AudioMode ::=SEQUENCE
+{
+ audioLayer CHOICE
+ {
+ audioLayer1 NULL,
+ audioLayer2 NULL,
+ audioLayer3 NULL
+ },
+
+ audioSampling CHOICE
+ {
+ audioSampling32k NULL,
+ audioSampling44k1 NULL,
+ audioSampling48k NULL
+ },
+
+ multichannelType CHOICE
+ {
+ singleChannel NULL,
+ twoChannelStereo NULL,
+ twoChannelDual NULL
+ },
+
+ bitRate INTEGER (1..448), --units kbit/s
+ ...
+}
+
+IS13818AudioMode ::=SEQUENCE
+{
+ audioLayer CHOICE
+ {
+ audioLayer1 NULL,
+ audioLayer2 NULL,
+ audioLayer3 NULL
+ },
+
+ audioSampling CHOICE
+ {
+ audioSampling16k NULL,
+ audioSampling22k05 NULL,
+ audioSampling24k NULL,
+ audioSampling32k NULL,
+ audioSampling44k1 NULL,
+ audioSampling48k NULL
+ },
+
+ multichannelType CHOICE
+ {
+ singleChannel NULL,
+ twoChannelStereo NULL,
+ twoChannelDual NULL,
+ threeChannels2-1 NULL,
+ threeChannels3-0 NULL,
+ fourChannels2-0-2-0 NULL,
+ fourChannels2-2 NULL,
+ fourChannels3-1 NULL,
+ fiveChannels3-0-2-0 NULL,
+ fiveChannels3-2 NULL
+ },
+
+ lowFrequencyEnhancement BOOLEAN,
+
+ multilingual BOOLEAN,
+
+ bitRate INTEGER (1..1130), --units kbit/s
+ ...
+}
+
+G7231AnnexCMode ::= SEQUENCE
+{
+ maxAl-sduAudioFrames INTEGER (1..256),
+ silenceSuppression BOOLEAN,
+ g723AnnexCAudioMode SEQUENCE
+ {
+ highRateMode0 INTEGER (27..78), -- units octets
+ highRateMode1 INTEGER (27..78), -- units octets
+ lowRateMode0 INTEGER (23..66), -- units octets
+ lowRateMode1 INTEGER (23..66), -- units octets
+ sidMode0 INTEGER (6..17), -- units octets
+ sidMode1 INTEGER (6..17), -- units octets
+ ...
+ },
+ ...
+}
+
+-- ===================================================================================
+-- Request mode definitions: Data modes
+-- ===================================================================================
+
+DataMode ::=SEQUENCE
+{
+ application CHOICE
+ {
+ nonStandard NonStandardParameter,
+ t120 DataProtocolCapability,
+ dsm-cc DataProtocolCapability,
+ userData DataProtocolCapability,
+ t84 DataProtocolCapability,
+ t434 DataProtocolCapability,
+ h224 DataProtocolCapability,
+ nlpid SEQUENCE
+ {
+ nlpidProtocol DataProtocolCapability,
+ nlpidData OCTET STRING
+ },
+ dsvdControl NULL,
+ h222DataPartitioning DataProtocolCapability,
+ ...,
+ t30fax DataProtocolCapability,
+ t140 DataProtocolCapability
+ },
+ bitRate INTEGER (0..4294967295), -- units 100 bit/s
+ ...
+}
+
+-- ===================================================================================
+-- Request mode definitions: Encryption modes
+-- ===================================================================================
+
+EncryptionMode ::=CHOICE
+{
+ nonStandard NonStandardParameter,
+ h233Encryption NULL,
+ ...
+}
+
+ -- ===================================================================================
+-- Round Trip Delay definitions
+-- ===================================================================================
+
+RoundTripDelayRequest ::=SEQUENCE
+{
+ sequenceNumber SequenceNumber,
+ ...
+}
+
+RoundTripDelayResponse ::=SEQUENCE
+{
+ sequenceNumber SequenceNumber,
+ ...
+}
+
+-- ===================================================================================
+-- Maintenance Loop definitions
+-- ===================================================================================
+
+MaintenanceLoopRequest ::=SEQUENCE
+{
+ type CHOICE
+ {
+ systemLoop NULL,
+ mediaLoop LogicalChannelNumber,
+ logicalChannelLoop LogicalChannelNumber,
+ ...
+ },
+ ...
+}
+
+MaintenanceLoopAck ::=SEQUENCE
+{
+ type CHOICE
+ {
+ systemLoop NULL,
+ mediaLoop LogicalChannelNumber,
+ logicalChannelLoop LogicalChannelNumber,
+ ...
+ },
+ ...
+}
+
+MaintenanceLoopReject ::=SEQUENCE
+{
+ type CHOICE
+ {
+ systemLoop NULL,
+ mediaLoop LogicalChannelNumber,
+ logicalChannelLoop LogicalChannelNumber,
+ ...
+ },
+ cause CHOICE
+ {
+ canNotPerformLoop NULL,
+ ...
+ },
+ ...
+}
+
+MaintenanceLoopOffCommand ::=SEQUENCE
+{
+ ...
+}
+
+-- ===================================================================================
+-- Communication Mode definitions
+-- ===================================================================================
+
+CommunicationModeCommand ::=SEQUENCE
+{
+ communicationModeTable SET SIZE(1..256) OF CommunicationModeTableEntry,
+ ...
+}
+
+CommunicationModeRequest ::=SEQUENCE
+{
+ ...
+}
+
+CommunicationModeResponse ::=CHOICE
+{
+ communicationModeTable SET SIZE(1..256) OF CommunicationModeTableEntry,
+ ...
+}
+
+CommunicationModeTableEntry ::=SEQUENCE
+{
+ nonStandard SEQUENCE OF NonStandardParameter OPTIONAL,
+ sessionID INTEGER(1..255),
+ associatedSessionID INTEGER(1..255) OPTIONAL,
+
+ terminalLabel TerminalLabel OPTIONAL, -- if not present,
+ -- it refers to all participants
+ -- in the conference
+ sessionDescription BMPString (SIZE(1..128)) ,
+ -- Basic ISO/IEC 10646-1 (Unicode)
+ dataType CHOICE
+ {
+ videoData VideoCapability,
+ audioData AudioCapability,
+ data DataApplicationCapability,
+ ...
+ },
+ mediaChannel TransportAddress OPTIONAL,
+ mediaGuaranteedDelivery BOOLEAN OPTIONAL,
+ mediaControlChannel TransportAddress OPTIONAL, -- reverse RTCP channel
+ mediaControlGuaranteedDelivery BOOLEAN OPTIONAL,
+ ...,
+ redundancyEncoding RedundancyEncoding OPTIONAL,
+ sessionDependency INTEGER (1..255) OPTIONAL,
+ destination TerminalLabel OPTIONAL
+}
+
+-- ===================================================================================
+-- Conference Request definitions
+-- ===================================================================================
+
+ConferenceRequest ::=CHOICE
+{
+
+ terminalListRequest NULL, -- same as H.230 TCU (term->MC)
+
+ makeMeChair NULL, -- same as H.230 CCA (term->MC)
+ cancelMakeMeChair NULL, -- same as H.230 CIS (term->MC)
+
+ dropTerminal TerminalLabel, -- same as H.230 CCD(term->MC)
+
+ requestTerminalID TerminalLabel, -- sames as TCP (term->MC)
+
+ enterH243Password NULL, -- same as H.230 TCS1(MC->term)
+ enterH243TerminalID NULL, -- same as H.230 TCS2/TCI
+ -- (MC->term)
+ enterH243ConferenceID NULL, -- same as H.230 TCS3 (MC->term)
+ ...,
+ enterExtensionAddress NULL, -- same as H.230 TCS4 (GW->term)
+ requestChairTokenOwner NULL, -- same as H.230 TCA (term->MC)
+ requestTerminalCertificate SEQUENCE
+ {
+ terminalLabel TerminalLabel OPTIONAL,
+ certSelectionCriteria CertSelectionCriteria OPTIONAL,
+ sRandom INTEGER (1..4294967295) OPTIONAL,
+ -- this is the requester's challenge
+ ...
+ },
+ broadcastMyLogicalChannel LogicalChannelNumber, -- similar to H.230 MCV
+ makeTerminalBroadcaster TerminalLabel, -- similar to H.230 VCB
+ sendThisSource TerminalLabel, -- similar to H.230 VCS
+ requestAllTerminalIDs NULL,
+ remoteMCRequest RemoteMCRequest
+}
+
+CertSelectionCriteria ::=SEQUENCE SIZE (1..16) OF Criteria
+
+Criteria ::=SEQUENCE
+{
+ field OBJECT IDENTIFIER, -- may include certificate type
+ value OCTET STRING (SIZE(1..65535)),
+ ...
+}
+
+TerminalLabel ::=SEQUENCE
+{
+ mcuNumber McuNumber,
+ terminalNumber TerminalNumber,
+ ...
+}
+
+McuNumber ::=INTEGER(0..192)
+TerminalNumber ::=INTEGER(0..192)
+
+-- ===================================================================================
+-- Conference Response definitions
+-- ===================================================================================
+
+ConferenceResponse ::=CHOICE
+{
+ mCTerminalIDResponse SEQUENCE -- response to TCP(same as TIP)
+ { -- sent by MC only
+ terminalLabel TerminalLabel,
+ terminalID TerminalID,
+ ...
+ },
+
+ terminalIDResponse SEQUENCE -- response to TCS2 or TCI
+ { -- same as IIS
+ terminalLabel TerminalLabel, -- (term->MC)
+ terminalID TerminalID,
+ ...
+ },
+
+ conferenceIDResponse SEQUENCE -- response to TCS3
+ { -- same as IIS
+ terminalLabel TerminalLabel, -- (term->MC)
+ conferenceID ConferenceID,
+ ...
+ },
+
+ passwordResponse SEQUENCE -- response to TCS1
+ { -- same as IIS
+ terminalLabel TerminalLabel, -- (term->MC)
+ password Password,
+ ...
+ },
+
+ terminalListResponse SET SIZE (1..256) OF TerminalLabel,
+
+ videoCommandReject NULL, -- same as H.230 VCR
+ terminalDropReject NULL, -- same as H.230 CIR
+
+ makeMeChairResponse CHOICE -- same as H.230 CCR
+ {
+ grantedChairToken NULL, -- same as H.230 CIT
+ deniedChairToken NULL, -- same as H.230 CCR
+ ...
+ },
+ ...,
+ extensionAddressResponse SEQUENCE -- response to TCS4
+ {
+ extensionAddress TerminalID, -- same as IIS (term->GW)
+ ...
+ },
+ chairTokenOwnerResponse SEQUENCE -- response to TCA(same as TIR) sent by MC only
+ {
+ terminalLabel TerminalLabel,
+ terminalID TerminalID,
+ ...
+ },
+ terminalCertificateResponse SEQUENCE
+ {
+ terminalLabel TerminalLabel OPTIONAL,
+ certificateResponse OCTET STRING (SIZE(1..65535)) OPTIONAL,
+ ...
+ },
+ broadcastMyLogicalChannelResponse CHOICE
+ {
+ grantedBroadcastMyLogicalChannel NULL,
+ deniedBroadcastMyLogicalChannel NULL,
+ ...
+ },
+ makeTerminalBroadcasterResponse CHOICE
+ {
+ grantedMakeTerminalBroadcaster NULL,
+ deniedMakeTerminalBroadcaster NULL,
+ ...
+ },
+ sendThisSourceResponse CHOICE
+ {
+ grantedSendThisSource NULL,
+ deniedSendThisSource NULL,
+ ...
+ },
+ requestAllTerminalIDsResponse RequestAllTerminalIDsResponse,
+ remoteMCResponse RemoteMCResponse
+}
+
+TerminalID ::=OCTET STRING (SIZE(1..128)) -- as per H.230
+ConferenceID ::=OCTET STRING (SIZE(1..32))
+Password ::=OCTET STRING (SIZE(1..32))
+
+RequestAllTerminalIDsResponse ::=SEQUENCE
+{
+ terminalInformation SEQUENCE OF TerminalInformation,
+ ...
+}
+
+TerminalInformation ::=SEQUENCE
+{
+ terminalLabel TerminalLabel,
+ terminalID TerminalID,
+ ...
+}
+
+-- ===================================================================================
+-- Remote MC Request definitions
+-- ===================================================================================
+
+ RemoteMCRequest ::=CHOICE
+ {
+ masterActivate NULL,
+ slaveActivate NULL,
+ deActivate NULL,
+ ...
+ }
+
+ RemoteMCResponse ::=CHOICE
+ {
+ accept NULL,
+ reject CHOICE
+ {
+ unspecified NULL,
+ functionNotSupported NULL,
+ ...
+ },
+ ...
+ }
+
+-- ===================================================================================
+-- Command Message definitions
+-- ===================================================================================
+
+-- ===================================================================================
+-- Command Message : Send Terminal Capability Set
+-- ===================================================================================
+
+SendTerminalCapabilitySet ::=CHOICE
+{
+ specificRequest SEQUENCE
+ {
+ multiplexCapability BOOLEAN,
+
+ capabilityTableEntryNumbers SET SIZE (1..65535) OF CapabilityTableEntryNumber OPTIONAL,
+
+ capabilityDescriptorNumbers SET SIZE (1..256) OF CapabilityDescriptorNumber OPTIONAL,
+ ...
+ },
+ genericRequest NULL,
+ ...
+}
+
+-- ===================================================================================
+-- Command Message : Encryption
+-- ===================================================================================
+
+EncryptionCommand ::=CHOICE
+{
+ encryptionSE OCTET STRING, -- per H.233, but no error protection
+ encryptionIVRequest NULL, -- requests new IV
+ encryptionAlgorithmID SEQUENCE
+ {
+ h233AlgorithmIdentifier SequenceNumber,
+ associatedAlgorithm NonStandardParameter
+ },
+ ...
+}
+
+-- ===================================================================================
+-- Command Message : Flow Control
+-- ===================================================================================
+
+FlowControlCommand ::=SEQUENCE
+{
+ scope CHOICE
+ {
+ logicalChannelNumber LogicalChannelNumber,
+ resourceID INTEGER (0..65535),
+ wholeMultiplex NULL
+ },
+ restriction CHOICE
+ {
+ maximumBitRate INTEGER (0..16777215), -- units 100 bit/s
+ noRestriction NULL
+ },
+ ...
+}
+
+-- ===================================================================================
+-- Command Message : Change or End Session
+-- ===================================================================================
+
+EndSessionCommand ::=CHOICE
+{
+ nonStandard NonStandardParameter,
+
+ disconnect NULL,
+
+ gstnOptions CHOICE
+ {
+ telephonyMode NULL,
+ v8bis NULL,
+ v34DSVD NULL,
+ v34DuplexFAX NULL,
+ v34H324 NULL,
+ ...
+ },
+
+ ...,
+ isdnOptions CHOICE
+ {
+ telephonyMode NULL,
+ v140 NULL,
+ terminalOnHold NULL,
+ ...
+ }
+}
+
+-- ===================================================================================
+-- Command Message : Conference Commands
+-- ===================================================================================
+
+ConferenceCommand ::=CHOICE
+{
+ broadcastMyLogicalChannel LogicalChannelNumber, -- similar to H.230 MCV
+ cancelBroadcastMyLogicalChannel LogicalChannelNumber, -- similar to H.230 Cancel-MCV
+
+ makeTerminalBroadcaster TerminalLabel, -- same as H.230 VCB
+ cancelMakeTerminalBroadcaster NULL, -- same as H.230 Cancel-VCB
+
+ sendThisSource TerminalLabel, -- same as H.230 VCS
+ cancelSendThisSource NULL, -- same as H.230 cancel VCS
+
+ dropConference NULL, -- same as H.230 CCK
+ ...,
+ substituteConferenceIDCommand SubstituteConferenceIDCommand
+}
+
+SubstituteConferenceIDCommand ::=SEQUENCE
+{
+ conferenceIdentifier OCTET STRING (SIZE(16)),
+ ...
+}
+
+-- ===================================================================================
+-- Command Message : Miscellaneous H.230-like commands
+-- ===================================================================================
+
+MiscellaneousCommand ::=SEQUENCE
+{
+ logicalChannelNumber LogicalChannelNumber,
+ type CHOICE
+ {
+ equaliseDelay NULL, -- same as H.230 ACE
+ zeroDelay NULL, -- same as H.230 ACZ
+ multipointModeCommand NULL,
+ cancelMultipointModeCommand NULL,
+ videoFreezePicture NULL,
+ videoFastUpdatePicture NULL,
+
+ videoFastUpdateGOB SEQUENCE
+ {
+ firstGOB INTEGER (0..17),
+ numberOfGOBs INTEGER (1..18)
+ },
+
+ videoTemporalSpatialTradeOff INTEGER (0..31), -- commands a trade-off value
+
+ videoSendSyncEveryGOB NULL,
+ videoSendSyncEveryGOBCancel NULL,
+
+ ...,
+ videoFastUpdateMB SEQUENCE
+ {
+ firstGOB INTEGER (0..255) OPTIONAL,
+ firstMB INTEGER (1..8192) OPTIONAL,
+ numberOfMBs INTEGER (1..8192),
+ ...
+ },
+ maxH223MUXPDUsize INTEGER(1..65535), -- units octets
+ encryptionUpdate EncryptionSync,
+ encryptionUpdateRequest EncryptionUpdateRequest,
+ switchReceiveMediaOff NULL,
+ switchReceiveMediaOn NULL,
+
+ progressiveRefinementStart SEQUENCE
+ {
+ repeatCount CHOICE
+ {
+ doOneProgression NULL,
+ doContinuousProgressions NULL,
+ doOneIndependentProgression NULL,
+ doContinuousIndependentProgressions NULL,
+ ...
+ },
+ ...
+ },
+ progressiveRefinementAbortOne NULL,
+ progressiveRefinementAbortContinuous NULL
+
+ },
+
+ ...
+}
+
+KeyProtectionMethod ::=SEQUENCE -- specify how the new key is to be protected
+{
+ secureChannel BOOLEAN,
+ sharedSecret BOOLEAN,
+ certProtectedKey BOOLEAN,
+ ...
+}
+
+EncryptionUpdateRequest ::=SEQUENCE
+{
+ keyProtectionMethod KeyProtectionMethod OPTIONAL,
+ ...
+}
+
+-- ===================================================================================
+-- Command Message : H.223 Multiplex Reconfiguration
+-- ===================================================================================
+
+H223MultiplexReconfiguration ::=CHOICE
+{
+ h223ModeChange CHOICE
+ {
+ toLevel0 NULL,
+ toLevel1 NULL,
+ toLevel2 NULL,
+ toLevel2withOptionalHeader NULL,
+ ...
+ },
+
+ h223AnnexADoubleFlag CHOICE
+ {
+ start NULL,
+ stop NULL,
+ ...
+ },
+
+ ...
+}
+ -- ===================================================================================
+-- Indication Message definitions
+-- ===================================================================================
+
+-- ===================================================================================
+-- Indication Message : Function not understood
+-- ===================================================================================
+
+-- This is used to return a request, response or command that is not understood
+
+FunctionNotUnderstood ::=CHOICE
+{
+ request RequestMessage,
+ response ResponseMessage,
+ command CommandMessage
+}
+
+-- ===================================================================================
+-- Indication Message : Function not Supported
+-- ===================================================================================
+
+-- This is used to return a complete request, response or command that is not recognized
+
+FunctionNotSupported ::=SEQUENCE
+{
+ cause CHOICE
+ {
+ syntaxError NULL,
+ semanticError NULL,
+ unknownFunction NULL,
+ ...
+ },
+ returnedFunction OCTET STRING OPTIONAL,
+ ...
+}
+
+-- ===================================================================================
+-- Indication Message : Conference
+-- ===================================================================================
+
+ConferenceIndication ::=CHOICE
+{
+ sbeNumber INTEGER (0..9), -- same as H.230 SBE Number
+
+ terminalNumberAssign TerminalLabel, -- same as H.230 TIA
+
+ terminalJoinedConference TerminalLabel, -- same as H.230 TIN
+
+ terminalLeftConference TerminalLabel, -- same as H.230 TID
+
+ seenByAtLeastOneOther NULL, -- same as H.230 MIV
+ cancelSeenByAtLeastOneOther NULL, -- same as H.230 cancel MIV
+
+ seenByAll NULL, -- like H.230 MIV
+ cancelSeenByAll NULL, -- like H.230 MIV
+
+ terminalYouAreSeeing TerminalLabel, -- same as H.230 VIN
+
+ requestForFloor NULL, -- same as H.230 TIF
+
+ ...,
+ withdrawChairToken NULL, -- same as H.230 CCR
+ -- MC-> chair
+ floorRequested TerminalLabel -- same as H.230 TIF
+ -- MC-> chair
+}
+
+
+-- ===================================================================================
+-- Indication Message : Miscellaneous H.230-like indication
+-- ===================================================================================
+
+MiscellaneousIndication ::=SEQUENCE
+{
+ logicalChannelNumber LogicalChannelNumber,
+ type CHOICE
+ {
+ logicalChannelActive NULL, -- same as H.230 AIA and VIA
+ logicalChannelInactive NULL, -- same as H.230 AIM and VIS
+
+ multipointConference NULL,
+ cancelMultipointConference NULL,
+
+ multipointZeroComm NULL, -- same as H.230 MIZ
+ cancelMultipointZeroComm NULL, -- same as H.230 cancel MIZ
+
+ multipointSecondaryStatus NULL, -- same as H.230 MIS
+ cancelMultipointSecondaryStatus NULL, -- same as H.230 cancel MIS
+
+ videoIndicateReadyToActivate NULL, -- same as H.230 VIR
+
+ videoTemporalSpatialTradeOff INTEGER (0..31), -- indicates current trade-off
+
+ ...,
+ videoNotDecodedMBs SEQUENCE
+ {
+ firstMB INTEGER (1..8192),
+ numberOfMBs INTEGER (1..8192),
+ temporalReference INTEGER (0..255),
+ ...
+ },
+ transportCapability TransportCapability
+ },
+ ...
+}
+
+-- ===================================================================================
+-- Indication Message : Jitter Indication
+-- ===================================================================================
+
+JitterIndication ::=SEQUENCE
+{
+ scope CHOICE
+ {
+ logicalChannelNumber LogicalChannelNumber,
+ resourceID INTEGER (0..65535),
+ wholeMultiplex NULL
+ },
+ estimatedReceivedJitterMantissa INTEGER (0..3),
+ estimatedReceivedJitterExponent INTEGER (0..7),
+ skippedFrameCount INTEGER (0..15) OPTIONAL,
+ additionalDecoderBuffer INTEGER (0..262143) OPTIONAL, -- 262143 is 2^18 - 1
+ ...
+}
+
+-- ===================================================================================
+-- Indication Message : H.223 logical channel skew
+-- ===================================================================================
+
+H223SkewIndication ::=SEQUENCE
+{
+ logicalChannelNumber1 LogicalChannelNumber,
+ logicalChannelNumber2 LogicalChannelNumber,
+ skew INTEGER (0..4095), -- units milliseconds
+ ...
+}
+
+-- ===================================================================================
+-- Indication Message : H.225.0 maximum logical channel skew
+-- ===================================================================================
+
+H2250MaximumSkewIndication ::=SEQUENCE
+{
+ logicalChannelNumber1 LogicalChannelNumber,
+ logicalChannelNumber2 LogicalChannelNumber,
+ maximumSkew INTEGER (0..4095), -- units milliseconds
+ ...
+}
+
+-- ===================================================================================
+-- Indication Message : MC Location Indication
+-- ===================================================================================
+
+MCLocationIndication ::=SEQUENCE
+{
+ signalAddress TransportAddress, -- this is the H.323 Call Signalling
+ -- address of the entity which
+ -- contains the MC
+ ...
+}
+
+-- ===================================================================================
+-- Indication Message : Vendor Identification
+-- ===================================================================================
+
+ VendorIdentification ::=SEQUENCE
+ {
+ vendor NonStandardIdentifier,
+ productNumber OCTET STRING (SIZE(1..256)) OPTIONAL, -- per vendor
+ versionNumber OCTET STRING (SIZE(1..256)) OPTIONAL, -- per productNumber
+ ...
+ }
+
+
+-- ===================================================================================
+-- Indication Message : New ATM virtual channel indication
+-- ===================================================================================
+
+NewATMVCIndication ::=SEQUENCE
+{
+ resourceID INTEGER(0..65535),
+ bitRate INTEGER(1..65535), -- units 64 kbit/s
+ bitRateLockedToPCRClock BOOLEAN,
+ bitRateLockedToNetworkClock BOOLEAN,
+ aal CHOICE
+ {
+ aal1 SEQUENCE
+ {
+ clockRecovery CHOICE
+ {
+ nullClockRecovery NULL,
+ srtsClockRecovery NULL,
+ adaptiveClockRecovery NULL,
+ ...
+ },
+ errorCorrection CHOICE
+ {
+ nullErrorCorrection NULL,
+ longInterleaver NULL,
+ shortInterleaver NULL,
+ errorCorrectionOnly NULL,
+ ...
+ },
+ structuredDataTransfer BOOLEAN,
+ partiallyFilledCells BOOLEAN,
+ ...
+ },
+ aal5 SEQUENCE
+ {
+ forwardMaximumSDUSize INTEGER (0..65535), -- units octets
+ backwardMaximumSDUSize INTEGER (0..65535), -- units octets
+ ...
+ },
+ ...
+ },
+ multiplex CHOICE
+ {
+ noMultiplex NULL,
+ transportStream NULL,
+ programStream NULL,
+ ...
+ },
+ ...,
+ reverseParameters SEQUENCE
+ {
+ bitRate INTEGER(1..65535), -- units 64 kbit/s
+ bitRateLockedToPCRClock BOOLEAN,
+ bitRateLockedToNetworkClock BOOLEAN,
+ multiplex CHOICE
+ {
+ noMultiplex NULL,
+ transportStream NULL,
+ programStream NULL,
+ ...
+ },
+ ...
+ }
+}
+
+-- ===================================================================================
+-- Indication Message : user input
+-- ===================================================================================
+
+UserInputIndication ::=CHOICE
+{
+ nonStandard NonStandardParameter,
+ alphanumeric GeneralString,
+ ...,
+ userInputSupportIndication CHOICE
+ {
+ nonStandard NonStandardParameter,
+ basicString NULL,
+ iA5String NULL,
+ generalString NULL,
+ ...
+ },
+ signal SEQUENCE
+ {
+ signalType IA5String (SIZE (1) ^ FROM ("0123456789#*ABCD!")),
+-- signalType IA5String (SIZE (1)) (FROM ("0123456789#*ABCD!")),
+ duration INTEGER (1..65535) OPTIONAL, -- milliseconds
+ rtp SEQUENCE
+ {
+ timestamp INTEGER (0..4294967295) OPTIONAL,
+ expirationTime INTEGER (0..4294967295) OPTIONAL,
+ logicalChannelNumber LogicalChannelNumber,
+ ...
+ } OPTIONAL,
+ ...
+ },
+ signalUpdate SEQUENCE
+ {
+ duration INTEGER (1..65535), -- milliseconds
+ rtp SEQUENCE
+ {
+ logicalChannelNumber LogicalChannelNumber,
+ ...
+ } OPTIONAL,
+ ...
+ }
+}
+
+
+END
+
+
+
+
+
+
+
diff --git a/lib/asn1/test/asn1_SUITE_data/MissingEnd.asn1 b/lib/asn1/test/asn1_SUITE_data/MissingEnd.asn1
new file mode 100644
index 0000000000..66912ef693
--- /dev/null
+++ b/lib/asn1/test/asn1_SUITE_data/MissingEnd.asn1
@@ -0,0 +1,5 @@
+MissingEnd DEFINITIONS ::=
+BEGIN
+
+T ::= Typ
+
diff --git a/lib/asn1/test/asn1_SUITE_data/Mod.set.asn b/lib/asn1/test/asn1_SUITE_data/Mod.set.asn
new file mode 100644
index 0000000000..5dcd8706ae
--- /dev/null
+++ b/lib/asn1/test/asn1_SUITE_data/Mod.set.asn
@@ -0,0 +1,5 @@
+Mod1.asn
+Mod2.asn
+Mod3.asn
+Mod4.asn
+Mod5.asn
diff --git a/lib/asn1/test/asn1_SUITE_data/Mod1.asn b/lib/asn1/test/asn1_SUITE_data/Mod1.asn
new file mode 100644
index 0000000000..cb29997985
--- /dev/null
+++ b/lib/asn1/test/asn1_SUITE_data/Mod1.asn
@@ -0,0 +1,18 @@
+Mod1 DEFINITIONS AUTOMATIC TAGS ::=
+
+BEGIN
+
+IMPORTS
+ Co,Reg
+ FROM Mod5
+ Name
+ FROM Mod4;
+
+
+L ::= SEQUENCE {
+ country Co,
+ region Reg,
+ name Name
+}
+
+END
diff --git a/lib/asn1/test/asn1_SUITE_data/Mod2.asn b/lib/asn1/test/asn1_SUITE_data/Mod2.asn
new file mode 100644
index 0000000000..cc22c6f13c
--- /dev/null
+++ b/lib/asn1/test/asn1_SUITE_data/Mod2.asn
@@ -0,0 +1,43 @@
+Mod2 DEFINITIONS AUTOMATIC TAGS ::=
+
+BEGIN
+
+IMPORTS
+ Stat,Country
+ FROM Mod3
+ L
+ FROM Mod1
+ Time,LocName,ThingName,Name
+ FROM Mod4;
+
+T ::= SEQUENCE {
+ unit ENUMERATED{celsius,fahrenheit,kelvin},
+ degree INTEGER,
+ location L,
+ time Time,
+ statistics Stat
+}
+
+OtherName ::= SEQUENCE {
+ locationName LocName,
+ thingName ThingName
+}
+
+FirstName ::= CHOICE {
+ firstname PrintableString,
+ nickname PrintableString
+}
+
+FamilyName ::= SEQUENCE{
+ prefix ENUMERATED{none,von,af},
+ secondname PrintableString
+}
+
+Lang ::= SEQUENCE{
+ l PrintableString}
+
+Inhabitant ::= SEQUENCE {
+ name Name,
+ country Country}
+
+END
diff --git a/lib/asn1/test/asn1_SUITE_data/Mod3.asn b/lib/asn1/test/asn1_SUITE_data/Mod3.asn
new file mode 100644
index 0000000000..8069bedcf9
--- /dev/null
+++ b/lib/asn1/test/asn1_SUITE_data/Mod3.asn
@@ -0,0 +1,33 @@
+Mod3 DEFINITIONS AUTOMATIC TAGS ::=
+
+BEGIN
+
+IMPORTS
+ Name
+ FROM Mod4
+ Lang, Inhabitant,FirstName,FamilyName
+ FROM Mod2
+ TS, RFS, WS, HS
+ FROM Mod5;
+
+Stat ::= SEQUENCE {
+ tempstat TS,
+ rainfallstat RFS,
+ windstat WS,
+ humiditystat HS
+}
+
+Country ::= SEQUENCE{
+ name Name,
+ language Lang
+}
+
+RegionName ::= Name
+Inhabitants ::= SEQUENCE OF Inhabitant
+
+PersonName ::= SEQUENCE {
+ name1 FirstName,
+ name2 FamilyName
+}
+
+END
diff --git a/lib/asn1/test/asn1_SUITE_data/Mod4.asn b/lib/asn1/test/asn1_SUITE_data/Mod4.asn
new file mode 100644
index 0000000000..4a1aaff9dc
--- /dev/null
+++ b/lib/asn1/test/asn1_SUITE_data/Mod4.asn
@@ -0,0 +1,33 @@
+Mod4 DEFINITIONS AUTOMATIC TAGS ::=
+
+
+BEGIN
+
+IMPORTS
+ PersonName
+ FROM Mod3
+ OtherName,FirstName,FamilyName
+ FROM Mod2;
+
+Time ::= SEQUENCE {
+ year OCTET STRING(SIZE(4)),
+ month OCTET STRING(SIZE(2)),
+ hour INTEGER,
+ minute INTEGER
+}
+
+Name ::= CHOICE {
+ person PersonName,
+ othername OtherName
+}
+
+
+
+LocName ::= SEQUENCE {
+ region ENUMERATED{gotaland,svealand,norrland},
+ name PrintableString
+}
+
+ThingName ::= PrintableString
+
+END
diff --git a/lib/asn1/test/asn1_SUITE_data/Mod5.asn b/lib/asn1/test/asn1_SUITE_data/Mod5.asn
new file mode 100644
index 0000000000..71b483d0e0
--- /dev/null
+++ b/lib/asn1/test/asn1_SUITE_data/Mod5.asn
@@ -0,0 +1,37 @@
+Mod5 DEFINITIONS AUTOMATIC TAGS ::=
+
+BEGIN
+
+IMPORTS
+ Country,RegionName,Inhabitants
+ FROM Mod3;
+TS ::= SEQUENCE {
+ average INTEGER,
+ highest INTEGER,
+ lowest INTEGER
+}
+
+RFS ::= SEQUENCE {
+ average INTEGER,
+ highest INTEGER
+}
+
+WS ::= SEQUENCE {
+ average INTEGER,
+ highest INTEGER
+}
+
+HS ::= SEQUENCE {
+ average INTEGER,
+ highest INTEGER,
+ lowest INTEGER
+}
+
+Co ::= Country
+
+Reg ::= SEQUENCE {
+ name RegionName,
+ inhabitants Inhabitants
+}
+
+END
diff --git a/lib/asn1/test/asn1_SUITE_data/Mvrasn-11-4.asn b/lib/asn1/test/asn1_SUITE_data/Mvrasn-11-4.asn
new file mode 100644
index 0000000000..81c07a2dab
--- /dev/null
+++ b/lib/asn1/test/asn1_SUITE_data/Mvrasn-11-4.asn
@@ -0,0 +1,675 @@
+-- module(Mvrasn-11-4).
+-- vsn('%CCaseRev: %').
+-- date('%CCaseDate: %').
+-- author('eedkbu').
+-- =============================================================================
+
+-- =============================================================================
+--
+-- Title : "Mobile Service data types".
+--
+-- ASN.1 module: "MAP-MS-DataTypes".
+--
+-- =============================================================================
+
+-- ==============================================================
+-- #1. REVISION LOG
+-- ==============================================================
+-- Rev Date Name What
+-- .... ....... ....... ........................................
+-- PA1 981014 eedkbu First draft, based on GSM 09.02 v. 6.1.0.
+-- .... ....... ........ ........................................
+-- PA2 990112 eedkbu Insertion of all Data types relevant for
+-- DSD operation.
+-- .... ....... ........ ........................................
+
+Mvrasn-11-4
+
+DEFINITIONS
+
+IMPLICIT TAGS
+
+::=
+
+BEGIN
+
+EXPORTS
+
+ -- location registration types
+ UpdateGprsLocationArg,
+ UpdateGprsLocationRes,
+ CancelLocationArg,
+ CancelLocationRes,
+
+ -- subscriber management types
+ InsertSubscriberDataArg,
+ InsertSubscriberDataRes
+;
+
+IMPORTS
+
+ SS-SubscriptionOption,
+ SS-List,
+ maxNumOfSS
+FROM Mvrasn-14-4
+
+ SS-Code
+FROM Mvrasn-15-4
+
+ ISDN-AddressString,
+ maxISDN-AddressLength,
+ ISDN-SubaddressString,
+ IMSI,
+ LMSI,
+ Ext-BasicServiceCode,
+ NAEA-PreferredCI,
+ EMLPP-Info
+FROM Mvrasn-18-4
+
+ Ext-TeleserviceCode
+FROM Mvrasn-19-4
+
+ Ext-BearerServiceCode
+FROM Mvrasn-20-4
+
+ ExtensionContainer
+FROM Mvrasn-21-4
+
+;
+
+-- location registration types
+
+CancelLocationArg ::= [3] SEQUENCE {
+ identity Indentity,
+ cancellationType CancellationType OPTIONAL,
+ extensionContainer ExtensionContainer OPTIONAL,
+ ...}
+
+Indentity ::= CHOICE {
+ imsi IMSI,
+ imsi-WithLMSI IMSI-WithLMSI}
+
+
+CancellationType ::= ENUMERATED {
+ updateProcedure (0),
+ subscriptionWithdraw (1),
+ ...}
+
+
+CancelLocationRes ::= SEQUENCE {
+ extensionContainer ExtensionContainer OPTIONAL,
+ ...}
+
+IMSI-WithLMSI ::= SEQUENCE {
+ imsi IMSI,
+ lmsi LMSI,
+ -- a special value 00000000 indicates that the LMSI is not in use
+ ...}
+
+
+-- gprs location registration types
+
+UpdateGprsLocationArg ::= SEQUENCE {
+ imsi IMSI,
+ sgsn-Number ISDN-AddressString,
+ sgsn-Address GSN-Address,
+ extensionContainer ExtensionContainer OPTIONAL,
+ ...}
+
+GSN-Address ::= OCTET STRING (SIZE (4..16))
+ -- Octets are coded according to TS GSM 03.03
+
+UpdateGprsLocationRes ::= SEQUENCE {
+ hlr-Number ISDN-AddressString,
+ extensionContainer ExtensionContainer OPTIONAL,
+ ...}
+
+-- subscriber management types
+
+InsertSubscriberDataArg ::= SEQUENCE {
+ imsi [0] IMSI OPTIONAL,
+
+-- =========================================================
+-- EEDKBU:
+--
+-- the line:
+--
+-- "COMPONENTS OF SubscriberData,
+--
+-- has been removed due to insufficiencies of the used ASN.1-ERLANG
+-- compiler. Instead of this line the complete definition of
+-- "Subscriberdata" has been inserted.
+--
+-- This results in the same behaviour of the deocder/encoder but
+-- means only a replication of the ASN.1 definiton here.
+--
+ msisdn [1] ISDN-AddressString OPTIONAL,
+ category [2] Category OPTIONAL,
+ subscriberStatus [3] SubscriberStatus OPTIONAL,
+ bearerServiceList [4] BearerServiceList OPTIONAL,
+ -- The exception handling for reception of unsupported / not allocated
+ -- bearerServiceCodes is defined in section 6.8.1
+ teleserviceList [6] TeleserviceList OPTIONAL,
+ -- The exception handling for reception of unsupported / not allocated
+ -- teleserviceCodes is defined in section 6.8.1
+ provisionedSS [7] Ext-SS-InfoList OPTIONAL,
+ odb-Data [8] ODB-Data OPTIONAL,
+ roamingRestrictionDueToUnsupportedFeature [9] NULL OPTIONAL,
+ regionalSubscriptionData [10] ZoneCodeList OPTIONAL,
+ vbsSubscriptionData [11] VBSDataList OPTIONAL,
+ vgcsSubscriptionData [12] VGCSDataList OPTIONAL,
+ vlrCamelSubscriptionInfo [13] VlrCamelSubscriptionInfo OPTIONAL,
+
+-- =========================================================
+
+ extensionContainer [14] ExtensionContainer OPTIONAL,
+ ... ,
+ naea-PreferredCI [15] NAEA-PreferredCI OPTIONAL,
+ -- naea-PreferredCI is included at the discretion of the HLR operator.
+ gprsSubscriptionData [16] GPRSSubscriptionData OPTIONAL,
+ roamingRestrictedInSgsnDueToUnsupportedFeature [23] NULL OPTIONAL,
+ networkAccessMode [24] NetworkAccessMode OPTIONAL
+ }
+ -- If the Network Access Mode parameter is sent, it shall be present
+ -- only in the first sequence if the seqmentation is used
+
+-- =========================================================
+--
+-- EEDKBU: This data type 'NetworkAccessMode' has been included manually
+-- as it was not in the ASN.1 definitions in 09.02 6.1.0.
+-- This definition has been taken from the CR xxx.
+--
+
+NetworkAccessMode ::= ENUMERATED {
+ bothMSCAndSGSN (0),
+ onlyMSC (1),
+ onlySGSN (2),
+ ...}
+ -- if unknown values are received in NetworkAccessMode
+ -- they shall be discarded.
+
+--
+-- =========================================================
+
+
+GPRSDataList ::= SEQUENCE SIZE (1..maxNumOfPDP-Contexts) OF
+ PDP-Context
+
+maxNumOfPDP-Contexts INTEGER ::= 50
+
+PDP-Context ::= SEQUENCE {
+ pdp-ContextId ContextId,
+ pdp-Type [16] PDP-Type,
+ pdp-Address [17] PDP-Address OPTIONAL,
+ qos-Subscribed [18] QoS-Subscribed,
+ vplmnAddressAllowed [19] NULL OPTIONAL,
+ apn [20] APN,
+ extensionContainer [21] ExtensionContainer OPTIONAL,
+ ...}
+
+ContextId ::= INTEGER (1..maxNumOfPDP-Contexts)
+
+GPRSSubscriptionData::= SEQUENCE {
+ completeDataListIncluded NULL OPTIONAL,
+
+ -- If segmentation is used, completeDataListIncluded may only be
+ -- present in the first segment.
+ gprsDataList [1] GPRSDataList,
+ extensionContainer [2] ExtensionContainer OPTIONAL,
+ ...}
+
+APN ::= IA5String (SIZE (1..63))
+-- Octets are coded according to TS GSM 09.60
+
+PDP-Type ::= OCTET STRING (SIZE (2))
+-- Octets are coded according to TS GSM 09.60
+
+PDP-Address ::= OCTET STRING (SIZE (4..16))
+-- Octets are coded according to TS GSM 09.60
+
+QoS-Subscribed ::= OCTET STRING (SIZE (3))
+ -- Octets are coded according to TS GSM 04.08.
+
+
+SubscriberData ::= SEQUENCE {
+ msisdn [1] ISDN-AddressString OPTIONAL,
+ category [2] Category OPTIONAL,
+ subscriberStatus [3] SubscriberStatus OPTIONAL,
+ bearerServiceList [4] BearerServiceList OPTIONAL,
+ -- The exception handling for reception of unsupported / not allocated
+ -- bearerServiceCodes is defined in section 6.8.1
+ teleserviceList [6] TeleserviceList OPTIONAL,
+ -- The exception handling for reception of unsupported / not allocated
+ -- teleserviceCodes is defined in section 6.8.1
+ provisionedSS [7] Ext-SS-InfoList OPTIONAL,
+ odb-Data [8] ODB-Data OPTIONAL,
+ roamingRestrictionDueToUnsupportedFeature [9] NULL OPTIONAL,
+ regionalSubscriptionData [10] ZoneCodeList OPTIONAL,
+ vbsSubscriptionData [11] VBSDataList OPTIONAL,
+ vgcsSubscriptionData [12] VGCSDataList OPTIONAL,
+ vlrCamelSubscriptionInfo [13] VlrCamelSubscriptionInfo OPTIONAL
+ }
+
+Category ::= OCTET STRING (SIZE (1))
+ -- The internal structure is defined in CCITT Rec Q.763.
+
+SubscriberStatus ::= ENUMERATED {
+ serviceGranted (0),
+ operatorDeterminedBarring (1)}
+
+BearerServiceList ::= SEQUENCE SIZE (1..maxNumOfBearerServices) OF
+ Ext-BearerServiceCode
+
+maxNumOfBearerServices INTEGER ::= 50
+
+TeleserviceList ::= SEQUENCE SIZE (1..maxNumOfTeleservices) OF
+ Ext-TeleserviceCode
+
+maxNumOfTeleservices INTEGER ::= 20
+
+ODB-Data ::= SEQUENCE {
+ odb-GeneralData ODB-GeneralData,
+ odb-HPLMN-Data ODB-HPLMN-Data OPTIONAL,
+ extensionContainer ExtensionContainer OPTIONAL,
+ ...}
+
+ODB-GeneralData ::= BIT STRING {
+ allOG-CallsBarred (0),
+ internationalOGCallsBarred (1),
+ internationalOGCallsNotToHPLMN-CountryBarred (2),
+ interzonalOGCallsBarred (6),
+ interzonalOGCallsNotToHPLMN-CountryBarred (7),
+ interzonalOGCallsAndInternationalOGCallsNotToHPLMN-CountryBarred (8),
+ premiumRateInformationOGCallsBarred (3),
+ premiumRateEntertainementOGCallsBarred (4),
+ ss-AccessBarred (5),
+ allECT-Barred (9),
+ chargeableECT-Barred (10),
+ internationalECT-Barred (11),
+ interzonalECT-Barred (12),
+ doublyChargeableECT-Barred (13),
+ multipleECT-Barred (14)} (SIZE (15..32))
+ -- exception handling: reception of unknown bit assignments in the
+ -- ODB-GeneralData type shall be treated like unsupported ODB-GeneralData
+
+ODB-HPLMN-Data ::= BIT STRING {
+ plmn-SpecificBarringType1 (0),
+ plmn-SpecificBarringType2 (1),
+ plmn-SpecificBarringType3 (2),
+ plmn-SpecificBarringType4 (3)} (SIZE (4..32))
+ -- exception handling: reception of unknown bit assignments in the
+ -- ODB-HPLMN-Data type shall be treated like unsupported ODB-HPLMN-Data
+
+Ext-SS-InfoList ::= SEQUENCE SIZE (1..maxNumOfSS) OF
+ Ext-SS-Info
+
+Ext-SS-Info ::= CHOICE {
+ forwardingInfo [0] Ext-ForwInfo,
+ callBarringInfo [1] Ext-CallBarInfo,
+ cug-Info [2] CUG-Info,
+ ss-Data [3] Ext-SS-Data,
+ emlpp-Info [4] EMLPP-Info}
+
+
+Ext-ForwInfo ::= SEQUENCE {
+ ss-Code SS-Code,
+ forwardingFeatureList Ext-ForwFeatureList,
+ extensionContainer [0] ExtensionContainer OPTIONAL,
+ ...}
+
+Ext-ForwFeatureList ::=
+ SEQUENCE SIZE (1..maxNumOfExt-BasicServiceGroups) OF
+ Ext-ForwFeature
+
+Ext-ForwFeature ::= SEQUENCE {
+ basicService Ext-BasicServiceCode OPTIONAL,
+ ss-Status [4] Ext-SS-Status,
+ forwardedToNumber [5] ISDN-AddressString OPTIONAL,
+ -- When this data type is sent from an HLR which supports CAMEL Phase 2
+ -- to a VLR that supports CAMEL Phase 2 the VLR shall not check the
+ -- format of the number
+ forwardedToSubaddress [8] ISDN-SubaddressString OPTIONAL,
+ forwardingOptions [6] Ext-ForwOptions OPTIONAL,
+ noReplyConditionTime [7] Ext-NoRepCondTime OPTIONAL,
+ extensionContainer [9] ExtensionContainer OPTIONAL,
+ ...}
+
+Ext-SS-Status ::= OCTET STRING (SIZE (1..5))
+
+ -- OCTET 1:
+ --
+ -- bits 8765: 0000 (unused)
+ -- bits 4321: Used to convey the "P bit","R bit","A bit" and "Q bit",
+ -- representing supplementary service state information
+ -- as defined in TS GSM 03.11
+
+ -- bit 4: "Q bit"
+
+ -- bit 3: "P bit"
+
+ -- bit 2: "R bit"
+
+ -- bit 1: "A bit"
+
+ -- OCTETS 2-5: reserved for future use. They shall be discarded if
+ -- received and not understood.
+
+
+Ext-ForwOptions ::= OCTET STRING (SIZE (1..5))
+
+ -- OCTET 1:
+
+ -- bit 8: notification to forwarding party
+ -- 0 no notification
+ -- 1 notification
+
+ -- bit 7: 0 (unused)
+
+ -- bit 6: notification to calling party
+ -- 0 no notification
+ -- 1 notification
+
+ -- bit 5: 0 (unused)
+
+ -- bits 43: forwarding reason
+ -- 00 ms not reachable
+ -- 01 ms busy
+ -- 10 no reply
+ -- 11 unconditional
+
+ -- bits 21: 00 (unused)
+
+ -- OCTETS 2-5: reserved for future use. They shall be discarded if
+ -- received and not understood.
+
+Ext-NoRepCondTime ::= INTEGER (1..100)
+ -- Only values 5-30 are used.
+ -- Values in the ranges 1-4 and 31-100 are reserved for future use
+ -- If received:
+ -- values 1-4 shall be mapped on to value 5
+ -- values 31-100 shall be mapped on to value 30
+
+Ext-CallBarInfo ::= SEQUENCE {
+ ss-Code SS-Code,
+ callBarringFeatureList Ext-CallBarFeatureList,
+ extensionContainer ExtensionContainer OPTIONAL,
+ ...}
+
+Ext-CallBarFeatureList ::=
+ SEQUENCE SIZE (1..maxNumOfExt-BasicServiceGroups) OF
+ Ext-CallBarringFeature
+
+Ext-CallBarringFeature ::= SEQUENCE {
+ basicService Ext-BasicServiceCode OPTIONAL,
+ ss-Status [4] Ext-SS-Status,
+ extensionContainer ExtensionContainer OPTIONAL,
+ ...}
+
+CUG-Info ::= SEQUENCE {
+ cug-SubscriptionList CUG-SubscriptionList,
+ cug-FeatureList CUG-FeatureList OPTIONAL,
+ extensionContainer [0] ExtensionContainer OPTIONAL,
+ ...}
+
+CUG-SubscriptionList ::= SEQUENCE SIZE (0..maxNumOfCUG) OF
+ CUG-Subscription
+
+CUG-Subscription ::= SEQUENCE {
+ cug-Index CUG-Index,
+ cug-Interlock CUG-Interlock,
+ intraCUG-Options IntraCUG-Options,
+ basicServiceGroupList Ext-BasicServiceGroupList OPTIONAL,
+ extensionContainer [0] ExtensionContainer OPTIONAL,
+ ...}
+
+CUG-Index ::= INTEGER (0..32767)
+ -- The internal structure is defined in ETS 300 138.
+
+CUG-Interlock ::= OCTET STRING (SIZE (4))
+
+IntraCUG-Options ::= ENUMERATED {
+ noCUG-Restrictions (0),
+ cugIC-CallBarred (1),
+ cugOG-CallBarred (2)}
+
+maxNumOfCUG INTEGER ::= 10
+
+CUG-FeatureList ::= SEQUENCE SIZE (1..maxNumOfExt-BasicServiceGroups) OF
+ CUG-Feature
+
+Ext-BasicServiceGroupList ::= SEQUENCE SIZE
+ (1..maxNumOfExt-BasicServiceGroups) OF
+ Ext-BasicServiceCode
+
+maxNumOfExt-BasicServiceGroups INTEGER ::= 32
+
+CUG-Feature ::= SEQUENCE {
+ basicService Ext-BasicServiceCode OPTIONAL,
+ preferentialCUG-Indicator CUG-Index OPTIONAL,
+ interCUG-Restrictions InterCUG-Restrictions,
+ extensionContainer ExtensionContainer OPTIONAL,
+ ...}
+
+InterCUG-Restrictions::= OCTET STRING (SIZE (1))
+
+ -- bits 876543: 000000 (unused)
+ -- Exception handling:
+ -- bits 876543 shall be ignored if received and not understood
+
+ -- bits 21
+ -- 00 CUG only facilities
+ -- 01 CUG with outgoing access
+ -- 10 CUG with incoming access
+ -- 11 CUG with both outgoing and incoming access
+
+Ext-SS-Data ::= SEQUENCE {
+ ss-Code SS-Code,
+ ss-Status [4] Ext-SS-Status,
+ ss-SubscriptionOption SS-SubscriptionOption OPTIONAL,
+ basicServiceGroupList Ext-BasicServiceGroupList OPTIONAL,
+ extensionContainer [5] ExtensionContainer OPTIONAL,
+ ...}
+
+ZoneCodeList ::= SEQUENCE SIZE (1..maxNumOfZoneCodes) OF
+ ZoneCode
+
+ZoneCode ::= OCTET STRING (SIZE (2))
+ -- internal structure is defined in TS GSM 03.03
+
+maxNumOfZoneCodes INTEGER ::= 10
+
+InsertSubscriberDataRes ::= SEQUENCE {
+ teleserviceList [1] TeleserviceList OPTIONAL,
+ bearerServiceList [2] BearerServiceList OPTIONAL,
+ ss-List [3] SS-List OPTIONAL,
+ odb-GeneralData [4] ODB-GeneralData OPTIONAL,
+ regionalSubscriptionResponse [5] RegionalSubscriptionResponse OPTIONAL,
+ supportedCamelPhases [6] SupportedCamelPhases OPTIONAL,
+ extensionContainer [7] ExtensionContainer OPTIONAL,
+ ...}
+
+RegionalSubscriptionResponse ::= ENUMERATED {
+ networkNode-AreaRestricted (0),
+ tooManyZoneCodes (1),
+ zoneCodesConflict (2),
+ regionalSubscNotSupported (3)}
+
+DeleteSubscriberDataArg ::= SEQUENCE {
+ imsi [0] IMSI,
+ basicServiceList [1] BasicServiceList OPTIONAL,
+ -- The exception handling for reception of unsupported/not allocated
+ -- basicServiceCodes is defined in section 6.8.2
+ ss-List [2] SS-List OPTIONAL,
+ roamingRestrictionDueToUnsupportedFeature [4] NULL OPTIONAL,
+ regionalSubscriptionIdentifier [5] ZoneCode OPTIONAL,
+ vbsGroupIndication [7] NULL OPTIONAL,
+ vgcsGroupIndication [8] NULL OPTIONAL,
+ camelSubscriptionInfoWithdraw [9] NULL OPTIONAL,
+ extensionContainer [6] ExtensionContainer OPTIONAL,
+ ...,
+ gprsSubscriptionDataWithdraw [10] GPRSSubscriptionDataWithdraw OPTIONAL,
+ roamingRestrictedInSgsnDueToUnsuppportedFeature [11] NULL OPTIONAL}
+
+GPRSSubscriptionDataWithdraw ::= CHOICE {
+ allGPRSData NULL,
+ contextIdList ContextIdList}
+
+ContextIdList ::= SEQUENCE SIZE (1..maxNumOfPDP-Contexts) OF
+ ContextId
+
+BasicServiceList ::= SEQUENCE SIZE (1..maxNumOfBasicServices) OF
+ Ext-BasicServiceCode
+
+maxNumOfBasicServices INTEGER ::= 70
+
+DeleteSubscriberDataRes ::= SEQUENCE {
+ regionalSubscriptionResponse [0] RegionalSubscriptionResponse OPTIONAL,
+ extensionContainer ExtensionContainer OPTIONAL,
+ ...}
+
+VlrCamelSubscriptionInfo ::= SEQUENCE {
+ o-CSI [0] O-CSI OPTIONAL,
+ extensionContainer [1] ExtensionContainer OPTIONAL,
+ ...,
+ ss-CSI [2] SS-CSI OPTIONAL
+ }
+
+SS-CSI ::= SEQUENCE {
+ ss-CamelData SS-CamelData,
+ extensionContainer ExtensionContainer OPTIONAL,
+ ...}
+
+SS-CamelData ::= SEQUENCE {
+ ss-EventList SS-EventList,
+ gsmSCF-Address ISDN-AddressString,
+ extensionContainer [0] ExtensionContainer OPTIONAL,
+ ...
+ }
+
+SS-EventList ::= SEQUENCE SIZE (1..maxNumOfCamelSSEvents) OF SS-Code
+ -- Actions for the following SS-Code values are defined in CAMEL Phase 2:
+ -- ect SS-Code ::= '00110001'B
+ -- multiPTY SS-Code ::= '01010001'B
+ -- cd SS-Code ::= '00100100'B
+ -- all other SS codes shall be ignored
+
+maxNumOfCamelSSEvents INTEGER ::= 10
+
+O-CSI ::= SEQUENCE {
+ o-BcsmCamelTDPDataList O-BcsmCamelTDPDataList,
+ extensionContainer ExtensionContainer OPTIONAL,
+ ...,
+ camelCapabilityHandling [0] CamelCapabilityHandling OPTIONAL
+ }
+
+O-BcsmCamelTDPDataList ::= SEQUENCE SIZE (1..maxNumOfCamelTDPData) OF
+ O-BcsmCamelTDPData
+
+maxNumOfCamelTDPData INTEGER ::= 10
+
+O-BcsmCamelTDPData ::= SEQUENCE {
+ o-BcsmTriggerDetectionPoint O-BcsmTriggerDetectionPoint,
+ serviceKey ServiceKey,
+ gsmSCF-Address [0] ISDN-AddressString,
+ defaultCallHandling [1] DefaultCallHandling,
+ extensionContainer [2] ExtensionContainer OPTIONAL,
+ ...,
+ o-BcsmCamelTDP-Criteria [3] O-BcsmCamelTDP-Criteria OPTIONAL
+ }
+
+ServiceKey ::= INTEGER (0..2147483647)
+
+O-BcsmTriggerDetectionPoint ::= ENUMERATED {
+ collectedInfo (2),
+ ... }
+-- exception handling:
+-- For O-BcsmCamelTDPData sequences containing this parameter with any
+-- other value than the ones listed the receiver shall ignore the whole
+-- O-BcsmCamelTDPDatasequence.
+
+O-BcsmCamelTDP-Criteria ::= SEQUENCE {
+ destinationNumberCriteria [0] DestinationNumberCriteria OPTIONAL,
+ basicServiceCriteria [1] BasicServiceCriteria OPTIONAL,
+ callTypeCriteria [2] CallTypeCriteria OPTIONAL,
+ ... }
+
+DestinationNumberCriteria ::= SEQUENCE {
+ matchType [0] MatchType,
+ destinationNumberList [1] DestinationNumberList OPTIONAL,
+ destinationNumberLengthList [2] DestinationNumberLengthList OPTIONAL,
+ ... }
+
+DestinationNumberList ::= SEQUENCE SIZE (1..maxNumOfCamelDestinationNumbers) OF
+ ISDN-AddressString
+-- The receiving entity shall not check the format of a number in
+-- the dialled number list
+
+DestinationNumberLengthList ::= SEQUENCE SIZE
+-- (1..maxNumOfCamelDestinationNumberLengths) OF
+ (1..maxISDN-AddressLength) OF
+-- INTEGER(1..maxISDN-AddressLength)
+ INTEGER(1..maxNumOfSS)
+
+BasicServiceCriteria ::= SEQUENCE SIZE(1..maxNumOfCamelBasicServiceCriteria) OF
+ Ext-BasicServiceCode
+
+maxNumOfCamelDestinationNumbers INTEGER ::= 10
+
+maxNumOfCamelDestinationNumberLengths INTEGER ::= 3
+
+maxNumOfCamelBasicServiceCriteria INTEGER ::= 5
+
+CallTypeCriteria ::= ENUMERATED {
+ forwarded (0),
+ notForwarded (1)}
+
+MatchType ::= ENUMERATED {
+ inhibiting (0),
+ enabling (1)}
+
+
+DefaultCallHandling ::= ENUMERATED {
+ continueCall (0) ,
+ releaseCall (1) ,
+ ...}
+-- exception handling:
+-- reception of values in range 2-31 shall be treated as "continueCall"
+-- reception of values greater than 31 shall be treated as "releaseCall"
+
+CamelCapabilityHandling ::= INTEGER(1..16)
+-- value 1 = CAMEL phase 1,
+-- value 2 = CAMEL phase 2:
+-- reception of values greater than 2 shall be treated as CAMEL phase 2
+
+SupportedCamelPhases ::= BIT STRING {
+ phase1 (0),
+ phase2 (1) } (SIZE (1..16))
+
+-- VBS/VGCS types
+
+VBSDataList ::= SEQUENCE SIZE (1..maxNumOfVBSGroupIds) OF
+ VoiceBroadcastData
+
+VGCSDataList ::= SEQUENCE SIZE (1..maxNumOfVGCSGroupIds) OF
+ VoiceGroupCallData
+
+maxNumOfVBSGroupIds INTEGER ::= 50
+
+maxNumOfVGCSGroupIds INTEGER ::= 50
+
+VoiceGroupCallData ::= SEQUENCE {
+ groupId GroupId,
+ extensionContainer ExtensionContainer OPTIONAL,
+ ...}
+
+VoiceBroadcastData ::= SEQUENCE {
+ groupid GroupId,
+ broadcastInitEntitlement NULL OPTIONAL,
+ extensionContainer ExtensionContainer OPTIONAL,
+ ...}
+
+GroupId ::= OCTET STRING (SIZE (3))
+ -- Refers to the Group Identification as specified in GSM TS 03.03
+ -- and 03.68/ 03.69
+
+END
diff --git a/lib/asn1/test/asn1_SUITE_data/Mvrasn-11-6.asn b/lib/asn1/test/asn1_SUITE_data/Mvrasn-11-6.asn
new file mode 100644
index 0000000000..d826c1398f
--- /dev/null
+++ b/lib/asn1/test/asn1_SUITE_data/Mvrasn-11-6.asn
@@ -0,0 +1,1776 @@
+-- module(Mvrasn-11-6).
+-- vsn('%CCaseRev: %').
+-- date('%CCaseDate: %').
+-- author('etord').
+-- =============================================================================
+
+-- =============================================================================
+--
+-- Title : "Mobile Service data types".
+--
+-- ASN.1 module: "MAP-MS-DataTypes".
+--
+-- =============================================================================
+
+-- ==============================================================
+-- #1. REVISION LOG
+-- ==============================================================
+-- Rev Date Name What
+-- .... ....... ....... ........................................
+-- PA1 010201 etord First draft, based on GSM 29.002 v. 3.5.2.
+-- PA2 010813 etord Updated according to GSM 29.002 v. 3.8.0.
+-- .... ....... ........ ........................................
+
+Mvrasn-11-6
+
+DEFINITIONS
+
+IMPLICIT TAGS
+
+::=
+
+BEGIN
+
+EXPORTS
+
+ -- location registration types
+ UpdateLocationArg,
+ UpdateLocationRes,
+ CancelLocationArg,
+ CancelLocationRes,
+ PurgeMS-Arg,
+ PurgeMS-Res,
+ SendIdentificationArg,
+ SendIdentificationRes,
+ UpdateGprsLocationArg,
+ UpdateGprsLocationRes,
+ IST-SupportIndicator,
+
+ -- gprs location registration types
+ GSN-Address,
+
+ -- handover types
+ ForwardAccessSignalling-Arg,
+ PrepareHO-Arg,
+ PrepareHO-Res,
+ PrepareSubsequentHO-Arg,
+ PrepareSubsequentHO-Res,
+ ProcessAccessSignalling-Arg,
+ SendEndSignal-Arg,
+ SendEndSignal-Res,
+
+
+ -- authentication management types
+ SendAuthenticationInfoArg,
+ SendAuthenticationInfoRes,
+ AuthenticationFailureReportArg,
+ AuthenticationFailureReportRes,
+
+ -- security management types
+ EquipmentStatus,
+ Kc,
+
+ -- subscriber management types
+ InsertSubscriberDataArg,
+ InsertSubscriberDataRes,
+ LSAIdentity,
+ DeleteSubscriberDataArg,
+ DeleteSubscriberDataRes,
+ SubscriberData,
+ ODB-Data,
+ SubscriberStatus,
+ ZoneCodeList,
+ maxNumOfZoneCodes,
+ O-CSI,
+ D-CSI,
+ O-BcsmCamelTDPCriteriaList,
+ T-BCSM-CAMEL-TDP-CriteriaList,
+ SS-CSI,
+ ServiceKey,
+ DefaultCallHandling,
+ CamelCapabilityHandling,
+ BasicServiceCriteria,
+ SupportedCamelPhases,
+ maxNumOfCamelTDPData,
+ CUG-Index,
+ CUG-Interlock,
+ InterCUG-Restrictions,
+ IntraCUG-Options,
+ NotificationToMSUser,
+ IST-AlertTimerValue,
+ T-CSI,
+ T-BcsmTriggerDetectionPoint,
+
+ -- fault recovery types
+ ResetArg,
+ RestoreDataArg,
+ RestoreDataRes,
+
+-- provide subscriber info types
+GeographicalInformation,
+
+ -- subscriber information enquiry types
+ ProvideSubscriberInfoArg,
+ ProvideSubscriberInfoRes,
+ SubscriberInfo,
+ LocationInformation,
+ SubscriberState,
+
+ -- any time information enquiry types
+ AnyTimeInterrogationArg,
+ AnyTimeInterrogationRes,
+
+ -- any time information handling types
+ AnyTimeSubscriptionInterrogationArg,
+ AnyTimeSubscriptionInterrogationRes,
+ AnyTimeModificationArg,
+ AnyTimeModificationRes,
+
+ -- subscriber data modification notification types
+ NoteSubscriberDataModifiedArg,
+ NoteSubscriberDataModifiedRes,
+
+ -- gprs location information retrieval types
+ -- error in spec detected by our compiler SendRoutingInfoForGprsArg,
+ -- SendRoutingInfoForGprsRes,
+
+ -- failure reporting types
+ FailureReportArg,
+ FailureReportRes,
+
+ -- gprs notification types
+ NoteMsPresentForGprsArg,
+ NoteMsPresentForGprsRes,
+
+ -- Mobility Management types
+NoteMM-EventArg,
+ NoteMM-EventRes
+
+
+
+;
+
+IMPORTS
+ maxNumOfSS,
+ SS-SubscriptionOption,
+ SS-List,
+ SS-ForBS-Code,
+ Password
+FROM Mvrasn-14-6
+
+ SS-Code
+FROM Mvrasn-15-6
+
+
+ Ext-BearerServiceCode
+FROM Mvrasn-20-6
+
+
+ Ext-TeleserviceCode
+FROM Mvrasn-19-6
+
+
+ AddressString,
+ISDN-AddressString,
+ ISDN-SubaddressString,
+ FTN-AddressString,
+ AccessNetworkSignalInfo,
+ IMSI,
+ TMSI,
+ HLR-List,
+ LMSI,
+ Identity,
+ GlobalCellId,
+ CellGlobalIdOrServiceAreaIdOrLAI,
+ Ext-BasicServiceCode,
+ NAEA-PreferredCI,
+ EMLPP-Info,
+ MC-SS-Info,
+ SubscriberIdentity,
+ AgeOfLocationInformation,
+ LCSClientExternalID,
+ LCSClientInternalID,
+ Ext-SS-Status
+
+FROM Mvrasn-18-6
+
+
+ ExtensionContainer
+FROM Mvrasn-21-4
+
+;
+
+
+-- location registration types
+
+UpdateLocationArg ::= SEQUENCE {
+ imsi IMSI,
+
+ msc-Number [1] ISDN-AddressString,
+ vlr-Number ISDN-AddressString,
+ lmsi [10] LMSI OPTIONAL,
+ extensionContainer ExtensionContainer OPTIONAL,
+ ... ,
+ vlr-Capability [6] VLR-Capability OPTIONAL }
+
+VLR-Capability ::= SEQUENCE{
+ supportedCamelPhases [0] SupportedCamelPhases OPTIONAL,
+ extensionContainer ExtensionContainer OPTIONAL,
+ ... ,
+ solsaSupportIndicator [2] NULL OPTIONAL,
+ istSupportIndicator [1] IST-SupportIndicator OPTIONAL,
+ superChargerSupportedInServingNetworkEntity [3] SuperChargerInfo OPTIONAL,
+ longFTN-Supported [4] NULL OPTIONAL }
+
+SuperChargerInfo ::= CHOICE {
+ sendSubscriberData [0] NULL,
+ subscriberDataStored [1] AgeIndicator }
+
+AgeIndicator ::= OCTET STRING (SIZE (1..6))
+ -- The internal structure of this parameter is implementation specific.
+
+
+IST-SupportIndicator ::= ENUMERATED {
+ basicISTSupported (0),
+ istCommandSupported (1),
+ ...}
+-- exception handling:
+-- reception of values > 1 shall be mapped to ' istCommandSupported '
+
+
+UpdateLocationRes ::= SEQUENCE {
+ hlr-Number ISDN-AddressString,
+
+ extensionContainer ExtensionContainer OPTIONAL,
+ ... }
+
+CancelLocationArg ::= [3] SEQUENCE {
+ identity Identity,
+ cancellationType CancellationType OPTIONAL,
+ extensionContainer ExtensionContainer OPTIONAL,
+ ...}
+
+
+CancellationType ::= ENUMERATED {
+ updateProcedure (0),
+ subscriptionWithdraw (1),
+ ...}
+ -- The HLR shall not send values other than listed above
+
+
+CancelLocationRes ::= SEQUENCE {
+ extensionContainer ExtensionContainer OPTIONAL,
+ ...}
+
+PurgeMS-Arg ::= [3] SEQUENCE {
+ imsi IMSI,
+ vlr-Number [0] ISDN-AddressString OPTIONAL,
+ sgsn-Number [1] ISDN-AddressString OPTIONAL,
+ extensionContainer ExtensionContainer OPTIONAL,
+ ...}
+
+PurgeMS-Res ::= SEQUENCE {
+ freezeTMSI [0] NULL OPTIONAL,
+ freezeP-TMSI [1] NULL OPTIONAL,
+ extensionContainer ExtensionContainer OPTIONAL,
+ ...}
+
+SendIdentificationArg ::= SEQUENCE {
+ tmsi TMSI,
+ numberOfRequestedVectors NumberOfRequestedVectors OPTIONAL,
+ -- if segmentation is used, numberOfRequestedVectors shall be present in
+ -- the first segment and shall not be present in subsequent segments. If received
+ -- in a subsequent segment it shall be discarded.
+ segmentationProhibited NULL OPTIONAL,
+ -- if segmentation is prohibited the previous VLR shall not send the result
+ -- within a TC-CONTINUE message.
+ extensionContainer ExtensionContainer OPTIONAL,
+ ...}
+
+SendIdentificationRes ::= [3] SEQUENCE {
+ imsi IMSI OPTIONAL,
+ -- IMSI must be present if SendIdentificationRes is not segmented.
+ -- If the TC-Continue segmentation option is taken the IMSI must be
+ -- present in one segmented transmission of SendIdentificationRes.
+ authenticationSetList AuthenticationSetList OPTIONAL,
+ currentSecurityContext [2]CurrentSecurityContext OPTIONAL,
+ extensionContainer [3] ExtensionContainer OPTIONAL,
+ ...}
+
+-- authentication management types
+
+AuthenticationSetList ::= CHOICE {
+ tripletList [0] TripletList,
+ quintupletList [1] QuintupletList }
+
+TripletList ::= SEQUENCE SIZE (1..5) OF
+ AuthenticationTriplet
+
+QuintupletList ::= SEQUENCE SIZE (1..5) OF
+ AuthenticationQuintuplet
+
+AuthenticationTriplet ::= SEQUENCE {
+ rand RAND,
+ sres SRES,
+ kc Kc,
+ ...}
+
+AuthenticationQuintuplet ::= SEQUENCE {
+ rand RAND,
+ xres XRES,
+ ck CK,
+ ik IK,
+ autn AUTN,
+ ...}
+
+CurrentSecurityContext ::= CHOICE {
+ gsm-SecurityContextData [0] GSM-SecurityContextData,
+ umts-SecurityContextData [1] UMTS-SecurityContextData }
+
+GSM-SecurityContextData ::= SEQUENCE {
+ kc Kc,
+ cksn Cksn,
+ ... }
+
+UMTS-SecurityContextData ::= SEQUENCE {
+ ck CK,
+ ik IK,
+ ksi KSI,
+ ... }
+
+RAND ::= OCTET STRING (SIZE (16))
+
+SRES ::= OCTET STRING (SIZE (4))
+
+Kc ::= OCTET STRING (SIZE (8))
+
+XRES ::= OCTET STRING (SIZE (4..16))
+
+CK ::= OCTET STRING (SIZE (16))
+
+IK ::= OCTET STRING (SIZE (16))
+
+AUTN ::= OCTET STRING (SIZE (16))
+
+AUTS ::= OCTET STRING (SIZE (14))
+
+Cksn ::= OCTET STRING (SIZE (1))
+ -- The internal structure is defined in 3G TS 24.008
+
+KSI ::= OCTET STRING (SIZE (1))
+ -- The internal structure is defined in 3G TS 24.008
+
+AuthenticationFailureReportArg ::= SEQUENCE {
+ imsi IMSI,
+ failureCause FailureCause,
+ extensionContainer ExtensionContainer OPTIONAL,
+ ...}
+
+AuthenticationFailureReportRes ::= SEQUENCE {
+ extensionContainer ExtensionContainer OPTIONAL,
+ ...}
+
+FailureCause ::= ENUMERATED {
+ wrongUserResponse (0),
+ wrongNetworkSignature (1)}
+
+-- gprs location registration types
+
+UpdateGprsLocationArg ::= SEQUENCE {
+ imsi IMSI,
+ sgsn-Number ISDN-AddressString,
+ sgsn-Address GSN-Address,
+ extensionContainer ExtensionContainer OPTIONAL,
+ ... ,
+ sgsn-Capability [0] SGSN-Capability OPTIONAL }
+
+SGSN-Capability ::= SEQUENCE{
+ solsaSupportIndicator NULL OPTIONAL,
+ extensionContainer [1] ExtensionContainer OPTIONAL,
+ ... ,
+ superChargerSupportedInServingNetworkEntity [2] SuperChargerInfo OPTIONAL ,
+ gprsEnhancementsSupportIndicator [3] NULL OPTIONAL,
+ supportedCamelPhases [4] SupportedCamelPhases OPTIONAL }
+
+GSN-Address ::= OCTET STRING (SIZE (5..17))
+ -- Octets are coded according to TS GSM 03.03
+
+UpdateGprsLocationRes ::= SEQUENCE {
+ hlr-Number ISDN-AddressString,
+ extensionContainer ExtensionContainer OPTIONAL,
+ ...}
+
+-- handover types
+
+ForwardAccessSignalling-Arg ::= [3] SEQUENCE {
+ an-APDU AccessNetworkSignalInfo,
+ integrityProtectionInfo [0] IntegrityProtectionInformation OPTIONAL,
+ encryptionInfo [1] EncryptionInformation OPTIONAL,
+ keyStatus [2] KeyStatus OPTIONAL,
+ extensionContainer [3] ExtensionContainer OPTIONAL,
+ ...}
+
+KeyStatus ::= ENUMERATED {
+ old (0),
+ new (1),
+ ...}
+ -- exception handling:
+ -- received values in range 2-31 shall be treated as "old"
+ -- received values greater than 31 shall be treated as "new"
+
+PrepareHO-Arg ::= [3] SEQUENCE {
+ targetCellId [0] GlobalCellId OPTIONAL,
+ ho-NumberNotRequired NULL OPTIONAL,
+ targetRNCId [1] RNCId OPTIONAL,
+ an-APDU [2] AccessNetworkSignalInfo OPTIONAL,
+ multipleBearerRequested [3] NULL OPTIONAL,
+ imsi [4] IMSI OPTIONAL,
+ integrityProtectionInfo [5] IntegrityProtectionInformation OPTIONAL,
+ encryptionInfo [6] EncryptionInformation OPTIONAL,
+ radioResourceInformation [7] RadioResourceInformation OPTIONAL,
+ extensionContainer [8] ExtensionContainer OPTIONAL,
+ ...}
+
+PrepareHO-Res ::= [3] SEQUENCE {
+ handoverNumber [0] ISDN-AddressString OPTIONAL,
+ relocationNumberList [1] RelocationNumberList OPTIONAL,
+ an-APDU [2] AccessNetworkSignalInfo OPTIONAL,
+ multicallBearerInfo [3] MulticallBearerInfo OPTIONAL,
+ multipleBearerNotSupported NULL OPTIONAL,
+ extensionContainer [4] ExtensionContainer OPTIONAL,
+ ...}
+
+PrepareSubsequentHO-Arg ::= [3] SEQUENCE {
+ targetCellId [0] GlobalCellId OPTIONAL,
+ targetMSC-Number [1] ISDN-AddressString,
+ targetRNCId [2] RNCId OPTIONAL,
+ an-APDU [3] AccessNetworkSignalInfo OPTIONAL,
+ selectedRab-Id [4] RAB-Id OPTIONAL,
+ extensionContainer [5] ExtensionContainer OPTIONAL,
+ ...}
+
+PrepareSubsequentHO-Res ::= [3] SEQUENCE {
+ an-APDU AccessNetworkSignalInfo,
+ extensionContainer [0] ExtensionContainer OPTIONAL,
+ ...}
+
+ProcessAccessSignalling-Arg ::= [3] SEQUENCE {
+ an-APDU AccessNetworkSignalInfo,
+ extensionContainer [0] ExtensionContainer OPTIONAL,
+ ...}
+
+SendEndSignal-Arg ::= [3] SEQUENCE {
+ an-APDU AccessNetworkSignalInfo,
+ extensionContainer [0] ExtensionContainer OPTIONAL,
+ ...}
+
+SendEndSignal-Res ::= SEQUENCE {
+ extensionContainer [0] ExtensionContainer OPTIONAL,
+ ...}
+
+RNCId ::= OCTET STRING (SIZE (7))
+ -- Refers to the Target RNC-ID in the Target ID in 3G TS 25.413, where the encoding is
+ -- defined.
+
+RelocationNumberList ::= SEQUENCE SIZE (1..maxNumOfRelocationNumber) OF
+ RelocationNumber
+
+MulticallBearerInfo ::= INTEGER (1..maxNumOfRelocationNumber)
+
+RelocationNumber ::= SEQUENCE {
+ handoverNumber ISDN-AddressString,
+ rab-Id RAB-Id,
+ -- RAB Identity is needed to relate the calls with the radio access bearers.
+ ...}
+
+RAB-Id ::= INTEGER (1..maxNrOfRABs)
+
+maxNrOfRABs INTEGER ::= 255
+
+maxNumOfRelocationNumber INTEGER ::= 7
+
+RadioResourceInformation ::= OCTET STRING (SIZE (5..10))
+ -- Octets are coded according the Channel Type information element in GSM 08.08
+
+
+IntegrityProtectionInformation ::= OCTET STRING (SIZE (17..maxNumOfIntegrityInfo))
+ -- Octets are coded according to 3G TS 25.413
+
+
+maxNumOfIntegrityInfo INTEGER ::= 100
+
+EncryptionInformation ::= OCTET STRING (SIZE (17..maxNumOfEncryptionInfo))
+ -- Octets are coded according to 3G TS 25.413
+
+
+maxNumOfEncryptionInfo INTEGER ::= 100
+
+-- authentication management types
+
+SendAuthenticationInfoArg ::= SEQUENCE {
+ imsi [0] IMSI,
+ numberOfRequestedVectors NumberOfRequestedVectors,
+ segmentationProhibited NULL OPTIONAL,
+ -- if segmentation is prohibited the HLR shall not send the result within
+ -- a TC-CONTINUE message.
+ immediateResponsePreferred [1] NULL OPTIONAL,
+ -- if present, the HLR may send an immediate response with the available authentication
+ -- vectors (see � 8.5.2 for more information).
+ re-synchronisationInfo Re-synchronisationInfo OPTIONAL,
+ extensionContainer [2] ExtensionContainer OPTIONAL,
+ ...}
+
+NumberOfRequestedVectors ::= INTEGER (1..5)
+
+Re-synchronisationInfo ::= SEQUENCE {
+ rand RAND,
+ auts AUTS,
+ ...}
+
+SendAuthenticationInfoRes ::= [3] SEQUENCE {
+ authenticationSetList AuthenticationSetList OPTIONAL,
+ extensionContainer ExtensionContainer OPTIONAL,
+ ...}
+
+
+-- security management types
+
+EquipmentStatus ::= ENUMERATED {
+ whiteListed (0),
+ blackListed (1),
+ greyListed (2)}
+
+
+-- subscriber management types
+
+InsertSubscriberDataArg ::= SEQUENCE {
+ imsi [0] IMSI OPTIONAL,
+ COMPONENTS OF SubscriberData,
+ extensionContainer [14] ExtensionContainer OPTIONAL,
+ ... ,
+ naea-PreferredCI [15] NAEA-PreferredCI OPTIONAL,
+ -- naea-PreferredCI is included at the discretion of the HLR operator.
+ gprsSubscriptionData [16] GPRSSubscriptionData OPTIONAL,
+ roamingRestrictedInSgsnDueToUnsupportedFeature [23] NULL
+ OPTIONAL,
+ networkAccessMode [24] NetworkAccessMode OPTIONAL,
+ lsaInformation [25] LSAInformation OPTIONAL,
+ lmu-Indicator [21] NULL OPTIONAL,
+ lcsInformation [22] LCSInformation OPTIONAL,
+ istAlertTimer [26] IST-AlertTimerValue OPTIONAL,
+ superChargerSupportedInHLR [27] AgeIndicator OPTIONAL,
+ mc-SS-Info [28] MC-SS-Info OPTIONAL,
+ cs-AllocationRetentionPriority [29] CS-AllocationRetentionPriority OPTIONAL,
+ sgsn-CAMEL-SubscriptionInfo [17] SGSN-CAMEL-SubscriptionInfo OPTIONAL,
+ chargingCharacteristics [18] ChargingCharacteristics OPTIONAL
+ }
+ -- If the Network Access Mode parameter is sent, it shall be present only in
+ -- the first sequence if seqmentation is used
+
+CS-AllocationRetentionPriority ::= OCTET STRING (SIZE (1))
+ -- This data type encodes each priority level defined in TS 23.107 as the binary value
+ -- of the priority level.
+
+IST-AlertTimerValue ::= INTEGER (15..255)
+
+LCSInformation ::= SEQUENCE {
+ gmlc-List [0] GMLC-List OPTIONAL,
+ lcs-PrivacyExceptionList [1] LCS-PrivacyExceptionList OPTIONAL,
+ molr-List [2] MOLR-List OPTIONAL,
+ ...}
+
+GMLC-List ::= SEQUENCE SIZE (1..maxNumOfGMLC) OF
+ ISDN-AddressString
+ -- if segmentation is used, the complete GMLC-List shall be sent in one segment
+
+maxNumOfGMLC INTEGER ::= 5
+
+
+NetworkAccessMode ::= ENUMERATED {
+ bothMSCAndSGSN (0),
+ onlyMSC (1),
+ onlySGSN (2),
+ ...}
+ -- if unknown values are received in NetworkAccessMode
+ -- they shall be discarded.
+
+GPRSDataList ::= SEQUENCE SIZE (1..maxNumOfPDP-Contexts) OF
+ PDP-Context
+
+maxNumOfPDP-Contexts INTEGER ::= 50
+
+PDP-Context ::= SEQUENCE {
+ pdp-ContextId ContextId,
+ pdp-Type [16] PDP-Type,
+ pdp-Address [17] PDP-Address OPTIONAL,
+ qos-Subscribed [18] QoS-Subscribed,
+ vplmnAddressAllowed [19] NULL OPTIONAL,
+ apn [20] APN,
+ extensionContainer [21] ExtensionContainer OPTIONAL,
+ ... ,
+ ext-QoS-Subscribed [0] Ext-QoS-Subscribed OPTIONAL,
+ pdp-ChargingCharacteristics [1] ChargingCharacteristics OPTIONAL }
+ -- qos-Subscribed shall be discarded if ext-QoS-Subscribed is received and supported
+
+ContextId ::= INTEGER (1..maxNumOfPDP-Contexts)
+
+GPRSSubscriptionData ::= SEQUENCE {
+ completeDataListIncluded NULL OPTIONAL,
+
+ -- If segmentation is used, completeDataListIncluded may only be present in the
+ -- first segment.
+ gprsDataList [1] GPRSDataList,
+ extensionContainer [2] ExtensionContainer OPTIONAL,
+ ... }
+
+SGSN-CAMEL-SubscriptionInfo ::= SEQUENCE {
+ gprs-CSI [0] GPRS-CSI OPTIONAL,
+ sms-CSI [1] SMS-CSI OPTIONAL,
+ extensionContainer [2] ExtensionContainer OPTIONAL,
+ ...}
+
+GPRS-CSI ::= SEQUENCE {
+ gprs-CamelTDPDataList [0] GPRS-CamelTDPDataList OPTIONAL,
+ camelCapabilityHandling [1] CamelCapabilityHandling OPTIONAL,
+ extensionContainer [2] ExtensionContainer OPTIONAL,
+ notificationToCSE [3] NULL OPTIONAL,
+ csi-Active [4] NULL OPTIONAL,
+ ...}
+-- notificationToCSE and csi-Active shall not be present when GPRS-CSI is sent to SGSN.
+-- They may only be included in ATSI/ATM ack/NSDC message.
+-- GPRS-CamelTDPData and camelCapabilityHandling shall be present in
+-- the GPRS-CSI sequence.
+-- If GPRS-CSI is segmented, gprs-CamelTDPDataList and camelCapabilityHandling shall be
+-- present in the first segment
+
+GPRS-CamelTDPDataList ::= SEQUENCE SIZE (1..maxNumOfCamelTDPData) OF
+ GPRS-CamelTDPData
+-- GPRS-CamelTDPDataList shall not contain more than one instance of
+-- GPRS-CamelTDPData containing the same value for gprs-TriggerDetectionPoint.
+
+GPRS-CamelTDPData ::= SEQUENCE {
+ gprs-TriggerDetectionPoint [0] GPRS-TriggerDetectionPoint,
+ serviceKey [1] ServiceKey,
+ gsmSCF-Address [2] ISDN-AddressString,
+ defaultSessionHandling [3] DefaultGPRS-Handling,
+ extensionContainer [4] ExtensionContainer OPTIONAL,
+ ...
+ }
+
+DefaultGPRS-Handling ::= ENUMERATED {
+ continueTransaction (0) ,
+ releaseTransaction (1) ,
+ ...}
+-- exception handling:
+-- reception of values in range 2-31 shall be treated as "continueTransaction"
+-- reception of values greater than 31 shall be treated as "releaseTransaction"
+
+GPRS-TriggerDetectionPoint ::= ENUMERATED {
+ attach (1),
+ attachChangeOfPosition (2),
+ pdp-ContextEstablishment (11),
+ pdp-ContextEstablishmentAcknowledgement (12),
+ pdp-ContextChangeOfPosition (14),
+ ... }
+-- exception handling:
+-- For GPRS-CamelTDPData sequences containing this parameter with any
+-- other value than the ones listed the receiver shall ignore the whole
+-- GPRS-CamelTDPDatasequence.
+
+APN ::= OCTET STRING (SIZE (2..63))
+ -- Octets are coded according to TS GSM 03.03
+
+PDP-Type ::= OCTET STRING (SIZE (2))
+ -- Octets are coded according to TS GSM 09.60
+
+PDP-Address ::= OCTET STRING (SIZE (1..16))
+ -- Octets are coded according to TS GSM 09.60
+
+ -- The possible size values are:
+ -- 1-7 octets X.25 address type
+ -- 4 octets IPv4 address type
+ -- 16 octets Ipv6 address type
+
+QoS-Subscribed ::= OCTET STRING (SIZE (3))
+ -- Octets are coded according to TS GSM 04.08.
+
+Ext-QoS-Subscribed ::= OCTET STRING (SIZE (1..9))
+ -- OCTET 1:
+ -- Allocation/Retention Priority (This octet encodes each priority level defined in
+ -- 23.107 as the binary value of the priority level, declaration in 29.060)
+ -- Octets 2-9 are coded according to 3G TS 24.008 Quality of Service Octets
+ -- 6-13.
+
+ChargingCharacteristics ::= OCTET STRING (SIZE (2))
+ -- Octets are coded according to 3G TS 32.015.
+
+LSAOnlyAccessIndicator ::= ENUMERATED {
+ accessOutsideLSAsAllowed (0),
+ accessOutsideLSAsRestricted (1)}
+
+LSADataList ::= SEQUENCE SIZE (1..maxNumOfLSAs) OF
+ LSAData
+
+maxNumOfLSAs INTEGER ::= 20
+
+LSAData ::= SEQUENCE {
+ lsaIdentity [0] LSAIdentity,
+ lsaAttributes [1] LSAAttributes,
+ lsaActiveModeIndicator [2] NULL OPTIONAL,
+ extensionContainer [3] ExtensionContainer OPTIONAL,
+ ...}
+
+LSAInformation ::= SEQUENCE {
+ completeDataListIncluded NULL OPTIONAL,
+
+ -- If segmentation is used, completeDataListIncluded may only be present in the
+ -- first segment.
+ lsaOnlyAccessIndicator [1] LSAOnlyAccessIndicator OPTIONAL,
+ lsaDataList [2] LSADataList OPTIONAL,
+ extensionContainer [3] ExtensionContainer OPTIONAL,
+ ...}
+
+LSAIdentity ::= OCTET STRING (SIZE (3))
+ -- Octets are coded according to TS GSM 03.03
+
+LSAAttributes ::= OCTET STRING (SIZE (1))
+ -- Octets are coded according to TS GSM 08.08
+
+
+SubscriberData ::= SEQUENCE {
+ msisdn [1] ISDN-AddressString OPTIONAL,
+ category [2] Category OPTIONAL,
+ subscriberStatus [3] SubscriberStatus OPTIONAL,
+ bearerServiceList [4] BearerServiceList OPTIONAL,
+ -- The exception handling for reception of unsupported / not allocated
+ -- bearerServiceCodes is defined in section 8.8.1
+ teleserviceList [6] TeleserviceList OPTIONAL,
+ -- The exception handling for reception of unsupported / not allocated
+ -- teleserviceCodes is defined in section 8.8.1
+ provisionedSS [7] Ext-SS-InfoList OPTIONAL,
+ odb-Data [8] ODB-Data OPTIONAL,
+ roamingRestrictionDueToUnsupportedFeature [9] NULL OPTIONAL,
+ regionalSubscriptionData [10] ZoneCodeList OPTIONAL,
+ vbsSubscriptionData [11] VBSDataList OPTIONAL,
+ vgcsSubscriptionData [12] VGCSDataList OPTIONAL,
+ vlrCamelSubscriptionInfo [13] VlrCamelSubscriptionInfo OPTIONAL
+ }
+
+Category ::= OCTET STRING (SIZE (1))
+ -- The internal structure is defined in CCITT Rec Q.763.
+
+SubscriberStatus ::= ENUMERATED {
+ serviceGranted (0),
+ operatorDeterminedBarring (1)}
+
+BearerServiceList ::= SEQUENCE SIZE (1..maxNumOfBearerServices) OF
+ Ext-BearerServiceCode
+
+maxNumOfBearerServices INTEGER ::= 50
+
+TeleserviceList ::= SEQUENCE SIZE (1..maxNumOfTeleservices) OF
+ Ext-TeleserviceCode
+
+maxNumOfTeleservices INTEGER ::= 20
+
+ODB-Data ::= SEQUENCE {
+ odb-GeneralData ODB-GeneralData,
+ odb-HPLMN-Data ODB-HPLMN-Data OPTIONAL,
+ extensionContainer ExtensionContainer OPTIONAL,
+ ...}
+
+ODB-GeneralData ::= BIT STRING {
+ allOG-CallsBarred (0),
+ internationalOGCallsBarred (1),
+ internationalOGCallsNotToHPLMN-CountryBarred (2),
+ interzonalOGCallsBarred (6),
+ interzonalOGCallsNotToHPLMN-CountryBarred (7),
+ interzonalOGCallsAndInternationalOGCallsNotToHPLMN-CountryBarred (8),
+ premiumRateInformationOGCallsBarred (3),
+ premiumRateEntertainementOGCallsBarred (4),
+ ss-AccessBarred (5),
+ allECT-Barred (9),
+ chargeableECT-Barred (10),
+ internationalECT-Barred (11),
+ interzonalECT-Barred (12),
+ doublyChargeableECT-Barred (13),
+ multipleECT-Barred (14)} (SIZE (15..32))
+ -- exception handling: reception of unknown bit assignments in the
+ -- ODB-GeneralData type shall be treated like unsupported ODB-GeneralData
+
+ODB-HPLMN-Data ::= BIT STRING {
+ plmn-SpecificBarringType1 (0),
+ plmn-SpecificBarringType2 (1),
+ plmn-SpecificBarringType3 (2),
+ plmn-SpecificBarringType4 (3)} (SIZE (4..32))
+ -- exception handling: reception of unknown bit assignments in the
+ -- ODB-HPLMN-Data type shall be treated like unsupported ODB-HPLMN-Data
+
+Ext-SS-InfoList ::= SEQUENCE SIZE (1..maxNumOfSS) OF
+ Ext-SS-Info
+
+Ext-SS-Info ::= CHOICE {
+ forwardingInfo [0] Ext-ForwInfo,
+ callBarringInfo [1] Ext-CallBarInfo,
+ cug-Info [2] CUG-Info,
+ ss-Data [3] Ext-SS-Data,
+ emlpp-Info [4] EMLPP-Info}
+
+
+Ext-ForwInfo ::= SEQUENCE {
+ ss-Code SS-Code,
+ forwardingFeatureList Ext-ForwFeatureList,
+ extensionContainer [0] ExtensionContainer OPTIONAL,
+ ...}
+
+Ext-ForwFeatureList ::= SEQUENCE SIZE (1..maxNumOfExt-BasicServiceGroups) OF
+ Ext-ForwFeature
+
+Ext-ForwFeature ::= SEQUENCE {
+ basicService Ext-BasicServiceCode OPTIONAL,
+ ss-Status [4] Ext-SS-Status,
+ forwardedToNumber [5] ISDN-AddressString OPTIONAL,
+ -- When this data type is sent from an HLR which supports CAMEL Phase 2
+ -- to a VLR that supports CAMEL Phase 2 the VLR shall not check the
+ -- format of the number
+ forwardedToSubaddress [8] ISDN-SubaddressString OPTIONAL,
+ forwardingOptions [6] Ext-ForwOptions OPTIONAL,
+ noReplyConditionTime [7] Ext-NoRepCondTime OPTIONAL,
+ extensionContainer [9] ExtensionContainer OPTIONAL,
+ ...,
+ longForwardedToNumber [10] FTN-AddressString OPTIONAL }
+
+Ext-ForwOptions ::= OCTET STRING (SIZE (1..5))
+
+ -- OCTET 1:
+
+ -- bit 8: notification to forwarding party
+ -- 0 no notification
+ -- 1 notification
+
+ -- bit 7: redirecting presentation
+ -- 0 no presentation
+ -- 1 presentation
+
+ -- bit 6: notification to calling party
+ -- 0 no notification
+ -- 1 notification
+
+ -- bit 5: 0 (unused)
+
+ -- bits 43: forwarding reason
+ -- 00 ms not reachable
+ -- 01 ms busy
+ -- 10 no reply
+ -- 11 unconditional
+
+ -- bits 21: 00 (unused)
+
+ -- OCTETS 2-5: reserved for future use. They shall be discarded if
+ -- received and not understood.
+
+Ext-NoRepCondTime ::= INTEGER (1..100)
+ -- Only values 5-30 are used.
+ -- Values in the ranges 1-4 and 31-100 are reserved for future use
+ -- If received:
+ -- values 1-4 shall be mapped on to value 5
+ -- values 31-100 shall be mapped on to value 30
+
+Ext-CallBarInfo ::= SEQUENCE {
+ ss-Code SS-Code,
+ callBarringFeatureList Ext-CallBarFeatureList,
+ extensionContainer ExtensionContainer OPTIONAL,
+ ...}
+
+Ext-CallBarFeatureList ::= SEQUENCE SIZE (1..maxNumOfExt-BasicServiceGroups) OF
+ Ext-CallBarringFeature
+
+Ext-CallBarringFeature ::= SEQUENCE {
+ basicService Ext-BasicServiceCode OPTIONAL,
+ ss-Status [4] Ext-SS-Status,
+ extensionContainer ExtensionContainer OPTIONAL,
+ ...}
+
+CUG-Info ::= SEQUENCE {
+ cug-SubscriptionList CUG-SubscriptionList,
+ cug-FeatureList CUG-FeatureList OPTIONAL,
+ extensionContainer [0] ExtensionContainer OPTIONAL,
+ ...}
+
+CUG-SubscriptionList ::= SEQUENCE SIZE (0..maxNumOfCUG) OF
+ CUG-Subscription
+
+CUG-Subscription ::= SEQUENCE {
+ cug-Index CUG-Index,
+ cug-Interlock CUG-Interlock,
+ intraCUG-Options IntraCUG-Options,
+ basicServiceGroupList Ext-BasicServiceGroupList OPTIONAL,
+ extensionContainer [0] ExtensionContainer OPTIONAL,
+ ...}
+
+CUG-Index ::= INTEGER (0..32767)
+ -- The internal structure is defined in ETS 300 138.
+
+CUG-Interlock ::= OCTET STRING (SIZE (4))
+
+IntraCUG-Options ::= ENUMERATED {
+ noCUG-Restrictions (0),
+ cugIC-CallBarred (1),
+ cugOG-CallBarred (2)}
+
+maxNumOfCUG INTEGER ::= 10
+
+CUG-FeatureList ::= SEQUENCE SIZE (1..maxNumOfExt-BasicServiceGroups) OF
+ CUG-Feature
+
+Ext-BasicServiceGroupList ::= SEQUENCE SIZE (1..maxNumOfExt-BasicServiceGroups) OF
+ Ext-BasicServiceCode
+
+maxNumOfExt-BasicServiceGroups INTEGER ::= 32
+
+CUG-Feature ::= SEQUENCE {
+ basicService Ext-BasicServiceCode OPTIONAL,
+ preferentialCUG-Indicator CUG-Index OPTIONAL,
+ interCUG-Restrictions InterCUG-Restrictions,
+ extensionContainer ExtensionContainer OPTIONAL,
+ ...}
+
+InterCUG-Restrictions ::= OCTET STRING (SIZE (1))
+
+ -- bits 876543: 000000 (unused)
+ -- Exception handling:
+ -- bits 876543 shall be ignored if received and not understood
+
+ -- bits 21
+ -- 00 CUG only facilities
+ -- 01 CUG with outgoing access
+ -- 10 CUG with incoming access
+ -- 11 CUG with both outgoing and incoming access
+
+Ext-SS-Data ::= SEQUENCE {
+ ss-Code SS-Code,
+ ss-Status [4] Ext-SS-Status,
+ ss-SubscriptionOption SS-SubscriptionOption OPTIONAL,
+ basicServiceGroupList Ext-BasicServiceGroupList OPTIONAL,
+ extensionContainer [5] ExtensionContainer OPTIONAL,
+ ...}
+
+LCS-PrivacyExceptionList ::= SEQUENCE SIZE (1..maxNumOfPrivacyClass) OF
+ LCS-PrivacyClass
+
+maxNumOfPrivacyClass INTEGER ::= 4
+
+LCS-PrivacyClass ::= SEQUENCE {
+ ss-Code SS-Code,
+ ss-Status Ext-SS-Status,
+ notificationToMSUser [0] NotificationToMSUser OPTIONAL,
+ -- notificationToMSUser is expected only for
+ -- SS-code = callunrelated or SS-code = callrelated
+ externalClientList [1] ExternalClientList OPTIONAL,
+ -- externalClientList is expected only for SS-code = callunrelated
+ plmnClientList [2] PLMNClientList OPTIONAL,
+ -- plmnClientList is expected only for SS-code = plmn operator
+ extensionContainer [3] ExtensionContainer OPTIONAL,
+ -- if segmentation is used, the complete LCS-PrivacyClass shall be sent in one segment
+ ...}
+
+ExternalClientList ::= SEQUENCE SIZE (0..maxNumOfExternalClient) OF
+ ExternalClient
+
+maxNumOfExternalClient INTEGER ::= 5
+
+PLMNClientList ::= SEQUENCE SIZE (1..maxNumOfPLMNClient) OF
+ LCSClientInternalID
+
+maxNumOfPLMNClient INTEGER ::= 5
+
+ExternalClient ::= SEQUENCE {
+ clientIdentity LCSClientExternalID,
+ gmlc-Restriction [0] GMLC-Restriction OPTIONAL,
+ notificationToMSUser [1] NotificationToMSUser OPTIONAL,
+ extensionContainer [2] ExtensionContainer OPTIONAL,
+ ... }
+
+GMLC-Restriction ::= ENUMERATED {
+ gmlc-List (0),
+ home-Country (1) ,
+ ... }
+-- exception handling:
+-- At reception of any other value than the ones listed the receiver shall ignore
+-- GMLC-Restriction.
+
+NotificationToMSUser ::= ENUMERATED {
+ notifyLocationAllowed (0),
+ notifyAndVerify-LocationAllowedIfNoResponse (1),
+ notifyAndVerify-LocationNotAllowedIfNoResponse (2),
+ ... }
+-- exception handling:
+-- At reception of any other value than the ones listed the receiver shall ignore
+-- NotificationToMSUser.
+
+MOLR-List ::= SEQUENCE SIZE (1..maxNumOfMOLR-Class) OF
+ MOLR-Class
+
+maxNumOfMOLR-Class INTEGER ::= 3
+
+MOLR-Class ::= SEQUENCE {
+ ss-Code SS-Code,
+ ss-Status Ext-SS-Status,
+ extensionContainer [0] ExtensionContainer OPTIONAL,
+ ...}
+
+ZoneCodeList ::= SEQUENCE SIZE (1..maxNumOfZoneCodes)
+ OF ZoneCode
+
+ZoneCode ::= OCTET STRING (SIZE (2))
+ -- internal structure is defined in TS GSM 03.03
+
+maxNumOfZoneCodes INTEGER ::= 10
+
+InsertSubscriberDataRes ::= SEQUENCE {
+ teleserviceList [1] TeleserviceList OPTIONAL,
+ bearerServiceList [2] BearerServiceList OPTIONAL,
+ ss-List [3] SS-List OPTIONAL,
+ odb-GeneralData [4] ODB-GeneralData OPTIONAL,
+ regionalSubscriptionResponse [5] RegionalSubscriptionResponse OPTIONAL,
+ supportedCamelPhases [6] SupportedCamelPhases OPTIONAL,
+ extensionContainer [7] ExtensionContainer OPTIONAL,
+ ...}
+
+RegionalSubscriptionResponse ::= ENUMERATED {
+ networkNode-AreaRestricted (0),
+ tooManyZoneCodes (1),
+ zoneCodesConflict (2),
+ regionalSubscNotSupported (3)}
+
+DeleteSubscriberDataArg ::= SEQUENCE {
+ imsi [0] IMSI,
+ basicServiceList [1] BasicServiceList OPTIONAL,
+ -- The exception handling for reception of unsupported/not allocated
+ -- basicServiceCodes is defined in section 6.8.2
+ ss-List [2] SS-List OPTIONAL,
+ roamingRestrictionDueToUnsupportedFeature [4] NULL OPTIONAL,
+ regionalSubscriptionIdentifier [5] ZoneCode OPTIONAL,
+ vbsGroupIndication [7] NULL OPTIONAL,
+ vgcsGroupIndication [8] NULL OPTIONAL,
+ camelSubscriptionInfoWithdraw [9] NULL OPTIONAL,
+ extensionContainer [6] ExtensionContainer OPTIONAL,
+ ...,
+ gprsSubscriptionDataWithdraw [10] GPRSSubscriptionDataWithdraw OPTIONAL,
+ roamingRestrictedInSgsnDueToUnsuppportedFeature [11] NULL OPTIONAL,
+ lsaInformationWithdraw [12] LSAInformationWithdraw OPTIONAL,
+ gmlc-ListWithdraw [13] NULL OPTIONAL,
+ istInformationWithdraw [14] NULL OPTIONAL,
+ specificCSI-Withdraw [15] SpecificCSI-Withdraw OPTIONAL }
+
+SpecificCSI-Withdraw ::= BIT STRING {
+ o-csi (0),
+ ss-csi (1),
+ tif-csi (2),
+ d-csi (3),
+ vt-csi (4),
+ sms-csi (5),
+ m-csi (6),
+ gprs-csi(7)} (SIZE(8..32))
+-- exception handling:
+-- bits 8 to 31 shall be ignored if received
+
+GPRSSubscriptionDataWithdraw ::= CHOICE {
+ allGPRSData NULL,
+ contextIdList ContextIdList}
+
+ContextIdList ::= SEQUENCE SIZE (1..maxNumOfPDP-Contexts) OF
+ ContextId
+
+LSAInformationWithdraw ::= CHOICE {
+ allLSAData NULL,
+ lsaIdentityList LSAIdentityList }
+
+LSAIdentityList ::= SEQUENCE SIZE (1..maxNumOfLSAs) OF
+ LSAIdentity
+
+BasicServiceList ::= SEQUENCE SIZE (1..maxNumOfBasicServices) OF
+ Ext-BasicServiceCode
+
+maxNumOfBasicServices INTEGER ::= 70
+
+DeleteSubscriberDataRes ::= SEQUENCE {
+ regionalSubscriptionResponse [0] RegionalSubscriptionResponse OPTIONAL,
+ extensionContainer ExtensionContainer OPTIONAL,
+ ...}
+
+VlrCamelSubscriptionInfo ::= SEQUENCE {
+ o-CSI [0] O-CSI OPTIONAL,
+ extensionContainer [1] ExtensionContainer OPTIONAL,
+ ...,
+ ss-CSI [2] SS-CSI OPTIONAL,
+ o-BcsmCamelTDP-CriteriaList [4] O-BcsmCamelTDPCriteriaList OPTIONAL,
+ tif-CSI [3] NULL OPTIONAL,
+ m-CSI [5] M-CSI OPTIONAL,
+ sms-CSI [6] SMS-CSI OPTIONAL,
+ vt-CSI [7] T-CSI OPTIONAL,
+ t-BCSM-CAMEL-TDP-CriteriaList [8] T-BCSM-CAMEL-TDP-CriteriaList OPTIONAL,
+ d-CSI [9] D-CSI OPTIONAL}
+
+D-CSI ::= SEQUENCE {
+ dp-AnalysedInfoCriteriaList [0] DP-AnalysedInfoCriteriaList OPTIONAL,
+ camelCapabilityHandling [1] CamelCapabilityHandling OPTIONAL,
+ extensionContainer [2] ExtensionContainer OPTIONAL,
+ notificationToCSE [3] NULL OPTIONAL,
+ csi-Active [4] NULL OPTIONAL,
+ ...}
+-- notificationToCSE and csi-Active shall not be present when D-CSI is sent to VLR/GMSC.
+-- They may only be included in ATSI/ATM ack/NSDC message.
+-- DP-AnalysedInfoCriteria and camelCapabilityHandling shall be present in
+-- the D-CSI sequence.
+-- If D-CSI is segmented, dp-AnalysedInfoCriteriaList and camelCapabilityHandling shall be
+-- present in the first segment
+
+
+DP-AnalysedInfoCriteriaList ::= SEQUENCE SIZE (1..maxNumOfDP-AnalysedInfoCriteria) OF
+ DP-AnalysedInfoCriterium
+
+maxNumOfDP-AnalysedInfoCriteria INTEGER ::= 10
+
+DP-AnalysedInfoCriterium ::= SEQUENCE {
+ dialledNumber ISDN-AddressString,
+ serviceKey ServiceKey,
+ gsmSCF-Address ISDN-AddressString,
+ defaultCallHandling DefaultCallHandling,
+ extensionContainer ExtensionContainer OPTIONAL,
+ ...}
+
+SS-CSI ::= SEQUENCE {
+ ss-CamelData SS-CamelData,
+ extensionContainer ExtensionContainer OPTIONAL,
+ ...,
+ notificationToCSE [0] NULL OPTIONAL,
+ csi-Active [1] NULL OPTIONAL
+-- notificationToCSE and csi-Active shall not be present when SS-CSI is sent to VLR.
+-- They may only be included in ATSI/ATM ack/NSDC message.
+}
+
+SS-CamelData ::= SEQUENCE {
+ ss-EventList SS-EventList,
+ gsmSCF-Address ISDN-AddressString,
+ extensionContainer [0] ExtensionContainer OPTIONAL,
+ ... }
+
+SS-EventList ::= SEQUENCE SIZE (1..maxNumOfCamelSSEvents) OF SS-Code
+ -- Actions for the following SS-Code values are defined in CAMEL Phase 3:
+ -- ect SS-Code ::= '00110001'B
+ -- multiPTY SS-Code ::= '01010001'B
+ -- cd SS-Code ::= '00100100'B
+ -- ccbs SS-Code ::= '01000100'B
+ -- all other SS codes shall be ignored
+ -- When SS-CSI is sent to the VLR, it shall not contain a marking for ccbs.
+ -- If the VLR receives SS-CSI containing a marking for ccbs, the VLR shall discard the
+ -- ccbs marking in SS-CSI.
+
+maxNumOfCamelSSEvents INTEGER ::= 10
+
+O-CSI ::= SEQUENCE {
+ o-BcsmCamelTDPDataList O-BcsmCamelTDPDataList,
+ extensionContainer ExtensionContainer OPTIONAL,
+ ...,
+ camelCapabilityHandling [0] CamelCapabilityHandling OPTIONAL,
+ notificationToCSE [1] NULL OPTIONAL,
+ csiActive [2] NULL OPTIONAL}
+-- notificationtoCSE and csiActive shall not be present when O-CSI is sent to VLR/GMSC.
+-- They may only be included in ATSI/ATM ack/NSDC message.
+
+O-BcsmCamelTDPDataList ::= SEQUENCE SIZE (1..maxNumOfCamelTDPData) OF
+ O-BcsmCamelTDPData
+ -- O-BcsmCamelTDPDataList shall not contain more than one instance of
+ -- O-BcsmCamelTDPData containing the same value for o-BcsmTriggerDetectionPoint.
+ -- For CAMEL Phase 2, this means that only one instance of O-BcsmCamelTDPData is allowed
+ -- with o-BcsmTriggerDetectionPoint being equal to DP2.
+
+maxNumOfCamelTDPData INTEGER ::= 10
+
+O-BcsmCamelTDPData ::= SEQUENCE {
+ o-BcsmTriggerDetectionPoint O-BcsmTriggerDetectionPoint,
+ serviceKey ServiceKey,
+ gsmSCF-Address [0] ISDN-AddressString,
+ defaultCallHandling [1] DefaultCallHandling,
+ extensionContainer [2] ExtensionContainer OPTIONAL,
+ ...
+ }
+
+ServiceKey ::= INTEGER (0..2147483647)
+
+O-BcsmTriggerDetectionPoint ::= ENUMERATED {
+ collectedInfo (2),
+ ...,
+ routeSelectFailure (4) }
+ -- exception handling:
+ -- For O-BcsmCamelTDPData sequences containing this parameter with any
+ -- other value than the ones listed the receiver shall ignore the whole
+ -- O-BcsmCamelTDPDatasequence.
+ -- For O-BcsmCamelTDP-Criteria sequences containing this parameter with any
+ -- other value than the ones listed the receiver shall ignore the whole
+ -- O-BcsmCamelTDP-Criteria sequence.
+
+O-BcsmCamelTDPCriteriaList ::= SEQUENCE SIZE (1..maxNumOfCamelTDPData) OF
+ O-BcsmCamelTDP-Criteria
+
+T-BCSM-CAMEL-TDP-CriteriaList ::= SEQUENCE SIZE (1..maxNumOfCamelTDPData) OF
+ T-BCSM-CAMEL-TDP-Criteria
+
+O-BcsmCamelTDP-Criteria ::= SEQUENCE {
+ o-BcsmTriggerDetectionPoint O-BcsmTriggerDetectionPoint,
+ destinationNumberCriteria [0] DestinationNumberCriteria OPTIONAL,
+ basicServiceCriteria [1] BasicServiceCriteria OPTIONAL,
+ callTypeCriteria [2] CallTypeCriteria OPTIONAL,
+ ...,
+ o-CauseValueCriteria [3] O-CauseValueCriteria OPTIONAL,
+ extensionContainer [4] ExtensionContainer OPTIONAL }
+
+T-BCSM-CAMEL-TDP-Criteria ::= SEQUENCE {
+ t-BCSM-TriggerDetectionPoint T-BcsmTriggerDetectionPoint,
+ basicServiceCriteria [0] BasicServiceCriteria OPTIONAL,
+ t-CauseValueCriteria [1] T-CauseValueCriteria OPTIONAL,
+ ... }
+
+DestinationNumberCriteria ::= SEQUENCE {
+ matchType [0] MatchType,
+ destinationNumberList [1] DestinationNumberList OPTIONAL,
+ destinationNumberLengthList [2] DestinationNumberLengthList OPTIONAL,
+ -- one or both of destinationNumberList and destinationNumberLengthList
+ -- shall be present
+ ...}
+
+DestinationNumberList ::= SEQUENCE SIZE (1..maxNumOfCamelDestinationNumbers) OF
+ ISDN-AddressString
+ -- The receiving entity shall not check the format of a number in
+ -- the dialled number list
+
+DestinationNumberLengthList ::= SEQUENCE SIZE (1..maxNumOfCamelDestinationNumberLengths)
+OF
+ INTEGER(1..maxNumOfISDN-AddressDigits)
+
+BasicServiceCriteria ::= SEQUENCE SIZE(1..maxNumOfCamelBasicServiceCriteria) OF
+ Ext-BasicServiceCode
+
+maxNumOfISDN-AddressDigits INTEGER ::= 15
+
+maxNumOfCamelDestinationNumbers INTEGER ::= 10
+
+maxNumOfCamelDestinationNumberLengths INTEGER ::= 3
+
+maxNumOfCamelBasicServiceCriteria INTEGER ::= 5
+
+CallTypeCriteria ::= ENUMERATED {
+ forwarded (0),
+ notForwarded (1)}
+
+MatchType ::= ENUMERATED {
+ inhibiting (0),
+ enabling (1)}
+
+O-CauseValueCriteria ::= SEQUENCE SIZE(1..maxNumOfCAMEL-O-CauseValueCriteria) OF
+ CauseValue
+
+T-CauseValueCriteria ::= SEQUENCE SIZE(1..maxNumOfCAMEL-T-CauseValueCriteria) OF
+ CauseValue
+
+maxNumOfCAMEL-O-CauseValueCriteria INTEGER ::= 5
+
+maxNumOfCAMEL-T-CauseValueCriteria INTEGER ::= 5
+
+CauseValue ::= OCTET STRING (SIZE(1))
+-- Type extracted from Cause parameter in ITU-T Recommendation Q.763.
+-- For the use of cause value refer to ITU-T Recommendation Q.850.
+
+
+DefaultCallHandling ::= ENUMERATED {
+ continueCall (0) ,
+ releaseCall (1) ,
+ ...}
+ -- exception handling:
+ -- reception of values in range 2-31 shall be treated as "continueCall"
+ -- reception of values greater than 31 shall be treated as "releaseCall"
+
+CamelCapabilityHandling ::= INTEGER(1..16)
+ -- value 1 = CAMEL phase 1,
+ -- value 2 = CAMEL phase 2,
+ -- value 3 = CAMEL Phase 3:
+ -- reception of values greater than 3 shall be treated as CAMEL phase 3.
+
+SupportedCamelPhases ::= BIT STRING {
+ phase1 (0),
+ phase2 (1) ,
+ phase3 (2) } (SIZE (1..16))
+-- A node shall mark in the BIT STRING all CAMEL Phases it supports.
+-- Other values than listed above shall be discarded.
+
+SMS-CSI ::= SEQUENCE {
+ sms-CAMEL-TDP-DataList [0] SMS-CAMEL-TDP-DataList OPTIONAL,
+ camelCapabilityHandling [1] CamelCapabilityHandling OPTIONAL,
+ extensionContainer [2] ExtensionContainer OPTIONAL,
+ notificationToCSE [3] NULL OPTIONAL,
+ csi-Active [4] NULL OPTIONAL,
+ ...}
+-- notificationToCSE and csi-Active shall not be present when SMS-CSI is sent to VLR/SGSN.
+-- They may only be included in ATSI/ATM ack/NSDC message.
+-- SMS-CAMEL-TDP-Data and camelCapabilityHandling shall be present in
+-- the SMS-CSI sequence.
+-- If SMS-CSI is segmented, sms-CAMEL-TDP-DataList and camelCapabilityHandling shall be
+-- present in the first segment
+
+SMS-CAMEL-TDP-DataList ::= SEQUENCE SIZE (1..maxNumOfCamelTDPData) OF
+ SMS-CAMEL-TDP-Data
+-- SMS-CAMEL-TDP-DataList shall not contain more than one instance of
+-- SMS-CAMEL-TDP-Data containing the same value for sms-TriggerDetectionPoint.
+
+SMS-CAMEL-TDP-Data ::= SEQUENCE {
+ sms-TriggerDetectionPoint [0] SMS-TriggerDetectionPoint,
+ serviceKey [1] ServiceKey,
+ gsmSCF-Address [2] ISDN-AddressString,
+ defaultSMS-Handling [3] DefaultSMS-Handling,
+ extensionContainer [4] ExtensionContainer OPTIONAL,
+ ...
+ }
+
+SMS-TriggerDetectionPoint ::= ENUMERATED {
+ sms-CollectedInfo (1),
+ ... }
+-- exception handling:
+-- For SMS-CAMEL-TDP-Data sequences containing this parameter with any
+-- other value than the ones listed the receiver shall ignore the whole
+-- SMS-CAMEL-TDP-Data sequence.
+
+DefaultSMS-Handling ::= ENUMERATED {
+ continueTransaction (0) ,
+ releaseTransaction (1) ,
+ ...}
+-- exception handling:
+-- reception of values in range 2-31 shall be treated as "continueTransaction"
+-- reception of values greater than 31 shall be treated as "releaseTransaction"
+
+M-CSI ::= SEQUENCE {
+ mobilityTriggers MobilityTriggers,
+ serviceKey ServiceKey,
+ gsmSCF-Address [0] ISDN-AddressString,
+ extensionContainer [1] ExtensionContainer OPTIONAL,
+ notificationToCSE [2] NULL OPTIONAL,
+ csi-Active [3] NULL OPTIONAL,
+ ...}
+-- notificationToCSE and csi-Active shall not be present when M-CSI is sent to VLR.
+-- They may only be included in ATSI/ATM ack/NSDC message.
+
+MobilityTriggers ::= SEQUENCE SIZE (1..maxNumOfMobilityTriggers) OF
+ MM-Code
+
+maxNumOfMobilityTriggers INTEGER ::= 10
+
+MM-Code ::= OCTET STRING (SIZE (1))
+-- This type is used to indicate a Mobility Management event.
+-- Actions for the following M-Code values are defined in CAMEL Phase 3:
+--
+-- Location-update-in-same-VLR MM-Code ::= '00000000'B
+-- Location-update-to-other-VLR MM-Code ::= '00000001'B
+-- IMSI-Attach MM-Code ::= '00000010'B
+-- MS-initiated-IMSI-Detach MM-Code ::= '00000011'B
+-- Network-initiated-IMSI-Detach MM-Code ::= '00000100'B
+--
+-- If any other MM-code is received in M-CSI, then that MM-code shall be
+-- ignored.
+
+T-CSI ::= SEQUENCE {
+ t-BcsmCamelTDPDataList T-BcsmCamelTDPDataList,
+ extensionContainer ExtensionContainer OPTIONAL,
+ ...,
+ camelCapabilityHandling [0] CamelCapabilityHandling OPTIONAL,
+ notificationToCSE [1] NULL OPTIONAL,
+ csi-Active [2] NULL OPTIONAL}
+-- notificationToCSE and csi-Active shall not be present when VT-CSI/T-CSI is sent
+-- to VLR/GMSC.
+-- They may only be included in ATSI/ATM ack/NSDC message.
+
+T-BcsmCamelTDPDataList ::= SEQUENCE SIZE (1..maxNumOfCamelTDPData) OF
+ T-BcsmCamelTDPData
+ --- T-BcsmCamelTDPDataList shall not contain more than one instance of
+ --- T-BcsmCamelTDPData containing the same value for t-BcsmTriggerDetectionPoint.
+ --- For CAMEL Phase 2, this means that only one instance of T-BcsmCamelTDPData is
+ --- allowed
+ --- with t-BcsmTriggerDetectionPoint being equal to DP12.
+ --- For CAMEL Phase 3, more TDP�s are allowed.
+
+T-BcsmCamelTDPData ::= SEQUENCE {
+ t-BcsmTriggerDetectionPoint T-BcsmTriggerDetectionPoint,
+ serviceKey ServiceKey,
+ gsmSCF-Address [0] ISDN-AddressString,
+ defaultCallHandling [1] DefaultCallHandling,
+ extensionContainer [2] ExtensionContainer OPTIONAL,
+ ...}
+
+T-BcsmTriggerDetectionPoint ::= ENUMERATED {
+ termAttemptAuthorized (12),
+ ... ,
+ tBusy (13),
+ tNoAnswer (14)}
+ -- exception handling:
+ -- For T-BcsmCamelTDPData sequences containing this parameter with any other
+ -- value than the ones listed above, the receiver shall ignore the whole
+ -- T-BcsmCamelTDPData sequence.
+
+
+-- failure report types
+
+FailureReportArg ::= SEQUENCE {
+ imsi [0] IMSI,
+ ggsn-Number [1] ISDN-AddressString ,
+ ggsn-Address [2] GSN-Address OPTIONAL,
+ extensionContainer [3] ExtensionContainer OPTIONAL,
+ ...}
+
+FailureReportRes ::= SEQUENCE {
+ ggsn-Address [0] GSN-Address OPTIONAL,
+ extensionContainer [1] ExtensionContainer OPTIONAL,
+ ...}
+
+-- gprs notification types
+
+NoteMsPresentForGprsArg ::= SEQUENCE {
+ imsi [0] IMSI,
+ sgsn-Address [1] GSN-Address,
+ ggsn-Address [2] GSN-Address OPTIONAL,
+ extensionContainer [3] ExtensionContainer OPTIONAL,
+ ...}
+
+NoteMsPresentForGprsRes ::= SEQUENCE {
+ extensionContainer [0] ExtensionContainer OPTIONAL,
+ ...}
+
+
+-- fault recovery types
+
+ResetArg ::= SEQUENCE {
+ hlr-Number ISDN-AddressString,
+ hlr-List HLR-List OPTIONAL,
+ ...}
+
+RestoreDataArg ::= SEQUENCE {
+ imsi IMSI,
+ lmsi LMSI OPTIONAL,
+ extensionContainer ExtensionContainer OPTIONAL,
+ ... ,
+ vlr-Capability [6] VLR-Capability OPTIONAL }
+
+RestoreDataRes ::= SEQUENCE {
+ hlr-Number ISDN-AddressString,
+ msNotReachable NULL OPTIONAL,
+ extensionContainer ExtensionContainer OPTIONAL,
+ ...}
+
+-- VBS/VGCS types
+VBSDataList ::= SEQUENCE SIZE (1..maxNumOfVBSGroupIds) OF
+ VoiceBroadcastData
+
+VGCSDataList ::= SEQUENCE SIZE (1..maxNumOfVGCSGroupIds) OF
+ VoiceGroupCallData
+
+maxNumOfVBSGroupIds INTEGER ::= 50
+
+maxNumOfVGCSGroupIds INTEGER ::= 50
+
+VoiceGroupCallData ::= SEQUENCE {
+ groupId GroupId,
+ extensionContainer ExtensionContainer OPTIONAL,
+ ...}
+
+VoiceBroadcastData ::= SEQUENCE {
+ groupid GroupId,
+ broadcastInitEntitlement NULL OPTIONAL,
+ extensionContainer ExtensionContainer OPTIONAL,
+ ...}
+
+GroupId ::= OCTET STRING (SIZE (3))
+ -- Refers to the Group Identification as specified in GSM TS 03.03
+ -- and 03.68/ 03.69
+
+-- provide subscriber info types
+
+ProvideSubscriberInfoArg ::= SEQUENCE {
+ imsi [0] IMSI,
+ lmsi [1] LMSI OPTIONAL,
+ requestedInfo [2] RequestedInfo,
+ extensionContainer [3] ExtensionContainer OPTIONAL,
+ ...}
+
+ProvideSubscriberInfoRes ::= SEQUENCE {
+ subscriberInfo SubscriberInfo,
+ extensionContainer ExtensionContainer OPTIONAL,
+ ...}
+
+SubscriberInfo ::= SEQUENCE {
+ locationInformation [0] LocationInformation OPTIONAL,
+ subscriberState [1] SubscriberState OPTIONAL,
+ extensionContainer [2] ExtensionContainer OPTIONAL,
+ ...}
+
+RequestedInfo ::= SEQUENCE {
+ locationInformation [0] NULL OPTIONAL,
+ subscriberState [1] NULL OPTIONAL,
+ extensionContainer [2] ExtensionContainer OPTIONAL,
+ ...,
+ currentLocation [3] NULL OPTIONAL }
+-- currentLocation shall not be present if locationInformation
+-- is not present in the RequestedInfo parameter
+
+LocationInformation ::= SEQUENCE {
+ ageOfLocationInformation AgeOfLocationInformation OPTIONAL,
+ geographicalInformation [0] GeographicalInformation OPTIONAL,
+ vlr-number [1] ISDN-AddressString OPTIONAL,
+ locationNumber [2] LocationNumber OPTIONAL,
+ cellGlobalIdOrServiceAreaIdOrLAI [3] CellGlobalIdOrServiceAreaIdOrLAI OPTIONAL,
+ extensionContainer [4] ExtensionContainer OPTIONAL,
+ ... ,
+ selectedLSA-Id [5] LSAIdentity OPTIONAL,
+ msc-Number [6] ISDN-AddressString OPTIONAL,
+ geodeticInformation [7] GeodeticInformation OPTIONAL,
+ currentLocationRetrieved [8] NULL OPTIONAL,
+ sai-Present [9] NULL OPTIONAL }
+-- sai-Present indicates that the cellGlobalIdOrServiceAreaIdOrLAI parameter contains
+-- a Service Area Identity.
+-- currentLocationRetrieved shall be present
+-- if the location information were retrieved after a successfull paging.
+
+GeographicalInformation ::= OCTET STRING (SIZE (8))
+-- Refers to geographical Information defined in GSM 03.32.
+-- Only the description of an ellipsoid point with uncertainty circle
+-- as specified in GSM 03.32 is allowed to be used
+-- The internal structure according to GSM 03.32 is as follows:
+-- Type of shape (ellipsoid point with uncertainty circle) 1 octet
+-- Degrees of Latitude 3 octets
+-- Degrees of Longitude 3 octets
+-- Uncertainty code 1 octet
+
+GeodeticInformation ::= OCTET STRING (SIZE (10))
+-- Refers to Calling Geodetic Location defined in Q.763 (1999).
+-- Only the description of an ellipsoid point with uncertainty circle
+-- as specified in Q.763 (1999) is allowed to be used
+-- The internal structure according to Q.763 (1999) is as follows:
+-- Screening and presentation indicators 1 octet
+-- Type of shape (ellipsoid point with uncertainty circle) 1 octet
+-- Degrees of Latitude 3 octets
+-- Degrees of Longitude 3 octets
+-- Uncertainty code 1 octet
+-- Confidence 1 octet
+
+LocationNumber ::= OCTET STRING (SIZE (2..10))
+ -- the internal structure is defined in CCITT Rec Q.763
+
+SubscriberState ::= CHOICE {
+ assumedIdle [0] NULL,
+ camelBusy [1] NULL,
+ netDetNotReachable NotReachableReason,
+ notProvidedFromVLR [2] NULL}
+
+NotReachableReason ::= ENUMERATED {
+ msPurged (0),
+ imsiDetached (1),
+ restrictedArea (2),
+ notRegistered (3)}
+
+-- any time interrogation info types
+
+AnyTimeInterrogationArg ::= SEQUENCE {
+ subscriberIdentity [0] SubscriberIdentity,
+ requestedInfo [1] RequestedInfo,
+ gsmSCF-Address [3] ISDN-AddressString,
+ extensionContainer [2] ExtensionContainer OPTIONAL,
+ ...}
+
+AnyTimeInterrogationRes ::= SEQUENCE {
+ subscriberInfo SubscriberInfo,
+ extensionContainer ExtensionContainer OPTIONAL,
+ ...}
+
+
+-- any time information handling types
+
+AnyTimeSubscriptionInterrogationArg ::= SEQUENCE {
+ subscriberIdentity [0] SubscriberIdentity,
+ requestedSubscriptionInfo [1] RequestedSubscriptionInfo,
+ gsmSCF-Address [2] ISDN-AddressString,
+ extensionContainer [3] ExtensionContainer OPTIONAL,
+ longFTN-Supported [4] NULL OPTIONAL,
+ ...}
+
+AnyTimeSubscriptionInterrogationRes ::= SEQUENCE {
+ callForwardingData [1] CallForwardingData OPTIONAL,
+ callBarringData [2] CallBarringData OPTIONAL,
+ odb-Info [3] ODB-Info OPTIONAL,
+ camel-SubscriptionInfo [4] CAMEL-SubscriptionInfo OPTIONAL,
+ supportedVLR-CAMEL-Phases [5] SupportedCamelPhases OPTIONAL,
+ supportedSGSN-CAMEL-Phases [6] SupportedCamelPhases OPTIONAL,
+ extensionContainer [7] ExtensionContainer OPTIONAL,
+ ...}
+
+RequestedSubscriptionInfo ::= SEQUENCE {
+ requestedSS-Info [1] SS-ForBS-Code OPTIONAL,
+ odb [2] NULL OPTIONAL,
+ requestedCAMEL-SubscriptionInfo [3] RequestedCAMEL-SubscriptionInfo OPTIONAL,
+ supportedVLR-CAMEL-Phases [4] NULL OPTIONAL,
+ supportedSGSN-CAMEL-Phases [5] NULL OPTIONAL,
+ extensionContainer [6] ExtensionContainer OPTIONAL,
+ ...}
+
+RequestedCAMEL-SubscriptionInfo ::= ENUMERATED {
+ o-CSI (0),
+ t-CSI (1),
+ vt-CSI (2),
+ tif-CSI (3),
+ gprs-CSI (4),
+ sms-CSI (5),
+ ss-CSI (6),
+ m-CSI (7),
+ d-csi (8)}
+
+CallForwardingData ::= SEQUENCE {
+ forwardingFeatureList Ext-ForwFeatureList,
+ notificationToCSE NULL OPTIONAL,
+ extensionContainer [0] ExtensionContainer OPTIONAL,
+ ...}
+
+CallBarringData ::= SEQUENCE {
+ callBarringFeatureList Ext-CallBarFeatureList,
+ password Password,
+ wrongPasswordAttemptsCounter WrongPasswordAttemptsCounter,
+ notificationToCSE NULL OPTIONAL,
+ extensionContainer ExtensionContainer OPTIONAL,
+ ...}
+
+WrongPasswordAttemptsCounter ::= INTEGER (0..4)
+
+ODB-Info ::= SEQUENCE {
+ odb-Data ODB-Data,
+ notificationToCSE NULL OPTIONAL,
+ extensionContainer ExtensionContainer OPTIONAL,
+ ...}
+
+CAMEL-SubscriptionInfo ::= SEQUENCE {
+ o-CSI [0] O-CSI OPTIONAL,
+ o-BcsmCamelTDP-CriteriaList [1] O-BcsmCamelTDPCriteriaList OPTIONAL,
+ d-CSI [2] D-CSI OPTIONAL,
+ t-CSI [3] T-CSI OPTIONAL,
+ t-BCSM-CAMEL-TDP-CriteriaList [4] T-BCSM-CAMEL-TDP-CriteriaList OPTIONAL,
+ vt-CSI [5] T-CSI OPTIONAL,
+ vt-BCSM-CAMEL-TDP-CriteriaList [6] T-BCSM-CAMEL-TDP-CriteriaList OPTIONAL,
+ tif-CSI [7] NULL OPTIONAL,
+ tif-CSI-NotificationToCSE [8] NULL OPTIONAL,
+ gprs-CSI [9] GPRS-CSI OPTIONAL,
+ sms-CSI [10] SMS-CSI OPTIONAL,
+ ss-CSI [11] SS-CSI OPTIONAL,
+ m-CSI [12] M-CSI OPTIONAL,
+ extensionContainer [13] ExtensionContainer OPTIONAL,
+ ...}
+
+AnyTimeModificationArg ::= SEQUENCE {
+ subscriberIdentity [0] SubscriberIdentity,
+ gsmSCF-Address [1] ISDN-AddressString,
+ modificationRequestFor-CF-Info [2] ModificationRequestFor-CF-Info OPTIONAL,
+ modificationRequestFor-CB-Info [3] ModificationRequestFor-CB-Info OPTIONAL,
+ modificationRequestFor-CSI [4] ModificationRequestFor-CSI OPTIONAL,
+ extensionContainer [5] ExtensionContainer OPTIONAL,
+ longFTN-Supported [6] NULL OPTIONAL,
+ ...}
+
+AnyTimeModificationRes ::= SEQUENCE {
+ ss-InfoFor-CSE [0] Ext-SS-InfoFor-CSE OPTIONAL,
+ camel-SubscriptionInfo [1] CAMEL-SubscriptionInfo OPTIONAL,
+ extensionContainer [2] ExtensionContainer OPTIONAL,
+ ...}
+
+ModificationRequestFor-CF-Info ::= SEQUENCE {
+ ss-Code [0] SS-Code,
+ basicService [1] Ext-BasicServiceCode OPTIONAL,
+ ss-Status [2] Ext-SS-Status OPTIONAL,
+ forwardedToNumber [3] AddressString OPTIONAL,
+ forwardedToSubaddress [4] ISDN-SubaddressString OPTIONAL,
+ noReplyConditionTime [5] Ext-NoRepCondTime OPTIONAL,
+ modifyNotificationToCSE [6] ModificationInstruction OPTIONAL,
+ extensionContainer [7] ExtensionContainer OPTIONAL,
+ ...}
+
+ModificationRequestFor-CB-Info ::= SEQUENCE {
+ ss-Code [0] SS-Code,
+ basicService [1] Ext-BasicServiceCode OPTIONAL,
+ ss-Status [2] Ext-SS-Status OPTIONAL,
+ password [3] Password OPTIONAL,
+ wrongPasswordAttemptsCounter [4] WrongPasswordAttemptsCounter OPTIONAL,
+ modifyNotificationToCSE [5] ModificationInstruction OPTIONAL,
+ extensionContainer [6] ExtensionContainer OPTIONAL,
+ ...}
+
+ModificationRequestFor-CSI ::= SEQUENCE {
+ requestedCamel-SubscriptionInfo [0] RequestedCAMEL-SubscriptionInfo,
+ modifyNotificationToCSE [1] ModificationInstruction OPTIONAL,
+ modifyCSI-State [2] ModificationInstruction OPTIONAL,
+ extensionContainer [3] ExtensionContainer OPTIONAL,
+ ...}
+
+ModificationInstruction ::= ENUMERATED {
+ deactivate (0),
+ activate (1)}
+
+-- subscriber data modification notification types
+
+NoteSubscriberDataModifiedArg ::= SEQUENCE {
+ imsi IMSI,
+ msisdn ISDN-AddressString,
+ forwardingInfoFor-CSE [0] Ext-ForwardingInfoFor-CSE OPTIONAL,
+ callBarringInfoFor-CSE [1] Ext-CallBarringInfoFor-CSE OPTIONAL,
+ odb-Info [2] ODB-Info OPTIONAL,
+ camel-SubscriptionInfo [3] CAMEL-SubscriptionInfo OPTIONAL,
+ allInformationSent [4] NULL OPTIONAL,
+ extensionContainer ExtensionContainer OPTIONAL,
+ ...}
+
+NoteSubscriberDataModifiedRes ::= SEQUENCE {
+ extensionContainer ExtensionContainer OPTIONAL,
+ ...}
+
+
+-- mobility management event notificatioon info types
+
+NoteMM-EventArg::= SEQUENCE {
+ serviceKey ServiceKey,
+ eventMet [0] MM-Code,
+ imsi [1] IMSI,
+ msisdn [2] ISDN-AddressString,
+ locationInformation [3] LocationInformation OPTIONAL,
+ supportedCAMELPhases [5] SupportedCamelPhases OPTIONAL,
+ extensionContainer [6] ExtensionContainer OPTIONAL,
+ ...}
+
+NoteMM-EventRes ::= SEQUENCE {
+ extensionContainer ExtensionContainer OPTIONAL,
+ ...}
+
+Ext-SS-InfoFor-CSE ::= CHOICE {
+ forwardingInfoFor-CSE [0] Ext-ForwardingInfoFor-CSE,
+ callBarringInfoFor-CSE [1] Ext-CallBarringInfoFor-CSE
+ }
+
+Ext-ForwardingInfoFor-CSE ::= SEQUENCE {
+ ss-Code [0] SS-Code,
+ forwardingFeatureList [1] Ext-ForwFeatureList,
+ notificationToCSE [2] NULL,
+ extensionContainer [3] ExtensionContainer OPTIONAL,
+ ...}
+
+Ext-CallBarringInfoFor-CSE ::= SEQUENCE {
+ ss-Code [0] SS-Code,
+ callBarringFeatureList [1] Ext-CallBarFeatureList,
+ password [2] Password,
+ wrongPasswordAttemptsCounter [3] WrongPasswordAttemptsCounter,
+ notificationToCSE [4] NULL,
+ extensionContainer [5] ExtensionContainer OPTIONAL,
+ ...}
+
+
+END
+
diff --git a/lib/asn1/test/asn1_SUITE_data/Mvrasn-14-4.asn b/lib/asn1/test/asn1_SUITE_data/Mvrasn-14-4.asn
new file mode 100644
index 0000000000..d545a746ec
--- /dev/null
+++ b/lib/asn1/test/asn1_SUITE_data/Mvrasn-14-4.asn
@@ -0,0 +1,66 @@
+-- module(Mvrasn-14-4).
+-- vsn('%CCaseRev: %').
+-- date('%CCaseDate: %').
+-- author('eedkbu').
+-- =============================================================================
+
+-- =============================================================================
+--
+-- Title : "Supplementary Service data types".
+--
+-- ASN.1 module: "MAP-SS-DataTypes".
+--
+-- =============================================================================
+
+
+-- ==============================================================
+-- #1. REVISION LOG
+-- ==============================================================
+-- Rev Date Name What
+-- .... ....... ....... ........................................
+-- PA1 981014 eedkbu First draft, based on GSM 09.02 v. 6.1.0.
+-- ..............................................................
+
+Mvrasn-14-4
+
+DEFINITIONS
+
+IMPLICIT TAGS
+
+::=
+
+BEGIN
+
+EXPORTS
+
+ SS-SubscriptionOption,
+ SS-List,
+ maxNumOfSS
+;
+
+IMPORTS
+
+ SS-Code
+FROM Mvrasn-15-4
+
+;
+
+SS-SubscriptionOption ::= CHOICE {
+ cliRestrictionOption [2] CliRestrictionOption,
+ overrideCategory [1] OverrideCategory}
+
+CliRestrictionOption ::= ENUMERATED {
+ permanent (0),
+ temporaryDefaultRestricted (1),
+ temporaryDefaultAllowed (2)}
+
+OverrideCategory ::= ENUMERATED {
+ overrideEnabled (0),
+ overrideDisabled (1)}
+
+SS-List ::= SEQUENCE SIZE (1..maxNumOfSS) OF
+ SS-Code
+
+maxNumOfSS INTEGER ::= 30
+
+END
diff --git a/lib/asn1/test/asn1_SUITE_data/Mvrasn-14-6.asn b/lib/asn1/test/asn1_SUITE_data/Mvrasn-14-6.asn
new file mode 100644
index 0000000000..3b4a827776
--- /dev/null
+++ b/lib/asn1/test/asn1_SUITE_data/Mvrasn-14-6.asn
@@ -0,0 +1,352 @@
+-- module(Mvrasn-14-6).
+-- vsn('%CCaseRev: %').
+-- date('%CCaseDate: %').
+-- author('etord').
+-- =============================================================================
+
+-- =============================================================================
+--
+-- Title : "Supplementary Service data types".
+--
+-- ASN.1 module: "MAP-SS-DataTypes".
+--
+-- =============================================================================
+
+
+-- ==============================================================
+-- #1. REVISION LOG
+-- ==============================================================
+-- Rev Date Name What
+-- .... ....... ....... ........................................
+-- PA1 010813 etord First draft, based on GSM 29.002 v. 3.8.0.
+-- ..............................................................
+
+Mvrasn-14-6
+
+DEFINITIONS
+
+IMPLICIT TAGS
+
+::=
+
+BEGIN
+
+EXPORTS
+ RegisterSS-Arg,
+ SS-Info,
+ SS-Status,
+ SS-SubscriptionOption,
+ SS-ForBS-Code,
+ InterrogateSS-Res,
+ USSD-Arg,
+ USSD-Res,
+ USSD-DataCodingScheme,
+ USSD-String,
+ Password,
+ GuidanceInfo,
+ SS-List,
+ SS-InfoList,
+ OverrideCategory,
+ CliRestrictionOption,
+ NoReplyConditionTime,
+ ForwardingOptions,
+ maxNumOfSS,
+ SS-Data,
+ SS-InvocationNotificationArg,
+ SS-InvocationNotificationRes,
+ CCBS-Feature,
+ RegisterCC-EntryArg,
+ RegisterCC-EntryRes,
+ EraseCC-EntryArg,
+ EraseCC-EntryRes
+;
+
+IMPORTS
+ AddressString,
+ ISDN-AddressString,
+ ISDN-SubaddressString,
+ FTN-AddressString,
+ IMSI,
+ BasicServiceCode,
+ AlertingPattern,
+ EMLPP-Priority,
+ MaxMC-Bearers,
+ MC-Bearers,
+ ExternalSignalInfo
+FROM Mvrasn-18-6
+
+ ExtensionContainer
+FROM Mvrasn-21-4
+
+ SS-Code
+FROM Mvrasn-15-6
+;
+
+RegisterSS-Arg ::= SEQUENCE {
+ ss-Code SS-Code,
+ basicService BasicServiceCode OPTIONAL,
+ forwardedToNumber [4] AddressString OPTIONAL,
+ forwardedToSubaddress [6] ISDN-SubaddressString OPTIONAL,
+ noReplyConditionTime [5] NoReplyConditionTime OPTIONAL,
+ ...,
+ defaultPriority [7] EMLPP-Priority OPTIONAL,
+ nbrUser [8] MC-Bearers OPTIONAL,
+ longFTN-Supported [9] NULL OPTIONAL }
+
+NoReplyConditionTime ::= INTEGER (5..30)
+
+SS-Info ::= CHOICE {
+ forwardingInfo [0] ForwardingInfo,
+ callBarringInfo [1] CallBarringInfo,
+ ss-Data [3] SS-Data}
+
+ForwardingInfo ::= SEQUENCE {
+ ss-Code SS-Code OPTIONAL,
+ forwardingFeatureList ForwardingFeatureList,
+ ...}
+
+ForwardingFeatureList ::=
+ SEQUENCE SIZE (1..maxNumOfBasicServiceGroups) OF
+ ForwardingFeature
+
+ForwardingFeature ::= SEQUENCE {
+ basicService BasicServiceCode OPTIONAL,
+ ss-Status [4] SS-Status OPTIONAL,
+ forwardedToNumber [5] ISDN-AddressString OPTIONAL,
+ forwardedToSubaddress [8] ISDN-SubaddressString OPTIONAL,
+ forwardingOptions [6] ForwardingOptions OPTIONAL,
+ noReplyConditionTime [7] NoReplyConditionTime OPTIONAL,
+ ...,
+ longForwardedToNumber [9] FTN-AddressString OPTIONAL }
+
+SS-Status ::= OCTET STRING (SIZE (1))
+
+ -- bits 8765: 0000 (unused)
+ -- bits 4321: Used to convey the "P bit","R bit","A bit" and "Q bit",
+ -- representing supplementary service state information
+ -- as defined in TS GSM 03.11
+
+ -- bit 4: "Q bit"
+
+ -- bit 3: "P bit"
+
+ -- bit 2: "R bit"
+
+ -- bit 1: "A bit"
+
+ForwardingOptions ::= OCTET STRING (SIZE (1))
+
+ -- bit 8: notification to forwarding party
+ -- 0 no notification
+ -- 1 notification
+
+ -- bit 7: redirecting presentation
+ -- 0 no presentation
+ -- 1 presentation
+
+ -- bit 6: notification to calling party
+ -- 0 no notification
+ -- 1 notification
+
+ -- bit 5: 0 (unused)
+
+ -- bits 43: forwarding reason
+ -- 00 ms not reachable
+ -- 01 ms busy
+ -- 10 no reply
+ -- 11 unconditional when used in a SRI Result,
+ -- or call deflection when used in a RCH Argument
+ -- bits 21: 00 (unused)
+
+CallBarringInfo ::= SEQUENCE {
+ ss-Code SS-Code OPTIONAL,
+ callBarringFeatureList CallBarringFeatureList,
+ ...}
+
+CallBarringFeatureList ::= SEQUENCE SIZE (1..maxNumOfBasicServiceGroups) OF
+ CallBarringFeature
+
+CallBarringFeature ::= SEQUENCE {
+ basicService BasicServiceCode OPTIONAL,
+ ss-Status [4] SS-Status OPTIONAL,
+ ...}
+
+SS-Data ::= SEQUENCE {
+ ss-Code SS-Code OPTIONAL,
+ ss-Status [4] SS-Status OPTIONAL,
+ ss-SubscriptionOption SS-SubscriptionOption OPTIONAL,
+ basicServiceGroupList BasicServiceGroupList OPTIONAL,
+ ...,
+ defaultPriority EMLPP-Priority OPTIONAL,
+ nbrUser [5] MC-Bearers OPTIONAL
+ }
+
+SS-SubscriptionOption ::= CHOICE {
+ cliRestrictionOption [2] CliRestrictionOption,
+ overrideCategory [1] OverrideCategory}
+
+CliRestrictionOption ::= ENUMERATED {
+ permanent (0),
+ temporaryDefaultRestricted (1),
+ temporaryDefaultAllowed (2)}
+
+OverrideCategory ::= ENUMERATED {
+ overrideEnabled (0),
+ overrideDisabled (1)}
+
+SS-ForBS-Code ::= SEQUENCE {
+ ss-Code SS-Code,
+ basicService BasicServiceCode OPTIONAL,
+ ...,
+ longFTN-Supported [4] NULL OPTIONAL }
+
+GenericServiceInfo ::= SEQUENCE {
+ ss-Status SS-Status,
+ cliRestrictionOption CliRestrictionOption OPTIONAL,
+ ...,
+ maximumEntitledPriority [0] EMLPP-Priority OPTIONAL,
+ defaultPriority [1] EMLPP-Priority OPTIONAL,
+ ccbs-FeatureList [2] CCBS-FeatureList OPTIONAL,
+ nbrSB [3] MaxMC-Bearers OPTIONAL,
+ nbrUser [4] MC-Bearers OPTIONAL,
+ nbrSN [5] MC-Bearers OPTIONAL }
+
+CCBS-FeatureList ::= SEQUENCE SIZE (1..maxNumOfCCBS-Requests) OF
+ CCBS-Feature
+
+maxNumOfCCBS-Requests INTEGER ::= 5
+
+CCBS-Feature ::= SEQUENCE {
+ ccbs-Index [0] CCBS-Index OPTIONAL,
+ b-subscriberNumber [1] ISDN-AddressString OPTIONAL,
+ b-subscriberSubaddress [2] ISDN-SubaddressString OPTIONAL,
+ basicServiceGroup [3] BasicServiceCode OPTIONAL,
+ ...}
+
+CCBS-Index ::= INTEGER (1..maxNumOfCCBS-Requests)
+
+InterrogateSS-Res ::= CHOICE {
+ ss-Status [0] SS-Status,
+ basicServiceGroupList [2] BasicServiceGroupList,
+ forwardingFeatureList [3] ForwardingFeatureList,
+ genericServiceInfo [4] GenericServiceInfo }
+
+USSD-Arg ::= SEQUENCE {
+ ussd-DataCodingScheme USSD-DataCodingScheme,
+ ussd-String USSD-String,
+ ... ,
+ alertingPattern AlertingPattern OPTIONAL,
+ msisdn [0] ISDN-AddressString OPTIONAL }
+
+USSD-Res ::= SEQUENCE {
+ ussd-DataCodingScheme USSD-DataCodingScheme,
+ ussd-String USSD-String,
+ ...}
+
+USSD-DataCodingScheme ::= OCTET STRING (SIZE (1))
+ -- The structure of the USSD-DataCodingScheme is defined by
+ -- the Cell Broadcast Data Coding Scheme as described in
+ -- TS GSM 03.38
+
+USSD-String ::= OCTET STRING (SIZE (1..maxUSSD-StringLength))
+ -- The structure of the contents of the USSD-String is dependent
+ -- on the USSD-DataCodingScheme as described in TS GSM 03.38.
+
+maxUSSD-StringLength INTEGER ::= 160
+
+Password ::= NumericString
+ (FROM ("0"|"1"|"2"|"3"|"4"|"5"|"6"|"7"|"8"|"9"))
+ (SIZE (4))
+
+GuidanceInfo ::= ENUMERATED {
+ enterPW (0),
+ enterNewPW (1),
+ enterNewPW-Again (2)}
+ -- How this information is really delivered to the subscriber
+ -- (display, announcement, ...) is not part of this
+ -- specification.
+
+SS-List ::= SEQUENCE SIZE (1..maxNumOfSS) OF
+ SS-Code
+
+maxNumOfSS INTEGER ::= 30
+
+SS-InfoList ::= SEQUENCE SIZE (1..maxNumOfSS) OF
+ SS-Info
+
+BasicServiceGroupList ::= SEQUENCE SIZE (1..maxNumOfBasicServiceGroups) OF
+ BasicServiceCode
+
+maxNumOfBasicServiceGroups INTEGER ::= 13
+
+SS-InvocationNotificationArg ::= SEQUENCE {
+ imsi [0] IMSI,
+ msisdn [1] ISDN-AddressString,
+ ss-Event [2] SS-Code,
+ -- The following SS-Code values are allowed :
+ -- ect SS-Code ::= '00110001'B
+ -- multiPTY SS-Code ::= '01010001'B
+ -- cd SS-Code ::= '00100100'B
+ -- ccbs SS-Code ::= '01000100'B
+ ss-EventSpecification [3] SS-EventSpecification OPTIONAL,
+ extensionContainer [4] ExtensionContainer OPTIONAL,
+ ...,
+ b-subscriberNumber [5] ISDN-AddressString OPTIONAL,
+ ccbs-RequestState [6] CCBS-RequestState OPTIONAL
+ }
+
+CCBS-RequestState ::= ENUMERATED {
+ request (0),
+ recall (1),
+ active (2),
+ completed (3),
+ suspended (4),
+ frozen (5),
+ deleted (6)
+ }
+
+SS-InvocationNotificationRes ::= SEQUENCE {
+ extensionContainer ExtensionContainer OPTIONAL,
+ ...
+ }
+
+SS-EventSpecification ::= SEQUENCE SIZE (1..maxEventSpecification) OF
+ AddressString
+
+maxEventSpecification INTEGER ::= 2
+
+RegisterCC-EntryArg ::= SEQUENCE {
+ ss-Code [0] SS-Code,
+ ccbs-Data [1] CCBS-Data OPTIONAL,
+ ...}
+
+CCBS-Data ::= SEQUENCE {
+ ccbs-Feature [0] CCBS-Feature,
+ translatedB-Number [1] ISDN-AddressString,
+ serviceIndicator [2] ServiceIndicator OPTIONAL,
+ callInfo [3] ExternalSignalInfo,
+ networkSignalInfo [4] ExternalSignalInfo,
+ ...}
+
+ServiceIndicator ::= BIT STRING {
+ clir-invoked (0),
+ camel-invoked (1)} (SIZE(2..32))
+ -- exception handling:
+ -- bits 2 to 31 shall be ignored if received and not understood
+
+RegisterCC-EntryRes ::= SEQUENCE {
+ ccbs-Feature [0] CCBS-Feature OPTIONAL,
+ ...}
+
+EraseCC-EntryArg ::= SEQUENCE {
+ ss-Code [0] SS-Code,
+ ccbs-Index [1] CCBS-Index OPTIONAL,
+ ...}
+
+EraseCC-EntryRes ::= SEQUENCE {
+ ss-Code [0] SS-Code,
+ ss-Status [1] SS-Status OPTIONAL,
+ ...}
+
+END
+
diff --git a/lib/asn1/test/asn1_SUITE_data/Mvrasn-15-4.asn b/lib/asn1/test/asn1_SUITE_data/Mvrasn-15-4.asn
new file mode 100644
index 0000000000..fed9f38d1a
--- /dev/null
+++ b/lib/asn1/test/asn1_SUITE_data/Mvrasn-15-4.asn
@@ -0,0 +1,42 @@
+-- module(Mvrasn-15-4).
+-- vsn('%CCaseRev: %').
+-- date('%CCaseDate: %').
+-- author('eedkbu').
+-- =============================================================================
+
+-- =============================================================================
+--
+-- Title : "Supplementary service codes".
+--
+-- ASN.1 module: "MAP-SS-Code".
+--
+-- =============================================================================
+
+
+-- ==============================================================
+-- #1. REVISION LOG
+-- ==============================================================
+-- Rev Date Name What
+-- .... ....... ....... ........................................
+-- PA1 981014 eedkbu First draft, based on GSM 09.02 v. 6.1.0.
+-- ..............................................................
+
+Mvrasn-15-4
+
+DEFINITIONS
+
+::=
+
+BEGIN
+
+SS-Code ::= OCTET STRING (SIZE (1))
+ -- This type is used to represent the code identifying a single
+ -- supplementary service, a group of supplementary services, or
+ -- all supplementary services. The services and abbreviations
+ -- used are defined in TS GSM 02.04. The internal structure is
+ -- defined as follows:
+ --
+ -- bits 87654321: group (bits 8765), and specific service
+ -- (bits 4321)
+
+END
diff --git a/lib/asn1/test/asn1_SUITE_data/Mvrasn-15-6.asn b/lib/asn1/test/asn1_SUITE_data/Mvrasn-15-6.asn
new file mode 100644
index 0000000000..b9813e8481
--- /dev/null
+++ b/lib/asn1/test/asn1_SUITE_data/Mvrasn-15-6.asn
@@ -0,0 +1,202 @@
+-- module(Mvrasn-15-6).
+-- vsn('%CCaseRev: %').
+-- date('%CCaseDate: %').
+-- author('etord').
+-- =============================================================================
+
+-- =============================================================================
+--
+-- Title : "Supplementary service codes".
+--
+-- ASN.1 module: "MAP-SS-Code".
+--
+-- =============================================================================
+
+
+-- ==============================================================
+-- #1. REVISION LOG
+-- ==============================================================
+-- Rev Date Name What
+-- .... ....... ....... ........................................
+-- PA1 010813 etord First draft, based on GSM 29.002 v. 3.8.0.
+-- ..............................................................
+
+Mvrasn-15-6
+
+DEFINITIONS
+
+::=
+
+BEGIN
+
+SS-Code ::= OCTET STRING (SIZE (1))
+ -- This type is used to represent the code identifying a single
+ -- supplementary service, a group of supplementary services, or
+ -- all supplementary services. The services and abbreviations
+ -- used are defined in TS GSM 02.04. The internal structure is
+ -- defined as follows:
+ --
+ -- bits 87654321: group (bits 8765), and specific service
+ -- (bits 4321)
+
+allSS SS-Code ::= '00000000'B
+ -- reserved for possible future use
+ -- all SS
+
+allLineIdentificationSS SS-Code ::= '00010000'B
+ -- reserved for possible future use
+ -- all line identification SS
+clip SS-Code ::= '00010001'B
+ -- calling line identification presentation
+clir SS-Code ::= '00010010'B
+ -- calling line identification restriction
+colp SS-Code ::= '00010011'B
+ -- connected line identification presentation
+colr SS-Code ::= '00010100'B
+ -- connected line identification restriction
+mci SS-Code ::= '00010101'B
+ -- reserved for possible future use
+ -- malicious call identification
+
+allNameIdentificationSS SS-Code ::= '00011000'B
+ -- all name identification SS
+cnap SS-Code ::= '00011001'B
+ -- calling name presentation
+
+ -- SS-Codes '00011010'B to '00011111'B are reserved for future
+ -- NameIdentification Supplementary Service use.
+
+allForwardingSS SS-Code ::= '00100000'B
+ -- all forwarding SS
+cfu SS-Code ::= '00100001'B
+ -- call forwarding unconditional
+allCondForwardingSS SS-Code ::= '00101000'B
+ -- all conditional forwarding SS
+cfb SS-Code ::= '00101001'B
+ -- call forwarding on mobile subscriber busy
+cfnry SS-Code ::= '00101010'B
+ -- call forwarding on no reply
+cfnrc SS-Code ::= '00101011'B
+ -- call forwarding on mobile subscriber not reachable
+cd SS-Code ::= '00100100'B
+ -- call deflection
+
+allCallOfferingSS SS-Code ::= '00110000'B
+ -- reserved for possible future use
+ -- all call offering SS includes also all forwarding SS
+ect SS-Code ::= '00110001'B
+ -- explicit call transfer
+mah SS-Code ::= '00110010'B
+ -- reserved for possible future use
+ -- mobile access hunting
+
+allCallCompletionSS SS-Code ::= '01000000'B
+ -- reserved for possible future use
+ -- all Call completion SS
+cw SS-Code ::= '01000001'B
+ -- call waiting
+hold SS-Code ::= '01000010'B
+ -- call hold
+ccbs-A SS-Code ::= '01000011'B
+ -- completion of call to busy subscribers, originating side
+ccbs-B SS-Code ::= '01000100'B
+ -- completion of call to busy subscribers, destination side
+ -- this SS-Code is used only in InsertSubscriberData and DeleteSubscriberData
+mc SS-Code ::= '01000101'B
+ -- multicall
+
+allMultiPartySS SS-Code ::= '01010000'B
+ -- reserved for possible future use
+ -- all multiparty SS
+multiPTY SS-Code ::= '01010001'B
+ -- multiparty
+
+allCommunityOfInterest-SS SS-Code ::= '01100000'B
+ -- reserved for possible future use
+ -- all community of interest SS
+cug SS-Code ::= '01100001'B
+ -- closed user group
+
+allChargingSS SS-Code ::= '01110000'B
+ -- reserved for possible future use
+ -- all charging SS
+aoci SS-Code ::= '01110001'B
+ -- advice of charge information
+aocc SS-Code ::= '01110010'B
+ -- advice of charge charging
+
+allAdditionalInfoTransferSS SS-Code ::= '10000000'B
+ -- reserved for possible future use
+ -- all additional information transfer SS
+uus1 SS-Code ::= '10000001'B
+ -- UUS1 user-to-user signalling
+uus2 SS-Code ::= '10000010'B
+ -- UUS2 user-to-user signalling
+uus3 SS-Code ::= '10000011'B
+ -- UUS3 user-to-user signalling
+
+allBarringSS SS-Code ::= '10010000'B
+ -- all barring SS
+barringOfOutgoingCalls SS-Code ::= '10010001'B
+ -- barring of outgoing calls
+baoc SS-Code ::= '10010010'B
+ -- barring of all outgoing calls
+boic SS-Code ::= '10010011'B
+ -- barring of outgoing international calls
+boicExHC SS-Code ::= '10010100'B
+ -- barring of outgoing international calls except those directed
+ -- to the home PLMN
+barringOfIncomingCalls SS-Code ::= '10011001'B
+ -- barring of incoming calls
+baic SS-Code ::= '10011010'B
+ -- barring of all incoming calls
+bicRoam SS-Code ::= '10011011'B
+ -- barring of incoming calls when roaming outside home PLMN
+ -- Country
+
+allPLMN-specificSS SS-Code ::= '11110000'B
+plmn-specificSS-1 SS-Code ::= '11110001'B
+plmn-specificSS-2 SS-Code ::= '11110010'B
+plmn-specificSS-3 SS-Code ::= '11110011'B
+plmn-specificSS-4 SS-Code ::= '11110100'B
+plmn-specificSS-5 SS-Code ::= '11110101'B
+plmn-specificSS-6 SS-Code ::= '11110110'B
+plmn-specificSS-7 SS-Code ::= '11110111'B
+plmn-specificSS-8 SS-Code ::= '11111000'B
+plmn-specificSS-9 SS-Code ::= '11111001'B
+plmn-specificSS-A SS-Code ::= '11111010'B
+plmn-specificSS-B SS-Code ::= '11111011'B
+plmn-specificSS-C SS-Code ::= '11111100'B
+plmn-specificSS-D SS-Code ::= '11111101'B
+plmn-specificSS-E SS-Code ::= '11111110'B
+plmn-specificSS-F SS-Code ::= '11111111'B
+
+allCallPrioritySS SS-Code ::= '10100000'B
+ -- reserved for possible future use
+ -- all call priority SS
+emlpp SS-Code ::= '10100001'B
+ -- enhanced Multilevel Precedence Pre-emption (EMLPP) service
+
+allLCSPrivacyException SS-Code ::= '10110000'B
+ -- all LCS Privacy Exception Classes
+universal SS-Code ::= '10110001'B
+ -- allow location by any LCS client
+callrelated SS-Code ::= '10110010'B
+ -- allow location by any value added LCS client to which a call
+ -- is established from the target MS
+callunrelated SS-Code ::= '10110011'B
+ -- allow location by designated external value added LCS clients
+plmnoperator SS-Code ::= '10110100'B
+ -- allow location by designated PLMN operator LCS clients
+
+allMOLR-SS SS-Code ::= '11000000'B
+ -- all Mobile Originating Location Request Classes
+basicSelfLocation SS-Code ::= '11000001'B
+ -- allow an MS to request its own location
+autonomousSelfLocation SS-Code ::= '11000010'B
+ -- allow an MS to perform self location without interaction
+ -- with the PLMN for a predetermined period of time
+transferToThirdParty SS-Code ::= '11000011'B
+ -- allow an MS to request transfer of its location to another LCS client
+
+END
diff --git a/lib/asn1/test/asn1_SUITE_data/Mvrasn-17-4.asn b/lib/asn1/test/asn1_SUITE_data/Mvrasn-17-4.asn
new file mode 100644
index 0000000000..29f3a0ff3b
--- /dev/null
+++ b/lib/asn1/test/asn1_SUITE_data/Mvrasn-17-4.asn
@@ -0,0 +1,100 @@
+-- module(Mvrasn-17-4).
+-- vsn('%CCaseRev: %').
+-- date('%CCaseDate: %').
+-- author('eedkbu').
+-- =============================================================================
+
+-- =============================================================================
+--
+-- Title : "Error data types".
+--
+-- ASN.1 module: "MAP-ER-DataTypes".
+--
+-- =============================================================================
+
+
+-- ==============================================================
+-- #1. REVISION LOG
+-- ==============================================================
+-- Rev Date Name What
+-- .... ....... ....... ........................................
+-- PA1 981014 eedkbu First draft, based on GSM 09.02 v. 6.1.0.
+-- ..............................................................
+
+Mvrasn-17-4
+
+DEFINITIONS
+
+IMPLICIT TAGS
+
+::=
+
+BEGIN
+
+EXPORTS
+ RoamingNotAllowedParam,
+ SystemFailureParam,
+ DataMissingParam,
+ UnexpectedDataParam,
+ UnknownSubscriberParam,
+ UnidentifiedSubParam
+
+;
+
+IMPORTS
+
+ ExtensionContainer
+FROM Mvrasn-21-4
+
+ NetworkResource
+FROM Mvrasn-18-4
+
+;
+
+RoamingNotAllowedParam ::= SEQUENCE {
+ roamingNotAllowedCause RoamingNotAllowedCause,
+ extensionContainer ExtensionContainer OPTIONAL,
+ ...}
+
+RoamingNotAllowedCause ::= ENUMERATED {
+ plmnRoamingNotAllowed (0),
+ operatorDeterminedBarring (3)}
+
+SystemFailureParam ::= CHOICE {
+ networkResource NetworkResource,
+ -- networkResource must not be used in version 3
+ extensibleSystemFailureParam ExtensibleSystemFailureParam
+ -- extensibleSystemFailureParam must not be used in version <3
+ }
+
+ExtensibleSystemFailureParam ::= SEQUENCE {
+ networkResource NetworkResource OPTIONAL,
+ extensionContainer ExtensionContainer OPTIONAL,
+ ...}
+
+DataMissingParam ::= SEQUENCE {
+ extensionContainer ExtensionContainer OPTIONAL,
+ ...}
+
+UnexpectedDataParam ::= SEQUENCE {
+ extensionContainer ExtensionContainer OPTIONAL,
+ ...}
+
+UnknownSubscriberParam ::= SEQUENCE {
+ extensionContainer ExtensionContainer OPTIONAL,
+ ...,
+ unknownSubscriberDiagnostic UnknownSubscriberDiagnostic OPTIONAL}
+
+UnknownSubscriberDiagnostic ::= ENUMERATED {
+ imsiUnknown (0),
+ gprsSubscriptionUnknown (1),
+ ...}
+ -- if unknown values are received in
+ -- unknownSubscriberDiagnostic they shall be discarded
+
+UnidentifiedSubParam ::= SEQUENCE {
+ extensionContainer ExtensionContainer OPTIONAL,
+ ...}
+
+END
+
diff --git a/lib/asn1/test/asn1_SUITE_data/Mvrasn-18-4.asn b/lib/asn1/test/asn1_SUITE_data/Mvrasn-18-4.asn
new file mode 100644
index 0000000000..f14ad46c5f
--- /dev/null
+++ b/lib/asn1/test/asn1_SUITE_data/Mvrasn-18-4.asn
@@ -0,0 +1,215 @@
+-- module(Mvrasn-18-4).
+-- vsn('%CCaseRev: %').
+-- date('%CCaseDate: %').
+-- author('eedkbu').
+-- =============================================================================
+
+-- =============================================================================
+--
+-- Title : "Common data types".
+--
+-- ASN.1 module: "MAP-CommonDataTypes".
+--
+-- =============================================================================
+
+-- ==============================================================
+-- #1. REVISION LOG
+-- ==============================================================
+-- Rev Date Name What
+-- .... ....... ....... ........................................
+-- PA1 981014 eedkbu First draft, based on GSM 09.02 v. 6.1.0.
+-- ..............................................................
+
+Mvrasn-18-4
+
+DEFINITIONS
+
+IMPLICIT TAGS
+
+::=
+
+BEGIN
+
+EXPORTS
+
+ -- general data types and values
+ AddressString,
+ ISDN-AddressString,
+ maxISDN-AddressLength,
+ ISDN-SubaddressString,
+-- ExternalSignalInfo,
+ LMSI,
+
+ -- data types for numbering and identification
+ IMSI,
+ NetworkResource,
+ NAEA-PreferredCI,
+
+ -- data types for subscriber management
+ Ext-BasicServiceCode,
+ EMLPP-Info
+;
+
+IMPORTS
+
+ ExtensionContainer
+FROM Mvrasn-21-4
+
+ Ext-BearerServiceCode
+FROM Mvrasn-20-4
+
+ Ext-TeleserviceCode
+FROM Mvrasn-19-4
+
+;
+
+-- general data types
+
+TBCD-STRING ::= OCTET STRING
+ -- This type (Telephony Binary Coded Decimal String) is used to
+ -- represent several digits from 0 through 9, *, #, a, b, c, two
+ -- digits per octet, each digit encoded 0000 to 1001 (0 to 9),
+ -- 1010 (*), 1011 (#), 1100 (a), 1101 (b) or 1110 (c); 1111 used
+ -- as filler when there is an odd number of digits.
+
+ -- bits 8765 of octet n encoding digit 2n
+ -- bits 4321 of octet n encoding digit 2(n-1) +1
+
+AddressString ::= OCTET STRING (SIZE (1..maxAddressLength))
+ -- This type is used to represent a number for addressing
+ -- purposes. It is composed of
+ -- a) one octet for nature of address, and numbering plan
+ -- indicator.
+ -- b) digits of an address encoded as TBCD-String.
+
+ -- a) The first octet includes a one bit extension indicator, a
+ -- 3 bits nature of address indicator and a 4 bits numbering
+ -- plan indicator, encoded as follows:
+
+ -- bit 8: 1 (no extension)
+
+ -- bits 765: nature of address indicator
+ -- 000 unknown
+ -- 001 international number
+ -- 010 national significant number
+ -- 011 network specific number
+ -- 100 subscriber number
+ -- 101 reserved
+ -- 110 abbreviated number
+ -- 111 reserved for extension
+
+ -- bits 4321: numbering plan indicator
+ -- 0000 unknown
+ -- 0001 ISDN/Telephony Numbering Plan (Rec CCITT E.164)
+ -- 0010 spare
+ -- 0011 data numbering plan (CCITT Rec X.121)
+ -- 0100 telex numbering plan (CCITT Rec F.69)
+ -- 0101 spare
+ -- 0110 land mobile numbering plan (CCITT Rec E.212)
+ -- 0111 spare
+ -- 1000 national numbering plan
+ -- 1001 private numbering plan
+ -- 1111 reserved for extension
+
+ -- all other values are reserved.
+
+ -- b) The following octets representing digits of an address
+ -- encoded as a TBCD-STRING.
+
+maxAddressLength INTEGER ::= 20
+
+ISDN-AddressString ::=
+ AddressString (SIZE (1..maxISDN-AddressLength))
+ -- This type is used to represent ISDN numbers.
+
+maxISDN-AddressLength INTEGER ::= 9
+
+ISDN-SubaddressString ::=
+ OCTET STRING (SIZE (1..maxISDN-SubaddressLength))
+ -- This type is used to represent ISDN subaddresses.
+ -- It is composed of
+ -- a) one octet for type of subaddress and odd/even indicator.
+ -- b) 20 octets for subaddress information.
+
+ -- a) The first octet includes a one bit extension indicator, a
+ -- 3 bits type of subaddress and a one bit odd/even indicator,
+ -- encoded as follows:
+
+ -- bit 8: 1 (no extension)
+
+ -- bits 765: type of subaddress
+ -- 000 NSAP (X.213/ISO 8348 AD2)
+ -- 010 User Specified
+ -- All other values are reserved
+
+ -- bit 4: odd/even indicator
+ -- 0 even number of address signals
+ -- 1 odd number of address signals
+ -- The odd/even indicator is used when the type of subaddress
+ -- is "user specified" and the coding is BCD.
+
+ -- bits 321: 000 (unused)
+
+ -- b) Subaddress information.
+ -- The NSAP X.213/ISO8348AD2 address shall be formatted as specified
+ -- by octet 4 which contains the Authority and Format Identifier
+ -- (AFI). The encoding is made according to the "preferred binary
+ -- encoding" as defined in X.213/ISO834AD2. For the definition
+ -- of this type of subaddress, see CCITT Rec I.334.
+
+ -- For User-specific subaddress, this field is encoded according
+ -- to the user specification, subject to a maximum length of 20
+ -- octets. When interworking with X.25 networks BCD coding should
+ -- be applied.
+
+maxISDN-SubaddressLength INTEGER ::= 21
+
+-- data types for numbering and identification
+
+IMSI ::= TBCD-STRING (SIZE (3..8))
+ -- digits of MCC, MNC, MSIN are concatenated in this order.
+
+LMSI ::= OCTET STRING (SIZE (4))
+
+NetworkResource ::= ENUMERATED {
+ plmn (0),
+ hlr (1),
+ vlr (2),
+ pvlr (3),
+ controllingMSC (4),
+ vmsc (5),
+ eir (6),
+ rss (7)}
+
+NAEA-PreferredCI ::= SEQUENCE {
+ naea-PreferredCIC [0] NAEA-CIC,
+ extensionContainer [1] ExtensionContainer OPTIONAL,
+ ...}
+
+NAEA-CIC ::= OCTET STRING (SIZE (3))
+ -- The internal structure is defined by the Carrier Identification
+ -- parameter in ANSI T1.113.3. Carrier codes between "000" and "999" may
+ -- be encoded as 3 digits using "000" to "999" or as 4 digits using
+ -- "0000" to "0999". Carrier codes between "1000" and "9999" are encoded
+ -- using 4 digits.
+
+
+-- data types for subscriber management
+
+Ext-BasicServiceCode ::= CHOICE {
+ ext-BearerService [2] Ext-BearerServiceCode,
+ ext-Teleservice [3] Ext-TeleserviceCode}
+
+EMLPP-Info ::= SEQUENCE {
+ maximumentitledPriority EMLPP-Priority,
+ defaultPriority EMLPP-Priority,
+ extensionContainer ExtensionContainer OPTIONAL,
+ ...}
+
+EMLPP-Priority ::= INTEGER (0..15)
+ -- The mapping from the values A,B,0,1,2,3,4 to the integer-value is
+ -- specified as follows where A is the highest and 4 is the lowest
+ -- priority level
+ -- the integer values 7-15 are spare and shall be mapped to value 4
+
+END
diff --git a/lib/asn1/test/asn1_SUITE_data/Mvrasn-18-6.asn b/lib/asn1/test/asn1_SUITE_data/Mvrasn-18-6.asn
new file mode 100644
index 0000000000..901fc0e057
--- /dev/null
+++ b/lib/asn1/test/asn1_SUITE_data/Mvrasn-18-6.asn
@@ -0,0 +1,515 @@
+-- module(Mvrasn-18-6).
+-- vsn('%CCaseRev: %').
+-- date('%CCaseDate: %').
+-- author('etord').
+-- =============================================================================
+
+-- =============================================================================
+--
+-- Title : "Common data types".
+--
+-- ASN.1 module: "MAP-CommonDataTypes".
+--
+-- =============================================================================
+
+-- ==============================================================
+-- #1. REVISION LOG
+-- ==============================================================
+-- Rev Date Name What
+-- .... ....... ....... ........................................
+-- PA1 010813 etord First draft, based on GSM 29.002 v. 3.8.0.
+-- ..............................................................
+
+Mvrasn-18-6
+
+DEFINITIONS
+
+IMPLICIT TAGS
+
+::=
+
+BEGIN
+
+EXPORTS
+
+ -- general data types and values
+ AddressString,
+ ISDN-AddressString,
+ maxISDN-AddressLength,
+ FTN-AddressString,
+ ISDN-SubaddressString,
+ ExternalSignalInfo,
+ Ext-ExternalSignalInfo,
+ AccessNetworkSignalInfo,
+ SignalInfo,
+ maxSignalInfoLength,
+ AlertingPattern,
+
+ -- data types for numbering and identification
+ IMSI,
+ TMSI,
+ Identity,
+ SubscriberId,
+ IMEI,
+ HLR-List,
+ LMSI,
+ GlobalCellId,
+ NetworkResource,
+ NAEA-PreferredCI,
+ NAEA-CIC,
+ ASCI-CallReference,
+ SubscriberIdentity,
+
+ -- data types for CAMEL
+ CellGlobalIdOrServiceAreaIdOrLAI,
+
+ -- data types for subscriber management
+ BasicServiceCode,
+ Ext-BasicServiceCode,
+ EMLPP-Info,
+ EMLPP-Priority,
+ MC-SS-Info,
+ MaxMC-Bearers,
+ MC-Bearers,
+ Ext-SS-Status,
+
+ -- data types for geographic location
+ AgeOfLocationInformation,
+ LCSClientExternalID,
+ LCSClientInternalID
+;
+
+IMPORTS
+ TeleserviceCode,
+ Ext-TeleserviceCode
+FROM Mvrasn-19-6
+
+ BearerServiceCode,
+ Ext-BearerServiceCode
+FROM Mvrasn-20-6
+
+ SS-Code
+FROM Mvrasn-15-6
+
+ ExtensionContainer
+FROM Mvrasn-21-4
+;
+
+
+-- general data types
+
+TBCD-STRING ::= OCTET STRING
+ -- This type (Telephony Binary Coded Decimal String) is used to
+ -- represent several digits from 0 through 9, *, #, a, b, c, two
+ -- digits per octet, each digit encoded 0000 to 1001 (0 to 9),
+ -- 1010 (*), 1011 (#), 1100 (a), 1101 (b) or 1110 (c); 1111 used
+ -- as filler when there is an odd number of digits.
+
+ -- bits 8765 of octet n encoding digit 2n
+ -- bits 4321 of octet n encoding digit 2(n-1) +1
+
+AddressString ::= OCTET STRING (SIZE (1..maxAddressLength))
+ -- This type is used to represent a number for addressing
+ -- purposes. It is composed of
+ -- a) one octet for nature of address, and numbering plan
+ -- indicator.
+ -- b) digits of an address encoded as TBCD-String.
+
+ -- a) The first octet includes a one bit extension indicator, a
+ -- 3 bits nature of address indicator and a 4 bits numbering
+ -- plan indicator, encoded as follows:
+
+ -- bit 8: 1 (no extension)
+
+ -- bits 765: nature of address indicator
+ -- 000 unknown
+ -- 001 international number
+ -- 010 national significant number
+ -- 011 network specific number
+ -- 100 subscriber number
+ -- 101 reserved
+ -- 110 abbreviated number
+ -- 111 reserved for extension
+
+ -- bits 4321: numbering plan indicator
+ -- 0000 unknown
+ -- 0001 ISDN/Telephony Numbering Plan (Rec CCITT E.164)
+ -- 0010 spare
+ -- 0011 data numbering plan (CCITT Rec X.121)
+ -- 0100 telex numbering plan (CCITT Rec F.69)
+ -- 0101 spare
+ -- 0110 land mobile numbering plan (CCITT Rec E.212)
+ -- 0111 spare
+ -- 1000 national numbering plan
+ -- 1001 private numbering plan
+ -- 1111 reserved for extension
+
+ -- all other values are reserved.
+
+ -- b) The following octets representing digits of an address
+ -- encoded as a TBCD-STRING.
+
+maxAddressLength INTEGER ::= 20
+
+ISDN-AddressString ::=
+ AddressString (SIZE (1..maxISDN-AddressLength))
+ -- This type is used to represent ISDN numbers.
+
+maxISDN-AddressLength INTEGER ::= 9
+
+FTN-AddressString ::=
+ AddressString (SIZE (1..maxFTN-AddressLength))
+ -- This type is used to represent forwarded-to numbers.
+
+maxFTN-AddressLength INTEGER ::= 15
+
+ISDN-SubaddressString ::=
+ OCTET STRING (SIZE (1..maxISDN-SubaddressLength))
+ -- This type is used to represent ISDN subaddresses.
+ -- It is composed of
+ -- a) one octet for type of subaddress and odd/even indicator.
+ -- b) 20 octets for subaddress information.
+
+ -- a) The first octet includes a one bit extension indicator, a
+ -- 3 bits type of subaddress and a one bit odd/even indicator,
+ -- encoded as follows:
+
+ -- bit 8: 1 (no extension)
+
+ -- bits 765: type of subaddress
+ -- 000 NSAP (X.213/ISO 8348 AD2)
+ -- 010 User Specified
+ -- All other values are reserved
+
+ -- bit 4: odd/even indicator
+ -- 0 even number of address signals
+ -- 1 odd number of address signals
+ -- The odd/even indicator is used when the type of subaddress
+ -- is "user specified" and the coding is BCD.
+
+ -- bits 321: 000 (unused)
+
+ -- b) Subaddress information.
+ -- The NSAP X.213/ISO8348AD2 address shall be formatted as specified
+ -- by octet 4 which contains the Authority and Format Identifier
+ -- (AFI). The encoding is made according to the "preferred binary
+ -- encoding" as defined in X.213/ISO834AD2. For the definition
+ -- of this type of subaddress, see CCITT Rec I.334.
+
+ -- For User-specific subaddress, this field is encoded according
+ -- to the user specification, subject to a maximum length of 20
+ -- octets. When interworking with X.25 networks BCD coding should
+ -- be applied.
+
+maxISDN-SubaddressLength INTEGER ::= 21
+
+ExternalSignalInfo ::= SEQUENCE {
+ protocolId ProtocolId,
+ signalInfo SignalInfo,
+ -- Information about the internal structure is given in
+ -- subclause 7.6.9.
+ extensionContainer ExtensionContainer OPTIONAL,
+ -- extensionContainer must not be used in version 2
+ ...}
+
+SignalInfo ::= OCTET STRING (SIZE (1..maxSignalInfoLength))
+
+maxSignalInfoLength INTEGER ::= 200
+ -- This NamedValue represents the theoretical maximum number of octets which is
+ -- available to carry a single instance of the SignalInfo data type,
+ -- without requiring segmentation to cope with the network layer service.
+ -- However, the actual maximum size available for an instance of the data
+ -- type may be lower, especially when other information elements
+ -- have to be included in the same component.
+
+ProtocolId ::= ENUMERATED {
+ gsm-0408 (1),
+ gsm-0806 (2),
+ gsm-BSSMAP (3),
+ -- Value 3 is reserved and must not be used
+ ets-300102-1 (4)}
+
+Ext-ExternalSignalInfo ::= SEQUENCE {
+ ext-ProtocolId Ext-ProtocolId,
+ signalInfo SignalInfo,
+ -- Information about the internal structure is given in
+ -- subclause 7.6.9.10
+ extensionContainer ExtensionContainer OPTIONAL,
+ ...}
+
+Ext-ProtocolId ::= ENUMERATED {
+ ets-300356 (1),
+ ...
+ }
+-- exception handling:
+-- For Ext-ExternalSignalInfo sequences containing this parameter with any
+-- other value than the ones listed the receiver shall ignore the whole
+-- Ext-ExternalSignalInfo sequence.
+
+AccessNetworkSignalInfo ::= SEQUENCE {
+ accessNetworkProtocolId AccessNetworkProtocolId,
+ signalInfo LongSignalInfo,
+ -- Information about the internal structure is given in
+ extensionContainer ExtensionContainer OPTIONAL,
+ ...}
+
+LongSignalInfo ::= OCTET STRING (SIZE (1..maxLongSignalInfoLength))
+
+maxLongSignalInfoLength INTEGER ::= 2560
+ -- This Named Value represents the maximum number of octets which is available
+ -- to carry a single instance of the LongSignalInfo data type using
+ -- White Book SCCP with the maximum number of segments.
+ -- It takes account of the octets used by the lower layers of the protocol, and
+ -- other information elements which may be included in the same component.
+
+
+AccessNetworkProtocolId ::= ENUMERATED {
+ gsm-0806 (1),
+ ts3G-25413 (2),
+ ...}
+ -- exception handling:
+ -- For AccessNetworkSignalInfo sequences containing this parameter with any
+ -- other value than the ones listed the receiver shall ignore the whole
+ -- AccessNetworkSignalInfo sequence.
+
+AlertingPattern ::= OCTET STRING (SIZE (1) )
+ -- This type is used to represent Alerting Pattern
+
+ -- bits 8765 : 0000 (unused)
+
+ -- bits 43 : type of Pattern
+ -- 00 level
+ -- 01 category
+ -- 10 category
+ -- all other values are reserved.
+
+ -- bits 21 : type of alerting
+
+alertingLevel-0 AlertingPattern ::= '00000000'B
+alertingLevel-1 AlertingPattern ::= '00000001'B
+alertingLevel-2 AlertingPattern ::= '00000010'B
+ -- all other values of Alerting level are reserved
+ -- Alerting Levels are defined in GSM 02.07
+
+alertingCategory-1 AlertingPattern ::= '00000100'B
+alertingCategory-2 AlertingPattern ::= '00000101'B
+alertingCategory-3 AlertingPattern ::= '00000110'B
+alertingCategory-4 AlertingPattern ::= '00000111'B
+alertingCategory-5 AlertingPattern ::= '00001000'B
+ -- all other values of Alerting Category are reserved
+ -- Alerting categories are defined in GSM 02.07
+
+
+-- data types for numbering and identification
+
+IMSI ::= TBCD-STRING (SIZE (3..8))
+ -- digits of MCC, MNC, MSIN are concatenated in this order.
+
+Identity ::= CHOICE {
+ imsi IMSI,
+ imsi-WithLMSI IMSI-WithLMSI}
+
+IMSI-WithLMSI ::= SEQUENCE {
+ imsi IMSI,
+ lmsi LMSI,
+ -- a special value 00000000 indicates that the LMSI is not in use
+ ...}
+
+ASCI-CallReference ::= TBCD-STRING (SIZE (1..8))
+ -- digits of VGCS/VBC-area,Group-ID are concatenated in this order.
+
+
+TMSI ::= OCTET STRING (SIZE (1..4))
+
+SubscriberId ::= CHOICE {
+ imsi [0] IMSI,
+ tmsi [1] TMSI}
+
+IMEI ::= TBCD-STRING (SIZE (8))
+ -- Refers to International Mobile Station Equipment Identity
+ -- and Software Version Number (SVN) defined in TS GSM 03.03.
+ -- If the SVN is not present the last octet shall contain the
+ -- digit 0 and a filler.
+ -- If present the SVN shall be included in the last octet.
+
+HLR-Id ::= IMSI
+ -- leading digits of IMSI, i.e. (MCC, MNC, leading digits of
+ -- MSIN) forming HLR Id defined in TS GSM 03.03.
+
+HLR-List ::= SEQUENCE SIZE (1..maxNumOfHLR-Id) OF
+ HLR-Id
+
+maxNumOfHLR-Id INTEGER ::= 50
+
+LMSI ::= OCTET STRING (SIZE (4))
+
+GlobalCellId ::= OCTET STRING (SIZE (5..7))
+ -- Refers to Cell Global Identification defined in TS GSM 03.03.
+ -- The internal structure is defined as follows:
+ -- octet 1 bits 4321 Mobile Country Code 1st digit
+ -- bits 8765 Mobile Country Code 2nd digit
+ -- octet 2 bits 4321 Mobile Country Code 3rd digit
+ -- bits 8765 Mobile Network Code 3rd digit
+ -- or filler (1111) for 2 digit MNCs
+ -- octet 3 bits 4321 Mobile Network Code 1st digit
+ -- bits 8765 Mobile Network Code 2nd digit
+ -- octets 4 and 5 Location Area Code according to TS GSM 04.08
+ -- octets 6 and 7 Cell Identity (CI) according to TS GSM 04.08
+
+NetworkResource ::= ENUMERATED {
+ plmn (0),
+ hlr (1),
+ vlr (2),
+ pvlr (3),
+ controllingMSC (4),
+ vmsc (5),
+ eir (6),
+ rss (7)}
+
+NAEA-PreferredCI ::= SEQUENCE {
+ naea-PreferredCIC [0] NAEA-CIC,
+ extensionContainer [1] ExtensionContainer OPTIONAL,
+ ...}
+
+NAEA-CIC ::= OCTET STRING (SIZE (3))
+ -- The internal structure is defined by the Carrier Identification
+ -- parameter in ANSI T1.113.3. Carrier codes between �000� and �999� may
+ -- be encoded as 3 digits using �000� to �999� or as 4 digits using
+ -- �0000� to �0999�. Carrier codes between �1000� and �9999� are encoded
+ -- using 4 digits.
+
+SubscriberIdentity ::= CHOICE {
+ imsi [0] IMSI,
+ msisdn [1] ISDN-AddressString
+ }
+
+LCSClientExternalID ::= SEQUENCE {
+ externalAddress [0] AddressString OPTIONAL,
+ extensionContainer [1] ExtensionContainer OPTIONAL,
+ ... }
+
+LCSClientInternalID ::= ENUMERATED {
+ broadcastService (0),
+ o-andM-HPLMN (1),
+ o-andM-VPLMN (2),
+ anonymousLocation (3),
+ targetMSsubscribedService (4),
+ ... }
+-- for a CAMEL phase 3 PLMN operator client, the value targetMSsubscribedService shall be used
+
+
+-- data types for CAMEL
+
+CellGlobalIdOrServiceAreaIdOrLAI ::= CHOICE {
+ cellGlobalIdOrServiceAreaIdFixedLength [0] CellGlobalIdOrServiceAreaIdFixedLength,
+ laiFixedLength [1] LAIFixedLength}
+
+CellGlobalIdOrServiceAreaIdFixedLength ::= OCTET STRING (SIZE (7))
+ -- Refers to Cell Global Identification or Service Are Identification
+ -- defined in 3G TS 23.003.
+ -- The internal structure is defined as follows:
+ -- octet 1 bits 4321 Mobile Country Code 1st digit
+ -- bits 8765 Mobile Country Code 2nd digit
+ -- octet 2 bits 4321 Mobile Country Code 3rd digit
+ -- bits 8765 Mobile Network Code 3rd digit
+ -- or filler (1111) for 2 digit MNCs
+ -- octet 3 bits 4321 Mobile Network Code 1st digit
+ -- bits 8765 Mobile Network Code 2nd digit
+ -- octets 4 and 5 Location Area Code according to 3G TS 24.008
+ -- octets 6 and 7 Cell Identity (CI) value or
+ -- Service Area Code (SAC) value
+ -- according to 3G TS 23.003
+
+LAIFixedLength ::= OCTET STRING (SIZE (5))
+ -- Refers to Location Area Identification defined in TS GSM 03.03.
+ -- The internal structure is defined as follows:
+ -- octet 1 bits 4321 Mobile Country Code 1st digit
+ -- bits 8765 Mobile Country Code 2nd digit
+ -- octet 2 bits 4321 Mobile Country Code 3rd digit
+ -- bits 8765 Mobile Network Code 3rd digit
+ -- or filler (1111) for 2 digit MNCs
+ -- octet 3 bits 4321 Mobile Network Code 1st digit
+ -- bits 8765 Mobile Network Code 2nd digit
+ -- octets 4 and 5 Location Area Code according to TS GSM 04.08
+
+
+-- data types for subscriber management
+
+BasicServiceCode ::= CHOICE {
+ bearerService [2] BearerServiceCode,
+ teleservice [3] TeleserviceCode}
+
+Ext-BasicServiceCode ::= CHOICE {
+ ext-BearerService [2] Ext-BearerServiceCode,
+ ext-Teleservice [3] Ext-TeleserviceCode}
+
+EMLPP-Info ::= SEQUENCE {
+ maximumentitledPriority EMLPP-Priority,
+ defaultPriority EMLPP-Priority,
+ extensionContainer ExtensionContainer OPTIONAL,
+ ...}
+
+EMLPP-Priority ::= INTEGER (0..15)
+ -- The mapping from the values A,B,0,1,2,3,4 to the integer-value is
+ -- specified as follows where A is the highest and 4 is the lowest
+ -- priority level
+ -- the integer values 7-15 are spare and shall be mapped to value 4
+
+priorityLevelA EMLPP-Priority ::= 6
+priorityLevelB EMLPP-Priority ::= 5
+priorityLevel0 EMLPP-Priority ::= 0
+priorityLevel1 EMLPP-Priority ::= 1
+priorityLevel2 EMLPP-Priority ::= 2
+priorityLevel3 EMLPP-Priority ::= 3
+priorityLevel4 EMLPP-Priority ::= 4
+
+
+MC-SS-Info ::= SEQUENCE {
+ ss-Code [0] SS-Code,
+ ss-Status [1] Ext-SS-Status,
+ nbrSB [2] MaxMC-Bearers,
+ nbrUser [3] MC-Bearers,
+ extensionContainer [4] ExtensionContainer OPTIONAL,
+ ...}
+
+MaxMC-Bearers ::= INTEGER (2..maxNumOfMC-Bearers)
+
+MC-Bearers ::= INTEGER (1..maxNumOfMC-Bearers)
+
+maxNumOfMC-Bearers INTEGER ::= 7
+
+
+Ext-SS-Status ::= OCTET STRING (SIZE (1..5))
+
+ -- OCTET 1:
+ --
+ -- bits 8765: 0000 (unused)
+ -- bits 4321: Used to convey the "P bit","R bit","A bit" and "Q bit",
+ -- representing supplementary service state information
+ -- as defined in TS GSM 03.11
+
+ -- bit 4: "Q bit"
+
+ -- bit 3: "P bit"
+
+ -- bit 2: "R bit"
+
+ -- bit 1: "A bit"
+
+ -- OCTETS 2-5: reserved for future use. They shall be discarded if
+ -- received and not understood.
+
+
+
+ -- data types for geographic location
+
+AgeOfLocationInformation ::= INTEGER (0..32767)
+-- the value represents the elapsed time in minutes since the last
+-- network contact of the mobile station (i.e. the actuality of the
+-- location information).
+-- value �0� indicates that the MS is currently in contact with the
+-- network
+-- value �32767� indicates that the location information is at least
+-- 32767 minutes old
+
+END
diff --git a/lib/asn1/test/asn1_SUITE_data/Mvrasn-19-4.asn b/lib/asn1/test/asn1_SUITE_data/Mvrasn-19-4.asn
new file mode 100644
index 0000000000..3cb60d7131
--- /dev/null
+++ b/lib/asn1/test/asn1_SUITE_data/Mvrasn-19-4.asn
@@ -0,0 +1,53 @@
+-- module(Mvrasn-19-4).
+-- vsn('%CCaseRev: %').
+-- date('%CCaseDate: %').
+-- author('eedkbu').
+-- =============================================================================
+
+-- =============================================================================
+--
+-- Title : "Teleservice Codes".
+--
+-- ASN.1 module: "MAP-TS-Code".
+--
+-- =============================================================================
+
+-- ==============================================================
+-- #1. REVISION LOG
+-- ==============================================================
+-- Rev Date Name What
+-- .... ....... ....... ........................................
+-- PA1 981014 eedkbu First draft, based on GSM 09.02 v. 6.1.0.
+-- ..............................................................
+
+Mvrasn-19-4
+
+DEFINITIONS
+
+::=
+
+BEGIN
+
+Ext-TeleserviceCode ::= OCTET STRING (SIZE (1..5))
+ -- This type is used to represent the code identifying a single
+ -- teleservice, a group of teleservices, or all teleservices. The
+ -- services are defined in TS GSM 02.03.
+ -- The internal structure is defined as follows:
+
+ -- OCTET 1:
+ -- bits 87654321: group (bits 8765) and specific service
+ -- (bits 4321)
+
+ -- OCTETS 2-5: reserved for future use. If received the
+ -- Ext-TeleserviceCode shall be
+ -- treated according to the exception handling defined for the
+ -- operation that uses this type.
+
+ -- Ext-TeleserviceCode includes all values defined for TeleserviceCode.
+
+
+allShortMessageServices Ext-TeleserviceCode ::= '00100000'B
+shortMessageMT-PP Ext-TeleserviceCode ::= '00100001'B
+shortMessageMO-PP Ext-TeleserviceCode ::= '00100010'B
+
+END
diff --git a/lib/asn1/test/asn1_SUITE_data/Mvrasn-19-6.asn b/lib/asn1/test/asn1_SUITE_data/Mvrasn-19-6.asn
new file mode 100644
index 0000000000..4a7c550deb
--- /dev/null
+++ b/lib/asn1/test/asn1_SUITE_data/Mvrasn-19-6.asn
@@ -0,0 +1,109 @@
+-- module(Mvrasn-19-6).
+-- vsn('%CCaseRev: %').
+-- date('%CCaseDate: %').
+-- author('etord').
+-- =============================================================================
+
+-- =============================================================================
+--
+-- Title : "Teleservice Codes".
+--
+-- ASN.1 module: "MAP-TS-Code".
+--
+-- =============================================================================
+
+-- ==============================================================
+-- #1. REVISION LOG
+-- ==============================================================
+-- Rev Date Name What
+-- .... ....... ....... ........................................
+-- PA1 010813 etord First draft, based on GSM 29.002 v. 3.8.0.
+-- ..............................................................
+
+
+Mvrasn-19-6
+
+DEFINITIONS
+
+::=
+
+BEGIN
+
+TeleserviceCode ::= OCTET STRING (SIZE (1))
+ -- This type is used to represent the code identifying a single
+ -- teleservice, a group of teleservices, or all teleservices. The
+ -- services are defined in TS GSM 02.03.
+ -- The internal structure is defined as follows:
+
+ -- bits 87654321: group (bits 8765) and specific service
+ -- (bits 4321)
+
+Ext-TeleserviceCode ::= OCTET STRING (SIZE (1..5))
+ -- This type is used to represent the code identifying a single
+ -- teleservice, a group of teleservices, or all teleservices. The
+ -- services are defined in TS GSM 02.03.
+ -- The internal structure is defined as follows:
+
+ -- OCTET 1:
+ -- bits 87654321: group (bits 8765) and specific service
+ -- (bits 4321)
+
+ -- OCTETS 2-5: reserved for future use. If received the
+ -- Ext-TeleserviceCode shall be
+ -- treated according to the exception handling defined for the
+ -- operation that uses this type.
+
+ -- Ext-TeleserviceCode includes all values defined for TeleserviceCode.
+
+
+allTeleservices TeleserviceCode ::= '00000000'B
+
+allSpeechTransmissionServices TeleserviceCode ::= '00010000'B
+telephony TeleserviceCode ::= '00010001'B
+emergencyCalls TeleserviceCode ::= '00010010'B
+
+allShortMessageServices TeleserviceCode ::= '00100000'B
+shortMessageMT-PP TeleserviceCode ::= '00100001'B
+shortMessageMO-PP TeleserviceCode ::= '00100010'B
+
+allFacsimileTransmissionServices TeleserviceCode ::= '01100000'B
+facsimileGroup3AndAlterSpeech TeleserviceCode ::= '01100001'B
+automaticFacsimileGroup3 TeleserviceCode ::= '01100010'B
+facsimileGroup4 TeleserviceCode ::= '01100011'B
+
+-- The following non-hierarchical Compound Teleservice Groups
+-- are defined in TS GSM 02.30:
+allDataTeleservices TeleserviceCode ::= '01110000'B
+ -- covers Teleservice Groups 'allFacsimileTransmissionServices'
+ -- and 'allShortMessageServices'
+allTeleservices-ExeptSMS TeleserviceCode ::= '10000000'B
+ -- covers Teleservice Groups 'allSpeechTransmissionServices' and
+ -- 'allFacsimileTransmissionServices'
+--
+-- Compound Teleservice Group Codes are only used in call
+-- independent supplementary service operations, i.e. they
+-- are not used in InsertSubscriberData or in
+-- DeleteSubscriberData messages.
+
+allVoiceGroupCallServices TeleserviceCode ::= '10010000'B
+voiceGroupCall TeleserviceCode ::= '10010001'B
+voiceBroadcastCall TeleserviceCode ::= '10010010'B
+
+allPLMN-specificTS TeleserviceCode ::= '11010000'B
+plmn-specificTS-1 TeleserviceCode ::= '11010001'B
+plmn-specificTS-2 TeleserviceCode ::= '11010010'B
+plmn-specificTS-3 TeleserviceCode ::= '11010011'B
+plmn-specificTS-4 TeleserviceCode ::= '11010100'B
+plmn-specificTS-5 TeleserviceCode ::= '11010101'B
+plmn-specificTS-6 TeleserviceCode ::= '11010110'B
+plmn-specificTS-7 TeleserviceCode ::= '11010111'B
+plmn-specificTS-8 TeleserviceCode ::= '11011000'B
+plmn-specificTS-9 TeleserviceCode ::= '11011001'B
+plmn-specificTS-A TeleserviceCode ::= '11011010'B
+plmn-specificTS-B TeleserviceCode ::= '11011011'B
+plmn-specificTS-C TeleserviceCode ::= '11011100'B
+plmn-specificTS-D TeleserviceCode ::= '11011101'B
+plmn-specificTS-E TeleserviceCode ::= '11011110'B
+plmn-specificTS-F TeleserviceCode ::= '11011111'B
+
+END
diff --git a/lib/asn1/test/asn1_SUITE_data/Mvrasn-20-4.asn b/lib/asn1/test/asn1_SUITE_data/Mvrasn-20-4.asn
new file mode 100644
index 0000000000..8b74c07b5a
--- /dev/null
+++ b/lib/asn1/test/asn1_SUITE_data/Mvrasn-20-4.asn
@@ -0,0 +1,54 @@
+-- module(Mvrasn-20-4).
+-- vsn('%CCaseRev: %').
+-- date('%CCaseDate: %').
+-- author('eedkbu').
+-- =============================================================================
+
+-- =============================================================================
+--
+-- Title : "Bearer Service Codes".
+--
+-- ASN.1 module: "MAP-BS-Code".
+--
+-- =============================================================================
+
+-- ==============================================================
+-- #1. REVISION LOG
+-- ==============================================================
+-- Rev Date Name What
+-- .... ....... ....... ........................................
+-- PA1 981014 eedkbu First draft, based on GSM 09.02 v. 6.1.0.
+-- ..............................................................
+
+Mvrasn-20-4
+
+DEFINITIONS
+
+::=
+
+BEGIN
+
+Ext-BearerServiceCode ::= OCTET STRING (SIZE (1..5))
+ -- This type is used to represent the code identifying a single
+ -- bearer service, a group of bearer services, or all bearer
+ -- services. The services are defined in TS GSM 02.02.
+ -- The internal structure is defined as follows:
+ --
+ -- OCTET 1:
+ -- plmn-specific bearer services:
+ -- bits 87654321: defined by the HPLMN operator
+ --
+ -- rest of bearer services:
+ -- bit 8: 0 (unused)
+ -- bits 7654321: group (bits 7654), and rate, if applicable
+ -- (bits 321)
+
+ -- OCTETS 2-5: reserved for future use. If received the
+ -- Ext-TeleserviceCode shall be
+ -- treated according to the exception handling defined for the
+ -- operation that uses this type.
+
+
+ -- Ext-BearerServiceCode includes all values defined for BearerServiceCode.
+
+END
diff --git a/lib/asn1/test/asn1_SUITE_data/Mvrasn-20-6.asn b/lib/asn1/test/asn1_SUITE_data/Mvrasn-20-6.asn
new file mode 100644
index 0000000000..6b56cb211f
--- /dev/null
+++ b/lib/asn1/test/asn1_SUITE_data/Mvrasn-20-6.asn
@@ -0,0 +1,147 @@
+-- module(Mvrasn-20-6).
+-- vsn('%CCaseRev: %').
+-- date('%CCaseDate: %').
+-- author('etord').
+-- =============================================================================
+
+-- =============================================================================
+--
+-- Title : "Bearer Service Codes".
+--
+-- ASN.1 module: "MAP-BS-Code".
+--
+-- =============================================================================
+
+-- ==============================================================
+-- #1. REVISION LOG
+-- ==============================================================
+-- Rev Date Name What
+-- .... ....... ....... ........................................
+-- PA1 010813 etord First draft, based on GSM 29.002 v. 3.8.0.
+-- ..............................................................
+
+Mvrasn-20-6
+
+DEFINITIONS
+
+::=
+
+BEGIN
+
+BearerServiceCode ::= OCTET STRING (SIZE (1))
+ -- This type is used to represent the code identifying a single
+ -- bearer service, a group of bearer services, or all bearer
+ -- services. The services are defined in TS GSM 02.02.
+ -- The internal structure is defined as follows:
+ --
+ -- plmn-specific bearer services:
+ -- bits 87654321: defined by the HPLMN operator
+
+ -- rest of bearer services:
+ -- bit 8: 0 (unused)
+ -- bits 7654321: group (bits 7654), and rate, if applicable
+ -- (bits 321)
+
+Ext-BearerServiceCode ::= OCTET STRING (SIZE (1..5))
+ -- This type is used to represent the code identifying a single
+ -- bearer service, a group of bearer services, or all bearer
+ -- services. The services are defined in TS GSM 02.02.
+ -- The internal structure is defined as follows:
+ --
+ -- OCTET 1:
+ -- plmn-specific bearer services:
+ -- bits 87654321: defined by the HPLMN operator
+ --
+ -- rest of bearer services:
+ -- bit 8: 0 (unused)
+ -- bits 7654321: group (bits 7654), and rate, if applicable
+ -- (bits 321)
+
+ -- OCTETS 2-5: reserved for future use. If received the
+ -- Ext-TeleserviceCode shall be
+ -- treated according to the exception handling defined for the
+ -- operation that uses this type.
+
+
+ -- Ext-BearerServiceCode includes all values defined for BearerServiceCode.
+
+
+allBearerServices BearerServiceCode ::= '00000000'B
+
+allDataCDA-Services BearerServiceCode ::= '00010000'B
+dataCDA-300bps BearerServiceCode ::= '00010001'B
+dataCDA-1200bps BearerServiceCode ::= '00010010'B
+dataCDA-1200-75bps BearerServiceCode ::= '00010011'B
+dataCDA-2400bps BearerServiceCode ::= '00010100'B
+dataCDA-4800bps BearerServiceCode ::= '00010101'B
+dataCDA-9600bps BearerServiceCode ::= '00010110'B
+general-dataCDA BearerServiceCode ::= '00010111'B
+
+allDataCDS-Services BearerServiceCode ::= '00011000'B
+dataCDS-1200bps BearerServiceCode ::= '00011010'B
+dataCDS-2400bps BearerServiceCode ::= '00011100'B
+dataCDS-4800bps BearerServiceCode ::= '00011101'B
+dataCDS-9600bps BearerServiceCode ::= '00011110'B
+general-dataCDS BearerServiceCode ::= '00011111'B
+
+allPadAccessCA-Services BearerServiceCode ::= '00100000'B
+padAccessCA-300bps BearerServiceCode ::= '00100001'B
+padAccessCA-1200bps BearerServiceCode ::= '00100010'B
+padAccessCA-1200-75bps BearerServiceCode ::= '00100011'B
+padAccessCA-2400bps BearerServiceCode ::= '00100100'B
+padAccessCA-4800bps BearerServiceCode ::= '00100101'B
+padAccessCA-9600bps BearerServiceCode ::= '00100110'B
+general-padAccessCA BearerServiceCode ::= '00100111'B
+
+allDataPDS-Services BearerServiceCode ::= '00101000'B
+dataPDS-2400bps BearerServiceCode ::= '00101100'B
+dataPDS-4800bps BearerServiceCode ::= '00101101'B
+dataPDS-9600bps BearerServiceCode ::= '00101110'B
+general-dataPDS BearerServiceCode ::= '00101111'B
+
+allAlternateSpeech-DataCDA BearerServiceCode ::= '00110000'B
+
+allAlternateSpeech-DataCDS BearerServiceCode ::= '00111000'B
+
+allSpeechFollowedByDataCDA BearerServiceCode ::= '01000000'B
+
+allSpeechFollowedByDataCDS BearerServiceCode ::= '01001000'B
+
+-- The following non-hierarchical Compound Bearer Service
+-- Groups are defined in TS GSM 02.30:
+allDataCircuitAsynchronous BearerServiceCode ::= '01010000'B
+ -- covers "allDataCDA-Services", "allAlternateSpeech-DataCDA" and
+ -- "allSpeechFollowedByDataCDA"
+allAsynchronousServices BearerServiceCode ::= '01100000'B
+ -- covers "allDataCDA-Services", "allAlternateSpeech-DataCDA",
+ -- "allSpeechFollowedByDataCDA" and "allPadAccessCDA-Services"
+allDataCircuitSynchronous BearerServiceCode ::= '01011000'B
+ -- covers "allDataCDS-Services", "allAlternateSpeech-DataCDS" and
+ -- "allSpeechFollowedByDataCDS"
+allSynchronousServices BearerServiceCode ::= '01101000'B
+ -- covers "allDataCDS-Services", "allAlternateSpeech-DataCDS",
+ -- "allSpeechFollowedByDataCDS" and "allDataPDS-Services"
+--
+-- Compound Bearer Service Group Codes are only used in call
+-- independent supplementary service operations, i.e. they
+-- are not used in InsertSubscriberData or in
+-- DeleteSubscriberData messages.
+
+allPLMN-specificBS BearerServiceCode ::= '11010000'B
+plmn-specificBS-1 BearerServiceCode ::= '11010001'B
+plmn-specificBS-2 BearerServiceCode ::= '11010010'B
+plmn-specificBS-3 BearerServiceCode ::= '11010011'B
+plmn-specificBS-4 BearerServiceCode ::= '11010100'B
+plmn-specificBS-5 BearerServiceCode ::= '11010101'B
+plmn-specificBS-6 BearerServiceCode ::= '11010110'B
+plmn-specificBS-7 BearerServiceCode ::= '11010111'B
+plmn-specificBS-8 BearerServiceCode ::= '11011000'B
+plmn-specificBS-9 BearerServiceCode ::= '11011001'B
+plmn-specificBS-A BearerServiceCode ::= '11011010'B
+plmn-specificBS-B BearerServiceCode ::= '11011011'B
+plmn-specificBS-C BearerServiceCode ::= '11011100'B
+plmn-specificBS-D BearerServiceCode ::= '11011101'B
+plmn-specificBS-E BearerServiceCode ::= '11011110'B
+plmn-specificBS-F BearerServiceCode ::= '11011111'B
+
+END
diff --git a/lib/asn1/test/asn1_SUITE_data/Mvrasn-21-4.asn b/lib/asn1/test/asn1_SUITE_data/Mvrasn-21-4.asn
new file mode 100644
index 0000000000..44e77a559d
--- /dev/null
+++ b/lib/asn1/test/asn1_SUITE_data/Mvrasn-21-4.asn
@@ -0,0 +1,66 @@
+-- module(Mvrasn-21-4).
+-- vsn('%CCaseRev: %').
+-- date('%CCaseDate: %').
+-- author('eedkbu').
+-- =============================================================================
+
+-- =============================================================================
+--
+-- Title : "Extension data types".
+--
+-- ASN.1 module: "MAP-ExtensionDataTypes".
+--
+-- =============================================================================
+
+-- ==============================================================
+-- #1. REVISION LOG
+-- ==============================================================
+-- Rev Date Name What
+-- .... ....... ....... ........................................
+-- PA1 981014 eedkbu First draft including changes due to
+-- incompatibilities of the ASN.1-ERLANG
+-- compiler from OTP.
+-- Based on GSM 09.02 v. 6.1.0.
+-- ..............................................................
+
+
+-- =============================================================================
+--
+-- NOTE:
+--
+-- This module was changed compared to the original in the ETSI
+-- standard GSM 09.02 v. 6.1.0. The reason for this change was an
+-- incompatibility of the used ASN.1-ERLANG compiler from OTP.
+--
+-- In GSM 09.02 v. 6.1.0 the data type 'ExtensionContainer' is partly
+-- defined by the ASN.1 type 'CLASS', but the ASN.1-ERLANG compiler is
+-- not able to handle such a 'CLASS' construct correctly. Therefore, and
+-- since the content of a received 'ExtensionContainer' is not of further
+-- interest at this stage of the project, the data type 'ExtensionContainer'
+-- has been changed here.
+--
+-- The new definition of 'ExtensionContainer' is simply an ASN.1 'Extension'
+-- ('...'). This definition allows to receive any kind of information
+-- within the 'ExtensionContainer' without causing a crash of the
+-- decoder when handling the respective message.
+--
+-- =============================================================================
+
+Mvrasn-21-4
+
+DEFINITIONS
+
+IMPLICIT TAGS
+
+::=
+
+BEGIN
+
+EXPORTS
+
+ ExtensionContainer;
+
+ExtensionContainer ::= SEQUENCE {
+ ...}
+
+END
diff --git a/lib/asn1/test/asn1_SUITE_data/Mvrasn-Constants-1.asn b/lib/asn1/test/asn1_SUITE_data/Mvrasn-Constants-1.asn
new file mode 100644
index 0000000000..7eaacdd335
--- /dev/null
+++ b/lib/asn1/test/asn1_SUITE_data/Mvrasn-Constants-1.asn
@@ -0,0 +1,85 @@
+-- module(Mvrasn-Constants-1).
+-- vsn('%CCaseRev: %').
+-- date('%CCaseDate: %').
+-- author('eedkbu').
+-- =============================================================================
+
+-- =============================================================================
+--
+-- Title : "MAP Constants".
+--
+-- ASN.1 module: "MAP-Constants"
+--
+-- =============================================================================
+
+-- =============================================================================
+--
+-- NOTE:
+--
+-- In GSM 09.02 v. 6.1.0 all ASN.1 modules have 'Object Identifier' included
+-- to indicate these modules uniquely. To have a same kind of definite naming
+-- convention, parts of the these 'Object Identifier' have been included in
+-- the file names that store the respective ASN.1 modules.
+--
+-- Therefore, the file name "Mvrasn-20-4.asn" indicates moduls '20' in
+-- version '4' (PHASE 3).
+--
+-- As there is no such 'Object Identifier' in GSM 09.02 v. 3.11.0,
+-- the names for the ASN.1 files of the ASN.1 modules from
+-- this standard version are selected by the author. They are chosen the way
+-- that they are indicating the relation to those modules
+-- from GSM 09.02 v. 3.11.0
+--
+-- =============================================================================
+
+-- ==============================================================
+-- #1. REVISION LOG
+-- ==============================================================
+-- Rev Date Name What
+-- .... ....... ....... ........................................
+-- PA1 981015 eedkbu First draft. Based on GSM 09.02 v. 3.11.0)
+-- ..............................................................
+
+
+Mvrasn-Constants-1
+
+DEFINITIONS
+
+::=
+
+BEGIN
+
+EXPORTS
+
+maxNumberOfTeleServices,
+maxNumberOfBearerServices,
+maxNumberOfSupplServices,
+
+maxNumberOfCUG,
+maxNumberOfForwardingFeatures,
+maxNumberOfCallBarringFeatures,
+maxNumberOfHlrId,
+maxAddressLength,
+maxNumberOfSentParameters
+
+;
+
+-- value assignment
+
+maxNumberOfTeleServices INTEGER ::= 20
+maxNumberOfBearerServices INTEGER ::= 50
+maxNumberOfSupplServices INTEGER ::= 30
+
+maxNumberOfCUG INTEGER ::= 10
+maxNumberOfForwardingFeatures INTEGER ::= 13
+maxNumberOfCallBarringFeatures INTEGER ::= 13
+maxNumberOfHlrId INTEGER ::= 50
+maxAddressLength INTEGER ::= 20
+
+
+maxNumberOfSentParameters INTEGER ::= 10
+-- this named value should correspond to the maximum of
+-- the maxNumberOfCUG and the maximum number of authentication
+-- set which may be returned by a HLR plus 1.
+
+END
diff --git a/lib/asn1/test/asn1_SUITE_data/Mvrasn-DataTypes-1.asn b/lib/asn1/test/asn1_SUITE_data/Mvrasn-DataTypes-1.asn
new file mode 100644
index 0000000000..56b11852ae
--- /dev/null
+++ b/lib/asn1/test/asn1_SUITE_data/Mvrasn-DataTypes-1.asn
@@ -0,0 +1,454 @@
+-- module(Mvrasn-DataTypes-1).
+-- vsn('%CCaseRev: %').
+-- date('%CCaseDate: %').
+-- author('eedkbu').
+-- =============================================================================
+
+-- =============================================================================
+--
+-- Title : "MAP Data Types".
+--
+-- ASN.1 module: "MAP-DataTypes".
+--
+-- =============================================================================
+
+-- =============================================================================
+--
+-- NOTE:
+--
+-- In GSM 09.02 v. 6.1.0 all ASN.1 modules have 'Object Identifier' included
+-- to indicate these modules uniquely. To have a same kind of definite naming
+-- convention, parts of the these 'Object Identifier' have been included in
+-- the file names that store the respective ASN.1 modules.
+--
+-- Therefore, the file name "Mvrasn-20-4.asn" indicates moduls '20' in
+-- version '4' (PHASE 3).
+--
+-- As there is no such 'Object Identifier' in GSM 09.02 v. 3.11.0,
+-- the names for the ASN.1 files of the ASN.1 modules from
+-- this standard version are selected by the author. They are chosen the way
+-- that they are indicating the relation to those modules
+-- from GSM 09.02 v. 3.11.0.
+--
+-- =============================================================================
+
+-- ==============================================================
+-- #1. REVISION LOG
+-- ==============================================================
+-- Rev Date Name What
+-- .... ....... ....... ........................................
+-- PA1 981014 eedkbu First draft, based on GSM 09.02 v. 3.11.0.
+-- ..............................................................
+-- PA2 990114 etord Included Reset operation
+-- ..............................................................
+
+Mvrasn-DataTypes-1
+
+DEFINITIONS
+
+::=
+
+BEGIN
+
+IMPORTS
+-- imports upper boundaries for data types
+
+ maxNumberOfTeleServices,
+ maxNumberOfBearerServices,
+ maxNumberOfSupplServices,
+ maxNumberOfCUG,
+ maxNumberOfForwardingFeatures,
+ maxNumberOfCallBarringFeatures,
+ maxNumberOfHlrId,
+ maxAddressLength,
+ maxNumberOfSentParameters
+FROM Mvrasn-Constants-1
+
+;
+
+
+-- =========================================================
+--
+-- NOTE:
+--
+-- The data type "SendParameterArg" and "ResetArg" are not given in the
+-- original GSM 09.02 v. 3.11.0 standard, but have been
+-- introduced here for two reasons:
+--
+-- 1. In the OPERATION MACRO "SendParameters" is a PARAMETER (=ARGument) and
+-- a RESULT defined. The ASN.1 en/decoder is not able to handle
+-- the MACRO definition. Therefore, the new data type has been
+-- introduced
+--
+-- 2. To align the documentation of the ASN.1 data types in
+-- GSM 09.02 v. 3.11.0 with those of GSM 09.02 v. 6.1.0.
+--
+-- =========================================================
+
+SendParametersArg ::= SEQUENCE {
+ subscriberId SubscriberId,
+ requestParameters RequestParameters
+ }
+
+ResetArg ::= SEQUENCE {
+ networkResource NetworkResource,
+ originatingEntityNumber IsdnAddressString,
+ hlrId HlrList OPTIONAL
+ }
+
+
+-- common data types
+
+SentParameters ::= SEQUENCE
+ SIZE(1..maxNumberOfSentParameters)
+ OF SentParameter
+
+
+TBCD-STRING ::= OCTET STRING
+ -- digits 0 through 9, two digits per octet,
+ -- each digit encoded 0000 to 1001,
+ -- 1111 used as filler when there is an odd number of digit.
+
+
+AddressString ::= OCTET STRING (SIZE (1..maxAddressLength))
+ -- see internal description in section 6.4.1
+
+IsdnAddressString ::= AddressString (SIZE (1..10))
+
+IMSI ::= TBCD-STRING (SIZE (2..8))
+ -- MCC, MNC, MSIN concatenated in this order
+
+TMSI ::= OCTET STRING (SIZE (1..4))
+
+
+SubscriberId ::= CHOICE {
+ imsi [0] IMPLICIT IMSI,
+ tmsi [1] IMPLICIT TMSI}
+
+
+-- data types for numbering and identification
+
+HlrId ::= IMSI
+ -- leading digits of IMSI
+
+HlrList ::= SEQUENCE
+ SIZE(1.. maxNumberOfHlrId)
+ OF HlrId
+
+
+-- data types for subscriber management
+
+--
+Category ::= OCTET STRING (SIZE (1))
+ -- internal structure defined in CCITT Rec Q.763
+
+BearerServiceCode ::= OCTET STRING (SIZE (1))
+ -- Internal structure according to table 6.4/1
+ -- BIT 8 Transparency indicator (if applicable)
+ -- 0 transparent
+ -- 1 non transparent
+
+ -- BIT 7654 Bearer service group
+ -- 0001 3.1 kHz ex PLMN
+ -- 0010 Circuit data asynchronous
+ -- 0011 Circuit data synchronous
+ -- 0100 PAD access c.d.a
+ -- 0101 Packet data synchrounous
+ -- 0110 Alternate speech/c.d.a
+ -- 0111 Alternate speech c.d.s
+ -- 1000 Speech followed by data c.d.a
+ -- 1001 Speech followed by data c.d.s
+ -- 1111 12.6 kb/s unrestricted digital
+
+ -- BIT 321 Rate (when applicable)
+ -- 000 Any
+ -- 001 300-300 b/s
+ -- 010 1200-1200 b/s
+ -- 011 1200-75 b/s
+ -- 100 2400-2400 b/s
+ -- 101 4800-4800 b/s
+ -- 110 9600-9600 b/s
+
+
+ -- Bits 321 = 000 can be used to refer to all
+ -- the bearer services of the corresponding group.
+ -- Value "00000000" can be used to refer to all the defined
+ -- bearer services.
+ -- For the codes referring to a group or all bearer services
+ -- the Transparency Indicator is not applicable and has to be set to "0"
+
+
+BearerServiceList ::= SEQUENCE
+ SIZE(1 .. maxNumberOfBearerServices)
+ OF BearerServiceCode
+
+
+TeleserviceCode ::= OCTET STRING (SIZE (1))
+ -- Internal structure according to table 6.4/2
+ -- Bit 8-5 encode the teleservice group
+
+ -- Bit 4-1 = 0000 can be used to refer to all the
+ -- teleservices of the corresponding group.
+ -- Value "00000000" can be used to refer to all the defined
+ -- teleservices
+
+TeleserviceList ::= SEQUENCE
+ SIZE(1 .. maxNumberOfTeleServices)
+ OF TeleserviceCode
+
+
+BasicServiceCode ::= CHOICE {
+ bearerService [2] IMPLICIT BearerServiceCode,
+ teleservice [3] IMPLICIT TeleserviceCode}
+
+--
+SubscriberStatus ::= ENUMERATED{
+ serviceGranted (0),
+ operatorOGCallBarring (1)}
+
+ -- Data types for supplementary services
+
+SS-Code ::= OCTET STRING (SIZE(1))
+ -- Internal structure according to
+ -- table 6.4/3
+ -- Bit 8-5
+ -- 0001 Number Identification services
+ -- 0010 Forwarding services
+ -- 0011 Call offering services
+ -- 0100 Call completion services
+ -- 0101 Multi-party services
+ -- 0110 Community of interest services
+ -- 0111 Charging services
+ -- 1000 Additional information transfer services
+ -- 1001 Call restriction services
+ -- Bit 4-1 = 0000 can be use to refer to
+ -- a group of supplementary services
+ -- eg, "00100000" can be used to refer to all
+ -- forwarding services
+ -- "00101000" can be used to refer to all
+ -- conditional forwarding services
+ -- "00000000" can be used to refer to all
+ -- supplementary services
+
+SS-Status ::= OCTET STRING (SIZE (1))
+ -- Bit 8-4 Unused
+ -- Bit 3 Provision indicator
+ -- 0 : Not provisioned
+ -- 1 : Provisioned
+ -- Bit 2 Registration indicator (if applicable)
+ -- 0 : Not Registered
+ -- 1 : Registered
+ -- Bit 1 Activation indicator (If applicable)
+ -- 0 : Not Active
+ -- 1 : Active
+
+SS-Information ::= CHOICE{
+ forwardingInfo [0] IMPLICIT ForwardingInfo,
+ callBarringInfo [1] IMPLICIT CallBarringInfo,
+ cug-Information [2] IMPLICIT CUG-Information,
+ ss-Data [3] IMPLICIT SS-Data}
+
+SS-InfoList ::= SEQUENCE
+ SIZE(1 .. maxNumberOfSupplServices)
+ OF SS-Information
+
+
+--
+SS-Data ::= SEQUENCE{
+ ss-Code SS-Code,
+ ss-Status [4] IMPLICIT SS-Status OPTIONAL,
+ ss-SubscriptionOption SS-SubscriptionOption OPTIONAL}
+
+SS-SubscriptionOption ::= CHOICE{
+ perCallBasis [5] IMPLICIT BOOLEAN,
+ notificationToHeldRetrievedParty [6] IMPLICIT BOOLEAN,
+ userToUserServiceIndicator [7] IMPLICIT UserToUserServiceIndicator,
+ maximumConfereesNumber [8] IMPLICIT MaximumConfereesNumber,
+ huntGroupAccessSelectionOrder [9] IMPLICIT HuntGroupAccessSelectionOrder}
+
+
+
+ForwardingOptions ::= OCTET STRING (SIZE(1))
+ -- Bit 8-7 Notification to forwarding party
+ -- 00 No notification
+ -- 01 notification with calling number identity
+ -- 10 notification without calling number identity
+ -- Bit 6-5 Notification to calling party
+ -- 00 No notification
+ -- 01 Notification with forwarded-to number
+ -- 10 Notification without forwarded-to number
+
+
+UserToUserServiceIndicator ::= OCTET STRING (SIZE(1))
+ -- Bit 8 : service 1
+ -- Bit 7 : service 2
+ -- Bit 6 : service 3
+ -- Bit 5-1 : Reserved
+ -- Bit 8 to 6 coded "1" if the service
+ -- is available to the subscriber
+
+
+MaximumConfereesNumber ::= INTEGER (1..10)
+
+
+
+HuntGroupAccessSelectionOrder ::= ENUMERATED{
+ random (0),
+ sequential (1)}
+
+
+NoReplyConditionTime ::= INTEGER (5..30)
+
+
+CUG-Facilities ::= OCTET STRING (SIZE (1))
+ -- Bit 8-3 000000 (Unused)
+ -- Bit 2-1
+ -- 00 CUG only facilities
+ -- 01 CUG with outgoing access
+ -- 10 CUG with incoming access
+ -- 11 CUG with both outgoing and incoming access
+
+CUG-Interlock ::= OCTET STRING (SIZE (4))
+ -- Internal structure defined in Rec CCITT Q.763
+
+CUG-Index ::= OCTET STRING (SIZE (1))
+ -- Internal structure defined in Rec CCITT Q.763
+
+CUG-Options ::= OCTET STRING (SIZE (1))
+ -- BIT 8-4 00000 (Unused)
+ -- BIT 3 preferential CUG indicator
+ -- 0 no preferential
+ -- 1 preferential CUG
+ -- BIT 2 barring of incoming calls within the CUG
+ -- 0 no barring
+ -- 1 barring
+ -- BIT 1 barring of outgoing calls within the CUG
+ -- 0 no barring
+ -- 1 barring
+
+CUG-Feature ::= SEQUENCE {
+ cug-interlock CUG-Interlock,
+ cug-Index CUG-Index,
+ cug-Options CUG-Options,
+ ss-Status SS-Status}
+
+
+CUG-FeatureList ::= SEQUENCE SIZE (
+ 1..maxNumberOfCUG) OF CUG-Feature
+
+
+-- =========================================================
+--
+-- EEDKBU:
+--
+-- The original CUG-Information data type has been:
+--
+-- ------------------
+--
+-- CUG-Information ::= SEQUENCE{
+-- cug-Facilities CUG-Facilities,
+-- CHOICE{
+-- cug-Feature [0] IMPLICIT CUG-Feature,
+-- cug-FeatureList [1] IMPLICIT CUG-FeatureList}}
+ -- the first alternative of the choice should be used
+ -- for the preferred CUG.
+--
+-- ------------------
+--
+-- This is incorrect ASN.1 notation! The CHOICE has also to be a named
+-- type. Therefore, the definition was changed and can be seen below:
+--
+-- =========================================================
+
+
+CUG-Information ::= SEQUENCE{
+ cug-Facilities CUG-Facilities,
+ cug-FeatureChoice CHOICE{
+ cug-Feature [0] IMPLICIT CUG-Feature,
+ cug-FeatureList [1] IMPLICIT CUG-FeatureList}}
+ -- the first alternative of the choice should be used
+ -- for the preferred CUG.
+
+--
+ForwardingInfo ::= SEQUENCE{
+ ss-Code SS-Code OPTIONAL,
+ forwardingFeatureList ForwardingFeatureList}
+
+ForwardingFeature ::= SEQUENCE {
+ basicService BasicServiceCode OPTIONAL,
+ ss-Status [4] IMPLICIT SS-Status,
+ forwardedToNumber [5] IMPLICIT IsdnAddressString OPTIONAL,
+ forwardingOptions [6] IMPLICIT ForwardingOptions OPTIONAL,
+ noReplyConditionTime [7] IMPLICIT NoReplyConditionTime OPTIONAL}
+
+ForwardingFeatureList ::= SEQUENCE SIZE (1.. maxNumberOfForwardingFeatures)
+ OF ForwardingFeature
+
+CallBarringInfo ::= SEQUENCE {
+ ss-Code SS-Code,
+ callBarringFeatureList CallBarringFeatureList}
+
+CallBarringFeature ::= SEQUENCE{
+ basicServiceCode BasicServiceCode OPTIONAL,
+ ss-Status [4] IMPLICIT SS-Status }
+
+CallBarringFeatureList ::= SEQUENCE SIZE (1.. maxNumberOfCallBarringFeatures)
+OF CallBarringFeature
+
+SubscriberData ::= SEQUENCE{
+ msIsdn [1] IMPLICIT IsdnAddressString OPTIONAL,
+ category [2] IMPLICIT Category OPTIONAL,
+ subscriberStatus [3] IMPLICIT SubscriberStatus OPTIONAL,
+ bearerServiceList [4] IMPLICIT BearerServiceList OPTIONAL,
+ teleserviceList [6] IMPLICIT TeleserviceList OPTIONAL,
+ provisonedSupplServices [7] IMPLICIT SS-InfoList OPTIONAL}
+
+-- Data types for security procedures
+
+AuthenticationSet ::= SEQUENCE {
+ rand Rand,
+ sres Sres,
+ kc Kc}
+
+
+Rand ::= OCTET STRING (SIZE (16))
+
+Sres ::= OCTET STRING (SIZE (4))
+
+Kc ::= OCTET STRING (SIZE (8))
+
+Ki ::= OCTET STRING (SIZE (16))
+
+
+-- Data types for fault recovery, call tracing
+
+NetworkResource ::= ENUMERATED {
+ pLMN (0),
+ hLR (1),
+ vLR (2),
+ previous-VLR (3),
+ controlling-MSC (4),
+ vMSC (5),
+ eIR (6),
+ radioSubSystem (7)}
+
+
+-- other data types
+
+RequestParameter ::= ENUMERATED{
+ request-IMSI (0),
+ request-AuthenticationSet (1),
+ request-SubscriberData (2),
+ request-CUG-Information (3),
+ request-Ki (4)}
+
+RequestParameters ::= SEQUENCE SIZE (1..2) OF RequestParameter
+
+SentParameter ::= CHOICE{
+ imsi [0] IMPLICIT IMSI,
+ authenticationSet [1] IMPLICIT AuthenticationSet,
+ subscriberData [2] IMPLICIT SubscriberData,
+ cug-information [3] IMPLICIT CUG-Information,
+ ki [4] IMPLICIT Ki}
+
+END
diff --git a/lib/asn1/test/asn1_SUITE_data/Mvrasn.set.asn b/lib/asn1/test/asn1_SUITE_data/Mvrasn.set.asn
new file mode 100644
index 0000000000..8a61da0160
--- /dev/null
+++ b/lib/asn1/test/asn1_SUITE_data/Mvrasn.set.asn
@@ -0,0 +1,7 @@
+Mvrasn-11-6.asn
+Mvrasn-21-4.asn
+Mvrasn-20-6.asn
+Mvrasn-19-6.asn
+Mvrasn-15-6.asn
+Mvrasn-18-6.asn
+Mvrasn-14-6.asn
diff --git a/lib/asn1/test/asn1_SUITE_data/Mvrasn4.set.asn b/lib/asn1/test/asn1_SUITE_data/Mvrasn4.set.asn
new file mode 100644
index 0000000000..76e8147d12
--- /dev/null
+++ b/lib/asn1/test/asn1_SUITE_data/Mvrasn4.set.asn
@@ -0,0 +1,10 @@
+Mvrasn-Constants-1.asn
+Mvrasn-DataTypes-1.asn
+Mvrasn-21-4.asn
+Mvrasn-20-4.asn
+Mvrasn-19-4.asn
+Mvrasn-18-4.asn
+Mvrasn-17-4.asn
+Mvrasn-15-4.asn
+Mvrasn-14-4.asn
+Mvrasn-11-4.asn
diff --git a/lib/asn1/test/asn1_SUITE_data/Mvrasn6.set.asn b/lib/asn1/test/asn1_SUITE_data/Mvrasn6.set.asn
new file mode 100644
index 0000000000..2a3f54ca9a
--- /dev/null
+++ b/lib/asn1/test/asn1_SUITE_data/Mvrasn6.set.asn
@@ -0,0 +1,7 @@
+Mvrasn-21-4.asn
+Mvrasn-20-6.asn
+Mvrasn-19-6.asn
+Mvrasn-15-6.asn
+Mvrasn-18-6.asn
+Mvrasn-14-6.asn
+Mvrasn-11-6.asn
diff --git a/lib/asn1/test/asn1_SUITE_data/MyMerge.set.asn b/lib/asn1/test/asn1_SUITE_data/MyMerge.set.asn
new file mode 100644
index 0000000000..32c562b43f
--- /dev/null
+++ b/lib/asn1/test/asn1_SUITE_data/MyMerge.set.asn
@@ -0,0 +1,2 @@
+MySO
+IMP
diff --git a/lib/asn1/test/asn1_SUITE_data/NoImport.asn b/lib/asn1/test/asn1_SUITE_data/NoImport.asn
new file mode 100644
index 0000000000..2ab09d91fd
--- /dev/null
+++ b/lib/asn1/test/asn1_SUITE_data/NoImport.asn
@@ -0,0 +1,14 @@
+NoImport DEFINITIONS AUTOMATIC TAGS ::=
+
+BEGIN
+
+IMPORTS
+ Typ
+ FROM IMP;
+
+
+Seq2 ::= SEQUENCE {
+ a Typ,
+ b INTEGER}
+
+END
diff --git a/lib/asn1/test/asn1_SUITE_data/Nortel.asn b/lib/asn1/test/asn1_SUITE_data/Nortel.asn
new file mode 100755
index 0000000000..a27c78a0b5
--- /dev/null
+++ b/lib/asn1/test/asn1_SUITE_data/Nortel.asn
@@ -0,0 +1,592 @@
+Nortel DEFINITIONS IMPLICIT TAGS ::=
+
+BEGIN
+
+-- EXPORTS Nortel;
+
+--IMPORTS
+
+-- IMSI, IMEI
+-- FROM MAP-commonDataTypes { iso (1) identified-organization (4) etsi (0) mobileDomain (0) gsm-Network (1) modules (3) map-CommonDataTypes (18) version2 (2) };
+
+--
+-- Note that the syntax of AE-title to be used is from
+-- CCITT Rec. X.227 / ISO 8650 corrigendum and not "ANY"
+--
+------------------------------------------------------------------------------
+--
+-- CALL AND EVENT RECORDS
+--
+------------------------------------------------------------------------------
+
+CellId ::= OCTET STRING (SIZE(2))
+--
+-- Coded according to TS GSM 04.08
+--
+
+RecordingEntity ::= AddressString
+
+SMSResult ::= Diagnostics
+
+MessageReference ::= OCTET STRING
+
+ManagementExtensions ::= SET OF ManagementExtension
+
+CalledNumber ::= BCDDirectoryNumber
+
+DMI-EXTENSION ::= DMI-TYPE-IDENTIFIER
+
+DMI-TYPE-IDENTIFIER ::= CLASS {&id OBJECT IDENTIFIER UNIQUE,
+ &Value
+} WITH SYNTAX {TYPE &Value
+ ID &id
+}
+
+
+-- ManagementExtension ::= OCTET STRING
+
+ ManagementExtension ::= SEQUENCE {
+ identifier DMI-EXTENSION.&id({ManagementExtensionSet}),
+ significance [1] BOOLEAN DEFAULT FALSE,
+ information
+ [2] DMI-EXTENSION.&Value({ManagementExtensionSet}{@.identifier})
+ }
+
+ManagementExtensionSet DMI-EXTENSION ::= {...}
+
+ServiceKey ::= INTEGER (0..2147483647)
+
+DefaultGPRS-Handling ::= ENUMERATED {
+ continueTransaction (0) ,
+ releaseTransaction (1)
+ }
+-- exception handling:
+-- reception of values in range 2-31 shall be treated as "continueTransaction"
+-- reception of values greater than 31 shall be treated as "releaseTransaction"
+
+AddressString ::= OCTET STRING (SIZE (1..maxAddressLength))
+ -- This type is used to represent a number for addressing
+ -- purposes. It is composed of
+ -- a) one octet for nature of address, and numbering plan
+ -- indicator.
+ -- b) digits of an address encoded as TBCD-String.
+
+ -- a) The first octet includes a one bit extension indicator, a
+ -- 3 bits nature of address indicator and a 4 bits numbering
+ -- plan indicator, encoded as follows:
+
+ -- bit 8: 1 (no extension)
+
+ -- bits 765: nature of address indicator
+ -- 000 unknown
+ -- 001 international number
+ -- 010 national significant number
+ -- 011 network specific number
+ -- 100 subscriber number
+ -- 101 reserved
+ -- 110 abbreviated number
+ -- 111 reserved for extension
+
+ -- bits 4321: numbering plan indicator
+ -- 0000 unknown
+ -- 0001 ISDN/Telephony Numbering Plan (Rec ITU-T E.164)
+ -- 0010 spare
+ -- 0011 data numbering plan (ITU-T Rec X.121)
+ -- 0100 telex numbering plan (ITU-T Rec F.69)
+ -- 0101 spare
+ -- 0110 land mobile numbering plan (ITU-T Rec E.212)
+ -- 0111 spare
+ -- 1000 national numbering plan
+ -- 1001 private numbering plan
+ -- 1111 reserved for extension
+
+ -- all other values are reserved.
+
+ -- b) The following octets representing digits of an address
+ -- encoded as a TBCD-STRING.
+
+maxAddressLength INTEGER ::= 20
+
+ISDN-AddressString ::=
+ AddressString (SIZE (1..maxISDN-AddressLength))
+ -- This type is used to represent ISDN numbers.
+
+maxISDN-AddressLength INTEGER ::= 9
+
+BCDDirectoryNumber ::= OCTET STRING
+ -- This type contains the binary coded decimal representation of
+ -- a directory number e.g. calling/called/connected/translated number.
+ -- The encoding of the octet string is in accordance with the
+ -- the elements "Calling party BCD number", "Called party BCD number"
+ -- and "Connected number" defined in TS GSM 04.08.
+ -- This encoding includes type of number and number plan information
+ -- together with a BCD encoded digit string.
+ -- It may also contain both a presentation and screening indicator
+ -- (octet 3a).
+ -- For the avoidance of doubt, this field does not include
+ -- octets 1 and 2, the element name and length, as this would be
+ -- redundant.
+
+
+
+Diagnostics ::= CHOICE
+{
+ gsm0408Cause [0] INTEGER,
+ -- See TS GSM 04.08
+ gsm0902MapErrorValue [1] INTEGER,
+ -- Note: The value to be stored here corresponds to
+ -- the local values defined in the MAP-Errors and
+ -- MAP-DialogueInformation modules, for full details
+ -- see TS GSM 09.02.
+ ccittQ767Cause [2] INTEGER,
+ -- See CCITT Q.767
+ networkSpecificCause [3] ManagementExtension,
+ -- To be defined by network operator
+ manufacturerSpecificCause [4] ManagementExtension
+ -- To be defined by manufacturer
+}
+
+LocationAreaCode ::= OCTET STRING (SIZE(2))
+ --
+ -- See TS GSM 04.08
+ --
+
+CallEventRecord ::= CHOICE
+{
+-- Record values 0..16 are 3G curcuit switch specifick
+--
+-- sgsnPDPRecord [20] SGSNPDPRecord,
+ ggsnPDPRecord [21] GGSNPDPRecord
+-- sgsnMMRecord [22] SGSNMMRecord,
+-- sgsnSMORecord [23] SGSNSMORecord,
+-- sgsnSMTRecord [24] SGSNSMTRecord
+}
+
+CallDuration ::= INTEGER
+ --
+ -- The call duration in seconds.
+ -- For successful calls this is the chargeable duration.
+ -- For call attempts this is the call holding time.
+
+TimeStamp ::= OCTET STRING (SIZE(9))
+ --
+ -- The contents of this field are a compact form of the UTCTime format
+ -- containing local time plus an offset to universal time. Binary coded
+ -- decimal encoding is employed for the digits to reduce the storage and
+ -- transmission overhead
+ -- e.g. YYMMDDhhmmssShhmm
+ -- where
+ -- YY = Year 00 to 99 BCD encoded
+ -- MM = Month 01 to 12 BCD encoded
+ -- DD = Day 01 to 31 BCD encoded
+ -- hh = hour 00 to 23 BCD encoded
+ -- mm = minute 00 to 59 BCD encoded
+ -- ss = second 00 to 59 BCD encoded
+ -- S = Sign 0 = "+", "-" ASCII encoded
+ -- hh = hour 00 to 23 BCD encoded
+ -- mm = minute 00 to 59 BCD encoded
+ --
+
+MSISDN ::= ISDN-AddressString
+
+IMSI ::= TBCD-STRING (SIZE (3..8))
+ -- digits of MCC, MNC, MSIN are concatenated in this order.
+
+IMEI ::= TBCD-STRING (SIZE (8))
+ -- Refers to International Mobile Station Equipment Identity
+ -- and Software Version Number (SVN) defined in TS 3GPP TS 23.003 [17].
+ -- If the SVN is not present the last octet shall contain the
+ -- digit 0 and a filler.
+ -- If present the SVN shall be included in the last octet.
+
+
+TBCD-STRING ::= OCTET STRING
+ -- This type (Telephony Binary Coded Decimal String) is used to
+ -- represent several digits from 0 through 9, *, #, a, b, c, two
+ -- digits per octet, each digit encoded 0000 to 1001 (0 to 9),
+ -- 1010 (*), 1011 (#), 1100 (a), 1101 (b) or 1110 (c); 1111 used
+ -- as filler when there is an odd number of digits.
+
+ -- bits 8765 of octet n encoding digit 2n
+ -- bits 4321 of octet n encoding digit 2(n-1) +1
+
+GGSNPDPRecord ::= SET
+{
+ recordType [0] CallEventRecordType,
+ networkInitiation [1] NetworkInitiatedPDPContext OPTIONAL,
+ servedIMSI [3] IMSI,
+ ggsnAddress [4] GSNAddress,
+ chargingID [5] ChargingID,
+ sgsnAddress [6] SEQUENCE OF GSNAddress,
+ accessPointNameNI [7] AccessPointNameNI,
+ pdpType [8] PDPType,
+ servedPDPAddress [9] PDPAddress OPTIONAL,
+ dynamicAddressFlag [11] DynamicAddressFlag OPTIONAL,
+ listOfTrafficVolumes [12] SEQUENCE OF ChangeOfCharCondition,
+ recordOpeningTime [13] TimeStamp,
+ duration [14] CallDuration,
+ causeForRecClosing [15] CauseForRecClosing,
+ diagnostics [16] Diagnostics OPTIONAL,
+ recordSequenceNumber [17] INTEGER OPTIONAL,
+ nodeID [18] NodeID OPTIONAL,
+ recordExtensions [19] ManagementExtensions OPTIONAL,
+ localSequenceNumber [20] LocalSequenceNumber OPTIONAL,
+ apnSelectionMode [21] APNSelectionMode OPTIONAL,
+ servedMSISDN [22] MSISDN OPTIONAL,
+ chargingCharacteristics [23] ChargingCharacteristics OPTIONAL
+}
+
+-- sgsnPLMNIdentifier [27] PLMN-Id
+
+
+
+
+------------------------------------------------------------------------------
+--
+-- OBJECT IDENTIFIERS
+--
+------------------------------------------------------------------------------
+
+gsm1205InformationModel OBJECT IDENTIFIER ::=
+ { ccitt (0) identified-organization (4) etsi (0) mobileDomain (0)
+ gsm-Operation-Maintenance (3) gsm-12-05 (5) informationModel (0) }
+
+gsm1205ASN1Module OBJECT IDENTIFIER ::=
+ { gsm1205InformationModel asn1Module(2) }
+
+------------------------------------------------------------------------------
+--
+-- COMMON DATA TYPES
+--
+------------------------------------------------------------------------------
+
+AccessPointNameNI ::= IA5String (SIZE(1..63))
+ --
+ -- Network Identifier part of APN in "dot" representation
+ -- For example, if the complete APN is 'apn1a.apn1b.apn1c.mnc022.mcc111.gprs'
+ -- NI is 'apn1a.apn1b.apn1c' and is presented in this form in the CDR.
+
+AccessPointNameOI ::= IA5String (SIZE(1..37))
+ --
+ -- Operator Identifier part of APN in "dot" representation
+ -- In the 'apn1a.apn1b.apn1c.mnc022.mcc111.gprs' example, the OI portion is 'mnc022.mcc111.gprs'
+ -- and is presented in this form in the CDR.
+
+APNSelectionMode::= ENUMERATED
+{
+ --
+ -- See Information Elements TS 29.060
+ --
+ mSorNetworkProvidedSubscriptionVerified (0),
+ mSProvidedSubscriptionNotVerified (1),
+ networkProvidedSubscriptionNotVerified (2)
+}
+
+CAMELAccessPointNameNI ::= AccessPointNameNI
+
+CAMELAccessPointNameOI ::= AccessPointNameOI
+
+CauseForRecClosing ::= INTEGER
+{
+ --
+ -- in GGSN the value sGSNChange should be used for partial record
+ -- generation due to SGSN Address List Overflow
+ --
+ -- cause codes 0 to 15 are defined in TS 32.005 as 'CauseForTerm' (cause for termination)
+ --
+ normalRelease (0),
+ abnormalRelease (4),
+ cAMELInitCallRelease (5),
+ volumeLimit (16),
+ timeLimit (17),
+ sGSNChange (18),
+ maxChangeCond (19),
+ managementIntervention (20)
+}
+
+ChangeCondition ::= ENUMERATED
+{
+ qoSChange (0),
+ tariffTime (1),
+ recordClosure (2)
+}
+
+ChangeOfCharCondition ::= SEQUENCE
+{
+ --
+ -- used in PDP context record only
+ --
+ qosRequested [1] QoSInformation OPTIONAL,
+ qosNegotiated [2] QoSInformation OPTIONAL,
+ dataVolumeGPRSUplink [3] DataVolumeGPRS,
+ dataVolumeGPRSDownlink [4] DataVolumeGPRS,
+ changeCondition [5] ChangeCondition,
+ changeTime [6] TimeStamp
+}
+
+ChangeLocation ::= SEQUENCE
+{
+ --
+ -- used in SGSNMMRecord only
+ --
+ locationAreaCode [0] LocationAreaCode,
+ routingAreaCode [1] RoutingAreaCode,
+ cellId [2] CellId OPTIONAL,
+ changeTime [3] TimeStamp
+}
+
+ChargingCharacteristics ::= OCTET STRING (SIZE(2))
+ --
+ -- Descriptions for the bits of the flag set:
+ --
+ -- Bit 1: H (Hot billing) := '00000001'B
+ -- Bit 2: F (Flat rate) := '00000010'B
+ -- Bit 3: P (Prepaid service) := '00000100'B
+ -- Bit 4: N (Normal billing) := '00001000'B
+ -- Bit 5: - (Reserved, set to 0) := '00010000'B
+ -- Bit 6: - (Reserved, set to 0) := '00100000'B
+ -- Bit 7: - (Reserved, set to 0) := '01000000'B
+ -- Bit 8: - (Reserved, set to 0) := '10000000'B
+ --
+
+ChargingID ::= INTEGER (0..4294967295)
+ --
+ -- generated in GGSN, part of PDP context, see TS 23.060
+ -- 0..4294967295 is equivalent to 0..2**32-1
+
+DataVolumeGPRS ::= INTEGER
+ --
+ -- The volume of data transferred in octets.
+ --
+
+DynamicAddressFlag ::= BOOLEAN
+
+ETSIAddress ::= AddressString
+ --
+ --first octet for nature of address, and numbering plan indicator (3 for X.121)
+ --other octets TBCD
+ -- See TS 29.002
+ --
+
+FFDAppendIndicator ::= BOOLEAN
+
+FreeFormatData ::= OCTET STRING (SIZE(1..160))
+ --
+ -- Free formated data as sent in the FurnishChargingInformationGPRS
+ -- see TS 29.078
+ --
+
+GSNAddress ::= IPAddress
+
+GSMQoSInformation ::=SEQUENCE
+{
+ reliability [0] QoSReliability,
+ delay [1] QoSDelay,
+ precedence [2] QoSPrecedence,
+ peakThroughput [3] QoSPeakThroughput,
+ meanThroughput [4] QoSMeanThroughput
+}
+
+IPAddress ::= CHOICE
+{
+ iPBinaryAddress IPBinaryAddress,
+ iPTextRepresentedAddress IPTextRepresentedAddress
+}
+
+IPBinaryAddress ::= CHOICE
+{
+ iPBinV4Address [0] OCTET STRING (SIZE(4)),
+ iPBinV6Address [1] OCTET STRING (SIZE(16))
+}
+
+IPTextRepresentedAddress ::= CHOICE
+{ --
+ -- IP address in the familiar "dot" notation
+ --
+ iPTextV4Address [2] IA5String (SIZE(7..15)),
+ iPTextV6Address [3] IA5String (SIZE(15..45))
+}
+
+LocalSequenceNumber ::= INTEGER (0..4294967295)
+ --
+ -- Sequence number of the record in this node
+ -- 0.. 4294967295 is equivalent to 0..2**32-1, unsigned integer in four octets
+
+MSNetworkCapability ::= OCTET STRING (SIZE(1..8))
+
+NetworkInitiatedPDPContext ::= BOOLEAN
+ --
+ -- Set to true if PDP context was initiated from network side
+ --
+
+NodeID ::= IA5String (SIZE(1..20))
+
+PDPAddress ::= CHOICE
+{
+ iPAddress [0] IPAddress,
+ eTSIAddress [1] ETSIAddress
+}
+
+PDPType ::= OCTET STRING (SIZE(2))
+ --
+ --OCTET 1: PDP Type Organization
+ --OCTET 2: PDP Type Number
+ -- See TS 29.060
+ --
+
+PLMN-Id ::= OCTET STRING (SIZE (3))
+ -- This is a 1:1 copy from the Routing Area Identity (RAI) IE specified in TS 29.060
+ -- as follows:
+ -- OCTET 1 of PLMN-Id = OCTET 2 of RAI
+ -- OCTET 2 of PLMN-Id = OCTET 3 of RAI
+ -- OCTET 3 of PLMN-Id = OCTET 4 of RAI
+
+
+QoSDelay ::= ENUMERATED
+{
+ --
+ -- See Quality of service TS 24.008
+ --
+ delayClass1 (1),
+ delayClass2 (2),
+ delayClass3 (3),
+ delayClass4 (4)
+}
+
+QoSInformation ::= CHOICE
+{
+ gsmQosInformation [0] GSMQoSInformation,
+ umtsQosInformation [1] OCTET STRING (SIZE (4..12))
+}
+-- When dealing with a pre R99 QoS profile the GSN may either choose the "GSMQoSInformation" or the
+-- "umtsQoSInformation" encoding. Dealing with R99 QoS profiles the GSN shall apply the
+-- "umtsQoSInformation" encoding. The umtsQosInformation octet string is a 1:1 copy of the contents
+-- (starting with octet 4) of the "Quality of service Profile" information element specified in
+-- 3GPP TS 29.060 [22] for R99 and GSM TS 09.60 for pre R99 cases.
+--}
+
+QoSMeanThroughput ::= ENUMERATED
+{
+ --
+ -- See Quality of service TS 24.008
+ --
+ subscribedMeanThroughput (0), -- MS to network direction
+ -- Network to MS direction needs not to be covered since value (0) = "reserved"
+ mean100octetPh (1),
+ mean200octetPh (2),
+ mean500octetPh (3),
+ mean1000octetPh (4),
+ mean2000octetPh (5),
+ mean5000octetPh (6),
+ mean10000octetPh (7),
+ mean20000octetPh (8),
+ mean50000octetPh (9),
+ mean100000octetPh (10),
+ mean200000octetPh (11),
+ mean500000octetPh (12),
+ mean1000000octetPh (13),
+ mean2000000octetPh (14),
+ mean5000000octetPh (15),
+ mean10000000octetPh (16),
+ mean20000000octetPh (17),
+ mean50000000octetPh (18),
+ reserved (30),
+ bestEffort (31)
+}
+
+QoSPeakThroughput ::= ENUMERATED
+{
+ --
+ -- See Quality of service TS 24.008
+ --
+ unspecified (0),
+ upTo1000octetPs (1),
+ upTo2000octetPs (2),
+ upTo4000octetPs (3),
+ upTo8000octetPs (4),
+ upTo16000octetPs (5),
+ upTo32000octetPs (6),
+ upTo64000octetPs (7),
+ upTo128000octetPs (8),
+ upTo256000octetPs (9)
+}
+
+QoSPrecedence ::= ENUMERATED
+{
+ --
+ -- See Quality of service TS 24.008
+ --
+ unspecified (0),
+ highPriority (1),
+ normalPriority (2),
+ lowPriority (3)
+}
+
+QoSReliability ::= ENUMERATED
+{
+ --
+ -- See Quality of service TS 24.008
+ --
+ unspecifiedReliability (0),
+ acknowledgedGTP (1),
+ unackGTPAcknowLLC (2),
+ unackGTPLLCAcknowRLC (3),
+ unackGTPLLCRLC (4),
+ unacknowUnprotectedData (5)
+}
+
+RoutingAreaCode ::= OCTET STRING (SIZE(1))
+ --
+ -- See TS 24.008
+ --
+
+SCFAddress ::= AddressString
+ --
+ -- See TS 29.002
+ --
+
+NumberOfDPEncountered ::= INTEGER
+
+SGSNChange ::= BOOLEAN
+ --
+ -- present if first record after inter SGSN routing area update
+ -- in new SGSN
+ --
+
+SystemType ::= ENUMERATED
+{
+ unknown (0),
+ iuUTRAN (1),
+ gERAN (2)
+}
+
+CallEventRecordType ::= INTEGER
+{
+ moCallRecord (0),
+ mtCallRecord (1),
+ roamingRecord (2),
+ incGatewayRecord (3),
+ outGatewayRecord (4),
+ transitCallRecord (5),
+ moSMSRecord (6),
+ mtSMSRecord (7),
+ moSMSIWRecord (8),
+ mtSMSGWRecord (9),
+ ssActionRecord (10),
+ hlrIntRecord (11),
+ locUpdateHLRRecord (12),
+ locUpdateVLRRecord (13),
+ commonEquipRecord (14),
+ moTraceRecord (15),
+ mtTraceRecord (16),
+ termCAMELRecord (17),
+ sgsnPDPRecord (18),
+ ggsnPDPRecord (19),
+ sgsnMMRecord (20),
+ sgsnSMORecord (21),
+ sgsnSMTRecord (22)
+
+}
+
+END
+
diff --git a/lib/asn1/test/asn1_SUITE_data/Null.py b/lib/asn1/test/asn1_SUITE_data/Null.py
new file mode 100644
index 0000000000..23e5f38140
--- /dev/null
+++ b/lib/asn1/test/asn1_SUITE_data/Null.py
@@ -0,0 +1,22 @@
+Null DEFINITIONS ::=
+BEGIN
+
+-- F.2.9 Null
+-- Use a null type to indicate the effective absence of a component
+-- of a sequence.
+-- EXAMPLE
+
+PatientIdentifier ::= SEQUENCE {
+ name VisibleString,
+ roomNumber CHOICE {
+ room INTEGER,
+ outPatient NULL -- if an out-patient --
+ }
+}
+
+lastPatient PatientIdentifier ::= {
+ name "Jane Doe",
+ roomNumber outPatient : NULL
+}
+
+END
diff --git a/lib/asn1/test/asn1_SUITE_data/OLD-MEDIA-GATEWAY-CONTROL.asn b/lib/asn1/test/asn1_SUITE_data/OLD-MEDIA-GATEWAY-CONTROL.asn
new file mode 100644
index 0000000000..35a54aaac5
--- /dev/null
+++ b/lib/asn1/test/asn1_SUITE_data/OLD-MEDIA-GATEWAY-CONTROL.asn
@@ -0,0 +1,950 @@
+-- This ASN.1 spec has been extracted from the Megaco/H.248 spec
+-- http://www.ietf.org/internet-drafts/draft-ietf-megaco-merged-01.txt
+--
+-- o Removed stuff named nonStandard
+-- o Major enhancements of the indentation has been performed.
+--
+-- Hakan Mattsson <[email protected]>
+--
+-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
+-- ANNEX A: BINARY ENCODING OF THE PROTOCOL (NORMATIVE)
+-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
+--
+-- This Annex specifies the syntax of messages using the notation
+-- defined in ASN.1 [ITU-T Recommendation X.680 (1997): Information
+-- Technology - Abstract Syntax Notation One (ASN.1) - Specification of
+-- basic notation.]. Messages shall be encoded for transmission by
+-- applying the basic encoding rules specified in [ITU-T Recommendation
+-- X.690(1994) Information Technology - ASN.1 Encoding Rules:
+-- Specification of Basic Encoding Rules (BER)].
+--
+-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
+-- A.1 Coding of wildcards
+-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
+--
+-- The use of wildcards ALL and CHOOSE is allowed in the protocol.
+-- This allows a MGC to partially specify Termination IDs and let the
+-- MG choose from the values that conform to the partial specification.
+-- Termination IDs may encode a hierarchy of names. This hierarchy is
+-- provisioned. For instance, a TerminationID may consist of a trunk
+-- group, a trunk within the group and a circuit. Wildcarding must be
+-- possible at all levels. The following paragraphs explain how this
+-- is achieved.
+--
+-- The ASN.1 description uses octet strings of up to 8 octets in length
+-- for Termination IDs. This means that Termination IDs consist of at
+-- most 64 bits. A fully specified Termination ID may be preceded by a
+-- sequence of wildcarding fields. A wildcarding field is one octet in
+-- length. Bit 7 (the most significant bit) of this octet specifies
+-- what type of wildcarding is invoked: if the bit value equals 1,
+-- then the ALL wildcard is used; if the bit value if 0, then the
+-- CHOOSE wildcard is used. Bit 6 of the wildcarding field specifies
+-- whether the wildcarding pertains to one level in the hierarchical
+-- naming scheme (bit value 0) or to the level of the hierarchy
+-- specified in the wildcarding field plus all lower levels (bit value
+-- 1). Bits 0 through 5 of the wildcarding field specify the bit
+-- position in the Termination ID at which the starts.
+--
+-- We illustrate this scheme with some examples. In these examples,
+-- the most significant bit in a string of bits appears on the left
+-- hand side.
+--
+-- Assume that Termination IDs are three octets long and that each
+-- octet represents a level in a hierarchical naming scheme. A valid
+-- Termination ID is
+-- 00000001 00011110 01010101.
+--
+-- Addressing ALL names with prefix 00000001 00011110 is done as
+-- follows:
+-- wildcarding field: 10000111
+-- Termination ID: 00000001 00011110 xxxxxxxx.
+--
+-- The values of the bits labeled "x" is irrelevant and shall be
+-- ignored by the receiver.
+--
+-- Indicating to the receiver that is must choose a name with 00011110
+-- as the second octet is done as follows:
+-- wildcarding fields: 00010111 followed by 00000111
+-- Termination ID: xxxxxxxx 00011110 xxxxxxxx.
+--
+-- The first wildcard field indicates a CHOOSE wildcard for the level
+-- in the naming hierarchy starting at bit 23, the highest level in our
+-- assumed naming scheme. The second wildcard field indicates a CHOOSE
+-- wildcard for the level in the naming hierarchy starting at bit 7,
+-- the lowest level in our assumed naming scheme.
+--
+-- Finally, a CHOOSE-wildcarded name with the highest level of the name
+-- equal to 00000001 is specified as follows:
+-- wildcard field: 01001111
+-- Termination ID: 0000001 xxxxxxxx xxxxxxxx .
+--
+-- Bit value 1 at bit position 6 of the first octet of the wildcard
+-- field indicates that the wildcarding pertains to the specified level
+-- in the naming hierarchy and all lower levels.
+--
+-- Context IDs may also be wildcarded. In the case of Context IDs,
+-- however, specifying partial names is not allowed. Context ID 0x0
+-- SHALL be used to indicate the NULL Context, Context ID 0xFFFFFFFE
+-- SHALL be used to indicate a CHOOSE wildcard, and Context ID
+-- 0xFFFFFFFF SHALL be used to indicate an ALL wildcard.
+--
+-- TerminationID 0xFFFFFFFFFFFFFFFF SHALL be used to indicate the ROOT
+-- Termination.
+--
+-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
+-- Digit maps and path names
+-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
+--
+-- From a syntactic viewpoint, digit maps are strings with syntactic
+-- restrictions imposed upon them. The syntax of valid digit maps is
+-- specified in ABNF [RFC 2234]. The syntax for digit maps presented
+-- in this section is for illustrative purposes only. The definition of
+-- digitMap in Annex B takes precedence in the case of differences
+-- between the two.
+--
+-- digitMap = (digitString / LWSP "(" LWSP digitStringList LWSP ")"
+-- LWSP)
+-- digitStringList = digitString *( LWSP "/" LWSP digitString )
+-- digitString = 1*(digitStringElement)
+-- digitStringElement = digitPosition [DOT]
+-- digitPosition = digitMapLetter / digitMapRange
+-- digitMapRange = ("x" / LWSP "[" LWSP digitLetter LWSP "]" LWSP)
+-- digitLetter = *((DIGIT "-" DIGIT) /digitMapLetter)
+-- digitMapLetter = DIGIT ;digits 0-9
+-- / %x41-4B / %x61-6B ;a-k and A-K
+-- / "L" / "S" ;Inter-event timers
+-- ;(long, short)
+-- / "Z" ;Long duration event
+-- DOT = %x2E ; "."
+-- LWSP = *(WSP / COMMENT / EOL)
+-- WSP = SP / HTAB
+-- COMMENT = ";" *(SafeChar / RestChar / WSP) EOL
+-- EOL = (CR [LF]) / LF
+-- SP = %x20
+-- HTAB = %x09
+-- CR = %x0D
+-- LF = %x0A
+-- SafeChar = DIGIT / ALPHA / "+" / "-" / "&" / "!" / "_" / "/" /
+-- "'" / "?" / "@" / "^" / "`" / "~" / "*" / "$" / "\" /
+-- "(" / ")" / "%" / "."
+-- RestChar = ";" / "[" / "]" / "{" / "}" / ":" / "," / "#" /
+-- "<" / ">" / "=" / %x22
+-- DIGIT = %x30-39 ; digits 0 through 9
+-- ALPHA = %x41-5A / %x61-7A ; A-Z, a-z
+-- A path name is also a string with syntactic restrictions imposed
+-- upon it. The ABNF production defining it is copied from Annex B.
+--
+-- PathName = NAME *(["/"] ["*"] ["@"] (ALPHA / DIGIT)) ["*"]
+-- NAME = ALPHA *63(ALPHA / DIGIT / "_" )
+--
+-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
+-- A.2 ASN.1 syntax specification
+-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
+--
+-- This section contains the ASN.1 specification of the H.248 protocol
+-- syntax.
+--
+-- NOTE - In case a transport mechanism is used that employs
+-- application level framing, the definition of Transaction below
+-- changes. Refer to the annex defining the transport mechanism for
+-- the definition that applies in that case.
+--
+-- NOTE - The ASN.1 specification below contains a clause defining
+-- TerminationIDList as a sequence of TerminationIDs. The length of
+-- this sequence SHALL be one, except possibly when used in
+-- contextAuditResult.
+-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
+
+OLD-MEDIA-GATEWAY-CONTROL DEFINITIONS AUTOMATIC TAGS::=
+BEGIN
+
+MegacoMessage ::= SEQUENCE
+{
+ authHeader AuthenticationHeader OPTIONAL,
+ mess Message
+}
+
+AuthenticationHeader ::= SEQUENCE
+{
+ secParmIndex SecurityParmIndex,
+ seqNum SequenceNum,
+ ad AuthData
+}
+
+SecurityParmIndex ::= OCTET STRING(SIZE(4))
+
+SequenceNum ::= OCTET STRING(SIZE(4))
+
+AuthData ::= OCTET STRING (SIZE (12..32))
+
+Message ::= SEQUENCE
+{
+ version INTEGER(0..99),
+ -- The version of the protocol defined here is equal to 1.
+ mId MId, -- Name/address of message originator
+ messageBody CHOICE
+ {
+ messageError ErrorDescriptor,
+ transactions SEQUENCE OF Transaction
+ },
+ ...
+}
+
+MId ::= CHOICE
+{
+ ip4Address IP4Address,
+ ip6Address IP6Address,
+ domainName DomainName,
+ deviceName PathName,
+ mtpAddress OCTET STRING(SIZE(2)),
+ -- Addressing structure of mtpAddress:
+ -- 15 0
+ -- | PC | NI |
+ -- 14 bits 2 bits
+ ...
+}
+
+DomainName ::= SEQUENCE
+{
+ name IA5String,
+ -- The name starts with an alphanumeric digit followed by a
+ -- sequence of alphanumeric digits, hyphens and dots. No two
+ -- dots shall occur consecutively.
+ portNumber INTEGER(0..65535) OPTIONAL
+}
+
+IP4Address ::= SEQUENCE
+{
+ address OCTET STRING (SIZE(4)),
+ portNumber INTEGER(0..65535) OPTIONAL
+}
+
+IP6Address ::= SEQUENCE
+{
+ address OCTET STRING (SIZE(16)),
+ portNumber INTEGER(0..65535) OPTIONAL
+}
+
+PathName ::= IA5String(SIZE (1..64))
+-- See section A.3
+
+Transaction ::= CHOICE
+{
+ transactionRequest TransactionRequest,
+ transactionPending TransactionPending,
+ transactionReply TransactionReply,
+ transactionResponseAck TransactionResponseAck,
+ -- use of response acks is dependent on underlying transport
+ ...
+}
+
+TransactionId ::= INTEGER(0..4294967295) -- 32 bit unsigned integer
+
+TransactionRequest ::= SEQUENCE
+{
+ transactionId TransactionId,
+ actions SEQUENCE OF ActionRequest,
+ ...
+}
+
+TransactionPending ::= SEQUENCE
+{
+ transactionId TransactionId,
+ ...
+}
+
+TransactionReply ::= SEQUENCE
+{
+ transactionId TransactionId,
+ immAckRequired NULL OPTIONAL,
+ transactionResult CHOICE
+ {
+ transactionError ErrorDescriptor,
+ actionReplies SEQUENCE OF ActionReply
+ },
+ ...
+}
+
+TransactionResponseAck ::= SEQUENCE
+{
+ firstAck TransactionId,
+ lastAck TransactionId OPTIONAL
+}
+
+ErrorDescriptor ::= SEQUENCE
+{
+ errorCode ErrorCode,
+ errorText ErrorText OPTIONAL
+}
+
+ErrorCode ::= INTEGER(0..65535)
+-- See section 13 for IANA considerations w.r.t. error codes
+
+ErrorText ::= IA5String
+
+ContextID ::= INTEGER(0..4294967295)
+
+-- Context NULL Value: 0
+-- Context CHOOSE Value: 4294967294 (0xFFFFFFFE)
+-- Context ALL Value: 4294967295 (0xFFFFFFFF)
+
+
+ActionRequest ::= SEQUENCE
+{
+ contextId ContextID,
+ contextRequest ContextRequest OPTIONAL,
+ contextAttrAuditReq ContextAttrAuditRequest OPTIONAL,
+ commandRequests SEQUENCE OF CommandRequest
+}
+
+ActionReply ::= SEQUENCE
+{
+ contextId ContextID,
+ errorDescriptor ErrorDescriptor OPTIONAL,
+ contextReply ContextRequest OPTIONAL,
+ commandReply SEQUENCE OF CommandReply
+}
+
+ContextRequest ::= SEQUENCE
+{
+ priority INTEGER(0..15) OPTIONAL,
+ emergency BOOLEAN OPTIONAL,
+ topologyReq SEQUENCE OF TopologyRequest OPTIONAL,
+ ...
+}
+
+ContextAttrAuditRequest ::= SEQUENCE
+{
+ topology NULL OPTIONAL,
+ emergency NULL OPTIONAL,
+ priority NULL OPTIONAL,
+ ...
+}
+
+CommandRequest ::= SEQUENCE
+{
+ command Command,
+ optional NULL OPTIONAL,
+ wildcardReturn NULL OPTIONAL,
+ ...
+}
+
+Command ::= CHOICE
+{
+ addReq AmmRequest,
+ moveReq AmmRequest,
+ modReq AmmRequest,
+ -- Add, Move, Modify requests have the same parameters
+ subtractReq SubtractRequest,
+ auditCapRequest AuditRequest,
+ auditValueRequest AuditRequest,
+ notifyReq NotifyRequest,
+ serviceChangeReq ServiceChangeRequest,
+ ...
+}
+
+CommandReply ::= CHOICE
+{
+ addReply AmmsReply,
+ moveReply AmmsReply,
+ modReply AmmsReply,
+ subtractReply AmmsReply,
+ -- Add, Move, Modify, Subtract replies have the same parameters
+ auditCapReply AuditReply,
+ auditValueReply AuditReply,
+ notifyReply NotifyReply,
+ serviceChangeReply ServiceChangeReply,
+ ...
+}
+
+TopologyRequest ::= SEQUENCE
+{
+ terminationFrom TerminationID,
+ terminationTo TerminationID,
+ topologyDirection ENUMERATED
+ {
+ bothway(0),
+ isolate(1),
+ oneway(2)
+ }
+}
+
+AmmRequest ::= SEQUENCE
+{
+ terminationID TerminationIDList,
+ descriptors SEQUENCE OF AmmDescriptor,
+ -- At most one descriptor of each type (see AmmDescriptor)
+ -- allowed in the sequence.
+ ...
+}
+
+AmmDescriptor ::= CHOICE
+{
+ mediaDescriptor MediaDescriptor,
+ modemDescriptor ModemDescriptor,
+ muxDescriptor MuxDescriptor,
+ eventsDescriptor EventsDescriptor,
+ eventBufferDescriptor EventBufferDescriptor,
+ signalsDescriptor SignalsDescriptor,
+ digitMapDescriptor DigitMapDescriptor,
+ auditDescriptor AuditDescriptor,
+...
+}
+
+AmmsReply ::= SEQUENCE
+{
+ terminationID TerminationIDList,
+ terminationAudit TerminationAudit OPTIONAL,
+ ...
+}
+
+SubtractRequest ::= SEQUENCE
+{
+ terminationID TerminationIDList,
+ auditDescriptor AuditDescriptor OPTIONAL,
+ ...
+}
+
+AuditRequest ::= SEQUENCE
+{
+ terminationID TerminationID,
+ auditDescriptor AuditDescriptor,
+ ...
+}
+
+AuditReply ::= SEQUENCE
+{
+ terminationID TerminationID,
+ auditResult AuditResult,
+ ...
+}
+
+AuditResult ::= CHOICE
+{
+ contextAuditResult TerminationIDList,
+ terminationAuditResult TerminationAudit
+}
+
+
+
+TerminationAudit ::= SEQUENCE OF AuditReturnParameter
+
+AuditReturnParameter ::= CHOICE
+{
+ errorDescriptor ErrorDescriptor,
+ mediaDescriptor MediaDescriptor,
+ modemDescriptor ModemDescriptor,
+ muxDescriptor MuxDescriptor,
+ eventsDescriptor EventsDescriptor,
+ eventBufferDescriptor EventBufferDescriptor,
+ signalsDescriptor SignalsDescriptor,
+ digitMapDescriptor DigitMapDescriptor,
+ observedEventsDescriptor ObservedEventsDescriptor,
+ statisticsDescriptor StatisticsDescriptor,
+ packagesDescriptor PackagesDescriptor,
+ emptyDescriptors AuditDescriptor,
+ ...
+}
+
+AuditDescriptor ::= SEQUENCE
+{
+ auditToken BIT STRING
+ {
+ muxToken(0),
+ modemToken(1),
+ mediaToken(2),
+ eventsToken(3),
+ signalsToken(4),
+ digitMapToken(5),
+ statsToken(6),
+ observedEventsToken(7),
+ packagesToken(8),
+ eventBufferToken(9)
+ } OPTIONAL,
+ ...
+}
+
+NotifyRequest ::= SEQUENCE
+{
+ terminationID TerminationIDList,
+ observedEventsDescriptor ObservedEventsDescriptor,
+ errorDescriptor ErrorDescriptor OPTIONAL,
+ ...
+}
+
+NotifyReply ::= SEQUENCE
+{
+ terminationID TerminationIDList OPTIONAL,
+ errorDescriptor ErrorDescriptor OPTIONAL,
+ ...
+}
+
+ObservedEventsDescriptor ::= SEQUENCE
+{
+ requestId RequestID,
+ observedEventLst SEQUENCE OF ObservedEvent
+}
+
+ObservedEvent ::= SEQUENCE
+{
+ eventName EventName,
+ streamID StreamID OPTIONAL,
+ eventParList SEQUENCE OF EventParameter,
+ timeNotation TimeNotation OPTIONAL,
+ ...
+}
+
+EventName ::= PkgdName
+
+EventParameter ::= SEQUENCE
+{
+ eventParameterName Name,
+ value Value
+}
+
+ServiceChangeRequest ::= SEQUENCE
+{
+ terminationID TerminationIDList,
+ serviceChangeParms ServiceChangeParm,
+ ...
+}
+
+ServiceChangeReply ::= SEQUENCE
+{
+ terminationID TerminationIDList,
+ serviceChangeResult ServiceChangeResult,
+ ...
+}
+
+-- For ServiceChangeResult, no parameters are mandatory. Hence the
+-- distinction between ServiceChangeParm and ServiceChangeResParm.
+
+ServiceChangeResult ::= CHOICE
+{
+ errorDescriptor ErrorDescriptor,
+ serviceChangeResParms ServiceChangeResParm
+}
+
+WildcardField ::= OCTET STRING(SIZE(1))
+
+TerminationID ::= SEQUENCE
+{
+ wildcard SEQUENCE OF WildcardField,
+ id OCTET STRING(SIZE(1..8)),
+ ...
+}
+-- See Section A.1 for explanation of wildcarding mechanism.
+-- Termination ID 0xFFFFFFFFFFFFFFFF indicates the ROOT Termination.
+
+TerminationIDList ::= SEQUENCE OF TerminationID
+
+MediaDescriptor ::= SEQUENCE
+{
+
+ termStateDescr TerminationStateDescriptor OPTIONAL,
+ streams CHOICE
+ {
+ oneStream StreamParms,
+ multiStream SEQUENCE OF StreamDescriptor
+ },
+ ...
+}
+
+StreamDescriptor ::= SEQUENCE
+{
+ streamID StreamID,
+ streamParms StreamParms
+}
+
+StreamParms ::= SEQUENCE
+{
+ localControlDescriptor LocalControlDescriptor OPTIONAL,
+ localDescriptor LocalRemoteDescriptor OPTIONAL,
+ remoteDescriptor LocalRemoteDescriptor OPTIONAL,
+ ...
+}
+
+LocalControlDescriptor ::= SEQUENCE
+{
+ streamMode StreamMode OPTIONAL,
+ reserveValue BOOLEAN,
+ reserveGroup BOOLEAN,
+ propertyParms SEQUENCE OF PropertyParm,
+ ...
+}
+
+StreamMode ::= ENUMERATED
+{
+ sendOnly(0),
+ recvOnly(1),
+ sendRecv(2),
+ inactive(3),
+ loopBack(4),
+ ...
+}
+
+-- In PropertyParm, value is a SEQUENCE OF octet string. When sent
+-- by an MGC the interpretation is as follows:
+-- empty sequence means CHOOSE
+-- one element sequence specifies value
+-- If the sublist field is not selected, a longer sequence means
+-- "choose one of the values" (i.e. value1 OR value2 OR ...)
+-- If the sublist field is selected,
+-- a sequence with more than one element encodes the value of a
+-- list-valued property (i.e. value1 AND value2 AND ...).
+-- The relation field may only be selected if the value sequence
+-- has length 1. It indicates that the MG has to choose a value
+-- for the property. E.g., x > 3 (using the greaterThan
+-- value for relation) instructs the MG to choose any value larger
+-- than 3 for property x.
+-- The range field may only be selected if the value sequence
+-- has length 2. It indicates that the MG has to choose a value
+-- in the range between the first octet in the value sequence and
+-- the trailing octet in the value sequence, including the
+-- boundary values.
+-- When sent by the MG, only responses to an AuditCapability request
+-- may contain multiple values, a range, or a relation field.
+
+PropertyParm ::= SEQUENCE
+{
+ name PkgdName,
+ value SEQUENCE OF OCTET STRING,
+ extraInfo CHOICE
+ {
+ relation Relation,
+ range BOOLEAN,
+ sublist BOOLEAN
+ } OPTIONAL,
+ ...
+}
+
+Name ::= OCTET STRING(SIZE(2))
+
+PkgdName ::= OCTET STRING(SIZE(4))
+-- represents Package Name (2 octets) plus Property Name (2 octets)
+-- To wildcard a package use 0xFFFF for first two octets, choose
+-- is not allowed. To reference native property tag specified in
+-- Annex C, use 0x0000 as first two octets.
+-- Wildcarding of Package Name is permitted only if Property Name is
+-- also wildcarded.
+
+Relation ::= ENUMERATED
+{
+ greaterThan(0),
+ smallerThan(1),
+ unequalTo(2),
+ ...
+}
+
+LocalRemoteDescriptor ::= SEQUENCE
+{
+ propGrps SEQUENCE OF PropertyGroup,
+ ...
+}
+
+PropertyGroup ::= SEQUENCE OF PropertyParm
+
+TerminationStateDescriptor ::= SEQUENCE
+{
+ propertyParms SEQUENCE OF PropertyParm,
+ eventBufferControl EventBufferControl OPTIONAL,
+ serviceState ServiceState OPTIONAL,
+ ...
+}
+
+EventBufferControl ::= ENUMERATED
+{
+ off(0),
+ lockStep(1),
+ ...
+}
+
+ServiceState ::= ENUMERATED
+{
+ test(0),
+ outOfSvc(1),
+ inSvc(2),
+ ...
+}
+
+MuxDescriptor ::= SEQUENCE
+{
+ muxType MuxType,
+ termList SEQUENCE OF TerminationID,
+-- nonStandardData NonStandardData OPTIONAL,
+ ...
+}
+
+MuxType ::= ENUMERATED
+{
+ h221(0),
+ h223(1),
+ h226(2),
+ v76(3),
+ ...
+}
+
+StreamID ::= INTEGER(0..65535) -- 16 bit unsigned integer
+
+EventsDescriptor ::= SEQUENCE
+{
+ requestID RequestID,
+ eventList SEQUENCE OF RequestedEvent,
+ ...
+}
+
+RequestedEvent ::= SEQUENCE
+{
+ pkgdName PkgdName,
+ streamID StreamID OPTIONAL,
+ eventAction RequestedActions OPTIONAL,
+ evParList SEQUENCE OF EventParameter,
+ ...
+}
+
+RequestedActions ::= SEQUENCE
+{
+ keepActive BOOLEAN,
+ eventDM EventDM OPTIONAL,
+ secondEvent SecondEventsDescriptor OPTIONAL,
+ signalsDescriptor SignalsDescriptor OPTIONAL,
+ ...
+}
+
+
+EventDM ::= CHOICE
+{
+ digitMapName DigitMapName,
+ digitMapValue DigitMapValue
+}
+
+SecondEventsDescriptor ::= SEQUENCE
+{
+ requestID RequestID,
+ eventList SEQUENCE OF SecondRequestedEvent,
+ ...
+}
+
+SecondRequestedEvent ::= SEQUENCE
+{
+ pkgdName PkgdName,
+ streamID StreamID OPTIONAL,
+ eventAction SecondRequestedActions OPTIONAL,
+ evParList SEQUENCE OF EventParameter,
+ ...
+}
+
+SecondRequestedActions ::= SEQUENCE
+{
+ keepActive BOOLEAN,
+ eventDM EventDM OPTIONAL,
+ signalsDescriptor SignalsDescriptor OPTIONAL,
+ ...
+}
+
+EventBufferDescriptor ::= SEQUENCE OF EventSpec
+
+EventSpec ::= SEQUENCE
+{
+ eventName EventName,
+ streamID StreamID OPTIONAL,
+ eventParList SEQUENCE OF EventParameter,
+ ...
+}
+
+SignalsDescriptor ::= SEQUENCE OF SignalRequest
+
+SignalRequest ::= CHOICE
+{
+ signal Signal,
+ seqSigList SeqSigList,
+ ...
+}
+
+SeqSigList ::= SEQUENCE
+{
+ id INTEGER(0..65535),
+ signalList SEQUENCE OF Signal
+}
+
+Signal ::= SEQUENCE
+{
+ signalName SignalName,
+ streamID StreamID OPTIONAL,
+ sigType SignalType OPTIONAL,
+ duration INTEGER (0..65535) OPTIONAL,
+ notifyCompletion NotifyCompletion OPTIONAL,
+ keepActive BOOLEAN OPTIONAL,
+ sigParList SEQUENCE OF SigParameter,
+ ...
+}
+
+SignalType ::= ENUMERATED
+{
+ brief(0),
+ onOff(1),
+ timeOut(2),
+ ...
+}
+
+SignalName ::= PkgdName
+
+NotifyCompletion ::= BIT STRING
+{
+ onTimeOut(0),
+ onInterruptByEvent(1),
+ onInterruptByNewSignalDescr(2),
+ otherReason(3)
+}
+
+SigParameter ::= SEQUENCE
+{
+ sigParameterName Name,
+ value Value
+}
+
+RequestID ::= INTEGER(0..4294967295) -- 32 bit unsigned integer
+
+ModemDescriptor ::= SEQUENCE
+{
+ mtl SEQUENCE OF ModemType,
+ mpl SEQUENCE OF PropertyParm
+-- nonStandardData NonStandardData OPTIONAL
+}
+
+ModemType ::= ENUMERATED
+{
+ v18(0),
+ v22(1),
+ v22bis(2),
+ v32(3),
+ v32bis(4),
+ v34(5),
+ v90(6),
+ v91(7),
+ synchISDN(8),
+ ...
+}
+
+DigitMapDescriptor ::= SEQUENCE
+{
+ digitMapName DigitMapName OPTIONAL,
+ digitMapValue DigitMapValue OPTIONAL
+}
+
+DigitMapName ::= Name
+
+DigitMapValue ::= SEQUENCE
+{
+ startTimer INTEGER(0..99) OPTIONAL,
+ shortTimer INTEGER(0..99) OPTIONAL,
+ longTimer INTEGER(0..99) OPTIONAL,
+ digitMapBody IA5String,
+ -- See Section A.3 for explanation of digit map syntax
+ ...
+}
+
+ServiceChangeParm ::= SEQUENCE
+{
+ serviceChangeMethod ServiceChangeMethod,
+ serviceChangeAddress ServiceChangeAddress OPTIONAL,
+ serviceChangeVersion INTEGER(0..99) OPTIONAL,
+ serviceChangeProfile ServiceChangeProfile OPTIONAL,
+ serviceChangeReason Value,
+ serviceChangeDelay INTEGER(0..4294967295) OPTIONAL,
+ -- 32 bit unsigned integer
+ serviceChangeMgcId MId OPTIONAL,
+ timeStamp TimeNotation OPTIONAL,
+-- nonStandardData NonStandardData OPTIONAL,
+ ...
+}
+
+ServiceChangeAddress ::= CHOICE
+{
+ portNumber INTEGER(0..65535), -- TCP/UDP port number
+ ip4Address IP4Address,
+ ip6Address IP6Address,
+ domainName DomainName,
+ deviceName PathName,
+ mtpAddress OCTET STRING(SIZE(2)),
+ ...
+}
+
+ServiceChangeResParm ::= SEQUENCE
+{
+ serviceChangeMgcId MId OPTIONAL,
+ serviceChangeAddress ServiceChangeAddress OPTIONAL,
+ serviceChangeVersion INTEGER(0..99) OPTIONAL,
+ serviceChangeProfile ServiceChangeProfile OPTIONAL,
+ ...
+}
+
+ServiceChangeMethod ::= ENUMERATED
+{
+ failover(0),
+ forced(1),
+ graceful(2),
+ restart(3),
+ disconnected(4),
+ handOff(5),
+ ...
+}
+
+ServiceChangeProfile ::= SEQUENCE
+{
+ profileName Name,
+ version INTEGER(0..99)
+}
+
+PackagesDescriptor ::= SEQUENCE OF PackagesItem
+
+PackagesItem ::= SEQUENCE
+{
+ packageName Name,
+ packageVersion INTEGER(0..99),
+ ...
+}
+
+StatisticsDescriptor ::= SEQUENCE OF StatisticsParameter
+
+StatisticsParameter ::= SEQUENCE
+{
+ statName PkgdName,
+ statValue Value
+}
+
+-- NonStandardData ::= SEQUENCE
+-- {
+-- nonStandardIdentifier NonStandardIdentifier,
+-- data OCTET STRING
+-- }
+--
+-- NonStandardIdentifier ::= CHOICE
+-- {
+-- object OBJECT IDENTIFIER,
+-- h221NonStandard H221NonStandard,
+-- experimental IA5String(SIZE(8)),
+-- first two characters should be "X-" or "X+"
+-- ...
+-- }
+--
+-- H221NonStandard ::= SEQUENCE
+-- {
+-- t35CountryCode1 INTEGER(0..255),
+-- t35CountryCode2 INTEGER(0..255), country, as per T.35
+-- t35Extension INTEGER(0..255), assigned nationally
+-- manufacturerCode INTEGER(0..65535), assigned nationally
+-- ...
+-- }
+
+TimeNotation ::= SEQUENCE
+{
+ date IA5String(SIZE(8)), -- yyyymmdd format
+ time IA5String(SIZE(8)) -- hhmmssss format
+}
+
+Value ::= OCTET STRING
+
+
+END
+
diff --git a/lib/asn1/test/asn1_SUITE_data/OTP-PKIX.asn1config b/lib/asn1/test/asn1_SUITE_data/OTP-PKIX.asn1config
new file mode 100644
index 0000000000..8d96aaecf1
--- /dev/null
+++ b/lib/asn1/test/asn1_SUITE_data/OTP-PKIX.asn1config
@@ -0,0 +1,2 @@
+{exclusive_decode,{'OTP-PKIX',
+ [{decode_TBSCert_exclusive,['CertificatePKIX1Explicit88',[{tbsCertificate,undecoded}]]}]}}.
diff --git a/lib/asn1/test/asn1_SUITE_data/OTP-PKIX.set.asn b/lib/asn1/test/asn1_SUITE_data/OTP-PKIX.set.asn
new file mode 100644
index 0000000000..1b198d3b91
--- /dev/null
+++ b/lib/asn1/test/asn1_SUITE_data/OTP-PKIX.set.asn
@@ -0,0 +1,5 @@
+SSL-PKIX.asn1
+PKIX1Explicit88.asn1
+PKIX1Implicit88.asn1
+PKIXAttributeCertificate.asn1
+PKIX1Algorithms88.asn1
diff --git a/lib/asn1/test/asn1_SUITE_data/ObjIdValues.asn1 b/lib/asn1/test/asn1_SUITE_data/ObjIdValues.asn1
new file mode 100644
index 0000000000..9368e8dceb
--- /dev/null
+++ b/lib/asn1/test/asn1_SUITE_data/ObjIdValues.asn1
@@ -0,0 +1,66 @@
+
+ObjIdValues
+
+DEFINITIONS
+
+IMPLICIT TAGS
+
+::=
+
+BEGIN
+
+ObjIdType ::= OBJECT IDENTIFIER
+
+mobileDomainId OBJECT IDENTIFIER ::=
+ {ccitt (0) identified-organization (4) etsi (0) mobileDomain (0)}
+mobileDomainId-Alt1 OBJECT IDENTIFIER ::=
+ {ccitt identified-organization etsi (0) mobileDomain (0)}
+mobileDomainId-Alt2 OBJECT IDENTIFIER ::=
+ {0 4 0 0}
+
+gsm-NetworkId OBJECT IDENTIFIER ::=
+ {mobileDomainId gsm-Network (1)}
+
+CommonComponentId ::= INTEGER (0..9)
+
+as-Id CommonComponentId ::= 1
+
+map-DialogueAS OBJECT IDENTIFIER ::=
+{gsm-NetworkId as-Id map-DialoguePDU (1) version1 (1)}
+
+-- test for OTP-4354
+-- But it only caused a warning
+objid OBJECT IDENTIFIER ::= {mobileDomainId-Alt2 as-Id}
+
+itu-t-a OBJECT IDENTIFIER ::= {itu-t recommendation a}
+itu-t-b OBJECT IDENTIFIER ::= {itu-t recommendation b}
+itu-t-c OBJECT IDENTIFIER ::= {itu-t recommendation c}
+itu-t-d OBJECT IDENTIFIER ::= {itu-t recommendation d}
+itu-t-e OBJECT IDENTIFIER ::= {itu-t recommendation e}
+itu-t-f OBJECT IDENTIFIER ::= {itu-t recommendation f}
+itu-t-g OBJECT IDENTIFIER ::= {itu-t recommendation g}
+itu-t-h OBJECT IDENTIFIER ::= {itu-t recommendation h}
+itu-t-i OBJECT IDENTIFIER ::= {itu-t recommendation i}
+itu-t-j OBJECT IDENTIFIER ::= {itu-t recommendation j}
+itu-t-k OBJECT IDENTIFIER ::= {itu-t recommendation k}
+itu-t-l OBJECT IDENTIFIER ::= {itu-t recommendation l}
+itu-t-m OBJECT IDENTIFIER ::= {itu-t recommendation m}
+itu-t-n OBJECT IDENTIFIER ::= {itu-t recommendation n}
+itu-t-o OBJECT IDENTIFIER ::= {itu-t recommendation o}
+itu-t-p OBJECT IDENTIFIER ::= {itu-t recommendation p}
+itu-t-q OBJECT IDENTIFIER ::= {itu-t recommendation q}
+itu-t-r OBJECT IDENTIFIER ::= {itu-t recommendation r}
+itu-t-t OBJECT IDENTIFIER ::= {itu-t recommendation t}
+itu-t-u OBJECT IDENTIFIER ::= {itu-t recommendation u}
+itu-t-v OBJECT IDENTIFIER ::= {itu-t recommendation v}
+itu-t-w OBJECT IDENTIFIER ::= {itu-t recommendation w}
+itu-t-x OBJECT IDENTIFIER ::= {itu-t recommendation x}
+itu-t-y OBJECT IDENTIFIER ::= {itu-t recommendation y}
+itu-t-z OBJECT IDENTIFIER ::= {itu-t recommendation z}
+ccitt-q OBJECT IDENTIFIER ::= {ccitt question}
+ccitt-a OBJECT IDENTIFIER ::= {ccitt administration}
+ccitt-n OBJECT IDENTIFIER ::= {ccitt network-operator}
+iso-i OBJECT IDENTIFIER ::= {iso identified-organization}
+joint-iso OBJECT IDENTIFIER ::= {joint-iso-ccitt}
+
+END
diff --git a/lib/asn1/test/asn1_SUITE_data/Objects.asn b/lib/asn1/test/asn1_SUITE_data/Objects.asn
new file mode 100644
index 0000000000..f911acbbe9
--- /dev/null
+++ b/lib/asn1/test/asn1_SUITE_data/Objects.asn
@@ -0,0 +1,61 @@
+Objects DEFINITIONS ::=
+BEGIN
+
+OPERATION ::= CLASS
+ {
+ &ArgumentType OPTIONAL,
+ &ResultType OPTIONAL,
+ &Errors ERROR OPTIONAL,
+ &Linked OPERATION OPTIONAL,
+ &resultReturned BOOLEAN DEFAULT TRUE,
+ &operationCode INTEGER UNIQUE
+ }
+WITH SYNTAX
+ {
+ [ARGUMENT &ArgumentType]
+ [RESULT &ResultType]
+ [RETURN RESULT &resultReturned]
+ [ERRORS &Errors]
+ [LINKED &Linked]
+ CODE &operationCode
+ }
+
+ERROR ::= CLASS
+ {
+ &ParameterType OPTIONAL,
+ &errorCode INTEGER UNIQUE
+ }
+WITH SYNTAX
+ {
+ [PARAMETER &ParameterType]
+ CODE &errorCode
+ }
+
+My-Operations OPERATION ::= { operationA | operationB }
+
+operationA OPERATION ::= {
+ ARGUMENT INTEGER
+ ERRORS { { PARAMETER INTEGER CODE 1000 } | { CODE 1001 } }
+ CODE 1
+}
+
+operationB OPERATION ::= {
+ ARGUMENT IA5String
+ RESULT BOOLEAN
+ ERRORS { { CODE 1002 } | { PARAMETER IA5String CODE 1003 } }
+ CODE 2
+}
+
+My-OperationErrors ERROR ::= { My-Operations.&Errors }
+
+My-OperationAERror ERROR ::= {operationA.&Errors}
+-- Equals:
+-- My-OperationErrors ERROR ::= { { PARAMETER INTEGER CODE 1000 } | { CODE 1001 } | { CODE 1002 } | { PARAMETER IA5String CODE 1003 } }
+
+My-OperationErrorCodes INTEGER ::= { My-Operations.&Errors.&errorCode }
+-- Equals:
+-- My-OperationErrorCodes INTEGER ::= { 1000 | 1001 | 1002 | 1003 }
+
+END
+
+
diff --git a/lib/asn1/test/asn1_SUITE_data/Octetstr.py b/lib/asn1/test/asn1_SUITE_data/Octetstr.py
new file mode 100644
index 0000000000..e971acf192
--- /dev/null
+++ b/lib/asn1/test/asn1_SUITE_data/Octetstr.py
@@ -0,0 +1,15 @@
+Octetstr DEFINITIONS ::=
+BEGIN
+
+-- F.2.6.1
+-- Use an octet string type to model binary data whose format and length are
+-- unspecified, or specified elsewhere, and whose length in bits is a
+-- multiple of eight.
+-- EXAMPLE
+
+G4FacsimileImage ::= OCTET STRING
+-- a sequence of octets conforming to
+-- Recommendations T.5 and T.6
+image G4FacsimileImage ::= '3FE2EBAD471005'H
+
+END
diff --git a/lib/asn1/test/asn1_SUITE_data/One.py b/lib/asn1/test/asn1_SUITE_data/One.py
new file mode 100644
index 0000000000..89083fbd66
--- /dev/null
+++ b/lib/asn1/test/asn1_SUITE_data/One.py
@@ -0,0 +1,52 @@
+One DEFINITIONS ::=
+
+BEGIN
+EXPORTS Boo,Foo,Bar;
+--IMPORTS
+--Fooo , Abba FROM Bobby
+--Robbe FROM Tst;
+
+Boo ::= [1] INTEGER (0..200)
+
+Foo ::= One.Boo
+
+Bar ::= SEQUENCE {
+ ff One.Foo,
+ aa One.Boo }
+
+
+ S ::= [1] IMPLICIT SEQUENCE {
+ authInfo
+ INTEGER, -- defined by authentication protocol
+ authData
+ Boo
+ }
+
+
+--S::= Jojo
+--T ::= S
+--U ::= T
+--Jojo ::= [PRIVATE 21] SET {
+-- Boo ,x
+-- d SEQUENCE {
+-- [0] INTEGER OPTIONAL,
+-- [1] INTEGER DEFAULT 55 },
+-- g [2] INTEGER (0..10) }
+--
+--J ::= [PRIVATE 22] EXPLICIT SEQUENCE {
+-- y SEQUENCE {
+-- one INTEGER,
+-- two INTEGER },
+-- x INTEGER (1..3),
+-- a Boo OPTIONAL,
+-- b INTEGER }
+--
+--Noo ::= [PRIVATE 23] SEQUENCE {
+-- [0] Jojo,
+-- [1] J }
+
+
+
+
+END
+
diff --git a/lib/asn1/test/asn1_SUITE_data/OpenType.asn1 b/lib/asn1/test/asn1_SUITE_data/OpenType.asn1
new file mode 100644
index 0000000000..8016f3663c
--- /dev/null
+++ b/lib/asn1/test/asn1_SUITE_data/OpenType.asn1
@@ -0,0 +1,12 @@
+OpenType DEFINITIONS AUTOMATIC TAGS ::=
+
+BEGIN
+
+Stype ::= SEQUENCE {
+ a INTEGER,
+ b BOOLEAN
+}
+Ot ::= TYPE-IDENTIFIER.&Type (Stype)
+
+END
+
diff --git a/lib/asn1/test/asn1_SUITE_data/OpenTypeImplicitTag.asn b/lib/asn1/test/asn1_SUITE_data/OpenTypeImplicitTag.asn
new file mode 100644
index 0000000000..ee25b5cf3c
--- /dev/null
+++ b/lib/asn1/test/asn1_SUITE_data/OpenTypeImplicitTag.asn
@@ -0,0 +1,19 @@
+OpenTypeImplicitTag DEFINITIONS IMPLICIT TAGS ::=
+
+BEGIN
+
+Seq ::= SEQUENCE {
+ a [1] A OPTIONAL,
+ b [2] ANY OPTIONAL,
+ c [3] INTEGER,
+ d [4] C.&Type OPTIONAL
+}
+
+C ::= CLASS {
+ &Type,
+ &id INTEGER
+}
+
+A ::= ANY
+
+END
diff --git a/lib/asn1/test/asn1_SUITE_data/Opt.asn1 b/lib/asn1/test/asn1_SUITE_data/Opt.asn1
new file mode 100644
index 0000000000..48c2a09b64
--- /dev/null
+++ b/lib/asn1/test/asn1_SUITE_data/Opt.asn1
@@ -0,0 +1,31 @@
+Opt DEFINITIONS IMPLICIT TAGS ::=
+
+BEGIN
+
+Opt1 ::= SEQUENCE
+{
+ bool0 [0] BOOLEAN,
+ bool1 [1] BOOLEAN OPTIONAL,
+ bool2 [2] BOOLEAN OPTIONAL,
+ bool3 [3] BOOLEAN OPTIONAL
+}
+
+
+Opt2 ::= SEQUENCE
+{
+ bool10 [10] BOOLEAN,
+ bool11 [11] BOOLEAN OPTIONAL,
+ bool12 [12] BOOLEAN OPTIONAL,
+ bool13 [13] BOOLEAN
+}
+
+
+Opt3 ::= SEQUENCE
+{
+ bool30 [30] BOOLEAN OPTIONAL,
+ bool31 [31] BOOLEAN OPTIONAL,
+ bool32 [32] BOOLEAN OPTIONAL,
+ bool33 [33] BOOLEAN OPTIONAL
+}
+
+END
diff --git a/lib/asn1/test/asn1_SUITE_data/Opt.py b/lib/asn1/test/asn1_SUITE_data/Opt.py
new file mode 100644
index 0000000000..48c2a09b64
--- /dev/null
+++ b/lib/asn1/test/asn1_SUITE_data/Opt.py
@@ -0,0 +1,31 @@
+Opt DEFINITIONS IMPLICIT TAGS ::=
+
+BEGIN
+
+Opt1 ::= SEQUENCE
+{
+ bool0 [0] BOOLEAN,
+ bool1 [1] BOOLEAN OPTIONAL,
+ bool2 [2] BOOLEAN OPTIONAL,
+ bool3 [3] BOOLEAN OPTIONAL
+}
+
+
+Opt2 ::= SEQUENCE
+{
+ bool10 [10] BOOLEAN,
+ bool11 [11] BOOLEAN OPTIONAL,
+ bool12 [12] BOOLEAN OPTIONAL,
+ bool13 [13] BOOLEAN
+}
+
+
+Opt3 ::= SEQUENCE
+{
+ bool30 [30] BOOLEAN OPTIONAL,
+ bool31 [31] BOOLEAN OPTIONAL,
+ bool32 [32] BOOLEAN OPTIONAL,
+ bool33 [33] BOOLEAN OPTIONAL
+}
+
+END
diff --git a/lib/asn1/test/asn1_SUITE_data/P-Record.asn1config b/lib/asn1/test/asn1_SUITE_data/P-Record.asn1config
new file mode 100644
index 0000000000..45405da8bf
--- /dev/null
+++ b/lib/asn1/test/asn1_SUITE_data/P-Record.asn1config
@@ -0,0 +1 @@
+{selective_decode,{'P-Record',[{sel_dec,['PersonnelRecord',title]}]}}.
diff --git a/lib/asn1/test/asn1_SUITE_data/P-Record.asn1db b/lib/asn1/test/asn1_SUITE_data/P-Record.asn1db
new file mode 100644
index 0000000000..13e1162c64
--- /dev/null
+++ b/lib/asn1/test/asn1_SUITE_data/P-Record.asn1db
Binary files differ
diff --git a/lib/asn1/test/asn1_SUITE_data/P-Record.erl b/lib/asn1/test/asn1_SUITE_data/P-Record.erl
new file mode 100644
index 0000000000..9fc6f50d64
--- /dev/null
+++ b/lib/asn1/test/asn1_SUITE_data/P-Record.erl
@@ -0,0 +1,244 @@
+%% Generated by the Erlang ASN.1 BER-compiler version, utilizing bit-syntax:1.3.1.4
+%% Purpose: encoder and decoder to the types in mod P-Record
+
+-module('P-Record').
+-include("P-Record.hrl").
+-define('RT_PER',asn1rt_per_bin).
+-export([encoding_rule/0]).
+-export([
+'enc_PersonnelRecord'/1,
+'enc_ChildInformation'/1,
+'enc_Name'/1,
+'enc_EmployeeNumber'/1,
+'enc_Date'/1
+]).
+
+-export([
+'dec_PersonnelRecord'/2,
+'dec_ChildInformation'/2,
+'dec_Name'/2,
+'dec_EmployeeNumber'/2,
+'dec_Date'/2
+]).
+
+-export([
+'v'/0
+]).
+
+
+
+-export([encode/2,decode/2,encode_disp/2,decode_disp/2]).
+
+encoding_rule() ->
+ per_bin.
+
+encode(Type,Data) ->
+case catch ?RT_PER:complete(encode_disp(Type,Data)) of
+ {'EXIT',{error,Reason}} ->
+ {error,Reason};
+ {'EXIT',Reason} ->
+ {error,{asn1,Reason}};
+ {Bytes,Len} ->
+ {ok,Bytes};
+ X ->
+ {ok,X}
+end.
+
+decode(Type,Data) ->
+case catch decode_disp(Type,Data) of
+ {'EXIT',{error,Reason}} ->
+ {error,Reason};
+ {'EXIT',Reason} ->
+ {error,{asn1,Reason}};
+ {X,_Rest} ->
+ {ok,X};
+ {X,_Rest,_Len} ->
+ {ok,X}
+end.
+
+encode_disp('PersonnelRecord',Data) -> 'enc_PersonnelRecord'(Data);
+encode_disp('ChildInformation',Data) -> 'enc_ChildInformation'(Data);
+encode_disp('Name',Data) -> 'enc_Name'(Data);
+encode_disp('EmployeeNumber',Data) -> 'enc_EmployeeNumber'(Data);
+encode_disp('Date',Data) -> 'enc_Date'(Data);
+encode_disp(Type,Data) -> exit({error,{asn1,{undefined_type,Type}}}).
+
+
+decode_disp('PersonnelRecord',Data) -> 'dec_PersonnelRecord'(Data,mandatory);
+decode_disp('ChildInformation',Data) -> 'dec_ChildInformation'(Data,mandatory);
+decode_disp('Name',Data) -> 'dec_Name'(Data,mandatory);
+decode_disp('EmployeeNumber',Data) -> 'dec_EmployeeNumber'(Data,mandatory);
+decode_disp('Date',Data) -> 'dec_Date'(Data,mandatory);
+decode_disp(Type,Data) -> exit({error,{asn1,{undefined_type,Type}}}).
+
+
+
+
+
+'enc_PersonnelRecord'(Val) ->
+{Val1,Opt} = ?RT_PER:fixoptionals([{children,6}],Val),
+[
+?RT_PER:setoptionals(Opt),
+
+%% attribute number 1 with type Externaltypereference6P-RecordName
+'enc_Name'(?RT_PER:cindex(2,Val1,name)),
+
+%% attribute number 2 with type VisibleString
+?RT_PER:encode_VisibleString([],?RT_PER:cindex(3,Val1,title)),
+
+%% attribute number 3 with type INTEGER
+?RT_PER:encode_integer([],?RT_PER:cindex(4,Val1,number)),
+
+%% attribute number 4 with type VisibleString
+?RT_PER:encode_VisibleString([],?RT_PER:cindex(5,Val1,dateOfHire)),
+
+%% attribute number 5 with type Externaltypereference10P-RecordName
+'enc_Name'(?RT_PER:cindex(6,Val1,nameOfSpouse)),
+case ?RT_PER:cindex(7,Val1,children) of
+asn1_DEFAULT -> [];
+_ ->
+
+%% attribute number 6 with type SEQUENCE OF
+'enc_PersonnelRecord_children'(?RT_PER:cindex(7,Val1,children))
+end].
+
+'enc_PersonnelRecord_children'({'PersonnelRecord_children',Val}) ->
+'enc_PersonnelRecord_children'(Val);
+
+'enc_PersonnelRecord_children'(Val) ->
+[
+
+ ?RT_PER:encode_length(undefined,length(Val)),
+ 'enc_PersonnelRecord_children_components'(Val, [])
+].
+'enc_PersonnelRecord_children_components'([], Acc) -> lists:reverse(Acc);
+
+'enc_PersonnelRecord_children_components'([H|T], Acc) ->
+'enc_PersonnelRecord_children_components'(T, ['enc_ChildInformation'(H)
+
+ | Acc]).
+
+'dec_PersonnelRecord_children'(Bytes,Telltype) ->
+
+{Num,Bytes1} = ?RT_PER:decode_length(Bytes,undefined),
+'dec_PersonnelRecord_children_components'(Num, Bytes1, Telltype, []).
+'dec_PersonnelRecord_children_components'(0, Bytes, Telltype, Acc) ->
+ {lists:reverse(Acc), Bytes};
+'dec_PersonnelRecord_children_components'(Num, Bytes, Telltype, Acc) ->
+ {Term,Remain} = 'P-Record':'dec_ChildInformation'(Bytes,Telltype),
+ 'dec_PersonnelRecord_children_components'(Num-1, Remain, Telltype, [Term|Acc]).
+
+
+'dec_PersonnelRecord'(Bytes,Telltype) ->
+{Opt,Bytes1} = ?RT_PER:getoptionals(Bytes,1),
+%% attribute number 1 with type Name
+{Term1,Bytes2} = 'dec_Name'(Bytes1,telltype),
+
+%% attribute number 2 with type VisibleString
+{Term2,Bytes3} = ?RT_PER:decode_VisibleString(Bytes2,[]),
+
+%% attribute number 3 with type INTEGER
+{Term3,Bytes4} = ?RT_PER:decode_integer(Bytes3,[]),
+
+%% attribute number 4 with type VisibleString
+{Term4,Bytes5} = ?RT_PER:decode_VisibleString(Bytes4,[]),
+
+%% attribute number 5 with type Name
+{Term5,Bytes6} = 'dec_Name'(Bytes5,telltype),
+
+%% attribute number 6 with type SEQUENCE OF
+{Term6,Bytes7} = case element(1,Opt) of
+1 ->'dec_PersonnelRecord_children'(Bytes6, Telltype);
+0 ->{[],Bytes6}
+
+end,
+{{'PersonnelRecord',Term1,Term2,Term3,Term4,Term5,Term6},Bytes7}.
+
+'enc_ChildInformation'(Val) ->
+{Val1,Opt} = ?RT_PER:fixoptionals([{name,1},{dateOfBirth,2}],Val),
+[
+?RT_PER:setoptionals(Opt),
+case ?RT_PER:cindex(2,Val1,name) of
+asn1_NOVALUE -> [];
+_ ->
+
+%% attribute number 1 with type Externaltypereference15P-RecordName
+'enc_Name'(?RT_PER:cindex(2,Val1,name))
+end,
+case ?RT_PER:cindex(3,Val1,dateOfBirth) of
+asn1_NOVALUE -> [];
+_ ->
+
+%% attribute number 2 with type VisibleString
+?RT_PER:encode_VisibleString([],?RT_PER:cindex(3,Val1,dateOfBirth))
+end].
+
+
+'dec_ChildInformation'(Bytes,Telltype) ->
+{Opt,Bytes1} = ?RT_PER:getoptionals(Bytes,2),
+%% attribute number 1 with type Name
+{Term1,Bytes2} = case element(1,Opt) of
+1 ->'dec_Name'(Bytes1,telltype);
+0 ->{asn1_NOVALUE,Bytes1}
+
+end,
+
+%% attribute number 2 with type VisibleString
+{Term2,Bytes3} = case element(2,Opt) of
+1 ->?RT_PER:decode_VisibleString(Bytes2,[]);
+0 ->{asn1_NOVALUE,Bytes2}
+
+end,
+{{'ChildInformation',Term1,Term2},Bytes3}.
+
+'enc_Name'(Val) ->
+Val1 = ?RT_PER:list_to_record('Name', Val),
+[
+
+%% attribute number 1 with type VisibleString
+?RT_PER:encode_VisibleString([],?RT_PER:cindex(2,Val1,givenName)),
+
+%% attribute number 2 with type VisibleString
+?RT_PER:encode_VisibleString([],?RT_PER:cindex(3,Val1,initial)),
+
+%% attribute number 3 with type VisibleString
+?RT_PER:encode_VisibleString([],?RT_PER:cindex(4,Val1,familyName))].
+
+
+'dec_Name'(Bytes,Telltype) ->
+
+%% attribute number 1 with type VisibleString
+{Term1,Bytes1} = ?RT_PER:decode_VisibleString(Bytes,[]),
+
+%% attribute number 2 with type VisibleString
+{Term2,Bytes2} = ?RT_PER:decode_VisibleString(Bytes1,[]),
+
+%% attribute number 3 with type VisibleString
+{Term3,Bytes3} = ?RT_PER:decode_VisibleString(Bytes2,[]),
+{{'Name',Term1,Term2,Term3},Bytes3}.
+
+
+'enc_EmployeeNumber'({'EmployeeNumber',Val}) ->
+'enc_EmployeeNumber'(Val);
+
+'enc_EmployeeNumber'(Val) ->
+?RT_PER:encode_integer([],Val).
+
+
+'dec_EmployeeNumber'(Bytes,Telltype) ->
+?RT_PER:decode_integer(Bytes,[]).
+
+
+'enc_Date'({'Date',Val}) ->
+'enc_Date'(Val);
+
+'enc_Date'(Val) ->
+?RT_PER:encode_VisibleString([],Val).
+
+
+'dec_Date'(Bytes,Telltype) ->
+?RT_PER:decode_VisibleString(Bytes,[]).
+
+'v'() ->
+{'PersonnelRecord',{'Name',{74,111,104,110},[80],[83,109,105,116,104]},[68,105,114,101,99,116,111,114],51,[49,57,55,49,48,57,49,55],{'Name',{77,97,114,121},[84],[83,109,105,116,104]},[{'ChildInformation',{'Name',[82,97,108,112,104],[84],[83,109,105,116,104]},[49,57,53,55,49,49,49,49]},{'ChildInformation',{'Name',[83,117,115,97,110],[66],[74,111,110,101,115]},[49,57,53,57,48,55,49,55]}]}.
+
diff --git a/lib/asn1/test/asn1_SUITE_data/P-Record.hrl b/lib/asn1/test/asn1_SUITE_data/P-Record.hrl
new file mode 100644
index 0000000000..92aa1a44e2
--- /dev/null
+++ b/lib/asn1/test/asn1_SUITE_data/P-Record.hrl
@@ -0,0 +1,17 @@
+%% Generated by the Erlang ASN.1 compiler version:1.3.1.4
+%% Purpose: Erlang record definitions for each named and unnamed
+%% SEQUENCE and SET, and macro definitions for each value
+%% definition,in module P-Record
+
+
+
+-record('PersonnelRecord',{
+name, title, number, dateOfHire, nameOfSpouse, children = asn1_DEFAULT}).
+
+-record('ChildInformation',{
+name = asn1_NOVALUE, dateOfBirth = asn1_NOVALUE}).
+
+-record('Name',{
+givenName, initial, familyName}).
+
+-define('v', {'PersonnelRecord',{'Name',{74,111,104,110},[80],[83,109,105,116,104]},[68,105,114,101,99,116,111,114],51,[49,57,55,49,48,57,49,55],{'Name',{77,97,114,121},[84],[83,109,105,116,104]},[{'ChildInformation',{'Name',[82,97,108,112,104],[84],[83,109,105,116,104]},[49,57,53,55,49,49,49,49]},{'ChildInformation',{'Name',[83,117,115,97,110],[66],[74,111,110,101,115]},[49,57,53,57,48,55,49,55]}]}).
diff --git a/lib/asn1/test/asn1_SUITE_data/P-Record.py b/lib/asn1/test/asn1_SUITE_data/P-Record.py
new file mode 100644
index 0000000000..f1db09ac6c
--- /dev/null
+++ b/lib/asn1/test/asn1_SUITE_data/P-Record.py
@@ -0,0 +1,59 @@
+P-Record DEFINITIONS ::=
+BEGIN
+
+
+PersonnelRecord ::= [APPLICATION 0] SET
+{ name Name,
+ title VisibleString,
+ number EmployeeNumber,
+ dateOfHire Date,
+ nameOfSpouse [1] Name,
+ children SEQUENCE OF ChildInformation DEFAULT {}
+}
+
+ChildInformation ::= SET
+{ name Name,
+ dateOfBirth Date
+}
+
+Name ::= [APPLICATION 1] SEQUENCE
+{ givenName VisibleString,
+ initial VisibleString,
+ familyName VisibleString
+}
+
+EmployeeNumber ::= [APPLICATION 2] INTEGER
+Date ::= [APPLICATION 3] VisibleString -- YYYY MMDD
+
+v PersonnelRecord ::=
+{
+ name {
+ givenName "John",
+ initial "P",
+ familyName "Smith"
+ },
+ title "Director",
+ number 51,
+ dateOfHire "19710917",
+ nameOfSpouse {
+ givenName "Mary",
+ initial "T",
+ familyName "Smith"
+ },
+ children {
+ {name {
+ givenName "Ralph",
+ initial "T",
+ familyName "Smith"
+ } ,
+ dateOfBirth "19571111"},
+ {name {
+ givenName "Susan",
+ initial "B",
+ familyName "Jones"
+ } ,
+ dateOfBirth "19590717" }
+ }
+}
+
+END
diff --git a/lib/asn1/test/asn1_SUITE_data/P-RecordA1.asn b/lib/asn1/test/asn1_SUITE_data/P-RecordA1.asn
new file mode 100644
index 0000000000..33ba690e1e
--- /dev/null
+++ b/lib/asn1/test/asn1_SUITE_data/P-RecordA1.asn
@@ -0,0 +1,29 @@
+P-RecordA1 DEFINITIONS AUTOMATIC TAGS ::=
+
+BEGIN
+
+PersonnelRecord ::= [APPLICATION 0] IMPLICIT SET {
+ name Name,
+ title [0] VisibleString,
+ number EmployeeNumber,
+ dateOfHire [1] Date,
+ nameOfSpouse [2] Name,
+ children [3] IMPLICIT SEQUENCE OF ChildInformation DEFAULT {}
+}
+
+ChildInformation ::= SET {
+ name Name,
+ dateOfBirth [0] Date
+}
+
+Name ::= [APPLICATION 1] IMPLICIT SEQUENCE {
+ givenName VisibleString,
+ initial VisibleString,
+ familyName VisibleString
+}
+
+EmployeeNumber ::= [APPLICATION 2] IMPLICIT INTEGER
+
+Date ::= [APPLICATION 3] IMPLICIT VisibleString -- YYYYMMDD
+
+END \ No newline at end of file
diff --git a/lib/asn1/test/asn1_SUITE_data/P-RecordA2.asn b/lib/asn1/test/asn1_SUITE_data/P-RecordA2.asn
new file mode 100644
index 0000000000..50ae419399
--- /dev/null
+++ b/lib/asn1/test/asn1_SUITE_data/P-RecordA2.asn
@@ -0,0 +1,33 @@
+P-RecordA2 DEFINITIONS AUTOMATIC TAGS ::=
+
+BEGIN
+
+
+PersonnelRecord ::= [APPLICATION 0] IMPLICIT SET {
+ name Name,
+ title [0] VisibleString,
+ number EmployeeNumber,
+ dateOfHire [1] Date,
+ nameOfSpouse [2] Name,
+ children [3] IMPLICIT SEQUENCE OF ChildInformation DEFAULT {}
+}
+
+ChildInformation ::= SET {
+ name Name,
+ dateOfBirth [0] Date
+}
+
+Name ::= [APPLICATION 1] IMPLICIT SEQUENCE {
+ givenName NameString,
+ initial NameString (SIZE(1)),
+ familyName NameString
+}
+
+EmployeeNumber ::= [APPLICATION 2] IMPLICIT INTEGER
+
+Date ::= [APPLICATION 3] IMPLICIT VisibleString (FROM("0".."9") ^ SIZE(8)) -- YYYYMMDD
+
+NameString ::= VisibleString (FROM("a".."z" | "A".."Z" | "-.") ^ SIZE(1..64))
+
+
+END \ No newline at end of file
diff --git a/lib/asn1/test/asn1_SUITE_data/P-RecordA3.asn b/lib/asn1/test/asn1_SUITE_data/P-RecordA3.asn
new file mode 100644
index 0000000000..74023140e4
--- /dev/null
+++ b/lib/asn1/test/asn1_SUITE_data/P-RecordA3.asn
@@ -0,0 +1,40 @@
+P-RecordA3 DEFINITIONS AUTOMATIC TAGS ::=
+
+BEGIN
+
+PersonnelRecord ::= [APPLICATION 0] IMPLICIT SET {
+ name Name,
+ title [0] VisibleString,
+ number EmployeeNumber,
+ dateOfHire [1] Date,
+ nameOfSpouse [2] Name,
+ children [3] IMPLICIT SEQUENCE (SIZE(2, ...)) OF ChildInformation OPTIONAL,
+ ...
+}
+
+ChildInformation ::= SET {
+ name Name,
+ dateOfBirth [0] Date,
+ ...,
+ sex [1] IMPLICIT ENUMERATED {
+ male(1),
+ female(2),
+ unknown(3)
+ } OPTIONAL
+}
+
+Name ::= [APPLICATION 1] IMPLICIT SEQUENCE {
+ givenName NameString,
+ initial NameString (SIZE(1)),
+ familyName NameString,
+ ...
+}
+
+EmployeeNumber ::= [APPLICATION 2] IMPLICIT INTEGER (0..9999, ...)
+
+Date ::= [APPLICATION 3] IMPLICIT VisibleString (FROM("0".."9") ^ SIZE(8, ..., 9..20)) -- YYYYMMDD
+
+NameString ::= VisibleString (FROM("a".."z" | "A".."Z" | "-.") ^ SIZE(1..64, ...))
+
+
+END \ No newline at end of file
diff --git a/lib/asn1/test/asn1_SUITE_data/P.py b/lib/asn1/test/asn1_SUITE_data/P.py
new file mode 100644
index 0000000000..1431ae07b9
--- /dev/null
+++ b/lib/asn1/test/asn1_SUITE_data/P.py
@@ -0,0 +1,19 @@
+P DEFINITIONS IMPLICIT TAGS ::=
+BEGIN
+EXPORTS P1, P2;
+
+P1 ::= SEQUENCE {
+ name PrintableString,
+ location INTEGER {home(0),field(1),roving(2)},
+ age INTEGER OPTIONAL
+ }
+
+P2 ::= SEQUENCE {
+ name PrintableString,
+ location INTEGER {home(0),field(1),roving(2)},
+ age INTEGER OPTIONAL,
+ nr BOOLEAN
+ }
+END
+
+
diff --git a/lib/asn1/test/asn1_SUITE_data/PDUs.py b/lib/asn1/test/asn1_SUITE_data/PDUs.py
new file mode 100644
index 0000000000..907348193f
--- /dev/null
+++ b/lib/asn1/test/asn1_SUITE_data/PDUs.py
@@ -0,0 +1,325 @@
+PDUs DEFINITIONS ::=
+
+-- Search for 'org' to find changes for erlang.
+
+-- SnmpMgmtCom and PDUs only for dbg.
+
+
+BEGIN
+EXPORTS SnmpPrivMsg, SnmpAuthMsg, SnmpMgmtCom, PDUs;
+
+-- From RFC 1442
+
+ -- names of objects
+
+ ObjectName ::=
+ OBJECT IDENTIFIER
+
+
+ -- syntax of objects
+
+ ObjectSyntax ::=
+ CHOICE {
+ simple
+ SimpleSyntax,
+
+ -- note that SEQUENCEs for conceptual tables and
+ -- rows are not mentioned here...
+
+ applicationWide
+ ApplicationSyntax
+ }
+
+
+ -- built-in ASN.1 types
+
+ SimpleSyntax ::=
+ CHOICE {
+ -- INTEGERs with a more restrictive range
+ -- may also be used
+ integerValue
+ INTEGER,
+
+ stringValue
+ OCTET STRING,
+
+ objectIDValue
+ OBJECT IDENTIFIER,
+
+ -- only the enumerated form is allowed
+ bitValue
+ BIT STRING
+ }
+
+
+ -- indistinguishable from INTEGER, but never needs more than
+ -- 32Bits for a two's complement representation
+ Integer32 ::=
+ [UNIVERSAL 2]
+ IMPLICIT INTEGER (-2147483648..2147483647)
+
+
+ -- applicationWide types
+
+ ApplicationSyntax ::=
+ CHOICE {
+ ipAddressValue
+ IpAddress,
+
+ counterValue
+ Counter32,
+
+ gaugeValue
+ Gauge32,
+
+ timeticksValue
+ TimeTicks,
+
+ arbitraryValue
+ Opaque,
+
+ nsapAddressValue
+ NsapAddress,
+
+ bigCounterValue
+ Counter64,
+
+ unsignedIntegerValue
+ UInteger32
+ }
+
+ -- in networkByte order
+ -- (this is a tagged type for historical reasons)
+ IpAddress ::=
+ [APPLICATION 0]
+ IMPLICIT OCTET STRING (SIZE (4))
+
+
+
+
+ -- this wraps
+ Counter32 ::=
+ [APPLICATION 1]
+ IMPLICIT INTEGER (0..4294967295)
+
+ -- this doesn't wrap
+ Gauge32 ::=
+ [APPLICATION 2]
+ IMPLICIT INTEGER (0..4294967295)
+
+ -- hundredths of seconds since an epoch
+ TimeTicks ::=
+ [APPLICATION 3]
+ IMPLICIT INTEGER (0..4294967295)
+
+ -- for backwardCompatibility only
+ Opaque ::=
+ [APPLICATION 4]
+ IMPLICIT OCTET STRING
+
+ -- for OSI NSAP addresses
+ -- (this is a tagged type for historical reasons)
+ NsapAddress ::=
+ [APPLICATION 5]
+-- org: IMPLICIT OCTET STRING (SIZE (1 | 4..21))
+ IMPLICIT OCTET STRING
+
+ -- for counters that wrap in less than one hour with only 32 bits
+ Counter64 ::=
+ [APPLICATION 6]
+ IMPLICIT INTEGER (0..18446744073709551615)
+
+ -- an unsigned 32Bit quantity
+ UInteger32 ::=
+ [APPLICATION 7]
+ IMPLICIT INTEGER (0..4294967295)
+
+
+-- From RFC 1445
+
+ SnmpPrivMsg ::= [1] IMPLICIT SEQUENCE {
+ privDst
+ OBJECT IDENTIFIER,
+ privData
+ [1] IMPLICIT OCTET STRING
+ }
+
+ SnmpAuthMsg ::= [1] IMPLICIT SEQUENCE {
+ authInfo
+ ANY, -- defined by authentication protocol
+ authData
+ SnmpMgmtCom
+ }
+
+ SnmpMgmtCom ::= [2] IMPLICIT SEQUENCE {
+ dstParty
+ OBJECT IDENTIFIER,
+ srcParty
+ OBJECT IDENTIFIER,
+ context
+ OBJECT IDENTIFIER,
+ pdu
+ PDUs
+ }
+
+
+-- From RFC 1448
+
+ -- org: no tag at all. we need a tag to test 'PDUs'.
+ PDUs ::= [PRIVATE 1]
+ -- remove tag when 'PDUs' only is used in another type.
+ CHOICE {
+ getRequest
+ GetRequestPdu,
+
+ getNextRequest
+ GetNextRequestPdu,
+
+ getBulkRequest
+ GetBulkRequestPdu,
+
+ response
+ ResponsePdu,
+
+ setRequest
+ SetRequestPdu,
+
+ informRequest
+ InformRequestPdu,
+
+ snmpV2Trap
+ SNMPv2TrapPdu
+ }
+
+ -- PDUs
+
+ GetRequestPdu ::=
+ [0]
+ IMPLICIT PDU
+
+ GetNextRequestPdu ::=
+ [1]
+ IMPLICIT PDU
+
+ ResponsePdu ::=
+ [2]
+ IMPLICIT PDU
+
+ SetRequestPdu ::=
+ [3]
+ IMPLICIT PDU
+
+ -- [4] is obsolete
+
+ GetBulkRequestPdu ::=
+ [5]
+ IMPLICIT BulkPDU
+
+ InformRequestPdu ::=
+ [6]
+ IMPLICIT PDU
+
+ SNMPv2TrapPdu ::=
+ [7]
+ IMPLICIT PDU
+
+
+ maxBindings
+ INTEGER ::= 2147483647
+
+ PDU ::=
+ SEQUENCE {
+ requestId
+ Integer32,
+
+ errorStatus -- sometimes ignored
+ INTEGER {
+ noError(0),
+ tooBig(1),
+ noSuchName(2), -- for proxy compatibility
+ badValue(3), -- for proxy compatibility
+ readOnly(4), -- for proxy compatibility
+ genErr(5),
+ noAccess(6),
+ wrongType(7),
+ wrongLength(8),
+ wrongEncoding(9),
+ wrongValue(10),
+ noCreation(11),
+ inconsistentValue(12),
+ resourceUnavailable(13),
+ commitFailed(14),
+ undoFailed(15),
+ authorizationError(16),
+ notWritable(17),
+ inconsistentName(18)
+ },
+
+ errorIndex -- sometimes ignored
+ INTEGER (0..maxBindings),
+
+ variableBindings -- values are sometimes ignored
+ VarBindList
+ }
+
+
+ BulkPDU ::= -- MUST be identical in
+ SEQUENCE { -- structure to PDU
+ requestId
+ Integer32,
+
+ nonRepeaters
+ INTEGER (0..maxBindings),
+
+ maxRepetitions
+ INTEGER (0..maxBindings),
+
+ variableBindings -- values are ignored
+ VarBindList
+ }
+
+
+ VarBind ::=
+ SEQUENCE {
+ name
+ ObjectName,
+
+ data CHOICE {
+ value
+ ObjectSyntax,
+
+ unSpecified -- in retrieval requests
+ NULL,
+
+ -- exceptions in responses
+ noSuchObject[0]
+ IMPLICIT NULL,
+
+ noSuchInstance[1]
+ IMPLICIT NULL,
+
+ endOfMibView[2]
+ IMPLICIT NULL
+ }
+ }
+
+
+ -- variableBinding list
+
+ VarBindList ::=
+ SEQUENCE OF VarBind
+
+-- org:
+-- VarBindList ::=
+-- SEQUENCE (SIZE (0..maxBindings)) OF
+-- VarBind
+
+END
+
+
+
+
+
+
+
+
diff --git a/lib/asn1/test/asn1_SUITE_data/PKIX1Algorithms88.asn1 b/lib/asn1/test/asn1_SUITE_data/PKIX1Algorithms88.asn1
new file mode 100644
index 0000000000..e78de69b0e
--- /dev/null
+++ b/lib/asn1/test/asn1_SUITE_data/PKIX1Algorithms88.asn1
@@ -0,0 +1,274 @@
+ PKIX1Algorithms88 { iso(1) identified-organization(3) dod(6)
+ internet(1) security(5) mechanisms(5) pkix(7) id-mod(0)
+ id-mod-pkix1-algorithms(17) }
+
+ DEFINITIONS EXPLICIT TAGS ::= BEGIN
+
+ -- EXPORTS All;
+
+ -- IMPORTS NONE;
+
+ --
+ -- One-way Hash Functions
+ --
+
+ md2 OBJECT IDENTIFIER ::= {
+ iso(1) member-body(2) us(840) rsadsi(113549)
+ digestAlgorithm(2) 2 }
+
+ md5 OBJECT IDENTIFIER ::= {
+ iso(1) member-body(2) us(840) rsadsi(113549)
+ digestAlgorithm(2) 5 }
+
+ id-sha1 OBJECT IDENTIFIER ::= {
+ iso(1) identified-organization(3) oiw(14) secsig(3)
+ algorithms(2) 26 }
+
+ --
+ -- DSA Keys and Signatures
+ --
+
+ -- OID for DSA public key
+
+ id-dsa OBJECT IDENTIFIER ::= {
+ iso(1) member-body(2) us(840) x9-57(10040) x9algorithm(4) 1 }
+
+ -- encoding for DSA public key
+
+ DSAPublicKey ::= INTEGER -- public key, y
+
+ Dss-Parms ::= SEQUENCE {
+ p INTEGER,
+ q INTEGER,
+ g INTEGER }
+
+ -- OID for DSA signature generated with SHA-1 hash
+
+ id-dsa-with-sha1 OBJECT IDENTIFIER ::= {
+ iso(1) member-body(2) us(840) x9-57 (10040) x9algorithm(4) 3 }
+
+ -- encoding for DSA signature generated with SHA-1 hash
+
+ Dss-Sig-Value ::= SEQUENCE {
+ r INTEGER,
+ s INTEGER }
+
+ --
+ -- RSA Keys and Signatures
+ --
+
+ -- arc for RSA public key and RSA signature OIDs
+
+ pkcs-1 OBJECT IDENTIFIER ::= {
+ iso(1) member-body(2) us(840) rsadsi(113549) pkcs(1) 1 }
+
+ -- OID for RSA public keys
+
+ rsaEncryption OBJECT IDENTIFIER ::= { pkcs-1 1 }
+
+ -- OID for RSA signature generated with MD2 hash
+
+ md2WithRSAEncryption OBJECT IDENTIFIER ::= { pkcs-1 2 }
+
+ -- OID for RSA signature generated with MD5 hash
+
+ md5WithRSAEncryption OBJECT IDENTIFIER ::= { pkcs-1 4 }
+
+ -- OID for RSA signature generated with SHA-1 hash
+
+ sha1WithRSAEncryption OBJECT IDENTIFIER ::= { pkcs-1 5 }
+
+ -- encoding for RSA public key
+
+ RSAPublicKey ::= SEQUENCE {
+ modulus INTEGER, -- n
+ publicExponent INTEGER } -- e
+
+ --
+ -- Diffie-Hellman Keys
+ --
+
+ dhpublicnumber OBJECT IDENTIFIER ::= {
+ iso(1) member-body(2) us(840) ansi-x942(10046)
+ number-type(2) 1 }
+
+ -- encoding for DSA public key
+
+ DHPublicKey ::= INTEGER -- public key, y = g^x mod p
+
+ DomainParameters ::= SEQUENCE {
+ p INTEGER, -- odd prime, p=jq +1
+ g INTEGER, -- generator, g
+ q INTEGER, -- factor of p-1
+ j INTEGER OPTIONAL, -- subgroup factor, j>= 2
+ validationParms ValidationParms OPTIONAL }
+
+ ValidationParms ::= SEQUENCE {
+ seed BIT STRING,
+ pgenCounter INTEGER }
+
+ --
+ -- KEA Keys
+ --
+
+ id-keyExchangeAlgorithm OBJECT IDENTIFIER ::=
+ { 2 16 840 1 101 2 1 1 22 }
+
+ KEA-Parms-Id ::= OCTET STRING
+
+ --
+ -- Elliptic Curve Keys, Signatures, and Curves
+ --
+
+ ansi-X9-62 OBJECT IDENTIFIER ::= {
+ iso(1) member-body(2) us(840) 10045 }
+
+ FieldID ::= SEQUENCE { -- Finite field
+ fieldType OBJECT IDENTIFIER,
+ parameters ANY DEFINED BY fieldType }
+
+ -- Arc for ECDSA signature OIDS
+
+ id-ecSigType OBJECT IDENTIFIER ::= { ansi-X9-62 signatures(4) }
+
+ -- OID for ECDSA signatures with SHA-1
+
+ ecdsa-with-SHA1 OBJECT IDENTIFIER ::= { id-ecSigType 1 }
+
+ -- OID for an elliptic curve signature
+ -- format for the value of an ECDSA signature value
+
+ ECDSA-Sig-Value ::= SEQUENCE {
+ r INTEGER,
+ s INTEGER }
+
+ -- recognized field type OIDs are defined in the following arc
+
+ id-fieldType OBJECT IDENTIFIER ::= { ansi-X9-62 fieldType(1) }
+
+ -- where fieldType is prime-field, the parameters are of type Prime-p
+
+ prime-field OBJECT IDENTIFIER ::= { id-fieldType 1 }
+
+ Prime-p ::= INTEGER -- Finite field F(p), where p is an odd prime
+
+ -- where fieldType is characteristic-two-field, the parameters are
+ -- of type Characteristic-two
+
+ characteristic-two-field OBJECT IDENTIFIER ::= { id-fieldType 2 }
+
+ Characteristic-two ::= SEQUENCE {
+ m INTEGER, -- Field size 2^m
+ basis OBJECT IDENTIFIER,
+ parameters ANY DEFINED BY basis }
+
+ -- recognized basis type OIDs are defined in the following arc
+
+ id-characteristic-two-basis OBJECT IDENTIFIER ::= {
+ characteristic-two-field basisType(3) }
+
+ -- gnbasis is identified by OID gnBasis and indicates
+ -- parameters are NULL
+
+ gnBasis OBJECT IDENTIFIER ::= { id-characteristic-two-basis 1 }
+
+ -- parameters for this basis are NULL
+
+ -- trinomial basis is identified by OID tpBasis and indicates
+ -- parameters of type Pentanomial
+
+ tpBasis OBJECT IDENTIFIER ::= { id-characteristic-two-basis 2 }
+
+ -- Trinomial basis representation of F2^m
+ -- Integer k for reduction polynomial xm + xk + 1
+
+ Trinomial ::= INTEGER
+
+ -- for pentanomial basis is identified by OID ppBasis and indicates
+ -- parameters of type Pentanomial
+
+ ppBasis OBJECT IDENTIFIER ::= { id-characteristic-two-basis 3 }
+
+ -- Pentanomial basis representation of F2^m
+ -- reduction polynomial integers k1, k2, k3
+ -- f(x) = x**m + x**k3 + x**k2 + x**k1 + 1
+
+ Pentanomial ::= SEQUENCE {
+ k1 INTEGER,
+ k2 INTEGER,
+ k3 INTEGER }
+
+ -- The object identifiers gnBasis, tpBasis and ppBasis name
+ -- three kinds of basis for characteristic-two finite fields
+
+ FieldElement ::= OCTET STRING -- Finite field element
+
+ ECPoint ::= OCTET STRING -- Elliptic curve point
+
+ -- Elliptic Curve parameters may be specified explicitly,
+ -- specified implicitly through a "named curve", or
+ -- inherited from the CA
+
+ EcpkParameters ::= CHOICE {
+ ecParameters ECParameters,
+ namedCurve OBJECT IDENTIFIER,
+ implicitlyCA NULL }
+
+ ECParameters ::= SEQUENCE { -- Elliptic curve parameters
+ version ECPVer,
+ fieldID FieldID,
+ curve Curve,
+ base ECPoint, -- Base point G
+ order INTEGER, -- Order n of the base point
+ cofactor INTEGER OPTIONAL } -- The integer h = #E(Fq)/n
+
+ ECPVer ::= INTEGER {ecpVer1(1)}
+
+ Curve ::= SEQUENCE {
+ a FieldElement, -- Elliptic curve coefficient a
+ b FieldElement, -- Elliptic curve coefficient b
+ seed BIT STRING OPTIONAL }
+
+ id-publicKeyType OBJECT IDENTIFIER ::= { ansi-X9-62 keyType(2) }
+
+ id-ecPublicKey OBJECT IDENTIFIER ::= { id-publicKeyType 1 }
+
+ -- Named Elliptic Curves in ANSI X9.62.
+
+ ellipticCurve OBJECT IDENTIFIER ::= { ansi-X9-62 curves(3) }
+
+ c-TwoCurve OBJECT IDENTIFIER ::= {
+ ellipticCurve characteristicTwo(0) }
+
+ c2pnb163v1 OBJECT IDENTIFIER ::= { c-TwoCurve 1 }
+ c2pnb163v2 OBJECT IDENTIFIER ::= { c-TwoCurve 2 }
+ c2pnb163v3 OBJECT IDENTIFIER ::= { c-TwoCurve 3 }
+ c2pnb176w1 OBJECT IDENTIFIER ::= { c-TwoCurve 4 }
+ c2tnb191v1 OBJECT IDENTIFIER ::= { c-TwoCurve 5 }
+ c2tnb191v2 OBJECT IDENTIFIER ::= { c-TwoCurve 6 }
+ c2tnb191v3 OBJECT IDENTIFIER ::= { c-TwoCurve 7 }
+ c2onb191v4 OBJECT IDENTIFIER ::= { c-TwoCurve 8 }
+ c2onb191v5 OBJECT IDENTIFIER ::= { c-TwoCurve 9 }
+ c2pnb208w1 OBJECT IDENTIFIER ::= { c-TwoCurve 10 }
+ c2tnb239v1 OBJECT IDENTIFIER ::= { c-TwoCurve 11 }
+ c2tnb239v2 OBJECT IDENTIFIER ::= { c-TwoCurve 12 }
+ c2tnb239v3 OBJECT IDENTIFIER ::= { c-TwoCurve 13 }
+ c2onb239v4 OBJECT IDENTIFIER ::= { c-TwoCurve 14 }
+ c2onb239v5 OBJECT IDENTIFIER ::= { c-TwoCurve 15 }
+ c2pnb272w1 OBJECT IDENTIFIER ::= { c-TwoCurve 16 }
+ c2pnb304w1 OBJECT IDENTIFIER ::= { c-TwoCurve 17 }
+ c2tnb359v1 OBJECT IDENTIFIER ::= { c-TwoCurve 18 }
+ c2pnb368w1 OBJECT IDENTIFIER ::= { c-TwoCurve 19 }
+ c2tnb431r1 OBJECT IDENTIFIER ::= { c-TwoCurve 20 }
+
+ primeCurve OBJECT IDENTIFIER ::= { ellipticCurve prime(1) }
+
+ prime192v1 OBJECT IDENTIFIER ::= { primeCurve 1 }
+ prime192v2 OBJECT IDENTIFIER ::= { primeCurve 2 }
+ prime192v3 OBJECT IDENTIFIER ::= { primeCurve 3 }
+ prime239v1 OBJECT IDENTIFIER ::= { primeCurve 4 }
+ prime239v2 OBJECT IDENTIFIER ::= { primeCurve 5 }
+ prime239v3 OBJECT IDENTIFIER ::= { primeCurve 6 }
+ prime256v1 OBJECT IDENTIFIER ::= { primeCurve 7 }
+
+ END
diff --git a/lib/asn1/test/asn1_SUITE_data/PKIX1Explicit88.asn1 b/lib/asn1/test/asn1_SUITE_data/PKIX1Explicit88.asn1
new file mode 100644
index 0000000000..7874679a38
--- /dev/null
+++ b/lib/asn1/test/asn1_SUITE_data/PKIX1Explicit88.asn1
@@ -0,0 +1,619 @@
+PKIX1Explicit88 { iso(1) identified-organization(3) dod(6) internet(1)
+ security(5) mechanisms(5) pkix(7) id-mod(0) id-pkix1-explicit(18) }
+
+DEFINITIONS EXPLICIT TAGS ::=
+
+BEGIN
+
+-- EXPORTS ALL --
+
+-- IMPORTS NONE --
+
+-- UNIVERSAL Types defined in 1993 and 1998 ASN.1
+-- and required by this specification
+
+-- UniversalString ::= [UNIVERSAL 28] IMPLICIT OCTET STRING
+ -- UniversalString is defined in ASN.1:1993
+
+-- BMPString ::= [UNIVERSAL 30] IMPLICIT OCTET STRING
+ -- BMPString is the subtype of UniversalString and models
+ -- the Basic Multilingual Plane of ISO/IEC/ITU 10646-1
+
+--UTF8String ::= [UNIVERSAL 12] IMPLICIT OCTET STRING
+ -- The content of this type conforms to RFC 2279.
+
+-- PKIX specific OIDs
+
+id-pkix OBJECT IDENTIFIER ::=
+ { iso(1) identified-organization(3) dod(6) internet(1)
+ security(5) mechanisms(5) pkix(7) }
+
+-- PKIX arcs
+
+id-pe OBJECT IDENTIFIER ::= { id-pkix 1 }
+ -- arc for private certificate extensions
+id-qt OBJECT IDENTIFIER ::= { id-pkix 2 }
+ -- arc for policy qualifier types
+id-kp OBJECT IDENTIFIER ::= { id-pkix 3 }
+ -- arc for extended key purpose OIDS
+id-ad OBJECT IDENTIFIER ::= { id-pkix 48 }
+ -- arc for access descriptors
+
+-- policyQualifierIds for Internet policy qualifiers
+
+id-qt-cps OBJECT IDENTIFIER ::= { id-qt 1 }
+ -- OID for CPS qualifier
+id-qt-unotice OBJECT IDENTIFIER ::= { id-qt 2 }
+ -- OID for user notice qualifier
+
+-- access descriptor definitions
+
+id-ad-ocsp OBJECT IDENTIFIER ::= { id-ad 1 }
+id-ad-caIssuers OBJECT IDENTIFIER ::= { id-ad 2 }
+id-ad-timeStamping OBJECT IDENTIFIER ::= { id-ad 3 }
+id-ad-caRepository OBJECT IDENTIFIER ::= { id-ad 5 }
+
+-- attribute data types
+
+Attribute ::= SEQUENCE {
+ type AttributeType,
+ values SET OF AttributeValue }
+ -- at least one value is required
+
+AttributeType ::= OBJECT IDENTIFIER
+
+AttributeValue ::= ANY
+
+AttributeTypeAndValue ::= SEQUENCE {
+ type AttributeType,
+ value AttributeValue }
+
+-- suggested naming attributes: Definition of the following
+-- information object set may be augmented to meet local
+-- requirements. Note that deleting members of the set may
+-- prevent interoperability with conforming implementations.
+-- presented in pairs: the AttributeType followed by the
+-- type definition for the corresponding AttributeValue
+--Arc for standard naming attributes
+id-at OBJECT IDENTIFIER ::= { joint-iso-ccitt(2) ds(5) 4 }
+
+-- Naming attributes of type X520name
+
+id-at-name AttributeType ::= { id-at 41 }
+id-at-surname AttributeType ::= { id-at 4 }
+id-at-givenName AttributeType ::= { id-at 42 }
+id-at-initials AttributeType ::= { id-at 43 }
+id-at-generationQualifier AttributeType ::= { id-at 44 }
+
+X520name ::= CHOICE {
+ teletexString TeletexString (SIZE (1..ub-name)),
+ printableString PrintableString (SIZE (1..ub-name)),
+ universalString UniversalString (SIZE (1..ub-name)),
+ utf8String UTF8String (SIZE (1..ub-name)),
+ bmpString BMPString (SIZE (1..ub-name)) }
+
+-- Naming attributes of type X520CommonName
+
+id-at-commonName AttributeType ::= { id-at 3 }
+
+X520CommonName ::= CHOICE {
+ teletexString TeletexString (SIZE (1..ub-common-name)),
+ printableString PrintableString (SIZE (1..ub-common-name)),
+ universalString UniversalString (SIZE (1..ub-common-name)),
+ utf8String UTF8String (SIZE (1..ub-common-name)),
+ bmpString BMPString (SIZE (1..ub-common-name)) }
+
+-- Naming attributes of type X520LocalityName
+
+id-at-localityName AttributeType ::= { id-at 7 }
+
+X520LocalityName ::= CHOICE {
+ teletexString TeletexString (SIZE (1..ub-locality-name)),
+ printableString PrintableString (SIZE (1..ub-locality-name)),
+ universalString UniversalString (SIZE (1..ub-locality-name)),
+ utf8String UTF8String (SIZE (1..ub-locality-name)),
+ bmpString BMPString (SIZE (1..ub-locality-name)) }
+
+-- Naming attributes of type X520StateOrProvinceName
+
+id-at-stateOrProvinceName AttributeType ::= { id-at 8 }
+
+X520StateOrProvinceName ::= CHOICE {
+ teletexString TeletexString (SIZE (1..ub-state-name)),
+ printableString PrintableString (SIZE (1..ub-state-name)),
+ universalString UniversalString (SIZE (1..ub-state-name)),
+ utf8String UTF8String (SIZE (1..ub-state-name)),
+ bmpString BMPString (SIZE(1..ub-state-name)) }
+
+-- Naming attributes of type X520OrganizationName
+
+id-at-organizationName AttributeType ::= { id-at 10 }
+
+X520OrganizationName ::= CHOICE {
+ teletexString TeletexString
+ (SIZE (1..ub-organization-name)),
+ printableString PrintableString
+ (SIZE (1..ub-organization-name)),
+ universalString UniversalString
+ (SIZE (1..ub-organization-name)),
+ utf8String UTF8String
+ (SIZE (1..ub-organization-name)),
+ bmpString BMPString
+ (SIZE (1..ub-organization-name)) }
+
+-- Naming attributes of type X520OrganizationalUnitName
+
+id-at-organizationalUnitName AttributeType ::= { id-at 11 }
+
+X520OrganizationalUnitName ::= CHOICE {
+ teletexString TeletexString
+ (SIZE (1..ub-organizational-unit-name)),
+ printableString PrintableString
+ (SIZE (1..ub-organizational-unit-name)),
+ universalString UniversalString
+ (SIZE (1..ub-organizational-unit-name)),
+ utf8String UTF8String
+ (SIZE (1..ub-organizational-unit-name)),
+ bmpString BMPString
+ (SIZE (1..ub-organizational-unit-name)) }
+
+-- Naming attributes of type X520Title
+
+id-at-title AttributeType ::= { id-at 12 }
+
+X520Title ::= CHOICE {
+ teletexString TeletexString (SIZE (1..ub-title)),
+ printableString PrintableString (SIZE (1..ub-title)),
+ universalString UniversalString (SIZE (1..ub-title)),
+ utf8String UTF8String (SIZE (1..ub-title)),
+ bmpString BMPString (SIZE (1..ub-title)) }
+
+-- Naming attributes of type X520dnQualifier
+
+id-at-dnQualifier AttributeType ::= { id-at 46 }
+
+X520dnQualifier ::= PrintableString
+
+-- Naming attributes of type X520countryName (digraph from IS 3166)
+
+id-at-countryName AttributeType ::= { id-at 6 }
+
+X520countryName ::= PrintableString (SIZE (2))
+
+-- Naming attributes of type X520SerialNumber
+
+id-at-serialNumber AttributeType ::= { id-at 5 }
+
+X520SerialNumber ::= PrintableString (SIZE (1..ub-serial-number))
+
+-- Naming attributes of type X520Pseudonym
+
+id-at-pseudonym AttributeType ::= { id-at 65 }
+
+X520Pseudonym ::= CHOICE {
+ teletexString TeletexString (SIZE (1..ub-pseudonym)),
+ printableString PrintableString (SIZE (1..ub-pseudonym)),
+ universalString UniversalString (SIZE (1..ub-pseudonym)),
+ utf8String UTF8String (SIZE (1..ub-pseudonym)),
+ bmpString BMPString (SIZE (1..ub-pseudonym)) }
+
+-- Naming attributes of type DomainComponent (from RFC 2247)
+
+id-domainComponent AttributeType ::=
+ { 0 9 2342 19200300 100 1 25 }
+
+DomainComponent ::= IA5String
+
+-- Legacy attributes
+
+pkcs-9 OBJECT IDENTIFIER ::=
+ { iso(1) member-body(2) us(840) rsadsi(113549) pkcs(1) 9 }
+
+id-emailAddress AttributeType ::= { pkcs-9 1 }
+
+EmailAddress ::= IA5String (SIZE (1..ub-emailaddress-length))
+
+-- naming data types --
+
+Name ::= CHOICE { -- only one possibility for now --
+ rdnSequence RDNSequence }
+
+RDNSequence ::= SEQUENCE OF RelativeDistinguishedName
+
+DistinguishedName ::= RDNSequence
+
+RelativeDistinguishedName ::=
+ SET SIZE (1 .. MAX) OF AttributeTypeAndValue
+
+-- Directory string type --
+
+DirectoryString ::= CHOICE {
+ teletexString TeletexString (SIZE (1..MAX)),
+ printableString PrintableString (SIZE (1..MAX)),
+ universalString UniversalString (SIZE (1..MAX)),
+ utf8String UTF8String (SIZE (1..MAX)),
+ bmpString BMPString (SIZE (1..MAX)) }
+
+-- certificate and CRL specific structures begin here
+
+Certificate ::= SEQUENCE {
+ tbsCertificate TBSCertificate,
+ signatureAlgorithm AlgorithmIdentifier,
+ signature BIT STRING }
+
+TBSCertificate ::= SEQUENCE {
+ version [0] Version DEFAULT v1,
+ serialNumber CertificateSerialNumber,
+ signature AlgorithmIdentifier,
+ 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 }
+
+UniqueIdentifier ::= BIT STRING
+
+SubjectPublicKeyInfo ::= SEQUENCE {
+ algorithm AlgorithmIdentifier,
+ subjectPublicKey BIT STRING }
+
+Extensions ::= SEQUENCE SIZE (1..MAX) OF Extension
+
+Extension ::= SEQUENCE {
+ extnID OBJECT IDENTIFIER,
+ critical BOOLEAN DEFAULT FALSE,
+ extnValue OCTET STRING }
+
+-- CRL structures
+
+CertificateList ::= SEQUENCE {
+ tbsCertList TBSCertList,
+ signatureAlgorithm AlgorithmIdentifier,
+ signature BIT STRING }
+
+TBSCertList ::= SEQUENCE {
+ version Version OPTIONAL,
+ -- if present, MUST be v2
+ signature AlgorithmIdentifier,
+ issuer Name,
+ thisUpdate Time,
+ nextUpdate Time OPTIONAL,
+ revokedCertificates SEQUENCE OF SEQUENCE {
+ userCertificate CertificateSerialNumber,
+ revocationDate Time,
+ crlEntryExtensions Extensions OPTIONAL
+ -- if present, MUST be v2
+ } OPTIONAL,
+ crlExtensions [0] Extensions OPTIONAL }
+ -- if present, MUST be v2
+
+-- Version, Time, CertificateSerialNumber, and Extensions were
+-- defined earlier for use in the certificate structure
+
+AlgorithmIdentifier ::= SEQUENCE {
+ algorithm OBJECT IDENTIFIER,
+ parameters ANY DEFINED BY algorithm OPTIONAL }
+ -- contains a value of the type
+ -- registered for use with the
+ -- algorithm object identifier value
+
+-- X.400 address syntax starts here
+
+ORAddress ::= SEQUENCE {
+ built-in-standard-attributes BuiltInStandardAttributes,
+ built-in-domain-defined-attributes
+ BuiltInDomainDefinedAttributes OPTIONAL,
+ -- see also teletex-domain-defined-attributes
+ extension-attributes ExtensionAttributes OPTIONAL }
+
+-- Built-in Standard Attributes
+
+BuiltInStandardAttributes ::= SEQUENCE {
+ country-name CountryName OPTIONAL,
+ administration-domain-name AdministrationDomainName OPTIONAL,
+ network-address [0] IMPLICIT NetworkAddress OPTIONAL,
+ -- see also extended-network-address
+ terminal-identifier [1] IMPLICIT TerminalIdentifier OPTIONAL,
+ private-domain-name [2] PrivateDomainName OPTIONAL,
+ organization-name [3] IMPLICIT OrganizationName OPTIONAL,
+ -- see also teletex-organization-name
+ numeric-user-identifier [4] IMPLICIT NumericUserIdentifier
+ OPTIONAL,
+ personal-name [5] IMPLICIT PersonalName OPTIONAL,
+ -- see also teletex-personal-name
+ organizational-unit-names [6] IMPLICIT OrganizationalUnitNames
+ OPTIONAL }
+ -- see also teletex-organizational-unit-names
+
+CountryName ::= [APPLICATION 1] CHOICE {
+ x121-dcc-code NumericString
+ (SIZE (ub-country-name-numeric-length)),
+ iso-3166-alpha2-code PrintableString
+ (SIZE (ub-country-name-alpha-length)) }
+
+AdministrationDomainName ::= [APPLICATION 2] CHOICE {
+ numeric NumericString (SIZE (0..ub-domain-name-length)),
+ printable PrintableString (SIZE (0..ub-domain-name-length)) }
+
+NetworkAddress ::= X121Address -- see also extended-network-address
+
+X121Address ::= NumericString (SIZE (1..ub-x121-address-length))
+
+TerminalIdentifier ::= PrintableString (SIZE
+(1..ub-terminal-id-length))
+
+PrivateDomainName ::= CHOICE {
+ numeric NumericString (SIZE (1..ub-domain-name-length)),
+ printable PrintableString (SIZE (1..ub-domain-name-length)) }
+
+OrganizationName ::= PrintableString
+ (SIZE (1..ub-organization-name-length))
+ -- see also teletex-organization-name
+
+NumericUserIdentifier ::= NumericString
+ (SIZE (1..ub-numeric-user-id-length))
+
+PersonalName ::= SET {
+ surname [0] IMPLICIT PrintableString
+ (SIZE (1..ub-surname-length)),
+ given-name [1] IMPLICIT PrintableString
+ (SIZE (1..ub-given-name-length)) OPTIONAL,
+ initials [2] IMPLICIT PrintableString
+ (SIZE (1..ub-initials-length)) OPTIONAL,
+ generation-qualifier [3] IMPLICIT PrintableString
+ (SIZE (1..ub-generation-qualifier-length))
+ OPTIONAL }
+ -- see also teletex-personal-name
+
+OrganizationalUnitNames ::= SEQUENCE SIZE (1..ub-organizational-units)
+ OF OrganizationalUnitName
+ -- see also teletex-organizational-unit-names
+
+OrganizationalUnitName ::= PrintableString (SIZE
+ (1..ub-organizational-unit-name-length))
+
+-- Built-in Domain-defined Attributes
+
+BuiltInDomainDefinedAttributes ::= SEQUENCE SIZE
+ (1..ub-domain-defined-attributes) OF
+ BuiltInDomainDefinedAttribute
+
+BuiltInDomainDefinedAttribute ::= SEQUENCE {
+ type PrintableString (SIZE
+ (1..ub-domain-defined-attribute-type-length)),
+ value PrintableString (SIZE
+ (1..ub-domain-defined-attribute-value-length)) }
+
+-- Extension Attributes
+
+ExtensionAttributes ::= SET SIZE (1..ub-extension-attributes) OF
+ ExtensionAttribute
+
+ExtensionAttribute ::= SEQUENCE {
+ extension-attribute-type [0] IMPLICIT INTEGER
+ (0..ub-extension-attributes),
+ extension-attribute-value [1]
+ ANY DEFINED BY extension-attribute-type }
+
+-- Extension types and attribute values
+
+common-name INTEGER ::= 1
+
+CommonName ::= PrintableString (SIZE (1..ub-common-name-length))
+
+teletex-common-name INTEGER ::= 2
+
+TeletexCommonName ::= TeletexString (SIZE (1..ub-common-name-length))
+
+teletex-organization-name INTEGER ::= 3
+
+TeletexOrganizationName ::=
+ TeletexString (SIZE (1..ub-organization-name-length))
+
+teletex-personal-name INTEGER ::= 4
+
+TeletexPersonalName ::= SET {
+ surname [0] IMPLICIT TeletexString
+ (SIZE (1..ub-surname-length)),
+ given-name [1] IMPLICIT TeletexString
+ (SIZE (1..ub-given-name-length)) OPTIONAL,
+ initials [2] IMPLICIT TeletexString
+ (SIZE (1..ub-initials-length)) OPTIONAL,
+ generation-qualifier [3] IMPLICIT TeletexString
+ (SIZE (1..ub-generation-qualifier-length))
+ OPTIONAL }
+
+teletex-organizational-unit-names INTEGER ::= 5
+
+TeletexOrganizationalUnitNames ::= SEQUENCE SIZE
+ (1..ub-organizational-units) OF TeletexOrganizationalUnitName
+
+TeletexOrganizationalUnitName ::= TeletexString
+ (SIZE (1..ub-organizational-unit-name-length))
+
+pds-name INTEGER ::= 7
+
+PDSName ::= PrintableString (SIZE (1..ub-pds-name-length))
+
+physical-delivery-country-name INTEGER ::= 8
+
+PhysicalDeliveryCountryName ::= CHOICE {
+ x121-dcc-code NumericString (SIZE
+(ub-country-name-numeric-length)),
+ iso-3166-alpha2-code PrintableString
+ (SIZE (ub-country-name-alpha-length)) }
+
+postal-code INTEGER ::= 9
+
+PostalCode ::= CHOICE {
+ numeric-code NumericString (SIZE (1..ub-postal-code-length)),
+ printable-code PrintableString (SIZE (1..ub-postal-code-length)) }
+
+physical-delivery-office-name INTEGER ::= 10
+
+PhysicalDeliveryOfficeName ::= PDSParameter
+
+physical-delivery-office-number INTEGER ::= 11
+
+PhysicalDeliveryOfficeNumber ::= PDSParameter
+
+extension-OR-address-components INTEGER ::= 12
+
+ExtensionORAddressComponents ::= PDSParameter
+
+physical-delivery-personal-name INTEGER ::= 13
+
+PhysicalDeliveryPersonalName ::= PDSParameter
+
+physical-delivery-organization-name INTEGER ::= 14
+
+PhysicalDeliveryOrganizationName ::= PDSParameter
+
+extension-physical-delivery-address-components INTEGER ::= 15
+
+ExtensionPhysicalDeliveryAddressComponents ::= PDSParameter
+
+unformatted-postal-address INTEGER ::= 16
+
+UnformattedPostalAddress ::= SET {
+ printable-address SEQUENCE SIZE (1..ub-pds-physical-address-lines)
+ OF PrintableString (SIZE (1..ub-pds-parameter-length))
+ OPTIONAL,
+ teletex-string TeletexString
+ (SIZE (1..ub-unformatted-address-length)) OPTIONAL }
+
+street-address INTEGER ::= 17
+
+StreetAddress ::= PDSParameter
+
+post-office-box-address INTEGER ::= 18
+
+PostOfficeBoxAddress ::= PDSParameter
+
+poste-restante-address INTEGER ::= 19
+
+PosteRestanteAddress ::= PDSParameter
+
+unique-postal-name INTEGER ::= 20
+
+UniquePostalName ::= PDSParameter
+
+local-postal-attributes INTEGER ::= 21
+
+LocalPostalAttributes ::= PDSParameter
+
+PDSParameter ::= SET {
+ printable-string PrintableString
+ (SIZE(1..ub-pds-parameter-length)) OPTIONAL,
+ teletex-string TeletexString
+ (SIZE(1..ub-pds-parameter-length)) OPTIONAL }
+
+extended-network-address INTEGER ::= 22
+
+ExtendedNetworkAddress ::= CHOICE {
+ e163-4-address SEQUENCE {
+ number [0] IMPLICIT NumericString
+ (SIZE (1..ub-e163-4-number-length)),
+ sub-address [1] IMPLICIT NumericString
+ (SIZE (1..ub-e163-4-sub-address-length))
+ OPTIONAL },
+ psap-address [0] IMPLICIT PresentationAddress }
+
+PresentationAddress ::= SEQUENCE {
+ pSelector [0] EXPLICIT OCTET STRING OPTIONAL,
+ sSelector [1] EXPLICIT OCTET STRING OPTIONAL,
+ tSelector [2] EXPLICIT OCTET STRING OPTIONAL,
+ nAddresses [3] EXPLICIT SET SIZE (1..MAX) OF OCTET STRING }
+
+terminal-type INTEGER ::= 23
+
+TerminalType ::= INTEGER {
+ telex (3),
+ teletex (4),
+ g3-facsimile (5),
+ g4-facsimile (6),
+ ia5-terminal (7),
+ videotex (8) } (0..ub-integer-options)
+
+-- Extension Domain-defined Attributes
+
+teletex-domain-defined-attributes INTEGER ::= 6
+
+TeletexDomainDefinedAttributes ::= SEQUENCE SIZE
+ (1..ub-domain-defined-attributes) OF TeletexDomainDefinedAttribute
+
+TeletexDomainDefinedAttribute ::= SEQUENCE {
+ type TeletexString
+ (SIZE (1..ub-domain-defined-attribute-type-length)),
+ value TeletexString
+ (SIZE (1..ub-domain-defined-attribute-value-length)) }
+
+-- specifications of Upper Bounds MUST be regarded as mandatory
+-- from Annex B of ITU-T X.411 Reference Definition of MTS Parameter
+-- Upper Bounds
+
+-- Upper Bounds
+ub-name INTEGER ::= 32768
+ub-common-name INTEGER ::= 64
+ub-locality-name INTEGER ::= 128
+ub-state-name INTEGER ::= 128
+ub-organization-name INTEGER ::= 64
+ub-organizational-unit-name INTEGER ::= 64
+ub-title INTEGER ::= 64
+ub-serial-number INTEGER ::= 64
+ub-match INTEGER ::= 128
+ub-emailaddress-length INTEGER ::= 128
+ub-common-name-length INTEGER ::= 64
+ub-country-name-alpha-length INTEGER ::= 2
+ub-country-name-numeric-length INTEGER ::= 3
+ub-domain-defined-attributes INTEGER ::= 4
+ub-domain-defined-attribute-type-length INTEGER ::= 8
+ub-domain-defined-attribute-value-length INTEGER ::= 128
+ub-domain-name-length INTEGER ::= 16
+ub-extension-attributes INTEGER ::= 256
+ub-e163-4-number-length INTEGER ::= 15
+ub-e163-4-sub-address-length INTEGER ::= 40
+ub-generation-qualifier-length INTEGER ::= 3
+ub-given-name-length INTEGER ::= 16
+ub-initials-length INTEGER ::= 5
+ub-integer-options INTEGER ::= 256
+ub-numeric-user-id-length INTEGER ::= 32
+ub-organization-name-length INTEGER ::= 64
+ub-organizational-unit-name-length INTEGER ::= 32
+ub-organizational-units INTEGER ::= 4
+ub-pds-name-length INTEGER ::= 16
+ub-pds-parameter-length INTEGER ::= 30
+ub-pds-physical-address-lines INTEGER ::= 6
+ub-postal-code-length INTEGER ::= 16
+ub-pseudonym INTEGER ::= 128
+ub-surname-length INTEGER ::= 40
+ub-terminal-id-length INTEGER ::= 24
+ub-unformatted-address-length INTEGER ::= 180
+ub-x121-address-length INTEGER ::= 16
+
+-- Note - upper bounds on string types, such as TeletexString, are
+-- measured in characters. Excepting PrintableString or IA5String, a
+-- significantly greater number of octets will be required to hold
+-- such a value. As a minimum, 16 octets, or twice the specified
+-- upper bound, whichever is the larger, should be allowed for
+-- TeletexString. For UTF8String or UniversalString at least four
+-- times the upper bound should be allowed.
+
+END
diff --git a/lib/asn1/test/asn1_SUITE_data/PKIX1Explicit93.asn1 b/lib/asn1/test/asn1_SUITE_data/PKIX1Explicit93.asn1
new file mode 100644
index 0000000000..714a682160
--- /dev/null
+++ b/lib/asn1/test/asn1_SUITE_data/PKIX1Explicit93.asn1
@@ -0,0 +1,779 @@
+PKIX1Explicit93 {iso(1) identified-organization(3) dod(6) internet(1)
+ security(5) mechanisms(5) pkix(7) id-mod(0) id-pkix1-explicit-93(3)}
+
+
+DEFINITIONS EXPLICIT TAGS ::=
+
+BEGIN
+
+-- EXPORTS ALL --
+
+IMPORTS
+ authorityKeyIdentifier, subjectKeyIdentifier, keyUsage,
+ extendedKeyUsage, privateKeyUsagePeriod, certificatePolicies,
+ policyMappings, subjectAltName, issuerAltName,
+ basicConstraints, nameConstraints, policyConstraints,
+ cRLDistributionPoints, subjectDirectoryAttributes,
+ cRLNumber, reasonCode, instructionCode, invalidityDate,
+ issuingDistributionPoint, certificateIssuer,
+ deltaCRLIndicator, authorityInfoAccess, id-ce
+ FROM PKIX1Implicit93 {iso(1) identified-organization(3)
+ dod(6) internet(1) security(5) mechanisms(5) pkix(7)
+ id-mod(0) id-pkix1-implicit-93(4)} ;
+
+--
+ -- Locally defined OIDs --
+
+id-pkix OBJECT IDENTIFIER ::=
+ { iso(1) identified-organization(3) dod(6) internet(1)
+ security(5) mechanisms(5) pkix(7) }
+
+-- PKIX arcs
+-- arc for private certificate extensions
+id-pe OBJECT IDENTIFIER ::= { id-pkix 1 }
+ -- arc for policy qualifier types
+id-qt OBJECT IDENTIFIER ::= { id-pkix 2 }
+-- arc for extended key purpose OIDS
+id-kp OBJECT IDENTIFIER ::= { id-pkix 3 }
+-- arc for access descriptors
+id-ad OBJECT IDENTIFIER ::= { id-pkix 48 }
+
+-- policyQualifierIds for Internet policy qualifiers
+id-qt-cps OBJECT IDENTIFIER ::= { id-qt 1 }
+ -- OID for CPS qualifier
+
+id-qt-unotice OBJECT IDENTIFIER ::= { id-qt 2 }
+ -- OID for user notice qualifier
+
+-- based on excerpts from AuthenticationFramework
+-- {joint-iso-ccitt ds(5) modules(1) authenticationFramework(7) 2}
+
+ -- Public Key Certificate --
+
+Certificate ::= SIGNED { SEQUENCE {
+ version [0] Version DEFAULT v1,
+ serialNumber CertificateSerialNumber,
+ signature AlgorithmIdentifier,
+ issuer Name,
+ validity Validity,
+ subject Name,
+ subjectPublicKeyInfo SubjectPublicKeyInfo,
+ issuerUniqueIdentifier [1] IMPLICIT UniqueIdentifier OPTIONAL,
+ ---if present, version shall be v2 or v3--
+ subjectUniqueIdentifier [2] IMPLICIT UniqueIdentifier OPTIONAL,
+ ---if present, version shall be v2 or v3--
+ extensions [3] Extensions OPTIONAL
+ --if present, version shall be v3--} }
+
+UniqueIdentifier ::= BIT STRING
+
+Version ::= INTEGER { v1(0), v2(1), v3(2) }
+
+CertificateSerialNumber ::= INTEGER
+
+Validity ::= SEQUENCE {
+ notBefore Time,
+ notAfter Time }
+
+Time ::= CHOICE {
+ utcTime UTCTime,
+ generalTime GeneralizedTime }
+
+SubjectPublicKeyInfo ::= SEQUENCE{
+ algorithm AlgorithmIdentifier,
+ subjectPublicKey BIT STRING}
+
+Extensions ::= SEQUENCE SIZE (1..MAX) OF Extension
+
+Extension ::= SEQUENCE {
+ extnId EXTENSION.&id ({ExtensionSet}),
+ critical BOOLEAN DEFAULT FALSE,
+ extnValue OCTET STRING }
+ -- contains a DER encoding of a value of type
+ -- &ExtnType for the
+ -- extension object identified by extnId --
+
+-- The following information object set is defined to constrain the
+-- set of legal certificate extensions.
+
+ExtensionSet EXTENSION ::= { authorityKeyIdentifier |
+ subjectKeyIdentifier |
+ keyUsage |
+ extendedKeyUsage |
+ privateKeyUsagePeriod |
+ certificatePolicies |
+ policyMappings |
+ subjectAltName |
+ issuerAltName |
+ basicConstraints |
+ nameConstraints |
+ policyConstraints |
+ cRLDistributionPoints |
+ subjectDirectoryAttributes |
+ authorityInfoAccess }
+
+EXTENSION ::= CLASS {
+ &id OBJECT IDENTIFIER UNIQUE,
+ &ExtnType }
+WITH SYNTAX {
+ SYNTAX &ExtnType
+ IDENTIFIED BY &id }
+
+ -- Certificate Revocation List --
+
+CertificateList ::= SIGNED { SEQUENCE {
+ version Version OPTIONAL, -- if present, shall be v2
+ signature AlgorithmIdentifier,
+ issuer Name,
+ thisUpdate Time,
+ nextUpdate Time OPTIONAL,
+ revokedCertificates SEQUENCE OF SEQUENCE {
+ userCertificate CertificateSerialNumber,
+ revocationDate Time,
+ crlEntryExtensions EntryExtensions OPTIONAL } OPTIONAL,
+ crlExtensions [0] CRLExtensions OPTIONAL }}
+
+CRLExtensions ::= SEQUENCE SIZE (1..MAX) OF CRLExtension
+
+CRLExtension ::= SEQUENCE {
+ extnId EXTENSION.&id ({CRLExtensionSet}),
+ critical BOOLEAN DEFAULT FALSE,
+ extnValue OCTET STRING }
+ -- contains a DER encoding of a value of type
+ -- &ExtnType for the
+ -- extension object identified by extnId --
+
+-- The following information object set is defined to constrain the
+-- set of legal CRL extensions.
+
+CRLExtensionSet EXTENSION ::= { authorityKeyIdentifier |
+ issuerAltName |
+ cRLNumber |
+ deltaCRLIndicator |
+ issuingDistributionPoint }
+
+-- EXTENSION defined above for certificates
+
+EntryExtensions ::= SEQUENCE SIZE (1..MAX) OF EntryExtension
+
+EntryExtension ::= SEQUENCE {
+ extnId EXTENSION.&id ({EntryExtensionSet}),
+ critical BOOLEAN DEFAULT FALSE,
+ extnValue OCTET STRING }
+ -- contains a DER encoding of a value of type
+ -- &ExtnType for the
+ -- extension object identified by extnId --
+
+-- The following information object set is defined to constrain the
+-- set of legal CRL entry extensions.
+
+EntryExtensionSet EXTENSION ::= { reasonCode |
+ instructionCode |
+ invalidityDate |
+ certificateIssuer }
+
+ -- information object classes used in the defintion --
+ -- of certificates and CRLs --
+
+-- Parameterized Type SIGNED --
+
+ SIGNED { ToBeSigned } ::= SEQUENCE {
+ toBeSigned ToBeSigned,
+ algorithm AlgorithmIdentifier,
+ signature BIT STRING
+ }
+
+-- Definition of AlgorithmIdentifier
+-- ISO definition was:
+--
+-- AlgorithmIdentifier ::= SEQUENCE {
+-- algorithm ALGORITHM.&id({SupportedAlgorithms}),
+-- parameters ALGORITHM.&Type({SupportedAlgorithms}
+-- { @algorithm}) OPTIONAL }
+-- Definition of ALGORITHM
+-- ALGORITHM ::= TYPE-IDENTIFIER
+
+-- The following PKIX definition replaces the X.509 definition
+--
+
+AlgorithmIdentifier ::= SEQUENCE {
+ algorithm ALGORITHM-ID.&id({SupportedAlgorithms}),
+ parameters ALGORITHM-ID.&Type({SupportedAlgorithms}
+ { @algorithm}) OPTIONAL }
+
+-- Definition of ALGORITHM-ID
+
+ ALGORITHM-ID ::= CLASS {
+ &id OBJECT IDENTIFIER UNIQUE,
+ &Type OPTIONAL
+ }
+ WITH SYNTAX { OID &id [PARMS &Type] }
+
+-- The definition of SupportedAlgorithms may be modified as this
+-- document does not specify a mandatory algorithm set. In addition,
+-- the set is specified as extensible, since additional algorithms
+-- may be supported
+
+SupportedAlgorithms ALGORITHM-ID ::= { ..., -- extensible
+ rsaPublicKey |
+ rsaSHA-1 |
+ rsaMD5 |
+ rsaMD2 |
+ dssPublicKey |
+ dsaSHA-1 |
+ dhPublicKey }
+
+-- OIDs and parameter structures for ALGORITHM-IDs used
+-- in this specification
+
+rsaPublicKey ALGORITHM-ID ::= { OID rsaEncryption PARMS NULL }
+
+rsaSHA-1 ALGORITHM-ID ::= { OID sha1WithRSAEncryption PARMS NULL }
+
+rsaMD5 ALGORITHM-ID ::= { OID md5WithRSAEncryption PARMS NULL }
+
+rsaMD2 ALGORITHM-ID ::= { OID md2WithRSAEncryption PARMS NULL }
+
+dssPublicKey ALGORITHM-ID ::= { OID id-dsa PARMS Dss-Parms }
+
+dsaSHA-1 ALGORITHM-ID ::= { OID id-dsa-with-sha1 }
+
+dhPublicKey ALGORITHM-ID ::= {OID dhpublicnumber PARMS DomainParameters}
+
+-- algorithm identifiers and parameter structures
+
+pkcs-1 OBJECT IDENTIFIER ::= {
+ iso(1) member-body(2) us(840) rsadsi(113549) pkcs(1) 1 }
+
+rsaEncryption OBJECT IDENTIFIER ::= { pkcs-1 1 }
+
+md2WithRSAEncryption OBJECT IDENTIFIER ::= { pkcs-1 2 }
+
+md5WithRSAEncryption OBJECT IDENTIFIER ::= { pkcs-1 4 }
+
+sha1WithRSAEncryption OBJECT IDENTIFIER ::= { pkcs-1 5 }
+
+id-dsa-with-sha1 OBJECT IDENTIFIER ::= {
+ iso(1) member-body(2) us(840) x9-57 (10040) x9algorithm(4) 3 }
+
+Dss-Sig-Value ::= SEQUENCE {
+ r INTEGER,
+ s INTEGER }
+
+dhpublicnumber OBJECT IDENTIFIER ::= {
+ iso(1) member-body(2) us(840) ansi-x942(10046) number-type(2) 1 }
+
+DomainParameters ::= SEQUENCE {
+ p INTEGER, -- odd prime, p=jq +1
+ g INTEGER, -- generator, g
+ q INTEGER, -- factor of p-1
+ j INTEGER OPTIONAL, -- subgroup factor, j>= 2
+ validationParms ValidationParms OPTIONAL }
+
+ValidationParms ::= SEQUENCE {
+ seed BIT STRING,
+ pgenCounter INTEGER }
+
+id-dsa OBJECT IDENTIFIER ::= {
+ iso(1) member-body(2) us(840) x9-57(10040) x9algorithm(4) 1 }
+
+Dss-Parms ::= SEQUENCE {
+ p INTEGER,
+ q INTEGER,
+ g INTEGER }
+
+ -- The ASN.1 in this section supports the Name type
+ -- and the directoryAttribute extension
+
+-- attribute data types --
+
+Attribute ::= SEQUENCE {
+ type ATTRIBUTE.&id ({SupportedAttributes}),
+ values SET SIZE (1 .. MAX) OF ATTRIBUTE.&Type
+ ({SupportedAttributes}{@type})}
+
+AttributeTypeAndValue ::= SEQUENCE {
+ type ATTRIBUTE.&id ({SupportedAttributes}),
+ value ATTRIBUTE.&Type ({SupportedAttributes}{@type})}
+
+-- naming data types --
+
+Name ::= CHOICE { -- only one possibility for now --
+ rdnSequence RDNSequence }
+
+RDNSequence ::= SEQUENCE OF RelativeDistinguishedName
+
+RelativeDistinguishedName ::=
+ SET SIZE (1 .. MAX) OF AttributeTypeAndValue
+
+ID ::= OBJECT IDENTIFIER
+
+-- ATTRIBUTE information object class specification
+-- Note: This has been greatly simplified for PKIX !!
+
+ATTRIBUTE ::= CLASS {
+ &Type,
+ &id OBJECT IDENTIFIER UNIQUE }
+WITH SYNTAX {
+ WITH SYNTAX &Type ID &id }
+
+-- suggested naming attributes
+-- Definition of the following information object set may be
+-- augmented to meet local requirements. Note that deleting
+-- members of the set may prevent interoperability with
+-- conforming implementations.
+
+SupportedAttributes ATTRIBUTE ::= {
+ name | commonName | surname | givenName | initials |
+ generationQualifier | dnQualifier | countryName |
+ localityName | stateOrProvinceName | organizationName |
+ organizationalUnitName | title | pkcs9email }
+
+name ATTRIBUTE ::= {
+ WITH SYNTAX DirectoryString { ub-name }
+ ID id-at-name }
+
+commonName ATTRIBUTE ::= {
+ WITH SYNTAX DirectoryString {ub-common-name}
+ ID id-at-commonName }
+
+surname ATTRIBUTE ::= {
+ WITH SYNTAX DirectoryString {ub-name}
+ ID id-at-surname }
+
+givenName ATTRIBUTE ::= {
+ WITH SYNTAX DirectoryString {ub-name}
+ ID id-at-givenName }
+
+initials ATTRIBUTE ::= {
+ WITH SYNTAX DirectoryString {ub-name}
+ ID id-at-initials }
+
+generationQualifier ATTRIBUTE ::= {
+ WITH SYNTAX DirectoryString {ub-name}
+ ID id-at-generationQualifier}
+
+dnQualifier ATTRIBUTE ::= {
+ WITH SYNTAX PrintableString
+ ID id-at-dnQualifier }
+
+
+countryName ATTRIBUTE ::= {
+ WITH SYNTAX PrintableString (SIZE (2))
+ -- IS 3166 codes only
+ ID id-at-countryName }
+
+localityName ATTRIBUTE ::= {
+ WITH SYNTAX DirectoryString {ub-locality-name}
+ ID id-at-localityName }
+
+stateOrProvinceName ATTRIBUTE ::= {
+ WITH SYNTAX DirectoryString {ub-state-name}
+ ID id-at-stateOrProvinceName }
+
+organizationName ATTRIBUTE ::= {
+ WITH SYNTAX DirectoryString {ub-organization-name}
+ ID id-at-organizationName }
+
+organizationalUnitName ATTRIBUTE ::= {
+ WITH SYNTAX DirectoryString {ub-organizational-unit-name}
+ ID id-at-organizationalUnitName }
+
+title ATTRIBUTE ::= {
+ WITH SYNTAX DirectoryString {ub-title}
+ ID id-at-title }
+
+ -- Legacy attributes
+
+pkcs9email ATTRIBUTE ::= {
+ WITH SYNTAX PHGString
+ ID emailAddress }
+
+PHGString ::= IA5String (SIZE(1..ub-emailaddress-length))
+
+pkcs-9 OBJECT IDENTIFIER ::=
+ { iso(1) member-body(2) us(840) rsadsi(113549) pkcs(1) 9 }
+
+emailAddress OBJECT IDENTIFIER ::= { pkcs-9 1 }
+
+ -- object identifiers for Name type and directory attribute support
+
+-- Object identifier assignments --
+
+id-at OBJECT IDENTIFIER ::= {joint-iso-ccitt(2) ds(5) 4}
+
+-- Attributes --
+
+id-at-commonName OBJECT IDENTIFIER ::= {id-at 3}
+id-at-surname OBJECT IDENTIFIER ::= {id-at 4}
+id-at-countryName OBJECT IDENTIFIER ::= {id-at 6}
+id-at-localityName OBJECT IDENTIFIER ::= {id-at 7}
+id-at-stateOrProvinceName OBJECT IDENTIFIER ::= {id-at 8}
+id-at-organizationName OBJECT IDENTIFIER ::= {id-at 10}
+id-at-organizationalUnitName OBJECT IDENTIFIER ::= {id-at 11}
+id-at-title OBJECT IDENTIFIER ::= {id-at 12}
+id-at-name OBJECT IDENTIFIER ::= {id-at 41}
+id-at-givenName OBJECT IDENTIFIER ::= {id-at 42}
+id-at-initials OBJECT IDENTIFIER ::= {id-at 43}
+id-at-generationQualifier OBJECT IDENTIFIER ::= {id-at 44}
+id-at-dnQualifier OBJECT IDENTIFIER ::= {id-at 46}
+
+-- Directory string type, used extensively in Name types --
+
+DirectoryString { INTEGER:maxSize } ::= CHOICE {
+ teletexString TeletexString (SIZE (1..maxSize)),
+ printableString PrintableString (SIZE (1..maxSize)),
+ universalString UniversalString (SIZE (1..maxSize)),
+ bmpString BMPString (SIZE(1..maxSize)),
+ utf8String UTF8String (SIZE(1..maxSize))
+ }
+
+ -- End of ASN.1 for Name type and directory attribute support --
+
+ -- The ASN.1 in this section supports X.400 style names --
+ -- for implementations that use the x400Address component --
+ -- of GeneralName. --
+
+ORAddress ::= SEQUENCE {
+ built-in-standard-attributes BuiltInStandardAttributes,
+ built-in-domain-defined-attributes
+ BuiltInDomainDefinedAttributes OPTIONAL,
+ -- see also teletex-domain-defined-attributes
+ extension-attributes ExtensionAttributes OPTIONAL }
+
+-- The OR-address is semantically absent from the OR-name if the
+-- built-in-standard-attribute sequence is empty and the
+-- built-in-domain-defined-attributes and extension-attributes are
+-- both omitted.
+
+-- Built-in Standard Attributes
+
+BuiltInStandardAttributes ::= SEQUENCE {
+ country-name CountryName OPTIONAL,
+ administration-domain-name AdministrationDomainName OPTIONAL,
+ network-address [0] NetworkAddress OPTIONAL,
+ -- see also extended-network-address
+ terminal-identifier [1] TerminalIdentifier OPTIONAL,
+ private-domain-name [2] PrivateDomainName OPTIONAL,
+ organization-name [3] OrganizationName OPTIONAL,
+ -- see also teletex-organization-name
+ numeric-user-identifier [4] NumericUserIdentifier OPTIONAL,
+ personal-name [5] PersonalName OPTIONAL,
+ -- see also teletex-personal-name
+ organizational-unit-names [6] OrganizationalUnitNames OPTIONAL
+ -- see also teletex-organizational-unit-names -- }
+
+CountryName ::= [APPLICATION 1] CHOICE {
+ x121-dcc-code NumericString
+ (SIZE (ub-country-name-numeric-length)),
+ iso-3166-alpha2-code PrintableString
+ (SIZE (ub-country-name-alpha-length)) }
+
+AdministrationDomainName ::= [APPLICATION 2] CHOICE {
+ numeric NumericString (SIZE (0..ub-domain-name-length)),
+ printable PrintableString (SIZE (0..ub-domain-name-length)) }
+
+NetworkAddress ::= X121Address
+-- see also extended-network-address
+
+
+X121Address ::= NumericString (SIZE (1..ub-x121-address-length))
+
+TerminalIdentifier ::= PrintableString (SIZE (1..ub-terminal-id-length))
+
+PrivateDomainName ::= CHOICE {
+ numeric NumericString (SIZE (1..ub-domain-name-length)),
+ printable PrintableString (SIZE (1..ub-domain-name-length)) }
+
+OrganizationName ::= PrintableString
+ (SIZE (1..ub-organization-name-length))
+-- see also teletex-organization-name
+
+NumericUserIdentifier ::= NumericString
+ (SIZE (1..ub-numeric-user-id-length))
+
+PersonalName ::= SET {
+ surname [0] PrintableString (SIZE (1..ub-surname-length)),
+ given-name [1] PrintableString
+ (SIZE (1..ub-given-name-length)) OPTIONAL,
+ initials [2] PrintableString
+ (SIZE (1..ub-initials-length)) OPTIONAL,
+ generation-qualifier [3] PrintableString
+ (SIZE (1..ub-generation-qualifier-length)) OPTIONAL}
+-- see also teletex-personal-name
+
+OrganizationalUnitNames ::= SEQUENCE SIZE (1..ub-organizational-units)
+ OF OrganizationalUnitName
+-- see also teletex-organizational-unit-names
+
+OrganizationalUnitName ::= PrintableString (SIZE
+ (1..ub-organizational-unit-name-length))
+
+-- Built-in Domain-defined Attributes
+BuiltInDomainDefinedAttributes ::= SEQUENCE SIZE
+ (1..ub-domain-defined-attributes) OF
+ BuiltInDomainDefinedAttribute
+
+BuiltInDomainDefinedAttribute ::= SEQUENCE {
+ type PrintableString (SIZE
+ (1..ub-domain-defined-attribute-type-length)),
+ value PrintableString (SIZE
+ (1..ub-domain-defined-attribute-value-length)) }
+
+-- Extension Attributes
+
+ExtensionAttributes ::= SET SIZE (1..ub-extension-attributes)
+ OF ExtensionAttribute
+ExtensionAttribute ::= SEQUENCE {
+ extension-attribute-type [0] EXTENSION-ATTRIBUTE.&id
+ ({ExtensionAttributeTable}),
+ extension-attribute-value [1] EXTENSION-ATTRIBUTE.&Type
+ ({ExtensionAttributeTable} {@extension-attribute-type}) }
+
+EXTENSION-ATTRIBUTE ::= CLASS {
+ &id INTEGER (0..ub-extension-attributes) UNIQUE,
+ &Type }
+WITH SYNTAX {&Type IDENTIFIED BY &id}
+
+ExtensionAttributeTable EXTENSION-ATTRIBUTE ::= {
+ common-name |
+ teletex-common-name |
+ teletex-organization-name |
+ teletex-personal-name |
+ teletex-organizational-unit-names |
+ teletex-domain-defined-attributes |
+ pds-name |
+ physical-delivery-country-name |
+ postal-code |
+ physical-delivery-office-name |
+ physical-delivery-office-number |
+ extension-OR-address-components |
+ physical-delivery-personal-name |
+ physical-delivery-organization-name |
+ extension-physical-delivery-address-components |
+ unformatted-postal-address |
+ street-address |
+ post-office-box-address |
+ poste-restante-address |
+ unique-postal-name |
+ local-postal-attributes |
+ extended-network-address |
+ terminal-type }
+
+-- Extension Standard Attributes
+
+common-name EXTENSION-ATTRIBUTE ::= {CommonName IDENTIFIED BY 1}
+
+CommonName ::= PrintableString (SIZE (1..ub-common-name-length))
+
+teletex-common-name EXTENSION-ATTRIBUTE ::=
+ {TeletexCommonName IDENTIFIED BY 2}
+
+TeletexCommonName ::= TeletexString (SIZE (1..ub-common-name-length))
+
+teletex-organization-name EXTENSION-ATTRIBUTE ::=
+ {TeletexOrganizationName IDENTIFIED BY 3}
+
+TeletexOrganizationName ::=
+ TeletexString (SIZE (1..ub-organization-name-length))
+
+teletex-personal-name EXTENSION-ATTRIBUTE ::=
+ {TeletexPersonalName IDENTIFIED BY 4}
+
+TeletexPersonalName ::= SET {
+ surname [0] TeletexString (SIZE (1..ub-surname-length)),
+ given-name [1] TeletexString
+ (SIZE (1..ub-given-name-length)) OPTIONAL,
+ initials [2] TeletexString (SIZE (1..ub-initials-length)) OPTIONAL,
+ generation-qualifier [3] TeletexString (SIZE
+ (1..ub-generation-qualifier-length)) OPTIONAL }
+
+teletex-organizational-unit-names EXTENSION-ATTRIBUTE ::=
+ {TeletexOrganizationalUnitNames IDENTIFIED BY 5}
+
+TeletexOrganizationalUnitNames ::= SEQUENCE SIZE
+ (1..ub-organizational-units) OF TeletexOrganizationalUnitName
+
+TeletexOrganizationalUnitName ::= TeletexString
+ (SIZE (1..ub-organizational-unit-name-length))
+
+pds-name EXTENSION-ATTRIBUTE ::= {PDSName IDENTIFIED BY 7}
+
+PDSName ::= PrintableString (SIZE (1..ub-pds-name-length))
+
+physical-delivery-country-name EXTENSION-ATTRIBUTE ::=
+ {PhysicalDeliveryCountryName IDENTIFIED BY 8}
+
+PhysicalDeliveryCountryName ::= CHOICE {
+ x121-dcc-code NumericString (SIZE (ub-country-name-numeric-length)),
+ iso-3166-alpha2-code PrintableString
+ (SIZE (ub-country-name-alpha-length)) }
+
+postal-code EXTENSION-ATTRIBUTE ::= {PostalCode IDENTIFIED BY 9}
+
+PostalCode ::= CHOICE {
+ numeric-code NumericString (SIZE (1..ub-postal-code-length)),
+ printable-code PrintableString (SIZE (1..ub-postal-code-length)) }
+
+physical-delivery-office-name EXTENSION-ATTRIBUTE ::=
+ {PhysicalDeliveryOfficeName IDENTIFIED BY 10}
+
+PhysicalDeliveryOfficeName ::= PDSParameter
+
+physical-delivery-office-number EXTENSION-ATTRIBUTE ::=
+ {PhysicalDeliveryOfficeNumber IDENTIFIED BY 11}
+
+PhysicalDeliveryOfficeNumber ::= PDSParameter
+
+extension-OR-address-components EXTENSION-ATTRIBUTE ::=
+ {ExtensionORAddressComponents IDENTIFIED BY 12}
+
+ExtensionORAddressComponents ::= PDSParameter
+
+physical-delivery-personal-name EXTENSION-ATTRIBUTE ::=
+ {PhysicalDeliveryPersonalName IDENTIFIED BY 13}
+
+PhysicalDeliveryPersonalName ::= PDSParameter
+
+physical-delivery-organization-name EXTENSION-ATTRIBUTE ::=
+ {PhysicalDeliveryOrganizationName IDENTIFIED BY 14}
+
+PhysicalDeliveryOrganizationName ::= PDSParameter
+
+extension-physical-delivery-address-components EXTENSION-ATTRIBUTE ::=
+ {ExtensionPhysicalDeliveryAddressComponents IDENTIFIED BY 15}
+
+ExtensionPhysicalDeliveryAddressComponents ::= PDSParameter
+
+unformatted-postal-address EXTENSION-ATTRIBUTE ::=
+ {UnformattedPostalAddress IDENTIFIED BY 16}
+
+UnformattedPostalAddress ::= SET {
+ printable-address SEQUENCE SIZE (1..ub-pds-physical-address-lines) OF
+ PrintableString (SIZE (1..ub-pds-parameter-length)) OPTIONAL,
+ teletex-string TeletexString (SIZE
+ (1..ub-unformatted-address-length)) OPTIONAL }
+
+street-address EXTENSION-ATTRIBUTE ::=
+ {StreetAddress IDENTIFIED BY 17}
+
+StreetAddress ::= PDSParameter
+
+post-office-box-address EXTENSION-ATTRIBUTE ::=
+ {PostOfficeBoxAddress IDENTIFIED BY 18}
+
+PostOfficeBoxAddress ::= PDSParameter
+
+poste-restante-address EXTENSION-ATTRIBUTE ::=
+ {PosteRestanteAddress IDENTIFIED BY 19}
+
+PosteRestanteAddress ::= PDSParameter
+
+unique-postal-name EXTENSION-ATTRIBUTE ::=
+ {UniquePostalName IDENTIFIED BY 20}
+
+UniquePostalName ::= PDSParameter
+
+local-postal-attributes EXTENSION-ATTRIBUTE ::=
+ {LocalPostalAttributes IDENTIFIED BY 21}
+
+LocalPostalAttributes ::= PDSParameter
+
+PDSParameter ::= SET {
+ printable-string PrintableString
+ (SIZE(1..ub-pds-parameter-length)) OPTIONAL,
+ teletex-string TeletexString
+ (SIZE(1..ub-pds-parameter-length)) OPTIONAL }
+
+extended-network-address EXTENSION-ATTRIBUTE ::=
+ {ExtendedNetworkAddress IDENTIFIED BY 22}
+
+ExtendedNetworkAddress ::= CHOICE {
+ e163-4-address SEQUENCE {
+ number [0] NumericString
+ (SIZE (1..ub-e163-4-number-length)),
+ sub-address [1] NumericString
+ (SIZE (1..ub-e163-4-sub-address-length)) OPTIONAL},
+ psap-address [0] PresentationAddress }
+
+PresentationAddress ::= SEQUENCE {
+ pSelector [0] EXPLICIT OCTET STRING OPTIONAL,
+ sSelector [1] EXPLICIT OCTET STRING OPTIONAL,
+ tSelector [2] EXPLICIT OCTET STRING OPTIONAL,
+ nAddresses [3] EXPLICIT SET SIZE (1..MAX) OF OCTET STRING}
+
+
+terminal-type EXTENSION-ATTRIBUTE ::= {TerminalType IDENTIFIED BY 23}
+
+TerminalType ::= INTEGER {
+ telex (3),
+ teletex (4),
+ g3-facsimile (5),
+ g4-facsimile (6),
+ ia5-terminal (7),
+ videotex (8) } (0..ub-integer-options)
+
+-- Extension Domain-defined Attributes
+
+teletex-domain-defined-attributes EXTENSION-ATTRIBUTE ::=
+ {TeletexDomainDefinedAttributes IDENTIFIED BY 6}
+
+TeletexDomainDefinedAttributes ::= SEQUENCE SIZE
+ (1..ub-domain-defined-attributes) OF TeletexDomainDefinedAttribute
+
+TeletexDomainDefinedAttribute ::= SEQUENCE {
+ type TeletexString
+ (SIZE (1..ub-domain-defined-attribute-type-length)),
+ value TeletexString
+ (SIZE (1..ub-domain-defined-attribute-value-length)) }
+
+-- specifications of Upper Bounds
+-- shall be regarded as mandatory
+-- from Annex B of ITU-T X.411
+-- Reference Definition of MTS Parameter Upper Bounds
+
+-- Upper Bounds
+ub-name INTEGER ::= 32768
+ub-common-name INTEGER ::= 64
+ub-locality-name INTEGER ::= 128
+ub-state-name INTEGER ::= 128
+ub-organization-name INTEGER ::= 64
+ub-organizational-unit-name INTEGER ::= 64
+ub-title INTEGER ::= 64
+ub-match INTEGER ::= 128
+
+ub-emailaddress-length INTEGER ::= 128
+
+ub-common-name-length INTEGER ::= 64
+ub-country-name-alpha-length INTEGER ::= 2
+ub-country-name-numeric-length INTEGER ::= 3
+ub-domain-defined-attributes INTEGER ::= 4
+ub-domain-defined-attribute-type-length INTEGER ::= 8
+ub-domain-defined-attribute-value-length INTEGER ::= 128
+ub-domain-name-length INTEGER ::= 16
+ub-extension-attributes INTEGER ::= 256
+ub-e163-4-number-length INTEGER ::= 15
+ub-e163-4-sub-address-length INTEGER ::= 40
+ub-generation-qualifier-length INTEGER ::= 3
+ub-given-name-length INTEGER ::= 16
+ub-initials-length INTEGER ::= 5
+ub-integer-options INTEGER ::= 256
+ub-numeric-user-id-length INTEGER ::= 32
+ub-organization-name-length INTEGER ::= 64
+ub-organizational-unit-name-length INTEGER ::= 32
+ub-organizational-units INTEGER ::= 4
+ub-pds-name-length INTEGER ::= 16
+ub-pds-parameter-length INTEGER ::= 30
+ub-pds-physical-address-lines INTEGER ::= 6
+ub-postal-code-length INTEGER ::= 16
+ub-surname-length INTEGER ::= 40
+ub-terminal-id-length INTEGER ::= 24
+ub-unformatted-address-length INTEGER ::= 180
+ub-x121-address-length INTEGER ::= 16
+
+-- Note - upper bounds on TeletexString are measured in characters.
+-- A significantly greater number of octets will be required to hold
+-- such a value. As a minimum, 16 octets, or twice the specified upper
+-- bound, whichever is the larger, should be allowed.
+
+END
diff --git a/lib/asn1/test/asn1_SUITE_data/PKIX1Implicit88.asn1 b/lib/asn1/test/asn1_SUITE_data/PKIX1Implicit88.asn1
new file mode 100644
index 0000000000..47362e9061
--- /dev/null
+++ b/lib/asn1/test/asn1_SUITE_data/PKIX1Implicit88.asn1
@@ -0,0 +1,349 @@
+PKIX1Implicit88 { iso(1) identified-organization(3) dod(6) internet(1)
+ security(5) mechanisms(5) pkix(7) id-mod(0) id-pkix1-implicit(19) }
+
+DEFINITIONS IMPLICIT TAGS ::=
+
+BEGIN
+
+-- EXPORTS ALL --
+
+IMPORTS
+ id-pe, id-kp, id-qt-unotice, id-qt-cps,
+ -- delete following line if "new" types are supported --
+ -- BMPString,
+ -- UTF8String, end "new" types
+ ORAddress, Name, RelativeDistinguishedName,
+ CertificateSerialNumber, Attribute, DirectoryString
+ FROM PKIX1Explicit88 { iso(1) identified-organization(3)
+ dod(6) internet(1) security(5) mechanisms(5) pkix(7)
+ id-mod(0) id-pkix1-explicit(18) };
+
+
+-- ISO arc for standard certificate and CRL extensions
+
+id-ce OBJECT IDENTIFIER ::= {joint-iso-ccitt(2) ds(5) 29}
+
+-- authority key identifier OID and syntax
+
+id-ce-authorityKeyIdentifier OBJECT IDENTIFIER ::= { id-ce 35 }
+
+AuthorityKeyIdentifier ::= SEQUENCE {
+ keyIdentifier [0] KeyIdentifier OPTIONAL,
+ authorityCertIssuer [1] GeneralNames OPTIONAL,
+ authorityCertSerialNumber [2] CertificateSerialNumber OPTIONAL }
+ -- authorityCertIssuer and authorityCertSerialNumber MUST both
+ -- be present or both be absent
+
+KeyIdentifier ::= OCTET STRING
+
+-- subject key identifier OID and syntax
+
+id-ce-subjectKeyIdentifier OBJECT IDENTIFIER ::= { id-ce 14 }
+
+SubjectKeyIdentifier ::= KeyIdentifier
+
+-- key usage extension OID and syntax
+
+id-ce-keyUsage OBJECT IDENTIFIER ::= { id-ce 15 }
+
+KeyUsage ::= BIT STRING {
+ digitalSignature (0),
+ nonRepudiation (1),
+ keyEncipherment (2),
+ dataEncipherment (3),
+ keyAgreement (4),
+ keyCertSign (5),
+ cRLSign (6),
+ encipherOnly (7),
+ decipherOnly (8) }
+
+-- private key usage period extension OID and syntax
+
+id-ce-privateKeyUsagePeriod OBJECT IDENTIFIER ::= { id-ce 16 }
+
+PrivateKeyUsagePeriod ::= SEQUENCE {
+ notBefore [0] GeneralizedTime OPTIONAL,
+ notAfter [1] GeneralizedTime OPTIONAL }
+ -- either notBefore or notAfter MUST be present
+
+-- certificate policies extension OID and syntax
+
+id-ce-certificatePolicies OBJECT IDENTIFIER ::= { id-ce 32 }
+
+anyPolicy OBJECT IDENTIFIER ::= { id-ce-certificatePolicies 0 }
+
+CertificatePolicies ::= SEQUENCE SIZE (1..MAX) OF PolicyInformation
+
+PolicyInformation ::= SEQUENCE {
+ policyIdentifier CertPolicyId,
+ policyQualifiers SEQUENCE SIZE (1..MAX) OF
+ PolicyQualifierInfo OPTIONAL }
+
+CertPolicyId ::= OBJECT IDENTIFIER
+
+PolicyQualifierInfo ::= SEQUENCE {
+ policyQualifierId PolicyQualifierId,
+ qualifier ANY DEFINED BY policyQualifierId }
+
+-- Implementations that recognize additional policy qualifiers MUST
+-- augment the following definition for PolicyQualifierId
+
+PolicyQualifierId ::=
+ OBJECT IDENTIFIER ( id-qt-cps | id-qt-unotice )
+
+-- CPS pointer qualifier
+
+CPSuri ::= IA5String
+
+-- user notice qualifier
+
+UserNotice ::= SEQUENCE {
+ noticeRef NoticeReference OPTIONAL,
+ explicitText DisplayText OPTIONAL}
+
+NoticeReference ::= SEQUENCE {
+ organization DisplayText,
+ noticeNumbers SEQUENCE OF INTEGER }
+
+DisplayText ::= CHOICE {
+ ia5String IA5String (SIZE (1..200)),
+ visibleString VisibleString (SIZE (1..200)),
+ bmpString BMPString (SIZE (1..200)),
+ utf8String UTF8String (SIZE (1..200)) }
+
+-- policy mapping extension OID and syntax
+
+id-ce-policyMappings OBJECT IDENTIFIER ::= { id-ce 33 }
+
+PolicyMappings ::= SEQUENCE SIZE (1..MAX) OF SEQUENCE {
+ issuerDomainPolicy CertPolicyId,
+ subjectDomainPolicy CertPolicyId }
+
+-- subject alternative name extension OID and syntax
+
+id-ce-subjectAltName OBJECT IDENTIFIER ::= { id-ce 17 }
+
+SubjectAltName ::= GeneralNames
+
+GeneralNames ::= SEQUENCE SIZE (1..MAX) OF GeneralName
+
+GeneralName ::= CHOICE {
+ otherName [0] AnotherName,
+ rfc822Name [1] IA5String,
+ dNSName [2] IA5String,
+ x400Address [3] ORAddress,
+ directoryName [4] Name,
+ ediPartyName [5] EDIPartyName,
+ uniformResourceIdentifier [6] IA5String,
+ iPAddress [7] OCTET STRING,
+ registeredID [8] OBJECT IDENTIFIER }
+
+-- AnotherName replaces OTHER-NAME ::= TYPE-IDENTIFIER, as
+-- TYPE-IDENTIFIER is not supported in the '88 ASN.1 syntax
+
+AnotherName ::= SEQUENCE {
+ type-id OBJECT IDENTIFIER,
+ value [0] EXPLICIT ANY DEFINED BY type-id }
+
+EDIPartyName ::= SEQUENCE {
+ nameAssigner [0] DirectoryString OPTIONAL,
+ partyName [1] DirectoryString }
+
+-- issuer alternative name extension OID and syntax
+
+id-ce-issuerAltName OBJECT IDENTIFIER ::= { id-ce 18 }
+
+IssuerAltName ::= GeneralNames
+
+id-ce-subjectDirectoryAttributes OBJECT IDENTIFIER ::= { id-ce 9 }
+
+SubjectDirectoryAttributes ::= SEQUENCE SIZE (1..MAX) OF Attribute
+
+-- basic constraints extension OID and syntax
+
+id-ce-basicConstraints OBJECT IDENTIFIER ::= { id-ce 19 }
+
+BasicConstraints ::= SEQUENCE {
+ cA BOOLEAN DEFAULT FALSE,
+ pathLenConstraint INTEGER (0..MAX) OPTIONAL }
+
+-- name constraints extension OID and syntax
+
+id-ce-nameConstraints OBJECT IDENTIFIER ::= { id-ce 30 }
+
+NameConstraints ::= SEQUENCE {
+ permittedSubtrees [0] GeneralSubtrees OPTIONAL,
+ excludedSubtrees [1] GeneralSubtrees OPTIONAL }
+
+GeneralSubtrees ::= SEQUENCE SIZE (1..MAX) OF GeneralSubtree
+
+GeneralSubtree ::= SEQUENCE {
+ base GeneralName,
+ minimum [0] BaseDistance DEFAULT 0,
+ maximum [1] BaseDistance OPTIONAL }
+
+BaseDistance ::= INTEGER (0..MAX)
+
+-- policy constraints extension OID and syntax
+
+id-ce-policyConstraints OBJECT IDENTIFIER ::= { id-ce 36 }
+
+PolicyConstraints ::= SEQUENCE {
+ requireExplicitPolicy [0] SkipCerts OPTIONAL,
+ inhibitPolicyMapping [1] SkipCerts OPTIONAL }
+
+SkipCerts ::= INTEGER (0..MAX)
+
+-- CRL distribution points extension OID and syntax
+
+id-ce-cRLDistributionPoints OBJECT IDENTIFIER ::= {id-ce 31}
+
+CRLDistributionPoints ::= SEQUENCE SIZE (1..MAX) OF DistributionPoint
+
+DistributionPoint ::= SEQUENCE {
+ distributionPoint [0] DistributionPointName OPTIONAL,
+ reasons [1] ReasonFlags OPTIONAL,
+ cRLIssuer [2] GeneralNames OPTIONAL }
+
+DistributionPointName ::= CHOICE {
+ fullName [0] GeneralNames,
+ nameRelativeToCRLIssuer [1] RelativeDistinguishedName }
+
+ReasonFlags ::= BIT STRING {
+ unused (0),
+ keyCompromise (1),
+ cACompromise (2),
+ affiliationChanged (3),
+ superseded (4),
+ cessationOfOperation (5),
+ certificateHold (6),
+ privilegeWithdrawn (7),
+ aACompromise (8) }
+
+-- extended key usage extension OID and syntax
+
+id-ce-extKeyUsage OBJECT IDENTIFIER ::= {id-ce 37}
+
+ExtKeyUsageSyntax ::= SEQUENCE SIZE (1..MAX) OF KeyPurposeId
+
+
+KeyPurposeId ::= OBJECT IDENTIFIER
+
+-- permit unspecified key uses
+
+anyExtendedKeyUsage OBJECT IDENTIFIER ::= { id-ce-extKeyUsage 0 }
+
+-- extended key purpose OIDs
+
+id-kp-serverAuth OBJECT IDENTIFIER ::= { id-kp 1 }
+id-kp-clientAuth OBJECT IDENTIFIER ::= { id-kp 2 }
+id-kp-codeSigning OBJECT IDENTIFIER ::= { id-kp 3 }
+id-kp-emailProtection OBJECT IDENTIFIER ::= { id-kp 4 }
+id-kp-timeStamping OBJECT IDENTIFIER ::= { id-kp 8 }
+id-kp-OCSPSigning OBJECT IDENTIFIER ::= { id-kp 9 }
+
+-- inhibit any policy OID and syntax
+
+id-ce-inhibitAnyPolicy OBJECT IDENTIFIER ::= { id-ce 54 }
+
+InhibitAnyPolicy ::= SkipCerts
+
+-- freshest (delta)CRL extension OID and syntax
+
+id-ce-freshestCRL OBJECT IDENTIFIER ::= { id-ce 46 }
+
+FreshestCRL ::= CRLDistributionPoints
+
+-- authority info access
+
+id-pe-authorityInfoAccess OBJECT IDENTIFIER ::= { id-pe 1 }
+
+AuthorityInfoAccessSyntax ::=
+ SEQUENCE SIZE (1..MAX) OF AccessDescription
+
+AccessDescription ::= SEQUENCE {
+ accessMethod OBJECT IDENTIFIER,
+ accessLocation GeneralName }
+
+-- subject info access
+
+id-pe-subjectInfoAccess OBJECT IDENTIFIER ::= { id-pe 11 }
+
+SubjectInfoAccessSyntax ::=
+ SEQUENCE SIZE (1..MAX) OF AccessDescription
+
+-- CRL number extension OID and syntax
+
+id-ce-cRLNumber OBJECT IDENTIFIER ::= { id-ce 20 }
+
+CRLNumber ::= INTEGER (0..MAX)
+
+-- issuing distribution point extension OID and syntax
+
+id-ce-issuingDistributionPoint OBJECT IDENTIFIER ::= { id-ce 28 }
+
+IssuingDistributionPoint ::= SEQUENCE {
+ distributionPoint [0] DistributionPointName OPTIONAL,
+ onlyContainsUserCerts [1] BOOLEAN DEFAULT FALSE,
+ onlyContainsCACerts [2] BOOLEAN DEFAULT FALSE,
+ onlySomeReasons [3] ReasonFlags OPTIONAL,
+ indirectCRL [4] BOOLEAN DEFAULT FALSE,
+ onlyContainsAttributeCerts [5] BOOLEAN DEFAULT FALSE }
+
+id-ce-deltaCRLIndicator OBJECT IDENTIFIER ::= { id-ce 27 }
+
+BaseCRLNumber ::= CRLNumber
+
+-- CRL reasons extension OID and syntax
+
+id-ce-cRLReasons OBJECT IDENTIFIER ::= { id-ce 21 }
+
+CRLReason ::= ENUMERATED {
+ unspecified (0),
+ keyCompromise (1),
+ cACompromise (2),
+ affiliationChanged (3),
+ superseded (4),
+ cessationOfOperation (5),
+ certificateHold (6),
+ removeFromCRL (8),
+ privilegeWithdrawn (9),
+ aACompromise (10) }
+
+-- certificate issuer CRL entry extension OID and syntax
+
+id-ce-certificateIssuer OBJECT IDENTIFIER ::= { id-ce 29 }
+
+CertificateIssuer ::= GeneralNames
+
+-- hold instruction extension OID and syntax
+
+id-ce-holdInstructionCode OBJECT IDENTIFIER ::= { id-ce 23 }
+
+HoldInstructionCode ::= OBJECT IDENTIFIER
+
+-- ANSI x9 holdinstructions
+
+-- ANSI x9 arc holdinstruction arc
+
+holdInstruction OBJECT IDENTIFIER ::=
+ {joint-iso-itu-t(2) member-body(2) us(840) x9cm(10040) 2}
+
+-- ANSI X9 holdinstructions referenced by this standard
+
+id-holdinstruction-none OBJECT IDENTIFIER ::=
+ {holdInstruction 1} -- deprecated
+
+id-holdinstruction-callissuer OBJECT IDENTIFIER ::=
+ {holdInstruction 2}
+
+id-holdinstruction-reject OBJECT IDENTIFIER ::=
+ {holdInstruction 3}
+
+-- invalidity date CRL entry extension OID and syntax
+
+id-ce-invalidityDate OBJECT IDENTIFIER ::= { id-ce 24 }
+
+InvalidityDate ::= GeneralizedTime
+
+END
diff --git a/lib/asn1/test/asn1_SUITE_data/PKIX1Implicit93.asn1 b/lib/asn1/test/asn1_SUITE_data/PKIX1Implicit93.asn1
new file mode 100644
index 0000000000..c90b5eb199
--- /dev/null
+++ b/lib/asn1/test/asn1_SUITE_data/PKIX1Implicit93.asn1
@@ -0,0 +1,357 @@
+PKIX1Implicit93 {iso(1) identified-organization(3) dod(6) internet(1)
+ security(5) mechanisms(5) pkix(7) id-mod(0) id-pkix1-implicit-93(4)}
+
+DEFINITIONS IMPLICIT TAGS::=
+
+BEGIN
+
+--EXPORTS ALL --
+
+IMPORTS
+ id-pe, id-qt, id-kp, id-ad, id-qt-unotice,
+ ORAddress, Name, RelativeDistinguishedName,
+ CertificateSerialNumber, CertificateList,
+ AlgorithmIdentifier, ub-name, DirectoryString,
+ Attribute, EXTENSION
+ FROM PKIX1Explicit93 {iso(1) identified-organization(3)
+ dod(6) internet(1) security(5) mechanisms(5) pkix(7)
+ id-mod(0) id-pkix1-explicit-93(3)};
+
+-- Key and policy information extensions --
+
+authorityKeyIdentifier EXTENSION ::= {
+ SYNTAX AuthorityKeyIdentifier
+ IDENTIFIED BY id-ce-authorityKeyIdentifier }
+
+AuthorityKeyIdentifier ::= SEQUENCE {
+ keyIdentifier [0] KeyIdentifier OPTIONAL,
+ authorityCertIssuer [1] GeneralNames OPTIONAL,
+ authorityCertSerialNumber [2] CertificateSerialNumber OPTIONAL }
+ ( WITH COMPONENTS {..., authorityCertIssuer PRESENT,
+ authorityCertSerialNumber PRESENT} |
+ WITH COMPONENTS {..., authorityCertIssuer ABSENT,
+ authorityCertSerialNumber ABSENT} )
+
+KeyIdentifier ::= OCTET STRING
+
+subjectKeyIdentifier EXTENSION ::= {
+ SYNTAX SubjectKeyIdentifier
+ IDENTIFIED BY id-ce-subjectKeyIdentifier }
+
+SubjectKeyIdentifier ::= KeyIdentifier
+
+keyUsage EXTENSION ::= {
+ SYNTAX KeyUsage
+ IDENTIFIED BY id-ce-keyUsage }
+
+KeyUsage ::= BIT STRING {
+ digitalSignature (0),
+ nonRepudiation (1),
+ keyEncipherment (2),
+ dataEncipherment (3),
+ keyAgreement (4),
+ keyCertSign (5),
+ cRLSign (6),
+ encipherOnly (7),
+ decipherOnly (8) }
+
+extendedKeyUsage EXTENSION ::= {
+ SYNTAX SEQUENCE SIZE (1..MAX) OF KeyPurposeId
+ IDENTIFIED BY id-ce-extKeyUsage }
+
+KeyPurposeId ::= OBJECT IDENTIFIER
+
+-- PKIX-defined extended key purpose OIDs
+id-kp-serverAuth OBJECT IDENTIFIER ::= { id-kp 1 }
+id-kp-clientAuth OBJECT IDENTIFIER ::= { id-kp 2 }
+id-kp-codeSigning OBJECT IDENTIFIER ::= { id-kp 3 }
+id-kp-emailProtection OBJECT IDENTIFIER ::= { id-kp 4 }
+id-kp-ipsecEndSystem OBJECT IDENTIFIER ::= { id-kp 5 }
+id-kp-ipsecTunnel OBJECT IDENTIFIER ::= { id-kp 6 }
+id-kp-ipsecUser OBJECT IDENTIFIER ::= { id-kp 7 }
+id-kp-timeStamping OBJECT IDENTIFIER ::= { id-kp 8 }
+
+privateKeyUsagePeriod EXTENSION ::= {
+ SYNTAX PrivateKeyUsagePeriod
+ IDENTIFIED BY { id-ce-privateKeyUsagePeriod } }
+
+PrivateKeyUsagePeriod ::= SEQUENCE {
+ notBefore [0] GeneralizedTime OPTIONAL,
+ notAfter [1] GeneralizedTime OPTIONAL }
+ ( WITH COMPONENTS {..., notBefore PRESENT} |
+ WITH COMPONENTS {..., notAfter PRESENT} )
+
+certificatePolicies EXTENSION ::= {
+ SYNTAX CertificatePoliciesSyntax
+ IDENTIFIED BY id-ce-certificatePolicies }
+
+CertificatePoliciesSyntax ::=
+ SEQUENCE SIZE (1..MAX) OF PolicyInformation
+
+PolicyInformation ::= SEQUENCE {
+ policyIdentifier CertPolicyId,
+ policyQualifiers SEQUENCE SIZE (1..MAX) OF
+ PolicyQualifierInfo OPTIONAL }
+
+CertPolicyId ::= OBJECT IDENTIFIER
+
+PolicyQualifierInfo ::= SEQUENCE {
+ policyQualifierId CERT-POLICY-QUALIFIER.&id
+ ({SupportedPolicyQualifiers}),
+ qualifier CERT-POLICY-QUALIFIER.&Qualifier
+ ({SupportedPolicyQualifiers}
+ {@policyQualifierId})OPTIONAL }
+
+SupportedPolicyQualifiers CERT-POLICY-QUALIFIER ::= { noticeToUser |
+ pointerToCPS }
+
+CERT-POLICY-QUALIFIER ::= CLASS {
+ &id OBJECT IDENTIFIER UNIQUE,
+ &Qualifier OPTIONAL }
+WITH SYNTAX {
+ POLICY-QUALIFIER-ID &id
+ [QUALIFIER-TYPE &Qualifier] }
+
+policyMappings EXTENSION ::= {
+ SYNTAX PolicyMappingsSyntax
+ IDENTIFIED BY id-ce-policyMappings }
+
+PolicyMappingsSyntax ::= SEQUENCE SIZE (1..MAX) OF SEQUENCE {
+ issuerDomainPolicy CertPolicyId,
+ subjectDomainPolicy CertPolicyId }
+
+-- Certificate subject and certificate issuer attributes extensions --
+
+subjectAltName EXTENSION ::= {
+ SYNTAX GeneralNames
+ IDENTIFIED BY id-ce-subjectAltName }
+
+GeneralNames ::= SEQUENCE SIZE (1..MAX) OF GeneralName
+
+GeneralName ::= CHOICE {
+ otherName [0] INSTANCE OF OTHER-NAME,
+ rfc822Name [1] IA5String,
+ dNSName [2] IA5String,
+ x400Address [3] ORAddress,
+ directoryName [4] Name,
+ ediPartyName [5] EDIPartyName,
+ uniformResourceIdentifier [6] IA5String,
+ iPAddress [7] OCTET STRING,
+ registeredID [8] OBJECT IDENTIFIER }
+
+OTHER-NAME ::= TYPE-IDENTIFIER
+
+EDIPartyName ::= SEQUENCE {
+ nameAssigner [0] DirectoryString {ub-name} OPTIONAL,
+ partyName [1] DirectoryString {ub-name} }
+
+issuerAltName EXTENSION ::= {
+ SYNTAX GeneralNames
+ IDENTIFIED BY id-ce-issuerAltName }
+
+subjectDirectoryAttributes EXTENSION ::= {
+ SYNTAX AttributesSyntax
+ IDENTIFIED BY id-ce-subjectDirectoryAttributes }
+
+AttributesSyntax ::= SEQUENCE SIZE (1..MAX) OF Attribute
+
+-- Certification path constraints extensions --
+
+basicConstraints EXTENSION ::= {
+ SYNTAX BasicConstraintsSyntax
+ IDENTIFIED BY id-ce-basicConstraints }
+
+BasicConstraintsSyntax ::= SEQUENCE {
+ cA BOOLEAN DEFAULT FALSE,
+ pathLenConstraint INTEGER (0..MAX) OPTIONAL }
+
+nameConstraints EXTENSION ::= {
+ SYNTAX NameConstraintsSyntax
+ IDENTIFIED BY id-ce-nameConstraints }
+
+NameConstraintsSyntax ::= SEQUENCE {
+ permittedSubtrees [0] GeneralSubtrees OPTIONAL,
+ excludedSubtrees [1] GeneralSubtrees OPTIONAL }
+
+GeneralSubtrees ::= SEQUENCE SIZE (1..MAX) OF GeneralSubtree
+
+GeneralSubtree ::= SEQUENCE {
+ base GeneralName,
+ minimum [0] BaseDistance DEFAULT 0,
+ maximum [1] BaseDistance OPTIONAL }
+
+BaseDistance ::= INTEGER (0..MAX)
+
+policyConstraints EXTENSION ::= {
+ SYNTAX PolicyConstraintsSyntax
+ IDENTIFIED BY id-ce-policyConstraints }
+
+PolicyConstraintsSyntax ::= SEQUENCE {
+ requireExplicitPolicy [0] SkipCerts OPTIONAL,
+ inhibitPolicyMapping [1] SkipCerts OPTIONAL }
+
+SkipCerts ::= INTEGER (0..MAX)
+
+-- Basic CRL extensions --
+
+cRLNumber EXTENSION ::= {
+ SYNTAX CRLNumber
+ IDENTIFIED BY id-ce-cRLNumber }
+
+CRLNumber ::= INTEGER (0..MAX)
+
+reasonCode EXTENSION ::= {
+ SYNTAX CRLReason
+ IDENTIFIED BY id-ce-reasonCode }
+
+CRLReason ::= ENUMERATED {
+ unspecified (0),
+ keyCompromise (1),
+ cACompromise (2),
+ affiliationChanged (3),
+ superseded (4),
+ cessationOfOperation (5),
+ certificateHold (6),
+ removeFromCRL (8) }
+
+instructionCode EXTENSION ::= {
+ SYNTAX HoldInstruction
+ IDENTIFIED BY id-ce-instructionCode }
+
+HoldInstruction ::= OBJECT IDENTIFIER
+
+-- holdinstructions described in this specification, from ANSI x9
+
+-- ANSI x9 arc holdinstruction arc
+holdInstruction OBJECT IDENTIFIER ::= {
+ joint-iso-ccitt(2) member-body(2) us(840) x9cm(10040) 2}
+
+-- ANSI X9 holdinstructions referenced by this standard
+id-holdinstruction-none OBJECT IDENTIFIER ::= {holdInstruction 1}
+id-holdinstruction-callissuer OBJECT IDENTIFIER ::= {holdInstruction 2}
+id-holdinstruction-reject OBJECT IDENTIFIER ::= {holdInstruction 3}
+
+invalidityDate EXTENSION ::= {
+ SYNTAX GeneralizedTime
+ IDENTIFIED BY id-ce-invalidityDate }
+
+-- CRL distribution points and delta-CRL extensions --
+
+cRLDistributionPoints EXTENSION ::= {
+ SYNTAX CRLDistPointsSyntax
+ IDENTIFIED BY id-ce-cRLDistributionPoints }
+
+CRLDistPointsSyntax ::= SEQUENCE SIZE (1..MAX) OF DistributionPoint
+
+DistributionPoint ::= SEQUENCE {
+ distributionPoint [0] DistributionPointName OPTIONAL,
+ reasons [1] ReasonFlags OPTIONAL,
+ cRLIssuer [2] GeneralNames OPTIONAL }
+
+DistributionPointName ::= CHOICE {
+ fullName [0] GeneralNames,
+ nameRelativeToCRLIssuer [1] RelativeDistinguishedName }
+
+ReasonFlags ::= BIT STRING {
+ unused (0),
+ keyCompromise (1),
+ caCompromise (2),
+ affiliationChanged (3),
+ superseded (4),
+ cessationOfOperation (5),
+ certificateHold (6) }
+
+issuingDistributionPoint EXTENSION ::= {
+ SYNTAX IssuingDistPointSyntax
+ IDENTIFIED BY id-ce-issuingDistributionPoint }
+
+IssuingDistPointSyntax ::= SEQUENCE {
+ distributionPoint [0] DistributionPointName OPTIONAL,
+ onlyContainsUserCerts [1] BOOLEAN DEFAULT FALSE,
+ onlyContainsCACerts [2] BOOLEAN DEFAULT FALSE,
+ onlySomeReasons [3] ReasonFlags OPTIONAL,
+ indirectCRL [4] BOOLEAN DEFAULT FALSE }
+
+certificateIssuer EXTENSION ::= {
+ SYNTAX GeneralNames
+ IDENTIFIED BY id-ce-certificateIssuer }
+
+deltaCRLIndicator EXTENSION ::= {
+ SYNTAX BaseCRLNumber
+ IDENTIFIED BY id-ce-deltaCRLIndicator }
+
+BaseCRLNumber ::= CRLNumber
+
+-- Object identifier assignments for ISO certificate extensions --
+id-ce OBJECT IDENTIFIER ::= {joint-iso-ccitt(2) ds(5) 29}
+
+id-ce-subjectDirectoryAttributes OBJECT IDENTIFIER ::= {id-ce 9}
+
+id-ce-subjectKeyIdentifier OBJECT IDENTIFIER ::= {id-ce 14}
+id-ce-keyUsage OBJECT IDENTIFIER ::= {id-ce 15}
+id-ce-privateKeyUsagePeriod OBJECT IDENTIFIER ::= {id-ce 16}
+id-ce-subjectAltName OBJECT IDENTIFIER ::= {id-ce 17}
+id-ce-issuerAltName OBJECT IDENTIFIER ::= {id-ce 18}
+id-ce-basicConstraints OBJECT IDENTIFIER ::= {id-ce 19}
+id-ce-cRLNumber OBJECT IDENTIFIER ::= {id-ce 20}
+id-ce-reasonCode OBJECT IDENTIFIER ::= {id-ce 21}
+id-ce-instructionCode OBJECT IDENTIFIER ::= {id-ce 23}
+id-ce-invalidityDate OBJECT IDENTIFIER ::= {id-ce 24}
+id-ce-deltaCRLIndicator OBJECT IDENTIFIER ::= {id-ce 27}
+id-ce-issuingDistributionPoint OBJECT IDENTIFIER ::= {id-ce 28}
+id-ce-certificateIssuer OBJECT IDENTIFIER ::= {id-ce 29}
+id-ce-nameConstraints OBJECT IDENTIFIER ::= {id-ce 30}
+id-ce-cRLDistributionPoints OBJECT IDENTIFIER ::= {id-ce 31}
+id-ce-certificatePolicies OBJECT IDENTIFIER ::= {id-ce 32}
+id-ce-policyMappings OBJECT IDENTIFIER ::= {id-ce 33}
+id-ce-policyConstraints OBJECT IDENTIFIER ::= {id-ce 36}
+id-ce-authorityKeyIdentifier OBJECT IDENTIFIER ::= {id-ce 35}
+id-ce-extKeyUsage OBJECT IDENTIFIER ::= {id-ce 37}
+
+-- PKIX 1 extensions
+
+authorityInfoAccess EXTENSION ::= {
+ SYNTAX AuthorityInfoAccessSyntax
+ IDENTIFIED BY id-pe-authorityInfoAccess }
+
+AuthorityInfoAccessSyntax ::=
+ SEQUENCE SIZE (1..MAX) OF AccessDescription
+
+AccessDescription ::= SEQUENCE {
+ accessMethod OBJECT IDENTIFIER,
+ accessLocation GeneralName }
+
+id-pe-authorityInfoAccess OBJECT IDENTIFIER ::= { id-pe 1 }
+
+id-ad-ocsp OBJECT IDENTIFIER ::= { id-ad 1 }
+id-ad-caIssuers OBJECT IDENTIFIER ::= { id-ad 2 }
+
+-- PKIX policy qualifier definitions
+
+noticeToUser CERT-POLICY-QUALIFIER ::= {
+ POLICY-QUALIFIER-ID id-qt-cps QUALIFIER-TYPE CPSuri}
+
+pointerToCPS CERT-POLICY-QUALIFIER ::= {
+ POLICY-QUALIFIER-ID id-qt-unotice QUALIFIER-TYPE UserNotice}
+
+id-qt-cps OBJECT IDENTIFIER ::= { id-qt 1 }
+
+id-qt-unotice OBJECT IDENTIFIER ::= { id-qt 2 }
+
+CPSuri ::= IA5String
+
+UserNotice ::= SEQUENCE {
+ noticeRef NoticeReference OPTIONAL,
+ explicitText DisplayText OPTIONAL}
+
+NoticeReference ::= SEQUENCE {
+ organization DisplayText,
+ noticeNumbers SEQUENCE OF INTEGER }
+
+DisplayText ::= CHOICE {
+ visibleString VisibleString (SIZE (1..200)),
+ bmpString BMPString (SIZE (1..200)),
+ utf8String UTF8String (SIZE (1..200)) }
+
+
+END
diff --git a/lib/asn1/test/asn1_SUITE_data/PKIXAttributeCertificate.asn1 b/lib/asn1/test/asn1_SUITE_data/PKIXAttributeCertificate.asn1
new file mode 100644
index 0000000000..2d0997fdfc
--- /dev/null
+++ b/lib/asn1/test/asn1_SUITE_data/PKIXAttributeCertificate.asn1
@@ -0,0 +1,189 @@
+ PKIXAttributeCertificate {iso(1) identified-organization(3) dod(6)
+ internet(1) security(5) mechanisms(5) pkix(7) id-mod(0)
+ id-mod-attribute-cert(12)}
+
+ DEFINITIONS IMPLICIT TAGS ::=
+
+ BEGIN
+
+ -- EXPORTS ALL --
+
+ IMPORTS
+
+ -- IMPORTed module OIDs MAY change if [PKIXPROF] changes
+ -- PKIX Certificate Extensions
+ Attribute, AlgorithmIdentifier, CertificateSerialNumber,
+ Extensions, UniqueIdentifier,
+ id-pkix, id-pe, id-kp, id-ad, id-at
+ FROM PKIX1Explicit88 {iso(1) identified-organization(3)
+ dod(6) internet(1) security(5) mechanisms(5)
+ pkix(7) id-mod(0) id-pkix1-explicit-88(1)}
+
+ GeneralName, GeneralNames, id-ce
+ FROM PKIX1Implicit88 {iso(1) identified-organization(3)
+ dod(6) internet(1) security(5) mechanisms(5)
+ pkix(7) id-mod(0) id-pkix1-implicit-88(2)} ;
+
+ id-pe-ac-auditIdentity OBJECT IDENTIFIER ::= { id-pe 4 }
+ id-pe-aaControls OBJECT IDENTIFIER ::= { id-pe 6 }
+ id-pe-ac-proxying OBJECT IDENTIFIER ::= { id-pe 10 }
+ id-ce-targetInformation OBJECT IDENTIFIER ::= { id-ce 55 }
+
+ id-aca OBJECT IDENTIFIER ::= { id-pkix 10 }
+ id-aca-authenticationInfo OBJECT IDENTIFIER ::= { id-aca 1 }
+ id-aca-accessIdentity OBJECT IDENTIFIER ::= { id-aca 2 }
+ id-aca-chargingIdentity OBJECT IDENTIFIER ::= { id-aca 3 }
+ id-aca-group OBJECT IDENTIFIER ::= { id-aca 4 }
+ -- { id-aca 5 } is reserved
+ id-aca-encAttrs OBJECT IDENTIFIER ::= { id-aca 6 }
+
+ id-at-role OBJECT IDENTIFIER ::= { id-at 72}
+ id-at-clearance OBJECT IDENTIFIER ::=
+ { joint-iso-ccitt(2) ds(5) module(1)
+ selected-attribute-types(5) clearance (55) }
+
+ -- Uncomment this if using a 1988 level ASN.1 compiler
+-- UTF8String ::= [UNIVERSAL 12] IMPLICIT OCTET STRING
+
+ AttributeCertificate ::= SEQUENCE {
+ acinfo AttributeCertificateInfo,
+ signatureAlgorithm AlgorithmIdentifier,
+ signatureValue BIT STRING
+ }
+
+ AttributeCertificateInfo ::= SEQUENCE {
+ version AttCertVersion, -- version is v2
+ holder Holder,
+ issuer AttCertIssuer,
+ signature AlgorithmIdentifier,
+ serialNumber CertificateSerialNumber,
+ attrCertValidityPeriod AttCertValidityPeriod,
+ attributes SEQUENCE OF Attribute,
+ issuerUniqueID UniqueIdentifier OPTIONAL,
+ extensions Extensions OPTIONAL
+ }
+
+ AttCertVersion ::= INTEGER { v2(1) }
+
+ Holder ::= SEQUENCE {
+ baseCertificateID [0] IssuerSerial OPTIONAL,
+ -- the issuer and serial number of
+ -- the holder's Public Key Certificate
+ entityName [1] GeneralNames OPTIONAL,
+ -- the name of the claimant or role
+ objectDigestInfo [2] ObjectDigestInfo OPTIONAL
+ -- used to directly authenticate the
+ -- holder, for example, an executable
+ }
+
+ ObjectDigestInfo ::= SEQUENCE {
+ digestedObjectType ENUMERATED {
+ publicKey (0),
+ publicKeyCert (1),
+ otherObjectTypes (2) },
+ -- otherObjectTypes MUST NOT
+ -- MUST NOT be used in this profile
+ otherObjectTypeID OBJECT IDENTIFIER OPTIONAL,
+ digestAlgorithm AlgorithmIdentifier,
+ objectDigest BIT STRING
+ }
+
+ AttCertIssuer ::= CHOICE {
+ v1Form GeneralNames, -- MUST NOT be used in this
+ -- profile
+ v2Form [0] V2Form -- v2 only
+ }
+
+ V2Form ::= SEQUENCE {
+ issuerName GeneralNames OPTIONAL,
+ baseCertificateID [0] IssuerSerial OPTIONAL,
+ objectDigestInfo [1] ObjectDigestInfo OPTIONAL
+ -- issuerName MUST be present in this profile
+ -- baseCertificateID and objectDigestInfo MUST
+ -- NOT be present in this profile
+ }
+
+ IssuerSerial ::= SEQUENCE {
+ issuer GeneralNames,
+ serial CertificateSerialNumber,
+ issuerUID UniqueIdentifier OPTIONAL
+ }
+
+ AttCertValidityPeriod ::= SEQUENCE {
+ notBeforeTime GeneralizedTime,
+ notAfterTime GeneralizedTime
+ }
+
+ Targets ::= SEQUENCE OF Target
+
+ Target ::= CHOICE {
+ targetName [0] GeneralName,
+ targetGroup [1] GeneralName,
+ targetCert [2] TargetCert
+ }
+
+ TargetCert ::= SEQUENCE {
+ targetCertificate IssuerSerial,
+ targetName GeneralName OPTIONAL,
+ certDigestInfo ObjectDigestInfo OPTIONAL
+ }
+
+ IetfAttrSyntax ::= SEQUENCE {
+ policyAuthority[0] GeneralNames OPTIONAL,
+ values SEQUENCE OF CHOICE {
+ octets OCTET STRING,
+ oid OBJECT IDENTIFIER,
+ string UTF8String
+ }
+ }
+
+ SvceAuthInfo ::= SEQUENCE {
+ service GeneralName,
+ ident GeneralName,
+ authInfo OCTET STRING OPTIONAL
+ }
+
+ RoleSyntax ::= SEQUENCE {
+ roleAuthority [0] GeneralNames OPTIONAL,
+ roleName [1] GeneralName
+ }
+
+ Clearance ::= SEQUENCE {
+ policyId [0] OBJECT IDENTIFIER,
+ classList [1] ClassList DEFAULT {unclassified},
+ securityCategories
+ [2] SET OF SecurityCategory OPTIONAL
+ }
+
+ ClassList ::= BIT STRING {
+ unmarked (0),
+ unclassified (1),
+ restricted (2),
+ confidential (3),
+ secret (4),
+ topSecret (5)
+ }
+
+ SecurityCategory ::= SEQUENCE {
+ type [0] IMPLICIT OBJECT IDENTIFIER,
+ value [1] ANY DEFINED BY type
+ }
+
+ AAControls ::= SEQUENCE {
+ pathLenConstraint INTEGER (0..MAX) OPTIONAL,
+ permittedAttrs [0] AttrSpec OPTIONAL,
+ excludedAttrs [1] AttrSpec OPTIONAL,
+ permitUnSpecified BOOLEAN DEFAULT TRUE
+ }
+
+ AttrSpec::= SEQUENCE OF OBJECT IDENTIFIER
+
+ ACClearAttrs ::= SEQUENCE {
+ acIssuer GeneralName,
+ acSerial INTEGER,
+ attrs SEQUENCE OF Attribute
+ }
+
+ ProxyInfo ::= SEQUENCE OF Targets
+
+ END
diff --git a/lib/asn1/test/asn1_SUITE_data/Param.asn1 b/lib/asn1/test/asn1_SUITE_data/Param.asn1
new file mode 100644
index 0000000000..b2987a7885
--- /dev/null
+++ b/lib/asn1/test/asn1_SUITE_data/Param.asn1
@@ -0,0 +1,93 @@
+-- **************************************************************
+--
+-- Information Element Definitions
+--
+-- **************************************************************
+
+Param -- { object identifier to be allocated }--
+DEFINITIONS AUTOMATIC TAGS ::=
+
+BEGIN
+
+-- A
+
+Criticality ::= ENUMERATED { reject, ignore, notify }
+
+Presence ::= ENUMERATED { optional, conditional, mandatory }
+
+ProtocolExtensionID ::= INTEGER (0..65535)
+
+RANAP-PROTOCOL-EXTENSION ::= CLASS {
+ &id ProtocolExtensionID UNIQUE,
+ &criticality Criticality,
+ &Extension,
+ &presence Presence
+}
+WITH SYNTAX {
+ ID &id
+ CRITICALITY &criticality
+ EXTENSION &Extension
+ PRESENCE &presence
+}
+
+ProtocolExtensionContainer {RANAP-PROTOCOL-EXTENSION : ExtensionSetParam} ::=
+ SEQUENCE (SIZE (1..10)) OF
+ ProtocolExtensionField {{ExtensionSetParam}}
+
+ProtocolExtensionField {RANAP-PROTOCOL-EXTENSION : ExtensionSetParam} ::= SEQUENCE {
+ id RANAP-PROTOCOL-EXTENSION.&id ({ExtensionSetParam}),
+ criticality RANAP-PROTOCOL-EXTENSION.&criticality ({ExtensionSetParam}{@id}),
+ extensionValue RANAP-PROTOCOL-EXTENSION.&Extension ({ExtensionSetParam}{@id})
+}
+
+
+AllocationOrRetentionPriority ::= SEQUENCE {
+ priorityLevel BOOLEAN,
+ iE-Extensions ProtocolExtensionContainer { {AllocationOrRetentionPriority-ExtIEs} } OPTIONAL,
+ ...
+}
+
+AllocationOrRetentionPriority-ExtIEs RANAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+obj1 RANAP-PROTOCOL-EXTENSION ::= {
+ ID id-one
+ CRITICALITY ignore
+ EXTENSION INTEGER
+ PRESENCE optional
+}
+
+obj2 RANAP-PROTOCOL-EXTENSION ::= {
+ ID id-two
+ CRITICALITY ignore
+ EXTENSION BOOLEAN
+ PRESENCE optional
+}
+
+id-one INTEGER ::= 1
+id-two INTEGER ::= 2
+
+-- The following code for test of OTP-4242, ValueFromObject
+-- Similar use as in the Camel spec
+
+CONFIG-DATA ::= CLASS {
+ &minLevel INTEGER,
+ &maxLevel INTEGER
+}
+WITH SYNTAX {
+ MINLEVEL &minLevel
+ MAXLEVEL &maxLevel
+}
+
+config-data CONFIG-DATA ::= {MINLEVEL 1 MAXLEVEL 3}
+
+OS1 ::= OCTET STRING (SIZE (config-data.&minLevel .. config-data.&maxLevel))
+
+POS2 {CONFIG-DATA:obj} ::= OCTET STRING (SIZE(obj.&minLevel .. obj.&maxLevel))
+
+OS2 ::= POS2 {config-data}
+
+
+END
+
diff --git a/lib/asn1/test/asn1_SUITE_data/ParamBasic.asn1 b/lib/asn1/test/asn1_SUITE_data/ParamBasic.asn1
new file mode 100644
index 0000000000..491bdf8956
--- /dev/null
+++ b/lib/asn1/test/asn1_SUITE_data/ParamBasic.asn1
@@ -0,0 +1,23 @@
+ParamBasic DEFINITIONS AUTOMATIC TAGS ::=
+
+BEGIN
+
+General1{T,T:val} ::= SEQUENCE {
+ number INTEGER,
+ string T DEFAULT val
+}
+
+T11 ::= General1{PrintableString,"hej"}
+
+T12 ::= General1{BIT STRING,'1010'B}
+
+General2{T} ::= SEQUENCE {
+ number INTEGER,
+ string T
+}
+
+T21 ::= General2{PrintableString}
+
+T22 ::= General2{BIT STRING}
+
+END
diff --git a/lib/asn1/test/asn1_SUITE_data/PartialDecMyHTTP.asn b/lib/asn1/test/asn1_SUITE_data/PartialDecMyHTTP.asn
new file mode 100644
index 0000000000..aad3c4d833
--- /dev/null
+++ b/lib/asn1/test/asn1_SUITE_data/PartialDecMyHTTP.asn
@@ -0,0 +1,19 @@
+PartialDecMyHTTP DEFINITIONS AUTOMATIC TAGS ::=
+
+BEGIN
+
+GetRequest ::= SEQUENCE {
+ header-only BOOLEAN,
+ lock BOOLEAN,
+ accept-types AcceptTypes,
+ url Url, ...
+}
+
+AcceptTypes ::= SET {
+ standards BIT STRING {html(0), plain-text(1), gif(2), jpeg(3)} (SIZE (4)) OPTIONAL,
+ others SEQUENCE OF VisibleString (SIZE (4)) OPTIONAL
+}
+
+Url ::= VisibleString (FROM ("a".."z"|"A".."Z"|"0".."9"| "./-_~%#"))
+
+END
diff --git a/lib/asn1/test/asn1_SUITE_data/PartialDecMyHTTP.asn1config b/lib/asn1/test/asn1_SUITE_data/PartialDecMyHTTP.asn1config
new file mode 100644
index 0000000000..bafd7f46ac
--- /dev/null
+++ b/lib/asn1/test/asn1_SUITE_data/PartialDecMyHTTP.asn1config
@@ -0,0 +1,3 @@
+{exclusive_decode,{'PartialDecMyHTTP',
+ [{decode_GetRequest_incomplete,
+ ['GetRequest',[{'accept-types',[{others,parts}]}]]}]}}.
diff --git a/lib/asn1/test/asn1_SUITE_data/PartialDecSeq.asn b/lib/asn1/test/asn1_SUITE_data/PartialDecSeq.asn
new file mode 100644
index 0000000000..17844f12b9
--- /dev/null
+++ b/lib/asn1/test/asn1_SUITE_data/PartialDecSeq.asn
@@ -0,0 +1,34 @@
+PartialDecSeq DEFINITIONS AUTOMATIC TAGS ::=
+
+BEGIN
+
+A ::= SEQUENCE {
+ a INTEGER DEFAULT 15,
+ b [0] B DEFAULT {a 12, b TRUE}
+}
+
+C ::= [11] EXPLICIT D
+B ::= [12] C
+D ::= SEQUENCE {
+ a INTEGER,
+ b BOOLEAN
+}
+
+F ::= CHOICE {
+ fa INTEGER,
+ fb E --161
+}
+
+E ::= SEQUENCE {
+ a INTEGER, -- matched
+ b SEQUENCE OF D, -- matched value of component a of first D in E_b
+ c BOOLEAN OPTIONAL,
+ d CHOICE {
+ da SEQUENCE OF A,
+ db INTEGER,
+ dc [3] SET {dca INTEGER,dcb BOOLEAN, dcc SEQUENCE{dcca INTEGER,dccb INTEGER}}
+ }
+}
+
+
+END
diff --git a/lib/asn1/test/asn1_SUITE_data/PartialDecSeq.asn1config b/lib/asn1/test/asn1_SUITE_data/PartialDecSeq.asn1config
new file mode 100644
index 0000000000..19fa3c990e
--- /dev/null
+++ b/lib/asn1/test/asn1_SUITE_data/PartialDecSeq.asn1config
@@ -0,0 +1,22 @@
+{selective_decode,{'PartialDecSeq',
+ [{selected_decode_F1,['F',fb,b,[1],a]},
+ {selected_decode_F2,['F',fb,b]},
+ {selected_decode_F3,['F',fb,b,[1]]},
+ {selected_decode_F4,['F',fb,d,da,[1],b,a]},
+ {selected_decode_E1,['E',d,dc,dcc,dcca]}]}}.
+%% partial_incomplete_decode tuplen inneh�ller tv� element. Den
+%% f�rsta �r bara en nyckel den andra �r en tupel med modulnamnet i
+%% en tupel {module,Name} och det andra elementet �r en lista av tupler:
+%% D�r varje tupel beskriver en partiell ofullst�ndig dekod. F�rsta
+%% elementet i den tupeln �r namnet p� funktionen som ska g�ra den
+%% partiella dekodningen. Det andra elementet �r en lista av typnamn/
+%% komponentnamn som �r en sekvens (path) till de element som ej skall
+%% avkodas.
+{exclusive_decode,{'PartialDecSeq',
+ [{decode_F_fb_incomplete,['F',[{fb,[{b,parts},{d,undecoded}]}]]},
+ {decode_D_incomplete,['D',[{a,undecoded}]]},
+ {decode_F_fb_exclusive2,['F',[{fb,[{b,parts},{d,[{da,parts}]}]}]]}, {decode_F_fb_exclusive3,['F',[{fb,[{b,parts},{d,[{da,parts},{dc,[{dcc,undecoded}]}]}]}]]}]}}.
+{module_name,'Seq.asn1'}.
+{compile_options,[ber_bin,optimize,debug_info]}.
+{multifile_compile,['M1.asn','M2.asn']}.
+
diff --git a/lib/asn1/test/asn1_SUITE_data/PartialDecSeq2.asn b/lib/asn1/test/asn1_SUITE_data/PartialDecSeq2.asn
new file mode 100644
index 0000000000..2e77d250d2
--- /dev/null
+++ b/lib/asn1/test/asn1_SUITE_data/PartialDecSeq2.asn
@@ -0,0 +1,29 @@
+PartialDecSeq2 DEFINITIONS AUTOMATIC TAGS ::=
+
+BEGIN
+
+B ::= CHOICE {
+ a INTEGER,
+ b SEQUENCE {aa INTEGER, ba INTEGER},
+ c S
+}
+
+S ::= SEQUENCE {
+ a BOOLEAN,
+ b BOOLEAN
+}
+
+A ::= SEQUENCE {
+ a INTEGER DEFAULT 15,
+ b B DEFAULT b:{aa 13, ba 14},
+ c CHOICE {a INTEGER,b SEQUENCE{a BOOLEAN, b BOOLEAN}} DEFAULT b:{a TRUE, b FALSE}
+}
+
+C ::= D
+
+D ::= SEQUENCE {
+ a INTEGER,
+ b BOOLEAN
+}
+
+END
diff --git a/lib/asn1/test/asn1_SUITE_data/PartialDecSeq2.asn1config b/lib/asn1/test/asn1_SUITE_data/PartialDecSeq2.asn1config
new file mode 100644
index 0000000000..d9967d9958
--- /dev/null
+++ b/lib/asn1/test/asn1_SUITE_data/PartialDecSeq2.asn1config
@@ -0,0 +1,4 @@
+%{partial_decode,{{module,'Seq2'},['F',fb,b,[1],a]}}.
+{exclusive_decode,{'PartialDecSeq2',
+ [{decode_A_c_b_incomplete,['A',[{c,[{a,undecoded},{b,undecoded}]}]]},
+ {decode_D_incomplete,['D',[{a,undecoded}]]}]}}.
diff --git a/lib/asn1/test/asn1_SUITE_data/PartialDecSeq3.asn b/lib/asn1/test/asn1_SUITE_data/PartialDecSeq3.asn
new file mode 100644
index 0000000000..3b530733ef
--- /dev/null
+++ b/lib/asn1/test/asn1_SUITE_data/PartialDecSeq3.asn
@@ -0,0 +1,45 @@
+PartialDecSeq3 DEFINITIONS AUTOMATIC TAGS ::=
+
+BEGIN
+
+S1 ::= SEQUENCE {
+ a INTEGER,
+ b S2 OPTIONAL,
+ c C1,
+ d SO1
+}
+
+S2 ::= SEQUENCE {
+ a BOOLEAN,
+ b INTEGER,
+ c SEQUENCE OF S3,
+ ...
+}
+
+C1 ::= CHOICE {
+ a SEQUENCE OF S3,
+ b SEQUENCE {a INTEGER, b BOOLEAN, c S4}
+}
+
+S3 ::= SEQUENCE {
+ first INTEGER,
+ second PrintableString,
+ third OCTET STRING (SIZE(2..100)),
+ fourth BIT STRING {one(0),two(1),three(2),four(3),five(4),six(5)}(SIZE(1..6)),
+ ...
+}
+
+S4 ::= SET {
+ name Name,
+ title VisibleString
+}
+
+Name ::= SEQUENCE {
+ givenName VisibleString,
+ initial VisibleString,
+ familyName VisibleString
+}
+
+SO1 ::= SEQUENCE (SIZE(2..6)) OF Name
+
+END
diff --git a/lib/asn1/test/asn1_SUITE_data/PartialDecSeq3.asn1config b/lib/asn1/test/asn1_SUITE_data/PartialDecSeq3.asn1config
new file mode 100644
index 0000000000..44d22aa1d4
--- /dev/null
+++ b/lib/asn1/test/asn1_SUITE_data/PartialDecSeq3.asn1config
@@ -0,0 +1,2 @@
+{exclusive_decode,{'PartialDecSeq3',
+ [{decode_S1_incomplete,['S1',[{b,[{c,parts}]},{c,[{a,parts}]},{d,parts}]]}]}}.
diff --git a/lib/asn1/test/asn1_SUITE_data/Pattern.asn b/lib/asn1/test/asn1_SUITE_data/Pattern.asn
new file mode 100644
index 0000000000..730b4ba32a
--- /dev/null
+++ b/lib/asn1/test/asn1_SUITE_data/Pattern.asn
@@ -0,0 +1,8 @@
+Pattern DEFINITIONS AUTOMATIC TAGS ::=
+
+BEGIN
+
+DateAndTime ::= VisibleString (PATTERN "\d#2/\d#2/\d#4-\d#2:\d#2")
+-- DD/MM/YYY-HH:MM
+
+END \ No newline at end of file
diff --git a/lib/asn1/test/asn1_SUITE_data/Person.py b/lib/asn1/test/asn1_SUITE_data/Person.py
new file mode 100644
index 0000000000..60c1e06391
--- /dev/null
+++ b/lib/asn1/test/asn1_SUITE_data/Person.py
@@ -0,0 +1,10 @@
+Person DEFINITIONS IMPLICIT TAGS ::=
+BEGIN
+EXPORTS Person;
+
+Person ::= [PRIVATE 19] SEQUENCE {
+ name PrintableString,
+ location INTEGER {home(0),field(1),roving(2)},
+ age INTEGER OPTIONAL
+ }
+END
diff --git a/lib/asn1/test/asn1_SUITE_data/Prim.asn1 b/lib/asn1/test/asn1_SUITE_data/Prim.asn1
new file mode 100644
index 0000000000..1a905988f5
--- /dev/null
+++ b/lib/asn1/test/asn1_SUITE_data/Prim.asn1
@@ -0,0 +1,32 @@
+Prim DEFINITIONS IMPLICIT TAGS ::=
+
+BEGIN
+
+ Bool ::= BOOLEAN
+ BoolCon ::= [20] BOOLEAN
+ BoolPri ::= [PRIVATE 21] BOOLEAN
+ BoolApp ::= [APPLICATION 22] BOOLEAN
+ BoolExpCon ::= [30] EXPLICIT BOOLEAN
+ BoolExpPri ::= [PRIVATE 31] EXPLICIT BOOLEAN
+ BoolExpApp ::= [APPLICATION 32] EXPLICIT BOOLEAN
+
+ Int ::= INTEGER
+ IntCon ::= [40] INTEGER
+ IntPri ::= [PRIVATE 41] INTEGER
+ IntApp ::= [APPLICATION 42] INTEGER
+ IntExpCon ::= [50] EXPLICIT INTEGER
+ IntExpPri ::= [PRIVATE 51] EXPLICIT INTEGER
+ IntExpApp ::= [APPLICATION 52] EXPLICIT INTEGER
+
+ IntEnum ::= INTEGER {first(1),last(31)}
+
+ Enum ::= ENUMERATED {monday(1),tuesday(2),wednesday(3),thursday(4),
+ friday(5),saturday(6),sunday(7)}
+
+ ObjId ::= OBJECT IDENTIFIER
+
+ RelOid ::= RELATIVE-OID
+
+ Null ::= NULL
+
+END
diff --git a/lib/asn1/test/asn1_SUITE_data/PrimExternal.asn1 b/lib/asn1/test/asn1_SUITE_data/PrimExternal.asn1
new file mode 100644
index 0000000000..2db685896d
--- /dev/null
+++ b/lib/asn1/test/asn1_SUITE_data/PrimExternal.asn1
@@ -0,0 +1,39 @@
+PrimExternal DEFINITIONS IMPLICIT TAGS ::=
+
+BEGIN
+
+IMPORTS XNT, XImp, XExp FROM External;
+
+
+
+NT ::= OCTET STRING
+Imp ::= [1] OCTET STRING
+Exp ::= [2] EXPLICIT OCTET STRING
+
+NTNT ::= NT
+ImpNT ::= [3] NT
+ExpNT ::= [4] EXPLICIT NT
+
+NTImp ::= Imp
+ImpImp ::= [5] Imp
+ExpImp ::= [6] EXPLICIT Imp
+
+NTExp ::= Exp
+ImpExp ::= [7] Exp
+ExpExp ::= [8] EXPLICIT Exp
+
+XNTNT ::= XNT
+XImpNT ::= [3] XNT
+XExpNT ::= [4] EXPLICIT XNT
+
+XNTImp ::= XImp
+XImpImp ::= [5] XImp
+XExpImp ::= [6] EXPLICIT XImp
+
+XNTExp ::= XExp
+XImpExp ::= [7] XExp
+XExpExp ::= [8] EXPLICIT XExp
+
+
+END
+
diff --git a/lib/asn1/test/asn1_SUITE_data/PrimStrings.asn1 b/lib/asn1/test/asn1_SUITE_data/PrimStrings.asn1
new file mode 100644
index 0000000000..d287840f30
--- /dev/null
+++ b/lib/asn1/test/asn1_SUITE_data/PrimStrings.asn1
@@ -0,0 +1,97 @@
+PrimStrings DEFINITIONS IMPLICIT TAGS ::=
+
+BEGIN
+
+ Bs1 ::= BIT STRING
+ Bs2 ::= BIT STRING {su(0), mo(1), tu(2), we(3), th(4), fr(5), sa(6) } (SIZE (7))
+ Bs3 ::= BIT STRING {su(0), mo(1), tu(2), we(3), th(4), fr(5), sa(6) } (SIZE (1..7))
+ Bs4 ::= BIT STRING {su(0), mo(1), tu(2), we(3), th(4), fr(5), sa(6) } (SIZE (1..32))
+ Bs5 ::= BIT STRING {su(0), mo(17), tu(2), we(3), th(4), fr(5), sa(6) } (SIZE (1..32))
+ Bs6 ::= BIT STRING {su(0), mo(17), tu(2), we(3), th(4), fr(5), sa(6)} (SIZE (16..32))
+ Bs7 ::= BIT STRING (SIZE (24))
+ BsPri ::= [PRIVATE 61] BIT STRING
+ BsExpPri ::= [PRIVATE 61] EXPLICIT BIT STRING
+ ODB-GeneralData ::= BIT STRING {
+ allOG-CallsBarred (0),
+ internationalOGCallsBarred (1),
+ internationalOGCallsNotToHPLMN-CountryBarred (2),
+ interzonalOGCallsBarred (6),
+ interzonalOGCallsNotToHPLMN-CountryBarred (7),
+ interzonalOGCallsAndInternationalOGCallsNotToHPLMN-CountryBarred (8),
+ premiumRateInformationOGCallsBarred (3),
+ premiumRateEntertainementOGCallsBarred (4),
+ ss-AccessBarred (5),
+ allECT-Barred (9),
+ chargeableECT-Barred (10),
+ internationalECT-Barred (11),
+ interzonalECT-Barred (12),
+ doublyChargeableECT-Barred (13),
+ multipleECT-Barred (14)} (SIZE (15..32))
+ -- exception handling: reception of unknown bit assignments in the
+ -- ODB-GeneralData type shall be treated like unsupported ODB-GeneralData
+
+ TransportLayerAddress ::= BIT STRING (SIZE (1..160, ...))
+
+ --TestS is to test OTP-4353. See also x691 15.3 and x680 21.7
+ TestS ::= BIT STRING {a(0),b(1)} (SIZE (3..8))
+
+ -- OTP-5932
+ BSMAX ::= BIT STRING (SIZE (5..MAX))
+
+ -- OTP-7602
+
+BS255 ::= BIT STRING (SIZE (255))
+
+BS256 ::= BIT STRING (SIZE (256))
+
+BS1024 ::= BIT STRING (SIZE (1024))
+
+
+
+ Os ::= OCTET STRING
+ OsCon ::= [60] OCTET STRING
+ OsPri ::= [PRIVATE 61] OCTET STRING
+ OsApp ::= [APPLICATION 62] OCTET STRING
+ OsExpCon ::= [60] EXPLICIT OCTET STRING
+ OsExpPri ::= [PRIVATE 61] EXPLICIT OCTET STRING
+ OsExpApp ::= [APPLICATION 62] EXPLICIT OCTET STRING
+
+ Ns ::= NumericString
+ NsCon ::= [70] NumericString
+ NsExpCon ::= [71] EXPLICIT NumericString
+
+ Ps ::= PrintableString
+
+ Ts ::= TeletexString
+
+ Vxs ::= VideotexString
+
+ Vis ::= VisibleString
+
+ IA5 ::= IA5String
+
+ Grs ::= GraphicString
+
+ ODesc ::= ObjectDescriptor
+
+ ODescSeq ::= SEQUENCE {
+ o ObjectDescriptor OPTIONAL,
+ i INTEGER
+ }
+
+ Ges ::= GeneralString
+
+ Us ::= UniversalString
+ UsCon ::= [70] UniversalString
+ UsExpCon ::= [71] EXPLICIT UniversalString
+
+ BMP ::= BMPString
+
+ Gt ::= GeneralizedTime
+
+ UTC ::= UTCTime
+
+ UTF ::= UTF8String
+
+
+END
diff --git a/lib/asn1/test/asn1_SUITE_data/RANAP-CommonDataTypes.asn1 b/lib/asn1/test/asn1_SUITE_data/RANAP-CommonDataTypes.asn1
new file mode 100644
index 0000000000..ff5357f000
--- /dev/null
+++ b/lib/asn1/test/asn1_SUITE_data/RANAP-CommonDataTypes.asn1
@@ -0,0 +1,45 @@
+-- RANAP-CommonDataTypes.asn
+--
+-- Taken from 3GPP TS 25.413 V8.2.1 (2009-03)
+-- http://www.3gpp.org/ftp/Specs/archive/25_series/25.413/25413-821.zip
+--
+-- 9.3.5 Common Definitions
+--
+-- $Id$
+--
+
+-- **************************************************************
+--
+-- Common definitions
+--
+-- **************************************************************
+
+RANAP-CommonDataTypes {
+itu-t (0) identified-organization (4) etsi (0) mobileDomain (0)
+umts-Access (20) modules (3) ranap (0) version1 (1) ranap-CommonDataTypes (3) }
+
+DEFINITIONS AUTOMATIC TAGS ::=
+
+BEGIN
+
+Criticality ::= ENUMERATED { reject, ignore, notify }
+
+Presence ::= ENUMERATED { optional, conditional, mandatory }
+
+PrivateIE-ID ::= CHOICE {
+ local INTEGER (0..65535),
+ global OBJECT IDENTIFIER
+}
+
+ProcedureCode ::= INTEGER (0..255)
+
+ProtocolExtensionID ::= INTEGER (0..65535)
+
+ProtocolIE-ID ::= INTEGER (0..65535)
+
+TriggeringMessage ::= ENUMERATED { initiating-message, successful-outcome, unsuccessfull-outcome, outcome }
+
+END
+
+
+
diff --git a/lib/asn1/test/asn1_SUITE_data/RANAP-Constants.asn1 b/lib/asn1/test/asn1_SUITE_data/RANAP-Constants.asn1
new file mode 100644
index 0000000000..c8df218b29
--- /dev/null
+++ b/lib/asn1/test/asn1_SUITE_data/RANAP-Constants.asn1
@@ -0,0 +1,355 @@
+-- RANAP-Constants.asn
+--
+-- Taken from 3GPP TS 25.413 V8.2.1 (2009-03)
+-- http://www.3gpp.org/ftp/Specs/archive/25_series/25.413/25413-821.zip
+--
+-- 9.3.6 Constant Definitions
+--
+-- $Id$
+--
+-- **************************************************************
+--
+-- Constant definitions
+--
+-- **************************************************************
+
+RANAP-Constants {
+itu-t (0) identified-organization (4) etsi (0) mobileDomain (0)
+umts-Access (20) modules (3) ranap (0) version1 (1) ranap-Constants (4) }
+
+DEFINITIONS AUTOMATIC TAGS ::=
+
+BEGIN
+
+-- **************************************************************
+--
+-- Elementary Procedures
+--
+-- **************************************************************
+
+id-RAB-Assignment INTEGER ::= 0
+id-Iu-Release INTEGER ::= 1
+id-RelocationPreparation INTEGER ::= 2
+id-RelocationResourceAllocation INTEGER ::= 3
+id-RelocationCancel INTEGER ::= 4
+id-SRNS-ContextTransfer INTEGER ::= 5
+id-SecurityModeControl INTEGER ::= 6
+id-DataVolumeReport INTEGER ::= 7
+id-Reset INTEGER ::= 9
+id-RAB-ReleaseRequest INTEGER ::= 10
+id-Iu-ReleaseRequest INTEGER ::= 11
+id-RelocationDetect INTEGER ::= 12
+id-RelocationComplete INTEGER ::= 13
+id-Paging INTEGER ::= 14
+id-CommonID INTEGER ::= 15
+id-CN-InvokeTrace INTEGER ::= 16
+id-LocationReportingControl INTEGER ::= 17
+id-LocationReport INTEGER ::= 18
+id-InitialUE-Message INTEGER ::= 19
+id-DirectTransfer INTEGER ::= 20
+id-OverloadControl INTEGER ::= 21
+id-ErrorIndication INTEGER ::= 22
+id-SRNS-DataForward INTEGER ::= 23
+id-ForwardSRNS-Context INTEGER ::= 24
+id-privateMessage INTEGER ::= 25
+id-CN-DeactivateTrace INTEGER ::= 26
+id-ResetResource INTEGER ::= 27
+id-RANAP-Relocation INTEGER ::= 28
+id-RAB-ModifyRequest INTEGER ::= 29
+id-LocationRelatedData INTEGER ::= 30
+id-InformationTransfer INTEGER ::= 31
+id-UESpecificInformation INTEGER ::= 32
+id-UplinkInformationExchange INTEGER ::= 33
+id-DirectInformationTransfer INTEGER ::= 34
+id-MBMSSessionStart INTEGER ::= 35
+id-MBMSSessionUpdate INTEGER ::= 36
+id-MBMSSessionStop INTEGER ::= 37
+id-MBMSUELinking INTEGER ::= 38
+id-MBMSRegistration INTEGER ::= 39
+id-MBMSCNDe-Registration-Procedure INTEGER ::= 40
+id-MBMSRABEstablishmentIndication INTEGER ::= 41
+id-MBMSRABRelease INTEGER ::= 42
+id-enhancedRelocationComplete INTEGER ::= 43
+id-enhancedRelocationCompleteConfirm INTEGER ::= 44
+id-RANAPenhancedRelocation INTEGER ::= 45
+id-SRVCCPreparation INTEGER ::= 256
+
+
+
+-- **************************************************************
+--
+-- Extension constants
+--
+-- **************************************************************
+
+maxPrivateIEs INTEGER ::= 65535
+maxProtocolExtensions INTEGER ::= 65535
+maxProtocolIEs INTEGER ::= 65535
+
+-- **************************************************************
+--
+-- Lists
+--
+-- **************************************************************
+
+maxNrOfDTs INTEGER ::= 15
+maxNrOfErrors INTEGER ::= 256
+maxNrOfIuSigConIds INTEGER ::= 250
+maxNrOfPDPDirections INTEGER ::= 2
+maxNrOfPoints INTEGER ::= 15
+maxNrOfRABs INTEGER ::= 256
+maxNrOfSeparateTrafficDirections INTEGER ::= 2
+maxNrOfSRBs INTEGER ::= 8
+maxNrOfVol INTEGER ::= 2
+maxNrOfLevels INTEGER ::= 256
+maxNrOfAltValues INTEGER ::= 16
+maxNrOfPLMNsSN INTEGER ::= 32
+maxNrOfLAs INTEGER ::= 65536
+maxNrOfSNAs INTEGER ::= 65536
+maxNrOfUEsToBeTraced INTEGER ::= 64
+maxNrOfInterfaces INTEGER ::= 16
+maxRAB-Subflows INTEGER ::= 7
+maxRAB-SubflowCombination INTEGER ::= 64
+maxSet INTEGER ::= 9
+maxNrOfHSDSCHMACdFlows-1 INTEGER ::= 7
+maxnoofMulticastServicesPerUE INTEGER ::= 128
+maxnoofMulticastServicesPerRNC INTEGER ::= 512
+maxMBMSSA INTEGER ::= 256
+maxMBMSRA INTEGER ::= 65536
+maxNrOfEDCHMACdFlows-1 INTEGER ::= 7
+maxGANSSSet INTEGER ::= 9
+
+-- **************************************************************
+--
+-- IEs
+--
+-- **************************************************************
+
+id-AreaIdentity INTEGER ::= 0
+id-CN-DomainIndicator INTEGER ::= 3
+id-Cause INTEGER ::= 4
+id-ChosenEncryptionAlgorithm INTEGER ::= 5
+id-ChosenIntegrityProtectionAlgorithm INTEGER ::= 6
+id-ClassmarkInformation2 INTEGER ::= 7
+id-ClassmarkInformation3 INTEGER ::= 8
+id-CriticalityDiagnostics INTEGER ::= 9
+id-DL-GTP-PDU-SequenceNumber INTEGER ::= 10
+id-EncryptionInformation INTEGER ::= 11
+id-IntegrityProtectionInformation INTEGER ::= 12
+id-IuTransportAssociation INTEGER ::= 13
+id-L3-Information INTEGER ::= 14
+id-LAI INTEGER ::= 15
+id-NAS-PDU INTEGER ::= 16
+id-NonSearchingIndication INTEGER ::= 17
+id-NumberOfSteps INTEGER ::= 18
+id-OMC-ID INTEGER ::= 19
+id-OldBSS-ToNewBSS-Information INTEGER ::= 20
+id-PagingAreaID INTEGER ::= 21
+id-PagingCause INTEGER ::= 22
+id-PermanentNAS-UE-ID INTEGER ::= 23
+id-RAB-ContextItem INTEGER ::= 24
+id-RAB-ContextList INTEGER ::= 25
+id-RAB-DataForwardingItem INTEGER ::= 26
+id-RAB-DataForwardingItem-SRNS-CtxReq INTEGER ::= 27
+id-RAB-DataForwardingList INTEGER ::= 28
+id-RAB-DataForwardingList-SRNS-CtxReq INTEGER ::= 29
+id-RAB-DataVolumeReportItem INTEGER ::= 30
+id-RAB-DataVolumeReportList INTEGER ::= 31
+id-RAB-DataVolumeReportRequestItem INTEGER ::= 32
+id-RAB-DataVolumeReportRequestList INTEGER ::= 33
+id-RAB-FailedItem INTEGER ::= 34
+id-RAB-FailedList INTEGER ::= 35
+id-RAB-ID INTEGER ::= 36
+id-RAB-QueuedItem INTEGER ::= 37
+id-RAB-QueuedList INTEGER ::= 38
+id-RAB-ReleaseFailedList INTEGER ::= 39
+id-RAB-ReleaseItem INTEGER ::= 40
+id-RAB-ReleaseList INTEGER ::= 41
+id-RAB-ReleasedItem INTEGER ::= 42
+id-RAB-ReleasedList INTEGER ::= 43
+id-RAB-ReleasedList-IuRelComp INTEGER ::= 44
+id-RAB-RelocationReleaseItem INTEGER ::= 45
+id-RAB-RelocationReleaseList INTEGER ::= 46
+id-RAB-SetupItem-RelocReq INTEGER ::= 47
+id-RAB-SetupItem-RelocReqAck INTEGER ::= 48
+id-RAB-SetupList-RelocReq INTEGER ::= 49
+id-RAB-SetupList-RelocReqAck INTEGER ::= 50
+id-RAB-SetupOrModifiedItem INTEGER ::= 51
+id-RAB-SetupOrModifiedList INTEGER ::= 52
+id-RAB-SetupOrModifyItem INTEGER ::= 53
+id-RAB-SetupOrModifyList INTEGER ::= 54
+id-RAC INTEGER ::= 55
+id-RelocationType INTEGER ::= 56
+id-RequestType INTEGER ::= 57
+id-SAI INTEGER ::= 58
+id-SAPI INTEGER ::= 59
+id-SourceID INTEGER ::= 60
+id-Source-ToTarget-TransparentContainer INTEGER ::= 61
+id-TargetID INTEGER ::= 62
+id-Target-ToSource-TransparentContainer INTEGER ::= 63
+id-TemporaryUE-ID INTEGER ::= 64
+id-TraceReference INTEGER ::= 65
+id-TraceType INTEGER ::= 66
+id-TransportLayerAddress INTEGER ::= 67
+id-TriggerID INTEGER ::= 68
+id-UE-ID INTEGER ::= 69
+id-UL-GTP-PDU-SequenceNumber INTEGER ::= 70
+id-RAB-FailedtoReportItem INTEGER ::= 71
+id-RAB-FailedtoReportList INTEGER ::= 72
+id-KeyStatus INTEGER ::= 75
+id-DRX-CycleLengthCoefficient INTEGER ::= 76
+id-IuSigConIdList INTEGER ::= 77
+id-IuSigConIdItem INTEGER ::= 78
+id-IuSigConId INTEGER ::= 79
+id-DirectTransferInformationItem-RANAP-RelocInf INTEGER ::= 80
+id-DirectTransferInformationList-RANAP-RelocInf INTEGER ::= 81
+id-RAB-ContextItem-RANAP-RelocInf INTEGER ::= 82
+id-RAB-ContextList-RANAP-RelocInf INTEGER ::= 83
+id-RAB-ContextFailedtoTransferItem INTEGER ::= 84
+id-RAB-ContextFailedtoTransferList INTEGER ::= 85
+id-GlobalRNC-ID INTEGER ::= 86
+id-RAB-ReleasedItem-IuRelComp INTEGER ::= 87
+id-MessageStructure INTEGER ::= 88
+id-Alt-RAB-Parameters INTEGER ::= 89
+id-Ass-RAB-Parameters INTEGER ::= 90
+id-RAB-ModifyList INTEGER ::= 91
+id-RAB-ModifyItem INTEGER ::= 92
+id-TypeOfError INTEGER ::= 93
+id-BroadcastAssistanceDataDecipheringKeys INTEGER ::= 94
+id-LocationRelatedDataRequestType INTEGER ::= 95
+id-GlobalCN-ID INTEGER ::= 96
+id-LastKnownServiceArea INTEGER ::= 97
+id-SRB-TrCH-Mapping INTEGER ::= 98
+id-InterSystemInformation-TransparentContainer INTEGER ::= 99
+id-NewBSS-To-OldBSS-Information INTEGER ::= 100
+id-SourceRNC-PDCP-context-info INTEGER ::= 103
+id-InformationTransferID INTEGER ::= 104
+id-SNA-Access-Information INTEGER ::= 105
+id-ProvidedData INTEGER ::= 106
+id-GERAN-BSC-Container INTEGER ::= 107
+id-GERAN-Classmark INTEGER ::= 108
+id-GERAN-Iumode-RAB-Failed-RABAssgntResponse-Item INTEGER ::= 109
+id-GERAN-Iumode-RAB-FailedList-RABAssgntResponse INTEGER ::= 110
+id-VerticalAccuracyCode INTEGER ::= 111
+id-ResponseTime INTEGER ::= 112
+id-PositioningPriority INTEGER ::= 113
+id-ClientType INTEGER ::= 114
+id-LocationRelatedDataRequestTypeSpecificToGERANIuMode INTEGER ::= 115
+id-SignallingIndication INTEGER ::= 116
+id-hS-DSCH-MAC-d-Flow-ID INTEGER ::= 117
+id-UESBI-Iu INTEGER ::= 118
+id-PositionData INTEGER ::= 119
+id-PositionDataSpecificToGERANIuMode INTEGER ::= 120
+id-CellLoadInformationGroup INTEGER ::= 121
+id-AccuracyFulfilmentIndicator INTEGER ::= 122
+id-InformationTransferType INTEGER ::= 123
+id-TraceRecordingSessionInformation INTEGER ::= 124
+id-TracePropagationParameters INTEGER ::= 125
+id-InterSystemInformationTransferType INTEGER ::= 126
+id-SelectedPLMN-ID INTEGER ::= 127
+id-RedirectionCompleted INTEGER ::= 128
+id-RedirectionIndication INTEGER ::= 129
+id-NAS-SequenceNumber INTEGER ::= 130
+id-RejectCauseValue INTEGER ::= 131
+id-APN INTEGER ::= 132
+id-CNMBMSLinkingInformation INTEGER ::= 133
+id-DeltaRAListofIdleModeUEs INTEGER ::= 134
+id-FrequenceLayerConvergenceFlag INTEGER ::= 135
+id-InformationExchangeID INTEGER ::= 136
+id-InformationExchangeType INTEGER ::= 137
+id-InformationRequested INTEGER ::= 138
+id-InformationRequestType INTEGER ::= 139
+id-IPMulticastAddress INTEGER ::= 140
+id-JoinedMBMSBearerServicesList INTEGER ::= 141
+id-LeftMBMSBearerServicesList INTEGER ::= 142
+id-MBMSBearerServiceType INTEGER ::= 143
+id-MBMSCNDe-Registration INTEGER ::= 144
+id-MBMSServiceArea INTEGER ::= 145
+id-MBMSSessionDuration INTEGER ::= 146
+id-MBMSSessionIdentity INTEGER ::= 147
+id-PDP-TypeInformation INTEGER ::= 148
+id-RAB-Parameters INTEGER ::= 149
+id-RAListofIdleModeUEs INTEGER ::= 150
+id-MBMSRegistrationRequestType INTEGER ::= 151
+id-SessionUpdateID INTEGER ::= 152
+id-TMGI INTEGER ::= 153
+id-TransportLayerInformation INTEGER ::= 154
+id-UnsuccessfulLinkingList INTEGER ::= 155
+id-MBMSLinkingInformation INTEGER ::= 156
+id-MBMSSessionRepetitionNumber INTEGER ::= 157
+id-AlternativeRABConfiguration INTEGER ::= 158
+id-AlternativeRABConfigurationRequest INTEGER ::= 159
+id-E-DCH-MAC-d-Flow-ID INTEGER ::= 160
+id-SourceBSS-ToTargetBSS-TransparentContainer INTEGER ::= 161
+id-TargetBSS-ToSourceBSS-TransparentContainer INTEGER ::= 162
+id-TimeToMBMSDataTransfer INTEGER ::= 163
+id-IncludeVelocity INTEGER ::= 164
+id-VelocityEstimate INTEGER ::= 165
+id-RedirectAttemptFlag INTEGER ::= 166
+id-RAT-Type INTEGER ::= 167
+id-PeriodicLocationInfo INTEGER ::= 168
+id-MBMSCountingInformation INTEGER ::= 169
+id-170-not-to-be-used-for-IE-ids INTEGER ::= 170
+id-ExtendedRNC-ID INTEGER ::= 171
+id-Alt-RAB-Parameter-ExtendedGuaranteedBitrateInf INTEGER ::= 172
+id-Alt-RAB-Parameter-ExtendedMaxBitrateInf INTEGER ::= 173
+id-Ass-RAB-Parameter-ExtendedGuaranteedBitrateList INTEGER ::= 174
+id-Ass-RAB-Parameter-ExtendedMaxBitrateList INTEGER ::= 175
+id-RAB-Parameter-ExtendedGuaranteedBitrateList INTEGER ::= 176
+id-RAB-Parameter-ExtendedMaxBitrateList INTEGER ::= 177
+id-Requested-RAB-Parameter-ExtendedMaxBitrateList INTEGER ::= 178
+id-Requested-RAB-Parameter-ExtendedGuaranteedBitrateList INTEGER ::= 179
+id-LAofIdleModeUEs INTEGER ::= 180
+id-newLAListofIdleModeUEs INTEGER ::= 181
+id-LAListwithNoIdleModeUEsAnyMore INTEGER ::= 182
+id-183-not-to-be-used-for-IE-ids INTEGER ::= 183
+id-GANSS-PositioningDataSet INTEGER ::= 184
+id-RequestedGANSSAssistanceData INTEGER ::= 185
+id-BroadcastGANSSAssistanceDataDecipheringKeys INTEGER ::= 186
+id-d-RNTI-for-NoIuCSUP INTEGER ::= 187
+id-RAB-SetupList-EnhancedRelocCompleteReq INTEGER ::= 188
+id-RAB-SetupItem-EnhancedRelocCompleteReq INTEGER ::= 189
+id-RAB-SetupList-EnhancedRelocCompleteRes INTEGER ::= 190
+id-RAB-SetupItem-EnhancedRelocCompleteRes INTEGER ::= 191
+id-RAB-SetupList-EnhRelocInfoReq INTEGER ::= 192
+id-RAB-SetupItem-EnhRelocInfoReq INTEGER ::= 193
+id-RAB-SetupList-EnhRelocInfoRes INTEGER ::= 194
+id-RAB-SetupItem-EnhRelocInfoRes INTEGER ::= 195
+id-OldIuSigConId INTEGER ::= 196
+id-RAB-FailedList-EnhRelocInfoRes INTEGER ::= 197
+id-RAB-FailedItem-EnhRelocInfoRes INTEGER ::= 198
+id-Global-ENB-ID INTEGER ::= 199
+id-UE-History-Information INTEGER ::= 200
+id-MBMSSynchronisationInformation INTEGER ::= 201
+id-SubscriberProfileIDforRFP INTEGER ::= 202
+id-CSG-Id INTEGER ::= 203
+id-OldIuSigConIdCS INTEGER ::= 204
+id-OldIuSigConIdPS INTEGER ::= 205
+id-GlobalCN-IDCS INTEGER ::= 206
+id-GlobalCN-IDPS INTEGER ::= 207
+id-SourceExtendedRNC-ID INTEGER ::= 208
+id-RAB-ToBeReleasedItem-EnhancedRelocCompleteRes INTEGER ::= 209
+id-RAB-ToBeReleasedList-EnhancedRelocCompleteRes INTEGER ::= 210
+id-SourceRNC-ID INTEGER ::= 211
+id-Relocation-TargetRNC-ID INTEGER ::= 212
+id-Relocation-TargetExtendedRNC-ID INTEGER ::= 213
+id-Alt-RAB-Parameter-SupportedGuaranteedBitrateInf INTEGER ::= 214
+id-Alt-RAB-Parameter-SupportedMaxBitrateInf INTEGER ::= 215
+id-Ass-RAB-Parameter-SupportedGuaranteedBitrateList INTEGER ::= 216
+id-Ass-RAB-Parameter-SupportedMaxBitrateList INTEGER ::= 217
+id-RAB-Parameter-SupportedGuaranteedBitrateList INTEGER ::= 218
+id-RAB-Parameter-SupportedMaxBitrateList INTEGER ::= 219
+id-Requested-RAB-Parameter-SupportedMaxBitrateList INTEGER ::= 220
+id-Requested-RAB-Parameter-SupportedGuaranteedBitrateList INTEGER ::= 221
+id-Relocation-SourceRNC-ID INTEGER ::= 222
+id-Relocation-SourceExtendedRNC-ID INTEGER ::= 223
+id-EncryptionKey INTEGER ::= 224
+id-IntegrityProtectionKey INTEGER ::= 225
+id-SRVCC-HO-Indication INTEGER ::= 226
+id-SRVCC-Information INTEGER ::= 227
+id-SRVCC-Operation-Possible INTEGER ::= 228
+
+END
+
+
+
diff --git a/lib/asn1/test/asn1_SUITE_data/RANAP-Containers.asn1 b/lib/asn1/test/asn1_SUITE_data/RANAP-Containers.asn1
new file mode 100644
index 0000000000..5168fa6917
--- /dev/null
+++ b/lib/asn1/test/asn1_SUITE_data/RANAP-Containers.asn1
@@ -0,0 +1,206 @@
+-- RANAP-Containers.asn
+--
+-- Taken from 3GPP TS 25.413 V8.2.1 (2009-03)
+-- http://www.3gpp.org/ftp/Specs/archive/25_series/25.413/25413-821.zip
+--
+-- 9.3.7 Container Definitions
+--
+-- $Id$
+--
+
+-- **************************************************************
+--
+-- Container definitions
+--
+-- **************************************************************
+
+RANAP-Containers {
+itu-t (0) identified-organization (4) etsi (0) mobileDomain (0)
+umts-Access (20) modules (3) ranap (0) version1 (1) ranap-Containers (5) }
+
+DEFINITIONS AUTOMATIC TAGS ::=
+
+BEGIN
+
+-- **************************************************************
+--
+-- IE parameter types from other modules.
+--
+-- **************************************************************
+
+IMPORTS
+ Criticality,
+ Presence,
+ PrivateIE-ID,
+ ProtocolExtensionID,
+ ProtocolIE-ID
+FROM RANAP-CommonDataTypes
+
+ maxPrivateIEs,
+ maxProtocolExtensions,
+ maxProtocolIEs
+FROM RANAP-Constants;
+
+-- **************************************************************
+--
+-- Class Definition for Protocol IEs
+--
+-- **************************************************************
+
+RANAP-PROTOCOL-IES ::= CLASS {
+ &id ProtocolIE-ID UNIQUE,
+ &criticality Criticality,
+ &Value,
+ &presence Presence
+}
+WITH SYNTAX {
+ ID &id
+ CRITICALITY &criticality
+ TYPE &Value
+ PRESENCE &presence
+}
+
+-- **************************************************************
+--
+-- Class Definition for Protocol IEs
+--
+-- **************************************************************
+
+RANAP-PROTOCOL-IES-PAIR ::= CLASS {
+ &id ProtocolIE-ID UNIQUE,
+ &firstCriticality Criticality,
+ &FirstValue,
+ &secondCriticality Criticality,
+ &SecondValue,
+ &presence Presence
+}
+WITH SYNTAX {
+ ID &id
+ FIRST CRITICALITY &firstCriticality
+ FIRST TYPE &FirstValue
+ SECOND CRITICALITY &secondCriticality
+ SECOND TYPE &SecondValue
+ PRESENCE &presence
+}
+
+-- **************************************************************
+--
+-- Class Definition for Protocol Extensions
+--
+-- **************************************************************
+
+RANAP-PROTOCOL-EXTENSION ::= CLASS {
+ &id ProtocolExtensionID UNIQUE,
+ &criticality Criticality,
+ &Extension,
+ &presence Presence
+}
+WITH SYNTAX {
+ ID &id
+ CRITICALITY &criticality
+ EXTENSION &Extension
+ PRESENCE &presence
+}
+
+-- **************************************************************
+--
+-- Class Definition for Private IEs
+--
+-- **************************************************************
+
+RANAP-PRIVATE-IES ::= CLASS {
+ &id PrivateIE-ID,
+ &criticality Criticality,
+ &Value,
+ &presence Presence
+}
+WITH SYNTAX {
+ ID &id
+ CRITICALITY &criticality
+ TYPE &Value
+ PRESENCE &presence
+}
+
+-- **************************************************************
+--
+-- Container for Protocol IEs
+--
+-- **************************************************************
+
+ProtocolIE-Container {RANAP-PROTOCOL-IES : IEsSetParam} ::=
+ SEQUENCE (SIZE (0..maxProtocolIEs)) OF
+ ProtocolIE-Field {{IEsSetParam}}
+
+ProtocolIE-Field {RANAP-PROTOCOL-IES : IEsSetParam} ::= SEQUENCE {
+ id RANAP-PROTOCOL-IES.&id ({IEsSetParam}),
+ criticality RANAP-PROTOCOL-IES.&criticality ({IEsSetParam}{@id}),
+ value RANAP-PROTOCOL-IES.&Value ({IEsSetParam}{@id})
+}
+
+-- **************************************************************
+--
+-- Container for Protocol IE Pairs
+--
+-- **************************************************************
+
+ProtocolIE-ContainerPair {RANAP-PROTOCOL-IES-PAIR : IEsSetParam} ::=
+ SEQUENCE (SIZE (0..maxProtocolIEs)) OF
+ ProtocolIE-FieldPair {{IEsSetParam}}
+
+ProtocolIE-FieldPair {RANAP-PROTOCOL-IES-PAIR : IEsSetParam} ::= SEQUENCE {
+ id RANAP-PROTOCOL-IES-PAIR.&id ({IEsSetParam}),
+ firstCriticality RANAP-PROTOCOL-IES-PAIR.&firstCriticality ({IEsSetParam}{@id}),
+ firstValue RANAP-PROTOCOL-IES-PAIR.&FirstValue ({IEsSetParam}{@id}),
+ secondCriticality RANAP-PROTOCOL-IES-PAIR.&secondCriticality ({IEsSetParam}{@id}),
+ secondValue RANAP-PROTOCOL-IES-PAIR.&SecondValue ({IEsSetParam}{@id})
+}
+
+-- **************************************************************
+--
+-- Container Lists for Protocol IE Containers
+--
+-- **************************************************************
+
+ProtocolIE-ContainerList {INTEGER : lowerBound, INTEGER : upperBound, RANAP-PROTOCOL-IES : IEsSetParam} ::=
+ SEQUENCE (SIZE (lowerBound..upperBound)) OF
+ ProtocolIE-Container {{IEsSetParam}}
+
+ProtocolIE-ContainerPairList {INTEGER : lowerBound, INTEGER : upperBound, RANAP-PROTOCOL-IES-PAIR : IEsSetParam} ::=
+ SEQUENCE (SIZE (lowerBound..upperBound)) OF
+ ProtocolIE-ContainerPair {{IEsSetParam}}
+
+-- **************************************************************
+--
+-- Container for Protocol Extensions
+--
+-- **************************************************************
+
+ProtocolExtensionContainer {RANAP-PROTOCOL-EXTENSION : ExtensionSetParam} ::=
+ SEQUENCE (SIZE (1..maxProtocolExtensions)) OF
+ ProtocolExtensionField {{ExtensionSetParam}}
+
+ProtocolExtensionField {RANAP-PROTOCOL-EXTENSION : ExtensionSetParam} ::= SEQUENCE {
+ id RANAP-PROTOCOL-EXTENSION.&id ({ExtensionSetParam}),
+ criticality RANAP-PROTOCOL-EXTENSION.&criticality ({ExtensionSetParam}{@id}),
+ extensionValue RANAP-PROTOCOL-EXTENSION.&Extension ({ExtensionSetParam}{@id})
+}
+
+-- **************************************************************
+--
+-- Container for Private IEs
+--
+-- **************************************************************
+
+PrivateIE-Container {RANAP-PRIVATE-IES : IEsSetParam } ::=
+ SEQUENCE (SIZE (1.. maxPrivateIEs)) OF
+ PrivateIE-Field {{IEsSetParam}}
+
+PrivateIE-Field {RANAP-PRIVATE-IES : IEsSetParam} ::= SEQUENCE {
+ id RANAP-PRIVATE-IES.&id ({IEsSetParam}),
+ criticality RANAP-PRIVATE-IES.&criticality ({IEsSetParam}{@id}),
+ value RANAP-PRIVATE-IES.&Value ({IEsSetParam}{@id})
+}
+
+END
+
+
diff --git a/lib/asn1/test/asn1_SUITE_data/RANAP-IEs.asn1 b/lib/asn1/test/asn1_SUITE_data/RANAP-IEs.asn1
new file mode 100644
index 0000000000..351dad436b
--- /dev/null
+++ b/lib/asn1/test/asn1_SUITE_data/RANAP-IEs.asn1
@@ -0,0 +1,2081 @@
+-- RANAP-IEs.asn
+--
+-- Taken from 3GPP TS 25.413 V8.2.1 (2009-03)
+-- http://www.3gpp.org/ftp/Specs/archive/25_series/25.413/25413-821.zip
+--
+-- 9.3.4 Information Element Definitions
+--
+-- $Id$
+--
+
+-- **************************************************************
+--
+-- Information Element Definitions
+--
+-- **************************************************************
+
+RANAP-IEs {
+itu-t (0) identified-organization (4) etsi (0) mobileDomain (0)
+umts-Access (20) modules (3) ranap (0) version1 (1) ranap-IEs (2) }
+
+DEFINITIONS AUTOMATIC TAGS ::=
+
+BEGIN
+
+IMPORTS
+ maxNrOfErrors,
+ maxNrOfPDPDirections,
+ maxNrOfPoints,
+ maxNrOfRABs,
+ maxNrOfSRBs,
+ maxNrOfSeparateTrafficDirections,
+ maxRAB-Subflows,
+ maxRAB-SubflowCombination,
+ maxNrOfLevels,
+ maxNrOfAltValues,
+ maxNrOfSNAs,
+ maxNrOfLAs,
+ maxNrOfPLMNsSN,
+ maxSet,
+ maxNrOfHSDSCHMACdFlows-1,
+ maxNrOfUEsToBeTraced,
+ maxNrOfInterfaces,
+ maxnoofMulticastServicesPerRNC,
+ maxMBMSSA,
+ maxMBMSRA,
+ maxnoofMulticastServicesPerUE,
+ maxNrOfEDCHMACdFlows-1,
+ maxGANSSSet,
+
+ id-CN-DomainIndicator,
+ id-MessageStructure,
+ id-SRB-TrCH-Mapping,
+ id-TypeOfError,
+ id-hS-DSCH-MAC-d-Flow-ID,
+ id-SignallingIndication,
+ id-CellLoadInformationGroup,
+ id-TraceRecordingSessionInformation,
+ id-MBMSLinkingInformation,
+ id-AlternativeRABConfiguration,
+ id-AlternativeRABConfigurationRequest,
+ id-E-DCH-MAC-d-Flow-ID,
+ id-RAC,
+ id-Alt-RAB-Parameter-ExtendedGuaranteedBitrateInf,
+ id-Alt-RAB-Parameter-ExtendedMaxBitrateInf,
+ id-Ass-RAB-Parameter-ExtendedGuaranteedBitrateList,
+ id-Ass-RAB-Parameter-ExtendedMaxBitrateList,
+ id-RAB-Parameter-ExtendedGuaranteedBitrateList,
+ id-RAB-Parameter-ExtendedMaxBitrateList,
+ id-Requested-RAB-Parameter-ExtendedMaxBitrateList,
+ id-Requested-RAB-Parameter-ExtendedGuaranteedBitrateList,
+ id-LAofIdleModeUEs,
+ id-newLAListofIdleModeUEs,
+ id-LAListwithNoIdleModeUEsAnyMore,
+ id-ExtendedRNC-ID,
+ id-GANSS-PositioningDataSet,
+ id-d-RNTI-for-NoIuCSUP,
+ id-UE-History-Information,
+ id-SubscriberProfileIDforRFP,
+ id-Alt-RAB-Parameter-SupportedGuaranteedBitrateInf,
+ id-Alt-RAB-Parameter-SupportedMaxBitrateInf,
+ id-Ass-RAB-Parameter-SupportedGuaranteedBitrateList,
+ id-Ass-RAB-Parameter-SupportedMaxBitrateList,
+ id-RAB-Parameter-SupportedGuaranteedBitrateList,
+ id-RAB-Parameter-SupportedMaxBitrateList,
+ id-Requested-RAB-Parameter-SupportedMaxBitrateList,
+ id-Requested-RAB-Parameter-SupportedGuaranteedBitrateList
+
+
+FROM RANAP-Constants
+
+ Criticality,
+ ProcedureCode,
+ ProtocolIE-ID,
+ TriggeringMessage
+FROM RANAP-CommonDataTypes
+
+ ProtocolExtensionContainer{},
+ RANAP-PROTOCOL-EXTENSION
+FROM RANAP-Containers;
+
+-- A
+
+AccuracyFulfilmentIndicator ::= ENUMERATED{
+ requested-Accuracy-Fulfilled,
+ requested-Accuracy-Not-Fulfilled,
+ ...
+}
+
+AllocationOrRetentionPriority ::= SEQUENCE {
+ priorityLevel PriorityLevel,
+ pre-emptionCapability Pre-emptionCapability,
+ pre-emptionVulnerability Pre-emptionVulnerability,
+ queuingAllowed QueuingAllowed,
+ iE-Extensions ProtocolExtensionContainer { {AllocationOrRetentionPriority-ExtIEs} } OPTIONAL,
+ ...
+}
+
+AllocationOrRetentionPriority-ExtIEs RANAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+Alt-RAB-Parameters ::= SEQUENCE {
+ altMaxBitrateInf Alt-RAB-Parameter-MaxBitrateInf OPTIONAL,
+ altGuaranteedBitRateInf Alt-RAB-Parameter-GuaranteedBitrateInf OPTIONAL,
+ iE-Extensions ProtocolExtensionContainer { {Alt-RAB-Parameters-ExtIEs} } OPTIONAL,
+ ...
+}
+
+Alt-RAB-Parameters-ExtIEs RANAP-PROTOCOL-EXTENSION ::= {
+-- Extension for Release 6 to indicate an alternative RAB configuration --
+ { ID id-AlternativeRABConfiguration CRITICALITY ignore EXTENSION RAB-Parameters PRESENCE optional }|
+-- Extension for Release 7 to indicate an alternative list of Extended Guaranteed Bitrates --
+{ ID id-Alt-RAB-Parameter-ExtendedGuaranteedBitrateInf CRITICALITY ignore EXTENSION Alt-RAB-Parameter-ExtendedGuaranteedBitrateInf PRESENCE optional }|
+-- Extension for Release 7 to indicate an alternative list of Extended Maximum Bitrates --
+{ ID id-Alt-RAB-Parameter-ExtendedMaxBitrateInf CRITICALITY ignore EXTENSION Alt-RAB-Parameter-ExtendedMaxBitrateInf PRESENCE optional }|
+-- Extension for Release 8 to indicate an alternative list of Supported Maximum Bitrates --
+{ ID id-Alt-RAB-Parameter-SupportedMaxBitrateInf CRITICALITY reject EXTENSION Alt-RAB-Parameter-SupportedMaxBitrateInf PRESENCE optional }|
+-- Extension for Release 8 to indicate an alternative list of Supported Guaranteed Bitrates --
+{ ID id-Alt-RAB-Parameter-SupportedGuaranteedBitrateInf CRITICALITY reject EXTENSION Alt-RAB-Parameter-SupportedGuaranteedBitrateInf PRESENCE optional },
+ ...
+}
+
+Alt-RAB-Parameter-ExtendedGuaranteedBitrateInf ::= SEQUENCE {
+ altExtendedGuaranteedBitrateType Alt-RAB-Parameter-GuaranteedBitrateType,
+ altExtendedGuaranteedBitrates Alt-RAB-Parameter-ExtendedGuaranteedBitrates OPTIONAL
+ -- This IE shall be present if the Type of Extended Guaranteed Bit Rates Information IE is set to "Value range" or "Discrete values" --,
+ ...
+}
+
+Alt-RAB-Parameter-ExtendedGuaranteedBitrates ::= SEQUENCE (SIZE (1..maxNrOfAltValues)) OF
+ Alt-RAB-Parameter-ExtendedGuaranteedBitrateList
+
+Alt-RAB-Parameter-ExtendedGuaranteedBitrateList ::= SEQUENCE (SIZE (1..maxNrOfSeparateTrafficDirections)) OF ExtendedGuaranteedBitrate
+
+Alt-RAB-Parameter-GuaranteedBitrateInf ::= SEQUENCE {
+ altGuaranteedBitrateType Alt-RAB-Parameter-GuaranteedBitrateType,
+ altGuaranteedBitrates Alt-RAB-Parameter-GuaranteedBitrates OPTIONAL
+ -- This IE shall be present if the Type of Guaranteed Bit Rates Information IE is set to "Value range" or "Discrete values" --,
+ ...
+}
+
+Alt-RAB-Parameter-GuaranteedBitrateType ::= ENUMERATED{
+ unspecified,
+ value-range,
+ discrete-values,
+ ...
+}
+
+Alt-RAB-Parameter-GuaranteedBitrates ::= SEQUENCE (SIZE (1..maxNrOfAltValues)) OF
+ Alt-RAB-Parameter-GuaranteedBitrateList
+
+
+Alt-RAB-Parameter-GuaranteedBitrateList ::= SEQUENCE (SIZE (1..maxNrOfSeparateTrafficDirections)) OF GuaranteedBitrate
+
+Alt-RAB-Parameter-SupportedGuaranteedBitrateInf ::= SEQUENCE {
+ altSupportedGuaranteedBitrateType Alt-RAB-Parameter-GuaranteedBitrateType,
+ altSupportedGuaranteedBitrates Alt-RAB-Parameter-SupportedGuaranteedBitrates OPTIONAL
+ -- This IE shall be present if the Type of Supported Guaranteed Bit Rates Information IE is set to "Value range" or "Discrete values" --,
+ iE-Extensions ProtocolExtensionContainer { { Alt-RAB-Parameter-SupportedGuaranteedBitrateInf-ExtIEs} } OPTIONAL,
+ ...
+}
+
+Alt-RAB-Parameter-SupportedGuaranteedBitrateInf-ExtIEs RANAP-PROTOCOL-EXTENSION ::= {
+...
+}
+
+Alt-RAB-Parameter-SupportedGuaranteedBitrates ::= SEQUENCE (SIZE (1..maxNrOfAltValues)) OF
+ SupportedRAB-ParameterBitrateList
+
+
+Alt-RAB-Parameter-ExtendedMaxBitrateInf ::= SEQUENCE {
+ altExtendedMaxBitrateType Alt-RAB-Parameter-MaxBitrateType,
+ altExtendedMaxBitrates Alt-RAB-Parameter-ExtendedMaxBitrates OPTIONAL
+ -- This IE shall be present if the Type of Extended Alternative Maximum Bit Rates Information IE is set to "Value range" or "Discrete values" --,
+ ...
+}
+
+Alt-RAB-Parameter-ExtendedMaxBitrates ::= SEQUENCE (SIZE (1..maxNrOfAltValues)) OF
+ Alt-RAB-Parameter-ExtendedMaxBitrateList
+
+Alt-RAB-Parameter-ExtendedMaxBitrateList ::= SEQUENCE (SIZE (1..maxNrOfSeparateTrafficDirections)) OF ExtendedMaxBitrate
+
+Alt-RAB-Parameter-MaxBitrateInf ::= SEQUENCE {
+ altMaxBitrateType Alt-RAB-Parameter-MaxBitrateType,
+ altMaxBitrates Alt-RAB-Parameter-MaxBitrates OPTIONAL
+ -- This IE shall be present if the Type of Alternative Maximun Bit Rates Information IE is set to "Value range" or "Discrete values" --,
+ ...
+}
+
+Alt-RAB-Parameter-MaxBitrateType ::= ENUMERATED{
+ unspecified,
+ value-range,
+ discrete-values,
+ ...
+}
+
+Alt-RAB-Parameter-MaxBitrates ::= SEQUENCE (SIZE (1..maxNrOfAltValues)) OF
+ Alt-RAB-Parameter-MaxBitrateList
+
+
+Alt-RAB-Parameter-MaxBitrateList ::= SEQUENCE (SIZE (1..maxNrOfSeparateTrafficDirections)) OF MaxBitrate
+
+
+Alt-RAB-Parameter-SupportedMaxBitrateInf ::= SEQUENCE {
+ altSupportedMaxBitrateType Alt-RAB-Parameter-MaxBitrateType,
+ altSupportedMaxBitrates Alt-RAB-Parameter-SupportedMaxBitrates OPTIONAL
+ -- This IE shall be present if the Type of Supported Alternative Maximun Bit Rates Information IE is set to "Value range" or "Discrete values" --,
+ iE-Extensions ProtocolExtensionContainer { { Alt-RAB-Parameter-SupportedMaxBitrateInf-ExtIEs} } OPTIONAL,
+...
+}
+
+Alt-RAB-Parameter-SupportedMaxBitrateInf-ExtIEs RANAP-PROTOCOL-EXTENSION ::= {
+...
+}
+
+
+Alt-RAB-Parameter-SupportedMaxBitrates ::= SEQUENCE (SIZE (1..maxNrOfAltValues)) OF
+ SupportedRAB-ParameterBitrateList
+
+AlternativeRABConfigurationRequest ::= ENUMERATED{
+ alternative-RAB-configuration-Requested,
+ ...
+}
+
+APN ::= OCTET STRING (SIZE (1..255))
+-- Reference: 23.003
+
+AreaIdentity ::= CHOICE {
+ sAI SAI,
+ geographicalArea GeographicalArea,
+ ...
+}
+
+Ass-RAB-Parameters ::= SEQUENCE {
+ assMaxBitrateInf Ass-RAB-Parameter-MaxBitrateList OPTIONAL,
+ assGuaranteedBitRateInf Ass-RAB-Parameter-GuaranteedBitrateList OPTIONAL,
+ iE-Extensions ProtocolExtensionContainer { {Ass-RAB-Parameters-ExtIEs} } OPTIONAL,
+ ...
+}
+
+Ass-RAB-Parameters-ExtIEs RANAP-PROTOCOL-EXTENSION ::= {
+-- Extension for Release 7 to indicate an extended assigned Guaranteed Bitrate --
+ { ID id-Ass-RAB-Parameter-ExtendedGuaranteedBitrateList CRITICALITY reject EXTENSION Ass-RAB-Parameter-ExtendedGuaranteedBitrateList PRESENCE optional }|
+-- Extension for Release 7 to indicate an extended assigned Maximum Bitrate --
+ { ID id-Ass-RAB-Parameter-ExtendedMaxBitrateList CRITICALITY reject EXTENSION Ass-RAB-Parameter-ExtendedMaxBitrateList PRESENCE optional }|
+-- Extension for Release 8 to indicate an supported assigned Maximum Bitrate --
+ { ID id-Ass-RAB-Parameter-SupportedMaxBitrateList CRITICALITY ignore EXTENSION SupportedRAB-ParameterBitrateList PRESENCE optional }|
+-- Extension for Release 8 to indicate an supported assigned Guaranteed Bitrate --
+ { ID id-Ass-RAB-Parameter-SupportedGuaranteedBitrateList CRITICALITY ignore EXTENSION SupportedRAB-ParameterBitrateList PRESENCE optional },
+ ...
+}
+
+Ass-RAB-Parameter-ExtendedGuaranteedBitrateList ::= SEQUENCE (SIZE (1..maxNrOfSeparateTrafficDirections)) OF ExtendedGuaranteedBitrate
+
+Ass-RAB-Parameter-ExtendedMaxBitrateList ::= SEQUENCE (SIZE (1..maxNrOfSeparateTrafficDirections)) OF ExtendedMaxBitrate
+
+
+Ass-RAB-Parameter-GuaranteedBitrateList ::= SEQUENCE (SIZE (1..maxNrOfSeparateTrafficDirections)) OF GuaranteedBitrate
+
+
+Ass-RAB-Parameter-MaxBitrateList ::= SEQUENCE (SIZE (1..maxNrOfSeparateTrafficDirections)) OF MaxBitrate
+
+AuthorisedPLMNs ::= SEQUENCE (SIZE (1..maxNrOfPLMNsSN)) OF
+ SEQUENCE {
+ pLMNidentity PLMNidentity,
+ authorisedSNAsList AuthorisedSNAs OPTIONAL,
+ iE-Extensions ProtocolExtensionContainer { {AuthorisedPLMNs-ExtIEs} } OPTIONAL,
+ ...
+ }
+
+AuthorisedPLMNs-ExtIEs RANAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+AuthorisedSNAs ::= SEQUENCE (SIZE (1..maxNrOfSNAs)) OF SNAC
+
+
+-- B
+
+BindingID ::= OCTET STRING (SIZE (4))
+
+BroadcastAssistanceDataDecipheringKeys ::= SEQUENCE {
+ cipheringKeyFlag BIT STRING (SIZE (1)),
+ currentDecipheringKey BIT STRING (SIZE (56)),
+ nextDecipheringKey BIT STRING (SIZE (56)),
+ ...
+}
+
+-- C
+
+
+Cause ::= CHOICE {
+ radioNetwork CauseRadioNetwork,
+ transmissionNetwork CauseTransmissionNetwork,
+ nAS CauseNAS,
+ protocol CauseProtocol,
+ misc CauseMisc,
+ non-Standard CauseNon-Standard,
+ ...,
+ radioNetworkExtension CauseRadioNetworkExtension
+}
+
+CauseMisc ::= INTEGER {
+ om-intervention (113),
+ no-resource-available (114),
+ unspecified-failure (115),
+ network-optimisation (116)
+} (113..128)
+
+CauseNAS ::= INTEGER {
+ user-restriction-start-indication (81),
+ user-restriction-end-indication (82),
+ normal-release (83)
+} (81..96)
+
+CauseProtocol ::= INTEGER {
+ transfer-syntax-error (97),
+ semantic-error (98),
+ message-not-compatible-with-receiver-state (99),
+ abstract-syntax-error-reject (100),
+ abstract-syntax-error-ignore-and-notify (101),
+ abstract-syntax-error-falsely-constructed-message (102)
+} (97..112)
+
+CauseRadioNetwork ::= INTEGER {
+ rab-pre-empted (1),
+ trelocoverall-expiry (2),
+ trelocprep-expiry (3),
+ treloccomplete-expiry (4),
+ tqueing-expiry (5),
+ relocation-triggered (6),
+ trellocalloc-expiry(7),
+ unable-to-establish-during-relocation (8),
+ unknown-target-rnc (9),
+ relocation-cancelled (10),
+ successful-relocation (11),
+ requested-ciphering-and-or-integrity-protection-algorithms-not-supported (12),
+ conflict-with-already-existing-integrity-protection-and-or-ciphering-information (13),
+ failure-in-the-radio-interface-procedure (14),
+ release-due-to-utran-generated-reason (15),
+ user-inactivity (16),
+ time-critical-relocation (17),
+ requested-traffic-class-not-available (18),
+ invalid-rab-parameters-value (19),
+ requested-maximum-bit-rate-not-available (20),
+ requested-guaranteed-bit-rate-not-available (21),
+ requested-transfer-delay-not-achievable (22),
+ invalid-rab-parameters-combination (23),
+ condition-violation-for-sdu-parameters (24),
+ condition-violation-for-traffic-handling-priority (25),
+ condition-violation-for-guaranteed-bit-rate (26),
+ user-plane-versions-not-supported (27),
+ iu-up-failure (28),
+ relocation-failure-in-target-CN-RNC-or-target-system(29),
+ invalid-RAB-ID (30),
+ no-remaining-rab (31),
+ interaction-with-other-procedure (32),
+ requested-maximum-bit-rate-for-dl-not-available (33),
+ requested-maximum-bit-rate-for-ul-not-available (34),
+ requested-guaranteed-bit-rate-for-dl-not-available (35),
+ requested-guaranteed-bit-rate-for-ul-not-available (36),
+ repeated-integrity-checking-failure (37),
+ requested-request-type-not-supported (38),
+ request-superseded (39),
+ release-due-to-UE-generated-signalling-connection-release (40),
+ resource-optimisation-relocation (41),
+ requested-information-not-available (42),
+ relocation-desirable-for-radio-reasons (43),
+ relocation-not-supported-in-target-RNC-or-target-system (44),
+ directed-retry (45),
+ radio-connection-with-UE-Lost (46),
+ rNC-unable-to-establish-all-RFCs (47),
+ deciphering-keys-not-available(48),
+ dedicated-assistance-data-not-available(49),
+ relocation-target-not-allowed (50),
+ location-reporting-congestion (51),
+ reduce-load-in-serving-cell (52),
+ no-radio-resources-available-in-target-cell (53),
+ gERAN-Iumode-failure (54),
+ access-restricted-due-to-shared-networks (55),
+ incoming-relocation-not-supported-due-to-PUESBINE-feature (56),
+ traffic-load-in-the-target-cell-higher-than-in-the-source-cell (57),
+ mBMS-no-multicast-service-for-this-UE(58),
+ mBMS-unknown-UE-ID(59),
+ successful-MBMS-session-start-no-data-bearer-necessary(60),
+ mBMS-superseded-due-to-NNSF(61),
+ mBMS-UE-linking-already-done(62),
+ mBMS-UE-de-linking-failure-no-existing-UE-linking(63),
+ tMGI-unknown(64)
+} (1..64)
+
+CauseRadioNetworkExtension ::= INTEGER {
+ iP-multicast-address-and-APN-not-valid(257),
+ mBMS-de-registration-rejected-due-to-implicit-registration(258),
+ mBMS-request-superseded(259),
+ mBMS-de-registration-during-session-not-allowed(260),
+ mBMS-no-data-bearer-necessary(261),
+ periodicLocationInformationNotAvailable(262),
+ gTP-Resources-Unavailable(263),
+ tMGI-inUse-overlapping-MBMS-service-area(264),
+ mBMS-no-cell-in-MBMS-service-area(265),
+ no-Iu-CS-UP-relocation(266),
+ successful-MBMS-Session-Start-IP-Multicast-Bearer-established(267),
+ cS-fallback-triggered(268)
+} (257..512)
+
+CauseNon-Standard ::= INTEGER (129..256)
+-- Cause value 256 shall not be used --
+
+CauseTransmissionNetwork ::= INTEGER {
+ signalling-transport-resource-failure (65),
+ iu-transport-connection-failed-to-establish (66)
+} (65..80)
+
+Cell-Capacity-Class-Value ::= INTEGER (1..100,...)
+
+CellLoadInformation ::= SEQUENCE {
+ cell-Capacity-Class-Value Cell-Capacity-Class-Value,
+ loadValue LoadValue,
+ rTLoadValue RTLoadValue OPTIONAL,
+ nRTLoadInformationValue NRTLoadInformationValue OPTIONAL,
+ iE-Extensions ProtocolExtensionContainer { { CellLoadInformation-ExtIEs } } OPTIONAL,
+ ...
+}
+
+CellLoadInformation-ExtIEs RANAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+CellLoadInformationGroup ::= SEQUENCE {
+ sourceCellID SourceCellID,
+ uplinkCellLoadInformation CellLoadInformation OPTIONAL,
+ downlinkCellLoadInformation CellLoadInformation OPTIONAL,
+ iE-Extensions ProtocolExtensionContainer { { CellLoadInformationGroup-ExtIEs } } OPTIONAL,
+ ...
+}
+
+CellLoadInformationGroup-ExtIEs RANAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+CellType ::= ENUMERATED{
+ macro,
+ micro,
+ pico,
+ femto,
+ ...
+}
+
+ClientType ::= ENUMERATED {
+ emergency-Services,
+ value-Added-Services,
+ pLMN-Operator-Services,
+ lawful-Intercept-Services,
+ pLMN-Operator-Broadcast-Services,
+ pLMN-Operator-O-et-M,
+ pLMN-Operator-Anonymous-Statistics,
+ pLMN-Operator-Target-MS-Service-Support,
+ ...
+}
+
+CriticalityDiagnostics ::= SEQUENCE {
+ procedureCode ProcedureCode OPTIONAL,
+ triggeringMessage TriggeringMessage OPTIONAL,
+ procedureCriticality Criticality OPTIONAL,
+ iEsCriticalityDiagnostics CriticalityDiagnostics-IE-List OPTIONAL,
+ iE-Extensions ProtocolExtensionContainer { {CriticalityDiagnostics-ExtIEs} } OPTIONAL,
+ ...
+}
+
+CriticalityDiagnostics-ExtIEs RANAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+CriticalityDiagnostics-IE-List ::= SEQUENCE (SIZE (1..maxNrOfErrors)) OF
+ SEQUENCE {
+ iECriticality Criticality,
+ iE-ID ProtocolIE-ID,
+ repetitionNumber RepetitionNumber0 OPTIONAL,
+ iE-Extensions ProtocolExtensionContainer { {CriticalityDiagnostics-IE-List-ExtIEs} } OPTIONAL,
+ ...
+ }
+
+CriticalityDiagnostics-IE-List-ExtIEs RANAP-PROTOCOL-EXTENSION ::= {
+-- Extension for Release 99 to enable reporting the message structure down to the erroneous IE --
+ { ID id-MessageStructure CRITICALITY ignore EXTENSION MessageStructure PRESENCE optional } |
+-- Extension for Release 99 to enable reporting if a reported error is due to a not understood or a missing IE --
+ { ID id-TypeOfError CRITICALITY ignore EXTENSION TypeOfError PRESENCE mandatory },
+ ...
+}
+
+MessageStructure ::= SEQUENCE (SIZE (1..maxNrOfLevels)) OF
+ SEQUENCE {
+ iE-ID ProtocolIE-ID,
+ repetitionNumber RepetitionNumber1 OPTIONAL,
+ iE-Extensions ProtocolExtensionContainer { {MessageStructure-ExtIEs} } OPTIONAL,
+ ...
+ }
+
+MessageStructure-ExtIEs RANAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+CGI ::= SEQUENCE {
+ pLMNidentity PLMNidentity,
+ lAC LAC,
+ cI CI,
+ iE-Extensions ProtocolExtensionContainer { {CGI-ExtIEs} } OPTIONAL
+}
+
+CGI-ExtIEs RANAP-PROTOCOL-EXTENSION ::= {
+-- Extension for Release 6 to enable Inter-RAT PS Handover between UTRAN and GERAN A/Gb --
+ { ID id-RAC CRITICALITY ignore EXTENSION RAC PRESENCE optional },
+ ...
+}
+
+ChosenEncryptionAlgorithm ::= EncryptionAlgorithm
+
+ChosenIntegrityProtectionAlgorithm ::= IntegrityProtectionAlgorithm
+
+CI ::= OCTET STRING (SIZE (2))
+
+ClassmarkInformation2 ::= OCTET STRING
+
+ClassmarkInformation3 ::= OCTET STRING
+
+CN-DomainIndicator ::= ENUMERATED {
+ cs-domain,
+ ps-domain
+}
+
+CN-ID ::= INTEGER (0..4095)
+
+CSG-Id ::= BIT STRING (SIZE (27))
+
+
+-- D
+
+DataVolumeReference ::= INTEGER (0..255)
+
+DataVolumeReportingIndication ::= ENUMERATED {
+ do-report,
+ do-not-report
+}
+
+DCH-ID ::= INTEGER (0..255)
+
+DeliveryOfErroneousSDU ::= ENUMERATED {
+ yes,
+ no,
+ no-error-detection-consideration
+}
+
+DeliveryOrder::= ENUMERATED {
+ delivery-order-requested,
+ delivery-order-not-requested
+}
+
+DeltaRAListofIdleModeUEs ::= SEQUENCE {
+ newRAListofIdleModeUEs NewRAListofIdleModeUEs OPTIONAL,
+ rAListwithNoIdleModeUEsAnyMore RAListwithNoIdleModeUEsAnyMore OPTIONAL,
+ iE-Extensions ProtocolExtensionContainer { {DeltaRAListofIdleModeUEs-ExtIEs} } OPTIONAL
+}
+
+NewRAListofIdleModeUEs ::= SEQUENCE (SIZE (1..maxMBMSRA)) OF
+ RAC
+
+RAListwithNoIdleModeUEsAnyMore ::= SEQUENCE (SIZE (1..maxMBMSRA)) OF
+ RAC
+
+DeltaRAListofIdleModeUEs-ExtIEs RANAP-PROTOCOL-EXTENSION ::= {
+{ ID id-newLAListofIdleModeUEs CRITICALITY reject EXTENSION LAListofIdleModeUEs PRESENCE conditional }|
+ -- This IE shall be present if the New RA List of Idle Mode UEs IE is included. --
+{ ID id-LAListwithNoIdleModeUEsAnyMore CRITICALITY reject EXTENSION LAListofIdleModeUEs PRESENCE conditional },
+ -- This IE shall be presentif the RA List with No Idle Mode UEs Any More IE is included. --
+ ...
+}
+
+ForwardingIndication::=ENUMERATED{
+ forwarding-admitted,
+ ...
+}
+
+DL-GTP-PDU-SequenceNumber ::= INTEGER (0..65535)
+
+DL-N-PDU-SequenceNumber ::= INTEGER (0..65535)
+
+D-RNTI ::= INTEGER (0..1048575)
+
+DRX-CycleLengthCoefficient ::= INTEGER (6..9)
+
+DSCH-ID ::= INTEGER (0..255)
+
+
+-- E
+
+E-DCH-MAC-d-Flow-ID ::= INTEGER (0.. maxNrOfEDCHMACdFlows-1)
+
+ENB-ID ::= CHOICE {
+ macroENB-ID BIT STRING (SIZE(20)),
+ homeENB-ID BIT STRING (SIZE(28)),
+ ...
+}
+
+Global-ENB-ID ::= SEQUENCE {
+ pLMNidentity PLMNidentity,
+ eNB-ID ENB-ID,
+ iE-Extensions ProtocolExtensionContainer { {GlobalENB-ID-ExtIEs} } OPTIONAL,
+ selectedTAI TAI,
+ ...
+}
+
+GlobalENB-ID-ExtIEs RANAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+EncryptionAlgorithm ::= INTEGER { no-encryption (0), standard-UMTS-encryption-algorith-UEA1 (1), standard-UMTS-encryption-algorithm-UEA2 (2) } (0..15)
+
+EncryptionInformation ::= SEQUENCE {
+ permittedAlgorithms PermittedEncryptionAlgorithms,
+ key EncryptionKey,
+ iE-Extensions ProtocolExtensionContainer { {EncryptionInformation-ExtIEs} } OPTIONAL
+}
+
+EncryptionInformation-ExtIEs RANAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+EncryptionKey ::= BIT STRING (SIZE (128))
+-- Reference: 33.102
+
+EquipmentsToBeTraced ::= CHOICE {
+ iMEIlist IMEIList,
+ iMEISVlist IMEISVList,
+ iMEIgroup IMEIGroup,
+ iMEISVgroup IMEISVGroup,
+ ...
+}
+
+Event ::= ENUMERATED {
+ stop-change-of-service-area,
+ direct,
+ change-of-servicearea,
+ ...,
+ stop-direct,
+ periodic,
+ stop-periodic
+}
+
+ExtendedGuaranteedBitrate ::= INTEGER (16000001..256000000)
+-- Unit is bits per sec
+
+ExtendedMaxBitrate ::= INTEGER (16000001..256000000)
+-- Unit is bits per sec
+
+ExtendedRNC-ID ::= INTEGER (4096..65535)
+
+-- F
+
+FrequenceLayerConvergenceFlag ::= ENUMERATED {
+ no-FLC-flag,
+ ...
+}
+
+-- G
+
+GANSS-PositioningDataSet ::= SEQUENCE(SIZE(1..maxGANSSSet)) OF GANSS-PositioningMethodAndUsage
+
+GANSS-PositioningMethodAndUsage ::= OCTET STRING (SIZE(1))
+
+GeographicalArea ::= CHOICE {
+ point GA-Point,
+ pointWithUnCertainty GA-PointWithUnCertainty,
+ polygon GA-Polygon,
+ ...,
+ pointWithUncertaintyEllipse GA-PointWithUnCertaintyEllipse,
+ pointWithAltitude GA-PointWithAltitude,
+ pointWithAltitudeAndUncertaintyEllipsoid GA-PointWithAltitudeAndUncertaintyEllipsoid,
+ ellipsoidArc GA-EllipsoidArc
+}
+
+GeographicalCoordinates ::= SEQUENCE {
+ latitudeSign ENUMERATED { north, south },
+ latitude INTEGER (0..8388607),
+ longitude INTEGER (-8388608..8388607),
+ iE-Extensions ProtocolExtensionContainer { {GeographicalCoordinates-ExtIEs} } OPTIONAL,
+ ...
+}
+
+GeographicalCoordinates-ExtIEs RANAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+GA-AltitudeAndDirection ::= SEQUENCE {
+ directionOfAltitude ENUMERATED {height, depth},
+ altitude INTEGER (0..32767),
+ ...
+}
+
+GA-EllipsoidArc ::= SEQUENCE {
+ geographicalCoordinates GeographicalCoordinates,
+ innerRadius INTEGER (0..65535),
+ uncertaintyRadius INTEGER (0..127),
+ offsetAngle INTEGER (0..179),
+ includedAngle INTEGER (0..179),
+ confidence INTEGER (0..127),
+ iE-Extensions ProtocolExtensionContainer { { GA-EllipsoidArc-ExtIEs} } OPTIONAL,
+ ...
+}
+
+GA-EllipsoidArc-ExtIEs RANAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+GA-Point ::= SEQUENCE {
+ geographicalCoordinates GeographicalCoordinates,
+ iE-Extensions ProtocolExtensionContainer { {GA-Point-ExtIEs} } OPTIONAL,
+ ...
+}
+
+GA-Point-ExtIEs RANAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+GA-PointWithAltitude ::= SEQUENCE {
+ geographicalCoordinates GeographicalCoordinates,
+ altitudeAndDirection GA-AltitudeAndDirection,
+ iE-Extensions ProtocolExtensionContainer { { GA-PointWithAltitude-ExtIEs} } OPTIONAL,
+ ...
+}
+
+GA-PointWithAltitude-ExtIEs RANAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+GA-PointWithAltitudeAndUncertaintyEllipsoid ::= SEQUENCE {
+ geographicalCoordinates GeographicalCoordinates,
+ altitudeAndDirection GA-AltitudeAndDirection,
+ uncertaintyEllipse GA-UncertaintyEllipse,
+ uncertaintyAltitude INTEGER (0..127),
+ confidence INTEGER (0..127),
+ iE-Extensions ProtocolExtensionContainer { { GA-PointWithAltitudeAndUncertaintyEllipsoid-ExtIEs} } OPTIONAL,
+ ...
+}
+
+GA-PointWithAltitudeAndUncertaintyEllipsoid-ExtIEs RANAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+GA-PointWithUnCertainty ::=SEQUENCE {
+ geographicalCoordinates GeographicalCoordinates,
+ iE-Extensions ProtocolExtensionContainer { {GA-PointWithUnCertainty-ExtIEs} } OPTIONAL,
+ uncertaintyCode INTEGER (0..127)
+}
+
+GA-PointWithUnCertainty-ExtIEs RANAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+GA-PointWithUnCertaintyEllipse ::= SEQUENCE {
+ geographicalCoordinates GeographicalCoordinates,
+ uncertaintyEllipse GA-UncertaintyEllipse,
+ confidence INTEGER (0..127),
+ iE-Extensions ProtocolExtensionContainer { { GA-PointWithUnCertaintyEllipse-ExtIEs} } OPTIONAL,
+ ...
+}
+
+GA-PointWithUnCertaintyEllipse-ExtIEs RANAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+GA-Polygon ::= SEQUENCE (SIZE (1..maxNrOfPoints)) OF
+ SEQUENCE {
+ geographicalCoordinates GeographicalCoordinates,
+ iE-Extensions ProtocolExtensionContainer { {GA-Polygon-ExtIEs} } OPTIONAL,
+ ...
+ }
+
+GA-Polygon-ExtIEs RANAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+GA-UncertaintyEllipse ::= SEQUENCE {
+ uncertaintySemi-major INTEGER (0..127),
+ uncertaintySemi-minor INTEGER (0..127),
+ orientationOfMajorAxis INTEGER (0..179), -- The values 90..179 shall not be used.
+ ...
+}
+
+GERAN-BSC-Container ::= OCTET STRING
+ -- GERAN BSC Container as defined in [11] --
+
+
+GERAN-Cell-ID ::= SEQUENCE {
+ lAI LAI,
+ rAC RAC,
+ cI CI,
+ iE-Extensions ProtocolExtensionContainer { {GERAN-Cell-ID-ExtIEs} } OPTIONAL
+}
+
+GERAN-Cell-ID-ExtIEs RANAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+GERAN-Classmark ::= OCTET STRING
+ -- GERAN Classmark as defined in [11] --
+
+GlobalCN-ID ::= SEQUENCE {
+ pLMNidentity PLMNidentity,
+ cN-ID CN-ID
+}
+
+
+GlobalRNC-ID ::= SEQUENCE {
+ pLMNidentity PLMNidentity,
+ rNC-ID RNC-ID
+}
+
+GTP-TEI ::= OCTET STRING (SIZE (4))
+
+GuaranteedBitrate ::= INTEGER (0..16000000)
+-- Unit is bits per sec
+
+-- H
+
+HS-DSCH-MAC-d-Flow-ID ::= INTEGER (0.. maxNrOfHSDSCHMACdFlows-1)
+
+-- I
+
+
+IMEI ::= OCTET STRING (SIZE (8))
+-- Reference: 23.003
+
+IMEIGroup ::= SEQUENCE {
+ iMEI IMEI,
+ iMEIMask BIT STRING (SIZE (7)),
+ iE-Extensions ProtocolExtensionContainer { { IMEIGroup-ExtIEs} } OPTIONAL
+}
+
+IMEIGroup-ExtIEs RANAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+IMEIList ::= SEQUENCE (SIZE (1..maxNrOfUEsToBeTraced)) OF IMEI
+
+IMEISV ::= OCTET STRING (SIZE (8))
+-- Reference: 23.003
+
+IMEISVGroup ::= SEQUENCE {
+ iMEISV IMEISV,
+ iMEISVMask BIT STRING (SIZE (7)),
+ iE-Extensions ProtocolExtensionContainer { { IMEISVGroup-ExtIEs} } OPTIONAL
+}
+
+IMEISVGroup-ExtIEs RANAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+IMEISVList ::= SEQUENCE (SIZE (1..maxNrOfUEsToBeTraced)) OF IMEISV
+
+IMSI ::= TBCD-STRING (SIZE (3..8))
+-- Reference: 23.003
+
+IncludeVelocity ::= ENUMERATED {
+ requested
+}
+
+InformationExchangeID ::= INTEGER (0.. 1048575)
+
+InformationExchangeType ::= ENUMERATED {
+ transfer,
+ request,
+ ...
+}
+
+InformationRequested ::= CHOICE {
+ requestedMBMSIPMulticastAddressandAPNRequest RequestedMBMSIPMulticastAddressandAPNRequest,
+ requestedMulticastServiceList RequestedMulticastServiceList,
+ ...
+}
+
+
+InformationRequestType ::= CHOICE {
+ mBMSIPMulticastAddressandAPNRequest MBMSIPMulticastAddressandAPNRequest,
+ permanentNAS-UE-ID PermanentNAS-UE-ID,
+ ...
+}
+
+InformationTransferID ::= INTEGER (0.. 1048575)
+
+InformationTransferType ::= CHOICE {
+ rNCTraceInformation RNCTraceInformation,
+ ...
+}
+
+IntegrityProtectionAlgorithm ::= INTEGER {
+ standard-UMTS-integrity-algorithm-UIA1 (0), standard-UMTS-integrity-algorithm-UIA2 (1),
+ no-value (15)
+} (0..15)
+
+IntegrityProtectionInformation ::= SEQUENCE {
+ permittedAlgorithms PermittedIntegrityProtectionAlgorithms,
+ key IntegrityProtectionKey,
+ iE-Extensions ProtocolExtensionContainer { {IntegrityProtectionInformation-ExtIEs} } OPTIONAL
+}
+
+IntegrityProtectionInformation-ExtIEs RANAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+IntegrityProtectionKey ::= BIT STRING (SIZE (128))
+
+InterSystemInformationTransferType ::= CHOICE {
+ rIM-Transfer RIM-Transfer,
+ ...
+}
+
+InterSystemInformation-TransparentContainer ::= SEQUENCE {
+ downlinkCellLoadInformation CellLoadInformation OPTIONAL,
+ uplinkCellLoadInformation CellLoadInformation OPTIONAL,
+ iE-Extensions ProtocolExtensionContainer { { InterSystemInformation-TransparentContainer-ExtIEs} } OPTIONAL,
+ ...
+}
+
+InterSystemInformation-TransparentContainer-ExtIEs RANAP-PROTOCOL-EXTENSION ::= {
+...
+}
+
+IPMulticastAddress ::= OCTET STRING (SIZE (4..16))
+-- Reference: 23.003
+
+IuSignallingConnectionIdentifier ::= BIT STRING (SIZE (24))
+
+IuTransportAssociation ::= CHOICE {
+ gTP-TEI GTP-TEI,
+ bindingID BindingID,
+ ...
+}
+
+-- J
+-- K
+
+KeyStatus ::= ENUMERATED {
+ old,
+ new,
+ ...
+}
+-- L
+
+LA-LIST ::= SEQUENCE (SIZE (1..maxNrOfLAs)) OF
+ SEQUENCE {
+ lAC LAC,
+ listOF-SNAs ListOF-SNAs,
+ iE-Extensions ProtocolExtensionContainer { { LA-LIST-ExtIEs} } OPTIONAL,
+ ...
+ }
+
+LA-LIST-ExtIEs RANAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+LAC ::= OCTET STRING (SIZE (2))
+
+LAI ::= SEQUENCE {
+ pLMNidentity PLMNidentity,
+ lAC LAC,
+ iE-Extensions ProtocolExtensionContainer { {LAI-ExtIEs} } OPTIONAL
+}
+
+LAI-ExtIEs RANAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+LastKnownServiceArea ::= SEQUENCE {
+ sAI SAI,
+ ageOfSAI INTEGER (0..32767),
+ iE-Extensions ProtocolExtensionContainer { {LastKnownServiceArea-ExtIEs} } OPTIONAL,
+ ...
+}
+
+LastKnownServiceArea-ExtIEs RANAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+LastVisitedUTRANCell-Item ::= SEQUENCE {
+ uTRAN-CellID UTRAN-CellID,
+ cellType CellType,
+ time-UE-StayedInCell Time-UE-StayedInCell,
+ iE-Extensions ProtocolExtensionContainer { {LastVisitedUTRANCell-Item-ExtIEs} } OPTIONAL,
+ ...
+}
+
+LastVisitedUTRANCell-Item-ExtIEs RANAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+ListOF-SNAs ::= SEQUENCE (SIZE (1..maxNrOfSNAs)) OF SNAC
+
+ListOfInterfacesToTrace ::= SEQUENCE (SIZE (1..maxNrOfInterfaces)) OF InterfacesToTraceItem
+
+InterfacesToTraceItem ::= SEQUENCE {
+ interface ENUMERATED {iu-cs, iu-ps, iur, iub, uu, ...},
+ iE-Extensions ProtocolExtensionContainer { {InterfacesToTraceItem-ExtIEs} } OPTIONAL,
+ ...
+}
+
+InterfacesToTraceItem-ExtIEs RANAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+LoadValue ::= INTEGER (0..100)
+
+LocationRelatedDataRequestType ::= SEQUENCE {
+ requestedLocationRelatedDataType RequestedLocationRelatedDataType,
+ requestedGPSAssistanceData RequestedGPSAssistanceData OPTIONAL,
+ -- This IE shall be present if the Requested Location Related Data Type IE is set to �Dedicated Assistance Data for Assisted GPS� or
+ -- `Dedicated Assistance Data for Assisted GPS and GANSS�
+ ...
+}
+
+LocationRelatedDataRequestTypeSpecificToGERANIuMode ::= ENUMERATED {
+ decipheringKeysEOTD,
+ dedicatedMobileAssistedEOTDAssistanceData,
+ dedicatedMobileBasedEOTDAssistanceData,
+ ...
+}
+
+L3-Information ::= OCTET STRING
+
+-- M
+
+MaxBitrate ::= INTEGER (1..16000000)
+-- Unit is bits per sec
+
+MaxSDU-Size ::= INTEGER (0..32768)
+-- MaxSDU-Size
+-- Unit is bit
+
+MBMS-PTP-RAB-ID ::= BIT STRING (SIZE (8))
+
+MBMSBearerServiceType ::= ENUMERATED {
+ multicast,
+ broadcast,
+ ...
+}
+
+MBMSCNDe-Registration ::= ENUMERATED {
+ normalsessionstop,
+ deregister,
+ ...
+}
+
+
+MBMSCountingInformation ::= ENUMERATED {
+ counting,
+ notcounting,
+ ...
+}
+
+MBMSHCIndicator ::= ENUMERATED {
+ uncompressed-header,
+ compressed-header,
+ ...
+}
+
+MBMSIPMulticastAddressandAPNRequest ::= SEQUENCE (SIZE (1..maxnoofMulticastServicesPerRNC)) OF
+ TMGI
+
+MBMSLinkingInformation ::= ENUMERATED {
+ uE-has-joined-multicast-services,
+ ...
+}
+
+MBMSRegistrationRequestType ::= ENUMERATED {
+ register,
+ deregister,
+ ...
+}
+
+MBMSServiceArea ::= OCTET STRING
+
+MBMSSessionDuration ::= OCTET STRING (SIZE (3))
+
+
+
+MBMSSessionIdentity ::= OCTET STRING (SIZE (1))
+
+MBMSSessionRepetitionNumber ::= OCTET STRING (SIZE (1))
+
+
+-- N
+
+
+NAS-PDU ::= OCTET STRING
+
+NAS-SequenceNumber ::= BIT STRING (SIZE (2))
+-- Reference: 24.008
+
+NAS-SynchronisationIndicator ::= BIT STRING (SIZE (4))
+
+NewBSS-To-OldBSS-Information ::= OCTET STRING
+
+NonSearchingIndication ::= ENUMERATED {
+ non-searching,
+ searching
+}
+
+NRTLoadInformationValue ::= INTEGER (0..3)
+
+NumberOfIuInstances ::= INTEGER (1..2)
+
+NumberOfSteps ::= INTEGER (1..16)
+
+-- O
+
+OldBSS-ToNewBSS-Information ::= OCTET STRING
+
+OMC-ID ::= OCTET STRING (SIZE (3..22))
+-- Reference: GSM [25]
+
+-- P
+
+PagingAreaID ::= CHOICE {
+ lAI LAI,
+ rAI RAI,
+ ...
+}
+
+PagingCause ::= ENUMERATED {
+ terminating-conversational-call,
+ terminating-streaming-call,
+ terminating-interactive-call,
+ terminating-background-call,
+ terminating-low-priority-signalling,
+ ...,
+ terminating-high-priority-signalling
+}
+
+PDP-TypeInformation ::= SEQUENCE (SIZE (1..maxNrOfPDPDirections)) OF
+ PDP-Type
+
+PDP-Type ::= ENUMERATED {
+ empty,
+ ppp,
+ osp-ihoss -- this value shall not be used -- ,
+ ipv4,
+ ipv6,
+ ...
+}
+
+PeriodicLocationInfo ::= SEQUENCE {
+ reportingAmount INTEGER (1..8639999, ...),
+ reportingInterval INTEGER (1..8639999, ...),
+ iE-Extensions ProtocolExtensionContainer { { PeriodicLocationInfo-ExtIEs } } OPTIONAL,
+ ...
+}
+
+PeriodicLocationInfo-ExtIEs RANAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+
+PermanentNAS-UE-ID ::= CHOICE {
+ iMSI IMSI,
+ ...
+}
+
+PermittedEncryptionAlgorithms ::= SEQUENCE (SIZE (1..16)) OF
+ EncryptionAlgorithm
+
+PermittedIntegrityProtectionAlgorithms ::= SEQUENCE (SIZE (1..16)) OF
+ IntegrityProtectionAlgorithm
+
+PLMNidentity ::= TBCD-STRING (SIZE (3))
+
+PLMNs-in-shared-network ::= SEQUENCE (SIZE (1..maxNrOfPLMNsSN)) OF
+ SEQUENCE {
+ pLMNidentity PLMNidentity,
+ lA-LIST LA-LIST,
+ iE-Extensions ProtocolExtensionContainer { { PLMNs-in-shared-network-ExtIEs} } OPTIONAL,
+ ...
+ }
+
+PLMNs-in-shared-network-ExtIEs RANAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+PositioningDataDiscriminator ::= BIT STRING (SIZE(4))
+
+PositioningDataSet ::= SEQUENCE(SIZE(1..maxSet)) OF PositioningMethodAndUsage
+
+PositioningMethodAndUsage ::= OCTET STRING (SIZE(1))
+
+PositioningPriority ::= ENUMERATED {
+ high-Priority,
+ normal-Priority,
+...
+}
+
+PositionData ::= SEQUENCE {
+ positioningDataDiscriminator PositioningDataDiscriminator,
+ positioningDataSet PositioningDataSet OPTIONAL,
+-- This IE shall be present if the PositioningDataDiscriminator IE is set to the value "0000" --
+ iE-Extensions ProtocolExtensionContainer { {PositionData-ExtIEs} } OPTIONAL,
+ ...
+}
+
+PositionData-ExtIEs RANAP-PROTOCOL-EXTENSION ::= {
+ { ID id-GANSS-PositioningDataSet CRITICALITY ignore EXTENSION GANSS-PositioningDataSet PRESENCE optional },
+ ...
+}
+
+PositionDataSpecificToGERANIuMode ::= OCTET STRING
+
+Pre-emptionCapability ::= ENUMERATED {
+ shall-not-trigger-pre-emption,
+ may-trigger-pre-emption
+}
+
+Pre-emptionVulnerability ::= ENUMERATED {
+ not-pre-emptable,
+ pre-emptable
+}
+
+PriorityLevel ::= INTEGER { spare (0), highest (1), lowest (14), no-priority (15) } (0..15)
+
+ProvidedData ::= CHOICE {
+ shared-network-information Shared-Network-Information,
+ ...
+}
+
+P-TMSI ::= OCTET STRING (SIZE (4))
+
+-- Q
+
+QueuingAllowed ::= ENUMERATED {
+ queueing-not-allowed,
+ queueing-allowed
+}
+
+-- R
+RAB-AsymmetryIndicator::= ENUMERATED {
+ symmetric-bidirectional,
+ asymmetric-unidirectional-downlink,
+ asymmetric-unidirectional-uplink,
+ asymmetric-bidirectional,
+ ...
+}
+
+RAB-ID ::= BIT STRING (SIZE (8))
+
+RAB-Parameter-ExtendedGuaranteedBitrateList ::= SEQUENCE (SIZE (1..maxNrOfSeparateTrafficDirections)) OF ExtendedGuaranteedBitrate
+
+RAB-Parameter-ExtendedMaxBitrateList ::= SEQUENCE (SIZE (1..maxNrOfSeparateTrafficDirections)) OF ExtendedMaxBitrate
+
+
+RAB-Parameter-GuaranteedBitrateList ::= SEQUENCE (SIZE (1..maxNrOfSeparateTrafficDirections)) OF GuaranteedBitrate
+--This IE shall be ignored if Supported Guaranteed Bit rate is present--
+
+RAB-Parameter-MaxBitrateList ::= SEQUENCE (SIZE (1..maxNrOfSeparateTrafficDirections)) OF MaxBitrate
+--This IE shall be ignored if Supported Maximum Bit rate is present--
+
+RAB-Parameters ::= SEQUENCE {
+ trafficClass TrafficClass,
+ rAB-AsymmetryIndicator RAB-AsymmetryIndicator,
+ maxBitrate RAB-Parameter-MaxBitrateList,
+ guaranteedBitRate RAB-Parameter-GuaranteedBitrateList OPTIONAL
+ -- This IE shall be present the traffic class IE is set to "Conversational" or "Streaming" --,
+ deliveryOrder DeliveryOrder,
+ maxSDU-Size MaxSDU-Size,
+ sDU-Parameters SDU-Parameters,
+ transferDelay TransferDelay OPTIONAL
+ -- This IE shall be present the traffic class IE is set to "Conversational" or "Streaming" --,
+ trafficHandlingPriority TrafficHandlingPriority OPTIONAL
+ -- This IE shall be present the traffic class IE is set to "Interactive" --,
+ allocationOrRetentionPriority AllocationOrRetentionPriority OPTIONAL,
+ sourceStatisticsDescriptor SourceStatisticsDescriptor OPTIONAL
+ -- This IE shall be present the traffic class IE is set to "Conversational" or "Streaming" --,
+ relocationRequirement RelocationRequirement OPTIONAL,
+ iE-Extensions ProtocolExtensionContainer { {RAB-Parameters-ExtIEs} } OPTIONAL,
+ ...
+}
+
+RAB-Parameters-ExtIEs RANAP-PROTOCOL-EXTENSION ::= {
+-- Extension for Release 5 to enable indication that Interactive User Plane data is of a signalling nature --
+ { ID id-SignallingIndication CRITICALITY ignore EXTENSION SignallingIndication PRESENCE optional }|
+-- Extension for Release 7 to indicate an Extended Guaranteed Bitrate --
+{ ID id-RAB-Parameter-ExtendedGuaranteedBitrateList CRITICALITY reject EXTENSION RAB-Parameter-ExtendedGuaranteedBitrateList PRESENCE optional }|
+-- Extension for Release 7 to indicate an Extended Maximum Bitrate --
+{ ID id-RAB-Parameter-ExtendedMaxBitrateList CRITICALITY reject EXTENSION RAB-Parameter-ExtendedMaxBitrateList PRESENCE optional }|
+-- Extension for Release 8 to indicate an Supported Maximum Bitrate --
+{ ID id-RAB-Parameter-SupportedMaxBitrateList CRITICALITY reject EXTENSION SupportedRAB-ParameterBitrateList PRESENCE optional }|
+-- Extension for Release 8 to indicate an Supported Guaranteed Bitrate --
+{ ID id-RAB-Parameter-SupportedGuaranteedBitrateList CRITICALITY reject EXTENSION SupportedRAB-ParameterBitrateList PRESENCE optional },
+ ...
+}
+
+RAB-SubflowCombinationBitRate ::= INTEGER (0..16000000)
+
+RAB-TrCH-Mapping ::= SEQUENCE ( SIZE (1..maxNrOfRABs)) OF
+ RAB-TrCH-MappingItem
+
+RAB-TrCH-MappingItem ::= SEQUENCE {
+ rAB-ID RAB-ID,
+ trCH-ID-List TrCH-ID-List,
+ iE-Extensions ProtocolExtensionContainer { { RAB-TrCH-MappingItem-ExtIEs} } OPTIONAL,
+ ...
+}
+
+RAB-TrCH-MappingItem-ExtIEs RANAP-PROTOCOL-EXTENSION ::= {
+-- Extension for Release 99 to enable transfer of RAB Subflow mapping onto Iur transport channel Ids for a given indicated domain --
+ { ID id-CN-DomainIndicator CRITICALITY ignore EXTENSION CN-DomainIndicator PRESENCE optional },
+ ...
+}
+
+RAC ::= OCTET STRING (SIZE (1))
+
+RAI ::= SEQUENCE {
+ lAI LAI,
+ rAC RAC,
+ iE-Extensions ProtocolExtensionContainer { {RAI-ExtIEs} } OPTIONAL,
+ ...
+}
+
+RAI-ExtIEs RANAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+RAListofIdleModeUEs ::= CHOICE {
+ notEmptyRAListofIdleModeUEs NotEmptyRAListofIdleModeUEs,
+ emptyFullRAListofIdleModeUEs ENUMERATED {emptylist,fulllist,...},
+ ...
+}
+
+NotEmptyRAListofIdleModeUEs ::= SEQUENCE {
+ rAofIdleModeUEs RAofIdleModeUEs,
+ iE-Extensions ProtocolExtensionContainer { {NotEmptyRAListofIdleModeUEs-ExtIEs} } OPTIONAL
+}
+
+RAofIdleModeUEs ::= SEQUENCE (SIZE (1..maxMBMSRA)) OF
+ RAC
+
+NotEmptyRAListofIdleModeUEs-ExtIEs RANAP-PROTOCOL-EXTENSION ::= {
+{ ID id-LAofIdleModeUEs CRITICALITY reject EXTENSION LAListofIdleModeUEs PRESENCE conditional },
+ -- This IE shall be present if the RA of Idle Mode UEs IE is included. --
+ ...
+}
+
+LAListofIdleModeUEs ::= SEQUENCE (SIZE (1..maxMBMSRA)) OF
+ LAI
+
+RAT-Type ::= ENUMERATED {
+ utran,
+ geran,
+ ...
+}
+
+RateControlAllowed ::= ENUMERATED {
+ not-allowed,
+ allowed
+}
+
+RedirectAttemptFlag ::= NULL
+
+RedirectionCompleted ::= ENUMERATED {
+ redirection-completed,
+ ...
+}
+
+RejectCauseValue ::= ENUMERATED {
+ pLMN-Not-Allowed,
+ location-Area-Not-Allowed,
+ roaming-Not-Allowed-In-This-Location-Area,
+ no-Suitable-Cell-In-Location-Area,
+ gPRS-Services-Not-Allowed-In-This-PLMN,
+ cS-PS-coordination-required,
+ ...
+}
+
+
+RelocationRequirement ::= ENUMERATED {
+ lossless,
+ none,
+ ...,
+ realtime
+}
+
+RelocationType ::= ENUMERATED {
+ ue-not-involved,
+ ue-involved,
+ ...
+}
+
+RepetitionNumber0 ::= INTEGER (0..255)
+
+RepetitionNumber1 ::= INTEGER (1..256)
+
+
+ReportArea ::= ENUMERATED {
+ service-area,
+ geographical-area,
+ ...
+}
+
+RequestedGPSAssistanceData ::= OCTET STRING (SIZE (1 .. 38 ))
+ -- gpsAssistanceData as defined in 24.080 --
+
+RequestedGANSSAssistanceData ::= OCTET STRING (SIZE (1 .. 201 ))
+ -- ganssAssistanceData as defined in 24.080 --
+
+RequestedLocationRelatedDataType ::= ENUMERATED {
+ decipheringKeysUEBasedOTDOA,
+ decipheringKeysAssistedGPS,
+ dedicatedAssistanceDataUEBasedOTDOA,
+ dedicatedAssistanceDataAssistedGPS,
+ ...,
+-- Release 7 extension elements --
+ decipheringKeysAssistedGANSS,
+ dedicatedAssistanceDataAssistedGANSS,
+ decipheringKeysAssistedGPSandGANSS,
+ dedicatedAssistanceDataAssistedGPSandGANSS
+}
+
+RequestedMBMSIPMulticastAddressandAPNRequest ::= SEQUENCE (SIZE (1..maxnoofMulticastServicesPerRNC)) OF
+ MBMSIPMulticastAddressandAPNlist
+
+MBMSIPMulticastAddressandAPNlist ::= SEQUENCE {
+ tMGI TMGI,
+ iPMulticastAddress IPMulticastAddress,
+ aPN APN,
+ iE-Extensions ProtocolExtensionContainer { {MBMSIPMulticastAddressandAPNlist-ExtIEs} } OPTIONAL,
+ ...
+}
+
+MBMSIPMulticastAddressandAPNlist-ExtIEs RANAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+RequestedMulticastServiceList ::= SEQUENCE (SIZE (1.. maxnoofMulticastServicesPerUE)) OF
+ TMGI
+
+Requested-RAB-Parameter-Values ::= SEQUENCE {
+ requestedMaxBitrates Requested-RAB-Parameter-MaxBitrateList OPTIONAL,
+ requestedGuaranteedBitrates Requested-RAB-Parameter-GuaranteedBitrateList OPTIONAL,
+ iE-Extensions ProtocolExtensionContainer { { Requested-RAB-Parameter-Values-ExtIEs} } OPTIONAL,
+ ...
+}
+
+Requested-RAB-Parameter-Values-ExtIEs RANAP-PROTOCOL-EXTENSION ::= {
+-- Extension for Release 6 to enable RNC to request the execution of an alternative RAB configuration --
+ { ID id-AlternativeRABConfigurationRequest CRITICALITY ignore EXTENSION AlternativeRABConfigurationRequest PRESENCE optional }|
+-- Extension for Release 7 to request an Extended Maximum Bitrate --
+ { ID id-Requested-RAB-Parameter-ExtendedMaxBitrateList CRITICALITY reject EXTENSION Requested-RAB-Parameter-ExtendedMaxBitrateList PRESENCE optional }|
+-- Extension for Release 7 to request an Extended Guaranteed Bitrate --
+ { ID id-Requested-RAB-Parameter-ExtendedGuaranteedBitrateList CRITICALITY reject EXTENSION Requested-RAB-Parameter-ExtendedGuaranteedBitrateList PRESENCE optional }|
+-- Extension for Release 8 to request an Supported Maximum Bitrate --
+ { ID id-Requested-RAB-Parameter-SupportedMaxBitrateList CRITICALITY reject EXTENSION SupportedRAB-ParameterBitrateList PRESENCE optional }|
+-- Extension for Release 8 to request an Supported Guaranteed Bitrate --
+ { ID id-Requested-RAB-Parameter-SupportedGuaranteedBitrateList CRITICALITY reject EXTENSION SupportedRAB-ParameterBitrateList PRESENCE optional },
+ ...
+}
+
+Requested-RAB-Parameter-ExtendedMaxBitrateList ::= SEQUENCE (SIZE (1..maxNrOfSeparateTrafficDirections)) OF ExtendedMaxBitrate
+
+Requested-RAB-Parameter-ExtendedGuaranteedBitrateList ::= SEQUENCE (SIZE (1..maxNrOfSeparateTrafficDirections)) OF ExtendedGuaranteedBitrate
+
+Requested-RAB-Parameter-MaxBitrateList ::= SEQUENCE (SIZE (1..maxNrOfSeparateTrafficDirections)) OF MaxBitrate
+
+Requested-RAB-Parameter-GuaranteedBitrateList ::= SEQUENCE (SIZE (1..maxNrOfSeparateTrafficDirections)) OF GuaranteedBitrate
+
+
+RequestType ::= SEQUENCE {
+ event Event,
+ reportArea ReportArea,
+ accuracyCode INTEGER (0..127) OPTIONAL,
+ ...
+}
+
+ResidualBitErrorRatio ::= SEQUENCE {
+ mantissa INTEGER (1..9),
+ exponent INTEGER (1..8),
+ iE-Extensions ProtocolExtensionContainer { {ResidualBitErrorRatio-ExtIEs} } OPTIONAL
+}
+-- ResidualBitErrorRatio = mantissa * 10^-exponent
+
+ResidualBitErrorRatio-ExtIEs RANAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+ResponseTime ::= ENUMERATED {
+ lowdelay,
+ delaytolerant,
+...
+}
+
+RIMInformation ::= OCTET STRING
+
+RIM-Transfer ::= SEQUENCE {
+ rIMInformation RIMInformation,
+ rIMRoutingAddress RIMRoutingAddress OPTIONAL,
+ iE-Extensions ProtocolExtensionContainer { {RIM-Transfer-ExtIEs} } OPTIONAL
+}
+
+RIM-Transfer-ExtIEs RANAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+RIMRoutingAddress ::= CHOICE {
+ targetRNC-ID TargetRNC-ID,
+ gERAN-Cell-ID GERAN-Cell-ID,
+ ...
+}
+
+
+RNC-ID ::= INTEGER (0..4095)
+-- RNC-ID ::= BIT STRING (SIZE (12))
+-- Harmonized with RNSAP and NBAP definitions
+
+
+RNCTraceInformation::= SEQUENCE {
+ traceReference TraceReference,
+ traceActivationIndicator ENUMERATED {activated,deactivated},
+ equipmentsToBeTraced EquipmentsToBeTraced OPTIONAL,
+ -- This IE shall be present if the Trace Activation Indicator IE is set to "Activated".
+ iE-Extensions ProtocolExtensionContainer { { RNCTraceInformation-ExtIEs} } OPTIONAL
+}
+
+RNCTraceInformation-ExtIEs RANAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+RRC-Container ::= OCTET STRING
+
+RTLoadValue ::= INTEGER (0..100)
+
+-- S
+
+SAC ::= OCTET STRING (SIZE (2))
+
+SAI ::= SEQUENCE {
+ pLMNidentity PLMNidentity,
+ lAC LAC,
+ sAC SAC,
+ iE-Extensions ProtocolExtensionContainer { {SAI-ExtIEs} } OPTIONAL
+}
+
+SAI-ExtIEs RANAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+SAPI ::= ENUMERATED {
+ sapi-0,
+ sapi-3,
+ ...
+}
+
+SessionUpdateID ::= INTEGER (0.. 1048575)
+
+Shared-Network-Information ::= SEQUENCE {
+ pLMNs-in-shared-network PLMNs-in-shared-network,
+ iE-Extensions ProtocolExtensionContainer { {Shared-Network-Information-ExtIEs} } OPTIONAL,
+ ...
+ }
+
+Shared-Network-Information-ExtIEs RANAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+SignallingIndication ::= ENUMERATED {
+ signalling,
+ ...
+}
+
+SDU-ErrorRatio ::= SEQUENCE {
+ mantissa INTEGER (1..9),
+ exponent INTEGER (1..6),
+ iE-Extensions ProtocolExtensionContainer { {SDU-ErrorRatio-ExtIEs} } OPTIONAL
+}
+-- SDU-ErrorRatio = mantissa * 10^-exponent
+
+SDU-ErrorRatio-ExtIEs RANAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+SDU-FormatInformationParameters ::= SEQUENCE (SIZE (1..maxRAB-SubflowCombination)) OF
+ SEQUENCE {
+ subflowSDU-Size SubflowSDU-Size OPTIONAL,
+ rAB-SubflowCombinationBitRate RAB-SubflowCombinationBitRate OPTIONAL,
+ iE-Extensions ProtocolExtensionContainer { {SDU-FormatInformationParameters-ExtIEs} } OPTIONAL,
+ ...
+ }
+
+SDU-FormatInformationParameters-ExtIEs RANAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+SDU-Parameters ::= SEQUENCE (SIZE (1..maxRAB-Subflows)) OF
+ SEQUENCE {
+ sDU-ErrorRatio SDU-ErrorRatio OPTIONAL
+ -- This IE shall be present if the Delivery Of Erroneous SDU IE is set to "Yes" or "No" --,
+ residualBitErrorRatio ResidualBitErrorRatio,
+ deliveryOfErroneousSDU DeliveryOfErroneousSDU,
+ sDU-FormatInformationParameters SDU-FormatInformationParameters OPTIONAL,
+ iE-Extensions ProtocolExtensionContainer { {SDU-Parameters-ExtIEs} } OPTIONAL,
+ ...
+ }
+
+SDU-Parameters-ExtIEs RANAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+SNA-Access-Information ::= SEQUENCE {
+ authorisedPLMNs AuthorisedPLMNs,
+ iE-Extensions ProtocolExtensionContainer { {SNA-Access-Information-ExtIEs} } OPTIONAL,
+ ...
+ }
+
+SNA-Access-Information-ExtIEs RANAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+SNAC ::= INTEGER (0..65535)
+
+Service-Handover ::= ENUMERATED {
+ handover-to-GSM-should-be-performed,
+ handover-to-GSM-should-not-be-performed,
+ handover-to-GSM-shall-not-be-performed,
+ ...
+}
+
+Source-ToTarget-TransparentContainer ::= OCTET STRING
+-- This IE is a transparent container, the IE shall be encoded not as an OCTET STRING but according to the type specifications of the target system.
+-- Note: In the current version of this specification, this IE may either carry the Source RNC to
+-- Target RNC Transparent Container or the Source eNB to Target eNB Transparent Container IE as
+-- defined in [49]
+
+SourceeNodeB-ToTargeteNodeB-TransparentContainer ::= OCTET STRING
+
+
+SourceCellID ::= CHOICE {
+ sourceUTRANCellID SourceUTRANCellID,
+ sourceGERANCellID CGI,
+ ...
+}
+
+SourceBSS-ToTargetBSS-TransparentContainer ::= OCTET STRING
+
+SourceID ::= CHOICE {
+ sourceRNC-ID SourceRNC-ID,
+ sAI SAI,
+ ...
+}
+
+
+SourceRNC-ID ::= SEQUENCE {
+ pLMNidentity PLMNidentity,
+ rNC-ID RNC-ID,
+ iE-Extensions ProtocolExtensionContainer { {SourceRNC-ID-ExtIEs} } OPTIONAL
+}
+
+SourceRNC-ID-ExtIEs RANAP-PROTOCOL-EXTENSION ::= {
+-- Extension for Release 7 to indicate extended RNC-ID --
+ { ID id-ExtendedRNC-ID CRITICALITY reject EXTENSION ExtendedRNC-ID PRESENCE optional },
+ ...
+}
+
+SourceRNC-ToTargetRNC-TransparentContainer ::= SEQUENCE {
+ rRC-Container RRC-Container,
+ numberOfIuInstances NumberOfIuInstances,
+ relocationType RelocationType,
+ chosenIntegrityProtectionAlgorithm ChosenIntegrityProtectionAlgorithm OPTIONAL,
+ integrityProtectionKey IntegrityProtectionKey OPTIONAL,
+ chosenEncryptionAlgorithForSignalling ChosenEncryptionAlgorithm OPTIONAL,
+ cipheringKey EncryptionKey OPTIONAL,
+ chosenEncryptionAlgorithForCS ChosenEncryptionAlgorithm OPTIONAL,
+ chosenEncryptionAlgorithForPS ChosenEncryptionAlgorithm OPTIONAL,
+ d-RNTI D-RNTI OPTIONAL
+ -- This IE shall be present if the Relocation type IE is set to "UE not involved in relocation of SRNS" --,
+ targetCellId TargetCellId OPTIONAL
+ -- This IE shall be present if the Relocation type IE is set to "UE involved in relocation of SRNS" --,
+ rAB-TrCH-Mapping RAB-TrCH-Mapping OPTIONAL,
+ iE-Extensions ProtocolExtensionContainer { {SourceRNC-ToTargetRNC-TransparentContainer-ExtIEs} } OPTIONAL,
+ ...
+}
+
+SourceRNC-ToTargetRNC-TransparentContainer-ExtIEs RANAP-PROTOCOL-EXTENSION ::= {
+-- Extension for Release 99 to enable transfer of SRB mapping onto Iur transport channel Ids --
+ { ID id-SRB-TrCH-Mapping CRITICALITY reject EXTENSION SRB-TrCH-Mapping PRESENCE optional }|
+-- Extension for Release 5 to enable Inter RAN Load Information Exchange over Iu --
+ {ID id-CellLoadInformationGroup CRITICALITY ignore EXTENSION CellLoadInformationGroup PRESENCE optional}|
+-- Extension for Release 6 to provide Trace Recording Session Information to the Target RNC --
+ {ID id-TraceRecordingSessionInformation CRITICALITY ignore EXTENSION TraceRecordingSessionInformation PRESENCE optional}|
+-- Extension for Release 6 to indicate to the Target RNC that the UE has activated Multicast Service --
+ {ID id-MBMSLinkingInformation CRITICALITY ignore EXTENSION MBMSLinkingInformation PRESENCE optional}|
+ {ID id-d-RNTI-for-NoIuCSUP CRITICALITY reject EXTENSION D-RNTI PRESENCE optional}|
+ {ID id-UE-History-Information CRITICALITY ignore EXTENSION UE-History-Information PRESENCE optional}|
+ {ID id-SubscriberProfileIDforRFP CRITICALITY ignore EXTENSION SubscriberProfileIDforRFP PRESENCE optional},
+ ...
+}
+
+SubscriberProfileIDforRFP ::= INTEGER (1..256)
+
+SourceStatisticsDescriptor ::= ENUMERATED {
+ speech,
+ unknown,
+ ...
+}
+
+SupportedRAB-ParameterBitrateList ::= SEQUENCE (SIZE (1..maxNrOfSeparateTrafficDirections)) OF SupportedBitrate
+
+SupportedBitrate ::= INTEGER (1..1000000000, ...)
+-- Unit is bits per sec
+
+SourceUTRANCellID ::= SEQUENCE {
+ pLMNidentity PLMNidentity,
+ iE-Extensions ProtocolExtensionContainer { {SourceUTRANCellID-ExtIEs} } OPTIONAL
+}
+
+SourceUTRANCellID-ExtIEs RANAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+SRB-ID ::= INTEGER (1..32)
+
+SRB-TrCH-Mapping ::= SEQUENCE ( SIZE (1..maxNrOfSRBs)) OF
+ SRB-TrCH-MappingItem
+
+SRB-TrCH-MappingItem ::= SEQUENCE {
+ sRB-ID SRB-ID,
+ trCH-ID TrCH-ID,
+ iE-Extensions ProtocolExtensionContainer { { SRB-TrCH-MappingItem-ExtIEs} } OPTIONAL,
+ ...
+}
+
+
+SRB-TrCH-MappingItem-ExtIEs RANAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+SRVCC-HO-Indication ::= ENUMERATED {
+ ps-and-cs,
+ cs-only,
+ ...
+}
+
+SRVCC-Information ::= SEQUENCE {
+ nonce BIT STRING (SIZE (128)),
+ iE-Extensions ProtocolExtensionContainer { { SRVCC-Information-ExtIEs} } OPTIONAL,
+ ...
+}
+
+SRVCC-Information-ExtIEs RANAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+SRVCC-Operation-Possible ::= ENUMERATED {
+ srvcc-possible,
+ ...
+}
+
+SubflowSDU-Size ::= INTEGER (0..4095)
+-- Unit is bit
+
+
+-- T
+TAC ::= OCTET STRING (SIZE (2))
+
+TAI ::= SEQUENCE {
+ pLMNidentity PLMNidentity,
+ tAC TAC,
+ iE-Extensions ProtocolExtensionContainer { {TAI-ExtIEs} } OPTIONAL
+}
+
+TAI-ExtIEs RANAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+
+Target-ToSource-TransparentContainer ::= OCTET STRING
+-- This IE is a transparent container, the IE shall be encoded not as an OCTET STRING but according to the type specifications of the target system.
+-- Note: In the current version of this specification, this IE may either carry the Target RNC to
+-- Source RNC Transparent Container or the Target eNB to Source eNB Transparent Container IE as
+-- defined in [49]
+
+TargeteNodeB-ToSourceeNodeB-TransparentContainer ::= OCTET STRING
+
+TargetBSS-ToSourceBSS-TransparentContainer ::= OCTET STRING
+
+TargetCellId ::= INTEGER (0..268435455)
+
+TargetID ::= CHOICE {
+ targetRNC-ID TargetRNC-ID,
+ cGI CGI,
+
+ ...,
+ targeteNB-ID Global-ENB-ID
+}
+
+
+
+
+TargetRNC-ID ::= SEQUENCE {
+ lAI LAI,
+ rAC RAC OPTIONAL,
+ rNC-ID RNC-ID,
+ iE-Extensions ProtocolExtensionContainer { {TargetRNC-ID-ExtIEs} } OPTIONAL
+}
+
+TargetRNC-ID-ExtIEs RANAP-PROTOCOL-EXTENSION ::= {
+-- Extension for Release 7 to indicate extended RNC-ID --
+ { ID id-ExtendedRNC-ID CRITICALITY reject EXTENSION ExtendedRNC-ID PRESENCE optional },
+ ...
+}
+
+TargetRNC-ToSourceRNC-TransparentContainer ::= SEQUENCE {
+ rRC-Container RRC-Container,
+ d-RNTI D-RNTI OPTIONAL
+ -- May be included to allow the triggering of the Relocation Detect procedure from the Iur Interface --,
+ iE-Extensions ProtocolExtensionContainer { {TargetRNC-ToSourceRNC-TransparentContainer-ExtIEs} } OPTIONAL,
+ ...
+}
+
+TargetRNC-ToSourceRNC-TransparentContainer-ExtIEs RANAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+TBCD-STRING ::= OCTET STRING
+
+TemporaryUE-ID ::= CHOICE {
+ tMSI TMSI,
+ p-TMSI P-TMSI,
+ ...
+}
+
+Time-UE-StayedInCell ::= INTEGER (0..4095)
+
+TimeToMBMSDataTransfer ::= OCTET STRING(SIZE(1))
+
+
+TMGI ::= SEQUENCE {
+ pLMNidentity PLMNidentity,
+ serviceID OCTET STRING (SIZE (3)),
+ iE-Extensions ProtocolExtensionContainer { {TMGI-ExtIEs} } OPTIONAL
+}
+
+TMGI-ExtIEs RANAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+TMSI ::= OCTET STRING (SIZE (4))
+
+TraceDepth ::= ENUMERATED {
+ minimum,
+ medium,
+ maximum,
+ ...
+}
+
+TracePropagationParameters ::= SEQUENCE {
+ traceRecordingSessionReference TraceRecordingSessionReference,
+ traceDepth TraceDepth,
+ listOfInterfacesToTrace ListOfInterfacesToTrace OPTIONAL,
+ iE-Extensions ProtocolExtensionContainer { { TracePropagationParameters-ExtIEs} } OPTIONAL,
+ ...
+}
+
+TracePropagationParameters-ExtIEs RANAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+TraceRecordingSessionInformation ::= SEQUENCE {
+ traceReference TraceReference,
+ traceRecordingSessionReference TraceRecordingSessionReference,
+ iE-Extensions ProtocolExtensionContainer { { TraceRecordingSessionInformation-ExtIEs} } OPTIONAL,
+ ...
+}
+
+TraceRecordingSessionInformation-ExtIEs RANAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+TraceRecordingSessionReference ::= INTEGER (0..65535)
+
+TraceReference ::= OCTET STRING (SIZE (2..3))
+
+TraceType ::= OCTET STRING (SIZE (1))
+-- Reference: GSM TS 12.08
+
+TrafficClass ::= ENUMERATED {
+ conversational,
+ streaming,
+ interactive,
+ background,
+ ...
+}
+
+TrafficHandlingPriority ::= INTEGER { spare (0), highest (1), lowest (14), no-priority-used (15) } (0..15)
+
+TransferDelay ::= INTEGER (0..65535)
+-- Unit is millisecond
+
+UnsuccessfullyTransmittedDataVolume ::= INTEGER (0..4294967295)
+
+TransportLayerAddress ::= BIT STRING (SIZE (1..160, ...))
+
+TrCH-ID ::= SEQUENCE {
+ dCH-ID DCH-ID OPTIONAL,
+ dSCH-ID DSCH-ID OPTIONAL,
+ uSCH-ID USCH-ID OPTIONAL,
+ iE-Extensions ProtocolExtensionContainer { { TrCH-ID-ExtIEs} } OPTIONAL,
+ ...
+}
+
+TrCH-ID-ExtIEs RANAP-PROTOCOL-EXTENSION ::= {
+-- Extension for Release 5 to enable transfer of HS-DSCH-MAC-d-Flow-ID onto Iur transport channel ID --
+ {ID id-hS-DSCH-MAC-d-Flow-ID CRITICALITY ignore EXTENSION HS-DSCH-MAC-d-Flow-ID PRESENCE optional}|
+-- Extension for Release 6 to enable transfer of E-DCH-MAC-d-Flow-ID onto Iur transport channel ID --
+ {ID id-E-DCH-MAC-d-Flow-ID CRITICALITY ignore EXTENSION E-DCH-MAC-d-Flow-ID PRESENCE optional},
+ ...
+}
+
+TrCH-ID-List ::= SEQUENCE (SIZE (1..maxRAB-Subflows)) OF
+ TrCH-ID
+
+TriggerID ::= OCTET STRING (SIZE (3..22))
+
+TypeOfError ::= ENUMERATED {
+ not-understood,
+ missing,
+ ...
+}
+
+
+-- U
+
+UE-History-Information ::= OCTET STRING
+
+UE-ID ::= CHOICE {
+ imsi IMSI,
+ imei IMEI,
+ ...,
+ imeisv IMEISV
+
+}
+
+UESBI-Iu ::= SEQUENCE {
+ uESBI-IuA UESBI-IuA OPTIONAL,
+ uESBI-IuB UESBI-IuB OPTIONAL,
+ iE-Extensions ProtocolExtensionContainer { {UESBI-Iu-ExtIEs} } OPTIONAL,
+ ...
+}
+
+UESBI-Iu-ExtIEs RANAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+UESBI-IuA ::= BIT STRING (SIZE(1..128))
+-- Reference: TR25.994 --
+UESBI-IuB ::= BIT STRING (SIZE(1..128))
+-- Reference: TR25.995 --
+
+UL-GTP-PDU-SequenceNumber ::= INTEGER (0..65535)
+
+UL-N-PDU-SequenceNumber ::= INTEGER (0..65535)
+
+UP-ModeVersions ::= BIT STRING (SIZE (16))
+
+USCH-ID ::= INTEGER (0..255)
+
+UserPlaneMode ::= ENUMERATED {
+ transparent-mode,
+ support-mode-for-predefined-SDU-sizes,
+ ...
+}
+
+UTRAN-CellID ::= SEQUENCE {
+ pLMNidentity PLMNidentity,
+ cellID TargetCellId,
+ iE-Extensions ProtocolExtensionContainer { { UTRAN-CellID-ExtIEs} } OPTIONAL
+}
+
+UTRAN-CellID-ExtIEs RANAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+
+-- V
+
+VelocityEstimate ::= CHOICE {
+ horizontalVelocity HorizontalVelocity,
+ horizontalWithVerticalVelocity HorizontalWithVerticalVelocity,
+ horizontalVelocityWithUncertainty HorizontalVelocityWithUncertainty,
+ horizontalWithVeritcalVelocityAndUncertainty HorizontalWithVerticalVelocityAndUncertainty,
+ ...
+}
+
+HorizontalVelocity ::= SEQUENCE {
+ horizontalSpeedAndBearing HorizontalSpeedAndBearing,
+ iE-Extensions ProtocolExtensionContainer { { HorizontalVelocity-ExtIEs} } OPTIONAL,
+ ...
+}
+
+HorizontalVelocity-ExtIEs RANAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+HorizontalWithVerticalVelocity ::= SEQUENCE {
+ horizontalSpeedAndBearing HorizontalSpeedAndBearing,
+ veritcalVelocity VerticalVelocity,
+ iE-Extensions ProtocolExtensionContainer { { HorizontalWithVerticalVelocity-ExtIEs} } OPTIONAL,
+ ...
+}
+
+HorizontalWithVerticalVelocity-ExtIEs RANAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+
+HorizontalVelocityWithUncertainty ::= SEQUENCE {
+ horizontalSpeedAndBearing HorizontalSpeedAndBearing,
+ uncertaintySpeed INTEGER (0..255),
+ iE-Extensions ProtocolExtensionContainer { { HorizontalVelocityWithUncertainty-ExtIEs} } OPTIONAL,
+ ...
+}
+
+HorizontalVelocityWithUncertainty-ExtIEs RANAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+HorizontalWithVerticalVelocityAndUncertainty ::= SEQUENCE {
+ horizontalSpeedAndBearing HorizontalSpeedAndBearing,
+ veritcalVelocity VerticalVelocity,
+ horizontalUncertaintySpeed INTEGER (0..255),
+ verticalUncertaintySpeed INTEGER (0..255),
+ iE-Extensions ProtocolExtensionContainer { { HorizontalWithVerticalVelocityAndUncertainty-ExtIEs} } OPTIONAL,
+ ...
+}
+
+HorizontalWithVerticalVelocityAndUncertainty-ExtIEs RANAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+HorizontalSpeedAndBearing ::= SEQUENCE {
+ bearing INTEGER (0..359),
+ horizontalSpeed INTEGER (0..2047)
+}
+
+VerticalVelocity ::= SEQUENCE {
+ veritcalSpeed INTEGER (0..255),
+ veritcalSpeedDirection VerticalSpeedDirection
+}
+
+VerticalSpeedDirection ::= ENUMERATED {
+ upward,
+ downward
+}
+
+VerticalAccuracyCode ::= INTEGER (0..127)
+
+END
+
+
diff --git a/lib/asn1/test/asn1_SUITE_data/RANAP-PDU-Contents.asn1 b/lib/asn1/test/asn1_SUITE_data/RANAP-PDU-Contents.asn1
new file mode 100644
index 0000000000..c83f60f13e
--- /dev/null
+++ b/lib/asn1/test/asn1_SUITE_data/RANAP-PDU-Contents.asn1
@@ -0,0 +1,3383 @@
+-- RANAP-PDU-Contents.asn
+--
+-- Taken from 3GPP TS 25.413 V8.2.1 (2009-03)
+-- http://www.3gpp.org/ftp/Specs/archive/25_series/25.413/25413-821.zip
+--
+-- 9.3.3 PDU Definitions
+--
+-- $Id$
+--
+
+-- **************************************************************
+--
+-- PDU definitions for RANAP.
+--
+-- **************************************************************
+
+RANAP-PDU-Contents {
+itu-t (0) identified-organization (4) etsi (0) mobileDomain (0)
+umts-Access (20) modules (3) ranap (0) version1 (1) ranap-PDU-Contents (1) }
+
+DEFINITIONS AUTOMATIC TAGS ::=
+
+BEGIN
+
+-- **************************************************************
+--
+-- IE parameter types from other modules.
+--
+-- **************************************************************
+
+IMPORTS
+ AccuracyFulfilmentIndicator,
+ APN,
+ BroadcastAssistanceDataDecipheringKeys,
+ LocationRelatedDataRequestType,
+ LocationRelatedDataRequestTypeSpecificToGERANIuMode,
+ DataVolumeReference,
+ CellLoadInformation,
+ AreaIdentity,
+ CN-DomainIndicator,
+ Cause,
+ ClientType,
+ CriticalityDiagnostics,
+ ChosenEncryptionAlgorithm,
+ ChosenIntegrityProtectionAlgorithm,
+ ClassmarkInformation2,
+ ClassmarkInformation3,
+ CSG-Id,
+ DL-GTP-PDU-SequenceNumber,
+ DL-N-PDU-SequenceNumber,
+ DataVolumeReportingIndication,
+ DeltaRAListofIdleModeUEs,
+ DRX-CycleLengthCoefficient,
+ EncryptionInformation,
+ EncryptionKey,
+ ExtendedRNC-ID,
+ FrequenceLayerConvergenceFlag,
+ GERAN-BSC-Container,
+ GERAN-Classmark,
+ Global-ENB-ID,
+ GlobalCN-ID,
+ GlobalRNC-ID,
+ GTP-TEI,
+ IncludeVelocity,
+ InformationExchangeID,
+ InformationExchangeType,
+ InformationRequested,
+ InformationRequestType,
+ InformationTransferID,
+ InformationTransferType,
+ InterSystemInformationTransferType,
+ IntegrityProtectionInformation,
+ IntegrityProtectionKey,
+ InterSystemInformation-TransparentContainer,
+ IPMulticastAddress,
+ IuSignallingConnectionIdentifier,
+ IuTransportAssociation,
+ KeyStatus,
+ L3-Information,
+ LAI,
+ LastKnownServiceArea,
+ MBMS-PTP-RAB-ID,
+ MBMSBearerServiceType,
+ MBMSCountingInformation,
+ MBMSCNDe-Registration,
+ MBMSHCIndicator,
+ MBMSRegistrationRequestType,
+ MBMSServiceArea,
+ MBMSSessionDuration,
+ MBMSSessionIdentity,
+ MBMSSessionRepetitionNumber,
+ NAS-PDU,
+ NAS-SequenceNumber,
+ NAS-SynchronisationIndicator,
+ NewBSS-To-OldBSS-Information,
+ NonSearchingIndication,
+ NumberOfSteps,
+ OMC-ID,
+ OldBSS-ToNewBSS-Information,
+ PagingAreaID,
+ PagingCause,
+ PDP-TypeInformation,
+ PermanentNAS-UE-ID,
+ PLMNidentity,
+ PositionData,
+ PositionDataSpecificToGERANIuMode,
+ PositioningPriority,
+ ProvidedData,
+ RAB-ID,
+ RAB-Parameters,
+ RAC,
+ RAListofIdleModeUEs,
+ RAT-Type,
+ RedirectAttemptFlag,
+ RedirectionCompleted,
+ RejectCauseValue,
+ RelocationType,
+ RequestedGANSSAssistanceData,
+ RequestType,
+ Requested-RAB-Parameter-Values,
+ ResponseTime,
+ RRC-Container,
+ SAI,
+ SAPI,
+ Service-Handover,
+ SessionUpdateID,
+ SNA-Access-Information,
+ SourceBSS-ToTargetBSS-TransparentContainer,
+ SourceID,
+ Source-ToTarget-TransparentContainer,
+ SourceRNC-ToTargetRNC-TransparentContainer,
+ SRVCC-HO-Indication,
+ SRVCC-Information,
+ SRVCC-Operation-Possible,
+ TargetBSS-ToSourceBSS-TransparentContainer,
+ TargetID,
+ Target-ToSource-TransparentContainer,
+ TargetRNC-ToSourceRNC-TransparentContainer,
+ TemporaryUE-ID,
+ TimeToMBMSDataTransfer,
+ TMGI,
+ TracePropagationParameters,
+ TraceReference,
+ TraceType,
+ UnsuccessfullyTransmittedDataVolume,
+ TransportLayerAddress,
+ TriggerID,
+ UE-ID,
+ UESBI-Iu,
+ UL-GTP-PDU-SequenceNumber,
+ UL-N-PDU-SequenceNumber,
+ UP-ModeVersions,
+ UserPlaneMode,
+ VelocityEstimate,
+ VerticalAccuracyCode,
+ Alt-RAB-Parameters,
+ Ass-RAB-Parameters,
+ PeriodicLocationInfo,
+ SubscriberProfileIDforRFP
+FROM RANAP-IEs
+
+
+ PrivateIE-Container{},
+ ProtocolExtensionContainer{},
+ ProtocolIE-ContainerList{},
+ ProtocolIE-ContainerPair{},
+ ProtocolIE-ContainerPairList{},
+ ProtocolIE-Container{},
+ RANAP-PRIVATE-IES,
+ RANAP-PROTOCOL-EXTENSION,
+ RANAP-PROTOCOL-IES,
+ RANAP-PROTOCOL-IES-PAIR
+FROM RANAP-Containers
+
+ maxNrOfDTs,
+ maxNrOfErrors,
+ maxNrOfIuSigConIds,
+ maxNrOfRABs,
+ maxNrOfVol,
+ maxnoofMulticastServicesPerUE,
+
+ id-AccuracyFulfilmentIndicator,
+ id-APN,
+ id-AreaIdentity,
+ id-Alt-RAB-Parameters,
+ id-Ass-RAB-Parameters,
+ id-BroadcastAssistanceDataDecipheringKeys,
+ id-LocationRelatedDataRequestType,
+ id-CN-DomainIndicator,
+ id-Cause,
+ id-ChosenEncryptionAlgorithm,
+ id-ChosenIntegrityProtectionAlgorithm,
+ id-ClassmarkInformation2,
+ id-ClassmarkInformation3,
+ id-ClientType,
+ id-CNMBMSLinkingInformation,
+ id-CriticalityDiagnostics,
+ id-CSG-Id,
+ id-DeltaRAListofIdleModeUEs,
+ id-DRX-CycleLengthCoefficient,
+ id-DirectTransferInformationItem-RANAP-RelocInf,
+ id-DirectTransferInformationList-RANAP-RelocInf,
+ id-DL-GTP-PDU-SequenceNumber,
+ id-EncryptionInformation,
+ id-EncryptionKey,
+ id-ExtendedRNC-ID,
+ id-FrequenceLayerConvergenceFlag,
+ id-GERAN-BSC-Container,
+ id-GERAN-Classmark,
+ id-GERAN-Iumode-RAB-Failed-RABAssgntResponse-Item,
+ id-GERAN-Iumode-RAB-FailedList-RABAssgntResponse,
+ id-Global-ENB-ID,
+ id-GlobalCN-ID,
+ id-GlobalCN-IDCS,
+ id-GlobalCN-IDPS,
+ id-GlobalRNC-ID,
+ id-IncludeVelocity,
+ id-InformationExchangeID,
+ id-InformationExchangeType,
+ id-InformationRequested,
+ id-InformationRequestType,
+ id-InformationTransferID,
+ id-InformationTransferType,
+ id-IntegrityProtectionInformation,
+ id-IntegrityProtectionKey,
+ id-InterSystemInformationTransferType,
+ id-InterSystemInformation-TransparentContainer,
+ id-IPMulticastAddress,
+ id-IuSigConId,
+ id-OldIuSigConId,
+ id-OldIuSigConIdCS,
+ id-OldIuSigConIdPS,
+ id-IuSigConIdItem,
+ id-IuSigConIdList,
+ id-IuTransportAssociation,
+ id-JoinedMBMSBearerServicesList,
+ id-KeyStatus,
+ id-L3-Information,
+ id-LAI,
+ id-LastKnownServiceArea,
+ id-LeftMBMSBearerServicesList,
+ id-LocationRelatedDataRequestTypeSpecificToGERANIuMode,
+ id-MBMSBearerServiceType,
+ id-MBMSCountingInformation,
+ id-MBMSCNDe-Registration,
+ id-MBMSRegistrationRequestType,
+ id-MBMSSynchronisationInformation,
+ id-MBMSServiceArea,
+ id-MBMSSessionDuration,
+ id-MBMSSessionIdentity,
+ id-MBMSSessionRepetitionNumber,
+ id-NAS-PDU,
+ id-NAS-SequenceNumber,
+ id-NewBSS-To-OldBSS-Information,
+ id-NonSearchingIndication,
+ id-NumberOfSteps,
+ id-OMC-ID,
+ id-OldBSS-ToNewBSS-Information,
+ id-PagingAreaID,
+ id-PagingCause,
+ id-PDP-TypeInformation,
+ id-PermanentNAS-UE-ID,
+ id-PositionData,
+ id-PositionDataSpecificToGERANIuMode,
+ id-PositioningPriority,
+ id-ProvidedData,
+ id-RAB-ContextItem,
+ id-RAB-ContextList,
+ id-RAB-ContextFailedtoTransferItem,
+ id-RAB-ContextFailedtoTransferList,
+ id-RAB-ContextItem-RANAP-RelocInf,
+ id-RAB-ContextList-RANAP-RelocInf,
+ id-RAB-DataForwardingItem,
+ id-RAB-DataForwardingItem-SRNS-CtxReq,
+ id-RAB-DataForwardingList,
+ id-RAB-DataForwardingList-SRNS-CtxReq,
+ id-RAB-DataVolumeReportItem,
+ id-RAB-DataVolumeReportList,
+ id-RAB-DataVolumeReportRequestItem,
+ id-RAB-DataVolumeReportRequestList,
+ id-RAB-FailedItem,
+ id-RAB-FailedList,
+ id-RAB-FailedList-EnhRelocInfoRes,
+ id-RAB-FailedItem-EnhRelocInfoRes,
+ id-RAB-FailedtoReportItem,
+ id-RAB-FailedtoReportList,
+ id-RAB-ID,
+ id-RAB-ModifyList,
+ id-RAB-ModifyItem,
+ id-RAB-Parameters,
+ id-RAB-QueuedItem,
+ id-RAB-QueuedList,
+ id-RAB-ReleaseFailedList,
+ id-RAB-ReleaseItem,
+ id-RAB-ReleasedItem-IuRelComp,
+ id-RAB-ReleaseList,
+ id-RAB-ReleasedItem,
+ id-RAB-ReleasedList,
+ id-RAB-ReleasedList-IuRelComp,
+ id-RAB-RelocationReleaseItem,
+ id-RAB-RelocationReleaseList,
+ id-RAB-SetupItem-RelocReq,
+ id-RAB-SetupItem-RelocReqAck,
+ id-RAB-SetupList-RelocReq,
+ id-RAB-SetupList-RelocReqAck,
+ id-RAB-SetupList-EnhRelocInfoReq,
+ id-RAB-SetupItem-EnhRelocInfoReq,
+ id-RAB-SetupList-EnhRelocInfoRes,
+ id-RAB-SetupItem-EnhRelocInfoRes,
+ id-RAB-SetupList-EnhancedRelocCompleteReq,
+ id-RAB-SetupItem-EnhancedRelocCompleteReq,
+ id-RAB-SetupList-EnhancedRelocCompleteRes,
+ id-RAB-SetupItem-EnhancedRelocCompleteRes,
+ id-RAB-SetupOrModifiedItem,
+ id-RAB-SetupOrModifiedList,
+ id-RAB-SetupOrModifyItem,
+ id-RAB-SetupOrModifyList,
+ id-RAB-ToBeReleasedItem-EnhancedRelocCompleteRes,
+ id-RAB-ToBeReleasedList-EnhancedRelocCompleteRes,
+ id-RAC,
+ id-RAListofIdleModeUEs,
+ id-RAT-Type,
+ id-RedirectAttemptFlag,
+ id-RedirectionCompleted,
+ id-RedirectionIndication,
+ id-RejectCauseValue,
+ id-RelocationType,
+ id-Relocation-SourceRNC-ID,
+ id-Relocation-SourceExtendedRNC-ID,
+ id-Relocation-TargetRNC-ID,
+ id-Relocation-TargetExtendedRNC-ID,
+ id-RequestedGANSSAssistanceData,
+ id-RequestType,
+ id-ResponseTime,
+ id-SAI,
+ id-SAPI,
+ id-SelectedPLMN-ID,
+ id-SessionUpdateID,
+ id-SNA-Access-Information,
+ id-SourceBSS-ToTargetBSS-TransparentContainer,
+ id-SourceRNC-ID,
+ id-SourceExtendedRNC-ID,
+ id-SourceID,
+ id-Source-ToTarget-TransparentContainer,
+ id-SourceRNC-PDCP-context-info,
+ id-SRVCC-HO-Indication,
+ id-SRVCC-Information,
+ id-SRVCC-Operation-Possible,
+ id-TargetBSS-ToSourceBSS-TransparentContainer,
+ id-TargetID,
+ id-Target-ToSource-TransparentContainer,
+ id-TemporaryUE-ID,
+ id-TimeToMBMSDataTransfer,
+ id-TMGI,
+ id-TracePropagationParameters,
+ id-TraceReference,
+ id-TraceType,
+ id-TransportLayerAddress,
+ id-TransportLayerInformation,
+ id-TriggerID,
+ id-UE-ID,
+ id-UESBI-Iu,
+ id-UL-GTP-PDU-SequenceNumber,
+ id-UnsuccessfulLinkingList,
+ id-VelocityEstimate,
+ id-VerticalAccuracyCode,
+ id-PeriodicLocationInfo,
+ id-BroadcastGANSSAssistanceDataDecipheringKeys,
+ id-SubscriberProfileIDforRFP
+FROM RANAP-Constants;
+
+-- **************************************************************
+--
+-- Common Container Lists
+--
+-- **************************************************************
+
+RAB-IE-ContainerList { RANAP-PROTOCOL-IES : IEsSetParam } ::= ProtocolIE-ContainerList { 1, maxNrOfRABs, {IEsSetParam} }
+RAB-IE-ContainerPairList { RANAP-PROTOCOL-IES-PAIR : IEsSetParam } ::= ProtocolIE-ContainerPairList { 1, maxNrOfRABs, {IEsSetParam} }
+ProtocolError-IE-ContainerList { RANAP-PROTOCOL-IES : IEsSetParam } ::= ProtocolIE-ContainerList { 1, maxNrOfRABs, {IEsSetParam} }
+IuSigConId-IE-ContainerList { RANAP-PROTOCOL-IES : IEsSetParam } ::= ProtocolIE-ContainerList { 1, maxNrOfIuSigConIds, {IEsSetParam} }
+DirectTransfer-IE-ContainerList { RANAP-PROTOCOL-IES : IEsSetParam } ::= ProtocolIE-ContainerList { 1, maxNrOfDTs, {IEsSetParam} }
+
+-- **************************************************************
+--
+-- Iu RELEASE ELEMENTARY PROCEDURE
+--
+-- **************************************************************
+
+-- **************************************************************
+--
+-- Iu Release Command
+--
+-- **************************************************************
+
+Iu-ReleaseCommand ::= SEQUENCE {
+ protocolIEs ProtocolIE-Container { {Iu-ReleaseCommandIEs} },
+ protocolExtensions ProtocolExtensionContainer { {Iu-ReleaseCommandExtensions} } OPTIONAL,
+ ...
+}
+
+Iu-ReleaseCommandIEs RANAP-PROTOCOL-IES ::= {
+ { ID id-Cause CRITICALITY ignore TYPE Cause PRESENCE mandatory },
+ ...
+}
+
+Iu-ReleaseCommandExtensions RANAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+-- **************************************************************
+--
+-- Iu Release Complete
+--
+-- **************************************************************
+
+Iu-ReleaseComplete ::= SEQUENCE {
+ protocolIEs ProtocolIE-Container { {Iu-ReleaseCompleteIEs} },
+ protocolExtensions ProtocolExtensionContainer { {Iu-ReleaseCompleteExtensions} } OPTIONAL,
+ ...
+}
+
+Iu-ReleaseCompleteIEs RANAP-PROTOCOL-IES ::= {
+ { ID id-RAB-DataVolumeReportList CRITICALITY ignore TYPE RAB-DataVolumeReportList PRESENCE optional } |
+ { ID id-RAB-ReleasedList-IuRelComp CRITICALITY ignore TYPE RAB-ReleasedList-IuRelComp PRESENCE optional } |
+ { ID id-CriticalityDiagnostics CRITICALITY ignore TYPE CriticalityDiagnostics PRESENCE optional },
+ ...
+}
+
+RAB-DataVolumeReportList ::= RAB-IE-ContainerList { {RAB-DataVolumeReportItemIEs} }
+
+RAB-DataVolumeReportItemIEs RANAP-PROTOCOL-IES ::= {
+ { ID id-RAB-DataVolumeReportItem CRITICALITY ignore TYPE RAB-DataVolumeReportItem PRESENCE mandatory },
+ ...
+}
+
+RAB-DataVolumeReportItem ::= SEQUENCE {
+ rAB-ID RAB-ID,
+ dl-UnsuccessfullyTransmittedDataVolume DataVolumeList OPTIONAL
+ -- This IE shall always be present although its presence is optional --,
+ iE-Extensions ProtocolExtensionContainer { {RAB-DataVolumeReportItem-ExtIEs} } OPTIONAL,
+ ...
+}
+
+RAB-DataVolumeReportItem-ExtIEs RANAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+RAB-ReleasedList-IuRelComp ::= RAB-IE-ContainerList { {RAB-ReleasedItem-IuRelComp-IEs} }
+
+RAB-ReleasedItem-IuRelComp-IEs RANAP-PROTOCOL-IES ::= {
+ { ID id-RAB-ReleasedItem-IuRelComp CRITICALITY ignore TYPE RAB-ReleasedItem-IuRelComp PRESENCE mandatory },
+ ...
+}
+
+RAB-ReleasedItem-IuRelComp ::= SEQUENCE {
+ rAB-ID RAB-ID,
+ dL-GTP-PDU-SequenceNumber DL-GTP-PDU-SequenceNumber OPTIONAL,
+ uL-GTP-PDU-SequenceNumber UL-GTP-PDU-SequenceNumber OPTIONAL,
+ iE-Extensions ProtocolExtensionContainer { {RAB-ReleasedItem-IuRelComp-ExtIEs} } OPTIONAL,
+ ...
+}
+
+RAB-ReleasedItem-IuRelComp-ExtIEs RANAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+
+Iu-ReleaseCompleteExtensions RANAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+-- **************************************************************
+--
+-- RELOCATION PREPARATION ELEMENTARY PROCEDURE
+--
+-- **************************************************************
+
+-- **************************************************************
+--
+-- Relocation Required
+--
+-- **************************************************************
+
+RelocationRequired ::= SEQUENCE {
+ protocolIEs ProtocolIE-Container { {RelocationRequiredIEs} },
+ protocolExtensions ProtocolExtensionContainer { {RelocationRequiredExtensions} } OPTIONAL,
+...
+}
+
+RelocationRequiredIEs RANAP-PROTOCOL-IES ::= {
+ { ID id-RelocationType CRITICALITY reject TYPE RelocationType PRESENCE mandatory } |
+ { ID id-Cause CRITICALITY ignore TYPE Cause PRESENCE mandatory } |
+ { ID id-SourceID CRITICALITY ignore TYPE SourceID PRESENCE mandatory } |
+ { ID id-TargetID CRITICALITY reject TYPE TargetID PRESENCE mandatory } |
+ { ID id-ClassmarkInformation2 CRITICALITY reject TYPE ClassmarkInformation2 PRESENCE conditional
+ -- This IE shall be present if the Target ID IE contains a CGI IE and Source BSS To Target BSS Transparent Container is not included -- } |
+ { ID id-ClassmarkInformation3 CRITICALITY ignore TYPE ClassmarkInformation3 PRESENCE conditional
+ -- This IE shall be present if the Target ID IE contains a CGI IE and Source BSS To Target BSS Transparent Container is not included -- } |
+ { ID id-Source-ToTarget-TransparentContainer
+ CRITICALITY reject TYPE Source-ToTarget-TransparentContainer PRESENCE conditional
+ -- This IE shall be present if the Target ID IE contains a RNC-ID IE or eNB-ID -- } |
+ { ID id-OldBSS-ToNewBSS-Information CRITICALITY ignore TYPE OldBSS-ToNewBSS-Information PRESENCE optional } ,
+ ...
+}
+
+RelocationRequiredExtensions RANAP-PROTOCOL-EXTENSION ::= {
+-- Extension for Release 5 to enable GERAN support over Iu-cs --
+ { ID id-GERAN-Classmark CRITICALITY ignore EXTENSION GERAN-Classmark PRESENCE optional } |
+-- Extension for Release 6 to enable Inter-RAT PS Handover between UTRAN and GERAN A/Gb --
+ { ID id-SourceBSS-ToTargetBSS-TransparentContainer CRITICALITY ignore EXTENSION SourceBSS-ToTargetBSS-TransparentContainer PRESENCE optional }|
+-- Extension for Release 8 for SRVCC operation --
+ { ID id-SRVCC-HO-Indication CRITICALITY reject EXTENSION SRVCC-HO-Indication PRESENCE optional },
+ ...
+}
+
+-- **************************************************************
+--
+-- Relocation Command
+--
+-- **************************************************************
+
+RelocationCommand ::= SEQUENCE {
+ protocolIEs ProtocolIE-Container { {RelocationCommandIEs} },
+ protocolExtensions ProtocolExtensionContainer { {RelocationCommandExtensions} } OPTIONAL,
+ ...
+}
+
+RelocationCommandIEs RANAP-PROTOCOL-IES ::= {
+ { ID id-Target-ToSource-TransparentContainer
+ CRITICALITY reject TYPE Target-ToSource-TransparentContainer PRESENCE optional } |
+ { ID id-L3-Information CRITICALITY ignore TYPE L3-Information PRESENCE optional } |
+ { ID id-RAB-RelocationReleaseList CRITICALITY ignore TYPE RAB-RelocationReleaseList PRESENCE optional } |
+ { ID id-RAB-DataForwardingList CRITICALITY ignore TYPE RAB-DataForwardingList PRESENCE optional } |
+ { ID id-CriticalityDiagnostics CRITICALITY ignore TYPE CriticalityDiagnostics PRESENCE optional },
+ ...
+}
+
+RAB-RelocationReleaseList ::= RAB-IE-ContainerList { {RAB-RelocationReleaseItemIEs} }
+
+RAB-RelocationReleaseItemIEs RANAP-PROTOCOL-IES ::= {
+ { ID id-RAB-RelocationReleaseItem CRITICALITY ignore TYPE RAB-RelocationReleaseItem PRESENCE mandatory },
+ ...
+}
+
+RAB-RelocationReleaseItem ::= SEQUENCE {
+ rAB-ID RAB-ID,
+ iE-Extensions ProtocolExtensionContainer { {RAB-RelocationReleaseItem-ExtIEs} } OPTIONAL,
+ ...
+}
+
+RAB-RelocationReleaseItem-ExtIEs RANAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+RAB-DataForwardingList ::= RAB-IE-ContainerList { {RAB-DataForwardingItemIEs} }
+
+RAB-DataForwardingItemIEs RANAP-PROTOCOL-IES ::= {
+ { ID id-RAB-DataForwardingItem CRITICALITY ignore TYPE RAB-DataForwardingItem PRESENCE mandatory },
+ ...
+}
+
+RAB-DataForwardingItem ::= SEQUENCE {
+ rAB-ID RAB-ID,
+ transportLayerAddress TransportLayerAddress,
+ iuTransportAssociation IuTransportAssociation,
+ iE-Extensions ProtocolExtensionContainer { {RAB-DataForwardingItem-ExtIEs} } OPTIONAL,
+ ...
+}
+
+RAB-DataForwardingItem-ExtIEs RANAP-PROTOCOL-EXTENSION ::= {
+-- Extension for Release 5 to allow transfer of a second pair of TLA and association --
+ {ID id-TransportLayerAddress CRITICALITY ignore EXTENSION TransportLayerAddress PRESENCE optional} |
+ {ID id-IuTransportAssociation CRITICALITY ignore EXTENSION IuTransportAssociation PRESENCE optional},
+ ...
+}
+
+RelocationCommandExtensions RANAP-PROTOCOL-EXTENSION ::= {
+-- Extension for Release 5 to enable Inter RAN Load Information Exchange over Iu --
+ { ID id-InterSystemInformation-TransparentContainer CRITICALITY ignore EXTENSION InterSystemInformation-TransparentContainer PRESENCE optional } |
+-- Extension for Release 6 to enable Inter-RAT PS Handover between UTRAN and GERAN A/Gb --
+ { ID id-TargetBSS-ToSourceBSS-TransparentContainer CRITICALITY ignore EXTENSION TargetBSS-ToSourceBSS-TransparentContainer PRESENCE optional },
+ ...
+}
+
+-- **************************************************************
+--
+-- Relocation Preparation Failure
+--
+-- **************************************************************
+
+RelocationPreparationFailure ::= SEQUENCE {
+ protocolIEs ProtocolIE-Container { {RelocationPreparationFailureIEs} },
+ protocolExtensions ProtocolExtensionContainer { {RelocationPreparationFailureExtensions} } OPTIONAL,
+...
+}
+
+RelocationPreparationFailureIEs RANAP-PROTOCOL-IES ::= {
+ { ID id-Cause CRITICALITY ignore TYPE Cause PRESENCE mandatory } |
+ { ID id-CriticalityDiagnostics CRITICALITY ignore TYPE CriticalityDiagnostics PRESENCE optional },
+ ...
+}
+
+RelocationPreparationFailureExtensions RANAP-PROTOCOL-EXTENSION ::= {
+-- Extension for Release 5 to enable Inter RAN Load Information Exchange over Iu --
+ { ID id-InterSystemInformation-TransparentContainer CRITICALITY ignore EXTENSION InterSystemInformation-TransparentContainer PRESENCE optional },
+ ...
+}
+
+-- **************************************************************
+--
+-- RELOCATION RESOURCE ALLOCATION ELEMENTARY PROCEDURE
+--
+-- **************************************************************
+
+-- **************************************************************
+--
+-- Relocation Request
+--
+-- **************************************************************
+
+RelocationRequest ::= SEQUENCE {
+ protocolIEs ProtocolIE-Container { {RelocationRequestIEs} },
+ protocolExtensions ProtocolExtensionContainer { {RelocationRequestExtensions} } OPTIONAL,
+ ...
+}
+
+RelocationRequestIEs RANAP-PROTOCOL-IES ::= {
+ { ID id-PermanentNAS-UE-ID CRITICALITY ignore TYPE PermanentNAS-UE-ID PRESENCE optional } |
+ { ID id-Cause CRITICALITY ignore TYPE Cause PRESENCE mandatory } |
+ { ID id-CN-DomainIndicator CRITICALITY reject TYPE CN-DomainIndicator PRESENCE mandatory } |
+ { ID id-Source-ToTarget-TransparentContainer
+ CRITICALITY reject TYPE SourceRNC-ToTargetRNC-TransparentContainer PRESENCE mandatory } |
+ { ID id-RAB-SetupList-RelocReq CRITICALITY reject TYPE RAB-SetupList-RelocReq PRESENCE optional } |
+ { ID id-IntegrityProtectionInformation CRITICALITY ignore TYPE IntegrityProtectionInformation PRESENCE optional } |
+ { ID id-EncryptionInformation CRITICALITY ignore TYPE EncryptionInformation PRESENCE optional } |
+ { ID id-IuSigConId CRITICALITY ignore TYPE IuSignallingConnectionIdentifier PRESENCE mandatory },
+ ...
+}
+
+RAB-SetupList-RelocReq ::= RAB-IE-ContainerList { {RAB-SetupItem-RelocReq-IEs} }
+
+RAB-SetupItem-RelocReq-IEs RANAP-PROTOCOL-IES ::= {
+ { ID id-RAB-SetupItem-RelocReq CRITICALITY reject TYPE RAB-SetupItem-RelocReq PRESENCE mandatory },
+ ...
+}
+
+RAB-SetupItem-RelocReq ::= SEQUENCE {
+ rAB-ID RAB-ID,
+ nAS-SynchronisationIndicator NAS-SynchronisationIndicator OPTIONAL,
+ rAB-Parameters RAB-Parameters,
+ dataVolumeReportingIndication DataVolumeReportingIndication OPTIONAL
+ -- This IE shall be present if the CN domain indicator IE is set to "PS domain" --,
+ pDP-TypeInformation PDP-TypeInformation OPTIONAL
+ -- This IE shall be present if the CN domain indicator IE is set to "PS domain" --,
+ userPlaneInformation UserPlaneInformation,
+ transportLayerAddress TransportLayerAddress,
+ iuTransportAssociation IuTransportAssociation,
+ service-Handover Service-Handover OPTIONAL,
+ iE-Extensions ProtocolExtensionContainer { {RAB-SetupItem-RelocReq-ExtIEs} } OPTIONAL,
+ ...
+}
+
+RAB-SetupItem-RelocReq-ExtIEs RANAP-PROTOCOL-EXTENSION ::= {
+-- Extension for Release 4 to enable RAB Quality of Service negotiation over Iu --
+ {ID id-Alt-RAB-Parameters CRITICALITY ignore EXTENSION Alt-RAB-Parameters PRESENCE optional} |
+-- Extension for Release 5 to enable GERAN support over Iu-cs --
+ { ID id-GERAN-BSC-Container CRITICALITY ignore EXTENSION GERAN-BSC-Container PRESENCE optional },
+ ...
+}
+
+UserPlaneInformation ::= SEQUENCE {
+ userPlaneMode UserPlaneMode,
+ uP-ModeVersions UP-ModeVersions,
+ iE-Extensions ProtocolExtensionContainer { {UserPlaneInformation-ExtIEs} } OPTIONAL,
+ ...
+}
+
+UserPlaneInformation-ExtIEs RANAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+RelocationRequestExtensions RANAP-PROTOCOL-EXTENSION ::= {
+-- Extension for Release 4 --
+ { ID id-GlobalCN-ID CRITICALITY reject EXTENSION GlobalCN-ID PRESENCE optional} |
+-- Extension for Release 5 to enable shared networks in connected mode --
+ { ID id-SNA-Access-Information CRITICALITY ignore EXTENSION SNA-Access-Information PRESENCE optional} |
+-- Extension for Release 5 to enable specific behaviour by the RNC in relation with early UE handling --
+ { ID id-UESBI-Iu CRITICALITY ignore EXTENSION UESBI-Iu PRESENCE optional}|
+-- Extension for Release 6 to convey the selected PLMN id in network sharing mobility scenarios --
+ { ID id-SelectedPLMN-ID CRITICALITY ignore EXTENSION PLMNidentity PRESENCE optional }|
+-- Extension for Release 6 to enable MBMS UE linking at relocation --
+ { ID id-CNMBMSLinkingInformation CRITICALITY ignore EXTENSION CNMBMSLinkingInformation PRESENCE optional},
+ ...
+}
+
+CNMBMSLinkingInformation ::= SEQUENCE {
+ joinedMBMSBearerService-IEs JoinedMBMSBearerService-IEs,
+ iE-Extensions ProtocolExtensionContainer { {CNMBMSLinkingInformation-ExtIEs} } OPTIONAL,
+ ...
+}
+
+CNMBMSLinkingInformation-ExtIEs RANAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+JoinedMBMSBearerService-IEs ::= SEQUENCE (SIZE (1.. maxnoofMulticastServicesPerUE)) OF
+ SEQUENCE {
+ tMGI TMGI,
+ mBMS-PTP-RAB-ID MBMS-PTP-RAB-ID,
+ iE-Extensions ProtocolExtensionContainer { {JoinedMBMSBearerService-ExtIEs} } OPTIONAL,
+ ...
+ }
+
+JoinedMBMSBearerService-ExtIEs RANAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+-- **************************************************************
+--
+-- Relocation Request Acknowledge
+--
+-- **************************************************************
+
+RelocationRequestAcknowledge ::= SEQUENCE {
+ protocolIEs ProtocolIE-Container { {RelocationRequestAcknowledgeIEs} },
+ protocolExtensions ProtocolExtensionContainer { {RelocationRequestAcknowledgeExtensions} } OPTIONAL,
+ ...
+}
+
+RelocationRequestAcknowledgeIEs RANAP-PROTOCOL-IES ::= {
+ { ID id-Target-ToSource-TransparentContainer
+ CRITICALITY ignore TYPE TargetRNC-ToSourceRNC-TransparentContainer PRESENCE optional } |
+ { ID id-RAB-SetupList-RelocReqAck CRITICALITY ignore TYPE RAB-SetupList-RelocReqAck PRESENCE optional} |
+ { ID id-RAB-FailedList CRITICALITY ignore TYPE RAB-FailedList PRESENCE optional }|
+ { ID id-ChosenIntegrityProtectionAlgorithm CRITICALITY ignore TYPE ChosenIntegrityProtectionAlgorithm PRESENCE optional } |
+ { ID id-ChosenEncryptionAlgorithm CRITICALITY ignore TYPE ChosenEncryptionAlgorithm PRESENCE optional } |
+ { ID id-CriticalityDiagnostics CRITICALITY ignore TYPE CriticalityDiagnostics PRESENCE optional },
+ ...
+}
+
+RAB-SetupList-RelocReqAck ::= RAB-IE-ContainerList { {RAB-SetupItem-RelocReqAck-IEs} }
+
+RAB-SetupItem-RelocReqAck-IEs RANAP-PROTOCOL-IES ::= {
+ { ID id-RAB-SetupItem-RelocReqAck CRITICALITY reject TYPE RAB-SetupItem-RelocReqAck PRESENCE mandatory },
+ ...
+}
+
+RAB-SetupItem-RelocReqAck ::= SEQUENCE {
+ rAB-ID RAB-ID,
+ transportLayerAddress TransportLayerAddress OPTIONAL,
+ iuTransportAssociation IuTransportAssociation OPTIONAL,
+ iE-Extensions ProtocolExtensionContainer { {RAB-SetupItem-RelocReqAck-ExtIEs} } OPTIONAL,
+ ...
+}
+
+RAB-SetupItem-RelocReqAck-ExtIEs RANAP-PROTOCOL-EXTENSION ::= {
+-- Extension for Release 4 to enable RAB Quality of Service negotiation over Iu --
+ {ID id-Ass-RAB-Parameters CRITICALITY ignore EXTENSION Ass-RAB-Parameters PRESENCE optional } |
+-- Extension for Release 5 to allow transfer of a second pair of TLA and association --
+ {ID id-TransportLayerAddress CRITICALITY ignore EXTENSION TransportLayerAddress PRESENCE optional} |
+ {ID id-IuTransportAssociation CRITICALITY ignore EXTENSION IuTransportAssociation PRESENCE optional},
+ ...
+}
+
+RAB-FailedList ::= RAB-IE-ContainerList { {RAB-FailedItemIEs} }
+
+RAB-FailedItemIEs RANAP-PROTOCOL-IES ::= {
+ { ID id-RAB-FailedItem CRITICALITY ignore TYPE RAB-FailedItem PRESENCE mandatory },
+ ...
+}
+
+RAB-FailedItem ::= SEQUENCE {
+ rAB-ID RAB-ID,
+ cause Cause,
+ iE-Extensions ProtocolExtensionContainer { {RAB-FailedItem-ExtIEs} } OPTIONAL,
+ ...
+}
+
+RAB-FailedItem-ExtIEs RANAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+RelocationRequestAcknowledgeExtensions RANAP-PROTOCOL-EXTENSION ::= {
+-- Extension for Release 5 to enable Inter RAN Load Information Exchange over Iu --
+ {ID id-NewBSS-To-OldBSS-Information CRITICALITY ignore EXTENSION NewBSS-To-OldBSS-Information PRESENCE optional },
+ ...
+}
+
+-- **************************************************************
+--
+-- Relocation Failure
+--
+-- **************************************************************
+
+RelocationFailure ::= SEQUENCE {
+ protocolIEs ProtocolIE-Container { {RelocationFailureIEs} },
+ protocolExtensions ProtocolExtensionContainer { {RelocationFailureExtensions} } OPTIONAL,
+ ...
+}
+
+RelocationFailureIEs RANAP-PROTOCOL-IES ::= {
+ { ID id-Cause CRITICALITY ignore TYPE Cause PRESENCE mandatory } |
+ { ID id-CriticalityDiagnostics CRITICALITY ignore TYPE CriticalityDiagnostics PRESENCE optional },
+ ...
+}
+
+RelocationFailureExtensions RANAP-PROTOCOL-EXTENSION ::= {
+-- Extension for Release 5 to enable Inter RAN Load Information Exchange over Iu --
+ { ID id-NewBSS-To-OldBSS-Information CRITICALITY ignore EXTENSION NewBSS-To-OldBSS-Information PRESENCE optional } |
+-- Extension for Release 5 to enable GERAN support over Iu-cs --
+ { ID id-GERAN-Classmark CRITICALITY ignore EXTENSION GERAN-Classmark PRESENCE optional },
+ ...
+}
+
+-- **************************************************************
+--
+-- RELOCATION CANCEL ELEMENTARY PROCEDURE
+--
+-- **************************************************************
+
+-- **************************************************************
+--
+-- Relocation Cancel
+--
+-- **************************************************************
+
+RelocationCancel ::= SEQUENCE {
+ protocolIEs ProtocolIE-Container { {RelocationCancelIEs} },
+ protocolExtensions ProtocolExtensionContainer { {RelocationCancelExtensions} } OPTIONAL,
+ ...
+}
+
+RelocationCancelIEs RANAP-PROTOCOL-IES ::= {
+ { ID id-Cause CRITICALITY ignore TYPE Cause PRESENCE mandatory },
+ ...
+}
+
+RelocationCancelExtensions RANAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+-- **************************************************************
+--
+-- Relocation Cancel Acknowledge
+--
+-- **************************************************************
+
+RelocationCancelAcknowledge ::= SEQUENCE {
+ protocolIEs ProtocolIE-Container { {RelocationCancelAcknowledgeIEs} },
+ protocolExtensions ProtocolExtensionContainer { {RelocationCancelAcknowledgeExtensions} } OPTIONAL,
+ ...
+}
+
+RelocationCancelAcknowledgeIEs RANAP-PROTOCOL-IES ::= {
+ { ID id-CriticalityDiagnostics CRITICALITY ignore TYPE CriticalityDiagnostics PRESENCE optional },
+ ...
+}
+
+RelocationCancelAcknowledgeExtensions RANAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+-- **************************************************************
+--
+-- SRNS CONTEXT TRANSFER OPEARATION
+--
+-- **************************************************************
+
+-- **************************************************************
+--
+-- SRNS Context Request
+--
+-- **************************************************************
+
+SRNS-ContextRequest ::= SEQUENCE {
+ protocolIEs ProtocolIE-Container { {SRNS-ContextRequestIEs} },
+ protocolExtensions ProtocolExtensionContainer { {SRNS-ContextRequestExtensions} } OPTIONAL,
+ ...
+}
+
+SRNS-ContextRequestIEs RANAP-PROTOCOL-IES ::= {
+ { ID id-RAB-DataForwardingList-SRNS-CtxReq CRITICALITY ignore TYPE RAB-DataForwardingList-SRNS-CtxReq PRESENCE mandatory },
+ ...
+}
+
+RAB-DataForwardingList-SRNS-CtxReq ::= RAB-IE-ContainerList { {RAB-DataForwardingItem-SRNS-CtxReq-IEs} }
+
+RAB-DataForwardingItem-SRNS-CtxReq-IEs RANAP-PROTOCOL-IES ::= {
+ { ID id-RAB-DataForwardingItem-SRNS-CtxReq CRITICALITY reject TYPE RAB-DataForwardingItem-SRNS-CtxReq PRESENCE mandatory },
+ ...
+}
+
+RAB-DataForwardingItem-SRNS-CtxReq ::= SEQUENCE {
+ rAB-ID RAB-ID,
+ iE-Extensions ProtocolExtensionContainer { {RAB-DataForwardingItem-SRNS-CtxReq-ExtIEs} } OPTIONAL,
+ ...
+}
+
+RAB-DataForwardingItem-SRNS-CtxReq-ExtIEs RANAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+SRNS-ContextRequestExtensions RANAP-PROTOCOL-EXTENSION ::= {
+-- The SGSN may include the IE, when available to indicate the RAT from which the context request originates, to correct measurement points in SRNC. --
+ {ID id-RAT-Type CRITICALITY ignore EXTENSION RAT-Type PRESENCE optional },
+ ...
+}
+
+-- **************************************************************
+--
+-- SRNS Context Response
+--
+-- **************************************************************
+
+SRNS-ContextResponse ::= SEQUENCE {
+ protocolIEs ProtocolIE-Container { {SRNS-ContextResponseIEs} },
+ protocolExtensions ProtocolExtensionContainer { {SRNS-ContextResponseExtensions} } OPTIONAL,
+ ...
+}
+
+SRNS-ContextResponseIEs RANAP-PROTOCOL-IES ::= {
+ { ID id-RAB-ContextList CRITICALITY ignore TYPE RAB-ContextList PRESENCE optional } |
+ { ID id-RAB-ContextFailedtoTransferList CRITICALITY ignore TYPE RAB-ContextFailedtoTransferList PRESENCE optional }|
+ { ID id-CriticalityDiagnostics CRITICALITY ignore TYPE CriticalityDiagnostics PRESENCE optional },
+ ...
+}
+
+RAB-ContextList ::= RAB-IE-ContainerList { {RAB-ContextItemIEs} }
+
+RAB-ContextItemIEs RANAP-PROTOCOL-IES ::= {
+ { ID id-RAB-ContextItem CRITICALITY ignore TYPE RAB-ContextItem PRESENCE mandatory },
+ ...
+}
+
+RAB-ContextItem ::= SEQUENCE {
+ rAB-ID RAB-ID,
+ dl-GTP-PDU-SequenceNumber DL-GTP-PDU-SequenceNumber OPTIONAL,
+ ul-GTP-PDU-SequenceNumber UL-GTP-PDU-SequenceNumber OPTIONAL,
+ dl-N-PDU-SequenceNumber DL-N-PDU-SequenceNumber OPTIONAL,
+ ul-N-PDU-SequenceNumber UL-N-PDU-SequenceNumber OPTIONAL,
+ iE-Extensions ProtocolExtensionContainer { {RAB-ContextItem-ExtIEs} } OPTIONAL,
+ ...
+}
+
+RAB-ContextItem-ExtIEs RANAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+RAB-ContextFailedtoTransferList ::= RAB-IE-ContainerList { {RABs-ContextFailedtoTransferItemIEs} }
+
+RABs-ContextFailedtoTransferItemIEs RANAP-PROTOCOL-IES ::= {
+ { ID id-RAB-ContextFailedtoTransferItem CRITICALITY ignore TYPE RABs-ContextFailedtoTransferItem PRESENCE mandatory },
+ ...
+}
+
+RABs-ContextFailedtoTransferItem::= SEQUENCE {
+ rAB-ID RAB-ID,
+ cause Cause,
+ iE-Extensions ProtocolExtensionContainer { { RABs-ContextFailedtoTransferItem-ExtIEs} } OPTIONAL,
+ ...
+}
+
+
+RABs-ContextFailedtoTransferItem-ExtIEs RANAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+SRNS-ContextResponseExtensions RANAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+-- **************************************************************
+--
+-- SECURITY MODE CONTROL ELEMENTARY PROCEDURE
+--
+-- **************************************************************
+
+-- **************************************************************
+--
+-- Security Mode Command
+--
+-- **************************************************************
+
+SecurityModeCommand ::= SEQUENCE {
+ protocolIEs ProtocolIE-Container { {SecurityModeCommandIEs} },
+ protocolExtensions ProtocolExtensionContainer { {SecurityModeCommandExtensions} } OPTIONAL,
+ ...
+}
+
+SecurityModeCommandIEs RANAP-PROTOCOL-IES ::= {
+ { ID id-IntegrityProtectionInformation CRITICALITY reject TYPE IntegrityProtectionInformation PRESENCE mandatory } |
+ { ID id-EncryptionInformation CRITICALITY ignore TYPE EncryptionInformation PRESENCE optional } |
+ { ID id-KeyStatus CRITICALITY reject TYPE KeyStatus PRESENCE mandatory},
+ ...
+}
+
+SecurityModeCommandExtensions RANAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+-- **************************************************************
+--
+-- Security Mode Complete
+--
+-- **************************************************************
+
+SecurityModeComplete ::= SEQUENCE {
+ protocolIEs ProtocolIE-Container { {SecurityModeCompleteIEs} },
+ protocolExtensions ProtocolExtensionContainer { {SecurityModeCompleteExtensions} } OPTIONAL,
+ ...
+}
+
+SecurityModeCompleteIEs RANAP-PROTOCOL-IES ::= {
+ { ID id-ChosenIntegrityProtectionAlgorithm CRITICALITY reject TYPE ChosenIntegrityProtectionAlgorithm PRESENCE mandatory } |
+ { ID id-ChosenEncryptionAlgorithm CRITICALITY ignore TYPE ChosenEncryptionAlgorithm PRESENCE optional } |
+ { ID id-CriticalityDiagnostics CRITICALITY ignore TYPE CriticalityDiagnostics PRESENCE optional },
+ ...
+}
+
+SecurityModeCompleteExtensions RANAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+-- **************************************************************
+--
+-- Security Mode Reject
+--
+-- **************************************************************
+
+SecurityModeReject ::= SEQUENCE {
+ protocolIEs ProtocolIE-Container { {SecurityModeRejectIEs} },
+ protocolExtensions ProtocolExtensionContainer { {SecurityModeRejectExtensions} } OPTIONAL,
+ ...
+}
+
+SecurityModeRejectIEs RANAP-PROTOCOL-IES ::= {
+ { ID id-Cause CRITICALITY ignore TYPE Cause PRESENCE mandatory } |
+ { ID id-CriticalityDiagnostics CRITICALITY ignore TYPE CriticalityDiagnostics PRESENCE optional },
+ ...
+}
+
+SecurityModeRejectExtensions RANAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+-- **************************************************************
+--
+-- DATA VOLUME REPORT ELEMENTARY PROCEDURE
+--
+-- **************************************************************
+
+-- **************************************************************
+--
+-- Data Volume Report Request
+--
+-- **************************************************************
+
+DataVolumeReportRequest ::= SEQUENCE {
+ protocolIEs ProtocolIE-Container { {DataVolumeReportRequestIEs} },
+ protocolExtensions ProtocolExtensionContainer { {DataVolumeReportRequestExtensions} } OPTIONAL,
+ ...
+}
+
+DataVolumeReportRequestIEs RANAP-PROTOCOL-IES ::= {
+ { ID id-RAB-DataVolumeReportRequestList CRITICALITY ignore TYPE RAB-DataVolumeReportRequestList PRESENCE mandatory },
+ ...
+}
+
+RAB-DataVolumeReportRequestList ::= RAB-IE-ContainerList { {RAB-DataVolumeReportRequestItemIEs} }
+
+RAB-DataVolumeReportRequestItemIEs RANAP-PROTOCOL-IES ::= {
+ { ID id-RAB-DataVolumeReportRequestItem CRITICALITY reject TYPE RAB-DataVolumeReportRequestItem PRESENCE mandatory },
+ ...
+}
+
+RAB-DataVolumeReportRequestItem ::= SEQUENCE {
+ rAB-ID RAB-ID,
+ iE-Extensions ProtocolExtensionContainer { {RAB-DataVolumeReportRequestItem-ExtIEs} } OPTIONAL,
+ ...
+}
+
+RAB-DataVolumeReportRequestItem-ExtIEs RANAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+DataVolumeReportRequestExtensions RANAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+-- **************************************************************
+--
+-- Data Volume Report
+--
+-- **************************************************************
+
+DataVolumeReport ::= SEQUENCE {
+ protocolIEs ProtocolIE-Container { {DataVolumeReportIEs} },
+ protocolExtensions ProtocolExtensionContainer { {DataVolumeReportExtensions} } OPTIONAL,
+ ...
+}
+
+DataVolumeReportIEs RANAP-PROTOCOL-IES ::= {
+ { ID id-RAB-DataVolumeReportList CRITICALITY ignore TYPE RAB-DataVolumeReportList PRESENCE optional } |
+ { ID id-RAB-FailedtoReportList CRITICALITY ignore TYPE RAB-FailedtoReportList PRESENCE optional } |
+ { ID id-CriticalityDiagnostics CRITICALITY ignore TYPE CriticalityDiagnostics PRESENCE optional },
+ ...
+}
+
+DataVolumeReportExtensions RANAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+RAB-FailedtoReportList ::= RAB-IE-ContainerList { {RABs-failed-to-reportItemIEs} }
+
+RABs-failed-to-reportItemIEs RANAP-PROTOCOL-IES ::= {
+ { ID id-RAB-FailedtoReportItem CRITICALITY ignore TYPE RABs-failed-to-reportItem PRESENCE mandatory },
+ ...
+}
+
+RABs-failed-to-reportItem::= SEQUENCE {
+ rAB-ID RAB-ID,
+ cause Cause,
+ iE-Extensions ProtocolExtensionContainer { { RABs-failed-to-reportItem-ExtIEs} } OPTIONAL,
+ ...
+}
+
+
+RABs-failed-to-reportItem-ExtIEs RANAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+
+-- **************************************************************
+--
+-- RESET ELEMENTARY PROCEDURE
+--
+-- **************************************************************
+
+-- **************************************************************
+--
+-- Reset
+--
+-- **************************************************************
+
+Reset ::= SEQUENCE {
+ protocolIEs ProtocolIE-Container { {ResetIEs} },
+ protocolExtensions ProtocolExtensionContainer { {ResetExtensions} } OPTIONAL,
+ ...
+}
+
+ResetIEs RANAP-PROTOCOL-IES ::= {
+ { ID id-Cause CRITICALITY ignore TYPE Cause PRESENCE mandatory } |
+ { ID id-CN-DomainIndicator CRITICALITY reject TYPE CN-DomainIndicator PRESENCE mandatory } |
+ { ID id-GlobalRNC-ID CRITICALITY ignore TYPE GlobalRNC-ID PRESENCE optional },
+ ...
+}
+
+ResetExtensions RANAP-PROTOCOL-EXTENSION ::= {
+-- Extension for Release 4 --
+ { ID id-GlobalCN-ID CRITICALITY ignore EXTENSION GlobalCN-ID PRESENCE optional}|
+-- Extension for Release 7 to indicate extended RNC-ID --
+ { ID id-ExtendedRNC-ID CRITICALITY reject EXTENSION ExtendedRNC-ID PRESENCE optional },
+ ...
+}
+
+-- **************************************************************
+--
+-- Reset Acknowledge
+--
+-- **************************************************************
+
+ResetAcknowledge ::= SEQUENCE {
+ protocolIEs ProtocolIE-Container { {ResetAcknowledgeIEs} },
+ protocolExtensions ProtocolExtensionContainer { {ResetAcknowledgeExtensions} } OPTIONAL,
+ ...
+}
+
+ResetAcknowledgeIEs RANAP-PROTOCOL-IES ::= {
+ { ID id-CN-DomainIndicator CRITICALITY reject TYPE CN-DomainIndicator PRESENCE mandatory } |
+ { ID id-CriticalityDiagnostics CRITICALITY ignore TYPE CriticalityDiagnostics PRESENCE optional } |
+ { ID id-GlobalRNC-ID CRITICALITY ignore TYPE GlobalRNC-ID PRESENCE optional },
+ ...
+}
+
+ResetAcknowledgeExtensions RANAP-PROTOCOL-EXTENSION ::= {
+-- Extension for Release 4 --
+ { ID id-GlobalCN-ID CRITICALITY ignore EXTENSION GlobalCN-ID PRESENCE optional}|
+-- Extension for Release 7 to indicate extended RNC-ID --
+ { ID id-ExtendedRNC-ID CRITICALITY reject EXTENSION ExtendedRNC-ID PRESENCE optional },
+ ...
+}
+-- **************************************************************
+--
+-- RESET RESOURCE ELEMENTARY PROCEDURE
+--
+-- **************************************************************
+
+
+-- **************************************************************
+--
+-- Reset Resource
+--
+-- **************************************************************
+
+ResetResource ::= SEQUENCE {
+ protocolIEs ProtocolIE-Container { {ResetResourceIEs} },
+ protocolExtensions ProtocolExtensionContainer { {ResetResourceExtensions} } OPTIONAL,
+ ...
+}
+
+ResetResourceIEs RANAP-PROTOCOL-IES ::= {
+ { ID id-CN-DomainIndicator CRITICALITY reject TYPE CN-DomainIndicator PRESENCE mandatory } |
+ { ID id-Cause CRITICALITY ignore TYPE Cause PRESENCE mandatory } |
+ { ID id-IuSigConIdList CRITICALITY ignore TYPE ResetResourceList PRESENCE mandatory } |
+ { ID id-GlobalRNC-ID CRITICALITY ignore TYPE GlobalRNC-ID PRESENCE optional },
+ ...
+}
+
+ResetResourceList ::= IuSigConId-IE-ContainerList{ {ResetResourceItemIEs} }
+
+ResetResourceItemIEs RANAP-PROTOCOL-IES ::= {
+ { ID id-IuSigConIdItem CRITICALITY reject TYPE ResetResourceItem PRESENCE mandatory },
+ ...
+}
+
+ResetResourceItem ::= SEQUENCE {
+ iuSigConId IuSignallingConnectionIdentifier,
+ iE-Extensions ProtocolExtensionContainer { { ResetResourceItem-ExtIEs} } OPTIONAL,
+ ...
+}
+
+ResetResourceItem-ExtIEs RANAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+ResetResourceExtensions RANAP-PROTOCOL-EXTENSION ::= {
+-- Extension for Release 4 --
+ { ID id-GlobalCN-ID CRITICALITY ignore EXTENSION GlobalCN-ID PRESENCE optional}|
+-- Extension for Release 7 to indicate extended RNC-ID --
+ { ID id-ExtendedRNC-ID CRITICALITY reject EXTENSION ExtendedRNC-ID PRESENCE optional },
+ ...
+}
+
+-- **************************************************************
+--
+-- Reset Resource Acknowledge
+--
+-- **************************************************************
+
+ResetResourceAcknowledge ::= SEQUENCE {
+ protocolIEs ProtocolIE-Container { {ResetResourceAcknowledgeIEs} },
+ protocolExtensions ProtocolExtensionContainer { {ResetResourceAcknowledgeExtensions} } OPTIONAL,
+ ...
+}
+
+ResetResourceAcknowledgeIEs RANAP-PROTOCOL-IES ::= {
+ { ID id-CN-DomainIndicator CRITICALITY reject TYPE CN-DomainIndicator PRESENCE mandatory } |
+ { ID id-IuSigConIdList CRITICALITY ignore TYPE ResetResourceAckList PRESENCE mandatory } |
+ { ID id-GlobalRNC-ID CRITICALITY ignore TYPE GlobalRNC-ID PRESENCE optional } |
+ { ID id-CriticalityDiagnostics CRITICALITY ignore TYPE CriticalityDiagnostics PRESENCE optional },
+ ...
+}
+ResetResourceAckList ::= IuSigConId-IE-ContainerList{ {ResetResourceAckItemIEs} }
+
+ResetResourceAckItemIEs RANAP-PROTOCOL-IES ::= {
+ { ID id-IuSigConIdItem CRITICALITY reject TYPE ResetResourceAckItem PRESENCE mandatory },
+ ...
+}
+
+ResetResourceAckItem ::= SEQUENCE {
+ iuSigConId IuSignallingConnectionIdentifier,
+ iE-Extensions ProtocolExtensionContainer { { ResetResourceAckItem-ExtIEs} } OPTIONAL,
+ ...
+}
+
+ResetResourceAckItem-ExtIEs RANAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+ResetResourceAcknowledgeExtensions RANAP-PROTOCOL-EXTENSION ::= {
+-- Extension for Release 4 --
+ { ID id-GlobalCN-ID CRITICALITY ignore EXTENSION GlobalCN-ID PRESENCE optional}|
+-- Extension for Release 7 to indicate extended RNC-ID --
+ { ID id-ExtendedRNC-ID CRITICALITY reject EXTENSION ExtendedRNC-ID PRESENCE optional},
+ ...
+}
+
+-- **************************************************************
+--
+-- RAB RELEASE REQUEST ELEMENTARY PROCEDURE
+--
+-- **************************************************************
+
+-- **************************************************************
+--
+-- RAB Release Request
+--
+-- **************************************************************
+
+RAB-ReleaseRequest ::= SEQUENCE {
+ protocolIEs ProtocolIE-Container { {RAB-ReleaseRequestIEs} },
+ protocolExtensions ProtocolExtensionContainer { {RAB-ReleaseRequestExtensions} } OPTIONAL,
+ ...
+}
+
+RAB-ReleaseRequestIEs RANAP-PROTOCOL-IES ::= {
+ { ID id-RAB-ReleaseList CRITICALITY ignore TYPE RAB-ReleaseList PRESENCE mandatory },
+ ...
+}
+
+RAB-ReleaseList ::= RAB-IE-ContainerList { {RAB-ReleaseItemIEs} }
+
+RAB-ReleaseItemIEs RANAP-PROTOCOL-IES ::= {
+ { ID id-RAB-ReleaseItem CRITICALITY ignore TYPE RAB-ReleaseItem PRESENCE mandatory },
+ ...
+}
+
+RAB-ReleaseItem ::= SEQUENCE {
+ rAB-ID RAB-ID,
+ cause Cause,
+ iE-Extensions ProtocolExtensionContainer { {RAB-ReleaseItem-ExtIEs} } OPTIONAL,
+ ...
+}
+
+RAB-ReleaseItem-ExtIEs RANAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+RAB-ReleaseRequestExtensions RANAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+-- **************************************************************
+--
+-- Iu RELEASE REQUEST ELEMENTARY PROCEDURE
+--
+-- **************************************************************
+
+-- **************************************************************
+--
+-- Iu Release Request
+--
+-- **************************************************************
+
+Iu-ReleaseRequest ::= SEQUENCE {
+ protocolIEs ProtocolIE-Container { {Iu-ReleaseRequestIEs} },
+ protocolExtensions ProtocolExtensionContainer { {Iu-ReleaseRequestExtensions} } OPTIONAL,
+ ...
+}
+
+Iu-ReleaseRequestIEs RANAP-PROTOCOL-IES ::= {
+ { ID id-Cause CRITICALITY ignore TYPE Cause PRESENCE mandatory },
+ ...
+}
+
+Iu-ReleaseRequestExtensions RANAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+-- **************************************************************
+--
+-- RELOCATION DETECT ELEMENTARY PROCEDURE
+--
+-- **************************************************************
+
+-- **************************************************************
+--
+-- Relocation Detect
+--
+-- **************************************************************
+
+RelocationDetect ::= SEQUENCE {
+ protocolIEs ProtocolIE-Container { {RelocationDetectIEs} },
+ protocolExtensions ProtocolExtensionContainer { {RelocationDetectExtensions} } OPTIONAL,
+ ...
+}
+
+RelocationDetectIEs RANAP-PROTOCOL-IES ::= {
+ ...
+}
+
+RelocationDetectExtensions RANAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+-- **************************************************************
+--
+-- RELOCATION COMPLETE ELEMENTARY PROCEDURE
+--
+-- **************************************************************
+
+-- **************************************************************
+--
+-- Relocation Complete
+--
+-- **************************************************************
+
+RelocationComplete ::= SEQUENCE {
+ protocolIEs ProtocolIE-Container { {RelocationCompleteIEs} },
+ protocolExtensions ProtocolExtensionContainer { {RelocationCompleteExtensions} } OPTIONAL,
+ ...
+}
+
+RelocationCompleteIEs RANAP-PROTOCOL-IES ::= {
+ ...
+}
+
+RelocationCompleteExtensions RANAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+-- **************************************************************
+--
+-- ENHANCED RELOCATION COMPLETE ELEMENTARY PROCEDURE
+--
+-- **************************************************************
+
+-- **************************************************************
+--
+-- Enhanced Relocation Complete Request
+--
+-- **************************************************************
+
+EnhancedRelocationCompleteRequest ::= SEQUENCE {
+ protocolIEs ProtocolIE-Container { {EnhancedRelocationCompleteRequestIEs} },
+ protocolExtensions ProtocolExtensionContainer { {EnhancedRelocationCompleteRequestExtensions} } OPTIONAL,
+ ...
+}
+
+EnhancedRelocationCompleteRequestIEs RANAP-PROTOCOL-IES ::= {
+ { ID id-OldIuSigConId CRITICALITY reject TYPE IuSignallingConnectionIdentifier PRESENCE mandatory } |
+ { ID id-IuSigConId CRITICALITY reject TYPE IuSignallingConnectionIdentifier PRESENCE mandatory } |
+ { ID id-Relocation-SourceRNC-ID CRITICALITY ignore TYPE GlobalRNC-ID PRESENCE mandatory } |
+ { ID id-Relocation-SourceExtendedRNC-ID CRITICALITY ignore TYPE ExtendedRNC-ID PRESENCE optional } |
+ { ID id-Relocation-TargetRNC-ID CRITICALITY reject TYPE GlobalRNC-ID PRESENCE mandatory } |
+ { ID id-Relocation-TargetExtendedRNC-ID CRITICALITY reject TYPE ExtendedRNC-ID PRESENCE optional } |
+ { ID id-RAB-SetupList-EnhancedRelocCompleteReq CRITICALITY reject TYPE RAB-SetupList-EnhancedRelocCompleteReq PRESENCE optional }
+, ...
+}
+
+RAB-SetupList-EnhancedRelocCompleteReq ::= RAB-IE-ContainerList { { RAB-SetupItem-EnhancedRelocCompleteReq-IEs} }
+
+RAB-SetupItem-EnhancedRelocCompleteReq-IEs RANAP-PROTOCOL-IES ::= {
+ { ID id-RAB-SetupItem-EnhancedRelocCompleteReq CRITICALITY reject TYPE RAB-SetupItem-EnhancedRelocCompleteReq PRESENCE mandatory },
+ ...
+}
+
+RAB-SetupItem-EnhancedRelocCompleteReq ::= SEQUENCE {
+ rAB-ID RAB-ID,
+ transportLayerAddressReq1 TransportLayerAddress OPTIONAL,
+ iuTransportAssociationReq1 IuTransportAssociation OPTIONAL,
+ ass-RAB-Parameters Ass-RAB-Parameters OPTIONAL,
+ iE-Extensions ProtocolExtensionContainer { { RAB-SetupItem-EnhancedRelocCompleteReq-ExtIEs} } OPTIONAL,
+ ...
+}
+
+RAB-SetupItem-EnhancedRelocCompleteReq-ExtIEs RANAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+EnhancedRelocationCompleteRequestExtensions RANAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+-- **************************************************************
+--
+-- Enhanced Relocation Complete Response
+--
+-- **************************************************************
+
+EnhancedRelocationCompleteResponse ::= SEQUENCE {
+ protocolIEs ProtocolIE-Container { {EnhancedRelocationCompleteResponseIEs} },
+ protocolExtensions ProtocolExtensionContainer { {EnhancedRelocationCompleteResponseExtensions} } OPTIONAL,
+ ...
+}
+
+EnhancedRelocationCompleteResponseIEs RANAP-PROTOCOL-IES ::= {
+ { ID id-RAB-SetupList-EnhancedRelocCompleteRes CRITICALITY ignore TYPE RAB-SetupList-EnhancedRelocCompleteRes PRESENCE optional} |
+ { ID id-RAB-ToBeReleasedList-EnhancedRelocCompleteRes CRITICALITY ignore TYPE RAB-ToBeReleasedList-EnhancedRelocCompleteRes PRESENCE optional} |
+ { ID id-CriticalityDiagnostics CRITICALITY ignore TYPE CriticalityDiagnostics PRESENCE optional },
+ ...
+}
+
+RAB-SetupList-EnhancedRelocCompleteRes ::= RAB-IE-ContainerList { {RAB-SetupItem-EnhancedRelocCompleteRes-IEs} }
+
+RAB-SetupItem-EnhancedRelocCompleteRes-IEs RANAP-PROTOCOL-IES ::= {
+ { ID id-RAB-SetupItem-EnhancedRelocCompleteRes CRITICALITY reject TYPE RAB-SetupItem-EnhancedRelocCompleteRes PRESENCE mandatory },
+ ...
+}
+
+RAB-SetupItem-EnhancedRelocCompleteRes ::= SEQUENCE {
+ rAB-ID RAB-ID,
+ rAB-Parameters RAB-Parameters OPTIONAL,
+ userPlaneInformation UserPlaneInformation,
+ transportLayerAddressRes1 TransportLayerAddress OPTIONAL,
+ iuTransportAssociationRes1 IuTransportAssociation OPTIONAL,
+ rab2beReleasedList RAB-ToBeReleasedList-EnhancedRelocCompleteRes OPTIONAL,
+ iE-Extensions ProtocolExtensionContainer { { RAB-SetupItem-EnhancedRelocCompleteRes-ExtIEs} } OPTIONAL,
+ ...
+}
+
+RAB-SetupItem-EnhancedRelocCompleteRes-ExtIEs RANAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+RAB-ToBeReleasedList-EnhancedRelocCompleteRes ::= RAB-IE-ContainerList { {RAB-ToBeReleasedItem-EnhancedRelocCompleteRes-IEs} }
+
+RAB-ToBeReleasedItem-EnhancedRelocCompleteRes-IEs RANAP-PROTOCOL-IES ::= {
+ { ID id-RAB-ToBeReleasedItem-EnhancedRelocCompleteRes CRITICALITY ignore TYPE RAB-ToBeReleasedItem-EnhancedRelocCompleteRes PRESENCE mandatory },
+ ...
+}
+
+RAB-ToBeReleasedItem-EnhancedRelocCompleteRes ::= SEQUENCE {
+ rAB-ID RAB-ID,
+ cause Cause,
+ iE-Extensions ProtocolExtensionContainer { { RAB-ToBeReleasedItem-EnhancedRelocCompleteRes-ExtIEs} } OPTIONAL,
+ ...
+}
+
+RAB-ToBeReleasedItem-EnhancedRelocCompleteRes-ExtIEs RANAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+EnhancedRelocationCompleteResponseExtensions RANAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+-- **************************************************************
+--
+-- Enhanced Relocation Complete Failure
+--
+-- **************************************************************
+
+EnhancedRelocationCompleteFailure ::= SEQUENCE {
+ protocolIEs ProtocolIE-Container { {EnhancedRelocationCompleteFailureIEs} },
+ protocolExtensions ProtocolExtensionContainer { {EnhancedRelocationCompleteFailureExtensions} } OPTIONAL,
+ ...
+}
+
+EnhancedRelocationCompleteFailureIEs RANAP-PROTOCOL-IES ::= {
+ { ID id-Cause CRITICALITY ignore TYPE Cause PRESENCE mandatory } |
+ { ID id-CriticalityDiagnostics CRITICALITY ignore TYPE CriticalityDiagnostics PRESENCE optional },
+ ...
+}
+
+EnhancedRelocationCompleteFailureExtensions RANAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+-- **************************************************************
+--
+-- Enhanced Relocation Complete Confirm
+--
+-- **************************************************************
+
+EnhancedRelocationCompleteConfirm ::= SEQUENCE {
+ protocolIEs ProtocolIE-Container { {EnhancedRelocationCompleteConfirmIEs} },
+ protocolExtensions ProtocolExtensionContainer { {EnhancedRelocationCompleteConfirmExtensions} } OPTIONAL,
+ ...
+}
+
+EnhancedRelocationCompleteConfirmIEs RANAP-PROTOCOL-IES ::= {
+ { ID id-RAB-FailedList CRITICALITY ignore TYPE RAB-FailedList PRESENCE optional },
+ ...
+}
+
+EnhancedRelocationCompleteConfirmExtensions RANAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+
+-- **************************************************************
+--
+-- PAGING ELEMENTARY PROCEDURE
+--
+-- **************************************************************
+
+-- **************************************************************
+--
+-- Paging
+--
+-- **************************************************************
+
+Paging ::= SEQUENCE {
+ protocolIEs ProtocolIE-Container { {PagingIEs} },
+ protocolExtensions ProtocolExtensionContainer { {PagingExtensions} } OPTIONAL,
+ ...
+}
+
+PagingIEs RANAP-PROTOCOL-IES ::= {
+ { ID id-CN-DomainIndicator CRITICALITY ignore TYPE CN-DomainIndicator PRESENCE mandatory } |
+ { ID id-PermanentNAS-UE-ID CRITICALITY ignore TYPE PermanentNAS-UE-ID PRESENCE mandatory } |
+ { ID id-TemporaryUE-ID CRITICALITY ignore TYPE TemporaryUE-ID PRESENCE optional } |
+ { ID id-PagingAreaID CRITICALITY ignore TYPE PagingAreaID PRESENCE optional } |
+ { ID id-PagingCause CRITICALITY ignore TYPE PagingCause PRESENCE optional } |
+ { ID id-NonSearchingIndication CRITICALITY ignore TYPE NonSearchingIndication PRESENCE optional } |
+ { ID id-DRX-CycleLengthCoefficient CRITICALITY ignore TYPE DRX-CycleLengthCoefficient PRESENCE optional } ,
+ ...
+}
+
+PagingExtensions RANAP-PROTOCOL-EXTENSION ::= {
+-- Extension for Release 5 to enable NNSF --
+ { ID id-GlobalCN-ID CRITICALITY ignore EXTENSION GlobalCN-ID PRESENCE optional } ,
+ ...
+}
+
+-- **************************************************************
+--
+-- COMMON ID ELEMENTARY PROCEDURE
+--
+-- **************************************************************
+
+-- **************************************************************
+--
+-- Common ID
+--
+-- **************************************************************
+
+CommonID ::= SEQUENCE {
+ protocolIEs ProtocolIE-Container { {CommonID-IEs} },
+ protocolExtensions ProtocolExtensionContainer { {CommonIDExtensions} } OPTIONAL,
+ ...
+}
+
+CommonID-IEs RANAP-PROTOCOL-IES ::= {
+ { ID id-PermanentNAS-UE-ID CRITICALITY ignore TYPE PermanentNAS-UE-ID PRESENCE mandatory },
+ ...
+}
+
+CommonIDExtensions RANAP-PROTOCOL-EXTENSION ::= {
+-- Extension for Release 5 to enable shared networks in connected mode --
+ { ID id-SNA-Access-Information CRITICALITY ignore EXTENSION SNA-Access-Information PRESENCE optional } |
+-- Extension for Release 5 to enable specific behaviour by the RNC in relation with early UE handling --
+ { ID id-UESBI-Iu CRITICALITY ignore EXTENSION UESBI-Iu PRESENCE optional}|
+-- Extension for Release 6 to indicate the selected plmn in GWCN configuration for network sharing non-supporting UEs --
+ { ID id-SelectedPLMN-ID CRITICALITY ignore EXTENSION PLMNidentity PRESENCE optional }|
+-- Extension for Release 8 to indicate the Subscriber Profile ID for RAT/Frequency Selection Priority --
+ {ID id-SubscriberProfileIDforRFP CRITICALITY ignore EXTENSION SubscriberProfileIDforRFP PRESENCE optional},
+ ...
+}
+
+-- **************************************************************
+--
+-- CN INVOKE TRACE ELEMENTARY PROCEDURE
+--
+-- **************************************************************
+
+-- **************************************************************
+--
+-- CN Invoke Trace
+--
+-- **************************************************************
+
+CN-InvokeTrace ::= SEQUENCE {
+ protocolIEs ProtocolIE-Container { {CN-InvokeTraceIEs} },
+ protocolExtensions ProtocolExtensionContainer { {CN-InvokeTraceExtensions} } OPTIONAL,
+ ...
+}
+
+CN-InvokeTraceIEs RANAP-PROTOCOL-IES ::= {
+ { ID id-TraceType CRITICALITY ignore TYPE TraceType PRESENCE optional } |
+ -- This information is mandatory for GERAN Iu Mode, not applicable to UTRAN --
+ { ID id-TraceReference CRITICALITY ignore TYPE TraceReference PRESENCE mandatory } |
+ { ID id-TriggerID CRITICALITY ignore TYPE TriggerID PRESENCE optional } |
+ -- This information is mandatory for GERAN Iu Mode, not applicable to UTRAN --
+ { ID id-UE-ID CRITICALITY ignore TYPE UE-ID PRESENCE optional } |
+ -- This information is mandatory for UTRAN, optional for GERAN Iu mode --
+ { ID id-OMC-ID CRITICALITY ignore TYPE OMC-ID PRESENCE optional },
+ -- This information is mandatory for GERAN Iu Mode, not applicable to UTRAN --
+ ...
+}
+
+CN-InvokeTraceExtensions RANAP-PROTOCOL-EXTENSION ::= {
+-- Extension for Release 6 to enable signalling based activation for Subscriber and Equipment Trace over Iu interface --
+ { ID id-TracePropagationParameters CRITICALITY ignore EXTENSION TracePropagationParameters PRESENCE optional } ,
+ ...
+}
+
+-- **************************************************************
+--
+-- CN DEACTIVATE TRACE ELEMENTARY PROCEDURE
+--
+-- **************************************************************
+
+-- **************************************************************
+--
+-- CN Deactivate Trace
+--
+-- **************************************************************
+
+CN-DeactivateTrace ::= SEQUENCE {
+ protocolIEs ProtocolIE-Container { {CN-DeactivateTraceIEs} },
+ protocolExtensions ProtocolExtensionContainer { {CN-DeactivateTraceExtensions} } OPTIONAL,
+ ...
+}
+
+CN-DeactivateTraceIEs RANAP-PROTOCOL-IES ::= {
+ { ID id-TraceReference CRITICALITY ignore TYPE TraceReference PRESENCE mandatory } |
+ { ID id-TriggerID CRITICALITY ignore TYPE TriggerID PRESENCE optional },
+ -- This information is optional for GERAN Iu Mode, not applicable to UTRAN --
+ ...
+}
+
+CN-DeactivateTraceExtensions RANAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+-- **************************************************************
+--
+-- LOCATION REPORTING CONTROL ELEMENTARY PROCEDURE
+--
+-- **************************************************************
+
+-- **************************************************************
+--
+-- Location Reporting Control
+--
+-- **************************************************************
+
+LocationReportingControl ::= SEQUENCE {
+ protocolIEs ProtocolIE-Container { {LocationReportingControlIEs} },
+ protocolExtensions ProtocolExtensionContainer { {LocationReportingControlExtensions} } OPTIONAL,
+ ...
+}
+
+LocationReportingControlIEs RANAP-PROTOCOL-IES ::= {
+ { ID id-RequestType CRITICALITY ignore TYPE RequestType PRESENCE mandatory },
+ ...
+}
+
+LocationReportingControlExtensions RANAP-PROTOCOL-EXTENSION ::= {
+-- Extension for Release 4 to enhance the location request over Iu --
+ { ID id-VerticalAccuracyCode CRITICALITY ignore EXTENSION VerticalAccuracyCode PRESENCE optional } |
+-- Extension for Release 4 to enhance the location request over Iu --
+ { ID id-ResponseTime CRITICALITY ignore EXTENSION ResponseTime PRESENCE optional } |
+-- Extension for Release 4 to enhance the location request over Iu --
+ { ID id-PositioningPriority CRITICALITY ignore EXTENSION PositioningPriority PRESENCE optional } |
+-- Extension for Release 4 to enhance the location request over Iu --
+ { ID id-ClientType CRITICALITY ignore EXTENSION ClientType PRESENCE optional } |
+-- Extension for Release 7 to allow the request of velocity over Iu --
+ { ID id-IncludeVelocity CRITICALITY ignore EXTENSION IncludeVelocity PRESENCE optional } |
+-- Extension for Release 7 to allow periodic reporting over Iu --
+ { ID id-PeriodicLocationInfo CRITICALITY ignore EXTENSION PeriodicLocationInfo PRESENCE optional },
+ ...
+}
+
+-- **************************************************************
+--
+-- LOCATION REPORT ELEMENTARY PROCEDURE
+--
+-- **************************************************************
+
+-- **************************************************************
+--
+-- Location Report
+--
+-- **************************************************************
+
+LocationReport ::= SEQUENCE {
+ protocolIEs ProtocolIE-Container { {LocationReportIEs} },
+ protocolExtensions ProtocolExtensionContainer { {LocationReportExtensions} } OPTIONAL,
+ ...
+}
+
+LocationReportIEs RANAP-PROTOCOL-IES ::= {
+ { ID id-AreaIdentity CRITICALITY ignore TYPE AreaIdentity PRESENCE optional } |
+ { ID id-Cause CRITICALITY ignore TYPE Cause PRESENCE optional } |
+ { ID id-RequestType CRITICALITY ignore TYPE RequestType PRESENCE optional } ,
+ ...
+}
+
+LocationReportExtensions RANAP-PROTOCOL-EXTENSION ::= {
+-- Extension for Release 4 to enable report of Last Known Service Area with its Age over Iu --
+ { ID id-LastKnownServiceArea CRITICALITY ignore EXTENSION LastKnownServiceArea PRESENCE optional} |
+-- Extension for Release 5 to pass the positioning methods that have been used --
+ { ID id-PositionData CRITICALITY ignore EXTENSION PositionData PRESENCE optional}|
+-- Extension for Release 5 to pass the positioning methods that have been used for GERAN Iu mode --
+ { ID id-PositionDataSpecificToGERANIuMode CRITICALITY ignore EXTENSION PositionDataSpecificToGERANIuMode PRESENCE optional }|
+ -- This extension is optional for GERAN Iu mode only, not applicable for UTRAN --
+-- Extension for Release 6 to indicate whether the returned position estimate satisfies the requested accuracy or not --
+ { ID id-AccuracyFulfilmentIndicator CRITICALITY ignore EXTENSION AccuracyFulfilmentIndicator PRESENCE optional}|
+-- Extension for Release 7 to provide a velocity estimate --
+ { ID id-VelocityEstimate CRITICALITY ignore EXTENSION VelocityEstimate PRESENCE optional},
+ ...
+}
+
+-- **************************************************************
+--
+-- INITIAL UE MESSAGE ELEMENTARY PROCEDURE
+--
+-- **************************************************************
+
+-- **************************************************************
+--
+-- Initial UE Message
+--
+-- **************************************************************
+
+InitialUE-Message ::= SEQUENCE {
+ protocolIEs ProtocolIE-Container { {InitialUE-MessageIEs} },
+ protocolExtensions ProtocolExtensionContainer { {InitialUE-MessageExtensions} } OPTIONAL,
+ ...
+}
+
+InitialUE-MessageIEs RANAP-PROTOCOL-IES ::= {
+ { ID id-CN-DomainIndicator CRITICALITY ignore TYPE CN-DomainIndicator PRESENCE mandatory } |
+ { ID id-LAI CRITICALITY ignore TYPE LAI PRESENCE mandatory } |
+ { ID id-RAC CRITICALITY ignore TYPE RAC PRESENCE conditional
+ -- This IE shall be present if the CN Domain Indicator IE is set to "PS domain" -- } |
+ { ID id-SAI CRITICALITY ignore TYPE SAI PRESENCE mandatory } |
+ { ID id-NAS-PDU CRITICALITY ignore TYPE NAS-PDU PRESENCE mandatory } |
+ { ID id-IuSigConId CRITICALITY ignore TYPE IuSignallingConnectionIdentifier PRESENCE mandatory } |
+ { ID id-GlobalRNC-ID CRITICALITY ignore TYPE GlobalRNC-ID PRESENCE mandatory },
+ ...
+}
+
+InitialUE-MessageExtensions RANAP-PROTOCOL-EXTENSION ::= {
+-- Extension for Release 5 to enable GERAN support over Iu-cs --
+ { ID id-GERAN-Classmark CRITICALITY ignore EXTENSION GERAN-Classmark PRESENCE optional } |
+-- Extension for Release 6 to convey the selected PLMN id in shared networks --
+ { ID id-SelectedPLMN-ID CRITICALITY ignore EXTENSION PLMNidentity PRESENCE optional } |
+-- Extension for Release 6 to enable rerouting in MOCN configuration for network sharing non-supporting UEs --
+ { ID id-PermanentNAS-UE-ID CRITICALITY ignore EXTENSION PermanentNAS-UE-ID PRESENCE optional } |
+-- Extension for Release 6 to enable rerouting in MOCN configuration for network sharing non-supporting UEs --
+ { ID id-NAS-SequenceNumber CRITICALITY ignore EXTENSION NAS-SequenceNumber PRESENCE optional } |
+-- Extension for Release 6 to indicate rerouting in MOCN configuration for network sharing non-supporting UEs --
+ { ID id-RedirectAttemptFlag CRITICALITY ignore EXTENSION RedirectAttemptFlag PRESENCE optional } |
+-- Extension for Release 7 to indicate extended RNC-ID --
+ { ID id-ExtendedRNC-ID CRITICALITY reject EXTENSION ExtendedRNC-ID PRESENCE optional } |
+-- Extension for Release 8 to support CSG --
+ { ID id-CSG-Id CRITICALITY reject EXTENSION CSG-Id PRESENCE optional },
+ ...
+}
+
+-- **************************************************************
+--
+-- DIRECT TRANSFER ELEMENTARY PROCEDURE
+--
+-- **************************************************************
+
+-- **************************************************************
+--
+-- Direct Transfer
+--
+-- **************************************************************
+
+DirectTransfer ::= SEQUENCE {
+ protocolIEs ProtocolIE-Container { {DirectTransferIEs} },
+ protocolExtensions ProtocolExtensionContainer { {DirectTransferExtensions} } OPTIONAL,
+ ...
+}
+
+DirectTransferIEs RANAP-PROTOCOL-IES ::= {
+ { ID id-NAS-PDU CRITICALITY ignore TYPE NAS-PDU PRESENCE mandatory } |
+ { ID id-LAI CRITICALITY ignore TYPE LAI PRESENCE optional } |
+ { ID id-RAC CRITICALITY ignore TYPE RAC PRESENCE optional } |
+ { ID id-SAI CRITICALITY ignore TYPE SAI PRESENCE optional } |
+ { ID id-SAPI CRITICALITY ignore TYPE SAPI PRESENCE optional },
+ ...
+}
+
+DirectTransferExtensions RANAP-PROTOCOL-EXTENSION ::= {
+-- Extension for Release 6 to enable rerouting in MOCN configuration for network sharing non-supporting UEs --
+ { ID id-RedirectionIndication CRITICALITY ignore EXTENSION RedirectionIndication PRESENCE optional }|
+-- Extension for Release 6 to indicate the MOCN rerouting is completed --
+ { ID id-RedirectionCompleted CRITICALITY ignore EXTENSION RedirectionCompleted PRESENCE optional }|
+-- Extension for Release 8 to indicate the Subscriber Profile ID for RAT/Frequency Selection Priority --
+ {ID id-SubscriberProfileIDforRFP CRITICALITY ignore EXTENSION SubscriberProfileIDforRFP PRESENCE optional},
+ ...
+}
+
+RedirectionIndication ::= ProtocolIE-Container { {RedirectionIndication-IEs} }
+
+RedirectionIndication-IEs RANAP-PROTOCOL-IES ::= {
+ { ID id-NAS-PDU CRITICALITY ignore TYPE NAS-PDU PRESENCE mandatory }|
+ { ID id-RejectCauseValue CRITICALITY ignore TYPE RejectCauseValue PRESENCE mandatory}|
+ { ID id-NAS-SequenceNumber CRITICALITY ignore TYPE NAS-SequenceNumber PRESENCE optional}|
+ { ID id-PermanentNAS-UE-ID CRITICALITY ignore TYPE PermanentNAS-UE-ID PRESENCE optional},
+ ...
+}
+
+-- **************************************************************
+--
+-- OVERLOAD CONTROL ELEMENTARY PROCEDURE
+--
+-- **************************************************************
+
+-- **************************************************************
+--
+-- Overload
+--
+-- **************************************************************
+
+Overload ::= SEQUENCE {
+ protocolIEs ProtocolIE-Container { {OverloadIEs} },
+ protocolExtensions ProtocolExtensionContainer { {OverloadExtensions} } OPTIONAL,
+ ...
+}
+
+OverloadIEs RANAP-PROTOCOL-IES ::= {
+ { ID id-NumberOfSteps CRITICALITY ignore TYPE NumberOfSteps PRESENCE optional } |
+ { ID id-GlobalRNC-ID CRITICALITY ignore TYPE GlobalRNC-ID PRESENCE optional },
+ ...
+}
+
+OverloadExtensions RANAP-PROTOCOL-EXTENSION ::= {
+-- Extension for Release 99 to enable the indication to the RNC which CN domain is suffering the signalling traffic overload --
+ { ID id-CN-DomainIndicator CRITICALITY ignore EXTENSION CN-DomainIndicator PRESENCE optional } |
+-- Extension for Release 5 to enable NNSF --
+ { ID id-GlobalCN-ID CRITICALITY ignore EXTENSION GlobalCN-ID PRESENCE optional } |
+-- Extension for Release 7 to indicate extended RNC-ID --
+ { ID id-ExtendedRNC-ID CRITICALITY reject EXTENSION ExtendedRNC-ID PRESENCE optional },
+ ...
+}
+
+-- **************************************************************
+--
+-- ERROR INDICATION ELEMENTARY PROCEDURE
+--
+-- **************************************************************
+
+-- **************************************************************
+--
+-- Error Indication
+--
+-- **************************************************************
+
+ErrorIndication ::= SEQUENCE {
+ protocolIEs ProtocolIE-Container { {ErrorIndicationIEs} },
+ protocolExtensions ProtocolExtensionContainer { {ErrorIndicationExtensions} } OPTIONAL,
+ ...
+}
+
+ErrorIndicationIEs RANAP-PROTOCOL-IES ::= {
+ { ID id-Cause CRITICALITY ignore TYPE Cause PRESENCE optional } |
+ { ID id-CriticalityDiagnostics CRITICALITY ignore TYPE CriticalityDiagnostics PRESENCE optional } |
+ { ID id-CN-DomainIndicator CRITICALITY ignore TYPE CN-DomainIndicator PRESENCE optional } |
+ { ID id-GlobalRNC-ID CRITICALITY ignore TYPE GlobalRNC-ID PRESENCE optional },
+ ...
+}
+
+ErrorIndicationExtensions RANAP-PROTOCOL-EXTENSION ::= {
+-- Extension for Release 4 --
+ { ID id-GlobalCN-ID CRITICALITY ignore EXTENSION GlobalCN-ID PRESENCE optional}|
+-- Extension for Release 7 to indicate extended RNC-ID --
+ { ID id-ExtendedRNC-ID CRITICALITY reject EXTENSION ExtendedRNC-ID PRESENCE optional },
+ ...
+}
+
+-- **************************************************************
+--
+-- SRNS DATA FORWARD ELEMENTARY PROCEDURE
+--
+-- **************************************************************
+
+-- **************************************************************
+--
+-- SRNS Data Forward Command
+--
+-- **************************************************************
+
+SRNS-DataForwardCommand ::= SEQUENCE {
+ protocolIEs ProtocolIE-Container { {SRNS-DataForwardCommandIEs} },
+ protocolExtensions ProtocolExtensionContainer { {SRNS-DataForwardCommandExtensions} } OPTIONAL,
+ ...
+}
+
+SRNS-DataForwardCommandIEs RANAP-PROTOCOL-IES ::= {
+ { ID id-RAB-DataForwardingList CRITICALITY ignore TYPE RAB-DataForwardingList PRESENCE optional },
+ ...
+}
+
+SRNS-DataForwardCommandExtensions RANAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+-- **************************************************************
+--
+-- FORWARD SRNS CONTEXT ELEMENTARY PROCEDURE
+--
+-- **************************************************************
+
+-- **************************************************************
+--
+-- Forward SRNS Context
+--
+-- **************************************************************
+
+ForwardSRNS-Context ::= SEQUENCE {
+ protocolIEs ProtocolIE-Container { {ForwardSRNS-ContextIEs} },
+ protocolExtensions ProtocolExtensionContainer { {ForwardSRNS-ContextExtensions} } OPTIONAL,
+ ...
+}
+
+ForwardSRNS-ContextIEs RANAP-PROTOCOL-IES ::= {
+ { ID id-RAB-ContextList CRITICALITY ignore TYPE RAB-ContextList PRESENCE mandatory },
+ ...
+}
+
+ForwardSRNS-ContextExtensions RANAP-PROTOCOL-EXTENSION ::= {
+-- Extension for Release 5 to enable relocation of Source RNC PDCP context info --
+ { ID id-SourceRNC-PDCP-context-info CRITICALITY ignore EXTENSION RRC-Container PRESENCE optional},
+ ...
+}
+
+-- **************************************************************
+--
+-- RAB ASSIGNMENT ELEMENTARY PROCEDURE
+--
+-- **************************************************************
+
+-- **************************************************************
+--
+-- RAB Assignment Request
+--
+-- **************************************************************
+
+RAB-AssignmentRequest ::= SEQUENCE {
+ protocolIEs ProtocolIE-Container { {RAB-AssignmentRequestIEs} },
+ protocolExtensions ProtocolExtensionContainer { {RAB-AssignmentRequestExtensions} } OPTIONAL,
+ ...
+}
+
+RAB-AssignmentRequestIEs RANAP-PROTOCOL-IES ::= {
+ { ID id-RAB-SetupOrModifyList CRITICALITY ignore TYPE RAB-SetupOrModifyList PRESENCE optional } |
+ { ID id-RAB-ReleaseList CRITICALITY ignore TYPE RAB-ReleaseList PRESENCE optional },
+ ...
+}
+
+RAB-SetupOrModifyList ::= RAB-IE-ContainerPairList { {RAB-SetupOrModifyItem-IEs} }
+
+RAB-SetupOrModifyItem-IEs RANAP-PROTOCOL-IES-PAIR ::= {
+ { ID id-RAB-SetupOrModifyItem FIRST CRITICALITY reject FIRST TYPE RAB-SetupOrModifyItemFirst
+ SECOND CRITICALITY ignore SECOND TYPE RAB-SetupOrModifyItemSecond
+ PRESENCE mandatory },
+ ...
+}
+
+RAB-SetupOrModifyItemFirst ::= SEQUENCE {
+ rAB-ID RAB-ID,
+ nAS-SynchronisationIndicator NAS-SynchronisationIndicator OPTIONAL,
+ rAB-Parameters RAB-Parameters OPTIONAL,
+ userPlaneInformation UserPlaneInformation OPTIONAL,
+ transportLayerInformation TransportLayerInformation OPTIONAL,
+ service-Handover Service-Handover OPTIONAL,
+ iE-Extensions ProtocolExtensionContainer { {RAB-SetupOrModifyItemFirst-ExtIEs} } OPTIONAL,
+ ...
+}
+
+TransportLayerInformation ::= SEQUENCE {
+ transportLayerAddress TransportLayerAddress,
+ iuTransportAssociation IuTransportAssociation,
+ iE-Extensions ProtocolExtensionContainer { {TransportLayerInformation-ExtIEs} } OPTIONAL,
+ ...
+}
+
+TransportLayerInformation-ExtIEs RANAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+RAB-SetupOrModifyItemFirst-ExtIEs RANAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+RAB-SetupOrModifyItemSecond ::= SEQUENCE {
+ pDP-TypeInformation PDP-TypeInformation OPTIONAL,
+ dataVolumeReportingIndication DataVolumeReportingIndication OPTIONAL,
+ dl-GTP-PDU-SequenceNumber DL-GTP-PDU-SequenceNumber OPTIONAL,
+ ul-GTP-PDU-SequenceNumber UL-GTP-PDU-SequenceNumber OPTIONAL,
+ dl-N-PDU-SequenceNumber DL-N-PDU-SequenceNumber OPTIONAL,
+ ul-N-PDU-SequenceNumber UL-N-PDU-SequenceNumber OPTIONAL,
+ iE-Extensions ProtocolExtensionContainer { {RAB-SetupOrModifyItemSecond-ExtIEs} } OPTIONAL,
+ ...
+}
+
+RAB-SetupOrModifyItemSecond-ExtIEs RANAP-PROTOCOL-EXTENSION ::= {
+-- Extension for Release 4 to enable RAB Quality of Service negotiation over Iu --
+ { ID id-Alt-RAB-Parameters CRITICALITY ignore EXTENSION Alt-RAB-Parameters PRESENCE optional } |
+-- Extension for Release 5 to enable GERAN support over Iu-cs --
+ { ID id-GERAN-BSC-Container CRITICALITY ignore EXTENSION GERAN-BSC-Container PRESENCE optional } ,
+ ...
+}
+
+RAB-AssignmentRequestExtensions RANAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+-- **************************************************************
+--
+-- RAB Assignment Response
+--
+-- **************************************************************
+
+RAB-AssignmentResponse ::= SEQUENCE {
+ protocolIEs ProtocolIE-Container { {RAB-AssignmentResponseIEs} },
+ protocolExtensions ProtocolExtensionContainer { {RAB-AssignmentResponseExtensions} } OPTIONAL,
+ ...
+}
+
+RAB-AssignmentResponseIEs RANAP-PROTOCOL-IES ::= {
+ { ID id-RAB-SetupOrModifiedList CRITICALITY ignore TYPE RAB-SetupOrModifiedList PRESENCE optional } |
+ { ID id-RAB-ReleasedList CRITICALITY ignore TYPE RAB-ReleasedList PRESENCE optional } |
+
+ { ID id-RAB-QueuedList CRITICALITY ignore TYPE RAB-QueuedList PRESENCE optional } |
+ { ID id-RAB-FailedList CRITICALITY ignore TYPE RAB-FailedList PRESENCE optional } |
+ { ID id-RAB-ReleaseFailedList CRITICALITY ignore TYPE RAB-ReleaseFailedList PRESENCE optional } |
+ { ID id-CriticalityDiagnostics CRITICALITY ignore TYPE CriticalityDiagnostics PRESENCE optional },
+ ...
+}
+
+RAB-SetupOrModifiedList ::= RAB-IE-ContainerList { {RAB-SetupOrModifiedItemIEs} }
+
+RAB-SetupOrModifiedItemIEs RANAP-PROTOCOL-IES ::= {
+ { ID id-RAB-SetupOrModifiedItem CRITICALITY ignore TYPE RAB-SetupOrModifiedItem PRESENCE mandatory },
+ ...
+}
+
+RAB-SetupOrModifiedItem ::= SEQUENCE {
+ rAB-ID RAB-ID,
+ transportLayerAddress TransportLayerAddress OPTIONAL,
+ iuTransportAssociation IuTransportAssociation OPTIONAL,
+ dl-dataVolumes DataVolumeList OPTIONAL,
+ iE-Extensions ProtocolExtensionContainer { {RAB-SetupOrModifiedItem-ExtIEs} } OPTIONAL,
+ ...
+}
+
+RAB-SetupOrModifiedItem-ExtIEs RANAP-PROTOCOL-EXTENSION ::= {
+-- Extension for Release 4 to enable RAB Quality of Service negotiation over Iu --
+ { ID id-Ass-RAB-Parameters CRITICALITY ignore EXTENSION Ass-RAB-Parameters PRESENCE optional },
+ ...
+}
+
+RAB-ReleasedList ::= RAB-IE-ContainerList { {RAB-ReleasedItemIEs} }
+
+RAB-ReleasedItemIEs RANAP-PROTOCOL-IES ::= {
+ { ID id-RAB-ReleasedItem CRITICALITY ignore TYPE RAB-ReleasedItem PRESENCE mandatory },
+ ...
+}
+
+RAB-ReleasedItem ::= SEQUENCE {
+ rAB-ID RAB-ID,
+ dl-dataVolumes DataVolumeList OPTIONAL,
+ dL-GTP-PDU-SequenceNumber DL-GTP-PDU-SequenceNumber OPTIONAL,
+ uL-GTP-PDU-SequenceNumber UL-GTP-PDU-SequenceNumber OPTIONAL,
+ iE-Extensions ProtocolExtensionContainer { {RAB-ReleasedItem-ExtIEs} } OPTIONAL,
+ ...
+}
+
+RAB-ReleasedItem-ExtIEs RANAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+DataVolumeList ::= SEQUENCE (SIZE (1..maxNrOfVol)) OF
+ SEQUENCE {
+ dl-UnsuccessfullyTransmittedDataVolume UnsuccessfullyTransmittedDataVolume,
+ dataVolumeReference DataVolumeReference OPTIONAL,
+ iE-Extensions ProtocolExtensionContainer { {DataVolumeList-ExtIEs} } OPTIONAL,
+ ...
+ }
+
+DataVolumeList-ExtIEs RANAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+RAB-QueuedList ::= RAB-IE-ContainerList { {RAB-QueuedItemIEs} }
+
+RAB-QueuedItemIEs RANAP-PROTOCOL-IES ::= {
+ { ID id-RAB-QueuedItem CRITICALITY ignore TYPE RAB-QueuedItem PRESENCE mandatory },
+ ...
+}
+
+RAB-QueuedItem ::= SEQUENCE {
+ rAB-ID RAB-ID,
+ iE-Extensions ProtocolExtensionContainer { {RAB-QueuedItem-ExtIEs} } OPTIONAL,
+ ...
+}
+
+RAB-QueuedItem-ExtIEs RANAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+RAB-ReleaseFailedList ::= RAB-FailedList
+
+RAB-AssignmentResponseExtensions RANAP-PROTOCOL-EXTENSION ::= {
+-- Extension for Release 5 to enable GERAN support over Iu-cs --
+ { ID id-GERAN-Iumode-RAB-FailedList-RABAssgntResponse CRITICALITY ignore EXTENSION GERAN-Iumode-RAB-FailedList-RABAssgntResponse PRESENCE optional} ,
+ ...
+}
+
+GERAN-Iumode-RAB-FailedList-RABAssgntResponse ::= RAB-IE-ContainerList { {GERAN-Iumode-RAB-Failed-RABAssgntResponse-ItemIEs} }
+
+GERAN-Iumode-RAB-Failed-RABAssgntResponse-ItemIEs RANAP-PROTOCOL-IES ::= {
+ { ID id-GERAN-Iumode-RAB-Failed-RABAssgntResponse-Item CRITICALITY ignore TYPE GERAN-Iumode-RAB-Failed-RABAssgntResponse-Item PRESENCE mandatory },
+ ...
+}
+
+GERAN-Iumode-RAB-Failed-RABAssgntResponse-Item ::= SEQUENCE {
+ rAB-ID RAB-ID,
+ cause Cause,
+ gERAN-Classmark GERAN-Classmark OPTIONAL,
+ iE-Extensions ProtocolExtensionContainer { {GERAN-Iumode-RAB-Failed-RABAssgntResponse-Item-ExtIEs} } OPTIONAL,
+ ...
+}
+
+GERAN-Iumode-RAB-Failed-RABAssgntResponse-Item-ExtIEs RANAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+-- **************************************************************
+--
+-- PRIVATE MESSAGE
+--
+-- **************************************************************
+
+PrivateMessage ::= SEQUENCE {
+ privateIEs PrivateIE-Container { {PrivateMessage-IEs } },
+ ...
+}
+
+PrivateMessage-IEs RANAP-PRIVATE-IES ::= {
+ ...
+}
+
+-- **************************************************************
+--
+-- RANAP RELOCATION INFORMATION ELEMENTARY PROCEDURE
+--
+-- **************************************************************
+
+RANAP-RelocationInformation ::= SEQUENCE {
+ protocolIEs ProtocolIE-Container { {RANAP-RelocationInformationIEs} },
+ protocolExtensions ProtocolExtensionContainer { {RANAP-RelocationInformationExtensions} } OPTIONAL,
+ ...
+}
+
+RANAP-RelocationInformationIEs RANAP-PROTOCOL-IES ::= {
+ { ID id-DirectTransferInformationList-RANAP-RelocInf
+ CRITICALITY ignore TYPE DirectTransferInformationList-RANAP-RelocInf
+ PRESENCE optional } |
+ { ID id-RAB-ContextList-RANAP-RelocInf CRITICALITY ignore TYPE RAB-ContextList-RANAP-RelocInf PRESENCE optional },
+ ...
+}
+
+DirectTransferInformationList-RANAP-RelocInf ::= DirectTransfer-IE-ContainerList { {DirectTransferInformationItemIEs-RANAP-RelocInf} }
+
+DirectTransferInformationItemIEs-RANAP-RelocInf RANAP-PROTOCOL-IES ::= {
+ { ID id-DirectTransferInformationItem-RANAP-RelocInf
+ CRITICALITY ignore TYPE DirectTransferInformationItem-RANAP-RelocInf
+ PRESENCE mandatory },
+ ...
+}
+
+DirectTransferInformationItem-RANAP-RelocInf ::= SEQUENCE {
+ nAS-PDU NAS-PDU,
+ sAPI SAPI,
+ cN-DomainIndicator CN-DomainIndicator,
+ iE-Extensions ProtocolExtensionContainer { {RANAP-DirectTransferInformationItem-ExtIEs-RANAP-RelocInf} } OPTIONAL,
+ ...
+}
+
+RANAP-DirectTransferInformationItem-ExtIEs-RANAP-RelocInf RANAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+RAB-ContextList-RANAP-RelocInf ::= RAB-IE-ContainerList { {RAB-ContextItemIEs-RANAP-RelocInf} }
+
+RAB-ContextItemIEs-RANAP-RelocInf RANAP-PROTOCOL-IES ::= {
+ { ID id-RAB-ContextItem-RANAP-RelocInf CRITICALITY ignore TYPE RAB-ContextItem-RANAP-RelocInf PRESENCE mandatory },
+ ...
+}
+
+RAB-ContextItem-RANAP-RelocInf ::= SEQUENCE {
+ rAB-ID RAB-ID,
+ dl-GTP-PDU-SequenceNumber DL-GTP-PDU-SequenceNumber OPTIONAL,
+ ul-GTP-PDU-SequenceNumber UL-GTP-PDU-SequenceNumber OPTIONAL,
+ dl-N-PDU-SequenceNumber DL-N-PDU-SequenceNumber OPTIONAL,
+ ul-N-PDU-SequenceNumber UL-N-PDU-SequenceNumber OPTIONAL,
+ iE-Extensions ProtocolExtensionContainer { {RAB-ContextItem-ExtIEs-RANAP-RelocInf} } OPTIONAL,
+ ...
+}
+
+RAB-ContextItem-ExtIEs-RANAP-RelocInf RANAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+RANAP-RelocationInformationExtensions RANAP-PROTOCOL-EXTENSION ::= {
+-- Extension for Release 5 to enable relocation of Source RNC PDCP context info --
+ { ID id-SourceRNC-PDCP-context-info CRITICALITY ignore EXTENSION RRC-Container PRESENCE optional},
+ ...
+}
+
+-- **************************************************************
+--
+-- RANAP ENHANCED RELOCATION INFORMATION ELEMENTARY PROCEDURE
+--
+-- **************************************************************
+
+-- **************************************************************
+--
+-- RANAP Enhanced Relocation Information Request
+--
+-- **************************************************************
+
+RANAP-EnhancedRelocationInformationRequest ::= SEQUENCE {
+ protocolIEs ProtocolIE-Container { {RANAP-EnhancedRelocationInformationRequestIEs} },
+ protocolExtensions ProtocolExtensionContainer { {RANAP-EnhancedRelocationInformationRequestExtensions} } OPTIONAL,
+ ...
+}
+
+RANAP-EnhancedRelocationInformationRequestIEs RANAP-PROTOCOL-IES ::= {
+ { ID id-Source-ToTarget-TransparentContainer
+ CRITICALITY reject TYPE SourceRNC-ToTargetRNC-TransparentContainer PRESENCE mandatory } |
+ { ID id-OldIuSigConIdCS CRITICALITY ignore TYPE IuSignallingConnectionIdentifier PRESENCE optional } |
+ { ID id-GlobalCN-IDCS CRITICALITY reject TYPE GlobalCN-ID PRESENCE optional} |
+ { ID id-OldIuSigConIdPS CRITICALITY ignore TYPE IuSignallingConnectionIdentifier PRESENCE optional } |
+ { ID id-GlobalCN-IDCS CRITICALITY reject TYPE GlobalCN-ID PRESENCE optional} |
+ { ID id-RAB-SetupList-EnhRelocInfoReq CRITICALITY reject TYPE RAB-SetupList-EnhRelocInfoReq PRESENCE optional } |
+ { ID id-SNA-Access-Information CRITICALITY ignore TYPE SNA-Access-Information PRESENCE optional} |
+ { ID id-UESBI-Iu CRITICALITY ignore TYPE UESBI-Iu PRESENCE optional}|
+ { ID id-SelectedPLMN-ID CRITICALITY ignore TYPE PLMNidentity PRESENCE optional }|
+ { ID id-CNMBMSLinkingInformation CRITICALITY ignore TYPE CNMBMSLinkingInformation PRESENCE optional},
+ ...
+}
+
+RAB-SetupList-EnhRelocInfoReq ::= RAB-IE-ContainerList { { RAB-SetupItem-EnhRelocInfoReq-IEs} }
+
+RAB-SetupItem-EnhRelocInfoReq-IEs RANAP-PROTOCOL-IES ::= {
+ { ID id-RAB-SetupItem-EnhRelocInfoReq CRITICALITY reject TYPE RAB-SetupItem-EnhRelocInfoReq PRESENCE mandatory },
+ ...
+}
+
+RAB-SetupItem-EnhRelocInfoReq ::= SEQUENCE {
+ rAB-ID RAB-ID,
+ cN-DomainIndicator CN-DomainIndicator,
+ rAB-Parameters RAB-Parameters,
+ dataVolumeReportingIndication DataVolumeReportingIndication OPTIONAL
+ -- This IE shall be present if the CN domain indicator IE is set to "PS domain" --,
+ pDP-TypeInformation PDP-TypeInformation OPTIONAL
+ -- This IE shall be present if the CN domain indicator IE is set to "PS domain" --,
+ userPlaneInformation UserPlaneInformation,
+ dataForwardingInformation TNLInformationEnhRelInfoReq OPTIONAL,
+ sourceSideIuULTNLInfo TNLInformationEnhRelInfoReq OPTIONAL,
+
+ service-Handover Service-Handover OPTIONAL,
+ alt-RAB-Parameters Alt-RAB-Parameters OPTIONAL,
+ iE-Extensions ProtocolExtensionContainer { { RAB-SetupItem-EnhRelocInfoReq-ExtIEs} } OPTIONAL,
+ ...
+}
+
+RAB-SetupItem-EnhRelocInfoReq-ExtIEs RANAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+TNLInformationEnhRelInfoReq ::=SEQUENCE{
+ transportLayerAddress TransportLayerAddress,
+ iuTransportAssociation IuTransportAssociation,
+ iE-Extensions ProtocolExtensionContainer { { TNLInformationEnhRelInfoReq-ExtIEs} } OPTIONAL,
+ ...
+}
+
+TNLInformationEnhRelInfoReq-ExtIEs RANAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+
+RANAP-EnhancedRelocationInformationRequestExtensions RANAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+-- **************************************************************
+--
+-- RANAP Enhanced Relocation Information Response
+--
+-- **************************************************************
+
+RANAP-EnhancedRelocationInformationResponse ::= SEQUENCE {
+ protocolIEs ProtocolIE-Container { {RANAP-EnhancedRelocationInformationResponseIEs} },
+ protocolExtensions ProtocolExtensionContainer { {RANAP-EnhancedRelocationInformationResponseExtensions} } OPTIONAL,
+ ...
+}
+
+RANAP-EnhancedRelocationInformationResponseIEs RANAP-PROTOCOL-IES ::= {
+ { ID id-Target-ToSource-TransparentContainer
+ CRITICALITY ignore TYPE TargetRNC-ToSourceRNC-TransparentContainer PRESENCE optional } |
+ { ID id-RAB-SetupList-EnhRelocInfoRes CRITICALITY ignore TYPE RAB-SetupList-EnhRelocInfoRes PRESENCE optional} |
+ { ID id-RAB-FailedList-EnhRelocInfoRes CRITICALITY ignore TYPE RAB-FailedList-EnhRelocInfoRes PRESENCE optional }|
+ { ID id-CriticalityDiagnostics CRITICALITY ignore TYPE CriticalityDiagnostics PRESENCE optional },
+ ...
+}
+
+RAB-SetupList-EnhRelocInfoRes ::= RAB-IE-ContainerList { { RAB-SetupItem-EnhRelocInfoRes-IEs} }
+
+RAB-SetupItem-EnhRelocInfoRes-IEs RANAP-PROTOCOL-IES ::= {
+ { ID id-RAB-SetupItem-EnhRelocInfoRes CRITICALITY reject TYPE RAB-SetupItem-EnhRelocInfoRes PRESENCE mandatory },
+ ...
+}
+
+RAB-SetupItem-EnhRelocInfoRes ::= SEQUENCE {
+ cN-DomainIndicator CN-DomainIndicator,
+ rAB-ID RAB-ID,
+ dataForwardingInformation TNLInformationEnhRelInfoRes OPTIONAL,
+ ass-RAB-Parameters Ass-RAB-Parameters OPTIONAL,
+ iE-Extensions ProtocolExtensionContainer { { RAB-SetupItem-EnhRelocInfoRes-ExtIEs} } OPTIONAL,
+ ...
+}
+
+RAB-SetupItem-EnhRelocInfoRes-ExtIEs RANAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+RAB-FailedList-EnhRelocInfoRes ::= RAB-IE-ContainerList { { RAB-FailedItem-EnhRelocInfoRes-IEs} }
+
+RAB-FailedItem-EnhRelocInfoRes-IEs RANAP-PROTOCOL-IES ::= {
+ { ID id-RAB-FailedItem-EnhRelocInfoRes CRITICALITY reject TYPE RAB-FailedItem-EnhRelocInfoRes PRESENCE mandatory },
+ ...
+}
+
+RAB-FailedItem-EnhRelocInfoRes ::= SEQUENCE {
+ cN-DomainIndicator CN-DomainIndicator,
+ rAB-ID RAB-ID,
+ cause Cause,
+ iE-Extensions ProtocolExtensionContainer { { RAB-FailedItem-EnhRelocInfoRes-ExtIEs} } OPTIONAL,
+ ...
+}
+
+RAB-FailedItem-EnhRelocInfoRes-ExtIEs RANAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+TNLInformationEnhRelInfoRes ::=SEQUENCE{
+ dl-forwardingTransportLayerAddress TransportLayerAddress,
+ dl-forwardingTransportAssociation IuTransportAssociation,
+ iE-Extensions ProtocolExtensionContainer { { TNLInformationEnhRelInfoRes-ExtIEs} } OPTIONAL,
+ ...
+}
+
+TNLInformationEnhRelInfoRes-ExtIEs RANAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+RANAP-EnhancedRelocationInformationResponseExtensions RANAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+-- **************************************************************
+--
+-- RAB MODIFICATION REQUEST ELEMENTARY PROCEDURE
+--
+-- **************************************************************
+
+-- **************************************************************
+--
+-- RAB Modify Request
+--
+-- **************************************************************
+
+RAB-ModifyRequest ::= SEQUENCE {
+ protocolIEs ProtocolIE-Container { {RAB-ModifyRequestIEs} },
+ protocolExtensions ProtocolExtensionContainer { {RAB-ModifyRequestExtensions} } OPTIONAL,
+ ...
+}
+
+RAB-ModifyRequestIEs RANAP-PROTOCOL-IES ::= {
+ { ID id-RAB-ModifyList CRITICALITY ignore TYPE RAB-ModifyList PRESENCE mandatory},
+ ...
+}
+
+RAB-ModifyList ::= RAB-IE-ContainerList { {RAB-ModifyItemIEs} }
+
+RAB-ModifyItemIEs RANAP-PROTOCOL-IES ::= {
+ { ID id-RAB-ModifyItem CRITICALITY ignore TYPE RAB-ModifyItem PRESENCE mandatory },
+ ...
+}
+
+RAB-ModifyItem ::= SEQUENCE {
+ rAB-ID RAB-ID,
+ requested-RAB-Parameter-Values Requested-RAB-Parameter-Values,
+ iE-Extensions ProtocolExtensionContainer { {RAB-ModifyItem-ExtIEs} } OPTIONAL,
+ ...
+}
+
+RAB-ModifyItem-ExtIEs RANAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+RAB-ModifyRequestExtensions RANAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+-- **************************************************************
+--
+-- LOCATION RELATED DATA ELEMENTARY PROCEDURE
+--
+-- **************************************************************
+
+-- **************************************************************
+--
+-- Location Related Data Request
+--
+-- **************************************************************
+
+LocationRelatedDataRequest ::= SEQUENCE {
+ protocolIEs ProtocolIE-Container { {LocationRelatedDataRequestIEs} },
+ protocolExtensions ProtocolExtensionContainer { {LocationRelatedDataRequestExtensions} } OPTIONAL,
+ ...
+}
+
+LocationRelatedDataRequestIEs RANAP-PROTOCOL-IES ::= {
+ { ID id-LocationRelatedDataRequestType CRITICALITY reject TYPE LocationRelatedDataRequestType PRESENCE optional },
+ -- This IE is mandatory for UTRAN, optional for GERAN Iu Mode �-
+ ...
+}
+
+LocationRelatedDataRequestExtensions RANAP-PROTOCOL-EXTENSION ::= {
+-- Extension for Release 5 to enable LCS support for GERAN Iu mode --
+ { ID id-LocationRelatedDataRequestTypeSpecificToGERANIuMode CRITICALITY reject EXTENSION LocationRelatedDataRequestTypeSpecificToGERANIuMode PRESENCE optional }|
+ -- The previous extension is optional for GERAN Iu Mode only, not applicable for UTRAN --
+ -- Extension for Release 7 to request GANSS Assistance Data. This IE shall be present if the Requested Location Related Data Type IE is set to
+ -- �Dedicated Assistance Data for Assisted GANSS� or `Dedicated Assistance Data for Assisted GPS and GANSS�--
+ { ID id-RequestedGANSSAssistanceData CRITICALITY reject EXTENSION RequestedGANSSAssistanceData PRESENCE conditional },
+ ...
+}
+
+-- **************************************************************
+--
+-- Location Related Data Response
+--
+-- **************************************************************
+
+LocationRelatedDataResponse ::= SEQUENCE {
+ protocolIEs ProtocolIE-Container { { LocationRelatedDataResponseIEs} },
+ protocolExtensions ProtocolExtensionContainer { { LocationRelatedDataResponseExtensions} } OPTIONAL,
+ ...
+}
+
+LocationRelatedDataResponseIEs RANAP-PROTOCOL-IES ::= {
+ { ID id-BroadcastAssistanceDataDecipheringKeys CRITICALITY ignore TYPE BroadcastAssistanceDataDecipheringKeys PRESENCE optional },
+ ...
+}
+
+LocationRelatedDataResponseExtensions RANAP-PROTOCOL-EXTENSION ::= {
+-- Extension for error handling
+ { ID id-CriticalityDiagnostics CRITICALITY ignore EXTENSION CriticalityDiagnostics PRESENCE optional }|
+ { ID id-BroadcastGANSSAssistanceDataDecipheringKeys CRITICALITY ignore EXTENSION BroadcastAssistanceDataDecipheringKeys PRESENCE optional},
+ ...
+}
+
+-- **************************************************************
+--
+-- Location Related Data Failure
+--
+-- **************************************************************
+
+LocationRelatedDataFailure ::= SEQUENCE {
+ protocolIEs ProtocolIE-Container { { LocationRelatedDataFailureIEs} },
+ protocolExtensions ProtocolExtensionContainer { { LocationRelatedDataFailureExtensions} } OPTIONAL,
+ ...
+}
+
+LocationRelatedDataFailureIEs RANAP-PROTOCOL-IES ::= {
+ { ID id-Cause CRITICALITY ignore TYPE Cause PRESENCE mandatory },
+ ...
+}
+
+LocationRelatedDataFailureExtensions RANAP-PROTOCOL-EXTENSION ::= {
+-- Extension for error handling
+ { ID id-CriticalityDiagnostics CRITICALITY ignore EXTENSION CriticalityDiagnostics PRESENCE optional },
+ ...
+}
+
+-- **************************************************************
+--
+-- INFORMATION TRANSFER ELEMENTARY PROCEDURE
+--
+-- **************************************************************
+
+-- **************************************************************
+--
+-- Information Transfer Indication
+--
+-- **************************************************************
+
+InformationTransferIndication ::= SEQUENCE {
+ protocolIEs ProtocolIE-Container { { InformationTransferIndicationIEs} },
+ protocolExtensions ProtocolExtensionContainer { { InformationTransferIndicationExtensions} } OPTIONAL,
+ ...
+}
+
+InformationTransferIndicationIEs RANAP-PROTOCOL-IES ::= {
+ { ID id-InformationTransferID CRITICALITY reject TYPE InformationTransferID PRESENCE mandatory } |
+ { ID id-ProvidedData CRITICALITY reject TYPE ProvidedData PRESENCE mandatory } |
+ { ID id-CN-DomainIndicator CRITICALITY reject TYPE CN-DomainIndicator PRESENCE mandatory } |
+ { ID id-GlobalCN-ID CRITICALITY ignore TYPE GlobalCN-ID PRESENCE optional},
+ ...
+}
+
+InformationTransferIndicationExtensions RANAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+-- **************************************************************
+--
+-- Information Transfer Confirmation
+--
+-- **************************************************************
+
+InformationTransferConfirmation ::= SEQUENCE {
+ protocolIEs ProtocolIE-Container { { InformationTransferConfirmationIEs} },
+ protocolExtensions ProtocolExtensionContainer { { InformationTransferConfirmationExtensions} } OPTIONAL,
+ ...
+}
+
+InformationTransferConfirmationIEs RANAP-PROTOCOL-IES ::= {
+ { ID id-InformationTransferID CRITICALITY ignore TYPE InformationTransferID PRESENCE mandatory } |
+ { ID id-CN-DomainIndicator CRITICALITY ignore TYPE CN-DomainIndicator PRESENCE mandatory } |
+ { ID id-CriticalityDiagnostics CRITICALITY ignore TYPE CriticalityDiagnostics PRESENCE optional } |
+ { ID id-GlobalRNC-ID CRITICALITY ignore TYPE GlobalRNC-ID PRESENCE mandatory },
+ ...
+}
+
+InformationTransferConfirmationExtensions RANAP-PROTOCOL-EXTENSION ::= {
+-- Extension for Release 7 to indicate extended RNC-ID --
+ { ID id-ExtendedRNC-ID CRITICALITY reject EXTENSION ExtendedRNC-ID PRESENCE optional },
+ ...
+}
+
+-- **************************************************************
+--
+-- Information Transfer Failure
+--
+-- **************************************************************
+
+InformationTransferFailure ::= SEQUENCE {
+ protocolIEs ProtocolIE-Container { { InformationTransferFailureIEs} },
+ protocolExtensions ProtocolExtensionContainer { { InformationTransferFailureExtensions} } OPTIONAL,
+ ...
+}
+
+InformationTransferFailureIEs RANAP-PROTOCOL-IES ::= {
+ { ID id-InformationTransferID CRITICALITY ignore TYPE InformationTransferID PRESENCE mandatory } |
+ { ID id-CN-DomainIndicator CRITICALITY ignore TYPE CN-DomainIndicator PRESENCE mandatory } |
+ { ID id-Cause CRITICALITY ignore TYPE Cause PRESENCE mandatory } |
+ { ID id-CriticalityDiagnostics CRITICALITY ignore TYPE CriticalityDiagnostics PRESENCE optional } |
+ { ID id-GlobalRNC-ID CRITICALITY ignore TYPE GlobalRNC-ID PRESENCE mandatory },
+ ...
+}
+
+InformationTransferFailureExtensions RANAP-PROTOCOL-EXTENSION ::= {
+-- Extension for Release 7 to indicate extended RNC-ID --
+ { ID id-ExtendedRNC-ID CRITICALITY reject EXTENSION ExtendedRNC-ID PRESENCE optional },
+ ...
+}
+
+-- **************************************************************
+--
+-- UE SPECIFIC INFORMATION ELEMENTARY PROCEDURE
+--
+-- **************************************************************
+
+-- **************************************************************
+--
+-- UE Specific Information Indication
+--
+-- **************************************************************
+
+UESpecificInformationIndication ::= SEQUENCE {
+ protocolIEs ProtocolIE-Container { {UESpecificInformationIndicationIEs} },
+ protocolExtensions ProtocolExtensionContainer { {UESpecificInformationIndicationExtensions} } OPTIONAL,
+ ...
+}
+
+UESpecificInformationIndicationIEs RANAP-PROTOCOL-IES ::= {
+ { ID id-UESBI-Iu CRITICALITY ignore TYPE UESBI-Iu PRESENCE optional },
+ ...
+}
+
+UESpecificInformationIndicationExtensions RANAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+-- **************************************************************
+--
+-- DIRECT INFORMATION TRANSFER ELEMENTARY PROCEDURE
+--
+-- **************************************************************
+
+-- **************************************************************
+--
+-- Direct Information Transfer
+--
+-- **************************************************************
+
+DirectInformationTransfer ::= SEQUENCE {
+ protocolIEs ProtocolIE-Container { { DirectInformationTransferIEs} },
+ protocolExtensions ProtocolExtensionContainer { { DirectInformationTransferExtensions} } OPTIONAL,
+ ...
+}
+
+DirectInformationTransferIEs RANAP-PROTOCOL-IES ::= {
+ { ID id-InterSystemInformationTransferType CRITICALITY ignore TYPE InterSystemInformationTransferType PRESENCE optional } |
+ { ID id-CN-DomainIndicator CRITICALITY ignore TYPE CN-DomainIndicator PRESENCE mandatory } |
+ { ID id-GlobalRNC-ID CRITICALITY ignore TYPE GlobalRNC-ID PRESENCE optional } |
+ { ID id-GlobalCN-ID CRITICALITY ignore TYPE GlobalCN-ID PRESENCE optional },
+ ...
+}
+
+DirectInformationTransferExtensions RANAP-PROTOCOL-EXTENSION ::= {
+-- Extension for Release 7 to indicate extended RNC-ID --
+ { ID id-ExtendedRNC-ID CRITICALITY reject EXTENSION ExtendedRNC-ID PRESENCE optional },
+ ...
+}
+
+-- **************************************************************
+--
+-- UPLINK INFORMATION EXCHANGE ELEMENTARY PROCEDURE
+--
+-- **************************************************************
+
+-- **************************************************************
+--
+-- Uplink Information Exchange Request
+--
+-- **************************************************************
+
+UplinkInformationExchangeRequest ::= SEQUENCE {
+ protocolIEs ProtocolIE-Container { { UplinkInformationExchangeRequestIEs} },
+ protocolExtensions ProtocolExtensionContainer { { UplinkInformationExchangeRequestExtensions} } OPTIONAL,
+ ...
+}
+
+UplinkInformationExchangeRequestIEs RANAP-PROTOCOL-IES ::= {
+ { ID id-InformationExchangeID CRITICALITY reject TYPE InformationExchangeID PRESENCE mandatory } |
+ { ID id-InformationExchangeType CRITICALITY reject TYPE InformationExchangeType PRESENCE mandatory } |
+ { ID id-InformationTransferType CRITICALITY reject TYPE InformationTransferType PRESENCE conditional
+ -- This IE shall be present if the Information Exchange Type IE is set to "transfer" -- } |
+ { ID id-InformationRequestType CRITICALITY reject TYPE InformationRequestType PRESENCE conditional
+ -- This IE shall be present if the Information Exchange Type IE is set to "request" -- } |
+ { ID id-CN-DomainIndicator CRITICALITY reject TYPE CN-DomainIndicator PRESENCE mandatory } |
+ { ID id-GlobalRNC-ID CRITICALITY reject TYPE GlobalRNC-ID PRESENCE mandatory },
+ ...
+}
+
+UplinkInformationExchangeRequestExtensions RANAP-PROTOCOL-EXTENSION ::= {
+-- Extension for Release 7 to indicate extended RNC-ID --
+ { ID id-ExtendedRNC-ID CRITICALITY reject EXTENSION ExtendedRNC-ID PRESENCE optional },
+ ...
+}
+
+-- **************************************************************
+--
+-- Uplink Information Exchange Response
+--
+-- **************************************************************
+
+UplinkInformationExchangeResponse ::= SEQUENCE {
+ protocolIEs ProtocolIE-Container { { UplinkInformationExchangeResponseIEs} },
+ protocolExtensions ProtocolExtensionContainer { { UplinkInformationExchangeResponseExtensions} } OPTIONAL,
+ ...
+}
+
+UplinkInformationExchangeResponseIEs RANAP-PROTOCOL-IES ::= {
+ { ID id-InformationExchangeID CRITICALITY ignore TYPE InformationExchangeID PRESENCE mandatory } |
+ { ID id-InformationRequested CRITICALITY ignore TYPE InformationRequested PRESENCE optional } |
+ { ID id-CN-DomainIndicator CRITICALITY ignore TYPE CN-DomainIndicator PRESENCE mandatory } |
+ { ID id-GlobalCN-ID CRITICALITY ignore TYPE GlobalCN-ID PRESENCE optional } |
+ { ID id-CriticalityDiagnostics CRITICALITY ignore TYPE CriticalityDiagnostics PRESENCE optional } ,
+ ...
+}
+
+UplinkInformationExchangeResponseExtensions RANAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+-- **************************************************************
+--
+-- Uplink Information Exchange Failure
+--
+-- **************************************************************
+
+UplinkInformationExchangeFailure ::= SEQUENCE {
+ protocolIEs ProtocolIE-Container { { UplinkInformationExchangeFailureIEs} },
+ protocolExtensions ProtocolExtensionContainer { { UplinkInformationExchangeFailureExtensions} } OPTIONAL,
+ ...
+}
+
+UplinkInformationExchangeFailureIEs RANAP-PROTOCOL-IES ::= {
+ { ID id-InformationExchangeID CRITICALITY ignore TYPE InformationExchangeID PRESENCE mandatory } |
+ { ID id-CN-DomainIndicator CRITICALITY ignore TYPE CN-DomainIndicator PRESENCE mandatory } |
+ { ID id-GlobalCN-ID CRITICALITY ignore TYPE GlobalCN-ID PRESENCE optional } |
+ { ID id-Cause CRITICALITY ignore TYPE Cause PRESENCE mandatory } |
+ { ID id-CriticalityDiagnostics CRITICALITY ignore TYPE CriticalityDiagnostics PRESENCE optional } ,
+ ...
+}
+
+UplinkInformationExchangeFailureExtensions RANAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+-- **************************************************************
+--
+-- MBMS SESSION START PROCEDURE
+--
+-- **************************************************************
+
+-- **************************************************************
+--
+-- MBMS Session Start
+--
+-- **************************************************************
+
+MBMSSessionStart ::= SEQUENCE {
+ protocolIEs ProtocolIE-Container { { MBMSSessionStartIEs} },
+ protocolExtensions ProtocolExtensionContainer { { MBMSSessionStartExtensions} } OPTIONAL,
+ ...
+}
+
+MBMSSessionStartIEs RANAP-PROTOCOL-IES ::= {
+ { ID id-TMGI CRITICALITY reject TYPE TMGI PRESENCE mandatory } |
+ { ID id-MBMSSessionIdentity CRITICALITY ignore TYPE MBMSSessionIdentity PRESENCE optional } |
+ { ID id-MBMSBearerServiceType CRITICALITY reject TYPE MBMSBearerServiceType PRESENCE mandatory } |
+ { ID id-IuSigConId CRITICALITY reject TYPE IuSignallingConnectionIdentifier PRESENCE mandatory }|
+ { ID id-RAB-Parameters CRITICALITY reject TYPE RAB-Parameters PRESENCE mandatory } |
+ { ID id-PDP-TypeInformation CRITICALITY ignore TYPE PDP-TypeInformation PRESENCE optional } |
+ { ID id-MBMSSessionDuration CRITICALITY reject TYPE MBMSSessionDuration PRESENCE mandatory } |
+ { ID id-MBMSServiceArea CRITICALITY reject TYPE MBMSServiceArea PRESENCE mandatory } |
+ { ID id-FrequenceLayerConvergenceFlag CRITICALITY ignore TYPE FrequenceLayerConvergenceFlag PRESENCE optional } |
+ { ID id-RAListofIdleModeUEs CRITICALITY ignore TYPE RAListofIdleModeUEs PRESENCE optional } |
+ { ID id-GlobalCN-ID CRITICALITY reject TYPE GlobalCN-ID PRESENCE optional } |
+ { ID id-MBMSSessionRepetitionNumber CRITICALITY ignore TYPE MBMSSessionRepetitionNumber PRESENCE optional } |
+ { ID id-TimeToMBMSDataTransfer CRITICALITY reject TYPE TimeToMBMSDataTransfer PRESENCE mandatory },
+ ...
+}
+
+MBMSSessionStartExtensions RANAP-PROTOCOL-EXTENSION ::= {
+-- Extension for Release 6 to enable MBMS counting in broadcast mode --
+ { ID id-MBMSCountingInformation CRITICALITY ignore EXTENSION MBMSCountingInformation PRESENCE optional } |
+ { ID id-MBMSSynchronisationInformation CRITICALITY ignore EXTENSION MBMSSynchronisationInformation PRESENCE optional },
+ ...
+}
+
+MBMSSynchronisationInformation ::= SEQUENCE {
+ mBMSHCIndicator MBMSHCIndicator,
+ iPMulticastAddress IPMulticastAddress,
+ gTPDLTEID GTP-TEI,
+ iE-Extensions ProtocolExtensionContainer { {MBMSSynchronisationInformation-ExtIEs} } OPTIONAL,
+ ...
+}
+
+MBMSSynchronisationInformation-ExtIEs RANAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+-- **************************************************************
+--
+-- MBMS Session Start Response
+--
+-- **************************************************************
+
+MBMSSessionStartResponse::= SEQUENCE {
+ protocolIEs ProtocolIE-Container { {MBMSSessionStartResponseIEs} },
+ protocolExtensions ProtocolExtensionContainer { {MBMSSessionStartResponseExtensions} } OPTIONAL,
+ ...
+}
+
+MBMSSessionStartResponseIEs RANAP-PROTOCOL-IES ::= {
+ { ID id-TransportLayerInformation CRITICALITY ignore TYPE TransportLayerInformation PRESENCE optional } |
+ { ID id-Cause CRITICALITY ignore TYPE Cause PRESENCE optional } |
+ { ID id-CriticalityDiagnostics CRITICALITY ignore TYPE CriticalityDiagnostics PRESENCE optional } ,
+ ...
+}
+
+MBMSSessionStartResponseExtensions RANAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+-- **************************************************************
+--
+-- MBMS Session Start Failure
+--
+-- **************************************************************
+
+MBMSSessionStartFailure ::= SEQUENCE {
+ protocolIEs ProtocolIE-Container { { MBMSSessionStartFailureIEs} },
+ protocolExtensions ProtocolExtensionContainer { { MBMSSessionStartFailureExtensions} } OPTIONAL,
+ ...
+}
+
+MBMSSessionStartFailureIEs RANAP-PROTOCOL-IES ::= {
+ { ID id-Cause CRITICALITY ignore TYPE Cause PRESENCE mandatory } |
+ { ID id-CriticalityDiagnostics CRITICALITY ignore TYPE CriticalityDiagnostics PRESENCE optional } ,
+ ...
+}
+
+MBMSSessionStartFailureExtensions RANAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+-- **************************************************************
+--
+-- MBMS SESSION UPDATE PROCEDURE
+--
+-- **************************************************************
+
+-- **************************************************************
+--
+-- MBMS Session Update
+--
+-- **************************************************************
+
+MBMSSessionUpdate ::= SEQUENCE {
+ protocolIEs ProtocolIE-Container { { MBMSSessionUpdateIEs} },
+ protocolExtensions ProtocolExtensionContainer { { MBMSSessionUpdateExtensions} } OPTIONAL,
+ ...
+}
+
+MBMSSessionUpdateIEs RANAP-PROTOCOL-IES ::= {
+ { ID id-SessionUpdateID CRITICALITY reject TYPE SessionUpdateID PRESENCE mandatory } |
+ { ID id-DeltaRAListofIdleModeUEs CRITICALITY reject TYPE DeltaRAListofIdleModeUEs PRESENCE mandatory },
+ ...
+}
+
+MBMSSessionUpdateExtensions RANAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+-- **************************************************************
+--
+-- MBMS Session Update Response
+--
+-- **************************************************************
+
+MBMSSessionUpdateResponse ::= SEQUENCE {
+ protocolIEs ProtocolIE-Container { { MBMSSessionUpdateResponseIEs} },
+ protocolExtensions ProtocolExtensionContainer { { MBMSSessionUpdateResponseExtensions} } OPTIONAL,
+ ...
+}
+
+MBMSSessionUpdateResponseIEs RANAP-PROTOCOL-IES ::= {
+ { ID id-SessionUpdateID CRITICALITY ignore TYPE SessionUpdateID PRESENCE mandatory } |
+ { ID id-TransportLayerInformation CRITICALITY ignore TYPE TransportLayerInformation PRESENCE optional } |
+ { ID id-Cause CRITICALITY ignore TYPE Cause PRESENCE optional } |
+ { ID id-CriticalityDiagnostics CRITICALITY ignore TYPE CriticalityDiagnostics PRESENCE optional } ,
+ ...
+}
+
+MBMSSessionUpdateResponseExtensions RANAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+-- **************************************************************
+--
+-- MBMS Session Update Failure
+--
+-- **************************************************************
+
+MBMSSessionUpdateFailure ::= SEQUENCE {
+ protocolIEs ProtocolIE-Container { { MBMSSessionUpdateFailureIEs} },
+ protocolExtensions ProtocolExtensionContainer { { MBMSSessionUpdateFailureExtensions} } OPTIONAL,
+ ...
+}
+
+MBMSSessionUpdateFailureIEs RANAP-PROTOCOL-IES ::= {
+ { ID id-SessionUpdateID CRITICALITY ignore TYPE SessionUpdateID PRESENCE mandatory } |
+ { ID id-Cause CRITICALITY ignore TYPE Cause PRESENCE mandatory } |
+ { ID id-CriticalityDiagnostics CRITICALITY ignore TYPE CriticalityDiagnostics PRESENCE optional } ,
+ ...
+}
+
+MBMSSessionUpdateFailureExtensions RANAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+-- **************************************************************
+--
+-- MBMS SESSION STOP PROCEDURE
+--
+-- **************************************************************
+
+-- **************************************************************
+--
+-- MBMS Session Stop
+--
+-- **************************************************************
+
+MBMSSessionStop ::= SEQUENCE {
+ protocolIEs ProtocolIE-Container { { MBMSSessionStopIEs} },
+ protocolExtensions ProtocolExtensionContainer { { MBMSSessionStopExtensions} } OPTIONAL,
+ ...
+}
+
+MBMSSessionStopIEs RANAP-PROTOCOL-IES ::= {
+ { ID id-MBMSCNDe-Registration CRITICALITY reject TYPE MBMSCNDe-Registration PRESENCE mandatory },
+ ...
+}
+
+MBMSSessionStopExtensions RANAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+-- **************************************************************
+--
+-- MBMS Session Stop Response
+--
+-- **************************************************************
+
+MBMSSessionStopResponse ::= SEQUENCE {
+ protocolIEs ProtocolIE-Container { { MBMSSessionStopResponseIEs} },
+ protocolExtensions ProtocolExtensionContainer { { MBMSSessionStopResponseExtensions} } OPTIONAL,
+ ...
+}
+
+MBMSSessionStopResponseIEs RANAP-PROTOCOL-IES ::= {
+ { ID id-Cause CRITICALITY ignore TYPE Cause PRESENCE optional } |
+ { ID id-CriticalityDiagnostics CRITICALITY ignore TYPE CriticalityDiagnostics PRESENCE optional } ,
+ ...
+}
+
+MBMSSessionStopResponseExtensions RANAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+-- **************************************************************
+--
+-- MBMS UE LINKING PROCEDURE
+--
+-- **************************************************************
+
+-- **************************************************************
+--
+-- MBMS UE Linking Request
+--
+-- **************************************************************
+
+MBMSUELinkingRequest ::= SEQUENCE {
+ protocolIEs ProtocolIE-Container { { MBMSUELinkingRequestIEs} },
+ protocolExtensions ProtocolExtensionContainer { { MBMSUELinkingRequestExtensions} } OPTIONAL,
+ ...
+}
+
+MBMSUELinkingRequestIEs RANAP-PROTOCOL-IES ::= {
+ { ID id-JoinedMBMSBearerServicesList CRITICALITY reject TYPE JoinedMBMSBearerService-IEs PRESENCE optional } |
+ { ID id-LeftMBMSBearerServicesList CRITICALITY reject TYPE LeftMBMSBearerService-IEs PRESENCE optional },
+ ...
+}
+
+LeftMBMSBearerService-IEs ::= SEQUENCE (SIZE (1.. maxnoofMulticastServicesPerUE)) OF
+ SEQUENCE {
+ tMGI TMGI,
+ iE-Extensions ProtocolExtensionContainer { {LeftMBMSBearerService-ExtIEs} } OPTIONAL,
+ ...
+ }
+
+LeftMBMSBearerService-ExtIEs RANAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+MBMSUELinkingRequestExtensions RANAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+-- **************************************************************
+--
+-- MBMS UE Linking Response
+--
+-- **************************************************************
+
+MBMSUELinkingResponse ::= SEQUENCE {
+ protocolIEs ProtocolIE-Container { { MBMSUELinkingResponseIEs} },
+ protocolExtensions ProtocolExtensionContainer { { MBMSUELinkingResponseExtensions} } OPTIONAL,
+ ...
+}
+
+MBMSUELinkingResponseIEs RANAP-PROTOCOL-IES ::= {
+ { ID id-UnsuccessfulLinkingList CRITICALITY ignore TYPE UnsuccessfulLinking-IEs PRESENCE optional } |
+ { ID id-CriticalityDiagnostics CRITICALITY ignore TYPE CriticalityDiagnostics PRESENCE optional } ,
+ ...
+}
+
+UnsuccessfulLinking-IEs ::= SEQUENCE (SIZE (1.. maxnoofMulticastServicesPerUE)) OF
+ SEQUENCE {
+ tMGI TMGI,
+ cause Cause,
+ iE-Extensions ProtocolExtensionContainer { {UnsuccessfulLinking-ExtIEs} } OPTIONAL,
+ ...
+ }
+
+UnsuccessfulLinking-ExtIEs RANAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+MBMSUELinkingResponseExtensions RANAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+-- **************************************************************
+--
+-- MBMS REGISTRATION PROCEDURE
+--
+-- **************************************************************
+
+-- **************************************************************
+--
+-- MBMS Registration Request
+--
+-- **************************************************************
+
+MBMSRegistrationRequest ::= SEQUENCE {
+ protocolIEs ProtocolIE-Container { { MBMSRegistrationRequestIEs} },
+ protocolExtensions ProtocolExtensionContainer { { MBMSRegistrationRequestExtensions} } OPTIONAL,
+ ...
+}
+
+MBMSRegistrationRequestIEs RANAP-PROTOCOL-IES ::= {
+ { ID id-MBMSRegistrationRequestType CRITICALITY reject TYPE MBMSRegistrationRequestType PRESENCE mandatory } |
+ { ID id-TMGI CRITICALITY reject TYPE TMGI PRESENCE mandatory } |
+ { ID id-IPMulticastAddress CRITICALITY reject TYPE IPMulticastAddress PRESENCE conditional
+ -- This IE shall be present if the MBMS Registration Request Type IE is set to "register" -- } |
+ { ID id-APN CRITICALITY reject TYPE APN PRESENCE conditional
+ -- This IE shall be present if the MBMS Registration Request Type IE is set to "register" -- } |
+ { ID id-GlobalRNC-ID CRITICALITY reject TYPE GlobalRNC-ID PRESENCE optional },
+ ...
+}
+
+MBMSRegistrationRequestExtensions RANAP-PROTOCOL-EXTENSION ::= {
+-- Extension for Release 7 to indicate extended RNC-ID --
+ { ID id-ExtendedRNC-ID CRITICALITY reject EXTENSION ExtendedRNC-ID PRESENCE optional },
+ ...
+}
+
+-- **************************************************************
+--
+-- MBMS Registration Response
+--
+-- **************************************************************
+
+MBMSRegistrationResponse ::= SEQUENCE {
+ protocolIEs ProtocolIE-Container { { MBMSRegistrationResponseIEs} },
+ protocolExtensions ProtocolExtensionContainer { { MBMSRegistrationResponseExtensions} } OPTIONAL,
+ ...
+}
+
+MBMSRegistrationResponseIEs RANAP-PROTOCOL-IES ::= {
+ { ID id-TMGI CRITICALITY ignore TYPE TMGI PRESENCE optional } |
+ { ID id-GlobalCN-ID CRITICALITY ignore TYPE GlobalCN-ID PRESENCE optional } |
+ { ID id-CriticalityDiagnostics CRITICALITY ignore TYPE CriticalityDiagnostics PRESENCE optional } ,
+ ...
+}
+
+MBMSRegistrationResponseExtensions RANAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+-- **************************************************************
+--
+-- MBMS Registration Failure
+--
+-- **************************************************************
+
+MBMSRegistrationFailure ::= SEQUENCE {
+ protocolIEs ProtocolIE-Container { { MBMSRegistrationFailureIEs} },
+ protocolExtensions ProtocolExtensionContainer { { MBMSRegistrationFailureExtensions} } OPTIONAL,
+ ...
+}
+
+MBMSRegistrationFailureIEs RANAP-PROTOCOL-IES ::= {
+ { ID id-TMGI CRITICALITY ignore TYPE TMGI PRESENCE optional } |
+ { ID id-GlobalCN-ID CRITICALITY ignore TYPE GlobalCN-ID PRESENCE optional } |
+ { ID id-Cause CRITICALITY ignore TYPE Cause PRESENCE mandatory } |
+ { ID id-CriticalityDiagnostics CRITICALITY ignore TYPE CriticalityDiagnostics PRESENCE optional } ,
+ ...
+}
+
+MBMSRegistrationFailureExtensions RANAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+-- **************************************************************
+--
+-- MBMS CN DE-REGISTRATION PROCEDURE
+--
+-- **************************************************************
+
+-- **************************************************************
+--
+-- MBMS CN De-Registration Request
+--
+-- **************************************************************
+
+MBMSCNDe-RegistrationRequest ::= SEQUENCE {
+ protocolIEs ProtocolIE-Container { { MBMSCNDe-RegistrationRequestIEs} },
+ protocolExtensions ProtocolExtensionContainer { { MBMSCNDe-RegistrationRequestExtensions} } OPTIONAL,
+ ...
+}
+
+MBMSCNDe-RegistrationRequestIEs RANAP-PROTOCOL-IES ::= {
+ { ID id-TMGI CRITICALITY reject TYPE TMGI PRESENCE mandatory } |
+ { ID id-GlobalCN-ID CRITICALITY reject TYPE GlobalCN-ID PRESENCE optional },
+ ...
+}
+
+MBMSCNDe-RegistrationRequestExtensions RANAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+-- **************************************************************
+--
+-- MBMS CN De-Registration Response
+--
+-- **************************************************************
+
+MBMSCNDe-RegistrationResponse ::= SEQUENCE {
+ protocolIEs ProtocolIE-Container { { MBMSCNDe-RegistrationResponseIEs} },
+ protocolExtensions ProtocolExtensionContainer { { MBMSCNDe-RegistrationResponseExtensions} } OPTIONAL,
+ ...
+}
+
+MBMSCNDe-RegistrationResponseIEs RANAP-PROTOCOL-IES ::= {
+ { ID id-TMGI CRITICALITY ignore TYPE TMGI PRESENCE mandatory } |
+ { ID id-GlobalRNC-ID CRITICALITY ignore TYPE GlobalRNC-ID PRESENCE mandatory } |
+ { ID id-Cause CRITICALITY ignore TYPE Cause PRESENCE optional } |
+ { ID id-CriticalityDiagnostics CRITICALITY ignore TYPE CriticalityDiagnostics PRESENCE optional } ,
+ ...
+}
+
+MBMSCNDe-RegistrationResponseExtensions RANAP-PROTOCOL-EXTENSION ::= {
+-- Extension for Release 7 to indicate extended RNC-ID --
+ { ID id-ExtendedRNC-ID CRITICALITY reject EXTENSION ExtendedRNC-ID PRESENCE optional },
+ ...
+}
+
+-- **************************************************************
+--
+-- MBMS RAB ESTABLISHMENT INDICATION PROCEDURE
+--
+-- **************************************************************
+
+-- **************************************************************
+--
+-- MBMS RAB Establishment Indication
+--
+-- **************************************************************
+
+MBMSRABEstablishmentIndication ::= SEQUENCE {
+ protocolIEs ProtocolIE-Container { { MBMSRABEstablishmentIndicationIEs} },
+ protocolExtensions ProtocolExtensionContainer { { MBMSRABEstablishmentIndicationExtensions} } OPTIONAL,
+ ...
+}
+
+MBMSRABEstablishmentIndicationIEs RANAP-PROTOCOL-IES ::= {
+ { ID id-TransportLayerInformation CRITICALITY ignore TYPE TransportLayerInformation PRESENCE mandatory } ,
+ ...
+}
+
+MBMSRABEstablishmentIndicationExtensions RANAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+-- **************************************************************
+--
+-- MBMS RAB RELEASE PROCEDURE
+--
+-- **************************************************************
+
+-- **************************************************************
+--
+-- MBMS RAB Release Request
+--
+-- **************************************************************
+
+MBMSRABReleaseRequest ::= SEQUENCE {
+ protocolIEs ProtocolIE-Container { {MBMSRABReleaseRequestIEs} },
+ protocolExtensions ProtocolExtensionContainer { {MBMSRABReleaseRequestExtensions} } OPTIONAL,
+ ...
+}
+
+MBMSRABReleaseRequestIEs RANAP-PROTOCOL-IES ::= {
+ { ID id-Cause CRITICALITY ignore TYPE Cause PRESENCE mandatory },
+ ...
+}
+
+
+MBMSRABReleaseRequestExtensions RANAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+-- **************************************************************
+--
+-- MBMS RAB Release
+--
+-- **************************************************************
+
+MBMSRABRelease ::= SEQUENCE {
+ protocolIEs ProtocolIE-Container { {MBMSRABReleaseIEs} },
+ protocolExtensions ProtocolExtensionContainer { {MBMSRABReleaseExtensions} } OPTIONAL,
+ ...
+}
+
+MBMSRABReleaseIEs RANAP-PROTOCOL-IES ::= {
+ { ID id-Cause CRITICALITY ignore TYPE Cause PRESENCE mandatory }|
+ { ID id-CriticalityDiagnostics CRITICALITY ignore TYPE CriticalityDiagnostics PRESENCE optional },
+ ...
+}
+
+MBMSRABReleaseExtensions RANAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+-- **************************************************************
+--
+-- MBMS RAB Release Failure
+--
+-- **************************************************************
+
+MBMSRABReleaseFailure ::= SEQUENCE {
+ protocolIEs ProtocolIE-Container { {MBMSRABReleaseFailureIEs} },
+ protocolExtensions ProtocolExtensionContainer { {MBMSRABReleaseFailureExtensions} } OPTIONAL,
+ ...
+}
+
+MBMSRABReleaseFailureIEs RANAP-PROTOCOL-IES ::= {
+ { ID id-Cause CRITICALITY ignore TYPE Cause PRESENCE mandatory }|
+ { ID id-CriticalityDiagnostics CRITICALITY ignore TYPE CriticalityDiagnostics PRESENCE optional },
+ ...
+}
+
+MBMSRABReleaseFailureExtensions RANAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+-- **************************************************************
+--
+-- SRVCC PREPARATION ELEMENTARY PROCEDURE
+--
+-- **************************************************************
+
+-- **************************************************************
+--
+-- SRVCC CS Keys Request
+--
+-- **************************************************************
+
+SRVCC-CSKeysRequest ::= SEQUENCE {
+ protocolIEs ProtocolIE-Container { {SRVCC-CSKeysRequestIEs} },
+ protocolExtensions ProtocolExtensionContainer { {SRVCC-CSKeysRequestExtensions} } OPTIONAL,
+ ...
+}
+
+SRVCC-CSKeysRequestIEs RANAP-PROTOCOL-IES ::= {
+ ...
+}
+
+SRVCC-CSKeysRequestExtensions RANAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+-- **************************************************************
+--
+-- SRVCC CS Keys Response
+--
+-- **************************************************************
+
+SRVCC-CSKeysResponse ::= SEQUENCE {
+ protocolIEs ProtocolIE-Container { {SRVCC-CSKeysResponseIEs} },
+ protocolExtensions ProtocolExtensionContainer { {SRVCC-CSKeysResponseExtensions} } OPTIONAL,
+ ...
+}
+
+SRVCC-CSKeysResponseIEs RANAP-PROTOCOL-IES ::= {
+ { ID id-IntegrityProtectionKey CRITICALITY reject TYPE IntegrityProtectionKey PRESENCE mandatory }|
+ { ID id-EncryptionKey CRITICALITY reject TYPE EncryptionKey PRESENCE mandatory }|
+ { ID id-SRVCC-Information CRITICALITY reject TYPE SRVCC-Information PRESENCE mandatory }|
+ { ID id-CriticalityDiagnostics CRITICALITY ignore TYPE CriticalityDiagnostics PRESENCE optional },
+ ...
+}
+
+SRVCC-CSKeysResponseExtensions RANAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+
+END
+
+
+
diff --git a/lib/asn1/test/asn1_SUITE_data/RANAP-PDU-Descriptions.asn1 b/lib/asn1/test/asn1_SUITE_data/RANAP-PDU-Descriptions.asn1
new file mode 100644
index 0000000000..a7f4aded76
--- /dev/null
+++ b/lib/asn1/test/asn1_SUITE_data/RANAP-PDU-Descriptions.asn1
@@ -0,0 +1,619 @@
+-- RANAP-PDU-Descriptions.asn
+--
+-- Taken from 3GPP TS 25.413 V8.2.1 (2009-03)
+-- http://www.3gpp.org/ftp/Specs/archive/25_series/25.413/25413-821.zip
+--
+-- 9.3.2 Elementary Procedure Definitions
+--
+-- $Id$
+--
+
+-- **************************************************************
+--
+-- Elementary Procedure definitions
+--
+-- **************************************************************
+
+RANAP-PDU-Descriptions {
+itu-t (0) identified-organization (4) etsi (0) mobileDomain (0)
+umts-Access (20) modules (3) ranap (0) version1 (1) ranap-PDU-Descriptions (0)}
+
+DEFINITIONS AUTOMATIC TAGS ::=
+
+BEGIN
+
+-- **************************************************************
+--
+-- IE parameter types from other modules.
+--
+-- **************************************************************
+
+IMPORTS
+ Criticality,
+ ProcedureCode
+FROM RANAP-CommonDataTypes
+
+ Iu-ReleaseCommand,
+ Iu-ReleaseComplete,
+ RelocationCommand,
+ RelocationPreparationFailure,
+ RelocationRequired,
+ RelocationRequest,
+ RelocationRequestAcknowledge,
+ RelocationFailure,
+ RelocationCancel,
+ RelocationCancelAcknowledge,
+ EnhancedRelocationCompleteRequest,
+ EnhancedRelocationCompleteResponse,
+ EnhancedRelocationCompleteFailure,
+ EnhancedRelocationCompleteConfirm,
+ SRNS-ContextRequest,
+ SRNS-ContextResponse,
+ SecurityModeCommand,
+ SecurityModeComplete,
+ SecurityModeReject,
+ DataVolumeReportRequest,
+ DataVolumeReport,
+ Reset,
+ ResetAcknowledge,
+ RAB-ReleaseRequest,
+ Iu-ReleaseRequest,
+ RelocationDetect,
+ RelocationComplete,
+ Paging,
+ CommonID,
+ CN-InvokeTrace,
+ CN-DeactivateTrace,
+ LocationReportingControl,
+ LocationReport,
+ InitialUE-Message,
+ DirectTransfer,
+ Overload,
+ ErrorIndication,
+ SRNS-DataForwardCommand,
+ ForwardSRNS-Context,
+ RAB-AssignmentRequest,
+ RAB-AssignmentResponse,
+ RAB-ModifyRequest,
+ PrivateMessage,
+ ResetResource,
+ ResetResourceAcknowledge,
+ RANAP-RelocationInformation,
+ RANAP-EnhancedRelocationInformationRequest,
+ RANAP-EnhancedRelocationInformationResponse,
+ LocationRelatedDataRequest,
+ LocationRelatedDataResponse,
+ LocationRelatedDataFailure,
+ InformationTransferIndication,
+ InformationTransferConfirmation,
+ InformationTransferFailure,
+ UESpecificInformationIndication,
+ DirectInformationTransfer,
+ UplinkInformationExchangeRequest,
+ UplinkInformationExchangeResponse,
+ UplinkInformationExchangeFailure,
+ MBMSSessionStart,
+ MBMSSessionStartResponse,
+ MBMSSessionStartFailure,
+ MBMSSessionUpdate,
+ MBMSSessionUpdateResponse,
+ MBMSSessionUpdateFailure,
+ MBMSSessionStop,
+ MBMSSessionStopResponse,
+ MBMSUELinkingRequest,
+ MBMSUELinkingResponse,
+ MBMSRegistrationRequest,
+ MBMSRegistrationResponse,
+ MBMSRegistrationFailure,
+ MBMSCNDe-RegistrationRequest,
+ MBMSCNDe-RegistrationResponse,
+ MBMSRABEstablishmentIndication,
+ MBMSRABReleaseRequest,
+ MBMSRABRelease,
+ MBMSRABReleaseFailure,
+ SRVCC-CSKeysRequest,
+ SRVCC-CSKeysResponse
+FROM RANAP-PDU-Contents
+
+ id-LocationRelatedData,
+ id-CN-DeactivateTrace,
+ id-CN-InvokeTrace,
+ id-CommonID,
+ id-DataVolumeReport,
+ id-DirectTransfer,
+ id-ErrorIndication,
+ id-ForwardSRNS-Context,
+ id-InformationTransfer,
+ id-InitialUE-Message,
+ id-Iu-Release,
+ id-Iu-ReleaseRequest,
+ id-LocationReport,
+ id-LocationReportingControl,
+ id-OverloadControl,
+ id-Paging,
+ id-privateMessage,
+ id-RAB-Assignment,
+ id-RAB-ReleaseRequest,
+ id-RAB-ModifyRequest,
+ id-RANAP-Relocation,
+ id-RANAPenhancedRelocation,
+ id-RelocationCancel,
+ id-RelocationComplete,
+ id-RelocationDetect,
+ id-RelocationPreparation,
+ id-RelocationResourceAllocation,
+ id-enhancedRelocationComplete,
+ id-enhancedRelocationCompleteConfirm,
+ id-Reset,
+ id-SRNS-ContextTransfer,
+ id-SRNS-DataForward,
+ id-SecurityModeControl,
+ id-ResetResource,
+ id-UESpecificInformation,
+ id-DirectInformationTransfer,
+ id-UplinkInformationExchange,
+ id-MBMSSessionStart,
+ id-MBMSSessionUpdate,
+ id-MBMSSessionStop,
+ id-MBMSUELinking,
+ id-MBMSRegistration,
+ id-MBMSCNDe-Registration-Procedure,
+ id-MBMSRABEstablishmentIndication,
+ id-MBMSRABRelease,
+ id-SRVCCPreparation
+
+FROM RANAP-Constants;
+
+-- **************************************************************
+--
+-- Interface Elementary Procedure Class
+--
+-- **************************************************************
+
+RANAP-ELEMENTARY-PROCEDURE ::= CLASS {
+ &InitiatingMessage ,
+ &SuccessfulOutcome OPTIONAL,
+ &UnsuccessfulOutcome OPTIONAL,
+ &Outcome OPTIONAL,
+ &procedureCode ProcedureCode UNIQUE,
+ &criticality Criticality DEFAULT ignore
+}
+WITH SYNTAX {
+ INITIATING MESSAGE &InitiatingMessage
+ [SUCCESSFUL OUTCOME &SuccessfulOutcome]
+ [UNSUCCESSFUL OUTCOME &UnsuccessfulOutcome]
+ [OUTCOME &Outcome]
+ PROCEDURE CODE &procedureCode
+ [CRITICALITY &criticality]
+}
+
+-- **************************************************************
+--
+-- Interface PDU Definition
+--
+-- **************************************************************
+
+RANAP-PDU ::= CHOICE {
+ initiatingMessage InitiatingMessage,
+ successfulOutcome SuccessfulOutcome,
+ unsuccessfulOutcome UnsuccessfulOutcome,
+ outcome Outcome,
+ ...
+}
+
+InitiatingMessage ::= SEQUENCE {
+ procedureCode RANAP-ELEMENTARY-PROCEDURE.&procedureCode ({RANAP-ELEMENTARY-PROCEDURES}),
+ criticality RANAP-ELEMENTARY-PROCEDURE.&criticality ({RANAP-ELEMENTARY-PROCEDURES}{@procedureCode}),
+ value RANAP-ELEMENTARY-PROCEDURE.&InitiatingMessage ({RANAP-ELEMENTARY-PROCEDURES}{@procedureCode})
+}
+
+SuccessfulOutcome ::= SEQUENCE {
+ procedureCode RANAP-ELEMENTARY-PROCEDURE.&procedureCode ({RANAP-ELEMENTARY-PROCEDURES}),
+ criticality RANAP-ELEMENTARY-PROCEDURE.&criticality ({RANAP-ELEMENTARY-PROCEDURES}{@procedureCode}),
+ value RANAP-ELEMENTARY-PROCEDURE.&SuccessfulOutcome ({RANAP-ELEMENTARY-PROCEDURES}{@procedureCode})
+}
+
+UnsuccessfulOutcome ::= SEQUENCE {
+ procedureCode RANAP-ELEMENTARY-PROCEDURE.&procedureCode ({RANAP-ELEMENTARY-PROCEDURES}),
+ criticality RANAP-ELEMENTARY-PROCEDURE.&criticality ({RANAP-ELEMENTARY-PROCEDURES}{@procedureCode}),
+ value RANAP-ELEMENTARY-PROCEDURE.&UnsuccessfulOutcome ({RANAP-ELEMENTARY-PROCEDURES}{@procedureCode})
+}
+
+Outcome ::= SEQUENCE {
+ procedureCode RANAP-ELEMENTARY-PROCEDURE.&procedureCode ({RANAP-ELEMENTARY-PROCEDURES}),
+ criticality RANAP-ELEMENTARY-PROCEDURE.&criticality ({RANAP-ELEMENTARY-PROCEDURES}{@procedureCode}),
+ value RANAP-ELEMENTARY-PROCEDURE.&Outcome ({RANAP-ELEMENTARY-PROCEDURES}{@procedureCode})
+}
+
+-- **************************************************************
+--
+-- Interface Elementary Procedure List
+--
+-- **************************************************************
+
+RANAP-ELEMENTARY-PROCEDURES RANAP-ELEMENTARY-PROCEDURE ::= {
+ RANAP-ELEMENTARY-PROCEDURES-CLASS-1 |
+ RANAP-ELEMENTARY-PROCEDURES-CLASS-2 |
+ RANAP-ELEMENTARY-PROCEDURES-CLASS-3 ,
+ ...
+}
+
+
+RANAP-ELEMENTARY-PROCEDURES-CLASS-1 RANAP-ELEMENTARY-PROCEDURE ::= {
+ iu-Release |
+ relocationPreparation |
+ relocationResourceAllocation |
+ relocationCancel |
+ sRNS-ContextTransfer |
+ securityModeControl |
+ dataVolumeReport |
+ reset |
+ resetResource ,
+ ...,
+ locationRelatedData |
+ informationTransfer |
+ uplinkInformationExchange |
+ mBMSSessionStart |
+ mBMSSessionUpdate |
+ mBMSSessionStop |
+ mBMSUELinking |
+ mBMSRegistration |
+ mBMSCNDe-Registration |
+ mBMSRABRelease |
+ enhancedRelocationComplete |
+ rANAP-enhancedRelocation |
+ sRVCCPreparation}
+
+RANAP-ELEMENTARY-PROCEDURES-CLASS-2 RANAP-ELEMENTARY-PROCEDURE ::= {
+ rAB-ReleaseRequest |
+ iu-ReleaseRequest |
+ relocationDetect |
+ relocationComplete |
+ paging |
+ commonID |
+ cN-InvokeTrace |
+ cN-DeactivateTrace |
+ locationReportingControl |
+ locationReport |
+ initialUE-Message |
+ directTransfer |
+ overloadControl |
+ errorIndication |
+ sRNS-DataForward |
+ forwardSRNS-Context |
+ privateMessage |
+ rANAP-Relocation ,
+ ...,
+ rAB-ModifyRequest |
+ uESpecificInformation |
+ directInformationTransfer |
+ mBMSRABEstablishmentIndication |
+ enhancedRelocationCompleteConfirm
+}
+
+RANAP-ELEMENTARY-PROCEDURES-CLASS-3 RANAP-ELEMENTARY-PROCEDURE ::= {
+ rAB-Assignment ,
+ ...
+}
+
+-- **************************************************************
+--
+-- Interface Elementary Procedures
+--
+-- **************************************************************
+
+iu-Release RANAP-ELEMENTARY-PROCEDURE ::= {
+ INITIATING MESSAGE Iu-ReleaseCommand
+ SUCCESSFUL OUTCOME Iu-ReleaseComplete
+ PROCEDURE CODE id-Iu-Release
+ CRITICALITY reject
+}
+
+relocationPreparation RANAP-ELEMENTARY-PROCEDURE ::= {
+ INITIATING MESSAGE RelocationRequired
+ SUCCESSFUL OUTCOME RelocationCommand
+ UNSUCCESSFUL OUTCOME RelocationPreparationFailure
+ PROCEDURE CODE id-RelocationPreparation
+ CRITICALITY reject
+}
+
+relocationResourceAllocation RANAP-ELEMENTARY-PROCEDURE ::= {
+ INITIATING MESSAGE RelocationRequest
+ SUCCESSFUL OUTCOME RelocationRequestAcknowledge
+ UNSUCCESSFUL OUTCOME RelocationFailure
+ PROCEDURE CODE id-RelocationResourceAllocation
+ CRITICALITY reject
+}
+
+relocationCancel RANAP-ELEMENTARY-PROCEDURE ::= {
+ INITIATING MESSAGE RelocationCancel
+ SUCCESSFUL OUTCOME RelocationCancelAcknowledge
+ PROCEDURE CODE id-RelocationCancel
+ CRITICALITY reject
+}
+
+sRNS-ContextTransfer RANAP-ELEMENTARY-PROCEDURE ::= {
+ INITIATING MESSAGE SRNS-ContextRequest
+ SUCCESSFUL OUTCOME SRNS-ContextResponse
+ PROCEDURE CODE id-SRNS-ContextTransfer
+ CRITICALITY reject
+}
+
+securityModeControl RANAP-ELEMENTARY-PROCEDURE ::= {
+ INITIATING MESSAGE SecurityModeCommand
+ SUCCESSFUL OUTCOME SecurityModeComplete
+ UNSUCCESSFUL OUTCOME SecurityModeReject
+ PROCEDURE CODE id-SecurityModeControl
+ CRITICALITY reject
+}
+
+dataVolumeReport RANAP-ELEMENTARY-PROCEDURE ::= {
+ INITIATING MESSAGE DataVolumeReportRequest
+ SUCCESSFUL OUTCOME DataVolumeReport
+ PROCEDURE CODE id-DataVolumeReport
+ CRITICALITY reject
+}
+
+
+reset RANAP-ELEMENTARY-PROCEDURE ::= {
+ INITIATING MESSAGE Reset
+ SUCCESSFUL OUTCOME ResetAcknowledge
+ PROCEDURE CODE id-Reset
+ CRITICALITY reject
+}
+
+rAB-ReleaseRequest RANAP-ELEMENTARY-PROCEDURE ::= {
+ INITIATING MESSAGE RAB-ReleaseRequest
+ PROCEDURE CODE id-RAB-ReleaseRequest
+ CRITICALITY ignore
+}
+
+iu-ReleaseRequest RANAP-ELEMENTARY-PROCEDURE ::= {
+ INITIATING MESSAGE Iu-ReleaseRequest
+ PROCEDURE CODE id-Iu-ReleaseRequest
+ CRITICALITY ignore
+}
+
+relocationDetect RANAP-ELEMENTARY-PROCEDURE ::= {
+ INITIATING MESSAGE RelocationDetect
+ PROCEDURE CODE id-RelocationDetect
+ CRITICALITY ignore
+}
+
+relocationComplete RANAP-ELEMENTARY-PROCEDURE ::= {
+ INITIATING MESSAGE RelocationComplete
+ PROCEDURE CODE id-RelocationComplete
+ CRITICALITY ignore
+}
+
+paging RANAP-ELEMENTARY-PROCEDURE ::= {
+ INITIATING MESSAGE Paging
+ PROCEDURE CODE id-Paging
+ CRITICALITY ignore
+}
+
+commonID RANAP-ELEMENTARY-PROCEDURE ::= {
+ INITIATING MESSAGE CommonID
+ PROCEDURE CODE id-CommonID
+ CRITICALITY ignore
+}
+
+cN-InvokeTrace RANAP-ELEMENTARY-PROCEDURE ::= {
+ INITIATING MESSAGE CN-InvokeTrace
+ PROCEDURE CODE id-CN-InvokeTrace
+ CRITICALITY ignore
+}
+
+cN-DeactivateTrace RANAP-ELEMENTARY-PROCEDURE ::= {
+ INITIATING MESSAGE CN-DeactivateTrace
+ PROCEDURE CODE id-CN-DeactivateTrace
+ CRITICALITY ignore
+}
+
+locationReportingControl RANAP-ELEMENTARY-PROCEDURE ::= {
+ INITIATING MESSAGE LocationReportingControl
+ PROCEDURE CODE id-LocationReportingControl
+ CRITICALITY ignore
+}
+
+locationReport RANAP-ELEMENTARY-PROCEDURE ::= {
+ INITIATING MESSAGE LocationReport
+ PROCEDURE CODE id-LocationReport
+ CRITICALITY ignore
+}
+
+initialUE-Message RANAP-ELEMENTARY-PROCEDURE ::= {
+ INITIATING MESSAGE InitialUE-Message
+ PROCEDURE CODE id-InitialUE-Message
+ CRITICALITY ignore
+}
+
+directTransfer RANAP-ELEMENTARY-PROCEDURE ::= {
+ INITIATING MESSAGE DirectTransfer
+ PROCEDURE CODE id-DirectTransfer
+ CRITICALITY ignore
+}
+
+overloadControl RANAP-ELEMENTARY-PROCEDURE ::= {
+ INITIATING MESSAGE Overload
+ PROCEDURE CODE id-OverloadControl
+ CRITICALITY ignore
+}
+
+errorIndication RANAP-ELEMENTARY-PROCEDURE ::= {
+ INITIATING MESSAGE ErrorIndication
+ PROCEDURE CODE id-ErrorIndication
+ CRITICALITY ignore
+}
+
+sRNS-DataForward RANAP-ELEMENTARY-PROCEDURE ::= {
+ INITIATING MESSAGE SRNS-DataForwardCommand
+ PROCEDURE CODE id-SRNS-DataForward
+ CRITICALITY ignore
+}
+
+forwardSRNS-Context RANAP-ELEMENTARY-PROCEDURE ::= {
+ INITIATING MESSAGE ForwardSRNS-Context
+ PROCEDURE CODE id-ForwardSRNS-Context
+ CRITICALITY ignore
+}
+
+rAB-Assignment RANAP-ELEMENTARY-PROCEDURE ::= {
+ INITIATING MESSAGE RAB-AssignmentRequest
+ OUTCOME RAB-AssignmentResponse
+ PROCEDURE CODE id-RAB-Assignment
+ CRITICALITY reject
+}
+
+privateMessage RANAP-ELEMENTARY-PROCEDURE ::= {
+ INITIATING MESSAGE PrivateMessage
+
+ PROCEDURE CODE id-privateMessage
+ CRITICALITY ignore
+}
+
+resetResource RANAP-ELEMENTARY-PROCEDURE ::= {
+ INITIATING MESSAGE ResetResource
+ SUCCESSFUL OUTCOME ResetResourceAcknowledge
+ PROCEDURE CODE id-ResetResource
+ CRITICALITY reject
+}
+
+rANAP-Relocation RANAP-ELEMENTARY-PROCEDURE ::= {
+ INITIATING MESSAGE RANAP-RelocationInformation
+ PROCEDURE CODE id-RANAP-Relocation
+ CRITICALITY ignore
+}
+
+rAB-ModifyRequest RANAP-ELEMENTARY-PROCEDURE ::= {
+ INITIATING MESSAGE RAB-ModifyRequest
+ PROCEDURE CODE id-RAB-ModifyRequest
+ CRITICALITY ignore
+}
+
+locationRelatedData RANAP-ELEMENTARY-PROCEDURE ::= {
+ INITIATING MESSAGE LocationRelatedDataRequest
+ SUCCESSFUL OUTCOME LocationRelatedDataResponse
+ UNSUCCESSFUL OUTCOME LocationRelatedDataFailure
+ PROCEDURE CODE id-LocationRelatedData
+ CRITICALITY reject
+}
+
+informationTransfer RANAP-ELEMENTARY-PROCEDURE ::= {
+ INITIATING MESSAGE InformationTransferIndication
+ SUCCESSFUL OUTCOME InformationTransferConfirmation
+ UNSUCCESSFUL OUTCOME InformationTransferFailure
+ PROCEDURE CODE id-InformationTransfer
+ CRITICALITY reject
+}
+
+uESpecificInformation RANAP-ELEMENTARY-PROCEDURE ::= {
+ INITIATING MESSAGE UESpecificInformationIndication
+ PROCEDURE CODE id-UESpecificInformation
+ CRITICALITY ignore
+}
+
+directInformationTransfer RANAP-ELEMENTARY-PROCEDURE ::= {
+ INITIATING MESSAGE DirectInformationTransfer
+ PROCEDURE CODE id-DirectInformationTransfer
+ CRITICALITY ignore
+}
+
+uplinkInformationExchange RANAP-ELEMENTARY-PROCEDURE ::= {
+ INITIATING MESSAGE UplinkInformationExchangeRequest
+ SUCCESSFUL OUTCOME UplinkInformationExchangeResponse
+ UNSUCCESSFUL OUTCOME UplinkInformationExchangeFailure
+ PROCEDURE CODE id-UplinkInformationExchange
+ CRITICALITY reject
+}
+
+mBMSSessionStart RANAP-ELEMENTARY-PROCEDURE ::= {
+ INITIATING MESSAGE MBMSSessionStart
+ SUCCESSFUL OUTCOME MBMSSessionStartResponse
+ UNSUCCESSFUL OUTCOME MBMSSessionStartFailure
+ PROCEDURE CODE id-MBMSSessionStart
+ CRITICALITY reject
+}
+
+mBMSSessionUpdate RANAP-ELEMENTARY-PROCEDURE ::= {
+ INITIATING MESSAGE MBMSSessionUpdate
+ SUCCESSFUL OUTCOME MBMSSessionUpdateResponse
+ UNSUCCESSFUL OUTCOME MBMSSessionUpdateFailure
+ PROCEDURE CODE id-MBMSSessionUpdate
+ CRITICALITY reject
+}
+
+mBMSSessionStop RANAP-ELEMENTARY-PROCEDURE ::= {
+ INITIATING MESSAGE MBMSSessionStop
+ SUCCESSFUL OUTCOME MBMSSessionStopResponse
+ PROCEDURE CODE id-MBMSSessionStop
+ CRITICALITY reject
+}
+
+mBMSUELinking RANAP-ELEMENTARY-PROCEDURE ::= {
+ INITIATING MESSAGE MBMSUELinkingRequest
+ OUTCOME MBMSUELinkingResponse
+ PROCEDURE CODE id-MBMSUELinking
+ CRITICALITY reject
+}
+
+mBMSRegistration RANAP-ELEMENTARY-PROCEDURE ::= {
+ INITIATING MESSAGE MBMSRegistrationRequest
+ SUCCESSFUL OUTCOME MBMSRegistrationResponse
+ UNSUCCESSFUL OUTCOME MBMSRegistrationFailure
+ PROCEDURE CODE id-MBMSRegistration
+ CRITICALITY reject
+}
+
+mBMSCNDe-Registration RANAP-ELEMENTARY-PROCEDURE ::= {
+ INITIATING MESSAGE MBMSCNDe-RegistrationRequest
+ SUCCESSFUL OUTCOME MBMSCNDe-RegistrationResponse
+ PROCEDURE CODE id-MBMSCNDe-Registration-Procedure
+ CRITICALITY reject
+}
+
+mBMSRABEstablishmentIndication RANAP-ELEMENTARY-PROCEDURE ::= {
+ INITIATING MESSAGE MBMSRABEstablishmentIndication
+ PROCEDURE CODE id-MBMSRABEstablishmentIndication
+ CRITICALITY ignore
+}
+
+mBMSRABRelease RANAP-ELEMENTARY-PROCEDURE ::= {
+ INITIATING MESSAGE MBMSRABReleaseRequest
+ SUCCESSFUL OUTCOME MBMSRABRelease
+ UNSUCCESSFUL OUTCOME MBMSRABReleaseFailure
+ PROCEDURE CODE id-MBMSRABRelease
+ CRITICALITY reject
+}
+enhancedRelocationComplete RANAP-ELEMENTARY-PROCEDURE ::= {
+ INITIATING MESSAGE EnhancedRelocationCompleteRequest
+ SUCCESSFUL OUTCOME EnhancedRelocationCompleteResponse
+ UNSUCCESSFUL OUTCOME EnhancedRelocationCompleteFailure
+ PROCEDURE CODE id-enhancedRelocationComplete
+ CRITICALITY reject
+}
+
+enhancedRelocationCompleteConfirm RANAP-ELEMENTARY-PROCEDURE ::= {
+ INITIATING MESSAGE EnhancedRelocationCompleteConfirm
+ PROCEDURE CODE id-enhancedRelocationCompleteConfirm
+ CRITICALITY ignore
+}
+
+rANAP-enhancedRelocation RANAP-ELEMENTARY-PROCEDURE ::= {
+ INITIATING MESSAGE RANAP-EnhancedRelocationInformationRequest
+ SUCCESSFUL OUTCOME RANAP-EnhancedRelocationInformationResponse
+ PROCEDURE CODE id-RANAPenhancedRelocation
+ CRITICALITY reject
+}
+
+sRVCCPreparation RANAP-ELEMENTARY-PROCEDURE ::= {
+ INITIATING MESSAGE SRVCC-CSKeysRequest
+ OUTCOME SRVCC-CSKeysResponse
+ PROCEDURE CODE id-SRVCCPreparation
+ CRITICALITY reject
+}
+
+END
+
+
+
diff --git a/lib/asn1/test/asn1_SUITE_data/RANAP.asn1 b/lib/asn1/test/asn1_SUITE_data/RANAP.asn1
new file mode 100644
index 0000000000..55fb58b163
--- /dev/null
+++ b/lib/asn1/test/asn1_SUITE_data/RANAP.asn1
@@ -0,0 +1,3237 @@
+RANAP DEFINITIONS AUTOMATIC TAGS ::=
+BEGIN
+-- **************************************************************
+--
+-- Common definitions
+--
+-- **************************************************************
+
+-- RANAP-CommonDataTypes { object identifier to be allocated }--
+-- DEFINITIONS AUTOMATIC TAGS ::=
+
+-- BEGIN
+
+Criticality ::= ENUMERATED { reject, ignore, notify }
+
+Presence ::= ENUMERATED { optional, conditional, mandatory }
+
+PrivateIE-ID ::= CHOICE {
+ local INTEGER (0..65535),
+ global OBJECT IDENTIFIER
+}
+
+ProcedureCode ::= INTEGER (0..255)
+
+ProtocolExtensionID ::= INTEGER (0..65535)
+
+ProtocolIE-ID ::= INTEGER (0..65535)
+
+TriggeringMessage ::= ENUMERATED { initiating-message, successful-outcome, unsuccessfull-outcome, outcome }
+
+-- END
+-- **************************************************************
+--
+-- Constant definitions
+--
+-- **************************************************************
+
+-- RANAP-Constants { object identifier to be allocated }--
+-- DEFINITIONS AUTOMATIC TAGS ::=
+
+-- BEGIN
+
+-- **************************************************************
+--
+-- Elementary Procedures
+--
+-- **************************************************************
+
+id-RAB-Assignment INTEGER ::= 0
+id-Iu-Release INTEGER ::= 1
+id-RelocationPreparation INTEGER ::= 2
+id-RelocationResourceAllocation INTEGER ::= 3
+id-RelocationCancel INTEGER ::= 4
+id-SRNS-ContextTransfer INTEGER ::= 5
+id-SecurityModeControl INTEGER ::= 6
+id-DataVolumeReport INTEGER ::= 7
+id-CN-InformationBroadcast INTEGER ::= 8
+id-Reset INTEGER ::= 9
+id-RAB-ReleaseRequest INTEGER ::= 10
+id-Iu-ReleaseRequest INTEGER ::= 11
+id-RelocationDetect INTEGER ::= 12
+id-RelocationComplete INTEGER ::= 13
+id-Paging INTEGER ::= 14
+id-CommonID INTEGER ::= 15
+id-CN-InvokeTrace INTEGER ::= 16
+id-LocationReportingControl INTEGER ::= 17
+id-LocationReport INTEGER ::= 18
+id-InitialUE-Message INTEGER ::= 19
+id-DirectTransfer INTEGER ::= 20
+id-OverloadControl INTEGER ::= 21
+id-ErrorIndication INTEGER ::= 22
+id-SRNS-DataForward INTEGER ::= 23
+id-ForwardSRNS-Context INTEGER ::= 24
+id-privateMessage INTEGER ::= 25
+id-CN-DeactivateTrace INTEGER ::= 26
+id-ResetResource INTEGER ::= 27
+id-RANAP-Relocation INTEGER ::= 28
+
+-- **************************************************************
+--
+-- Extension constants
+--
+-- **************************************************************
+
+maxPrivateIEs INTEGER ::= 65535
+maxProtocolExtensions INTEGER ::= 65535
+maxProtocolIEs INTEGER ::= 65535
+
+-- **************************************************************
+--
+-- Lists
+--
+-- **************************************************************
+
+maxNrOfDTs INTEGER ::= 15
+maxNrOfErrors INTEGER ::= 256
+maxNrOfIuSigConIds INTEGER ::= 1000
+maxNrOfPDPDirections INTEGER ::= 2
+maxNrOfPieces INTEGER ::= 16
+maxNrOfPoints INTEGER ::= 15
+maxNrOfRABs INTEGER ::= 256
+maxNrOfSeparateTrafficDirections INTEGER ::= 2
+maxNrOfVol INTEGER ::= 2
+
+maxRAB-Subflows INTEGER ::= 7
+maxRAB-SubflowCombination INTEGER ::= 64
+
+-- **************************************************************
+--
+-- IEs
+--
+-- **************************************************************
+
+id-AreaIdentity INTEGER ::= 0
+id-CN-BroadcastInformationPiece INTEGER ::= 1
+id-CN-BroadcastInformationPieceList INTEGER ::= 2
+id-CN-DomainIndicator INTEGER ::= 3
+id-Cause INTEGER ::= 4
+id-ChosenEncryptionAlgorithm INTEGER ::= 5
+id-ChosenIntegrityProtectionAlgorithm INTEGER ::= 6
+id-ClassmarkInformation2 INTEGER ::= 7
+id-ClassmarkInformation3 INTEGER ::= 8
+id-CriticalityDiagnostics INTEGER ::= 9
+id-DL-GTP-PDU-SequenceNumber INTEGER ::= 10
+id-EncryptionInformation INTEGER ::= 11
+id-IntegrityProtectionInformation INTEGER ::= 12
+id-IuTransportAssociation INTEGER ::= 13
+id-L3-Information INTEGER ::= 14
+id-LAI INTEGER ::= 15
+id-NAS-PDU INTEGER ::= 16
+id-NonSearchingIndication INTEGER ::= 17
+id-NumberOfSteps INTEGER ::= 18
+id-OMC-ID INTEGER ::= 19
+id-OldBSS-ToNewBSS-Information INTEGER ::= 20
+id-PagingAreaID INTEGER ::= 21
+id-PagingCause INTEGER ::= 22
+id-PermanentNAS-UE-ID INTEGER ::= 23
+id-RAB-ContextItem INTEGER ::= 24
+id-RAB-ContextList INTEGER ::= 25
+id-RAB-DataForwardingItem INTEGER ::= 26
+id-RAB-DataForwardingItem-SRNS-CtxReq INTEGER ::= 27
+id-RAB-DataForwardingList INTEGER ::= 28
+id-RAB-DataForwardingList-SRNS-CtxReq INTEGER ::= 29
+id-RAB-DataVolumeReportItem INTEGER ::= 30
+id-RAB-DataVolumeReportList INTEGER ::= 31
+id-RAB-DataVolumeReportRequestItem INTEGER ::= 32
+id-RAB-DataVolumeReportRequestList INTEGER ::= 33
+id-RAB-FailedItem INTEGER ::= 34
+id-RAB-FailedList INTEGER ::= 35
+id-RAB-ID INTEGER ::= 36
+id-RAB-QueuedItem INTEGER ::= 37
+id-RAB-QueuedList INTEGER ::= 38
+id-RAB-ReleaseFailedList INTEGER ::= 39
+id-RAB-ReleaseItem INTEGER ::= 40
+id-RAB-ReleaseList INTEGER ::= 41
+id-RAB-ReleasedItem INTEGER ::= 42
+id-RAB-ReleasedList INTEGER ::= 43
+id-RAB-ReleasedList-IuRelComp INTEGER ::= 44
+id-RAB-RelocationReleaseItem INTEGER ::= 45
+id-RAB-RelocationReleaseList INTEGER ::= 46
+id-RAB-SetupItem-RelocReq INTEGER ::= 47
+id-RAB-SetupItem-RelocReqAck INTEGER ::= 48
+id-RAB-SetupList-RelocReq INTEGER ::= 49
+id-RAB-SetupList-RelocReqAck INTEGER ::= 50
+id-RAB-SetupOrModifiedItem INTEGER ::= 51
+id-RAB-SetupOrModifiedList INTEGER ::= 52
+id-RAB-SetupOrModifyItem INTEGER ::= 53
+id-RAB-SetupOrModifyList INTEGER ::= 54
+id-RAC INTEGER ::= 55
+id-RelocationType INTEGER ::= 56
+id-RequestType INTEGER ::= 57
+id-SAI INTEGER ::= 58
+id-SAPI INTEGER ::= 59
+id-SourceID INTEGER ::= 60
+id-SourceRNC-ToTargetRNC-TransparentContainer INTEGER ::= 61
+id-TargetID INTEGER ::= 62
+id-TargetRNC-ToSourceRNC-TransparentContainer INTEGER ::= 63
+id-TemporaryUE-ID INTEGER ::= 64
+id-TraceReference INTEGER ::= 65
+id-TraceType INTEGER ::= 66
+id-TransportLayerAddress INTEGER ::= 67
+id-TriggerID INTEGER ::= 68
+id-UE-ID INTEGER ::= 69
+id-UL-GTP-PDU-SequenceNumber INTEGER ::= 70
+id-RAB-FailedtoReportItem INTEGER ::= 71
+id-RAB-FailedtoReportList INTEGER ::= 72
+id-KeyStatus INTEGER ::= 75
+id-DRX-CycleLengthCoefficient INTEGER ::= 76
+id-IuSigConIdList INTEGER ::= 77
+id-IuSigConIdItem INTEGER ::= 78
+id-IuSigConId INTEGER ::= 79
+id-DirectTransferInformationItem-RANAP-RelocInf INTEGER ::= 80
+id-DirectTransferInformationList-RANAP-RelocInf INTEGER ::= 81
+id-RAB-ContextItem-RANAP-RelocInf INTEGER ::= 82
+id-RAB-ContextList-RANAP-RelocInf INTEGER ::= 83
+id-RAB-ContextFailedtoTransferItem INTEGER ::= 84
+id-RAB-ContextFailedtoTransferList INTEGER ::= 85
+id-GlobalRNC-ID INTEGER ::= 86
+id-RAB-ReleasedItem-IuRelComp INTEGER ::= 87
+
+-- END **************************************************************
+--
+-- Container definitions
+--
+-- **************************************************************
+
+-- RANAP-Containers { object identifier to be allocated }--
+-- DEFINITIONS AUTOMATIC TAGS ::=
+
+-- BEGIN
+
+-- **************************************************************
+--
+-- IE parameter types from other modules.
+--
+-- **************************************************************
+
+-- **************************************************************
+--
+-- Class Definition for Protocol IEs
+--
+-- **************************************************************
+
+RANAP-PROTOCOL-IES ::= CLASS {
+ &id ProtocolIE-ID UNIQUE,
+ &criticality Criticality,
+ &Value,
+ &presence Presence
+}
+WITH SYNTAX {
+ ID &id
+ CRITICALITY &criticality
+ TYPE &Value
+ PRESENCE &presence
+}
+
+-- **************************************************************
+--
+-- Class Definition for Protocol IEs
+--
+-- **************************************************************
+
+RANAP-PROTOCOL-IES-PAIR ::= CLASS {
+ &id ProtocolIE-ID UNIQUE,
+ &firstCriticality Criticality,
+ &FirstValue,
+ &secondCriticality Criticality,
+ &SecondValue,
+ &presence Presence
+}
+WITH SYNTAX {
+ ID &id
+ FIRST CRITICALITY &firstCriticality
+ FIRST TYPE &FirstValue
+ SECOND CRITICALITY &secondCriticality
+ SECOND TYPE &SecondValue
+ PRESENCE &presence
+}
+
+-- **************************************************************
+--
+-- Class Definition for Protocol Extensions
+--
+-- **************************************************************
+
+RANAP-PROTOCOL-EXTENSION ::= CLASS {
+ &id ProtocolExtensionID UNIQUE,
+ &criticality Criticality,
+ &Extension,
+ &presence Presence
+}
+WITH SYNTAX {
+ ID &id
+ CRITICALITY &criticality
+ EXTENSION &Extension
+ PRESENCE &presence
+}
+
+-- **************************************************************
+--
+-- Class Definition for Private IEs
+--
+-- **************************************************************
+
+RANAP-PRIVATE-IES ::= CLASS {
+ &id PrivateIE-ID,
+ &criticality Criticality,
+ &Value,
+ &presence Presence
+}
+WITH SYNTAX {
+ ID &id
+ CRITICALITY &criticality
+ TYPE &Value
+ PRESENCE &presence
+}
+
+-- **************************************************************
+--
+-- Container for Protocol IEs
+--
+-- **************************************************************
+
+ProtocolIE-Container {RANAP-PROTOCOL-IES : IEsSetParam} ::=
+ SEQUENCE (SIZE (0..maxProtocolIEs)) OF
+ ProtocolIE-Field {{IEsSetParam}}
+
+ProtocolIE-Field {RANAP-PROTOCOL-IES : IEsSetParam} ::= SEQUENCE {
+ id RANAP-PROTOCOL-IES.&id ({IEsSetParam}),
+ criticality RANAP-PROTOCOL-IES.&criticality ({IEsSetParam}{@id}),
+ value RANAP-PROTOCOL-IES.&Value ({IEsSetParam}{@id})
+}
+
+-- **************************************************************
+--
+-- Container for Protocol IE Pairs
+--
+-- **************************************************************
+
+ProtocolIE-ContainerPair {RANAP-PROTOCOL-IES-PAIR : IEsSetParam} ::=
+ SEQUENCE (SIZE (0..maxProtocolIEs)) OF
+ ProtocolIE-FieldPair {{IEsSetParam}}
+
+ProtocolIE-FieldPair {RANAP-PROTOCOL-IES-PAIR : IEsSetParam} ::= SEQUENCE {
+ id RANAP-PROTOCOL-IES-PAIR.&id ({IEsSetParam}),
+ firstCriticality RANAP-PROTOCOL-IES-PAIR.&firstCriticality ({IEsSetParam}{@id}),
+ firstValue RANAP-PROTOCOL-IES-PAIR.&FirstValue ({IEsSetParam}{@id}),
+ secondCriticality RANAP-PROTOCOL-IES-PAIR.&secondCriticality ({IEsSetParam}{@id}),
+ secondValue RANAP-PROTOCOL-IES-PAIR.&SecondValue ({IEsSetParam}{@id})
+}
+
+-- **************************************************************
+--
+-- Container Lists for Protocol IE Containers
+--
+-- **************************************************************
+
+ProtocolIE-ContainerList {INTEGER : lowerBound, INTEGER : upperBound, RANAP-PROTOCOL-IES : IEsSetParam} ::=
+ SEQUENCE (SIZE (lowerBound..upperBound)) OF
+ ProtocolIE-Container {{IEsSetParam}}
+
+ProtocolIE-ContainerPairList {INTEGER : lowerBound, INTEGER : upperBound, RANAP-PROTOCOL-IES-PAIR : IEsSetParam} ::=
+ SEQUENCE (SIZE (lowerBound..upperBound)) OF
+ ProtocolIE-ContainerPair {{IEsSetParam}}
+
+-- **************************************************************
+--
+-- Container for Protocol Extensions
+--
+-- **************************************************************
+
+ProtocolExtensionContainer {RANAP-PROTOCOL-EXTENSION : ExtensionSetParam} ::=
+ SEQUENCE (SIZE (1..maxProtocolExtensions)) OF
+ ProtocolExtensionField {{ExtensionSetParam}}
+
+ProtocolExtensionField {RANAP-PROTOCOL-EXTENSION : ExtensionSetParam} ::= SEQUENCE {
+ id RANAP-PROTOCOL-EXTENSION.&id ({ExtensionSetParam}),
+ criticality RANAP-PROTOCOL-EXTENSION.&criticality ({ExtensionSetParam}{@id}),
+ extensionValue RANAP-PROTOCOL-EXTENSION.&Extension ({ExtensionSetParam}{@id})
+}
+
+-- **************************************************************
+--
+-- Container for Private IEs
+--
+-- **************************************************************
+
+PrivateIE-Container {RANAP-PRIVATE-IES : IEsSetParam } ::=
+ SEQUENCE (SIZE (1.. maxPrivateIEs)) OF
+ PrivateIE-Field {{IEsSetParam}}
+
+PrivateIE-Field {RANAP-PRIVATE-IES : IEsSetParam} ::= SEQUENCE {
+ id RANAP-PRIVATE-IES.&id ({IEsSetParam}),
+ criticality RANAP-PRIVATE-IES.&criticality ({IEsSetParam}{@id}),
+ value RANAP-PRIVATE-IES.&Value ({IEsSetParam}{@id})
+}
+
+-- END **************************************************************
+--
+-- Information Element Definitions
+--
+-- **************************************************************
+
+-- RANAP-IEs { object identifier to be allocated }--
+-- DEFINITIONS AUTOMATIC TAGS ::=
+
+-- BEGIN
+
+-- A
+
+AllocationOrRetentionPriority ::= SEQUENCE {
+ priorityLevel PriorityLevel,
+ pre-emptionCapability Pre-emptionCapability,
+ pre-emptionVulnerability Pre-emptionVulnerability,
+ queuingAllowed QueuingAllowed,
+ iE-Extensions ProtocolExtensionContainer { {AllocationOrRetentionPriority-ExtIEs} } OPTIONAL,
+ ...
+}
+
+AllocationOrRetentionPriority-ExtIEs RANAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+AreaIdentity ::= CHOICE {
+ sAI SAI,
+ geographicalArea GeographicalArea,
+ ...
+}
+
+-- B
+
+BindingID ::= OCTET STRING (SIZE (4))
+
+-- C
+
+
+Cause ::= CHOICE {
+ radioNetwork CauseRadioNetwork,
+ transmissionNetwork CauseTransmissionNetwork,
+ nAS CauseNAS,
+ protocol CauseProtocol,
+ misc CauseMisc,
+ non-Standard CauseNon-Standard,
+ ...
+}
+
+CauseMisc ::= INTEGER {
+ om-intervention (113),
+ no-resource-available (114),
+ unspecified-failure (115),
+ network-optimisation (116)
+} (113..128)
+
+CauseNAS ::= INTEGER {
+ user-restriction-start-indication (81),
+ user-restriction-end-indication (82),
+ normal-release (83)
+} (81..96)
+
+CauseProtocol ::= INTEGER {
+ transfer-syntax-error (97),
+ semantic-error (98),
+ message-not-compatible-with-receiver-state (99),
+ abstract-syntax-error-reject (100),
+ abstract-syntax-error-ignore-and-notify (101)
+
+} (97..112)
+
+CauseRadioNetwork ::= INTEGER {
+ rab-pre-empted (1),
+ trelocoverall-expiry (2),
+ trelocprep-expiry (3),
+ treloccomplete-expiry (4),
+ tqueing-expiry (5),
+ relocation-triggered (6),
+ trellocalloc-expiry(7),
+ unable-to-establish-during-relocation (8),
+ unknown-target-rnc (9),
+ relocation-cancelled (10),
+ successful-relocation (11),
+ requested-ciphering-and-or-integrity-protection-algorithms-not-supported (12),
+ change-of-ciphering-and-or-integrity-protection-is-not-supported (13),
+ failure-in-the-radio-interface-procedure (14),
+ release-due-to-utran-generated-reason (15),
+ user-inactivity (16),
+ time-critical-relocation (17),
+ requested-traffic-class-not-available (18),
+ invalid-rab-parameters-value (19),
+ requested-maximum-bit-rate-not-available (20),
+ requested-guaranteed-bit-rate-not-available (21),
+ requested-transfer-delay-not-achievable (22),
+ invalid-rab-parameters-combination (23),
+ condition-violation-for-sdu-parameters (24),
+ condition-violation-for-traffic-handling-priority (25),
+ condition-violation-for-guaranteed-bit-rate (26),
+ user-plane-versions-not-supported (27),
+ iu-up-failure (28),
+ relocation-failure-in-target-CN-RNC-or-target-system(29),
+ invalid-RAB-ID (30),
+ no-remaining-rab (31),
+ interaction-with-other-procedure (32),
+ requested-maximum-bit-rate-for-dl-not-available (33),
+ requested-maximum-bitr-ate-for-ul-not-available (34),
+ requested-guaranteed-bit-rate-for-dl-not-available (35),
+ requested-guaranteed-bit-rate-for-ul-not-available (36),
+ repeated-integrity-checking-failure (37),
+ requested-report-type-not-supported (38),
+ request-superseded (39),
+ release-due-to-UE-generated-signalling-connection-release (40)
+} (1..64)
+
+CauseNon-Standard ::= INTEGER (129..256)
+
+CauseTransmissionNetwork ::= INTEGER {
+ logical-error-unknown-iu-transport-association (65)
+} (65..80)
+
+
+CriticalityDiagnostics ::= SEQUENCE {
+ procedureCode ProcedureCode OPTIONAL,
+ triggeringMessage TriggeringMessage OPTIONAL,
+ criticalityResponse Criticality OPTIONAL,
+ iEsCriticalityResponses CriticalityDiagnostics-IE-List OPTIONAL,
+ iE-Extensions ProtocolExtensionContainer { {CriticalityDiagnostics-ExtIEs} } OPTIONAL,
+ ...
+}
+
+CriticalityDiagnostics-ExtIEs RANAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+CriticalityDiagnostics-IE-List ::= SEQUENCE (SIZE (1..maxNrOfErrors)) OF
+ SEQUENCE {
+ criticalityResponse Criticality,
+ iE-ID ProtocolIE-ID,
+ repetitionNumber RepetitionNumber OPTIONAL,
+ iE-Extensions ProtocolExtensionContainer { {CriticalityDiagnostics-IE-List-ExtIEs} } OPTIONAL,
+ ...
+ }
+
+CriticalityDiagnostics-IE-List-ExtIEs RANAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+CGI ::= SEQUENCE {
+ pLMN-ID PLMN-ID,
+ lAC LAC,
+ cI CI,
+ iE-Extensions ProtocolExtensionContainer { {CGI-ExtIEs} } OPTIONAL
+}
+
+CGI-ExtIEs RANAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+ChosenEncryptionAlgorithm ::= EncryptionAlgorithm
+
+ChosenIntegrityProtectionAlgorithm ::= IntegrityProtectionAlgorithm
+
+CI ::= OCTET STRING (SIZE (2))
+
+ClassmarkInformation2 ::= OCTET STRING
+
+ClassmarkInformation3 ::= OCTET STRING
+
+CN-DomainIndicator ::= ENUMERATED {
+ cs-domain,
+ ps-domain
+}
+
+
+CN-BroadcastArea ::= CHOICE {
+ lAI LAI,
+ rAI RAI,
+ sAI SAI,
+ geographicalArea GeographicalArea,
+ ...
+}
+
+-- D
+
+DataVolumeReference ::= INTEGER (0..255)
+
+DataVolumeReportingIndication ::= ENUMERATED {
+ do-report,
+ do-not-report
+}
+
+DCH-ID ::= INTEGER (0..255)
+
+DeliveryOfErroneousSDU ::= ENUMERATED {
+ yes,
+ no,
+ no-error-detection-consideration
+}
+
+DeliveryOrder::= ENUMERATED {
+ delivery-order-requested,
+ delivery-order-not-requested
+}
+
+DL-GTP-PDU-SequenceNumber ::= INTEGER (0..65535)
+-- Reference: xx.xxx
+
+DL-N-PDU-SequenceNumber ::= INTEGER (0..65535)
+-- Reference: xx.xxx
+
+D-RNTI ::= INTEGER (0..1048575)
+
+DRX-CycleLengthCoefficient ::= INTEGER (2..12)
+DSCH-ID ::= INTEGER (0..255)
+
+-- E
+
+EncryptionAlgorithm ::= INTEGER { no-encryption (0), standard-UMTS-encryption-algorith-UEA1 (1) } (0..15)
+
+EncryptionInformation ::= SEQUENCE {
+ permittedAlgorithms PermittedEncryptionAlgorithms,
+ key EncryptionKey,
+ iE-Extensions ProtocolExtensionContainer { {EncryptionInformation-ExtIEs} } OPTIONAL
+}
+
+EncryptionInformation-ExtIEs RANAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+EncryptionKey ::= BIT STRING (SIZE (128))
+-- Reference: 33.102
+
+Event ::= ENUMERATED {
+ stop,
+ direct,
+ change-of-servicearea,
+ ...
+}
+
+-- F
+-- G
+
+GeographicalArea ::= CHOICE {
+ point GA-Point,
+ pointWithUnCertainty GA-PointWithUnCertainty,
+ polygon GA-Polygon,
+ ...
+}
+
+GeographicalCoordinates ::= SEQUENCE {
+ latitudeSign ENUMERATED { north, south },
+ latitude INTEGER (0..8388607),
+ longitude INTEGER (-8388608..8388607),
+ iE-Extensions ProtocolExtensionContainer { {GeographicalCoordinates-ExtIEs} } OPTIONAL,
+ ...
+}
+
+GeographicalCoordinates-ExtIEs RANAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+GA-Point ::= SEQUENCE {
+ geographicalCoordinates GeographicalCoordinates,
+ iE-Extensions ProtocolExtensionContainer { {GA-Point-ExtIEs} } OPTIONAL,
+ ...
+}
+
+GA-Point-ExtIEs RANAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+GA-PointWithUnCertainty ::=SEQUENCE {
+ geographicalCoordinates GeographicalCoordinates,
+ iE-Extensions ProtocolExtensionContainer { {GA-PointWithUnCertainty-ExtIEs} } OPTIONAL,
+ uncertaintyCode INTEGER (0..127)
+}
+
+GA-PointWithUnCertainty-ExtIEs RANAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+GA-Polygon ::= SEQUENCE (SIZE (1..maxNrOfPoints)) OF
+ SEQUENCE {
+ geographicalCoordinates GeographicalCoordinates,
+ iE-Extensions ProtocolExtensionContainer { {GA-Polygon-ExtIEs} } OPTIONAL,
+ ...
+ }
+
+GA-Polygon-ExtIEs RANAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+GlobalRNC-ID ::= SEQUENCE {
+ pLMN-ID PLMN-ID,
+ rNC-ID RNC-ID
+}
+
+GTP-TEI ::= OCTET STRING (SIZE (4))
+-- Reference: xx.xxx
+
+GuaranteedBitrate ::= INTEGER (0..16000000)
+-- Unit is bits per sec
+
+-- H
+
+-- I
+InformationIdentity ::= INTEGER (0..255)
+
+InformationPriority ::= INTEGER (0..15)
+
+InformationControl ::= ENUMERATED {
+ on,
+ off
+}
+
+
+IMEI ::= OCTET STRING (SIZE (8))
+-- Reference: 23.003
+
+IMSI ::= TBCD-STRING (SIZE (3..8))
+-- Reference: 23.003
+
+IntegrityProtectionAlgorithm ::= INTEGER { standard-UMTS-integrity-algorithm-UIA1 (0) } (0..15)
+
+IntegrityProtectionInformation ::= SEQUENCE {
+ permittedAlgorithms PermittedIntegrityProtectionAlgorithms,
+ key IntegrityProtectionKey,
+ iE-Extensions ProtocolExtensionContainer { {IntegrityProtectionInformation-ExtIEs} } OPTIONAL
+}
+
+IntegrityProtectionInformation-ExtIEs RANAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+IntegrityProtectionKey ::= BIT STRING (SIZE (128))
+
+IuSignallingConnectionIdentifier ::= BIT STRING (SIZE (24))
+
+IuTransportAssociation ::= CHOICE {
+ gTP-TEI GTP-TEI,
+ bindingID BindingID,
+ ...
+}
+
+-- J
+-- K
+
+KeyStatus ::= ENUMERATED {
+ old,
+ new,
+ ...
+}
+-- L
+
+LAC ::= OCTET STRING (SIZE (2))
+
+LAI ::= SEQUENCE {
+ pLMN-ID PLMN-ID,
+ lAC LAC,
+ iE-Extensions ProtocolExtensionContainer { {LAI-ExtIEs} } OPTIONAL
+}
+
+LAI-ExtIEs RANAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+L3-Information ::= OCTET STRING
+
+-- M
+
+MaxBitrate ::= INTEGER (1..16000000)
+-- Unit is bits per sec
+
+MaxSDU-Size ::= INTEGER (0..32768)
+-- MaxSDU-Size
+-- Unit is bit
+
+MCC ::= TBCD-STRING (SIZE (2))
+-- Reference: 24.008
+
+MNC ::= TBCD-STRING (SIZE (2))
+-- Reference: 24.008
+
+-- N
+
+
+NAS-BroadcastInformation ::= OCTET STRING
+
+NAS-PDU ::= OCTET STRING
+
+NAS-SynchronisationIndicator ::= BIT STRING (SIZE (4))
+
+NonSearchingIndication ::= ENUMERATED {
+ non-searching,
+ searching
+}
+
+NumberOfIuInstances ::= INTEGER (1..2)
+
+NumberOfSteps ::= INTEGER (1..16)
+
+-- O
+
+OldBSS-ToNewBSS-Information ::= OCTET STRING
+
+OMC-ID ::= OCTET STRING (SIZE (3..22))
+-- Reference: GSM TS 12.20
+
+-- P
+
+PagingAreaID ::= CHOICE {
+ lAI LAI,
+ rAI RAI,
+ ...
+}
+
+PagingCause ::= ENUMERATED {
+ speech-call,
+ cs-data-call,
+ ps-data-call,
+ sms,
+ ...
+}
+
+PDP-TypeInformation ::= SEQUENCE (SIZE (1..maxNrOfPDPDirections)) OF
+ PDP-Type
+
+PDP-Type ::= ENUMERATED {
+ empty,
+ ppp,
+ osp-ihoss -- this value is used for OSP:IHOSS -- ,
+ ipv4,
+ ipv6,
+ ...
+}
+
+PermanentNAS-UE-ID ::= CHOICE {
+ iMSI IMSI,
+ ...
+}
+
+PermittedEncryptionAlgorithms ::= SEQUENCE (SIZE (1..16)) OF
+ EncryptionAlgorithm
+
+PermittedIntegrityProtectionAlgorithms ::= SEQUENCE (SIZE (1..16)) OF
+ IntegrityProtectionAlgorithm
+
+PLMN-ID ::= TBCD-STRING (SIZE (3))
+
+Pre-emptionCapability ::= ENUMERATED {
+ can-not-trigger-pre-emption,
+ can-trigger-pre-emption
+}
+
+Pre-emptionVulnerability ::= ENUMERATED {
+ not-vulnerable-to-pre-emption,
+ vulnerable-to-pre-emption
+}
+
+PriorityLevel ::= INTEGER { spare (0), highest (1), lowest (14), no-priority (15) } (0..15)
+
+P-TMSI ::= OCTET STRING (SIZE (4))
+
+-- Q
+
+QueuingAllowed ::= ENUMERATED {
+ queueing-not-allowed,
+ queueing-allowed
+}
+
+-- R
+RAB-AsymmetryIndicator::= ENUMERATED {
+ symmetric-bidirectional,
+ asymmetric-unidirectional-downlink,
+ asymmetric-unidirectional-uplink,
+ asymmetric-bidirectional,
+ ...
+}
+
+RAB-ID ::= BIT STRING (SIZE (8))
+
+RAB-Parameter-GuaranteedBitrateList ::= SEQUENCE (SIZE (1..maxNrOfSeparateTrafficDirections)) OF GuaranteedBitrate
+
+RAB-Parameter-MaxBitrateList ::= SEQUENCE (SIZE (1..maxNrOfSeparateTrafficDirections)) OF MaxBitrate
+
+RAB-Parameters ::= SEQUENCE {
+ trafficClass TrafficClass,
+ rAB-AsymmetryIndicator RAB-AsymmetryIndicator,
+ maxBitrate RAB-Parameter-MaxBitrateList,
+ guaranteedBitRate RAB-Parameter-GuaranteedBitrateList OPTIONAL
+ -- This IE is only present when traffic class indicates Conversational or Streaming --,
+ deliveryOrder DeliveryOrder,
+ maxSDU-Size MaxSDU-Size,
+ sDU-Parameters SDU-Parameters,
+ transferDelay TransferDelay OPTIONAL
+ -- This IE is only present when traffic class indicates Conversational or Streaming --,
+ trafficHandlingPriority TrafficHandlingPriority OPTIONAL
+ -- This IE is only present when traffic class indicates Interactiv --,
+ allocationOrRetentionPriority AllocationOrRetentionPriority OPTIONAL,
+ sourceStatisticsDescriptor SourceStatisticsDescriptor OPTIONAL
+ -- This IE is only present when traffic class indicates Conversational or Streaming --,
+ iE-Extensions ProtocolExtensionContainer { {RAB-Parameters-ExtIEs} } OPTIONAL,
+ ...
+}
+
+RAB-Parameters-ExtIEs RANAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+RAB-SubflowCombinationBitRate ::= INTEGER (0..16000000)
+
+RAB-TrCH-Mapping ::= SEQUENCE ( SIZE (1..maxNrOfRABs)) OF
+ RAB-TrCH-MappingItem
+
+RAB-TrCH-MappingItem ::= SEQUENCE {
+ rAB-ID RAB-ID,
+ trCH-ID-List TrCH-ID-List,
+ ...
+}
+
+RAC ::= OCTET STRING (SIZE (1))
+
+RAI ::= SEQUENCE {
+ lAI LAI,
+ rAC RAC,
+ iE-Extensions ProtocolExtensionContainer { {RAI-ExtIEs} } OPTIONAL,
+ ...
+}
+
+RAI-ExtIEs RANAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+RateControlAllowed ::= ENUMERATED {
+ not-allowed,
+ allowed
+}
+
+RelocationType ::= ENUMERATED {
+ ue-not-involved,
+ ue-involved,
+ ...
+}
+
+RepetitionNumber ::= INTEGER (0..255)
+
+ReportArea ::= ENUMERATED {
+ service-area,
+ geographical-coordinates,
+ ...
+}
+
+RequestType ::= SEQUENCE {
+ event Event,
+ reportArea ReportArea,
+ accuracyCode INTEGER (0..127) OPTIONAL,
+ -- To be used if Geographical Coordinates shall be reported with a requested accuracy. --
+ ...
+}
+
+ResidualBitErrorRatio ::= SEQUENCE {
+ mantissa INTEGER (1..9),
+ exponent INTEGER (1..8),
+ iE-Extensions ProtocolExtensionContainer { {ResidualBitErrorRatio-ExtIEs} } OPTIONAL
+}
+-- ResidualBitErrorRatio = mantissa * 10^-exponent
+
+ResidualBitErrorRatio-ExtIEs RANAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+RNC-ID ::= INTEGER (0..4095)
+-- RNC-ID ::= BIT STRING (SIZE (12))
+-- Harmonized with RNSAP and NBAP definitions
+
+RRC-Container ::= OCTET STRING
+
+-- S
+
+SAC ::= OCTET STRING (SIZE (2))
+
+SAI ::= SEQUENCE {
+ pLMN-ID PLMN-ID,
+ lAC LAC,
+ sAC SAC,
+ iE-Extensions ProtocolExtensionContainer { {SAI-ExtIEs} } OPTIONAL
+}
+
+SAI-ExtIEs RANAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+SAPI ::= ENUMERATED {
+ normal-priority,
+ low-priority,
+ ...
+}
+
+SDU-ErrorRatio ::= SEQUENCE {
+ mantissa INTEGER (1..9),
+ exponent INTEGER (1..6),
+ iE-Extensions ProtocolExtensionContainer { {SDU-ErrorRatio-ExtIEs} } OPTIONAL
+}
+-- SDU-ErrorRatio = mantissa * 10^-exponent
+
+SDU-ErrorRatio-ExtIEs RANAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+SDU-FormatInformationParameters ::= SEQUENCE (SIZE (1..maxRAB-SubflowCombination)) OF
+ SEQUENCE {
+ subflowSDU-Size SubflowSDU-Size OPTIONAL
+ -- This IE is only present for RABs that have predefined SDU size(s) --,
+ rAB-SubflowCombinationBitRate RAB-SubflowCombinationBitRate OPTIONAL
+ -- At least either of subflowSDU-Size or rABsubflowCombinationBitRate --
+ -- shall be present when SDUformatInformationParameter is present --,
+ iE-Extensions ProtocolExtensionContainer { {SDU-FormatInformationParameters-ExtIEs} } OPTIONAL,
+ ...
+ }
+
+SDU-FormatInformationParameters-ExtIEs RANAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+SDU-Parameters ::= SEQUENCE (SIZE (1..maxRAB-Subflows)) OF
+ SEQUENCE {
+ sDU-ErrorRatio SDU-ErrorRatio OPTIONAL
+ -- This IE is not present when DeliveryOfErroneousSDU is set to no-error-detection-consideration --,
+ residualBitErrorRatio ResidualBitErrorRatio,
+ deliveryOfErroneousSDU DeliveryOfErroneousSDU,
+ sDU-FormatInformationParameters SDU-FormatInformationParameters OPTIONAL
+ -- When signalled, this IE indicates that the RAB is rate controllable --,
+ iE-Extensions ProtocolExtensionContainer { {SDU-Parameters-ExtIEs} } OPTIONAL,
+ ...
+ }
+
+SDU-Parameters-ExtIEs RANAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+SourceID ::= CHOICE {
+ sourceRNC-ID SourceRNC-ID, -- If UMTS target
+ sAI SAI, -- if GSM target
+ ...
+}
+
+
+SourceRNC-ID ::= SEQUENCE {
+ pLMN-ID PLMN-ID,
+ rNC-ID RNC-ID,
+ iE-Extensions ProtocolExtensionContainer { {SourceRNC-ID-ExtIEs} } OPTIONAL
+}
+
+SourceRNC-ID-ExtIEs RANAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+SourceRNC-ToTargetRNC-TransparentContainer ::= SEQUENCE {
+ rRC-Container RRC-Container,
+ numberOfIuInstances NumberOfIuInstances,
+ relocationType RelocationType,
+ chosenIntegrityProtectionAlgorithm ChosenIntegrityProtectionAlgorithm OPTIONAL
+ -- Must be present for intra UMTS Handovers if available --,
+ integrityProtectionKey IntegrityProtectionKey OPTIONAL
+ -- Must be present for intra UMTS Handovers if available --,
+ chosenEncryptionAlgorithForSignalling ChosenEncryptionAlgorithm OPTIONAL
+ -- Must be present for intra UMTS Handovers if ciphering is active --,
+ cipheringKey EncryptionKey OPTIONAL
+ -- Must be present for intra UMTS Handovers if ciphering is active --,
+ chosenEncryptionAlgorithForCS ChosenEncryptionAlgorithm OPTIONAL
+ -- Must be present for intra UMTS Handovers if ciphering is active --,
+ chosenEncryptionAlgorithForPS ChosenEncryptionAlgorithm OPTIONAL
+ -- Must be present for intra UMTS Handovers if ciphering is active --,
+ d-RNTI D-RNTI OPTIONAL
+ -- Included for SRNS Relocation without UE involvement --,
+ targetCellId TargetCellId OPTIONAL
+ -- Included for SRNS Relocation with UE involvement --,
+ rAB-TrCH-Mapping RAB-TrCH-Mapping OPTIONAL
+ -- Included for SRNS Relocation without UE involvement and --
+ -- if RABs are carried on DCH, USCH or DSCH transport channels --,
+ iE-Extensions ProtocolExtensionContainer { {SourceRNC-ToTargetRNC-TransparentContainer-ExtIEs} } OPTIONAL,
+ ...
+}
+
+SourceRNC-ToTargetRNC-TransparentContainer-ExtIEs RANAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+SourceStatisticsDescriptor ::= ENUMERATED {
+ speech,
+ unknown,
+ ...
+}
+
+SubflowSDU-Size ::= INTEGER (0..4095)
+-- Unit is bit
+
+
+-- T
+
+TargetCellId ::= INTEGER (0..268435455)
+
+TargetID ::= CHOICE {
+ targetRNC-ID TargetRNC-ID, -- If UMTS target
+ cGI CGI, -- If GSM target
+ ...
+}
+
+
+
+
+TargetRNC-ID ::= SEQUENCE {
+ lAI LAI,
+ rAC RAC OPTIONAL
+ -- Must always be present towards the PS domain and never towards the CS domain --,
+ rNC-ID RNC-ID,
+ iE-Extensions ProtocolExtensionContainer { {TargetRNC-ID-ExtIEs} } OPTIONAL
+}
+
+TargetRNC-ID-ExtIEs RANAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+TargetRNC-ToSourceRNC-TransparentContainer ::= SEQUENCE {
+ rRC-Container RRC-Container,
+ d-RNTI D-RNTI OPTIONAL
+ -- May be included to allow the triggering of the Relocation Detect procedure from the Iur Interface --,
+ iE-Extensions ProtocolExtensionContainer { {TargetRNC-ToSourceRNC-TransparentContainer-ExtIEs} } OPTIONAL,
+ ...
+}
+
+TargetRNC-ToSourceRNC-TransparentContainer-ExtIEs RANAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+TBCD-STRING ::= OCTET STRING
+
+TemporaryUE-ID ::= CHOICE {
+ tMSI TMSI,
+ p-TMSI P-TMSI,
+ ...
+}
+
+TMSI ::= OCTET STRING (SIZE (4))
+
+TraceReference ::= OCTET STRING (SIZE (2..3))
+
+TraceType ::= OCTET STRING (SIZE (1))
+-- Reference: GSM TS 12.08
+
+TrafficClass ::= ENUMERATED {
+ conversational,
+ streaming,
+ interactive,
+ background,
+ ...
+}
+
+TrafficHandlingPriority ::= INTEGER { spare (0), highest (1), lowest (14), no-priority-used (15) } (0..15)
+
+TransferDelay ::= INTEGER (0..65535)
+-- Unit is millisecond
+
+UnsuccessfullyTransmittedDataVolume ::= INTEGER (0..4294967295)
+
+TransportLayerAddress ::= BIT STRING (SIZE (1..160, ...))
+
+TrCH-ID ::= SEQUENCE {
+ dCH-ID DCH-ID OPTIONAL
+ -- At least one of these IEs shall be included --,
+ dSCH-ID DSCH-ID OPTIONAL
+ -- At least one of these IEs shall be included --,
+ uSCH-ID USCH-ID OPTIONAL
+ -- At least one of these IEs shall be included --,
+ ...
+}
+
+TrCH-ID-List ::= SEQUENCE (SIZE (1..maxRAB-Subflows)) OF
+ TrCH-ID
+
+TriggerID ::= OCTET STRING (SIZE (3..22))
+
+-- U
+
+UE-ID ::= CHOICE {
+ imsi IMSI,
+ imei IMEI,
+ ...
+}
+
+UL-GTP-PDU-SequenceNumber ::= INTEGER (0..65535)
+
+UL-N-PDU-SequenceNumber ::= INTEGER (0..65535)
+
+UP-ModeVersions ::= BIT STRING (SIZE (16))
+
+USCH-ID ::= INTEGER (0..255)
+
+UserPlaneMode ::= ENUMERATED {
+ transparent-mode,
+ support-mode-for-predefined-SDU-sizes,
+ ...
+}
+
+-- END **************************************************************
+--
+-- PDU definitions for RANAP.
+--
+-- **************************************************************
+
+-- RANAP-PDU-Contents { object identifier to be allocated }--
+-- DEFINITIONS AUTOMATIC TAGS ::=
+
+-- BEGIN
+
+-- **************************************************************
+--
+-- IE parameter types from other modules.
+--
+-- **************************************************************
+
+-- **************************************************************
+--
+-- Common Container Lists
+--
+-- **************************************************************
+
+RAB-IE-ContainerList { RANAP-PROTOCOL-IES : IEsSetParam } ::= ProtocolIE-ContainerList { 1, maxNrOfRABs, {IEsSetParam} }
+RAB-IE-ContainerPairList { RANAP-PROTOCOL-IES-PAIR : IEsSetParam } ::= ProtocolIE-ContainerPairList { 1, maxNrOfRABs, {IEsSetParam} }
+ProtocolError-IE-ContainerList { RANAP-PROTOCOL-IES : IEsSetParam } ::= ProtocolIE-ContainerList { 1, maxNrOfRABs, {IEsSetParam} }
+CN-BroadcastInfPiece-IE-ContainerList { RANAP-PROTOCOL-IES : IEsSetParam } ::= ProtocolIE-ContainerList { 1, maxNrOfPieces, {IEsSetParam} }
+IuSigConId-IE-ContainerList { RANAP-PROTOCOL-IES : IEsSetParam } ::= ProtocolIE-ContainerList { 1, maxNrOfIuSigConIds, {IEsSetParam} }
+DirectTransfer-IE-ContainerList { RANAP-PROTOCOL-IES : IEsSetParam } ::= ProtocolIE-ContainerList { 1, maxNrOfDTs, {IEsSetParam} }
+
+-- **************************************************************
+--
+-- Iu RELEASE ELEMENTARY PROCEDURE
+--
+-- **************************************************************
+
+-- **************************************************************
+--
+-- Iu Release Command
+--
+-- **************************************************************
+
+Iu-ReleaseCommand ::= SEQUENCE {
+ protocolIEs ProtocolIE-Container { {Iu-ReleaseCommandIEs} },
+ protocolExtensions ProtocolExtensionContainer { {Iu-ReleaseCommandExtensions} } OPTIONAL,
+ ...
+}
+
+Iu-ReleaseCommandIEs RANAP-PROTOCOL-IES ::= {
+ { ID id-Cause CRITICALITY ignore TYPE Cause PRESENCE mandatory },
+ ...
+}
+
+Iu-ReleaseCommandExtensions RANAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+-- **************************************************************
+--
+-- Iu Release Complete
+--
+-- **************************************************************
+
+Iu-ReleaseComplete ::= SEQUENCE {
+ protocolIEs ProtocolIE-Container { {Iu-ReleaseCompleteIEs} },
+ protocolExtensions ProtocolExtensionContainer { {Iu-ReleaseCompleteExtensions} } OPTIONAL,
+ ...
+}
+
+Iu-ReleaseCompleteIEs RANAP-PROTOCOL-IES ::= {
+ { ID id-RAB-DataVolumeReportList CRITICALITY ignore TYPE RAB-DataVolumeReportList PRESENCE conditional
+ -- This group is only present if data volume reporting for PS domain is required -- } |
+ { ID id-RAB-ReleasedList-IuRelComp CRITICALITY ignore TYPE RAB-ReleasedList-IuRelComp PRESENCE conditional
+ -- This group is only present for RABs towards the PS domain when the release was initiated by UTRAN -- } |
+ { ID id-CriticalityDiagnostics CRITICALITY ignore TYPE CriticalityDiagnostics PRESENCE optional },
+ ...
+}
+
+RAB-DataVolumeReportList ::= RAB-IE-ContainerList { {RAB-DataVolumeReportItemIEs} }
+
+RAB-DataVolumeReportItemIEs RANAP-PROTOCOL-IES ::= {
+ { ID id-RAB-DataVolumeReportItem CRITICALITY ignore TYPE RAB-DataVolumeReportItem PRESENCE mandatory },
+ ...
+}
+
+RAB-DataVolumeReportItem ::= SEQUENCE {
+ rAB-ID RAB-ID,
+ dl-UnsuccessfullyTransmittedDataVolume DataVolumeList OPTIONAL
+ -- This IE is only present if data volume reporting for PS domain is required --,
+ iE-Extensions ProtocolExtensionContainer { {RAB-DataVolumeReportItem-ExtIEs} } OPTIONAL,
+ ...
+}
+
+RAB-DataVolumeReportItem-ExtIEs RANAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+RAB-ReleasedList-IuRelComp ::= RAB-IE-ContainerList { {RAB-ReleasedItem-IuRelComp-IEs} }
+
+RAB-ReleasedItem-IuRelComp-IEs RANAP-PROTOCOL-IES ::= {
+ { ID id-RAB-ReleasedItem-IuRelComp CRITICALITY ignore TYPE RAB-ReleasedItem-IuRelComp PRESENCE mandatory },
+ ...
+}
+
+RAB-ReleasedItem-IuRelComp ::= SEQUENCE {
+ rAB-ID RAB-ID,
+ dL-GTP-PDU-SequenceNumber DL-GTP-PDU-SequenceNumber,
+ uL-GTP-PDU-SequenceNumber UL-GTP-PDU-SequenceNumber,
+ iE-Extensions ProtocolExtensionContainer { {RAB-ReleasedItem-IuRelComp-ExtIEs} } OPTIONAL,
+ ...
+}
+
+RAB-ReleasedItem-IuRelComp-ExtIEs RANAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+
+Iu-ReleaseCompleteExtensions RANAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+-- **************************************************************
+--
+-- RELOCATION PREPARATION ELEMENTARY PROCEDURE
+--
+-- **************************************************************
+
+-- **************************************************************
+--
+-- Relocation Required
+--
+-- **************************************************************
+
+RelocationRequired ::= SEQUENCE {
+ protocolIEs ProtocolIE-Container { {RelocationRequiredIEs} },
+ protocolExtensions ProtocolExtensionContainer { {RelocationRequiredExtensions} } OPTIONAL,
+ ...
+}
+
+RelocationRequiredIEs RANAP-PROTOCOL-IES ::= {
+ { ID id-RelocationType CRITICALITY ignore TYPE RelocationType PRESENCE mandatory } |
+ { ID id-Cause CRITICALITY ignore TYPE Cause PRESENCE mandatory } |
+ { ID id-SourceID CRITICALITY ignore TYPE SourceID PRESENCE mandatory } |
+ { ID id-TargetID CRITICALITY reject TYPE TargetID PRESENCE mandatory } |
+ { ID id-ClassmarkInformation2 CRITICALITY ignore TYPE ClassmarkInformation2 PRESENCE conditional
+ -- This is only present when initiating an inter system handover towards GSM BSC -- } |
+ { ID id-ClassmarkInformation3 CRITICALITY ignore TYPE ClassmarkInformation3 PRESENCE conditional
+ -- This is only present when initiating an inter system handover towards GSM BSC -- } |
+ { ID id-SourceRNC-ToTargetRNC-TransparentContainer
+ CRITICALITY reject TYPE SourceRNC-ToTargetRNC-TransparentContainer PRESENCE conditional
+ -- This IE shall be present when initiating relocation of SRNS -- } |
+ { ID id-OldBSS-ToNewBSS-Information CRITICALITY ignore TYPE OldBSS-ToNewBSS-Information PRESENCE conditional
+ -- This is only present when initiating an inter system handover towards GSM BSC -- } ,
+ ...
+}
+
+RelocationRequiredExtensions RANAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+-- **************************************************************
+--
+-- Relocation Command
+--
+-- **************************************************************
+
+RelocationCommand ::= SEQUENCE {
+ protocolIEs ProtocolIE-Container { {RelocationCommandIEs} },
+ protocolExtensions ProtocolExtensionContainer { {RelocationCommandExtensions} } OPTIONAL,
+ ...
+}
+
+RelocationCommandIEs RANAP-PROTOCOL-IES ::= {
+ { ID id-TargetRNC-ToSourceRNC-TransparentContainer
+ CRITICALITY reject TYPE TargetRNC-ToSourceRNC-TransparentContainer PRESENCE conditional
+ -- This IE shall be included if it is received by the CN from the relocation target. -- } |
+ { ID id-L3-Information CRITICALITY ignore TYPE L3-Information PRESENCE conditional
+ -- This IE shall be included if it is received by the CN from the relocation target. -- } |
+ { ID id-RAB-RelocationReleaseList CRITICALITY ignore TYPE RAB-RelocationReleaseList PRESENCE optional } |
+ { ID id-RAB-DataForwardingList CRITICALITY ignore TYPE RAB-DataForwardingList PRESENCE conditional
+ -- This group if applicable is only present for RABs towards the PS domain -- } |
+ { ID id-CriticalityDiagnostics CRITICALITY ignore TYPE CriticalityDiagnostics PRESENCE optional },
+ ...
+}
+
+RAB-RelocationReleaseList ::= RAB-IE-ContainerList { {RAB-RelocationReleaseItemIEs} }
+
+RAB-RelocationReleaseItemIEs RANAP-PROTOCOL-IES ::= {
+ { ID id-RAB-RelocationReleaseItem CRITICALITY ignore TYPE RAB-RelocationReleaseItem PRESENCE mandatory },
+ ...
+}
+
+RAB-RelocationReleaseItem ::= SEQUENCE {
+ rAB-ID RAB-ID,
+ iE-Extensions ProtocolExtensionContainer { {RAB-RelocationReleaseItem-ExtIEs} } OPTIONAL,
+ ...
+}
+
+RAB-RelocationReleaseItem-ExtIEs RANAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+RAB-DataForwardingList ::= RAB-IE-ContainerList { {RAB-DataForwardingItemIEs} }
+
+RAB-DataForwardingItemIEs RANAP-PROTOCOL-IES ::= {
+ { ID id-RAB-DataForwardingItem CRITICALITY ignore TYPE RAB-DataForwardingItem PRESENCE mandatory },
+ ...
+}
+
+RAB-DataForwardingItem ::= SEQUENCE {
+ rAB-ID RAB-ID,
+ transportLayerAddress TransportLayerAddress,
+ iuTransportAssociation IuTransportAssociation,
+ iE-Extensions ProtocolExtensionContainer { {RAB-DataForwardingItem-ExtIEs} } OPTIONAL,
+ ...
+}
+
+RAB-DataForwardingItem-ExtIEs RANAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+RelocationCommandExtensions RANAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+-- **************************************************************
+--
+-- Relocation Preparation Failure
+--
+-- **************************************************************
+
+RelocationPreparationFailure ::= SEQUENCE {
+ protocolIEs ProtocolIE-Container { {RelocationPreparationFailureIEs} },
+ protocolExtensions ProtocolExtensionContainer { {RelocationPreparationFailureExtensions} } OPTIONAL,
+ ...
+}
+
+RelocationPreparationFailureIEs RANAP-PROTOCOL-IES ::= {
+ { ID id-Cause CRITICALITY ignore TYPE Cause PRESENCE mandatory } |
+ { ID id-CriticalityDiagnostics CRITICALITY ignore TYPE CriticalityDiagnostics PRESENCE optional },
+ ...
+}
+
+RelocationPreparationFailureExtensions RANAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+-- **************************************************************
+--
+-- RELOCATION RESOURCE ALLOCATION ELEMENTARY PROCEDURE
+--
+-- **************************************************************
+
+-- **************************************************************
+--
+-- Relocation Request
+--
+-- **************************************************************
+
+RelocationRequest ::= SEQUENCE {
+ protocolIEs ProtocolIE-Container { {RelocationRequestIEs} },
+ protocolExtensions ProtocolExtensionContainer { {RelocationRequestExtensions} } OPTIONAL,
+ ...
+}
+
+RelocationRequestIEs RANAP-PROTOCOL-IES ::= {
+ { ID id-PermanentNAS-UE-ID CRITICALITY ignore TYPE PermanentNAS-UE-ID PRESENCE conditional
+ -- This IE is only present if available at the sending side -- } |
+ { ID id-Cause CRITICALITY ignore TYPE Cause PRESENCE mandatory } |
+ { ID id-CN-DomainIndicator CRITICALITY ignore TYPE CN-DomainIndicator PRESENCE mandatory } |
+ { ID id-SourceRNC-ToTargetRNC-TransparentContainer
+ CRITICALITY reject TYPE SourceRNC-ToTargetRNC-TransparentContainer PRESENCE mandatory } |
+ { ID id-RAB-SetupList-RelocReq CRITICALITY reject TYPE RAB-SetupList-RelocReq PRESENCE optional } |
+ { ID id-IntegrityProtectionInformation CRITICALITY ignore TYPE IntegrityProtectionInformation PRESENCE conditional
+ -- This IE is only present if available at the sending side -- } |
+ { ID id-EncryptionInformation CRITICALITY ignore TYPE EncryptionInformation PRESENCE optional } |
+ { ID id-IuSigConId CRITICALITY ignore TYPE IuSignallingConnectionIdentifier PRESENCE mandatory },
+ ...
+}
+
+RAB-SetupList-RelocReq ::= RAB-IE-ContainerList { {RAB-SetupItem-RelocReq-IEs} }
+
+RAB-SetupItem-RelocReq-IEs RANAP-PROTOCOL-IES ::= {
+ { ID id-RAB-SetupItem-RelocReq CRITICALITY reject TYPE RAB-SetupItem-RelocReq PRESENCE mandatory },
+ ...
+}
+
+RAB-SetupItem-RelocReq ::= SEQUENCE {
+ rAB-ID RAB-ID,
+ nAS-SynchronisationIndicator NAS-SynchronisationIndicator OPTIONAL
+ -- This IE is present if the relevant NAS information is provided by the CN --,
+ rAB-Parameters RAB-Parameters,
+ dataVolumeReportingIndication DataVolumeReportingIndication OPTIONAL
+ -- This IE is only present if available at the sending side --,
+ pDP-TypeInformation PDP-TypeInformation OPTIONAL
+ -- This IE is only present for RABs towards the PS domain --,
+ userPlaneInformation UserPlaneInformation,
+ transportLayerAddress TransportLayerAddress,
+ iuTransportAssociation IuTransportAssociation,
+ iE-Extensions ProtocolExtensionContainer { {RAB-SetupItem-RelocReq-ExtIEs} } OPTIONAL,
+ ...
+}
+
+RAB-SetupItem-RelocReq-ExtIEs RANAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+UserPlaneInformation ::= SEQUENCE {
+ userPlaneMode UserPlaneMode,
+ uP-ModeVersions UP-ModeVersions,
+ iE-Extensions ProtocolExtensionContainer { {UserPlaneInformation-ExtIEs} } OPTIONAL,
+ ...
+}
+
+UserPlaneInformation-ExtIEs RANAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+RelocationRequestExtensions RANAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+-- **************************************************************
+--
+-- Relocation Request Acknowledge
+--
+-- **************************************************************
+
+RelocationRequestAcknowledge ::= SEQUENCE {
+ protocolIEs ProtocolIE-Container { {RelocationRequestAcknowledgeIEs} },
+ protocolExtensions ProtocolExtensionContainer { {RelocationRequestAcknowledgeExtensions} } OPTIONAL,
+ ...
+}
+
+RelocationRequestAcknowledgeIEs RANAP-PROTOCOL-IES ::= {
+ { ID id-TargetRNC-ToSourceRNC-TransparentContainer
+ CRITICALITY ignore TYPE TargetRNC-ToSourceRNC-TransparentContainer PRESENCE conditional
+ -- Must be included if applicapble and if not sent via the other CN -- } |
+ { ID id-RAB-SetupList-RelocReqAck CRITICALITY ignore TYPE RAB-SetupList-RelocReqAck PRESENCE optional} |
+ { ID id-RAB-FailedList CRITICALITY ignore TYPE RAB-FailedList PRESENCE optional }|
+ { ID id-ChosenIntegrityProtectionAlgorithm CRITICALITY ignore TYPE ChosenIntegrityProtectionAlgorithm PRESENCE conditional
+ -- This IE is only present if available at the sending side -- } |
+ { ID id-ChosenEncryptionAlgorithm CRITICALITY ignore TYPE ChosenEncryptionAlgorithm PRESENCE optional } |
+ { ID id-CriticalityDiagnostics CRITICALITY ignore TYPE CriticalityDiagnostics PRESENCE optional },
+ ...
+}
+
+RAB-SetupList-RelocReqAck ::= RAB-IE-ContainerList { {RAB-SetupItem-RelocReqAck-IEs} }
+
+RAB-SetupItem-RelocReqAck-IEs RANAP-PROTOCOL-IES ::= {
+ { ID id-RAB-SetupItem-RelocReqAck CRITICALITY reject TYPE RAB-SetupItem-RelocReqAck PRESENCE mandatory },
+ ...
+}
+
+RAB-SetupItem-RelocReqAck ::= SEQUENCE {
+ rAB-ID RAB-ID,
+ transportLayerAddress TransportLayerAddress OPTIONAL,
+ --This IE is only present for RABS towards the PS Domain
+ iuTransportAssociation IuTransportAssociation OPTIONAL,
+ --This IE is only present for RABS towards the PS Domain
+ iE-Extensions ProtocolExtensionContainer { {RAB-SetupItem-RelocReqAck-ExtIEs} } OPTIONAL,
+ ...
+}
+
+RAB-SetupItem-RelocReqAck-ExtIEs RANAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+RAB-FailedList ::= RAB-IE-ContainerList { {RAB-FailedItemIEs} }
+
+RAB-FailedItemIEs RANAP-PROTOCOL-IES ::= {
+ { ID id-RAB-FailedItem CRITICALITY ignore TYPE RAB-FailedItem PRESENCE mandatory },
+ ...
+}
+
+RAB-FailedItem ::= SEQUENCE {
+ rAB-ID RAB-ID,
+ cause Cause,
+ iE-Extensions ProtocolExtensionContainer { {RAB-FailedItem-ExtIEs} } OPTIONAL,
+ ...
+}
+
+RAB-FailedItem-ExtIEs RANAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+RelocationRequestAcknowledgeExtensions RANAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+-- **************************************************************
+--
+-- Relocation Failure
+--
+-- **************************************************************
+
+RelocationFailure ::= SEQUENCE {
+ protocolIEs ProtocolIE-Container { {RelocationFailureIEs} },
+ protocolExtensions ProtocolExtensionContainer { {RelocationFailureExtensions} } OPTIONAL,
+ ...
+}
+
+RelocationFailureIEs RANAP-PROTOCOL-IES ::= {
+ { ID id-Cause CRITICALITY ignore TYPE Cause PRESENCE mandatory } |
+ { ID id-CriticalityDiagnostics CRITICALITY ignore TYPE CriticalityDiagnostics PRESENCE optional },
+ ...
+}
+
+RelocationFailureExtensions RANAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+-- **************************************************************
+--
+-- RELOCATION CANCEL ELEMENTARY PROCEDURE
+--
+-- **************************************************************
+
+-- **************************************************************
+--
+-- Relocation Cancel
+--
+-- **************************************************************
+
+RelocationCancel ::= SEQUENCE {
+ protocolIEs ProtocolIE-Container { {RelocationCancelIEs} },
+ protocolExtensions ProtocolExtensionContainer { {RelocationCancelExtensions} } OPTIONAL,
+ ...
+}
+
+RelocationCancelIEs RANAP-PROTOCOL-IES ::= {
+ { ID id-Cause CRITICALITY ignore TYPE Cause PRESENCE mandatory },
+ ...
+}
+
+RelocationCancelExtensions RANAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+-- **************************************************************
+--
+-- Relocation Cancel Acknowledge
+--
+-- **************************************************************
+
+RelocationCancelAcknowledge ::= SEQUENCE {
+ protocolIEs ProtocolIE-Container { {RelocationCancelAcknowledgeIEs} },
+ protocolExtensions ProtocolExtensionContainer { {RelocationCancelAcknowledgeExtensions} } OPTIONAL,
+ ...
+}
+
+RelocationCancelAcknowledgeIEs RANAP-PROTOCOL-IES ::= {
+ { ID id-CriticalityDiagnostics CRITICALITY ignore TYPE CriticalityDiagnostics PRESENCE optional },
+ ...
+}
+
+RelocationCancelAcknowledgeExtensions RANAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+-- **************************************************************
+--
+-- SRNS CONTEXT TRANSFER OPEARATION
+--
+-- **************************************************************
+
+-- **************************************************************
+--
+-- SRNS Context Request
+--
+-- **************************************************************
+
+SRNS-ContextRequest ::= SEQUENCE {
+ protocolIEs ProtocolIE-Container { {SRNS-ContextRequestIEs} },
+ protocolExtensions ProtocolExtensionContainer { {SRNS-ContextRequestExtensions} } OPTIONAL,
+ ...
+}
+
+SRNS-ContextRequestIEs RANAP-PROTOCOL-IES ::= {
+ { ID id-RAB-DataForwardingList-SRNS-CtxReq CRITICALITY ignore TYPE RAB-DataForwardingList-SRNS-CtxReq PRESENCE mandatory },
+ ...
+}
+
+RAB-DataForwardingList-SRNS-CtxReq ::= RAB-IE-ContainerList { {RAB-DataForwardingItem-SRNS-CtxReq-IEs} }
+
+RAB-DataForwardingItem-SRNS-CtxReq-IEs RANAP-PROTOCOL-IES ::= {
+ { ID id-RAB-DataForwardingItem-SRNS-CtxReq CRITICALITY ignore TYPE RAB-DataForwardingItem-SRNS-CtxReq PRESENCE mandatory },
+ ...
+}
+
+RAB-DataForwardingItem-SRNS-CtxReq ::= SEQUENCE {
+ rAB-ID RAB-ID,
+ iE-Extensions ProtocolExtensionContainer { {RAB-DataForwardingItem-SRNS-CtxReq-ExtIEs} } OPTIONAL,
+ ...
+}
+
+RAB-DataForwardingItem-SRNS-CtxReq-ExtIEs RANAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+SRNS-ContextRequestExtensions RANAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+-- **************************************************************
+--
+-- SRNS Context Response
+--
+-- **************************************************************
+
+SRNS-ContextResponse ::= SEQUENCE {
+ protocolIEs ProtocolIE-Container { {SRNS-ContextResponseIEs} },
+ protocolExtensions ProtocolExtensionContainer { {SRNS-ContextResponseExtensions} } OPTIONAL,
+ ...
+}
+
+SRNS-ContextResponseIEs RANAP-PROTOCOL-IES ::= {
+
+ { ID id-RAB-ContextList CRITICALITY ignore TYPE RAB-ContextList PRESENCE conditional
+ -- This group must be present at least when no other group is present, ie. at least one group must be present -- } |
+ { ID id-RAB-ContextFailedtoTransferList CRITICALITY ignore TYPE RAB-ContextFailedtoTransferList PRESENCE conditional
+ -- This group must be present at least when no other group is present, ie. at least one group must be present -- }|
+ { ID id-CriticalityDiagnostics CRITICALITY ignore TYPE CriticalityDiagnostics PRESENCE optional },
+ ...
+}
+
+RAB-ContextList ::= RAB-IE-ContainerList { {RAB-ContextItemIEs} }
+
+RAB-ContextItemIEs RANAP-PROTOCOL-IES ::= {
+ { ID id-RAB-ContextItem CRITICALITY ignore TYPE RAB-ContextItem PRESENCE mandatory },
+ ...
+}
+
+RAB-ContextItem ::= SEQUENCE {
+ rAB-ID RAB-ID,
+ dl-GTP-PDU-SequenceNumber DL-GTP-PDU-SequenceNumber,
+ ul-GTP-PDU-SequenceNumber UL-GTP-PDU-SequenceNumber,
+ dl-N-PDU-SequenceNumber DL-N-PDU-SequenceNumber,
+ ul-N-PDU-SequenceNumber UL-N-PDU-SequenceNumber,
+ iE-Extensions ProtocolExtensionContainer { {RAB-ContextItem-ExtIEs} } OPTIONAL,
+ ...
+}
+
+RAB-ContextItem-ExtIEs RANAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+RAB-ContextFailedtoTransferList ::= RAB-IE-ContainerList { {RABs-ContextFailedtoTransferItemIEs} }
+
+RABs-ContextFailedtoTransferItemIEs RANAP-PROTOCOL-IES ::= {
+ { ID id-RAB-ContextFailedtoTransferItem CRITICALITY ignore TYPE RABs-ContextFailedtoTransferItem PRESENCE mandatory },
+ ...
+}
+
+RABs-ContextFailedtoTransferItem::= SEQUENCE {
+ rAB-ID RAB-ID,
+ cause Cause,
+ iE-Extensions ProtocolExtensionContainer { { RABs-ContextFailedtoTransferItem-ExtIEs} } OPTIONAL,
+ ...
+}
+
+
+RABs-ContextFailedtoTransferItem-ExtIEs RANAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+SRNS-ContextResponseExtensions RANAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+-- **************************************************************
+--
+-- SECURITY MODE CONTROL ELEMENTARY PROCEDURE
+--
+-- **************************************************************
+
+-- **************************************************************
+--
+-- Security Mode Command
+--
+-- **************************************************************
+
+SecurityModeCommand ::= SEQUENCE {
+ protocolIEs ProtocolIE-Container { {SecurityModeCommandIEs} },
+ protocolExtensions ProtocolExtensionContainer { {SecurityModeCommandExtensions} } OPTIONAL,
+ ...
+}
+
+SecurityModeCommandIEs RANAP-PROTOCOL-IES ::= {
+ { ID id-IntegrityProtectionInformation CRITICALITY ignore TYPE IntegrityProtectionInformation PRESENCE mandatory } |
+ { ID id-EncryptionInformation CRITICALITY ignore TYPE EncryptionInformation PRESENCE optional } |
+ { ID id-KeyStatus CRITICALITY ignore TYPE KeyStatus PRESENCE mandatory},
+ ...
+}
+
+SecurityModeCommandExtensions RANAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+-- **************************************************************
+--
+-- Security Mode Complete
+--
+-- **************************************************************
+
+SecurityModeComplete ::= SEQUENCE {
+ protocolIEs ProtocolIE-Container { {SecurityModeCompleteIEs} },
+ protocolExtensions ProtocolExtensionContainer { {SecurityModeCompleteExtensions} } OPTIONAL,
+ ...
+}
+
+SecurityModeCompleteIEs RANAP-PROTOCOL-IES ::= {
+ { ID id-ChosenIntegrityProtectionAlgorithm CRITICALITY ignore TYPE ChosenIntegrityProtectionAlgorithm PRESENCE mandatory } |
+ { ID id-ChosenEncryptionAlgorithm CRITICALITY ignore TYPE ChosenEncryptionAlgorithm PRESENCE optional } |
+ { ID id-CriticalityDiagnostics CRITICALITY ignore TYPE CriticalityDiagnostics PRESENCE optional },
+ ...
+}
+
+SecurityModeCompleteExtensions RANAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+-- **************************************************************
+--
+-- Security Mode Reject
+--
+-- **************************************************************
+
+SecurityModeReject ::= SEQUENCE {
+ protocolIEs ProtocolIE-Container { {SecurityModeRejectIEs} },
+ protocolExtensions ProtocolExtensionContainer { {SecurityModeRejectExtensions} } OPTIONAL,
+ ...
+}
+
+SecurityModeRejectIEs RANAP-PROTOCOL-IES ::= {
+ { ID id-Cause CRITICALITY ignore TYPE Cause PRESENCE mandatory } |
+ { ID id-CriticalityDiagnostics CRITICALITY ignore TYPE CriticalityDiagnostics PRESENCE optional },
+ ...
+}
+
+SecurityModeRejectExtensions RANAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+-- **************************************************************
+--
+-- DATA VOLUME REPORT ELEMENTARY PROCEDURE
+--
+-- **************************************************************
+
+-- **************************************************************
+--
+-- Data Volume Report Request
+--
+-- **************************************************************
+
+DataVolumeReportRequest ::= SEQUENCE {
+ protocolIEs ProtocolIE-Container { {DataVolumeReportRequestIEs} },
+ protocolExtensions ProtocolExtensionContainer { {DataVolumeReportRequestExtensions} } OPTIONAL,
+ ...
+}
+
+DataVolumeReportRequestIEs RANAP-PROTOCOL-IES ::= {
+ { ID id-RAB-DataVolumeReportRequestList CRITICALITY ignore TYPE RAB-DataVolumeReportRequestList PRESENCE mandatory },
+ ...
+}
+
+RAB-DataVolumeReportRequestList ::= RAB-IE-ContainerList { {RAB-DataVolumeReportRequestItemIEs} }
+
+RAB-DataVolumeReportRequestItemIEs RANAP-PROTOCOL-IES ::= {
+ { ID id-RAB-DataVolumeReportRequestItem CRITICALITY ignore TYPE RAB-DataVolumeReportRequestItem PRESENCE mandatory },
+ ...
+}
+
+RAB-DataVolumeReportRequestItem ::= SEQUENCE {
+ rAB-ID RAB-ID,
+ iE-Extensions ProtocolExtensionContainer { {RAB-DataVolumeReportRequestItem-ExtIEs} } OPTIONAL,
+ ...
+}
+
+RAB-DataVolumeReportRequestItem-ExtIEs RANAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+DataVolumeReportRequestExtensions RANAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+-- **************************************************************
+--
+-- Data Volume Report
+--
+-- **************************************************************
+
+DataVolumeReport ::= SEQUENCE {
+ protocolIEs ProtocolIE-Container { {DataVolumeReportIEs} },
+ protocolExtensions ProtocolExtensionContainer { {DataVolumeReportExtensions} } OPTIONAL,
+ ...
+}
+
+DataVolumeReportIEs RANAP-PROTOCOL-IES ::= {
+ { ID id-RAB-DataVolumeReportList CRITICALITY ignore TYPE RAB-DataVolumeReportList PRESENCE conditional
+ -- This group must be present at least when no other group is present, ie. at least one group must be present -- } |
+ { ID id-RAB-FailedtoReportList CRITICALITY ignore TYPE RAB-FailedtoReportList PRESENCE conditional
+ -- This group must be present at least when no other group is present, ie. at least one group must be present -- } |
+ { ID id-CriticalityDiagnostics CRITICALITY ignore TYPE CriticalityDiagnostics PRESENCE optional },
+ ...
+}
+
+DataVolumeReportExtensions RANAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+RAB-FailedtoReportList ::= RAB-IE-ContainerList { {RABs-failed-to-reportItemIEs} }
+
+RABs-failed-to-reportItemIEs RANAP-PROTOCOL-IES ::= {
+ { ID id-RAB-FailedtoReportItem CRITICALITY ignore TYPE RABs-failed-to-reportItem PRESENCE mandatory },
+ ...
+}
+
+RABs-failed-to-reportItem::= SEQUENCE {
+ rAB-ID RAB-ID,
+ cause Cause,
+ iE-Extensions ProtocolExtensionContainer { { RABs-failed-to-reportItem-ExtIEs} } OPTIONAL,
+ ...
+}
+
+
+RABs-failed-to-reportItem-ExtIEs RANAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+-- **************************************************************
+--
+-- CN INFORMATION BROADCAST
+--
+-- **************************************************************
+
+-- **************************************************************
+--
+-- CN Information Broadcast Request
+--
+-- **************************************************************
+
+CN-InformationBroadcastRequest ::= SEQUENCE {
+ protocolIEs ProtocolIE-Container { {CN-InformationBroadcastRequestIEs} },
+ protocolExtensions ProtocolExtensionContainer { {CN-InformationBroadcastRequestExtensions} } OPTIONAL,
+ ...
+}
+
+CN-InformationBroadcastRequestIEs RANAP-PROTOCOL-IES ::= {
+ { ID id-CN-DomainIndicator CRITICALITY ignore TYPE CN-DomainIndicator PRESENCE mandatory } |
+ { ID id-CN-BroadcastInformationPieceList CRITICALITY ignore TYPE CN-BroadcastInformationPieceList PRESENCE mandatory },
+ ...
+}
+
+CN-BroadcastInformationPieceList ::= CN-BroadcastInfPiece-IE-ContainerList { {CN-BroadcastInformationPieceIEs} }
+
+CN-BroadcastInformationPieceIEs RANAP-PROTOCOL-IES ::= {
+ { ID id-CN-BroadcastInformationPiece CRITICALITY ignore TYPE CN-BroadcastInformationPiece PRESENCE mandatory },
+ ...
+}
+
+CN-BroadcastInformationPiece ::= SEQUENCE {
+ informationIdentity InformationIdentity,
+ nAS-BroadcastInformation NAS-BroadcastInformation OPTIONAL
+ -- Included if CN requests UTRAN to broadcast the information piece --,
+ cN-BroadcastArea CN-BroadcastArea OPTIONAL
+ -- Included if CN requests UTRAN to broadcast the information piece --,
+ informationPriority InformationPriority OPTIONAL
+ -- Included if CN requests UTRAN to broadcast the information piece --,
+ informationControl InformationControl,
+ iE-Extensions ProtocolExtensionContainer { {CN-BroadcastInformationPiece-ExtIEs} } OPTIONAL,
+ ...
+}
+
+CN-BroadcastInformationPiece-ExtIEs RANAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+CN-InformationBroadcastRequestExtensions RANAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+-- **************************************************************
+--
+-- CN Information Broadcast Confirm
+--
+-- **************************************************************
+
+CN-InformationBroadcastConfirm ::= SEQUENCE {
+ protocolIEs ProtocolIE-Container { {CN-InformationBroadcastConfirmIEs} },
+ protocolExtensions ProtocolExtensionContainer { {CN-InformationBroadcastConfirmExtensions} } OPTIONAL,
+ ...
+}
+
+CN-InformationBroadcastConfirmIEs RANAP-PROTOCOL-IES ::= {
+ { ID id-CN-DomainIndicator CRITICALITY ignore TYPE CN-DomainIndicator PRESENCE mandatory } |
+ { ID id-CriticalityDiagnostics CRITICALITY ignore TYPE CriticalityDiagnostics PRESENCE optional } |
+ { ID id-GlobalRNC-ID CRITICALITY ignore TYPE GlobalRNC-ID PRESENCE mandatory },
+ ...
+}
+
+CN-InformationBroadcastConfirmExtensions RANAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+-- **************************************************************
+--
+-- CN Information Broadcast Reject
+--
+-- **************************************************************
+
+CN-InformationBroadcastReject ::= SEQUENCE {
+ protocolIEs ProtocolIE-Container { {CN-InformationBroadcastRejectIEs} },
+ protocolExtensions ProtocolExtensionContainer { {CN-InformationBroadcastRejectExtensions} } OPTIONAL,
+ ...
+}
+
+CN-InformationBroadcastRejectIEs RANAP-PROTOCOL-IES ::= {
+ { ID id-CN-DomainIndicator CRITICALITY ignore TYPE CN-DomainIndicator PRESENCE mandatory } |
+ { ID id-Cause CRITICALITY ignore TYPE Cause PRESENCE mandatory } |
+ { ID id-CriticalityDiagnostics CRITICALITY ignore TYPE CriticalityDiagnostics PRESENCE optional } |
+ { ID id-GlobalRNC-ID CRITICALITY ignore TYPE GlobalRNC-ID PRESENCE mandatory },
+ ...
+}
+
+CN-InformationBroadcastRejectExtensions RANAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+-- **************************************************************
+--
+-- RESET ELEMENTARY PROCEDURE
+--
+-- **************************************************************
+
+-- **************************************************************
+--
+-- Reset
+--
+-- **************************************************************
+
+Reset ::= SEQUENCE {
+ protocolIEs ProtocolIE-Container { {ResetIEs} },
+ protocolExtensions ProtocolExtensionContainer { {ResetExtensions} } OPTIONAL,
+ ...
+}
+
+ResetIEs RANAP-PROTOCOL-IES ::= {
+ { ID id-Cause CRITICALITY ignore TYPE Cause PRESENCE mandatory } |
+ { ID id-CN-DomainIndicator CRITICALITY ignore TYPE CN-DomainIndicator PRESENCE mandatory } |
+ { ID id-GlobalRNC-ID CRITICALITY ignore TYPE GlobalRNC-ID PRESENCE conditional
+ -- This IE is always used in the uplink direction -- },
+ ...
+}
+
+ResetExtensions RANAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+-- **************************************************************
+--
+-- Reset Acknowledge
+--
+-- **************************************************************
+
+ResetAcknowledge ::= SEQUENCE {
+ protocolIEs ProtocolIE-Container { {ResetAcknowledgeIEs} },
+ protocolExtensions ProtocolExtensionContainer { {ResetAcknowledgeExtensions} } OPTIONAL,
+ ...
+}
+
+ResetAcknowledgeIEs RANAP-PROTOCOL-IES ::= {
+ { ID id-CN-DomainIndicator CRITICALITY ignore TYPE CN-DomainIndicator PRESENCE mandatory } |
+ { ID id-CriticalityDiagnostics CRITICALITY ignore TYPE CriticalityDiagnostics PRESENCE optional } |
+ { ID id-GlobalRNC-ID CRITICALITY ignore TYPE GlobalRNC-ID PRESENCE conditional
+ -- This IE is always used in the uplink direction -- },
+ ...
+}
+
+ResetAcknowledgeExtensions RANAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+-- **************************************************************
+--
+-- RESET RESOURCE ELEMENTARY PROCEDURE
+--
+-- **************************************************************
+
+
+-- **************************************************************
+--
+-- Reset Resource
+--
+-- **************************************************************
+
+ResetResource ::= SEQUENCE {
+ protocolIEs ProtocolIE-Container { {ResetResourceIEs} },
+ protocolExtensions ProtocolExtensionContainer { {ResetResourceExtensions} } OPTIONAL,
+ ...
+}
+
+ResetResourceIEs RANAP-PROTOCOL-IES ::= {
+ { ID id-CN-DomainIndicator CRITICALITY ignore TYPE CN-DomainIndicator PRESENCE mandatory } |
+ { ID id-Cause CRITICALITY ignore TYPE Cause PRESENCE mandatory } |
+ { ID id-IuSigConIdList CRITICALITY ignore TYPE ResetResourceList PRESENCE mandatory } |
+ { ID id-GlobalRNC-ID CRITICALITY ignore TYPE GlobalRNC-ID PRESENCE conditional
+ -- This IE is always used in the uplink direction -- },
+ ...
+}
+
+ResetResourceList ::= IuSigConId-IE-ContainerList{ {ResetResourceItemIEs} }
+
+ResetResourceItemIEs RANAP-PROTOCOL-IES ::= {
+ { ID id-IuSigConIdItem CRITICALITY ignore TYPE ResetResourceItem PRESENCE mandatory },
+ ...
+}
+
+ResetResourceItem ::= SEQUENCE {
+ iuSigConId IuSignallingConnectionIdentifier,
+ iE-Extensions ProtocolExtensionContainer { { ResetResourceItem-ExtIEs} } OPTIONAL,
+ ...
+}
+
+ResetResourceItem-ExtIEs RANAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+ResetResourceExtensions RANAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+-- **************************************************************
+--
+-- Reset Resource Acknowledge
+--
+-- **************************************************************
+
+ResetResourceAcknowledge ::= SEQUENCE {
+ protocolIEs ProtocolIE-Container { {ResetResourceAcknowledgeIEs} },
+ protocolExtensions ProtocolExtensionContainer { {ResetResourceAcknowledgeExtensions} } OPTIONAL,
+ ...
+}
+
+ResetResourceAcknowledgeIEs RANAP-PROTOCOL-IES ::= {
+ { ID id-CN-DomainIndicator CRITICALITY ignore TYPE CN-DomainIndicator PRESENCE mandatory } |
+ { ID id-IuSigConIdList CRITICALITY ignore TYPE ResetResourceAckList PRESENCE mandatory } |
+ { ID id-GlobalRNC-ID CRITICALITY ignore TYPE GlobalRNC-ID PRESENCE conditional
+ -- This IE is always used in the uplink direction -- } |
+ { ID id-CriticalityDiagnostics CRITICALITY ignore TYPE CriticalityDiagnostics PRESENCE optional },
+ ...
+}
+ResetResourceAckList ::= IuSigConId-IE-ContainerList{ {ResetResourceAckItemIEs} }
+
+ResetResourceAckItemIEs RANAP-PROTOCOL-IES ::= {
+ { ID id-IuSigConIdItem CRITICALITY ignore TYPE ResetResourceAckItem PRESENCE mandatory },
+ ...
+}
+
+ResetResourceAckItem ::= SEQUENCE {
+ iuSigConId IuSignallingConnectionIdentifier,
+ iE-Extensions ProtocolExtensionContainer { { ResetResourceAckItem-ExtIEs} } OPTIONAL,
+ ...
+}
+
+ResetResourceAckItem-ExtIEs RANAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+ResetResourceAcknowledgeExtensions RANAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+-- **************************************************************
+--
+-- RAB RELEASE REQUEST ELEMENTARY PROCEDURE
+--
+-- **************************************************************
+
+-- **************************************************************
+--
+-- RAB Release Request
+--
+-- **************************************************************
+
+RAB-ReleaseRequest ::= SEQUENCE {
+ protocolIEs ProtocolIE-Container { {RAB-ReleaseRequestIEs} },
+ protocolExtensions ProtocolExtensionContainer { {RAB-ReleaseRequestExtensions} } OPTIONAL,
+ ...
+}
+
+RAB-ReleaseRequestIEs RANAP-PROTOCOL-IES ::= {
+ { ID id-RAB-ReleaseList CRITICALITY ignore TYPE RAB-ReleaseList PRESENCE mandatory },
+ ...
+}
+
+RAB-ReleaseList ::= RAB-IE-ContainerList { {RAB-ReleaseItemIEs} }
+
+RAB-ReleaseItemIEs RANAP-PROTOCOL-IES ::= {
+ { ID id-RAB-ReleaseItem CRITICALITY ignore TYPE RAB-ReleaseItem PRESENCE mandatory },
+ ...
+}
+
+RAB-ReleaseItem ::= SEQUENCE {
+ rAB-ID RAB-ID,
+ cause Cause,
+ iE-Extensions ProtocolExtensionContainer { {RAB-ReleaseItem-ExtIEs} } OPTIONAL,
+ ...
+}
+
+RAB-ReleaseItem-ExtIEs RANAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+RAB-ReleaseRequestExtensions RANAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+-- **************************************************************
+--
+-- Iu RELEASE REQUEST ELEMENTARY PROCEDURE
+--
+-- **************************************************************
+
+-- **************************************************************
+--
+-- Iu Release Request
+--
+-- **************************************************************
+
+Iu-ReleaseRequest ::= SEQUENCE {
+ protocolIEs ProtocolIE-Container { {Iu-ReleaseRequestIEs} },
+ protocolExtensions ProtocolExtensionContainer { {Iu-ReleaseRequestExtensions} } OPTIONAL,
+ ...
+}
+
+Iu-ReleaseRequestIEs RANAP-PROTOCOL-IES ::= {
+ { ID id-Cause CRITICALITY ignore TYPE Cause PRESENCE mandatory },
+ ...
+}
+
+Iu-ReleaseRequestExtensions RANAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+-- **************************************************************
+--
+-- RELOCATION DETECT ELEMENTARY PROCEDURE
+--
+-- **************************************************************
+
+-- **************************************************************
+--
+-- Relocation Detect
+--
+-- **************************************************************
+
+RelocationDetect ::= SEQUENCE {
+ protocolIEs ProtocolIE-Container { {RelocationDetectIEs} },
+ protocolExtensions ProtocolExtensionContainer { {RelocationDetectExtensions} } OPTIONAL,
+ ...
+}
+
+RelocationDetectIEs RANAP-PROTOCOL-IES ::= {
+ ...
+}
+
+RelocationDetectExtensions RANAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+-- **************************************************************
+--
+-- RELOCATION COMPLETE ELEMENTARY PROCEDURE
+--
+-- **************************************************************
+
+-- **************************************************************
+--
+-- Relocation Complete
+--
+-- **************************************************************
+
+RelocationComplete ::= SEQUENCE {
+ protocolIEs ProtocolIE-Container { {RelocationCompleteIEs} },
+ protocolExtensions ProtocolExtensionContainer { {RelocationCompleteExtensions} } OPTIONAL,
+ ...
+}
+
+RelocationCompleteIEs RANAP-PROTOCOL-IES ::= {
+ ...
+}
+
+RelocationCompleteExtensions RANAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+-- **************************************************************
+--
+-- PAGING ELEMENTARY PROCEDURE
+--
+-- **************************************************************
+
+-- **************************************************************
+--
+-- Paging
+--
+-- **************************************************************
+
+Paging ::= SEQUENCE {
+ protocolIEs ProtocolIE-Container { {PagingIEs} },
+ protocolExtensions ProtocolExtensionContainer { {PagingExtensions} } OPTIONAL,
+ ...
+}
+
+PagingIEs RANAP-PROTOCOL-IES ::= {
+ { ID id-CN-DomainIndicator CRITICALITY ignore TYPE CN-DomainIndicator PRESENCE mandatory } |
+ { ID id-PermanentNAS-UE-ID CRITICALITY ignore TYPE PermanentNAS-UE-ID PRESENCE mandatory } |
+ { ID id-TemporaryUE-ID CRITICALITY ignore TYPE TemporaryUE-ID PRESENCE optional } |
+ { ID id-PagingAreaID CRITICALITY ignore TYPE PagingAreaID PRESENCE optional } |
+ { ID id-PagingCause CRITICALITY ignore TYPE PagingCause PRESENCE optional } |
+ { ID id-NonSearchingIndication CRITICALITY ignore TYPE NonSearchingIndication PRESENCE optional } |
+ { ID id-DRX-CycleLengthCoefficient CRITICALITY ignore TYPE DRX-CycleLengthCoefficient PRESENCE optional } ,
+ ...
+}
+
+PagingExtensions RANAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+-- **************************************************************
+--
+-- COMMON ID ELEMENTARY PROCEDURE
+--
+-- **************************************************************
+
+-- **************************************************************
+--
+-- Common ID
+--
+-- **************************************************************
+
+CommonID ::= SEQUENCE {
+ protocolIEs ProtocolIE-Container { {CommonID-IEs} },
+ protocolExtensions ProtocolExtensionContainer { {CommonIDExtensions} } OPTIONAL,
+ ...
+}
+
+CommonID-IEs RANAP-PROTOCOL-IES ::= {
+ { ID id-PermanentNAS-UE-ID CRITICALITY ignore TYPE PermanentNAS-UE-ID PRESENCE mandatory },
+ ...
+}
+
+CommonIDExtensions RANAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+-- **************************************************************
+--
+-- CN INVOKE TRACE ELEMENTARY PROCEDURE
+--
+-- **************************************************************
+
+-- **************************************************************
+--
+-- CN Invoke Trace
+--
+-- **************************************************************
+
+CN-InvokeTrace ::= SEQUENCE {
+ protocolIEs ProtocolIE-Container { {CN-InvokeTraceIEs} },
+ protocolExtensions ProtocolExtensionContainer { {CN-InvokeTraceExtensions} } OPTIONAL,
+ ...
+}
+
+CN-InvokeTraceIEs RANAP-PROTOCOL-IES ::= {
+ { ID id-TraceType CRITICALITY ignore TYPE TraceType PRESENCE mandatory } |
+ { ID id-TraceReference CRITICALITY ignore TYPE TraceReference PRESENCE mandatory } |
+ { ID id-TriggerID CRITICALITY ignore TYPE TriggerID PRESENCE optional } |
+ { ID id-UE-ID CRITICALITY ignore TYPE UE-ID PRESENCE optional } |
+ { ID id-OMC-ID CRITICALITY ignore TYPE OMC-ID PRESENCE optional },
+ ...
+}
+
+CN-InvokeTraceExtensions RANAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+-- **************************************************************
+--
+-- CN DEACTIVATE TRACE ELEMENTARY PROCEDURE
+--
+-- **************************************************************
+
+-- **************************************************************
+--
+-- CN Deactivate Trace
+--
+-- **************************************************************
+
+CN-DeactivateTrace ::= SEQUENCE {
+ protocolIEs ProtocolIE-Container { {CN-DeactivateTraceIEs} },
+ protocolExtensions ProtocolExtensionContainer { {CN-DeactivateTraceExtensions} } OPTIONAL,
+ ...
+}
+
+CN-DeactivateTraceIEs RANAP-PROTOCOL-IES ::= {
+ { ID id-TraceReference CRITICALITY ignore TYPE TraceReference PRESENCE mandatory } |
+ { ID id-TriggerID CRITICALITY ignore TYPE TriggerID PRESENCE optional },
+ ...
+}
+
+CN-DeactivateTraceExtensions RANAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+-- **************************************************************
+--
+-- LOCATION REPORTING CONTROL ELEMENTARY PROCEDURE
+--
+-- **************************************************************
+
+-- **************************************************************
+--
+-- Location Reporting Control
+--
+-- **************************************************************
+
+LocationReportingControl ::= SEQUENCE {
+ protocolIEs ProtocolIE-Container { {LocationReportingControlIEs} },
+ protocolExtensions ProtocolExtensionContainer { {LocationReportingControlExtensions} } OPTIONAL,
+ ...
+}
+
+LocationReportingControlIEs RANAP-PROTOCOL-IES ::= {
+ { ID id-RequestType CRITICALITY ignore TYPE RequestType PRESENCE mandatory },
+ ...
+}
+
+LocationReportingControlExtensions RANAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+-- **************************************************************
+--
+-- LOCATION REPORT ELEMENTARY PROCEDURE
+--
+-- **************************************************************
+
+-- **************************************************************
+--
+-- Location Report
+--
+-- **************************************************************
+
+LocationReport ::= SEQUENCE {
+ protocolIEs ProtocolIE-Container { {LocationReportIEs} },
+ protocolExtensions ProtocolExtensionContainer { {LocationReportExtensions} } OPTIONAL,
+ ...
+}
+
+LocationReportIEs RANAP-PROTOCOL-IES ::= {
+ { ID id-AreaIdentity CRITICALITY ignore TYPE AreaIdentity PRESENCE optional } |
+ { ID id-Cause CRITICALITY ignore TYPE Cause PRESENCE optional },
+ ...
+}
+
+LocationReportExtensions RANAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+-- **************************************************************
+--
+-- INITIAL UE MESSAGE ELEMENTARY PROCEDURE
+--
+-- **************************************************************
+
+-- **************************************************************
+--
+-- Initial UE Message
+--
+-- **************************************************************
+
+InitialUE-Message ::= SEQUENCE {
+ protocolIEs ProtocolIE-Container { {InitialUE-MessageIEs} },
+ protocolExtensions ProtocolExtensionContainer { {InitialUE-MessageExtensions} } OPTIONAL,
+ ...
+}
+
+InitialUE-MessageIEs RANAP-PROTOCOL-IES ::= {
+ { ID id-CN-DomainIndicator CRITICALITY ignore TYPE CN-DomainIndicator PRESENCE mandatory } |
+ { ID id-LAI CRITICALITY ignore TYPE LAI PRESENCE mandatory } |
+ { ID id-RAC CRITICALITY ignore TYPE RAC PRESENCE conditional
+ -- This IE is only present for RABs towards the PS domain -- } |
+ { ID id-SAI CRITICALITY ignore TYPE SAI PRESENCE mandatory } |
+ { ID id-NAS-PDU CRITICALITY ignore TYPE NAS-PDU PRESENCE mandatory } |
+ { ID id-IuSigConId CRITICALITY ignore TYPE IuSignallingConnectionIdentifier PRESENCE mandatory } |
+ { ID id-GlobalRNC-ID CRITICALITY ignore TYPE GlobalRNC-ID PRESENCE mandatory },
+
+ ...
+}
+
+InitialUE-MessageExtensions RANAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+-- **************************************************************
+--
+-- DIRECT TRANSFER ELEMENTARY PROCEDURE
+--
+-- **************************************************************
+
+-- **************************************************************
+--
+-- Direct Transfer
+--
+-- **************************************************************
+
+DirectTransfer ::= SEQUENCE {
+ protocolIEs ProtocolIE-Container { {DirectTransferIEs} },
+ protocolExtensions ProtocolExtensionContainer { {DirectTransferExtensions} } OPTIONAL,
+ ...
+}
+
+DirectTransferIEs RANAP-PROTOCOL-IES ::= {
+ { ID id-NAS-PDU CRITICALITY ignore TYPE NAS-PDU PRESENCE mandatory } |
+ { ID id-LAI CRITICALITY ignore TYPE LAI PRESENCE conditional
+ -- This IE is only present if the message is directed to the PS domain -- } |
+ { ID id-RAC CRITICALITY ignore TYPE RAC PRESENCE conditional
+ -- This IE is only present if the message is directed to the PS domain -- } |
+ { ID id-SAPI CRITICALITY ignore TYPE SAPI PRESENCE conditional
+ -- This IE is always used in downlink direction-- },
+ ...
+}
+
+DirectTransferExtensions RANAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+-- **************************************************************
+--
+-- OVERLOAD CONTROL ELEMENTARY PROCEDURE
+--
+-- **************************************************************
+
+-- **************************************************************
+--
+-- Overload
+--
+-- **************************************************************
+
+Overload ::= SEQUENCE {
+ protocolIEs ProtocolIE-Container { {OverloadIEs} },
+ protocolExtensions ProtocolExtensionContainer { {OverloadExtensions} } OPTIONAL,
+ ...
+}
+
+OverloadIEs RANAP-PROTOCOL-IES ::= {
+ { ID id-NumberOfSteps CRITICALITY ignore TYPE NumberOfSteps PRESENCE optional } |
+ { ID id-GlobalRNC-ID CRITICALITY ignore TYPE GlobalRNC-ID PRESENCE conditional
+ -- This IE is always used in the uplink direction -- },
+ ...
+}
+
+OverloadExtensions RANAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+-- **************************************************************
+--
+-- ERROR INDICATION ELEMENTARY PROCEDURE
+--
+-- **************************************************************
+
+-- **************************************************************
+--
+-- Error Indication
+--
+-- **************************************************************
+
+ErrorIndication ::= SEQUENCE {
+ protocolIEs ProtocolIE-Container { {ErrorIndicationIEs} },
+ protocolExtensions ProtocolExtensionContainer { {ErrorIndicationExtensions} } OPTIONAL,
+ ...
+}
+
+ErrorIndicationIEs RANAP-PROTOCOL-IES ::= {
+ { ID id-Cause CRITICALITY ignore TYPE Cause PRESENCE conditional
+ -- At least either of Cause IE or Criticality IE shall be present -- } |
+ { ID id-CriticalityDiagnostics CRITICALITY ignore TYPE CriticalityDiagnostics PRESENCE conditional
+ -- At least either of Cause IE or Criticality IE shall be present -- } |
+ { ID id-CN-DomainIndicator CRITICALITY ignore TYPE CN-DomainIndicator PRESENCE optional } |
+ { ID id-TransportLayerAddress CRITICALITY ignore TYPE TransportLayerAddress PRESENCE optional } |
+ { ID id-IuTransportAssociation CRITICALITY ignore TYPE IuTransportAssociation PRESENCE optional } |
+ { ID id-GlobalRNC-ID CRITICALITY ignore TYPE GlobalRNC-ID PRESENCE conditional
+ -- This IE is always used in the uplink direction when message is sent connectionless -- },
+ ...
+}
+
+ErrorIndicationExtensions RANAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+-- **************************************************************
+--
+-- SRNS DATA FORWARD ELEMENTARY PROCEDURE
+--
+-- **************************************************************
+
+-- **************************************************************
+--
+-- SRNS Data Forward Command
+--
+-- **************************************************************
+
+SRNS-DataForwardCommand ::= SEQUENCE {
+ protocolIEs ProtocolIE-Container { {SRNS-DataForwardCommandIEs} },
+ protocolExtensions ProtocolExtensionContainer { {SRNS-DataForwardCommandExtensions} } OPTIONAL,
+ ...
+}
+
+SRNS-DataForwardCommandIEs RANAP-PROTOCOL-IES ::= {
+ { ID id-RAB-DataForwardingList CRITICALITY ignore TYPE RAB-DataForwardingList PRESENCE conditional
+ -- This group is only present for RABs towards the PS domain -- },
+ ...
+}
+
+SRNS-DataForwardCommandExtensions RANAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+-- **************************************************************
+--
+-- FORWARD SRNS CONTEXT ELEMENTARY PROCEDURE
+--
+-- **************************************************************
+
+-- **************************************************************
+--
+-- Forward SRNS Context
+--
+-- **************************************************************
+
+ForwardSRNS-Context ::= SEQUENCE {
+ protocolIEs ProtocolIE-Container { {ForwardSRNS-ContextIEs} },
+ protocolExtensions ProtocolExtensionContainer { {ForwardSRNS-ContextExtensions} } OPTIONAL,
+ ...
+}
+
+ForwardSRNS-ContextIEs RANAP-PROTOCOL-IES ::= {
+ { ID id-RAB-ContextList CRITICALITY ignore TYPE RAB-ContextList PRESENCE mandatory },
+ ...
+}
+
+ForwardSRNS-ContextExtensions RANAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+-- **************************************************************
+--
+-- RAB ASSIGNMENT ELEMENTARY PROCEDURE
+--
+-- **************************************************************
+
+-- **************************************************************
+--
+-- RAB Assignment Request
+--
+-- **************************************************************
+
+RAB-AssignmentRequest ::= SEQUENCE {
+ protocolIEs ProtocolIE-Container { {RAB-AssignmentRequestIEs} },
+ protocolExtensions ProtocolExtensionContainer { {RAB-AssignmentRequestExtensions} } OPTIONAL,
+ ...
+}
+
+RAB-AssignmentRequestIEs RANAP-PROTOCOL-IES ::= {
+ { ID id-RAB-SetupOrModifyList CRITICALITY ignore TYPE RAB-SetupOrModifyList PRESENCE conditional
+ -- This group must be present at least when no other group is present, ie. at least one group must be present -- } |
+ { ID id-RAB-ReleaseList CRITICALITY ignore TYPE RAB-ReleaseList PRESENCE conditional
+ -- This group must be present at least when no other group is present, ie. at least one group must be present -- },
+ ...
+}
+
+RAB-SetupOrModifyList ::= RAB-IE-ContainerPairList { {RAB-SetupOrModifyItem-IEs} }
+
+RAB-SetupOrModifyItem-IEs RANAP-PROTOCOL-IES-PAIR ::= {
+ { ID id-RAB-SetupOrModifyItem FIRST CRITICALITY reject FIRST TYPE RAB-SetupOrModifyItemFirst
+ SECOND CRITICALITY ignore SECOND TYPE RAB-SetupOrModifyItemSecond
+ PRESENCE mandatory },
+ ...
+}
+
+RAB-SetupOrModifyItemFirst ::= SEQUENCE {
+ rAB-ID RAB-ID,
+ nAS-SynchronisationIndicator NAS-SynchronisationIndicator OPTIONAL
+ -- This IE is present if the relevant NAS information is provided by the CN --,
+ rAB-Parameters RAB-Parameters,
+ userPlaneInformation UserPlaneInformation,
+ transportLayerAddress TransportLayerAddress,
+ iuTransportAssociation IuTransportAssociation,
+ iE-Extensions ProtocolExtensionContainer { {RAB-SetupOrModifyItemFirst-ExtIEs} } OPTIONAL,
+ ...
+}
+
+RAB-SetupOrModifyItemFirst-ExtIEs RANAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+RAB-SetupOrModifyItemSecond ::= SEQUENCE {
+ pDP-TypeInformation PDP-TypeInformation
+ -- This IE is only present for RABs towards the PS domain -- OPTIONAL,
+ dataVolumeReportingIndication DataVolumeReportingIndication OPTIONAL
+ -- This IE, if applicable, is only present for RABs towards the PS domain --,
+ dl-GTP-PDU-SequenceNumber DL-GTP-PDU-SequenceNumber OPTIONAL
+ -- This IE, if applicable, is only present for RABs towards the PS domain --,
+ ul-GTP-PDU-SequenceNumber UL-GTP-PDU-SequenceNumber OPTIONAL
+ -- This IE, if applicable, is only present for RABs towards the PS domain --,
+ dl-N-PDU-SequenceNumber DL-N-PDU-SequenceNumber OPTIONAL
+ -- This IE, if applicable, is only present for RABs towards the PS domain --,
+ ul-N-PDU-SequenceNumber UL-N-PDU-SequenceNumber OPTIONAL
+ -- This IE, if applicable, is only present for RABs towards the PS domain --,
+ iE-Extensions ProtocolExtensionContainer { {RAB-SetupOrModifyItemSecond-ExtIEs} } OPTIONAL,
+ ...
+}
+
+RAB-SetupOrModifyItemSecond-ExtIEs RANAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+RAB-AssignmentRequestExtensions RANAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+-- **************************************************************
+--
+-- RAB Assignment Response
+--
+-- **************************************************************
+
+RAB-AssignmentResponse ::= SEQUENCE {
+ protocolIEs ProtocolIE-Container { {RAB-AssignmentResponseIEs} },
+ protocolExtensions ProtocolExtensionContainer { {RAB-AssignmentResponseExtensions} } OPTIONAL,
+ ...
+}
+
+RAB-AssignmentResponseIEs RANAP-PROTOCOL-IES ::= {
+ { ID id-RAB-SetupOrModifiedList CRITICALITY ignore TYPE RAB-SetupOrModifiedList PRESENCE conditional
+ -- This group must be present at least when no other group is present, ie. at least one group must be present -- } |
+ { ID id-RAB-ReleasedList CRITICALITY ignore TYPE RAB-ReleasedList PRESENCE conditional
+ -- This group must be present at least when no other group is present, ie. at least one group must be present -- } |
+
+ { ID id-RAB-QueuedList CRITICALITY ignore TYPE RAB-QueuedList PRESENCE conditional
+ -- This group must be present at least when no other group is present, ie. at least one group must be present -- } |
+ { ID id-RAB-FailedList CRITICALITY ignore TYPE RAB-FailedList PRESENCE conditional
+ -- This group must be present at least when no other group is present, ie. at least one group must be present -- } |
+ { ID id-RAB-ReleaseFailedList CRITICALITY ignore TYPE RAB-ReleaseFailedList PRESENCE conditional
+ -- This group must be present at least when no other group is present, ie. at least one group must be present -- } |
+ { ID id-CriticalityDiagnostics CRITICALITY ignore TYPE CriticalityDiagnostics PRESENCE optional },
+ ...
+}
+
+RAB-SetupOrModifiedList ::= RAB-IE-ContainerList { {RAB-SetupOrModifiedItemIEs} }
+
+RAB-SetupOrModifiedItemIEs RANAP-PROTOCOL-IES ::= {
+ { ID id-RAB-SetupOrModifiedItem CRITICALITY ignore TYPE RAB-SetupOrModifiedItem PRESENCE mandatory },
+ ...
+}
+
+RAB-SetupOrModifiedItem ::= SEQUENCE {
+ rAB-ID RAB-ID,
+ transportLayerAddress TransportLayerAddress OPTIONAL
+ -- This IE is only present for RABs towards the PS domain --,
+ iuTransportAssociation IuTransportAssociation OPTIONAL
+ -- This IE is only present for RABs towards the PS domain --,
+ dl-dataVolumes DataVolumeList OPTIONAL
+ -- This IE is only present if the RAB has been modified and --
+ -- RAB data volume reporting for PS domain is required --,
+ iE-Extensions ProtocolExtensionContainer { {RAB-SetupOrModifiedItem-ExtIEs} } OPTIONAL,
+ ...
+}
+
+RAB-SetupOrModifiedItem-ExtIEs RANAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+RAB-ReleasedList ::= RAB-IE-ContainerList { {RAB-ReleasedItemIEs} }
+
+RAB-ReleasedItemIEs RANAP-PROTOCOL-IES ::= {
+ { ID id-RAB-ReleasedItem CRITICALITY ignore TYPE RAB-ReleasedItem PRESENCE mandatory },
+ ...
+}
+
+RAB-ReleasedItem ::= SEQUENCE {
+ rAB-ID RAB-ID,
+ dl-dataVolumes DataVolumeList OPTIONAL
+ -- This IE is only present if data volume reporting for PS domain is required --,
+ dL-GTP-PDU-SequenceNumber DL-GTP-PDU-SequenceNumber OPTIONAL
+ -- This IE is only present for RABs towards the PS domain when the release is UTRAN initiated -- ,
+ uL-GTP-PDU-SequenceNumber UL-GTP-PDU-SequenceNumber OPTIONAL
+ -- This IE is only present for RABs towards the PS domain when the release is UTRAN initiated -- ,
+ iE-Extensions ProtocolExtensionContainer { {RAB-ReleasedItem-ExtIEs} } OPTIONAL,
+ ...
+}
+
+RAB-ReleasedItem-ExtIEs RANAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+DataVolumeList ::= SEQUENCE (SIZE (1..maxNrOfVol)) OF
+ SEQUENCE {
+ dl-UnsuccessfullyTransmittedDataVolume UnsuccessfullyTransmittedDataVolume,
+ dataVolumeReference DataVolumeReference OPTIONAL,
+ iE-Extensions ProtocolExtensionContainer { {DataVolumeList-ExtIEs} } OPTIONAL,
+ ...
+ }
+
+DataVolumeList-ExtIEs RANAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+RAB-QueuedList ::= RAB-IE-ContainerList { {RAB-QueuedItemIEs} }
+
+RAB-QueuedItemIEs RANAP-PROTOCOL-IES ::= {
+ { ID id-RAB-QueuedItem CRITICALITY ignore TYPE RAB-QueuedItem PRESENCE mandatory },
+ ...
+}
+
+RAB-QueuedItem ::= SEQUENCE {
+ rAB-ID RAB-ID,
+ iE-Extensions ProtocolExtensionContainer { {RAB-QueuedItem-ExtIEs} } OPTIONAL,
+ ...
+}
+
+RAB-QueuedItem-ExtIEs RANAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+RAB-ReleaseFailedList ::= RAB-FailedList
+
+RAB-AssignmentResponseExtensions RANAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+-- **************************************************************
+--
+-- PRIVATE MESSAGE
+--
+-- **************************************************************
+
+PrivateMessage ::= SEQUENCE {
+ privateIEs PrivateIE-Container { {PrivateMessage-IEs } },
+ ...
+}
+
+PrivateMessage-IEs RANAP-PRIVATE-IES ::= {
+ ...
+}
+
+-- **************************************************************
+--
+-- RANAP RELOCATION INFORMATION ELEMENTARY PROCEDURE
+--
+-- **************************************************************
+
+RANAP-RelocationInformation ::= SEQUENCE {
+ protocolIEs ProtocolIE-Container { {RANAP-RelocationInformationIEs} },
+ protocolExtensions ProtocolExtensionContainer { {RANAP-RelocationInformationExtensions} } OPTIONAL,
+ ...
+}
+
+RANAP-RelocationInformationIEs RANAP-PROTOCOL-IES ::= {
+ { ID id-DirectTransferInformationList-RANAP-RelocInf
+ CRITICALITY ignore TYPE DirectTransferInformationList-RANAP-RelocInf
+ PRESENCE optional } |
+ { ID id-RAB-ContextList-RANAP-RelocInf CRITICALITY ignore TYPE RAB-ContextList-RANAP-RelocInf PRESENCE optional },
+ ...
+}
+
+DirectTransferInformationList-RANAP-RelocInf ::= DirectTransfer-IE-ContainerList { {DirectTransferInformationItemIEs-RANAP-RelocInf} }
+
+DirectTransferInformationItemIEs-RANAP-RelocInf RANAP-PROTOCOL-IES ::= {
+ { ID id-DirectTransferInformationItem-RANAP-RelocInf
+ CRITICALITY ignore TYPE DirectTransferInformationItem-RANAP-RelocInf
+ PRESENCE mandatory },
+ ...
+}
+
+DirectTransferInformationItem-RANAP-RelocInf ::= SEQUENCE {
+ nAS-PDU NAS-PDU,
+ sAPI SAPI,
+ iE-Extensions ProtocolExtensionContainer { {RANAP-DirectTransferInformationItem-ExtIEs-RANAP-RelocInf} } OPTIONAL,
+ ...
+}
+
+RANAP-DirectTransferInformationItem-ExtIEs-RANAP-RelocInf RANAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+RAB-ContextList-RANAP-RelocInf ::= RAB-IE-ContainerList { {RAB-ContextItemIEs-RANAP-RelocInf} }
+
+RAB-ContextItemIEs-RANAP-RelocInf RANAP-PROTOCOL-IES ::= {
+ { ID id-RAB-ContextItem-RANAP-RelocInf CRITICALITY ignore TYPE RAB-ContextItem-RANAP-RelocInf PRESENCE mandatory },
+ ...
+}
+
+RAB-ContextItem-RANAP-RelocInf ::= SEQUENCE {
+ rAB-ID RAB-ID,
+ dl-GTP-PDU-SequenceNumber DL-GTP-PDU-SequenceNumber,
+ ul-GTP-PDU-SequenceNumber UL-GTP-PDU-SequenceNumber,
+ dl-N-PDU-SequenceNumber DL-N-PDU-SequenceNumber,
+ ul-N-PDU-SequenceNumber UL-N-PDU-SequenceNumber,
+ iE-Extensions ProtocolExtensionContainer { {RAB-ContextItem-ExtIEs-RANAP-RelocInf} } OPTIONAL,
+ ...
+}
+
+RAB-ContextItem-ExtIEs-RANAP-RelocInf RANAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+RANAP-RelocationInformationExtensions RANAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+-- END
+-- **************************************************************
+--
+-- Elementary Procedure definitions
+--
+-- **************************************************************
+
+-- RANAP-PDU-Descriptions { object identifier to be allocated }--
+-- DEFINITIONS AUTOMATIC TAGS ::=
+
+-- BEGIN
+
+-- **************************************************************
+--
+-- IE parameter types from other modules.
+--
+-- **************************************************************
+
+
+-- **************************************************************
+--
+-- Interface Elementary Procedure Class
+--
+-- **************************************************************
+
+RANAP-ELEMENTARY-PROCEDURE ::= CLASS {
+ &InitiatingMessage ,
+ &SuccessfulOutcome OPTIONAL,
+ &UnsuccessfulOutcome OPTIONAL,
+ &Outcome OPTIONAL,
+ &procedureCode ProcedureCode UNIQUE,
+ &criticality Criticality DEFAULT ignore
+}
+WITH SYNTAX {
+ INITIATING MESSAGE &InitiatingMessage
+ [SUCCESSFUL OUTCOME &SuccessfulOutcome]
+ [UNSUCCESSFUL OUTCOME &UnsuccessfulOutcome]
+ [OUTCOME &Outcome]
+ PROCEDURE CODE &procedureCode
+ [CRITICALITY &criticality]
+}
+
+-- **************************************************************
+--
+-- Interface PDU Definition
+--
+-- **************************************************************
+
+RANAP-PDU ::= CHOICE {
+ initiatingMessage InitiatingMessage,
+ successfulOutcome SuccessfulOutcome,
+ unsuccessfulOutcome UnsuccessfulOutcome,
+ outcome Outcome,
+ ...
+}
+
+InitiatingMessage ::= SEQUENCE {
+ procedureCode RANAP-ELEMENTARY-PROCEDURE.&procedureCode ({RANAP-ELEMENTARY-PROCEDURES}),
+ criticality RANAP-ELEMENTARY-PROCEDURE.&criticality ({RANAP-ELEMENTARY-PROCEDURES}{@procedureCode}),
+ value RANAP-ELEMENTARY-PROCEDURE.&InitiatingMessage ({RANAP-ELEMENTARY-PROCEDURES}{@procedureCode})
+}
+
+SuccessfulOutcome ::= SEQUENCE {
+ procedureCode RANAP-ELEMENTARY-PROCEDURE.&procedureCode ({RANAP-ELEMENTARY-PROCEDURES}),
+ criticality RANAP-ELEMENTARY-PROCEDURE.&criticality ({RANAP-ELEMENTARY-PROCEDURES}{@procedureCode}),
+ value RANAP-ELEMENTARY-PROCEDURE.&SuccessfulOutcome ({RANAP-ELEMENTARY-PROCEDURES}{@procedureCode})
+}
+
+UnsuccessfulOutcome ::= SEQUENCE {
+ procedureCode RANAP-ELEMENTARY-PROCEDURE.&procedureCode ({RANAP-ELEMENTARY-PROCEDURES}),
+ criticality RANAP-ELEMENTARY-PROCEDURE.&criticality ({RANAP-ELEMENTARY-PROCEDURES}{@procedureCode}),
+ value RANAP-ELEMENTARY-PROCEDURE.&UnsuccessfulOutcome ({RANAP-ELEMENTARY-PROCEDURES}{@procedureCode})
+}
+
+Outcome ::= SEQUENCE {
+ procedureCode RANAP-ELEMENTARY-PROCEDURE.&procedureCode ({RANAP-ELEMENTARY-PROCEDURES}),
+ criticality RANAP-ELEMENTARY-PROCEDURE.&criticality ({RANAP-ELEMENTARY-PROCEDURES}{@procedureCode}),
+ value RANAP-ELEMENTARY-PROCEDURE.&Outcome ({RANAP-ELEMENTARY-PROCEDURES}{@procedureCode})
+}
+
+-- **************************************************************
+--
+-- Interface Elementary Procedure List
+--
+-- **************************************************************
+
+RANAP-ELEMENTARY-PROCEDURES RANAP-ELEMENTARY-PROCEDURE ::= {
+ RANAP-ELEMENTARY-PROCEDURES-CLASS-1 |
+ RANAP-ELEMENTARY-PROCEDURES-CLASS-2 |
+ RANAP-ELEMENTARY-PROCEDURES-CLASS-3 ,
+ ...
+}
+
+
+RANAP-ELEMENTARY-PROCEDURES-CLASS-1 RANAP-ELEMENTARY-PROCEDURE ::= {
+ iu-Release |
+ relocationPreparation |
+ relocationResourceAllocation |
+ relocationCancel |
+ sRNS-ContextTransfer |
+ securityModeControl |
+ dataVolumeReport |
+ cN-InformationBroadcast |
+ reset |
+ resetResource ,
+ ...
+}
+
+RANAP-ELEMENTARY-PROCEDURES-CLASS-2 RANAP-ELEMENTARY-PROCEDURE ::= {
+ rAB-ReleaseRequest |
+ iu-ReleaseRequest |
+ relocationDetect |
+ relocationComplete |
+ paging |
+ commonID |
+ cN-InvokeTrace |
+ cN-DeactivateTrace |
+ locationReportingControl |
+ locationReport |
+ initialUE-Message |
+ directTransfer |
+ overloadControl |
+ errorIndication |
+ sRNS-DataForward |
+ forwardSRNS-Context |
+ privateMessage |
+ rANAP-Relocation ,
+ ...
+}
+
+RANAP-ELEMENTARY-PROCEDURES-CLASS-3 RANAP-ELEMENTARY-PROCEDURE ::= {
+ rAB-Assignment ,
+ ...
+}
+
+-- **************************************************************
+--
+-- Interface Elementary Procedures
+--
+-- **************************************************************
+
+iu-Release RANAP-ELEMENTARY-PROCEDURE ::= {
+ INITIATING MESSAGE Iu-ReleaseCommand
+ SUCCESSFUL OUTCOME Iu-ReleaseComplete
+ PROCEDURE CODE id-Iu-Release
+ CRITICALITY ignore
+}
+
+relocationPreparation RANAP-ELEMENTARY-PROCEDURE ::= {
+ INITIATING MESSAGE RelocationRequired
+ SUCCESSFUL OUTCOME RelocationCommand
+ UNSUCCESSFUL OUTCOME RelocationPreparationFailure
+ PROCEDURE CODE id-RelocationPreparation
+ CRITICALITY ignore
+}
+
+relocationResourceAllocation RANAP-ELEMENTARY-PROCEDURE ::= {
+ INITIATING MESSAGE RelocationRequest
+ SUCCESSFUL OUTCOME RelocationRequestAcknowledge
+ UNSUCCESSFUL OUTCOME RelocationFailure
+ PROCEDURE CODE id-RelocationResourceAllocation
+ CRITICALITY ignore
+}
+
+relocationCancel RANAP-ELEMENTARY-PROCEDURE ::= {
+ INITIATING MESSAGE RelocationCancel
+ SUCCESSFUL OUTCOME RelocationCancelAcknowledge
+ PROCEDURE CODE id-RelocationCancel
+ CRITICALITY ignore
+}
+
+sRNS-ContextTransfer RANAP-ELEMENTARY-PROCEDURE ::= {
+ INITIATING MESSAGE SRNS-ContextRequest
+ SUCCESSFUL OUTCOME SRNS-ContextResponse
+ PROCEDURE CODE id-SRNS-ContextTransfer
+ CRITICALITY ignore
+}
+
+securityModeControl RANAP-ELEMENTARY-PROCEDURE ::= {
+ INITIATING MESSAGE SecurityModeCommand
+ SUCCESSFUL OUTCOME SecurityModeComplete
+ UNSUCCESSFUL OUTCOME SecurityModeReject
+ PROCEDURE CODE id-SecurityModeControl
+ CRITICALITY ignore
+}
+
+dataVolumeReport RANAP-ELEMENTARY-PROCEDURE ::= {
+ INITIATING MESSAGE DataVolumeReportRequest
+ SUCCESSFUL OUTCOME DataVolumeReport
+ PROCEDURE CODE id-DataVolumeReport
+ CRITICALITY ignore
+}
+
+cN-InformationBroadcast RANAP-ELEMENTARY-PROCEDURE ::= {
+ INITIATING MESSAGE CN-InformationBroadcastRequest
+ SUCCESSFUL OUTCOME CN-InformationBroadcastConfirm
+ UNSUCCESSFUL OUTCOME CN-InformationBroadcastReject
+ PROCEDURE CODE id-CN-InformationBroadcast
+ CRITICALITY ignore
+}
+
+reset RANAP-ELEMENTARY-PROCEDURE ::= {
+ INITIATING MESSAGE Reset
+ SUCCESSFUL OUTCOME ResetAcknowledge
+ PROCEDURE CODE id-Reset
+ CRITICALITY ignore
+}
+
+rAB-ReleaseRequest RANAP-ELEMENTARY-PROCEDURE ::= {
+ INITIATING MESSAGE RAB-ReleaseRequest
+ PROCEDURE CODE id-RAB-ReleaseRequest
+ CRITICALITY ignore
+}
+
+iu-ReleaseRequest RANAP-ELEMENTARY-PROCEDURE ::= {
+ INITIATING MESSAGE Iu-ReleaseRequest
+ PROCEDURE CODE id-Iu-ReleaseRequest
+ CRITICALITY ignore
+}
+
+relocationDetect RANAP-ELEMENTARY-PROCEDURE ::= {
+ INITIATING MESSAGE RelocationDetect
+ PROCEDURE CODE id-RelocationDetect
+ CRITICALITY ignore
+}
+
+relocationComplete RANAP-ELEMENTARY-PROCEDURE ::= {
+ INITIATING MESSAGE RelocationComplete
+ PROCEDURE CODE id-RelocationComplete
+ CRITICALITY ignore
+}
+
+paging RANAP-ELEMENTARY-PROCEDURE ::= {
+ INITIATING MESSAGE Paging
+ PROCEDURE CODE id-Paging
+ CRITICALITY ignore
+}
+
+commonID RANAP-ELEMENTARY-PROCEDURE ::= {
+ INITIATING MESSAGE CommonID
+ PROCEDURE CODE id-CommonID
+ CRITICALITY ignore
+}
+
+cN-InvokeTrace RANAP-ELEMENTARY-PROCEDURE ::= {
+ INITIATING MESSAGE CN-InvokeTrace
+ PROCEDURE CODE id-CN-InvokeTrace
+ CRITICALITY ignore
+}
+
+cN-DeactivateTrace RANAP-ELEMENTARY-PROCEDURE ::= {
+ INITIATING MESSAGE CN-DeactivateTrace
+ PROCEDURE CODE id-CN-DeactivateTrace
+ CRITICALITY ignore
+}
+
+locationReportingControl RANAP-ELEMENTARY-PROCEDURE ::= {
+ INITIATING MESSAGE LocationReportingControl
+ PROCEDURE CODE id-LocationReportingControl
+ CRITICALITY ignore
+}
+
+locationReport RANAP-ELEMENTARY-PROCEDURE ::= {
+ INITIATING MESSAGE LocationReport
+ PROCEDURE CODE id-LocationReport
+ CRITICALITY ignore
+}
+
+initialUE-Message RANAP-ELEMENTARY-PROCEDURE ::= {
+ INITIATING MESSAGE InitialUE-Message
+ PROCEDURE CODE id-InitialUE-Message
+ CRITICALITY ignore
+}
+
+directTransfer RANAP-ELEMENTARY-PROCEDURE ::= {
+ INITIATING MESSAGE DirectTransfer
+ PROCEDURE CODE id-DirectTransfer
+ CRITICALITY ignore
+}
+
+overloadControl RANAP-ELEMENTARY-PROCEDURE ::= {
+ INITIATING MESSAGE Overload
+ PROCEDURE CODE id-OverloadControl
+ CRITICALITY ignore
+}
+
+errorIndication RANAP-ELEMENTARY-PROCEDURE ::= {
+ INITIATING MESSAGE ErrorIndication
+ PROCEDURE CODE id-ErrorIndication
+ CRITICALITY ignore
+}
+
+sRNS-DataForward RANAP-ELEMENTARY-PROCEDURE ::= {
+ INITIATING MESSAGE SRNS-DataForwardCommand
+ PROCEDURE CODE id-SRNS-DataForward
+ CRITICALITY ignore
+}
+
+forwardSRNS-Context RANAP-ELEMENTARY-PROCEDURE ::= {
+ INITIATING MESSAGE ForwardSRNS-Context
+ PROCEDURE CODE id-ForwardSRNS-Context
+ CRITICALITY ignore
+}
+
+rAB-Assignment RANAP-ELEMENTARY-PROCEDURE ::= {
+ INITIATING MESSAGE RAB-AssignmentRequest
+ OUTCOME RAB-AssignmentResponse
+ PROCEDURE CODE id-RAB-Assignment
+ CRITICALITY ignore
+}
+
+privateMessage RANAP-ELEMENTARY-PROCEDURE ::= {
+ INITIATING MESSAGE PrivateMessage
+
+ PROCEDURE CODE id-privateMessage
+ CRITICALITY ignore
+}
+
+resetResource RANAP-ELEMENTARY-PROCEDURE ::= {
+ INITIATING MESSAGE ResetResource
+ SUCCESSFUL OUTCOME ResetResourceAcknowledge
+ PROCEDURE CODE id-ResetResource
+ CRITICALITY ignore
+}
+
+rANAP-Relocation RANAP-ELEMENTARY-PROCEDURE ::= {
+ INITIATING MESSAGE RANAP-RelocationInformation
+ PROCEDURE CODE id-RANAP-Relocation
+ CRITICALITY ignore
+}
+
+END
diff --git a/lib/asn1/test/asn1_SUITE_data/RANAPSET.set.asn1 b/lib/asn1/test/asn1_SUITE_data/RANAPSET.set.asn1
new file mode 100644
index 0000000000..b40936514e
--- /dev/null
+++ b/lib/asn1/test/asn1_SUITE_data/RANAPSET.set.asn1
@@ -0,0 +1,6 @@
+RANAP-CommonDataTypes.asn1
+RANAP-Constants.asn1
+RANAP-Containers.asn1
+RANAP-IEs.asn1
+RANAP-PDU-Contents.asn1
+RANAP-PDU-Descriptions.asn1
diff --git a/lib/asn1/test/asn1_SUITE_data/RANAPextract1.asn b/lib/asn1/test/asn1_SUITE_data/RANAPextract1.asn
new file mode 100644
index 0000000000..2f28cb7384
--- /dev/null
+++ b/lib/asn1/test/asn1_SUITE_data/RANAPextract1.asn
@@ -0,0 +1,142 @@
+RANAPextract1 DEFINITIONS ::=
+BEGIN
+
+
+RANAP-ELEMENTARY-PROCEDURE ::= CLASS {
+ &InitiatingMessage ,
+ &SuccessfulOutcome OPTIONAL,
+ &UnsuccessfulOutcome OPTIONAL,
+ &Outcome OPTIONAL,
+ &procedureCode ProcedureCode UNIQUE,
+ &criticality Criticality DEFAULT ignore
+}
+WITH SYNTAX {
+ INITIATING MESSAGE &InitiatingMessage
+ [SUCCESSFUL OUTCOME &SuccessfulOutcome]
+ [UNSUCCESSFUL OUTCOME &UnsuccessfulOutcome]
+ [OUTCOME &Outcome]
+ PROCEDURE CODE &procedureCode
+ [CRITICALITY &criticality]
+}
+
+RANAP-PDU ::= CHOICE {
+ initiatingMessage InitiatingMessage,
+-- successfulOutcome SuccessfulOutcome,
+-- unsuccessfulOutcome UnsuccessfulOutcome,
+-- outcome Outcome,
+ ...
+}
+
+InitiatingMessage ::= SEQUENCE {
+ procedureCode RANAP-ELEMENTARY-PROCEDURE.&procedureCode ({RANAP-ELEMENTARY-PROCEDURES}),
+ criticality RANAP-ELEMENTARY-PROCEDURE.&criticality ({RANAP-ELEMENTARY-PROCEDURES}{@procedureCode}),
+ value RANAP-ELEMENTARY-PROCEDURE.&InitiatingMessage ({RANAP-ELEMENTARY-PROCEDURES}{@procedureCode})
+ }
+
+
+InitiatingMessage2 ::= SEQUENCE {
+ procedureCode RANAP-ELEMENTARY-PROCEDURE.&procedureCode ({RANAP-ELEMENTARY-PROCEDURES-2}),
+ criticality RANAP-ELEMENTARY-PROCEDURE.&criticality ({RANAP-ELEMENTARY-PROCEDURES-2}{@procedureCode}),
+ value RANAP-ELEMENTARY-PROCEDURE.&InitiatingMessage ({RANAP-ELEMENTARY-PROCEDURES-2}{@procedureCode})
+}
+
+iu-Release RANAP-ELEMENTARY-PROCEDURE ::= {
+ INITIATING MESSAGE Iu-ReleaseCommand
+ SUCCESSFUL OUTCOME Iu-ReleaseComplete
+ PROCEDURE CODE id-Iu-Release
+ CRITICALITY ignore
+}
+
+relocationPreparation RANAP-ELEMENTARY-PROCEDURE ::= {
+ INITIATING MESSAGE Iu-ReleaseCommand
+ SUCCESSFUL OUTCOME Iu-ReleaseComplete
+ PROCEDURE CODE id-RelocationPreparation
+ CRITICALITY notify
+}
+
+object3 RANAP-ELEMENTARY-PROCEDURE ::= {
+ &InitiatingMessage Iu-ReleaseCommand,
+ &SuccessfulOutcome Iu-ReleaseComplete,
+ &procedureCode id-Iu-Release-3,
+ &criticality reject
+ }
+
+
+-- OTP-5466
+testObject RANAP-ELEMENTARY-PROCEDURE ::= {
+ INITIATING MESSAGE Iu-ReleaseCommand
+ SUCCESSFUL OUTCOME Iu-ReleaseComplete
+ PROCEDURE CODE id-test
+ CRITICALITY notify
+}
+
+testObject2 RANAP-ELEMENTARY-PROCEDURE ::= {
+ INITIATING MESSAGE Iu-ReleaseCommand
+ SUCCESSFUL OUTCOME Iu-ReleaseComplete
+ PROCEDURE CODE id-test2
+ CRITICALITY notify
+}
+-- OTP-5466
+
+
+
+RANAP-ELEMENTARY-PROCEDURES RANAP-ELEMENTARY-PROCEDURE ::= {
+ iu-Release |
+ relocationPreparation ,
+ ...
+ }
+
+-- additional definition R-E-P and change in RANAP-ELEMENTARY-PROCEDURES-2
+-- from RANAP-ELEMENTARY-PROCEDURE to R-E-P to test OTP-4441
+
+R-E-P ::= RANAP-ELEMENTARY-PROCEDURE
+
+-- add for RANAP-ELEMENTARY-PROCEDURES-2 and object3 OTP-4275
+RANAP-ELEMENTARY-PROCEDURES-2 RANAP-ELEMENTARY-PROCEDURE ::= {
+ iu-Release |
+ relocationPreparation ,
+ ...,
+ object3
+}
+
+
+-- OTP-5466
+RANAP-ELEMENTARY-PROCEDURES-3 RANAP-ELEMENTARY-PROCEDURE ::= {
+ {INITIATING MESSAGE Iu-ReleaseCommand
+ SUCCESSFUL OUTCOME Iu-ReleaseComplete
+ PROCEDURE CODE id-test
+ CRITICALITY notify}
+}
+
+RANAP-ELEMENTARY-PROCEDURES-4 RANAP-ELEMENTARY-PROCEDURE ::= {
+ iu-Release|
+ testObject,
+ ...,
+ relocationPreparation |
+ testObject2
+}
+-- OTP-5466
+
+
+
+
+Iu-ReleaseCommand ::= SEQUENCE {
+ first INTEGER,
+ second BOOLEAN
+ }
+
+Iu-ReleaseComplete ::= INTEGER (1..510)
+
+ProcedureCode ::= INTEGER (0..255)
+Criticality ::= ENUMERATED { reject, ignore, notify }
+id-Iu-Release INTEGER ::= 1
+id-RelocationPreparation INTEGER ::= 2
+id-Iu-Release-3 INTEGER ::= 3
+-- OTP-5466
+id-test INTEGER ::= 4
+id-test2 INTEGER ::= 5
+-- OTP-5466
+
+END
+
+
diff --git a/lib/asn1/test/asn1_SUITE_data/ROSE.asn1 b/lib/asn1/test/asn1_SUITE_data/ROSE.asn1
new file mode 100644
index 0000000000..2fefae3caf
--- /dev/null
+++ b/lib/asn1/test/asn1_SUITE_data/ROSE.asn1
@@ -0,0 +1,449 @@
+ROSE DEFINITIONS IMPLICIT TAGS ::=
+
+
+BEGIN
+
+OPERATION ::= CLASS
+{
+ &ArgumentType OPTIONAL,
+ &argumentTypeOptional BOOLEAN OPTIONAL,
+ &returnResult BOOLEAN DEFAULT TRUE,
+ &ResultType OPTIONAL,
+ &resultTypeOptional BOOLEAN OPTIONAL,
+ &Errors ERROR OPTIONAL,
+ &Linked OPERATION OPTIONAL,
+ &synchronous BOOLEAN DEFAULT FALSE,
+ &idempotent BOOLEAN DEFAULT FALSE,
+ &alwaysReturns BOOLEAN DEFAULT TRUE,
+ &InvokePriority Priority OPTIONAL,
+ &ResultPriority Priority OPTIONAL,
+ &operationCode Code UNIQUE OPTIONAL
+ }
+WITH SYNTAX
+ {
+ [ARGUMENT &ArgumentType [OPTIONAL &argumentTypeOptional]]
+ [RESULT &ResultType [OPTIONAL &resultTypeOptional]]
+ [RETURN RESULT &returnResult]
+ [ERRORS &Errors]
+ [LINKED &Linked]
+ [SYNCHRONOUS &synchronous]
+ [IDEMPOTENT &idempotent]
+ [ALWAYS RESPONDS &alwaysReturns]
+ [INVOKE PRIORITY &InvokePriority]
+ [RESULT-PRIORITY &ResultPriority]
+ [CODE &operationCode]
+ }
+
+ERROR ::= CLASS
+{
+ &ParameterType OPTIONAL,
+ &parameterTypeOptional BOOLEAN OPTIONAL,
+ &ErrorPriority Priority OPTIONAL,
+ &errorCode Code UNIQUE OPTIONAL
+ }
+WITH SYNTAX
+{
+ [PARAMETER &ParameterType [OPTIONAL &parameterTypeOptional]]
+ [PRIORITY &ErrorPriority]
+ [CODE &errorCode]
+ }
+
+OPERATION-PACKAGE ::= CLASS
+{
+ &Both OPERATION OPTIONAL,
+ &Consumer OPERATION OPTIONAL,
+ &Supplier OPERATION OPTIONAL,
+ &id OBJECT IDENTIFIER UNIQUE OPTIONAL
+ }
+WITH SYNTAX
+{
+ [OPERATIONS &Both]
+ [CONSUMER INVOKES &Supplier]
+ [SUPPLIER INVOKES &Consumer]
+ [ID &id]
+ }
+
+CONNECTION-PACKAGE ::= CLASS
+{
+ &bind OPERATION DEFAULT emptyBind,
+ &unbind OPERATION DEFAULT emptyUnbind,
+ &responderCanUnbind BOOLEAN DEFAULT FALSE,
+ &unbindCanFail BOOLEAN DEFAULT FALSE,
+ &id OBJECT IDENTIFIER UNIQUE OPTIONAL
+ }
+WITH SYNTAX
+{
+ [BIND &bind]
+ [UNBIND &unbind]
+ [RESPONDER UNBIND &responderCanUnbind]
+ [FAILURE TO UNBIND &unbindCanFail]
+ [ID &id]
+ }
+
+CONTRACT ::= CLASS
+{
+ &connection CONNECTION-PACKAGE OPTIONAL,
+ &OperationsOf OPERATION-PACKAGE OPTIONAL,
+ &InitiatorConsumerOf OPERATION-PACKAGE OPTIONAL,
+ &InitiatorSupplierOf OPERATION-PACKAGE OPTIONAL,
+ &id OBJECT IDENTIFIER UNIQUE OPTIONAL
+ }
+WITH SYNTAX
+{
+ [CONNECTION &connection]
+ [OPERATIONS OF &OperationsOf]
+ [INITIATOR CONSUMER OF &InitiatorConsumerOf]
+ [RESPONDER CONSUMER OF &InitiatorSupplierOf]
+ [ID &id]
+}
+
+ROS-OBJECT-CLASS ::= CLASS
+{
+ &Is ROS-OBJECT-CLASS OPTIONAL,
+ &Initiates CONTRACT OPTIONAL,
+ &Responds CONTRACT OPTIONAL,
+ &InitiatesAndResponds CONTRACT OPTIONAL,
+ &id OBJECT IDENTIFIER UNIQUE
+ }
+WITH SYNTAX
+{
+ [IS &Is]
+ [BOTH &InitiatesAndResponds]
+ [INITIATES &Initiates]
+ [RESPONDS &Responds]
+ ID &id
+ }
+
+Code ::= CHOICE
+{
+ local INTEGER,
+ global OBJECT IDENTIFIER
+ }
+
+Priority ::= INTEGER (0..MAX)
+
+ROS {InvokeId:InvokeIdSet,OPERATION:Invokable,OPERATION:Returnable} ::= CHOICE
+ {
+ invoke [1] Invoke {{InvokeIdSet}, {Invokable}},
+ returnResult [2] ReturnResult {{Returnable}},
+ returnError [3] ReturnError {{Errors{{Returnable}}}},
+ reject [4] Reject
+ }
+(CONSTRAINED BY {-- must conform to the above definition --}
+ ! RejectProblem : general-unrecognizedPDU)
+
+Invoke {InvokeId:InvokeIdSet, OPERATION:Operations} ::= SEQUENCE
+{
+ invokeId InvokeId (InvokeIdSet)
+ (CONSTRAINED BY {-- must be unambiguous --}
+ ! RejectProblem : invoke-duplicateInvocation),
+ linkedId CHOICE {
+ present [0] IMPLICIT present < InvokeId,
+ absent [1] IMPLICIT NULL
+ }
+ (CONSTRAINED BY {-- must identify an outstanding operation --}
+ ! RejectProblem : invoke-unrecognizedLinkedId)
+ (CONSTRAINED BY {-- which has one or more linked operations--}
+ ! RejectProblem : invoke-linkedResponseUnexpected)
+ OPTIONAL,
+ opcode OPERATION.&operationCode
+ ({Operations}
+ ! RejectProblem : invoke-unrecognizedOperation),
+ argument OPERATION.&ArgumentType
+ ({Operations} {@opcode}
+ ! RejectProblem : invoke-mistypedArgument)
+ OPTIONAL
+ }
+(CONSTRAINED BY {-- must conform to the above definition --}
+ ! RejectProblem : general-mistypedPDU)
+(
+WITH COMPONENTS
+{...,
+ linkedId ABSENT
+ }
+| WITH COMPONENTS
+{...,
+ linkedId PRESENT,
+ opcode
+ (CONSTRAINED BY {-- must be in the &Linked field of the associated operation --
+ }
+ ! RejectProblem : invoke-unexpectedLinkedOperation)
+ }
+)
+
+ReturnResult {OPERATION:Operations}::= SEQUENCE
+{
+ invokeId InvokeId
+ (CONSTRAINED BY {-- must be that for an outstanding operation --}
+ ! RejectProblem:returnResult-unrecognizedInvocation)
+ (CONSTRAINED BY {-- which returns a result --}
+ ! RejectProblem:returnResult-resultResponseUnexpected),
+ result SEQUENCE
+ {
+ opcode OPERATION.&operationCode
+ ({Operations})(CONSTRAINED BY {-- identified by invokeId --}
+ ! RejectProblem:returnResult-unrecognizedInvocation),
+ result OPERATION.&ResultType ({Operations} {@.opcode}
+ ! RejectProblem:returnResult-mistypedResult)
+ }
+ OPTIONAL
+ }
+(CONSTRAINED BY {-- must conform to the above definition --
+ }
+! RejectProblem:general-mistypedPDU)
+
+ReturnError {ERROR:Errors} ::= SEQUENCE
+{
+ invokeId InvokeId
+ (CONSTRAINED BY {-- must be that for an outstanding operation --
+ }
+ ! RejectProblem : returnError-unrecognizedInvocation)
+ (CONSTRAINED BY {-- which returns an error --
+ }
+ ! RejectProblem : returnError-errorResponseUnexpected),
+ errcode ERROR.&errorCode
+ ({Errors}
+ ! RejectProblem : returnError-unrecognizedError)
+ (CONSTRAINED BY {-- must be in the &Errors field of the associated operation --
+ }
+ ! RejectProblem : returnError-unexpectedError),
+ parameter ERROR.&ParameterType
+ ({Errors}{@errcode}
+ ! RejectProblem : returnError-mistypedParameter) OPTIONAL
+ }
+(CONSTRAINED BY {-- must conform to the above definition --
+ }
+! RejectProblem : general-mistypedPDU)
+
+Reject ::= SEQUENCE
+{
+ invokeId InvokeId,
+ problem CHOICE
+ {
+ general [0] GeneralProblem,
+ invoke [1] InvokeProblem,
+ returnResult [2] ReturnResultProblem,
+ returnError [3] ReturnErrorProblem
+ }
+ }
+(CONSTRAINED BY {-- must conform to the above definition --
+ }
+! RejectProblem : general-mistypedPDU)
+
+GeneralProblem ::= INTEGER
+{
+ unrecognizedPDU (0),
+ mistypedPDU (1),
+ badlyStructuredPDU (2)
+ }
+
+InvokeProblem ::= INTEGER
+{
+ duplicateInvocation (0),
+ unrecognizedOperation (1),
+ mistypedArgument (2),
+ resourceLimitation (3),
+ releaseInProgress (4),
+ unrecognizedLinkedId (5),
+ linkedResponseUnexpected (6),
+ unexpectedLinkedOperation (7)
+ }
+
+ReturnResultProblem ::= INTEGER
+{
+ unrecognizedInvocation (0),
+ resultResponseUnexpected (1),
+ mistypedResult (2)
+ }
+
+ReturnErrorProblem ::= INTEGER
+{
+ unrecognizedInvocation (0),
+ errorResponseUnexpected (1),
+ unrecognizedError (2),
+ unexpectedError (3),
+ mistypedParameter (4)
+ }
+
+RejectProblem ::= INTEGER
+{
+ general-unrecognizedPDU (0),
+ general-mistypedPDU (1),
+ general-badlyStructuredPDU (2),
+ invoke-duplicateInvocation (10),
+ invoke-unrecognizedOperation (11),
+ invoke-mistypedArgument (12),
+ invoke-resourceLimitation (13),
+ invoke-releaseInProgress (14),
+ invoke-unrecognizedLinkedId (15),
+ invoke-linkedResponseUnexpected (16),
+ invoke-unexpectedLinkedOperation (17),
+ returnResult-unrecognizedInvocation (20),
+ returnResult-resultResponseUnexpected (21),
+ returnResult-mistypedResult (22),
+ returnError-unrecognizedInvocation (30),
+ returnError-errorResponseUnexpected (31),
+ returnError-unrecognizedError (32),
+ returnError-unexpectedError (33),
+ returnError-mistypedParameter (34)
+ }
+
+InvokeId ::= CHOICE
+{
+ present INTEGER,
+ absent NULL
+ }
+
+noInvokeId InvokeId ::= absent:NULL
+
+NoInvokeId InvokeId ::= {noInvokeId}
+
+Errors {OPERATION:Operations} ERROR ::= {Operations.&Errors}
+
+Bind {OPERATION:operation} ::= CHOICE
+{
+ bind-invoke [16] OPERATION.&ArgumentType({operation}),
+ bind-result [17] OPERATION.&ResultType ({operation}),
+ bind-error [18] OPERATION.&Errors.&ParameterType ({operation})
+ }
+
+Unbind {OPERATION:operation} ::= CHOICE
+{
+ unbind-invoke [19] OPERATION.&ArgumentType({operation}),
+ unbind-result [20] OPERATION.&ResultType ({operation}),
+ unbind-error [21] OPERATION.&Errors.&ParameterType ({operation})
+ }
+
+emptyBind OPERATION ::= {ERRORS {refuse} SYNCHRONOUS TRUE}
+
+emptyUnbind OPERATION ::= { SYNCHRONOUS TRUE }
+
+refuse ERROR ::= {CODE local:-1}
+
+no-op OPERATION ::=
+ {
+ IDEMPOTENT TRUE
+ ALWAYS RESPONDS FALSE
+ CODE local:-1
+ }
+
+Forward {OPERATION:OperationSet} OPERATION ::=
+{
+ OperationSet |
+ OperationSet.&Linked.&Linked |
+ OperationSet.&Linked.&Linked.&Linked.&Linked
+ }
+
+Reverse {OPERATION:OperationSet} OPERATION ::=
+{Forward{{OperationSet.&Linked}}}
+
+ConsumerPerforms {OPERATION-PACKAGE:package} OPERATION ::=
+{
+ Forward{{package.&Consumer}} |
+ Forward{{package.&Both}} |
+ Reverse{{package.&Supplier}} |
+ Reverse{{package.&Both}}
+ }
+
+SupplierPerforms {OPERATION-PACKAGE:package} OPERATION ::=
+{
+ Forward{{package.&Supplier}} |
+ Forward{{package.&Both}} |
+ Reverse{{package.&Consumer}} |
+ Reverse{{package.&Both}}
+ }
+
+AllOperations {OPERATION-PACKAGE:package} OPERATION ::=
+{
+ ConsumerPerforms {package} |
+ SupplierPerforms {package}
+ }
+
+recode {OPERATION:operation, Code:code} OPERATION ::=
+{
+ ARGUMENT operation.&ArgumentType
+ OPTIONAL operation.&argumentTypeOptional
+ RESULT operation.&ResultType
+ OPTIONAL operation.&resultTypeOptional
+ RETURN RESULT operation.&returnResult
+ ERRORS {operation.&Errors}
+ LINKED {operation.&Linked}
+ SYNCHRONOUS operation.&synchronous
+ ALWAYS RESPONDS operation.&alwaysReturns
+ INVOKE PRIORITY {operation.&InvokePriority}
+ RESULT-PRIORITY {operation.&ResultPriority}
+ CODE code
+ }
+
+switch {OPERATION-PACKAGE:package, OBJECT IDENTIFIER:id} OPERATION-PACKAGE ::=
+{
+ OPERATIONS {package.&Both}
+ CONSUMER INVOKES {package.&Consumer}
+ SUPPLIER INVOKES {package.&Supplier}
+ ID id
+ }
+
+combine {OPERATION-PACKAGE:ConsumerConsumes,OPERATION-PACKAGE:ConsumerSupplies,
+ OPERATION-PACKAGE:base
+ } OPERATION-PACKAGE ::=
+{
+ OPERATIONS {ConsumerConsumes.&Both | ConsumerSupplies.&Both}
+ CONSUMER INVOKES {ConsumerConsumes.&Consumer | ConsumerSupplies.&Supplier}
+ SUPPLIER INVOKES {ConsumerConsumes.&Supplier | ConsumerSupplies.&Consumer}
+ ID base.&id
+ }
+
+ROS-SingleAS {InvokeId:InvokeIdSet, OPERATION-PACKAGE:package} ::= ROS
+{{InvokeIdSet}, {AllOperations{package}}, {AllOperations{package}}}
+
+ROS-ConsumerAS {InvokeId:InvokeIdSet, OPERATION-PACKAGE:package} ::= ROS
+{{InvokeIdSet}, {ConsumerPerforms{package}}, {SupplierPerforms{package}}}
+
+ROS-SupplierAS {InvokeId:InvokeIdSet, OPERATION-PACKAGE:package} ::= ROS
+{{InvokeIdSet}, {SupplierPerforms{package}}, {ConsumerPerforms{package}}}
+
+probe OPERATION ::=
+ {
+ ARGUMENT SEQUENCE
+ {
+ invokeId [0] InvokeId
+ }
+ RESULT ENUMERATED{running(0), finished(1), unknown(2), ...}
+ IDEMPOTENT TRUE
+ CODE local:-2
+ }
+
+acknowledge OPERATION ::=
+ {
+ ARGUMENT InvokeId
+ RESULT ENUMERATED{acknowledged(0), unknown(1), ...}
+ IDEMPOTENT TRUE
+ CODE local:-3
+ }
+
+ProbeAndAcknowledge OPERATION ::= {probe | acknowledge}
+
+cancel OPERATION ::=
+ {
+ ARGUMENT InvokeId
+ ERRORS {cancelFailed}
+ IDEMPOTENT TRUE
+ CODE local:-4
+ }
+
+cancelFailed ERROR ::=
+ {
+ PARAMETER SET
+ {
+ problem [0] CancelProblem,
+ operation [1] InvokeId
+ }
+ CODE local:-2
+ }
+
+CancelProblem ::= ENUMERATED
+{unknownOperation(0), tooLate(1), operationNotCancellable(2), ...}
+
+cancelled ERROR ::= {CODE local:-3}
+
+END -- end of useful definitions.
diff --git a/lib/asn1/test/asn1_SUITE_data/Real.py b/lib/asn1/test/asn1_SUITE_data/Real.py
new file mode 100644
index 0000000000..6b7a748b4e
--- /dev/null
+++ b/lib/asn1/test/asn1_SUITE_data/Real.py
@@ -0,0 +1,31 @@
+Real DEFINITIONS ::=
+BEGIN
+
+-- F.2.4.1
+-- Use a real type to model an approximate number.
+-- EXAMPLE
+
+AngleInRadians ::= REAL
+
+pi REAL ::=
+ {mantissa 3141592653589793238462643383279, base 10, exponent -30}
+
+-- F.2.4.2
+-- Application designers may wish to ensure full interworking with real
+-- values despite
+-- differences in floating point hardware, and in implementation
+-- decisions to use
+-- (for example) single or double length floating point for an application.
+-- This can be achieved by the following:
+ App-X-Real ::= REAL (WITH COMPONENTS {
+ mantissa (-16777215..16777215),
+ base (2),
+ exponent (-125..128) } )
+
+-- Senders shall not transmit values outside these ranges
+-- and conforming receivers shall be capable of receiving
+-- and processing all values in these ranges.
+
+ girth App-X-Real ::= {mantissa 16, base 2, exponent 1}
+
+END
diff --git a/lib/asn1/test/asn1_SUITE_data/Remote-Operations-Generic-ROS-PDUs.asn1 b/lib/asn1/test/asn1_SUITE_data/Remote-Operations-Generic-ROS-PDUs.asn1
new file mode 100644
index 0000000000..7dcf4fda0e
--- /dev/null
+++ b/lib/asn1/test/asn1_SUITE_data/Remote-Operations-Generic-ROS-PDUs.asn1
@@ -0,0 +1,203 @@
+Remote-Operations-Generic-ROS-PDUs {joint-iso-itu-t remote-operations(4) generic-ROS-PDUs(6) version1(0)}
+DEFINITIONS IMPLICIT TAGS ::=
+BEGIN
+
+-- exports everything
+
+IMPORTS OPERATION, ERROR
+FROM Remote-Operations-Information-Objects {joint-iso-itu-t remote-operations(4) informationObjects(5) version1(0)};
+
+
+ROS {InvokeId:InvokeIdSet,OPERATION:Invokable,OPERATION:Returnable} ::= CHOICE
+ {
+ invoke [1] Invoke {{InvokeIdSet}, {Invokable}},
+ returnResult [2] ReturnResult {{Returnable}},
+ returnError [3] ReturnError {{Errors{{Returnable}}}},
+ reject [4] Reject
+ }
+(CONSTRAINED BY {-- must conform to the above definition --}
+ ! RejectProblem : general-unrecognizedPDU)
+
+Invoke {InvokeId:InvokeIdSet, OPERATION:Operations} ::= SEQUENCE
+{
+ invokeId InvokeId (InvokeIdSet)
+ (CONSTRAINED BY {-- must be unambiguous --}
+ ! RejectProblem : invoke-duplicateInvocation),
+ linkedId CHOICE {
+ present [0] IMPLICIT present < InvokeId,
+ absent [1] IMPLICIT NULL
+ }
+ (CONSTRAINED BY {-- must identify an outstanding operation --}
+ ! RejectProblem : invoke-unrecognizedLinkedId)
+ (CONSTRAINED BY {-- which has one or more linked operations--}
+ ! RejectProblem : invoke-linkedResponseUnexpected)
+ OPTIONAL,
+ opcode OPERATION.&operationCode
+ ({Operations}
+ ! RejectProblem : invoke-unrecognizedOperation),
+ argument OPERATION.&ArgumentType
+ ({Operations} {@opcode}
+ ! RejectProblem : invoke-mistypedArgument)
+ OPTIONAL
+ }
+(CONSTRAINED BY {-- must conform to the above definition --}
+ ! RejectProblem : general-mistypedPDU)
+(
+WITH COMPONENTS
+{...,
+ linkedId ABSENT
+ }
+| WITH COMPONENTS
+{...,
+ linkedId PRESENT,
+ opcode
+ (CONSTRAINED BY {-- must be in the &Linked field of the associated operation --
+ }
+ ! RejectProblem : invoke-unexpectedLinkedOperation)
+ }
+)
+
+ReturnResult {OPERATION:Operations}::= SEQUENCE
+{
+ invokeId InvokeId
+ (CONSTRAINED BY {-- must be that for an outstanding operation --}
+ ! RejectProblem:returnResult-unrecognizedInvocation)
+ (CONSTRAINED BY {-- which returns a result --}
+ ! RejectProblem:returnResult-resultResponseUnexpected),
+ result SEQUENCE
+ {
+ opcode OPERATION.&operationCode
+ ({Operations})(CONSTRAINED BY {-- identified by invokeId --}
+ ! RejectProblem:returnResult-unrecognizedInvocation),
+ result OPERATION.&ResultType ({Operations} {@.opcode}
+ ! RejectProblem:returnResult-mistypedResult)
+ }
+ OPTIONAL
+ }
+(CONSTRAINED BY {-- must conform to the above definition --
+ }
+! RejectProblem:general-mistypedPDU)
+
+ReturnError {ERROR:Errors} ::= SEQUENCE
+{
+ invokeId InvokeId
+ (CONSTRAINED BY {-- must be that for an outstanding operation --
+ }
+ ! RejectProblem : returnError-unrecognizedInvocation)
+ (CONSTRAINED BY {-- which returns an error --
+ }
+ ! RejectProblem : returnError-errorResponseUnexpected),
+ errcode ERROR.&errorCode
+ ({Errors}
+ ! RejectProblem : returnError-unrecognizedError)
+ (CONSTRAINED BY {-- must be in the &Errors field of the associated operation --
+ }
+ ! RejectProblem : returnError-unexpectedError),
+ parameter ERROR.&ParameterType
+ ({Errors}{@errcode}
+ ! RejectProblem : returnError-mistypedParameter) OPTIONAL
+ }
+(CONSTRAINED BY {-- must conform to the above definition --
+ }
+! RejectProblem : general-mistypedPDU)
+
+Reject ::= SEQUENCE
+{
+ invokeId InvokeId,
+ problem CHOICE
+ {
+ general [0] GeneralProblem,
+ invoke [1] InvokeProblem,
+ returnResult [2] ReturnResultProblem,
+ returnError [3] ReturnErrorProblem
+ }
+ }
+(CONSTRAINED BY {-- must conform to the above definition --
+ }
+! RejectProblem : general-mistypedPDU)
+
+GeneralProblem ::= INTEGER
+{
+ unrecognizedPDU (0),
+ mistypedPDU (1),
+ badlyStructuredPDU (2)
+ }
+
+InvokeProblem ::= INTEGER
+{
+ duplicateInvocation (0),
+ unrecognizedOperation (1),
+ mistypedArgument (2),
+ resourceLimitation (3),
+ releaseInProgress (4),
+ unrecognizedLinkedId (5),
+ linkedResponseUnexpected (6),
+ unexpectedLinkedOperation (7)
+ }
+
+ReturnResultProblem ::= INTEGER
+{
+ unrecognizedInvocation (0),
+ resultResponseUnexpected (1),
+ mistypedResult (2)
+ }
+
+ReturnErrorProblem ::= INTEGER
+{
+ unrecognizedInvocation (0),
+ errorResponseUnexpected (1),
+ unrecognizedError (2),
+ unexpectedError (3),
+ mistypedParameter (4)
+ }
+
+RejectProblem ::= INTEGER
+{
+ general-unrecognizedPDU (0),
+ general-mistypedPDU (1),
+ general-badlyStructuredPDU (2),
+ invoke-duplicateInvocation (10),
+ invoke-unrecognizedOperation (11),
+ invoke-mistypedArgument (12),
+ invoke-resourceLimitation (13),
+ invoke-releaseInProgress (14),
+ invoke-unrecognizedLinkedId (15),
+ invoke-linkedResponseUnexpected (16),
+ invoke-unexpectedLinkedOperation (17),
+ returnResult-unrecognizedInvocation (20),
+ returnResult-resultResponseUnexpected (21),
+ returnResult-mistypedResult (22),
+ returnError-unrecognizedInvocation (30),
+ returnError-errorResponseUnexpected (31),
+ returnError-unrecognizedError (32),
+ returnError-unexpectedError (33),
+ returnError-mistypedParameter (34)
+ }
+
+InvokeId ::= CHOICE
+{
+ present INTEGER,
+ absent NULL
+ }
+
+noInvokeId InvokeId ::= absent:NULL
+
+NoInvokeId InvokeId ::= {noInvokeId}
+
+Errors {OPERATION:Operations} ERROR ::= {Operations.&Errors}
+
+Bind {OPERATION:operation} ::= CHOICE
+{
+ bind-invoke [16] OPERATION.&ArgumentType({operation}),
+ bind-result [17] OPERATION.&ResultType ({operation}),
+ bind-error [18] OPERATION.&Errors.&ParameterType ({operation})
+ }
+
+Unbind {OPERATION:operation} ::= CHOICE
+{
+ unbind-invoke [19] OPERATION.&ArgumentType({operation}),
+ unbind-result [20] OPERATION.&ResultType ({operation}),
+ unbind-error [21] OPERATION.&Errors.&ParameterType ({operation})
+ }
+
+END -- end of generic ROS PDU definitions
diff --git a/lib/asn1/test/asn1_SUITE_data/Remote-Operations-Information-Objects.asn1 b/lib/asn1/test/asn1_SUITE_data/Remote-Operations-Information-Objects.asn1
new file mode 100644
index 0000000000..b467c0a754
--- /dev/null
+++ b/lib/asn1/test/asn1_SUITE_data/Remote-Operations-Information-Objects.asn1
@@ -0,0 +1,130 @@
+Remote-Operations-Information-Objects {joint-iso-itu-t remote-operations(4) informationObjects(5) version2(1)}
+DEFINITIONS IMPLICIT TAGS ::=
+BEGIN
+
+-- exports everything
+
+IMPORTS emptyBind, emptyUnbind
+FROM Remote-Operations-Useful-Definitions
+{joint-iso-itu-t remote-operations(4) useful-definitions(7) version1(0)};
+
+OPERATION ::= CLASS
+{
+ &ArgumentType OPTIONAL,
+ &argumentTypeOptional BOOLEAN OPTIONAL,
+ &returnResult BOOLEAN DEFAULT TRUE,
+ &ResultType OPTIONAL,
+ &resultTypeOptional BOOLEAN OPTIONAL,
+ &Errors ERROR OPTIONAL,
+ &Linked OPERATION OPTIONAL,
+ &synchronous BOOLEAN DEFAULT FALSE,
+ &idempotent BOOLEAN DEFAULT FALSE,
+ &alwaysReturns BOOLEAN DEFAULT TRUE,
+ &InvokePriority Priority OPTIONAL,
+ &ResultPriority Priority OPTIONAL,
+ &operationCode Code UNIQUE OPTIONAL
+ }
+WITH SYNTAX
+ {
+ [ARGUMENT &ArgumentType [OPTIONAL &argumentTypeOptional]]
+ [RESULT &ResultType [OPTIONAL &resultTypeOptional]]
+ [RETURN RESULT &returnResult]
+ [ERRORS &Errors]
+ [LINKED &Linked]
+ [SYNCHRONOUS &synchronous]
+ [IDEMPOTENT &idempotent]
+ [ALWAYS RESPONDS &alwaysReturns]
+ [INVOKE PRIORITY &InvokePriority]
+ [RESULT-PRIORITY &ResultPriority]
+ [CODE &operationCode]
+ }
+
+ERROR ::= CLASS
+{
+ &ParameterType OPTIONAL,
+ &parameterTypeOptional BOOLEAN OPTIONAL,
+ &ErrorPriority Priority OPTIONAL,
+ &errorCode Code UNIQUE OPTIONAL
+ }
+WITH SYNTAX
+{
+ [PARAMETER &ParameterType [OPTIONAL &parameterTypeOptional]]
+ [PRIORITY &ErrorPriority]
+ [CODE &errorCode]
+ }
+
+OPERATION-PACKAGE ::= CLASS
+{
+ &Both OPERATION OPTIONAL,
+ &Consumer OPERATION OPTIONAL,
+ &Supplier OPERATION OPTIONAL,
+ &id OBJECT IDENTIFIER UNIQUE OPTIONAL
+ }
+WITH SYNTAX
+{
+ [OPERATIONS &Both]
+ [CONSUMER INVOKES &Supplier]
+ [SUPPLIER INVOKES &Consumer]
+ [ID &id]
+ }
+
+CONNECTION-PACKAGE ::= CLASS
+{
+ &bind OPERATION DEFAULT emptyBind,
+ &unbind OPERATION DEFAULT emptyUnbind,
+ &responderCanUnbind BOOLEAN DEFAULT FALSE,
+ &unbindCanFail BOOLEAN DEFAULT FALSE,
+ &id OBJECT IDENTIFIER UNIQUE OPTIONAL
+ }
+WITH SYNTAX
+{
+ [BIND &bind]
+ [UNBIND &unbind]
+ [RESPONDER UNBIND &responderCanUnbind]
+ [FAILURE TO UNBIND &unbindCanFail]
+ [ID &id]
+ }
+
+CONTRACT ::= CLASS
+{
+ &connection CONNECTION-PACKAGE OPTIONAL,
+ &OperationsOf OPERATION-PACKAGE OPTIONAL,
+ &InitiatorConsumerOf OPERATION-PACKAGE OPTIONAL,
+ &InitiatorSupplierOf OPERATION-PACKAGE OPTIONAL,
+ &id OBJECT IDENTIFIER UNIQUE OPTIONAL
+ }
+WITH SYNTAX
+{
+ [CONNECTION &connection]
+ [OPERATIONS OF &OperationsOf]
+ [INITIATOR CONSUMER OF &InitiatorConsumerOf]
+ [RESPONDER CONSUMER OF &InitiatorSupplierOf]
+ [ID &id]
+}
+
+ROS-OBJECT-CLASS ::= CLASS
+{
+ &Is ROS-OBJECT-CLASS OPTIONAL,
+ &Initiates CONTRACT OPTIONAL,
+ &Responds CONTRACT OPTIONAL,
+ &InitiatesAndResponds CONTRACT OPTIONAL,
+ &id OBJECT IDENTIFIER UNIQUE
+ }
+WITH SYNTAX
+{
+ [IS &Is]
+ [BOTH &InitiatesAndResponds]
+ [INITIATES &Initiates]
+ [RESPONDS &Responds]
+ ID &id
+ }
+
+Code ::= CHOICE
+{
+ local INTEGER,
+ global OBJECT IDENTIFIER
+ }
+
+Priority ::= INTEGER (0..MAX)
+
+END -- end of Information Object specifications
diff --git a/lib/asn1/test/asn1_SUITE_data/Remote-Operations-Merged.set.asn1 b/lib/asn1/test/asn1_SUITE_data/Remote-Operations-Merged.set.asn1
new file mode 100644
index 0000000000..c321464a2e
--- /dev/null
+++ b/lib/asn1/test/asn1_SUITE_data/Remote-Operations-Merged.set.asn1
@@ -0,0 +1,3 @@
+Remote-Operations-Generic-ROS-PDUs.asn1
+Remote-Operations-Information-Objects.asn1
+Remote-Operations-Useful-Definitions.asn1
diff --git a/lib/asn1/test/asn1_SUITE_data/Remote-Operations-Useful-Definitions.asn1 b/lib/asn1/test/asn1_SUITE_data/Remote-Operations-Useful-Definitions.asn1
new file mode 100644
index 0000000000..989c23dd5f
--- /dev/null
+++ b/lib/asn1/test/asn1_SUITE_data/Remote-Operations-Useful-Definitions.asn1
@@ -0,0 +1,149 @@
+Remote-Operations-Useful-Definitions {joint-iso-itu-t remote-operations(4) useful-definitions(7) version2(1)}
+DEFINITIONS IMPLICIT TAGS ::=
+BEGIN
+
+-- exports everything
+
+IMPORTS
+
+ OPERATION, ERROR, OPERATION-PACKAGE, Code
+ FROM Remote-Operations-Information-Objects
+ {joint-iso-itu-t remote-operations(4) informationObjects(5) version1(0)}
+ InvokeId, ROS{}
+ FROM Remote-Operations-Generic-ROS-PDUs
+ {joint-iso-itu-t remote-operations(4) generic-ROS-PDUs(6) version1(0)};
+
+
+emptyBind OPERATION ::= {ERRORS {refuse} SYNCHRONOUS TRUE}
+
+emptyUnbind OPERATION ::= { SYNCHRONOUS TRUE }
+
+refuse ERROR ::= {CODE local:-1}
+
+no-op OPERATION ::=
+ {
+ IDEMPOTENT TRUE
+ ALWAYS RESPONDS FALSE
+ CODE local:-1
+ }
+
+Forward {OPERATION:OperationSet} OPERATION ::=
+{
+ OperationSet |
+ OperationSet.&Linked.&Linked |
+ OperationSet.&Linked.&Linked.&Linked.&Linked
+ }
+
+Reverse {OPERATION:OperationSet} OPERATION ::=
+{Forward{{OperationSet.&Linked}}}
+
+ConsumerPerforms {OPERATION-PACKAGE:package} OPERATION ::=
+{
+ Forward{{package.&Consumer}} |
+ Forward{{package.&Both}} |
+ Reverse{{package.&Supplier}} |
+ Reverse{{package.&Both}}
+ }
+
+SupplierPerforms {OPERATION-PACKAGE:package} OPERATION ::=
+{
+ Forward{{package.&Supplier}} |
+ Forward{{package.&Both}} |
+ Reverse{{package.&Consumer}} |
+ Reverse{{package.&Both}}
+ }
+
+AllOperations {OPERATION-PACKAGE:package} OPERATION ::=
+{
+ ConsumerPerforms {package} |
+ SupplierPerforms {package}
+ }
+
+recode {OPERATION:operation, Code:code} OPERATION ::=
+{
+ ARGUMENT operation.&ArgumentType
+ OPTIONAL operation.&argumentTypeOptional
+ RESULT operation.&ResultType
+ OPTIONAL operation.&resultTypeOptional
+ RETURN RESULT operation.&returnResult
+ ERRORS {operation.&Errors}
+ LINKED {operation.&Linked}
+ SYNCHRONOUS operation.&synchronous
+ ALWAYS RESPONDS operation.&alwaysReturns
+ INVOKE PRIORITY {operation.&InvokePriority}
+ RESULT-PRIORITY {operation.&ResultPriority}
+ CODE code
+ }
+
+switch {OPERATION-PACKAGE:package, OBJECT IDENTIFIER:id} OPERATION-PACKAGE ::=
+{
+ OPERATIONS {package.&Both}
+ CONSUMER INVOKES {package.&Consumer}
+ SUPPLIER INVOKES {package.&Supplier}
+ ID id
+ }
+
+combine {OPERATION-PACKAGE:ConsumerConsumes,OPERATION-PACKAGE:ConsumerSupplies,
+ OPERATION-PACKAGE:base
+ } OPERATION-PACKAGE ::=
+{
+ OPERATIONS {ConsumerConsumes.&Both | ConsumerSupplies.&Both}
+ CONSUMER INVOKES {ConsumerConsumes.&Consumer | ConsumerSupplies.&Supplier}
+ SUPPLIER INVOKES {ConsumerConsumes.&Supplier | ConsumerSupplies.&Consumer}
+ ID base.&id
+ }
+
+ROS-SingleAS {InvokeId:InvokeIdSet, OPERATION-PACKAGE:package} ::= ROS
+{{InvokeIdSet}, {AllOperations{package}}, {AllOperations{package}}}
+
+ROS-ConsumerAS {InvokeId:InvokeIdSet, OPERATION-PACKAGE:package} ::= ROS
+{{InvokeIdSet}, {ConsumerPerforms{package}}, {SupplierPerforms{package}}}
+
+ROS-SupplierAS {InvokeId:InvokeIdSet, OPERATION-PACKAGE:package} ::= ROS
+{{InvokeIdSet}, {SupplierPerforms{package}}, {ConsumerPerforms{package}}}
+
+probe OPERATION ::=
+ {
+ ARGUMENT SEQUENCE
+ {
+ invokeId [0] InvokeId
+ }
+ RESULT ENUMERATED{running(0), finished(1), unknown(2), ...}
+ IDEMPOTENT TRUE
+ CODE local:-2
+ }
+
+acknowledge OPERATION ::=
+ {
+ ARGUMENT InvokeId
+ RESULT ENUMERATED{acknowledged(0), unknown(1), ...}
+ IDEMPOTENT TRUE
+ CODE local:-3
+ }
+
+ProbeAndAcknowledge OPERATION ::= {probe | acknowledge}
+
+cancel OPERATION ::=
+ {
+ ARGUMENT InvokeId
+ ERRORS {cancelFailed}
+ IDEMPOTENT TRUE
+ CODE local:-4
+ }
+
+cancelFailed ERROR ::=
+ {
+ PARAMETER SET
+ {
+ problem [0] CancelProblem,
+ operation [1] InvokeId
+ }
+ CODE local:-2
+ }
+
+CancelProblem ::= ENUMERATED
+{unknownOperation(0), tooLate(1), operationNotCancellable(2), ...}
+
+cancelled ERROR ::= {CODE local:-3}
+
+END -- end of useful definitions.
diff --git a/lib/asn1/test/asn1_SUITE_data/S1AP-CommonDataTypes.asn b/lib/asn1/test/asn1_SUITE_data/S1AP-CommonDataTypes.asn
new file mode 100644
index 0000000000..3ddbf35a2f
--- /dev/null
+++ b/lib/asn1/test/asn1_SUITE_data/S1AP-CommonDataTypes.asn
@@ -0,0 +1,35 @@
+-- $Id$
+-- 3GPP TS 36.413 V8.6.1 (2009-06)
+-- 9.3.5 Common Definitions
+-- **************************************************************
+--
+-- Common definitions
+--
+-- **************************************************************
+
+S1AP-CommonDataTypes {
+itu-t (0) identified-organization (4) etsi (0) mobileDomain (0)
+eps-Access (20) modules (3) s1ap (1) version1 (1) s1ap-CommonDataTypes (3) }
+
+DEFINITIONS AUTOMATIC TAGS ::=
+
+BEGIN
+
+Criticality ::= ENUMERATED { reject, ignore, notify }
+
+Presence ::= ENUMERATED { optional, conditional, mandatory }
+
+PrivateIE-ID ::= CHOICE {
+ local INTEGER (0..65535),
+ global OBJECT IDENTIFIER
+}
+
+ProcedureCode ::= INTEGER (0..255)
+
+ProtocolExtensionID ::= INTEGER (0..65535)
+
+ProtocolIE-ID ::= INTEGER (0..65535)
+
+TriggeringMessage ::= ENUMERATED { initiating-message, successful-outcome, unsuccessfull-outcome }
+
+END
diff --git a/lib/asn1/test/asn1_SUITE_data/S1AP-Constants.asn b/lib/asn1/test/asn1_SUITE_data/S1AP-Constants.asn
new file mode 100644
index 0000000000..ff4e8779cd
--- /dev/null
+++ b/lib/asn1/test/asn1_SUITE_data/S1AP-Constants.asn
@@ -0,0 +1,251 @@
+-- $Id$
+-- 3GPP TS 36.413 V8.6.1 (2009-06)
+-- 9.3.6 Constant Definitions
+-- **************************************************************
+--
+-- Constant definitions
+--
+-- **************************************************************
+
+S1AP-Constants {
+itu-t (0) identified-organization (4) etsi (0) mobileDomain (0)
+eps-Access (20) modules (3) s1ap (1) version1 (1) s1ap-Constants (4) }
+
+DEFINITIONS AUTOMATIC TAGS ::=
+
+BEGIN
+
+-- **************************************************************
+--
+-- IE parameter types from other modules.
+--
+-- **************************************************************
+
+IMPORTS
+ ProcedureCode,
+ ProtocolIE-ID
+
+FROM S1AP-CommonDataTypes;
+
+
+-- **************************************************************
+--
+-- Elementary Procedures
+--
+-- **************************************************************
+
+id-HandoverPreparation ProcedureCode ::= 0
+id-HandoverResourceAllocation ProcedureCode ::= 1
+id-HandoverNotification ProcedureCode ::= 2
+id-PathSwitchRequest ProcedureCode ::= 3
+id-HandoverCancel ProcedureCode ::= 4
+id-E-RABSetup ProcedureCode ::= 5
+id-E-RABModify ProcedureCode ::= 6
+id-E-RABRelease ProcedureCode ::= 7
+id-E-RABReleaseIndication ProcedureCode ::= 8
+id-InitialContextSetup ProcedureCode ::= 9
+id-Paging ProcedureCode ::= 10
+id-downlinkNASTransport ProcedureCode ::= 11
+id-initialUEMessage ProcedureCode ::= 12
+id-uplinkNASTransport ProcedureCode ::= 13
+id-Reset ProcedureCode::= 14
+id-ErrorIndication ProcedureCode ::= 15
+id-NASNonDeliveryIndication ProcedureCode ::= 16
+id-S1Setup ProcedureCode ::= 17
+id-UEContextReleaseRequest ProcedureCode ::= 18
+id-DownlinkS1cdma2000tunneling ProcedureCode ::= 19
+id-UplinkS1cdma2000tunneling ProcedureCode ::= 20
+id-UEContextModification ProcedureCode ::= 21
+id-UECapabilityInfoIndication ProcedureCode ::= 22
+id-UEContextRelease ProcedureCode ::= 23
+id-eNBStatusTransfer ProcedureCode ::= 24
+id-MMEStatusTransfer ProcedureCode ::= 25
+id-DeactivateTrace ProcedureCode ::= 26
+id-TraceStart ProcedureCode ::= 27
+id-TraceFailureIndication ProcedureCode ::= 28
+id-ENBConfigurationUpdate ProcedureCode ::= 29
+id-MMEConfigurationUpdate ProcedureCode ::= 30
+id-LocationReportingControl ProcedureCode ::= 31
+id-LocationReportingFailureIndication ProcedureCode ::= 32
+id-LocationReport ProcedureCode ::= 33
+id-OverloadStart ProcedureCode ::= 34
+id-OverloadStop ProcedureCode ::= 35
+id-WriteReplaceWarning ProcedureCode ::= 36
+id-eNBDirectInformationTransfer ProcedureCode ::= 37
+id-MMEDirectInformationTransfer ProcedureCode ::= 38
+id-PrivateMessage ProcedureCode ::= 39
+id-eNBConfigurationTransfer ProcedureCode ::= 40
+id-MMEConfigurationTransfer ProcedureCode ::= 41
+id-CellTrafficTrace ProcedureCode ::= 42
+
+-- **************************************************************
+--
+-- Extension constants
+--
+-- **************************************************************
+
+maxPrivateIEs INTEGER ::= 65535
+maxProtocolExtensions INTEGER ::= 65535
+maxProtocolIEs INTEGER ::= 65535
+-- **************************************************************
+--
+-- Lists
+--
+-- **************************************************************
+
+maxNrOfCSGs INTEGER ::= 256
+maxNrOfE-RABs INTEGER ::= 256
+maxnoofTAIs INTEGER ::= 256
+maxnoofTACs INTEGER ::= 256
+maxNrOfErrors INTEGER ::= 256
+maxnoofBPLMNs INTEGER ::= 6
+maxnoofPLMNsPerMME INTEGER ::= 32
+maxnoofEPLMNs INTEGER ::= 15
+maxnoofEPLMNsPlusOne INTEGER ::= 16
+maxnoofForbLACs INTEGER ::= 4096
+maxnoofForbTACs INTEGER ::= 4096
+maxNrOfIndividualS1ConnectionsToReset INTEGER ::= 256
+maxnoofCells INTEGER ::= 16
+maxnoofTAIforWarning INTEGER ::= 65535
+maxnoofCellID INTEGER ::= 65535
+maxnoofEmergencyAreaID INTEGER ::= 65535
+maxnoofCellinTAI INTEGER ::= 65535
+maxnoofCellinEAI INTEGER ::= 65535
+maxnoofeNBX2TLAs INTEGER ::= 2
+maxnoofRATs INTEGER ::= 8
+maxnoofGroupIDs INTEGER ::= 65535
+maxnoofMMECs INTEGER ::= 256
+
+
+
+
+-- **************************************************************
+--
+-- IEs
+--
+-- **************************************************************
+
+id-MME-UE-S1AP-ID ProtocolIE-ID ::= 0
+id-HandoverType ProtocolIE-ID ::= 1
+id-Cause ProtocolIE-ID ::= 2
+id-SourceID ProtocolIE-ID ::= 3
+id-TargetID ProtocolIE-ID ::= 4
+id-eNB-UE-S1AP-ID ProtocolIE-ID ::= 8
+id-E-RABSubjecttoDataForwardingList ProtocolIE-ID ::= 12
+id-E-RABtoReleaseListHOCmd ProtocolIE-ID ::= 13
+id-E-RABDataForwardingItem ProtocolIE-ID ::= 14
+id-E-RABReleaseItemBearerRelComp ProtocolIE-ID ::= 15
+id-E-RABToBeSetupListBearerSUReq ProtocolIE-ID ::= 16
+id-E-RABToBeSetupItemBearerSUReq ProtocolIE-ID ::= 17
+id-E-RABAdmittedList ProtocolIE-ID ::= 18
+id-E-RABFailedToSetupListHOReqAck ProtocolIE-ID ::= 19
+id-E-RABAdmittedItem ProtocolIE-ID ::= 20
+id-E-RABFailedtoSetupItemHOReqAck ProtocolIE-ID ::= 21
+id-E-RABToBeSwitchedDLList ProtocolIE-ID ::= 22
+id-E-RABToBeSwitchedDLItem ProtocolIE-ID ::= 23
+id-E-RABToBeSetupListCtxtSUReq ProtocolIE-ID ::= 24
+id-TraceActivation ProtocolIE-ID ::= 25
+id-NAS-PDU ProtocolIE-ID ::= 26
+id-E-RABToBeSetupItemHOReq ProtocolIE-ID ::= 27
+id-E-RABSetupListBearerSURes ProtocolIE-ID ::= 28
+id-E-RABFailedToSetupListBearerSURes ProtocolIE-ID ::= 29
+id-E-RABToBeModifiedListBearerModReq ProtocolIE-ID ::= 30
+id-E-RABModifyListBearerModRes ProtocolIE-ID ::= 31
+id-E-RABFailedToModifyList ProtocolIE-ID ::= 32
+id-E-RABToBeReleasedList ProtocolIE-ID ::= 33
+id-E-RABFailedToReleaseList ProtocolIE-ID ::= 34
+id-E-RABItem ProtocolIE-ID ::= 35
+id-E-RABToBeModifiedItemBearerModReq ProtocolIE-ID ::= 36
+id-E-RABModifyItemBearerModRes ProtocolIE-ID ::= 37
+id-E-RABReleaseItem ProtocolIE-ID ::= 38
+id-E-RABSetupItemBearerSURes ProtocolIE-ID ::= 39
+id-SecurityContext ProtocolIE-ID ::= 40
+id-HandoverRestrictionList ProtocolIE-ID ::= 41
+id-UEPagingID ProtocolIE-ID ::= 43
+id-pagingDRX ProtocolIE-ID ::= 44
+id-TAIList ProtocolIE-ID ::= 46
+id-TAIItem ProtocolIE-ID ::= 47
+id-E-RABFailedToSetupListCtxtSURes ProtocolIE-ID ::= 48
+id-E-RABReleaseItemHOCmd ProtocolIE-ID ::= 49
+id-E-RABSetupItemCtxtSURes ProtocolIE-ID ::= 50
+id-E-RABSetupListCtxtSURes ProtocolIE-ID ::= 51
+id-E-RABToBeSetupItemCtxtSUReq ProtocolIE-ID ::= 52
+id-E-RABToBeSetupListHOReq ProtocolIE-ID ::= 53
+id-GERANtoLTEHOInformationRes ProtocolIE-ID ::= 55
+id-UTRANtoLTEHOInformationRes ProtocolIE-ID ::= 57
+id-CriticalityDiagnostics ProtocolIE-ID ::= 58
+id-Global-ENB-ID ProtocolIE-ID ::= 59
+id-eNBname ProtocolIE-ID ::= 60
+id-MMEname ProtocolIE-ID ::= 61
+id-ServedPLMNs ProtocolIE-ID ::= 63
+id-SupportedTAs ProtocolIE-ID ::= 64
+id-TimeToWait ProtocolIE-ID ::= 65
+id-uEaggregateMaximumBitrate ProtocolIE-ID ::= 66
+id-TAI ProtocolIE-ID ::= 67
+id-E-RABReleaseListBearerRelComp ProtocolIE-ID ::= 69
+id-cdma2000PDU ProtocolIE-ID ::= 70
+id-cdma2000RATType ProtocolIE-ID ::= 71
+id-cdma2000SectorID ProtocolIE-ID ::= 72
+id-SecurityKey ProtocolIE-ID ::= 73
+id-UERadioCapability ProtocolIE-ID ::= 74
+id-GUMMEI-ID ProtocolIE-ID ::= 75
+id-E-RABInformationListItem ProtocolIE-ID ::= 78
+id-Direct-Forwarding-Path-Availability ProtocolIE-ID ::= 79
+id-UEIdentityIndexValue ProtocolIE-ID ::= 80
+id-cdma2000HOStatus ProtocolIE-ID ::= 83
+id-cdma2000HORequiredIndication ProtocolIE-ID ::= 84
+id-E-UTRAN-Trace-ID ProtocolIE-ID ::= 86
+id-RelativeMMECapacity ProtocolIE-ID ::= 87
+id-SourceMME-UE-S1AP-ID ProtocolIE-ID ::= 88
+id-Bearers-SubjectToStatusTransfer-Item ProtocolIE-ID ::= 89
+id-eNB-StatusTransfer-TransparentContainer ProtocolIE-ID ::= 90
+id-UE-associatedLogicalS1-ConnectionItem ProtocolIE-ID ::= 91
+id-ResetType ProtocolIE-ID ::= 92
+id-UE-associatedLogicalS1-ConnectionListResAck ProtocolIE-ID ::= 93
+id-E-RABToBeSwitchedULItem ProtocolIE-ID ::= 94
+id-E-RABToBeSwitchedULList ProtocolIE-ID ::= 95
+id-S-TMSI ProtocolIE-ID ::= 96
+id-cdma2000OneXRAND ProtocolIE-ID ::= 97
+id-RequestType ProtocolIE-ID ::= 98
+id-UE-S1AP-IDs ProtocolIE-ID ::= 99
+id-EUTRAN-CGI ProtocolIE-ID ::= 100
+id-OverloadResponse ProtocolIE-ID ::= 101
+id-cdma2000OneXSRVCCInfo ProtocolIE-ID ::= 102
+id-E-RABFailedToBeReleasedList ProtocolIE-ID ::= 103
+id-Source-ToTarget-TransparentContainer ProtocolIE-ID ::= 104
+id-ServedGUMMEIs ProtocolIE-ID ::= 105
+id-SubscriberProfileIDforRFP ProtocolIE-ID ::= 106
+id-UESecurityCapabilities ProtocolIE-ID ::= 107
+id-CSFallbackIndicator ProtocolIE-ID ::= 108
+id-CNDomain ProtocolIE-ID ::= 109
+id-E-RABReleasedList ProtocolIE-ID ::= 110
+id-MessageIdentifier ProtocolIE-ID ::= 111
+id-SerialNumber ProtocolIE-ID ::= 112
+id-WarningAreaList ProtocolIE-ID ::= 113
+id-RepetitionPeriod ProtocolIE-ID ::= 114
+id-NumberofBroadcastRequest ProtocolIE-ID ::= 115
+id-WarningType ProtocolIE-ID ::= 116
+id-WarningSecurityInfo ProtocolIE-ID ::= 117
+id-DataCodingScheme ProtocolIE-ID ::= 118
+id-WarningMessageContents ProtocolIE-ID ::= 119
+id-BroadcastCompletedAreaList ProtocolIE-ID ::= 120
+id-Inter-SystemInformationTransferTypeEDT ProtocolIE-ID ::= 121
+id-Inter-SystemInformationTransferTypeMDT ProtocolIE-ID ::= 122
+id-Target-ToSource-TransparentContainer ProtocolIE-ID ::= 123
+id-SRVCCOperationPossible ProtocolIE-ID ::= 124
+id-SRVCCHOIndication ProtocolIE-ID ::= 125
+id-NAS-DownlinkCount ProtocolIE-ID ::= 126
+id-CSG-Id ProtocolIE-ID ::= 127
+id-CSG-IdList ProtocolIE-ID ::= 128
+id-SONConfigurationTransferECT ProtocolIE-ID ::= 129
+id-SONConfigurationTransferMCT ProtocolIE-ID ::= 130
+id-TraceCollectionEntityIPAddress ProtocolIE-ID ::= 131
+id-MSClassmark2 ProtocolIE-ID ::= 132
+id-MSClassmark3 ProtocolIE-ID ::= 133
+id-RRC-Establishment-Cause ProtocolIE-ID ::= 134
+id-NASSecurityParametersfromE-UTRAN ProtocolIE-ID ::= 135
+id-NASSecurityParameterstoE-UTRAN ProtocolIE-ID ::= 136
+id-DefaultPagingDRX ProtocolIE-ID ::= 137
+id-Source-ToTarget-TransparentContainer-Secondary ProtocolIE-ID ::= 138
+id-Target-ToSource-TransparentContainer-Secondary ProtocolIE-ID ::= 139
+END
diff --git a/lib/asn1/test/asn1_SUITE_data/S1AP-Containers.asn b/lib/asn1/test/asn1_SUITE_data/S1AP-Containers.asn
new file mode 100644
index 0000000000..63883f424c
--- /dev/null
+++ b/lib/asn1/test/asn1_SUITE_data/S1AP-Containers.asn
@@ -0,0 +1,201 @@
+-- $Id$
+-- 3GPP TS 36.413 V8.6.1 (2009-06)
+-- 9.3.7 Container Definitions
+-- **************************************************************
+--
+-- Container definitions
+--
+-- **************************************************************
+
+
+S1AP-Containers {
+itu-t (0) identified-organization (4) etsi (0) mobileDomain (0)
+eps-Access (20) modules (3) s1ap (1) version1 (1) s1ap-Containers (5) }
+
+DEFINITIONS AUTOMATIC TAGS ::=
+
+BEGIN
+
+-- **************************************************************
+--
+-- IE parameter types from other modules.
+--
+-- **************************************************************
+
+IMPORTS
+ Criticality,
+ Presence,
+ PrivateIE-ID,
+ ProtocolExtensionID,
+ ProtocolIE-ID
+FROM S1AP-CommonDataTypes
+
+ maxPrivateIEs,
+ maxProtocolExtensions,
+ maxProtocolIEs
+FROM S1AP-Constants;
+
+-- **************************************************************
+--
+-- Class Definition for Protocol IEs
+--
+-- **************************************************************
+
+S1AP-PROTOCOL-IES ::= CLASS {
+ &id ProtocolIE-ID UNIQUE,
+ &criticality Criticality,
+ &Value,
+ &presence Presence
+}
+WITH SYNTAX {
+ ID &id
+ CRITICALITY &criticality
+ TYPE &Value
+ PRESENCE &presence
+}
+
+-- **************************************************************
+--
+-- Class Definition for Protocol IEs
+--
+-- **************************************************************
+
+S1AP-PROTOCOL-IES-PAIR ::= CLASS {
+ &id ProtocolIE-ID UNIQUE,
+ &firstCriticality Criticality,
+ &FirstValue,
+ &secondCriticality Criticality,
+ &SecondValue,
+ &presence Presence
+}
+WITH SYNTAX {
+ ID &id
+ FIRST CRITICALITY &firstCriticality
+ FIRST TYPE &FirstValue
+ SECOND CRITICALITY &secondCriticality
+ SECOND TYPE &SecondValue
+ PRESENCE &presence
+}
+
+-- **************************************************************
+--
+-- Class Definition for Protocol Extensions
+--
+-- **************************************************************
+
+S1AP-PROTOCOL-EXTENSION ::= CLASS {
+ &id ProtocolExtensionID UNIQUE,
+ &criticality Criticality,
+ &Extension,
+ &presence Presence
+}
+WITH SYNTAX {
+ ID &id
+ CRITICALITY &criticality
+ EXTENSION &Extension
+ PRESENCE &presence
+}
+
+-- **************************************************************
+--
+-- Class Definition for Private IEs
+--
+-- **************************************************************
+
+S1AP-PRIVATE-IES ::= CLASS {
+ &id PrivateIE-ID,
+ &criticality Criticality,
+ &Value,
+ &presence Presence
+}
+WITH SYNTAX {
+ ID &id
+ CRITICALITY &criticality
+ TYPE &Value
+ PRESENCE &presence
+}
+
+-- **************************************************************
+--
+-- Container for Protocol IEs
+--
+-- **************************************************************
+
+ProtocolIE-Container {S1AP-PROTOCOL-IES : IEsSetParam} ::=
+ SEQUENCE (SIZE (0..maxProtocolIEs)) OF
+ ProtocolIE-Field {{IEsSetParam}}
+
+ProtocolIE-SingleContainer {S1AP-PROTOCOL-IES : IEsSetParam} ::=
+ ProtocolIE-Field {{IEsSetParam}}
+
+ProtocolIE-Field {S1AP-PROTOCOL-IES : IEsSetParam} ::= SEQUENCE {
+ id S1AP-PROTOCOL-IES.&id ({IEsSetParam}),
+ criticality S1AP-PROTOCOL-IES.&criticality ({IEsSetParam}{@id}),
+ value S1AP-PROTOCOL-IES.&Value ({IEsSetParam}{@id})
+}
+
+-- **************************************************************
+--
+-- Container for Protocol IE Pairs
+--
+-- **************************************************************
+
+ProtocolIE-ContainerPair {S1AP-PROTOCOL-IES-PAIR : IEsSetParam} ::=
+ SEQUENCE (SIZE (0..maxProtocolIEs)) OF
+ ProtocolIE-FieldPair {{IEsSetParam}}
+
+ProtocolIE-FieldPair {S1AP-PROTOCOL-IES-PAIR : IEsSetParam} ::= SEQUENCE {
+ id S1AP-PROTOCOL-IES-PAIR.&id ({IEsSetParam}),
+ firstCriticality S1AP-PROTOCOL-IES-PAIR.&firstCriticality ({IEsSetParam}{@id}),
+ firstValue S1AP-PROTOCOL-IES-PAIR.&FirstValue ({IEsSetParam}{@id}),
+ secondCriticality S1AP-PROTOCOL-IES-PAIR.&secondCriticality ({IEsSetParam}{@id}),
+ secondValue S1AP-PROTOCOL-IES-PAIR.&SecondValue ({IEsSetParam}{@id})
+}
+
+-- **************************************************************
+--
+-- Container Lists for Protocol IE Containers
+--
+-- **************************************************************
+
+ProtocolIE-ContainerList {INTEGER : lowerBound, INTEGER : upperBound, S1AP-PROTOCOL-IES : IEsSetParam} ::=
+ SEQUENCE (SIZE (lowerBound..upperBound)) OF
+ ProtocolIE-SingleContainer {{IEsSetParam}}
+
+ProtocolIE-ContainerPairList {INTEGER : lowerBound, INTEGER : upperBound, S1AP-PROTOCOL-IES-PAIR : IEsSetParam} ::=
+ SEQUENCE (SIZE (lowerBound..upperBound)) OF
+ ProtocolIE-ContainerPair {{IEsSetParam}}
+
+-- **************************************************************
+--
+-- Container for Protocol Extensions
+--
+-- **************************************************************
+
+ProtocolExtensionContainer {S1AP-PROTOCOL-EXTENSION : ExtensionSetParam} ::=
+ SEQUENCE (SIZE (1..maxProtocolExtensions)) OF
+ ProtocolExtensionField {{ExtensionSetParam}}
+
+ProtocolExtensionField {S1AP-PROTOCOL-EXTENSION : ExtensionSetParam} ::= SEQUENCE {
+ id S1AP-PROTOCOL-EXTENSION.&id ({ExtensionSetParam}),
+ criticality S1AP-PROTOCOL-EXTENSION.&criticality ({ExtensionSetParam}{@id}),
+ extensionValue S1AP-PROTOCOL-EXTENSION.&Extension ({ExtensionSetParam}{@id})
+}
+
+-- **************************************************************
+--
+-- Container for Private IEs
+--
+-- **************************************************************
+
+PrivateIE-Container {S1AP-PRIVATE-IES : IEsSetParam } ::=
+ SEQUENCE (SIZE (1.. maxPrivateIEs)) OF
+ PrivateIE-Field {{IEsSetParam}}
+
+PrivateIE-Field {S1AP-PRIVATE-IES : IEsSetParam} ::= SEQUENCE {
+ id S1AP-PRIVATE-IES.&id ({IEsSetParam}),
+ criticality S1AP-PRIVATE-IES.&criticality ({IEsSetParam}{@id}),
+ value S1AP-PRIVATE-IES.&Value ({IEsSetParam}{@id})
+}
+
+END
diff --git a/lib/asn1/test/asn1_SUITE_data/S1AP-IEs.asn b/lib/asn1/test/asn1_SUITE_data/S1AP-IEs.asn
new file mode 100644
index 0000000000..719bf1359b
--- /dev/null
+++ b/lib/asn1/test/asn1_SUITE_data/S1AP-IEs.asn
@@ -0,0 +1,1178 @@
+-- $Id$
+-- 3GPP TS 36.413 V8.6.1 (2009-06)
+-- 9.3.4 Information Element Definitions
+-- **************************************************************
+--
+-- Information Element Definitions
+--
+-- **************************************************************
+
+S1AP-IEs {
+itu-t (0) identified-organization (4) etsi (0) mobileDomain (0)
+eps-Access (20) modules (3) s1ap (1) version1 (1) s1ap-IEs (2) }
+
+DEFINITIONS AUTOMATIC TAGS ::=
+
+BEGIN
+
+IMPORTS
+ id-E-RABInformationListItem,
+ id-E-RABItem,
+ id-Bearers-SubjectToStatusTransfer-Item,
+ maxNrOfCSGs,
+ maxNrOfE-RABs,
+ maxNrOfErrors,
+ maxnoofBPLMNs,
+ maxnoofPLMNsPerMME,
+ maxnoofTACs,
+ maxnoofEPLMNs,
+ maxnoofEPLMNsPlusOne,
+ maxnoofForbLACs,
+ maxnoofForbTACs,
+ maxnoofTACs,
+ maxnoofCells,
+ maxnoofCellID,
+ maxnoofEmergencyAreaID,
+ maxnoofTAIforWarning,
+ maxnoofCellinTAI,
+ maxnoofCellinEAI,
+ maxnoofeNBX2TLAs,
+ maxnoofRATs,
+ maxnoofGroupIDs,
+ maxnoofMMECs
+
+
+
+FROM S1AP-Constants
+
+ Criticality,
+ ProcedureCode,
+ ProtocolIE-ID,
+ TriggeringMessage
+FROM S1AP-CommonDataTypes
+
+ ProtocolExtensionContainer{},
+ S1AP-PROTOCOL-EXTENSION,
+ ProtocolIE-SingleContainer{},
+ S1AP-PROTOCOL-IES
+
+FROM S1AP-Containers;
+
+-- A
+
+
+AllocationAndRetentionPriority ::= SEQUENCE {
+ priorityLevel PriorityLevel,
+ pre-emptionCapability Pre-emptionCapability,
+ pre-emptionVulnerability Pre-emptionVulnerability,
+ iE-Extensions ProtocolExtensionContainer { {AllocationAndRetentionPriority-ExtIEs} } OPTIONAL,
+ ...
+}
+
+AllocationAndRetentionPriority-ExtIEs S1AP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+
+-- B
+
+Bearers-SubjectToStatusTransferList ::= SEQUENCE (SIZE(1.. maxNrOfE-RABs)) OF ProtocolIE-SingleContainer { { Bearers-SubjectToStatusTransfer-ItemIEs } }
+
+Bearers-SubjectToStatusTransfer-ItemIEs S1AP-PROTOCOL-IES ::= {
+ { ID id-Bearers-SubjectToStatusTransfer-Item CRITICALITY ignore TYPE Bearers-SubjectToStatusTransfer-Item PRESENCE mandatory },
+ ...
+}
+
+Bearers-SubjectToStatusTransfer-Item ::= SEQUENCE {
+ e-RAB-ID E-RAB-ID,
+ uL-COUNTvalue COUNTvalue,
+ dL-COUNTvalue COUNTvalue,
+ receiveStatusofULPDCPSDUs ReceiveStatusofULPDCPSDUs OPTIONAL,
+ iE-Extensions ProtocolExtensionContainer { {Bearers-SubjectToStatusTransfer-ItemExtIEs} } OPTIONAL,
+ ...
+}
+
+Bearers-SubjectToStatusTransfer-ItemExtIEs S1AP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+BitRate ::= INTEGER (0..10000000000)
+
+BPLMNs ::= SEQUENCE (SIZE(1.. maxnoofBPLMNs)) OF PLMNidentity
+
+BroadcastCompletedAreaList ::= CHOICE {
+ cellID-Broadcast CellID-Broadcast,
+ tAI-Broadcast TAI-Broadcast,
+ emergencyAreaID-Broadcast EmergencyAreaID-Broadcast,
+ ...
+}
+
+
+-- C
+
+Cause ::= CHOICE {
+ radioNetwork CauseRadioNetwork,
+ transport CauseTransport,
+ nas CauseNas,
+ protocol CauseProtocol,
+ misc CauseMisc,
+ ...
+}
+
+CauseMisc ::= ENUMERATED {
+ control-processing-overload,
+ not-enough-user-plane-processing-resources,
+ hardware-failure,
+ om-intervention,
+ unspecified,
+ unknown-PLMN,
+...
+}
+
+CauseProtocol ::= ENUMERATED {
+ transfer-syntax-error,
+ abstract-syntax-error-reject,
+ abstract-syntax-error-ignore-and-notify,
+ message-not-compatible-with-receiver-state,
+ semantic-error,
+ abstract-syntax-error-falsely-constructed-message,
+ unspecified,
+ ...
+}
+
+CauseRadioNetwork ::= ENUMERATED {
+ unspecified,
+ tx2relocoverall-expiry,
+ successful-handover,
+ release-due-to-eutran-generated-reason,
+ handover-cancelled,
+ partial-handover,
+ ho-failure-in-target-EPC-eNB-or-target-system,
+ ho-target-not-allowed,
+ tS1relocoverall-expiry,
+ tS1relocprep-expiry,
+ cell-not-available,
+ unknown-targetID,
+ no-radio-resources-available-in-target-cell,
+ unknown-mme-ue-s1ap-id,
+ unknown-enb-ue-s1ap-id,
+ unknown-pair-ue-s1ap-id,
+ handover-desirable-for-radio-reason,
+ time-critical-handover,
+ resource-optimisation-handover,
+ reduce-load-in-serving-cell,
+ user-inactivity,
+ radio-connection-with-ue-lost,
+ load-balancing-tau-required,
+ cs-fallback-triggered,
+ ue-not-available-for-ps-service,
+ radio-resources-not-available,
+ failure-in-radio-interface-procedure,
+ invalid-qos-combination,
+ interrat-redirection,
+ interaction-with-other-procedure,
+ unknown-E-RAB-ID,
+ multiple-E-RAB-ID-instances,
+ encryption-and-or-integrity-protection-algorithms-not-supported,
+ s1-intra-system-handover-triggered,
+ s1-inter-system-handover-triggered,
+ x2-handover-triggered,
+ ...,
+ redirection-towards-1xRTT
+
+}
+
+CauseTransport ::= ENUMERATED {
+ transport-resource-unavailable,
+ unspecified,
+ ...
+}
+
+CauseNas ::= ENUMERATED {
+ normal-release,
+ authentication-failure,
+ detach,
+ unspecified,
+ ...
+}
+
+CellIdentity ::= BIT STRING (SIZE (28))
+
+CellID-Broadcast ::= SEQUENCE (SIZE(1..maxnoofCellID)) OF CellID-Broadcast-Item
+
+CellID-Broadcast-Item ::= SEQUENCE {
+ eCGI EUTRAN-CGI,
+ iE-Extensions ProtocolExtensionContainer { {CellID-Broadcast-Item-ExtIEs} } OPTIONAL,
+ ...
+}
+
+CellID-Broadcast-Item-ExtIEs S1AP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+
+Cdma2000PDU ::= OCTET STRING
+
+Cdma2000RATType ::= ENUMERATED {
+ hRPD,
+ onexRTT,
+ ...
+}
+
+Cdma2000SectorID ::= OCTET STRING
+
+Cdma2000HOStatus ::= ENUMERATED {
+ hOSuccess,
+ hOFailure,
+ ...
+}
+
+Cdma2000HORequiredIndication ::= ENUMERATED {
+ true,
+ ...
+}
+
+Cdma2000OneXSRVCCInfo ::= SEQUENCE {
+ cdma2000OneXMEID Cdma2000OneXMEID,
+ cdma2000OneXMSI Cdma2000OneXMSI,
+ cdma2000OneXPilot Cdma2000OneXPilot,
+ iE-Extensions ProtocolExtensionContainer { {Cdma2000OneXSRVCCInfo-ExtIEs} } OPTIONAL,
+ ...
+}
+
+Cdma2000OneXSRVCCInfo-ExtIEs S1AP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+Cdma2000OneXMEID ::= OCTET STRING
+
+Cdma2000OneXMSI ::= OCTET STRING
+
+Cdma2000OneXPilot ::= OCTET STRING
+
+Cdma2000OneXRAND ::= OCTET STRING
+
+
+Cell-Size ::= ENUMERATED {verysmall, small, medium, large, ...}
+
+CellType ::= SEQUENCE {
+ cell-Size Cell-Size,
+ iE-Extensions ProtocolExtensionContainer { { CellType-ExtIEs}} OPTIONAL,
+ ...
+}
+
+CellType-ExtIEs S1AP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+CGI ::= SEQUENCE {
+ pLMNidentity PLMNidentity,
+ lAC LAC,
+ cI CI,
+ rAC RAC OPTIONAL,
+ iE-Extensions ProtocolExtensionContainer { {CGI-ExtIEs} } OPTIONAL,
+ ...
+ }
+
+CGI-ExtIEs S1AP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+CI ::= OCTET STRING (SIZE (2))
+
+CNDomain ::= ENUMERATED {
+ ps,
+ cs
+}
+
+CSFallbackIndicator ::= ENUMERATED {
+ cs-fallback-required,
+ ...,
+ cs-fallback-high-priority
+}
+
+CSG-Id ::= BIT STRING (SIZE (27))
+
+
+CSG-IdList ::= SEQUENCE (SIZE (1..maxNrOfCSGs)) OF CSG-IdList-Item
+
+CSG-IdList-Item ::= SEQUENCE {
+ cSG-Id CSG-Id,
+ iE-Extensions ProtocolExtensionContainer { {CSG-IdList-Item-ExtIEs} } OPTIONAL,
+ ...
+}
+
+CSG-IdList-Item-ExtIEs S1AP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+COUNTvalue ::= SEQUENCE {
+ pDCP-SN PDCP-SN,
+ hFN HFN,
+ iE-Extensions ProtocolExtensionContainer { {COUNTvalue-ExtIEs} } OPTIONAL,
+ ...
+}
+COUNTvalue-ExtIEs S1AP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+CriticalityDiagnostics ::= SEQUENCE {
+ procedureCode ProcedureCode OPTIONAL,
+ triggeringMessage TriggeringMessage OPTIONAL,
+ procedureCriticality Criticality OPTIONAL,
+ iEsCriticalityDiagnostics CriticalityDiagnostics-IE-List OPTIONAL,
+ iE-Extensions ProtocolExtensionContainer {{CriticalityDiagnostics-ExtIEs}} OPTIONAL,
+ ...
+}
+
+CriticalityDiagnostics-ExtIEs S1AP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+CriticalityDiagnostics-IE-List ::= SEQUENCE (SIZE (1..maxNrOfErrors)) OF CriticalityDiagnostics-IE-Item
+
+CriticalityDiagnostics-IE-Item ::= SEQUENCE {
+ iECriticality Criticality,
+ iE-ID ProtocolIE-ID,
+ typeOfError TypeOfError,
+ iE-Extensions ProtocolExtensionContainer {{CriticalityDiagnostics-IE-Item-ExtIEs}} OPTIONAL,
+ ...
+}
+
+CriticalityDiagnostics-IE-Item-ExtIEs S1AP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+
+-- D
+
+DataCodingScheme ::= BIT STRING (SIZE (8))
+
+DL-Forwarding ::= ENUMERATED {
+ dL-Forwarding-proposed,
+ ...
+}
+
+Direct-Forwarding-Path-Availability ::= ENUMERATED {
+ directPathAvailable,
+ ...
+}
+
+-- E
+
+ECGIList ::= SEQUENCE (SIZE(1..maxnoofCellID)) OF EUTRAN-CGI
+
+EmergencyAreaIDList ::= SEQUENCE (SIZE(1..maxnoofEmergencyAreaID)) OF EmergencyAreaID
+
+EmergencyAreaID ::= OCTET STRING (SIZE (3))
+
+EmergencyAreaID-Broadcast ::= SEQUENCE (SIZE(1..maxnoofEmergencyAreaID)) OF EmergencyAreaID-Broadcast-Item
+
+EmergencyAreaID-Broadcast-Item ::= SEQUENCE {
+ emergencyAreaID EmergencyAreaID,
+ completedCellinEAI CompletedCellinEAI,
+ iE-Extensions ProtocolExtensionContainer { {EmergencyAreaID-Broadcast-Item-ExtIEs} } OPTIONAL,
+ ...
+}
+
+EmergencyAreaID-Broadcast-Item-ExtIEs S1AP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+
+CompletedCellinEAI ::= SEQUENCE (SIZE(1..maxnoofCellinEAI)) OF CompletedCellinEAI-Item
+
+CompletedCellinEAI-Item ::= SEQUENCE {
+ eCGI EUTRAN-CGI,
+ iE-Extensions ProtocolExtensionContainer { {CompletedCellinEAI-Item-ExtIEs} } OPTIONAL,
+ ...
+}
+
+CompletedCellinEAI-Item-ExtIEs S1AP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+ENB-ID ::= CHOICE {
+ macroENB-ID BIT STRING (SIZE(20)),
+ homeENB-ID BIT STRING (SIZE(28)),
+ ...
+}
+
+GERAN-Cell-ID ::= SEQUENCE {
+ lAI LAI,
+ rAC RAC,
+ cI CI,
+ iE-Extensions ProtocolExtensionContainer { { GERAN-Cell-ID-ExtIEs} } OPTIONAL,
+ ...
+}
+
+GERAN-Cell-ID-ExtIEs S1AP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+Global-ENB-ID ::= SEQUENCE {
+ pLMNidentity PLMNidentity,
+ eNB-ID ENB-ID,
+ iE-Extensions ProtocolExtensionContainer { {GlobalENB-ID-ExtIEs} } OPTIONAL,
+ ...
+}
+
+GlobalENB-ID-ExtIEs S1AP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+
+ENB-StatusTransfer-TransparentContainer ::= SEQUENCE {
+ bearers-SubjectToStatusTransferList Bearers-SubjectToStatusTransferList,
+ iE-Extensions ProtocolExtensionContainer { {ENB-StatusTransfer-TransparentContainer-ExtIEs} } OPTIONAL,
+ ...
+}
+
+ENB-StatusTransfer-TransparentContainer-ExtIEs S1AP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+ENB-UE-S1AP-ID ::= INTEGER (0..16777215)
+
+ENBname ::= PrintableString (SIZE (1..150,...))
+
+ENBX2TLAs ::= SEQUENCE (SIZE(1.. maxnoofeNBX2TLAs)) OF TransportLayerAddress
+
+EncryptionAlgorithms ::= BIT STRING (SIZE (16,...))
+
+EPLMNs ::= SEQUENCE (SIZE(1..maxnoofEPLMNs)) OF PLMNidentity
+EventType ::= ENUMERATED {
+ direct,
+ change-of-serve-cell,
+ stop-change-of-serve-cell,
+ ...
+}
+
+E-RAB-ID ::= INTEGER (0..15, ...)
+
+E-RABInformationList ::= SEQUENCE (SIZE (1.. maxNrOfE-RABs)) OF ProtocolIE-SingleContainer { { E-RABInformationListIEs } }
+
+E-RABInformationListIEs S1AP-PROTOCOL-IES ::= {
+ { ID id-E-RABInformationListItem CRITICALITY ignore TYPE E-RABInformationListItem PRESENCE mandatory },
+ ...
+}
+
+E-RABInformationListItem ::= SEQUENCE {
+ e-RAB-ID E-RAB-ID,
+ dL-Forwarding DL-Forwarding OPTIONAL,
+ iE-Extensions ProtocolExtensionContainer { {E-RABInformationListItem-ExtIEs} } OPTIONAL,
+ ...
+}
+
+E-RABInformationListItem-ExtIEs S1AP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+E-RABList ::= SEQUENCE (SIZE(1.. maxNrOfE-RABs)) OF ProtocolIE-SingleContainer { {E-RABItemIEs} }
+
+E-RABItemIEs S1AP-PROTOCOL-IES ::= {
+ { ID id-E-RABItem CRITICALITY ignore TYPE E-RABItem PRESENCE mandatory },
+ ...
+}
+
+E-RABItem ::= SEQUENCE {
+ e-RAB-ID E-RAB-ID,
+ cause Cause,
+ iE-Extensions ProtocolExtensionContainer { {E-RABItem-ExtIEs} } OPTIONAL,
+ ...
+}
+
+E-RABItem-ExtIEs S1AP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+
+
+
+E-RABLevelQoSParameters ::= SEQUENCE {
+ qCI QCI,
+ allocationRetentionPriority AllocationAndRetentionPriority,
+ gbrQosInformation GBR-QosInformation OPTIONAL,
+ iE-Extensions ProtocolExtensionContainer { {E-RABQoSParameters-ExtIEs} } OPTIONAL,
+ ...
+}
+
+E-RABQoSParameters-ExtIEs S1AP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+
+EUTRAN-CGI ::= SEQUENCE {
+ pLMNidentity PLMNidentity,
+ cell-ID CellIdentity,
+ iE-Extensions ProtocolExtensionContainer { {EUTRAN-CGI-ExtIEs} } OPTIONAL,
+ ...
+}
+
+EUTRAN-CGI-ExtIEs S1AP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+ExtendedRNC-ID ::= INTEGER (4096..65535)
+
+-- F
+
+ForbiddenInterRATs ::= ENUMERATED {
+ all,
+ geran,
+ utran,
+ cdma2000,
+ ...
+}
+
+ForbiddenTAs ::= SEQUENCE (SIZE(1.. maxnoofEPLMNsPlusOne)) OF ForbiddenTAs-Item
+
+ForbiddenTAs-Item ::= SEQUENCE {
+ pLMN-Identity PLMNidentity,
+ forbiddenTACs ForbiddenTACs,
+ iE-Extensions ProtocolExtensionContainer { {ForbiddenTAs-Item-ExtIEs} } OPTIONAL,
+ ...
+}
+
+ForbiddenTAs-Item-ExtIEs S1AP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+ForbiddenTACs ::= SEQUENCE (SIZE(1..maxnoofForbTACs)) OF TAC
+
+ForbiddenLAs ::= SEQUENCE (SIZE(1..maxnoofEPLMNsPlusOne)) OF ForbiddenLAs-Item
+
+ForbiddenLAs-Item ::= SEQUENCE {
+ pLMN-Identity PLMNidentity,
+ forbiddenLACs ForbiddenLACs,
+ iE-Extensions ProtocolExtensionContainer { {ForbiddenLAs-Item-ExtIEs} } OPTIONAL,
+ ...
+}
+
+ForbiddenLAs-Item-ExtIEs S1AP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+ForbiddenLACs ::= SEQUENCE (SIZE(1..maxnoofForbLACs)) OF LAC
+
+-- G
+
+GBR-QosInformation ::= SEQUENCE {
+ e-RAB-MaximumBitrateDL BitRate,
+ e-RAB-MaximumBitrateUL BitRate,
+ e-RAB-GuaranteedBitrateDL BitRate,
+ e-RAB-GuaranteedBitrateUL BitRate,
+ iE-Extensions ProtocolExtensionContainer { { GBR-QosInformation-ExtIEs} } OPTIONAL,
+ ...
+}
+
+GBR-QosInformation-ExtIEs S1AP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+
+GTP-TEID ::= OCTET STRING (SIZE (4))
+
+GUMMEI ::= SEQUENCE {
+ pLMN-Identity PLMNidentity,
+ mME-Group-ID MME-Group-ID,
+ mME-Code MME-Code,
+ iE-Extensions ProtocolExtensionContainer { {GUMMEI-ExtIEs} } OPTIONAL,
+ ...
+}
+
+GUMMEI-ExtIEs S1AP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+-- H
+
+HandoverRestrictionList ::= SEQUENCE {
+ servingPLMN PLMNidentity,
+ equivalentPLMNs EPLMNs OPTIONAL,
+ forbiddenTAs ForbiddenTAs OPTIONAL,
+ forbiddenLAs ForbiddenLAs OPTIONAL,
+ forbiddenInterRATs ForbiddenInterRATs OPTIONAL,
+ iE-Extensions ProtocolExtensionContainer { {HandoverRestrictionList-ExtIEs} } OPTIONAL,
+ ...
+}
+
+HandoverRestrictionList-ExtIEs S1AP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+HandoverType ::= ENUMERATED {
+ intralte,
+ ltetoutran,
+ ltetogeran,
+ utrantolte,
+ gerantolte,
+ ...
+}
+
+HFN ::= INTEGER (0..1048575)
+
+-- I
+
+IMSI ::= OCTET STRING (SIZE (3..8))
+
+IntegrityProtectionAlgorithms ::= BIT STRING (SIZE (16,...))
+
+InterfacesToTrace ::= BIT STRING (SIZE (8))
+
+
+
+-- J
+-- K
+-- L
+
+
+LAC ::= OCTET STRING (SIZE (2))
+
+LAI ::= SEQUENCE {
+ pLMNidentity PLMNidentity,
+ lAC LAC,
+ iE-Extensions ProtocolExtensionContainer { {LAI-ExtIEs} } OPTIONAL,
+ ...
+}
+
+LAI-ExtIEs S1AP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+LastVisitedCell-Item ::= CHOICE {
+ e-UTRAN-Cell LastVisitedEUTRANCellInformation,
+ uTRAN-Cell LastVisitedUTRANCellInformation,
+ gERAN-Cell LastVisitedGERANCellInformation,
+ ...
+}
+LastVisitedEUTRANCellInformation ::= SEQUENCE {
+ global-Cell-ID EUTRAN-CGI,
+ cellType CellType,
+ time-UE-StayedInCell Time-UE-StayedInCell,
+ iE-Extensions ProtocolExtensionContainer { { LastVisitedEUTRANCellInformation-ExtIEs} } OPTIONAL,
+ ...
+}
+LastVisitedEUTRANCellInformation-ExtIEs S1AP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+LastVisitedUTRANCellInformation ::= OCTET STRING
+
+LastVisitedGERANCellInformation ::= CHOICE {
+ undefined NULL,
+ ...
+}
+
+L3-Information ::= OCTET STRING
+
+
+-- M
+
+MessageIdentifier ::= BIT STRING (SIZE (16))
+
+MMEname ::= PrintableString (SIZE (1..150,...))
+
+MME-Group-ID ::= OCTET STRING (SIZE (2))
+
+MME-Code ::= OCTET STRING (SIZE (1))
+
+MME-UE-S1AP-ID ::= INTEGER (0..4294967295)
+M-TMSI ::= OCTET STRING (SIZE (4))
+
+MSClassmark2 ::= OCTET STRING
+MSClassmark3 ::= OCTET STRING
+
+-- N
+
+NAS-PDU ::= OCTET STRING
+
+NASSecurityParametersfromE-UTRAN ::= OCTET STRING
+
+NASSecurityParameterstoE-UTRAN ::= OCTET STRING
+
+NumberofBroadcastRequest ::= INTEGER (0..65535)
+
+NumberofBroadcast ::= INTEGER (0..65535)
+
+-- O
+OldBSS-ToNewBSS-Information ::= OCTET STRING
+
+OverloadAction ::= ENUMERATED {
+reject-non-emergency-mo-dt,
+reject-all-rrc-cr-signalling,
+permit-emergency-sessions-only,
+ ...
+}
+
+OverloadResponse ::= CHOICE {
+ overloadAction OverloadAction,
+ ...
+}
+
+
+-- P
+
+PagingDRX ::= ENUMERATED {
+ v32,
+ v64,
+ v128,
+ v256,
+ ...
+ }
+
+PDCP-SN ::= INTEGER (0..4095)
+
+PLMNidentity ::= TBCD-STRING
+
+Pre-emptionCapability ::= ENUMERATED {
+ shall-not-trigger-pre-emption,
+ may-trigger-pre-emption
+}
+
+Pre-emptionVulnerability ::= ENUMERATED {
+ not-pre-emptable,
+ pre-emptable
+}
+
+PriorityLevel ::= INTEGER { spare (0), highest (1), lowest (14), no-priority (15) } (0..15)
+
+
+-- Q
+
+QCI ::= INTEGER (0..255)
+
+-- R
+
+ReceiveStatusofULPDCPSDUs ::= BIT STRING (SIZE(4096))
+
+RelativeMMECapacity ::= INTEGER (0..255)
+
+RAC ::= OCTET STRING (SIZE (1))
+
+
+RequestType ::= SEQUENCE {
+ eventType EventType,
+ reportArea ReportArea,
+ iE-Extensions ProtocolExtensionContainer { { RequestType-ExtIEs} } OPTIONAL,
+ ...
+}
+
+
+RequestType-ExtIEs S1AP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+RIMTransfer ::= SEQUENCE {
+ rIMInformation RIMInformation,
+ rIMRoutingAddress RIMRoutingAddress OPTIONAL,
+ iE-Extensions ProtocolExtensionContainer { { RIMTransfer-ExtIEs} } OPTIONAL,
+...
+}
+
+RIMTransfer-ExtIEs S1AP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+RIMInformation ::= OCTET STRING
+
+RIMRoutingAddress ::= CHOICE {
+ gERAN-Cell-ID GERAN-Cell-ID,
+ ...
+}
+
+ReportArea ::= ENUMERATED {
+ ecgi,
+ ...
+}
+
+RepetitionPeriod ::= INTEGER (0..4096)
+
+
+RNC-ID ::= INTEGER (0..4095)
+
+RRC-Container ::= OCTET STRING
+
+RRC-Establishment-Cause ::= ENUMERATED {
+ emergency,
+ highPriorityAccess,
+ mt-Access,
+ mo-Signalling,
+ mo-Data,
+ ...
+}
+
+-- S
+
+
+SecurityKey ::= BIT STRING (SIZE(256))
+
+
+
+SecurityContext ::= SEQUENCE {
+ nextHopChainingCount INTEGER (0..7),
+ nextHopParameter SecurityKey,
+ iE-Extensions ProtocolExtensionContainer { { SecurityContext-ExtIEs} } OPTIONAL,
+ ...
+}
+
+
+SecurityContext-ExtIEs S1AP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+SerialNumber ::= BIT STRING (SIZE (16))
+
+SONInformation ::= CHOICE{
+ sONInformationRequest SONInformationRequest,
+ sONInformationReply SONInformationReply,
+ ...
+}
+
+SONInformationRequest ::= ENUMERATED {
+ x2TNL-Configuration-Info,
+ ...
+}
+
+SONInformationReply ::= SEQUENCE {
+ x2TNLConfigurationInfo X2TNLConfigurationInfo OPTIONAL,
+ iE-Extensions ProtocolExtensionContainer {{SONInformationReply-ExtIEs}} OPTIONAL,
+ ...
+}
+
+SONInformationReply-ExtIEs S1AP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+
+SONConfigurationTransfer ::= SEQUENCE {
+ targeteNB-ID TargeteNB-ID,
+ sourceeNB-ID SourceeNB-ID,
+ sONInformation SONInformation,
+ iE-Extensions ProtocolExtensionContainer { { SONConfigurationTransfer-ExtIEs} } OPTIONAL,
+...
+}
+
+SONConfigurationTransfer-ExtIEs S1AP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+
+
+Source-ToTarget-TransparentContainer ::= OCTET STRING
+
+SourceBSS-ToTargetBSS-TransparentContainer ::= OCTET STRING
+SourceeNB-ID ::= SEQUENCE {
+ global-ENB-ID Global-ENB-ID,
+ selected-TAI TAI,
+ iE-Extensions ProtocolExtensionContainer { {SourceeNB-ID-ExtIEs} } OPTIONAL
+}
+
+SourceeNB-ID-ExtIEs S1AP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+SRVCCOperationPossible ::= ENUMERATED {
+ possible,
+ ...
+}
+
+SRVCCHOIndication ::= ENUMERATED {
+ pSandCS,
+ cSonly,
+ ...
+}
+
+SourceeNB-ToTargeteNB-TransparentContainer ::= SEQUENCE {
+ rRC-Container RRC-Container,
+ e-RABInformationList E-RABInformationList OPTIONAL,
+ targetCell-ID EUTRAN-CGI,
+ subscriberProfileIDforRFP SubscriberProfileIDforRFP OPTIONAL,
+ uE-HistoryInformation UE-HistoryInformation,
+ iE-Extensions ProtocolExtensionContainer { {SourceeNB-ToTargeteNB-TransparentContainer-ExtIEs} } OPTIONAL,
+ ...
+}
+
+SourceeNB-ToTargeteNB-TransparentContainer-ExtIEs S1AP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+
+SourceRNC-ToTargetRNC-TransparentContainer ::= OCTET STRING
+
+
+ServedGUMMEIs ::= SEQUENCE (SIZE (1.. maxnoofRATs)) OF ServedGUMMEIsItem
+
+ServedGUMMEIsItem ::= SEQUENCE {
+ servedPLMNs ServedPLMNs,
+ servedGroupIDs ServedGroupIDs,
+ servedMMECs ServedMMECs,
+ iE-Extensions ProtocolExtensionContainer { {ServedGUMMEIsItem-ExtIEs} } OPTIONAL,
+ ...
+}
+
+ServedGUMMEIsItem-ExtIEs S1AP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+ServedGroupIDs ::= SEQUENCE (SIZE(1.. maxnoofGroupIDs)) OF MME-Group-ID
+ServedMMECs ::= SEQUENCE (SIZE(1.. maxnoofMMECs)) OF MME-Code
+
+ServedPLMNs ::= SEQUENCE (SIZE(1.. maxnoofPLMNsPerMME)) OF PLMNidentity
+
+SubscriberProfileIDforRFP ::= INTEGER (1..256)
+
+SupportedTAs ::= SEQUENCE (SIZE(1.. maxnoofTACs)) OF SupportedTAs-Item
+
+SupportedTAs-Item ::= SEQUENCE {
+ tAC TAC,
+ broadcastPLMNs BPLMNs,
+ iE-Extensions ProtocolExtensionContainer { {SupportedTAs-Item-ExtIEs} } OPTIONAL,
+ ...
+}
+
+SupportedTAs-Item-ExtIEs S1AP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+S-TMSI ::= SEQUENCE {
+ mMEC MME-Code,
+ m-TMSI M-TMSI,
+ iE-Extensions ProtocolExtensionContainer { {S-TMSI-ExtIEs} } OPTIONAL,
+ ...
+}
+
+S-TMSI-ExtIEs S1AP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+-- T
+
+TAC ::= OCTET STRING (SIZE (2))
+
+TAIListforWarning ::= SEQUENCE (SIZE(1..maxnoofTAIforWarning)) OF TAI
+
+TAI ::= SEQUENCE {
+ pLMNidentity PLMNidentity,
+ tAC TAC,
+ iE-Extensions ProtocolExtensionContainer { {TAI-ExtIEs} } OPTIONAL,
+ ...
+}
+
+TAI-ExtIEs S1AP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+TAI-Broadcast ::= SEQUENCE (SIZE(1..maxnoofTAIforWarning)) OF TAI-Broadcast-Item
+
+TAI-Broadcast-Item ::= SEQUENCE {
+ tAI TAI,
+ completedCellinTAI CompletedCellinTAI,
+ iE-Extensions ProtocolExtensionContainer { {TAI-Broadcast-Item-ExtIEs} } OPTIONAL,
+ ...
+}
+
+TAI-Broadcast-Item-ExtIEs S1AP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+CompletedCellinTAI ::= SEQUENCE (SIZE(1..maxnoofCellinTAI)) OF CompletedCellinTAI-Item
+
+CompletedCellinTAI-Item ::= SEQUENCE{
+ eCGI EUTRAN-CGI,
+ iE-Extensions ProtocolExtensionContainer { {CompletedCellinTAI-Item-ExtIEs} } OPTIONAL,
+ ...
+}
+
+CompletedCellinTAI-Item-ExtIEs S1AP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+TBCD-STRING ::= OCTET STRING (SIZE (3))
+
+TargetID ::= CHOICE {
+ targeteNB-ID TargeteNB-ID,
+ targetRNC-ID TargetRNC-ID,
+ cGI CGI,
+ ...
+}
+
+TargeteNB-ID ::= SEQUENCE {
+ global-ENB-ID Global-ENB-ID,
+ selected-TAI TAI,
+ iE-Extensions ProtocolExtensionContainer { {TargeteNB-ID-ExtIEs} } OPTIONAL,
+ ...
+}
+
+TargeteNB-ID-ExtIEs S1AP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+TargetRNC-ID ::= SEQUENCE {
+ lAI LAI,
+ rAC RAC OPTIONAL,
+ rNC-ID RNC-ID,
+ extendedRNC-ID ExtendedRNC-ID OPTIONAL,
+ iE-Extensions ProtocolExtensionContainer { {TargetRNC-ID-ExtIEs} } OPTIONAL,
+ ...
+ }
+
+
+TargetRNC-ID-ExtIEs S1AP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+
+TargeteNB-ToSourceeNB-TransparentContainer ::= SEQUENCE {
+ rRC-Container RRC-Container,
+ iE-Extensions ProtocolExtensionContainer { {TargeteNB-ToSourceeNB-TransparentContainer-ExtIEs} } OPTIONAL,
+ ...
+}
+
+TargeteNB-ToSourceeNB-TransparentContainer-ExtIEs S1AP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+Target-ToSource-TransparentContainer ::= OCTET STRING
+TargetRNC-ToSourceRNC-TransparentContainer ::= OCTET STRING
+TargetBSS-ToSourceBSS-TransparentContainer ::= OCTET STRING
+
+TimeToWait ::= ENUMERATED {v1s, v2s, v5s, v10s, v20s, v60s, ...}
+
+Time-UE-StayedInCell ::= INTEGER (0..4095)
+
+TransportLayerAddress ::= BIT STRING (SIZE(1..160, ...))
+
+TraceActivation ::= SEQUENCE {
+ e-UTRAN-Trace-ID E-UTRAN-Trace-ID,
+ interfacesToTrace InterfacesToTrace,
+traceDepth TraceDepth,
+traceCollectionEntityIPAddress TransportLayerAddress,
+ iE-Extensions ProtocolExtensionContainer { { TraceActivation-ExtIEs} } OPTIONAL,
+ ...
+}
+
+TraceActivation-ExtIEs S1AP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+TraceDepth ::= ENUMERATED {
+ minimum,
+ medium,
+ maximum,
+ minimumWithoutVendorSpecificExtension,
+ mediumWithoutVendorSpecificExtension,
+ maximumWithoutVendorSpecificExtension,
+ ...
+}
+
+E-UTRAN-Trace-ID ::= OCTET STRING (SIZE (8))
+
+TypeOfError ::= ENUMERATED {
+ not-understood,
+ missing,
+ ...
+}
+
+-- U
+
+UEAggregateMaximumBitrate ::= SEQUENCE {
+ uEaggregateMaximumBitRateDL BitRate,
+ uEaggregateMaximumBitRateUL BitRate,
+ iE-Extensions ProtocolExtensionContainer { {UEAggregate-MaximumBitrates-ExtIEs} } OPTIONAL,
+ ...
+}
+
+UEAggregate-MaximumBitrates-ExtIEs S1AP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+
+
+UE-S1AP-IDs ::= CHOICE{
+ uE-S1AP-ID-pair UE-S1AP-ID-pair,
+ mME-UE-S1AP-ID MME-UE-S1AP-ID,
+ ...
+}
+
+UE-S1AP-ID-pair ::= SEQUENCE{
+ mME-UE-S1AP-ID MME-UE-S1AP-ID,
+ eNB-UE-S1AP-ID ENB-UE-S1AP-ID,
+ iE-Extensions ProtocolExtensionContainer { {UE-S1AP-ID-pair-ExtIEs} } OPTIONAL,
+ ...
+}
+UE-S1AP-ID-pair-ExtIEs S1AP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+
+UE-associatedLogicalS1-ConnectionItem ::= SEQUENCE {
+ mME-UE-S1AP-ID MME-UE-S1AP-ID OPTIONAL,
+ eNB-UE-S1AP-ID ENB-UE-S1AP-ID OPTIONAL,
+ iE-Extensions ProtocolExtensionContainer { { UE-associatedLogicalS1-ConnectionItemExtIEs} } OPTIONAL,
+ ...
+}
+
+
+UE-associatedLogicalS1-ConnectionItemExtIEs S1AP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+UEIdentityIndexValue ::= BIT STRING (SIZE (10))
+
+UE-HistoryInformation ::= SEQUENCE (SIZE(1..maxnoofCells)) OF LastVisitedCell-Item
+
+UEPagingID ::= CHOICE {
+ s-TMSI S-TMSI,
+ iMSI IMSI,
+ ...
+ }
+
+UERadioCapability ::= OCTET STRING
+
+UESecurityCapabilities ::= SEQUENCE {
+ encryptionAlgorithms EncryptionAlgorithms,
+ integrityProtectionAlgorithms IntegrityProtectionAlgorithms,
+ iE-Extensions ProtocolExtensionContainer { { UESecurityCapabilities-ExtIEs} } OPTIONAL,
+...
+}
+
+UESecurityCapabilities-ExtIEs S1AP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+-- V
+-- W
+
+WarningAreaList ::= CHOICE {
+ cellIDList ECGIList,
+ trackingAreaListforWarning TAIListforWarning,
+ emergencyAreaIDList EmergencyAreaIDList,
+ ...
+}
+
+
+WarningType ::= OCTET STRING (SIZE (2))
+
+WarningSecurityInfo ::= OCTET STRING (SIZE (50))
+
+
+WarningMessageContents ::= OCTET STRING (SIZE(1..9600))
+
+
+-- X
+
+
+X2TNLConfigurationInfo ::= SEQUENCE {
+ eNBX2TransportLayerAddresses ENBX2TLAs,
+ iE-Extensions ProtocolExtensionContainer { { X2TNLConfigurationInfo-ExtIEs} } OPTIONAL,
+ ...
+}
+
+X2TNLConfigurationInfo-ExtIEs S1AP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+-- Y
+-- Z
+
+END
diff --git a/lib/asn1/test/asn1_SUITE_data/S1AP-PDU-Contents.asn b/lib/asn1/test/asn1_SUITE_data/S1AP-PDU-Contents.asn
new file mode 100644
index 0000000000..e9762a2b62
--- /dev/null
+++ b/lib/asn1/test/asn1_SUITE_data/S1AP-PDU-Contents.asn
@@ -0,0 +1,2083 @@
+-- $Id$
+-- 3GPP TS 36.413 V8.6.1 (2009-06)
+-- 9.3.3 PDU Definitions
+-- **************************************************************
+--
+-- PDU definitions for S1AP.
+--
+-- **************************************************************
+
+S1AP-PDU-Contents {
+itu-t (0) identified-organization (4) etsi (0) mobileDomain (0)
+eps-Access (20) modules (3) s1ap (1) version1 (1) s1ap-PDU-Contents (1) }
+
+DEFINITIONS AUTOMATIC TAGS ::=
+
+BEGIN
+
+-- **************************************************************
+--
+-- IE parameter types from other modules.
+--
+-- **************************************************************
+
+IMPORTS
+
+ UEAggregateMaximumBitrate,
+ Cause,
+ Cdma2000HORequiredIndication,
+ Cdma2000HOStatus,
+ Cdma2000OneXSRVCCInfo,
+ Cdma2000OneXRAND,
+ Cdma2000PDU,
+ Cdma2000RATType,
+ Cdma2000SectorID,
+ CNDomain,
+ CriticalityDiagnostics,
+ CSFallbackIndicator,
+ CSG-Id,
+ CSG-IdList,
+ Direct-Forwarding-Path-Availability,
+ Global-ENB-ID,
+ EUTRAN-CGI,
+ ENBname,
+ ENB-StatusTransfer-TransparentContainer,
+ ENB-UE-S1AP-ID,
+ GTP-TEID,
+ GUMMEI,
+ HandoverRestrictionList,
+ HandoverType,
+ MMEname,
+ MME-UE-S1AP-ID,
+ MSClassmark2,
+ MSClassmark3,
+ NAS-PDU,
+ NASSecurityParametersfromE-UTRAN,
+ NASSecurityParameterstoE-UTRAN,
+ OverloadResponse,
+ PagingDRX,
+ PLMNidentity,
+ RIMTransfer,
+ RelativeMMECapacity,
+ RequestType,
+ E-RAB-ID,
+ E-RABLevelQoSParameters,
+ E-RABList,
+ SecurityKey,
+ SecurityContext,
+ ServedGUMMEIs,
+ SONConfigurationTransfer,
+ Source-ToTarget-TransparentContainer,
+ SourceBSS-ToTargetBSS-TransparentContainer,
+ SourceeNB-ToTargeteNB-TransparentContainer,
+ SourceRNC-ToTargetRNC-TransparentContainer,
+ SubscriberProfileIDforRFP,
+ SRVCCOperationPossible,
+ SRVCCHOIndication,
+ SupportedTAs,
+ TAI,
+ Target-ToSource-TransparentContainer,
+ TargetBSS-ToSourceBSS-TransparentContainer,
+ TargeteNB-ToSourceeNB-TransparentContainer,
+ TargetID,
+ TargetRNC-ToSourceRNC-TransparentContainer,
+ TimeToWait,
+ TraceActivation,
+ E-UTRAN-Trace-ID,
+ TransportLayerAddress,
+ UEIdentityIndexValue,
+ UEPagingID,
+ UERadioCapability,
+ UE-S1AP-IDs,
+ UE-associatedLogicalS1-ConnectionItem,
+ UESecurityCapabilities,
+ S-TMSI,
+ MessageIdentifier,
+ SerialNumber,
+ WarningAreaList,
+ RepetitionPeriod,
+ NumberofBroadcastRequest,
+ WarningType,
+ WarningSecurityInfo,
+ DataCodingScheme,
+ WarningMessageContents,
+ BroadcastCompletedAreaList,
+ RRC-Establishment-Cause
+
+FROM S1AP-IEs
+
+ PrivateIE-Container{},
+ ProtocolExtensionContainer{},
+ ProtocolIE-Container{},
+ ProtocolIE-ContainerList{},
+ ProtocolIE-ContainerPair{},
+ ProtocolIE-ContainerPairList{},
+ ProtocolIE-SingleContainer{},
+ S1AP-PRIVATE-IES,
+ S1AP-PROTOCOL-EXTENSION,
+ S1AP-PROTOCOL-IES,
+ S1AP-PROTOCOL-IES-PAIR
+FROM S1AP-Containers
+
+
+ id-uEaggregateMaximumBitrate,
+ id-Cause,
+ id-cdma2000HORequiredIndication,
+ id-cdma2000HOStatus,
+ id-cdma2000OneXSRVCCInfo,
+ id-cdma2000OneXRAND,
+ id-cdma2000PDU,
+ id-cdma2000RATType,
+ id-cdma2000SectorID,
+ id-CNDomain,
+ id-CriticalityDiagnostics,
+ id-CSFallbackIndicator,
+ id-CSG-Id,
+ id-CSG-IdList,
+ id-DefaultPagingDRX,
+ id-Direct-Forwarding-Path-Availability,
+ id-Global-ENB-ID,
+ id-EUTRAN-CGI,
+ id-eNBname,
+ id-eNB-StatusTransfer-TransparentContainer,
+ id-eNB-UE-S1AP-ID,
+ id-GERANtoLTEHOInformationRes,
+ id-GUMMEI-ID,
+ id-HandoverRestrictionList,
+ id-HandoverType,
+ id-InitialContextSetup,
+ id-Inter-SystemInformationTransferTypeEDT,
+ id-Inter-SystemInformationTransferTypeMDT,
+ id-NAS-DownlinkCount,
+ id-MMEname,
+ id-MME-UE-S1AP-ID,
+ id-MSClassmark2,
+ id-MSClassmark3,
+ id-NAS-PDU,
+ id-NASSecurityParametersfromE-UTRAN,
+ id-NASSecurityParameterstoE-UTRAN,
+ id-OverloadResponse,
+ id-pagingDRX,
+ id-RelativeMMECapacity,
+ id-RequestType,
+ id-E-RABAdmittedItem,
+ id-E-RABAdmittedList,
+ id-E-RABDataForwardingItem,
+ id-E-RABFailedToModifyList,
+ id-E-RABFailedToReleaseList,
+ id-E-RABFailedtoSetupItemHOReqAck,
+ id-E-RABFailedToSetupListBearerSURes,
+ id-E-RABFailedToSetupListCtxtSURes,
+ id-E-RABFailedToSetupListHOReqAck,
+ id-E-RABFailedToBeReleasedList,
+ id-E-RABModify,
+ id-E-RABModifyItemBearerModRes,
+ id-E-RABModifyListBearerModRes,
+ id-E-RABRelease,
+ id-E-RABReleaseItemBearerRelComp,
+ id-E-RABReleaseItemHOCmd,
+ id-E-RABReleaseListBearerRelComp,
+ id-E-RABReleaseIndication,
+ id-E-RABSetup,
+ id-E-RABSetupItemBearerSURes,
+ id-E-RABSetupItemCtxtSURes,
+ id-E-RABSetupListBearerSURes,
+ id-E-RABSetupListCtxtSURes,
+ id-E-RABSubjecttoDataForwardingList,
+ id-E-RABToBeModifiedItemBearerModReq,
+ id-E-RABToBeModifiedListBearerModReq,
+ id-E-RABToBeReleasedList,
+ id-E-RABReleasedList,
+ id-E-RABToBeSetupItemBearerSUReq,
+ id-E-RABToBeSetupItemCtxtSUReq,
+ id-E-RABToBeSetupItemHOReq,
+ id-E-RABToBeSetupListBearerSUReq,
+ id-E-RABToBeSetupListCtxtSUReq,
+ id-E-RABToBeSetupListHOReq,
+ id-E-RABToBeSwitchedDLItem,
+ id-E-RABToBeSwitchedDLList,
+ id-E-RABToBeSwitchedULList,
+ id-E-RABToBeSwitchedULItem,
+ id-E-RABtoReleaseListHOCmd,
+ id-SecurityKey,
+ id-SecurityContext,
+ id-ServedGUMMEIs,
+ id-SONConfigurationTransferECT,
+ id-SONConfigurationTransferMCT,
+ id-Source-ToTarget-TransparentContainer,
+ id-Source-ToTarget-TransparentContainer-Secondary,
+ id-SourceMME-UE-S1AP-ID,
+ id-SRVCCOperationPossible,
+ id-SRVCCHOIndication,
+ id-SubscriberProfileIDforRFP,
+ id-SupportedTAs,
+ id-S-TMSI,
+ id-TAI,
+ id-TAIItem,
+ id-TAIList,
+ id-Target-ToSource-TransparentContainer,
+ id-Target-ToSource-TransparentContainer-Secondary,
+ id-TargetID,
+ id-TimeToWait,
+ id-TraceActivation,
+ id-E-UTRAN-Trace-ID,
+ id-UEIdentityIndexValue,
+ id-UEPagingID,
+ id-UERadioCapability,
+ id-UTRANtoLTEHOInformationRes,
+ id-UE-associatedLogicalS1-ConnectionListResAck,
+ id-UE-associatedLogicalS1-ConnectionItem,
+ id-UESecurityCapabilities,
+ id-UE-S1AP-IDs,
+ id-ResetType,
+ id-MessageIdentifier,
+ id-SerialNumber,
+ id-WarningAreaList,
+ id-RepetitionPeriod,
+ id-NumberofBroadcastRequest,
+ id-WarningType,
+ id-WarningSecurityInfo,
+ id-DataCodingScheme,
+ id-WarningMessageContents,
+ id-BroadcastCompletedAreaList,
+ id-RRC-Establishment-Cause,
+ id-TraceCollectionEntityIPAddress,
+ maxnoofTAIs,
+ maxNrOfErrors,
+ maxNrOfE-RABs,
+ maxNrOfIndividualS1ConnectionsToReset,
+ maxnoofEmergencyAreaID,
+ maxnoofCellID,
+ maxnoofTAIforWarning,
+ maxnoofCellinTAI,
+ maxnoofCellinEAI
+
+
+FROM S1AP-Constants;
+
+-- **************************************************************
+--
+-- Common Container Lists
+--
+-- **************************************************************
+
+E-RAB-IE-ContainerList { S1AP-PROTOCOL-IES : IEsSetParam } ::= ProtocolIE-ContainerList { 1, maxNrOfE-RABs, {IEsSetParam} }
+E-RAB-IE-ContainerPairList { S1AP-PROTOCOL-IES-PAIR : IEsSetParam } ::= ProtocolIE-ContainerPairList { 1, maxNrOfE-RABs, {IEsSetParam} }
+ProtocolError-IE-ContainerList { S1AP-PROTOCOL-IES : IEsSetParam } ::= ProtocolIE-ContainerList { 1, maxNrOfE-RABs, {IEsSetParam} }
+
+-- **************************************************************
+--
+-- HANDOVER PREPARATION ELEMENTARY PROCEDURE
+--
+-- **************************************************************
+
+-- **************************************************************
+--
+-- Handover Required
+--
+-- **************************************************************
+
+HandoverRequired ::= SEQUENCE {
+ protocolIEs ProtocolIE-Container { { HandoverRequiredIEs} },
+ ...
+}
+
+HandoverRequiredIEs S1AP-PROTOCOL-IES ::= {
+ { ID id-MME-UE-S1AP-ID CRITICALITY reject TYPE MME-UE-S1AP-ID PRESENCE mandatory } |
+ { ID id-eNB-UE-S1AP-ID CRITICALITY reject TYPE ENB-UE-S1AP-ID PRESENCE mandatory } |
+ { ID id-HandoverType CRITICALITY reject TYPE HandoverType PRESENCE mandatory } |
+ { ID id-Cause CRITICALITY ignore TYPE Cause PRESENCE mandatory } |
+ { ID id-TargetID CRITICALITY reject TYPE TargetID PRESENCE mandatory } |
+ { ID id-Direct-Forwarding-Path-Availability CRITICALITY ignore TYPE Direct-Forwarding-Path-Availability PRESENCE optional } |
+ { ID id-SRVCCHOIndication CRITICALITY reject TYPE SRVCCHOIndication PRESENCE optional }|
+ { ID id-Source-ToTarget-TransparentContainer CRITICALITY reject TYPE Source-ToTarget-TransparentContainer PRESENCE mandatory }|
+ { ID id-Source-ToTarget-TransparentContainer-Secondary CRITICALITY reject TYPE Source-ToTarget-TransparentContainer PRESENCE optional }|
+ { ID id-MSClassmark2 CRITICALITY reject TYPE MSClassmark2 PRESENCE conditional }|
+ { ID id-MSClassmark3 CRITICALITY ignore TYPE MSClassmark3 PRESENCE conditional },
+ ...
+}
+
+
+-- **************************************************************
+--
+-- Handover Command
+--
+-- **************************************************************
+
+HandoverCommand ::= SEQUENCE {
+ protocolIEs ProtocolIE-Container { { HandoverCommandIEs} },
+ ...
+}
+
+HandoverCommandIEs S1AP-PROTOCOL-IES ::= {
+ { ID id-MME-UE-S1AP-ID CRITICALITY reject TYPE MME-UE-S1AP-ID PRESENCE mandatory } |
+ { ID id-eNB-UE-S1AP-ID CRITICALITY reject TYPE ENB-UE-S1AP-ID PRESENCE mandatory } |
+ { ID id-HandoverType CRITICALITY reject TYPE HandoverType PRESENCE mandatory } |
+ { ID id-NASSecurityParametersfromE-UTRAN CRITICALITY reject TYPE NASSecurityParametersfromE-UTRAN PRESENCE conditional
+ -- This IE shall be present if HandoverType IE is set to value "LTEtoUTRAN" or "LTEtoGERAN" -- }|
+ { ID id-E-RABSubjecttoDataForwardingList CRITICALITY ignore TYPE E-RABSubjecttoDataForwardingList PRESENCE optional } |
+ { ID id-E-RABtoReleaseListHOCmd CRITICALITY ignore TYPE E-RABList PRESENCE optional } |
+ { ID id-Target-ToSource-TransparentContainer CRITICALITY reject TYPE Target-ToSource-TransparentContainer PRESENCE mandatory }|
+ { ID id-Target-ToSource-TransparentContainer-Secondary CRITICALITY reject TYPE Target-ToSource-TransparentContainer PRESENCE optional }|
+ { ID id-CriticalityDiagnostics CRITICALITY ignore TYPE CriticalityDiagnostics PRESENCE optional },
+ ...
+}
+
+E-RABSubjecttoDataForwardingList ::= E-RAB-IE-ContainerList { {E-RABDataForwardingItemIEs} }
+
+E-RABDataForwardingItemIEs S1AP-PROTOCOL-IES ::= {
+ { ID id-E-RABDataForwardingItem CRITICALITY ignore TYPE E-RABDataForwardingItem PRESENCE mandatory },
+ ...
+}
+
+E-RABDataForwardingItem ::= SEQUENCE {
+ e-RAB-ID E-RAB-ID,
+ dL-transportLayerAddress TransportLayerAddress OPTIONAL,
+ dL-gTP-TEID GTP-TEID OPTIONAL,
+ uL-TransportLayerAddress TransportLayerAddress OPTIONAL,
+ uL-GTP-TEID GTP-TEID OPTIONAL,
+ iE-Extensions ProtocolExtensionContainer { { E-RABDataForwardingItem-ExtIEs} } OPTIONAL,
+ ...
+}
+
+E-RABDataForwardingItem-ExtIEs S1AP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+
+
+-- **************************************************************
+--
+-- Handover Preparation Failure
+--
+-- **************************************************************
+
+HandoverPreparationFailure ::= SEQUENCE {
+ protocolIEs ProtocolIE-Container { { HandoverPreparationFailureIEs} },
+ ...
+}
+
+HandoverPreparationFailureIEs S1AP-PROTOCOL-IES ::= {
+ { ID id-MME-UE-S1AP-ID CRITICALITY ignore TYPE MME-UE-S1AP-ID PRESENCE mandatory } |
+ { ID id-eNB-UE-S1AP-ID CRITICALITY ignore TYPE ENB-UE-S1AP-ID PRESENCE mandatory } |
+ { ID id-Cause CRITICALITY ignore TYPE Cause PRESENCE mandatory }|
+ { ID id-CriticalityDiagnostics CRITICALITY ignore TYPE CriticalityDiagnostics PRESENCE optional },
+ ...
+}
+
+-- **************************************************************
+--
+-- HANDOVER RESOURCE ALLOCATION ELEMENTARY PROCEDURE
+--
+-- **************************************************************
+
+-- **************************************************************
+--
+-- Handover Request
+--
+-- **************************************************************
+
+HandoverRequest ::= SEQUENCE {
+ protocolIEs ProtocolIE-Container { {HandoverRequestIEs} },
+ ...
+}
+
+HandoverRequestIEs S1AP-PROTOCOL-IES ::= {
+ { ID id-MME-UE-S1AP-ID CRITICALITY reject TYPE MME-UE-S1AP-ID PRESENCE mandatory } |
+ { ID id-HandoverType CRITICALITY reject TYPE HandoverType PRESENCE mandatory } |
+ { ID id-Cause CRITICALITY ignore TYPE Cause PRESENCE mandatory } |
+ { ID id-uEaggregateMaximumBitrate CRITICALITY reject TYPE UEAggregateMaximumBitrate PRESENCE mandatory }|
+ { ID id-E-RABToBeSetupListHOReq CRITICALITY reject TYPE E-RABToBeSetupListHOReq PRESENCE mandatory } |
+ { ID id-Source-ToTarget-TransparentContainer CRITICALITY reject TYPE Source-ToTarget-TransparentContainer PRESENCE mandatory } |
+ { ID id-UESecurityCapabilities CRITICALITY reject TYPE UESecurityCapabilities PRESENCE mandatory }|
+ { ID id-HandoverRestrictionList CRITICALITY ignore TYPE HandoverRestrictionList PRESENCE optional }|
+ { ID id-TraceActivation CRITICALITY ignore TYPE TraceActivation PRESENCE optional }|
+ { ID id-RequestType CRITICALITY ignore TYPE RequestType PRESENCE optional }|
+ { ID id-SRVCCOperationPossible CRITICALITY ignore TYPE SRVCCOperationPossible PRESENCE optional }|
+ { ID id-SecurityContext CRITICALITY reject TYPE SecurityContext PRESENCE mandatory}|
+ { ID id-NASSecurityParameterstoE-UTRAN CRITICALITY reject TYPE NASSecurityParameterstoE-UTRAN PRESENCE conditional
+ -- This IE shall be present if the Handover Type IE is set to the value "UTRANtoLTE" or "GERANtoLTE" -- },
+ ...
+}
+
+E-RABToBeSetupListHOReq ::= E-RAB-IE-ContainerList { {E-RABToBeSetupItemHOReqIEs} }
+
+E-RABToBeSetupItemHOReqIEs S1AP-PROTOCOL-IES ::= {
+ { ID id-E-RABToBeSetupItemHOReq CRITICALITY reject TYPE E-RABToBeSetupItemHOReq PRESENCE mandatory },
+ ...
+}
+
+E-RABToBeSetupItemHOReq ::= SEQUENCE {
+ e-RAB-ID E-RAB-ID,
+ transportLayerAddress TransportLayerAddress,
+ gTP-TEID GTP-TEID,
+ e-RABlevelQosParameters E-RABLevelQoSParameters,
+ iE-Extensions ProtocolExtensionContainer { {E-RABToBeSetupItemHOReq-ExtIEs} } OPTIONAL,
+ ...
+}
+
+E-RABToBeSetupItemHOReq-ExtIEs S1AP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+-- **************************************************************
+--
+-- Handover Request Acknowledge
+--
+-- **************************************************************
+
+HandoverRequestAcknowledge ::= SEQUENCE {
+ protocolIEs ProtocolIE-Container { {HandoverRequestAcknowledgeIEs} },
+ ...
+}
+
+HandoverRequestAcknowledgeIEs S1AP-PROTOCOL-IES ::= {
+ { ID id-MME-UE-S1AP-ID CRITICALITY ignore TYPE MME-UE-S1AP-ID PRESENCE mandatory } |
+ { ID id-eNB-UE-S1AP-ID CRITICALITY ignore TYPE ENB-UE-S1AP-ID PRESENCE mandatory } |
+ { ID id-E-RABAdmittedList CRITICALITY ignore TYPE E-RABAdmittedList PRESENCE mandatory } |
+ { ID id-E-RABFailedToSetupListHOReqAck CRITICALITY ignore TYPE E-RABFailedtoSetupListHOReqAck PRESENCE optional } |
+ { ID id-Target-ToSource-TransparentContainer CRITICALITY reject TYPE Target-ToSource-TransparentContainer PRESENCE mandatory }|
+ { ID id-CriticalityDiagnostics CRITICALITY ignore TYPE CriticalityDiagnostics PRESENCE optional },
+ ...
+}
+
+E-RABAdmittedList ::= E-RAB-IE-ContainerList { {E-RABAdmittedItemIEs} }
+
+E-RABAdmittedItemIEs S1AP-PROTOCOL-IES ::= {
+ { ID id-E-RABAdmittedItem CRITICALITY ignore TYPE E-RABAdmittedItem PRESENCE mandatory },
+ ...
+}
+
+E-RABAdmittedItem ::= SEQUENCE {
+ e-RAB-ID E-RAB-ID,
+ transportLayerAddress TransportLayerAddress,
+ gTP-TEID GTP-TEID,
+ dL-transportLayerAddress TransportLayerAddress OPTIONAL,
+ dL-gTP-TEID GTP-TEID OPTIONAL,
+ uL-TransportLayerAddress TransportLayerAddress OPTIONAL,
+ uL-GTP-TEID GTP-TEID OPTIONAL,
+ iE-Extensions ProtocolExtensionContainer { {E-RABAdmittedItem-ExtIEs} } OPTIONAL,
+ ...
+}
+
+E-RABAdmittedItem-ExtIEs S1AP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+E-RABFailedtoSetupListHOReqAck ::= E-RAB-IE-ContainerList { {E-RABFailedtoSetupItemHOReqAckIEs} }
+
+E-RABFailedtoSetupItemHOReqAckIEs S1AP-PROTOCOL-IES ::= {
+ { ID id-E-RABFailedtoSetupItemHOReqAck CRITICALITY ignore TYPE E-RABFailedToSetupItemHOReqAck PRESENCE mandatory },
+ ...
+}
+
+E-RABFailedToSetupItemHOReqAck ::= SEQUENCE {
+ e-RAB-ID E-RAB-ID,
+ cause Cause,
+ iE-Extensions ProtocolExtensionContainer { { E-RABFailedToSetupItemHOReqAckExtIEs} } OPTIONAL,
+ ...
+}
+
+E-RABFailedToSetupItemHOReqAckExtIEs S1AP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+
+-- **************************************************************
+--
+-- Handover Failure
+--
+-- **************************************************************
+
+HandoverFailure ::= SEQUENCE {
+ protocolIEs ProtocolIE-Container { { HandoverFailureIEs} },
+ ...
+}
+
+HandoverFailureIEs S1AP-PROTOCOL-IES ::= {
+ { ID id-MME-UE-S1AP-ID CRITICALITY ignore TYPE MME-UE-S1AP-ID PRESENCE mandatory } |
+ { ID id-Cause CRITICALITY ignore TYPE Cause PRESENCE mandatory }|
+ { ID id-CriticalityDiagnostics CRITICALITY ignore TYPE CriticalityDiagnostics PRESENCE optional },
+ ...
+}
+
+-- **************************************************************
+--
+-- HANDOVER NOTIFICATION ELEMENTARY PROCEDURE
+--
+-- **************************************************************
+
+-- **************************************************************
+--
+-- Handover Notify
+--
+-- **************************************************************
+
+HandoverNotify ::= SEQUENCE {
+ protocolIEs ProtocolIE-Container { { HandoverNotifyIEs} },
+ ...
+}
+
+HandoverNotifyIEs S1AP-PROTOCOL-IES ::= {
+ { ID id-MME-UE-S1AP-ID CRITICALITY reject TYPE MME-UE-S1AP-ID PRESENCE mandatory } |
+ { ID id-eNB-UE-S1AP-ID CRITICALITY reject TYPE ENB-UE-S1AP-ID PRESENCE mandatory } |
+ { ID id-EUTRAN-CGI CRITICALITY ignore TYPE EUTRAN-CGI PRESENCE mandatory}|
+ { ID id-TAI CRITICALITY ignore TYPE TAI PRESENCE mandatory},
+ ...
+}
+
+-- **************************************************************
+--
+-- PATH SWITCH REQUEST ELEMENTARY PROCEDURE
+--
+-- **************************************************************
+
+-- **************************************************************
+--
+-- Path Switch Request
+--
+-- **************************************************************
+
+PathSwitchRequest ::= SEQUENCE {
+ protocolIEs ProtocolIE-Container { { PathSwitchRequestIEs} },
+ ...
+}
+
+PathSwitchRequestIEs S1AP-PROTOCOL-IES ::= {
+ { ID id-eNB-UE-S1AP-ID CRITICALITY reject TYPE ENB-UE-S1AP-ID PRESENCE mandatory }|
+ { ID id-E-RABToBeSwitchedDLList CRITICALITY reject TYPE E-RABToBeSwitchedDLList PRESENCE mandatory }|
+ { ID id-SourceMME-UE-S1AP-ID CRITICALITY reject TYPE MME-UE-S1AP-ID PRESENCE mandatory }|
+ { ID id-EUTRAN-CGI CRITICALITY ignore TYPE EUTRAN-CGI PRESENCE mandatory}|
+ { ID id-TAI CRITICALITY ignore TYPE TAI PRESENCE mandatory}|
+ { ID id-UESecurityCapabilities CRITICALITY ignore TYPE UESecurityCapabilities PRESENCE mandatory },
+ ...
+}
+
+E-RABToBeSwitchedDLList ::= E-RAB-IE-ContainerList { {E-RABToBeSwitchedDLItemIEs} }
+
+E-RABToBeSwitchedDLItemIEs S1AP-PROTOCOL-IES ::= {
+ { ID id-E-RABToBeSwitchedDLItem CRITICALITY reject TYPE E-RABToBeSwitchedDLItem PRESENCE mandatory },
+ ...
+}
+
+E-RABToBeSwitchedDLItem ::= SEQUENCE {
+ e-RAB-ID E-RAB-ID,
+ transportLayerAddress TransportLayerAddress,
+ gTP-TEID GTP-TEID,
+ iE-Extensions ProtocolExtensionContainer { { E-RABToBeSwitchedDLItem-ExtIEs} } OPTIONAL,
+ ...
+}
+
+E-RABToBeSwitchedDLItem-ExtIEs S1AP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+-- **************************************************************
+--
+-- Path Switch Request Acknowledge
+--
+-- **************************************************************
+
+PathSwitchRequestAcknowledge ::= SEQUENCE {
+ protocolIEs ProtocolIE-Container { { PathSwitchRequestAcknowledgeIEs} },
+ ...
+}
+
+PathSwitchRequestAcknowledgeIEs S1AP-PROTOCOL-IES ::= {
+ { ID id-MME-UE-S1AP-ID CRITICALITY ignore TYPE MME-UE-S1AP-ID PRESENCE mandatory } |
+ { ID id-eNB-UE-S1AP-ID CRITICALITY ignore TYPE ENB-UE-S1AP-ID PRESENCE mandatory }|
+ { ID id-uEaggregateMaximumBitrate CRITICALITY ignore TYPE UEAggregateMaximumBitrate PRESENCE optional }|
+ { ID id-E-RABToBeSwitchedULList CRITICALITY ignore TYPE E-RABToBeSwitchedULList PRESENCE optional }|
+ { ID id-E-RABToBeReleasedList CRITICALITY ignore TYPE E-RABList PRESENCE optional }|
+ { ID id-SecurityContext CRITICALITY reject TYPE SecurityContext PRESENCE mandatory}|
+ { ID id-CriticalityDiagnostics CRITICALITY ignore TYPE CriticalityDiagnostics PRESENCE optional },
+ ...
+}
+
+E-RABToBeSwitchedULList ::= E-RAB-IE-ContainerList { {E-RABToBeSwitchedULItemIEs} }
+
+E-RABToBeSwitchedULItemIEs S1AP-PROTOCOL-IES ::= {
+ { ID id-E-RABToBeSwitchedULItem CRITICALITY ignore TYPE E-RABToBeSwitchedULItem PRESENCE mandatory },
+ ...
+}
+
+E-RABToBeSwitchedULItem ::= SEQUENCE {
+ e-RAB-ID E-RAB-ID,
+ transportLayerAddress TransportLayerAddress,
+ gTP-TEID GTP-TEID,
+ iE-Extensions ProtocolExtensionContainer { { E-RABToBeSwitchedULItem-ExtIEs} } OPTIONAL,
+ ...
+}
+
+E-RABToBeSwitchedULItem-ExtIEs S1AP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+
+-- **************************************************************
+--
+-- Path Switch Request Failure
+--
+-- **************************************************************
+
+PathSwitchRequestFailure ::= SEQUENCE {
+ protocolIEs ProtocolIE-Container { { PathSwitchRequestFailureIEs} },
+ ...
+}
+
+PathSwitchRequestFailureIEs S1AP-PROTOCOL-IES ::= {
+ { ID id-MME-UE-S1AP-ID CRITICALITY ignore TYPE MME-UE-S1AP-ID PRESENCE mandatory } |
+ { ID id-eNB-UE-S1AP-ID CRITICALITY ignore TYPE ENB-UE-S1AP-ID PRESENCE mandatory } |
+ { ID id-Cause CRITICALITY ignore TYPE Cause PRESENCE mandatory }|
+ { ID id-CriticalityDiagnostics CRITICALITY ignore TYPE CriticalityDiagnostics PRESENCE optional },
+ ...
+}
+
+-- **************************************************************
+--
+-- HANDOVER CANCEL ELEMENTARY PROCEDURE
+--
+-- **************************************************************
+
+-- **************************************************************
+--
+-- Handover Cancel
+--
+-- **************************************************************
+
+HandoverCancel ::= SEQUENCE {
+ protocolIEs ProtocolIE-Container { { HandoverCancelIEs} },
+ ...
+}
+
+HandoverCancelIEs S1AP-PROTOCOL-IES ::= {
+ { ID id-MME-UE-S1AP-ID CRITICALITY reject TYPE MME-UE-S1AP-ID PRESENCE mandatory } |
+ { ID id-eNB-UE-S1AP-ID CRITICALITY reject TYPE ENB-UE-S1AP-ID PRESENCE mandatory } |
+ { ID id-Cause CRITICALITY ignore TYPE Cause PRESENCE mandatory },
+ ...
+}
+
+-- **************************************************************
+--
+-- Handover Cancel Request Acknowledge
+--
+-- **************************************************************
+
+HandoverCancelAcknowledge ::= SEQUENCE {
+ protocolIEs ProtocolIE-Container { { HandoverCancelAcknowledgeIEs} },
+ ...
+}
+
+HandoverCancelAcknowledgeIEs S1AP-PROTOCOL-IES ::= {
+ { ID id-MME-UE-S1AP-ID CRITICALITY ignore TYPE MME-UE-S1AP-ID PRESENCE mandatory } |
+ { ID id-eNB-UE-S1AP-ID CRITICALITY ignore TYPE ENB-UE-S1AP-ID PRESENCE mandatory }|
+ { ID id-CriticalityDiagnostics CRITICALITY ignore TYPE CriticalityDiagnostics PRESENCE optional },
+ ...
+}
+
+-- **************************************************************
+--
+-- E-RAB SETUP ELEMENTARY PROCEDURE
+--
+-- **************************************************************
+
+-- **************************************************************
+--
+-- E-RAB Setup Request
+--
+-- **************************************************************
+
+E-RABSetupRequest ::= SEQUENCE {
+ protocolIEs ProtocolIE-Container { {E-RABSetupRequestIEs} },
+ ...
+}
+
+E-RABSetupRequestIEs S1AP-PROTOCOL-IES ::= {
+ { ID id-MME-UE-S1AP-ID CRITICALITY reject TYPE MME-UE-S1AP-ID PRESENCE mandatory }|
+ { ID id-eNB-UE-S1AP-ID CRITICALITY reject TYPE ENB-UE-S1AP-ID PRESENCE mandatory }|
+ { ID id-uEaggregateMaximumBitrate CRITICALITY reject TYPE UEAggregateMaximumBitrate PRESENCE optional }|
+ { ID id-E-RABToBeSetupListBearerSUReq CRITICALITY reject TYPE E-RABToBeSetupListBearerSUReq PRESENCE mandatory },
+ ...
+}
+
+E-RABToBeSetupListBearerSUReq ::= SEQUENCE (SIZE(1.. maxNrOfE-RABs)) OF ProtocolIE-SingleContainer { {E-RABToBeSetupItemBearerSUReqIEs} }
+
+E-RABToBeSetupItemBearerSUReqIEs S1AP-PROTOCOL-IES ::= {
+ { ID id-E-RABToBeSetupItemBearerSUReq CRITICALITY reject TYPE E-RABToBeSetupItemBearerSUReq PRESENCE mandatory },
+ ...
+}
+
+E-RABToBeSetupItemBearerSUReq ::= SEQUENCE {
+ e-RAB-ID E-RAB-ID,
+ e-RABlevelQoSParameters E-RABLevelQoSParameters,
+ transportLayerAddress TransportLayerAddress,
+ gTP-TEID GTP-TEID,
+ nAS-PDU NAS-PDU,
+ iE-Extensions ProtocolExtensionContainer { {E-RABToBeSetupItemBearerSUReqExtIEs} } OPTIONAL,
+ ...
+}
+
+
+E-RABToBeSetupItemBearerSUReqExtIEs S1AP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+
+-- **************************************************************
+--
+-- E-RAB Setup Response
+--
+-- **************************************************************
+
+E-RABSetupResponse ::= SEQUENCE {
+ protocolIEs ProtocolIE-Container { {E-RABSetupResponseIEs} },
+ ...
+}
+
+E-RABSetupResponseIEs S1AP-PROTOCOL-IES ::= {
+ { ID id-MME-UE-S1AP-ID CRITICALITY ignore TYPE MME-UE-S1AP-ID PRESENCE mandatory }|
+ { ID id-eNB-UE-S1AP-ID CRITICALITY ignore TYPE ENB-UE-S1AP-ID PRESENCE mandatory }|
+ { ID id-E-RABSetupListBearerSURes CRITICALITY ignore TYPE E-RABSetupListBearerSURes PRESENCE optional }|
+ { ID id-E-RABFailedToSetupListBearerSURes CRITICALITY ignore TYPE E-RABList PRESENCE optional }|
+ { ID id-CriticalityDiagnostics CRITICALITY ignore TYPE CriticalityDiagnostics PRESENCE optional },
+ ...
+}
+
+
+E-RABSetupListBearerSURes ::= SEQUENCE (SIZE(1.. maxNrOfE-RABs)) OF ProtocolIE-SingleContainer { {E-RABSetupItemBearerSUResIEs} }
+
+E-RABSetupItemBearerSUResIEs S1AP-PROTOCOL-IES ::= {
+ { ID id-E-RABSetupItemBearerSURes CRITICALITY ignore TYPE E-RABSetupItemBearerSURes PRESENCE mandatory },
+ ...
+}
+
+E-RABSetupItemBearerSURes ::= SEQUENCE {
+ e-RAB-ID E-RAB-ID,
+ transportLayerAddress TransportLayerAddress,
+ gTP-TEID GTP-TEID,
+ iE-Extensions ProtocolExtensionContainer { {E-RABSetupItemBearerSUResExtIEs} } OPTIONAL,
+ ...
+}
+
+
+E-RABSetupItemBearerSUResExtIEs S1AP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+
+
+-- **************************************************************
+--
+-- E-RAB MODIFY ELEMENTARY PROCEDURE
+--
+-- **************************************************************
+
+-- **************************************************************
+--
+-- E-RAB Modify Request
+--
+-- **************************************************************
+
+E-RABModifyRequest ::= SEQUENCE {
+ protocolIEs ProtocolIE-Container { {E-RABModifyRequestIEs} },
+ ...
+}
+
+E-RABModifyRequestIEs S1AP-PROTOCOL-IES ::= {
+ { ID id-MME-UE-S1AP-ID CRITICALITY reject TYPE MME-UE-S1AP-ID PRESENCE mandatory }|
+ { ID id-eNB-UE-S1AP-ID CRITICALITY reject TYPE ENB-UE-S1AP-ID PRESENCE mandatory }|
+ { ID id-uEaggregateMaximumBitrate CRITICALITY reject TYPE UEAggregateMaximumBitrate PRESENCE optional }|
+ { ID id-E-RABToBeModifiedListBearerModReq CRITICALITY reject TYPE E-RABToBeModifiedListBearerModReq PRESENCE mandatory },
+ ...
+}
+
+E-RABToBeModifiedListBearerModReq ::= SEQUENCE (SIZE(1.. maxNrOfE-RABs)) OF ProtocolIE-SingleContainer { {E-RABToBeModifiedItemBearerModReqIEs} }
+
+E-RABToBeModifiedItemBearerModReqIEs S1AP-PROTOCOL-IES ::= {
+ { ID id-E-RABToBeModifiedItemBearerModReq CRITICALITY reject TYPE E-RABToBeModifiedItemBearerModReq PRESENCE mandatory },
+ ...
+}
+
+E-RABToBeModifiedItemBearerModReq ::= SEQUENCE {
+ e-RAB-ID E-RAB-ID,
+ e-RABLevelQoSParameters E-RABLevelQoSParameters,
+ nAS-PDU NAS-PDU,
+ iE-Extensions ProtocolExtensionContainer { {E-RABToBeModifyItemBearerModReqExtIEs} } OPTIONAL,
+ ...
+}
+
+
+E-RABToBeModifyItemBearerModReqExtIEs S1AP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+
+
+-- **************************************************************
+--
+-- E-RAB Modify Response
+--
+-- **************************************************************
+
+E-RABModifyResponse ::= SEQUENCE {
+ protocolIEs ProtocolIE-Container { {E-RABModifyResponseIEs} },
+ ...
+}
+
+E-RABModifyResponseIEs S1AP-PROTOCOL-IES ::= {
+ { ID id-MME-UE-S1AP-ID CRITICALITY ignore TYPE MME-UE-S1AP-ID PRESENCE mandatory }|
+ { ID id-eNB-UE-S1AP-ID CRITICALITY ignore TYPE ENB-UE-S1AP-ID PRESENCE mandatory }|
+ { ID id-E-RABModifyListBearerModRes CRITICALITY ignore TYPE E-RABModifyListBearerModRes PRESENCE optional }|
+ { ID id-E-RABFailedToModifyList CRITICALITY ignore TYPE E-RABList PRESENCE optional }|
+ { ID id-CriticalityDiagnostics CRITICALITY ignore TYPE CriticalityDiagnostics PRESENCE optional },
+ ...
+}
+
+
+E-RABModifyListBearerModRes ::= SEQUENCE (SIZE(1.. maxNrOfE-RABs)) OF ProtocolIE-SingleContainer { {E-RABModifyItemBearerModResIEs} }
+
+E-RABModifyItemBearerModResIEs S1AP-PROTOCOL-IES ::= {
+ { ID id-E-RABModifyItemBearerModRes CRITICALITY ignore TYPE E-RABModifyItemBearerModRes PRESENCE mandatory },
+ ...
+}
+
+E-RABModifyItemBearerModRes ::= SEQUENCE {
+ e-RAB-ID E-RAB-ID,
+ iE-Extensions ProtocolExtensionContainer { {E-RABModifyItemBearerModResExtIEs} } OPTIONAL,
+ ...
+}
+
+
+E-RABModifyItemBearerModResExtIEs S1AP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+
+
+
+-- **************************************************************
+--
+-- E-RAB RELEASE ELEMENTARY PROCEDURE
+--
+-- **************************************************************
+
+-- **************************************************************
+--
+-- E-RAB Release Command
+--
+-- **************************************************************
+
+E-RABReleaseCommand ::= SEQUENCE {
+ protocolIEs ProtocolIE-Container { {E-RABReleaseCommandIEs} },
+ ...
+}
+
+E-RABReleaseCommandIEs S1AP-PROTOCOL-IES ::= {
+ { ID id-MME-UE-S1AP-ID CRITICALITY reject TYPE MME-UE-S1AP-ID PRESENCE mandatory }|
+ { ID id-eNB-UE-S1AP-ID CRITICALITY reject TYPE ENB-UE-S1AP-ID PRESENCE mandatory }|
+ { ID id-uEaggregateMaximumBitrate CRITICALITY reject TYPE UEAggregateMaximumBitrate PRESENCE optional }|
+ { ID id-E-RABToBeReleasedList CRITICALITY ignore TYPE E-RABList PRESENCE mandatory }|
+ { ID id-NAS-PDU CRITICALITY ignore TYPE NAS-PDU PRESENCE optional },
+ ...
+}
+
+
+-- **************************************************************
+--
+-- E-RAB Release Response
+--
+-- **************************************************************
+
+E-RABReleaseResponse ::= SEQUENCE {
+ protocolIEs ProtocolIE-Container { { E-RABReleaseResponseIEs } },
+ ...
+}
+
+E-RABReleaseResponseIEs S1AP-PROTOCOL-IES ::= {
+ { ID id-MME-UE-S1AP-ID CRITICALITY ignore TYPE MME-UE-S1AP-ID PRESENCE mandatory }|
+ { ID id-eNB-UE-S1AP-ID CRITICALITY ignore TYPE ENB-UE-S1AP-ID PRESENCE mandatory }|
+ { ID id-E-RABReleaseListBearerRelComp CRITICALITY ignore TYPE E-RABReleaseListBearerRelComp PRESENCE optional }|
+ { ID id-E-RABFailedToReleaseList CRITICALITY ignore TYPE E-RABList PRESENCE optional }|
+ { ID id-CriticalityDiagnostics CRITICALITY ignore TYPE CriticalityDiagnostics PRESENCE optional },
+ ...
+}
+
+
+E-RABReleaseListBearerRelComp ::= SEQUENCE (SIZE(1.. maxNrOfE-RABs)) OF ProtocolIE-SingleContainer { {E-RABReleaseItemBearerRelCompIEs} }
+
+E-RABReleaseItemBearerRelCompIEs S1AP-PROTOCOL-IES ::= {
+ { ID id-E-RABReleaseItemBearerRelComp CRITICALITY ignore TYPE E-RABReleaseItemBearerRelComp PRESENCE mandatory },
+ ...
+}
+
+E-RABReleaseItemBearerRelComp ::= SEQUENCE {
+ e-RAB-ID E-RAB-ID,
+ iE-Extensions ProtocolExtensionContainer { {E-RABReleaseItemBearerRelCompExtIEs} } OPTIONAL,
+ ...
+}
+
+
+E-RABReleaseItemBearerRelCompExtIEs S1AP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+
+
+-- **************************************************************
+--
+-- E-RAB RELEASE INDICATION ELEMENTARY PROCEDURE
+--
+-- **************************************************************
+
+-- **************************************************************
+--
+-- E-RAB Release Indication
+--
+-- **************************************************************
+
+E-RABReleaseIndication ::= SEQUENCE {
+ protocolIEs ProtocolIE-Container { {E-RABReleaseIndicationIEs} },
+ ...
+}
+
+E-RABReleaseIndicationIEs S1AP-PROTOCOL-IES ::= {
+ { ID id-MME-UE-S1AP-ID CRITICALITY reject TYPE MME-UE-S1AP-ID PRESENCE mandatory }|
+ { ID id-eNB-UE-S1AP-ID CRITICALITY reject TYPE ENB-UE-S1AP-ID PRESENCE mandatory }|
+ { ID id-E-RABReleasedList CRITICALITY ignore TYPE E-RABList PRESENCE mandatory },
+ ...
+}
+-- **************************************************************
+--
+-- INITIAL CONTEXT SETUP ELEMENTARY PROCEDURE
+--
+-- **************************************************************
+
+-- **************************************************************
+--
+-- Initial Context Setup Request
+--
+-- **************************************************************
+
+InitialContextSetupRequest ::= SEQUENCE {
+ protocolIEs ProtocolIE-Container { {InitialContextSetupRequestIEs} },
+ ...
+}
+
+InitialContextSetupRequestIEs S1AP-PROTOCOL-IES ::= {
+ { ID id-MME-UE-S1AP-ID CRITICALITY reject TYPE MME-UE-S1AP-ID PRESENCE mandatory }|
+ { ID id-eNB-UE-S1AP-ID CRITICALITY reject TYPE ENB-UE-S1AP-ID PRESENCE mandatory }|
+ { ID id-uEaggregateMaximumBitrate CRITICALITY reject TYPE UEAggregateMaximumBitrate PRESENCE mandatory }|
+ { ID id-E-RABToBeSetupListCtxtSUReq CRITICALITY reject TYPE E-RABToBeSetupListCtxtSUReq PRESENCE mandatory }|
+ { ID id-UESecurityCapabilities CRITICALITY reject TYPE UESecurityCapabilities PRESENCE mandatory }|
+ { ID id-SecurityKey CRITICALITY reject TYPE SecurityKey PRESENCE mandatory }|
+ { ID id-TraceActivation CRITICALITY ignore TYPE TraceActivation PRESENCE optional }|
+ { ID id-HandoverRestrictionList CRITICALITY ignore TYPE HandoverRestrictionList PRESENCE optional }|
+ { ID id-UERadioCapability CRITICALITY ignore TYPE UERadioCapability PRESENCE optional }|
+ { ID id-SubscriberProfileIDforRFP CRITICALITY ignore TYPE SubscriberProfileIDforRFP PRESENCE optional }|
+ { ID id-CSFallbackIndicator CRITICALITY reject TYPE CSFallbackIndicator PRESENCE optional }|
+ { ID id-SRVCCOperationPossible CRITICALITY ignore TYPE SRVCCOperationPossible PRESENCE optional },
+ ...
+}
+
+
+
+
+E-RABToBeSetupListCtxtSUReq ::= SEQUENCE (SIZE(1.. maxNrOfE-RABs)) OF ProtocolIE-SingleContainer { {E-RABToBeSetupItemCtxtSUReqIEs} }
+
+E-RABToBeSetupItemCtxtSUReqIEs S1AP-PROTOCOL-IES ::= {
+ { ID id-E-RABToBeSetupItemCtxtSUReq CRITICALITY reject TYPE E-RABToBeSetupItemCtxtSUReq PRESENCE mandatory },
+ ...
+}
+
+E-RABToBeSetupItemCtxtSUReq ::= SEQUENCE {
+ e-RAB-ID E-RAB-ID,
+ e-RABlevelQoSParameters E-RABLevelQoSParameters,
+ transportLayerAddress TransportLayerAddress,
+ gTP-TEID GTP-TEID,
+ nAS-PDU NAS-PDU OPTIONAL,
+ iE-Extensions ProtocolExtensionContainer { {E-RABToBeSetupItemCtxtSUReqExtIEs} } OPTIONAL,
+ ...
+}
+
+
+E-RABToBeSetupItemCtxtSUReqExtIEs S1AP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+
+-- **************************************************************
+--
+-- Initial Context Setup Response
+--
+-- **************************************************************
+
+InitialContextSetupResponse ::= SEQUENCE {
+ protocolIEs ProtocolIE-Container { {InitialContextSetupResponseIEs} },
+ ...
+}
+
+InitialContextSetupResponseIEs S1AP-PROTOCOL-IES ::= {
+ { ID id-MME-UE-S1AP-ID CRITICALITY ignore TYPE MME-UE-S1AP-ID PRESENCE mandatory }|
+ { ID id-eNB-UE-S1AP-ID CRITICALITY ignore TYPE ENB-UE-S1AP-ID PRESENCE mandatory }|
+ { ID id-E-RABSetupListCtxtSURes CRITICALITY ignore TYPE E-RABSetupListCtxtSURes PRESENCE mandatory }|
+ { ID id-E-RABFailedToSetupListCtxtSURes CRITICALITY ignore TYPE E-RABList PRESENCE optional }|
+ { ID id-CriticalityDiagnostics CRITICALITY ignore TYPE CriticalityDiagnostics PRESENCE optional },
+ ...
+}
+
+
+E-RABSetupListCtxtSURes ::= SEQUENCE (SIZE(1.. maxNrOfE-RABs)) OF ProtocolIE-SingleContainer { {E-RABSetupItemCtxtSUResIEs} }
+
+E-RABSetupItemCtxtSUResIEs S1AP-PROTOCOL-IES ::= {
+ { ID id-E-RABSetupItemCtxtSURes CRITICALITY ignore TYPE E-RABSetupItemCtxtSURes PRESENCE mandatory },
+ ...
+}
+
+E-RABSetupItemCtxtSURes ::= SEQUENCE {
+ e-RAB-ID E-RAB-ID,
+ transportLayerAddress TransportLayerAddress,
+ gTP-TEID GTP-TEID,
+ iE-Extensions ProtocolExtensionContainer { {E-RABSetupItemCtxtSUResExtIEs} } OPTIONAL,
+ ...
+}
+
+
+E-RABSetupItemCtxtSUResExtIEs S1AP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+
+-- **************************************************************
+--
+-- Initial Context Setup Failure
+--
+-- **************************************************************
+
+InitialContextSetupFailure ::= SEQUENCE {
+ protocolIEs ProtocolIE-Container { {InitialContextSetupFailureIEs} },
+ ...
+}
+
+InitialContextSetupFailureIEs S1AP-PROTOCOL-IES ::= {
+ { ID id-MME-UE-S1AP-ID CRITICALITY ignore TYPE MME-UE-S1AP-ID PRESENCE mandatory }|
+ { ID id-eNB-UE-S1AP-ID CRITICALITY ignore TYPE ENB-UE-S1AP-ID PRESENCE mandatory }|
+ { ID id-Cause CRITICALITY ignore TYPE Cause PRESENCE mandatory }|
+ { ID id-CriticalityDiagnostics CRITICALITY ignore TYPE CriticalityDiagnostics PRESENCE optional },
+ ...
+}
+
+-- **************************************************************
+--
+-- PAGING ELEMENTARY PROCEDURE
+--
+-- **************************************************************
+
+
+-- **************************************************************
+--
+-- Paging
+--
+-- **************************************************************
+
+Paging ::= SEQUENCE {
+ protocolIEs ProtocolIE-Container {{PagingIEs}},
+ ...
+}
+
+PagingIEs S1AP-PROTOCOL-IES ::= {
+ { ID id-UEIdentityIndexValue CRITICALITY ignore TYPE UEIdentityIndexValue PRESENCE mandatory } |
+ { ID id-UEPagingID CRITICALITY ignore TYPE UEPagingID PRESENCE mandatory } |
+ { ID id-pagingDRX CRITICALITY ignore TYPE PagingDRX PRESENCE optional } |
+ { ID id-CNDomain CRITICALITY ignore TYPE CNDomain PRESENCE mandatory } |
+ { ID id-TAIList CRITICALITY ignore TYPE TAIList PRESENCE mandatory }|
+ { ID id-CSG-IdList CRITICALITY ignore TYPE CSG-IdList PRESENCE optional },
+ ...
+}
+
+TAIList::= SEQUENCE (SIZE(1.. maxnoofTAIs)) OF ProtocolIE-SingleContainer {{TAIItemIEs}}
+
+TAIItemIEs S1AP-PROTOCOL-IES ::= {
+ { ID id-TAIItem CRITICALITY ignore TYPE TAIItem PRESENCE mandatory },
+ ...
+}
+
+TAIItem ::= SEQUENCE {
+ tAI TAI,
+ iE-Extensions ProtocolExtensionContainer { {TAIItemExtIEs} } OPTIONAL,
+ ...
+}
+
+
+TAIItemExtIEs S1AP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+-- **************************************************************
+--
+-- UE CONTEXT RELEASE ELEMENTARY PROCEDURE
+--
+-- **************************************************************
+
+-- **************************************************************
+--
+-- UE CONTEXT RELEASE REQUEST
+--
+-- **************************************************************
+
+UEContextReleaseRequest ::= SEQUENCE {
+ protocolIEs ProtocolIE-Container {{UEContextReleaseRequest-IEs}},
+ ...
+}
+
+UEContextReleaseRequest-IEs S1AP-PROTOCOL-IES ::= {
+ { ID id-MME-UE-S1AP-ID CRITICALITY reject TYPE MME-UE-S1AP-ID PRESENCE mandatory} |
+ { ID id-eNB-UE-S1AP-ID CRITICALITY reject TYPE ENB-UE-S1AP-ID PRESENCE mandatory} |
+ { ID id-Cause CRITICALITY ignore TYPE Cause PRESENCE mandatory} ,
+ ...
+}
+
+-- **************************************************************
+--
+-- UE Context Release Command
+--
+-- **************************************************************
+
+UEContextReleaseCommand ::= SEQUENCE {
+ protocolIEs ProtocolIE-Container {{UEContextReleaseCommand-IEs}},
+ ...
+}
+
+UEContextReleaseCommand-IEs S1AP-PROTOCOL-IES ::= {
+ { ID id-UE-S1AP-IDs CRITICALITY reject TYPE UE-S1AP-IDs PRESENCE mandatory} |
+
+ { ID id-Cause CRITICALITY ignore TYPE Cause PRESENCE mandatory} ,
+ ...
+}
+
+-- **************************************************************
+--
+-- UE Context Release Complete
+--
+-- **************************************************************
+
+UEContextReleaseComplete ::= SEQUENCE {
+ protocolIEs ProtocolIE-Container {{UEContextReleaseComplete-IEs}},
+ ...
+}
+
+UEContextReleaseComplete-IEs S1AP-PROTOCOL-IES ::= {
+ { ID id-MME-UE-S1AP-ID CRITICALITY ignore TYPE MME-UE-S1AP-ID PRESENCE mandatory} |
+ { ID id-eNB-UE-S1AP-ID CRITICALITY ignore TYPE ENB-UE-S1AP-ID PRESENCE mandatory} |
+ { ID id-CriticalityDiagnostics CRITICALITY ignore TYPE CriticalityDiagnostics PRESENCE optional },
+ ...
+}
+
+
+-- **************************************************************
+--
+-- UE CONTEXT MODIFICATION ELEMENTARY PROCEDURE
+--
+-- **************************************************************
+
+-- **************************************************************
+--
+-- UE Context Modification Request
+--
+-- **************************************************************
+
+UEContextModificationRequest ::= SEQUENCE {
+ protocolIEs ProtocolIE-Container { { UEContextModificationRequestIEs} },
+ ...
+}
+
+UEContextModificationRequestIEs S1AP-PROTOCOL-IES ::= {
+ { ID id-MME-UE-S1AP-ID CRITICALITY reject TYPE MME-UE-S1AP-ID PRESENCE mandatory } |
+ { ID id-eNB-UE-S1AP-ID CRITICALITY reject TYPE ENB-UE-S1AP-ID PRESENCE mandatory } |
+ { ID id-SecurityKey CRITICALITY reject TYPE SecurityKey PRESENCE optional }|
+ { ID id-SubscriberProfileIDforRFP CRITICALITY ignore TYPE SubscriberProfileIDforRFP PRESENCE optional }|
+ { ID id-uEaggregateMaximumBitrate CRITICALITY ignore TYPE UEAggregateMaximumBitrate PRESENCE optional }|
+ { ID id-CSFallbackIndicator CRITICALITY reject TYPE CSFallbackIndicator PRESENCE optional },
+ ...
+}
+-- **************************************************************
+--
+-- UE Context Modification Response
+--
+-- **************************************************************
+
+UEContextModificationResponse ::= SEQUENCE {
+ protocolIEs ProtocolIE-Container { { UEContextModificationResponseIEs} },
+ ...
+}
+
+UEContextModificationResponseIEs S1AP-PROTOCOL-IES ::= {
+ { ID id-MME-UE-S1AP-ID CRITICALITY ignore TYPE MME-UE-S1AP-ID PRESENCE mandatory } |
+ { ID id-eNB-UE-S1AP-ID CRITICALITY ignore TYPE ENB-UE-S1AP-ID PRESENCE mandatory }|
+ { ID id-CriticalityDiagnostics CRITICALITY ignore TYPE CriticalityDiagnostics PRESENCE optional },
+ ...
+}-- **************************************************************
+--
+-- UE Context Modification Failure
+--
+-- **************************************************************
+
+UEContextModificationFailure ::= SEQUENCE {
+ protocolIEs ProtocolIE-Container { { UEContextModificationFailureIEs} },
+ ...
+}
+
+UEContextModificationFailureIEs S1AP-PROTOCOL-IES ::= {
+ { ID id-MME-UE-S1AP-ID CRITICALITY ignore TYPE MME-UE-S1AP-ID PRESENCE mandatory } |
+ { ID id-eNB-UE-S1AP-ID CRITICALITY ignore TYPE ENB-UE-S1AP-ID PRESENCE mandatory } |
+ { ID id-Cause CRITICALITY ignore TYPE Cause PRESENCE mandatory }|
+ { ID id-CriticalityDiagnostics CRITICALITY ignore TYPE CriticalityDiagnostics PRESENCE optional },
+ ...
+}
+
+-- **************************************************************
+--
+-- NAS TRANSPORT ELEMENTARY PROCEDURES
+--
+-- **************************************************************
+
+-- **************************************************************
+--
+-- DOWNLINK NAS TRANSPORT
+--
+-- **************************************************************
+
+DownlinkNASTransport ::= SEQUENCE {
+ protocolIEs ProtocolIE-Container {{DownlinkNASTransport-IEs}},
+ ...
+}
+
+DownlinkNASTransport-IEs S1AP-PROTOCOL-IES ::= {
+ { ID id-MME-UE-S1AP-ID CRITICALITY reject TYPE MME-UE-S1AP-ID PRESENCE mandatory} |
+ { ID id-eNB-UE-S1AP-ID CRITICALITY reject TYPE ENB-UE-S1AP-ID PRESENCE mandatory} |
+ { ID id-NAS-PDU CRITICALITY reject TYPE NAS-PDU PRESENCE mandatory} |
+ { ID id-HandoverRestrictionList CRITICALITY ignore TYPE HandoverRestrictionList PRESENCE optional },
+ ...
+}
+
+
+-- **************************************************************
+--
+-- INITIAL UE MESSAGE
+--
+-- **************************************************************
+
+InitialUEMessage ::= SEQUENCE {
+ protocolIEs ProtocolIE-Container {{InitialUEMessage-IEs}},
+ ...
+}
+
+InitialUEMessage-IEs S1AP-PROTOCOL-IES ::= {
+ { ID id-eNB-UE-S1AP-ID CRITICALITY reject TYPE ENB-UE-S1AP-ID PRESENCE mandatory} |
+ { ID id-NAS-PDU CRITICALITY reject TYPE NAS-PDU PRESENCE mandatory} |
+ { ID id-TAI CRITICALITY reject TYPE TAI PRESENCE mandatory} |
+ { ID id-EUTRAN-CGI CRITICALITY ignore TYPE EUTRAN-CGI PRESENCE mandatory} |
+ { ID id-RRC-Establishment-Cause CRITICALITY ignore TYPE RRC-Establishment-Cause PRESENCE mandatory} |
+ { ID id-S-TMSI CRITICALITY reject TYPE S-TMSI PRESENCE optional} |
+ { ID id-CSG-Id CRITICALITY reject TYPE CSG-Id PRESENCE optional} |
+ { ID id-GUMMEI-ID CRITICALITY reject TYPE GUMMEI PRESENCE optional},
+ ...
+}
+
+
+-- **************************************************************
+--
+-- UPLINK NAS TRANSPORT
+--
+-- **************************************************************
+
+UplinkNASTransport ::= SEQUENCE {
+ protocolIEs ProtocolIE-Container {{UplinkNASTransport-IEs}},
+ ...
+}
+
+UplinkNASTransport-IEs S1AP-PROTOCOL-IES ::= {
+ { ID id-MME-UE-S1AP-ID CRITICALITY reject TYPE MME-UE-S1AP-ID PRESENCE mandatory} |
+ { ID id-eNB-UE-S1AP-ID CRITICALITY reject TYPE ENB-UE-S1AP-ID PRESENCE mandatory} |
+ { ID id-NAS-PDU CRITICALITY reject TYPE NAS-PDU PRESENCE mandatory} |
+ { ID id-EUTRAN-CGI CRITICALITY ignore TYPE EUTRAN-CGI PRESENCE mandatory}|
+ { ID id-TAI CRITICALITY ignore TYPE TAI PRESENCE mandatory},
+ ...
+}
+-- **************************************************************
+--
+-- NAS NON DELIVERY INDICATION
+--
+-- **************************************************************
+
+NASNonDeliveryIndication ::= SEQUENCE {
+ protocolIEs ProtocolIE-Container {{NASNonDeliveryIndication-IEs}},
+ ...
+}
+
+NASNonDeliveryIndication-IEs S1AP-PROTOCOL-IES ::= {
+ { ID id-MME-UE-S1AP-ID CRITICALITY reject TYPE MME-UE-S1AP-ID PRESENCE mandatory} |
+ { ID id-eNB-UE-S1AP-ID CRITICALITY reject TYPE ENB-UE-S1AP-ID PRESENCE mandatory} |
+ { ID id-NAS-PDU CRITICALITY ignore TYPE NAS-PDU PRESENCE mandatory} |
+ { ID id-Cause CRITICALITY ignore TYPE Cause PRESENCE mandatory} ,
+ ...
+}
+
+-- **************************************************************
+--
+-- RESET ELEMENTARY PROCEDURE
+--
+-- **************************************************************
+
+-- **************************************************************
+--
+-- Reset
+--
+-- **************************************************************
+
+Reset ::= SEQUENCE {
+ protocolIEs ProtocolIE-Container { {ResetIEs} },
+ ...
+}
+
+ResetIEs S1AP-PROTOCOL-IES ::= {
+ { ID id-Cause CRITICALITY ignore TYPE Cause PRESENCE mandatory }|
+ { ID id-ResetType CRITICALITY reject TYPE ResetType PRESENCE mandatory },
+ ...
+}
+
+ResetType ::= CHOICE {
+ s1-Interface ResetAll,
+ partOfS1-Interface UE-associatedLogicalS1-ConnectionListRes,
+ ...
+}
+
+
+
+ResetAll ::= ENUMERATED {
+ reset-all,
+ ...
+}
+
+UE-associatedLogicalS1-ConnectionListRes ::= SEQUENCE (SIZE(1.. maxNrOfIndividualS1ConnectionsToReset)) OF ProtocolIE-SingleContainer { { UE-associatedLogicalS1-ConnectionItemRes } }
+
+UE-associatedLogicalS1-ConnectionItemRes S1AP-PROTOCOL-IES ::= {
+ { ID id-UE-associatedLogicalS1-ConnectionItem CRITICALITY reject TYPE UE-associatedLogicalS1-ConnectionItem PRESENCE mandatory },
+ ...
+}
+
+
+-- **************************************************************
+--
+-- Reset Acknowledge
+--
+-- **************************************************************
+
+ResetAcknowledge ::= SEQUENCE {
+ protocolIEs ProtocolIE-Container { {ResetAcknowledgeIEs} },
+ ...
+}
+
+ResetAcknowledgeIEs S1AP-PROTOCOL-IES ::= {
+ { ID id-UE-associatedLogicalS1-ConnectionListResAck CRITICALITY ignore TYPE UE-associatedLogicalS1-ConnectionListResAck PRESENCE optional }|
+ { ID id-CriticalityDiagnostics CRITICALITY ignore TYPE CriticalityDiagnostics PRESENCE optional },
+ ...
+}
+
+UE-associatedLogicalS1-ConnectionListResAck ::= SEQUENCE (SIZE(1.. maxNrOfIndividualS1ConnectionsToReset)) OF ProtocolIE-SingleContainer { { UE-associatedLogicalS1-ConnectionItemResAck } }
+
+UE-associatedLogicalS1-ConnectionItemResAck S1AP-PROTOCOL-IES ::= {
+ { ID id-UE-associatedLogicalS1-ConnectionItem CRITICALITY ignore TYPE UE-associatedLogicalS1-ConnectionItem PRESENCE mandatory },
+ ...
+}
+
+-- **************************************************************
+--
+-- ERROR INDICATION ELEMENTARY PROCEDURE
+--
+-- **************************************************************
+
+-- **************************************************************
+--
+-- Error Indication
+--
+-- **************************************************************
+
+ErrorIndication ::= SEQUENCE {
+ protocolIEs ProtocolIE-Container {{ErrorIndicationIEs}},
+ ...
+}
+
+ErrorIndicationIEs S1AP-PROTOCOL-IES ::= {
+ { ID id-MME-UE-S1AP-ID CRITICALITY ignore TYPE MME-UE-S1AP-ID PRESENCE optional } |
+ { ID id-eNB-UE-S1AP-ID CRITICALITY ignore TYPE ENB-UE-S1AP-ID PRESENCE optional } |
+ { ID id-Cause CRITICALITY ignore TYPE Cause PRESENCE optional } |
+ { ID id-CriticalityDiagnostics CRITICALITY ignore TYPE CriticalityDiagnostics PRESENCE optional } ,
+ ...
+}
+
+-- **************************************************************
+--
+-- S1 SETUP ELEMENTARY PROCEDURE
+--
+-- **************************************************************
+
+-- **************************************************************
+--
+-- S1 Setup Request
+--
+-- **************************************************************
+
+S1SetupRequest ::= SEQUENCE {
+ protocolIEs ProtocolIE-Container { {S1SetupRequestIEs} },
+ ...
+}
+
+S1SetupRequestIEs S1AP-PROTOCOL-IES ::= {
+ { ID id-Global-ENB-ID CRITICALITY reject TYPE Global-ENB-ID PRESENCE mandatory}|
+ { ID id-eNBname CRITICALITY ignore TYPE ENBname PRESENCE optional}|
+ { ID id-SupportedTAs CRITICALITY reject TYPE SupportedTAs PRESENCE mandatory}|
+ { ID id-DefaultPagingDRX CRITICALITY ignore TYPE PagingDRX PRESENCE mandatory}|
+ { ID id-CSG-IdList CRITICALITY reject TYPE CSG-IdList PRESENCE optional},
+ ...
+}
+
+-- **************************************************************
+--
+-- S1 Setup Response
+--
+-- **************************************************************
+
+S1SetupResponse ::= SEQUENCE {
+ protocolIEs ProtocolIE-Container { {S1SetupResponseIEs} },
+ ...
+}
+
+
+S1SetupResponseIEs S1AP-PROTOCOL-IES ::= {
+ { ID id-MMEname CRITICALITY ignore TYPE MMEname PRESENCE optional }|
+ { ID id-ServedGUMMEIs CRITICALITY reject TYPE ServedGUMMEIs PRESENCE mandatory }|
+ { ID id-RelativeMMECapacity CRITICALITY ignore TYPE RelativeMMECapacity PRESENCE mandatory }|
+ { ID id-CriticalityDiagnostics CRITICALITY ignore TYPE CriticalityDiagnostics PRESENCE optional },
+ ...
+}
+
+-- **************************************************************
+--
+-- S1 Setup Failure
+--
+-- **************************************************************
+
+S1SetupFailure ::= SEQUENCE {
+ protocolIEs ProtocolIE-Container { {S1SetupFailureIEs} },
+ ...
+}
+
+S1SetupFailureIEs S1AP-PROTOCOL-IES ::= {
+ { ID id-Cause CRITICALITY ignore TYPE Cause PRESENCE mandatory }|
+ { ID id-TimeToWait CRITICALITY ignore TYPE TimeToWait PRESENCE optional }|
+ { ID id-CriticalityDiagnostics CRITICALITY ignore TYPE CriticalityDiagnostics PRESENCE optional },
+ ...
+}
+
+-- **************************************************************
+--
+-- ENB CONFIGURATION UPDATE ELEMENTARY PROCEDURE
+--
+-- **************************************************************
+
+-- **************************************************************
+--
+-- eNB Configuration Update
+--
+-- **************************************************************
+
+ENBConfigurationUpdate ::= SEQUENCE {
+ protocolIEs ProtocolIE-Container { {ENBConfigurationUpdateIEs} },
+ ...
+}
+
+ENBConfigurationUpdateIEs S1AP-PROTOCOL-IES ::= {
+ { ID id-eNBname CRITICALITY ignore TYPE ENBname PRESENCE optional }|
+ { ID id-SupportedTAs CRITICALITY reject TYPE SupportedTAs PRESENCE optional }|
+ { ID id-CSG-IdList CRITICALITY reject TYPE CSG-IdList PRESENCE optional}|
+ { ID id-DefaultPagingDRX CRITICALITY ignore TYPE PagingDRX PRESENCE optional },
+ ...
+}
+
+-- **************************************************************
+--
+-- eNB Configuration Update Acknowledge
+--
+-- **************************************************************
+
+ENBConfigurationUpdateAcknowledge ::= SEQUENCE {
+ protocolIEs ProtocolIE-Container { {ENBConfigurationUpdateAcknowledgeIEs} },
+ ...
+}
+
+
+ENBConfigurationUpdateAcknowledgeIEs S1AP-PROTOCOL-IES ::= {
+ { ID id-CriticalityDiagnostics CRITICALITY ignore TYPE CriticalityDiagnostics PRESENCE optional },
+ ...
+}
+
+-- **************************************************************
+--
+-- eNB Configuration Update Failure
+--
+-- **************************************************************
+
+ENBConfigurationUpdateFailure ::= SEQUENCE {
+ protocolIEs ProtocolIE-Container { {ENBConfigurationUpdateFailureIEs} },
+ ...
+}
+
+ENBConfigurationUpdateFailureIEs S1AP-PROTOCOL-IES ::= {
+ { ID id-Cause CRITICALITY ignore TYPE Cause PRESENCE mandatory }|
+ { ID id-TimeToWait CRITICALITY ignore TYPE TimeToWait PRESENCE optional }|
+ { ID id-CriticalityDiagnostics CRITICALITY ignore TYPE CriticalityDiagnostics PRESENCE optional },
+...
+}
+
+
+-- **************************************************************
+--
+-- MME Configuration UPDATE ELEMENTARY PROCEDURE
+--
+-- **************************************************************
+
+-- **************************************************************
+--
+-- MME Configuration Update
+--
+-- **************************************************************
+
+MMEConfigurationUpdate ::= SEQUENCE {
+ protocolIEs ProtocolIE-Container { {MMEConfigurationUpdateIEs} },
+ ...
+}
+
+MMEConfigurationUpdateIEs S1AP-PROTOCOL-IES ::= {
+ { ID id-MMEname CRITICALITY ignore TYPE MMEname PRESENCE optional }|
+ { ID id-ServedGUMMEIs CRITICALITY reject TYPE ServedGUMMEIs PRESENCE optional }|
+ { ID id-RelativeMMECapacity CRITICALITY reject TYPE RelativeMMECapacity PRESENCE optional},
+ ...
+}
+
+-- **************************************************************
+--
+-- MME Configuration Update Acknowledge
+--
+-- **************************************************************
+
+MMEConfigurationUpdateAcknowledge ::= SEQUENCE {
+ protocolIEs ProtocolIE-Container { {MMEConfigurationUpdateAcknowledgeIEs} },
+ ...
+}
+
+
+MMEConfigurationUpdateAcknowledgeIEs S1AP-PROTOCOL-IES ::= {
+ { ID id-CriticalityDiagnostics CRITICALITY ignore TYPE CriticalityDiagnostics PRESENCE optional },
+ ...
+}
+
+-- **************************************************************
+--
+-- MME Configuration Update Failure
+--
+-- **************************************************************
+
+MMEConfigurationUpdateFailure ::= SEQUENCE {
+ protocolIEs ProtocolIE-Container { {MMEConfigurationUpdateFailureIEs} },
+ ...
+}
+
+MMEConfigurationUpdateFailureIEs S1AP-PROTOCOL-IES ::= {
+ { ID id-Cause CRITICALITY ignore TYPE Cause PRESENCE mandatory }|
+ { ID id-TimeToWait CRITICALITY ignore TYPE TimeToWait PRESENCE optional }|
+ { ID id-CriticalityDiagnostics CRITICALITY ignore TYPE CriticalityDiagnostics PRESENCE optional },
+ ...
+}
+
+-- **************************************************************
+--
+-- DOWNLINK S1 CDMA2000 TUNNELING ELEMENTARY PROCEDURE
+--
+-- **************************************************************
+
+-- **************************************************************
+--
+-- Downlink S1 CDMA2000 Tunneling
+--
+-- **************************************************************
+
+DownlinkS1cdma2000tunneling ::= SEQUENCE {
+ protocolIEs ProtocolIE-Container { {DownlinkS1cdma2000tunnelingIEs} },
+ ...
+}
+
+DownlinkS1cdma2000tunnelingIEs S1AP-PROTOCOL-IES ::= {
+ { ID id-MME-UE-S1AP-ID CRITICALITY reject TYPE MME-UE-S1AP-ID PRESENCE mandatory } |
+ { ID id-eNB-UE-S1AP-ID CRITICALITY reject TYPE ENB-UE-S1AP-ID PRESENCE mandatory } |
+ { ID id-E-RABSubjecttoDataForwardingList CRITICALITY ignore TYPE E-RABSubjecttoDataForwardingList PRESENCE optional } |
+ { ID id-cdma2000HOStatus CRITICALITY ignore TYPE Cdma2000HOStatus PRESENCE optional } |
+ { ID id-cdma2000RATType CRITICALITY reject TYPE Cdma2000RATType PRESENCE mandatory } |
+ { ID id-cdma2000PDU CRITICALITY reject TYPE Cdma2000PDU PRESENCE mandatory },
+ ...
+}
+
+-- **************************************************************
+--
+-- UPLINK S1 CDMA2000 TUNNELING ELEMENTARY PROCEDURE
+--
+-- **************************************************************
+
+-- **************************************************************
+--
+-- Uplink S1 CDMA2000 Tunneling
+--
+-- **************************************************************
+
+UplinkS1cdma2000tunneling ::= SEQUENCE {
+ protocolIEs ProtocolIE-Container { {UplinkS1cdma2000tunnelingIEs} },
+ ...
+}
+
+UplinkS1cdma2000tunnelingIEs S1AP-PROTOCOL-IES ::= {
+ { ID id-MME-UE-S1AP-ID CRITICALITY reject TYPE MME-UE-S1AP-ID PRESENCE mandatory } |
+ { ID id-eNB-UE-S1AP-ID CRITICALITY reject TYPE ENB-UE-S1AP-ID PRESENCE mandatory } |
+ { ID id-cdma2000RATType CRITICALITY reject TYPE Cdma2000RATType PRESENCE mandatory } |
+ { ID id-cdma2000SectorID CRITICALITY reject TYPE Cdma2000SectorID PRESENCE mandatory } |
+ { ID id-cdma2000HORequiredIndication CRITICALITY ignore TYPE Cdma2000HORequiredIndication PRESENCE optional } |
+ { ID id-cdma2000OneXSRVCCInfo CRITICALITY reject TYPE Cdma2000OneXSRVCCInfo PRESENCE optional } |
+ { ID id-cdma2000OneXRAND CRITICALITY reject TYPE Cdma2000OneXRAND PRESENCE optional } |
+ { ID id-cdma2000PDU CRITICALITY reject TYPE Cdma2000PDU PRESENCE mandatory },
+ ...
+}
+
+-- **************************************************************
+--
+-- UE CAPABILITY INFO INDICATION ELEMENTARY PROCEDURE
+--
+-- **************************************************************
+
+-- **************************************************************
+--
+-- UE Capability Info Indication
+--
+-- **************************************************************
+
+UECapabilityInfoIndication ::= SEQUENCE {
+ protocolIEs ProtocolIE-Container { { UECapabilityInfoIndicationIEs} },
+ ...
+}
+
+UECapabilityInfoIndicationIEs S1AP-PROTOCOL-IES ::= {
+ { ID id-MME-UE-S1AP-ID CRITICALITY reject TYPE MME-UE-S1AP-ID PRESENCE mandatory } |
+ { ID id-eNB-UE-S1AP-ID CRITICALITY reject TYPE ENB-UE-S1AP-ID PRESENCE mandatory } |
+ { ID id-UERadioCapability CRITICALITY ignore TYPE UERadioCapability PRESENCE mandatory } ,
+ ...
+}
+
+-- **************************************************************
+--
+-- eNB STATUS TRANSFER ELEMENTARY PROCEDURE
+--
+-- **************************************************************
+
+-- **************************************************************
+--
+-- eNB Status Transfer
+--
+-- **************************************************************
+
+ENBStatusTransfer ::= SEQUENCE {
+ protocolIEs ProtocolIE-Container { {ENBStatusTransferIEs} },
+ ...
+}
+
+ENBStatusTransferIEs S1AP-PROTOCOL-IES ::= {
+ { ID id-MME-UE-S1AP-ID CRITICALITY reject TYPE MME-UE-S1AP-ID PRESENCE mandatory} |
+ { ID id-eNB-UE-S1AP-ID CRITICALITY reject TYPE ENB-UE-S1AP-ID PRESENCE mandatory} |
+ { ID id-eNB-StatusTransfer-TransparentContainer CRITICALITY reject TYPE ENB-StatusTransfer-TransparentContainer PRESENCE mandatory} ,
+ ...
+}
+
+
+-- **************************************************************
+--
+-- MME STATUS TRANSFER ELEMENTARY PROCEDURE
+--
+-- **************************************************************
+
+-- **************************************************************
+--
+-- MME Status Transfer
+--
+-- **************************************************************
+
+MMEStatusTransfer ::= SEQUENCE {
+ protocolIEs ProtocolIE-Container { {MMEStatusTransferIEs} },
+ ...
+}
+
+MMEStatusTransferIEs S1AP-PROTOCOL-IES ::= {
+ { ID id-MME-UE-S1AP-ID CRITICALITY reject TYPE MME-UE-S1AP-ID PRESENCE mandatory} |
+ { ID id-eNB-UE-S1AP-ID CRITICALITY reject TYPE ENB-UE-S1AP-ID PRESENCE mandatory} |
+ { ID id-eNB-StatusTransfer-TransparentContainer CRITICALITY reject TYPE ENB-StatusTransfer-TransparentContainer PRESENCE mandatory} ,
+ ...
+}
+
+
+-- **************************************************************
+--
+-- TRACE ELEMENTARY PROCEDURES
+--
+-- **************************************************************
+-- **************************************************************
+--
+-- Trace Start
+--
+-- **************************************************************
+
+TraceStart ::= SEQUENCE {
+ protocolIEs ProtocolIE-Container { {TraceStartIEs} },
+ ...
+}
+
+TraceStartIEs S1AP-PROTOCOL-IES ::= {
+ { ID id-MME-UE-S1AP-ID CRITICALITY reject TYPE MME-UE-S1AP-ID PRESENCE mandatory} |
+ { ID id-eNB-UE-S1AP-ID CRITICALITY reject TYPE ENB-UE-S1AP-ID PRESENCE mandatory} |
+ { ID id-TraceActivation CRITICALITY ignore TYPE TraceActivation PRESENCE mandatory },
+ ...
+}
+
+-- **************************************************************
+--
+-- Trace Failure Indication
+--
+-- **************************************************************
+
+TraceFailureIndication ::= SEQUENCE {
+ protocolIEs ProtocolIE-Container { {TraceFailureIndicationIEs} },
+ ...
+}
+
+TraceFailureIndicationIEs S1AP-PROTOCOL-IES ::= {
+ { ID id-MME-UE-S1AP-ID CRITICALITY reject TYPE MME-UE-S1AP-ID PRESENCE mandatory} |
+ { ID id-eNB-UE-S1AP-ID CRITICALITY reject TYPE ENB-UE-S1AP-ID PRESENCE mandatory} |
+ { ID id-E-UTRAN-Trace-ID CRITICALITY ignore TYPE E-UTRAN-Trace-ID PRESENCE mandatory} |
+ { ID id-Cause CRITICALITY ignore TYPE Cause PRESENCE mandatory} ,
+ ...
+}
+
+-- **************************************************************
+--
+-- DEACTIVATE TRACE ELEMENTARY PROCEDURE
+--
+-- **************************************************************
+
+-- **************************************************************
+--
+-- DEACTIVATE TRACE
+--
+-- **************************************************************
+
+DeactivateTrace ::= SEQUENCE {
+ protocolIEs ProtocolIE-Container { { DeactivateTraceIEs} },
+ ...
+}
+
+DeactivateTraceIEs S1AP-PROTOCOL-IES ::= {
+ { ID id-MME-UE-S1AP-ID CRITICALITY reject TYPE MME-UE-S1AP-ID PRESENCE mandatory} |
+ { ID id-eNB-UE-S1AP-ID CRITICALITY reject TYPE ENB-UE-S1AP-ID PRESENCE mandatory} |
+ { ID id-E-UTRAN-Trace-ID CRITICALITY ignore TYPE E-UTRAN-Trace-ID PRESENCE mandatory },
+ ...
+}
+
+-- **************************************************************
+--
+-- CELL TRAFFIC TRACE ELEMENTARY PROCEDURE
+--
+-- **************************************************************
+
+-- **************************************************************
+--
+-- CELL TRAFFIC TRACE
+--
+-- **************************************************************
+
+CellTrafficTrace ::= SEQUENCE {
+protocolIEs ProtocolIE-Container { { CellTrafficTraceIEs } },
+...
+}
+
+CellTrafficTraceIEs S1AP-PROTOCOL-IES ::= {
+ {ID id-MME-UE-S1AP-ID CRITICALITY reject TYPE MME-UE-S1AP-ID PRESENCE mandatory} |
+ {ID id-eNB-UE-S1AP-ID CRITICALITY reject TYPE ENB-UE-S1AP-ID PRESENCE mandatory} |
+ {ID id-E-UTRAN-Trace-ID CRITICALITY ignore TYPE E-UTRAN-Trace-ID PRESENCE mandatory}|
+ {ID id-EUTRAN-CGI CRITICALITY ignore TYPE EUTRAN-CGI PRESENCE mandatory}|
+ {ID id-TraceCollectionEntityIPAddress CRITICALITY ignore TYPE TransportLayerAddress PRESENCE mandatory },
+ ...
+}
+
+-- **************************************************************
+--
+-- LOCATION ELEMENTARY PROCEDURES
+--
+-- **************************************************************
+
+-- **************************************************************
+--
+-- Location Reporting Control
+--
+-- **************************************************************
+
+LocationReportingControl ::= SEQUENCE {
+ protocolIEs ProtocolIE-Container { { LocationReportingControlIEs} },
+ ...
+}
+
+LocationReportingControlIEs S1AP-PROTOCOL-IES ::= {
+ { ID id-MME-UE-S1AP-ID CRITICALITY reject TYPE MME-UE-S1AP-ID PRESENCE mandatory} |
+ { ID id-eNB-UE-S1AP-ID CRITICALITY reject TYPE ENB-UE-S1AP-ID PRESENCE mandatory} |
+ { ID id-RequestType CRITICALITY ignore TYPE RequestType PRESENCE mandatory } ,
+ ...
+}
+
+-- **************************************************************
+--
+-- Location Report Failure Indication
+--
+-- **************************************************************
+
+LocationReportingFailureIndication ::= SEQUENCE {
+ protocolIEs ProtocolIE-Container { { LocationReportingFailureIndicationIEs} },
+ ...
+}
+
+LocationReportingFailureIndicationIEs S1AP-PROTOCOL-IES ::= {
+ { ID id-MME-UE-S1AP-ID CRITICALITY reject TYPE MME-UE-S1AP-ID PRESENCE mandatory} |
+ { ID id-eNB-UE-S1AP-ID CRITICALITY reject TYPE ENB-UE-S1AP-ID PRESENCE mandatory} |
+ { ID id-Cause CRITICALITY ignore TYPE Cause PRESENCE mandatory},
+ ...
+}
+
+-- **************************************************************
+--
+-- Location Report
+--
+-- **************************************************************
+
+LocationReport ::= SEQUENCE {
+ protocolIEs ProtocolIE-Container { { LocationReportIEs} },
+ ...
+}
+
+LocationReportIEs S1AP-PROTOCOL-IES ::= {
+ { ID id-MME-UE-S1AP-ID CRITICALITY reject TYPE MME-UE-S1AP-ID PRESENCE mandatory} |
+ { ID id-eNB-UE-S1AP-ID CRITICALITY reject TYPE ENB-UE-S1AP-ID PRESENCE mandatory} |
+ { ID id-EUTRAN-CGI CRITICALITY ignore TYPE EUTRAN-CGI PRESENCE mandatory} |
+ { ID id-TAI CRITICALITY ignore TYPE TAI PRESENCE mandatory} |
+ { ID id-RequestType CRITICALITY ignore TYPE RequestType PRESENCE mandatory} ,
+ ...
+}
+
+-- **************************************************************
+--
+-- OVERLOAD ELEMENTARY PROCEDURES
+--
+-- **************************************************************
+
+-- **************************************************************
+--
+-- Overload Start
+--
+-- **************************************************************
+
+OverloadStart ::= SEQUENCE {
+ protocolIEs ProtocolIE-Container { {OverloadStartIEs} },
+ ...
+}
+
+OverloadStartIEs S1AP-PROTOCOL-IES ::= {
+ { ID id-OverloadResponse CRITICALITY reject TYPE OverloadResponse PRESENCE mandatory },
+ ...
+}
+-- **************************************************************
+--
+-- Overload Stop
+--
+-- **************************************************************
+
+OverloadStop ::= SEQUENCE {
+ protocolIEs ProtocolIE-Container { {OverloadStopIEs} },
+ ...
+}
+
+OverloadStopIEs S1AP-PROTOCOL-IES ::= {
+ ...
+}
+-- **************************************************************
+--
+-- WRITE-REPLACE WARNING ELEMENTARY PROCEDURE
+--
+-- **************************************************************
+
+-- **************************************************************
+--
+-- Write-Replace Warning Request
+--
+-- **************************************************************
+
+
+WriteReplaceWarningRequest ::= SEQUENCE {
+ protocolIEs ProtocolIE-Container { {WriteReplaceWarningRequestIEs} },
+ ...
+}
+
+WriteReplaceWarningRequestIEs S1AP-PROTOCOL-IES ::= {
+ { ID id-MessageIdentifier CRITICALITY reject TYPE MessageIdentifier PRESENCE mandatory }|
+ { ID id-SerialNumber CRITICALITY reject TYPE SerialNumber PRESENCE mandatory }|
+ { ID id-WarningAreaList CRITICALITY ignore TYPE WarningAreaList PRESENCE optional }|
+ { ID id-RepetitionPeriod CRITICALITY reject TYPE RepetitionPeriod PRESENCE mandatory }|
+ { ID id-NumberofBroadcastRequest CRITICALITY reject TYPE NumberofBroadcastRequest PRESENCE mandatory }|
+ { ID id-WarningType CRITICALITY ignore TYPE WarningType PRESENCE optional }|
+ { ID id-WarningSecurityInfo CRITICALITY ignore TYPE WarningSecurityInfo PRESENCE optional }|
+ { ID id-DataCodingScheme CRITICALITY ignore TYPE DataCodingScheme PRESENCE optional }|
+ { ID id-WarningMessageContents CRITICALITY ignore TYPE WarningMessageContents PRESENCE optional },
+ ...
+}
+-- **************************************************************
+--
+-- Write-Replace Warning Response
+--
+-- **************************************************************
+
+WriteReplaceWarningResponse ::= SEQUENCE {
+ protocolIEs ProtocolIE-Container { {WriteReplaceWarningResponseIEs} },
+ ...
+}
+
+WriteReplaceWarningResponseIEs S1AP-PROTOCOL-IES ::= {
+ { ID id-MessageIdentifier CRITICALITY reject TYPE MessageIdentifier PRESENCE mandatory }|
+ { ID id-SerialNumber CRITICALITY reject TYPE SerialNumber PRESENCE mandatory }|
+ { ID id-BroadcastCompletedAreaList CRITICALITY reject TYPE BroadcastCompletedAreaList PRESENCE mandatory }|
+ { ID id-CriticalityDiagnostics CRITICALITY ignore TYPE CriticalityDiagnostics PRESENCE optional},
+ ...
+}
+
+-- **************************************************************
+--
+-- eNB DIRECT INFORMATION TRANSFER ELEMENTARY PROCEDURE
+--
+-- **************************************************************
+
+-- **************************************************************
+--
+-- eNB Direct Information Transfer
+--
+-- **************************************************************
+
+ENBDirectInformationTransfer ::= SEQUENCE {
+ protocolIEs ProtocolIE-Container {{ ENBDirectInformationTransferIEs}},
+ ...
+}
+
+ENBDirectInformationTransferIEs S1AP-PROTOCOL-IES ::= {
+ { ID id-Inter-SystemInformationTransferTypeEDT CRITICALITY reject TYPE Inter-SystemInformationTransferType PRESENCE mandatory} ,
+ ...
+}
+
+Inter-SystemInformationTransferType ::= CHOICE {
+ rIMTransfer RIMTransfer,
+ ...
+}
+
+-- **************************************************************
+--
+-- MME DIRECT INFORMATION TRANSFER ELEMENTARY PROCEDURE
+--
+-- **************************************************************
+
+-- **************************************************************
+--
+-- MME Direct Information Transfer
+--
+-- **************************************************************
+
+MMEDirectInformationTransfer ::= SEQUENCE {
+ protocolIEs ProtocolIE-Container {{ MMEDirectInformationTransferIEs}},
+ ...
+}
+
+MMEDirectInformationTransferIEs S1AP-PROTOCOL-IES ::= {
+ { ID id-Inter-SystemInformationTransferTypeMDT CRITICALITY reject TYPE Inter-SystemInformationTransferType PRESENCE mandatory} ,
+ ...
+}
+-- **************************************************************
+--
+-- eNB CONFIGURATION TRANSFER ELEMENTARY PROCEDURE
+--
+-- **************************************************************
+
+-- **************************************************************
+--
+-- eNB Configuration Transfer
+--
+-- **************************************************************
+
+ENBConfigurationTransfer ::= SEQUENCE {
+ protocolIEs ProtocolIE-Container {{ ENBConfigurationTransferIEs}},
+ ...
+}
+
+ENBConfigurationTransferIEs S1AP-PROTOCOL-IES ::= {
+ { ID id-SONConfigurationTransferECT CRITICALITY ignore TYPE SONConfigurationTransfer PRESENCE optional} ,
+ ...
+}
+
+-- **************************************************************
+--
+-- MME CONFIGURATION TRANSFER ELEMENTARY PROCEDURE
+--
+-- **************************************************************
+
+-- **************************************************************
+--
+-- MME Configuration Transfer
+--
+-- **************************************************************
+
+MMEConfigurationTransfer ::= SEQUENCE {
+ protocolIEs ProtocolIE-Container {{ MMEConfigurationTransferIEs}},
+ ...
+}
+
+MMEConfigurationTransferIEs S1AP-PROTOCOL-IES ::= {
+ { ID id-SONConfigurationTransferMCT CRITICALITY ignore TYPE SONConfigurationTransfer PRESENCE optional} ,
+ ...
+}
+
+-- **************************************************************
+--
+-- PRIVATE MESSAGE ELEMENTARY PROCEDURE
+--
+-- **************************************************************
+
+-- **************************************************************
+--
+-- Private Message
+--
+-- **************************************************************
+
+PrivateMessage ::= SEQUENCE {
+ privateIEs PrivateIE-Container {{PrivateMessageIEs}},
+ ...
+}
+
+PrivateMessageIEs S1AP-PRIVATE-IES ::= {
+ ...
+}
+
+END
diff --git a/lib/asn1/test/asn1_SUITE_data/S1AP-PDU-Descriptions.asn b/lib/asn1/test/asn1_SUITE_data/S1AP-PDU-Descriptions.asn
new file mode 100644
index 0000000000..46667cac2d
--- /dev/null
+++ b/lib/asn1/test/asn1_SUITE_data/S1AP-PDU-Descriptions.asn
@@ -0,0 +1,548 @@
+-- $Id$
+-- 3GPP TS 36.413 V8.6.1 (2009-06)
+-- 9.3.2 Elementary Procedure Definitions
+-- **************************************************************
+--
+-- Elementary Procedure definitions
+--
+-- **************************************************************
+
+S1AP-PDU-Descriptions {
+itu-t (0) identified-organization (4) etsi (0) mobileDomain (0)
+eps-Access (20) modules (3) s1ap (1) version1 (1) s1ap-PDU-Descriptions (0)}
+
+DEFINITIONS AUTOMATIC TAGS ::=
+
+BEGIN
+
+-- **************************************************************
+--
+-- IE parameter types from other modules.
+--
+-- **************************************************************
+
+IMPORTS
+ Criticality,
+ ProcedureCode
+FROM S1AP-CommonDataTypes
+
+ CellTrafficTrace,
+ DeactivateTrace,
+ DownlinkNASTransport,
+ DownlinkS1cdma2000tunneling,
+ ENBDirectInformationTransfer,
+ ENBStatusTransfer,
+ ENBConfigurationUpdate,
+ ENBConfigurationUpdateAcknowledge,
+ ENBConfigurationUpdateFailure,
+ ErrorIndication,
+ HandoverCancel,
+ HandoverCancelAcknowledge,
+ HandoverCommand,
+ HandoverFailure,
+ HandoverNotify,
+ HandoverPreparationFailure,
+ HandoverRequest,
+ HandoverRequestAcknowledge,
+ HandoverRequired,
+ InitialContextSetupFailure,
+ InitialContextSetupRequest,
+ InitialContextSetupResponse,
+ InitialUEMessage,
+ LocationReportingControl,
+ LocationReportingFailureIndication,
+ LocationReport,
+ MMEConfigurationUpdate,
+ MMEConfigurationUpdateAcknowledge,
+ MMEConfigurationUpdateFailure,
+ MMEDirectInformationTransfer,
+ MMEStatusTransfer,
+ NASNonDeliveryIndication,
+ OverloadStart,
+ OverloadStop,
+ Paging,
+ PathSwitchRequest,
+ PathSwitchRequestAcknowledge,
+ PathSwitchRequestFailure,
+ PrivateMessage,
+ Reset,
+ ResetAcknowledge,
+ S1SetupFailure,
+ S1SetupRequest,
+ S1SetupResponse,
+ E-RABModifyRequest,
+ E-RABModifyResponse,
+ E-RABReleaseCommand,
+ E-RABReleaseResponse,
+ E-RABReleaseIndication,
+ E-RABSetupRequest,
+ E-RABSetupResponse,
+ TraceFailureIndication,
+ TraceStart,
+ UECapabilityInfoIndication,
+ UEContextModificationFailure,
+ UEContextModificationRequest,
+ UEContextModificationResponse,
+ UEContextReleaseCommand,
+ UEContextReleaseComplete,
+ UEContextReleaseRequest,
+ UplinkNASTransport,
+ UplinkS1cdma2000tunneling,
+ WriteReplaceWarningRequest,
+ WriteReplaceWarningResponse,
+ ENBConfigurationTransfer,
+ MMEConfigurationTransfer
+
+
+FROM S1AP-PDU-Contents
+
+ id-CellTrafficTrace,
+ id-DeactivateTrace,
+ id-downlinkNASTransport,
+ id-DownlinkS1cdma2000tunneling,
+ id-eNBStatusTransfer,
+ id-ErrorIndication,
+ id-HandoverCancel,
+ id-HandoverNotification,
+ id-HandoverPreparation,
+ id-HandoverResourceAllocation,
+ id-InitialContextSetup,
+ id-initialUEMessage,
+ id-ENBConfigurationUpdate,
+ id-LocationReportingControl,
+ id-LocationReportingFailureIndication,
+ id-LocationReport,
+ id-eNBDirectInformationTransfer,
+ id-MMEConfigurationUpdate,
+ id-MMEDirectInformationTransfer,
+ id-MMEStatusTransfer,
+ id-NASNonDeliveryIndication,
+ id-OverloadStart,
+ id-OverloadStop,
+ id-Paging,
+ id-PathSwitchRequest,
+ id-PrivateMessage,
+ id-Reset,
+ id-S1Setup,
+ id-E-RABModify,
+ id-E-RABRelease,
+ id-E-RABReleaseIndication,
+ id-E-RABSetup,
+ id-TraceFailureIndication,
+ id-TraceStart,
+ id-UECapabilityInfoIndication,
+ id-UEContextModification,
+ id-UEContextRelease,
+ id-UEContextReleaseRequest,
+ id-uplinkNASTransport,
+ id-UplinkS1cdma2000tunneling,
+ id-WriteReplaceWarning,
+ id-eNBConfigurationTransfer,
+ id-MMEConfigurationTransfer
+FROM S1AP-Constants;
+
+
+-- **************************************************************
+--
+-- Interface Elementary Procedure Class
+--
+-- **************************************************************
+
+S1AP-ELEMENTARY-PROCEDURE ::= CLASS {
+ &InitiatingMessage ,
+ &SuccessfulOutcome OPTIONAL,
+ &UnsuccessfulOutcome OPTIONAL,
+ &procedureCode ProcedureCode UNIQUE,
+ &criticality Criticality DEFAULT ignore
+}
+WITH SYNTAX {
+ INITIATING MESSAGE &InitiatingMessage
+ [SUCCESSFUL OUTCOME &SuccessfulOutcome]
+ [UNSUCCESSFUL OUTCOME &UnsuccessfulOutcome]
+ PROCEDURE CODE &procedureCode
+ [CRITICALITY &criticality]
+}
+
+-- **************************************************************
+--
+-- Interface PDU Definition
+--
+-- **************************************************************
+
+S1AP-PDU ::= CHOICE {
+ initiatingMessage InitiatingMessage,
+ successfulOutcome SuccessfulOutcome,
+ unsuccessfulOutcome UnsuccessfulOutcome,
+ ...
+}
+
+InitiatingMessage ::= SEQUENCE {
+ procedureCode S1AP-ELEMENTARY-PROCEDURE.&procedureCode ({S1AP-ELEMENTARY-PROCEDURES}),
+ criticality S1AP-ELEMENTARY-PROCEDURE.&criticality ({S1AP-ELEMENTARY-PROCEDURES}{@procedureCode}),
+ value S1AP-ELEMENTARY-PROCEDURE.&InitiatingMessage ({S1AP-ELEMENTARY-PROCEDURES}{@procedureCode})
+}
+
+SuccessfulOutcome ::= SEQUENCE {
+ procedureCode S1AP-ELEMENTARY-PROCEDURE.&procedureCode ({S1AP-ELEMENTARY-PROCEDURES}),
+ criticality S1AP-ELEMENTARY-PROCEDURE.&criticality ({S1AP-ELEMENTARY-PROCEDURES}{@procedureCode}),
+ value S1AP-ELEMENTARY-PROCEDURE.&SuccessfulOutcome ({S1AP-ELEMENTARY-PROCEDURES}{@procedureCode})
+}
+
+UnsuccessfulOutcome ::= SEQUENCE {
+ procedureCode S1AP-ELEMENTARY-PROCEDURE.&procedureCode ({S1AP-ELEMENTARY-PROCEDURES}),
+ criticality S1AP-ELEMENTARY-PROCEDURE.&criticality ({S1AP-ELEMENTARY-PROCEDURES}{@procedureCode}),
+ value S1AP-ELEMENTARY-PROCEDURE.&UnsuccessfulOutcome ({S1AP-ELEMENTARY-PROCEDURES}{@procedureCode})
+}
+
+-- **************************************************************
+--
+-- Interface Elementary Procedure List
+--
+-- **************************************************************
+
+S1AP-ELEMENTARY-PROCEDURES S1AP-ELEMENTARY-PROCEDURE ::= {
+ S1AP-ELEMENTARY-PROCEDURES-CLASS-1 |
+ S1AP-ELEMENTARY-PROCEDURES-CLASS-2,
+ ...
+}
+
+
+S1AP-ELEMENTARY-PROCEDURES-CLASS-1 S1AP-ELEMENTARY-PROCEDURE ::= {
+ handoverPreparation |
+ handoverResourceAllocation |
+ pathSwitchRequest |
+ e-RABSetup |
+ e-RABModify |
+ e-RABRelease |
+ initialContextSetup |
+ handoverCancel |
+ reset |
+ s1Setup |
+ uEContextModification |
+ uEContextRelease |
+ eNBConfigurationUpdate |
+ mMEConfigurationUpdate |
+ writeReplaceWarning ,
+ ...
+}
+
+S1AP-ELEMENTARY-PROCEDURES-CLASS-2 S1AP-ELEMENTARY-PROCEDURE ::= {
+ handoverNotification |
+ e-RABReleaseIndication |
+ paging |
+ downlinkNASTransport |
+ initialUEMessage |
+ uplinkNASTransport |
+ errorIndication |
+ nASNonDeliveryIndication |
+ uEContextReleaseRequest |
+ downlinkS1cdma2000tunneling |
+ uplinkS1cdma2000tunneling |
+ uECapabilityInfoIndication |
+ eNBStatusTransfer |
+ mMEStatusTransfer |
+ deactivateTrace |
+ traceStart |
+ traceFailureIndication |
+ cellTrafficTrace |
+ locationReportingControl |
+ locationReportingFailureIndication |
+ locationReport |
+ overloadStart |
+ overloadStop |
+ eNBDirectInformationTransfer |
+ mMEDirectInformationTransfer |
+ eNBConfigurationTransfer |
+ mMEConfigurationTransfer |
+ privateMessage ,
+ ...
+}
+
+-- **************************************************************
+--
+-- Interface Elementary Procedures
+--
+-- **************************************************************
+
+handoverPreparation S1AP-ELEMENTARY-PROCEDURE ::= {
+ INITIATING MESSAGE HandoverRequired
+ SUCCESSFUL OUTCOME HandoverCommand
+ UNSUCCESSFUL OUTCOME HandoverPreparationFailure
+ PROCEDURE CODE id-HandoverPreparation
+ CRITICALITY reject
+}
+
+handoverResourceAllocation S1AP-ELEMENTARY-PROCEDURE ::= {
+ INITIATING MESSAGE HandoverRequest
+ SUCCESSFUL OUTCOME HandoverRequestAcknowledge
+ UNSUCCESSFUL OUTCOME HandoverFailure
+ PROCEDURE CODE id-HandoverResourceAllocation
+ CRITICALITY reject
+}
+
+handoverNotification S1AP-ELEMENTARY-PROCEDURE ::= {
+ INITIATING MESSAGE HandoverNotify
+ PROCEDURE CODE id-HandoverNotification
+ CRITICALITY ignore
+}
+
+pathSwitchRequest S1AP-ELEMENTARY-PROCEDURE ::= {
+ INITIATING MESSAGE PathSwitchRequest
+ SUCCESSFUL OUTCOME PathSwitchRequestAcknowledge
+ UNSUCCESSFUL OUTCOME PathSwitchRequestFailure
+ PROCEDURE CODE id-PathSwitchRequest
+ CRITICALITY reject
+}
+
+e-RABSetup S1AP-ELEMENTARY-PROCEDURE ::= {
+ INITIATING MESSAGE E-RABSetupRequest
+ SUCCESSFUL OUTCOME E-RABSetupResponse
+ PROCEDURE CODE id-E-RABSetup
+ CRITICALITY reject
+}
+
+e-RABModify S1AP-ELEMENTARY-PROCEDURE ::= {
+ INITIATING MESSAGE E-RABModifyRequest
+ SUCCESSFUL OUTCOME E-RABModifyResponse
+ PROCEDURE CODE id-E-RABModify
+ CRITICALITY reject
+}
+
+e-RABRelease S1AP-ELEMENTARY-PROCEDURE ::= {
+ INITIATING MESSAGE E-RABReleaseCommand
+ SUCCESSFUL OUTCOME E-RABReleaseResponse
+ PROCEDURE CODE id-E-RABRelease
+ CRITICALITY reject
+}
+
+e-RABReleaseIndication S1AP-ELEMENTARY-PROCEDURE ::= {
+ INITIATING MESSAGE E-RABReleaseIndication
+ PROCEDURE CODE id-E-RABReleaseIndication
+ CRITICALITY ignore
+}
+
+initialContextSetup S1AP-ELEMENTARY-PROCEDURE ::= {
+ INITIATING MESSAGE InitialContextSetupRequest
+ SUCCESSFUL OUTCOME InitialContextSetupResponse
+ UNSUCCESSFUL OUTCOME InitialContextSetupFailure
+ PROCEDURE CODE id-InitialContextSetup
+ CRITICALITY reject
+}
+
+uEContextReleaseRequest S1AP-ELEMENTARY-PROCEDURE ::= {
+ INITIATING MESSAGE UEContextReleaseRequest
+ PROCEDURE CODE id-UEContextReleaseRequest
+ CRITICALITY ignore
+}
+
+paging S1AP-ELEMENTARY-PROCEDURE ::= {
+ INITIATING MESSAGE Paging
+ PROCEDURE CODE id-Paging
+ CRITICALITY ignore
+}
+
+downlinkNASTransport S1AP-ELEMENTARY-PROCEDURE ::= {
+ INITIATING MESSAGE DownlinkNASTransport
+ PROCEDURE CODE id-downlinkNASTransport
+ CRITICALITY ignore
+}
+
+initialUEMessage S1AP-ELEMENTARY-PROCEDURE ::= {
+ INITIATING MESSAGE InitialUEMessage
+ PROCEDURE CODE id-initialUEMessage
+ CRITICALITY ignore
+}
+
+uplinkNASTransport S1AP-ELEMENTARY-PROCEDURE ::= {
+ INITIATING MESSAGE UplinkNASTransport
+ PROCEDURE CODE id-uplinkNASTransport
+ CRITICALITY ignore
+}
+nASNonDeliveryIndication S1AP-ELEMENTARY-PROCEDURE ::= {
+ INITIATING MESSAGE NASNonDeliveryIndication
+ PROCEDURE CODE id-NASNonDeliveryIndication
+ CRITICALITY ignore
+}
+
+handoverCancel S1AP-ELEMENTARY-PROCEDURE ::= {
+ INITIATING MESSAGE HandoverCancel
+ SUCCESSFUL OUTCOME HandoverCancelAcknowledge
+ PROCEDURE CODE id-HandoverCancel
+ CRITICALITY reject
+}
+
+reset S1AP-ELEMENTARY-PROCEDURE ::= {
+ INITIATING MESSAGE Reset
+ SUCCESSFUL OUTCOME ResetAcknowledge
+ PROCEDURE CODE id-Reset
+ CRITICALITY reject
+}
+
+errorIndication S1AP-ELEMENTARY-PROCEDURE ::= {
+ INITIATING MESSAGE ErrorIndication
+ PROCEDURE CODE id-ErrorIndication
+ CRITICALITY ignore
+}
+
+s1Setup S1AP-ELEMENTARY-PROCEDURE ::= {
+ INITIATING MESSAGE S1SetupRequest
+ SUCCESSFUL OUTCOME S1SetupResponse
+ UNSUCCESSFUL OUTCOME S1SetupFailure
+ PROCEDURE CODE id-S1Setup
+ CRITICALITY reject
+}
+
+eNBConfigurationUpdate S1AP-ELEMENTARY-PROCEDURE ::= {
+ INITIATING MESSAGE ENBConfigurationUpdate
+ SUCCESSFUL OUTCOME ENBConfigurationUpdateAcknowledge
+ UNSUCCESSFUL OUTCOME ENBConfigurationUpdateFailure
+ PROCEDURE CODE id-ENBConfigurationUpdate
+ CRITICALITY reject
+}
+
+mMEConfigurationUpdate S1AP-ELEMENTARY-PROCEDURE ::= {
+ INITIATING MESSAGE MMEConfigurationUpdate
+ SUCCESSFUL OUTCOME MMEConfigurationUpdateAcknowledge
+ UNSUCCESSFUL OUTCOME MMEConfigurationUpdateFailure
+ PROCEDURE CODE id-MMEConfigurationUpdate
+ CRITICALITY reject
+}
+
+downlinkS1cdma2000tunneling S1AP-ELEMENTARY-PROCEDURE ::= {
+ INITIATING MESSAGE DownlinkS1cdma2000tunneling
+ PROCEDURE CODE id-DownlinkS1cdma2000tunneling
+ CRITICALITY ignore
+}
+
+uplinkS1cdma2000tunneling S1AP-ELEMENTARY-PROCEDURE ::= {
+ INITIATING MESSAGE UplinkS1cdma2000tunneling
+ PROCEDURE CODE id-UplinkS1cdma2000tunneling
+ CRITICALITY ignore
+}
+
+uEContextModification S1AP-ELEMENTARY-PROCEDURE ::= {
+ INITIATING MESSAGE UEContextModificationRequest
+ SUCCESSFUL OUTCOME UEContextModificationResponse
+ UNSUCCESSFUL OUTCOME UEContextModificationFailure
+
+ PROCEDURE CODE id-UEContextModification
+ CRITICALITY reject
+}
+
+uECapabilityInfoIndication S1AP-ELEMENTARY-PROCEDURE ::= {
+ INITIATING MESSAGE UECapabilityInfoIndication
+ PROCEDURE CODE id-UECapabilityInfoIndication
+ CRITICALITY ignore
+}
+
+uEContextRelease S1AP-ELEMENTARY-PROCEDURE ::= {
+ INITIATING MESSAGE UEContextReleaseCommand
+ SUCCESSFUL OUTCOME UEContextReleaseComplete
+ PROCEDURE CODE id-UEContextRelease
+ CRITICALITY reject
+}
+
+eNBStatusTransfer S1AP-ELEMENTARY-PROCEDURE ::= {
+ INITIATING MESSAGE ENBStatusTransfer
+ PROCEDURE CODE id-eNBStatusTransfer
+ CRITICALITY ignore
+}
+
+mMEStatusTransfer S1AP-ELEMENTARY-PROCEDURE ::= {
+ INITIATING MESSAGE MMEStatusTransfer
+ PROCEDURE CODE id-MMEStatusTransfer
+ CRITICALITY ignore
+}
+
+deactivateTrace S1AP-ELEMENTARY-PROCEDURE ::= {
+ INITIATING MESSAGE DeactivateTrace
+ PROCEDURE CODE id-DeactivateTrace
+ CRITICALITY ignore
+}
+
+traceStart S1AP-ELEMENTARY-PROCEDURE ::= {
+ INITIATING MESSAGE TraceStart
+ PROCEDURE CODE id-TraceStart
+ CRITICALITY ignore
+}
+
+traceFailureIndication S1AP-ELEMENTARY-PROCEDURE ::= {
+ INITIATING MESSAGE TraceFailureIndication
+ PROCEDURE CODE id-TraceFailureIndication
+ CRITICALITY ignore
+}
+cellTrafficTrace S1AP-ELEMENTARY-PROCEDURE ::={
+INITIATING MESSAGE CellTrafficTrace
+PROCEDURE CODE id-CellTrafficTrace
+CRITICALITY ignore
+}
+
+locationReportingControl S1AP-ELEMENTARY-PROCEDURE ::= {
+ INITIATING MESSAGE LocationReportingControl
+ PROCEDURE CODE id-LocationReportingControl
+ CRITICALITY ignore
+}
+
+locationReportingFailureIndication S1AP-ELEMENTARY-PROCEDURE ::= {
+ INITIATING MESSAGE LocationReportingFailureIndication
+ PROCEDURE CODE id-LocationReportingFailureIndication
+ CRITICALITY ignore
+}
+
+locationReport S1AP-ELEMENTARY-PROCEDURE ::= {
+ INITIATING MESSAGE LocationReport
+ PROCEDURE CODE id-LocationReport
+ CRITICALITY ignore
+}
+
+overloadStart S1AP-ELEMENTARY-PROCEDURE ::= {
+ INITIATING MESSAGE OverloadStart
+ PROCEDURE CODE id-OverloadStart
+ CRITICALITY ignore
+}
+
+overloadStop S1AP-ELEMENTARY-PROCEDURE ::= {
+ INITIATING MESSAGE OverloadStop
+ PROCEDURE CODE id-OverloadStop
+ CRITICALITY reject
+}
+
+writeReplaceWarning S1AP-ELEMENTARY-PROCEDURE ::= {
+ INITIATING MESSAGE WriteReplaceWarningRequest
+ SUCCESSFUL OUTCOME WriteReplaceWarningResponse
+ PROCEDURE CODE id-WriteReplaceWarning
+ CRITICALITY reject
+}
+
+eNBDirectInformationTransfer S1AP-ELEMENTARY-PROCEDURE ::= {
+ INITIATING MESSAGE ENBDirectInformationTransfer
+ PROCEDURE CODE id-eNBDirectInformationTransfer
+ CRITICALITY ignore
+}
+
+mMEDirectInformationTransfer S1AP-ELEMENTARY-PROCEDURE ::= {
+ INITIATING MESSAGE MMEDirectInformationTransfer
+ PROCEDURE CODE id-MMEDirectInformationTransfer
+ CRITICALITY ignore
+}
+
+eNBConfigurationTransfer S1AP-ELEMENTARY-PROCEDURE ::= {
+ INITIATING MESSAGE ENBConfigurationTransfer
+ PROCEDURE CODE id-eNBConfigurationTransfer
+ CRITICALITY ignore
+}
+
+mMEConfigurationTransfer S1AP-ELEMENTARY-PROCEDURE ::= {
+ INITIATING MESSAGE MMEConfigurationTransfer
+ PROCEDURE CODE id-MMEConfigurationTransfer
+ CRITICALITY ignore
+}
+
+
+privateMessage S1AP-ELEMENTARY-PROCEDURE ::= {
+ INITIATING MESSAGE PrivateMessage
+ PROCEDURE CODE id-PrivateMessage
+ CRITICALITY ignore
+}
+
+END
diff --git a/lib/asn1/test/asn1_SUITE_data/SOpttest.asn b/lib/asn1/test/asn1_SUITE_data/SOpttest.asn
new file mode 100644
index 0000000000..498d3ebec1
--- /dev/null
+++ b/lib/asn1/test/asn1_SUITE_data/SOpttest.asn
@@ -0,0 +1,30 @@
+SOpttest DEFINITIONS IMPLICIT TAGS ::=
+BEGIN
+
+S ::= SEQUENCE {
+ a [0] A,
+ b [1] B OPTIONAL,
+ c [2] C OPTIONAL
+
+ }
+
+
+A ::= SEQUENCE {
+ scriptKey [0] INTEGER (0..214783647),
+ scriptAttribute1 [1] EXPLICIT INTEGER OPTIONAL,
+ scriptAttribute2 [2] EXPLICIT INTEGER OPTIONAL
+ }
+
+B ::= SEQUENCE {
+ iNLegToBeCreated [0] INTEGER OPTIONAL,
+ callingPartysCategory [1] INTEGER OPTIONAL,
+ redirectingPartyID [2] INTEGER OPTIONAL
+ }
+
+C ::= SEQUENCE {
+ iNLegToBeCreated [0] INTEGER OPTIONAL,
+ callingPartysCategory [1] INTEGER OPTIONAL,
+ redirectingPartyID [2] INTEGER OPTIONAL
+ }
+
+END
diff --git a/lib/asn1/test/asn1_SUITE_data/SSL-PKIX.asn1 b/lib/asn1/test/asn1_SUITE_data/SSL-PKIX.asn1
new file mode 100644
index 0000000000..31d78bebbe
--- /dev/null
+++ b/lib/asn1/test/asn1_SUITE_data/SSL-PKIX.asn1
@@ -0,0 +1,704 @@
+SSL-PKIX {iso(1) identified-organization(3) dod(6) internet(1)
+ private(4) enterprices(1) ericsson(193) otp(19) ssl(10)
+ pkix1(1)}
+
+DEFINITIONS EXPLICIT TAGS ::=
+
+BEGIN
+
+-- EXPORTS ALL
+
+IMPORTS
+ -- Certificate (parts of)
+ Version,
+ CertificateSerialNumber,
+ --AlgorithmIdentifier,
+ Validity,
+ UniqueIdentifier,
+
+ -- AttribyteTypeAndValue
+ Name,
+ AttributeType,
+ id-at-name,
+ id-at-surname,
+ id-at-givenName,
+ id-at-initials,
+ id-at-generationQualifier, X520name,
+ id-at-commonName, X520CommonName,
+ id-at-localityName, X520LocalityName,
+ id-at-stateOrProvinceName, X520StateOrProvinceName,
+ id-at-organizationName, X520OrganizationName,
+ id-at-organizationalUnitName, X520OrganizationalUnitName,
+ id-at-title, X520Title,
+ id-at-dnQualifier, X520dnQualifier,
+ id-at-countryName, X520countryName,
+ id-at-serialNumber, X520SerialNumber,
+ id-at-pseudonym, X520Pseudonym,
+ id-domainComponent, DomainComponent,
+ id-emailAddress, EmailAddress,
+
+ -- Extension Attributes
+ common-name, CommonName,
+ teletex-common-name, TeletexCommonName,
+ teletex-personal-name, TeletexPersonalName,
+ pds-name, PDSName,
+ physical-delivery-country-name, PhysicalDeliveryCountryName,
+ postal-code, PostalCode,
+ physical-delivery-office-name, PhysicalDeliveryOfficeName,
+ physical-delivery-office-number, PhysicalDeliveryOfficeNumber,
+ extension-OR-address-components, ExtensionORAddressComponents,
+ physical-delivery-personal-name, PhysicalDeliveryPersonalName,
+ physical-delivery-organization-name, PhysicalDeliveryOrganizationName,
+ extension-physical-delivery-address-components,
+ ExtensionPhysicalDeliveryAddressComponents,
+ unformatted-postal-address, UnformattedPostalAddress,
+ street-address, StreetAddress,
+ post-office-box-address, PostOfficeBoxAddress,
+ poste-restante-address, PosteRestanteAddress,
+ unique-postal-name, UniquePostalName,
+ local-postal-attributes, LocalPostalAttributes,
+ extended-network-address, ExtendedNetworkAddress,
+ terminal-type, TerminalType,
+ teletex-domain-defined-attributes, TeletexDomainDefinedAttributes
+
+ FROM PKIX1Explicit88 { iso(1) identified-organization(3) dod(6)
+ internet(1) security(5) mechanisms(5) pkix(7) id-mod(0)
+ id-pkix1-explicit(18) }
+
+ -- Extensions
+ id-ce-authorityKeyIdentifier, AuthorityKeyIdentifier,
+ id-ce-subjectKeyIdentifier, SubjectKeyIdentifier,
+ id-ce-keyUsage, KeyUsage,
+ id-ce-privateKeyUsagePeriod, PrivateKeyUsagePeriod,
+ id-ce-certificatePolicies, CertificatePolicies,
+ id-ce-policyMappings, PolicyMappings,
+ id-ce-subjectAltName, SubjectAltName,
+ id-ce-issuerAltName, IssuerAltName,
+ id-ce-subjectDirectoryAttributes, SubjectDirectoryAttributes,
+ id-ce-basicConstraints, BasicConstraints,
+ id-ce-nameConstraints, NameConstraints,
+ id-ce-policyConstraints, PolicyConstraints,
+ id-ce-cRLDistributionPoints, CRLDistributionPoints,
+ id-ce-extKeyUsage, ExtKeyUsageSyntax,
+ id-ce-inhibitAnyPolicy, InhibitAnyPolicy,
+ id-ce-freshestCRL, FreshestCRL,
+ id-pe-authorityInfoAccess, AuthorityInfoAccessSyntax,
+ id-pe-subjectInfoAccess, SubjectInfoAccessSyntax,
+ id-ce-cRLNumber, CRLNumber,
+ id-ce-issuingDistributionPoint, IssuingDistributionPoint,
+ id-ce-deltaCRLIndicator, BaseCRLNumber,
+ id-ce-cRLReasons, CRLReason,
+ id-ce-certificateIssuer, CertificateIssuer,
+ id-ce-holdInstructionCode, HoldInstructionCode,
+ id-ce-invalidityDate, InvalidityDate
+
+ FROM PKIX1Implicit88 { iso(1) identified-organization(3) dod(6)
+ internet(1) security(5) mechanisms(5) pkix(7) id-mod(0)
+ id-pkix1-implicit(19) }
+
+ --Keys and Signatures
+ id-dsa, Dss-Parms, DSAPublicKey,
+ id-dsa-with-sha1,
+ md2WithRSAEncryption,
+ md5WithRSAEncryption,
+ sha1WithRSAEncryption,
+ rsaEncryption, RSAPublicKey,
+ dhpublicnumber, DomainParameters, DHPublicKey,
+ id-keyExchangeAlgorithm, KEA-Parms-Id, --KEA-PublicKey,
+ ecdsa-with-SHA1,
+ prime-field, Prime-p,
+ characteristic-two-field, --Characteristic-two,
+ gnBasis,
+ tpBasis, Trinomial,
+ ppBasis, Pentanomial,
+ id-ecPublicKey, EcpkParameters, ECPoint
+ FROM PKIX1Algorithms88 { iso(1) identified-organization(3) dod(6)
+ internet(1) security(5) mechanisms(5) pkix(7) id-mod(0)
+ id-mod-pkix1-algorithms(17) };
+
+--
+-- Certificate
+--
+
+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 -- }
+
+
+-- Attribute type and values
+--
+
+ATTRIBUTE-TYPE-AND-VALUE-CLASS ::= CLASS {
+ &id AttributeType UNIQUE,
+ &Type }
+ WITH SYNTAX {
+ ID &id
+ TYPE &Type }
+
+AttributeTypeAndValue ::= SEQUENCE {
+ type ATTRIBUTE-TYPE-AND-VALUE-CLASS.&id
+ ({SupportedAttributeTypeAndValues}),
+ value ATTRIBUTE-TYPE-AND-VALUE-CLASS.&Type
+ ({SupportedAttributeTypeAndValues}{@type}) }
+
+SupportedAttributeTypeAndValues ATTRIBUTE-TYPE-AND-VALUE-CLASS ::=
+ { name | surname | givenName | initials | generationQualifier |
+ commonName | localityName | stateOrProvinceName | organizationName |
+ organizationalUnitName | title | dnQualifier | countryName |
+ serialNumber | pseudonym | domainComponent | emailAddress }
+
+name ATTRIBUTE-TYPE-AND-VALUE-CLASS ::= {
+ ID id-at-name
+ TYPE X520name }
+
+surname ATTRIBUTE-TYPE-AND-VALUE-CLASS ::= {
+ ID id-at-surname
+ TYPE X520name }
+
+givenName ATTRIBUTE-TYPE-AND-VALUE-CLASS ::= {
+ ID id-at-givenName
+ TYPE X520name }
+
+initials ATTRIBUTE-TYPE-AND-VALUE-CLASS ::= {
+ ID id-at-initials
+ TYPE X520name }
+
+generationQualifier ATTRIBUTE-TYPE-AND-VALUE-CLASS ::= {
+ ID id-at-generationQualifier
+ TYPE X520name }
+
+commonName ATTRIBUTE-TYPE-AND-VALUE-CLASS ::= {
+ ID id-at-commonName
+ TYPE X520CommonName }
+
+localityName ATTRIBUTE-TYPE-AND-VALUE-CLASS ::= {
+ ID id-at-localityName
+ TYPE X520LocalityName }
+
+stateOrProvinceName ATTRIBUTE-TYPE-AND-VALUE-CLASS ::= {
+ ID id-at-stateOrProvinceName
+ TYPE X520StateOrProvinceName }
+
+organizationName ATTRIBUTE-TYPE-AND-VALUE-CLASS ::= {
+ ID id-at-organizationName
+ TYPE X520OrganizationName }
+
+organizationalUnitName ATTRIBUTE-TYPE-AND-VALUE-CLASS ::= {
+ ID id-at-organizationalUnitName
+ TYPE X520OrganizationalUnitName }
+
+title ATTRIBUTE-TYPE-AND-VALUE-CLASS ::= {
+ ID id-at-title
+ TYPE X520Title }
+
+dnQualifier ATTRIBUTE-TYPE-AND-VALUE-CLASS ::= {
+ ID id-at-dnQualifier
+ TYPE X520dnQualifier }
+
+countryName ATTRIBUTE-TYPE-AND-VALUE-CLASS ::= {
+ ID id-at-countryName
+ TYPE X520countryName }
+
+serialNumber ATTRIBUTE-TYPE-AND-VALUE-CLASS ::= {
+ ID id-at-serialNumber
+ TYPE X520SerialNumber }
+
+pseudonym ATTRIBUTE-TYPE-AND-VALUE-CLASS ::= {
+ ID id-at-pseudonym
+ TYPE X520Pseudonym }
+
+domainComponent ATTRIBUTE-TYPE-AND-VALUE-CLASS ::= {
+ ID id-domainComponent
+ TYPE DomainComponent }
+
+emailAddress ATTRIBUTE-TYPE-AND-VALUE-CLASS ::= {
+ ID id-emailAddress
+ TYPE EmailAddress }
+
+--
+-- Signature and Public Key Algorithms
+--
+
+SubjectPublicKeyInfo ::= SEQUENCE {
+ algorithm SEQUENCE {
+ algo PUBLIC-KEY-ALGORITHM-CLASS.&id
+ ({SupportedPublicKeyAlgorithms}),
+ parameters PUBLIC-KEY-ALGORITHM-CLASS.&Type
+ ({SupportedPublicKeyAlgorithms}{@.algo})
+ OPTIONAL
+ },
+ subjectPublicKey PUBLIC-KEY-ALGORITHM-CLASS.&PublicKeyType
+ ({SupportedPublicKeyAlgorithms}{@algorithm.algo}) }
+
+-- The following is needed for conversion of SubjectPublicKeyInfo.
+
+SubjectPublicKeyInfo-Any ::= SEQUENCE {
+ algorithm PublicKeyAlgorithm,
+ subjectPublicKey ANY }
+
+
+SIGNATURE-ALGORITHM-CLASS ::= CLASS {
+ &id OBJECT IDENTIFIER UNIQUE,
+ &Type OPTIONAL }
+ WITH SYNTAX {
+ ID &id
+ [TYPE &Type] }
+
+PUBLIC-KEY-ALGORITHM-CLASS ::= CLASS {
+ &id OBJECT IDENTIFIER UNIQUE,
+ &Type OPTIONAL,
+ &PublicKeyType OPTIONAL }
+ WITH SYNTAX {
+ ID &id
+ [TYPE &Type]
+ [PUBLIC-KEY-TYPE &PublicKeyType] }
+
+SignatureAlgorithm ::= SEQUENCE {
+ algorithm SIGNATURE-ALGORITHM-CLASS.&id
+ ({SupportedSignatureAlgorithms}),
+ parameters SIGNATURE-ALGORITHM-CLASS.&Type
+ ({SupportedSignatureAlgorithms}{@algorithm})
+ OPTIONAL }
+
+SignatureAlgorithm-Any ::= SEQUENCE {
+ algorithm OBJECT IDENTIFIER,
+ parameters ANY OPTIONAL }
+
+PublicKeyAlgorithm ::= SEQUENCE {
+ algorithm PUBLIC-KEY-ALGORITHM-CLASS.&id
+ ({SupportedPublicKeyAlgorithms}),
+ parameters PUBLIC-KEY-ALGORITHM-CLASS.&Type
+ ({SupportedPublicKeyAlgorithms}{@algorithm})
+ OPTIONAL }
+
+SupportedSignatureAlgorithms SIGNATURE-ALGORITHM-CLASS ::= {
+ dsa-with-sha1 | md2-with-rsa-encryption |
+ md5-with-rsa-encryption | sha1-with-rsa-encryption |
+ ecdsa-with-sha1 }
+
+SupportedPublicKeyAlgorithms PUBLIC-KEY-ALGORITHM-CLASS ::= {
+ dsa | rsa-encryption | dh | kea | ec-public-key }
+
+ -- DSA Keys and Signatures
+
+ -- SubjectPublicKeyInfo:
+
+ dsa PUBLIC-KEY-ALGORITHM-CLASS ::= {
+ ID id-dsa
+ TYPE Dss-Parms -- XXX Must be OPTIONAL
+ PUBLIC-KEY-TYPE DSAPublicKey }
+
+ -- Certificate.signatureAlgorithm
+
+ dsa-with-sha1 SIGNATURE-ALGORITHM-CLASS ::= {
+ ID id-dsa-with-sha1
+ TYPE NULL } -- XXX Must be empty and not NULL
+
+ --
+ -- RSA Keys and Signatures
+ --
+
+ -- Certificate.signatureAlgorithm
+
+ md2-with-rsa-encryption SIGNATURE-ALGORITHM-CLASS ::= {
+ ID md2WithRSAEncryption
+ TYPE NULL }
+
+ md5-with-rsa-encryption SIGNATURE-ALGORITHM-CLASS ::= {
+ ID md5WithRSAEncryption
+ TYPE NULL }
+
+ sha1-with-rsa-encryption SIGNATURE-ALGORITHM-CLASS ::= {
+ ID sha1WithRSAEncryption
+ TYPE NULL }
+
+ -- Certificate.signature
+ -- See PKCS #1 (RFC 2313). XXX
+
+ -- SubjectPublicKeyInfo:
+
+ rsa-encryption PUBLIC-KEY-ALGORITHM-CLASS ::= {
+ ID rsaEncryption
+ TYPE NULL
+ PUBLIC-KEY-TYPE RSAPublicKey }
+
+ --
+ -- Diffie-Hellman Keys
+ --
+
+ -- SubjectPublicKeyInfo:
+
+ dh PUBLIC-KEY-ALGORITHM-CLASS ::= {
+ ID dhpublicnumber
+ TYPE DomainParameters
+ PUBLIC-KEY-TYPE DHPublicKey }
+
+ -- There are no Diffie-Hellman signature algorithms
+
+ --
+ -- KEA Keys
+ --
+
+ -- SubjectPublicKeyInfo:
+
+ KEA-PublicKey ::= INTEGER
+
+ kea PUBLIC-KEY-ALGORITHM-CLASS ::= {
+ ID id-keyExchangeAlgorithm
+ TYPE KEA-Parms-Id
+ PUBLIC-KEY-TYPE KEA-PublicKey }
+
+ -- There are no KEA signature algorithms
+
+ --
+ -- Elliptic Curve Keys, Signatures, and Curves
+ --
+
+ -- Certificate.signatureAlgorithm
+
+ ecdsa-with-sha1 SIGNATURE-ALGORITHM-CLASS ::= {
+ ID ecdsa-with-SHA1
+ TYPE NULL } -- XXX Must be empty and not NULL
+
+ FIELD-ID-CLASS ::= CLASS {
+ &id OBJECT IDENTIFIER UNIQUE,
+ &Type }
+ WITH SYNTAX {
+ ID &id
+ TYPE &Type }
+
+ FieldID ::= SEQUENCE { -- Finite field
+ fieldType FIELD-ID-CLASS.&id({SupportedFieldIds}),
+ parameters FIELD-ID-CLASS.&Type({SupportedFieldIds}{@fieldType}) }
+
+ SupportedFieldIds FIELD-ID-CLASS ::= {
+ field-prime-field | field-characteristic-two }
+
+ field-prime-field FIELD-ID-CLASS ::= {
+ ID prime-field
+ TYPE Prime-p }
+
+ CHARACTERISTIC-TWO-CLASS ::= CLASS {
+ &id OBJECT IDENTIFIER UNIQUE,
+ &Type }
+ WITH SYNTAX {
+ ID &id
+ TYPE &Type }
+
+ Characteristic-two ::= SEQUENCE { -- Finite field
+ m INTEGER, -- Field size 2^m
+ basis CHARACTERISTIC-TWO-CLASS.&id({SupportedCharacteristicTwos}),
+ parameters CHARACTERISTIC-TWO-CLASS.&Type
+ ({SupportedCharacteristicTwos}{@basis}) }
+
+ SupportedCharacteristicTwos CHARACTERISTIC-TWO-CLASS ::= {
+ gn-basis | tp-basis | pp-basis }
+
+ field-characteristic-two FIELD-ID-CLASS ::= {
+ ID characteristic-two-field
+ TYPE Characteristic-two }
+
+ gn-basis CHARACTERISTIC-TWO-CLASS ::= {
+ ID gnBasis
+ TYPE NULL }
+
+ tp-basis CHARACTERISTIC-TWO-CLASS ::= {
+ ID tpBasis
+ TYPE Trinomial }
+
+ pp-basis CHARACTERISTIC-TWO-CLASS ::= {
+ ID ppBasis
+ TYPE Pentanomial }
+
+ -- SubjectPublicKeyInfo.algorithm
+
+ ec-public-key PUBLIC-KEY-ALGORITHM-CLASS ::= {
+ ID id-ecPublicKey
+ TYPE EcpkParameters
+ PUBLIC-KEY-TYPE ECPoint }
+
+--
+-- Extension Attributes
+--
+
+EXTENSION-ATTRIBUTE-CLASS ::= CLASS {
+ &id INTEGER UNIQUE,
+ &Type }
+ WITH SYNTAX {
+ ID &id
+ TYPE &Type }
+
+ExtensionAttributes ::= SET SIZE (1..MAX) OF ExtensionAttribute
+
+-- XXX Below we should have extension-attribute-type and extension-
+-- attribute-value but Erlang ASN1 does not like it.
+ExtensionAttribute ::= SEQUENCE {
+ extensionAttributeType [0] IMPLICIT EXTENSION-ATTRIBUTE-CLASS.&id
+ ({SupportedExtensionAttributes}),
+ extensionAttributeValue [1] EXTENSION-ATTRIBUTE-CLASS.&Type
+ ({SupportedExtensionAttributes}{@extensionAttributeType}) }
+
+SupportedExtensionAttributes EXTENSION-ATTRIBUTE-CLASS ::= {
+ x400-common-name |
+ x400-teletex-common-name |
+ x400-teletex-personal-name |
+ x400-pds-name |
+ x400-physical-delivery-country-name |
+ x400-postal-code |
+ x400-physical-delivery-office-name |
+ x400-physical-delivery-office-number |
+ x400-extension-OR-address-components |
+ x400-physical-delivery-personal-name |
+ x400-physical-delivery-organization-name |
+ x400-extension-physical-delivery-address-components |
+ x400-unformatted-postal-address |
+ x400-street-address |
+ x400-post-office-box-address |
+ x400-poste-restante-address |
+ x400-unique-postal-name |
+ x400-local-postal-attributes |
+ x400-extended-network-address |
+ x400-terminal-type |
+ x400-teletex-domain-defined-attributes }
+
+-- Extension types and attribute values
+
+x400-common-name EXTENSION-ATTRIBUTE-CLASS ::= {
+ ID common-name
+ TYPE CommonName }
+
+x400-teletex-common-name EXTENSION-ATTRIBUTE-CLASS ::= {
+ ID teletex-common-name
+ TYPE TeletexCommonName }
+
+x400-teletex-personal-name EXTENSION-ATTRIBUTE-CLASS ::= {
+ ID teletex-personal-name
+ TYPE TeletexPersonalName }
+
+x400-pds-name EXTENSION-ATTRIBUTE-CLASS ::= {
+ ID pds-name
+ TYPE PDSName }
+
+x400-physical-delivery-country-name EXTENSION-ATTRIBUTE-CLASS ::= {
+ ID physical-delivery-country-name
+ TYPE PhysicalDeliveryCountryName }
+
+x400-postal-code EXTENSION-ATTRIBUTE-CLASS ::= {
+ ID postal-code
+ TYPE PostalCode }
+
+x400-physical-delivery-office-name EXTENSION-ATTRIBUTE-CLASS ::= {
+ ID physical-delivery-office-name
+ TYPE PhysicalDeliveryOfficeName }
+
+x400-physical-delivery-office-number EXTENSION-ATTRIBUTE-CLASS ::= {
+ ID physical-delivery-office-number
+ TYPE PhysicalDeliveryOfficeNumber }
+
+x400-extension-OR-address-components EXTENSION-ATTRIBUTE-CLASS ::= {
+ ID extension-OR-address-components
+ TYPE ExtensionORAddressComponents }
+
+x400-physical-delivery-personal-name EXTENSION-ATTRIBUTE-CLASS ::= {
+ ID physical-delivery-personal-name
+ TYPE PhysicalDeliveryPersonalName }
+
+x400-physical-delivery-organization-name EXTENSION-ATTRIBUTE-CLASS ::= {
+ ID physical-delivery-organization-name
+ TYPE PhysicalDeliveryOrganizationName }
+
+x400-extension-physical-delivery-address-components
+ EXTENSION-ATTRIBUTE-CLASS ::= {
+ ID extension-physical-delivery-address-components
+ TYPE ExtensionPhysicalDeliveryAddressComponents }
+
+x400-unformatted-postal-address EXTENSION-ATTRIBUTE-CLASS ::= {
+ ID unformatted-postal-address
+ TYPE UnformattedPostalAddress }
+
+x400-street-address EXTENSION-ATTRIBUTE-CLASS ::= {
+ ID street-address
+ TYPE StreetAddress }
+
+x400-post-office-box-address EXTENSION-ATTRIBUTE-CLASS ::= {
+ ID post-office-box-address
+ TYPE PostOfficeBoxAddress }
+
+x400-poste-restante-address EXTENSION-ATTRIBUTE-CLASS ::= {
+ ID poste-restante-address
+ TYPE PosteRestanteAddress }
+
+x400-unique-postal-name EXTENSION-ATTRIBUTE-CLASS ::= {
+ ID unique-postal-name
+ TYPE UniquePostalName }
+
+x400-local-postal-attributes EXTENSION-ATTRIBUTE-CLASS ::= {
+ ID local-postal-attributes
+ TYPE LocalPostalAttributes }
+
+x400-extended-network-address EXTENSION-ATTRIBUTE-CLASS ::= {
+ ID extended-network-address
+ TYPE ExtendedNetworkAddress }
+
+x400-terminal-type EXTENSION-ATTRIBUTE-CLASS ::= {
+ ID terminal-type
+ TYPE TerminalType }
+
+x400-teletex-domain-defined-attributes EXTENSION-ATTRIBUTE-CLASS ::= {
+ ID teletex-domain-defined-attributes
+ TYPE TeletexDomainDefinedAttributes }
+
+-- Extensions
+
+Extensions ::= SEQUENCE SIZE (1..MAX) OF Extension
+
+EXTENSION-CLASS ::= CLASS {
+ &id OBJECT IDENTIFIER UNIQUE,
+ &Type OPTIONAL}
+ WITH SYNTAX {
+ ID &id
+ [TYPE &Type] }
+
+Extension ::= SEQUENCE {
+ extnID EXTENSION-CLASS.&id({SupportedExtensions}),
+ critical BOOLEAN DEFAULT FALSE,
+ extnValue EXTENSION-CLASS.&Type({SupportedExtensions}{@extnID}) }
+
+-- The following is needed for conversion between Extension and Extension-Cd
+
+ObjId ::= OBJECT IDENTIFIER
+Boolean ::= BOOLEAN
+Any ::= ANY
+
+Extension-Any ::= SEQUENCE {
+ extnID OBJECT IDENTIFIER,
+ critical BOOLEAN DEFAULT FALSE,
+ extnValue ANY }
+
+SupportedExtensions EXTENSION-CLASS ::= { authorityKeyIdentifier |
+ subjectKeyIdentifier | keyUsage | privateKeyUsagePeriod |
+ certificatePolicies | policyMappings | subjectAltName |
+ issuerAltName | subjectDirectoryAttributes | basicConstraints |
+ nameConstraints | policyConstraints | cRLDistributionPoints |
+ extKeyUsage | inhibitAnyPolicy | freshestCRL | authorityInfoAccess |
+ subjectInfoAccess | cRLNumber | issuingDistributionPoint |
+ deltaCRLIndicator | cRLReasons | certificateIssuer |
+ holdInstructionCode | invalidityDate }
+
+authorityKeyIdentifier EXTENSION-CLASS ::= {
+ ID id-ce-authorityKeyIdentifier
+ TYPE AuthorityKeyIdentifier }
+
+subjectKeyIdentifier EXTENSION-CLASS ::= {
+ ID id-ce-subjectKeyIdentifier
+ TYPE SubjectKeyIdentifier }
+
+keyUsage EXTENSION-CLASS ::= {
+ ID id-ce-keyUsage
+ TYPE KeyUsage }
+
+privateKeyUsagePeriod EXTENSION-CLASS ::= {
+ ID id-ce-privateKeyUsagePeriod
+ TYPE PrivateKeyUsagePeriod }
+
+certificatePolicies EXTENSION-CLASS ::= {
+ ID id-ce-certificatePolicies
+ TYPE CertificatePolicies }
+
+policyMappings EXTENSION-CLASS ::= {
+ ID id-ce-policyMappings
+ TYPE PolicyMappings }
+
+subjectAltName EXTENSION-CLASS ::= {
+ ID id-ce-subjectAltName
+ TYPE SubjectAltName }
+
+issuerAltName EXTENSION-CLASS ::= {
+ ID id-ce-issuerAltName
+ TYPE IssuerAltName }
+
+subjectDirectoryAttributes EXTENSION-CLASS ::= {
+ ID id-ce-subjectDirectoryAttributes
+ TYPE SubjectDirectoryAttributes }
+
+basicConstraints EXTENSION-CLASS ::= {
+ ID id-ce-basicConstraints
+ TYPE BasicConstraints }
+
+nameConstraints EXTENSION-CLASS ::= {
+ ID id-ce-nameConstraints
+ TYPE NameConstraints }
+
+policyConstraints EXTENSION-CLASS ::= {
+ ID id-ce-policyConstraints
+ TYPE PolicyConstraints }
+
+cRLDistributionPoints EXTENSION-CLASS ::= {
+ ID id-ce-cRLDistributionPoints
+ TYPE CRLDistributionPoints }
+
+extKeyUsage EXTENSION-CLASS ::= {
+ ID id-ce-extKeyUsage
+ TYPE ExtKeyUsageSyntax }
+
+inhibitAnyPolicy EXTENSION-CLASS ::= {
+ ID id-ce-inhibitAnyPolicy
+ TYPE InhibitAnyPolicy }
+
+freshestCRL EXTENSION-CLASS ::= {
+ ID id-ce-freshestCRL
+ TYPE FreshestCRL }
+
+authorityInfoAccess EXTENSION-CLASS ::= {
+ ID id-pe-authorityInfoAccess
+ TYPE AuthorityInfoAccessSyntax }
+
+subjectInfoAccess EXTENSION-CLASS ::= {
+ ID id-pe-subjectInfoAccess
+ TYPE SubjectInfoAccessSyntax }
+
+cRLNumber EXTENSION-CLASS ::= {
+ ID id-ce-cRLNumber
+ TYPE CRLNumber }
+
+issuingDistributionPoint EXTENSION-CLASS ::= {
+ ID id-ce-issuingDistributionPoint
+ TYPE IssuingDistributionPoint }
+
+deltaCRLIndicator EXTENSION-CLASS ::= {
+ ID id-ce-deltaCRLIndicator
+ TYPE BaseCRLNumber }
+
+cRLReasons EXTENSION-CLASS ::= {
+ ID id-ce-cRLReasons
+ TYPE CRLReason }
+
+certificateIssuer EXTENSION-CLASS ::= {
+ ID id-ce-certificateIssuer
+ TYPE CertificateIssuer }
+
+holdInstructionCode EXTENSION-CLASS ::= {
+ ID id-ce-holdInstructionCode
+ TYPE HoldInstructionCode }
+
+invalidityDate EXTENSION-CLASS ::= {
+ ID id-ce-invalidityDate
+ TYPE InvalidityDate }
+
+END
diff --git a/lib/asn1/test/asn1_SUITE_data/SelectedAttributeTypes.asn b/lib/asn1/test/asn1_SUITE_data/SelectedAttributeTypes.asn
new file mode 100644
index 0000000000..25f20e5c01
--- /dev/null
+++ b/lib/asn1/test/asn1_SUITE_data/SelectedAttributeTypes.asn
@@ -0,0 +1,1466 @@
+-- Module SelectedAttributeTypes (X.520:08/1997)
+
+SelectedAttributeTypes {joint-iso-itu-t ds(5) module(1)
+ selectedAttributeTypes(5) 3} DEFINITIONS ::=
+BEGIN
+
+-- EXPORTS All
+-- The types and values defined in this module are exported for use in the other ASN.1 modules contained
+-- within the Directory Specifications, and for the use of other applications which will use them to access
+-- Directory services. Other applications may use them for their own purposes, but this will not constrain
+-- extensions and modifications needed to maintain or improve the Directory service.
+IMPORTS
+ informationFramework, upperBounds, id-at, id-mr, id-avc,
+ directoryAbstractService, id-pr, id-not, id-cat
+ FROM UsefulDefinitions {joint-iso-itu-t ds(5) module(1)
+ usefulDefinitions(0) 3}
+ Attribute, ATTRIBUTE, MATCHING-RULE, AttributeType, OBJECT-CLASS,
+ DistinguishedName, objectIdentifierMatch, distinguishedNameMatch,
+ CONTEXT, ContextAssertion, AttributeCombination, ContextCombination,
+ MAPPING-BASED-MATCHING, MRMapping, AttributeValueAssertion
+ FROM InformationFramework informationFramework
+ G3FacsimileNonBasicParameters
+ FROM MTSAbstractService {joint-iso-itu-t mhs(6) mts(3) modules(0)
+ mts-abstract-service(1) version-1999(1)}
+ ub-answerback, ub-name, ub-common-name, ub-surname, ub-serial-number,
+ ub-locality-name, ub-state-name, ub-street-address, ub-organization-name,
+ ub-organizational-unit-name, ub-title, ub-description,
+ ub-business-category, ub-postal-line, ub-postal-string, ub-postal-code,
+ ub-post-office-box, ub-physical-office-name, ub-telex-number,
+ ub-country-code, ub-teletex-terminal-id, ub-telephone-number,
+ ub-x121-address, ub-international-isdn-number, ub-destination-indicator,
+ ub-user-password, ub-match, ub-knowledge-information,
+ ub-directory-string-first-component-match, ub-localeContextSyntax,
+ ub-pseudonym
+ FROM UpperBounds upperBounds
+ FilterItem, HierarchySelections, SearchControlOptions, ServiceControlOptions
+ FROM DirectoryAbstractService directoryAbstractService;
+
+-- Directory string type
+DirectoryString{INTEGER:maxSize} ::= CHOICE {
+ teletexString TeletexString(SIZE (1..maxSize)),
+ printableString PrintableString(SIZE (1..maxSize)),
+ universalString UniversalString(SIZE (1..maxSize)),
+ bmpString BMPString(SIZE (1..maxSize)),
+ uTF8String UTF8String(SIZE (1..maxSize))
+}
+
+-- Attribute types
+knowledgeInformation ATTRIBUTE ::= {
+ WITH SYNTAX DirectoryString {ub-knowledge-information}
+ EQUALITY MATCHING RULE caseIgnoreMatch
+ ID id-at-knowledgeInformation
+}
+
+name ATTRIBUTE ::= {
+ WITH SYNTAX DirectoryString {ub-name}
+ EQUALITY MATCHING RULE caseIgnoreMatch
+ SUBSTRINGS MATCHING RULE caseIgnoreSubstringsMatch
+ ID id-at-name
+}
+
+commonName ATTRIBUTE ::= {
+ SUBTYPE OF name
+ WITH SYNTAX DirectoryString {ub-common-name}
+ ID id-at-commonName
+}
+
+surname ATTRIBUTE ::= {
+ SUBTYPE OF name
+ WITH SYNTAX DirectoryString {ub-surname}
+ ID id-at-surname
+}
+
+givenName ATTRIBUTE ::= {
+ SUBTYPE OF name
+ WITH SYNTAX DirectoryString {ub-name}
+ ID id-at-givenName
+}
+
+initials ATTRIBUTE ::= {
+ SUBTYPE OF name
+ WITH SYNTAX DirectoryString {ub-name}
+ ID id-at-initials
+}
+
+generationQualifier ATTRIBUTE ::= {
+ SUBTYPE OF name
+ WITH SYNTAX DirectoryString {ub-name}
+ ID id-at-generationQualifier
+}
+
+uniqueIdentifier ATTRIBUTE ::= {
+ WITH SYNTAX UniqueIdentifier
+ EQUALITY MATCHING RULE bitStringMatch
+ ID id-at-uniqueIdentifier
+}
+
+UniqueIdentifier ::= BIT STRING
+
+dnQualifier ATTRIBUTE ::= {
+ WITH SYNTAX PrintableString
+ EQUALITY MATCHING RULE caseIgnoreMatch
+ ORDERING MATCHING RULE caseIgnoreOrderingMatch
+ SUBSTRINGS MATCHING RULE caseIgnoreSubstringsMatch
+ ID id-at-dnQualifier
+}
+
+serialNumber ATTRIBUTE ::= {
+ WITH SYNTAX PrintableString(SIZE (1..ub-serial-number))
+ EQUALITY MATCHING RULE caseIgnoreMatch
+ SUBSTRINGS MATCHING RULE caseIgnoreSubstringsMatch
+ ID id-at-serialNumber
+}
+
+pseudonym ATTRIBUTE ::= {
+ SUBTYPE OF name
+ WITH SYNTAX DirectoryString {ub-pseudonym}
+ ID id-at-pseudonym
+}
+
+countryName ATTRIBUTE ::= {
+ SUBTYPE OF name
+ WITH SYNTAX CountryName
+ SINGLE VALUE TRUE
+ ID id-at-countryName
+}
+
+CountryName ::= PrintableString(SIZE (2)) -- ISO 3166 codes only
+
+
+localityName ATTRIBUTE ::= {
+ SUBTYPE OF name
+ WITH SYNTAX DirectoryString {ub-locality-name}
+ ID id-at-localityName
+}
+
+collectiveLocalityName ATTRIBUTE ::= {
+ SUBTYPE OF localityName
+ COLLECTIVE TRUE
+ ID id-at-collectiveLocalityName
+}
+
+stateOrProvinceName ATTRIBUTE ::= {
+ SUBTYPE OF name
+ WITH SYNTAX DirectoryString {ub-state-name}
+ ID id-at-stateOrProvinceName
+}
+
+collectiveStateOrProvinceName ATTRIBUTE ::= {
+ SUBTYPE OF stateOrProvinceName
+ COLLECTIVE TRUE
+ ID id-at-collectiveStateOrProvinceName
+}
+
+streetAddress ATTRIBUTE ::= {
+ WITH SYNTAX DirectoryString {ub-street-address}
+ EQUALITY MATCHING RULE caseIgnoreMatch
+ SUBSTRINGS MATCHING RULE caseIgnoreSubstringsMatch
+ ID id-at-streetAddress
+}
+
+collectiveStreetAddress ATTRIBUTE ::= {
+ SUBTYPE OF streetAddress
+ COLLECTIVE TRUE
+ ID id-at-collectiveStreetAddress
+}
+
+houseIdentifier ATTRIBUTE ::= {
+ WITH SYNTAX DirectoryString {ub-name}
+ EQUALITY MATCHING RULE caseIgnoreMatch
+ SUBSTRINGS MATCHING RULE caseIgnoreSubstringsMatch
+ ID id-at-houseIdentifier
+}
+
+organizationName ATTRIBUTE ::= {
+ SUBTYPE OF name
+ WITH SYNTAX DirectoryString {ub-organization-name}
+ ID id-at-organizationName
+}
+
+collectiveOrganizationName ATTRIBUTE ::= {
+ SUBTYPE OF organizationName
+ COLLECTIVE TRUE
+ ID id-at-collectiveOrganizationName
+}
+
+organizationalUnitName ATTRIBUTE ::= {
+ SUBTYPE OF name
+ WITH SYNTAX DirectoryString {ub-organizational-unit-name}
+ ID id-at-organizationalUnitName
+}
+
+collectiveOrganizationalUnitName ATTRIBUTE ::= {
+ SUBTYPE OF organizationalUnitName
+ COLLECTIVE TRUE
+ ID id-at-collectiveOrganizationalUnitName
+}
+
+title ATTRIBUTE ::= {
+ SUBTYPE OF name
+ WITH SYNTAX DirectoryString {ub-title}
+ ID id-at-title
+}
+
+description ATTRIBUTE ::= {
+ WITH SYNTAX DirectoryString {ub-description}
+ EQUALITY MATCHING RULE caseIgnoreMatch
+ SUBSTRINGS MATCHING RULE caseIgnoreSubstringsMatch
+ ID id-at-description
+}
+
+searchGuide ATTRIBUTE ::= {WITH SYNTAX Guide
+ ID id-at-searchGuide
+}
+
+Guide ::= SET {
+ objectClass [0] OBJECT-CLASS.&id OPTIONAL,
+ criteria [1] Criteria
+}
+
+Criteria ::= CHOICE {
+ type [0] CriteriaItem,
+ and [1] SET OF Criteria,
+ or [2] SET OF Criteria,
+ not [3] Criteria
+}
+
+CriteriaItem ::= CHOICE {
+ equality [0] AttributeType,
+ substrings [1] AttributeType,
+ greaterOrEqual [2] AttributeType,
+ lessOrEqual [3] AttributeType,
+ approximateMatch [4] AttributeType
+}
+
+enhancedSearchGuide ATTRIBUTE ::= {
+ WITH SYNTAX EnhancedGuide
+ ID id-at-enhancedSearchGuide
+}
+
+EnhancedGuide ::= SEQUENCE {
+ objectClass [0] OBJECT-CLASS.&id,
+ criteria [1] Criteria,
+ subset
+ [2] INTEGER {baseObject(0), oneLevel(1), wholeSubtree(2)} DEFAULT oneLevel
+}
+
+businessCategory ATTRIBUTE ::= {
+ WITH SYNTAX DirectoryString {ub-business-category}
+ EQUALITY MATCHING RULE caseIgnoreMatch
+ SUBSTRINGS MATCHING RULE caseIgnoreSubstringsMatch
+ ID id-at-businessCategory
+}
+
+postalAddress ATTRIBUTE ::= {
+ WITH SYNTAX PostalAddress
+ EQUALITY MATCHING RULE caseIgnoreListMatch
+ SUBSTRINGS MATCHING RULE caseIgnoreListSubstringsMatch
+ ID id-at-postalAddress
+}
+
+PostalAddress ::=
+ SEQUENCE SIZE (1..ub-postal-line) OF DirectoryString{ub-postal-string}
+
+collectivePostalAddress ATTRIBUTE ::= {
+ SUBTYPE OF postalAddress
+ COLLECTIVE TRUE
+ ID id-at-collectivePostalAddress
+}
+
+postalCode ATTRIBUTE ::= {
+ WITH SYNTAX DirectoryString {ub-postal-code}
+ EQUALITY MATCHING RULE caseIgnoreMatch
+ SUBSTRINGS MATCHING RULE caseIgnoreSubstringsMatch
+ ID id-at-postalCode
+}
+
+collectivePostalCode ATTRIBUTE ::= {
+ SUBTYPE OF postalCode
+ COLLECTIVE TRUE
+ ID id-at-collectivePostalCode
+}
+
+postOfficeBox ATTRIBUTE ::= {
+ WITH SYNTAX DirectoryString {ub-post-office-box}
+ EQUALITY MATCHING RULE caseIgnoreMatch
+ SUBSTRINGS MATCHING RULE caseIgnoreSubstringsMatch
+ ID id-at-postOfficeBox
+}
+
+collectivePostOfficeBox ATTRIBUTE ::= {
+ SUBTYPE OF postOfficeBox
+ COLLECTIVE TRUE
+ ID id-at-collectivePostOfficeBox
+}
+
+physicalDeliveryOfficeName ATTRIBUTE ::= {
+ WITH SYNTAX DirectoryString {ub-physical-office-name}
+ EQUALITY MATCHING RULE caseIgnoreMatch
+ SUBSTRINGS MATCHING RULE caseIgnoreSubstringsMatch
+ ID id-at-physicalDeliveryOfficeName
+}
+
+collectivePhysicalDeliveryOfficeName ATTRIBUTE ::= {
+ SUBTYPE OF physicalDeliveryOfficeName
+ COLLECTIVE TRUE
+ ID id-at-collectivePhysicalDeliveryOfficeName
+}
+
+telephoneNumber ATTRIBUTE ::= {
+ WITH SYNTAX TelephoneNumber
+ EQUALITY MATCHING RULE telephoneNumberMatch
+ SUBSTRINGS MATCHING RULE telephoneNumberSubstringsMatch
+ ID id-at-telephoneNumber
+}
+
+TelephoneNumber ::= PrintableString(SIZE (1..ub-telephone-number))
+
+-- String complying with CCITT Rec. E.123 only
+collectiveTelephoneNumber ATTRIBUTE ::= {
+ SUBTYPE OF telephoneNumber
+ COLLECTIVE TRUE
+ ID id-at-collectiveTelephoneNumber
+}
+
+telexNumber ATTRIBUTE ::= {
+ WITH SYNTAX TelexNumber
+ ID id-at-telexNumber
+}
+
+TelexNumber ::= SEQUENCE {
+ telexNumber PrintableString(SIZE (1..ub-telex-number)),
+ countryCode PrintableString(SIZE (1..ub-country-code)),
+ answerback PrintableString(SIZE (1..ub-answerback))
+}
+
+collectiveTelexNumber ATTRIBUTE ::= {
+ SUBTYPE OF telexNumber
+ COLLECTIVE TRUE
+ ID id-at-collectiveTelexNumber
+}
+
+facsimileTelephoneNumber ATTRIBUTE ::= {
+ WITH SYNTAX FacsimileTelephoneNumber
+ EQUALITY MATCHING RULE facsimileNumberMatch
+ SUBSTRINGS MATCHING RULE facsimileNumberSubstringsMatch
+ ID id-at-facsimileTelephoneNumber
+}
+
+facsimileNumberMatch MATCHING-RULE ::= {
+ SYNTAX TelephoneNumber
+ ID id-mr-facsimileNumberMatch
+}
+
+facsimileNumberSubstringsMatch MATCHING-RULE ::= {
+ SYNTAX SubstringAssertion
+ ID id-mr-facsimileNumberSubstringsMatch
+}
+
+FacsimileTelephoneNumber ::= SEQUENCE {
+ telephoneNumber TelephoneNumber,
+ parameters G3FacsimileNonBasicParameters OPTIONAL
+}
+
+collectiveFacsimileTelephoneNumber ATTRIBUTE ::= {
+ SUBTYPE OF facsimileTelephoneNumber
+ COLLECTIVE TRUE
+ ID id-at-collectiveFacsimileTelephoneNumber
+}
+
+x121Address ATTRIBUTE ::= {
+ WITH SYNTAX X121Address
+ EQUALITY MATCHING RULE numericStringMatch
+ SUBSTRINGS MATCHING RULE numericStringSubstringsMatch
+ ID id-at-x121Address
+}
+
+X121Address ::= NumericString(SIZE (1..ub-x121-address))
+
+-- String as defined by ITU-T Rec. X.121
+internationalISDNNumber ATTRIBUTE ::= {
+ WITH SYNTAX InternationalISDNNumber
+ EQUALITY MATCHING RULE numericStringMatch
+ SUBSTRINGS MATCHING RULE numericStringSubstringsMatch
+ ID id-at-internationalISDNNumber
+}
+
+InternationalISDNNumber ::=
+ NumericString(SIZE (1..ub-international-isdn-number))
+
+-- String complying with ITU-T Rec. E.164 only
+collectiveInternationalISDNNumber ATTRIBUTE ::= {
+ SUBTYPE OF internationalISDNNumber
+ COLLECTIVE TRUE
+ ID id-at-collectiveInternationalISDNNumber
+}
+
+registeredAddress ATTRIBUTE ::= {
+ SUBTYPE OF postalAddress
+ WITH SYNTAX PostalAddress
+ ID id-at-registeredAddress
+}
+
+destinationIndicator ATTRIBUTE ::= {
+ WITH SYNTAX DestinationIndicator
+ EQUALITY MATCHING RULE caseIgnoreMatch
+ SUBSTRINGS MATCHING RULE caseIgnoreSubstringsMatch
+ ID id-at-destinationIndicator
+}
+
+DestinationIndicator ::= PrintableString(SIZE (1..ub-destination-indicator))
+
+communicationsService ATTRIBUTE ::= {
+ WITH SYNTAX OBJECT IDENTIFIER
+ EQUALITY MATCHING RULE objectIdentifierMatch
+ ID id-at-communicationsService
+}
+
+communicationsNetwork ATTRIBUTE ::= {
+ WITH SYNTAX OBJECT IDENTIFIER
+ EQUALITY MATCHING RULE objectIdentifierMatch
+ SINGLE VALUE TRUE
+ ID id-at-communicationsNetwork
+}
+
+-- alphabetical characters only
+preferredDeliveryMethod ATTRIBUTE ::= {
+ WITH SYNTAX PreferredDeliveryMethod
+ SINGLE VALUE TRUE
+ ID id-at-preferredDeliveryMethod
+}
+
+PreferredDeliveryMethod ::=
+ SEQUENCE OF
+ INTEGER {any-delivery-method(0), mhs-delivery(1), physical-delivery(2),
+ telex-delivery(3), teletex-delivery(4), g3-facsimile-delivery(5),
+ g4-facsimile-delivery(6), ia5-terminal-delivery(7),
+ videotex-delivery(8), telephone-delivery(9)}
+
+presentationAddress ATTRIBUTE ::= {
+ WITH SYNTAX PresentationAddress
+ EQUALITY MATCHING RULE presentationAddressMatch
+ SINGLE VALUE TRUE
+ ID id-at-presentationAddress
+}
+
+PresentationAddress ::= SEQUENCE {
+ pSelector [0] OCTET STRING OPTIONAL,
+ sSelector [1] OCTET STRING OPTIONAL,
+ tSelector [2] OCTET STRING OPTIONAL,
+ nAddresses [3] SET SIZE (1..MAX) OF OCTET STRING
+}
+
+supportedApplicationContext ATTRIBUTE ::= {
+ WITH SYNTAX OBJECT IDENTIFIER
+ EQUALITY MATCHING RULE objectIdentifierMatch
+ ID id-at-supportedApplicationContext
+}
+
+protocolInformation ATTRIBUTE ::= {
+ WITH SYNTAX ProtocolInformation
+ EQUALITY MATCHING RULE protocolInformationMatch
+ ID id-at-protocolInformation
+}
+
+ProtocolInformation ::= SEQUENCE {
+ nAddress OCTET STRING,
+ profiles SET OF OBJECT IDENTIFIER
+}
+
+distinguishedName ATTRIBUTE ::= {
+ WITH SYNTAX DistinguishedName
+ EQUALITY MATCHING RULE distinguishedNameMatch
+ ID id-at-distinguishedName
+}
+
+member ATTRIBUTE ::= {SUBTYPE OF distinguishedName
+ ID id-at-member
+}
+
+uniqueMember ATTRIBUTE ::= {
+ WITH SYNTAX NameAndOptionalUID
+ EQUALITY MATCHING RULE uniqueMemberMatch
+ ID id-at-uniqueMember
+}
+
+NameAndOptionalUID ::= SEQUENCE {
+ dn DistinguishedName,
+ uid UniqueIdentifier OPTIONAL
+}
+
+owner ATTRIBUTE ::= {SUBTYPE OF distinguishedName
+ ID id-at-owner
+}
+
+roleOccupant ATTRIBUTE ::= {
+ SUBTYPE OF distinguishedName
+ ID id-at-roleOccupant
+}
+
+seeAlso ATTRIBUTE ::= {SUBTYPE OF distinguishedName
+ ID id-at-seeAlso
+}
+
+dmdName ATTRIBUTE ::= {
+ SUBTYPE OF name
+ WITH SYNTAX DirectoryString {ub-common-name}
+ ID id-at-dmdName
+}
+
+dSAProblem ATTRIBUTE ::= {
+ WITH SYNTAX OBJECT IDENTIFIER
+ EQUALITY MATCHING RULE objectIdentifierMatch
+ ID id-not-dSAProblem
+}
+
+searchServiceProblem ATTRIBUTE ::= {
+ WITH SYNTAX OBJECT IDENTIFIER
+ EQUALITY MATCHING RULE objectIdentifierMatch
+ SINGLE VALUE TRUE
+ ID id-not-searchServiceProblem
+}
+
+serviceType ATTRIBUTE ::= {
+ WITH SYNTAX OBJECT IDENTIFIER
+ EQUALITY MATCHING RULE objectIdentifierMatch
+ SINGLE VALUE TRUE
+ ID id-not-serviceType
+}
+
+attributeTypeList ATTRIBUTE ::= {
+ WITH SYNTAX OBJECT IDENTIFIER
+ EQUALITY MATCHING RULE objectIdentifierMatch
+ ID id-not-attributeTypeList
+}
+
+filterItem ATTRIBUTE ::= {
+ WITH SYNTAX FilterItem
+ ID id-not-filterItem
+}
+
+attributeCombinations ATTRIBUTE ::= {
+ WITH SYNTAX AttributeCombination
+ ID id-not-attributeCombinations
+}
+
+contextTypeList ATTRIBUTE ::= {
+ WITH SYNTAX OBJECT IDENTIFIER
+ EQUALITY MATCHING RULE objectIdentifierMatch
+ ID id-not-contextTypeList
+}
+
+contextList ATTRIBUTE ::= {
+ WITH SYNTAX ContextAssertion
+ ID id-not-contextList
+}
+
+hierarchySelectList ATTRIBUTE ::= {
+ WITH SYNTAX HierarchySelections
+ SINGLE VALUE TRUE
+ ID id-not-hierarchySelectList
+}
+
+searchOptionsList ATTRIBUTE ::= {
+ WITH SYNTAX SearchControlOptions
+ SINGLE VALUE TRUE
+ ID id-not-searchOptionsList
+}
+
+serviceControlOptionsList ATTRIBUTE ::= {
+ WITH SYNTAX ServiceControlOptions
+ SINGLE VALUE TRUE
+ ID id-not-serviceControlOptionsList
+}
+
+multipleMatchingLocalities ATTRIBUTE ::= {
+ WITH SYNTAX MultipleMatchingLocalities
+ ID id-not-multipleMatchingLocalities
+}
+
+MultipleMatchingLocalities ::= SEQUENCE {
+ matchingRuleUsed MATCHING-RULE.&id OPTIONAL,
+ attributeList SEQUENCE OF AttributeValueAssertion
+}
+
+proposedRelaxation ATTRIBUTE ::= {
+ WITH SYNTAX SEQUENCE OF MRMapping
+ ID id-not-proposedRelaxation
+}
+
+appliedRelaxation ATTRIBUTE ::= {
+ WITH SYNTAX OBJECT IDENTIFIER
+ EQUALITY MATCHING RULE objectIdentifierMatch
+ ID id-not-appliedRelaxation
+}
+
+-- Matching rules
+caseIgnoreMatch MATCHING-RULE ::= {
+ SYNTAX DirectoryString {ub-match}
+ ID id-mr-caseIgnoreMatch
+}
+
+caseIgnoreOrderingMatch MATCHING-RULE ::= {
+ SYNTAX DirectoryString {ub-match}
+ ID id-mr-caseIgnoreOrderingMatch
+}
+
+caseIgnoreSubstringsMatch MATCHING-RULE ::= {
+ SYNTAX SubstringAssertion
+ ID id-mr-caseIgnoreSubstringsMatch
+}
+
+SubstringAssertion ::=
+ SEQUENCE OF
+ CHOICE {initial [0] DirectoryString{ub-match},
+ any [1] DirectoryString{ub-match},
+ final [2] DirectoryString{ub-match},
+ control Attribute
+ } -- Used to specify interpretation of the following items
+
+-- at most one initial and one final component
+caseExactMatch MATCHING-RULE ::= {
+ SYNTAX DirectoryString {ub-match}
+ ID id-mr-caseExactMatch
+}
+
+caseExactOrderingMatch MATCHING-RULE ::= {
+ SYNTAX DirectoryString {ub-match}
+ ID id-mr-caseExactOrderingMatch
+}
+
+caseExactSubstringsMatch MATCHING-RULE ::= {
+ SYNTAX SubstringAssertion -- only the PrintableString choice
+ ID id-mr-caseExactSubstringsMatch
+}
+
+numericStringMatch MATCHING-RULE ::= {
+ SYNTAX NumericString
+ ID id-mr-numericStringMatch
+}
+
+numericStringOrderingMatch MATCHING-RULE ::= {
+ SYNTAX NumericString
+ ID id-mr-numericStringOrderingMatch
+}
+
+numericStringSubstringsMatch MATCHING-RULE ::= {
+ SYNTAX SubstringAssertion
+ ID id-mr-numericStringSubstringsMatch
+}
+
+caseIgnoreListMatch MATCHING-RULE ::= {
+ SYNTAX CaseIgnoreListMatch
+ ID id-mr-caseIgnoreListMatch
+}
+
+CaseIgnoreListMatch ::= SEQUENCE OF DirectoryString{ub-match}
+
+caseIgnoreListSubstringsMatch MATCHING-RULE ::= {
+ SYNTAX SubstringAssertion
+ ID id-mr-caseIgnoreListSubstringsMatch
+}
+
+storedPrefixMatch MATCHING-RULE ::= {
+ SYNTAX DirectoryString {ub-match}
+ ID id-mr-storedPrefixMatch
+}
+
+booleanMatch MATCHING-RULE ::= {SYNTAX BOOLEAN
+ ID id-mr-booleanMatch
+}
+
+integerMatch MATCHING-RULE ::= {SYNTAX INTEGER
+ ID id-mr-integerMatch
+}
+
+integerOrderingMatch MATCHING-RULE ::= {
+ SYNTAX INTEGER
+ ID id-mr-integerOrderingMatch
+}
+
+bitStringMatch MATCHING-RULE ::= {
+ SYNTAX BIT STRING
+ ID id-mr-bitStringMatch
+}
+
+octetStringMatch MATCHING-RULE ::= {
+ SYNTAX OCTET STRING
+ ID id-mr-octetStringMatch
+}
+
+octetStringOrderingMatch MATCHING-RULE ::= {
+ SYNTAX OCTET STRING
+ ID id-mr-octetStringOrderingMatch
+}
+
+octetStringSubstringsMatch MATCHING-RULE ::= {
+ SYNTAX OctetSubstringAssertion
+ ID id-mr-octetStringSubstringsMatch
+}
+
+OctetSubstringAssertion ::=
+ SEQUENCE OF
+ CHOICE {initial [0] OCTET STRING,
+ any [1] OCTET STRING,
+ final [2] OCTET STRING}
+
+-- at most one initial and one final component
+telephoneNumberMatch MATCHING-RULE ::= {
+ SYNTAX TelephoneNumber
+ ID id-mr-telephoneNumberMatch
+}
+
+telephoneNumberSubstringsMatch MATCHING-RULE ::= {
+ SYNTAX SubstringAssertion
+ ID id-mr-telephoneNumberSubstringsMatch
+}
+
+presentationAddressMatch MATCHING-RULE ::= {
+ SYNTAX PresentationAddress
+ ID id-mr-presentationAddressMatch
+}
+
+uniqueMemberMatch MATCHING-RULE ::= {
+ SYNTAX NameAndOptionalUID
+ ID id-mr-uniqueMemberMatch
+}
+
+protocolInformationMatch MATCHING-RULE ::= {
+ SYNTAX OCTET STRING
+ ID id-mr-protocolInformationMatch
+}
+
+uTCTimeMatch MATCHING-RULE ::= {SYNTAX UTCTime
+ ID id-mr-uTCTimeMatch
+}
+
+uTCTimeOrderingMatch MATCHING-RULE ::= {
+ SYNTAX UTCTime
+ ID id-mr-uTCTimeOrderingMatch
+}
+
+generalizedTimeMatch MATCHING-RULE ::= {
+ SYNTAX GeneralizedTime
+ -- as per 41.3 b) or c) of ITU-T Rec. X.680 | ISO/IEC 8824-1
+ ID id-mr-generalizedTimeMatch
+}
+
+generalizedTimeOrderingMatch MATCHING-RULE ::= {
+ SYNTAX GeneralizedTime
+ -- as per 41.3 b) or c) of ITU-T Rec. X.680 | ISO/IEC 8824-1
+ ID id-mr-generalizedTimeOrderingMatch
+}
+
+integerFirstComponentMatch MATCHING-RULE ::= {
+ SYNTAX INTEGER
+ ID id-mr-integerFirstComponentMatch
+}
+
+objectIdentifierFirstComponentMatch MATCHING-RULE ::= {
+ SYNTAX OBJECT IDENTIFIER
+ ID id-mr-objectIdentifierFirstComponentMatch
+}
+
+directoryStringFirstComponentMatch MATCHING-RULE ::= {
+ SYNTAX DirectoryString {ub-directory-string-first-component-match}
+ ID id-mr-directoryStringFirstComponentMatch
+}
+
+wordMatch MATCHING-RULE ::= {
+ SYNTAX DirectoryString {ub-match}
+ ID id-mr-wordMatch
+}
+
+keywordMatch MATCHING-RULE ::= {
+ SYNTAX DirectoryString {ub-match}
+ ID id-mr-keywordMatch
+}
+
+systemProposedMatch MATCHING-RULE ::= {ID id-mr-systemProposedMatch
+}
+
+generalWordMatch MATCHING-RULE ::= {
+ SYNTAX SubstringAssertion
+ ID id-mr-generalWordMatch
+}
+
+sequenceMatchType ATTRIBUTE ::= {
+ WITH SYNTAX
+ ENUMERATED {sequenceExact(0), sequenceDeletion(1),
+ sequenceRestrictedDeletion(2), sequencePermutation(3),
+ sequencePermutationAndDeletion(4), sequenceProviderDefined(5)}
+ SINGLE VALUE TRUE
+ ID id-cat-sequenceMatchType
+} -- defaulting to sequenceExact,
+
+wordMatchTypes ATTRIBUTE ::= {
+ WITH SYNTAX
+ ENUMERATED {wordExact(0), wordTruncated(1), wordPhonetic(2),
+ wordProviderDefined(3)}
+ SINGLE VALUE TRUE
+ ID id-cat-wordMatchType
+} -- defaulting to wordExact
+
+characterMatchTypes ATTRIBUTE ::= {
+ WITH SYNTAX
+ ENUMERATED {characterExact(0), characterCaseIgnore(1), characterMapped(2)}
+ SINGLE VALUE TRUE
+ ID id-cat-characterMatchTypes
+}
+
+selectedContexts ATTRIBUTE ::= {
+ WITH SYNTAX ContextAssertion
+ ID id-cat-selectedContexts
+}
+
+approximateStringMatch MATCHING-RULE ::= {ID id-mr-approximateStringMatch
+}
+
+ignoreIfAbsentMatch MATCHING-RULE ::= {ID id-mr-ignoreIfAbsentMatch
+}
+
+nullMatch MATCHING-RULE ::= {ID id-mr-nullMatch
+}
+
+ZONAL-MATCHING ::=
+ MAPPING-BASED-MATCHING{ZonalSelect, TRUE, ZonalResult, zonalMatch.&id}
+
+ZonalSelect ::= SEQUENCE OF AttributeType
+
+ZonalResult ::= ENUMERATED {
+ cannot-select-mapping(0), zero-mappings(2), multiple-mappings(3)}
+
+zonalMatch MATCHING-RULE ::= {
+ UNIQUE-MATCH-INDICATOR multipleMatchingLocalities.&id
+ ID id-mr-zonalMatch
+}
+
+-- Contexts
+languageContext CONTEXT ::= {
+ WITH SYNTAX LanguageContextSyntax
+ ID id-avc-language
+}
+
+LanguageContextSyntax ::= PrintableString(SIZE (2..3)) -- ISO 639-2 codes only
+
+
+temporalContext CONTEXT ::= {
+ WITH SYNTAX TimeSpecification
+ ASSERTED AS TimeAssertion
+ ID id-avc-temporal
+}
+
+TimeSpecification ::= SEQUENCE {
+ time
+ CHOICE {absolute
+ SEQUENCE {startTime [0] GeneralizedTime OPTIONAL,
+ endTime [1] GeneralizedTime OPTIONAL},
+ periodic SET OF Period},
+ notThisTime BOOLEAN DEFAULT FALSE,
+ timeZone TimeZone OPTIONAL
+}
+
+Period ::= SEQUENCE {
+ timesOfDay [0] SET SIZE (1..MAX) OF DayTimeBand OPTIONAL,
+ days
+ [1] CHOICE {intDay SET OF INTEGER,
+ bitDay
+ BIT STRING {sunday(0), monday(1), tuesday(2), wednesday(3),
+ thursday(4), friday(5), saturday(6)},
+ dayOf XDayOf} OPTIONAL,
+ weeks
+ [2] CHOICE {allWeeks NULL,
+ intWeek SET OF INTEGER,
+ bitWeek
+ BIT STRING {week1(0), week2(1), week3(2), week4(3), week5(4)}
+ } OPTIONAL,
+ months
+ [3] CHOICE {allMonths NULL,
+ intMonth SET OF INTEGER,
+ bitMonth
+ BIT STRING {january(0), february(1), march(2), april(3),
+ may(4), june(5), july(6), august(7),
+ september(8), october(9), november(10),
+ december(11)}} OPTIONAL,
+ years [4] SET OF INTEGER(1000..MAX) OPTIONAL
+}
+
+XDayOf ::= CHOICE {
+ first [1] NamedDay,
+ second [2] NamedDay,
+ third [3] NamedDay,
+ fourth [4] NamedDay,
+ fifth [5] NamedDay
+}
+
+NamedDay ::= CHOICE {
+ intNamedDays
+ ENUMERATED {sunday(1), monday(2), tuesday(3), wednesday(4), thursday(5),
+ friday(6), saturday(7)},
+ bitNamedDays
+ BIT STRING {sunday(0), monday(1), tuesday(2), wednesday(3), thursday(4),
+ friday(5), saturday(6)}
+}
+
+DayTimeBand ::= SEQUENCE {
+ startDayTime [0] DayTime DEFAULT {hour 0},
+ endDayTime [1] DayTime DEFAULT {hour 23, minute 59, second 59}
+}
+
+DayTime ::= SEQUENCE {
+ hour [0] INTEGER(0..23),
+ minute [1] INTEGER(0..59) DEFAULT 0,
+ second [2] INTEGER(0..59) DEFAULT 0
+}
+
+TimeZone ::= INTEGER(-12..12)
+
+TimeAssertion ::= CHOICE {
+ now NULL,
+ at GeneralizedTime,
+ between
+ SEQUENCE {startTime [0] GeneralizedTime,
+ endTime [1] GeneralizedTime OPTIONAL,
+ entirely BOOLEAN DEFAULT FALSE}
+}
+
+localeContext CONTEXT ::= {
+ WITH SYNTAX LocaleContextSyntax
+ ID id-avc-locale
+}
+
+LocaleContextSyntax ::= CHOICE {
+ localeID1 OBJECT IDENTIFIER,
+ localeID2 DirectoryString{ub-localeContextSyntax}
+}
+
+-- Object identifier assignments -
+-- object identifiers assigned in other modules are shown in comments
+-- Attributes
+-- id-at-objectClass OBJECT IDENTIFIER ::= {id-at 0}
+-- id-at-aliasedEntryName OBJECT IDENTIFIER ::= {id-at 1}
+id-at-encryptedAliasedEntryName OBJECT IDENTIFIER ::=
+ {id-at 1 2}
+
+id-at-knowledgeInformation OBJECT IDENTIFIER ::= {id-at 2}
+
+id-at-commonName OBJECT IDENTIFIER ::= {id-at 3}
+
+id-at-encryptedCommonName OBJECT IDENTIFIER ::= {id-at 3 2}
+
+id-at-surname OBJECT IDENTIFIER ::= {id-at 4}
+
+id-at-encryptedSurname OBJECT IDENTIFIER ::= {id-at 4 2}
+
+id-at-serialNumber OBJECT IDENTIFIER ::= {id-at 5}
+
+id-at-encryptedSerialNumber OBJECT IDENTIFIER ::= {id-at 5 2}
+
+id-at-countryName OBJECT IDENTIFIER ::= {id-at 6}
+
+id-at-encryptedCountryName OBJECT IDENTIFIER ::= {id-at 6 2}
+
+id-at-localityName OBJECT IDENTIFIER ::= {id-at 7}
+
+id-at-encryptedLocalityName OBJECT IDENTIFIER ::= {id-at 7 2}
+
+id-at-collectiveLocalityName OBJECT IDENTIFIER ::= {id-at 7 1}
+
+id-at-encryptedCollectiveLocalityName OBJECT IDENTIFIER ::= {id-at 7 1 2}
+
+id-at-stateOrProvinceName OBJECT IDENTIFIER ::= {id-at 8}
+
+id-at-encryptedStateOrProvinceName OBJECT IDENTIFIER ::= {id-at 8 2}
+
+id-at-collectiveStateOrProvinceName OBJECT IDENTIFIER ::= {id-at 8 1}
+
+id-at-encryptedCollectiveStateOrProvinceName OBJECT IDENTIFIER ::=
+ {id-at 8 1 2}
+
+id-at-streetAddress OBJECT IDENTIFIER ::= {id-at 9}
+
+id-at-encryptedStreetAddress OBJECT IDENTIFIER ::= {id-at 9 2}
+
+id-at-collectiveStreetAddress OBJECT IDENTIFIER ::= {id-at 9 1}
+
+id-at-encryptedCollectiveStreetAddress OBJECT IDENTIFIER ::= {id-at 9 1 2}
+
+id-at-organizationName OBJECT IDENTIFIER ::= {id-at 10}
+
+id-at-encryptedOrganizationName OBJECT IDENTIFIER ::= {id-at 10 2}
+
+id-at-collectiveOrganizationName OBJECT IDENTIFIER ::= {id-at 10 1}
+
+id-at-encryptedCollectiveOrganizationName OBJECT IDENTIFIER ::= {id-at 10 1 2}
+
+id-at-organizationalUnitName OBJECT IDENTIFIER ::= {id-at 11}
+
+id-at-encryptedOrganizationalUnitName OBJECT IDENTIFIER ::= {id-at 11 2}
+
+id-at-collectiveOrganizationalUnitName OBJECT IDENTIFIER ::= {id-at 11 1}
+
+id-at-encryptedCollectiveOrganizationalUnitName OBJECT IDENTIFIER ::=
+ {id-at 11 1 2}
+
+id-at-title OBJECT IDENTIFIER ::= {id-at 12}
+
+id-at-encryptedTitle OBJECT IDENTIFIER ::= {id-at 12 2}
+
+id-at-description OBJECT IDENTIFIER ::= {id-at 13}
+
+id-at-encryptedDescription OBJECT IDENTIFIER ::= {id-at 13 2}
+
+id-at-searchGuide OBJECT IDENTIFIER ::= {id-at 14}
+
+id-at-encryptedSearchGuide OBJECT IDENTIFIER ::= {id-at 14 2}
+
+id-at-businessCategory OBJECT IDENTIFIER ::= {id-at 15}
+
+id-at-encryptedBusinessCategory OBJECT IDENTIFIER ::= {id-at 15 2}
+
+id-at-postalAddress OBJECT IDENTIFIER ::= {id-at 16}
+
+id-at-encryptedPostalAddress OBJECT IDENTIFIER ::= {id-at 16 2}
+
+id-at-collectivePostalAddress OBJECT IDENTIFIER ::= {id-at 16 1}
+
+id-at-encryptedCollectivePostalAddress OBJECT IDENTIFIER ::= {id-at 16 1 2}
+
+id-at-postalCode OBJECT IDENTIFIER ::= {id-at 17}
+
+id-at-encryptedPostalCode OBJECT IDENTIFIER ::= {id-at 17 2}
+
+id-at-collectivePostalCode OBJECT IDENTIFIER ::= {id-at 17 1}
+
+id-at-encryptedCollectivePostalCode OBJECT IDENTIFIER ::= {id-at 17 1 2}
+
+id-at-postOfficeBox OBJECT IDENTIFIER ::= {id-at 18}
+
+id-at-encryptedPostOfficeBox OBJECT IDENTIFIER ::= {id-at 18 2}
+
+id-at-collectivePostOfficeBox OBJECT IDENTIFIER ::= {id-at 18 1}
+
+id-at-encryptedCollectivePostOfficeBox OBJECT IDENTIFIER ::= {id-at 18 1 2}
+
+id-at-physicalDeliveryOfficeName OBJECT IDENTIFIER ::= {id-at 19}
+
+id-at-encryptedPhysicalDeliveryOfficeName OBJECT IDENTIFIER ::= {id-at 19 2}
+
+id-at-collectivePhysicalDeliveryOfficeName OBJECT IDENTIFIER ::= {id-at 19 1}
+
+id-at-encryptedCollectivePhysicalDeliveryOfficeName OBJECT IDENTIFIER ::=
+ {id-at 19 1 2}
+
+id-at-telephoneNumber OBJECT IDENTIFIER ::= {id-at 20}
+
+id-at-encryptedTelephoneNumber OBJECT IDENTIFIER ::= {id-at 20 2}
+
+id-at-collectiveTelephoneNumber OBJECT IDENTIFIER ::= {id-at 20 1}
+
+id-at-encryptedCollectiveTelephoneNumber OBJECT IDENTIFIER ::= {id-at 20 1 2}
+
+id-at-telexNumber OBJECT IDENTIFIER ::= {id-at 21}
+
+id-at-encryptedTelexNumber OBJECT IDENTIFIER ::= {id-at 21 2}
+
+id-at-collectiveTelexNumber OBJECT IDENTIFIER ::= {id-at 21 1}
+
+id-at-encryptedCollectiveTelexNumber OBJECT IDENTIFIER ::= {id-at 21 1 2}
+
+-- id-at-teletexTerminalIdentifier OBJECT IDENTIFIER ::= {id-at 22}
+-- id-at-encryptedTeletexTerminalIdentifier OBJECT IDENTIFIER ::= {id-at 22 2}
+-- id-at-collectiveTeletexTerminalIdentifier OBJECT IDENTIFIER ::= {id-at 22 1}
+-- id-at-encryptedCollectiveTeletexTerminalIdentifier
+-- OBJECT IDENTIFIER ::= {id-at 22 1 2}
+id-at-facsimileTelephoneNumber OBJECT IDENTIFIER ::=
+ {id-at 23}
+
+id-at-encryptedFacsimileTelephoneNumber OBJECT IDENTIFIER ::= {id-at 23 2}
+
+id-at-collectiveFacsimileTelephoneNumber OBJECT IDENTIFIER ::= {id-at 23 1}
+
+id-at-encryptedCollectiveFacsimileTelephoneNumber OBJECT IDENTIFIER ::=
+ {id-at 23 1 2}
+
+id-at-x121Address OBJECT IDENTIFIER ::= {id-at 24}
+
+id-at-encryptedX121Address OBJECT IDENTIFIER ::= {id-at 24 2}
+
+id-at-internationalISDNNumber OBJECT IDENTIFIER ::= {id-at 25}
+
+id-at-encryptedInternationalISDNNumber OBJECT IDENTIFIER ::= {id-at 25 2}
+
+id-at-collectiveInternationalISDNNumber OBJECT IDENTIFIER ::= {id-at 25 1}
+
+id-at-encryptedCollectiveInternationalISDNNumber OBJECT IDENTIFIER ::=
+ {id-at 25 1 2}
+
+id-at-registeredAddress OBJECT IDENTIFIER ::= {id-at 26}
+
+id-at-encryptedRegisteredAddress OBJECT IDENTIFIER ::= {id-at 26 2}
+
+id-at-destinationIndicator OBJECT IDENTIFIER ::= {id-at 27}
+
+id-at-encryptedDestinationIndicator OBJECT IDENTIFIER ::= {id-at 27 2}
+
+id-at-preferredDeliveryMethod OBJECT IDENTIFIER ::= {id-at 28}
+
+id-at-encryptedPreferredDeliveryMethod OBJECT IDENTIFIER ::= {id-at 28 2}
+
+id-at-presentationAddress OBJECT IDENTIFIER ::= {id-at 29}
+
+id-at-encryptedPresentationAddress OBJECT IDENTIFIER ::= {id-at 29 2}
+
+id-at-supportedApplicationContext OBJECT IDENTIFIER ::= {id-at 30}
+
+id-at-encryptedSupportedApplicationContext OBJECT IDENTIFIER ::= {id-at 30 2}
+
+id-at-member OBJECT IDENTIFIER ::= {id-at 31}
+
+id-at-encryptedMember OBJECT IDENTIFIER ::= {id-at 31 2}
+
+id-at-owner OBJECT IDENTIFIER ::= {id-at 32}
+
+id-at-encryptedOwner OBJECT IDENTIFIER ::= {id-at 32 2}
+
+id-at-roleOccupant OBJECT IDENTIFIER ::= {id-at 33}
+
+id-at-encryptedRoleOccupant OBJECT IDENTIFIER ::= {id-at 33 2}
+
+id-at-seeAlso OBJECT IDENTIFIER ::= {id-at 34}
+
+id-at-encryptedSeeAlso OBJECT IDENTIFIER ::= {id-at 34 2}
+
+-- id-at-userPassword OBJECT IDENTIFIER ::= {id-at 35}
+id-at-encryptedUserPassword OBJECT IDENTIFIER ::=
+ {id-at 35 2}
+
+-- id-at-userCertificate OBJECT IDENTIFIER ::= {id-at 36}
+id-at-encryptedUserCertificate OBJECT IDENTIFIER ::=
+ {id-at 36 2}
+
+-- id-at-cACertificate OBJECT IDENTIFIER ::= {id-at 37}
+id-at-encryptedCACertificate OBJECT IDENTIFIER ::=
+ {id-at 37 2}
+
+-- id-at-authorityRevocationList OBJECT IDENTIFIER ::= {id-at 38}
+id-at-encryptedAuthorityRevocationList OBJECT IDENTIFIER ::=
+ {id-at 38 2}
+
+-- id-at-certificateRevocationList OBJECT IDENTIFIER ::= {id-at 39}
+id-at-encryptedCertificateRevocationList OBJECT IDENTIFIER ::=
+ {id-at 39 2}
+
+-- id-at-crossCertificatePair OBJECT IDENTIFIER ::= {id-at 40}
+id-at-encryptedCrossCertificatePair OBJECT IDENTIFIER ::=
+ {id-at 40 2}
+
+id-at-name OBJECT IDENTIFIER ::= {id-at 41}
+
+id-at-givenName OBJECT IDENTIFIER ::= {id-at 42}
+
+id-at-encryptedGivenName OBJECT IDENTIFIER ::= {id-at 42 2}
+
+id-at-initials OBJECT IDENTIFIER ::= {id-at 43}
+
+id-at-encryptedInitials OBJECT IDENTIFIER ::= {id-at 43 2}
+
+id-at-generationQualifier OBJECT IDENTIFIER ::= {id-at 44}
+
+id-at-encryptedGenerationQualifier OBJECT IDENTIFIER ::= {id-at 44 2}
+
+id-at-uniqueIdentifier OBJECT IDENTIFIER ::= {id-at 45}
+
+id-at-encryptedUniqueIdentifier OBJECT IDENTIFIER ::= {id-at 45 2}
+
+id-at-dnQualifier OBJECT IDENTIFIER ::= {id-at 46}
+
+id-at-encryptedDnQualifier OBJECT IDENTIFIER ::= {id-at 46 2}
+
+id-at-enhancedSearchGuide OBJECT IDENTIFIER ::= {id-at 47}
+
+id-at-encryptedEnhancedSearchGuide OBJECT IDENTIFIER ::= {id-at 47 2}
+
+id-at-protocolInformation OBJECT IDENTIFIER ::= {id-at 48}
+
+id-at-encryptedProtocolInformation OBJECT IDENTIFIER ::= {id-at 48 2}
+
+id-at-distinguishedName OBJECT IDENTIFIER ::= {id-at 49}
+
+id-at-encryptedDistinguishedName OBJECT IDENTIFIER ::= {id-at 49 2}
+
+id-at-uniqueMember OBJECT IDENTIFIER ::= {id-at 50}
+
+id-at-encryptedUniqueMember OBJECT IDENTIFIER ::= {id-at 50 2}
+
+id-at-houseIdentifier OBJECT IDENTIFIER ::= {id-at 51}
+
+id-at-encryptedHouseIdentifier OBJECT IDENTIFIER ::= {id-at 51 2}
+
+--id-at-supportedAlgorithms OBJECT IDENTIFIER ::= {id-at 52}
+id-at-encryptedSupportedAlgorithms OBJECT IDENTIFIER ::=
+ {id-at 52 2}
+
+--id-at-deltaRevocationList OBJECT IDENTIFIER ::= {id-at 53}
+id-at-encryptedDeltaRevocationList OBJECT IDENTIFIER ::=
+ {id-at 53 2}
+
+id-at-dmdName OBJECT IDENTIFIER ::= {id-at 54}
+
+id-at-encryptedDmdName OBJECT IDENTIFIER ::= {id-at 54 2}
+
+-- id-at-clearance OBJECT IDENTIFIER ::= {id-at 55}
+id-at-encryptedClearance OBJECT IDENTIFIER ::=
+ {id-at 55 2}
+
+-- id-at-defaultDirQop OBJECT IDENTIFIER ::= {id-at 56}
+id-at-encryptedDefaultDirQop OBJECT IDENTIFIER ::=
+ {id-at 56 2}
+
+-- id-at-attributeIntegrityInfo OBJECT IDENTIFIER ::= {id-at 57}
+id-at-encryptedAttributeIntegrityInfo OBJECT IDENTIFIER ::=
+ {id-at 57 2}
+
+--id-at-attributeCertificate OBJECT IDENTIFIER ::= {id-at 58}
+id-at-encryptedAttributeCertificate OBJECT IDENTIFIER ::=
+ {id-at 58 2}
+
+-- id-at-attributeCertificateRevocationList OBJECT IDENTIFIER ::= {id-at 59}
+id-at-encryptedAttributeCertificateRevocationList OBJECT IDENTIFIER ::=
+ {id-at 59 2}
+
+-- id-at-confKeyInfo OBJECT IDENTIFIER ::= {id-at 60}
+id-at-encryptedConfKeyInfo OBJECT IDENTIFIER ::=
+ {id-at 60 2}
+
+-- id-at-family-information OBJECT IDENTIFIER {id-at 64}
+id-at-pseudonym OBJECT IDENTIFIER ::=
+ {id-at 65}
+
+id-at-communicationsService OBJECT IDENTIFIER ::= {id-at 66}
+
+id-at-communicationsNetwork OBJECT IDENTIFIER ::= {id-at 67}
+
+-- Matching rules
+-- id-mr-objectIdentifierMatch OBJECT IDENTIFIER ::= {id-mr 0}
+-- id-mr-distinguishedNameMatch OBJECT IDENTIFIER ::= {id-mr 1}
+id-mr-caseIgnoreMatch OBJECT IDENTIFIER ::=
+ {id-mr 2}
+
+id-mr-caseIgnoreOrderingMatch OBJECT IDENTIFIER ::= {id-mr 3}
+
+id-mr-caseIgnoreSubstringsMatch OBJECT IDENTIFIER ::= {id-mr 4}
+
+id-mr-caseExactMatch OBJECT IDENTIFIER ::= {id-mr 5}
+
+id-mr-caseExactOrderingMatch OBJECT IDENTIFIER ::= {id-mr 6}
+
+id-mr-caseExactSubstringsMatch OBJECT IDENTIFIER ::= {id-mr 7}
+
+id-mr-numericStringMatch OBJECT IDENTIFIER ::= {id-mr 8}
+
+id-mr-numericStringOrderingMatch OBJECT IDENTIFIER ::= {id-mr 9}
+
+id-mr-numericStringSubstringsMatch OBJECT IDENTIFIER ::= {id-mr 10}
+
+id-mr-caseIgnoreListMatch OBJECT IDENTIFIER ::= {id-mr 11}
+
+id-mr-caseIgnoreListSubstringsMatch OBJECT IDENTIFIER ::= {id-mr 12}
+
+id-mr-booleanMatch OBJECT IDENTIFIER ::= {id-mr 13}
+
+id-mr-integerMatch OBJECT IDENTIFIER ::= {id-mr 14}
+
+id-mr-integerOrderingMatch OBJECT IDENTIFIER ::= {id-mr 15}
+
+id-mr-bitStringMatch OBJECT IDENTIFIER ::= {id-mr 16}
+
+id-mr-octetStringMatch OBJECT IDENTIFIER ::= {id-mr 17}
+
+id-mr-octetStringOrderingMatch OBJECT IDENTIFIER ::= {id-mr 18}
+
+id-mr-octetStringSubstringsMatch OBJECT IDENTIFIER ::= {id-mr 19}
+
+id-mr-telephoneNumberMatch OBJECT IDENTIFIER ::= {id-mr 20}
+
+id-mr-telephoneNumberSubstringsMatch OBJECT IDENTIFIER ::= {id-mr 21}
+
+id-mr-presentationAddressMatch OBJECT IDENTIFIER ::= {id-mr 22}
+
+id-mr-uniqueMemberMatch OBJECT IDENTIFIER ::= {id-mr 23}
+
+id-mr-protocolInformationMatch OBJECT IDENTIFIER ::= {id-mr 24}
+
+id-mr-uTCTimeMatch OBJECT IDENTIFIER ::= {id-mr 25}
+
+id-mr-uTCTimeOrderingMatch OBJECT IDENTIFIER ::= {id-mr 26}
+
+id-mr-generalizedTimeMatch OBJECT IDENTIFIER ::= {id-mr 27}
+
+id-mr-generalizedTimeOrderingMatch OBJECT IDENTIFIER ::= {id-mr 28}
+
+id-mr-integerFirstComponentMatch OBJECT IDENTIFIER ::= {id-mr 29}
+
+id-mr-objectIdentifierFirstComponentMatch OBJECT IDENTIFIER ::= {id-mr 30}
+
+id-mr-directoryStringFirstComponentMatch OBJECT IDENTIFIER ::= {id-mr 31}
+
+id-mr-wordMatch OBJECT IDENTIFIER ::= {id-mr 32}
+
+id-mr-keywordMatch OBJECT IDENTIFIER ::= {id-mr 33}
+
+-- id-mr-certificateExactMatch OBJECT IDENTIFIER ::= {id-mr 34}
+-- id-mr-certificateMatch OBJECT IDENTIFIER ::= {id-mr 35}
+-- id-mr-certificatePairExactMatch OBJECT IDENTIFIER ::= {id-mr 36}
+-- id-mr-certificatePairMatch OBJECT IDENTIFIER ::= {id-mr 37}
+-- id-mr-certificateListExactMatch OBJECT IDENTIFIER ::= {id-mr 38}
+-- id-mr-certificateListMatch OBJECT IDENTIFIER ::= {id-mr 39}
+-- id-mr-algorithmIdentifierMatch OBJECT IDENTIFIER ::= {id-mr 40}
+id-mr-storedPrefixMatch OBJECT IDENTIFIER ::=
+ {id-mr 41}
+
+-- id-mr-attributeCertificateMatch OBJECT IDENTIFIER ::= {id-mr 42}
+-- id-mr-readerAndKeyIDMatch OBJECT IDENTIFIER ::= {id-mr 43}
+--id-mr-attributeIntegrityMatch OBJECT IDENTIFIER ::= {id-mr 44}
+id-mr-systemProposedMatch OBJECT IDENTIFIER ::=
+ {id-mr 47}
+
+id-mr-generalWordMatch OBJECT IDENTIFIER ::= {id-mr 48}
+
+id-mr-approximateStringMatch OBJECT IDENTIFIER ::= {id-mr 49}
+
+id-mr-ignoreIfAbsentMatch OBJECT IDENTIFIER ::= {id-mr 50}
+
+id-mr-nullMatch OBJECT IDENTIFIER ::= {id-mr 51}
+
+id-mr-zonalMatch OBJECT IDENTIFIER ::= {id-mr 52}
+
+id-mr-facsimileNumberMatch OBJECT IDENTIFIER ::= {id-mr 63}
+
+id-mr-facsimileNumberSubstringsMatch OBJECT IDENTIFIER ::= {id-mr 64}
+
+-- contexts
+id-avc-language OBJECT IDENTIFIER ::= {id-avc 0}
+
+id-avc-temporal OBJECT IDENTIFIER ::= {id-avc 1}
+
+id-avc-locale OBJECT IDENTIFIER ::= {id-avc 2}
+
+--id-avc-attributeValueSecurityLabelContext OBJECT IDENTIFIER ::= {id-avc 3}
+--id-avc-attributeValueIntegrityInfoContext OBJECT IDENTIFIER ::= {id-avc 4}
+-- Problem definitions
+id-pr-targetDsaUnavailable OBJECT IDENTIFIER ::=
+ {id-pr 1}
+
+id-pr-dataSourceUnavailable OBJECT IDENTIFIER ::= {id-pr 2}
+
+id-pr-unidentifiedOperation OBJECT IDENTIFIER ::= {id-pr 3}
+
+id-pr-unavailableOperation OBJECT IDENTIFIER ::= {id-pr 4}
+
+id-pr-searchAttributeViolation OBJECT IDENTIFIER ::= {id-pr 5}
+
+id-pr-searchAttributeCombinationViolation OBJECT IDENTIFIER ::= {id-pr 6}
+
+id-pr-searchValueNotAllowed OBJECT IDENTIFIER ::= {id-pr 7}
+
+id-pr-missingSearchAttribute OBJECT IDENTIFIER ::= {id-pr 8}
+
+id-pr-searchValueViolation OBJECT IDENTIFIER ::= {id-pr 9}
+
+id-pr-attributeNegationViolation OBJECT IDENTIFIER ::= {id-pr 10}
+
+id-pr-searchValueRequired OBJECT IDENTIFIER ::= {id-pr 11}
+
+id-pr-invalidSearchValue OBJECT IDENTIFIER ::= {id-pr 12}
+
+id-pr-searchContextViolation OBJECT IDENTIFIER ::= {id-pr 13}
+
+id-pr-searchContextCombinationViolation OBJECT IDENTIFIER ::= {id-pr 14}
+
+id-pr-missingSearchContext OBJECT IDENTIFIER ::= {id-pr 15}
+
+id-pr-searchContextValueViolation OBJECT IDENTIFIER ::= {id-pr 16}
+
+id-pr-searchContextValueRequired OBJECT IDENTIFIER ::= {id-pr 17}
+
+id-pr-invalidContextSearchValue OBJECT IDENTIFIER ::= {id-pr 18}
+
+id-pr-unsupportedMatchingRule OBJECT IDENTIFIER ::= {id-pr 19}
+
+id-pr-attributeMatchingViolation OBJECT IDENTIFIER ::= {id-pr 20}
+
+id-pr-unsupportedMatchingUse OBJECT IDENTIFIER ::= {id-pr 21}
+
+id-pr-matchingUseViolation OBJECT IDENTIFIER ::= {id-pr 22}
+
+id-pr-hierarchySelectForbidden OBJECT IDENTIFIER ::= {id-pr 23}
+
+id-pr-invalidHierarchySelect OBJECT IDENTIFIER ::= {id-pr 24}
+
+id-pr-unavailableHierarchySelect OBJECT IDENTIFIER ::= {id-pr 25}
+
+id-pr-invalidSearchOptions OBJECT IDENTIFIER ::= {id-pr 26}
+
+id-pr-missingSearchOptions OBJECT IDENTIFIER ::= {id-pr 27}
+
+id-pr-invalidServiceControlOptions OBJECT IDENTIFIER ::= {id-pr 28}
+
+id-pr-missingServiceControlOptions OBJECT IDENTIFIER ::= {id-pr 29}
+
+id-pr-searchSubsetViolation OBJECT IDENTIFIER ::= {id-pr 30}
+
+id-pr-unmatchedKeyAttributes OBJECT IDENTIFIER ::= {id-pr 31}
+
+id-pr-ambiguousKeyAttributes OBJECT IDENTIFIER ::= {id-pr 32}
+
+-- Notification attributes
+id-not-dSAProblem OBJECT IDENTIFIER ::= {id-not 0}
+
+id-not-searchServiceProblem OBJECT IDENTIFIER ::= {id-not 1}
+
+id-not-serviceType OBJECT IDENTIFIER ::= {id-not 2}
+
+id-not-attributeTypeList OBJECT IDENTIFIER ::= {id-not 3}
+
+id-not-matchingRuleList OBJECT IDENTIFIER ::= {id-not 4}
+
+id-not-filterItem OBJECT IDENTIFIER ::= {id-not 5}
+
+id-not-attributeCombinations OBJECT IDENTIFIER ::= {id-not 6}
+
+id-not-contextTypeList OBJECT IDENTIFIER ::= {id-not 7}
+
+id-not-contextList OBJECT IDENTIFIER ::= {id-not 8}
+
+id-not-contextCombinations OBJECT IDENTIFIER ::= {id-not 9}
+
+id-not-hierarchySelectList OBJECT IDENTIFIER ::= {id-not 10}
+
+id-not-searchOptionsList OBJECT IDENTIFIER ::= {id-not 11}
+
+id-not-serviceControlOptionsList OBJECT IDENTIFIER ::= {id-not 12}
+
+id-not-multipleMatchingLocalities OBJECT IDENTIFIER ::= {id-not 13}
+
+id-not-proposedRelaxation OBJECT IDENTIFIER ::= {id-not 14}
+
+id-not-appliedRelaxation OBJECT IDENTIFIER ::= {id-not 15}
+
+id-not-substringRequirements OBJECT IDENTIFIER ::= {id-not 16}
+
+-- Control attributes
+id-cat-sequenceMatchType OBJECT IDENTIFIER ::=
+ {id-cat 1}
+
+id-cat-wordMatchType OBJECT IDENTIFIER ::= {id-cat 2}
+
+id-cat-characterMatchTypes OBJECT IDENTIFIER ::= {id-cat 3}
+
+id-cat-selectedContexts OBJECT IDENTIFIER ::= {id-cat 4}
+
+END -- SelectedAttributeTypes
+
+-- Generated by Asnp, the ASN.1 pretty-printer of France Telecom R&D
+
diff --git a/lib/asn1/test/asn1_SUITE_data/SelectionType.asn b/lib/asn1/test/asn1_SUITE_data/SelectionType.asn
new file mode 100644
index 0000000000..d7bfbf1788
--- /dev/null
+++ b/lib/asn1/test/asn1_SUITE_data/SelectionType.asn
@@ -0,0 +1,59 @@
+SelectionType DEFINITIONS AUTOMATIC TAGS ::=
+
+BEGIN
+
+Element ::= CHOICE {bool BOOLEAN,
+ atomic-no INTEGER(1..103),
+ bs BIT STRING,
+ os OCTET STRING,
+ null NULL,
+ oi OBJECT IDENTIFIER,
+ od ObjectDescriptor,
+ ext EXTERNAL,
+ ePDV EMBEDDED PDV,
+ utf UTF8String,
+ ro RELATIVE-OID,
+ nums NumericString,
+ symbol PrintableString,
+ telet TeletexString,
+ t61 T61String,
+ video VideotexString,
+ ia5 IA5String,
+ utctime UTCTime,
+ generalizedTime GeneralizedTime,
+ gs GraphicString,
+ vs VisibleString,
+-- iso64 ISO646String,
+ generalString GeneralString,
+ univ UniversalString,
+ cs CHARACTER STRING,
+ bmp BMPString}
+
+MendeleyevTable ::= SEQUENCE OF symbol < Element
+BoolType ::= bool < Element
+
+einsteinium symbol < Element ::= "Es"
+boolv bool < Element ::= TRUE
+intv atomic-no < Element ::= 4
+bsv bs < Element ::= '1001'B
+osv os < Element ::= '313'H
+nullv null < Element ::= NULL
+oiv oi < Element ::= {2 1 1}
+odv od < Element ::= "ObjectDesc"
+utfv utf < Element ::= "utf8"
+rov ro < Element ::= {5 32767 256}
+numsv nums < Element ::= "089"
+teletv telet < Element ::= "telet"
+t61v t61 < Element ::= "t61"
+videov video < Element ::= "video"
+ia5v ia5 < Element ::= "ia5"
+utctimev utctime < Element ::= "9805281429Z"
+gTime generalizedTime < Element ::= "19980528142905.1"
+gsv gs < Element ::= "graphic"
+vsv vs < Element ::= "visible"
+--iso64v iso64 < Element ::= "iso"
+gStringv generalString < Element ::= "general"
+univv univ < Element ::= "Universal"
+bmov bmp < Element ::= "bmp"
+
+END
diff --git a/lib/asn1/test/asn1_SUITE_data/Seq.py b/lib/asn1/test/asn1_SUITE_data/Seq.py
new file mode 100644
index 0000000000..f345373ab5
--- /dev/null
+++ b/lib/asn1/test/asn1_SUITE_data/Seq.py
@@ -0,0 +1,152 @@
+Seq DEFINITIONS IMPLICIT TAGS ::=
+
+BEGIN
+
+IMPORTS Set1 FROM SeqSetLib;
+
+Seq ::= SEQUENCE
+{
+ bool BOOLEAN,
+ boolCon [20] BOOLEAN,
+ boolPri [PRIVATE 21] BOOLEAN,
+ boolApp [APPLICATION 22] BOOLEAN,
+ boolExpCon [30] EXPLICIT BOOLEAN,
+ boolExpPri [PRIVATE 31] EXPLICIT BOOLEAN,
+ boolExpApp [APPLICATION 32] EXPLICIT BOOLEAN
+}
+
+Seq1 ::= SEQUENCE
+{
+ bool1 BOOLEAN,
+ int1 INTEGER,
+ seq1 SeqIn
+}
+
+Seq2 ::= SEQUENCE
+{
+ seq2 SeqIn,
+ bool2 BOOLEAN,
+ int2 INTEGER
+}
+
+Seq3 ::= SEQUENCE
+{
+ bool3 BOOLEAN,
+ seq3 SeqIn,
+ int3 INTEGER
+}
+
+Seq4 ::= SEQUENCE
+{
+ seq41 SeqIn,
+ seq42 SeqIn,
+ seq43 SeqIn
+}
+SeqDef1 ::= SET
+{
+ bool1 BOOLEAN DEFAULT TRUE,
+ int1 INTEGER,
+ seq1 SeqIn DEFAULT {}
+}
+
+SeqDef2 ::= SET
+{
+ seq2 SeqIn DEFAULT {},
+ bool2 BOOLEAN,
+ int2 INTEGER
+}
+
+SeqDef3 ::= SET
+{
+ bool3 BOOLEAN DEFAULT TRUE,
+ seq3 SeqIn DEFAULT {},
+ int3 INTEGER DEFAULT 17
+}
+
+SeqOpt1 ::= SET
+{
+ bool1 BOOLEAN OPTIONAL,
+ int1 INTEGER,
+ seq1 SeqIn OPTIONAL
+}
+
+SeqOpt2 ::= SET
+{
+ seq2 SeqIn OPTIONAL,
+ bool2 BOOLEAN,
+ int2 INTEGER
+}
+
+SeqOpt3 ::= SET
+{
+ bool3 BOOLEAN OPTIONAL,
+ seq3 SeqIn OPTIONAL,
+ int3 INTEGER OPTIONAL
+}
+
+
+SeqIn ::= SEQUENCE
+{
+ boolIn BOOLEAN OPTIONAL,
+ intIn INTEGER DEFAULT 12
+}
+
+
+SeqS1 ::= SEQUENCE
+{
+ boolS1 BOOLEAN,
+ intS1 INTEGER,
+ seqS1 SEQUENCE { boolIn BOOLEAN,
+ intIn INTEGER }
+}
+
+SeqS2 ::= SEQUENCE
+{
+ seqS2 SEQUENCE { boolIn BOOLEAN,
+ intIn INTEGER },
+ boolS2 BOOLEAN,
+ intS2 INTEGER
+
+}
+
+SeqS3 ::= SEQUENCE
+{
+ boolS3 BOOLEAN,
+ seqS3 SEQUENCE { boolIn BOOLEAN,
+ intIn INTEGER },
+ intS3 INTEGER
+
+}
+
+
+SeqImp1 ::= SET
+{
+ set Set1,
+ bool BOOLEAN,
+ int INTEGER
+}
+
+
+SeqImp2 ::= SET
+{
+ bool BOOLEAN,
+ set Set1,
+ int INTEGER
+}
+
+
+SeqImp3 ::= SET
+{
+ bool BOOLEAN,
+ int INTEGER,
+ set Set1
+}
+
+
+
+END
+
+
+
+
+
diff --git a/lib/asn1/test/asn1_SUITE_data/Seq2738.asn1 b/lib/asn1/test/asn1_SUITE_data/Seq2738.asn1
new file mode 100644
index 0000000000..c852adc57e
--- /dev/null
+++ b/lib/asn1/test/asn1_SUITE_data/Seq2738.asn1
@@ -0,0 +1,37 @@
+Seq2738 DEFINITIONS IMPLICIT TAGS ::=
+
+-- Tests that a missing mandatory component of an optional
+-- component is detected as an error and not just as if the optional
+-- component was missing
+
+BEGIN
+
+-- We create a value of type SeqWithOptFake , encode it and then
+-- try to decode it as a value of type SeqWithOpt.
+-- The decoder should detect this as an error, because the
+-- mandatory first component of type INTEGER in OptSeq is missing
+
+SeqOpt ::= SEQUENCE
+{
+ int INTEGER,
+ opt OptSeq OPTIONAL
+}
+
+SeqOptFake ::= SEQUENCE
+{
+ int INTEGER,
+ opt OptSeqFake OPTIONAL
+}
+
+OptSeq ::= SEQUENCE
+{
+ int INTEGER
+}
+
+OptSeqFake ::= SEQUENCE
+{
+ bool BOOLEAN
+}
+
+
+END
diff --git a/lib/asn1/test/asn1_SUITE_data/SeqBadComma.asn b/lib/asn1/test/asn1_SUITE_data/SeqBadComma.asn
new file mode 100644
index 0000000000..64729beccd
--- /dev/null
+++ b/lib/asn1/test/asn1_SUITE_data/SeqBadComma.asn
@@ -0,0 +1,10 @@
+SeqBadComma DEFINITIONS AUTOMATIC TAGS ::=
+
+BEGIN
+
+Seq ::= SEQUENCE {
+ a INTEGER,
+ n BOOLEAN,
+}
+
+END
diff --git a/lib/asn1/test/asn1_SUITE_data/SeqDefault.asn1 b/lib/asn1/test/asn1_SUITE_data/SeqDefault.asn1
new file mode 100644
index 0000000000..99e79da972
--- /dev/null
+++ b/lib/asn1/test/asn1_SUITE_data/SeqDefault.asn1
@@ -0,0 +1,77 @@
+SeqDefault DEFINITIONS IMPLICIT TAGS ::=
+
+BEGIN
+
+
+SeqDef1 ::= SEQUENCE
+{
+ bool1 BOOLEAN DEFAULT TRUE,
+ int1 INTEGER,
+ seq1 SeqIn DEFAULT {}
+}
+
+SeqDef1Imp ::= SEQUENCE
+{
+ bool1 [1] BOOLEAN DEFAULT TRUE,
+ int1 INTEGER,
+ seq1 [2] SeqIn DEFAULT {}
+}
+
+SeqDef1Exp ::= SEQUENCE
+{
+ bool1 [1] EXPLICIT BOOLEAN DEFAULT TRUE,
+ int1 INTEGER,
+ seq1 [2] EXPLICIT SeqIn DEFAULT {}
+}
+
+SeqDef2 ::= SEQUENCE
+{
+ seq2 SeqIn DEFAULT {},
+ bool2 BOOLEAN DEFAULT TRUE,
+ int2 INTEGER
+}
+
+SeqDef2Imp ::= SEQUENCE
+{
+ seq2 [1] SeqIn DEFAULT {},
+ bool2 [2] BOOLEAN DEFAULT TRUE,
+ int2 INTEGER
+}
+
+SeqDef2Exp ::= SEQUENCE
+{
+ seq2 [1] EXPLICIT SeqIn DEFAULT {},
+ bool2 [2] EXPLICIT BOOLEAN,
+ int2 INTEGER
+}
+
+SeqDef3 ::= SEQUENCE
+{
+ bool3 BOOLEAN DEFAULT TRUE,
+ seq3 SeqIn DEFAULT {},
+ int3 INTEGER DEFAULT 17
+}
+
+SeqDef3Imp ::= SEQUENCE
+{
+ bool3 [1] BOOLEAN DEFAULT TRUE,
+ seq3 [2] SeqIn DEFAULT {},
+ int3 INTEGER DEFAULT 17
+}
+
+SeqDef3Exp ::= SEQUENCE
+{
+ bool3 [1] EXPLICIT BOOLEAN DEFAULT TRUE,
+ seq3 [2] EXPLICIT SeqIn DEFAULT {},
+ int3 INTEGER DEFAULT 17
+}
+
+
+
+SeqIn ::= SEQUENCE
+{
+ boolIn BOOLEAN OPTIONAL,
+ intIn INTEGER DEFAULT 12
+}
+
+END
diff --git a/lib/asn1/test/asn1_SUITE_data/SeqExtension.asn1 b/lib/asn1/test/asn1_SUITE_data/SeqExtension.asn1
new file mode 100644
index 0000000000..bb0a7cca3a
--- /dev/null
+++ b/lib/asn1/test/asn1_SUITE_data/SeqExtension.asn1
@@ -0,0 +1,37 @@
+SeqExtension DEFINITIONS IMPLICIT TAGS ::=
+
+BEGIN
+
+IMPORTS XSeqExt1, XSeqExt2 FROM External;
+
+
+SeqExt1 ::= SEQUENCE
+{
+ ...
+}
+
+SeqExt2 ::= SEQUENCE
+{
+ bool BOOLEAN,
+ int INTEGER,
+ ...
+}
+
+SeqExt3 ::= SEQUENCE
+{
+ ...,
+ bool BOOLEAN,
+ int INTEGER
+}
+
+SeqExt4 ::= SEQUENCE
+{
+ bool BOOLEAN,
+ ...,
+ int INTEGER
+}
+
+SeqExt1X ::= XSeqExt1
+SeqExt2X ::= XSeqExt2
+
+END
diff --git a/lib/asn1/test/asn1_SUITE_data/SeqExternal.asn1 b/lib/asn1/test/asn1_SUITE_data/SeqExternal.asn1
new file mode 100644
index 0000000000..9d575c1d6b
--- /dev/null
+++ b/lib/asn1/test/asn1_SUITE_data/SeqExternal.asn1
@@ -0,0 +1,68 @@
+SeqExternal DEFINITIONS IMPLICIT TAGS ::=
+
+BEGIN
+
+IMPORTS XSet1, XSeqNT, XSeqImp, XSeqExp FROM External;
+
+
+
+SeqXSet1 ::= SEQUENCE
+{
+ set XSet1,
+ bool BOOLEAN,
+ int INTEGER
+}
+
+
+SeqXSet2 ::= SEQUENCE
+{
+ bool BOOLEAN,
+ set XSet1,
+ int INTEGER
+}
+
+
+SeqXSet3 ::= SEQUENCE
+{
+ bool BOOLEAN,
+ int INTEGER,
+ set XSet1
+}
+
+
+
+NT ::= SEQUENCE {
+ os OCTET STRING,
+ bool BOOLEAN}
+Imp ::= [1] SEQUENCE {
+ os OCTET STRING,
+ bool BOOLEAN}
+Exp ::= [2] EXPLICIT SEQUENCE {
+ os OCTET STRING,
+ bool BOOLEAN}
+
+NTNT ::= NT
+ImpNT ::= [3] NT
+ExpNT ::= [4] EXPLICIT NT
+
+NTImp ::= Imp
+ImpImp ::= [5] Imp
+ExpImp ::= [6] EXPLICIT Imp
+
+NTExp ::= Exp
+ImpExp ::= [7] Exp
+ExpExp ::= [8] EXPLICIT Exp
+
+XNTNT ::= XSeqNT
+XImpNT ::= [3] XSeqNT
+XExpNT ::= [4] EXPLICIT XSeqNT
+
+XNTImp ::= XSeqImp
+XImpImp ::= [5] XSeqImp
+XExpImp ::= [6] EXPLICIT XSeqImp
+
+XNTExp ::= XSeqExp
+XImpExp ::= [7] XSeqExp
+XExpExp ::= [8] EXPLICIT XSeqExp
+
+END
diff --git a/lib/asn1/test/asn1_SUITE_data/SeqOf.asn1 b/lib/asn1/test/asn1_SUITE_data/SeqOf.asn1
new file mode 100644
index 0000000000..330944cf5c
--- /dev/null
+++ b/lib/asn1/test/asn1_SUITE_data/SeqOf.asn1
@@ -0,0 +1,65 @@
+SeqOf DEFINITIONS IMPLICIT TAGS ::=
+
+BEGIN
+
+
+Seq1 ::= SEQUENCE
+{
+ bool1 BOOLEAN,
+ int1 INTEGER,
+ seq1 SEQUENCE OF SeqIn DEFAULT {}
+}
+
+Seq2 ::= SEQUENCE
+{
+ seq2 SEQUENCE OF SeqIn DEFAULT {},
+ bool2 BOOLEAN,
+ int2 INTEGER
+}
+
+Seq3 ::= SEQUENCE
+{
+ bool3 BOOLEAN,
+ seq3 SEQUENCE OF SeqIn DEFAULT {},
+ int3 INTEGER
+}
+
+Seq4 ::= SEQUENCE
+{
+ seq41 [41] SEQUENCE OF SeqIn DEFAULT {},
+ seq42 [42] SEQUENCE OF SeqIn DEFAULT {},
+ seq43 [43] SEQUENCE OF SeqIn DEFAULT {}
+}
+
+
+
+SeqIn ::= SEQUENCE
+{
+ boolIn BOOLEAN,
+ intIn INTEGER
+}
+
+
+SeqOs ::= SEQUENCE OF OCTET STRING
+SeqOsImp ::= [23] SEQUENCE OF OCTET STRING
+SeqOsExp ::= [24] EXPLICIT SEQUENCE OF OCTET STRING
+
+SeqCho ::= SEQUENCE OF CHOICE {bool BOOLEAN,
+ int INTEGER,
+ last NULL}
+
+SeqOfInt ::= SEQUENCE OF INTEGER
+
+
+
+
+SeqEmp ::= SEQUENCE
+{
+ seq1 SEQUENCE OF Empty DEFAULT {}
+}
+
+Empty ::= SEQUENCE
+{
+}
+
+END
diff --git a/lib/asn1/test/asn1_SUITE_data/SeqOf.py b/lib/asn1/test/asn1_SUITE_data/SeqOf.py
new file mode 100644
index 0000000000..c941418934
--- /dev/null
+++ b/lib/asn1/test/asn1_SUITE_data/SeqOf.py
@@ -0,0 +1,45 @@
+SeqOf DEFINITIONS IMPLICIT TAGS ::=
+
+BEGIN
+
+
+Seq1 ::= SEQUENCE
+{
+ bool1 BOOLEAN,
+ int1 INTEGER,
+ seq1 SEQUENCE OF SeqIn DEFAULT {}
+}
+
+Seq2 ::= SEQUENCE
+{
+ seq2 SEQUENCE OF SeqIn DEFAULT {},
+ bool2 BOOLEAN,
+ int2 INTEGER
+}
+
+Seq3 ::= SEQUENCE
+{
+ bool3 BOOLEAN,
+ seq3 SEQUENCE OF SeqIn DEFAULT {},
+ int3 INTEGER
+}
+
+Seq4 ::= SEQUENCE
+{
+ seq41 [41] SEQUENCE OF SeqIn DEFAULT {},
+ seq42 [42] SEQUENCE OF SeqIn DEFAULT {},
+ seq43 [43] SEQUENCE OF SeqIn DEFAULT {}
+}
+
+
+
+SeqIn ::= SEQUENCE
+{
+ boolIn BOOLEAN,
+ intIn INTEGER
+}
+
+
+
+
+END
diff --git a/lib/asn1/test/asn1_SUITE_data/SeqOfCho.asn1 b/lib/asn1/test/asn1_SUITE_data/SeqOfCho.asn1
new file mode 100644
index 0000000000..8d3d006ed9
--- /dev/null
+++ b/lib/asn1/test/asn1_SUITE_data/SeqOfCho.asn1
@@ -0,0 +1,73 @@
+SeqOfCho DEFINITIONS IMPLICIT TAGS ::=
+
+BEGIN
+
+
+
+SeqChoDef ::= SEQUENCE
+{
+ bool1 BOOLEAN,
+ int1 INTEGER,
+ seq1 SEQUENCE OF ChoIn DEFAULT {}
+}
+
+SeqChoOpt ::= SEQUENCE
+{
+ bool1 BOOLEAN,
+ int1 INTEGER,
+ seq1 SEQUENCE OF ChoIn OPTIONAL
+}
+
+SeqChoEmbDef ::= SEQUENCE
+{
+ bool1 BOOLEAN,
+ int1 INTEGER,
+ seq1 SEQUENCE OF CHOICE
+ {
+ boolIn BOOLEAN,
+ intIn INTEGER
+ } DEFAULT {}
+}
+
+SeqChoEmbOpt ::= SEQUENCE
+{
+ bool1 BOOLEAN,
+ int1 INTEGER,
+ seq1 SEQUENCE OF CHOICE
+ {
+ boolIn BOOLEAN,
+ intIn INTEGER
+ } OPTIONAL
+}
+
+SeqOfChoEmbDef ::= SEQUENCE OF SEQUENCE
+{
+ bool1 BOOLEAN,
+ int1 INTEGER,
+ seq1 SEQUENCE OF CHOICE
+ {
+ boolIn BOOLEAN,
+ intIn INTEGER
+ } DEFAULT {}
+}
+
+
+SeqOfChoEmbOpt ::= SEQUENCE OF SEQUENCE
+{
+ bool1 BOOLEAN,
+ int1 INTEGER,
+ seq1 SEQUENCE OF CHOICE
+ {
+ boolIn BOOLEAN,
+ intIn INTEGER
+ } OPTIONAL
+}
+
+
+ChoIn ::= CHOICE
+{
+ boolIn BOOLEAN,
+ intIn INTEGER
+}
+
+END
diff --git a/lib/asn1/test/asn1_SUITE_data/SeqOfEnum.asn1 b/lib/asn1/test/asn1_SUITE_data/SeqOfEnum.asn1
new file mode 100644
index 0000000000..b8ca9c4654
--- /dev/null
+++ b/lib/asn1/test/asn1_SUITE_data/SeqOfEnum.asn1
@@ -0,0 +1,11 @@
+SeqOfEnum DEFINITIONS AUTOMATIC TAGS ::=
+
+BEGIN
+
+Enum ::= ENUMERATED {a (0),
+ b (1),
+ c (2)}
+
+SeqOfEnum ::= SEQUENCE OF Enum
+
+END
diff --git a/lib/asn1/test/asn1_SUITE_data/SeqOfExternal.asn1 b/lib/asn1/test/asn1_SUITE_data/SeqOfExternal.asn1
new file mode 100644
index 0000000000..607e81540f
--- /dev/null
+++ b/lib/asn1/test/asn1_SUITE_data/SeqOfExternal.asn1
@@ -0,0 +1,42 @@
+SeqOfExternal DEFINITIONS IMPLICIT TAGS ::=
+
+BEGIN
+
+IMPORTS XSeqNT, XSeqImp, XSeqExp FROM External;
+
+
+NT ::= SEQUENCE {
+ os OCTET STRING,
+ bool BOOLEAN}
+Imp ::= [21] SEQUENCE {
+ os OCTET STRING,
+ bool BOOLEAN}
+Exp ::= [22] EXPLICIT SEQUENCE {
+ os OCTET STRING,
+ bool BOOLEAN}
+
+NTNT ::= SEQUENCE OF NT
+ImpNT ::= [3] SEQUENCE OF NT
+ExpNT ::= [4] EXPLICIT SEQUENCE OF NT
+
+NTImp ::= SEQUENCE OF Imp
+ImpImp ::= [5] SEQUENCE OF Imp
+ExpImp ::= [6] EXPLICIT SEQUENCE OF Imp
+
+NTExp ::= SEQUENCE OF Exp
+ImpExp ::= [7] SEQUENCE OF Exp
+ExpExp ::= [8] EXPLICIT SEQUENCE OF Exp
+
+XNTNT ::= SEQUENCE OF XSeqNT
+XImpNT ::= [3] SEQUENCE OF XSeqNT
+XExpNT ::= [4] EXPLICIT SEQUENCE OF XSeqNT
+
+XNTImp ::= SEQUENCE OF XSeqImp
+XImpImp ::= [5] SEQUENCE OF XSeqImp
+XExpImp ::= [6] EXPLICIT SEQUENCE OF XSeqImp
+
+XNTExp ::= SEQUENCE OF XSeqExp
+XImpExp ::= [7] SEQUENCE OF XSeqExp
+XExpExp ::= [8] EXPLICIT SEQUENCE OF XSeqExp
+
+END
diff --git a/lib/asn1/test/asn1_SUITE_data/SeqOfTag.asn1 b/lib/asn1/test/asn1_SUITE_data/SeqOfTag.asn1
new file mode 100644
index 0000000000..74b820a28d
--- /dev/null
+++ b/lib/asn1/test/asn1_SUITE_data/SeqOfTag.asn1
@@ -0,0 +1,65 @@
+SeqOfTag DEFINITIONS IMPLICIT TAGS ::=
+
+BEGIN
+
+IMPORTS XSeqNT, XSeqImp, XSeqExp FROM External;
+
+SeqTagNt ::= [APPLICATION 20] SEQUENCE {
+ nt SEQUENCE OF NT}
+
+SeqTagNtI ::= [APPLICATION 20] SEQUENCE {
+ imp SEQUENCE OF Imp}
+
+SeqTagNtE ::= [APPLICATION 20] SEQUENCE {
+ exp SEQUENCE OF Exp }
+
+SeqTagI ::= [APPLICATION 21] SEQUENCE {
+ nt [0] SEQUENCE OF NT}
+
+SeqTagII ::= [APPLICATION 21] SEQUENCE {
+ imp [1] SEQUENCE OF Imp}
+
+SeqTagIE ::= [APPLICATION 21] SEQUENCE {
+ exp [2] SEQUENCE OF Exp}
+
+SeqTagE ::= [APPLICATION 22] SEQUENCE {
+ nt [0] EXPLICIT SEQUENCE OF NT}
+
+SeqTagEI ::= [APPLICATION 22] SEQUENCE {
+ imp [1] EXPLICIT SEQUENCE OF Imp}
+
+SeqTagEE ::= [APPLICATION 22] SEQUENCE {
+ exp [2] EXPLICIT SEQUENCE OF Exp}
+
+SeqTagXNt ::= [APPLICATION 30] SEQUENCE {
+ xnt SEQUENCE OF XSeqNT}
+
+SeqTagXI ::= [APPLICATION 30] SEQUENCE {
+ ximp SEQUENCE OF XSeqImp}
+
+SeqTagXE ::= [APPLICATION 30] SEQUENCE {
+ xexp SEQUENCE OF XSeqExp }
+
+SeqTagImpX ::= [APPLICATION 31] SEQUENCE {
+ xnt [3] SEQUENCE OF XSeqNT,
+ ximp [4] SEQUENCE OF XSeqImp,
+ xexp [5] SEQUENCE OF XSeqExp }
+
+SeqTagExpX ::= [APPLICATION 32] SEQUENCE {
+ xnt [3] EXPLICIT SEQUENCE OF XSeqNT,
+ ximp [4] EXPLICIT SEQUENCE OF XSeqImp,
+ xexp [5] EXPLICIT SEQUENCE OF XSeqExp }
+
+
+
+NT ::= SEQUENCE {
+ os OCTET STRING,
+ bool BOOLEAN}
+Imp ::= [21] SEQUENCE {
+ os OCTET STRING,
+ bool BOOLEAN}
+Exp ::= [22] EXPLICIT SEQUENCE {
+ os OCTET STRING,
+ bool BOOLEAN}
+
+END
diff --git a/lib/asn1/test/asn1_SUITE_data/SeqOptional.asn1 b/lib/asn1/test/asn1_SUITE_data/SeqOptional.asn1
new file mode 100644
index 0000000000..a8fef52dda
--- /dev/null
+++ b/lib/asn1/test/asn1_SUITE_data/SeqOptional.asn1
@@ -0,0 +1,86 @@
+SeqOptional DEFINITIONS IMPLICIT TAGS ::=
+
+BEGIN
+
+
+SeqOpt1 ::= SEQUENCE
+{
+ bool1 BOOLEAN OPTIONAL,
+ int1 INTEGER,
+ seq1 SeqIn OPTIONAL
+}
+
+SeqOpt1Imp ::= SEQUENCE
+{
+ bool1 [1] BOOLEAN OPTIONAL,
+ int1 INTEGER,
+ seq1 [2] SeqIn OPTIONAL
+}
+
+SeqOpt1Exp ::= SEQUENCE
+{
+ bool1 [1] EXPLICIT BOOLEAN OPTIONAL,
+ int1 INTEGER,
+ seq1 [2] EXPLICIT SeqIn OPTIONAL
+}
+
+SeqOpt2 ::= SEQUENCE
+{
+ seq2 SeqIn OPTIONAL,
+ bool2 BOOLEAN,
+ int2 INTEGER
+}
+
+SeqOpt2Imp ::= SEQUENCE
+{
+ seq2 [1] SeqIn OPTIONAL,
+ bool2 [2] BOOLEAN,
+ int2 INTEGER
+}
+
+SeqOpt2Exp ::= SEQUENCE
+{
+ seq2 [1] EXPLICIT SeqIn OPTIONAL,
+ bool2 [2] EXPLICIT BOOLEAN,
+ int2 INTEGER
+}
+
+SeqOpt3 ::= SEQUENCE
+{
+ bool3 BOOLEAN OPTIONAL,
+ seq3 SeqIn OPTIONAL,
+ int3 INTEGER OPTIONAL
+}
+
+SeqOpt3Imp ::= SEQUENCE
+{
+ bool3 [1] BOOLEAN OPTIONAL,
+ seq3 [2] SeqIn OPTIONAL,
+ int3 INTEGER OPTIONAL
+}
+
+SeqOpt3Exp ::= SEQUENCE
+{
+ bool3 [1] EXPLICIT BOOLEAN OPTIONAL,
+ seq3 [2] EXPLICIT SeqIn OPTIONAL,
+ int3 INTEGER OPTIONAL
+}
+
+
+SeqChoOpt ::= SEQUENCE
+{
+ int INTEGER,
+ cho CHOICE {
+ boolC BOOLEAN,
+ intC INTEGER
+ } OPTIONAL
+}
+
+
+SeqIn ::= SEQUENCE
+{
+ boolIn BOOLEAN,
+ intIn INTEGER
+}
+
+END
diff --git a/lib/asn1/test/asn1_SUITE_data/SeqOptional2.asn b/lib/asn1/test/asn1_SUITE_data/SeqOptional2.asn
new file mode 100644
index 0000000000..7de9134096
--- /dev/null
+++ b/lib/asn1/test/asn1_SUITE_data/SeqOptional2.asn
@@ -0,0 +1,90 @@
+SeqOptional2 DEFINITIONS IMPLICIT TAGS ::=
+
+BEGIN
+
+
+SeqOpt1 ::= SEQUENCE
+{
+ bool1 BOOLEAN OPTIONAL,
+ int1 INTEGER,
+ seq1 SeqIn OPTIONAL
+}
+
+SeqOpt1Imp ::= SEQUENCE
+{
+ bool1 [1] BOOLEAN OPTIONAL,
+ int1 INTEGER,
+ seq1 [2] SeqIn OPTIONAL,
+ seq2 [2] SeqIn OPTIONAL,
+ ...,
+ int2 [3] SeqIn,
+ int3 [3] SeqIn
+}
+
+SeqOpt1Exp ::= SEQUENCE
+{
+ bool1 [1] EXPLICIT BOOLEAN OPTIONAL,
+ int1 INTEGER,
+ seq1 [2] EXPLICIT SeqIn OPTIONAL
+}
+
+SeqOpt2 ::= SEQUENCE
+{
+ seq2 SeqIn OPTIONAL,
+ bool2 BOOLEAN,
+ int2 INTEGER
+}
+
+SeqOpt2Imp ::= SEQUENCE
+{
+ seq2 [1] SeqIn OPTIONAL,
+ bool2 [2] BOOLEAN,
+ int2 INTEGER
+}
+
+SeqOpt2Exp ::= SEQUENCE
+{
+ seq2 [1] EXPLICIT SeqIn OPTIONAL,
+ bool2 [2] EXPLICIT BOOLEAN,
+ int2 INTEGER
+}
+
+SeqOpt3 ::= SEQUENCE
+{
+ bool3 BOOLEAN OPTIONAL,
+ seq3 SeqIn OPTIONAL,
+ int3 INTEGER OPTIONAL
+}
+
+SeqOpt3Imp ::= SEQUENCE
+{
+ bool3 [1] BOOLEAN OPTIONAL,
+ seq3 [2] SeqIn OPTIONAL,
+ int3 INTEGER OPTIONAL
+}
+
+SeqOpt3Exp ::= SEQUENCE
+{
+ bool3 [1] EXPLICIT BOOLEAN OPTIONAL,
+ seq3 [2] EXPLICIT SeqIn OPTIONAL,
+ int3 INTEGER OPTIONAL
+}
+
+
+SeqChoOpt ::= SEQUENCE
+{
+ int INTEGER,
+ cho CHOICE {
+ boolC BOOLEAN,
+ intC INTEGER
+ } OPTIONAL
+}
+
+
+SeqIn ::= SEQUENCE
+{
+ boolIn BOOLEAN,
+ intIn INTEGER
+}
+
+END
diff --git a/lib/asn1/test/asn1_SUITE_data/SeqPrim.asn1 b/lib/asn1/test/asn1_SUITE_data/SeqPrim.asn1
new file mode 100644
index 0000000000..20c4126c0b
--- /dev/null
+++ b/lib/asn1/test/asn1_SUITE_data/SeqPrim.asn1
@@ -0,0 +1,19 @@
+SeqPrim DEFINITIONS IMPLICIT TAGS ::=
+
+BEGIN
+
+
+Seq ::= SEQUENCE
+{
+ bool BOOLEAN,
+ boolCon [20] BOOLEAN,
+ boolPri [PRIVATE 21] BOOLEAN,
+ boolApp [APPLICATION 22] BOOLEAN,
+ boolExpCon [30] EXPLICIT BOOLEAN,
+ boolExpPri [PRIVATE 31] EXPLICIT BOOLEAN,
+ boolExpApp [APPLICATION 32] EXPLICIT BOOLEAN
+}
+
+Empty ::= SEQUENCE {}
+
+END
diff --git a/lib/asn1/test/asn1_SUITE_data/SeqSetIndefinite.asn b/lib/asn1/test/asn1_SUITE_data/SeqSetIndefinite.asn
new file mode 100644
index 0000000000..b56b8cdc17
--- /dev/null
+++ b/lib/asn1/test/asn1_SUITE_data/SeqSetIndefinite.asn
@@ -0,0 +1,41 @@
+SeqSetIndefinite DEFINITIONS IMPLICIT TAGS ::=
+
+BEGIN
+
+SetS3 ::= SET
+{
+ boolS3 BOOLEAN,
+ setS3 SET { boolIn BOOLEAN,
+ intIn INTEGER },
+ intS3 INTEGER
+
+}
+
+SetS3Ext ::= SET
+{
+ boolS3 BOOLEAN,
+ setS3 SET { boolIn BOOLEAN,
+ intIn INTEGER,... },
+ intS3 INTEGER
+}
+
+
+SeqS3 ::= SEQUENCE
+{
+ boolS3 BOOLEAN,
+ seqS3 SEQUENCE { boolIn BOOLEAN,
+ intIn INTEGER },
+ intS3 INTEGER
+
+}
+
+SeqS3Ext ::= SEQUENCE
+{
+ boolS3 BOOLEAN,
+ seqS3 SEQUENCE { boolIn BOOLEAN,
+ intIn INTEGER,... },
+ intS3 INTEGER
+
+}
+
+END
diff --git a/lib/asn1/test/asn1_SUITE_data/SeqSetLib.py b/lib/asn1/test/asn1_SUITE_data/SeqSetLib.py
new file mode 100644
index 0000000000..f7d15ae3b4
--- /dev/null
+++ b/lib/asn1/test/asn1_SUITE_data/SeqSetLib.py
@@ -0,0 +1,32 @@
+SeqSetLib DEFINITIONS IMPLICIT TAGS ::=
+
+BEGIN
+EXPORTS Seq1,Set1;
+
+Seq1 ::= SEQUENCE
+{
+ bool1 BOOLEAN,
+ int1 INTEGER,
+ seq1 SeqIn
+}
+
+Set1 ::= SET
+{
+ bool1 BOOLEAN,
+ int1 INTEGER,
+ set1 SetIn
+}
+
+SetIn ::= SET
+{
+ boolIn BOOLEAN,
+ intIn INTEGER
+}
+
+SeqIn ::= SEQUENCE
+{
+ boolIn BOOLEAN,
+ intIn INTEGER
+}
+
+END
diff --git a/lib/asn1/test/asn1_SUITE_data/SeqTag.asn1 b/lib/asn1/test/asn1_SUITE_data/SeqTag.asn1
new file mode 100644
index 0000000000..950f88d663
--- /dev/null
+++ b/lib/asn1/test/asn1_SUITE_data/SeqTag.asn1
@@ -0,0 +1,48 @@
+SeqTag DEFINITIONS IMPLICIT TAGS ::=
+
+BEGIN
+
+IMPORTS XSet1, XSeqNT, XSeqImp, XSeqExp FROM External;
+
+SeqTag ::= [APPLICATION 20] SEQUENCE {
+ nt NT,
+ imp Imp,
+ exp Exp }
+
+SeqTagImp ::= [APPLICATION 21] SEQUENCE {
+ nt [0] NT,
+ imp [1] Imp,
+ exp [2] Exp}
+
+SeqTagExp ::= [APPLICATION 22] SEQUENCE {
+ nt [0] EXPLICIT NT,
+ imp [1] EXPLICIT Imp,
+ exp [2] EXPLICIT Exp}
+
+SeqTagX ::= [APPLICATION 30] SEQUENCE {
+ xnt XSeqNT,
+ ximp XSeqImp,
+ xexp XSeqExp }
+
+SeqTagImpX ::= [APPLICATION 31] SEQUENCE {
+ xnt [3] XSeqNT,
+ ximp [4] XSeqImp,
+ xexp [5] XSeqExp }
+
+SeqTagExpX ::= [APPLICATION 32] SEQUENCE {
+ xnt [3] EXPLICIT XSeqNT,
+ ximp [4] EXPLICIT XSeqImp,
+ xexp [5] EXPLICIT XSeqExp }
+
+
+NT ::= SEQUENCE {
+ os OCTET STRING,
+ bool BOOLEAN}
+Imp ::= [1] SEQUENCE {
+ os OCTET STRING,
+ bool BOOLEAN}
+Exp ::= [2] EXPLICIT SEQUENCE {
+ os OCTET STRING,
+ bool BOOLEAN}
+
+END
diff --git a/lib/asn1/test/asn1_SUITE_data/SeqTypeRefCho.asn1 b/lib/asn1/test/asn1_SUITE_data/SeqTypeRefCho.asn1
new file mode 100644
index 0000000000..5c662fbd95
--- /dev/null
+++ b/lib/asn1/test/asn1_SUITE_data/SeqTypeRefCho.asn1
@@ -0,0 +1,28 @@
+SeqTypeRefCho DEFINITIONS IMPLICIT TAGS ::=
+
+BEGIN
+
+
+
+SeqTRcho ::= SEQUENCE
+{
+ seqCho SeqCho,
+ seqChoE [135] EXPLICIT SeqCho,
+
+ seqCho-E SeqChoExp,
+ seqChoE-E [335] EXPLICIT SeqChoExp
+
+}
+
+SeqCho ::= CHOICE {
+ choInt INTEGER,
+ choOs OCTET STRING
+ }
+
+SeqChoExp ::= [65] EXPLICIT CHOICE {
+ choInt INTEGER,
+ choOs OCTET STRING
+ }
+
+
+END
diff --git a/lib/asn1/test/asn1_SUITE_data/SeqTypeRefPrim.asn1 b/lib/asn1/test/asn1_SUITE_data/SeqTypeRefPrim.asn1
new file mode 100644
index 0000000000..93f03fad2b
--- /dev/null
+++ b/lib/asn1/test/asn1_SUITE_data/SeqTypeRefPrim.asn1
@@ -0,0 +1,48 @@
+SeqTypeRefPrim DEFINITIONS IMPLICIT TAGS ::=
+
+BEGIN
+
+
+SeqTR ::= SEQUENCE
+{
+ octStr OctStr,
+ octStrI [114] OctStr,
+ octStrE [115] EXPLICIT OctStr,
+
+ octStr-I OctStrImp,
+ octStrI-I [214] OctStrImp,
+ octStrE-I [215] EXPLICIT OctStrImp,
+
+ octStr-E OctStrExp,
+ octStrI-E [314] OctStrExp,
+ octStrE-E [315] EXPLICIT OctStrExp
+
+}
+
+OctStr ::= OCTET STRING
+OctStrImp ::= [14] OCTET STRING
+OctStrExp ::= [15] EXPLICIT OCTET STRING
+
+-- Types to test {Type,Value} notation, see OTP-4057
+
+Int ::= INTEGER
+Bool ::= BOOLEAN
+Enum ::= ENUMERATED {a(0),b(1),c(2)}
+BitStr ::= BIT STRING
+Null ::= NULL
+OId ::= OBJECT IDENTIFIER
+VStr ::= VisibleString
+
+Seq ::= SEQUENCE {
+ octstr OctStr,
+ int Int,
+ bool Bool,
+ enum Enum,
+ bitstr BitStr,
+ null Null,
+ oid OId,
+ vstr VStr
+}
+
+
+END
diff --git a/lib/asn1/test/asn1_SUITE_data/SeqTypeRefSeq.asn1 b/lib/asn1/test/asn1_SUITE_data/SeqTypeRefSeq.asn1
new file mode 100644
index 0000000000..0e528ac710
--- /dev/null
+++ b/lib/asn1/test/asn1_SUITE_data/SeqTypeRefSeq.asn1
@@ -0,0 +1,113 @@
+SeqTypeRefSeq DEFINITIONS IMPLICIT TAGS ::=
+
+BEGIN
+
+Seq1 ::= SEQUENCE
+{
+ bool1 BOOLEAN,
+ int1 INTEGER,
+ seq1 SeqIn
+}
+
+Seq2 ::= SEQUENCE
+{
+ seq2 SeqIn,
+ bool2 BOOLEAN,
+ int2 INTEGER
+}
+
+Seq3 ::= SEQUENCE
+{
+ bool3 BOOLEAN,
+ seq3 SeqIn,
+ int3 INTEGER
+}
+
+Seq4 ::= SEQUENCE
+{
+ seq41 SeqIn,
+ seq42 SeqIn,
+ seq43 SeqIn
+}
+
+
+SeqIn ::= SEQUENCE
+{
+ boolIn BOOLEAN,
+ intIn INTEGER
+}
+
+
+SeqS1 ::= SEQUENCE
+{
+ boolS1 BOOLEAN,
+ intS1 INTEGER,
+ seqS1 SEQUENCE { boolIn BOOLEAN,
+ intIn INTEGER }
+}
+
+SeqS2 ::= SEQUENCE
+{
+ seqS2 SEQUENCE { boolIn BOOLEAN,
+ intIn INTEGER },
+ boolS2 BOOLEAN,
+ intS2 INTEGER
+
+}
+
+SeqS3 ::= SEQUENCE
+{
+ boolS3 BOOLEAN,
+ seqS3 SEQUENCE { boolIn BOOLEAN,
+ intIn INTEGER },
+ intS3 INTEGER
+
+}
+
+
+SeqSTag ::= SEQUENCE
+{
+ seqS1 SEQUENCE { b1 BOOLEAN,
+ i1 INTEGER },
+ seqS2 [7] SEQUENCE { b2 BOOLEAN,
+ i2 INTEGER },
+ seqS3 [8] EXPLICIT SEQUENCE { b3 BOOLEAN,
+ i3 INTEGER }
+}
+
+
+
+SeqTRseq ::= SEQUENCE
+{
+ seqSeq SeqSeq,
+ seqSeqI [134] SeqSeq,
+ seqSeqE [135] EXPLICIT SeqSeq,
+
+ seqSeq-I SeqSeqImp,
+ seqSeqI-I [234] SeqSeqImp,
+ seqSeqE-I [235] EXPLICIT SeqSeqImp,
+
+ seqSeq-E SeqSeqExp,
+ seqSeqI-E [334] SeqSeqExp,
+ seqSeqE-E [335] EXPLICIT SeqSeqExp
+
+}
+
+SeqSeq ::= SEQUENCE {
+ seqInt INTEGER,
+ seqOs OCTET STRING
+ }
+
+SeqSeqImp ::= [64] SEQUENCE {
+ seqInt INTEGER,
+ seqOs OCTET STRING
+ }
+
+SeqSeqExp ::= [65] EXPLICIT SEQUENCE {
+ seqInt INTEGER,
+ seqOs OCTET STRING
+ }
+
+
+
+END
diff --git a/lib/asn1/test/asn1_SUITE_data/SeqTypeRefSet.asn1 b/lib/asn1/test/asn1_SUITE_data/SeqTypeRefSet.asn1
new file mode 100644
index 0000000000..45dc05a0c3
--- /dev/null
+++ b/lib/asn1/test/asn1_SUITE_data/SeqTypeRefSet.asn1
@@ -0,0 +1,39 @@
+SeqTypeRefSet DEFINITIONS IMPLICIT TAGS ::=
+
+BEGIN
+
+
+
+SeqTRset ::= SEQUENCE
+{
+ seqSet SeqSet,
+ seqSetI [124] SeqSet,
+ seqSetE [125] EXPLICIT SeqSet,
+
+ seqSet-I SeqSetImp,
+ seqSetI-I [224] SeqSetImp,
+ seqSetE-I [225] EXPLICIT SeqSetImp,
+
+ seqSet-E SeqSetExp,
+ seqSetI-E [324] SeqSetExp,
+ seqSetE-E [325] EXPLICIT SeqSetExp
+
+}
+
+SeqSet ::= SET {
+ setInt INTEGER,
+ setOs OCTET STRING
+ }
+
+SeqSetImp ::= [54] SET {
+ setInt INTEGER,
+ setOs OCTET STRING
+ }
+
+SeqSetExp ::= [55] EXPLICIT SET {
+ setInt INTEGER,
+ setOs OCTET STRING
+ }
+
+
+END
diff --git a/lib/asn1/test/asn1_SUITE_data/SequenceBadComma.asn b/lib/asn1/test/asn1_SUITE_data/SequenceBadComma.asn
new file mode 100644
index 0000000000..436815aa9b
--- /dev/null
+++ b/lib/asn1/test/asn1_SUITE_data/SequenceBadComma.asn
@@ -0,0 +1,10 @@
+SequenceBadComma DEFINITIONS IMPLICIT TAGS ::=
+BEGIN
+EXPORTS Person;
+
+Person ::= [PRIVATE 19] SEQUENCE {,
+ name PrintableString,
+ location INTEGER {home(0),field(1),roving(2)},
+ age INTEGER OPTIONAL
+ }
+END
diff --git a/lib/asn1/test/asn1_SUITE_data/SequenceBadComponentName.asn1 b/lib/asn1/test/asn1_SUITE_data/SequenceBadComponentName.asn1
new file mode 100644
index 0000000000..8b2b8816db
--- /dev/null
+++ b/lib/asn1/test/asn1_SUITE_data/SequenceBadComponentName.asn1
@@ -0,0 +1,10 @@
+SequenceBadComponentName DEFINITIONS ::=
+BEGIN
+
+T ::= Typ
+
+Typ ::= SEQUENCE {
+ a INTEGER,
+ C Typ}
+
+END
diff --git a/lib/asn1/test/asn1_SUITE_data/SequenceBadComponentType.asn1 b/lib/asn1/test/asn1_SUITE_data/SequenceBadComponentType.asn1
new file mode 100644
index 0000000000..0c33f48906
--- /dev/null
+++ b/lib/asn1/test/asn1_SUITE_data/SequenceBadComponentType.asn1
@@ -0,0 +1,10 @@
+SequenceBadComponentType DEFINITIONS ::=
+BEGIN
+
+T ::= Typ
+
+Typ ::= SEQUENCE {
+ a b,
+ c T}
+
+END
diff --git a/lib/asn1/test/asn1_SUITE_data/Set.py b/lib/asn1/test/asn1_SUITE_data/Set.py
new file mode 100644
index 0000000000..4062f6b804
--- /dev/null
+++ b/lib/asn1/test/asn1_SUITE_data/Set.py
@@ -0,0 +1,141 @@
+Set DEFINITIONS IMPLICIT TAGS ::=
+
+BEGIN
+
+IMPORTS Seq1 FROM SeqSetLib;
+
+Set ::= SET
+{
+ bool BOOLEAN,
+ boolCon [20] BOOLEAN,
+ boolPri [PRIVATE 21] BOOLEAN,
+ boolApp [APPLICATION 22] BOOLEAN,
+ boolExpCon [30] EXPLICIT BOOLEAN,
+ boolExpPri [PRIVATE 31] EXPLICIT BOOLEAN,
+ boolExpApp [APPLICATION 32] EXPLICIT BOOLEAN
+}
+
+Set1 ::= SET
+{
+ bool1 BOOLEAN,
+ int1 INTEGER,
+ set1 SetIn
+}
+
+Set2 ::= SET
+{
+ set2 SetIn,
+ bool2 BOOLEAN,
+ int2 INTEGER
+}
+
+Set3 ::= SET
+{
+ bool3 BOOLEAN,
+ set3 SetIn,
+ int3 INTEGER
+}
+
+SetDef1 ::= SET
+{
+ bool1 BOOLEAN DEFAULT TRUE,
+ int1 INTEGER,
+ set1 SetIn DEFAULT {}
+}
+
+SetDef2 ::= SET
+{
+ set2 SetIn DEFAULT {},
+ bool2 BOOLEAN,
+ int2 INTEGER
+}
+
+SetDef3 ::= SET
+{
+ bool3 BOOLEAN DEFAULT TRUE,
+ set3 SetIn DEFAULT {},
+ int3 INTEGER DEFAULT 17
+}
+
+SetOpt1 ::= SET
+{
+ bool1 BOOLEAN OPTIONAL,
+ int1 INTEGER,
+ set1 SetIn OPTIONAL
+}
+
+SetOpt2 ::= SET
+{
+ set2 SetIn OPTIONAL,
+ bool2 BOOLEAN,
+ int2 INTEGER
+}
+
+SetOpt3 ::= SET
+{
+ bool3 BOOLEAN OPTIONAL,
+ set3 SetIn OPTIONAL,
+ int3 INTEGER OPTIONAL
+}
+
+SetIn ::= SET
+{
+ boolIn BOOLEAN,
+ intIn INTEGER
+}
+
+
+SetS1 ::= SET
+{
+ boolS1 BOOLEAN,
+ intS1 INTEGER,
+ setS1 SET { boolIn BOOLEAN,
+ intIn INTEGER }
+}
+
+SetS2 ::= SET
+{
+ setS2 SET { boolIn BOOLEAN,
+ intIn INTEGER },
+ boolS2 BOOLEAN,
+ intS2 INTEGER
+
+}
+
+SetS3 ::= SET
+{
+ boolS3 BOOLEAN,
+ setS3 SET { boolIn BOOLEAN,
+ intIn INTEGER },
+ intS3 INTEGER
+
+}
+
+
+SetImp1 ::= SET
+{
+ seq Seq1,
+ bool BOOLEAN,
+ int INTEGER
+}
+
+
+SetImp2 ::= SET
+{
+ bool BOOLEAN,
+ seq Seq1,
+ int INTEGER
+}
+
+
+SetImp3 ::= SET
+{
+ bool BOOLEAN,
+ int INTEGER,
+ seq Seq1
+}
+
+
+
+
+END
diff --git a/lib/asn1/test/asn1_SUITE_data/SetDefault.asn1 b/lib/asn1/test/asn1_SUITE_data/SetDefault.asn1
new file mode 100644
index 0000000000..cb9e0ead62
--- /dev/null
+++ b/lib/asn1/test/asn1_SUITE_data/SetDefault.asn1
@@ -0,0 +1,33 @@
+SetDefault DEFINITIONS IMPLICIT TAGS ::=
+
+BEGIN
+
+
+SetDef1 ::= SET
+{
+ bool1 BOOLEAN DEFAULT TRUE,
+ int1 INTEGER,
+ set1 SetIn DEFAULT {}
+}
+
+SetDef2 ::= SET
+{
+ set2 SetIn DEFAULT {},
+ bool2 BOOLEAN,
+ int2 INTEGER
+}
+
+SetDef3 ::= SET
+{
+ bool3 BOOLEAN DEFAULT TRUE,
+ set3 SetIn DEFAULT {},
+ int3 INTEGER DEFAULT 17
+}
+
+SetIn ::= SET
+{
+ boolIn BOOLEAN OPTIONAL,
+ intIn INTEGER DEFAULT 12
+}
+
+END
diff --git a/lib/asn1/test/asn1_SUITE_data/SetExtension.asn1 b/lib/asn1/test/asn1_SUITE_data/SetExtension.asn1
new file mode 100644
index 0000000000..53091d3eea
--- /dev/null
+++ b/lib/asn1/test/asn1_SUITE_data/SetExtension.asn1
@@ -0,0 +1,37 @@
+SetExtension DEFINITIONS IMPLICIT TAGS ::=
+
+BEGIN
+
+IMPORTS XSetExt1, XSetExt2 FROM External;
+
+SetExt1 ::= SET
+{
+ ...
+}
+
+SetExt2 ::= SET
+{
+ bool BOOLEAN,
+ int INTEGER,
+ ...
+}
+
+SetExt3 ::= SET
+{
+ ...,
+ bool BOOLEAN,
+ int INTEGER
+}
+
+SetExt4 ::= SET
+{
+ bool BOOLEAN,
+ ...,
+ int INTEGER
+}
+
+SetExt1X ::= XSetExt1
+SetExt2X ::= XSetExt2
+
+
+END
diff --git a/lib/asn1/test/asn1_SUITE_data/SetExternal.asn1 b/lib/asn1/test/asn1_SUITE_data/SetExternal.asn1
new file mode 100644
index 0000000000..394a068280
--- /dev/null
+++ b/lib/asn1/test/asn1_SUITE_data/SetExternal.asn1
@@ -0,0 +1,68 @@
+SetExternal DEFINITIONS IMPLICIT TAGS ::=
+
+BEGIN
+
+IMPORTS XSeq1, XSetNT, XSetImp, XSetExp FROM External;
+
+
+
+SetXSeq1 ::= SET
+{
+ seq XSeq1,
+ bool BOOLEAN,
+ int INTEGER
+}
+
+
+SetXSeq2 ::= SET
+{
+ bool BOOLEAN,
+ seq XSeq1,
+ int INTEGER
+}
+
+
+SetXSeq3 ::= SET
+{
+ bool BOOLEAN,
+ int INTEGER,
+ seq XSeq1
+}
+
+
+NT ::= SET {
+ os OCTET STRING,
+ bool BOOLEAN}
+Imp ::= [11] SET {
+ os OCTET STRING,
+ bool BOOLEAN}
+Exp ::= [12] EXPLICIT SET {
+ os OCTET STRING,
+ bool BOOLEAN}
+
+NTNT ::= NT
+ImpNT ::= [3] NT
+ExpNT ::= [4] EXPLICIT NT
+
+NTImp ::= Imp
+ImpImp ::= [5] Imp
+ExpImp ::= [6] EXPLICIT Imp
+
+NTExp ::= Exp
+ImpExp ::= [7] Exp
+ExpExp ::= [8] EXPLICIT Exp
+
+XNTNT ::= XSetNT
+XImpNT ::= [3] XSetNT
+XExpNT ::= [4] EXPLICIT XSetNT
+
+XNTImp ::= XSetImp
+XImpImp ::= [5] XSetImp
+XExpImp ::= [6] EXPLICIT XSetImp
+
+XNTExp ::= XSetExp
+XImpExp ::= [7] XSetExp
+XExpExp ::= [8] EXPLICIT XSetExp
+
+
+END
diff --git a/lib/asn1/test/asn1_SUITE_data/SetOf.asn1 b/lib/asn1/test/asn1_SUITE_data/SetOf.asn1
new file mode 100644
index 0000000000..cdb770f8de
--- /dev/null
+++ b/lib/asn1/test/asn1_SUITE_data/SetOf.asn1
@@ -0,0 +1,61 @@
+SetOf DEFINITIONS IMPLICIT TAGS ::=
+
+BEGIN
+
+Set1 ::= SET
+{
+ bool1 BOOLEAN,
+ int1 INTEGER,
+ set1 SET OF SetIn DEFAULT {}
+}
+
+Set2 ::= SET
+{
+ set2 SET OF SetIn DEFAULT {},
+ bool2 BOOLEAN,
+ int2 INTEGER
+}
+
+Set3 ::= SET
+{
+ bool3 BOOLEAN,
+ set3 SET OF SetIn DEFAULT {},
+ int3 INTEGER
+}
+
+Set4 ::= SET
+{
+ set41 [41] SET OF SetIn DEFAULT {},
+ set42 [42] SET OF SetIn DEFAULT {},
+ set43 [43] SET OF SetIn DEFAULT {}
+}
+
+
+
+SetIn ::= SET
+{
+ boolIn BOOLEAN,
+ intIn INTEGER
+}
+
+
+SetOs ::= SET OF OCTET STRING
+SetOsImp ::= [23] SET OF OCTET STRING
+SetOsExp ::= [24] EXPLICIT SET OF OCTET STRING
+
+SetCho ::= SET OF CHOICE {bool BOOLEAN,
+ int INTEGER,
+ last NULL}
+
+
+
+SetEmp ::= SET
+{
+ set1 SET OF Empty DEFAULT {}
+}
+
+Empty ::= SET
+{
+}
+
+END
diff --git a/lib/asn1/test/asn1_SUITE_data/SetOf.py b/lib/asn1/test/asn1_SUITE_data/SetOf.py
new file mode 100644
index 0000000000..4e2ea16fcc
--- /dev/null
+++ b/lib/asn1/test/asn1_SUITE_data/SetOf.py
@@ -0,0 +1,42 @@
+SetOf DEFINITIONS IMPLICIT TAGS ::=
+
+BEGIN
+
+
+Set1 ::= SET
+{
+ bool1 BOOLEAN,
+ int1 INTEGER,
+ set1 SET OF SetIn DEFAULT {}
+}
+
+Set2 ::= SET
+{
+ set2 SET OF SetIn DEFAULT {},
+ bool2 BOOLEAN,
+ int2 INTEGER
+}
+
+Set3 ::= SET
+{
+ bool3 BOOLEAN,
+ set3 SET OF SetIn DEFAULT {},
+ int3 INTEGER
+}
+
+Set4 ::= SET
+{
+ set41 [41] SET OF SetIn DEFAULT {},
+ set42 [42] SET OF SetIn DEFAULT {},
+ set43 [43] SET OF SetIn DEFAULT {}
+}
+
+
+
+SetIn ::= SET
+{
+ boolIn BOOLEAN,
+ intIn INTEGER
+}
+
+END
diff --git a/lib/asn1/test/asn1_SUITE_data/SetOfCho.asn1 b/lib/asn1/test/asn1_SUITE_data/SetOfCho.asn1
new file mode 100644
index 0000000000..3571a2b277
--- /dev/null
+++ b/lib/asn1/test/asn1_SUITE_data/SetOfCho.asn1
@@ -0,0 +1,73 @@
+SetOfCho DEFINITIONS IMPLICIT TAGS ::=
+
+BEGIN
+
+
+
+SetChoDef ::= SET
+{
+ bool1 BOOLEAN,
+ int1 INTEGER,
+ set1 SET OF ChoIn DEFAULT {}
+}
+
+SetChoOpt ::= SET
+{
+ bool1 BOOLEAN,
+ int1 INTEGER,
+ set1 SET OF ChoIn OPTIONAL
+}
+
+SetChoEmbDef ::= SET
+{
+ bool1 BOOLEAN,
+ int1 INTEGER,
+ set1 SET OF CHOICE
+ {
+ boolIn BOOLEAN,
+ intIn INTEGER
+ } DEFAULT {}
+}
+
+SetChoEmbOpt ::= SET
+{
+ bool1 BOOLEAN,
+ int1 INTEGER,
+ set1 SET OF CHOICE
+ {
+ boolIn BOOLEAN,
+ intIn INTEGER
+ } OPTIONAL
+}
+
+SetOfChoEmbDef ::= SET OF SET
+{
+ bool1 BOOLEAN,
+ int1 INTEGER,
+ set1 SET OF CHOICE
+ {
+ boolIn BOOLEAN,
+ intIn INTEGER
+ } DEFAULT {}
+}
+
+
+SetOfChoEmbOpt ::= SET OF SET
+{
+ bool1 BOOLEAN,
+ int1 INTEGER,
+ set1 SET OF CHOICE
+ {
+ boolIn BOOLEAN,
+ intIn INTEGER
+ } OPTIONAL
+}
+
+
+ChoIn ::= CHOICE
+{
+ boolIn BOOLEAN,
+ intIn INTEGER
+}
+
+END
diff --git a/lib/asn1/test/asn1_SUITE_data/SetOfExternal.asn1 b/lib/asn1/test/asn1_SUITE_data/SetOfExternal.asn1
new file mode 100644
index 0000000000..c08f2a51ee
--- /dev/null
+++ b/lib/asn1/test/asn1_SUITE_data/SetOfExternal.asn1
@@ -0,0 +1,42 @@
+SetOfExternal DEFINITIONS IMPLICIT TAGS ::=
+
+BEGIN
+
+IMPORTS XSetNT, XSetImp, XSetExp FROM External;
+
+
+NT ::= SET {
+ os OCTET STRING,
+ bool BOOLEAN}
+Imp ::= [21] SET {
+ os OCTET STRING,
+ bool BOOLEAN}
+Exp ::= [22] EXPLICIT SET {
+ os OCTET STRING,
+ bool BOOLEAN}
+
+NTNT ::= SET OF NT
+ImpNT ::= [3] SET OF NT
+ExpNT ::= [4] EXPLICIT SET OF NT
+
+NTImp ::= SET OF Imp
+ImpImp ::= [5] SET OF Imp
+ExpImp ::= [6] EXPLICIT SET OF Imp
+
+NTExp ::= SET OF Exp
+ImpExp ::= [7] SET OF Exp
+ExpExp ::= [8] EXPLICIT SET OF Exp
+
+XNTNT ::= SET OF XSetNT
+XImpNT ::= [3] SET OF XSetNT
+XExpNT ::= [4] EXPLICIT SET OF XSetNT
+
+XNTImp ::= SET OF XSetImp
+XImpImp ::= [5] SET OF XSetImp
+XExpImp ::= [6] EXPLICIT SET OF XSetImp
+
+XNTExp ::= SET OF XSetExp
+XImpExp ::= [7] SET OF XSetExp
+XExpExp ::= [8] EXPLICIT SET OF XSetExp
+
+END
diff --git a/lib/asn1/test/asn1_SUITE_data/SetOfTag.asn1 b/lib/asn1/test/asn1_SUITE_data/SetOfTag.asn1
new file mode 100644
index 0000000000..e137e8fa40
--- /dev/null
+++ b/lib/asn1/test/asn1_SUITE_data/SetOfTag.asn1
@@ -0,0 +1,65 @@
+SetOfTag DEFINITIONS IMPLICIT TAGS ::=
+
+BEGIN
+
+IMPORTS XSetNT, XSetImp, XSetExp FROM External;
+
+SetTagNt ::= [APPLICATION 20] SET {
+ nt SET OF NT}
+
+SetTagNtI ::= [APPLICATION 20] SET {
+ imp SET OF Imp}
+
+SetTagNtE ::= [APPLICATION 20] SET {
+ exp SET OF Exp }
+
+SetTagI ::= [APPLICATION 21] SET {
+ nt [0] SET OF NT}
+
+SetTagII ::= [APPLICATION 21] SET {
+ imp [1] SET OF Imp}
+
+SetTagIE ::= [APPLICATION 21] SET {
+ exp [2] SET OF Exp}
+
+SetTagE ::= [APPLICATION 22] SET {
+ nt [0] EXPLICIT SET OF NT}
+
+SetTagEI ::= [APPLICATION 22] SET {
+ imp [1] EXPLICIT SET OF Imp}
+
+SetTagEE ::= [APPLICATION 22] SET {
+ exp [2] EXPLICIT SET OF Exp}
+
+SetTagXNt ::= [APPLICATION 30] SET {
+ xnt SET OF XSetNT}
+
+SetTagXI ::= [APPLICATION 30] SET {
+ ximp SET OF XSetImp}
+
+SetTagXE ::= [APPLICATION 30] SET {
+ xexp SET OF XSetExp }
+
+SetTagImpX ::= [APPLICATION 31] SET {
+ xnt [3] SET OF XSetNT,
+ ximp [4] SET OF XSetImp,
+ xexp [5] SET OF XSetExp }
+
+SetTagExpX ::= [APPLICATION 32] SET {
+ xnt [3] EXPLICIT SET OF XSetNT,
+ ximp [4] EXPLICIT SET OF XSetImp,
+ xexp [5] EXPLICIT SET OF XSetExp }
+
+
+
+NT ::= SET {
+ os OCTET STRING,
+ bool BOOLEAN}
+Imp ::= [21] SET {
+ os OCTET STRING,
+ bool BOOLEAN}
+Exp ::= [22] EXPLICIT SET {
+ os OCTET STRING,
+ bool BOOLEAN}
+
+END
diff --git a/lib/asn1/test/asn1_SUITE_data/SetOptional.asn1 b/lib/asn1/test/asn1_SUITE_data/SetOptional.asn1
new file mode 100644
index 0000000000..5d2f2526b3
--- /dev/null
+++ b/lib/asn1/test/asn1_SUITE_data/SetOptional.asn1
@@ -0,0 +1,77 @@
+SetOptional DEFINITIONS IMPLICIT TAGS ::=
+
+BEGIN
+
+SetOpt1 ::= SET
+{
+ bool1 BOOLEAN OPTIONAL,
+ int1 INTEGER,
+ set1 SetIn OPTIONAL
+}
+
+SetOpt1Imp ::= SEQUENCE
+{
+ bool1 [1] BOOLEAN OPTIONAL,
+ int1 INTEGER,
+ set1 [2] SetIn OPTIONAL
+}
+
+SetOpt1Exp ::= SEQUENCE
+{
+ bool1 [1] EXPLICIT BOOLEAN OPTIONAL,
+ int1 INTEGER,
+ set1 [2] EXPLICIT SetIn OPTIONAL
+}
+
+SetOpt2 ::= SET
+{
+ set2 SetIn OPTIONAL,
+ bool2 BOOLEAN,
+ int2 INTEGER
+}
+
+SetOpt2Imp ::= SEQUENCE
+{
+ set2 [1] SetIn OPTIONAL,
+ bool2 [2] BOOLEAN,
+ int2 INTEGER
+}
+
+SetOpt2Exp ::= SEQUENCE
+{
+ set2 [1] EXPLICIT SetIn OPTIONAL,
+ bool2 [2] EXPLICIT BOOLEAN,
+ int2 INTEGER
+}
+
+SetOpt3 ::= SET
+{
+ bool3 BOOLEAN OPTIONAL,
+ set3 SetIn OPTIONAL,
+ int3 INTEGER OPTIONAL
+}
+
+SetOpt3Imp ::= SEQUENCE
+{
+ bool3 [1] BOOLEAN OPTIONAL,
+ set3 [2] SetIn OPTIONAL,
+ int3 INTEGER OPTIONAL
+}
+
+SetOpt3Exp ::= SEQUENCE
+{
+ bool3 [1] EXPLICIT BOOLEAN OPTIONAL,
+ set3 [2] EXPLICIT SetIn OPTIONAL,
+ int3 INTEGER OPTIONAL
+}
+
+
+
+SetIn ::= SET
+{
+ boolIn BOOLEAN,
+ intIn INTEGER
+}
+
+
+END
diff --git a/lib/asn1/test/asn1_SUITE_data/SetPrim.asn1 b/lib/asn1/test/asn1_SUITE_data/SetPrim.asn1
new file mode 100644
index 0000000000..06c4932625
--- /dev/null
+++ b/lib/asn1/test/asn1_SUITE_data/SetPrim.asn1
@@ -0,0 +1,20 @@
+SetPrim DEFINITIONS IMPLICIT TAGS ::=
+
+BEGIN
+
+Set ::= SET
+{
+ bool BOOLEAN,
+ boolCon [20] BOOLEAN,
+ boolPri [PRIVATE 21] BOOLEAN,
+ boolApp [APPLICATION 22] BOOLEAN,
+ boolExpCon [30] EXPLICIT BOOLEAN,
+ boolExpPri [PRIVATE 31] EXPLICIT BOOLEAN,
+ boolExpApp [APPLICATION 32] EXPLICIT BOOLEAN
+}
+
+Empty ::= SET
+{
+}
+
+END
diff --git a/lib/asn1/test/asn1_SUITE_data/SetTag.asn1 b/lib/asn1/test/asn1_SUITE_data/SetTag.asn1
new file mode 100644
index 0000000000..3f7422edaf
--- /dev/null
+++ b/lib/asn1/test/asn1_SUITE_data/SetTag.asn1
@@ -0,0 +1,47 @@
+SetTag DEFINITIONS IMPLICIT TAGS ::=
+
+BEGIN
+
+IMPORTS XSeq1, XSetNT, XSetImp, XSetExp FROM External;
+
+SetTag ::= [APPLICATION 20] SET {
+ nt NT,
+ imp Imp,
+ exp Exp }
+
+SetTagImp ::= [APPLICATION 21] SET {
+ nt [0] NT,
+ imp [1] Imp,
+ exp [2] Exp}
+
+SetTagExp ::= [APPLICATION 22] SET {
+ nt [0] EXPLICIT NT,
+ imp [1] EXPLICIT Imp,
+ exp [2] EXPLICIT Exp}
+
+SetTagX ::= [APPLICATION 30] SET {
+ xnt XSetNT,
+ ximp XSetImp,
+ xexp XSetExp }
+
+SetTagImpX ::= [APPLICATION 31] SET {
+ xnt [3] XSetNT,
+ ximp [4] XSetImp,
+ xexp [5] XSetExp }
+
+SetTagExpX ::= [APPLICATION 32] SET {
+ xnt [3] EXPLICIT XSetNT,
+ ximp [4] EXPLICIT XSetImp,
+ xexp [5] EXPLICIT XSetExp }
+
+NT ::= SET {
+ os OCTET STRING,
+ bool BOOLEAN}
+Imp ::= [11] SET {
+ os OCTET STRING,
+ bool BOOLEAN}
+Exp ::= [12] EXPLICIT SET {
+ os OCTET STRING,
+ bool BOOLEAN}
+
+END
diff --git a/lib/asn1/test/asn1_SUITE_data/SetTypeRefCho.asn1 b/lib/asn1/test/asn1_SUITE_data/SetTypeRefCho.asn1
new file mode 100644
index 0000000000..32c9d95703
--- /dev/null
+++ b/lib/asn1/test/asn1_SUITE_data/SetTypeRefCho.asn1
@@ -0,0 +1,27 @@
+SetTypeRefCho DEFINITIONS IMPLICIT TAGS ::=
+
+BEGIN
+
+
+SetTRcho ::= SET
+{
+ setCho SetCho,
+ setChoE [135] EXPLICIT SetCho,
+
+ setCho-E SetChoExp,
+ setChoE-E [335] EXPLICIT SetChoExp
+
+}
+
+SetCho ::= CHOICE {
+ choInt INTEGER,
+ choOs OCTET STRING
+ }
+
+SetChoExp ::= [65] EXPLICIT CHOICE {
+ choInt INTEGER,
+ choOs OCTET STRING
+ }
+
+
+END
diff --git a/lib/asn1/test/asn1_SUITE_data/SetTypeRefPrim.asn1 b/lib/asn1/test/asn1_SUITE_data/SetTypeRefPrim.asn1
new file mode 100644
index 0000000000..d8f2396c02
--- /dev/null
+++ b/lib/asn1/test/asn1_SUITE_data/SetTypeRefPrim.asn1
@@ -0,0 +1,29 @@
+SetTypeRefPrim DEFINITIONS IMPLICIT TAGS ::=
+
+BEGIN
+
+
+
+SetTR ::= SET
+{
+ octStr OctStr,
+ octStrI [114] OctStr,
+ octStrE [115] EXPLICIT OctStr,
+
+ octStr-I OctStrImp,
+ octStrI-I [214] OctStrImp,
+ octStrE-I [215] EXPLICIT OctStrImp,
+
+ octStr-E OctStrExp,
+ octStrI-E [314] OctStrExp,
+ octStrE-E [315] EXPLICIT OctStrExp
+
+}
+
+OctStr ::= OCTET STRING
+OctStrImp ::= [14] OCTET STRING
+OctStrExp ::= [15] EXPLICIT OCTET STRING
+
+
+
+END
diff --git a/lib/asn1/test/asn1_SUITE_data/SetTypeRefSeq.asn1 b/lib/asn1/test/asn1_SUITE_data/SetTypeRefSeq.asn1
new file mode 100644
index 0000000000..72dd71c6eb
--- /dev/null
+++ b/lib/asn1/test/asn1_SUITE_data/SetTypeRefSeq.asn1
@@ -0,0 +1,38 @@
+SetTypeRefSeq DEFINITIONS IMPLICIT TAGS ::=
+
+BEGIN
+
+
+
+SetTRseq ::= SET
+{
+ setSeq SetSeq,
+ setSeqI [134] SetSeq,
+ setSeqE [135] EXPLICIT SetSeq,
+
+ setSeq-I SetSeqImp,
+ setSeqI-I [234] SetSeqImp,
+ setSeqE-I [235] EXPLICIT SetSeqImp,
+
+ setSeq-E SetSeqExp,
+ setSeqI-E [334] SetSeqExp,
+ setSeqE-E [335] EXPLICIT SetSeqExp
+
+}
+
+SetSeq ::= SEQUENCE {
+ seqInt INTEGER,
+ seqOs OCTET STRING
+ }
+
+SetSeqImp ::= [64] SEQUENCE {
+ seqInt INTEGER,
+ seqOs OCTET STRING
+ }
+
+SetSeqExp ::= [65] EXPLICIT SEQUENCE {
+ seqInt INTEGER,
+ seqOs OCTET STRING
+ }
+
+END
diff --git a/lib/asn1/test/asn1_SUITE_data/SetTypeRefSet.asn1 b/lib/asn1/test/asn1_SUITE_data/SetTypeRefSet.asn1
new file mode 100644
index 0000000000..b215d598dc
--- /dev/null
+++ b/lib/asn1/test/asn1_SUITE_data/SetTypeRefSet.asn1
@@ -0,0 +1,110 @@
+SetTypeRefSet DEFINITIONS IMPLICIT TAGS ::=
+
+BEGIN
+
+Set1 ::= SET
+{
+ bool1 BOOLEAN,
+ int1 INTEGER,
+ set1 SetIn
+}
+
+Set2 ::= SET
+{
+ set2 SetIn,
+ bool2 BOOLEAN,
+ int2 INTEGER
+}
+
+Set3 ::= SET
+{
+ bool3 BOOLEAN,
+ set3 SetIn,
+ int3 INTEGER
+}
+
+Set4 ::= SEQUENCE
+{
+ set41 SetIn,
+ set42 SetIn,
+ set43 SetIn
+}
+
+
+SetIn ::= SET
+{
+ boolIn BOOLEAN,
+ intIn INTEGER
+}
+
+
+SetS1 ::= SET
+{
+ boolS1 BOOLEAN,
+ intS1 INTEGER,
+ setS1 SET { boolIn BOOLEAN,
+ intIn INTEGER }
+}
+
+SetS2 ::= SET
+{
+ setS2 SET { boolIn BOOLEAN,
+ intIn INTEGER },
+ boolS2 BOOLEAN,
+ intS2 INTEGER
+
+}
+
+SetS3 ::= SET
+{
+ boolS3 BOOLEAN,
+ setS3 SET { boolIn BOOLEAN,
+ intIn INTEGER },
+ intS3 INTEGER
+
+}
+
+SetSTag ::= SET
+{
+ setS1 SET { b1 BOOLEAN,
+ i1 INTEGER },
+ setS2 [7] SET { b2 BOOLEAN,
+ i2 INTEGER },
+ setS3 [8] EXPLICIT SET { b3 BOOLEAN,
+ i3 INTEGER }
+}
+
+
+SetTRset ::= SET
+{
+ setSet SetSet,
+ setSetI [124] SetSet,
+ setSetE [125] EXPLICIT SetSet,
+
+ setSet-I SetSetImp,
+ setSetI-I [224] SetSetImp,
+ setSetE-I [225] EXPLICIT SetSetImp,
+
+ setSet-E SetSetExp,
+ setSetI-E [324] SetSetExp,
+ setSetE-E [325] EXPLICIT SetSetExp
+
+}
+
+SetSet ::= SET {
+ setInt INTEGER,
+ setOs OCTET STRING
+ }
+
+SetSetImp ::= [54] SET {
+ setInt INTEGER,
+ setOs OCTET STRING
+ }
+
+SetSetExp ::= [55] EXPLICIT SET {
+ setInt INTEGER,
+ setOs OCTET STRING
+ }
+
+
+END
diff --git a/lib/asn1/test/asn1_SUITE_data/String.py b/lib/asn1/test/asn1_SUITE_data/String.py
new file mode 100644
index 0000000000..338d50784b
--- /dev/null
+++ b/lib/asn1/test/asn1_SUITE_data/String.py
@@ -0,0 +1,7 @@
+String DEFINITIONS IMPLICIT TAGS ::=
+BEGIN
+EXPORTS;
+
+IA51 ::= IA5String (SIZE (1..128)) (FROM ("0123456789#*,"))
+
+END
diff --git a/lib/asn1/test/asn1_SUITE_data/SwCDR.py b/lib/asn1/test/asn1_SUITE_data/SwCDR.py
new file mode 100644
index 0000000000..9492183cdf
--- /dev/null
+++ b/lib/asn1/test/asn1_SUITE_data/SwCDR.py
@@ -0,0 +1,213 @@
+SwCDR DEFINITIONS
+ IMPLICIT TAGS ::=
+
+
+BEGIN
+
+EXPORTS
+ SwCDR;
+
+SwCDR ::= CHOICE
+{
+ origSvcCallRecord [0] OrigSvcCallRecord,
+ termSvcCallRecord [1] TermSvcCallRecord
+}
+
+--OrigSvcCallRecord ::= SET
+OrigSvcCallRecord ::= SEQUENCE
+{
+ callCorrelationId [0] INTEGER ,
+ chargingIndicator [1] ChargingIndicator,
+ sequenceNo [2] INTEGER ,
+ callingParty [3] CallingNumber,
+ calledParty [4] CalledNumber,
+ connectedNumber [5] ConnectedNumber,
+ startDate [6] StartDate,
+ startTime [7] StartTime,
+ duration [8] CallDuration ,
+-- bearerClass [] BearerClass ,
+ trafficType [9] TrafficType ,
+ qosFwd [10] QoSClass ,
+ qosBkwd [11] QoSClass ,
+ forwardPcrClp0 [12] CellRate ,
+ forwardPcrClp01 [13] CellRate ,
+ backwardPcrClp0 [14] CellRate ,
+ backwardPcrClp01 [15] CellRate ,
+ forwardScrClp0 [16] CellRate ,
+ forwardScrClp01 [17] CellRate ,
+ backwardScrClp0 [18] CellRate ,
+ backwardScrClp01 [19] CellRate ,
+ forwardMcrClp0 [20] CellRate ,
+ forwardMcrClp01 [21] CellRate ,
+ backwardMcrClp0 [22] CellRate ,
+ backwardMcrClp01 [23] CellRate ,
+ forwardMbsClp0 [24] CellRate ,
+ forwardMbsClp01 [25] CellRate ,
+ forwardBEI [26] INTEGER ,
+ backwardBEI [27] INTEGER ,
+ forwardTagging [28] INTEGER ,
+ backwardTagging [29] INTEGER ,
+-- egressCellrate0 [] INTEGER,
+-- egressCellrate01 [] INTEGER,
+ ingressCellrate0 [30] INTEGER ,
+-- ingressCellrate01 [] INTEGER ,
+ ingressCellrate1 [31] INTEGER ,
+ connectionConfig [32] UserPlaneConnection OPTIONAL
+-- causeForTerm [33] CauseForTerm OPTIONAL
+}
+
+--TermSvcCallRecord ::= SET
+TermSvcCallRecord ::= SEQUENCE
+{
+ callCorrelationId [0] INTEGER ,
+ chargingIndicator [1] ChargingIndicator,
+ sequenceNo [2] INTEGER ,
+ callingParty [3] CallingNumber,
+ calledParty [4] CalledNumber,
+ connectedNumber [5] ConnectedNumber,
+ startDate [6] StartDate,
+ startTime [7] StartTime,
+ duration [8] CallDuration ,
+-- bearerClass [] BearerClass ,
+ trafficType [9] TrafficType ,
+ qosFwd [10] QoSClass ,
+ qosBkwd [11] QoSClass ,
+ forwardPcrClp0 [12] CellRate ,
+ forwardPcrClp01 [13] CellRate ,
+ backwardPcrClp0 [14] CellRate ,
+ backwardPcrClp01 [15] CellRate ,
+ forwardScrClp0 [16] CellRate ,
+ forwardScrClp01 [17] CellRate ,
+ backwardScrClp0 [18] CellRate ,
+ backwardScrClp01 [19] CellRate ,
+ forwardMcrClp0 [20] CellRate ,
+ forwardMcrClp01 [21] CellRate ,
+ backwardMcrClp0 [22] CellRate ,
+ backwardMcrClp01 [23] CellRate ,
+ forwardMbsClp0 [24] CellRate ,
+ forwardMbsClp01 [25] CellRate ,
+ forwardBEI [26] INTEGER ,
+ backwardBEI [27] INTEGER ,
+ forwardTagging [28] INTEGER ,
+ backwardTagging [29] INTEGER ,
+-- egressCellrate0 [] INTEGER ,
+-- egressCellrate01 [] INTEGER ,
+ ingressCellrate0 [30] INTEGER ,
+-- ingressCellrate01 [] INTEGER ,
+ ingressCellrate1 [31] INTEGER ,
+ connectionConfig [32] UserPlaneConnection OPTIONAL
+-- causeForTerm [33] CauseForTerm OPTIONAL
+}
+
+ChargingIndicator ::= INTEGER
+{
+ origCallRecord (0),
+ termCallRecord (1)
+}
+
+CallingNumber ::= OCTET STRING (SIZE (12))
+ -- BCD encoded representation of the number.
+ -- Contains: TypeOfNumber, NumberingPlanInformation
+ -- and either an E.164 number or a NSAP style of number,
+ -- including a possible subaddress.
+CalledNumber ::= OCTET STRING (SIZE (20))
+ -- BCD encoded representation of the number.
+ -- Contains: TypeOfNumber, NumberingPlanInformation,
+ -- PresentationIndicator, ScreeningIndicator
+ -- and either an E.164 number or a NSAP style of number,
+ -- including a possible subaddress.
+
+ConnectedNumber ::= OCTET STRING (SIZE (12))
+ -- BCD encoded representation of the number.
+ -- Contains: TypeOfNumber, NumberingPlanInformation,
+ -- PresentationIndicator, ScreeningIndicator
+ -- and either an E.164 number or a NSAP style of number,
+ -- including a possible subaddress.
+
+
+QoSClass ::= INTEGER
+ -- Explicit values ToBeDefined,
+ -- until then: value received in SETUP-msg
+
+--BearerClass ::= INTEGER
+--{
+-- bcobA (0),
+-- bcobC (1),
+-- bcobX (2)
+--}
+TrafficType ::= INTEGER
+{
+ noIndication (0),
+ abr (1),
+ cbr (2),
+ vbr (3),
+ vbrrt (4),
+ vbrnrt (5),
+ ubr (6)
+}
+
+--TimingRequirements ::= INTEGER
+--{
+-- noIndication (0),
+-- endToEndRequired (1),
+-- endToEndNotRequired (2)
+--}
+
+--ClippingSusceptibility ::= INTEGER
+--{
+-- notSusceptible (0),
+-- susceptible (1)
+--}
+UserPlaneConnection ::= INTEGER
+{
+ pointToPoint (0),
+ pointToMultipoint (1)
+}
+
+--AALParameters ::= INTEGER AAL Type only
+--{
+-- userDefined (0),
+-- aal1 (1),
+-- aal2 (2),
+-- aal34 (3),
+-- aal5 (5)
+--}
+
+CellRate ::= INTEGER
+ -- Value range not less than 2^24.
+
+-- BurstSize ::= ToBeDefined
+
+-- TaggingRequest ::= ToBeDefined
+--Timestamp ::= OCTET STRING (SIZE (11))
+ -- The contents of this field is a compact form of
+ -- the UTCTime format, containing local time plus
+ -- an offset to universal time.
+ -- The compact format is YYMMDDhhmmssdddShhmm, where:
+ -- YY = year, 00-99, BCD encoded
+ -- MM = month, 01-12, BCD encoded
+ -- DD = day, 01-31, BCD encoded
+ -- hh = hour, 00-23, BCD encoded
+ -- mm = minute, 00-59, BCD encoded
+ -- ss = second, 00-59, BCD encoded
+ -- ddd = millisecond, 000-999, BCD encoded
+ -- and rightjustified as "0ddd"
+ -- S = sign, "+"/"-", ASCII encoded
+
+StartDate ::= OCTET STRING (SIZE (8))
+
+StartTime ::= OCTET STRING (SIZE (6))
+
+CallDuration ::= INTEGER
+-- Expressed as number of millseconds
+
+Cellrate ::= INTEGER
+-- Value range 0-2^64
+CauseForTerm ::= INTEGER
+{
+ unsuccessfulCallAttempt (0),
+ abnormalTermination (1)
+}
+
+END
+
diff --git a/lib/asn1/test/asn1_SUITE_data/Syntax.py b/lib/asn1/test/asn1_SUITE_data/Syntax.py
new file mode 100644
index 0000000000..867d1148e1
--- /dev/null
+++ b/lib/asn1/test/asn1_SUITE_data/Syntax.py
@@ -0,0 +1,10 @@
+Syntax DEFINITIONS IMPLICIT TAGS ::=
+BEGIN
+EXPORTS Person;
+
+Person ::= [PRIVATE 19] SEQUENCE {,
+ name PrintableString,
+ location INTEGER {home(0),field(1),roving(2)},
+ age INTEGER OPTIONAL
+ }
+END
diff --git a/lib/asn1/test/asn1_SUITE_data/TCAPMessages-simple.asn b/lib/asn1/test/asn1_SUITE_data/TCAPMessages-simple.asn
new file mode 100644
index 0000000000..a9ace659d5
--- /dev/null
+++ b/lib/asn1/test/asn1_SUITE_data/TCAPMessages-simple.asn
@@ -0,0 +1,206 @@
+TCAPMessages-simple { ccitt recommendation q 773 modules (2) messages (1) version2 (2) }
+
+DEFINITIONS ::=
+
+BEGIN
+
+EXPORTS OPERATION, ERROR, Component, InvokeIdType;
+
+-- Transaction Portion fields
+
+MessageType ::= CHOICE { unidirectional [APPLICATION 1] IMPLICIT Unidirectional,
+ begin [APPLICATION 2] IMPLICIT Begin,
+ end [APPLICATION 4] IMPLICIT End,
+ continue [APPLICATION 5] IMPLICIT Continue,
+ abort [APPLICATION 7] IMPLICIT Abort }
+
+Unidirectional ::= SEQUENCE {
+ dialoguePortion DialoguePortion OPTIONAL,
+ components ComponentPortion }
+
+Begin ::= SEQUENCE {
+ otid OrigTransactionID,
+ dialoguePortion DialoguePortion OPTIONAL,
+ components ComponentPortion OPTIONAL
+ }
+
+End ::= SEQUENCE {
+ dtid DestTransactionID,
+ dialoguePortion DialoguePortion OPTIONAL,
+ components ComponentPortion OPTIONAL
+ }
+
+Continue ::= SEQUENCE {
+ otid OrigTransactionID,
+ dtid DestTransactionID,
+ dialoguePortion DialoguePortion OPTIONAL,
+ components ComponentPortion OPTIONAL
+ }
+
+Abort ::= SEQUENCE {
+ dtid DestTransactionID,
+ reason CHOICE { p-abortCause P-AbortCause, u-abortCause DialoguePortion } OPTIONAL
+ }
+
+-- NOTE When the Abort Message is generated by the Transaction sublayer, a p-Abort Cause must be
+-- present.The u-abortCause may be generated by the component sublayer in which case it is an ABRT
+-- APDU, or by the TC-User in which case it could be either an ABRT APDU or data in some user-defined
+-- abstract syntax.
+
+DialoguePortion ::= [APPLICATION 11] EXTERNAL
+
+-- The dialogue portion carries the dialogue control PDUs as value of the external data type.
+-- The direct reference should be set to { ccitt recommendation q 773 as (1) dialogue-as (1) version (1) }
+-- if structured dialogue is used and to { ccitt recommendation q 773 as (1) unidialogue-as (2) version (1) }
+-- if unstructured dialogue is used or any user defined abstract syntax name when only user information
+-- is carried (e.g. when user information is sent in a 1988 Abort message).
+
+OrigTransactionID ::= [APPLICATION 8] IMPLICIT OCTET STRING (SIZE (1..4) )
+DestTransactionID ::= [APPLICATION 9] IMPLICIT OCTET STRING (SIZE (1..4) )
+
+P-AbortCause ::= [APPLICATION 10] IMPLICIT INTEGER {
+ unrecognizedMessageType (0),
+ unrecognizedTransactionID (1),
+ badlyFormattedTransactionPortion (2),
+ incorrectTransactionPortion (3),
+ resourceLimitation (4) }
+
+-- COMPONENT PORTION. The last field in the transaction portion of the TCAP message is the Component Portion.
+-- The Component Portion may be absent.
+
+ComponentPortion ::= [APPLICATION 12] IMPLICIT SEQUENCE SIZE (1..MAX) OF Component
+
+-- Component Portion fields
+-- COMPONENT TYPE. Recommendation X.229 defines four Application Protocol Data Units (APDUs).
+-- TCAP adds returnResultNotLast to allow for the segmentation of a result.
+
+Component ::= CHOICE {
+ invoke [1] IMPLICIT Invoke,
+ returnResultLast [2] IMPLICIT ReturnResult,
+ returnError [3] IMPLICIT ReturnError,
+ reject [4] IMPLICIT Reject,
+ returnResultNotLast [7] IMPLICIT ReturnResult }
+
+-- The Components are sequences of data elements.
+
+Invoke ::= SEQUENCE {
+ invokeID InvokeIdType,
+ linkedID [0] IMPLICIT InvokeIdType OPTIONAL,
+ operationCode OPERATION,
+ parameter ANY DEFINED BY operationCode OPTIONAL }
+
+-- ANY is filled by the single ASN.1 data type following the keyword PARAMETER or the keyword ARGUMENT
+-- in the type definition of a particular operation.
+
+ReturnResult ::= SEQUENCE {
+ invokeID InvokeIdType,
+ result SEQUENCE {
+ operationCode OPERATION,
+ parameter ANY DEFINED BY operationCode
+ } OPTIONAL
+ }
+
+-- ANY is filled by the single ASN.1 data type following the keyword RESULT in the type definition
+-- of a particular operation.
+
+ReturnError ::= SEQUENCE {
+ invokeID InvokeIdType,
+ errorCode ERROR,
+ parameter ANY DEFINED BY errorCode OPTIONAL }
+
+-- ANY is filled by the single ASN.1 data type following the keyword PARAMETER in the type definition
+-- of a particular error.
+
+
+
+-- Recommendation Q.773 (06/97) 3
+
+Reject ::= SEQUENCE {
+ invokeID CHOICE {
+ derivable InvokeIdType,
+ not-derivable NULL },
+ problem CHOICE {
+ generalProblem [0] IMPLICIT GeneralProblem,
+ invokeProblem [1] IMPLICIT InvokeProblem,
+ returnResultProblem [2] IMPLICIT ReturnResultProblem,
+ returnErrorProblem [3] IMPLICIT ReturnErrorProblem
+ }
+ }
+
+InvokeIdType ::= INTEGER ( -128..127)
+
+-- OPERATIONS
+-- Operations are specified with the OPERATION MACRO.
+-- When an operation is specified, the valid parameter set, results, and errors for that operation are indicated.
+-- Default values and optional parameters are permitted.
+
+-- FAKE OPERATION
+OPERATION ::= INTEGER ( 0..65535 )
+ERROR ::= INTEGER ( 0..65535 )
+
+--OPERATION MACRO ::=
+--BEGIN
+-- TYPE NOTATION ::= Parameter Result Errors LinkedOperations
+-- VALUE NOTATION ::= value (VALUE CHOICE { localValue INTEGER, globalValue OBJECT IDENTIFIER } )
+-- Parameter ::= ArgKeyword NamedType | empty ArgKeyword ::= "ARGUMENT" | "PARAMETER"
+-- Result ::= "RESULT" ResultType | empty
+-- Errors ::= "ERRORS" "{"ErrorNames"}" | empty
+-- LinkedOperations ::= "LINKED" "{"LinkedOperationNames"}" | empty
+-- ResultType ::= NamedType | empty
+-- ErrorNames ::= ErrorList | empty
+-- ErrorList ::= Error | ErrorList "," Error
+-- Error ::= value (ERROR)
+--
+-- shall reference an error value
+--
+-- | type
+-- shall reference an error type
+--
+-- if no error value is specified
+-- LinkedOperationNames ::= OperationList | empty
+-- OperationList ::= Operation | OperationList "," Operation
+-- Operation ::= value (OPERATION)
+-- shall reference an operation value
+-- | type
+-- shall reference an operation type if
+--
+-- no operation value is specified
+-- NamedType ::= identifier type | type
+--END
+
+-- ERRORS
+-- Errors are specified with the ERROR MACRO.
+-- When an error is specified, the valid parameters for that error are indicated.
+-- Default values and optional parameters are permitted.
+
+--ERROR MACRO ::=
+--BEGIN
+-- TYPE NOTATION ::= Parameter
+-- VALUE NOTATION ::= value (VALUE CHOICE { localValue INTEGER, globalValue OBJECT IDENTIFIER } )
+-- Parameter ::= "PARAMETER" NamedType | empty
+-- NamedType ::= identifier type | type
+--END
+
+-- PROBLEMS
+
+GeneralProblem ::= INTEGER { unrecognizedComponent (0),
+ mistypedComponent (1),
+ badlyStructuredComponent (2) }
+InvokeProblem ::= INTEGER { duplicateInvokeID (0),
+ unrecognizedOperation (1),
+ mistypedParameter (2),
+ resourceLimitation (3),
+ initiatingRelease (4),
+ unrecognizedLinkedID (5),
+ linkedResponseUnexpected (6),
+ unexpectedLinkedOperation (7) }
+ReturnResultProblem ::= INTEGER { unrecognizedInvokeID (0),
+ returnResultUnexpected (1),
+ mistypedParameter (2) }
+ReturnErrorProblem ::= INTEGER { unrecognizedInvokeID (0),
+ returnErrorUnexpected (1),
+ unrecognizedError (2),
+ unexpectedError (3),
+ mistypedParameter (4) }
+
+END -- TCAPMessages
diff --git a/lib/asn1/test/asn1_SUITE_data/TCAPMessages.asn b/lib/asn1/test/asn1_SUITE_data/TCAPMessages.asn
new file mode 100644
index 0000000000..ed8b4c6927
--- /dev/null
+++ b/lib/asn1/test/asn1_SUITE_data/TCAPMessages.asn
@@ -0,0 +1,98 @@
+-- Module TCAPMessages (Q.773:06/1997)
+-- See also the README file
+-- See also the index of all ASN.1 assignments needed in this Recommendation
+
+TCAPMessages {itu-t recommendation q 773 modules(2) messages(1) version3(3)}
+DEFINITIONS IMPLICIT TAGS ::=
+BEGIN
+
+-- EXPORTS everything
+-- Transaction Portion fields.
+IMPORTS
+ ROS{}, InvokeId
+ FROM Remote-Operations-Generic-ROS-PDUs {joint-iso-itu-t
+ remote-operations(4) generic-ROS-PDUs(6) version1(0)}
+ OPERATION
+ FROM Remote-Operations-Information-Objects {joint-iso-itu-t
+ remote-operations(4) informationObjects(5) version1(0)};
+
+TCMessage{OPERATION:Invokable, OPERATION:Returnable} ::= CHOICE {
+ unidirectional [APPLICATION 1] Unidirectional{{Invokable}, {Returnable}},
+ begin [APPLICATION 2] Begin{{Invokable}, {Returnable}},
+ end [APPLICATION 4] End{{Invokable}, {Returnable}},
+ continue [APPLICATION 5] Continue{{Invokable}, {Returnable}},
+ abort [APPLICATION 7] Abort
+}
+
+Unidirectional{OPERATION:Invokable, OPERATION:Returnable} ::= SEQUENCE {
+ dialoguePortion DialoguePortion OPTIONAL,
+ components ComponentPortion{{Invokable}, {Returnable}}
+}
+
+Begin{OPERATION:Invokable, OPERATION:Returnable} ::= SEQUENCE {
+ otid OrigTransactionID,
+ dialoguePortion DialoguePortion OPTIONAL,
+ components ComponentPortion{{Invokable}, {Returnable}} OPTIONAL
+}
+
+End{OPERATION:Invokable, OPERATION:Returnable} ::= SEQUENCE {
+ dtid DestTransactionID,
+ dialoguePortion DialoguePortion OPTIONAL,
+ components ComponentPortion{{Invokable}, {Returnable}} OPTIONAL
+}
+
+Continue{OPERATION:Invokable, OPERATION:Returnable} ::= SEQUENCE {
+ otid OrigTransactionID,
+ dtid DestTransactionID,
+ dialoguePortion DialoguePortion OPTIONAL,
+ components ComponentPortion{{Invokable}, {Returnable}} OPTIONAL
+}
+
+Abort ::= SEQUENCE {
+ dtid DestTransactionID,
+ reason CHOICE {p-abortCause P-AbortCause,
+ u-abortCause DialoguePortion} OPTIONAL
+}
+
+-- NOTE - When the Abort Message is generated by the Transaction sublayer, a p-Abort Cause may be
+-- present. The u-abortCause may be generated by the component sublayer in which case it is an ABRT
+-- APDU, or by the TC-User in which case it could be either an ABRT APDU or data in some user-defined
+-- abstract syntax.
+DialoguePortion ::= [APPLICATION 11] EXPLICIT EXTERNAL
+
+-- The dialogue portion carries the dialogue control PDUs as value of the external data type. The direct
+-- reference should be set to {itu-t recommendation q 773 as(1) dialogue-as(1) version1(1)} if structured
+-- dialogue is used and to {itu-t recommendation q 773 as(1) unidialogue-as(2) version1(1)} if unstructured
+-- dialogue is used.
+OrigTransactionID ::= [APPLICATION 8] OCTET STRING(SIZE (1..4))
+
+DestTransactionID ::= [APPLICATION 9] OCTET STRING(SIZE (1..4))
+
+P-AbortCause ::= [APPLICATION 10] INTEGER {
+ unrecognizedMessageType(0), unrecognizedTransactionID(1),
+ badlyFormattedTransactionPortion(2), incorrectTransactionPortion(3),
+ resourceLimitation(4)}(0..127)
+
+-- COMPONENT PORTION. The last field in the transaction portion of the TCAP message is the
+-- component portion. The component portion may be absent.
+ComponentPortion{OPERATION:Invokable, OPERATION:Returnable} ::=
+ [APPLICATION 12]
+ SEQUENCE SIZE (1..MAX) OF Component{{Invokable}, {Returnable}}
+
+-- Component Portion fields
+-- Recommendation X.880 defines four Application Protocol Data Units (APDUs) for invoking
+-- operations, returning results or error, and for the rejection of invalid PDUs.
+-- TCAP adds returnResultNotLast to allow for the segmentation of a result.
+Component{OPERATION:Invokable, OPERATION:Returnable} ::= CHOICE {
+ basicROS ROS{{TCInvokeIdSet}, {Invokable}, {Returnable}},
+ returnResultNotLast
+ [7] returnResult < ROS{{TCInvokeIdSet}, {Invokable}, {Returnable}}
+}
+
+TCInvokeIdSet ::= InvokeId(WITH COMPONENTS {
+ present (-128..127)
+ })
+
+END -- TCAPMessages
+
+-- Generated by Asnp, the ASN.1 pretty-printer of France Telecom R&D \ No newline at end of file
diff --git a/lib/asn1/test/asn1_SUITE_data/TCAPPackage.asn b/lib/asn1/test/asn1_SUITE_data/TCAPPackage.asn
new file mode 100644
index 0000000000..fcaeff3bfa
--- /dev/null
+++ b/lib/asn1/test/asn1_SUITE_data/TCAPPackage.asn
@@ -0,0 +1,271 @@
+TCAPPackage {iso(1) memberbody(2) usa(840) t1-114(10013) modules(0)
+ tcapPackage(0) version4(4)} DEFINITIONS ::=
+
+-- iso(1) memberbody(2)
+-- usa(840) T1.114(10013)
+BEGIN -- defining a module called TCAPPackage which contains type
+
+-- definitions for the contents of any generic TCAP message
+-- exports everything
+IMPORTS
+ OPERATION, ERROR
+ FROM Remote-Operations-Information-Objects {joint-iso-itu-t remote-operations(4) informationObjects(5) version1(0)};
+-- TCAPRemoteperationsInformationbjects {iso(1) memberbody(2) usa(840)
+-- t1-114(10013) modules(0) information-objects(1) version4(4)};
+
+PackageType ::= CHOICE {
+ unidirectional [PRIVATE 1] IMPLICIT UniTransactionPDU,
+ queryWithPerm [PRIVATE 2] IMPLICIT TransactionPDU,
+ queryWithoutPerm [PRIVATE 3] IMPLICIT TransactionPDU,
+ response [PRIVATE 4] IMPLICIT TransactionPDU,
+ conversationWithPerm [PRIVATE 5] IMPLICIT TransactionPDU,
+ conversationWithoutPerm [PRIVATE 6] IMPLICIT TransactionPDU,
+ abort [PRIVATE 22] IMPLICIT Abort}
+
+UniTransactionPDU ::= SEQUENCE {
+ identifier TransactionID,
+ dialoguePortion DialoguePortion OPTIONAL,
+ componentPortion ComponentSequence}
+
+TransactionPDU ::= SEQUENCE {
+ identifier TransactionID,
+ dialoguePortion DialoguePortion OPTIONAL,
+ componentPortion ComponentSequence OPTIONAL}
+
+-- TransactionPDU should include either a Dialogue Portion,
+-- a Component Sequence or both
+TransactionID ::= [PRIVATE 7] IMPLICIT OCTET STRING
+
+-- 0 octets for the Unidirectional, 4 octets for Query, Response & Abort
+-- 8 octets for Conversation in the order Originating then Responding TID
+Abort ::= SEQUENCE {
+ identifier TransactionID,
+ dialoguePortion DialoguePortion OPTIONAL,
+ causeInformation
+ CHOICE {abortCause P-Abort-cause,
+ userInformation UserAbortInformation} OPTIONAL}
+
+-- When the Abort package is generated by the Transaction sublayer,
+-- the P-Abort-cause must be present
+P-Abort-cause ::= [PRIVATE 23] IMPLICIT INTEGER {
+ unrecognizedPackageType(1), incorrectTransactionPortion(2),
+ badlyStructuredTransactionPortion(3), unassignedRespondingTransactionID(4),
+ permissionToReleaseProblem(5), -- for further study
+ resourceUnavailable(6), unrecognizedDialoguePortionID(7),
+ badlyStructuredDialoguePortion(8), missingDialoguePortion(9),
+ inconsistentDialoguePortion(10)}
+
+DialoguePortion ::= [PRIVATE 25] IMPLICIT SEQUENCE {
+ version ProtocolVersion OPTIONAL,
+ applicationContext
+ CHOICE {integerApplicationId IntegerApplicationContext,
+ objectApplicationId ObjectIDApplicationContext} OPTIONAL,
+ userInformation UserInformation OPTIONAL,
+ securityContext
+ CHOICE {integerSecurityId [0] IMPLICIT INTEGER,
+ objectSecurityId [1] IMPLICIT OBJECT IDENTIFIER} OPTIONAL,
+ confidentiality [2] IMPLICIT Confidentiality OPTIONAL}
+
+ProtocolVersion ::= [PRIVATE 26] IMPLICIT OCTET STRING(SIZE (1))
+
+-- 0000 0000 not used
+-- 0000 0001 T1.114-1996
+-- 0000 0010 T1.114-2000
+-- other reserved
+-- These values can be combined using the bit-wise logical or operation
+-- to indicate support for more than one version, e.g. the value 0000 0011
+-- means that both 1996 and 2000 versions are supported
+IntegerApplicationContext ::= [PRIVATE 27] IMPLICIT INTEGER
+
+ObjectIDApplicationContext ::= [PRIVATE 28] IMPLICIT OBJECT IDENTIFIER
+
+UserInformation ::= [PRIVATE 29] IMPLICIT SEQUENCE OF EXTERNAL
+
+Confidentiality ::= SEQUENCE {
+ confidentialityId
+ CHOICE {integerConfidentialityId [0] IMPLICIT INTEGER,
+ objectConfidentialityId [1] IMPLICIT OBJECT IDENTIFIER} OPTIONAL,
+ ...
+ -- The extension marker indicates the possible presence of items
+ -- in the confidentiality set that are used by the confidentiality
+ -- algorithm.--}
+
+UserAbortInformation ::= [PRIVATE 24] EXTERNAL
+
+--ComponentSequence ::= [PRIVATE 8] IMPLICIT SEQUENCE OF ComponentPDU
+ComponentSequence ::= [PRIVATE 8] IMPLICIT SEQUENCE OF ComponentPDU{NoInvokeId,ProbeAndAcknowledge,ProbeAndAcknowledge}
+-- Component Portion specification starts below
+ComponentPDU{InvokeId:InvokeIdSet, OPERATION:Invocable, OPERATION:Returnable}
+ ::= CHOICE {
+ invokeLast
+ [PRIVATE 9] IMPLICIT Invoke{{InvokeIdSet}, {Invocable}}
+ (CONSTRAINED BY {
+ --invocable.&invokeLast must be TRUE --} !
+ RejectProblem:generalincorrectComponentPortion),
+ returnResultLast [PRIVATE 10] IMPLICIT ReturnResult{{Returnable}},
+ returnError
+ [PRIVATE 11] IMPLICIT ReturnError{{Errors {{Returnable}}}},
+ reject [PRIVATE 12] IMPLICIT Reject,
+ invokeNotLast
+ [PRIVATE 13] IMPLICIT Invoke{{InvokeIdSet}, {Invocable}}
+ (CONSTRAINED BY {
+ --invocable.&invokeLast must be FALSE --} !
+ RejectProblem:generalincorrectComponentPortion),
+ returnResultNotLast [PRIVATE 14] IMPLICIT ReturnResult{{Returnable}}}
+ (CONSTRAINED BY { -- must conform to the above definition --} !
+ RejectProblem:generalunrecognisedComponentType)
+
+Invoke{InvokeId:InvokeIdSet, OPERATION:Operations} ::= SEQUENCE {
+ componentIDs
+ [PRIVATE 15] IMPLICIT OCTET STRING(SIZE (0..2))
+ -- The invoke ID precedes the correlation id. There may be no
+ -- identifier,only an invoke ID, or both invoke and correlation
+ -- ID.
+ (CONSTRAINED BY {-- must be unambiguous --} !
+ RejectProblem:invokeduplicateInvocation)
+ (CONSTRAINED BY {-- correlation ID must identify an--
+ -- outstanding operation --} !
+ RejectProblem:invokeunrecognisedCorrelationId)
+ OPTIONAL,
+ -- operationCode
+ opcode
+ OPERATION.&operationCode
+ -- ((Operations) !RejectProblem:invokeunrecognisedOperation),
+ ({Operations} !RejectProblem:invokeunrecognisedOperation),
+ parameter
+ -- OPERATION.&ParameterType
+ OPERATION.&ResultType
+ ({Operations}{@opcode} !RejectProblem:invoke-mistypedArgument) OPTIONAL}
+ (CONSTRAINED BY { -- must conform to the above definition --} !
+ RejectProblem:generalincorrectComponentPortion)
+ (CONSTRAINED BY { -- must have consistent encoding --} !
+ RejectProblem:generalbadlyStructuredCompPortion)
+ (CONSTRAINED BY { -- must conform to T1.114.3 encoding rules --} !
+ RejectProblem:generalincorrectComponentCoding)
+
+ReturnResult{OPERATION:Operations} ::= SEQUENCE {
+ componentID
+ [PRIVATE 15] IMPLICIT OCTET STRING(SIZE (1))
+ (CONSTRAINED BY {
+ --must be that of an outstanding operation--} !
+ RejectProblem:
+ returnResultunrecognisedCorrelationId)
+ (CONSTRAINED BY {-- which returns a result --} !
+ RejectProblem:returnResultunexpectedReturnResult),
+ parameter
+ OPERATION.&ResultType
+ -- ({Operations}{@opcode} !RejectProblem:returnResultincorrectParameter)
+-- ({Operations}{@componentID} !RejectProblem:returnResultincorrectParameter)
+ OPTIONAL}
+ (CONSTRAINED BY { -- must conform to the above definition --} !
+ RejectProblem:generalincorrectComponentPortion)
+ (CONSTRAINED BY { -- must have consistent encoding --} !
+ RejectProblem:generalbadlyStructuredCompPortion)
+ (CONSTRAINED BY { -- must conform to T1.114.3 encoding rules --} !
+ RejectProblem:generalincorrectComponentCoding)
+
+ReturnError{ERROR:Errors} ::= SEQUENCE {
+ componentID
+ [PRIVATE 15] IMPLICIT OCTET STRING(SIZE (1))
+ (CONSTRAINED BY {
+ --must be that of an outstanding operation--} !
+ RejectProblem:returnErrorunrecognisedCorrelationId)
+ (CONSTRAINED BY {--which returns an error--} !
+ RejectProblem:returnErrorunexpectedReturnError),
+ errorCode
+ ERROR.&errorCode({Errors} !RejectProblem:returnErrorunrecognisedError)
+ (CONSTRAINED BY {-- must be in the &Errors field of the--
+ -- associated operation --} !RejectProblem:returnErrorunexpectedError),
+ parameter
+ -- Error.&ParameterType
+ ERROR.&ParameterType
+ -- ({Errors}{@errorcode} !RejectProblem:returnErrorincorrectParameter)
+ ({Errors}{@errorCode} !RejectProblem:returnErrorincorrectParameter)
+ OPTIONAL}
+ (CONSTRAINED BY { -- must conform to the above definition --} !
+ RejectProblem:generalincorrectComponentPortion)
+ (CONSTRAINED BY { -- must have consistent encoding --} !
+ RejectProblem:generalbadlyStructuredCompPortion)
+ (CONSTRAINED BY { -- must conform to T1.114.3 encoding rules --} !
+ RejectProblem:generalincorrectComponentCoding)
+
+Reject ::= SEQUENCE {
+ componentID [PRIVATE 15] IMPLICIT OCTET STRING(SIZE (0..1)),
+ rejectProblem [PRIVATE 21] IMPLICIT Problem,
+ parameter
+ CHOICE {paramSequence [PRIVATE 16] IMPLICIT SEQUENCE {},
+ paramSet [PRIVATE 18] IMPLICIT SET {}}}
+ -- The choice between paramSequence and paramSet is implementation
+ -- dependent, however paramSequence is preferred.
+ (CONSTRAINED BY { -- must conform to the above definition --} !
+ RejectProblem:generalincorrectComponentPortion)
+ (CONSTRAINED BY { -- must have consistent encoding --} !
+ RejectProblem:generalbadlyStructuredCompPortion)
+ (CONSTRAINED BY { -- must conform to T1.114.3 encoding rules --} !
+ RejectProblem:generalincorrectComponentCoding)
+
+-- PROBLEMS, the specification of Problems follows
+Problem ::= INTEGER {
+ generalunrecognisedComponentType(257), generalincorrectComponentPortion(258),
+ generalbadlyStructuredCompPortion(259), generalincorrectComponentCoding(260),
+ invokeduplicateInvocation(513), invokeunrecognisedOperation(514),
+ invokeincorrectParameter(515), invokeunrecognisedCorrelationID(516),
+ returnResultunrecognisedCorrelationID(769),
+ returnResultunexpectedReturnResult(770), returnResultincorrectParameter(771),
+ returnErrorunrecognisedCorrelationID(1025),
+ returnErrorunexpectedReturnError(1026), returnErrorunrecognisedError(1027),
+ returnErrorunexpectedError(1028),
+ returnErrorincorrectParameter(1029),
+ -- Applications using T1.114-1988 report Transaction portion
+ -- problems using a Reject component with a problem code in
+ -- the range 1281e6
+ -- It is preferred that other applications report
+ -- these problems using the Abort package type
+ transactionunrecognizedPackageType(1281),
+ transactionincorrectTransPortion(1282),
+ transactionbadlyStructuredTransPortion(1283),
+ transactionunassignedRespondingTransID(1284),
+ transactionpermissionToReleaseProblem(1285),
+ transactionresourceUnavailable(1286)}
+
+ --added imaginary defs by Bertil
+
+ InvokeId ::= CHOICE
+{
+ present INTEGER,
+ absent NULL
+}
+
+noInvokeId InvokeId ::= absent:NULL
+
+NoInvokeId InvokeId ::= {noInvokeId}
+
+probe OPERATION ::=
+ {
+ ARGUMENT SEQUENCE
+ {
+ invokeId [0] InvokeId
+ }
+ RESULT ENUMERATED{running(0), finished(1), unknown(2), ...}
+ ERRORS ErrorSet
+ ALWAYS RESPONDS TRUE
+ CODE local:-2
+ }
+
+acknowledge OPERATION ::=
+ {
+ ARGUMENT InvokeId
+ RESULT ENUMERATED{acknowledged(0), unknown(1), ...}
+ ALWAYS RESPONDS TRUE
+ CODE local:-3
+ }
+
+ProbeAndAcknowledge OPERATION ::= {probe | acknowledge}
+
+error1 ERROR ::= {PARAMETER INTEGER PRIORITY 25 CODE local:22}
+error2 ERROR ::= {PARAMETER BOOLEAN PRIORITY 15 CODE local:21}
+ErrorSet ERROR ::= {error1|error2}
+--parameterized object set definition
+Errors{OPERATION:OperationSet} ERROR ::= {OperationSet.&Errors}
+
+END -- end of the TCAPPackage Module
diff --git a/lib/asn1/test/asn1_SUITE_data/TCAPPackage.asn1config b/lib/asn1/test/asn1_SUITE_data/TCAPPackage.asn1config
new file mode 100644
index 0000000000..b0ccd7d34c
--- /dev/null
+++ b/lib/asn1/test/asn1_SUITE_data/TCAPPackage.asn1config
@@ -0,0 +1,12 @@
+{exclusive_decode, {'TCAPPackage',
+ [{decode_PackageType, ['PackageType',
+ [{unidirectional, undecoded},
+ {queryWithPerm, [{componentPortion, parts}]},
+ {queryWithoutPerm, undecoded},
+ {response, [{componentPortion, parts}]},
+ {conversationWithPerm, undecoded},
+ {conversationWithoutPerm, undecoded},
+ {abort, undecoded}]]},
+ {decode_TransactionPDU, ['TransactionPDU',
+ [{componentPortion, parts}]]}]}}.
+
diff --git a/lib/asn1/test/asn1_SUITE_data/TCAPPackage_msg.erl b/lib/asn1/test/asn1_SUITE_data/TCAPPackage_msg.erl
new file mode 100644
index 0000000000..cc9a483f49
--- /dev/null
+++ b/lib/asn1/test/asn1_SUITE_data/TCAPPackage_msg.erl
@@ -0,0 +1,141 @@
+%%
+%% %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('TCAPPackage_msg').
+
+-compile(export_all).
+
+-include("TCAPPackage.hrl").
+
+val('PackageType',unidirectional) ->
+ {unidirectional,val('UniTransactionPDU')};
+val('PackageType',abort) ->
+ {abort,val('Abort')};
+val('PackageType',Component) ->
+ {Component,val('TransactionPDU')};
+val('ComponentPDU',1) ->
+ {invokeLast,val('Invoke')};
+val('ComponentPDU',2) ->
+ {returnResultLast,val('ReturnResult')};
+val('ComponentPDU',3) ->
+ {returnError,val('ReturnError')}.
+
+
+
+val('UniTransactionPDU') ->
+ #'UniTransactionPDU'{identifier=val('TransactionID'),
+ dialoguePortion=val('DialoguePortion'),
+ componentPortion=val('ComponentSequence')};
+val('TransactionPDU') ->
+ #'TransactionPDU'{identifier=val('TransactionID'),
+ dialoguePortion=val('DialoguePortion'),
+ componentPortion=val('ComponentSequence')};
+val('TransactionID') ->
+ "OCTET STRING";
+val('DialoguePortion') ->
+ #'DialoguePortion'{version=val('ProtocolVersion'),
+ applicationContext={integerApplicationId,12},
+ userInformation=val('UserInformation'),
+ securityContext={integerSecurityId,13},
+ confidentiality=val('Confidentiality')};
+val('Confidentiality') ->
+ #'Confidentiality'{confidentialityId={integerConfidentialityId,14}};
+val('ProtocolVersion') ->
+ "K";
+val('UserInformation') ->
+ [val('EXTERNAL'),val('EXTERNAL')];
+val('EXTERNAL') ->
+ #'EXTERNAL'{'direct-reference'={0,1,2},
+ encoding={'single-ASN1-type',[1,2,3,4]}};
+val('ComponentSequence') ->
+ [val('ComponentPDU',1),val('ComponentPDU',2),val('ComponentPDU',3)];
+val('Invoke') ->
+ #'Invoke'{componentIDs="AB",
+ opcode={local,-2},
+ parameter=running};
+val('ReturnResult') ->
+ #'ReturnResult'{componentID="C",
+ parameter=[1,2,3,4]};
+val('ReturnError') ->
+ #'ReturnError'{componentID="D",
+ errorCode={local,21},
+ parameter=true};
+val('Abort') ->
+ #'Abort'{identifier=val('TransactionID'),
+ dialoguePortion=val('DialoguePortion'),
+ causeInformation={abortCause,unrecognizedPackageType}};
+val(Type) ->
+ io:format("Missing type: ~p~n",[Type]).
+
+
+check_result('PackageType',unidirectional,Res) ->
+ {unidirectional,
+ {'UniTransactionPDU',
+ "OCTET STRING",
+ {'DialoguePortion',"K",
+ {integerApplicationId,12},
+ [_,%{'EXTERNAL',{syntax,{0,1,2}},asn1_NOVALUE,OTVal},
+ _],%{'EXTERNAL',{syntax,{0,1,2}},asn1_NOVALUE,OTVal}],
+ {integerSecurityId,13},
+ {'Confidentiality',
+ {integerConfidentialityId,14}}},
+ [{invokeLast,
+ {_,"AB",{local,-2},running}},
+ {returnResultLast,{_,"C",_}},
+ {returnError,{_,"D",{local,21},true}}]}} = Res,
+ ok;
+%% check_OT_val(OTVal);
+check_result('PackageType',abort,Res)->
+ {abort,{'Abort',"OCTET STRING",
+ {'DialoguePortion',"K",
+ {integerApplicationId,12},
+ [_,%{'EXTERNAL',{syntax,{0,1,2}},asn1_NOVALUE,OTVal},
+ _],%{'EXTERNAL',{syntax,{0,1,2}},asn1_NOVALUE,OTVal}],
+ {integerSecurityId,13},
+ {'Confidentiality',
+ {integerConfidentialityId,14}}},
+ {abortCause,unrecognizedPackageType}}} = Res,
+ ok;
+%% check_OT_val(OTVal);
+check_result('PackageType',response,Res) ->
+ {response,{'TransactionPDU',"OCTET STRING",
+ {'DialoguePortion',
+ "K",
+ {integerApplicationId,12},
+ [_,%{'EXTERNAL',{syntax,{0,1,2}},asn1_NOVALUE,OTVal},
+ _],%{'EXTERNAL',{syntax,{0,1,2}},asn1_NOVALUE,OTVal}],
+ {integerSecurityId,13},
+ {'Confidentiality',
+ {integerConfidentialityId,14}}},
+ [{invokeLast,
+ {_,"AB",{local,-2},running}},
+ {returnResultLast,
+ {_,"C",_}},
+ {returnError,
+ {_,"D",{local,21},true}}]}} = Res,
+ ok.
+%% check_OT_val(OTVal).
+
+check_OT_val([160,4,1,2,3,4]) ->
+ ok;
+check_OT_val(<<160,4,1,2,3,4>>) ->
+ ok;
+check_OT_val(_) ->
+ error.
+
diff --git a/lib/asn1/test/asn1_SUITE_data/TConstr.asn1 b/lib/asn1/test/asn1_SUITE_data/TConstr.asn1
new file mode 100644
index 0000000000..63f5dbde77
--- /dev/null
+++ b/lib/asn1/test/asn1_SUITE_data/TConstr.asn1
@@ -0,0 +1,95 @@
+-- The idea with this spec is to gather definitions that has a
+-- complicated structure of table constraints.
+TConstr DEFINITIONS AUTOMATIC TAGS ::=
+
+BEGIN
+
+MYCLASS ::= CLASS {
+ &id OBJECT IDENTIFIER UNIQUE,
+ &Type,
+ &Result OPTIONAL
+} WITH SYNTAX {
+ ID &id
+ TYPE &Type
+ [RESULT &Result]
+}
+
+object1 MYCLASS ::= {ID id-object1 TYPE Type-object1 RESULT INTEGER}
+object2 MYCLASS ::= {ID id-object2 TYPE Type-object2}
+object3 MYCLASS ::= {ID id-object3 TYPE Type-object3 RESULT BOOLEAN}
+
+ObjectSet MYCLASS ::= {object1 | object2 | object3}
+
+id-object1 OBJECT IDENTIFIER ::= {2 4}
+id-object2 OBJECT IDENTIFIER ::= {2 5}
+id-object3 OBJECT IDENTIFIER ::= {2 6 7}
+
+
+Type-object1 ::= SEQUENCE {
+ a INTEGER,
+ b BOOLEAN
+}
+
+Type-object2 ::= ENUMERATED {first, second, third}
+
+Type-object3 ::= CHOICE {
+ first SEQUENCE {a BOOLEAN, b INTEGER},
+ second INTEGER
+}
+
+Seq1 ::= SEQUENCE {
+ a SEQUENCE {aa INTEGER, ab MYCLASS.&id ({ObjectSet})},
+ b SEQUENCE {ba INTEGER, bb MYCLASS.&Type ({ObjectSet}{@a.ab})}
+}
+
+Seq2 ::= SEQUENCE {
+ identity INTEGER,
+ content SEQUENCE {
+ subid MYCLASS.&id ({ObjectSet}),
+ subcontent MYCLASS.&Type ({ObjectSet}{@content.subid}),
+ subresult MYCLASS.&Result ({ObjectSet}{@content.subid})
+ }
+}
+
+
+-- following from Peter's definitions
+
+
+MY-CLASS ::= CLASS {
+ &id OBJECT IDENTIFIER UNIQUE,
+ &Type }
+ WITH SYNTAX {
+ ID &id
+ TYPE &Type }
+
+Info ::= SEQUENCE {
+ xyz SEQUENCE {
+ abc MY-CLASS.&id({Supported})
+ },
+ uvw MY-CLASS.&Type ({Supported}{@xyz.abc}) }
+
+Supported MY-CLASS ::= { dsa | rsa }
+
+-- dsa
+
+ id-dsa OBJECT IDENTIFIER ::= { 1 2 }
+
+ DSAPublicKey ::= INTEGER -- public key, y
+
+ dsa MY-CLASS ::= {
+ ID id-dsa
+ TYPE DSAPublicKey }
+
+-- rsa
+
+ rsaEncryption OBJECT IDENTIFIER ::= { 1 3 4 }
+
+ RSAPublicKey ::= SEQUENCE {
+ modulus INTEGER, -- n
+ publicExponent INTEGER } -- e
+
+ rsa MY-CLASS ::= {
+ ID rsaEncryption
+ TYPE RSAPublicKey }
+
+END
diff --git a/lib/asn1/test/asn1_SUITE_data/TConstrChoice.asn1 b/lib/asn1/test/asn1_SUITE_data/TConstrChoice.asn1
new file mode 100644
index 0000000000..4f17786e78
--- /dev/null
+++ b/lib/asn1/test/asn1_SUITE_data/TConstrChoice.asn1
@@ -0,0 +1,175 @@
+TConstrChoice DEFINITIONS ::=
+BEGIN
+
+
+FilterItem ::= CHOICE {
+ equality [0] AttributeValueAssertion,
+ substrings [1] SEQUENCE {
+ type ATTRIBUTE.&id({SupportedAttributes}),
+ strings SEQUENCE OF CHOICE {
+ initial [0] ATTRIBUTE.&Type
+ ({SupportedAttributes}{@substrings.type}),
+ any [1] ATTRIBUTE.&Type
+ ({SupportedAttributes}{@substrings.type}),
+ final [2] ATTRIBUTE.&Type
+ ({SupportedAttributes}{@substrings.type}) }},
+ greaterOrEqual [2] AttributeValueAssertion,
+ lessOrEqual [3] AttributeValueAssertion,
+ present [4] AttributeType,
+ approximateMatch [5] AttributeValueAssertion,
+ extensibleMatch [6] MatchingRuleAssertion }
+
+AttributeValueAssertion ::= SEQUENCE {
+ type ATTRIBUTE.&id({SupportedAttributes}),
+ assertion ATTRIBUTE.&equality-match.&AssertionType
+ ({SupportedAttributes}{@type}) }
+
+MatchingRuleAssertion ::= SEQUENCE {
+ type MATCHING-RULE.&id({MatchingRules}),
+ assertion MATCHING-RULE.&AssertionType ({MatchingRules}{@type})
+ }
+
+AttributeType ::= INTEGER(0..127)
+
+ATTRIBUTE ::= CLASS {
+ &derivation ATTRIBUTE OPTIONAL,
+ &Type OPTIONAL,
+ &equality-match MATCHING-RULE OPTIONAL,
+ &ordering-match MATCHING-RULE OPTIONAL,
+ &substrings-match MATCHING-RULE OPTIONAL,
+ &single-valued BOOLEAN DEFAULT FALSE,
+ &collective BOOLEAN DEFAULT FALSE,
+ &no-user-modification BOOLEAN DEFAULT FALSE,
+ &usage Attribute-Usage DEFAULT userApplications,
+ &id OBJECT IDENTIFIER UNIQUE }
+WITH SYNTAX {
+ [SUBTYPE OF &derivation]
+ [WITH SYNTAX &Type]
+ [EQUALITY MATCHING RULE &equality-match]
+ [ORDERING MATCHING RULE &ordering-match]
+ [SUBSTRINGS MATCHING RULE &substrings-match]
+ [SINGLE VALUE &single-valued]
+ [COLLECTIVE &collective]
+ [NO USER MODIFICATION &no-user-modification]
+ [USAGE &usage]
+ ID &id }
+
+Attribute-Usage ::= ENUMERATED { userApplications(0),
+ directoryOperation(1), distributedOperation(2),
+ dSAOperation(3) }
+
+
+surname ATTRIBUTE ::= { -- family name
+ SUBTYPE OF name
+ WITH SYNTAX DirectoryString
+ ID id-at-surname }
+
+givenName ATTRIBUTE ::= { -- first name
+ SUBTYPE OF name
+ WITH SYNTAX DirectoryString
+ ID id-at-givenName }
+
+countryName ATTRIBUTE ::= { -- country
+ SUBTYPE OF name
+ WITH SYNTAX PrintableString (SIZE (2)) -- [ISO3166] codes
+ SINGLE VALUE TRUE
+ ID id-at-countryName}
+
+SupportedAttributes ATTRIBUTE ::=
+{surname | givenName | countryName}
+
+-- id-at-surname DirectoryString ::= universalString:"SureName"
+
+id-at-surname OBJECT IDENTIFIER ::= {2 4}
+
+-- id-at-givenName DirectoryString ::= printableString:"GivenName"
+
+id-at-givenName OBJECT IDENTIFIER ::= {2 5}
+
+-- id-at-countryName PrintableString (SIZE (2)) ::= "CN"
+
+id-at-countryName OBJECT IDENTIFIER ::= {2 6}
+
+MATCHING-RULE ::= CLASS {
+ &AssertionType OPTIONAL,
+ &id OBJECT IDENTIFIER UNIQUE }
+WITH SYNTAX {
+ [SYNTAX &AssertionType]
+ ID &id }
+
+MatchingRules MATCHING-RULE ::= {
+ caseIgnoreMatch | booleanMatch | integerMatch }
+
+LessMatchingRules MATCHING-RULE ::= {
+ MatchingRules EXCEPT caseIgnoreMatch }
+
+ExtensibleMatchingRules MATCHING-RULE ::= {
+ caseIgnoreMatch | booleanMatch | integerMatch, ... }
+
+name ATTRIBUTE ::= {
+ WITH SYNTAX DirectoryString
+ EQUALITY MATCHING RULE caseIgnoreMatch
+ ID id-name }
+
+
+DirectoryString ::= CHOICE {
+ teletexString TeletexString (SIZE (1..maxSize)),
+ printableString PrintableString (SIZE (1..maxSize)),
+ universalString UniversalString (SIZE (1..maxSize)),
+ bmpString BMPString (SIZE (1..maxSize))
+-- utf8String UTF8String (SIZE (1..maxSize))
+ }
+
+maxSize INTEGER ::= 25
+
+caseIgnoreMatch MATCHING-RULE ::= {
+ SYNTAX DirectoryString
+ ID id-caseIgnoreMatch
+ }
+
+booleanMatch MATCHING-RULE ::= {
+ SYNTAX BOOLEAN
+ ID id-booleanMatch
+ }
+
+integerMatch MATCHING-RULE ::= {
+ SYNTAX INTEGER
+ ID id-integerMatch
+ }
+
+id-mr OBJECT IDENTIFIER ::=
+{2 5 11}
+
+id-name OBJECT IDENTIFIER ::= {2 5 11 5}
+
+id-caseIgnoreMatch OBJECT IDENTIFIER ::= {2 5 11 2}
+
+id-booleanMatch OBJECT IDENTIFIER ::= {2 5 11 13}
+
+id-integerMatch OBJECT IDENTIFIER ::= {2 5 11 14}
+
+--{joint-iso-itu-t ds(5) matchingRule(13)}
+
+-- test code for OTP-4248
+
+NOTUNIQUE ::= CLASS {
+ &value INTEGER,
+ &Type
+}
+WITH SYNTAX {
+ VALUE &value
+ TYPE &Type
+}
+
+
+nuObject NOTUNIQUE ::= {VALUE 3 TYPE FilterItem}
+
+NuObjectSet NOTUNIQUE ::= {nuObject}
+
+Seq ::= SEQUENCE {
+ a NOTUNIQUE.&value ({NuObjectSet}),
+ b NOTUNIQUE.&Type ({NuObjectSet}{@a})
+}
+
+
+END
diff --git a/lib/asn1/test/asn1_SUITE_data/Time.py b/lib/asn1/test/asn1_SUITE_data/Time.py
new file mode 100644
index 0000000000..e3672464e4
--- /dev/null
+++ b/lib/asn1/test/asn1_SUITE_data/Time.py
@@ -0,0 +1,7 @@
+Time DEFINITIONS IMPLICIT TAGS ::=
+BEGIN
+EXPORTS;
+
+Pstr ::= PrintableString
+
+END
diff --git a/lib/asn1/test/asn1_SUITE_data/Tst.py b/lib/asn1/test/asn1_SUITE_data/Tst.py
new file mode 100644
index 0000000000..d80b32dad5
--- /dev/null
+++ b/lib/asn1/test/asn1_SUITE_data/Tst.py
@@ -0,0 +1,153 @@
+Tst { 2 6 6 24 7 1 } DEFINITIONS IMPLICIT TAGS ::=
+
+BEGIN
+
+--EXPORTS SomeSet , Id0 , Aset,Id1 ,A,B,C,
+-- Uhh ,Foo ,Cho,Person,Hobbe,Robbe,X,Y;
+
+IMPORTS Fooo FROM Bobby;
+
+
+Robbe ::= SET {
+ ttt TT }
+
+Koo ::= SET {
+ c CHOICE {
+ a INTEGER,
+ b BOOLEAN },
+ s SET OF Id0 }
+
+
+Hobbe ::= [APPLICATION 1] SET {
+ aaa [0] SET OF INTEGER,
+ bbb [1] UU
+ }
+
+UU ::= PP
+PP ::= CHOICE {
+ cc [1] CHOICE {
+ a [0] INTEGER,
+ b [1] BOOLEAN,
+ c [2] BIT STRING },
+ ii [0] Id0
+ }
+
+
+TT ::= SS
+SS ::= SET {
+ b BOOLEAN DEFAULT TRUE
+ }
+
+Aset ::= [PRIVATE 2] SET OF Uhh
+
+
+
+SomeSet ::= [PRIVATE 3] IMPLICIT SET {
+ aaaa [2] SET{
+ ggg [0] INTEGER},
+ kkkk [1] SET OF Id2,
+ booby [4] OCTET STRING,
+ puck [3] INTEGER {red(0),blue(1),yellow(-2)},
+ baby [5] IMPLICIT Id1,
+ bool [6] BOOLEAN }
+
+
+Id0 ::= INTEGER (4 .. 99)
+
+Id1 ::= Id0
+
+Id2 ::= [PRIVATE 4] EXPLICIT Id1
+
+
+Uhh ::= SET {
+ a [1] IMPLICIT Id1}
+
+
+
+Soon ::= [PRIVATE 5] Moon
+
+Moon ::= [PRIVATE 6] IMPLICIT Person
+
+
+Person ::= [PRIVATE 7] IMPLICIT SEQUENCE {
+ szzzs SET OF SET {
+ aaa [0] INTEGER,
+ bbb [1] Id0},
+ cho Cho,
+ name OCTET STRING ,
+ location INTEGER,
+ asss Aset,
+ oops [2] IMPLICIT SET {
+ q [0] INTEGER,
+ p [1] Uhh},
+ on INTEGER,
+ mybits [3] IMPLICIT BIT STRING,
+ foo Foo,
+ age INTEGER,
+ hobbe [5] SEQUENCE {
+ a [4] CHOICE {
+ a INTEGER,
+ b BOOLEAN },
+ b [5] Id0}}
+
+
+
+
+
+Foo ::= [PRIVATE 8] IMPLICIT SEQUENCE {
+ goofy [3] INTEGER OPTIONAL,
+ somestring [10] IMPLICIT OCTET STRING DEFAULT '77BB'H,
+ hoohoo [11] IMPLICIT SEQUENCE {
+ bar [1] Id1 OPTIONAL,
+ foo INTEGER,
+ zombie [9] CHOICE {
+ a [1] IMPLICIT INTEGER,
+ b [2] IMPLICIT BOOLEAN }
+ },
+ moon [4] IMPLICIT INTEGER }
+
+
+
+Cho ::= [PRIVATE 9] EXPLICIT CHOICE {
+ somestring [2] IMPLICIT OCTET STRING,
+ goofy [9] INTEGER,
+ moon [4] IMPLICIT INTEGER }
+
+
+A ::= [APPLICATION 2] SET {
+ ppp IA5String ,
+ a [0] INTEGER {aaa(6),bbb(77)} DEFAULT 998,
+ b [1] Id1 OPTIONAL,
+ c [2] OCTET STRING (SIZE(8)),
+ dd [3] BIT STRING DEFAULT '11001'B }
+
+B ::= [APPLICATION 3] SET {
+ ww [1] SET {
+ a A OPTIONAL,
+ goofy [3] INTEGER OPTIONAL,
+ somestring [10] IMPLICIT OCTET STRING DEFAULT '77BB'H }
+ }
+
+
+C::= [APPLICATION 4] SEQUENCE OF X
+
+Y ::= OBJECT IDENTIFIER
+
+X ::= SET {
+ a NULL,
+ b GeneralString,
+ c UTCTime,
+ d VideotexString,
+ g GeneralizedTime,
+ h GraphicString,
+ i VisibleString,
+ j IA5String,
+ k PrintableString,
+ l OCTET STRING,
+ e TeletexString,
+ m ANY,
+ n ObjectDescriptor,
+ o OBJECT IDENTIFIER,
+ f NumericString }
+
+END
diff --git a/lib/asn1/test/asn1_SUITE_data/Two.py b/lib/asn1/test/asn1_SUITE_data/Two.py
new file mode 100644
index 0000000000..c8e6f1a55b
--- /dev/null
+++ b/lib/asn1/test/asn1_SUITE_data/Two.py
@@ -0,0 +1,34 @@
+Two { 1 2 3} DEFINITIONS EXPLICIT TAGS ::=
+
+BEGIN
+EXPORTS A, D,Boo,Szz;
+
+
+
+D ::= [PRIVATE 1] SEQUENCE {
+ a INTEGER,
+ b Boo,
+ c ANY DEFINED BY a ,
+ d ANY }
+
+
+Boo ::= SEQUENCE OF INTEGER (198..200)
+
+A ::= [PRIVATE 2] SEQUENCE {
+ a INTEGER (1..1),
+ b INTEGER (3..3) }
+
+
+Szz ::= CHOICE {
+ one INTEGER,
+ two BOOLEAN }
+
+C ::= SET {
+ a [0] INTEGER (0..8),
+ xx [4] CHOICE {
+ [7] INTEGER (9..10),
+ a INTEGER (11 ..13) },
+ f Boo,
+ r [2] INTEGER (20..22)}
+END
+
diff --git a/lib/asn1/test/asn1_SUITE_data/UPERDefault.asn b/lib/asn1/test/asn1_SUITE_data/UPERDefault.asn
new file mode 100644
index 0000000000..7b81a0e09f
--- /dev/null
+++ b/lib/asn1/test/asn1_SUITE_data/UPERDefault.asn
@@ -0,0 +1,18 @@
+UPERDefault DEFINITIONS AUTOMATIC TAGS ::=
+
+BEGIN
+
+-- OTP-7681
+Int ::= INTEGER (0..32767)
+
+Seq ::= SEQUENCE {
+ a Int,
+ b INTEGER (-27..27) DEFAULT 0, -- OTP-7678
+ c INTEGER OPTIONAL
+}
+
+seq Seq ::=
+{a 12,
+ b 0}
+
+END \ No newline at end of file
diff --git a/lib/asn1/test/asn1_SUITE_data/UndefType.py b/lib/asn1/test/asn1_SUITE_data/UndefType.py
new file mode 100644
index 0000000000..cdbe083803
--- /dev/null
+++ b/lib/asn1/test/asn1_SUITE_data/UndefType.py
@@ -0,0 +1,14 @@
+Person DEFINITIONS IMPLICIT TAGS ::=
+BEGIN
+EXPORTS Person;
+IMPORTS
+ ImportedFromUndefined FROM UndefinedModule;
+
+Feltyp ::= UndefinedType
+Feltyp2 ::= ImportedFromUndefined
+Person ::= [PRIVATE 19] SEQUENCE {
+ name Undefined,
+ location INTEGER {home(0),field(1),roving(2)},
+ age ImportedFromUndefined OPTIONAL
+ }
+END
diff --git a/lib/asn1/test/asn1_SUITE_data/UpperBounds.asn b/lib/asn1/test/asn1_SUITE_data/UpperBounds.asn
new file mode 100755
index 0000000000..247260495b
--- /dev/null
+++ b/lib/asn1/test/asn1_SUITE_data/UpperBounds.asn
@@ -0,0 +1,89 @@
+-- Module UpperBounds (X.520:08/1997)
+
+UpperBounds {joint-iso-itu-t ds(5) module(1) upperBounds(10) 3} DEFINITIONS ::=
+BEGIN
+
+-- EXPORTS All
+-- The types and values defined in this module are exported for use in the other ASN.1 modules contained
+-- within the Directory Specifications, and for the use of other applications which will use them to access
+-- Directory services. Other applications may use them for their own purposes, but this will not constrain
+-- extensions and modifications needed to maintain or improve the Directory service.
+ub-answerback INTEGER ::=
+ 8
+
+ub-business-category INTEGER ::= 128
+
+ub-common-name INTEGER ::= 64
+
+ub-country-code INTEGER ::= 4
+
+ub-description INTEGER ::= 1024
+
+ub-destination-indicator INTEGER ::= 128
+
+ub-directory-string-first-component-match INTEGER ::= 32768
+
+ub-international-isdn-number INTEGER ::= 16
+
+ub-knowledge-information INTEGER ::= 32768
+
+ub-locality-name INTEGER ::= 128
+
+ub-match INTEGER ::= 128
+
+ub-name INTEGER ::= 64
+
+ub-organization-name INTEGER ::= 64
+
+ub-organizational-unit-name INTEGER ::= 64
+
+ub-physical-office-name INTEGER ::= 128
+
+ub-post-office-box INTEGER ::= 40
+
+ub-postal-code INTEGER ::= 40
+
+ub-postal-line INTEGER ::= 6
+
+ub-postal-string INTEGER ::= 30
+
+ub-privacy-mark-length INTEGER ::= 128
+
+ub-schema INTEGER ::= 1024
+
+ub-search INTEGER ::= 1023-- This definition is missing; to be provided --
+
+ub-serial-number INTEGER ::= 64
+
+ub-state-name INTEGER ::= 128
+
+ub-street-address INTEGER ::= 128
+
+ub-surname INTEGER ::= 64
+
+ub-tag INTEGER ::= 64
+
+ub-telephone-number INTEGER ::= 32
+
+ub-teletex-terminal-id INTEGER ::= 1024
+
+ub-telex-number INTEGER ::= 14
+
+ub-title INTEGER ::= 64
+
+ub-user-password INTEGER ::= 128
+
+ub-x121-address INTEGER ::= 15
+
+ub-localeContextSyntax INTEGER ::= 128
+
+ub-locale-context-syntax INTEGER ::= 64
+
+ub-pseudonym INTEGER ::= 128
+
+ub-content INTEGER ::= 32768
+
+END -- UpperBounds
+
+-- Generated by Asnp, the ASN.1 pretty-printer of France Telecom R&D
+
diff --git a/lib/asn1/test/asn1_SUITE_data/UsefulDefinitions.asn b/lib/asn1/test/asn1_SUITE_data/UsefulDefinitions.asn
new file mode 100755
index 0000000000..d9601bb7d0
--- /dev/null
+++ b/lib/asn1/test/asn1_SUITE_data/UsefulDefinitions.asn
@@ -0,0 +1,238 @@
+-- Module UsefulDefinitions (X.501:08/1997)
+UsefulDefinitions {joint-iso-itu-t ds(5) module(1) usefulDefinitions(0) 3}
+DEFINITIONS ::=
+BEGIN
+
+-- EXPORTS All -
+-- The types and values defined in this module are exported for use in the other ASN.1 modules contained
+-- within the Directory Specifications, and for the use of other applications which will use them to access
+-- Directory services. Other applications may use them for their own purposes, but this will not constrain
+-- extensions and modifications needed to maintain or improve the Directory service.
+ID ::= OBJECT IDENTIFIER
+
+ds ID ::= {joint-iso-itu-t ds(5)}
+
+-- categories of information object
+module ID ::= {ds 1}
+
+serviceElement ID ::= {ds 2}
+
+applicationContext ID ::= {ds 3}
+
+attributeType ID ::= {ds 4}
+
+attributeSyntax ID ::= {ds 5}
+
+objectClass ID ::= {ds 6}
+
+-- attributeSet ID ::= {ds 7}
+algorithm ID ::= {ds 8}
+
+abstractSyntax ID ::= {ds 9}
+
+-- object ID ::= {ds 10}
+-- port ID ::= {ds 11}
+dsaOperationalAttribute ID ::=
+ {ds 12}
+
+matchingRule ID ::= {ds 13}
+
+knowledgeMatchingRule ID ::= {ds 14}
+
+nameForm ID ::= {ds 15}
+
+group ID ::= {ds 16}
+
+subentry ID ::= {ds 17}
+
+operationalAttributeType ID ::= {ds 18}
+
+operationalBinding ID ::= {ds 19}
+
+schemaObjectClass ID ::= {ds 20}
+
+schemaOperationalAttribute ID ::= {ds 21}
+
+administrativeRoles ID ::= {ds 23}
+
+accessControlAttribute ID ::= {ds 24}
+
+rosObject ID ::= {ds 25}
+
+contract ID ::= {ds 26}
+
+package ID ::= {ds 27}
+
+accessControlSchemes ID ::= {ds 28}
+
+certificateExtension ID ::= {ds 29}
+
+managementObject ID ::= {ds 30}
+
+attributeValueContext ID ::= {ds 31}
+
+-- securityExchange ID ::= {ds 32}
+idmProtocol ID ::= {ds 33}
+
+problem ID ::= {ds 34}
+
+notification ID ::= {ds 35}
+
+matchingRestriction ID ::=
+ {ds 36} -- None are currently defined by this specification
+
+controlAttributeType ID ::= {ds 37}
+
+-- modules
+usefulDefinitions ID ::= {module usefulDefinitions(0) 3}
+
+informationFramework ID ::= {module informationFramework(1) 3}
+
+directoryAbstractService ID ::= {module directoryAbstractService(2) 3}
+
+distributedOperations ID ::= {module distributedOperations(3) 3}
+
+protocolObjectIdentifiers ID ::= {module protocolObjectIdentifiers(4) 3}
+
+selectedAttributeTypes ID ::= {module selectedAttributeTypes(5) 3}
+
+selectedObjectClasses ID ::= {module selectedObjectClasses(6) 3}
+
+authenticationFramework ID ::= {module authenticationFramework(7) 3}
+
+algorithmObjectIdentifiers ID ::= {module algorithmObjectIdentifiers(8) 3}
+
+directoryObjectIdentifiers ID ::= {module directoryObjectIdentifiers(9) 3}
+
+upperBounds ID ::= {module upperBounds(10) 3}
+
+dap ID ::= {module dap(11) 3}
+
+dsp ID ::= {module dsp(12) 3}
+
+distributedDirectoryOIDs ID ::= {module distributedDirectoryOIDs(13) 3}
+
+directoryShadowOIDs ID ::= {module directoryShadowOIDs(14) 3}
+
+directoryShadowAbstractService ID ::=
+ {module directoryShadowAbstractService(15) 3}
+
+disp ID ::= {module disp(16) 3}
+
+dop ID ::= {module dop(17) 3}
+
+opBindingManagement ID ::= {module opBindingManagement(18) 3}
+
+opBindingOIDs ID ::= {module opBindingOIDs(19) 3}
+
+hierarchicalOperationalBindings ID ::=
+ {module hierarchicalOperationalBindings(20) 3}
+
+dsaOperationalAttributeTypes ID ::= {module dsaOperationalAttributeTypes(22) 3}
+
+schemaAdministration ID ::= {module schemaAdministration(23) 3}
+
+basicAccessControl ID ::= {module basicAccessControl(24) 3}
+
+directoryOperationalBindingTypes ID ::=
+ {module directoryOperationalBindingTypes(25) 3}
+
+certificateExtensions ID ::= {module certificateExtensions(26) 0}
+
+directoryManagement ID ::= {module directoryManagement(27) 1}
+
+enhancedSecurity ID ::= {module enhancedSecurity(28) 1}
+
+iDMProtocolSpecification ID ::= {module iDMProtocolSpecification(30) 4}
+
+directoryIDMProtocols ID ::= {module directoryIDMProtocols(31) 4}
+
+-- directorySecurityExchanges ID ::= {module directorySecurityExchanges (29) 1}
+-- synonyms
+id-oc ID ::=
+ objectClass
+
+id-at ID ::= attributeType
+
+id-as ID ::= abstractSyntax
+
+id-mr ID ::= matchingRule
+
+id-nf ID ::= nameForm
+
+id-sc ID ::= subentry
+
+id-oa ID ::= operationalAttributeType
+
+id-ob ID ::= operationalBinding
+
+id-doa ID ::= dsaOperationalAttribute
+
+id-kmr ID ::= knowledgeMatchingRule
+
+id-soc ID ::= schemaObjectClass
+
+id-soa ID ::= schemaOperationalAttribute
+
+id-ar ID ::= administrativeRoles
+
+id-aca ID ::= accessControlAttribute
+
+id-ac ID ::= applicationContext
+
+id-rosObject ID ::= rosObject
+
+id-contract ID ::= contract
+
+id-package ID ::= package
+
+id-acScheme ID ::= accessControlSchemes
+
+id-ce ID ::= certificateExtension
+
+id-mgt ID ::= managementObject
+
+id-idm ID ::= idmProtocol
+
+id-avc ID ::= attributeValueContext
+
+-- id-se ID ::= securityExchange
+id-pr ID ::= problem
+
+id-not ID ::= notification
+
+id-mre ID ::= matchingRestriction
+
+id-cat ID ::= controlAttributeType
+
+-- obsolete module identifiers
+-- usefulDefinition ID ::= {module 0}
+-- informationFramework ID ::= {module 1}
+-- directoryAbstractService ID ::= {module 2}
+-- distributedOperations ID ::= {module 3}
+-- protocolObjectIdentifiers ID ::= {module 4}
+-- selectedAttributeTypes ID ::= {module 5}
+-- selectedObjectClasses ID ::= {module 6}
+-- authenticationFramework ID ::= {module 7}
+-- algorithmObjectIdentifiers ID ::= {module 8}
+-- directoryObjectIdentifiers ID ::= {module 9}
+-- upperBounds ID ::= {module 10}
+-- dap ID ::= {module 11}
+-- dsp ID ::= {module 12}
+-- distributedDirectoryObjectIdentifiers ID ::= {module 13}
+-- unused module identifiers
+-- directoryShadowOIDs ID ::= {module 14}
+-- directoryShadowAbstractService ID ::= {module 15}
+-- disp ID ::= {module 16}
+-- dop ID ::= {module 17}
+-- opBindingManagement ID ::= {module 18}
+-- opBindingOIDs ID ::= {module 19}
+-- hierarchicalOperationalBindings ID ::= {module 20}
+-- dsaOperationalAttributeTypes ID ::= {module 22}
+-- schemaAdministration ID ::= {module 23}
+-- basicAccessControl ID ::= {module 24}
+-- operationalBindingOIDs ID ::= {module 25}
+END -- UsefulDefinitions
+
+-- Generated by Asnp, the ASN.1 pretty-printer of France Telecom R&D
+
diff --git a/lib/asn1/test/asn1_SUITE_data/ValueTest.asn b/lib/asn1/test/asn1_SUITE_data/ValueTest.asn
new file mode 100644
index 0000000000..dae9ae498a
--- /dev/null
+++ b/lib/asn1/test/asn1_SUITE_data/ValueTest.asn
@@ -0,0 +1,53 @@
+ValueTest DEFINITIONS ::=
+
+BEGIN
+
+--Criticality ::= ENUMERATED { reject, ignore, notify }(reject)
+
+--Ignore ::= Criticality(ignore)
+
+--SubCriticality ::= Criticality(reject|notify)
+
+INNL ::= INTEGER {zero(0),one(1),ten(10)}
+BSNNL ::= BIT STRING {zero(0),one(1),two(2)}
+RadioButton ::= ENUMERATED {button1(0),button2(1),button3(2)}
+
+-- OTP-6695
+vANY ANY ::= INTEGER:12
+
+-- basic type value test for coverage
+vBOOLEAN BOOLEAN ::= TRUE
+vINTEGER INTEGER ::= 12
+vINTEGERNNL INNL ::= zero
+vENUMERATED RadioButton ::= button1
+vBS BSNNL ::= {zero,two}
+vNULL NULL ::= NULL
+vOS OCTET STRING ::= '313233'H
+vOD OBJECT IDENTIFIER ::= {2 1 1}
+
+
+--Character strings
+numericstring NumericString ::= "01234567"
+printablestring PrintableString ::= "PrintableString"
+visiblestring VisibleString ::= "VisibleString"
+cr IA5String ::= {0,13}
+ia5string1 IA5String ::= {"First line",cr, "Second line"}
+ia5string2 IA5String ::= {{5,5},{4,4},{6,6}}
+teletexstring TeletexString ::= "TeletexString"
+videotexstring VideotexString ::= "VideotexString"
+utctime UTCTime ::= "97100211-0500"
+generalizedtime GeneralizedTime ::= "19971002103130.5"
+objectdescriptor ObjectDescriptor ::= "ObjectDescriptor"
+graphicstring GraphicString ::= "GraphicString"
+generalstring GeneralString ::= "GeneralString"
+bmpstring1 BMPString ::= "BMPString"
+--bmpstring2 BMPString ::= [{0,0,0,66},{0,0,0,77},{0,0,0,80},{0,0,0,115},{0,0,0,116},{0,0,0,114},{0,0,0,105},{0,0,0,110},{0,0,0,103}]
+latinCapitalLetterA UniversalString ::= {0,0,0,65}
+greekCapitalLetterSigma UniversalString ::= {0,0,3,145}
+my-universalstring UniversalString ::= {"This is a capital A: ",
+ latinCapitalLetterA,
+ ", and a capital sigma: ",
+ greekCapitalLetterSigma,
+ "; try and spot the difference!"}
+
+END
diff --git a/lib/asn1/test/asn1_SUITE_data/XSeq.py b/lib/asn1/test/asn1_SUITE_data/XSeq.py
new file mode 100644
index 0000000000..b068ab4393
--- /dev/null
+++ b/lib/asn1/test/asn1_SUITE_data/XSeq.py
@@ -0,0 +1,42 @@
+XSeq DEFINITIONS ::=
+BEGIN
+
+-- F.2.10.2
+-- Use a sequence type to model a collection of variables whose
+-- types are the same,
+-- whose number is known and modest, and whose order is significant,
+-- provided that the
+-- makeup of the collection is unlikely to change from one version
+-- of the protocol to the next.
+-- EXAMPLE
+
+NamesOfOfficers ::= SEQUENCE {
+ president VisibleString,
+ vicePresident VisibleString,
+ secretary VisibleString}
+
+acmeCorp NamesOfOfficers ::= {
+ president "Jane Doe",
+ vicePresident "John Doe",
+ secretary "Joe Doe"}
+
+-- F.2.10.3
+-- Use a sequence type to model a collection of variables whose types differ,
+-- whose number is known and modest, and whose order is significant,
+-- provided that
+-- the makeup of the collection is unlikely to change from one version
+-- of the protocol to the next.
+-- EXAMPLE
+
+Credentials ::= SEQUENCE {
+ userName VisibleString,
+ password VisibleString,
+ accountNumber INTEGER}
+
+-- Empty SEQUENCE stupid but just for test
+BasicCallCategories ::= SEQUENCE
+{
+ ... -- So far, no specific categories identified
+}
+
+END
diff --git a/lib/asn1/test/asn1_SUITE_data/XSeqOf.py b/lib/asn1/test/asn1_SUITE_data/XSeqOf.py
new file mode 100644
index 0000000000..f9fee92e56
--- /dev/null
+++ b/lib/asn1/test/asn1_SUITE_data/XSeqOf.py
@@ -0,0 +1,19 @@
+XSeqOf DEFINITIONS ::=
+BEGIN
+
+-- F.2.10.1
+-- Use a sequence-of type to model a collection of variables whose
+-- types are the same,
+-- whose number is large or unpredictable, and whose order is significant.
+-- EXAMPLE
+
+NamesOfMemberNations ::= SEQUENCE OF VisibleString
+-- in alphabetical order
+
+firstTwo NamesOfMemberNations ::= {"Australia", "Austria"}
+
+DayNames1 ::= SEQUENCE SIZE(7) OF VisibleString
+DayNames2 ::= SEQUENCE SIZE(1..7) OF VisibleString
+DayNames3 ::= SEQUENCE (SIZE(7)) OF VisibleString
+DayNames4 ::= SEQUENCE (SIZE(1..7)) OF VisibleString
+END
diff --git a/lib/asn1/test/asn1_SUITE_data/XSet.py b/lib/asn1/test/asn1_SUITE_data/XSet.py
new file mode 100644
index 0000000000..39e58a39ab
--- /dev/null
+++ b/lib/asn1/test/asn1_SUITE_data/XSet.py
@@ -0,0 +1,47 @@
+XSet DEFINITIONS ::=
+BEGIN
+
+-- F.2.11.1
+-- Use a set type to model a collection of variables whose number is
+-- known and modest
+-- and whose order is insignificant. If automatic tagging is not in
+-- effect, identify each
+-- variable by context-specifically tagging it as shown below.
+-- (With automatic tagging, the tags are not needed.)
+-- EXAMPLE
+
+ UserName ::= SET {
+ personalName [0] VisibleString,
+ organizationName [1] VisibleString,
+ countryName [2] VisibleString}
+
+ user UserName ::= {
+ countryName "Nigeria",
+ personalName "Jonas Maruba",
+ organizationName "Meteorology, Ltd."}
+
+ UserName2 ::= SET {
+ personalName [0] VisibleString,
+ organizationName [1] VisibleString OPTIONAL
+ -- defaults to that of the local organization -- ,
+ countryName [2] VisibleString OPTIONAL
+ -- defaults to that of the local country -- }
+
+-- F.2.11.3
+-- Use a set type to model a collection of variables whose makeup is
+-- likely to change
+-- from one version of the protocol to the next.
+-- Identify each variable by context-specifically
+-- tagging it to retain control of the tags used.
+-- EXAMPLE
+
+ UserName3 ::= SET {
+ personalName [0] VisibleString,
+ organizationName [1] VisibleString OPTIONAL ,
+ -- defaults to that of the local organization
+ countryName [2] VisibleString OPTIONAL
+ -- defaults to that of the local country
+ -- other optional attributes are for further study --}
+ user3 UserName3 ::= { personalName "Jonas Maruba" }
+
+END
diff --git a/lib/asn1/test/asn1_SUITE_data/XSetOf.py b/lib/asn1/test/asn1_SUITE_data/XSetOf.py
new file mode 100644
index 0000000000..93337d0c33
--- /dev/null
+++ b/lib/asn1/test/asn1_SUITE_data/XSetOf.py
@@ -0,0 +1,12 @@
+XSetOf DEFINITIONS ::=
+BEGIN
+
+-- F.2.11.4
+--Use a set-of type to model a collection of variables whose types are
+-- the same and whose order is insignificant.
+-- EXAMPLE
+
+ Keywords ::= SET OF VisibleString -- in arbitrary order
+ someASN1Keywords Keywords ::= {"INTEGER", "BOOLEAN", "REAL"}
+
+END
diff --git a/lib/asn1/test/asn1_SUITE_data/a_SeqIn.erl b/lib/asn1/test/asn1_SUITE_data/a_SeqIn.erl
new file mode 100644
index 0000000000..a447524358
--- /dev/null
+++ b/lib/asn1/test/asn1_SUITE_data/a_SeqIn.erl
@@ -0,0 +1,31 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 2008-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(a_SeqIn).
+
+-export([record_name/0]).
+
+-include("Seq.hrl").
+
+record_name()->
+ Rec = #a_SeqIn{boolIn=true,intIn=12},
+ element(1,Rec).
+
+
diff --git a/lib/asn1/test/asn1_SUITE_data/b_SeqIn.erl b/lib/asn1/test/asn1_SUITE_data/b_SeqIn.erl
new file mode 100644
index 0000000000..a416322b8c
--- /dev/null
+++ b/lib/asn1/test/asn1_SUITE_data/b_SeqIn.erl
@@ -0,0 +1,29 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 2008-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(b_SeqIn).
+
+-export([record_name/0]).
+
+-include("Seq.hrl").
+
+record_name()->
+ Rec = #b_SeqIn{boolIn=true,intIn=12},
+ element(1,Rec).
diff --git a/lib/asn1/test/asn1_SUITE_data/extensionAdditionGroup.erl b/lib/asn1/test/asn1_SUITE_data/extensionAdditionGroup.erl
new file mode 100644
index 0000000000..1cf2eb4088
--- /dev/null
+++ b/lib/asn1/test/asn1_SUITE_data/extensionAdditionGroup.erl
@@ -0,0 +1,131 @@
+%%%-------------------------------------------------------------------
+%%% File : extensionAdditionGroup.erl
+%%% Author : Kenneth Lundin
+%%% Description :
+%%%
+%%% Created : 18 May 2010 by kenneth
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 2001-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(extensionAdditionGroup).
+-include("Extension-Addition-Group.hrl").
+
+
+-compile(export_all).
+
+run(Erule) ->
+ Val = #'Ax'{a=253, b = true, c= {e,true}, g="123", h = true},
+ io:format("~p:~p~n",[Erule,Val]),
+ {ok,List}= asn1rt:encode('Extension-Addition-Group','Ax',Val),
+ Enc = iolist_to_binary(List),
+ io:format("~p~n",[Enc]),
+ {ok,Val2} = asn1rt:decode('Extension-Addition-Group','Ax',Enc),
+ io:format("~p~n",[Val2]),
+ case Val2 of
+ Val -> ok;
+ _ -> exit({expected,Val, got, Val2})
+ end.
+
+run2(Erule) ->
+ Val = #'Ax3'{a=253, b = true, s = #'Ax3_s'{sa = 11, sb = true, sextaddgroup = 17}},
+ io:format("~p:~p~n",[Erule,Val]),
+ {ok,List}= asn1rt:encode('Extension-Addition-Group','Ax3',Val),
+ Enc = iolist_to_binary(List),
+ io:format("~p~n",[Enc]),
+ {ok,Val2} = asn1rt:decode('Extension-Addition-Group','Ax3',Enc),
+ io:format("~p~n",[Val2]),
+ case Val2 of
+ Val -> ok;
+ _ -> exit({expected,Val, got, Val2})
+ end.
+
+run3(Erule) ->
+ Val =
+{'RRC-DL-DCCH-Message',
+ {c1,
+ {rrcConnectionReconfiguration,
+ {'RRC-RRCConnectionReconfiguration',0,
+ {c1,
+ {'rrcConnectionReconfiguration-r8',
+ {'RRC-RRCConnectionReconfiguration-r8-IEs',
+ {'RRC-MeasConfig',asn1_NOVALUE,asn1_NOVALUE,asn1_NOVALUE,asn1_NOVALUE,
+ asn1_NOVALUE,asn1_NOVALUE,asn1_NOVALUE,asn1_NOVALUE,asn1_NOVALUE,
+ asn1_NOVALUE,asn1_NOVALUE},
+ asn1_NOVALUE,
+ [[80,66,0,5,10,0,5,0,24,11,7,84,54,33,0,1,1,0,0,0,1,39,5,66,127,0,0,1],
+ []],
+ {'RRC-RadioResourceConfigDedicated',
+ [{'RRC-SRB-ToAddMod',1,
+ {explicitValue,
+ {am,
+ {'RRC-RLC-Config_am',
+ {'RRC-UL-AM-RLC',ms45,pInfinity,kBinfinity,t4},
+ {'RRC-DL-AM-RLC',ms35,ms0}}}},
+ {explicitValue,
+ {'RRC-LogicalChannelConfig',
+ {'RRC-LogicalChannelConfig_ul-SpecificParameters',3,infinity,
+ ms50,0},
+ asn1_NOVALUE}}}],
+ [{'RRC-DRB-ToAddMod',3,3,
+ {'RRC-PDCP-Config',infinity,
+ {'RRC-PDCP-Config_rlc-AM',false},
+ asn1_NOVALUE,
+ {notUsed,'NULL'}},
+ {am,
+ {'RRC-RLC-Config_am',
+ {'RRC-UL-AM-RLC',ms70,p256,kBinfinity,t4},
+ {'RRC-DL-AM-RLC',ms35,ms40}}},
+ 3,
+ {'RRC-LogicalChannelConfig',
+ {'RRC-LogicalChannelConfig_ul-SpecificParameters',5,infinity,ms50,
+ 1},
+ asn1_NOVALUE}},
+ {'RRC-DRB-ToAddMod',4,4,
+ {'RRC-PDCP-Config',infinity,
+ {'RRC-PDCP-Config_rlc-AM',false},
+ asn1_NOVALUE,
+ {notUsed,'NULL'}},
+ {am,
+ {'RRC-RLC-Config_am',
+ {'RRC-UL-AM-RLC',ms70,p256,kBinfinity,t4},
+ {'RRC-DL-AM-RLC',ms35,ms40}}},
+ 4,
+ {'RRC-LogicalChannelConfig',
+ {'RRC-LogicalChannelConfig_ul-SpecificParameters',5,infinity,ms50,
+ 1},
+ asn1_NOVALUE}}],
+ asn1_NOVALUE,
+ {explicitValue,
+ {'RRC-MAC-MainConfig',
+ {'RRC-MAC-MainConfig_ul-SCH-Config',n4,sf10,sf10240,false},
+ asn1_NOVALUE,sf500,
+ {setup,{'RRC-MAC-MainConfig_phr-Config_setup',sf200,sf200,dB3}},
+ asn1_NOVALUE}},
+ asn1_NOVALUE,asn1_NOVALUE,asn1_NOVALUE},
+ asn1_NOVALUE,asn1_NOVALUE}}}}}}},
+ io:format("~p:~p~n",[Erule,Val]),
+ {ok,List}= asn1rt:encode('EUTRA-RRC-Definitions','DL-DCCH-Message',Val),
+ Enc = iolist_to_binary(List),
+ io:format("Result from encode:~n~p~n",[Enc]),
+ {ok,Val2} = asn1rt:decode('EUTRA-RRC-Definitions','DL-DCCH-Message',Enc),
+ io:format("Result from decode:~n~p~n",[Val2]),
+ case Val2 of
+ Val -> ok;
+ _ -> exit({expected,Val, got, Val2})
+ end.
diff --git a/lib/asn1/test/asn1_SUITE_data/megacomessages/Msg1.val b/lib/asn1/test/asn1_SUITE_data/megacomessages/Msg1.val
new file mode 100644
index 0000000000..7802193dd2
--- /dev/null
+++ b/lib/asn1/test/asn1_SUITE_data/megacomessages/Msg1.val
Binary files differ
diff --git a/lib/asn1/test/asn1_SUITE_data/megacomessages/Msg10.val b/lib/asn1/test/asn1_SUITE_data/megacomessages/Msg10.val
new file mode 100644
index 0000000000..8ba4a710ba
--- /dev/null
+++ b/lib/asn1/test/asn1_SUITE_data/megacomessages/Msg10.val
Binary files differ
diff --git a/lib/asn1/test/asn1_SUITE_data/megacomessages/Msg11.val b/lib/asn1/test/asn1_SUITE_data/megacomessages/Msg11.val
new file mode 100644
index 0000000000..c2298be3d9
--- /dev/null
+++ b/lib/asn1/test/asn1_SUITE_data/megacomessages/Msg11.val
Binary files differ
diff --git a/lib/asn1/test/asn1_SUITE_data/megacomessages/Msg12.val b/lib/asn1/test/asn1_SUITE_data/megacomessages/Msg12.val
new file mode 100644
index 0000000000..cb5c0c666c
--- /dev/null
+++ b/lib/asn1/test/asn1_SUITE_data/megacomessages/Msg12.val
Binary files differ
diff --git a/lib/asn1/test/asn1_SUITE_data/megacomessages/Msg13.val b/lib/asn1/test/asn1_SUITE_data/megacomessages/Msg13.val
new file mode 100644
index 0000000000..3fe1df73bb
--- /dev/null
+++ b/lib/asn1/test/asn1_SUITE_data/megacomessages/Msg13.val
Binary files differ
diff --git a/lib/asn1/test/asn1_SUITE_data/megacomessages/Msg14.val b/lib/asn1/test/asn1_SUITE_data/megacomessages/Msg14.val
new file mode 100644
index 0000000000..17ad9159c5
--- /dev/null
+++ b/lib/asn1/test/asn1_SUITE_data/megacomessages/Msg14.val
Binary files differ
diff --git a/lib/asn1/test/asn1_SUITE_data/megacomessages/Msg15.val b/lib/asn1/test/asn1_SUITE_data/megacomessages/Msg15.val
new file mode 100644
index 0000000000..4ef840762d
--- /dev/null
+++ b/lib/asn1/test/asn1_SUITE_data/megacomessages/Msg15.val
Binary files differ
diff --git a/lib/asn1/test/asn1_SUITE_data/megacomessages/Msg16.val b/lib/asn1/test/asn1_SUITE_data/megacomessages/Msg16.val
new file mode 100644
index 0000000000..5252c4da38
--- /dev/null
+++ b/lib/asn1/test/asn1_SUITE_data/megacomessages/Msg16.val
Binary files differ
diff --git a/lib/asn1/test/asn1_SUITE_data/megacomessages/Msg17.val b/lib/asn1/test/asn1_SUITE_data/megacomessages/Msg17.val
new file mode 100644
index 0000000000..8e040d78a2
--- /dev/null
+++ b/lib/asn1/test/asn1_SUITE_data/megacomessages/Msg17.val
Binary files differ
diff --git a/lib/asn1/test/asn1_SUITE_data/megacomessages/Msg18.val b/lib/asn1/test/asn1_SUITE_data/megacomessages/Msg18.val
new file mode 100644
index 0000000000..0980cd37d4
--- /dev/null
+++ b/lib/asn1/test/asn1_SUITE_data/megacomessages/Msg18.val
Binary files differ
diff --git a/lib/asn1/test/asn1_SUITE_data/megacomessages/Msg19.val b/lib/asn1/test/asn1_SUITE_data/megacomessages/Msg19.val
new file mode 100644
index 0000000000..c49f885c71
--- /dev/null
+++ b/lib/asn1/test/asn1_SUITE_data/megacomessages/Msg19.val
Binary files differ
diff --git a/lib/asn1/test/asn1_SUITE_data/megacomessages/Msg2.val b/lib/asn1/test/asn1_SUITE_data/megacomessages/Msg2.val
new file mode 100644
index 0000000000..eeb8a5fb90
--- /dev/null
+++ b/lib/asn1/test/asn1_SUITE_data/megacomessages/Msg2.val
Binary files differ
diff --git a/lib/asn1/test/asn1_SUITE_data/megacomessages/Msg20.val b/lib/asn1/test/asn1_SUITE_data/megacomessages/Msg20.val
new file mode 100644
index 0000000000..7b55708fa6
--- /dev/null
+++ b/lib/asn1/test/asn1_SUITE_data/megacomessages/Msg20.val
Binary files differ
diff --git a/lib/asn1/test/asn1_SUITE_data/megacomessages/Msg21.val b/lib/asn1/test/asn1_SUITE_data/megacomessages/Msg21.val
new file mode 100644
index 0000000000..108eeb8b07
--- /dev/null
+++ b/lib/asn1/test/asn1_SUITE_data/megacomessages/Msg21.val
Binary files differ
diff --git a/lib/asn1/test/asn1_SUITE_data/megacomessages/Msg22.val b/lib/asn1/test/asn1_SUITE_data/megacomessages/Msg22.val
new file mode 100644
index 0000000000..3d9f9fefcf
--- /dev/null
+++ b/lib/asn1/test/asn1_SUITE_data/megacomessages/Msg22.val
Binary files differ
diff --git a/lib/asn1/test/asn1_SUITE_data/megacomessages/Msg23.val b/lib/asn1/test/asn1_SUITE_data/megacomessages/Msg23.val
new file mode 100644
index 0000000000..61a329a76a
--- /dev/null
+++ b/lib/asn1/test/asn1_SUITE_data/megacomessages/Msg23.val
Binary files differ
diff --git a/lib/asn1/test/asn1_SUITE_data/megacomessages/Msg24.val b/lib/asn1/test/asn1_SUITE_data/megacomessages/Msg24.val
new file mode 100644
index 0000000000..55adab5e8f
--- /dev/null
+++ b/lib/asn1/test/asn1_SUITE_data/megacomessages/Msg24.val
Binary files differ
diff --git a/lib/asn1/test/asn1_SUITE_data/megacomessages/Msg25.val b/lib/asn1/test/asn1_SUITE_data/megacomessages/Msg25.val
new file mode 100644
index 0000000000..d351fb575a
--- /dev/null
+++ b/lib/asn1/test/asn1_SUITE_data/megacomessages/Msg25.val
Binary files differ
diff --git a/lib/asn1/test/asn1_SUITE_data/megacomessages/Msg3.val b/lib/asn1/test/asn1_SUITE_data/megacomessages/Msg3.val
new file mode 100644
index 0000000000..01b7a1335a
--- /dev/null
+++ b/lib/asn1/test/asn1_SUITE_data/megacomessages/Msg3.val
Binary files differ
diff --git a/lib/asn1/test/asn1_SUITE_data/megacomessages/Msg4.val b/lib/asn1/test/asn1_SUITE_data/megacomessages/Msg4.val
new file mode 100644
index 0000000000..462033fa84
--- /dev/null
+++ b/lib/asn1/test/asn1_SUITE_data/megacomessages/Msg4.val
Binary files differ
diff --git a/lib/asn1/test/asn1_SUITE_data/megacomessages/Msg5.val b/lib/asn1/test/asn1_SUITE_data/megacomessages/Msg5.val
new file mode 100644
index 0000000000..78bdaa3200
--- /dev/null
+++ b/lib/asn1/test/asn1_SUITE_data/megacomessages/Msg5.val
Binary files differ
diff --git a/lib/asn1/test/asn1_SUITE_data/megacomessages/Msg6.val b/lib/asn1/test/asn1_SUITE_data/megacomessages/Msg6.val
new file mode 100644
index 0000000000..24af9044a8
--- /dev/null
+++ b/lib/asn1/test/asn1_SUITE_data/megacomessages/Msg6.val
Binary files differ
diff --git a/lib/asn1/test/asn1_SUITE_data/megacomessages/Msg7.val b/lib/asn1/test/asn1_SUITE_data/megacomessages/Msg7.val
new file mode 100644
index 0000000000..ab028e7128
--- /dev/null
+++ b/lib/asn1/test/asn1_SUITE_data/megacomessages/Msg7.val
Binary files differ
diff --git a/lib/asn1/test/asn1_SUITE_data/megacomessages/Msg8.val b/lib/asn1/test/asn1_SUITE_data/megacomessages/Msg8.val
new file mode 100644
index 0000000000..2d42b73c0c
--- /dev/null
+++ b/lib/asn1/test/asn1_SUITE_data/megacomessages/Msg8.val
Binary files differ
diff --git a/lib/asn1/test/asn1_SUITE_data/megacomessages/Msg9.val b/lib/asn1/test/asn1_SUITE_data/megacomessages/Msg9.val
new file mode 100644
index 0000000000..3581dc033a
--- /dev/null
+++ b/lib/asn1/test/asn1_SUITE_data/megacomessages/Msg9.val
Binary files differ
diff --git a/lib/asn1/test/asn1_SUITE_data/modified_x420/AuthenticationFramework.asn b/lib/asn1/test/asn1_SUITE_data/modified_x420/AuthenticationFramework.asn
new file mode 100644
index 0000000000..5cfa9062f0
--- /dev/null
+++ b/lib/asn1/test/asn1_SUITE_data/modified_x420/AuthenticationFramework.asn
@@ -0,0 +1,290 @@
+-- Module AuthenticationFramework (X.509:08/1997)
+
+AuthenticationFramework {joint-iso-itu-t ds(5) module(1)
+ authenticationFramework(7) 3} DEFINITIONS ::=
+BEGIN
+
+-- EXPORTS All
+-- The types and values defined in this module are exported for use in the other ASN.1 modules contained
+-- within the Directory Specifications, and for the use of other applications which will use them to access
+-- Directory services. Other applications may use them for their own purposes, but this will not constrain
+-- extensions and modifications needed to maintain or improve the Directory service.
+IMPORTS
+ id-at, id-mr, informationFramework, upperBounds, selectedAttributeTypes,
+ basicAccessControl, certificateExtensions
+ FROM UsefulDefinitions {joint-iso-itu-t ds(5) module(1)
+ usefulDefinitions(0) 3}
+ Name, ATTRIBUTE, AttributeType, MATCHING-RULE, Attribute
+ FROM InformationFramework informationFramework
+ ub-user-password
+ FROM UpperBounds upperBounds
+ AuthenticationLevel
+ FROM BasicAccessControl basicAccessControl
+ UniqueIdentifier, octetStringMatch
+ FROM SelectedAttributeTypes selectedAttributeTypes
+ certificateExactMatch, certificatePairExactMatch, certificateListExactMatch,
+ GeneralNames
+ FROM CertificateExtensions certificateExtensions;
+
+-- basic certificate definition
+Certificate ::=
+ SIGNED
+ {SEQUENCE {version [0] Version DEFAULT v1,
+ serialNumber CertificateSerialNumber,
+ signature AlgorithmIdentifier,
+ issuer Name,
+ validity Validity,
+ subject Name,
+ subjectPublicKeyInfo SubjectPublicKeyInfo,
+ issuerUniqueIdentifier [1] IMPLICIT UniqueIdentifier OPTIONAL,
+ -- if present, version must be v2 or v3
+ subjectUniqueIdentifier [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
+
+AlgorithmIdentifier ::= SEQUENCE {
+ algorithm ALGORITHM.&id({SupportedAlgorithms}),
+ parameters ALGORITHM.&Type({SupportedAlgorithms}{@algorithm}) OPTIONAL
+}
+
+-- Definition of the following information object set is deferred, perhaps to standardized
+-- profiles or to protocol implementation conformance statements. The set is required to
+-- specify a table constraint on the parameters component of AlgorithmIdentifier.
+SupportedAlgorithms ALGORITHM ::=
+{...}
+
+Validity ::= SEQUENCE {notBefore Time,
+ notAfter Time
+}
+
+SubjectPublicKeyInfo ::= SEQUENCE {
+ algorithm AlgorithmIdentifier,
+ subjectPublicKey BIT STRING
+}
+
+Time ::= CHOICE {utcTime UTCTime,
+ generalizedTime GeneralizedTime
+}
+
+Extensions ::= SEQUENCE OF Extension
+
+-- For those extensions where ordering of individual extensions within the SEQUENCE is significant, the
+-- specification of those individual extensions shall include the rules for the significance of the order therein
+Extension ::= SEQUENCE {
+ extnId EXTENSION.&id({ExtensionSet}),
+ critical BOOLEAN DEFAULT FALSE,
+ extnValue OCTET STRING-- contains a DER encoding of a value of type &ExtnType
+-- for the extension object identified by extnId
+}
+
+ExtensionSet EXTENSION ::=
+ {...}
+
+EXTENSION ::= CLASS {&id OBJECT IDENTIFIER UNIQUE,
+ &ExtnType
+}WITH SYNTAX {SYNTAX &ExtnType
+ IDENTIFIED BY &id
+}
+
+-- other certificate constructs
+Certificates ::= SEQUENCE {
+ userCertificate Certificate,
+ certificationPath ForwardCertificationPath OPTIONAL
+}
+
+ForwardCertificationPath ::= SEQUENCE OF CrossCertificates
+
+CrossCertificates ::= SET OF Certificate
+
+CertificationPath ::= SEQUENCE {
+ userCertificate Certificate,
+ theCACertificates SEQUENCE OF CertificatePair OPTIONAL
+}
+
+CertificatePair ::= SEQUENCE {
+ issuedByThisCA [0] Certificate OPTIONAL,
+ issuedToThisCA [1] Certificate OPTIONAL
+ -- at least one of the pair shall be present
+}
+
+-- Certificate Revocation List (CRL)
+CertificateList ::=
+ SIGNED
+ {SEQUENCE {version Version OPTIONAL,
+ -- if present, version must be v2
+ signature AlgorithmIdentifier,
+ issuer Name,
+ thisUpdate Time,
+ nextUpdate Time OPTIONAL,
+ revokedCertificates
+ SEQUENCE OF
+ SEQUENCE {userCertificate CertificateSerialNumber,
+ revocationDate Time,
+ crlEntryExtensions Extensions OPTIONAL} OPTIONAL,
+ crlExtensions [0] Extensions OPTIONAL}}
+
+-- attribute certificate
+AttributeCertificationPath ::= SEQUENCE {
+ attributeCertificate AttributeCertificate,
+ acPath SEQUENCE OF ACPathData OPTIONAL
+}
+
+ACPathData ::= SEQUENCE {
+ certificate [0] Certificate OPTIONAL,
+ attributeCertificate [1] AttributeCertificate OPTIONAL
+}
+
+attributeCertificate ATTRIBUTE ::= {
+ WITH SYNTAX AttributeCertificate
+ EQUALITY MATCHING RULE attributeCertificateMatch
+ ID id-at-attributeCertificate
+}
+
+AttributeCertificate ::= SIGNED{AttributeCertificateInfo}
+
+AttributeCertificateInfo ::= SEQUENCE {
+ version Version DEFAULT v1,
+ subject
+ CHOICE {baseCertificateID [0] IssuerSerial, -- associated with a Public Key Certificate--
+ subjectName [1] GeneralNames}, -- associated with a name
+ issuer GeneralNames, -- CA issuing the attribute certificate
+ signature AlgorithmIdentifier,
+ serialNumber CertificateSerialNumber,
+ attCertValidityPeriod AttCertValidityPeriod,
+ attributes SEQUENCE OF Attribute,
+ issuerUniqueID UniqueIdentifier OPTIONAL,
+ extensions Extensions OPTIONAL
+}
+
+IssuerSerial ::= SEQUENCE {
+ issuer GeneralNames,
+ serial CertificateSerialNumber,
+ issuerUID UniqueIdentifier OPTIONAL
+}
+
+AttCertValidityPeriod ::= SEQUENCE {
+ notBeforeTime GeneralizedTime,
+ notAfterTime GeneralizedTime
+}
+
+attributeCertificateMatch MATCHING-RULE ::= {
+ SYNTAX AttributeCertificateAssertion
+ ID id-mr-attributeCertificateMatch
+}
+
+AttributeCertificateAssertion ::= SEQUENCE {
+ subject
+ [0] CHOICE {baseCertificateID [0] IssuerSerial,
+ subjectName [1] Name} OPTIONAL,
+ issuer [1] Name OPTIONAL,
+ attCertValidity [2] GeneralizedTime OPTIONAL,
+ attType [3] SET OF AttributeType OPTIONAL
+}
+
+-- At least one component of the sequence must be present
+-- attribute types
+userPassword ATTRIBUTE ::= {
+ WITH SYNTAX OCTET STRING(SIZE (0..ub-user-password))
+ EQUALITY MATCHING RULE octetStringMatch
+ ID id-at-userPassword
+}
+
+userCertificate ATTRIBUTE ::= {
+ WITH SYNTAX Certificate
+ EQUALITY MATCHING RULE certificateExactMatch
+ ID id-at-userCertificate
+}
+
+cACertificate ATTRIBUTE ::= {
+ WITH SYNTAX Certificate
+ EQUALITY MATCHING RULE certificateExactMatch
+ ID id-at-cAcertificate
+}
+
+crossCertificatePair ATTRIBUTE ::= {
+ WITH SYNTAX CertificatePair
+ EQUALITY MATCHING RULE certificatePairExactMatch
+ ID id-at-crossCertificatePair
+}
+
+authorityRevocationList ATTRIBUTE ::= {
+ WITH SYNTAX CertificateList
+ EQUALITY MATCHING RULE certificateListExactMatch
+ ID id-at-authorityRevocationList
+}
+
+certificateRevocationList ATTRIBUTE ::= {
+ WITH SYNTAX CertificateList
+ EQUALITY MATCHING RULE certificateListExactMatch
+ ID id-at-certificateRevocationList
+}
+
+attributeCertificateRevocationList ATTRIBUTE ::= {
+ WITH SYNTAX CertificateList
+ ID id-at-attributeCertificateRevocationList
+}
+
+-- information object classes
+ALGORITHM ::= TYPE-IDENTIFIER
+
+-- parameterized types
+HASH{ToBeHashed} ::= SEQUENCE {
+ algorithmIdentifier AlgorithmIdentifier,
+ hashValue
+ BIT STRING
+ (CONSTRAINED BY {
+ -- must be the result of applying a hashing procedure to the DER-encoded octets
+ -- of a value of -- ToBeHashed})
+}
+
+ENCRYPTED-HASH{ToBeSigned} ::=
+ BIT STRING
+ (CONSTRAINED BY {
+ -- must be the result of applying a hashing procedure to the DER-encoded octets
+ -- of a value of --ToBeSigned -- and then applying an encipherment procedure to those octets --})
+
+ENCRYPTED{ToBeEnciphered} ::=
+ BIT STRING
+ (CONSTRAINED BY {
+ -- must be the result of applying an encipherment procedure
+ -- to the BER-encoded octets of a value of --ToBeEnciphered})
+
+SIGNATURE{ToBeSigned} ::= SEQUENCE {
+ algorithmIdentifier AlgorithmIdentifier,
+ encrypted ENCRYPTED-HASH{ToBeSigned}
+}
+
+SIGNED{ToBeSigned} ::= SEQUENCE {
+ toBeSigned ToBeSigned,
+ COMPONENTS OF SIGNATURE{ToBeSigned}
+}
+
+-- object identifier assignments
+id-at-userPassword OBJECT IDENTIFIER ::=
+ {id-at 35}
+
+id-at-userCertificate OBJECT IDENTIFIER ::= {id-at 36}
+
+id-at-cAcertificate OBJECT IDENTIFIER ::= {id-at 37}
+
+id-at-authorityRevocationList OBJECT IDENTIFIER ::= {id-at 38}
+
+id-at-certificateRevocationList OBJECT IDENTIFIER ::= {id-at 39}
+
+id-at-crossCertificatePair OBJECT IDENTIFIER ::= {id-at 40}
+
+id-at-attributeCertificate OBJECT IDENTIFIER ::= {id-at 58}
+
+id-at-attributeCertificateRevocationList OBJECT IDENTIFIER ::= {id-at 59}
+
+id-mr-attributeCertificateMatch OBJECT IDENTIFIER ::= {id-mr 42}
+
+END
+
+-- Generated by Asnp, the ASN.1 pretty-printer of France Telecom R&D
+
diff --git a/lib/asn1/test/asn1_SUITE_data/modified_x420/BasicAccessControl.asn b/lib/asn1/test/asn1_SUITE_data/modified_x420/BasicAccessControl.asn
new file mode 100644
index 0000000000..d8b2b687ae
--- /dev/null
+++ b/lib/asn1/test/asn1_SUITE_data/modified_x420/BasicAccessControl.asn
@@ -0,0 +1,184 @@
+-- Module BasicAccessControl (X.501:08/1997)
+BasicAccessControl {joint-iso-itu-t ds(5) module(1) basicAccessControl(24) 3}
+DEFINITIONS ::=
+BEGIN
+
+-- EXPORTS All
+-- The types and values defined in this module are exported for use in the other ASN.1 modules contained
+-- within the Directory Specifications, and for the use of other applications which will use them to access
+-- Directory services. Other applications may use them for their own purposes, but this will not constrain
+-- extensions and modifications needed to maintain or improve the Directory service.
+IMPORTS
+ id-aca, id-acScheme, informationFramework, upperBounds,
+ selectedAttributeTypes, directoryAbstractService
+ FROM UsefulDefinitions {joint-iso-itu-t ds(5) module(1)
+ usefulDefinitions(0) 3}
+ ATTRIBUTE, AttributeType, DistinguishedName, ContextAssertion,
+ SubtreeSpecification, SupportedAttributes, MATCHING-RULE,
+ objectIdentifierMatch, Refinement
+ FROM InformationFramework informationFramework
+ Filter
+ FROM DirectoryAbstractService directoryAbstractService
+ ub-tag
+ FROM UpperBounds upperBounds
+ NameAndOptionalUID, directoryStringFirstComponentMatch, DirectoryString{}
+ FROM SelectedAttributeTypes selectedAttributeTypes;
+
+-- types
+ACIItem ::= SEQUENCE {
+ identificationTag DirectoryString{ub-tag},
+ precedence Precedence,
+ authenticationLevel AuthenticationLevel,
+ itemOrUserFirst
+ CHOICE {itemFirst
+ [0] SEQUENCE {protectedItems ProtectedItems,
+ itemPermissions SET OF ItemPermission},
+ userFirst
+ [1] SEQUENCE {userClasses UserClasses,
+ userPermissions SET OF UserPermission}}
+}
+
+Precedence ::= INTEGER(0..255)
+
+ProtectedItems ::= SEQUENCE {
+ entry [0] NULL OPTIONAL,
+ allUserAttributeTypes [1] NULL OPTIONAL,
+ attributeType
+ [2] SET SIZE (1..MAX) OF AttributeType OPTIONAL,
+ allAttributeValues
+ [3] SET SIZE (1..MAX) OF AttributeType OPTIONAL,
+ allUserAttributeTypesAndValues [4] NULL OPTIONAL,
+ attributeValue
+ [5] SET SIZE (1..MAX) OF AttributeTypeAndValue OPTIONAL,
+ selfValue
+ [6] SET SIZE (1..MAX) OF AttributeType OPTIONAL,
+ rangeOfValues [7] Filter OPTIONAL,
+ maxValueCount
+ [8] SET SIZE (1..MAX) OF MaxValueCount OPTIONAL,
+ maxImmSub [9] INTEGER OPTIONAL,
+ restrictedBy
+ [10] SET SIZE (1..MAX) OF RestrictedValue OPTIONAL,
+ contexts
+ [11] SET SIZE (1..MAX) OF ContextAssertion OPTIONAL,
+ classes [12] Refinement OPTIONAL
+}
+
+MaxValueCount ::= SEQUENCE {type AttributeType,
+ maxCount INTEGER
+}
+
+RestrictedValue ::= SEQUENCE {type AttributeType,
+ valuesIn AttributeType
+}
+
+UserClasses ::= SEQUENCE {
+ allUsers [0] NULL OPTIONAL,
+ thisEntry [1] NULL OPTIONAL,
+ name [2] SET SIZE (1..MAX) OF NameAndOptionalUID OPTIONAL,
+ userGroup [3] SET SIZE (1..MAX) OF NameAndOptionalUID OPTIONAL,
+ -- dn component must be the name of an
+ -- entry of GroupOfUniqueNames
+ subtree [4] SET SIZE (1..MAX) OF SubtreeSpecification OPTIONAL
+}
+
+ItemPermission ::= SEQUENCE {
+ precedence Precedence OPTIONAL,
+ -- defaults to precedence in ACIItem
+ userClasses UserClasses,
+ grantsAndDenials GrantsAndDenials
+}
+
+UserPermission ::= SEQUENCE {
+ precedence Precedence OPTIONAL,
+ -- defaults to precedence in ACIItem
+ protectedItems ProtectedItems,
+ grantsAndDenials GrantsAndDenials
+}
+
+AuthenticationLevel ::= CHOICE {
+ basicLevels
+ SEQUENCE {level ENUMERATED {none(0), simple(1), strong(2)},
+ localQualifier INTEGER OPTIONAL,
+ signed BOOLEAN DEFAULT FALSE},
+ other EXTERNAL
+}
+
+GrantsAndDenials ::= BIT STRING {
+ -- permissions that may be used in conjunction
+ -- with any component of ProtectedItems
+ grantAdd(0), denyAdd(1), grantDiscloseOnError(2), denyDiscloseOnError(3),
+ grantRead(4), denyRead(5), grantRemove(6),
+ denyRemove(7),
+ -- permissions that may be used only in conjunction
+ -- with the entry component
+ grantBrowse(8), denyBrowse(9), grantExport(10), denyExport(11),
+ grantImport(12), denyImport(13), grantModify(14), denyModify(15),
+ grantRename(16), denyRename(17), grantReturnDN(18),
+ denyReturnDN(19),
+ -- permissions that may be used in conjunction
+ -- with any component, except entry, of ProtectedItems
+ grantCompare(20), denyCompare(21), grantFilterMatch(22), denyFilterMatch(23),
+ grantInvoke(24), denyInvoke(25)}
+
+AttributeTypeAndValue ::= SEQUENCE {
+ type ATTRIBUTE.&id({SupportedAttributes}),
+ value ATTRIBUTE.&Type({SupportedAttributes}{@type})
+}
+
+-- attributes
+accessControlScheme ATTRIBUTE ::= {
+ WITH SYNTAX OBJECT IDENTIFIER
+ EQUALITY MATCHING RULE objectIdentifierMatch
+ SINGLE VALUE TRUE
+ USAGE directoryOperation
+ ID id-aca-accessControlScheme
+}
+
+prescriptiveACI ATTRIBUTE ::= {
+ WITH SYNTAX ACIItem
+ EQUALITY MATCHING RULE directoryStringFirstComponentMatch
+ USAGE directoryOperation
+ ID id-aca-prescriptiveACI
+}
+
+entryACI ATTRIBUTE ::= {
+ WITH SYNTAX ACIItem
+ EQUALITY MATCHING RULE directoryStringFirstComponentMatch
+ USAGE directoryOperation
+ ID id-aca-entryACI
+}
+
+subentryACI ATTRIBUTE ::= {
+ WITH SYNTAX ACIItem
+ EQUALITY MATCHING RULE directoryStringFirstComponentMatch
+ USAGE directoryOperation
+ ID id-aca-subentryACI
+}
+
+-- object identifier assignments
+-- attributes
+id-aca-accessControlScheme OBJECT IDENTIFIER ::=
+ {id-aca 1}
+
+id-aca-prescriptiveACI OBJECT IDENTIFIER ::= {id-aca 4}
+
+id-aca-entryACI OBJECT IDENTIFIER ::= {id-aca 5}
+
+id-aca-subentryACI OBJECT IDENTIFIER ::= {id-aca 6}
+
+-- access control schemes -
+basicAccessControlScheme OBJECT IDENTIFIER ::=
+ {id-acScheme 1}
+
+simplifiedAccessControlScheme OBJECT IDENTIFIER ::= {id-acScheme 2}
+
+rule-based-access-control OBJECT IDENTIFIER ::= {id-acScheme 3}
+
+rule-and-basic-access-control OBJECT IDENTIFIER ::= {id-acScheme 4}
+
+rule-and-simple-access-control OBJECT IDENTIFIER ::= {id-acScheme 5}
+
+END -- BasicAccessControl
+
+-- Generated by Asnp, the ASN.1 pretty-printer of France Telecom R&D
+
diff --git a/lib/asn1/test/asn1_SUITE_data/modified_x420/CertificateExtensions.asn b/lib/asn1/test/asn1_SUITE_data/modified_x420/CertificateExtensions.asn
new file mode 100644
index 0000000000..0daf2208e9
--- /dev/null
+++ b/lib/asn1/test/asn1_SUITE_data/modified_x420/CertificateExtensions.asn
@@ -0,0 +1,498 @@
+-- Module CertificateExtensions (X.509:08/1997)
+
+CertificateExtensions {joint-iso-itu-t ds(5) module(1)
+ certificateExtensions(26) 0} DEFINITIONS IMPLICIT TAGS ::=
+BEGIN
+
+-- EXPORTS ALL
+IMPORTS
+ id-at, id-ce, id-mr, informationFramework, authenticationFramework,
+ selectedAttributeTypes, upperBounds
+ FROM UsefulDefinitions {joint-iso-itu-t ds(5) module(1)
+ usefulDefinitions(0) 3}
+ Name, RelativeDistinguishedName, ATTRIBUTE, Attribute, MATCHING-RULE
+ FROM InformationFramework informationFramework
+ CertificateSerialNumber, CertificateList, AlgorithmIdentifier, EXTENSION,
+ Time
+ FROM AuthenticationFramework authenticationFramework
+ DirectoryString{}
+ FROM SelectedAttributeTypes selectedAttributeTypes
+ ub-name
+ FROM UpperBounds upperBounds
+ ORAddress
+ FROM MTSAbstractService {joint-iso-itu-t mhs(6) mts(3) modules(0)
+ mts-abstract-service(1) version-1999(1)};
+
+-- Unless explicitly noted otherwise, there is no significance to the ordering
+-- of components of a SEQUENCE OF construct in this Specification.
+-- Key and policy information extensions
+authorityKeyIdentifier EXTENSION ::= {
+ SYNTAX AuthorityKeyIdentifier
+ IDENTIFIED BY id-ce-authorityKeyIdentifier
+}
+
+AuthorityKeyIdentifier ::= SEQUENCE {
+ keyIdentifier [0] KeyIdentifier OPTIONAL,
+ authorityCertIssuer [1] GeneralNames OPTIONAL,
+ authorityCertSerialNumber [2] CertificateSerialNumber OPTIONAL
+}
+(WITH COMPONENTS {
+ ...,
+ authorityCertIssuer PRESENT,
+ authorityCertSerialNumber PRESENT
+ } |
+ WITH COMPONENTS {
+ ...,
+ authorityCertIssuer ABSENT,
+ authorityCertSerialNumber ABSENT
+ })
+
+KeyIdentifier ::= OCTET STRING
+
+subjectKeyIdentifier EXTENSION ::= {
+ SYNTAX SubjectKeyIdentifier
+ IDENTIFIED BY id-ce-subjectKeyIdentifier
+}
+
+SubjectKeyIdentifier ::= KeyIdentifier
+
+keyUsage EXTENSION ::= {SYNTAX KeyUsage
+ IDENTIFIED BY id-ce-keyUsage
+}
+
+KeyUsage ::= BIT STRING {
+ digitalSignature(0), nonRepudiation(1), keyEncipherment(2),
+ dataEncipherment(3), keyAgreement(4), keyCertSign(5), cRLSign(6),
+ encipherOnly(7), decipherOnly(8)}
+
+extKeyUsage EXTENSION ::= {
+ SYNTAX SEQUENCE SIZE (1..MAX) OF KeyPurposeId
+ IDENTIFIED BY id-ce-extKeyUsage
+}
+
+KeyPurposeId ::= OBJECT IDENTIFIER
+
+privateKeyUsagePeriod EXTENSION ::= {
+ SYNTAX PrivateKeyUsagePeriod
+ IDENTIFIED BY id-ce-privateKeyUsagePeriod
+}
+
+PrivateKeyUsagePeriod ::= SEQUENCE {
+ notBefore [0] GeneralizedTime OPTIONAL,
+ notAfter [1] GeneralizedTime OPTIONAL
+}
+(WITH COMPONENTS {
+ ...,
+ notBefore PRESENT
+ } | WITH COMPONENTS {
+ ...,
+ notAfter PRESENT
+ })
+
+certificatePolicies EXTENSION ::= {
+ SYNTAX CertificatePoliciesSyntax
+ IDENTIFIED BY id-ce-certificatePolicies
+}
+
+CertificatePoliciesSyntax ::= SEQUENCE SIZE (1..MAX) OF PolicyInformation
+
+PolicyInformation ::= SEQUENCE {
+ policyIdentifier CertPolicyId,
+ policyQualifiers SEQUENCE SIZE (1..MAX) OF PolicyQualifierInfo OPTIONAL
+}
+
+CertPolicyId ::= OBJECT IDENTIFIER
+
+PolicyQualifierInfo ::= SEQUENCE {
+ policyQualifierId CERT-POLICY-QUALIFIER.&id({SupportedPolicyQualifiers}),
+ qualifier
+ CERT-POLICY-QUALIFIER.&Qualifier
+ ({SupportedPolicyQualifiers}{@policyQualifierId}) OPTIONAL
+}
+
+SupportedPolicyQualifiers CERT-POLICY-QUALIFIER ::=
+ {...}
+
+CERT-POLICY-QUALIFIER ::= CLASS {
+ &id OBJECT IDENTIFIER UNIQUE,
+ &Qualifier OPTIONAL
+}WITH SYNTAX {POLICY-QUALIFIER-ID &id
+ [QUALIFIER-TYPE &Qualifier]
+}
+
+policyMappings EXTENSION ::= {
+ SYNTAX PolicyMappingsSyntax
+ IDENTIFIED BY id-ce-policyMappings
+}
+
+PolicyMappingsSyntax ::=
+ SEQUENCE SIZE (1..MAX) OF
+ SEQUENCE {issuerDomainPolicy CertPolicyId,
+ subjectDomainPolicy CertPolicyId}
+
+supportedAlgorithms ATTRIBUTE ::= {
+ WITH SYNTAX SupportedAlgorithm
+ EQUALITY MATCHING RULE algorithmIdentifierMatch
+ ID id-at-supportedAlgorithms
+}
+
+SupportedAlgorithm ::= SEQUENCE {
+ algorithmIdentifier AlgorithmIdentifier,
+ intendedUsage [0] KeyUsage OPTIONAL,
+ intendedCertificatePolicies [1] CertificatePoliciesSyntax OPTIONAL
+}
+
+-- Certificate subject and certificate issuer attributes extensions
+subjectAltName EXTENSION ::= {
+ SYNTAX GeneralNames
+ IDENTIFIED BY id-ce-subjectAltName
+}
+
+GeneralNames ::= SEQUENCE SIZE (1..MAX) OF GeneralName
+
+GeneralName ::= CHOICE {
+ otherName [0] INSTANCE OF OTHER-NAME,
+ rfc822Name [1] IA5String,
+ dNSName [2] IA5String,
+ x400Address [3] ORAddress,
+ directoryName [4] Name,
+ ediPartyName [5] EDIPartyName,
+ uniformResourceIdentifier [6] IA5String,
+ iPAddress [7] OCTET STRING,
+ registeredID [8] OBJECT IDENTIFIER
+}
+
+OTHER-NAME ::= TYPE-IDENTIFIER
+
+EDIPartyName ::= SEQUENCE {
+ nameAssigner [0] DirectoryString{ub-name} OPTIONAL,
+ partyName [1] DirectoryString{ub-name}
+}
+
+issuerAltName EXTENSION ::= {
+ SYNTAX GeneralNames
+ IDENTIFIED BY id-ce-issuerAltName
+}
+
+subjectDirectoryAttributes EXTENSION ::= {
+ SYNTAX AttributesSyntax
+ IDENTIFIED BY id-ce-subjectDirectoryAttributes
+}
+
+AttributesSyntax ::= SEQUENCE SIZE (1..MAX) OF Attribute
+
+-- Certification path constraints extensions
+basicConstraints EXTENSION ::= {
+ SYNTAX BasicConstraintsSyntax
+ IDENTIFIED BY id-ce-basicConstraints
+}
+
+BasicConstraintsSyntax ::= SEQUENCE {
+ cA BOOLEAN DEFAULT FALSE,
+ pathLenConstraint INTEGER(0..MAX) OPTIONAL
+}
+
+nameConstraints EXTENSION ::= {
+ SYNTAX NameConstraintsSyntax
+ IDENTIFIED BY id-ce-nameConstraint
+}
+
+NameConstraintsSyntax ::= SEQUENCE {
+ permittedSubtrees [0] GeneralSubtrees OPTIONAL,
+ excludedSubtrees [1] GeneralSubtrees OPTIONAL,
+ requiredNameForms [2] NameForms OPTIONAL
+}
+
+GeneralSubtrees ::= SEQUENCE SIZE (1..MAX) OF GeneralSubtree
+
+GeneralSubtree ::= SEQUENCE {
+ base GeneralName,
+ minimum [0] BaseDistance DEFAULT 0,
+ maximum [1] BaseDistance OPTIONAL
+}
+
+BaseDistance ::= INTEGER(0..MAX)
+
+NameForms ::= SEQUENCE {
+ basicNameForms [0] BasicNameForms OPTIONAL,
+ otherNameForms [1] SEQUENCE SIZE (1..MAX) OF OBJECT IDENTIFIER OPTIONAL
+}(ALL EXCEPT ({ --none; i.e.:at least one component shall be present--}))
+
+BasicNameForms ::= BIT STRING {
+ rfc822Name(0), dNSName(1), x400Address(2), directoryName(3), ediPartyName(4),
+ uniformResourceIdentifier(5), iPAddress(6), registeredID(7)}(SIZE (1..MAX))
+
+policyConstraints EXTENSION ::= {
+ SYNTAX PolicyConstraintsSyntax
+ IDENTIFIED BY id-ce-policyConstraints
+}
+
+PolicyConstraintsSyntax ::= SEQUENCE {
+ requireExplicitPolicy [0] SkipCerts OPTIONAL,
+ inhibitPolicyMapping [1] SkipCerts OPTIONAL
+}
+
+SkipCerts ::= INTEGER(0..MAX)
+
+CertPolicySet ::= SEQUENCE SIZE (1..MAX) OF CertPolicyId
+
+-- Basic CRL extensions
+cRLNumber EXTENSION ::= {
+ SYNTAX CRLNumber
+ IDENTIFIED BY id-ce-cRLNumber
+}
+
+CRLNumber ::= INTEGER(0..MAX)
+
+reasonCode EXTENSION ::= {
+ SYNTAX CRLReason
+ IDENTIFIED BY id-ce-reasonCode
+}
+
+CRLReason ::= ENUMERATED {
+ unspecified(0), keyCompromise(1), cACompromise(2), affiliationChanged(3),
+ superseded(4), cessationOfOperation(5), certificateHold(6), removeFromCRL(8)
+}
+
+instructionCode EXTENSION ::= {
+ SYNTAX HoldInstruction
+ IDENTIFIED BY id-ce-instructionCode
+}
+
+HoldInstruction ::= OBJECT IDENTIFIER
+
+invalidityDate EXTENSION ::= {
+ SYNTAX GeneralizedTime
+ IDENTIFIED BY id-ce-invalidityDate
+}
+
+-- CRL distribution points and delta-CRL extensions
+cRLDistributionPoints EXTENSION ::= {
+ SYNTAX CRLDistPointsSyntax
+ IDENTIFIED BY id-ce-cRLDistributionPoints
+}
+
+CRLDistPointsSyntax ::= SEQUENCE SIZE (1..MAX) OF DistributionPoint
+
+DistributionPoint ::= SEQUENCE {
+ distributionPoint [0] DistributionPointName OPTIONAL,
+ reasons [1] ReasonFlags OPTIONAL,
+ cRLIssuer [2] GeneralNames OPTIONAL
+}
+
+DistributionPointName ::= CHOICE {
+ fullName [0] GeneralNames,
+ nameRelativeToCRLIssuer [1] RelativeDistinguishedName
+}
+
+ReasonFlags ::= BIT STRING {
+ unused(0), keyCompromise(1), caCompromise(2), affiliationChanged(3),
+ superseded(4), cessationOfOperation(5), certificateHold(6)}
+
+issuingDistributionPoint EXTENSION ::= {
+ SYNTAX IssuingDistPointSyntax
+ IDENTIFIED BY id-ce-issuingDistributionPoint
+}
+
+IssuingDistPointSyntax ::= SEQUENCE {
+ distributionPoint [0] DistributionPointName OPTIONAL,
+ onlyContainsUserCerts [1] BOOLEAN DEFAULT FALSE,
+ onlyContainsCACerts [2] BOOLEAN DEFAULT FALSE,
+ onlySomeReasons [3] ReasonFlags OPTIONAL,
+ indirectCRL [4] BOOLEAN DEFAULT FALSE
+}
+
+certificateIssuer EXTENSION ::= {
+ SYNTAX GeneralNames
+ IDENTIFIED BY id-ce-certificateIssuer
+}
+
+deltaCRLIndicator EXTENSION ::= {
+ SYNTAX BaseCRLNumber
+ IDENTIFIED BY id-ce-deltaCRLIndicator
+}
+
+BaseCRLNumber ::= CRLNumber
+
+deltaRevocationList ATTRIBUTE ::= {
+ WITH SYNTAX CertificateList
+ EQUALITY MATCHING RULE certificateListExactMatch
+ ID id-at-deltaRevocationList
+}
+
+-- Matching rules
+certificateExactMatch MATCHING-RULE ::= {
+ SYNTAX CertificateExactAssertion
+ ID id-mr-certificateExactMatch
+}
+
+CertificateExactAssertion ::= SEQUENCE {
+ serialNumber CertificateSerialNumber,
+ issuer Name
+}
+
+certificateMatch MATCHING-RULE ::= {
+ SYNTAX CertificateAssertion
+ ID id-mr-certificateMatch
+}
+
+CertificateAssertion ::= SEQUENCE {
+ serialNumber [0] CertificateSerialNumber OPTIONAL,
+ issuer [1] Name OPTIONAL,
+ subjectKeyIdentifier [2] SubjectKeyIdentifier OPTIONAL,
+ authorityKeyIdentifier [3] AuthorityKeyIdentifier OPTIONAL,
+ certificateValid [4] Time OPTIONAL,
+ privateKeyValid [5] GeneralizedTime OPTIONAL,
+ subjectPublicKeyAlgID [6] OBJECT IDENTIFIER OPTIONAL,
+ keyUsage [7] KeyUsage OPTIONAL,
+ subjectAltName [8] AltNameType OPTIONAL,
+ policy [9] CertPolicySet OPTIONAL,
+ pathToName [10] Name OPTIONAL
+}
+
+AltNameType ::= CHOICE {
+ builtinNameForm
+ ENUMERATED {rfc822Name(1), dNSName(2), x400Address(3), directoryName(4),
+ ediPartyName(5), uniformResourceIdentifier(6), iPAddress(7),
+ registeredId(8)},
+ otherNameForm OBJECT IDENTIFIER
+}
+
+certificatePairExactMatch MATCHING-RULE ::= {
+ SYNTAX CertificatePairExactAssertion
+ ID id-mr-certificatePairExactMatch
+}
+
+CertificatePairExactAssertion ::= SEQUENCE {
+ forwardAssertion [0] CertificateExactAssertion OPTIONAL,
+ reverseAssertion [1] CertificateExactAssertion OPTIONAL
+}
+(WITH COMPONENTS {
+ ...,
+ forwardAssertion PRESENT
+ } | WITH COMPONENTS {
+ ...,
+ reverseAssertion PRESENT
+ })
+
+certificatePairMatch MATCHING-RULE ::= {
+ SYNTAX CertificatePairAssertion
+ ID id-mr-certificatePairMatch
+}
+
+CertificatePairAssertion ::= SEQUENCE {
+ forwardAssertion [0] CertificateAssertion OPTIONAL,
+ reverseAssertion [1] CertificateAssertion OPTIONAL
+}
+(WITH COMPONENTS {
+ ...,
+ forwardAssertion PRESENT
+ } | WITH COMPONENTS {
+ ...,
+ reverseAssertion PRESENT
+ })
+
+certificateListExactMatch MATCHING-RULE ::= {
+ SYNTAX CertificateListExactAssertion
+ ID id-mr-certificateListExactMatch
+}
+
+CertificateListExactAssertion ::= SEQUENCE {
+ issuer Name,
+ thisUpdate Time,
+ distributionPoint DistributionPointName OPTIONAL
+}
+
+certificateListMatch MATCHING-RULE ::= {
+ SYNTAX CertificateListAssertion
+ ID id-mr-certificateListMatch
+}
+
+CertificateListAssertion ::= SEQUENCE {
+ issuer Name OPTIONAL,
+ minCRLNumber [0] CRLNumber OPTIONAL,
+ maxCRLNumber [1] CRLNumber OPTIONAL,
+ reasonFlags ReasonFlags OPTIONAL,
+ dateAndTime Time OPTIONAL,
+ distributionPoint [2] DistributionPointName OPTIONAL
+}
+
+algorithmIdentifierMatch MATCHING-RULE ::= {
+ SYNTAX AlgorithmIdentifier
+ ID id-mr-algorithmIdentifierMatch
+}
+
+-- Object identifier assignments
+id-at-supportedAlgorithms OBJECT IDENTIFIER ::=
+ {id-at 52}
+
+id-at-deltaRevocationList OBJECT IDENTIFIER ::= {id-at 53}
+
+id-ce-subjectDirectoryAttributes OBJECT IDENTIFIER ::= {id-ce 9}
+
+id-ce-subjectKeyIdentifier OBJECT IDENTIFIER ::= {id-ce 14}
+
+id-ce-keyUsage OBJECT IDENTIFIER ::= {id-ce 15}
+
+id-ce-privateKeyUsagePeriod OBJECT IDENTIFIER ::= {id-ce 16}
+
+id-ce-subjectAltName OBJECT IDENTIFIER ::= {id-ce 17}
+
+id-ce-issuerAltName OBJECT IDENTIFIER ::= {id-ce 18}
+
+id-ce-basicConstraints OBJECT IDENTIFIER ::= {id-ce 19}
+
+id-ce-cRLNumber OBJECT IDENTIFIER ::= {id-ce 20}
+
+id-ce-reasonCode OBJECT IDENTIFIER ::= {id-ce 21}
+
+id-ce-instructionCode OBJECT IDENTIFIER ::= {id-ce 23}
+
+id-ce-invalidityDate OBJECT IDENTIFIER ::= {id-ce 24}
+
+id-ce-deltaCRLIndicator OBJECT IDENTIFIER ::= {id-ce 27}
+
+id-ce-issuingDistributionPoint OBJECT IDENTIFIER ::= {id-ce 28}
+
+id-ce-certificateIssuer OBJECT IDENTIFIER ::= {id-ce 29}
+
+id-ce-nameConstraint OBJECT IDENTIFIER ::= {id-ce 30 1}
+
+id-ce-cRLDistributionPoints OBJECT IDENTIFIER ::= {id-ce 31}
+
+id-ce-certificatePolicies OBJECT IDENTIFIER ::= {id-ce 32}
+
+id-ce-policyMappings OBJECT IDENTIFIER ::= {id-ce 33}
+
+-- deprecated OBJECT IDENTIFIER ::= {id-ce 34}
+id-ce-authorityKeyIdentifier OBJECT IDENTIFIER ::=
+ {id-ce 35}
+
+id-ce-policyConstraints OBJECT IDENTIFIER ::= {id-ce 36}
+
+id-ce-extKeyUsage OBJECT IDENTIFIER ::= {id-ce 37}
+
+id-mr-certificateExactMatch OBJECT IDENTIFIER ::= {id-mr 34}
+
+id-mr-certificateMatch OBJECT IDENTIFIER ::= {id-mr 35}
+
+id-mr-certificatePairExactMatch OBJECT IDENTIFIER ::= {id-mr 36}
+
+id-mr-certificatePairMatch OBJECT IDENTIFIER ::= {id-mr 37}
+
+id-mr-certificateListExactMatch OBJECT IDENTIFIER ::= {id-mr 38}
+
+id-mr-certificateListMatch OBJECT IDENTIFIER ::= {id-mr 39}
+
+id-mr-algorithmIdentifierMatch OBJECT IDENTIFIER ::= {id-mr 40}
+
+id-ce-inhibitAnyPolicy OBJECT IDENTIFIER ::= {id-ce 54}
+
+-- The following OBJECT IDENTIFIERS are not used by this Specification:
+-- {id-ce 2}, {id-ce 3}, {id-ce 4}, {id-ce 5}, {id-ce 6}, {id-ce 7},
+-- {id-ce 8}, {id-ce 10}, {id-ce 11}, {id-ce 12}, {id-ce 13},
+-- {id-ce 22}, {id-ce 25}, {id-ce 26}, {id-ce 30}
+END
+
+-- Generated by Asnp, the ASN.1 pretty-printer of France Telecom R&D
+
diff --git a/lib/asn1/test/asn1_SUITE_data/modified_x420/InformationFramework.asn b/lib/asn1/test/asn1_SUITE_data/modified_x420/InformationFramework.asn
new file mode 100644
index 0000000000..5c26febd5b
--- /dev/null
+++ b/lib/asn1/test/asn1_SUITE_data/modified_x420/InformationFramework.asn
@@ -0,0 +1,868 @@
+-- Module InformationFramework (X.501:08/1997)
+InformationFramework {joint-iso-itu-t ds(5) module(1) informationFramework(1)
+ 3} DEFINITIONS ::=
+BEGIN
+
+-- EXPORTS All -
+-- The types and values defined in this module are exported for use in the other ASN.1 modules contained
+-- within the Directory Specifications, and for the use of other applications which will use them to access
+-- Directory services. Other applications may use them for their own purposes, but this will not constrain
+-- extensions and modifications needed to maintain or improve the Directory service.
+IMPORTS
+ id-oc, id-at, id-mr, id-oa, id-sc, id-ar, id-nf, selectedAttributeTypes,
+ directoryAbstractService, upperBounds
+ FROM UsefulDefinitions {joint-iso-itu-t ds(5) module(1)
+ usefulDefinitions(0) 3}
+ commonName, generalizedTimeMatch, generalizedTimeOrderingMatch, booleanMatch,
+ integerMatch, integerOrderingMatch, objectIdentifierFirstComponentMatch,
+ integerFirstComponentMatch, DirectoryString{}
+ FROM SelectedAttributeTypes selectedAttributeTypes
+-- TypeAndContextAssertion, ServiceControlOptions, SearchControlOptions,
+-- HierarchySelections, FamilyGrouping, FamilyReturn
+-- FROM DirectoryAbstractService directoryAbstractService
+ ub-search
+ FROM UpperBounds upperBounds;
+
+-- attribute data types
+Attribute ::= SEQUENCE {
+ type ATTRIBUTE.&id({SupportedAttributes}),
+ values
+ SET SIZE (0..MAX) OF ATTRIBUTE.&Type({SupportedAttributes}{@type}),
+ valuesWithContext
+ SET SIZE (1..MAX) OF
+ SEQUENCE {value ATTRIBUTE.&Type({SupportedAttributes}{@type}),
+ contextList SET SIZE (1..MAX) OF Context} OPTIONAL
+}
+
+AttributeType ::= ATTRIBUTE.&id
+
+AttributeValue ::= ATTRIBUTE.&Type
+
+Context ::= SEQUENCE {
+ contextType CONTEXT.&id({SupportedContexts}),
+ contextValues
+ SET SIZE (1..MAX) OF CONTEXT.&Type({SupportedContexts}{@contextType}),
+ fallback BOOLEAN DEFAULT FALSE
+}
+
+AttributeValueAssertion ::= SEQUENCE {
+ type ATTRIBUTE.&id({SupportedAttributes}),
+ assertion
+ ATTRIBUTE.&equality-match.&AssertionType({SupportedAttributes}{@type}),
+ assertedContexts
+ CHOICE {allContexts [0] NULL,
+ selectedContexts [1] SET SIZE (1..MAX) OF ContextAssertion
+ } OPTIONAL
+}
+
+ContextAssertion ::= SEQUENCE {
+ contextType CONTEXT.&id({SupportedContexts}),
+ contextValues
+ SET SIZE (1..MAX) OF CONTEXT.&Assertion({SupportedContexts}{@contextType})
+}
+
+AttributeTypeAssertion ::= SEQUENCE {
+ type ATTRIBUTE.&id({SupportedAttributes}),
+ assertedContexts SEQUENCE SIZE (1..MAX) OF ContextAssertion OPTIONAL
+}
+
+-- Definition of the following information object set is deferred, perhaps to standardized
+-- profiles or to protocol implementation conformance statements. The set is required to
+-- specify a table constraint on the values component of Attribute, the value component
+-- of AttributeTypeAndValue, and the assertion component of AttributeValueAssertion.
+SupportedAttributes ATTRIBUTE ::=
+ {objectClass | aliasedEntryName, ...}
+
+-- Definition of the following information object set is deferred, perhaps to standardized
+-- profiles or to protocol implementation conformance statements. The set is required to
+-- specify a table constraint on the context specifications
+SupportedContexts CONTEXT ::=
+ {...}
+
+-- naming data types
+Name ::= CHOICE { -- only one possibility for now --rdnSequence RDNSequence
+}
+
+RDNSequence ::= SEQUENCE OF RelativeDistinguishedName
+
+DistinguishedName ::= RDNSequence
+
+RelativeDistinguishedName ::=
+ SET SIZE (1..MAX) OF AttributeTypeAndDistinguishedValue
+
+AttributeTypeAndDistinguishedValue ::= SEQUENCE {
+ type ATTRIBUTE.&id({SupportedAttributes}),
+ value ATTRIBUTE.&Type({SupportedAttributes}{@type}),
+ primaryDistinguished BOOLEAN DEFAULT TRUE,
+ valuesWithContext
+ SET SIZE (1..MAX) OF
+ SEQUENCE {distingAttrValue
+ [0] ATTRIBUTE.&Type({SupportedAttributes}{@type}) OPTIONAL,
+ contextList SET SIZE (1..MAX) OF Context} OPTIONAL
+}
+
+-- subtree data types
+SubtreeSpecification ::= SEQUENCE {
+ base [0] LocalName DEFAULT {},
+ COMPONENTS OF ChopSpecification,
+ specificationFilter [4] Refinement OPTIONAL
+}
+
+-- empty sequence specifies whole administrative area
+LocalName ::= RDNSequence
+
+ChopSpecification ::= SEQUENCE {
+ specificExclusions
+ [1] SET SIZE (1..MAX) OF
+ CHOICE {chopBefore [0] LocalName,
+ chopAfter [1] LocalName} OPTIONAL,
+ minimum [2] BaseDistance DEFAULT 0,
+ maximum [3] BaseDistance OPTIONAL
+}
+
+BaseDistance ::= INTEGER(0..MAX)
+
+Refinement ::= CHOICE {
+ item [0] OBJECT-CLASS.&id,
+ and [1] SET OF Refinement,
+ or [2] SET OF Refinement,
+ not [3] Refinement
+}
+
+-- OBJECT-CLASS information object class specification
+OBJECT-CLASS ::= CLASS {
+ &Superclasses OBJECT-CLASS OPTIONAL,
+ &kind ObjectClassKind DEFAULT structural,
+ &MandatoryAttributes ATTRIBUTE OPTIONAL,
+ &OptionalAttributes ATTRIBUTE OPTIONAL,
+ &id OBJECT IDENTIFIER UNIQUE
+}
+WITH SYNTAX {
+ [SUBCLASS OF &Superclasses]
+ [KIND &kind]
+ [MUST CONTAIN &MandatoryAttributes]
+ [MAY CONTAIN &OptionalAttributes]
+ ID &id
+}
+
+ObjectClassKind ::= ENUMERATED {abstract(0), structural(1), auxiliary(2)}
+
+-- object classes
+top OBJECT-CLASS ::= {
+ KIND abstract
+ MUST CONTAIN {objectClass}
+ ID id-oc-top
+}
+
+alias OBJECT-CLASS ::= {
+ SUBCLASS OF {top}
+ MUST CONTAIN {aliasedEntryName}
+ ID id-oc-alias
+}
+
+parent OBJECT-CLASS ::= {KIND abstract
+ ID id-oc-parent
+}
+
+child OBJECT-CLASS ::= {KIND auxiliary
+ ID id-oc-child
+}
+
+-- ATTRIBUTE information object class specification
+ATTRIBUTE ::= CLASS {
+ &derivation ATTRIBUTE OPTIONAL,
+ &Type OPTIONAL, -- either &Type or &derivation required
+ &equality-match MATCHING-RULE OPTIONAL,
+ &ordering-match MATCHING-RULE OPTIONAL,
+ &substrings-match MATCHING-RULE OPTIONAL,
+ &single-valued BOOLEAN DEFAULT FALSE,
+ &collective BOOLEAN DEFAULT FALSE,
+ -- operational extensions
+ &no-user-modification BOOLEAN DEFAULT FALSE,
+ &usage AttributeUsage DEFAULT userApplications,
+ &id OBJECT IDENTIFIER UNIQUE
+}
+WITH SYNTAX {
+ [SUBTYPE OF &derivation]
+ [WITH SYNTAX &Type]
+ [EQUALITY MATCHING RULE &equality-match]
+ [ORDERING MATCHING RULE &ordering-match]
+ [SUBSTRINGS MATCHING RULE &substrings-match]
+ [SINGLE VALUE &single-valued]
+ [COLLECTIVE &collective]
+ [NO USER MODIFICATION &no-user-modification]
+ [USAGE &usage]
+ ID &id
+}
+
+AttributeUsage ::= ENUMERATED {
+ userApplications(0), directoryOperation(1), distributedOperation(2),
+ dSAOperation(3)}
+
+-- attributes
+objectClass ATTRIBUTE ::= {
+ WITH SYNTAX OBJECT IDENTIFIER
+ EQUALITY MATCHING RULE objectIdentifierMatch
+ ID id-at-objectClass
+}
+
+aliasedEntryName ATTRIBUTE ::= {
+ WITH SYNTAX DistinguishedName
+ EQUALITY MATCHING RULE distinguishedNameMatch
+ SINGLE VALUE TRUE
+ ID id-at-aliasedEntryName
+}
+
+-- MATCHING-RULE information object class specification
+MATCHING-RULE ::= CLASS {
+ &ParentMatchingRules MATCHING-RULE.&id OPTIONAL,
+ &AssertionType OPTIONAL,
+ &uniqueMatchIndicator ATTRIBUTE.&id OPTIONAL,
+ &id OBJECT IDENTIFIER UNIQUE
+}
+WITH SYNTAX {
+ [PARENT &ParentMatchingRules]
+ [SYNTAX &AssertionType]
+ [UNIQUE-MATCH-INDICATOR &uniqueMatchIndicator]
+ ID &id
+}
+
+-- matching rules
+objectIdentifierMatch MATCHING-RULE ::= {
+ SYNTAX OBJECT IDENTIFIER
+ ID id-mr-objectIdentifierMatch
+}
+
+distinguishedNameMatch MATCHING-RULE ::= {
+ SYNTAX DistinguishedName
+ ID id-mr-distinguishedNameMatch
+}
+
+MAPPING-BASED-MATCHING{SelectedBy, BOOLEAN:combinable, MappingResult,
+ OBJECT IDENTIFIER:matchingRule} ::= CLASS {
+ &selectBy SelectedBy OPTIONAL,
+ &ApplicableTo ATTRIBUTE,
+ &subtypesIncluded BOOLEAN DEFAULT TRUE,
+ &combinable BOOLEAN(combinable),
+ &mappingResults MappingResult OPTIONAL,
+ &userControl BOOLEAN DEFAULT FALSE,
+ &exclusive BOOLEAN DEFAULT TRUE,
+ &matching-rule MATCHING-RULE.&id(matchingRule),
+ &id OBJECT IDENTIFIER UNIQUE
+}
+WITH SYNTAX {
+ [SELECT BY &selectBy]
+ APPLICABLE TO &ApplicableTo
+ [SUBTYPES INCLUDED &subtypesIncluded]
+ COMBINABLE &combinable
+ [MAPPING RESULTS &mappingResults]
+ [USER CONTROL &userControl]
+ [EXCLUSIVE &exclusive]
+ MATCHING RULE &matching-rule
+ ID &id
+}
+
+-- NAME-FORM information object class specification
+NAME-FORM ::= CLASS {
+ &namedObjectClass OBJECT-CLASS,
+ &MandatoryAttributes ATTRIBUTE,
+ &OptionalAttributes ATTRIBUTE OPTIONAL,
+ &id OBJECT IDENTIFIER UNIQUE
+}
+WITH SYNTAX {
+ NAMES &namedObjectClass
+ WITH ATTRIBUTES &MandatoryAttributes
+ [AND OPTIONALLY &OptionalAttributes]
+ ID &id
+}
+
+-- STRUCTURE-RULE class and DIT structure rule data types
+STRUCTURE-RULE ::= CLASS {
+ &nameForm NAME-FORM,
+ &SuperiorStructureRules STRUCTURE-RULE OPTIONAL,
+ &id RuleIdentifier
+}
+WITH SYNTAX {
+ NAME FORM &nameForm
+ [SUPERIOR RULES &SuperiorStructureRules]
+ ID &id
+}
+
+DITStructureRule ::= SEQUENCE {
+ ruleIdentifier RuleIdentifier,
+ -- must be unique within the scope of the subschema
+ nameForm NAME-FORM.&id,
+ superiorStructureRules SET SIZE (1..MAX) OF RuleIdentifier OPTIONAL
+}
+
+RuleIdentifier ::= INTEGER
+
+-- CONTENT-RULE class and DIT content rule data types
+CONTENT-RULE ::= CLASS {
+ &structuralClass OBJECT-CLASS.&id UNIQUE,
+ &Auxiliaries OBJECT-CLASS OPTIONAL,
+ &Mandatory ATTRIBUTE OPTIONAL,
+ &Optional ATTRIBUTE OPTIONAL,
+ &Precluded ATTRIBUTE OPTIONAL
+}
+WITH SYNTAX {
+ STRUCTURAL OBJECT-CLASS &structuralClass
+ [AUXILIARY OBJECT-CLASSES &Auxiliaries]
+ [MUST CONTAIN &Mandatory]
+ [MAY CONTAIN &Optional]
+ [MUST-NOT CONTAIN &Precluded]
+}
+
+DITContentRule ::= SEQUENCE {
+ structuralObjectClass OBJECT-CLASS.&id,
+ auxiliaries SET SIZE (1..MAX) OF OBJECT-CLASS.&id OPTIONAL,
+ mandatory [1] SET SIZE (1..MAX) OF ATTRIBUTE.&id OPTIONAL,
+ optional [2] SET SIZE (1..MAX) OF ATTRIBUTE.&id OPTIONAL,
+ precluded [3] SET SIZE (1..MAX) OF ATTRIBUTE.&id OPTIONAL
+}
+
+CONTEXT ::= CLASS {
+ &Type ,
+ &Assertion OPTIONAL,
+ &id OBJECT IDENTIFIER UNIQUE
+}WITH SYNTAX {WITH SYNTAX &Type
+ [ASSERTED AS &Assertion]
+ ID &id
+}
+
+DITContextUse ::= SEQUENCE {
+ attributeType ATTRIBUTE.&id,
+ mandatoryContexts [1] SET SIZE (1..MAX) OF CONTEXT.&id OPTIONAL,
+ optionalContexts [2] SET SIZE (1..MAX) OF CONTEXT.&id OPTIONAL
+}
+
+DIT-CONTEXT-USE-RULE ::= CLASS {
+ &attributeType ATTRIBUTE.&id UNIQUE,
+ &Mandatory CONTEXT OPTIONAL,
+ &Optional CONTEXT OPTIONAL
+}
+WITH SYNTAX {
+ ATTRIBUTE TYPE &attributeType
+ [MANDATORY CONTEXTS &Mandatory]
+ [OPTIONAL CONTEXTS &Optional]
+}
+
+-- system schema information objects
+-- object classes
+subentry OBJECT-CLASS ::= {
+ SUBCLASS OF {top}
+ KIND structural
+ MUST CONTAIN {commonName | subtreeSpecification}
+ ID id-sc-subentry
+}
+
+subentryNameForm NAME-FORM ::= {
+ NAMES subentry
+ WITH ATTRIBUTES {commonName}
+ ID id-nf-subentryNameForm
+}
+
+accessControlSubentry OBJECT-CLASS ::= {
+ KIND auxiliary
+ ID id-sc-accessControlSubentry
+}
+
+collectiveAttributeSubentry OBJECT-CLASS ::= {
+ KIND auxiliary
+ ID id-sc-collectiveAttributeSubentry
+}
+
+--contextAssertionSubentry OBJECT-CLASS ::= {
+-- KIND auxiliary
+-- MUST CONTAIN {contextAssertionDefaults}
+-- ID id-sc-contextAssertionSubentry
+--}
+
+-- serviceAdminSubentry OBJECT-CLASS ::= {
+-- KIND auxiliary
+-- MUST CONTAIN {searchRules}
+-- ID id-sc-serviceAdminSubentry
+-- }
+
+-- attributes
+createTimestamp ATTRIBUTE ::= {
+ WITH SYNTAX GeneralizedTime
+ -- as per 41.3 b) or c) of ITU-T Rec. X.680 | ISO/IEC 8824-1
+ EQUALITY MATCHING RULE generalizedTimeMatch
+ ORDERING MATCHING RULE generalizedTimeOrderingMatch
+ SINGLE VALUE TRUE
+ NO USER MODIFICATION TRUE
+ USAGE directoryOperation
+ ID id-oa-createTimestamp
+}
+
+modifyTimestamp ATTRIBUTE ::= {
+ WITH SYNTAX GeneralizedTime
+ -- as per 41.3 b) or c) of ITU-T Rec. X.680 | ISO/IEC 8824-1
+ EQUALITY MATCHING RULE generalizedTimeMatch
+ ORDERING MATCHING RULE generalizedTimeOrderingMatch
+ SINGLE VALUE TRUE
+ NO USER MODIFICATION TRUE
+ USAGE directoryOperation
+ ID id-oa-modifyTimestamp
+}
+
+subschemaTimestamp ATTRIBUTE ::= {
+ WITH SYNTAX GeneralizedTime
+ -- as per 41.3 b) or c) of ITU-T Rec.X. 680 | ISO/IEC 8824-1
+ EQUALITY MATCHING RULE generalizedTimeMatch
+ ORDERING MATCHING RULE generalizedTimeOrderingMatch
+ SINGLE VALUE TRUE
+ NO USER MODIFICATION TRUE
+ USAGE directoryOperation
+ ID id-oa-subschemaTimestamp
+}
+
+creatorsName ATTRIBUTE ::= {
+ WITH SYNTAX DistinguishedName
+ EQUALITY MATCHING RULE distinguishedNameMatch
+ SINGLE VALUE TRUE
+ NO USER MODIFICATION TRUE
+ USAGE directoryOperation
+ ID id-oa-creatorsName
+}
+
+modifiersName ATTRIBUTE ::= {
+ WITH SYNTAX DistinguishedName
+ EQUALITY MATCHING RULE distinguishedNameMatch
+ SINGLE VALUE TRUE
+ NO USER MODIFICATION TRUE
+ USAGE directoryOperation
+ ID id-oa-modifiersName
+}
+
+subschemaSubentryList ATTRIBUTE ::= {
+ WITH SYNTAX DistinguishedName
+ EQUALITY MATCHING RULE distinguishedNameMatch
+ SINGLE VALUE TRUE
+ NO USER MODIFICATION TRUE
+ USAGE directoryOperation
+ ID id-oa-subschemaSubentryList
+}
+
+accessControlSubentryList ATTRIBUTE ::= {
+ WITH SYNTAX DistinguishedName
+ EQUALITY MATCHING RULE distinguishedNameMatch
+ NO USER MODIFICATION TRUE
+ USAGE directoryOperation
+ ID id-oa-accessControlSubentryList
+}
+
+collectiveAttributeSubentryList ATTRIBUTE ::= {
+ WITH SYNTAX DistinguishedName
+ EQUALITY MATCHING RULE distinguishedNameMatch
+ NO USER MODIFICATION TRUE
+ USAGE directoryOperation
+ ID id-oa-collectiveAttributeSubentryList
+}
+
+contextDefaultSubentryList ATTRIBUTE ::= {
+ WITH SYNTAX DistinguishedName
+ EQUALITY MATCHING RULE distinguishedNameMatch
+ NO USER MODIFICATION TRUE
+ USAGE directoryOperation
+ ID id-oa-contextDefaultSubentryList
+}
+
+serviceAdminSubentryList ATTRIBUTE ::= {
+ WITH SYNTAX DistinguishedName
+ EQUALITY MATCHING RULE distinguishedNameMatch
+ NO USER MODIFICATION TRUE
+ USAGE directoryOperation
+ ID id-oa-serviceAdminSubentryList
+}
+
+hasSubordinates ATTRIBUTE ::= {
+ WITH SYNTAX BOOLEAN
+ EQUALITY MATCHING RULE booleanMatch
+ SINGLE VALUE TRUE
+ NO USER MODIFICATION TRUE
+ USAGE directoryOperation
+ ID id-oa-hasSubordinates
+}
+
+administrativeRole ATTRIBUTE ::= {
+ WITH SYNTAX OBJECT-CLASS.&id
+ EQUALITY MATCHING RULE objectIdentifierMatch
+ USAGE directoryOperation
+ ID id-oa-administrativeRole
+}
+
+subtreeSpecification ATTRIBUTE ::= {
+ WITH SYNTAX SubtreeSpecification
+ USAGE directoryOperation
+ ID id-oa-subtreeSpecification
+}
+
+collectiveExclusions ATTRIBUTE ::= {
+ WITH SYNTAX OBJECT IDENTIFIER
+ EQUALITY MATCHING RULE objectIdentifierMatch
+ USAGE directoryOperation
+ ID id-oa-collectiveExclusions
+}
+
+-- contextAssertionDefaults ATTRIBUTE ::= {
+-- WITH SYNTAX TypeAndContextAssertion
+-- EQUALITY MATCHING RULE objectIdentifierFirstComponentMatch
+-- USAGE directoryOperation
+-- ID id-oa-contextAssertionDefault
+-- }
+
+-- searchRules ATTRIBUTE ::= {
+-- WITH SYNTAX SearchRuleDescription
+-- EQUALITY MATCHING RULE integerFirstComponentMatch
+-- USAGE directoryOperation
+-- ID id-oa-searchRules
+-- }
+
+-- SearchRuleDescription ::= SEQUENCE {
+-- COMPONENTS OF SearchRule,
+-- name [28] SET SIZE (1..MAX) OF DirectoryString{ub-search} OPTIONAL,
+-- description [29] DirectoryString{ub-search} OPTIONAL,
+-- obsolete [30] BOOLEAN DEFAULT FALSE
+-- }
+
+hierarchyLevel ATTRIBUTE ::= {
+ WITH SYNTAX INTEGER
+ EQUALITY MATCHING RULE integerMatch
+ ORDERING MATCHING RULE integerOrderingMatch
+ SINGLE VALUE TRUE
+ NO USER MODIFICATION TRUE
+ USAGE directoryOperation
+ ID id-oa-hierarchyLevel
+}
+
+hierarchyBelow ATTRIBUTE ::= {
+ WITH SYNTAX BOOLEAN
+ EQUALITY MATCHING RULE booleanMatch
+ SINGLE VALUE TRUE
+ NO USER MODIFICATION TRUE
+ USAGE directoryOperation
+ ID id-oa-hierarchyBelow
+}
+
+hierarchyParent ATTRIBUTE ::= {
+ WITH SYNTAX DistinguishedName
+ EQUALITY MATCHING RULE distinguishedNameMatch
+ SINGLE VALUE TRUE
+ USAGE directoryOperation
+ ID id-oa-hierarchyParent
+}
+
+-- SearchRule ::= SEQUENCE {
+-- COMPONENTS OF SearchRuleId,
+-- serviceType [1] OBJECT IDENTIFIER OPTIONAL,
+-- userClass [2] INTEGER OPTIONAL,
+-- inputAttributeTypes
+-- [3] SEQUENCE SIZE (1..MAX) OF RequestAttribute OPTIONAL,
+-- attributeCombination [4] AttributeCombination DEFAULT and:{},
+-- outputAttributeTypes [5] SEQUENCE SIZE (1..MAX) OF ResultAttribute OPTIONAL,
+-- defaultControls [6] ControlOptions OPTIONAL,
+-- mandatoryControls [7] ControlOptions OPTIONAL,
+-- searchRuleControls [8] ControlOptions OPTIONAL,
+-- familyGrouping [9] FamilyGrouping OPTIONAL,
+-- familyReturn [10] FamilyReturn OPTIONAL,
+-- relaxation [11] RelaxationPolicy OPTIONAL,
+-- additionalControl [12] SEQUENCE SIZE (1..MAX) OF AttributeType OPTIONAL,
+-- allowedSubset [13] AllowedSubset DEFAULT '111'B,
+-- imposedSubset [14] ImposedSubset OPTIONAL,
+-- entryLimit [15] EntryLimit OPTIONAL
+-- }
+
+SearchRuleId ::= SEQUENCE {id INTEGER,
+ dmdId [0] OBJECT IDENTIFIER
+}
+
+AllowedSubset ::= BIT STRING {baseObject(0), oneLevel(1), wholeSubtree(2)}
+
+ImposedSubset ::= ENUMERATED {baseObject(0), oneLevel(1), wholeSubtree(2)}
+
+RequestAttribute ::= SEQUENCE {
+ attributeType ATTRIBUTE.&id({SupportedAttributes}),
+ includeSubtypes [0] BOOLEAN DEFAULT FALSE,
+ selectedValues
+ [1] SEQUENCE SIZE (0..MAX) OF
+ ATTRIBUTE.&Type({SupportedAttributes}{@attributeType}) OPTIONAL,
+ defaultValues
+ [2] SEQUENCE SIZE (0..MAX) OF
+ SEQUENCE {entryType OBJECT-CLASS.&id OPTIONAL,
+ values
+ SEQUENCE OF
+ ATTRIBUTE.&Type({SupportedAttributes}{@attributeType})
+ } OPTIONAL,
+ contexts [3] SEQUENCE SIZE (0..MAX) OF ContextProfile OPTIONAL,
+ contextCombination [4] ContextCombination DEFAULT and:{},
+ matchingUse [5] SEQUENCE SIZE (1..MAX) OF MatchingUse OPTIONAL
+}
+
+ContextProfile ::= SEQUENCE {
+ contextType CONTEXT.&id({SupportedContexts}),
+ contextValue
+ SEQUENCE SIZE (1..MAX) OF
+ CONTEXT.&Assertion({SupportedContexts}{@contextType}) OPTIONAL
+}
+
+ContextCombination ::= CHOICE {
+ context [0] CONTEXT.&id,
+ and [1] SEQUENCE OF ContextCombination,
+ or [2] SEQUENCE OF ContextCombination,
+ not [3] ContextCombination
+}
+
+MatchingUse ::= SEQUENCE {
+ restrictionType MATCHING-RESTRICTION.&id({SupportedMatchingRestrictions}),
+ restrictionValue
+ MATCHING-RESTRICTION.&Restriction
+ ({SupportedMatchingRestrictions}{@restrictionType})
+}
+
+-- Definition of the following information object set is deferred, perhaps to standardized
+-- profiles or to protocol implementation conformance statements. The set is required to
+-- specify a table constraint on the components of SupportedMatchingRestrictions
+SupportedMatchingRestrictions MATCHING-RESTRICTION ::=
+ {...}
+
+AttributeCombination ::= CHOICE {
+ attribute [0] AttributeType,
+ and [1] SEQUENCE OF AttributeCombination,
+ or [2] SEQUENCE OF AttributeCombination,
+ not [3] AttributeCombination
+}
+
+ResultAttribute ::= SEQUENCE {
+ attributeType ATTRIBUTE.&id({SupportedAttributes}),
+ outputValues
+ CHOICE {selectedValues
+ SEQUENCE SIZE (1..MAX) OF
+ ATTRIBUTE.&Type({SupportedAttributes}{@attributeType}),
+ matchedValuesOnly NULL} OPTIONAL,
+ contexts [0] SEQUENCE SIZE (1..MAX) OF ContextProfile OPTIONAL
+}
+
+OutputValues ::= CHOICE {
+ selectedValues
+ SEQUENCE SIZE (1..MAX) OF ATTRIBUTE.&Type({SupportedAttributes}),
+ matchedValuesOnly NULL
+}
+
+-- ControlOptions ::= SEQUENCE {
+-- serviceControls [0] ServiceControlOptions DEFAULT {},
+-- searchOptions [1] SearchControlOptions DEFAULT {searchAliases},
+-- hierarchyOptions [2] HierarchySelections OPTIONAL
+-- }
+
+EntryLimit ::= SEQUENCE {default INTEGER,
+ max INTEGER
+}
+
+RelaxationPolicy ::= SEQUENCE {
+ basic [0] MRMapping DEFAULT {},
+ tightenings [1] SEQUENCE SIZE (1..MAX) OF MRMapping OPTIONAL,
+ relaxations [2] SEQUENCE SIZE (1..MAX) OF MRMapping OPTIONAL,
+ maximum [3] INTEGER OPTIONAL, -- mandatory if tightenings is present
+ minimum [4] INTEGER DEFAULT 1
+}
+
+MRMapping ::= SEQUENCE {
+ mapping [0] SEQUENCE SIZE (1..MAX) OF Mapping OPTIONAL,
+ substitution [1] SEQUENCE SIZE (1..MAX) OF MRSubstitution OPTIONAL
+}
+
+Mapping ::= SEQUENCE {
+ mappingFunction
+ OBJECT IDENTIFIER
+ (CONSTRAINED BY {-- shall be an--
+
+ -- object identifier of a mapping-based matching algorithm -- }),
+ level INTEGER DEFAULT 0
+}
+
+MRSubstitution ::= SEQUENCE {
+ attribute AttributeType,
+ oldMatchingRule [0] MATCHING-RULE.&id OPTIONAL,
+ newMatchingRule [1] MATCHING-RULE.&id OPTIONAL
+}
+
+-- SEARCH-RULE ::= CLASS {
+-- &dmdId OBJECT IDENTIFIER,
+-- &serviceType OBJECT IDENTIFIER OPTIONAL,
+-- &userClass INTEGER OPTIONAL,
+-- &InputAttributeTypes REQUEST-ATTRIBUTE OPTIONAL,
+-- &combination AttributeCombination OPTIONAL,
+-- &OutputAttributeTypes RESULT-ATTRIBUTE OPTIONAL,
+-- &defaultControls ControlOptions OPTIONAL,
+-- &mandatoryControls ControlOptions OPTIONAL,
+-- &searchRuleControls ControlOptions OPTIONAL,
+-- &familyGrouping FamilyGrouping OPTIONAL,
+-- &familyReturn FamilyReturn OPTIONAL,
+-- &additionalControl AttributeType OPTIONAL,
+-- &relaxation RelaxationPolicy OPTIONAL,
+-- &entryLimit EntryLimit OPTIONAL,
+-- &allowedSubset AllowedSubset DEFAULT '111'B,
+-- &imposedSubset ImposedSubset OPTIONAL,
+-- &id INTEGER UNIQUE
+-- }
+-- WITH SYNTAX {
+-- DMD ID &dmdId
+-- [SERVICE-TYPE &serviceType]
+-- [USER-CLASS &userClass]
+-- [INPUT ATTRIBUTES &InputAttributeTypes]
+-- [COMBINATION &combination]
+-- [OUTPUT ATTRIBUTES &OutputAttributeTypes]
+-- [DEFAULT CONTROL &defaultControls]
+-- [MANDATORY CONTROL &mandatoryControls]
+-- [SEARCH-RULE CONTROL &searchRuleControls]
+-- [FAMILY-GROUPING &familyGrouping]
+-- [FAMILY-RETURN &familyReturn]
+-- [ADDITIONAL CONTROL &additionalControl]
+-- [RELAXATION &relaxation]
+-- [ALLOWED SUBSET &allowedSubset]
+-- [IMPOSED SUBSET &imposedSubset]
+-- [ENTRY LIMIT &entryLimit]
+-- ID &id
+-- }
+
+REQUEST-ATTRIBUTE ::= CLASS {
+ &attributeType ATTRIBUTE.&id,
+ &SelectedValues ATTRIBUTE.&Type OPTIONAL,
+ &DefaultValues SEQUENCE {entryType OBJECT-CLASS.&id OPTIONAL,
+ values SEQUENCE OF ATTRIBUTE.&Type
+ } OPTIONAL,
+ &contexts SEQUENCE OF ContextProfile OPTIONAL,
+ &contextCombination ContextCombination OPTIONAL,
+ &MatchingUse MatchingUse OPTIONAL,
+ &includeSubtypes BOOLEAN DEFAULT FALSE
+}
+WITH SYNTAX {
+ ATTRIBUTE TYPE &attributeType
+ [SELECTED VALUES &SelectedValues]
+ [DEFAULT VALUES &DefaultValues]
+ [CONTEXTS &contexts]
+ [CONTEXT COMBINATION &contextCombination]
+ [MATCHING USE &MatchingUse]
+ [INCLUDE SUBTYPES &includeSubtypes]
+}
+
+RESULT-ATTRIBUTE ::= CLASS {
+ &attributeType ATTRIBUTE.&id,
+ &outputValues OutputValues OPTIONAL,
+ &contexts ContextProfile OPTIONAL
+}
+WITH SYNTAX {
+ ATTRIBUTE TYPE &attributeType
+ [OUTPUT VALUES &outputValues]
+ [CONTEXTS &contexts]
+}
+
+MATCHING-RESTRICTION ::= CLASS {
+ &Restriction ,
+ &Rules MATCHING-RULE.&id,
+ &id OBJECT IDENTIFIER UNIQUE
+}WITH SYNTAX {RESTRICTION &Restriction
+ RULES &Rules
+ ID &id
+}
+
+-- object identifier assignments
+-- object classes
+id-oc-top OBJECT IDENTIFIER ::=
+ {id-oc 0}
+
+id-oc-alias OBJECT IDENTIFIER ::= {id-oc 1}
+
+id-oc-parent OBJECT IDENTIFIER ::= {id-oc 28}
+
+id-oc-child OBJECT IDENTIFIER ::= {id-oc 29}
+
+-- attributes
+id-at-objectClass OBJECT IDENTIFIER ::= {id-at 0}
+
+id-at-aliasedEntryName OBJECT IDENTIFIER ::= {id-at 1}
+
+-- matching rules
+id-mr-objectIdentifierMatch OBJECT IDENTIFIER ::= {id-mr 0}
+
+id-mr-distinguishedNameMatch OBJECT IDENTIFIER ::= {id-mr 1}
+
+-- operational attributes
+id-oa-excludeAllCollectiveAttributes OBJECT IDENTIFIER ::=
+ {id-oa 0}
+
+id-oa-createTimestamp OBJECT IDENTIFIER ::= {id-oa 1}
+
+id-oa-modifyTimestamp OBJECT IDENTIFIER ::= {id-oa 2}
+
+id-oa-creatorsName OBJECT IDENTIFIER ::= {id-oa 3}
+
+id-oa-modifiersName OBJECT IDENTIFIER ::= {id-oa 4}
+
+id-oa-administrativeRole OBJECT IDENTIFIER ::= {id-oa 5}
+
+id-oa-subtreeSpecification OBJECT IDENTIFIER ::= {id-oa 6}
+
+id-oa-collectiveExclusions OBJECT IDENTIFIER ::= {id-oa 7}
+
+id-oa-subschemaTimestamp OBJECT IDENTIFIER ::= {id-oa 8}
+
+id-oa-hasSubordinates OBJECT IDENTIFIER ::= {id-oa 9}
+
+id-oa-subschemaSubentryList OBJECT IDENTIFIER ::= {id-oa 10}
+
+id-oa-accessControlSubentryList OBJECT IDENTIFIER ::= {id-oa 11}
+
+id-oa-collectiveAttributeSubentryList OBJECT IDENTIFIER ::= {id-oa 12}
+
+id-oa-contextDefaultSubentryList OBJECT IDENTIFIER ::= {id-oa 13}
+
+id-oa-contextAssertionDefault OBJECT IDENTIFIER ::= {id-oa 14}
+
+id-oa-serviceAdminSubentryList OBJECT IDENTIFIER ::= {id-oa 15}
+
+id-oa-searchRules OBJECT IDENTIFIER ::= {id-oa 16}
+
+id-oa-hierarchyLevel OBJECT IDENTIFIER ::= {id-oa 17}
+
+id-oa-hierarchyBelow OBJECT IDENTIFIER ::= {id-oa 18}
+
+id-oa-hierarchyParent OBJECT IDENTIFIER ::= {id-oa 19}
+
+-- subentry classes
+id-sc-subentry OBJECT IDENTIFIER ::= {id-sc 0}
+
+id-sc-accessControlSubentry OBJECT IDENTIFIER ::= {id-sc 1}
+
+id-sc-collectiveAttributeSubentry OBJECT IDENTIFIER ::= {id-sc 2}
+
+id-sc-contextAssertionSubentry OBJECT IDENTIFIER ::= {id-sc 3}
+
+id-sc-serviceAdminSubentry OBJECT IDENTIFIER ::= {id-sc 4}
+
+-- Name forms
+id-nf-subentryNameForm OBJECT IDENTIFIER ::= {id-nf 16}
+
+-- administrative roles
+id-ar-autonomousArea OBJECT IDENTIFIER ::= {id-ar 1}
+
+id-ar-accessControlSpecificArea OBJECT IDENTIFIER ::= {id-ar 2}
+
+id-ar-accessControlInnerArea OBJECT IDENTIFIER ::= {id-ar 3}
+
+id-ar-subschemaAdminSpecificArea OBJECT IDENTIFIER ::= {id-ar 4}
+
+id-ar-collectiveAttributeSpecificArea OBJECT IDENTIFIER ::= {id-ar 5}
+
+id-ar-collectiveAttributeInnerArea OBJECT IDENTIFIER ::= {id-ar 6}
+
+id-ar-contextDefaultSpecificArea OBJECT IDENTIFIER ::= {id-ar 7}
+
+id-ar-serviceSpecificArea OBJECT IDENTIFIER ::= {id-ar 8}
+
+END -- InformationFramework
+
+-- Generated by Asnp, the ASN.1 pretty-printer of France Telecom R&D
+
diff --git a/lib/asn1/test/asn1_SUITE_data/modified_x420/MTSAbstractService.asn b/lib/asn1/test/asn1_SUITE_data/modified_x420/MTSAbstractService.asn
new file mode 100644
index 0000000000..68a5118bc8
--- /dev/null
+++ b/lib/asn1/test/asn1_SUITE_data/modified_x420/MTSAbstractService.asn
@@ -0,0 +1,2366 @@
+-- Module MTSAbstractService (X.411:06/1999)
+MTSAbstractService {joint-iso-itu-t mhs(6) mts(3) modules(0)
+ mts-abstract-service(1) version-1999(1)} DEFINITIONS IMPLICIT TAGS ::=
+BEGIN
+
+-- Prologue
+-- Exports everything
+IMPORTS
+ -- Remote Operations
+ CONNECTION-PACKAGE, CONTRACT, ERROR, OPERATION, OPERATION-PACKAGE,
+ ROS-OBJECT-CLASS
+ --==
+ FROM Remote-Operations-Information-Objects {joint-iso-itu-t
+ remote-operations(4) informationObjects(5) version1(0)}
+ emptyUnbind
+ --==
+ FROM Remote-Operations-Useful-Definitions {joint-iso-itu-t
+ remote-operations(4) useful-definitions(7) version1(0)}
+ -- MTA Abstract Service
+ internal-trace-information, trace-information
+ --==
+ FROM MTAAbstractService {joint-iso-itu-t mhs(6) mts(3) modules(0)
+ mta-abstract-service(2) version-1999(1)}
+ -- MS Abstract Service Extension
+ forwarding-request
+ --==
+ FROM MSAbstractService {joint-iso-itu-t mhs(6) ms(4) modules(0)
+ abstract-service(1) version-1999(1)}
+ -- IPM Information Objects
+ IPMPerRecipientEnvelopeExtensions
+ --==
+ FROM IPMSInformationObjects {joint-iso-itu-t mhs(6) ipms(1) modules(0)
+ information-objects(2) version-1999(1)}
+ -- Object Identifiers
+ id-att-physicalRendition-basic, id-cp-mts-connect, id-ct-mts-access,
+ id-ct-mts-forced-access, id-ot-mts, id-ot-mts-user, id-pt-administration,
+ id-pt-delivery, id-pt-submission, id-tok-asymmetricToken
+ --==
+ FROM MTSObjectIdentifiers {joint-iso-itu-t mhs(6) mts(3) modules(0)
+ object-identifiers(0) version-1999(1)}
+ -- Operation and Error Codes
+ err-control-violates-registration,
+ err-deferred-delivery-cancellation-rejected, err-delivery-control-violated,
+ err-element-of-service-not-subscribed, err-inconsistent-request,
+ err-message-submission-identifier-invalid,
+ err-new-credentials-unacceptable,
+ err-old-credentials-incorrectly-specified, err-operation-refused,
+ err-originator-invalid, err-recipient-improperly-specified,
+ err-register-rejected, err-remote-bind-error, err-security-error,
+ err-submission-control-violated, err-unsupported-critical-function,
+ op-cancel-deferred-delivery, op-change-credentials, op-delivery-control,
+ op-message-delivery, op-message-submission, op-probe-submission,
+ op-register, op-report-delivery, op-submission-control
+ --==
+ FROM MTSAccessProtocol {joint-iso-itu-t mhs(6) protocols(0) modules(0)
+ mts-access-protocol(1) version-1999(1)}
+ -- Directory Definitions
+ Name
+ --==
+ FROM InformationFramework
+ PresentationAddress
+ --==
+ FROM SelectedAttributeTypes
+ ALGORITHM, AlgorithmIdentifier, Certificates, ENCRYPTED{}, SIGNATURE{},
+ SIGNED{}
+ --==
+ FROM AuthenticationFramework
+
+ -- Certificate Extensions
+ CertificateAssertion
+ --==
+ FROM CertificateExtensions
+
+ -- Upper Bounds
+ ub-bit-options, ub-built-in-content-type,
+ ub-built-in-encoded-information-types, ub-certificates,
+ ub-common-name-length, ub-content-id-length, ub-content-length,
+ ub-content-types, ub-country-name-alpha-length,
+ ub-country-name-numeric-length, ub-deliverable-class, ub-diagnostic-codes,
+ ub-dl-expansions, ub-domain-defined-attributes,
+ ub-domain-defined-attribute-type-length,
+ ub-domain-defined-attribute-value-length, ub-domain-name-length,
+ ub-encoded-information-types, ub-extension-attributes, ub-extension-types,
+ ub-e163-4-number-length, ub-e163-4-sub-address-length,
+ ub-generation-qualifier-length, ub-given-name-length, ub-initials-length,
+ ub-integer-options, ub-local-id-length, ub-mta-name-length,
+ ub-mts-user-types, ub-numeric-user-id-length, ub-organization-name-length,
+ ub-organizational-units, ub-organizational-unit-name-length,
+ ub-orig-and-dl-expansions, ub-password-length, ub-pds-name-length,
+ ub-pds-parameter-length, ub-pds-physical-address-lines,
+ ub-postal-code-length, ub-privacy-mark-length, ub-queue-size,
+ ub-reason-codes, ub-recipients, ub-recipient-number-for-advice-length,
+ ub-redirections, ub-redirection-classes, ub-restrictions,
+ ub-security-categories, ub-security-labels, ub-security-problems,
+ ub-supplementary-info-length, ub-surname-length, ub-terminal-id-length,
+ ub-tsap-id-length, ub-unformatted-address-length,
+ ub-universal-generation-qualifier-length, ub-universal-given-name-length,
+ ub-universal-initials-length, ub-universal-surname-length,
+ ub-x121-address-length
+ --==
+ FROM MTSUpperBounds {joint-iso-itu-t mhs(6) mts(3) modules(0)
+ upper-bounds(3) version-1999(1)};
+
+operationObject1 OPERATION ::= {LINKED {operationObject2}
+}
+
+operationObject2 OPERATION ::= {LINKED {operationObject3}
+}
+
+operationObject3 OPERATION ::= {LINKED {operationObject4}
+}
+
+operationObject4 OPERATION ::= {LINKED {...}
+}
+
+-- Objects
+MHS-OBJECT ::= ROS-OBJECT-CLASS
+
+mts MHS-OBJECT ::= {
+ INITIATES {mts-forced-access-contract}
+ RESPONDS {mts-access-contract}
+ ID id-ot-mts
+}
+
+mts-user MHS-OBJECT ::= {
+ INITIATES {mts-access-contract}
+ RESPONDS {mts-forced-access-contract}
+ ID id-ot-mts-user
+}
+
+-- Contracts
+mts-access-contract CONTRACT ::= {
+ CONNECTION mts-connect
+ INITIATOR CONSUMER OF {submission | delivery | administration}
+ ID id-ct-mts-access
+}
+
+mts-forced-access-contract CONTRACT ::= {
+ CONNECTION mts-connect
+ RESPONDER CONSUMER OF {submission | delivery | administration}
+ ID id-ct-mts-forced-access
+}
+
+-- Connection package
+mts-connect CONNECTION-PACKAGE ::= {
+ BIND mts-bind
+ UNBIND mts-unbind
+ ID id-cp-mts-connect
+}
+
+-- Ports
+PORT ::= OPERATION-PACKAGE
+
+submission PORT ::= {
+ OPERATIONS {operationObject1, ...}
+ CONSUMER INVOKES
+ {message-submission | probe-submission | cancel-deferred-delivery, ...}
+ SUPPLIER INVOKES {submission-control, ...}
+ ID id-pt-submission
+}
+
+delivery PORT ::= {
+ OPERATIONS {operationObject1, ...}
+ CONSUMER INVOKES {delivery-control, ...}
+ SUPPLIER INVOKES {message-delivery | report-delivery, ...}
+ ID id-pt-delivery
+}
+
+administration PORT ::= {
+ OPERATIONS {change-credentials, ...}
+ CONSUMER INVOKES {register, ...}
+ SUPPLIER INVOKES {operationObject1, ...}
+ ID id-pt-administration
+}
+
+-- MTS-bind and MTS-unbind
+ABSTRACT-OPERATION ::= OPERATION
+
+ABSTRACT-ERROR ::= ERROR
+
+mts-bind ABSTRACT-OPERATION ::= {
+ ARGUMENT MTSBindArgument
+ RESULT MTSBindResult
+ ERRORS {mts-bind-error}
+}
+
+MTSBindArgument ::= SET {
+ initiator-name ObjectName,
+ messages-waiting [1] EXPLICIT MessagesWaiting OPTIONAL,
+ initiator-credentials [2] InitiatorCredentials,
+ security-context [3] SecurityContext OPTIONAL,
+ ...,
+ extensions
+ [5] SET OF ExtensionField{{MTSBindExtensions}} DEFAULT {}
+}
+
+MTSBindExtensions EXTENSION ::= {PrivateExtensions, ...}
+
+-- May contain private extensions and future standardised extensions
+MTSBindResult ::= SET {
+ responder-name ObjectName,
+ messages-waiting [1] EXPLICIT MessagesWaiting OPTIONAL,
+ responder-credentials [2] ResponderCredentials,
+ ...,
+ extensions
+ [5] SET OF ExtensionField{{MTSBindResultExtensions}} DEFAULT {}
+}
+
+MTSBindResultExtensions EXTENSION ::= {PrivateExtensions, ...}
+
+-- May contain private extensions and future standardised extensions
+mts-bind-error ABSTRACT-ERROR ::= {
+ PARAMETER
+ INTEGER {busy(0), authentication-error(2), unacceptable-dialogue-mode(3),
+ unacceptable-security-context(4),
+ inadequate-association-confidentiality(5)}(0..ub-integer-options)
+}
+
+mts-unbind ABSTRACT-OPERATION ::= emptyUnbind
+
+-- Association Control Parameters
+ObjectName ::= CHOICE {
+ user-agent ORAddressAndOptionalDirectoryName,
+ mTA [0] MTAName,
+ message-store [4] ORAddressAndOptionalDirectoryName
+}
+
+MessagesWaiting ::= SET {
+ urgent [0] DeliveryQueue,
+ normal [1] DeliveryQueue,
+ non-urgent [2] DeliveryQueue
+}
+
+DeliveryQueue ::= SET {
+ messages [0] INTEGER(0..ub-queue-size),
+ octets [1] INTEGER(0..ub-content-length) OPTIONAL
+}
+
+InitiatorCredentials ::= Credentials
+
+ResponderCredentials ::= Credentials
+
+Credentials ::= CHOICE {
+ simple Password,
+ strong [0] StrongCredentials,
+ ...,
+ protected [1] ProtectedPassword
+}
+
+Password ::= CHOICE {
+ ia5-string IA5String(SIZE (0..ub-password-length)),
+ octet-string OCTET STRING(SIZE (0..ub-password-length))
+}
+
+StrongCredentials ::= SET {
+ bind-token [0] Token OPTIONAL,
+ certificate [1] Certificates OPTIONAL,
+ ...,
+ certificate-selector [2] CertificateAssertion OPTIONAL
+}
+
+ProtectedPassword ::= SET {
+ signature
+ SIGNATURE{SET {password Password,
+ time1 [0] UTCTime OPTIONAL,
+ time2 [1] UTCTime OPTIONAL,
+ random1 [2] BIT STRING OPTIONAL,
+ random2 [3] BIT STRING OPTIONAL}},
+ time1 [0] UTCTime OPTIONAL,
+ time2 [1] UTCTime OPTIONAL,
+ random1 [2] BIT STRING OPTIONAL,
+ random2 [3] BIT STRING OPTIONAL
+}
+
+SecurityContext ::= SET SIZE (1..ub-security-labels) OF SecurityLabel
+
+-- Submission Port
+message-submission ABSTRACT-OPERATION ::= {
+ ARGUMENT MessageSubmissionArgument
+ RESULT MessageSubmissionResult
+ ERRORS
+ {submission-control-violated | element-of-service-not-subscribed |
+ originator-invalid | recipient-improperly-specified |
+ inconsistent-request | security-error | unsupported-critical-function |
+ remote-bind-error}
+ LINKED {operationObject1, ...}
+ INVOKE PRIORITY {4 | 6 | 7}
+ CODE op-message-submission
+}
+
+MessageSubmissionArgument ::= SEQUENCE {
+ envelope MessageSubmissionEnvelope,
+ content Content
+}
+
+MessageSubmissionResult ::= SET {
+ message-submission-identifier MessageSubmissionIdentifier,
+ message-submission-time [0] MessageSubmissionTime,
+ content-identifier ContentIdentifier OPTIONAL,
+ extensions
+ [1] SET OF ExtensionField{{MessageSubmissionResultExtensions}} DEFAULT {}
+}
+
+MessageSubmissionResultExtensions EXTENSION ::=
+ {-- May contain the following extensions, private extensions, and future standardised extensions,
+ -- at most one instance of each extension type:
+ originating-MTA-certificate | proof-of-submission | PrivateExtensions,
+ ...}
+
+probe-submission ABSTRACT-OPERATION ::= {
+ ARGUMENT ProbeSubmissionArgument
+ RESULT ProbeSubmissionResult
+ ERRORS
+ {submission-control-violated | element-of-service-not-subscribed |
+ originator-invalid | recipient-improperly-specified |
+ inconsistent-request | security-error | unsupported-critical-function |
+ remote-bind-error}
+ LINKED {operationObject1, ...}
+ INVOKE PRIORITY {5}
+ CODE op-probe-submission
+}
+
+ProbeSubmissionArgument ::= ProbeSubmissionEnvelope
+
+ProbeSubmissionResult ::= SET {
+ probe-submission-identifier ProbeSubmissionIdentifier,
+ probe-submission-time [0] ProbeSubmissionTime,
+ content-identifier ContentIdentifier OPTIONAL,
+ extensions
+ [1] SET OF ExtensionField{{ProbeResultExtensions}} DEFAULT {}
+}
+
+ProbeResultExtensions EXTENSION ::= {PrivateExtensions, ...}
+
+-- May contain private extensions and future standardised extensions,
+-- at most one instance of each extension type
+cancel-deferred-delivery ABSTRACT-OPERATION ::= {
+ ARGUMENT CancelDeferredDeliveryArgument
+ RESULT CancelDeferredDeliveryResult
+ ERRORS
+ {deferred-delivery-cancellation-rejected |
+ message-submission-identifier-invalid | remote-bind-error}
+ LINKED {operationObject1, ...}
+ INVOKE PRIORITY {3}
+ CODE op-cancel-deferred-delivery
+}
+
+CancelDeferredDeliveryArgument ::= MessageSubmissionIdentifier
+
+CancelDeferredDeliveryResult ::= NULL
+
+submission-control ABSTRACT-OPERATION ::= {
+ ARGUMENT SubmissionControlArgument
+ RESULT SubmissionControlResult
+ ERRORS {security-error | remote-bind-error}
+ LINKED {operationObject1, ...}
+ INVOKE PRIORITY {3}
+ CODE op-submission-control
+}
+
+SubmissionControlArgument ::= SubmissionControls
+
+SubmissionControlResult ::= Waiting
+
+submission-control-violated ABSTRACT-ERROR ::= {
+ PARAMETER NULL
+ CODE err-submission-control-violated
+}
+
+element-of-service-not-subscribed ABSTRACT-ERROR ::= {
+ PARAMETER NULL
+ CODE err-element-of-service-not-subscribed
+}
+
+deferred-delivery-cancellation-rejected ABSTRACT-ERROR ::= {
+ PARAMETER NULL
+ CODE err-deferred-delivery-cancellation-rejected
+}
+
+originator-invalid ABSTRACT-ERROR ::= {
+ PARAMETER NULL
+ CODE err-originator-invalid
+}
+
+recipient-improperly-specified ABSTRACT-ERROR ::= {
+ PARAMETER ImproperlySpecifiedRecipients
+ CODE err-recipient-improperly-specified
+}
+
+ImproperlySpecifiedRecipients ::=
+ SEQUENCE SIZE (1..ub-recipients) OF RecipientName
+
+message-submission-identifier-invalid ABSTRACT-ERROR ::= {
+ PARAMETER NULL
+ CODE err-message-submission-identifier-invalid
+}
+
+inconsistent-request ABSTRACT-ERROR ::= {
+ PARAMETER NULL
+ CODE err-inconsistent-request
+}
+
+security-error ABSTRACT-ERROR ::= {
+ PARAMETER SecurityProblem
+ CODE err-security-error
+}
+
+SecurityProblem ::= INTEGER {
+ assemby-instructions-conflict-with-security-services(0),
+ authentication-problem(1), authentication-failure-on-subject-message(2),
+ confidentiality-association-problem(3), decryption-failed(4),
+ decryption-key-unobtainable(5), failure-of-proof-of-message(6),
+ forbidden-user-security-label-register(7),
+ incompatible-change-with-original-security-context(8),
+ integrity-failure-on-subject-message(9), invalid-security-label(10),
+ invalid-security-label-update(11), key-failure(12),
+ mandatory-parameter-absence(13), operation-security-failure(14),
+ redirection-prohibited(15), refused-alternate-recipient-name(16),
+ repudiation-failure-of-message(17),
+ responder-credentials-checking-problem(18), security-context-failure(19),
+ security-context-problem(20), security-policy-violation(21),
+ security-services-refusal(22), token-decryption-failed(23), token-error(24),
+ unable-to-aggregate-security-labels(25), unauthorised-dl-name(26),
+ unauthorised-entry-class(27),
+ unauthorised-originally-intended-recipient-name(28),
+ unauthorised-originator-name(29), unauthorised-recipient-name(30),
+ unauthorised-security-label-update(31), unauthorised-user-name(32),
+ unknown-security-label(33), unsupported-algorithm-identifier(34),
+ unsupported-security-policy(35)}(0..ub-security-problems)
+
+unsupported-critical-function ABSTRACT-ERROR ::= {
+ PARAMETER NULL
+ CODE err-unsupported-critical-function
+}
+
+remote-bind-error ABSTRACT-ERROR ::= {
+ PARAMETER NULL
+ CODE err-remote-bind-error
+}
+
+-- Submission Port Parameters
+MessageSubmissionIdentifier ::= MTSIdentifier
+
+MessageSubmissionTime ::= Time
+
+ProbeSubmissionIdentifier ::= MTSIdentifier
+
+ProbeSubmissionTime ::= Time
+
+SubmissionControls ::=
+ Controls
+ (WITH COMPONENTS {
+ ...,
+ permissible-content-types ABSENT,
+ permissible-encoded-information-types ABSENT
+ })
+
+Waiting ::= SET {
+ waiting-operations [0] Operations DEFAULT {},
+ waiting-messages [1] WaitingMessages DEFAULT {},
+ waiting-content-types
+ [2] SET SIZE (0..ub-content-types) OF ContentType DEFAULT {},
+ waiting-encoded-information-types EncodedInformationTypes OPTIONAL
+}
+
+Operations ::= BIT STRING {
+ probe-submission-or-report-delivery(0),
+ message-submission-or-message-delivery(1)}(SIZE (0..ub-bit-options))
+
+-- holding 'one', not-holding 'zero'
+WaitingMessages ::= BIT STRING {
+ long-content(0), low-priority(1), other-security-labels(2)
+}(SIZE (0..ub-bit-options))
+
+-- Delivery Port
+message-delivery ABSTRACT-OPERATION ::= {
+ ARGUMENT MessageDeliveryArgument
+ RESULT MessageDeliveryResult
+ ERRORS
+ {delivery-control-violated | security-error |
+ unsupported-critical-function}
+ LINKED {operationObject1, ...}
+ INVOKE PRIORITY {4 | 6 | 7}
+ CODE op-message-delivery
+}
+
+MessageDeliveryArgument ::= SEQUENCE {
+ COMPONENTS OF MessageDeliveryEnvelope,
+ content Content
+}
+
+MessageDeliveryResult ::= SET {
+ recipient-certificate [0] RecipientCertificate OPTIONAL,
+ proof-of-delivery [1] IMPLICIT ProofOfDelivery OPTIONAL,
+ ...,
+ extensions
+ [2] SET OF ExtensionField{{MessageDeliveryResultExtensions}} DEFAULT {}
+}
+
+MessageDeliveryResultExtensions EXTENSION ::= {PrivateExtensions, ...}
+
+-- May contain private extensions and future standardised extensions
+report-delivery ABSTRACT-OPERATION ::= {
+ ARGUMENT ReportDeliveryArgument
+ RESULT ReportDeliveryResult
+ ERRORS
+ {delivery-control-violated | security-error |
+ unsupported-critical-function}
+ LINKED {operationObject1, ...}
+ INVOKE PRIORITY {5}
+ CODE op-report-delivery
+}
+
+ReportDeliveryArgument ::= SET {
+ COMPONENTS OF ReportDeliveryEnvelope,
+ returned-content [0] Content OPTIONAL
+}
+
+ReportDeliveryResult ::= CHOICE {
+ empty-result NULL,
+ ...,
+ extensions
+ SET SIZE (1..MAX) OF ExtensionField{{ReportDeliveryResultExtensions}}
+}
+
+ReportDeliveryResultExtensions EXTENSION ::= {PrivateExtensions, ...}
+
+-- May contain private extensions and future standardised extensions
+delivery-control ABSTRACT-OPERATION ::= {
+ ARGUMENT DeliveryControlArgument
+ RESULT DeliveryControlResult
+ ERRORS
+ {control-violates-registration | security-error | operation-refused}
+ LINKED {operationObject1, ...}
+ INVOKE PRIORITY {3}
+ CODE op-delivery-control
+}
+
+DeliveryControlArgument ::= SET {
+ COMPONENTS OF DeliveryControls,
+ extensions
+ [6] SET OF ExtensionField{{DeliveryControlExtensions}} DEFAULT {}
+}
+
+DeliveryControlExtensions EXTENSION ::= {PrivateExtensions, ...}
+
+-- May contain private extensions and future standardised extensions
+DeliveryControlResult ::= SET {
+ COMPONENTS OF Waiting,
+ extensions
+ [6] SET OF ExtensionField{{DeliveryControlResultExtensions}} DEFAULT {}
+}
+
+DeliveryControlResultExtensions EXTENSION ::= {PrivateExtensions, ...}
+
+-- May contain private extensions and future standardised extensions
+delivery-control-violated ABSTRACT-ERROR ::= {
+ PARAMETER NULL
+ CODE err-delivery-control-violated
+}
+
+control-violates-registration ABSTRACT-ERROR ::= {
+ PARAMETER NULL
+ CODE err-control-violates-registration
+}
+
+operation-refused ABSTRACT-ERROR ::= {
+ PARAMETER RefusedOperation
+ CODE err-operation-refused
+}
+
+RefusedOperation ::= SET {
+ refused-argument
+ CHOICE {built-in-argument [1] RefusedArgument,
+ refused-extension EXTENSION.&id},
+ refusal-reason [2] RefusalReason
+}
+
+RefusedArgument ::= INTEGER {
+ user-name(0), user-address(1), deliverable-content-types(2),
+ deliverable-maximum-content-length(3),
+ deliverable-encoded-information-types-constraints(4),
+ deliverable-security-labels(5), recipient-assigned-redirections(6),
+ restricted-delivery(7),
+ retrieve-registrations(8), -- value 9 reserved for possible future extension to Register arguments
+ restrict(10), permissible-operations(11), permissible-lowest-priority(12),
+ permissible-encoded-information-types(13), permissible-content-types(14),
+ permissible-maximum-content-length(15), permissible-security-context(16)
+}(0..ub-integer-options)
+
+RefusalReason ::= INTEGER {
+ facility-unavailable(0), facility-not-subscribed(1),
+ parameter-unacceptable(2)}(0..ub-integer-options)
+
+-- Delivery Port Parameters
+RecipientCertificate ::= Certificates
+
+ProofOfDelivery ::=
+ SIGNATURE
+ {SEQUENCE {algorithm-identifier
+ ProofOfDeliveryAlgorithmIdentifier,
+ delivery-time MessageDeliveryTime,
+ this-recipient-name ThisRecipientName,
+ originally-intended-recipient-name
+ OriginallyIntendedRecipientName OPTIONAL,
+ content Content,
+ content-identifier ContentIdentifier OPTIONAL,
+ message-security-label
+ MessageSecurityLabel OPTIONAL}}
+
+ProofOfDeliveryAlgorithmIdentifier ::= AlgorithmIdentifier
+
+DeliveryControls ::= Controls
+
+Controls ::= SET {
+ restrict [0] BOOLEAN DEFAULT TRUE,
+ -- update 'TRUE', remove 'FALSE'
+ permissible-operations [1] Operations OPTIONAL,
+ permissible-maximum-content-length [2] ContentLength OPTIONAL,
+ permissible-lowest-priority Priority OPTIONAL,
+ permissible-content-types [4] ContentTypes OPTIONAL,
+ permissible-encoded-information-types
+ PermissibleEncodedInformationTypes OPTIONAL,
+ permissible-security-context [5] SecurityContext OPTIONAL
+}
+
+-- Note - The Tags [0], [1] and [2] are altered for the Register operation only.
+PermissibleEncodedInformationTypes ::=
+ EncodedInformationTypesConstraints
+
+-- Administration Port
+register ABSTRACT-OPERATION ::= {
+ ARGUMENT RegisterArgument
+ RESULT RegisterResult
+ ERRORS
+ {register-rejected | remote-bind-error | operation-refused |
+ security-error}
+ LINKED {operationObject1, ...}
+ INVOKE PRIORITY {5}
+ CODE op-register
+}
+
+RegisterArgument ::= SET {
+ user-name UserName OPTIONAL,
+ user-address [0] UserAddress OPTIONAL,
+ deliverable-class
+ SET SIZE (1..ub-deliverable-class) OF DeliverableClass OPTIONAL,
+ default-delivery-controls [2] EXPLICIT DefaultDeliveryControls OPTIONAL,
+ redirections [3] Redirections OPTIONAL,
+ restricted-delivery [4] RestrictedDelivery OPTIONAL,
+ retrieve-registrations [5] RegistrationTypes OPTIONAL,
+ extensions
+ [6] SET OF ExtensionField{{RegisterExtensions}} DEFAULT {}
+}
+
+RegisterExtensions EXTENSION ::= {PrivateExtensions, ...}
+
+-- May contain private extensions and future standardised extensions
+RegisterResult ::= CHOICE {
+ empty-result NULL,
+ non-empty-result
+ SET {registered-information
+ [0] RegisterArgument
+ (WITH COMPONENTS {
+ ...,
+ retrieve-registrations ABSENT
+ }) OPTIONAL,
+ extensions
+ [1] SET OF ExtensionField{{RegisterResultExtensions}} DEFAULT {}
+ }
+}
+
+RegisterResultExtensions EXTENSION ::= {PrivateExtensions, ...}
+
+-- May contain private extensions and future standardised extensions
+change-credentials ABSTRACT-OPERATION ::= {
+ ARGUMENT ChangeCredentialsArgument
+ RESULT NULL
+ ERRORS
+ {new-credentials-unacceptable | old-credentials-incorrectly-specified |
+ remote-bind-error | security-error}
+ LINKED {operationObject1, ...}
+ INVOKE PRIORITY {5}
+ CODE op-change-credentials
+}
+
+ChangeCredentialsArgument ::= SET {
+ old-credentials [0] Credentials(WITH COMPONENTS {
+ simple
+ }),
+ new-credentials [1] Credentials(WITH COMPONENTS {
+ simple
+ })
+}
+
+register-rejected ABSTRACT-ERROR ::= {
+ PARAMETER NULL
+ CODE err-register-rejected
+}
+
+new-credentials-unacceptable ABSTRACT-ERROR ::= {
+ PARAMETER NULL
+ CODE err-new-credentials-unacceptable
+}
+
+old-credentials-incorrectly-specified ABSTRACT-ERROR ::= {
+ PARAMETER NULL
+ CODE err-old-credentials-incorrectly-specified
+}
+
+-- Administration Port Parameters
+UserName ::= ORAddressAndOptionalDirectoryName
+
+UserAddress ::= CHOICE {
+ x121
+ [0] SEQUENCE {x121-address
+ NumericString(SIZE (1..ub-x121-address-length)) OPTIONAL,
+ tsap-id
+ PrintableString(SIZE (1..ub-tsap-id-length)) OPTIONAL
+ },
+ presentation [1] PSAPAddress
+}
+
+PSAPAddress ::= PresentationAddress
+
+DeliverableClass ::=
+ MessageClass
+ (WITH COMPONENTS {
+ ...,
+ priority ABSENT,
+ -- The 'objects' component shall always be defaulted.
+ -- objects ABSENT,
+ -- A component with a DEFAULT clause cannot be ABSENT
+ applies-only-to ABSENT
+ })
+
+DefaultDeliveryControls ::=
+ Controls
+ (WITH COMPONENTS {
+ ...,
+
+ -- The 'restrict' component shall always be defaulted.
+ -- restrict ABSENT,
+ -- A component with a DEFAULT clause cannot be ABSENT
+ permissible-security-context ABSENT
+ })
+
+Redirections ::= SEQUENCE SIZE (1..ub-redirections) OF RecipientRedirection
+
+RecipientRedirection ::= SET {
+ redirection-classes
+ [0] SET SIZE (1..ub-redirection-classes) OF RedirectionClass OPTIONAL,
+ recipient-assigned-alternate-recipient
+ [1] RecipientAssignedAlternateRecipient OPTIONAL
+}
+
+RedirectionClass ::= MessageClass
+
+MessageClass ::= SET {
+ content-types [0] ContentTypes OPTIONAL,
+ maximum-content-length [1] ContentLength OPTIONAL,
+ encoded-information-types-constraints
+ [2] EncodedInformationTypesConstraints OPTIONAL,
+ security-labels [3] SecurityContext OPTIONAL,
+ priority [4] SET OF Priority OPTIONAL,
+ objects
+ [5] ENUMERATED {messages(0), reports(1), both(2), ...
+ } DEFAULT both,
+ applies-only-to [6] SEQUENCE OF Restriction OPTIONAL, -- Not considered in the case of Reports
+ extensions
+ [7] SET OF ExtensionField{{MessageClassExtensions}} DEFAULT {}
+}
+
+EncodedInformationTypesConstraints ::= SEQUENCE {
+ unacceptable-eits [0] ExtendedEncodedInformationTypes OPTIONAL,
+ acceptable-eits [1] ExtendedEncodedInformationTypes OPTIONAL,
+ exclusively-acceptable-eits [2] ExtendedEncodedInformationTypes OPTIONAL
+}
+
+MessageClassExtensions EXTENSION ::= {PrivateExtensions, ...}
+
+-- May contain private extensions and future standardised extensions
+RecipientAssignedAlternateRecipient ::=
+ ORAddressAndOrDirectoryName
+
+RestrictedDelivery ::= SEQUENCE SIZE (1..ub-restrictions) OF Restriction
+
+Restriction ::= SET {
+ permitted BOOLEAN DEFAULT TRUE,
+ source-type
+ BIT STRING {originated-by(0), redirected-by(1), dl-expanded-by(2)}
+ DEFAULT {originated-by, redirected-by, dl-expanded-by},
+ source-name ExactOrPattern OPTIONAL
+}
+
+ExactOrPattern ::= CHOICE {
+ exact-match [0] ORName,
+ pattern-match [1] ORName
+}
+
+RegistrationTypes ::= SEQUENCE {
+ standard-parameters
+ [0] BIT STRING {user-name(0), user-address(1), deliverable-class(2),
+ default-delivery-controls(3), redirections(4),
+ restricted-delivery(5)} OPTIONAL,
+ extensions [1] SET OF EXTENSION.&id({RegisterExtensions}) OPTIONAL
+}
+
+-- Message Submission Envelope
+MessageSubmissionEnvelope ::= SET {
+ COMPONENTS OF PerMessageSubmissionFields,
+ per-recipient-fields
+ [1] SEQUENCE SIZE (1..ub-recipients) OF
+ PerRecipientMessageSubmissionFields
+}
+
+PerMessageSubmissionFields ::= SET {
+ originator-name OriginatorName,
+ original-encoded-information-types OriginalEncodedInformationTypes OPTIONAL,
+ content-type ContentType,
+ content-identifier ContentIdentifier OPTIONAL,
+ priority Priority DEFAULT normal,
+ per-message-indicators PerMessageIndicators DEFAULT {},
+ deferred-delivery-time [0] DeferredDeliveryTime OPTIONAL,
+ extensions
+ [2] SET OF ExtensionField{{PerMessageSubmissionExtensions}} DEFAULT {}
+}
+
+PerMessageSubmissionExtensions EXTENSION ::=
+ {-- May contain the following extensions, private extensions, and future standardised extensions,
+ -- at most one instance of each extension type:
+ recipient-reassignment-prohibited | dl-expansion-prohibited |
+ conversion-with-loss-prohibited | latest-delivery-time |
+ originator-return-address | originator-certificate |
+ content-confidentiality-algorithm-identifier |
+ message-origin-authentication-check | message-security-label |
+ proof-of-submission-request | content-correlator | dl-exempted-recipients |
+ certificate-selectors | multiple-originator-certificates |
+ forwarding-request -- for MS Abstract Service only -- | PrivateExtensions,
+ ...}
+
+PerRecipientMessageSubmissionFields ::= SET {
+ recipient-name RecipientName,
+ originator-report-request [0] OriginatorReportRequest,
+ explicit-conversion [1] ExplicitConversion OPTIONAL,
+ extensions
+ [2] SET OF ExtensionField{{PerRecipientMessageSubmissionExtensions}}
+ DEFAULT {}
+}
+
+PerRecipientMessageSubmissionExtensions EXTENSION ::=
+ {-- May contain the following extensions, private extensions, and future standardised extensions,
+ -- at most one instance of each extension type:
+ originator-requested-alternate-recipient | requested-delivery-method |
+ physical-forwarding-prohibited | physical-forwarding-address-request |
+ physical-delivery-modes | registered-mail-type | recipient-number-for-advice
+ | physical-rendition-attributes | physical-delivery-report-request |
+ message-token | content-integrity-check | proof-of-delivery-request |
+ certificate-selectors-override | recipient-certificate |
+ IPMPerRecipientEnvelopeExtensions | PrivateExtensions, ...}
+
+-- Probe Submission Envelope
+ProbeSubmissionEnvelope ::= SET {
+ COMPONENTS OF PerProbeSubmissionFields,
+ per-recipient-fields
+ [3] SEQUENCE SIZE (1..ub-recipients) OF PerRecipientProbeSubmissionFields
+}
+
+PerProbeSubmissionFields ::= SET {
+ originator-name OriginatorName,
+ original-encoded-information-types OriginalEncodedInformationTypes OPTIONAL,
+ content-type ContentType,
+ content-identifier ContentIdentifier OPTIONAL,
+ content-length [0] ContentLength OPTIONAL,
+ per-message-indicators PerMessageIndicators DEFAULT {},
+ extensions
+ [2] SET OF ExtensionField{{PerProbeSubmissionExtensions}} DEFAULT {}
+}
+
+PerProbeSubmissionExtensions EXTENSION ::=
+ {-- May contain the following extensions, private extensions, and future standardised extensions,
+ -- at most one instance of each extension type:
+ recipient-reassignment-prohibited | dl-expansion-prohibited |
+ conversion-with-loss-prohibited | originator-certificate |
+ message-security-label | content-correlator |
+ probe-origin-authentication-check | PrivateExtensions, ...}
+
+PerRecipientProbeSubmissionFields ::= SET {
+ recipient-name RecipientName,
+ originator-report-request [0] OriginatorReportRequest,
+ explicit-conversion [1] ExplicitConversion OPTIONAL,
+ extensions
+ [2] SET OF ExtensionField{{PerRecipientProbeSubmissionExtensions}}
+ DEFAULT {}
+}
+
+PerRecipientProbeSubmissionExtensions EXTENSION ::=
+ {-- May contain the following extensions, private extensions, and future standardised extensions,
+ -- at most one instance of each extension type:
+ originator-requested-alternate-recipient | requested-delivery-method |
+ physical-rendition-attributes | PrivateExtensions, ...}
+
+-- Message Delivery Envelope
+MessageDeliveryEnvelope ::= SEQUENCE {
+ message-delivery-identifier MessageDeliveryIdentifier,
+ message-delivery-time MessageDeliveryTime,
+ other-fields OtherMessageDeliveryFields
+}
+
+OtherMessageDeliveryFields ::= SET {
+ content-type DeliveredContentType,
+ originator-name DeliveredOriginatorName,
+ original-encoded-information-types
+ [1] OriginalEncodedInformationTypes OPTIONAL,
+ priority Priority DEFAULT normal,
+ delivery-flags [2] DeliveryFlags OPTIONAL,
+ other-recipient-names [3] OtherRecipientNames OPTIONAL,
+ this-recipient-name [4] ThisRecipientName,
+ originally-intended-recipient-name
+ [5] OriginallyIntendedRecipientName OPTIONAL,
+ converted-encoded-information-types
+ [6] ConvertedEncodedInformationTypes OPTIONAL,
+ message-submission-time [7] MessageSubmissionTime,
+ content-identifier [8] ContentIdentifier OPTIONAL,
+ extensions
+ [9] SET OF ExtensionField{{MessageDeliveryExtensions}} DEFAULT {}
+}
+
+MessageDeliveryExtensions EXTENSION ::=
+ {-- May contain the following extensions, private extensions, and future standardised extensions,
+ -- at most one instance of each extension type:
+ conversion-with-loss-prohibited | requested-delivery-method |
+ physical-forwarding-prohibited | physical-forwarding-address-request |
+ physical-delivery-modes | registered-mail-type | recipient-number-for-advice
+ | physical-rendition-attributes | originator-return-address |
+ physical-delivery-report-request | originator-certificate | message-token |
+ content-confidentiality-algorithm-identifier | content-integrity-check |
+ message-origin-authentication-check | message-security-label |
+ proof-of-delivery-request | dl-exempted-recipients | certificate-selectors |
+ certificate-selectors-override | multiple-originator-certificates |
+ recipient-certificate | IPMPerRecipientEnvelopeExtensions |
+ redirection-history | dl-expansion-history | trace-information |
+ internal-trace-information | PrivateExtensions, ...}
+
+-- Report Delivery Envelope
+ReportDeliveryEnvelope ::= SET {
+ COMPONENTS OF PerReportDeliveryFields,
+ per-recipient-fields
+ SEQUENCE SIZE (1..ub-recipients) OF PerRecipientReportDeliveryFields
+}
+
+PerReportDeliveryFields ::= SET {
+ subject-submission-identifier SubjectSubmissionIdentifier,
+ content-identifier ContentIdentifier OPTIONAL,
+ content-type ContentType OPTIONAL,
+ original-encoded-information-types OriginalEncodedInformationTypes OPTIONAL,
+ extensions
+ [1] SET OF ExtensionField{{ReportDeliveryExtensions}} DEFAULT {}
+}
+
+ReportDeliveryExtensions EXTENSION ::=
+ {-- May contain the following extensions, private extensions, and future standardised extensions,
+ -- at most one instance of each extension type:
+ message-security-label | content-correlator | redirection-history |
+ originator-and-DL-expansion-history | reporting-DL-name |
+ reporting-MTA-certificate | report-origin-authentication-check |
+ trace-information | internal-trace-information | reporting-MTA-name |
+ PrivateExtensions, ...}
+
+PerRecipientReportDeliveryFields ::= SET {
+ actual-recipient-name [0] ActualRecipientName,
+ report-type [1] ReportType,
+ converted-encoded-information-types
+ ConvertedEncodedInformationTypes OPTIONAL,
+ originally-intended-recipient-name
+ [2] OriginallyIntendedRecipientName OPTIONAL,
+ supplementary-information [3] SupplementaryInformation OPTIONAL,
+ extensions
+ [4] SET OF ExtensionField{{PerRecipientReportDeliveryExtensions}}
+ DEFAULT {}
+}
+
+PerRecipientReportDeliveryExtensions EXTENSION ::=
+ {-- May contain the following extensions, private extensions, and future standardised extensions,
+ -- at most one instance of each extension type:
+ redirection-history | physical-forwarding-address | recipient-certificate |
+ proof-of-delivery | PrivateExtensions, ...}
+
+ReportType ::= CHOICE {
+ delivery [0] DeliveryReport,
+ non-delivery [1] NonDeliveryReport
+}
+
+DeliveryReport ::= SET {
+ message-delivery-time [0] MessageDeliveryTime,
+ type-of-MTS-user [1] TypeOfMTSUser DEFAULT public
+}
+
+NonDeliveryReport ::= SET {
+ non-delivery-reason-code [0] NonDeliveryReasonCode,
+ non-delivery-diagnostic-code [1] NonDeliveryDiagnosticCode OPTIONAL
+}
+
+-- Envelope Fields
+OriginatorName ::= ORAddressAndOrDirectoryName
+
+DeliveredOriginatorName ::= ORAddressAndOptionalDirectoryName
+
+OriginalEncodedInformationTypes ::= EncodedInformationTypes
+
+ContentTypes ::= SET SIZE (1..ub-content-types) OF ContentType
+
+ContentType ::= CHOICE {
+ built-in BuiltInContentType,
+ extended ExtendedContentType
+}
+
+BuiltInContentType ::= [APPLICATION 6] INTEGER {
+ unidentified(0),
+ external(1), -- identified by the object-identifier of the EXTERNAL content
+ interpersonal-messaging-1984(2), interpersonal-messaging-1988(22),
+ edi-messaging(35), voice-messaging(40)}(0..ub-built-in-content-type)
+
+ExtendedContentType ::= RELATIVE-OID
+
+DeliveredContentType ::= CHOICE {
+ built-in [0] BuiltInContentType,
+ extended ExtendedContentType
+}
+
+ContentIdentifier ::=
+ [APPLICATION 10] PrintableString(SIZE (1..ub-content-id-length))
+
+PerMessageIndicators ::= [APPLICATION 8] BIT STRING {
+ disclosure-of-other-recipients(0), -- disclosure-of-other-recipients-requested 'one',
+
+ -- disclosure-of-other-recipients-prohibited 'zero';
+ -- ignored for Probe-submission
+ implicit-conversion-prohibited(1), -- implicit-conversion-prohibited 'one',
+
+ -- implicit-conversion-allowed 'zero'
+ alternate-recipient-allowed(2), -- alternate-recipient-allowed 'one',
+
+ -- alternate-recipient-prohibited 'zero'
+ content-return-request(3), -- content-return-requested 'one',
+
+ -- content-return-not-requested 'zero';
+ -- ignored for Probe-submission
+ reserved(4), -- bit reserved by MOTIS 1986
+ bit-5(5),
+ bit-6(6), -- notification type-1 : bit 5 'zero' and bit 6 'one'
+
+ -- notification type-2 : bit 5 'one' and bit 6 'zero'
+ -- notification type-3 : bit 5 'one' and bit 6 'one'
+ -- the mapping between notification type 1, 2, 3
+ -- and the content specific notification types are defined
+ -- in relevant content specifications
+ service-message(7) -- the message content is for service purposes;
+
+
+-- it may be a notification related to a service message;
+-- used only by bilateral agreement --}(SIZE (0..ub-bit-options))
+
+RecipientName ::= ORAddressAndOrDirectoryName
+
+OriginatorReportRequest ::= BIT STRING {report(3), non-delivery-report(4)
+
+-- at most one bit shall be 'one':
+-- report bit 'one' requests a 'report';
+-- non-delivery-report bit 'one' requests a 'non-delivery-report';
+-- both bits 'zero' requests 'no-report' --}(SIZE (0..ub-bit-options))
+
+ExplicitConversion ::= INTEGER {
+ ia5-text-to-teletex(0),
+ -- values 1 to 7 are no longer defined
+ ia5-text-to-g3-facsimile(8), ia5-text-to-g4-class-1(9),
+ ia5-text-to-videotex(10), teletex-to-ia5-text(11),
+ teletex-to-g3-facsimile(12), teletex-to-g4-class-1(13),
+ teletex-to-videotex(14),
+ -- value 15 is no longer defined
+ videotex-to-ia5-text(16), videotex-to-teletex(17)}(0..ub-integer-options)
+
+DeferredDeliveryTime ::= Time
+
+Priority ::= [APPLICATION 7] ENUMERATED {normal(0), non-urgent(1), urgent(2)}
+
+ContentLength ::= INTEGER(0..ub-content-length)
+
+MessageDeliveryIdentifier ::= MTSIdentifier
+
+MessageDeliveryTime ::= Time
+
+DeliveryFlags ::= BIT STRING {
+ implicit-conversion-prohibited(1) -- implicit-conversion-prohibited 'one',
+
+ -- implicit-conversion-allowed 'zero' --}(SIZE (0..ub-bit-options))
+
+OtherRecipientNames ::= SEQUENCE SIZE (1..ub-recipients) OF OtherRecipientName
+
+OtherRecipientName ::= ORAddressAndOptionalDirectoryName
+
+ThisRecipientName ::= ORAddressAndOptionalDirectoryName
+
+OriginallyIntendedRecipientName ::= ORAddressAndOptionalDirectoryName
+
+ConvertedEncodedInformationTypes ::= EncodedInformationTypes
+
+SubjectSubmissionIdentifier ::= MTSIdentifier
+
+ActualRecipientName ::= ORAddressAndOrDirectoryName
+
+TypeOfMTSUser ::= INTEGER {
+ public(0), private(1), ms(2), dl(3), pdau(4), physical-recipient(5), other(6)
+}(0..ub-mts-user-types)
+
+NonDeliveryReasonCode ::= INTEGER {
+ transfer-failure(0), unable-to-transfer(1), conversion-not-performed(2),
+ physical-rendition-not-performed(3), physical-delivery-not-performed(4),
+ restricted-delivery(5), directory-operation-unsuccessful(6),
+ deferred-delivery-not-performed(7), transfer-failure-for-security-reason(8)
+}(0..ub-reason-codes)
+
+NonDeliveryDiagnosticCode ::= INTEGER {
+ unrecognised-OR-name(0), ambiguous-OR-name(1), mts-congestion(2),
+ loop-detected(3), recipient-unavailable(4), maximum-time-expired(5),
+ encoded-information-types-unsupported(6), content-too-long(7),
+ conversion-impractical(8), implicit-conversion-prohibited(9),
+ implicit-conversion-not-subscribed(10), invalid-arguments(11),
+ content-syntax-error(12), size-constraint-violation(13),
+ protocol-violation(14), content-type-not-supported(15),
+ too-many-recipients(16), no-bilateral-agreement(17),
+ unsupported-critical-function(18), conversion-with-loss-prohibited(19),
+ line-too-long(20), page-split(21), pictorial-symbol-loss(22),
+ punctuation-symbol-loss(23), alphabetic-character-loss(24),
+ multiple-information-loss(25), recipient-reassignment-prohibited(26),
+ redirection-loop-detected(27), dl-expansion-prohibited(28),
+ no-dl-submit-permission(29), dl-expansion-failure(30),
+ physical-rendition-attributes-not-supported(31),
+ undeliverable-mail-physical-delivery-address-incorrect(32),
+ undeliverable-mail-physical-delivery-office-incorrect-or-invalid(33),
+ undeliverable-mail-physical-delivery-address-incomplete(34),
+ undeliverable-mail-recipient-unknown(35),
+ undeliverable-mail-recipient-deceased(36),
+ undeliverable-mail-organization-expired(37),
+ undeliverable-mail-recipient-refused-to-accept(38),
+ undeliverable-mail-recipient-did-not-claim(39),
+ undeliverable-mail-recipient-changed-address-permanently(40),
+ undeliverable-mail-recipient-changed-address-temporarily(41),
+ undeliverable-mail-recipient-changed-temporary-address(42),
+ undeliverable-mail-new-address-unknown(43),
+ undeliverable-mail-recipient-did-not-want-forwarding(44),
+ undeliverable-mail-originator-prohibited-forwarding(45),
+ secure-messaging-error(46), unable-to-downgrade(47),
+ unable-to-complete-transfer(48), transfer-attempts-limit-reached(49),
+ incorrect-notification-type(50),
+ dl-expansion-prohibited-by-security-policy(51),
+ forbidden-alternate-recipient(52), security-policy-violation(53),
+ security-services-refusal(54), unauthorised-dl-member(55),
+ unauthorised-dl-name(56),
+ unauthorised-originally-intended-recipient-name(57),
+ unauthorised-originator-name(58), unauthorised-recipient-name(59),
+ unreliable-system(60), authentication-failure-on-subject-message(61),
+ decryption-failed(62), decryption-key-unobtainable(63),
+ double-envelope-creation-failure(64),
+ double-enveloping-message-restoring-failure(65),
+ failure-of-proof-of-message(66), integrity-failure-on-subject-message(67),
+ invalid-security-label(68), key-failure(69), mandatory-parameter-absence(70),
+ operation-security-failure(71), repudiation-failure-of-message(72),
+ security-context-failure(73), token-decryption-failed(74), token-error(75),
+ unknown-security-label(76), unsupported-algorithm-identifier(77),
+ unsupported-security-policy(78)}(0..ub-diagnostic-codes)
+
+SupplementaryInformation ::=
+ PrintableString(SIZE (1..ub-supplementary-info-length))
+
+-- Extension Fields
+EXTENSION ::= CLASS {
+ &id ExtensionType UNIQUE,
+ &Type OPTIONAL,
+ &absent &Type OPTIONAL,
+ &recommended Criticality DEFAULT {}
+}
+WITH SYNTAX {
+ [&Type
+ [IF ABSENT &absent],]
+ [RECOMMENDED CRITICALITY &recommended,]
+ IDENTIFIED BY &id
+}
+
+ExtensionType ::= CHOICE {
+ standard-extension [0] INTEGER(0..ub-extension-types),
+ private-extension [3] OBJECT IDENTIFIER
+}
+
+Criticality ::= BIT STRING {for-submission(0), for-transfer(1), for-delivery(2)
+}(SIZE (0..ub-bit-options)) -- critical 'one', non-critical 'zero'
+
+
+ExtensionField{EXTENSION:ChosenFrom} ::= SEQUENCE {
+ type EXTENSION.&id({ChosenFrom}),
+ criticality [1] Criticality DEFAULT {},
+ value [2] EXTENSION.&Type({ChosenFrom}{@type}) DEFAULT NULL:NULL
+}
+
+PrivateExtensions EXTENSION ::=
+ {-- Any value shall be relayed and delivered if not Critical (see Table 27)
+ -- except those values whose semantics the MTA obeys which are defined to be removed when obeyed.
+ -- Shall be IDENTIFIED BY ExtensionType.private-extension --...}
+
+recipient-reassignment-prohibited EXTENSION ::= {
+ RecipientReassignmentProhibited
+ IF ABSENT recipient-reassignment-allowed,
+ RECOMMENDED CRITICALITY {for-delivery},
+ IDENTIFIED BY standard-extension:1
+}
+
+RecipientReassignmentProhibited ::= ENUMERATED {
+ recipient-reassignment-allowed(0), recipient-reassignment-prohibited(1)
+}
+
+originator-requested-alternate-recipient EXTENSION ::= {
+ OriginatorRequestedAlternateRecipient,
+ RECOMMENDED CRITICALITY {for-submission},
+ IDENTIFIED BY standard-extension:2
+}
+
+OriginatorRequestedAlternateRecipient ::= ORAddressAndOrDirectoryName
+
+-- OriginatorRequestedAlternateRecipient as defined here differs from the field of the same name
+-- defined in Figure 4, since on submission the OR-address need not be present, but on
+-- transfer the OR-address must be present.
+dl-expansion-prohibited EXTENSION ::= {
+ DLExpansionProhibited
+ IF ABSENT dl-expansion-allowed,
+ RECOMMENDED CRITICALITY {for-delivery},
+ IDENTIFIED BY standard-extension:3
+}
+
+DLExpansionProhibited ::= ENUMERATED {
+ dl-expansion-allowed(0), dl-expansion-prohibited(1)}
+
+conversion-with-loss-prohibited EXTENSION ::= {
+ ConversionWithLossProhibited
+ IF ABSENT conversion-with-loss-allowed,
+ RECOMMENDED CRITICALITY {for-delivery},
+ IDENTIFIED BY standard-extension:4
+}
+
+ConversionWithLossProhibited ::= ENUMERATED {
+ conversion-with-loss-allowed(0), conversion-with-loss-prohibited(1)
+}
+
+latest-delivery-time EXTENSION ::= {
+ LatestDeliveryTime,
+ RECOMMENDED CRITICALITY {for-delivery},
+ IDENTIFIED BY standard-extension:5
+}
+
+LatestDeliveryTime ::= Time
+
+requested-delivery-method EXTENSION ::= {
+ RequestedDeliveryMethod
+ IF ABSENT {any-delivery-method},
+ IDENTIFIED BY standard-extension:6
+}
+
+RequestedDeliveryMethod ::=
+ SEQUENCE OF INTEGER { -- each different in order of preference,
+ -- most preferred first
+ any-delivery-method(0), mhs-delivery(1), physical-delivery(2),
+ telex-delivery(3), teletex-delivery(4), g3-facsimile-delivery(5),
+ g4-facsimile-delivery(6), ia5-terminal-delivery(7), videotex-delivery(8),
+ telephone-delivery(9)}(0..ub-integer-options)
+
+physical-forwarding-prohibited EXTENSION ::= {
+ PhysicalForwardingProhibited
+ IF ABSENT physical-forwarding-allowed,
+ RECOMMENDED CRITICALITY {for-delivery},
+ IDENTIFIED BY standard-extension:7
+}
+
+PhysicalForwardingProhibited ::= ENUMERATED {
+ physical-forwarding-allowed(0), physical-forwarding-prohibited(1)}
+
+physical-forwarding-address-request EXTENSION ::= {
+ PhysicalForwardingAddressRequest
+ IF ABSENT physical-forwarding-address-not-requested,
+ RECOMMENDED CRITICALITY {for-delivery},
+ IDENTIFIED BY standard-extension:8
+}
+
+PhysicalForwardingAddressRequest ::= ENUMERATED {
+ physical-forwarding-address-not-requested(0),
+ physical-forwarding-address-requested(1)}
+
+physical-delivery-modes EXTENSION ::= {
+ PhysicalDeliveryModes
+ IF ABSENT {ordinary-mail},
+ RECOMMENDED CRITICALITY {for-delivery},
+ IDENTIFIED BY standard-extension:9
+}
+
+PhysicalDeliveryModes ::= BIT STRING {
+ ordinary-mail(0), special-delivery(1), express-mail(2),
+ counter-collection(3), counter-collection-with-telephone-advice(4),
+ counter-collection-with-telex-advice(5),
+ counter-collection-with-teletex-advice(6), bureau-fax-delivery(7)
+
+-- bits 0 to 6 are mutually exclusive
+-- bit 7 can be set independently of any of bits 0 to 6 --}
+(SIZE (0..ub-bit-options))
+
+registered-mail-type EXTENSION ::= {
+ RegisteredMailType
+ IF ABSENT non-registered-mail,
+ RECOMMENDED CRITICALITY {for-delivery},
+ IDENTIFIED BY standard-extension:10
+}
+
+RegisteredMailType ::= INTEGER {
+ non-registered-mail(0), registered-mail(1),
+ registered-mail-to-addressee-in-person(2)}(0..ub-integer-options)
+
+recipient-number-for-advice EXTENSION ::= {
+ RecipientNumberForAdvice,
+ RECOMMENDED CRITICALITY {for-delivery},
+ IDENTIFIED BY standard-extension:11
+}
+
+RecipientNumberForAdvice ::=
+ TeletexString(SIZE (1..ub-recipient-number-for-advice-length))
+
+physical-rendition-attributes EXTENSION ::= {
+ PhysicalRenditionAttributes
+ IF ABSENT id-att-physicalRendition-basic,
+ RECOMMENDED CRITICALITY {for-delivery},
+ IDENTIFIED BY standard-extension:12
+}
+
+PhysicalRenditionAttributes ::= OBJECT IDENTIFIER
+
+originator-return-address EXTENSION ::= {
+ OriginatorReturnAddress,
+ IDENTIFIED BY standard-extension:13
+}
+
+OriginatorReturnAddress ::= ORAddress
+
+physical-delivery-report-request EXTENSION ::= {
+ PhysicalDeliveryReportRequest
+ IF ABSENT return-of-undeliverable-mail-by-PDS,
+ RECOMMENDED CRITICALITY {for-delivery},
+ IDENTIFIED BY standard-extension:14
+}
+
+PhysicalDeliveryReportRequest ::= INTEGER {
+ return-of-undeliverable-mail-by-PDS(0), return-of-notification-by-PDS(1),
+ return-of-notification-by-MHS(2), return-of-notification-by-MHS-and-PDS(3)
+}(0..ub-integer-options)
+
+originator-certificate EXTENSION ::= {
+ OriginatorCertificate,
+ IDENTIFIED BY standard-extension:15
+}
+
+OriginatorCertificate ::= Certificates
+
+message-token EXTENSION ::= {
+ MessageToken,
+ RECOMMENDED CRITICALITY {for-delivery},
+ IDENTIFIED BY standard-extension:16
+}
+
+MessageToken ::= Token
+
+content-confidentiality-algorithm-identifier EXTENSION ::= {
+ ContentConfidentialityAlgorithmIdentifier,
+ RECOMMENDED CRITICALITY {for-delivery},
+ IDENTIFIED BY standard-extension:17
+}
+
+ContentConfidentialityAlgorithmIdentifier ::= AlgorithmIdentifier
+
+content-integrity-check EXTENSION ::= {
+ ContentIntegrityCheck,
+ RECOMMENDED CRITICALITY {for-delivery},
+ IDENTIFIED BY standard-extension:18
+}
+
+ContentIntegrityCheck ::=
+ SIGNATURE
+ {SEQUENCE {algorithm-identifier
+ ContentIntegrityAlgorithmIdentifier OPTIONAL,
+ content Content}}
+
+ContentIntegrityAlgorithmIdentifier ::= AlgorithmIdentifier
+
+message-origin-authentication-check EXTENSION ::= {
+ MessageOriginAuthenticationCheck,
+ RECOMMENDED CRITICALITY {for-delivery},
+ IDENTIFIED BY standard-extension:19
+}
+
+MessageOriginAuthenticationCheck ::=
+ SIGNATURE
+ {SEQUENCE {algorithm-identifier
+ MessageOriginAuthenticationAlgorithmIdentifier,
+ content Content,
+ content-identifier ContentIdentifier OPTIONAL,
+ message-security-label MessageSecurityLabel OPTIONAL}}
+
+MessageOriginAuthenticationAlgorithmIdentifier ::= AlgorithmIdentifier
+
+message-security-label EXTENSION ::= {
+ MessageSecurityLabel,
+ RECOMMENDED CRITICALITY {for-delivery},
+ IDENTIFIED BY standard-extension:20
+}
+
+MessageSecurityLabel ::= SecurityLabel
+
+proof-of-submission-request EXTENSION ::= {
+ ProofOfSubmissionRequest
+ IF ABSENT proof-of-submission-not-requested,
+ RECOMMENDED CRITICALITY {for-submission},
+ IDENTIFIED BY standard-extension:21
+}
+
+ProofOfSubmissionRequest ::= ENUMERATED {
+ proof-of-submission-not-requested(0), proof-of-submission-requested(1)
+}
+
+proof-of-delivery-request EXTENSION ::= {
+ ProofOfDeliveryRequest
+ IF ABSENT proof-of-delivery-not-requested,
+ RECOMMENDED CRITICALITY {for-delivery},
+ IDENTIFIED BY standard-extension:22
+}
+
+ProofOfDeliveryRequest ::= ENUMERATED {
+ proof-of-delivery-not-requested(0), proof-of-delivery-requested(1)}
+
+content-correlator EXTENSION ::= {
+ ContentCorrelator,
+ IDENTIFIED BY standard-extension:23
+}
+
+ContentCorrelator ::= CHOICE {ia5text IA5String,
+ octets OCTET STRING
+}
+
+probe-origin-authentication-check EXTENSION ::= {
+ ProbeOriginAuthenticationCheck,
+ RECOMMENDED CRITICALITY {for-delivery},
+ IDENTIFIED BY standard-extension:24
+}
+
+ProbeOriginAuthenticationCheck ::=
+ SIGNATURE
+ {SEQUENCE {algorithm-identifier
+ ProbeOriginAuthenticationAlgorithmIdentifier,
+ content-identifier ContentIdentifier OPTIONAL,
+ message-security-label MessageSecurityLabel OPTIONAL}}
+
+ProbeOriginAuthenticationAlgorithmIdentifier ::= AlgorithmIdentifier
+
+redirection-history EXTENSION ::= {
+ RedirectionHistory,
+ IDENTIFIED BY standard-extension:25
+}
+
+RedirectionHistory ::= SEQUENCE SIZE (1..ub-redirections) OF Redirection
+
+Redirection ::= SEQUENCE {
+ intended-recipient-name IntendedRecipientName,
+ redirection-reason RedirectionReason
+}
+
+IntendedRecipientName ::= SEQUENCE {
+ intended-recipient ORAddressAndOptionalDirectoryName,
+ redirection-time Time
+}
+
+RedirectionReason ::= ENUMERATED {
+ recipient-assigned-alternate-recipient(0),
+ originator-requested-alternate-recipient(1),
+ recipient-MD-assigned-alternate-recipient(2),
+ -- The following values may not be supported by implementations of earlier versions of this Service Definition
+ directory-look-up(3), alias(4), ...
+ }
+
+dl-expansion-history EXTENSION ::= {
+ DLExpansionHistory,
+ IDENTIFIED BY standard-extension:26
+}
+
+DLExpansionHistory ::= SEQUENCE SIZE (1..ub-dl-expansions) OF DLExpansion
+
+DLExpansion ::= SEQUENCE {
+ dl ORAddressAndOptionalDirectoryName,
+ dl-expansion-time Time
+}
+
+physical-forwarding-address EXTENSION ::= {
+ PhysicalForwardingAddress,
+ IDENTIFIED BY standard-extension:27
+}
+
+PhysicalForwardingAddress ::= ORAddressAndOptionalDirectoryName
+
+recipient-certificate EXTENSION ::= {
+ RecipientCertificate,
+ IDENTIFIED BY standard-extension:28
+}
+
+proof-of-delivery EXTENSION ::= {
+ ProofOfDelivery,
+ IDENTIFIED BY standard-extension:29
+}
+
+originator-and-DL-expansion-history EXTENSION ::= {
+ OriginatorAndDLExpansionHistory,
+ IDENTIFIED BY standard-extension:30
+}
+
+OriginatorAndDLExpansionHistory ::=
+ SEQUENCE SIZE (2..ub-orig-and-dl-expansions) OF OriginatorAndDLExpansion
+
+OriginatorAndDLExpansion ::= SEQUENCE {
+ originator-or-dl-name ORAddressAndOptionalDirectoryName,
+ origination-or-expansion-time Time
+}
+
+reporting-DL-name EXTENSION ::= {
+ ReportingDLName,
+ IDENTIFIED BY standard-extension:31
+}
+
+ReportingDLName ::= ORAddressAndOptionalDirectoryName
+
+reporting-MTA-certificate EXTENSION ::= {
+ ReportingMTACertificate,
+ RECOMMENDED CRITICALITY {for-delivery},
+ IDENTIFIED BY standard-extension:32
+}
+
+ReportingMTACertificate ::= Certificates
+
+report-origin-authentication-check EXTENSION ::= {
+ ReportOriginAuthenticationCheck,
+ RECOMMENDED CRITICALITY {for-delivery},
+ IDENTIFIED BY standard-extension:33
+}
+
+ReportOriginAuthenticationCheck ::=
+ SIGNATURE
+ {SEQUENCE {algorithm-identifier
+ ReportOriginAuthenticationAlgorithmIdentifier,
+ content-identifier ContentIdentifier OPTIONAL,
+ message-security-label MessageSecurityLabel OPTIONAL,
+ per-recipient
+ SEQUENCE SIZE (1..ub-recipients) OF PerRecipientReportFields
+ }}
+
+ReportOriginAuthenticationAlgorithmIdentifier ::= AlgorithmIdentifier
+
+PerRecipientReportFields ::= SEQUENCE {
+ actual-recipient-name ActualRecipientName,
+ originally-intended-recipient-name OriginallyIntendedRecipientName OPTIONAL,
+ report-type
+ CHOICE {delivery [0] PerRecipientDeliveryReportFields,
+ non-delivery [1] PerRecipientNonDeliveryReportFields}
+}
+
+PerRecipientDeliveryReportFields ::= SEQUENCE {
+ message-delivery-time MessageDeliveryTime,
+ type-of-MTS-user TypeOfMTSUser,
+ recipient-certificate [0] RecipientCertificate OPTIONAL,
+ proof-of-delivery [1] ProofOfDelivery OPTIONAL
+}
+
+PerRecipientNonDeliveryReportFields ::= SEQUENCE {
+ non-delivery-reason-code NonDeliveryReasonCode,
+ non-delivery-diagnostic-code NonDeliveryDiagnosticCode OPTIONAL
+}
+
+originating-MTA-certificate EXTENSION ::= {
+ OriginatingMTACertificate,
+ IDENTIFIED BY standard-extension:34
+}
+
+OriginatingMTACertificate ::= Certificates
+
+proof-of-submission EXTENSION ::= {
+ ProofOfSubmission,
+ IDENTIFIED BY standard-extension:35
+}
+
+ProofOfSubmission ::=
+ SIGNATURE
+ {SEQUENCE {algorithm-identifier
+ ProofOfSubmissionAlgorithmIdentifier,
+ message-submission-envelope MessageSubmissionEnvelope,
+ content Content,
+ message-submission-identifier MessageSubmissionIdentifier,
+ message-submission-time MessageSubmissionTime}}
+
+ProofOfSubmissionAlgorithmIdentifier ::= AlgorithmIdentifier
+
+reporting-MTA-name EXTENSION ::= {
+ ReportingMTAName,
+ IDENTIFIED BY standard-extension:39
+}
+
+ReportingMTAName ::= SEQUENCE {
+ domain GlobalDomainIdentifier,
+ mta-name MTAName,
+ mta-directory-name [0] Name OPTIONAL
+}
+
+multiple-originator-certificates EXTENSION ::= {
+ ExtendedCertificates,
+ IDENTIFIED BY standard-extension:40
+}
+
+ExtendedCertificates ::= SET SIZE (1..ub-certificates) OF ExtendedCertificate
+
+ExtendedCertificate ::= CHOICE {
+ directory-entry [0] Name, -- Name of a Directory entry where the certificate can be found
+ certificate [1] Certificates
+}
+
+dl-exempted-recipients EXTENSION ::= {
+ DLExemptedRecipients,
+ IDENTIFIED BY standard-extension:42
+}
+
+DLExemptedRecipients ::= SET OF ORAddressAndOrDirectoryName
+
+certificate-selectors EXTENSION ::= {
+ CertificateSelectors,
+ IDENTIFIED BY standard-extension:45
+}
+
+CertificateSelectors ::= SET {
+ encryption-recipient [0] CertificateAssertion OPTIONAL,
+ encryption-originator [1] CertificateAssertion OPTIONAL,
+ content-integrity-check [2] CertificateAssertion OPTIONAL,
+ token-signature [3] CertificateAssertion OPTIONAL,
+ message-origin-authentication [4] CertificateAssertion OPTIONAL
+}
+
+certificate-selectors-override EXTENSION ::= {
+ CertificateSelectors
+ (WITH COMPONENTS {
+ ...,
+ message-origin-authentication ABSENT
+ }),
+ IDENTIFIED BY standard-extension:46
+}
+
+-- Some standard-extensions are defined elsewhere:
+-- 36 (forwarding-request) in ITU-T Rec. X.413 | ISO/IEC 10021-5;
+-- 37 (trace-information), and 38 (internal-trace-information) in Figure 4;
+-- 41 (blind-copy-recipients), 43 (body-part-encryption-token), and 44 (forwarded-content-token) in
+-- ITU-T Rec. X.420 | ISO/IEC 10021-7
+-- Common Parameter Types
+Content ::=
+ OCTET
+ STRING -- when the content-type has the integer value external, the value of the
+
+-- content octet string is the ASN.1 encoding of the external-content;
+-- an external-content is a data type EXTERNAL
+MTSIdentifier ::= [APPLICATION 4] SEQUENCE {
+ global-domain-identifier GlobalDomainIdentifier,
+ local-identifier LocalIdentifier
+}
+
+LocalIdentifier ::= IA5String(SIZE (1..ub-local-id-length))
+
+GlobalDomainIdentifier ::= [APPLICATION 3] SEQUENCE {
+ country-name CountryName,
+ administration-domain-name AdministrationDomainName,
+ private-domain-identifier PrivateDomainIdentifier OPTIONAL
+}
+
+PrivateDomainIdentifier ::= CHOICE {
+ numeric NumericString(SIZE (1..ub-domain-name-length)),
+ printable PrintableString(SIZE (1..ub-domain-name-length))
+}
+
+MTAName ::= IA5String(SIZE (1..ub-mta-name-length))
+
+Time ::= UTCTime
+
+-- OR Names
+ORAddressAndOrDirectoryName ::= ORName
+
+ORAddressAndOptionalDirectoryName ::= ORName
+
+ORName ::= [APPLICATION 0] SEQUENCE {
+ -- address --COMPONENTS OF ORAddress,
+ directory-name [0] Name OPTIONAL
+}
+
+ORAddress ::= SEQUENCE {
+ built-in-standard-attributes BuiltInStandardAttributes,
+ built-in-domain-defined-attributes BuiltInDomainDefinedAttributes OPTIONAL,
+ -- see also teletex-domain-defined-attributes
+ extension-attributes ExtensionAttributes OPTIONAL
+}
+
+-- The OR-address is semantically absent from the OR-name if the built-in-standard-attribute
+-- sequence is empty and the built-in-domain-defined-attributes and extension-attributes are both omitted.
+-- Built-in Standard Attributes
+BuiltInStandardAttributes ::= SEQUENCE {
+ country-name CountryName OPTIONAL,
+ administration-domain-name AdministrationDomainName OPTIONAL,
+ network-address [0] NetworkAddress OPTIONAL,
+ -- see also extended-network-address
+ terminal-identifier [1] TerminalIdentifier OPTIONAL,
+ private-domain-name [2] PrivateDomainName OPTIONAL,
+ organization-name [3] OrganizationName OPTIONAL,
+ -- see also teletex-organization-name
+ numeric-user-identifier [4] NumericUserIdentifier OPTIONAL,
+ personal-name [5] PersonalName OPTIONAL,
+ -- see also teletex-personal-name
+ organizational-unit-names [6] OrganizationalUnitNames OPTIONAL
+ -- see also teletex-organizational-unit-names
+}
+
+CountryName ::= [APPLICATION 1] CHOICE {
+ x121-dcc-code NumericString(SIZE (ub-country-name-numeric-length)),
+ iso-3166-alpha2-code PrintableString(SIZE (ub-country-name-alpha-length))
+}
+
+AdministrationDomainName ::= [APPLICATION 2] CHOICE {
+ numeric NumericString(SIZE (0..ub-domain-name-length)),
+ printable PrintableString(SIZE (0..ub-domain-name-length))
+}
+
+NetworkAddress ::= X121Address
+
+-- see also extended-network-address
+X121Address ::= NumericString(SIZE (1..ub-x121-address-length))
+
+TerminalIdentifier ::= PrintableString(SIZE (1..ub-terminal-id-length))
+
+PrivateDomainName ::= CHOICE {
+ numeric NumericString(SIZE (1..ub-domain-name-length)),
+ printable PrintableString(SIZE (1..ub-domain-name-length))
+}
+
+OrganizationName ::= PrintableString(SIZE (1..ub-organization-name-length))
+
+-- see also teletex-organization-name
+NumericUserIdentifier ::= NumericString(SIZE (1..ub-numeric-user-id-length))
+
+PersonalName ::= SET {
+ surname [0] PrintableString(SIZE (1..ub-surname-length)),
+ given-name
+ [1] PrintableString(SIZE (1..ub-given-name-length)) OPTIONAL,
+ initials
+ [2] PrintableString(SIZE (1..ub-initials-length)) OPTIONAL,
+ generation-qualifier
+ [3] PrintableString(SIZE (1..ub-generation-qualifier-length)) OPTIONAL
+}
+
+-- see also teletex-personal-name
+OrganizationalUnitNames ::=
+ SEQUENCE SIZE (1..ub-organizational-units) OF OrganizationalUnitName
+
+-- see also teletex-organizational-unit-names
+OrganizationalUnitName ::=
+ PrintableString(SIZE (1..ub-organizational-unit-name-length))
+
+-- Built-in Domain-defined Attributes
+BuiltInDomainDefinedAttributes ::=
+ SEQUENCE SIZE (1..ub-domain-defined-attributes) OF
+ BuiltInDomainDefinedAttribute
+
+BuiltInDomainDefinedAttribute ::= SEQUENCE {
+ type PrintableString(SIZE (1..ub-domain-defined-attribute-type-length)),
+ value PrintableString(SIZE (1..ub-domain-defined-attribute-value-length))
+}
+
+-- Extension Attributes
+ExtensionAttributes ::=
+ SET SIZE (1..ub-extension-attributes) OF ExtensionAttribute
+
+ExtensionAttribute ::= SEQUENCE {
+ extension-attribute-type
+ [0] EXTENSION-ATTRIBUTE.&id({ExtensionAttributeTable}),
+ extension-attribute-value
+ [1] EXTENSION-ATTRIBUTE.&Type
+ ({ExtensionAttributeTable}{@extension-attribute-type})
+}
+
+EXTENSION-ATTRIBUTE ::= CLASS {
+ &id INTEGER(0..ub-extension-attributes) UNIQUE,
+ &Type
+}WITH SYNTAX {&Type
+ IDENTIFIED BY &id
+}
+
+ExtensionAttributeTable EXTENSION-ATTRIBUTE ::=
+ {common-name | teletex-common-name | universal-common-name |
+ teletex-organization-name | universal-organization-name |
+ teletex-personal-name | universal-personal-name |
+ teletex-organizational-unit-names | universal-organizational-unit-names |
+ teletex-domain-defined-attributes | universal-domain-defined-attributes |
+ pds-name | physical-delivery-country-name | postal-code |
+ physical-delivery-office-name | universal-physical-delivery-office-name |
+ physical-delivery-office-number | universal-physical-delivery-office-number
+ | extension-OR-address-components |
+ universal-extension-OR-address-components | physical-delivery-personal-name
+ | universal-physical-delivery-personal-name |
+ physical-delivery-organization-name |
+ universal-physical-delivery-organization-name |
+ extension-physical-delivery-address-components |
+ universal-extension-physical-delivery-address-components |
+ unformatted-postal-address | universal-unformatted-postal-address |
+ street-address | universal-street-address | post-office-box-address |
+ universal-post-office-box-address | poste-restante-address |
+ universal-poste-restante-address | unique-postal-name |
+ universal-unique-postal-name | local-postal-attributes |
+ universal-local-postal-attributes | extended-network-address | terminal-type
+ }
+
+-- Extension Standard Attributes
+common-name EXTENSION-ATTRIBUTE ::= {CommonName
+ IDENTIFIED BY 1
+}
+
+CommonName ::= PrintableString(SIZE (1..ub-common-name-length))
+
+teletex-common-name EXTENSION-ATTRIBUTE ::= {TeletexCommonName
+ IDENTIFIED BY 2
+}
+
+TeletexCommonName ::= TeletexString(SIZE (1..ub-common-name-length))
+
+universal-common-name EXTENSION-ATTRIBUTE ::= {
+ UniversalCommonName
+ IDENTIFIED BY 24
+}
+
+UniversalCommonName ::= UniversalOrBMPString{ub-common-name-length}
+
+teletex-organization-name EXTENSION-ATTRIBUTE ::= {
+ TeletexOrganizationName
+ IDENTIFIED BY 3
+}
+
+TeletexOrganizationName ::=
+ TeletexString(SIZE (1..ub-organization-name-length))
+
+universal-organization-name EXTENSION-ATTRIBUTE ::= {
+ UniversalOrganizationName
+ IDENTIFIED BY 25
+}
+
+UniversalOrganizationName ::= UniversalOrBMPString{ub-organization-name-length}
+
+teletex-personal-name EXTENSION-ATTRIBUTE ::= {
+ TeletexPersonalName
+ IDENTIFIED BY 4
+}
+
+TeletexPersonalName ::= SET {
+ surname [0] TeletexString(SIZE (1..ub-surname-length)),
+ given-name
+ [1] TeletexString(SIZE (1..ub-given-name-length)) OPTIONAL,
+ initials
+ [2] TeletexString(SIZE (1..ub-initials-length)) OPTIONAL,
+ generation-qualifier
+ [3] TeletexString(SIZE (1..ub-generation-qualifier-length)) OPTIONAL
+}
+
+universal-personal-name EXTENSION-ATTRIBUTE ::= {
+ UniversalPersonalName
+ IDENTIFIED BY 26
+}
+
+UniversalPersonalName ::= SET {
+ surname [0] UniversalOrBMPString{ub-universal-surname-length},
+ -- If a language is specified within surname, then that language applies to each of the following
+ -- optional components unless the component specifies another language.
+ given-name
+ [1] UniversalOrBMPString{ub-universal-given-name-length} OPTIONAL,
+ initials
+ [2] UniversalOrBMPString{ub-universal-initials-length} OPTIONAL,
+ generation-qualifier
+ [3] UniversalOrBMPString{ub-universal-generation-qualifier-length}
+ OPTIONAL
+}
+
+teletex-organizational-unit-names EXTENSION-ATTRIBUTE ::= {
+ TeletexOrganizationalUnitNames
+ IDENTIFIED BY 5
+}
+
+TeletexOrganizationalUnitNames ::=
+ SEQUENCE SIZE (1..ub-organizational-units) OF TeletexOrganizationalUnitName
+
+TeletexOrganizationalUnitName ::=
+ TeletexString(SIZE (1..ub-organizational-unit-name-length))
+
+universal-organizational-unit-names EXTENSION-ATTRIBUTE ::= {
+ UniversalOrganizationalUnitNames
+ IDENTIFIED BY 27
+}
+
+UniversalOrganizationalUnitNames ::=
+ SEQUENCE SIZE (1..ub-organizational-units) OF UniversalOrganizationalUnitName
+
+-- If a unit name specifies a language, then that language applies to subordinate unit names unless
+-- the subordinate specifies another language.
+UniversalOrganizationalUnitName ::=
+ UniversalOrBMPString{ub-organizational-unit-name-length}
+
+UniversalOrBMPString{INTEGER:ub-string-length} ::= SET {
+ character-encoding
+ CHOICE {two-octets BMPString(SIZE (1..ub-string-length)),
+ four-octets UniversalString(SIZE (1..ub-string-length))},
+ iso-639-language-code PrintableString(SIZE (2 | 5)) OPTIONAL
+}
+
+pds-name EXTENSION-ATTRIBUTE ::= {PDSName
+ IDENTIFIED BY 7
+}
+
+PDSName ::= PrintableString(SIZE (1..ub-pds-name-length))
+
+physical-delivery-country-name EXTENSION-ATTRIBUTE ::= {
+ PhysicalDeliveryCountryName
+ IDENTIFIED BY 8
+}
+
+PhysicalDeliveryCountryName ::= CHOICE {
+ x121-dcc-code NumericString(SIZE (ub-country-name-numeric-length)),
+ iso-3166-alpha2-code PrintableString(SIZE (ub-country-name-alpha-length))
+}
+
+postal-code EXTENSION-ATTRIBUTE ::= {PostalCode
+ IDENTIFIED BY 9
+}
+
+PostalCode ::= CHOICE {
+ numeric-code NumericString(SIZE (1..ub-postal-code-length)),
+ printable-code PrintableString(SIZE (1..ub-postal-code-length))
+}
+
+physical-delivery-office-name EXTENSION-ATTRIBUTE ::= {
+ PhysicalDeliveryOfficeName
+ IDENTIFIED BY 10
+}
+
+PhysicalDeliveryOfficeName ::= PDSParameter
+
+universal-physical-delivery-office-name EXTENSION-ATTRIBUTE ::= {
+ UniversalPhysicalDeliveryOfficeName
+ IDENTIFIED BY 29
+}
+
+UniversalPhysicalDeliveryOfficeName ::= UniversalPDSParameter
+
+physical-delivery-office-number EXTENSION-ATTRIBUTE ::= {
+ PhysicalDeliveryOfficeNumber
+ IDENTIFIED BY 11
+}
+
+PhysicalDeliveryOfficeNumber ::= PDSParameter
+
+universal-physical-delivery-office-number EXTENSION-ATTRIBUTE ::= {
+ UniversalPhysicalDeliveryOfficeNumber
+ IDENTIFIED BY 30
+}
+
+UniversalPhysicalDeliveryOfficeNumber ::= UniversalPDSParameter
+
+extension-OR-address-components EXTENSION-ATTRIBUTE ::= {
+ ExtensionORAddressComponents
+ IDENTIFIED BY 12
+}
+
+ExtensionORAddressComponents ::= PDSParameter
+
+universal-extension-OR-address-components EXTENSION-ATTRIBUTE ::= {
+ UniversalExtensionORAddressComponents
+ IDENTIFIED BY 31
+}
+
+UniversalExtensionORAddressComponents ::= UniversalPDSParameter
+
+physical-delivery-personal-name EXTENSION-ATTRIBUTE ::= {
+ PhysicalDeliveryPersonalName
+ IDENTIFIED BY 13
+}
+
+PhysicalDeliveryPersonalName ::= PDSParameter
+
+universal-physical-delivery-personal-name EXTENSION-ATTRIBUTE ::= {
+ UniversalPhysicalDeliveryPersonalName
+ IDENTIFIED BY 32
+}
+
+UniversalPhysicalDeliveryPersonalName ::= UniversalPDSParameter
+
+physical-delivery-organization-name EXTENSION-ATTRIBUTE ::= {
+ PhysicalDeliveryOrganizationName
+ IDENTIFIED BY 14
+}
+
+PhysicalDeliveryOrganizationName ::= PDSParameter
+
+universal-physical-delivery-organization-name EXTENSION-ATTRIBUTE ::=
+{UniversalPhysicalDeliveryOrganizationName
+ IDENTIFIED BY 33
+}
+
+UniversalPhysicalDeliveryOrganizationName ::= UniversalPDSParameter
+
+extension-physical-delivery-address-components EXTENSION-ATTRIBUTE ::=
+{ExtensionPhysicalDeliveryAddressComponents
+ IDENTIFIED BY 15
+}
+
+ExtensionPhysicalDeliveryAddressComponents ::= PDSParameter
+
+universal-extension-physical-delivery-address-components EXTENSION-ATTRIBUTE
+ ::= {UniversalExtensionPhysicalDeliveryAddressComponents
+ IDENTIFIED BY 34
+}
+
+UniversalExtensionPhysicalDeliveryAddressComponents ::= UniversalPDSParameter
+
+unformatted-postal-address EXTENSION-ATTRIBUTE ::= {
+ UnformattedPostalAddress
+ IDENTIFIED BY 16
+}
+
+UnformattedPostalAddress ::= SET {
+ printable-address
+ SEQUENCE SIZE (1..ub-pds-physical-address-lines) OF
+ PrintableString(SIZE (1..ub-pds-parameter-length)) OPTIONAL,
+ teletex-string
+ TeletexString(SIZE (1..ub-unformatted-address-length)) OPTIONAL
+}
+
+universal-unformatted-postal-address EXTENSION-ATTRIBUTE ::= {
+ UniversalUnformattedPostalAddress
+ IDENTIFIED BY 35
+}
+
+UniversalUnformattedPostalAddress ::=
+ UniversalOrBMPString{ub-unformatted-address-length}
+
+street-address EXTENSION-ATTRIBUTE ::= {StreetAddress
+ IDENTIFIED BY 17
+}
+
+StreetAddress ::= PDSParameter
+
+universal-street-address EXTENSION-ATTRIBUTE ::= {
+ UniversalStreetAddress
+ IDENTIFIED BY 36
+}
+
+UniversalStreetAddress ::= UniversalPDSParameter
+
+post-office-box-address EXTENSION-ATTRIBUTE ::= {
+ PostOfficeBoxAddress
+ IDENTIFIED BY 18
+}
+
+PostOfficeBoxAddress ::= PDSParameter
+
+universal-post-office-box-address EXTENSION-ATTRIBUTE ::= {
+ UniversalPostOfficeBoxAddress
+ IDENTIFIED BY 37
+}
+
+UniversalPostOfficeBoxAddress ::= UniversalPDSParameter
+
+poste-restante-address EXTENSION-ATTRIBUTE ::= {
+ PosteRestanteAddress
+ IDENTIFIED BY 19
+}
+
+PosteRestanteAddress ::= PDSParameter
+
+universal-poste-restante-address EXTENSION-ATTRIBUTE ::= {
+ UniversalPosteRestanteAddress
+ IDENTIFIED BY 38
+}
+
+UniversalPosteRestanteAddress ::= UniversalPDSParameter
+
+unique-postal-name EXTENSION-ATTRIBUTE ::= {UniquePostalName
+ IDENTIFIED BY 20
+}
+
+UniquePostalName ::= PDSParameter
+
+universal-unique-postal-name EXTENSION-ATTRIBUTE ::= {
+ UniversalUniquePostalName
+ IDENTIFIED BY 39
+}
+
+UniversalUniquePostalName ::= UniversalPDSParameter
+
+local-postal-attributes EXTENSION-ATTRIBUTE ::= {
+ LocalPostalAttributes
+ IDENTIFIED BY 21
+}
+
+LocalPostalAttributes ::= PDSParameter
+
+universal-local-postal-attributes EXTENSION-ATTRIBUTE ::= {
+ UniversalLocalPostalAttributes
+ IDENTIFIED BY 40
+}
+
+UniversalLocalPostalAttributes ::= UniversalPDSParameter
+
+PDSParameter ::= SET {
+ printable-string PrintableString(SIZE (1..ub-pds-parameter-length)) OPTIONAL,
+ teletex-string TeletexString(SIZE (1..ub-pds-parameter-length)) OPTIONAL
+}
+
+UniversalPDSParameter ::= UniversalOrBMPString{ub-pds-parameter-length}
+
+extended-network-address EXTENSION-ATTRIBUTE ::= {
+ ExtendedNetworkAddress
+ IDENTIFIED BY 22
+}
+
+ExtendedNetworkAddress ::= CHOICE {
+ e163-4-address
+ SEQUENCE {number
+ [0] NumericString(SIZE (1..ub-e163-4-number-length)),
+ sub-address
+ [1] NumericString(SIZE (1..ub-e163-4-sub-address-length))
+ OPTIONAL},
+ psap-address [0] PresentationAddress
+}
+
+terminal-type EXTENSION-ATTRIBUTE ::= {TerminalType
+ IDENTIFIED BY 23
+}
+
+TerminalType ::= INTEGER {
+ telex(3), teletex(4), g3-facsimile(5), g4-facsimile(6), ia5-terminal(7),
+ videotex(8)}(0..ub-integer-options)
+
+-- Extension Domain-defined Attributes
+teletex-domain-defined-attributes EXTENSION-ATTRIBUTE ::= {
+ TeletexDomainDefinedAttributes
+ IDENTIFIED BY 6
+}
+
+TeletexDomainDefinedAttributes ::=
+ SEQUENCE SIZE (1..ub-domain-defined-attributes) OF
+ TeletexDomainDefinedAttribute
+
+TeletexDomainDefinedAttribute ::= SEQUENCE {
+ type TeletexString(SIZE (1..ub-domain-defined-attribute-type-length)),
+ value TeletexString(SIZE (1..ub-domain-defined-attribute-value-length))
+}
+
+universal-domain-defined-attributes EXTENSION-ATTRIBUTE ::= {
+ UniversalDomainDefinedAttributes
+ IDENTIFIED BY 28
+}
+
+UniversalDomainDefinedAttributes ::=
+ SEQUENCE SIZE (1..ub-domain-defined-attributes) OF
+ UniversalDomainDefinedAttribute
+
+UniversalDomainDefinedAttribute ::= SEQUENCE {
+ type UniversalOrBMPString{ub-domain-defined-attribute-type-length},
+ value UniversalOrBMPString{ub-domain-defined-attribute-value-length}
+}
+
+-- Encoded Information Types
+EncodedInformationTypes ::= [APPLICATION 5] SET {
+ built-in-encoded-information-types [0] BuiltInEncodedInformationTypes,
+ -- non-basic-parameters --COMPONENTS OF NonBasicParameters,
+ extended-encoded-information-types
+ [4] ExtendedEncodedInformationTypes OPTIONAL
+}
+
+-- Built-in Encoded Information Types
+BuiltInEncodedInformationTypes ::= BIT STRING {
+ unknown(0), ia5-text(2), g3-facsimile(3), g4-class-1(4), teletex(5),
+ videotex(6), voice(7), sfd(8), mixed-mode(9)
+}(SIZE (0..ub-built-in-encoded-information-types))
+
+-- Extended Encoded Information Types
+ExtendedEncodedInformationTypes ::=
+ SET SIZE (1..ub-encoded-information-types) OF ExtendedEncodedInformationType
+
+ExtendedEncodedInformationType ::= OBJECT IDENTIFIER
+
+-- Non-basic Parameters
+NonBasicParameters ::= SET {
+ g3-facsimile [1] G3FacsimileNonBasicParameters DEFAULT {},
+ teletex [2] TeletexNonBasicParameters DEFAULT {}
+}
+
+G3FacsimileNonBasicParameters ::= BIT STRING {
+ two-dimensional(8), -- As defined in ITU-T Recommendation T.30
+ fine-resolution(9), --
+ unlimited-length(20), -- These bit values are chosen such that when
+ b4-length(21), -- encoded using ASN.1 Basic Encoding Rules
+ a3-width(22), -- the resulting octets have the same values
+ b4-width(23), -- as for T.30 encoding
+ t6-coding(25), --
+ uncompressed(30), -- Trailing zero bits are not significant.
+ width-middle-864-of-1728(37), -- It is recommended that implementations
+ width-middle-1216-of-1728(38), -- should not encode more than 32 bits unless
+ resolution-type(44), -- higher numbered bits are non-zero.
+ resolution-400x400(45), resolution-300x300(46), resolution-8x15(47),
+ edi(49), dtm(50), bft(51), mixed-mode(58), character-mode(60),
+ twelve-bits(65), preferred-huffmann(66), full-colour(67), jpeg(68),
+ processable-mode-26(71)}
+
+TeletexNonBasicParameters ::= SET {
+ graphic-character-sets [0] TeletexString OPTIONAL,
+ control-character-sets [1] TeletexString OPTIONAL,
+ page-formats [2] OCTET STRING OPTIONAL,
+ miscellaneous-terminal-capabilities [3] TeletexString OPTIONAL,
+ private-use
+ [4] OCTET STRING
+ OPTIONAL -- maximum ub-teletex-private-use-length octets --
+}
+
+-- as defined in CCITT Recommendation T.62
+-- Token
+Token ::= SEQUENCE {
+ token-type-identifier [0] TOKEN.&id({TokensTable}),
+ token
+ [1] TOKEN.&Type({TokensTable}{@token-type-identifier})
+}
+
+TOKEN ::= TYPE-IDENTIFIER
+
+TokensTable TOKEN ::= {asymmetric-token, ...}
+
+asymmetric-token TOKEN ::= {
+ AsymmetricToken
+ IDENTIFIED BY id-tok-asymmetricToken
+}
+
+AsymmetricToken ::=
+ SIGNED
+ {SEQUENCE {signature-algorithm-identifier AlgorithmIdentifier,
+ name
+ CHOICE {recipient-name RecipientName,
+ mta
+ [3] SEQUENCE {global-domain-identifier
+ GlobalDomainIdentifier OPTIONAL,
+ mta-name MTAName
+ }},
+ time Time,
+ signed-data [0] TokenData OPTIONAL,
+ encryption-algorithm-identifier
+ [1] AlgorithmIdentifier OPTIONAL,
+ encrypted-data
+ [2] ENCRYPTED{TokenData} OPTIONAL}}
+
+TokenData ::= SEQUENCE {
+ type [0] TOKEN-DATA.&id({TokenDataTable}),
+ value [1] TOKEN-DATA.&Type({TokenDataTable}{@type})
+}
+
+TOKEN-DATA ::= CLASS {&id INTEGER UNIQUE,
+ &Type
+}WITH SYNTAX {&Type
+ IDENTIFIED BY &id
+}
+
+TokenDataTable TOKEN-DATA ::=
+ {bind-token-signed-data | message-token-signed-data |
+ message-token-encrypted-data | bind-token-encrypted-data, ...}
+
+bind-token-signed-data TOKEN-DATA ::= {BindTokenSignedData
+ IDENTIFIED BY 1
+}
+
+BindTokenSignedData ::= RandomNumber
+
+RandomNumber ::= BIT STRING
+
+message-token-signed-data TOKEN-DATA ::= {
+ MessageTokenSignedData
+ IDENTIFIED BY 2
+}
+
+MessageTokenSignedData ::= SEQUENCE {
+ content-confidentiality-algorithm-identifier
+ [0] ContentConfidentialityAlgorithmIdentifier OPTIONAL,
+ content-integrity-check
+ [1] ContentIntegrityCheck OPTIONAL,
+ message-security-label
+ [2] MessageSecurityLabel OPTIONAL,
+ proof-of-delivery-request
+ [3] ProofOfDeliveryRequest OPTIONAL,
+ message-sequence-number [4] INTEGER OPTIONAL
+}
+
+message-token-encrypted-data TOKEN-DATA ::= {
+ MessageTokenEncryptedData
+ IDENTIFIED BY 3
+}
+
+MessageTokenEncryptedData ::= SEQUENCE {
+ content-confidentiality-key [0] EncryptionKey OPTIONAL,
+ content-integrity-check [1] ContentIntegrityCheck OPTIONAL,
+ message-security-label [2] MessageSecurityLabel OPTIONAL,
+ content-integrity-key [3] EncryptionKey OPTIONAL,
+ message-sequence-number [4] INTEGER OPTIONAL
+}
+
+EncryptionKey ::= BIT STRING
+
+bind-token-encrypted-data TOKEN-DATA ::= {
+ BindTokenEncryptedData
+ IDENTIFIED BY 4
+}
+
+BindTokenEncryptedData ::= EXTERNAL
+
+-- Security Label
+SecurityLabel ::= SET {
+ security-policy-identifier SecurityPolicyIdentifier OPTIONAL,
+ security-classification SecurityClassification OPTIONAL,
+ privacy-mark PrivacyMark OPTIONAL,
+ security-categories SecurityCategories OPTIONAL
+}
+
+SecurityPolicyIdentifier ::= OBJECT IDENTIFIER
+
+SecurityClassification ::= INTEGER {
+ unmarked(0), unclassified(1), restricted(2), confidential(3), secret(4),
+ top-secret(5)}(0..ub-integer-options)
+
+PrivacyMark ::= PrintableString(SIZE (1..ub-privacy-mark-length))
+
+SecurityCategories ::= SET SIZE (1..ub-security-categories) OF SecurityCategory
+
+SecurityCategory ::= SEQUENCE {
+ type [0] SECURITY-CATEGORY.&id({SecurityCategoriesTable}),
+ value [1] SECURITY-CATEGORY.&Type({SecurityCategoriesTable}{@type})
+}
+
+SECURITY-CATEGORY ::= TYPE-IDENTIFIER
+
+SecurityCategoriesTable SECURITY-CATEGORY ::=
+ {...}
+
+END -- of MTSAbstractService
+
+-- Generated by Asnp, the ASN.1 pretty-printer of France Telecom R&D
+
diff --git a/lib/asn1/test/asn1_SUITE_data/modified_x420/MTSUpperBounds.asn b/lib/asn1/test/asn1_SUITE_data/modified_x420/MTSUpperBounds.asn
new file mode 100644
index 0000000000..10eac962cb
--- /dev/null
+++ b/lib/asn1/test/asn1_SUITE_data/modified_x420/MTSUpperBounds.asn
@@ -0,0 +1,146 @@
+-- Module MTSUpperBounds (X.411:06/1999)
+MTSUpperBounds {joint-iso-itu-t mhs(6) mts(3) modules(0) upper-bounds(3)
+ version-1999(1)} DEFINITIONS IMPLICIT TAGS ::=
+BEGIN
+
+-- Prologue
+-- Exports everything
+IMPORTS -- nothing -- ;
+
+-- Upper Bounds
+ub-additional-info INTEGER ::= 1024
+
+ub-bilateral-info INTEGER ::= 1024
+
+ub-bit-options INTEGER ::= 16
+
+ub-built-in-content-type INTEGER ::= 32767
+
+ub-built-in-encoded-information-types INTEGER ::= 32
+
+ub-certificates INTEGER ::= 64
+
+ub-common-name-length INTEGER ::= 64
+
+ub-content-correlator-length INTEGER ::= 512
+
+ub-content-id-length INTEGER ::= 16
+
+ub-content-length INTEGER ::= 2147483647 -- the largest integer in 32 bits
+
+ub-content-types INTEGER ::= 1024
+
+ub-country-name-alpha-length INTEGER ::= 2
+
+ub-country-name-numeric-length INTEGER ::= 3
+
+ub-diagnostic-codes INTEGER ::= 32767
+
+ub-deliverable-class INTEGER ::= 256
+
+ub-dl-expansions INTEGER ::= 512
+
+ub-domain-defined-attributes INTEGER ::= 4
+
+ub-domain-defined-attribute-type-length INTEGER ::= 8
+
+ub-domain-defined-attribute-value-length INTEGER ::= 128
+
+ub-domain-name-length INTEGER ::= 16
+
+ub-encoded-information-types INTEGER ::= 1024
+
+ub-extension-attributes INTEGER ::= 256
+
+ub-extension-types INTEGER ::= 256
+
+ub-e163-4-number-length INTEGER ::= 15
+
+ub-e163-4-sub-address-length INTEGER ::= 40
+
+ub-generation-qualifier-length INTEGER ::= 3
+
+ub-given-name-length INTEGER ::= 16
+
+ub-initials-length INTEGER ::= 5
+
+ub-integer-options INTEGER ::= 256
+
+ub-labels-and-redirections INTEGER ::= 256
+
+ub-local-id-length INTEGER ::= 32
+
+ub-mta-name-length INTEGER ::= 32
+
+ub-mts-user-types INTEGER ::= 256
+
+ub-numeric-user-id-length INTEGER ::= 32
+
+ub-organization-name-length INTEGER ::= 64
+
+ub-organizational-unit-name-length INTEGER ::= 32
+
+ub-organizational-units INTEGER ::= 4
+
+ub-orig-and-dl-expansions INTEGER ::= 513 -- ub-dl-expansions plus one
+
+ub-password-length INTEGER ::= 62
+
+ub-pds-name-length INTEGER ::= 16
+
+ub-pds-parameter-length INTEGER ::= 30
+
+ub-pds-physical-address-lines INTEGER ::= 6
+
+ub-postal-code-length INTEGER ::= 16
+
+ub-privacy-mark-length INTEGER ::= 128
+
+ub-queue-size INTEGER ::= 2147483647 -- the largest integer in 32 bits
+
+ub-reason-codes INTEGER ::= 32767
+
+ub-recipient-number-for-advice-length INTEGER ::= 32
+
+ub-recipients INTEGER ::= 32767
+
+ub-redirection-classes INTEGER ::= 256
+
+ub-redirections INTEGER ::= 512
+
+ub-restrictions INTEGER ::= 1024
+
+ub-security-categories INTEGER ::= 64
+
+ub-security-labels INTEGER ::= 256
+
+ub-security-problems INTEGER ::= 256
+
+ub-supplementary-info-length INTEGER ::= 256
+
+ub-surname-length INTEGER ::= 40
+
+ub-teletex-private-use-length INTEGER ::= 128
+
+ub-terminal-id-length INTEGER ::= 24
+
+ub-transfers INTEGER ::= 512
+
+ub-tsap-id-length INTEGER ::= 16
+
+ub-unformatted-address-length INTEGER ::= 180
+
+ub-universal-generation-qualifier-length INTEGER ::= 16
+
+ub-universal-given-name-length INTEGER ::= 40
+
+ub-universal-initials-length INTEGER ::= 16
+
+ub-universal-surname-length INTEGER ::= 64
+
+ub-x121-address-length INTEGER ::= 16
+
+END -- of MTSUpperBounds
+
+-- Generated by Asnp, the ASN.1 pretty-printer of France Telecom R&D
+
diff --git a/lib/asn1/test/asn1_SUITE_data/modified_x420/PKCS7.asn b/lib/asn1/test/asn1_SUITE_data/modified_x420/PKCS7.asn
new file mode 100644
index 0000000000..7a06661cc0
--- /dev/null
+++ b/lib/asn1/test/asn1_SUITE_data/modified_x420/PKCS7.asn
@@ -0,0 +1,343 @@
+-- Module PKCS7 (X.420:06/1999)
+-- The ASN.1 in version 1.5 of the PKCS#7 document is not defined in an ASN.1 module. This prevents an IMPORT of it into other ASN.1 modules.
+-- This Annex contains a module of PKCS#7 ASN.1 definitions conforming to current ASN.1 standards rather than the obsolescent (and now deprecated) 1988/90 version of ASN.1 used in version 1.5 of PKCS#7.
+-- Extensions to PKCS#7 defined in RFC 2630 are included.
+-- If differences are found between the ASN.1 in the following module and that in PKCS#7, the latter is definitive.
+PKCS7 {iso member-body usa(840) rsadsi(113549) pkcs(1) 7
+ module(0) -- module not currently defined in PKCS#7 --} DEFINITIONS IMPLICIT
+TAGS ::=
+BEGIN
+
+IMPORTS
+ -- Directory Information Framework
+ Attribute, Name
+ --==
+ FROM InformationFramework {joint-iso-itu-t ds(5) module(1)
+ informationFramework(1) 3}
+ -- Directory Authentication Framework
+ AlgorithmIdentifier, AttributeCertificate, Certificate, CertificateList,
+ CertificateSerialNumber, HASH{}, SIGNED{}
+ --==
+ FROM AuthenticationFramework {joint-iso-itu-t ds(5) module(1)
+ authenticationFramework(7) 3};
+
+-- In PKCS#7 the HASHED parameterised type applies the hash function to the
+-- contents octets component of a DER encoding of a value of the parameter.
+-- The ENCRYPTED parameterised type is redefined here because PKCS#7 encrypted values are
+-- defined as OCTET STRING, instead of BIT STRING as in the Directory Authentication Framework
+ENCRYPTED{ToBeEnciphered} ::=
+ OCTET STRING
+ (CONSTRAINED BY {
+ -- must be the result of applying an encipherment procedure to the contents octets component
+ -- of a definite-length BER-encoding of a value of --ToBeEnciphered})
+
+ContentInfo ::= SEQUENCE {
+ content-type PKCS7-CONTENT-TYPE.&id({PKCS7ContentTable}),
+-- pkcs7-content [0] PKCS7-CONTENT-TYPE.&Type({PKCS7ContentTable}) OPTIONAL
+ pkcs7-content [0] EXPLICIT ANY DEFINED BY contentType OPTIONAL
+}
+
+PKCS7-CONTENT-TYPE ::= TYPE-IDENTIFIER
+
+PKCS7ContentTable PKCS7-CONTENT-TYPE ::=
+ {data | signed-data | enveloped-data | signed-and-enveloped-data |
+ digested-data | encrypted-data | authenticated-data, ...}
+
+-- Data
+data PKCS7-CONTENT-TYPE ::= {Data
+ IDENTIFIED BY id-data
+}
+
+Data ::= OCTET STRING
+
+-- Signed Data
+signed-data PKCS7-CONTENT-TYPE ::= {SignedData
+ IDENTIFIED BY id-signed-data
+}
+
+SignedData ::= SEQUENCE {
+ version Version,
+ digestAlgorithms DigestAlgorithmIdentifiers,
+ contentInfo ContentInfo,
+ certificates [0] CertificateSet OPTIONAL,
+ crls [1] CertificateRevocationLists OPTIONAL,
+ signerInfos SignerInfos
+}
+
+Version ::= INTEGER
+
+DigestAlgorithmIdentifiers ::= SET OF DigestAlgorithmIdentifier
+
+DigestAlgorithmIdentifier ::= AlgorithmIdentifier
+
+CertificateSet ::= SET OF CertificateChoice
+
+CertificateChoice ::= CHOICE {
+ certificate Certificate,
+ extendedCertificate [0] ExtendedCertificate, -- Obsolete
+ attributeCertificate [1] AttributeCertificate
+}
+
+CertificateRevocationLists ::= SET OF CertificateList
+
+SignerInfos ::= SET OF SignerInfo
+
+SignerInfo ::= SEQUENCE {
+ version Version,
+ signerIdentifier SignerIdentifier,
+ digestAlgorithm DigestAlgorithmIdentifier,
+ authenticatedAttributes [0] Attributes OPTIONAL,
+ digestEncryptionAlgorithm DigestEncryptionAlgorithmIdentifier,
+ encryptedDigest EncryptedDigest,
+ unauthenticatedAttributes [1] Attributes OPTIONAL
+}
+
+SignerIdentifier ::= CHOICE {
+ issuerAndSerialNumber IssuerAndSerialNumber,
+ subjectKeyIdentifier [2] SubjectKeyIdentifier
+}
+
+IssuerAndSerialNumber ::= SEQUENCE {
+ issuer Name,
+ serialNumber CertificateSerialNumber
+}
+
+SubjectKeyIdentifier ::= OCTET STRING
+
+DigestEncryptionAlgorithmIdentifier ::= AlgorithmIdentifier
+
+EncryptedDigest ::= ENCRYPTED{DigestInfo}
+
+DigestInfo ::= SEQUENCE {
+ digestAlgorithm DigestAlgorithmIdentifier,
+ digest Digest
+}
+
+Digest ::=
+ HASH
+ {CHOICE {content
+ [1] PKCS7-CONTENT-TYPE.&Type({PKCS7ContentTable}),
+ authenticated-attributes [0] EXPLICIT Attributes}}
+
+-- Enveloped Data
+enveloped-data PKCS7-CONTENT-TYPE ::= {
+ EnvelopedData
+ IDENTIFIED BY id-enveloped-data
+}
+
+EnvelopedData ::= SEQUENCE {
+ version Version,
+ originatorInfo [0] OriginatorInfo OPTIONAL,
+ recipientInfos RecipientInfos,
+ encryptedContentInfo EncryptedContentInfo,
+ unprotectedAttributes [1] Attributes OPTIONAL
+}
+
+OriginatorInfo ::= SEQUENCE {
+ certificates [0] CertificateSet OPTIONAL,
+ crls [1] CertificateRevocationLists OPTIONAL
+}
+
+RecipientInfos ::= SET SIZE (1..MAX) OF RecipientInfo
+
+RecipientInfo ::= CHOICE {
+ keyTransportRecipientInfo KeyTransportRecipientInfo,
+ keyAgreementRecipientInfo [1] KeyAgreementRecipientInfo,
+ keyEncryptionKeyRecipientInfo [2] KeyEncryptionKeyRecipientInfo
+}
+
+KeyTransportRecipientInfo ::= SEQUENCE {
+ version Version,
+ recipientIdentifier RecipientIdentifier,
+ keyEncryptionAlgorithm KeyEncryptionAlgorithmIdentifier,
+ encryptedKey EncryptedKey
+}
+
+RecipientIdentifier ::= CHOICE {
+ issuerAndSerialNumber IssuerAndSerialNumber,
+ subjectKeyIdentifier [0] SubjectKeyIdentifier
+}
+
+KeyEncryptionAlgorithmIdentifier ::= AlgorithmIdentifier
+
+EncryptedKey ::= OCTET STRING
+
+KeyAgreementRecipientInfo ::= SEQUENCE {
+ version Version,
+ originator [0] OriginatorIdentifierOrKey,
+ userKeyingMaterial [1] EXPLICIT OCTET STRING OPTIONAL,
+ keyEncryptionAlgorithm KeyEncryptionAlgorithmIdentifier,
+ recipientEncryptedKeys RecipientEncryptedKeys
+}
+
+OriginatorIdentifierOrKey ::= CHOICE {
+ issuerAndSerialNumber IssuerAndSerialNumber,
+ subjectKeyIdentifier [0] SubjectKeyIdentifier,
+ originatorPublicKey [1] OriginatorPublicKey
+}
+
+OriginatorPublicKey ::= SEQUENCE {
+ algorithm AlgorithmIdentifier,
+ publicKey BIT STRING
+}
+
+RecipientEncryptedKeys ::= SEQUENCE OF RecipientEncryptedKey
+
+RecipientEncryptedKey ::= SEQUENCE {
+ recipientIdentifier KeyAgreementRecipientIdentifier,
+ encryptedKey EncryptedKey
+}
+
+KeyAgreementRecipientIdentifier ::= CHOICE {
+ issuerAndSerialNumber IssuerAndSerialNumber,
+ recipientKeyIdentifier [0] RecipientKeyIdentifier
+}
+
+RecipientKeyIdentifier ::= SEQUENCE {
+ subjectKeyIdentifier SubjectKeyIdentifier,
+ date GeneralizedTime OPTIONAL,
+ otherKeyAttribute OtherKeyAttribute OPTIONAL
+}
+
+OtherKeyAttribute ::= SEQUENCE {
+ keyAttributeIdentifier OTHER-KEY-ATTRIBUTE.&id({OtherKeyAttributeTable}),
+ keyAttribute
+ OTHER-KEY-ATTRIBUTE.&Type
+ ({OtherKeyAttributeTable}{@keyAttributeIdentifier}) OPTIONAL
+}
+
+OTHER-KEY-ATTRIBUTE ::= TYPE-IDENTIFIER
+
+OtherKeyAttributeTable OTHER-KEY-ATTRIBUTE ::=
+ {...}
+
+KeyEncryptionKeyRecipientInfo ::= SEQUENCE {
+ version Version,
+ keyEncryptionKeyIdentifier KeyEncryptionKeyIdentifier,
+ keyEncryptionAlgorithm KeyEncryptionAlgorithmIdentifier,
+ encryptedKey EncryptedKey
+}
+
+KeyEncryptionKeyIdentifier ::= SEQUENCE {
+ keyIdentifier OCTET STRING,
+ date GeneralizedTime OPTIONAL,
+ otherKeyAttribute OtherKeyAttribute OPTIONAL
+}
+
+EncryptedContentInfo ::= SEQUENCE {
+ contentType PKCS7-CONTENT-TYPE.&id({PKCS7ContentTable}),
+ contentEncryptionAlgorithm ContentEncryptionAlgorithmIdentifier,
+ encryptedContent
+ [0] ENCRYPTED{PKCS7-CONTENT-TYPE.&Type({PKCS7ContentTable}{@.contentType})}
+ OPTIONAL
+}
+
+ContentEncryptionAlgorithmIdentifier ::= AlgorithmIdentifier
+
+-- Signed and Enveloped Data
+signed-and-enveloped-data PKCS7-CONTENT-TYPE ::= {
+ SignedAndEnvelopedData
+ IDENTIFIED BY id-signed-and-enveloped-data
+}
+
+SignedAndEnvelopedData ::= SEQUENCE {
+ version Version,
+ recipientInfos SET SIZE (1..MAX) OF KeyTransportRecipientInfo,
+ digestAlgorithms DigestAlgorithmIdentifiers,
+ encryptedContentInfo EncryptedContentInfo,
+ certificates [0] CertificateSet OPTIONAL,
+ crls [1] CertificateRevocationLists OPTIONAL,
+ signerInfos
+ SET SIZE (1..MAX) OF
+ SignerInfo
+ (WITH COMPONENTS {
+ ...,
+ signerIdentifier (WITH COMPONENTS {
+ issuerAndSerialNumber PRESENT
+ }),
+ authenticatedAttributes ABSENT,
+ unauthenticatedAttributes ABSENT
+ })
+}
+
+-- Digested Data
+digested-data PKCS7-CONTENT-TYPE ::= {
+ DigestedData
+ IDENTIFIED BY id-digested-data
+}
+
+DigestedData ::= SEQUENCE {
+ version Version,
+ digestAlgorithm DigestAlgorithmIdentifier,
+ contentInfo ContentInfo,
+ digest HASH{PKCS7-CONTENT-TYPE.&Type({PKCS7ContentTable})}
+}
+
+-- Encrypted Data
+encrypted-data PKCS7-CONTENT-TYPE ::= {
+ EncryptedData
+ IDENTIFIED BY id-encrypted-data
+}
+
+EncryptedData ::= SEQUENCE {
+ version Version,
+ encryptedContentInfo EncryptedContentInfo,
+ unprotectedAttributes [1] Attributes OPTIONAL
+}
+
+-- Authenticated Data
+authenticated-data PKCS7-CONTENT-TYPE ::= {
+ AuthenticatedData
+ IDENTIFIED BY id-authenticated-data
+}
+
+AuthenticatedData ::= SEQUENCE {
+ version Version,
+ originatorInfo [0] OriginatorInfo OPTIONAL,
+ recipientInfos RecipientInfos,
+ macAlgorithm MessageAuthenticationCodeAlgorithmIdentifier,
+ digestAlgorithm [1] DigestAlgorithmIdentifier OPTIONAL,
+ contentInfo ContentInfo,
+ authenticatedAttributes [2] Attributes OPTIONAL,
+ messageAuthenticationCode MessageAuthenticationCode,
+ unauthenticatedAttributes [3] Attributes OPTIONAL
+}
+
+MessageAuthenticationCodeAlgorithmIdentifier ::= AlgorithmIdentifier
+
+MessageAuthenticationCode ::= OCTET STRING
+
+-- Object Identifiers
+id-pkcs OBJECT IDENTIFIER ::=
+ {iso member-body usa(840) rsadsi(113549) pkcs(1)}
+
+id-data OBJECT IDENTIFIER ::= {id-pkcs 7 1}
+
+id-signed-data OBJECT IDENTIFIER ::= {id-pkcs 7 2}
+
+id-enveloped-data OBJECT IDENTIFIER ::= {id-pkcs 7 3}
+
+id-signed-and-enveloped-data OBJECT IDENTIFIER ::= {id-pkcs 7 4}
+
+id-digested-data OBJECT IDENTIFIER ::= {id-pkcs 7 5}
+
+id-encrypted-data OBJECT IDENTIFIER ::= {id-pkcs 7 6}
+
+id-authenticated-data OBJECT IDENTIFIER ::= {id-pkcs 9 16 1 2}
+
+-- Definitions from PKCS#6
+ExtendedCertificate ::=
+ SIGNED{ExtendedCertificateInfo}
+
+ExtendedCertificateInfo ::= SEQUENCE {
+ version Version,
+ certificate Certificate,
+ attributes Attributes
+}
+
+Attributes ::= SET OF Attribute
+
+END -- of PKCS#7
+
+-- Generated by Asnp, the ASN.1 pretty-printer of France Telecom R&D
+
diff --git a/lib/asn1/test/asn1_SUITE_data/modified_x420/SelectedAttributeTypes.asn b/lib/asn1/test/asn1_SUITE_data/modified_x420/SelectedAttributeTypes.asn
new file mode 100644
index 0000000000..07bba30690
--- /dev/null
+++ b/lib/asn1/test/asn1_SUITE_data/modified_x420/SelectedAttributeTypes.asn
@@ -0,0 +1,1466 @@
+-- Module SelectedAttributeTypes (X.520:08/1997)
+
+SelectedAttributeTypes {joint-iso-itu-t ds(5) module(1)
+ selectedAttributeTypes(5) 3} DEFINITIONS ::=
+BEGIN
+
+-- EXPORTS All
+-- The types and values defined in this module are exported for use in the other ASN.1 modules contained
+-- within the Directory Specifications, and for the use of other applications which will use them to access
+-- Directory services. Other applications may use them for their own purposes, but this will not constrain
+-- extensions and modifications needed to maintain or improve the Directory service.
+IMPORTS
+ informationFramework, upperBounds, id-at, id-mr, id-avc,
+ directoryAbstractService, id-pr, id-not, id-cat
+ FROM UsefulDefinitions {joint-iso-itu-t ds(5) module(1)
+ usefulDefinitions(0) 3}
+ Attribute, ATTRIBUTE, MATCHING-RULE, AttributeType, OBJECT-CLASS,
+ DistinguishedName, objectIdentifierMatch, distinguishedNameMatch,
+ CONTEXT, ContextAssertion, AttributeCombination, ContextCombination,
+ MAPPING-BASED-MATCHING, MRMapping, AttributeValueAssertion
+ FROM InformationFramework informationFramework
+ G3FacsimileNonBasicParameters
+ FROM MTSAbstractService {joint-iso-itu-t mhs(6) mts(3) modules(0)
+ mts-abstract-service(1) version-1999(1)}
+ ub-answerback, ub-name, ub-common-name, ub-surname, ub-serial-number,
+ ub-locality-name, ub-state-name, ub-street-address, ub-organization-name,
+ ub-organizational-unit-name, ub-title, ub-description,
+ ub-business-category, ub-postal-line, ub-postal-string, ub-postal-code,
+ ub-post-office-box, ub-physical-office-name, ub-telex-number,
+ ub-country-code, ub-teletex-terminal-id, ub-telephone-number,
+ ub-x121-address, ub-international-isdn-number, ub-destination-indicator,
+ ub-user-password, ub-match, ub-knowledge-information,
+ ub-directory-string-first-component-match, ub-localeContextSyntax,
+ ub-pseudonym
+ FROM UpperBounds upperBounds
+ FilterItem, HierarchySelections, SearchControlOptions, ServiceControlOptions
+ FROM DirectoryAbstractService directoryAbstractService;
+
+-- Directory string type
+DirectoryString{INTEGER:maxSize} ::= CHOICE {
+ teletexString TeletexString(SIZE (1..maxSize)),
+ printableString PrintableString(SIZE (1..maxSize)),
+ universalString UniversalString(SIZE (1..maxSize)),
+ bmpString BMPString(SIZE (1..maxSize)),
+ uTF8String UTF8String(SIZE (1..maxSize))
+}
+
+-- Attribute types
+knowledgeInformation ATTRIBUTE ::= {
+ WITH SYNTAX DirectoryString {ub-knowledge-information}
+ EQUALITY MATCHING RULE caseIgnoreMatch
+ ID id-at-knowledgeInformation
+}
+
+name ATTRIBUTE ::= {
+ WITH SYNTAX DirectoryString {ub-name}
+ EQUALITY MATCHING RULE caseIgnoreMatch
+ SUBSTRINGS MATCHING RULE caseIgnoreSubstringsMatch
+ ID id-at-name
+}
+
+commonName ATTRIBUTE ::= {
+ SUBTYPE OF name
+ WITH SYNTAX DirectoryString {ub-common-name}
+ ID id-at-commonName
+}
+
+surname ATTRIBUTE ::= {
+ SUBTYPE OF name
+ WITH SYNTAX DirectoryString {ub-surname}
+ ID id-at-surname
+}
+
+givenName ATTRIBUTE ::= {
+ SUBTYPE OF name
+ WITH SYNTAX DirectoryString {ub-name}
+ ID id-at-givenName
+}
+
+initials ATTRIBUTE ::= {
+ SUBTYPE OF name
+ WITH SYNTAX DirectoryString {ub-name}
+ ID id-at-initials
+}
+
+generationQualifier ATTRIBUTE ::= {
+ SUBTYPE OF name
+ WITH SYNTAX DirectoryString {ub-name}
+ ID id-at-generationQualifier
+}
+
+uniqueIdentifier ATTRIBUTE ::= {
+ WITH SYNTAX UniqueIdentifier
+ EQUALITY MATCHING RULE bitStringMatch
+ ID id-at-uniqueIdentifier
+}
+
+UniqueIdentifier ::= BIT STRING
+
+dnQualifier ATTRIBUTE ::= {
+ WITH SYNTAX PrintableString
+ EQUALITY MATCHING RULE caseIgnoreMatch
+ ORDERING MATCHING RULE caseIgnoreOrderingMatch
+ SUBSTRINGS MATCHING RULE caseIgnoreSubstringsMatch
+ ID id-at-dnQualifier
+}
+
+serialNumber ATTRIBUTE ::= {
+ WITH SYNTAX PrintableString(SIZE (1..ub-serial-number))
+ EQUALITY MATCHING RULE caseIgnoreMatch
+ SUBSTRINGS MATCHING RULE caseIgnoreSubstringsMatch
+ ID id-at-serialNumber
+}
+
+pseudonym ATTRIBUTE ::= {
+ SUBTYPE OF name
+ WITH SYNTAX DirectoryString {ub-pseudonym}
+ ID id-at-pseudonym
+}
+
+countryName ATTRIBUTE ::= {
+ SUBTYPE OF name
+ WITH SYNTAX CountryName
+ SINGLE VALUE TRUE
+ ID id-at-countryName
+}
+
+CountryName ::= PrintableString(SIZE (2)) -- ISO 3166 codes only
+
+
+localityName ATTRIBUTE ::= {
+ SUBTYPE OF name
+ WITH SYNTAX DirectoryString {ub-locality-name}
+ ID id-at-localityName
+}
+
+collectiveLocalityName ATTRIBUTE ::= {
+ SUBTYPE OF localityName
+ COLLECTIVE TRUE
+ ID id-at-collectiveLocalityName
+}
+
+stateOrProvinceName ATTRIBUTE ::= {
+ SUBTYPE OF name
+ WITH SYNTAX DirectoryString {ub-state-name}
+ ID id-at-stateOrProvinceName
+}
+
+collectiveStateOrProvinceName ATTRIBUTE ::= {
+ SUBTYPE OF stateOrProvinceName
+ COLLECTIVE TRUE
+ ID id-at-collectiveStateOrProvinceName
+}
+
+streetAddress ATTRIBUTE ::= {
+ WITH SYNTAX DirectoryString {ub-street-address}
+ EQUALITY MATCHING RULE caseIgnoreMatch
+ SUBSTRINGS MATCHING RULE caseIgnoreSubstringsMatch
+ ID id-at-streetAddress
+}
+
+collectiveStreetAddress ATTRIBUTE ::= {
+ SUBTYPE OF streetAddress
+ COLLECTIVE TRUE
+ ID id-at-collectiveStreetAddress
+}
+
+houseIdentifier ATTRIBUTE ::= {
+ WITH SYNTAX DirectoryString {ub-name}
+ EQUALITY MATCHING RULE caseIgnoreMatch
+ SUBSTRINGS MATCHING RULE caseIgnoreSubstringsMatch
+ ID id-at-houseIdentifier
+}
+
+organizationName ATTRIBUTE ::= {
+ SUBTYPE OF name
+ WITH SYNTAX DirectoryString {ub-organization-name}
+ ID id-at-organizationName
+}
+
+collectiveOrganizationName ATTRIBUTE ::= {
+ SUBTYPE OF organizationName
+ COLLECTIVE TRUE
+ ID id-at-collectiveOrganizationName
+}
+
+organizationalUnitName ATTRIBUTE ::= {
+ SUBTYPE OF name
+ WITH SYNTAX DirectoryString {ub-organizational-unit-name}
+ ID id-at-organizationalUnitName
+}
+
+collectiveOrganizationalUnitName ATTRIBUTE ::= {
+ SUBTYPE OF organizationalUnitName
+ COLLECTIVE TRUE
+ ID id-at-collectiveOrganizationalUnitName
+}
+
+title ATTRIBUTE ::= {
+ SUBTYPE OF name
+ WITH SYNTAX DirectoryString {ub-title}
+ ID id-at-title
+}
+
+description ATTRIBUTE ::= {
+ WITH SYNTAX DirectoryString {ub-description}
+ EQUALITY MATCHING RULE caseIgnoreMatch
+ SUBSTRINGS MATCHING RULE caseIgnoreSubstringsMatch
+ ID id-at-description
+}
+
+searchGuide ATTRIBUTE ::= {WITH SYNTAX Guide
+ ID id-at-searchGuide
+}
+
+Guide ::= SET {
+ objectClass [0] OBJECT-CLASS.&id OPTIONAL,
+ criteria [1] Criteria
+}
+
+Criteria ::= CHOICE {
+ type [0] CriteriaItem,
+ and [1] SET OF Criteria,
+ or [2] SET OF Criteria,
+ not [3] Criteria
+}
+
+CriteriaItem ::= CHOICE {
+ equality [0] AttributeType,
+ substrings [1] AttributeType,
+ greaterOrEqual [2] AttributeType,
+ lessOrEqual [3] AttributeType,
+ approximateMatch [4] AttributeType
+}
+
+enhancedSearchGuide ATTRIBUTE ::= {
+ WITH SYNTAX EnhancedGuide
+ ID id-at-enhancedSearchGuide
+}
+
+EnhancedGuide ::= SEQUENCE {
+ objectClass [0] OBJECT-CLASS.&id,
+ criteria [1] Criteria,
+ subset
+ [2] INTEGER {baseObject(0), oneLevel(1), wholeSubtree(2)} DEFAULT oneLevel
+}
+
+businessCategory ATTRIBUTE ::= {
+ WITH SYNTAX DirectoryString {ub-business-category}
+ EQUALITY MATCHING RULE caseIgnoreMatch
+ SUBSTRINGS MATCHING RULE caseIgnoreSubstringsMatch
+ ID id-at-businessCategory
+}
+
+postalAddress ATTRIBUTE ::= {
+ WITH SYNTAX PostalAddress
+ EQUALITY MATCHING RULE caseIgnoreListMatch
+ SUBSTRINGS MATCHING RULE caseIgnoreListSubstringsMatch
+ ID id-at-postalAddress
+}
+
+PostalAddress ::=
+ SEQUENCE SIZE (1..ub-postal-line) OF DirectoryString{ub-postal-string}
+
+collectivePostalAddress ATTRIBUTE ::= {
+ SUBTYPE OF postalAddress
+ COLLECTIVE TRUE
+ ID id-at-collectivePostalAddress
+}
+
+postalCode ATTRIBUTE ::= {
+ WITH SYNTAX DirectoryString {ub-postal-code}
+ EQUALITY MATCHING RULE caseIgnoreMatch
+ SUBSTRINGS MATCHING RULE caseIgnoreSubstringsMatch
+ ID id-at-postalCode
+}
+
+collectivePostalCode ATTRIBUTE ::= {
+ SUBTYPE OF postalCode
+ COLLECTIVE TRUE
+ ID id-at-collectivePostalCode
+}
+
+postOfficeBox ATTRIBUTE ::= {
+ WITH SYNTAX DirectoryString {ub-post-office-box}
+ EQUALITY MATCHING RULE caseIgnoreMatch
+ SUBSTRINGS MATCHING RULE caseIgnoreSubstringsMatch
+ ID id-at-postOfficeBox
+}
+
+collectivePostOfficeBox ATTRIBUTE ::= {
+ SUBTYPE OF postOfficeBox
+ COLLECTIVE TRUE
+ ID id-at-collectivePostOfficeBox
+}
+
+physicalDeliveryOfficeName ATTRIBUTE ::= {
+ WITH SYNTAX DirectoryString {ub-physical-office-name}
+ EQUALITY MATCHING RULE caseIgnoreMatch
+ SUBSTRINGS MATCHING RULE caseIgnoreSubstringsMatch
+ ID id-at-physicalDeliveryOfficeName
+}
+
+collectivePhysicalDeliveryOfficeName ATTRIBUTE ::= {
+ SUBTYPE OF physicalDeliveryOfficeName
+ COLLECTIVE TRUE
+ ID id-at-collectivePhysicalDeliveryOfficeName
+}
+
+telephoneNumber ATTRIBUTE ::= {
+ WITH SYNTAX TelephoneNumber
+ EQUALITY MATCHING RULE telephoneNumberMatch
+ SUBSTRINGS MATCHING RULE telephoneNumberSubstringsMatch
+ ID id-at-telephoneNumber
+}
+
+TelephoneNumber ::= PrintableString(SIZE (1..ub-telephone-number))
+
+-- String complying with CCITT Rec. E.123 only
+collectiveTelephoneNumber ATTRIBUTE ::= {
+ SUBTYPE OF telephoneNumber
+ COLLECTIVE TRUE
+ ID id-at-collectiveTelephoneNumber
+}
+
+telexNumber ATTRIBUTE ::= {
+ WITH SYNTAX TelexNumber
+ ID id-at-telexNumber
+}
+
+TelexNumber ::= SEQUENCE {
+ telexNumber PrintableString(SIZE (1..ub-telex-number)),
+ countryCode PrintableString(SIZE (1..ub-country-code)),
+ answerback PrintableString(SIZE (1..ub-answerback))
+}
+
+collectiveTelexNumber ATTRIBUTE ::= {
+ SUBTYPE OF telexNumber
+ COLLECTIVE TRUE
+ ID id-at-collectiveTelexNumber
+}
+
+facsimileTelephoneNumber ATTRIBUTE ::= {
+ WITH SYNTAX FacsimileTelephoneNumber
+ EQUALITY MATCHING RULE facsimileNumberMatch
+ SUBSTRINGS MATCHING RULE facsimileNumberSubstringsMatch
+ ID id-at-facsimileTelephoneNumber
+}
+
+facsimileNumberMatch MATCHING-RULE ::= {
+ SYNTAX TelephoneNumber
+ ID id-mr-facsimileNumberMatch
+}
+
+facsimileNumberSubstringsMatch MATCHING-RULE ::= {
+ SYNTAX SubstringAssertion
+ ID id-mr-facsimileNumberSubstringsMatch
+}
+
+FacsimileTelephoneNumber ::= SEQUENCE {
+ telephoneNumber TelephoneNumber,
+ parameters G3FacsimileNonBasicParameters OPTIONAL
+}
+
+collectiveFacsimileTelephoneNumber ATTRIBUTE ::= {
+ SUBTYPE OF facsimileTelephoneNumber
+ COLLECTIVE TRUE
+ ID id-at-collectiveFacsimileTelephoneNumber
+}
+
+x121Address ATTRIBUTE ::= {
+ WITH SYNTAX X121Address
+ EQUALITY MATCHING RULE numericStringMatch
+ SUBSTRINGS MATCHING RULE numericStringSubstringsMatch
+ ID id-at-x121Address
+}
+
+X121Address ::= NumericString(SIZE (1..ub-x121-address))
+
+-- String as defined by ITU-T Rec. X.121
+internationalISDNNumber ATTRIBUTE ::= {
+ WITH SYNTAX InternationalISDNNumber
+ EQUALITY MATCHING RULE numericStringMatch
+ SUBSTRINGS MATCHING RULE numericStringSubstringsMatch
+ ID id-at-internationalISDNNumber
+}
+
+InternationalISDNNumber ::=
+ NumericString(SIZE (1..ub-international-isdn-number))
+
+-- String complying with ITU-T Rec. E.164 only
+collectiveInternationalISDNNumber ATTRIBUTE ::= {
+ SUBTYPE OF internationalISDNNumber
+ COLLECTIVE TRUE
+ ID id-at-collectiveInternationalISDNNumber
+}
+
+registeredAddress ATTRIBUTE ::= {
+ SUBTYPE OF postalAddress
+ WITH SYNTAX PostalAddress
+ ID id-at-registeredAddress
+}
+
+destinationIndicator ATTRIBUTE ::= {
+ WITH SYNTAX DestinationIndicator
+ EQUALITY MATCHING RULE caseIgnoreMatch
+ SUBSTRINGS MATCHING RULE caseIgnoreSubstringsMatch
+ ID id-at-destinationIndicator
+}
+
+DestinationIndicator ::= PrintableString(SIZE (1..ub-destination-indicator))
+
+communicationsService ATTRIBUTE ::= {
+ WITH SYNTAX OBJECT IDENTIFIER
+ EQUALITY MATCHING RULE objectIdentifierMatch
+ ID id-at-communicationsService
+}
+
+communicationsNetwork ATTRIBUTE ::= {
+ WITH SYNTAX OBJECT IDENTIFIER
+ EQUALITY MATCHING RULE objectIdentifierMatch
+ SINGLE VALUE TRUE
+ ID id-at-communicationsNetwork
+}
+
+-- alphabetical characters only
+preferredDeliveryMethod ATTRIBUTE ::= {
+ WITH SYNTAX PreferredDeliveryMethod
+ SINGLE VALUE TRUE
+ ID id-at-preferredDeliveryMethod
+}
+
+PreferredDeliveryMethod ::=
+ SEQUENCE OF
+ INTEGER {any-delivery-method(0), mhs-delivery(1), physical-delivery(2),
+ telex-delivery(3), teletex-delivery(4), g3-facsimile-delivery(5),
+ g4-facsimile-delivery(6), ia5-terminal-delivery(7),
+ videotex-delivery(8), telephone-delivery(9)}
+
+presentationAddress ATTRIBUTE ::= {
+ WITH SYNTAX PresentationAddress
+ EQUALITY MATCHING RULE presentationAddressMatch
+ SINGLE VALUE TRUE
+ ID id-at-presentationAddress
+}
+
+PresentationAddress ::= SEQUENCE {
+ pSelector [0] OCTET STRING OPTIONAL,
+ sSelector [1] OCTET STRING OPTIONAL,
+ tSelector [2] OCTET STRING OPTIONAL,
+ nAddresses [3] SET SIZE (1..MAX) OF OCTET STRING
+}
+
+supportedApplicationContext ATTRIBUTE ::= {
+ WITH SYNTAX OBJECT IDENTIFIER
+ EQUALITY MATCHING RULE objectIdentifierMatch
+ ID id-at-supportedApplicationContext
+}
+
+protocolInformation ATTRIBUTE ::= {
+ WITH SYNTAX ProtocolInformation
+ EQUALITY MATCHING RULE protocolInformationMatch
+ ID id-at-protocolInformation
+}
+
+ProtocolInformation ::= SEQUENCE {
+ nAddress OCTET STRING,
+ profiles SET OF OBJECT IDENTIFIER
+}
+
+distinguishedName ATTRIBUTE ::= {
+ WITH SYNTAX DistinguishedName
+ EQUALITY MATCHING RULE distinguishedNameMatch
+ ID id-at-distinguishedName
+}
+
+member ATTRIBUTE ::= {SUBTYPE OF distinguishedName
+ ID id-at-member
+}
+
+uniqueMember ATTRIBUTE ::= {
+ WITH SYNTAX NameAndOptionalUID
+ EQUALITY MATCHING RULE uniqueMemberMatch
+ ID id-at-uniqueMember
+}
+
+NameAndOptionalUID ::= SEQUENCE {
+ dn DistinguishedName,
+ uid UniqueIdentifier OPTIONAL
+}
+
+owner ATTRIBUTE ::= {SUBTYPE OF distinguishedName
+ ID id-at-owner
+}
+
+roleOccupant ATTRIBUTE ::= {
+ SUBTYPE OF distinguishedName
+ ID id-at-roleOccupant
+}
+
+seeAlso ATTRIBUTE ::= {SUBTYPE OF distinguishedName
+ ID id-at-seeAlso
+}
+
+dmdName ATTRIBUTE ::= {
+ SUBTYPE OF name
+ WITH SYNTAX DirectoryString {ub-common-name}
+ ID id-at-dmdName
+}
+
+dSAProblem ATTRIBUTE ::= {
+ WITH SYNTAX OBJECT IDENTIFIER
+ EQUALITY MATCHING RULE objectIdentifierMatch
+ ID id-not-dSAProblem
+}
+
+searchServiceProblem ATTRIBUTE ::= {
+ WITH SYNTAX OBJECT IDENTIFIER
+ EQUALITY MATCHING RULE objectIdentifierMatch
+ SINGLE VALUE TRUE
+ ID id-not-searchServiceProblem
+}
+
+serviceType ATTRIBUTE ::= {
+ WITH SYNTAX OBJECT IDENTIFIER
+ EQUALITY MATCHING RULE objectIdentifierMatch
+ SINGLE VALUE TRUE
+ ID id-not-serviceType
+}
+
+attributeTypeList ATTRIBUTE ::= {
+ WITH SYNTAX OBJECT IDENTIFIER
+ EQUALITY MATCHING RULE objectIdentifierMatch
+ ID id-not-attributeTypeList
+}
+
+filterItem ATTRIBUTE ::= {
+ WITH SYNTAX FilterItem
+ ID id-not-filterItem
+}
+
+attributeCombinations ATTRIBUTE ::= {
+ WITH SYNTAX AttributeCombination
+ ID id-not-attributeCombinations
+}
+
+contextTypeList ATTRIBUTE ::= {
+ WITH SYNTAX OBJECT IDENTIFIER
+ EQUALITY MATCHING RULE objectIdentifierMatch
+ ID id-not-contextTypeList
+}
+
+contextList ATTRIBUTE ::= {
+ WITH SYNTAX ContextAssertion
+ ID id-not-contextList
+}
+
+hierarchySelectList ATTRIBUTE ::= {
+ WITH SYNTAX HierarchySelections
+ SINGLE VALUE TRUE
+ ID id-not-hierarchySelectList
+}
+
+searchOptionsList ATTRIBUTE ::= {
+ WITH SYNTAX SearchControlOptions
+ SINGLE VALUE TRUE
+ ID id-not-searchOptionsList
+}
+
+serviceControlOptionsList ATTRIBUTE ::= {
+ WITH SYNTAX ServiceControlOptions
+ SINGLE VALUE TRUE
+ ID id-not-serviceControlOptionsList
+}
+
+multipleMatchingLocalities ATTRIBUTE ::= {
+ WITH SYNTAX MultipleMatchingLocalities
+ ID id-not-multipleMatchingLocalities
+}
+
+MultipleMatchingLocalities ::= SEQUENCE {
+ matchingRuleUsed MATCHING-RULE.&id OPTIONAL,
+ attributeList SEQUENCE OF AttributeValueAssertion
+}
+
+proposedRelaxation ATTRIBUTE ::= {
+ WITH SYNTAX SEQUENCE OF MRMapping
+ ID id-not-proposedRelaxation
+}
+
+appliedRelaxation ATTRIBUTE ::= {
+ WITH SYNTAX OBJECT IDENTIFIER
+ EQUALITY MATCHING RULE objectIdentifierMatch
+ ID id-not-appliedRelaxation
+}
+
+-- Matching rules
+caseIgnoreMatch MATCHING-RULE ::= {
+ SYNTAX DirectoryString {ub-match}
+ ID id-mr-caseIgnoreMatch
+}
+
+caseIgnoreOrderingMatch MATCHING-RULE ::= {
+ SYNTAX DirectoryString {ub-match}
+ ID id-mr-caseIgnoreOrderingMatch
+}
+
+caseIgnoreSubstringsMatch MATCHING-RULE ::= {
+ SYNTAX SubstringAssertion
+ ID id-mr-caseIgnoreSubstringsMatch
+}
+
+SubstringAssertion ::=
+ SEQUENCE OF
+ CHOICE {initial [0] DirectoryString{ub-match},
+ any [1] DirectoryString{ub-match},
+ final [2] DirectoryString{ub-match},
+ control Attribute
+ } -- Used to specify interpretation of the following items
+
+-- at most one initial and one final component
+caseExactMatch MATCHING-RULE ::= {
+ SYNTAX DirectoryString {ub-match}
+ ID id-mr-caseExactMatch
+}
+
+caseExactOrderingMatch MATCHING-RULE ::= {
+ SYNTAX DirectoryString {ub-match}
+ ID id-mr-caseExactOrderingMatch
+}
+
+caseExactSubstringsMatch MATCHING-RULE ::= {
+ SYNTAX SubstringAssertion -- only the PrintableString choice
+ ID id-mr-caseExactSubstringsMatch
+}
+
+numericStringMatch MATCHING-RULE ::= {
+ SYNTAX NumericString
+ ID id-mr-numericStringMatch
+}
+
+numericStringOrderingMatch MATCHING-RULE ::= {
+ SYNTAX NumericString
+ ID id-mr-numericStringOrderingMatch
+}
+
+numericStringSubstringsMatch MATCHING-RULE ::= {
+ SYNTAX SubstringAssertion
+ ID id-mr-numericStringSubstringsMatch
+}
+
+caseIgnoreListMatch MATCHING-RULE ::= {
+ SYNTAX CaseIgnoreListMatch
+ ID id-mr-caseIgnoreListMatch
+}
+
+CaseIgnoreListMatch ::= SEQUENCE OF DirectoryString{ub-match}
+
+caseIgnoreListSubstringsMatch MATCHING-RULE ::= {
+ SYNTAX SubstringAssertion
+ ID id-mr-caseIgnoreListSubstringsMatch
+}
+
+storedPrefixMatch MATCHING-RULE ::= {
+ SYNTAX DirectoryString {ub-match}
+ ID id-mr-storedPrefixMatch
+}
+
+booleanMatch MATCHING-RULE ::= {SYNTAX BOOLEAN
+ ID id-mr-booleanMatch
+}
+
+integerMatch MATCHING-RULE ::= {SYNTAX INTEGER
+ ID id-mr-integerMatch
+}
+
+integerOrderingMatch MATCHING-RULE ::= {
+ SYNTAX INTEGER
+ ID id-mr-integerOrderingMatch
+}
+
+bitStringMatch MATCHING-RULE ::= {
+ SYNTAX BIT STRING
+ ID id-mr-bitStringMatch
+}
+
+octetStringMatch MATCHING-RULE ::= {
+ SYNTAX OCTET STRING
+ ID id-mr-octetStringMatch
+}
+
+octetStringOrderingMatch MATCHING-RULE ::= {
+ SYNTAX OCTET STRING
+ ID id-mr-octetStringOrderingMatch
+}
+
+octetStringSubstringsMatch MATCHING-RULE ::= {
+ SYNTAX OctetSubstringAssertion
+ ID id-mr-octetStringSubstringsMatch
+}
+
+OctetSubstringAssertion ::=
+ SEQUENCE OF
+ CHOICE {initial [0] OCTET STRING,
+ any [1] OCTET STRING,
+ final [2] OCTET STRING}
+
+-- at most one initial and one final component
+telephoneNumberMatch MATCHING-RULE ::= {
+ SYNTAX TelephoneNumber
+ ID id-mr-telephoneNumberMatch
+}
+
+telephoneNumberSubstringsMatch MATCHING-RULE ::= {
+ SYNTAX SubstringAssertion
+ ID id-mr-telephoneNumberSubstringsMatch
+}
+
+presentationAddressMatch MATCHING-RULE ::= {
+ SYNTAX PresentationAddress
+ ID id-mr-presentationAddressMatch
+}
+
+uniqueMemberMatch MATCHING-RULE ::= {
+ SYNTAX NameAndOptionalUID
+ ID id-mr-uniqueMemberMatch
+}
+
+protocolInformationMatch MATCHING-RULE ::= {
+ SYNTAX OCTET STRING
+ ID id-mr-protocolInformationMatch
+}
+
+uTCTimeMatch MATCHING-RULE ::= {SYNTAX UTCTime
+ ID id-mr-uTCTimeMatch
+}
+
+uTCTimeOrderingMatch MATCHING-RULE ::= {
+ SYNTAX UTCTime
+ ID id-mr-uTCTimeOrderingMatch
+}
+
+generalizedTimeMatch MATCHING-RULE ::= {
+ SYNTAX GeneralizedTime
+ -- as per 41.3 b) or c) of ITU-T Rec. X.680 | ISO/IEC 8824-1
+ ID id-mr-generalizedTimeMatch
+}
+
+generalizedTimeOrderingMatch MATCHING-RULE ::= {
+ SYNTAX GeneralizedTime
+ -- as per 41.3 b) or c) of ITU-T Rec. X.680 | ISO/IEC 8824-1
+ ID id-mr-generalizedTimeOrderingMatch
+}
+
+integerFirstComponentMatch MATCHING-RULE ::= {
+ SYNTAX INTEGER
+ ID id-mr-integerFirstComponentMatch
+}
+
+objectIdentifierFirstComponentMatch MATCHING-RULE ::= {
+ SYNTAX OBJECT IDENTIFIER
+ ID id-mr-objectIdentifierFirstComponentMatch
+}
+
+directoryStringFirstComponentMatch MATCHING-RULE ::= {
+ SYNTAX DirectoryString {ub-directory-string-first-component-match}
+ ID id-mr-directoryStringFirstComponentMatch
+}
+
+wordMatch MATCHING-RULE ::= {
+ SYNTAX DirectoryString {ub-match}
+ ID id-mr-wordMatch
+}
+
+keywordMatch MATCHING-RULE ::= {
+ SYNTAX DirectoryString {ub-match}
+ ID id-mr-keywordMatch
+}
+
+systemProposedMatch MATCHING-RULE ::= {ID id-mr-systemProposedMatch
+}
+
+generalWordMatch MATCHING-RULE ::= {
+ SYNTAX SubstringAssertion
+ ID id-mr-generalWordMatch
+}
+
+sequenceMatchType ATTRIBUTE ::= {
+ WITH SYNTAX
+ ENUMERATED {sequenceExact(0), sequenceDeletion(1),
+ sequenceRestrictedDeletion(2), sequencePermutation(3),
+ sequencePermutationAndDeletion(4), sequenceProviderDefined(5)}
+ SINGLE VALUE TRUE
+ ID id-cat-sequenceMatchType
+} -- defaulting to sequenceExact,
+
+wordMatchTypes ATTRIBUTE ::= {
+ WITH SYNTAX
+ ENUMERATED {wordExact(0), wordTruncated(1), wordPhonetic(2),
+ wordProviderDefined(3)}
+ SINGLE VALUE TRUE
+ ID id-cat-wordMatchType
+} -- defaulting to wordExact
+
+characterMatchTypes ATTRIBUTE ::= {
+ WITH SYNTAX
+ ENUMERATED {characterExact(0), characterCaseIgnore(1), characterMapped(2)}
+ SINGLE VALUE TRUE
+ ID id-cat-characterMatchTypes
+}
+
+selectedContexts ATTRIBUTE ::= {
+ WITH SYNTAX ContextAssertion
+ ID id-cat-selectedContexts
+}
+
+approximateStringMatch MATCHING-RULE ::= {ID id-mr-approximateStringMatch
+}
+
+ignoreIfAbsentMatch MATCHING-RULE ::= {ID id-mr-ignoreIfAbsentMatch
+}
+
+nullMatch MATCHING-RULE ::= {ID id-mr-nullMatch
+}
+
+ZONAL-MATCHING ::=
+ MAPPING-BASED-MATCHING{ZonalSelect, TRUE, ZonalResult, zonalMatch.&id}
+
+ZonalSelect ::= SEQUENCE OF AttributeType
+
+ZonalResult ::= ENUMERATED {
+ cannot-select-mapping(0), zero-mappings(2), multiple-mappings(3)}
+
+zonalMatch MATCHING-RULE ::= {
+ UNIQUE-MATCH-INDICATOR multipleMatchingLocalities.&id
+ ID id-mr-zonalMatch
+}
+
+-- Contexts
+languageContext CONTEXT ::= {
+ WITH SYNTAX LanguageContextSyntax
+ ID id-avc-language
+}
+
+LanguageContextSyntax ::= PrintableString(SIZE (2..3)) -- ISO 639-2 codes only
+
+
+temporalContext CONTEXT ::= {
+ WITH SYNTAX TimeSpecification
+ ASSERTED AS TimeAssertion
+ ID id-avc-temporal
+}
+
+TimeSpecification ::= SEQUENCE {
+ time
+ CHOICE {absolute
+ SEQUENCE {startTime [0] GeneralizedTime OPTIONAL,
+ endTime [1] GeneralizedTime OPTIONAL},
+ periodic SET OF Period},
+ notThisTime BOOLEAN DEFAULT FALSE,
+ timeZone TimeZone OPTIONAL
+}
+
+Period ::= SEQUENCE {
+ timesOfDay [0] SET SIZE (1..MAX) OF DayTimeBand OPTIONAL,
+ days
+ [1] CHOICE {intDay SET OF INTEGER,
+ bitDay
+ BIT STRING {sunday(0), monday(1), tuesday(2), wednesday(3),
+ thursday(4), friday(5), saturday(6)},
+ dayOf XDayOf} OPTIONAL,
+ weeks
+ [2] CHOICE {allWeeks NULL,
+ intWeek SET OF INTEGER,
+ bitWeek
+ BIT STRING {week1(0), week2(1), week3(2), week4(3), week5(4)}
+ } OPTIONAL,
+ months
+ [3] CHOICE {allMonths NULL,
+ intMonth SET OF INTEGER,
+ bitMonth
+ BIT STRING {january(0), february(1), march(2), april(3),
+ may(4), june(5), july(6), august(7),
+ september(8), october(9), november(10),
+ december(11)}} OPTIONAL,
+ years [4] SET OF INTEGER(1000..MAX) OPTIONAL
+}
+
+XDayOf ::= CHOICE {
+ first [1] NamedDay,
+ second [2] NamedDay,
+ third [3] NamedDay,
+ fourth [4] NamedDay,
+ fifth [5] NamedDay
+}
+
+NamedDay ::= CHOICE {
+ intNamedDays
+ ENUMERATED {sunday(1), monday(2), tuesday(3), wednesday(4), thursday(5),
+ friday(6), saturday(7)},
+ bitNamedDays
+ BIT STRING {sunday(0), monday(1), tuesday(2), wednesday(3), thursday(4),
+ friday(5), saturday(6)}
+}
+
+DayTimeBand ::= SEQUENCE {
+ startDayTime [0] DayTime DEFAULT {hour 0},
+ endDayTime [1] DayTime DEFAULT {hour 23, minute 59, second 59}
+}
+
+DayTime ::= SEQUENCE {
+ hour [0] INTEGER(0..23),
+ minute [1] INTEGER(0..59) DEFAULT 0,
+ second [2] INTEGER(0..59) DEFAULT 0
+}
+
+TimeZone ::= INTEGER(-12..12)
+
+TimeAssertion ::= CHOICE {
+ now NULL,
+ at GeneralizedTime,
+ between
+ SEQUENCE {startTime [0] GeneralizedTime,
+ endTime [1] GeneralizedTime OPTIONAL,
+ entirely BOOLEAN DEFAULT FALSE}
+}
+
+localeContext CONTEXT ::= {
+ WITH SYNTAX LocaleContextSyntax
+ ID id-avc-locale
+}
+
+LocaleContextSyntax ::= CHOICE {
+ localeID1 OBJECT IDENTIFIER,
+ localeID2 DirectoryString{ub-localeContextSyntax}
+}
+
+-- Object identifier assignments -
+-- object identifiers assigned in other modules are shown in comments
+-- Attributes
+-- id-at-objectClass OBJECT IDENTIFIER ::= {id-at 0}
+-- id-at-aliasedEntryName OBJECT IDENTIFIER ::= {id-at 1}
+id-at-encryptedAliasedEntryName OBJECT IDENTIFIER ::=
+ {id-at 1 2}
+
+id-at-knowledgeInformation OBJECT IDENTIFIER ::= {id-at 2}
+
+id-at-commonName OBJECT IDENTIFIER ::= {id-at 3}
+
+id-at-encryptedCommonName OBJECT IDENTIFIER ::= {id-at 3 2}
+
+id-at-surname OBJECT IDENTIFIER ::= {id-at 4}
+
+id-at-encryptedSurname OBJECT IDENTIFIER ::= {id-at 4 2}
+
+id-at-serialNumber OBJECT IDENTIFIER ::= {id-at 5}
+
+id-at-encryptedSerialNumber OBJECT IDENTIFIER ::= {id-at 5 2}
+
+id-at-countryName OBJECT IDENTIFIER ::= {id-at 6}
+
+id-at-encryptedCountryName OBJECT IDENTIFIER ::= {id-at 6 2}
+
+id-at-localityName OBJECT IDENTIFIER ::= {id-at 7}
+
+id-at-encryptedLocalityName OBJECT IDENTIFIER ::= {id-at 7 2}
+
+id-at-collectiveLocalityName OBJECT IDENTIFIER ::= {id-at 7 1}
+
+id-at-encryptedCollectiveLocalityName OBJECT IDENTIFIER ::= {id-at 7 1 2}
+
+id-at-stateOrProvinceName OBJECT IDENTIFIER ::= {id-at 8}
+
+id-at-encryptedStateOrProvinceName OBJECT IDENTIFIER ::= {id-at 8 2}
+
+id-at-collectiveStateOrProvinceName OBJECT IDENTIFIER ::= {id-at 8 1}
+
+id-at-encryptedCollectiveStateOrProvinceName OBJECT IDENTIFIER ::=
+ {id-at 8 1 2}
+
+id-at-streetAddress OBJECT IDENTIFIER ::= {id-at 9}
+
+id-at-encryptedStreetAddress OBJECT IDENTIFIER ::= {id-at 9 2}
+
+id-at-collectiveStreetAddress OBJECT IDENTIFIER ::= {id-at 9 1}
+
+id-at-encryptedCollectiveStreetAddress OBJECT IDENTIFIER ::= {id-at 9 1 2}
+
+id-at-organizationName OBJECT IDENTIFIER ::= {id-at 10}
+
+id-at-encryptedOrganizationName OBJECT IDENTIFIER ::= {id-at 10 2}
+
+id-at-collectiveOrganizationName OBJECT IDENTIFIER ::= {id-at 10 1}
+
+id-at-encryptedCollectiveOrganizationName OBJECT IDENTIFIER ::= {id-at 10 1 2}
+
+id-at-organizationalUnitName OBJECT IDENTIFIER ::= {id-at 11}
+
+id-at-encryptedOrganizationalUnitName OBJECT IDENTIFIER ::= {id-at 11 2}
+
+id-at-collectiveOrganizationalUnitName OBJECT IDENTIFIER ::= {id-at 11 1}
+
+id-at-encryptedCollectiveOrganizationalUnitName OBJECT IDENTIFIER ::=
+ {id-at 11 1 2}
+
+id-at-title OBJECT IDENTIFIER ::= {id-at 12}
+
+id-at-encryptedTitle OBJECT IDENTIFIER ::= {id-at 12 2}
+
+id-at-description OBJECT IDENTIFIER ::= {id-at 13}
+
+id-at-encryptedDescription OBJECT IDENTIFIER ::= {id-at 13 2}
+
+id-at-searchGuide OBJECT IDENTIFIER ::= {id-at 14}
+
+id-at-encryptedSearchGuide OBJECT IDENTIFIER ::= {id-at 14 2}
+
+id-at-businessCategory OBJECT IDENTIFIER ::= {id-at 15}
+
+id-at-encryptedBusinessCategory OBJECT IDENTIFIER ::= {id-at 15 2}
+
+id-at-postalAddress OBJECT IDENTIFIER ::= {id-at 16}
+
+id-at-encryptedPostalAddress OBJECT IDENTIFIER ::= {id-at 16 2}
+
+id-at-collectivePostalAddress OBJECT IDENTIFIER ::= {id-at 16 1}
+
+id-at-encryptedCollectivePostalAddress OBJECT IDENTIFIER ::= {id-at 16 1 2}
+
+id-at-postalCode OBJECT IDENTIFIER ::= {id-at 17}
+
+id-at-encryptedPostalCode OBJECT IDENTIFIER ::= {id-at 17 2}
+
+id-at-collectivePostalCode OBJECT IDENTIFIER ::= {id-at 17 1}
+
+id-at-encryptedCollectivePostalCode OBJECT IDENTIFIER ::= {id-at 17 1 2}
+
+id-at-postOfficeBox OBJECT IDENTIFIER ::= {id-at 18}
+
+id-at-encryptedPostOfficeBox OBJECT IDENTIFIER ::= {id-at 18 2}
+
+id-at-collectivePostOfficeBox OBJECT IDENTIFIER ::= {id-at 18 1}
+
+id-at-encryptedCollectivePostOfficeBox OBJECT IDENTIFIER ::= {id-at 18 1 2}
+
+id-at-physicalDeliveryOfficeName OBJECT IDENTIFIER ::= {id-at 19}
+
+id-at-encryptedPhysicalDeliveryOfficeName OBJECT IDENTIFIER ::= {id-at 19 2}
+
+id-at-collectivePhysicalDeliveryOfficeName OBJECT IDENTIFIER ::= {id-at 19 1}
+
+id-at-encryptedCollectivePhysicalDeliveryOfficeName OBJECT IDENTIFIER ::=
+ {id-at 19 1 2}
+
+id-at-telephoneNumber OBJECT IDENTIFIER ::= {id-at 20}
+
+id-at-encryptedTelephoneNumber OBJECT IDENTIFIER ::= {id-at 20 2}
+
+id-at-collectiveTelephoneNumber OBJECT IDENTIFIER ::= {id-at 20 1}
+
+id-at-encryptedCollectiveTelephoneNumber OBJECT IDENTIFIER ::= {id-at 20 1 2}
+
+id-at-telexNumber OBJECT IDENTIFIER ::= {id-at 21}
+
+id-at-encryptedTelexNumber OBJECT IDENTIFIER ::= {id-at 21 2}
+
+id-at-collectiveTelexNumber OBJECT IDENTIFIER ::= {id-at 21 1}
+
+id-at-encryptedCollectiveTelexNumber OBJECT IDENTIFIER ::= {id-at 21 1 2}
+
+-- id-at-teletexTerminalIdentifier OBJECT IDENTIFIER ::= {id-at 22}
+-- id-at-encryptedTeletexTerminalIdentifier OBJECT IDENTIFIER ::= {id-at 22 2}
+-- id-at-collectiveTeletexTerminalIdentifier OBJECT IDENTIFIER ::= {id-at 22 1}
+-- id-at-encryptedCollectiveTeletexTerminalIdentifier
+-- OBJECT IDENTIFIER ::= {id-at 22 1 2}
+id-at-facsimileTelephoneNumber OBJECT IDENTIFIER ::=
+ {id-at 23}
+
+id-at-encryptedFacsimileTelephoneNumber OBJECT IDENTIFIER ::= {id-at 23 2}
+
+id-at-collectiveFacsimileTelephoneNumber OBJECT IDENTIFIER ::= {id-at 23 1}
+
+id-at-encryptedCollectiveFacsimileTelephoneNumber OBJECT IDENTIFIER ::=
+ {id-at 23 1 2}
+
+id-at-x121Address OBJECT IDENTIFIER ::= {id-at 24}
+
+id-at-encryptedX121Address OBJECT IDENTIFIER ::= {id-at 24 2}
+
+id-at-internationalISDNNumber OBJECT IDENTIFIER ::= {id-at 25}
+
+id-at-encryptedInternationalISDNNumber OBJECT IDENTIFIER ::= {id-at 25 2}
+
+id-at-collectiveInternationalISDNNumber OBJECT IDENTIFIER ::= {id-at 25 1}
+
+id-at-encryptedCollectiveInternationalISDNNumber OBJECT IDENTIFIER ::=
+ {id-at 25 1 2}
+
+id-at-registeredAddress OBJECT IDENTIFIER ::= {id-at 26}
+
+id-at-encryptedRegisteredAddress OBJECT IDENTIFIER ::= {id-at 26 2}
+
+id-at-destinationIndicator OBJECT IDENTIFIER ::= {id-at 27}
+
+id-at-encryptedDestinationIndicator OBJECT IDENTIFIER ::= {id-at 27 2}
+
+id-at-preferredDeliveryMethod OBJECT IDENTIFIER ::= {id-at 28}
+
+id-at-encryptedPreferredDeliveryMethod OBJECT IDENTIFIER ::= {id-at 28 2}
+
+id-at-presentationAddress OBJECT IDENTIFIER ::= {id-at 29}
+
+id-at-encryptedPresentationAddress OBJECT IDENTIFIER ::= {id-at 29 2}
+
+id-at-supportedApplicationContext OBJECT IDENTIFIER ::= {id-at 30}
+
+id-at-encryptedSupportedApplicationContext OBJECT IDENTIFIER ::= {id-at 30 2}
+
+id-at-member OBJECT IDENTIFIER ::= {id-at 31}
+
+id-at-encryptedMember OBJECT IDENTIFIER ::= {id-at 31 2}
+
+id-at-owner OBJECT IDENTIFIER ::= {id-at 32}
+
+id-at-encryptedOwner OBJECT IDENTIFIER ::= {id-at 32 2}
+
+id-at-roleOccupant OBJECT IDENTIFIER ::= {id-at 33}
+
+id-at-encryptedRoleOccupant OBJECT IDENTIFIER ::= {id-at 33 2}
+
+id-at-seeAlso OBJECT IDENTIFIER ::= {id-at 34}
+
+id-at-encryptedSeeAlso OBJECT IDENTIFIER ::= {id-at 34 2}
+
+-- id-at-userPassword OBJECT IDENTIFIER ::= {id-at 35}
+id-at-encryptedUserPassword OBJECT IDENTIFIER ::=
+ {id-at 35 2}
+
+-- id-at-userCertificate OBJECT IDENTIFIER ::= {id-at 36}
+id-at-encryptedUserCertificate OBJECT IDENTIFIER ::=
+ {id-at 36 2}
+
+-- id-at-cACertificate OBJECT IDENTIFIER ::= {id-at 37}
+id-at-encryptedCACertificate OBJECT IDENTIFIER ::=
+ {id-at 37 2}
+
+-- id-at-authorityRevocationList OBJECT IDENTIFIER ::= {id-at 38}
+id-at-encryptedAuthorityRevocationList OBJECT IDENTIFIER ::=
+ {id-at 38 2}
+
+-- id-at-certificateRevocationList OBJECT IDENTIFIER ::= {id-at 39}
+id-at-encryptedCertificateRevocationList OBJECT IDENTIFIER ::=
+ {id-at 39 2}
+
+-- id-at-crossCertificatePair OBJECT IDENTIFIER ::= {id-at 40}
+id-at-encryptedCrossCertificatePair OBJECT IDENTIFIER ::=
+ {id-at 40 2}
+
+id-at-name OBJECT IDENTIFIER ::= {id-at 41}
+
+id-at-givenName OBJECT IDENTIFIER ::= {id-at 42}
+
+id-at-encryptedGivenName OBJECT IDENTIFIER ::= {id-at 42 2}
+
+id-at-initials OBJECT IDENTIFIER ::= {id-at 43}
+
+id-at-encryptedInitials OBJECT IDENTIFIER ::= {id-at 43 2}
+
+id-at-generationQualifier OBJECT IDENTIFIER ::= {id-at 44}
+
+id-at-encryptedGenerationQualifier OBJECT IDENTIFIER ::= {id-at 44 2}
+
+id-at-uniqueIdentifier OBJECT IDENTIFIER ::= {id-at 45}
+
+id-at-encryptedUniqueIdentifier OBJECT IDENTIFIER ::= {id-at 45 2}
+
+id-at-dnQualifier OBJECT IDENTIFIER ::= {id-at 46}
+
+id-at-encryptedDnQualifier OBJECT IDENTIFIER ::= {id-at 46 2}
+
+id-at-enhancedSearchGuide OBJECT IDENTIFIER ::= {id-at 47}
+
+id-at-encryptedEnhancedSearchGuide OBJECT IDENTIFIER ::= {id-at 47 2}
+
+id-at-protocolInformation OBJECT IDENTIFIER ::= {id-at 48}
+
+id-at-encryptedProtocolInformation OBJECT IDENTIFIER ::= {id-at 48 2}
+
+id-at-distinguishedName OBJECT IDENTIFIER ::= {id-at 49}
+
+id-at-encryptedDistinguishedName OBJECT IDENTIFIER ::= {id-at 49 2}
+
+id-at-uniqueMember OBJECT IDENTIFIER ::= {id-at 50}
+
+id-at-encryptedUniqueMember OBJECT IDENTIFIER ::= {id-at 50 2}
+
+id-at-houseIdentifier OBJECT IDENTIFIER ::= {id-at 51}
+
+id-at-encryptedHouseIdentifier OBJECT IDENTIFIER ::= {id-at 51 2}
+
+--id-at-supportedAlgorithms OBJECT IDENTIFIER ::= {id-at 52}
+id-at-encryptedSupportedAlgorithms OBJECT IDENTIFIER ::=
+ {id-at 52 2}
+
+--id-at-deltaRevocationList OBJECT IDENTIFIER ::= {id-at 53}
+id-at-encryptedDeltaRevocationList OBJECT IDENTIFIER ::=
+ {id-at 53 2}
+
+id-at-dmdName OBJECT IDENTIFIER ::= {id-at 54}
+
+id-at-encryptedDmdName OBJECT IDENTIFIER ::= {id-at 54 2}
+
+-- id-at-clearance OBJECT IDENTIFIER ::= {id-at 55}
+id-at-encryptedClearance OBJECT IDENTIFIER ::=
+ {id-at 55 2}
+
+-- id-at-defaultDirQop OBJECT IDENTIFIER ::= {id-at 56}
+id-at-encryptedDefaultDirQop OBJECT IDENTIFIER ::=
+ {id-at 56 2}
+
+-- id-at-attributeIntegrityInfo OBJECT IDENTIFIER ::= {id-at 57}
+id-at-encryptedAttributeIntegrityInfo OBJECT IDENTIFIER ::=
+ {id-at 57 2}
+
+--id-at-attributeCertificate OBJECT IDENTIFIER ::= {id-at 58}
+id-at-encryptedAttributeCertificate OBJECT IDENTIFIER ::=
+ {id-at 58 2}
+
+-- id-at-attributeCertificateRevocationList OBJECT IDENTIFIER ::= {id-at 59}
+id-at-encryptedAttributeCertificateRevocationList OBJECT IDENTIFIER ::=
+ {id-at 59 2}
+
+-- id-at-confKeyInfo OBJECT IDENTIFIER ::= {id-at 60}
+id-at-encryptedConfKeyInfo OBJECT IDENTIFIER ::=
+ {id-at 60 2}
+
+-- id-at-family-information OBJECT IDENTIFIER {id-at 64}
+id-at-pseudonym OBJECT IDENTIFIER ::=
+ {id-at 65}
+
+id-at-communicationsService OBJECT IDENTIFIER ::= {id-at 66}
+
+id-at-communicationsNetwork OBJECT IDENTIFIER ::= {id-at 67}
+
+-- Matching rules
+-- id-mr-objectIdentifierMatch OBJECT IDENTIFIER ::= {id-mr 0}
+-- id-mr-distinguishedNameMatch OBJECT IDENTIFIER ::= {id-mr 1}
+id-mr-caseIgnoreMatch OBJECT IDENTIFIER ::=
+ {id-mr 2}
+
+id-mr-caseIgnoreOrderingMatch OBJECT IDENTIFIER ::= {id-mr 3}
+
+id-mr-caseIgnoreSubstringsMatch OBJECT IDENTIFIER ::= {id-mr 4}
+
+id-mr-caseExactMatch OBJECT IDENTIFIER ::= {id-mr 5}
+
+id-mr-caseExactOrderingMatch OBJECT IDENTIFIER ::= {id-mr 6}
+
+id-mr-caseExactSubstringsMatch OBJECT IDENTIFIER ::= {id-mr 7}
+
+id-mr-numericStringMatch OBJECT IDENTIFIER ::= {id-mr 8}
+
+id-mr-numericStringOrderingMatch OBJECT IDENTIFIER ::= {id-mr 9}
+
+id-mr-numericStringSubstringsMatch OBJECT IDENTIFIER ::= {id-mr 10}
+
+id-mr-caseIgnoreListMatch OBJECT IDENTIFIER ::= {id-mr 11}
+
+id-mr-caseIgnoreListSubstringsMatch OBJECT IDENTIFIER ::= {id-mr 12}
+
+id-mr-booleanMatch OBJECT IDENTIFIER ::= {id-mr 13}
+
+id-mr-integerMatch OBJECT IDENTIFIER ::= {id-mr 14}
+
+id-mr-integerOrderingMatch OBJECT IDENTIFIER ::= {id-mr 15}
+
+id-mr-bitStringMatch OBJECT IDENTIFIER ::= {id-mr 16}
+
+id-mr-octetStringMatch OBJECT IDENTIFIER ::= {id-mr 17}
+
+id-mr-octetStringOrderingMatch OBJECT IDENTIFIER ::= {id-mr 18}
+
+id-mr-octetStringSubstringsMatch OBJECT IDENTIFIER ::= {id-mr 19}
+
+id-mr-telephoneNumberMatch OBJECT IDENTIFIER ::= {id-mr 20}
+
+id-mr-telephoneNumberSubstringsMatch OBJECT IDENTIFIER ::= {id-mr 21}
+
+id-mr-presentationAddressMatch OBJECT IDENTIFIER ::= {id-mr 22}
+
+id-mr-uniqueMemberMatch OBJECT IDENTIFIER ::= {id-mr 23}
+
+id-mr-protocolInformationMatch OBJECT IDENTIFIER ::= {id-mr 24}
+
+id-mr-uTCTimeMatch OBJECT IDENTIFIER ::= {id-mr 25}
+
+id-mr-uTCTimeOrderingMatch OBJECT IDENTIFIER ::= {id-mr 26}
+
+id-mr-generalizedTimeMatch OBJECT IDENTIFIER ::= {id-mr 27}
+
+id-mr-generalizedTimeOrderingMatch OBJECT IDENTIFIER ::= {id-mr 28}
+
+id-mr-integerFirstComponentMatch OBJECT IDENTIFIER ::= {id-mr 29}
+
+id-mr-objectIdentifierFirstComponentMatch OBJECT IDENTIFIER ::= {id-mr 30}
+
+id-mr-directoryStringFirstComponentMatch OBJECT IDENTIFIER ::= {id-mr 31}
+
+id-mr-wordMatch OBJECT IDENTIFIER ::= {id-mr 32}
+
+id-mr-keywordMatch OBJECT IDENTIFIER ::= {id-mr 33}
+
+-- id-mr-certificateExactMatch OBJECT IDENTIFIER ::= {id-mr 34}
+-- id-mr-certificateMatch OBJECT IDENTIFIER ::= {id-mr 35}
+-- id-mr-certificatePairExactMatch OBJECT IDENTIFIER ::= {id-mr 36}
+-- id-mr-certificatePairMatch OBJECT IDENTIFIER ::= {id-mr 37}
+-- id-mr-certificateListExactMatch OBJECT IDENTIFIER ::= {id-mr 38}
+-- id-mr-certificateListMatch OBJECT IDENTIFIER ::= {id-mr 39}
+-- id-mr-algorithmIdentifierMatch OBJECT IDENTIFIER ::= {id-mr 40}
+id-mr-storedPrefixMatch OBJECT IDENTIFIER ::=
+ {id-mr 41}
+
+-- id-mr-attributeCertificateMatch OBJECT IDENTIFIER ::= {id-mr 42}
+-- id-mr-readerAndKeyIDMatch OBJECT IDENTIFIER ::= {id-mr 43}
+--id-mr-attributeIntegrityMatch OBJECT IDENTIFIER ::= {id-mr 44}
+id-mr-systemProposedMatch OBJECT IDENTIFIER ::=
+ {id-mr 47}
+
+id-mr-generalWordMatch OBJECT IDENTIFIER ::= {id-mr 48}
+
+id-mr-approximateStringMatch OBJECT IDENTIFIER ::= {id-mr 49}
+
+id-mr-ignoreIfAbsentMatch OBJECT IDENTIFIER ::= {id-mr 50}
+
+id-mr-nullMatch OBJECT IDENTIFIER ::= {id-mr 51}
+
+id-mr-zonalMatch OBJECT IDENTIFIER ::= {id-mr 52}
+
+id-mr-facsimileNumberMatch OBJECT IDENTIFIER ::= {id-mr 63}
+
+id-mr-facsimileNumberSubstringsMatch OBJECT IDENTIFIER ::= {id-mr 64}
+
+-- contexts
+id-avc-language OBJECT IDENTIFIER ::= {id-avc 0}
+
+id-avc-temporal OBJECT IDENTIFIER ::= {id-avc 1}
+
+id-avc-locale OBJECT IDENTIFIER ::= {id-avc 2}
+
+--id-avc-attributeValueSecurityLabelContext OBJECT IDENTIFIER ::= {id-avc 3}
+--id-avc-attributeValueIntegrityInfoContext OBJECT IDENTIFIER ::= {id-avc 4}
+-- Problem definitions
+id-pr-targetDsaUnavailable OBJECT IDENTIFIER ::=
+ {id-pr 1}
+
+id-pr-dataSourceUnavailable OBJECT IDENTIFIER ::= {id-pr 2}
+
+id-pr-unidentifiedOperation OBJECT IDENTIFIER ::= {id-pr 3}
+
+id-pr-unavailableOperation OBJECT IDENTIFIER ::= {id-pr 4}
+
+id-pr-searchAttributeViolation OBJECT IDENTIFIER ::= {id-pr 5}
+
+id-pr-searchAttributeCombinationViolation OBJECT IDENTIFIER ::= {id-pr 6}
+
+id-pr-searchValueNotAllowed OBJECT IDENTIFIER ::= {id-pr 7}
+
+id-pr-missingSearchAttribute OBJECT IDENTIFIER ::= {id-pr 8}
+
+id-pr-searchValueViolation OBJECT IDENTIFIER ::= {id-pr 9}
+
+id-pr-attributeNegationViolation OBJECT IDENTIFIER ::= {id-pr 10}
+
+id-pr-searchValueRequired OBJECT IDENTIFIER ::= {id-pr 11}
+
+id-pr-invalidSearchValue OBJECT IDENTIFIER ::= {id-pr 12}
+
+id-pr-searchContextViolation OBJECT IDENTIFIER ::= {id-pr 13}
+
+id-pr-searchContextCombinationViolation OBJECT IDENTIFIER ::= {id-pr 14}
+
+id-pr-missingSearchContext OBJECT IDENTIFIER ::= {id-pr 15}
+
+id-pr-searchContextValueViolation OBJECT IDENTIFIER ::= {id-pr 16}
+
+id-pr-searchContextValueRequired OBJECT IDENTIFIER ::= {id-pr 17}
+
+id-pr-invalidContextSearchValue OBJECT IDENTIFIER ::= {id-pr 18}
+
+id-pr-unsupportedMatchingRule OBJECT IDENTIFIER ::= {id-pr 19}
+
+id-pr-attributeMatchingViolation OBJECT IDENTIFIER ::= {id-pr 20}
+
+id-pr-unsupportedMatchingUse OBJECT IDENTIFIER ::= {id-pr 21}
+
+id-pr-matchingUseViolation OBJECT IDENTIFIER ::= {id-pr 22}
+
+id-pr-hierarchySelectForbidden OBJECT IDENTIFIER ::= {id-pr 23}
+
+id-pr-invalidHierarchySelect OBJECT IDENTIFIER ::= {id-pr 24}
+
+id-pr-unavailableHierarchySelect OBJECT IDENTIFIER ::= {id-pr 25}
+
+id-pr-invalidSearchOptions OBJECT IDENTIFIER ::= {id-pr 26}
+
+id-pr-missingSearchOptions OBJECT IDENTIFIER ::= {id-pr 27}
+
+id-pr-invalidServiceControlOptions OBJECT IDENTIFIER ::= {id-pr 28}
+
+id-pr-missingServiceControlOptions OBJECT IDENTIFIER ::= {id-pr 29}
+
+id-pr-searchSubsetViolation OBJECT IDENTIFIER ::= {id-pr 30}
+
+id-pr-unmatchedKeyAttributes OBJECT IDENTIFIER ::= {id-pr 31}
+
+id-pr-ambiguousKeyAttributes OBJECT IDENTIFIER ::= {id-pr 32}
+
+-- Notification attributes
+id-not-dSAProblem OBJECT IDENTIFIER ::= {id-not 0}
+
+id-not-searchServiceProblem OBJECT IDENTIFIER ::= {id-not 1}
+
+id-not-serviceType OBJECT IDENTIFIER ::= {id-not 2}
+
+id-not-attributeTypeList OBJECT IDENTIFIER ::= {id-not 3}
+
+id-not-matchingRuleList OBJECT IDENTIFIER ::= {id-not 4}
+
+id-not-filterItem OBJECT IDENTIFIER ::= {id-not 5}
+
+id-not-attributeCombinations OBJECT IDENTIFIER ::= {id-not 6}
+
+id-not-contextTypeList OBJECT IDENTIFIER ::= {id-not 7}
+
+id-not-contextList OBJECT IDENTIFIER ::= {id-not 8}
+
+id-not-contextCombinations OBJECT IDENTIFIER ::= {id-not 9}
+
+id-not-hierarchySelectList OBJECT IDENTIFIER ::= {id-not 10}
+
+id-not-searchOptionsList OBJECT IDENTIFIER ::= {id-not 11}
+
+id-not-serviceControlOptionsList OBJECT IDENTIFIER ::= {id-not 12}
+
+id-not-multipleMatchingLocalities OBJECT IDENTIFIER ::= {id-not 13}
+
+id-not-proposedRelaxation OBJECT IDENTIFIER ::= {id-not 14}
+
+id-not-appliedRelaxation OBJECT IDENTIFIER ::= {id-not 15}
+
+id-not-substringRequirements OBJECT IDENTIFIER ::= {id-not 16}
+
+-- Control attributes
+id-cat-sequenceMatchType OBJECT IDENTIFIER ::=
+ {id-cat 1}
+
+id-cat-wordMatchType OBJECT IDENTIFIER ::= {id-cat 2}
+
+id-cat-characterMatchTypes OBJECT IDENTIFIER ::= {id-cat 3}
+
+id-cat-selectedContexts OBJECT IDENTIFIER ::= {id-cat 4}
+
+END -- SelectedAttributeTypes
+
+-- Generated by Asnp, the ASN.1 pretty-printer of France Telecom R&D
+
diff --git a/lib/asn1/test/asn1_SUITE_data/modified_x420/UpperBounds.asn b/lib/asn1/test/asn1_SUITE_data/modified_x420/UpperBounds.asn
new file mode 100644
index 0000000000..37890f8b49
--- /dev/null
+++ b/lib/asn1/test/asn1_SUITE_data/modified_x420/UpperBounds.asn
@@ -0,0 +1,89 @@
+-- Module UpperBounds (X.520:08/1997)
+
+UpperBounds {joint-iso-itu-t ds(5) module(1) upperBounds(10) 3} DEFINITIONS ::=
+BEGIN
+
+-- EXPORTS All
+-- The types and values defined in this module are exported for use in the other ASN.1 modules contained
+-- within the Directory Specifications, and for the use of other applications which will use them to access
+-- Directory services. Other applications may use them for their own purposes, but this will not constrain
+-- extensions and modifications needed to maintain or improve the Directory service.
+ub-answerback INTEGER ::=
+ 8
+
+ub-business-category INTEGER ::= 128
+
+ub-common-name INTEGER ::= 64
+
+ub-country-code INTEGER ::= 4
+
+ub-description INTEGER ::= 1024
+
+ub-destination-indicator INTEGER ::= 128
+
+ub-directory-string-first-component-match INTEGER ::= 32768
+
+ub-international-isdn-number INTEGER ::= 16
+
+ub-knowledge-information INTEGER ::= 32768
+
+ub-locality-name INTEGER ::= 128
+
+ub-match INTEGER ::= 128
+
+ub-name INTEGER ::= 64
+
+ub-organization-name INTEGER ::= 64
+
+ub-organizational-unit-name INTEGER ::= 64
+
+ub-physical-office-name INTEGER ::= 128
+
+ub-post-office-box INTEGER ::= 40
+
+ub-postal-code INTEGER ::= 40
+
+ub-postal-line INTEGER ::= 6
+
+ub-postal-string INTEGER ::= 30
+
+ub-privacy-mark-length INTEGER ::= 128
+
+ub-schema INTEGER ::= 1024
+
+ub-search INTEGER ::= 32768
+
+ub-serial-number INTEGER ::= 64
+
+ub-state-name INTEGER ::= 128
+
+ub-street-address INTEGER ::= 128
+
+ub-surname INTEGER ::= 64
+
+ub-tag INTEGER ::= 64
+
+ub-telephone-number INTEGER ::= 32
+
+ub-teletex-terminal-id INTEGER ::= 1024
+
+ub-telex-number INTEGER ::= 14
+
+ub-title INTEGER ::= 64
+
+ub-user-password INTEGER ::= 128
+
+ub-x121-address INTEGER ::= 15
+
+ub-localeContextSyntax INTEGER ::= 128
+
+ub-locale-context-syntax INTEGER ::= 64
+
+ub-pseudonym INTEGER ::= 128
+
+ub-content INTEGER ::= 32768
+
+END -- UpperBounds
+
+-- Generated by Asnp, the ASN.1 pretty-printer of France Telecom R&D
+
diff --git a/lib/asn1/test/asn1_SUITE_data/modified_x420/UsefulDefinitions.asn b/lib/asn1/test/asn1_SUITE_data/modified_x420/UsefulDefinitions.asn
new file mode 100644
index 0000000000..d9601bb7d0
--- /dev/null
+++ b/lib/asn1/test/asn1_SUITE_data/modified_x420/UsefulDefinitions.asn
@@ -0,0 +1,238 @@
+-- Module UsefulDefinitions (X.501:08/1997)
+UsefulDefinitions {joint-iso-itu-t ds(5) module(1) usefulDefinitions(0) 3}
+DEFINITIONS ::=
+BEGIN
+
+-- EXPORTS All -
+-- The types and values defined in this module are exported for use in the other ASN.1 modules contained
+-- within the Directory Specifications, and for the use of other applications which will use them to access
+-- Directory services. Other applications may use them for their own purposes, but this will not constrain
+-- extensions and modifications needed to maintain or improve the Directory service.
+ID ::= OBJECT IDENTIFIER
+
+ds ID ::= {joint-iso-itu-t ds(5)}
+
+-- categories of information object
+module ID ::= {ds 1}
+
+serviceElement ID ::= {ds 2}
+
+applicationContext ID ::= {ds 3}
+
+attributeType ID ::= {ds 4}
+
+attributeSyntax ID ::= {ds 5}
+
+objectClass ID ::= {ds 6}
+
+-- attributeSet ID ::= {ds 7}
+algorithm ID ::= {ds 8}
+
+abstractSyntax ID ::= {ds 9}
+
+-- object ID ::= {ds 10}
+-- port ID ::= {ds 11}
+dsaOperationalAttribute ID ::=
+ {ds 12}
+
+matchingRule ID ::= {ds 13}
+
+knowledgeMatchingRule ID ::= {ds 14}
+
+nameForm ID ::= {ds 15}
+
+group ID ::= {ds 16}
+
+subentry ID ::= {ds 17}
+
+operationalAttributeType ID ::= {ds 18}
+
+operationalBinding ID ::= {ds 19}
+
+schemaObjectClass ID ::= {ds 20}
+
+schemaOperationalAttribute ID ::= {ds 21}
+
+administrativeRoles ID ::= {ds 23}
+
+accessControlAttribute ID ::= {ds 24}
+
+rosObject ID ::= {ds 25}
+
+contract ID ::= {ds 26}
+
+package ID ::= {ds 27}
+
+accessControlSchemes ID ::= {ds 28}
+
+certificateExtension ID ::= {ds 29}
+
+managementObject ID ::= {ds 30}
+
+attributeValueContext ID ::= {ds 31}
+
+-- securityExchange ID ::= {ds 32}
+idmProtocol ID ::= {ds 33}
+
+problem ID ::= {ds 34}
+
+notification ID ::= {ds 35}
+
+matchingRestriction ID ::=
+ {ds 36} -- None are currently defined by this specification
+
+controlAttributeType ID ::= {ds 37}
+
+-- modules
+usefulDefinitions ID ::= {module usefulDefinitions(0) 3}
+
+informationFramework ID ::= {module informationFramework(1) 3}
+
+directoryAbstractService ID ::= {module directoryAbstractService(2) 3}
+
+distributedOperations ID ::= {module distributedOperations(3) 3}
+
+protocolObjectIdentifiers ID ::= {module protocolObjectIdentifiers(4) 3}
+
+selectedAttributeTypes ID ::= {module selectedAttributeTypes(5) 3}
+
+selectedObjectClasses ID ::= {module selectedObjectClasses(6) 3}
+
+authenticationFramework ID ::= {module authenticationFramework(7) 3}
+
+algorithmObjectIdentifiers ID ::= {module algorithmObjectIdentifiers(8) 3}
+
+directoryObjectIdentifiers ID ::= {module directoryObjectIdentifiers(9) 3}
+
+upperBounds ID ::= {module upperBounds(10) 3}
+
+dap ID ::= {module dap(11) 3}
+
+dsp ID ::= {module dsp(12) 3}
+
+distributedDirectoryOIDs ID ::= {module distributedDirectoryOIDs(13) 3}
+
+directoryShadowOIDs ID ::= {module directoryShadowOIDs(14) 3}
+
+directoryShadowAbstractService ID ::=
+ {module directoryShadowAbstractService(15) 3}
+
+disp ID ::= {module disp(16) 3}
+
+dop ID ::= {module dop(17) 3}
+
+opBindingManagement ID ::= {module opBindingManagement(18) 3}
+
+opBindingOIDs ID ::= {module opBindingOIDs(19) 3}
+
+hierarchicalOperationalBindings ID ::=
+ {module hierarchicalOperationalBindings(20) 3}
+
+dsaOperationalAttributeTypes ID ::= {module dsaOperationalAttributeTypes(22) 3}
+
+schemaAdministration ID ::= {module schemaAdministration(23) 3}
+
+basicAccessControl ID ::= {module basicAccessControl(24) 3}
+
+directoryOperationalBindingTypes ID ::=
+ {module directoryOperationalBindingTypes(25) 3}
+
+certificateExtensions ID ::= {module certificateExtensions(26) 0}
+
+directoryManagement ID ::= {module directoryManagement(27) 1}
+
+enhancedSecurity ID ::= {module enhancedSecurity(28) 1}
+
+iDMProtocolSpecification ID ::= {module iDMProtocolSpecification(30) 4}
+
+directoryIDMProtocols ID ::= {module directoryIDMProtocols(31) 4}
+
+-- directorySecurityExchanges ID ::= {module directorySecurityExchanges (29) 1}
+-- synonyms
+id-oc ID ::=
+ objectClass
+
+id-at ID ::= attributeType
+
+id-as ID ::= abstractSyntax
+
+id-mr ID ::= matchingRule
+
+id-nf ID ::= nameForm
+
+id-sc ID ::= subentry
+
+id-oa ID ::= operationalAttributeType
+
+id-ob ID ::= operationalBinding
+
+id-doa ID ::= dsaOperationalAttribute
+
+id-kmr ID ::= knowledgeMatchingRule
+
+id-soc ID ::= schemaObjectClass
+
+id-soa ID ::= schemaOperationalAttribute
+
+id-ar ID ::= administrativeRoles
+
+id-aca ID ::= accessControlAttribute
+
+id-ac ID ::= applicationContext
+
+id-rosObject ID ::= rosObject
+
+id-contract ID ::= contract
+
+id-package ID ::= package
+
+id-acScheme ID ::= accessControlSchemes
+
+id-ce ID ::= certificateExtension
+
+id-mgt ID ::= managementObject
+
+id-idm ID ::= idmProtocol
+
+id-avc ID ::= attributeValueContext
+
+-- id-se ID ::= securityExchange
+id-pr ID ::= problem
+
+id-not ID ::= notification
+
+id-mre ID ::= matchingRestriction
+
+id-cat ID ::= controlAttributeType
+
+-- obsolete module identifiers
+-- usefulDefinition ID ::= {module 0}
+-- informationFramework ID ::= {module 1}
+-- directoryAbstractService ID ::= {module 2}
+-- distributedOperations ID ::= {module 3}
+-- protocolObjectIdentifiers ID ::= {module 4}
+-- selectedAttributeTypes ID ::= {module 5}
+-- selectedObjectClasses ID ::= {module 6}
+-- authenticationFramework ID ::= {module 7}
+-- algorithmObjectIdentifiers ID ::= {module 8}
+-- directoryObjectIdentifiers ID ::= {module 9}
+-- upperBounds ID ::= {module 10}
+-- dap ID ::= {module 11}
+-- dsp ID ::= {module 12}
+-- distributedDirectoryObjectIdentifiers ID ::= {module 13}
+-- unused module identifiers
+-- directoryShadowOIDs ID ::= {module 14}
+-- directoryShadowAbstractService ID ::= {module 15}
+-- disp ID ::= {module 16}
+-- dop ID ::= {module 17}
+-- opBindingManagement ID ::= {module 18}
+-- opBindingOIDs ID ::= {module 19}
+-- hierarchicalOperationalBindings ID ::= {module 20}
+-- dsaOperationalAttributeTypes ID ::= {module 22}
+-- schemaAdministration ID ::= {module 23}
+-- basicAccessControl ID ::= {module 24}
+-- operationalBindingOIDs ID ::= {module 25}
+END -- UsefulDefinitions
+
+-- Generated by Asnp, the ASN.1 pretty-printer of France Telecom R&D
+
diff --git a/lib/asn1/test/asn1_SUITE_data/modified_x420/p7_signed_data.pem b/lib/asn1/test/asn1_SUITE_data/modified_x420/p7_signed_data.pem
new file mode 100644
index 0000000000..fc6bdebd8b
--- /dev/null
+++ b/lib/asn1/test/asn1_SUITE_data/modified_x420/p7_signed_data.pem
@@ -0,0 +1,23 @@
+-----BEGIN PKCS7-----
+MIIDxQYJKoZIhvcNAQcCoIIDtjCCA7ICAQExCzAJBgUrDgMCGgUAMBoGCSqGSIb3
+DQEHAaANBAtwbGFpbiB0ZXh0CqCCAeMwggHfMIIBSAIJAKB+Sm2O7vxbMA0GCSqG
+SIb3DQEBBAUAMDQxCzAJBgNVBAYTAlNFMRQwEgYDVQQKEwtFcmljc3NvbiBBQjEP
+MA0GA1UECxMGTkVUU2ltMB4XDTA4MDIyOTE1MzEwMFoXDTE4MDIyNjE1MzEwMFow
+NDELMAkGA1UEBhMCU0UxFDASBgNVBAoTC0VyaWNzc29uIEFCMQ8wDQYDVQQLEwZO
+RVRTaW0wgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAM2EtqGq/lu0DdUfexOk
+X4icontyAFXqJL8TRtsL4tSTleQiHICH+glBpJ1Grk/x5YV6Fke49hSBHhG3J8A7
+CpicAmXTiZR2LGvdLoO2HEwItlR9IaFICsr2/piHzB/ZWnu0uzeHBQW3gJNGG21V
+KltZapcBew3jNG8wdPdykPpnAgMBAAEwDQYJKoZIhvcNAQEEBQADgYEAK//FOT1m
+KamyWjwWs1hzmngpqmvQAR4CcD3F5jtbwz8bNZtfoRr1VnJktZhorVb5uWPfahH2
+qnvJEX8EtoY7un8O3N1sJFVFcTkEIz2THalYZG6bQ8owqr4s3vZ3XoOBD5ukVwjE
+sVdDSa4b713tiHCsWoGca7cn6i6y6s/oDpwxggGbMIIBlwIBATBBMDQxCzAJBgNV
+BAYTAlNFMRQwEgYDVQQKEwtFcmljc3NvbiBBQjEPMA0GA1UECxMGTkVUU2ltAgkA
+oH5KbY7u/FswCQYFKw4DAhoFAKCBsTAYBgkqhkiG9w0BCQMxCwYJKoZIhvcNAQcB
+MBwGCSqGSIb3DQEJBTEPFw0wODAyMjkxNTMxMDFaMCMGCSqGSIb3DQEJBDEWBBQF
+/OBF9SkVcUzcMGOVsg3QKX/hGTBSBgkqhkiG9w0BCQ8xRTBDMAoGCCqGSIb3DQMH
+MA4GCCqGSIb3DQMCAgIAgDANBggqhkiG9w0DAgIBQDAHBgUrDgMCBzANBggqhkiG
+9w0DAgIBKDANBgkqhkiG9w0BAQEFAASBgEA7LwwdYP7LMMAoBl7qX+XMF66c5stq
+e9f2BpGsFGqhfDac+tmnCkRu1clr9VUld0DSuw+Qc3oUnpix/Vo5mwmbQ19iR/f9
+oBmm85iZMBDy8vScS6Vm7u+mHvQ9d4iNNS7MDQ8peEu9ItxWe1x3LuCAMbvGMiXE
+75U3Iy4ZYCq4
+-----END PKCS7-----
diff --git a/lib/asn1/test/asn1_SUITE_data/nbapsystem/NBAP-CommonDataTypes.asn b/lib/asn1/test/asn1_SUITE_data/nbapsystem/NBAP-CommonDataTypes.asn
new file mode 100755
index 0000000000..e3f6e83d6b
--- /dev/null
+++ b/lib/asn1/test/asn1_SUITE_data/nbapsystem/NBAP-CommonDataTypes.asn
@@ -0,0 +1,58 @@
+-- **************************************************************
+--
+-- Common definitions
+--
+-- **************************************************************
+
+NBAP-CommonDataTypes {
+itu-t (0) identified-organization (4) etsi (0) mobileDomain (0)
+umts-Access (20) modules (3) nbap (2) version1 (1) nbap-CommonDataTypes (3) }
+
+DEFINITIONS AUTOMATIC TAGS ::=
+
+BEGIN
+
+-- **************************************************************
+--
+-- Extension constants
+--
+-- **************************************************************
+
+maxPrivateIEs INTEGER ::= 65535
+maxProtocolExtensions INTEGER ::= 65535
+maxProtocolIEs INTEGER ::= 65535
+
+-- **************************************************************
+--
+-- Common Data Types
+--
+-- **************************************************************
+
+Criticality ::= ENUMERATED { reject, ignore, notify }
+
+MessageDiscriminator ::= ENUMERATED { common, dedicated }
+
+Presence ::= ENUMERATED { optional, conditional, mandatory }
+
+PrivateIE-ID ::= CHOICE {
+ local INTEGER (0..maxPrivateIEs),
+ global OBJECT IDENTIFIER
+}
+
+ProcedureCode ::= INTEGER (0..255)
+
+ProcedureID ::= SEQUENCE {
+ procedureCode ProcedureCode,
+ ddMode ENUMERATED { tdd, fdd, common, ... }
+}
+
+ProtocolIE-ID ::= INTEGER (0..maxProtocolIEs)
+
+TransactionID ::= CHOICE {
+ shortTransActionId INTEGER (0..127),
+ longTransActionId INTEGER (0..32767)
+}
+
+TriggeringMessage ::= ENUMERATED { initiating-message, successful-outcome, unsuccessfull-outcome, outcome }
+
+END
diff --git a/lib/asn1/test/asn1_SUITE_data/nbapsystem/NBAP-Constants.asn b/lib/asn1/test/asn1_SUITE_data/nbapsystem/NBAP-Constants.asn
new file mode 100755
index 0000000000..1411d455b7
--- /dev/null
+++ b/lib/asn1/test/asn1_SUITE_data/nbapsystem/NBAP-Constants.asn
@@ -0,0 +1,688 @@
+-- **************************************************************
+--
+-- Constant definitions
+--
+-- **************************************************************
+
+NBAP-Constants {
+itu-t (0) identified-organization (4) etsi (0) mobileDomain (0)
+umts-Access (20) modules (3) nbap (2) version1 (1) nbap-Constants (4)}
+
+DEFINITIONS AUTOMATIC TAGS ::=
+
+BEGIN
+
+IMPORTS
+ ProcedureCode,
+ ProtocolIE-ID
+FROM NBAP-CommonDataTypes;
+
+-- **************************************************************
+--
+-- Elementary Procedures
+--
+-- **************************************************************
+
+id-audit ProcedureCode ::= 0
+id-auditRequired ProcedureCode ::= 1
+id-blockResource ProcedureCode ::= 2
+id-cellDeletion ProcedureCode ::= 3
+id-cellReconfiguration ProcedureCode ::= 4
+id-cellSetup ProcedureCode ::= 5
+id-cellSynchronisationInitiation ProcedureCode ::= 45
+id-cellSynchronisationReconfiguration ProcedureCode ::= 46
+id-cellSynchronisationReporting ProcedureCode ::= 47
+id-cellSynchronisationTermination ProcedureCode ::= 48
+id-cellSynchronisationFailure ProcedureCode ::= 49
+id-commonMeasurementFailure ProcedureCode ::= 6
+id-commonMeasurementInitiation ProcedureCode ::= 7
+id-commonMeasurementReport ProcedureCode ::= 8
+id-commonMeasurementTermination ProcedureCode ::= 9
+id-commonTransportChannelDelete ProcedureCode ::= 10
+id-commonTransportChannelReconfigure ProcedureCode ::= 11
+id-commonTransportChannelSetup ProcedureCode ::= 12
+id-compressedModeCommand ProcedureCode ::= 14
+id-dedicatedMeasurementFailure ProcedureCode ::= 16
+id-dedicatedMeasurementInitiation ProcedureCode ::= 17
+id-dedicatedMeasurementReport ProcedureCode ::= 18
+id-dedicatedMeasurementTermination ProcedureCode ::= 19
+id-downlinkPowerControl ProcedureCode ::= 20
+id-downlinkPowerTimeslotControl ProcedureCode ::= 38
+id-errorIndicationForCommon ProcedureCode ::= 35
+id-errorIndicationForDedicated ProcedureCode ::= 21
+id-informationExchangeFailure ProcedureCode ::= 40
+id-informationExchangeInitiation ProcedureCode ::= 41
+id-informationExchangeTermination ProcedureCode ::= 42
+id-informationReporting ProcedureCode ::= 43
+id-BearerRearrangement ProcedureCode ::= 50
+id-physicalSharedChannelReconfiguration ProcedureCode ::= 37
+id-privateMessageForCommon ProcedureCode ::= 36
+id-privateMessageForDedicated ProcedureCode ::= 22
+id-radioLinkAddition ProcedureCode ::= 23
+id-radioLinkDeletion ProcedureCode ::= 24
+id-radioLinkFailure ProcedureCode ::= 25
+id-radioLinkPreemption ProcedureCode ::= 39
+id-radioLinkRestoration ProcedureCode ::= 26
+id-radioLinkSetup ProcedureCode ::= 27
+id-reset ProcedureCode ::= 13
+id-resourceStatusIndication ProcedureCode ::= 28
+id-cellSynchronisationAdjustment ProcedureCode ::= 44
+id-synchronisedRadioLinkReconfigurationCancellation ProcedureCode ::= 29
+id-synchronisedRadioLinkReconfigurationCommit ProcedureCode ::= 30
+id-synchronisedRadioLinkReconfigurationPreparation ProcedureCode ::= 31
+id-systemInformationUpdate ProcedureCode ::= 32
+id-unblockResource ProcedureCode ::= 33
+id-unSynchronisedRadioLinkReconfiguration ProcedureCode ::= 34
+id-radioLinkActivation ProcedureCode ::= 51
+id-radioLinkParameterUpdate ProcedureCode ::= 52
+
+-- **************************************************************
+--
+-- Lists
+--
+-- **************************************************************
+
+maxNrOfCodes INTEGER ::= 10
+maxNrOfDLTSs INTEGER ::= 15
+maxNrOfDLTSLCRs INTEGER ::= 6
+maxNrOfErrors INTEGER ::= 256
+maxNrOfTFs INTEGER ::= 32
+maxNrOfTFCs INTEGER ::= 1024
+maxNrOfRLs INTEGER ::= 16
+maxNrOfRLs-1 INTEGER ::= 15 -- maxNrOfRLs - 1
+maxNrOfRLs-2 INTEGER ::= 14 -- maxNrOfRLs - 2
+maxNrOfRLSets INTEGER ::= maxNrOfRLs
+maxNrOfDPCHs INTEGER ::= 240
+maxNrOfDPCHLCRs INTEGER ::= 240
+maxNrOfSCCPCHs INTEGER ::= 8
+maxNrOfCPCHs INTEGER ::= 16
+maxNrOfPCPCHs INTEGER ::= 64
+maxNrOfDCHs INTEGER ::= 128
+maxNrOfDSCHs INTEGER ::= 32
+maxNrOfFACHs INTEGER ::= 8
+maxNrOfCCTrCHs INTEGER ::= 16
+maxNrOfPDSCHs INTEGER ::= 256
+maxNrOfHSPDSCHs INTEGER ::= 16
+maxNrOfPUSCHs INTEGER ::= 256
+maxNrOfPDSCHSets INTEGER ::= 256
+maxNrOfPRACHLCRs INTEGER ::= 8
+maxNrOfPUSCHSets INTEGER ::= 256
+maxNrOfSCCPCHLCRs INTEGER ::= 8
+maxNrOfULTSs INTEGER ::= 15
+maxNrOfULTSLCRs INTEGER ::= 6
+maxNrOfUSCHs INTEGER ::= 32
+maxAPSigNum INTEGER ::= 16
+maxNrOfSlotFormatsPRACH INTEGER ::= 8
+maxCellinNodeB INTEGER ::= 256
+maxCCPinNodeB INTEGER ::= 256
+maxCPCHCell INTEGER ::= maxNrOfCPCHs
+maxCTFC INTEGER ::= 16777215
+maxLocalCellinNodeB INTEGER ::= maxCellinNodeB
+maxNoofLen INTEGER ::= 7
+maxFPACHCell INTEGER ::= 8
+maxRACHCell INTEGER ::= maxPRACHCell
+maxPRACHCell INTEGER ::= 16
+maxPCPCHCell INTEGER ::= 64
+maxSCCPCHCell INTEGER ::= 32
+maxSCPICHCell INTEGER ::= 32
+maxTTI-count INTEGER ::= 4
+maxIBSEG INTEGER ::= 16
+maxIB INTEGER ::= 64
+maxFACHCell INTEGER ::= 256 -- maxNrOfFACHs * maxSCCPCHCell
+maxRateMatching INTEGER ::= 256
+maxCodeNrComp-1 INTEGER ::= 256
+maxHS-PDSCHCodeNrComp-1 INTEGER ::= 15
+maxHS-SCCHCodeNrComp-1 INTEGER ::= 127
+maxNrOfCellSyncBursts INTEGER ::= 10
+maxNrOfCodeGroups INTEGER ::= 256
+maxNrOfReceptsPerSyncFrame INTEGER ::= 16
+maxNrOfMeasNCell INTEGER ::= 96
+maxNrOfMeasNCell-1 INTEGER ::= 95 -- maxNrOfMeasNCell - 1
+maxNrOfTFCIGroups INTEGER ::= 256
+maxNrOfTFCI1Combs INTEGER ::= 512
+maxNrOfTFCI2Combs INTEGER ::= 1024
+maxNrOfTFCI2Combs-1 INTEGER ::= 1023
+maxNrOfSF INTEGER ::= 8
+maxTGPS INTEGER ::= 6
+maxCommunicationContext INTEGER ::= 1048575
+maxNrOfLevels INTEGER ::= 256
+maxNoSat INTEGER ::= 16
+maxNoGPSItems INTEGER ::= 8
+maxNrOfHSSCCHs INTEGER ::= 32
+maxNrOfHSSICHs INTEGER ::= 4
+maxNrOfSyncFramesLCR INTEGER ::= 512
+maxNrOfReceptionsperSyncFrameLCR INTEGER ::= 8
+maxNrOfSyncDLCodesLCR INTEGER ::= 32
+maxNrOfHSSCCHCodes INTEGER ::= 4
+maxNrOfMACdFlows INTEGER ::= 8
+maxNrOfMACdFlows-1 INTEGER ::= 7 -- maxNrOfMACdFlows - 1
+maxNrOfMACdPDUIndexes INTEGER ::= 8
+maxNrOfMACdPDUIndexes-1 INTEGER ::= 7 -- maxNoOfMACdPDUIndexes - 1
+maxNrOfPriorityQueues INTEGER ::= 8
+maxNrOfPriorityQueues-1 INTEGER ::= 7 -- maxNoOfPriorityQueues - 1
+maxNrOfHARQProcesses INTEGER ::= 8
+maxNrOfContextsOnUeList INTEGER ::= 16
+maxNrOfCellPortionsPerCell INTEGER ::= 64
+maxNrOfCellPortionsPerCell-1 INTEGER ::= 63
+maxNrOfPriorityClasses INTEGER ::= 16
+maxNrOfSatAlmanac-maxNoSat INTEGER ::= 16 -- maxNrofSatAlmanac - maxNoSat
+
+
+-- **************************************************************
+--
+-- IEs
+--
+-- **************************************************************
+
+id-AICH-Information ProtocolIE-ID ::= 0
+id-AICH-InformationItem-ResourceStatusInd ProtocolIE-ID ::= 1
+id-BCH-Information ProtocolIE-ID ::= 7
+id-BCH-InformationItem-ResourceStatusInd ProtocolIE-ID ::= 8
+id-BCCH-ModificationTime ProtocolIE-ID ::= 9
+id-BlockingPriorityIndicator ProtocolIE-ID ::= 10
+id-Cause ProtocolIE-ID ::= 13
+id-CCP-InformationItem-AuditRsp ProtocolIE-ID ::= 14
+id-CCP-InformationList-AuditRsp ProtocolIE-ID ::= 15
+id-CCP-InformationItem-ResourceStatusInd ProtocolIE-ID ::= 16
+id-Cell-InformationItem-AuditRsp ProtocolIE-ID ::= 17
+id-Cell-InformationItem-ResourceStatusInd ProtocolIE-ID ::= 18
+id-Cell-InformationList-AuditRsp ProtocolIE-ID ::= 19
+id-CellParameterID ProtocolIE-ID ::= 23
+id-CFN ProtocolIE-ID ::= 24
+id-C-ID ProtocolIE-ID ::= 25
+id-CommonMeasurementAccuracy ProtocolIE-ID ::= 39
+id-CommonMeasurementObjectType-CM-Rprt ProtocolIE-ID ::= 31
+id-CommonMeasurementObjectType-CM-Rqst ProtocolIE-ID ::= 32
+id-CommonMeasurementObjectType-CM-Rsp ProtocolIE-ID ::= 33
+id-CommonMeasurementType ProtocolIE-ID ::= 34
+id-CommonPhysicalChannelID ProtocolIE-ID ::= 35
+id-CommonPhysicalChannelType-CTCH-SetupRqstFDD ProtocolIE-ID ::= 36
+id-CommonPhysicalChannelType-CTCH-SetupRqstTDD ProtocolIE-ID ::= 37
+id-CommunicationControlPortID ProtocolIE-ID ::= 40
+id-ConfigurationGenerationID ProtocolIE-ID ::= 43
+id-CRNC-CommunicationContextID ProtocolIE-ID ::= 44
+id-CriticalityDiagnostics ProtocolIE-ID ::= 45
+id-DCHs-to-Add-FDD ProtocolIE-ID ::= 48
+id-DCH-AddList-RL-ReconfPrepTDD ProtocolIE-ID ::= 49
+id-DCHs-to-Add-TDD ProtocolIE-ID ::= 50
+id-DCH-DeleteList-RL-ReconfPrepFDD ProtocolIE-ID ::= 52
+id-DCH-DeleteList-RL-ReconfPrepTDD ProtocolIE-ID ::= 53
+id-DCH-DeleteList-RL-ReconfRqstFDD ProtocolIE-ID ::= 54
+id-DCH-DeleteList-RL-ReconfRqstTDD ProtocolIE-ID ::= 55
+id-DCH-FDD-Information ProtocolIE-ID ::= 56
+id-DCH-TDD-Information ProtocolIE-ID ::= 57
+id-DCH-InformationResponse ProtocolIE-ID ::= 59
+id-FDD-DCHs-to-Modify ProtocolIE-ID ::= 62
+id-TDD-DCHs-to-Modify ProtocolIE-ID ::= 63
+id-DCH-ModifyList-RL-ReconfRqstTDD ProtocolIE-ID ::= 65
+id-DCH-RearrangeList-Bearer-RearrangeInd ProtocolIE-ID ::= 135
+id-DedicatedMeasurementObjectType-DM-Rprt ProtocolIE-ID ::= 67
+id-DedicatedMeasurementObjectType-DM-Rqst ProtocolIE-ID ::= 68
+id-DedicatedMeasurementObjectType-DM-Rsp ProtocolIE-ID ::= 69
+id-DedicatedMeasurementType ProtocolIE-ID ::= 70
+id-DL-CCTrCH-InformationItem-RL-SetupRqstTDD ProtocolIE-ID ::= 72
+id-DL-CCTrCH-InformationList-RL-AdditionRqstTDD ProtocolIE-ID ::= 73
+id-DL-CCTrCH-InformationList-RL-SetupRqstTDD ProtocolIE-ID ::= 76
+id-DL-DPCH-InformationItem-RL-AdditionRqstTDD ProtocolIE-ID ::= 77
+id-DL-DPCH-InformationList-RL-SetupRqstTDD ProtocolIE-ID ::= 79
+id-DL-DPCH-Information-RL-ReconfPrepFDD ProtocolIE-ID ::= 81
+id-DL-DPCH-Information-RL-ReconfRqstFDD ProtocolIE-ID ::= 82
+id-DL-DPCH-Information-RL-SetupRqstFDD ProtocolIE-ID ::= 83
+id-DL-DPCH-TimingAdjustment ProtocolIE-ID ::= 21
+id-DL-ReferencePowerInformationItem-DL-PC-Rqst ProtocolIE-ID ::= 84
+id-DLReferencePower ProtocolIE-ID ::= 85
+id-DLReferencePowerList-DL-PC-Rqst ProtocolIE-ID ::= 86
+id-DSCH-AddItem-RL-ReconfPrepFDD ProtocolIE-ID ::= 87
+id-DSCHs-to-Add-FDD ProtocolIE-ID ::= 89
+id-DSCH-DeleteItem-RL-ReconfPrepFDD ProtocolIE-ID ::= 91
+id-DSCH-DeleteList-RL-ReconfPrepFDD ProtocolIE-ID ::= 93
+id-DSCHs-to-Add-TDD ProtocolIE-ID ::= 96
+id-DSCH-Information-DeleteList-RL-ReconfPrepTDD ProtocolIE-ID ::= 98
+id-DSCH-Information-ModifyList-RL-ReconfPrepTDD ProtocolIE-ID ::= 100
+id-DSCH-InformationResponse ProtocolIE-ID ::= 105
+id-DSCH-FDD-Information ProtocolIE-ID ::= 106
+id-DSCH-TDD-Information ProtocolIE-ID ::= 107
+id-DSCH-ModifyItem-RL-ReconfPrepFDD ProtocolIE-ID ::= 108
+id-DSCH-ModifyList-RL-ReconfPrepFDD ProtocolIE-ID ::= 112
+id-DSCH-RearrangeList-Bearer-RearrangeInd ProtocolIE-ID ::= 136
+id-End-Of-Audit-Sequence-Indicator ProtocolIE-ID ::= 113
+id-FACH-Information ProtocolIE-ID ::= 116
+id-FACH-InformationItem-ResourceStatusInd ProtocolIE-ID ::= 117
+id-FACH-ParametersList-CTCH-ReconfRqstTDD ProtocolIE-ID ::= 120
+id-FACH-ParametersListIE-CTCH-SetupRqstFDD ProtocolIE-ID ::= 121
+id-FACH-ParametersListIE-CTCH-SetupRqstTDD ProtocolIE-ID ::= 122
+id-IndicationType-ResourceStatusInd ProtocolIE-ID ::= 123
+id-Local-Cell-ID ProtocolIE-ID ::= 124
+id-Local-Cell-Group-InformationItem-AuditRsp ProtocolIE-ID ::= 2
+id-Local-Cell-Group-InformationItem-ResourceStatusInd ProtocolIE-ID ::= 3
+id-Local-Cell-Group-InformationItem2-ResourceStatusInd ProtocolIE-ID ::= 4
+id-Local-Cell-Group-InformationList-AuditRsp ProtocolIE-ID ::= 5
+id-Local-Cell-InformationItem-AuditRsp ProtocolIE-ID ::= 125
+id-Local-Cell-InformationItem-ResourceStatusInd ProtocolIE-ID ::= 126
+id-Local-Cell-InformationItem2-ResourceStatusInd ProtocolIE-ID ::= 127
+id-Local-Cell-InformationList-AuditRsp ProtocolIE-ID ::= 128
+id-AdjustmentPeriod ProtocolIE-ID ::= 129
+id-MaxAdjustmentStep ProtocolIE-ID ::= 130
+id-MaximumTransmissionPower ProtocolIE-ID ::= 131
+id-MeasurementFilterCoefficient ProtocolIE-ID ::= 132
+id-MeasurementID ProtocolIE-ID ::= 133
+id-MessageStructure ProtocolIE-ID ::= 115
+id-MIB-SB-SIB-InformationList-SystemInfoUpdateRqst ProtocolIE-ID ::= 134
+id-NodeB-CommunicationContextID ProtocolIE-ID ::= 143
+id-NeighbouringCellMeasurementInformation ProtocolIE-ID ::= 455
+id-P-CCPCH-Information ProtocolIE-ID ::= 144
+id-P-CCPCH-InformationItem-ResourceStatusInd ProtocolIE-ID ::= 145
+id-P-CPICH-Information ProtocolIE-ID ::= 146
+id-P-CPICH-InformationItem-ResourceStatusInd ProtocolIE-ID ::= 147
+id-P-SCH-Information ProtocolIE-ID ::= 148
+id-PCCPCH-Information-Cell-ReconfRqstTDD ProtocolIE-ID ::= 150
+id-PCCPCH-Information-Cell-SetupRqstTDD ProtocolIE-ID ::= 151
+id-PCH-Parameters-CTCH-ReconfRqstTDD ProtocolIE-ID ::= 155
+id-PCH-ParametersItem-CTCH-SetupRqstFDD ProtocolIE-ID ::= 156
+id-PCH-ParametersItem-CTCH-SetupRqstTDD ProtocolIE-ID ::= 157
+id-PCH-Information ProtocolIE-ID ::= 158
+id-PDSCH-Information-AddListIE-PSCH-ReconfRqst ProtocolIE-ID ::= 161
+id-PDSCH-Information-ModifyListIE-PSCH-ReconfRqst ProtocolIE-ID ::= 162
+id-PDSCHSets-AddList-PSCH-ReconfRqst ProtocolIE-ID ::= 163
+id-PDSCHSets-DeleteList-PSCH-ReconfRqst ProtocolIE-ID ::= 164
+id-PDSCHSets-ModifyList-PSCH-ReconfRqst ProtocolIE-ID ::= 165
+id-PICH-Information ProtocolIE-ID ::= 166
+id-PICH-Parameters-CTCH-ReconfRqstTDD ProtocolIE-ID ::= 168
+id-PowerAdjustmentType ProtocolIE-ID ::= 169
+id-PRACH-Information ProtocolIE-ID ::= 170
+id-PrimaryCCPCH-Information-Cell-ReconfRqstFDD ProtocolIE-ID ::= 175
+id-PrimaryCCPCH-Information-Cell-SetupRqstFDD ProtocolIE-ID ::= 176
+id-PrimaryCPICH-Information-Cell-ReconfRqstFDD ProtocolIE-ID ::= 177
+id-PrimaryCPICH-Information-Cell-SetupRqstFDD ProtocolIE-ID ::= 178
+id-PrimarySCH-Information-Cell-ReconfRqstFDD ProtocolIE-ID ::= 179
+id-PrimarySCH-Information-Cell-SetupRqstFDD ProtocolIE-ID ::= 180
+id-PrimaryScramblingCode ProtocolIE-ID ::= 181
+id-SCH-Information-Cell-ReconfRqstTDD ProtocolIE-ID ::= 183
+id-SCH-Information-Cell-SetupRqstTDD ProtocolIE-ID ::= 184
+id-PUSCH-Information-AddListIE-PSCH-ReconfRqst ProtocolIE-ID ::= 185
+id-PUSCH-Information-ModifyListIE-PSCH-ReconfRqst ProtocolIE-ID ::= 186
+id-PUSCHSets-AddList-PSCH-ReconfRqst ProtocolIE-ID ::= 187
+id-PUSCHSets-DeleteList-PSCH-ReconfRqst ProtocolIE-ID ::= 188
+id-PUSCHSets-ModifyList-PSCH-ReconfRqst ProtocolIE-ID ::= 189
+id-RACH-Information ProtocolIE-ID ::= 190
+id-RACH-ParametersItem-CTCH-SetupRqstFDD ProtocolIE-ID ::= 196
+id-RACH-ParameterItem-CTCH-SetupRqstTDD ProtocolIE-ID ::= 197
+id-ReportCharacteristics ProtocolIE-ID ::= 198
+id-Reporting-Object-RL-FailureInd ProtocolIE-ID ::= 199
+id-Reporting-Object-RL-RestoreInd ProtocolIE-ID ::= 200
+id-RL-InformationItem-DM-Rprt ProtocolIE-ID ::= 202
+id-RL-InformationItem-DM-Rqst ProtocolIE-ID ::= 203
+id-RL-InformationItem-DM-Rsp ProtocolIE-ID ::= 204
+id-RL-InformationItem-RL-AdditionRqstFDD ProtocolIE-ID ::= 205
+id-RL-informationItem-RL-DeletionRqst ProtocolIE-ID ::= 206
+id-RL-InformationItem-RL-FailureInd ProtocolIE-ID ::= 207
+id-RL-InformationItem-RL-PreemptRequiredInd ProtocolIE-ID ::= 286
+id-RL-InformationItem-RL-ReconfPrepFDD ProtocolIE-ID ::= 208
+id-RL-InformationItem-RL-ReconfRqstFDD ProtocolIE-ID ::= 209
+id-RL-InformationItem-RL-RestoreInd ProtocolIE-ID ::= 210
+id-RL-InformationItem-RL-SetupRqstFDD ProtocolIE-ID ::= 211
+id-RL-InformationList-RL-AdditionRqstFDD ProtocolIE-ID ::= 212
+id-RL-informationList-RL-DeletionRqst ProtocolIE-ID ::= 213
+id-RL-InformationList-RL-PreemptRequiredInd ProtocolIE-ID ::= 237
+id-RL-InformationList-RL-ReconfPrepFDD ProtocolIE-ID ::= 214
+id-RL-InformationList-RL-ReconfRqstFDD ProtocolIE-ID ::= 215
+id-RL-InformationList-RL-SetupRqstFDD ProtocolIE-ID ::= 216
+id-RL-InformationResponseItem-RL-AdditionRspFDD ProtocolIE-ID ::= 217
+id-RL-InformationResponseItem-RL-ReconfReady ProtocolIE-ID ::= 218
+id-RL-InformationResponseItem-RL-ReconfRsp ProtocolIE-ID ::= 219
+id-RL-InformationResponseItem-RL-SetupRspFDD ProtocolIE-ID ::= 220
+id-RL-InformationResponseList-RL-AdditionRspFDD ProtocolIE-ID ::= 221
+id-RL-InformationResponseList-RL-ReconfReady ProtocolIE-ID ::= 222
+id-RL-InformationResponseList-RL-ReconfRsp ProtocolIE-ID ::= 223
+id-RL-InformationResponseList-RL-SetupRspFDD ProtocolIE-ID ::= 224
+id-RL-InformationResponse-RL-AdditionRspTDD ProtocolIE-ID ::= 225
+id-RL-InformationResponse-RL-SetupRspTDD ProtocolIE-ID ::= 226
+id-RL-Information-RL-AdditionRqstTDD ProtocolIE-ID ::= 227
+id-RL-Information-RL-ReconfRqstTDD ProtocolIE-ID ::= 228
+id-RL-Information-RL-ReconfPrepTDD ProtocolIE-ID ::= 229
+id-RL-Information-RL-SetupRqstTDD ProtocolIE-ID ::= 230
+id-RL-ReconfigurationFailureItem-RL-ReconfFailure ProtocolIE-ID ::= 236
+id-RL-Set-InformationItem-DM-Rprt ProtocolIE-ID ::= 238
+id-RL-Set-InformationItem-DM-Rsp ProtocolIE-ID ::= 240
+id-RL-Set-InformationItem-RL-FailureInd ProtocolIE-ID ::= 241
+id-RL-Set-InformationItem-RL-RestoreInd ProtocolIE-ID ::= 242
+id-S-CCPCH-Information ProtocolIE-ID ::= 247
+id-S-CPICH-Information ProtocolIE-ID ::= 249
+id-SCH-Information ProtocolIE-ID ::= 251
+id-S-SCH-Information ProtocolIE-ID ::= 253
+id-Secondary-CCPCHListIE-CTCH-ReconfRqstTDD ProtocolIE-ID ::= 257
+id-Secondary-CCPCH-parameterListIE-CTCH-SetupRqstTDD ProtocolIE-ID ::= 258
+id-Secondary-CCPCH-Parameters-CTCH-ReconfRqstTDD ProtocolIE-ID ::= 259
+id-SecondaryCPICH-InformationItem-Cell-ReconfRqstFDD ProtocolIE-ID ::= 260
+id-SecondaryCPICH-InformationItem-Cell-SetupRqstFDD ProtocolIE-ID ::= 261
+id-SecondaryCPICH-InformationList-Cell-ReconfRqstFDD ProtocolIE-ID ::= 262
+id-SecondaryCPICH-InformationList-Cell-SetupRqstFDD ProtocolIE-ID ::= 263
+id-SecondarySCH-Information-Cell-ReconfRqstFDD ProtocolIE-ID ::= 264
+id-SecondarySCH-Information-Cell-SetupRqstFDD ProtocolIE-ID ::= 265
+id-SegmentInformationListIE-SystemInfoUpdate ProtocolIE-ID ::= 266
+id-SFN ProtocolIE-ID ::= 268
+id-SignallingBearerRequestIndicator ProtocolIE-ID ::= 138
+id-ShutdownTimer ProtocolIE-ID ::= 269
+id-Start-Of-Audit-Sequence-Indicator ProtocolIE-ID ::= 114
+id-Successful-RL-InformationRespItem-RL-AdditionFailureFDD ProtocolIE-ID ::= 270
+id-Successful-RL-InformationRespItem-RL-SetupFailureFDD ProtocolIE-ID ::= 271
+id-SyncCase ProtocolIE-ID ::= 274
+id-SyncCaseIndicatorItem-Cell-SetupRqstTDD-PSCH ProtocolIE-ID ::= 275
+id-T-Cell ProtocolIE-ID ::= 276
+id-TargetCommunicationControlPortID ProtocolIE-ID ::= 139
+id-TimeSlotConfigurationList-Cell-ReconfRqstTDD ProtocolIE-ID ::= 277
+id-TimeSlotConfigurationList-Cell-SetupRqstTDD ProtocolIE-ID ::= 278
+id-TransmissionDiversityApplied ProtocolIE-ID ::= 279
+id-TypeOfError ProtocolIE-ID ::= 508
+id-UARFCNforNt ProtocolIE-ID ::= 280
+id-UARFCNforNd ProtocolIE-ID ::= 281
+id-UARFCNforNu ProtocolIE-ID ::= 282
+id-UL-CCTrCH-InformationItem-RL-SetupRqstTDD ProtocolIE-ID ::= 284
+id-UL-CCTrCH-InformationList-RL-AdditionRqstTDD ProtocolIE-ID ::= 285
+id-UL-CCTrCH-InformationList-RL-SetupRqstTDD ProtocolIE-ID ::= 288
+id-UL-DPCH-InformationItem-RL-AdditionRqstTDD ProtocolIE-ID ::= 289
+id-UL-DPCH-InformationList-RL-SetupRqstTDD ProtocolIE-ID ::= 291
+id-UL-DPCH-Information-RL-ReconfPrepFDD ProtocolIE-ID ::= 293
+id-UL-DPCH-Information-RL-ReconfRqstFDD ProtocolIE-ID ::= 294
+id-UL-DPCH-Information-RL-SetupRqstFDD ProtocolIE-ID ::= 295
+id-Unsuccessful-RL-InformationRespItem-RL-AdditionFailureFDD ProtocolIE-ID ::= 296
+id-Unsuccessful-RL-InformationRespItem-RL-SetupFailureFDD ProtocolIE-ID ::= 297
+id-Unsuccessful-RL-InformationResp-RL-AdditionFailureTDD ProtocolIE-ID ::= 300
+id-Unsuccessful-RL-InformationResp-RL-SetupFailureTDD ProtocolIE-ID ::= 301
+id-USCH-Information-Add ProtocolIE-ID ::= 302
+id-USCH-Information-DeleteList-RL-ReconfPrepTDD ProtocolIE-ID ::= 304
+id-USCH-Information-ModifyList-RL-ReconfPrepTDD ProtocolIE-ID ::= 306
+id-USCH-InformationResponse ProtocolIE-ID ::= 309
+id-USCH-Information ProtocolIE-ID ::= 310
+id-USCH-RearrangeList-Bearer-RearrangeInd ProtocolIE-ID ::= 141
+id-Active-Pattern-Sequence-Information ProtocolIE-ID ::= 315
+id-AICH-ParametersListIE-CTCH-ReconfRqstFDD ProtocolIE-ID ::= 316
+id-AdjustmentRatio ProtocolIE-ID ::= 317
+id-AP-AICH-Information ProtocolIE-ID ::= 320
+id-AP-AICH-ParametersListIE-CTCH-ReconfRqstFDD ProtocolIE-ID ::= 322
+id-FACH-ParametersListIE-CTCH-ReconfRqstFDD ProtocolIE-ID ::= 323
+id-CauseLevel-PSCH-ReconfFailure ProtocolIE-ID ::= 324
+id-CauseLevel-RL-AdditionFailureFDD ProtocolIE-ID ::= 325
+id-CauseLevel-RL-AdditionFailureTDD ProtocolIE-ID ::= 326
+id-CauseLevel-RL-ReconfFailure ProtocolIE-ID ::= 327
+id-CauseLevel-RL-SetupFailureFDD ProtocolIE-ID ::= 328
+id-CauseLevel-RL-SetupFailureTDD ProtocolIE-ID ::= 329
+id-CDCA-ICH-Information ProtocolIE-ID ::= 330
+id-CDCA-ICH-ParametersListIE-CTCH-ReconfRqstFDD ProtocolIE-ID ::= 332
+id-Closed-Loop-Timing-Adjustment-Mode ProtocolIE-ID ::= 333
+id-CommonPhysicalChannelType-CTCH-ReconfRqstFDD ProtocolIE-ID ::= 334
+id-Compressed-Mode-Deactivation-Flag ProtocolIE-ID ::= 335
+id-CPCH-Information ProtocolIE-ID ::= 336
+id-CPCH-Parameters-CTCH-SetupRsp ProtocolIE-ID ::= 342
+id-CPCH-ParametersListIE-CTCH-ReconfRqstFDD ProtocolIE-ID ::= 343
+id-DL-CCTrCH-InformationAddList-RL-ReconfPrepTDD ProtocolIE-ID ::= 346
+id-DL-CCTrCH-InformationDeleteItem-RL-ReconfRqstTDD ProtocolIE-ID ::= 347
+id-DL-CCTrCH-InformationDeleteList-RL-ReconfPrepTDD ProtocolIE-ID ::= 348
+id-DL-CCTrCH-InformationDeleteList-RL-ReconfRqstTDD ProtocolIE-ID ::= 349
+id-DL-CCTrCH-InformationModifyItem-RL-ReconfRqstTDD ProtocolIE-ID ::= 350
+id-DL-CCTrCH-InformationModifyList-RL-ReconfPrepTDD ProtocolIE-ID ::= 351
+id-DL-CCTrCH-InformationModifyList-RL-ReconfRqstTDD ProtocolIE-ID ::= 352
+id-DL-DPCH-InformationAddListIE-RL-ReconfPrepTDD ProtocolIE-ID ::= 353
+id-DL-DPCH-InformationModify-AddListIE-RL-ReconfPrepTDD ProtocolIE-ID ::= 355
+id-DL-DPCH-InformationModify-DeleteListIE-RL-ReconfPrepTDD ProtocolIE-ID ::= 356
+id-DL-DPCH-InformationModify-ModifyListIE-RL-ReconfPrepTDD ProtocolIE-ID ::= 357
+id-DL-TPC-Pattern01Count ProtocolIE-ID ::= 358
+id-DPC-Mode ProtocolIE-ID ::= 450
+id-DPCHConstant ProtocolIE-ID ::= 359
+id-DSCH-FDD-Common-Information ProtocolIE-ID ::= 94
+id-EnhancedDSCHPC ProtocolIE-ID ::= 110
+id-EnhancedDSCHPCIndicator ProtocolIE-ID ::= 111
+id-FACH-ParametersList-CTCH-SetupRsp ProtocolIE-ID ::= 362
+id-Limited-power-increase-information-Cell-SetupRqstFDD ProtocolIE-ID ::= 369
+id-PCH-Parameters-CTCH-SetupRsp ProtocolIE-ID ::= 374
+id-PCH-ParametersItem-CTCH-ReconfRqstFDD ProtocolIE-ID ::= 375
+id-PCPCH-Information ProtocolIE-ID ::= 376
+id-PICH-ParametersItem-CTCH-ReconfRqstFDD ProtocolIE-ID ::= 380
+id-PRACHConstant ProtocolIE-ID ::= 381
+id-PRACH-ParametersListIE-CTCH-ReconfRqstFDD ProtocolIE-ID ::= 383
+id-PUSCHConstant ProtocolIE-ID ::= 384
+id-RACH-Parameters-CTCH-SetupRsp ProtocolIE-ID ::= 385
+id-SSDT-CellIDforEDSCHPC ProtocolIE-ID ::= 443
+id-Synchronisation-Configuration-Cell-ReconfRqst ProtocolIE-ID ::= 393
+id-Synchronisation-Configuration-Cell-SetupRqst ProtocolIE-ID ::= 394
+id-Transmission-Gap-Pattern-Sequence-Information ProtocolIE-ID ::= 395
+id-UL-CCTrCH-InformationAddList-RL-ReconfPrepTDD ProtocolIE-ID ::= 396
+id-UL-CCTrCH-InformationDeleteItem-RL-ReconfRqstTDD ProtocolIE-ID ::= 397
+id-UL-CCTrCH-InformationDeleteList-RL-ReconfPrepTDD ProtocolIE-ID ::= 398
+id-UL-CCTrCH-InformationDeleteList-RL-ReconfRqstTDD ProtocolIE-ID ::= 399
+id-UL-CCTrCH-InformationModifyItem-RL-ReconfRqstTDD ProtocolIE-ID ::= 400
+id-UL-CCTrCH-InformationModifyList-RL-ReconfPrepTDD ProtocolIE-ID ::= 401
+id-UL-CCTrCH-InformationModifyList-RL-ReconfRqstTDD ProtocolIE-ID ::= 402
+id-UL-DPCH-InformationAddListIE-RL-ReconfPrepTDD ProtocolIE-ID ::= 403
+id-UL-DPCH-InformationModify-AddListIE-RL-ReconfPrepTDD ProtocolIE-ID ::= 405
+id-UL-DPCH-InformationModify-DeleteListIE-RL-ReconfPrepTDD ProtocolIE-ID ::= 406
+id-UL-DPCH-InformationModify-ModifyListIE-RL-ReconfPrepTDD ProtocolIE-ID ::= 407
+id-Unsuccessful-PDSCHSetItem-PSCH-ReconfFailureTDD ProtocolIE-ID ::= 408
+id-Unsuccessful-PUSCHSetItem-PSCH-ReconfFailureTDD ProtocolIE-ID ::= 409
+id-CommunicationContextInfoItem-Reset ProtocolIE-ID ::= 412
+id-CommunicationControlPortInfoItem-Reset ProtocolIE-ID ::= 414
+id-ResetIndicator ProtocolIE-ID ::= 416
+id-TFCI2-Bearer-Information-RL-SetupRqstFDD ProtocolIE-ID ::= 417
+id-TFCI2-BearerSpecificInformation-RL-ReconfPrepFDD ProtocolIE-ID ::= 418
+id-TFCI2-BearerInformationResponse ProtocolIE-ID ::= 419
+id-TFCI2BearerRequestIndicator ProtocolIE-ID ::= 142
+id-TimingAdvanceApplied ProtocolIE-ID ::= 287
+id-CFNReportingIndicator ProtocolIE-ID ::= 6
+id-SFNReportingIndicator ProtocolIE-ID ::= 11
+id-InnerLoopDLPCStatus ProtocolIE-ID ::= 12
+id-TimeslotISCPInfo ProtocolIE-ID ::= 283
+id-PICH-ParametersItem-CTCH-SetupRqstTDD ProtocolIE-ID ::= 167
+id-PRACH-ParametersItem-CTCH-SetupRqstTDD ProtocolIE-ID ::= 20
+id-CCTrCH-InformationItem-RL-FailureInd ProtocolIE-ID ::= 46
+id-CCTrCH-InformationItem-RL-RestoreInd ProtocolIE-ID ::= 47
+id-CauseLevel-SyncAdjustmntFailureTDD ProtocolIE-ID ::= 420
+id-CellAdjustmentInfo-SyncAdjustmntRqstTDD ProtocolIE-ID ::= 421
+id-CellAdjustmentInfoItem-SyncAdjustmentRqstTDD ProtocolIE-ID ::= 494
+id-CellSyncBurstInfoList-CellSyncReconfRqstTDD ProtocolIE-ID ::= 482
+id-CellSyncBurstTransInit-CellSyncInitiationRqstTDD ProtocolIE-ID ::= 422
+id-CellSyncBurstMeasureInit-CellSyncInitiationRqstTDD ProtocolIE-ID ::= 423
+id-CellSyncBurstTransReconfiguration-CellSyncReconfRqstTDD ProtocolIE-ID ::= 424
+id-CellSyncBurstMeasReconfiguration-CellSyncReconfRqstTDD ProtocolIE-ID ::= 425
+id-CellSyncBurstTransInfoList-CellSyncReconfRqstTDD ProtocolIE-ID ::= 426
+id-CellSyncBurstMeasInfoList-CellSyncReconfRqstTDD ProtocolIE-ID ::= 427
+id-CellSyncBurstTransReconfInfo-CellSyncReconfRqstTDD ProtocolIE-ID ::= 428
+id-CellSyncInfo-CellSyncReprtTDD ProtocolIE-ID ::= 429
+id-CSBTransmissionID ProtocolIE-ID ::= 430
+id-CSBMeasurementID ProtocolIE-ID ::= 431
+id-IntStdPhCellSyncInfoItem-CellSyncReprtTDD ProtocolIE-ID ::= 432
+id-NCyclesPerSFNperiod ProtocolIE-ID ::= 433
+id-NRepetitionsPerCyclePeriod ProtocolIE-ID ::= 434
+id-SyncFrameNumber ProtocolIE-ID ::= 437
+id-SynchronisationReportType ProtocolIE-ID ::= 438
+id-SynchronisationReportCharacteristics ProtocolIE-ID ::= 439
+id-Unsuccessful-cell-InformationRespItem-SyncAdjustmntFailureTDD ProtocolIE-ID ::= 440
+id-LateEntranceCellSyncInfoItem-CellSyncReprtTDD ProtocolIE-ID ::= 119
+id-ReferenceClockAvailability ProtocolIE-ID ::= 435
+id-ReferenceSFNoffset ProtocolIE-ID ::= 436
+id-InformationExchangeID ProtocolIE-ID ::= 444
+id-InformationExchangeObjectType-InfEx-Rqst ProtocolIE-ID ::= 445
+id-InformationType ProtocolIE-ID ::= 446
+id-InformationReportCharacteristics ProtocolIE-ID ::= 447
+id-InformationExchangeObjectType-InfEx-Rsp ProtocolIE-ID ::= 448
+id-InformationExchangeObjectType-InfEx-Rprt ProtocolIE-ID ::= 449
+id-IPDLParameter-Information-Cell-ReconfRqstFDD ProtocolIE-ID ::= 451
+id-IPDLParameter-Information-Cell-SetupRqstFDD ProtocolIE-ID ::= 452
+id-IPDLParameter-Information-Cell-ReconfRqstTDD ProtocolIE-ID ::= 453
+id-IPDLParameter-Information-Cell-SetupRqstTDD ProtocolIE-ID ::= 454
+id-DL-DPCH-LCR-Information-RL-SetupRqstTDD ProtocolIE-ID ::= 74
+id-DwPCH-LCR-Information ProtocolIE-ID ::= 78
+id-DwPCH-LCR-InformationList-AuditRsp ProtocolIE-ID ::= 90
+id-DwPCH-LCR-Information-Cell-SetupRqstTDD ProtocolIE-ID ::= 97
+id-DwPCH-LCR-Information-Cell-ReconfRqstTDD ProtocolIE-ID ::= 99
+id-DwPCH-LCR-Information-ResourceStatusInd ProtocolIE-ID ::= 101
+id-maxFACH-Power-LCR-CTCH-SetupRqstTDD ProtocolIE-ID ::= 154
+id-maxFACH-Power-LCR-CTCH-ReconfRqstTDD ProtocolIE-ID ::= 174
+id-FPACH-LCR-Information ProtocolIE-ID ::= 290
+id-FPACH-LCR-Information-AuditRsp ProtocolIE-ID ::= 292
+id-FPACH-LCR-InformationList-AuditRsp ProtocolIE-ID ::= 22
+id-FPACH-LCR-InformationList-ResourceStatusInd ProtocolIE-ID ::= 311
+id-FPACH-LCR-Parameters-CTCH-SetupRqstTDD ProtocolIE-ID ::= 312
+id-FPACH-LCR-Parameters-CTCH-ReconfRqstTDD ProtocolIE-ID ::= 314
+id-PCCPCH-LCR-Information-Cell-SetupRqstTDD ProtocolIE-ID ::= 456
+id-PCH-Power-LCR-CTCH-SetupRqstTDD ProtocolIE-ID ::= 457
+id-PCH-Power-LCR-CTCH-ReconfRqstTDD ProtocolIE-ID ::= 458
+id-PICH-LCR-Parameters-CTCH-SetupRqstTDD ProtocolIE-ID ::= 459
+id-PRACH-LCR-ParametersList-CTCH-SetupRqstTDD ProtocolIE-ID ::= 461
+id-RL-InformationResponse-LCR-RL-SetupRspTDD ProtocolIE-ID ::= 463
+id-Secondary-CCPCH-LCR-parameterList-CTCH-SetupRqstTDD ProtocolIE-ID ::= 465
+id-TimeSlot ProtocolIE-ID ::= 495
+id-TimeSlotConfigurationList-LCR-Cell-ReconfRqstTDD ProtocolIE-ID ::= 466
+id-TimeSlotConfigurationList-LCR-Cell-SetupRqstTDD ProtocolIE-ID ::= 467
+id-TimeslotISCP-LCR-InfoList-RL-SetupRqstTDD ProtocolIE-ID ::= 468
+id-TimeSlotLCR-CM-Rqst ProtocolIE-ID ::= 469
+id-UL-DPCH-LCR-Information-RL-SetupRqstTDD ProtocolIE-ID ::= 470
+id-DL-DPCH-InformationItem-LCR-RL-AdditionRqstTDD ProtocolIE-ID ::= 472
+id-UL-DPCH-InformationItem-LCR-RL-AdditionRqstTDD ProtocolIE-ID ::= 473
+id-TimeslotISCP-InformationList-LCR-RL-AdditionRqstTDD ProtocolIE-ID ::= 474
+id-DL-DPCH-LCR-InformationAddList-RL-ReconfPrepTDD ProtocolIE-ID ::= 475
+id-DL-DPCH-LCR-InformationModify-AddList-RL-ReconfPrepTDD ProtocolIE-ID ::= 477
+id-DL-Timeslot-LCR-InformationModify-ModifyList-RL-ReconfPrepTDD ProtocolIE-ID ::= 479
+id-TimeslotISCPInfoList-LCR-DL-PC-RqstTDD ProtocolIE-ID ::= 480
+id-UL-DPCH-LCR-InformationAddListIE-RL-ReconfPrepTDD ProtocolIE-ID ::= 481
+id-UL-DPCH-LCR-InformationModify-AddList ProtocolIE-ID ::= 483
+id-UL-TimeslotLCR-Information-RL-ReconfPrepTDD ProtocolIE-ID ::= 485
+id-UL-SIRTarget ProtocolIE-ID ::= 510
+id-PDSCH-AddInformation-LCR-PSCH-ReconfRqst ProtocolIE-ID ::= 486
+id-PDSCH-AddInformation-LCR-AddListIE-PSCH-ReconfRqst ProtocolIE-ID ::= 487
+id-PDSCH-Information-Cell-SetupRqstFDD ProtocolIE-ID ::= 26
+id-PDSCH-Information-Cell-ReconfRqstFDD ProtocolIE-ID ::= 27
+id-PDSCH-ModifyInformation-LCR-PSCH-ReconfRqst ProtocolIE-ID ::= 488
+id-PDSCH-ModifyInformation-LCR-ModifyListIE-PSCH-ReconfRqst ProtocolIE-ID ::= 489
+id-PUSCH-AddInformation-LCR-PSCH-ReconfRqst ProtocolIE-ID ::= 490
+id-PUSCH-AddInformation-LCR-AddListIE-PSCH-ReconfRqst ProtocolIE-ID ::= 491
+id-PUSCH-ModifyInformation-LCR-PSCH-ReconfRqst ProtocolIE-ID ::= 492
+id-PUSCH-ModifyInformation-LCR-ModifyListIE-PSCH-ReconfRqst ProtocolIE-ID ::= 493
+id-timeslotInfo-CellSyncInitiationRqstTDD ProtocolIE-ID ::= 496
+id-SyncReportType-CellSyncReprtTDD ProtocolIE-ID ::= 497
+id-Power-Local-Cell-Group-InformationItem-AuditRsp ProtocolIE-ID ::= 498
+id-Power-Local-Cell-Group-InformationItem-ResourceStatusInd ProtocolIE-ID ::= 499
+id-Power-Local-Cell-Group-InformationItem2-ResourceStatusInd ProtocolIE-ID ::= 500
+id-Power-Local-Cell-Group-InformationList-AuditRsp ProtocolIE-ID ::= 501
+id-Power-Local-Cell-Group-InformationList-ResourceStatusInd ProtocolIE-ID ::= 502
+id-Power-Local-Cell-Group-InformationList2-ResourceStatusInd ProtocolIE-ID ::= 503
+id-Power-Local-Cell-Group-ID ProtocolIE-ID ::= 504
+id-PUSCH-Info-DM-Rqst ProtocolIE-ID ::= 505
+id-PUSCH-Info-DM-Rsp ProtocolIE-ID ::= 506
+id-PUSCH-Info-DM-Rprt ProtocolIE-ID ::= 507
+id-InitDL-Power ProtocolIE-ID ::= 509
+id-cellSyncBurstRepetitionPeriod ProtocolIE-ID ::= 511
+id-ReportCharacteristicsType-OnModification ProtocolIE-ID ::= 512
+id-SFNSFNMeasurementValueInformation ProtocolIE-ID ::= 513
+id-SFNSFNMeasurementThresholdInformation ProtocolIE-ID ::= 514
+id-TUTRANGPSMeasurementValueInformation ProtocolIE-ID ::= 515
+id-TUTRANGPSMeasurementThresholdInformation ProtocolIE-ID ::= 516
+id-Rx-Timing-Deviation-Value-LCR ProtocolIE-ID ::= 520
+id-RL-InformationResponse-LCR-RL-AdditionRspTDD ProtocolIE-ID ::= 51
+id-DL-PowerBalancing-Information ProtocolIE-ID ::= 28
+id-DL-PowerBalancing-ActivationIndicator ProtocolIE-ID ::= 29
+id-DL-PowerBalancing-UpdatedIndicator ProtocolIE-ID ::= 30
+id-CCTrCH-Initial-DL-Power-RL-SetupRqstTDD ProtocolIE-ID ::= 517
+id-CCTrCH-Initial-DL-Power-RL-AdditionRqstTDD ProtocolIE-ID ::= 518
+id-CCTrCH-Initial-DL-Power-RL-ReconfPrepTDD ProtocolIE-ID ::= 519
+id-IPDLParameter-Information-LCR-Cell-SetupRqstTDD ProtocolIE-ID ::= 41
+id-IPDLParameter-Information-LCR-Cell-ReconfRqstTDD ProtocolIE-ID ::= 42
+id-HS-PDSCH-HS-SCCH-MaxPower-PSCH-ReconfRqst ProtocolIE-ID ::= 522
+id-HS-PDSCH-HS-SCCH-ScramblingCode-PSCH-ReconfRqst ProtocolIE-ID ::= 523
+id-HS-PDSCH-FDD-Code-Information-PSCH-ReconfRqst ProtocolIE-ID ::= 524
+id-HS-SCCH-FDD-Code-Information-PSCH-ReconfRqst ProtocolIE-ID ::= 525
+id-HS-PDSCH-TDD-Information-PSCH-ReconfRqst ProtocolIE-ID ::= 526
+id-Add-To-HS-SCCH-Resource-Pool-PSCH-ReconfRqst ProtocolIE-ID ::= 527
+id-Modify-HS-SCCH-Resource-Pool-PSCH-ReconfRqst ProtocolIE-ID ::= 528
+id-Delete-From-HS-SCCH-Resource-Pool-PSCH-ReconfRqst ProtocolIE-ID ::= 529
+id-bindingID ProtocolIE-ID ::= 102
+id-RL-Specific-DCH-Info ProtocolIE-ID ::= 103
+id-transportlayeraddress ProtocolIE-ID ::= 104
+id-DelayedActivation ProtocolIE-ID ::= 231
+id-DelayedActivationList-RL-ActivationCmdFDD ProtocolIE-ID ::= 232
+id-DelayedActivationInformation-RL-ActivationCmdFDD ProtocolIE-ID ::= 233
+id-DelayedActivationList-RL-ActivationCmdTDD ProtocolIE-ID ::= 234
+id-DelayedActivationInformation-RL-ActivationCmdTDD ProtocolIE-ID ::= 235
+id-neighbouringTDDCellMeasurementInformationLCR ProtocolIE-ID ::= 58
+id-SYNCDlCodeId-TransInitLCR-CellSyncInitiationRqstTDD ProtocolIE-ID ::= 543
+id-SYNCDlCodeId-MeasureInitLCR-CellSyncInitiationRqstTDD ProtocolIE-ID ::= 544
+id-SYNCDlCodeIdTransReconfInfoLCR-CellSyncReconfRqstTDD ProtocolIE-ID ::= 545
+id-SYNCDlCodeIdMeasReconfigurationLCR-CellSyncReconfRqstTDD ProtocolIE-ID ::= 546
+id-SYNCDlCodeIdMeasInfoList-CellSyncReconfRqstTDD ProtocolIE-ID ::= 547
+id-SyncDLCodeIdsMeasInfoList-CellSyncReprtTDD ProtocolIE-ID ::= 548
+id-SyncDLCodeIdThreInfoLCR ProtocolIE-ID ::= 549
+id-NSubCyclesPerCyclePeriod-CellSyncReconfRqstTDD ProtocolIE-ID ::= 550
+id-DwPCH-Power ProtocolIE-ID ::= 551
+id-AccumulatedClockupdate-CellSyncReprtTDD ProtocolIE-ID ::= 552
+id-Angle-Of-Arrival-Value-LCR ProtocolIE-ID ::= 521
+id-HSDSCH-FDD-Information ProtocolIE-ID ::= 530
+id-HSDSCH-FDD-Information-Response ProtocolIE-ID ::= 531
+id-HSDSCH-Information-to-Modify ProtocolIE-ID ::= 534
+id-HSDSCH-RNTI ProtocolIE-ID ::= 535
+id-HSDSCH-TDD-Information ProtocolIE-ID ::= 536
+id-HSDSCH-TDD-Information-Response ProtocolIE-ID ::= 537
+id-HSPDSCH-RL-ID ProtocolIE-ID ::= 541
+id-PrimCCPCH-RSCP-DL-PC-RqstTDD ProtocolIE-ID ::= 542
+id-Qth-Parameter ProtocolIE-ID ::= 64
+id-PDSCH-RL-ID ProtocolIE-ID ::= 66
+id-HSDSCH-RearrangeList-Bearer-RearrangeInd ProtocolIE-ID ::= 553
+id-UL-Synchronisation-Parameters-LCR ProtocolIE-ID ::= 554
+id-HSDSCH-FDD-Update-Information ProtocolIE-ID ::= 555
+id-HSDSCH-TDD-Update-Information ProtocolIE-ID ::= 556
+id-DL-DPCH-TimeSlotFormat-LCR-ModifyItem-RL-ReconfPrepTDD ProtocolIE-ID ::= 558
+id-UL-DPCH-TimeSlotFormat-LCR-ModifyItem-RL-ReconfPrepTDD ProtocolIE-ID ::= 559
+id-TDD-TPC-UplinkStepSize-LCR-RL-SetupRqstTDD ProtocolIE-ID ::= 560
+id-TDD-TPC-UplinkStepSize-LCR-RL-AdditionRqstTDD ProtocolIE-ID ::= 561
+id-TDD-TPC-DownlinkStepSize-RL-AdditionRqstTDD ProtocolIE-ID ::= 562
+id-TDD-TPC-UplinkStepSize-InformationAdd-LCR-RL-ReconfPrepTDD ProtocolIE-ID ::= 563
+id-TDD-TPC-UplinkStepSize-InformationModify-LCR-RL-ReconfPrepTDD ProtocolIE-ID ::= 564
+id-TDD-TPC-DownlinkStepSize-InformationModify-RL-ReconfPrepTDD ProtocolIE-ID ::= 565
+id-TDD-TPC-DownlinkStepSize-InformationAdd-RL-ReconfPrepTDD ProtocolIE-ID ::= 566
+id-CCTrCH-Maximum-DL-Power-RL-SetupRqstTDD ProtocolIE-ID ::= 567
+id-CCTrCH-Minimum-DL-Power-RL-SetupRqstTDD ProtocolIE-ID ::= 568
+id-CCTrCH-Maximum-DL-Power-RL-AdditionRqstTDD ProtocolIE-ID ::= 569
+id-CCTrCH-Minimum-DL-Power-RL-AdditionRqstTDD ProtocolIE-ID ::= 570
+id-CCTrCH-Maximum-DL-Power-InformationAdd-RL-ReconfPrepTDD ProtocolIE-ID ::= 571
+id-CCTrCH-Minimum-DL-Power-InformationAdd-RL-ReconfPrepTDD ProtocolIE-ID ::= 572
+id-CCTrCH-Maximum-DL-Power-InformationModify-RL-ReconfPrepTDD ProtocolIE-ID ::= 573
+id-CCTrCH-Minimum-DL-Power-InformationModify-RL-ReconfPrepTDD ProtocolIE-ID ::= 574
+id-Maximum-DL-Power-Modify-LCR-InformationModify-RL-ReconfPrepTDD ProtocolIE-ID ::= 575
+id-Minimum-DL-Power-Modify-LCR-InformationModify-RL-ReconfPrepTDD ProtocolIE-ID ::= 576
+id-DL-DPCH-LCR-InformationModify-ModifyList-RL-ReconfRqstTDD ProtocolIE-ID ::= 577
+id-CCTrCH-Maximum-DL-Power-InformationModify-RL-ReconfRqstTDD ProtocolIE-ID ::= 578
+id-CCTrCH-Minimum-DL-Power-InformationModify-RL-ReconfRqstTDD ProtocolIE-ID ::= 579
+id-Initial-DL-Power-TimeslotLCR-InformationItem ProtocolIE-ID ::= 580
+id-Maximum-DL-Power-TimeslotLCR-InformationItem ProtocolIE-ID ::= 581
+id-Minimum-DL-Power-TimeslotLCR-InformationItem ProtocolIE-ID ::= 582
+id-HS-DSCHProvidedBitRate ProtocolIE-ID ::= 583
+id-HS-DSCHRequiredPower ProtocolIE-ID ::= 585
+id-HS-DSCHRequiredPowerValue ProtocolIE-ID ::= 586
+id-TransmittedCarrierPowerOfAllCodesNotUsedForHS-PDSCHOrHS-SCCHTransmission ProtocolIE-ID ::= 587
+id-HS-SICH-Reception-Quality ProtocolIE-ID ::= 588
+id-HS-SICH-Reception-Quality-Measurement-Value ProtocolIE-ID ::= 589
+id-HSSICH-Info-DM-Rprt ProtocolIE-ID ::= 590
+id-HSSICH-Info-DM-Rqst ProtocolIE-ID ::= 591
+id-HSSICH-Info-DM-Rsp ProtocolIE-ID ::= 592
+id-Best-Cell-Portions-Value ProtocolIE-ID ::= 593
+id-Primary-CPICH-Usage-for-Channel-Estimation ProtocolIE-ID ::= 594
+id-Secondary-CPICH-Information-Change ProtocolIE-ID ::= 595
+id-NumberOfReportedCellPortions ProtocolIE-ID ::= 596
+id-TimeslotISCP-LCR-InfoList-RL-ReconfPrepTDD ProtocolIE-ID ::= 599
+id-Unidirectional-DCH-Indicator ProtocolIE-ID ::= 602
+id-TimingAdjustmentValueLCR ProtocolIE-ID ::= 603
+id-multipleRL-dl-DPCH-InformationList ProtocolIE-ID ::= 604
+id-multipleRL-dl-DPCH-InformationModifyList ProtocolIE-ID ::= 605
+id-multipleRL-ul-DPCH-InformationList ProtocolIE-ID ::= 606
+id-multipleRL-ul-DPCH-InformationModifyList ProtocolIE-ID ::= 607
+id-RL-ID ProtocolIE-ID ::= 608
+id-SAT-Info-Almanac-ExtItem ProtocolIE-ID ::= 609
+id-HSDPA-Capability ProtocolIE-ID ::= 610
+id-HSDSCH-Resources-Information-AuditRsp ProtocolIE-ID ::= 611
+id-HSDSCH-Resources-Information-ResourceStatusInd ProtocolIE-ID ::= 612
+id-HSDSCH-MACdFlows-to-Add ProtocolIE-ID ::= 613
+id-HSDSCH-MACdFlows-to-Delete ProtocolIE-ID ::= 614
+id-HSDSCH-Information-to-Modify-Unsynchronised ProtocolIE-ID ::= 615
+id-TnlQos ProtocolIE-ID ::= 616
+id-PrimaryCCPCH-RSCP-Delta ProtocolIE-ID ::= 623
+
+
+END
diff --git a/lib/asn1/test/asn1_SUITE_data/nbapsystem/NBAP-Containers.asn b/lib/asn1/test/asn1_SUITE_data/nbapsystem/NBAP-Containers.asn
new file mode 100755
index 0000000000..fb08451103
--- /dev/null
+++ b/lib/asn1/test/asn1_SUITE_data/nbapsystem/NBAP-Containers.asn
@@ -0,0 +1,197 @@
+-- **************************************************************
+--
+-- Container definitions
+--
+-- **************************************************************
+
+NBAP-Containers {
+itu-t (0) identified-organization (4) etsi (0) mobileDomain (0)
+umts-Access (20) modules (3) nbap (2) version1 (1) nbap-Containers (5) }
+
+DEFINITIONS AUTOMATIC TAGS ::=
+
+BEGIN
+
+-- **************************************************************
+--
+-- IE parameter types from other modules.
+--
+-- **************************************************************
+
+IMPORTS
+ maxProtocolExtensions,
+ maxPrivateIEs,
+ maxProtocolIEs,
+ Criticality,
+ Presence,
+ PrivateIE-ID,
+ ProtocolIE-ID
+FROM NBAP-CommonDataTypes;
+
+-- **************************************************************
+--
+-- Class Definition for Protocol IEs
+--
+-- **************************************************************
+
+NBAP-PROTOCOL-IES ::= CLASS {
+ &id ProtocolIE-ID UNIQUE,
+ &criticality Criticality,
+ &Value,
+ &presence Presence
+}
+WITH SYNTAX {
+ ID &id
+ CRITICALITY &criticality
+ TYPE &Value
+ PRESENCE &presence
+}
+
+-- **************************************************************
+--
+-- Class Definition for Protocol IEs
+--
+-- **************************************************************
+
+NBAP-PROTOCOL-IES-PAIR ::= CLASS {
+ &id ProtocolIE-ID UNIQUE,
+ &firstCriticality Criticality,
+ &FirstValue,
+ &secondCriticality Criticality,
+ &SecondValue,
+ &presence Presence
+}
+WITH SYNTAX {
+ ID &id
+ FIRST CRITICALITY &firstCriticality
+ FIRST TYPE &FirstValue
+ SECOND CRITICALITY &secondCriticality
+ SECOND TYPE &SecondValue
+ PRESENCE &presence
+}
+
+-- **************************************************************
+--
+-- Class Definition for Protocol Extensions
+--
+-- **************************************************************
+
+NBAP-PROTOCOL-EXTENSION ::= CLASS {
+ &id ProtocolIE-ID UNIQUE,
+ &criticality Criticality,
+ &Extension,
+ &presence Presence
+}
+WITH SYNTAX {
+ ID &id
+ CRITICALITY &criticality
+ EXTENSION &Extension
+ PRESENCE &presence
+}
+
+-- **************************************************************
+--
+-- Class Definition for Private IEs
+--
+-- **************************************************************
+
+NBAP-PRIVATE-IES ::= CLASS {
+ &id PrivateIE-ID,
+ &criticality Criticality,
+ &Value,
+ &presence Presence
+}
+WITH SYNTAX {
+ ID &id
+ CRITICALITY &criticality
+ TYPE &Value
+ PRESENCE &presence
+}
+
+-- **************************************************************
+--
+-- Container for Protocol IEs
+--
+-- **************************************************************
+
+ProtocolIE-Container {NBAP-PROTOCOL-IES : IEsSetParam} ::=
+ SEQUENCE (SIZE (0..maxProtocolIEs)) OF
+ ProtocolIE-Field {{IEsSetParam}}
+
+ProtocolIE-Single-Container {NBAP-PROTOCOL-IES : IEsSetParam} ::=
+ ProtocolIE-Field {{IEsSetParam}}
+
+ProtocolIE-Field {NBAP-PROTOCOL-IES : IEsSetParam} ::= SEQUENCE {
+ id NBAP-PROTOCOL-IES.&id ({IEsSetParam}),
+ criticality NBAP-PROTOCOL-IES.&criticality ({IEsSetParam}{@id}),
+ value NBAP-PROTOCOL-IES.&Value ({IEsSetParam}{@id})
+}
+
+-- **************************************************************
+--
+-- Container for Protocol IE Pairs
+--
+-- **************************************************************
+
+ProtocolIE-ContainerPair {NBAP-PROTOCOL-IES-PAIR : IEsSetParam} ::=
+ SEQUENCE (SIZE (0..maxProtocolIEs)) OF
+ ProtocolIE-FieldPair {{IEsSetParam}}
+
+ProtocolIE-FieldPair {NBAP-PROTOCOL-IES-PAIR : IEsSetParam} ::= SEQUENCE {
+ id NBAP-PROTOCOL-IES-PAIR.&id ({IEsSetParam}),
+ firstCriticality NBAP-PROTOCOL-IES-PAIR.&firstCriticality ({IEsSetParam}{@id}),
+ firstValue NBAP-PROTOCOL-IES-PAIR.&FirstValue ({IEsSetParam}{@id}),
+ secondCriticality NBAP-PROTOCOL-IES-PAIR.&secondCriticality ({IEsSetParam}{@id}),
+ secondValue NBAP-PROTOCOL-IES-PAIR.&SecondValue ({IEsSetParam}{@id})
+}
+
+-- **************************************************************
+--
+-- Container Lists for Protocol IE Containers
+--
+-- **************************************************************
+
+ProtocolIE-ContainerList {INTEGER : lowerBound, INTEGER : upperBound, NBAP-PROTOCOL-IES : IEsSetParam} ::=
+ SEQUENCE (SIZE (lowerBound..upperBound)) OF
+ ProtocolIE-Container {{IEsSetParam}}
+
+ProtocolIE-ContainerPairList {INTEGER : lowerBound, INTEGER : upperBound, NBAP-PROTOCOL-IES-PAIR : IEsSetParam} ::=
+ SEQUENCE (SIZE (lowerBound..upperBound)) OF
+ ProtocolIE-ContainerPair {{IEsSetParam}}
+
+-- **************************************************************
+--
+-- Container for Protocol Extensions
+--
+-- **************************************************************
+
+ProtocolExtensionContainer {NBAP-PROTOCOL-EXTENSION : ExtensionSetParam} ::=
+ SEQUENCE (SIZE (1..maxProtocolExtensions)) OF
+ ProtocolExtensionField {{ExtensionSetParam}}
+
+ProtocolExtensionField {NBAP-PROTOCOL-EXTENSION : ExtensionSetParam} ::= SEQUENCE {
+ id NBAP-PROTOCOL-EXTENSION.&id ({ExtensionSetParam}),
+ criticality NBAP-PROTOCOL-EXTENSION.&criticality ({ExtensionSetParam}{@id}),
+ extensionValue NBAP-PROTOCOL-EXTENSION.&Extension ({ExtensionSetParam}{@id})
+}
+
+-- **************************************************************
+--
+-- Container for Private IEs
+--
+-- **************************************************************
+
+PrivateIE-Container {NBAP-PRIVATE-IES : IEsSetParam} ::=
+ SEQUENCE (SIZE (1..maxPrivateIEs)) OF
+ PrivateIE-Field {{IEsSetParam}}
+
+PrivateIE-Field {NBAP-PRIVATE-IES : IEsSetParam} ::= SEQUENCE {
+ id NBAP-PRIVATE-IES.&id
+ ({IEsSetParam}),
+ criticality NBAP-PRIVATE-IES.&criticality
+ ({IEsSetParam}{@id}),
+ value NBAP-PRIVATE-IES.&Value
+ ({IEsSetParam}{@id})
+}
+
+END
diff --git a/lib/asn1/test/asn1_SUITE_data/nbapsystem/NBAP-IEs.asn b/lib/asn1/test/asn1_SUITE_data/nbapsystem/NBAP-IEs.asn
new file mode 100755
index 0000000000..848d8f6099
--- /dev/null
+++ b/lib/asn1/test/asn1_SUITE_data/nbapsystem/NBAP-IEs.asn
@@ -0,0 +1,4127 @@
+--******************************************************************************
+--
+-- Information Element Definitions
+--
+--******************************************************************************
+
+NBAP-IEs {
+itu-t (0) identified-organization (4) etsi (0) mobileDomain (0)
+umts-Access (20) modules (3) nbap (2) version1 (1) nbap-IEs (2) }
+
+DEFINITIONS AUTOMATIC TAGS ::=
+BEGIN
+
+IMPORTS
+ maxNrOfRLs,
+ maxNrOfTFCs,
+ maxNrOfErrors,
+ maxCTFC,
+ maxNrOfTFs,
+ maxTTI-count,
+ maxRateMatching,
+ maxCodeNrComp-1,
+ maxHS-PDSCHCodeNrComp-1,
+ maxHS-SCCHCodeNrComp-1,
+ maxNrOfCellSyncBursts,
+ maxNrOfCodeGroups,
+ maxNrOfMeasNCell,
+ maxNrOfMeasNCell-1,
+ maxNrOfReceptsPerSyncFrame,
+ maxNrOfTFCIGroups,
+ maxNrOfTFCI1Combs,
+ maxNrOfTFCI2Combs,
+ maxNrOfTFCI2Combs-1,
+ maxNrOfSF,
+ maxTGPS,
+ maxNrOfUSCHs,
+ maxNrOfULTSs,
+ maxNrOfULTSLCRs,
+ maxNrOfDPCHs,
+ maxNrOfDPCHLCRs,
+ maxNrOfCodes,
+ maxNrOfDSCHs,
+ maxNrOfDLTSs,
+ maxNrOfDLTSLCRs,
+ maxNrOfDCHs,
+ maxNrOfLevels,
+ maxNoGPSItems,
+ maxNoSat,
+ maxNrOfCellPortionsPerCell,
+ maxNrOfCellPortionsPerCell-1,
+ maxNrOfHSSCCHs,
+ maxNrOfHSSCCHCodes,
+ maxNrOfMACdFlows,
+ maxNrOfMACdFlows-1,
+ maxNrOfMACdPDUIndexes,
+ maxNrOfMACdPDUIndexes-1,
+ maxNrOfPriorityQueues,
+ maxNrOfPriorityQueues-1,
+ maxNrOfHARQProcesses,
+ maxNrOfSyncDLCodesLCR,
+ maxNrOfSyncFramesLCR,
+ maxNrOfContextsOnUeList,
+ maxNrOfPriorityClasses,
+ maxNrOfSatAlmanac-maxNoSat,
+
+ id-MessageStructure,
+ id-ReportCharacteristicsType-OnModification,
+ id-Rx-Timing-Deviation-Value-LCR,
+ id-SFNSFNMeasurementValueInformation,
+ id-SFNSFNMeasurementThresholdInformation,
+ id-TUTRANGPSMeasurementValueInformation,
+ id-TUTRANGPSMeasurementThresholdInformation,
+ id-TypeOfError,
+ id-transportlayeraddress,
+ id-bindingID,
+ id-Angle-Of-Arrival-Value-LCR,
+ id-SyncDLCodeIdThreInfoLCR,
+ id-neighbouringTDDCellMeasurementInformationLCR,
+ id-HS-SICH-Reception-Quality,
+ id-HS-SICH-Reception-Quality-Measurement-Value,
+ id-Initial-DL-Power-TimeslotLCR-InformationItem,
+ id-Maximum-DL-Power-TimeslotLCR-InformationItem,
+ id-Minimum-DL-Power-TimeslotLCR-InformationItem,
+ id-TransmittedCarrierPowerOfAllCodesNotUsedForHS-PDSCHOrHS-SCCHTransmission,
+ id-HS-DSCHRequiredPower,
+ id-HS-DSCHProvidedBitRate,
+ id-HS-DSCHRequiredPowerValue,
+ id-Best-Cell-Portions-Value,
+ id-Unidirectional-DCH-Indicator,
+ id-SAT-Info-Almanac-ExtItem,
+ id-TnlQos
+FROM NBAP-Constants
+
+ Criticality,
+ ProcedureID,
+ ProtocolIE-ID,
+ TransactionID,
+ TriggeringMessage
+FROM NBAP-CommonDataTypes
+
+ NBAP-PROTOCOL-IES,
+ ProtocolExtensionContainer{},
+ ProtocolIE-Single-Container{},
+ NBAP-PROTOCOL-EXTENSION
+FROM NBAP-Containers;
+
+-- ==========================================
+-- A
+-- ==========================================
+
+AckNack-RepetitionFactor ::= INTEGER (1..4,...)
+-- Step: 1
+
+Ack-Power-Offset ::= INTEGER (0..8,...)
+-- According to mapping in ref. [9] subclause 4.2.1
+
+Acknowledged-PCPCH-access-preambles ::= INTEGER (0..15,...)
+-- According to mapping in [22].
+
+Acknowledged-PRACH-preambles-Value ::= INTEGER(0..240,...)
+-- According to mapping in [22].
+
+AddorDeleteIndicator ::= ENUMERATED {
+ add,
+ delete
+}
+
+Active-Pattern-Sequence-Information ::= SEQUENCE {
+ cMConfigurationChangeCFN CFN,
+ transmission-Gap-Pattern-Sequence-Status Transmission-Gap-Pattern-Sequence-Status-List OPTIONAL,
+ iE-Extensions ProtocolExtensionContainer { {Active-Pattern-Sequence-Information-ExtIEs} } OPTIONAL,
+ ...
+}
+
+Active-Pattern-Sequence-Information-ExtIEs NBAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+Transmission-Gap-Pattern-Sequence-Status-List ::= SEQUENCE (SIZE (0..maxTGPS)) OF
+ SEQUENCE {
+ tGPSID TGPSID,
+ tGPRC TGPRC,
+ tGCFN CFN,
+ iE-Extensions ProtocolExtensionContainer { { Transmission-Gap-Pattern-Sequence-Status-List-ExtIEs } } OPTIONAL,
+ ...
+}
+
+Transmission-Gap-Pattern-Sequence-Status-List-ExtIEs NBAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+AICH-Power ::= INTEGER (-22..5)
+-- Offset in dB.
+
+AICH-TransmissionTiming ::= ENUMERATED {
+ v0,
+ v1
+}
+
+AllocationRetentionPriority ::= SEQUENCE {
+ priorityLevel PriorityLevel,
+ pre-emptionCapability Pre-emptionCapability,
+ pre-emptionVulnerability Pre-emptionVulnerability,
+ iE-Extensions ProtocolExtensionContainer { {AllocationRetentionPriority-ExtIEs} } OPTIONAL,
+ ...
+}
+
+AllocationRetentionPriority-ExtIEs NBAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+Angle-Of-Arrival-Value-LCR ::= SEQUENCE {
+ aOA-LCR AOA-LCR,
+ aOA-LCR-Accuracy-Class AOA-LCR-Accuracy-Class,
+ iE-Extensions ProtocolExtensionContainer { {Angle-Of-Arrival-Value-LCR-ExtIEs} } OPTIONAL,
+...
+}
+
+Angle-Of-Arrival-Value-LCR-ExtIEs NBAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+AOA-LCR ::= INTEGER (0..719)
+-- Angle Of Arrival for 1.28Mcps TDD
+
+AOA-LCR-Accuracy-Class ::= ENUMERATED {a,b,c,d,e,f,g,h,...}
+
+APPreambleSignature ::= INTEGER (0..15)
+
+APSubChannelNumber ::= INTEGER (0..11)
+
+AvailabilityStatus ::= ENUMERATED {
+ empty,
+ in-test,
+ failed,
+ power-off,
+ off-line,
+ off-duty,
+ dependency,
+ degraded,
+ not-installed,
+ log-full,
+ ...
+}
+
+-- ==========================================
+-- B
+-- ==========================================
+
+BCCH-ModificationTime ::= INTEGER (0..511)
+-- Time = BCCH-ModificationTime * 8
+-- Range 0 to 4088, step 8
+-- All SFN values in which MIB may be mapped are allowed
+
+Best-Cell-Portions-Value::= SEQUENCE (SIZE (1..maxNrOfCellPortionsPerCell)) OF Best-Cell-Portions-Item
+
+Best-Cell-Portions-Item ::= SEQUENCE {
+ cellPortionID CellPortionID,
+ sIRValue SIR-Value,
+ iE-Extensions ProtocolExtensionContainer { { Best-Cell-Portions-Item-ExtIEs} } OPTIONAL,
+ ...
+}
+
+Best-Cell-Portions-Item-ExtIEs NBAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+BindingID ::= OCTET STRING (SIZE (1..4, ...))
+-- If the Binding ID includes a UDP port, the UDP port is included in octet 1 and 2.The first octet of
+-- the UDP port field is included in the first octet of the Binding ID.
+
+BetaCD ::= INTEGER (0..15)
+
+BlockingPriorityIndicator ::= ENUMERATED {
+ high,
+ normal,
+ low,
+ ...
+}
+-- High priority: Block resource immediately.
+-- Normal priority: Block resource when idle or upon timer expiry.
+-- Low priority: Block resource when idle.
+
+SCTD-Indicator ::= ENUMERATED {
+ active,
+ inactive
+}
+
+-- ==========================================
+-- C
+-- ==========================================
+
+Cause ::= CHOICE {
+ radioNetwork CauseRadioNetwork,
+ transport CauseTransport,
+ protocol CauseProtocol,
+ misc CauseMisc,
+ ...
+}
+
+CauseMisc ::= ENUMERATED {
+ control-processing-overload,
+ hardware-failure,
+ oam-intervention,
+ not-enough-user-plane-processing-resources,
+ unspecified,
+ ...
+}
+
+CauseProtocol ::= ENUMERATED {
+ transfer-syntax-error,
+ abstract-syntax-error-reject,
+ abstract-syntax-error-ignore-and-notify,
+ message-not-compatible-with-receiver-state,
+ semantic-error,
+ unspecified,
+ abstract-syntax-error-falsely-constructed-message,
+ ...
+}
+
+CauseRadioNetwork ::= ENUMERATED {
+ unknown-C-ID,
+ cell-not-available,
+ power-level-not-supported,
+ dl-radio-resources-not-available,
+ ul-radio-resources-not-available,
+ rl-already-ActivatedOrAllocated,
+ nodeB-Resources-unavailable,
+ measurement-not-supported-for-the-object,
+ combining-resources-not-available,
+ requested-configuration-not-supported,
+ synchronisation-failure,
+ priority-transport-channel-established,
+ sIB-Origination-in-Node-B-not-Supported,
+ requested-tx-diversity-mode-not-supported,
+ unspecified,
+ bCCH-scheduling-error,
+ measurement-temporarily-not-available,
+ invalid-CM-settings,
+ reconfiguration-CFN-not-elapsed,
+ number-of-DL-codes-not-supported,
+ s-cipch-not-supported,
+ combining-not-supported,
+ ul-sf-not-supported,
+ dl-SF-not-supported,
+ common-transport-channel-type-not-supported,
+ dedicated-transport-channel-type-not-supported,
+ downlink-shared-channel-type-not-supported,
+ uplink-shared-channel-type-not-supported,
+ cm-not-supported,
+ tx-diversity-no-longer-supported,
+ unknown-Local-Cell-ID,
+ ...,
+ number-of-UL-codes-not-supported,
+ information-temporarily-not-available,
+ information-provision-not-supported-for-the-object,
+ cell-synchronisation-not-supported,
+ cell-synchronisation-adjustment-not-supported,
+ dpc-mode-change-not-supported,
+ iPDL-already-activated,
+ iPDL-not-supported,
+ iPDL-parameters-not-available,
+ frequency-acquisition-not-supported,
+ power-balancing-status-not-compatible,
+ requested-typeofbearer-re-arrangement-not-supported,
+ signalling-Bearer-Re-arrangement-not-supported,
+ bearer-Re-arrangement-needed,
+ delayed-activation-not-supported,
+ rl-timing-adjustment-not-supported
+}
+
+CauseTransport ::= ENUMERATED {
+ transport-resource-unavailable,
+ unspecified,
+ ...
+}
+
+CCTrCH-ID ::= INTEGER (0..15)
+
+CDSubChannelNumbers ::= BIT STRING {
+ subCh11(0),
+ subCh10(1),
+ subCh9(2),
+ subCh8(3),
+ subCh7(4),
+ subCh6(5),
+ subCh5(6),
+ subCh4(7),
+ subCh3(8),
+ subCh2(9),
+ subCh1(10),
+ subCh0(11)
+ } (SIZE (12))
+
+CellParameterID ::= INTEGER (0..127,...)
+
+CellPortionID ::= INTEGER (0..maxNrOfCellPortionsPerCell-1,...)
+
+CellSyncBurstCode ::= INTEGER(0..7, ...)
+
+CellSyncBurstCodeShift ::= INTEGER(0..7)
+
+CellSyncBurstRepetitionPeriod ::= INTEGER (0..4095)
+
+CellSyncBurstSIR ::= INTEGER (0..31)
+
+CellSyncBurstTiming ::= CHOICE {
+ initialPhase INTEGER (0..1048575,...),
+ steadyStatePhase INTEGER (0..255,...)
+}
+
+CellSyncBurstTimingLCR ::= CHOICE {
+ initialPhase INTEGER (0..524287,...),
+ steadyStatePhase INTEGER (0..127,...)
+}
+
+CellSyncBurstTimingThreshold ::= INTEGER(0..254)
+
+CFN ::= INTEGER (0..255)
+
+Channel-Assignment-Indication ::= ENUMERATED {
+ cA-Active,
+ cA-Inactive
+}
+
+ChipOffset ::= INTEGER (0..38399)
+-- Unit Chip
+
+C-ID ::= INTEGER (0..65535)
+
+Closedlooptimingadjustmentmode ::= ENUMERATED {
+ adj-1-slot,
+ adj-2-slot,
+ ...
+}
+
+CommonChannelsCapacityConsumptionLaw ::= SEQUENCE (SIZE(1..maxNrOfSF)) OF
+ SEQUENCE {
+ dl-Cost INTEGER (0..65535),
+ ul-Cost INTEGER (0..65535),
+ iE-Extensions ProtocolExtensionContainer { { CommonChannelsCapacityConsumptionLaw-ExtIEs } } OPTIONAL,
+ ...
+}
+
+CommonChannelsCapacityConsumptionLaw-ExtIEs NBAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+CommonMeasurementAccuracy ::= CHOICE {
+ tUTRANGPSMeasurementAccuracyClass TUTRANGPSAccuracyClass,
+ ...
+}
+
+CommonMeasurementType ::= ENUMERATED {
+ received-total-wide-band-power,
+ transmitted-carrier-power,
+ acknowledged-prach-preambles,
+ ul-timeslot-iscp,
+ acknowledged-PCPCH-access-preambles,
+ detected-PCPCH-access-preambles,
+ ...,
+ uTRAN-GPS-Timing-of-Cell-Frames-for-UE-Positioning,
+ sFN-SFN-Observed-Time-Difference,
+ transmittedCarrierPowerOfAllCodesNotUsedForHS-PDSCHOrHS-SCCHTransmission,
+ hS-DSCH-Required-Power,
+ hS-DSCH-Provided-Bit-Rate
+}
+
+CommonMeasurementValue ::= CHOICE {
+ transmitted-carrier-power Transmitted-Carrier-Power-Value,
+ received-total-wide-band-power Received-total-wide-band-power-Value,
+ acknowledged-prach-preambles Acknowledged-PRACH-preambles-Value,
+ uL-TimeslotISCP UL-TimeslotISCP-Value,
+ acknowledged-PCPCH-access-preambles Acknowledged-PCPCH-access-preambles,
+ detected-PCPCH-access-preambles Detected-PCPCH-access-preambles,
+ ...,
+ extension-CommonMeasurementValue Extension-CommonMeasurementValue
+}
+
+Extension-CommonMeasurementValue ::= ProtocolIE-Single-Container {{ Extension-CommonMeasurementValueIE }}
+
+Extension-CommonMeasurementValueIE NBAP-PROTOCOL-IES ::= {
+ { ID id-TUTRANGPSMeasurementValueInformation CRITICALITY ignore TYPE TUTRANGPSMeasurementValueInformation PRESENCE mandatory }|
+ { ID id-SFNSFNMeasurementValueInformation CRITICALITY ignore TYPE SFNSFNMeasurementValueInformation PRESENCE mandatory }|
+ { ID id-TransmittedCarrierPowerOfAllCodesNotUsedForHS-PDSCHOrHS-SCCHTransmission CRITICALITY ignore TYPE TransmittedCarrierPowerOfAllCodesNotUsedForHS-PDSCHOrHS-SCCHTransmissionValue PRESENCE mandatory }|
+ { ID id-HS-DSCHRequiredPower CRITICALITY ignore TYPE HS-DSCHRequiredPower PRESENCE mandatory }|
+ { ID id-HS-DSCHProvidedBitRate CRITICALITY ignore TYPE HS-DSCHProvidedBitRate PRESENCE mandatory }
+}
+
+CommonMeasurementValueInformation ::= CHOICE {
+ measurementAvailable CommonMeasurementAvailable,
+ measurementnotAvailable CommonMeasurementnotAvailable
+}
+
+CommonMeasurementAvailable::= SEQUENCE {
+ commonmeasurementValue CommonMeasurementValue,
+ ie-Extensions ProtocolExtensionContainer { { CommonMeasurementAvailableItem-ExtIEs} } OPTIONAL,
+ ...
+}
+
+CommonMeasurementAvailableItem-ExtIEs NBAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+CommonMeasurementnotAvailable ::= NULL
+
+CommonPhysicalChannelID ::= INTEGER (0..255)
+
+Common-PhysicalChannel-Status-Information ::= SEQUENCE {
+ commonPhysicalChannelID CommonPhysicalChannelID,
+ resourceOperationalState ResourceOperationalState,
+ availabilityStatus AvailabilityStatus,
+ iE-Extensions ProtocolExtensionContainer { { Common-PhysicalChannel-Status-Information-ExtIEs} } OPTIONAL,
+ ...
+}
+
+Common-PhysicalChannel-Status-Information-ExtIEs NBAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+CommonTransportChannelID ::= INTEGER (0..255)
+
+CommonTransportChannel-InformationResponse ::= SEQUENCE {
+ commonTransportChannelID CommonTransportChannelID,
+ bindingID BindingID OPTIONAL,
+ transportLayerAddress TransportLayerAddress OPTIONAL,
+ iE-Extensions ProtocolExtensionContainer { { CommonTransportChannel-InformationResponse-ExtIEs} } OPTIONAL,
+ ...
+}
+
+CommonTransportChannel-InformationResponse-ExtIEs NBAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+Common-TransportChannel-Status-Information ::= SEQUENCE {
+ commonTransportChannelID CommonTransportChannelID,
+ resourceOperationalState ResourceOperationalState,
+ availabilityStatus AvailabilityStatus,
+ iE-Extensions ProtocolExtensionContainer { { Common-TransportChannel-Status-Information-ExtIEs} } OPTIONAL,
+ ...
+}
+
+Common-TransportChannel-Status-Information-ExtIEs NBAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+CommunicationControlPortID ::= INTEGER (0..65535)
+
+Compressed-Mode-Deactivation-Flag::= ENUMERATED {
+ deactivate,
+ maintain-Active
+}
+
+ConfigurationGenerationID ::= INTEGER (0..255)
+-- Value '0' means "No configuration"
+
+ConstantValue ::= INTEGER (-10..10,...)
+-- -10 dB - +10 dB
+-- unit dB
+-- step 1 dB
+
+CPCH-Allowed-Total-Rate ::= ENUMERATED {
+ v15,
+ v30,
+ v60,
+ v120,
+ v240,
+ v480,
+ v960,
+ v1920,
+ v2880,
+ v3840,
+ v4800,
+ v5760,
+ ...
+}
+
+CPCHScramblingCodeNumber ::= INTEGER (0..79)
+
+CPCH-UL-DPCCH-SlotFormat ::= INTEGER (0..2,...)
+
+CQI-Feedback-Cycle ::= ENUMERATED {v0, v2, v4, v8, v10, v20, v40, v80, v160,...}
+
+CQI-Power-Offset ::= INTEGER (0..8,...)
+-- According to mapping in ref. [9] subclause 4.2.1
+
+CQI-RepetitionFactor ::= INTEGER (1..4,...)
+-- Step: 1
+
+CriticalityDiagnostics ::= SEQUENCE {
+ procedureID ProcedureID OPTIONAL,
+ triggeringMessage TriggeringMessage OPTIONAL,
+ procedureCriticality Criticality OPTIONAL,
+ transactionID TransactionID OPTIONAL,
+ iEsCriticalityDiagnostics CriticalityDiagnostics-IE-List OPTIONAL,
+ iE-Extensions ProtocolExtensionContainer { {CriticalityDiagnostics-ExtIEs} } OPTIONAL,
+ ...
+}
+
+CriticalityDiagnostics-ExtIEs NBAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+CriticalityDiagnostics-IE-List ::= SEQUENCE (SIZE (1..maxNrOfErrors)) OF
+ SEQUENCE {
+ iECriticality Criticality,
+ iE-ID ProtocolIE-ID,
+ repetitionNumber RepetitionNumber0 OPTIONAL,
+ iE-Extensions ProtocolExtensionContainer { {CriticalityDiagnostics-IE-List-ExtIEs} } OPTIONAL,
+ ...
+ }
+
+CriticalityDiagnostics-IE-List-ExtIEs NBAP-PROTOCOL-EXTENSION ::= {
+ { ID id-MessageStructure CRITICALITY ignore EXTENSION MessageStructure PRESENCE optional }|
+ { ID id-TypeOfError CRITICALITY ignore EXTENSION TypeOfError PRESENCE mandatory },
+ ...
+}
+
+CRNC-CommunicationContextID ::= INTEGER (0..1048575)
+
+CSBMeasurementID ::= INTEGER (0..65535)
+
+CSBTransmissionID ::= INTEGER (0..65535)
+
+-- ==========================================
+-- D
+-- ==========================================
+
+DATA-ID ::= INTEGER (0..3)
+
+DCH-ID ::= INTEGER (0..255)
+
+DCH-FDD-Information ::= SEQUENCE (SIZE (1..maxNrOfDCHs)) OF DCH-FDD-InformationItem
+
+DCH-FDD-InformationItem ::= SEQUENCE {
+ payloadCRC-PresenceIndicator PayloadCRC-PresenceIndicator,
+ ul-FP-Mode UL-FP-Mode,
+ toAWS ToAWS,
+ toAWE ToAWE,
+ dCH-SpecificInformationList DCH-Specific-FDD-InformationList,
+ iE-Extensions ProtocolExtensionContainer { { DCH-FDD-InformationItem-ExtIEs} } OPTIONAL,
+ ...
+}
+
+DCH-FDD-InformationItem-ExtIEs NBAP-PROTOCOL-EXTENSION ::= {
+ { ID id-TnlQos CRITICALITY ignore EXTENSION TnlQos PRESENCE optional },
+ ...
+}
+
+DCH-Specific-FDD-InformationList ::= SEQUENCE (SIZE (1..maxNrOfDCHs)) OF DCH-Specific-FDD-Item
+
+DCH-Specific-FDD-Item ::= SEQUENCE {
+ dCH-ID DCH-ID,
+ ul-TransportFormatSet TransportFormatSet,
+ dl-TransportFormatSet TransportFormatSet,
+ allocationRetentionPriority AllocationRetentionPriority,
+ frameHandlingPriority FrameHandlingPriority,
+ qE-Selector QE-Selector,
+ iE-Extensions ProtocolExtensionContainer { { DCH-Specific-FDD-Item-ExtIEs} } OPTIONAL,
+ ...
+}
+
+DCH-Specific-FDD-Item-ExtIEs NBAP-PROTOCOL-EXTENSION ::= {
+ { ID id-Unidirectional-DCH-Indicator CRITICALITY reject EXTENSION Unidirectional-DCH-Indicator PRESENCE optional },
+ ...
+}
+
+DCH-InformationResponse ::= SEQUENCE (SIZE (1..maxNrOfDCHs)) OF DCH-InformationResponseItem
+
+DCH-InformationResponseItem ::= SEQUENCE {
+ dCH-ID DCH-ID,
+ bindingID BindingID OPTIONAL,
+ transportLayerAddress TransportLayerAddress OPTIONAL,
+ iE-Extensions ProtocolExtensionContainer { { DCH-InformationResponseItem-ExtIEs} } OPTIONAL,
+ ...
+}
+
+DCH-InformationResponseItem-ExtIEs NBAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+DCH-TDD-Information ::= SEQUENCE (SIZE (1..maxNrOfDCHs)) OF DCH-TDD-InformationItem
+
+DCH-TDD-InformationItem ::= SEQUENCE {
+ payloadCRC-PresenceIndicator PayloadCRC-PresenceIndicator,
+ ul-FP-Mode UL-FP-Mode,
+ toAWS ToAWS,
+ toAWE ToAWE,
+ dCH-SpecificInformationList DCH-Specific-TDD-InformationList,
+ iE-Extensions ProtocolExtensionContainer { { DCH-TDD-InformationItem-ExtIEs} } OPTIONAL,
+ ...
+}
+
+DCH-TDD-InformationItem-ExtIEs NBAP-PROTOCOL-EXTENSION ::= {
+ {ID id-TnlQos CRITICALITY ignore EXTENSION TnlQos PRESENCE optional},
+ ...
+}
+
+DCH-Specific-TDD-InformationList ::= SEQUENCE (SIZE (1..maxNrOfDCHs)) OF DCH-Specific-TDD-Item
+
+DCH-Specific-TDD-Item ::= SEQUENCE {
+ dCH-ID DCH-ID,
+ ul-CCTrCH-ID CCTrCH-ID,
+ dl-CCTrCH-ID CCTrCH-ID,
+ ul-TransportFormatSet TransportFormatSet,
+ dl-TransportFormatSet TransportFormatSet,
+ allocationRetentionPriority AllocationRetentionPriority,
+ frameHandlingPriority FrameHandlingPriority,
+ qE-Selector QE-Selector OPTIONAL,
+ -- This IE shall be present if DCH is part of set of Coordinated DCHs
+ iE-Extensions ProtocolExtensionContainer { { DCH-Specific-TDD-Item-ExtIEs} } OPTIONAL,
+ ...
+}
+
+DCH-Specific-TDD-Item-ExtIEs NBAP-PROTOCOL-EXTENSION ::= {
+ { ID id-Unidirectional-DCH-Indicator CRITICALITY reject EXTENSION Unidirectional-DCH-Indicator PRESENCE optional },
+ ...
+}
+
+FDD-DCHs-to-Modify ::= SEQUENCE (SIZE (1..maxNrOfDCHs)) OF FDD-DCHs-to-ModifyItem
+
+FDD-DCHs-to-ModifyItem ::= SEQUENCE {
+ ul-FP-Mode UL-FP-Mode OPTIONAL,
+ toAWS ToAWS OPTIONAL,
+ toAWE ToAWE OPTIONAL,
+ transportBearerRequestIndicator TransportBearerRequestIndicator,
+ dCH-SpecificInformationList DCH-ModifySpecificInformation-FDD,
+ iE-Extensions ProtocolExtensionContainer { { FDD-DCHs-to-ModifyItem-ExtIEs} } OPTIONAL,
+ ...
+}
+
+FDD-DCHs-to-ModifyItem-ExtIEs NBAP-PROTOCOL-EXTENSION ::= {
+ {ID id-TnlQos CRITICALITY ignore EXTENSION TnlQos PRESENCE optional},
+ ...
+}
+
+DCH-ModifySpecificInformation-FDD::= SEQUENCE (SIZE (1..maxNrOfDCHs)) OF DCH-ModifySpecificItem-FDD
+
+DCH-ModifySpecificItem-FDD::= SEQUENCE {
+ dCH-ID DCH-ID,
+ ul-TransportFormatSet TransportFormatSet OPTIONAL,
+ dl-TransportFormatSet TransportFormatSet OPTIONAL,
+ allocationRetentionPriority AllocationRetentionPriority OPTIONAL,
+ frameHandlingPriority FrameHandlingPriority OPTIONAL,
+ iE-Extensions ProtocolExtensionContainer { { DCH-ModifySpecificItem-FDD-ExtIEs} } OPTIONAL,
+ ...
+}
+
+DCH-ModifySpecificItem-FDD-ExtIEs NBAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+
+TDD-DCHs-to-Modify ::= SEQUENCE (SIZE (1..maxNrOfDCHs)) OF DCH-ModifyItem-TDD
+
+DCH-ModifyItem-TDD ::= SEQUENCE {
+ ul-FP-Mode UL-FP-Mode OPTIONAL,
+ toAWS ToAWS OPTIONAL,
+ toAWE ToAWE OPTIONAL,
+ transportBearerRequestIndicator TransportBearerRequestIndicator,
+ dCH-SpecificInformationList DCH-ModifySpecificInformation-TDD,
+ iE-Extensions ProtocolExtensionContainer { { TDD-DCHs-to-ModifyItem-ExtIEs} } OPTIONAL,
+ ...
+}
+
+TDD-DCHs-to-ModifyItem-ExtIEs NBAP-PROTOCOL-EXTENSION ::= {
+ {ID id-TnlQos CRITICALITY ignore EXTENSION TnlQos PRESENCE optional},
+ ...
+}
+
+DCH-ModifySpecificInformation-TDD ::= SEQUENCE (SIZE (1..maxNrOfDCHs)) OF DCH-ModifySpecificItem-TDD
+
+DCH-ModifySpecificItem-TDD ::= SEQUENCE {
+ dCH-ID DCH-ID,
+ ul-CCTrCH-ID CCTrCH-ID OPTIONAL,
+ dl-CCTrCH-ID CCTrCH-ID OPTIONAL,
+ ul-TransportFormatSet TransportFormatSet OPTIONAL,
+ dl-TransportFormatSet TransportFormatSet OPTIONAL,
+ allocationRetentionPriority AllocationRetentionPriority OPTIONAL,
+ frameHandlingPriority FrameHandlingPriority OPTIONAL,
+ iE-Extensions ProtocolExtensionContainer { { DCH-ModifySpecificItem-TDD-ExtIEs} } OPTIONAL,
+ ...
+}
+
+DCH-ModifySpecificItem-TDD-ExtIEs NBAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+DedicatedChannelsCapacityConsumptionLaw ::= SEQUENCE ( SIZE(1..maxNrOfSF) ) OF
+ SEQUENCE {
+ dl-Cost-1 INTEGER (0..65535),
+ dl-Cost-2 INTEGER (0..65535),
+ ul-Cost-1 INTEGER (0..65535),
+ ul-Cost-2 INTEGER (0..65535),
+ iE-Extensions ProtocolExtensionContainer { { DedicatedChannelsCapacityConsumptionLaw-ExtIEs } } OPTIONAL,
+ ...
+}
+
+DedicatedChannelsCapacityConsumptionLaw-ExtIEs NBAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+DedicatedMeasurementType ::= ENUMERATED {
+ sir,
+ sir-error,
+ transmitted-code-power,
+ rscp,
+ rx-timing-deviation,
+ round-trip-time,
+ ...,
+ rx-timing-deviation-LCR,
+ angle-Of-Arrival-LCR,
+ hs-sich-quality,
+ best-Cell-Portions
+
+}
+
+DedicatedMeasurementValue ::= CHOICE {
+ sIR-Value SIR-Value,
+ sIR-ErrorValue SIR-Error-Value,
+ transmittedCodePowerValue Transmitted-Code-Power-Value,
+ rSCP RSCP-Value,
+ rxTimingDeviationValue Rx-Timing-Deviation-Value,
+ roundTripTime Round-Trip-Time-Value,
+ ...,
+ extension-DedicatedMeasurementValue Extension-DedicatedMeasurementValue
+}
+
+Extension-DedicatedMeasurementValue ::= ProtocolIE-Single-Container {{ Extension-DedicatedMeasurementValueIE }}
+
+Extension-DedicatedMeasurementValueIE NBAP-PROTOCOL-IES ::= {
+ { ID id-Rx-Timing-Deviation-Value-LCR CRITICALITY reject TYPE Rx-Timing-Deviation-Value-LCR PRESENCE mandatory }|
+ { ID id-Angle-Of-Arrival-Value-LCR CRITICALITY reject TYPE Angle-Of-Arrival-Value-LCR PRESENCE mandatory }|
+ { ID id-HS-SICH-Reception-Quality CRITICALITY reject TYPE HS-SICH-Reception-Quality-Value PRESENCE mandatory }|
+ { ID id-Best-Cell-Portions-Value CRITICALITY reject TYPE Best-Cell-Portions-Value PRESENCE mandatory },
+ ...
+}
+
+DedicatedMeasurementValueInformation ::= CHOICE {
+ measurementAvailable DedicatedMeasurementAvailable,
+ measurementnotAvailable DedicatedMeasurementnotAvailable
+}
+
+DedicatedMeasurementAvailable::= SEQUENCE {
+ dedicatedmeasurementValue DedicatedMeasurementValue,
+ cFN CFN OPTIONAL,
+ ie-Extensions ProtocolExtensionContainer { { DedicatedMeasurementAvailableItem-ExtIEs} } OPTIONAL,
+ ...
+}
+
+DedicatedMeasurementAvailableItem-ExtIEs NBAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+DedicatedMeasurementnotAvailable ::= NULL
+
+DelayedActivation ::= CHOICE {
+ cfn CFN,
+ separate-indication NULL
+}
+
+DelayedActivationUpdate ::= CHOICE {
+ activate Activate-Info,
+ deactivate Deactivate-Info
+}
+
+Activate-Info ::= SEQUENCE {
+ activation-type Execution-Type,
+ initial-dl-tx-power DL-Power,
+ firstRLS-Indicator FirstRLS-Indicator OPTIONAL, --FDD Only
+ propagation-delay PropagationDelay OPTIONAL, --FDD Only
+ iE-Extensions ProtocolExtensionContainer { { Activate-Info-ExtIEs} } OPTIONAL,
+ ...
+}
+
+Activate-Info-ExtIEs NBAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+Deactivate-Info ::= SEQUENCE {
+ deactivation-type Execution-Type,
+ iE-Extensions ProtocolExtensionContainer { { Deactivate-Info-ExtIEs} } OPTIONAL,
+ ...
+}
+
+Deactivate-Info-ExtIEs NBAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+Execution-Type ::= CHOICE {
+ synchronised CFN,
+ unsynchronised NULL
+}
+
+Detected-PCPCH-access-preambles ::= INTEGER (0..240,...)
+-- According to mapping in [22].
+
+DeltaSIR ::= INTEGER (0..30)
+-- Unit dB, Step 0.1 dB, Range 0..3 dB.
+
+DGPSCorrections ::= SEQUENCE {
+ gpstow GPSTOW,
+ status-health GPS-Status-Health,
+ satelliteinfo SAT-Info-DGPSCorrections,
+ ie-Extensions ProtocolExtensionContainer { { DGPSCorrections-ExtIEs} } OPTIONAL,
+ ...
+}
+
+DGPSCorrections-ExtIEs NBAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+DGPSThresholds ::= SEQUENCE {
+ prcdeviation PRCDeviation,
+ ie-Extensions ProtocolExtensionContainer { { DGPSThresholds-ExtIEs} } OPTIONAL,
+ ...
+}
+
+DGPSThresholds-ExtIEs NBAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+DiscardTimer ::= ENUMERATED {v20,v40,v60,v80,v100,v120,v140,v160,v180,v200,v250,v300,v400,v500,v750,v1000,v1250,v1500,v1750,v2000,v2500,v3000,v3500,v4000,v4500,v5000,v7500,
+ ...
+}
+
+DiversityControlField ::= ENUMERATED {
+ may,
+ must,
+ must-not,
+ ...
+}
+
+DiversityMode ::= ENUMERATED {
+ none,
+ sTTD,
+ closed-loop-mode1,
+ closed-loop-mode2,
+ ...
+}
+
+DL-DPCH-SlotFormat ::= INTEGER (0..16,...)
+
+DL-DPCH-TimingAdjustment ::= ENUMERATED {
+ timing-advance,
+ timing-delay
+}
+
+DL-Timeslot-Information ::= SEQUENCE (SIZE (1.. maxNrOfDLTSs)) OF DL-Timeslot-InformationItem
+
+DL-Timeslot-InformationItem ::= SEQUENCE {
+ timeSlot TimeSlot,
+ midambleShiftAndBurstType MidambleShiftAndBurstType,
+ tFCI-Presence TFCI-Presence,
+ dL-Code-Information TDD-DL-Code-Information,
+ iE-Extensions ProtocolExtensionContainer { { DL-Timeslot-InformationItem-ExtIEs} } OPTIONAL,
+ ...
+}
+
+DL-Timeslot-InformationItem-ExtIEs NBAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+DL-TimeslotLCR-Information ::= SEQUENCE (SIZE (1.. maxNrOfDLTSLCRs)) OF DL-TimeslotLCR-InformationItem
+
+DL-TimeslotLCR-InformationItem ::= SEQUENCE {
+ timeSlotLCR TimeSlotLCR,
+ midambleShiftLCR MidambleShiftLCR,
+ tFCI-Presence TFCI-Presence,
+ dL-Code-LCR-Information TDD-DL-Code-LCR-Information,
+ iE-Extensions ProtocolExtensionContainer { { DL-TimeslotLCR-InformationItem-ExtIEs} } OPTIONAL,
+ ...
+}
+
+DL-TimeslotLCR-InformationItem-ExtIEs NBAP-PROTOCOL-EXTENSION ::= {
+ { ID id-Initial-DL-Power-TimeslotLCR-InformationItem CRITICALITY ignore EXTENSION DL-Power PRESENCE optional }|
+ -- Applicable to 1.28Mcps TDD only
+ { ID id-Maximum-DL-Power-TimeslotLCR-InformationItem CRITICALITY ignore EXTENSION DL-Power PRESENCE optional }|
+ -- Applicable to 1.28Mcps TDD only
+ { ID id-Minimum-DL-Power-TimeslotLCR-InformationItem CRITICALITY ignore EXTENSION DL-Power PRESENCE optional },
+ -- Applicable to 1.28Mcps TDD only
+ ...
+}
+
+DL-FrameType ::= ENUMERATED {
+ typeA,
+ typeB,
+ ...
+}
+
+DL-or-Global-CapacityCredit ::= INTEGER (0..65535)
+
+DL-Power ::= INTEGER (-350..150)
+-- Value = DL-Power/10
+-- Unit dB, Range -35dB .. +15dB, Step +0.1dB
+
+DLPowerAveragingWindowSize ::= INTEGER (1..60)
+
+DL-PowerBalancing-Information ::= SEQUENCE {
+ powerAdjustmentType PowerAdjustmentType,
+ dLReferencePower DL-Power OPTIONAL,
+ -- This IE shall be present if Power Adjustment Type IE equals to 'Common'
+ dLReferencePowerList-DL-PC-Rqst DL-ReferencePowerInformationList OPTIONAL,
+ -- This IE shall be present if Power Adjustment Type IE equals to 'Individual'
+ maxAdjustmentStep MaxAdjustmentStep OPTIONAL,
+ -- This IE shall be present if Power Adjustment Type IE equals to 'Common' or 'Individual'
+ adjustmentPeriod AdjustmentPeriod OPTIONAL,
+ -- This IE shall be present if Power Adjustment Type IE equals to 'Common' or 'Individual'
+ adjustmentRatio ScaledAdjustmentRatio OPTIONAL,
+ -- This IE shall be present if Power Adjustment Type IE equals to 'Common' or 'Individual'
+ iE-Extensions ProtocolExtensionContainer { { DL-PowerBalancing-Information-ExtIEs } } OPTIONAL,
+ ...
+}
+
+DL-PowerBalancing-Information-ExtIEs NBAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+DL-ReferencePowerInformationList ::= SEQUENCE (SIZE (1..maxNrOfRLs)) OF DL-ReferencePowerInformationItem
+
+DL-ReferencePowerInformationItem ::= SEQUENCE {
+ rL-ID RL-ID,
+ dl-Reference-Power DL-Power,
+ iE-Extensions ProtocolExtensionContainer { {DL-ReferencePowerInformationItem-ExtIEs} } OPTIONAL,
+ ...
+}
+
+DL-ReferencePowerInformationItem-ExtIEs NBAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+DL-PowerBalancing-ActivationIndicator ::= ENUMERATED {
+ dL-PowerBalancing-Activated
+}
+
+DL-PowerBalancing-UpdatedIndicator ::= ENUMERATED {
+ dL-PowerBalancing-Updated
+}
+
+DL-ScramblingCode ::= INTEGER (0..15)
+-- 0= Primary scrambling code of the cell, 1..15= Secondary scrambling code --
+
+DL-TimeslotISCP ::= INTEGER (0..91)
+
+DL-TimeslotISCPInfo ::= SEQUENCE (SIZE (1..maxNrOfDLTSs)) OF DL-TimeslotISCPInfoItem
+
+DL-TimeslotISCPInfoItem ::= SEQUENCE {
+ timeSlot TimeSlot,
+ dL-TimeslotISCP DL-TimeslotISCP,
+ iE-Extensions ProtocolExtensionContainer { {DL-TimeslotISCPInfoItem-ExtIEs} } OPTIONAL,
+ ...
+ }
+
+DL-TimeslotISCPInfoItem-ExtIEs NBAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+DL-TimeslotISCPInfoLCR ::= SEQUENCE (SIZE (1..maxNrOfDLTSLCRs)) OF DL-TimeslotISCPInfoItemLCR
+
+DL-TimeslotISCPInfoItemLCR ::= SEQUENCE {
+ timeSlotLCR TimeSlotLCR,
+ dL-TimeslotISCP DL-TimeslotISCP,
+ iE-Extensions ProtocolExtensionContainer { {DL-TimeslotISCPInfoItemLCR-ExtIEs} } OPTIONAL,
+ ...
+ }
+
+DL-TimeslotISCPInfoItemLCR-ExtIEs NBAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+DL-TPC-Pattern01Count ::= INTEGER (0..30,...)
+
+Downlink-Compressed-Mode-Method ::= ENUMERATED {
+ puncturing,
+ sFdiv2,
+ higher-layer-scheduling,
+ ...
+}
+
+DPC-Mode ::= ENUMERATED {
+ mode0,
+ mode1,
+ ...
+}
+
+DPCH-ID ::= INTEGER (0..239)
+
+DSCH-ID ::= INTEGER (0..255)
+
+DSCH-InformationResponse ::= SEQUENCE (SIZE (1..maxNrOfDSCHs)) OF DSCH-InformationResponseItem
+
+DSCH-InformationResponseItem ::= SEQUENCE {
+ dSCH-ID DSCH-ID,
+ bindingID BindingID OPTIONAL,
+ transportLayerAddress TransportLayerAddress OPTIONAL,
+ iE-Extensions ProtocolExtensionContainer { { DSCH-InformationResponseItem-ExtIEs } } OPTIONAL,
+ ...
+}
+
+DSCH-InformationResponseItem-ExtIEs NBAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+DSCH-FDD-Common-Information ::= SEQUENCE {
+ enhancedDSCHPCIndicator EnhancedDSCHPCIndicator OPTIONAL,
+ enhancedDSCHPC EnhancedDSCHPC OPTIONAL,
+ -- The IE shall be present if the Enhanced DSCH PC Indicator IE is set to "Enhanced DSCH PC Active in the UE".
+ iE-Extensions ProtocolExtensionContainer { { DSCH-FDD-Common-Information-ExtIEs} } OPTIONAL,
+ ...
+}
+
+DSCH-FDD-Common-Information-ExtIEs NBAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+DSCH-FDD-Information ::= SEQUENCE (SIZE (1..maxNrOfDSCHs)) OF DSCH-FDD-InformationItem
+
+DSCH-FDD-InformationItem ::= SEQUENCE {
+ dSCH-ID DSCH-ID,
+ transportFormatSet TransportFormatSet,
+ allocationRetentionPriority AllocationRetentionPriority,
+ frameHandlingPriority FrameHandlingPriority,
+ toAWS ToAWS,
+ toAWE ToAWE,
+ iE-Extensions ProtocolExtensionContainer { { DSCH-FDD-InformationItem-ExtIEs} } OPTIONAL,
+ ...
+}
+
+DSCH-FDD-InformationItem-ExtIEs NBAP-PROTOCOL-EXTENSION ::= {
+ { ID id-bindingID CRITICALITY ignore EXTENSION BindingID PRESENCE optional }|
+ { ID id-transportlayeraddress CRITICALITY ignore EXTENSION TransportLayerAddress PRESENCE optional },
+ ...
+}
+
+DSCH-TDD-Information ::= SEQUENCE (SIZE (1..maxNrOfDSCHs)) OF DSCH-TDD-InformationItem
+
+DSCH-TDD-InformationItem ::= SEQUENCE {
+ dSCH-ID DSCH-ID,
+ cCTrCH-ID CCTrCH-ID,
+ transportFormatSet TransportFormatSet,
+ allocationRetentionPriority AllocationRetentionPriority,
+ frameHandlingPriority FrameHandlingPriority,
+ toAWS ToAWS,
+ toAWE ToAWE,
+ iE-Extensions ProtocolExtensionContainer { { DSCH-TDD-InformationItem-ExtIEs} } OPTIONAL,
+ ...
+}
+
+DSCH-TDD-InformationItem-ExtIEs NBAP-PROTOCOL-EXTENSION ::= {
+ { ID id-bindingID CRITICALITY ignore EXTENSION BindingID PRESENCE optional }|
+ -- Shall be ignored if bearer establishment with ALCAP.
+ { ID id-transportlayeraddress CRITICALITY ignore EXTENSION TransportLayerAddress PRESENCE optional },
+ -- Shall be ignored if bearer establishment with ALCAP.
+ ...
+}
+
+DsField ::= BIT STRING (SIZE (8))
+
+DwPCH-Power ::= INTEGER (-150..400,...)
+-- DwPCH-power = power * 10
+-- If power <= -15 DwPCH shall be set to -150
+-- If power >= 40 DwPCH shall be set to 400
+-- Unit dBm, Range -15dBm .. +40 dBm, Step +0.1dB
+
+
+-- ==========================================
+-- E
+-- ==========================================
+
+End-Of-Audit-Sequence-Indicator ::= ENUMERATED {
+ end-of-audit-sequence,
+ not-end-of-audit-sequence
+}
+
+EnhancedDSCHPC ::= SEQUENCE {
+ enhancedDSCHPCWnd EnhancedDSCHPCWnd,
+ enhancedDSCHPCCounter EnhancedDSCHPCCounter,
+ enhancedDSCHPowerOffset EnhancedDSCHPowerOffset,
+ ...
+}
+
+EnhancedDSCHPCCounter ::= INTEGER (1..50)
+
+EnhancedDSCHPCIndicator ::= ENUMERATED {
+ enhancedDSCHPCActiveInTheUE,
+ enhancedDSCHPCNotActiveInTheUE
+}
+
+EnhancedDSCHPCWnd ::= INTEGER (1..10)
+
+EnhancedDSCHPowerOffset ::= INTEGER (-15..0)
+
+-- ==========================================
+-- F
+-- ==========================================
+
+FDD-DL-ChannelisationCodeNumber ::= INTEGER(0.. 511)
+-- According to the mapping in [9]. The maximum value is equal to the DL spreading factor -1--
+
+FDD-DL-CodeInformation ::= SEQUENCE (SIZE (1..maxNrOfCodes)) OF FDD-DL-CodeInformationItem
+
+FDD-DL-CodeInformationItem ::= SEQUENCE {
+ dl-ScramblingCode DL-ScramblingCode,
+ fdd-DL-ChannelisationCodeNumber FDD-DL-ChannelisationCodeNumber,
+ transmissionGapPatternSequenceCodeInformation TransmissionGapPatternSequenceCodeInformation OPTIONAL,
+ iE-Extensions ProtocolExtensionContainer { { FDD-DL-CodeInformationItem-ExtIEs} } OPTIONAL,
+ ...
+}
+
+FDD-DL-CodeInformationItem-ExtIEs NBAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+FDD-S-CCPCH-Offset ::= INTEGER (0..149)
+-- 0: 0 chip, 1: 256 chip, 2: 512 chip, .. ,149: 38144 chip [7] --
+
+FDD-TPC-DownlinkStepSize ::= ENUMERATED {
+ step-size0-5,
+ step-size1,
+ step-size1-5,
+ step-size2,
+ ...
+}
+
+FirstRLS-Indicator ::= ENUMERATED {
+ first-RLS,
+ not-first-RLS,
+ ...
+}
+
+FNReportingIndicator ::= ENUMERATED {
+ fN-reporting-required,
+ fN-reporting-not-required
+}
+
+FrameHandlingPriority ::= INTEGER (0..15)
+-- 0=lowest priority, 15=highest priority --
+
+FrameAdjustmentValue ::= INTEGER(0..4095)
+
+FrameOffset ::= INTEGER (0..255)
+
+FPACH-Power ::= INTEGER (-150..400,...) -- FPACH-power = power * 10
+-- If power <= -15 FPACH shall be set to -150
+-- If power >= 40 FPACH shall be set to 400
+-- Unit dBm, Range -15dBm .. +40 dBm, Step +0.1dB
+
+-- ==========================================
+-- G
+-- ==========================================
+
+GapLength ::= INTEGER (1..14)
+-- Unit slot
+
+GapDuration ::= INTEGER (1..144,...)
+-- Unit frame
+
+GenericTrafficCategory ::= BIT STRING (SIZE (8))
+
+GPS-Almanac ::= SEQUENCE {
+ wna-alm BIT STRING (SIZE (8)),
+ sat-info-almanac SAT-Info-Almanac,
+ sVGlobalHealth-alm BIT STRING (SIZE (364)) OPTIONAL,
+ ie-Extensions ProtocolExtensionContainer { { GPS-Almanac-ExtIEs} } OPTIONAL,
+ ...
+}
+
+GPS-Almanac-ExtIEs NBAP-PROTOCOL-EXTENSION ::= {
+ { ID id-SAT-Info-Almanac-ExtItem CRITICALITY ignore EXTENSION SAT-Info-Almanac-ExtList PRESENCE optional},
+ ...
+}
+
+GPS-Ionospheric-Model ::= SEQUENCE {
+ alpha-zero-ionos BIT STRING (SIZE (8)),
+ alpha-one-ionos BIT STRING (SIZE (8)),
+ alpha-two-ionos BIT STRING (SIZE (8)),
+ alpha-three-ionos BIT STRING (SIZE (8)),
+ beta-zero-ionos BIT STRING (SIZE (8)),
+ beta-one-ionos BIT STRING (SIZE (8)),
+ beta-two-ionos BIT STRING (SIZE (8)),
+ beta-three-ionos BIT STRING (SIZE (8)),
+ ie-Extensions ProtocolExtensionContainer { { GPS-Ionospheric-Model-ExtIEs} } OPTIONAL,
+ ...
+}
+
+GPS-Ionospheric-Model-ExtIEs NBAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+GPS-Information ::= SEQUENCE (SIZE (0..maxNoGPSItems)) OF GPS-Information-Item
+-- This IE shall be present if the Information Type Item IE indicates 'GPS Information'
+
+GPS-Information-Item ::= ENUMERATED {
+ gps-navigation-model-and-time-recovery,
+ gps-ionospheric-model,
+ gps-utc-model,
+ gps-almanac,
+ gps-rt-integrity,
+ ...
+}
+
+GPS-RealTime-Integrity ::= CHOICE {
+ bad-satellites GPSBadSat-Info-RealTime-Integrity,
+ no-bad-satellites NULL
+}
+
+GPSBadSat-Info-RealTime-Integrity ::= SEQUENCE {
+ sat-info SATInfo-RealTime-Integrity,
+ ie-Extensions ProtocolExtensionContainer { { GPSBadSat-Info-RealTime-Integrity-ExtIEs} } OPTIONAL,
+ ...
+}
+
+GPSBadSat-Info-RealTime-Integrity-ExtIEs NBAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+GPS-NavigationModel-and-TimeRecovery ::= SEQUENCE (SIZE (1..maxNoSat)) OF GPS-NavandRecovery-Item
+
+GPS-NavandRecovery-Item ::= SEQUENCE {
+ tx-tow-nav INTEGER (0..1048575),
+ sat-id-nav SAT-ID,
+ tlm-message-nav BIT STRING (SIZE (14)),
+ tlm-revd-c-nav BIT STRING (SIZE (2)),
+ ho-word-nav BIT STRING (SIZE (22)),
+ w-n-nav BIT STRING (SIZE (10)),
+ ca-or-p-on-l2-nav BIT STRING (SIZE (2)),
+ user-range-accuracy-index-nav BIT STRING (SIZE (4)),
+ sv-health-nav BIT STRING (SIZE (6)),
+ iodc-nav BIT STRING (SIZE (10)),
+ l2-p-dataflag-nav BIT STRING (SIZE (1)),
+ sf1-reserved-nav BIT STRING (SIZE (87)),
+ t-gd-nav BIT STRING (SIZE (8)),
+ t-oc-nav BIT STRING (SIZE (16)),
+ a-f-2-nav BIT STRING (SIZE (8)),
+ a-f-1-nav BIT STRING (SIZE (16)),
+ a-f-zero-nav BIT STRING (SIZE (22)),
+ c-rs-nav BIT STRING (SIZE (16)),
+ delta-n-nav BIT STRING (SIZE (16)),
+ m-zero-nav BIT STRING (SIZE (32)),
+ c-uc-nav BIT STRING (SIZE (16)),
+ gps-e-nav BIT STRING (SIZE (32)),
+ c-us-nav BIT STRING (SIZE (16)),
+ a-sqrt-nav BIT STRING (SIZE (32)),
+ t-oe-nav BIT STRING (SIZE (16)),
+ fit-interval-flag-nav BIT STRING (SIZE (1)),
+ aodo-nav BIT STRING (SIZE (5)),
+ c-ic-nav BIT STRING (SIZE (16)),
+ omega-zero-nav BIT STRING (SIZE (32)),
+ c-is-nav BIT STRING (SIZE (16)),
+ i-zero-nav BIT STRING (SIZE (32)),
+ c-rc-nav BIT STRING (SIZE (16)),
+ gps-omega-nav BIT STRING (SIZE (32)),
+ omegadot-nav BIT STRING (SIZE (24)),
+ idot-nav BIT STRING (SIZE (14)),
+ spare-zero-fill BIT STRING (SIZE (20)),
+ ie-Extensions ProtocolExtensionContainer { { GPS-NavandRecovery-Item-ExtIEs} } OPTIONAL,
+ ...
+}
+
+GPS-NavandRecovery-Item-ExtIEs NBAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+
+GPS-RX-POS ::= SEQUENCE {
+ latitudeSign ENUMERATED {north, south},
+ latitude INTEGER (0..8388607),
+ longitude INTEGER (-8388608..8388607),
+ directionOfAltitude ENUMERATED {height, depth},
+ altitude INTEGER (0..32767),
+ iE-Extensions ProtocolExtensionContainer { { GPS-RX-POS-ExtIEs} } OPTIONAL,
+ ...
+}
+
+GPS-RX-POS-ExtIEs NBAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+GPS-Status-Health ::= ENUMERATED {
+ udre-scale-1dot0,
+ udre-scale-0dot75,
+ udre-scale-0dot5,
+ udre-scale-0dot3,
+ udre-scale-0dot1,
+ no-data,
+ invalid-data
+}
+
+GPSTOW ::= INTEGER (0..604799)
+
+GPS-UTC-Model ::= SEQUENCE {
+ a-one-utc BIT STRING (SIZE (24)),
+ a-zero-utc BIT STRING (SIZE (32)),
+ t-ot-utc BIT STRING (SIZE (8)),
+ delta-t-ls-utc BIT STRING (SIZE (8)),
+ w-n-t-utc BIT STRING (SIZE (8)),
+ w-n-lsf-utc BIT STRING (SIZE (8)),
+ dn-utc BIT STRING (SIZE (8)),
+ delta-t-lsf-utc BIT STRING (SIZE (8)),
+ ie-Extensions ProtocolExtensionContainer { { GPS-UTC-Model-ExtIEs} } OPTIONAL,
+ ...
+}
+
+GPS-UTC-Model-ExtIEs NBAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+-- ==========================================
+-- H
+-- ==========================================
+
+
+HARQ-MemoryPartitioning ::= CHOICE {
+ implicit HARQ-MemoryPartitioning-Implicit,
+ explicit HARQ-MemoryPartitioning-Explicit,
+ ...
+ }
+
+HARQ-MemoryPartitioning-Implicit ::= SEQUENCE {
+ number-of-Processes INTEGER (1..8,...),
+ iE-Extensions ProtocolExtensionContainer { { HARQ-MemoryPartitioning-Implicit-ExtIEs } } OPTIONAL,
+ ...
+}
+
+HARQ-MemoryPartitioning-Implicit-ExtIEs NBAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+HARQ-MemoryPartitioning-Explicit ::= SEQUENCE {
+ hARQ-MemoryPartitioningList HARQ-MemoryPartitioningList,
+ iE-Extensions ProtocolExtensionContainer { { HARQ-MemoryPartitioning-Explicit-ExtIEs } } OPTIONAL,
+ ...
+}
+
+HARQ-MemoryPartitioning-Explicit-ExtIEs NBAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+HARQ-MemoryPartitioningList ::= SEQUENCE (SIZE (1..maxNrOfHARQProcesses)) OF HARQ-MemoryPartitioningItem
+
+HARQ-MemoryPartitioningItem ::= SEQUENCE {
+ process-Memory-Size ENUMERATED {
+ hms800, hms1600, hms2400, hms3200, hms4000,
+ hms4800, hms5600, hms6400, hms7200, hms8000,
+ hms8800, hms9600, hms10400, hms11200, hms12000,
+ hms12800, hms13600, hms14400, hms15200, hms16000,
+ hms17600, hms19200, hms20800, hms22400, hms24000,
+ hms25600, hms27200, hms28800, hms30400, hms32000,
+ hms36000, hms40000, hms44000, hms48000, hms52000,
+ hms56000, hms60000, hms64000, hms68000, hms72000,
+ hms76000, hms80000, hms88000, hms96000, hms104000,
+ hms112000, hms120000, hms128000, hms136000, hms144000,
+ hms152000, hms160000, hms176000, hms192000, hms208000,
+ hms224000, hms240000, hms256000, hms272000, hms288000,
+ hms304000,...},
+ iE-Extensions ProtocolExtensionContainer { { HARQ-MemoryPartitioningItem-ExtIEs } } OPTIONAL,
+ ...
+}
+
+HARQ-MemoryPartitioningItem-ExtIEs NBAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+HSDPA-Capability ::= ENUMERATED {hsdpa-capable, hsdpa-non-capable}
+
+HS-DSCHProvidedBitRate ::= SEQUENCE (SIZE (1..maxNrOfPriorityClasses)) OF HS-DSCHProvidedBitRate-Item
+
+HS-DSCHProvidedBitRate-Item ::= SEQUENCE {
+ schedulingPriorityIndicator SchedulingPriorityIndicator,
+ hS-DSCHProvidedBitRateValue HS-DSCHProvidedBitRateValue,
+ iE-Extensions ProtocolExtensionContainer { { HS-DSCHProvidedBitRate-Item-ExtIEs} } OPTIONAL,
+ ...
+}
+
+HS-DSCHProvidedBitRate-Item-ExtIEs NBAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+HS-DSCHProvidedBitRateValue ::= INTEGER(0..16777215,...)
+-- Unit bit/s, Range 0..2^24-1, Step 1 bit
+
+
+HS-DSCHRequiredPower ::= SEQUENCE (SIZE (1..maxNrOfPriorityClasses)) OF HS-DSCHRequiredPower-Item
+
+HS-DSCHRequiredPower-Item ::= SEQUENCE {
+ schedulingPriorityIndicator SchedulingPriorityIndicator,
+ hS-DSCHRequiredPowerValue HS-DSCHRequiredPowerValue,
+ hS-DSCHRequiredPowerPerUEInformation HS-DSCHRequiredPowerPerUEInformation OPTIONAL,
+ iE-Extensions ProtocolExtensionContainer { { HS-DSCHRequiredPower-Item-ExtIEs} } OPTIONAL,
+ ...
+}
+
+HS-DSCHRequiredPower-Item-ExtIEs NBAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+HS-DSCHRequiredPowerValue ::= INTEGER(0..1000)
+-- Unit %, Range 0 ..1000, Step 0.1%
+
+HS-DSCHRequiredPowerPerUEInformation ::= SEQUENCE (SIZE (1.. maxNrOfContextsOnUeList)) OF HS-DSCHRequiredPowerPerUEInformation-Item
+
+
+HS-DSCHRequiredPowerPerUEInformation-Item ::= SEQUENCE {
+ cRNC-CommunicationContextID CRNC-CommunicationContextID,
+ hS-DSCHRequiredPowerPerUEWeight HS-DSCHRequiredPowerPerUEWeight OPTIONAL,
+ iE-Extensions ProtocolExtensionContainer { { HS-DSCHRequiredPowerPerUEInformation-Item-ExtIEs} } OPTIONAL,
+ ...
+}
+
+HS-DSCHRequiredPowerPerUEInformation-Item-ExtIEs NBAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+HS-DSCHRequiredPowerPerUEWeight ::= INTEGER(0..100)
+-- Unit %, Range 0 ..100, Step 1%
+
+
+HSDSCH-FDD-Information ::= SEQUENCE {
+ hSDSCH-MACdFlows-Information HSDSCH-MACdFlows-Information,
+ ueCapability-Info UE-Capability-Information,
+ mAChs-Reordering-Buffer-Size-for-RLC-UM MAChsReorderingBufferSize-for-RLC-UM,
+ cqiFeedback-CycleK CQI-Feedback-Cycle,
+ cqiRepetitionFactor CQI-RepetitionFactor OPTIONAL,
+ -- This IE shall be present if the CQI Feedback Cycle k is greater than 0
+ ackNackRepetitionFactor AckNack-RepetitionFactor,
+ cqiPowerOffset CQI-Power-Offset,
+ ackPowerOffset Ack-Power-Offset,
+ nackPowerOffset Nack-Power-Offset,
+ hsscch-PowerOffset HSSCCH-PowerOffset OPTIONAL,
+ measurement-Power-Offset Measurement-Power-Offset OPTIONAL,
+ iE-Extensions ProtocolExtensionContainer { { HSDSCH-FDD-Information-ExtIEs} } OPTIONAL,
+ ...
+}
+
+HSDSCH-FDD-Information-ExtIEs NBAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+HSDSCH-TDD-Information ::= SEQUENCE {
+ hSDSCH-MACdFlows-Information HSDSCH-MACdFlows-Information,
+ ueCapability-Info UE-Capability-Information,
+ mAChs-Reordering-Buffer-Size-for-RLC-UM MAChsReorderingBufferSize-for-RLC-UM,
+ tDD-AckNack-Power-Offset TDD-AckNack-Power-Offset,
+ iE-Extensions ProtocolExtensionContainer { { HSDSCH-TDD-Information-ExtIEs} } OPTIONAL,
+ ...
+}
+
+HSDSCH-TDD-Information-ExtIEs NBAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+
+HSDSCH-Information-to-Modify ::= SEQUENCE {
+ hsDSCH-MACdFlow-Specific-Info-to-Modify HSDSCH-MACdFlow-Specific-InfoList-to-Modify OPTIONAL,
+ priorityQueueInfotoModify PriorityQueue-InfoList-to-Modify OPTIONAL,
+ mAChs-Reordering-Buffer-Size-for-RLC-UM MAChsReorderingBufferSize-for-RLC-UM OPTIONAL,
+ cqiFeedback-CycleK CQI-Feedback-Cycle OPTIONAL, -- For FDD only
+ cqiRepetitionFactor CQI-RepetitionFactor OPTIONAL, -- For FDD only
+ ackNackRepetitionFactor AckNack-RepetitionFactor OPTIONAL, -- For FDD only
+ cqiPowerOffset CQI-Power-Offset OPTIONAL, -- For FDD only
+ ackPowerOffset Ack-Power-Offset OPTIONAL, -- For FDD only
+ nackPowerOffset Nack-Power-Offset OPTIONAL, -- For FDD only
+ hsscch-PowerOffset HSSCCH-PowerOffset OPTIONAL, -- For FDD only
+ measurement-Power-Offset Measurement-Power-Offset OPTIONAL, -- For FDD only
+ hSSCCHCodeChangeGrant HSSCCH-Code-Change-Grant OPTIONAL,
+ tDDAckNackPowerOffset TDD-AckNack-Power-Offset OPTIONAL, -- For TDD only
+ iE-Extensions ProtocolExtensionContainer { { HSDSCH-Information-to-Modify-ExtIEs} } OPTIONAL,
+ ...
+}
+
+HSDSCH-Information-to-Modify-ExtIEs NBAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+HSDSCH-MACdFlow-Specific-InfoList-to-Modify ::= SEQUENCE (SIZE (1..maxNrOfMACdFlows)) OF HSDSCH-MACdFlow-Specific-InfoItem-to-Modify
+
+HSDSCH-MACdFlow-Specific-InfoItem-to-Modify ::= SEQUENCE {
+ hsDSCH-MACdFlow-ID HSDSCH-MACdFlow-ID,
+ allocationRetentionPriority AllocationRetentionPriority OPTIONAL,
+ transportBearerRequestIndicator TransportBearerRequestIndicator,
+ bindingID BindingID OPTIONAL,
+ transportLayerAddress TransportLayerAddress OPTIONAL,
+ iE-Extensions ProtocolExtensionContainer { { HSDSCH-MACdFlow-Specific-InfoItem-to-Modify-ExtIEs} } OPTIONAL,
+ ...
+}
+
+HSDSCH-MACdFlow-Specific-InfoItem-to-Modify-ExtIEs NBAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+HSDSCH-Information-to-Modify-Unsynchronised ::= SEQUENCE {
+ hsDSCH-MACdFlow-Specific-Info-to-Modify HSDSCH-MACdFlow-Specific-InfoList-to-Modify OPTIONAL,
+ priorityQueueInfotoModifyUnsynchronised PriorityQueue-InfoList-to-Modify-Unsynchronised OPTIONAL,
+ cqiPowerOffset CQI-Power-Offset OPTIONAL, -- For FDD only
+ ackPowerOffset Ack-Power-Offset OPTIONAL, -- For FDD only
+ nackPowerOffset Nack-Power-Offset OPTIONAL, -- For FDD only
+ hsscch-PowerOffset HSSCCH-PowerOffset OPTIONAL, -- For FDD only
+ tDDAckNackPowerOffset TDD-AckNack-Power-Offset OPTIONAL, -- For TDD only
+ iE-Extensions ProtocolExtensionContainer { { HSDSCH-Information-to-Modify-Unsynchronised-ExtIEs} } OPTIONAL,
+ ...
+}
+
+HSDSCH-Information-to-Modify-Unsynchronised-ExtIEs NBAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+HSDSCH-FDD-Information-Response ::= SEQUENCE {
+ hsDSCH-MACdFlow-Specific-InformationResp HSDSCH-MACdFlow-Specific-InformationResp OPTIONAL,
+ hsSCCH-Specific-Information-ResponseFDD HSSCCH-Specific-InformationRespListFDD OPTIONAL,
+ hARQ-MemoryPartitioning HARQ-MemoryPartitioning OPTIONAL,
+ iE-Extensions ProtocolExtensionContainer { { HSDSCH-FDD-Information-Response-ExtIEs } } OPTIONAL,
+ ...
+}
+
+HSDSCH-FDD-Information-Response-ExtIEs NBAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+HSDSCH-TDD-Information-Response ::= SEQUENCE {
+ hsDSCH-MACdFlow-Specific-InformationResp HSDSCH-MACdFlow-Specific-InformationResp OPTIONAL,
+ hsSCCH-Specific-Information-ResponseTDD HSSCCH-Specific-InformationRespListTDD OPTIONAL, -- Not Applicable to 1.28Mcps TDD
+ hsSCCH-Specific-Information-ResponseTDDLCR HSSCCH-Specific-InformationRespListTDDLCR OPTIONAL, -- Not Applicable to 3.84Mcps TDD
+ hARQ-MemoryPartitioning HARQ-MemoryPartitioning OPTIONAL,
+ iE-Extensions ProtocolExtensionContainer { { HSDSCH-TDD-Information-Response-ExtIEs } } OPTIONAL,
+ ...
+}
+
+HSDSCH-TDD-Information-Response-ExtIEs NBAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+HSDSCH-MACdFlow-Specific-InformationResp ::= SEQUENCE (SIZE (1..maxNrOfMACdFlows)) OF HSDSCH-MACdFlow-Specific-InformationResp-Item
+
+HSDSCH-MACdFlow-Specific-InformationResp-Item ::= SEQUENCE {
+ hsDSCHMacdFlow-Id HSDSCH-MACdFlow-ID,
+ bindingID BindingID OPTIONAL,
+ transportLayerAddress TransportLayerAddress OPTIONAL,
+ hSDSCH-Initial-Capacity-Allocation HSDSCH-Initial-Capacity-Allocation OPTIONAL,
+ iE-Extensions ProtocolExtensionContainer { { HSDSCH-MACdFlow-Specific-InformationRespItem-ExtIEs } } OPTIONAL,
+ ...
+}
+
+HSDSCH-MACdFlow-Specific-InformationRespItem-ExtIEs NBAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+HSDSCH-MACdFlows-Information ::= SEQUENCE {
+ hSDSCH-MACdFlow-Specific-Info HSDSCH-MACdFlow-Specific-InfoList,
+ priorityQueue-Info PriorityQueue-InfoList,
+ iE-Extensions ProtocolExtensionContainer { { HSDSCH-MACdFlows-Information-ExtIEs } } OPTIONAL,
+ ...
+}
+
+HSDSCH-MACdFlows-Information-ExtIEs NBAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+HSDSCH-MACdFlow-Specific-InfoList ::= SEQUENCE (SIZE (1..maxNrOfMACdFlows)) OF HSDSCH-MACdFlow-Specific-InfoItem
+
+HSDSCH-MACdFlow-Specific-InfoItem ::= SEQUENCE {
+ hsDSCH-MACdFlow-ID HSDSCH-MACdFlow-ID,
+ allocationRetentionPriority AllocationRetentionPriority,
+ bindingID BindingID OPTIONAL,
+ transportLayerAddress TransportLayerAddress OPTIONAL,
+ iE-Extensions ProtocolExtensionContainer { { HSDSCH-MACdFlow-Specific-InfoItem-ExtIEs} } OPTIONAL,
+ ...
+}
+
+HSDSCH-MACdFlow-Specific-InfoItem-ExtIEs NBAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+HSDSCH-MACdFlows-to-Delete ::= SEQUENCE (SIZE (1..maxNrOfMACdFlows)) OF HSDSCH-MACdFlows-to-Delete-Item
+
+HSDSCH-MACdFlows-to-Delete-Item ::= SEQUENCE {
+ hsDSCH-MACdFlow-ID HSDSCH-MACdFlow-ID,
+ iE-Extensions ProtocolExtensionContainer { { HSDSCH-MACdFlows-to-Delete-Item-ExtIEs} } OPTIONAL,
+ ...
+}
+
+HSDSCH-MACdFlows-to-Delete-Item-ExtIEs NBAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+HSSCCH-PowerOffset ::= INTEGER (0..255)
+-- PowerOffset = -32 + offset * 0.25
+-- Unit dB, Range -32dB .. +31.75dB, Step +0.25dB
+
+HSDSCH-Initial-Capacity-Allocation::= SEQUENCE (SIZE (1..maxNrOfPriorityQueues)) OF HSDSCH-Initial-Capacity-AllocationItem
+
+HSDSCH-Initial-Capacity-AllocationItem ::= SEQUENCE {
+ schedulingPriorityIndicator SchedulingPriorityIndicator,
+ maximum-MACdPDU-Size MACdPDU-Size,
+ hSDSCH-InitialWindowSize HSDSCH-InitialWindowSize,
+ iE-Extensions ProtocolExtensionContainer { { HSDSCH-Initial-Capacity-AllocationItem-ExtIEs } } OPTIONAL,
+ ...
+}
+
+HSDSCH-Initial-Capacity-AllocationItem-ExtIEs NBAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+HSDSCH-InitialWindowSize ::= INTEGER (1..255)
+-- Number of MAC-d PDUs.
+
+HSSCCH-Specific-InformationRespListFDD ::= SEQUENCE (SIZE (1..maxNrOfHSSCCHCodes)) OF HSSCCH-Codes
+
+HSSCCH-Codes ::= SEQUENCE {
+ codeNumber INTEGER (0..127),
+ iE-Extensions ProtocolExtensionContainer { { HSSCCH-Specific-InformationRespItemFDD-ExtIEs } } OPTIONAL,
+ ...
+}
+
+HSSCCH-Specific-InformationRespItemFDD-ExtIEs NBAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+HSSCCH-Specific-InformationRespListTDD ::= SEQUENCE (SIZE (1..maxNrOfHSSCCHCodes)) OF HSSCCH-Specific-InformationRespItemTDD
+
+HSSCCH-Specific-InformationRespItemTDD ::= SEQUENCE {
+ timeslot TimeSlot,
+ midambleShiftAndBurstType MidambleShiftAndBurstType,
+ tDD-ChannelisationCode TDD-ChannelisationCode,
+ hSSICH-Info HSSICH-Info,
+ iE-Extensions ProtocolExtensionContainer { { HSSCCH-Specific-InformationRespItemTDD-ExtIEs } } OPTIONAL,
+ ...
+}
+
+HSSCCH-Specific-InformationRespItemTDD-ExtIEs NBAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+HSSCCH-Specific-InformationRespListTDDLCR ::= SEQUENCE (SIZE (1..maxNrOfHSSCCHCodes)) OF HSSCCH-Specific-InformationRespItemTDDLCR
+
+HSSCCH-Specific-InformationRespItemTDDLCR ::= SEQUENCE {
+ timeslotLCR TimeSlotLCR,
+ midambleShiftLCR MidambleShiftLCR,
+ first-TDD-ChannelisationCode TDD-ChannelisationCode,
+ second-TDD-ChannelisationCode TDD-ChannelisationCode,
+ hSSICH-InfoLCR HSSICH-InfoLCR,
+ iE-Extensions ProtocolExtensionContainer { { HSSCCH-Specific-InformationRespItemTDDLCR-ExtIEs } } OPTIONAL,
+ ...
+}
+
+HSSCCH-Specific-InformationRespItemTDDLCR-ExtIEs NBAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+HSSICH-Info ::= SEQUENCE {
+ hsSICH-ID HS-SICH-ID,
+ timeslot TimeSlot,
+ midambleShiftAndBurstType MidambleShiftAndBurstType,
+ tDD-ChannelisationCode TDD-ChannelisationCode,
+ iE-Extensions ProtocolExtensionContainer { { HSSICH-Info-ExtIEs } } OPTIONAL,
+ ...
+}
+
+HSSICH-Info-ExtIEs NBAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+HSSICH-InfoLCR ::= SEQUENCE {
+ hsSICH-ID HS-SICH-ID,
+ timeslotLCR TimeSlotLCR,
+ midambleShiftLCR MidambleShiftLCR,
+ tDD-ChannelisationCode TDD-ChannelisationCode,
+ iE-Extensions ProtocolExtensionContainer { { HSSICH-Info-LCR-ExtIEs } } OPTIONAL,
+ ...
+}
+
+HSSICH-Info-LCR-ExtIEs NBAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+HS-SICH-Reception-Quality-Value ::= SEQUENCE {
+ failed-HS-SICH HS-SICH-failed,
+ missed-HS-SICH HS-SICH-missed,
+ total-HS-SICH HS-SICH-total,
+ iE-Extensions ProtocolExtensionContainer { { HS-SICH-Reception-Quality-Value-ExtIEs} } OPTIONAL,
+...
+}
+
+HS-SICH-Reception-Quality-Value-ExtIEs NBAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+HS-SICH-failed ::= INTEGER (0..20)
+
+HS-SICH-missed ::= INTEGER (0..20)
+
+HS-SICH-total ::= INTEGER (0..20)
+
+HS-SICH-Reception-Quality-Measurement-Value ::= INTEGER (0..20)
+-- According to mapping in [23]
+
+HSDSCH-MACdFlow-ID ::= INTEGER (0..maxNrOfMACdFlows-1)
+
+HSDSCH-RNTI ::= INTEGER (0..65535)
+
+HS-PDSCH-FDD-Code-Information ::= SEQUENCE {
+ number-of-HS-PDSCH-codes INTEGER (0..maxHS-PDSCHCodeNrComp-1),
+ hS-PDSCH-Start-code-number HS-PDSCH-Start-code-number OPTIONAL,
+-- Only included when number of HS-DSCH codes > 0
+ iE-Extensions ProtocolExtensionContainer { { HS-PDSCH-FDD-Code-Information-ExtIEs} } OPTIONAL,
+ ...
+}
+
+HS-PDSCH-FDD-Code-Information-ExtIEs NBAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+HS-PDSCH-Start-code-number ::= INTEGER (1..maxHS-PDSCHCodeNrComp-1)
+
+HS-SCCH-ID ::= INTEGER (0..31)
+HS-SICH-ID ::= INTEGER (0..31)
+
+HS-SCCH-FDD-Code-Information::= CHOICE {
+ replace HS-SCCH-FDD-Code-List,
+ remove NULL,
+ ...
+}
+
+HS-SCCH-FDD-Code-List ::= SEQUENCE (SIZE (1..maxNrOfHSSCCHs)) OF HS-SCCH-FDD-Code-Information-Item
+
+HS-SCCH-FDD-Code-Information-Item ::= INTEGER (0..maxHS-SCCHCodeNrComp-1)
+
+HSSCCH-CodeChangeIndicator ::= ENUMERATED {
+ hsSCCHCodeChangeNeeded
+}
+
+HSSCCH-Code-Change-Grant ::= ENUMERATED {
+ changeGranted
+}
+
+HSDSCH-FDD-Update-Information ::= SEQUENCE {
+ hsSCCHCodeChangeIndicator HSSCCH-CodeChangeIndicator OPTIONAL,
+ cqiFeedback-CycleK CQI-Feedback-Cycle OPTIONAL,
+ cqiRepetitionFactor CQI-RepetitionFactor OPTIONAL,
+ ackNackRepetitionFactor AckNack-RepetitionFactor OPTIONAL,
+ cqiPowerOffset CQI-Power-Offset OPTIONAL,
+ ackPowerOffset Ack-Power-Offset OPTIONAL,
+ nackPowerOffset Nack-Power-Offset OPTIONAL,
+ iE-Extensions ProtocolExtensionContainer { { HSDSCH-FDD-Update-Information-ExtIEs } } OPTIONAL,
+ ...
+}
+
+HSDSCH-FDD-Update-Information-ExtIEs NBAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+HSDSCH-TDD-Update-Information ::= SEQUENCE {
+ hsSCCHCodeChangeIndicator HSSCCH-CodeChangeIndicator OPTIONAL,
+ tDDAckNackPowerOffset TDD-AckNack-Power-Offset OPTIONAL,
+ iE-Extensions ProtocolExtensionContainer { { HSDSCH-TDD-Update-Information-ExtIEs } } OPTIONAL,
+ ...
+}
+
+HSDSCH-TDD-Update-Information-ExtIEs NBAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+-- ==========================================
+-- I
+-- ==========================================
+
+IB-OC-ID ::= INTEGER (1..16)
+
+IB-SG-DATA ::= BIT STRING
+-- Contains SIB data fixed" or "SIB data variable" in segment as encoded in ref.[18].
+
+IB-SG-POS ::= INTEGER (0..4094)
+-- Only even positions allowed
+
+IB-SG-REP ::= ENUMERATED {rep4, rep8, rep16, rep32, rep64, rep128, rep256, rep512, rep1024, rep2048, rep4096}
+
+IB-Type ::= ENUMERATED {
+ mIB,
+ sB1,
+ sB2,
+ sIB1,
+ sIB2,
+ sIB3,
+ sIB4,
+ sIB5,
+ sIB6,
+ sIB7,
+ sIB8,
+ sIB9,
+ sIB10,
+ sIB11,
+ sIB12,
+ sIB13,
+ sIB13dot1,
+ sIB13dot2,
+ sIB13dot3,
+ sIB13dot4,
+ sIB14,
+ sIB15,
+ sIB15dot1,
+ sIB15dot2,
+ sIB15dot3,
+ sIB16,
+ ...,
+ sIB17,
+ sIB15dot4,
+ sIB18,
+ sIB15dot5
+}
+
+InformationReportCharacteristics ::= CHOICE {
+ onDemand NULL,
+ periodic InformationReportCharacteristicsType-ReportPeriodicity,
+ onModification InformationReportCharacteristicsType-OnModification,
+ ...
+}
+
+InformationReportCharacteristicsType-ReportPeriodicity ::= CHOICE {
+ min ReportPeriodicity-Scaledmin,
+ hours ReportPeriodicity-Scaledhour,
+ ...
+}
+
+InformationReportCharacteristicsType-OnModification ::= SEQUENCE {
+ information-thresholds InformationThresholds OPTIONAL,
+ ie-Extensions ProtocolExtensionContainer { { InformationReportCharacteristicsType-OnModification-ExtIEs} } OPTIONAL,
+ ...
+}
+
+InformationReportCharacteristicsType-OnModification-ExtIEs NBAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+InformationThresholds ::= CHOICE {
+ dgps DGPSThresholds,
+ ...
+}
+
+InformationExchangeID ::= INTEGER (0..1048575)
+
+InformationType ::= SEQUENCE {
+ information-Type-Item Information-Type-Item,
+ gPSInformation GPS-Information OPTIONAL,
+ -- The IE shall be present if the Information Type Item IE indicates "GPS Information".
+ iE-Extensions ProtocolExtensionContainer { { Information-Type-ExtIEs} } OPTIONAL,
+...
+}
+
+Information-Type-ExtIEs NBAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+Information-Type-Item ::= ENUMERATED {
+ gpsinformation,
+ dgpscorrections,
+ gpsrxpos,
+ ...
+}
+
+InnerLoopDLPCStatus ::= ENUMERATED {
+ active,
+ inactive
+}
+
+IPDL-Indicator ::= ENUMERATED {
+ active,
+ inactive
+}
+
+
+IPDL-FDD-Parameters ::= SEQUENCE {
+ iP-SpacingFDD ENUMERATED{sp5,sp7,sp10,sp15,sp20,sp30,sp40,sp50,...},
+ iP-Length ENUMERATED{len5, len10},
+ seed INTEGER(0..63),
+ burstModeParams BurstModeParams OPTIONAL,
+ iP-Offset INTEGER(0..9),
+ iE-Extensions ProtocolExtensionContainer { { IPDLFDDParameter-ExtIEs} } OPTIONAL,
+ ...
+}
+
+IPDLFDDParameter-ExtIEs NBAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+IPDL-TDD-Parameters ::= SEQUENCE {
+ iP-SpacingTDD ENUMERATED{sp30,sp40,sp50,sp70,sp100,...},
+ iP-Start INTEGER(0..4095),
+ iP-Slot INTEGER(0..14),
+ iP-PCCPCH ENUMERATED{switchOff-1-Frame,switchOff-2-Frames},
+ burstModeParams BurstModeParams OPTIONAL,
+ iE-Extensions ProtocolExtensionContainer { { IPDLTDDParameter-ExtIEs} } OPTIONAL,
+ ...
+}
+
+IPDL-TDD-Parameters-LCR ::= SEQUENCE {
+ iP-SpacingTDD ENUMERATED{sp30,sp40,sp50,sp70,sp100,...},
+ iP-Start INTEGER(0..4095),
+ iP-Sub ENUMERATED{first,second,both},
+ burstModeParams BurstModeParams OPTIONAL,
+ iE-Extensions ProtocolExtensionContainer { { IPDLTDDParameterLCR-ExtIEs} } OPTIONAL,
+ ...
+}
+
+BurstModeParams ::= SEQUENCE {
+ burstStart INTEGER(0..15),
+ burstLength INTEGER(10..25),
+ burstFreq INTEGER(1..16),
+ ...
+}
+
+IPDLTDDParameter-ExtIEs NBAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+IPDLTDDParameterLCR-ExtIEs NBAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+-- ==========================================
+-- J
+-- ==========================================
+
+-- ==========================================
+-- K
+-- ==========================================
+
+-- ==========================================
+-- L
+-- ==========================================
+
+LimitedPowerIncrease ::= ENUMERATED {
+ used,
+ not-used
+}
+
+Local-Cell-ID ::= INTEGER (0..268435455)
+
+-- ==========================================
+-- M
+-- ==========================================
+
+MACdPDU-Size ::= INTEGER (1..5000,...)
+
+MACdPDU-Size-Indexlist ::= SEQUENCE (SIZE (1..maxNrOfMACdPDUIndexes)) OF MACdPDU-Size-IndexItem
+
+MACdPDU-Size-IndexItem ::= SEQUENCE {
+ sID SID,
+ macdPDU-Size MACdPDU-Size,
+ iE-Extensions ProtocolExtensionContainer { { MACdPDU-Size-IndexItem-ExtIEs} } OPTIONAL,
+ ...
+}
+
+MACdPDU-Size-IndexItem-ExtIEs NBAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+MACdPDU-Size-Indexlist-to-Modify ::= SEQUENCE (SIZE (1..maxNrOfMACdPDUIndexes)) OF MACdPDU-Size-IndexItem-to-Modify
+
+MACdPDU-Size-IndexItem-to-Modify ::= SEQUENCE {
+ sID SID,
+ macdPDU-Size MACdPDU-Size,
+ iE-Extensions ProtocolExtensionContainer { { MACdPDU-Size-IndexItem-to-Modify-ExtIEs} } OPTIONAL,
+ ...
+}
+
+MACdPDU-Size-IndexItem-to-Modify-ExtIEs NBAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+MAChsGuaranteedBitRate ::= INTEGER (0..16777215,...)
+
+MAChsReorderingBufferSize-for-RLC-UM ::= INTEGER (0..300,...)
+-- Unit kBytes
+
+MAC-hsWindowSize ::= ENUMERATED {v4, v6, v8, v12, v16, v24, v32,...}
+
+MaximumDL-PowerCapability ::= INTEGER(0..500)
+-- Unit dBm, Range 0dBm .. 50dBm, Step +0.1dB
+
+Maximum-PDSCH-Power ::= SEQUENCE {
+ maximum-PDSCH-Power-SF4 DL-Power OPTIONAL,
+ maximum-PDSCH-Power-SF8 DL-Power OPTIONAL,
+ maximum-PDSCH-Power-SF16 DL-Power OPTIONAL,
+ maximum-PDSCH-Power-SF32 DL-Power OPTIONAL,
+ maximum-PDSCH-Power-SF64 DL-Power OPTIONAL,
+ maximum-PDSCH-Power-SF128 DL-Power OPTIONAL,
+ maximum-PDSCH-Power-SF256 DL-Power OPTIONAL,
+ iE-Extensions ProtocolExtensionContainer { { Maximum-PDSCH-Power-ExtIEs} } OPTIONAL,
+ ...
+}
+
+Maximum-PDSCH-Power-ExtIEs NBAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+MaximumTransmissionPower ::= INTEGER(0..500)
+-- Unit dBm, Range 0dBm .. 50dBm, Step +0.1dB
+
+MaxNrOfUL-DPDCHs ::= INTEGER (1..6)
+
+Max-Number-of-PCPCHes ::= INTEGER (1..64,...)
+
+MaxPRACH-MidambleShifts ::= ENUMERATED {
+ shift4,
+ shift8,
+ ...
+}
+
+MeasurementFilterCoefficient ::= ENUMERATED {k0, k1, k2, k3, k4, k5, k6, k7, k8, k9, k11, k13, k15, k17, k19,...}
+-- Measurement Filter Coefficient to be used for measurement
+
+MeasurementID ::= INTEGER (0..1048575)
+
+Measurement-Power-Offset ::= INTEGER(-12 .. 26)
+-- Actual value = IE value * 0.5
+
+MessageStructure ::= SEQUENCE (SIZE (1..maxNrOfLevels)) OF
+ SEQUENCE {
+ iE-ID ProtocolIE-ID,
+ repetitionNumber RepetitionNumber1 OPTIONAL,
+ iE-Extensions ProtocolExtensionContainer { {MessageStructure-ExtIEs} } OPTIONAL,
+ ...
+ }
+
+MessageStructure-ExtIEs NBAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+MidambleConfigurationLCR ::= ENUMERATED {v2, v4, v6, v8, v10, v12, v14, v16, ...}
+
+MidambleConfigurationBurstType1And3 ::= ENUMERATED {v4, v8, v16}
+
+MidambleConfigurationBurstType2 ::= ENUMERATED {v3, v6}
+
+MidambleShiftAndBurstType ::= CHOICE {
+ type1 SEQUENCE {
+ midambleConfigurationBurstType1And3 MidambleConfigurationBurstType1And3,
+ midambleAllocationMode CHOICE {
+ defaultMidamble NULL,
+ commonMidamble NULL,
+ ueSpecificMidamble MidambleShiftLong,
+ ...
+ },
+ ...
+ },
+ type2 SEQUENCE {
+ midambleConfigurationBurstType2 MidambleConfigurationBurstType2,
+ midambleAllocationMode CHOICE {
+ defaultMidamble NULL,
+ commonMidamble NULL,
+ ueSpecificMidamble MidambleShiftShort,
+ ...
+ },
+ ...
+ },
+ type3 SEQUENCE {
+ midambleConfigurationBurstType1And3 MidambleConfigurationBurstType1And3,
+ midambleAllocationMode CHOICE {
+ defaultMidamble NULL,
+ ueSpecificMidamble MidambleShiftLong,
+ ...
+ },
+ ...
+ },
+ ...
+}
+
+MidambleShiftLong ::= INTEGER (0..15)
+
+MidambleShiftShort ::= INTEGER (0..5)
+
+MidambleShiftLCR ::= SEQUENCE {
+ midambleAllocationMode MidambleAllocationMode,
+ midambleShift MidambleShiftLong OPTIONAL,
+ -- The IE shall be present if the Midamble Allocation Mode IE is set to "UE specific midamble".
+midambleConfigurationLCR MidambleConfigurationLCR,
+ iE-Extensions ProtocolExtensionContainer { {MidambleShiftLCR-ExtIEs} } OPTIONAL,
+ ...
+ }
+
+MidambleAllocationMode ::= ENUMERATED {
+ defaultMidamble,
+ commonMidamble,
+ uESpecificMidamble,
+ ...
+ }
+
+MidambleShiftLCR-ExtIEs NBAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+MinimumDL-PowerCapability ::= INTEGER(0..800)
+-- Unit dBm, Range -30dBm .. 50dBm, Step +0.1dB
+
+MinSpreadingFactor ::= ENUMERATED {
+ v4,
+ v8,
+ v16,
+ v32,
+ v64,
+ v128,
+ v256,
+ v512
+}
+-- TDD Mapping scheme for the minimum spreading factor 1 and 2: "256" means 1, "512" means 2
+
+ModifyPriorityQueue ::= CHOICE {
+ addPriorityQueue PriorityQueue-InfoItem-to-Add,
+ modifyPriorityQueue PriorityQueue-InfoItem-to-Modify,
+ deletePriorityQueue PriorityQueue-Id,
+ ...
+}
+
+Modulation ::= ENUMERATED {
+ qPSK,
+ eightPSK,
+ ...
+}
+
+MinUL-ChannelisationCodeLength ::= ENUMERATED {
+ v4,
+ v8,
+ v16,
+ v32,
+ v64,
+ v128,
+ v256,
+ ...
+}
+
+MultiplexingPosition ::= ENUMERATED {
+ fixed,
+ flexible
+}
+
+-- ==========================================
+-- N
+-- ==========================================
+
+Nack-Power-Offset ::= INTEGER (0..8,...)
+-- According to mapping in ref. [9] subclause 4.2.1
+
+NCyclesPerSFNperiod ::= ENUMERATED {
+ v1,
+ v2,
+ v4,
+ v8,
+ ...,
+ v16,
+ v32,
+ v64
+}
+
+NEOT ::= INTEGER (0..8)
+
+NFmax ::= INTEGER (1..64,...)
+
+NRepetitionsPerCyclePeriod ::= INTEGER (2..10)
+
+N-INSYNC-IND ::= INTEGER (1..256)
+
+N-OUTSYNC-IND ::= INTEGER (1..256)
+
+NeighbouringCellMeasurementInformation ::= SEQUENCE (SIZE (1..maxNrOfMeasNCell)) OF
+ CHOICE {
+ neighbouringFDDCellMeasurementInformation NeighbouringFDDCellMeasurementInformation, -- FDD only
+ neighbouringTDDCellMeasurementInformation NeighbouringTDDCellMeasurementInformation,
+ -- Applicable to 3.84Mcps TDD only
+ ...,
+ extension-neighbouringCellMeasurementInformation Extension-neighbouringCellMeasurementInformation
+ }
+
+Extension-neighbouringCellMeasurementInformation ::= ProtocolIE-Single-Container {{ Extension-neighbouringCellMeasurementInformationIE }}
+
+Extension-neighbouringCellMeasurementInformationIE NBAP-PROTOCOL-IES ::= {
+ { ID id-neighbouringTDDCellMeasurementInformationLCR CRITICALITY reject TYPE NeighbouringTDDCellMeasurementInformationLCR PRESENCE mandatory }, -- Applicable to 1.28Mcps TDD only
+ ...
+}
+
+NeighbouringFDDCellMeasurementInformation ::= SEQUENCE {
+ uC-Id UC-Id,
+ uARFCN UARFCN,
+ primaryScramblingCode PrimaryScramblingCode,
+ iE-Extensions ProtocolExtensionContainer { { NeighbouringFDDCellMeasurementInformationItem-ExtIEs} } OPTIONAL,
+ ...
+}
+
+NeighbouringFDDCellMeasurementInformationItem-ExtIEs NBAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+NeighbouringTDDCellMeasurementInformation ::= SEQUENCE {
+ uC-Id UC-Id,
+ uARFCN UARFCN,
+ cellParameterID CellParameterID,
+ timeSlot TimeSlot OPTIONAL,
+ midambleShiftAndBurstType MidambleShiftAndBurstType OPTIONAL,
+ iE-Extensions ProtocolExtensionContainer { { NeighbouringTDDCellMeasurementInformationItem-ExtIEs} } OPTIONAL,
+ ...
+}
+
+NeighbouringTDDCellMeasurementInformationItem-ExtIEs NBAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+NeighbouringTDDCellMeasurementInformationLCR ::= SEQUENCE {
+ uC-Id UC-Id,
+ uARFCN UARFCN,
+ cellParameterID CellParameterID,
+ timeSlotLCR TimeSlotLCR OPTIONAL,
+ midambleShiftLCR MidambleShiftLCR OPTIONAL,
+ iE-Extensions ProtocolExtensionContainer { { NeighbouringTDDCellMeasurementInformationLCRItem-ExtIEs} } OPTIONAL,
+ ...
+}
+
+NeighbouringTDDCellMeasurementInformationLCRItem-ExtIEs NBAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+NodeB-CommunicationContextID ::= INTEGER (0..1048575)
+
+NumberOfReportedCellPortions ::= INTEGER (1..maxNrOfCellPortionsPerCell,...)
+
+NStartMessage ::= INTEGER (1..8)
+
+NSubCyclesPerCyclePeriod ::= INTEGER (1..16,...)
+
+-- ==========================================
+-- O
+-- ==========================================
+
+-- ==========================================
+-- P
+-- ==========================================
+
+PagingIndicatorLength ::= ENUMERATED {
+ v2,
+ v4,
+ v8,
+ ...
+}
+
+PayloadCRC-PresenceIndicator ::= ENUMERATED {
+ cRC-Included,
+ cRC-NotIncluded,
+ ...
+}
+
+PCCPCH-Power ::= INTEGER (-150..400,...)
+-- PCCPCH-power = power * 10
+-- If power <= -15 PCCPCH shall be set to -150
+-- If power >= 40 PCCPCH shall be set to 400
+-- Unit dBm, Range -15dBm .. +40 dBm, Step +0.1dB
+
+PCP-Length ::= ENUMERATED{
+ v0,
+ v8
+}
+
+PDSCH-CodeMapping ::= SEQUENCE {
+ dl-ScramblingCode DL-ScramblingCode,
+ signallingMethod CHOICE {
+ code-Range PDSCH-CodeMapping-PDSCH-CodeMappingInformationList,
+ tFCI-Range PDSCH-CodeMapping-DSCH-MappingInformationList,
+ explicit PDSCH-CodeMapping-PDSCH-CodeInformationList,
+ ...,
+ replace PDSCH-CodeMapping-ReplacedPDSCH-CodeInformationList
+ },
+ iE-Extensions ProtocolExtensionContainer { { PDSCH-CodeMapping-ExtIEs} } OPTIONAL,
+ ...
+}
+
+PDSCH-CodeMapping-ExtIEs NBAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+PDSCH-CodeMapping-CodeNumberComp ::= INTEGER (0..maxCodeNrComp-1)
+
+PDSCH-CodeMapping-SpreadingFactor ::= ENUMERATED {
+ v4,
+ v8,
+ v16,
+ v32,
+ v64,
+ v128,
+ v256,
+ ...
+}
+
+PDSCH-CodeMapping-PDSCH-CodeMappingInformationList ::= SEQUENCE (SIZE (1..maxNrOfCodeGroups)) OF
+ SEQUENCE {
+ spreadingFactor PDSCH-CodeMapping-SpreadingFactor,
+ multi-CodeInfo PDSCH-Multi-CodeInfo,
+ start-CodeNumber PDSCH-CodeMapping-CodeNumberComp,
+ stop-CodeNumber PDSCH-CodeMapping-CodeNumberComp,
+ iE-Extensions ProtocolExtensionContainer { { PDSCH-CodeMapping-PDSCH-CodeMappingInformationList-ExtIEs} } OPTIONAL,
+ ...
+}
+
+PDSCH-CodeMapping-PDSCH-CodeMappingInformationList-ExtIEs NBAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+PDSCH-CodeMapping-DSCH-MappingInformationList ::= SEQUENCE (SIZE (1..maxNrOfTFCIGroups)) OF
+ SEQUENCE {
+ maxTFCI-field2-Value PDSCH-CodeMapping-MaxTFCI-Field2-Value,
+ spreadingFactor PDSCH-CodeMapping-SpreadingFactor,
+ multi-CodeInfo PDSCH-Multi-CodeInfo,
+ codeNumber PDSCH-CodeMapping-CodeNumberComp,
+ iE-Extensions ProtocolExtensionContainer { { PDSCH-CodeMapping-DSCH-MappingInformationList-ExtIEs} } OPTIONAL,
+ ...
+}
+
+PDSCH-CodeMapping-DSCH-MappingInformationList-ExtIEs NBAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+PDSCH-CodeMapping-MaxTFCI-Field2-Value ::= INTEGER (1..1023)
+
+PDSCH-CodeMapping-PDSCH-CodeInformationList ::= SEQUENCE (SIZE (1..maxNrOfTFCI2Combs)) OF
+ SEQUENCE {
+ spreadingFactor PDSCH-CodeMapping-SpreadingFactor,
+ multi-CodeInfo PDSCH-Multi-CodeInfo,
+ codeNumber PDSCH-CodeMapping-CodeNumberComp,
+ iE-Extensions ProtocolExtensionContainer { { PDSCH-CodeMapping-PDSCH-CodeInformationList-ExtIEs} } OPTIONAL,
+ ...
+}
+
+PDSCH-CodeMapping-PDSCH-CodeInformationList-ExtIEs NBAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+PDSCH-CodeMapping-ReplacedPDSCH-CodeInformationList ::= SEQUENCE (SIZE (1..maxNrOfTFCI2Combs)) OF
+ SEQUENCE {
+ tfci-Field2 TFCS-MaxTFCI-field2-Value,
+ spreadingFactor PDSCH-CodeMapping-SpreadingFactor,
+ multi-CodeInfo PDSCH-Multi-CodeInfo,
+ codeNumber PDSCH-CodeMapping-CodeNumberComp,
+ iE-Extensions ProtocolExtensionContainer { { PDSCH-CodeMapping-ReplacedPDSCH-CodeInformationList-ExtIEs} } OPTIONAL,
+ ...
+}
+
+PDSCH-CodeMapping-ReplacedPDSCH-CodeInformationList-ExtIEs NBAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+PDSCH-Multi-CodeInfo ::= INTEGER (1..16)
+
+PDSCH-ID ::= INTEGER (0..255)
+
+PDSCHSet-ID ::= INTEGER (0..255)
+
+PICH-Mode ::= ENUMERATED {
+ v18,
+ v36,
+ v72,
+ v144,
+ ...
+}
+
+PICH-Power ::= INTEGER (-10..5)
+-- Unit dB, Range -10dB .. +5dB, Step +1dB
+
+PowerAdjustmentType ::= ENUMERATED {
+ none,
+ common,
+ individual
+}
+
+PowerOffset ::= INTEGER (0..24)
+-- PowerOffset = offset * 0.25
+-- Unit dB, Range 0dB .. +6dB, Step +0.25dB
+
+PowerRaiseLimit ::= INTEGER (0..10)
+
+PRACH-Midamble ::= ENUMERATED {
+ inverted,
+ direct,
+ ...
+}
+
+PRC ::= INTEGER (-2047..2047)
+--pseudo range correction; scaling factor 0.32 meters
+
+PRCDeviation ::= ENUMERATED {
+ one,
+ two,
+ five,
+ ten,
+ ...
+}
+
+PreambleSignatures ::= BIT STRING {
+ signature15(0),
+ signature14(1),
+ signature13(2),
+ signature12(3),
+ signature11(4),
+ signature10(5),
+ signature9(6),
+ signature8(7),
+ signature7(8),
+ signature6(9),
+ signature5(10),
+ signature4(11),
+ signature3(12),
+ signature2(13),
+ signature1(14),
+ signature0(15)
+ } (SIZE (16))
+
+PreambleThreshold ::= INTEGER (0..72)
+-- 0= -36.0dB, 1= -35.5dB, ... , 72= 0.0dB
+
+PredictedSFNSFNDeviationLimit ::=INTEGER (1..256)
+-- Unit chip, Step 1/16 chip, Range 1/16..16 chip
+
+PredictedTUTRANGPSDeviationLimit ::= INTEGER (1..256)
+-- Unit chip, Step 1/16 chip, Range 1/16..16 chip
+
+Pre-emptionCapability ::= ENUMERATED {
+ shall-not-trigger-pre-emption,
+ may-trigger-pre-emption
+}
+
+Pre-emptionVulnerability ::= ENUMERATED {
+ not-pre-emptable,
+ pre-emptable
+}
+
+PrimaryCPICH-Power ::= INTEGER(-100..500)
+-- step 0.1 (Range -10.0..50.0) Unit is dBm
+
+Primary-CPICH-Usage-for-Channel-Estimation ::= ENUMERATED {
+primary-CPICH-may-be-used,
+primary-CPICH-shall-not-be-used
+}
+
+PrimaryScramblingCode ::= INTEGER (0..511)
+
+PriorityLevel ::= INTEGER (0..15)
+-- 0 = spare, 1 = highest priority, ...14 = lowest priority and 15 = no priority
+
+PriorityQueue-Id ::= INTEGER (0..maxNrOfPriorityQueues-1)
+
+PriorityQueue-InfoList ::= SEQUENCE (SIZE (1..maxNrOfPriorityQueues)) OF PriorityQueue-InfoItem
+
+PriorityQueue-InfoItem ::= SEQUENCE {
+ priorityQueueId PriorityQueue-Id,
+ associatedHSDSCH-MACdFlow HSDSCH-MACdFlow-ID,
+ schedulingPriorityIndicator SchedulingPriorityIndicator,
+ t1 T1,
+ discardTimer DiscardTimer OPTIONAL,
+ mAC-hsWindowSize MAC-hsWindowSize,
+ mAChsGuaranteedBitRate MAChsGuaranteedBitRate OPTIONAL,
+ macdPDU-Size-Index MACdPDU-Size-Indexlist,
+ rLC-Mode RLC-Mode,
+ iE-Extensions ProtocolExtensionContainer { { PriorityQueue-InfoItem-ExtIEs} } OPTIONAL,
+ ...
+}
+
+PriorityQueue-InfoItem-ExtIEs NBAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+PriorityQueue-InfoList-to-Modify ::= SEQUENCE (SIZE (1..maxNrOfPriorityQueues)) OF ModifyPriorityQueue
+
+PriorityQueue-InfoItem-to-Add ::= SEQUENCE {
+ priorityQueueId PriorityQueue-Id,
+ associatedHSDSCH-MACdFlow HSDSCH-MACdFlow-ID,
+ schedulingPriorityIndicator SchedulingPriorityIndicator,
+ t1 T1,
+ discardTimer DiscardTimer OPTIONAL,
+ mAC-hsWindowSize MAC-hsWindowSize,
+ mAChsGuaranteedBitRate MAChsGuaranteedBitRate OPTIONAL,
+ macdPDU-Size-Index MACdPDU-Size-Indexlist,
+ rLC-Mode RLC-Mode,
+ iE-Extensions ProtocolExtensionContainer { { PriorityQueue-InfoItem-to-Add-ExtIEs} } OPTIONAL,
+ ...
+}
+
+PriorityQueue-InfoItem-to-Add-ExtIEs NBAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+PriorityQueue-InfoItem-to-Modify ::= SEQUENCE {
+ priorityQueueId PriorityQueue-Id,
+ schedulingPriorityIndicator SchedulingPriorityIndicator OPTIONAL,
+ t1 T1 OPTIONAL,
+ discardTimer DiscardTimer OPTIONAL,
+ mAC-hsWindowSize MAC-hsWindowSize OPTIONAL,
+ mAChsGuaranteedBitRate MAChsGuaranteedBitRate OPTIONAL,
+ macdPDU-Size-Index-to-Modify MACdPDU-Size-Indexlist-to-Modify OPTIONAL,
+ iE-Extensions ProtocolExtensionContainer { { PriorityQueue-InfoItem-to-Modify-ExtIEs} } OPTIONAL,
+ ...
+}
+
+PriorityQueue-InfoItem-to-Modify-ExtIEs NBAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+PriorityQueue-InfoList-to-Modify-Unsynchronised ::= SEQUENCE (SIZE (1..maxNrOfPriorityQueues)) OF PriorityQueue-InfoItem-to-Modify-Unsynchronised
+
+PriorityQueue-InfoItem-to-Modify-Unsynchronised ::= SEQUENCE {
+ priorityQueueId PriorityQueue-Id,
+ schedulingPriorityIndicator SchedulingPriorityIndicator OPTIONAL,
+ discardTimer DiscardTimer OPTIONAL,
+ mAChsGuaranteedBitRate MAChsGuaranteedBitRate OPTIONAL,
+ iE-Extensions ProtocolExtensionContainer { { PriorityQueue-InfoItem-to-Modify-Unsynchronised-ExtIEs} } OPTIONAL,
+ ...
+}
+
+PriorityQueue-InfoItem-to-Modify-Unsynchronised-ExtIEs NBAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+PrimaryCCPCH-RSCP ::= INTEGER (0..91)
+-- Mapping of non-negative values according to [23]
+
+PrimaryCCPCH-RSCP-Delta ::= INTEGER (-5..-1,...)
+-- Mapping of negative values according to [23]
+
+PropagationDelay ::= INTEGER (0..255)
+-- Unit: chips, step size 3 chips
+-- example: 0 = 0chip, 1 = 3chips
+
+SCH-TimeSlot ::= INTEGER (0..6)
+
+PunctureLimit ::= INTEGER (0..15)
+-- 0: 40%; 1: 44%; ... 14: 96%; 15: 100%
+
+PUSCH-ID ::= INTEGER (0..255)
+
+PUSCHSet-ID ::= INTEGER (0..255)
+
+-- ==========================================
+-- Q
+-- ==========================================
+
+QE-Selector ::= ENUMERATED {
+ selected,
+ non-selected
+}
+
+Qth-Parameter ::= INTEGER (-20..0)
+-- Unit dB, Step 1dB
+
+-- ==========================================
+-- R
+-- ==========================================
+
+RACH-SlotFormat ::= ENUMERATED {
+ v0,
+ v1,
+ v2,
+ v3,
+ ...
+}
+
+RACH-SubChannelNumbers ::= BIT STRING {
+ subCh11(0),
+ subCh10(1),
+ subCh9(2),
+ subCh8(3),
+ subCh7(4),
+ subCh6(5),
+ subCh5(6),
+ subCh4(7),
+ subCh3(8),
+ subCh2(9),
+ subCh1(10),
+ subCh0(11)
+ } (SIZE (12))
+
+RL-Specific-DCH-Info ::= SEQUENCE (SIZE (1..maxNrOfDCHs)) OF RL-Specific-DCH-Info-Item
+
+RL-Specific-DCH-Info-Item ::= SEQUENCE {
+ dCH-id DCH-ID,
+ bindingID BindingID OPTIONAL,
+ transportlayeraddress TransportLayerAddress OPTIONAL,
+ iE-Extensions ProtocolExtensionContainer { { RL-Specific-DCH-Info-Item-ExtIEs} } OPTIONAL,
+ ...
+}
+
+RL-Specific-DCH-Info-Item-ExtIEs NBAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+Range-Correction-Rate ::= INTEGER (-127..127)
+-- scaling factor 0.032 m/s
+
+ReferenceClockAvailability ::= ENUMERATED {
+ available,
+ notAvailable
+}
+
+ReferenceSFNoffset ::= INTEGER (0..255)
+
+RepetitionLength ::= INTEGER (1..63)
+
+RepetitionPeriod ::= ENUMERATED {
+ v1,
+ v2,
+ v4,
+ v8,
+ v16,
+ v32,
+ v64,
+ ...
+}
+
+RepetitionNumber0 ::= INTEGER (0..255)
+
+RepetitionNumber1 ::= INTEGER (1..256)
+
+RefTFCNumber ::= INTEGER (0..3)
+
+ReportCharacteristics ::= CHOICE {
+ onDemand NULL,
+ periodic ReportCharacteristicsType-ReportPeriodicity,
+ event-a ReportCharacteristicsType-EventA,
+ event-b ReportCharacteristicsType-EventB,
+ event-c ReportCharacteristicsType-EventC,
+ event-d ReportCharacteristicsType-EventD,
+ event-e ReportCharacteristicsType-EventE,
+ event-f ReportCharacteristicsType-EventF,
+ ...,
+ extension-ReportCharacteristics Extension-ReportCharacteristics
+}
+
+Extension-ReportCharacteristics ::= ProtocolIE-Single-Container {{ Extension-ReportCharacteristicsIE }}
+
+Extension-ReportCharacteristicsIE NBAP-PROTOCOL-IES ::= {
+ { ID id-ReportCharacteristicsType-OnModification CRITICALITY reject TYPE ReportCharacteristicsType-OnModification PRESENCE mandatory }
+}
+
+ReportCharacteristicsType-EventA ::= SEQUENCE {
+ measurementThreshold ReportCharacteristicsType-MeasurementThreshold,
+ measurementHysteresisTime ReportCharacteristicsType-ScaledMeasurementHysteresisTime OPTIONAL,
+ iE-Extensions ProtocolExtensionContainer { { ReportCharacteristicsType-EventA-ExtIEs} } OPTIONAL,
+ ...
+ }
+
+ReportCharacteristicsType-EventA-ExtIEs NBAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+ReportCharacteristicsType-EventB ::= SEQUENCE {
+ measurementThreshold ReportCharacteristicsType-MeasurementThreshold,
+ measurementHysteresisTime ReportCharacteristicsType-ScaledMeasurementHysteresisTime OPTIONAL,
+ iE-Extensions ProtocolExtensionContainer { { ReportCharacteristicsType-EventB-ExtIEs} } OPTIONAL,
+ ...
+ }
+
+ReportCharacteristicsType-EventB-ExtIEs NBAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+ReportCharacteristicsType-EventC ::= SEQUENCE {
+ measurementIncreaseThreshold ReportCharacteristicsType-MeasurementIncreaseDecreaseThreshold,
+ measurementChangeTime ReportCharacteristicsType-ScaledMeasurementChangeTime,
+ iE-Extensions ProtocolExtensionContainer { { ReportCharacteristicsType-EventC-ExtIEs} } OPTIONAL,
+ ...
+ }
+
+ReportCharacteristicsType-EventC-ExtIEs NBAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+ReportCharacteristicsType-EventD ::= SEQUENCE {
+ measurementDecreaseThreshold ReportCharacteristicsType-MeasurementIncreaseDecreaseThreshold,
+ measurementChangeTime ReportCharacteristicsType-ScaledMeasurementChangeTime,
+ iE-Extensions ProtocolExtensionContainer { { ReportCharacteristicsType-EventD-ExtIEs} } OPTIONAL,
+ ...
+ }
+
+ReportCharacteristicsType-EventD-ExtIEs NBAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+ReportCharacteristicsType-EventE ::= SEQUENCE {
+ measurementThreshold1 ReportCharacteristicsType-MeasurementThreshold,
+ measurementThreshold2 ReportCharacteristicsType-MeasurementThreshold OPTIONAL,
+ measurementHysteresisTime ReportCharacteristicsType-ScaledMeasurementHysteresisTime OPTIONAL,
+ reportPeriodicity ReportCharacteristicsType-ReportPeriodicity OPTIONAL,
+ iE-Extensions ProtocolExtensionContainer { { ReportCharacteristicsType-EventE-ExtIEs} } OPTIONAL,
+ ...
+ }
+
+ReportCharacteristicsType-EventE-ExtIEs NBAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+ReportCharacteristicsType-EventF ::= SEQUENCE {
+ measurementThreshold1 ReportCharacteristicsType-MeasurementThreshold,
+ measurementThreshold2 ReportCharacteristicsType-MeasurementThreshold OPTIONAL,
+ measurementHysteresisTime ReportCharacteristicsType-ScaledMeasurementHysteresisTime OPTIONAL,
+ reportPeriodicity ReportCharacteristicsType-ReportPeriodicity OPTIONAL,
+ iE-Extensions ProtocolExtensionContainer { { ReportCharacteristicsType-EventF-ExtIEs} } OPTIONAL,
+ ...
+ }
+
+ReportCharacteristicsType-EventF-ExtIEs NBAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+ReportCharacteristicsType-OnModification ::= SEQUENCE {
+ measurementThreshold ReportCharacteristicsType-MeasurementThreshold,
+ iE-Extensions ProtocolExtensionContainer { { ReportCharacteristicsType-OnModification-ExtIEs} } OPTIONAL,
+ ...
+ }
+
+ReportCharacteristicsType-OnModification-ExtIEs NBAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+ReportCharacteristicsType-MeasurementIncreaseDecreaseThreshold ::= CHOICE {
+ received-total-wide-band-power Received-total-wide-band-power-Value-IncrDecrThres,
+ transmitted-carrier-power Transmitted-Carrier-Power-Value,
+ acknowledged-prach-preambles Acknowledged-PRACH-preambles-Value,
+ uL-TimeslotISCP UL-TimeslotISCP-Value-IncrDecrThres,
+ sir SIR-Value-IncrDecrThres,
+ sir-error SIR-Error-Value-IncrDecrThres,
+ transmitted-code-power Transmitted-Code-Power-Value-IncrDecrThres,
+ rscp RSCP-Value-IncrDecrThres,
+ round-trip-time Round-Trip-Time-IncrDecrThres,
+ acknowledged-PCPCH-access-preambles Acknowledged-PCPCH-access-preambles,
+ detected-PCPCH-access-preambles Detected-PCPCH-access-preambles,
+ ...,
+ extension-ReportCharacteristicsType-MeasurementIncreaseDecreaseThreshold Extension-ReportCharacteristicsType-MeasurementIncreaseDecreaseThreshold
+}
+
+Extension-ReportCharacteristicsType-MeasurementIncreaseDecreaseThreshold ::= ProtocolIE-Single-Container {{ Extension-ReportCharacteristicsType-MeasurementIncreaseDecreaseThresholdIE }}
+
+Extension-ReportCharacteristicsType-MeasurementIncreaseDecreaseThresholdIE NBAP-PROTOCOL-IES ::= {
+{ ID id-TransmittedCarrierPowerOfAllCodesNotUsedForHS-PDSCHOrHS-SCCHTransmission CRITICALITY reject TYPE TransmittedCarrierPowerOfAllCodesNotUsedForHS-PDSCHOrHS-SCCHTransmissionValue PRESENCE mandatory}
+}
+
+ReportCharacteristicsType-MeasurementThreshold ::= CHOICE {
+ received-total-wide-band-power Received-total-wide-band-power-Value,
+ transmitted-carrier-power Transmitted-Carrier-Power-Value,
+ acknowledged-prach-preambles Acknowledged-PRACH-preambles-Value,
+ uL-TimeslotISCP UL-TimeslotISCP-Value,
+ sir SIR-Value,
+ sir-error SIR-Error-Value,
+ transmitted-code-power Transmitted-Code-Power-Value,
+ rscp RSCP-Value,
+ rx-timing-deviation Rx-Timing-Deviation-Value,
+ round-trip-time Round-Trip-Time-Value,
+ acknowledged-PCPCH-access-preambles Acknowledged-PCPCH-access-preambles,
+ detected-PCPCH-access-preambles Detected-PCPCH-access-preambles,
+ ...,
+ extension-ReportCharacteristicsType-MeasurementThreshold Extension-ReportCharacteristicsType-MeasurementThreshold
+}
+
+Extension-ReportCharacteristicsType-MeasurementThreshold ::= ProtocolIE-Single-Container {{ Extension-ReportCharacteristicsType-MeasurementThresholdIE }}
+
+Extension-ReportCharacteristicsType-MeasurementThresholdIE NBAP-PROTOCOL-IES ::= {
+ { ID id-TUTRANGPSMeasurementThresholdInformation CRITICALITY reject TYPE TUTRANGPSMeasurementThresholdInformation PRESENCE mandatory }|
+ { ID id-SFNSFNMeasurementThresholdInformation CRITICALITY reject TYPE SFNSFNMeasurementThresholdInformation PRESENCE mandatory }|
+ { ID id-Rx-Timing-Deviation-Value-LCR CRITICALITY reject TYPE Rx-Timing-Deviation-Value-LCR PRESENCE mandatory}|
+ { ID id-HS-SICH-Reception-Quality-Measurement-Value CRITICALITY reject TYPE HS-SICH-Reception-Quality-Measurement-Value PRESENCE mandatory}|
+ { ID id-TransmittedCarrierPowerOfAllCodesNotUsedForHS-PDSCHOrHS-SCCHTransmission CRITICALITY reject TYPE TransmittedCarrierPowerOfAllCodesNotUsedForHS-PDSCHOrHS-SCCHTransmissionValue PRESENCE mandatory}|
+ { ID id-HS-DSCHRequiredPowerValue CRITICALITY reject TYPE HS-DSCHRequiredPowerValue PRESENCE mandatory}
+}
+
+ReportCharacteristicsType-ScaledMeasurementChangeTime ::= CHOICE {
+ msec MeasurementChangeTime-Scaledmsec,
+ ...
+}
+
+MeasurementChangeTime-Scaledmsec ::= INTEGER (1..6000,...)
+-- MeasurementChangeTime-Scaledmsec = Time * 10
+-- Unit ms, Range 10ms .. 60000ms(1min), Step 10ms
+
+ReportCharacteristicsType-ScaledMeasurementHysteresisTime ::= CHOICE {
+ msec MeasurementHysteresisTime-Scaledmsec,
+ ...
+}
+
+MeasurementHysteresisTime-Scaledmsec ::= INTEGER (1..6000,...)
+-- MeasurementHysteresisTime-Scaledmsec = Time * 10
+-- Unit ms, Range 10ms .. 60000ms(1min), Step 10ms
+
+ReportCharacteristicsType-ReportPeriodicity ::= CHOICE {
+ msec ReportPeriodicity-Scaledmsec,
+ min ReportPeriodicity-Scaledmin,
+ ...
+}
+
+ReportPeriodicity-Scaledmsec ::= INTEGER (1..6000,...)
+-- ReportPeriodicity-msec = ReportPeriodicity * 10
+-- Unit ms, Range 10ms .. 60000ms(1min), Step 10ms
+
+ReportPeriodicity-Scaledmin ::= INTEGER (1..60,...)
+-- Unit min, Range 1min .. 60min(hour), Step 1min
+
+ReportPeriodicity-Scaledhour ::= INTEGER (1..24,...)
+-- Unit hour, Range 1hour .. 24hours(day), Step 1hour
+
+ResourceOperationalState ::= ENUMERATED {
+ enabled,
+ disabled
+}
+
+RL-ID ::= INTEGER (0..31)
+
+RL-Set-ID ::= INTEGER (0..31)
+
+RLC-Mode ::= ENUMERATED {
+ rLC-AM,
+ rLC-UM,
+ ...
+}
+
+Round-Trip-Time-IncrDecrThres ::= INTEGER(0..32766)
+
+RNC-ID ::= INTEGER (0..4095)
+
+Round-Trip-Time-Value ::= INTEGER(0..32767)
+-- According to mapping in [22]
+
+RSCP-Value ::= INTEGER (0..127)
+-- According to mapping in [23]
+
+RSCP-Value-IncrDecrThres ::= INTEGER (0..126)
+
+Received-total-wide-band-power-Value ::= INTEGER(0..621)
+-- According to mapping in [22]/[23]
+
+Received-total-wide-band-power-Value-IncrDecrThres ::= INTEGER (0..620)
+
+RequestedDataValueInformation ::= CHOICE {
+ informationAvailable InformationAvailable,
+ informationnotAvailable InformationnotAvailable
+}
+
+InformationAvailable::= SEQUENCE {
+ requesteddataValue RequestedDataValue,
+ ie-Extensions ProtocolExtensionContainer { { InformationAvailableItem-ExtIEs} } OPTIONAL,
+ ...
+}
+
+InformationAvailableItem-ExtIEs NBAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+InformationnotAvailable ::= NULL
+
+RequestedDataValue ::= SEQUENCE {
+ dgps-corrections DGPSCorrections OPTIONAL,
+ gps-navandrecovery GPS-NavigationModel-and-TimeRecovery OPTIONAL,
+ gps-ionos-model GPS-Ionospheric-Model OPTIONAL,
+ gps-utc-model GPS-UTC-Model OPTIONAL,
+ gps-almanac GPS-Almanac OPTIONAL,
+ gps-rt-integrity GPS-RealTime-Integrity OPTIONAL,
+ gpsrxpos GPS-RX-POS OPTIONAL,
+ iE-Extensions ProtocolExtensionContainer { { RequestedDataValue-ExtIEs} } OPTIONAL,
+ ...
+}
+
+RequestedDataValue-ExtIEs NBAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+Rx-Timing-Deviation-Value ::= INTEGER (0..8191)
+-- According to mapping in [23]
+
+Rx-Timing-Deviation-Value-LCR ::= INTEGER (0..511)
+-- According to mapping in [23]
+
+-- ==========================================
+-- S
+-- ==========================================
+
+AdjustmentPeriod ::= INTEGER(1..256)
+-- Unit Frame
+
+SAT-ID ::= INTEGER (0..63)
+
+SAT-Info-Almanac ::= SEQUENCE (SIZE (1..maxNoSat)) OF SAT-Info-Almanac-Item
+
+SAT-Info-Almanac-Item ::= SEQUENCE {
+ data-id DATA-ID,
+ sat-id SAT-ID,
+ gps-e-alm BIT STRING (SIZE (16)),
+ gps-toa-alm BIT STRING (SIZE (8)),
+ gps-delta-I-alm BIT STRING (SIZE (16)),
+ omegadot-alm BIT STRING (SIZE (16)),
+ svhealth-alm BIT STRING (SIZE (8)),
+ gps-a-sqrt-alm BIT STRING (SIZE (24)),
+ omegazero-alm BIT STRING (SIZE (24)),
+ m-zero-alm BIT STRING (SIZE (24)),
+ gps-omega-alm BIT STRING (SIZE (24)),
+ gps-af-zero-alm BIT STRING (SIZE (11)),
+ gps-af-one-alm BIT STRING (SIZE (11)),
+ ie-Extensions ProtocolExtensionContainer { { SAT-Info-Almanac-Item-ExtIEs} } OPTIONAL,
+ ...
+} -- This GPS-Almanac-Information is for the 1st 16 satellites
+
+SAT-Info-Almanac-Item-ExtIEs NBAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+SAT-Info-Almanac-ExtList ::= SEQUENCE (SIZE (1..maxNrOfSatAlmanac-maxNoSat)) OF SAT-Info-Almanac-ExtItem
+
+SAT-Info-Almanac-ExtItem ::= SEQUENCE {
+ data-id DATA-ID,
+ sat-id SAT-ID,
+ gps-e-alm BIT STRING (SIZE (16)),
+ gps-toa-alm BIT STRING (SIZE (8)),
+ gps-delta-I-alm BIT STRING (SIZE (16)),
+ omegadot-alm BIT STRING (SIZE (16)),
+ svhealth-alm BIT STRING (SIZE (8)),
+ gps-a-sqrt-alm BIT STRING (SIZE (24)),
+ omegazero-alm BIT STRING (SIZE (24)),
+ m-zero-alm BIT STRING (SIZE (24)),
+ gps-omega-alm BIT STRING (SIZE (24)),
+ gps-af-zero-alm BIT STRING (SIZE (11)),
+ gps-af-one-alm BIT STRING (SIZE (11)),
+ ie-Extensions ProtocolExtensionContainer { { SAT-Info-Almanac-ExtItemIEs } } OPTIONAL,
+ ...
+} -- Includes the GPS-Almanac-Information for 17th through 32nd satellites.
+
+SAT-Info-Almanac-ExtItemIEs NBAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+SAT-Info-DGPSCorrections ::= SEQUENCE (SIZE (1..maxNoSat)) OF SAT-Info-DGPSCorrections-Item
+
+SAT-Info-DGPSCorrections-Item ::= SEQUENCE {
+ sat-id SAT-ID,
+ iode-dgps BIT STRING (SIZE (8)),
+ udre UDRE,
+ prc PRC,
+ range-correction-rate Range-Correction-Rate,
+ ie-Extensions ProtocolExtensionContainer { { SAT-Info-DGPSCorrections-Item-ExtIEs} } OPTIONAL,
+ ...
+}
+
+SAT-Info-DGPSCorrections-Item-ExtIEs NBAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+SATInfo-RealTime-Integrity ::= SEQUENCE (SIZE (1..maxNoSat)) OF SAT-Info-RealTime-Integrity-Item
+
+SAT-Info-RealTime-Integrity-Item ::= SEQUENCE {
+ bad-sat-id SAT-ID,
+ ie-Extensions ProtocolExtensionContainer { { SAT-Info-RealTime-Integrity-Item-ExtIEs} } OPTIONAL,
+ ...
+}
+
+SAT-Info-RealTime-Integrity-Item-ExtIEs NBAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+ScaledAdjustmentRatio ::= INTEGER(0..100)
+-- AdjustmentRatio = ScaledAdjustmentRatio / 100
+
+MaxAdjustmentStep ::= INTEGER(1..10)
+-- Unit Slot
+
+SchedulingPriorityIndicator ::= INTEGER (0..15) -- lowest (0), highest (15)
+
+SID ::= INTEGER (0..maxNrOfMACdPDUIndexes-1)
+
+ScramblingCodeNumber ::= INTEGER (0..15)
+
+Secondary-CPICH-Information-Change ::= CHOICE {
+ new-secondary-CPICH CommonPhysicalChannelID,
+ secondary-CPICH-shall-not-be-used NULL,
+...
+}
+
+SecondaryCCPCH-SlotFormat ::= INTEGER(0..17,...)
+
+Segment-Type ::= ENUMERATED {
+ first-segment,
+ first-segment-short,
+ subsequent-segment,
+ last-segment,
+ last-segment-short,
+ complete-SIB,
+ complete-SIB-short,
+ ...
+}
+
+S-FieldLength ::= ENUMERATED {
+ v1,
+ v2,
+ ...
+}
+
+SFN ::= INTEGER (0..4095)
+
+SFNSFN-FDD ::= INTEGER (0..614399)
+
+SFNSFN-TDD ::= INTEGER (0..40961)
+
+SFNSFNChangeLimit ::= INTEGER (1..256)
+-- Unit chip, Step 1/16 chip, Range 1/16..16 chip
+
+SFNSFNDriftRate ::= INTEGER (-100..100)
+-- Unit chip/s, Step 1/256 chip/s, Range -100/256..+100/256 chip/s
+
+SFNSFNDriftRateQuality ::= INTEGER (0..100)
+-- Unit chip/s, Step 1/256 chip/s, Range 0..100/256 chip/s
+
+SFNSFNMeasurementThresholdInformation::= SEQUENCE {
+ sFNSFNChangeLimit SFNSFNChangeLimit OPTIONAL,
+ predictedSFNSFNDeviationLimit PredictedSFNSFNDeviationLimit OPTIONAL,
+ iE-Extensions ProtocolExtensionContainer { { SFNSFNMeasurementThresholdInformation-ExtIEs} } OPTIONAL,
+ ...
+}
+
+SFNSFNMeasurementThresholdInformation-ExtIEs NBAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+SFNSFNMeasurementValueInformation ::= SEQUENCE {
+ successfullNeighbouringCellSFNSFNObservedTimeDifferenceMeasurementInformation SEQUENCE (SIZE(1..maxNrOfMeasNCell)) OF
+ SEQUENCE {
+ uC-Id UC-Id,
+ sFNSFNValue SFNSFNValue,
+ sFNSFNQuality SFNSFNQuality OPTIONAL,
+ sFNSFNDriftRate SFNSFNDriftRate,
+ sFNSFNDriftRateQuality SFNSFNDriftRateQuality OPTIONAL,
+ sFNSFNTimeStampInformation SFNSFNTimeStampInformation,
+ iE-Extensions ProtocolExtensionContainer { { SuccessfullNeighbouringCellSFNSFNObservedTimeDifferenceMeasurementInformationItem-ExtIEs} } OPTIONAL,
+ ...
+ },
+ unsuccessfullNeighbouringCellSFNSFNObservedTimeDifferenceMeasurementInformation SEQUENCE (SIZE(0..maxNrOfMeasNCell-1)) OF
+ SEQUENCE {
+ uC-Id UC-Id,
+ iE-Extensions ProtocolExtensionContainer { { UnsuccessfullNeighbouringCellSFNSFNObservedTimeDifferenceMeasurementInformationItem-ExtIEs} } OPTIONAL,
+ ...
+ },
+ iE-Extensions ProtocolExtensionContainer { { SFNSFNMeasurementValueInformationItem-ExtIEs} } OPTIONAL,
+ ...
+}
+
+SFNSFNMeasurementValueInformationItem-ExtIEs NBAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+SuccessfullNeighbouringCellSFNSFNObservedTimeDifferenceMeasurementInformationItem-ExtIEs NBAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+UnsuccessfullNeighbouringCellSFNSFNObservedTimeDifferenceMeasurementInformationItem-ExtIEs NBAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+SFNSFNQuality ::= INTEGER (0..255)
+-- Unit chip, Step 1/16 chip, Range 0.. 255/16 chip
+
+ShutdownTimer ::= INTEGER (1..3600)
+-- Unit sec
+
+SIB-Originator ::= ENUMERATED {
+ nodeB,
+ cRNC,
+ ...
+}
+
+SIR-Error-Value ::= INTEGER (0..125)
+-- According to mapping in [22]
+
+SFNSFNTimeStampInformation ::= CHOICE {
+ sFNSFNTimeStamp-FDD SFN,
+ sFNSFNTimeStamp-TDD SFNSFNTimeStamp-TDD,
+ ...}
+
+SFNSFNTimeStamp-TDD::= SEQUENCE {
+ sFN SFN,
+ timeSlot TimeSlot,
+ iE-Extensions ProtocolExtensionContainer { { SFNSFNTimeStamp-ExtIEs} } OPTIONAL,
+ ...
+}
+
+SFNSFNTimeStamp-ExtIEs NBAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+SFNSFNValue ::= CHOICE {
+ sFNSFN-FDD SFNSFN-FDD,
+ sFNSFN-TDD SFNSFN-TDD,
+ ...
+}
+
+SIR-Error-Value-IncrDecrThres ::= INTEGER (0..124)
+
+SIR-Value ::= INTEGER (0..63)
+-- According to mapping in [22]/[23]
+
+SIR-Value-IncrDecrThres ::= INTEGER (0..62)
+
+SignallingBearerRequestIndicator::= ENUMERATED {bearerRequested}
+
+SpecialBurstScheduling ::= INTEGER (1..256) -- Number of frames between special burst transmission during DTX
+
+SSDT-Cell-Identity ::= ENUMERATED {a, b, c, d, e, f, g, h}
+
+SSDT-CellID-Length ::= ENUMERATED {
+ short,
+ medium,
+ long
+}
+
+SSDT-Indication ::= ENUMERATED {
+ ssdt-active-in-the-UE,
+ ssdt-not-active-in-the-UE
+}
+
+Start-Of-Audit-Sequence-Indicator ::= ENUMERATED {
+ start-of-audit-sequence,
+ not-start-of-audit-sequence
+}
+
+STTD-Indicator ::= ENUMERATED {
+ active,
+ inactive,
+ ...
+}
+
+SSDT-SupportIndicator ::= ENUMERATED {
+ sSDT-Supported,
+ sSDT-not-supported
+}
+
+SyncCase ::= INTEGER (1..2,...)
+
+SYNCDlCodeId ::= INTEGER (1..32,...)
+
+SyncFrameNumber ::= INTEGER (1..10)
+
+SynchronisationReportCharacteristics ::= SEQUENCE {
+ synchronisationReportCharacteristicsType SynchronisationReportCharacteristicsType,
+ synchronisationReportCharactThreExc SynchronisationReportCharactThreExc OPTIONAL,
+ -- This IE shall be included if the synchronisationReportCharacteristicsType IE is set to "thresholdExceeding".
+ iE-Extensions ProtocolExtensionContainer { { SynchronisationReportCharacteristics-ExtIEs } } OPTIONAL,
+ ...
+}
+
+SynchronisationReportCharacteristics-ExtIEs NBAP-PROTOCOL-EXTENSION ::= {
+ { ID id-SyncDLCodeIdThreInfoLCR CRITICALITY ignore EXTENSION SyncDLCodeIdThreInfoLCR PRESENCE optional },
+ ...
+}
+
+SynchronisationReportCharactThreExc ::= SEQUENCE (SIZE (1..maxNrOfCellSyncBursts)) OF SynchronisationReportCharactThreInfoItem -- Mandatory for 3.84Mcps TDD only. Not Applicable to 1.28Mcps TDD.
+
+SynchronisationReportCharactThreInfoItem ::= SEQUENCE {
+ syncFrameNumber SyncFrameNumber,
+ cellSyncBurstInformation SEQUENCE (SIZE (1.. maxNrOfReceptsPerSyncFrame)) OF SynchronisationReportCharactCellSyncBurstInfoItem,
+ iE-Extensions ProtocolExtensionContainer { { SynchronisationReportCharactThreInfoItem-ExtIEs } } OPTIONAL,
+ ...
+}
+
+SynchronisationReportCharactThreInfoItem-ExtIEs NBAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+SynchronisationReportCharactCellSyncBurstInfoItem ::= SEQUENCE {
+ cellSyncBurstCode CellSyncBurstCode,
+ cellSyncBurstCodeShift CellSyncBurstCodeShift,
+ cellSyncBurstTiming CellSyncBurstTiming OPTIONAL,
+ cellSyncBurstTimingThreshold CellSyncBurstTimingThreshold OPTIONAL,
+ iE-Extensions ProtocolExtensionContainer { { SynchronisationReportCharactCellSyncBurstInfoItem-ExtIEs } } OPTIONAL,
+ ...
+}
+
+SynchronisationReportCharactCellSyncBurstInfoItem-ExtIEs NBAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+SyncDLCodeIdThreInfoLCR ::= SEQUENCE (SIZE (0..maxNrOfSyncFramesLCR)) OF SyncDLCodeIdThreInfoList --Mandatory for 1.28Mcps TDD only. Not Applicable to 3.84Mcps TDD.
+
+SyncDLCodeIdThreInfoList ::= SEQUENCE {
+ syncFrameNoToReceive SyncFrameNumber,
+ syncDLCodeIdInfoLCR SyncDLCodeInfoListLCR,
+ iE-Extensions ProtocolExtensionContainer { { SyncDLCodeIdThreInfoList-ExtIEs } } OPTIONAL,
+ ...
+}
+
+SyncDLCodeIdThreInfoList-ExtIEs NBAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+SyncDLCodeInfoListLCR ::= SEQUENCE (SIZE (1..maxNrOfSyncDLCodesLCR)) OF SyncDLCodeInfoItemLCR
+
+SyncDLCodeInfoItemLCR ::= SEQUENCE {
+ syncDLCodeId SYNCDlCodeId,
+ syncDLCodeIdArrivTime CellSyncBurstTimingLCR OPTIONAL,
+ syncDLCodeIdTimingThre CellSyncBurstTimingThreshold OPTIONAL,
+ iE-Extensions ProtocolExtensionContainer { { SyncDLCodeInfoItem-LCR-ExtIEs } } OPTIONAL,
+ ...
+}
+
+SyncDLCodeInfoItem-LCR-ExtIEs NBAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+SynchronisationReportCharacteristicsType ::= ENUMERATED {
+ frameRelated,
+ sFNperiodRelated,
+ cycleLengthRelated,
+ thresholdExceeding,
+ frequencyAcquisitionCompleted,
+ ...
+}
+
+SynchronisationReportType ::= ENUMERATED {
+ initialPhase,
+ steadyStatePhase,
+ lateEntrantCell,
+ frequencyAcquisition,
+ ...
+}
+
+-- ==========================================
+-- T
+-- ==========================================
+
+T1 ::= ENUMERATED {v10,v20,v30,v40,v50,v60,v70,v80,v90,v100,v120,v140,v160,v200,v300,v400,...}
+
+T-Cell ::= ENUMERATED {
+ v0,
+ v1,
+ v2,
+ v3,
+ v4,
+ v5,
+ v6,
+ v7,
+ v8,
+ v9
+}
+
+T-RLFAILURE ::= INTEGER (0..255)
+-- Unit seconds, Range 0s .. 25.5s, Step 0.1s
+
+TDD-AckNack-Power-Offset ::= INTEGER (-7..8,...)
+-- Unit dB, Range -7dB .. +8dB, Step 1dB
+
+TDD-ChannelisationCode ::= ENUMERATED {
+ chCode1div1,
+ chCode2div1,
+ chCode2div2,
+ chCode4div1,
+ chCode4div2,
+ chCode4div3,
+ chCode4div4,
+ chCode8div1,
+ chCode8div2,
+ chCode8div3,
+ chCode8div4,
+ chCode8div5,
+ chCode8div6,
+ chCode8div7,
+ chCode8div8,
+ chCode16div1,
+ chCode16div2,
+ chCode16div3,
+ chCode16div4,
+ chCode16div5,
+ chCode16div6,
+ chCode16div7,
+ chCode16div8,
+ chCode16div9,
+ chCode16div10,
+ chCode16div11,
+ chCode16div12,
+ chCode16div13,
+ chCode16div14,
+ chCode16div15,
+ chCode16div16,
+ ...
+}
+
+TDD-ChannelisationCodeLCR ::= SEQUENCE {
+ tDD-ChannelisationCode TDD-ChannelisationCode,
+ modulation Modulation, -- Modulation options for 1.28Mcps TDD in contrast to 3.84Mcps TDD
+ iE-Extensions ProtocolExtensionContainer { { TDD-ChannelisationCodeLCR-ExtIEs} } OPTIONAL,
+ ...
+}
+
+TDD-ChannelisationCodeLCR-ExtIEs NBAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+TDD-DL-Code-Information ::= SEQUENCE (SIZE (1..maxNrOfDPCHs)) OF TDD-DL-Code-InformationItem
+
+TDD-DL-Code-InformationItem ::= SEQUENCE {
+ dPCH-ID DPCH-ID,
+ tdd-ChannelisationCode TDD-ChannelisationCode,
+ iE-Extensions ProtocolExtensionContainer { { TDD-DL-Code-InformationItem-ExtIEs} } OPTIONAL,
+ ...
+}
+
+TDD-DL-Code-InformationItem-ExtIEs NBAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+TDD-DL-Code-LCR-Information ::= SEQUENCE (SIZE (1..maxNrOfDPCHLCRs)) OF TDD-DL-Code-LCR-InformationItem
+
+TDD-DL-Code-LCR-InformationItem ::= SEQUENCE {
+ dPCH-ID DPCH-ID,
+ tdd-ChannelisationCodeLCR TDD-ChannelisationCodeLCR,
+ tdd-DL-DPCH-TimeSlotFormat-LCR TDD-DL-DPCH-TimeSlotFormat-LCR,
+ iE-Extensions ProtocolExtensionContainer { { TDD-DL-Code-LCR-InformationItem-ExtIEs} } OPTIONAL,
+ ...
+}
+
+TDD-DL-Code-LCR-InformationItem-ExtIEs NBAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+TDD-DL-DPCH-TimeSlotFormat-LCR ::= CHOICE {
+ qPSK QPSK-DL-DPCH-TimeSlotFormatTDD-LCR,
+ eightPSK EightPSK-DL-DPCH-TimeSlotFormatTDD-LCR,
+ ...
+}
+
+QPSK-DL-DPCH-TimeSlotFormatTDD-LCR ::= INTEGER(0..24,...)
+
+EightPSK-DL-DPCH-TimeSlotFormatTDD-LCR ::= INTEGER(0..24,...)
+
+TDD-DPCHOffset ::= CHOICE {
+ initialOffset INTEGER (0..255),
+ noinitialOffset INTEGER (0..63)
+}
+
+TDD-PhysicalChannelOffset ::= INTEGER (0..63)
+
+TDD-TPC-DownlinkStepSize ::= ENUMERATED {
+ step-size1,
+ step-size2,
+ step-size3,
+ ...
+}
+
+TDD-TPC-UplinkStepSize-LCR ::= ENUMERATED {
+ step-size1,
+ step-size2,
+ step-size3,
+ ...
+}
+
+TransportFormatCombination-Beta ::= CHOICE {
+ signalledGainFactors SEQUENCE {
+ gainFactor CHOICE {
+ fdd SEQUENCE {
+ betaC BetaCD,
+ betaD BetaCD,
+ iE-Extensions ProtocolExtensionContainer { { GainFactorFDD-ExtIEs } } OPTIONAL,
+ ...
+ },
+ tdd BetaCD,
+ ...
+ },
+ refTFCNumber RefTFCNumber OPTIONAL,
+ iE-Extensions ProtocolExtensionContainer { { SignalledGainFactors-ExtIEs } } OPTIONAL,
+ ...
+ },
+ computedGainFactors RefTFCNumber,
+ ...
+}
+
+GainFactorFDD-ExtIEs NBAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+SignalledGainFactors-ExtIEs NBAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+TDD-UL-Code-Information ::= SEQUENCE (SIZE (1..maxNrOfDPCHs)) OF TDD-UL-Code-InformationItem
+
+TDD-UL-Code-InformationItem ::= SEQUENCE {
+ dPCH-ID DPCH-ID,
+ tdd-ChannelisationCode TDD-ChannelisationCode,
+ iE-Extensions ProtocolExtensionContainer { { TDD-UL-Code-InformationItem-ExtIEs} } OPTIONAL,
+ ...
+}
+
+TDD-UL-Code-InformationItem-ExtIEs NBAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+TDD-UL-Code-LCR-Information ::= SEQUENCE (SIZE (1..maxNrOfDPCHLCRs)) OF TDD-UL-Code-LCR-InformationItem
+
+TDD-UL-Code-LCR-InformationItem ::= SEQUENCE {
+ dPCH-ID DPCH-ID,
+ tdd-ChannelisationCodeLCR TDD-ChannelisationCodeLCR,
+ tdd-UL-DPCH-TimeSlotFormat-LCR TDD-UL-DPCH-TimeSlotFormat-LCR,
+ iE-Extensions ProtocolExtensionContainer { { TDD-UL-Code-LCR-InformationItem-ExtIEs} } OPTIONAL,
+ ...
+}
+
+TDD-UL-Code-LCR-InformationItem-ExtIEs NBAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+TDD-UL-DPCH-TimeSlotFormat-LCR ::= CHOICE {
+ qPSK QPSK-UL-DPCH-TimeSlotFormatTDD-LCR,
+ eightPSK EightPSK-UL-DPCH-TimeSlotFormatTDD-LCR,
+ ...
+}
+
+QPSK-UL-DPCH-TimeSlotFormatTDD-LCR ::= INTEGER(0..69,...)
+
+EightPSK-UL-DPCH-TimeSlotFormatTDD-LCR ::= INTEGER(0..24,...)
+
+TFCI-Coding ::= ENUMERATED {
+ v4,
+ v8,
+ v16,
+ v32,
+ ...
+}
+
+TFCI-Presence ::= ENUMERATED {
+ present,
+ not-present
+}
+
+TFCI-SignallingMode ::= SEQUENCE {
+ tFCI-SignallingOption TFCI-SignallingMode-TFCI-SignallingOption,
+ splitType TFCI-SignallingMode-SplitType OPTIONAL,
+ -- This IE shall be present if the TFCI signalling option is set to "split" --
+ lengthOfTFCI2 TFCI-SignallingMode-LengthOfTFCI2 OPTIONAL,
+ iE-Extensions ProtocolExtensionContainer { { TFCI-SignallingMode-ExtIEs} } OPTIONAL,
+ ...
+}
+
+TFCI-SignallingMode-ExtIEs NBAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+TFCI-SignallingMode-LengthOfTFCI2 ::= INTEGER (1..10)
+
+TFCI-SignallingMode-SplitType ::= ENUMERATED {
+ hard,
+ logical
+}
+
+TFCI-SignallingMode-TFCI-SignallingOption ::= ENUMERATED {
+ normal,
+ split
+}
+
+TFCI2-BearerInformationResponse ::= SEQUENCE {
+ bindingID BindingID,
+ transportLayerAddress TransportLayerAddress,
+ iE-Extensions ProtocolExtensionContainer { { TFCI2-BearerInformationResponse-ExtIEs} } OPTIONAL,
+ ...
+}
+
+TFCI2-BearerInformationResponse-ExtIEs NBAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+TFCI2BearerRequestIndicator ::= ENUMERATED {newBearerRequested}
+
+TGD ::= INTEGER (0|15..269)
+-- 0 = Undefined, only one transmission gap in the transmission gap pattern sequence
+
+TGPRC ::= INTEGER (0..511)
+-- 0 = infinity
+
+TGPSID ::= INTEGER (1.. maxTGPS)
+
+TGSN ::= INTEGER (0..14)
+
+TimeSlot ::= INTEGER (0..14)
+
+TimeSlotDirection ::= ENUMERATED {
+ ul,
+ dl,
+ ...
+}
+
+TimeSlotLCR ::= INTEGER (0..6)
+
+TimeSlotStatus ::= ENUMERATED {
+ active,
+ not-active,
+ ...
+}
+
+TimingAdjustmentValue ::= CHOICE {
+ initialPhase INTEGER (0..1048575,...),
+ steadyStatePhase INTEGER (0..255,...)
+}
+
+TimingAdjustmentValueLCR ::= CHOICE {
+ initialPhase INTEGER (0..524287,...),
+ steadyStatePhase INTEGER (0..127,...)
+}
+
+TimingAdvanceApplied ::= ENUMERATED {
+ yes,
+ no
+}
+
+TnlQos ::= CHOICE {
+ dsField DsField,
+ genericTrafficCategory GenericTrafficCategory,
+ ...
+}
+
+ToAWE ::= INTEGER (0..2559)
+-- Unit ms
+
+ToAWS ::= INTEGER (0..1279)
+-- Unit ms
+
+Transmission-Gap-Pattern-Sequence-Information ::= SEQUENCE (SIZE (1..maxTGPS)) OF
+ SEQUENCE {
+ tGPSID TGPSID,
+ tGSN TGSN,
+ tGL1 GapLength,
+ tGL2 GapLength OPTIONAL,
+ tGD TGD,
+ tGPL1 GapDuration,
+ tGPL2 GapDuration OPTIONAL,
+ uL-DL-mode UL-DL-mode,
+ downlink-Compressed-Mode-Method Downlink-Compressed-Mode-Method OPTIONAL,
+ -- This IE shall be present if the UL/DL mode IE is set to "DL only" or "UL/DL"
+ uplink-Compressed-Mode-Method Uplink-Compressed-Mode-Method OPTIONAL,
+ -- This IE shall be present if the UL/DL mode IE is set to "UL only" or "UL/DL"
+ dL-FrameType DL-FrameType,
+ delta-SIR1 DeltaSIR,
+ delta-SIR-after1 DeltaSIR,
+ delta-SIR2 DeltaSIR OPTIONAL,
+ delta-SIR-after2 DeltaSIR OPTIONAL,
+ iE-Extensions ProtocolExtensionContainer { {Transmission-Gap-Pattern-Sequence-Information-ExtIEs} } OPTIONAL,
+ ...
+ }
+
+Transmission-Gap-Pattern-Sequence-Information-ExtIEs NBAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+TransmissionGapPatternSequenceCodeInformation ::= ENUMERATED{
+code-change,
+nocode-change
+}
+
+TransmittedCarrierPowerOfAllCodesNotUsedForHS-PDSCHOrHS-SCCHTransmissionValue ::= INTEGER(0..100)
+-- According to mapping in [22] and [23]
+
+Transmitted-Carrier-Power-Value ::= INTEGER(0..100)
+-- According to mapping in [22]/[23]
+
+Transmitted-Code-Power-Value ::= INTEGER (0..127)
+-- According to mapping in [22]/[23]. Values 0 to 9 and 123 to 127 shall not be used.
+
+Transmitted-Code-Power-Value-IncrDecrThres ::= INTEGER (0..112,...)
+
+TransmissionDiversityApplied ::= BOOLEAN
+-- true: applied, false: not applied
+
+TransmitDiversityIndicator ::= ENUMERATED {
+ active,
+ inactive
+}
+
+TFCS ::= SEQUENCE {
+ tFCSvalues CHOICE {
+ no-Split-in-TFCI TFCS-TFCSList,
+ split-in-TFCI SEQUENCE {
+ transportFormatCombination-DCH TFCS-DCHList,
+ signallingMethod CHOICE {
+ tFCI-Range TFCS-MapingOnDSCHList,
+ explicit TFCS-DSCHList,
+ ...
+ },
+ iE-Extensions ProtocolExtensionContainer { { Split-in-TFCI-ExtIEs } } OPTIONAL,
+ ...
+ },
+ ...
+ },
+ iE-Extensions ProtocolExtensionContainer { { TFCS-ExtIEs} } OPTIONAL,
+ ...
+}
+
+Split-in-TFCI-ExtIEs NBAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+TFCS-ExtIEs NBAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+TFCS-TFCSList ::= SEQUENCE (SIZE (1..maxNrOfTFCs)) OF
+ SEQUENCE {
+ cTFC TFCS-CTFC,
+ tFC-Beta TransportFormatCombination-Beta OPTIONAL,
+ -- The IE shall be present if the TFCS concerns a UL DPCH or PRACH channel [FDD - or PCPCH channel].
+ iE-Extensions ProtocolExtensionContainer { { TFCS-TFCSList-ExtIEs} } OPTIONAL,
+ ...
+}
+
+TFCS-TFCSList-ExtIEs NBAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+TFCS-CTFC ::= CHOICE {
+ ctfc2bit INTEGER (0..3),
+ ctfc4bit INTEGER (0..15),
+ ctfc6bit INTEGER (0..63),
+ ctfc8bit INTEGER (0..255),
+ ctfc12bit INTEGER (0..4095),
+ ctfc16bit INTEGER (0..65535),
+ ctfcmaxbit INTEGER (0..maxCTFC)
+}
+
+TFCS-DCHList ::= SEQUENCE (SIZE (1..maxNrOfTFCI1Combs)) OF
+ SEQUENCE {
+ cTFC TFCS-CTFC,
+ iE-Extensions ProtocolExtensionContainer { { TFCS-DCHList-ExtIEs} } OPTIONAL,
+ ...
+}
+
+TFCS-DCHList-ExtIEs NBAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+TFCS-MapingOnDSCHList ::= SEQUENCE (SIZE (1..maxNrOfTFCIGroups)) OF
+ SEQUENCE {
+ maxTFCI-field2-Value TFCS-MaxTFCI-field2-Value,
+ cTFC-DSCH TFCS-CTFC,
+ iE-Extensions ProtocolExtensionContainer { { TFCS-MapingOnDSCHList-ExtIEs} } OPTIONAL,
+ ...
+}
+
+TFCS-MapingOnDSCHList-ExtIEs NBAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+TFCS-MaxTFCI-field2-Value ::= INTEGER (1..maxNrOfTFCI2Combs-1)
+
+TFCS-DSCHList ::= SEQUENCE (SIZE (1..maxNrOfTFCI2Combs)) OF
+ SEQUENCE {
+ cTFC-DSCH TFCS-CTFC,
+ iE-Extensions ProtocolExtensionContainer { { TFCS-DSCHList-ExtIEs} } OPTIONAL,
+ ...
+}
+
+TFCS-DSCHList-ExtIEs NBAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+TransportBearerRequestIndicator ::= ENUMERATED {
+ bearerRequested,
+ bearerNotRequested,
+ ...
+}
+
+TransportFormatSet ::= SEQUENCE {
+ dynamicParts TransportFormatSet-DynamicPartList,
+ semi-staticPart TransportFormatSet-Semi-staticPart,
+ iE-Extensions ProtocolExtensionContainer { { TransportFormatSet-ExtIEs} } OPTIONAL,
+ ...
+}
+
+TransportFormatSet-ExtIEs NBAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+TransportFormatSet-DynamicPartList ::= SEQUENCE (SIZE (1..maxNrOfTFs)) OF
+ SEQUENCE {
+ nrOfTransportBlocks TransportFormatSet-NrOfTransportBlocks,
+ transportBlockSize TransportFormatSet-TransportBlockSize OPTIONAL,
+ -- This IE shall be present if the Number of Transport Blocks IE is set to a value greater than 0
+ mode TransportFormatSet-ModeDP,
+ iE-Extensions ProtocolExtensionContainer { { TransportFormatSet-DynamicPartList-ExtIEs} } OPTIONAL,
+ ...
+ }
+
+TransportFormatSet-DynamicPartList-ExtIEs NBAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+TDD-TransportFormatSet-ModeDP ::= SEQUENCE {
+ transmissionTimeIntervalInformation TransmissionTimeIntervalInformation OPTIONAL,
+ -- This IE shall be present if the Transmission Time Interval IE in the Semi-static Transport Format Information IE is set to "dynamic"
+ iE-Extensions ProtocolExtensionContainer { {TDD-TransportFormatSet-ModeDP-ExtIEs} } OPTIONAL,
+ ...
+ }
+
+TDD-TransportFormatSet-ModeDP-ExtIEs NBAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+TransmissionTimeIntervalInformation ::= SEQUENCE (SIZE (1..maxTTI-count)) OF
+ SEQUENCE {
+ transmissionTimeInterval TransportFormatSet-TransmissionTimeIntervalDynamic,
+ iE-Extensions ProtocolExtensionContainer { { TransmissionTimeIntervalInformation-ExtIEs} } OPTIONAL,
+ ...
+}
+
+TransmissionTimeIntervalInformation-ExtIEs NBAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+TransportFormatSet-Semi-staticPart ::= SEQUENCE {
+ transmissionTimeInterval TransportFormatSet-TransmissionTimeIntervalSemiStatic,
+ channelCoding TransportFormatSet-ChannelCodingType,
+ codingRate TransportFormatSet-CodingRate OPTIONAL,
+ -- This IE shall be present if the Type of channel coding IE is set to 'convolutional' or 'turbo'
+ rateMatchingAttribute TransportFormatSet-RateMatchingAttribute,
+ cRC-Size TransportFormatSet-CRC-Size,
+ mode TransportFormatSet-ModeSSP ,
+ iE-Extensions ProtocolExtensionContainer { { TransportFormatSet-Semi-staticPart-ExtIEs} } OPTIONAL,
+ ...
+}
+
+TransportFormatSet-Semi-staticPart-ExtIEs NBAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+TransportFormatSet-ChannelCodingType ::= ENUMERATED {
+ no-codingTDD,
+ convolutional-coding,
+ turbo-coding,
+ ...
+}
+
+TransportFormatSet-CodingRate ::= ENUMERATED {
+ half,
+ third,
+ ...
+}
+
+TransportFormatSet-CRC-Size ::= ENUMERATED {
+ v0,
+ v8,
+ v12,
+ v16,
+ v24,
+ ...
+}
+
+TransportFormatSet-ModeDP ::= CHOICE {
+ tdd TDD-TransportFormatSet-ModeDP,
+ notApplicable NULL,
+ ...
+}
+
+TransportFormatSet-ModeSSP ::= CHOICE {
+ tdd TransportFormatSet-SecondInterleavingMode,
+ notApplicable NULL,
+ ...
+}
+
+TransportFormatSet-NrOfTransportBlocks ::= INTEGER (0..512)
+
+TransportFormatSet-RateMatchingAttribute ::= INTEGER (1..maxRateMatching)
+
+TransportFormatSet-SecondInterleavingMode ::= ENUMERATED {
+ frame-related,
+ timeSlot-related,
+ ...
+}
+
+TransportFormatSet-TransmissionTimeIntervalDynamic ::= ENUMERATED {
+ msec-10,
+ msec-20,
+ msec-40,
+ msec-80,
+ ...
+}
+
+TransportFormatSet-TransmissionTimeIntervalSemiStatic ::= ENUMERATED {
+ msec-10,
+ msec-20,
+ msec-40,
+ msec-80,
+ dynamic,
+ ...,
+ msec-5
+}
+
+TransportFormatSet-TransportBlockSize ::= INTEGER (0..5000)
+
+TransportLayerAddress ::= BIT STRING (SIZE (1..160, ...))
+
+TSTD-Indicator ::= ENUMERATED {
+ active,
+ inactive
+}
+
+TUTRANGPS ::= SEQUENCE {
+ ms-part INTEGER (0..16383),
+ ls-part INTEGER (0..4294967295)
+}
+
+TUTRANGPSChangeLimit ::= INTEGER (1..256)
+-- Unit chip, Step 1/16 chip, Range 1/16..16 chip
+
+TUTRANGPSDriftRate ::= INTEGER (-50..50)
+-- Unit chip/s, Step 1/256 chip/s, Range -50/256..+50/256 chip/s
+
+TUTRANGPSDriftRateQuality ::= INTEGER (0..50)
+-- Unit chip/s, Step 1/256 chip/s, Range 0..50/256 chip/s
+
+TUTRANGPSAccuracyClass ::= ENUMERATED {
+ accuracy-class-A,
+ accuracy-class-B,
+ accuracy-class-C,
+ ...
+}
+
+TUTRANGPSMeasurementThresholdInformation ::= SEQUENCE {
+ tUTRANGPSChangeLimit TUTRANGPSChangeLimit OPTIONAL,
+ predictedTUTRANGPSDeviationLimit PredictedTUTRANGPSDeviationLimit OPTIONAL,
+ iE-Extensions ProtocolExtensionContainer { { TUTRANGPSMeasurementThresholdInformation-ExtIEs} } OPTIONAL,
+ ...
+}
+
+TUTRANGPSMeasurementThresholdInformation-ExtIEs NBAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+TUTRANGPSMeasurementValueInformation ::= SEQUENCE {
+ tUTRANGPS TUTRANGPS,
+ tUTRANGPSQuality TUTRANGPSQuality OPTIONAL,
+ tUTRANGPSDriftRate TUTRANGPSDriftRate,
+ tUTRANGPSDriftRateQuality TUTRANGPSDriftRateQuality OPTIONAL,
+ iE-Extensions ProtocolExtensionContainer { {TUTRANGPSMeasurementValueInformationItem-ExtIEs} } OPTIONAL,
+ ...
+}
+
+TUTRANGPSMeasurementValueInformationItem-ExtIEs NBAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+TUTRANGPSQuality ::= INTEGER (0..255)
+-- Unit chip, Step 1/16 chip, Range 0.. 255/16 chip
+
+TypeOfError ::= ENUMERATED {
+ not-understood,
+ missing,
+ ...
+}
+
+-- ==========================================
+-- U
+-- ==========================================
+
+UARFCN ::= INTEGER (0..16383, ...)
+-- corresponds to 0MHz .. 3276.6MHz
+
+UC-Id ::= SEQUENCE {
+ rNC-ID RNC-ID,
+ c-ID C-ID,
+ iE-Extensions ProtocolExtensionContainer { {UC-Id-ExtIEs} } OPTIONAL,
+ ...
+}
+UC-Id-ExtIEs NBAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+UDRE ::= ENUMERATED {
+ udre-minusequal-one-m,
+ udre-betweenoneandfour-m,
+ udre-betweenfourandeight-m,
+ udre-greaterequaleight-m
+}
+
+
+UE-Capability-Information ::= SEQUENCE {
+ hSDSCH-Physical-Layer-Category INTEGER (1..64,...),
+ iE-Extensions ProtocolExtensionContainer { { UE-Capability-Information-ExtIEs } } OPTIONAL,
+ ...
+}
+
+UE-Capability-Information-ExtIEs NBAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+UL-CapacityCredit ::= INTEGER (0..65535)
+
+UL-DL-mode ::= ENUMERATED {
+ ul-only,
+ dl-only,
+ both-ul-and-dl
+}
+
+Uplink-Compressed-Mode-Method ::= ENUMERATED {
+ sFdiv2,
+ higher-layer-scheduling,
+ ...
+}
+
+UL-Timeslot-Information ::= SEQUENCE (SIZE (1..maxNrOfULTSs)) OF UL-Timeslot-InformationItem
+
+UL-Timeslot-InformationItem ::= SEQUENCE {
+ timeSlot TimeSlot,
+ midambleShiftAndBurstType MidambleShiftAndBurstType,
+ tFCI-Presence TFCI-Presence,
+ uL-Code-InformationList TDD-UL-Code-Information,
+ iE-Extensions ProtocolExtensionContainer { { UL-Timeslot-InformationItem-ExtIEs} } OPTIONAL,
+ ...
+}
+
+UL-Timeslot-InformationItem-ExtIEs NBAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+UL-TimeslotLCR-Information ::= SEQUENCE (SIZE (1..maxNrOfULTSLCRs)) OF UL-TimeslotLCR-InformationItem
+
+UL-TimeslotLCR-InformationItem ::= SEQUENCE {
+ timeSlotLCR TimeSlotLCR,
+ midambleShiftLCR MidambleShiftLCR,
+ tFCI-Presence TFCI-Presence,
+ uL-Code-InformationList TDD-UL-Code-LCR-Information,
+ iE-Extensions ProtocolExtensionContainer { { UL-TimeslotLCR-InformationItem-ExtIEs} } OPTIONAL,
+ ...
+}
+
+UL-TimeslotLCR-InformationItem-ExtIEs NBAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+UL-DPCCH-SlotFormat ::= INTEGER (0..5,...)
+
+UL-SIR ::= INTEGER (-82..173)
+-- According to mapping in [16]
+
+UL-FP-Mode ::= ENUMERATED {
+ normal,
+ silent,
+ ...
+}
+
+UL-PhysCH-SF-Variation ::= ENUMERATED {
+ sf-variation-supported,
+ sf-variation-not-supported
+}
+
+UL-ScramblingCode ::= SEQUENCE {
+ uL-ScramblingCodeNumber UL-ScramblingCodeNumber,
+ uL-ScramblingCodeLength UL-ScramblingCodeLength,
+ iE-Extensions ProtocolExtensionContainer { { UL-ScramblingCode-ExtIEs } } OPTIONAL,
+ ...
+}
+
+UL-ScramblingCode-ExtIEs NBAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+UL-ScramblingCodeNumber ::= INTEGER (0..16777215)
+
+UL-ScramblingCodeLength ::= ENUMERATED {
+ short,
+ long
+}
+
+UL-Synchronisation-Parameters-LCR ::= SEQUENCE {
+ uL-Synchronisation-StepSize UL-Synchronisation-StepSize,
+ uL-Synchronisation-Frequency UL-Synchronisation-Frequency,
+ iE-Extensions ProtocolExtensionContainer { { UL-Synchronisation-Parameters-LCR-ExtIEs } } OPTIONAL,
+ ...
+}
+
+UL-Synchronisation-Parameters-LCR-ExtIEs NBAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+UL-Synchronisation-StepSize ::= INTEGER (1..8)
+
+UL-Synchronisation-Frequency ::= INTEGER (1..8)
+
+UL-TimeSlot-ISCP-Info ::= SEQUENCE (SIZE (1..maxNrOfULTSs)) OF UL-TimeSlot-ISCP-InfoItem
+
+UL-TimeSlot-ISCP-InfoItem ::= SEQUENCE {
+ timeSlot TimeSlot,
+ iSCP UL-TimeslotISCP-Value,
+ iE-Extensions ProtocolExtensionContainer { { UL-TimeSlot-ISCP-InfoItem-ExtIEs} } OPTIONAL,
+ ...
+ }
+
+UL-TimeSlot-ISCP-InfoItem-ExtIEs NBAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+UL-TimeSlot-ISCP-LCR-Info ::= SEQUENCE (SIZE (1..maxNrOfULTSLCRs)) OF UL-TimeSlot-ISCP-LCR-InfoItem
+
+UL-TimeSlot-ISCP-LCR-InfoItem ::= SEQUENCE {
+ timeSlotLCR TimeSlotLCR,
+ iSCP UL-TimeslotISCP-Value,
+ iE-Extensions ProtocolExtensionContainer { { UL-TimeSlot-ISCP-LCR-InfoItem-ExtIEs} } OPTIONAL,
+ ...
+ }
+
+UL-TimeSlot-ISCP-LCR-InfoItem-ExtIEs NBAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+Unidirectional-DCH-Indicator ::= ENUMERATED {
+ downlink-DCH-only,
+ uplink-DCH-only
+}
+
+USCH-Information ::= SEQUENCE (SIZE (1..maxNrOfUSCHs)) OF USCH-InformationItem
+
+USCH-InformationItem ::= SEQUENCE {
+ uSCH-ID USCH-ID,
+ cCTrCH-ID CCTrCH-ID, -- UL CCTrCH in which the USCH is mapped
+ transportFormatSet TransportFormatSet, -- For USCH
+ allocationRetentionPriority AllocationRetentionPriority,
+ iE-Extensions ProtocolExtensionContainer { { USCH-InformationItem-ExtIEs} } OPTIONAL,
+ ...
+}
+
+USCH-InformationItem-ExtIEs NBAP-PROTOCOL-EXTENSION ::= {
+ { ID id-bindingID CRITICALITY ignore EXTENSION BindingID PRESENCE optional }|
+ -- Shall be ignored if bearer establishment with ALCAP.
+ { ID id-transportlayeraddress CRITICALITY ignore EXTENSION TransportLayerAddress PRESENCE optional }|
+ -- Shall be ignored if bearer establishment with ALCAP.
+{ ID id-TnlQos CRITICALITY ignore EXTENSION TnlQos PRESENCE optional },
+ ...
+}
+
+USCH-InformationResponse ::= SEQUENCE (SIZE (1..maxNrOfUSCHs)) OF USCH-InformationResponseItem
+
+USCH-InformationResponseItem ::= SEQUENCE {
+ uSCH-ID USCH-ID,
+ bindingID BindingID OPTIONAL,
+ transportLayerAddress TransportLayerAddress OPTIONAL,
+ iE-Extensions ProtocolExtensionContainer { { USCH-InformationResponseItem-ExtIEs} } OPTIONAL,
+ ...
+}
+
+USCH-InformationResponseItem-ExtIEs NBAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+UL-TimeslotISCP-Value ::= INTEGER (0..127)
+-- According to mapping in [23]
+
+UL-TimeslotISCP-Value-IncrDecrThres ::= INTEGER (0..126)
+
+USCH-ID ::= INTEGER (0..255)
+
+-- ==========================================
+-- V
+-- ==========================================
+
+-- ==========================================
+-- W
+-- ==========================================
+
+-- ==========================================
+-- X
+-- ==========================================
+
+-- ==========================================
+-- Y
+-- ==========================================
+
+-- ==========================================
+-- Z
+-- ==========================================
+
+END
diff --git a/lib/asn1/test/asn1_SUITE_data/nbapsystem/NBAP-PDU-Contents.asn b/lib/asn1/test/asn1_SUITE_data/nbapsystem/NBAP-PDU-Contents.asn
new file mode 100755
index 0000000000..9ecfa688a2
--- /dev/null
+++ b/lib/asn1/test/asn1_SUITE_data/nbapsystem/NBAP-PDU-Contents.asn
@@ -0,0 +1,9234 @@
+-- **************************************************************
+--
+-- PDU definitions for NBAP.
+--
+-- **************************************************************
+
+NBAP-PDU-Contents {
+itu-t (0) identified-organization (4) etsi (0) mobileDomain (0)
+umts-Access (20) modules (3) nbap (2) version1 (1) nbap-PDU-Contents (1) }
+
+DEFINITIONS AUTOMATIC TAGS ::=
+
+BEGIN
+
+-- **************************************************************
+--
+-- IE parameter types from other modules.
+--
+-- **************************************************************
+
+IMPORTS
+ Active-Pattern-Sequence-Information,
+ AddorDeleteIndicator,
+ AICH-Power,
+ AICH-TransmissionTiming,
+ AllocationRetentionPriority,
+ APPreambleSignature,
+ APSubChannelNumber,
+ AvailabilityStatus,
+ BCCH-ModificationTime,
+ BindingID,
+ BlockingPriorityIndicator,
+ SCTD-Indicator,
+ Cause,
+ CCTrCH-ID,
+ CDSubChannelNumbers,
+ CellParameterID,
+ CellSyncBurstCode,
+ CellSyncBurstCodeShift,
+ CellSyncBurstRepetitionPeriod,
+ CellSyncBurstSIR,
+ CellSyncBurstTiming,
+ CellSyncBurstTimingThreshold,
+ CFN,
+ Channel-Assignment-Indication,
+ ChipOffset,
+ C-ID,
+ Closedlooptimingadjustmentmode,
+ CommonChannelsCapacityConsumptionLaw,
+ Compressed-Mode-Deactivation-Flag,
+ CommonMeasurementAccuracy,
+ CommonMeasurementType,
+ CommonMeasurementValue,
+ CommonMeasurementValueInformation,
+ CommonPhysicalChannelID,
+ Common-PhysicalChannel-Status-Information,
+ Common-TransportChannel-Status-Information,
+ CommonTransportChannelID,
+ CommonTransportChannel-InformationResponse,
+ CommunicationControlPortID,
+ ConfigurationGenerationID,
+ ConstantValue,
+ CriticalityDiagnostics,
+ CPCH-Allowed-Total-Rate,
+ CPCHScramblingCodeNumber,
+ CPCH-UL-DPCCH-SlotFormat,
+ CRNC-CommunicationContextID,
+ CSBMeasurementID,
+ CSBTransmissionID,
+ DCH-FDD-Information,
+ DCH-InformationResponse,
+ DCH-ID,
+ FDD-DCHs-to-Modify,
+ TDD-DCHs-to-Modify,
+ DCH-TDD-Information,
+ DedicatedChannelsCapacityConsumptionLaw,
+ DedicatedMeasurementType,
+ DedicatedMeasurementValue,
+ DedicatedMeasurementValueInformation,
+ DelayedActivation,
+ DelayedActivationUpdate,
+ DiversityControlField,
+ DiversityMode,
+ DL-DPCH-SlotFormat,
+ DL-DPCH-TimingAdjustment,
+ DL-or-Global-CapacityCredit,
+ DL-Power,
+ DL-PowerBalancing-Information,
+ DL-PowerBalancing-ActivationIndicator,
+ DLPowerAveragingWindowSize,
+ DL-PowerBalancing-UpdatedIndicator,
+ DL-ScramblingCode,
+ DL-TimeslotISCP,
+ DL-Timeslot-Information,
+ DL-TimeslotLCR-Information,
+ DL-TimeslotISCPInfo,
+ DL-TimeslotISCPInfoLCR,
+ DL-TPC-Pattern01Count,
+ DPC-Mode,
+ DPCH-ID,
+ DSCH-ID,
+ DSCH-FDD-Common-Information,
+ DSCH-FDD-Information,
+ DSCH-InformationResponse,
+ DSCH-TDD-Information,
+ DwPCH-Power,
+ End-Of-Audit-Sequence-Indicator,
+ EnhancedDSCHPC,
+ EnhancedDSCHPCCounter,
+ EnhancedDSCHPCIndicator,
+ EnhancedDSCHPCWnd,
+ EnhancedDSCHPowerOffset,
+ FDD-DL-ChannelisationCodeNumber,
+ FDD-DL-CodeInformation,
+ FDD-S-CCPCH-Offset,
+ FDD-TPC-DownlinkStepSize,
+ FirstRLS-Indicator,
+ FNReportingIndicator,
+ FPACH-Power,
+ FrameAdjustmentValue,
+ FrameHandlingPriority,
+ FrameOffset,
+ HSDPA-Capability,
+ HS-PDSCH-FDD-Code-Information,
+ HS-SCCH-ID,
+ HS-SCCH-FDD-Code-Information,
+ HS-SICH-ID,
+ IB-OC-ID,
+ IB-SG-DATA,
+ IB-SG-POS,
+ IB-SG-REP,
+ IB-Type,
+ InformationExchangeID,
+ InformationReportCharacteristics,
+ InformationType,
+ InnerLoopDLPCStatus,
+ IPDL-FDD-Parameters,
+ IPDL-TDD-Parameters,
+ IPDL-Indicator,
+ IPDL-TDD-Parameters-LCR,
+ LimitedPowerIncrease,
+ Local-Cell-ID,
+ MaximumDL-PowerCapability,
+ Maximum-PDSCH-Power,
+ MaximumTransmissionPower,
+ Max-Number-of-PCPCHes,
+ MaxNrOfUL-DPDCHs,
+ MaxPRACH-MidambleShifts,
+ MeasurementFilterCoefficient,
+ MeasurementID,
+ MidambleAllocationMode,
+ MidambleShiftAndBurstType,
+ MidambleShiftLCR,
+ MinimumDL-PowerCapability,
+ MinSpreadingFactor,
+ MinUL-ChannelisationCodeLength,
+ MultiplexingPosition,
+ NEOT,
+ NCyclesPerSFNperiod,
+ NFmax,
+ NRepetitionsPerCyclePeriod,
+ N-INSYNC-IND,
+ N-OUTSYNC-IND,
+ NeighbouringCellMeasurementInformation,
+ NeighbouringFDDCellMeasurementInformation,
+ NeighbouringTDDCellMeasurementInformation,
+ NodeB-CommunicationContextID,
+ NumberOfReportedCellPortions,
+ NStartMessage,
+ NSubCyclesPerCyclePeriod,
+ PagingIndicatorLength,
+ PayloadCRC-PresenceIndicator,
+ PCCPCH-Power,
+ PCP-Length,
+ PDSCH-CodeMapping,
+ PDSCHSet-ID,
+ PDSCH-ID,
+ PICH-Mode,
+ PICH-Power,
+ PowerAdjustmentType,
+ PowerOffset,
+ PowerRaiseLimit,
+ PRACH-Midamble,
+ PreambleSignatures,
+ PreambleThreshold,
+ PredictedSFNSFNDeviationLimit,
+ PredictedTUTRANGPSDeviationLimit,
+ PrimaryCPICH-Power,
+ Primary-CPICH-Usage-for-Channel-Estimation,
+ PrimaryScramblingCode,
+ PropagationDelay,
+ SCH-TimeSlot,
+ PunctureLimit,
+ PUSCHSet-ID,
+ PUSCH-ID,
+ QE-Selector,
+ Qth-Parameter,
+ RACH-SlotFormat,
+ RACH-SubChannelNumbers,
+ ReferenceClockAvailability,
+ ReferenceSFNoffset,
+ RepetitionLength,
+ RepetitionPeriod,
+ ReportCharacteristics,
+ RequestedDataValue,
+ RequestedDataValueInformation,
+ ResourceOperationalState,
+ RL-Set-ID,
+ RL-ID,
+ RL-Specific-DCH-Info,
+ Received-total-wide-band-power-Value,
+ AdjustmentPeriod,
+ ScaledAdjustmentRatio,
+ MaxAdjustmentStep,
+ RNC-ID,
+ ScramblingCodeNumber,
+ Secondary-CPICH-Information-Change,
+ SecondaryCCPCH-SlotFormat,
+ Segment-Type,
+ S-FieldLength,
+ SFN,
+ SFNSFNChangeLimit,
+ SFNSFNDriftRate,
+ SFNSFNDriftRateQuality,
+ SFNSFNQuality,
+ ShutdownTimer,
+ SIB-Originator,
+ SpecialBurstScheduling,
+ SignallingBearerRequestIndicator,
+ SSDT-Cell-Identity,
+ SSDT-CellID-Length,
+ SSDT-Indication,
+ Start-Of-Audit-Sequence-Indicator,
+ STTD-Indicator,
+ SSDT-SupportIndicator,
+ SyncCase,
+ SYNCDlCodeId,
+ SyncFrameNumber,
+ SynchronisationReportCharacteristics,
+ SynchronisationReportType,
+ T-Cell,
+ T-RLFAILURE,
+ TDD-ChannelisationCode,
+ TDD-ChannelisationCodeLCR,
+ TDD-DL-Code-LCR-Information,
+ TDD-DPCHOffset,
+ TDD-TPC-DownlinkStepSize,
+ TDD-PhysicalChannelOffset,
+ TDD-UL-Code-LCR-Information,
+ TFCI2-BearerInformationResponse,
+ TFCI2BearerRequestIndicator,
+ TFCI-Coding,
+ TFCI-Presence,
+ TFCI-SignallingMode,
+ TFCS,
+ TimeSlot,
+ TimeSlotLCR,
+ TimeSlotDirection,
+ TimeSlotStatus,
+ TimingAdjustmentValue,
+ TimingAdvanceApplied,
+ TnlQos,
+ ToAWE,
+ ToAWS,
+ TransmissionDiversityApplied,
+ TransmitDiversityIndicator,
+ TransmissionGapPatternSequenceCodeInformation,
+ Transmission-Gap-Pattern-Sequence-Information,
+ TransportBearerRequestIndicator,
+ TransportFormatSet,
+ TransportLayerAddress,
+ TSTD-Indicator,
+ TUTRANGPS,
+ TUTRANGPSChangeLimit,
+ TUTRANGPSDriftRate,
+ TUTRANGPSDriftRateQuality,
+ TUTRANGPSQuality,
+ UARFCN,
+ UC-Id,
+ USCH-Information,
+ USCH-InformationResponse,
+ UL-CapacityCredit,
+ UL-DPCCH-SlotFormat,
+ UL-SIR,
+ UL-FP-Mode,
+ UL-PhysCH-SF-Variation,
+ UL-ScramblingCode,
+ UL-Timeslot-Information,
+ UL-TimeslotLCR-Information,
+ UL-TimeSlot-ISCP-Info,
+ UL-TimeSlot-ISCP-LCR-Info,
+ UL-TimeslotISCP-Value,
+ UL-TimeslotISCP-Value-IncrDecrThres,
+ USCH-ID,
+ HSDSCH-FDD-Information,
+ HSDSCH-FDD-Information-Response,
+ HSDSCH-Information-to-Modify,
+ HSDSCH-Information-to-Modify-Unsynchronised,
+ HSDSCH-MACdFlow-ID,
+ HSDSCH-MACdFlows-Information,
+ HSDSCH-MACdFlows-to-Delete,
+ HSDSCH-RNTI,
+ HSDSCH-TDD-Information,
+ HSDSCH-TDD-Information-Response,
+ PrimaryCCPCH-RSCP,
+ HSDSCH-FDD-Update-Information,
+ HSDSCH-TDD-Update-Information,
+ UL-Synchronisation-Parameters-LCR,
+ TDD-DL-DPCH-TimeSlotFormat-LCR,
+ TDD-UL-DPCH-TimeSlotFormat-LCR,
+ TDD-TPC-UplinkStepSize-LCR,
+ CellSyncBurstTimingLCR,
+ TimingAdjustmentValueLCR,
+ PrimaryCCPCH-RSCP-Delta
+FROM NBAP-IEs
+
+ PrivateIE-Container{},
+ ProtocolExtensionContainer{},
+ ProtocolIE-Container{},
+ ProtocolIE-Single-Container{},
+ ProtocolIE-ContainerList{},
+ NBAP-PRIVATE-IES,
+ NBAP-PROTOCOL-IES,
+ NBAP-PROTOCOL-EXTENSION
+FROM NBAP-Containers
+
+ id-Active-Pattern-Sequence-Information,
+ id-AdjustmentRatio,
+ id-AICH-Information,
+ id-AICH-ParametersListIE-CTCH-ReconfRqstFDD,
+ id-AP-AICH-Information,
+ id-AP-AICH-ParametersListIE-CTCH-ReconfRqstFDD,
+ id-BCH-Information,
+ id-BCCH-ModificationTime,
+ id-bindingID,
+ id-BlockingPriorityIndicator,
+ id-Cause,
+ id-CauseLevel-PSCH-ReconfFailure,
+ id-CauseLevel-RL-AdditionFailureFDD,
+ id-CauseLevel-RL-AdditionFailureTDD,
+ id-CauseLevel-RL-ReconfFailure,
+ id-CauseLevel-RL-SetupFailureFDD,
+ id-CauseLevel-RL-SetupFailureTDD,
+ id-CauseLevel-SyncAdjustmntFailureTDD,
+ id-CCP-InformationItem-AuditRsp,
+ id-CCP-InformationList-AuditRsp,
+ id-CCP-InformationItem-ResourceStatusInd,
+ id-CCTrCH-InformationItem-RL-FailureInd,
+ id-CCTrCH-InformationItem-RL-RestoreInd,
+ id-CCTrCH-Initial-DL-Power-RL-AdditionRqstTDD,
+ id-CCTrCH-Initial-DL-Power-RL-ReconfPrepTDD,
+ id-CCTrCH-Initial-DL-Power-RL-SetupRqstTDD,
+ id-CDCA-ICH-Information,
+ id-CDCA-ICH-ParametersListIE-CTCH-ReconfRqstFDD,
+ id-CellAdjustmentInfo-SyncAdjustmntRqstTDD,
+ id-CellAdjustmentInfoItem-SyncAdjustmentRqstTDD,
+ id-Cell-InformationItem-AuditRsp,
+ id-Cell-InformationItem-ResourceStatusInd,
+ id-Cell-InformationList-AuditRsp,
+ id-CellParameterID,
+ id-CellSyncBurstTransInit-CellSyncInitiationRqstTDD,
+ id-CellSyncBurstMeasureInit-CellSyncInitiationRqstTDD,
+ id-cellSyncBurstRepetitionPeriod,
+ id-CellSyncBurstTransReconfiguration-CellSyncReconfRqstTDD,
+ id-CellSyncBurstTransReconfInfo-CellSyncReconfRqstTDD,
+ id-CellSyncBurstMeasReconfiguration-CellSyncReconfRqstTDD,
+ id-CellSyncBurstMeasInfoList-CellSyncReconfRqstTDD,
+ id-CellSyncBurstInfoList-CellSyncReconfRqstTDD,
+ id-CellSyncInfo-CellSyncReprtTDD,
+ id-CFN,
+ id-CFNReportingIndicator,
+ id-C-ID,
+ id-Closed-Loop-Timing-Adjustment-Mode,
+ id-CommonMeasurementAccuracy,
+ id-CommonMeasurementObjectType-CM-Rprt,
+ id-CommonMeasurementObjectType-CM-Rqst,
+ id-CommonMeasurementObjectType-CM-Rsp,
+ id-CommonMeasurementType,
+ id-CommonPhysicalChannelID,
+ id-CommonPhysicalChannelType-CTCH-ReconfRqstFDD,
+ id-CommonPhysicalChannelType-CTCH-SetupRqstFDD,
+ id-CommonPhysicalChannelType-CTCH-SetupRqstTDD,
+ id-CommunicationContextInfoItem-Reset,
+ id-CommunicationControlPortID,
+ id-CommunicationControlPortInfoItem-Reset,
+ id-Compressed-Mode-Deactivation-Flag,
+ id-ConfigurationGenerationID,
+ id-CPCH-Information,
+ id-CPCH-Parameters-CTCH-SetupRsp,
+ id-CPCH-ParametersListIE-CTCH-ReconfRqstFDD,
+ id-CRNC-CommunicationContextID,
+ id-CriticalityDiagnostics,
+ id-CSBTransmissionID,
+ id-CSBMeasurementID,
+ id-DCHs-to-Add-FDD,
+ id-DCHs-to-Add-TDD,
+ id-DCH-AddList-RL-ReconfPrepTDD,
+ id-DCH-DeleteList-RL-ReconfPrepFDD,
+ id-DCH-DeleteList-RL-ReconfPrepTDD,
+ id-DCH-DeleteList-RL-ReconfRqstFDD,
+ id-DCH-DeleteList-RL-ReconfRqstTDD,
+ id-DCH-FDD-Information,
+ id-DCH-TDD-Information,
+ id-DCH-InformationResponse,
+ id-DCH-RearrangeList-Bearer-RearrangeInd,
+ id-DSCH-RearrangeList-Bearer-RearrangeInd,
+ id-FDD-DCHs-to-Modify,
+ id-TDD-DCHs-to-Modify,
+ id-DedicatedMeasurementObjectType-DM-Rprt,
+ id-DedicatedMeasurementObjectType-DM-Rqst,
+ id-DedicatedMeasurementObjectType-DM-Rsp,
+ id-DedicatedMeasurementType,
+ id-DelayedActivation,
+ id-DelayedActivationList-RL-ActivationCmdFDD,
+ id-DelayedActivationList-RL-ActivationCmdTDD,
+ id-DelayedActivationInformation-RL-ActivationCmdFDD,
+ id-DelayedActivationInformation-RL-ActivationCmdTDD,
+ id-DL-CCTrCH-InformationAddList-RL-ReconfPrepTDD,
+ id-DL-CCTrCH-InformationDeleteItem-RL-ReconfRqstTDD,
+ id-DL-CCTrCH-InformationDeleteList-RL-ReconfPrepTDD,
+ id-DL-CCTrCH-InformationDeleteList-RL-ReconfRqstTDD,
+ id-DL-CCTrCH-InformationItem-RL-SetupRqstTDD,
+ id-DL-CCTrCH-InformationList-RL-AdditionRqstTDD,
+ id-DL-CCTrCH-InformationList-RL-SetupRqstTDD,
+ id-DL-CCTrCH-InformationModifyItem-RL-ReconfRqstTDD,
+ id-DL-CCTrCH-InformationModifyList-RL-ReconfPrepTDD,
+ id-DL-CCTrCH-InformationModifyList-RL-ReconfRqstTDD,
+ id-DL-DPCH-InformationAddListIE-RL-ReconfPrepTDD,
+ id-DL-DPCH-InformationItem-RL-AdditionRqstTDD,
+ id-DL-DPCH-InformationList-RL-SetupRqstTDD,
+ id-DL-DPCH-InformationModify-AddListIE-RL-ReconfPrepTDD,
+ id-DL-DPCH-InformationModify-DeleteListIE-RL-ReconfPrepTDD,
+ id-DL-DPCH-InformationModify-ModifyListIE-RL-ReconfPrepTDD,
+ id-DL-DPCH-Information-RL-ReconfPrepFDD,
+ id-DL-DPCH-Information-RL-ReconfRqstFDD,
+ id-DL-DPCH-Information-RL-SetupRqstFDD,
+ id-DL-DPCH-TimingAdjustment,
+ id-DL-PowerBalancing-Information,
+ id-DL-PowerBalancing-ActivationIndicator,
+ id-DL-ReferencePowerInformationItem-DL-PC-Rqst,
+ id-DL-PowerBalancing-UpdatedIndicator,
+ id-DLReferencePower,
+ id-DLReferencePowerList-DL-PC-Rqst,
+ id-DL-TPC-Pattern01Count,
+ id-DPC-Mode,
+ id-DPCHConstant,
+ id-DSCH-AddItem-RL-ReconfPrepFDD,
+ id-DSCHs-to-Add-FDD,
+ id-DSCH-DeleteItem-RL-ReconfPrepFDD,
+ id-DSCH-DeleteList-RL-ReconfPrepFDD,
+ id-DSCHs-to-Add-TDD,
+ id-DSCH-Information-DeleteList-RL-ReconfPrepTDD,
+ id-DSCH-Information-ModifyList-RL-ReconfPrepTDD,
+ id-DSCH-InformationResponse,
+ id-DSCH-FDD-Information,
+ id-DSCH-FDD-Common-Information,
+ id-DSCH-TDD-Information,
+ id-DSCH-ModifyItem-RL-ReconfPrepFDD,
+ id-DSCH-ModifyList-RL-ReconfPrepFDD,
+ id-End-Of-Audit-Sequence-Indicator,
+ id-EnhancedDSCHPC,
+ id-EnhancedDSCHPCIndicator,
+ id-FACH-Information,
+ id-FACH-ParametersList-CTCH-ReconfRqstTDD,
+ id-FACH-ParametersList-CTCH-SetupRsp,
+ id-FACH-ParametersListIE-CTCH-ReconfRqstFDD,
+ id-FACH-ParametersListIE-CTCH-SetupRqstFDD,
+ id-FACH-ParametersListIE-CTCH-SetupRqstTDD,
+ id-IndicationType-ResourceStatusInd,
+ id-InformationExchangeID,
+ id-InformationExchangeObjectType-InfEx-Rqst,
+ id-InformationExchangeObjectType-InfEx-Rsp,
+ id-InformationExchangeObjectType-InfEx-Rprt,
+ id-InformationReportCharacteristics,
+ id-InformationType,
+ id-InitDL-Power,
+ id-InnerLoopDLPCStatus,
+ id-IntStdPhCellSyncInfoItem-CellSyncReprtTDD,
+ id-IPDLParameter-Information-Cell-ReconfRqstFDD,
+ id-IPDLParameter-Information-Cell-SetupRqstFDD,
+ id-IPDLParameter-Information-Cell-ReconfRqstTDD,
+ id-IPDLParameter-Information-Cell-SetupRqstTDD,
+ id-LateEntranceCellSyncInfoItem-CellSyncReprtTDD,
+ id-Limited-power-increase-information-Cell-SetupRqstFDD,
+ id-Local-Cell-ID,
+ id-Local-Cell-Group-InformationItem-AuditRsp,
+ id-Local-Cell-Group-InformationItem-ResourceStatusInd,
+ id-Local-Cell-Group-InformationItem2-ResourceStatusInd,
+ id-Local-Cell-Group-InformationList-AuditRsp,
+ id-Local-Cell-InformationItem-AuditRsp,
+ id-Local-Cell-InformationItem-ResourceStatusInd,
+ id-Local-Cell-InformationItem2-ResourceStatusInd,
+ id-Local-Cell-InformationList-AuditRsp,
+ id-AdjustmentPeriod,
+ id-MaxAdjustmentStep,
+ id-MaximumTransmissionPower,
+ id-MeasurementFilterCoefficient,
+ id-MeasurementID,
+ id-MIB-SB-SIB-InformationList-SystemInfoUpdateRqst,
+ id-multipleRL-dl-DPCH-InformationList,
+ id-multipleRL-dl-DPCH-InformationModifyList,
+ id-multipleRL-ul-DPCH-InformationList,
+ id-multipleRL-ul-DPCH-InformationModifyList,
+ id-NCyclesPerSFNperiod,
+ id-NeighbouringCellMeasurementInformation,
+ id-NodeB-CommunicationContextID,
+ id-NRepetitionsPerCyclePeriod,
+ id-NumberOfReportedCellPortions,
+ id-P-CCPCH-Information,
+ id-P-CPICH-Information,
+ id-P-SCH-Information,
+ id-PCCPCH-Information-Cell-ReconfRqstTDD,
+ id-PCCPCH-Information-Cell-SetupRqstTDD,
+ id-PCH-Parameters-CTCH-ReconfRqstTDD,
+ id-PCH-Parameters-CTCH-SetupRsp,
+ id-PCH-ParametersItem-CTCH-ReconfRqstFDD,
+ id-PCH-ParametersItem-CTCH-SetupRqstFDD,
+ id-PCH-ParametersItem-CTCH-SetupRqstTDD,
+ id-PCH-Information,
+ id-PCPCH-Information,
+ id-PICH-ParametersItem-CTCH-ReconfRqstFDD,
+ id-PDSCH-Information-AddListIE-PSCH-ReconfRqst,
+ id-PDSCH-Information-Cell-SetupRqstFDD,
+ id-PDSCH-Information-Cell-ReconfRqstFDD,
+ id-PDSCH-Information-ModifyListIE-PSCH-ReconfRqst,
+ id-PDSCH-RL-ID,
+ id-PDSCHSets-AddList-PSCH-ReconfRqst,
+ id-PDSCHSets-DeleteList-PSCH-ReconfRqst,
+ id-PDSCHSets-ModifyList-PSCH-ReconfRqst,
+ id-PICH-Information,
+ id-PICH-Parameters-CTCH-ReconfRqstTDD,
+ id-PICH-ParametersItem-CTCH-SetupRqstTDD,
+ id-PowerAdjustmentType,
+ id-Power-Local-Cell-Group-InformationItem-AuditRsp,
+ id-Power-Local-Cell-Group-InformationItem-ResourceStatusInd,
+ id-Power-Local-Cell-Group-InformationItem2-ResourceStatusInd,
+ id-Power-Local-Cell-Group-InformationList-AuditRsp,
+ id-Power-Local-Cell-Group-InformationList-ResourceStatusInd,
+ id-Power-Local-Cell-Group-InformationList2-ResourceStatusInd,
+ id-Power-Local-Cell-Group-ID,
+ id-PRACH-Information,
+ id-PRACHConstant,
+ id-PRACH-ParametersItem-CTCH-SetupRqstTDD,
+ id-PRACH-ParametersListIE-CTCH-ReconfRqstFDD,
+ id-PrimaryCCPCH-Information-Cell-ReconfRqstFDD,
+ id-PrimaryCCPCH-Information-Cell-SetupRqstFDD,
+ id-PrimaryCPICH-Information-Cell-ReconfRqstFDD,
+ id-PrimaryCPICH-Information-Cell-SetupRqstFDD,
+ id-Primary-CPICH-Usage-for-Channel-Estimation,
+ id-PrimarySCH-Information-Cell-ReconfRqstFDD,
+ id-PrimarySCH-Information-Cell-SetupRqstFDD,
+ id-PrimaryScramblingCode,
+ id-SCH-Information-Cell-ReconfRqstTDD,
+ id-SCH-Information-Cell-SetupRqstTDD,
+ id-PUSCH-Information-AddListIE-PSCH-ReconfRqst,
+ id-PUSCH-Information-ModifyListIE-PSCH-ReconfRqst,
+ id-PUSCHConstant,
+ id-PUSCHSets-AddList-PSCH-ReconfRqst,
+ id-PUSCHSets-DeleteList-PSCH-ReconfRqst,
+ id-PUSCHSets-ModifyList-PSCH-ReconfRqst,
+ id-Qth-Parameter,
+ id-RACH-Information,
+ id-RACH-Parameters-CTCH-SetupRsp,
+ id-RACH-ParametersItem-CTCH-SetupRqstFDD,
+ id-RACH-ParameterItem-CTCH-SetupRqstTDD,
+ id-ReferenceClockAvailability,
+ id-ReferenceSFNoffset,
+ id-ReportCharacteristics,
+ id-Reporting-Object-RL-FailureInd,
+ id-Reporting-Object-RL-RestoreInd,
+ id-ResetIndicator,
+ id-RL-ID,
+ id-RL-InformationItem-DM-Rprt,
+ id-RL-InformationItem-DM-Rqst,
+ id-RL-InformationItem-DM-Rsp,
+ id-RL-InformationItem-RL-AdditionRqstFDD,
+ id-RL-informationItem-RL-DeletionRqst,
+ id-RL-InformationItem-RL-FailureInd,
+ id-RL-InformationItem-RL-PreemptRequiredInd,
+ id-RL-InformationItem-RL-ReconfPrepFDD,
+ id-RL-InformationItem-RL-ReconfRqstFDD,
+ id-RL-InformationItem-RL-RestoreInd,
+ id-RL-InformationItem-RL-SetupRqstFDD,
+ id-RL-InformationList-RL-AdditionRqstFDD,
+ id-RL-informationList-RL-DeletionRqst,
+ id-RL-InformationList-RL-PreemptRequiredInd,
+ id-RL-InformationList-RL-ReconfPrepFDD,
+ id-RL-InformationList-RL-ReconfRqstFDD,
+ id-RL-InformationList-RL-SetupRqstFDD,
+ id-RL-InformationResponseItem-RL-AdditionRspFDD,
+ id-RL-InformationResponseItem-RL-ReconfReady,
+ id-RL-InformationResponseItem-RL-ReconfRsp,
+ id-RL-InformationResponseItem-RL-SetupRspFDD,
+ id-RL-InformationResponseList-RL-AdditionRspFDD,
+ id-RL-InformationResponseList-RL-ReconfReady,
+ id-RL-InformationResponseList-RL-ReconfRsp,
+ id-RL-InformationResponseList-RL-SetupRspFDD,
+ id-RL-InformationResponse-RL-AdditionRspTDD,
+ id-RL-InformationResponse-RL-SetupRspTDD,
+ id-RL-Information-RL-AdditionRqstTDD,
+ id-RL-Information-RL-ReconfRqstTDD,
+ id-RL-Information-RL-ReconfPrepTDD,
+ id-RL-Information-RL-SetupRqstTDD,
+ id-RL-ReconfigurationFailureItem-RL-ReconfFailure,
+ id-RL-Set-InformationItem-DM-Rprt,
+ id-RL-Set-InformationItem-DM-Rsp,
+ id-RL-Set-InformationItem-RL-FailureInd,
+ id-RL-Set-InformationItem-RL-RestoreInd,
+ id-RL-Specific-DCH-Info,
+ id-S-CCPCH-Information,
+ id-S-CPICH-Information,
+ id-SCH-Information,
+ id-S-SCH-Information,
+ id-Secondary-CCPCHListIE-CTCH-ReconfRqstTDD,
+ id-Secondary-CCPCH-parameterListIE-CTCH-SetupRqstTDD,
+ id-Secondary-CCPCH-Parameters-CTCH-ReconfRqstTDD,
+ id-SecondaryCPICH-InformationItem-Cell-ReconfRqstFDD,
+ id-SecondaryCPICH-InformationItem-Cell-SetupRqstFDD,
+ id-SecondaryCPICH-InformationList-Cell-ReconfRqstFDD,
+ id-SecondaryCPICH-InformationList-Cell-SetupRqstFDD,
+ id-Secondary-CPICH-Information-Change,
+ id-SecondarySCH-Information-Cell-ReconfRqstFDD,
+ id-SecondarySCH-Information-Cell-SetupRqstFDD,
+ id-SegmentInformationListIE-SystemInfoUpdate,
+ id-SFN,
+ id-SFNReportingIndicator,
+ id-ShutdownTimer,
+ id-SignallingBearerRequestIndicator,
+ id-SSDT-CellIDforEDSCHPC,
+ id-Start-Of-Audit-Sequence-Indicator,
+ id-Successful-RL-InformationRespItem-RL-AdditionFailureFDD,
+ id-Successful-RL-InformationRespItem-RL-SetupFailureFDD,
+ id-Synchronisation-Configuration-Cell-ReconfRqst,
+ id-Synchronisation-Configuration-Cell-SetupRqst,
+ id-SyncCase,
+ id-SyncCaseIndicatorItem-Cell-SetupRqstTDD-PSCH,
+ id-SyncFrameNumber,
+ id-SynchronisationReportType,
+ id-SynchronisationReportCharacteristics,
+ id-SyncReportType-CellSyncReprtTDD,
+ id-T-Cell,
+ id-TargetCommunicationControlPortID,
+ id-TFCI2-Bearer-Information-RL-SetupRqstFDD,
+ id-TFCI2-BearerInformationResponse,
+ id-TFCI2BearerRequestIndicator,
+ id-TFCI2-BearerSpecificInformation-RL-ReconfPrepFDD,
+ id-Transmission-Gap-Pattern-Sequence-Information,
+ id-TimeSlotConfigurationList-Cell-ReconfRqstTDD,
+ id-TimeSlotConfigurationList-Cell-SetupRqstTDD,
+ id-timeslotInfo-CellSyncInitiationRqstTDD,
+ id-TimeslotISCPInfo,
+ id-TimingAdvanceApplied,
+ id-TnlQos,
+ id-TransmissionDiversityApplied,
+ id-transportlayeraddress,
+ id-UARFCNforNt,
+ id-UARFCNforNd,
+ id-UARFCNforNu,
+ id-UL-CCTrCH-InformationAddList-RL-ReconfPrepTDD,
+ id-UL-CCTrCH-InformationDeleteItem-RL-ReconfRqstTDD,
+ id-UL-CCTrCH-InformationDeleteList-RL-ReconfPrepTDD,
+ id-UL-CCTrCH-InformationDeleteList-RL-ReconfRqstTDD,
+ id-UL-CCTrCH-InformationItem-RL-SetupRqstTDD,
+ id-UL-CCTrCH-InformationList-RL-AdditionRqstTDD,
+ id-UL-CCTrCH-InformationList-RL-SetupRqstTDD,
+ id-UL-CCTrCH-InformationModifyItem-RL-ReconfRqstTDD,
+ id-UL-CCTrCH-InformationModifyList-RL-ReconfPrepTDD,
+ id-UL-CCTrCH-InformationModifyList-RL-ReconfRqstTDD,
+ id-UL-DPCH-InformationAddListIE-RL-ReconfPrepTDD,
+ id-UL-DPCH-InformationItem-RL-AdditionRqstTDD,
+ id-UL-DPCH-InformationList-RL-SetupRqstTDD,
+ id-UL-DPCH-InformationModify-AddListIE-RL-ReconfPrepTDD,
+ id-UL-DPCH-InformationModify-DeleteListIE-RL-ReconfPrepTDD,
+ id-UL-DPCH-InformationModify-ModifyListIE-RL-ReconfPrepTDD,
+ id-UL-DPCH-Information-RL-ReconfPrepFDD,
+ id-UL-DPCH-Information-RL-ReconfRqstFDD,
+ id-UL-DPCH-Information-RL-SetupRqstFDD,
+ id-Unsuccessful-cell-InformationRespItem-SyncAdjustmntFailureTDD,
+ id-Unsuccessful-PDSCHSetItem-PSCH-ReconfFailureTDD,
+ id-Unsuccessful-PUSCHSetItem-PSCH-ReconfFailureTDD,
+ id-Unsuccessful-RL-InformationRespItem-RL-AdditionFailureFDD,
+ id-Unsuccessful-RL-InformationRespItem-RL-SetupFailureFDD,
+ id-Unsuccessful-RL-InformationResp-RL-AdditionFailureTDD,
+ id-Unsuccessful-RL-InformationResp-RL-SetupFailureTDD,
+ id-USCH-Information-Add,
+ id-USCH-Information-DeleteList-RL-ReconfPrepTDD,
+ id-USCH-Information-ModifyList-RL-ReconfPrepTDD,
+ id-USCH-InformationResponse,
+ id-USCH-Information,
+ id-USCH-RearrangeList-Bearer-RearrangeInd,
+ id-DL-DPCH-LCR-Information-RL-SetupRqstTDD,
+ id-DwPCH-LCR-Information ,
+ id-DwPCH-LCR-InformationList-AuditRsp,
+ id-DwPCH-LCR-Information-Cell-SetupRqstTDD,
+ id-DwPCH-LCR-Information-Cell-ReconfRqstTDD,
+ id-DwPCH-LCR-Information-ResourceStatusInd,
+ id-maxFACH-Power-LCR-CTCH-SetupRqstTDD,
+ id-maxFACH-Power-LCR-CTCH-ReconfRqstTDD,
+ id-FPACH-LCR-Information,
+ id-FPACH-LCR-Information-AuditRsp,
+ id-FPACH-LCR-InformationList-AuditRsp,
+ id-FPACH-LCR-InformationList-ResourceStatusInd,
+ id-FPACH-LCR-Parameters-CTCH-SetupRqstTDD,
+ id-FPACH-LCR-Parameters-CTCH-ReconfRqstTDD,
+ id-PCCPCH-LCR-Information-Cell-SetupRqstTDD,
+ id-PCH-Power-LCR-CTCH-SetupRqstTDD,
+ id-PCH-Power-LCR-CTCH-ReconfRqstTDD,
+ id-PICH-LCR-Parameters-CTCH-SetupRqstTDD,
+ id-PRACH-LCR-ParametersList-CTCH-SetupRqstTDD,
+ id-RL-InformationResponse-LCR-RL-SetupRspTDD ,
+ id-Secondary-CCPCH-LCR-parameterList-CTCH-SetupRqstTDD,
+ id-TimeSlot,
+ id-TimeSlotConfigurationList-LCR-Cell-ReconfRqstTDD,
+ id-TimeSlotConfigurationList-LCR-Cell-SetupRqstTDD,
+ id-TimeslotISCP-LCR-InfoList-RL-SetupRqstTDD,
+ id-TimeSlotLCR-CM-Rqst,
+ id-UL-DPCH-LCR-Information-RL-SetupRqstTDD,
+ id-DL-DPCH-InformationItem-LCR-RL-AdditionRqstTDD,
+ id-UL-DPCH-InformationItem-LCR-RL-AdditionRqstTDD,
+ id-TimeslotISCP-InformationList-LCR-RL-AdditionRqstTDD,
+ id-DL-DPCH-LCR-InformationAddList-RL-ReconfPrepTDD,
+ id-DL-DPCH-LCR-InformationModify-AddList-RL-ReconfPrepTDD,
+ id-DL-Timeslot-LCR-InformationModify-ModifyList-RL-ReconfPrepTDD,
+ id-TimeslotISCPInfoList-LCR-DL-PC-RqstTDD,
+ id-UL-DPCH-LCR-InformationAddListIE-RL-ReconfPrepTDD,
+ id-UL-DPCH-LCR-InformationModify-AddList,
+ id-UL-TimeslotLCR-Information-RL-ReconfPrepTDD,
+ id-UL-SIRTarget,
+ id-PDSCH-AddInformation-LCR-PSCH-ReconfRqst,
+ id-PDSCH-AddInformation-LCR-AddListIE-PSCH-ReconfRqst,
+ id-PDSCH-ModifyInformation-LCR-PSCH-ReconfRqst,
+ id-PDSCH-ModifyInformation-LCR-ModifyListIE-PSCH-ReconfRqst,
+ id-PUSCH-AddInformation-LCR-PSCH-ReconfRqst,
+ id-PUSCH-AddInformation-LCR-AddListIE-PSCH-ReconfRqst,
+ id-PUSCH-ModifyInformation-LCR-PSCH-ReconfRqst,
+ id-PUSCH-ModifyInformation-LCR-ModifyListIE-PSCH-ReconfRqst,
+ id-PUSCH-Info-DM-Rqst,
+ id-PUSCH-Info-DM-Rsp,
+ id-PUSCH-Info-DM-Rprt,
+ id-RL-InformationResponse-LCR-RL-AdditionRspTDD,
+ id-IPDLParameter-Information-LCR-Cell-SetupRqstTDD,
+ id-IPDLParameter-Information-LCR-Cell-ReconfRqstTDD,
+ id-HS-PDSCH-HS-SCCH-MaxPower-PSCH-ReconfRqst,
+ id-HS-PDSCH-HS-SCCH-ScramblingCode-PSCH-ReconfRqst,
+ id-HS-PDSCH-FDD-Code-Information-PSCH-ReconfRqst,
+ id-HS-SCCH-FDD-Code-Information-PSCH-ReconfRqst,
+ id-HS-PDSCH-TDD-Information-PSCH-ReconfRqst,
+ id-Add-To-HS-SCCH-Resource-Pool-PSCH-ReconfRqst,
+ id-Modify-HS-SCCH-Resource-Pool-PSCH-ReconfRqst,
+ id-Delete-From-HS-SCCH-Resource-Pool-PSCH-ReconfRqst,
+ id-SYNCDlCodeId-TransInitLCR-CellSyncInitiationRqstTDD,
+ id-SYNCDlCodeId-MeasureInitLCR-CellSyncInitiationRqstTDD,
+ id-SYNCDlCodeIdTransReconfInfoLCR-CellSyncReconfRqstTDD,
+ id-SYNCDlCodeIdMeasReconfigurationLCR-CellSyncReconfRqstTDD,
+ id-SYNCDlCodeIdMeasInfoList-CellSyncReconfRqstTDD,
+ id-SyncDLCodeIdsMeasInfoList-CellSyncReprtTDD,
+ id-NSubCyclesPerCyclePeriod-CellSyncReconfRqstTDD,
+ id-DwPCH-Power,
+ id-AccumulatedClockupdate-CellSyncReprtTDD,
+ id-HSDPA-Capability,
+ id-HSDSCH-FDD-Information,
+ id-HSDSCH-FDD-Information-Response,
+ id-HSDSCH-Information-to-Modify,
+ id-HSDSCH-Information-to-Modify-Unsynchronised,
+ id-HSDSCH-MACdFlows-to-Add,
+ id-HSDSCH-MACdFlows-to-Delete,
+ id-HSDSCH-RearrangeList-Bearer-RearrangeInd,
+ id-HSDSCH-Resources-Information-AuditRsp,
+ id-HSDSCH-Resources-Information-ResourceStatusInd,
+ id-HSDSCH-RNTI,
+ id-HSDSCH-TDD-Information,
+ id-HSDSCH-TDD-Information-Response,
+ id-HSPDSCH-RL-ID,
+ id-HSSICH-Info-DM-Rprt,
+ id-HSSICH-Info-DM-Rqst,
+ id-HSSICH-Info-DM-Rsp,
+ id-PrimCCPCH-RSCP-DL-PC-RqstTDD,
+ id-HSDSCH-FDD-Update-Information,
+ id-HSDSCH-TDD-Update-Information,
+ id-UL-Synchronisation-Parameters-LCR,
+ id-DL-DPCH-TimeSlotFormat-LCR-ModifyItem-RL-ReconfPrepTDD,
+ id-UL-DPCH-TimeSlotFormat-LCR-ModifyItem-RL-ReconfPrepTDD,
+ id-CCTrCH-Maximum-DL-Power-RL-SetupRqstTDD,
+ id-CCTrCH-Minimum-DL-Power-RL-SetupRqstTDD,
+ id-CCTrCH-Maximum-DL-Power-RL-AdditionRqstTDD,
+ id-CCTrCH-Minimum-DL-Power-RL-AdditionRqstTDD,
+ id-CCTrCH-Maximum-DL-Power-InformationAdd-RL-ReconfPrepTDD,
+ id-CCTrCH-Minimum-DL-Power-InformationAdd-RL-ReconfPrepTDD,
+ id-CCTrCH-Maximum-DL-Power-InformationModify-RL-ReconfPrepTDD,
+ id-CCTrCH-Minimum-DL-Power-InformationModify-RL-ReconfPrepTDD,
+ id-Maximum-DL-Power-Modify-LCR-InformationModify-RL-ReconfPrepTDD,
+ id-Minimum-DL-Power-Modify-LCR-InformationModify-RL-ReconfPrepTDD,
+ id-DL-DPCH-LCR-InformationModify-ModifyList-RL-ReconfRqstTDD,
+ id-CCTrCH-Maximum-DL-Power-InformationModify-RL-ReconfRqstTDD,
+ id-CCTrCH-Minimum-DL-Power-InformationModify-RL-ReconfRqstTDD,
+ id-TDD-TPC-UplinkStepSize-LCR-RL-SetupRqstTDD,
+ id-TDD-TPC-UplinkStepSize-LCR-RL-AdditionRqstTDD,
+ id-TDD-TPC-DownlinkStepSize-RL-AdditionRqstTDD,
+ id-TDD-TPC-UplinkStepSize-InformationAdd-LCR-RL-ReconfPrepTDD,
+ id-TDD-TPC-UplinkStepSize-InformationModify-LCR-RL-ReconfPrepTDD,
+ id-TDD-TPC-DownlinkStepSize-InformationModify-RL-ReconfPrepTDD,
+ id-TDD-TPC-DownlinkStepSize-InformationAdd-RL-ReconfPrepTDD,
+ id-TimeslotISCP-LCR-InfoList-RL-ReconfPrepTDD,
+ id-TimingAdjustmentValueLCR,
+ id-PrimaryCCPCH-RSCP-Delta,
+
+
+ maxNrOfCCTrCHs,
+ maxNrOfCellSyncBursts,
+ maxNrOfCodes,
+ maxNrOfCPCHs,
+ maxNrOfDCHs,
+ maxNrOfDLTSs,
+ maxNrOfDLTSLCRs,
+ maxNrOfDPCHs,
+ maxNrOfDPCHLCRs,
+ maxNrOfDSCHs,
+ maxNrOfFACHs,
+ maxNrOfRLs,
+ maxNrOfRLs-1,
+ maxNrOfRLs-2,
+ maxNrOfRLSets,
+ maxNrOfPCPCHs,
+ maxNrOfPDSCHs,
+ maxNrOfPUSCHs,
+ maxNrOfPRACHLCRs,
+ maxNrOfPDSCHSets,
+ maxNrOfPUSCHSets,
+ maxNrOfReceptsPerSyncFrame,
+ maxNrOfSCCPCHs,
+ maxNrOfSCCPCHLCRs,
+ maxNrOfULTSs,
+ maxNrOfULTSLCRs,
+ maxNrOfUSCHs,
+ maxAPSigNum,
+ maxCPCHCell,
+ maxFACHCell,
+ maxFPACHCell,
+ maxNoofLen,
+ maxRACHCell,
+ maxPCPCHCell,
+ maxPRACHCell,
+ maxSCCPCHCell,
+ maxSCPICHCell,
+ maxCellinNodeB,
+ maxCCPinNodeB,
+ maxCommunicationContext,
+ maxLocalCellinNodeB,
+ maxNrOfSlotFormatsPRACH,
+ maxIB,
+ maxIBSEG,
+ maxNrOfHSSCCHs,
+ maxNrOfHSSICHs,
+ maxNrOfHSPDSCHs,
+ maxNrOfSyncFramesLCR,
+ maxNrOfReceptionsperSyncFrameLCR,
+ maxNrOfSyncDLCodesLCR,
+ maxNrOfMACdFlows
+FROM NBAP-Constants;
+
+-- **************************************************************
+--
+-- COMMON TRANSPORT CHANNEL SETUP REQUEST FDD
+--
+-- **************************************************************
+
+CommonTransportChannelSetupRequestFDD ::= SEQUENCE {
+ protocolIEs ProtocolIE-Container {{CommonTransportChannelSetupRequestFDD-IEs}},
+ protocolExtensions ProtocolExtensionContainer {{CommonTransportChannelSetupRequestFDD-Extensions}} OPTIONAL,
+ ...
+}
+
+CommonTransportChannelSetupRequestFDD-Extensions NBAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+CommonTransportChannelSetupRequestFDD-IEs NBAP-PROTOCOL-IES ::= {
+ { ID id-C-ID CRITICALITY reject TYPE C-ID PRESENCE mandatory }|
+ { ID id-ConfigurationGenerationID CRITICALITY reject TYPE ConfigurationGenerationID PRESENCE mandatory }|
+ { ID id-CommonPhysicalChannelType-CTCH-SetupRqstFDD CRITICALITY ignore TYPE CommonPhysicalChannelType-CTCH-SetupRqstFDD PRESENCE mandatory },
+ ...
+}
+
+CommonPhysicalChannelType-CTCH-SetupRqstFDD ::= CHOICE {
+ secondary-CCPCH-parameters Secondary-CCPCH-CTCH-SetupRqstFDD,
+ pRACH-parameters PRACH-CTCH-SetupRqstFDD,
+ pCPCHes-parameters PCPCH-CTCH-SetupRqstFDD,
+ ...
+}
+
+Secondary-CCPCH-CTCH-SetupRqstFDD ::= SEQUENCE {
+ commonPhysicalChannelID CommonPhysicalChannelID,
+ fdd-S-CCPCH-Offset FDD-S-CCPCH-Offset,
+ dl-ScramblingCode DL-ScramblingCode OPTIONAL,
+ -- This IE shall be present if the PCH Parameters IE is not present
+ fdd-DL-ChannelisationCodeNumber FDD-DL-ChannelisationCodeNumber,
+ tFCS TFCS,
+ secondary-CCPCH-SlotFormat SecondaryCCPCH-SlotFormat,
+ tFCI-Presence TFCI-Presence OPTIONAL,
+ -- This IE shall be present if the Secondary CCPCH Slot Format is set to any of the values from 8 to 17
+ multiplexingPosition MultiplexingPosition,
+ powerOffsetInformation PowerOffsetInformation-CTCH-SetupRqstFDD,
+ sTTD-Indicator STTD-Indicator,
+ fACH-Parameters FACH-ParametersList-CTCH-SetupRqstFDD OPTIONAL,
+ pCH-Parameters PCH-Parameters-CTCH-SetupRqstFDD OPTIONAL,
+ iE-Extensions ProtocolExtensionContainer { { Secondary-CCPCHItem-CTCH-SetupRqstFDD-ExtIEs} } OPTIONAL,
+ ...
+}
+
+Secondary-CCPCHItem-CTCH-SetupRqstFDD-ExtIEs NBAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+PowerOffsetInformation-CTCH-SetupRqstFDD ::= SEQUENCE {
+ pO1-ForTFCI-Bits PowerOffset,
+ pO3-ForPilotBits PowerOffset,
+ iE-Extensions ProtocolExtensionContainer { { PowerOffsetInformation-CTCH-SetupRqstFDD-ExtIEs} } OPTIONAL,
+ ...
+}
+
+PowerOffsetInformation-CTCH-SetupRqstFDD-ExtIEs NBAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+FACH-ParametersList-CTCH-SetupRqstFDD ::= ProtocolIE-Single-Container {{ FACH-ParametersListIEs-CTCH-SetupRqstFDD }}
+
+FACH-ParametersListIEs-CTCH-SetupRqstFDD NBAP-PROTOCOL-IES ::= {
+ { ID id-FACH-ParametersListIE-CTCH-SetupRqstFDD CRITICALITY reject TYPE FACH-ParametersListIE-CTCH-SetupRqstFDD PRESENCE mandatory }
+}
+
+FACH-ParametersListIE-CTCH-SetupRqstFDD ::= SEQUENCE (SIZE (1..maxNrOfFACHs)) OF FACH-ParametersItem-CTCH-SetupRqstFDD
+
+FACH-ParametersItem-CTCH-SetupRqstFDD ::= SEQUENCE {
+ commonTransportChannelID CommonTransportChannelID,
+ transportFormatSet TransportFormatSet,
+ toAWS ToAWS,
+ toAWE ToAWE,
+ maxFACH-Power DL-Power,
+ iE-Extensions ProtocolExtensionContainer { { FACH-ParametersItem-CTCH-SetupRqstFDD-ExtIEs} } OPTIONAL,
+ ...
+}
+
+FACH-ParametersItem-CTCH-SetupRqstFDD-ExtIEs NBAP-PROTOCOL-EXTENSION ::= {
+{ ID id-bindingID CRITICALITY ignore EXTENSION BindingID PRESENCE optional }|
+{ ID id-transportlayeraddress CRITICALITY ignore EXTENSION TransportLayerAddress PRESENCE optional },
+ ...
+}
+
+PCH-Parameters-CTCH-SetupRqstFDD ::= ProtocolIE-Single-Container {{ PCH-ParametersIE-CTCH-SetupRqstFDD }}
+
+PCH-ParametersIE-CTCH-SetupRqstFDD NBAP-PROTOCOL-IES ::= {
+ { ID id-PCH-ParametersItem-CTCH-SetupRqstFDD CRITICALITY reject TYPE PCH-ParametersItem-CTCH-SetupRqstFDD PRESENCE mandatory }
+}
+
+PCH-ParametersItem-CTCH-SetupRqstFDD ::= SEQUENCE {
+ commonTransportChannelID CommonTransportChannelID,
+ transportFormatSet TransportFormatSet,
+ toAWS ToAWS,
+ toAWE ToAWE,
+ pCH-Power DL-Power,
+ pICH-Parameters PICH-Parameters-CTCH-SetupRqstFDD,
+ iE-Extensions ProtocolExtensionContainer { { PCH-ParametersItem-CTCH-SetupRqstFDD-ExtIEs} } OPTIONAL,
+ ...
+}
+
+PCH-ParametersItem-CTCH-SetupRqstFDD-ExtIEs NBAP-PROTOCOL-EXTENSION ::= {
+ { ID id-bindingID CRITICALITY ignore EXTENSION BindingID PRESENCE optional }|
+ { ID id-transportlayeraddress CRITICALITY ignore EXTENSION TransportLayerAddress PRESENCE optional },
+ ...
+}
+
+PICH-Parameters-CTCH-SetupRqstFDD ::= SEQUENCE {
+ commonPhysicalChannelID CommonPhysicalChannelID,
+ fdd-dl-ChannelisationCodeNumber FDD-DL-ChannelisationCodeNumber,
+ pICH-Power PICH-Power,
+ pICH-Mode PICH-Mode,
+ sTTD-Indicator STTD-Indicator,
+ iE-Extensions ProtocolExtensionContainer { { PICH-Parameters-CTCH-SetupRqstFDD-ExtIEs} } OPTIONAL,
+ ...
+}
+
+PICH-Parameters-CTCH-SetupRqstFDD-ExtIEs NBAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+PRACH-CTCH-SetupRqstFDD ::= SEQUENCE {
+ commonPhysicalChannelID CommonPhysicalChannelID,
+ scramblingCodeNumber ScramblingCodeNumber,
+ tFCS TFCS,
+ preambleSignatures PreambleSignatures,
+ allowedSlotFormatInformation AllowedSlotFormatInformationList-CTCH-SetupRqstFDD,
+ rACH-SubChannelNumbers RACH-SubChannelNumbers,
+ ul-punctureLimit PunctureLimit,
+ preambleThreshold PreambleThreshold,
+ rACH-Parameters RACH-Parameters-CTCH-SetupRqstFDD,
+ aICH-Parameters AICH-Parameters-CTCH-SetupRqstFDD,
+ iE-Extensions ProtocolExtensionContainer { { PRACHItem-CTCH-SetupRqstFDD-ExtIEs} } OPTIONAL,
+ ...
+}
+
+PRACHItem-CTCH-SetupRqstFDD-ExtIEs NBAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+AllowedSlotFormatInformationList-CTCH-SetupRqstFDD ::= SEQUENCE (SIZE (1.. maxNrOfSlotFormatsPRACH)) OF AllowedSlotFormatInformationItem-CTCH-SetupRqstFDD
+
+AllowedSlotFormatInformationItem-CTCH-SetupRqstFDD ::= SEQUENCE {
+ rACHSlotFormat RACH-SlotFormat,
+ iE-Extensions ProtocolExtensionContainer { { AllowedSlotFormatInformationItem-CTCH-SetupRqstFDD-ExtIEs} } OPTIONAL,
+ ...
+}
+
+AllowedSlotFormatInformationItem-CTCH-SetupRqstFDD-ExtIEs NBAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+RACH-Parameters-CTCH-SetupRqstFDD ::= ProtocolIE-Single-Container {{ RACH-ParametersIE-CTCH-SetupRqstFDD }}
+
+RACH-ParametersIE-CTCH-SetupRqstFDD NBAP-PROTOCOL-IES ::= {
+ { ID id-RACH-ParametersItem-CTCH-SetupRqstFDD CRITICALITY reject TYPE RACH-ParametersItem-CTCH-SetupRqstFDD PRESENCE mandatory }
+}
+
+RACH-ParametersItem-CTCH-SetupRqstFDD ::= SEQUENCE {
+ commonTransportChannelID CommonTransportChannelID,
+ transportFormatSet TransportFormatSet,
+ iE-Extensions ProtocolExtensionContainer { { RACH-ParametersItem-CTCH-SetupRqstFDD-ExtIEs} } OPTIONAL,
+ ...
+ }
+
+RACH-ParametersItem-CTCH-SetupRqstFDD-ExtIEs NBAP-PROTOCOL-EXTENSION ::= {
+ { ID id-bindingID CRITICALITY ignore EXTENSION BindingID PRESENCE optional }|
+ { ID id-transportlayeraddress CRITICALITY ignore EXTENSION TransportLayerAddress PRESENCE optional },
+ ...
+}
+
+AICH-Parameters-CTCH-SetupRqstFDD ::= SEQUENCE {
+ commonPhysicalChannelID CommonPhysicalChannelID,
+ aICH-TransmissionTiming AICH-TransmissionTiming,
+ fdd-dl-ChannelisationCodeNumber FDD-DL-ChannelisationCodeNumber,
+ aICH-Power AICH-Power,
+ sTTD-Indicator STTD-Indicator,
+ iE-Extensions ProtocolExtensionContainer { { AICH-Parameters-CTCH-SetupRqstFDD-ExtIEs} } OPTIONAL,
+ ...
+}
+
+AICH-Parameters-CTCH-SetupRqstFDD-ExtIEs NBAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+PCPCH-CTCH-SetupRqstFDD ::= SEQUENCE {
+ cPCH-Parameters CPCH-Parameters-CTCH-SetupRqstFDD,
+ iE-Extensions ProtocolExtensionContainer { { PCPCHItem-CTCH-SetupRqstFDD-ExtIEs} } OPTIONAL,
+ ...
+}
+
+PCPCHItem-CTCH-SetupRqstFDD-ExtIEs NBAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+CPCH-Parameters-CTCH-SetupRqstFDD ::= SEQUENCE {
+ commonTransportChannelID CommonTransportChannelID,
+ transportFormatSet TransportFormatSet,
+ aPPreambleScramblingCode CPCHScramblingCodeNumber,
+ cDPreambleScramblingCode CPCHScramblingCodeNumber,
+ tFCS TFCS,
+ cDSignatures PreambleSignatures OPTIONAL,
+ cDSubChannelNumbers CDSubChannelNumbers OPTIONAL,
+ punctureLimit PunctureLimit,
+ cPCH-UL-DPCCH-SlotFormat CPCH-UL-DPCCH-SlotFormat,
+ uL-SIR UL-SIR,
+ initialDL-transmissionPower DL-Power,
+ maximumDLPower DL-Power,
+ minimumDLPower DL-Power,
+ pO2-ForTPC-Bits PowerOffset,
+ fDD-TPC-DownlinkStepSize FDD-TPC-DownlinkStepSize,
+ nStartMessage NStartMessage,
+ nEOT NEOT,
+ channel-Assignment-Indication Channel-Assignment-Indication,
+ cPCH-Allowed-Total-Rate CPCH-Allowed-Total-Rate,
+ pCPCHChannelInfomation PCPCHChannelInformationList-CTCH-SetupRqstFDD,
+ vCAMMapping-Information VCAMMapping-InformationList-CTCH-SetupRqstFDD OPTIONAL,
+ -- this IE shall be present if the Channel Assignment Indication is set to "CA Active" --
+ aP-AICH-Parameters AP-AICH-Parameters-CTCH-SetupRqstFDD,
+ cDCA-ICH-Parameters CDCA-ICH-Parameters-CTCH-SetupRqstFDD,
+ iE-Extensions ProtocolExtensionContainer { { CPCH-Parameters-CTCH-SetupRqstFDD-ExtIEs} } OPTIONAL,
+ ...
+}
+
+CPCH-Parameters-CTCH-SetupRqstFDD-ExtIEs NBAP-PROTOCOL-EXTENSION ::= {
+ { ID id-bindingID CRITICALITY ignore EXTENSION BindingID PRESENCE optional }|
+ { ID id-transportlayeraddress CRITICALITY ignore EXTENSION TransportLayerAddress PRESENCE optional },
+ ...
+}
+
+PCPCHChannelInformationList-CTCH-SetupRqstFDD ::= SEQUENCE (SIZE (1..maxNrOfPCPCHs)) OF PCPCHChannelInformationItem-CTCH-SetupRqstFDD
+
+PCPCHChannelInformationItem-CTCH-SetupRqstFDD ::= SEQUENCE {
+ commonPhysicalChannelID CommonPhysicalChannelID,
+ cPCHScramblingCodeNumber CPCHScramblingCodeNumber,
+ dL-ScramblingCode DL-ScramblingCode,
+ fdd-dl-ChannelisationCodeNumber FDD-DL-ChannelisationCodeNumber,
+ pCP-Length PCP-Length,
+ uCSM-Information UCSM-Information-CTCH-SetupRqstFDD OPTIONAL,
+ -- this IE shall be present if the Channel Assignment Indication is equal to "CA Inactive" --
+ iE-Extensions ProtocolExtensionContainer { { PCPCHChannelInformationItem-CTCH-SetupRqstFDD-ExtIEs} } OPTIONAL,
+ ...
+}
+
+PCPCHChannelInformationItem-CTCH-SetupRqstFDD-ExtIEs NBAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+UCSM-Information-CTCH-SetupRqstFDD ::= SEQUENCE {
+ minUL-ChannelisationCodeLength MinUL-ChannelisationCodeLength,
+ nFmax NFmax,
+ channelRequestParameters ChannelRequestParametersList-CTCH-SetupRqstFDD OPTIONAL,
+ iE-Extensions ProtocolExtensionContainer { { UCSM-InformationItem-CTCH-SetupRqstFDD-ExtIEs} } OPTIONAL,
+ ...
+ }
+
+UCSM-InformationItem-CTCH-SetupRqstFDD-ExtIEs NBAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+ChannelRequestParametersList-CTCH-SetupRqstFDD ::= SEQUENCE (SIZE (1..maxAPSigNum)) OF ChannelRequestParametersItem-CTCH-SetupRqstFDD
+
+ChannelRequestParametersItem-CTCH-SetupRqstFDD ::= SEQUENCE {
+ aPPreambleSignature APPreambleSignature,
+ aPSubChannelNumber APSubChannelNumber OPTIONAL,
+ iE-Extensions ProtocolExtensionContainer { { ChannelRequestParametersItem-CTCH-SetupRqstFDD-ExtIEs} } OPTIONAL,
+ ...
+}
+
+ChannelRequestParametersItem-CTCH-SetupRqstFDD-ExtIEs NBAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+VCAMMapping-InformationList-CTCH-SetupRqstFDD ::= SEQUENCE (SIZE (1..maxNoofLen)) OF VCAMMapping-InformationItem-CTCH-SetupRqstFDD
+
+VCAMMapping-InformationItem-CTCH-SetupRqstFDD ::= SEQUENCE {
+ minUL-ChannelisationCodeLength MinUL-ChannelisationCodeLength,
+ nFmax NFmax,
+ max-Number-of-PCPCHes Max-Number-of-PCPCHes,
+ sFRequestParameters SFRequestParametersList-CTCH-SetupRqstFDD,
+ iE-Extensions ProtocolExtensionContainer { { VCAMMapping-InformationItem-CTCH-SetupRqstFDD-ExtIEs} } OPTIONAL,
+ ...
+}
+
+VCAMMapping-InformationItem-CTCH-SetupRqstFDD-ExtIEs NBAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+SFRequestParametersList-CTCH-SetupRqstFDD ::= SEQUENCE (SIZE (1..maxAPSigNum)) OF SFRequestParametersItem-CTCH-SetupRqstFDD
+
+SFRequestParametersItem-CTCH-SetupRqstFDD ::= SEQUENCE {
+ aPPreambleSignature APPreambleSignature,
+ aPSubChannelNumber APSubChannelNumber OPTIONAL,
+ iE-Extensions ProtocolExtensionContainer { { SFRequestParametersItem-CTCH-SetupRqstFDD-ExtIEs} } OPTIONAL,
+ ...
+}
+
+SFRequestParametersItem-CTCH-SetupRqstFDD-ExtIEs NBAP-PROTOCOL-EXTENSION::= {
+ ...
+}
+
+AP-AICH-Parameters-CTCH-SetupRqstFDD ::= SEQUENCE {
+ commonPhysicalChannelID CommonPhysicalChannelID,
+ fdd-dl-ChannelisationCodeNumber FDD-DL-ChannelisationCodeNumber,
+ aP-AICH-Power AICH-Power,
+ cSICH-Power AICH-Power,
+ sTTD-Indicator STTD-Indicator,
+ iE-Extensions ProtocolExtensionContainer { { AP-AICH-Parameters-CTCH-SetupRqstFDD-ExtIEs} } OPTIONAL,
+ ...
+}
+
+AP-AICH-Parameters-CTCH-SetupRqstFDD-ExtIEs NBAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+CDCA-ICH-Parameters-CTCH-SetupRqstFDD ::= SEQUENCE {
+ commonPhysicalChannelID CommonPhysicalChannelID,
+ fdd-dl-ChannelisationCodeNumber FDD-DL-ChannelisationCodeNumber,
+ cDCA-ICH-Power AICH-Power,
+ sTTD-Indicator STTD-Indicator,
+ iE-Extensions ProtocolExtensionContainer { { CDCA-ICH-Parameters-CTCH-SetupRqstFDD-ExtIEs} } OPTIONAL,
+ ...
+}
+
+CDCA-ICH-Parameters-CTCH-SetupRqstFDD-ExtIEs NBAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+-- **************************************************************
+--
+-- COMMON TRANSPORT CHANNEL SETUP REQUEST TDD
+--
+-- **************************************************************
+
+CommonTransportChannelSetupRequestTDD ::= SEQUENCE {
+ protocolIEs ProtocolIE-Container {{CommonTransportChannelSetupRequestTDD-IEs}},
+ protocolExtensions ProtocolExtensionContainer {{CommonTransportChannelSetupRequestTDD-Extensions}} OPTIONAL,
+ ...
+}
+
+CommonTransportChannelSetupRequestTDD-IEs NBAP-PROTOCOL-IES ::= {
+ { ID id-C-ID CRITICALITY reject TYPE C-ID PRESENCE mandatory }|
+ { ID id-ConfigurationGenerationID CRITICALITY reject TYPE ConfigurationGenerationID PRESENCE mandatory }|
+ { ID id-CommonPhysicalChannelType-CTCH-SetupRqstTDD CRITICALITY ignore TYPE CommonPhysicalChannelType-CTCH-SetupRqstTDD PRESENCE mandatory },
+ ...
+}
+
+CommonTransportChannelSetupRequestTDD-Extensions NBAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+CommonPhysicalChannelType-CTCH-SetupRqstTDD ::= CHOICE {
+ secondary-CCPCH-parameters Secondary-CCPCH-CTCH-SetupRqstTDD,
+ pRACH-parameters PRACH-CTCH-SetupRqstTDD,
+ ...
+}
+
+Secondary-CCPCH-CTCH-SetupRqstTDD ::= SEQUENCE {
+ sCCPCH-CCTrCH-ID CCTrCH-ID, -- For DL CCTrCH supporting one or several Secondary CCPCHs
+ tFCS TFCS, -- For DL CCTrCH supporting one or several Secondary CCPCHs
+ tFCI-Coding TFCI-Coding,
+ punctureLimit PunctureLimit,
+ secondaryCCPCH-parameterList Secondary-CCPCH-parameterList-CTCH-SetupRqstTDD,
+ fACH-ParametersList FACH-ParametersList-CTCH-SetupRqstTDD OPTIONAL,
+ pCH-Parameters PCH-Parameters-CTCH-SetupRqstTDD OPTIONAL,
+ iE-Extensions ProtocolExtensionContainer {{Secondary-CCPCHItem-CTCH-SetupRqstTDD-ExtIEs}} OPTIONAL,
+ ...
+}
+
+Secondary-CCPCHItem-CTCH-SetupRqstTDD-ExtIEs NBAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+Secondary-CCPCH-parameterList-CTCH-SetupRqstTDD ::= ProtocolIE-Single-Container {{ Secondary-CCPCH-parameterListIEs-CTCH-SetupRqstTDD }}
+
+Secondary-CCPCH-parameterListIEs-CTCH-SetupRqstTDD NBAP-PROTOCOL-IES ::= {
+ { ID id-Secondary-CCPCH-parameterListIE-CTCH-SetupRqstTDD CRITICALITY reject TYPE Secondary-CCPCH-parameterListIE-CTCH-SetupRqstTDD PRESENCE optional }|
+ { ID id-Secondary-CCPCH-LCR-parameterList-CTCH-SetupRqstTDD CRITICALITY reject TYPE Secondary-CCPCH-LCR-parameterList-CTCH-SetupRqstTDD PRESENCE optional }
+}
+
+Secondary-CCPCH-parameterListIE-CTCH-SetupRqstTDD ::= SEQUENCE (SIZE (1..maxNrOfSCCPCHs)) OF Secondary-CCPCH-parameterItem-CTCH-SetupRqstTDD
+
+Secondary-CCPCH-parameterItem-CTCH-SetupRqstTDD ::= SEQUENCE {
+ commonPhysicalChannelID CommonPhysicalChannelID,
+ tdd-ChannelisationCode TDD-ChannelisationCode,
+ timeslot TimeSlot,
+ midambleShiftandBurstType MidambleShiftAndBurstType,
+ tdd-PhysicalChannelOffset TDD-PhysicalChannelOffset,
+ repetitionPeriod RepetitionPeriod,
+ repetitionLength RepetitionLength,
+ s-CCPCH-Power DL-Power,
+ iE-Extensions ProtocolExtensionContainer { { Secondary-CCPCH-parameterItem-CTCH-SetupRqstTDD-ExtIEs} } OPTIONAL,
+ ...
+}
+
+Secondary-CCPCH-parameterItem-CTCH-SetupRqstTDD-ExtIEs NBAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+FACH-ParametersList-CTCH-SetupRqstTDD ::= ProtocolIE-Single-Container {{ FACH-ParametersListIEs-CTCH-SetupRqstTDD }}
+
+FACH-ParametersListIEs-CTCH-SetupRqstTDD NBAP-PROTOCOL-IES ::= {
+ { ID id-FACH-ParametersListIE-CTCH-SetupRqstTDD CRITICALITY reject TYPE FACH-ParametersListIE-CTCH-SetupRqstTDD PRESENCE mandatory }
+}
+
+FACH-ParametersListIE-CTCH-SetupRqstTDD ::= SEQUENCE (SIZE (1..maxNrOfFACHs)) OF FACH-ParametersItem-CTCH-SetupRqstTDD
+
+FACH-ParametersItem-CTCH-SetupRqstTDD ::= SEQUENCE {
+ commonTransportChannelID CommonTransportChannelID,
+ fACH-CCTrCH-ID CCTrCH-ID,
+ dl-TransportFormatSet TransportFormatSet,
+ toAWS ToAWS,
+ toAWE ToAWE,
+ iE-Extensions ProtocolExtensionContainer { { FACH-ParametersItem-CTCH-SetupRqstTDD-ExtIEs} } OPTIONAL,
+ ...
+}
+
+FACH-ParametersItem-CTCH-SetupRqstTDD-ExtIEs NBAP-PROTOCOL-EXTENSION ::= {
+ { ID id-maxFACH-Power-LCR-CTCH-SetupRqstTDD CRITICALITY reject EXTENSION DL-Power PRESENCE optional }|
+ -- Applicable to 1.28Mcps TDD only
+ { ID id-bindingID CRITICALITY ignore EXTENSION BindingID PRESENCE optional }|
+ -- Shall be ignored if bearer establishment with ALCAP.
+ { ID id-transportlayeraddress CRITICALITY ignore EXTENSION TransportLayerAddress PRESENCE optional },
+ -- Shall be ignored if bearer establishment with ALCAP.
+ ...
+}
+
+PCH-Parameters-CTCH-SetupRqstTDD ::= ProtocolIE-Single-Container {{ PCH-ParametersIE-CTCH-SetupRqstTDD }}
+
+PCH-ParametersIE-CTCH-SetupRqstTDD NBAP-PROTOCOL-IES ::= {
+ { ID id-PCH-ParametersItem-CTCH-SetupRqstTDD CRITICALITY reject TYPE PCH-ParametersItem-CTCH-SetupRqstTDD PRESENCE mandatory }
+}
+
+PCH-ParametersItem-CTCH-SetupRqstTDD ::= SEQUENCE {
+ commonTransportChannelID CommonTransportChannelID,
+ pCH-CCTrCH-ID CCTrCH-ID,
+ dl-TransportFormatSet TransportFormatSet, -- For the DL.
+ toAWS ToAWS,
+ toAWE ToAWE,
+ pICH-Parameters PICH-Parameters-CTCH-SetupRqstTDD,
+ iE-Extensions ProtocolExtensionContainer { { PCH-ParametersItem-CTCH-SetupRqstTDD-ExtIEs} } OPTIONAL,
+ ...
+}
+
+PCH-ParametersItem-CTCH-SetupRqstTDD-ExtIEs NBAP-PROTOCOL-EXTENSION ::= {
+ { ID id-PCH-Power-LCR-CTCH-SetupRqstTDD CRITICALITY reject EXTENSION DL-Power PRESENCE optional }|
+ { ID id-bindingID CRITICALITY ignore EXTENSION BindingID PRESENCE optional }|
+ -- Shall be ignored if bearer establishment with ALCAP.
+ { ID id-transportlayeraddress CRITICALITY ignore EXTENSION TransportLayerAddress PRESENCE optional },
+ -- Shall be ignored if bearer establishment with ALCAP.
+ ...
+}
+
+PICH-Parameters-CTCH-SetupRqstTDD ::= ProtocolIE-Single-Container {{ PICH-ParametersIE-CTCH-SetupRqstTDD }}
+
+PICH-ParametersIE-CTCH-SetupRqstTDD NBAP-PROTOCOL-IES ::= {
+ { ID id-PICH-ParametersItem-CTCH-SetupRqstTDD CRITICALITY reject TYPE PICH-ParametersItem-CTCH-SetupRqstTDD PRESENCE optional }|
+ { ID id-PICH-LCR-Parameters-CTCH-SetupRqstTDD CRITICALITY reject TYPE PICH-LCR-Parameters-CTCH-SetupRqstTDD PRESENCE optional }
+}
+
+PICH-ParametersItem-CTCH-SetupRqstTDD ::= SEQUENCE {
+ commonPhysicalChannelID CommonPhysicalChannelID,
+ tdd-ChannelisationCode TDD-ChannelisationCode,
+ timeSlot TimeSlot,
+ midambleshiftAndBurstType MidambleShiftAndBurstType,
+ tdd-PhysicalChannelOffset TDD-PhysicalChannelOffset,
+ repetitionPeriod RepetitionPeriod,
+ repetitionLength RepetitionLength,
+ pagingIndicatorLength PagingIndicatorLength,
+ pICH-Power PICH-Power,
+ iE-Extensions ProtocolExtensionContainer { { PICH-ParametersItem-CTCH-SetupRqstTDD-ExtIEs} } OPTIONAL,
+ ...
+}
+
+PICH-ParametersItem-CTCH-SetupRqstTDD-ExtIEs NBAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+PICH-LCR-Parameters-CTCH-SetupRqstTDD ::= SEQUENCE {
+ commonPhysicalChannelID CommonPhysicalChannelID,
+ tdd-ChannelisationCodeLCR TDD-ChannelisationCodeLCR,
+ timeSlotLCR TimeSlotLCR,
+ midambleShiftLCR MidambleShiftLCR,
+ tdd-PhysicalChannelOffset TDD-PhysicalChannelOffset,
+ repetitionPeriod RepetitionPeriod,
+ repetitionLength RepetitionLength,
+ pagingIndicatorLength PagingIndicatorLength,
+ pICH-Power PICH-Power,
+ second-TDD-ChannelisationCodeLCR TDD-ChannelisationCodeLCR,
+ iE-Extensions ProtocolExtensionContainer { { PICH-LCR-ParametersItem-CTCH-SetupRqstTDD-ExtIEs} } OPTIONAL,
+ ...
+}
+
+PICH-LCR-ParametersItem-CTCH-SetupRqstTDD-ExtIEs NBAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+Secondary-CCPCH-LCR-parameterList-CTCH-SetupRqstTDD ::= SEQUENCE (SIZE (1..maxNrOfSCCPCHLCRs)) OF Secondary-CCPCH-LCR-parameterItem-CTCH-SetupRqstTDD
+
+Secondary-CCPCH-LCR-parameterItem-CTCH-SetupRqstTDD ::= SEQUENCE {
+ commonPhysicalChannelID CommonPhysicalChannelID,
+ tdd-ChannelisationCodeLCR TDD-ChannelisationCodeLCR,
+ timeslotLCR TimeSlotLCR,
+ midambleShiftLCR MidambleShiftLCR,
+ tdd-PhysicalChannelOffset TDD-PhysicalChannelOffset,
+ repetitionPeriod RepetitionPeriod,
+ repetitionLength RepetitionLength,
+ s-CCPCH-Power DL-Power,
+ s-CCPCH-TimeSlotFormat-LCR TDD-DL-DPCH-TimeSlotFormat-LCR,
+ iE-Extensions ProtocolExtensionContainer { { Secondary-CCPCH-LCR-parameterItem-CTCH-SetupRqstTDD-ExtIEs} } OPTIONAL,
+ ...
+}
+
+Secondary-CCPCH-LCR-parameterItem-CTCH-SetupRqstTDD-ExtIEs NBAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+PRACH-CTCH-SetupRqstTDD ::= SEQUENCE {
+ pRACH-Parameters-CTCH-SetupRqstTDD PRACH-Parameters-CTCH-SetupRqstTDD,
+ iE-Extensions ProtocolExtensionContainer { { PRACH-CTCH-SetupRqstTDD-ExtIEs } } OPTIONAL,
+ ...
+}
+
+PRACH-CTCH-SetupRqstTDD-ExtIEs NBAP-PROTOCOL-EXTENSION ::= {
+ { ID id-FPACH-LCR-Parameters-CTCH-SetupRqstTDD CRITICALITY reject EXTENSION FPACH-LCR-Parameters-CTCH-SetupRqstTDD PRESENCE optional },
+ -- Mandatory for 1.28Mcps TDD, Not Applicable to 3.84Mcps TDD
+ ...
+}
+
+PRACH-Parameters-CTCH-SetupRqstTDD ::= ProtocolIE-Single-Container {{ PRACH-ParametersIE-CTCH-SetupRqstTDD }}
+
+PRACH-ParametersIE-CTCH-SetupRqstTDD NBAP-PROTOCOL-IES ::= {
+ { ID id-PRACH-ParametersItem-CTCH-SetupRqstTDD CRITICALITY reject TYPE PRACH-ParametersItem-CTCH-SetupRqstTDD PRESENCE optional }|
+ { ID id-PRACH-LCR-ParametersList-CTCH-SetupRqstTDD CRITICALITY reject TYPE PRACH-LCR-ParametersList-CTCH-SetupRqstTDD PRESENCE optional }
+}
+
+
+PRACH-ParametersItem-CTCH-SetupRqstTDD ::= SEQUENCE {
+ commonPhysicalChannelID CommonPhysicalChannelID,
+ tFCS TFCS,
+ timeslot TimeSlot,
+ tdd-ChannelisationCode TDD-ChannelisationCode,
+ maxPRACH-MidambleShifts MaxPRACH-MidambleShifts,
+ pRACH-Midamble PRACH-Midamble,
+ rACH RACH-Parameter-CTCH-SetupRqstTDD,
+ iE-Extensions ProtocolExtensionContainer { { PRACH-ParametersItem-CTCH-SetupRqstTDD-ExtIEs} } OPTIONAL,
+ ...
+}
+
+PRACH-ParametersItem-CTCH-SetupRqstTDD-ExtIEs NBAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+RACH-Parameter-CTCH-SetupRqstTDD ::= ProtocolIE-Single-Container {{ RACH-ParameterIE-CTCH-SetupRqstTDD }}
+
+RACH-ParameterIE-CTCH-SetupRqstTDD NBAP-PROTOCOL-IES ::= {
+ { ID id-RACH-ParameterItem-CTCH-SetupRqstTDD CRITICALITY reject TYPE RACH-ParameterItem-CTCH-SetupRqstTDD PRESENCE mandatory }
+}
+
+RACH-ParameterItem-CTCH-SetupRqstTDD ::= SEQUENCE {
+ commonTransportChannelID CommonTransportChannelID,
+ uL-TransportFormatSet TransportFormatSet, -- For the UL
+ iE-Extensions ProtocolExtensionContainer { { RACH-ParameterItem-CTCH-SetupRqstTDD-ExtIEs} } OPTIONAL,
+ ...
+}
+
+RACH-ParameterItem-CTCH-SetupRqstTDD-ExtIEs NBAP-PROTOCOL-EXTENSION ::= {
+ { ID id-bindingID CRITICALITY ignore EXTENSION BindingID PRESENCE optional }|
+ -- Shall be ignored if bearer establishment with ALCAP.
+ { ID id-transportlayeraddress CRITICALITY ignore EXTENSION TransportLayerAddress PRESENCE optional },
+ -- Shall be ignored if bearer establishment with ALCAP.
+ ...
+}
+
+PRACH-LCR-ParametersList-CTCH-SetupRqstTDD ::= SEQUENCE (SIZE (1..maxNrOfPRACHLCRs)) OF PRACH-LCR-ParametersItem-CTCH-SetupRqstTDD
+
+PRACH-LCR-ParametersItem-CTCH-SetupRqstTDD ::= SEQUENCE {
+ commonPhysicalChannelID CommonPhysicalChannelID,
+ tFCS TFCS,
+ timeslotLCR TimeSlotLCR,
+ tdd-ChannelisationCodeLCR TDD-ChannelisationCodeLCR,
+ midambleShiftLCR MidambleShiftLCR,
+ rACH RACH-Parameter-CTCH-SetupRqstTDD,
+ iE-Extensions ProtocolExtensionContainer { { PRACH-LCR-ParametersItem-CTCH-SetupRqstTDD-ExtIEs} } OPTIONAL,
+ ...
+}
+
+PRACH-LCR-ParametersItem-CTCH-SetupRqstTDD-ExtIEs NBAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+FPACH-LCR-Parameters-CTCH-SetupRqstTDD ::= SEQUENCE {
+ commonPhysicalChannelID CommonPhysicalChannelID,
+ tdd-ChannelisationCodeLCR TDD-ChannelisationCodeLCR,
+ timeslotLCR TimeSlotLCR,
+ midambleShiftLCR MidambleShiftLCR,
+ fPACH-Power FPACH-Power,
+ iE-Extensions ProtocolExtensionContainer { { FPACH-LCR-ParametersItem-CTCH-SetupRqstTDD-ExtIEs} } OPTIONAL,
+ ...
+}
+
+FPACH-LCR-ParametersItem-CTCH-SetupRqstTDD-ExtIEs NBAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+-- **************************************************************
+--
+-- COMMON TRANSPORT CHANNEL SETUP RESPONSE
+--
+-- **************************************************************
+
+CommonTransportChannelSetupResponse ::= SEQUENCE {
+ protocolIEs ProtocolIE-Container {{CommonTransportChannelSetupResponse-IEs}},
+ protocolExtensions ProtocolExtensionContainer {{CommonTransportChannelSetupResponse-Extensions}} OPTIONAL,
+ ...
+}
+
+CommonTransportChannelSetupResponse-IEs NBAP-PROTOCOL-IES ::= {
+ { ID id-FACH-ParametersList-CTCH-SetupRsp CRITICALITY ignore TYPE FACH-CommonTransportChannel-InformationResponse PRESENCE optional }|
+ { ID id-PCH-Parameters-CTCH-SetupRsp CRITICALITY ignore TYPE CommonTransportChannel-InformationResponse PRESENCE optional }|
+ { ID id-RACH-Parameters-CTCH-SetupRsp CRITICALITY ignore TYPE CommonTransportChannel-InformationResponse PRESENCE optional }|
+ { ID id-CPCH-Parameters-CTCH-SetupRsp CRITICALITY ignore TYPE CommonTransportChannel-InformationResponse PRESENCE optional }|
+ { ID id-CriticalityDiagnostics CRITICALITY ignore TYPE CriticalityDiagnostics PRESENCE optional },
+ ...
+}
+
+CommonTransportChannelSetupResponse-Extensions NBAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+FACH-CommonTransportChannel-InformationResponse ::= SEQUENCE (SIZE (1..maxNrOfFACHs)) OF CommonTransportChannel-InformationResponse
+
+-- **************************************************************
+--
+-- COMMON TRANSPORT CHANNEL SETUP FAILURE
+--
+-- **************************************************************
+
+CommonTransportChannelSetupFailure ::= SEQUENCE {
+ protocolIEs ProtocolIE-Container {{CommonTransportChannelSetupFailure-IEs}},
+ protocolExtensions ProtocolExtensionContainer {{CommonTransportChannelSetupFailure-Extensions}} OPTIONAL,
+ ...
+}
+
+CommonTransportChannelSetupFailure-IEs NBAP-PROTOCOL-IES ::= {
+ { ID id-Cause CRITICALITY ignore TYPE Cause PRESENCE mandatory }|
+ { ID id-CriticalityDiagnostics CRITICALITY ignore TYPE CriticalityDiagnostics PRESENCE optional },
+ ...
+}
+
+CommonTransportChannelSetupFailure-Extensions NBAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+-- **************************************************************
+--
+-- COMMON TRANSPORT CHANNEL RECONFIGURATION REQUEST FDD
+--
+-- **************************************************************
+
+CommonTransportChannelReconfigurationRequestFDD ::= SEQUENCE {
+ protocolIEs ProtocolIE-Container {{CommonTransportChannelReconfigurationRequestFDD-IEs}},
+ protocolExtensions ProtocolExtensionContainer {{CommonTransportChannelReconfigurationRequestFDD-Extensions}} OPTIONAL,
+ ...
+}
+
+CommonTransportChannelReconfigurationRequestFDD-IEs NBAP-PROTOCOL-IES ::= {
+ { ID id-C-ID CRITICALITY reject TYPE C-ID PRESENCE mandatory }|
+ { ID id-ConfigurationGenerationID CRITICALITY reject TYPE ConfigurationGenerationID PRESENCE mandatory }|
+ { ID id-CommonPhysicalChannelType-CTCH-ReconfRqstFDD CRITICALITY reject TYPE CommonPhysicalChannelType-CTCH-ReconfRqstFDD PRESENCE mandatory },
+ ...
+}
+
+CommonTransportChannelReconfigurationRequestFDD-Extensions NBAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+CommonPhysicalChannelType-CTCH-ReconfRqstFDD ::= CHOICE {
+ secondary-CCPCH-parameters Secondary-CCPCHList-CTCH-ReconfRqstFDD,
+ pRACH-parameters PRACHList-CTCH-ReconfRqstFDD,
+ cPCH-parameters CPCHList-CTCH-ReconfRqstFDD,
+ ...
+}
+
+Secondary-CCPCHList-CTCH-ReconfRqstFDD ::= SEQUENCE {
+ fACH-ParametersList-CTCH-ReconfRqstFDD FACH-ParametersList-CTCH-ReconfRqstFDD OPTIONAL,
+ pCH-Parameters-CTCH-ReconfRqstFDD PCH-Parameters-CTCH-ReconfRqstFDD OPTIONAL,
+ pICH-Parameters-CTCH-ReconfRqstFDD PICH-Parameters-CTCH-ReconfRqstFDD OPTIONAL,
+ iE-Extensions ProtocolExtensionContainer { { Secondary-CCPCH-CTCH-ReconfRqstFDD-ExtIEs} } OPTIONAL,
+ ...
+}
+
+Secondary-CCPCH-CTCH-ReconfRqstFDD-ExtIEs NBAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+FACH-ParametersList-CTCH-ReconfRqstFDD ::= ProtocolIE-Single-Container {{ FACH-ParametersListIEs-CTCH-ReconfRqstFDD }}
+
+FACH-ParametersListIEs-CTCH-ReconfRqstFDD NBAP-PROTOCOL-IES ::= {
+ { ID id-FACH-ParametersListIE-CTCH-ReconfRqstFDD CRITICALITY reject TYPE FACH-ParametersListIE-CTCH-ReconfRqstFDD PRESENCE mandatory }
+}
+
+FACH-ParametersListIE-CTCH-ReconfRqstFDD ::= SEQUENCE (SIZE (1..maxFACHCell)) OF FACH-ParametersItem-CTCH-ReconfRqstFDD
+
+FACH-ParametersItem-CTCH-ReconfRqstFDD ::= SEQUENCE {
+ commonTransportChannelID CommonTransportChannelID,
+ maxFACH-Power DL-Power OPTIONAL,
+ toAWS ToAWS OPTIONAL,
+ toAWE ToAWE OPTIONAL,
+ iE-Extensions ProtocolExtensionContainer { { FACH-ParametersItem-CTCH-ReconfRqstFDD-ExtIEs} } OPTIONAL,
+ ...
+}
+
+FACH-ParametersItem-CTCH-ReconfRqstFDD-ExtIEs NBAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+PCH-Parameters-CTCH-ReconfRqstFDD ::= ProtocolIE-Single-Container {{ PCH-ParametersIE-CTCH-ReconfRqstFDD }}
+
+PCH-ParametersIE-CTCH-ReconfRqstFDD NBAP-PROTOCOL-IES ::= {
+ { ID id-PCH-ParametersItem-CTCH-ReconfRqstFDD CRITICALITY reject TYPE PCH-ParametersItem-CTCH-ReconfRqstFDD PRESENCE mandatory }
+}
+
+PCH-ParametersItem-CTCH-ReconfRqstFDD ::= SEQUENCE {
+ commonTransportChannelID CommonTransportChannelID,
+ pCH-Power DL-Power OPTIONAL,
+ toAWS ToAWS OPTIONAL,
+ toAWE ToAWE OPTIONAL,
+ iE-Extensions ProtocolExtensionContainer { { PCH-ParametersItem-CTCH-ReconfRqstFDD-ExtIEs} } OPTIONAL,
+ ...
+}
+
+PCH-ParametersItem-CTCH-ReconfRqstFDD-ExtIEs NBAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+PICH-Parameters-CTCH-ReconfRqstFDD ::= ProtocolIE-Single-Container {{ PICH-ParametersIE-CTCH-ReconfRqstFDD }}
+
+PICH-ParametersIE-CTCH-ReconfRqstFDD NBAP-PROTOCOL-IES ::= {
+ { ID id-PICH-ParametersItem-CTCH-ReconfRqstFDD CRITICALITY reject TYPE PICH-ParametersItem-CTCH-ReconfRqstFDD PRESENCE mandatory }
+}
+
+PICH-ParametersItem-CTCH-ReconfRqstFDD ::= SEQUENCE {
+ commonPhysicalChannelID CommonPhysicalChannelID,
+ pICH-Power PICH-Power OPTIONAL,
+ iE-Extensions ProtocolExtensionContainer { { PICH-ParametersItem-CTCH-ReconfRqstFDD-ExtIEs} } OPTIONAL,
+ ...
+}
+
+PICH-ParametersItem-CTCH-ReconfRqstFDD-ExtIEs NBAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+PRACHList-CTCH-ReconfRqstFDD ::= SEQUENCE {
+ pRACH-ParametersList-CTCH-ReconfRqstFDD PRACH-ParametersList-CTCH-ReconfRqstFDD OPTIONAL,
+ aICH-ParametersList-CTCH-ReconfRqstFDD AICH-ParametersList-CTCH-ReconfRqstFDD OPTIONAL,
+ iE-Extensions ProtocolExtensionContainer { { PRACH-CTCH-ReconfRqstFDD-ExtIEs} } OPTIONAL,
+ ...
+}
+
+PRACH-CTCH-ReconfRqstFDD-ExtIEs NBAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+PRACH-ParametersList-CTCH-ReconfRqstFDD ::= ProtocolIE-Single-Container {{ PRACH-ParametersListIEs-CTCH-ReconfRqstFDD }}
+
+PRACH-ParametersListIEs-CTCH-ReconfRqstFDD NBAP-PROTOCOL-IES ::= {
+ { ID id-PRACH-ParametersListIE-CTCH-ReconfRqstFDD CRITICALITY reject TYPE PRACH-ParametersListIE-CTCH-ReconfRqstFDD PRESENCE mandatory }
+}
+
+PRACH-ParametersListIE-CTCH-ReconfRqstFDD ::= SEQUENCE (SIZE (1..maxPRACHCell)) OF PRACH-ParametersItem-CTCH-ReconfRqstFDD
+
+PRACH-ParametersItem-CTCH-ReconfRqstFDD ::= SEQUENCE {
+ commonPhysicalChannelID CommonPhysicalChannelID,
+ preambleSignatures PreambleSignatures OPTIONAL,
+ allowedSlotFormatInformation AllowedSlotFormatInformationList-CTCH-ReconfRqstFDD OPTIONAL,
+ rACH-SubChannelNumbers RACH-SubChannelNumbers OPTIONAL,
+ iE-Extensions ProtocolExtensionContainer { { PRACH-ParametersItem-CTCH-ReconfRqstFDD-ExtIEs} } OPTIONAL,
+ ...
+}
+
+PRACH-ParametersItem-CTCH-ReconfRqstFDD-ExtIEs NBAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+AllowedSlotFormatInformationList-CTCH-ReconfRqstFDD ::= SEQUENCE (SIZE (1.. maxNrOfSlotFormatsPRACH)) OF AllowedSlotFormatInformationItem-CTCH-ReconfRqstFDD
+
+AllowedSlotFormatInformationItem-CTCH-ReconfRqstFDD ::= SEQUENCE {
+ rACH-SlotFormat RACH-SlotFormat,
+ iE-Extensions ProtocolExtensionContainer { { AllowedSlotFormatInformationItem-CTCH-ReconfRqstFDD-ExtIEs} } OPTIONAL,
+ ...
+}
+
+AllowedSlotFormatInformationItem-CTCH-ReconfRqstFDD-ExtIEs NBAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+AICH-ParametersList-CTCH-ReconfRqstFDD ::= ProtocolIE-Single-Container {{ AICH-ParametersListIEs-CTCH-ReconfRqstFDD }}
+
+AICH-ParametersListIEs-CTCH-ReconfRqstFDD NBAP-PROTOCOL-IES ::= {
+ { ID id-AICH-ParametersListIE-CTCH-ReconfRqstFDD CRITICALITY reject TYPE AICH-ParametersListIE-CTCH-ReconfRqstFDD PRESENCE mandatory }
+}
+
+AICH-ParametersListIE-CTCH-ReconfRqstFDD ::= SEQUENCE (SIZE (1..maxPRACHCell)) OF AICH-ParametersItem-CTCH-ReconfRqstFDD
+
+AICH-ParametersItem-CTCH-ReconfRqstFDD ::= SEQUENCE {
+ commonPhysicalChannelID CommonPhysicalChannelID,
+ aICH-Power AICH-Power OPTIONAL,
+ iE-Extensions ProtocolExtensionContainer { { AICH-ParametersItemIE-CTCH-ReconfRqstFDD-ExtIEs} } OPTIONAL,
+ ...
+}
+
+AICH-ParametersItemIE-CTCH-ReconfRqstFDD-ExtIEs NBAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+CPCHList-CTCH-ReconfRqstFDD ::= SEQUENCE {
+ cPCH-ParametersList-CTCH-ReconfRqstFDD CPCH-ParametersList-CTCH-ReconfRqstFDD OPTIONAL,
+ aP-AICH-ParametersList-CTCH-ReconfRqstFDD AP-AICH-ParametersList-CTCH-ReconfRqstFDD OPTIONAL,
+ cDCA-ICH-ParametersList-CTCH-ReconfRqstFDD CDCA-ICH-ParametersList-CTCH-ReconfRqstFDD OPTIONAL,
+ iE-Extensions ProtocolExtensionContainer { { CPCHListItem-CTCH-ReconfRqstFDD-ExtIEs} } OPTIONAL,
+ ...
+}
+
+CPCHListItem-CTCH-ReconfRqstFDD-ExtIEs NBAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+CPCH-ParametersList-CTCH-ReconfRqstFDD ::= ProtocolIE-Single-Container {{ CPCH-ParametersListIEs-CTCH-ReconfRqstFDD }}
+
+CPCH-ParametersListIEs-CTCH-ReconfRqstFDD NBAP-PROTOCOL-IES ::= {
+ { ID id-CPCH-ParametersListIE-CTCH-ReconfRqstFDD CRITICALITY reject TYPE CPCH-ParametersListIE-CTCH-ReconfRqstFDD PRESENCE mandatory }
+}
+
+CPCH-ParametersListIE-CTCH-ReconfRqstFDD ::= SEQUENCE (SIZE (1..maxNrOfCPCHs)) OF CPCH-ParametersItem-CTCH-ReconfRqstFDD
+
+CPCH-ParametersItem-CTCH-ReconfRqstFDD ::= SEQUENCE {
+ commonTransportChannelID CommonTransportChannelID,
+ uL-SIR UL-SIR OPTIONAL,
+ initialDL-transmissionPower DL-Power OPTIONAL,
+ maximumDLPower DL-Power OPTIONAL,
+ minimumDLPower DL-Power OPTIONAL,
+ iE-Extensions ProtocolExtensionContainer { { CPCH-ParametersItem-CTCH-ReconfRqstFDD-ExtIEs} } OPTIONAL,
+ ...
+}
+
+CPCH-ParametersItem-CTCH-ReconfRqstFDD-ExtIEs NBAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+AP-AICH-ParametersList-CTCH-ReconfRqstFDD ::= ProtocolIE-Single-Container {{ AP-AICH-ParametersListIEs-CTCH-ReconfRqstFDD }}
+
+AP-AICH-ParametersListIEs-CTCH-ReconfRqstFDD NBAP-PROTOCOL-IES ::= {
+ { ID id-AP-AICH-ParametersListIE-CTCH-ReconfRqstFDD CRITICALITY reject TYPE AP-AICH-ParametersListIE-CTCH-ReconfRqstFDD PRESENCE mandatory }
+}
+
+AP-AICH-ParametersListIE-CTCH-ReconfRqstFDD ::= SEQUENCE (SIZE (1..maxNrOfCPCHs)) OF AP-AICH-ParametersItem-CTCH-ReconfRqstFDD
+
+AP-AICH-ParametersItem-CTCH-ReconfRqstFDD ::= SEQUENCE {
+ commonPhysicalChannelID CommonPhysicalChannelID,
+ aP-AICH-Power AICH-Power OPTIONAL,
+ cSICH-Power AICH-Power OPTIONAL,
+ iE-Extensions ProtocolExtensionContainer { { AP-AICH-ParametersItemIE-CTCH-ReconfRqstFDD-ExtIEs} } OPTIONAL,
+ ...
+}
+
+AP-AICH-ParametersItemIE-CTCH-ReconfRqstFDD-ExtIEs NBAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+CDCA-ICH-ParametersList-CTCH-ReconfRqstFDD ::= ProtocolIE-Single-Container {{ CDCA-ICH-ParametersListIEs-CTCH-ReconfRqstFDD }}
+
+CDCA-ICH-ParametersListIEs-CTCH-ReconfRqstFDD NBAP-PROTOCOL-IES ::= {
+ { ID id-CDCA-ICH-ParametersListIE-CTCH-ReconfRqstFDD CRITICALITY reject TYPE CDCA-ICH-ParametersListIE-CTCH-ReconfRqstFDD PRESENCE mandatory }
+}
+
+CDCA-ICH-ParametersListIE-CTCH-ReconfRqstFDD ::= SEQUENCE (SIZE (1..maxNrOfCPCHs)) OF CDCA-ICH-ParametersItem-CTCH-ReconfRqstFDD
+
+CDCA-ICH-ParametersItem-CTCH-ReconfRqstFDD ::= SEQUENCE {
+ commonPhysicalChannelID CommonPhysicalChannelID,
+ cDCA-ICH-Power AICH-Power OPTIONAL,
+ iE-Extensions ProtocolExtensionContainer { { CDCA-ICH-ParametersItemIE-CTCH-ReconfRqstFDD-ExtIEs} } OPTIONAL,
+ ...
+}
+
+CDCA-ICH-ParametersItemIE-CTCH-ReconfRqstFDD-ExtIEs NBAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+-- **************************************************************
+--
+-- COMMON TRANSPORT CHANNEL RECONFIGURATION REQUEST TDD
+--
+-- **************************************************************
+
+CommonTransportChannelReconfigurationRequestTDD ::= SEQUENCE {
+ protocolIEs ProtocolIE-Container {{CommonTransportChannelReconfigurationRequestTDD-IEs}},
+ protocolExtensions ProtocolExtensionContainer {{CommonTransportChannelReconfigurationRequestTDD-Extensions}} OPTIONAL,
+ ...
+}
+
+CommonTransportChannelReconfigurationRequestTDD-IEs NBAP-PROTOCOL-IES ::= {
+ { ID id-C-ID CRITICALITY reject TYPE C-ID PRESENCE mandatory }|
+ { ID id-ConfigurationGenerationID CRITICALITY reject TYPE ConfigurationGenerationID PRESENCE mandatory }|
+ { ID id-Secondary-CCPCH-Parameters-CTCH-ReconfRqstTDD CRITICALITY reject TYPE Secondary-CCPCH-Parameters-CTCH-ReconfRqstTDD PRESENCE optional }|
+ { ID id-PICH-Parameters-CTCH-ReconfRqstTDD CRITICALITY reject TYPE PICH-Parameters-CTCH-ReconfRqstTDD PRESENCE optional }|
+ { ID id-FACH-ParametersList-CTCH-ReconfRqstTDD CRITICALITY reject TYPE FACH-ParametersList-CTCH-ReconfRqstTDD PRESENCE optional }|
+ { ID id-PCH-Parameters-CTCH-ReconfRqstTDD CRITICALITY reject TYPE PCH-Parameters-CTCH-ReconfRqstTDD PRESENCE optional },
+ ...
+}
+
+CommonTransportChannelReconfigurationRequestTDD-Extensions NBAP-PROTOCOL-EXTENSION ::= {
+ { ID id-FPACH-LCR-Parameters-CTCH-ReconfRqstTDD CRITICALITY reject EXTENSION FPACH-LCR-Parameters-CTCH-ReconfRqstTDD PRESENCE optional }, -- Mandatory For 1.28Mcps TDD, Not Applicable to 3.84Mcps TDD
+ ...
+}
+
+Secondary-CCPCH-Parameters-CTCH-ReconfRqstTDD::= SEQUENCE {
+ cCTrCH-ID CCTrCH-ID,
+ secondaryCCPCHList Secondary-CCPCHList-CTCH-ReconfRqstTDD OPTIONAL,
+ iE-Extensions ProtocolExtensionContainer { { Secondary-CCPCH-CTCH-ReconfRqstTDD-ExtIEs} } OPTIONAL,
+ ...
+}
+
+Secondary-CCPCH-CTCH-ReconfRqstTDD-ExtIEs NBAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+Secondary-CCPCHList-CTCH-ReconfRqstTDD ::= ProtocolIE-Single-Container {{ Secondary-CCPCHListIEs-CTCH-ReconfRqstTDD }}
+
+Secondary-CCPCHListIEs-CTCH-ReconfRqstTDD NBAP-PROTOCOL-IES ::= {
+ { ID id-Secondary-CCPCHListIE-CTCH-ReconfRqstTDD CRITICALITY reject TYPE Secondary-CCPCHListIE-CTCH-ReconfRqstTDD PRESENCE mandatory }
+}
+
+Secondary-CCPCHListIE-CTCH-ReconfRqstTDD ::= SEQUENCE (SIZE (1..maxNrOfSCCPCHs)) OF Secondary-CCPCHItem-CTCH-ReconfRqstTDD
+
+Secondary-CCPCHItem-CTCH-ReconfRqstTDD ::= SEQUENCE {
+ commonPhysicalChannelID CommonPhysicalChannelID,
+ sCCPCH-Power DL-Power OPTIONAL,
+ iE-Extensions ProtocolExtensionContainer { { Secondary-CCPCHItem-CTCH-ReconfRqstTDD-ExtIEs} } OPTIONAL,
+ ...
+}
+
+Secondary-CCPCHItem-CTCH-ReconfRqstTDD-ExtIEs NBAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+PICH-Parameters-CTCH-ReconfRqstTDD ::= SEQUENCE {
+ commonPhysicalChannelID CommonPhysicalChannelID,
+ pICH-Power PICH-Power OPTIONAL,
+ iE-Extensions ProtocolExtensionContainer { { PICH-Parameters-CTCH-ReconfRqstTDD-ExtIEs} } OPTIONAL,
+ ...
+}
+
+PICH-Parameters-CTCH-ReconfRqstTDD-ExtIEs NBAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+FACH-ParametersList-CTCH-ReconfRqstTDD ::= SEQUENCE (SIZE (0..maxNrOfFACHs)) OF FACH-ParametersItem-CTCH-ReconfRqstTDD
+
+FACH-ParametersItem-CTCH-ReconfRqstTDD ::= SEQUENCE {
+ commonTransportChannelID CommonTransportChannelID,
+ toAWS ToAWS OPTIONAL,
+ toAWE ToAWE OPTIONAL,
+ iE-Extensions ProtocolExtensionContainer { { FACH-ParametersItem-CTCH-ReconfRqstTDD-ExtIEs} } OPTIONAL,
+ ...
+}
+
+FACH-ParametersItem-CTCH-ReconfRqstTDD-ExtIEs NBAP-PROTOCOL-EXTENSION ::= {
+ { ID id-maxFACH-Power-LCR-CTCH-ReconfRqstTDD CRITICALITY reject EXTENSION DL-Power PRESENCE optional },
+ -- Applicable to 1.28Mcps TDD only
+ ...
+}
+
+PCH-Parameters-CTCH-ReconfRqstTDD ::= SEQUENCE {
+ commonTransportChannelID CommonTransportChannelID,
+ toAWS ToAWS OPTIONAL,
+ toAWE ToAWE OPTIONAL,
+ iE-Extensions ProtocolExtensionContainer { { PCH-Parameters-CTCH-ReconfRqstTDD-ExtIEs} } OPTIONAL,
+ ...
+}
+
+PCH-Parameters-CTCH-ReconfRqstTDD-ExtIEs NBAP-PROTOCOL-EXTENSION ::= {
+ { ID id-PCH-Power-LCR-CTCH-ReconfRqstTDD CRITICALITY reject EXTENSION DL-Power PRESENCE optional },
+ ... -- Applicable to 1.28Mcps TDD only
+}
+
+FPACH-LCR-Parameters-CTCH-ReconfRqstTDD ::= SEQUENCE {
+ commonPhysicalChannelId CommonPhysicalChannelID,
+ fPACHPower FPACH-Power OPTIONAL,
+ iE-Extensions ProtocolExtensionContainer { { FPACH-LCR-Parameters-CTCH-ReconfRqstTDD-ExtIEs} } OPTIONAL,
+ ...
+}
+
+FPACH-LCR-Parameters-CTCH-ReconfRqstTDD-ExtIEs NBAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+-- **************************************************************
+--
+-- COMMON TRANSPORT CHANNEL RECONFIGURATION RESPONSE
+--
+-- **************************************************************
+
+CommonTransportChannelReconfigurationResponse ::= SEQUENCE {
+ protocolIEs ProtocolIE-Container {{CommonTransportChannelReconfigurationResponse-IEs}},
+ protocolExtensions ProtocolExtensionContainer {{CommonTransportChannelReconfigurationResponse-Extensions}} OPTIONAL,
+ ...
+}
+
+CommonTransportChannelReconfigurationResponse-IEs NBAP-PROTOCOL-IES ::= {
+ { ID id-CriticalityDiagnostics CRITICALITY ignore TYPE CriticalityDiagnostics PRESENCE optional},
+ ...
+}
+
+CommonTransportChannelReconfigurationResponse-Extensions NBAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+-- **************************************************************
+--
+-- COMMON TRANSPORT CHANNEL RECONFIGURATION FAILURE
+--
+-- **************************************************************
+
+CommonTransportChannelReconfigurationFailure ::= SEQUENCE {
+ protocolIEs ProtocolIE-Container {{CommonTransportChannelReconfigurationFailure-IEs}},
+ protocolExtensions ProtocolExtensionContainer {{CommonTransportChannelReconfigurationFailure-Extensions}} OPTIONAL,
+ ...
+}
+
+CommonTransportChannelReconfigurationFailure-IEs NBAP-PROTOCOL-IES ::= {
+ { ID id-Cause CRITICALITY ignore TYPE Cause PRESENCE mandatory }|
+ { ID id-CriticalityDiagnostics CRITICALITY ignore TYPE CriticalityDiagnostics PRESENCE optional },
+ ...
+}
+
+CommonTransportChannelReconfigurationFailure-Extensions NBAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+-- **************************************************************
+--
+-- COMMON TRANSPORT CHANNEL DELETION REQUEST
+--
+-- **************************************************************
+
+CommonTransportChannelDeletionRequest ::= SEQUENCE {
+ protocolIEs ProtocolIE-Container {{CommonTransportChannelDeletionRequest-IEs}},
+ protocolExtensions ProtocolExtensionContainer {{CommonTransportChannelDeletionRequest-Extensions}} OPTIONAL,
+ ...
+}
+
+CommonTransportChannelDeletionRequest-IEs NBAP-PROTOCOL-IES ::= {
+ { ID id-C-ID CRITICALITY reject TYPE C-ID PRESENCE mandatory}|
+ { ID id-CommonPhysicalChannelID CRITICALITY reject TYPE CommonPhysicalChannelID PRESENCE mandatory}|
+ { ID id-ConfigurationGenerationID CRITICALITY reject TYPE ConfigurationGenerationID PRESENCE mandatory},
+ ...
+}
+
+CommonTransportChannelDeletionRequest-Extensions NBAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+-- **************************************************************
+--
+-- COMMON TRANSPORT CHANNEL DELETION RESPONSE
+--
+-- **************************************************************
+
+CommonTransportChannelDeletionResponse ::= SEQUENCE {
+ protocolIEs ProtocolIE-Container {{CommonTransportChannelDeletionResponse-IEs}},
+ protocolExtensions ProtocolExtensionContainer {{CommonTransportChannelDeletionResponse-Extensions}} OPTIONAL,
+ ...
+}
+
+CommonTransportChannelDeletionResponse-IEs NBAP-PROTOCOL-IES ::= {
+ { ID id-CriticalityDiagnostics CRITICALITY ignore TYPE CriticalityDiagnostics PRESENCE optional},
+ ...
+}
+
+CommonTransportChannelDeletionResponse-Extensions NBAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+-- **************************************************************
+--
+-- BLOCK RESOURCE REQUEST
+--
+-- **************************************************************
+
+BlockResourceRequest ::= SEQUENCE {
+ protocolIEs ProtocolIE-Container {{BlockResourceRequest-IEs}},
+ protocolExtensions ProtocolExtensionContainer {{BlockResourceRequest-Extensions}} OPTIONAL,
+ ...
+}
+
+BlockResourceRequest-IEs NBAP-PROTOCOL-IES ::= {
+ { ID id-C-ID CRITICALITY reject TYPE C-ID PRESENCE mandatory }|
+ { ID id-BlockingPriorityIndicator CRITICALITY reject TYPE BlockingPriorityIndicator PRESENCE mandatory }|
+ { ID id-ShutdownTimer CRITICALITY reject TYPE ShutdownTimer PRESENCE conditional },
+ -- The IE shall be present if the Blocking Priority Indicator IE indicates "Normal Priority"--
+ ...
+}
+
+BlockResourceRequest-Extensions NBAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+-- **************************************************************
+--
+-- BLOCK RESOURCE RESPONSE
+--
+-- **************************************************************
+
+BlockResourceResponse ::= SEQUENCE {
+ protocolIEs ProtocolIE-Container {{BlockResourceResponse-IEs}},
+ protocolExtensions ProtocolExtensionContainer {{BlockResourceResponse-Extensions}} OPTIONAL,
+ ...
+}
+
+BlockResourceResponse-IEs NBAP-PROTOCOL-IES ::= {
+ { ID id-CriticalityDiagnostics CRITICALITY ignore TYPE CriticalityDiagnostics PRESENCE optional},
+ ...
+}
+
+BlockResourceResponse-Extensions NBAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+-- **************************************************************
+--
+-- BLOCK RESOURCE FAILURE
+--
+-- **************************************************************
+
+BlockResourceFailure ::= SEQUENCE {
+ protocolIEs ProtocolIE-Container {{BlockResourceFailure-IEs}},
+ protocolExtensions ProtocolExtensionContainer {{BlockResourceFailure-Extensions}} OPTIONAL,
+ ...
+}
+
+BlockResourceFailure-IEs NBAP-PROTOCOL-IES ::= {
+ { ID id-Cause CRITICALITY ignore TYPE Cause PRESENCE mandatory }|
+ { ID id-CriticalityDiagnostics CRITICALITY ignore TYPE CriticalityDiagnostics PRESENCE optional },
+ ...
+}
+
+BlockResourceFailure-Extensions NBAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+-- **************************************************************
+--
+-- UNBLOCK RESOURCE INDICATION
+--
+-- **************************************************************
+
+UnblockResourceIndication ::= SEQUENCE {
+ protocolIEs ProtocolIE-Container {{UnblockResourceIndication-IEs}},
+ protocolExtensions ProtocolExtensionContainer {{UnblockResourceIndication-Extensions}} OPTIONAL,
+ ...
+}
+
+UnblockResourceIndication-IEs NBAP-PROTOCOL-IES ::= {
+ { ID id-C-ID CRITICALITY ignore TYPE C-ID PRESENCE mandatory},
+ ...
+}
+
+UnblockResourceIndication-Extensions NBAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+-- **************************************************************
+--
+-- AUDIT REQUIRED INDICATION
+--
+-- **************************************************************
+
+AuditRequiredIndication ::= SEQUENCE {
+ protocolIEs ProtocolIE-Container {{AuditRequiredIndication-IEs}},
+ protocolExtensions ProtocolExtensionContainer {{AuditRequiredIndication-Extensions}} OPTIONAL,
+ ...
+}
+
+AuditRequiredIndication-IEs NBAP-PROTOCOL-IES ::= {
+ ...
+}
+
+AuditRequiredIndication-Extensions NBAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+-- **************************************************************
+--
+-- AUDIT REQUEST
+--
+-- **************************************************************
+
+AuditRequest ::= SEQUENCE {
+ protocolIEs ProtocolIE-Container {{AuditRequest-IEs}},
+ protocolExtensions ProtocolExtensionContainer {{AuditRequest-Extensions}} OPTIONAL,
+ ...
+}
+
+AuditRequest-IEs NBAP-PROTOCOL-IES ::= {
+ { ID id-Start-Of-Audit-Sequence-Indicator CRITICALITY reject TYPE Start-Of-Audit-Sequence-Indicator PRESENCE mandatory },
+ ...
+}
+
+AuditRequest-Extensions NBAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+-- **************************************************************
+--
+-- AUDIT RESPONSE
+--
+-- **************************************************************
+
+AuditResponse ::= SEQUENCE {
+ protocolIEs ProtocolIE-Container {{AuditResponse-IEs}},
+ protocolExtensions ProtocolExtensionContainer {{AuditResponse-Extensions}} OPTIONAL,
+ ...
+}
+
+AuditResponse-IEs NBAP-PROTOCOL-IES ::= {
+ { ID id-End-Of-Audit-Sequence-Indicator CRITICALITY ignore TYPE End-Of-Audit-Sequence-Indicator PRESENCE mandatory }|
+ { ID id-Cell-InformationList-AuditRsp CRITICALITY ignore TYPE Cell-InformationList-AuditRsp PRESENCE optional }|
+ { ID id-CCP-InformationList-AuditRsp CRITICALITY ignore TYPE CCP-InformationList-AuditRsp PRESENCE optional }|
+ -- CCP (Communication Control Port) --
+ { ID id-Local-Cell-InformationList-AuditRsp CRITICALITY ignore TYPE Local-Cell-InformationList-AuditRsp PRESENCE optional }|
+ { ID id-Local-Cell-Group-InformationList-AuditRsp CRITICALITY ignore TYPE Local-Cell-Group-InformationList-AuditRsp PRESENCE optional }|
+ { ID id-CriticalityDiagnostics CRITICALITY ignore TYPE CriticalityDiagnostics PRESENCE optional },
+ ...
+}
+
+AuditResponse-Extensions NBAP-PROTOCOL-EXTENSION ::= {
+ { ID id-Power-Local-Cell-Group-InformationList-AuditRsp CRITICALITY ignore EXTENSION Power-Local-Cell-Group-InformationList-AuditRsp PRESENCE optional },
+ ...
+}
+
+Cell-InformationList-AuditRsp ::= SEQUENCE (SIZE (1..maxCellinNodeB)) OF ProtocolIE-Single-Container {{ Cell-InformationItemIE-AuditRsp}}
+
+Cell-InformationItemIE-AuditRsp NBAP-PROTOCOL-IES ::= {
+ { ID id-Cell-InformationItem-AuditRsp CRITICALITY ignore TYPE Cell-InformationItem-AuditRsp PRESENCE optional }
+}
+
+Cell-InformationItem-AuditRsp ::= SEQUENCE {
+ c-ID C-ID,
+ configurationGenerationID ConfigurationGenerationID,
+ resourceOperationalState ResourceOperationalState,
+ availabilityStatus AvailabilityStatus,
+ local-Cell-ID Local-Cell-ID,
+ primary-SCH-Information P-SCH-Information-AuditRsp OPTIONAL,
+ secondary-SCH-Information S-SCH-Information-AuditRsp OPTIONAL,
+ primary-CPICH-Information P-CPICH-Information-AuditRsp OPTIONAL,
+ secondary-CPICH-InformationList S-CPICH-InformationList-AuditRsp OPTIONAL,
+ primary-CCPCH-Information P-CCPCH-Information-AuditRsp OPTIONAL,
+ bCH-Information BCH-Information-AuditRsp OPTIONAL,
+ secondary-CCPCH-InformationList S-CCPCH-InformationList-AuditRsp OPTIONAL,
+ pCH-Information PCH-Information-AuditRsp OPTIONAL,
+ pICH-Information PICH-Information-AuditRsp OPTIONAL,
+ fACH-InformationList FACH-InformationList-AuditRsp OPTIONAL,
+ pRACH-InformationList PRACH-InformationList-AuditRsp OPTIONAL,
+ rACH-InformationList RACH-InformationList-AuditRsp OPTIONAL,
+ aICH-InformationList AICH-InformationList-AuditRsp OPTIONAL,
+ pCPCH-InformationList PCPCH-InformationList-AuditRsp OPTIONAL,
+ cPCH-InformationList CPCH-InformationList-AuditRsp OPTIONAL,
+ aP-AICH-InformationList AP-AICH-InformationList-AuditRsp OPTIONAL,
+ cDCA-ICH-InformationList CDCA-ICH-InformationList-AuditRsp OPTIONAL,
+ sCH-Information SCH-Information-AuditRsp OPTIONAL,
+ iE-Extensions ProtocolExtensionContainer { { Cell-InformationItem-AuditRsp-ExtIEs} } OPTIONAL,
+ ...
+}
+
+Cell-InformationItem-AuditRsp-ExtIEs NBAP-PROTOCOL-EXTENSION ::= {
+ { ID id-FPACH-LCR-InformationList-AuditRsp CRITICALITY ignore EXTENSION FPACH-LCR-InformationList-AuditRsp PRESENCE optional }|
+ -- Applicable to 1.28Mcps TDD only
+ { ID id-DwPCH-LCR-InformationList-AuditRsp CRITICALITY ignore EXTENSION Common-PhysicalChannel-Status-Information PRESENCE optional }|
+ -- Applicable to 1.28Mcps TDD only
+ { ID id-HSDSCH-Resources-Information-AuditRsp CRITICALITY ignore EXTENSION HS-DSCH-Resources-Information-AuditRsp PRESENCE optional },
+ ...
+}
+
+P-SCH-Information-AuditRsp ::= ProtocolIE-Single-Container {{ P-SCH-InformationIE-AuditRsp }}
+
+P-SCH-InformationIE-AuditRsp NBAP-PROTOCOL-IES ::= {
+ { ID id-P-SCH-Information CRITICALITY ignore TYPE Common-PhysicalChannel-Status-Information PRESENCE mandatory }
+}
+
+S-SCH-Information-AuditRsp ::= ProtocolIE-Single-Container {{ S-SCH-InformationIE-AuditRsp }}
+
+S-SCH-InformationIE-AuditRsp NBAP-PROTOCOL-IES ::= {
+ { ID id-S-SCH-Information CRITICALITY ignore TYPE Common-PhysicalChannel-Status-Information PRESENCE mandatory }
+}
+
+P-CPICH-Information-AuditRsp ::= ProtocolIE-Single-Container {{ P-CPICH-InformationIE-AuditRsp }}
+
+P-CPICH-InformationIE-AuditRsp NBAP-PROTOCOL-IES ::= {
+ { ID id-P-CPICH-Information CRITICALITY ignore TYPE Common-PhysicalChannel-Status-Information PRESENCE mandatory }
+}
+
+S-CPICH-InformationList-AuditRsp ::= SEQUENCE (SIZE (1..maxSCPICHCell)) OF ProtocolIE-Single-Container {{ S-CPICH-InformationItemIE-AuditRsp }}
+
+S-CPICH-InformationItemIE-AuditRsp NBAP-PROTOCOL-IES ::= {
+ { ID id-S-CPICH-Information CRITICALITY ignore TYPE Common-PhysicalChannel-Status-Information PRESENCE mandatory }
+}
+
+P-CCPCH-Information-AuditRsp ::= ProtocolIE-Single-Container {{ P-CCPCH-InformationIE-AuditRsp }}
+
+P-CCPCH-InformationIE-AuditRsp NBAP-PROTOCOL-IES ::= {
+ { ID id-P-CCPCH-Information CRITICALITY ignore TYPE Common-PhysicalChannel-Status-Information PRESENCE mandatory }
+}
+
+BCH-Information-AuditRsp ::= ProtocolIE-Single-Container {{ BCH-InformationIE-AuditRsp }}
+
+BCH-InformationIE-AuditRsp NBAP-PROTOCOL-IES ::= {
+ { ID id-BCH-Information CRITICALITY ignore TYPE Common-TransportChannel-Status-Information PRESENCE mandatory }
+}
+
+S-CCPCH-InformationList-AuditRsp ::= SEQUENCE (SIZE (1..maxSCCPCHCell)) OF ProtocolIE-Single-Container {{ S-CCPCH-InformationItemIE-AuditRsp }}
+
+S-CCPCH-InformationItemIE-AuditRsp NBAP-PROTOCOL-IES ::= {
+ { ID id-S-CCPCH-Information CRITICALITY ignore TYPE Common-PhysicalChannel-Status-Information PRESENCE mandatory }
+}
+PCH-Information-AuditRsp ::= ProtocolIE-Single-Container {{ PCH-InformationIE-AuditRsp }}
+
+PCH-InformationIE-AuditRsp NBAP-PROTOCOL-IES ::= {
+ { ID id-PCH-Information CRITICALITY ignore TYPE Common-TransportChannel-Status-Information PRESENCE mandatory }
+}
+
+PICH-Information-AuditRsp ::= ProtocolIE-Single-Container {{ PICH-InformationIE-AuditRsp }}
+
+PICH-InformationIE-AuditRsp NBAP-PROTOCOL-IES ::= {
+ { ID id-PICH-Information CRITICALITY ignore TYPE Common-PhysicalChannel-Status-Information PRESENCE mandatory }
+}
+
+FACH-InformationList-AuditRsp ::= SEQUENCE (SIZE (1..maxFACHCell)) OF ProtocolIE-Single-Container {{ FACH-InformationItemIE-AuditRsp }}
+
+FACH-InformationItemIE-AuditRsp NBAP-PROTOCOL-IES ::= {
+ { ID id-FACH-Information CRITICALITY ignore TYPE Common-TransportChannel-Status-Information PRESENCE mandatory }
+}
+
+PRACH-InformationList-AuditRsp ::= SEQUENCE (SIZE (1..maxPRACHCell)) OF ProtocolIE-Single-Container {{ PRACH-InformationItemIE-AuditRsp }}
+
+PRACH-InformationItemIE-AuditRsp NBAP-PROTOCOL-IES ::= {
+ { ID id-PRACH-Information CRITICALITY ignore TYPE Common-PhysicalChannel-Status-Information PRESENCE mandatory }
+}
+
+RACH-InformationList-AuditRsp ::= SEQUENCE (SIZE (1..maxRACHCell)) OF ProtocolIE-Single-Container {{ RACH-InformationItemIE-AuditRsp }}
+
+RACH-InformationItemIE-AuditRsp NBAP-PROTOCOL-IES ::= {
+ { ID id-RACH-Information CRITICALITY ignore TYPE Common-TransportChannel-Status-Information PRESENCE mandatory }
+}
+
+AICH-InformationList-AuditRsp ::= SEQUENCE (SIZE (1..maxPRACHCell)) OF ProtocolIE-Single-Container {{ AICH-InformationItemIE-AuditRsp }}
+
+AICH-InformationItemIE-AuditRsp NBAP-PROTOCOL-IES ::= {
+ { ID id-AICH-Information CRITICALITY ignore TYPE Common-PhysicalChannel-Status-Information PRESENCE mandatory }
+}
+
+PCPCH-InformationList-AuditRsp ::= SEQUENCE (SIZE (1..maxPCPCHCell)) OF ProtocolIE-Single-Container {{ PCPCH-InformationItemIE-AuditRsp }}
+
+PCPCH-InformationItemIE-AuditRsp NBAP-PROTOCOL-IES ::= {
+ { ID id-PCPCH-Information CRITICALITY ignore TYPE Common-PhysicalChannel-Status-Information PRESENCE optional }
+}
+
+CPCH-InformationList-AuditRsp ::= SEQUENCE (SIZE (1..maxCPCHCell)) OF ProtocolIE-Single-Container {{ CPCH-InformationItemIE-AuditRsp }}
+
+CPCH-InformationItemIE-AuditRsp NBAP-PROTOCOL-IES ::= {
+ { ID id-CPCH-Information CRITICALITY ignore TYPE Common-TransportChannel-Status-Information PRESENCE optional }
+}
+
+AP-AICH-InformationList-AuditRsp ::= SEQUENCE (SIZE (1..maxCPCHCell)) OF ProtocolIE-Single-Container {{ AP-AICH-InformationItemIE-AuditRsp }}
+
+AP-AICH-InformationItemIE-AuditRsp NBAP-PROTOCOL-IES ::= {
+ { ID id-AP-AICH-Information CRITICALITY ignore TYPE Common-PhysicalChannel-Status-Information PRESENCE mandatory }
+}
+
+CDCA-ICH-InformationList-AuditRsp ::= SEQUENCE (SIZE (1..maxCPCHCell)) OF ProtocolIE-Single-Container {{ CDCA-ICH-InformationItemIE-AuditRsp }}
+
+CDCA-ICH-InformationItemIE-AuditRsp NBAP-PROTOCOL-IES ::= {
+ { ID id-CDCA-ICH-Information CRITICALITY ignore TYPE Common-PhysicalChannel-Status-Information PRESENCE mandatory }
+}
+
+SCH-Information-AuditRsp ::= ProtocolIE-Single-Container {{ SCH-InformationIE-AuditRsp }}
+
+SCH-InformationIE-AuditRsp NBAP-PROTOCOL-IES ::= {
+ { ID id-SCH-Information CRITICALITY ignore TYPE Common-PhysicalChannel-Status-Information PRESENCE mandatory }
+}
+
+CCP-InformationList-AuditRsp ::=SEQUENCE (SIZE (1..maxCCPinNodeB)) OF ProtocolIE-Single-Container {{ CCP-InformationItemIE-AuditRsp }}
+
+CCP-InformationItemIE-AuditRsp NBAP-PROTOCOL-IES ::= {
+ {ID id-CCP-InformationItem-AuditRsp CRITICALITY ignore TYPE CCP-InformationItem-AuditRsp PRESENCE mandatory}
+}
+
+CCP-InformationItem-AuditRsp ::= SEQUENCE {
+ communicationControlPortID CommunicationControlPortID,
+ resourceOperationalState ResourceOperationalState,
+ availabilityStatus AvailabilityStatus,
+ iE-Extensions ProtocolExtensionContainer {{ CCP-InformationItem-AuditRsp-ExtIEs }} OPTIONAL,
+ ...
+}
+
+CCP-InformationItem-AuditRsp-ExtIEs NBAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+FPACH-LCR-InformationList-AuditRsp ::= SEQUENCE (SIZE (1..maxFPACHCell)) OF ProtocolIE-Single-Container {{ FPACH-LCR-InformationItemIE-AuditRsp }}
+
+FPACH-LCR-InformationItemIE-AuditRsp NBAP-PROTOCOL-IES ::= {
+ { ID id-FPACH-LCR-Information-AuditRsp CRITICALITY ignore TYPE Common-PhysicalChannel-Status-Information PRESENCE mandatory }
+}
+
+HS-DSCH-Resources-Information-AuditRsp ::= SEQUENCE {
+ resourceOperationalState ResourceOperationalState,
+ availabilityStatus AvailabilityStatus,
+ iE-Extensions ProtocolExtensionContainer {{ HS-DSCH-Resources-Information-AuditRsp-ExtIEs }} OPTIONAL,
+ ...
+}
+
+HS-DSCH-Resources-Information-AuditRsp-ExtIEs NBAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+Local-Cell-InformationList-AuditRsp ::=SEQUENCE (SIZE (1..maxLocalCellinNodeB)) OF ProtocolIE-Single-Container {{ Local-Cell-InformationItemIE-AuditRsp }}
+
+Local-Cell-InformationItemIE-AuditRsp NBAP-PROTOCOL-IES ::= {
+ { ID id-Local-Cell-InformationItem-AuditRsp CRITICALITY ignore TYPE Local-Cell-InformationItem-AuditRsp PRESENCE mandatory}
+}
+
+Local-Cell-InformationItem-AuditRsp ::= SEQUENCE {
+ local-Cell-ID Local-Cell-ID,
+ dl-or-global-capacityCredit DL-or-Global-CapacityCredit,
+ ul-capacityCredit UL-CapacityCredit OPTIONAL,
+ commonChannelsCapacityConsumptionLaw CommonChannelsCapacityConsumptionLaw,
+ dedicatedChannelsCapacityConsumptionLaw DedicatedChannelsCapacityConsumptionLaw,
+ maximumDL-PowerCapability MaximumDL-PowerCapability OPTIONAL,
+ minSpreadingFactor MinSpreadingFactor OPTIONAL,
+ minimumDL-PowerCapability MinimumDL-PowerCapability OPTIONAL,
+ local-Cell-Group-ID Local-Cell-ID OPTIONAL,
+ iE-Extensions ProtocolExtensionContainer {{ Local-Cell-InformationItem-AuditRsp-ExtIEs}} OPTIONAL,
+ ...
+}
+
+Local-Cell-InformationItem-AuditRsp-ExtIEs NBAP-PROTOCOL-EXTENSION ::= {
+ { ID id-ReferenceClockAvailability CRITICALITY ignore EXTENSION ReferenceClockAvailability PRESENCE optional }|
+ { ID id-Power-Local-Cell-Group-ID CRITICALITY ignore EXTENSION Local-Cell-ID PRESENCE optional }|
+ { ID id-HSDPA-Capability CRITICALITY ignore EXTENSION HSDPA-Capability PRESENCE optional },
+ ...
+}
+
+Local-Cell-Group-InformationList-AuditRsp ::= SEQUENCE (SIZE (1..maxLocalCellinNodeB)) OF ProtocolIE-Single-Container {{ Local-Cell-Group-InformationItemIE-AuditRsp }}
+
+Local-Cell-Group-InformationItemIE-AuditRsp NBAP-PROTOCOL-IES ::= {
+ { ID id-Local-Cell-Group-InformationItem-AuditRsp CRITICALITY ignore TYPE Local-Cell-Group-InformationItem-AuditRsp PRESENCE mandatory}
+}
+
+Local-Cell-Group-InformationItem-AuditRsp ::= SEQUENCE {
+ local-Cell-Group-ID Local-Cell-ID,
+ dl-or-global-capacityCredit DL-or-Global-CapacityCredit,
+ ul-capacityCredit UL-CapacityCredit OPTIONAL,
+ commonChannelsCapacityConsumptionLaw CommonChannelsCapacityConsumptionLaw,
+ dedicatedChannelsCapacityConsumptionLaw DedicatedChannelsCapacityConsumptionLaw,
+ iE-Extensions ProtocolExtensionContainer {{ Local-Cell-Group-InformationItem-AuditRsp-ExtIEs}} OPTIONAL,
+ ...
+}
+
+Local-Cell-Group-InformationItem-AuditRsp-ExtIEs NBAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+Power-Local-Cell-Group-InformationList-AuditRsp ::= SEQUENCE (SIZE (1..maxLocalCellinNodeB)) OF ProtocolIE-Single-Container {{ Power-Local-Cell-Group-InformationItemIE-AuditRsp }}
+
+Power-Local-Cell-Group-InformationItemIE-AuditRsp NBAP-PROTOCOL-IES ::= {
+ { ID id-Power-Local-Cell-Group-InformationItem-AuditRsp CRITICALITY ignore TYPE Power-Local-Cell-Group-InformationItem-AuditRsp PRESENCE mandatory}
+}
+
+Power-Local-Cell-Group-InformationItem-AuditRsp ::= SEQUENCE {
+ power-Local-Cell-Group-ID Local-Cell-ID,
+ maximumDL-PowerCapability MaximumDL-PowerCapability,
+ iE-Extensions ProtocolExtensionContainer {{ Power-Local-Cell-Group-InformationItem-AuditRsp-ExtIEs}} OPTIONAL,
+ ...
+}
+
+Power-Local-Cell-Group-InformationItem-AuditRsp-ExtIEs NBAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+-- **************************************************************
+--
+-- AUDIT FAILURE
+--
+-- **************************************************************
+
+AuditFailure ::= SEQUENCE {
+ protocolIEs ProtocolIE-Container {{AuditFailure-IEs}},
+ protocolExtensions ProtocolExtensionContainer {{AuditFailure-Extensions}} OPTIONAL,
+ ...
+}
+
+AuditFailure-IEs NBAP-PROTOCOL-IES ::= {
+ { ID id-Cause CRITICALITY ignore TYPE Cause PRESENCE mandatory }|
+ { ID id-CriticalityDiagnostics CRITICALITY ignore TYPE CriticalityDiagnostics PRESENCE optional },
+ ...
+}
+
+AuditFailure-Extensions NBAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+-- **************************************************************
+--
+-- COMMON MEASUREMENT INITIATION REQUEST
+--
+-- **************************************************************
+
+CommonMeasurementInitiationRequest ::= SEQUENCE {
+ protocolIEs ProtocolIE-Container {{CommonMeasurementInitiationRequest-IEs}},
+ protocolExtensions ProtocolExtensionContainer {{CommonMeasurementInitiationRequest-Extensions}} OPTIONAL,
+ ...
+}
+
+CommonMeasurementInitiationRequest-IEs NBAP-PROTOCOL-IES ::= {
+ { ID id-MeasurementID CRITICALITY reject TYPE MeasurementID PRESENCE mandatory }|
+ { ID id-CommonMeasurementObjectType-CM-Rqst CRITICALITY reject TYPE CommonMeasurementObjectType-CM-Rqst PRESENCE mandatory }|
+ { ID id-CommonMeasurementType CRITICALITY reject TYPE CommonMeasurementType PRESENCE mandatory }|
+ { ID id-MeasurementFilterCoefficient CRITICALITY reject TYPE MeasurementFilterCoefficient PRESENCE optional }|
+ { ID id-ReportCharacteristics CRITICALITY reject TYPE ReportCharacteristics PRESENCE mandatory }|
+ { ID id-SFNReportingIndicator CRITICALITY reject TYPE FNReportingIndicator PRESENCE mandatory }|
+ { ID id-SFN CRITICALITY reject TYPE SFN PRESENCE optional },
+ ...
+}
+
+CommonMeasurementInitiationRequest-Extensions NBAP-PROTOCOL-EXTENSION ::= {
+ {ID id-CommonMeasurementAccuracy CRITICALITY reject EXTENSION CommonMeasurementAccuracy PRESENCE optional},
+ ...
+}
+
+CommonMeasurementObjectType-CM-Rqst ::= CHOICE {
+ cell Cell-CM-Rqst,
+ rACH RACH-CM-Rqst,
+ cPCH CPCH-CM-Rqst,
+ ...
+}
+
+Cell-CM-Rqst ::= SEQUENCE {
+ c-ID C-ID,
+ timeSlot TimeSlot OPTIONAL, -- Applicable to 3.84Mcps TDD only
+ iE-Extensions ProtocolExtensionContainer { { CellItem-CM-Rqst-ExtIEs} } OPTIONAL,
+ ...
+}
+
+CellItem-CM-Rqst-ExtIEs NBAP-PROTOCOL-EXTENSION ::= {
+ { ID id-TimeSlotLCR-CM-Rqst CRITICALITY reject EXTENSION TimeSlotLCR PRESENCE optional }|
+ -- Applicable to 1.28Mcps TDD only
+ {ID id-NeighbouringCellMeasurementInformation CRITICALITY ignore EXTENSION NeighbouringCellMeasurementInformation PRESENCE optional },
+ ...
+}
+
+RACH-CM-Rqst ::= SEQUENCE {
+ c-ID C-ID,
+ commonTransportChannelID CommonTransportChannelID,
+ iE-Extensions ProtocolExtensionContainer { { RACHItem-CM-Rqst-ExtIEs} } OPTIONAL,
+ ...
+}
+
+RACHItem-CM-Rqst-ExtIEs NBAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+CPCH-CM-Rqst ::= SEQUENCE {
+ c-ID C-ID,
+ commonTransportChannelID CommonTransportChannelID,
+ spreadingfactor MinUL-ChannelisationCodeLength OPTIONAL,
+ iE-Extensions ProtocolExtensionContainer { { CPCHItem-CM-Rqst-ExtIEs} } OPTIONAL,
+ ...
+}
+
+CPCHItem-CM-Rqst-ExtIEs NBAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+-- **************************************************************
+--
+-- COMMON MEASUREMENT INITIATION RESPONSE
+--
+-- **************************************************************
+
+CommonMeasurementInitiationResponse ::= SEQUENCE {
+ protocolIEs ProtocolIE-Container {{CommonMeasurementInitiationResponse-IEs}},
+ protocolExtensions ProtocolExtensionContainer {{CommonMeasurementInitiationResponse-Extensions}} OPTIONAL,
+ ...
+}
+
+CommonMeasurementInitiationResponse-IEs NBAP-PROTOCOL-IES ::= {
+ { ID id-MeasurementID CRITICALITY ignore TYPE MeasurementID PRESENCE mandatory }|
+ { ID id-CommonMeasurementObjectType-CM-Rsp CRITICALITY ignore TYPE CommonMeasurementObjectType-CM-Rsp PRESENCE optional }|
+ { ID id-SFN CRITICALITY ignore TYPE SFN PRESENCE optional }|
+ { ID id-CriticalityDiagnostics CRITICALITY ignore TYPE CriticalityDiagnostics PRESENCE optional },
+ ...
+}
+
+CommonMeasurementInitiationResponse-Extensions NBAP-PROTOCOL-EXTENSION ::= {
+ {ID id-CommonMeasurementAccuracy CRITICALITY ignore EXTENSION CommonMeasurementAccuracy PRESENCE optional},
+ ...
+}
+
+CommonMeasurementObjectType-CM-Rsp ::= CHOICE {
+ cell Cell-CM-Rsp,
+ rACH RACH-CM-Rsp,
+ cPCH CPCH-CM-Rsp,
+ ...
+ }
+
+Cell-CM-Rsp ::= SEQUENCE {
+ commonMeasurementValue CommonMeasurementValue,
+ iE-Extensions ProtocolExtensionContainer { { CellItem-CM-Rsp-ExtIEs} } OPTIONAL,
+ ...
+ }
+
+CellItem-CM-Rsp-ExtIEs NBAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+RACH-CM-Rsp ::= SEQUENCE {
+ commonMeasurementValue CommonMeasurementValue,
+ iE-Extensions ProtocolExtensionContainer { { RACHItem-CM-Rsp-ExtIEs} } OPTIONAL,
+ ...
+ }
+
+RACHItem-CM-Rsp-ExtIEs NBAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+CPCH-CM-Rsp ::= SEQUENCE {
+ commonMeasurementValue CommonMeasurementValue,
+ iE-Extensions ProtocolExtensionContainer { { CPCHItem-CM-Rsp-ExtIEs} } OPTIONAL,
+ ...
+ }
+
+CPCHItem-CM-Rsp-ExtIEs NBAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+-- **************************************************************
+--
+-- COMMON MEASUREMENT INITIATION FAILURE
+--
+-- **************************************************************
+
+CommonMeasurementInitiationFailure ::= SEQUENCE {
+ protocolIEs ProtocolIE-Container {{CommonMeasurementInitiationFailure-IEs}},
+ protocolExtensions ProtocolExtensionContainer {{CommonMeasurementInitiationFailure-Extensions}} OPTIONAL,
+ ...
+}
+
+CommonMeasurementInitiationFailure-IEs NBAP-PROTOCOL-IES ::= {
+ { ID id-MeasurementID CRITICALITY ignore TYPE MeasurementID PRESENCE mandatory }|
+ { ID id-Cause CRITICALITY ignore TYPE Cause PRESENCE mandatory }|
+ { ID id-CriticalityDiagnostics CRITICALITY ignore TYPE CriticalityDiagnostics PRESENCE optional },
+ ...
+}
+
+CommonMeasurementInitiationFailure-Extensions NBAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+-- **************************************************************
+--
+-- COMMON MEASUREMENT REPORT
+--
+-- **************************************************************
+
+CommonMeasurementReport ::= SEQUENCE {
+ protocolIEs ProtocolIE-Container {{CommonMeasurementReport-IEs}},
+ protocolExtensions ProtocolExtensionContainer {{CommonMeasurementReport-Extensions}} OPTIONAL,
+ ...
+}
+
+CommonMeasurementReport-IEs NBAP-PROTOCOL-IES ::= {
+ { ID id-MeasurementID CRITICALITY ignore TYPE MeasurementID PRESENCE mandatory }|
+ { ID id-CommonMeasurementObjectType-CM-Rprt CRITICALITY ignore TYPE CommonMeasurementObjectType-CM-Rprt PRESENCE mandatory }|
+ { ID id-SFN CRITICALITY ignore TYPE SFN PRESENCE optional },
+ ...
+}
+
+CommonMeasurementReport-Extensions NBAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+CommonMeasurementObjectType-CM-Rprt ::= CHOICE {
+ cell Cell-CM-Rprt,
+ rACH RACH-CM-Rprt,
+ cPCH CPCH-CM-Rprt,
+ ...
+ }
+
+Cell-CM-Rprt ::= SEQUENCE {
+ commonMeasurementValueInformation CommonMeasurementValueInformation,
+ iE-Extensions ProtocolExtensionContainer {{ CellItem-CM-Rprt-ExtIEs }} OPTIONAL,
+ ...
+
+ }
+
+CellItem-CM-Rprt-ExtIEs NBAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+
+RACH-CM-Rprt ::= SEQUENCE {
+ commonMeasurementValueInformation CommonMeasurementValueInformation,
+ iE-Extensions ProtocolExtensionContainer {{ RACHItem-CM-Rprt-ExtIEs }} OPTIONAL,
+ ...
+ }
+
+RACHItem-CM-Rprt-ExtIEs NBAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+CPCH-CM-Rprt ::= SEQUENCE {
+ commonMeasurementValueInformation CommonMeasurementValueInformation,
+ iE-Extensions ProtocolExtensionContainer {{ CPCHItem-CM-Rprt-ExtIEs }} OPTIONAL,
+ ...
+ }
+
+CPCHItem-CM-Rprt-ExtIEs NBAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+-- **************************************************************
+--
+-- COMMON MEASUREMENT TERMINATION REQUEST
+--
+-- **************************************************************
+
+CommonMeasurementTerminationRequest ::= SEQUENCE {
+ protocolIEs ProtocolIE-Container {{CommonMeasurementTerminationRequest-IEs}},
+ protocolExtensions ProtocolExtensionContainer {{CommonMeasurementTerminationRequest-Extensions}} OPTIONAL,
+ ...
+}
+
+CommonMeasurementTerminationRequest-IEs NBAP-PROTOCOL-IES ::= {
+ { ID id-MeasurementID CRITICALITY ignore TYPE MeasurementID PRESENCE mandatory},
+ ...
+}
+
+CommonMeasurementTerminationRequest-Extensions NBAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+-- **************************************************************
+--
+-- COMMON MEASUREMENT FAILURE INDICATION
+--
+-- **************************************************************
+
+CommonMeasurementFailureIndication ::= SEQUENCE {
+ protocolIEs ProtocolIE-Container {{CommonMeasurementFailureIndication-IEs}},
+ protocolExtensions ProtocolExtensionContainer {{CommonMeasurementFailureIndication-Extensions}} OPTIONAL,
+ ...
+}
+
+CommonMeasurementFailureIndication-IEs NBAP-PROTOCOL-IES ::= {
+ { ID id-MeasurementID CRITICALITY ignore TYPE MeasurementID PRESENCE mandatory }|
+ { ID id-Cause CRITICALITY ignore TYPE Cause PRESENCE mandatory },
+ ...
+}
+
+CommonMeasurementFailureIndication-Extensions NBAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+-- **************************************************************
+--
+-- CELL SETUP REQUEST FDD
+--
+-- **************************************************************
+
+CellSetupRequestFDD ::= SEQUENCE {
+ protocolIEs ProtocolIE-Container {{CellSetupRequestFDD-IEs}},
+ protocolExtensions ProtocolExtensionContainer {{CellSetupRequestFDD-Extensions}} OPTIONAL,
+ ...
+}
+
+CellSetupRequestFDD-IEs NBAP-PROTOCOL-IES ::= {
+ { ID id-Local-Cell-ID CRITICALITY reject TYPE Local-Cell-ID PRESENCE mandatory }|
+ { ID id-C-ID CRITICALITY reject TYPE C-ID PRESENCE mandatory }|
+ { ID id-ConfigurationGenerationID CRITICALITY reject TYPE ConfigurationGenerationID PRESENCE mandatory }|
+ { ID id-T-Cell CRITICALITY reject TYPE T-Cell PRESENCE mandatory }|
+ { ID id-UARFCNforNu CRITICALITY reject TYPE UARFCN PRESENCE mandatory }|
+ { ID id-UARFCNforNd CRITICALITY reject TYPE UARFCN PRESENCE mandatory }|
+ { ID id-MaximumTransmissionPower CRITICALITY reject TYPE MaximumTransmissionPower PRESENCE mandatory }|
+ { ID id-Closed-Loop-Timing-Adjustment-Mode CRITICALITY reject TYPE Closedlooptimingadjustmentmode PRESENCE optional }|
+ { ID id-PrimaryScramblingCode CRITICALITY reject TYPE PrimaryScramblingCode PRESENCE mandatory }|
+ { ID id-Synchronisation-Configuration-Cell-SetupRqst CRITICALITY reject TYPE Synchronisation-Configuration-Cell-SetupRqst PRESENCE mandatory }|
+ { ID id-DL-TPC-Pattern01Count CRITICALITY reject TYPE DL-TPC-Pattern01Count PRESENCE mandatory }|
+ { ID id-PrimarySCH-Information-Cell-SetupRqstFDD CRITICALITY reject TYPE PrimarySCH-Information-Cell-SetupRqstFDD PRESENCE mandatory }|
+ { ID id-SecondarySCH-Information-Cell-SetupRqstFDD CRITICALITY reject TYPE SecondarySCH-Information-Cell-SetupRqstFDD PRESENCE mandatory }|
+ { ID id-PrimaryCPICH-Information-Cell-SetupRqstFDD CRITICALITY reject TYPE PrimaryCPICH-Information-Cell-SetupRqstFDD PRESENCE mandatory }|
+ { ID id-SecondaryCPICH-InformationList-Cell-SetupRqstFDD CRITICALITY reject TYPE SecondaryCPICH-InformationList-Cell-SetupRqstFDD PRESENCE optional }|
+ { ID id-PrimaryCCPCH-Information-Cell-SetupRqstFDD CRITICALITY reject TYPE PrimaryCCPCH-Information-Cell-SetupRqstFDD PRESENCE mandatory }|
+ { ID id-Limited-power-increase-information-Cell-SetupRqstFDD CRITICALITY reject TYPE Limited-power-increase-information-Cell-SetupRqstFDD PRESENCE mandatory },
+ ...
+}
+
+CellSetupRequestFDD-Extensions NBAP-PROTOCOL-EXTENSION ::= {
+ {ID id-IPDLParameter-Information-Cell-SetupRqstFDD CRITICALITY reject EXTENSION IPDLParameter-Information-Cell-SetupRqstFDD PRESENCE optional }|
+ {ID id-PDSCH-Information-Cell-SetupRqstFDD CRITICALITY reject EXTENSION PDSCH-Information-Cell-SetupRqstFDD PRESENCE optional },
+ ...
+}
+
+Synchronisation-Configuration-Cell-SetupRqst ::= SEQUENCE {
+ n-INSYNC-IND N-INSYNC-IND,
+ n-OUTSYNC-IND N-OUTSYNC-IND,
+ t-RLFAILURE T-RLFAILURE,
+ iE-Extensions ProtocolExtensionContainer { { Synchronisation-Configuration-Cell-SetupRqst-ExtIEs} } OPTIONAL,
+ ...
+}
+
+Synchronisation-Configuration-Cell-SetupRqst-ExtIEs NBAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+PrimarySCH-Information-Cell-SetupRqstFDD ::= SEQUENCE {
+ commonPhysicalChannelID CommonPhysicalChannelID,
+ primarySCH-Power DL-Power,
+ tSTD-Indicator TSTD-Indicator,
+ iE-Extensions ProtocolExtensionContainer { { PrimarySCH-Information-Cell-SetupRqstFDD-ExtIEs} } OPTIONAL,
+ ...
+}
+
+PrimarySCH-Information-Cell-SetupRqstFDD-ExtIEs NBAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+SecondarySCH-Information-Cell-SetupRqstFDD ::= SEQUENCE {
+ commonPhysicalChannelID CommonPhysicalChannelID,
+ secondarySCH-Power DL-Power,
+ tSTD-Indicator TSTD-Indicator,
+ iE-Extensions ProtocolExtensionContainer { { SecondarySCH-Information-Cell-SetupRqstFDD-ExtIEs} } OPTIONAL,
+ ...
+}
+
+SecondarySCH-Information-Cell-SetupRqstFDD-ExtIEs NBAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+PrimaryCPICH-Information-Cell-SetupRqstFDD ::= SEQUENCE {
+ commonPhysicalChannelID CommonPhysicalChannelID,
+ primaryCPICH-Power PrimaryCPICH-Power,
+ transmitDiversityIndicator TransmitDiversityIndicator,
+ iE-Extensions ProtocolExtensionContainer { { PrimaryCPICH-Information-Cell-SetupRqstFDD-ExtIEs} } OPTIONAL,
+ ...
+}
+
+PrimaryCPICH-Information-Cell-SetupRqstFDD-ExtIEs NBAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+SecondaryCPICH-InformationList-Cell-SetupRqstFDD ::= SEQUENCE (SIZE (1..maxSCPICHCell)) OF ProtocolIE-Single-Container{{ SecondaryCPICH-InformationItemIE-Cell-SetupRqstFDD }}
+
+SecondaryCPICH-InformationItemIE-Cell-SetupRqstFDD NBAP-PROTOCOL-IES ::= {
+ { ID id-SecondaryCPICH-InformationItem-Cell-SetupRqstFDD CRITICALITY reject TYPE SecondaryCPICH-InformationItem-Cell-SetupRqstFDD PRESENCE mandatory}
+}
+
+SecondaryCPICH-InformationItem-Cell-SetupRqstFDD ::= SEQUENCE {
+ commonPhysicalChannelID CommonPhysicalChannelID,
+ dl-ScramblingCode DL-ScramblingCode,
+ fDD-DL-ChannelisationCodeNumber FDD-DL-ChannelisationCodeNumber,
+ secondaryCPICH-Power DL-Power,
+ transmitDiversityIndicator TransmitDiversityIndicator,
+ iE-Extensions ProtocolExtensionContainer { { SecondaryCPICH-InformationItem-Cell-SetupRqstFDD-ExtIEs} } OPTIONAL,
+ ...
+}
+
+SecondaryCPICH-InformationItem-Cell-SetupRqstFDD-ExtIEs NBAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+PrimaryCCPCH-Information-Cell-SetupRqstFDD ::= SEQUENCE {
+ commonPhysicalChannelID CommonPhysicalChannelID,
+ bCH-information BCH-Information-Cell-SetupRqstFDD,
+ sTTD-Indicator STTD-Indicator,
+ iE-Extensions ProtocolExtensionContainer { { PrimaryCCPCH-Information-Cell-SetupRqstFDD-ExtIEs} } OPTIONAL,
+ ...
+}
+
+PrimaryCCPCH-Information-Cell-SetupRqstFDD-ExtIEs NBAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+BCH-Information-Cell-SetupRqstFDD ::= SEQUENCE {
+ commonTransportChannelID CommonTransportChannelID,
+ bCH-Power DL-Power,
+ iE-Extensions ProtocolExtensionContainer { { BCH-Information-Cell-SetupRqstFDD-ExtIEs} } OPTIONAL,
+ ...
+ }
+
+BCH-Information-Cell-SetupRqstFDD-ExtIEs NBAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+Limited-power-increase-information-Cell-SetupRqstFDD ::= SEQUENCE {
+ powerRaiseLimit PowerRaiseLimit,
+ dLPowerAveragingWindowSize DLPowerAveragingWindowSize,
+ iE-Extensions ProtocolExtensionContainer { { Limited-power-increase-information-Cell-SetupRqstFDD-ExtIEs} } OPTIONAL,
+ ...
+}
+
+Limited-power-increase-information-Cell-SetupRqstFDD-ExtIEs NBAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+IPDLParameter-Information-Cell-SetupRqstFDD::= SEQUENCE {
+ iPDL-FDD-Parameters IPDL-FDD-Parameters,
+ iPDL-Indicator IPDL-Indicator,
+ iE-Extensions ProtocolExtensionContainer { { IPDLParameter-Information-Cell-SetupRqstFDD-ExtIEs} } OPTIONAL,
+ ...
+}
+
+IPDLParameter-Information-Cell-SetupRqstFDD-ExtIEs NBAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+PDSCH-Information-Cell-SetupRqstFDD ::= SEQUENCE {
+ maximum-PDSCH-Power Maximum-PDSCH-Power,
+ iE-Extensions ProtocolExtensionContainer { { PDSCH-Information-Cell-SetupRqstFDD-ExtIEs} } OPTIONAL,
+ ...
+}
+
+PDSCH-Information-Cell-SetupRqstFDD-ExtIEs NBAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+-- **************************************************************
+--
+-- CELL SETUP REQUEST TDD
+--
+-- **************************************************************
+
+CellSetupRequestTDD ::= SEQUENCE {
+ protocolIEs ProtocolIE-Container {{CellSetupRequestTDD-IEs}},
+ protocolExtensions ProtocolExtensionContainer {{CellSetupRequestTDD-Extensions}} OPTIONAL,
+ ...
+}
+
+CellSetupRequestTDD-IEs NBAP-PROTOCOL-IES ::= {
+ { ID id-Local-Cell-ID CRITICALITY reject TYPE Local-Cell-ID PRESENCE mandatory }|
+ { ID id-C-ID CRITICALITY reject TYPE C-ID PRESENCE mandatory }|
+ { ID id-ConfigurationGenerationID CRITICALITY reject TYPE ConfigurationGenerationID PRESENCE mandatory }|
+ { ID id-UARFCNforNt CRITICALITY reject TYPE UARFCN PRESENCE mandatory }|
+ { ID id-CellParameterID CRITICALITY reject TYPE CellParameterID PRESENCE mandatory }|
+ { ID id-MaximumTransmissionPower CRITICALITY reject TYPE MaximumTransmissionPower PRESENCE mandatory }|
+ { ID id-TransmissionDiversityApplied CRITICALITY reject TYPE TransmissionDiversityApplied PRESENCE mandatory }|
+ { ID id-SyncCase CRITICALITY reject TYPE SyncCase PRESENCE mandatory }|
+ { ID id-Synchronisation-Configuration-Cell-SetupRqst CRITICALITY reject TYPE Synchronisation-Configuration-Cell-SetupRqst PRESENCE mandatory }|
+ { ID id-DPCHConstant CRITICALITY reject TYPE ConstantValue PRESENCE mandatory }| -- This IE shall be ignored by the Node B.
+ { ID id-PUSCHConstant CRITICALITY reject TYPE ConstantValue PRESENCE mandatory }| -- This IE shall be ignored by the Node B.
+ { ID id-PRACHConstant CRITICALITY reject TYPE ConstantValue PRESENCE mandatory }| -- This IE shall be ignored by the Node B.
+ { ID id-TimingAdvanceApplied CRITICALITY reject TYPE TimingAdvanceApplied PRESENCE mandatory }|
+ { ID id-SCH-Information-Cell-SetupRqstTDD CRITICALITY reject TYPE SCH-Information-Cell-SetupRqstTDD PRESENCE optional }| -- Mandatory for 3.84Mcps TDD, Not Applicable to 1.28Mcps TDD
+ { ID id-PCCPCH-Information-Cell-SetupRqstTDD CRITICALITY reject TYPE PCCPCH-Information-Cell-SetupRqstTDD PRESENCE optional }| -- Mandatory for 3.84Mcps TDD, Not Applicable to 1.28Mcps TDD
+ { ID id-TimeSlotConfigurationList-Cell-SetupRqstTDD CRITICALITY reject TYPE TimeSlotConfigurationList-Cell-SetupRqstTDD PRESENCE optional }, -- Mandatory for 3.84Mcps TDD, Not Applicable to 1.28Mcps TDD
+ ...
+}
+
+CellSetupRequestTDD-Extensions NBAP-PROTOCOL-EXTENSION ::= {
+ { ID id-TimeSlotConfigurationList-LCR-Cell-SetupRqstTDD CRITICALITY reject EXTENSION TimeSlotConfigurationList-LCR-Cell-SetupRqstTDD PRESENCE optional }| -- Mandatory for 1.28Mcps TDD, Not Applicable to 3.84Mcps TDD
+ { ID id-PCCPCH-LCR-Information-Cell-SetupRqstTDD CRITICALITY reject EXTENSION PCCPCH-LCR-Information-Cell-SetupRqstTDD PRESENCE optional }| -- Mandatory for 1.28Mcps TDD, Not Applicable to 3.84Mcps TDD
+ { ID id-DwPCH-LCR-Information-Cell-SetupRqstTDD CRITICALITY reject EXTENSION DwPCH-LCR-Information-Cell-SetupRqstTDD PRESENCE optional }| -- Mandatory for 1.28Mcps TDD, Not Applicable to 3.84Mcps TDD
+ { ID id-ReferenceSFNoffset CRITICALITY ignore EXTENSION ReferenceSFNoffset PRESENCE optional }|
+ { ID id-IPDLParameter-Information-Cell-SetupRqstTDD CRITICALITY reject EXTENSION IPDLParameter-Information-Cell-SetupRqstTDD PRESENCE optional }| -- Applicable to 3.84Mcps TDD only
+ { ID id-IPDLParameter-Information-LCR-Cell-SetupRqstTDD CRITICALITY reject EXTENSION IPDLParameter-Information-LCR-Cell-SetupRqstTDD PRESENCE optional }, -- Applicable to 1.28Mcps TDD only
+ ...
+}
+
+
+SCH-Information-Cell-SetupRqstTDD ::= SEQUENCE {
+ commonPhysicalChannelID CommonPhysicalChannelID,
+ syncCaseIndicator SyncCaseIndicator-Cell-SetupRqstTDD-PSCH,
+ sCH-Power DL-Power,
+ tSTD-Indicator TSTD-Indicator,
+ iE-Extensions ProtocolExtensionContainer { { SCH-Information-Cell-SetupRqstTDD-ExtIEs} } OPTIONAL,
+ ...
+}
+
+SCH-Information-Cell-SetupRqstTDD-ExtIEs NBAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+SyncCaseIndicator-Cell-SetupRqstTDD-PSCH ::= ProtocolIE-Single-Container {{ SyncCaseIndicatorIE-Cell-SetupRqstTDD-PSCH }}
+
+SyncCaseIndicatorIE-Cell-SetupRqstTDD-PSCH NBAP-PROTOCOL-IES ::= {
+ { ID id-SyncCaseIndicatorItem-Cell-SetupRqstTDD-PSCH CRITICALITY reject TYPE SyncCaseIndicatorItem-Cell-SetupRqstTDD-PSCH PRESENCE mandatory }
+}
+
+SyncCaseIndicatorItem-Cell-SetupRqstTDD-PSCH ::= CHOICE {
+ case1 Case1-Cell-SetupRqstTDD,
+ case2 Case2-Cell-SetupRqstTDD,
+ ...
+}
+
+Case1-Cell-SetupRqstTDD ::= SEQUENCE {
+ timeSlot TimeSlot,
+ iE-Extensions ProtocolExtensionContainer { { Case1Item-Cell-SetupRqstTDD-ExtIEs} } OPTIONAL,
+ ...
+}
+
+Case1Item-Cell-SetupRqstTDD-ExtIEs NBAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+Case2-Cell-SetupRqstTDD ::= SEQUENCE {
+ sCH-TimeSlot SCH-TimeSlot,
+ iE-Extensions ProtocolExtensionContainer { { Case2Item-Cell-SetupRqstTDD-ExtIEs} } OPTIONAL,
+ ...
+}
+
+Case2Item-Cell-SetupRqstTDD-ExtIEs NBAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+
+PCCPCH-Information-Cell-SetupRqstTDD ::= SEQUENCE {
+ commonPhysicalChannelID CommonPhysicalChannelID,
+ tdd-PhysicalChannelOffset TDD-PhysicalChannelOffset,
+ repetitionPeriod RepetitionPeriod,
+ repetitionLength RepetitionLength,
+ pCCPCH-Power PCCPCH-Power,
+ sCTD-Indicator SCTD-Indicator,
+ iE-Extensions ProtocolExtensionContainer { { PCCPCH-Information-Cell-SetupRqstTDD-ExtIEs} } OPTIONAL,
+ ...
+}
+
+PCCPCH-Information-Cell-SetupRqstTDD-ExtIEs NBAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+TimeSlotConfigurationList-Cell-SetupRqstTDD ::= SEQUENCE (SIZE (1..15)) OF TimeSlotConfigurationItem-Cell-SetupRqstTDD
+
+TimeSlotConfigurationItem-Cell-SetupRqstTDD ::= SEQUENCE {
+ timeSlot TimeSlot,
+ timeSlotStatus TimeSlotStatus,
+ timeSlotDirection TimeSlotDirection,
+ iE-Extensions ProtocolExtensionContainer { { TimeSlotConfigurationItem-Cell-SetupRqstTDD-ExtIEs} } OPTIONAL,
+ ...
+}
+
+TimeSlotConfigurationItem-Cell-SetupRqstTDD-ExtIEs NBAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+TimeSlotConfigurationList-LCR-Cell-SetupRqstTDD ::= SEQUENCE (SIZE (1..7)) OF TimeSlotConfigurationItem-LCR-Cell-SetupRqstTDD
+
+TimeSlotConfigurationItem-LCR-Cell-SetupRqstTDD ::= SEQUENCE {
+ timeSlotLCR TimeSlotLCR,
+ timeSlotStatus TimeSlotStatus,
+ timeSlotDirection TimeSlotDirection,
+ iE-Extensions ProtocolExtensionContainer { { TimeSlotConfigurationItem-LCR-Cell-SetupRqstTDD-ExtIEs} } OPTIONAL,
+ ...
+}
+
+TimeSlotConfigurationItem-LCR-Cell-SetupRqstTDD-ExtIEs NBAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+PCCPCH-LCR-Information-Cell-SetupRqstTDD ::= SEQUENCE {
+ commonPhysicalChannelID CommonPhysicalChannelID,
+ tdd-PhysicalChannelOffset TDD-PhysicalChannelOffset,
+ repetitionPeriod RepetitionPeriod,
+ repetitionLength RepetitionLength,
+ pCCPCH-Power PCCPCH-Power,
+ sCTD-Indicator SCTD-Indicator,
+ tSTD-Indicator TSTD-Indicator,
+ iE-Extensions ProtocolExtensionContainer { { PCCPCH-LCR-Information-Cell-SetupRqstTDD-ExtIEs} } OPTIONAL,
+ ...
+}
+
+PCCPCH-LCR-Information-Cell-SetupRqstTDD-ExtIEs NBAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+DwPCH-LCR-Information-Cell-SetupRqstTDD ::= SEQUENCE {
+ commonPhysicalChannelId CommonPhysicalChannelID,
+ tSTD-Indicator TSTD-Indicator,
+ dwPCH-Power DwPCH-Power,
+ iE-Extensions ProtocolExtensionContainer { { DwPCH-LCR-Information-Cell-SetupRqstTDD-ExtIEs} } OPTIONAL,
+ ...
+}
+
+DwPCH-LCR-Information-Cell-SetupRqstTDD-ExtIEs NBAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+IPDLParameter-Information-Cell-SetupRqstTDD ::= SEQUENCE {
+ iPDL-TDD-Parameters IPDL-TDD-Parameters,
+ iPDL-Indicator IPDL-Indicator,
+ iE-Extensions ProtocolExtensionContainer { { IPDLParameter-Information-Cell-SetupRqstTDD-ExtIEs} } OPTIONAL,
+ ...
+}
+
+IPDLParameter-Information-Cell-SetupRqstTDD-ExtIEs NBAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+IPDLParameter-Information-LCR-Cell-SetupRqstTDD ::= SEQUENCE {
+ iPDL-TDD-Parameters-LCR IPDL-TDD-Parameters-LCR,
+ iPDL-Indicator IPDL-Indicator,
+ iE-Extensions ProtocolExtensionContainer { { IPDLParameter-Information-LCR-Cell-SetupRqstTDD-ExtIEs} } OPTIONAL,
+ ...
+}
+
+IPDLParameter-Information-LCR-Cell-SetupRqstTDD-ExtIEs NBAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+-- **************************************************************
+--
+-- CELL SETUP RESPONSE
+--
+-- **************************************************************
+
+CellSetupResponse ::= SEQUENCE {
+ protocolIEs ProtocolIE-Container {{CellSetupResponse-IEs}},
+ protocolExtensions ProtocolExtensionContainer {{CellSetupResponse-Extensions}} OPTIONAL,
+ ...
+}
+
+CellSetupResponse-IEs NBAP-PROTOCOL-IES ::= {
+ { ID id-CriticalityDiagnostics CRITICALITY ignore TYPE CriticalityDiagnostics PRESENCE optional},
+ ...
+}
+
+CellSetupResponse-Extensions NBAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+-- **************************************************************
+--
+-- CELL SETUP FAILURE
+--
+-- **************************************************************
+
+CellSetupFailure ::= SEQUENCE {
+ protocolIEs ProtocolIE-Container {{CellSetupFailure-IEs}},
+ protocolExtensions ProtocolExtensionContainer {{CellSetupFailure-Extensions}} OPTIONAL,
+ ...
+}
+
+CellSetupFailure-IEs NBAP-PROTOCOL-IES ::= {
+ { ID id-Cause CRITICALITY ignore TYPE Cause PRESENCE mandatory }|
+ { ID id-CriticalityDiagnostics CRITICALITY ignore TYPE CriticalityDiagnostics PRESENCE optional },
+ ...
+}
+
+CellSetupFailure-Extensions NBAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+-- **************************************************************
+--
+-- CELL RECONFIGURATION REQUEST FDD
+--
+-- **************************************************************
+
+CellReconfigurationRequestFDD ::= SEQUENCE {
+ protocolIEs ProtocolIE-Container {{CellReconfigurationRequestFDD-IEs}},
+ protocolExtensions ProtocolExtensionContainer {{CellReconfigurationRequestFDD-Extensions}} OPTIONAL,
+ ...
+}
+
+CellReconfigurationRequestFDD-IEs NBAP-PROTOCOL-IES ::= {
+ { ID id-C-ID CRITICALITY reject TYPE C-ID PRESENCE mandatory }|
+ { ID id-ConfigurationGenerationID CRITICALITY reject TYPE ConfigurationGenerationID PRESENCE mandatory }|
+ { ID id-MaximumTransmissionPower CRITICALITY reject TYPE MaximumTransmissionPower PRESENCE optional }|
+ { ID id-Synchronisation-Configuration-Cell-ReconfRqst CRITICALITY reject TYPE Synchronisation-Configuration-Cell-ReconfRqst PRESENCE optional }|
+ { ID id-PrimarySCH-Information-Cell-ReconfRqstFDD CRITICALITY reject TYPE PrimarySCH-Information-Cell-ReconfRqstFDD PRESENCE optional }|
+ { ID id-SecondarySCH-Information-Cell-ReconfRqstFDD CRITICALITY reject TYPE SecondarySCH-Information-Cell-ReconfRqstFDD PRESENCE optional }|
+ { ID id-PrimaryCPICH-Information-Cell-ReconfRqstFDD CRITICALITY reject TYPE PrimaryCPICH-Information-Cell-ReconfRqstFDD PRESENCE optional }|
+ { ID id-SecondaryCPICH-InformationList-Cell-ReconfRqstFDD CRITICALITY reject TYPE SecondaryCPICH-InformationList-Cell-ReconfRqstFDD PRESENCE optional }|
+ { ID id-PrimaryCCPCH-Information-Cell-ReconfRqstFDD CRITICALITY reject TYPE PrimaryCCPCH-Information-Cell-ReconfRqstFDD PRESENCE optional },
+ ...
+}
+
+CellReconfigurationRequestFDD-Extensions NBAP-PROTOCOL-EXTENSION ::= {
+ {ID id-IPDLParameter-Information-Cell-ReconfRqstFDD CRITICALITY reject EXTENSION IPDLParameter-Information-Cell-ReconfRqstFDD PRESENCE optional }|
+ {ID id-PDSCH-Information-Cell-ReconfRqstFDD CRITICALITY reject EXTENSION PDSCH-Information-Cell-ReconfRqstFDD PRESENCE optional },
+ ...
+}
+
+Synchronisation-Configuration-Cell-ReconfRqst ::= SEQUENCE {
+ n-INSYNC-IND N-INSYNC-IND,
+ n-OUTSYNC-IND N-OUTSYNC-IND,
+ t-RLFAILURE T-RLFAILURE,
+ iE-Extensions ProtocolExtensionContainer { { Synchronisation-Configuration-Cell-ReconfRqst-ExtIEs} } OPTIONAL,
+ ...
+}
+
+Synchronisation-Configuration-Cell-ReconfRqst-ExtIEs NBAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+PrimarySCH-Information-Cell-ReconfRqstFDD ::= SEQUENCE {
+ commonPhysicalChannelID CommonPhysicalChannelID,
+ primarySCH-Power DL-Power,
+ iE-Extensions ProtocolExtensionContainer { { PrimarySCH-Information-Cell-ReconfRqstFDD-ExtIEs} } OPTIONAL,
+ ...
+ }
+
+PrimarySCH-Information-Cell-ReconfRqstFDD-ExtIEs NBAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+SecondarySCH-Information-Cell-ReconfRqstFDD ::= SEQUENCE {
+ commonPhysicalChannelID CommonPhysicalChannelID,
+ secondarySCH-Power DL-Power,
+ iE-Extensions ProtocolExtensionContainer { { SecondarySCH-Information-Cell-ReconfRqstFDD-ExtIEs} } OPTIONAL,
+ ...
+ }
+
+SecondarySCH-Information-Cell-ReconfRqstFDD-ExtIEs NBAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+PrimaryCPICH-Information-Cell-ReconfRqstFDD ::= SEQUENCE {
+ commonPhysicalChannelID CommonPhysicalChannelID,
+ primaryCPICH-Power PrimaryCPICH-Power,
+ iE-Extensions ProtocolExtensionContainer { { PrimaryCPICH-Information-Cell-ReconfRqstFDD-ExtIEs} } OPTIONAL,
+ ...
+ }
+
+PrimaryCPICH-Information-Cell-ReconfRqstFDD-ExtIEs NBAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+SecondaryCPICH-InformationList-Cell-ReconfRqstFDD ::= SEQUENCE (SIZE (1..maxSCPICHCell)) OF ProtocolIE-Single-Container{{ SecondaryCPICH-InformationItemIE-Cell-ReconfRqstFDD }}
+
+SecondaryCPICH-InformationItemIE-Cell-ReconfRqstFDD NBAP-PROTOCOL-IES ::= {
+ { ID id-SecondaryCPICH-InformationItem-Cell-ReconfRqstFDD CRITICALITY reject TYPE SecondaryCPICH-InformationItem-Cell-ReconfRqstFDD PRESENCE mandatory }
+}
+
+SecondaryCPICH-InformationItem-Cell-ReconfRqstFDD ::= SEQUENCE {
+ commonPhysicalChannelID CommonPhysicalChannelID,
+ secondaryCPICH-Power DL-Power,
+ iE-Extensions ProtocolExtensionContainer { { SecondaryCPICH-InformationItem-Cell-ReconfRqstFDD-ExtIEs} } OPTIONAL,
+ ...
+ }
+
+SecondaryCPICH-InformationItem-Cell-ReconfRqstFDD-ExtIEs NBAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+PrimaryCCPCH-Information-Cell-ReconfRqstFDD ::= SEQUENCE {
+ bCH-information BCH-information-Cell-ReconfRqstFDD,
+ iE-Extensions ProtocolExtensionContainer { { PrimaryCCPCH-Information-Cell-ReconfRqstFDD-ExtIEs} } OPTIONAL,
+ ...
+ }
+
+PrimaryCCPCH-Information-Cell-ReconfRqstFDD-ExtIEs NBAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+BCH-information-Cell-ReconfRqstFDD ::= SEQUENCE {
+ commonTransportChannelID CommonTransportChannelID,
+ bCH-Power DL-Power,
+ iE-Extensions ProtocolExtensionContainer { { BCH-information-Cell-ReconfRqstFDD-ExtIEs} } OPTIONAL,
+ ...
+ }
+
+BCH-information-Cell-ReconfRqstFDD-ExtIEs NBAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+IPDLParameter-Information-Cell-ReconfRqstFDD::= SEQUENCE {
+ iPDL-FDD-Parameters IPDL-FDD-Parameters OPTIONAL,
+ iPDL-Indicator IPDL-Indicator,
+ iE-Extensions ProtocolExtensionContainer { { IPDLParameter-Information-Cell-ReconfRqstFDD-ExtIEs} } OPTIONAL,
+ ...
+}
+
+IPDLParameter-Information-Cell-ReconfRqstFDD-ExtIEs NBAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+PDSCH-Information-Cell-ReconfRqstFDD ::= SEQUENCE {
+ maximumPDSCH-Power Maximum-PDSCH-Power,
+ iE-Extensions ProtocolExtensionContainer { { PDSCH-Information-Cell-ReconfRqstFDD-ExtIEs} } OPTIONAL,
+ ...
+}
+
+PDSCH-Information-Cell-ReconfRqstFDD-ExtIEs NBAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+-- **************************************************************
+--
+-- CELL RECONFIGURATION REQUEST TDD
+--
+-- **************************************************************
+
+CellReconfigurationRequestTDD ::= SEQUENCE {
+ protocolIEs ProtocolIE-Container {{CellReconfigurationRequestTDD-IEs}},
+ protocolExtensions ProtocolExtensionContainer {{CellReconfigurationRequestTDD-Extensions}} OPTIONAL,
+ ...
+}
+
+CellReconfigurationRequestTDD-IEs NBAP-PROTOCOL-IES ::= {
+ { ID id-C-ID CRITICALITY reject TYPE C-ID PRESENCE mandatory }|
+ { ID id-ConfigurationGenerationID CRITICALITY reject TYPE ConfigurationGenerationID PRESENCE mandatory }|
+ { ID id-Synchronisation-Configuration-Cell-ReconfRqst CRITICALITY reject TYPE Synchronisation-Configuration-Cell-ReconfRqst PRESENCE optional }|
+ { ID id-TimingAdvanceApplied CRITICALITY reject TYPE TimingAdvanceApplied PRESENCE optional }|
+ { ID id-SCH-Information-Cell-ReconfRqstTDD CRITICALITY reject TYPE SCH-Information-Cell-ReconfRqstTDD PRESENCE optional }|
+ -- Applicable to 3.84Mcps TDD only
+ { ID id-PCCPCH-Information-Cell-ReconfRqstTDD CRITICALITY reject TYPE PCCPCH-Information-Cell-ReconfRqstTDD PRESENCE optional }|
+ { ID id-MaximumTransmissionPower CRITICALITY reject TYPE MaximumTransmissionPower PRESENCE optional }|
+ { ID id-DPCHConstant CRITICALITY reject TYPE ConstantValue PRESENCE optional }|
+ -- This IE shall be ignored by the Node B.
+ { ID id-PUSCHConstant CRITICALITY reject TYPE ConstantValue PRESENCE optional }|
+ -- This IE shall be ignored by the Node B.
+ { ID id-PRACHConstant CRITICALITY reject TYPE ConstantValue PRESENCE optional }|
+ -- This IE shall be ignored by the Node B.
+ { ID id-TimeSlotConfigurationList-Cell-ReconfRqstTDD CRITICALITY reject TYPE TimeSlotConfigurationList-Cell-ReconfRqstTDD PRESENCE optional },
+ -- Mandatory for 3.84Mcps TDD only. Not Applicable to 1.28Mcps TDD.
+ ...
+}
+
+CellReconfigurationRequestTDD-Extensions NBAP-PROTOCOL-EXTENSION ::= {
+ { ID id-TimeSlotConfigurationList-LCR-Cell-ReconfRqstTDD CRITICALITY reject EXTENSION TimeSlotConfigurationList-LCR-Cell-ReconfRqstTDD PRESENCE optional }| -- Mandatory for 1.28Mcps TDD, Not Applicable to 3.84Mcps TDD
+ { ID id-DwPCH-LCR-Information-Cell-ReconfRqstTDD CRITICALITY reject EXTENSION DwPCH-LCR-Information-Cell-ReconfRqstTDD PRESENCE optional }| -- Mandatory for 1.28Mcps TDD, Not Applicable to 3.84Mcps TDD
+ { ID id-IPDLParameter-Information-Cell-ReconfRqstTDD CRITICALITY reject EXTENSION IPDLParameter-Information-Cell-ReconfRqstTDD PRESENCE optional }| -- Applicable to 3.84Mcps TDD only
+ { ID id-IPDLParameter-Information-LCR-Cell-ReconfRqstTDD CRITICALITY reject EXTENSION IPDLParameter-Information-LCR-Cell-ReconfRqstTDD PRESENCE optional }, -- Applicable to 1.28Mcps TDD only
+ ...
+}
+
+SCH-Information-Cell-ReconfRqstTDD ::= SEQUENCE {
+ commonPhysicalChannelID CommonPhysicalChannelID,
+ sCH-Power DL-Power,
+ iE-Extensions ProtocolExtensionContainer { { PSCH-Information-Cell-ReconfRqstTDD-ExtIEs} } OPTIONAL,
+ ...
+}
+
+PSCH-Information-Cell-ReconfRqstTDD-ExtIEs NBAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+PCCPCH-Information-Cell-ReconfRqstTDD ::= SEQUENCE {
+ commonPhysicalChannelID CommonPhysicalChannelID,
+ pCCPCH-Power PCCPCH-Power,
+ iE-Extensions ProtocolExtensionContainer { { PCCPCH-Information-Cell-ReconfRqstTDD-ExtIEs} } OPTIONAL,
+ ...
+}
+
+PCCPCH-Information-Cell-ReconfRqstTDD-ExtIEs NBAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+TimeSlotConfigurationList-Cell-ReconfRqstTDD ::= SEQUENCE (SIZE (1..15)) OF TimeSlotConfigurationItem-Cell-ReconfRqstTDD
+
+TimeSlotConfigurationItem-Cell-ReconfRqstTDD ::= SEQUENCE {
+ timeSlot TimeSlot,
+ timeSlotStatus TimeSlotStatus,
+ timeSlotDirection TimeSlotDirection,
+ iE-Extensions ProtocolExtensionContainer { { TimeSlotConfigurationItem-Cell-ReconfRqstTDD-ExtIEs} } OPTIONAL,
+ ...
+ }
+
+TimeSlotConfigurationItem-Cell-ReconfRqstTDD-ExtIEs NBAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+TimeSlotConfigurationList-LCR-Cell-ReconfRqstTDD ::= SEQUENCE (SIZE (1..7)) OF TimeSlotConfigurationItem-LCR-Cell-ReconfRqstTDD
+
+TimeSlotConfigurationItem-LCR-Cell-ReconfRqstTDD ::= SEQUENCE {
+ timeSlotLCR TimeSlotLCR,
+ timeSlotStatus TimeSlotStatus,
+ timeSlotDirection TimeSlotDirection,
+ iE-Extensions ProtocolExtensionContainer { { TimeSlotConfigurationItem-LCR-Cell-ReconfRqstTDD-ExtIEs} } OPTIONAL,
+ ...
+ }
+
+TimeSlotConfigurationItem-LCR-Cell-ReconfRqstTDD-ExtIEs NBAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+DwPCH-LCR-Information-Cell-ReconfRqstTDD ::= SEQUENCE {
+ commonPhysicalChannelId CommonPhysicalChannelID,
+ dwPCH-Power DwPCH-Power,
+ iE-Extensions ProtocolExtensionContainer { { DwPCH-LCR-Information-Cell-ReconfRqstTDD-ExtIEs} } OPTIONAL,
+ ...
+ }
+
+DwPCH-LCR-Information-Cell-ReconfRqstTDD-ExtIEs NBAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+IPDLParameter-Information-Cell-ReconfRqstTDD ::= SEQUENCE {
+ iPDL-TDD-Parameters IPDL-TDD-Parameters OPTIONAL,
+ iPDL-Indicator IPDL-Indicator,
+ iE-Extensions ProtocolExtensionContainer { { IPDLParameter-Information-Cell-ReconfRqstTDD-ExtIEs} } OPTIONAL,
+ ...
+}
+
+IPDLParameter-Information-Cell-ReconfRqstTDD-ExtIEs NBAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+IPDLParameter-Information-LCR-Cell-ReconfRqstTDD ::= SEQUENCE {
+ iPDL-TDD-Parameters-LCR IPDL-TDD-Parameters-LCR OPTIONAL,
+ iPDL-Indicator IPDL-Indicator,
+ iE-Extensions ProtocolExtensionContainer { { IPDLParameter-Information-LCR-Cell-ReconfRqstTDD-ExtIEs} } OPTIONAL,
+ ...
+}
+
+IPDLParameter-Information-LCR-Cell-ReconfRqstTDD-ExtIEs NBAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+-- **************************************************************
+--
+-- CELL RECONFIGURATION RESPONSE
+--
+-- **************************************************************
+
+CellReconfigurationResponse ::= SEQUENCE {
+ protocolIEs ProtocolIE-Container {{CellReconfigurationResponse-IEs}},
+ protocolExtensions ProtocolExtensionContainer {{CellReconfigurationResponse-Extensions}} OPTIONAL,
+ ...
+}
+
+CellReconfigurationResponse-IEs NBAP-PROTOCOL-IES ::= {
+ { ID id-CriticalityDiagnostics CRITICALITY ignore TYPE CriticalityDiagnostics PRESENCE optional},
+ ...
+}
+
+CellReconfigurationResponse-Extensions NBAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+-- **************************************************************
+--
+-- CELL RECONFIGURATION FAILURE
+--
+-- **************************************************************
+
+CellReconfigurationFailure ::= SEQUENCE {
+ protocolIEs ProtocolIE-Container {{CellReconfigurationFailure-IEs}},
+ protocolExtensions ProtocolExtensionContainer {{CellReconfigurationFailure-Extensions}} OPTIONAL,
+ ...
+}
+
+CellReconfigurationFailure-IEs NBAP-PROTOCOL-IES ::= {
+ { ID id-Cause CRITICALITY ignore TYPE Cause PRESENCE mandatory }|
+ { ID id-CriticalityDiagnostics CRITICALITY ignore TYPE CriticalityDiagnostics PRESENCE optional },
+ ...
+}
+
+CellReconfigurationFailure-Extensions NBAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+-- **************************************************************
+--
+-- CELL DELETION REQUEST
+--
+-- **************************************************************
+
+CellDeletionRequest ::= SEQUENCE {
+ protocolIEs ProtocolIE-Container {{CellDeletionRequest-IEs}},
+ protocolExtensions ProtocolExtensionContainer {{CellDeletionRequest-Extensions}} OPTIONAL,
+ ...
+}
+
+CellDeletionRequest-IEs NBAP-PROTOCOL-IES ::= {
+ { ID id-C-ID CRITICALITY reject TYPE C-ID PRESENCE mandatory},
+ ...
+}
+
+CellDeletionRequest-Extensions NBAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+-- **************************************************************
+--
+-- CELL DELETION RESPONSE
+--
+-- **************************************************************
+
+CellDeletionResponse ::= SEQUENCE {
+ protocolIEs ProtocolIE-Container {{CellDeletionResponse-IEs}},
+ protocolExtensions ProtocolExtensionContainer {{CellDeletionResponse-Extensions}} OPTIONAL,
+ ...
+}
+
+CellDeletionResponse-IEs NBAP-PROTOCOL-IES ::= {
+ { ID id-CriticalityDiagnostics CRITICALITY ignore TYPE CriticalityDiagnostics PRESENCE optional},
+ ...
+}
+
+CellDeletionResponse-Extensions NBAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+-- **************************************************************
+--
+-- RESOURCE STATUS INDICATION
+--
+-- **************************************************************
+
+ResourceStatusIndication ::= SEQUENCE {
+ protocolIEs ProtocolIE-Container {{ResourceStatusIndication-IEs}},
+ protocolExtensions ProtocolExtensionContainer {{ResourceStatusIndication-Extensions}} OPTIONAL,
+ ...
+}
+
+ResourceStatusIndication-IEs NBAP-PROTOCOL-IES ::= {
+ { ID id-IndicationType-ResourceStatusInd CRITICALITY ignore TYPE IndicationType-ResourceStatusInd PRESENCE mandatory }|
+ { ID id-Cause CRITICALITY ignore TYPE Cause PRESENCE optional },
+ ...
+}
+
+ResourceStatusIndication-Extensions NBAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+IndicationType-ResourceStatusInd ::= CHOICE {
+ no-Failure No-Failure-ResourceStatusInd,
+ serviceImpacting ServiceImpacting-ResourceStatusInd,
+ ...
+}
+
+No-Failure-ResourceStatusInd ::= SEQUENCE {
+ local-Cell-InformationList Local-Cell-InformationList-ResourceStatusInd,
+ local-Cell-Group-InformationList Local-Cell-Group-InformationList-ResourceStatusInd OPTIONAL,
+ iE-Extensions ProtocolExtensionContainer { { No-FailureItem-ResourceStatusInd-ExtIEs} } OPTIONAL,
+ ...
+}
+
+No-FailureItem-ResourceStatusInd-ExtIEs NBAP-PROTOCOL-EXTENSION ::= {
+ { ID id-Power-Local-Cell-Group-InformationList-ResourceStatusInd CRITICALITY ignore EXTENSION Power-Local-Cell-Group-InformationList-ResourceStatusInd PRESENCE optional },
+ ...
+}
+
+Local-Cell-InformationList-ResourceStatusInd ::= SEQUENCE(SIZE (1..maxLocalCellinNodeB)) OF ProtocolIE-Single-Container {{ Local-Cell-InformationItemIE-ResourceStatusInd }}
+
+Local-Cell-InformationItemIE-ResourceStatusInd NBAP-PROTOCOL-IES ::= {
+ { ID id-Local-Cell-InformationItem-ResourceStatusInd CRITICALITY ignore TYPE Local-Cell-InformationItem-ResourceStatusInd PRESENCE mandatory }
+}
+
+Local-Cell-InformationItem-ResourceStatusInd ::= SEQUENCE {
+ local-CellID Local-Cell-ID,
+ addorDeleteIndicator AddorDeleteIndicator,
+ dl-or-global-capacityCredit DL-or-Global-CapacityCredit OPTIONAL,
+ -- This IE shall be present if AddorDeleteIndicator IE is set to "add"
+ ul-capacityCredit UL-CapacityCredit OPTIONAL,
+ commonChannelsCapacityConsumptionLaw CommonChannelsCapacityConsumptionLaw OPTIONAL,
+ -- This IE shall be present if AddorDeleteIndicator IE is set to "add"
+ dedicatedChannelsCapacityConsumptionLaw DedicatedChannelsCapacityConsumptionLaw OPTIONAL,
+ -- This IE shall be present if AddorDeleteIndicator IE is set to "add"
+ maximumDL-PowerCapability MaximumDL-PowerCapability OPTIONAL,
+ -- This IE shall be present if AddorDeleteIndicator IE is set to "add"
+ minSpreadingFactor MinSpreadingFactor OPTIONAL,
+ -- This IE shall be present if AddorDeleteIndicator IE is set to "add"
+ minimumDL-PowerCapability MinimumDL-PowerCapability OPTIONAL,
+ -- This IE shall be present if AddorDeleteIndicator IE is set to "add"
+ local-Cell-Group-ID Local-Cell-ID OPTIONAL,
+ iE-Extensions ProtocolExtensionContainer { { Local-Cell-InformationItem-ResourceStatusInd-ExtIEs} } OPTIONAL,
+ ...
+}
+
+Local-Cell-InformationItem-ResourceStatusInd-ExtIEs NBAP-PROTOCOL-EXTENSION ::= {
+ { ID id-ReferenceClockAvailability CRITICALITY ignore EXTENSION ReferenceClockAvailability PRESENCE optional }|
+ -- This IE shall be present if AddorDeleteIndicator IE is set to "add" and the Local Cell is related to a TDD cell
+ { ID id-Power-Local-Cell-Group-ID CRITICALITY ignore EXTENSION Local-Cell-ID PRESENCE optional }|
+ { ID id-HSDPA-Capability CRITICALITY ignore EXTENSION HSDPA-Capability PRESENCE optional },
+ ...
+}
+
+Local-Cell-Group-InformationList-ResourceStatusInd ::= SEQUENCE(SIZE (1..maxLocalCellinNodeB)) OF ProtocolIE-Single-Container {{ Local-Cell-Group-InformationItemIE-ResourceStatusInd }}
+
+Local-Cell-Group-InformationItemIE-ResourceStatusInd NBAP-PROTOCOL-IES ::= {
+ { ID id-Local-Cell-Group-InformationItem-ResourceStatusInd CRITICALITY ignore TYPE Local-Cell-Group-InformationItem-ResourceStatusInd PRESENCE mandatory }
+}
+
+Local-Cell-Group-InformationItem-ResourceStatusInd::= SEQUENCE {
+ local-Cell-Group-ID Local-Cell-ID,
+ dl-or-global-capacityCredit DL-or-Global-CapacityCredit,
+ ul-capacityCredit UL-CapacityCredit OPTIONAL,
+ commonChannelsCapacityConsumptionLaw CommonChannelsCapacityConsumptionLaw,
+ dedicatedChannelsCapacityConsumptionLaw DedicatedChannelsCapacityConsumptionLaw,
+ iE-Extensions ProtocolExtensionContainer { { Local-Cell-Group-InformationItem-ResourceStatusInd-ExtIEs} } OPTIONAL,
+ ...
+}
+
+Local-Cell-Group-InformationItem-ResourceStatusInd-ExtIEs NBAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+Power-Local-Cell-Group-InformationList-ResourceStatusInd ::= SEQUENCE(SIZE (1..maxLocalCellinNodeB)) OF ProtocolIE-Single-Container {{ Power-Local-Cell-Group-InformationItemIE-ResourceStatusInd }}
+
+Power-Local-Cell-Group-InformationItemIE-ResourceStatusInd NBAP-PROTOCOL-IES ::= {
+ { ID id-Power-Local-Cell-Group-InformationItem-ResourceStatusInd CRITICALITY ignore TYPE Power-Local-Cell-Group-InformationItem-ResourceStatusInd PRESENCE mandatory }
+}
+
+Power-Local-Cell-Group-InformationItem-ResourceStatusInd::= SEQUENCE {
+ power-Local-Cell-Group-ID Local-Cell-ID,
+ maximumDL-PowerCapability MaximumDL-PowerCapability,
+ iE-Extensions ProtocolExtensionContainer { { Power-Local-Cell-Group-InformationItem-ResourceStatusInd-ExtIEs} } OPTIONAL,
+ ...
+}
+
+Power-Local-Cell-Group-InformationItem-ResourceStatusInd-ExtIEs NBAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+ServiceImpacting-ResourceStatusInd ::= SEQUENCE {
+ local-Cell-InformationList Local-Cell-InformationList2-ResourceStatusInd OPTIONAL,
+ local-Cell-Group-InformationList Local-Cell-Group-InformationList2-ResourceStatusInd OPTIONAL,
+ cCP-InformationList CCP-InformationList-ResourceStatusInd OPTIONAL,
+ cell-InformationList Cell-InformationList-ResourceStatusInd OPTIONAL,
+ iE-Extensions ProtocolExtensionContainer { { ServiceImpactingItem-ResourceStatusInd-ExtIEs} } OPTIONAL,
+ ...
+}
+
+ServiceImpactingItem-ResourceStatusInd-ExtIEs NBAP-PROTOCOL-EXTENSION ::= {
+ { ID id-Power-Local-Cell-Group-InformationList2-ResourceStatusInd CRITICALITY ignore EXTENSION Power-Local-Cell-Group-InformationList2-ResourceStatusInd PRESENCE optional },
+ ...
+}
+
+Local-Cell-InformationList2-ResourceStatusInd ::= SEQUENCE(SIZE (1..maxLocalCellinNodeB)) OF ProtocolIE-Single-Container {{ Local-Cell-InformationItemIE2-ResourceStatusInd }}
+
+Local-Cell-InformationItemIE2-ResourceStatusInd NBAP-PROTOCOL-IES ::= {
+ { ID id-Local-Cell-InformationItem2-ResourceStatusInd CRITICALITY ignore TYPE Local-Cell-InformationItem2-ResourceStatusInd PRESENCE mandatory }
+}
+
+Local-Cell-InformationItem2-ResourceStatusInd ::= SEQUENCE {
+ local-Cell-ID Local-Cell-ID,
+ dl-or-global-capacityCredit DL-or-Global-CapacityCredit OPTIONAL,
+ ul-capacityCredit UL-CapacityCredit OPTIONAL,
+ commonChannelsCapacityConsumptionLaw CommonChannelsCapacityConsumptionLaw OPTIONAL,
+ dedicatedChannelsCapacityConsumptionLaw DedicatedChannelsCapacityConsumptionLaw OPTIONAL,
+ maximum-DL-PowerCapability MaximumDL-PowerCapability OPTIONAL,
+ minSpreadingFactor MinSpreadingFactor OPTIONAL,
+ minimumDL-PowerCapability MinimumDL-PowerCapability OPTIONAL,
+ iE-Extensions ProtocolExtensionContainer { { Local-Cell-InformationItem2-ResourceStatusInd-ExtIEs} } OPTIONAL,
+ ...
+}
+
+Local-Cell-InformationItem2-ResourceStatusInd-ExtIEs NBAP-PROTOCOL-EXTENSION ::= {
+ { ID id-ReferenceClockAvailability CRITICALITY ignore EXTENSION ReferenceClockAvailability PRESENCE optional }|
+ { ID id-HSDPA-Capability CRITICALITY ignore EXTENSION HSDPA-Capability PRESENCE optional },
+ ...
+}
+
+Local-Cell-Group-InformationList2-ResourceStatusInd ::= SEQUENCE(SIZE (1..maxLocalCellinNodeB)) OF ProtocolIE-Single-Container {{ Local-Cell-Group-InformationItemIE2-ResourceStatusInd }}
+
+Local-Cell-Group-InformationItemIE2-ResourceStatusInd NBAP-PROTOCOL-IES ::= {
+ { ID id-Local-Cell-Group-InformationItem2-ResourceStatusInd CRITICALITY ignore TYPE Local-Cell-Group-InformationItem2-ResourceStatusInd PRESENCE mandatory }
+}
+
+Local-Cell-Group-InformationItem2-ResourceStatusInd ::= SEQUENCE {
+ local-Cell-Group-ID Local-Cell-ID,
+ dl-or-global-capacityCredit DL-or-Global-CapacityCredit OPTIONAL,
+ ul-capacityCredit UL-CapacityCredit OPTIONAL,
+ commonChannelsCapacityConsumptionLaw CommonChannelsCapacityConsumptionLaw OPTIONAL,
+ dedicatedChannelsCapacityConsumptionLaw DedicatedChannelsCapacityConsumptionLaw OPTIONAL,
+ iE-Extensions ProtocolExtensionContainer { { Local-Cell-Group-InformationItem2-ResourceStatusInd-ExtIEs} } OPTIONAL,
+ ...
+}
+
+Local-Cell-Group-InformationItem2-ResourceStatusInd-ExtIEs NBAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+Power-Local-Cell-Group-InformationList2-ResourceStatusInd ::= SEQUENCE(SIZE (1..maxLocalCellinNodeB)) OF ProtocolIE-Single-Container {{ Power-Local-Cell-Group-InformationItemIE2-ResourceStatusInd }}
+
+Power-Local-Cell-Group-InformationItemIE2-ResourceStatusInd NBAP-PROTOCOL-IES ::= {
+ { ID id-Power-Local-Cell-Group-InformationItem2-ResourceStatusInd CRITICALITY ignore TYPE Power-Local-Cell-Group-InformationItem2-ResourceStatusInd PRESENCE mandatory }
+}
+
+Power-Local-Cell-Group-InformationItem2-ResourceStatusInd::= SEQUENCE {
+ power-Local-Cell-Group-ID Local-Cell-ID,
+ maximumDL-PowerCapability MaximumDL-PowerCapability,
+ iE-Extensions ProtocolExtensionContainer { { Power-Local-Cell-Group-InformationItem2-ResourceStatusInd-ExtIEs} } OPTIONAL,
+ ...
+}
+
+Power-Local-Cell-Group-InformationItem2-ResourceStatusInd-ExtIEs NBAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+CCP-InformationList-ResourceStatusInd ::= SEQUENCE (SIZE (1..maxCCPinNodeB)) OF ProtocolIE-Single-Container {{ CCP-InformationItemIE-ResourceStatusInd }}
+
+CCP-InformationItemIE-ResourceStatusInd NBAP-PROTOCOL-IES ::= {
+ { ID id-CCP-InformationItem-ResourceStatusInd CRITICALITY ignore TYPE CCP-InformationItem-ResourceStatusInd PRESENCE mandatory }
+}
+
+CCP-InformationItem-ResourceStatusInd ::= SEQUENCE {
+ communicationControlPortID CommunicationControlPortID,
+ resourceOperationalState ResourceOperationalState,
+ availabilityStatus AvailabilityStatus,
+ iE-Extensions ProtocolExtensionContainer { { CCP-InformationItem-ResourceStatusInd-ExtIEs} } OPTIONAL,
+ ...
+}
+
+CCP-InformationItem-ResourceStatusInd-ExtIEs NBAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+Cell-InformationList-ResourceStatusInd ::= SEQUENCE (SIZE (1..maxCellinNodeB)) OF ProtocolIE-Single-Container {{ Cell-InformationItemIE-ResourceStatusInd }}
+
+Cell-InformationItemIE-ResourceStatusInd NBAP-PROTOCOL-IES ::= {
+ { ID id-Cell-InformationItem-ResourceStatusInd CRITICALITY ignore TYPE Cell-InformationItem-ResourceStatusInd PRESENCE mandatory }
+}
+
+Cell-InformationItem-ResourceStatusInd ::= SEQUENCE {
+ c-ID C-ID,
+ resourceOperationalState ResourceOperationalState OPTIONAL,
+ availabilityStatus AvailabilityStatus OPTIONAL,
+ primary-SCH-Information P-SCH-Information-ResourceStatusInd OPTIONAL, -- FDD only
+ secondary-SCH-Information S-SCH-Information-ResourceStatusInd OPTIONAL, -- FDD only
+ primary-CPICH-Information P-CPICH-Information-ResourceStatusInd OPTIONAL, -- FDD only
+ secondary-CPICH-Information S-CPICH-InformationList-ResourceStatusInd OPTIONAL, -- FDD only
+ primary-CCPCH-Information P-CCPCH-Information-ResourceStatusInd OPTIONAL,
+ bCH-Information BCH-Information-ResourceStatusInd OPTIONAL,
+ secondary-CCPCH-InformationList S-CCPCH-InformationList-ResourceStatusInd OPTIONAL,
+ pCH-Information PCH-Information-ResourceStatusInd OPTIONAL,
+ pICH-Information PICH-Information-ResourceStatusInd OPTIONAL,
+ fACH-InformationList FACH-InformationList-ResourceStatusInd OPTIONAL,
+ pRACH-InformationList PRACH-InformationList-ResourceStatusInd OPTIONAL,
+ rACH-InformationList RACH-InformationList-ResourceStatusInd OPTIONAL,
+ aICH-InformationList AICH-InformationList-ResourceStatusInd OPTIONAL, -- FDD only
+ pCPCH-InformationList PCPCH-InformationList-ResourceStatusInd OPTIONAL, -- FDD only
+ cPCH-InformationList CPCH-InformationList-ResourceStatusInd OPTIONAL, -- FDD only
+ aP-AICH-InformationList AP-AICH-InformationList-ResourceStatusInd OPTIONAL, -- FDD only
+ cDCA-ICH-InformationList CDCA-ICH-InformationList-ResourceStatusInd OPTIONAL, -- FDD only
+ sCH-Information SCH-Information-ResourceStatusInd OPTIONAL, -- Applicable to 3.84Mcps TDD only
+ iE-Extensions ProtocolExtensionContainer { { Cell-InformationItem-ResourceStatusInd-ExtIEs} } OPTIONAL,
+ ...
+}
+
+Cell-InformationItem-ResourceStatusInd-ExtIEs NBAP-PROTOCOL-EXTENSION ::= {
+ { ID id-FPACH-LCR-InformationList-ResourceStatusInd CRITICALITY ignore EXTENSION FPACH-LCR-InformationList-ResourceStatusInd PRESENCE optional }| -- Applicable to 1.28Mcps TDD only
+ { ID id-DwPCH-LCR-Information-ResourceStatusInd CRITICALITY ignore EXTENSION DwPCH-LCR-Information-ResourceStatusInd PRESENCE optional }| -- Applicable to 1.28Mcps TDD only
+ { ID id-HSDSCH-Resources-Information-ResourceStatusInd CRITICALITY ignore EXTENSION HS-DSCH-Resources-Information-ResourceStatusInd PRESENCE optional },
+ ...
+}
+
+P-SCH-Information-ResourceStatusInd ::= ProtocolIE-Single-Container {{ P-SCH-InformationIE-ResourceStatusInd }}
+
+P-SCH-InformationIE-ResourceStatusInd NBAP-PROTOCOL-IES ::= {
+ { ID id-P-SCH-Information CRITICALITY ignore TYPE Common-PhysicalChannel-Status-Information PRESENCE mandatory }
+}
+
+S-SCH-Information-ResourceStatusInd ::= ProtocolIE-Single-Container {{ S-SCH-InformationIE-ResourceStatusInd }}
+
+S-SCH-InformationIE-ResourceStatusInd NBAP-PROTOCOL-IES ::= {
+ { ID id-S-SCH-Information CRITICALITY ignore TYPE Common-PhysicalChannel-Status-Information PRESENCE mandatory }
+}
+
+P-CPICH-Information-ResourceStatusInd ::= ProtocolIE-Single-Container {{ P-CPICH-InformationIE-ResourceStatusInd }}
+
+P-CPICH-InformationIE-ResourceStatusInd NBAP-PROTOCOL-IES ::= {
+ { ID id-P-CPICH-Information CRITICALITY ignore TYPE Common-PhysicalChannel-Status-Information PRESENCE mandatory }
+}
+
+S-CPICH-InformationList-ResourceStatusInd ::= SEQUENCE (SIZE (1..maxSCPICHCell)) OF ProtocolIE-Single-Container {{ S-CPICH-InformationItemIE-ResourceStatusInd }}
+
+S-CPICH-InformationItemIE-ResourceStatusInd NBAP-PROTOCOL-IES ::= {
+ { ID id-S-CPICH-Information CRITICALITY ignore TYPE Common-PhysicalChannel-Status-Information PRESENCE mandatory }
+}
+
+P-CCPCH-Information-ResourceStatusInd ::= ProtocolIE-Single-Container {{ P-CCPCH-InformationIE-ResourceStatusInd }}
+
+P-CCPCH-InformationIE-ResourceStatusInd NBAP-PROTOCOL-IES ::= {
+ { ID id-P-CCPCH-Information CRITICALITY ignore TYPE Common-PhysicalChannel-Status-Information PRESENCE mandatory }
+}
+
+BCH-Information-ResourceStatusInd ::= ProtocolIE-Single-Container {{ BCH-InformationIE-ResourceStatusInd }}
+
+BCH-InformationIE-ResourceStatusInd NBAP-PROTOCOL-IES ::= {
+ { ID id-BCH-Information CRITICALITY ignore TYPE Common-TransportChannel-Status-Information PRESENCE mandatory }
+}
+
+S-CCPCH-InformationList-ResourceStatusInd ::= SEQUENCE (SIZE (1..maxSCCPCHCell)) OF ProtocolIE-Single-Container {{ S-CCPCH-InformationItemIE-ResourceStatusInd }}
+
+S-CCPCH-InformationItemIE-ResourceStatusInd NBAP-PROTOCOL-IES ::= {
+ { ID id-S-CCPCH-Information CRITICALITY ignore TYPE Common-PhysicalChannel-Status-Information PRESENCE mandatory }
+}
+
+PCH-Information-ResourceStatusInd ::= ProtocolIE-Single-Container {{ PCH-InformationIE-ResourceStatusInd }}
+
+PCH-InformationIE-ResourceStatusInd NBAP-PROTOCOL-IES ::= {
+ { ID id-PCH-Information CRITICALITY ignore TYPE Common-TransportChannel-Status-Information PRESENCE mandatory }
+}
+
+PICH-Information-ResourceStatusInd ::= ProtocolIE-Single-Container {{ PICH-InformationIE-ResourceStatusInd }}
+
+PICH-InformationIE-ResourceStatusInd NBAP-PROTOCOL-IES ::= {
+ { ID id-PICH-Information CRITICALITY ignore TYPE Common-PhysicalChannel-Status-Information PRESENCE mandatory }
+}
+
+FACH-InformationList-ResourceStatusInd ::= SEQUENCE (SIZE (1..maxFACHCell)) OF ProtocolIE-Single-Container {{ FACH-InformationItemIE-ResourceStatusInd }}
+
+FACH-InformationItemIE-ResourceStatusInd NBAP-PROTOCOL-IES ::= {
+ { ID id-FACH-Information CRITICALITY ignore TYPE Common-TransportChannel-Status-Information PRESENCE mandatory }
+}
+
+PRACH-InformationList-ResourceStatusInd ::= SEQUENCE (SIZE (1..maxPRACHCell)) OF ProtocolIE-Single-Container {{ PRACH-InformationItemIE-ResourceStatusInd }}
+
+PRACH-InformationItemIE-ResourceStatusInd NBAP-PROTOCOL-IES ::= {
+ { ID id-PRACH-Information CRITICALITY ignore TYPE Common-PhysicalChannel-Status-Information PRESENCE mandatory }
+}
+
+RACH-InformationList-ResourceStatusInd ::= SEQUENCE (SIZE (1..maxPRACHCell)) OF ProtocolIE-Single-Container {{ RACH-InformationItemIE-ResourceStatusInd }}
+
+RACH-InformationItemIE-ResourceStatusInd NBAP-PROTOCOL-IES ::= {
+ { ID id-RACH-Information CRITICALITY ignore TYPE Common-TransportChannel-Status-Information PRESENCE mandatory }
+}
+
+AICH-InformationList-ResourceStatusInd ::= SEQUENCE (SIZE (1..maxPRACHCell)) OF ProtocolIE-Single-Container {{ AICH-InformationItemIE-ResourceStatusInd }}
+
+AICH-InformationItemIE-ResourceStatusInd NBAP-PROTOCOL-IES ::= {
+ { ID id-AICH-Information CRITICALITY ignore TYPE Common-PhysicalChannel-Status-Information PRESENCE mandatory }
+}
+
+PCPCH-InformationList-ResourceStatusInd ::= SEQUENCE (SIZE (1..maxPCPCHCell)) OF ProtocolIE-Single-Container {{ PCPCH-InformationItemIE-ResourceStatusInd }}
+
+PCPCH-InformationItemIE-ResourceStatusInd NBAP-PROTOCOL-IES ::= {
+ { ID id-PCPCH-Information CRITICALITY ignore TYPE Common-PhysicalChannel-Status-Information PRESENCE optional }
+}
+
+CPCH-InformationList-ResourceStatusInd ::= SEQUENCE (SIZE (1..maxCPCHCell)) OF ProtocolIE-Single-Container {{ CPCH-InformationItemIE-ResourceStatusInd }}
+
+CPCH-InformationItemIE-ResourceStatusInd NBAP-PROTOCOL-IES ::= {
+ { ID id-CPCH-Information CRITICALITY ignore TYPE Common-TransportChannel-Status-Information PRESENCE optional }
+}
+
+AP-AICH-InformationList-ResourceStatusInd ::= SEQUENCE (SIZE (1..maxCPCHCell)) OF ProtocolIE-Single-Container {{ AP-AICH-InformationItemIE-ResourceStatusInd }}
+
+AP-AICH-InformationItemIE-ResourceStatusInd NBAP-PROTOCOL-IES ::= {
+ { ID id-AP-AICH-Information CRITICALITY ignore TYPE Common-PhysicalChannel-Status-Information PRESENCE optional }
+}
+
+CDCA-ICH-InformationList-ResourceStatusInd ::= SEQUENCE (SIZE (1..maxCPCHCell)) OF ProtocolIE-Single-Container {{ CDCA-ICH-InformationItemIE-ResourceStatusInd }}
+
+CDCA-ICH-InformationItemIE-ResourceStatusInd NBAP-PROTOCOL-IES ::= {
+ { ID id-CDCA-ICH-Information CRITICALITY ignore TYPE Common-PhysicalChannel-Status-Information PRESENCE optional }
+}
+
+SCH-Information-ResourceStatusInd ::= ProtocolIE-Single-Container {{ SCH-InformationIE-ResourceStatusInd }}
+
+SCH-InformationIE-ResourceStatusInd NBAP-PROTOCOL-IES ::= {
+ { ID id-SCH-Information CRITICALITY ignore TYPE Common-PhysicalChannel-Status-Information PRESENCE mandatory }
+}
+
+FPACH-LCR-InformationList-ResourceStatusInd ::= SEQUENCE (SIZE (1..maxFPACHCell)) OF ProtocolIE-Single-Container {{ FPACH-LCR-InformationItemIE-ResourceStatusInd }}
+
+FPACH-LCR-InformationItemIE-ResourceStatusInd NBAP-PROTOCOL-IES ::= {
+ { ID id-FPACH-LCR-Information CRITICALITY ignore TYPE Common-PhysicalChannel-Status-Information PRESENCE mandatory }
+}
+
+DwPCH-LCR-Information-ResourceStatusInd ::= ProtocolIE-Single-Container {{ DwPCH-LCR-InformationIE-ResourceStatusInd }}
+
+DwPCH-LCR-InformationIE-ResourceStatusInd NBAP-PROTOCOL-IES ::= {
+ { ID id-DwPCH-LCR-Information CRITICALITY ignore TYPE Common-PhysicalChannel-Status-Information PRESENCE mandatory }
+}
+
+HS-DSCH-Resources-Information-ResourceStatusInd ::= SEQUENCE {
+ resourceOperationalState ResourceOperationalState,
+ availabilityStatus AvailabilityStatus,
+ iE-Extensions ProtocolExtensionContainer {{ HS-DSCH-Resources-Information-ResourceStatusInd-ExtIEs }} OPTIONAL,
+ ...
+}
+
+HS-DSCH-Resources-Information-ResourceStatusInd-ExtIEs NBAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+-- **************************************************************
+--
+-- SYSTEM INFORMATION UPDATE REQUEST
+--
+-- **************************************************************
+
+SystemInformationUpdateRequest ::= SEQUENCE {
+ protocolIEs ProtocolIE-Container {{SystemInformationUpdateRequest-IEs}},
+ protocolExtensions ProtocolExtensionContainer {{SystemInformationUpdateRequest-Extensions}} OPTIONAL,
+ ...
+}
+
+SystemInformationUpdateRequest-IEs NBAP-PROTOCOL-IES ::= {
+ { ID id-C-ID CRITICALITY reject TYPE C-ID PRESENCE mandatory }|
+ { ID id-BCCH-ModificationTime CRITICALITY reject TYPE BCCH-ModificationTime PRESENCE optional }|
+ { ID id-MIB-SB-SIB-InformationList-SystemInfoUpdateRqst CRITICALITY reject TYPE MIB-SB-SIB-InformationList-SystemInfoUpdateRqst PRESENCE mandatory },
+ ...
+}
+
+SystemInformationUpdateRequest-Extensions NBAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+MIB-SB-SIB-InformationList-SystemInfoUpdateRqst ::= SEQUENCE (SIZE (1..maxIB)) OF MIB-SB-SIB-InformationItem-SystemInfoUpdateRqst
+
+MIB-SB-SIB-InformationItem-SystemInfoUpdateRqst ::= SEQUENCE {
+ iB-Type IB-Type,
+ iB-OC-ID IB-OC-ID,
+ deletionIndicator DeletionIndicator-SystemInfoUpdate,
+ iE-Extensions ProtocolExtensionContainer { { MIB-SB-SIB-InformationItem-SystemInfoUpdateRqst-ExtIEs} } OPTIONAL,
+ ...
+}
+
+MIB-SB-SIB-InformationItem-SystemInfoUpdateRqst-ExtIEs NBAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+DeletionIndicator-SystemInfoUpdate ::= CHOICE {
+ no-Deletion No-Deletion-SystemInfoUpdate,
+ yes-Deletion NULL
+
+}
+
+No-Deletion-SystemInfoUpdate ::= SEQUENCE {
+ sIB-Originator SIB-Originator OPTIONAL,
+ -- This IE shall be present if the IB-Type IE is set to "SIB"
+ iB-SG-REP IB-SG-REP OPTIONAL,
+ segmentInformationList SegmentInformationList-SystemInfoUpdate,
+ iE-Extensions ProtocolExtensionContainer { { No-DeletionItem-SystemInfoUpdate-ExtIEs} } OPTIONAL,
+ ...
+}
+
+No-DeletionItem-SystemInfoUpdate-ExtIEs NBAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+SegmentInformationList-SystemInfoUpdate ::= ProtocolIE-Single-Container {{ SegmentInformationListIEs-SystemInfoUpdate }}
+
+SegmentInformationListIEs-SystemInfoUpdate NBAP-PROTOCOL-IES ::= {
+ { ID id-SegmentInformationListIE-SystemInfoUpdate CRITICALITY reject TYPE SegmentInformationListIE-SystemInfoUpdate PRESENCE mandatory }
+}
+
+SegmentInformationListIE-SystemInfoUpdate ::= SEQUENCE (SIZE (1..maxIBSEG)) OF SegmentInformationItem-SystemInfoUpdate
+
+SegmentInformationItem-SystemInfoUpdate ::= SEQUENCE {
+ iB-SG-POS IB-SG-POS OPTIONAL,
+ segment-Type Segment-Type OPTIONAL,
+ -- This IE shall be present if the SIB Originator IE is set to "CRNC" or the IB-Type IE is set to "MIB", "SB1" or "SB2"
+ iB-SG-DATA IB-SG-DATA OPTIONAL,
+ -- This IE shall be present if the SIB Originator IE is set to "CRNC" or the IB-Type IE is set to "MIB", "SB1" or "SB2"
+ iE-Extensions ProtocolExtensionContainer { { SegmentInformationItem-SystemInfoUpdate-ExtIEs} } OPTIONAL,
+ ...
+}
+
+SegmentInformationItem-SystemInfoUpdate-ExtIEs NBAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+-- **************************************************************
+--
+-- SYSTEM INFORMATION UPDATE RESPONSE
+--
+-- **************************************************************
+
+SystemInformationUpdateResponse ::= SEQUENCE {
+ protocolIEs ProtocolIE-Container {{SystemInformationUpdateResponse-IEs}},
+ protocolExtensions ProtocolExtensionContainer {{SystemInformationUpdateResponse-Extensions}} OPTIONAL,
+ ...
+}
+
+SystemInformationUpdateResponse-IEs NBAP-PROTOCOL-IES ::= {
+ { ID id-CriticalityDiagnostics CRITICALITY ignore TYPE CriticalityDiagnostics PRESENCE optional},
+ ...
+}
+
+SystemInformationUpdateResponse-Extensions NBAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+-- **************************************************************
+--
+-- SYSTEM INFORMATION UPDATE FAILURE
+--
+-- **************************************************************
+
+SystemInformationUpdateFailure ::= SEQUENCE {
+ protocolIEs ProtocolIE-Container {{SystemInformationUpdateFailure-IEs}},
+ protocolExtensions ProtocolExtensionContainer {{SystemInformationUpdateFailure-Extensions}} OPTIONAL,
+ ...
+}
+
+SystemInformationUpdateFailure-IEs NBAP-PROTOCOL-IES ::= {
+ { ID id-Cause CRITICALITY ignore TYPE Cause PRESENCE mandatory }|
+ { ID id-CriticalityDiagnostics CRITICALITY ignore TYPE CriticalityDiagnostics PRESENCE optional },
+ ...
+}
+
+SystemInformationUpdateFailure-Extensions NBAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+-- **************************************************************
+--
+-- RADIO LINK SETUP REQUEST FDD
+--
+-- **************************************************************
+
+RadioLinkSetupRequestFDD ::= SEQUENCE {
+ protocolIEs ProtocolIE-Container {{RadioLinkSetupRequestFDD-IEs}},
+ protocolExtensions ProtocolExtensionContainer {{RadioLinkSetupRequestFDD-Extensions}} OPTIONAL,
+ ...
+}
+
+RadioLinkSetupRequestFDD-IEs NBAP-PROTOCOL-IES ::= {
+ { ID id-CRNC-CommunicationContextID CRITICALITY reject TYPE CRNC-CommunicationContextID PRESENCE mandatory }|
+ { ID id-UL-DPCH-Information-RL-SetupRqstFDD CRITICALITY reject TYPE UL-DPCH-Information-RL-SetupRqstFDD PRESENCE mandatory }|
+ { ID id-DL-DPCH-Information-RL-SetupRqstFDD CRITICALITY reject TYPE DL-DPCH-Information-RL-SetupRqstFDD PRESENCE mandatory }|
+ { ID id-DCH-FDD-Information CRITICALITY reject TYPE DCH-FDD-Information PRESENCE mandatory }|
+ { ID id-DSCH-FDD-Information CRITICALITY reject TYPE DSCH-FDD-Information PRESENCE optional }|
+ { ID id-TFCI2-Bearer-Information-RL-SetupRqstFDD CRITICALITY ignore TYPE TFCI2-Bearer-Information-RL-SetupRqstFDD PRESENCE optional }|
+ { ID id-RL-InformationList-RL-SetupRqstFDD CRITICALITY notify TYPE RL-InformationList-RL-SetupRqstFDD PRESENCE mandatory }|
+ { ID id-Transmission-Gap-Pattern-Sequence-Information CRITICALITY reject TYPE Transmission-Gap-Pattern-Sequence-Information PRESENCE optional } |
+ { ID id-Active-Pattern-Sequence-Information CRITICALITY reject TYPE Active-Pattern-Sequence-Information PRESENCE optional },
+ ...
+}
+
+RadioLinkSetupRequestFDD-Extensions NBAP-PROTOCOL-EXTENSION ::= {
+ { ID id-DSCH-FDD-Common-Information CRITICALITY ignore EXTENSION DSCH-FDD-Common-Information PRESENCE optional }|
+ { ID id-DL-PowerBalancing-Information CRITICALITY ignore EXTENSION DL-PowerBalancing-Information PRESENCE optional }|
+ { ID id-HSDSCH-FDD-Information CRITICALITY reject EXTENSION HSDSCH-FDD-Information PRESENCE optional }|
+ { ID id-HSDSCH-RNTI CRITICALITY reject EXTENSION HSDSCH-RNTI PRESENCE conditional }|
+ -- The IE shall be present if HS-DSCH Information IE is present
+ { ID id-HSPDSCH-RL-ID CRITICALITY reject EXTENSION RL-ID PRESENCE conditional },
+ -- The IE shall be present if HS-DSCH Information IE is present
+ ...
+}
+
+UL-DPCH-Information-RL-SetupRqstFDD ::= SEQUENCE {
+ ul-ScramblingCode UL-ScramblingCode,
+ minUL-ChannelisationCodeLength MinUL-ChannelisationCodeLength,
+ maxNrOfUL-DPDCHs MaxNrOfUL-DPDCHs OPTIONAL,
+ -- This IE shall be present if Min UL Channelisation Code length IE is set to 4 --
+ ul-PunctureLimit PunctureLimit,
+ tFCS TFCS,
+ ul-DPCCH-SlotFormat UL-DPCCH-SlotFormat,
+ ul-SIR-Target UL-SIR,
+ diversityMode DiversityMode,
+ sSDT-CellID-Length SSDT-CellID-Length OPTIONAL,
+ s-FieldLength S-FieldLength OPTIONAL,
+ iE-Extensions ProtocolExtensionContainer { { UL-DPCH-Information-RL-SetupRqstFDD-ExtIEs} } OPTIONAL,
+ ...
+}
+
+UL-DPCH-Information-RL-SetupRqstFDD-ExtIEs NBAP-PROTOCOL-EXTENSION ::= {
+ {ID id-DPC-Mode CRITICALITY reject EXTENSION DPC-Mode PRESENCE optional },
+ ...
+}
+
+DL-DPCH-Information-RL-SetupRqstFDD ::= SEQUENCE {
+ tFCS TFCS,
+ dl-DPCH-SlotFormat DL-DPCH-SlotFormat,
+ tFCI-SignallingMode TFCI-SignallingMode,
+ tFCI-Presence TFCI-Presence OPTIONAL,
+ -- this IE shall be present if the DL DPCH slot format IE is set to any of the values from 12 to 16 --
+ multiplexingPosition MultiplexingPosition,
+ pDSCH-RL-ID RL-ID OPTIONAL,
+ -- This IE shall be present if the DSCH Information IE is present --
+ pDSCH-CodeMapping PDSCH-CodeMapping OPTIONAL,
+ -- This IE shall be present if the DSCH Information IE is present --
+ powerOffsetInformation PowerOffsetInformation-RL-SetupRqstFDD,
+ fdd-TPC-DownlinkStepSize FDD-TPC-DownlinkStepSize,
+ limitedPowerIncrease LimitedPowerIncrease,
+ innerLoopDLPCStatus InnerLoopDLPCStatus,
+ iE-Extensions ProtocolExtensionContainer { { DL-DPCH-Information-RL-SetupRqstFDD-ExtIEs} } OPTIONAL,
+ ...
+}
+
+DL-DPCH-Information-RL-SetupRqstFDD-ExtIEs NBAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+PowerOffsetInformation-RL-SetupRqstFDD ::= SEQUENCE {
+ pO1-ForTFCI-Bits PowerOffset,
+ pO2-ForTPC-Bits PowerOffset,
+ pO3-ForPilotBits PowerOffset,
+ iE-Extensions ProtocolExtensionContainer { { PowerOffsetInformation-RL-SetupRqstFDD-ExtIEs} } OPTIONAL,
+ ...
+}
+
+PowerOffsetInformation-RL-SetupRqstFDD-ExtIEs NBAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+TFCI2-Bearer-Information-RL-SetupRqstFDD ::= SEQUENCE {
+ toAWS ToAWS,
+ toAWE ToAWE,
+ iE-Extensions ProtocolExtensionContainer { { TFCI2-Bearer-Information-RL-SetupRqstFDD-ExtIEs} } OPTIONAL,
+ ...
+}
+
+TFCI2-Bearer-Information-RL-SetupRqstFDD-ExtIEs NBAP-PROTOCOL-EXTENSION ::= {
+ { ID id-bindingID CRITICALITY ignore EXTENSION BindingID PRESENCE optional }|
+ { ID id-transportlayeraddress CRITICALITY ignore EXTENSION TransportLayerAddress PRESENCE optional },
+ ...
+}
+
+RL-InformationList-RL-SetupRqstFDD ::= SEQUENCE (SIZE (1..maxNrOfRLs)) OF
+ ProtocolIE-Single-Container{{ RL-InformationItemIE-RL-SetupRqstFDD }}
+
+RL-InformationItemIE-RL-SetupRqstFDD NBAP-PROTOCOL-IES ::= {
+ { ID id-RL-InformationItem-RL-SetupRqstFDD CRITICALITY notify TYPE RL-InformationItem-RL-SetupRqstFDD PRESENCE mandatory}
+}
+
+RL-InformationItem-RL-SetupRqstFDD ::= SEQUENCE {
+ rL-ID RL-ID,
+ c-ID C-ID,
+ firstRLS-indicator FirstRLS-Indicator,
+ frameOffset FrameOffset,
+ chipOffset ChipOffset,
+ propagationDelay PropagationDelay OPTIONAL,
+ diversityControlField DiversityControlField OPTIONAL,
+ -- This IE shall be present if the RL is not the first one in the RL Information IE
+ dl-CodeInformation FDD-DL-CodeInformation,
+ initialDL-transmissionPower DL-Power,
+ maximumDL-power DL-Power,
+ minimumDL-power DL-Power,
+ sSDT-Cell-Identity SSDT-Cell-Identity OPTIONAL,
+ transmitDiversityIndicator TransmitDiversityIndicator OPTIONAL,
+ -- This IE shall be present if Diversity Mode IE in UL DPCH Information group is not set to "none"
+ iE-Extensions ProtocolExtensionContainer { { RL-InformationItem-RL-SetupRqstFDD-ExtIEs} } OPTIONAL,
+ ...
+}
+
+RL-InformationItem-RL-SetupRqstFDD-ExtIEs NBAP-PROTOCOL-EXTENSION ::= {
+ { ID id-SSDT-CellIDforEDSCHPC CRITICALITY ignore EXTENSION SSDT-Cell-Identity PRESENCE conditional }|
+ -- This IE shall be present if Enhanced DSCH PC IE is present in the DSCH Common Information IE.
+ { ID id-RL-Specific-DCH-Info CRITICALITY ignore EXTENSION RL-Specific-DCH-Info PRESENCE optional }|
+ { ID id-DelayedActivation CRITICALITY reject EXTENSION DelayedActivation PRESENCE optional }|
+ { ID id-Qth-Parameter CRITICALITY ignore EXTENSION Qth-Parameter PRESENCE optional }|
+ { ID id-Primary-CPICH-Usage-for-Channel-Estimation CRITICALITY ignore EXTENSION Primary-CPICH-Usage-for-Channel-Estimation PRESENCE optional },
+ ...
+}
+
+-- **************************************************************
+--
+-- RADIO LINK SETUP REQUEST TDD
+--
+-- **************************************************************
+
+RadioLinkSetupRequestTDD ::= SEQUENCE {
+ protocolIEs ProtocolIE-Container {{RadioLinkSetupRequestTDD-IEs}},
+ protocolExtensions ProtocolExtensionContainer {{RadioLinkSetupRequestTDD-Extensions}} OPTIONAL,
+ ...
+}
+
+RadioLinkSetupRequestTDD-IEs NBAP-PROTOCOL-IES ::= {
+ { ID id-CRNC-CommunicationContextID CRITICALITY reject TYPE CRNC-CommunicationContextID PRESENCE mandatory }|
+ { ID id-UL-CCTrCH-InformationList-RL-SetupRqstTDD CRITICALITY notify TYPE UL-CCTrCH-InformationList-RL-SetupRqstTDD PRESENCE optional }|
+ { ID id-DL-CCTrCH-InformationList-RL-SetupRqstTDD CRITICALITY notify TYPE DL-CCTrCH-InformationList-RL-SetupRqstTDD PRESENCE optional }|
+ { ID id-DCH-TDD-Information CRITICALITY reject TYPE DCH-TDD-Information PRESENCE optional }|
+ { ID id-DSCH-TDD-Information CRITICALITY reject TYPE DSCH-TDD-Information PRESENCE optional }|
+ { ID id-USCH-Information CRITICALITY reject TYPE USCH-Information PRESENCE optional }|
+ { ID id-RL-Information-RL-SetupRqstTDD CRITICALITY reject TYPE RL-Information-RL-SetupRqstTDD PRESENCE mandatory },
+ ...
+}
+
+RadioLinkSetupRequestTDD-Extensions NBAP-PROTOCOL-EXTENSION ::= {
+ { ID id-HSDSCH-TDD-Information CRITICALITY reject EXTENSION HSDSCH-TDD-Information PRESENCE optional }|
+ { ID id-HSDSCH-RNTI CRITICALITY reject EXTENSION HSDSCH-RNTI PRESENCE conditional }|
+ -- The IE shall be present if HS-DSCH Information IE is present
+ { ID id-HSPDSCH-RL-ID CRITICALITY reject EXTENSION RL-ID PRESENCE conditional }|
+ -- The IE shall be present if HS-DSCH Information IE is present
+ { ID id-PDSCH-RL-ID CRITICALITY ignore EXTENSION RL-ID PRESENCE optional },
+ ...
+}
+
+UL-CCTrCH-InformationList-RL-SetupRqstTDD ::= SEQUENCE (SIZE(1..maxNrOfCCTrCHs)) OF
+ ProtocolIE-Single-Container{{ UL-CCTrCH-InformationItemIE-RL-SetupRqstTDD }}
+
+UL-CCTrCH-InformationItemIE-RL-SetupRqstTDD NBAP-PROTOCOL-IES ::= {
+ { ID id-UL-CCTrCH-InformationItem-RL-SetupRqstTDD CRITICALITY notify TYPE UL-CCTrCH-InformationItem-RL-SetupRqstTDD PRESENCE mandatory}
+}
+
+UL-CCTrCH-InformationItem-RL-SetupRqstTDD ::= SEQUENCE {
+ cCTrCH-ID CCTrCH-ID,
+ tFCS TFCS,
+ tFCI-Coding TFCI-Coding,
+ punctureLimit PunctureLimit,
+ uL-DPCH-Information UL-DPCH-Information-RL-SetupRqstTDD OPTIONAL, -- Applicable to 3.84Mcps TDD only
+ iE-Extensions ProtocolExtensionContainer { { UL-CCTrCH-InformationItem-RL-SetupRqstTDD-ExtIEs} } OPTIONAL,
+ ...
+}
+
+UL-CCTrCH-InformationItem-RL-SetupRqstTDD-ExtIEs NBAP-PROTOCOL-EXTENSION ::= {
+ { ID id-UL-DPCH-LCR-Information-RL-SetupRqstTDD CRITICALITY notify EXTENSION UL-DPCH-LCR-Information-RL-SetupRqstTDD PRESENCE optional }| -- Applicable to 1.28Mcps TDD only
+ { ID id-UL-SIRTarget CRITICALITY reject EXTENSION UL-SIR PRESENCE optional }|
+ -- Mandatory for 1.28Mcps TDD, Not Applicable to 3.84Mcps TDD.
+ { ID id-TDD-TPC-UplinkStepSize-LCR-RL-SetupRqstTDD CRITICALITY reject EXTENSION TDD-TPC-UplinkStepSize-LCR PRESENCE optional },
+ -- Mandatory for 1.28Mcps TDD, Not Applicable to 3.84Mcps TDD.
+ ...
+}
+
+UL-DPCH-Information-RL-SetupRqstTDD ::= ProtocolIE-Single-Container{{ UL-DPCH-InformationIE-RL-SetupRqstTDD }}
+
+UL-DPCH-InformationIE-RL-SetupRqstTDD NBAP-PROTOCOL-IES ::= {
+ { ID id-UL-DPCH-InformationList-RL-SetupRqstTDD CRITICALITY notify TYPE UL-DPCH-InformationItem-RL-SetupRqstTDD PRESENCE mandatory }
+}
+
+UL-DPCH-InformationItem-RL-SetupRqstTDD ::= SEQUENCE {
+ repetitionPeriod RepetitionPeriod,
+ repetitionLength RepetitionLength,
+ tdd-DPCHOffset TDD-DPCHOffset,
+ uL-Timeslot-Information UL-Timeslot-Information,
+ iE-Extensions ProtocolExtensionContainer { { UL-DPCH-InformationItem-RL-SetupRqstTDD-ExtIEs} } OPTIONAL,
+ ...
+}
+
+UL-DPCH-InformationItem-RL-SetupRqstTDD-ExtIEs NBAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+UL-DPCH-LCR-Information-RL-SetupRqstTDD ::= SEQUENCE {
+ repetitionPeriod RepetitionPeriod,
+ repetitionLength RepetitionLength,
+ tdd-DPCHOffset TDD-DPCHOffset,
+ uL-TimeslotLCR-Information UL-TimeslotLCR-Information,
+ iE-Extensions ProtocolExtensionContainer { { UL-DPCH-LCR-InformationItem-RL-SetupRqstTDD-ExtIEs} } OPTIONAL,
+ ...
+}
+
+UL-DPCH-LCR-InformationItem-RL-SetupRqstTDD-ExtIEs NBAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+DL-CCTrCH-InformationList-RL-SetupRqstTDD ::= SEQUENCE (SIZE (1..maxNrOfCCTrCHs)) OF ProtocolIE-Single-Container{{ DL-CCTrCH-InformationItemIE-RL-SetupRqstTDD }}
+
+DL-CCTrCH-InformationItemIE-RL-SetupRqstTDD NBAP-PROTOCOL-IES ::= {
+ { ID id-DL-CCTrCH-InformationItem-RL-SetupRqstTDD CRITICALITY notify TYPE DL-CCTrCH-InformationItem-RL-SetupRqstTDD PRESENCE mandatory}
+}
+
+DL-CCTrCH-InformationItem-RL-SetupRqstTDD ::= SEQUENCE {
+ cCTrCH-ID CCTrCH-ID,
+ tFCS TFCS,
+ tFCI-Coding TFCI-Coding,
+ punctureLimit PunctureLimit,
+ tdd-TPC-DownlinkStepSize TDD-TPC-DownlinkStepSize,
+ cCTrCH-TPCList CCTrCH-TPCList-RL-SetupRqstTDD OPTIONAL,
+ dL-DPCH-Information DL-DPCH-Information-RL-SetupRqstTDD OPTIONAL, -- Applicable to 3.84Mcps TDD only
+ iE-Extensions ProtocolExtensionContainer { { DL-CCTrCH-InformationItem-RL-SetupRqstTDD-ExtIEs} } OPTIONAL,
+ ...
+}
+
+DL-CCTrCH-InformationItem-RL-SetupRqstTDD-ExtIEs NBAP-PROTOCOL-EXTENSION ::= {
+ { ID id-DL-DPCH-LCR-Information-RL-SetupRqstTDD CRITICALITY notify EXTENSION DL-DPCH-LCR-Information-RL-SetupRqstTDD PRESENCE optional }| -- Applicable to 1.28Mcps TDD only
+ { ID id-CCTrCH-Initial-DL-Power-RL-SetupRqstTDD CRITICALITY ignore EXTENSION DL-Power PRESENCE optional }|
+ { ID id-CCTrCH-Maximum-DL-Power-RL-SetupRqstTDD CRITICALITY ignore EXTENSION DL-Power PRESENCE optional }|
+ { ID id-CCTrCH-Minimum-DL-Power-RL-SetupRqstTDD CRITICALITY ignore EXTENSION DL-Power PRESENCE optional },
+ ...
+}
+
+CCTrCH-TPCList-RL-SetupRqstTDD ::= SEQUENCE (SIZE (1..maxNrOfCCTrCHs)) OF CCTrCH-TPCItem-RL-SetupRqstTDD
+
+CCTrCH-TPCItem-RL-SetupRqstTDD ::= SEQUENCE {
+ cCTrCH-ID CCTrCH-ID,
+ iE-Extensions ProtocolExtensionContainer { { CCTrCH-TPCItem-RL-SetupRqstTDD-ExtIEs} } OPTIONAL,
+ ...
+}
+
+CCTrCH-TPCItem-RL-SetupRqstTDD-ExtIEs NBAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+DL-DPCH-Information-RL-SetupRqstTDD ::= ProtocolIE-Single-Container{{ DL-DPCH-InformationIE-RL-SetupRqstTDD }}
+
+DL-DPCH-InformationIE-RL-SetupRqstTDD NBAP-PROTOCOL-IES ::= {
+ { ID id-DL-DPCH-InformationList-RL-SetupRqstTDD CRITICALITY notify TYPE DL-DPCH-InformationItem-RL-SetupRqstTDD PRESENCE mandatory }
+}
+
+DL-DPCH-InformationItem-RL-SetupRqstTDD ::= SEQUENCE {
+ repetitionPeriod RepetitionPeriod,
+ repetitionLength RepetitionLength,
+ tdd-DPCHOffset TDD-DPCHOffset,
+ dL-Timeslot-Information DL-Timeslot-Information,
+ iE-Extensions ProtocolExtensionContainer { { DL-DPCH-InformationItem-RL-SetupRqstTDD-ExtIEs} } OPTIONAL,
+ ...
+}
+
+DL-DPCH-InformationItem-RL-SetupRqstTDD-ExtIEs NBAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+DL-DPCH-LCR-Information-RL-SetupRqstTDD ::= SEQUENCE {
+ repetitionPeriod RepetitionPeriod,
+ repetitionLength RepetitionLength,
+ tdd-DPCHOffset TDD-DPCHOffset,
+ dL-TimeslotLCR-Information DL-TimeslotLCR-Information,
+ tstdIndicator TSTD-Indicator,
+ iE-Extensions ProtocolExtensionContainer { { DL-DPCH-LCR-InformationItem-RL-SetupRqstTDD-ExtIEs} } OPTIONAL,
+ ...
+}
+
+DL-DPCH-LCR-InformationItem-RL-SetupRqstTDD-ExtIEs NBAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+RL-Information-RL-SetupRqstTDD ::= SEQUENCE {
+ rL-ID RL-ID,
+ c-ID C-ID,
+ frameOffset FrameOffset,
+ specialBurstScheduling SpecialBurstScheduling,
+ initialDL-transmissionPower DL-Power,
+ maximumDL-power DL-Power,
+ minimumDL-power DL-Power,
+ dL-TimeSlotISCPInfo DL-TimeslotISCPInfo OPTIONAL, -- Applicable to 3.84Mcps TDD only
+ iE-Extensions ProtocolExtensionContainer { { RL-Information-RL-SetupRqstTDD-ExtIEs} } OPTIONAL,
+ ...
+}
+
+RL-Information-RL-SetupRqstTDD-ExtIEs NBAP-PROTOCOL-EXTENSION ::= {
+ { ID id-TimeslotISCP-LCR-InfoList-RL-SetupRqstTDD CRITICALITY reject EXTENSION DL-TimeslotISCPInfoLCR PRESENCE optional }|
+ -- Applicable to 1.28Mcps TDD only
+ { ID id-RL-Specific-DCH-Info CRITICALITY ignore EXTENSION RL-Specific-DCH-Info PRESENCE optional }|
+ { ID id-DelayedActivation CRITICALITY reject EXTENSION DelayedActivation PRESENCE optional }|
+ { ID id-UL-Synchronisation-Parameters-LCR CRITICALITY ignore EXTENSION UL-Synchronisation-Parameters-LCR PRESENCE optional },
+ -- Mandatory for 1.28Mcps TDD, Not Applicable to 3.84Mcps TDD
+ ...
+}
+
+-- **************************************************************
+--
+-- RADIO LINK SETUP RESPONSE FDD
+--
+-- **************************************************************
+
+RadioLinkSetupResponseFDD ::= SEQUENCE {
+ protocolIEs ProtocolIE-Container {{RadioLinkSetupResponseFDD-IEs}},
+ protocolExtensions ProtocolExtensionContainer {{RadioLinkSetupResponseFDD-Extensions}} OPTIONAL,
+ ...
+}
+
+RadioLinkSetupResponseFDD-IEs NBAP-PROTOCOL-IES ::= {
+ { ID id-CRNC-CommunicationContextID CRITICALITY ignore TYPE CRNC-CommunicationContextID PRESENCE mandatory}|
+ { ID id-NodeB-CommunicationContextID CRITICALITY ignore TYPE NodeB-CommunicationContextID PRESENCE mandatory}|
+ { ID id-CommunicationControlPortID CRITICALITY ignore TYPE CommunicationControlPortID PRESENCE mandatory}|
+ { ID id-RL-InformationResponseList-RL-SetupRspFDD CRITICALITY ignore TYPE RL-InformationResponseList-RL-SetupRspFDD PRESENCE mandatory}|
+ { ID id-TFCI2-BearerInformationResponse CRITICALITY ignore TYPE TFCI2-BearerInformationResponse PRESENCE optional}|
+ { ID id-CriticalityDiagnostics CRITICALITY ignore TYPE CriticalityDiagnostics PRESENCE optional},
+ ...
+}
+
+RadioLinkSetupResponseFDD-Extensions NBAP-PROTOCOL-EXTENSION ::= {
+ { ID id-HSDSCH-FDD-Information-Response CRITICALITY ignore EXTENSION HSDSCH-FDD-Information-Response PRESENCE optional}, ...
+}
+
+RL-InformationResponseList-RL-SetupRspFDD ::= SEQUENCE (SIZE (1..maxNrOfRLs)) OF ProtocolIE-Single-Container{{ RL-InformationResponseItemIE-RL-SetupRspFDD }}
+
+RL-InformationResponseItemIE-RL-SetupRspFDD NBAP-PROTOCOL-IES ::= {
+ { ID id-RL-InformationResponseItem-RL-SetupRspFDD CRITICALITY ignore TYPE RL-InformationResponseItem-RL-SetupRspFDD PRESENCE mandatory}
+}
+
+RL-InformationResponseItem-RL-SetupRspFDD ::= SEQUENCE {
+ rL-ID RL-ID,
+ rL-Set-ID RL-Set-ID,
+ received-total-wide-band-power Received-total-wide-band-power-Value,
+ diversityIndication DiversityIndication-RL-SetupRspFDD,
+ dSCH-InformationResponseList DSCH-InformationResponseList-RL-SetupRspFDD OPTIONAL,
+ sSDT-SupportIndicator SSDT-SupportIndicator,
+ iE-Extensions ProtocolExtensionContainer { { RL-InformationResponseItem-RL-SetupRspFDD-ExtIEs} } OPTIONAL,
+ ...
+}
+
+RL-InformationResponseItem-RL-SetupRspFDD-ExtIEs NBAP-PROTOCOL-EXTENSION ::= {
+ { ID id-DL-PowerBalancing-ActivationIndicator CRITICALITY ignore EXTENSION DL-PowerBalancing-ActivationIndicator PRESENCE optional},
+ ...
+}
+
+DiversityIndication-RL-SetupRspFDD ::= CHOICE {
+ combining Combining-RL-SetupRspFDD,
+ nonCombiningOrFirstRL NonCombiningOrFirstRL-RL-SetupRspFDD
+}
+
+Combining-RL-SetupRspFDD ::= SEQUENCE {
+ rL-ID RL-ID,
+ iE-Extensions ProtocolExtensionContainer { { Combining-RL-SetupRspFDD-ExtIEs} } OPTIONAL,
+ ...
+}
+
+Combining-RL-SetupRspFDD-ExtIEs NBAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+NonCombiningOrFirstRL-RL-SetupRspFDD ::= SEQUENCE {
+ dCH-InformationResponse DCH-InformationResponse,
+ iE-Extensions ProtocolExtensionContainer { { NonCombiningOrFirstRLItem-RL-SetupRspFDD-ExtIEs} } OPTIONAL,
+ ...
+}
+
+NonCombiningOrFirstRLItem-RL-SetupRspFDD-ExtIEs NBAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+DSCH-InformationResponseList-RL-SetupRspFDD ::= ProtocolIE-Single-Container {{ DSCH-InformationResponseListIEs-RL-SetupRspFDD }}
+
+DSCH-InformationResponseListIEs-RL-SetupRspFDD NBAP-PROTOCOL-IES ::= {
+ { ID id-DSCH-InformationResponse CRITICALITY ignore TYPE DSCH-InformationResponse PRESENCE mandatory }
+}
+
+-- **************************************************************
+--
+-- RADIO LINK SETUP RESPONSE TDD
+--
+-- **************************************************************
+
+RadioLinkSetupResponseTDD ::= SEQUENCE {
+ protocolIEs ProtocolIE-Container {{RadioLinkSetupResponseTDD-IEs}},
+ protocolExtensions ProtocolExtensionContainer {{RadioLinkSetupResponseTDD-Extensions}} OPTIONAL,
+ ...
+}
+
+RadioLinkSetupResponseTDD-IEs NBAP-PROTOCOL-IES ::= {
+ { ID id-CRNC-CommunicationContextID CRITICALITY ignore TYPE CRNC-CommunicationContextID PRESENCE mandatory }|
+ { ID id-NodeB-CommunicationContextID CRITICALITY ignore TYPE NodeB-CommunicationContextID PRESENCE mandatory }|
+ { ID id-CommunicationControlPortID CRITICALITY ignore TYPE CommunicationControlPortID PRESENCE mandatory }|
+ { ID id-RL-InformationResponse-RL-SetupRspTDD CRITICALITY ignore TYPE RL-InformationResponse-RL-SetupRspTDD PRESENCE optional }|
+ -- Mandatory for 3.84Mcps TDD, Not Applicable to 1.28Mcps TDD
+ { ID id-CriticalityDiagnostics CRITICALITY ignore TYPE CriticalityDiagnostics PRESENCE optional },
+ ...
+}
+
+RadioLinkSetupResponseTDD-Extensions NBAP-PROTOCOL-EXTENSION ::= {
+ { ID id-RL-InformationResponse-LCR-RL-SetupRspTDD CRITICALITY ignore EXTENSION RL-InformationResponse-LCR-RL-SetupRspTDD PRESENCE optional }| -- Mandatory for 1.28Mcps TDD, Not Applicable to 3.84Mcps TDD
+ { ID id-HSDSCH-TDD-Information-Response CRITICALITY ignore EXTENSION HSDSCH-TDD-Information-Response PRESENCE optional },
+ ...
+}
+
+RL-InformationResponse-RL-SetupRspTDD ::= SEQUENCE {
+ rL-ID RL-ID,
+ uL-TimeSlot-ISCP-Info UL-TimeSlot-ISCP-Info,
+ ul-PhysCH-SF-Variation UL-PhysCH-SF-Variation,
+ dCH-InformationResponseList DCH-InformationResponseList-RL-SetupRspTDD OPTIONAL,
+ dSCH-InformationResponseList DSCH-InformationResponseList-RL-SetupRspTDD OPTIONAL,
+ uSCH-InformationResponseList USCH-InformationResponseList-RL-SetupRspTDD OPTIONAL,
+ iE-Extensions ProtocolExtensionContainer { { RL-InformationResponseList-RL-SetupRspTDD-ExtIEs} } OPTIONAL,
+ ...
+}
+
+RL-InformationResponseList-RL-SetupRspTDD-ExtIEs NBAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+DCH-InformationResponseList-RL-SetupRspTDD ::= ProtocolIE-Single-Container{{ DCH-InformationResponseListIEs-RL-SetupRspTDD }}
+
+DCH-InformationResponseListIEs-RL-SetupRspTDD NBAP-PROTOCOL-IES ::= {
+ { ID id-DCH-InformationResponse CRITICALITY ignore TYPE DCH-InformationResponse PRESENCE mandatory}
+ }
+
+DSCH-InformationResponseList-RL-SetupRspTDD ::= ProtocolIE-Single-Container {{ DSCH-InformationResponseListIEs-RL-SetupRspTDD }}
+
+DSCH-InformationResponseListIEs-RL-SetupRspTDD NBAP-PROTOCOL-IES ::= {
+ { ID id-DSCH-InformationResponse CRITICALITY ignore TYPE DSCH-InformationResponse PRESENCE mandatory }
+}
+
+USCH-InformationResponseList-RL-SetupRspTDD ::= ProtocolIE-Single-Container {{ USCH-InformationResponseListIEs-RL-SetupRspTDD }}
+
+USCH-InformationResponseListIEs-RL-SetupRspTDD NBAP-PROTOCOL-IES ::= {
+ { ID id-USCH-InformationResponse CRITICALITY ignore TYPE USCH-InformationResponse PRESENCE mandatory }
+}
+
+RL-InformationResponse-LCR-RL-SetupRspTDD ::= SEQUENCE {
+ rL-ID RL-ID,
+ uL-TimeSlot-ISCP-LCR-Info UL-TimeSlot-ISCP-LCR-Info,
+ ul-PhysCH-SF-Variation UL-PhysCH-SF-Variation,
+ dCH-InformationResponseList DCH-InformationResponseList-RL-SetupRspTDD OPTIONAL,
+ dSCH-InformationResponseList DSCH-InformationResponseList-RL-SetupRspTDD OPTIONAL,
+ uSCH-InformationResponseList USCH-InformationResponseList-RL-SetupRspTDD OPTIONAL,
+ iE-Extensions ProtocolExtensionContainer { { RL-InformationResponseList-LCR-RL-SetupRspTDD-ExtIEs} } OPTIONAL,
+ ...
+}
+
+RL-InformationResponseList-LCR-RL-SetupRspTDD-ExtIEs NBAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+-- **************************************************************
+--
+-- RADIO LINK SETUP FAILURE FDD
+--
+-- **************************************************************
+
+RadioLinkSetupFailureFDD ::= SEQUENCE {
+ protocolIEs ProtocolIE-Container {{RadioLinkSetupFailureFDD-IEs}},
+ protocolExtensions ProtocolExtensionContainer {{RadioLinkSetupFailureFDD-Extensions}} OPTIONAL,
+ ...
+}
+
+RadioLinkSetupFailureFDD-IEs NBAP-PROTOCOL-IES ::= {
+ { ID id-CRNC-CommunicationContextID CRITICALITY ignore TYPE CRNC-CommunicationContextID PRESENCE mandatory }|
+ { ID id-NodeB-CommunicationContextID CRITICALITY ignore TYPE NodeB-CommunicationContextID PRESENCE conditional }|
+ -- This IE shall be present if at least one of the radio links has been successfully set up
+ { ID id-CommunicationControlPortID CRITICALITY ignore TYPE CommunicationControlPortID PRESENCE optional }|
+ { ID id-CauseLevel-RL-SetupFailureFDD CRITICALITY ignore TYPE CauseLevel-RL-SetupFailureFDD PRESENCE mandatory }|
+ { ID id-CriticalityDiagnostics CRITICALITY ignore TYPE CriticalityDiagnostics PRESENCE optional },
+ ...
+}
+
+RadioLinkSetupFailureFDD-Extensions NBAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+CauseLevel-RL-SetupFailureFDD ::= CHOICE {
+ generalCause GeneralCauseList-RL-SetupFailureFDD,
+ rLSpecificCause RLSpecificCauseList-RL-SetupFailureFDD,
+ ...
+}
+
+GeneralCauseList-RL-SetupFailureFDD ::= SEQUENCE {
+ cause Cause,
+ iE-Extensions ProtocolExtensionContainer { { GeneralCauseItem-RL-SetupFailureFDD-ExtIEs} } OPTIONAL,
+ ...
+}
+
+GeneralCauseItem-RL-SetupFailureFDD-ExtIEs NBAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+RLSpecificCauseList-RL-SetupFailureFDD ::= SEQUENCE {
+ unsuccessful-RL-InformationRespList-RL-SetupFailureFDD Unsuccessful-RL-InformationRespList-RL-SetupFailureFDD,
+ successful-RL-InformationRespList-RL-SetupFailureFDD Successful-RL-InformationRespList-RL-SetupFailureFDD OPTIONAL,
+ iE-Extensions ProtocolExtensionContainer { { RLSpecificCauseItem-RL-SetupFailureFDD-ExtIEs} } OPTIONAL,
+ ...
+}
+
+RLSpecificCauseItem-RL-SetupFailureFDD-ExtIEs NBAP-PROTOCOL-EXTENSION ::= {
+ { ID id-HSDSCH-FDD-Information-Response CRITICALITY ignore EXTENSION HSDSCH-FDD-Information-Response PRESENCE optional},
+ ...
+}
+
+Unsuccessful-RL-InformationRespList-RL-SetupFailureFDD ::= SEQUENCE (SIZE (1..maxNrOfRLs)) OF ProtocolIE-Single-Container {{ Unsuccessful-RL-InformationRespItemIE-RL-SetupFailureFDD }}
+
+Unsuccessful-RL-InformationRespItemIE-RL-SetupFailureFDD NBAP-PROTOCOL-IES ::= {
+ { ID id-Unsuccessful-RL-InformationRespItem-RL-SetupFailureFDD CRITICALITY ignore TYPE Unsuccessful-RL-InformationRespItem-RL-SetupFailureFDD PRESENCE mandatory}
+}
+
+Unsuccessful-RL-InformationRespItem-RL-SetupFailureFDD ::= SEQUENCE {
+ rL-ID RL-ID,
+ cause Cause,
+ iE-Extensions ProtocolExtensionContainer { { Unsuccessful-RL-InformationRespItem-RL-SetupFailureFDD-ExtIEs} } OPTIONAL,
+ ...
+}
+
+Unsuccessful-RL-InformationRespItem-RL-SetupFailureFDD-ExtIEs NBAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+Successful-RL-InformationRespList-RL-SetupFailureFDD ::= SEQUENCE (SIZE (1.. maxNrOfRLs)) OF ProtocolIE-Single-Container {{ Successful-RL-InformationRespItemIE-RL-SetupFailureFDD }}
+
+Successful-RL-InformationRespItemIE-RL-SetupFailureFDD NBAP-PROTOCOL-IES ::= {
+ { ID id-Successful-RL-InformationRespItem-RL-SetupFailureFDD CRITICALITY ignore TYPE Successful-RL-InformationRespItem-RL-SetupFailureFDD PRESENCE mandatory}
+}
+
+Successful-RL-InformationRespItem-RL-SetupFailureFDD ::= SEQUENCE {
+ rL-ID RL-ID,
+ rL-Set-ID RL-Set-ID,
+ received-total-wide-band-power Received-total-wide-band-power-Value,
+ diversityIndication DiversityIndication-RL-SetupFailureFDD,
+ dSCH-InformationResponseList DSCH-InformationRespList-RL-SetupFailureFDD OPTIONAL,
+ tFCI2-BearerInformationResponse TFCI2-BearerInformationResponse OPTIONAL,
+ -- There shall be only one TFCI2 bearer per Node B Communication Context.
+ sSDT-SupportIndicator SSDT-SupportIndicator,
+ iE-Extensions ProtocolExtensionContainer { { Successful-RL-InformationRespItem-RL-SetupFailureFDD-ExtIEs} } OPTIONAL,
+ ...
+}
+
+Successful-RL-InformationRespItem-RL-SetupFailureFDD-ExtIEs NBAP-PROTOCOL-EXTENSION ::= {
+ { ID id-DL-PowerBalancing-ActivationIndicator CRITICALITY ignore EXTENSION DL-PowerBalancing-ActivationIndicator PRESENCE optional},
+ ...
+}
+
+DiversityIndication-RL-SetupFailureFDD ::= CHOICE {
+ combining Combining-RL-SetupFailureFDD,
+ nonCombiningOrFirstRL NonCombiningOrFirstRL-RL-SetupFailureFDD
+}
+
+Combining-RL-SetupFailureFDD ::= SEQUENCE {
+ rL-ID RL-ID,
+ iE-Extensions ProtocolExtensionContainer { { CombiningItem-RL-SetupFailureFDD-ExtIEs} } OPTIONAL,
+ ...
+ }
+
+CombiningItem-RL-SetupFailureFDD-ExtIEs NBAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+NonCombiningOrFirstRL-RL-SetupFailureFDD ::= SEQUENCE {
+ dCH-InformationResponse DCH-InformationResponse,
+ iE-Extensions ProtocolExtensionContainer { { NonCombiningOrFirstRLItem-RL-SetupFailureFDD-ExtIEs} } OPTIONAL,
+ ...
+}
+
+NonCombiningOrFirstRLItem-RL-SetupFailureFDD-ExtIEs NBAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+DSCH-InformationRespList-RL-SetupFailureFDD ::= ProtocolIE-Single-Container {{ DSCH-InformationRespListIEs-RL-SetupFailureFDD }}
+
+DSCH-InformationRespListIEs-RL-SetupFailureFDD NBAP-PROTOCOL-IES ::= {
+ { ID id-DSCH-InformationResponse CRITICALITY ignore TYPE DSCH-InformationResponse PRESENCE mandatory }
+}
+
+-- **************************************************************
+--
+-- RADIO LINK SETUP FAILURE TDD
+--
+-- **************************************************************
+
+RadioLinkSetupFailureTDD ::= SEQUENCE {
+ protocolIEs ProtocolIE-Container {{RadioLinkSetupFailureTDD-IEs}},
+ protocolExtensions ProtocolExtensionContainer {{RadioLinkSetupFailureTDD-Extensions}} OPTIONAL,
+ ...
+}
+
+RadioLinkSetupFailureTDD-IEs NBAP-PROTOCOL-IES ::= {
+ { ID id-CRNC-CommunicationContextID CRITICALITY ignore TYPE CRNC-CommunicationContextID PRESENCE mandatory }|
+ { ID id-CauseLevel-RL-SetupFailureTDD CRITICALITY ignore TYPE CauseLevel-RL-SetupFailureTDD PRESENCE mandatory }|
+ { ID id-CriticalityDiagnostics CRITICALITY ignore TYPE CriticalityDiagnostics PRESENCE optional },
+ ...
+}
+
+RadioLinkSetupFailureTDD-Extensions NBAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+CauseLevel-RL-SetupFailureTDD ::= CHOICE {
+ generalCause GeneralCauseList-RL-SetupFailureTDD,
+ rLSpecificCause RLSpecificCauseList-RL-SetupFailureTDD,
+ ...
+}
+
+GeneralCauseList-RL-SetupFailureTDD ::= SEQUENCE {
+ cause Cause,
+ iE-Extensions ProtocolExtensionContainer { { GeneralCauseItem-RL-SetupFailureTDD-ExtIEs} } OPTIONAL,
+ ...
+}
+
+GeneralCauseItem-RL-SetupFailureTDD-ExtIEs NBAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+RLSpecificCauseList-RL-SetupFailureTDD ::= SEQUENCE {
+ unsuccessful-RL-InformationRespItem-RL-SetupFailureTDD Unsuccessful-RL-InformationRespItem-RL-SetupFailureTDD,
+ iE-Extensions ProtocolExtensionContainer { { RLSpecificCauseItem-RL-SetupFailureTDD-ExtIEs} } OPTIONAL,
+ ...
+}
+
+RLSpecificCauseItem-RL-SetupFailureTDD-ExtIEs NBAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+Unsuccessful-RL-InformationRespItem-RL-SetupFailureTDD ::= ProtocolIE-Single-Container { {Unsuccessful-RL-InformationRespItemIE-RL-SetupFailureTDD} }
+
+Unsuccessful-RL-InformationRespItemIE-RL-SetupFailureTDD NBAP-PROTOCOL-IES ::= {
+ { ID id-Unsuccessful-RL-InformationResp-RL-SetupFailureTDD CRITICALITY ignore TYPE Unsuccessful-RL-InformationResp-RL-SetupFailureTDD PRESENCE mandatory }
+}
+
+Unsuccessful-RL-InformationResp-RL-SetupFailureTDD ::= SEQUENCE {
+ rL-ID RL-ID,
+ cause Cause,
+ iE-Extensions ProtocolExtensionContainer { { Unsuccessful-RL-InformationResp-RL-SetupFailureTDD-ExtIEs} } OPTIONAL,
+ ...
+}
+
+Unsuccessful-RL-InformationResp-RL-SetupFailureTDD-ExtIEs NBAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+-- **************************************************************
+--
+-- RADIO LINK ADDITION REQUEST FDD
+--
+-- **************************************************************
+
+RadioLinkAdditionRequestFDD ::= SEQUENCE {
+ protocolIEs ProtocolIE-Container {{RadioLinkAdditionRequestFDD-IEs}},
+ protocolExtensions ProtocolExtensionContainer {{RadioLinkAdditionRequestFDD-Extensions}} OPTIONAL,
+ ...
+}
+
+RadioLinkAdditionRequestFDD-IEs NBAP-PROTOCOL-IES ::= {
+ { ID id-NodeB-CommunicationContextID CRITICALITY reject TYPE NodeB-CommunicationContextID PRESENCE mandatory } |
+ { ID id-Compressed-Mode-Deactivation-Flag CRITICALITY reject TYPE Compressed-Mode-Deactivation-Flag PRESENCE optional }|
+ { ID id-RL-InformationList-RL-AdditionRqstFDD CRITICALITY notify TYPE RL-InformationList-RL-AdditionRqstFDD PRESENCE mandatory },
+ ...
+}
+
+RadioLinkAdditionRequestFDD-Extensions NBAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+RL-InformationList-RL-AdditionRqstFDD ::= SEQUENCE (SIZE (1..maxNrOfRLs-1)) OF ProtocolIE-Single-Container {{ RL-InformationItemIE-RL-AdditionRqstFDD}}
+
+RL-InformationItemIE-RL-AdditionRqstFDD NBAP-PROTOCOL-IES ::= {
+ { ID id-RL-InformationItem-RL-AdditionRqstFDD CRITICALITY notify TYPE RL-InformationItem-RL-AdditionRqstFDD PRESENCE mandatory}
+}
+
+RL-InformationItem-RL-AdditionRqstFDD ::= SEQUENCE {
+ rL-ID RL-ID,
+ c-ID C-ID,
+ frameOffset FrameOffset,
+ chipOffset ChipOffset,
+ diversityControlField DiversityControlField,
+ dl-CodeInformation FDD-DL-CodeInformation,
+ initialDL-TransmissionPower DL-Power OPTIONAL,
+ maximumDL-Power DL-Power OPTIONAL,
+ minimumDL-Power DL-Power OPTIONAL,
+ sSDT-CellIdentity SSDT-Cell-Identity OPTIONAL,
+ transmitDiversityIndicator TransmitDiversityIndicator OPTIONAL,
+ iE-Extensions ProtocolExtensionContainer { { RL-InformationItem-RL-AdditionRqstFDD-ExtIEs} } OPTIONAL,
+ ...
+}
+
+RL-InformationItem-RL-AdditionRqstFDD-ExtIEs NBAP-PROTOCOL-EXTENSION ::= {
+ { ID id-DLReferencePower CRITICALITY ignore EXTENSION DL-Power PRESENCE optional}|
+ { ID id-RL-Specific-DCH-Info CRITICALITY ignore EXTENSION RL-Specific-DCH-Info PRESENCE optional }|
+ { ID id-DelayedActivation CRITICALITY reject EXTENSION DelayedActivation PRESENCE optional }|
+ { ID id-Qth-Parameter CRITICALITY ignore EXTENSION Qth-Parameter PRESENCE optional }|
+ { ID id-Primary-CPICH-Usage-for-Channel-Estimation CRITICALITY ignore EXTENSION Primary-CPICH-Usage-for-Channel-Estimation PRESENCE optional },
+ ...
+}
+
+-- **************************************************************
+--
+-- RADIO LINK ADDITION REQUEST TDD
+--
+-- **************************************************************
+
+RadioLinkAdditionRequestTDD ::= SEQUENCE {
+ protocolIEs ProtocolIE-Container {{RadioLinkAdditionRequestTDD-IEs}},
+ protocolExtensions ProtocolExtensionContainer {{RadioLinkAdditionRequestTDD-Extensions}} OPTIONAL,
+ ...
+}
+
+RadioLinkAdditionRequestTDD-IEs NBAP-PROTOCOL-IES ::= {
+ { ID id-NodeB-CommunicationContextID CRITICALITY reject TYPE NodeB-CommunicationContextID PRESENCE mandatory }|
+ { ID id-UL-CCTrCH-InformationList-RL-AdditionRqstTDD CRITICALITY reject TYPE UL-CCTrCH-InformationList-RL-AdditionRqstTDD PRESENCE optional }|
+ { ID id-DL-CCTrCH-InformationList-RL-AdditionRqstTDD CRITICALITY reject TYPE DL-CCTrCH-InformationList-RL-AdditionRqstTDD PRESENCE optional }|
+ { ID id-RL-Information-RL-AdditionRqstTDD CRITICALITY reject TYPE RL-Information-RL-AdditionRqstTDD PRESENCE mandatory },
+ ...
+}
+
+RadioLinkAdditionRequestTDD-Extensions NBAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+UL-CCTrCH-InformationList-RL-AdditionRqstTDD ::= SEQUENCE (SIZE (1..maxNrOfCCTrCHs)) OF UL-CCTrCH-InformationItem-RL-AdditionRqstTDD
+
+UL-CCTrCH-InformationItem-RL-AdditionRqstTDD ::= SEQUENCE {
+ cCTrCH-ID CCTrCH-ID,
+ uL-DPCH-Information UL-DPCH-InformationList-RL-AdditionRqstTDD OPTIONAL, -- Applicable to 3.84cps TDD only
+ iE-Extensions ProtocolExtensionContainer { { UL-CCTrCH-InformationItem-RL-AdditionRqstTDD-ExtIEs} } OPTIONAL,
+ ...
+}
+
+UL-CCTrCH-InformationItem-RL-AdditionRqstTDD-ExtIEs NBAP-PROTOCOL-EXTENSION ::= {
+ { ID id-UL-DPCH-InformationItem-LCR-RL-AdditionRqstTDD CRITICALITY notify EXTENSION UL-DPCH-InformationItem-LCR-RL-AdditionRqstTDD PRESENCE optional }| -- Applicable to 1.28cps TDD only
+ { ID id-TDD-TPC-UplinkStepSize-LCR-RL-AdditionRqstTDD CRITICALITY reject EXTENSION TDD-TPC-UplinkStepSize-LCR PRESENCE optional },
+-- Applicable to 1.28cps TDD only
+ ...
+}
+
+UL-DPCH-InformationList-RL-AdditionRqstTDD ::= ProtocolIE-Single-Container {{ UL-DPCH-InformationItemIE-RL-AdditionRqstTDD }}
+
+UL-DPCH-InformationItemIE-RL-AdditionRqstTDD NBAP-PROTOCOL-IES ::= {
+ { ID id-UL-DPCH-InformationItem-RL-AdditionRqstTDD CRITICALITY notify TYPE UL-DPCH-InformationItem-RL-AdditionRqstTDD PRESENCE optional} -- For 3.84Mcps TDD only
+}
+
+UL-DPCH-InformationItem-RL-AdditionRqstTDD ::= SEQUENCE {
+ repetitionPeriod RepetitionPeriod,
+ repetitionLength RepetitionLength,
+ tdd-DPCHOffset TDD-DPCHOffset,
+ uL-Timeslot-Information UL-Timeslot-Information,
+ iE-Extensions ProtocolExtensionContainer { { UL-DPCH-InformationItem-RL-AdditionRqstTDD-ExtIEs} } OPTIONAL,
+ ...
+}
+
+UL-DPCH-InformationItem-RL-AdditionRqstTDD-ExtIEs NBAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+DL-CCTrCH-InformationList-RL-AdditionRqstTDD ::= SEQUENCE (SIZE (1..maxNrOfCCTrCHs)) OF DL-CCTrCH-InformationItem-RL-AdditionRqstTDD
+
+DL-CCTrCH-InformationItem-RL-AdditionRqstTDD ::= SEQUENCE {
+ cCTrCH-ID CCTrCH-ID,
+ dL-DPCH-Information DL-DPCH-InformationList-RL-AdditionRqstTDD OPTIONAL, -- Applicable to 3.84Mcps TDD only
+ iE-Extensions ProtocolExtensionContainer { { DL-CCTrCH-InformationItem-RL-AdditionRqstTDD-ExtIEs} } OPTIONAL,
+ ...
+}
+
+DL-CCTrCH-InformationItem-RL-AdditionRqstTDD-ExtIEs NBAP-PROTOCOL-EXTENSION ::= {
+ { ID id-DL-DPCH-InformationItem-LCR-RL-AdditionRqstTDD CRITICALITY notify EXTENSION DL-DPCH-InformationItem-LCR-RL-AdditionRqstTDD PRESENCE optional }| -- Applicable to 1.28Mcps TDD only
+ { ID id-CCTrCH-Initial-DL-Power-RL-AdditionRqstTDD CRITICALITY ignore EXTENSION DL-Power PRESENCE optional }|
+ { ID id-TDD-TPC-DownlinkStepSize-RL-AdditionRqstTDD CRITICALITY reject EXTENSION TDD-TPC-DownlinkStepSize PRESENCE optional }|
+ { ID id-CCTrCH-Maximum-DL-Power-RL-AdditionRqstTDD CRITICALITY ignore EXTENSION DL-Power PRESENCE optional }|
+ { ID id-CCTrCH-Minimum-DL-Power-RL-AdditionRqstTDD CRITICALITY ignore EXTENSION DL-Power PRESENCE optional },
+ ...
+}
+
+DL-DPCH-InformationList-RL-AdditionRqstTDD ::= ProtocolIE-Single-Container {{ DL-DPCH-InformationItemIE-RL-AdditionRqstTDD }}
+
+DL-DPCH-InformationItemIE-RL-AdditionRqstTDD NBAP-PROTOCOL-IES ::= {
+ { ID id-DL-DPCH-InformationItem-RL-AdditionRqstTDD CRITICALITY notify TYPE DL-DPCH-InformationItem-RL-AdditionRqstTDD PRESENCE mandatory}
+}
+
+DL-DPCH-InformationItem-RL-AdditionRqstTDD ::= SEQUENCE {
+ repetitionPeriod RepetitionPeriod,
+ repetitionLength RepetitionLength,
+ tdd-DPCHOffset TDD-DPCHOffset,
+ dL-Timeslot-Information DL-Timeslot-Information,
+ iE-Extensions ProtocolExtensionContainer { { DL-DPCH-InformationItem-RL-AdditionRqstTDD-ExtIEs} } OPTIONAL,
+ ...
+}
+
+DL-DPCH-InformationItem-RL-AdditionRqstTDD-ExtIEs NBAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+RL-Information-RL-AdditionRqstTDD ::= SEQUENCE {
+ rL-ID RL-ID,
+ c-ID C-ID,
+ frameOffset FrameOffset,
+ diversityControlField DiversityControlField,
+ initial-DL-Transmission-Power DL-Power OPTIONAL,
+ maximumDL-Power DL-Power OPTIONAL,
+ minimumDL-Power DL-Power OPTIONAL,
+ dL-TimeSlotISCPInfo DL-TimeslotISCPInfo OPTIONAL, -- Applicable to 3.84Mcps TDD only
+ iE-Extensions ProtocolExtensionContainer { { RL-information-RL-AdditionRqstTDD-ExtIEs} } OPTIONAL,
+ ...
+ }
+
+RL-information-RL-AdditionRqstTDD-ExtIEs NBAP-PROTOCOL-EXTENSION ::= {
+ { ID id-TimeslotISCP-InformationList-LCR-RL-AdditionRqstTDD CRITICALITY reject EXTENSION DL-TimeslotISCPInfoLCR PRESENCE optional }| -- Applicable to 1.28Mcps TDD only
+ { ID id-RL-Specific-DCH-Info CRITICALITY ignore EXTENSION RL-Specific-DCH-Info PRESENCE optional }|
+ { ID id-DelayedActivation CRITICALITY reject EXTENSION DelayedActivation PRESENCE optional }|
+ { ID id-UL-Synchronisation-Parameters-LCR CRITICALITY ignore EXTENSION UL-Synchronisation-Parameters-LCR PRESENCE optional }, -- Mandatory for 1.28Mcps TDD, Not Applicable to 3.84Mcps TDD
+ ...
+}
+
+UL-DPCH-InformationItem-LCR-RL-AdditionRqstTDD ::= SEQUENCE {
+ repetitionPeriod RepetitionPeriod,
+ repetitionLength RepetitionLength,
+ tdd-DPCHOffset TDD-DPCHOffset,
+ uL-TimeslotLCR-Information UL-TimeslotLCR-Information,
+ iE-Extensions ProtocolExtensionContainer { { UL-DPCH-InformationItem-LCR-RL-AdditionRqstTDD-ExtIEs} } OPTIONAL,
+ ...
+}
+
+UL-DPCH-InformationItem-LCR-RL-AdditionRqstTDD-ExtIEs NBAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+DL-DPCH-InformationItem-LCR-RL-AdditionRqstTDD ::= SEQUENCE {
+ repetitionPeriod RepetitionPeriod,
+ repetitionLength RepetitionLength,
+ tdd-DPCHOffset TDD-DPCHOffset,
+ dL-TimeslotLCR-Information DL-TimeslotLCR-Information,
+ iE-Extensions ProtocolExtensionContainer { { DL-DPCH-InformationItem-LCR-RL-AdditionRqstTDD-ExtIEs} } OPTIONAL,
+ ...
+}
+
+DL-DPCH-InformationItem-LCR-RL-AdditionRqstTDD-ExtIEs NBAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+-- **************************************************************
+--
+-- RADIO LINK ADDITION RESPONSE FDD
+--
+-- **************************************************************
+
+RadioLinkAdditionResponseFDD ::= SEQUENCE {
+ protocolIEs ProtocolIE-Container {{RadioLinkAdditionResponseFDD-IEs}},
+ protocolExtensions ProtocolExtensionContainer {{RadioLinkAdditionResponseFDD-Extensions}} OPTIONAL,
+ ...
+}
+
+RadioLinkAdditionResponseFDD-IEs NBAP-PROTOCOL-IES ::= {
+ { ID id-CRNC-CommunicationContextID CRITICALITY ignore TYPE CRNC-CommunicationContextID PRESENCE mandatory }|
+ { ID id-RL-InformationResponseList-RL-AdditionRspFDD CRITICALITY ignore TYPE RL-InformationResponseList-RL-AdditionRspFDD PRESENCE mandatory }|
+ { ID id-CriticalityDiagnostics CRITICALITY ignore TYPE CriticalityDiagnostics PRESENCE optional },
+ ...
+}
+
+RadioLinkAdditionResponseFDD-Extensions NBAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+RL-InformationResponseList-RL-AdditionRspFDD ::= SEQUENCE (SIZE (1..maxNrOfRLs-1)) OF ProtocolIE-Single-Container {{ RL-InformationResponseItemIE-RL-AdditionRspFDD }}
+
+RL-InformationResponseItemIE-RL-AdditionRspFDD NBAP-PROTOCOL-IES ::= {
+ { ID id-RL-InformationResponseItem-RL-AdditionRspFDD CRITICALITY ignore TYPE RL-InformationResponseItem-RL-AdditionRspFDD PRESENCE mandatory}
+}
+
+RL-InformationResponseItem-RL-AdditionRspFDD ::= SEQUENCE {
+ rL-ID RL-ID,
+ rL-Set-ID RL-Set-ID,
+ received-total-wide-band-power Received-total-wide-band-power-Value,
+ diversityIndication DiversityIndication-RL-AdditionRspFDD,
+ sSDT-SupportIndicator SSDT-SupportIndicator,
+ iE-Extensions ProtocolExtensionContainer { { RL-InformationResponseItem-RL-AdditionRspFDD-ExtIEs} } OPTIONAL,
+ ...
+}
+
+RL-InformationResponseItem-RL-AdditionRspFDD-ExtIEs NBAP-PROTOCOL-EXTENSION ::= {
+ { ID id-DL-PowerBalancing-ActivationIndicator CRITICALITY ignore EXTENSION DL-PowerBalancing-ActivationIndicator PRESENCE optional},
+ ...
+}
+
+DiversityIndication-RL-AdditionRspFDD ::= CHOICE {
+ combining Combining-RL-AdditionRspFDD,
+ non-combining Non-Combining-RL-AdditionRspFDD
+}
+
+Combining-RL-AdditionRspFDD ::= SEQUENCE {
+ rL-ID RL-ID,
+ iE-Extensions ProtocolExtensionContainer { { CombiningItem-RL-AdditionRspFDD-ExtIEs} } OPTIONAL,
+ ...
+}
+
+CombiningItem-RL-AdditionRspFDD-ExtIEs NBAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+Non-Combining-RL-AdditionRspFDD ::= SEQUENCE {
+ dCH-InformationResponse DCH-InformationResponse,
+ iE-Extensions ProtocolExtensionContainer { { Non-CombiningItem-RL-AdditionRspFDD-ExtIEs} } OPTIONAL,
+ ...
+}
+
+Non-CombiningItem-RL-AdditionRspFDD-ExtIEs NBAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+-- **************************************************************
+--
+-- RADIO LINK ADDITION RESPONSE TDD
+--
+-- **************************************************************
+
+RadioLinkAdditionResponseTDD ::= SEQUENCE {
+ protocolIEs ProtocolIE-Container {{RadioLinkAdditionResponseTDD-IEs}},
+ protocolExtensions ProtocolExtensionContainer {{RadioLinkAdditionResponseTDD-Extensions}} OPTIONAL,
+ ...
+}
+
+RadioLinkAdditionResponseTDD-IEs NBAP-PROTOCOL-IES ::= {
+ { ID id-CRNC-CommunicationContextID CRITICALITY ignore TYPE CRNC-CommunicationContextID PRESENCE mandatory }|
+ { ID id-RL-InformationResponse-RL-AdditionRspTDD CRITICALITY ignore TYPE RL-InformationResponse-RL-AdditionRspTDD PRESENCE optional }| -- Mandatory for 3.84Mcps TDD, Not Applicable to 1.28Mcps TDD
+ { ID id-CriticalityDiagnostics CRITICALITY ignore TYPE CriticalityDiagnostics PRESENCE optional },
+ ...
+}
+
+RadioLinkAdditionResponseTDD-Extensions NBAP-PROTOCOL-EXTENSION ::= {
+ { ID id-RL-InformationResponse-LCR-RL-AdditionRspTDD CRITICALITY ignore EXTENSION RL-InformationResponse-LCR-RL-AdditionRspTDD PRESENCE optional }, -- Mandatory for 1.28Mcps TDD, Not Applicable to 3.84Mcps TDD
+ ...
+}
+
+RL-InformationResponse-RL-AdditionRspTDD ::= SEQUENCE {
+ rL-ID RL-ID,
+ uL-TimeSlot-ISCP-Info UL-TimeSlot-ISCP-Info,
+ ul-PhysCH-SF-Variation UL-PhysCH-SF-Variation,
+ dCH-Information DCH-Information-RL-AdditionRspTDD OPTIONAL,
+ dSCH-InformationResponseList DSCH-InformationResponseList-RL-AdditionRspTDD OPTIONAL,
+ uSCH-InformationResponseList USCH-InformationResponseList-RL-AdditionRspTDD OPTIONAL,
+ iE-Extensions ProtocolExtensionContainer { { RL-InformationResponse-RL-AdditionRspTDD-ExtIEs} } OPTIONAL,
+ ...
+}
+
+RL-InformationResponse-RL-AdditionRspTDD-ExtIEs NBAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+DCH-Information-RL-AdditionRspTDD ::= SEQUENCE {
+ diversityIndication DiversityIndication-RL-AdditionRspTDD,
+ iE-Extensions ProtocolExtensionContainer { { DCH-Information-RL-AdditionRspTDD-ExtIEs} } OPTIONAL,
+ ...
+}
+
+DCH-Information-RL-AdditionRspTDD-ExtIEs NBAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+DiversityIndication-RL-AdditionRspTDD ::= CHOICE {
+ combining Combining-RL-AdditionRspTDD, -- Indicates whether the old Transport Bearer shall be reused or not
+ non-Combining Non-Combining-RL-AdditionRspTDD
+}
+
+Combining-RL-AdditionRspTDD ::= SEQUENCE {
+ rL-ID RL-ID, -- Reference RL
+ iE-Extensions ProtocolExtensionContainer { { CombiningItem-RL-AdditionRspTDD-ExtIEs} } OPTIONAL,
+ ...
+}
+
+CombiningItem-RL-AdditionRspTDD-ExtIEs NBAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+Non-Combining-RL-AdditionRspTDD ::= SEQUENCE {
+ dCH-InformationResponse DCH-InformationResponse,
+ iE-Extensions ProtocolExtensionContainer { { Non-CombiningItem-RL-AdditionRspTDD-ExtIEs} } OPTIONAL,
+ ...
+}
+
+Non-CombiningItem-RL-AdditionRspTDD-ExtIEs NBAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+DSCH-InformationResponseList-RL-AdditionRspTDD ::= ProtocolIE-Single-Container {{ DSCH-InformationResponseListIEs-RL-AdditionRspTDD }}
+
+DSCH-InformationResponseListIEs-RL-AdditionRspTDD NBAP-PROTOCOL-IES ::= {
+ { ID id-DSCH-InformationResponse CRITICALITY ignore TYPE DSCH-InformationResponse PRESENCE mandatory }
+}
+
+USCH-InformationResponseList-RL-AdditionRspTDD ::= ProtocolIE-Single-Container {{ USCH-InformationResponseListIEs-RL-AdditionRspTDD }}
+
+USCH-InformationResponseListIEs-RL-AdditionRspTDD NBAP-PROTOCOL-IES ::= {
+ { ID id-USCH-InformationResponse CRITICALITY ignore TYPE USCH-InformationResponse PRESENCE mandatory }
+}
+
+RL-InformationResponse-LCR-RL-AdditionRspTDD ::= SEQUENCE {
+ rL-ID RL-ID,
+ uL-TimeSlot-ISCP-InfoLCR UL-TimeSlot-ISCP-LCR-Info,
+ ul-PhysCH-SF-Variation UL-PhysCH-SF-Variation,
+ dCH-Information DCH-Information-RL-AdditionRspTDD OPTIONAL,
+ dSCH-InformationResponseList DSCH-InformationResponseList-RL-AdditionRspTDD OPTIONAL,
+ uSCH-InformationResponseList USCH-InformationResponseList-RL-AdditionRspTDD OPTIONAL,
+ iE-Extensions ProtocolExtensionContainer { { RL-InformationResponse-LCR-RL-AdditionRspTDD-ExtIEs} } OPTIONAL,
+ ...
+}
+
+RL-InformationResponse-LCR-RL-AdditionRspTDD-ExtIEs NBAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+-- **************************************************************
+--
+-- RADIO LINK ADDITION FAILURE FDD
+--
+-- **************************************************************
+
+RadioLinkAdditionFailureFDD ::= SEQUENCE {
+ protocolIEs ProtocolIE-Container {{RadioLinkAdditionFailureFDD-IEs}},
+ protocolExtensions ProtocolExtensionContainer {{RadioLinkAdditionFailureFDD-Extensions}} OPTIONAL,
+ ...
+}
+
+RadioLinkAdditionFailureFDD-IEs NBAP-PROTOCOL-IES ::= {
+ { ID id-CRNC-CommunicationContextID CRITICALITY ignore TYPE CRNC-CommunicationContextID PRESENCE mandatory }|
+ { ID id-CauseLevel-RL-AdditionFailureFDD CRITICALITY ignore TYPE CauseLevel-RL-AdditionFailureFDD PRESENCE mandatory }|
+ { ID id-CriticalityDiagnostics CRITICALITY ignore TYPE CriticalityDiagnostics PRESENCE optional },
+ ...
+}
+
+RadioLinkAdditionFailureFDD-Extensions NBAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+CauseLevel-RL-AdditionFailureFDD ::= CHOICE {
+ generalCause GeneralCauseList-RL-AdditionFailureFDD,
+ rLSpecificCause RLSpecificCauseList-RL-AdditionFailureFDD,
+ ...
+}
+
+GeneralCauseList-RL-AdditionFailureFDD ::= SEQUENCE {
+ cause Cause,
+ iE-Extensions ProtocolExtensionContainer { { GeneralCauseItem-RL-AdditionFailureFDD-ExtIEs} } OPTIONAL,
+ ...
+}
+
+GeneralCauseItem-RL-AdditionFailureFDD-ExtIEs NBAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+RLSpecificCauseList-RL-AdditionFailureFDD ::= SEQUENCE {
+ unsuccessful-RL-InformationRespList-RL-AdditionFailureFDD Unsuccessful-RL-InformationRespList-RL-AdditionFailureFDD,
+ successful-RL-InformationRespList-RL-AdditionFailureFDD Successful-RL-InformationRespList-RL-AdditionFailureFDD OPTIONAL,
+ iE-Extensions ProtocolExtensionContainer { { RLSpecificCauseItem-RL-AdditionFailureFDD-ExtIEs} } OPTIONAL,
+ ...
+}
+
+RLSpecificCauseItem-RL-AdditionFailureFDD-ExtIEs NBAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+Unsuccessful-RL-InformationRespList-RL-AdditionFailureFDD ::= SEQUENCE (SIZE (1..maxNrOfRLs-1)) OF ProtocolIE-Single-Container {{ Unsuccessful-RL-InformationRespItemIE-RL-AdditionFailureFDD }}
+
+Unsuccessful-RL-InformationRespItemIE-RL-AdditionFailureFDD NBAP-PROTOCOL-IES ::= {
+ { ID id-Unsuccessful-RL-InformationRespItem-RL-AdditionFailureFDD CRITICALITY ignore TYPE Unsuccessful-RL-InformationRespItem-RL-AdditionFailureFDD PRESENCE mandatory}
+}
+
+Unsuccessful-RL-InformationRespItem-RL-AdditionFailureFDD ::= SEQUENCE {
+ rL-ID RL-ID,
+ cause Cause,
+ iE-Extensions ProtocolExtensionContainer { { Unsuccessful-RL-InformationRespItem-RL-AdditionFailureFDD-ExtIEs} } OPTIONAL,
+ ...
+}
+
+Unsuccessful-RL-InformationRespItem-RL-AdditionFailureFDD-ExtIEs NBAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+Successful-RL-InformationRespList-RL-AdditionFailureFDD ::= SEQUENCE (SIZE (1..maxNrOfRLs-2)) OF ProtocolIE-Single-Container {{ Successful-RL-InformationRespItemIE-RL-AdditionFailureFDD }}
+
+Successful-RL-InformationRespItemIE-RL-AdditionFailureFDD NBAP-PROTOCOL-IES ::= {
+ { ID id-Successful-RL-InformationRespItem-RL-AdditionFailureFDD CRITICALITY ignore TYPE Successful-RL-InformationRespItem-RL-AdditionFailureFDD PRESENCE mandatory}
+}
+
+Successful-RL-InformationRespItem-RL-AdditionFailureFDD ::= SEQUENCE {
+ rL-ID RL-ID,
+ rL-Set-ID RL-Set-ID,
+ received-total-wide-band-power Received-total-wide-band-power-Value,
+ diversityIndication DiversityIndication-RL-AdditionFailureFDD,
+ sSDT-SupportIndicator SSDT-SupportIndicator,
+ iE-Extensions ProtocolExtensionContainer { { Successful-RL-InformationRespItem-RL-AdditionFailureFDD-ExtIEs} } OPTIONAL,
+ ...
+}
+
+Successful-RL-InformationRespItem-RL-AdditionFailureFDD-ExtIEs NBAP-PROTOCOL-EXTENSION ::= {
+ { ID id-DL-PowerBalancing-ActivationIndicator CRITICALITY ignore EXTENSION DL-PowerBalancing-ActivationIndicator PRESENCE optional},
+ ...
+}
+
+DiversityIndication-RL-AdditionFailureFDD ::= CHOICE {
+ combining Combining-RL-AdditionFailureFDD,
+ non-Combining Non-Combining-RL-AdditionFailureFDD
+}
+
+Combining-RL-AdditionFailureFDD ::= SEQUENCE {
+ rL-ID RL-ID,
+ iE-Extensions ProtocolExtensionContainer { { CombiningItem-RL-AdditionFailureFDD-ExtIEs} } OPTIONAL,
+ ...
+ }
+
+CombiningItem-RL-AdditionFailureFDD-ExtIEs NBAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+Non-Combining-RL-AdditionFailureFDD ::= SEQUENCE {
+ dCH-InformationResponse DCH-InformationResponse,
+ iE-Extensions ProtocolExtensionContainer { { Non-CombiningItem-RL-AdditionFailureFDD-ExtIEs} } OPTIONAL,
+ ...
+}
+
+Non-CombiningItem-RL-AdditionFailureFDD-ExtIEs NBAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+-- **************************************************************
+--
+-- RADIO LINK ADDITION FAILURE TDD
+--
+-- **************************************************************
+
+RadioLinkAdditionFailureTDD ::= SEQUENCE {
+ protocolIEs ProtocolIE-Container {{RadioLinkAdditionFailureTDD-IEs}},
+ protocolExtensions ProtocolExtensionContainer {{RadioLinkAdditionFailureTDD-Extensions}} OPTIONAL,
+ ...
+}
+
+RadioLinkAdditionFailureTDD-IEs NBAP-PROTOCOL-IES ::= {
+ { ID id-CRNC-CommunicationContextID CRITICALITY ignore TYPE CRNC-CommunicationContextID PRESENCE mandatory }|
+ { ID id-CauseLevel-RL-AdditionFailureTDD CRITICALITY ignore TYPE CauseLevel-RL-AdditionFailureTDD PRESENCE mandatory }|
+ { ID id-CriticalityDiagnostics CRITICALITY ignore TYPE CriticalityDiagnostics PRESENCE optional },
+ ...
+}
+
+RadioLinkAdditionFailureTDD-Extensions NBAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+CauseLevel-RL-AdditionFailureTDD ::= CHOICE {
+ generalCause GeneralCauseList-RL-AdditionFailureTDD,
+ rLSpecificCause RLSpecificCauseList-RL-AdditionFailureTDD,
+ ...
+}
+
+GeneralCauseList-RL-AdditionFailureTDD ::= SEQUENCE {
+ cause Cause,
+ iE-Extensions ProtocolExtensionContainer { { GeneralCauseItem-RL-AdditionFailureTDD-ExtIEs} } OPTIONAL,
+ ...
+}
+
+GeneralCauseItem-RL-AdditionFailureTDD-ExtIEs NBAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+RLSpecificCauseList-RL-AdditionFailureTDD ::= SEQUENCE {
+ unsuccessful-RL-InformationRespItem-RL-AdditionFailureTDD Unsuccessful-RL-InformationRespItem-RL-AdditionFailureTDD,
+ iE-Extensions ProtocolExtensionContainer { { RLSpecificCauseItem-RL-AdditionFailureTDD-ExtIEs} } OPTIONAL,
+ ...
+}
+
+RLSpecificCauseItem-RL-AdditionFailureTDD-ExtIEs NBAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+Unsuccessful-RL-InformationRespItem-RL-AdditionFailureTDD ::= ProtocolIE-Single-Container { {Unsuccessful-RL-InformationRespItemIE-RL-AdditionFailureTDD} }
+
+Unsuccessful-RL-InformationRespItemIE-RL-AdditionFailureTDD NBAP-PROTOCOL-IES ::= {
+ { ID id-Unsuccessful-RL-InformationResp-RL-AdditionFailureTDD CRITICALITY ignore TYPE Unsuccessful-RL-InformationResp-RL-AdditionFailureTDD PRESENCE mandatory }
+}
+
+Unsuccessful-RL-InformationResp-RL-AdditionFailureTDD ::= SEQUENCE {
+ rL-ID RL-ID,
+ cause Cause,
+ iE-Extensions ProtocolExtensionContainer { { Unsuccessful-RL-InformationResp-RL-AdditionFailureTDD-ExtIEs} } OPTIONAL,
+ ...
+}
+
+Unsuccessful-RL-InformationResp-RL-AdditionFailureTDD-ExtIEs NBAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+-- **************************************************************
+--
+-- RADIO LINK RECONFIGURATION PREPARE FDD
+--
+-- **************************************************************
+
+RadioLinkReconfigurationPrepareFDD ::= SEQUENCE {
+ protocolIEs ProtocolIE-Container {{RadioLinkReconfigurationPrepareFDD-IEs}},
+ protocolExtensions ProtocolExtensionContainer {{RadioLinkReconfigurationPrepareFDD-Extensions}} OPTIONAL,
+ ...
+}
+
+RadioLinkReconfigurationPrepareFDD-IEs NBAP-PROTOCOL-IES ::= {
+ { ID id-NodeB-CommunicationContextID CRITICALITY reject TYPE NodeB-CommunicationContextID PRESENCE mandatory }|
+ { ID id-UL-DPCH-Information-RL-ReconfPrepFDD CRITICALITY reject TYPE UL-DPCH-Information-RL-ReconfPrepFDD PRESENCE optional } |
+ { ID id-DL-DPCH-Information-RL-ReconfPrepFDD CRITICALITY reject TYPE DL-DPCH-Information-RL-ReconfPrepFDD PRESENCE optional } |
+ { ID id-FDD-DCHs-to-Modify CRITICALITY reject TYPE FDD-DCHs-to-Modify PRESENCE optional } |
+ { ID id-DCHs-to-Add-FDD CRITICALITY reject TYPE DCH-FDD-Information PRESENCE optional } |
+ { ID id-DCH-DeleteList-RL-ReconfPrepFDD CRITICALITY reject TYPE DCH-DeleteList-RL-ReconfPrepFDD PRESENCE optional } |
+ { ID id-DSCH-ModifyList-RL-ReconfPrepFDD CRITICALITY reject TYPE DSCH-ModifyList-RL-ReconfPrepFDD PRESENCE optional } |
+ { ID id-DSCHs-to-Add-FDD CRITICALITY reject TYPE DSCH-FDD-Information PRESENCE optional } |
+ { ID id-DSCH-DeleteList-RL-ReconfPrepFDD CRITICALITY reject TYPE DSCH-DeleteList-RL-ReconfPrepFDD PRESENCE optional } |
+ { ID id-TFCI2-BearerSpecificInformation-RL-ReconfPrepFDD CRITICALITY reject TYPE TFCI2-BearerSpecificInformation-RL-ReconfPrepFDD
+ PRESENCE optional } |
+ { ID id-RL-InformationList-RL-ReconfPrepFDD CRITICALITY reject TYPE RL-InformationList-RL-ReconfPrepFDD PRESENCE optional }|
+ { ID id-Transmission-Gap-Pattern-Sequence-Information CRITICALITY reject TYPE Transmission-Gap-Pattern-Sequence-Information PRESENCE optional },
+ ...
+}
+
+RadioLinkReconfigurationPrepareFDD-Extensions NBAP-PROTOCOL-EXTENSION ::= {
+ { ID id-DSCH-FDD-Common-Information CRITICALITY ignore EXTENSION DSCH-FDD-Common-Information PRESENCE optional }|
+ { ID id-SignallingBearerRequestIndicator CRITICALITY reject EXTENSION SignallingBearerRequestIndicator PRESENCE optional }|
+ { ID id-HSDSCH-FDD-Information CRITICALITY reject EXTENSION HSDSCH-FDD-Information PRESENCE optional }|
+ { ID id-HSDSCH-Information-to-Modify CRITICALITY reject EXTENSION HSDSCH-Information-to-Modify PRESENCE optional }|
+ { ID id-HSDSCH-MACdFlows-to-Add CRITICALITY reject EXTENSION HSDSCH-MACdFlows-Information PRESENCE optional }|
+ { ID id-HSDSCH-MACdFlows-to-Delete CRITICALITY reject EXTENSION HSDSCH-MACdFlows-to-Delete PRESENCE optional }|
+ { ID id-HSDSCH-RNTI CRITICALITY reject EXTENSION HSDSCH-RNTI PRESENCE conditional }|
+ -- The IE shall be present if HS-PDSCH RL ID IE is present.
+ { ID id-HSPDSCH-RL-ID CRITICALITY reject EXTENSION RL-ID PRESENCE optional },
+ ...
+}
+
+UL-DPCH-Information-RL-ReconfPrepFDD ::= SEQUENCE {
+ ul-ScramblingCode UL-ScramblingCode OPTIONAL,
+ ul-SIR-Target UL-SIR OPTIONAL,
+ minUL-ChannelisationCodeLength MinUL-ChannelisationCodeLength OPTIONAL,
+ maxNrOfUL-DPDCHs MaxNrOfUL-DPDCHs OPTIONAL,
+ -- This IE shall be present if minUL-ChannelisationCodeLength Ie is set to 4
+ ul-PunctureLimit PunctureLimit OPTIONAL,
+ tFCS TFCS OPTIONAL,
+ ul-DPCCH-SlotFormat UL-DPCCH-SlotFormat OPTIONAL,
+ diversityMode DiversityMode OPTIONAL,
+ sSDT-CellIDLength SSDT-CellID-Length OPTIONAL,
+ s-FieldLength S-FieldLength OPTIONAL,
+ iE-Extensions ProtocolExtensionContainer { { UL-DPCH-Information-RL-ReconfPrepFDD-ExtIEs} } OPTIONAL,
+ ...
+}
+
+UL-DPCH-Information-RL-ReconfPrepFDD-ExtIEs NBAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+DL-DPCH-Information-RL-ReconfPrepFDD ::= SEQUENCE {
+ tFCS TFCS OPTIONAL,
+ dl-DPCH-SlotFormat DL-DPCH-SlotFormat OPTIONAL,
+ tFCI-SignallingMode TFCI-SignallingMode OPTIONAL,
+ tFCI-Presence TFCI-Presence OPTIONAL,
+ -- This IE shall be present if the DL DPCH Slot Format IE is set to any of the values from 12 to 16
+ multiplexingPosition MultiplexingPosition OPTIONAL,
+ pDSCH-CodeMapping PDSCH-CodeMapping OPTIONAL,
+ pDSCH-RL-ID RL-ID OPTIONAL,
+ limitedPowerIncrease LimitedPowerIncrease OPTIONAL,
+ iE-Extensions ProtocolExtensionContainer { { DL-DPCH-Information-RL-ReconfPrepFDD-ExtIEs} } OPTIONAL,
+ ...
+}
+
+DL-DPCH-Information-RL-ReconfPrepFDD-ExtIEs NBAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+DCH-DeleteList-RL-ReconfPrepFDD ::= SEQUENCE (SIZE (1..maxNrOfDCHs)) OF DCH-DeleteItem-RL-ReconfPrepFDD
+
+DCH-DeleteItem-RL-ReconfPrepFDD ::= SEQUENCE {
+ dCH-ID DCH-ID,
+ iE-Extensions ProtocolExtensionContainer { { DCH-DeleteItem-RL-ReconfPrepFDD-ExtIEs} } OPTIONAL,
+ ...
+}
+
+DCH-DeleteItem-RL-ReconfPrepFDD-ExtIEs NBAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+DSCH-ModifyList-RL-ReconfPrepFDD ::= SEQUENCE (SIZE (1..maxNrOfDSCHs)) OF ProtocolIE-Single-Container {{DSCH-ModifyItemIE-RL-ReconfPrepFDD }}
+
+DSCH-ModifyItemIE-RL-ReconfPrepFDD NBAP-PROTOCOL-IES ::= {
+ { ID id-DSCH-ModifyItem-RL-ReconfPrepFDD CRITICALITY reject TYPE DSCH-ModifyItem-RL-ReconfPrepFDD PRESENCE mandatory}
+}
+
+DSCH-ModifyItem-RL-ReconfPrepFDD ::= SEQUENCE {
+ dSCH-ID DSCH-ID,
+ dl-TransportFormatSet TransportFormatSet OPTIONAL,
+ allocationRetentionPriority AllocationRetentionPriority OPTIONAL,
+ frameHandlingPriority FrameHandlingPriority OPTIONAL,
+ toAWS ToAWS OPTIONAL,
+ toAWE ToAWE OPTIONAL,
+ transportBearerRequestIndicator TransportBearerRequestIndicator,
+ iE-Extensions ProtocolExtensionContainer { { DSCH-ModifyItem-RL-ReconfPrepFDD-ExtIEs} } OPTIONAL,
+ ...
+}
+
+DSCH-ModifyItem-RL-ReconfPrepFDD-ExtIEs NBAP-PROTOCOL-EXTENSION ::= {
+ { ID id-bindingID CRITICALITY ignore EXTENSION BindingID PRESENCE optional }|
+ { ID id-transportlayeraddress CRITICALITY ignore EXTENSION TransportLayerAddress PRESENCE optional },
+ ...
+}
+
+DSCH-DeleteList-RL-ReconfPrepFDD ::= SEQUENCE (SIZE (1..maxNrOfDSCHs)) OF ProtocolIE-Single-Container {{DSCH-DeleteItemIE-RL-ReconfPrepFDD }}
+
+DSCH-DeleteItemIE-RL-ReconfPrepFDD NBAP-PROTOCOL-IES ::= {
+ { ID id-DSCH-DeleteItem-RL-ReconfPrepFDD CRITICALITY reject TYPE DSCH-DeleteItem-RL-ReconfPrepFDD PRESENCE mandatory}
+}
+
+DSCH-DeleteItem-RL-ReconfPrepFDD ::= SEQUENCE {
+ dSCH-ID DSCH-ID,
+ iE-Extensions ProtocolExtensionContainer { { DSCH-DeleteItem-RL-ReconfPrepFDD-ExtIEs} } OPTIONAL,
+ ...
+}
+
+DSCH-DeleteItem-RL-ReconfPrepFDD-ExtIEs NBAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+TFCI2-BearerSpecificInformation-RL-ReconfPrepFDD ::= CHOICE {
+ addOrModify AddOrModify-TFCI2-RL-ReconfPrepFDD,
+ delete NULL
+}
+
+AddOrModify-TFCI2-RL-ReconfPrepFDD ::= SEQUENCE {
+ toAWS ToAWS,
+ toAWE ToAWE,
+ iE-Extensions ProtocolExtensionContainer { { AddOrModify-TFCI2-RL-ReconfPrepFDD-ExtIEs} } OPTIONAL,
+ ...
+}
+
+AddOrModify-TFCI2-RL-ReconfPrepFDD-ExtIEs NBAP-PROTOCOL-EXTENSION ::= {
+ { ID id-TFCI2BearerRequestIndicator CRITICALITY reject EXTENSION TFCI2BearerRequestIndicator PRESENCE optional }|
+ { ID id-bindingID CRITICALITY ignore EXTENSION BindingID PRESENCE optional }|
+ { ID id-transportlayeraddress CRITICALITY ignore EXTENSION TransportLayerAddress PRESENCE optional },
+ ...
+}
+
+RL-InformationList-RL-ReconfPrepFDD ::= SEQUENCE (SIZE (1..maxNrOfRLs)) OF ProtocolIE-Single-Container {{ RL-InformationItemIE-RL-ReconfPrepFDD }}
+
+RL-InformationItemIE-RL-ReconfPrepFDD NBAP-PROTOCOL-IES ::= {
+ { ID id-RL-InformationItem-RL-ReconfPrepFDD CRITICALITY reject TYPE RL-InformationItem-RL-ReconfPrepFDD PRESENCE mandatory}
+}
+
+RL-InformationItem-RL-ReconfPrepFDD ::= SEQUENCE {
+ rL-ID RL-ID,
+ dl-CodeInformation FDD-DL-CodeInformation OPTIONAL,
+ maxDL-Power DL-Power OPTIONAL,
+ minDL-Power DL-Power OPTIONAL,
+ sSDT-Indication SSDT-Indication OPTIONAL,
+ sSDT-Cell-Identity SSDT-Cell-Identity OPTIONAL,
+ -- The IE shall be present if the SSDT Indication IE is set to "SSDT Active in the UE"
+ transmitDiversityIndicator TransmitDiversityIndicator OPTIONAL,
+ -- This IE shall be present if Diversity Mode IE is present in UL DPCH Information IE and it is not set to "none"
+ iE-Extensions ProtocolExtensionContainer { { RL-InformationItem-RL-ReconfPrepFDD-ExtIEs} } OPTIONAL,
+ ...
+}
+
+RL-InformationItem-RL-ReconfPrepFDD-ExtIEs NBAP-PROTOCOL-EXTENSION ::= {
+ { ID id-SSDT-CellIDforEDSCHPC CRITICALITY ignore EXTENSION SSDT-Cell-Identity PRESENCE conditional }|
+ -- This IE shall be present if Enhanced DSCH PC IE is present in the DSCH Common Information IE.
+ { ID id-DLReferencePower CRITICALITY ignore EXTENSION DL-Power PRESENCE optional }|
+ { ID id-RL-Specific-DCH-Info CRITICALITY ignore EXTENSION RL-Specific-DCH-Info PRESENCE optional }|
+ { ID id-DL-DPCH-TimingAdjustment CRITICALITY reject EXTENSION DL-DPCH-TimingAdjustment PRESENCE optional }|
+ { ID id-Qth-Parameter CRITICALITY ignore EXTENSION Qth-Parameter PRESENCE optional }|
+ { ID id-Primary-CPICH-Usage-for-Channel-Estimation CRITICALITY ignore EXTENSION Primary-CPICH-Usage-for-Channel-Estimation PRESENCE optional }|
+ { ID id-Secondary-CPICH-Information-Change CRITICALITY ignore EXTENSION Secondary-CPICH-Information-Change PRESENCE optional },
+ ...
+}
+
+
+-- **************************************************************
+--
+-- RADIO LINK RECONFIGURATION PREPARE TDD
+--
+-- **************************************************************
+
+RadioLinkReconfigurationPrepareTDD ::= SEQUENCE {
+ protocolIEs ProtocolIE-Container {{RadioLinkReconfigurationPrepareTDD-IEs}},
+ protocolExtensions ProtocolExtensionContainer {{RadioLinkReconfigurationPrepareTDD-Extensions}} OPTIONAL,
+ ...
+}
+
+RadioLinkReconfigurationPrepareTDD-IEs NBAP-PROTOCOL-IES ::= {
+ { ID id-NodeB-CommunicationContextID CRITICALITY reject TYPE NodeB-CommunicationContextID PRESENCE mandatory }|
+ { ID id-UL-CCTrCH-InformationAddList-RL-ReconfPrepTDD CRITICALITY reject TYPE UL-CCTrCH-InformationAddList-RL-ReconfPrepTDD PRESENCE optional }|
+ { ID id-UL-CCTrCH-InformationModifyList-RL-ReconfPrepTDD CRITICALITY reject TYPE UL-CCTrCH-InformationModifyList-RL-ReconfPrepTDD PRESENCE optional }|
+ { ID id-UL-CCTrCH-InformationDeleteList-RL-ReconfPrepTDD CRITICALITY reject TYPE UL-CCTrCH-InformationDeleteList-RL-ReconfPrepTDD PRESENCE optional }|
+ { ID id-DL-CCTrCH-InformationAddList-RL-ReconfPrepTDD CRITICALITY reject TYPE DL-CCTrCH-InformationAddList-RL-ReconfPrepTDD PRESENCE optional }|
+ { ID id-DL-CCTrCH-InformationModifyList-RL-ReconfPrepTDD CRITICALITY reject TYPE DL-CCTrCH-InformationModifyList-RL-ReconfPrepTDD PRESENCE optional }|
+ { ID id-DL-CCTrCH-InformationDeleteList-RL-ReconfPrepTDD CRITICALITY reject TYPE DL-CCTrCH-InformationDeleteList-RL-ReconfPrepTDD PRESENCE optional }|
+ { ID id-TDD-DCHs-to-Modify CRITICALITY reject TYPE TDD-DCHs-to-Modify PRESENCE optional }|
+ { ID id-DCHs-to-Add-TDD CRITICALITY reject TYPE DCH-TDD-Information PRESENCE optional }|
+ { ID id-DCH-DeleteList-RL-ReconfPrepTDD CRITICALITY reject TYPE DCH-DeleteList-RL-ReconfPrepTDD PRESENCE optional }|
+ { ID id-DSCH-Information-ModifyList-RL-ReconfPrepTDD CRITICALITY reject TYPE DSCH-Information-ModifyList-RL-ReconfPrepTDD PRESENCE optional }|
+ { ID id-DSCHs-to-Add-TDD CRITICALITY reject TYPE DSCH-TDD-Information PRESENCE optional }|
+ { ID id-DSCH-Information-DeleteList-RL-ReconfPrepTDD CRITICALITY reject TYPE DSCH-Information-DeleteList-RL-ReconfPrepTDD PRESENCE optional }|
+ { ID id-USCH-Information-ModifyList-RL-ReconfPrepTDD CRITICALITY reject TYPE USCH-Information-ModifyList-RL-ReconfPrepTDD PRESENCE optional }|
+ { ID id-USCH-Information-Add CRITICALITY reject TYPE USCH-Information PRESENCE optional }|
+ { ID id-USCH-Information-DeleteList-RL-ReconfPrepTDD CRITICALITY reject TYPE USCH-Information-DeleteList-RL-ReconfPrepTDD PRESENCE optional }|
+ { ID id-RL-Information-RL-ReconfPrepTDD CRITICALITY reject TYPE RL-Information-RL-ReconfPrepTDD PRESENCE optional },
+-- This RL Information is the for the 1st RL IE repetition
+ ...
+}
+
+RadioLinkReconfigurationPrepareTDD-Extensions NBAP-PROTOCOL-EXTENSION ::= {
+ { ID id-SignallingBearerRequestIndicator CRITICALITY reject EXTENSION SignallingBearerRequestIndicator PRESENCE optional }|
+ { ID id-HSDSCH-TDD-Information CRITICALITY reject EXTENSION HSDSCH-TDD-Information PRESENCE optional }|
+ { ID id-HSDSCH-Information-to-Modify CRITICALITY reject EXTENSION HSDSCH-Information-to-Modify PRESENCE optional }|
+ { ID id-HSDSCH-MACdFlows-to-Add CRITICALITY reject EXTENSION HSDSCH-MACdFlows-Information PRESENCE optional }|
+ { ID id-HSDSCH-MACdFlows-to-Delete CRITICALITY reject EXTENSION HSDSCH-MACdFlows-to-Delete PRESENCE optional }|
+ { ID id-HSDSCH-RNTI CRITICALITY reject EXTENSION HSDSCH-RNTI PRESENCE conditional }|
+ -- The IE shall be present if HS-PDSCH RL ID IE is present.
+ { ID id-HSPDSCH-RL-ID CRITICALITY reject EXTENSION RL-ID PRESENCE optional }|
+ { ID id-PDSCH-RL-ID CRITICALITY ignore EXTENSION RL-ID PRESENCE optional }|
+ { ID id-RL-Information-RL-ReconfPrepTDD CRITICALITY reject EXTENSION MultipleRL-Information-RL-ReconfPrepTDD PRESENCE optional },
+-- This RL Information is the for the 2nd and beyond repetition of RL information,
+ ...
+}
+
+UL-CCTrCH-InformationAddList-RL-ReconfPrepTDD ::= SEQUENCE (SIZE (1..maxNrOfCCTrCHs)) OF UL-CCTrCH-InformationAddItem-RL-ReconfPrepTDD
+
+UL-CCTrCH-InformationAddItem-RL-ReconfPrepTDD ::= SEQUENCE {
+ cCTrCH-ID CCTrCH-ID,
+ tFCS TFCS,
+ tFCI-Coding TFCI-Coding,
+ punctureLimit PunctureLimit,
+ ul-DPCH-InformationList UL-DPCH-InformationAddList-RL-ReconfPrepTDD OPTIONAL,
+-- This DPCH Information is the for the first RL repetition, DPCH information for RL repetitions 2 and on, should be defined in MultipleRL-UL-DPCH-InformationAddList-RL-ReconfPrepTDD
+ iE-Extensions ProtocolExtensionContainer { { UL-CCTrCH-InformationAddItem-RL-ReconfPrepTDD-ExtIEs} } OPTIONAL,
+ ...
+}
+
+UL-CCTrCH-InformationAddItem-RL-ReconfPrepTDD-ExtIEs NBAP-PROTOCOL-EXTENSION ::= {
+ { ID id-UL-DPCH-LCR-InformationAddListIE-RL-ReconfPrepTDD CRITICALITY reject EXTENSION UL-DPCH-LCR-InformationAddList-RL-ReconfPrepTDD PRESENCE optional }| -- Applicable to 1.28Mcps TDD only
+-- This DPCH Information is the for the first RL repetition, DPCH information for RL repetitions 2 and on, should be defined in MultipleRL-UL-DPCH-InformationAddList-RL-ReconfPrepTDD
+ { ID id-UL-SIRTarget CRITICALITY reject EXTENSION UL-SIR PRESENCE optional }|
+ -- Mandatory for 1.28Mcps TDD, Not Applicable to 3.84Mcps TDD.
+-- This Information is the for the first RL repetition, SIR Target information for RL repetitions 2 and on, should be defined in MultipleRL-UL-DPCH-InformationAddList-RL-ReconfPrepTDD
+ { ID id-TDD-TPC-UplinkStepSize-InformationAdd-LCR-RL-ReconfPrepTDD CRITICALITY reject EXTENSION TDD-TPC-UplinkStepSize-LCR PRESENCE optional }|
+-- This Information is the for the first RL repetition, TPCinformation for RL repetitions 2 and on, should be defined in MultipleRL-UL-DPCH-InformationAddList-RL-ReconfPrepTDD
+ -- Mandatory for 1.28Mcps TDD, Not Applicable to 3.84Mcps TDD.
+ { ID id-RL-ID CRITICALITY ignore EXTENSION RL-ID PRESENCE optional}|
+-- This is the RL ID for the first RL repetition
+ { ID id-multipleRL-ul-DPCH-InformationList CRITICALITY reject EXTENSION MultipleRL-UL-DPCH-InformationAddList-RL-ReconfPrepTDD PRESENCE optional },
+-- This Information is the for the 2nd and beyond RL repetition,
+ ...
+}
+
+MultipleRL-UL-DPCH-InformationAddList-RL-ReconfPrepTDD ::= SEQUENCE (SIZE (1..maxNrOfRLs-1)) OF MultipleRL-UL-DPCH-InformationAddListIE-RL-ReconfPrepTDD
+--Includes the 2nd through the max number of radio link repetitions.
+
+MultipleRL-UL-DPCH-InformationAddListIE-RL-ReconfPrepTDD ::= SEQUENCE {
+ ul-DPCH-InformationList UL-DPCH-InformationAddList-RL-ReconfPrepTDD OPTIONAL,
+ ul-DPCH-InformationListLCR UL-DPCH-LCR-InformationAddList-RL-ReconfPrepTDD OPTIONAL,
+ ul-sir-target UL-SIR OPTIONAL,
+ -- Mandatory for 1.28Mcps TDD, Not Applicable to 3.84Mcps TDD.
+ tDD-TPC-UplinkStepSize-LCR TDD-TPC-UplinkStepSize-LCR OPTIONAL,
+ -- Mandatory for 1.28Mcps TDD, Not Applicable to 3.84Mcps TDD.
+ rL-ID RL-ID OPTIONAL,
+ iE-Extensions ProtocolExtensionContainer { { MultipleRL-UL-DPCH-InformationAddListIE-RL-ReconfPrepTDD-ExtIEs} } OPTIONAL,
+...
+}
+
+MultipleRL-UL-DPCH-InformationAddListIE-RL-ReconfPrepTDD-ExtIEs NBAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+UL-DPCH-InformationAddList-RL-ReconfPrepTDD ::= ProtocolIE-Single-Container {{ UL-DPCH-InformationAddListIEs-RL-ReconfPrepTDD }}
+
+UL-DPCH-InformationAddListIEs-RL-ReconfPrepTDD NBAP-PROTOCOL-IES ::= {
+ { ID id-UL-DPCH-InformationAddListIE-RL-ReconfPrepTDD CRITICALITY reject TYPE UL-DPCH-InformationAddItem-RL-ReconfPrepTDD PRESENCE mandatory }
+}
+
+UL-DPCH-InformationAddItem-RL-ReconfPrepTDD ::= SEQUENCE {
+ repetitionPeriod RepetitionPeriod,
+ repetitionLength RepetitionLength,
+ tdd-DPCHOffset TDD-DPCHOffset,
+ uL-Timeslot-Information UL-Timeslot-Information,
+ iE-Extensions ProtocolExtensionContainer { { UL-DPCH-InformationAddItem-RL-ReconfPrepTDD-ExtIEs} } OPTIONAL,
+ ...
+}
+
+UL-DPCH-InformationAddItem-RL-ReconfPrepTDD-ExtIEs NBAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+UL-DPCH-LCR-InformationAddList-RL-ReconfPrepTDD ::= SEQUENCE {
+ repetitionPeriod RepetitionPeriod,
+ repetitionLength RepetitionLength,
+ tdd-DPCHOffset TDD-DPCHOffset,
+ uL-Timeslot-InformationLCR UL-TimeslotLCR-Information,
+ iE-Extensions ProtocolExtensionContainer { { UL-DPCH-LCR-InformationAddItem-RL-ReconfPrepTDD-ExtIEs} } OPTIONAL,
+ ...
+}
+
+UL-DPCH-LCR-InformationAddItem-RL-ReconfPrepTDD-ExtIEs NBAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+UL-CCTrCH-InformationModifyList-RL-ReconfPrepTDD ::= SEQUENCE (SIZE (1..maxNrOfCCTrCHs)) OF UL-CCTrCH-InformationModifyItem-RL-ReconfPrepTDD
+
+UL-CCTrCH-InformationModifyItem-RL-ReconfPrepTDD ::= SEQUENCE {
+ cCTrCH-ID CCTrCH-ID,
+ tFCS TFCS OPTIONAL,
+ tFCI-Coding TFCI-Coding OPTIONAL,
+ punctureLimit PunctureLimit OPTIONAL,
+ ul-DPCH-InformationAddList UL-DPCH-InformationModify-AddList-RL-ReconfPrepTDD OPTIONAL,
+-- This DPCH Information is the for the first RL repetition, DPCH information for RL repetitions 2 and on, should be defined in MultipleRL-UL-DPCH-InformationModifyList-RL-ReconfPrepTDD
+ ul-DPCH-InformationModifyList UL-DPCH-InformationModify-ModifyList-RL-ReconfPrepTDD OPTIONAL,
+-- This DPCH Information is the for the first RL repetition, DPCH information for RL repetitions 2 and on, should be defined in MultipleRL-UL-DPCH-InformationModifyList-RL-ReconfPrepTDD
+ ul-DPCH-InformationDeleteList UL-DPCH-InformationModify-DeleteList-RL-ReconfPrepTDD OPTIONAL,
+-- This DPCH Information is the for the first RL repetition, DPCH information for RL repetitions 2 and on, should be defined in MultipleRL-UL-DPCH-InformationModifyList-RL-ReconfPrepTDD
+ iE-Extensions ProtocolExtensionContainer { { UL-CCTrCH-InformationModifyItem-RL-ReconfPrepTDD-ExtIEs} } OPTIONAL,
+ ...
+}
+
+UL-CCTrCH-InformationModifyItem-RL-ReconfPrepTDD-ExtIEs NBAP-PROTOCOL-EXTENSION ::= {
+ { ID id-UL-DPCH-LCR-InformationModify-AddList CRITICALITY reject EXTENSION UL-DPCH-LCR-InformationModify-AddList-RL-ReconfPrepTDD PRESENCE optional }| -- Applicable to 1.28Mcps TDD only
+-- This DPCH Information is the for the first RL repetition, DPCH information for RL repetitions 2 and on, should be defined in MultipleRL-UL-DPCH-InformationModifyList-RL-ReconfPrepTDD
+ { ID id-UL-SIRTarget CRITICALITY reject EXTENSION UL-SIR PRESENCE optional }|
+ -- Applicable to 1.28Mcps TDD only.
+-- This Information is the for the first RL repetition, SIR Target information for RL repetitions 2 and on, should be defined in MultipleRL-UL-DPCH-InformationModifyList-RL-ReconfPrepTDD
+ { ID id-TDD-TPC-UplinkStepSize-InformationModify-LCR-RL-ReconfPrepTDD CRITICALITY reject EXTENSION TDD-TPC-UplinkStepSize-LCR PRESENCE optional }|
+ -- Applicable to 1.28Mcps TDD only
+-- This Information is the for the first RL repetition, Step Size information for RL repetitions 2 and on, should be defined in MultipleRL-UL-DPCH-InformationModifyList-RL-ReconfPrepTDD
+ { ID id-RL-ID CRITICALITY ignore EXTENSION RL-ID PRESENCE optional }|
+-- This is the RL ID for the first RL repetition
+ { ID id-multipleRL-ul-DPCH-InformationModifyList CRITICALITY reject EXTENSION MultipleRL-UL-DPCH-InformationModifyList-RL-ReconfPrepTDD PRESENCE optional },
+-- This DPCH Information is the for the 2nd and beyond RL repetition,
+ ...
+}
+
+UL-DPCH-InformationModify-AddList-RL-ReconfPrepTDD ::= ProtocolIE-Single-Container {{ UL-DPCH-InformationModify-AddListIEs-RL-ReconfPrepTDD }}
+
+UL-DPCH-InformationModify-AddListIEs-RL-ReconfPrepTDD NBAP-PROTOCOL-IES ::= {
+ { ID id-UL-DPCH-InformationModify-AddListIE-RL-ReconfPrepTDD CRITICALITY reject TYPE UL-DPCH-InformationModify-AddItem-RL-ReconfPrepTDD PRESENCE mandatory }
+}
+
+MultipleRL-UL-DPCH-InformationModifyList-RL-ReconfPrepTDD ::= SEQUENCE (SIZE (1..maxNrOfRLs-1)) OF MultipleRL-UL-DPCH-InformationModifyListIE-RL-ReconfPrepTDD
+--Includes the 2nd through the max number of radio link information repetitions.
+
+MultipleRL-UL-DPCH-InformationModifyListIE-RL-ReconfPrepTDD ::= SEQUENCE {
+ ul-DPCH-InformationAddList UL-DPCH-InformationModify-AddList-RL-ReconfPrepTDD OPTIONAL,
+ ul-DPCH-InformationModifyList UL-DPCH-InformationModify-ModifyList-RL-ReconfPrepTDD OPTIONAL,
+ ul-DPCH-InformationDeleteList UL-DPCH-InformationModify-DeleteList-RL-ReconfPrepTDD OPTIONAL,
+ ul-DPCH-InformationAddListLCR UL-DPCH-LCR-InformationModify-AddList-RL-ReconfPrepTDD OPTIONAL,
+ ul-sir-target UL-SIR OPTIONAL,
+ tDD-TPC-UplinkStepSize-LCR TDD-TPC-UplinkStepSize-LCR OPTIONAL,
+ rL-ID RL-ID OPTIONAL,
+-- This DPCH Information is the for the 2nd and beyond RL repetitions,
+ iE-Extensions ProtocolExtensionContainer { { MultipleRL-UL-DPCH-InformationModifyListIE-RL-ReconfPrepTDD-ExtIEs} } OPTIONAL,
+...
+}
+
+
+MultipleRL-UL-DPCH-InformationModifyListIE-RL-ReconfPrepTDD-ExtIEs NBAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+UL-DPCH-InformationModify-AddItem-RL-ReconfPrepTDD ::= SEQUENCE {
+ repetitionPeriod RepetitionPeriod,
+ repetitionLength RepetitionLength,
+ tdd-DPCHOffset TDD-DPCHOffset,
+ uL-Timeslot-Information UL-Timeslot-Information,
+ iE-Extensions ProtocolExtensionContainer { { UL-DPCH-InformationModify-AddItem-RL-ReconfPrepTDD-ExtIEs} } OPTIONAL,
+ ...
+}
+
+UL-DPCH-InformationModify-AddItem-RL-ReconfPrepTDD-ExtIEs NBAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+UL-DPCH-LCR-InformationModify-AddList-RL-ReconfPrepTDD ::= SEQUENCE {
+ repetitionPeriod RepetitionPeriod,
+ repetitionLength RepetitionLength,
+ tdd-DPCHOffset TDD-DPCHOffset,
+ uL-Timeslot-InformationLCR UL-TimeslotLCR-Information,
+ iE-Extensions ProtocolExtensionContainer { { UL-DPCH-LCR-InformationModify-AddItem-RL-ReconfPrepTDD-ExtIEs} } OPTIONAL,
+ ...
+}
+
+UL-DPCH-LCR-InformationModify-AddItem-RL-ReconfPrepTDD-ExtIEs NBAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+UL-DPCH-InformationModify-ModifyList-RL-ReconfPrepTDD ::= ProtocolIE-Single-Container {{ UL-DPCH-InformationModify-ModifyListIEs-RL-ReconfPrepTDD }}
+
+UL-DPCH-InformationModify-ModifyListIEs-RL-ReconfPrepTDD NBAP-PROTOCOL-IES ::= {
+ { ID id-UL-DPCH-InformationModify-ModifyListIE-RL-ReconfPrepTDD CRITICALITY reject TYPE UL-DPCH-InformationModify-ModifyItem-RL-ReconfPrepTDD PRESENCE mandatory }
+}
+
+UL-DPCH-InformationModify-ModifyItem-RL-ReconfPrepTDD ::= SEQUENCE {
+ repetitionPeriod RepetitionPeriod OPTIONAL,
+ repetitionLength RepetitionLength OPTIONAL,
+ tdd-DPCHOffset TDD-DPCHOffset OPTIONAL,
+ uL-Timeslot-InformationModify-ModifyList-RL-ReconfPrepTDD UL-Timeslot-InformationModify-ModifyList-RL-ReconfPrepTDD OPTIONAL,
+ iE-Extensions ProtocolExtensionContainer { { UL-DPCH-InformationModify-ModifyItem-RL-ReconfPrepTDD-ExtIEs} } OPTIONAL,
+ ...
+}
+
+UL-DPCH-InformationModify-ModifyItem-RL-ReconfPrepTDD-ExtIEs NBAP-PROTOCOL-EXTENSION ::= {
+ { ID id-UL-TimeslotLCR-Information-RL-ReconfPrepTDD CRITICALITY reject EXTENSION UL-TimeslotLCR-InformationModify-ModifyList-RL-ReconfPrepTDD PRESENCE optional }, -- Applicable to 1.28Mcps TDD only
+ ...
+}
+
+UL-Timeslot-InformationModify-ModifyList-RL-ReconfPrepTDD ::= SEQUENCE (SIZE (1..maxNrOfULTSs)) OF UL-Timeslot-InformationModify-ModifyItem-RL-ReconfPrepTDD -- Applicable to 3.84Mcps TDD only
+
+UL-Timeslot-InformationModify-ModifyItem-RL-ReconfPrepTDD ::= SEQUENCE {
+ timeSlot TimeSlot,
+ midambleShiftAndBurstType MidambleShiftAndBurstType OPTIONAL,
+ tFCI-Presence TFCI-Presence OPTIONAL,
+ uL-Code-InformationModify-ModifyList-RL-ReconfPrepTDD UL-Code-InformationModify-ModifyList-RL-ReconfPrepTDD OPTIONAL,
+ iE-Extensions ProtocolExtensionContainer { { UL-Timeslot-InformationModify-ModifyItem-RL-ReconfPrepTDD-ExtIEs} } OPTIONAL,
+ ...
+}
+
+UL-Timeslot-InformationModify-ModifyItem-RL-ReconfPrepTDD-ExtIEs NBAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+UL-Code-InformationModify-ModifyList-RL-ReconfPrepTDD ::= SEQUENCE (SIZE (1..maxNrOfDPCHs)) OF UL-Code-InformationModify-ModifyItem-RL-ReconfPrepTDD
+
+UL-Code-InformationModify-ModifyItem-RL-ReconfPrepTDD ::= SEQUENCE {
+ dPCH-ID DPCH-ID,
+ tdd-ChannelisationCode TDD-ChannelisationCode OPTIONAL,
+ iE-Extensions ProtocolExtensionContainer { { UL-Code-InformationModify-ModifyItem-RL-ReconfPrepTDD-ExtIEs} } OPTIONAL,
+ ...
+}
+
+UL-Code-InformationModify-ModifyItem-RL-ReconfPrepTDD-ExtIEs NBAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+UL-TimeslotLCR-InformationModify-ModifyList-RL-ReconfPrepTDD ::= SEQUENCE (SIZE (1..maxNrOfULTSLCRs)) OF UL-Timeslot-LCR-InformationModify-ModifyItem-RL-ReconfPrepTDD -- Applicable to 1.28Mcps TDD only
+
+UL-Timeslot-LCR-InformationModify-ModifyItem-RL-ReconfPrepTDD ::= SEQUENCE {
+ timeSlotLCR TimeSlotLCR,
+ midambleShiftLCR MidambleShiftLCR OPTIONAL,
+ tFCI-Presence TFCI-Presence OPTIONAL,
+ uL-Code-InformationModify-ModifyList-RL-ReconfPrepTDDLCR UL-Code-InformationModify-ModifyList-RL-ReconfPrepTDDLCR OPTIONAL,
+ iE-Extensions ProtocolExtensionContainer { { UL-Timeslot-LCR-InformationModify-ModifyItem-RL-ReconfPrepTDD-ExtIEs} } OPTIONAL,
+ ...
+}
+
+UL-Timeslot-LCR-InformationModify-ModifyItem-RL-ReconfPrepTDD-ExtIEs NBAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+UL-Code-InformationModify-ModifyList-RL-ReconfPrepTDDLCR ::= SEQUENCE (SIZE (1..maxNrOfDPCHLCRs)) OF UL-Code-InformationModify-ModifyItem-RL-ReconfPrepTDDLCR
+
+UL-Code-InformationModify-ModifyItem-RL-ReconfPrepTDDLCR ::= SEQUENCE {
+ dPCH-ID DPCH-ID,
+ tdd-ChannelisationCodeLCR TDD-ChannelisationCodeLCR OPTIONAL,
+ iE-Extensions ProtocolExtensionContainer { { UL-Code-InformationModify-ModifyItem-RL-ReconfPrepTDDLCR-ExtIEs} } OPTIONAL,
+ ...
+}
+
+UL-Code-InformationModify-ModifyItem-RL-ReconfPrepTDDLCR-ExtIEs NBAP-PROTOCOL-EXTENSION ::= {
+{ ID id-UL-DPCH-TimeSlotFormat-LCR-ModifyItem-RL-ReconfPrepTDD CRITICALITY reject EXTENSION TDD-UL-DPCH-TimeSlotFormat-LCR PRESENCE optional},
+
+ ...
+}
+
+UL-DPCH-InformationModify-DeleteList-RL-ReconfPrepTDD ::= ProtocolIE-Single-Container {{ UL-DPCH-InformationModify-DeleteListIEs-RL-ReconfPrepTDD }}
+
+UL-DPCH-InformationModify-DeleteListIEs-RL-ReconfPrepTDD NBAP-PROTOCOL-IES ::= {
+ { ID id-UL-DPCH-InformationModify-DeleteListIE-RL-ReconfPrepTDD CRITICALITY reject TYPE UL-DPCH-InformationModify-DeleteListIE-RL-ReconfPrepTDD PRESENCE mandatory }
+}
+
+UL-DPCH-InformationModify-DeleteListIE-RL-ReconfPrepTDD ::= SEQUENCE (SIZE (1..maxNrOfDPCHs)) OF UL-DPCH-InformationModify-DeleteItem-RL-ReconfPrepTDD
+
+UL-DPCH-InformationModify-DeleteItem-RL-ReconfPrepTDD ::= SEQUENCE {
+ dPCH-ID DPCH-ID,
+ iE-Extensions ProtocolExtensionContainer { { UL-DPCH-InformationModify-DeleteItem-RL-ReconfPrepTDD-ExtIEs} } OPTIONAL,
+ ...
+}
+
+UL-DPCH-InformationModify-DeleteItem-RL-ReconfPrepTDD-ExtIEs NBAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+UL-CCTrCH-InformationDeleteList-RL-ReconfPrepTDD ::= SEQUENCE (SIZE (1..maxNrOfCCTrCHs)) OF UL-CCTrCH-InformationDeleteItem-RL-ReconfPrepTDD
+
+UL-CCTrCH-InformationDeleteItem-RL-ReconfPrepTDD ::= SEQUENCE {
+ cCTrCH-ID CCTrCH-ID,
+ iE-Extensions ProtocolExtensionContainer { { UL-CCTrCH-InformationDeleteItem-RL-ReconfPrepTDD-ExtIEs} } OPTIONAL,
+ ...
+}
+
+UL-CCTrCH-InformationDeleteItem-RL-ReconfPrepTDD-ExtIEs NBAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+DL-CCTrCH-InformationAddList-RL-ReconfPrepTDD ::= SEQUENCE (SIZE (1..maxNrOfCCTrCHs)) OF DL-CCTrCH-InformationAddItem-RL-ReconfPrepTDD
+
+DL-CCTrCH-InformationAddItem-RL-ReconfPrepTDD ::= SEQUENCE {
+ cCTrCH-ID CCTrCH-ID,
+ tFCS TFCS,
+ tFCI-Coding TFCI-Coding,
+ punctureLimit PunctureLimit,
+ cCTrCH-TPCList CCTrCH-TPCAddList-RL-ReconfPrepTDD OPTIONAL,
+ dl-DPCH-InformationList DL-DPCH-InformationAddList-RL-ReconfPrepTDD OPTIONAL,
+-- This DPCH Information is the for the first RL repetition, DPCH information for RL repetitions 2 and on, should be defined in MultipleRL-DL-DPCH-InformationAddList-RL-ReconfPrepTDD
+ iE-Extensions ProtocolExtensionContainer { { DL-CCTrCH-InformationAddItem-RL-ReconfPrepTDD-ExtIEs} } OPTIONAL,
+ ...
+}
+
+DL-CCTrCH-InformationAddItem-RL-ReconfPrepTDD-ExtIEs NBAP-PROTOCOL-EXTENSION ::= {
+ { ID id-DL-DPCH-LCR-InformationAddList-RL-ReconfPrepTDD CRITICALITY reject EXTENSION DL-DPCH-LCR-InformationAddList-RL-ReconfPrepTDD PRESENCE optional }| -- Applicable to 1.28Mcps TDD only
+-- This DPCH Information is the for the first RL repetition, DPCH information for RL repetitions 2 and on, should be defined in MultipleRL-DL-DPCH-InformationAddList-RL-ReconfPrepTDD
+ { ID id-CCTrCH-Initial-DL-Power-RL-ReconfPrepTDD CRITICALITY ignore EXTENSION DL-Power PRESENCE optional }|
+-- This DL Power inforrmation is the for the first RL repetition, DL power information for RL repetitions 2 and on, should be defined in MultipleRL-DL-DPCH-InformationAddList-RL-ReconfPrepTDD
+ { ID id-TDD-TPC-DownlinkStepSize-InformationAdd-RL-ReconfPrepTDD CRITICALITY reject EXTENSION TDD-TPC-DownlinkStepSize PRESENCE optional}|
+-- This DL step size is the for the first RL repetition, DL step size information for RL repetitions 2 and on, should be defined in MultipleRL-DL-DPCH-InformationAddList-RL-ReconfPrepTDD
+ { ID id-CCTrCH-Maximum-DL-Power-InformationAdd-RL-ReconfPrepTDD CRITICALITY ignore EXTENSION DL-Power PRESENCE optional }|
+-- This DL Power inforrmation is the for the first RL repetition, DL power information for RL repetitions 2 and on, should be defined in MultipleRL-DL-DPCH-InformationAddList-RL-ReconfPrepTDD
+ { ID id-CCTrCH-Minimum-DL-Power-InformationAdd-RL-ReconfPrepTDD CRITICALITY ignore EXTENSION DL-Power PRESENCE optional }|
+-- This DL Power inforrmation is the for the first RL repetition, DL power information for RL repetitions 2 and on, should be defined in MultipleRL-DL-DPCH-InformationAddList-RL-ReconfPrepTDD
+ { ID id-RL-ID CRITICALITY ignore EXTENSION RL-ID PRESENCE optional }|
+-- This is the RL ID for the first RL repetition
+ { ID id-multipleRL-ul-DPCH-InformationList CRITICALITY reject EXTENSION MultipleRL-DL-DPCH-InformationAddList-RL-ReconfPrepTDD PRESENCE optional },
+-- This DPCH Information is the for the 2nd and beyond RL repetition,
+ ...
+}
+
+MultipleRL-DL-DPCH-InformationAddList-RL-ReconfPrepTDD ::= SEQUENCE (SIZE (1..maxNrOfRLs-1)) OF MultipleRL-DL-DPCH-InformationAddListIE-RL-ReconfPrepTDD
+--Includes the 2nd through the max number of radio link information repetitions.
+
+MultipleRL-DL-DPCH-InformationAddListIE-RL-ReconfPrepTDD ::= SEQUENCE {
+ dl-DPCH-InformationList DL-DPCH-InformationAddList-RL-ReconfPrepTDD OPTIONAL,
+ dl-DPCH-InformationListLCR DL-DPCH-LCR-InformationAddList-RL-ReconfPrepTDD OPTIONAL,
+ cCTrCH-Initial-DL-Power DL-Power OPTIONAL,
+ tDD-TPC-DownlinkStepSize TDD-TPC-DownlinkStepSize OPTIONAL,
+ cCTrCH-Maximum-DL-Power-InformationAdd-RL-ReconfPrepTDD DL-Power OPTIONAL,
+ cCTrCH-Minimum-DL-Power-InformationAdd-RL-ReconfPrepTDD DL-Power OPTIONAL,
+ rL-ID RL-ID OPTIONAL,
+ iE-Extensions ProtocolExtensionContainer { { MultipleRL-DL-DPCH-InformationAddListIE-RL-ReconfPrepTDD-ExtIEs} } OPTIONAL,
+ ...
+}
+
+MultipleRL-DL-DPCH-InformationAddListIE-RL-ReconfPrepTDD-ExtIEs NBAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+CCTrCH-TPCAddList-RL-ReconfPrepTDD ::= SEQUENCE (SIZE (1..maxNrOfCCTrCHs)) OF CCTrCH-TPCAddItem-RL-ReconfPrepTDD -- Applicable to 3.84Mcps TDD only
+
+CCTrCH-TPCAddItem-RL-ReconfPrepTDD ::= SEQUENCE {
+ cCTrCH-ID CCTrCH-ID,
+ iE-Extensions ProtocolExtensionContainer { { CCTrCH-TPCAddItem-RL-ReconfPrepTDD-ExtIEs} } OPTIONAL,
+ ...
+}
+
+CCTrCH-TPCAddItem-RL-ReconfPrepTDD-ExtIEs NBAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+DL-DPCH-InformationAddList-RL-ReconfPrepTDD ::= ProtocolIE-Single-Container {{ DL-DPCH-InformationAddListIEs-RL-ReconfPrepTDD }}
+
+DL-DPCH-InformationAddListIEs-RL-ReconfPrepTDD NBAP-PROTOCOL-IES ::= {
+ { ID id-DL-DPCH-InformationAddListIE-RL-ReconfPrepTDD CRITICALITY reject TYPE DL-DPCH-InformationAddItem-RL-ReconfPrepTDD PRESENCE mandatory }
+}
+
+DL-DPCH-InformationAddItem-RL-ReconfPrepTDD ::= SEQUENCE {
+ repetitionPeriod RepetitionPeriod,
+ repetitionLength RepetitionLength,
+ tdd-DPCHOffset TDD-DPCHOffset,
+ dL-Timeslot-Information DL-Timeslot-Information,
+ iE-Extensions ProtocolExtensionContainer { { DL-DPCH-InformationAddItem-RL-ReconfPrepTDD-ExtIEs} } OPTIONAL,
+ ...
+}
+
+DL-DPCH-InformationAddItem-RL-ReconfPrepTDD-ExtIEs NBAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+DL-DPCH-LCR-InformationAddList-RL-ReconfPrepTDD ::= SEQUENCE {
+ repetitionPeriod RepetitionPeriod,
+ repetitionLength RepetitionLength,
+ tdd-DPCHOffset TDD-DPCHOffset,
+ dL-Timeslot-InformationLCR DL-TimeslotLCR-Information,
+ iE-Extensions ProtocolExtensionContainer { { DL-DPCH-LCR-InformationAddItem-RL-ReconfPrepTDD-ExtIEs} } OPTIONAL,
+ ...
+}
+
+DL-DPCH-LCR-InformationAddItem-RL-ReconfPrepTDD-ExtIEs NBAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+DL-CCTrCH-InformationModifyList-RL-ReconfPrepTDD ::= SEQUENCE (SIZE (1..maxNrOfCCTrCHs)) OF DL-CCTrCH-InformationModifyItem-RL-ReconfPrepTDD
+
+DL-CCTrCH-InformationModifyItem-RL-ReconfPrepTDD ::= SEQUENCE {
+ cCTrCH-ID CCTrCH-ID,
+ tFCS TFCS OPTIONAL,
+ tFCI-Coding TFCI-Coding OPTIONAL,
+ punctureLimit PunctureLimit OPTIONAL,
+ cCTrCH-TPCList CCTrCH-TPCModifyList-RL-ReconfPrepTDD OPTIONAL,
+ dl-DPCH-InformationAddList DL-DPCH-InformationModify-AddList-RL-ReconfPrepTDD OPTIONAL,
+-- This DPCH Information is the for the first RL repetition, DPCH information for RL repetitions 2 and on, should be defined in MultipleRL-DL-DPCH-InformationModifyList-RL-ReconfPrepTDD
+ dl-DPCH-InformationModifyList DL-DPCH-InformationModify-ModifyList-RL-ReconfPrepTDD OPTIONAL,
+-- This DPCH Information is the for the first RL repetition, DPCH information for RL repetitions 2 and on, should be defined in MultipleRL-DL-DPCH-InformationModifyList-RL-ReconfPrepTDD
+ dl-DPCH-InformationDeleteList DL-DPCH-InformationModify-DeleteList-RL-ReconfPrepTDD OPTIONAL,
+-- This DPCH Information is the for the first RL repetition, DPCH information for RL repetitions 2 and on, should be defined in MultipleRL-DL-DPCH-InformationModifyList-RL-ReconfPrepTDD
+ iE-Extensions ProtocolExtensionContainer { { DL-CCTrCH-InformationModifyItem-RL-ReconfPrepTDD-ExtIEs} } OPTIONAL,
+ ...
+}
+
+DL-CCTrCH-InformationModifyItem-RL-ReconfPrepTDD-ExtIEs NBAP-PROTOCOL-EXTENSION ::= {
+ { ID id-DL-DPCH-LCR-InformationModify-AddList-RL-ReconfPrepTDD CRITICALITY reject EXTENSION DL-DPCH-LCR-InformationModify-AddList-RL-ReconfPrepTDD PRESENCE optional }| -- Applicable to 1.28Mcps TDD only
+-- This DPCH Information is the for the first RL repetition, DPCH information for RL repetitions 2 and on, should be defined in MultipleRL-DL-DPCH-InformationModifyList-RL-ReconfPrepTDD
+ { ID id-TDD-TPC-DownlinkStepSize-InformationModify-RL-ReconfPrepTDD CRITICALITY reject EXTENSION TDD-TPC-DownlinkStepSize PRESENCE optional}|
+-- This Step Size Information is the for the first RL repetition, step size information for RL repetitions 2 and on, should be defined in MultipleRL-DL-DPCH-InformationModifyList-RL-ReconfPrepTDD
+ { ID id-CCTrCH-Maximum-DL-Power-InformationModify-RL-ReconfPrepTDD CRITICALITY ignore EXTENSION DL-Power PRESENCE optional }|
+-- This power Information is the for the first RL repetition, power information for RL repetitions 2 and on, should be defined in MultipleRL-DL-DPCH-InformationModifyList-RL-ReconfPrepTDD
+ { ID id-CCTrCH-Minimum-DL-Power-InformationModify-RL-ReconfPrepTDD CRITICALITY ignore EXTENSION DL-Power PRESENCE optional }|
+-- This power Information is the for the first RL repetition, power information for RL repetitions 2 and on, should be defined in MultipleRL-DL-DPCH-InformationModifyList-RL-ReconfPrepTDD
+ { ID id-RL-ID CRITICALITY ignore EXTENSION RL-ID PRESENCE optional }|
+-- This is the RL ID for the first RL repetition
+ { ID id-multipleRL-dl-DPCH-InformationModifyList CRITICALITY reject EXTENSION MultipleRL-DL-DPCH-InformationModifyList-RL-ReconfPrepTDD PRESENCE optional },
+-- This DPCH Information is the for the 2nd and beyond RL repetitions,
+ ...
+}
+
+MultipleRL-DL-DPCH-InformationModifyList-RL-ReconfPrepTDD ::= SEQUENCE (SIZE (1..maxNrOfRLs-1)) OF MultipleRL-DL-DPCH-InformationModifyListIE-RL-ReconfPrepTDD
+--Includes the 2nd through the max number of radio link information repetitions.
+
+MultipleRL-DL-DPCH-InformationModifyListIE-RL-ReconfPrepTDD ::= SEQUENCE {
+ dl-DPCH-InformationAddList DL-DPCH-InformationModify-AddList-RL-ReconfPrepTDD OPTIONAL,
+ dl-DPCH-InformationModifyList DL-DPCH-InformationModify-ModifyList-RL-ReconfPrepTDD OPTIONAL,
+ dl-DPCH-InformationDeleteList DL-DPCH-InformationModify-DeleteList-RL-ReconfPrepTDD OPTIONAL,
+ dl-DPCH-InformationAddListLCR DL-DPCH-LCR-InformationModify-AddList-RL-ReconfPrepTDD OPTIONAL,
+ tDD-TPC-DownlinkStepSize-InformationModify-RL-ReconfPrepTDD TDD-TPC-DownlinkStepSize OPTIONAL,
+ cCTrCH-Maximum-DL-Power-InformationModify-RL-ReconfPrepTDD DL-Power OPTIONAL,
+ cCTrCH-Minimum-DL-Power-InformationModify-RL-ReconfPrepTDD DL-Power OPTIONAL,
+ rL-ID RL-ID OPTIONAL,
+ iE-Extensions ProtocolExtensionContainer { { MultipleRL-DL-DPCH-InformationModifyListIE-RL-ReconfPrepTDD-ExtIEs} } OPTIONAL,
+...
+}
+
+MultipleRL-DL-DPCH-InformationModifyListIE-RL-ReconfPrepTDD-ExtIEs NBAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+CCTrCH-TPCModifyList-RL-ReconfPrepTDD ::= SEQUENCE (SIZE (1..maxNrOfCCTrCHs)) OF CCTrCH-TPCModifyItem-RL-ReconfPrepTDD
+
+CCTrCH-TPCModifyItem-RL-ReconfPrepTDD ::= SEQUENCE {
+ cCTrCH-ID CCTrCH-ID,
+ iE-Extensions ProtocolExtensionContainer { { CCTrCH-TPCModifyItem-RL-ReconfPrepTDD-ExtIEs} } OPTIONAL,
+ ...
+}
+
+CCTrCH-TPCModifyItem-RL-ReconfPrepTDD-ExtIEs NBAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+DL-DPCH-InformationModify-AddList-RL-ReconfPrepTDD ::= ProtocolIE-Single-Container {{ DL-DPCH-InformationModify-AddListIEs-RL-ReconfPrepTDD }}
+-- Applicable to 3.84Mcps TDD only
+
+DL-DPCH-InformationModify-AddListIEs-RL-ReconfPrepTDD NBAP-PROTOCOL-IES ::= {
+ { ID id-DL-DPCH-InformationModify-AddListIE-RL-ReconfPrepTDD CRITICALITY reject TYPE DL-DPCH-InformationModify-AddItem-RL-ReconfPrepTDD PRESENCE mandatory }
+}
+
+DL-DPCH-InformationModify-AddItem-RL-ReconfPrepTDD ::= SEQUENCE {
+ repetitionPeriod RepetitionPeriod,
+ repetitionLength RepetitionLength,
+ tdd-DPCHOffset TDD-DPCHOffset,
+ dL-Timeslot-Information DL-Timeslot-Information,
+ iE-Extensions ProtocolExtensionContainer { { DL-DPCH-InformationModify-AddItem-RL-ReconfPrepTDD-ExtIEs} } OPTIONAL,
+ ...
+}
+
+DL-DPCH-InformationModify-AddItem-RL-ReconfPrepTDD-ExtIEs NBAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+DL-DPCH-LCR-InformationModify-AddList-RL-ReconfPrepTDD ::= SEQUENCE {
+ repetitionPeriod RepetitionPeriod,
+ repetitionLength RepetitionLength,
+ tdd-DPCHOffset TDD-DPCHOffset,
+ dL-Timeslot-InformationLCR DL-TimeslotLCR-Information,
+ iE-Extensions ProtocolExtensionContainer { { DL-DPCH-LCR-InformationModify-AddItem-RL-ReconfPrepTDD-ExtIEs} } OPTIONAL,
+ ...
+}
+
+DL-DPCH-LCR-InformationModify-AddItem-RL-ReconfPrepTDD-ExtIEs NBAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+DL-DPCH-InformationModify-ModifyList-RL-ReconfPrepTDD ::= ProtocolIE-Single-Container {{ DL-DPCH-InformationModify-ModifyListIEs-RL-ReconfPrepTDD }}
+
+DL-DPCH-InformationModify-ModifyListIEs-RL-ReconfPrepTDD NBAP-PROTOCOL-IES ::= {
+ { ID id-DL-DPCH-InformationModify-ModifyListIE-RL-ReconfPrepTDD CRITICALITY reject TYPE DL-DPCH-InformationModify-ModifyItem-RL-ReconfPrepTDD PRESENCE mandatory }
+}
+
+DL-DPCH-InformationModify-ModifyItem-RL-ReconfPrepTDD ::= SEQUENCE {
+ repetitionPeriod RepetitionPeriod OPTIONAL,
+ repetitionLength RepetitionLength OPTIONAL,
+ tdd-DPCHOffset TDD-DPCHOffset OPTIONAL,
+ dL-Timeslot-InformationAddModify-ModifyList-RL-ReconfPrepTDD DL-Timeslot-InformationModify-ModifyList-RL-ReconfPrepTDD OPTIONAL,
+ iE-Extensions ProtocolExtensionContainer { { DL-DPCH-InformationModify-ModifyItem-RL-ReconfPrepTDD-ExtIEs} } OPTIONAL,
+ ...
+}
+
+DL-DPCH-InformationModify-ModifyItem-RL-ReconfPrepTDD-ExtIEs NBAP-PROTOCOL-EXTENSION ::= {
+ { ID id-DL-Timeslot-LCR-InformationModify-ModifyList-RL-ReconfPrepTDD CRITICALITY reject EXTENSION DL-Timeslot-LCR-InformationModify-ModifyList-RL-ReconfPrepTDD PRESENCE optional },
+ ...
+}
+
+DL-Timeslot-InformationModify-ModifyList-RL-ReconfPrepTDD ::= SEQUENCE (SIZE (1..maxNrOfDLTSs)) OF DL-Timeslot-InformationModify-ModifyItem-RL-ReconfPrepTDD
+
+DL-Timeslot-InformationModify-ModifyItem-RL-ReconfPrepTDD ::= SEQUENCE {
+ timeSlot TimeSlot,
+ midambleShiftAndBurstType MidambleShiftAndBurstType OPTIONAL,
+ tFCI-Presence TFCI-Presence OPTIONAL,
+ dL-Code-InformationModify-ModifyList-RL-ReconfPrepTDD DL-Code-InformationModify-ModifyList-RL-ReconfPrepTDD OPTIONAL,
+ iE-Extensions ProtocolExtensionContainer { { DL-Timeslot-InformationModify-ModifyItem-RL-ReconfPrepTDD-ExtIEs} } OPTIONAL,
+ ...
+}
+
+DL-Timeslot-InformationModify-ModifyItem-RL-ReconfPrepTDD-ExtIEs NBAP-PROTOCOL-EXTENSION ::= {
+ { ID id-Maximum-DL-Power-Modify-LCR-InformationModify-RL-ReconfPrepTDD CRITICALITY ignore EXTENSION DL-Power PRESENCE optional }|
+ -- Applicable to 1.28Mcps TDD only
+ { ID id-Minimum-DL-Power-Modify-LCR-InformationModify-RL-ReconfPrepTDD CRITICALITY ignore EXTENSION DL-Power PRESENCE optional },
+ -- Applicable to 1.28Mcps TDD only
+ ...
+}
+DL-Code-InformationModify-ModifyList-RL-ReconfPrepTDD ::= SEQUENCE (SIZE (0..maxNrOfDPCHs)) OF DL-Code-InformationModify-ModifyItem-RL-ReconfPrepTDD
+
+DL-Code-InformationModify-ModifyItem-RL-ReconfPrepTDD ::= SEQUENCE {
+ dPCH-ID DPCH-ID,
+ tdd-ChannelisationCode TDD-ChannelisationCode OPTIONAL,
+ iE-Extensions ProtocolExtensionContainer { { DL-Code-InformationModify-ModifyItem-RL-ReconfPrepTDD-ExtIEs} } OPTIONAL,
+ ...
+}
+
+DL-Code-InformationModify-ModifyItem-RL-ReconfPrepTDD-ExtIEs NBAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+DL-Timeslot-LCR-InformationModify-ModifyList-RL-ReconfPrepTDD ::= SEQUENCE (SIZE (1..maxNrOfDLTSLCRs)) OF DL-Timeslot-LCR-InformationModify-ModifyItem-RL-ReconfPrepTDD
+
+DL-Timeslot-LCR-InformationModify-ModifyItem-RL-ReconfPrepTDD ::= SEQUENCE {
+ timeSlotLCR TimeSlotLCR,
+ midambleShiftLCR MidambleShiftLCR OPTIONAL,
+ tFCI-Presence TFCI-Presence OPTIONAL,
+ dL-Code-LCR-InformationModify-ModifyList-RL-ReconfPrepTDD DL-Code-LCR-InformationModify-ModifyList-RL-ReconfPrepTDD OPTIONAL,
+ iE-Extensions ProtocolExtensionContainer { { DL-Timeslot-LCR-InformationModify-ModifyItem-RL-ReconfPrepTDD-ExtIEs} } OPTIONAL,
+ ...
+}
+
+DL-Timeslot-LCR-InformationModify-ModifyItem-RL-ReconfPrepTDD-ExtIEs NBAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+DL-Code-LCR-InformationModify-ModifyList-RL-ReconfPrepTDD ::= SEQUENCE (SIZE (1..maxNrOfDPCHLCRs)) OF DL-Code-LCR-InformationModify-ModifyItem-RL-ReconfPrepTDD
+
+DL-Code-LCR-InformationModify-ModifyItem-RL-ReconfPrepTDD ::= SEQUENCE {
+ dPCH-ID DPCH-ID,
+ tdd-ChannelisationCodeLCR TDD-ChannelisationCodeLCR OPTIONAL,
+ iE-Extensions ProtocolExtensionContainer { { DL-Code-LCR-InformationModify-ModifyItem-RL-ReconfPrepTDD-ExtIEs} } OPTIONAL,
+ ...
+}
+
+DL-Code-LCR-InformationModify-ModifyItem-RL-ReconfPrepTDD-ExtIEs NBAP-PROTOCOL-EXTENSION ::= {
+ { ID id-DL-DPCH-TimeSlotFormat-LCR-ModifyItem-RL-ReconfPrepTDD CRITICALITY reject EXTENSION TDD-DL-DPCH-TimeSlotFormat-LCR PRESENCE optional},
+ ...
+}
+
+DL-DPCH-InformationModify-DeleteList-RL-ReconfPrepTDD ::= ProtocolIE-Single-Container {{ DL-DPCH-InformationModify-DeleteListIEs-RL-ReconfPrepTDD }}
+
+DL-DPCH-InformationModify-DeleteListIEs-RL-ReconfPrepTDD NBAP-PROTOCOL-IES ::= {
+ { ID id-DL-DPCH-InformationModify-DeleteListIE-RL-ReconfPrepTDD CRITICALITY reject TYPE DL-DPCH-InformationModify-DeleteListIE-RL-ReconfPrepTDD PRESENCE mandatory }
+}
+
+DL-DPCH-InformationModify-DeleteListIE-RL-ReconfPrepTDD ::= SEQUENCE (SIZE (1..maxNrOfDPCHs)) OF DL-DPCH-InformationModify-DeleteItem-RL-ReconfPrepTDD
+
+DL-DPCH-InformationModify-DeleteItem-RL-ReconfPrepTDD ::= SEQUENCE {
+ dPCH-ID DPCH-ID,
+ iE-Extensions ProtocolExtensionContainer { { DL-DPCH-InformationModify-DeleteItem-RL-ReconfPrepTDD-ExtIEs} } OPTIONAL,
+ ...
+}
+
+DL-DPCH-InformationModify-DeleteItem-RL-ReconfPrepTDD-ExtIEs NBAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+DL-CCTrCH-InformationDeleteList-RL-ReconfPrepTDD ::= SEQUENCE (SIZE (1..maxNrOfCCTrCHs)) OF DL-CCTrCH-InformationDeleteItem-RL-ReconfPrepTDD
+
+DL-CCTrCH-InformationDeleteItem-RL-ReconfPrepTDD ::= SEQUENCE {
+ cCTrCH-ID CCTrCH-ID,
+ iE-Extensions ProtocolExtensionContainer { { DL-CCTrCH-InformationDeleteItem-RL-ReconfPrepTDD-ExtIEs} } OPTIONAL,
+ ...
+}
+
+DL-CCTrCH-InformationDeleteItem-RL-ReconfPrepTDD-ExtIEs NBAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+DCH-DeleteList-RL-ReconfPrepTDD ::= SEQUENCE (SIZE (1..maxNrOfDCHs)) OF DCH-DeleteItem-RL-ReconfPrepTDD
+
+DCH-DeleteItem-RL-ReconfPrepTDD ::= SEQUENCE {
+ dCH-ID DCH-ID,
+ iE-Extensions ProtocolExtensionContainer { { DCH-DeleteItem-RL-ReconfPrepTDD-ExtIEs} } OPTIONAL,
+ ...
+}
+
+DCH-DeleteItem-RL-ReconfPrepTDD-ExtIEs NBAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+DSCH-Information-ModifyList-RL-ReconfPrepTDD ::= SEQUENCE (SIZE (1..maxNrOfDSCHs)) OF DSCH-Information-ModifyItem-RL-ReconfPrepTDD
+
+DSCH-Information-ModifyItem-RL-ReconfPrepTDD ::= SEQUENCE {
+ dSCH-ID DSCH-ID,
+ cCTrCH-ID CCTrCH-ID OPTIONAL,
+ -- DL CCTrCH in which the DSCH is mapped
+ transportFormatSet TransportFormatSet OPTIONAL,
+ allocationRetentionPriority AllocationRetentionPriority OPTIONAL,
+ frameHandlingPriority FrameHandlingPriority OPTIONAL,
+ toAWS ToAWS OPTIONAL,
+ toAWE ToAWE OPTIONAL,
+ transportBearerRequestIndicator TransportBearerRequestIndicator,
+ iE-Extensions ProtocolExtensionContainer { { DSCH-Information-ModifyItem-RL-ReconfPrepTDD-ExtIEs} } OPTIONAL,
+ ...
+ }
+
+DSCH-Information-ModifyItem-RL-ReconfPrepTDD-ExtIEs NBAP-PROTOCOL-EXTENSION ::= {
+ { ID id-bindingID CRITICALITY ignore EXTENSION BindingID PRESENCE optional }|
+ -- Shall be ignored if bearer establishment with ALCAP.
+ { ID id-transportlayeraddress CRITICALITY ignore EXTENSION TransportLayerAddress PRESENCE optional },
+ -- Shall be ignored if bearer establishment with ALCAP.
+ ...
+}
+
+DSCH-Information-DeleteList-RL-ReconfPrepTDD ::= SEQUENCE (SIZE (1..maxNrOfDSCHs)) OF DSCH-Information-DeleteItem-RL-ReconfPrepTDD
+
+DSCH-Information-DeleteItem-RL-ReconfPrepTDD ::= SEQUENCE {
+ dSCH-ID DSCH-ID,
+ iE-Extensions ProtocolExtensionContainer { { DSCH-Information-DeleteItem-RL-ReconfPrepTDD-ExtIEs} } OPTIONAL,
+ ...
+}
+
+DSCH-Information-DeleteItem-RL-ReconfPrepTDD-ExtIEs NBAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+USCH-Information-ModifyList-RL-ReconfPrepTDD ::= SEQUENCE (SIZE (1..maxNrOfUSCHs)) OF USCH-Information-ModifyItem-RL-ReconfPrepTDD
+
+USCH-Information-ModifyItem-RL-ReconfPrepTDD ::= SEQUENCE {
+ uSCH-ID USCH-ID,
+ transportFormatSet TransportFormatSet OPTIONAL,
+ allocationRetentionPriority AllocationRetentionPriority OPTIONAL,
+ cCTrCH-ID CCTrCH-ID OPTIONAL, -- UL CCTrCH in which the USCH is mapped
+ transportBearerRequestIndicator TransportBearerRequestIndicator,
+ iE-Extensions ProtocolExtensionContainer { { USCH-Information-ModifyItem-RL-ReconfPrepTDD-ExtIEs} } OPTIONAL,
+ ...
+}
+
+USCH-Information-ModifyItem-RL-ReconfPrepTDD-ExtIEs NBAP-PROTOCOL-EXTENSION ::= {
+ { ID id-bindingID CRITICALITY ignore EXTENSION BindingID PRESENCE optional }|
+ -- Shall be ignored if bearer establishment with ALCAP.
+ { ID id-transportlayeraddress CRITICALITY ignore EXTENSION TransportLayerAddress PRESENCE optional }|
+ -- Shall be ignored if bearer establishment with ALCAP.
+ { ID id-TnlQos CRITICALITY ignore EXTENSION TnlQos PRESENCE optional },
+ ...
+}
+
+USCH-Information-DeleteList-RL-ReconfPrepTDD ::= SEQUENCE (SIZE (1..maxNrOfUSCHs)) OF USCH-Information-DeleteItem-RL-ReconfPrepTDD
+
+USCH-Information-DeleteItem-RL-ReconfPrepTDD ::= SEQUENCE {
+ uSCH-ID USCH-ID,
+ iE-Extensions ProtocolExtensionContainer { { USCH-Information-DeleteItem-RL-ReconfPrepTDD-ExtIEs} } OPTIONAL,
+ ...
+
+}
+
+USCH-Information-DeleteItem-RL-ReconfPrepTDD-ExtIEs NBAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+MultipleRL-Information-RL-ReconfPrepTDD ::= SEQUENCE (SIZE (1..maxNrOfRLs-1)) OF RL-Information-RL-ReconfPrepTDD
+--Includes the 2nd through the max number of radio link information repetitions.
+
+RL-Information-RL-ReconfPrepTDD ::= SEQUENCE {
+ rL-ID RL-ID,
+ maxDL-Power DL-Power OPTIONAL,
+ minDL-Power DL-Power OPTIONAL,
+ iE-Extensions ProtocolExtensionContainer { { RL-Information-RL-ReconfPrepTDD-ExtIEs} } OPTIONAL,
+ ...
+}
+
+RL-Information-RL-ReconfPrepTDD-ExtIEs NBAP-PROTOCOL-EXTENSION ::= {
+ { ID id-InitDL-Power CRITICALITY ignore EXTENSION DL-Power PRESENCE optional }|
+ { ID id-RL-Specific-DCH-Info CRITICALITY ignore EXTENSION RL-Specific-DCH-Info PRESENCE optional }|
+ { ID id-UL-Synchronisation-Parameters-LCR CRITICALITY ignore EXTENSION UL-Synchronisation-Parameters-LCR PRESENCE optional }|
+ -- Mandatory for 1.28Mcps TDD, Not Applicable to 3.84Mcps TDD
+ { ID id-TimeslotISCP-LCR-InfoList-RL-ReconfPrepTDD CRITICALITY ignore EXTENSION DL-TimeslotISCPInfoLCR PRESENCE optional },
+ -- Applicable to 1.28Mcps TDD only
+ ...
+}
+
+
+-- **************************************************************
+--
+-- RADIO LINK RECONFIGURATION READY
+--
+-- **************************************************************
+
+RadioLinkReconfigurationReady ::= SEQUENCE {
+ protocolIEs ProtocolIE-Container {{RadioLinkReconfigurationReady-IEs}},
+ protocolExtensions ProtocolExtensionContainer {{RadioLinkReconfigurationReady-Extensions}} OPTIONAL,
+ ...
+}
+
+RadioLinkReconfigurationReady-IEs NBAP-PROTOCOL-IES ::= {
+ { ID id-CRNC-CommunicationContextID CRITICALITY ignore TYPE CRNC-CommunicationContextID PRESENCE mandatory }|
+ { ID id-RL-InformationResponseList-RL-ReconfReady CRITICALITY ignore TYPE RL-InformationResponseList-RL-ReconfReady PRESENCE optional }|
+ { ID id-CriticalityDiagnostics CRITICALITY ignore TYPE CriticalityDiagnostics PRESENCE optional },
+ ...
+}
+
+RadioLinkReconfigurationReady-Extensions NBAP-PROTOCOL-EXTENSION ::= {
+ { ID id-TargetCommunicationControlPortID CRITICALITY ignore EXTENSION CommunicationControlPortID PRESENCE optional }|
+ { ID id-HSDSCH-FDD-Information-Response CRITICALITY ignore EXTENSION HSDSCH-FDD-Information-Response PRESENCE optional }|
+ -- FDD only
+ { ID id-HSDSCH-TDD-Information-Response CRITICALITY ignore EXTENSION HSDSCH-TDD-Information-Response PRESENCE optional },
+ -- TDD only
+ ...
+}
+
+RL-InformationResponseList-RL-ReconfReady ::= SEQUENCE (SIZE (1..maxNrOfRLs)) OF ProtocolIE-Single-Container {{ RL-InformationResponseItemIE-RL-ReconfReady}}
+
+RL-InformationResponseItemIE-RL-ReconfReady NBAP-PROTOCOL-IES ::= {
+ { ID id-RL-InformationResponseItem-RL-ReconfReady CRITICALITY ignore TYPE RL-InformationResponseItem-RL-ReconfReady PRESENCE mandatory }
+}
+
+RL-InformationResponseItem-RL-ReconfReady ::= SEQUENCE {
+ rL-ID RL-ID,
+ dCH-InformationResponseList-RL-ReconfReady DCH-InformationResponseList-RL-ReconfReady OPTIONAL,
+ dSCH-InformationResponseList-RL-ReconfReady DSCH-InformationResponseList-RL-ReconfReady OPTIONAL,
+ uSCH-InformationResponseList-RL-ReconfReady USCH-InformationResponseList-RL-ReconfReady OPTIONAL, -- TDD only
+ tFCI2-BearerInformationResponse TFCI2-BearerInformationResponse OPTIONAL,
+ -- FDD only. There shall be only one TFCI2 bearer per Node B Communication Context.
+ iE-Extensions ProtocolExtensionContainer { { RL-InformationResponseItem-RL-ReconfReady-ExtIEs} } OPTIONAL,
+ ...
+}
+
+RL-InformationResponseItem-RL-ReconfReady-ExtIEs NBAP-PROTOCOL-EXTENSION ::= {
+ { ID id-DL-PowerBalancing-UpdatedIndicator CRITICALITY ignore EXTENSION DL-PowerBalancing-UpdatedIndicator PRESENCE optional},
+ ...
+}
+
+DCH-InformationResponseList-RL-ReconfReady::= ProtocolIE-Single-Container {{ DCH-InformationResponseListIEs-RL-ReconfReady }}
+
+DCH-InformationResponseListIEs-RL-ReconfReady NBAP-PROTOCOL-IES ::= {
+ { ID id-DCH-InformationResponse CRITICALITY ignore TYPE DCH-InformationResponse PRESENCE mandatory }
+}
+
+DSCH-InformationResponseList-RL-ReconfReady::= ProtocolIE-Single-Container {{ DSCH-InformationResponseListIEs-RL-ReconfReady }}
+
+DSCH-InformationResponseListIEs-RL-ReconfReady NBAP-PROTOCOL-IES ::= {
+ { ID id-DSCH-InformationResponse CRITICALITY ignore TYPE DSCH-InformationResponse PRESENCE mandatory }
+}
+
+USCH-InformationResponseList-RL-ReconfReady::= ProtocolIE-Single-Container {{ USCH-InformationResponseListIEs-RL-ReconfReady }}
+
+USCH-InformationResponseListIEs-RL-ReconfReady NBAP-PROTOCOL-IES ::= {
+ { ID id-USCH-InformationResponse CRITICALITY ignore TYPE USCH-InformationResponse PRESENCE mandatory }
+}
+
+-- **************************************************************
+--
+-- RADIO LINK RECONFIGURATION FAILURE
+--
+-- **************************************************************
+
+RadioLinkReconfigurationFailure ::= SEQUENCE {
+ protocolIEs ProtocolIE-Container {{RadioLinkReconfigurationFailure-IEs}},
+ protocolExtensions ProtocolExtensionContainer {{RadioLinkReconfigurationFailure-Extensions}} OPTIONAL,
+ ...
+}
+
+RadioLinkReconfigurationFailure-IEs NBAP-PROTOCOL-IES ::= {
+ { ID id-CRNC-CommunicationContextID CRITICALITY ignore TYPE CRNC-CommunicationContextID PRESENCE mandatory } |
+ { ID id-CauseLevel-RL-ReconfFailure CRITICALITY ignore TYPE CauseLevel-RL-ReconfFailure PRESENCE mandatory } |
+ { ID id-CriticalityDiagnostics CRITICALITY ignore TYPE CriticalityDiagnostics PRESENCE optional },
+ ...
+}
+
+RadioLinkReconfigurationFailure-Extensions NBAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+CauseLevel-RL-ReconfFailure ::= CHOICE {
+ generalCause GeneralCauseList-RL-ReconfFailure,
+ rLSpecificCause RLSpecificCauseList-RL-ReconfFailure,
+ ...
+}
+
+GeneralCauseList-RL-ReconfFailure ::= SEQUENCE {
+ cause Cause,
+ iE-Extensions ProtocolExtensionContainer { { GeneralCauseItem-RL-ReconfFailure-ExtIEs} } OPTIONAL,
+ ...
+ }
+
+GeneralCauseItem-RL-ReconfFailure-ExtIEs NBAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+RLSpecificCauseList-RL-ReconfFailure ::= SEQUENCE {
+ rL-ReconfigurationFailureList-RL-ReconfFailure RL-ReconfigurationFailureList-RL-ReconfFailure OPTIONAL,
+ iE-Extensions ProtocolExtensionContainer { { RLSpecificCauseItem-RL-ReconfFailure-ExtIEs} } OPTIONAL,
+ ...
+ }
+
+RLSpecificCauseItem-RL-ReconfFailure-ExtIEs NBAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+RL-ReconfigurationFailureList-RL-ReconfFailure ::= SEQUENCE (SIZE (1..maxNrOfRLs)) OF ProtocolIE-Single-Container {{ RL-ReconfigurationFailureItemIE-RL-ReconfFailure}}
+
+RL-ReconfigurationFailureItemIE-RL-ReconfFailure NBAP-PROTOCOL-IES ::= {
+ { ID id-RL-ReconfigurationFailureItem-RL-ReconfFailure CRITICALITY ignore TYPE RL-ReconfigurationFailureItem-RL-ReconfFailure PRESENCE mandatory}
+}
+
+RL-ReconfigurationFailureItem-RL-ReconfFailure ::= SEQUENCE {
+ rL-ID RL-ID,
+ cause Cause,
+ iE-Extensions ProtocolExtensionContainer { { RL-ReconfigurationFailureItem-RL-ReconfFailure-ExtIEs} } OPTIONAL,
+ ...
+ }
+
+RL-ReconfigurationFailureItem-RL-ReconfFailure-ExtIEs NBAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+-- **************************************************************
+--
+-- RADIO LINK RECONFIGURATION COMMIT
+--
+-- **************************************************************
+
+RadioLinkReconfigurationCommit ::= SEQUENCE {
+ protocolIEs ProtocolIE-Container {{RadioLinkReconfigurationCommit-IEs}},
+ protocolExtensions ProtocolExtensionContainer {{RadioLinkReconfigurationCommit-Extensions}} OPTIONAL,
+ ...
+}
+
+RadioLinkReconfigurationCommit-IEs NBAP-PROTOCOL-IES ::= {
+ { ID id-NodeB-CommunicationContextID CRITICALITY ignore TYPE NodeB-CommunicationContextID PRESENCE mandatory } |
+ { ID id-CFN CRITICALITY ignore TYPE CFN PRESENCE mandatory }|
+ { ID id-Active-Pattern-Sequence-Information CRITICALITY ignore TYPE Active-Pattern-Sequence-Information PRESENCE optional },
+ -- FDD only
+ ...
+}
+
+RadioLinkReconfigurationCommit-Extensions NBAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+-- **************************************************************
+--
+-- RADIO LINK RECONFIGURATION CANCEL
+--
+-- **************************************************************
+
+RadioLinkReconfigurationCancel ::= SEQUENCE {
+ protocolIEs ProtocolIE-Container {{RadioLinkReconfigurationCancel-IEs}},
+ protocolExtensions ProtocolExtensionContainer {{RadioLinkReconfigurationCancel-Extensions}} OPTIONAL,
+ ...
+}
+
+RadioLinkReconfigurationCancel-IEs NBAP-PROTOCOL-IES ::= {
+ { ID id-NodeB-CommunicationContextID CRITICALITY ignore TYPE NodeB-CommunicationContextID PRESENCE mandatory },
+ ...
+}
+
+RadioLinkReconfigurationCancel-Extensions NBAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+-- **************************************************************
+--
+-- RADIO LINK RECONFIGURATION REQUEST FDD
+--
+-- **************************************************************
+
+RadioLinkReconfigurationRequestFDD ::= SEQUENCE {
+ protocolIEs ProtocolIE-Container {{RadioLinkReconfigurationRequestFDD-IEs}},
+ protocolExtensions ProtocolExtensionContainer {{RadioLinkReconfigurationRequestFDD-Extensions}} OPTIONAL,
+ ...
+}
+
+RadioLinkReconfigurationRequestFDD-IEs NBAP-PROTOCOL-IES ::= {
+ { ID id-NodeB-CommunicationContextID CRITICALITY reject TYPE NodeB-CommunicationContextID PRESENCE mandatory }|
+ { ID id-UL-DPCH-Information-RL-ReconfRqstFDD CRITICALITY reject TYPE UL-DPCH-Information-RL-ReconfRqstFDD PRESENCE optional }|
+ { ID id-DL-DPCH-Information-RL-ReconfRqstFDD CRITICALITY reject TYPE DL-DPCH-Information-RL-ReconfRqstFDD PRESENCE optional }|
+ { ID id-FDD-DCHs-to-Modify CRITICALITY reject TYPE FDD-DCHs-to-Modify PRESENCE optional }|
+ { ID id-DCHs-to-Add-FDD CRITICALITY reject TYPE DCH-FDD-Information PRESENCE optional }|
+ { ID id-DCH-DeleteList-RL-ReconfRqstFDD CRITICALITY reject TYPE DCH-DeleteList-RL-ReconfRqstFDD PRESENCE optional }|
+ { ID id-RL-InformationList-RL-ReconfRqstFDD CRITICALITY reject TYPE RL-InformationList-RL-ReconfRqstFDD PRESENCE optional }|
+ { ID id-Transmission-Gap-Pattern-Sequence-Information CRITICALITY reject TYPE Transmission-Gap-Pattern-Sequence-Information PRESENCE optional },
+ ...
+}
+
+RadioLinkReconfigurationRequestFDD-Extensions NBAP-PROTOCOL-EXTENSION ::= {
+ { ID id-SignallingBearerRequestIndicator CRITICALITY reject EXTENSION SignallingBearerRequestIndicator PRESENCE optional }|
+ { ID id-HSDSCH-FDD-Information CRITICALITY reject EXTENSION HSDSCH-FDD-Information PRESENCE optional }|
+ { ID id-HSDSCH-Information-to-Modify-Unsynchronised CRITICALITY reject EXTENSION HSDSCH-Information-to-Modify-Unsynchronised PRESENCE optional }|
+ { ID id-HSDSCH-MACdFlows-to-Add CRITICALITY reject EXTENSION HSDSCH-MACdFlows-Information PRESENCE optional }|
+ { ID id-HSDSCH-MACdFlows-to-Delete CRITICALITY reject EXTENSION HSDSCH-MACdFlows-to-Delete PRESENCE optional }|
+ { ID id-HSDSCH-RNTI CRITICALITY reject EXTENSION HSDSCH-RNTI PRESENCE conditional }|
+ -- The IE shall be present if HS-PDSCH RL ID IE is present.
+ { ID id-HSPDSCH-RL-ID CRITICALITY reject EXTENSION RL-ID PRESENCE optional },
+ ...
+}
+
+
+UL-DPCH-Information-RL-ReconfRqstFDD ::= SEQUENCE {
+ ul-TFCS TFCS OPTIONAL,
+ iE-Extensions ProtocolExtensionContainer { { UL-DPCH-Information-RL-ReconfRqstFDD-ExtIEs} } OPTIONAL,
+ ...
+}
+
+UL-DPCH-Information-RL-ReconfRqstFDD-ExtIEs NBAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+DL-DPCH-Information-RL-ReconfRqstFDD ::= SEQUENCE {
+ dl-TFCS TFCS OPTIONAL,
+ tFCI-SignallingMode TFCI-SignallingMode OPTIONAL,
+ limitedPowerIncrease LimitedPowerIncrease OPTIONAL,
+ iE-Extensions ProtocolExtensionContainer { { DL-DPCH-Information-RL-ReconfRqstFDD-ExtIEs} } OPTIONAL,
+ ...
+ }
+
+DL-DPCH-Information-RL-ReconfRqstFDD-ExtIEs NBAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+DCH-DeleteList-RL-ReconfRqstFDD ::= SEQUENCE (SIZE (1..maxNrOfDCHs)) OF DCH-DeleteItem-RL-ReconfRqstFDD
+
+DCH-DeleteItem-RL-ReconfRqstFDD ::= SEQUENCE {
+ dCH-ID DCH-ID,
+ iE-Extensions ProtocolExtensionContainer { { DCH-DeleteItem-RL-ReconfRqstFDD-ExtIEs} } OPTIONAL,
+ ...
+
+}
+
+DCH-DeleteItem-RL-ReconfRqstFDD-ExtIEs NBAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+RL-InformationList-RL-ReconfRqstFDD ::= SEQUENCE (SIZE (1..maxNrOfRLs)) OF ProtocolIE-Single-Container {{ RL-InformationItemIE-RL-ReconfRqstFDD}}
+
+RL-InformationItemIE-RL-ReconfRqstFDD NBAP-PROTOCOL-IES ::= {
+ { ID id-RL-InformationItem-RL-ReconfRqstFDD CRITICALITY reject TYPE RL-InformationItem-RL-ReconfRqstFDD PRESENCE mandatory}
+}
+
+RL-InformationItem-RL-ReconfRqstFDD ::= SEQUENCE {
+ rL-ID RL-ID,
+ maxDL-Power DL-Power OPTIONAL,
+ minDL-Power DL-Power OPTIONAL,
+ dl-CodeInformation FDD-DL-CodeInformation OPTIONAL,
+-- The IE shall be present if the Transmission Gap Pattern Sequence Information IE is included and the indicated Downlink Compressed Mode method for at least one of the included Transmission Gap Pattern Sequence is set to "SF/2".
+ iE-Extensions ProtocolExtensionContainer { { RL-InformationItem-RL-ReconfRqstFDD-ExtIEs} } OPTIONAL,
+ ...
+}
+
+RL-InformationItem-RL-ReconfRqstFDD-ExtIEs NBAP-PROTOCOL-EXTENSION ::= {
+ { ID id-DLReferencePower CRITICALITY ignore EXTENSION DL-Power PRESENCE optional }|
+ { ID id-RL-Specific-DCH-Info CRITICALITY ignore EXTENSION RL-Specific-DCH-Info PRESENCE optional },
+ ...
+}
+
+-- **************************************************************
+--
+-- RADIO LINK RECONFIGURATION REQUEST TDD
+--
+-- **************************************************************
+
+RadioLinkReconfigurationRequestTDD ::= SEQUENCE {
+ protocolIEs ProtocolIE-Container {{RadioLinkReconfigurationRequestTDD-IEs}},
+ protocolExtensions ProtocolExtensionContainer {{RadioLinkReconfigurationRequestTDD-Extensions}} OPTIONAL,
+ ...
+}
+
+RadioLinkReconfigurationRequestTDD-IEs NBAP-PROTOCOL-IES ::= {
+ { ID id-NodeB-CommunicationContextID CRITICALITY reject TYPE NodeB-CommunicationContextID PRESENCE mandatory }|
+ { ID id-UL-CCTrCH-InformationModifyList-RL-ReconfRqstTDD CRITICALITY notify TYPE UL-CCTrCH-InformationModifyList-RL-ReconfRqstTDD PRESENCE optional } |
+ { ID id-UL-CCTrCH-InformationDeleteList-RL-ReconfRqstTDD CRITICALITY notify TYPE UL-CCTrCH-InformationDeleteList-RL-ReconfRqstTDD PRESENCE optional } |
+ { ID id-DL-CCTrCH-InformationModifyList-RL-ReconfRqstTDD CRITICALITY notify TYPE DL-CCTrCH-InformationModifyList-RL-ReconfRqstTDD PRESENCE optional } |
+ { ID id-DL-CCTrCH-InformationDeleteList-RL-ReconfRqstTDD CRITICALITY notify TYPE DL-CCTrCH-InformationDeleteList-RL-ReconfRqstTDD PRESENCE optional } |
+ { ID id-TDD-DCHs-to-Modify CRITICALITY reject TYPE TDD-DCHs-to-Modify PRESENCE optional }|
+ { ID id-DCHs-to-Add-TDD CRITICALITY reject TYPE DCH-TDD-Information PRESENCE optional }|
+ { ID id-DCH-DeleteList-RL-ReconfRqstTDD CRITICALITY reject TYPE DCH-DeleteList-RL-ReconfRqstTDD PRESENCE optional }|
+ { ID id-RL-Information-RL-ReconfRqstTDD CRITICALITY reject TYPE RL-Information-RL-ReconfRqstTDD PRESENCE optional },
+-- This RL-Information-RL-ReconfRqstTDD is the first RL information repetition in the RL-Information List. Repetition 2 and on, should be defined in Multiple-RL-Information-RL-ReconfRqstTDD,
+ ...
+}
+
+RadioLinkReconfigurationRequestTDD-Extensions NBAP-PROTOCOL-EXTENSION ::= {
+ { ID id-SignallingBearerRequestIndicator CRITICALITY reject EXTENSION SignallingBearerRequestIndicator PRESENCE optional }|
+ { ID id-RL-Information-RL-ReconfRqstTDD CRITICALITY reject EXTENSION Multiple-RL-Information-RL-ReconfRqstTDD PRESENCE optional }|
+--Includes the 2nd through the max number of radio link information repetitions.
+ { ID id-HSDSCH-TDD-Information CRITICALITY reject EXTENSION HSDSCH-TDD-Information PRESENCE optional }|
+ { ID id-HSDSCH-Information-to-Modify-Unsynchronised CRITICALITY reject EXTENSION HSDSCH-Information-to-Modify-Unsynchronised PRESENCE optional }|
+ { ID id-HSDSCH-MACdFlows-to-Add CRITICALITY reject EXTENSION HSDSCH-MACdFlows-Information PRESENCE optional }|
+ { ID id-HSDSCH-MACdFlows-to-Delete CRITICALITY reject EXTENSION HSDSCH-MACdFlows-to-Delete PRESENCE optional }|
+ { ID id-HSDSCH-RNTI CRITICALITY reject EXTENSION HSDSCH-RNTI PRESENCE conditional }|
+ -- The IE shall be present if HS-PDSCH RL ID IE is present.
+ { ID id-HSPDSCH-RL-ID CRITICALITY reject EXTENSION RL-ID PRESENCE optional },
+ ...
+}
+
+UL-CCTrCH-InformationModifyList-RL-ReconfRqstTDD ::= SEQUENCE (SIZE (1..maxNrOfCCTrCHs)) OF ProtocolIE-Single-Container {{ UL-CCTrCH-InformationModifyItemIE-RL-ReconfRqstTDD}}
+
+UL-CCTrCH-InformationModifyItemIE-RL-ReconfRqstTDD NBAP-PROTOCOL-IES ::= {
+ { ID id-UL-CCTrCH-InformationModifyItem-RL-ReconfRqstTDD CRITICALITY notify TYPE UL-CCTrCH-InformationModifyItem-RL-ReconfRqstTDD PRESENCE mandatory}
+}
+
+UL-CCTrCH-InformationModifyItem-RL-ReconfRqstTDD ::= SEQUENCE {
+ cCTrCH-ID CCTrCH-ID,
+ tFCS TFCS OPTIONAL,
+ punctureLimit PunctureLimit OPTIONAL,
+ iE-Extensions ProtocolExtensionContainer { { UL-CCTrCH-InformationModifyItem-RL-ReconfRqstTDD-ExtIEs} } OPTIONAL,
+ ...
+}
+
+UL-CCTrCH-InformationModifyItem-RL-ReconfRqstTDD-ExtIEs NBAP-PROTOCOL-EXTENSION ::= {
+{ ID id-UL-SIRTarget CRITICALITY reject EXTENSION UL-SIR PRESENCE optional },
+ -- Applicable to 1.28Mcps TDD only
+ ...
+}
+
+UL-CCTrCH-InformationDeleteList-RL-ReconfRqstTDD ::= SEQUENCE (SIZE (1..maxNrOfCCTrCHs)) OF ProtocolIE-Single-Container {{ UL-CCTrCH-InformationDeleteItemIE-RL-ReconfRqstTDD}}
+
+UL-CCTrCH-InformationDeleteItemIE-RL-ReconfRqstTDD NBAP-PROTOCOL-IES ::= {
+ { ID id-UL-CCTrCH-InformationDeleteItem-RL-ReconfRqstTDD CRITICALITY notify TYPE UL-CCTrCH-InformationDeleteItem-RL-ReconfRqstTDD PRESENCE mandatory}
+}
+
+UL-CCTrCH-InformationDeleteItem-RL-ReconfRqstTDD ::= SEQUENCE {
+ cCTrCH-ID CCTrCH-ID,
+ iE-Extensions ProtocolExtensionContainer { { UL-CCTrCH-InformationDeleteItem-RL-ReconfRqstTDD-ExtIEs} } OPTIONAL,
+ ...
+}
+
+UL-CCTrCH-InformationDeleteItem-RL-ReconfRqstTDD-ExtIEs NBAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+DL-CCTrCH-InformationModifyList-RL-ReconfRqstTDD ::= SEQUENCE (SIZE (1..maxNrOfCCTrCHs)) OF ProtocolIE-Single-Container {{ DL-CCTrCH-InformationModifyItemIE-RL-ReconfRqstTDD}}
+
+DL-CCTrCH-InformationModifyItemIE-RL-ReconfRqstTDD NBAP-PROTOCOL-IES ::= {
+ { ID id-DL-CCTrCH-InformationModifyItem-RL-ReconfRqstTDD CRITICALITY notify TYPE DL-CCTrCH-InformationModifyItem-RL-ReconfRqstTDD PRESENCE mandatory}
+}
+
+DL-CCTrCH-InformationModifyItem-RL-ReconfRqstTDD ::= SEQUENCE {
+ cCTrCH-ID CCTrCH-ID,
+ tFCS TFCS OPTIONAL,
+ punctureLimit PunctureLimit OPTIONAL,
+ iE-Extensions ProtocolExtensionContainer { { DL-CCTrCH-InformationModifyItem-RL-ReconfRqstTDD-ExtIEs} } OPTIONAL,
+ ...
+}
+
+DL-CCTrCH-InformationModifyItem-RL-ReconfRqstTDD-ExtIEs NBAP-PROTOCOL-EXTENSION ::= {
+ { ID id-DL-DPCH-LCR-InformationModify-ModifyList-RL-ReconfRqstTDD CRITICALITY ignore EXTENSION DL-DPCH-LCR-InformationModify-ModifyList-RL-ReconfRqstTDD PRESENCE optional }| -- Applicable to 1.28Mcps TDD only
+ { ID id-CCTrCH-Maximum-DL-Power-InformationModify-RL-ReconfRqstTDD CRITICALITY ignore EXTENSION DL-Power PRESENCE optional }|
+ { ID id-CCTrCH-Minimum-DL-Power-InformationModify-RL-ReconfRqstTDD CRITICALITY ignore EXTENSION DL-Power PRESENCE optional },
+ ...
+}
+
+DL-DPCH-LCR-InformationModify-ModifyList-RL-ReconfRqstTDD ::= SEQUENCE {
+ dL-Timeslot-LCR-InformationModify-ModifyList-RL-ReconfRqstTDD DL-Timeslot-LCR-InformationModify-ModifyList-RL-ReconfRqstTDD OPTIONAL,
+ iE-Extensions ProtocolExtensionContainer { { DL-DPCH-LCR-InformationModify-ModifyList-RL-ReconfRqstTDD-ExtIEs} } OPTIONAL,
+ ...
+}
+
+DL-DPCH-LCR-InformationModify-ModifyList-RL-ReconfRqstTDD-ExtIEs NBAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+DL-Timeslot-LCR-InformationModify-ModifyList-RL-ReconfRqstTDD ::= SEQUENCE (SIZE (1..maxNrOfDLTSLCRs)) OF DL-Timeslot-LCR-InformationModify-ModifyItem-RL-ReconfRqstTDD
+
+DL-Timeslot-LCR-InformationModify-ModifyItem-RL-ReconfRqstTDD ::= SEQUENCE {
+ timeSlotLCR TimeSlotLCR,
+ maxPowerLCR DL-Power OPTIONAL,
+ minPowerLCR DL-Power OPTIONAL,
+ iE-Extensions ProtocolExtensionContainer { { DL-Timeslot-LCR-InformationModify-ModifyItem-RL-ReconfRqstTDD-ExtIEs} } OPTIONAL,
+ ...
+}
+
+DL-Timeslot-LCR-InformationModify-ModifyItem-RL-ReconfRqstTDD-ExtIEs NBAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+DL-CCTrCH-InformationDeleteList-RL-ReconfRqstTDD ::= SEQUENCE (SIZE (1..maxNrOfCCTrCHs)) OF ProtocolIE-Single-Container {{ DL-CCTrCH-InformationDeleteItemIE-RL-ReconfRqstTDD}}
+
+DL-CCTrCH-InformationDeleteItemIE-RL-ReconfRqstTDD NBAP-PROTOCOL-IES ::= {
+ { ID id-DL-CCTrCH-InformationDeleteItem-RL-ReconfRqstTDD CRITICALITY notify TYPE DL-CCTrCH-InformationDeleteItem-RL-ReconfRqstTDD PRESENCE mandatory}
+}
+
+DL-CCTrCH-InformationDeleteItem-RL-ReconfRqstTDD ::= SEQUENCE {
+ cCTrCH-ID CCTrCH-ID,
+ iE-Extensions ProtocolExtensionContainer { { DL-CCTrCH-InformationDeleteItem-RL-ReconfRqstTDD-ExtIEs} } OPTIONAL,
+ ...
+}
+
+DL-CCTrCH-InformationDeleteItem-RL-ReconfRqstTDD-ExtIEs NBAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+DCH-DeleteList-RL-ReconfRqstTDD ::= SEQUENCE (SIZE (1..maxNrOfDCHs)) OF DCH-DeleteItem-RL-ReconfRqstTDD
+
+DCH-DeleteItem-RL-ReconfRqstTDD ::= SEQUENCE {
+ dCH-ID DCH-ID,
+ iE-Extensions ProtocolExtensionContainer { { DCH-DeleteItem-RL-ReconfRqstTDD-ExtIEs} } OPTIONAL,
+ ...
+}
+
+DCH-DeleteItem-RL-ReconfRqstTDD-ExtIEs NBAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+Multiple-RL-Information-RL-ReconfRqstTDD ::= SEQUENCE (SIZE (1..maxNrOfRLs-1)) OF RL-Information-RL-ReconfRqstTDD
+--Includes the 2nd through the max number of radio link information repetitions.
+
+RL-Information-RL-ReconfRqstTDD ::= SEQUENCE {
+ rL-ID RL-ID,
+ maxDL-Power DL-Power OPTIONAL,
+ minDL-Power DL-Power OPTIONAL,
+ iE-Extensions ProtocolExtensionContainer { { RL-InformationItem-RL-ReconfRqstTDD-ExtIEs} } OPTIONAL,
+ ...
+}
+
+RL-InformationItem-RL-ReconfRqstTDD-ExtIEs NBAP-PROTOCOL-EXTENSION ::= {
+ { ID id-RL-Specific-DCH-Info CRITICALITY ignore EXTENSION RL-Specific-DCH-Info PRESENCE optional }|
+ { ID id-UL-Synchronisation-Parameters-LCR CRITICALITY ignore EXTENSION UL-Synchronisation-Parameters-LCR PRESENCE optional }, -- Mandatory for 1.28Mcps TDD, Not Applicable to 3.84Mcps TDD
+ ...
+}
+
+-- **************************************************************
+--
+-- RADIO LINK RECONFIGURATION RESPONSE
+--
+-- **************************************************************
+
+RadioLinkReconfigurationResponse ::= SEQUENCE {
+ protocolIEs ProtocolIE-Container {{RadioLinkReconfigurationResponse-IEs}},
+ protocolExtensions ProtocolExtensionContainer {{RadioLinkReconfigurationResponse-Extensions}} OPTIONAL,
+ ...
+}
+
+RadioLinkReconfigurationResponse-IEs NBAP-PROTOCOL-IES ::= {
+ { ID id-CRNC-CommunicationContextID CRITICALITY ignore TYPE CRNC-CommunicationContextID PRESENCE mandatory } |
+ { ID id-RL-InformationResponseList-RL-ReconfRsp CRITICALITY ignore TYPE RL-InformationResponseList-RL-ReconfRsp PRESENCE optional } |
+ { ID id-CriticalityDiagnostics CRITICALITY ignore TYPE CriticalityDiagnostics PRESENCE optional },
+ ...
+}
+
+RadioLinkReconfigurationResponse-Extensions NBAP-PROTOCOL-EXTENSION ::= {
+ { ID id-TargetCommunicationControlPortID CRITICALITY ignore EXTENSION CommunicationControlPortID PRESENCE optional }|
+ { ID id-HSDSCH-FDD-Information-Response CRITICALITY ignore EXTENSION HSDSCH-FDD-Information-Response PRESENCE optional }|
+ -- FDD only
+ { ID id-HSDSCH-TDD-Information-Response CRITICALITY ignore EXTENSION HSDSCH-TDD-Information-Response PRESENCE optional },
+ -- TDD only
+ ...
+}
+
+RL-InformationResponseList-RL-ReconfRsp ::= SEQUENCE (SIZE (1..maxNrOfRLs)) OF ProtocolIE-Single-Container {{RL-InformationResponseItemIE-RL-ReconfRsp}}
+
+RL-InformationResponseItemIE-RL-ReconfRsp NBAP-PROTOCOL-IES ::= {
+ { ID id-RL-InformationResponseItem-RL-ReconfRsp CRITICALITY ignore TYPE RL-InformationResponseItem-RL-ReconfRsp PRESENCE mandatory}
+}
+
+RL-InformationResponseItem-RL-ReconfRsp ::= SEQUENCE {
+ rL-ID RL-ID,
+ dCH-InformationResponseList-RL-ReconfRsp DCH-InformationResponseList-RL-ReconfRsp OPTIONAL,
+ iE-Extensions ProtocolExtensionContainer { { RL-InformationResponseItem-RL-ReconfRsp-ExtIEs} } OPTIONAL,
+ ...
+}
+
+RL-InformationResponseItem-RL-ReconfRsp-ExtIEs NBAP-PROTOCOL-EXTENSION ::= {
+ { ID id-DL-PowerBalancing-UpdatedIndicator CRITICALITY ignore EXTENSION DL-PowerBalancing-UpdatedIndicator PRESENCE optional },
+ -- FDD only
+ ...
+}
+
+DCH-InformationResponseList-RL-ReconfRsp::= ProtocolIE-Single-Container {{ DCH-InformationResponseListIEs-RL-ReconfRsp }}
+
+DCH-InformationResponseListIEs-RL-ReconfRsp NBAP-PROTOCOL-IES ::= {
+ { ID id-DCH-InformationResponse CRITICALITY ignore TYPE DCH-InformationResponse PRESENCE mandatory }
+}
+
+-- **************************************************************
+--
+-- RADIO LINK DELETION REQUEST
+--
+-- **************************************************************
+
+RadioLinkDeletionRequest ::= SEQUENCE {
+ protocolIEs ProtocolIE-Container {{RadioLinkDeletionRequest-IEs}},
+ protocolExtensions ProtocolExtensionContainer {{RadioLinkDeletionRequest-Extensions}} OPTIONAL,
+ ...
+}
+
+RadioLinkDeletionRequest-IEs NBAP-PROTOCOL-IES ::= {
+ { ID id-NodeB-CommunicationContextID CRITICALITY reject TYPE NodeB-CommunicationContextID PRESENCE mandatory }|
+ { ID id-CRNC-CommunicationContextID CRITICALITY reject TYPE CRNC-CommunicationContextID PRESENCE mandatory }|
+ { ID id-RL-informationList-RL-DeletionRqst CRITICALITY notify TYPE RL-informationList-RL-DeletionRqst PRESENCE mandatory },
+ ...
+}
+
+RadioLinkDeletionRequest-Extensions NBAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+RL-informationList-RL-DeletionRqst ::= SEQUENCE (SIZE (1..maxNrOfRLs)) OF ProtocolIE-Single-Container {{RL-informationItemIE-RL-DeletionRqst}}
+
+RL-informationItemIE-RL-DeletionRqst NBAP-PROTOCOL-IES ::= {
+ { ID id-RL-informationItem-RL-DeletionRqst CRITICALITY notify TYPE RL-informationItem-RL-DeletionRqst PRESENCE mandatory}
+}
+
+RL-informationItem-RL-DeletionRqst ::= SEQUENCE {
+ rL-ID RL-ID,
+ iE-Extensions ProtocolExtensionContainer { { RL-informationItem-RL-DeletionRqst-ExtIEs} } OPTIONAL,
+ ...
+ }
+
+RL-informationItem-RL-DeletionRqst-ExtIEs NBAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+-- **************************************************************
+--
+-- RADIO LINK DELETION RESPONSE
+--
+-- **************************************************************
+
+RadioLinkDeletionResponse ::= SEQUENCE {
+ protocolIEs ProtocolIE-Container {{RadioLinkDeletionResponse-IEs}},
+ protocolExtensions ProtocolExtensionContainer {{RadioLinkDeletionResponse-Extensions}} OPTIONAL,
+ ...
+}
+
+RadioLinkDeletionResponse-IEs NBAP-PROTOCOL-IES ::= {
+ { ID id-CRNC-CommunicationContextID CRITICALITY ignore TYPE CRNC-CommunicationContextID PRESENCE mandatory }|
+ { ID id-CriticalityDiagnostics CRITICALITY ignore TYPE CriticalityDiagnostics PRESENCE optional },
+ ...
+}
+
+RadioLinkDeletionResponse-Extensions NBAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+
+-- **************************************************************
+--
+-- DL POWER CONTROL REQUEST FDD
+--
+-- **************************************************************
+
+DL-PowerControlRequest ::= SEQUENCE {
+ protocolIEs ProtocolIE-Container {{DL-PowerControlRequest-IEs}},
+ protocolExtensions ProtocolExtensionContainer {{DL-PowerControlRequest-Extensions}} OPTIONAL,
+ ...
+}
+
+DL-PowerControlRequest-IEs NBAP-PROTOCOL-IES ::= {
+ { ID id-NodeB-CommunicationContextID CRITICALITY ignore TYPE NodeB-CommunicationContextID PRESENCE mandatory } |
+ { ID id-PowerAdjustmentType CRITICALITY ignore TYPE PowerAdjustmentType PRESENCE mandatory} |
+ { ID id-DLReferencePower CRITICALITY ignore TYPE DL-Power PRESENCE conditional} |
+ -- This IE shall be present if the Adjustment Type IE is set to 'Common'
+ { ID id-InnerLoopDLPCStatus CRITICALITY ignore TYPE InnerLoopDLPCStatus PRESENCE optional } |
+ { ID id-DLReferencePowerList-DL-PC-Rqst CRITICALITY ignore TYPE DL-ReferencePowerInformationList-DL-PC-Rqst PRESENCE conditional } |
+ -- This IE shall be present if the Adjustment Type IE is set to 'Individual'
+ { ID id-MaxAdjustmentStep CRITICALITY ignore TYPE MaxAdjustmentStep PRESENCE conditional} |
+ -- This IE shall be present if the Adjustment Type IE is set to 'Common' or 'Individual'
+ { ID id-AdjustmentPeriod CRITICALITY ignore TYPE AdjustmentPeriod PRESENCE conditional }|
+ -- This IE shall be present if the Adjustment Type IE is set to 'Common' or 'Individual'
+ { ID id-AdjustmentRatio CRITICALITY ignore TYPE ScaledAdjustmentRatio PRESENCE conditional },
+ -- This IE shall be present if the Adjustment Type IE is set to 'Common' or 'Individual'
+ ...
+}
+
+DL-PowerControlRequest-Extensions NBAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+DL-ReferencePowerInformationList-DL-PC-Rqst ::= SEQUENCE (SIZE (1..maxNrOfRLs)) OF ProtocolIE-Single-Container {{DL-ReferencePowerInformationItemIE-DL-PC-Rqst }}
+
+DL-ReferencePowerInformationItemIE-DL-PC-Rqst NBAP-PROTOCOL-IES ::= {
+ { ID id-DL-ReferencePowerInformationItem-DL-PC-Rqst CRITICALITY ignore TYPE DL-ReferencePowerInformationItem-DL-PC-Rqst PRESENCE mandatory
+}
+}
+
+DL-ReferencePowerInformationItem-DL-PC-Rqst ::= SEQUENCE {
+ rL-ID RL-ID,
+ dl-ReferencePower DL-Power,
+ iE-Extensions ProtocolExtensionContainer { { DL-ReferencePowerInformationItem-DL-PC-Rqst-ExtIEs } } OPTIONAL,
+ ...
+}
+
+DL-ReferencePowerInformationItem-DL-PC-Rqst-ExtIEs NBAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+-- **************************************************************
+--
+-- DL POWER TIMESLOT CONTROL REQUEST TDD
+--
+-- **************************************************************
+
+DL-PowerTimeslotControlRequest ::= SEQUENCE {
+ protocolIEs ProtocolIE-Container {{DL-PowerTimeslotControlRequest-IEs}},
+ protocolExtensions ProtocolExtensionContainer {{DL-PowerTimeslotControlRequest-Extensions}} OPTIONAL,
+ ...
+}
+
+DL-PowerTimeslotControlRequest-IEs NBAP-PROTOCOL-IES ::= {
+ { ID id-NodeB-CommunicationContextID CRITICALITY ignore TYPE NodeB-CommunicationContextID PRESENCE mandatory } |
+ { ID id-TimeslotISCPInfo CRITICALITY ignore TYPE DL-TimeslotISCPInfo PRESENCE optional },
+ -- Mandatory for 3.84Mcps TDD, Not Applicable to 1.28Mcps TDD
+
+ ...
+}
+
+DL-PowerTimeslotControlRequest-Extensions NBAP-PROTOCOL-EXTENSION ::= {
+ { ID id-TimeslotISCPInfoList-LCR-DL-PC-RqstTDD CRITICALITY ignore EXTENSION DL-TimeslotISCPInfoLCR PRESENCE optional }|
+ -- Mandatory for 1.28Mcps TDD, Not Applicable to 3.84Mcps TDD
+ { ID id-PrimCCPCH-RSCP-DL-PC-RqstTDD CRITICALITY ignore EXTENSION PrimaryCCPCH-RSCP PRESENCE optional }|
+ { ID id-PrimaryCCPCH-RSCP-Delta CRITICALITY ignore EXTENSION PrimaryCCPCH-RSCP-Delta PRESENCE optional },
+ ...
+}
+
+-- **************************************************************
+--
+-- DEDICATED MEASUREMENT INITIATION REQUEST
+--
+-- **************************************************************
+
+DedicatedMeasurementInitiationRequest ::= SEQUENCE {
+ protocolIEs ProtocolIE-Container {{DedicatedMeasurementInitiationRequest-IEs}},
+ protocolExtensions ProtocolExtensionContainer {{DedicatedMeasurementInitiationRequest-Extensions}} OPTIONAL,
+ ...
+}
+
+DedicatedMeasurementInitiationRequest-IEs NBAP-PROTOCOL-IES ::= {
+ { ID id-NodeB-CommunicationContextID CRITICALITY reject TYPE NodeB-CommunicationContextID PRESENCE mandatory } |
+ { ID id-MeasurementID CRITICALITY reject TYPE MeasurementID PRESENCE mandatory } |
+ { ID id-DedicatedMeasurementObjectType-DM-Rqst CRITICALITY reject TYPE DedicatedMeasurementObjectType-DM-Rqst PRESENCE mandatory } |
+ { ID id-DedicatedMeasurementType CRITICALITY reject TYPE DedicatedMeasurementType PRESENCE mandatory } |
+ { ID id-MeasurementFilterCoefficient CRITICALITY reject TYPE MeasurementFilterCoefficient PRESENCE optional } |
+ { ID id-ReportCharacteristics CRITICALITY reject TYPE ReportCharacteristics PRESENCE mandatory } |
+ { ID id-CFNReportingIndicator CRITICALITY reject TYPE FNReportingIndicator PRESENCE mandatory } |
+ { ID id-CFN CRITICALITY reject TYPE CFN PRESENCE optional } ,
+ ...
+}
+
+DedicatedMeasurementInitiationRequest-Extensions NBAP-PROTOCOL-EXTENSION ::= {
+ { ID id-NumberOfReportedCellPortions CRITICALITY reject EXTENSION NumberOfReportedCellPortions PRESENCE conditional },
+ -- The IE shall be present if the Dedicated Measurement Type IE is set to "Best Cell Portions", FDD only.
+ ...
+}
+
+DedicatedMeasurementObjectType-DM-Rqst ::= CHOICE {
+ rL RL-DM-Rqst,
+ rLS RL-Set-DM-Rqst, -- for FDD only
+ all-RL AllRL-DM-Rqst,
+ all-RLS AllRL-Set-DM-Rqst, -- for FDD only
+ ...
+}
+
+RL-DM-Rqst ::= SEQUENCE {
+ rL-InformationList RL-InformationList-DM-Rqst,
+ iE-Extensions ProtocolExtensionContainer { { RLItem-DM-Rqst-ExtIEs } } OPTIONAL,
+ ...
+}
+
+RLItem-DM-Rqst-ExtIEs NBAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+RL-InformationList-DM-Rqst ::= SEQUENCE (SIZE (1..maxNrOfRLs)) OF ProtocolIE-Single-Container {{ RL-InformationItemIE-DM-Rqst }}
+
+RL-InformationItemIE-DM-Rqst NBAP-PROTOCOL-IES ::= {
+ { ID id-RL-InformationItem-DM-Rqst CRITICALITY reject TYPE RL-InformationItem-DM-Rqst PRESENCE mandatory }
+}
+
+RL-InformationItem-DM-Rqst ::= SEQUENCE {
+ rL-ID RL-ID,
+ dPCH-ID DPCH-ID OPTIONAL, -- for TDD only
+ iE-Extensions ProtocolExtensionContainer { { RL-InformationItem-DM-Rqst-ExtIEs } } OPTIONAL,
+ ...
+ }
+
+RL-InformationItem-DM-Rqst-ExtIEs NBAP-PROTOCOL-EXTENSION ::= {
+ { ID id-PUSCH-Info-DM-Rqst CRITICALITY reject EXTENSION PUSCH-Info-DM-Rqst PRESENCE optional}|
+ -- TDD only
+ { ID id-HSSICH-Info-DM-Rqst CRITICALITY reject EXTENSION HSSICH-Info-DM-Rqst PRESENCE optional},
+ -- TDD only
+ ...
+}
+
+PUSCH-Info-DM-Rqst ::= SEQUENCE (SIZE (1..maxNrOfPUSCHs)) OF PUSCH-ID
+
+HSSICH-Info-DM-Rqst ::= SEQUENCE (SIZE (1..maxNrOfHSSICHs)) OF HS-SICH-ID
+
+RL-Set-DM-Rqst ::= SEQUENCE {
+ rL-Set-InformationList-DM-Rqst RL-Set-InformationList-DM-Rqst,
+ iE-Extensions ProtocolExtensionContainer { { RL-SetItem-DM-Rqst-ExtIEs } } OPTIONAL,
+ ...
+}
+
+RL-SetItem-DM-Rqst-ExtIEs NBAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+RL-Set-InformationList-DM-Rqst ::= SEQUENCE (SIZE(1..maxNrOfRLSets)) OF RL-Set-InformationItem-DM-Rqst
+
+RL-Set-InformationItem-DM-Rqst ::= SEQUENCE {
+ rL-Set-ID RL-Set-ID,
+ iE-Extensions ProtocolExtensionContainer { { RL-Set-InformationItem-DM-Rqst-ExtIEs} } OPTIONAL,
+ ...
+}
+
+RL-Set-InformationItem-DM-Rqst-ExtIEs NBAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+AllRL-DM-Rqst ::= NULL
+
+
+AllRL-Set-DM-Rqst ::= NULL
+
+-- **************************************************************
+--
+-- DEDICATED MEASUREMENT INITIATION RESPONSE
+--
+-- **************************************************************
+
+DedicatedMeasurementInitiationResponse ::= SEQUENCE {
+ protocolIEs ProtocolIE-Container {{DedicatedMeasurementInitiationResponse-IEs}},
+ protocolExtensions ProtocolExtensionContainer {{DedicatedMeasurementInitiationResponse-Extensions}} OPTIONAL,
+ ...
+}
+
+DedicatedMeasurementInitiationResponse-IEs NBAP-PROTOCOL-IES ::= {
+ { ID id-CRNC-CommunicationContextID CRITICALITY ignore TYPE CRNC-CommunicationContextID PRESENCE mandatory } |
+ { ID id-MeasurementID CRITICALITY ignore TYPE MeasurementID PRESENCE mandatory } |
+ { ID id-DedicatedMeasurementObjectType-DM-Rsp CRITICALITY ignore TYPE DedicatedMeasurementObjectType-DM-Rsp PRESENCE optional } |
+ { ID id-CriticalityDiagnostics CRITICALITY ignore TYPE CriticalityDiagnostics PRESENCE optional },
+ ...
+}
+
+DedicatedMeasurementInitiationResponse-Extensions NBAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+DedicatedMeasurementObjectType-DM-Rsp ::= CHOICE {
+ rL RL-DM-Rsp,
+ rLS RL-Set-DM-Rsp, -- for FDD only
+ all-RL RL-DM-Rsp,
+ all-RLS RL-Set-DM-Rsp, -- for FDD only
+ ...
+}
+
+RL-DM-Rsp ::= SEQUENCE {
+ rL-InformationList-DM-Rsp RL-InformationList-DM-Rsp,
+ iE-Extensions ProtocolExtensionContainer { { RLItem-DM-Rsp-ExtIEs } } OPTIONAL,
+ ...
+}
+
+RLItem-DM-Rsp-ExtIEs NBAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+RL-InformationList-DM-Rsp ::= SEQUENCE (SIZE (1..maxNrOfRLs)) OF ProtocolIE-Single-Container {{ RL-InformationItemIE-DM-Rsp }}
+
+RL-InformationItemIE-DM-Rsp NBAP-PROTOCOL-IES ::= {
+ { ID id-RL-InformationItem-DM-Rsp CRITICALITY ignore TYPE RL-InformationItem-DM-Rsp PRESENCE mandatory }
+}
+
+RL-InformationItem-DM-Rsp ::= SEQUENCE {
+ rL-ID RL-ID,
+ dPCH-ID DPCH-ID OPTIONAL, -- for TDD only
+ dedicatedMeasurementValue DedicatedMeasurementValue,
+ cFN CFN OPTIONAL,
+ iE-Extensions ProtocolExtensionContainer { { RL-InformationItem-DM-Rsp-ExtIEs } } OPTIONAL,
+ ...
+}
+
+RL-InformationItem-DM-Rsp-ExtIEs NBAP-PROTOCOL-EXTENSION ::= {
+ {ID id-PUSCH-Info-DM-Rsp CRITICALITY reject EXTENSION PUSCH-Info-DM-Rsp PRESENCE optional}|
+ -- TDD only
+ {ID id-HSSICH-Info-DM-Rsp CRITICALITY reject EXTENSION HS-SICH-ID PRESENCE optional},
+ -- TDD only
+ ...
+}
+
+PUSCH-Info-DM-Rsp ::= SEQUENCE (SIZE (1..maxNrOfPUSCHs)) OF PUSCH-ID
+
+RL-Set-DM-Rsp ::= SEQUENCE {
+ rL-Set-InformationList-DM-Rsp RL-Set-InformationList-DM-Rsp,
+ iE-Extensions ProtocolExtensionContainer { { RL-SetItem-DM-Rsp-ExtIEs } } OPTIONAL,
+ ...
+}
+
+RL-SetItem-DM-Rsp-ExtIEs NBAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+RL-Set-InformationList-DM-Rsp ::= SEQUENCE (SIZE (1..maxNrOfRLSets)) OF ProtocolIE-Single-Container {{ RL-Set-InformationItemIE-DM-Rsp }}
+
+RL-Set-InformationItemIE-DM-Rsp NBAP-PROTOCOL-IES ::= {
+ { ID id-RL-Set-InformationItem-DM-Rsp CRITICALITY ignore TYPE RL-Set-InformationItem-DM-Rsp PRESENCE mandatory}
+}
+
+RL-Set-InformationItem-DM-Rsp ::= SEQUENCE {
+ rL-Set-ID RL-Set-ID,
+ dedicatedMeasurementValue DedicatedMeasurementValue,
+ cFN CFN OPTIONAL,
+ iE-Extensions ProtocolExtensionContainer { { RL-Set-InformationItem-DM-Rsp-ExtIEs} } OPTIONAL,
+ ...
+}
+
+RL-Set-InformationItem-DM-Rsp-ExtIEs NBAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+-- **************************************************************
+--
+-- DEDICATED MEASUREMENT INITIATION FAILURE
+--
+-- **************************************************************
+
+DedicatedMeasurementInitiationFailure ::= SEQUENCE {
+ protocolIEs ProtocolIE-Container {{DedicatedMeasurementInitiationFailure-IEs}},
+ protocolExtensions ProtocolExtensionContainer {{DedicatedMeasurementInitiationFailure-Extensions}} OPTIONAL,
+ ...
+}
+
+DedicatedMeasurementInitiationFailure-IEs NBAP-PROTOCOL-IES ::= {
+ { ID id-CRNC-CommunicationContextID CRITICALITY ignore TYPE CRNC-CommunicationContextID PRESENCE mandatory } |
+ { ID id-MeasurementID CRITICALITY ignore TYPE MeasurementID PRESENCE mandatory } |
+ { ID id-Cause CRITICALITY ignore TYPE Cause PRESENCE mandatory } |
+ { ID id-CriticalityDiagnostics CRITICALITY ignore TYPE CriticalityDiagnostics PRESENCE optional },
+ ...
+}
+
+DedicatedMeasurementInitiationFailure-Extensions NBAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+-- **************************************************************
+--
+-- DEDICATED MEASUREMENT REPORT
+--
+-- **************************************************************
+
+DedicatedMeasurementReport ::= SEQUENCE {
+ protocolIEs ProtocolIE-Container {{DedicatedMeasurementReport-IEs}},
+ protocolExtensions ProtocolExtensionContainer {{DedicatedMeasurementReport-Extensions}} OPTIONAL,
+ ...
+}
+
+DedicatedMeasurementReport-IEs NBAP-PROTOCOL-IES ::= {
+ { ID id-CRNC-CommunicationContextID CRITICALITY ignore TYPE CRNC-CommunicationContextID PRESENCE mandatory } |
+ { ID id-MeasurementID CRITICALITY ignore TYPE MeasurementID PRESENCE mandatory } |
+ { ID id-DedicatedMeasurementObjectType-DM-Rprt CRITICALITY ignore TYPE DedicatedMeasurementObjectType-DM-Rprt PRESENCE mandatory } ,
+ ...
+}
+
+DedicatedMeasurementReport-Extensions NBAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+DedicatedMeasurementObjectType-DM-Rprt ::= CHOICE {
+ rL RL-DM-Rprt,
+ rLS RL-Set-DM-Rprt, -- for FDD only
+ all-RL RL-DM-Rprt,
+ all-RLS RL-Set-DM-Rprt, -- for FDD only
+ ...
+}
+
+RL-DM-Rprt ::= SEQUENCE {
+ rL-InformationList-DM-Rprt RL-InformationList-DM-Rprt,
+ iE-Extensions ProtocolExtensionContainer { { RLItem-DM-Rprt-ExtIEs } } OPTIONAL,
+ ...
+}
+
+RLItem-DM-Rprt-ExtIEs NBAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+RL-InformationList-DM-Rprt ::= SEQUENCE (SIZE (1..maxNrOfRLs)) OF ProtocolIE-Single-Container {{ RL-InformationItemIE-DM-Rprt }}
+
+RL-InformationItemIE-DM-Rprt NBAP-PROTOCOL-IES ::= {
+ { ID id-RL-InformationItem-DM-Rprt CRITICALITY ignore TYPE RL-InformationItem-DM-Rprt PRESENCE mandatory }
+}
+
+RL-InformationItem-DM-Rprt ::= SEQUENCE {
+ rL-ID RL-ID,
+ dPCH-ID DPCH-ID OPTIONAL, -- for TDD only
+ dedicatedMeasurementValueInformation DedicatedMeasurementValueInformation,
+ iE-Extensions ProtocolExtensionContainer { { RL-InformationItem-DM-Rprt-ExtIEs } } OPTIONAL,
+ ...
+}
+
+RL-InformationItem-DM-Rprt-ExtIEs NBAP-PROTOCOL-EXTENSION ::= {
+ {ID id-PUSCH-Info-DM-Rprt CRITICALITY reject EXTENSION PUSCH-Info-DM-Rprt PRESENCE optional}|
+ -- TDD only
+ {ID id-HSSICH-Info-DM-Rprt CRITICALITY reject EXTENSION HS-SICH-ID PRESENCE optional},
+ -- TDD only
+ ...
+}
+
+PUSCH-Info-DM-Rprt ::= SEQUENCE (SIZE (0..maxNrOfPUSCHs)) OF PUSCH-ID
+
+RL-Set-DM-Rprt ::= SEQUENCE {
+ rL-Set-InformationList-DM-Rprt RL-Set-InformationList-DM-Rprt,
+ iE-Extensions ProtocolExtensionContainer { { RL-SetItem-DM-Rprt-ExtIEs } } OPTIONAL,
+ ...
+}
+
+RL-SetItem-DM-Rprt-ExtIEs NBAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+RL-Set-InformationList-DM-Rprt ::= SEQUENCE (SIZE (1..maxNrOfRLSets)) OF ProtocolIE-Single-Container {{ RL-Set-InformationItemIE-DM-Rprt }}
+
+RL-Set-InformationItemIE-DM-Rprt NBAP-PROTOCOL-IES ::= {
+ { ID id-RL-Set-InformationItem-DM-Rprt CRITICALITY ignore TYPE RL-Set-InformationItem-DM-Rprt PRESENCE mandatory }
+}
+
+RL-Set-InformationItem-DM-Rprt ::= SEQUENCE {
+ rL-Set-ID RL-Set-ID,
+ dedicatedMeasurementValueInformation DedicatedMeasurementValueInformation,
+ iE-Extensions ProtocolExtensionContainer { { RL-Set-InformationItem-DM-Rprt-ExtIEs} } OPTIONAL,
+ ...
+}
+
+RL-Set-InformationItem-DM-Rprt-ExtIEs NBAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+-- **************************************************************
+--
+-- DEDICATED MEASUREMENT TERMINATION REQUEST
+--
+-- **************************************************************
+
+DedicatedMeasurementTerminationRequest ::= SEQUENCE {
+ protocolIEs ProtocolIE-Container {{DedicatedMeasurementTerminationRequest-IEs}},
+ protocolExtensions ProtocolExtensionContainer {{DedicatedMeasurementTerminationRequest-Extensions}} OPTIONAL,
+ ...
+}
+
+DedicatedMeasurementTerminationRequest-IEs NBAP-PROTOCOL-IES ::= {
+ { ID id-NodeB-CommunicationContextID CRITICALITY ignore TYPE NodeB-CommunicationContextID PRESENCE mandatory } |
+ { ID id-MeasurementID CRITICALITY ignore TYPE MeasurementID PRESENCE mandatory },
+ ...
+}
+
+DedicatedMeasurementTerminationRequest-Extensions NBAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+-- **************************************************************
+--
+-- DEDICATED MEASUREMENT FAILURE INDICATION
+--
+-- **************************************************************
+
+DedicatedMeasurementFailureIndication ::= SEQUENCE {
+ protocolIEs ProtocolIE-Container {{DedicatedMeasurementFailureIndication-IEs}},
+ protocolExtensions ProtocolExtensionContainer {{DedicatedMeasurementFailureIndication-Extensions}} OPTIONAL,
+ ...
+}
+
+DedicatedMeasurementFailureIndication-IEs NBAP-PROTOCOL-IES ::= {
+ { ID id-CRNC-CommunicationContextID CRITICALITY ignore TYPE CRNC-CommunicationContextID PRESENCE mandatory } |
+ { ID id-MeasurementID CRITICALITY ignore TYPE MeasurementID PRESENCE mandatory } |
+ { ID id-Cause CRITICALITY ignore TYPE Cause PRESENCE mandatory },
+ ...
+}
+
+DedicatedMeasurementFailureIndication-Extensions NBAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+-- **************************************************************
+--
+-- RADIO LINK FAILURE INDICATION
+--
+-- **************************************************************
+
+RadioLinkFailureIndication ::= SEQUENCE {
+ protocolIEs ProtocolIE-Container {{RadioLinkFailureIndication-IEs}},
+ protocolExtensions ProtocolExtensionContainer {{RadioLinkFailureIndication-Extensions}} OPTIONAL,
+ ...
+}
+
+RadioLinkFailureIndication-IEs NBAP-PROTOCOL-IES ::= {
+ { ID id-CRNC-CommunicationContextID CRITICALITY ignore TYPE CRNC-CommunicationContextID PRESENCE mandatory } |
+ { ID id-Reporting-Object-RL-FailureInd CRITICALITY ignore TYPE Reporting-Object-RL-FailureInd PRESENCE mandatory } ,
+ ...
+}
+
+RadioLinkFailureIndication-Extensions NBAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+Reporting-Object-RL-FailureInd ::= CHOICE {
+ rL RL-RL-FailureInd,
+ rL-Set RL-Set-RL-FailureInd, --FDD only
+ ...,
+ cCTrCH CCTrCH-RL-FailureInd --TDD only
+}
+
+RL-RL-FailureInd ::= SEQUENCE {
+ rL-InformationList-RL-FailureInd RL-InformationList-RL-FailureInd,
+ iE-Extensions ProtocolExtensionContainer { { RLItem-RL-FailureInd-ExtIEs } } OPTIONAL,
+ ...
+ }
+
+RLItem-RL-FailureInd-ExtIEs NBAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+RL-InformationList-RL-FailureInd ::= SEQUENCE (SIZE (1..maxNrOfRLs)) OF ProtocolIE-Single-Container {{ RL-InformationItemIE-RL-FailureInd}}
+
+RL-InformationItemIE-RL-FailureInd NBAP-PROTOCOL-IES ::= {
+ { ID id-RL-InformationItem-RL-FailureInd CRITICALITY ignore TYPE RL-InformationItem-RL-FailureInd PRESENCE mandatory}
+ }
+
+RL-InformationItem-RL-FailureInd ::= SEQUENCE {
+ rL-ID RL-ID,
+ cause Cause,
+ iE-Extensions ProtocolExtensionContainer { { RL-InformationItem-RL-FailureInd-ExtIEs } } OPTIONAL,
+ ...
+ }
+
+RL-InformationItem-RL-FailureInd-ExtIEs NBAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+RL-Set-RL-FailureInd ::= SEQUENCE {
+ rL-Set-InformationList-RL-FailureInd RL-Set-InformationList-RL-FailureInd,
+ iE-Extensions ProtocolExtensionContainer { { RL-SetItem-RL-FailureInd-ExtIEs } } OPTIONAL,
+ ...
+ }
+
+RL-SetItem-RL-FailureInd-ExtIEs NBAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+RL-Set-InformationList-RL-FailureInd ::= SEQUENCE (SIZE (1..maxNrOfRLSets)) OF ProtocolIE-Single-Container {{ RL-Set-InformationItemIE-RL-FailureInd }}
+
+RL-Set-InformationItemIE-RL-FailureInd NBAP-PROTOCOL-IES ::= {
+ { ID id-RL-Set-InformationItem-RL-FailureInd CRITICALITY ignore TYPE RL-Set-InformationItem-RL-FailureInd PRESENCE mandatory }
+}
+
+RL-Set-InformationItem-RL-FailureInd ::= SEQUENCE {
+ rL-Set-ID RL-Set-ID,
+ cause Cause,
+ iE-Extensions ProtocolExtensionContainer { { RL-Set-InformationItem-RL-FailureInd-ExtIEs} } OPTIONAL,
+ ...
+}
+
+RL-Set-InformationItem-RL-FailureInd-ExtIEs NBAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+CCTrCH-RL-FailureInd ::= SEQUENCE {
+ rL-ID RL-ID,
+ cCTrCH-InformationList-RL-FailureInd CCTrCH-InformationList-RL-FailureInd,
+ iE-Extensions ProtocolExtensionContainer { { CCTrCHItem-RL-FailureInd-ExtIEs } } OPTIONAL,
+ ...
+ }
+
+CCTrCHItem-RL-FailureInd-ExtIEs NBAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+CCTrCH-InformationList-RL-FailureInd ::= SEQUENCE (SIZE (1..maxNrOfCCTrCHs)) OF ProtocolIE-Single-Container {{ CCTrCH-InformationItemIE-RL-FailureInd}}
+
+CCTrCH-InformationItemIE-RL-FailureInd NBAP-PROTOCOL-IES ::= {
+ { ID id-CCTrCH-InformationItem-RL-FailureInd CRITICALITY ignore TYPE CCTrCH-InformationItem-RL-FailureInd PRESENCE mandatory}
+ }
+
+CCTrCH-InformationItem-RL-FailureInd ::= SEQUENCE {
+ cCTrCH-ID CCTrCH-ID,
+ cause Cause,
+ iE-Extensions ProtocolExtensionContainer { { CCTrCH-InformationItem-RL-FailureInd-ExtIEs } } OPTIONAL,
+ ...
+ }
+
+CCTrCH-InformationItem-RL-FailureInd-ExtIEs NBAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+-- **************************************************************
+--
+-- RADIO LINK PREEMPTION REQUIRED INDICATION
+--
+-- **************************************************************
+
+RadioLinkPreemptionRequiredIndication ::= SEQUENCE {
+ protocolIEs ProtocolIE-Container {{RadioLinkPreemptionRequiredIndication-IEs}},
+ protocolExtensions ProtocolExtensionContainer {{RadioLinkPreemptionRequiredIndication-Extensions}} OPTIONAL,
+ ...
+}
+
+RadioLinkPreemptionRequiredIndication-IEs NBAP-PROTOCOL-IES ::= {
+ { ID id-CRNC-CommunicationContextID CRITICALITY ignore TYPE CRNC-CommunicationContextID PRESENCE mandatory } |
+ { ID id-RL-InformationList-RL-PreemptRequiredInd CRITICALITY ignore TYPE RL-InformationList-RL-PreemptRequiredInd PRESENCE optional },
+ ...
+}
+
+RadioLinkPreemptionRequiredIndication-Extensions NBAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+RL-InformationList-RL-PreemptRequiredInd ::= SEQUENCE (SIZE (1..maxNrOfRLs)) OF ProtocolIE-Single-Container { {RL-InformationItemIE-RL-PreemptRequiredInd}}
+
+RL-InformationItemIE-RL-PreemptRequiredInd NBAP-PROTOCOL-IES ::= {
+ { ID id-RL-InformationItem-RL-PreemptRequiredInd CRITICALITY ignore TYPE RL-InformationItem-RL-PreemptRequiredInd PRESENCE mandatory },
+ ...
+}
+
+RL-InformationItem-RL-PreemptRequiredInd::= SEQUENCE {
+ rL-ID RL-ID,
+ iE-Extensions ProtocolExtensionContainer { {RL-InformationItem-RL-PreemptRequiredInd-ExtIEs} } OPTIONAL,
+ ...
+}
+
+RL-InformationItem-RL-PreemptRequiredInd-ExtIEs NBAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+-- **************************************************************
+--
+-- RADIO LINK RESTORE INDICATION
+--
+-- **************************************************************
+
+RadioLinkRestoreIndication ::= SEQUENCE {
+ protocolIEs ProtocolIE-Container {{RadioLinkRestoreIndication-IEs}},
+ protocolExtensions ProtocolExtensionContainer {{RadioLinkRestoreIndication-Extensions}} OPTIONAL,
+ ...
+}
+
+RadioLinkRestoreIndication-IEs NBAP-PROTOCOL-IES ::= {
+ { ID id-CRNC-CommunicationContextID CRITICALITY ignore TYPE CRNC-CommunicationContextID PRESENCE mandatory } |
+ { ID id-Reporting-Object-RL-RestoreInd CRITICALITY ignore TYPE Reporting-Object-RL-RestoreInd PRESENCE mandatory },
+ ...
+}
+
+RadioLinkRestoreIndication-Extensions NBAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+Reporting-Object-RL-RestoreInd ::= CHOICE {
+ rL RL-RL-RestoreInd, --TDD only
+ rL-Set RL-Set-RL-RestoreInd, --FDD only
+ ...,
+ cCTrCH CCTrCH-RL-RestoreInd --TDD only
+}
+
+RL-RL-RestoreInd ::= SEQUENCE {
+ rL-InformationList-RL-RestoreInd RL-InformationList-RL-RestoreInd,
+ iE-Extensions ProtocolExtensionContainer { { RLItem-RL-RestoreInd-ExtIEs } } OPTIONAL,
+ ...
+ }
+
+RLItem-RL-RestoreInd-ExtIEs NBAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+RL-InformationList-RL-RestoreInd ::= SEQUENCE (SIZE (1..maxNrOfRLs)) OF ProtocolIE-Single-Container {{RL-InformationItemIE-RL-RestoreInd}}
+
+RL-InformationItemIE-RL-RestoreInd NBAP-PROTOCOL-IES ::= {
+ { ID id-RL-InformationItem-RL-RestoreInd CRITICALITY ignore TYPE RL-InformationItem-RL-RestoreInd PRESENCE mandatory}
+ }
+
+RL-InformationItem-RL-RestoreInd ::= SEQUENCE {
+ rL-ID RL-ID,
+ iE-Extensions ProtocolExtensionContainer { { RL-InformationItem-RL-RestoreInd-ExtIEs } } OPTIONAL,
+ ...
+ }
+
+RL-InformationItem-RL-RestoreInd-ExtIEs NBAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+RL-Set-RL-RestoreInd ::= SEQUENCE {
+ rL-Set-InformationList-RL-RestoreInd RL-Set-InformationList-RL-RestoreInd,
+ iE-Extensions ProtocolExtensionContainer { { RL-SetItem-RL-RestoreInd-ExtIEs } } OPTIONAL,
+ ...
+ }
+
+RL-SetItem-RL-RestoreInd-ExtIEs NBAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+RL-Set-InformationList-RL-RestoreInd ::= SEQUENCE (SIZE (1..maxNrOfRLSets)) OF ProtocolIE-Single-Container {{ RL-Set-InformationItemIE-RL-RestoreInd }}
+
+RL-Set-InformationItemIE-RL-RestoreInd NBAP-PROTOCOL-IES ::= {
+ { ID id-RL-Set-InformationItem-RL-RestoreInd CRITICALITY ignore TYPE RL-Set-InformationItem-RL-RestoreInd PRESENCE mandatory }
+ }
+
+RL-Set-InformationItem-RL-RestoreInd ::= SEQUENCE {
+ rL-Set-ID RL-Set-ID,
+ iE-Extensions ProtocolExtensionContainer { { RL-Set-InformationItem-RL-RestoreInd-ExtIEs} } OPTIONAL,
+ ...
+}
+
+RL-Set-InformationItem-RL-RestoreInd-ExtIEs NBAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+CCTrCH-RL-RestoreInd ::= SEQUENCE {
+ rL-ID RL-ID,
+ cCTrCH-InformationList-RL-RestoreInd CCTrCH-InformationList-RL-RestoreInd,
+ iE-Extensions ProtocolExtensionContainer { { CCTrCHItem-RL-RestoreInd-ExtIEs } } OPTIONAL,
+ ...
+ }
+
+CCTrCHItem-RL-RestoreInd-ExtIEs NBAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+CCTrCH-InformationList-RL-RestoreInd ::= SEQUENCE (SIZE (1..maxNrOfCCTrCHs)) OF ProtocolIE-Single-Container {{ CCTrCH-InformationItemIE-RL-RestoreInd}}
+
+CCTrCH-InformationItemIE-RL-RestoreInd NBAP-PROTOCOL-IES ::= {
+ { ID id-CCTrCH-InformationItem-RL-RestoreInd CRITICALITY ignore TYPE CCTrCH-InformationItem-RL-RestoreInd PRESENCE mandatory }
+ }
+
+CCTrCH-InformationItem-RL-RestoreInd ::= SEQUENCE {
+ cCTrCH-ID CCTrCH-ID,
+ iE-Extensions ProtocolExtensionContainer { { CCTrCH-InformationItem-RL-RestoreInd-ExtIEs } } OPTIONAL,
+ ...
+ }
+
+CCTrCH-InformationItem-RL-RestoreInd-ExtIEs NBAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+-- **************************************************************
+--
+-- COMPRESSED MODE COMMAND FDD
+--
+-- **************************************************************
+
+CompressedModeCommand ::= SEQUENCE {
+ protocolIEs ProtocolIE-Container {{CompressedModeCommand-IEs}},
+ protocolExtensions ProtocolExtensionContainer {{CompressedModeCommand-Extensions}} OPTIONAL,
+ ...
+}
+
+CompressedModeCommand-IEs NBAP-PROTOCOL-IES ::= {
+ { ID id-NodeB-CommunicationContextID CRITICALITY ignore TYPE NodeB-CommunicationContextID PRESENCE mandatory } |
+ { ID id-Active-Pattern-Sequence-Information CRITICALITY ignore TYPE Active-Pattern-Sequence-Information PRESENCE mandatory },
+ ...
+}
+
+CompressedModeCommand-Extensions NBAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+
+-- **************************************************************
+--
+-- ERROR INDICATION
+--
+-- **************************************************************
+
+ErrorIndication ::= SEQUENCE {
+ protocolIEs ProtocolIE-Container {{ErrorIndication-IEs}},
+ protocolExtensions ProtocolExtensionContainer {{ErrorIndication-Extensions}} OPTIONAL,
+ ...
+}
+
+ErrorIndication-IEs NBAP-PROTOCOL-IES ::= {
+ { ID id-CRNC-CommunicationContextID CRITICALITY ignore TYPE CRNC-CommunicationContextID PRESENCE optional } |
+ { ID id-NodeB-CommunicationContextID CRITICALITY ignore TYPE NodeB-CommunicationContextID PRESENCE optional } |
+ { ID id-Cause CRITICALITY ignore TYPE Cause PRESENCE optional } |
+ { ID id-CriticalityDiagnostics CRITICALITY ignore TYPE CriticalityDiagnostics PRESENCE optional },
+ ...
+}
+
+ErrorIndication-Extensions NBAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+-- **************************************************************
+--
+-- PRIVATE MESSAGE
+--
+-- **************************************************************
+
+PrivateMessage ::= SEQUENCE {
+ privateIEs PrivateIE-Container {{PrivateMessage-IEs}},
+ ...
+}
+
+PrivateMessage-IEs NBAP-PRIVATE-IES ::= {
+ ...
+}
+
+-- **************************************************************
+--
+-- PHYSICAL SHARED CHANNEL RECONFIGURATION REQUEST FDD
+--
+-- **************************************************************
+
+PhysicalSharedChannelReconfigurationRequestFDD ::= SEQUENCE {
+ protocolIEs ProtocolIE-Container {{PhysicalSharedChannelReconfigurationRequestFDD-IEs}},
+ protocolExtensions ProtocolExtensionContainer {{PhysicalSharedChannelReconfigurationRequestFDD-Extensions}} OPTIONAL,
+ ...
+}
+
+PhysicalSharedChannelReconfigurationRequestFDD-IEs NBAP-PROTOCOL-IES ::= {
+ { ID id-C-ID CRITICALITY reject TYPE C-ID PRESENCE mandatory }|
+ { ID id-ConfigurationGenerationID CRITICALITY reject TYPE ConfigurationGenerationID PRESENCE mandatory }|
+ { ID id-SFN CRITICALITY reject TYPE SFN PRESENCE optional }|
+ { ID id-HS-PDSCH-HS-SCCH-MaxPower-PSCH-ReconfRqst CRITICALITY reject TYPE MaximumTransmissionPower PRESENCE optional }|
+ { ID id-HS-PDSCH-HS-SCCH-ScramblingCode-PSCH-ReconfRqst CRITICALITY reject TYPE DL-ScramblingCode PRESENCE optional }|
+ { ID id-HS-PDSCH-FDD-Code-Information-PSCH-ReconfRqst CRITICALITY reject TYPE HS-PDSCH-FDD-Code-Information PRESENCE optional }|
+ { ID id-HS-SCCH-FDD-Code-Information-PSCH-ReconfRqst CRITICALITY reject TYPE HS-SCCH-FDD-Code-Information PRESENCE optional },
+ ...
+}
+
+PhysicalSharedChannelReconfigurationRequestFDD-Extensions NBAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+-- **************************************************************
+--
+-- PHYSICAL SHARED CHANNEL RECONFIGURATION REQUEST TDD
+--
+-- **************************************************************
+
+PhysicalSharedChannelReconfigurationRequestTDD ::= SEQUENCE {
+ protocolIEs ProtocolIE-Container {{PhysicalSharedChannelReconfigurationRequestTDD-IEs}},
+ protocolExtensions ProtocolExtensionContainer {{PhysicalSharedChannelReconfigurationRequestTDD-Extensions}} OPTIONAL,
+ ...
+}
+
+PhysicalSharedChannelReconfigurationRequestTDD-IEs NBAP-PROTOCOL-IES ::= {
+ { ID id-C-ID CRITICALITY reject TYPE C-ID PRESENCE mandatory }|
+ { ID id-SFN CRITICALITY reject TYPE SFN PRESENCE optional }|
+ { ID id-PDSCHSets-AddList-PSCH-ReconfRqst CRITICALITY reject TYPE PDSCHSets-AddList-PSCH-ReconfRqst PRESENCE optional }|
+ { ID id-PDSCHSets-ModifyList-PSCH-ReconfRqst CRITICALITY reject TYPE PDSCHSets-ModifyList-PSCH-ReconfRqst PRESENCE optional }|
+ { ID id-PDSCHSets-DeleteList-PSCH-ReconfRqst CRITICALITY reject TYPE PDSCHSets-DeleteList-PSCH-ReconfRqst PRESENCE optional }|
+ { ID id-PUSCHSets-AddList-PSCH-ReconfRqst CRITICALITY reject TYPE PUSCHSets-AddList-PSCH-ReconfRqst PRESENCE optional }|
+ { ID id-PUSCHSets-ModifyList-PSCH-ReconfRqst CRITICALITY reject TYPE PUSCHSets-ModifyList-PSCH-ReconfRqst PRESENCE optional }|
+ { ID id-PUSCHSets-DeleteList-PSCH-ReconfRqst CRITICALITY reject TYPE PUSCHSets-DeleteList-PSCH-ReconfRqst PRESENCE optional },
+ ...
+}
+
+PhysicalSharedChannelReconfigurationRequestTDD-Extensions NBAP-PROTOCOL-EXTENSION ::= {
+ { ID id-HS-PDSCH-TDD-Information-PSCH-ReconfRqst CRITICALITY reject EXTENSION HS-PDSCH-TDD-Information-PSCH-ReconfRqst PRESENCE optional } |
+ { ID id-Add-To-HS-SCCH-Resource-Pool-PSCH-ReconfRqst CRITICALITY reject EXTENSION Add-To-HS-SCCH-Resource-Pool-PSCH-ReconfRqst PRESENCE optional } |
+ { ID id-Modify-HS-SCCH-Resource-Pool-PSCH-ReconfRqst CRITICALITY reject EXTENSION Modify-HS-SCCH-Resource-Pool-PSCH-ReconfRqst PRESENCE optional } |
+ { ID id-Delete-From-HS-SCCH-Resource-Pool-PSCH-ReconfRqst CRITICALITY reject EXTENSION Delete-From-HS-SCCH-Resource-Pool-PSCH-ReconfRqst PRESENCE optional } |
+ { ID id-ConfigurationGenerationID CRITICALITY reject EXTENSION ConfigurationGenerationID PRESENCE optional },
+ ...
+}
+
+PDSCHSets-AddList-PSCH-ReconfRqst ::= SEQUENCE (SIZE (1..maxNrOfPDSCHSets)) OF PDSCHSets-AddItem-PSCH-ReconfRqst
+
+PDSCHSets-AddItem-PSCH-ReconfRqst ::= SEQUENCE {
+ pDSCHSet-ID PDSCHSet-ID,
+ pDSCH-InformationList PDSCH-Information-AddList-PSCH-ReconfRqst OPTIONAL, -- Mandatory for 3.84Mcps TDD. Not Applicable to 1.28Mcps TDD
+ iE-Extensions ProtocolExtensionContainer { {PDSCHSets-AddItem-PSCH-ReconfRqst-ExtIEs} } OPTIONAL,
+ ...
+}
+
+PDSCHSets-AddItem-PSCH-ReconfRqst-ExtIEs NBAP-PROTOCOL-EXTENSION ::= {
+ {ID id-PDSCH-AddInformation-LCR-PSCH-ReconfRqst CRITICALITY reject EXTENSION PDSCH-AddInformation-LCR-AddItem-PSCH-ReconfRqst PRESENCE optional}, -- Mandatory for 1.28Mcps TDD. Not Applicable to 3.84Mcps TDD
+ ...
+}
+
+PDSCH-Information-AddList-PSCH-ReconfRqst ::= ProtocolIE-Single-Container {{ PDSCH-Information-AddListIEs-PSCH-ReconfRqst }}
+-- Mandatory for 3.84Mcps TDD, Not Applicable to 1.28Mcps TDD
+
+PDSCH-Information-AddListIEs-PSCH-ReconfRqst NBAP-PROTOCOL-IES ::= {
+ {ID id-PDSCH-Information-AddListIE-PSCH-ReconfRqst CRITICALITY reject TYPE PDSCH-Information-AddItem-PSCH-ReconfRqst PRESENCE mandatory}
+}
+
+PDSCH-Information-AddItem-PSCH-ReconfRqst ::= SEQUENCE {
+ repetitionPeriod RepetitionPeriod,
+ repetitionLength RepetitionLength,
+ tdd-PhysicalChannelOffset TDD-PhysicalChannelOffset,
+ dL-Timeslot-InformationAddList-PSCH-ReconfRqst DL-Timeslot-InformationAddList-PSCH-ReconfRqst,
+ iE-Extensions ProtocolExtensionContainer { {PDSCH-Information-AddItem-PSCH-ReconfRqst-ExtIEs} } OPTIONAL,
+ ...
+ }
+
+PDSCH-Information-AddItem-PSCH-ReconfRqst-ExtIEs NBAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+DL-Timeslot-InformationAddList-PSCH-ReconfRqst ::= SEQUENCE (SIZE (1.. maxNrOfDLTSs)) OF DL-Timeslot-InformationAddItem-PSCH-ReconfRqst
+
+DL-Timeslot-InformationAddItem-PSCH-ReconfRqst ::= SEQUENCE {
+ timeSlot TimeSlot,
+ midambleShiftAndBurstType MidambleShiftAndBurstType,
+ tFCI-Presence TFCI-Presence,
+ dL-Code-InformationAddList-PSCH-ReconfRqst DL-Code-InformationAddList-PSCH-ReconfRqst,
+ iE-Extensions ProtocolExtensionContainer { { DL-Timeslot-InformationAddItem-PSCH-ReconfRqst-ExtIEs} } OPTIONAL,
+ ...
+}
+
+DL-Timeslot-InformationAddItem-PSCH-ReconfRqst-ExtIEs NBAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+DL-Code-InformationAddList-PSCH-ReconfRqst ::= SEQUENCE (SIZE (1..maxNrOfPDSCHs)) OF DL-Code-InformationAddItem-PSCH-ReconfRqst
+
+DL-Code-InformationAddItem-PSCH-ReconfRqst ::= SEQUENCE {
+ pDSCH-ID PDSCH-ID,
+ tdd-ChannelisationCode TDD-ChannelisationCode,
+ iE-Extensions ProtocolExtensionContainer { { DL-Code-InformationAddItem-PSCH-ReconfRqst-ExtIEs} } OPTIONAL,
+ ...
+}
+
+DL-Code-InformationAddItem-PSCH-ReconfRqst-ExtIEs NBAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+PDSCH-AddInformation-LCR-AddItem-PSCH-ReconfRqst ::= SEQUENCE {
+ repetitionPeriod RepetitionPeriod,
+ repetitionLength RepetitionLength,
+ tdd-PhysicalChannelOffset TDD-PhysicalChannelOffset,
+ dL-Timeslot-InformationAddList-LCR-PSCH-ReconfRqst DL-Timeslot-InformationAddList-LCR-PSCH-ReconfRqst,
+ iE-Extensions ProtocolExtensionContainer { {PDSCH-AddInformation-LCR-AddItem-PSCH-ReconfRqst-ExtIEs} } OPTIONAL,
+ ...
+ }
+
+PDSCH-AddInformation-LCR-AddItem-PSCH-ReconfRqst-ExtIEs NBAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+DL-Timeslot-InformationAddList-LCR-PSCH-ReconfRqst ::= SEQUENCE (SIZE (1.. maxNrOfDLTSLCRs)) OF DL-Timeslot-InformationAddItem-LCR-PSCH-ReconfRqst
+
+DL-Timeslot-InformationAddItem-LCR-PSCH-ReconfRqst ::= SEQUENCE {
+ timeSlotLCR TimeSlotLCR,
+ midambleShiftLCR MidambleShiftLCR,
+ tFCI-Presence TFCI-Presence,
+ dL-Code-InformationAddList-LCR-PSCH-ReconfRqst DL-Code-InformationAddList-LCR-PSCH-ReconfRqst,
+ iE-Extensions ProtocolExtensionContainer { { DL-Timeslot-InformationAddItem-LCR-PSCH-ReconfRqst-ExtIEs} } OPTIONAL,
+ ...
+}
+
+DL-Timeslot-InformationAddItem-LCR-PSCH-ReconfRqst-ExtIEs NBAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+DL-Code-InformationAddList-LCR-PSCH-ReconfRqst ::= SEQUENCE (SIZE (1..maxNrOfPDSCHs)) OF DL-Code-InformationAddItem-LCR-PSCH-ReconfRqst
+
+DL-Code-InformationAddItem-LCR-PSCH-ReconfRqst ::= SEQUENCE {
+ pDSCH-ID PDSCH-ID,
+ tdd-ChannelisationCodeLCR TDD-ChannelisationCodeLCR,
+ iE-Extensions ProtocolExtensionContainer { { DL-Code-InformationAddItem-LCR-PSCH-ReconfRqst-ExtIEs} } OPTIONAL,
+ ...
+}
+
+DL-Code-InformationAddItem-LCR-PSCH-ReconfRqst-ExtIEs NBAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+PDSCHSets-ModifyList-PSCH-ReconfRqst ::= SEQUENCE (SIZE (1..maxNrOfPDSCHSets)) OF PDSCHSets-ModifyItem-PSCH-ReconfRqst
+
+PDSCHSets-ModifyItem-PSCH-ReconfRqst ::= SEQUENCE {
+ pDSCHSet-ID PDSCHSet-ID,
+ pDSCH-InformationList PDSCH-Information-ModifyList-PSCH-ReconfRqst,
+ iE-Extensions ProtocolExtensionContainer { {PDSCHSets-ModifyItem-PSCH-ReconfRqst-ExtIEs} } OPTIONAL,
+ ...
+}
+
+PDSCHSets-ModifyItem-PSCH-ReconfRqst-ExtIEs NBAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+PDSCH-Information-ModifyList-PSCH-ReconfRqst ::= ProtocolIE-Single-Container {{ PDSCH-Information-ModifyListIEs-PSCH-ReconfRqst }}
+
+PDSCH-Information-ModifyListIEs-PSCH-ReconfRqst NBAP-PROTOCOL-IES ::= {
+ {ID id-PDSCH-Information-ModifyListIE-PSCH-ReconfRqst CRITICALITY reject TYPE PDSCH-Information-ModifyItem-PSCH-ReconfRqst PRESENCE optional}|
+ {ID id-PDSCH-ModifyInformation-LCR-PSCH-ReconfRqst CRITICALITY reject TYPE PDSCH-ModifyInformation-LCR-ModifyItem-PSCH-ReconfRqst PRESENCE optional}
+
+}
+
+PDSCH-Information-ModifyItem-PSCH-ReconfRqst ::= SEQUENCE {
+ repetitionPeriod RepetitionPeriod OPTIONAL,
+ repetitionLength RepetitionLength OPTIONAL,
+ tdd-PhysicalChannelOffset TDD-PhysicalChannelOffset OPTIONAL,
+ dL-Timeslot-InformationModifyList-PSCH-ReconfRqst DL-Timeslot-InformationModifyList-PSCH-ReconfRqst OPTIONAL,
+ iE-Extensions ProtocolExtensionContainer { {PDSCH-Information-ModifyItem-PSCH-ReconfRqst-ExtIEs} } OPTIONAL,
+ ...
+ }
+
+PDSCH-Information-ModifyItem-PSCH-ReconfRqst-ExtIEs NBAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+DL-Timeslot-InformationModifyList-PSCH-ReconfRqst ::= SEQUENCE (SIZE (1.. maxNrOfDLTSs)) OF DL-Timeslot-InformationModifyItem-PSCH-ReconfRqst
+
+DL-Timeslot-InformationModifyItem-PSCH-ReconfRqst ::= SEQUENCE {
+ timeSlot TimeSlot,
+ midambleShiftAndBurstType MidambleShiftAndBurstType OPTIONAL,
+ tFCI-Presence TFCI-Presence OPTIONAL,
+ dL-Code-InformationModifyList-PSCH-ReconfRqst DL-Code-InformationModifyList-PSCH-ReconfRqst OPTIONAL,
+ iE-Extensions ProtocolExtensionContainer { { DL-Timeslot-InformationModifyItem-PSCH-ReconfRqst-ExtIEs} } OPTIONAL,
+ ...
+}
+
+DL-Timeslot-InformationModifyItem-PSCH-ReconfRqst-ExtIEs NBAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+DL-Code-InformationModifyList-PSCH-ReconfRqst ::= SEQUENCE (SIZE (1..maxNrOfPDSCHs)) OF DL-Code-InformationModifyItem-PSCH-ReconfRqst
+
+DL-Code-InformationModifyItem-PSCH-ReconfRqst ::= SEQUENCE {
+ pDSCH-ID PDSCH-ID,
+ tdd-ChannelisationCode TDD-ChannelisationCode,
+ iE-Extensions ProtocolExtensionContainer { { DL-Code-InformationModifyItem-PSCH-ReconfRqst-ExtIEs} } OPTIONAL,
+ ...
+}
+
+DL-Code-InformationModifyItem-PSCH-ReconfRqst-ExtIEs NBAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+PDSCH-ModifyInformation-LCR-ModifyItem-PSCH-ReconfRqst ::= SEQUENCE {
+ repetitionPeriod RepetitionPeriod OPTIONAL,
+ repetitionLength RepetitionLength OPTIONAL,
+ tdd-PhysicalChannelOffset TDD-PhysicalChannelOffset OPTIONAL,
+ dL-Timeslot-LCR-InformationModifyList-PSCH-ReconfRqst DL-Timeslot-LCR-InformationModifyList-PSCH-ReconfRqst OPTIONAL,
+ iE-Extensions ProtocolExtensionContainer { {PDSCH-ModifyInformation-LCR-ModifyListIE-PSCH-ReconfRqst-ExtIEs} } OPTIONAL,
+ ...
+ }
+
+PDSCH-ModifyInformation-LCR-ModifyListIE-PSCH-ReconfRqst-ExtIEs NBAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+DL-Timeslot-LCR-InformationModifyList-PSCH-ReconfRqst ::= SEQUENCE (SIZE (1.. maxNrOfDLTSLCRs)) OF DL-Timeslot-LCR-InformationModifyItem-PSCH-ReconfRqst
+
+DL-Timeslot-LCR-InformationModifyItem-PSCH-ReconfRqst ::= SEQUENCE {
+ timeSlotLCR TimeSlotLCR,
+ midambleShiftLCR MidambleShiftLCR OPTIONAL,
+ tFCI-Presence TFCI-Presence OPTIONAL,
+ dL-Code-LCR-InformationModifyList-PSCH-ReconfRqst DL-Code-LCR-InformationModifyList-PSCH-ReconfRqst OPTIONAL,
+ iE-Extensions ProtocolExtensionContainer { { DL-Timeslot-LCR-InformationModifyItem-PSCH-ReconfRqst-ExtIEs} } OPTIONAL,
+ ...
+}
+
+DL-Timeslot-LCR-InformationModifyItem-PSCH-ReconfRqst-ExtIEs NBAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+DL-Code-LCR-InformationModifyList-PSCH-ReconfRqst ::= SEQUENCE (SIZE (1..maxNrOfPDSCHs)) OF DL-Code-LCR-InformationModifyItem-PSCH-ReconfRqst
+
+DL-Code-LCR-InformationModifyItem-PSCH-ReconfRqst ::= SEQUENCE {
+ pDSCH-ID PDSCH-ID,
+ tdd-ChannelisationCodeLCR TDD-ChannelisationCodeLCR,
+ iE-Extensions ProtocolExtensionContainer { { DL-Code-LCR-InformationModifyItem-PSCH-ReconfRqst-ExtIEs} } OPTIONAL,
+ ...
+}
+
+DL-Code-LCR-InformationModifyItem-PSCH-ReconfRqst-ExtIEs NBAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+PDSCHSets-DeleteList-PSCH-ReconfRqst ::= SEQUENCE (SIZE (1..maxNrOfPDSCHSets)) OF PDSCHSets-DeleteItem-PSCH-ReconfRqst
+
+PDSCHSets-DeleteItem-PSCH-ReconfRqst ::= SEQUENCE {
+ pDSCHSet-ID PDSCHSet-ID,
+ iE-Extensions ProtocolExtensionContainer { {PDSCHSets-DeleteItem-PSCH-ReconfRqst-ExtIEs} } OPTIONAL,
+ ...
+}
+
+PDSCHSets-DeleteItem-PSCH-ReconfRqst-ExtIEs NBAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+PUSCHSets-AddList-PSCH-ReconfRqst ::= SEQUENCE (SIZE (1..maxNrOfPUSCHSets)) OF PUSCHSets-AddItem-PSCH-ReconfRqst
+
+PUSCHSets-AddItem-PSCH-ReconfRqst ::= SEQUENCE {
+ pUSCHSet-ID PUSCHSet-ID,
+ pUSCH-InformationList PUSCH-Information-AddList-PSCH-ReconfRqst OPTIONAL,
+ -- Mandatory for 3.84Mcps TDD, Not Applicable to 1.28Mcps TDD
+ iE-Extensions ProtocolExtensionContainer { {PUSCHSets-AddItem-PSCH-ReconfRqst-ExtIEs} } OPTIONAL,
+ ...
+}
+
+PUSCHSets-AddItem-PSCH-ReconfRqst-ExtIEs NBAP-PROTOCOL-EXTENSION ::= {
+ {ID id-PUSCH-AddInformation-LCR-PSCH-ReconfRqst CRITICALITY reject EXTENSION PUSCH-AddInformation-LCR-AddItem-PSCH-ReconfRqst PRESENCE optional}, -- Mandatory for 1.28Mcps TDD, Not Applicable to 3.84Mcps TDD
+ ...
+}
+
+PUSCH-Information-AddList-PSCH-ReconfRqst ::= ProtocolIE-Single-Container {{ PUSCH-Information-AddListIEs-PSCH-ReconfRqst }}
+
+PUSCH-Information-AddListIEs-PSCH-ReconfRqst NBAP-PROTOCOL-IES ::= {
+ {ID id-PUSCH-Information-AddListIE-PSCH-ReconfRqst CRITICALITY reject TYPE PUSCH-Information-AddItem-PSCH-ReconfRqst PRESENCE mandatory}
+}
+
+PUSCH-Information-AddItem-PSCH-ReconfRqst ::= SEQUENCE {
+ repetitionPeriod RepetitionPeriod,
+ repetitionLength RepetitionLength,
+ tdd-PhysicalChannelOffset TDD-PhysicalChannelOffset,
+ uL-Timeslot-InformationAddList-PSCH-ReconfRqst UL-Timeslot-InformationAddList-PSCH-ReconfRqst,
+ iE-Extensions ProtocolExtensionContainer { {PUSCH-Information-AddItem-PSCH-ReconfRqst-ExtIEs} } OPTIONAL,
+ ...
+ }
+
+PUSCH-Information-AddItem-PSCH-ReconfRqst-ExtIEs NBAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+UL-Timeslot-InformationAddList-PSCH-ReconfRqst ::= SEQUENCE (SIZE (1..maxNrOfULTSs)) OF UL-Timeslot-InformationAddItem-PSCH-ReconfRqst
+
+UL-Timeslot-InformationAddItem-PSCH-ReconfRqst ::= SEQUENCE {
+ timeSlot TimeSlot,
+ midambleShiftAndBurstType MidambleShiftAndBurstType,
+ tFCI-Presence TFCI-Presence,
+ uL-Code-InformationAddList-PSCH-ReconfRqst UL-Code-InformationAddList-PSCH-ReconfRqst,
+ iE-Extensions ProtocolExtensionContainer { { UL-Timeslot-InformationAddItem-PSCH-ReconfRqst-ExtIEs} } OPTIONAL,
+ ...
+}
+
+UL-Timeslot-InformationAddItem-PSCH-ReconfRqst-ExtIEs NBAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+UL-Code-InformationAddList-PSCH-ReconfRqst ::= SEQUENCE (SIZE (1..maxNrOfPUSCHs)) OF UL-Code-InformationAddItem-PSCH-ReconfRqst
+
+UL-Code-InformationAddItem-PSCH-ReconfRqst ::= SEQUENCE {
+ pUSCH-ID PUSCH-ID,
+ tdd-ChannelisationCode TDD-ChannelisationCode,
+ iE-Extensions ProtocolExtensionContainer { { UL-Code-InformationAddItem-PSCH-ReconfRqst-ExtIEs} } OPTIONAL,
+ ...
+}
+
+UL-Code-InformationAddItem-PSCH-ReconfRqst-ExtIEs NBAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+PUSCH-AddInformation-LCR-AddItem-PSCH-ReconfRqst ::= SEQUENCE {
+ repetitionPeriod RepetitionPeriod,
+ repetitionLength RepetitionLength,
+ tdd-PhysicalChannelOffset TDD-PhysicalChannelOffset,
+ uL-Timeslot-InformationAddList-LCR-PSCH-ReconfRqst UL-Timeslot-InformationAddList-LCR-PSCH-ReconfRqst,
+ iE-Extensions ProtocolExtensionContainer { {PUSCH-AddInformation-LCR-AddItem-PSCH-ReconfRqst-ExtIEs} } OPTIONAL,
+ ...
+ }
+
+PUSCH-AddInformation-LCR-AddItem-PSCH-ReconfRqst-ExtIEs NBAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+UL-Timeslot-InformationAddList-LCR-PSCH-ReconfRqst ::= SEQUENCE (SIZE (1.. maxNrOfULTSLCRs)) OF UL-Timeslot-InformationAddItem-LCR-PSCH-ReconfRqst
+
+UL-Timeslot-InformationAddItem-LCR-PSCH-ReconfRqst ::= SEQUENCE {
+ timeSlotLCR TimeSlotLCR,
+ midambleShiftLCR MidambleShiftLCR,
+ tFCI-Presence TFCI-Presence,
+ uL-Code-InformationAddList-LCR-PSCH-ReconfRqst UL-Code-InformationAddList-LCR-PSCH-ReconfRqst,
+ iE-Extensions ProtocolExtensionContainer { { UL-Timeslot-InformationAddItem-LCR-PSCH-ReconfRqst-ExtIEs} } OPTIONAL,
+ ...
+}
+
+UL-Timeslot-InformationAddItem-LCR-PSCH-ReconfRqst-ExtIEs NBAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+UL-Code-InformationAddList-LCR-PSCH-ReconfRqst ::= SEQUENCE (SIZE (1..maxNrOfPUSCHs)) OF UL-Code-InformationAddItem-LCR-PSCH-ReconfRqst
+
+UL-Code-InformationAddItem-LCR-PSCH-ReconfRqst ::= SEQUENCE {
+ pUSCH-ID PUSCH-ID,
+ tdd-ChannelisationCodeLCR TDD-ChannelisationCodeLCR,
+ iE-Extensions ProtocolExtensionContainer { { UL-Code-InformationAddItem-LCR-PSCH-ReconfRqst-ExtIEs} } OPTIONAL,
+ ...
+}
+
+UL-Code-InformationAddItem-LCR-PSCH-ReconfRqst-ExtIEs NBAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+PUSCHSets-ModifyList-PSCH-ReconfRqst ::= SEQUENCE (SIZE (1..maxNrOfPUSCHSets)) OF PUSCHSets-ModifyItem-PSCH-ReconfRqst
+
+PUSCHSets-ModifyItem-PSCH-ReconfRqst ::= SEQUENCE {
+ pUSCHSet-ID PUSCHSet-ID,
+ pUSCH-InformationList PUSCH-Information-ModifyList-PSCH-ReconfRqst,
+ iE-Extensions ProtocolExtensionContainer { {PUSCHSets-ModifyItem-PSCH-ReconfRqst-ExtIEs} } OPTIONAL,
+ ...
+}
+
+PUSCHSets-ModifyItem-PSCH-ReconfRqst-ExtIEs NBAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+PUSCH-Information-ModifyList-PSCH-ReconfRqst ::= ProtocolIE-Single-Container {{ PUSCH-Information-ModifyListIEs-PSCH-ReconfRqst }}
+
+PUSCH-Information-ModifyListIEs-PSCH-ReconfRqst NBAP-PROTOCOL-IES ::= {
+ {ID id-PUSCH-Information-ModifyListIE-PSCH-ReconfRqst CRITICALITY reject TYPE PUSCH-Information-ModifyItem-PSCH-ReconfRqst PRESENCE optional}|
+ {ID id-PUSCH-ModifyInformation-LCR-PSCH-ReconfRqst CRITICALITY reject TYPE PUSCH-ModifyInformation-LCR-ModifyItem-PSCH-ReconfRqst PRESENCE optional}
+}
+
+PUSCH-Information-ModifyItem-PSCH-ReconfRqst ::= SEQUENCE {
+ repetitionPeriod RepetitionPeriod OPTIONAL,
+ repetitionLength RepetitionLength OPTIONAL,
+ tdd-PhysicalChannelOffset TDD-PhysicalChannelOffset OPTIONAL,
+ uL-Timeslot-InformationModifyList-PSCH-ReconfRqst UL-Timeslot-InformationModifyList-PSCH-ReconfRqst OPTIONAL,
+ iE-Extensions ProtocolExtensionContainer { {PUSCH-Information-ModifyItem-PSCH-ReconfRqst-ExtIEs} } OPTIONAL,
+ ...
+ }
+
+PUSCH-Information-ModifyItem-PSCH-ReconfRqst-ExtIEs NBAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+UL-Timeslot-InformationModifyList-PSCH-ReconfRqst ::= SEQUENCE (SIZE (1..maxNrOfULTSs)) OF UL-Timeslot-InformationModifyItem-PSCH-ReconfRqst
+
+UL-Timeslot-InformationModifyItem-PSCH-ReconfRqst ::= SEQUENCE {
+ timeSlot TimeSlot,
+ midambleShiftAndBurstType MidambleShiftAndBurstType OPTIONAL,
+ tFCI-Presence TFCI-Presence OPTIONAL,
+ uL-Code-InformationModifyList-PSCH-ReconfRqst UL-Code-InformationModifyList-PSCH-ReconfRqst OPTIONAL,
+ iE-Extensions ProtocolExtensionContainer { { UL-Timeslot-InformationModifyItem-PSCH-ReconfRqst-ExtIEs} } OPTIONAL,
+ ...
+}
+
+UL-Timeslot-InformationModifyItem-PSCH-ReconfRqst-ExtIEs NBAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+UL-Code-InformationModifyList-PSCH-ReconfRqst ::= SEQUENCE (SIZE (1..maxNrOfPUSCHs)) OF UL-Code-InformationModifyItem-PSCH-ReconfRqst
+
+UL-Code-InformationModifyItem-PSCH-ReconfRqst ::= SEQUENCE {
+ pUSCH-ID PUSCH-ID,
+ tdd-ChannelisationCode TDD-ChannelisationCode,
+ iE-Extensions ProtocolExtensionContainer { { UL-Code-InformationModifyItem-PSCH-ReconfRqst-ExtIEs} } OPTIONAL,
+ ...
+}
+
+UL-Code-InformationModifyItem-PSCH-ReconfRqst-ExtIEs NBAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+PUSCH-ModifyInformation-LCR-ModifyItem-PSCH-ReconfRqst ::= SEQUENCE {
+ repetitionPeriod RepetitionPeriod OPTIONAL,
+ repetitionLength RepetitionLength OPTIONAL,
+ tdd-PhysicalChannelOffset TDD-PhysicalChannelOffset OPTIONAL,
+ uL-Timeslot-InformationModifyList-LCR-PSCH-ReconfRqst UL-Timeslot-LCR-InformationModifyList-PSCH-ReconfRqst OPTIONAL,
+ iE-Extensions ProtocolExtensionContainer { {PUSCH-ModifyInformation-LCR-ModifyItem-PSCH-ReconfRqst-ExtIEs} } OPTIONAL,
+ ...
+ }
+
+PUSCH-ModifyInformation-LCR-ModifyItem-PSCH-ReconfRqst-ExtIEs NBAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+UL-Timeslot-LCR-InformationModifyList-PSCH-ReconfRqst ::= SEQUENCE (SIZE (1..maxNrOfULTSLCRs)) OF UL-Timeslot-LCR-InformationModifyItem-PSCH-ReconfRqst
+
+UL-Timeslot-LCR-InformationModifyItem-PSCH-ReconfRqst ::= SEQUENCE {
+ timeSlotLCR TimeSlotLCR,
+ midambleShiftLCR MidambleShiftLCR OPTIONAL,
+ tFCI-Presence TFCI-Presence OPTIONAL,
+ uL-Code-LCR-InformationModifyList-PSCH-ReconfRqst UL-Code-LCR-InformationModifyList-PSCH-ReconfRqst OPTIONAL,
+ iE-Extensions ProtocolExtensionContainer { { UL-Timeslot-LCR-InformationModifyItem-PSCH-ReconfRqst-ExtIEs} } OPTIONAL,
+ ...
+}
+
+UL-Timeslot-LCR-InformationModifyItem-PSCH-ReconfRqst-ExtIEs NBAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+UL-Code-LCR-InformationModifyList-PSCH-ReconfRqst ::= SEQUENCE (SIZE (1..maxNrOfPUSCHs)) OF UL-Code-LCR-InformationModifyItem-PSCH-ReconfRqst
+
+UL-Code-LCR-InformationModifyItem-PSCH-ReconfRqst ::= SEQUENCE {
+ pUSCH-ID PUSCH-ID,
+ tdd-ChannelisationCodeLCR TDD-ChannelisationCodeLCR,
+ iE-Extensions ProtocolExtensionContainer { { UL-Code-LCR-InformationModifyItem-PSCH-ReconfRqst-ExtIEs} } OPTIONAL,
+ ...
+}
+
+UL-Code-LCR-InformationModifyItem-PSCH-ReconfRqst-ExtIEs NBAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+PUSCHSets-DeleteList-PSCH-ReconfRqst ::= SEQUENCE (SIZE (1..maxNrOfPUSCHSets)) OF PUSCHSets-DeleteItem-PSCH-ReconfRqst
+
+PUSCHSets-DeleteItem-PSCH-ReconfRqst ::= SEQUENCE {
+ pUSCHSet-ID PUSCHSet-ID,
+ iE-Extensions ProtocolExtensionContainer { {PUSCHSets-DeleteItem-PSCH-ReconfRqst-ExtIEs} } OPTIONAL,
+ ...
+}
+
+PUSCHSets-DeleteItem-PSCH-ReconfRqst-ExtIEs NBAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+HS-PDSCH-TDD-Information-PSCH-ReconfRqst ::= SEQUENCE {
+ dL-HS-PDSCH-Timeslot-Information-PSCH-ReconfRqst DL-HS-PDSCH-Timeslot-Information-PSCH-ReconfRqst OPTIONAL,
+ dL-HS-PDSCH-Timeslot-Information-LCR-PSCH-ReconfRqst DL-HS-PDSCH-Timeslot-Information-LCR-PSCH-ReconfRqst OPTIONAL,
+ iE-Extensions ProtocolExtensionContainer { { HS-PDSCH-TDD-Information-PSCH-ReconfRqst-ExtIEs} } OPTIONAL,
+ ...
+ }
+
+HS-PDSCH-TDD-Information-PSCH-ReconfRqst-ExtIEs NBAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+DL-HS-PDSCH-Timeslot-Information-PSCH-ReconfRqst ::= SEQUENCE (SIZE (1..maxNrOfDLTSs)) OF DL-HS-PDSCH-Timeslot-InformationItem-PSCH-ReconfRqst
+
+DL-HS-PDSCH-Timeslot-InformationItem-PSCH-ReconfRqst::= SEQUENCE {
+ timeSlot TimeSlot,
+ midambleShiftAndBurstType MidambleShiftAndBurstType,
+ dl-HS-PDSCH-Codelist-PSCH-ReconfRqst DL-HS-PDSCH-Codelist-PSCH-ReconfRqst,
+ maxHSDSCH-HSSCCH-Power MaximumTransmissionPower OPTIONAL,
+ iE-Extensions ProtocolExtensionContainer { { DL-HS-PDSCH-Timeslot-InformationItem-PSCH-ReconfRqst-ExtIEs} } OPTIONAL,
+ ...
+}
+
+DL-HS-PDSCH-Timeslot-InformationItem-PSCH-ReconfRqst-ExtIEs NBAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+DL-HS-PDSCH-Codelist-PSCH-ReconfRqst ::= SEQUENCE (SIZE (1..maxNrOfHSPDSCHs)) OF TDD-ChannelisationCode
+
+DL-HS-PDSCH-Timeslot-Information-LCR-PSCH-ReconfRqst ::= SEQUENCE (SIZE (1..maxNrOfDLTSLCRs)) OF DL-HS-PDSCH-Timeslot-InformationItem-LCR-PSCH-ReconfRqst
+
+DL-HS-PDSCH-Timeslot-InformationItem-LCR-PSCH-ReconfRqst::= SEQUENCE {
+ timeSlot TimeSlotLCR,
+ midambleShiftAndBurstType MidambleShiftLCR,
+ dl-HS-PDSCH-Codelist-LCR-PSCH-ReconfRqst DL-HS-PDSCH-Codelist-LCR-PSCH-ReconfRqst,
+ maxHSDSCH-HSSCCH-Power MaximumTransmissionPower OPTIONAL,
+ iE-Extensions ProtocolExtensionContainer { { DL-HS-PDSCH-Timeslot-InformationItem-LCR-PSCH-ReconfRqst-ExtIEs} } OPTIONAL,
+ ...
+}
+
+DL-HS-PDSCH-Timeslot-InformationItem-LCR-PSCH-ReconfRqst-ExtIEs NBAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+DL-HS-PDSCH-Codelist-LCR-PSCH-ReconfRqst ::= SEQUENCE (SIZE (1..maxNrOfHSPDSCHs)) OF TDD-ChannelisationCode
+
+Add-To-HS-SCCH-Resource-Pool-PSCH-ReconfRqst::= SEQUENCE {
+ hS-SCCH-Information-PSCH-ReconfRqst HS-SCCH-Information-PSCH-ReconfRqst OPTIONAL,
+ hS-SCCH-Information-LCR-PSCH-ReconfRqst HS-SCCH-Information-LCR-PSCH-ReconfRqst OPTIONAL,
+ iE-Extensions ProtocolExtensionContainer { { Add-To-HS-SCCH-Resource-Pool-PSCH-ReconfRqst-ExtIEs} } OPTIONAL,
+ ...
+}
+
+Add-To-HS-SCCH-Resource-Pool-PSCH-ReconfRqst-ExtIEs NBAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+HS-SCCH-Information-PSCH-ReconfRqst::= SEQUENCE (SIZE (1..maxNrOfHSSCCHs)) OF HS-SCCH-InformationItem-PSCH-ReconfRqst
+
+HS-SCCH-InformationItem-PSCH-ReconfRqst ::= SEQUENCE {
+ hS-SCCH-ID HS-SCCH-ID,
+ timeSlot TimeSlot,
+ midambleShiftAndBurstType MidambleShiftAndBurstType,
+ tdd-ChannelisationCode TDD-ChannelisationCode,
+ hS-SCCH-MaxPower DL-Power,
+ hS-SICH-Information HS-SICH-Information-PSCH-ReconfRqst,
+ iE-Extensions ProtocolExtensionContainer { { HS-SCCH-InformationItem-PSCH-ReconfRqst-ExtIEs} } OPTIONAL,
+ ...
+}
+
+HS-SCCH-InformationItem-PSCH-ReconfRqst-ExtIEs NBAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+HS-SICH-Information-PSCH-ReconfRqst ::= SEQUENCE {
+ hsSICH-ID HS-SICH-ID,
+ timeSlot TimeSlot,
+ midambleShiftAndBurstType MidambleShiftAndBurstType,
+ tdd-ChannelisationCode TDD-ChannelisationCode,
+ iE-Extensions ProtocolExtensionContainer { { HS-SICH-Information-PSCH-ReconfRqst-ExtIEs} } OPTIONAL,
+ ...
+}
+
+HS-SICH-Information-PSCH-ReconfRqst-ExtIEs NBAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+HS-SCCH-Information-LCR-PSCH-ReconfRqst::= SEQUENCE (SIZE (1..maxNrOfHSSCCHs)) OF HS-SCCH-InformationItem-LCR-PSCH-ReconfRqst
+
+HS-SCCH-InformationItem-LCR-PSCH-ReconfRqst ::= SEQUENCE {
+ hS-SCCH-ID HS-SCCH-ID,
+ timeSlotLCR TimeSlotLCR,
+ midambleShiftLCR MidambleShiftLCR,
+ first-TDD-ChannelisationCode TDD-ChannelisationCode,
+ second-TDD-ChannelisationCode TDD-ChannelisationCode,
+ hS-SCCH-MaxPower DL-Power,
+ hS-SICH-Information-LCR HS-SICH-Information-LCR-PSCH-ReconfRqst,
+ iE-Extensions ProtocolExtensionContainer { { HS-SCCH-InformationItem-LCR-PSCH-ReconfRqst-ExtIEs} } OPTIONAL,
+ ...
+}
+
+HS-SCCH-InformationItem-LCR-PSCH-ReconfRqst-ExtIEs NBAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+HS-SICH-Information-LCR-PSCH-ReconfRqst ::= SEQUENCE {
+ hsSICH-ID HS-SICH-ID,
+ timeSlotLCR TimeSlotLCR,
+ midambleShiftLCR MidambleShiftLCR,
+ tdd-ChannelisationCode TDD-ChannelisationCode,
+ iE-Extensions ProtocolExtensionContainer { { HS-SICH-Information-LCR-PSCH-ReconfRqst-ExtIEs} } OPTIONAL,
+ ...
+}
+
+HS-SICH-Information-LCR-PSCH-ReconfRqst-ExtIEs NBAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+Modify-HS-SCCH-Resource-Pool-PSCH-ReconfRqst::= SEQUENCE {
+ hS-SCCH-InformationModify-PSCH-ReconfRqst HS-SCCH-InformationModify-PSCH-ReconfRqst OPTIONAL,
+ hS-SCCH-InformationModify-LCR-PSCH-ReconfRqst HS-SCCH-InformationModify-LCR-PSCH-ReconfRqst OPTIONAL,
+ iE-Extensions ProtocolExtensionContainer { { Modify-HS-SCCH-Resource-Pool-PSCH-ReconfRqst-ExtIEs} } OPTIONAL,
+ ...
+}
+
+Modify-HS-SCCH-Resource-Pool-PSCH-ReconfRqst-ExtIEs NBAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+HS-SCCH-InformationModify-PSCH-ReconfRqst::= SEQUENCE (SIZE (1..maxNrOfHSSCCHs)) OF HS-SCCH-InformationModifyItem-PSCH-ReconfRqst
+
+HS-SCCH-InformationModifyItem-PSCH-ReconfRqst ::= SEQUENCE {
+ hS-SCCH-ID HS-SCCH-ID,
+ timeSlot TimeSlot OPTIONAL,
+ midambleShiftAndBurstType MidambleShiftAndBurstType OPTIONAL,
+ tdd-ChannelisationCode TDD-ChannelisationCode OPTIONAL,
+ hS-SCCH-MaxPower DL-Power OPTIONAL,
+ hS-SICH-Information HS-SICH-InformationModify-PSCH-ReconfRqst OPTIONAL,
+ iE-Extensions ProtocolExtensionContainer { { HS-SCCH-InformationModifyItem-PSCH-ReconfRqst-ExtIEs} } OPTIONAL,
+ ...
+}
+
+HS-SCCH-InformationModifyItem-PSCH-ReconfRqst-ExtIEs NBAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+HS-SICH-InformationModify-PSCH-ReconfRqst ::= SEQUENCE {
+ hsSICH-ID HS-SICH-ID,
+ timeSlot TimeSlot OPTIONAL,
+ midambleShiftAndBurstType MidambleShiftAndBurstType OPTIONAL,
+ tdd-ChannelisationCode TDD-ChannelisationCode OPTIONAL,
+ iE-Extensions ProtocolExtensionContainer { { HS-SICH-InformationModify-PSCH-ReconfRqst-ExtIEs} } OPTIONAL,
+ ...
+}
+
+HS-SICH-InformationModify-PSCH-ReconfRqst-ExtIEs NBAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+HS-SCCH-InformationModify-LCR-PSCH-ReconfRqst::= SEQUENCE (SIZE (1..maxNrOfHSSCCHs)) OF HS-SCCH-InformationModifyItem-LCR-PSCH-ReconfRqst
+
+HS-SCCH-InformationModifyItem-LCR-PSCH-ReconfRqst ::= SEQUENCE {
+ hS-SCCH-ID HS-SCCH-ID,
+ timeSlotLCR TimeSlotLCR OPTIONAL,
+ midambleShiftLCR MidambleShiftLCR OPTIONAL,
+ first-TDD-ChannelisationCode TDD-ChannelisationCode OPTIONAL,
+ second-TDD-ChannelisationCode TDD-ChannelisationCode OPTIONAL,
+ hS-SCCH-MaxPower DL-Power OPTIONAL,
+ hS-SICH-Information-LCR HS-SICH-InformationModify-LCR-PSCH-ReconfRqst OPTIONAL,
+ iE-Extensions ProtocolExtensionContainer { { HS-SCCH-InformationModifyItem-LCR-PSCH-ReconfRqst-ExtIEs} } OPTIONAL,
+ ...
+}
+
+HS-SCCH-InformationModifyItem-LCR-PSCH-ReconfRqst-ExtIEs NBAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+HS-SICH-InformationModify-LCR-PSCH-ReconfRqst ::= SEQUENCE {
+ hsSICH-ID HS-SICH-ID,
+ timeSlotLCR TimeSlotLCR OPTIONAL,
+ midambleShiftLCR MidambleShiftLCR OPTIONAL,
+ tdd-ChannelisationCode TDD-ChannelisationCode OPTIONAL,
+ iE-Extensions ProtocolExtensionContainer { { HS-SICH-InformationModify-LCR-PSCH-ReconfRqst-ExtIEs} } OPTIONAL,
+ ...
+}
+
+HS-SICH-InformationModify-LCR-PSCH-ReconfRqst-ExtIEs NBAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+Delete-From-HS-SCCH-Resource-Pool-PSCH-ReconfRqst ::= SEQUENCE (SIZE (1..maxNrOfHSSCCHs)) OF Delete-From-HS-SCCH-Resource-PoolItem-PSCH-ReconfRqst
+
+Delete-From-HS-SCCH-Resource-PoolItem-PSCH-ReconfRqst ::= SEQUENCE {
+ hS-SCCH-ID HS-SCCH-ID,
+ iE-Extensions ProtocolExtensionContainer { { Delete-From-HS-SCCH-Resource-PoolItem-PSCH-ReconfRqst-ExtIEs} } OPTIONAL,
+ ...
+}
+
+Delete-From-HS-SCCH-Resource-PoolItem-PSCH-ReconfRqst-ExtIEs NBAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+-- **************************************************************
+--
+-- PHYSICAL SHARED CHANNEL RECONFIGURATION RESPONSE
+--
+-- **************************************************************
+
+PhysicalSharedChannelReconfigurationResponse ::= SEQUENCE {
+ protocolIEs ProtocolIE-Container {{PhysicalSharedChannelReconfigurationResponse-IEs}},
+ protocolExtensions ProtocolExtensionContainer {{PhysicalSharedChannelReconfigurationResponse-Extensions}} OPTIONAL,
+ ...
+}
+
+PhysicalSharedChannelReconfigurationResponse-IEs NBAP-PROTOCOL-IES ::= {
+ { ID id-CriticalityDiagnostics CRITICALITY ignore TYPE CriticalityDiagnostics PRESENCE optional },
+ ...
+}
+
+PhysicalSharedChannelReconfigurationResponse-Extensions NBAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+
+-- **************************************************************
+--
+-- PHYSICAL SHARED CHANNEL RECONFIGURATION FAILURE
+--
+-- **************************************************************
+
+PhysicalSharedChannelReconfigurationFailure ::= SEQUENCE {
+ protocolIEs ProtocolIE-Container {{PhysicalSharedChannelReconfigurationFailure-IEs}},
+ protocolExtensions ProtocolExtensionContainer {{PhysicalSharedChannelReconfigurationFailure-Extensions}} OPTIONAL,
+ ...
+}
+
+PhysicalSharedChannelReconfigurationFailure-IEs NBAP-PROTOCOL-IES ::= {
+ { ID id-CauseLevel-PSCH-ReconfFailure CRITICALITY ignore TYPE CauseLevel-PSCH-ReconfFailure PRESENCE mandatory }|
+ { ID id-CriticalityDiagnostics CRITICALITY ignore TYPE CriticalityDiagnostics PRESENCE optional },
+ ...
+}
+
+PhysicalSharedChannelReconfigurationFailure-Extensions NBAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+CauseLevel-PSCH-ReconfFailure ::= CHOICE {
+ generalCause GeneralCauseList-PSCH-ReconfFailure,
+ setSpecificCause SetSpecificCauseList-PSCH-ReconfFailureTDD,
+ ...
+}
+
+GeneralCauseList-PSCH-ReconfFailure ::= SEQUENCE {
+ cause Cause,
+ iE-Extensions ProtocolExtensionContainer { { GeneralCauseItem-PSCH-ReconfFailure-ExtIEs} } OPTIONAL,
+ ...
+}
+
+GeneralCauseItem-PSCH-ReconfFailure-ExtIEs NBAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+SetSpecificCauseList-PSCH-ReconfFailureTDD ::= SEQUENCE {
+ unsuccessful-PDSCHSetList-PSCH-ReconfFailureTDD Unsuccessful-PDSCHSetList-PSCH-ReconfFailureTDD OPTIONAL,
+ unsuccessful-PUSCHSetList-PSCH-ReconfFailureTDD Unsuccessful-PUSCHSetList-PSCH-ReconfFailureTDD OPTIONAL,
+ iE-Extensions ProtocolExtensionContainer { { SetSpecificCauseItem-PSCH-ReconfFailureTDD-ExtIEs} } OPTIONAL,
+ ...
+}
+
+SetSpecificCauseItem-PSCH-ReconfFailureTDD-ExtIEs NBAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+Unsuccessful-PDSCHSetList-PSCH-ReconfFailureTDD ::= SEQUENCE (SIZE (0.. maxNrOfPDSCHSets)) OF ProtocolIE-Single-Container {{ Unsuccessful-PDSCHSetItemIE-PSCH-ReconfFailureTDD }}
+
+Unsuccessful-PDSCHSetItemIE-PSCH-ReconfFailureTDD NBAP-PROTOCOL-IES ::= {
+ { ID id-Unsuccessful-PDSCHSetItem-PSCH-ReconfFailureTDD CRITICALITY ignore TYPE Unsuccessful-PDSCHSetItem-PSCH-ReconfFailureTDD PRESENCE mandatory}
+}
+
+Unsuccessful-PDSCHSetItem-PSCH-ReconfFailureTDD ::= SEQUENCE {
+ pDSCHSet-ID PDSCHSet-ID,
+ cause Cause,
+ iE-Extensions ProtocolExtensionContainer { {Unsuccessful-PDSCHSetItem-PSCH-ReconfFailureTDD-ExtIEs} } OPTIONAL,
+ ...
+}
+
+Unsuccessful-PDSCHSetItem-PSCH-ReconfFailureTDD-ExtIEs NBAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+Unsuccessful-PUSCHSetList-PSCH-ReconfFailureTDD ::= SEQUENCE (SIZE (0.. maxNrOfPUSCHSets)) OF ProtocolIE-Single-Container {{ Unsuccessful-PUSCHSetItemIE-PSCH-ReconfFailureTDD }}
+
+Unsuccessful-PUSCHSetItemIE-PSCH-ReconfFailureTDD NBAP-PROTOCOL-IES ::= {
+ { ID id-Unsuccessful-PUSCHSetItem-PSCH-ReconfFailureTDD CRITICALITY ignore TYPE Unsuccessful-PUSCHSetItem-PSCH-ReconfFailureTDD PRESENCE mandatory}
+}
+
+Unsuccessful-PUSCHSetItem-PSCH-ReconfFailureTDD ::= SEQUENCE {
+ pUSCHSet-ID PUSCHSet-ID,
+ cause Cause,
+ iE-Extensions ProtocolExtensionContainer { {Unsuccessful-PUSCHSetItem-PSCH-ReconfFailureTDD-ExtIEs} } OPTIONAL,
+ ...
+}
+
+Unsuccessful-PUSCHSetItem-PSCH-ReconfFailureTDD-ExtIEs NBAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+-- **************************************************************
+--
+-- RESET REQUEST
+--
+-- **************************************************************
+
+ResetRequest ::= SEQUENCE {
+ protocolIEs ProtocolIE-Container {{ResetRequest-IEs}},
+ protocolExtensions ProtocolExtensionContainer {{ResetRequest-Extensions}} OPTIONAL,
+ ...
+}
+
+ResetRequest-IEs NBAP-PROTOCOL-IES ::= {
+ {ID id-ResetIndicator CRITICALITY ignore TYPE ResetIndicator PRESENCE mandatory},
+ ...
+}
+
+ResetRequest-Extensions NBAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+ResetIndicator ::= CHOICE {
+ communicationContext CommunicationContextList-Reset,
+ communicationControlPort CommunicationControlPortList-Reset,
+ nodeB NULL,
+ ...
+}
+
+CommunicationContextList-Reset ::= SEQUENCE {
+ communicationContextInfoList-Reset CommunicationContextInfoList-Reset,
+ iE-Extensions ProtocolExtensionContainer { {CommunicationContextItem-Reset-ExtIEs} } OPTIONAL,
+ ...
+}
+
+CommunicationContextItem-Reset-ExtIEs NBAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+CommunicationContextInfoList-Reset ::= SEQUENCE (SIZE (1.. maxCommunicationContext)) OF ProtocolIE-Single-Container {{ CommunicationContextInfoItemIE-Reset }}
+
+CommunicationContextInfoItemIE-Reset NBAP-PROTOCOL-IES ::= {
+ {ID id-CommunicationContextInfoItem-Reset CRITICALITY reject TYPE CommunicationContextInfoItem-Reset PRESENCE mandatory}
+}
+
+CommunicationContextInfoItem-Reset ::= SEQUENCE {
+ communicationContextType-Reset CommunicationContextType-Reset,
+ iE-Extensions ProtocolExtensionContainer { { CommunicationContextInfoItem-Reset-ExtIEs} } OPTIONAL,
+ ...
+}
+
+CommunicationContextInfoItem-Reset-ExtIEs NBAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+CommunicationContextType-Reset ::= CHOICE {
+ cRNC-CommunicationContextID CRNC-CommunicationContextID,
+ nodeB-CommunicationContextID NodeB-CommunicationContextID,
+ ...
+}
+
+CommunicationControlPortList-Reset ::= SEQUENCE {
+ communicationControlPortInfoList-Reset CommunicationControlPortInfoList-Reset,
+ iE-Extensions ProtocolExtensionContainer { {CommunicationControlPortItem-Reset-ExtIEs} } OPTIONAL,
+ ...
+}
+
+CommunicationControlPortItem-Reset-ExtIEs NBAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+CommunicationControlPortInfoList-Reset ::= SEQUENCE (SIZE (1.. maxCCPinNodeB)) OF ProtocolIE-Single-Container {{CommunicationControlPortInfoItemIE-Reset }}
+
+CommunicationControlPortInfoItemIE-Reset NBAP-PROTOCOL-IES ::= {
+ {ID id-CommunicationControlPortInfoItem-Reset CRITICALITY reject TYPE CommunicationControlPortInfoItem-Reset PRESENCE mandatory}
+}
+
+CommunicationControlPortInfoItem-Reset ::= SEQUENCE {
+ communicationControlPortID CommunicationControlPortID,
+ iE-Extensions ProtocolExtensionContainer { {CommunicationControlPortInfoItem-Reset-ExtIEs} } OPTIONAL,
+ ...
+}
+
+CommunicationControlPortInfoItem-Reset-ExtIEs NBAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+-- **************************************************************
+--
+-- RESET RESPONSE
+--
+-- **************************************************************
+
+ResetResponse ::= SEQUENCE {
+ protocolIEs ProtocolIE-Container {{ResetResponse-IEs}},
+ protocolExtensions ProtocolExtensionContainer {{ResetResponse-Extensions}} OPTIONAL,
+ ...
+}
+
+ResetResponse-IEs NBAP-PROTOCOL-IES ::= {
+ {ID id-CriticalityDiagnostics CRITICALITY ignore TYPE CriticalityDiagnostics PRESENCE optional},
+ ...
+}
+
+ResetResponse-Extensions NBAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+-- **************************************************************
+--
+-- INFORMATION EXCHANGE INITIATION REQUEST
+--
+-- **************************************************************
+
+InformationExchangeInitiationRequest ::= SEQUENCE {
+ protocolIEs ProtocolIE-Container {{InformationExchangeInitiationRequest-IEs}},
+ protocolExtensions ProtocolExtensionContainer {{InformationExchangeInitiationRequest-Extensions}} OPTIONAL,
+ ...
+}
+
+InformationExchangeInitiationRequest-IEs NBAP-PROTOCOL-IES ::= {
+ { ID id-InformationExchangeID CRITICALITY reject TYPE InformationExchangeID PRESENCE mandatory }|
+ { ID id-InformationExchangeObjectType-InfEx-Rqst CRITICALITY reject TYPE InformationExchangeObjectType-InfEx-Rqst PRESENCE mandatory }|
+ { ID id-InformationType CRITICALITY reject TYPE InformationType PRESENCE mandatory }|
+ { ID id-InformationReportCharacteristics CRITICALITY reject TYPE InformationReportCharacteristics PRESENCE mandatory},
+ ...
+}
+
+InformationExchangeInitiationRequest-Extensions NBAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+InformationExchangeObjectType-InfEx-Rqst ::= CHOICE {
+ cell Cell-InfEx-Rqst,
+ ...
+}
+
+Cell-InfEx-Rqst ::= SEQUENCE {
+ c-ID C-ID,
+ iE-Extensions ProtocolExtensionContainer { { CellItem-InfEx-Rqst-ExtIEs} } OPTIONAL,
+ ...
+}
+
+CellItem-InfEx-Rqst-ExtIEs NBAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+-- **************************************************************
+--
+-- INFORMATION EXCHANGE INITIATION RESPONSE
+--
+-- **************************************************************
+
+InformationExchangeInitiationResponse ::= SEQUENCE {
+ protocolIEs ProtocolIE-Container {{InformationExchangeInitiationResponse-IEs}},
+ protocolExtensions ProtocolExtensionContainer {{InformationExchangeInitiationResponse-Extensions}} OPTIONAL,
+ ...
+}
+
+InformationExchangeInitiationResponse-IEs NBAP-PROTOCOL-IES ::= {
+ { ID id-InformationExchangeID CRITICALITY ignore TYPE InformationExchangeID PRESENCE mandatory }|
+ { ID id-InformationExchangeObjectType-InfEx-Rsp CRITICALITY ignore TYPE InformationExchangeObjectType-InfEx-Rsp PRESENCE optional }|
+ { ID id-CriticalityDiagnostics CRITICALITY ignore TYPE CriticalityDiagnostics PRESENCE optional },
+ ...
+}
+
+InformationExchangeInitiationResponse-Extensions NBAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+InformationExchangeObjectType-InfEx-Rsp ::= CHOICE {
+ cell Cell-InfEx-Rsp,
+ ...
+ }
+
+Cell-InfEx-Rsp ::= SEQUENCE {
+ requestedDataValue RequestedDataValue,
+ iE-Extensions ProtocolExtensionContainer { { CellItem-InfEx-Rsp-ExtIEs} } OPTIONAL,
+ ...
+ }
+
+CellItem-InfEx-Rsp-ExtIEs NBAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+-- **************************************************************
+--
+-- INFORMATION EXCHANGE INITIATION FAILURE
+--
+-- **************************************************************
+
+InformationExchangeInitiationFailure ::= SEQUENCE {
+ protocolIEs ProtocolIE-Container {{InformationExchangeInitiationFailure-IEs}},
+ protocolExtensions ProtocolExtensionContainer {{InformationExchangeInitiationFailure-Extensions}} OPTIONAL,
+ ...
+}
+
+InformationExchangeInitiationFailure-IEs NBAP-PROTOCOL-IES ::= {
+ { ID id-InformationExchangeID CRITICALITY ignore TYPE InformationExchangeID PRESENCE mandatory }|
+ { ID id-Cause CRITICALITY ignore TYPE Cause PRESENCE mandatory }|
+ { ID id-CriticalityDiagnostics CRITICALITY ignore TYPE CriticalityDiagnostics PRESENCE optional },
+ ...
+}
+
+InformationExchangeInitiationFailure-Extensions NBAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+-- **************************************************************
+--
+-- INFORMATION REPORT
+--
+-- **************************************************************
+
+InformationReport ::= SEQUENCE {
+ protocolIEs ProtocolIE-Container {{InformationReport-IEs}},
+ protocolExtensions ProtocolExtensionContainer {{InformationReport-Extensions}} OPTIONAL,
+ ...
+}
+
+InformationReport-IEs NBAP-PROTOCOL-IES ::= {
+ { ID id-InformationExchangeID CRITICALITY ignore TYPE InformationExchangeID PRESENCE mandatory }|
+ { ID id-InformationExchangeObjectType-InfEx-Rprt CRITICALITY ignore TYPE InformationExchangeObjectType-InfEx-Rprt PRESENCE mandatory },
+ ...
+}
+
+InformationReport-Extensions NBAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+InformationExchangeObjectType-InfEx-Rprt ::= CHOICE {
+ cell Cell-Inf-Rprt,
+ ...
+ }
+
+Cell-Inf-Rprt ::= SEQUENCE {
+ requestedDataValueInformation RequestedDataValueInformation,
+ iE-Extensions ProtocolExtensionContainer {{ CellItem-Inf-Rprt-ExtIEs }} OPTIONAL,
+ ...
+
+ }
+
+CellItem-Inf-Rprt-ExtIEs NBAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+-- **************************************************************
+--
+-- INFORMATION EXCHANGE TERMINATION REQUEST
+--
+-- **************************************************************
+
+InformationExchangeTerminationRequest ::= SEQUENCE {
+ protocolIEs ProtocolIE-Container {{InformationExchangeTerminationRequest-IEs}},
+ protocolExtensions ProtocolExtensionContainer {{InformationExchangeTerminationRequest-Extensions}} OPTIONAL,
+ ...
+}
+
+InformationExchangeTerminationRequest-IEs NBAP-PROTOCOL-IES ::= {
+ { ID id-InformationExchangeID CRITICALITY ignore TYPE InformationExchangeID PRESENCE mandatory},
+ ...
+}
+
+InformationExchangeTerminationRequest-Extensions NBAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+-- **************************************************************
+--
+-- INFORMATION EXCHANGE FAILURE INDICATION
+--
+-- **************************************************************
+
+InformationExchangeFailureIndication ::= SEQUENCE {
+ protocolIEs ProtocolIE-Container {{InformationExchangeFailureIndication-IEs}},
+ protocolExtensions ProtocolExtensionContainer {{InformationExchangeFailureIndication-Extensions}} OPTIONAL,
+ ...
+}
+
+InformationExchangeFailureIndication-IEs NBAP-PROTOCOL-IES ::= {
+ { ID id-InformationExchangeID CRITICALITY ignore TYPE InformationExchangeID PRESENCE mandatory }|
+ { ID id-Cause CRITICALITY ignore TYPE Cause PRESENCE mandatory },
+ ...
+}
+
+InformationExchangeFailureIndication-Extensions NBAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+-- **************************************************************
+--
+-- CELL SYNCHRONISATION INITIATION REQUEST TDD
+--
+-- **************************************************************
+
+CellSynchronisationInitiationRequestTDD ::= SEQUENCE {
+ protocolIEs ProtocolIE-Container {{CellSynchronisationInitiationRequestTDD-IEs}},
+ protocolExtensions ProtocolExtensionContainer {{CellSynchronisationInitiationRequestTDD-Extensions}} OPTIONAL,
+ ...
+}
+
+CellSynchronisationInitiationRequestTDD-Extensions NBAP-PROTOCOL-EXTENSION ::= {
+ { ID id-SYNCDlCodeId-TransInitLCR-CellSyncInitiationRqstTDD CRITICALITY reject EXTENSION SYNCDlCodeId-TransInitLCR-CellSyncInitiationRqstTDD PRESENCE optional }| -- Applicable to 1.28Mcps TDD only
+ { ID id-SYNCDlCodeId-MeasureInitLCR-CellSyncInitiationRqstTDD CRITICALITY reject EXTENSION SYNCDlCodeId-MeasureInitLCR-CellSyncInitiationRqstTDD PRESENCE optional }, -- Applicable to 1.28Mcps TDD only
+ ...
+}
+
+CellSynchronisationInitiationRequestTDD-IEs NBAP-PROTOCOL-IES ::= {
+ { ID id-C-ID CRITICALITY reject TYPE C-ID PRESENCE mandatory }|
+ { ID id-cellSyncBurstRepetitionPeriod CRITICALITY reject TYPE CellSyncBurstRepetitionPeriod PRESENCE mandatory }|
+ { ID id-timeslotInfo-CellSyncInitiationRqstTDD CRITICALITY reject TYPE TimeslotInfo-CellSyncInitiationRqstTDD PRESENCE optional }| -- Mandatory for 3.84Mcps TDD. Not Applicable to 1.28Mcps TDD.
+ { ID id-CellSyncBurstTransInit-CellSyncInitiationRqstTDD CRITICALITY reject TYPE CellSyncBurstTransInit-CellSyncInitiationRqstTDD PRESENCE optional }| -- Applicable to 3.84Mcps TDD only
+ { ID id-CellSyncBurstMeasureInit-CellSyncInitiationRqstTDD CRITICALITY reject TYPE CellSyncBurstMeasureInit-CellSyncInitiationRqstTDD PRESENCE optional }, -- Applicable to 3.84Mcps TDD only
+ ...
+}
+
+CellSyncBurstTransInit-CellSyncInitiationRqstTDD::= SEQUENCE {
+ cSBTransmissionID CSBTransmissionID,
+ sfn SFN,
+ cellSyncBurstCode CellSyncBurstCode,
+ cellSyncBurstCodeShift CellSyncBurstCodeShift,
+ initialDLTransPower DL-Power,
+ iE-Extensions ProtocolExtensionContainer { { CellSyncBurstTransInit-CellSyncInitiationRqstTDD-ExtIEs} } OPTIONAL,
+ ...
+ }
+
+CellSyncBurstTransInit-CellSyncInitiationRqstTDD-ExtIEs NBAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+TimeslotInfo-CellSyncInitiationRqstTDD::= SEQUENCE (SIZE (1..15)) OF TimeSlot
+
+CellSyncBurstMeasureInit-CellSyncInitiationRqstTDD::= SEQUENCE {
+ cSBMeasurementID CSBMeasurementID,
+ cellSyncBurstCode CellSyncBurstCode,
+ cellSyncBurstCodeShift CellSyncBurstCodeShift,
+ synchronisationReportType SynchronisationReportType,
+ sfn SFN OPTIONAL,
+ synchronisationReportCharacteristics SynchronisationReportCharacteristics,
+ iE-Extensions ProtocolExtensionContainer { { CellSyncBurstMeasureInit-CellSyncInitiationRqstTDD-ExtIEs} } OPTIONAL,
+ ...
+ }
+
+CellSyncBurstMeasureInit-CellSyncInitiationRqstTDD-ExtIEs NBAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+SYNCDlCodeId-TransInitLCR-CellSyncInitiationRqstTDD::= SEQUENCE {
+ cSBTransmissionID CSBTransmissionID,
+ sfn SFN,
+ uARFCN UARFCN,
+ sYNCDlCodeId SYNCDlCodeId,
+ dwPCH-Power DwPCH-Power,
+ iE-Extensions ProtocolExtensionContainer { { SYNCDlCodeId-TransInitLCR-CellSyncInitiationRqstTDD-ExtIEs } } OPTIONAL,
+ ...
+}
+
+SYNCDlCodeId-TransInitLCR-CellSyncInitiationRqstTDD-ExtIEs NBAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+SYNCDlCodeId-MeasureInitLCR-CellSyncInitiationRqstTDD::= SEQUENCE {
+ cSBMeasurementID CSBMeasurementID,
+ sfn SFN OPTIONAL,
+ uARFCN UARFCN,
+ sYNCDlCodeId SYNCDlCodeId,
+ synchronisationReportType SynchronisationReportType,
+ synchronisationReportCharacteristics SynchronisationReportCharacteristics,
+ iE-Extensions ProtocolExtensionContainer { { SYNCDlCodeId-MeasureInitLCR-CellSyncInitiationRqstTDD-ExtIEs } } OPTIONAL,
+ ...
+}
+
+SYNCDlCodeId-MeasureInitLCR-CellSyncInitiationRqstTDD-ExtIEs NBAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+-- **************************************************************
+--
+-- CELL SYNCHRONISATION INITIATION RESPONSE TDD
+--
+-- **************************************************************
+
+CellSynchronisationInitiationResponseTDD ::= SEQUENCE {
+ protocolIEs ProtocolIE-Container {{CellSynchronisationInitiationResponseTDD-IEs}},
+ protocolExtensions ProtocolExtensionContainer {{CellSynchronisationInitiationResponseTDD-Extensions}} OPTIONAL,
+ ...
+}
+
+CellSynchronisationInitiationResponseTDD-Extensions NBAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+CellSynchronisationInitiationResponseTDD-IEs NBAP-PROTOCOL-IES ::= {
+ { ID id-CriticalityDiagnostics CRITICALITY ignore TYPE CriticalityDiagnostics PRESENCE optional },
+ ...
+}
+
+-- **************************************************************
+--
+-- CELL SYNCHRONISATION INITIATION FAILURE TDD
+--
+-- **************************************************************
+
+CellSynchronisationInitiationFailureTDD ::= SEQUENCE {
+ protocolIEs ProtocolIE-Container {{CellSynchronisationInitiationFailureTDD-IEs}},
+ protocolExtensions ProtocolExtensionContainer {{CellSynchronisationInitiationFailureTDD-Extensions}} OPTIONAL,
+ ...
+}
+
+CellSynchronisationInitiationFailureTDD-Extensions NBAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+CellSynchronisationInitiationFailureTDD-IEs NBAP-PROTOCOL-IES ::= {
+ { ID id-Cause CRITICALITY ignore TYPE Cause PRESENCE mandatory }|
+ { ID id-CriticalityDiagnostics CRITICALITY ignore TYPE CriticalityDiagnostics PRESENCE optional },
+ ...
+}
+
+-- **************************************************************
+--
+-- CELL SYNCHRONISATION RECONFIGURATION REQUEST TDD
+--
+-- **************************************************************
+
+CellSynchronisationReconfigurationRequestTDD ::= SEQUENCE {
+ protocolIEs ProtocolIE-Container {{CellSynchronisationReconfigurationRequestTDD-IEs}},
+ protocolExtensions ProtocolExtensionContainer {{CellSynchronisationReconfigurationRequestTDD-Extensions}} OPTIONAL,
+ ...
+}
+
+CellSynchronisationReconfigurationRequestTDD-Extensions NBAP-PROTOCOL-EXTENSION ::= {
+ { ID id-NSubCyclesPerCyclePeriod-CellSyncReconfRqstTDD CRITICALITY reject EXTENSION NSubCyclesPerCyclePeriod PRESENCE optional }| -- Applicable to 1.28Mcps TDD only
+ { ID id-SYNCDlCodeIdTransReconfInfoLCR-CellSyncReconfRqstTDD CRITICALITY reject EXTENSION SYNCDlCodeIdTransReconfInfoLCR-CellSyncReconfRqstTDD PRESENCE optional }| -- Applicable to 1.28Mcps TDD only
+ { ID id-SYNCDlCodeIdMeasReconfigurationLCR-CellSyncReconfRqstTDD CRITICALITY reject EXTENSION SYNCDlCodeIdMeasInfoLCR-CellSyncReconfRqstTDD PRESENCE optional }, -- Applicable to 1.28Mcps TDD only
+ ...
+}
+
+CellSynchronisationReconfigurationRequestTDD-IEs NBAP-PROTOCOL-IES ::= {
+ { ID id-C-ID CRITICALITY reject TYPE C-ID PRESENCE mandatory }|
+ { ID id-TimeSlot CRITICALITY reject TYPE TimeSlot PRESENCE mandatory }|
+ -- Applicable to 3.84Mcps TDD only. For 1.28Mcps TDD, the CRNC should set this to 0 and the Node B shall ignore it.
+ { ID id-NCyclesPerSFNperiod CRITICALITY reject TYPE NCyclesPerSFNperiod PRESENCE mandatory }|
+ { ID id-NRepetitionsPerCyclePeriod CRITICALITY reject TYPE NRepetitionsPerCyclePeriod PRESENCE mandatory }|
+ { ID id-CellSyncBurstTransReconfInfo-CellSyncReconfRqstTDD CRITICALITY reject TYPE CellSyncBurstTransReconfInfo-CellSyncReconfRqstTDD PRESENCE optional }| -- Applicable to 3.84Mcps TDD only
+ { ID id-CellSyncBurstMeasReconfiguration-CellSyncReconfRqstTDD CRITICALITY reject TYPE CellSyncBurstMeasInfo-CellSyncReconfRqstTDD PRESENCE optional }, -- Applicable to 3.84Mcps TDD only
+ ...
+}
+
+CellSyncBurstTransReconfInfo-CellSyncReconfRqstTDD ::= SEQUENCE (SIZE (1.. maxNrOfCellSyncBursts)) OF CellSyncBurstTransInfoItem-CellSyncReconfRqstTDD
+
+CellSyncBurstTransInfoItem-CellSyncReconfRqstTDD ::= SEQUENCE {
+ cSBTransmissionID CSBTransmissionID,
+ syncFrameNumberToTransmit SyncFrameNumber,
+ cellSyncBurstCode CellSyncBurstCode OPTIONAL,
+ cellSyncBurstCodeShift CellSyncBurstCodeShift OPTIONAL,
+ dlTransPower DL-Power OPTIONAL,
+ iE-Extensions ProtocolExtensionContainer { { CellSyncBurstTransInfoItem-CellSyncReconfRqstTDD-ExtIEs} } OPTIONAL,
+ ...
+}
+
+CellSyncBurstTransInfoItem-CellSyncReconfRqstTDD-ExtIEs NBAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+
+CellSyncBurstMeasInfo-CellSyncReconfRqstTDD ::= SEQUENCE {
+ cellSyncBurstMeasInfoList-CellSyncReconfRqstTDD CellSyncBurstMeasInfoList-CellSyncReconfRqstTDD,
+ synchronisationReportType SynchronisationReportTypeIE OPTIONAL,
+ synchronisationReportCharacteristics SynchronisationReportCharacteristicsIE OPTIONAL,
+ iE-Extensions ProtocolExtensionContainer { { CellSyncBurstMeasInfo-CellSyncReconfRqstTDD-ExtIEs} } OPTIONAL,
+ ...
+}
+
+CellSyncBurstMeasInfo-CellSyncReconfRqstTDD-ExtIEs NBAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+CellSyncBurstMeasInfoList-CellSyncReconfRqstTDD ::= ProtocolIE-Single-Container {{ CellSyncBurstMeasInfoListIEs-CellSyncReconfRqstTDD }}
+
+CellSyncBurstMeasInfoListIEs-CellSyncReconfRqstTDD NBAP-PROTOCOL-IES ::= {
+ { ID id-CellSyncBurstMeasInfoList-CellSyncReconfRqstTDD CRITICALITY reject TYPE CellSyncBurstMeasInfoListIE-CellSyncReconfRqstTDD PRESENCE mandatory }
+}
+
+SynchronisationReportTypeIE ::= ProtocolIE-Single-Container {{ SynchronisationReportTypeIEs }}
+
+SynchronisationReportTypeIEs NBAP-PROTOCOL-IES ::= {
+ { ID id-SynchronisationReportType CRITICALITY reject TYPE SynchronisationReportType PRESENCE mandatory }
+}
+
+SynchronisationReportCharacteristicsIE ::= ProtocolIE-Single-Container {{ SynchronisationReportCharacteristicsIEs }}
+
+SynchronisationReportCharacteristicsIEs NBAP-PROTOCOL-IES ::= {
+ { ID id-SynchronisationReportCharacteristics CRITICALITY reject TYPE SynchronisationReportCharacteristics PRESENCE mandatory }
+}
+
+
+CellSyncBurstMeasInfoListIE-CellSyncReconfRqstTDD ::= SEQUENCE (SIZE (1.. maxNrOfCellSyncBursts)) OF CellSyncBurstMeasInfoItem-CellSyncReconfRqstTDD
+
+CellSyncBurstMeasInfoItem-CellSyncReconfRqstTDD ::= SEQUENCE {
+ syncFrameNrToReceive SyncFrameNumber,
+ syncBurstInfo CellSyncBurstInfoList-CellSyncReconfRqstTDD,
+ iE-Extensions ProtocolExtensionContainer { { CellSyncBurstMeasInfoItem-CellSyncReconfRqstTDD-ExtIEs} } OPTIONAL,
+ ...
+}
+
+CellSyncBurstMeasInfoItem-CellSyncReconfRqstTDD-ExtIEs NBAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+CellSyncBurstInfoList-CellSyncReconfRqstTDD ::= SEQUENCE (SIZE (1..maxNrOfReceptsPerSyncFrame)) OF CellSyncBurstInfoItem-CellSyncReconfRqstTDD
+
+CellSyncBurstInfoItem-CellSyncReconfRqstTDD ::= SEQUENCE {
+ cSBMeasurementID CSBMeasurementID,
+ cellSyncBurstCode CellSyncBurstCode,
+ cellSyncBurstCodeShift CellSyncBurstCodeShift,
+ iE-Extensions ProtocolExtensionContainer { { CellSyncBurstInfoItem-CellSyncReconfRqstTDD-ExtIEs} } OPTIONAL,
+ ...
+}
+
+CellSyncBurstInfoItem-CellSyncReconfRqstTDD-ExtIEs NBAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+SYNCDlCodeIdTransReconfInfoLCR-CellSyncReconfRqstTDD ::= SEQUENCE (SIZE (1..maxNrOfSyncFramesLCR)) OF SYNCDlCodeIdTransReconfItemLCR-CellSyncReconfRqstTDD
+
+SYNCDlCodeIdTransReconfItemLCR-CellSyncReconfRqstTDD ::= SEQUENCE {
+ cSBTransmissionID CSBTransmissionID,
+ syncFrameNumberforTransmit SyncFrameNumber,
+ uARFCN UARFCN,
+ sYNCDlCodeId SYNCDlCodeId OPTIONAL,
+ dwPCH-Power DwPCH-Power OPTIONAL,
+ iE-Extensions ProtocolExtensionContainer { { SYNCDlCodeIdTransReconfInfoLCR-CellSyncReconfRqstTDD-ExtIEs} } OPTIONAL,
+ ...
+}
+
+SYNCDlCodeIdTransReconfInfoLCR-CellSyncReconfRqstTDD-ExtIEs NBAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+
+SYNCDlCodeIdMeasInfoLCR-CellSyncReconfRqstTDD::= SEQUENCE {
+ sYNCDlCodeIdMeasInfoList SYNCDlCodeIdMeasInfoList-CellSyncReconfRqstTDD,
+ synchronisationReportType SynchronisationReportType OPTIONAL,
+ synchronisationReportCharacteristics SynchronisationReportCharacteristics OPTIONAL,
+ iE-Extensions ProtocolExtensionContainer { { SYNCDlCodeIdMeasInfoLCR-CellSyncReconfRqstTDD-ExtIEs} } OPTIONAL,
+ ...
+}
+
+SYNCDlCodeIdMeasInfoLCR-CellSyncReconfRqstTDD-ExtIEs NBAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+SYNCDlCodeIdMeasInfoList-CellSyncReconfRqstTDD::= SEQUENCE (SIZE (1.. maxNrOfSyncDLCodesLCR)) OF SYNCDlCodeIdMeasInfoItem-CellSyncReconfRqstTDD
+
+SYNCDlCodeIdMeasInfoItem-CellSyncReconfRqstTDD ::= SEQUENCE {
+ syncFrameNrToReceive SyncFrameNumber,
+ sYNCDlCodeIdInfoLCR SYNCDlCodeIdInfoListLCR-CellSyncReconfRqstTDD,
+ iE-Extensions ProtocolExtensionContainer { { SYNCDlCodeIdMeasInfoItem-CellSyncReconfRqstTDD-ExtIEs} } OPTIONAL,
+ ...
+}
+
+SYNCDlCodeIdMeasInfoItem-CellSyncReconfRqstTDD-ExtIEs NBAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+SYNCDlCodeIdInfoListLCR-CellSyncReconfRqstTDD ::= SEQUENCE (SIZE (1.. maxNrOfReceptionsperSyncFrameLCR)) OF SYNCDlCodeIdInfoItemLCR-CellSyncReconfRqstTDD
+
+SYNCDlCodeIdInfoItemLCR-CellSyncReconfRqstTDD ::= SEQUENCE {
+ cSBMeasurementID CSBMeasurementID,
+ sYNCDlCodeId SYNCDlCodeId,
+ uARFCN UARFCN,
+ propagationDelayCompensation TimingAdjustmentValueLCR OPTIONAL,
+ iE-Extensions ProtocolExtensionContainer { { SYNCDlCodeIdInfoItemLCR-CellSyncReconfRqstTDD-ExtIEs} } OPTIONAL,
+ ...
+}
+
+SYNCDlCodeIdInfoItemLCR-CellSyncReconfRqstTDD-ExtIEs NBAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+-- **************************************************************
+--
+-- CELL SYNCHRONISATION RECONFIGURATION RESPONSE TDD
+--
+-- **************************************************************
+
+CellSynchronisationReconfigurationResponseTDD ::= SEQUENCE {
+ protocolIEs ProtocolIE-Container {{CellSynchronisationReconfigurationResponseTDD-IEs}},
+ protocolExtensions ProtocolExtensionContainer {{CellSynchronisationReconfigurationResponseTDD-Extensions}} OPTIONAL,
+ ...
+}
+
+CellSynchronisationReconfigurationResponseTDD-Extensions NBAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+CellSynchronisationReconfigurationResponseTDD-IEs NBAP-PROTOCOL-IES ::= {
+ { ID id-CriticalityDiagnostics CRITICALITY ignore TYPE CriticalityDiagnostics PRESENCE optional },
+ ...
+}
+
+-- **************************************************************
+--
+-- CELL SYNCHRONISATION RECONFIGURATION FAILURE TDD
+--
+-- **************************************************************
+
+CellSynchronisationReconfigurationFailureTDD ::= SEQUENCE {
+ protocolIEs ProtocolIE-Container {{CellSynchronisationReconfigurationFailureTDD-IEs}},
+ protocolExtensions ProtocolExtensionContainer {{CellSynchronisationReconfigurationFailureTDD-Extensions}} OPTIONAL,
+ ...
+}
+
+CellSynchronisationReconfigurationFailureTDD-Extensions NBAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+CellSynchronisationReconfigurationFailureTDD-IEs NBAP-PROTOCOL-IES ::= {
+ { ID id-Cause CRITICALITY ignore TYPE Cause PRESENCE mandatory }|
+ { ID id-CriticalityDiagnostics CRITICALITY ignore TYPE CriticalityDiagnostics PRESENCE optional },
+ ...
+}
+
+-- **************************************************************
+--
+-- CELL SYNCHRONISATION ADJUSTMENT REQUEST TDD
+--
+-- **************************************************************
+
+CellSynchronisationAdjustmentRequestTDD ::= SEQUENCE {
+ protocolIEs ProtocolIE-Container {{CellSynchronisationAdjustmentRequestTDD-IEs}},
+ protocolExtensions ProtocolExtensionContainer {{CellSynchronisationAdjustmentRequestTDD-Extensions}} OPTIONAL,
+ ...
+}
+
+CellSynchronisationAdjustmentRequestTDD-Extensions NBAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+CellSynchronisationAdjustmentRequestTDD-IEs NBAP-PROTOCOL-IES ::= {
+ { ID id-CellAdjustmentInfo-SyncAdjustmntRqstTDD CRITICALITY ignore TYPE CellAdjustmentInfo-SyncAdjustmentRqstTDD PRESENCE mandatory },
+ ...
+}
+
+CellAdjustmentInfo-SyncAdjustmentRqstTDD::= SEQUENCE (SIZE (1..maxCellinNodeB)) OF ProtocolIE-Single-Container {{ CellAdjustmentInfoItemIE-SyncAdjustmntRqstTDD }}
+
+CellAdjustmentInfoItemIE-SyncAdjustmntRqstTDD NBAP-PROTOCOL-IES ::= {
+ { ID id-CellAdjustmentInfoItem-SyncAdjustmentRqstTDD CRITICALITY ignore TYPE CellAdjustmentInfoItem-SyncAdjustmentRqstTDD PRESENCE mandatory }
+}
+
+CellAdjustmentInfoItem-SyncAdjustmentRqstTDD ::= SEQUENCE {
+ c-ID C-ID,
+ frameAdjustmentValue FrameAdjustmentValue OPTIONAL,
+ timingAdjustmentValue TimingAdjustmentValue OPTIONAL,
+ dLTransPower DL-Power OPTIONAL, -- Applicable to 3.84Mcps TDD only
+ sfn SFN OPTIONAL,
+ iE-Extensions ProtocolExtensionContainer { { CellAdjustmentInfoItem-SyncAdjustmntRqstTDD-ExtIEs} } OPTIONAL,
+ ...
+ }
+
+CellAdjustmentInfoItem-SyncAdjustmntRqstTDD-ExtIEs NBAP-PROTOCOL-EXTENSION ::= {
+ { ID id-DwPCH-Power CRITICALITY ignore EXTENSION DwPCH-Power PRESENCE optional }| -- Applicable to 1.28Mcps TDD only
+ { ID id-TimingAdjustmentValueLCR CRITICALITY ignore EXTENSION TimingAdjustmentValueLCR PRESENCE optional }, -- Applicable to 1.28Mcps TDD only
+ ...
+}
+
+-- **************************************************************
+--
+-- CELL SYNCHRONISATION ADJUSTMENT RESPONSE TDD
+--
+-- **************************************************************
+
+CellSynchronisationAdjustmentResponseTDD ::= SEQUENCE {
+ protocolIEs ProtocolIE-Container {{CellSynchronisationAdjustmentResponseTDD-IEs}},
+ protocolExtensions ProtocolExtensionContainer {{CellSynchronisationAdjustmentResponseTDD-Extensions}} OPTIONAL,
+ ...
+}
+
+CellSynchronisationAdjustmentResponseTDD-Extensions NBAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+CellSynchronisationAdjustmentResponseTDD-IEs NBAP-PROTOCOL-IES ::= {
+ { ID id-CriticalityDiagnostics CRITICALITY ignore TYPE CriticalityDiagnostics PRESENCE optional },
+ ...
+}
+
+-- **************************************************************
+--
+-- CELL SYNCHRONISATION ADJUSTMENT FAILURE TDD
+--
+-- **************************************************************
+
+CellSynchronisationAdjustmentFailureTDD ::= SEQUENCE {
+ protocolIEs ProtocolIE-Container {{CellSynchronisationAdjustmentFailureTDD-IEs}},
+ protocolExtensions ProtocolExtensionContainer {{CellSynchronisationAdjustmentFailureTDD-Extensions}} OPTIONAL,
+ ...
+}
+
+CellSynchronisationAdjustmentFailureTDD-Extensions NBAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+CellSynchronisationAdjustmentFailureTDD-IEs NBAP-PROTOCOL-IES ::= {
+ { ID id-CauseLevel-SyncAdjustmntFailureTDD CRITICALITY ignore TYPE CauseLevel-SyncAdjustmntFailureTDD PRESENCE mandatory }|
+ { ID id-CriticalityDiagnostics CRITICALITY ignore TYPE CriticalityDiagnostics PRESENCE optional },
+ ...
+}
+
+CauseLevel-SyncAdjustmntFailureTDD ::= CHOICE {
+ generalCause GeneralCauseList-SyncAdjustmntFailureTDD,
+ cellSpecificCause CellSpecificCauseList-SyncAdjustmntFailureTDD,
+ ...
+}
+
+GeneralCauseList-SyncAdjustmntFailureTDD::= SEQUENCE {
+ cause Cause,
+ iE-Extensions ProtocolExtensionContainer { { GeneralCauseList-SyncAdjustmntFailureTDD-ExtIEs} } OPTIONAL,
+ ...
+}
+
+GeneralCauseList-SyncAdjustmntFailureTDD-ExtIEs NBAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+CellSpecificCauseList-SyncAdjustmntFailureTDD ::= SEQUENCE {
+ unsuccessful-cell-InformationRespList-SyncAdjustmntFailureTDD Unsuccessful-cell-InformationRespList-SyncAdjustmntFailureTDD,
+ iE-Extensions ProtocolExtensionContainer { { CellSpecificCauseList-SyncAdjustmntFailureTDD-ExtIEs} } OPTIONAL,
+ ...
+}
+
+CellSpecificCauseList-SyncAdjustmntFailureTDD-ExtIEs NBAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+Unsuccessful-cell-InformationRespList-SyncAdjustmntFailureTDD ::= SEQUENCE (SIZE (1..maxCellinNodeB)) OF ProtocolIE-Single-Container {{ Unsuccessful-cell-InformationRespItemIE-SyncAdjustmntFailureTDD }}
+
+Unsuccessful-cell-InformationRespItemIE-SyncAdjustmntFailureTDD NBAP-PROTOCOL-IES ::= {
+ { ID id-Unsuccessful-cell-InformationRespItem-SyncAdjustmntFailureTDD CRITICALITY ignore TYPE Unsuccessful-cell-InformationRespItem-SyncAdjustmntFailureTDD PRESENCE mandatory},
+ ...
+}
+
+Unsuccessful-cell-InformationRespItem-SyncAdjustmntFailureTDD::= SEQUENCE {
+ c-ID C-ID,
+ cause Cause,
+ iE-Extensions ProtocolExtensionContainer { { Unsuccessful-cell-InformationRespItem-SyncAdjustmntFailureTDD-ExtIEs} } OPTIONAL,
+ ...
+}
+
+Unsuccessful-cell-InformationRespItem-SyncAdjustmntFailureTDD-ExtIEs NBAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+-- **************************************************************
+--
+-- CELL SYNCHRONISATION TERMINATION REQUEST TDD
+--
+-- **************************************************************
+
+CellSynchronisationTerminationRequestTDD ::= SEQUENCE {
+ protocolIEs ProtocolIE-Container {{CellSynchronisationTerminationRequestTDD-IEs}},
+ protocolExtensions ProtocolExtensionContainer {{CellSynchronisationTerminationRequestTDD-Extensions}} OPTIONAL,
+ ...
+}
+
+CellSynchronisationTerminationRequestTDD-Extensions NBAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+CellSynchronisationTerminationRequestTDD-IEs NBAP-PROTOCOL-IES ::= {
+ { ID id-C-ID CRITICALITY ignore TYPE C-ID PRESENCE mandatory }|
+ { ID id-CSBTransmissionID CRITICALITY ignore TYPE CSBTransmissionID PRESENCE optional }|
+ { ID id-CSBMeasurementID CRITICALITY ignore TYPE CSBMeasurementID PRESENCE optional },
+ ...
+}
+
+-- **************************************************************
+--
+-- CELL SYNCHRONISATION FAILURE INDICATION TDD
+--
+-- **************************************************************
+
+CellSynchronisationFailureIndicationTDD ::= SEQUENCE {
+ protocolIEs ProtocolIE-Container {{CellSynchronisationFailureIndicationTDD-IEs}},
+ protocolExtensions ProtocolExtensionContainer {{CellSynchronisationFailureIndicationTDD-Extensions}} OPTIONAL,
+ ...
+}
+
+CellSynchronisationFailureIndicationTDD-Extensions NBAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+CellSynchronisationFailureIndicationTDD-IEs NBAP-PROTOCOL-IES ::= {
+ { ID id-C-ID CRITICALITY ignore TYPE C-ID PRESENCE mandatory }|
+ { ID id-CSBTransmissionID CRITICALITY ignore TYPE CSBTransmissionID PRESENCE optional }|
+ { ID id-CSBMeasurementID CRITICALITY ignore TYPE CSBMeasurementID PRESENCE optional }|
+ { ID id-Cause CRITICALITY ignore TYPE Cause PRESENCE mandatory },
+ ...
+}
+
+-- **************************************************************
+--
+-- CELL SYNCHRONISATION REPORT TDD
+--
+-- **************************************************************
+
+CellSynchronisationReportTDD ::= SEQUENCE {
+ protocolIEs ProtocolIE-Container {{CellSynchronisationReportTDD-IEs}},
+ protocolExtensions ProtocolExtensionContainer {{CellSynchronisationReportTDD-Extensions}} OPTIONAL,
+ ...
+}
+
+CellSynchronisationReportTDD-Extensions NBAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+CellSynchronisationReportTDD-IEs NBAP-PROTOCOL-IES ::= {
+ { ID id-CellSyncInfo-CellSyncReprtTDD CRITICALITY ignore TYPE CellSyncInfo-CellSyncReprtTDD PRESENCE mandatory },
+ ...
+}
+
+
+CellSyncInfo-CellSyncReprtTDD ::= SEQUENCE (SIZE (1..maxCellinNodeB)) OF CellSyncInfoItemIE-CellSyncReprtTDD
+
+CellSyncInfoItemIE-CellSyncReprtTDD ::= SEQUENCE {
+ c-ID-CellSyncReprtTDD C-ID-IE-CellSyncReprtTDD,
+ syncReportType-CellSyncReprtTDD SyncReportTypeIE-CellSyncReprtTDD OPTIONAL,
+ ...
+}
+
+C-ID-IE-CellSyncReprtTDD ::= ProtocolIE-Single-Container {{ C-ID-IEs-CellSyncReprtTDD }}
+
+C-ID-IEs-CellSyncReprtTDD NBAP-PROTOCOL-IES ::= {
+ { ID id-C-ID CRITICALITY ignore TYPE C-ID PRESENCE mandatory}
+}
+
+SyncReportTypeIE-CellSyncReprtTDD::= ProtocolIE-Single-Container {{ SyncReportTypeIEs-CellSyncReprtTDD }}
+
+SyncReportTypeIEs-CellSyncReprtTDD NBAP-PROTOCOL-IES ::= {
+ { ID id-SyncReportType-CellSyncReprtTDD CRITICALITY ignore TYPE SyncReportType-CellSyncReprtTDD PRESENCE mandatory}
+}
+
+
+SyncReportType-CellSyncReprtTDD ::= CHOICE {
+ intStdPhSyncInfo-CellSyncReprtTDD IntStdPhCellSyncInfo-CellSyncReprtTDD,
+ lateEntrantCell NULL,
+ frequencyAcquisition NULL,
+ ...
+}
+
+IntStdPhCellSyncInfo-CellSyncReprtTDD ::= SEQUENCE {
+ cellSyncBurstMeasuredInfo CellSyncBurstMeasInfoList-CellSyncReprtTDD,
+ iE-Extensions ProtocolExtensionContainer { { IntStdPhCellSyncInfoList-CellSyncReprtTDD-ExtIEs} } OPTIONAL,
+ ...
+}
+
+IntStdPhCellSyncInfoList-CellSyncReprtTDD-ExtIEs NBAP-PROTOCOL-EXTENSION ::= {
+ { ID id-AccumulatedClockupdate-CellSyncReprtTDD CRITICALITY ignore EXTENSION TimingAdjustmentValue PRESENCE optional }|
+ { ID id-SyncDLCodeIdsMeasInfoList-CellSyncReprtTDD CRITICALITY ignore EXTENSION SyncDLCodeIdsMeasInfoList-CellSyncReprtTDD PRESENCE optional }, -- Mandatory for 1.28Mcps TDD. Not Applicable to 3.84Mcps TDD.
+ ...
+}
+
+CellSyncBurstMeasInfoList-CellSyncReprtTDD ::= SEQUENCE (SIZE (0.. maxNrOfCellSyncBursts)) OF CellSyncBurstMeasInfoItem-CellSyncReprtTDD -- Mandatory for 3.84Mcps TDD. Not Applicable to 1.28Mcps TDD.
+
+CellSyncBurstMeasInfoItem-CellSyncReprtTDD ::= SEQUENCE {
+ sFN SFN,
+ cellSyncBurstInfo-CellSyncReprtTDD SEQUENCE (SIZE (1..maxNrOfReceptsPerSyncFrame)) OF CellSyncBurstInfo-CellSyncReprtTDD,
+ iE-Extensions ProtocolExtensionContainer { { CellSyncBurstMeasInfoItem-CellSyncReprtTDD-ExtIEs} } OPTIONAL,
+ ...
+}
+
+CellSyncBurstMeasInfoItem-CellSyncReprtTDD-ExtIEs NBAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+CellSyncBurstInfo-CellSyncReprtTDD ::= CHOICE {
+ cellSyncBurstAvailable CellSyncBurstAvailable-CellSyncReprtTDD,
+ cellSyncBurstNotAvailable NULL,
+ ...
+}
+
+CellSyncBurstAvailable-CellSyncReprtTDD ::= SEQUENCE {
+ cellSyncBurstTiming CellSyncBurstTiming,
+ cellSyncBurstSIR CellSyncBurstSIR,
+ iE-Extensions ProtocolExtensionContainer { { CellSyncBurstAvailable-CellSyncReprtTDD-ExtIEs} } OPTIONAL,
+ ...
+}
+
+CellSyncBurstAvailable-CellSyncReprtTDD-ExtIEs NBAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+SyncDLCodeIdsMeasInfoList-CellSyncReprtTDD ::= SEQUENCE (SIZE (0..maxNrOfSyncFramesLCR)) OF SyncDLCodeIdsMeasInfoItem-CellSyncReprtTDD
+-- Mandatory for 1.28Mcps TDD. Not Applicable to 3.84Mcps TDD.
+
+SyncDLCodeIdsMeasInfoItem-CellSyncReprtTDD ::= SEQUENCE {
+ sFN SFN,
+ syncDLCodeIdInfo-CellSyncReprtTDD SyncDLCodeIdInfo-CellSyncReprtTDD,
+ iE-Extensions ProtocolExtensionContainer { { SyncDLCodeIdsMeasInfoItem-CellSyncReprtTDD-ExtIEs } } OPTIONAL,
+ ...
+}
+
+SyncDLCodeIdsMeasInfoItem-CellSyncReprtTDD-ExtIEs NBAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+SyncDLCodeIdInfo-CellSyncReprtTDD ::= SEQUENCE (SIZE (1..maxNrOfReceptionsperSyncFrameLCR)) OF SyncDLCodeIdItem-CellSyncReprtTDD
+
+SyncDLCodeIdItem-CellSyncReprtTDD ::= CHOICE {
+ syncDLCodeIdAvailable SyncDLCodeIdAvailable-CellSyncReprtTDD,
+ syncDLCodeIDNotAvailable NULL,
+ ...
+}
+
+SyncDLCodeIdAvailable-CellSyncReprtTDD ::= SEQUENCE {
+ syncDLCodeIdTiming CellSyncBurstTimingLCR,
+ syncDLCodeIdSIR CellSyncBurstSIR,
+ iE-Extensions ProtocolExtensionContainer { { SyncDLCodeIdAvailable-CellSyncReprtTDD-ExtIEs } } OPTIONAL,
+ ...
+}
+
+SyncDLCodeIdAvailable-CellSyncReprtTDD-ExtIEs NBAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+-- **************************************************************
+--
+-- BEARER REARRANGEMENT INDICATION
+--
+-- **************************************************************
+
+BearerRearrangementIndication ::= SEQUENCE {
+ protocolIEs ProtocolIE-Container {{BearerRearrangementIndication-IEs}},
+ protocolExtensions ProtocolExtensionContainer {{BearerRearrangementIndication-Extensions}} OPTIONAL,
+ ...
+}
+
+BearerRearrangementIndication-IEs NBAP-PROTOCOL-IES ::= {
+ { ID id-CRNC-CommunicationContextID CRITICALITY ignore TYPE CRNC-CommunicationContextID PRESENCE mandatory } |
+ { ID id-SignallingBearerRequestIndicator CRITICALITY ignore TYPE SignallingBearerRequestIndicator PRESENCE optional } |
+ { ID id-DCH-RearrangeList-Bearer-RearrangeInd CRITICALITY ignore TYPE DCH-RearrangeList-Bearer-RearrangeInd PRESENCE optional } |
+ { ID id-DSCH-RearrangeList-Bearer-RearrangeInd CRITICALITY ignore TYPE DSCH-RearrangeList-Bearer-RearrangeInd PRESENCE optional } |
+ { ID id-USCH-RearrangeList-Bearer-RearrangeInd CRITICALITY ignore TYPE USCH-RearrangeList-Bearer-RearrangeInd PRESENCE optional } |
+-- TDD only.
+ { ID id-TFCI2BearerRequestIndicator CRITICALITY ignore TYPE TFCI2BearerRequestIndicator PRESENCE optional }|
+ -- FDD only.
+ { ID id-HSDSCH-RearrangeList-Bearer-RearrangeInd CRITICALITY ignore TYPE HSDSCH-RearrangeList-Bearer-RearrangeInd PRESENCE optional },
+ ...
+}
+
+BearerRearrangementIndication-Extensions NBAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+DCH-RearrangeList-Bearer-RearrangeInd ::= SEQUENCE (SIZE (1..maxNrOfDCHs)) OF DCH-RearrangeItem-Bearer-RearrangeInd
+
+DCH-RearrangeItem-Bearer-RearrangeInd ::= SEQUENCE {
+ dCH-ID DCH-ID,
+ iE-Extensions ProtocolExtensionContainer { { DCH-RearrangeItem-Bearer-RearrangeInd-ExtIEs} } OPTIONAL,
+ ...
+}
+
+DCH-RearrangeItem-Bearer-RearrangeInd-ExtIEs NBAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+DSCH-RearrangeList-Bearer-RearrangeInd ::= SEQUENCE (SIZE (1..maxNrOfDSCHs)) OF DSCH-RearrangeItem-Bearer-RearrangeInd
+
+DSCH-RearrangeItem-Bearer-RearrangeInd ::= SEQUENCE {
+ dSCH-ID DSCH-ID,
+ iE-Extensions ProtocolExtensionContainer { { DSCH-RearrangeItem-Bearer-RearrangeInd-ExtIEs} } OPTIONAL,
+ ...
+}
+
+DSCH-RearrangeItem-Bearer-RearrangeInd-ExtIEs NBAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+USCH-RearrangeList-Bearer-RearrangeInd ::= SEQUENCE (SIZE (1..maxNrOfUSCHs)) OF USCH-RearrangeItem-Bearer-RearrangeInd
+
+USCH-RearrangeItem-Bearer-RearrangeInd ::= SEQUENCE {
+ uSCH-ID USCH-ID,
+ iE-Extensions ProtocolExtensionContainer { { USCH-RearrangeItem-Bearer-RearrangeInd-ExtIEs} } OPTIONAL,
+ ...
+}
+
+USCH-RearrangeItem-Bearer-RearrangeInd-ExtIEs NBAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+HSDSCH-RearrangeList-Bearer-RearrangeInd ::= SEQUENCE (SIZE (1..maxNrOfMACdFlows)) OF HSDSCH-RearrangeItem-Bearer-RearrangeInd
+
+HSDSCH-RearrangeItem-Bearer-RearrangeInd ::= SEQUENCE {
+ hsDSCH-MACdFlow-ID HSDSCH-MACdFlow-ID,
+ iE-Extensions ProtocolExtensionContainer { { HSDSCH-RearrangeItem-Bearer-RearrangeInd-ExtIEs} } OPTIONAL,
+ ...
+}
+
+HSDSCH-RearrangeItem-Bearer-RearrangeInd-ExtIEs NBAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+-- **************************************************************
+--
+-- RADIO LINK ACTIVATION COMMAND FDD
+--
+-- **************************************************************
+
+RadioLinkActivationCommandFDD ::= SEQUENCE {
+ protocolIEs ProtocolIE-Container {{RadioLinkActivationCommandFDD-IEs}},
+ protocolExtensions ProtocolExtensionContainer {{RadioLinkActivationCommandFDD-Extensions}} OPTIONAL,
+ ...
+}
+
+RadioLinkActivationCommandFDD-IEs NBAP-PROTOCOL-IES ::= {
+ { ID id-NodeB-CommunicationContextID CRITICALITY ignore TYPE NodeB-CommunicationContextID PRESENCE mandatory }|
+ { ID id-DelayedActivationList-RL-ActivationCmdFDD CRITICALITY ignore TYPE DelayedActivationInformationList-RL-ActivationCmdFDD PRESENCE mandatory },
+ ...
+}
+
+RadioLinkActivationCommandFDD-Extensions NBAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+DelayedActivationInformationList-RL-ActivationCmdFDD ::= SEQUENCE (SIZE (1..maxNrOfRLs)) OF ProtocolIE-Single-Container {
+ { DelayedActivationInformation-RL-ActivationCmdFDD-IEs} }
+
+DelayedActivationInformation-RL-ActivationCmdFDD-IEs NBAP-PROTOCOL-IES ::= {
+ { ID id-DelayedActivationInformation-RL-ActivationCmdFDD CRITICALITY ignore TYPE DelayedActivationInformation-RL-ActivationCmdFDD PRESENCE optional }
+}
+
+DelayedActivationInformation-RL-ActivationCmdFDD ::= SEQUENCE {
+ rL-ID RL-ID,
+ delayed-activation-update DelayedActivationUpdate,
+ iE-Extensions ProtocolExtensionContainer { { DelayedActivationInformation-RL-ActivationCmdFDD-ExtIEs} } OPTIONAL,
+ ...
+}
+
+DelayedActivationInformation-RL-ActivationCmdFDD-ExtIEs NBAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+-- **************************************************************
+--
+-- RADIO LINK ACTIVATION COMMAND TDD
+--
+-- **************************************************************
+
+RadioLinkActivationCommandTDD ::= SEQUENCE {
+ protocolIEs ProtocolIE-Container {{RadioLinkActivationCommandTDD-IEs}},
+ protocolExtensions ProtocolExtensionContainer {{RadioLinkActivationCommandTDD-Extensions}} OPTIONAL,
+ ...
+}
+
+RadioLinkActivationCommandTDD-IEs NBAP-PROTOCOL-IES ::= {
+ { ID id-NodeB-CommunicationContextID CRITICALITY ignore TYPE NodeB-CommunicationContextID PRESENCE mandatory }|
+ { ID id-DelayedActivationList-RL-ActivationCmdTDD CRITICALITY ignore TYPE DelayedActivationInformationList-RL-ActivationCmdTDD PRESENCE mandatory },
+ ...
+}
+
+RadioLinkActivationCommandTDD-Extensions NBAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+DelayedActivationInformationList-RL-ActivationCmdTDD ::= SEQUENCE (SIZE (1..maxNrOfRLs)) OF ProtocolIE-Single-Container {
+ { DelayedActivationInformation-RL-ActivationCmdTDD-IEs} }
+
+DelayedActivationInformation-RL-ActivationCmdTDD-IEs NBAP-PROTOCOL-IES ::= {
+ { ID id-DelayedActivationInformation-RL-ActivationCmdTDD CRITICALITY ignore TYPE DelayedActivationInformation-RL-ActivationCmdTDD PRESENCE optional }
+}
+
+DelayedActivationInformation-RL-ActivationCmdTDD ::= SEQUENCE {
+ rL-ID RL-ID,
+ delayed-activation-update DelayedActivationUpdate,
+ iE-Extensions ProtocolExtensionContainer { { DelayedActivationInformation-RL-ActivationCmdTDD-ExtIEs} } OPTIONAL,
+ ...
+}
+
+DelayedActivationInformation-RL-ActivationCmdTDD-ExtIEs NBAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+-- **************************************************************
+--
+-- RADIO LINK PARAMETER UPDATE INDICATION FDD
+--
+-- **************************************************************
+
+RadioLinkParameterUpdateIndicationFDD ::= SEQUENCE {
+ protocolIEs ProtocolIE-Container {{RadioLinkParameterUpdateIndicationFDD-IEs}},
+ protocolExtensions ProtocolExtensionContainer {{RadioLinkParameterUpdateIndicationFDD-Extensions}} OPTIONAL,
+ ...
+}
+
+RadioLinkParameterUpdateIndicationFDD-IEs NBAP-PROTOCOL-IES ::= {
+ { ID id-CRNC-CommunicationContextID CRITICALITY ignore TYPE CRNC-CommunicationContextID PRESENCE mandatory } |
+ { ID id-HSDSCH-FDD-Update-Information CRITICALITY ignore TYPE HSDSCH-FDD-Update-Information PRESENCE optional },
+ ...
+}
+
+RadioLinkParameterUpdateIndicationFDD-Extensions NBAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+-- **************************************************************
+--
+-- RADIO LINK PARAMETER UPDATE INDICATION TDD
+--
+-- **************************************************************
+
+RadioLinkParameterUpdateIndicationTDD ::= SEQUENCE {
+ protocolIEs ProtocolIE-Container {{RadioLinkParameterUpdateIndicationTDD-IEs}},
+ protocolExtensions ProtocolExtensionContainer {{RadioLinkParameterUpdateIndicationTDD-Extensions}} OPTIONAL,
+ ...
+}
+
+RadioLinkParameterUpdateIndicationTDD-IEs NBAP-PROTOCOL-IES ::= {
+ { ID id-CRNC-CommunicationContextID CRITICALITY ignore TYPE CRNC-CommunicationContextID PRESENCE mandatory } |
+ { ID id-HSDSCH-TDD-Update-Information CRITICALITY ignore TYPE HSDSCH-TDD-Update-Information PRESENCE optional },
+ ...
+}
+
+RadioLinkParameterUpdateIndicationTDD-Extensions NBAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+END
diff --git a/lib/asn1/test/asn1_SUITE_data/nbapsystem/NBAP-PDU-Discriptions.asn b/lib/asn1/test/asn1_SUITE_data/nbapsystem/NBAP-PDU-Discriptions.asn
new file mode 100755
index 0000000000..b9be9934e4
--- /dev/null
+++ b/lib/asn1/test/asn1_SUITE_data/nbapsystem/NBAP-PDU-Discriptions.asn
@@ -0,0 +1,916 @@
+-- **************************************************************
+--
+-- Elementary Procedure definitions
+--
+-- **************************************************************
+
+NBAP-PDU-Discriptions {
+itu-t (0) identified-organization (4) etsi (0) mobileDomain (0)
+umts-Access (20) modules (3) nbap (2) version1 (1) nbap-PDU-Descriptions (0) }
+
+DEFINITIONS AUTOMATIC TAGS ::=
+
+BEGIN
+
+-- **************************************************************
+--
+-- IE parameter types from other modules.
+--
+-- **************************************************************
+
+IMPORTS
+ Criticality,
+ ProcedureID,
+ MessageDiscriminator,
+ TransactionID
+FROM NBAP-CommonDataTypes
+
+ CommonTransportChannelSetupRequestFDD,
+ CommonTransportChannelSetupRequestTDD,
+ CommonTransportChannelSetupResponse,
+ CommonTransportChannelSetupFailure,
+ CommonTransportChannelReconfigurationRequestFDD,
+ CommonTransportChannelReconfigurationRequestTDD,
+ CommonTransportChannelReconfigurationResponse,
+ CommonTransportChannelReconfigurationFailure,
+ CommonTransportChannelDeletionRequest,
+ CommonTransportChannelDeletionResponse,
+ BlockResourceRequest,
+ BlockResourceResponse,
+ BlockResourceFailure,
+ UnblockResourceIndication,
+ AuditFailure,
+ AuditRequiredIndication,
+ AuditRequest,
+ AuditResponse,
+ CommonMeasurementInitiationRequest,
+ CommonMeasurementInitiationResponse,
+ CommonMeasurementInitiationFailure,
+ CommonMeasurementReport,
+ CommonMeasurementTerminationRequest,
+ CommonMeasurementFailureIndication,
+ CellSetupRequestFDD,
+ CellSetupRequestTDD,
+ CellSetupResponse,
+ CellSetupFailure,
+ CellReconfigurationRequestFDD,
+ CellReconfigurationRequestTDD,
+ CellReconfigurationResponse,
+ CellReconfigurationFailure,
+ CellDeletionRequest,
+ CellDeletionResponse,
+ InformationExchangeInitiationRequest,
+ InformationExchangeInitiationResponse,
+ InformationExchangeInitiationFailure,
+ InformationReport,
+ InformationExchangeTerminationRequest,
+ InformationExchangeFailureIndication,
+ BearerRearrangementIndication,
+ ResourceStatusIndication,
+ SystemInformationUpdateRequest,
+ SystemInformationUpdateResponse,
+ SystemInformationUpdateFailure,
+ ResetRequest,
+ ResetResponse,
+ RadioLinkActivationCommandFDD,
+ RadioLinkActivationCommandTDD,
+ RadioLinkPreemptionRequiredIndication,
+ RadioLinkSetupRequestFDD,
+ RadioLinkSetupRequestTDD,
+ RadioLinkSetupResponseFDD,
+ RadioLinkSetupResponseTDD,
+ RadioLinkSetupFailureFDD,
+ RadioLinkSetupFailureTDD,
+ RadioLinkAdditionRequestFDD,
+ RadioLinkAdditionRequestTDD,
+ RadioLinkAdditionResponseFDD,
+ RadioLinkAdditionResponseTDD,
+ RadioLinkAdditionFailureFDD,
+ RadioLinkAdditionFailureTDD,
+ RadioLinkParameterUpdateIndicationFDD,
+ RadioLinkParameterUpdateIndicationTDD,
+ RadioLinkReconfigurationPrepareFDD,
+ RadioLinkReconfigurationPrepareTDD,
+ RadioLinkReconfigurationReady,
+ RadioLinkReconfigurationFailure,
+ RadioLinkReconfigurationCommit,
+ RadioLinkReconfigurationCancel,
+ RadioLinkReconfigurationRequestFDD,
+ RadioLinkReconfigurationRequestTDD,
+ RadioLinkReconfigurationResponse,
+ RadioLinkDeletionRequest,
+ RadioLinkDeletionResponse,
+ DL-PowerControlRequest,
+ DL-PowerTimeslotControlRequest,
+ DedicatedMeasurementInitiationRequest,
+ DedicatedMeasurementInitiationResponse,
+ DedicatedMeasurementInitiationFailure,
+ DedicatedMeasurementReport,
+ DedicatedMeasurementTerminationRequest,
+ DedicatedMeasurementFailureIndication,
+ RadioLinkFailureIndication,
+ RadioLinkRestoreIndication,
+ CompressedModeCommand,
+ ErrorIndication,
+ PrivateMessage,
+ PhysicalSharedChannelReconfigurationRequestTDD,
+ PhysicalSharedChannelReconfigurationRequestFDD,
+ PhysicalSharedChannelReconfigurationResponse,
+ PhysicalSharedChannelReconfigurationFailure,
+ CellSynchronisationInitiationRequestTDD,
+ CellSynchronisationInitiationResponseTDD,
+ CellSynchronisationInitiationFailureTDD,
+ CellSynchronisationReconfigurationRequestTDD,
+ CellSynchronisationReconfigurationResponseTDD,
+ CellSynchronisationReconfigurationFailureTDD,
+ CellSynchronisationAdjustmentRequestTDD,
+ CellSynchronisationAdjustmentResponseTDD,
+ CellSynchronisationAdjustmentFailureTDD,
+ CellSynchronisationReportTDD,
+ CellSynchronisationTerminationRequestTDD,
+ CellSynchronisationFailureIndicationTDD
+FROM NBAP-PDU-Contents
+
+ id-audit,
+ id-auditRequired,
+ id-blockResource,
+ id-cellDeletion,
+ id-cellReconfiguration,
+ id-cellSetup,
+ id-cellSynchronisationInitiation,
+ id-cellSynchronisationReconfiguration,
+ id-cellSynchronisationReporting,
+ id-cellSynchronisationTermination,
+ id-cellSynchronisationFailure,
+ id-commonMeasurementFailure,
+ id-commonMeasurementInitiation,
+ id-commonMeasurementReport,
+ id-commonMeasurementTermination,
+ id-commonTransportChannelDelete,
+ id-commonTransportChannelReconfigure,
+ id-commonTransportChannelSetup,
+ id-compressedModeCommand,
+ id-dedicatedMeasurementFailure,
+ id-dedicatedMeasurementInitiation,
+ id-dedicatedMeasurementReport,
+ id-dedicatedMeasurementTermination,
+ id-downlinkPowerControl,
+ id-downlinkPowerTimeslotControl,
+ id-errorIndicationForDedicated,
+ id-errorIndicationForCommon,
+ id-informationExchangeFailure,
+ id-informationExchangeInitiation,
+ id-informationReporting,
+ id-informationExchangeTermination,
+ id-BearerRearrangement,
+ id-physicalSharedChannelReconfiguration,
+ id-privateMessageForDedicated,
+ id-privateMessageForCommon,
+ id-radioLinkActivation,
+ id-radioLinkAddition,
+ id-radioLinkDeletion,
+ id-radioLinkFailure,
+ id-radioLinkParameterUpdate,
+ id-radioLinkPreemption,
+ id-radioLinkRestoration,
+ id-radioLinkSetup,
+ id-reset,
+ id-resourceStatusIndication,
+ id-cellSynchronisationAdjustment,
+ id-synchronisedRadioLinkReconfigurationCancellation,
+ id-synchronisedRadioLinkReconfigurationCommit,
+ id-synchronisedRadioLinkReconfigurationPreparation,
+ id-systemInformationUpdate,
+ id-unblockResource,
+ id-unSynchronisedRadioLinkReconfiguration
+FROM NBAP-Constants;
+
+-- **************************************************************
+--
+-- Interface Elementary Procedure Class
+--
+-- **************************************************************
+
+NBAP-ELEMENTARY-PROCEDURE ::= CLASS {
+ &InitiatingMessage ,
+ &SuccessfulOutcome OPTIONAL,
+ &UnsuccessfulOutcome OPTIONAL,
+ &Outcome OPTIONAL,
+ &messageDiscriminator MessageDiscriminator,
+ &procedureID ProcedureID UNIQUE,
+ &criticality Criticality DEFAULT ignore
+}
+
+WITH SYNTAX {
+ INITIATING MESSAGE &InitiatingMessage
+ [SUCCESSFUL OUTCOME &SuccessfulOutcome]
+ [UNSUCCESSFUL OUTCOME &UnsuccessfulOutcome]
+ [OUTCOME &Outcome]
+ MESSAGE DISCRIMINATOR &messageDiscriminator
+ PROCEDURE ID &procedureID
+ [CRITICALITY &criticality]
+}
+
+-- **************************************************************
+--
+-- Interface PDU Definition
+--
+-- **************************************************************
+
+NBAP-PDU ::= CHOICE {
+ initiatingMessage InitiatingMessage,
+ succesfulOutcome SuccessfulOutcome,
+ unsuccesfulOutcome UnsuccessfulOutcome,
+ outcome Outcome,
+ ...
+}
+
+InitiatingMessage ::= SEQUENCE {
+ procedureID NBAP-ELEMENTARY-PROCEDURE.&procedureID ({NBAP-ELEMENTARY-PROCEDURES}),
+ criticality NBAP-ELEMENTARY-PROCEDURE.&criticality ({NBAP-ELEMENTARY-PROCEDURES}{@procedureID}),
+ messageDiscriminator NBAP-ELEMENTARY-PROCEDURE.&messageDiscriminator({NBAP-ELEMENTARY-PROCEDURES}{@procedureID}),
+ transactionID TransactionID,
+ value NBAP-ELEMENTARY-PROCEDURE.&InitiatingMessage({NBAP-ELEMENTARY-PROCEDURES}{@procedureID})
+}
+
+SuccessfulOutcome ::= SEQUENCE {
+ procedureID NBAP-ELEMENTARY-PROCEDURE.&procedureID ({NBAP-ELEMENTARY-PROCEDURES}),
+ criticality NBAP-ELEMENTARY-PROCEDURE.&criticality ({NBAP-ELEMENTARY-PROCEDURES}{@procedureID}),
+ messageDiscriminator NBAP-ELEMENTARY-PROCEDURE.&messageDiscriminator({NBAP-ELEMENTARY-PROCEDURES}{@procedureID}),
+ transactionID TransactionID,
+ value NBAP-ELEMENTARY-PROCEDURE.&SuccessfulOutcome({NBAP-ELEMENTARY-PROCEDURES}{@procedureID})
+}
+
+UnsuccessfulOutcome ::= SEQUENCE {
+ procedureID NBAP-ELEMENTARY-PROCEDURE.&procedureID ({NBAP-ELEMENTARY-PROCEDURES}),
+ criticality NBAP-ELEMENTARY-PROCEDURE.&criticality ({NBAP-ELEMENTARY-PROCEDURES}{@procedureID}),
+ messageDiscriminator NBAP-ELEMENTARY-PROCEDURE.&messageDiscriminator({NBAP-ELEMENTARY-PROCEDURES}{@procedureID}),
+ transactionID TransactionID,
+ value NBAP-ELEMENTARY-PROCEDURE.&UnsuccessfulOutcome({NBAP-ELEMENTARY-PROCEDURES}{@procedureID})
+}
+
+Outcome ::= SEQUENCE {
+ procedureID NBAP-ELEMENTARY-PROCEDURE.&procedureID ({NBAP-ELEMENTARY-PROCEDURES}),
+ criticality NBAP-ELEMENTARY-PROCEDURE.&criticality ({NBAP-ELEMENTARY-PROCEDURES}{@procedureID}),
+ messageDiscriminator NBAP-ELEMENTARY-PROCEDURE.&messageDiscriminator({NBAP-ELEMENTARY-PROCEDURES}{@procedureID}),
+ transactionID TransactionID,
+ value NBAP-ELEMENTARY-PROCEDURE.&Outcome ({NBAP-ELEMENTARY-PROCEDURES}{@procedureID})
+}
+
+-- **************************************************************
+--
+-- Interface Elementary Procedure List
+--
+-- **************************************************************
+
+NBAP-ELEMENTARY-PROCEDURES NBAP-ELEMENTARY-PROCEDURE ::= {
+ NBAP-ELEMENTARY-PROCEDURES-CLASS-1 |
+ NBAP-ELEMENTARY-PROCEDURES-CLASS-2 ,
+ ...
+}
+
+NBAP-ELEMENTARY-PROCEDURES-CLASS-1 NBAP-ELEMENTARY-PROCEDURE ::= {
+ cellSetupFDD |
+ cellSetupTDD |
+ cellReconfigurationFDD |
+ cellReconfigurationTDD |
+ cellDeletion |
+ commonTransportChannelSetupFDD |
+ commonTransportChannelSetupTDD |
+ commonTransportChannelReconfigureFDD |
+ commonTransportChannelReconfigureTDD |
+ commonTransportChannelDelete |
+ audit |
+ blockResource |
+ radioLinkSetupFDD |
+ radioLinkSetupTDD |
+ systemInformationUpdate |
+ commonMeasurementInitiation |
+ radioLinkAdditionFDD |
+ radioLinkAdditionTDD |
+ radioLinkDeletion |
+ reset |
+ synchronisedRadioLinkReconfigurationPreparationFDD |
+ synchronisedRadioLinkReconfigurationPreparationTDD |
+ unSynchronisedRadioLinkReconfigurationFDD |
+ unSynchronisedRadioLinkReconfigurationTDD |
+ dedicatedMeasurementInitiation |
+ physicalSharedChannelReconfigurationTDD ,
+ ...,
+ informationExchangeInitiation |
+ cellSynchronisationInitiationTDD |
+ cellSynchronisationReconfigurationTDD |
+ cellSynchronisationAdjustmentTDD |
+ physicalSharedChannelReconfigurationFDD
+}
+
+NBAP-ELEMENTARY-PROCEDURES-CLASS-2 NBAP-ELEMENTARY-PROCEDURE ::= {
+ resourceStatusIndication |
+ auditRequired |
+ commonMeasurementReport |
+ commonMeasurementTermination |
+ commonMeasurementFailure |
+ synchronisedRadioLinkReconfigurationCommit |
+ synchronisedRadioLinkReconfigurationCancellation |
+ radioLinkFailure |
+ radioLinkPreemption |
+ radioLinkRestoration |
+ dedicatedMeasurementReport |
+ dedicatedMeasurementTermination |
+ dedicatedMeasurementFailure |
+ downlinkPowerControlFDD |
+ downlinkPowerTimeslotControl |
+ compressedModeCommand |
+ unblockResource |
+ errorIndicationForDedicated |
+ errorIndicationForCommon |
+ privateMessageForDedicated |
+ privateMessageForCommon ,
+ ...,
+ informationReporting |
+ informationExchangeTermination |
+ informationExchangeFailure |
+ cellSynchronisationReportingTDD |
+ cellSynchronisationTerminationTDD |
+ cellSynchronisationFailureTDD |
+ bearerRearrangement |
+ radioLinkActivationFDD |
+ radioLinkActivationTDD |
+ radioLinkParameterUpdateFDD |
+ radioLinkParameterUpdateTDD
+}
+
+-- **************************************************************
+--
+-- Interface Elementary Procedures
+--
+-- **************************************************************
+
+-- Class 1
+
+-- *** CellSetup (FDD) ***
+cellSetupFDD NBAP-ELEMENTARY-PROCEDURE ::= {
+ INITIATING MESSAGE CellSetupRequestFDD
+ SUCCESSFUL OUTCOME CellSetupResponse
+ UNSUCCESSFUL OUTCOME CellSetupFailure
+ MESSAGE DISCRIMINATOR common
+ PROCEDURE ID { procedureCode id-cellSetup, ddMode fdd }
+ CRITICALITY reject
+}
+
+-- *** CellSetup (TDD) ***
+cellSetupTDD NBAP-ELEMENTARY-PROCEDURE ::= {
+ INITIATING MESSAGE CellSetupRequestTDD
+ SUCCESSFUL OUTCOME CellSetupResponse
+ UNSUCCESSFUL OUTCOME CellSetupFailure
+ MESSAGE DISCRIMINATOR common
+ PROCEDURE ID { procedureCode id-cellSetup, ddMode tdd }
+ CRITICALITY reject
+}
+
+-- *** CellReconfiguration(FDD) ***
+cellReconfigurationFDD NBAP-ELEMENTARY-PROCEDURE ::= {
+ INITIATING MESSAGE CellReconfigurationRequestFDD
+ SUCCESSFUL OUTCOME CellReconfigurationResponse
+ UNSUCCESSFUL OUTCOME CellReconfigurationFailure
+ MESSAGE DISCRIMINATOR common
+ PROCEDURE ID { procedureCode id-cellReconfiguration, ddMode fdd }
+ CRITICALITY reject
+}
+
+-- *** CellReconfiguration(TDD) ***
+cellReconfigurationTDD NBAP-ELEMENTARY-PROCEDURE ::= {
+ INITIATING MESSAGE CellReconfigurationRequestTDD
+ SUCCESSFUL OUTCOME CellReconfigurationResponse
+ UNSUCCESSFUL OUTCOME CellReconfigurationFailure
+ MESSAGE DISCRIMINATOR common
+ PROCEDURE ID { procedureCode id-cellReconfiguration, ddMode tdd }
+ CRITICALITY reject
+}
+
+-- *** CellDeletion ***
+cellDeletion NBAP-ELEMENTARY-PROCEDURE ::= {
+ INITIATING MESSAGE CellDeletionRequest
+ SUCCESSFUL OUTCOME CellDeletionResponse
+ MESSAGE DISCRIMINATOR common
+ PROCEDURE ID { procedureCode id-cellDeletion, ddMode common }
+ CRITICALITY reject
+}
+
+-- *** CommonTransportChannelSetup (FDD) ***
+commonTransportChannelSetupFDD NBAP-ELEMENTARY-PROCEDURE ::= {
+ INITIATING MESSAGE CommonTransportChannelSetupRequestFDD
+ SUCCESSFUL OUTCOME CommonTransportChannelSetupResponse
+ UNSUCCESSFUL OUTCOME CommonTransportChannelSetupFailure
+ MESSAGE DISCRIMINATOR common
+ PROCEDURE ID { procedureCode id-commonTransportChannelSetup, ddMode fdd }
+ CRITICALITY reject
+}
+
+-- *** CommonTransportChannelSetup (TDD) ***
+commonTransportChannelSetupTDD NBAP-ELEMENTARY-PROCEDURE ::= {
+ INITIATING MESSAGE CommonTransportChannelSetupRequestTDD
+ SUCCESSFUL OUTCOME CommonTransportChannelSetupResponse
+ UNSUCCESSFUL OUTCOME CommonTransportChannelSetupFailure
+ MESSAGE DISCRIMINATOR common
+ PROCEDURE ID { procedureCode id-commonTransportChannelSetup, ddMode tdd }
+ CRITICALITY reject
+}
+
+-- *** CommonTransportChannelReconfigure (FDD) ***
+commonTransportChannelReconfigureFDD NBAP-ELEMENTARY-PROCEDURE ::= {
+ INITIATING MESSAGE CommonTransportChannelReconfigurationRequestFDD
+ SUCCESSFUL OUTCOME CommonTransportChannelReconfigurationResponse
+ UNSUCCESSFUL OUTCOME CommonTransportChannelReconfigurationFailure
+ MESSAGE DISCRIMINATOR common
+ PROCEDURE ID { procedureCode id-commonTransportChannelReconfigure, ddMode fdd }
+ CRITICALITY reject
+}
+
+-- *** CommonTransportChannelReconfigure (TDD) ***
+commonTransportChannelReconfigureTDD NBAP-ELEMENTARY-PROCEDURE ::= {
+ INITIATING MESSAGE CommonTransportChannelReconfigurationRequestTDD
+ SUCCESSFUL OUTCOME CommonTransportChannelReconfigurationResponse
+ UNSUCCESSFUL OUTCOME CommonTransportChannelReconfigurationFailure
+ MESSAGE DISCRIMINATOR common
+ PROCEDURE ID { procedureCode id-commonTransportChannelReconfigure, ddMode tdd }
+ CRITICALITY reject
+}
+
+-- *** CommonTransportChannelDelete ***
+commonTransportChannelDelete NBAP-ELEMENTARY-PROCEDURE ::= {
+ INITIATING MESSAGE CommonTransportChannelDeletionRequest
+ SUCCESSFUL OUTCOME CommonTransportChannelDeletionResponse
+ MESSAGE DISCRIMINATOR common
+ PROCEDURE ID { procedureCode id-commonTransportChannelDelete, ddMode common }
+ CRITICALITY reject
+}
+
+-- *** Audit ***
+audit NBAP-ELEMENTARY-PROCEDURE ::= {
+ INITIATING MESSAGE AuditRequest
+ SUCCESSFUL OUTCOME AuditResponse
+ UNSUCCESSFUL OUTCOME AuditFailure
+ MESSAGE DISCRIMINATOR common
+ PROCEDURE ID { procedureCode id-audit, ddMode common }
+ CRITICALITY reject
+}
+
+-- *** BlockResourceRequest ***
+blockResource NBAP-ELEMENTARY-PROCEDURE ::= {
+ INITIATING MESSAGE BlockResourceRequest
+ SUCCESSFUL OUTCOME BlockResourceResponse
+ UNSUCCESSFUL OUTCOME BlockResourceFailure
+ MESSAGE DISCRIMINATOR common
+ PROCEDURE ID { procedureCode id-blockResource, ddMode common }
+ CRITICALITY reject
+}
+
+-- *** RadioLinkSetup (FDD) ***
+radioLinkSetupFDD NBAP-ELEMENTARY-PROCEDURE ::= {
+ INITIATING MESSAGE RadioLinkSetupRequestFDD
+ SUCCESSFUL OUTCOME RadioLinkSetupResponseFDD
+ UNSUCCESSFUL OUTCOME RadioLinkSetupFailureFDD
+ MESSAGE DISCRIMINATOR common
+ PROCEDURE ID { procedureCode id-radioLinkSetup, ddMode fdd }
+ CRITICALITY reject
+}
+
+-- *** RadioLinkSetup (TDD) ***
+radioLinkSetupTDD NBAP-ELEMENTARY-PROCEDURE ::= {
+ INITIATING MESSAGE RadioLinkSetupRequestTDD
+ SUCCESSFUL OUTCOME RadioLinkSetupResponseTDD
+ UNSUCCESSFUL OUTCOME RadioLinkSetupFailureTDD
+ MESSAGE DISCRIMINATOR common
+ PROCEDURE ID { procedureCode id-radioLinkSetup, ddMode tdd }
+ CRITICALITY reject
+}
+
+-- *** SystemInformationUpdate ***
+systemInformationUpdate NBAP-ELEMENTARY-PROCEDURE ::= {
+ INITIATING MESSAGE SystemInformationUpdateRequest
+ SUCCESSFUL OUTCOME SystemInformationUpdateResponse
+ UNSUCCESSFUL OUTCOME SystemInformationUpdateFailure
+ MESSAGE DISCRIMINATOR common
+ PROCEDURE ID { procedureCode id-systemInformationUpdate, ddMode common }
+ CRITICALITY reject
+}
+
+-- *** Reset ***
+reset NBAP-ELEMENTARY-PROCEDURE ::= {
+ INITIATING MESSAGE ResetRequest
+ SUCCESSFUL OUTCOME ResetResponse
+ MESSAGE DISCRIMINATOR common
+ PROCEDURE ID { procedureCode id-reset, ddMode common }
+ CRITICALITY reject
+}
+
+-- *** CommonMeasurementInitiation ***
+commonMeasurementInitiation NBAP-ELEMENTARY-PROCEDURE ::= {
+ INITIATING MESSAGE CommonMeasurementInitiationRequest
+ SUCCESSFUL OUTCOME CommonMeasurementInitiationResponse
+ UNSUCCESSFUL OUTCOME CommonMeasurementInitiationFailure
+ MESSAGE DISCRIMINATOR common
+ PROCEDURE ID { procedureCode id-commonMeasurementInitiation, ddMode common }
+ CRITICALITY reject
+}
+
+-- *** RadioLinkAddition (FDD) ***
+radioLinkAdditionFDD NBAP-ELEMENTARY-PROCEDURE ::= {
+ INITIATING MESSAGE RadioLinkAdditionRequestFDD
+ SUCCESSFUL OUTCOME RadioLinkAdditionResponseFDD
+ UNSUCCESSFUL OUTCOME RadioLinkAdditionFailureFDD
+ MESSAGE DISCRIMINATOR dedicated
+ PROCEDURE ID { procedureCode id-radioLinkAddition, ddMode fdd }
+ CRITICALITY reject
+}
+
+-- *** RadioLinkAddition (TDD) ***
+radioLinkAdditionTDD NBAP-ELEMENTARY-PROCEDURE ::= {
+ INITIATING MESSAGE RadioLinkAdditionRequestTDD
+ SUCCESSFUL OUTCOME RadioLinkAdditionResponseTDD
+ UNSUCCESSFUL OUTCOME RadioLinkAdditionFailureTDD
+ MESSAGE DISCRIMINATOR dedicated
+ PROCEDURE ID { procedureCode id-radioLinkAddition, ddMode tdd }
+ CRITICALITY reject
+}
+
+-- *** RadioLinkDeletion ***
+radioLinkDeletion NBAP-ELEMENTARY-PROCEDURE ::= {
+ INITIATING MESSAGE RadioLinkDeletionRequest
+ SUCCESSFUL OUTCOME RadioLinkDeletionResponse
+ MESSAGE DISCRIMINATOR dedicated
+ PROCEDURE ID { procedureCode id-radioLinkDeletion, ddMode common }
+ CRITICALITY reject
+}
+
+-- *** SynchronisedRadioLinkReconfigurationPreparation (FDD) ***
+synchronisedRadioLinkReconfigurationPreparationFDD NBAP-ELEMENTARY-PROCEDURE ::= {
+ INITIATING MESSAGE RadioLinkReconfigurationPrepareFDD
+ SUCCESSFUL OUTCOME RadioLinkReconfigurationReady
+ UNSUCCESSFUL OUTCOME RadioLinkReconfigurationFailure
+ MESSAGE DISCRIMINATOR dedicated
+ PROCEDURE ID { procedureCode id-synchronisedRadioLinkReconfigurationPreparation, ddMode fdd }
+ CRITICALITY reject
+}
+
+-- *** SynchronisedRadioLinkReconfigurationPreparation (TDD) ***
+synchronisedRadioLinkReconfigurationPreparationTDD NBAP-ELEMENTARY-PROCEDURE ::= {
+ INITIATING MESSAGE RadioLinkReconfigurationPrepareTDD
+ SUCCESSFUL OUTCOME RadioLinkReconfigurationReady
+ UNSUCCESSFUL OUTCOME RadioLinkReconfigurationFailure
+ MESSAGE DISCRIMINATOR dedicated
+ PROCEDURE ID { procedureCode id-synchronisedRadioLinkReconfigurationPreparation, ddMode tdd }
+ CRITICALITY reject
+}
+
+-- *** UnSynchronisedRadioLinkReconfiguration (FDD) ***
+unSynchronisedRadioLinkReconfigurationFDD NBAP-ELEMENTARY-PROCEDURE ::= {
+ INITIATING MESSAGE RadioLinkReconfigurationRequestFDD
+ SUCCESSFUL OUTCOME RadioLinkReconfigurationResponse
+ UNSUCCESSFUL OUTCOME RadioLinkReconfigurationFailure
+ MESSAGE DISCRIMINATOR dedicated
+ PROCEDURE ID { procedureCode id-unSynchronisedRadioLinkReconfiguration, ddMode fdd }
+ CRITICALITY reject
+}
+
+-- *** UnSynchronisedRadioLinkReconfiguration (TDD) ***
+unSynchronisedRadioLinkReconfigurationTDD NBAP-ELEMENTARY-PROCEDURE ::= {
+ INITIATING MESSAGE RadioLinkReconfigurationRequestTDD
+ SUCCESSFUL OUTCOME RadioLinkReconfigurationResponse
+ UNSUCCESSFUL OUTCOME RadioLinkReconfigurationFailure
+ MESSAGE DISCRIMINATOR dedicated
+ PROCEDURE ID { procedureCode id-unSynchronisedRadioLinkReconfiguration, ddMode tdd }
+ CRITICALITY reject
+}
+
+-- *** DedicatedMeasurementInitiation ***
+dedicatedMeasurementInitiation NBAP-ELEMENTARY-PROCEDURE ::= {
+ INITIATING MESSAGE DedicatedMeasurementInitiationRequest
+ SUCCESSFUL OUTCOME DedicatedMeasurementInitiationResponse
+ UNSUCCESSFUL OUTCOME DedicatedMeasurementInitiationFailure
+ MESSAGE DISCRIMINATOR dedicated
+ PROCEDURE ID { procedureCode id-dedicatedMeasurementInitiation, ddMode common }
+ CRITICALITY reject
+}
+
+-- *** PhysicalSharedChannelReconfiguration (FDD) ***
+physicalSharedChannelReconfigurationFDD NBAP-ELEMENTARY-PROCEDURE ::= {
+ INITIATING MESSAGE PhysicalSharedChannelReconfigurationRequestFDD
+ SUCCESSFUL OUTCOME PhysicalSharedChannelReconfigurationResponse
+ UNSUCCESSFUL OUTCOME PhysicalSharedChannelReconfigurationFailure
+ MESSAGE DISCRIMINATOR common
+ PROCEDURE ID { procedureCode id-physicalSharedChannelReconfiguration, ddMode fdd }
+ CRITICALITY reject
+}
+
+-- *** PhysicalSharedChannelReconfiguration (TDD) ***
+physicalSharedChannelReconfigurationTDD NBAP-ELEMENTARY-PROCEDURE ::= {
+ INITIATING MESSAGE PhysicalSharedChannelReconfigurationRequestTDD
+ SUCCESSFUL OUTCOME PhysicalSharedChannelReconfigurationResponse
+ UNSUCCESSFUL OUTCOME PhysicalSharedChannelReconfigurationFailure
+ MESSAGE DISCRIMINATOR common
+ PROCEDURE ID { procedureCode id-physicalSharedChannelReconfiguration, ddMode tdd }
+ CRITICALITY reject
+}
+
+-- *** InformationExchangeInitiation ***
+informationExchangeInitiation NBAP-ELEMENTARY-PROCEDURE ::= {
+ INITIATING MESSAGE InformationExchangeInitiationRequest
+ SUCCESSFUL OUTCOME InformationExchangeInitiationResponse
+ UNSUCCESSFUL OUTCOME InformationExchangeInitiationFailure
+ MESSAGE DISCRIMINATOR common
+ PROCEDURE ID { procedureCode id-informationExchangeInitiation, ddMode common }
+ CRITICALITY reject
+}
+
+-- *** CellSynchronisationInitiation (TDD only) ***
+cellSynchronisationInitiationTDD NBAP-ELEMENTARY-PROCEDURE ::= {
+ INITIATING MESSAGE CellSynchronisationInitiationRequestTDD
+ SUCCESSFUL OUTCOME CellSynchronisationInitiationResponseTDD
+ UNSUCCESSFUL OUTCOME CellSynchronisationInitiationFailureTDD
+ MESSAGE DISCRIMINATOR common
+ PROCEDURE ID { procedureCode id-cellSynchronisationInitiation, ddMode tdd }
+ CRITICALITY reject
+}
+
+-- *** CellSynchronisationReconfiguration (TDD only) ***
+cellSynchronisationReconfigurationTDD NBAP-ELEMENTARY-PROCEDURE ::= {
+ INITIATING MESSAGE CellSynchronisationReconfigurationRequestTDD
+ SUCCESSFUL OUTCOME CellSynchronisationReconfigurationResponseTDD
+ UNSUCCESSFUL OUTCOME CellSynchronisationReconfigurationFailureTDD
+ MESSAGE DISCRIMINATOR common
+ PROCEDURE ID { procedureCode id-cellSynchronisationReconfiguration, ddMode tdd }
+ CRITICALITY reject
+}
+
+-- *** CellSynchronisationAdjustment (TDD only) ***
+cellSynchronisationAdjustmentTDD NBAP-ELEMENTARY-PROCEDURE ::= {
+ INITIATING MESSAGE CellSynchronisationAdjustmentRequestTDD
+ SUCCESSFUL OUTCOME CellSynchronisationAdjustmentResponseTDD
+ UNSUCCESSFUL OUTCOME CellSynchronisationAdjustmentFailureTDD
+ MESSAGE DISCRIMINATOR common
+ PROCEDURE ID { procedureCode id-cellSynchronisationAdjustment, ddMode tdd }
+ CRITICALITY reject
+}
+
+-- Class 2
+
+-- *** ResourceStatusIndication ***
+resourceStatusIndication NBAP-ELEMENTARY-PROCEDURE ::= {
+ INITIATING MESSAGE ResourceStatusIndication
+ MESSAGE DISCRIMINATOR common
+ PROCEDURE ID { procedureCode id-resourceStatusIndication, ddMode common }
+ CRITICALITY ignore
+}
+
+-- *** AuditRequired ***
+auditRequired NBAP-ELEMENTARY-PROCEDURE ::= {
+ INITIATING MESSAGE AuditRequiredIndication
+ MESSAGE DISCRIMINATOR common
+ PROCEDURE ID { procedureCode id-auditRequired, ddMode common }
+ CRITICALITY ignore
+}
+
+-- *** CommonMeasurementReport ***
+commonMeasurementReport NBAP-ELEMENTARY-PROCEDURE ::= {
+ INITIATING MESSAGE CommonMeasurementReport
+ MESSAGE DISCRIMINATOR common
+ PROCEDURE ID { procedureCode id-commonMeasurementReport, ddMode common }
+ CRITICALITY ignore
+}
+
+-- *** CommonMeasurementTermination ***
+commonMeasurementTermination NBAP-ELEMENTARY-PROCEDURE ::= {
+ INITIATING MESSAGE CommonMeasurementTerminationRequest
+ MESSAGE DISCRIMINATOR common
+ PROCEDURE ID { procedureCode id-commonMeasurementTermination, ddMode common }
+ CRITICALITY ignore
+}
+
+-- *** CommonMeasurementFailure ***
+commonMeasurementFailure NBAP-ELEMENTARY-PROCEDURE ::= {
+ INITIATING MESSAGE CommonMeasurementFailureIndication
+ MESSAGE DISCRIMINATOR common
+ PROCEDURE ID { procedureCode id-commonMeasurementFailure, ddMode common }
+ CRITICALITY ignore
+}
+
+-- *** SynchronisedRadioLinkReconfigurationCommit ***
+synchronisedRadioLinkReconfigurationCommit NBAP-ELEMENTARY-PROCEDURE ::= {
+ INITIATING MESSAGE RadioLinkReconfigurationCommit
+ MESSAGE DISCRIMINATOR dedicated
+ PROCEDURE ID { procedureCode id-synchronisedRadioLinkReconfigurationCommit, ddMode common }
+ CRITICALITY ignore
+}
+
+-- *** SynchronisedRadioReconfigurationCancellation ***
+synchronisedRadioLinkReconfigurationCancellation NBAP-ELEMENTARY-PROCEDURE ::= {
+ INITIATING MESSAGE RadioLinkReconfigurationCancel
+ MESSAGE DISCRIMINATOR dedicated
+ PROCEDURE ID { procedureCode id-synchronisedRadioLinkReconfigurationCancellation, ddMode common }
+ CRITICALITY ignore
+}
+
+-- *** RadioLinkFailure ***
+radioLinkFailure NBAP-ELEMENTARY-PROCEDURE ::= {
+ INITIATING MESSAGE RadioLinkFailureIndication
+ MESSAGE DISCRIMINATOR dedicated
+ PROCEDURE ID { procedureCode id-radioLinkFailure, ddMode common }
+ CRITICALITY ignore
+}
+
+-- *** RadioLinkPreemption ***
+radioLinkPreemption NBAP-ELEMENTARY-PROCEDURE ::= {
+ INITIATING MESSAGE RadioLinkPreemptionRequiredIndication
+ MESSAGE DISCRIMINATOR dedicated
+ PROCEDURE ID { procedureCode id-radioLinkPreemption, ddMode common }
+ CRITICALITY ignore
+}
+
+-- *** RadioLinkRestoration ***
+radioLinkRestoration NBAP-ELEMENTARY-PROCEDURE ::= {
+ INITIATING MESSAGE RadioLinkRestoreIndication
+ MESSAGE DISCRIMINATOR dedicated
+ PROCEDURE ID { procedureCode id-radioLinkRestoration, ddMode common }
+ CRITICALITY ignore
+}
+
+-- *** DedicatedMeasurementReport ***
+dedicatedMeasurementReport NBAP-ELEMENTARY-PROCEDURE ::= {
+ INITIATING MESSAGE DedicatedMeasurementReport
+ MESSAGE DISCRIMINATOR dedicated
+ PROCEDURE ID { procedureCode id-dedicatedMeasurementReport, ddMode common }
+ CRITICALITY ignore
+}
+
+-- *** DedicatedMeasurementTermination ***
+dedicatedMeasurementTermination NBAP-ELEMENTARY-PROCEDURE ::= {
+ INITIATING MESSAGE DedicatedMeasurementTerminationRequest
+ MESSAGE DISCRIMINATOR dedicated
+ PROCEDURE ID { procedureCode id-dedicatedMeasurementTermination, ddMode common }
+ CRITICALITY ignore
+}
+
+-- *** DedicatedMeasurementFailure ***
+dedicatedMeasurementFailure NBAP-ELEMENTARY-PROCEDURE ::= {
+ INITIATING MESSAGE DedicatedMeasurementFailureIndication
+ MESSAGE DISCRIMINATOR dedicated
+ PROCEDURE ID { procedureCode id-dedicatedMeasurementFailure, ddMode common }
+ CRITICALITY ignore
+}
+
+-- *** DLPowerControl (FDD only) ***
+downlinkPowerControlFDD NBAP-ELEMENTARY-PROCEDURE ::= {
+ INITIATING MESSAGE DL-PowerControlRequest
+ MESSAGE DISCRIMINATOR dedicated
+ PROCEDURE ID { procedureCode id-downlinkPowerControl, ddMode fdd }
+ CRITICALITY ignore
+}
+
+-- *** DLPowerTimeslotControl (TDD only) ***
+downlinkPowerTimeslotControl NBAP-ELEMENTARY-PROCEDURE ::= {
+ INITIATING MESSAGE DL-PowerTimeslotControlRequest
+ MESSAGE DISCRIMINATOR dedicated
+ PROCEDURE ID { procedureCode id-downlinkPowerTimeslotControl, ddMode tdd }
+ CRITICALITY ignore
+}
+
+-- *** CompressedModeCommand (FDD only) ***
+compressedModeCommand NBAP-ELEMENTARY-PROCEDURE ::= {
+ INITIATING MESSAGE CompressedModeCommand
+ MESSAGE DISCRIMINATOR dedicated
+ PROCEDURE ID { procedureCode id-compressedModeCommand, ddMode fdd }
+ CRITICALITY ignore
+}
+
+-- *** UnblockResourceIndication ***
+unblockResource NBAP-ELEMENTARY-PROCEDURE ::= {
+ INITIATING MESSAGE UnblockResourceIndication
+ MESSAGE DISCRIMINATOR common
+ PROCEDURE ID { procedureCode id-unblockResource, ddMode common }
+ CRITICALITY ignore
+}
+
+-- *** ErrorIndication for Dedicated procedures ***
+errorIndicationForDedicated NBAP-ELEMENTARY-PROCEDURE ::= {
+ INITIATING MESSAGE ErrorIndication
+ MESSAGE DISCRIMINATOR dedicated
+ PROCEDURE ID { procedureCode id-errorIndicationForDedicated, ddMode common }
+ CRITICALITY ignore
+}
+
+-- *** ErrorIndication for Common procedures ***
+errorIndicationForCommon NBAP-ELEMENTARY-PROCEDURE ::= {
+ INITIATING MESSAGE ErrorIndication
+ MESSAGE DISCRIMINATOR common
+ PROCEDURE ID { procedureCode id-errorIndicationForCommon, ddMode common }
+ CRITICALITY ignore
+}
+
+-- *** CellSynchronisationReporting (TDD only) ***
+cellSynchronisationReportingTDD NBAP-ELEMENTARY-PROCEDURE ::= {
+ INITIATING MESSAGE CellSynchronisationReportTDD
+ MESSAGE DISCRIMINATOR common
+ PROCEDURE ID { procedureCode id-cellSynchronisationReporting, ddMode tdd }
+ CRITICALITY ignore
+}
+
+-- *** CellSynchronisationTermination (TDD only) ***
+cellSynchronisationTerminationTDD NBAP-ELEMENTARY-PROCEDURE ::= {
+ INITIATING MESSAGE CellSynchronisationTerminationRequestTDD
+ MESSAGE DISCRIMINATOR common
+ PROCEDURE ID { procedureCode id-cellSynchronisationTermination, ddMode tdd }
+ CRITICALITY ignore
+}
+
+-- *** CellSynchronisationFailure (TDD only) ***
+cellSynchronisationFailureTDD NBAP-ELEMENTARY-PROCEDURE ::= {
+ INITIATING MESSAGE CellSynchronisationFailureIndicationTDD
+ MESSAGE DISCRIMINATOR common
+ PROCEDURE ID { procedureCode id-cellSynchronisationFailure, ddMode tdd }
+ CRITICALITY ignore
+}
+
+-- *** PrivateMessage for Dedicated procedures ***
+privateMessageForDedicated NBAP-ELEMENTARY-PROCEDURE ::= {
+ INITIATING MESSAGE PrivateMessage
+ MESSAGE DISCRIMINATOR dedicated
+ PROCEDURE ID { procedureCode id-privateMessageForDedicated, ddMode common }
+ CRITICALITY ignore
+}
+
+-- *** PrivateMessage for Common procedures ***
+privateMessageForCommon NBAP-ELEMENTARY-PROCEDURE ::= {
+ INITIATING MESSAGE PrivateMessage
+ MESSAGE DISCRIMINATOR common
+ PROCEDURE ID { procedureCode id-privateMessageForCommon, ddMode common }
+ CRITICALITY ignore
+}
+
+-- *** InformationReporting ***
+informationReporting NBAP-ELEMENTARY-PROCEDURE ::= {
+ INITIATING MESSAGE InformationReport
+ MESSAGE DISCRIMINATOR common
+ PROCEDURE ID { procedureCode id-informationReporting, ddMode common }
+ CRITICALITY ignore
+}
+
+-- *** InformationExchangeTermination ***
+informationExchangeTermination NBAP-ELEMENTARY-PROCEDURE ::= {
+ INITIATING MESSAGE InformationExchangeTerminationRequest
+ MESSAGE DISCRIMINATOR common
+ PROCEDURE ID { procedureCode id-informationExchangeTermination, ddMode common }
+ CRITICALITY ignore
+}
+
+-- *** InformationExchangeFailure ***
+informationExchangeFailure NBAP-ELEMENTARY-PROCEDURE ::= {
+ INITIATING MESSAGE InformationExchangeFailureIndication
+ MESSAGE DISCRIMINATOR common
+ PROCEDURE ID { procedureCode id-informationExchangeFailure, ddMode common }
+ CRITICALITY ignore
+}
+
+-- *** BearerRearrangement ***
+bearerRearrangement NBAP-ELEMENTARY-PROCEDURE ::= {
+ INITIATING MESSAGE BearerRearrangementIndication
+ MESSAGE DISCRIMINATOR dedicated
+ PROCEDURE ID { procedureCode id-BearerRearrangement, ddMode common }
+ CRITICALITY ignore
+}
+
+-- *** RadioLinkActivation (FDD) ***
+radioLinkActivationFDD NBAP-ELEMENTARY-PROCEDURE ::= {
+ INITIATING MESSAGE RadioLinkActivationCommandFDD
+ MESSAGE DISCRIMINATOR dedicated
+ PROCEDURE ID { procedureCode id-radioLinkActivation, ddMode fdd }
+ CRITICALITY ignore
+}
+
+-- *** RadioLinkActivation (TDD) ***
+radioLinkActivationTDD NBAP-ELEMENTARY-PROCEDURE ::= {
+ INITIATING MESSAGE RadioLinkActivationCommandTDD
+ MESSAGE DISCRIMINATOR dedicated
+ PROCEDURE ID { procedureCode id-radioLinkActivation, ddMode tdd }
+ CRITICALITY ignore
+}
+
+-- *** RadioLinkParameterUpdate (FDD) ***
+radioLinkParameterUpdateFDD NBAP-ELEMENTARY-PROCEDURE ::= {
+ INITIATING MESSAGE RadioLinkParameterUpdateIndicationFDD
+ MESSAGE DISCRIMINATOR dedicated
+ PROCEDURE ID { procedureCode id-radioLinkParameterUpdate, ddMode fdd }
+ CRITICALITY ignore
+}
+
+-- *** RadioLinkParameterUpdate (TDD) ***
+radioLinkParameterUpdateTDD NBAP-ELEMENTARY-PROCEDURE ::= {
+ INITIATING MESSAGE RadioLinkParameterUpdateIndicationTDD
+ MESSAGE DISCRIMINATOR dedicated
+ PROCEDURE ID { procedureCode id-radioLinkParameterUpdate, ddMode tdd }
+ CRITICALITY ignore
+}
+
+END
+
diff --git a/lib/asn1/test/asn1_SUITE_data/p_record.asn1config b/lib/asn1/test/asn1_SUITE_data/p_record.asn1config
new file mode 100644
index 0000000000..a8eb00d43d
--- /dev/null
+++ b/lib/asn1/test/asn1_SUITE_data/p_record.asn1config
@@ -0,0 +1 @@
+{selective_decode,{'p_record',[{sel_dec,['PersonnelRecord',title]}]}}.
diff --git a/lib/asn1/test/asn1_SUITE_data/p_record.set.asn b/lib/asn1/test/asn1_SUITE_data/p_record.set.asn
new file mode 100644
index 0000000000..24d502d067
--- /dev/null
+++ b/lib/asn1/test/asn1_SUITE_data/p_record.set.asn
@@ -0,0 +1 @@
+P-Record.py
diff --git a/lib/asn1/test/asn1_SUITE_data/subdir/MySO.asn b/lib/asn1/test/asn1_SUITE_data/subdir/MySO.asn
new file mode 100644
index 0000000000..4c649da4c4
--- /dev/null
+++ b/lib/asn1/test/asn1_SUITE_data/subdir/MySO.asn
@@ -0,0 +1,14 @@
+MySO DEFINITIONS AUTOMATIC TAGS ::=
+
+BEGIN
+
+IMPORTS
+ T
+ FROM IMP;
+
+
+Seq2 ::= SEQUENCE {
+ a T,
+ b INTEGER}
+
+END \ No newline at end of file
diff --git a/lib/asn1/test/asn1_SUITE_data/subdir/subsubdir/.gitignore b/lib/asn1/test/asn1_SUITE_data/subdir/subsubdir/.gitignore
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/lib/asn1/test/asn1_SUITE_data/subdir/subsubdir/.gitignore
diff --git a/lib/asn1/test/asn1_SUITE_data/tcapsystem/DialoguePDUs.asn b/lib/asn1/test/asn1_SUITE_data/tcapsystem/DialoguePDUs.asn
new file mode 100644
index 0000000000..541dc55f6b
--- /dev/null
+++ b/lib/asn1/test/asn1_SUITE_data/tcapsystem/DialoguePDUs.asn
@@ -0,0 +1,80 @@
+-- Generated by Asnp, the pretty-printer of France Telecom R&D (http://asn1.elibel.tm.fr/asnp/)
+-- Module DialoguePDUs (Q.773:06/1997)
+DialoguePDUs {itu-t recommendation q 773 modules(2) dialoguePDUs(2) version1(1)}
+DEFINITIONS ::=
+BEGIN
+
+EXPORTS dialogue-as-id, DialoguePDU;
+
+-- abstract syntax name for structured dialogue APDUs
+dialogue-as-id OBJECT IDENTIFIER ::=
+ {itu-t recommendation q 773 as(1) dialogue-as(1) version1(1)}
+
+DialoguePDU ::= CHOICE {
+ dialogueRequest AARQ-apdu,
+ dialogueResponse AARE-apdu,
+ dialogueAbort ABRT-apdu
+}
+
+AARQ-apdu ::= [APPLICATION 0] IMPLICIT SEQUENCE {
+ protocol-version
+ [0] IMPLICIT BIT STRING {version1(0)} DEFAULT {version1},
+ application-context-name [1] OBJECT IDENTIFIER,
+ user-information [30] IMPLICIT SEQUENCE OF EXTERNAL OPTIONAL
+}
+
+AARE-apdu ::= [APPLICATION 1] IMPLICIT SEQUENCE {
+ protocol-version
+ [0] IMPLICIT BIT STRING {version1(0)} DEFAULT {version1},
+ application-context-name [1] OBJECT IDENTIFIER,
+ result [2] Associate-result,
+ result-source-diagnostic [3] Associate-source-diagnostic,
+ user-information [30] IMPLICIT SEQUENCE OF EXTERNAL OPTIONAL
+}
+
+-- RLRQ PDU is currently not used.
+-- It is included for completeness only.
+RLRQ-apdu ::= [APPLICATION 2] IMPLICIT SEQUENCE {
+ reason [0] IMPLICIT Release-request-reason OPTIONAL,
+ user-information [30] IMPLICIT SEQUENCE OF EXTERNAL OPTIONAL
+}
+
+-- RLRE PDU is currently not used.
+-- It is included for completeness only
+RLRE-apdu ::= [APPLICATION 3] IMPLICIT SEQUENCE {
+ reason [0] IMPLICIT Release-response-reason OPTIONAL,
+ user-information [30] IMPLICIT SEQUENCE OF EXTERNAL OPTIONAL
+}
+
+ABRT-apdu ::= [APPLICATION 4] IMPLICIT SEQUENCE {
+ abort-source [0] IMPLICIT ABRT-source,
+ user-information [30] IMPLICIT SEQUENCE OF EXTERNAL OPTIONAL
+}
+
+ABRT-source ::= INTEGER {dialogue-service-user(0), dialogue-service-provider(1)
+}
+
+Associate-result ::= INTEGER {accepted(0), reject-permanent(1)}
+
+Associate-source-diagnostic ::= CHOICE {
+ dialogue-service-user
+ [1] INTEGER {null(0), no-reason-given(1),
+ application-context-name-not-supported(2)},
+ dialogue-service-provider
+ [2] INTEGER {null(0), no-reason-given(1), no-common-dialogue-portion(2)}
+}
+
+-- Release-request-reason is currently not used.
+-- It is included for completeness only.
+Release-request-reason ::= INTEGER {normal(0), urgent(1), user-defined(30)
+}
+
+-- Release-response-reason is currently not used.
+-- It is included for completeness only.
+Release-response-reason ::= INTEGER {
+ normal(0), not-finished(1), user-defined(30)}
+
+END -- DialoguePDUs
+
+-- Generated by Asnp, the ASN.1 pretty-printer of France Telecom R&D
+
diff --git a/lib/asn1/test/asn1_SUITE_data/tcapsystem/MAP-ApplicationContexts.asn b/lib/asn1/test/asn1_SUITE_data/tcapsystem/MAP-ApplicationContexts.asn
new file mode 100644
index 0000000000..26367c8f39
--- /dev/null
+++ b/lib/asn1/test/asn1_SUITE_data/tcapsystem/MAP-ApplicationContexts.asn
@@ -0,0 +1,186 @@
+MAP-ApplicationContexts {
+ itu-t identified-organization (4) etsi (0) mobileDomain (0)
+ gsm-Network (1) modules (3) map-ApplicationContexts (2) version9 (9)}
+
+DEFINITIONS
+
+::=
+
+BEGIN
+
+
+-- EXPORTS everything
+
+
+IMPORTS
+ gsm-NetworkId,
+ ac-Id
+FROM MobileDomainDefinitions {
+ itu-t (0) identified-organization (4) etsi (0) mobileDomain (0)
+ mobileDomainDefinitions (0) version1 (1)}
+;
+
+-- application-context-names
+
+map-ac OBJECT IDENTIFIER ::= {gsm-NetworkId ac-Id}
+
+networkLocUpContext-v3 OBJECT IDENTIFIER ::=
+ {map-ac networkLocUp(1) version3(3)}
+
+locationCancellationContext-v3 OBJECT IDENTIFIER ::=
+ {map-ac locationCancel(2) version3(3)}
+
+roamingNumberEnquiryContext-v3 OBJECT IDENTIFIER ::=
+ {map-ac roamingNbEnquiry(3) version3(3)}
+
+authenticationFailureReportContext-v3 OBJECT IDENTIFIER ::=
+ {map-ac authenticationFailureReport(39) version3(3)}
+
+locationInfoRetrievalContext-v3 OBJECT IDENTIFIER ::=
+ {map-ac locInfoRetrieval(5) version3(3)}
+
+resetContext-v2 OBJECT IDENTIFIER ::=
+ {map-ac reset(10) version2(2)}
+
+handoverControlContext-v3 OBJECT IDENTIFIER ::=
+ {map-ac handoverControl(11) version3(3)}
+
+equipmentMngtContext-v3 OBJECT IDENTIFIER ::=
+ {map-ac equipmentMngt(13) version3(3)}
+
+infoRetrievalContext-v3 OBJECT IDENTIFIER ::=
+ {map-ac infoRetrieval(14) version3(3)}
+
+interVlrInfoRetrievalContext-v3 OBJECT IDENTIFIER ::=
+ {map-ac interVlrInfoRetrieval(15) version3(3)}
+
+subscriberDataMngtContext-v3 OBJECT IDENTIFIER ::=
+ {map-ac subscriberDataMngt(16) version3(3)}
+
+tracingContext-v3 OBJECT IDENTIFIER ::=
+ {map-ac tracing(17) version3(3)}
+
+networkFunctionalSsContext-v2 OBJECT IDENTIFIER ::=
+ {map-ac networkFunctionalSs(18) version2(2)}
+
+networkUnstructuredSsContext-v2 OBJECT IDENTIFIER ::=
+ {map-ac networkUnstructuredSs(19) version2(2)}
+
+shortMsgGatewayContext-v3 OBJECT IDENTIFIER ::=
+ {map-ac shortMsgGateway(20) version3(3)}
+
+shortMsgMO-RelayContext-v3 OBJECT IDENTIFIER ::=
+ {map-ac shortMsgMO-Relay(21) version3(3)}
+
+shortMsgAlertContext-v2 OBJECT IDENTIFIER ::=
+ {map-ac shortMsgAlert(23) version2(2)}
+
+mwdMngtContext-v3 OBJECT IDENTIFIER ::=
+ {map-ac mwdMngt(24) version3(3)}
+
+shortMsgMT-RelayContext-v3 OBJECT IDENTIFIER ::=
+ {map-ac shortMsgMT-Relay(25) version3(3)}
+
+imsiRetrievalContext-v2 OBJECT IDENTIFIER ::=
+ {map-ac imsiRetrieval(26) version2(2)}
+
+msPurgingContext-v3 OBJECT IDENTIFIER ::=
+ {map-ac msPurging(27) version3(3)}
+
+subscriberInfoEnquiryContext-v3 OBJECT IDENTIFIER ::=
+ {map-ac subscriberInfoEnquiry(28) version3(3)}
+
+anyTimeInfoEnquiryContext-v3 OBJECT IDENTIFIER ::=
+ {map-ac anyTimeInfoEnquiry(29) version3(3)}
+
+callControlTransferContext-v4 OBJECT IDENTIFIER ::=
+ {map-ac callControlTransfer(6) version4(4)}
+
+ss-InvocationNotificationContext-v3 OBJECT IDENTIFIER ::=
+ {map-ac ss-InvocationNotification(36) version3(3)}
+
+groupCallControlContext-v3 OBJECT IDENTIFIER ::=
+ {map-ac groupCallControl(31) version3(3)}
+
+gprsLocationUpdateContext-v3 OBJECT IDENTIFIER ::=
+ {map-ac gprsLocationUpdate(32) version3(3)}
+
+gprsLocationInfoRetrievalContext-v4 OBJECT IDENTIFIER ::=
+ {map-ac gprsLocationInfoRetrieval(33) version4(4)}
+
+failureReportContext-v3 OBJECT IDENTIFIER ::=
+ {map-ac failureReport(34) version3(3)}
+
+gprsNotifyContext-v3 OBJECT IDENTIFIER ::=
+ {map-ac gprsNotify(35) version3(3)}
+
+reportingContext-v3 OBJECT IDENTIFIER ::=
+ {map-ac reporting(7) version3(3)}
+
+callCompletionContext-v3 OBJECT IDENTIFIER ::=
+ {map-ac callCompletion(8) version3(3)}
+
+istAlertingContext-v3 OBJECT IDENTIFIER ::=
+ {map-ac istAlerting(4) version3(3)}
+
+serviceTerminationContext-v3 OBJECT IDENTIFIER ::=
+ {map-ac immediateTermination(9) version3(3)}
+
+locationSvcGatewayContext-v3 OBJECT IDENTIFIER ::=
+ {map-ac locationSvcGateway(37) version3(3)}
+
+locationSvcEnquiryContext-v3 OBJECT IDENTIFIER ::=
+ {map-ac locationSvcEnquiry(38) version3(3)}
+
+mm-EventReportingContext-v3 OBJECT IDENTIFIER ::=
+ {map-ac mm-EventReporting(42) version3(3)}
+
+anyTimeInfoHandlingContext-v3 OBJECT IDENTIFIER ::=
+ {map-ac anyTimeInfoHandling(43) version3(3)}
+
+subscriberDataModificationNotificationContext-v3 OBJECT IDENTIFIER ::=
+ {map-ac subscriberDataModificationNotification(22) version3(3)}
+
+secureTransportHandlingContext-v3 OBJECT IDENTIFIER ::=
+ {map-ac secureTransportHandling(40) version3(3)}
+
+-- The following Object Identifiers are reserved for application-contexts
+-- existing in previous versions of the protocol
+
+-- AC Name & Version Object Identifier
+--
+-- networkLocUpContext-v1 map-ac networkLocUp (1) version1 (1)
+-- networkLocUpContext-v2 map-ac networkLocUp (1) version2 (2)
+-- locationCancellationContext-v1 map-ac locationCancellation (2) version1 (1)
+-- locationCancellationContext-v2 map-ac locationCancellation (2) version2 (2)
+-- roamingNumberEnquiryContext-v1 map-ac roamingNumberEnquiry (3) version1 (1)
+-- roamingNumberEnquiryContext-v2 map-ac roamingNumberEnquiry (3) version2 (2)
+-- locationInfoRetrievalContext-v1 map-ac locationInfoRetrieval (5) version1 (1)
+-- locationInfoRetrievalContext-v2 map-ac locationInfoRetrieval (5) version2 (2)
+-- resetContext-v1 map-ac reset (10) version1 (1)
+-- handoverControlContext-v1 map-ac handoverControl (11) version1 (1)
+-- handoverControlContext-v2 map-ac handoverControl (11) version2 (2)
+-- sIWFSAllocationContext-v3 map-ac sIWFSAllocation (12) version3 (3)
+-- equipmentMngtContext-v1 map-ac equipmentMngt (13) version1 (1)
+-- equipmentMngtContext-v2 map-ac equipmentMngt (13) version2 (2)
+-- infoRetrievalContext-v1 map-ac infoRetrieval (14) version1 (1)
+-- infoRetrievalContext-v2 map-ac infoRetrieval (14) version2 (2)
+-- interVlrInfoRetrievalContext-v2 map-ac interVlrInfoRetrieval (15) version2 (2)
+-- subscriberDataMngtContext-v1 map-ac subscriberDataMngt (16) version1 (1)
+-- subscriberDataMngtContext-v2 map-ac subscriberDataMngt (16) version2 (2)
+-- tracingContext-v1 map-ac tracing (17) version1 (1)
+-- tracingContext-v2 map-ac tracing (17) version2 (2)
+-- networkFunctionalSsContext-v1 map-ac networkFunctionalSs (18) version1 (1)
+-- shortMsgGatewayContext-v1 map-ac shortMsgGateway (20) version1 (1)
+-- shortMsgGatewayContext-v2 map-ac shortMsgGateway (20) version2 (2)
+-- shortMsgRelayContext-v1 map-ac shortMsgRelay (21) version1 (1)
+-- shortMsgAlertContext-v1 map-ac shortMsgAlert (23) version1 (1)
+-- mwdMngtContext-v1 map-ac mwdMngt (24) version1 (1)
+-- mwdMngtContext-v2 map-ac mwdMngt (24) version2 (2)
+-- shortMsgMT-RelayContext-v2 map-ac shortMsgMT-Relay (25) version2 (2)
+-- msPurgingContext-v2 map-ac msPurging (27) version2 (2)
+-- callControlTransferContext-v3 map-ac callControlTransferContext (6) version3 (3)
+-- gprsLocationInfoRetrievalContext-v3 map-ac gprsLocationInfoRetrievalContext (33) version3 (3)
+
+
+END
diff --git a/lib/asn1/test/asn1_SUITE_data/tcapsystem/MAP-BS-Code.asn b/lib/asn1/test/asn1_SUITE_data/tcapsystem/MAP-BS-Code.asn
new file mode 100644
index 0000000000..d12501098e
--- /dev/null
+++ b/lib/asn1/test/asn1_SUITE_data/tcapsystem/MAP-BS-Code.asn
@@ -0,0 +1,126 @@
+MAP-BS-Code {
+ itu-t identified-organization (4) etsi (0) mobileDomain (0)
+ gsm-Network (1) modules (3) map-BS-Code (20) version9 (9)}
+
+DEFINITIONS
+
+::=
+
+BEGIN
+
+BearerServiceCode ::= OCTET STRING (SIZE (1))
+ -- This type is used to represent the code identifying a single
+ -- bearer service, a group of bearer services, or all bearer
+ -- services. The services are defined in TS 3GPP TS 22.002 [3].
+ -- The internal structure is defined as follows:
+ --
+ -- plmn-specific bearer services:
+ -- bits 87654321: defined by the HPLMN operator
+
+ -- rest of bearer services:
+ -- bit 8: 0 (unused)
+ -- bits 7654321: group (bits 7654), and rate, if applicable
+ -- (bits 321)
+
+Ext-BearerServiceCode ::= OCTET STRING (SIZE (1..5))
+ -- This type is used to represent the code identifying a single
+ -- bearer service, a group of bearer services, or all bearer
+ -- services. The services are defined in TS 3GPP TS 22.002 [3].
+ -- The internal structure is defined as follows:
+ --
+ -- OCTET 1:
+ -- plmn-specific bearer services:
+ -- bits 87654321: defined by the HPLMN operator
+ --
+ -- rest of bearer services:
+ -- bit 8: 0 (unused)
+ -- bits 7654321: group (bits 7654), and rate, if applicable
+ -- (bits 321)
+
+ -- OCTETS 2-5: reserved for future use. If received the
+ -- Ext-TeleserviceCode shall be
+ -- treated according to the exception handling defined for the
+ -- operation that uses this type.
+
+
+ -- Ext-BearerServiceCode includes all values defined for BearerServiceCode.
+
+allBearerServices BearerServiceCode ::= '00000000'B
+
+allDataCDA-Services BearerServiceCode ::= '00010000'B
+dataCDA-300bps BearerServiceCode ::= '00010001'B
+dataCDA-1200bps BearerServiceCode ::= '00010010'B
+dataCDA-1200-75bps BearerServiceCode ::= '00010011'B
+dataCDA-2400bps BearerServiceCode ::= '00010100'B
+dataCDA-4800bps BearerServiceCode ::= '00010101'B
+dataCDA-9600bps BearerServiceCode ::= '00010110'B
+general-dataCDA BearerServiceCode ::= '00010111'B
+
+allDataCDS-Services BearerServiceCode ::= '00011000'B
+dataCDS-1200bps BearerServiceCode ::= '00011010'B
+dataCDS-2400bps BearerServiceCode ::= '00011100'B
+dataCDS-4800bps BearerServiceCode ::= '00011101'B
+dataCDS-9600bps BearerServiceCode ::= '00011110'B
+general-dataCDS BearerServiceCode ::= '00011111'B
+
+allPadAccessCA-Services BearerServiceCode ::= '00100000'B
+padAccessCA-300bps BearerServiceCode ::= '00100001'B
+padAccessCA-1200bps BearerServiceCode ::= '00100010'B
+padAccessCA-1200-75bps BearerServiceCode ::= '00100011'B
+padAccessCA-2400bps BearerServiceCode ::= '00100100'B
+padAccessCA-4800bps BearerServiceCode ::= '00100101'B
+padAccessCA-9600bps BearerServiceCode ::= '00100110'B
+general-padAccessCA BearerServiceCode ::= '00100111'B
+
+allDataPDS-Services BearerServiceCode ::= '00101000'B
+dataPDS-2400bps BearerServiceCode ::= '00101100'B
+dataPDS-4800bps BearerServiceCode ::= '00101101'B
+dataPDS-9600bps BearerServiceCode ::= '00101110'B
+general-dataPDS BearerServiceCode ::= '00101111'B
+
+allAlternateSpeech-DataCDA BearerServiceCode ::= '00110000'B
+
+allAlternateSpeech-DataCDS BearerServiceCode ::= '00111000'B
+
+allSpeechFollowedByDataCDA BearerServiceCode ::= '01000000'B
+
+allSpeechFollowedByDataCDS BearerServiceCode ::= '01001000'B
+
+-- The following non-hierarchical Compound Bearer Service
+-- Groups are defined in TS 3GPP TS 22.030:
+allDataCircuitAsynchronous BearerServiceCode ::= '01010000'B
+ -- covers "allDataCDA-Services", "allAlternateSpeech-DataCDA" and
+ -- "allSpeechFollowedByDataCDA"
+allAsynchronousServices BearerServiceCode ::= '01100000'B
+ -- covers "allDataCDA-Services", "allAlternateSpeech-DataCDA",
+ -- "allSpeechFollowedByDataCDA" and "allPadAccessCDA-Services"
+allDataCircuitSynchronous BearerServiceCode ::= '01011000'B
+ -- covers "allDataCDS-Services", "allAlternateSpeech-DataCDS" and
+ -- "allSpeechFollowedByDataCDS"
+allSynchronousServices BearerServiceCode ::= '01101000'B
+ -- covers "allDataCDS-Services", "allAlternateSpeech-DataCDS",
+ -- "allSpeechFollowedByDataCDS" and "allDataPDS-Services"
+--
+-- Compound Bearer Service Group Codes are only used in call
+-- independent supplementary service operations, i.e. they
+-- are not used in InsertSubscriberData or in
+-- DeleteSubscriberData messages.
+
+allPLMN-specificBS BearerServiceCode ::= '11010000'B
+plmn-specificBS-1 BearerServiceCode ::= '11010001'B
+plmn-specificBS-2 BearerServiceCode ::= '11010010'B
+plmn-specificBS-3 BearerServiceCode ::= '11010011'B
+plmn-specificBS-4 BearerServiceCode ::= '11010100'B
+plmn-specificBS-5 BearerServiceCode ::= '11010101'B
+plmn-specificBS-6 BearerServiceCode ::= '11010110'B
+plmn-specificBS-7 BearerServiceCode ::= '11010111'B
+plmn-specificBS-8 BearerServiceCode ::= '11011000'B
+plmn-specificBS-9 BearerServiceCode ::= '11011001'B
+plmn-specificBS-A BearerServiceCode ::= '11011010'B
+plmn-specificBS-B BearerServiceCode ::= '11011011'B
+plmn-specificBS-C BearerServiceCode ::= '11011100'B
+plmn-specificBS-D BearerServiceCode ::= '11011101'B
+plmn-specificBS-E BearerServiceCode ::= '11011110'B
+plmn-specificBS-F BearerServiceCode ::= '11011111'B
+
+END
diff --git a/lib/asn1/test/asn1_SUITE_data/tcapsystem/MAP-CH-DataTypes.asn b/lib/asn1/test/asn1_SUITE_data/tcapsystem/MAP-CH-DataTypes.asn
new file mode 100644
index 0000000000..10e9d8ff98
--- /dev/null
+++ b/lib/asn1/test/asn1_SUITE_data/tcapsystem/MAP-CH-DataTypes.asn
@@ -0,0 +1,438 @@
+MAP-CH-DataTypes {
+ itu-t identified-organization (4) etsi (0) mobileDomain (0)
+ gsm-Network (1) modules (3) map-CH-DataTypes (13) version9 (9)}
+
+DEFINITIONS
+
+IMPLICIT TAGS
+
+::=
+
+BEGIN
+
+EXPORTS
+ SendRoutingInfoArg,
+ SendRoutingInfoRes,
+ ProvideRoamingNumberArg,
+ ProvideRoamingNumberRes,
+ ResumeCallHandlingArg,
+ ResumeCallHandlingRes,
+ NumberOfForwarding,
+ SuppressionOfAnnouncement,
+ CallReferenceNumber,
+ SetReportingStateArg,
+ SetReportingStateRes,
+ StatusReportArg,
+ StatusReportRes,
+ RemoteUserFreeArg,
+ RemoteUserFreeRes,
+ IST-AlertArg,
+ IST-AlertRes,
+ IST-CommandArg,
+IST-CommandRes
+;
+
+IMPORTS
+ SubscriberInfo,
+ SupportedCamelPhases,
+ OfferedCamel4CSIs,
+ CUG-Interlock,
+ O-CSI,
+ D-CSI,
+ O-BcsmCamelTDPCriteriaList,
+ T-BCSM-CAMEL-TDP-CriteriaList,
+ IST-SupportIndicator,
+ IST-AlertTimerValue,
+ T-CSI,
+ NumberPortabilityStatus
+FROM MAP-MS-DataTypes {
+ itu-t identified-organization (4) etsi (0) mobileDomain (0)
+ gsm-Network (1) modules (3) map-MS-DataTypes (11) version9 (9)}
+
+ ForwardingOptions,
+ SS-List,
+ CCBS-Feature
+FROM MAP-SS-DataTypes {
+ itu-t identified-organization (4) etsi (0) mobileDomain (0)
+ gsm-Network (1) modules (3) map-SS-DataTypes (14) version9 (9)}
+
+ ISDN-AddressString,
+ ISDN-SubaddressString,
+ FTN-AddressString,
+ ExternalSignalInfo,
+ Ext-ExternalSignalInfo,
+ IMSI,
+ LMSI,
+ Ext-BasicServiceCode,
+ AlertingPattern,
+ NAEA-PreferredCI
+FROM MAP-CommonDataTypes {
+ itu-t identified-organization (4) etsi (0) mobileDomain (0)
+ gsm-Network (1) modules (3) map-CommonDataTypes (18) version9 (9)}
+
+ ExtensionContainer
+FROM MAP-ExtensionDataTypes {
+ itu-t identified-organization (4) etsi (0) mobileDomain (0)
+ gsm-Network (1) modules (3) map-ExtensionDataTypes (21) version9 (9)}
+;
+
+
+CUG-CheckInfo ::= SEQUENCE {
+ cug-Interlock CUG-Interlock,
+ cug-OutgoingAccess NULL OPTIONAL,
+ extensionContainer ExtensionContainer OPTIONAL,
+ ...}
+
+NumberOfForwarding ::= INTEGER (1..5)
+
+SendRoutingInfoArg ::= SEQUENCE {
+ msisdn [0] ISDN-AddressString,
+ cug-CheckInfo [1] CUG-CheckInfo OPTIONAL,
+ numberOfForwarding [2] NumberOfForwarding OPTIONAL,
+ interrogationType [3] InterrogationType,
+ or-Interrogation [4] NULL OPTIONAL,
+ or-Capability [5] OR-Phase OPTIONAL,
+ gmsc-OrGsmSCF-Address [6] ISDN-AddressString,
+ callReferenceNumber [7] CallReferenceNumber OPTIONAL,
+ forwardingReason [8] ForwardingReason OPTIONAL,
+ basicServiceGroup [9] Ext-BasicServiceCode OPTIONAL,
+ networkSignalInfo [10] ExternalSignalInfo OPTIONAL,
+ camelInfo [11] CamelInfo OPTIONAL,
+ suppressionOfAnnouncement [12] SuppressionOfAnnouncement OPTIONAL,
+ extensionContainer [13] ExtensionContainer OPTIONAL,
+ ...,
+ alertingPattern [14] AlertingPattern OPTIONAL,
+ ccbs-Call [15] NULL OPTIONAL,
+ supportedCCBS-Phase [16] SupportedCCBS-Phase OPTIONAL,
+ additionalSignalInfo [17] Ext-ExternalSignalInfo OPTIONAL,
+ istSupportIndicator [18] IST-SupportIndicator OPTIONAL,
+ pre-pagingSupported [19] NULL OPTIONAL,
+ callDiversionTreatmentIndicator [20] CallDiversionTreatmentIndicator OPTIONAL,
+ longFTN-Supported [21] NULL OPTIONAL,
+ suppress-VT-CSI [22] NULL OPTIONAL,
+ suppressIncomingCallBarring [23] NULL OPTIONAL,
+ gsmSCF-InitiatedCall [24] NULL OPTIONAL,
+ basicServiceGroup2 [25] Ext-BasicServiceCode OPTIONAL,
+ networkSignalInfo2 [26] ExternalSignalInfo OPTIONAL
+ }
+
+SuppressionOfAnnouncement ::= NULL
+
+InterrogationType ::= ENUMERATED {
+ basicCall (0),
+ forwarding (1)}
+
+OR-Phase ::= INTEGER (1..127)
+
+CallReferenceNumber ::= OCTET STRING (SIZE (1..8))
+
+ForwardingReason ::= ENUMERATED {
+ notReachable (0),
+ busy (1),
+ noReply (2)}
+
+SupportedCCBS-Phase ::= INTEGER (1..127)
+-- exception handling:
+-- Only value 1 is used.
+-- Values in the ranges 2-127 are reserved for future use.
+-- If received values 2-127 shall be mapped on to value 1.
+
+CallDiversionTreatmentIndicator ::= OCTET STRING (SIZE(1))
+-- callDiversionAllowed (xxxx xx01)
+-- callDiversionNotAllowed (xxxx xx10)
+-- network default is call diversion allowed
+
+SendRoutingInfoRes ::= [3] SEQUENCE {
+ imsi [9] IMSI OPTIONAL,
+ -- IMSI must be present if SendRoutingInfoRes is not segmented.
+ -- If the TC-Result-NL segmentation option is taken the IMSI must be
+ -- present in one segmented transmission of SendRoutingInfoRes.
+ extendedRoutingInfo ExtendedRoutingInfo OPTIONAL,
+ cug-CheckInfo [3] CUG-CheckInfo OPTIONAL,
+ cugSubscriptionFlag [6] NULL OPTIONAL,
+ subscriberInfo [7] SubscriberInfo OPTIONAL,
+ ss-List [1] SS-List OPTIONAL,
+ basicService [5] Ext-BasicServiceCode OPTIONAL,
+ forwardingInterrogationRequired [4] NULL OPTIONAL,
+ vmsc-Address [2] ISDN-AddressString OPTIONAL,
+ extensionContainer [0] ExtensionContainer OPTIONAL,
+ ... ,
+ naea-PreferredCI [10] NAEA-PreferredCI OPTIONAL,
+ -- naea-PreferredCI is included at the discretion of the HLR operator.
+ ccbs-Indicators [11] CCBS-Indicators OPTIONAL,
+ msisdn [12] ISDN-AddressString OPTIONAL,
+ numberPortabilityStatus [13] NumberPortabilityStatus OPTIONAL,
+ istAlertTimer [14] IST-AlertTimerValue OPTIONAL,
+ supportedCamelPhasesInVMSC [15] SupportedCamelPhases OPTIONAL,
+ offeredCamel4CSIsInVMSC [16] OfferedCamel4CSIs OPTIONAL,
+ routingInfo2 [17] RoutingInfo OPTIONAL,
+ ss-List2 [18] SS-List OPTIONAL,
+ basicService2 [19] Ext-BasicServiceCode OPTIONAL,
+ allowedServices [20] AllowedServices OPTIONAL,
+ unavailabilityCause [21] UnavailabilityCause OPTIONAL
+ }
+
+AllowedServices ::= BIT STRING {
+ firstServiceAllowed (0),
+ secondServiceAllowed (1) } (SIZE (2..8))
+ -- firstService is the service indicated in the networkSignalInfo
+ -- secondService is the service indicated in the networkSignalInfo2
+ -- Other bits than listed above shall be discarded
+
+UnavailabilityCause ::= ENUMERATED {
+ bearerServiceNotProvisioned (1),
+ teleserviceNotProvisioned (2),
+ absentSubscriber (3),
+ busySubscriber (4),
+ callBarred (5),
+ cug-Reject (6),
+ ...}
+ -- exception handling:
+ -- Reception of other values than the ones listed shall result in the service
+ -- being unavailable for that call.
+
+CCBS-Indicators ::= SEQUENCE {
+ ccbs-Possible [0] NULL OPTIONAL,
+ keepCCBS-CallIndicator [1] NULL OPTIONAL,
+ extensionContainer [2] ExtensionContainer OPTIONAL,
+ ...}
+
+RoutingInfo ::= CHOICE {
+ roamingNumber ISDN-AddressString,
+ forwardingData ForwardingData}
+
+ForwardingData ::= SEQUENCE {
+ forwardedToNumber [5] ISDN-AddressString OPTIONAL,
+ -- When this datatype is sent from an HLR which supports CAMEL Phase 2
+ -- to a GMSC which supports CAMEL Phase 2 the GMSC shall not check the
+ -- format of the number
+ forwardedToSubaddress [4] ISDN-SubaddressString OPTIONAL,
+ forwardingOptions [6] ForwardingOptions OPTIONAL,
+ extensionContainer [7] ExtensionContainer OPTIONAL,
+ ...,
+ longForwardedToNumber [8] FTN-AddressString OPTIONAL}
+
+ProvideRoamingNumberArg ::= SEQUENCE {
+ imsi [0] IMSI,
+ msc-Number [1] ISDN-AddressString,
+ msisdn [2] ISDN-AddressString OPTIONAL,
+ lmsi [4] LMSI OPTIONAL,
+ gsm-BearerCapability [5] ExternalSignalInfo OPTIONAL,
+ networkSignalInfo [6] ExternalSignalInfo OPTIONAL,
+ suppressionOfAnnouncement [7] SuppressionOfAnnouncement OPTIONAL,
+ gmsc-Address [8] ISDN-AddressString OPTIONAL,
+ callReferenceNumber [9] CallReferenceNumber OPTIONAL,
+ or-Interrogation [10] NULL OPTIONAL,
+ extensionContainer [11] ExtensionContainer OPTIONAL,
+ ... ,
+ alertingPattern [12] AlertingPattern OPTIONAL,
+ ccbs-Call [13] NULL OPTIONAL,
+ supportedCamelPhasesInInterrogatingNode [15] SupportedCamelPhases OPTIONAL,
+ additionalSignalInfo [14] Ext-ExternalSignalInfo OPTIONAL,
+ orNotSupportedInGMSC [16] NULL OPTIONAL,
+ pre-pagingSupported [17] NULL OPTIONAL,
+ longFTN-Supported [18] NULL OPTIONAL,
+ suppress-VT-CSI [19] NULL OPTIONAL,
+ offeredCamel4CSIsInInterrogatingNode [20] OfferedCamel4CSIs OPTIONAL
+ }
+
+ProvideRoamingNumberRes ::= SEQUENCE {
+ roamingNumber ISDN-AddressString,
+ extensionContainer ExtensionContainer OPTIONAL,
+ ...}
+
+ResumeCallHandlingArg ::= SEQUENCE {
+ callReferenceNumber [0] CallReferenceNumber OPTIONAL,
+ basicServiceGroup [1] Ext-BasicServiceCode OPTIONAL,
+ forwardingData [2] ForwardingData OPTIONAL,
+ imsi [3] IMSI OPTIONAL,
+ cug-CheckInfo [4] CUG-CheckInfo OPTIONAL,
+ o-CSI [5] O-CSI OPTIONAL,
+ extensionContainer [7] ExtensionContainer OPTIONAL,
+ ccbs-Possible [8] NULL OPTIONAL,
+ msisdn [9] ISDN-AddressString OPTIONAL,
+ uu-Data [10] UU-Data OPTIONAL,
+ allInformationSent [11] NULL OPTIONAL,
+ ...,
+ d-csi [12] D-CSI OPTIONAL,
+ o-BcsmCamelTDPCriteriaList [13] O-BcsmCamelTDPCriteriaList OPTIONAL,
+ basicServiceGroup2 [14] Ext-BasicServiceCode OPTIONAL
+ }
+
+UU-Data ::= SEQUENCE {
+ uuIndicator [0] UUIndicator OPTIONAL,
+ uui [1] UUI OPTIONAL,
+ uusCFInteraction [2] NULL OPTIONAL,
+ extensionContainer [3] ExtensionContainer OPTIONAL,
+ ...}
+
+UUIndicator ::= OCTET STRING (SIZE (1))
+ -- Octets are coded according to ETS 300 356
+
+UUI ::= OCTET STRING (SIZE (1..131))
+ -- Octets are coded according to ETS 300 356
+
+ResumeCallHandlingRes ::= SEQUENCE {
+ extensionContainer ExtensionContainer OPTIONAL,
+ ...}
+
+CamelInfo ::= SEQUENCE {
+ supportedCamelPhases SupportedCamelPhases,
+ suppress-T-CSI NULL OPTIONAL,
+ extensionContainer ExtensionContainer OPTIONAL,
+ ... ,
+ offeredCamel4CSIs [0] OfferedCamel4CSIs OPTIONAL }
+
+ExtendedRoutingInfo ::= CHOICE {
+ routingInfo RoutingInfo,
+ camelRoutingInfo [8] CamelRoutingInfo}
+
+CamelRoutingInfo ::= SEQUENCE {
+ forwardingData ForwardingData OPTIONAL,
+ gmscCamelSubscriptionInfo [0] GmscCamelSubscriptionInfo,
+ extensionContainer [1] ExtensionContainer OPTIONAL,
+ ...}
+
+GmscCamelSubscriptionInfo ::= SEQUENCE {
+ t-CSI [0] T-CSI OPTIONAL,
+ o-CSI [1] O-CSI OPTIONAL,
+ extensionContainer [2] ExtensionContainer OPTIONAL,
+ ...,
+ o-BcsmCamelTDP-CriteriaList [3] O-BcsmCamelTDPCriteriaList OPTIONAL,
+ t-BCSM-CAMEL-TDP-CriteriaList [4] T-BCSM-CAMEL-TDP-CriteriaList OPTIONAL,
+ d-csi [5] D-CSI OPTIONAL}
+
+SetReportingStateArg ::= SEQUENCE {
+ imsi [0] IMSI OPTIONAL,
+ lmsi [1] LMSI OPTIONAL,
+ ccbs-Monitoring [2] ReportingState OPTIONAL,
+ extensionContainer [3] ExtensionContainer OPTIONAL,
+ ...}
+
+ReportingState ::= ENUMERATED {
+ stopMonitoring (0),
+ startMonitoring (1),
+ ...}
+ -- exception handling:
+ -- reception of values 2-10 shall be mapped to 'stopMonitoring'
+ -- reception of values > 10 shall be mapped to 'startMonitoring'
+
+SetReportingStateRes ::= SEQUENCE{
+ ccbs-SubscriberStatus [0] CCBS-SubscriberStatus OPTIONAL,
+ extensionContainer [1] ExtensionContainer OPTIONAL,
+ ...}
+
+CCBS-SubscriberStatus ::= ENUMERATED {
+ ccbsNotIdle (0),
+ ccbsIdle (1),
+ ccbsNotReachable (2),
+ ...}
+ -- exception handling:
+ -- reception of values 3-10 shall be mapped to 'ccbsNotIdle'
+ -- reception of values 11-20 shall be mapped to 'ccbsIdle'
+ -- reception of values > 20 shall be mapped to 'ccbsNotReachable'
+
+StatusReportArg ::= SEQUENCE{
+ imsi [0] IMSI,
+ eventReportData [1] EventReportData OPTIONAL,
+ callReportdata [2] CallReportData OPTIONAL,
+ extensionContainer [3] ExtensionContainer OPTIONAL,
+ ...}
+
+EventReportData ::= SEQUENCE{
+ ccbs-SubscriberStatus [0] CCBS-SubscriberStatus OPTIONAL,
+ extensionContainer [1] ExtensionContainer OPTIONAL,
+ ...}
+
+CallReportData ::= SEQUENCE{
+ monitoringMode [0] MonitoringMode OPTIONAL,
+ callOutcome [1] CallOutcome OPTIONAL,
+ extensionContainer [2] ExtensionContainer OPTIONAL,
+ ...}
+
+MonitoringMode ::= ENUMERATED {
+ a-side (0),
+ b-side (1),
+ ...}
+ -- exception handling:
+ -- reception of values 2-10 shall be mapped 'a-side'
+ -- reception of values > 10 shall be mapped to 'b-side'
+
+CallOutcome ::= ENUMERATED {
+ success (0),
+ failure (1),
+ busy (2),
+ ...}
+ -- exception handling:
+ -- reception of values 3-10 shall be mapped to 'success'
+ -- reception of values 11-20 shall be mapped to 'failure'
+ -- reception of values > 20 shall be mapped to 'busy'
+
+StatusReportRes ::= SEQUENCE {
+ extensionContainer [0] ExtensionContainer OPTIONAL,
+ ...}
+
+RemoteUserFreeArg ::= SEQUENCE{
+ imsi [0] IMSI,
+ callInfo [1] ExternalSignalInfo,
+ ccbs-Feature [2] CCBS-Feature,
+ translatedB-Number [3] ISDN-AddressString,
+ replaceB-Number [4] NULL OPTIONAL,
+ alertingPattern [5] AlertingPattern OPTIONAL,
+ extensionContainer [6] ExtensionContainer OPTIONAL,
+ ...}
+
+RemoteUserFreeRes ::= SEQUENCE{
+ ruf-Outcome [0] RUF-Outcome,
+ extensionContainer [1] ExtensionContainer OPTIONAL,
+ ...}
+
+RUF-Outcome ::= ENUMERATED{
+ accepted (0),
+ rejected (1),
+ noResponseFromFreeMS (2), -- T4 Expiry
+ noResponseFromBusyMS (3), -- T10 Expiry
+ udubFromFreeMS (4),
+ udubFromBusyMS (5),
+ ...}
+ -- exception handling:
+ -- reception of values 6-20 shall be mapped to 'accepted'
+ -- reception of values 21-30 shall be mapped to 'rejected'
+ -- reception of values 31-40 shall be mapped to 'noResponseFromFreeMS'
+ -- reception of values 41-50 shall be mapped to 'noResponseFromBusyMS'
+ -- reception of values 51-60 shall be mapped to 'udubFromFreeMS'
+ -- reception of values > 60 shall be mapped to 'udubFromBusyMS'
+
+IST-AlertArg ::= SEQUENCE{
+ imsi [0] IMSI,
+ extensionContainer [1] ExtensionContainer OPTIONAL,
+ ...}
+
+IST-AlertRes ::= SEQUENCE{
+ istAlertTimer [0] IST-AlertTimerValue OPTIONAL,
+ istInformationWithdraw [1] NULL OPTIONAL,
+ callTerminationIndicator [2] CallTerminationIndicator OPTIONAL,
+ extensionContainer [3] ExtensionContainer OPTIONAL,
+ ...}
+
+IST-CommandArg ::= SEQUENCE{
+ imsi [0] IMSI,
+ extensionContainer [1] ExtensionContainer OPTIONAL,
+ ...}
+
+IST-CommandRes ::= SEQUENCE{
+ extensionContainer ExtensionContainer OPTIONAL,
+ ...}
+
+CallTerminationIndicator ::= ENUMERATED {
+ terminateCallActivityReferred (0),
+ terminateAllCallActivities (1),
+ ...}
+ -- exception handling:
+ -- reception of values 2-10 shall be mapped to ' terminateCallActivityReferred '
+ -- reception of values > 10 shall be mapped to ' terminateAllCallActivities '
+
+ -- In MSCs not supporting linkage of all call activities, any value received shall
+ -- be interpreted as ' terminateCallActivityReferred '
+
+END
diff --git a/lib/asn1/test/asn1_SUITE_data/tcapsystem/MAP-CallHandlingOperations.asn b/lib/asn1/test/asn1_SUITE_data/tcapsystem/MAP-CallHandlingOperations.asn
new file mode 100644
index 0000000000..473e968247
--- /dev/null
+++ b/lib/asn1/test/asn1_SUITE_data/tcapsystem/MAP-CallHandlingOperations.asn
@@ -0,0 +1,198 @@
+MAP-CallHandlingOperations {
+ itu-t identified-organization (4) etsi (0) mobileDomain (0)
+ gsm-Network (1) modules (3) map-CallHandlingOperations (7)
+ version9 (9)}
+
+DEFINITIONS
+
+::=
+
+BEGIN
+
+EXPORTS
+ sendRoutingInfo,
+ provideRoamingNumber,
+ resumeCallHandling,
+ setReportingState,
+ statusReport,
+ remoteUserFree,
+ ist-Alert,
+ ist-Command
+;
+
+IMPORTS
+ OPERATION
+FROM Remote-Operations-Information-Objects {
+joint-iso-itu-t remote-operations(4)
+ informationObjects(5) version1(0)}
+
+ systemFailure,
+ dataMissing,
+ unexpectedDataValue,
+ facilityNotSupported,
+ or-NotAllowed,
+ unknownSubscriber,
+ numberChanged,
+ bearerServiceNotProvisioned,
+ teleserviceNotProvisioned,
+ noRoamingNumberAvailable,
+ absentSubscriber,
+ busySubscriber,
+ noSubscriberReply,
+ callBarred,
+ forwardingViolation,
+ forwardingFailed,
+ cug-Reject,
+ resourceLimitation,
+ incompatibleTerminal,
+ unidentifiedSubscriber
+
+FROM MAP-Errors {
+ itu-t identified-organization (4) etsi (0) mobileDomain (0)
+ gsm-Network (1) modules (3) map-Errors (10) version9 (9)}
+ SendRoutingInfoArg,
+ SendRoutingInfoRes,
+ ProvideRoamingNumberArg,
+ ProvideRoamingNumberRes,
+ ResumeCallHandlingArg,
+ ResumeCallHandlingRes,
+ SetReportingStateArg,
+ SetReportingStateRes,
+ StatusReportArg,
+ StatusReportRes,
+ RemoteUserFreeArg,
+ RemoteUserFreeRes,
+ IST-AlertArg,
+ IST-AlertRes,
+ IST-CommandArg,
+ IST-CommandRes
+FROM MAP-CH-DataTypes {
+ itu-t identified-organization (4) etsi (0) mobileDomain (0)
+ gsm-Network (1) modules (3) map-CH-DataTypes (13) version9 (9)}
+
+;
+
+sendRoutingInfo OPERATION ::= { --Timer m
+-- The timer is set to the upper limit of the range if the GMSC supports pre-paging.
+ ARGUMENT
+ SendRoutingInfoArg
+ RESULT
+ SendRoutingInfoRes
+ ERRORS {
+ systemFailure |
+ dataMissing |
+ unexpectedDataValue |
+ facilityNotSupported |
+ or-NotAllowed |
+ unknownSubscriber |
+ numberChanged |
+ bearerServiceNotProvisioned |
+ teleserviceNotProvisioned |
+ absentSubscriber |
+ busySubscriber |
+ noSubscriberReply |
+ callBarred |
+ cug-Reject |
+ forwardingViolation}
+ CODE local:22 }
+
+provideRoamingNumber OPERATION ::= { --Timer m
+-- The timer is set to the upper limit of the range if the HLR supports pre-paging.
+ ARGUMENT
+ ProvideRoamingNumberArg
+ RESULT
+ ProvideRoamingNumberRes
+ ERRORS {
+ systemFailure |
+ dataMissing |
+ unexpectedDataValue |
+ facilityNotSupported |
+ or-NotAllowed |
+ absentSubscriber |
+ noRoamingNumberAvailable}
+ CODE local:4 }
+
+resumeCallHandling OPERATION ::= { --Timer m
+ ARGUMENT
+ ResumeCallHandlingArg
+ RESULT
+ ResumeCallHandlingRes
+ -- optional
+ ERRORS {
+ forwardingFailed |
+ or-NotAllowed |
+ unexpectedDataValue |
+ dataMissing }
+ CODE local:6 }
+
+setReportingState OPERATION ::= { --Timer m
+ ARGUMENT
+ SetReportingStateArg
+ RESULT
+ SetReportingStateRes
+ -- optional
+ ERRORS {
+ systemFailure |
+ unidentifiedSubscriber |
+ unexpectedDataValue |
+ dataMissing |
+ resourceLimitation |
+ facilityNotSupported}
+ CODE local:73 }
+
+statusReport OPERATION ::= { --Timer m
+ ARGUMENT
+ StatusReportArg
+ RESULT
+ StatusReportRes
+ -- optional
+ ERRORS {
+ unknownSubscriber |
+ systemFailure |
+ unexpectedDataValue |
+ dataMissing}
+ CODE local:74 }
+
+remoteUserFree OPERATION ::= { --Timer ml
+ ARGUMENT
+ RemoteUserFreeArg
+ RESULT
+ RemoteUserFreeRes
+ ERRORS {
+ unexpectedDataValue |
+ dataMissing |
+ incompatibleTerminal |
+ absentSubscriber |
+ systemFailure |
+ busySubscriber}
+ CODE local:75 }
+
+ist-Alert OPERATION ::= { --Timer m
+ ARGUMENT
+ IST-AlertArg
+ RESULT
+ IST-AlertRes
+ -- optional
+ ERRORS {
+ unexpectedDataValue |
+ resourceLimitation |
+ unknownSubscriber |
+ systemFailure |
+ facilityNotSupported}
+ CODE local:87 }
+
+ist-Command OPERATION::= { --Timer m
+ ARGUMENT
+ IST-CommandArg
+ RESULT
+ IST-CommandRes
+ -- optional
+ ERRORS {
+ unexpectedDataValue |
+ resourceLimitation |
+ unknownSubscriber |
+ systemFailure |
+ facilityNotSupported}
+ CODE local:88 }
+
+END
diff --git a/lib/asn1/test/asn1_SUITE_data/tcapsystem/MAP-CommonDataTypes.asn b/lib/asn1/test/asn1_SUITE_data/tcapsystem/MAP-CommonDataTypes.asn
new file mode 100644
index 0000000000..55d234e91f
--- /dev/null
+++ b/lib/asn1/test/asn1_SUITE_data/tcapsystem/MAP-CommonDataTypes.asn
@@ -0,0 +1,612 @@
+MAP-CommonDataTypes {
+ itu-t identified-organization (4) etsi (0) mobileDomain (0)
+ gsm-Network (1) modules (3) map-CommonDataTypes (18) version9 (9)}
+
+DEFINITIONS
+
+IMPLICIT TAGS
+
+::=
+
+BEGIN
+
+EXPORTS
+
+ -- general data types and values
+ AddressString,
+ ISDN-AddressString,
+ maxISDN-AddressLength,
+ FTN-AddressString,
+ ISDN-SubaddressString,
+ ExternalSignalInfo,
+ Ext-ExternalSignalInfo,
+ AccessNetworkSignalInfo,
+ SignalInfo,
+ maxSignalInfoLength,
+ AlertingPattern,
+ TBCD-STRING,
+
+ -- data types for numbering and identification
+ IMSI,
+ TMSI,
+ Identity,
+ SubscriberId,
+ IMEI,
+ HLR-List,
+ LMSI,
+ GlobalCellId,
+ NetworkResource,
+ AdditionalNetworkResource,
+ NAEA-PreferredCI,
+ NAEA-CIC,
+ ASCI-CallReference,
+ SubscriberIdentity,
+
+ -- data types for CAMEL
+ CellGlobalIdOrServiceAreaIdOrLAI,
+ CellGlobalIdOrServiceAreaIdFixedLength,
+ LAIFixedLength,
+
+ -- data types for subscriber management
+ BasicServiceCode,
+ Ext-BasicServiceCode,
+ EMLPP-Info,
+ EMLPP-Priority,
+ MC-SS-Info,
+ MaxMC-Bearers,
+ MC-Bearers,
+ Ext-SS-Status,
+
+ -- data types for geographic location
+ AgeOfLocationInformation,
+ LCSClientExternalID,
+ LCSClientInternalID,
+ LCSServiceTypeID
+;
+
+IMPORTS
+ TeleserviceCode,
+ Ext-TeleserviceCode
+FROM MAP-TS-Code {
+ itu-t identified-organization (4) etsi (0) mobileDomain (0)
+ gsm-Network (1) modules (3) map-TS-Code (19) version9 (9)}
+
+ BearerServiceCode,
+ Ext-BearerServiceCode
+FROM MAP-BS-Code {
+ itu-t identified-organization (4) etsi (0) mobileDomain (0)
+ gsm-Network (1) modules (3) map-BS-Code (20) version9 (9)}
+
+ SS-Code
+FROM MAP-SS-Code {
+ itu-t identified-organization (4) etsi (0) mobileDomain (0)
+ gsm-Network (1) modules (3) map-SS-Code (15) version9 (9)}
+
+ ExtensionContainer
+FROM MAP-ExtensionDataTypes {
+ itu-t identified-organization (4) etsi (0) mobileDomain (0)
+ gsm-Network (1) modules (3) map-ExtensionDataTypes (21) version9 (9)}
+;
+
+
+-- general data types
+
+TBCD-STRING ::= OCTET STRING
+ -- This type (Telephony Binary Coded Decimal String) is used to
+ -- represent several digits from 0 through 9, *, #, a, b, c, two
+ -- digits per octet, each digit encoded 0000 to 1001 (0 to 9),
+ -- 1010 (*), 1011 (#), 1100 (a), 1101 (b) or 1110 (c); 1111 used
+ -- as filler when there is an odd number of digits.
+
+ -- bits 8765 of octet n encoding digit 2n
+ -- bits 4321 of octet n encoding digit 2(n-1) +1
+
+AddressString ::= OCTET STRING (SIZE (1..maxAddressLength))
+ -- This type is used to represent a number for addressing
+ -- purposes. It is composed of
+ -- a) one octet for nature of address, and numbering plan
+ -- indicator.
+ -- b) digits of an address encoded as TBCD-String.
+
+ -- a) The first octet includes a one bit extension indicator, a
+ -- 3 bits nature of address indicator and a 4 bits numbering
+ -- plan indicator, encoded as follows:
+
+ -- bit 8: 1 (no extension)
+
+ -- bits 765: nature of address indicator
+ -- 000 unknown
+ -- 001 international number
+ -- 010 national significant number
+ -- 011 network specific number
+ -- 100 subscriber number
+ -- 101 reserved
+ -- 110 abbreviated number
+ -- 111 reserved for extension
+
+ -- bits 4321: numbering plan indicator
+ -- 0000 unknown
+ -- 0001 ISDN/Telephony Numbering Plan (Rec ITU-T E.164)
+ -- 0010 spare
+ -- 0011 data numbering plan (ITU-T Rec X.121)
+ -- 0100 telex numbering plan (ITU-T Rec F.69)
+ -- 0101 spare
+ -- 0110 land mobile numbering plan (ITU-T Rec E.212)
+ -- 0111 spare
+ -- 1000 national numbering plan
+ -- 1001 private numbering plan
+ -- 1111 reserved for extension
+
+ -- all other values are reserved.
+
+ -- b) The following octets representing digits of an address
+ -- encoded as a TBCD-STRING.
+
+maxAddressLength INTEGER ::= 20
+
+ISDN-AddressString ::=
+ AddressString (SIZE (1..maxISDN-AddressLength))
+ -- This type is used to represent ISDN numbers.
+
+maxISDN-AddressLength INTEGER ::= 9
+
+FTN-AddressString ::=
+ AddressString (SIZE (1..maxFTN-AddressLength))
+ -- This type is used to represent forwarded-to numbers.
+ -- For long forwarded-to numbers (longer than 15 digits) NPI shall be unknown;
+ -- if NAI = international the first digits represent the country code (CC)
+ -- and the network destination code (NDC) as for E.164.
+
+maxFTN-AddressLength INTEGER ::= 15
+
+ISDN-SubaddressString ::=
+ OCTET STRING (SIZE (1..maxISDN-SubaddressLength))
+ -- This type is used to represent ISDN subaddresses.
+ -- It is composed of
+ -- a) one octet for type of subaddress and odd/even indicator.
+ -- b) 20 octets for subaddress information.
+
+ -- a) The first octet includes a one bit extension indicator, a
+ -- 3 bits type of subaddress and a one bit odd/even indicator,
+ -- encoded as follows:
+
+ -- bit 8: 1 (no extension)
+
+ -- bits 765: type of subaddress
+ -- 000 NSAP (X.213/ISO 8348 AD2)
+ -- 010 User Specified
+ -- All other values are reserved
+
+ -- bit 4: odd/even indicator
+ -- 0 even number of address signals
+ -- 1 odd number of address signals
+ -- The odd/even indicator is used when the type of subaddress
+ -- is "user specified" and the coding is BCD.
+
+ -- bits 321: 000 (unused)
+
+ -- b) Subaddress information.
+ -- The NSAP X.213/ISO8348AD2 address shall be formatted as specified
+ -- by octet 4 which contains the Authority and Format Identifier
+ -- (AFI). The encoding is made according to the "preferred binary
+ -- encoding" as defined in X.213/ISO834AD2. For the definition
+ -- of this type of subaddress, see ITU-T Rec I.334.
+
+ -- For User-specific subaddress, this field is encoded according
+ -- to the user specification, subject to a maximum length of 20
+ -- octets. When interworking with X.25 networks BCD coding should
+ -- be applied.
+
+maxISDN-SubaddressLength INTEGER ::= 21
+
+ExternalSignalInfo ::= SEQUENCE {
+ protocolId ProtocolId,
+ signalInfo SignalInfo,
+ -- Information about the internal structure is given in
+ -- clause 7.6.9.
+ extensionContainer ExtensionContainer OPTIONAL,
+ -- extensionContainer must not be used in version 2
+ ...}
+
+SignalInfo ::= OCTET STRING (SIZE (1..maxSignalInfoLength))
+
+maxSignalInfoLength INTEGER ::= 200
+ -- This NamedValue represents the theoretical maximum number of octets which is
+ -- available to carry a single instance of the SignalInfo data type,
+ -- without requiring segmentation to cope with the network layer service.
+ -- However, the actual maximum size available for an instance of the data
+ -- type may be lower, especially when other information elements
+ -- have to be included in the same component.
+
+ProtocolId ::= ENUMERATED {
+ gsm-0408 (1),
+ gsm-0806 (2),
+ gsm-BSSMAP (3),
+ -- Value 3 is reserved and must not be used
+ ets-300102-1 (4)}
+
+Ext-ExternalSignalInfo ::= SEQUENCE {
+ ext-ProtocolId Ext-ProtocolId,
+ signalInfo SignalInfo,
+ -- Information about the internal structure is given in
+ -- clause 7.6.9.10
+ extensionContainer ExtensionContainer OPTIONAL,
+ ...}
+
+Ext-ProtocolId ::= ENUMERATED {
+ ets-300356 (1),
+ ...
+ }
+-- exception handling:
+-- For Ext-ExternalSignalInfo sequences containing this parameter with any
+-- other value than the ones listed the receiver shall ignore the whole
+-- Ext-ExternalSignalInfo sequence.
+
+AccessNetworkSignalInfo ::= SEQUENCE {
+ accessNetworkProtocolId AccessNetworkProtocolId,
+ signalInfo LongSignalInfo,
+ -- Information about the internal structure is given in clause 7.6.9.1
+
+ extensionContainer ExtensionContainer OPTIONAL,
+ ...}
+
+LongSignalInfo ::= OCTET STRING (SIZE (1..maxLongSignalInfoLength))
+
+maxLongSignalInfoLength INTEGER ::= 2560
+ -- This Named Value represents the maximum number of octets which is available
+ -- to carry a single instance of the LongSignalInfo data type using
+ -- White Book SCCP with the maximum number of segments.
+ -- It takes account of the octets used by the lower layers of the protocol, and
+ -- other information elements which may be included in the same component.
+
+AccessNetworkProtocolId ::= ENUMERATED {
+ ts3G-48006 (1),
+ ts3G-25413 (2),
+ ...}
+ -- exception handling:
+ -- For AccessNetworkSignalInfo sequences containing this parameter with any
+ -- other value than the ones listed the receiver shall ignore the whole
+ -- AccessNetworkSignalInfo sequence.
+
+AlertingPattern ::= OCTET STRING (SIZE (1) )
+ -- This type is used to represent Alerting Pattern
+
+ -- bits 8765 : 0000 (unused)
+
+ -- bits 43 : type of Pattern
+ -- 00 level
+ -- 01 category
+ -- 10 category
+ -- all other values are reserved.
+
+ -- bits 21 : type of alerting
+
+alertingLevel-0 AlertingPattern ::= '00000000'B
+alertingLevel-1 AlertingPattern ::= '00000001'B
+alertingLevel-2 AlertingPattern ::= '00000010'B
+ -- all other values of Alerting level are reserved
+ -- Alerting Levels are defined in GSM 02.07
+
+alertingCategory-1 AlertingPattern ::= '00000100'B
+alertingCategory-2 AlertingPattern ::= '00000101'B
+alertingCategory-3 AlertingPattern ::= '00000110'B
+alertingCategory-4 AlertingPattern ::= '00000111'B
+alertingCategory-5 AlertingPattern ::= '00001000'B
+ -- all other values of Alerting Category are reserved
+ -- Alerting categories are defined in GSM 02.07
+
+-- data types for numbering and identification
+
+IMSI ::= TBCD-STRING (SIZE (3..8))
+ -- digits of MCC, MNC, MSIN are concatenated in this order.
+
+Identity ::= CHOICE {
+ imsi IMSI,
+ imsi-WithLMSI IMSI-WithLMSI}
+
+IMSI-WithLMSI ::= SEQUENCE {
+ imsi IMSI,
+ lmsi LMSI,
+ -- a special value 00000000 indicates that the LMSI is not in use
+ ...}
+
+ASCI-CallReference ::= TBCD-STRING (SIZE (1..8))
+ -- digits of VGCS/VBC-area,Group-ID are concatenated in this order.
+
+TMSI ::= OCTET STRING (SIZE (1..4))
+
+SubscriberId ::= CHOICE {
+ imsi [0] IMSI,
+ tmsi [1] TMSI}
+
+IMEI ::= TBCD-STRING (SIZE (8))
+ -- Refers to International Mobile Station Equipment Identity
+ -- and Software Version Number (SVN) defined in TS 3GPP TS 23.003 [17].
+ -- If the SVN is not present the last octet shall contain the
+ -- digit 0 and a filler.
+ -- If present the SVN shall be included in the last octet.
+
+HLR-Id ::= IMSI
+ -- leading digits of IMSI, i.e. (MCC, MNC, leading digits of
+ -- MSIN) forming HLR Id defined in TS 3GPP TS 23.003 [17].
+
+HLR-List ::= SEQUENCE SIZE (1..maxNumOfHLR-Id) OF
+ HLR-Id
+
+maxNumOfHLR-Id INTEGER ::= 50
+
+LMSI ::= OCTET STRING (SIZE (4))
+
+GlobalCellId ::= OCTET STRING (SIZE (5..7))
+ -- Refers to Cell Global Identification defined in TS 3GPP TS 23.003 [17].
+ -- The internal structure is defined as follows:
+ -- octet 1 bits 4321 Mobile Country Code 1st digit
+ -- bits 8765 Mobile Country Code 2nd digit
+ -- octet 2 bits 4321 Mobile Country Code 3rd digit
+ -- bits 8765 Mobile Network Code 3rd digit
+ -- or filler (1111) for 2 digit MNCs
+ -- octet 3 bits 4321 Mobile Network Code 1st digit
+ -- bits 8765 Mobile Network Code 2nd digit
+ -- octets 4 and 5 Location Area Code according to TS 3GPP TS 24.008 [35]
+ -- octets 6 and 7 Cell Identity (CI) according to TS 3GPP TS 24.008 [35]
+
+NetworkResource ::= ENUMERATED {
+ plmn (0),
+ hlr (1),
+ vlr (2),
+ pvlr (3),
+ controllingMSC (4),
+ vmsc (5),
+ eir (6),
+ rss (7)}
+
+AdditionalNetworkResource ::= ENUMERATED {
+ sgsn (0),
+ ggsn (1),
+ gmlc (2),
+ gsmSCF (3),
+ nplr (4),
+ auc (5),
+ ...}
+ -- if unknown value is received in AdditionalNetworkResource
+ -- it shall be ignored.
+
+
+NAEA-PreferredCI ::= SEQUENCE {
+ naea-PreferredCIC [0] NAEA-CIC,
+ extensionContainer [1] ExtensionContainer OPTIONAL,
+ ...}
+
+NAEA-CIC ::= OCTET STRING (SIZE (3))
+ -- The internal structure is defined by the Carrier Identification
+ -- parameter in ANSI T1.113.3. Carrier codes between "000" and "999" may
+ -- be encoded as 3 digits using "000" to "999" or as 4 digits using
+ -- "0000" to "0999". Carrier codes between "1000" and "9999" are encoded
+ -- using 4 digits.
+
+SubscriberIdentity ::= CHOICE {
+ imsi [0] IMSI,
+ msisdn [1] ISDN-AddressString
+ }
+
+LCSClientExternalID ::= SEQUENCE {
+ externalAddress [0] ISDN-AddressString OPTIONAL,
+ extensionContainer [1] ExtensionContainer OPTIONAL,
+ ... }
+
+LCSClientInternalID ::= ENUMERATED {
+ broadcastService (0),
+ o-andM-HPLMN (1),
+ o-andM-VPLMN (2),
+ anonymousLocation (3),
+ targetMSsubscribedService (4),
+ ... }
+-- for a CAMEL phase 3 PLMN operator client, the value targetMSsubscribedService shall be used
+
+LCSServiceTypeID ::= INTEGER (0..127)
+ -- the integer values 0-63 are reserved for Standard LCS service types
+ -- the integer values 64-127 are reserved for Non Standard LCS service types
+
+-- Standard LCS Service Types
+emergencyServices LCSServiceTypeID ::= 0
+emergencyAlertServices LCSServiceTypeID ::= 1
+personTracking LCSServiceTypeID ::= 2
+fleetManagement LCSServiceTypeID ::= 3
+assetManagement LCSServiceTypeID ::= 4
+trafficCongestionReporting LCSServiceTypeID ::= 5
+roadsideAssistance LCSServiceTypeID ::= 6
+routingToNearestCommercialEnterprise LCSServiceTypeID ::= 7
+navigation LCSServiceTypeID ::= 8
+ --this service type is reserved for use in previous releases
+citySightseeing LCSServiceTypeID ::= 9
+localizedAdvertising LCSServiceTypeID ::= 10
+mobileYellowPages LCSServiceTypeID ::= 11
+trafficAndPublicTransportationInfo LCSServiceTypeID ::= 12
+weather LCSServiceTypeID ::= 13
+assetAndServiceFinding LCSServiceTypeID ::= 14
+gaming LCSServiceTypeID ::= 15
+findYourFriend LCSServiceTypeID ::= 16
+dating LCSServiceTypeID ::= 17
+chatting LCSServiceTypeID ::= 18
+routeFinding LCSServiceTypeID ::= 19
+whereAmI LCSServiceTypeID ::= 20
+
+-- The values of LCSServiceTypeID are defined according to 3GPP TS 22.071.
+
+-- Non Standard LCS Service Types
+serv64 LCSServiceTypeID ::= 64
+serv65 LCSServiceTypeID ::= 65
+serv66 LCSServiceTypeID ::= 66
+serv67 LCSServiceTypeID ::= 67
+serv68 LCSServiceTypeID ::= 68
+serv69 LCSServiceTypeID ::= 69
+serv70 LCSServiceTypeID ::= 70
+serv71 LCSServiceTypeID ::= 71
+serv72 LCSServiceTypeID ::= 72
+serv73 LCSServiceTypeID ::= 73
+serv74 LCSServiceTypeID ::= 74
+serv75 LCSServiceTypeID ::= 75
+serv76 LCSServiceTypeID ::= 76
+serv77 LCSServiceTypeID ::= 77
+serv78 LCSServiceTypeID ::= 78
+serv79 LCSServiceTypeID ::= 79
+serv80 LCSServiceTypeID ::= 80
+serv81 LCSServiceTypeID ::= 81
+serv82 LCSServiceTypeID ::= 82
+serv83 LCSServiceTypeID ::= 83
+serv84 LCSServiceTypeID ::= 84
+serv85 LCSServiceTypeID ::= 85
+serv86 LCSServiceTypeID ::= 86
+serv87 LCSServiceTypeID ::= 87
+serv88 LCSServiceTypeID ::= 88
+serv89 LCSServiceTypeID ::= 89
+serv90 LCSServiceTypeID ::= 90
+serv91 LCSServiceTypeID ::= 91
+serv92 LCSServiceTypeID ::= 92
+serv93 LCSServiceTypeID ::= 93
+serv94 LCSServiceTypeID ::= 94
+serv95 LCSServiceTypeID ::= 95
+serv96 LCSServiceTypeID ::= 96
+serv97 LCSServiceTypeID ::= 97
+serv98 LCSServiceTypeID ::= 98
+serv99 LCSServiceTypeID ::= 99
+serv100 LCSServiceTypeID ::= 100
+serv101 LCSServiceTypeID ::= 101
+serv102 LCSServiceTypeID ::= 102
+serv103 LCSServiceTypeID ::= 103
+serv104 LCSServiceTypeID ::= 104
+serv105 LCSServiceTypeID ::= 105
+serv106 LCSServiceTypeID ::= 106
+serv107 LCSServiceTypeID ::= 107
+serv108 LCSServiceTypeID ::= 108
+serv109 LCSServiceTypeID ::= 109
+serv110 LCSServiceTypeID ::= 110
+serv111 LCSServiceTypeID ::= 111
+serv112 LCSServiceTypeID ::= 112
+serv113 LCSServiceTypeID ::= 113
+serv114 LCSServiceTypeID ::= 114
+serv115 LCSServiceTypeID ::= 115
+serv116 LCSServiceTypeID ::= 116
+serv117 LCSServiceTypeID ::= 117
+serv118 LCSServiceTypeID ::= 118
+serv119 LCSServiceTypeID ::= 119
+serv120 LCSServiceTypeID ::= 120
+serv121 LCSServiceTypeID ::= 121
+serv122 LCSServiceTypeID ::= 122
+serv123 LCSServiceTypeID ::= 123
+serv124 LCSServiceTypeID ::= 124
+serv125 LCSServiceTypeID ::= 125
+serv126 LCSServiceTypeID ::= 126
+serv127 LCSServiceTypeID ::= 127
+
+-- data types for CAMEL
+
+CellGlobalIdOrServiceAreaIdOrLAI ::= CHOICE {
+ cellGlobalIdOrServiceAreaIdFixedLength [0] CellGlobalIdOrServiceAreaIdFixedLength,
+ laiFixedLength [1] LAIFixedLength}
+
+CellGlobalIdOrServiceAreaIdFixedLength ::= OCTET STRING (SIZE (7))
+ -- Refers to Cell Global Identification or Service Are Identification
+ -- defined in 3GPP TS 23.003.
+ -- The internal structure is defined as follows:
+ -- octet 1 bits 4321 Mobile Country Code 1st digit
+ -- bits 8765 Mobile Country Code 2nd digit
+ -- octet 2 bits 4321 Mobile Country Code 3rd digit
+ -- bits 8765 Mobile Network Code 3rd digit
+ -- or filler (1111) for 2 digit MNCs
+ -- octet 3 bits 4321 Mobile Network Code 1st digit
+ -- bits 8765 Mobile Network Code 2nd digit
+ -- octets 4 and 5 Location Area Code according to 3GPP TS 24.008
+ -- octets 6 and 7 Cell Identity (CI) value or
+ -- Service Area Code (SAC) value
+ -- according to 3GPP TS 23.003
+
+LAIFixedLength ::= OCTET STRING (SIZE (5))
+ -- Refers to Location Area Identification defined in TS 3GPP TS 23.003 [17].
+ -- The internal structure is defined as follows:
+ -- octet 1 bits 4321 Mobile Country Code 1st digit
+ -- bits 8765 Mobile Country Code 2nd digit
+ -- octet 2 bits 4321 Mobile Country Code 3rd digit
+ -- bits 8765 Mobile Network Code 3rd digit
+ -- or filler (1111) for 2 digit MNCs
+ -- octet 3 bits 4321 Mobile Network Code 1st digit
+ -- bits 8765 Mobile Network Code 2nd digit
+ -- octets 4 and 5 Location Area Code according to TS 3GPP TS 24.008 [35]
+
+-- data types for subscriber management
+
+BasicServiceCode ::= CHOICE {
+ bearerService [2] BearerServiceCode,
+ teleservice [3] TeleserviceCode}
+
+Ext-BasicServiceCode ::= CHOICE {
+ ext-BearerService [2] Ext-BearerServiceCode,
+ ext-Teleservice [3] Ext-TeleserviceCode}
+
+EMLPP-Info ::= SEQUENCE {
+ maximumentitledPriority EMLPP-Priority,
+ defaultPriority EMLPP-Priority,
+ extensionContainer ExtensionContainer OPTIONAL,
+ ...}
+
+EMLPP-Priority ::= INTEGER (0..15)
+ -- The mapping from the values A,B,0,1,2,3,4 to the integer-value is
+ -- specified as follows where A is the highest and 4 is the lowest
+ -- priority level
+ -- the integer values 7-15 are spare and shall be mapped to value 4
+
+priorityLevelA EMLPP-Priority ::= 6
+priorityLevelB EMLPP-Priority ::= 5
+priorityLevel0 EMLPP-Priority ::= 0
+priorityLevel1 EMLPP-Priority ::= 1
+priorityLevel2 EMLPP-Priority ::= 2
+priorityLevel3 EMLPP-Priority ::= 3
+priorityLevel4 EMLPP-Priority ::= 4
+
+MC-SS-Info ::= SEQUENCE {
+ ss-Code [0] SS-Code,
+ ss-Status [1] Ext-SS-Status,
+ nbrSB [2] MaxMC-Bearers,
+ nbrUser [3] MC-Bearers,
+ extensionContainer [4] ExtensionContainer OPTIONAL,
+ ...}
+
+MaxMC-Bearers ::= INTEGER (2..maxNumOfMC-Bearers)
+
+MC-Bearers ::= INTEGER (1..maxNumOfMC-Bearers)
+
+maxNumOfMC-Bearers INTEGER ::= 7
+
+Ext-SS-Status ::= OCTET STRING (SIZE (1..5))
+
+ -- OCTET 1:
+ --
+ -- bits 8765: 0000 (unused)
+ -- bits 4321: Used to convey the "P bit","R bit","A bit" and "Q bit",
+ -- representing supplementary service state information
+ -- as defined in TS 3GPP TS 23.011 [22]
+
+ -- bit 4: "Q bit"
+
+ -- bit 3: "P bit"
+
+ -- bit 2: "R bit"
+
+ -- bit 1: "A bit"
+
+ -- OCTETS 2-5: reserved for future use. They shall be discarded if
+ -- received and not understood.
+
+
+ -- data types for geographic location
+
+AgeOfLocationInformation ::= INTEGER (0..32767)
+-- the value represents the elapsed time in minutes since the last
+-- network contact of the mobile station (i.e. the actuality of the
+-- location information).
+-- value "0" indicates that the MS is currently in contact with the
+-- network
+-- value "32767" indicates that the location information is at least
+-- 32767 minutes old
+
+END
diff --git a/lib/asn1/test/asn1_SUITE_data/tcapsystem/MAP-DialogueInformation.asn b/lib/asn1/test/asn1_SUITE_data/tcapsystem/MAP-DialogueInformation.asn
new file mode 100644
index 0000000000..5854cbe6b8
--- /dev/null
+++ b/lib/asn1/test/asn1_SUITE_data/tcapsystem/MAP-DialogueInformation.asn
@@ -0,0 +1,149 @@
+MAP-DialogueInformation {
+ itu-t identified-organization (4) etsi (0) mobileDomain (0)
+ gsm-Network (1) modules (3) map-DialogueInformation (3) version9 (9)}
+
+DEFINITIONS
+
+IMPLICIT TAGS
+
+::=
+
+BEGIN
+
+EXPORTS
+ map-DialogueAS,
+ MAP-DialoguePDU,
+ map-ProtectedDialogueAS,
+ MAP-ProtectedDialoguePDU
+
+;
+
+IMPORTS
+ gsm-NetworkId,
+ as-Id
+FROM MobileDomainDefinitions {
+ itu-t (0) identified-organization (4) etsi (0) mobileDomain (0)
+ mobileDomainDefinitions (0) version1 (1)}
+
+ AddressString
+FROM MAP-CommonDataTypes {
+ itu-t identified-organization (4) etsi (0) mobileDomain (0)
+ gsm-Network(1) modules (3) map-CommonDataTypes (18) version9 (9)}
+
+ ExtensionContainer
+FROM MAP-ExtensionDataTypes {
+ itu-t identified-organization (4) etsi (0) mobileDomain (0)
+ gsm-Network (1) modules (3) map-ExtensionDataTypes (21) version9 (9)}
+
+ SecurityHeader,
+ ProtectedPayload
+FROM MAP-ST-DataTypes {
+ itu-t identified-organization (4) etsi (0) mobileDomain (0)
+ gsm-Network (1) modules (3) map-ST-DataTypes (27) version9 (9)}
+
+;
+
+
+-- abstract syntax name for MAP-DialoguePDU
+
+map-DialogueAS OBJECT IDENTIFIER ::=
+ {gsm-NetworkId as-Id map-DialoguePDU (1) version1 (1)}
+
+MAP-DialoguePDU ::= CHOICE {
+ map-open [0] MAP-OpenInfo,
+ map-accept [1] MAP-AcceptInfo,
+ map-close [2] MAP-CloseInfo,
+ map-refuse [3] MAP-RefuseInfo,
+ map-userAbort [4] MAP-UserAbortInfo,
+ map-providerAbort [5] MAP-ProviderAbortInfo}
+
+MAP-OpenInfo ::= SEQUENCE {
+ destinationReference [0] AddressString OPTIONAL,
+ originationReference [1] AddressString OPTIONAL,
+ ...,
+ extensionContainer ExtensionContainer OPTIONAL
+ -- extensionContainer must not be used in version 2
+ }
+
+MAP-AcceptInfo ::= SEQUENCE {
+ ...,
+ extensionContainer ExtensionContainer OPTIONAL
+ -- extensionContainer must not be used in version 2
+ }
+
+MAP-CloseInfo ::= SEQUENCE {
+ ...,
+ extensionContainer ExtensionContainer OPTIONAL
+ -- extensionContainer must not be used in version 2
+ }
+
+MAP-RefuseInfo ::= SEQUENCE {
+ reason Reason,
+ ...,
+ extensionContainer ExtensionContainer OPTIONAL,
+ -- extensionContainer must not be used in version 2
+ alternativeApplicationContext OBJECT IDENTIFIER OPTIONAL
+ -- alternativeApplicationContext must not be used in version 2
+ }
+
+Reason ::= ENUMERATED {
+ noReasonGiven (0),
+ invalidDestinationReference (1),
+ invalidOriginatingReference (2),
+ encapsulatedAC-NotSupported (3) ,
+ transportProtectionNotAdequate (4)}
+ -- encapsulatedAC-NotSupported and transportProtectionNotAdequate must not be used in
+ -- dialogues with an AC different from secureTransportHandling
+
+MAP-UserAbortInfo ::= SEQUENCE {
+ map-UserAbortChoice MAP-UserAbortChoice,
+ ...,
+ extensionContainer ExtensionContainer OPTIONAL
+ -- extensionContainer must not be used in version 2
+ }
+
+MAP-UserAbortChoice ::= CHOICE {
+ userSpecificReason [0] NULL,
+ userResourceLimitation [1] NULL,
+ resourceUnavailable [2] ResourceUnavailableReason,
+ applicationProcedureCancellation [3] ProcedureCancellationReason}
+
+ResourceUnavailableReason ::= ENUMERATED {
+ shortTermResourceLimitation (0),
+ longTermResourceLimitation (1)}
+
+ProcedureCancellationReason ::= ENUMERATED {
+ handoverCancellation (0),
+ radioChannelRelease (1),
+ networkPathRelease (2),
+ callRelease (3),
+ associatedProcedureFailure (4),
+ tandemDialogueRelease (5),
+ remoteOperationsFailure (6)}
+
+MAP-ProviderAbortInfo ::= SEQUENCE {
+ map-ProviderAbortReason MAP-ProviderAbortReason,
+ ...,
+ extensionContainer ExtensionContainer OPTIONAL
+ -- extensionContainer must not be used in version 2
+ }
+
+MAP-ProviderAbortReason ::= ENUMERATED {
+ abnormalDialogue (0),
+ invalidPDU (1)}
+
+-- abstract syntax name for MAP-ProtectedDialoguePDU
+
+map-ProtectedDialogueAS OBJECT IDENTIFIER ::=
+ {gsm-NetworkId as-Id map-ProtectedDialoguePDU (3) version1 (1)}
+
+MAP-ProtectedDialoguePDU ::= SEQUENCE {
+ encapsulatedAC OBJECT IDENTIFIER,
+ securityHeader SecurityHeader OPTIONAL,
+ protectedPayload ProtectedPayload OPTIONAL,
+ ...}
+ -- The protectedPayload carries the result of applying the security function
+ -- defined in 3GPP TS 33.200 to the encoding of the securely transported
+ -- MAP-DialoguePDU
+
+END
diff --git a/lib/asn1/test/asn1_SUITE_data/tcapsystem/MAP-ER-DataTypes.asn b/lib/asn1/test/asn1_SUITE_data/tcapsystem/MAP-ER-DataTypes.asn
new file mode 100644
index 0000000000..b66702cb61
--- /dev/null
+++ b/lib/asn1/test/asn1_SUITE_data/tcapsystem/MAP-ER-DataTypes.asn
@@ -0,0 +1,405 @@
+MAP-ER-DataTypes {
+ itu-t identified-organization (4) etsi (0) mobileDomain (0)
+ gsm-Network (1) modules (3) map-ER-DataTypes (17) version9 (9)}
+
+DEFINITIONS
+
+IMPLICIT TAGS
+
+::=
+
+BEGIN
+
+EXPORTS
+ RoamingNotAllowedParam,
+ CallBarredParam,
+ CUG-RejectParam,
+ SS-IncompatibilityCause,
+ PW-RegistrationFailureCause,
+ SM-DeliveryFailureCause,
+ SystemFailureParam,
+ DataMissingParam,
+ UnexpectedDataParam,
+ FacilityNotSupParam,
+ OR-NotAllowedParam,
+ UnknownSubscriberParam,
+ NumberChangedParam,
+ UnidentifiedSubParam,
+ IllegalSubscriberParam,
+ IllegalEquipmentParam,
+ BearerServNotProvParam,
+ TeleservNotProvParam,
+ TracingBufferFullParam,
+ NoRoamingNbParam,
+ AbsentSubscriberParam,
+ BusySubscriberParam,
+ NoSubscriberReplyParam,
+ ForwardingViolationParam,
+ ForwardingFailedParam,
+ ATI-NotAllowedParam,
+ SubBusyForMT-SMS-Param,
+ MessageWaitListFullParam,
+ AbsentSubscriberSM-Param,
+ AbsentSubscriberDiagnosticSM,
+ ResourceLimitationParam,
+ NoGroupCallNbParam,
+ IncompatibleTerminalParam,
+ ShortTermDenialParam,
+ LongTermDenialParam,
+ UnauthorizedRequestingNetwork-Param,
+ UnauthorizedLCSClient-Param,
+ PositionMethodFailure-Param,
+ UnknownOrUnreachableLCSClient-Param,
+ MM-EventNotSupported-Param,
+ SecureTransportErrorParam,
+ ATSI-NotAllowedParam,
+ ATM-NotAllowedParam,
+ IllegalSS-OperationParam,
+ SS-NotAvailableParam,
+ SS-SubscriptionViolationParam,
+ InformationNotAvailableParam,
+ TargetCellOutsideGCA-Param
+
+;
+
+IMPORTS
+ SS-Status
+FROM MAP-SS-DataTypes {
+ itu-t identified-organization (4) etsi (0) mobileDomain (0)
+ gsm-Network (1) modules (3) map-SS-DataTypes (14) version9 (9)}
+
+ SignalInfo,
+ BasicServiceCode,
+ NetworkResource,
+ AdditionalNetworkResource
+FROM MAP-CommonDataTypes {
+ itu-t identified-organization (4) etsi (0) mobileDomain (0)
+ gsm-Network (1) modules (3) map-CommonDataTypes (18) version9 (9)}
+
+ SecurityHeader,
+ ProtectedPayload
+FROM MAP-ST-DataTypes {
+ itu-t identified-organization (4) etsi (0) mobileDomain (0)
+ gsm-Network (1) modules (3) map-ST-DataTypes (27) version9 (9)}
+
+
+ SS-Code
+FROM MAP-SS-Code {
+ itu-t identified-organization (4) etsi (0) mobileDomain (0)
+ gsm-Network (1) modules (3) map-SS-Code (15) version9 (9)}
+
+ ExtensionContainer
+FROM MAP-ExtensionDataTypes {
+ itu-t identified-organization (4) etsi (0) mobileDomain (0)
+ gsm-Network (1) modules (3) map-ExtensionDataTypes (21) version9 (9)}
+;
+
+RoamingNotAllowedParam ::= SEQUENCE {
+ roamingNotAllowedCause RoamingNotAllowedCause,
+ extensionContainer ExtensionContainer OPTIONAL,
+ ...}
+
+RoamingNotAllowedCause ::= ENUMERATED {
+ plmnRoamingNotAllowed (0),
+ operatorDeterminedBarring (3)}
+
+CallBarredParam ::= CHOICE {
+ callBarringCause CallBarringCause,
+ -- call BarringCause must not be used in version 3 and higher
+ extensibleCallBarredParam ExtensibleCallBarredParam
+ -- extensibleCallBarredParam must not be used in version <3
+ }
+
+CallBarringCause ::= ENUMERATED {
+ barringServiceActive (0),
+ operatorBarring (1)}
+
+ExtensibleCallBarredParam ::= SEQUENCE {
+ callBarringCause CallBarringCause OPTIONAL,
+ extensionContainer ExtensionContainer OPTIONAL,
+ ... ,
+ unauthorisedMessageOriginator [1] NULL OPTIONAL }
+
+CUG-RejectParam ::= SEQUENCE {
+ cug-RejectCause CUG-RejectCause OPTIONAL,
+ extensionContainer ExtensionContainer OPTIONAL,
+ ...}
+
+CUG-RejectCause ::= ENUMERATED {
+ incomingCallsBarredWithinCUG (0),
+ subscriberNotMemberOfCUG (1),
+ requestedBasicServiceViolatesCUG-Constraints (5),
+ calledPartySS-InteractionViolation (7)}
+
+SS-IncompatibilityCause ::= SEQUENCE {
+ ss-Code [1] SS-Code OPTIONAL,
+ basicService BasicServiceCode OPTIONAL,
+ ss-Status [4] SS-Status OPTIONAL,
+ ...}
+
+PW-RegistrationFailureCause ::= ENUMERATED {
+ undetermined (0),
+ invalidFormat (1),
+ newPasswordsMismatch (2)}
+
+SM-EnumeratedDeliveryFailureCause ::= ENUMERATED {
+ memoryCapacityExceeded (0),
+ equipmentProtocolError (1),
+ equipmentNotSM-Equipped (2),
+ unknownServiceCentre (3),
+ sc-Congestion (4),
+ invalidSME-Address (5),
+ subscriberNotSC-Subscriber (6)}
+
+SM-DeliveryFailureCause ::= SEQUENCE {
+ sm-EnumeratedDeliveryFailureCause SM-EnumeratedDeliveryFailureCause,
+ diagnosticInfo SignalInfo OPTIONAL,
+ extensionContainer ExtensionContainer OPTIONAL,
+ ...}
+
+AbsentSubscriberSM-Param ::= SEQUENCE {
+ absentSubscriberDiagnosticSM AbsentSubscriberDiagnosticSM OPTIONAL,
+ -- AbsentSubscriberDiagnosticSM can be either for non-GPRS
+ -- or for GPRS
+ extensionContainer ExtensionContainer OPTIONAL,
+ ...,
+ additionalAbsentSubscriberDiagnosticSM [0] AbsentSubscriberDiagnosticSM OPTIONAL }
+ -- if received, additionalAbsentSubscriberDiagnosticSM
+ -- is for GPRS and absentSubscriberDiagnosticSM is
+ -- for non-GPRS
+
+AbsentSubscriberDiagnosticSM ::= INTEGER (0..255)
+ -- AbsentSubscriberDiagnosticSM values are defined in 3GPP TS 23.040
+
+SystemFailureParam ::= CHOICE {
+ networkResource NetworkResource,
+ -- networkResource must not be used in version 3
+ extensibleSystemFailureParam ExtensibleSystemFailureParam
+ -- extensibleSystemFailureParam must not be used in version <3
+ }
+
+ExtensibleSystemFailureParam ::= SEQUENCE {
+ networkResource NetworkResource OPTIONAL,
+ extensionContainer ExtensionContainer OPTIONAL,
+ ...,
+ additionalNetworkResource [0] AdditionalNetworkResource OPTIONAL }
+
+DataMissingParam ::= SEQUENCE {
+ extensionContainer ExtensionContainer OPTIONAL,
+ ...}
+
+UnexpectedDataParam ::= SEQUENCE {
+ extensionContainer ExtensionContainer OPTIONAL,
+ ...}
+
+FacilityNotSupParam ::= SEQUENCE {
+ extensionContainer ExtensionContainer OPTIONAL,
+ ...,
+ shapeOfLocationEstimateNotSupported [0] NULL OPTIONAL,
+ neededLcsCapabilityNotSupportedInServingNode [1] NULL OPTIONAL }
+
+OR-NotAllowedParam ::= SEQUENCE {
+ extensionContainer ExtensionContainer OPTIONAL,
+ ...}
+
+UnknownSubscriberParam ::= SEQUENCE {
+ extensionContainer ExtensionContainer OPTIONAL,
+ ...,
+ unknownSubscriberDiagnostic UnknownSubscriberDiagnostic OPTIONAL}
+
+UnknownSubscriberDiagnostic ::= ENUMERATED {
+ imsiUnknown (0),
+ gprsSubscriptionUnknown (1),
+ ...,
+ npdbMismatch (2)}
+ -- if unknown values are received in
+ -- UnknownSubscriberDiagnostic they shall be discarded
+
+NumberChangedParam ::= SEQUENCE {
+ extensionContainer ExtensionContainer OPTIONAL,
+ ...}
+
+UnidentifiedSubParam ::= SEQUENCE {
+ extensionContainer ExtensionContainer OPTIONAL,
+ ...}
+
+IllegalSubscriberParam ::= SEQUENCE {
+ extensionContainer ExtensionContainer OPTIONAL,
+ ...}
+
+IllegalEquipmentParam ::= SEQUENCE {
+ extensionContainer ExtensionContainer OPTIONAL,
+ ...}
+
+BearerServNotProvParam ::= SEQUENCE {
+ extensionContainer ExtensionContainer OPTIONAL,
+ ...}
+
+TeleservNotProvParam ::= SEQUENCE {
+ extensionContainer ExtensionContainer OPTIONAL,
+ ...}
+
+TracingBufferFullParam ::= SEQUENCE {
+ extensionContainer ExtensionContainer OPTIONAL,
+ ...}
+
+NoRoamingNbParam ::= SEQUENCE {
+ extensionContainer ExtensionContainer OPTIONAL,
+ ...}
+
+AbsentSubscriberParam ::= SEQUENCE {
+ extensionContainer ExtensionContainer OPTIONAL,
+ ...,
+ absentSubscriberReason [0] AbsentSubscriberReason OPTIONAL}
+
+AbsentSubscriberReason ::= ENUMERATED {
+ imsiDetach (0),
+ restrictedArea (1),
+ noPageResponse (2),
+ ... ,
+ purgedMS (3)}
+-- exception handling: at reception of other values than the ones listed the
+-- AbsentSubscriberReason shall be ignored.
+-- The AbsentSubscriberReason: purgedMS is defined for the Super-Charger feature
+-- (see TS 23.116). If this value is received in a Provide Roaming Number response
+-- it shall be mapped to the AbsentSubscriberReason: imsiDetach in the Send Routeing
+-- Information response
+
+BusySubscriberParam ::= SEQUENCE {
+ extensionContainer ExtensionContainer OPTIONAL,
+ ...,
+ ccbs-Possible [0] NULL OPTIONAL,
+ ccbs-Busy [1] NULL OPTIONAL}
+
+NoSubscriberReplyParam ::= SEQUENCE {
+ extensionContainer ExtensionContainer OPTIONAL,
+ ...}
+
+ForwardingViolationParam ::= SEQUENCE {
+ extensionContainer ExtensionContainer OPTIONAL,
+ ...}
+
+ForwardingFailedParam ::= SEQUENCE {
+ extensionContainer ExtensionContainer OPTIONAL,
+ ...}
+
+ATI-NotAllowedParam ::= SEQUENCE {
+ extensionContainer ExtensionContainer OPTIONAL,
+ ...}
+
+ATSI-NotAllowedParam ::= SEQUENCE {
+ extensionContainer ExtensionContainer OPTIONAL,
+ ...}
+
+ATM-NotAllowedParam ::= SEQUENCE {
+ extensionContainer ExtensionContainer OPTIONAL,
+ ...}
+
+IllegalSS-OperationParam ::= SEQUENCE {
+ extensionContainer ExtensionContainer OPTIONAL,
+ ...}
+
+SS-NotAvailableParam ::= SEQUENCE {
+ extensionContainer ExtensionContainer OPTIONAL,
+ ...}
+
+SS-SubscriptionViolationParam ::= SEQUENCE {
+ extensionContainer ExtensionContainer OPTIONAL,
+ ...}
+
+InformationNotAvailableParam ::= SEQUENCE {
+ extensionContainer ExtensionContainer OPTIONAL,
+ ...}
+
+SubBusyForMT-SMS-Param ::= SEQUENCE {
+ extensionContainer ExtensionContainer OPTIONAL,
+ ... ,
+ gprsConnectionSuspended NULL OPTIONAL }
+ -- If GprsConnectionSuspended is not understood it shall
+ -- be discarded
+
+MessageWaitListFullParam ::= SEQUENCE {
+ extensionContainer ExtensionContainer OPTIONAL,
+ ...}
+
+ResourceLimitationParam ::= SEQUENCE {
+ extensionContainer ExtensionContainer OPTIONAL,
+ ...}
+
+NoGroupCallNbParam ::= SEQUENCE {
+ extensionContainer ExtensionContainer OPTIONAL,
+ ...}
+
+IncompatibleTerminalParam ::= SEQUENCE {
+ extensionContainer ExtensionContainer OPTIONAL,
+ ...}
+
+ShortTermDenialParam ::= SEQUENCE {
+ ...}
+
+LongTermDenialParam ::= SEQUENCE {
+ ...}
+
+UnauthorizedRequestingNetwork-Param ::= SEQUENCE {
+ extensionContainer ExtensionContainer OPTIONAL,
+ ...}
+
+UnauthorizedLCSClient-Param ::= SEQUENCE {
+ unauthorizedLCSClient-Diagnostic [0] UnauthorizedLCSClient-Diagnostic OPTIONAL,
+ extensionContainer [1] ExtensionContainer OPTIONAL,
+ ... }
+
+UnauthorizedLCSClient-Diagnostic ::= ENUMERATED {
+ noAdditionalInformation (0),
+ clientNotInMSPrivacyExceptionList (1),
+ callToClientNotSetup (2),
+ privacyOverrideNotApplicable (3),
+ disallowedByLocalRegulatoryRequirements (4),
+ ...,
+ unauthorizedPrivacyClass (5),
+ unauthorizedCallSessionUnrelatedExternalClient (6),
+ unauthorizedCallSessionRelatedExternalClient (7) }
+-- exception handling:
+-- any unrecognized value shall be ignored
+
+PositionMethodFailure-Param ::= SEQUENCE {
+ positionMethodFailure-Diagnostic [0] PositionMethodFailure-Diagnostic OPTIONAL,
+ extensionContainer [1] ExtensionContainer OPTIONAL,
+ ... }
+
+PositionMethodFailure-Diagnostic ::= ENUMERATED {
+ congestion (0),
+ insufficientResources (1),
+ insufficientMeasurementData (2),
+ inconsistentMeasurementData (3),
+ locationProcedureNotCompleted (4),
+ locationProcedureNotSupportedByTargetMS (5),
+ qoSNotAttainable (6),
+ positionMethodNotAvailableInNetwork (7),
+ positionMethodNotAvailableInLocationArea (8),
+ ... }
+-- exception handling:
+-- any unrecognized value shall be ignored
+
+UnknownOrUnreachableLCSClient-Param ::= SEQUENCE {
+ extensionContainer ExtensionContainer OPTIONAL,
+ ...}
+
+MM-EventNotSupported-Param ::= SEQUENCE {
+ extensionContainer ExtensionContainer OPTIONAL,
+ ...}
+
+TargetCellOutsideGCA-Param ::= SEQUENCE {
+ extensionContainer ExtensionContainer OPTIONAL,
+ ...}
+
+SecureTransportErrorParam ::= SEQUENCE {
+ securityHeader SecurityHeader,
+ protectedPayload ProtectedPayload OPTIONAL
+ }
+ -- The protectedPayload carries the result of applying the security function
+ -- defined in 3GPP TS 33.200 to the encoding of the securely transported error
+ -- parameter
+
+
+END
diff --git a/lib/asn1/test/asn1_SUITE_data/tcapsystem/MAP-Errors.asn b/lib/asn1/test/asn1_SUITE_data/tcapsystem/MAP-Errors.asn
new file mode 100644
index 0000000000..f0aa2b0a3a
--- /dev/null
+++ b/lib/asn1/test/asn1_SUITE_data/tcapsystem/MAP-Errors.asn
@@ -0,0 +1,507 @@
+MAP-Errors {
+ itu-t identified-organization (4) etsi (0) mobileDomain (0)
+ gsm-Network (1) modules (3) map-Errors (10) version9 (9)}
+
+DEFINITIONS
+
+::=
+
+BEGIN
+
+EXPORTS
+
+ -- generic errors
+ systemFailure,
+ dataMissing,
+ unexpectedDataValue,
+ facilityNotSupported,
+ incompatibleTerminal,
+ resourceLimitation,
+
+ -- identification and numbering errors
+ unknownSubscriber,
+ numberChanged,
+ unknownMSC,
+ unidentifiedSubscriber,
+ unknownEquipment,
+
+ -- subscription errors
+ roamingNotAllowed,
+ illegalSubscriber,
+ illegalEquipment,
+ bearerServiceNotProvisioned,
+ teleserviceNotProvisioned,
+
+ -- handover errors
+ noHandoverNumberAvailable,
+ subsequentHandoverFailure,
+ targetCellOutsideGroupCallArea,
+
+ -- operation and maintenance errors
+ tracingBufferFull,
+
+ -- call handling errors
+ or-NotAllowed,
+ noRoamingNumberAvailable,
+ busySubscriber,
+ noSubscriberReply,
+ absentSubscriber,
+ callBarred,
+ forwardingViolation,
+ forwardingFailed,
+ cug-Reject,
+
+ -- any time interrogation errors
+ ati-NotAllowed,
+
+ -- any time information handling errors
+ atsi-NotAllowed,
+ atm-NotAllowed,
+ informationNotAvailable,
+
+ -- supplementary service errors
+ illegalSS-Operation,
+ ss-ErrorStatus,
+ ss-NotAvailable,
+ ss-SubscriptionViolation,
+ ss-Incompatibility,
+ unknownAlphabet,
+ ussd-Busy,
+ pw-RegistrationFailure,
+ negativePW-Check,
+ numberOfPW-AttemptsViolation,
+ shortTermDenial,
+ longTermDenial,
+
+ -- short message service errors
+ subscriberBusyForMT-SMS,
+ sm-DeliveryFailure,
+ messageWaitingListFull,
+ absentSubscriberSM,
+
+ -- Group Call errors
+ noGroupCallNumberAvailable,
+
+ -- location service errors
+ unauthorizedRequestingNetwork,
+ unauthorizedLCSClient,
+ positionMethodFailure,
+ unknownOrUnreachableLCSClient,
+
+ -- Mobility Management errors
+ mm-EventNotSupported,
+
+ -- Secure transport errors
+ secureTransportError
+
+;
+
+IMPORTS
+ ERROR
+FROM Remote-Operations-Information-Objects {joint-iso-itu-t remote-operations(4)
+ informationObjects(5) version1(0) }
+
+ SS-Status
+FROM MAP-SS-DataTypes {
+ itu-t identified-organization (4) etsi (0) mobileDomain (0)
+ gsm-Network (1) modules (3) map-SS-DataTypes (14) version9 (9)}
+
+ SS-IncompatibilityCause,
+ PW-RegistrationFailureCause,
+ SM-DeliveryFailureCause,
+ SystemFailureParam,
+ DataMissingParam,
+ UnexpectedDataParam,
+ FacilityNotSupParam,
+ UnknownSubscriberParam,
+ NumberChangedParam,
+ UnidentifiedSubParam,
+ RoamingNotAllowedParam,
+ IllegalSubscriberParam,
+ IllegalEquipmentParam,
+ BearerServNotProvParam,
+ TeleservNotProvParam,
+ TracingBufferFullParam,
+ NoRoamingNbParam,
+ OR-NotAllowedParam,
+ AbsentSubscriberParam,
+ BusySubscriberParam,
+ NoSubscriberReplyParam,
+ CallBarredParam,
+ ForwardingViolationParam,
+ ForwardingFailedParam,
+ CUG-RejectParam,
+ ATI-NotAllowedParam,
+ SubBusyForMT-SMS-Param,
+ MessageWaitListFullParam,
+ AbsentSubscriberSM-Param,
+ ResourceLimitationParam,
+ NoGroupCallNbParam,
+ IncompatibleTerminalParam,
+ ShortTermDenialParam,
+ LongTermDenialParam,
+ UnauthorizedRequestingNetwork-Param,
+ UnauthorizedLCSClient-Param,
+ PositionMethodFailure-Param,
+ UnknownOrUnreachableLCSClient-Param,
+ MM-EventNotSupported-Param,
+ ATSI-NotAllowedParam,
+ ATM-NotAllowedParam,
+ IllegalSS-OperationParam,
+ SS-NotAvailableParam,
+ SS-SubscriptionViolationParam,
+ InformationNotAvailableParam,
+ TargetCellOutsideGCA-Param,
+ SecureTransportErrorParam
+FROM MAP-ER-DataTypes {
+ itu-t identified-organization (4) etsi (0) mobileDomain (0)
+ gsm-Network (1) modules (3) map-ER-DataTypes (17) version9 (9)}
+;
+
+-- generic errors
+
+systemFailure ERROR ::= {
+ PARAMETER
+ SystemFailureParam
+ -- optional
+ CODE local:34 }
+
+dataMissing ERROR ::= {
+ PARAMETER
+ DataMissingParam
+ -- optional
+ -- DataMissingParam must not be used in version <3
+ CODE local:35 }
+
+unexpectedDataValue ERROR ::= {
+ PARAMETER
+ UnexpectedDataParam
+ -- optional
+ -- UnexpectedDataParam must not be used in version <3
+ CODE local:36 }
+
+facilityNotSupported ERROR ::= {
+ PARAMETER
+ FacilityNotSupParam
+ -- optional
+ -- FacilityNotSupParam must not be used in version <3
+ CODE local:21 }
+
+incompatibleTerminal ERROR ::= {
+ PARAMETER
+ IncompatibleTerminalParam
+ -- optional
+ CODE local:28 }
+
+resourceLimitation ERROR ::= {
+ PARAMETER
+ ResourceLimitationParam
+ -- optional
+ CODE local:51 }
+
+-- identification and numbering errors
+
+unknownSubscriber ERROR ::= {
+ PARAMETER
+ UnknownSubscriberParam
+ -- optional
+ -- UnknownSubscriberParam must not be used in version <3
+ CODE local:1 }
+
+numberChanged ERROR ::= {
+ PARAMETER
+ NumberChangedParam
+ -- optional
+ CODE local:44 }
+
+unknownMSC ERROR ::= {
+ CODE local:3 }
+
+unidentifiedSubscriber ERROR ::= {
+ PARAMETER
+ UnidentifiedSubParam
+ -- optional
+ -- UunidentifiedSubParam must not be used in version <3
+ CODE local:5 }
+
+unknownEquipment ERROR ::= {
+ CODE local:7 }
+
+-- subscription errors
+
+roamingNotAllowed ERROR ::= {
+ PARAMETER
+ RoamingNotAllowedParam
+ CODE local:8 }
+
+illegalSubscriber ERROR ::= {
+ PARAMETER
+ IllegalSubscriberParam
+ -- optional
+ -- IllegalSubscriberParam must not be used in version <3
+ CODE local:9 }
+
+illegalEquipment ERROR ::= {
+ PARAMETER
+ IllegalEquipmentParam
+ -- optional
+ -- IllegalEquipmentParam must not be used in version <3
+ CODE local:12 }
+
+bearerServiceNotProvisioned ERROR ::= {
+ PARAMETER
+ BearerServNotProvParam
+ -- optional
+ -- BearerServNotProvParam must not be used in version <3
+ CODE local:10 }
+
+teleserviceNotProvisioned ERROR ::= {
+ PARAMETER
+ TeleservNotProvParam
+ -- optional
+ -- TeleservNotProvParam must not be used in version <3
+ CODE local:11 }
+
+-- handover errors
+
+noHandoverNumberAvailable ERROR ::= {
+ CODE local:25 }
+
+subsequentHandoverFailure ERROR ::= {
+ CODE local:26 }
+
+targetCellOutsideGroupCallArea ERROR ::= {
+ PARAMETER
+ TargetCellOutsideGCA-Param
+ -- optional
+ CODE local:42 }
+
+-- operation and maintenance errors
+
+tracingBufferFull ERROR ::= {
+ PARAMETER
+ TracingBufferFullParam
+ -- optional
+ CODE local: 40 }
+
+-- call handling errors
+
+noRoamingNumberAvailable ERROR ::= {
+ PARAMETER
+ NoRoamingNbParam
+ -- optional
+ CODE local:39 }
+
+absentSubscriber ERROR ::= {
+ PARAMETER
+ AbsentSubscriberParam
+ -- optional
+ -- AbsentSubscriberParam must not be used in version <3
+ CODE local:27 }
+
+busySubscriber ERROR ::= {
+ PARAMETER
+ BusySubscriberParam
+ -- optional
+ CODE local:45 }
+
+noSubscriberReply ERROR ::= {
+ PARAMETER
+ NoSubscriberReplyParam
+ -- optional
+ CODE local:46 }
+
+callBarred ERROR ::= {
+ PARAMETER
+ CallBarredParam
+ -- optional
+ CODE local:13 }
+
+forwardingViolation ERROR ::= {
+ PARAMETER
+ ForwardingViolationParam
+ -- optional
+ CODE local:14 }
+
+forwardingFailed ERROR ::= {
+ PARAMETER
+ ForwardingFailedParam
+ -- optional
+ CODE local:47 }
+
+cug-Reject ERROR ::= {
+ PARAMETER
+ CUG-RejectParam
+ -- optional
+ CODE local:15 }
+
+or-NotAllowed ERROR ::= {
+ PARAMETER
+ OR-NotAllowedParam
+ -- optional
+ CODE local:48 }
+
+-- any time interrogation errors
+ati-NotAllowed ERROR ::= {
+ PARAMETER
+ ATI-NotAllowedParam
+ -- optional
+ CODE local:49 }
+
+-- any time information handling errors
+atsi-NotAllowed ERROR ::= {
+ PARAMETER
+ ATSI-NotAllowedParam
+ -- optional
+ CODE local:60 }
+
+atm-NotAllowed ERROR ::= {
+ PARAMETER
+ ATM-NotAllowedParam
+ -- optional
+ CODE local:61 }
+
+informationNotAvailable ERROR ::= {
+ PARAMETER
+ InformationNotAvailableParam
+ -- optional
+ CODE local:62 }
+
+-- supplementary service errors
+
+illegalSS-Operation ERROR ::= {
+ PARAMETER
+ IllegalSS-OperationParam
+ -- optional
+ -- IllegalSS-OperationParam must not be used in version <3
+ CODE local:16 }
+
+ss-ErrorStatus ERROR ::= {
+ PARAMETER
+ SS-Status
+ -- optional
+ CODE local:17 }
+
+ss-NotAvailable ERROR ::= {
+ PARAMETER
+ SS-NotAvailableParam
+ -- optional
+ -- SS-NotAvailableParam must not be used in version <3
+ CODE local:18 }
+
+ss-SubscriptionViolation ERROR ::= {
+ PARAMETER
+ SS-SubscriptionViolationParam
+ -- optional
+ -- SS-SubscriptionViolationParam must not be used in version <3
+ CODE local:19 }
+
+ss-Incompatibility ERROR ::= {
+ PARAMETER
+ SS-IncompatibilityCause
+ -- optional
+ CODE local:20 }
+
+unknownAlphabet ERROR ::= {
+ CODE local:71 }
+
+ussd-Busy ERROR ::= {
+ CODE local:72 }
+
+pw-RegistrationFailure ERROR ::= {
+ PARAMETER
+ PW-RegistrationFailureCause
+ CODE local:37 }
+
+negativePW-Check ERROR ::= {
+ CODE local:38 }
+
+numberOfPW-AttemptsViolation ERROR ::= {
+ CODE local:43 }
+
+shortTermDenial ERROR ::= {
+ PARAMETER
+ ShortTermDenialParam
+ -- optional
+ CODE local:29 }
+
+longTermDenial ERROR ::= {
+ PARAMETER
+ LongTermDenialParam
+ -- optional
+ CODE local:30 }
+
+-- short message service errors
+
+subscriberBusyForMT-SMS ERROR ::= {
+ PARAMETER
+ SubBusyForMT-SMS-Param
+ -- optional
+ CODE local:31 }
+
+sm-DeliveryFailure ERROR ::= {
+ PARAMETER
+ SM-DeliveryFailureCause
+ CODE local:32 }
+
+messageWaitingListFull ERROR ::= {
+ PARAMETER
+ MessageWaitListFullParam
+ -- optional
+ CODE local:33 }
+
+absentSubscriberSM ERROR ::= {
+ PARAMETER
+ AbsentSubscriberSM-Param
+ -- optional
+ CODE local:6 }
+
+-- Group Call errors
+
+noGroupCallNumberAvailable ERROR ::= {
+ PARAMETER
+ NoGroupCallNbParam
+ -- optional
+ CODE local:50 }
+
+-- location service errors
+
+unauthorizedRequestingNetwork ERROR ::= {
+ PARAMETER
+ UnauthorizedRequestingNetwork-Param
+ -- optional
+ CODE local:52 }
+
+unauthorizedLCSClient ERROR ::= {
+ PARAMETER
+ UnauthorizedLCSClient-Param
+ -- optional
+ CODE local:53 }
+
+positionMethodFailure ERROR ::= {
+ PARAMETER
+ PositionMethodFailure-Param
+ -- optional
+ CODE local:54 }
+
+unknownOrUnreachableLCSClient ERROR ::= {
+ PARAMETER
+ UnknownOrUnreachableLCSClient-Param
+ -- optional
+ CODE local:58 }
+
+mm-EventNotSupported ERROR ::= {
+ PARAMETER
+ MM-EventNotSupported-Param
+ -- optional
+ CODE local:59 }
+
+ -- Secure transport errors
+
+secureTransportError ERROR ::= {
+ PARAMETER
+ SecureTransportErrorParam
+ CODE local:4 }
+
+
+END
diff --git a/lib/asn1/test/asn1_SUITE_data/tcapsystem/MAP-ExtensionDataTypes.asn b/lib/asn1/test/asn1_SUITE_data/tcapsystem/MAP-ExtensionDataTypes.asn
new file mode 100644
index 0000000000..ab4cb9c3b1
--- /dev/null
+++ b/lib/asn1/test/asn1_SUITE_data/tcapsystem/MAP-ExtensionDataTypes.asn
@@ -0,0 +1,65 @@
+MAP-ExtensionDataTypes {
+ itu-t identified-organization (4) etsi (0) mobileDomain (0)
+ gsm-Network (1) modules (3) map-ExtensionDataTypes (21) version9 (9)}
+
+DEFINITIONS
+
+IMPLICIT TAGS
+
+::=
+
+BEGIN
+
+EXPORTS
+
+ PrivateExtension,
+ ExtensionContainer,
+ SLR-ArgExtensionContainer;
+
+
+-- IOC for private MAP extensions
+
+
+MAP-EXTENSION ::= CLASS {
+ &ExtensionType OPTIONAL,
+ &extensionId OBJECT IDENTIFIER }
+ -- The length of the Object Identifier shall not exceed 16 octets and the
+ -- number of components of the Object Identifier shall not exceed 16
+
+-- data types
+
+ExtensionContainer ::= SEQUENCE {
+ privateExtensionList [0]PrivateExtensionList OPTIONAL,
+ pcs-Extensions [1]PCS-Extensions OPTIONAL,
+ ...}
+
+SLR-ArgExtensionContainer ::= SEQUENCE {
+ privateExtensionList [0]PrivateExtensionList OPTIONAL,
+ slr-Arg-PCS-Extensions [1]SLR-Arg-PCS-Extensions OPTIONAL,
+ ...}
+
+PrivateExtensionList ::= SEQUENCE SIZE (1..maxNumOfPrivateExtensions) OF
+ PrivateExtension
+
+PrivateExtension ::= SEQUENCE {
+ extId MAP-EXTENSION.&extensionId
+ ({ExtensionSet}),
+ extType MAP-EXTENSION.&ExtensionType
+ ({ExtensionSet}{@extId}) OPTIONAL}
+
+maxNumOfPrivateExtensions INTEGER ::= 10
+
+ExtensionSet MAP-EXTENSION ::=
+ {...
+ -- ExtensionSet is the set of all defined private extensions
+ }
+ -- Unsupported private extensions shall be discarded if received.
+
+PCS-Extensions ::= SEQUENCE {
+ ...}
+
+SLR-Arg-PCS-Extensions ::= SEQUENCE {
+ ...,
+ na-ESRK-Request [0] NULL OPTIONAL }
+
+END
diff --git a/lib/asn1/test/asn1_SUITE_data/tcapsystem/MAP-GR-DataTypes.asn b/lib/asn1/test/asn1_SUITE_data/tcapsystem/MAP-GR-DataTypes.asn
new file mode 100644
index 0000000000..8ceeea183b
--- /dev/null
+++ b/lib/asn1/test/asn1_SUITE_data/tcapsystem/MAP-GR-DataTypes.asn
@@ -0,0 +1,122 @@
+MAP-GR-DataTypes {
+ itu-t identified-organization (4) etsi (0) mobileDomain (0)
+ gsm-Network (1) modules (3) map-GR-DataTypes (23) version9 (9)}
+
+DEFINITIONS
+
+IMPLICIT TAGS
+
+::=
+
+BEGIN
+
+EXPORTS
+ PrepareGroupCallArg,
+ PrepareGroupCallRes,
+ SendGroupCallEndSignalArg,
+ SendGroupCallEndSignalRes,
+ ForwardGroupCallSignallingArg,
+ ProcessGroupCallSignallingArg
+;
+
+IMPORTS
+ ISDN-AddressString,
+ IMSI,
+ EMLPP-Priority,
+ ASCI-CallReference
+FROM MAP-CommonDataTypes {
+ itu-t identified-organization (4) etsi (0) mobileDomain (0)
+ gsm-Network (1) modules (3) map-CommonDataTypes (18) version9 (9)}
+
+ Ext-TeleserviceCode
+FROM MAP-TS-Code {
+ itu-t identified-organization (4) etsi (0) mobileDomain (0)
+ gsm-Network (1) modules (3) map-TS-Code (19) version9 (9)}
+
+ Kc
+FROM MAP-MS-DataTypes {
+ itu-t identified-organization (4) etsi (0) mobileDomain (0)
+ gsm-Network (1) modules (3) map-MS-DataTypes (11) version9 (9)}
+
+ ExtensionContainer
+FROM MAP-ExtensionDataTypes {
+ itu-t identified-organization (4) etsi (0) mobileDomain (0)
+ gsm-Network (1) modules (3) map-ExtensionDataTypes (21) version9 (9)}
+;
+
+
+PrepareGroupCallArg ::= SEQUENCE {
+ teleservice Ext-TeleserviceCode,
+ asciCallReference ASCI-CallReference,
+ codec-Info CODEC-Info,
+ cipheringAlgorithm CipheringAlgorithm,
+ groupKeyNumber [0] GroupKeyNumber OPTIONAL,
+ groupKey [1] Kc OPTIONAL,
+ priority [2] EMLPP-Priority OPTIONAL,
+ uplinkFree [3] NULL OPTIONAL,
+ extensionContainer [4] ExtensionContainer OPTIONAL,
+ ...}
+
+PrepareGroupCallRes ::= SEQUENCE {
+ groupCallNumber ISDN-AddressString,
+ extensionContainer ExtensionContainer OPTIONAL,
+ ...}
+
+SendGroupCallEndSignalArg ::= SEQUENCE {
+ imsi IMSI OPTIONAL,
+ extensionContainer ExtensionContainer OPTIONAL,
+ ...}
+
+SendGroupCallEndSignalRes ::= SEQUENCE {
+ extensionContainer ExtensionContainer OPTIONAL,
+ ...}
+
+ForwardGroupCallSignallingArg ::= SEQUENCE {
+ imsi IMSI OPTIONAL,
+ uplinkRequestAck [0] NULL OPTIONAL,
+ uplinkReleaseIndication [1] NULL OPTIONAL,
+ uplinkRejectCommand [2] NULL OPTIONAL,
+ uplinkSeizedCommand [3] NULL OPTIONAL,
+ uplinkReleaseCommand [4] NULL OPTIONAL,
+ extensionContainer ExtensionContainer OPTIONAL,
+ ...,
+ stateAttributes [5] StateAttributes OPTIONAL }
+
+ProcessGroupCallSignallingArg ::= SEQUENCE {
+ uplinkRequest [0] NULL OPTIONAL,
+ uplinkReleaseIndication [1] NULL OPTIONAL,
+ releaseGroupCall [2] NULL OPTIONAL,
+ extensionContainer ExtensionContainer OPTIONAL,
+ ...}
+
+GroupKeyNumber ::= INTEGER (0..15)
+
+CODEC-Info ::= OCTET STRING (SIZE (5..10))
+ -- Refers to channel type
+ -- coded according to 3GPP TS 48.008 [49] and including Element identifier and Length
+
+CipheringAlgorithm ::= OCTET STRING (SIZE (1))
+ -- Refers to 'permitted algorithms' in 'encryption information'
+ -- coded according to 3GPP TS 48.008 [49]:
+
+ -- Bits 8-1
+ -- 8765 4321
+ -- 0000 0001 No encryption
+ -- 0000 0010 GSM A5/1
+ -- 0000 0100 GSM A5/2
+ -- 0000 1000 GSM A5/3
+ -- 0001 0000 GSM A5/4
+ -- 0010 0000 GSM A5/5
+ -- 0100 0000 GSM A5/6
+ -- 1000 0000 GSM A5/7
+
+StateAttributes ::= SEQUENCE {
+ downlinkAttached [5] NULL OPTIONAL,
+ uplinkAttached [6] NULL OPTIONAL,
+ dualCommunication [7] NULL OPTIONAL,
+ callOriginator [8] NULL OPTIONAL }
+
+ -- Refers to 3GPP TS 44.068 for definitions of StateAttributes fields.
+
+
+END
diff --git a/lib/asn1/test/asn1_SUITE_data/tcapsystem/MAP-Group-Call-Operations.asn b/lib/asn1/test/asn1_SUITE_data/tcapsystem/MAP-Group-Call-Operations.asn
new file mode 100644
index 0000000000..55777fec68
--- /dev/null
+++ b/lib/asn1/test/asn1_SUITE_data/tcapsystem/MAP-Group-Call-Operations.asn
@@ -0,0 +1,72 @@
+MAP-Group-Call-Operations {
+ itu-t identified-organization (4) etsi (0) mobileDomain (0)
+ gsm-Network (1) modules (3) map-Group-Call-Operations (22)
+ version9 (9)}
+
+DEFINITIONS
+
+::=
+
+BEGIN
+
+EXPORTS
+ prepareGroupCall,
+ sendGroupCallEndSignal,
+ forwardGroupCallSignalling,
+ processGroupCallSignalling
+;
+
+IMPORTS
+ OPERATION
+FROM Remote-Operations-Information-Objects {
+joint-iso-itu-t remote-operations(4)
+ informationObjects(5) version1(0)}
+
+ systemFailure,
+ unexpectedDataValue,
+ noGroupCallNumberAvailable
+FROM MAP-Errors {
+ itu-t identified-organization (4) etsi (0) mobileDomain (0)
+ gsm-Network (1) modules (3) map-Errors (10) version9 (9)}
+
+ PrepareGroupCallArg,
+ PrepareGroupCallRes,
+ SendGroupCallEndSignalArg,
+ SendGroupCallEndSignalRes,
+ ForwardGroupCallSignallingArg,
+ ProcessGroupCallSignallingArg
+FROM MAP-GR-DataTypes {
+ itu-t identified-organization (4) etsi (0) mobileDomain (0)
+ gsm-Network (1) modules (3) map-GR-DataTypes (23) version9 (9)}
+
+;
+
+prepareGroupCall OPERATION ::= { --Timer m
+ ARGUMENT
+ PrepareGroupCallArg
+ RESULT
+ PrepareGroupCallRes
+ ERRORS {
+ systemFailure |
+ noGroupCallNumberAvailable |
+ unexpectedDataValue}
+ CODE local:39 }
+
+sendGroupCallEndSignal OPERATION ::= { --Timer l
+ ARGUMENT
+ SendGroupCallEndSignalArg
+ RESULT
+ SendGroupCallEndSignalRes
+ CODE local:40 }
+
+processGroupCallSignalling OPERATION ::= { --Timer s
+ ARGUMENT
+ ProcessGroupCallSignallingArg
+ CODE local:41 }
+
+forwardGroupCallSignalling OPERATION ::= { --Timer s
+ ARGUMENT
+ ForwardGroupCallSignallingArg
+ CODE local:42 }
+
+END
diff --git a/lib/asn1/test/asn1_SUITE_data/tcapsystem/MAP-LCS-DataTypes.asn b/lib/asn1/test/asn1_SUITE_data/tcapsystem/MAP-LCS-DataTypes.asn
new file mode 100644
index 0000000000..08962d6874
--- /dev/null
+++ b/lib/asn1/test/asn1_SUITE_data/tcapsystem/MAP-LCS-DataTypes.asn
@@ -0,0 +1,533 @@
+MAP-LCS-DataTypes {
+ itu-t identified-organization (4) etsi (0) mobileDomain (0)
+ gsm-Network (1) modules (3) map-LCS-DataTypes (25) version9 (9)}
+
+DEFINITIONS
+IMPLICIT TAGS
+::=
+BEGIN
+
+EXPORTS
+ RoutingInfoForLCS-Arg,
+ RoutingInfoForLCS-Res,
+ ProvideSubscriberLocation-Arg,
+ ProvideSubscriberLocation-Res,
+ SubscriberLocationReport-Arg,
+ SubscriberLocationReport-Res,
+ LocationType,
+ DeferredLocationEventType,
+ LCSClientName,
+ LCS-QoS,
+ Horizontal-Accuracy,
+ ResponseTime,
+ Ext-GeographicalInformation,
+ SupportedGADShapes,
+ Add-GeographicalInformation,
+ LCSRequestorID,
+ LCS-ReferenceNumber,
+ LCSCodeword,
+ AreaEventInfo
+;
+
+IMPORTS
+ AddressString,
+ ISDN-AddressString,
+ IMEI,
+ IMSI,
+ LMSI,
+ SubscriberIdentity,
+ AgeOfLocationInformation,
+ LCSClientExternalID,
+ LCSClientInternalID,
+ LCSServiceTypeID,
+ CellGlobalIdOrServiceAreaIdOrLAI
+FROM MAP-CommonDataTypes {
+ itu-t identified-organization (4) etsi (0) mobileDomain (0)
+ gsm-Network (1) modules (3) map-CommonDataTypes (18) version9 (9)}
+
+ ExtensionContainer
+FROM MAP-ExtensionDataTypes {
+ itu-t identified-organization (4) etsi (0) mobileDomain (0)
+ gsm-Network (1) modules (3) map-ExtensionDataTypes (21) version9 (9)}
+
+ USSD-DataCodingScheme,
+ USSD-String
+FROM MAP-SS-DataTypes {
+ itu-t identified-organization (4) etsi (0) mobileDomain (0) gsm-Network (1) modules (3)
+ map-SS-DataTypes (14) version9 (9)}
+
+ APN,
+ GSN-Address,
+ SupportedLCS-CapabilitySets
+FROM MAP-MS-DataTypes {
+ itu-t identified-organization (4) etsi (0) mobileDomain (0)
+ gsm-Network (1) modules (3) map-MS-DataTypes (11) version9 (9)}
+
+ Additional-Number
+FROM MAP-SM-DataTypes {
+ itu-t identified-organization (4) etsi (0) mobileDomain (0)
+ gsm-Network (1) modules (3) map-SM-DataTypes (16) version9 (9)}
+;
+
+
+RoutingInfoForLCS-Arg ::= SEQUENCE {
+ mlcNumber [0] ISDN-AddressString,
+ targetMS [1] SubscriberIdentity,
+ extensionContainer [2] ExtensionContainer OPTIONAL,
+ ...}
+
+RoutingInfoForLCS-Res ::= SEQUENCE {
+ targetMS [0] SubscriberIdentity,
+ lcsLocationInfo [1] LCSLocationInfo,
+ extensionContainer [2] ExtensionContainer OPTIONAL,
+ ...,
+ v-gmlc-Address [3] GSN-Address OPTIONAL,
+ h-gmlc-Address [4] GSN-Address OPTIONAL,
+ ppr-Address [5] GSN-Address OPTIONAL,
+ additional-v-gmlc-Address [6] GSN-Address OPTIONAL }
+
+LCSLocationInfo ::= SEQUENCE {
+ networkNode-Number ISDN-AddressString,
+ -- NetworkNode-number can be either msc-number or sgsn-number
+ lmsi [0] LMSI OPTIONAL,
+ extensionContainer [1] ExtensionContainer OPTIONAL,
+ ... ,
+ gprsNodeIndicator [2] NULL OPTIONAL,
+ -- gprsNodeIndicator is set only if the SGSN number is sent as the Network Node Number
+ additional-Number [3] Additional-Number OPTIONAL,
+ supportedLCS-CapabilitySets [4] SupportedLCS-CapabilitySets OPTIONAL,
+ additional-LCS-CapabilitySets [5] SupportedLCS-CapabilitySets OPTIONAL
+ }
+
+ProvideSubscriberLocation-Arg ::= SEQUENCE {
+ locationType LocationType,
+ mlc-Number ISDN-AddressString,
+ lcs-ClientID [0] LCS-ClientID OPTIONAL,
+ privacyOverride [1] NULL OPTIONAL,
+ imsi [2] IMSI OPTIONAL,
+ msisdn [3] ISDN-AddressString OPTIONAL,
+ lmsi [4] LMSI OPTIONAL,
+ imei [5] IMEI OPTIONAL,
+ lcs-Priority [6] LCS-Priority OPTIONAL,
+ lcs-QoS [7] LCS-QoS OPTIONAL,
+ extensionContainer [8] ExtensionContainer OPTIONAL,
+ ... ,
+ supportedGADShapes [9] SupportedGADShapes OPTIONAL,
+ lcs-ReferenceNumber [10] LCS-ReferenceNumber OPTIONAL,
+ lcsServiceTypeID [11] LCSServiceTypeID OPTIONAL,
+ lcsCodeword [12] LCSCodeword OPTIONAL,
+ lcs-PrivacyCheck [13] LCS-PrivacyCheck OPTIONAL,
+ areaEventInfo [14] AreaEventInfo OPTIONAL,
+ h-gmlc-Address [15] GSN-Address OPTIONAL }
+
+ -- one of imsi or msisdn is mandatory
+ -- If a location estimate type indicates activate deferred location or cancel deferred
+ -- location, a lcs-Reference number shall be included.
+
+LocationType ::= SEQUENCE {
+ locationEstimateType [0] LocationEstimateType,
+ ...,
+ deferredLocationEventType [1] DeferredLocationEventType OPTIONAL }
+
+LocationEstimateType ::= ENUMERATED {
+ currentLocation (0),
+ currentOrLastKnownLocation (1),
+ initialLocation (2),
+ ...,
+ activateDeferredLocation (3),
+ cancelDeferredLocation (4) }
+-- exception handling:
+-- a ProvideSubscriberLocation-Arg containing an unrecognized LocationEstimateType
+-- shall be rejected by the receiver with a return error cause of unexpected data value
+
+DeferredLocationEventType ::= BIT STRING {
+ msAvailable (0) ,
+ enteringIntoArea (1),
+ leavingFromArea (2),
+ beingInsideArea (3) } (SIZE (1..16))
+-- beingInsideArea is always treated as oneTimeEvent regardless of the possible value
+-- of occurrenceInfo inside areaEventInfo.
+-- exception handling:
+-- a ProvideSubscriberLocation-Arg containing other values than listed above in
+-- DeferredLocationEventType shall be rejected by the receiver with a return error cause of
+-- unexpected data value.
+
+LCS-ClientID ::= SEQUENCE {
+ lcsClientType [0] LCSClientType,
+ lcsClientExternalID [1] LCSClientExternalID OPTIONAL,
+ lcsClientDialedByMS [2] AddressString OPTIONAL,
+ lcsClientInternalID [3] LCSClientInternalID OPTIONAL,
+ lcsClientName [4] LCSClientName OPTIONAL,
+ ...,
+ lcsAPN [5] APN OPTIONAL,
+ lcsRequestorID [6] LCSRequestorID OPTIONAL }
+
+LCSClientType ::= ENUMERATED {
+ emergencyServices (0),
+ valueAddedServices (1),
+ plmnOperatorServices (2),
+ lawfulInterceptServices (3),
+ ... }
+ -- exception handling:
+ -- unrecognized values may be ignored if the LCS client uses the privacy override
+ -- otherwise, an unrecognized value shall be treated as unexpected data by a receiver
+ -- a return error shall then be returned if received in a MAP invoke
+
+LCSClientName ::= SEQUENCE {
+ dataCodingScheme [0] USSD-DataCodingScheme,
+ nameString [2] NameString,
+ ...,
+ lcs-FormatIndicator [3] LCS-FormatIndicator OPTIONAL }
+
+-- The USSD-DataCodingScheme shall indicate use of the default alphabet through the
+-- following encoding
+-- bit 7 6 5 4 3 2 1 0
+-- 0 0 0 0 1 1 1 1
+
+NameString ::= USSD-String (SIZE (1..maxNameStringLength))
+
+maxNameStringLength INTEGER ::= 63
+
+LCSRequestorID ::= SEQUENCE {
+ dataCodingScheme [0] USSD-DataCodingScheme,
+ requestorIDString [1] RequestorIDString,
+ ...,
+ lcs-FormatIndicator [2] LCS-FormatIndicator OPTIONAL }
+
+RequestorIDString ::= USSD-String (SIZE (1..maxRequestorIDStringLength))
+
+maxRequestorIDStringLength INTEGER ::= 63
+
+LCS-FormatIndicator ::= ENUMERATED {
+ logicalName (0),
+ e-mailAddress (1),
+ msisdn (2),
+ url (3),
+ sipUrl (4),
+ ... }
+
+LCS-Priority ::= OCTET STRING (SIZE (1))
+ -- 0 = highest priority
+ -- 1 = normal priority
+ -- all other values treated as 1
+
+LCS-QoS ::= SEQUENCE {
+ horizontal-accuracy [0] Horizontal-Accuracy OPTIONAL,
+ verticalCoordinateRequest [1] NULL OPTIONAL,
+ vertical-accuracy [2] Vertical-Accuracy OPTIONAL, responseTime [3] ResponseTime OPTIONAL,
+ extensionContainer [4] ExtensionContainer OPTIONAL,
+ ...}
+
+Horizontal-Accuracy ::= OCTET STRING (SIZE (1))
+ -- bit 8 = 0
+ -- bits 7-1 = 7 bit Uncertainty Code defined in 3GPP TS 23.032. The horizontal location
+ -- error should be less than the error indicated by the uncertainty code with 67%
+ -- confidence.
+
+Vertical-Accuracy ::= OCTET STRING (SIZE (1))
+ -- bit 8 = 0
+ -- bits 7-1 = 7 bit Vertical Uncertainty Code defined in 3GPP TS 23.032.
+ -- The vertical location error should be less than the error indicated
+ -- by the uncertainty code with 67% confidence.
+
+ResponseTime ::= SEQUENCE {
+ responseTimeCategory ResponseTimeCategory,
+ ...}
+-- note: an expandable SEQUENCE simplifies later addition of a numeric response time.
+
+ResponseTimeCategory ::= ENUMERATED {
+ lowdelay (0),
+ delaytolerant (1),
+ ... }
+-- exception handling:
+-- an unrecognized value shall be treated the same as value 1 (delaytolerant)
+
+SupportedGADShapes ::= BIT STRING {
+ ellipsoidPoint (0),
+ ellipsoidPointWithUncertaintyCircle (1),
+ ellipsoidPointWithUncertaintyEllipse (2),
+ polygon (3),
+ ellipsoidPointWithAltitude (4),
+ ellipsoidPointWithAltitudeAndUncertaintyElipsoid (5),
+ ellipsoidArc (6) } (SIZE (7..16))
+-- A node shall mark in the BIT STRING all Shapes defined in 3GPP TS 23.032 it supports.
+-- exception handling: bits 7 to 15 shall be ignored if received.
+
+LCS-ReferenceNumber::= OCTET STRING (SIZE(1))
+
+LCSCodeword ::= SEQUENCE {
+ dataCodingScheme [0] USSD-DataCodingScheme,
+ lcsCodewordString [1] LCSCodewordString,
+ ...}
+
+LCSCodewordString ::= USSD-String (SIZE (1..maxLCSCodewordStringLength))
+
+maxLCSCodewordStringLength INTEGER ::= 20
+
+LCS-PrivacyCheck ::= SEQUENCE {
+ callSessionUnrelated [0] PrivacyCheckRelatedAction,
+ callSessionRelated [1] PrivacyCheckRelatedAction OPTIONAL,
+ ...}
+
+PrivacyCheckRelatedAction ::= ENUMERATED {
+ allowedWithoutNotification (0),
+ allowedWithNotification (1),
+ allowedIfNoResponse (2),
+ restrictedIfNoResponse (3),
+ notAllowed (4),
+ ...}
+-- exception handling:
+-- a ProvideSubscriberLocation-Arg containing an unrecognized PrivacyCheckRelatedAction
+-- shall be rejected by the receiver with a return error cause of unexpected data value
+
+AreaEventInfo ::= SEQUENCE {
+ areaDefinition [0] AreaDefinition,
+ occurrenceInfo [1] OccurrenceInfo OPTIONAL,
+ intervalTime [2] IntervalTime OPTIONAL,
+ ...}
+
+AreaDefinition ::= SEQUENCE {
+ areaList [0] AreaList,
+ ...}
+
+AreaList ::= SEQUENCE SIZE (1..maxNumOfAreas) OF Area
+
+maxNumOfAreas INTEGER ::= 10
+
+Area ::= SEQUENCE {
+ areaType [0] AreaType,
+ areaIdentification [1] AreaIdentification,
+ ...}
+
+AreaType ::= ENUMERATED {
+ countryCode (0),
+ plmnId (1),
+ locationAreaId (2),
+ routingAreaId (3),
+ cellGlobalId (4),
+ ...}
+
+AreaIdentification ::= OCTET STRING (SIZE (2..7))
+ -- The internal structure is defined as follows:
+ -- octet 1 bits 4321 Mobile Country Code 1st digit
+ -- bits 8765 Mobile Country Code 2nd digit
+ -- octet 2 bits 4321 Mobile Country Code 3rd digit
+ -- bits 8765 Mobile Network Code 3rd digit if 3 digit MNC included
+ -- or filler (1111)
+ -- octet 3 bits 4321 Mobile Network Code 1st digit
+ -- bits 8765 Mobile Network Code 2nd digit
+ -- octets 4 and 5 Location Area Code (LAC)
+ -- octet 6 Routing Area Code (RAC) for Routing Area Id
+ -- octets 6 and 7 Cell Identity (CI) for Cell Global Id
+
+OccurrenceInfo ::= ENUMERATED {
+ oneTimeEvent (0),
+ multipleTimeEvent (1),
+ ...}
+
+IntervalTime ::= INTEGER (1..32767)
+ -- minimum interval time between area reports in seconds
+
+ProvideSubscriberLocation-Res ::= SEQUENCE {
+ locationEstimate Ext-GeographicalInformation,
+ ageOfLocationEstimate [0] AgeOfLocationInformation OPTIONAL,
+ extensionContainer [1] ExtensionContainer OPTIONAL,
+ ... ,
+ add-LocationEstimate [2] Add-GeographicalInformation OPTIONAL,
+ deferredmt-lrResponseIndicator [3] NULL OPTIONAL,
+ geranPositioningData [4] PositioningDataInformation OPTIONAL,
+ utranPositioningData [5] UtranPositioningDataInfo OPTIONAL,
+ cellIdOrSai [6] CellGlobalIdOrServiceAreaIdOrLAI OPTIONAL,
+ sai-Present [7] NULL OPTIONAL }
+
+-- if deferredmt-lrResponseIndicator is set, locationEstimate is ignored.
+
+-- the add-LocationEstimate parameter shall not be sent to a node that did not indicate the
+-- geographic shapes supported in the ProvideSubscriberLocation-Arg
+-- The locationEstimate and the add-locationEstimate parameters shall not be sent if
+-- the supportedGADShapes parameter has been received in ProvideSubscriberLocation-Arg
+-- and the shape encoded in locationEstimate or add-LocationEstimate is not marked
+-- as supported in supportedGADShapes. In such a case ProvideSubscriberLocation
+-- shall be rejected with error FacilityNotSupported with additional indication
+-- shapeOfLocationEstimateNotSupported.
+-- sai-Present indicates that the cellIdOrSai parameter contains a Service Area Identity.
+
+Ext-GeographicalInformation ::= OCTET STRING (SIZE (1..maxExt-GeographicalInformation))
+ -- Refers to geographical Information defined in 3GPP TS 23.032.
+ -- This is composed of 1 or more octets with an internal structure according to
+ -- 3GPP TS 23.032
+ -- Octet 1: Type of shape, only the following shapes in 3GPP TS 23.032 are allowed:
+ -- (a) Ellipsoid point with uncertainty circle
+ -- (b) Ellipsoid point with uncertainty ellipse
+ -- (c) Ellipsoid point with altitude and uncertainty ellipsoid
+ -- (d) Ellipsoid Arc
+ -- (e) Ellipsoid Point
+ -- Any other value in octet 1 shall be treated as invalid
+ -- Octets 2 to 8 for case (a) - Ellipsoid point with uncertainty circle
+ -- Degrees of Latitude 3 octets
+ -- Degrees of Longitude 3 octets
+ -- Uncertainty code 1 octet
+ -- Octets 2 to 11 for case (b) - Ellipsoid point with uncertainty ellipse:
+ -- Degrees of Latitude 3 octets
+ -- Degrees of Longitude 3 octets
+ -- Uncertainty semi-major axis 1 octet
+ -- Uncertainty semi-minor axis 1 octet
+ -- Angle of major axis 1 octet
+ -- Confidence 1 octet
+ -- Octets 2 to 14 for case (c) - Ellipsoid point with altitude and uncertainty ellipsoid
+ -- Degrees of Latitude 3 octets
+ -- Degrees of Longitude 3 octets
+ -- Altitude 2 octets
+ -- Uncertainty semi-major axis 1 octet
+ -- Uncertainty semi-minor axis 1 octet
+ -- Angle of major axis 1 octet
+ -- Uncertainty altitude 1 octet
+ -- Confidence 1 octet
+ -- Octets 2 to 13 for case (d) - Ellipsoid Arc
+ -- Degrees of Latitude 3 octets
+ -- Degrees of Longitude 3 octets
+ -- Inner radius 2 octets
+ -- Uncertainty radius 1 octet
+ -- Offset angle 1 octet
+ -- Included angle 1 octet
+ -- Confidence 1 octet
+ -- Octets 2 to 7 for case (e) - Ellipsoid Point
+ -- Degrees of Latitude 3 octets
+ -- Degrees of Longitude 3 octets
+
+ --
+ -- An Ext-GeographicalInformation parameter comprising more than one octet and
+ -- containing any other shape or an incorrect number of octets or coding according
+ -- to 3GPP TS 23.032 shall be treated as invalid data by a receiver.
+ --
+ -- An Ext-GeographicalInformation parameter comprising one octet shall be discarded
+ -- by the receiver if an Add-GeographicalInformation parameter is received
+ -- in the same message.
+ --
+ -- An Ext-GeographicalInformation parameter comprising one octet shall be treated as
+ -- invalid data by the receiver if an Add-GeographicalInformation parameter is not
+ -- received in the same message.
+
+maxExt-GeographicalInformation INTEGER ::= 20
+ -- the maximum length allows for further shapes in 3GPP TS 23.032 to be included in later
+ -- versions of 3GPP TS 29.002
+
+PositioningDataInformation ::= OCTET STRING (SIZE (2..maxPositioningDataInformation))
+ -- Refers to the Positioning Data defined in 3GPP TS 49.031.
+ -- This is composed of 2 or more octets with an internal structure according to
+ -- 3GPP TS 49.031.
+
+maxPositioningDataInformation INTEGER ::= 10
+ --
+
+UtranPositioningDataInfo ::= OCTET STRING (SIZE (3..maxUtranPositioningDataInfo))
+ -- Refers to the Position Data defined in 3GPP TS 25.413.
+ -- This is composed of the positioningDataDiscriminator and the positioningDataSet
+ -- included in positionData as defined in 3GPP TS 25.413.
+
+maxUtranPositioningDataInfo INTEGER ::= 11
+ --
+
+Add-GeographicalInformation ::= OCTET STRING (SIZE (1..maxAdd-GeographicalInformation))
+ -- Refers to geographical Information defined in 3GPP TS 23.032.
+ -- This is composed of 1 or more octets with an internal structure according to
+ -- 3GPP TS 23.032
+ -- Octet 1: Type of shape, all the shapes defined in 3GPP TS 23.032 are allowed:
+ -- Octets 2 to n (where n is the total number of octets necessary to encode the shape
+ -- according to 3GPP TS 23.032) are used to encode the shape itself in accordance with the
+ -- encoding defined in 3GPP TS 23.032
+ --
+ -- An Add-GeographicalInformation parameter, whether valid or invalid, received
+ -- together with a valid Ext-GeographicalInformation parameter in the same message
+ -- shall be discarded.
+ --
+ -- An Add-GeographicalInformation parameter containing any shape not defined in
+ -- 3GPP TS 23.032 or an incorrect number of octets or coding according to
+ -- 3GPP TS 23.032 shall be treated as invalid data by a receiver if not received
+ -- together with a valid Ext-GeographicalInformation parameter in the same message.
+
+maxAdd-GeographicalInformation INTEGER ::= 91
+ -- the maximum length allows support for all the shapes currently defined in 3GPP TS 23.032
+
+SubscriberLocationReport-Arg ::= SEQUENCE {
+ lcs-Event LCS-Event,
+ lcs-ClientID LCS-ClientID,
+ lcsLocationInfo LCSLocationInfo,
+ msisdn [0] ISDN-AddressString OPTIONAL,
+ imsi [1] IMSI OPTIONAL,
+ imei [2] IMEI OPTIONAL,
+ na-ESRD [3] ISDN-AddressString OPTIONAL,
+ na-ESRK [4] ISDN-AddressString OPTIONAL,
+ locationEstimate [5] Ext-GeographicalInformation OPTIONAL,
+ ageOfLocationEstimate [6] AgeOfLocationInformation OPTIONAL,
+ extensionContainer [7] ExtensionContainer OPTIONAL,
+ ... ,
+ add-LocationEstimate [8] Add-GeographicalInformation OPTIONAL,
+ deferredmt-lrData [9] Deferredmt-lrData OPTIONAL,
+ lcs-ReferenceNumber [10] LCS-ReferenceNumber OPTIONAL,
+ geranPositioningData [11] PositioningDataInformation OPTIONAL,
+ utranPositioningData [12] UtranPositioningDataInfo OPTIONAL,
+ na-ESRK-Request [16] NULL OPTIONAL,
+ cellIdOrSai [13] CellGlobalIdOrServiceAreaIdOrLAI OPTIONAL,
+ h-gmlc-Address [14] GSN-Address OPTIONAL,
+ lcsServiceTypeID [15] LCSServiceTypeID OPTIONAL,
+ sai-Present [17] NULL OPTIONAL }
+
+ -- one of msisdn or imsi is mandatory
+ -- a location estimate that is valid for the locationEstimate parameter should
+ -- be transferred in this parameter in preference to the add-LocationEstimate.
+ -- the deferredmt-lrData parameter shall be included if and only if the lcs-Event
+ -- indicates a deferredmt-lrResponse.
+ -- if the lcs-Event indicates a deferredmt-lrResponse then the locationEstimate
+ -- and the add-locationEstimate parameters shall not be sent if the
+ -- supportedGADShapes parameter had been received in ProvideSubscriberLocation-Arg
+ -- and the shape encoded in locationEstimate or add-LocationEstimate was not marked
+ -- as supported in supportedGADShapes. In such a case terminationCause
+ -- in deferredmt-lrData shall be present with value
+ -- shapeOfLocationEstimateNotSupported.
+ -- If a lcs event indicates deferred mt-lr response, the lcs-Reference number shall be
+ -- included.
+ -- sai-Present indicates that the cellIdOrSai parameter contains a Service Area Identity.
+
+Deferredmt-lrData ::= SEQUENCE {
+ deferredLocationEventType DeferredLocationEventType,
+ terminationCause [0] TerminationCause OPTIONAL,
+ lcsLocationInfo [1] LCSLocationInfo OPTIONAL,
+ ...}
+ -- lcsLocationInfo may be included only if a terminationCause is present
+ -- indicating mt-lrRestart.
+
+LCS-Event ::= ENUMERATED {
+ emergencyCallOrigination (0),
+ emergencyCallRelease (1),
+ mo-lr (2),
+ ...,
+ deferredmt-lrResponse (3) }
+ -- exception handling:
+ -- a SubscriberLocationReport-Arg containing an unrecognized LCS-Event
+ -- shall be rejected by a receiver with a return error cause of unexpected data value
+
+TerminationCause ::= ENUMERATED {
+ normal (0),
+ errorundefined (1),
+ internalTimeout (2),
+ congestion (3),
+ mt-lrRestart (4),
+ privacyViolation (5),
+ ...,
+ shapeOfLocationEstimateNotSupported (6) }
+-- mt-lrRestart shall be used to trigger the GMLC to restart the location procedure,
+-- either because the sending node knows that the terminal has moved under coverage
+-- of another MSC or SGSN (e.g. Send Identification received), or because the subscriber
+-- has been deregistered due to a Cancel Location received from HLR.
+--
+-- exception handling
+-- an unrecognized value shall be treated the same as value 1 (errorundefined)
+
+SubscriberLocationReport-Res ::= SEQUENCE {
+ extensionContainer ExtensionContainer OPTIONAL,
+ ...,
+ na-ESRK [0] ISDN-AddressString OPTIONAL }
+
+
+END
diff --git a/lib/asn1/test/asn1_SUITE_data/tcapsystem/MAP-LocationServiceOperations.asn b/lib/asn1/test/asn1_SUITE_data/tcapsystem/MAP-LocationServiceOperations.asn
new file mode 100644
index 0000000000..c28ac884ce
--- /dev/null
+++ b/lib/asn1/test/asn1_SUITE_data/tcapsystem/MAP-LocationServiceOperations.asn
@@ -0,0 +1,103 @@
+MAP-LocationServiceOperations {
+ itu-t identified-organization (4) etsi (0) mobileDomain (0)
+ gsm-Network (1) modules (3) map-LocationServiceOperations (24)
+ version9 (9)}
+
+DEFINITIONS
+
+::=
+
+BEGIN
+
+EXPORTS
+ provideSubscriberLocation,
+sendRoutingInfoForLCS,
+subscriberLocationReport
+;
+
+IMPORTS
+ OPERATION
+FROM Remote-Operations-Information-Objects {
+joint-iso-itu-t remote-operations(4)
+ informationObjects(5) version1(0)}
+
+systemFailure,
+ dataMissing,
+ unexpectedDataValue,
+ facilityNotSupported,
+ unknownSubscriber,
+ absentSubscriber,
+ unauthorizedRequestingNetwork,
+ unauthorizedLCSClient,
+ positionMethodFailure,
+ resourceLimitation,
+ unknownOrUnreachableLCSClient,
+ unidentifiedSubscriber,
+ illegalEquipment,
+ illegalSubscriber
+FROM MAP-Errors {
+ itu-t identified-organization (4) etsi (0) mobileDomain (0)
+ gsm-Network (1) modules (3) map-Errors (10) version9 (9)}
+
+ RoutingInfoForLCS-Arg,
+ RoutingInfoForLCS-Res,
+ ProvideSubscriberLocation-Arg,
+ ProvideSubscriberLocation-Res,
+ SubscriberLocationReport-Arg,
+ SubscriberLocationReport-Res
+FROM MAP-LCS-DataTypes {
+ itu-t identified-organization (4) etsi (0) mobileDomain (0)
+ gsm-Network (1) modules (3) map-LCS-DataTypes (25) version9 (9)}
+;
+
+sendRoutingInfoForLCS OPERATION ::= { --Timer m
+ ARGUMENT
+ RoutingInfoForLCS-Arg
+ RESULT
+ RoutingInfoForLCS-Res
+ ERRORS {
+ systemFailure |
+ dataMissing |
+ unexpectedDataValue |
+ facilityNotSupported |
+ unknownSubscriber |
+ absentSubscriber |
+ unauthorizedRequestingNetwork }
+ CODE local:85 }
+
+provideSubscriberLocation OPERATION ::= { --Timer ml
+ ARGUMENT
+ ProvideSubscriberLocation-Arg
+ RESULT
+ ProvideSubscriberLocation-Res
+ ERRORS {
+ systemFailure |
+ dataMissing |
+ unexpectedDataValue |
+ facilityNotSupported |
+ unidentifiedSubscriber |
+ illegalSubscriber |
+ illegalEquipment |
+ absentSubscriber |
+ unauthorizedRequestingNetwork |
+ unauthorizedLCSClient |
+ positionMethodFailure }
+ CODE local:83 }
+
+subscriberLocationReport OPERATION ::= { --Timer m
+ ARGUMENT
+ SubscriberLocationReport-Arg
+ RESULT
+ SubscriberLocationReport-Res
+ ERRORS {
+ systemFailure |
+ dataMissing |
+ resourceLimitation |
+ unexpectedDataValue |
+ unknownSubscriber |
+ unauthorizedRequestingNetwork |
+ unknownOrUnreachableLCSClient}
+ CODE local:86 }
+
+
+END
diff --git a/lib/asn1/test/asn1_SUITE_data/tcapsystem/MAP-MS-DataTypes.asn b/lib/asn1/test/asn1_SUITE_data/tcapsystem/MAP-MS-DataTypes.asn
new file mode 100644
index 0000000000..e905c44077
--- /dev/null
+++ b/lib/asn1/test/asn1_SUITE_data/tcapsystem/MAP-MS-DataTypes.asn
@@ -0,0 +1,2458 @@
+MAP-MS-DataTypes {
+ itu-t identified-organization (4) etsi (0) mobileDomain (0)
+ gsm-Network (1) modules (3) map-MS-DataTypes (11) version9 (9)}
+
+DEFINITIONS
+
+IMPLICIT TAGS
+
+::=
+
+BEGIN
+
+EXPORTS
+
+ -- location registration types
+ UpdateLocationArg,
+ UpdateLocationRes,
+ CancelLocationArg,
+ CancelLocationRes,
+ PurgeMS-Arg,
+ PurgeMS-Res,
+ SendIdentificationArg,
+ SendIdentificationRes,
+ UpdateGprsLocationArg,
+ UpdateGprsLocationRes,
+ IST-SupportIndicator,
+ SupportedLCS-CapabilitySets,
+
+ -- gprs location registration types
+ GSN-Address,
+
+ -- handover types
+ ForwardAccessSignalling-Arg,
+ PrepareHO-Arg,
+ PrepareHO-Res,
+ PrepareSubsequentHO-Arg,
+ PrepareSubsequentHO-Res,
+ ProcessAccessSignalling-Arg,
+ SendEndSignal-Arg,
+ SendEndSignal-Res,
+
+ -- authentication management types
+ SendAuthenticationInfoArg,
+ SendAuthenticationInfoRes,
+ AuthenticationFailureReportArg,
+ AuthenticationFailureReportRes,
+
+ -- security management types
+ Kc,
+
+ -- equipment management types
+ CheckIMEI-Arg,
+ CheckIMEI-Res,
+
+ -- subscriber management types
+ InsertSubscriberDataArg,
+ InsertSubscriberDataRes,
+ LSAIdentity,
+ DeleteSubscriberDataArg,
+ DeleteSubscriberDataRes,
+ Ext-QoS-Subscribed,
+ Ext2-QoS-Subscribed,
+ SubscriberData,
+ ODB-Data,
+ SubscriberStatus,
+ ZoneCodeList,
+ maxNumOfZoneCodes,
+ O-CSI,
+ D-CSI,
+ O-BcsmCamelTDPCriteriaList,
+ T-BCSM-CAMEL-TDP-CriteriaList,
+ SS-CSI,
+ ServiceKey,
+ DefaultCallHandling,
+ CamelCapabilityHandling,
+ BasicServiceCriteria,
+ SupportedCamelPhases,
+ OfferedCamel4CSIs,
+ OfferedCamel4Functionalities,
+ maxNumOfCamelTDPData,
+ CUG-Index,
+ CUG-Info,
+ CUG-Interlock,
+ InterCUG-Restrictions,
+ IntraCUG-Options,
+ NotificationToMSUser,
+ QoS-Subscribed,
+ IST-AlertTimerValue,
+ T-CSI,
+ T-BcsmTriggerDetectionPoint,
+ APN,
+
+ -- fault recovery types
+ ResetArg,
+ RestoreDataArg,
+ RestoreDataRes,
+
+-- provide subscriber info types
+ GeographicalInformation,
+ MS-Classmark2,
+ GPRSMSClass,
+
+ -- subscriber information enquiry types
+ ProvideSubscriberInfoArg,
+ ProvideSubscriberInfoRes,
+ SubscriberInfo,
+ LocationInformation,
+ LocationInformationGPRS,
+ RAIdentity,
+ SubscriberState,
+ GPRSChargingID,
+ MNPInfoRes,
+ RouteingNumber,
+
+ -- any time information enquiry types
+ AnyTimeInterrogationArg,
+ AnyTimeInterrogationRes,
+
+ -- any time information handling types
+ AnyTimeSubscriptionInterrogationArg,
+ AnyTimeSubscriptionInterrogationRes,
+ AnyTimeModificationArg,
+ AnyTimeModificationRes,
+
+ -- subscriber data modification notification types
+ NoteSubscriberDataModifiedArg,
+ NoteSubscriberDataModifiedRes,
+
+ -- gprs location information retrieval types
+ SendRoutingInfoForGprsArg,
+ SendRoutingInfoForGprsRes,
+
+ -- failure reporting types
+ FailureReportArg,
+ FailureReportRes,
+
+ -- gprs notification types
+ NoteMsPresentForGprsArg,
+ NoteMsPresentForGprsRes,
+
+ -- Mobility Management types
+ NoteMM-EventArg,
+ NoteMM-EventRes,
+ NumberPortabilityStatus
+
+;
+
+IMPORTS
+ maxNumOfSS,
+ SS-SubscriptionOption,
+ SS-List,
+ SS-ForBS-Code,
+ Password
+FROM MAP-SS-DataTypes {
+ itu-t identified-organization (4) etsi (0) mobileDomain (0)
+ gsm-Network (1) modules (3) map-SS-DataTypes (14) version9 (9)}
+
+ SS-Code
+FROM MAP-SS-Code {
+ itu-t identified-organization (4) etsi (0) mobileDomain (0)
+ gsm-Network (1) modules (3) map-SS-Code (15) version9 (9)}
+
+ Ext-BearerServiceCode
+FROM MAP-BS-Code {
+ itu-t identified-organization (4) etsi (0) mobileDomain (0)
+ gsm-Network (1) modules (3) map-BS-Code (20) version9 (9)}
+
+ Ext-TeleserviceCode
+FROM MAP-TS-Code {
+ itu-t identified-organization (4) etsi (0) mobileDomain (0)
+ gsm-Network (1) modules (3) map-TS-Code (19) version9 (9)}
+
+ AddressString,
+ ISDN-AddressString,
+ ISDN-SubaddressString,
+ FTN-AddressString,
+ AccessNetworkSignalInfo,
+ IMSI,
+ IMEI,
+ TMSI,
+ HLR-List,
+ LMSI,
+ Identity,
+ GlobalCellId,
+ CellGlobalIdOrServiceAreaIdOrLAI,
+ Ext-BasicServiceCode,
+ NAEA-PreferredCI,
+ EMLPP-Info,
+ MC-SS-Info,
+ SubscriberIdentity,
+ AgeOfLocationInformation,
+ LCSClientExternalID,
+ LCSClientInternalID,
+ Ext-SS-Status,
+ LCSServiceTypeID,
+ ASCI-CallReference,
+ TBCD-STRING
+FROM MAP-CommonDataTypes {
+ itu-t identified-organization (4) etsi (0) mobileDomain (0)
+ gsm-Network (1) modules (3) map-CommonDataTypes (18) version9 (9)}
+
+ ExtensionContainer
+FROM MAP-ExtensionDataTypes {
+ itu-t identified-organization (4) etsi (0) mobileDomain (0)
+ gsm-Network (1) modules (3) map-ExtensionDataTypes (21) version9 (9)}
+
+ AbsentSubscriberDiagnosticSM
+FROM MAP-ER-DataTypes {
+ itu-t identified-organization (4) etsi (0) mobileDomain (0)
+ gsm-Network (1) modules (3) map-ER-DataTypes (17) version9 (9)}
+
+;
+
+-- location registration types
+
+UpdateLocationArg ::= SEQUENCE {
+ imsi IMSI,
+ msc-Number [1] ISDN-AddressString,
+ vlr-Number ISDN-AddressString,
+ lmsi [10] LMSI OPTIONAL,
+ extensionContainer ExtensionContainer OPTIONAL,
+ ... ,
+ vlr-Capability [6] VLR-Capability OPTIONAL,
+ informPreviousNetworkEntity [11] NULL OPTIONAL,
+ cs-LCS-NotSupportedByUE [12] NULL OPTIONAL,
+ v-gmlc-Address [2] GSN-Address OPTIONAL,
+ add-info [13] ADD-Info OPTIONAL }
+
+VLR-Capability ::= SEQUENCE{
+ supportedCamelPhases [0] SupportedCamelPhases OPTIONAL,
+ extensionContainer ExtensionContainer OPTIONAL,
+ ... ,
+ solsaSupportIndicator [2] NULL OPTIONAL,
+ istSupportIndicator [1] IST-SupportIndicator OPTIONAL,
+ superChargerSupportedInServingNetworkEntity [3] SuperChargerInfo OPTIONAL,
+ longFTN-Supported [4] NULL OPTIONAL,
+ supportedLCS-CapabilitySets [5] SupportedLCS-CapabilitySets OPTIONAL,
+ offeredCamel4CSIs [6] OfferedCamel4CSIs OPTIONAL }
+
+SuperChargerInfo ::= CHOICE {
+ sendSubscriberData [0] NULL,
+ subscriberDataStored [1] AgeIndicator }
+
+AgeIndicator ::= OCTET STRING (SIZE (1..6))
+ -- The internal structure of this parameter is implementation specific.
+
+IST-SupportIndicator ::= ENUMERATED {
+ basicISTSupported (0),
+ istCommandSupported (1),
+ ...}
+-- exception handling:
+-- reception of values > 1 shall be mapped to ' istCommandSupported '
+
+SupportedLCS-CapabilitySets ::= BIT STRING {
+ lcsCapabilitySet1 (0),
+ lcsCapabilitySet2 (1),
+ lcsCapabilitySet3 (2),
+ lcsCapabilitySet4 (3) } (SIZE (2..16))
+-- Core network signalling capability set1 indicates LCS Release98 or Release99 version.
+-- Core network signalling capability set2 indicates LCS Release4.
+-- Core network signalling capability set3 indicates LCS Release5.
+-- Core network signalling capability set4 indicates LCS Release6 or later version.
+-- A node shall mark in the BIT STRING all LCS capability sets it supports.
+-- If no bit is set then the sending node does not support LCS.
+-- If the parameter is not sent by an VLR then the VLR may support at most capability set1.
+-- If the parameter is not sent by an SGSN then no support for LCS is assumed.
+-- An SGSN is not allowed to indicate support of capability set1.
+-- Other bits than listed above shall be discarded.
+
+UpdateLocationRes ::= SEQUENCE {
+ hlr-Number ISDN-AddressString,
+ extensionContainer ExtensionContainer OPTIONAL,
+ ...,
+ add-Capability NULL OPTIONAL }
+
+ADD-Info ::= SEQUENCE {
+ imeisv [0] IMEI,
+ skipSubscriberDataUpdate [1] NULL OPTIONAL,
+ ...}
+
+
+CancelLocationArg ::= [3] SEQUENCE {
+ identity Identity,
+ cancellationType CancellationType OPTIONAL,
+ extensionContainer ExtensionContainer OPTIONAL,
+ ...}
+
+CancellationType ::= ENUMERATED {
+ updateProcedure (0),
+ subscriptionWithdraw (1),
+ ...}
+ -- The HLR shall not send values other than listed above
+
+CancelLocationRes ::= SEQUENCE {
+ extensionContainer ExtensionContainer OPTIONAL,
+ ...}
+
+PurgeMS-Arg ::= [3] SEQUENCE {
+ imsi IMSI,
+ vlr-Number [0] ISDN-AddressString OPTIONAL,
+ sgsn-Number [1] ISDN-AddressString OPTIONAL,
+ extensionContainer ExtensionContainer OPTIONAL,
+ ...}
+
+PurgeMS-Res ::= SEQUENCE {
+ freezeTMSI [0] NULL OPTIONAL,
+ freezeP-TMSI [1] NULL OPTIONAL,
+ extensionContainer ExtensionContainer OPTIONAL,
+ ...}
+
+SendIdentificationArg ::= SEQUENCE {
+ tmsi TMSI,
+ numberOfRequestedVectors NumberOfRequestedVectors OPTIONAL,
+ -- within a dialogue numberOfRequestedVectors shall be present in
+ -- the first service request and shall not be present in subsequent service requests.
+ -- If received in a subsequent service request it shall be discarded.
+ segmentationProhibited NULL OPTIONAL,
+ extensionContainer ExtensionContainer OPTIONAL,
+ ...,
+ msc-Number ISDN-AddressString OPTIONAL }
+
+SendIdentificationRes ::= [3] SEQUENCE {
+ imsi IMSI OPTIONAL,
+ -- IMSI shall be present in the first (or only) service response of a dialogue.
+ -- If multiple service requests are present in a dialogue then IMSI
+ -- shall not be present in any service response other than the first one.
+ authenticationSetList AuthenticationSetList OPTIONAL,
+ currentSecurityContext [2]CurrentSecurityContext OPTIONAL,
+ extensionContainer [3] ExtensionContainer OPTIONAL,
+ ...}
+
+-- authentication management types
+
+AuthenticationSetList ::= CHOICE {
+ tripletList [0] TripletList,
+ quintupletList [1] QuintupletList }
+
+TripletList ::= SEQUENCE SIZE (1..5) OF
+ AuthenticationTriplet
+
+QuintupletList ::= SEQUENCE SIZE (1..5) OF
+ AuthenticationQuintuplet
+
+AuthenticationTriplet ::= SEQUENCE {
+ rand RAND,
+ sres SRES,
+ kc Kc,
+ ...}
+
+AuthenticationQuintuplet ::= SEQUENCE {
+ rand RAND,
+ xres XRES,
+ ck CK,
+ ik IK,
+ autn AUTN,
+ ...}
+
+CurrentSecurityContext ::= CHOICE {
+ gsm-SecurityContextData [0] GSM-SecurityContextData,
+ umts-SecurityContextData [1] UMTS-SecurityContextData }
+
+GSM-SecurityContextData ::= SEQUENCE {
+ kc Kc,
+ cksn Cksn,
+ ... }
+
+UMTS-SecurityContextData ::= SEQUENCE {
+ ck CK,
+ ik IK,
+ ksi KSI,
+ ... }
+
+RAND ::= OCTET STRING (SIZE (16))
+
+SRES ::= OCTET STRING (SIZE (4))
+
+Kc ::= OCTET STRING (SIZE (8))
+
+XRES ::= OCTET STRING (SIZE (4..16))
+
+CK ::= OCTET STRING (SIZE (16))
+
+IK ::= OCTET STRING (SIZE (16))
+
+AUTN ::= OCTET STRING (SIZE (16))
+
+AUTS ::= OCTET STRING (SIZE (14))
+
+Cksn ::= OCTET STRING (SIZE (1))
+ -- The internal structure is defined in 3GPP TS 24.008
+
+KSI ::= OCTET STRING (SIZE (1))
+ -- The internal structure is defined in 3GPP TS 24.008
+
+AuthenticationFailureReportArg ::= SEQUENCE {
+ imsi IMSI,
+ failureCause FailureCause,
+ extensionContainer ExtensionContainer OPTIONAL,
+ ... ,
+ re-attempt BOOLEAN OPTIONAL,
+ accessType AccessType OPTIONAL,
+ rand RAND OPTIONAL,
+ vlr-Number [0] ISDN-AddressString OPTIONAL,
+ sgsn-Number [1] ISDN-AddressString OPTIONAL }
+
+AccessType ::= ENUMERATED {
+ call (0),
+ emergencyCall (1),
+ locationUpdating (2),
+ supplementaryService (3),
+ shortMessage (4),
+ gprsAttach (5),
+ routingAreaUpdating (6),
+ serviceRequest (7),
+ pdpContextActivation (8),
+ pdpContextDeactivation (9),
+ ...,
+ gprsDetach (10)}
+ -- exception handling:
+ -- received values greater than 10 shall be ignored.
+
+AuthenticationFailureReportRes ::= SEQUENCE {
+ extensionContainer ExtensionContainer OPTIONAL,
+ ...}
+
+FailureCause ::= ENUMERATED {
+ wrongUserResponse (0),
+ wrongNetworkSignature (1)}
+
+-- gprs location registration types
+
+UpdateGprsLocationArg ::= SEQUENCE {
+ imsi IMSI,
+ sgsn-Number ISDN-AddressString,
+ sgsn-Address GSN-Address,
+ extensionContainer ExtensionContainer OPTIONAL,
+ ... ,
+ sgsn-Capability [0] SGSN-Capability OPTIONAL,
+ informPreviousNetworkEntity [1] NULL OPTIONAL,
+ ps-LCS-NotSupportedByUE [2] NULL OPTIONAL,
+ v-gmlc-Address [3] GSN-Address OPTIONAL,
+ add-info [4] ADD-Info OPTIONAL }
+
+SGSN-Capability ::= SEQUENCE{
+ solsaSupportIndicator NULL OPTIONAL,
+ extensionContainer [1] ExtensionContainer OPTIONAL,
+ ... ,
+ superChargerSupportedInServingNetworkEntity [2] SuperChargerInfo OPTIONAL ,
+ gprsEnhancementsSupportIndicator [3] NULL OPTIONAL,
+ supportedCamelPhases [4] SupportedCamelPhases OPTIONAL,
+ supportedLCS-CapabilitySets [5] SupportedLCS-CapabilitySets OPTIONAL,
+ offeredCamel4CSIs [6] OfferedCamel4CSIs OPTIONAL,
+ smsCallBarringSupportIndicator [7] NULL OPTIONAL }
+
+GSN-Address ::= OCTET STRING (SIZE (5..17))
+ -- Octets are coded according to TS 3GPP TS 23.003 [17]
+
+UpdateGprsLocationRes ::= SEQUENCE {
+ hlr-Number ISDN-AddressString,
+ extensionContainer ExtensionContainer OPTIONAL,
+ ...,
+ add-Capability NULL OPTIONAL }
+
+-- handover types
+
+ForwardAccessSignalling-Arg ::= [3] SEQUENCE {
+ an-APDU AccessNetworkSignalInfo,
+ integrityProtectionInfo [0] IntegrityProtectionInformation OPTIONAL,
+ encryptionInfo [1] EncryptionInformation OPTIONAL,
+ keyStatus [2] KeyStatus OPTIONAL,
+ allowedGSM-Algorithms [4] AllowedGSM-Algorithms OPTIONAL,
+ allowedUMTS-Algorithms [5] AllowedUMTS-Algorithms OPTIONAL,
+ radioResourceInformation [6] RadioResourceInformation OPTIONAL,
+ extensionContainer [3] ExtensionContainer OPTIONAL,
+ ...,
+ radioResourceList [7] RadioResourceList OPTIONAL,
+ bssmap-ServiceHandover [9] BSSMAP-ServiceHandover OPTIONAL,
+ ranap-ServiceHandover [8] RANAP-ServiceHandover OPTIONAL,
+ bssmap-ServiceHandoverList [10] BSSMAP-ServiceHandoverList OPTIONAL,
+ currentlyUsedCodec [11] Codec OPTIONAL,
+ iuSupportedCodecsList [12] SupportedCodecsList OPTIONAL,
+ rab-ConfigurationIndicator [13] NULL OPTIONAL,
+ iuSelectedCodec [14] Codec OPTIONAL }
+
+AllowedGSM-Algorithms ::= OCTET STRING (SIZE (1))
+ -- internal structure is coded as Algorithm identifier octet from
+ -- Permitted Algorithms defined in 3GPP TS 48.008
+ -- A node shall mark all GSM algorithms that are allowed in MSC-B
+
+AllowedUMTS-Algorithms ::= SEQUENCE {
+ integrityProtectionAlgorithms [0] PermittedIntegrityProtectionAlgorithms OPTIONAL,
+ encryptionAlgorithms [1] PermittedEncryptionAlgorithms OPTIONAL,
+ extensionContainer [2] ExtensionContainer OPTIONAL,
+ ...}
+
+PermittedIntegrityProtectionAlgorithms ::=
+ OCTET STRING (SIZE (1..maxPermittedIntegrityProtectionAlgorithmsLength))
+ -- Octets contain a complete PermittedIntegrityProtectionAlgorithms data type
+ -- as defined in 3GPP TS 25.413, encoded according to the encoding scheme
+ -- mandated by 3GPP TS 25.413.
+ -- Padding bits are included, if needed, in the least significant bits of the
+ -- last octet of the octet string.
+
+
+maxPermittedIntegrityProtectionAlgorithmsLength INTEGER ::= 9
+
+PermittedEncryptionAlgorithms ::=
+ OCTET STRING (SIZE (1..maxPermittedEncryptionAlgorithmsLength))
+ -- Octets contain a complete PermittedEncryptionAlgorithms data type
+ -- as defined in 3GPP TS 25.413, encoded according to the encoding scheme
+ -- mandated by 3GPP TS 25.413
+ -- Padding bits are included, if needed, in the least significant bits of the
+ -- last octet of the octet string.
+
+
+maxPermittedEncryptionAlgorithmsLength INTEGER ::= 9
+
+KeyStatus ::= ENUMERATED {
+ old (0),
+ new (1),
+ ...}
+ -- exception handling:
+ -- received values in range 2-31 shall be treated as "old"
+ -- received values greater than 31 shall be treated as "new"
+
+PrepareHO-Arg ::= [3] SEQUENCE {
+ targetCellId [0] GlobalCellId OPTIONAL,
+ ho-NumberNotRequired NULL OPTIONAL,
+ targetRNCId [1] RNCId OPTIONAL,
+ an-APDU [2] AccessNetworkSignalInfo OPTIONAL,
+ multipleBearerRequested [3] NULL OPTIONAL,
+ imsi [4] IMSI OPTIONAL,
+ integrityProtectionInfo [5] IntegrityProtectionInformation OPTIONAL,
+ encryptionInfo [6] EncryptionInformation OPTIONAL,
+ radioResourceInformation [7] RadioResourceInformation OPTIONAL,
+ allowedGSM-Algorithms [9] AllowedGSM-Algorithms OPTIONAL,
+ allowedUMTS-Algorithms [10] AllowedUMTS-Algorithms OPTIONAL,
+ radioResourceList [11] RadioResourceList OPTIONAL,
+ extensionContainer [8] ExtensionContainer OPTIONAL,
+ ... ,
+ rab-Id [12] RAB-Id OPTIONAL,
+ bssmap-ServiceHandover [13] BSSMAP-ServiceHandover OPTIONAL,
+ ranap-ServiceHandover [14] RANAP-ServiceHandover OPTIONAL,
+ bssmap-ServiceHandoverList [15] BSSMAP-ServiceHandoverList OPTIONAL,
+ asciCallReference [20] ASCI-CallReference OPTIONAL,
+ geran-classmark [16] GERAN-Classmark OPTIONAL,
+ iuCurrentlyUsedCodec [17] Codec OPTIONAL,
+ iuSupportedCodecsList [18] SupportedCodecsList OPTIONAL,
+ rab-ConfigurationIndicator [19] NULL OPTIONAL,
+ uesbi-Iu [21] UESBI-Iu OPTIONAL }
+
+BSSMAP-ServiceHandoverList ::= SEQUENCE SIZE (1.. maxNumOfServiceHandovers) OF
+ BSSMAP-ServiceHandoverInfo
+
+BSSMAP-ServiceHandoverInfo ::= SEQUENCE {
+ bssmap-ServiceHandover BSSMAP-ServiceHandover,
+ rab-Id RAB-Id,
+ -- RAB Identity is needed to relate the service handovers with the radio access bearers.
+ ...}
+
+maxNumOfServiceHandovers INTEGER ::= 7
+
+BSSMAP-ServiceHandover ::= OCTET STRING (SIZE (1))
+ -- Octets are coded according the Service Handover information element in
+ -- 3GPP TS 48.008.
+
+RANAP-ServiceHandover ::= OCTET STRING (SIZE (1))
+ -- Octet contains a complete Service-Handover data type
+ -- as defined in 3GPP TS 25.413, encoded according to the encoding scheme
+ -- mandated by 3GPP TS 25.413
+ -- Padding bits are included in the least significant bits.
+
+
+RadioResourceList ::= SEQUENCE SIZE (1.. maxNumOfRadioResources) OF
+ RadioResource
+
+RadioResource ::= SEQUENCE {
+ radioResourceInformation RadioResourceInformation,
+ rab-Id RAB-Id,
+ -- RAB Identity is needed to relate the radio resources with the radio access bearers.
+ ...}
+
+maxNumOfRadioResources INTEGER ::= 7
+
+PrepareHO-Res ::= [3] SEQUENCE {
+ handoverNumber [0] ISDN-AddressString OPTIONAL,
+ relocationNumberList [1] RelocationNumberList OPTIONAL,
+ an-APDU [2] AccessNetworkSignalInfo OPTIONAL,
+ multicallBearerInfo [3] MulticallBearerInfo OPTIONAL,
+ multipleBearerNotSupported NULL OPTIONAL,
+ selectedUMTS-Algorithms [5] SelectedUMTS-Algorithms OPTIONAL,
+ chosenRadioResourceInformation [6] ChosenRadioResourceInformation OPTIONAL,
+ extensionContainer [4] ExtensionContainer OPTIONAL,
+ ...,
+ iuSelectedCodec [7] Codec OPTIONAL,
+ iuAvailableCodecsList [8] CodecList OPTIONAL }
+
+SelectedUMTS-Algorithms ::= SEQUENCE {
+ integrityProtectionAlgorithm [0] ChosenIntegrityProtectionAlgorithm OPTIONAL,
+ encryptionAlgorithm [1] ChosenEncryptionAlgorithm OPTIONAL,
+ extensionContainer [2] ExtensionContainer OPTIONAL,
+ ...}
+
+ChosenIntegrityProtectionAlgorithm ::= OCTET STRING (SIZE (1))
+ -- Octet contains a complete IntegrityProtectionAlgorithm data type
+ -- as defined in 3GPP TS 25.413, encoded according to the encoding scheme
+ -- mandated by 3GPP TS 25.413
+ -- Padding bits are included in the least significant bits.
+
+ChosenEncryptionAlgorithm ::= OCTET STRING (SIZE (1))
+ -- Octet contains a complete EncryptionAlgorithm data type
+ -- as defined in 3GPP TS 25.413, encoded according to the encoding scheme
+ -- mandated by 3GPP TS 25.413
+ -- Padding bits are included in the least significant bits.
+
+ChosenRadioResourceInformation ::= SEQUENCE {
+ chosenChannelInfo [0] ChosenChannelInfo OPTIONAL,
+ chosenSpeechVersion [1] ChosenSpeechVersion OPTIONAL,
+ ...}
+
+ChosenChannelInfo ::= OCTET STRING (SIZE (1))
+ -- Octets are coded according the Chosen Channel information element in 3GPP TS 48.008
+
+ChosenSpeechVersion ::= OCTET STRING (SIZE (1))
+ -- Octets are coded according the Speech Version (chosen) information element in 3GPP TS
+ -- 48.008
+
+PrepareSubsequentHO-Arg ::= [3] SEQUENCE {
+ targetCellId [0] GlobalCellId OPTIONAL,
+ targetMSC-Number [1] ISDN-AddressString,
+ targetRNCId [2] RNCId OPTIONAL,
+ an-APDU [3] AccessNetworkSignalInfo OPTIONAL,
+ selectedRab-Id [4] RAB-Id OPTIONAL,
+ extensionContainer [5] ExtensionContainer OPTIONAL,
+ ...,
+ geran-classmark [6] GERAN-Classmark OPTIONAL,
+ rab-ConfigurationIndicator [7] NULL OPTIONAL }
+
+PrepareSubsequentHO-Res ::= [3] SEQUENCE {
+ an-APDU AccessNetworkSignalInfo,
+ extensionContainer [0] ExtensionContainer OPTIONAL,
+ ...}
+
+ProcessAccessSignalling-Arg ::= [3] SEQUENCE {
+ an-APDU AccessNetworkSignalInfo,
+ selectedUMTS-Algorithms [1] SelectedUMTS-Algorithms OPTIONAL,
+ selectedGSM-Algorithm [2] SelectedGSM-Algorithm OPTIONAL,
+ chosenRadioResourceInformation [3] ChosenRadioResourceInformation OPTIONAL,
+ selectedRab-Id [4] RAB-Id OPTIONAL,
+ extensionContainer [0] ExtensionContainer OPTIONAL,
+ ...,
+ iUSelectedCodec [5] Codec OPTIONAL,
+ iuAvailableCodecsList [6] CodecList OPTIONAL }
+
+SupportedCodecsList ::= SEQUENCE {
+ utranCodecList [0] CodecList OPTIONAL,
+ geranCodecList [1] CodecList OPTIONAL,
+ extensionContainer [2] ExtensionContainer OPTIONAL,
+ ...}
+
+CodecList ::= SEQUENCE {
+ codec1 [1] Codec,
+ codec2 [2] Codec OPTIONAL,
+ codec3 [3] Codec OPTIONAL,
+ codec4 [4] Codec OPTIONAL,
+ codec5 [5] Codec OPTIONAL,
+ codec6 [6] Codec OPTIONAL,
+ codec7 [7] Codec OPTIONAL,
+ codec8 [8] Codec OPTIONAL,
+ extensionContainer [9] ExtensionContainer OPTIONAL,
+ ...}
+ -- Codecs are sent in priority order where codec1 has highest priority
+
+Codec ::= OCTET STRING (SIZE (1..4))
+
+ -- The internal structure is defined as follows:
+ -- octet 1 Coded as Codec Identification code in 3GPP TS 26.103
+ -- octets 2,3,4 Parameters for the Codec as defined in 3GPP TS
+ -- 26.103, if available, length depending on the codec
+
+GERAN-Classmark ::= OCTET STRING (SIZE (2..87))
+ -- Octets are coded according the GERAN Classmark information element in 3GPP TS 48.008
+
+SelectedGSM-Algorithm ::= OCTET STRING (SIZE (1))
+ -- internal structure is coded as Algorithm identifier octet from Chosen Encryption
+ -- Algorithm defined in 3GPP TS 48.008
+ -- A node shall mark only the selected GSM algorithm
+
+SendEndSignal-Arg ::= [3] SEQUENCE {
+ an-APDU AccessNetworkSignalInfo,
+ extensionContainer [0] ExtensionContainer OPTIONAL,
+ ...}
+
+SendEndSignal-Res ::= SEQUENCE {
+ extensionContainer [0] ExtensionContainer OPTIONAL,
+ ...}
+
+RNCId ::= OCTET STRING (SIZE (7))
+ -- The internal structure is defined as follows:
+ -- octet 1 bits 4321 Mobile Country Code 1st digit
+ -- bits 8765 Mobile Country Code 2nd digit
+ -- octet 2 bits 4321 Mobile Country Code 3rd digit
+ -- bits 8765 Mobile Network Code 3rd digit
+ -- or filler (1111) for 2 digit MNCs
+ -- octet 3 bits 4321 Mobile Network Code 1st digit
+ -- bits 8765 Mobile Network Code 2nd digit
+ -- octets 4 and 5 Location Area Code according to 3GPP TS 24.008
+ -- octets 6 and 7 RNC Id value according to 3GPP TS 25.413
+
+RelocationNumberList ::= SEQUENCE SIZE (1..maxNumOfRelocationNumber) OF
+ RelocationNumber
+
+MulticallBearerInfo ::= INTEGER (1..maxNumOfRelocationNumber)
+
+RelocationNumber ::= SEQUENCE {
+ handoverNumber ISDN-AddressString,
+ rab-Id RAB-Id,
+ -- RAB Identity is needed to relate the calls with the radio access bearers.
+ ...}
+
+RAB-Id ::= INTEGER (1..maxNrOfRABs)
+
+maxNrOfRABs INTEGER ::= 255
+
+maxNumOfRelocationNumber INTEGER ::= 7
+
+RadioResourceInformation ::= OCTET STRING (SIZE (3..13))
+ -- Octets are coded according the Channel Type information element in 3GPP TS 48.008
+
+IntegrityProtectionInformation ::= OCTET STRING (SIZE (18..maxNumOfIntegrityInfo))
+ -- Octets contain a complete IntegrityProtectionInformation data type
+ -- as defined in 3GPP TS 25.413, encoded according to the encoding scheme
+ -- mandated by 3GPP TS 25.413
+ -- Padding bits are included, if needed, in the least significant bits of the
+ -- last octet of the octet string.
+
+maxNumOfIntegrityInfo INTEGER ::= 100
+
+EncryptionInformation ::= OCTET STRING (SIZE (18..maxNumOfEncryptionInfo))
+ -- Octets contain a complete EncryptionInformation data type
+ -- as defined in 3GPP TS 25.413, encoded according to the encoding scheme
+ -- mandated by 3GPP TS 25.413
+ -- Padding bits are included, if needed, in the least significant bits of the
+ -- last octet of the octet string.
+
+maxNumOfEncryptionInfo INTEGER ::= 100
+
+-- authentication management types
+
+SendAuthenticationInfoArg ::= SEQUENCE {
+ imsi [0] IMSI,
+ numberOfRequestedVectors NumberOfRequestedVectors,
+ segmentationProhibited NULL OPTIONAL,
+ immediateResponsePreferred [1] NULL OPTIONAL,
+ re-synchronisationInfo Re-synchronisationInfo OPTIONAL,
+ extensionContainer [2] ExtensionContainer OPTIONAL,
+ ...,
+ requestingNodeType [3] RequestingNodeType OPTIONAL,
+ requestingPLMN-Id [4] PLMN-Id OPTIONAL }
+
+PLMN-Id ::= OCTET STRING (SIZE (3))
+ -- The internal structure is defined as follows:
+ -- octet 1 bits 4321 Mobile Country Code 1st digit
+ -- bits 8765 Mobile Country Code 2nd digit
+ -- octet 2 bits 4321 Mobile Country Code 3rd digit
+ -- bits 8765 Mobile Network Code 3rd digit
+ -- or filler (1111) for 2 digit MNCs
+ -- octet 3 bits 4321 Mobile Network Code 1st digit
+ -- bits 8765 Mobile Network Code 2nd digit
+
+NumberOfRequestedVectors ::= INTEGER (1..5)
+
+Re-synchronisationInfo ::= SEQUENCE {
+ rand RAND,
+ auts AUTS,
+ ...}
+
+SendAuthenticationInfoRes ::= [3] SEQUENCE {
+ authenticationSetList AuthenticationSetList OPTIONAL,
+ extensionContainer ExtensionContainer OPTIONAL,
+ ...}
+
+RequestingNodeType ::= ENUMERATED {
+ vlr (0),
+ sgsn (1),
+ ...}
+ -- exception handling:
+ -- received values in the range 2-15 shall be treated as "vlr"
+ -- received values greater than 15 shall be treated as "sgsn"
+
+-- equipment management types
+
+CheckIMEI-Arg ::= SEQUENCE {
+ imei IMEI,
+ requestedEquipmentInfo RequestedEquipmentInfo,
+ extensionContainer ExtensionContainer OPTIONAL,
+ ...}
+
+CheckIMEI-Res ::= SEQUENCE {
+ equipmentStatus EquipmentStatus OPTIONAL,
+ bmuef UESBI-Iu OPTIONAL,
+ extensionContainer [0] ExtensionContainer OPTIONAL,
+ ...}
+
+RequestedEquipmentInfo::= BIT STRING {
+ equipmentStatus (0),
+ bmuef (1)} (SIZE (2..8))
+ -- exception handling: reception of unknown bit assignments in the
+ -- RequestedEquipmentInfo data type shall be discarded by the receiver
+
+UESBI-Iu ::= SEQUENCE {
+ uesbi-IuA [0] UESBI-IuA OPTIONAL,
+ uesbi-IuB [1] UESBI-IuB OPTIONAL,
+ ...}
+
+UESBI-IuA ::= BIT STRING (SIZE(1..128))
+-- See 3GPP TS 25.413
+
+UESBI-IuB ::= BIT STRING (SIZE(1..128))
+-- See 3GPP TS 25.413
+
+EquipmentStatus ::= ENUMERATED {
+ whiteListed (0),
+ blackListed (1),
+ greyListed (2)}
+
+-- subscriber management types
+
+InsertSubscriberDataArg ::= SEQUENCE {
+ imsi [0] IMSI OPTIONAL,
+ COMPONENTS OF SubscriberData,
+ extensionContainer [14] ExtensionContainer OPTIONAL,
+ ... ,
+ naea-PreferredCI [15] NAEA-PreferredCI OPTIONAL,
+ -- naea-PreferredCI is included at the discretion of the HLR operator.
+ gprsSubscriptionData [16] GPRSSubscriptionData OPTIONAL,
+ roamingRestrictedInSgsnDueToUnsupportedFeature [23] NULL
+ OPTIONAL,
+ networkAccessMode [24] NetworkAccessMode OPTIONAL,
+ lsaInformation [25] LSAInformation OPTIONAL,
+ lmu-Indicator [21] NULL OPTIONAL,
+ lcsInformation [22] LCSInformation OPTIONAL,
+ istAlertTimer [26] IST-AlertTimerValue OPTIONAL,
+ superChargerSupportedInHLR [27] AgeIndicator OPTIONAL,
+ mc-SS-Info [28] MC-SS-Info OPTIONAL,
+ cs-AllocationRetentionPriority [29] CS-AllocationRetentionPriority OPTIONAL,
+ sgsn-CAMEL-SubscriptionInfo [17] SGSN-CAMEL-SubscriptionInfo OPTIONAL,
+ chargingCharacteristics [18] ChargingCharacteristics OPTIONAL,
+ accessRestrictionData [19] AccessRestrictionData OPTIONAL
+ }
+ -- If the Network Access Mode parameter is sent, it shall be present only in
+ -- the first sequence if seqmentation is used
+
+AccessRestrictionData ::= BIT STRING {
+ utranNotAllowed (0),
+ geranNotAllowed (1) } (SIZE (2..8))
+ -- exception handling:
+ -- bits 2 to 7 shall be ignored if received and not understood
+
+
+CS-AllocationRetentionPriority ::= OCTET STRING (SIZE (1))
+ -- This data type encodes each priority level defined in TS 23.107 as the binary value
+ -- of the priority level.
+
+IST-AlertTimerValue ::= INTEGER (15..255)
+
+LCSInformation ::= SEQUENCE {
+ gmlc-List [0] GMLC-List OPTIONAL,
+ lcs-PrivacyExceptionList [1] LCS-PrivacyExceptionList OPTIONAL,
+ molr-List [2] MOLR-List OPTIONAL,
+ ...,
+ add-lcs-PrivacyExceptionList [3] LCS-PrivacyExceptionList OPTIONAL }
+ -- add-lcs-PrivacyExceptionList may be sent only if lcs-PrivacyExceptionList is
+ -- present and contains four instances of LCS-PrivacyClass. If the mentioned condition
+ -- is not satisfied the receiving node shall discard add-lcs-PrivacyExceptionList.
+ -- If an LCS-PrivacyClass is received both in lcs-PrivacyExceptionList and in
+ -- add-lcs-PrivacyExceptionList with the same SS-Code, then the error unexpected
+ -- data value shall be returned.
+
+GMLC-List ::= SEQUENCE SIZE (1..maxNumOfGMLC) OF
+ ISDN-AddressString
+ -- if segmentation is used, the complete GMLC-List shall be sent in one segment
+
+maxNumOfGMLC INTEGER ::= 5
+
+NetworkAccessMode ::= ENUMERATED {
+ bothMSCAndSGSN (0),
+ onlyMSC (1),
+ onlySGSN (2),
+ ...}
+ -- if unknown values are received in NetworkAccessMode
+ -- they shall be discarded.
+
+GPRSDataList ::= SEQUENCE SIZE (1..maxNumOfPDP-Contexts) OF
+ PDP-Context
+
+maxNumOfPDP-Contexts INTEGER ::= 50
+
+PDP-Context ::= SEQUENCE {
+ pdp-ContextId ContextId,
+ pdp-Type [16] PDP-Type,
+ pdp-Address [17] PDP-Address OPTIONAL,
+ qos-Subscribed [18] QoS-Subscribed,
+ vplmnAddressAllowed [19] NULL OPTIONAL,
+ apn [20] APN,
+ extensionContainer [21] ExtensionContainer OPTIONAL,
+ ... ,
+ ext-QoS-Subscribed [0] Ext-QoS-Subscribed OPTIONAL,
+ pdp-ChargingCharacteristics [1] ChargingCharacteristics OPTIONAL,
+ ext2-QoS-Subscribed [2] Ext2-QoS-Subscribed OPTIONAL
+ -- ext2-QoS-Subscribed may be present only if ext-QoS-Subscribed is present.
+ }
+
+ContextId ::= INTEGER (1..maxNumOfPDP-Contexts)
+
+GPRSSubscriptionData ::= SEQUENCE {
+ completeDataListIncluded NULL OPTIONAL,
+ -- If segmentation is used, completeDataListIncluded may only be present in the
+ -- first segment.
+ gprsDataList [1] GPRSDataList,
+ extensionContainer [2] ExtensionContainer OPTIONAL,
+ ... }
+
+SGSN-CAMEL-SubscriptionInfo ::= SEQUENCE {
+ gprs-CSI [0] GPRS-CSI OPTIONAL,
+ mo-sms-CSI [1] SMS-CSI OPTIONAL,
+ extensionContainer [2] ExtensionContainer OPTIONAL,
+ ...,
+ mt-sms-CSI [3] SMS-CSI OPTIONAL,
+ mt-smsCAMELTDP-CriteriaList [4] MT-smsCAMELTDP-CriteriaList OPTIONAL,
+ mg-csi [5] MG-CSI OPTIONAL
+ }
+
+GPRS-CSI ::= SEQUENCE {
+ gprs-CamelTDPDataList [0] GPRS-CamelTDPDataList OPTIONAL,
+ camelCapabilityHandling [1] CamelCapabilityHandling OPTIONAL,
+ extensionContainer [2] ExtensionContainer OPTIONAL,
+ notificationToCSE [3] NULL OPTIONAL,
+ csi-Active [4] NULL OPTIONAL,
+ ...}
+-- notificationToCSE and csi-Active shall not be present when GPRS-CSI is sent to SGSN.
+-- They may only be included in ATSI/ATM ack/NSDC message.
+-- GPRS-CamelTDPData and camelCapabilityHandling shall be present in
+-- the GPRS-CSI sequence.
+-- If GPRS-CSI is segmented, gprs-CamelTDPDataList and camelCapabilityHandling shall be
+-- present in the first segment
+
+GPRS-CamelTDPDataList ::= SEQUENCE SIZE (1..maxNumOfCamelTDPData) OF
+ GPRS-CamelTDPData
+-- GPRS-CamelTDPDataList shall not contain more than one instance of
+-- GPRS-CamelTDPData containing the same value for gprs-TriggerDetectionPoint.
+
+GPRS-CamelTDPData ::= SEQUENCE {
+ gprs-TriggerDetectionPoint [0] GPRS-TriggerDetectionPoint,
+ serviceKey [1] ServiceKey,
+ gsmSCF-Address [2] ISDN-AddressString,
+ defaultSessionHandling [3] DefaultGPRS-Handling,
+ extensionContainer [4] ExtensionContainer OPTIONAL,
+ ...
+ }
+
+DefaultGPRS-Handling ::= ENUMERATED {
+ continueTransaction (0) ,
+ releaseTransaction (1) ,
+ ...}
+-- exception handling:
+-- reception of values in range 2-31 shall be treated as "continueTransaction"
+-- reception of values greater than 31 shall be treated as "releaseTransaction"
+
+GPRS-TriggerDetectionPoint ::= ENUMERATED {
+ attach (1),
+ attachChangeOfPosition (2),
+ pdp-ContextEstablishment (11),
+ pdp-ContextEstablishmentAcknowledgement (12),
+ pdp-ContextChangeOfPosition (14),
+ ... }
+-- exception handling:
+-- For GPRS-CamelTDPData sequences containing this parameter with any
+-- other value than the ones listed the receiver shall ignore the whole
+-- GPRS-CamelTDPDatasequence.
+
+APN ::= OCTET STRING (SIZE (2..63))
+ -- Octets are coded according to TS 3GPP TS 23.003 [17]
+
+PDP-Type ::= OCTET STRING (SIZE (2))
+ -- Octets are coded according to TS 3GPP TS 29.060 [105]
+
+PDP-Address ::= OCTET STRING (SIZE (1..16))
+ -- Octets are coded according to TS 3GPP TS 29.060 [105]
+
+ -- The possible size values are:
+ -- 1-7 octets X.25 address type
+ -- 4 octets IPv4 address type
+ -- 16 octets Ipv6 address type
+
+QoS-Subscribed ::= OCTET STRING (SIZE (3))
+ -- Octets are coded according to TS 3GPP TS 24.008 [35] Quality of Service Octets
+ -- 3-5.
+
+Ext-QoS-Subscribed ::= OCTET STRING (SIZE (1..9))
+ -- OCTET 1:
+ -- Allocation/Retention Priority (This octet encodes each priority level defined in
+ -- 23.107 as the binary value of the priority level, declaration in 29.060)
+ -- Octets 2-9 are coded according to 3GPP TS 24.008 [35] Quality of Service Octets
+ -- 6-13.
+
+Ext2-QoS-Subscribed ::= OCTET STRING (SIZE (1..3))
+ -- Octets 1-3 are coded according to 3GPP TS 24.008 [35] Quality of Service Octets 14-16.
+ -- If Quality of Service information is structured with 14 octet length, then
+ -- Octet 1 is coded according to 3GPP TS 24.008 [35] Quality of Service Octet 14.
+
+ChargingCharacteristics ::= OCTET STRING (SIZE (2))
+ -- Octets are coded according to 3GPP TS 32.215.
+
+LSAOnlyAccessIndicator ::= ENUMERATED {
+ accessOutsideLSAsAllowed (0),
+ accessOutsideLSAsRestricted (1)}
+
+LSADataList ::= SEQUENCE SIZE (1..maxNumOfLSAs) OF
+ LSAData
+
+maxNumOfLSAs INTEGER ::= 20
+
+LSAData ::= SEQUENCE {
+ lsaIdentity [0] LSAIdentity,
+ lsaAttributes [1] LSAAttributes,
+ lsaActiveModeIndicator [2] NULL OPTIONAL,
+ extensionContainer [3] ExtensionContainer OPTIONAL,
+ ...}
+
+LSAInformation ::= SEQUENCE {
+ completeDataListIncluded NULL OPTIONAL,
+
+ -- If segmentation is used, completeDataListIncluded may only be present in the
+ -- first segment.
+ lsaOnlyAccessIndicator [1] LSAOnlyAccessIndicator OPTIONAL,
+ lsaDataList [2] LSADataList OPTIONAL,
+ extensionContainer [3] ExtensionContainer OPTIONAL,
+ ...}
+
+LSAIdentity ::= OCTET STRING (SIZE (3))
+ -- Octets are coded according to TS 3GPP TS 23.003 [17]
+
+LSAAttributes ::= OCTET STRING (SIZE (1))
+ -- Octets are coded according to TS 3GPP TS 48.008 [49]
+
+SubscriberData ::= SEQUENCE {
+ msisdn [1] ISDN-AddressString OPTIONAL,
+ category [2] Category OPTIONAL,
+ subscriberStatus [3] SubscriberStatus OPTIONAL,
+ bearerServiceList [4] BearerServiceList OPTIONAL,
+ -- The exception handling for reception of unsupported / not allocated
+ -- bearerServiceCodes is defined in section 8.8.1
+ teleserviceList [6] TeleserviceList OPTIONAL,
+ -- The exception handling for reception of unsupported / not allocated
+ -- teleserviceCodes is defined in section 8.8.1
+ provisionedSS [7] Ext-SS-InfoList OPTIONAL,
+ odb-Data [8] ODB-Data OPTIONAL,
+ roamingRestrictionDueToUnsupportedFeature [9] NULL OPTIONAL,
+ regionalSubscriptionData [10] ZoneCodeList OPTIONAL,
+ vbsSubscriptionData [11] VBSDataList OPTIONAL,
+ vgcsSubscriptionData [12] VGCSDataList OPTIONAL,
+ vlrCamelSubscriptionInfo [13] VlrCamelSubscriptionInfo OPTIONAL
+ }
+
+Category ::= OCTET STRING (SIZE (1))
+ -- The internal structure is defined in ITU-T Rec Q.763.
+
+SubscriberStatus ::= ENUMERATED {
+ serviceGranted (0),
+ operatorDeterminedBarring (1)}
+
+BearerServiceList ::= SEQUENCE SIZE (1..maxNumOfBearerServices) OF
+ Ext-BearerServiceCode
+
+maxNumOfBearerServices INTEGER ::= 50
+
+TeleserviceList ::= SEQUENCE SIZE (1..maxNumOfTeleservices) OF
+ Ext-TeleserviceCode
+
+maxNumOfTeleservices INTEGER ::= 20
+
+ODB-Data ::= SEQUENCE {
+ odb-GeneralData ODB-GeneralData,
+ odb-HPLMN-Data ODB-HPLMN-Data OPTIONAL,
+ extensionContainer ExtensionContainer OPTIONAL,
+ ...}
+
+ODB-GeneralData ::= BIT STRING {
+ allOG-CallsBarred (0),
+ internationalOGCallsBarred (1),
+ internationalOGCallsNotToHPLMN-CountryBarred (2),
+ interzonalOGCallsBarred (6),
+ interzonalOGCallsNotToHPLMN-CountryBarred (7),
+ interzonalOGCallsAndInternationalOGCallsNotToHPLMN-CountryBarred (8),
+ premiumRateInformationOGCallsBarred (3),
+ premiumRateEntertainementOGCallsBarred (4),
+ ss-AccessBarred (5),
+ allECT-Barred (9),
+ chargeableECT-Barred (10),
+ internationalECT-Barred (11),
+ interzonalECT-Barred (12),
+ doublyChargeableECT-Barred (13),
+ multipleECT-Barred (14),
+ allPacketOrientedServicesBarred (15),
+ roamerAccessToHPLMN-AP-Barred (16),
+ roamerAccessToVPLMN-AP-Barred (17),
+ roamingOutsidePLMNOG-CallsBarred (18),
+ allIC-CallsBarred (19),
+ roamingOutsidePLMNIC-CallsBarred (20),
+ roamingOutsidePLMNICountryIC-CallsBarred (21),
+ roamingOutsidePLMN-Barred (22),
+ roamingOutsidePLMN-CountryBarred (23),
+ registrationAllCF-Barred (24),
+ registrationCFNotToHPLMN-Barred (25),
+ registrationInterzonalCF-Barred (26),
+ registrationInterzonalCFNotToHPLMN-Barred (27),
+ registrationInternationalCF-Barred (28)} (SIZE (15..32))
+ -- exception handling: reception of unknown bit assignments in the
+ -- ODB-GeneralData type shall be treated like unsupported ODB-GeneralData
+ -- When the ODB-GeneralData type is removed from the HLR for a given subscriber,
+ -- in NoteSubscriberDataModified operation sent toward the gsmSCF
+ -- all bits shall be set to "O".
+
+ODB-HPLMN-Data ::= BIT STRING {
+ plmn-SpecificBarringType1 (0),
+ plmn-SpecificBarringType2 (1),
+ plmn-SpecificBarringType3 (2),
+ plmn-SpecificBarringType4 (3)} (SIZE (4..32))
+ -- exception handling: reception of unknown bit assignments in the
+ -- ODB-HPLMN-Data type shall be treated like unsupported ODB-HPLMN-Data
+ -- When the ODB-HPLMN-Data type is removed from the HLR for a given subscriber,
+ -- in NoteSubscriberDataModified operation sent toward the gsmSCF
+ -- all bits shall be set to "O".
+
+Ext-SS-InfoList ::= SEQUENCE SIZE (1..maxNumOfSS) OF
+ Ext-SS-Info
+
+Ext-SS-Info ::= CHOICE {
+ forwardingInfo [0] Ext-ForwInfo,
+ callBarringInfo [1] Ext-CallBarInfo,
+ cug-Info [2] CUG-Info,
+ ss-Data [3] Ext-SS-Data,
+ emlpp-Info [4] EMLPP-Info}
+
+Ext-ForwInfo ::= SEQUENCE {
+ ss-Code SS-Code,
+ forwardingFeatureList Ext-ForwFeatureList,
+ extensionContainer [0] ExtensionContainer OPTIONAL,
+ ...}
+
+Ext-ForwFeatureList ::= SEQUENCE SIZE (1..maxNumOfExt-BasicServiceGroups) OF
+ Ext-ForwFeature
+
+Ext-ForwFeature ::= SEQUENCE {
+ basicService Ext-BasicServiceCode OPTIONAL,
+ ss-Status [4] Ext-SS-Status,
+ forwardedToNumber [5] ISDN-AddressString OPTIONAL,
+ -- When this data type is sent from an HLR which supports CAMEL Phase 2
+ -- to a VLR that supports CAMEL Phase 2 the VLR shall not check the
+ -- format of the number
+ forwardedToSubaddress [8] ISDN-SubaddressString OPTIONAL,
+ forwardingOptions [6] Ext-ForwOptions OPTIONAL,
+ noReplyConditionTime [7] Ext-NoRepCondTime OPTIONAL,
+ extensionContainer [9] ExtensionContainer OPTIONAL,
+ ...,
+ longForwardedToNumber [10] FTN-AddressString OPTIONAL }
+
+Ext-ForwOptions ::= OCTET STRING (SIZE (1..5))
+
+ -- OCTET 1:
+
+ -- bit 8: notification to forwarding party
+ -- 0 no notification
+ -- 1 notification
+
+ -- bit 7: redirecting presentation
+ -- 0 no presentation
+ -- 1 presentation
+
+ -- bit 6: notification to calling party
+ -- 0 no notification
+ -- 1 notification
+
+ -- bit 5: 0 (unused)
+
+ -- bits 43: forwarding reason
+ -- 00 ms not reachable
+ -- 01 ms busy
+ -- 10 no reply
+ -- 11 unconditional
+
+ -- bits 21: 00 (unused)
+
+ -- OCTETS 2-5: reserved for future use. They shall be discarded if
+ -- received and not understood.
+
+Ext-NoRepCondTime ::= INTEGER (1..100)
+ -- Only values 5-30 are used.
+ -- Values in the ranges 1-4 and 31-100 are reserved for future use
+ -- If received:
+ -- values 1-4 shall be mapped on to value 5
+ -- values 31-100 shall be mapped on to value 30
+
+Ext-CallBarInfo ::= SEQUENCE {
+ ss-Code SS-Code,
+ callBarringFeatureList Ext-CallBarFeatureList,
+ extensionContainer ExtensionContainer OPTIONAL,
+ ...}
+
+Ext-CallBarFeatureList ::= SEQUENCE SIZE (1..maxNumOfExt-BasicServiceGroups) OF
+ Ext-CallBarringFeature
+
+Ext-CallBarringFeature ::= SEQUENCE {
+ basicService Ext-BasicServiceCode OPTIONAL,
+ ss-Status [4] Ext-SS-Status,
+ extensionContainer ExtensionContainer OPTIONAL,
+ ...}
+
+CUG-Info ::= SEQUENCE {
+ cug-SubscriptionList CUG-SubscriptionList,
+ cug-FeatureList CUG-FeatureList OPTIONAL,
+ extensionContainer [0] ExtensionContainer OPTIONAL,
+ ...}
+
+CUG-SubscriptionList ::= SEQUENCE SIZE (0..maxNumOfCUG) OF
+ CUG-Subscription
+
+CUG-Subscription ::= SEQUENCE {
+ cug-Index CUG-Index,
+ cug-Interlock CUG-Interlock,
+ intraCUG-Options IntraCUG-Options,
+ basicServiceGroupList Ext-BasicServiceGroupList OPTIONAL,
+ extensionContainer [0] ExtensionContainer OPTIONAL,
+ ...}
+
+CUG-Index ::= INTEGER (0..32767)
+ -- The internal structure is defined in ETS 300 138.
+
+CUG-Interlock ::= OCTET STRING (SIZE (4))
+
+IntraCUG-Options ::= ENUMERATED {
+ noCUG-Restrictions (0),
+ cugIC-CallBarred (1),
+ cugOG-CallBarred (2)}
+
+maxNumOfCUG INTEGER ::= 10
+
+CUG-FeatureList ::= SEQUENCE SIZE (1..maxNumOfExt-BasicServiceGroups) OF
+ CUG-Feature
+
+Ext-BasicServiceGroupList ::= SEQUENCE SIZE (1..maxNumOfExt-BasicServiceGroups) OF
+ Ext-BasicServiceCode
+
+maxNumOfExt-BasicServiceGroups INTEGER ::= 32
+
+CUG-Feature ::= SEQUENCE {
+ basicService Ext-BasicServiceCode OPTIONAL,
+ preferentialCUG-Indicator CUG-Index OPTIONAL,
+ interCUG-Restrictions InterCUG-Restrictions,
+ extensionContainer ExtensionContainer OPTIONAL,
+ ...}
+
+InterCUG-Restrictions ::= OCTET STRING (SIZE (1))
+
+ -- bits 876543: 000000 (unused)
+ -- Exception handling:
+ -- bits 876543 shall be ignored if received and not understood
+
+ -- bits 21
+ -- 00 CUG only facilities
+ -- 01 CUG with outgoing access
+ -- 10 CUG with incoming access
+ -- 11 CUG with both outgoing and incoming access
+
+Ext-SS-Data ::= SEQUENCE {
+ ss-Code SS-Code,
+ ss-Status [4] Ext-SS-Status,
+ ss-SubscriptionOption SS-SubscriptionOption OPTIONAL,
+ basicServiceGroupList Ext-BasicServiceGroupList OPTIONAL,
+ extensionContainer [5] ExtensionContainer OPTIONAL,
+ ...}
+
+LCS-PrivacyExceptionList ::= SEQUENCE SIZE (1..maxNumOfPrivacyClass) OF
+ LCS-PrivacyClass
+
+maxNumOfPrivacyClass INTEGER ::= 4
+
+LCS-PrivacyClass ::= SEQUENCE {
+ ss-Code SS-Code,
+ ss-Status Ext-SS-Status,
+ notificationToMSUser [0] NotificationToMSUser OPTIONAL,
+ -- notificationToMSUser may be sent only for SS-codes callSessionRelated
+ -- and callSessionUnrelated. If not received for SS-codes callSessionRelated
+ -- and callSessionUnrelated,
+ -- the default values according to 3GPP TS 23.271 shall be assumed.
+ externalClientList [1] ExternalClientList OPTIONAL,
+ -- externalClientList may be sent only for SS-code callSessionUnrelated to a
+ -- visited node that does not support LCS Release 4 or later versions.
+ -- externalClientList may be sent only for SS-codes callSessionUnrelated and
+ -- callSessionRelated to a visited node that supports LCS Release 4 or later versions.
+ plmnClientList [2] PLMNClientList OPTIONAL,
+ -- plmnClientList may be sent only for SS-code plmnoperator.
+ extensionContainer [3] ExtensionContainer OPTIONAL,
+ ...,
+ ext-externalClientList [4] Ext-ExternalClientList OPTIONAL,
+ -- Ext-externalClientList may be sent only if the visited node supports LCS Release 4 or
+ -- later versions, the user did specify more than 5 clients, and White Book SCCP is used.
+ serviceTypeList [5] ServiceTypeList OPTIONAL
+ -- serviceTypeList may be sent only for SS-code serviceType and if the visited node
+ -- supports LCS Release 5 or later versions.
+ --
+ -- if segmentation is used, the complete LCS-PrivacyClass shall be sent in one segment
+}
+
+ExternalClientList ::= SEQUENCE SIZE (0..maxNumOfExternalClient) OF
+ ExternalClient
+
+maxNumOfExternalClient INTEGER ::= 5
+
+PLMNClientList ::= SEQUENCE SIZE (1..maxNumOfPLMNClient) OF
+ LCSClientInternalID
+
+maxNumOfPLMNClient INTEGER ::= 5
+
+Ext-ExternalClientList ::= SEQUENCE SIZE (1..maxNumOfExt-ExternalClient) OF
+ ExternalClient
+
+maxNumOfExt-ExternalClient INTEGER ::= 35
+
+ExternalClient ::= SEQUENCE {
+ clientIdentity LCSClientExternalID,
+ gmlc-Restriction [0] GMLC-Restriction OPTIONAL,
+ notificationToMSUser [1] NotificationToMSUser OPTIONAL,
+ -- If notificationToMSUser is not received, the default value according to
+ -- 3GPP TS 23.271 shall be assumed.
+ extensionContainer [2] ExtensionContainer OPTIONAL,
+ ... }
+
+GMLC-Restriction ::= ENUMERATED {
+ gmlc-List (0),
+ home-Country (1) ,
+ ... }
+-- exception handling:
+-- At reception of any other value than the ones listed the receiver shall ignore
+-- GMLC-Restriction.
+
+NotificationToMSUser ::= ENUMERATED {
+ notifyLocationAllowed (0),
+ notifyAndVerify-LocationAllowedIfNoResponse (1),
+ notifyAndVerify-LocationNotAllowedIfNoResponse (2),
+ ...,
+ locationNotAllowed (3) }
+-- exception handling:
+-- At reception of any other value than the ones listed the receiver shall ignore
+-- NotificationToMSUser.
+
+ServiceTypeList ::= SEQUENCE SIZE (1..maxNumOfServiceType) OF
+ ServiceType
+
+maxNumOfServiceType INTEGER ::= 32
+
+ServiceType ::= SEQUENCE {
+ serviceTypeIdentity LCSServiceTypeID,
+ gmlc-Restriction [0] GMLC-Restriction OPTIONAL,
+ notificationToMSUser [1] NotificationToMSUser OPTIONAL,
+ -- If notificationToMSUser is not received, the default value according to
+ -- 3GPP TS 23.271 shall be assumed.
+ extensionContainer [2] ExtensionContainer OPTIONAL,
+ ... }
+
+MOLR-List ::= SEQUENCE SIZE (1..maxNumOfMOLR-Class) OF
+ MOLR-Class
+
+maxNumOfMOLR-Class INTEGER ::= 3
+
+MOLR-Class ::= SEQUENCE {
+ ss-Code SS-Code,
+ ss-Status Ext-SS-Status,
+ extensionContainer [0] ExtensionContainer OPTIONAL,
+ ...}
+
+ZoneCodeList ::= SEQUENCE SIZE (1..maxNumOfZoneCodes)
+ OF ZoneCode
+
+ZoneCode ::= OCTET STRING (SIZE (2))
+ -- internal structure is defined in TS 3GPP TS 23.003 [17]
+
+maxNumOfZoneCodes INTEGER ::= 10
+
+InsertSubscriberDataRes ::= SEQUENCE {
+ teleserviceList [1] TeleserviceList OPTIONAL,
+ bearerServiceList [2] BearerServiceList OPTIONAL,
+ ss-List [3] SS-List OPTIONAL,
+ odb-GeneralData [4] ODB-GeneralData OPTIONAL,
+ regionalSubscriptionResponse [5] RegionalSubscriptionResponse OPTIONAL,
+ supportedCamelPhases [6] SupportedCamelPhases OPTIONAL,
+ extensionContainer [7] ExtensionContainer OPTIONAL,
+ ... ,
+ offeredCamel4CSIs [8] OfferedCamel4CSIs OPTIONAL }
+
+RegionalSubscriptionResponse ::= ENUMERATED {
+ networkNode-AreaRestricted (0),
+ tooManyZoneCodes (1),
+ zoneCodesConflict (2),
+ regionalSubscNotSupported (3)}
+
+DeleteSubscriberDataArg ::= SEQUENCE {
+ imsi [0] IMSI,
+ basicServiceList [1] BasicServiceList OPTIONAL,
+ -- The exception handling for reception of unsupported/not allocated
+ -- basicServiceCodes is defined in section 6.8.2
+ ss-List [2] SS-List OPTIONAL,
+ roamingRestrictionDueToUnsupportedFeature [4] NULL OPTIONAL,
+ regionalSubscriptionIdentifier [5] ZoneCode OPTIONAL,
+ vbsGroupIndication [7] NULL OPTIONAL,
+ vgcsGroupIndication [8] NULL OPTIONAL,
+ camelSubscriptionInfoWithdraw [9] NULL OPTIONAL,
+ extensionContainer [6] ExtensionContainer OPTIONAL,
+ ...,
+ gprsSubscriptionDataWithdraw [10] GPRSSubscriptionDataWithdraw OPTIONAL,
+ roamingRestrictedInSgsnDueToUnsuppportedFeature [11] NULL OPTIONAL,
+ lsaInformationWithdraw [12] LSAInformationWithdraw OPTIONAL,
+ gmlc-ListWithdraw [13] NULL OPTIONAL,
+ istInformationWithdraw [14] NULL OPTIONAL,
+ specificCSI-Withdraw [15] SpecificCSI-Withdraw OPTIONAL }
+
+SpecificCSI-Withdraw ::= BIT STRING {
+ o-csi (0),
+ ss-csi (1),
+ tif-csi (2),
+ d-csi (3),
+ vt-csi (4),
+ mo-sms-csi (5),
+ m-csi (6),
+ gprs-csi (7),
+ t-csi (8),
+ mt-sms-csi (9),
+ mg-csi (10),
+ o-IM-CSI (11),
+ d-IM-CSI (12),
+ vt-IM-CSI (13) } (SIZE(8..32))
+-- exception handling:
+-- bits 11 to 31 shall be ignored if received by a non-IP Multimedia Core Network entity.
+-- bits 0-10 and 14-31 shall be ignored if received by an IP Multimedia Core Network entity.
+-- bits 11-13 are only applicable in an IP Multimedia Core Network.
+-- Bit 8 and bits 11-13 are only applicable for the NoteSubscriberDataModified operation.
+
+GPRSSubscriptionDataWithdraw ::= CHOICE {
+ allGPRSData NULL,
+ contextIdList ContextIdList}
+
+ContextIdList ::= SEQUENCE SIZE (1..maxNumOfPDP-Contexts) OF
+ ContextId
+
+LSAInformationWithdraw ::= CHOICE {
+ allLSAData NULL,
+ lsaIdentityList LSAIdentityList }
+
+LSAIdentityList ::= SEQUENCE SIZE (1..maxNumOfLSAs) OF
+ LSAIdentity
+
+BasicServiceList ::= SEQUENCE SIZE (1..maxNumOfBasicServices) OF
+ Ext-BasicServiceCode
+
+maxNumOfBasicServices INTEGER ::= 70
+
+DeleteSubscriberDataRes ::= SEQUENCE {
+ regionalSubscriptionResponse [0] RegionalSubscriptionResponse OPTIONAL,
+ extensionContainer ExtensionContainer OPTIONAL,
+ ...}
+
+VlrCamelSubscriptionInfo ::= SEQUENCE {
+ o-CSI [0] O-CSI OPTIONAL,
+ extensionContainer [1] ExtensionContainer OPTIONAL,
+ ...,
+ ss-CSI [2] SS-CSI OPTIONAL,
+ o-BcsmCamelTDP-CriteriaList [4] O-BcsmCamelTDPCriteriaList OPTIONAL,
+ tif-CSI [3] NULL OPTIONAL,
+ m-CSI [5] M-CSI OPTIONAL,
+ mo-sms-CSI [6] SMS-CSI OPTIONAL,
+ vt-CSI [7] T-CSI OPTIONAL,
+ t-BCSM-CAMEL-TDP-CriteriaList [8] T-BCSM-CAMEL-TDP-CriteriaList OPTIONAL,
+ d-CSI [9] D-CSI OPTIONAL,
+ mt-sms-CSI [10] SMS-CSI OPTIONAL,
+ mt-smsCAMELTDP-CriteriaList [11] MT-smsCAMELTDP-CriteriaList OPTIONAL
+ }
+
+MT-smsCAMELTDP-CriteriaList ::= SEQUENCE SIZE (1.. maxNumOfCamelTDPData) OF
+ MT-smsCAMELTDP-Criteria
+
+MT-smsCAMELTDP-Criteria ::= SEQUENCE {
+ sms-TriggerDetectionPoint SMS-TriggerDetectionPoint,
+ tpdu-TypeCriterion [0] TPDU-TypeCriterion OPTIONAL,
+ ... }
+
+TPDU-TypeCriterion ::= SEQUENCE SIZE (1..maxNumOfTPDUTypes) OF
+ MT-SMS-TPDU-Type
+
+
+maxNumOfTPDUTypes INTEGER ::= 5
+
+MT-SMS-TPDU-Type ::= ENUMERATED {
+ sms-DELIVER (0),
+ sms-SUBMIT-REPORT (1),
+ sms-STATUS-REPORT (2),
+ ... }
+
+-- exception handling:
+-- For TPDU-TypeCriterion sequences containing this parameter with any
+-- other value than the ones listed above the receiver shall ignore
+-- the whole TPDU-TypeCriterion sequence.
+-- In CAMEL phase 4, sms-SUBMIT-REPORT shall not be used and a received TPDU-TypeCriterion
+-- sequence containing sms-SUBMIT-REPORT shall be wholly ignored.
+
+D-CSI ::= SEQUENCE {
+ dp-AnalysedInfoCriteriaList [0] DP-AnalysedInfoCriteriaList OPTIONAL,
+ camelCapabilityHandling [1] CamelCapabilityHandling OPTIONAL,
+ extensionContainer [2] ExtensionContainer OPTIONAL,
+ notificationToCSE [3] NULL OPTIONAL,
+ csi-Active [4] NULL OPTIONAL,
+ ...}
+-- notificationToCSE and csi-Active shall not be present when D-CSI is sent to VLR/GMSC.
+-- They may only be included in ATSI/ATM ack/NSDC message.
+-- DP-AnalysedInfoCriteria and camelCapabilityHandling shall be present in
+-- the D-CSI sequence.
+-- If D-CSI is segmented, then the first segment shall contain dp-AnalysedInfoCriteriaList
+-- and camelCapabilityHandling. Subsequent segments shall not contain
+-- camelCapabilityHandling, but may contain dp-AnalysedInfoCriteriaList.
+
+DP-AnalysedInfoCriteriaList ::= SEQUENCE SIZE (1..maxNumOfDP-AnalysedInfoCriteria) OF
+ DP-AnalysedInfoCriterium
+
+maxNumOfDP-AnalysedInfoCriteria INTEGER ::= 10
+
+DP-AnalysedInfoCriterium ::= SEQUENCE {
+ dialledNumber ISDN-AddressString,
+ serviceKey ServiceKey,
+ gsmSCF-Address ISDN-AddressString,
+ defaultCallHandling DefaultCallHandling,
+ extensionContainer ExtensionContainer OPTIONAL,
+ ...}
+
+SS-CSI ::= SEQUENCE {
+ ss-CamelData SS-CamelData,
+ extensionContainer ExtensionContainer OPTIONAL,
+ ...,
+ notificationToCSE [0] NULL OPTIONAL,
+ csi-Active [1] NULL OPTIONAL
+-- notificationToCSE and csi-Active shall not be present when SS-CSI is sent to VLR.
+-- They may only be included in ATSI/ATM ack/NSDC message.
+}
+
+SS-CamelData ::= SEQUENCE {
+ ss-EventList SS-EventList,
+ gsmSCF-Address ISDN-AddressString,
+ extensionContainer [0] ExtensionContainer OPTIONAL,
+ ...}
+
+SS-EventList ::= SEQUENCE SIZE (1..maxNumOfCamelSSEvents) OF SS-Code
+ -- Actions for the following SS-Code values are defined in CAMEL Phase 3:
+ -- ect SS-Code ::= '00110001'B
+ -- multiPTY SS-Code ::= '01010001'B
+ -- cd SS-Code ::= '00100100'B
+ -- ccbs SS-Code ::= '01000100'B
+ -- all other SS codes shall be ignored
+ -- When SS-CSI is sent to the VLR, it shall not contain a marking for ccbs.
+ -- If the VLR receives SS-CSI containing a marking for ccbs, the VLR shall discard the
+ -- ccbs marking in SS-CSI.
+
+maxNumOfCamelSSEvents INTEGER ::= 10
+
+O-CSI ::= SEQUENCE {
+ o-BcsmCamelTDPDataList O-BcsmCamelTDPDataList,
+ extensionContainer ExtensionContainer OPTIONAL,
+ ...,
+ camelCapabilityHandling [0] CamelCapabilityHandling OPTIONAL,
+ notificationToCSE [1] NULL OPTIONAL,
+ csiActive [2] NULL OPTIONAL}
+-- notificationtoCSE and csiActive shall not be present when O-CSI is sent to VLR/GMSC.
+-- They may only be included in ATSI/ATM ack/NSDC message.
+-- O-CSI shall not be segmented.
+
+O-BcsmCamelTDPDataList ::= SEQUENCE SIZE (1..maxNumOfCamelTDPData) OF
+ O-BcsmCamelTDPData
+ -- O-BcsmCamelTDPDataList shall not contain more than one instance of
+ -- O-BcsmCamelTDPData containing the same value for o-BcsmTriggerDetectionPoint.
+ -- For CAMEL Phase 2, this means that only one instance of O-BcsmCamelTDPData is allowed
+ -- with o-BcsmTriggerDetectionPoint being equal to DP2.
+
+maxNumOfCamelTDPData INTEGER ::= 10
+
+O-BcsmCamelTDPData ::= SEQUENCE {
+ o-BcsmTriggerDetectionPoint O-BcsmTriggerDetectionPoint,
+ serviceKey ServiceKey,
+ gsmSCF-Address [0] ISDN-AddressString,
+ defaultCallHandling [1] DefaultCallHandling,
+ extensionContainer [2] ExtensionContainer OPTIONAL,
+ ...
+ }
+
+ServiceKey ::= INTEGER (0..2147483647)
+
+O-BcsmTriggerDetectionPoint ::= ENUMERATED {
+ collectedInfo (2),
+ ...,
+ routeSelectFailure (4) }
+ -- exception handling:
+ -- For O-BcsmCamelTDPData sequences containing this parameter with any
+ -- other value than the ones listed the receiver shall ignore the whole
+ -- O-BcsmCamelTDPDatasequence.
+ -- For O-BcsmCamelTDP-Criteria sequences containing this parameter with any
+ -- other value than the ones listed the receiver shall ignore the whole
+ -- O-BcsmCamelTDP-Criteria sequence.
+
+O-BcsmCamelTDPCriteriaList ::= SEQUENCE SIZE (1..maxNumOfCamelTDPData) OF
+ O-BcsmCamelTDP-Criteria
+
+T-BCSM-CAMEL-TDP-CriteriaList ::= SEQUENCE SIZE (1..maxNumOfCamelTDPData) OF
+ T-BCSM-CAMEL-TDP-Criteria
+
+O-BcsmCamelTDP-Criteria ::= SEQUENCE {
+ o-BcsmTriggerDetectionPoint O-BcsmTriggerDetectionPoint,
+ destinationNumberCriteria [0] DestinationNumberCriteria OPTIONAL,
+ basicServiceCriteria [1] BasicServiceCriteria OPTIONAL,
+ callTypeCriteria [2] CallTypeCriteria OPTIONAL,
+ ...,
+ o-CauseValueCriteria [3] O-CauseValueCriteria OPTIONAL,
+ extensionContainer [4] ExtensionContainer OPTIONAL }
+
+T-BCSM-CAMEL-TDP-Criteria ::= SEQUENCE {
+ t-BCSM-TriggerDetectionPoint T-BcsmTriggerDetectionPoint,
+ basicServiceCriteria [0] BasicServiceCriteria OPTIONAL,
+ t-CauseValueCriteria [1] T-CauseValueCriteria OPTIONAL,
+ ... }
+
+DestinationNumberCriteria ::= SEQUENCE {
+ matchType [0] MatchType,
+ destinationNumberList [1] DestinationNumberList OPTIONAL,
+ destinationNumberLengthList [2] DestinationNumberLengthList OPTIONAL,
+ -- one or both of destinationNumberList and destinationNumberLengthList
+ -- shall be present
+ ...}
+
+DestinationNumberList ::= SEQUENCE SIZE (1..maxNumOfCamelDestinationNumbers) OF
+ ISDN-AddressString
+ -- The receiving entity shall not check the format of a number in
+ -- the dialled number list
+
+DestinationNumberLengthList ::= SEQUENCE SIZE (1..maxNumOfCamelDestinationNumberLengths) OF
+ INTEGER(1..maxNumOfISDN-AddressDigits)
+
+BasicServiceCriteria ::= SEQUENCE SIZE(1..maxNumOfCamelBasicServiceCriteria) OF
+ Ext-BasicServiceCode
+
+maxNumOfISDN-AddressDigits INTEGER ::= 15
+
+maxNumOfCamelDestinationNumbers INTEGER ::= 10
+
+maxNumOfCamelDestinationNumberLengths INTEGER ::= 3
+
+maxNumOfCamelBasicServiceCriteria INTEGER ::= 5
+
+CallTypeCriteria ::= ENUMERATED {
+ forwarded (0),
+ notForwarded (1)}
+
+MatchType ::= ENUMERATED {
+ inhibiting (0),
+ enabling (1)}
+
+O-CauseValueCriteria ::= SEQUENCE SIZE(1..maxNumOfCAMEL-O-CauseValueCriteria) OF
+ CauseValue
+
+T-CauseValueCriteria ::= SEQUENCE SIZE(1..maxNumOfCAMEL-T-CauseValueCriteria) OF
+ CauseValue
+
+maxNumOfCAMEL-O-CauseValueCriteria INTEGER ::= 5
+
+maxNumOfCAMEL-T-CauseValueCriteria INTEGER ::= 5
+
+CauseValue ::= OCTET STRING (SIZE(1))
+-- Type extracted from Cause parameter in ITU-T Recommendation Q.763.
+-- For the use of cause value refer to ITU-T Recommendation Q.850.
+
+DefaultCallHandling ::= ENUMERATED {
+ continueCall (0) ,
+ releaseCall (1) ,
+ ...}
+ -- exception handling:
+ -- reception of values in range 2-31 shall be treated as "continueCall"
+ -- reception of values greater than 31 shall be treated as "releaseCall"
+
+CamelCapabilityHandling ::= INTEGER(1..16)
+ -- value 1 = CAMEL phase 1,
+ -- value 2 = CAMEL phase 2,
+ -- value 3 = CAMEL Phase 3,
+ -- value 4 = CAMEL phase 4:
+ -- reception of values greater than 4 shall be treated as CAMEL phase 4.
+
+SupportedCamelPhases ::= BIT STRING {
+ phase1 (0),
+ phase2 (1),
+ phase3 (2),
+ phase4 (3)} (SIZE (1..16))
+-- A node shall mark in the BIT STRING all CAMEL Phases it supports.
+-- Other values than listed above shall be discarded.
+
+OfferedCamel4CSIs ::= BIT STRING {
+ o-csi (0),
+ d-csi (1),
+ vt-csi (2),
+ t-csi (3),
+ mt-sms-csi (4),
+ mg-csi (5),
+ psi-enhancements (6)
+} (SIZE (7..16))
+-- A node supporting Camel phase 4 shall mark in the BIT STRING all Camel4 CSIs
+-- it offers.
+-- Other values than listed above shall be discarded.
+
+OfferedCamel4Functionalities ::= BIT STRING {
+ initiateCallAttempt (0),
+ splitLeg (1),
+ moveLeg (2),
+ disconnectLeg (3),
+ entityReleased (4),
+ dfc-WithArgument (5),
+ playTone (6),
+ dtmf-MidCall (7),
+ chargingIndicator (8),
+ alertingDP (9),
+ locationAtAlerting (10),
+ changeOfPositionDP (11),
+ or-Interactions (12),
+ warningToneEnhancements (13),
+ cf-Enhancements (14),
+ subscribedEnhancedDialledServices (15),
+ servingNetworkEnhancedDialledServices (16),
+ criteriaForChangeOfPositionDP (17),
+ serviceChangeDP (18)
+} (SIZE (15..64))
+-- A node supporting Camel phase 4 shall mark in the BIT STRING all CAMEL4
+-- functionalities it offers.
+-- Other values than listed above shall be discarded.
+
+SMS-CSI ::= SEQUENCE {
+ sms-CAMEL-TDP-DataList [0] SMS-CAMEL-TDP-DataList OPTIONAL,
+ camelCapabilityHandling [1] CamelCapabilityHandling OPTIONAL,
+ extensionContainer [2] ExtensionContainer OPTIONAL,
+ notificationToCSE [3] NULL OPTIONAL,
+ csi-Active [4] NULL OPTIONAL,
+ ...}
+-- notificationToCSE and csi-Active shall not be present
+-- when MO-SMS-CSI or MT-SMS-CSI is sent to VLR or SGSN.
+-- They may only be included in ATSI/ATM ack/NSDC message.
+-- SMS-CAMEL-TDP-Data and camelCapabilityHandling shall be present in
+-- the SMS-CSI sequence.
+-- If SMS-CSI is segmented, sms-CAMEL-TDP-DataList and camelCapabilityHandling shall be
+-- present in the first segment
+
+SMS-CAMEL-TDP-DataList ::= SEQUENCE SIZE (1..maxNumOfCamelTDPData) OF
+ SMS-CAMEL-TDP-Data
+-- SMS-CAMEL-TDP-DataList shall not contain more than one instance of
+-- SMS-CAMEL-TDP-Data containing the same value for sms-TriggerDetectionPoint.
+
+SMS-CAMEL-TDP-Data ::= SEQUENCE {
+ sms-TriggerDetectionPoint [0] SMS-TriggerDetectionPoint,
+ serviceKey [1] ServiceKey,
+ gsmSCF-Address [2] ISDN-AddressString,
+ defaultSMS-Handling [3] DefaultSMS-Handling,
+ extensionContainer [4] ExtensionContainer OPTIONAL,
+ ...
+ }
+
+SMS-TriggerDetectionPoint ::= ENUMERATED {
+ sms-CollectedInfo (1),
+ ...,
+ sms-DeliveryRequest (2)
+ }
+-- exception handling:
+-- For SMS-CAMEL-TDP-Data and MT-smsCAMELTDP-Criteria sequences containing this
+-- parameter with any other value than the ones listed the receiver shall ignore
+-- the whole sequence.
+--
+-- If this parameter is received with any other value than sms-CollectedInfo
+-- in an SMS-CAMEL-TDP-Data sequence contained in mo-sms-CSI, then the receiver shall
+-- ignore the whole SMS-CAMEL-TDP-Data sequence.
+--
+-- If this parameter is received with any other value than sms-DeliveryRequest
+-- in an SMS-CAMEL-TDP-Data sequence contained in mt-sms-CSI then the receiver shall
+-- ignore the whole SMS-CAMEL-TDP-Data sequence.
+--
+-- If this parameter is received with any other value than sms-DeliveryRequest
+-- in an MT-smsCAMELTDP-Criteria sequence then the receiver shall
+-- ignore the whole MT-smsCAMELTDP-Criteria sequence.
+
+DefaultSMS-Handling ::= ENUMERATED {
+ continueTransaction (0) ,
+ releaseTransaction (1) ,
+ ...}
+-- exception handling:
+-- reception of values in range 2-31 shall be treated as "continueTransaction"
+-- reception of values greater than 31 shall be treated as "releaseTransaction"
+
+M-CSI ::= SEQUENCE {
+ mobilityTriggers MobilityTriggers,
+ serviceKey ServiceKey,
+ gsmSCF-Address [0] ISDN-AddressString,
+ extensionContainer [1] ExtensionContainer OPTIONAL,
+ notificationToCSE [2] NULL OPTIONAL,
+ csi-Active [3] NULL OPTIONAL,
+ ...}
+-- notificationToCSE and csi-Active shall not be present when M-CSI is sent to VLR.
+-- They may only be included in ATSI/ATM ack/NSDC message.
+
+MG-CSI ::= SEQUENCE {
+ mobilityTriggers MobilityTriggers,
+ serviceKey ServiceKey,
+ gsmSCF-Address [0] ISDN-AddressString,
+ extensionContainer [1] ExtensionContainer OPTIONAL,
+ notificationToCSE [2] NULL OPTIONAL,
+ csi-Active [3] NULL OPTIONAL,
+ ...}
+-- notificationToCSE and csi-Active shall not be present when MG-CSI is sent to SGSN.
+-- They may only be included in ATSI/ATM ack/NSDC message.
+
+MobilityTriggers ::= SEQUENCE SIZE (1..maxNumOfMobilityTriggers) OF
+ MM-Code
+
+maxNumOfMobilityTriggers INTEGER ::= 10
+
+MM-Code ::= OCTET STRING (SIZE (1))
+-- This type is used to indicate a Mobility Management event.
+-- Actions for the following MM-Code values are defined in CAMEL Phase 4:
+--
+-- CS domain MM events:
+-- Location-update-in-same-VLR MM-Code ::= '00000000'B
+-- Location-update-to-other-VLR MM-Code ::= '00000001'B
+-- IMSI-Attach MM-Code ::= '00000010'B
+-- MS-initiated-IMSI-Detach MM-Code ::= '00000011'B
+-- Network-initiated-IMSI-Detach MM-Code ::= '00000100'B
+--
+-- PS domain MM events:
+-- Routeing-Area-update-in-same-SGSN MM-Code ::= '10000000'B
+-- Routeing-Area-update-to-other-SGSN-update-from-new-SGSN
+-- MM-Code ::= '10000001'B
+-- Routeing-Area-update-to-other-SGSN-disconnect-by-detach
+-- MM-Code ::= '10000010'B
+-- GPRS-Attach MM-Code ::= '10000011'B
+-- MS-initiated-GPRS-Detach MM-Code ::= '10000100'B
+-- Network-initiated-GPRS-Detach MM-Code ::= '10000101'B
+-- Network-initiated-transfer-to-MS-not-reachable-for-paging
+-- MM-Code ::= '10000110'B
+--
+-- If the MSC receives any other MM-code than the ones listed above for the
+-- CS domain, then the MSC shall ignore that MM-code.
+-- If the SGSN receives any other MM-code than the ones listed above for the
+-- PS domain, then the SGSN shall ignore that MM-code.
+
+T-CSI ::= SEQUENCE {
+ t-BcsmCamelTDPDataList T-BcsmCamelTDPDataList,
+ extensionContainer ExtensionContainer OPTIONAL,
+ ...,
+ camelCapabilityHandling [0] CamelCapabilityHandling OPTIONAL,
+ notificationToCSE [1] NULL OPTIONAL,
+ csi-Active [2] NULL OPTIONAL}
+-- notificationToCSE and csi-Active shall not be present when VT-CSI/T-CSI is sent
+-- to VLR/GMSC.
+-- They may only be included in ATSI/ATM ack/NSDC message.
+-- T-CSI shall not be segmented.
+
+T-BcsmCamelTDPDataList ::= SEQUENCE SIZE (1..maxNumOfCamelTDPData) OF
+ T-BcsmCamelTDPData
+ --- T-BcsmCamelTDPDataList shall not contain more than one instance of
+ --- T-BcsmCamelTDPData containing the same value for t-BcsmTriggerDetectionPoint.
+ --- For CAMEL Phase 2, this means that only one instance of T-BcsmCamelTDPData is allowed
+ --- with t-BcsmTriggerDetectionPoint being equal to DP12.
+ --- For CAMEL Phase 3, more TDP's are allowed.
+
+T-BcsmCamelTDPData ::= SEQUENCE {
+ t-BcsmTriggerDetectionPoint T-BcsmTriggerDetectionPoint,
+ serviceKey ServiceKey,
+ gsmSCF-Address [0] ISDN-AddressString,
+ defaultCallHandling [1] DefaultCallHandling,
+ extensionContainer [2] ExtensionContainer OPTIONAL,
+ ...}
+
+T-BcsmTriggerDetectionPoint ::= ENUMERATED {
+ termAttemptAuthorized (12),
+ ... ,
+ tBusy (13),
+ tNoAnswer (14)}
+ -- exception handling:
+ -- For T-BcsmCamelTDPData sequences containing this parameter with any other
+ -- value than the ones listed above, the receiver shall ignore the whole
+ -- T-BcsmCamelTDPData sequence.
+
+-- gprs location information retrieval types
+
+SendRoutingInfoForGprsArg ::= SEQUENCE {
+ imsi [0] IMSI,
+ ggsn-Address [1] GSN-Address OPTIONAL,
+ ggsn-Number [2] ISDN-AddressString,
+ extensionContainer [3] ExtensionContainer OPTIONAL,
+ ...}
+
+SendRoutingInfoForGprsRes ::= SEQUENCE {
+ sgsn-Address [0] GSN-Address,
+ ggsn-Address [1] GSN-Address OPTIONAL,
+ mobileNotReachableReason [2] AbsentSubscriberDiagnosticSM OPTIONAL,
+ extensionContainer [3] ExtensionContainer OPTIONAL,
+ ...}
+
+-- failure report types
+
+FailureReportArg ::= SEQUENCE {
+ imsi [0] IMSI,
+ ggsn-Number [1] ISDN-AddressString ,
+ ggsn-Address [2] GSN-Address OPTIONAL,
+ extensionContainer [3] ExtensionContainer OPTIONAL,
+ ...}
+
+FailureReportRes ::= SEQUENCE {
+ ggsn-Address [0] GSN-Address OPTIONAL,
+ extensionContainer [1] ExtensionContainer OPTIONAL,
+ ...}
+
+-- gprs notification types
+
+NoteMsPresentForGprsArg ::= SEQUENCE {
+ imsi [0] IMSI,
+ sgsn-Address [1] GSN-Address,
+ ggsn-Address [2] GSN-Address OPTIONAL,
+ extensionContainer [3] ExtensionContainer OPTIONAL,
+ ...}
+
+NoteMsPresentForGprsRes ::= SEQUENCE {
+ extensionContainer [0] ExtensionContainer OPTIONAL,
+ ...}
+
+-- fault recovery types
+
+ResetArg ::= SEQUENCE {
+ hlr-Number ISDN-AddressString,
+ hlr-List HLR-List OPTIONAL,
+ ...}
+
+RestoreDataArg ::= SEQUENCE {
+ imsi IMSI,
+ lmsi LMSI OPTIONAL,
+ extensionContainer ExtensionContainer OPTIONAL,
+ ... ,
+ vlr-Capability [6] VLR-Capability OPTIONAL }
+
+RestoreDataRes ::= SEQUENCE {
+ hlr-Number ISDN-AddressString,
+ msNotReachable NULL OPTIONAL,
+ extensionContainer ExtensionContainer OPTIONAL,
+ ...}
+
+-- VBS/VGCS types
+VBSDataList ::= SEQUENCE SIZE (1..maxNumOfVBSGroupIds) OF
+ VoiceBroadcastData
+
+VGCSDataList ::= SEQUENCE SIZE (1..maxNumOfVGCSGroupIds) OF
+ VoiceGroupCallData
+
+maxNumOfVBSGroupIds INTEGER ::= 50
+
+maxNumOfVGCSGroupIds INTEGER ::= 50
+
+VoiceGroupCallData ::= SEQUENCE {
+ groupId GroupId,
+ extensionContainer ExtensionContainer OPTIONAL,
+ ...}
+
+VoiceBroadcastData ::= SEQUENCE {
+ groupid GroupId,
+ broadcastInitEntitlement NULL OPTIONAL,
+ extensionContainer ExtensionContainer OPTIONAL,
+ ...}
+
+GroupId ::= TBCD-STRING (SIZE (3))
+ -- When Group-Id is less than six characters in length, the TBCD filler (1111)
+ -- is used to fill unused half octets.
+ -- Refers to the Group Identification as specified in 3GPP TS 23.003
+ -- and 3GPP TS 43.068/ 43.069
+
+-- provide subscriber info types
+
+ProvideSubscriberInfoArg ::= SEQUENCE {
+ imsi [0] IMSI,
+ lmsi [1] LMSI OPTIONAL,
+ requestedInfo [2] RequestedInfo,
+ extensionContainer [3] ExtensionContainer OPTIONAL,
+ ...}
+
+ProvideSubscriberInfoRes ::= SEQUENCE {
+ subscriberInfo SubscriberInfo,
+ extensionContainer ExtensionContainer OPTIONAL,
+ ...}
+
+SubscriberInfo ::= SEQUENCE {
+ locationInformation [0] LocationInformation OPTIONAL,
+ subscriberState [1] SubscriberState OPTIONAL,
+ extensionContainer [2] ExtensionContainer OPTIONAL,
+ ... ,
+ locationInformationGPRS [3] LocationInformationGPRS OPTIONAL,
+ ps-SubscriberState [4] PS-SubscriberState OPTIONAL,
+ imei [5] IMEI OPTIONAL,
+ ms-Classmark2 [6] MS-Classmark2 OPTIONAL,
+ gprs-MS-Class [7] GPRSMSClass OPTIONAL,
+ mnpInfoRes [8] MNPInfoRes OPTIONAL }
+
+-- If the HLR receives locationInformation, subscriberState or ms-Classmark2 from an SGSN
+-- it shall discard them.
+-- If the HLR receives locationInformationGPRS, ps-SubscriberState or gprs-MS-Class from
+-- a VLR it shall discard them.
+-- If the HLR receives parameters which it has not requested, it shall discard them.
+
+MNPInfoRes ::= SEQUENCE {
+ routeingNumber [0] RouteingNumber OPTIONAL,
+ imsi [1] IMSI OPTIONAL,
+ msisdn [2] ISDN-AddressString OPTIONAL,
+ numberPortabilityStatus [3] NumberPortabilityStatus OPTIONAL,
+ extensionContainer [4] ExtensionContainer OPTIONAL,
+ ... }
+-- The IMSI parameter contains a generic IMSI, i.e. it is not tied necessarily to the
+-- Subscriber. MCC and MNC values in this IMSI shall point to the Subscription Network of
+-- the Subscriber. See 3GPP TS 23.066 [108].
+
+RouteingNumber ::= TBCD-STRING (SIZE (1..5))
+
+
+NumberPortabilityStatus ::= ENUMERATED {
+ notKnownToBePorted (0),
+ ownNumberPortedOut (1),
+ foreignNumberPortedToForeignNetwork (2),
+ ...,
+ ownNumberNotPortedOut (4),
+ foreignNumberPortedIn (5)
+ }
+ -- exception handling:
+ -- reception of other values than the ones listed the receiver shall ignore the
+ -- whole NumberPortabilityStatus;
+ -- ownNumberNotPortedOut or foreignNumberPortedIn may only be included in Any Time
+ -- Interrogation message.
+
+MS-Classmark2 ::= OCTET STRING (SIZE (3))
+ -- This parameter carries the value part of the MS Classmark 2 IE defined in
+ -- 3GPP TS 24.008 [35].
+
+GPRSMSClass ::= SEQUENCE {
+ mSNetworkCapability [0] MSNetworkCapability,
+ mSRadioAccessCapability [1] MSRadioAccessCapability OPTIONAL
+ }
+
+MSNetworkCapability ::= OCTET STRING (SIZE (1..8))
+ -- This parameter carries the value part of the MS Network Capability IE defined in
+ -- 3GPP TS 24.008 [35].
+
+MSRadioAccessCapability ::= OCTET STRING (SIZE (1..50))
+ -- This parameter carries the value part of the MS Radio Access Capability IE defined in
+ -- 3GPP TS 24.008 [35].
+
+RequestedInfo ::= SEQUENCE {
+ locationInformation [0] NULL OPTIONAL,
+ subscriberState [1] NULL OPTIONAL,
+ extensionContainer [2] ExtensionContainer OPTIONAL,
+ ...,
+ currentLocation [3] NULL OPTIONAL,
+ requestedDomain [4] DomainType OPTIONAL,
+ imei [6] NULL OPTIONAL,
+ ms-classmark [5] NULL OPTIONAL,
+ mnpRequestedInfo [7] NULL OPTIONAL }
+
+-- currentLocation shall be absent if locationInformation is absent
+
+DomainType ::= ENUMERATED {
+ cs-Domain (0),
+ ps-Domain (1),
+ ...}
+-- exception handling:
+-- reception of values > 1 shall be mapped to 'cs-Domain'
+
+LocationInformation ::= SEQUENCE {
+ ageOfLocationInformation AgeOfLocationInformation OPTIONAL,
+ geographicalInformation [0] GeographicalInformation OPTIONAL,
+ vlr-number [1] ISDN-AddressString OPTIONAL,
+ locationNumber [2] LocationNumber OPTIONAL,
+ cellGlobalIdOrServiceAreaIdOrLAI [3] CellGlobalIdOrServiceAreaIdOrLAI OPTIONAL,
+ extensionContainer [4] ExtensionContainer OPTIONAL,
+ ... ,
+ selectedLSA-Id [5] LSAIdentity OPTIONAL,
+ msc-Number [6] ISDN-AddressString OPTIONAL,
+ geodeticInformation [7] GeodeticInformation OPTIONAL,
+ currentLocationRetrieved [8] NULL OPTIONAL,
+ sai-Present [9] NULL OPTIONAL }
+-- sai-Present indicates that the cellGlobalIdOrServiceAreaIdOrLAI parameter contains
+-- a Service Area Identity.
+-- currentLocationRetrieved shall be present
+-- if the location information were retrieved after a successfull paging.
+
+LocationInformationGPRS ::= SEQUENCE {
+ cellGlobalIdOrServiceAreaIdOrLAI [0] CellGlobalIdOrServiceAreaIdOrLAI OPTIONAL,
+ routeingAreaIdentity [1] RAIdentity OPTIONAL,
+ geographicalInformation [2] GeographicalInformation OPTIONAL,
+ sgsn-Number [3] ISDN-AddressString OPTIONAL,
+ selectedLSAIdentity [4] LSAIdentity OPTIONAL,
+ extensionContainer [5] ExtensionContainer OPTIONAL,
+ ...,
+ sai-Present [6] NULL OPTIONAL,
+ geodeticInformation [7] GeodeticInformation OPTIONAL,
+ currentLocationRetrieved [8] NULL OPTIONAL,
+ ageOfLocationInformation [9] AgeOfLocationInformation OPTIONAL }
+-- sai-Present indicates that the cellGlobalIdOrServiceAreaIdOrLAI parameter contains
+-- a Service Area Identity.
+-- currentLocationRetrieved shall be present if the location information
+-- was retrieved after successful paging.
+
+RAIdentity ::= OCTET STRING (SIZE (6))
+-- Routing Area Identity is coded in accordance with 3GPP TS 29.060 [105].
+-- It shall contain the value part defined in 3GPP TS 29.060 only. I.e. the 3GPP TS 29.060
+-- type identifier octet shall not be included.
+
+
+GeographicalInformation ::= OCTET STRING (SIZE (8))
+-- Refers to geographical Information defined in 3GPP TS 23.032.
+-- Only the description of an ellipsoid point with uncertainty circle
+-- as specified in 3GPP TS 23.032 is allowed to be used
+-- The internal structure according to 3GPP TS 23.032 is as follows:
+-- Type of shape (ellipsoid point with uncertainty circle) 1 octet
+-- Degrees of Latitude 3 octets
+-- Degrees of Longitude 3 octets
+-- Uncertainty code 1 octet
+
+GeodeticInformation ::= OCTET STRING (SIZE (10))
+-- Refers to Calling Geodetic Location defined in Q.763 (1999).
+-- Only the description of an ellipsoid point with uncertainty circle
+-- as specified in Q.763 (1999) is allowed to be used
+-- The internal structure according to Q.763 (1999) is as follows:
+-- Screening and presentation indicators 1 octet
+-- Type of shape (ellipsoid point with uncertainty circle) 1 octet
+-- Degrees of Latitude 3 octets
+-- Degrees of Longitude 3 octets
+-- Uncertainty code 1 octet
+-- Confidence 1 octet
+
+LocationNumber ::= OCTET STRING (SIZE (2..10))
+ -- the internal structure is defined in ITU-T Rec Q.763
+
+SubscriberState ::= CHOICE {
+ assumedIdle [0] NULL,
+ camelBusy [1] NULL,
+ netDetNotReachable NotReachableReason,
+ notProvidedFromVLR [2] NULL}
+
+PS-SubscriberState ::= CHOICE {
+ notProvidedFromSGSN [0] NULL,
+ ps-Detached [1] NULL,
+ ps-AttachedNotReachableForPaging [2] NULL,
+ ps-AttachedReachableForPaging [3] NULL,
+ ps-PDP-ActiveNotReachableForPaging [4] PDP-ContextInfoList,
+ ps-PDP-ActiveReachableForPaging [5] PDP-ContextInfoList,
+ netDetNotReachable NotReachableReason }
+
+PDP-ContextInfoList ::= SEQUENCE SIZE (1..maxNumOfPDP-Contexts) OF
+ PDP-ContextInfo
+
+PDP-ContextInfo ::= SEQUENCE {
+ pdp-ContextIdentifier [0] ContextId,
+ pdp-ContextActive [1] NULL OPTIONAL,
+ pdp-Type [2] PDP-Type,
+ pdp-Address [3] PDP-Address OPTIONAL,
+ apn-Subscribed [4] APN OPTIONAL,
+ apn-InUse [5] APN OPTIONAL,
+ nsapi [6] NSAPI OPTIONAL,
+ transactionId [7] TransactionId OPTIONAL,
+ teid-ForGnAndGp [8] TEID OPTIONAL,
+ teid-ForIu [9] TEID OPTIONAL,
+ ggsn-Address [10] GSN-Address OPTIONAL,
+ qos-Subscribed [11] Ext-QoS-Subscribed OPTIONAL,
+ qos-Requested [12] Ext-QoS-Subscribed OPTIONAL,
+ qos-Negotiated [13] Ext-QoS-Subscribed OPTIONAL,
+ chargingId [14] GPRSChargingID OPTIONAL,
+ chargingCharacteristics [15] ChargingCharacteristics OPTIONAL,
+ rnc-Address [16] GSN-Address OPTIONAL,
+ extensionContainer [17] ExtensionContainer OPTIONAL,
+ ...,
+ qos2-Subscribed [18] Ext2-QoS-Subscribed OPTIONAL,
+ -- qos2-Subscribed may be present only if qos-Subscribed is present.
+ qos2-Requested [19] Ext2-QoS-Subscribed OPTIONAL,
+ -- qos2-Requested may be present only if qos-Requested is present.
+ qos2-Negotiated [20] Ext2-QoS-Subscribed OPTIONAL
+ -- qos2-Negotiated may be present only if qos-Negotiated is present.
+ }
+
+NSAPI ::= INTEGER (0..15)
+-- This type is used to indicate the Network layer Service Access Point
+
+TransactionId ::= OCTET STRING (SIZE (1..2))
+-- This type carries the value part of the transaction identifier which is used in the
+-- session management messages on the access interface. The encoding is defined in
+-- 3GPP TS 24.008
+
+TEID ::= OCTET STRING (SIZE (4))
+-- This type carries the value part of the Tunnel Endpoint Identifier which is used to
+-- distinguish between different tunnels between the same pair of entities which communicate
+-- using the GPRS Tunnelling Protocol The encoding is defined in 3GPP TS 29.060.
+
+GPRSChargingID ::= OCTET STRING (SIZE (4))
+-- The Charging ID is a unique four octet value generated by the GGSN when
+-- a PDP Context is activated. A Charging ID is generated for each activated context.
+-- The encoding is defined in 3GPP TS 29.060.
+
+NotReachableReason ::= ENUMERATED {
+ msPurged (0),
+ imsiDetached (1),
+ restrictedArea (2),
+ notRegistered (3)}
+
+-- any time interrogation info types
+
+AnyTimeInterrogationArg ::= SEQUENCE {
+ subscriberIdentity [0] SubscriberIdentity,
+ requestedInfo [1] RequestedInfo,
+ gsmSCF-Address [3] ISDN-AddressString,
+ extensionContainer [2] ExtensionContainer OPTIONAL,
+ ...}
+
+AnyTimeInterrogationRes ::= SEQUENCE {
+ subscriberInfo SubscriberInfo,
+ extensionContainer ExtensionContainer OPTIONAL,
+ ...}
+
+-- any time information handling types
+
+AnyTimeSubscriptionInterrogationArg ::= SEQUENCE {
+ subscriberIdentity [0] SubscriberIdentity,
+ requestedSubscriptionInfo [1] RequestedSubscriptionInfo,
+ gsmSCF-Address [2] ISDN-AddressString,
+ extensionContainer [3] ExtensionContainer OPTIONAL,
+ longFTN-Supported [4] NULL OPTIONAL,
+ ...}
+
+AnyTimeSubscriptionInterrogationRes ::= SEQUENCE {
+ callForwardingData [1] CallForwardingData OPTIONAL,
+ callBarringData [2] CallBarringData OPTIONAL,
+ odb-Info [3] ODB-Info OPTIONAL,
+ camel-SubscriptionInfo [4] CAMEL-SubscriptionInfo OPTIONAL,
+ supportedVLR-CAMEL-Phases [5] SupportedCamelPhases OPTIONAL,
+ supportedSGSN-CAMEL-Phases [6] SupportedCamelPhases OPTIONAL,
+ extensionContainer [7] ExtensionContainer OPTIONAL,
+ ... ,
+ offeredCamel4CSIsInVLR [8] OfferedCamel4CSIs OPTIONAL,
+ offeredCamel4CSIsInSGSN [9] OfferedCamel4CSIs OPTIONAL }
+
+RequestedSubscriptionInfo ::= SEQUENCE {
+ requestedSS-Info [1] SS-ForBS-Code OPTIONAL,
+ odb [2] NULL OPTIONAL,
+ requestedCAMEL-SubscriptionInfo [3] RequestedCAMEL-SubscriptionInfo OPTIONAL,
+ supportedVLR-CAMEL-Phases [4] NULL OPTIONAL,
+ supportedSGSN-CAMEL-Phases [5] NULL OPTIONAL,
+ extensionContainer [6] ExtensionContainer OPTIONAL,
+ ...,
+ additionalRequestedCAMEL-SubscriptionInfo
+ [7] AdditionalRequestedCAMEL-SubscriptionInfo
+ OPTIONAL }
+
+RequestedCAMEL-SubscriptionInfo ::= ENUMERATED {
+ o-CSI (0),
+ t-CSI (1),
+ vt-CSI (2),
+ tif-CSI (3),
+ gprs-CSI (4),
+ mo-sms-CSI (5),
+ ss-CSI (6),
+ m-CSI (7),
+ d-csi (8)}
+
+AdditionalRequestedCAMEL-SubscriptionInfo ::= ENUMERATED {
+ mt-sms-CSI (0),
+ mg-csi (1),
+ o-IM-CSI (2),
+ d-IM-CSI (3),
+ vt-IM-CSI (4),
+ ...}
+-- exception handling: unknown values shall be discarded by the receiver.
+
+CallForwardingData ::= SEQUENCE {
+ forwardingFeatureList Ext-ForwFeatureList,
+ notificationToCSE NULL OPTIONAL,
+ extensionContainer [0] ExtensionContainer OPTIONAL,
+ ...}
+
+CallBarringData ::= SEQUENCE {
+ callBarringFeatureList Ext-CallBarFeatureList,
+ password Password OPTIONAL,
+ wrongPasswordAttemptsCounter WrongPasswordAttemptsCounter OPTIONAL,
+ notificationToCSE NULL OPTIONAL,
+ extensionContainer ExtensionContainer OPTIONAL,
+ ...}
+
+WrongPasswordAttemptsCounter ::= INTEGER (0..4)
+
+ODB-Info ::= SEQUENCE {
+ odb-Data ODB-Data,
+ notificationToCSE NULL OPTIONAL,
+ extensionContainer ExtensionContainer OPTIONAL,
+ ...}
+
+CAMEL-SubscriptionInfo ::= SEQUENCE {
+ o-CSI [0] O-CSI OPTIONAL,
+ o-BcsmCamelTDP-CriteriaList [1] O-BcsmCamelTDPCriteriaList OPTIONAL,
+ d-CSI [2] D-CSI OPTIONAL,
+ t-CSI [3] T-CSI OPTIONAL,
+ t-BCSM-CAMEL-TDP-CriteriaList [4] T-BCSM-CAMEL-TDP-CriteriaList OPTIONAL,
+ vt-CSI [5] T-CSI OPTIONAL,
+ vt-BCSM-CAMEL-TDP-CriteriaList [6] T-BCSM-CAMEL-TDP-CriteriaList OPTIONAL,
+ tif-CSI [7] NULL OPTIONAL,
+ tif-CSI-NotificationToCSE [8] NULL OPTIONAL,
+ gprs-CSI [9] GPRS-CSI OPTIONAL,
+ mo-sms-CSI [10] SMS-CSI OPTIONAL,
+ ss-CSI [11] SS-CSI OPTIONAL,
+ m-CSI [12] M-CSI OPTIONAL,
+ extensionContainer [13] ExtensionContainer OPTIONAL,
+ ...,
+ specificCSIDeletedList [14] SpecificCSI-Withdraw OPTIONAL,
+ mt-sms-CSI [15] SMS-CSI OPTIONAL,
+ mt-smsCAMELTDP-CriteriaList [16] MT-smsCAMELTDP-CriteriaList OPTIONAL,
+ mg-csi [17] MG-CSI OPTIONAL,
+ o-IM-CSI [18] O-CSI OPTIONAL,
+ o-IM-BcsmCamelTDP-CriteriaList [19] O-BcsmCamelTDPCriteriaList OPTIONAL,
+ d-IM-CSI [20] D-CSI OPTIONAL,
+ vt-IM-CSI [21] T-CSI OPTIONAL,
+ vt-IM-BCSM-CAMEL-TDP-CriteriaList [22] T-BCSM-CAMEL-TDP-CriteriaList OPTIONAL
+ }
+
+AnyTimeModificationArg ::= SEQUENCE {
+ subscriberIdentity [0] SubscriberIdentity,
+ gsmSCF-Address [1] ISDN-AddressString,
+ modificationRequestFor-CF-Info [2] ModificationRequestFor-CF-Info OPTIONAL,
+ modificationRequestFor-CB-Info [3] ModificationRequestFor-CB-Info OPTIONAL,
+ modificationRequestFor-CSI [4] ModificationRequestFor-CSI OPTIONAL,
+ extensionContainer [5] ExtensionContainer OPTIONAL,
+ longFTN-Supported [6] NULL OPTIONAL,
+ ...,
+ modificationRequestFor-ODB-data [7] ModificationRequestFor-ODB-data OPTIONAL }
+
+AnyTimeModificationRes ::= SEQUENCE {
+ ss-InfoFor-CSE [0] Ext-SS-InfoFor-CSE OPTIONAL,
+ camel-SubscriptionInfo [1] CAMEL-SubscriptionInfo OPTIONAL,
+ extensionContainer [2] ExtensionContainer OPTIONAL,
+ ...,
+ odb-Info [3] ODB-Info OPTIONAL }
+
+ModificationRequestFor-CF-Info ::= SEQUENCE {
+ ss-Code [0] SS-Code,
+ basicService [1] Ext-BasicServiceCode OPTIONAL,
+ ss-Status [2] Ext-SS-Status OPTIONAL,
+ forwardedToNumber [3] AddressString OPTIONAL,
+ forwardedToSubaddress [4] ISDN-SubaddressString OPTIONAL,
+ noReplyConditionTime [5] Ext-NoRepCondTime OPTIONAL,
+ modifyNotificationToCSE [6] ModificationInstruction OPTIONAL,
+ extensionContainer [7] ExtensionContainer OPTIONAL,
+ ...}
+
+ModificationRequestFor-CB-Info ::= SEQUENCE {
+ ss-Code [0] SS-Code,
+ basicService [1] Ext-BasicServiceCode OPTIONAL,
+ ss-Status [2] Ext-SS-Status OPTIONAL,
+ password [3] Password OPTIONAL,
+ wrongPasswordAttemptsCounter [4] WrongPasswordAttemptsCounter OPTIONAL,
+ modifyNotificationToCSE [5] ModificationInstruction OPTIONAL,
+ extensionContainer [6] ExtensionContainer OPTIONAL,
+ ...}
+
+ModificationRequestFor-ODB-data ::= SEQUENCE {
+ odb-data [0] ODB-Data OPTIONAL,
+ modifyNotificationToCSE [1] ModificationInstruction OPTIONAL,
+ extensionContainer [2] ExtensionContainer OPTIONAL,
+ ...}
+
+ModificationRequestFor-CSI ::= SEQUENCE {
+ requestedCamel-SubscriptionInfo [0] RequestedCAMEL-SubscriptionInfo,
+ modifyNotificationToCSE [1] ModificationInstruction OPTIONAL,
+ modifyCSI-State [2] ModificationInstruction OPTIONAL,
+ extensionContainer [3] ExtensionContainer OPTIONAL,
+ ...,
+ additionalRequestedCAMEL-SubscriptionInfo
+ [4] AdditionalRequestedCAMEL-SubscriptionInfo
+ OPTIONAL }
+-- requestedCamel-SubscriptionInfo shall be discarded if
+-- additionalRequestedCAMEL-SubscriptionInfo is received
+
+ModificationInstruction ::= ENUMERATED {
+ deactivate (0),
+ activate (1)}
+
+-- subscriber data modification notification types
+
+NoteSubscriberDataModifiedArg ::= SEQUENCE {
+ imsi IMSI,
+ msisdn ISDN-AddressString,
+ forwardingInfoFor-CSE [0] Ext-ForwardingInfoFor-CSE OPTIONAL,
+ callBarringInfoFor-CSE [1] Ext-CallBarringInfoFor-CSE OPTIONAL,
+ odb-Info [2] ODB-Info OPTIONAL,
+ camel-SubscriptionInfo [3] CAMEL-SubscriptionInfo OPTIONAL,
+ allInformationSent [4] NULL OPTIONAL,
+ extensionContainer ExtensionContainer OPTIONAL,
+ ...}
+
+NoteSubscriberDataModifiedRes ::= SEQUENCE {
+ extensionContainer ExtensionContainer OPTIONAL,
+ ...}
+
+-- mobility management event notificatioon info types
+
+NoteMM-EventArg::= SEQUENCE {
+ serviceKey ServiceKey,
+ eventMet [0] MM-Code,
+ imsi [1] IMSI,
+ msisdn [2] ISDN-AddressString,
+ locationInformation [3] LocationInformation OPTIONAL,
+ supportedCAMELPhases [5] SupportedCamelPhases OPTIONAL,
+ extensionContainer [6] ExtensionContainer OPTIONAL,
+ ...,
+ locationInformationGPRS [7] LocationInformationGPRS OPTIONAL,
+ offeredCamel4Functionalities [8] OfferedCamel4Functionalities OPTIONAL
+}
+
+NoteMM-EventRes ::= SEQUENCE {
+ extensionContainer ExtensionContainer OPTIONAL,
+ ...}
+
+Ext-SS-InfoFor-CSE ::= CHOICE {
+ forwardingInfoFor-CSE [0] Ext-ForwardingInfoFor-CSE,
+ callBarringInfoFor-CSE [1] Ext-CallBarringInfoFor-CSE
+ }
+
+Ext-ForwardingInfoFor-CSE ::= SEQUENCE {
+ ss-Code [0] SS-Code,
+ forwardingFeatureList [1] Ext-ForwFeatureList,
+ notificationToCSE [2] NULL OPTIONAL,
+ extensionContainer [3] ExtensionContainer OPTIONAL,
+ ...}
+
+Ext-CallBarringInfoFor-CSE ::= SEQUENCE {
+ ss-Code [0] SS-Code,
+ callBarringFeatureList [1] Ext-CallBarFeatureList,
+ password [2] Password OPTIONAL,
+ wrongPasswordAttemptsCounter [3] WrongPasswordAttemptsCounter OPTIONAL,
+ notificationToCSE [4] NULL OPTIONAL,
+ extensionContainer [5] ExtensionContainer OPTIONAL,
+ ...}
+
+END
diff --git a/lib/asn1/test/asn1_SUITE_data/tcapsystem/MAP-MobileServiceOperations.asn b/lib/asn1/test/asn1_SUITE_data/tcapsystem/MAP-MobileServiceOperations.asn
new file mode 100644
index 0000000000..b91eac7cdf
--- /dev/null
+++ b/lib/asn1/test/asn1_SUITE_data/tcapsystem/MAP-MobileServiceOperations.asn
@@ -0,0 +1,506 @@
+MAP-MobileServiceOperations {
+ itu-t identified-organization (4) etsi (0) mobileDomain (0)
+ gsm-Network (1) modules (3) map-MobileServiceOperations (5)
+ version9 (9)}
+
+DEFINITIONS
+
+::=
+
+BEGIN
+
+EXPORTS
+
+ -- location registration operations
+ updateLocation,
+ cancelLocation,
+ purgeMS,
+ sendIdentification,
+
+ -- gprs location registration operations
+ updateGprsLocation,
+
+ -- subscriber information enquiry operations
+ provideSubscriberInfo,
+
+ -- any time information enquiry operations
+ anyTimeInterrogation,
+
+ -- any time information handling operations
+ anyTimeSubscriptionInterrogation,
+ anyTimeModification,
+
+ -- subscriber data modification notification operations
+ noteSubscriberDataModified,
+
+
+ -- handover operations
+ prepareHandover,
+ sendEndSignal,
+ processAccessSignalling,
+ forwardAccessSignalling,
+ prepareSubsequentHandover,
+
+ -- authentication management operations
+ sendAuthenticationInfo,
+ authenticationFailureReport,
+
+ -- IMEI management operations
+ checkIMEI,
+
+ -- subscriber management operations
+ insertSubscriberData,
+ deleteSubscriberData,
+
+ -- fault recovery operations
+ reset,
+ forwardCheckSS-Indication,
+ restoreData,
+
+-- gprs location information retrieval operations
+ sendRoutingInfoForGprs,
+
+ -- failure reporting operations
+ failureReport,
+
+ -- gprs notification operations
+ noteMsPresentForGprs,
+
+-- Mobility Management operations
+ noteMM-Event
+;
+
+IMPORTS
+ OPERATION
+FROM Remote-Operations-Information-Objects {
+joint-iso-itu-t remote-operations(4)
+ informationObjects(5) version1(0)}
+
+ systemFailure,
+ dataMissing,
+ unexpectedDataValue,
+ unknownSubscriber,
+ unknownMSC,
+ unidentifiedSubscriber,
+ unknownEquipment,
+ roamingNotAllowed,
+ ati-NotAllowed,
+ noHandoverNumberAvailable,
+ subsequentHandoverFailure,
+ absentSubscriber,
+ mm-EventNotSupported,
+ atsi-NotAllowed,
+ atm-NotAllowed,
+ bearerServiceNotProvisioned,
+ teleserviceNotProvisioned,
+ callBarred,
+ illegalSS-Operation,
+ ss-ErrorStatus,
+ ss-NotAvailable,
+ ss-Incompatibility,
+ ss-SubscriptionViolation,
+ informationNotAvailable,
+ targetCellOutsideGroupCallArea
+
+
+FROM MAP-Errors {
+ itu-t identified-organization (4) etsi (0) mobileDomain (0)
+ gsm-Network (1) modules (3) map-Errors (10) version9 (9)}
+
+ UpdateLocationArg,
+ UpdateLocationRes,
+ CancelLocationArg,
+ CancelLocationRes,
+ PurgeMS-Arg,
+ PurgeMS-Res,
+ SendIdentificationArg,
+ SendIdentificationRes,
+ UpdateGprsLocationArg,
+ UpdateGprsLocationRes,
+ PrepareHO-Arg,
+ PrepareHO-Res,
+ForwardAccessSignalling-Arg,
+ProcessAccessSignalling-Arg,
+SendEndSignal-Arg,
+SendEndSignal-Res,
+PrepareSubsequentHO-Res,
+ PrepareSubsequentHO-Arg,
+ SendAuthenticationInfoArg,
+ SendAuthenticationInfoRes,
+ AuthenticationFailureReportArg,
+ AuthenticationFailureReportRes,
+ CheckIMEI-Arg,
+ CheckIMEI-Res,
+ InsertSubscriberDataArg,
+ InsertSubscriberDataRes,
+ DeleteSubscriberDataArg,
+ DeleteSubscriberDataRes,
+ ResetArg,
+ RestoreDataArg,
+ RestoreDataRes,
+ ProvideSubscriberInfoArg,
+ ProvideSubscriberInfoRes,
+ AnyTimeSubscriptionInterrogationArg,
+ AnyTimeSubscriptionInterrogationRes,
+ AnyTimeModificationArg,
+ AnyTimeModificationRes,
+ NoteSubscriberDataModifiedArg,
+ NoteSubscriberDataModifiedRes,
+ AnyTimeInterrogationArg,
+ AnyTimeInterrogationRes,
+ SendRoutingInfoForGprsArg,
+ SendRoutingInfoForGprsRes,
+ FailureReportArg,
+ FailureReportRes,
+ NoteMsPresentForGprsArg,
+ NoteMsPresentForGprsRes,
+ NoteMM-EventArg,
+ NoteMM-EventRes
+
+
+FROM MAP-MS-DataTypes {
+ itu-t identified-organization (4) etsi (0) mobileDomain (0)
+ gsm-Network (1) modules (3) map-MS-DataTypes (11) version9 (9)}
+
+;
+
+
+-- location registration operations
+
+updateLocation OPERATION ::= { --Timer m
+ ARGUMENT
+ UpdateLocationArg
+ RESULT
+ UpdateLocationRes
+ ERRORS {
+ systemFailure |
+ dataMissing |
+ unexpectedDataValue |
+ unknownSubscriber |
+ roamingNotAllowed}
+ CODE local:2 }
+
+cancelLocation OPERATION ::= { --Timer m
+ ARGUMENT
+ CancelLocationArg
+ RESULT
+ CancelLocationRes
+ -- optional
+ ERRORS {
+ dataMissing |
+ unexpectedDataValue}
+ CODE local:3 }
+
+purgeMS OPERATION ::= { --Timer m
+ ARGUMENT
+ PurgeMS-Arg
+ RESULT
+ PurgeMS-Res
+ -- optional
+ ERRORS{
+ dataMissing |
+ unexpectedDataValue|
+ unknownSubscriber}
+ CODE local:67 }
+
+sendIdentification OPERATION ::= { --Timer s
+ ARGUMENT
+ SendIdentificationArg
+ RESULT
+ SendIdentificationRes
+ ERRORS {
+ dataMissing |
+ unidentifiedSubscriber}
+ CODE local:55 }
+
+-- gprs location registration operations
+
+updateGprsLocation OPERATION ::= { --Timer m
+ ARGUMENT
+ UpdateGprsLocationArg
+ RESULT
+ UpdateGprsLocationRes
+ ERRORS {
+ systemFailure |
+ unexpectedDataValue |
+ unknownSubscriber |
+ roamingNotAllowed}
+ CODE local:23 }
+
+-- subscriber information enquiry operations
+
+provideSubscriberInfo OPERATION ::= { --Timer m
+ ARGUMENT
+ ProvideSubscriberInfoArg
+ RESULT
+ ProvideSubscriberInfoRes
+ ERRORS {
+ dataMissing |
+ unexpectedDataValue}
+ CODE local:70 }
+
+-- any time information enquiry operations
+
+anyTimeInterrogation OPERATION ::= { --Timer m
+ ARGUMENT
+ AnyTimeInterrogationArg
+ RESULT
+ AnyTimeInterrogationRes
+ ERRORS {
+ systemFailure |
+ ati-NotAllowed |
+ dataMissing |
+ unexpectedDataValue |
+ unknownSubscriber}
+ CODE local:71 }
+
+-- any time information handling operations
+
+anyTimeSubscriptionInterrogation OPERATION ::= { --Timer m
+ ARGUMENT
+ AnyTimeSubscriptionInterrogationArg
+ RESULT
+ AnyTimeSubscriptionInterrogationRes
+ ERRORS {
+ atsi-NotAllowed |
+ dataMissing |
+ unexpectedDataValue |
+ unknownSubscriber |
+ bearerServiceNotProvisioned |
+ teleserviceNotProvisioned |
+ callBarred |
+ illegalSS-Operation |
+ ss-NotAvailable |
+ informationNotAvailable}
+ CODE local:62 }
+
+anyTimeModification OPERATION ::= { --Timer m
+ ARGUMENT
+ AnyTimeModificationArg
+ RESULT
+ AnyTimeModificationRes
+ ERRORS {
+ atm-NotAllowed |
+ dataMissing |
+ unexpectedDataValue |
+ unknownSubscriber |
+ bearerServiceNotProvisioned |
+ teleserviceNotProvisioned |
+ callBarred |
+ illegalSS-Operation |
+ ss-SubscriptionViolation |
+ ss-ErrorStatus |
+ ss-Incompatibility |
+ informationNotAvailable}
+ CODE local:65 }
+
+-- subscriber data modification notification operations
+
+noteSubscriberDataModified OPERATION ::= { --Timer m
+ ARGUMENT
+ NoteSubscriberDataModifiedArg
+ RESULT
+ NoteSubscriberDataModifiedRes
+ -- optional
+ ERRORS {
+ dataMissing |
+ unexpectedDataValue |
+ unknownSubscriber}
+ CODE local:5 }
+
+-- handover operations
+
+prepareHandover OPERATION ::= { --Timer m
+ ARGUMENT
+ PrepareHO-Arg
+ RESULT
+ PrepareHO-Res
+ ERRORS {
+ systemFailure |
+ dataMissing |
+ unexpectedDataValue |
+ noHandoverNumberAvailable |
+ targetCellOutsideGroupCallArea }
+ CODE local:68 }
+
+sendEndSignal OPERATION ::= { --Timer l
+ ARGUMENT
+ SendEndSignal-Arg
+ RESULT
+ SendEndSignal-Res
+ CODE local:29 }
+
+processAccessSignalling OPERATION ::= { --Timer s
+ ARGUMENT
+ ProcessAccessSignalling-Arg
+ CODE local:33 }
+
+forwardAccessSignalling OPERATION ::= { --Timer s
+ ARGUMENT
+ ForwardAccessSignalling-Arg
+ CODE local:34 }
+
+prepareSubsequentHandover OPERATION ::= { --Timer m
+ ARGUMENT
+ PrepareSubsequentHO-Arg
+ RESULT
+ PrepareSubsequentHO-Res
+ ERRORS {
+ unexpectedDataValue |
+ dataMissing |
+ unknownMSC |
+ subsequentHandoverFailure}
+ CODE local:69 }
+
+-- authentication management operations
+
+sendAuthenticationInfo OPERATION ::= { --Timer m
+ ARGUMENT
+ SendAuthenticationInfoArg
+ -- optional
+ -- within a dialogue sendAuthenticationInfoArg shall not be present in
+ -- subsequent invoke components. If received in a subsequent invoke component
+ -- it shall be discarded.
+
+ RESULT
+ SendAuthenticationInfoRes
+ -- optional
+ ERRORS {
+ systemFailure |
+ dataMissing |
+ unexpectedDataValue |
+ unknownSubscriber}
+ CODE local:56 }
+
+authenticationFailureReport OPERATION ::= { --Timer m
+ ARGUMENT
+ AuthenticationFailureReportArg
+ RESULT
+ AuthenticationFailureReportRes
+ -- optional
+ ERRORS {
+ systemFailure |
+ unexpectedDataValue |
+ unknownSubscriber}
+ CODE local:15 }
+
+-- IMEI management operations
+
+checkIMEI OPERATION ::= { --Timer m
+ ARGUMENT
+ CheckIMEI-Arg
+ RESULT
+ CheckIMEI-Res
+ ERRORS {
+ systemFailure |
+ dataMissing |
+ unknownEquipment}
+ CODE local:43 }
+
+-- subscriber management operations
+
+insertSubscriberData OPERATION ::= { --Timer m
+ ARGUMENT
+ InsertSubscriberDataArg
+ RESULT
+ InsertSubscriberDataRes
+ -- optional
+ ERRORS {
+ dataMissing |
+ unexpectedDataValue |
+ unidentifiedSubscriber}
+ CODE local:7 }
+
+deleteSubscriberData OPERATION ::= { --Timer m
+ ARGUMENT
+ DeleteSubscriberDataArg
+ RESULT
+ DeleteSubscriberDataRes
+ -- optional
+ ERRORS {
+ dataMissing |
+ unexpectedDataValue |
+ unidentifiedSubscriber}
+ CODE local:8 }
+
+-- fault recovery operations
+
+reset OPERATION ::= { --Timer m
+ ARGUMENT
+ ResetArg
+ CODE local:37 }
+
+forwardCheckSS-Indication OPERATION ::= { --Timer s
+ CODE local:38 }
+
+restoreData OPERATION ::= { --Timer m
+ ARGUMENT
+ RestoreDataArg
+ RESULT
+ RestoreDataRes
+ ERRORS {
+ systemFailure |
+ dataMissing |
+ unexpectedDataValue |
+ unknownSubscriber}
+ CODE local:57 }
+
+-- gprs location information retrieval operations
+
+sendRoutingInfoForGprs OPERATION ::= { --Timer m
+ ARGUMENT
+ SendRoutingInfoForGprsArg
+ RESULT
+ SendRoutingInfoForGprsRes
+ ERRORS {
+ absentSubscriber |
+ systemFailure |
+ dataMissing |
+ unexpectedDataValue |
+ unknownSubscriber |
+ callBarred }
+ CODE local:24 }
+
+-- failure reporting operations
+
+failureReport OPERATION ::= { --Timer m
+ ARGUMENT
+ FailureReportArg
+ RESULT
+ FailureReportRes
+ -- optional
+ ERRORS {
+ systemFailure |
+ dataMissing |
+ unexpectedDataValue |
+ unknownSubscriber}
+ CODE local:25 }
+
+-- gprs notification operations
+
+noteMsPresentForGprs OPERATION ::= { --Timer m
+ ARGUMENT
+ NoteMsPresentForGprsArg
+ RESULT
+ NoteMsPresentForGprsRes
+ -- optional
+ ERRORS {
+ systemFailure |
+ dataMissing |
+ unexpectedDataValue |
+ unknownSubscriber}
+ CODE local:26 }
+
+noteMM-Event OPERATION ::= { --Timer m
+ ARGUMENT
+ NoteMM-EventArg
+ RESULT
+ NoteMM-EventRes
+ ERRORS {
+ dataMissing |
+ unexpectedDataValue |
+ unknownSubscriber |
+ mm-EventNotSupported}
+ CODE local:89 }
+
+END
diff --git a/lib/asn1/test/asn1_SUITE_data/tcapsystem/MAP-OM-DataTypes.asn b/lib/asn1/test/asn1_SUITE_data/tcapsystem/MAP-OM-DataTypes.asn
new file mode 100644
index 0000000000..3866b1e6e5
--- /dev/null
+++ b/lib/asn1/test/asn1_SUITE_data/tcapsystem/MAP-OM-DataTypes.asn
@@ -0,0 +1,62 @@
+MAP-OM-DataTypes {
+ itu-t identified-organization (4) etsi (0) mobileDomain (0)
+ gsm-Network (1) modules (3) map-OM-DataTypes (12) version9 (9)}
+
+DEFINITIONS
+
+IMPLICIT TAGS
+
+::=
+
+BEGIN
+
+EXPORTS
+ ActivateTraceModeArg,
+ ActivateTraceModeRes,
+ DeactivateTraceModeArg,
+ DeactivateTraceModeRes
+;
+
+IMPORTS
+ AddressString,
+ IMSI
+FROM MAP-CommonDataTypes {
+ itu-t identified-organization (4) etsi (0) mobileDomain (0)
+ gsm-Network (1) modules (3) map-CommonDataTypes (18) version9 (9)}
+
+ ExtensionContainer
+FROM MAP-ExtensionDataTypes {
+ itu-t identified-organization (4) etsi (0) mobileDomain (0)
+ gsm-Network (1) modules (3) map-ExtensionDataTypes (21) version9 (9)}
+
+;
+
+ActivateTraceModeArg ::= SEQUENCE {
+ imsi [0] IMSI OPTIONAL,
+ traceReference [1] TraceReference,
+ traceType [2] TraceType,
+ omc-Id [3] AddressString OPTIONAL,
+ extensionContainer [4] ExtensionContainer OPTIONAL,
+ ...}
+
+TraceReference ::= OCTET STRING (SIZE (1..2))
+
+TraceType ::= INTEGER
+ (0..255)
+ -- Trace types are fully defined in TS GSM 12.08.
+
+ActivateTraceModeRes ::= SEQUENCE {
+ extensionContainer [0] ExtensionContainer OPTIONAL,
+ ...}
+
+DeactivateTraceModeArg ::= SEQUENCE {
+ imsi [0] IMSI OPTIONAL,
+ traceReference [1] TraceReference,
+ extensionContainer [2] ExtensionContainer OPTIONAL,
+ ...}
+
+DeactivateTraceModeRes ::= SEQUENCE {
+ extensionContainer [0] ExtensionContainer OPTIONAL,
+ ...}
+
+END
diff --git a/lib/asn1/test/asn1_SUITE_data/tcapsystem/MAP-OperationAndMaintenanceOperations.asn b/lib/asn1/test/asn1_SUITE_data/tcapsystem/MAP-OperationAndMaintenanceOperations.asn
new file mode 100644
index 0000000000..adc50bd436
--- /dev/null
+++ b/lib/asn1/test/asn1_SUITE_data/tcapsystem/MAP-OperationAndMaintenanceOperations.asn
@@ -0,0 +1,91 @@
+MAP-OperationAndMaintenanceOperations {
+ itu-t identified-organization (4) etsi (0) mobileDomain (0)
+ gsm-Network (1) modules (3) map-OperationAndMaintenanceOperations (6)
+ version9 (9)}
+
+DEFINITIONS
+
+::=
+
+BEGIN
+
+EXPORTS
+ activateTraceMode,
+ deactivateTraceMode,
+ sendIMSI
+;
+
+IMPORTS
+ OPERATION
+FROM Remote-Operations-Information-Objects {
+joint-iso-itu-t remote-operations(4)
+ informationObjects(5) version1(0)}
+
+ systemFailure,
+ dataMissing,
+ unexpectedDataValue,
+ facilityNotSupported,
+ unknownSubscriber,
+ unidentifiedSubscriber,
+ tracingBufferFull
+FROM MAP-Errors {
+ itu-t identified-organization (4) etsi (0) mobileDomain (0)
+ gsm-Network (1) modules (3) map-Errors (10) version9 (9)}
+
+ ActivateTraceModeArg,
+ ActivateTraceModeRes,
+ DeactivateTraceModeArg,
+ DeactivateTraceModeRes
+FROM MAP-OM-DataTypes {
+ itu-t identified-organization (4) etsi (0) mobileDomain (0)
+ gsm-Network (1) modules (3) map-OM-DataTypes (12) version9 (9)}
+
+ ISDN-AddressString,
+ IMSI
+FROM MAP-CommonDataTypes {
+ itu-t identified-organization (4) etsi (0) mobileDomain (0)
+ gsm-Network (1) modules (3) map-CommonDataTypes (18) version9 (9)}
+;
+
+
+activateTraceMode OPERATION ::= { --Timer m
+ ARGUMENT
+ ActivateTraceModeArg
+ RESULT
+ ActivateTraceModeRes
+ -- optional
+ ERRORS {
+ systemFailure |
+ dataMissing |
+ unexpectedDataValue |
+ facilityNotSupported |
+ unidentifiedSubscriber |
+ tracingBufferFull}
+ CODE local:50 }
+
+deactivateTraceMode OPERATION ::= { --Timer m
+ ARGUMENT
+ DeactivateTraceModeArg
+ RESULT
+ DeactivateTraceModeRes
+ -- optional
+ ERRORS {
+ systemFailure |
+ dataMissing |
+ unexpectedDataValue |
+ facilityNotSupported |
+ unidentifiedSubscriber}
+ CODE local:51 }
+
+sendIMSI OPERATION ::= { --Timer m
+ ARGUMENT
+ ISDN-AddressString
+ RESULT
+ IMSI
+ ERRORS {
+ dataMissing |
+ unexpectedDataValue |
+ unknownSubscriber}
+ CODE local:58 }
+
+END
diff --git a/lib/asn1/test/asn1_SUITE_data/tcapsystem/MAP-Protocol.asn b/lib/asn1/test/asn1_SUITE_data/tcapsystem/MAP-Protocol.asn
new file mode 100644
index 0000000000..68dfb986c8
--- /dev/null
+++ b/lib/asn1/test/asn1_SUITE_data/tcapsystem/MAP-Protocol.asn
@@ -0,0 +1,176 @@
+MAP-Protocol {
+ itu-t identified-organization (4) etsi (0) mobileDomain (0)
+ gsm-Network (1) modules (3) map-Protocol (4) version9 (9)}
+
+DEFINITIONS
+
+::=
+
+BEGIN
+
+IMPORTS
+OPERATION
+FROM Remote-Operations-Information-Objects {
+joint-iso-itu-t remote-operations(4) informationObjects(5) version1(0)}
+
+ updateLocation,
+ cancelLocation,
+ purgeMS,
+ sendIdentification,
+ updateGprsLocation,
+ prepareHandover,
+ sendEndSignal,
+ processAccessSignalling,
+ forwardAccessSignalling,
+ prepareSubsequentHandover,
+ sendAuthenticationInfo,
+ authenticationFailureReport,
+ checkIMEI,
+ insertSubscriberData,
+ deleteSubscriberData,
+ reset,
+ forwardCheckSS-Indication,
+ restoreData,
+ provideSubscriberInfo,
+ anyTimeInterrogation,
+ anyTimeSubscriptionInterrogation,
+ anyTimeModification,
+ sendRoutingInfoForGprs,
+ failureReport,
+ noteMsPresentForGprs,
+ noteMM-Event,
+ noteSubscriberDataModified
+
+
+FROM MAP-MobileServiceOperations {
+ itu-t identified-organization (4) etsi (0) mobileDomain (0)
+ gsm-Network (1) modules (3) map-MobileServiceOperations (5)
+ version9 (9)}
+
+ activateTraceMode,
+ deactivateTraceMode,
+ sendIMSI
+FROM MAP-OperationAndMaintenanceOperations {
+ itu-t identified-organization (4) etsi (0) mobileDomain (0)
+ gsm-Network (1) modules (3) map-OperationAndMaintenanceOperations (6)
+ version9 (9)}
+
+ sendRoutingInfo,
+ provideRoamingNumber,
+ resumeCallHandling,
+ setReportingState,
+ statusReport,
+ remoteUserFree,
+ ist-Alert,
+ ist-Command
+FROM MAP-CallHandlingOperations {
+ itu-t identified-organization (4) etsi (0) mobileDomain (0)
+ gsm-Network (1) modules (3) map-CallHandlingOperations (7)
+ version9 (9)}
+
+ registerSS,
+ eraseSS,
+ activateSS,
+ deactivateSS,
+ interrogateSS,
+ processUnstructuredSS-Request,
+ unstructuredSS-Request,
+ unstructuredSS-Notify,
+ registerPassword,
+ getPassword,
+ ss-InvocationNotification,
+ registerCC-Entry,
+ eraseCC-Entry
+FROM MAP-SupplementaryServiceOperations {
+ itu-t identified-organization (4) etsi (0) mobileDomain (0)
+ gsm-Network (1) modules (3) map-SupplementaryServiceOperations (8)
+ version9 (9)}
+
+ sendRoutingInfoForSM,
+ mo-ForwardSM,
+ mt-ForwardSM,
+ reportSM-DeliveryStatus,
+ alertServiceCentre,
+ informServiceCentre,
+ readyForSM
+FROM MAP-ShortMessageServiceOperations {
+ itu-t identified-organization (4) etsi (0) mobileDomain (0)
+ gsm-Network (1) modules (3) map-ShortMessageServiceOperations (9)
+ version9 (9)}
+
+ prepareGroupCall,
+ processGroupCallSignalling,
+ forwardGroupCallSignalling,
+ sendGroupCallEndSignal
+FROM MAP-Group-Call-Operations {
+ itu-t identified-organization (4) etsi (0) mobileDomain (0)
+ gsm-Network (1) modules (3) map-Group-Call-Operations (22)
+ version9 (9)}
+
+ provideSubscriberLocation,
+ sendRoutingInfoForLCS,
+ subscriberLocationReport
+FROM MAP-LocationServiceOperations {
+ itu-t identified-organization (4) etsi (0) mobileDomain (0)
+ gsm-Network (1) modules (3) map-LocationServiceOperations (24)
+ version9 (9)}
+
+secureTransportClass1,
+secureTransportClass2,
+secureTransportClass3,
+secureTransportClass4
+
+FROM MAP-SecureTransportOperations {
+ itu-t identified-organization (4) etsi (0) mobileDomain (0)
+ gsm-Network (1) modules (3) map-SecureTransportOperations (26)
+ version9 (9)}
+
+;
+Supported-MAP-Operations OPERATION ::= {updateLocation | cancelLocation | purgeMS |
+sendIdentification | updateGprsLocation | prepareHandover | sendEndSignal |
+processAccessSignalling | forwardAccessSignalling | prepareSubsequentHandover |
+sendAuthenticationInfo | authenticationFailureReport | checkIMEI | insertSubscriberData |
+deleteSubscriberData | reset | forwardCheckSS-Indication | restoreData | provideSubscriberInfo |
+anyTimeInterrogation | anyTimeSubscriptionInterrogation | anyTimeModification |
+sendRoutingInfoForGprs | failureReport |noteMsPresentForGprs | noteMM-Event |
+noteSubscriberDataModified | activateTraceMode | deactivateTraceMode | sendIMSI |
+sendRoutingInfo | provideRoamingNumber | resumeCallHandling | setReportingState | statusReport | remoteUserFree | ist-Alert |
+ist-Command | registerSS | eraseSS | activateSS | deactivateSS | interrogateSS |
+processUnstructuredSS-Request | unstructuredSS-Request | unstructuredSS-Notify |
+registerPassword | getPassword | ss-InvocationNotification | registerCC-Entry | eraseCC-Entry |
+sendRoutingInfoForSM | mo-ForwardSM | mt-ForwardSM | reportSM-DeliveryStatus |
+alertServiceCentre | informServiceCentre | readyForSM | prepareGroupCall |
+processGroupCallSignalling | forwardGroupCallSignalling | sendGroupCallEndSignal |
+provideSubscriberLocation | sendRoutingInfoForLCS | subscriberLocationReport |
+secureTransportClass1 |secureTransportClass2 | secureTransportClass3 | secureTransportClass4}
+
+
+
+-- The following operation codes are reserved for operations
+-- existing in previous versions of the protocol
+
+-- Operation Name AC used Oper. Code
+--
+-- sendParameters map-ac infoRetrieval (14) version1 (1) local:9
+-- processUnstructuredSS-Data map-ac networkFunctionalSs (18) version1 (1) local:19
+-- performHandover map-ac handoverControl (11) version1 (1) local:28
+-- performSubsequentHandover map-ac handoverControl (11) version1 (1) local:30
+-- provideSIWFSNumber map-ac sIWFSAllocation (12) version3 (3) local:31
+-- siwfs-SignallingModify map-ac sIWFSAllocation (12) version3 (3) local:32
+-- noteInternalHandover map-ac handoverControl (11) version1 (1) local:35
+-- noteSubscriberPresent map-ac mwdMngt (24) version1 (1) local:48
+-- alertServiceCentreWithoutResult map-ac shortMsgAlert (23) version1 (1) local:49
+-- traceSubscriberActivity map-ac handoverControl (11) version1 (1) local:52
+-- beginSubscriberActivity map-ac networkFunctionalSs (18) version1 (1) local:54
+
+-- The following error codes are reserved for errors
+-- existing in previous versions of the protocol
+
+-- Error Name AC used Error Code
+--
+-- unknownBaseStation map-ac handoverControl (11) version1 (1) local:2
+-- invalidTargetBaseStation map-ac handoverControl (11) version1 (1) local:23
+-- noRadioResourceAvailable map-ac handoverControl (11) version1 (1) local:24
+
+
+END
diff --git a/lib/asn1/test/asn1_SUITE_data/tcapsystem/MAP-SM-DataTypes.asn b/lib/asn1/test/asn1_SUITE_data/tcapsystem/MAP-SM-DataTypes.asn
new file mode 100644
index 0000000000..664baa1b41
--- /dev/null
+++ b/lib/asn1/test/asn1_SUITE_data/tcapsystem/MAP-SM-DataTypes.asn
@@ -0,0 +1,217 @@
+MAP-SM-DataTypes {
+ itu-t identified-organization (4) etsi (0) mobileDomain (0)
+ gsm-Network (1) modules (3) map-SM-DataTypes (16) version9 (9)}
+
+DEFINITIONS
+
+IMPLICIT TAGS
+
+::=
+
+BEGIN
+
+EXPORTS
+ RoutingInfoForSM-Arg,
+ RoutingInfoForSM-Res,
+ MO-ForwardSM-Arg,
+ MO-ForwardSM-Res,
+ MT-ForwardSM-Arg,
+ MT-ForwardSM-Res,
+ ReportSM-DeliveryStatusArg,
+ ReportSM-DeliveryStatusRes,
+ AlertServiceCentreArg,
+ InformServiceCentreArg,
+ ReadyForSM-Arg,
+ ReadyForSM-Res,
+ SM-DeliveryOutcome,
+ AlertReason,
+ Additional-Number
+;
+
+IMPORTS
+ AddressString,
+ ISDN-AddressString,
+ SignalInfo,
+ IMSI,
+ LMSI
+FROM MAP-CommonDataTypes {
+ itu-t identified-organization (4) etsi (0) mobileDomain (0)
+ gsm-Network (1) modules (3) map-CommonDataTypes (18) version9 (9)}
+
+ AbsentSubscriberDiagnosticSM
+FROM MAP-ER-DataTypes {
+ itu-t identified-organization (4) etsi (0) mobileDomain (0)
+ gsm-Network (1) modules (3) map-ER-DataTypes (17) version9 (9)}
+
+ ExtensionContainer
+FROM MAP-ExtensionDataTypes {
+ itu-t identified-organization (4) etsi (0) mobileDomain (0)
+ gsm-Network (1) modules (3) map-ExtensionDataTypes (21) version9 (9)}
+;
+
+
+RoutingInfoForSM-Arg ::= SEQUENCE {
+ msisdn [0] ISDN-AddressString,
+ sm-RP-PRI [1] BOOLEAN,
+ serviceCentreAddress [2] AddressString,
+ extensionContainer [6] ExtensionContainer OPTIONAL,
+ ... ,
+ gprsSupportIndicator [7] NULL OPTIONAL,
+ -- gprsSupportIndicator is set only if the SMS-GMSC supports
+ -- receiving of two numbers from the HLR
+ sm-RP-MTI [8] SM-RP-MTI OPTIONAL,
+ sm-RP-SMEA [9] SM-RP-SMEA OPTIONAL }
+
+SM-RP-MTI ::= INTEGER (0..10)
+ -- 0 SMS Deliver
+ -- 1 SMS Status Report
+ -- other values are reserved for future use and shall be discarded if
+ -- received
+
+SM-RP-SMEA ::= OCTET STRING (SIZE (1..12))
+ -- this parameter contains an address field which is encoded
+ -- as defined in 3GPP TS 23.040. An address field contains 3 elements :
+ -- address-length
+ -- type-of-address
+ -- address-value
+
+RoutingInfoForSM-Res ::= SEQUENCE {
+ imsi IMSI,
+ locationInfoWithLMSI [0] LocationInfoWithLMSI,
+ extensionContainer [4] ExtensionContainer OPTIONAL,
+ ...}
+
+LocationInfoWithLMSI ::= SEQUENCE {
+ networkNode-Number [1] ISDN-AddressString,
+ lmsi LMSI OPTIONAL,
+ extensionContainer ExtensionContainer OPTIONAL,
+ ...,
+ gprsNodeIndicator [5] NULL OPTIONAL,
+ -- gprsNodeIndicator is set only if the SGSN number is sent as the
+ -- Network Node Number
+ additional-Number [6] Additional-Number OPTIONAL
+ -- NetworkNode-number can be either msc-number or sgsn-number
+ }
+
+Additional-Number ::= CHOICE {
+ msc-Number [0] ISDN-AddressString,
+ sgsn-Number [1] ISDN-AddressString}
+ -- additional-number can be either msc-number or sgsn-number
+ -- if received networkNode-number is msc-number then the
+ -- additional number is sgsn-number
+ -- if received networkNode-number is sgsn-number then the
+ -- additional number is msc-number
+
+MO-ForwardSM-Arg ::= SEQUENCE {
+ sm-RP-DA SM-RP-DA,
+ sm-RP-OA SM-RP-OA,
+ sm-RP-UI SignalInfo,
+ extensionContainer ExtensionContainer OPTIONAL,
+ ... ,
+ imsi IMSI OPTIONAL }
+
+MO-ForwardSM-Res ::= SEQUENCE {
+ sm-RP-UI SignalInfo OPTIONAL,
+ extensionContainer ExtensionContainer OPTIONAL,
+ ...}
+
+MT-ForwardSM-Arg ::= SEQUENCE {
+ sm-RP-DA SM-RP-DA,
+ sm-RP-OA SM-RP-OA,
+ sm-RP-UI SignalInfo,
+ moreMessagesToSend NULL OPTIONAL,
+ extensionContainer ExtensionContainer OPTIONAL,
+ ...}
+
+MT-ForwardSM-Res ::= SEQUENCE {
+ sm-RP-UI SignalInfo OPTIONAL,
+ extensionContainer ExtensionContainer OPTIONAL,
+ ...}
+
+SM-RP-DA ::= CHOICE {
+ imsi [0] IMSI,
+ lmsi [1] LMSI,
+ serviceCentreAddressDA [4] AddressString,
+ noSM-RP-DA [5] NULL}
+
+SM-RP-OA ::= CHOICE {
+ msisdn [2] ISDN-AddressString,
+ serviceCentreAddressOA [4] AddressString,
+ noSM-RP-OA [5] NULL}
+
+ReportSM-DeliveryStatusArg ::= SEQUENCE {
+ msisdn ISDN-AddressString,
+ serviceCentreAddress AddressString,
+ sm-DeliveryOutcome SM-DeliveryOutcome,
+ absentSubscriberDiagnosticSM [0] AbsentSubscriberDiagnosticSM
+ OPTIONAL,
+ extensionContainer [1] ExtensionContainer OPTIONAL,
+ ...,
+ gprsSupportIndicator [2] NULL OPTIONAL,
+ -- gprsSupportIndicator is set only if the SMS-GMSC supports
+ -- handling of two delivery outcomes
+ deliveryOutcomeIndicator [3] NULL OPTIONAL,
+ -- DeliveryOutcomeIndicator is set when the SM-DeliveryOutcome
+ -- is for GPRS
+ additionalSM-DeliveryOutcome [4] SM-DeliveryOutcome OPTIONAL,
+ -- If received, additionalSM-DeliveryOutcome is for GPRS
+ -- If DeliveryOutcomeIndicator is set, then AdditionalSM-DeliveryOutcome shall be absent
+ additionalAbsentSubscriberDiagnosticSM [5] AbsentSubscriberDiagnosticSM OPTIONAL
+ -- If received additionalAbsentSubscriberDiagnosticSM is for GPRS
+ -- If DeliveryOutcomeIndicator is set, then AdditionalAbsentSubscriberDiagnosticSM
+ -- shall be absent
+ }
+
+SM-DeliveryOutcome ::= ENUMERATED {
+ memoryCapacityExceeded (0),
+ absentSubscriber (1),
+ successfulTransfer (2)}
+
+ReportSM-DeliveryStatusRes ::= SEQUENCE {
+ storedMSISDN ISDN-AddressString OPTIONAL,
+ extensionContainer ExtensionContainer OPTIONAL,
+ ...}
+
+AlertServiceCentreArg ::= SEQUENCE {
+ msisdn ISDN-AddressString,
+ serviceCentreAddress AddressString,
+ ...}
+
+InformServiceCentreArg ::= SEQUENCE {
+ storedMSISDN ISDN-AddressString OPTIONAL,
+ mw-Status MW-Status OPTIONAL,
+ extensionContainer ExtensionContainer OPTIONAL,
+ ... ,
+ absentSubscriberDiagnosticSM AbsentSubscriberDiagnosticSM OPTIONAL,
+ additionalAbsentSubscriberDiagnosticSM [0] AbsentSubscriberDiagnosticSM OPTIONAL }
+ -- additionalAbsentSubscriberDiagnosticSM may be present only if
+ -- absentSubscriberDiagnosticSM is present.
+ -- if included, additionalAbsentSubscriberDiagnosticSM is for GPRS and
+ -- absentSubscriberDiagnosticSM is for non-GPRS
+
+MW-Status ::= BIT STRING {
+ sc-AddressNotIncluded (0),
+ mnrf-Set (1),
+ mcef-Set (2) ,
+ mnrg-Set (3)} (SIZE (6..16))
+ -- exception handling:
+ -- bits 4 to 15 shall be ignored if received and not understood
+
+ReadyForSM-Arg ::= SEQUENCE {
+ imsi [0] IMSI,
+ alertReason AlertReason,
+ alertReasonIndicator NULL OPTIONAL,
+ -- alertReasonIndicator is set only when the alertReason
+ -- sent to HLR is for GPRS
+ extensionContainer ExtensionContainer OPTIONAL,
+ ...}
+
+ReadyForSM-Res ::= SEQUENCE {
+ extensionContainer ExtensionContainer OPTIONAL,
+ ...}
+
+AlertReason ::= ENUMERATED {
+ ms-Present (0),
+ memoryAvailable (1)}
+
+END
diff --git a/lib/asn1/test/asn1_SUITE_data/tcapsystem/MAP-SS-Code.asn b/lib/asn1/test/asn1_SUITE_data/tcapsystem/MAP-SS-Code.asn
new file mode 100644
index 0000000000..d3f0957648
--- /dev/null
+++ b/lib/asn1/test/asn1_SUITE_data/tcapsystem/MAP-SS-Code.asn
@@ -0,0 +1,183 @@
+MAP-SS-Code {
+ itu-t identified-organization (4) etsi (0) mobileDomain (0)
+ gsm-Network (1) modules (3) map-SS-Code (15) version9 (9)}
+
+DEFINITIONS
+
+::=
+
+BEGIN
+
+SS-Code ::= OCTET STRING (SIZE (1))
+ -- This type is used to represent the code identifying a single
+ -- supplementary service, a group of supplementary services, or
+ -- all supplementary services. The services and abbreviations
+ -- used are defined in TS 3GPP TS 22.004 [5]. The internal structure is
+ -- defined as follows:
+ --
+ -- bits 87654321: group (bits 8765), and specific service
+ -- (bits 4321)
+
+allSS SS-Code ::= '00000000'B
+ -- reserved for possible future use
+ -- all SS
+
+allLineIdentificationSS SS-Code ::= '00010000'B
+ -- reserved for possible future use
+ -- all line identification SS
+clip SS-Code ::= '00010001'B
+ -- calling line identification presentation
+clir SS-Code ::= '00010010'B
+ -- calling line identification restriction
+colp SS-Code ::= '00010011'B
+ -- connected line identification presentation
+colr SS-Code ::= '00010100'B
+ -- connected line identification restriction
+mci SS-Code ::= '00010101'B
+ -- reserved for possible future use
+ -- malicious call identification
+
+allNameIdentificationSS SS-Code ::= '00011000'B
+ -- all name identification SS
+cnap SS-Code ::= '00011001'B
+ -- calling name presentation
+
+ -- SS-Codes '00011010'B to '00011111'B are reserved for future
+ -- NameIdentification Supplementary Service use.
+
+allForwardingSS SS-Code ::= '00100000'B
+ -- all forwarding SS
+cfu SS-Code ::= '00100001'B
+ -- call forwarding unconditional
+allCondForwardingSS SS-Code ::= '00101000'B
+ -- all conditional forwarding SS
+cfb SS-Code ::= '00101001'B
+ -- call forwarding on mobile subscriber busy
+cfnry SS-Code ::= '00101010'B
+ -- call forwarding on no reply
+cfnrc SS-Code ::= '00101011'B
+ -- call forwarding on mobile subscriber not reachable
+cd SS-Code ::= '00100100'B
+ -- call deflection
+
+allCallOfferingSS SS-Code ::= '00110000'B
+ -- reserved for possible future use
+ -- all call offering SS includes also all forwarding SS
+ect SS-Code ::= '00110001'B
+ -- explicit call transfer
+mah SS-Code ::= '00110010'B
+ -- reserved for possible future use
+ -- mobile access hunting
+
+allCallCompletionSS SS-Code ::= '01000000'B
+ -- reserved for possible future use
+ -- all Call completion SS
+cw SS-Code ::= '01000001'B
+ -- call waiting
+hold SS-Code ::= '01000010'B
+ -- call hold
+ccbs-A SS-Code ::= '01000011'B
+ -- completion of call to busy subscribers, originating side
+ccbs-B SS-Code ::= '01000100'B
+ -- completion of call to busy subscribers, destination side
+ -- this SS-Code is used only in InsertSubscriberData and DeleteSubscriberData
+mc SS-Code ::= '01000101'B
+ -- multicall
+
+allMultiPartySS SS-Code ::= '01010000'B
+ -- reserved for possible future use
+ -- all multiparty SS
+multiPTY SS-Code ::= '01010001'B
+ -- multiparty
+
+allCommunityOfInterest-SS SS-Code ::= '01100000'B
+ -- reserved for possible future use
+ -- all community of interest SS
+cug SS-Code ::= '01100001'B
+ -- closed user group
+
+allChargingSS SS-Code ::= '01110000'B
+ -- reserved for possible future use
+ -- all charging SS
+aoci SS-Code ::= '01110001'B
+ -- advice of charge information
+aocc SS-Code ::= '01110010'B
+ -- advice of charge charging
+
+allAdditionalInfoTransferSS SS-Code ::= '10000000'B
+ -- reserved for possible future use
+ -- all additional information transfer SS
+uus1 SS-Code ::= '10000001'B
+ -- UUS1 user-to-user signalling
+uus2 SS-Code ::= '10000010'B
+ -- UUS2 user-to-user signalling
+uus3 SS-Code ::= '10000011'B
+ -- UUS3 user-to-user signalling
+
+allBarringSS SS-Code ::= '10010000'B
+ -- all barring SS
+barringOfOutgoingCalls SS-Code ::= '10010001'B
+ -- barring of outgoing calls
+baoc SS-Code ::= '10010010'B
+ -- barring of all outgoing calls
+boic SS-Code ::= '10010011'B
+ -- barring of outgoing international calls
+boicExHC SS-Code ::= '10010100'B
+ -- barring of outgoing international calls except those directed
+ -- to the home PLMN Country
+barringOfIncomingCalls SS-Code ::= '10011001'B
+ -- barring of incoming calls
+baic SS-Code ::= '10011010'B
+ -- barring of all incoming calls
+bicRoam SS-Code ::= '10011011'B
+ -- barring of incoming calls when roaming outside home PLMN
+ -- Country
+
+allPLMN-specificSS SS-Code ::= '11110000'B
+plmn-specificSS-1 SS-Code ::= '11110001'B
+plmn-specificSS-2 SS-Code ::= '11110010'B
+plmn-specificSS-3 SS-Code ::= '11110011'B
+plmn-specificSS-4 SS-Code ::= '11110100'B
+plmn-specificSS-5 SS-Code ::= '11110101'B
+plmn-specificSS-6 SS-Code ::= '11110110'B
+plmn-specificSS-7 SS-Code ::= '11110111'B
+plmn-specificSS-8 SS-Code ::= '11111000'B
+plmn-specificSS-9 SS-Code ::= '11111001'B
+plmn-specificSS-A SS-Code ::= '11111010'B
+plmn-specificSS-B SS-Code ::= '11111011'B
+plmn-specificSS-C SS-Code ::= '11111100'B
+plmn-specificSS-D SS-Code ::= '11111101'B
+plmn-specificSS-E SS-Code ::= '11111110'B
+plmn-specificSS-F SS-Code ::= '11111111'B
+
+allCallPrioritySS SS-Code ::= '10100000'B
+ -- reserved for possible future use
+ -- all call priority SS
+emlpp SS-Code ::= '10100001'B
+ -- enhanced Multilevel Precedence Pre-emption (EMLPP) service
+
+allLCSPrivacyException SS-Code ::= '10110000'B
+ -- all LCS Privacy Exception Classes
+universal SS-Code ::= '10110001'B
+ -- allow location by any LCS client
+callSessionRelated SS-Code ::= '10110010'B
+ -- allow location by any value added LCS client to which a call/session
+ -- is established from the target MS
+callSessionUnrelated SS-Code ::= '10110011'B
+ -- allow location by designated external value added LCS clients
+plmnoperator SS-Code ::= '10110100'B
+ -- allow location by designated PLMN operator LCS clients
+serviceType SS-Code ::= '10110101'B
+ -- allow location by LCS clients of a designated LCS service type
+
+allMOLR-SS SS-Code ::= '11000000'B
+ -- all Mobile Originating Location Request Classes
+basicSelfLocation SS-Code ::= '11000001'B
+ -- allow an MS to request its own location
+autonomousSelfLocation SS-Code ::= '11000010'B
+ -- allow an MS to perform self location without interaction
+ -- with the PLMN for a predetermined period of time
+transferToThirdParty SS-Code ::= '11000011'B
+ -- allow an MS to request transfer of its location to another LCS client
+
+END
diff --git a/lib/asn1/test/asn1_SUITE_data/tcapsystem/MAP-SS-DataTypes.asn b/lib/asn1/test/asn1_SUITE_data/tcapsystem/MAP-SS-DataTypes.asn
new file mode 100644
index 0000000000..5cf9178353
--- /dev/null
+++ b/lib/asn1/test/asn1_SUITE_data/tcapsystem/MAP-SS-DataTypes.asn
@@ -0,0 +1,337 @@
+MAP-SS-DataTypes {
+ itu-t identified-organization (4) etsi (0) mobileDomain (0)
+ gsm-Network (1) modules (3) map-SS-DataTypes (14) version9 (9)}
+
+DEFINITIONS
+
+IMPLICIT TAGS
+
+::=
+
+BEGIN
+
+EXPORTS
+ RegisterSS-Arg,
+ SS-Info,
+ SS-Status,
+ SS-SubscriptionOption,
+ SS-ForBS-Code,
+ InterrogateSS-Res,
+ USSD-Arg,
+ USSD-Res,
+ USSD-DataCodingScheme,
+ USSD-String,
+ Password,
+ GuidanceInfo,
+ SS-List,
+ SS-InfoList,
+ OverrideCategory,
+ CliRestrictionOption,
+ NoReplyConditionTime,
+ ForwardingOptions,
+ maxNumOfSS,
+ SS-Data,
+ SS-InvocationNotificationArg,
+ SS-InvocationNotificationRes,
+ CCBS-Feature,
+ RegisterCC-EntryArg,
+ RegisterCC-EntryRes,
+ EraseCC-EntryArg,
+ EraseCC-EntryRes
+;
+
+IMPORTS
+ AddressString,
+ ISDN-AddressString,
+ ISDN-SubaddressString,
+ FTN-AddressString,
+ IMSI,
+ BasicServiceCode,
+ AlertingPattern,
+ EMLPP-Priority,
+ MaxMC-Bearers,
+ MC-Bearers,
+ ExternalSignalInfo
+FROM MAP-CommonDataTypes {
+ itu-t identified-organization (4) etsi (0) mobileDomain (0)
+ gsm-Network (1) modules (3) map-CommonDataTypes (18) version9 (9)}
+
+ ExtensionContainer
+FROM MAP-ExtensionDataTypes {
+ itu-t identified-organization (4) etsi (0) mobileDomain (0)
+ gsm-Network (1) modules (3) map-ExtensionDataTypes (21) version9 (9)}
+
+ SS-Code
+FROM MAP-SS-Code {
+ itu-t identified-organization (4) etsi (0) mobileDomain (0)
+ gsm-Network (1) modules (3) map-SS-Code (15) version9 (9)}
+;
+
+
+RegisterSS-Arg ::= SEQUENCE {
+ ss-Code SS-Code,
+ basicService BasicServiceCode OPTIONAL,
+ forwardedToNumber [4] AddressString OPTIONAL,
+ forwardedToSubaddress [6] ISDN-SubaddressString OPTIONAL,
+ noReplyConditionTime [5] NoReplyConditionTime OPTIONAL,
+ ...,
+ defaultPriority [7] EMLPP-Priority OPTIONAL,
+ nbrUser [8] MC-Bearers OPTIONAL,
+ longFTN-Supported [9] NULL OPTIONAL }
+
+NoReplyConditionTime ::= INTEGER (5..30)
+
+SS-Info ::= CHOICE {
+ forwardingInfo [0] ForwardingInfo,
+ callBarringInfo [1] CallBarringInfo,
+ ss-Data [3] SS-Data}
+
+ForwardingInfo ::= SEQUENCE {
+ ss-Code SS-Code OPTIONAL,
+ forwardingFeatureList ForwardingFeatureList,
+ ...}
+
+ForwardingFeatureList ::=
+ SEQUENCE SIZE (1..maxNumOfBasicServiceGroups) OF
+ ForwardingFeature
+
+ForwardingFeature ::= SEQUENCE {
+ basicService BasicServiceCode OPTIONAL,
+ ss-Status [4] SS-Status OPTIONAL,
+ forwardedToNumber [5] ISDN-AddressString OPTIONAL,
+ forwardedToSubaddress [8] ISDN-SubaddressString OPTIONAL,
+ forwardingOptions [6] ForwardingOptions OPTIONAL,
+ noReplyConditionTime [7] NoReplyConditionTime OPTIONAL,
+ ...,
+ longForwardedToNumber [9] FTN-AddressString OPTIONAL }
+
+SS-Status ::= OCTET STRING (SIZE (1))
+
+ -- bits 8765: 0000 (unused)
+ -- bits 4321: Used to convey the "P bit","R bit","A bit" and "Q bit",
+ -- representing supplementary service state information
+ -- as defined in TS 3GPP TS 23.011 [22]
+
+ -- bit 4: "Q bit"
+
+ -- bit 3: "P bit"
+
+ -- bit 2: "R bit"
+
+ -- bit 1: "A bit"
+
+ForwardingOptions ::= OCTET STRING (SIZE (1))
+
+ -- bit 8: notification to forwarding party
+ -- 0 no notification
+ -- 1 notification
+
+ -- bit 7: redirecting presentation
+ -- 0 no presentation
+ -- 1 presentation
+
+ -- bit 6: notification to calling party
+ -- 0 no notification
+ -- 1 notification
+
+ -- bit 5: 0 (unused)
+
+ -- bits 43: forwarding reason
+ -- 00 ms not reachable
+ -- 01 ms busy
+ -- 10 no reply
+ -- 11 unconditional when used in a SRI Result,
+ -- or call deflection when used in a RCH Argument
+ -- bits 21: 00 (unused)
+
+CallBarringInfo ::= SEQUENCE {
+ ss-Code SS-Code OPTIONAL,
+ callBarringFeatureList CallBarringFeatureList,
+ ...}
+
+CallBarringFeatureList ::= SEQUENCE SIZE (1..maxNumOfBasicServiceGroups) OF
+ CallBarringFeature
+
+CallBarringFeature ::= SEQUENCE {
+ basicService BasicServiceCode OPTIONAL,
+ ss-Status [4] SS-Status OPTIONAL,
+ ...}
+
+SS-Data ::= SEQUENCE {
+ ss-Code SS-Code OPTIONAL,
+ ss-Status [4] SS-Status OPTIONAL,
+ ss-SubscriptionOption SS-SubscriptionOption OPTIONAL,
+ basicServiceGroupList BasicServiceGroupList OPTIONAL,
+ ...,
+ defaultPriority EMLPP-Priority OPTIONAL,
+ nbrUser [5] MC-Bearers OPTIONAL
+ }
+
+SS-SubscriptionOption ::= CHOICE {
+ cliRestrictionOption [2] CliRestrictionOption,
+ overrideCategory [1] OverrideCategory}
+
+CliRestrictionOption ::= ENUMERATED {
+ permanent (0),
+ temporaryDefaultRestricted (1),
+ temporaryDefaultAllowed (2)}
+
+OverrideCategory ::= ENUMERATED {
+ overrideEnabled (0),
+ overrideDisabled (1)}
+
+SS-ForBS-Code ::= SEQUENCE {
+ ss-Code SS-Code,
+ basicService BasicServiceCode OPTIONAL,
+ ...,
+ longFTN-Supported [4] NULL OPTIONAL }
+
+GenericServiceInfo ::= SEQUENCE {
+ ss-Status SS-Status,
+ cliRestrictionOption CliRestrictionOption OPTIONAL,
+ ...,
+ maximumEntitledPriority [0] EMLPP-Priority OPTIONAL,
+ defaultPriority [1] EMLPP-Priority OPTIONAL,
+ ccbs-FeatureList [2] CCBS-FeatureList OPTIONAL,
+ nbrSB [3] MaxMC-Bearers OPTIONAL,
+ nbrUser [4] MC-Bearers OPTIONAL,
+ nbrSN [5] MC-Bearers OPTIONAL }
+
+CCBS-FeatureList ::= SEQUENCE SIZE (1..maxNumOfCCBS-Requests) OF
+ CCBS-Feature
+
+maxNumOfCCBS-Requests INTEGER ::= 5
+
+CCBS-Feature ::= SEQUENCE {
+ ccbs-Index [0] CCBS-Index OPTIONAL,
+ b-subscriberNumber [1] ISDN-AddressString OPTIONAL,
+ b-subscriberSubaddress [2] ISDN-SubaddressString OPTIONAL,
+ basicServiceGroup [3] BasicServiceCode OPTIONAL,
+ ...}
+
+CCBS-Index ::= INTEGER (1..maxNumOfCCBS-Requests)
+
+InterrogateSS-Res ::= CHOICE {
+ ss-Status [0] SS-Status,
+ basicServiceGroupList [2] BasicServiceGroupList,
+ forwardingFeatureList [3] ForwardingFeatureList,
+ genericServiceInfo [4] GenericServiceInfo }
+
+USSD-Arg ::= SEQUENCE {
+ ussd-DataCodingScheme USSD-DataCodingScheme,
+ ussd-String USSD-String,
+ ... ,
+ alertingPattern AlertingPattern OPTIONAL,
+ msisdn [0] ISDN-AddressString OPTIONAL }
+
+USSD-Res ::= SEQUENCE {
+ ussd-DataCodingScheme USSD-DataCodingScheme,
+ ussd-String USSD-String,
+ ...}
+
+USSD-DataCodingScheme ::= OCTET STRING (SIZE (1))
+ -- The structure of the USSD-DataCodingScheme is defined by
+ -- the Cell Broadcast Data Coding Scheme as described in
+ -- TS 3GPP TS 23.038 [25]
+
+USSD-String ::= OCTET STRING (SIZE (1..maxUSSD-StringLength))
+ -- The structure of the contents of the USSD-String is dependent
+ -- on the USSD-DataCodingScheme as described in TS 3GPP TS 23.038 [25].
+
+maxUSSD-StringLength INTEGER ::= 160
+
+Password ::= NumericString
+ (FROM ("0"|"1"|"2"|"3"|"4"|"5"|"6"|"7"|"8"|"9"))
+ (SIZE (4))
+
+GuidanceInfo ::= ENUMERATED {
+ enterPW (0),
+ enterNewPW (1),
+ enterNewPW-Again (2)}
+ -- How this information is really delivered to the subscriber
+ -- (display, announcement, ...) is not part of this
+ -- specification.
+
+SS-List ::= SEQUENCE SIZE (1..maxNumOfSS) OF
+ SS-Code
+
+maxNumOfSS INTEGER ::= 30
+
+SS-InfoList ::= SEQUENCE SIZE (1..maxNumOfSS) OF
+ SS-Info
+
+BasicServiceGroupList ::= SEQUENCE SIZE (1..maxNumOfBasicServiceGroups) OF
+ BasicServiceCode
+
+maxNumOfBasicServiceGroups INTEGER ::= 13
+
+SS-InvocationNotificationArg ::= SEQUENCE {
+ imsi [0] IMSI,
+ msisdn [1] ISDN-AddressString,
+ ss-Event [2] SS-Code,
+ -- The following SS-Code values are allowed :
+ -- ect SS-Code ::= '00110001'B
+ -- multiPTY SS-Code ::= '01010001'B
+ -- cd SS-Code ::= '00100100'B
+ -- ccbs SS-Code ::= '01000100'B
+ ss-EventSpecification [3] SS-EventSpecification OPTIONAL,
+ extensionContainer [4] ExtensionContainer OPTIONAL,
+ ...,
+ b-subscriberNumber [5] ISDN-AddressString OPTIONAL,
+ ccbs-RequestState [6] CCBS-RequestState OPTIONAL
+ }
+
+CCBS-RequestState ::= ENUMERATED {
+ request (0),
+ recall (1),
+ active (2),
+ completed (3),
+ suspended (4),
+ frozen (5),
+ deleted (6)
+ }
+
+SS-InvocationNotificationRes ::= SEQUENCE {
+ extensionContainer ExtensionContainer OPTIONAL,
+ ...
+ }
+
+SS-EventSpecification ::= SEQUENCE SIZE (1..maxEventSpecification) OF
+ AddressString
+
+maxEventSpecification INTEGER ::= 2
+
+RegisterCC-EntryArg ::= SEQUENCE {
+ ss-Code [0] SS-Code,
+ ccbs-Data [1] CCBS-Data OPTIONAL,
+ ...}
+
+CCBS-Data ::= SEQUENCE {
+ ccbs-Feature [0] CCBS-Feature,
+ translatedB-Number [1] ISDN-AddressString,
+ serviceIndicator [2] ServiceIndicator OPTIONAL,
+ callInfo [3] ExternalSignalInfo,
+ networkSignalInfo [4] ExternalSignalInfo,
+ ...}
+
+ServiceIndicator ::= BIT STRING {
+ clir-invoked (0),
+ camel-invoked (1)} (SIZE(2..32))
+ -- exception handling:
+ -- bits 2 to 31 shall be ignored if received and not understood
+
+RegisterCC-EntryRes ::= SEQUENCE {
+ ccbs-Feature [0] CCBS-Feature OPTIONAL,
+ ...}
+
+EraseCC-EntryArg ::= SEQUENCE {
+ ss-Code [0] SS-Code,
+ ccbs-Index [1] CCBS-Index OPTIONAL,
+ ...}
+
+EraseCC-EntryRes ::= SEQUENCE {
+ ss-Code [0] SS-Code,
+ ss-Status [1] SS-Status OPTIONAL,
+ ...}
+
+END
diff --git a/lib/asn1/test/asn1_SUITE_data/tcapsystem/MAP-ST-DataTypes.asn b/lib/asn1/test/asn1_SUITE_data/tcapsystem/MAP-ST-DataTypes.asn
new file mode 100644
index 0000000000..2eac16551d
--- /dev/null
+++ b/lib/asn1/test/asn1_SUITE_data/tcapsystem/MAP-ST-DataTypes.asn
@@ -0,0 +1,98 @@
+MAP-ST-DataTypes {
+ itu-t identified-organization (4) etsi (0) mobileDomain (0)
+ gsm-Network (1) modules (3) map-ST-DataTypes (27) version9 (9)}
+
+DEFINITIONS
+IMPLICIT TAGS
+::=
+BEGIN
+
+EXPORTS
+ SecureTransportArg,
+ SecureTransportRes,
+ SecurityHeader,
+ ProtectedPayload
+;
+
+IMPORTS
+ IMSI
+
+FROM MAP-CommonDataTypes {
+ itu-t identified-organization (4) etsi (0) mobileDomain (0)
+ gsm-Network (1) modules (3) map-CommonDataTypes (18) version9 (9)}
+;
+
+SecureTransportArg ::= SEQUENCE {
+ securityHeader SecurityHeader,
+ protectedPayload ProtectedPayload OPTIONAL
+ }
+ -- The protectedPayload carries the result of applying the security function
+ -- defined in 3GPP TS 33.200 to the encoding of the argument of the securely
+ -- transported operation
+
+SecureTransportRes ::= SEQUENCE {
+ securityHeader SecurityHeader,
+ protectedPayload ProtectedPayload OPTIONAL
+ }
+ -- The protectedPayload carries the result of applying the security function
+ -- defined in 3GPP TS 33.200 to the encoding of the result of the securely
+ -- transported operation
+
+SecurityHeader ::= SEQUENCE {
+ securityParametersIndex SecurityParametersIndex,
+ originalComponentIdentifier OriginalComponentIdentifier,
+ initialisationVector InitialisationVector OPTIONAL,
+ ...}
+
+ProtectedPayload ::= OCTET STRING(SIZE(1.. 3438))
+ -- In protection mode 0 (noProtection) the ProtectedPayload carries the transfer
+ -- syntax value of the component parameter identified by the
+ -- originalComponentIdentifier.
+ -- In protection mode 1 (integrityAuthenticity) the protectedPayload carries
+ -- the transfer syntax value of the component
+ -- parameter identified by the originalComponentIdentifier, followed by
+ -- the 32 bit integrity check value.
+ -- The integrity check value is the result of applying the hash algorithm
+ -- to the concatenation of the transfer syntax value of the SecurityHeader,
+ -- and the transfer syntax value of the component parameter.
+ -- In protection mode 2 (confidentialityIntegrityAuthenticity) the protected
+ -- payload carries the encrypted transfer syntax
+ -- value of the component parameter identified by the
+ -- originalComponentIdentifier, followed by the 32 bit integrity check value.
+ -- The integrity check value is the result of applying the hash algorithm
+ -- to the concatenation of the transfer syntax value of the SecurityHeader,
+ -- and the encrypted transfer syntax value of the component parameter.
+ -- See 33.200.
+ -- The length of the protectedPayload is adjusted according to the capabilities of
+ -- the lower protocol layers
+
+SecurityParametersIndex ::= OCTET STRING (SIZE(4))
+
+InitialisationVector ::= OCTET STRING (SIZE(14))
+ -- the internal structure is defined as follows:
+ -- Octets 1 to 4 : TVP. The TVP is a 32 bit time stamp. Its value is binary coded
+ -- and indicates the number of intervals of 100 milliseconds
+ -- elapsed since 1st January 2002, 0:00:00 UTC
+ -- Octets 5 to 10: NE-Id. The NE-Id uniquely identifies the sending network entity
+ -- within the PLMN. It is the entity's E.164 number without CC and
+ -- NDC. It is TBCD-coded, padded with zeros.
+ -- Octets 11 to 14: PROP. This 32 bit value is used to make the
+ -- InitialisationVector unique within the same TVP period.
+ -- The content is not standardized.
+
+
+OriginalComponentIdentifier ::= CHOICE {
+ operationCode [0] OperationCode,
+ errorCode [1] ErrorCode,
+ userInfo [2] NULL}
+
+OperationCode ::= CHOICE {
+ localValue INTEGER,
+ globalValue OBJECT IDENTIFIER}
+
+ErrorCode ::= CHOICE {
+ localValue INTEGER,
+ globalValue OBJECT IDENTIFIER}
+
+END
+
diff --git a/lib/asn1/test/asn1_SUITE_data/tcapsystem/MAP-SecureTransportOperations.asn b/lib/asn1/test/asn1_SUITE_data/tcapsystem/MAP-SecureTransportOperations.asn
new file mode 100644
index 0000000000..dfb830cddd
--- /dev/null
+++ b/lib/asn1/test/asn1_SUITE_data/tcapsystem/MAP-SecureTransportOperations.asn
@@ -0,0 +1,78 @@
+MAP-SecureTransportOperations {
+ itu-t identified-organization (4) etsi (0) mobileDomain (0)
+ gsm-Network (1) modules (3) map-SecureTransportOperations (26)
+ version9 (9)}
+
+DEFINITIONS
+
+::=
+
+BEGIN
+
+EXPORTS
+ secureTransportClass1,
+ secureTransportClass2,
+ secureTransportClass3,
+ secureTransportClass4
+;
+
+IMPORTS
+ OPERATION
+FROM Remote-Operations-Information-Objects {
+joint-iso-itu-t remote-operations(4)
+ informationObjects(5) version1(0)}
+
+ dataMissing,
+ secureTransportError,
+ unexpectedDataValue
+
+FROM MAP-Errors {
+ itu-t identified-organization (4) etsi (0) mobileDomain (0)
+ gsm-Network (1) modules (3) map-Errors (10) version9 (9)}
+
+ SecureTransportArg,
+ SecureTransportRes
+
+FROM MAP-ST-DataTypes {
+ itu-t identified-organization (4) etsi (0) mobileDomain (0)
+ gsm-Network (1) modules (3) map-ST-DataTypes (27) version9 (9)}
+;
+
+secureTransportClass1 OPERATION ::= { --Timer shall be the same as for the
+ --securely transported operation
+ ARGUMENT
+ SecureTransportArg
+ RESULT
+ SecureTransportRes
+ ERRORS {
+ secureTransportError |
+ dataMissing |
+ unexpectedDataValue}
+ CODE local:78 }
+
+secureTransportClass2 OPERATION ::= { --Timer shall be the same as for the
+ --securely transported operation
+ ARGUMENT
+ SecureTransportArg
+ ERRORS {
+ secureTransportError |
+ dataMissing |
+ unexpectedDataValue}
+ CODE local:79 }
+
+secureTransportClass3 OPERATION ::= { --Timer shall be the same as for the
+ --securely transported operation
+ ARGUMENT
+ SecureTransportArg
+ RESULT
+ SecureTransportRes
+ CODE local:80 }
+
+secureTransportClass4 OPERATION ::= { --Timer shall be the same as for the
+ --securely transported operation
+ ARGUMENT
+ SecureTransportArg
+ CODE local:81 }
+
+
+END
diff --git a/lib/asn1/test/asn1_SUITE_data/tcapsystem/MAP-ShortMessageServiceOperations.asn b/lib/asn1/test/asn1_SUITE_data/tcapsystem/MAP-ShortMessageServiceOperations.asn
new file mode 100644
index 0000000000..0cca86ceac
--- /dev/null
+++ b/lib/asn1/test/asn1_SUITE_data/tcapsystem/MAP-ShortMessageServiceOperations.asn
@@ -0,0 +1,155 @@
+-- asn1ct:compile("MAP-ShortMessageServiceOperations",[ber_bin, {outdir, "../compiled/umts_map"}]).
+
+MAP-ShortMessageServiceOperations {
+ itu-t identified-organization (4) etsi (0) mobileDomain (0)
+ gsm-Network (1) modules (3) map-ShortMessageServiceOperations (9)
+ version9 (9)}
+
+DEFINITIONS
+
+::=
+
+BEGIN
+
+EXPORTS
+ sendRoutingInfoForSM,
+ mo-ForwardSM,
+ mt-ForwardSM,
+ reportSM-DeliveryStatus,
+ alertServiceCentre,
+ informServiceCentre,
+ readyForSM
+;
+
+IMPORTS
+ OPERATION
+FROM Remote-Operations-Information-Objects {
+joint-iso-itu-t remote-operations(4)
+ informationObjects(5) version1(0)}
+
+ systemFailure,
+ dataMissing,
+ unexpectedDataValue,
+ facilityNotSupported,
+ unknownSubscriber,
+ unidentifiedSubscriber,
+ illegalSubscriber,
+ illegalEquipment,
+ teleserviceNotProvisioned,
+ callBarred,
+ subscriberBusyForMT-SMS,
+ sm-DeliveryFailure,
+ messageWaitingListFull,
+ absentSubscriberSM
+FROM MAP-Errors {
+ itu-t identified-organization (4) etsi (0) mobileDomain (0)
+ gsm-Network (1) modules (3) map-Errors (10) version9 (9)}
+
+ RoutingInfoForSM-Arg,
+ RoutingInfoForSM-Res,
+ MO-ForwardSM-Arg,
+ MO-ForwardSM-Res,
+ MT-ForwardSM-Arg,
+ MT-ForwardSM-Res,
+ ReportSM-DeliveryStatusArg,
+ ReportSM-DeliveryStatusRes,
+ AlertServiceCentreArg,
+ InformServiceCentreArg,
+ ReadyForSM-Arg,
+ ReadyForSM-Res
+FROM MAP-SM-DataTypes {
+ itu-t identified-organization (4) etsi (0) mobileDomain (0)
+ gsm-Network (1) modules (3) map-SM-DataTypes (16) version9 (9)}
+
+;
+
+sendRoutingInfoForSM OPERATION ::= { --Timer m
+ ARGUMENT
+ RoutingInfoForSM-Arg
+ RESULT
+ RoutingInfoForSM-Res
+ ERRORS {
+ systemFailure |
+ dataMissing |
+ unexpectedDataValue |
+ facilityNotSupported |
+ unknownSubscriber |
+ teleserviceNotProvisioned |
+ callBarred |
+ absentSubscriberSM}
+ CODE local:45 }
+
+mo-ForwardSM OPERATION ::= { --Timer ml
+ ARGUMENT
+ MO-ForwardSM-Arg
+ RESULT
+ MO-ForwardSM-Res
+ -- optional
+ ERRORS {
+ systemFailure |
+ unexpectedDataValue |
+ facilityNotSupported |
+ sm-DeliveryFailure}
+ CODE local:46 }
+
+mt-ForwardSM OPERATION ::= { --Timer ml
+ ARGUMENT
+ MT-ForwardSM-Arg
+ RESULT
+ MT-ForwardSM-Res
+ -- optional
+ ERRORS {
+ systemFailure |
+ dataMissing |
+ unexpectedDataValue |
+ facilityNotSupported |
+ unidentifiedSubscriber |
+ illegalSubscriber |
+ illegalEquipment |
+ subscriberBusyForMT-SMS |
+ sm-DeliveryFailure |
+ absentSubscriberSM}
+ CODE local:44 }
+
+reportSM-DeliveryStatus OPERATION ::= { --Timer s
+ ARGUMENT
+ ReportSM-DeliveryStatusArg
+ RESULT
+ ReportSM-DeliveryStatusRes
+ -- optional
+ ERRORS {
+ dataMissing |
+ unexpectedDataValue |
+ unknownSubscriber |
+ messageWaitingListFull}
+ CODE local:47 }
+
+alertServiceCentre OPERATION ::= { --Timer s
+ ARGUMENT
+ AlertServiceCentreArg
+ RETURN RESULT TRUE
+ ERRORS {
+ systemFailure |
+ dataMissing |
+ unexpectedDataValue}
+ CODE local:64 }
+
+informServiceCentre OPERATION ::= { --Timer s
+ ARGUMENT
+ InformServiceCentreArg
+ CODE local:63 }
+
+readyForSM OPERATION ::= { --Timer m
+ ARGUMENT
+ ReadyForSM-Arg
+ RESULT
+ ReadyForSM-Res
+ -- optional
+ ERRORS {
+ dataMissing |
+ unexpectedDataValue |
+ facilityNotSupported |
+ unknownSubscriber}
+ CODE local:66 }
+
+END
diff --git a/lib/asn1/test/asn1_SUITE_data/tcapsystem/MAP-SupplementaryServiceOperations.asn b/lib/asn1/test/asn1_SUITE_data/tcapsystem/MAP-SupplementaryServiceOperations.asn
new file mode 100644
index 0000000000..7c89273c8b
--- /dev/null
+++ b/lib/asn1/test/asn1_SUITE_data/tcapsystem/MAP-SupplementaryServiceOperations.asn
@@ -0,0 +1,295 @@
+MAP-SupplementaryServiceOperations {
+ itu-t identified-organization (4) etsi (0) mobileDomain (0)
+ gsm-Network (1) modules (3) map-SupplementaryServiceOperations (8)
+ version9 (9)}
+
+DEFINITIONS
+
+::=
+
+BEGIN
+
+EXPORTS
+ registerSS,
+ eraseSS,
+ activateSS,
+ deactivateSS,
+ interrogateSS,
+ processUnstructuredSS-Request,
+ unstructuredSS-Request,
+ unstructuredSS-Notify,
+ registerPassword,
+ getPassword,
+ ss-InvocationNotification,
+ registerCC-Entry,
+ eraseCC-Entry
+;
+
+IMPORTS
+ OPERATION
+FROM Remote-Operations-Information-Objects {
+joint-iso-itu-t remote-operations(4)
+ informationObjects(5) version1(0)}
+
+ systemFailure,
+ dataMissing,
+ unexpectedDataValue,
+ unknownSubscriber,
+ bearerServiceNotProvisioned,
+ teleserviceNotProvisioned,
+ callBarred,
+ illegalSS-Operation,
+ ss-ErrorStatus,
+ ss-NotAvailable,
+ ss-SubscriptionViolation,
+ ss-Incompatibility,
+ pw-RegistrationFailure,
+ negativePW-Check,
+ numberOfPW-AttemptsViolation,
+ unknownAlphabet,
+ ussd-Busy,
+ absentSubscriber,
+ illegalSubscriber,
+ illegalEquipment,
+ shortTermDenial,
+ longTermDenial,
+ facilityNotSupported
+FROM MAP-Errors {
+ itu-t identified-organization (4) etsi (0) mobileDomain (0)
+ gsm-Network (1) modules (3) map-Errors (10) version9 (9)}
+
+ RegisterSS-Arg,
+ SS-Info,
+ SS-ForBS-Code,
+ InterrogateSS-Res,
+ USSD-Arg,
+ USSD-Res,
+ Password,
+ GuidanceInfo,
+ SS-InvocationNotificationArg,
+ SS-InvocationNotificationRes,
+ RegisterCC-EntryArg,
+ RegisterCC-EntryRes,
+ EraseCC-EntryArg,
+ EraseCC-EntryRes
+FROM MAP-SS-DataTypes {
+ itu-t identified-organization (4) etsi (0) mobileDomain (0)
+ gsm-Network (1) modules (3) map-SS-DataTypes (14) version9 (9)}
+
+ SS-Code
+FROM MAP-SS-Code {
+ itu-t identified-organization (4) etsi (0) mobileDomain (0)
+ gsm-Network (1) modules (3) map-SS-Code (15) version9 (9)}
+;
+
+
+-- supplementary service handling operations
+
+registerSS OPERATION ::= { --Timer m
+ ARGUMENT
+ RegisterSS-Arg
+ RESULT
+ SS-Info
+ -- optional
+ ERRORS {
+ systemFailure |
+ dataMissing |
+ unexpectedDataValue |
+ bearerServiceNotProvisioned |
+ teleserviceNotProvisioned |
+ callBarred |
+ illegalSS-Operation |
+ ss-ErrorStatus |
+ ss-Incompatibility}
+ CODE local:10 }
+
+eraseSS OPERATION ::= { --Timer m
+ ARGUMENT
+ SS-ForBS-Code
+ RESULT
+ SS-Info
+ -- optional
+ ERRORS {
+ systemFailure |
+ dataMissing |
+ unexpectedDataValue |
+ bearerServiceNotProvisioned |
+ teleserviceNotProvisioned |
+ callBarred |
+ illegalSS-Operation |
+ ss-ErrorStatus
+ }
+ CODE local:11 }
+
+activateSS OPERATION ::= { --Timer m
+ ARGUMENT
+ SS-ForBS-Code
+ RESULT
+ SS-Info
+ -- optional
+ ERRORS {
+ systemFailure |
+ dataMissing |
+ unexpectedDataValue |
+ bearerServiceNotProvisioned |
+ teleserviceNotProvisioned |
+ callBarred |
+ illegalSS-Operation |
+ ss-ErrorStatus |
+ ss-SubscriptionViolation |
+ ss-Incompatibility |
+ negativePW-Check |
+ numberOfPW-AttemptsViolation}
+ CODE local:12 }
+
+deactivateSS OPERATION ::= { --Timer m
+ ARGUMENT
+ SS-ForBS-Code
+ RESULT
+ SS-Info
+ -- optional
+ ERRORS {
+ systemFailure |
+ dataMissing |
+ unexpectedDataValue |
+ bearerServiceNotProvisioned |
+ teleserviceNotProvisioned |
+ callBarred |
+ illegalSS-Operation |
+ ss-ErrorStatus |
+ ss-SubscriptionViolation |
+ negativePW-Check |
+ numberOfPW-AttemptsViolation}
+ CODE local:13 }
+
+interrogateSS OPERATION ::= { --Timer m
+ ARGUMENT
+ SS-ForBS-Code
+ RESULT
+ InterrogateSS-Res
+ ERRORS {
+ systemFailure |
+ dataMissing |
+ unexpectedDataValue |
+ bearerServiceNotProvisioned |
+ teleserviceNotProvisioned |
+ callBarred |
+ illegalSS-Operation |
+ ss-NotAvailable}
+ CODE local:14 }
+
+processUnstructuredSS-Request OPERATION ::= { --Timer 10 minutes
+ ARGUMENT
+ USSD-Arg
+ RESULT
+ USSD-Res
+ ERRORS {
+ systemFailure |
+ dataMissing |
+ unexpectedDataValue |
+ unknownAlphabet |
+ callBarred}
+ CODE local:59 }
+
+unstructuredSS-Request OPERATION ::= { --Timer ml
+ ARGUMENT
+ USSD-Arg
+ RESULT
+ USSD-Res
+ -- optional
+ ERRORS {
+ systemFailure |
+ dataMissing |
+ unexpectedDataValue |
+ absentSubscriber |
+ illegalSubscriber |
+ illegalEquipment |
+ unknownAlphabet |
+ ussd-Busy}
+ CODE local:60 }
+
+unstructuredSS-Notify OPERATION ::= { --Timer ml
+ ARGUMENT
+ USSD-Arg
+ RETURN RESULT TRUE
+ ERRORS {
+ systemFailure |
+ dataMissing |
+ unexpectedDataValue |
+ absentSubscriber |
+ illegalSubscriber |
+ illegalEquipment |
+ unknownAlphabet |
+ ussd-Busy}
+ CODE local:61 }
+
+registerPassword OPERATION ::= { --Timer ml
+ ARGUMENT
+ SS-Code
+ RESULT
+ Password
+ ERRORS {
+ systemFailure |
+ dataMissing |
+ unexpectedDataValue |
+ callBarred |
+ ss-SubscriptionViolation |
+ pw-RegistrationFailure |
+ negativePW-Check |
+ numberOfPW-AttemptsViolation}
+ LINKED {
+ getPassword}
+ CODE local:17 }
+
+getPassword OPERATION ::= { --Timer m
+ ARGUMENT
+ GuidanceInfo
+ RESULT
+ Password
+ CODE local:18 }
+
+ss-InvocationNotification OPERATION ::= { --Timer m
+ ARGUMENT
+ SS-InvocationNotificationArg
+ RESULT
+ SS-InvocationNotificationRes
+ -- optional
+ ERRORS {
+ dataMissing |
+ unexpectedDataValue |
+ unknownSubscriber}
+ CODE local:72 }
+
+registerCC-Entry OPERATION ::= { --Timer m
+ ARGUMENT
+ RegisterCC-EntryArg
+ RESULT
+ RegisterCC-EntryRes
+ ERRORS {
+ systemFailure |
+ dataMissing |
+ unexpectedDataValue |
+ callBarred |
+ illegalSS-Operation |
+ ss-ErrorStatus |
+ ss-Incompatibility |
+ shortTermDenial |
+ longTermDenial |
+ facilityNotSupported}
+ CODE local:76 }
+
+eraseCC-Entry OPERATION ::= { --Timer m
+ ARGUMENT
+ EraseCC-EntryArg
+ RESULT
+ EraseCC-EntryRes
+ ERRORS {
+ systemFailure |
+ dataMissing |
+ unexpectedDataValue |
+ callBarred |
+ illegalSS-Operation |
+ ss-ErrorStatus}
+ CODE local:77 }
+
+END
diff --git a/lib/asn1/test/asn1_SUITE_data/tcapsystem/MAP-TS-Code.asn b/lib/asn1/test/asn1_SUITE_data/tcapsystem/MAP-TS-Code.asn
new file mode 100644
index 0000000000..eface38b31
--- /dev/null
+++ b/lib/asn1/test/asn1_SUITE_data/tcapsystem/MAP-TS-Code.asn
@@ -0,0 +1,87 @@
+MAP-TS-Code {
+ itu-t identified-organization (4) etsi (0) mobileDomain (0)
+ gsm-Network (1) modules (3) map-TS-Code (19) version9 (9)}
+
+DEFINITIONS
+
+::=
+
+BEGIN
+
+TeleserviceCode ::= OCTET STRING (SIZE (1))
+ -- This type is used to represent the code identifying a single
+ -- teleservice, a group of teleservices, or all teleservices. The
+ -- services are defined in TS GSM 22.003 [4].
+ -- The internal structure is defined as follows:
+
+ -- bits 87654321: group (bits 8765) and specific service
+ -- (bits 4321)
+
+Ext-TeleserviceCode ::= OCTET STRING (SIZE (1..5))
+ -- This type is used to represent the code identifying a single
+ -- teleservice, a group of teleservices, or all teleservices. The
+ -- services are defined in TS GSM 22.003 [4].
+ -- The internal structure is defined as follows:
+
+ -- OCTET 1:
+ -- bits 87654321: group (bits 8765) and specific service
+ -- (bits 4321)
+
+ -- OCTETS 2-5: reserved for future use. If received the
+ -- Ext-TeleserviceCode shall be
+ -- treated according to the exception handling defined for the
+ -- operation that uses this type.
+
+ -- Ext-TeleserviceCode includes all values defined for TeleserviceCode.
+
+allTeleservices TeleserviceCode ::= '00000000'B
+
+allSpeechTransmissionServices TeleserviceCode ::= '00010000'B
+telephony TeleserviceCode ::= '00010001'B
+emergencyCalls TeleserviceCode ::= '00010010'B
+
+allShortMessageServices TeleserviceCode ::= '00100000'B
+shortMessageMT-PP TeleserviceCode ::= '00100001'B
+shortMessageMO-PP TeleserviceCode ::= '00100010'B
+
+allFacsimileTransmissionServices TeleserviceCode ::= '01100000'B
+facsimileGroup3AndAlterSpeech TeleserviceCode ::= '01100001'B
+automaticFacsimileGroup3 TeleserviceCode ::= '01100010'B
+facsimileGroup4 TeleserviceCode ::= '01100011'B
+
+-- The following non-hierarchical Compound Teleservice Groups
+-- are defined in TS 3GPP TS 22.030:
+allDataTeleservices TeleserviceCode ::= '01110000'B
+ -- covers Teleservice Groups 'allFacsimileTransmissionServices'
+ -- and 'allShortMessageServices'
+allTeleservices-ExeptSMS TeleserviceCode ::= '10000000'B
+ -- covers Teleservice Groups 'allSpeechTransmissionServices' and
+ -- 'allFacsimileTransmissionServices'
+--
+-- Compound Teleservice Group Codes are only used in call
+-- independent supplementary service operations, i.e. they
+-- are not used in InsertSubscriberData or in
+-- DeleteSubscriberData messages.
+
+allVoiceGroupCallServices TeleserviceCode ::= '10010000'B
+voiceGroupCall TeleserviceCode ::= '10010001'B
+voiceBroadcastCall TeleserviceCode ::= '10010010'B
+
+allPLMN-specificTS TeleserviceCode ::= '11010000'B
+plmn-specificTS-1 TeleserviceCode ::= '11010001'B
+plmn-specificTS-2 TeleserviceCode ::= '11010010'B
+plmn-specificTS-3 TeleserviceCode ::= '11010011'B
+plmn-specificTS-4 TeleserviceCode ::= '11010100'B
+plmn-specificTS-5 TeleserviceCode ::= '11010101'B
+plmn-specificTS-6 TeleserviceCode ::= '11010110'B
+plmn-specificTS-7 TeleserviceCode ::= '11010111'B
+plmn-specificTS-8 TeleserviceCode ::= '11011000'B
+plmn-specificTS-9 TeleserviceCode ::= '11011001'B
+plmn-specificTS-A TeleserviceCode ::= '11011010'B
+plmn-specificTS-B TeleserviceCode ::= '11011011'B
+plmn-specificTS-C TeleserviceCode ::= '11011100'B
+plmn-specificTS-D TeleserviceCode ::= '11011101'B
+plmn-specificTS-E TeleserviceCode ::= '11011110'B
+plmn-specificTS-F TeleserviceCode ::= '11011111'B
+
+END
diff --git a/lib/asn1/test/asn1_SUITE_data/tcapsystem/MobileDomainDefinitions.asn b/lib/asn1/test/asn1_SUITE_data/tcapsystem/MobileDomainDefinitions.asn
new file mode 100644
index 0000000000..30e7143882
--- /dev/null
+++ b/lib/asn1/test/asn1_SUITE_data/tcapsystem/MobileDomainDefinitions.asn
@@ -0,0 +1,38 @@
+MobileDomainDefinitions {itu-t (0) identified-organization (4) etsi (0)
+ mobileDomain (0) mobileDomainDefinitions (0) version1 (1)}
+
+DEFINITIONS ::=
+
+BEGIN
+
+-- Mobile DomainId
+mobileDomainId OBJECT IDENTIFIER ::=
+ {itu-t (0) identified-organization (4) etsi (0) mobileDomain (0)}
+
+-- Mobile Subdomains
+gsm-NetworkId OBJECT IDENTIFIER ::=
+ {mobileDomainId gsm-Network (1)}
+
+gsm-AccessId OBJECT IDENTIFIER ::=
+ {mobileDomainId gsm-Access (2)}
+
+gsm-OperationAndMaintenanceId OBJECT IDENTIFIER ::=
+ {mobileDomainId gsm-Operation-Maintenance (3)}
+
+gsm-MessagingId OBJECT IDENTIFIER ::=
+ {mobileDomainId gsm-Messaging (4)}
+
+-- Common Component Ids for structuring Mobile Subdomains
+CommonComponentId ::= INTEGER (0..9)
+
+ac-Id CommonComponentId ::= 0
+
+as-Id CommonComponentId ::= 1
+
+ase-Id CommonComponentId ::= 2
+
+moduleId CommonComponentId ::= 3
+
+er-Id CommonComponentId ::= 4
+
+END -- MobileDomainDefinitions \ No newline at end of file
diff --git a/lib/asn1/test/asn1_SUITE_data/tcapsystem/Remote-Operations-Generic-ROS-PDUs.asn b/lib/asn1/test/asn1_SUITE_data/tcapsystem/Remote-Operations-Generic-ROS-PDUs.asn
new file mode 100644
index 0000000000..d4d2eecea1
--- /dev/null
+++ b/lib/asn1/test/asn1_SUITE_data/tcapsystem/Remote-Operations-Generic-ROS-PDUs.asn
@@ -0,0 +1,167 @@
+-- Generated by Asnp, the pretty-printer of France Telecom R&D (http://asn1.elibel.tm.fr/asnp/)
+Remote-Operations-Generic-ROS-PDUs {joint-iso-itu-t remote-operations(4)
+ generic-ROS-PDUs(6) version1(0)}
+
+DEFINITIONS IMPLICIT TAGS
+
+::=
+
+BEGIN
+
+-- exports everything
+IMPORTS
+ OPERATION, ERROR
+ FROM Remote-Operations-Information-Objects {joint-iso-itu-t
+ remote-operations(4) informationObjects(5) version1(0)};
+
+ROS{InvokeId:InvokeIdSet, OPERATION:Invokable, OPERATION:Returnable} ::=
+ CHOICE {
+ invoke [1] Invoke{{InvokeIdSet}, {Invokable}},
+ returnResult [2] ReturnResult{{Returnable}},
+ returnError [3] ReturnError{{Errors {{Returnable}}}},
+ reject [4] Reject
+}
+(CONSTRAINED BY { -- must conform to the above definition --} !
+ RejectProblem:general-unrecognizedPDU)
+
+Invoke{InvokeId:InvokeIdSet, OPERATION:Operations} ::= SEQUENCE {
+ invokeId
+ InvokeId(InvokeIdSet)
+ (CONSTRAINED BY { -- must be unambiguous --} !
+ RejectProblem:invoke-duplicateInvocation),
+ linkedId
+ CHOICE {present [0] IMPLICIT present < InvokeId,
+ absent [1] IMPLICIT NULL
+ }
+ (CONSTRAINED BY { -- must identify an outstanding operation --} !
+ RejectProblem:invoke-unrecognizedLinkedId)
+ (CONSTRAINED BY { -- which has one or more linked operations--} !
+ RejectProblem:invoke-linkedResponseUnexpected) OPTIONAL,
+ opcode
+ OPERATION.&operationCode
+ ({Operations} !RejectProblem:invoke-unrecognizedOperation),
+ argument
+ OPERATION.&ArgumentType
+ ({Operations}{@opcode} !RejectProblem:invoke-mistypedArgument) OPTIONAL
+}
+(CONSTRAINED BY { -- must conform to the above definition --} !
+ RejectProblem:general-mistypedPDU)
+(WITH COMPONENTS {
+ ...,
+ linkedId ABSENT
+ } |
+ WITH COMPONENTS {
+ ...,
+ linkedId PRESENT,
+ opcode (CONSTRAINED BY { -- must be in the &Linked field of the associated operation --
+ } !RejectProblem:invoke-unexpectedLinkedOperation)
+ })
+
+-- continued on the next page
+ReturnResult{OPERATION:Operations} ::= SEQUENCE {
+ invokeId
+ InvokeId
+ (CONSTRAINED BY { -- must be that for an outstanding operation --} !
+ RejectProblem:returnResult-unrecognizedInvocation)
+ (CONSTRAINED BY { -- which returns a result --} !
+ RejectProblem:returnResult-resultResponseUnexpected),
+ result
+ SEQUENCE {opcode
+ OPERATION.&operationCode({Operations})
+ (CONSTRAINED BY { -- identified by invokeId --} !
+ RejectProblem:returnResult-unrecognizedInvocation),
+ result
+ OPERATION.&ResultType
+ ({Operations}{@.opcode} !
+ RejectProblem:returnResult-mistypedResult)} OPTIONAL
+}
+(CONSTRAINED BY { -- must conform to the above definition --} !
+ RejectProblem:general-mistypedPDU)
+
+ReturnError{ERROR:Errors} ::= SEQUENCE {
+ invokeId
+ InvokeId
+ (CONSTRAINED BY { -- must be that for an outstanding operation --} !
+ RejectProblem:returnError-unrecognizedInvocation)
+ (CONSTRAINED BY { -- which returns an error --} !
+ RejectProblem:returnError-errorResponseUnexpected),
+ errcode
+ ERROR.&errorCode({Errors} !RejectProblem:returnError-unrecognizedError)
+ (CONSTRAINED BY { -- must be in the &Errors field of the associated operation --
+ } !RejectProblem:returnError-unexpectedError),
+ parameter
+ ERROR.&ParameterType
+ ({Errors}{@errcode} !RejectProblem:returnError-mistypedParameter)
+ OPTIONAL
+}
+(CONSTRAINED BY { -- must conform to the above definition --} !
+ RejectProblem:general-mistypedPDU)
+
+Reject ::= SEQUENCE {
+ invokeId InvokeId,
+ problem
+ CHOICE {general [0] GeneralProblem,
+ invoke [1] InvokeProblem,
+ returnResult [2] ReturnResultProblem,
+ returnError [3] ReturnErrorProblem}
+}
+(CONSTRAINED BY { -- must conform to the above definition --} !
+ RejectProblem:general-mistypedPDU)
+
+GeneralProblem ::= INTEGER {
+ unrecognizedPDU(0), mistypedPDU(1), badlyStructuredPDU(2)}
+
+-- continued on the next page
+InvokeProblem ::= INTEGER {
+ duplicateInvocation(0), unrecognizedOperation(1), mistypedArgument(2),
+ resourceLimitation(3), releaseInProgress(4), unrecognizedLinkedId(5),
+ linkedResponseUnexpected(6), unexpectedLinkedOperation(7)}
+
+ReturnResultProblem ::= INTEGER {
+ unrecognizedInvocation(0), resultResponseUnexpected(1), mistypedResult(2)
+}
+
+ReturnErrorProblem ::= INTEGER {
+ unrecognizedInvocation(0), errorResponseUnexpected(1), unrecognizedError(2),
+ unexpectedError(3), mistypedParameter(4)}
+
+RejectProblem ::= INTEGER {
+ general-unrecognizedPDU(0), general-mistypedPDU(1),
+ general-badlyStructuredPDU(2), invoke-duplicateInvocation(10),
+ invoke-unrecognizedOperation(11), invoke-mistypedArgument(12),
+ invoke-resourceLimitation(13), invoke-releaseInProgress(14),
+ invoke-unrecognizedLinkedId(15), invoke-linkedResponseUnexpected(16),
+ invoke-unexpectedLinkedOperation(17),
+ returnResult-unrecognizedInvocation(20),
+ returnResult-resultResponseUnexpected(21), returnResult-mistypedResult(22),
+ returnError-unrecognizedInvocation(30),
+ returnError-errorResponseUnexpected(31), returnError-unrecognizedError(32),
+ returnError-unexpectedError(33), returnError-mistypedParameter(34)}
+
+InvokeId ::= CHOICE {present INTEGER,
+ absent NULL
+}
+
+noInvokeId InvokeId ::= absent:NULL
+
+NoInvokeId InvokeId ::= {noInvokeId}
+
+Errors{OPERATION:Operations} ERROR ::= {Operations.&Errors}
+
+-- continued on the next page
+Bind{OPERATION:operation} ::= CHOICE {
+ bind-invoke [16] OPERATION.&ArgumentType({operation}),
+ bind-result [17] OPERATION.&ResultType({operation}),
+ bind-error [18] OPERATION.&Errors.&ParameterType({operation})
+}
+
+Unbind{OPERATION:operation} ::= CHOICE {
+ unbind-invoke [19] OPERATION.&ArgumentType({operation}),
+ unbind-result [20] OPERATION.&ResultType({operation}),
+ unbind-error [21] OPERATION.&Errors.&ParameterType({operation})
+}
+
+END -- end of generic ROS PDU definitions
+
+-- Generated by Asnp, the ASN.1 pretty-printer of France Telecom R&D
+
diff --git a/lib/asn1/test/asn1_SUITE_data/tcapsystem/Remote-Operations-Information-Objects.asn b/lib/asn1/test/asn1_SUITE_data/tcapsystem/Remote-Operations-Information-Objects.asn
new file mode 100644
index 0000000000..74be149bb0
--- /dev/null
+++ b/lib/asn1/test/asn1_SUITE_data/tcapsystem/Remote-Operations-Information-Objects.asn
@@ -0,0 +1,127 @@
+-- Generated by Asnp, the pretty-printer of France Telecom R&D (http://asn1.elibel.tm.fr/asnp/)
+Remote-Operations-Information-Objects {joint-iso-itu-t remote-operations(4)
+ informationObjects(5) version1(0)}
+
+DEFINITIONS
+
+::=
+
+BEGIN
+
+-- exports everything
+IMPORTS
+ emptyBind, emptyUnbind
+ FROM Remote-Operations-Useful-Definitions {joint-iso-itu-t
+ remote-operations(4) useful-definitions(7) version1(0)};
+
+OPERATION ::= CLASS {
+ &ArgumentType OPTIONAL,
+ &argumentTypeOptional BOOLEAN OPTIONAL,
+ &returnResult BOOLEAN DEFAULT TRUE,
+ &ResultType OPTIONAL,
+ &resultTypeOptional BOOLEAN OPTIONAL,
+ &Errors ERROR OPTIONAL,
+ &Linked OPERATION OPTIONAL,
+ &synchronous BOOLEAN DEFAULT FALSE,
+ &alwaysReturns BOOLEAN DEFAULT TRUE,
+ &InvokePriority Priority OPTIONAL,
+ &ResultPriority Priority OPTIONAL,
+ &operationCode Code UNIQUE OPTIONAL
+}
+WITH SYNTAX {
+ [ARGUMENT &ArgumentType
+ [OPTIONAL &argumentTypeOptional]]
+ [RESULT &ResultType
+ [OPTIONAL &resultTypeOptional]]
+ [RETURN RESULT &returnResult]
+ [ERRORS &Errors]
+ [LINKED &Linked]
+ [SYNCHRONOUS &synchronous]
+ [ALWAYS RESPONDS &alwaysReturns]
+ [INVOKE PRIORITY &InvokePriority]
+ [RESULT-PRIORITY &ResultPriority]
+ [CODE &operationCode]
+}
+
+ERROR ::= CLASS {
+ &ParameterType OPTIONAL,
+ &parameterTypeOptional BOOLEAN OPTIONAL,
+ &ErrorPriority Priority OPTIONAL,
+ &errorCode Code UNIQUE OPTIONAL
+}
+WITH SYNTAX {
+ [PARAMETER &ParameterType
+ [OPTIONAL &parameterTypeOptional]]
+ [PRIORITY &ErrorPriority]
+ [CODE &errorCode]
+}
+
+OPERATION-PACKAGE ::= CLASS {
+ &Both OPERATION OPTIONAL,
+ &Consumer OPERATION OPTIONAL,
+ &Supplier OPERATION OPTIONAL,
+ &id OBJECT IDENTIFIER UNIQUE OPTIONAL
+}
+-- continued on the next page
+WITH SYNTAX {
+ [OPERATIONS &Both]
+ [CONSUMER INVOKES &Supplier]
+ [SUPPLIER INVOKES &Consumer]
+ [ID &id]
+}
+
+CONNECTION-PACKAGE ::= CLASS {
+ &bind OPERATION DEFAULT emptyBind,
+ &unbind OPERATION DEFAULT emptyUnbind,
+ &responderCanUnbind BOOLEAN DEFAULT FALSE,
+ &unbindCanFail BOOLEAN DEFAULT FALSE,
+ &id OBJECT IDENTIFIER UNIQUE OPTIONAL
+}
+WITH SYNTAX {
+ [BIND &bind]
+ [UNBIND &unbind]
+ [RESPONDER UNBIND &responderCanUnbind]
+ [FAILURE TO UNBIND &unbindCanFail]
+ [ID &id]
+}
+
+CONTRACT ::= CLASS {
+ &connection CONNECTION-PACKAGE OPTIONAL,
+ &OperationsOf OPERATION-PACKAGE OPTIONAL,
+ &InitiatorConsumerOf OPERATION-PACKAGE OPTIONAL,
+ &InitiatorSupplierOf OPERATION-PACKAGE OPTIONAL,
+ &id OBJECT IDENTIFIER UNIQUE OPTIONAL
+}
+WITH SYNTAX {
+ [CONNECTION &connection]
+ [OPERATIONS OF &OperationsOf]
+ [INITIATOR CONSUMER OF &InitiatorConsumerOf]
+ [RESPONDER CONSUMER OF &InitiatorSupplierOf]
+ [ID &id]
+}
+
+ROS-OBJECT-CLASS ::= CLASS {
+ &Is ROS-OBJECT-CLASS OPTIONAL,
+ &Initiates CONTRACT OPTIONAL,
+ &Responds CONTRACT OPTIONAL,
+ &InitiatesAndResponds CONTRACT OPTIONAL,
+ &id OBJECT IDENTIFIER UNIQUE
+}
+WITH SYNTAX {
+ [IS &Is]
+ [BOTH &InitiatesAndResponds]
+ [INITIATES &Initiates]
+ [RESPONDS &Responds]
+ ID &id
+}
+
+Code ::= CHOICE {local INTEGER,
+ global OBJECT IDENTIFIER
+}
+
+Priority ::= INTEGER(0..MAX)
+
+END -- end of Information Object specifications
+
+-- Generated by Asnp, the ASN.1 pretty-printer of France Telecom R&D
+
diff --git a/lib/asn1/test/asn1_SUITE_data/tcapsystem/Remote-Operations-Useful-Definitions.asn b/lib/asn1/test/asn1_SUITE_data/tcapsystem/Remote-Operations-Useful-Definitions.asn
new file mode 100644
index 0000000000..714b96b5c3
--- /dev/null
+++ b/lib/asn1/test/asn1_SUITE_data/tcapsystem/Remote-Operations-Useful-Definitions.asn
@@ -0,0 +1,99 @@
+-- Generated by Asnp, the pretty-printer of France Telecom R&D (http://asn1.elibel.tm.fr/asnp/)
+Remote-Operations-Useful-Definitions {joint-iso-itu-t remote-operations(4)
+ useful-definitions(7) version1(0)}
+
+DEFINITIONS IMPLICIT TAGS
+
+::=
+
+BEGIN
+
+-- exports everything
+IMPORTS
+ OPERATION, ERROR, OPERATION-PACKAGE, Code
+ FROM Remote-Operations-Information-Objects {joint-iso-itu-t
+ remote-operations(4) informationObjects(5) version1(0)}
+ InvokeId, ROS{}
+ FROM Remote-Operations-Generic-ROS-PDUs {joint-iso-itu-t
+ remote-operations(4) generic-ROS-PDUs(6) version1(0)};
+
+emptyBind OPERATION ::= {ERRORS {refuse}
+ SYNCHRONOUS TRUE
+}
+
+emptyUnbind OPERATION ::= {SYNCHRONOUS TRUE
+}
+
+refuse ERROR ::= {CODE local:-1
+}
+
+no-op OPERATION ::= {ALWAYS RESPONDS FALSE
+ CODE local:-1
+}
+
+Forward{OPERATION:OperationSet} OPERATION ::=
+ {OperationSet | OperationSet.&Linked.&Linked |
+ OperationSet.&Linked.&Linked.&Linked.&Linked}
+
+Reverse{OPERATION:OperationSet} OPERATION ::= {Forward{{OperationSet.&Linked}}}
+
+ConsumerPerforms{OPERATION-PACKAGE:package} OPERATION ::=
+ {Forward{{package.&Consumer}} | Forward{{package.&Both}} |
+ Reverse{{package.&Supplier}} | Reverse{{package.&Both}}}
+
+SupplierPerforms{OPERATION-PACKAGE:package} OPERATION ::=
+ {Forward{{package.&Supplier}} | Forward{{package.&Both}} |
+ Reverse{{package.&Consumer}} | Reverse{{package.&Both}}}
+
+AllOperations{OPERATION-PACKAGE:package} OPERATION ::=
+ {ConsumerPerforms{package} | SupplierPerforms{package}}
+
+-- continued on the next page
+recode{OPERATION:operation, Code:code} OPERATION ::= {
+ ARGUMENT operation.&ArgumentType
+ OPTIONAL operation.&argumentTypeOptional
+ RESULT operation.&ResultType
+ OPTIONAL operation.&resultTypeOptional
+ RETURN RESULT operation.&returnResult
+ ERRORS {operation.&Errors}
+ LINKED {operation.&Linked}
+ SYNCHRONOUS operation.&synchronous
+ ALWAYS RESPONDS operation.&alwaysReturns
+ INVOKE PRIORITY {operation.&InvokePriority}
+ RESULT-PRIORITY {operation.&ResultPriority}
+ CODE code
+}
+
+switch{OPERATION-PACKAGE:package, OBJECT IDENTIFIER:id} OPERATION-PACKAGE ::=
+{
+ OPERATIONS {package.&Both}
+ CONSUMER INVOKES {package.&Consumer}
+ SUPPLIER INVOKES {package.&Supplier}
+ ID id
+}
+
+combine{OPERATION-PACKAGE:ConsumerConsumes, OPERATION-PACKAGE:ConsumerSupplies,
+ OPERATION-PACKAGE:base} OPERATION-PACKAGE ::= {
+ OPERATIONS {ConsumerConsumes.&Both | ConsumerSupplies.&Both}
+ CONSUMER INVOKES {ConsumerConsumes.&Consumer | ConsumerSupplies.&Supplier}
+ SUPPLIER INVOKES {ConsumerConsumes.&Supplier | ConsumerSupplies.&Consumer}
+ ID base.&id
+}
+
+ROS-SingleAS{InvokeId:InvokeIdSet, OPERATION-PACKAGE:package} ::=
+ ROS{{InvokeIdSet}, {AllOperations {package}}, {AllOperations {package}}}
+
+ROS-ConsumerAS{InvokeId:InvokeIdSet, OPERATION-PACKAGE:package} ::=
+ ROS
+ {{InvokeIdSet}, {ConsumerPerforms {package}},
+ {SupplierPerforms {package}}}
+
+ROS-SupplierAS{InvokeId:InvokeIdSet, OPERATION-PACKAGE:package} ::=
+ ROS
+ {{InvokeIdSet}, {SupplierPerforms {package}},
+ {ConsumerPerforms {package}}}
+
+END -- end of useful definitions.
+
+-- Generated by Asnp, the ASN.1 pretty-printer of France Telecom R&D
+
diff --git a/lib/asn1/test/asn1_SUITE_data/tcapsystem/TC-Notation-Extensions.asn b/lib/asn1/test/asn1_SUITE_data/tcapsystem/TC-Notation-Extensions.asn
new file mode 100644
index 0000000000..89bfd105ef
--- /dev/null
+++ b/lib/asn1/test/asn1_SUITE_data/tcapsystem/TC-Notation-Extensions.asn
@@ -0,0 +1,87 @@
+-- Module TC-Notation-Extensions (Q.775:06/1997)
+
+TC-Notation-Extensions {itu-t recommendation q 775 modules(2)
+ notation-extension(4) version1(1)} DEFINITIONS ::=
+BEGIN
+
+IMPORTS
+ TCMessage{}
+ FROM TCAPMessages {itu-t recommendation q 773 modules(2) messages(1)
+ version3(3)}
+ Bind{}, Unbind{}
+ FROM Remote-Operations-Generic-ROS-PDUs {joint-iso-itu-t
+ remote-operations(4) generic-ROS-PDUs(6) version1(0)}
+ AllOperations{}, ConsumerPerforms{}, SupplierPerforms{}, combine{}
+ FROM Remote-Operations-Useful-Definitions {joint-iso-itu-t
+ remote-operations(4) useful-definitions(7) version1(0)}
+ CONTRACT, OPERATION-PACKAGE
+ FROM Remote-Operations-Information-Objects {joint-iso-itu-t
+ remote-operations(4) informationObjects(5) version1(0)}
+ UniDialoguePDU, uniDialogue-as-id
+ FROM UnidialoguePDUs {itu-t recommendation q 773 modules(2)
+ unidialoguePDUs(3) version1(1)}
+ DialoguePDU, dialogue-as-id
+ FROM DialoguePDUs {itu-t recommendation q 773 modules(2) dialoguePDUs(2)
+ version1(1)};
+
+APPLICATION-CONTEXT ::= CLASS {
+ &associationContract CONTRACT,
+ &dialogueMode DialogueMode,
+ &termination Termination OPTIONAL,
+ &componentGrouping BOOLEAN DEFAULT TRUE,
+ &dialogueAndComponentGrouping BOOLEAN DEFAULT TRUE,
+ &AdditionalASEs OBJECT IDENTIFIER OPTIONAL,
+ &AbstractSyntaxes ABSTRACT-SYNTAX,
+ &applicationContextName OBJECT IDENTIFIER UNIQUE
+}
+WITH SYNTAX {
+ CONTRACT &associationContract
+ DIALOGUE MODE &dialogueMode
+ [TERMINATION &termination]
+ [COMPONENT GROUPING ALLOWED &componentGrouping]
+ [DIALOGUE WITH COMPONENTS ALLOWED &dialogueAndComponentGrouping]
+ [ADDITIONAL ASES &AdditionalASEs]
+ ABSTRACT SYNTAXES &AbstractSyntaxes
+ APPLICATION CONTEXT NAME &applicationContextName
+}
+
+DialogueMode ::= ENUMERATED {structured(1), unstructured(2)}
+
+Termination ::= ENUMERATED {basic(1), prearranged(2)}
+
+dialogue-abstract-syntax ABSTRACT-SYNTAX ::= {
+ DialoguePDU
+ IDENTIFIED BY dialogue-as-id
+}
+
+uniDialogue-abstract-syntax ABSTRACT-SYNTAX ::= {
+ UniDialoguePDU
+ IDENTIFIED BY uniDialogue-as-id
+}
+
+TCSingleAS{OPERATION-PACKAGE:package} ::=
+ TCMessage{{AllOperations {package}}, {AllOperations {package}}}
+
+TCConsumerAS{OPERATION-PACKAGE:package} ::=
+ TCMessage{{ConsumerPerforms {package}}, {ConsumerPerforms {package}}}
+
+TCSupplierAS{OPERATION-PACKAGE:package} ::=
+ TCMessage{{SupplierPerforms {package}}, {SupplierPerforms {package}}}
+
+AllPackagesAS{APPLICATION-CONTEXT:ac} ::=
+ TCSingleAS
+ {combine{{ac.&associationContract.&OperationsOf |
+ ac.&associationContract.&InitiatorConsumerOf |
+ ac.&associationContract.&InitiatorSupplierOf},
+ {...}, --was illegaly empty, needs to be changed
+ { -- Information Object of class OPERATION-PACKAGE to be defined --}}}
+
+ConnectionAS{APPLICATION-CONTEXT:ac} ::= CHOICE {
+ bind Bind{ac.&associationContract.&connection.&bind},
+ unbind Unbind{ac.&associationContract.&connection.&unbind}
+}
+
+END
+
+-- Generated by Asnp, the ASN.1 pretty-printer of France Telecom R&D
+
diff --git a/lib/asn1/test/asn1_SUITE_data/tcapsystem/TCAP-Examples.asn b/lib/asn1/test/asn1_SUITE_data/tcapsystem/TCAP-Examples.asn
new file mode 100644
index 0000000000..17667af920
--- /dev/null
+++ b/lib/asn1/test/asn1_SUITE_data/tcapsystem/TCAP-Examples.asn
@@ -0,0 +1,72 @@
+-- Generated by Asnp, the pretty-printer of France Telecom R&D (http://asn1.elibel.tm.fr/asnp/)
+TCAP-Examples {itu-t recommendation q 775 modules(2) examples(2) version1(1)}
+DEFINITIONS ::=
+BEGIN
+
+IMPORTS
+ OPERATION, ERROR
+ FROM Remote-Operations-Information-Objects {joint-iso-itu-t
+ remote-operations(4) informationObjects(5) version1(0)};
+
+provideRoutingInformation OPERATION ::= {
+ ARGUMENT RequestArgument
+ RESULT RoutingInformation
+ ERRORS
+ {invalidCalledNumber | subscriberNotReachable | calledBarred |
+ processingFailure}
+ LINKED {getCallingPartyAddress}
+}
+
+-- timer T-pi = 10 s
+getCallingPartyAddress OPERATION ::= {
+ RESULT CallingPartyAddress
+ ERRORS {callingPartyAddressNotAvailable | processingFailure}
+}
+
+-- timer T-gp = 5 s
+invalidCalledNumber ERROR ::= {CODE local:1
+}
+
+subscriberNotReachable ERROR ::= {CODE local:2
+}
+
+calledBarred ERROR ::= {CODE local:3
+}
+
+callingPartyAddressNotAvailable ERROR ::= {CODE local:4
+}
+
+processingFailure ERROR ::= {CODE local:5
+}
+
+-- data types
+RequestArgument ::= SEQUENCE {
+ calledNumber IsdnNumber,
+ basicService BasicServiceIndicator OPTIONAL
+}
+
+RoutingInformation ::= CHOICE {
+ reroutingNumber [0] IMPLICIT IsdnNumber,
+ forwardedToNumber [1] IMPLICIT IsdnNumber
+}
+
+BasicServiceIndicator ::= ENUMERATED {speech(0), unrestrictedDigital(1)}
+
+CallingPartyAddress ::= IsdnNumber
+
+IsdnNumber ::= SEQUENCE {
+ typeOfAddress TypeOfAddress,
+ digits TelephonyString
+}
+
+TypeOfAddress ::= ENUMERATED {national(0), international(1), private(2)}
+
+TelephonyString ::=
+ IA5String
+ (FROM ("0" | "1" | "2" | "3" | "4" | "5" | "6" | "7" | "8" | "9" | "*" |
+ "#"))(SIZE (1..15))
+
+END
+
+-- Generated by Asnp, the ASN.1 pretty-printer of France Telecom R&D
+
diff --git a/lib/asn1/test/asn1_SUITE_data/tcapsystem/TCAP-Tools.asn b/lib/asn1/test/asn1_SUITE_data/tcapsystem/TCAP-Tools.asn
new file mode 100644
index 0000000000..09ea9d936f
--- /dev/null
+++ b/lib/asn1/test/asn1_SUITE_data/tcapsystem/TCAP-Tools.asn
@@ -0,0 +1,47 @@
+-- Generated by Asnp, the pretty-printer of France Telecom R&D (http://asn1.elibel.tm.fr/asnp/)
+TCAP-Tools {itu-t recommendation q 775 modules(2) tools(1) version1(1)}
+DEFINITIONS ::=
+BEGIN
+
+EXPORTS
+ cancel,
+ cancelFailed,
+ cancelled
+;
+
+IMPORTS
+ OPERATION, ERROR
+ FROM Remote-Operations-Information-Objects {joint-iso-itu-t
+ remote-operations(4) informationObjects(5) version1(0)}
+
+ TCInvokeIdSet
+ FROM TCAPMessages {itu-t recommendation q 773 modules(2) messages(1)
+ version3(3)}
+;
+
+cancel OPERATION ::= {
+ ARGUMENT present < TCInvokeIdSet
+ -- a TC-user may redefine this type to include
+ -- an empty result so that it becomes a Class 1 operation
+ ERRORS {cancelFailed}
+}
+
+-- timer = 15 s
+cancelFailed ERROR ::= {
+ PARAMETER
+ SET {problem [0] CancelProblem,
+ invokeId [1] present < TCInvokeIdSet}
+}
+
+CancelProblem ::= ENUMERATED {
+ unknownInvocation(0), tooLate(1), notCancellable(2)}
+
+-- a TC-user may redefine this type to include application-specific problems
+cancelled ERROR ::=
+ {}
+
+-- an error of this type should be included in the error list of cancellable operations
+END
+
+-- Generated by Asnp, the ASN.1 pretty-printer of France Telecom R&D
+
diff --git a/lib/asn1/test/asn1_SUITE_data/tcapsystem/TCAPMessages.asn b/lib/asn1/test/asn1_SUITE_data/tcapsystem/TCAPMessages.asn
new file mode 100644
index 0000000000..906cac23c8
--- /dev/null
+++ b/lib/asn1/test/asn1_SUITE_data/tcapsystem/TCAPMessages.asn
@@ -0,0 +1,149 @@
+-- Generated by Asnp, the pretty-printer of France Telecom R&D (http://asn1.elibel.tm.fr/asnp/)
+-- Module TCAPMessages (Q.773:06/1997)
+-- asn1ct:compile("TCAPMessages",[ber_bin]).
+TCAPMessages {itu-t recommendation q 773 modules(2) messages(1) version3(3)}
+
+DEFINITIONS IMPLICIT TAGS
+
+::=
+
+BEGIN
+
+-- EXPORTS everything
+-- Transaction Portion fields.
+IMPORTS
+ ROS{}, InvokeId
+ FROM Remote-Operations-Generic-ROS-PDUs {joint-iso-itu-t
+ remote-operations(4) generic-ROS-PDUs(6) version1(0)}
+ OPERATION
+ FROM Remote-Operations-Information-Objects {joint-iso-itu-t
+ remote-operations(4) informationObjects(5) version1(0)}
+ Supported-MAP-Operations
+ FROM MAP-Protocol {itu-t identified-organization (4) etsi (0) mobileDomain (0)
+ gsm-Network (1) modules (3) map-Protocol (4) version9 (9)}
+-- Start - Added by Eranga
+ dialogue-as-id
+ FROM DialoguePDUs {itu-t recommendation q 773 modules(2) dialoguePDUs(2)
+ version1(1)}
+ sendRoutingInfoForSM,
+ mo-ForwardSM,
+ mt-ForwardSM,
+ reportSM-DeliveryStatus,
+ alertServiceCentre,
+ informServiceCentre,
+ readyForSM
+ FROM MAP-ShortMessageServiceOperations {
+ itu-t identified-organization (4) etsi (0) mobileDomain (0)
+ gsm-Network (1) modules (3) map-ShortMessageServiceOperations (9)
+ version9 (9)}
+ gsm-MessagingId
+ FROM MobileDomainDefinitions {
+ itu-t identified-organization (4) etsi (0) mobileDomain (0)
+ mobileDomainDefinitions (0) version1 (1)}
+ Supported-MAP-Operations
+ FROM MAP-Protocol {
+ itu-t identified-organization (4) etsi (0) mobileDomain (0)
+ gsm-Network (1) modules (3) map-Protocol (4) version9 (9)}
+-- End - Added by Eranga
+;
+
+-- Start - Added by Eranga
+
+mapSpecificAS ABSTRACT-SYNTAX ::= {
+ MapSpecificPDUs
+ IDENTIFIED BY gsm-MessagingId
+}
+
+MapSpecificPDUs ::=
+ TCMessage{{MAPOperations-Invokable}, {MAPOperations-Returnable}}
+
+
+MAPOperations-Invokable OPERATION ::=
+ {sendRoutingInfoForSM | mo-ForwardSM | mt-ForwardSM}
+MAPOperations-Returnable OPERATION ::=
+ {reportSM-DeliveryStatus | alertServiceCentre | informServiceCentre | readyForSM}
+
+-- End - Added by Eranga
+
+
+TCMessage{OPERATION:Invokable, OPERATION:Returnable} ::= CHOICE {
+ unidirectional [APPLICATION 1] Unidirectional{{Invokable}, {Returnable}},
+ begin [APPLICATION 2] Begin{{Invokable}, {Returnable}},
+ end [APPLICATION 4] End{{Invokable}, {Returnable}},
+ continue [APPLICATION 5] Continue{{Invokable}, {Returnable}},
+ abort [APPLICATION 7] Abort
+}
+
+Unidirectional{OPERATION:Invokable, OPERATION:Returnable} ::= SEQUENCE {
+ dialoguePortion DialoguePortion OPTIONAL,
+ components ComponentPortion{{Invokable}, {Returnable}}
+}
+
+Begin{OPERATION:Invokable, OPERATION:Returnable} ::= SEQUENCE {
+ otid OrigTransactionID,
+ dialoguePortion DialoguePortion OPTIONAL,
+ components ComponentPortion{{Invokable}, {Returnable}} OPTIONAL
+}
+
+End{OPERATION:Invokable, OPERATION:Returnable} ::= SEQUENCE {
+ dtid DestTransactionID,
+ dialoguePortion DialoguePortion OPTIONAL,
+ components ComponentPortion{{Invokable}, {Returnable}} OPTIONAL
+}
+
+Continue{OPERATION:Invokable, OPERATION:Returnable} ::= SEQUENCE {
+ otid OrigTransactionID,
+ dtid DestTransactionID,
+ dialoguePortion DialoguePortion OPTIONAL,
+ components ComponentPortion{{Invokable}, {Returnable}} OPTIONAL
+}
+
+Abort ::= SEQUENCE {
+ dtid DestTransactionID,
+ reason CHOICE {p-abortCause P-AbortCause,
+ u-abortCause DialoguePortion} OPTIONAL
+}
+
+-- NOTE - When the Abort Message is generated by the Transaction sublayer, a p-Abort Cause may be
+-- present. The u-abortCause may be generated by the component sublayer in which case it is an ABRT
+-- APDU, or by the TC-User in which case it could be either an ABRT APDU or data in some user-defined
+-- abstract syntax.
+DialoguePortion ::= [APPLICATION 11] EXPLICIT EXTERNAL
+
+-- The dialogue portion carries the dialogue control PDUs as value of the external data type. The direct
+-- reference should be set to {itu-t recommendation q 773 as(1) dialogue-as(1) version1(1)} if structured
+-- dialogue is used and to {itu-t recommendation q 773 as(1) unidialogue-as(2) version1(1)} if unstructured
+-- dialogue is used.
+OrigTransactionID ::= [APPLICATION 8] OCTET STRING(SIZE (1..4))
+
+DestTransactionID ::= [APPLICATION 9] OCTET STRING(SIZE (1..4))
+
+P-AbortCause ::= [APPLICATION 10] INTEGER {
+ unrecognizedMessageType(0), unrecognizedTransactionID(1),
+ badlyFormattedTransactionPortion(2), incorrectTransactionPortion(3),
+ resourceLimitation(4)}(0..127)
+
+-- COMPONENT PORTION. The last field in the transaction portion of the TCAP message is the
+-- component portion. The component portion may be absent.
+ComponentPortion{OPERATION:Invokable, OPERATION:Returnable} ::=
+ [APPLICATION 12]
+ SEQUENCE SIZE (1..MAX) OF Component{{Invokable}, {Returnable}}
+
+-- Component Portion fields
+-- Recommendation X.880 defines four Application Protocol Data Units (APDUs) for invoking
+-- operations, returning results or error, and for the rejection of invalid PDUs.
+-- TCAP adds returnResultNotLast to allow for the segmentation of a result.
+Component{OPERATION:Invokable, OPERATION:Returnable} ::= CHOICE {
+ basicROS ROS{{TCInvokeIdSet}, {Invokable}, {Returnable}},
+ returnResultNotLast
+ [7] returnResult < ROS{{TCInvokeIdSet}, {Invokable}, {Returnable}}
+}
+
+TCInvokeIdSet ::= InvokeId(WITH COMPONENTS {
+ present (-128..127)
+ })
+
+END -- TCAPMessages
+
+-- Generated by Asnp, the ASN.1 pretty-printer of France Telecom R&D
+
diff --git a/lib/asn1/test/asn1_SUITE_data/tcapsystem/UnidialoguePDUs.asn b/lib/asn1/test/asn1_SUITE_data/tcapsystem/UnidialoguePDUs.asn
new file mode 100644
index 0000000000..4244cc8e65
--- /dev/null
+++ b/lib/asn1/test/asn1_SUITE_data/tcapsystem/UnidialoguePDUs.asn
@@ -0,0 +1,26 @@
+-- Generated by Asnp, the pretty-printer of France Telecom R&D (http://asn1.elibel.tm.fr/asnp/)
+-- Module UnidialoguePDUs (Q.773:06/1997)
+UnidialoguePDUs {itu-t recommendation q 773 modules(2) unidialoguePDUs(3)
+ version1(1)} DEFINITIONS ::=
+BEGIN
+
+EXPORTS uniDialogue-as-id, UniDialoguePDU;
+
+-- Abstract syntax name for unstructured dialogue APDUs
+uniDialogue-as-id OBJECT IDENTIFIER ::=
+ {itu-t recommendation q 773 as(1) unidialogue-as(2) version1(1)}
+
+UniDialoguePDU ::= CHOICE {unidialoguePDU AUDT-apdu
+}
+
+AUDT-apdu ::= [APPLICATION 0] IMPLICIT SEQUENCE {
+ protocol-version
+ [0] IMPLICIT BIT STRING {version1(0)} DEFAULT {version1},
+ application-context-name [1] OBJECT IDENTIFIER,
+ user-information [30] IMPLICIT SEQUENCE OF EXTERNAL OPTIONAL
+}
+
+END -- UNIDialoguePDU
+
+-- Generated by Asnp, the ASN.1 pretty-printer of France Telecom R&D
+
diff --git a/lib/asn1/test/asn1_SUITE_data/test_records.erl b/lib/asn1/test/asn1_SUITE_data/test_records.erl
new file mode 100644
index 0000000000..b2c9797fdc
--- /dev/null
+++ b/lib/asn1/test/asn1_SUITE_data/test_records.erl
@@ -0,0 +1,87 @@
+%%
+%% %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%
+%%
+%%
+
+-module(test_records).
+
+-export(['check_record_names_OTP-5812'/1]).
+
+%-include("test_server.hrl").
+%-include_lib("test_server/include/test_server.hrl").
+
+-define(line,put(test_server_loc,{?MODULE,?LINE}),).
+
+-include("NBAP-PDU-Discriptions.hrl").
+-include("NBAP-PDU-Contents.hrl").
+-include("NBAP-Containers.hrl").
+-include("NBAP-CommonDataTypes.hrl").
+-include("NBAP-IEs.hrl").
+
+
+
+
+'check_record_names_OTP-5812'(Msg) ->
+ io:format("Msg: ~n~p~n",[Msg]),
+ check_record_names(Msg).
+
+check_record_names({initiatingMessage,
+ #'InitiatingMessage'{procedureID = ProcedureID,
+ criticality = _Criticality,
+ messageDiscriminator = _MessageDisc,
+ transactionID = _TransactionID,
+ value = Value}}) ->
+
+ ?line ok = check_record_ProcedureID(ProcedureID),
+ ?line ok = check_record_Value(Value).
+
+check_record_ProcedureID(#'ProcedureID'{}) ->
+ ok;
+check_record_ProcedureID(_) -> false.
+
+check_record_Value(#'ResourceStatusIndication'{protocolIEs = ProtocolIEs}) ->
+ ?line ok = check_record_ProtocolIEs(ProtocolIEs);
+check_record_Value(_) -> false.
+
+check_record_ProtocolIEs([#'ProtocolIE-Field'{value =IndicationType}|_]) ->
+ ?line ok = check_record_NFResourceStatusInd(IndicationType);
+check_record_ProtocolIEs(_) -> false.
+
+check_record_NFResourceStatusInd({'no-Failure',#'No-Failure-ResourceStatusInd'{'local-Cell-InformationList'=[LCIPF]}}) ->
+ 'check_record_NFResourceStatusInd_ProtocolIE-Field'(LCIPF);
+check_record_NFResourceStatusInd(_) -> false.
+
+'check_record_NFResourceStatusInd_ProtocolIE-Field'(#'ProtocolIE-Field'{value=LCI}) ->
+ ?line ok = check_record_LCInfoResourceStatusInd(LCI);
+'check_record_NFResourceStatusInd_ProtocolIE-Field'(_) -> false.
+
+check_record_LCInfoResourceStatusInd(#'Local-Cell-InformationItem-ResourceStatusInd'{commonChannelsCapacityConsumptionLaw=[CCCCL],dedicatedChannelsCapacityConsumptionLaw=[DCCCL],'iE-Extensions' = [LCIRE]}) ->
+ ?line ok = check_record_CCCCL(CCCCL),
+ ?line ok = check_record_DCCCL(DCCCL),
+ ?line ok = check_record_LCIRE(LCIRE).
+
+check_record_CCCCL(#'CommonChannelsCapacityConsumptionLaw_SEQOF'{}) ->
+ ok;
+check_record_CCCCL(_) -> false.
+
+check_record_DCCCL(#'DedicatedChannelsCapacityConsumptionLaw_SEQOF'{}) ->
+ ok;
+check_record_DCCCL(_) -> false.
+check_record_LCIRE(#'ProtocolExtensionField'{}) ->
+ ok;
+check_record_LCIRE(_) -> false.
diff --git a/lib/asn1/test/asn1_SUITE_data/testobj.erl b/lib/asn1/test/asn1_SUITE_data/testobj.erl
new file mode 100644
index 0000000000..be7ceee7d1
--- /dev/null
+++ b/lib/asn1/test/asn1_SUITE_data/testobj.erl
@@ -0,0 +1,1443 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 2001-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(testobj).
+
+-include("RANAP.hrl").
+
+-compile(export_all).
+
+-define(ranap, 'RANAP').
+
+
+%% These are possible Reason-values for sccp_disconnect_req in RANPM
+%%
+%% 0,0,0,0,0,1,0,0, % Message-type
+%% 0,0,0,0,0,0,0,0, % Dest local ref (dummy) - 3 octets
+%% 0,0,0,0,0,0,0,0,
+%% 0,0,0,0,0,0,0,1,
+%% 0,0,0,0,0,0,0,0, % Source local ref (dummy) - 3 octets
+%% 0,0,0,0,0,0,0,0,
+%% 0,0,0,0,0,0,1,0,
+
+run() ->
+ ok = run_com_id(),
+ ok = run_dir_tsf_2cn(),
+ ok = run_dir_tsf_2rnc(),
+ ok = run_init_ue(),
+ ok = run_iu_rel_cmd(),
+ ok = run_iu_rel_cmp(),
+ ok = run_rab_ass_rsp_delete(),
+ ok = run_rab_ass_rsp_setup(),
+ ok = run_rab_create(),
+ ok = run_rab_rel(),
+ ok = run_reset(),
+ ok = run_reset_res(),
+ ok = run_sm_cmd(),
+ ok = run_sm_cmp(),
+ ok = run_sm_rej().
+
+
+ranap_pdu_contents(Enc,Type) ->
+ {initiatingMessage, #'InitiatingMessage'{
+ procedureCode = Type,
+ criticality = ignore, %{'Criticality', ignore}, %XXX
+ value = Enc
+ }}.
+
+ranap_pdu_contents_outcome(Enc,Type) ->
+ {outcome, #'Outcome'{
+ procedureCode = Type,
+ criticality = ignore,%XXX
+ value = Enc
+ }}.
+
+ranap_pdu_contents_suc(Enc,Type) ->
+ {successfulOutcome, #'SuccessfulOutcome'{
+ procedureCode = Type,
+ criticality = ignore,%XXX
+ value = Enc
+ }}.
+
+ranap_pdu_contents_unsuc(Enc,Type) ->
+ {unsuccessfulOutcome, #'UnsuccessfulOutcome'{
+ procedureCode = Type,
+ criticality = ignore,%XXX
+ value = Enc
+ }}.
+
+
+
+run_rab_rel() ->
+ RAS = rab_release_request(),
+ io:format("~w~n~n", [RAS]),
+ RanapRAS = ranap_pdu_contents(RAS,0), % 0=Rab Assignment Procedure
+ {ok, Tmp2} = wrapper_encode(?ranap, 'RANAP-PDU', RanapRAS),
+ EncRanapRAS = lists:flatten(Tmp2),
+ io:format("~w~n~n", [EncRanapRAS]),
+ {ok,{initiatingMessage,
+ #'InitiatingMessage'{procedureCode=ProcedureCode,
+ criticality=Criticality,
+ value=DecGeneral}}} =
+ wrapper_decode(?ranap, 'RANAP-PDU', EncRanapRAS),
+ io:format("~w~n~n", [DecGeneral]),
+ case DecGeneral of
+ {'RAB-AssignmentRequest',[{_ProtIEField,_Code,_Crit,DecRel}],_ASN1novalue} ->
+ io:format("~w~n~n", [DecRel])
+ end,
+ case DecRel of
+ [[{_ProtIEField1,_Code1,_Crit1,DecRelList}]] ->
+ io:format("~w~n~n", [DecRelList])
+ end,
+ ok.
+
+run_rab_create() ->
+ RabID = [0,1,0,1,0,1,0,1],
+ Teid = [0,13,83,211],
+ SgsnIP = [0,0,0,0,1,1,0,1,0,0,0,0,1,1,0,0,0,0,0,0,1,0,1,1,0,0,0,0,1,0,1,0],
+ RAS = rab_create_request(RabID, Teid, SgsnIP),
+ io:format("~w~n~n", [RAS]),
+ RanapRAS = ranap_pdu_contents(RAS,0), % 0=Rab Assignment Procedure
+ {ok, Tmp2} = wrapper_encode(?ranap, 'RANAP-PDU', RanapRAS),
+ EncRanapRAS = lists:flatten(Tmp2),
+ io:format("~w~n~n", [EncRanapRAS]),
+ {ok,{initiatingMessage,
+ #'InitiatingMessage'{procedureCode=ProcedureCode,
+ criticality=Criticality,
+ value=DecGeneral}}} =
+ wrapper_decode(?ranap, 'RANAP-PDU', EncRanapRAS),
+ io:format("~w~n~n", [DecGeneral]),
+ case DecGeneral of
+ {'RAB-AssignmentRequest',[{_ProtIEField,_Code,_Crit,DecSetOrMod}],_ASN1novalue} ->
+ io:format("~w~n~n", [DecSetOrMod])
+ end,
+ case DecSetOrMod of
+ [[{'ProtocolIE-FieldPair',_Code1,_Crit1,DecSetOrModFirst,_Crit2,DecSetOrModSecond}]] ->
+ io:format("~w~n~n", [DecSetOrModFirst]),
+ io:format("~w~n~n", [DecSetOrModSecond])
+ end,
+ ok.
+
+decode_initiating_ras(ProcedureCode,Crit,Val) ->
+ case ProcedureCode of
+ 0 -> % RAB-Assignment
+ wrapper_decode(?ranap, 'RAB-AssignmentRequest',Val)
+ end.
+
+
+run_rab_ass_rsp_setup() ->
+ RAR = rab_assignment_response_setup(),
+ io:format("~w~n~n", [RAR]),
+ RanapRAR = ranap_pdu_contents_outcome(RAR,0), % 0=Rab Assignment Procedure
+ {ok, Tmp2} = wrapper_encode(?ranap, 'RANAP-PDU', RanapRAR),
+ EncRanapRAR = lists:flatten(Tmp2),
+ io:format("~w~n~n", [EncRanapRAR]),
+ {ok,{outcome,
+ #'Outcome'{procedureCode=ProcedureCode,
+ criticality=Criticality,
+ value=DecGeneral}}} =
+ wrapper_decode(?ranap, 'RANAP-PDU', EncRanapRAR),
+ io:format("~w~n~n", [DecGeneral]),
+ case DecGeneral of
+ {'RAB-AssignmentResponse',[{_ProtIEField,52,_Crit,DecSetOrMod}], _ASN1novalue} ->
+ io:format("Setup or Modified: ~w~n~n", [DecSetOrMod])
+ end,
+ case DecSetOrMod of
+ [[{_ProtIEField1,51,_Crit1,DecSetOrModFirst}]] ->
+ io:format("Setup or Modified: ~w~n~n", [DecSetOrModFirst])
+ end,
+ ok.
+
+run_rab_ass_rsp_delete() ->
+ RAR = rab_assignment_response_delete(),
+ io:format("~w~n~n", [RAR]),
+ RanapRAR = ranap_pdu_contents_outcome(RAR,0), % 0=Rab Assignment Procedure
+ {ok, Tmp2} = wrapper_encode(?ranap, 'RANAP-PDU', RanapRAR),
+ EncRanapRAR = lists:flatten(Tmp2),
+ io:format("~w~n~n", [EncRanapRAR]),
+ {ok,{outcome,
+ #'Outcome'{procedureCode=ProcedureCode,
+ criticality=Criticality,
+ value=DecGeneral}}} =
+ wrapper_decode(?ranap, 'RANAP-PDU', EncRanapRAR),
+ io:format("~w~n~n", [DecGeneral]),
+ case DecGeneral of
+ {'RAB-AssignmentResponse',[{_ProtIEField2,43,_Crit2,DecRelsd}], _ASN1novalue} ->
+ io:format("Released: ~w~n~n", [DecRelsd])
+ end,
+ case DecRelsd of
+ [[{_ProtIEField3,_Code3,_Crit3,DecRelsdItem}]] ->
+ io:format("Released: ~w~n~n", [DecRelsdItem])
+ end,
+ ok.
+
+decode_initiating_rar(ProcedureCode,Crit,Val) ->
+ case ProcedureCode of
+ 0 -> % RAB-Assignment
+ wrapper_decode(?ranap, 'RAB-AssignmentResponse',Val)
+ end.
+
+
+
+run_init_ue() ->
+ INI = initial_ue(),
+ io:format("~w~n~n", [INI]),
+ RanapINI = ranap_pdu_contents(INI, 19), % 19 = InitialUE-Message
+ {ok, Tmp2} = wrapper_encode(?ranap, 'RANAP-PDU', RanapINI),
+ EncRanapINI = lists:flatten(Tmp2),
+ io:format("~w~n~n", [EncRanapINI]),
+
+ {ok,{initiatingMessage,
+ #'InitiatingMessage'{procedureCode=ProcedureCode,
+ criticality=Criticality,
+ value=DecGeneral}}} =
+ wrapper_decode(?ranap, 'RANAP-PDU', EncRanapINI),
+ io:format("~w~n~n", [DecGeneral]),
+ case DecGeneral of
+ {'InitialUE-Message',[{_ProtIEField,Code,_Crit,DecCN},
+ {_ProtIEField1,Code1,_Crit1,
+ {_LAI,LaiPlmnid,LaiLac,_ASN1novalue}},
+ {_ProtIEField2,Code2,_Crit2,DecRAC},
+ {_ProtIEField3,Code3,_Crit3,
+ {_SAI,SaiPlmnid,SaiLac,SaiSac,_ASN1novalue}},
+ {_ProtIEField4,Code4,_Crit4,DecNASPDU},
+ {_ProtIEField5,Code5,_Crit5,DecIUSCID},
+ {_ProtIEField6,Code6,_Crit6,
+ {_GRI,GlPlmnid,GlRNCID}}],_ASN1novalue} ->
+ io:format("CN Dom Ind: ~w~n", [DecCN]),
+ io:format("Code: ~w~n~n", [Code]),
+ io:format("LaiPlmnid: ~w~n", [LaiPlmnid]),
+ io:format("LaiLac: ~w~n", [LaiLac]),
+ io:format("Code: ~w~n~n", [Code1]),
+ io:format("RAC: ~w~n", [DecRAC]),
+ io:format("Code: ~w~n~n", [Code2]),
+ io:format("SaiPlmnid: ~w~n", [SaiPlmnid]),
+ io:format("SaiLac: ~w~n", [SaiLac]),
+ io:format("SaiSac: ~w~n", [SaiSac]),
+ io:format("Code: ~w~n~n", [Code3]),
+ io:format("NAS-PDU: ~w~n", [DecNASPDU]),
+ io:format("Code: ~w~n~n", [Code4]),
+ io:format("Iu Sign Con Id: ~w~n", [DecIUSCID]),
+ io:format("Code: ~w~n~n", [Code5]),
+ io:format("GlPlmnid: ~w~n", [GlPlmnid]),
+ io:format("GlRNCID: ~w~n", [GlRNCID]),
+ io:format("Code: ~w~n~n", [Code6])
+ end,
+ ok.
+
+% NasPdu = extract_ie({init_ue},'InitUE-MessageIEsNAS-PDU',ListsinLists),
+% io:format("Tebax~n~w~n~n", [NasPdu]),
+% ok.
+
+decode_initiating_ini(ProcedureCode,Crit,Val) ->
+ case ProcedureCode of
+ 19 -> % InitialUE-Message
+ wrapper_decode(?ranap, 'InitialUE-Message',Val)
+ end.
+
+
+run_dir_tsf_2cn() ->
+ DIR = direct_transfer_cn(),
+ io:format("~w~n~n", [DIR]),
+ RanapDIR = ranap_pdu_contents(DIR, 20), % 20 = DirectTransfer
+ {ok, Tmp2} = wrapper_encode(?ranap, 'RANAP-PDU', RanapDIR),
+ EncRanapDIR = lists:flatten(Tmp2),
+ io:format("~w~n~n", [EncRanapDIR]),
+ {ok,{initiatingMessage,
+ #'InitiatingMessage'{procedureCode=ProcedureCode,
+ criticality=Criticality,
+ value=DecGeneral}}} =
+ wrapper_decode(?ranap, 'RANAP-PDU', EncRanapDIR),
+ io:format("~w~n~n", [DecGeneral]),
+ case DecGeneral of
+ {'DirectTransfer',
+ [{_ProtIEField1,_Code1,_Crit1,DecNASPDU},
+ {_ProtIEField2,_Code2,_Crit2,DecLAI},
+ {_ProtIEField3,_Code3,_Crit3,DecRAC}],
+ _ASN1novalue} ->
+ io:format("NAS-PDU: ~w~n~n", [DecNASPDU]),
+ io:format("LAI: ~w~n~n", [DecLAI]),
+ io:format("RAC: ~w~n~n", [DecRAC])
+ end,
+ ok.
+
+run_dir_tsf_2rnc() ->
+ DIR = direct_transfer_rnc(),
+ io:format("~w~n~n", [DIR]),
+ RanapDIR = ranap_pdu_contents(DIR, 20), % 20 = DirectTransfer
+ {ok, Tmp2} = wrapper_encode(?ranap, 'RANAP-PDU', RanapDIR),
+ EncRanapDIR = lists:flatten(Tmp2),
+ io:format("~w~n~n", [EncRanapDIR]),
+ {ok,{initiatingMessage,
+ #'InitiatingMessage'{procedureCode=ProcedureCode,
+ criticality=Criticality,
+ value=DecGeneral}}} =
+ wrapper_decode(?ranap, 'RANAP-PDU', EncRanapDIR),
+ io:format("~w~n~n", [DecGeneral]),
+ case DecGeneral of
+ {'DirectTransfer',
+ [{_ProtIEField1,_Code1,_Crit1,DecNASPDU},
+ {_ProtIEField2,_Code2,_Crit2,DecSAPI}],
+ _ASN1novalue} ->
+ io:format("NAS-PDU: ~w~n~n", [DecNASPDU]),
+ io:format("SAPI: m~w~n~n", [DecSAPI])
+ end,
+ ok.
+
+decode_initiating_dir(ProcedureCode,Crit,Val) ->
+ io:format("ProcedureCode: ~w~n~n", [ProcedureCode]),
+ case ProcedureCode of
+ 20 -> % DirectTransfer
+ wrapper_decode(?ranap, 'DirectTransfer',Val)
+ end.
+
+% List = tuple2list(Dec),
+% io:format("~w~n~n", [List]),
+% NasPdu = extract_ie({dir_trans},'DirTransIEs-NAS-PDU',List),
+% io:format("~w~n~n", [NasPdu]),
+% ok.
+
+
+run_iu_rel_cmd() ->
+ IUR = iu_release_command(),
+ io:format("~w~n~n", [IUR]),
+ RanapIUR = ranap_pdu_contents(IUR, 1), % 1 = Iu-Release
+ {ok, Tmp2} = wrapper_encode(?ranap, 'RANAP-PDU', RanapIUR),
+ EncRanapIUR = lists:flatten(Tmp2),
+ io:format("~w~n~n", [EncRanapIUR]),
+ {ok,{initiatingMessage,
+ #'InitiatingMessage'{procedureCode=ProcedureCode,
+ criticality=Criticality,
+ value=DecGeneral}}} =
+ wrapper_decode(?ranap, 'RANAP-PDU', EncRanapIUR),
+ io:format("General: ~w~n~n", [DecGeneral]),
+ case DecGeneral of
+ {'Iu-ReleaseCommand',[{_ProtIEField,_Code,_Crit,DecCause}],_ASN1novalue} ->
+ io:format("Cause: ~w~n~n", [DecCause])
+ end.
+
+run_iu_rel_cmp() ->
+ IUP = iu_release_complete(),
+ io:format("~w~n~n", [IUP]),
+ RanapIUP = ranap_pdu_contents_suc(IUP, 1), % 1 = Iu-Release
+ {ok, Tmp2} = wrapper_encode(?ranap, 'RANAP-PDU', RanapIUP),
+ EncRanapIUP = lists:flatten(Tmp2),
+ io:format("~w~n~n", [EncRanapIUP]),
+ {ok,{successfulOutcome,
+ #'SuccessfulOutcome'{procedureCode=ProcedureCode,
+ criticality=Criticality,
+ value=DecGeneral}}} =
+ wrapper_decode(?ranap, 'RANAP-PDU', EncRanapIUP),
+ io:format("~w~n~n", [DecGeneral]).
+
+% run_iu_rel_req() ->
+% IUP = iu_release_request(),
+% io:format("~w~n~n", [IUP]),
+% {ok, Tmp} = wrapper_encode(?ranap, 'Iu-ReleaseRequest', IUP),
+% EncIUP = lists:flatten(Tmp),
+% RanapIUP = ranap_pdu_contents(EncIUP, 1), % 1 = Iu-Release
+% {ok, Tmp2} = wrapper_encode(?ranap, 'RANAP-PDU', RanapIUP),
+% EncRanapIUP = lists:flatten(Tmp2),
+% io:format("~w~n~n", [EncRanapIUP]),
+% case wrapper_decode(?ranap, 'RANAP-PDU', EncRanapIUP) of
+% {ok,{initiatingMessage,
+% #'InitiatingMessage'{procedureCode=ProcedureCode,
+% criticality=Criticality,
+% value=Value}}} ->
+% DecGeneral = decode_initiating_iu(ProcedureCode,Criticality,Value)
+% end,
+% io:format("~w~n~n", [DecGeneral]).
+
+decode_initiating_iu(ProcedureCode,Crit,Val) ->
+ case ProcedureCode of
+ 1 -> % Iu-Release
+ wrapper_decode(?ranap, 'Iu-ReleaseComplete',Val)
+ end.
+
+
+
+
+
+run_com_id() ->
+ COM = common_id(),
+ io:format("~w~n~n", [COM]),
+ RanapCOM = ranap_pdu_contents(COM, 15), % 15 = CommonID
+ {ok, Tmp2} = wrapper_encode(?ranap, 'RANAP-PDU', RanapCOM),
+ EncRanapCOM = lists:flatten(Tmp2),
+ io:format("~w~n~n", [EncRanapCOM]),
+ {ok,{initiatingMessage,
+ #'InitiatingMessage'{procedureCode=ProcedureCode,
+ criticality=Criticality,
+ value=DecGeneral}}} =
+ wrapper_decode(?ranap, 'RANAP-PDU', EncRanapCOM),
+ io:format("DecGeneral: ~w~n~n", [DecGeneral]),
+ case DecGeneral of
+ {'CommonID',[{_ProtIEField,23,_Crit,DecCause}],_ASN1novalue} ->
+ io:format("Cause: ~w~n~n", [DecCause]);
+ Error ->
+ io:format("Error: ~w~n~n", [Error])
+ end.
+
+
+decode_common_id(ProcedureCode,Crit,Val) ->
+ case ProcedureCode of
+ 15 -> % Common ID
+ wrapper_decode(?ranap, 'CommonID',Val);
+ Error ->
+ io:format("Error: ~w~n~n", [Error])
+ end.
+
+
+
+
+run_sm_cmd() ->
+ DIR = security_mode_cmd(),
+ io:format("~w~n~n", [DIR]),
+ RanapDIR = ranap_pdu_contents(DIR, 6), % 6 = Sec Mode
+ io:format("~w~n~n", [RanapDIR]),
+ {ok, Tmp2} = wrapper_encode(?ranap, 'RANAP-PDU', RanapDIR),
+ EncRanapDIR = lists:flatten(Tmp2),
+ io:format("~w~n~n", [EncRanapDIR]),
+ {ok,{initiatingMessage,
+ #'InitiatingMessage'{procedureCode=ProcedureCode,
+ criticality=Criticality,
+ value=DecGeneral}}} =
+ wrapper_decode(?ranap, 'RANAP-PDU', EncRanapDIR),
+ io:format("~w~n~n", [DecGeneral]),
+ case DecGeneral of
+ {'SecurityModeCommand',
+ [{_ProtIEField1,12,_Crit1,DecIPI},
+ {_ProtIEField2,11,_Crit2,DecEI},
+ {_ProtIEField3,75,_Crit3,DecKS}],
+ _ASN1novalue} ->
+ io:format("Integrity Protection Algoritm: ~w~n~n", [DecIPI]),
+ io:format("Encryption Information: ~w~n~n", [DecEI]),
+ io:format("Key Status: ~w~n~n", [DecKS])
+ end,
+ ok.
+
+run_sm_cmp() ->
+ DIR = security_mode_cmp(),
+ io:format("~w~n~n", [DIR]),
+ RanapDIR = ranap_pdu_contents_suc(DIR, 6), % 6 = Sec Mode
+ io:format("~w~n~n", [RanapDIR]),
+ {ok, Tmp2} = wrapper_encode(?ranap, 'RANAP-PDU', RanapDIR),
+ EncRanapDIR = lists:flatten(Tmp2),
+ io:format("~w~n~n", [EncRanapDIR]),
+ {ok,{successfulOutcome,
+ #'SuccessfulOutcome'{procedureCode=ProcedureCode,
+ criticality=Criticality,
+ value=DecGeneral}}} =
+ wrapper_decode(?ranap, 'RANAP-PDU', EncRanapDIR),
+ io:format("~w~n~n", [DecGeneral]),
+ case DecGeneral of
+ {'SecurityModeComplete',
+ [{_ProtIEField1,6,_Crit1,DecIPA},
+ {_ProtIEField2,5,_Crit2,DecEI}],
+ _ASN1novalue} ->
+ io:format("Integrity Protection Algoritm: ~w~n~n", [DecIPA]),
+ io:format("Encryption Information: ~w~n~n", [DecEI])
+ end,
+ ok.
+
+run_sm_rej() ->
+ DIR = security_mode_rej(),
+ io:format("~w~n~n", [DIR]),
+ RanapDIR = ranap_pdu_contents_unsuc(DIR, 6), % 6 = Sec Mode
+ io:format("~w~n~n", [RanapDIR]),
+ {ok, Tmp2} = wrapper_encode(?ranap, 'RANAP-PDU', RanapDIR),
+ EncRanapDIR = lists:flatten(Tmp2),
+ io:format("~w~n~n", [EncRanapDIR]),
+ {ok,{unsuccessfulOutcome,
+ #'UnsuccessfulOutcome'{procedureCode=ProcedureCode,
+ criticality=Criticality,
+ value=DecGeneral}}} =
+ wrapper_decode(?ranap, 'RANAP-PDU', EncRanapDIR),
+ io:format("~w~n~n", [DecGeneral]),
+% case DecGeneral of
+% {ok,{'SecurityModeReject',
+% [{_ProtIEField1,6,_Crit1,Value1},
+% {_ProtIEField2,5,_Crit2,Value2}],
+% _ASN1novalue}} ->
+% io:format("Value1: ~w~n~n", [Value1]),
+% io:format("Value2: ~w~n~n", [Value2]),
+% {ok,DecIPA} = wrapper_decode(?ranap, 'IntegrityProtectionAlgorithm', Value1),
+% {ok,DecEI} = wrapper_decode(?ranap, 'EncryptionAlgorithm', Value2),
+% io:format("Integrity Protection Algoritm: ~w~n~n", [DecIPA]),
+% io:format("Encryption Information: ~w~n~n", [DecEI])
+% end,
+ ok.
+
+decode_initiating_sm(ProcedureCode,Crit,Val) ->
+ io:format("ProcedureCode: ~w~n~n", [ProcedureCode]),
+ case ProcedureCode of
+ 6 -> % Sec Mode
+ wrapper_decode(?ranap, 'SecurityModeCommand',Val)
+ end.
+
+decode_suc_sm(ProcedureCode,Criticality,Value) ->
+ io:format("ProcedureCode: ~w~n~n", [ProcedureCode]),
+ case ProcedureCode of
+ 6 -> % Sec Mode
+ wrapper_decode(?ranap, 'SecurityModeComplete',Value)
+ end.
+
+decode_unsuc_sm(ProcedureCode,Criticality,Value) ->
+ io:format("ProcedureCode: ~w~n~n", [ProcedureCode]),
+ case ProcedureCode of
+ 6 -> % Sec Mode
+ wrapper_decode(?ranap, 'SecurityModeReject',Value)
+ end.
+
+
+
+
+
+
+
+run_reset() ->
+ IUP = reset(),
+ io:format("Reset: ~w~n~n", [IUP]),
+ RanapIUP = ranap_pdu_contents(IUP, 9), % 9 = Reset
+ {ok, Tmp2} = wrapper_encode(?ranap, 'RANAP-PDU', RanapIUP),
+ EncRanapIUP = lists:flatten(Tmp2),
+ io:format("Coded Reset: ~w~n~n", [EncRanapIUP]),
+ {ok,{initiatingMessage,
+ #'InitiatingMessage'{procedureCode=ProcedureCode,
+ criticality=Criticality,
+ value=DecGeneral}}} =
+ wrapper_decode(?ranap, 'RANAP-PDU', EncRanapIUP),
+ io:format("Decoded Reset: ~w~n~n", [DecGeneral]),
+
+ IUP1 = reset_ack(),
+ io:format("Reset Ack:~w~n~n", [IUP1]),
+ RanapIUP1 = ranap_pdu_contents_suc(IUP1, 9), % 9 = Reset
+ {ok, Tmp21} = wrapper_encode(?ranap, 'RANAP-PDU', RanapIUP1),
+ EncRanapIUP1 = lists:flatten(Tmp21),
+ io:format("Coded Reset Ack: ~w~n~n", [EncRanapIUP1]),
+ {ok,{successfulOutcome,
+ #'SuccessfulOutcome'{procedureCode=ProcedureCode1,
+ criticality=Criticality1,
+ value=DecGeneral1}}} =
+ wrapper_decode(?ranap, 'RANAP-PDU', EncRanapIUP1),
+ io:format("Decoded Reset Ack: ~w~n~n", [DecGeneral1]).
+
+% decode_init_reset(ProcedureCode,Crit,Val) ->
+% io:format("ProcedureCode: ~w~n~n", [ProcedureCode]),
+% case ProcedureCode of
+% 9 -> % reset
+% wrapper_decode(?ranap, 'Reset',Val)
+% end.
+
+% decode_init_reset_ack(ProcedureCode,Crit,Val) ->
+% io:format("ProcedureCode: ~w~n~n", [ProcedureCode]),
+% case ProcedureCode of
+% 9 -> % reset
+% wrapper_decode(?ranap, 'ResetAcknowledge',Val)
+% end.
+
+
+
+
+
+
+
+
+
+run_reset_res() ->
+ IUP = reset_res([12,13,14,15,16,17,18,19,20]),
+ io:format("Reset Rsource: ~w~n~n", [IUP]),
+ RanapIUP = ranap_pdu_contents(IUP, 27), % 27 = Reset Res
+ {ok, Tmp2} = wrapper_encode(?ranap, 'RANAP-PDU', RanapIUP),
+ EncRanapIUP = lists:flatten(Tmp2),
+ io:format("Coded Reset Resource: ~w~n~n", [EncRanapIUP]),
+ {ok,{initiatingMessage,
+ #'InitiatingMessage'{procedureCode=ProcedureCode,
+ criticality=Criticality,
+ value=DecGeneral}}} =
+ wrapper_decode(?ranap, 'RANAP-PDU', EncRanapIUP),
+ io:format("Decoded Reset Resource: ~w~n~n", [DecGeneral]),
+% case DecGeneral of
+% {ok,{'ResetResource',
+% [{'ProtocolIE-Field',3,ignore,Value1},
+% {'ProtocolIE-Field',4,ignore,Value2},
+% {'ProtocolIE-Field',77,ignore,Value3},
+% {'ProtocolIE-Field',86,ignore,Value4}],
+% asn1_NOVALUE}} ->
+% io:format("Value1: ~w~n~n", [Value1]),
+% io:format("Value2: ~w~n~n", [Value2]),
+% io:format("Value3: ~w~n~n", [Value3]),
+% io:format("Value4: ~w~n~n", [Value4]),
+% {ok,DecIPA} = wrapper_decode(?ranap, 'CN-DomainIndicator', Value1),
+% {ok,{_Radio,DecEI}} = wrapper_decode(?ranap, 'Cause', Value2),
+% {ok,DecRR} = wrapper_decode(?ranap, 'ResetResourceList', Value3),
+% DecRRI = case DecRR of
+% [[{'ProtocolIE-Field',78,ignore,Value5}]] ->
+% {ok,{_apa,DecRI,_asn1novalue}} =
+% wrapper_decode(?ranap, 'ResetResourceItem', Value5),
+% DecRI
+% end,
+% {ok,{_Gl_id,PLMN_ID,RNC_ID}} = wrapper_decode(?ranap, 'GlobalRNC-ID', Value4),
+% io:format("CN-DomainIndicator: ~w~n~n", [DecIPA]),
+% io:format("Cause: ~w~n~n", [DecEI]),
+% io:format("ResetResourceList: ~w~n~n", [DecRR]),
+% io:format(" ResetResourceItem: ~w~n~n", [DecRRI]),
+% io:format("GlobalRNC-ID: PLMN_ID: ~w, RNC_ID: ~w~n~n", [PLMN_ID,RNC_ID])
+% end,
+
+ RSA = reset_res_ack([12,13,14,15,16,17,18,19,20]),
+ io:format("~n~nReset Resource Ack:~w~n~n", [RSA]),
+ RanapRSA = ranap_pdu_contents_suc(RSA, 27), % 27 = Reset Res
+ {ok, Tmp12} = wrapper_encode(?ranap, 'RANAP-PDU', RanapRSA),
+ EncRanapRSA = lists:flatten(Tmp12),
+ io:format("Coded Reset Resource Ack: ~w~n~n", [EncRanapRSA]),
+ {ok,{successfulOutcome,
+ #'SuccessfulOutcome'{procedureCode=ProcedureCode1,
+ criticality=Criticality1,
+ value=DecGeneral1}}} =
+ wrapper_decode(?ranap, 'RANAP-PDU', EncRanapRSA),
+ io:format("Decoded Reset Resource Ack: ~w~n~n", [DecGeneral1]).
+% case DecGeneral1 of
+% {ok,{'ResetResourceAcknowledge',
+% [{'ProtocolIE-Field',3,ignore,Value12},
+% {'ProtocolIE-Field',77,ignore,Value32}],
+% asn1_NOVALUE}} ->
+% io:format("Value1: ~w~n~n", [Value12]),
+% io:format("Value3: ~w~n~n", [Value32]),
+% {ok,DecIPA2} = wrapper_decode(?ranap, 'CN-DomainIndicator', Value12),
+% {ok,DecRR2} = wrapper_decode(?ranap, 'ResetResourceList', Value32),
+% DecRRI2 = case DecRR2 of
+% [[{'ProtocolIE-Field',78,ignore,Value52}]] ->
+% {ok,{_apa2,DecRI2,_asn1novalue2}} =
+% wrapper_decode(?ranap, 'ResetResourceItem', Value52),
+% DecRI2
+% end,
+% io:format("CN-DomainIndicator: ~w~n~n", [DecIPA2]),
+% io:format("ResetResourceList: ~w~n~n", [DecRR2]),
+% io:format(" ResetResourceItem: ~w~n~n", [DecRRI2])
+% end.
+
+
+
+
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%%
+%% Kod f�r att s�tta ihop RANAP-meddelanden
+%%
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+rab_release_request() ->
+ #'RAB-AssignmentRequest'{
+ protocolIEs = rab_assign_request_release_ies()
+ }.
+
+rab_assign_request_release_ies() ->
+ [rab_assign_release_rab_release_list()].
+
+rab_assign_release_rab_release_list() ->
+ #'ProtocolIE-Field'{
+ id = 41, % 41 = id-RAB-ReleaseList
+ criticality = ignore,%XXX
+ value = rab_release_list()
+ }.
+
+rab_release_list() ->
+ [release_lists()].
+
+release_lists() ->
+ [rab_release_item_ies()].
+
+rab_release_item_ies() ->
+ #'ProtocolIE-Field'{
+ id = 40, % 40 = id-RAB-ReleaseItem
+ criticality = ignore,%XXX
+ value = rab_release_item()}.
+
+rab_release_item() ->
+ #'RAB-ReleaseItem'{'rAB-ID' = rab_id(),
+ cause = cause_nas()}.
+
+cause_nas() ->
+ {nAS, 'normal-release'}.
+
+
+
+
+
+
+rab_create_request(Rabid, Teid, SgsnIP) ->
+ #'RAB-AssignmentRequest'{
+ protocolIEs =
+ rab_assign_create_request_ies(Rabid, Teid, SgsnIP)
+ }.
+
+rab_assign_create_request_ies(Rabid, Teid, SgsnIP) ->
+ [rab_assign_setup_or_modify_list(Rabid, Teid, SgsnIP)].
+
+rab_assign_setup_or_modify_list(Rabid, Teid, SgsnIP) ->
+ #'ProtocolIE-Field'{
+ id = 54, %id-RAB-SetupOrModifyList
+ criticality = ignore,%XXX
+ value = rab_setup_or_modify_list(Rabid, Teid, SgsnIP)
+ }.
+
+rab_setup_or_modify_list(Rabid, Teid, SgsnIP) ->
+ [setup_or_modify_lists(Rabid, Teid, SgsnIP)].
+
+setup_or_modify_lists(Rabid, Teid, SgsnIP) ->
+ [rab_setup_or_modify_item_ies(Rabid, Teid, SgsnIP)].
+
+rab_setup_or_modify_item_ies(Rabid, Teid, SgsnIP) ->
+ #'ProtocolIE-FieldPair'{
+ id = 53,
+ firstCriticality = reject, %{'Criticality',reject},
+ firstValue = rab_setup_or_modify_item_first(Rabid, Teid, SgsnIP),
+ secondCriticality = ignore, %{'Criticality', ignore}
+ secondValue = rab_setup_or_modify_item_second()
+ }.
+
+rab_setup_or_modify_item_first(Rabid, Teid, SgsnIP) ->
+ #'RAB-SetupOrModifyItemFirst'{
+ 'rAB-ID' = Rabid, %ras_rab_id(Rabid),
+ 'rAB-Parameters' = rab_parameters(),
+ userPlaneInformation = user_plane_information(),
+ transportLayerAddress = SgsnIP,
+ iuTransportAssociation = ras_iu_transport_association(Teid)
+ }.
+
+ras_iu_transport_association(Teid) ->
+ {'gTP-TEI', Teid}.
+
+rab_id() ->
+ [0,1,0,1,0,1,0,1].
+
+rab_parameters() ->
+ #'RAB-Parameters'{
+ trafficClass = background,
+ 'rAB-AsymmetryIndicator' = 'symmetric-bidirectional',
+ maxBitrate = [200000],
+ deliveryOrder = 'delivery-order-not-requested',
+ 'maxSDU-Size' = 11,
+ 'sDU-Parameters' = sdu_parameters(),
+ trafficHandlingPriority = 14 %{'TrafficHandlingPriority', 14} %14=lowest
+ }.
+
+user_plane_information() ->
+ #'UserPlaneInformation'{
+ userPlaneMode = 'support-mode-for-predefined-SDU-sizes',
+ 'uP-ModeVersions' = 2#1010101010101010
+ }.
+
+transport_layer_address() ->
+ [1,1,0,0,1,1,0,0,1,1,1,1,0,0,0,0,1,0,1,0,1,0,1,0,0,0,0,0,1,1,1,1].
+% 1 2 3 4
+
+iu_transport_association() ->
+ {'gTP-TEI', [31,32,33,34]}.
+
+sdu_parameters() ->
+ [#'SDU-Parameters_SEQOF'{
+ 'sDU-ErrorRatio' = sdu_error_ratio(),
+ residualBitErrorRatio = residual_bit_error_ratio(),
+ deliveryOfErroneousSDU = no
+ }].
+
+sdu_error_ratio() ->
+ #'SDU-ErrorRatio'{
+ mantissa = 9,
+ exponent = 4
+ }.
+
+residual_bit_error_ratio() ->
+ #'ResidualBitErrorRatio'{
+ mantissa = 9,
+ exponent = 5
+ }.
+
+%allocationOrRetentionPriority() ->
+% #'AllocationOrRetentionPriority'{
+% priorityLevel = lowest,
+% 'pre-emptionCapability' = {'Pre-emptionCapability','can-trigger-pre-emption'},
+% 'pre-emptionVulnerability' = {'Pre-emptionVulnerability','not-vulnerable-to-pre-emption'},
+% queuingAllowed = {'QueuingAllowed','queueing-allowed'}
+% }.
+
+rab_setup_or_modify_item_second() -> % returns OpenType value
+ #'RAB-SetupOrModifyItemSecond'{
+ 'pDP-TypeInformation' = ['ipv4'],
+ dataVolumeReportingIndication = 'do-not-report',
+ 'dl-GTP-PDU-SequenceNumber' = 1,
+ 'ul-GTP-PDU-SequenceNumber' = 2,
+ 'dl-N-PDU-SequenceNumber' = 0,
+ 'ul-N-PDU-SequenceNumber' = 0
+ }.
+
+
+
+
+rab_assignment_response_setup() ->
+ #'RAB-AssignmentResponse'{
+ protocolIEs = rab_assignement_response_ies_setup()
+ }.
+
+rab_assignement_response_ies_setup() ->
+ [rab_ass_rsp_setup_or_modified_list()].
+
+rab_ass_rsp_setup_or_modified_list() ->
+ #'ProtocolIE-Field'{
+ id = 52, % 52=RAB-AssignRABSetupOrModifiedList
+ criticality = ignore,%XXX
+ value = rab_setup_or_modified_list()
+ }.
+
+rab_setup_or_modified_list() ->
+ [rab_setup_or_modified_item_list()].
+
+rab_setup_or_modified_item_list() ->
+ [rab_setup_or_modified_item_ies()].
+
+rab_setup_or_modified_item_ies() ->
+ #'ProtocolIE-Field'{
+ id = 51, % 51 = RAB-SetupOrModifiedItemIEs
+ criticality = reject, %{'Criticality', reject},
+ value = rab_setup_or_modified_item()
+ }.
+
+rab_setup_or_modified_item() ->
+ #'RAB-SetupOrModifiedItem'{
+ 'rAB-ID' = rab_id(),
+ transportLayerAddress = transport_layer_address(),
+ iuTransportAssociation = iu_transport_association()
+ }.
+
+
+
+
+
+
+rab_assignment_response_delete() ->
+ #'RAB-AssignmentResponse'{
+ protocolIEs = rab_assignement_response_ies_delete()
+ }.
+
+rab_assignement_response_ies_delete() ->
+ [rab_ass_rsp_rab_release_list()].
+
+rab_ass_rsp_rab_release_list() ->
+ #'ProtocolIE-Field'{
+ id = 43, % 41 = RAB-AssignRABReleasedList
+ criticality = ignore,%XXX
+ value = rab_released_list()
+ }.
+
+rab_released_list() ->
+ [released_lists()].
+
+released_lists() ->
+ [rab_released_item_ies()]. % 'ReleasedLists'
+
+rab_released_item_ies() ->
+ #'ProtocolIE-Field'{
+ id = 42, % 42 = RAB-ReleaseItemIEs
+ criticality = ignore,%XXX
+ value = rab_released_item()
+ }.
+
+rab_released_item() ->
+ #'RAB-ReleasedItem'{
+ 'rAB-ID' = rab_id()
+ }.
+
+
+
+initial_ue() ->
+ #'InitialUE-Message'{
+ protocolIEs = initial_ue_ies()
+ }.
+
+initial_ue_ies() ->
+ [cn_domain_ind(),
+ init_lai(),
+ init_rac(),
+ init_sai(),
+ init_nas_pdu(),
+ init_iu_sign_con_id(),
+ init_global_rnc_id_initial_ue()].
+
+
+cn_domain_indicator() ->
+ {'CN-DomainIndicator', 'ps-domain'}.
+
+init_lai() ->
+ #'ProtocolIE-Field'{
+ id = 15, % 15 = LAI
+ criticality = ignore,%XXX
+ value = lai()
+ }.
+
+lai() ->
+ #'LAI'{'pLMN-ID' = [25,26,27],
+ lAC = [25,26]}.
+
+init_rac() ->
+ #'ProtocolIE-Field'{
+ id = 55, % 55 = RAC
+ criticality = ignore,%XXX
+ value = rac()
+ }.
+
+rac() ->
+ [25].
+
+init_sai() ->
+ #'ProtocolIE-Field'{
+ id = 58, % 58 = SAI
+ criticality = ignore,%XXX
+ value = sai()
+ }.
+
+sai() ->
+ #'SAI'{'pLMN-ID' = [28,29,30], %KOLLA!!!!
+ lAC = [30,31],
+ sAC = [32,33]}.
+
+init_nas_pdu() ->
+ #'ProtocolIE-Field'{
+ id = 16, % 16 = NAS-PDU
+ criticality = ignore,%XXX
+ value = pdu_ar()
+ }.
+
+pdu_ac()->
+ [16#08,
+ 16#03].
+
+pdu_ar() ->
+ [16#08, % Skip indicator | Protocol discriminator
+ 16#01, % Attach Request
+ 16#01,16#b7, % MsNetworkCapability
+ 16#21, % Cksn | AttachType
+ 16#55,16#06, % DrxParameter
+ 16#05,16#61,16#86,16#14,16#09,16#f7, % MsId
+ 16#21,16#63,16#54,16#ac,16#dc,16#d5, % OldRai
+ 16#0a,16#f0,16#f1,16#f2,16#f3,16#f4, % MsRaCap
+ 16#f5,16#f6,16#f7,16#f8,16#f9 % MsRaCap continues
+ %%16#19,16#ab,16#cd,16#ef, % P-TMSI signature
+ %%16#17,16#5b, % Requested READY timer
+ %%16#91 % TMSI status
+ ].
+
+pdu_pdp() ->
+ [2#01001010, % Transaction_id | Protocol_disc
+ 2#01000001, % Message_type
+ 2#00001001, % Nsapi
+ 1, % Llc_sapi (dummie_value)
+ 1,1,1,1, % QoS dummie_value=1 (19 octets)
+ 1,1,1,1,1,
+ 1,1,1,1,1,
+ 1,1,1,1,1,
+ 7, % PDP_Address (Ltot=7),
+ 2#00000001, % ietf/etsi organisation
+ 2#00100001, % IPv4
+ 198, % IP address MSD
+ 124,
+ 56,
+ 124, % IP address LSD
+ 1, % APN optional (octet1=IEI)
+ 25, % APN total length
+ 4, % length lable1
+ 116,101,115,116, % lable1 = test
+ 4, % length lable2
+ 116,101,115,116, % lable2 = test
+ 4, % lenght lable3
+ 116,101,115,116, % lable3 = test
+ 4, % length lable3
+ 116,101,115,116, % lable4 = test
+ 4, % length label5
+ 103,112,114,115
+ ].
+
+pdu_auth_rsp() ->
+ [8,16#13,0,1,2,3,16#21,2,0,1].
+
+pdu_auth_fail() ->
+ [8,16#1C,1,16#22,2,0,1].
+
+init_iu_sign_con_id() ->
+ #'ProtocolIE-Field'{
+ id = 79, % 79 = id-IuSigConId
+ criticality = ignore,%XXX
+ value = iu_sign_con_id()
+ }.
+
+iu_sign_con_id() ->
+ 53245.
+% [1,0,1,0,1,0,1,0,
+% 1,0,1,0,1,0,1,0,
+% 1,0,1,0,1,0,1,1]
+
+init_global_rnc_id_initial_ue() ->
+ #'ProtocolIE-Field'{
+ id = 86, % 86 = id-GlobalRNC-ID
+ criticality = ignore,%XXX
+ value = global_rnc_id()
+ }.
+
+global_rnc_id() ->
+ #'GlobalRNC-ID'{'pLMN-ID' = [10,11,12], 'rNC-ID' = 2048}.
+
+direct_transfer_cn() ->
+ #'DirectTransfer'{
+ protocolIEs = direct_transfer_cn_ies()
+ }.
+
+direct_transfer_cn_ies() ->
+ [dir_cn_nas_pdu(),
+ dir_lai(),
+ dir_rac()].
+
+dir_cn_nas_pdu() ->
+ #'ProtocolIE-Field'{
+ id = 16, % 16 = id-NAS-PDU
+ criticality = ignore,%XXX
+ value = pdu_auth_fail()
+ }.
+
+dir_lai() ->
+ #'ProtocolIE-Field'{
+ id = 15, % 15 = id-LAI
+ criticality = ignore,%XXX
+ value = lai()
+ }.
+
+dir_rac() ->
+ #'ProtocolIE-Field'{
+ id = 55, % 55 = id-RAC
+ criticality = ignore,%XXX
+ value = rac()
+ }.
+
+
+
+
+
+
+direct_transfer_rnc() ->
+ #'DirectTransfer'{
+ protocolIEs = direct_transfer_rnc_ies()
+ }.
+
+direct_transfer_rnc_ies() ->
+ [dir_rnc_nas_pdu(),
+ dir_sapi()].
+
+dir_rnc_nas_pdu() ->
+ #'ProtocolIE-Field'{
+ id = 16, % 16 = id-NAS-PDU
+ criticality = ignore,%XXX
+ value = pdu_auth_rsp()
+ }.
+
+dir_sapi() ->
+ #'ProtocolIE-Field'{
+ id = 59, % 59 = id-SAPI
+ criticality = ignore,%XXX
+ value = sapi()
+ }.
+
+sapi() ->
+ 'normal-priority'.
+
+
+
+
+
+iu_release_command() ->
+ #'Iu-ReleaseCommand'{
+ protocolIEs = iu_rel_command_ies()
+ }.
+
+iu_rel_command_ies() ->
+ [iu_relcomcause_nas()].
+
+iu_relcomcause_nas() ->
+ #'ProtocolIE-Field'{
+ id = 4, % 4 = Id-Cause
+ criticality = ignore,%XXX
+ value = cause()
+ }.
+
+cause() ->
+ cause_nas().
+
+% cause() ->
+% {ok,Bytes} =
+% wrapper_encode(?ranap,'CauseNAS',
+% {'CauseNAS', 'normal-release'}),
+% Bytes.
+
+
+
+
+
+
+iu_release_complete() ->
+ #'Iu-ReleaseComplete'{
+ protocolIEs = iu_rel_comp_ies()
+ }.
+
+iu_rel_comp_ies() ->
+ [].
+% 'iu-RelCompRABDataVolumeReportList' = asn1_NOVALUE,
+% 'iu-RelCompRABReleasedListIuRelComp' = asn1_NOVALUE,
+% 'iu-RelCompCriticalityDiagnostics' = asn1_NOVALUE
+% }.
+
+
+
+
+
+
+
+
+common_id() ->
+ #'CommonID'{
+ protocolIEs = common_id_ies()
+ }.
+
+common_id_ies() ->
+ [common_id_imsi()].
+
+common_id_imsi() ->
+ #'ProtocolIE-Field'{
+ id = 23, % 23 = Perm. NAS ID (IMSI)
+ criticality = ignore, %ignore,%XXX %XXX
+ value = imsi()
+ }.
+
+imsi() ->
+ {iMSI, [1,2,3,4,5,6,7,8]}.
+
+
+
+
+
+
+
+
+
+
+security_mode_cmd() ->
+ #'SecurityModeCommand'{
+ protocolIEs = security_mode_cmd_ies()
+ }.
+
+security_mode_cmd_ies() ->
+ [security_mode_cmd_integ(),
+ security_mode_cmd_encr(),
+ security_mode_cmd_keystat()
+ ].
+
+security_mode_cmd_integ() ->
+ #'ProtocolIE-Field'{
+ id = 12, % 12 = Integ info
+ criticality = ignore,%{'Criticality', ignore},
+ value = integ_info()
+ }.
+
+integ_info() ->
+ #'IntegrityProtectionInformation'{
+ permittedAlgorithms = perm_integ_algs(),
+ key = key() }.
+
+perm_integ_algs() ->
+ [integ_prot_alg()].
+
+integ_prot_alg() ->
+ 'standard-UMTS-integrity-algorithm-UIA1'.
+
+key() ->
+ [1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,
+ 1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,
+ 1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,
+ 1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,
+ 1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,
+ 1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,
+ 1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,
+ 1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0].
+
+
+
+security_mode_cmd_encr() ->
+ #'ProtocolIE-Field'{
+ id = 11, % 11 = Encr info
+ criticality = ignore,%{'Criticality', ignore},
+ value = encr_info()
+ }.
+
+encr_info() ->
+ #'EncryptionInformation'{
+ permittedAlgorithms = perm_encr_algs(),
+ key = key() }.
+
+perm_encr_algs() ->
+ [encr_prot_alg()].
+
+encr_prot_alg() ->
+ 'standard-UMTS-encryption-algorith-UEA1'.
+
+security_mode_cmd_keystat() ->
+ #'ProtocolIE-Field'{
+ id = 75, % 75 = id-KeyStatus
+ criticality = ignore,%{'Criticality', ignore},
+ value = key_status()
+ }.
+
+key_status() ->
+ new.
+
+
+
+
+
+security_mode_cmp() ->
+ #'SecurityModeComplete'{
+ protocolIEs = security_mode_cmp_ies()
+ }.
+
+security_mode_cmp_ies() ->
+ [security_mode_cmp_ch_integ_prot_alg(),
+ security_mode_cmp_ch_encr_alg()
+ ].
+
+security_mode_cmp_ch_integ_prot_alg() ->
+ #'ProtocolIE-Field'{
+ id = 6, % 6 = Chosen Integ prot alg
+ criticality = ignore,%XXX
+ value = ch_integ_prot_alg()
+ }.
+
+ch_integ_prot_alg() ->
+ 'standard-UMTS-integrity-algorithm-UIA1'.
+
+
+security_mode_cmp_ch_encr_alg() ->
+ #'ProtocolIE-Field'{
+ id = 5, % 5 = Chosen Encr alg
+ criticality = ignore,%XXX
+ value = ch_encr_alg()
+ }.
+
+ch_encr_alg() ->
+ 'standard-UMTS-encryption-algorith-UEA1'.
+
+
+
+
+security_mode_rej() ->
+ #'SecurityModeReject'{
+ protocolIEs = security_mode_rej_ies()
+ }.
+
+security_mode_rej_ies() ->
+ [security_mode_rej_cause()].
+
+
+security_mode_rej_cause() ->
+ #'ProtocolIE-Field'{
+ id = 4, % 4 = Id-Cause
+ criticality = ignore,%XXX
+ value = cause_radio() % Se Reset
+ }.
+
+
+
+
+
+
+
+
+reset() ->
+ #'Reset'{
+ protocolIEs = reset_ies()
+ }.
+reset_ies() ->
+ {'Reset_protocolIEs', % this identifier is very unneccesary here
+ [reset_cause(),
+ cn_domain_ind(), % Se initial Ue
+ init_global_rnc_id() % ---- " ----
+ ]}.
+init_global_rnc_id() ->
+ #'ProtocolIE-Field'{
+ id = 86, % 86 = id-GlobalRNC-ID
+ criticality = ignore,%XXX
+ value = global_rnc_id()
+ }.
+
+reset_cause() ->
+ #'ProtocolIE-Field'{
+ id = 4, % 4 = id-Cause
+ criticality = ignore,%XXX
+ value = cause_radio()
+ }.
+%cause_open() ->
+% {ok,Bytes} =
+% wrapper_encode(?ranap,'Cause', cause_radio()),
+% Bytes.
+cause_radio() ->
+ {radioNetwork, 'release-due-to-utran-generated-reason'}.
+
+
+cn_domain_ind(IEs) when atom(IEs)->
+ setelement(1,cn_domain_ind(),IEs).
+
+cn_domain_ind() ->
+ #'ProtocolIE-Field'{
+ id = 3, % 3 = InitUE-MessageIEsCN-DomainIndicator
+ criticality = ignore,%XXX
+ value = cn_domain_indicator()
+ }.
+
+
+
+
+reset_ack() ->
+ #'ResetAcknowledge'{
+ protocolIEs = reset_ack_ies()
+ }.
+reset_ack_ies() ->
+ {'ResetAcknowledge_protocolIEs', % very unneccesary
+ [cn_domain_ind()]}. % Se initial Ue
+
+
+
+
+
+reset_res(IuSCId) ->
+ #'ResetResource'{
+ protocolIEs = reset_res_ies(IuSCId)
+ }.
+
+reset_res_ies(IuSCId) ->
+ {'ResetResource_protocolIEs', % very unneccesary
+ [
+ cn_domain_ind() % Se initial Ue
+ ,reset_cause() % Se reset
+ ,reset_res_list(IuSCId)
+ ,init_global_rnc_id_reset_res() % ---- " ----
+ ]}.
+
+init_global_rnc_id_reset_res() ->
+ #'ProtocolIE-Field'{
+ id = 86, % 86 = id-GlobalRNC-ID
+ criticality = ignore,%XXX
+ value = global_rnc_id()
+ }.
+
+reset_res_list(IuSCId) ->
+ #'ProtocolIE-Field'{
+ id = 77, % 77 = id-IuSigConIdList
+ criticality = ignore,%XXX
+ value = res_list(IuSCId)
+ }.
+
+res_list(IuSCId) ->
+ iu_Sig_Con_Id_list(IuSCId,[]).
+
+iu_Sig_Con_Id_list([],List) ->
+ List;
+
+iu_Sig_Con_Id_list([IuSCId|T],List) ->
+ Ie = [iu_Sig_Con_Id_ie(IuSCId)],
+ iu_Sig_Con_Id_list(T,[Ie|List]).
+
+iu_Sig_Con_Id_ie(IuSCId) ->
+ #'ProtocolIE-Field'{
+ id = 78, % 78 = id-IuSigConIdItem
+ criticality = ignore,%XXX
+ value = iu_Sig_Con_Id_item(IuSCId)}.
+
+iu_Sig_Con_Id_item(IuSCId) ->
+ #'ResetResourceItem'{
+ iuSigConId = IuSCId
+% 53432
+% [1,0,1,0,1,0,1,0,
+% 1,0,1,0,1,0,1,0,
+% 1,0,1,0,1,0,1,0]
+ }.
+
+
+reset_res_ack(IuSCId) ->
+ #'ResetResourceAcknowledge'{
+ protocolIEs = reset_res_ack_ies(IuSCId)
+ }.
+reset_res_ack_ies(IuSCId) ->
+ [
+ cn_domain_ind() % Se initial Ue
+ ,reset_res_list(IuSCId) % Se Reset Ressource
+ ].
+
+
+int2bin(Int) ->
+ EmptyList = [],
+ BitList_b1 = [Int band 2#1 | EmptyList],
+ BitList_b2 = [(Int bsr 1) band 2#1 | BitList_b1],
+ BitList_b3 = [(Int bsr 2) band 2#1 | BitList_b2],
+ BitList_b4 = [(Int bsr 3) band 2#1 | BitList_b3],
+ BitList_b5 = [(Int bsr 4) band 2#1 | BitList_b4],
+ BitList_b6 = [(Int bsr 5) band 2#1 | BitList_b5],
+ BitList_b7 = [(Int bsr 6) band 2#1 | BitList_b6],
+ BitList = [(Int bsr 7) band 2#1 | BitList_b7],
+ io:format("~n~w~n", [BitList]).
+
+
+%%%%%%%%%%%%%%%%% wrappers %%%%%%%%%%%%%%%%%%%%%%%%
+
+wrapper_encode(Module,Type,Value) ->
+ case asn1rt:encode(Module,Type,Value) of
+ {ok,X} when binary(X) ->
+ {ok, binary_to_list(X)};
+ {ok,X} ->
+ {ok, binary_to_list(list_to_binary(X))};
+ Error ->
+ Error
+ end.
+
+wrapper_decode(Module,Type,Bytes) ->
+ case Module:encoding_rule() of
+ ber ->
+ asn1rt:decode(Module,Type,Bytes);
+ ber_bin when binary(Bytes) ->
+ asn1rt:decode(Module,Type,Bytes);
+ ber_bin ->
+ asn1rt:decode(Module,Type,list_to_binary(Bytes));
+ ber_bin_v2 when binary(Bytes) ->
+ asn1rt:decode(Module,Type,Bytes);
+ ber_bin_v2 ->
+ asn1rt:decode(Module,Type,list_to_binary(Bytes));
+ per ->
+ asn1rt:decode(Module,Type,Bytes);
+ per_bin when binary(Bytes) ->
+ asn1rt:decode(Module,Type,Bytes);
+ per_bin ->
+ asn1rt:decode(Module,Type,list_to_binary(Bytes));
+ uper_bin ->
+ asn1rt:decode(Module,Type,list_to_binary(Bytes))
+ end.
diff --git a/lib/asn1/test/asn1_SUITE_data/x420/ACSE-1.asn b/lib/asn1/test/asn1_SUITE_data/x420/ACSE-1.asn
new file mode 100644
index 0000000000..3f1385323a
--- /dev/null
+++ b/lib/asn1/test/asn1_SUITE_data/x420/ACSE-1.asn
@@ -0,0 +1,253 @@
+-- Module ACSE-1 (X.237:04/1995)
+ACSE-1 {joint-iso-itu-t association-control(2) modules(0) apdus(0) version1(1)}
+-- ACSE-1 refers to ACSE version 1
+DEFINITIONS ::=
+BEGIN
+
+EXPORTS
+ acse-as-id, ACSE-apdu, aCSE-id, Application-context-name, AP-title,
+ AE-qualifier, AE-title, AP-invocation-identifier, AE-invocation-identifier,
+ Mechanism-name, Authentication-value, ACSE-requirements, ObjectSet;
+
+IMPORTS
+ Name, RelativeDistinguishedName
+ FROM InformationFramework {joint-iso-itu-t ds(5) module(1)
+ informationFramework(1) 3};
+
+-- The data types Name and RelativeDistinguishedName are imported from ISO/IEC 9594-2.
+-- object identifier assignments
+acse-as-id OBJECT IDENTIFIER ::=
+ {joint-iso-itu-t association-control(2) abstract-syntax(1) apdus(0)
+ version1(1)}
+
+-- may be used to reference the abstract syntax of the ACSE APDUs
+aCSE-id OBJECT IDENTIFIER ::=
+ {joint-iso-itu-t association-control(2) ase-id(3) acse-ase(1) version(1)}
+
+-- may be used to identify the Association Control ASE.
+-- top level CHOICE
+ACSE-apdu ::= CHOICE {
+ aarq AARQ-apdu,
+ aare AARE-apdu,
+ rlrq RLRQ-apdu,
+ rlre RLRE-apdu,
+ abrt ABRT-apdu,
+ ...
+}
+
+AARQ-apdu ::= [APPLICATION 0] IMPLICIT SEQUENCE {
+ protocol-version
+ [0] IMPLICIT BIT STRING {version1(0)} DEFAULT {version1},
+ application-context-name [1] Application-context-name,
+ called-AP-title [2] AP-title OPTIONAL,
+ called-AE-qualifier [3] AE-qualifier OPTIONAL,
+ called-AP-invocation-identifier [4] AP-invocation-identifier OPTIONAL,
+ called-AE-invocation-identifier [5] AE-invocation-identifier OPTIONAL,
+ calling-AP-title [6] AP-title OPTIONAL,
+ calling-AE-qualifier [7] AE-qualifier OPTIONAL,
+ calling-AP-invocation-identifier [8] AP-invocation-identifier OPTIONAL,
+ calling-AE-invocation-identifier [9] AE-invocation-identifier OPTIONAL,
+ -- The following field shall not be present if only the Kernel is used.
+ sender-acse-requirements [10] IMPLICIT ACSE-requirements OPTIONAL,
+ -- The following field shall only be present if the Authentication functional unit is selected.
+ mechanism-name [11] IMPLICIT Mechanism-name OPTIONAL,
+ -- The following field shall only be present if the Authentication functional unit is selected.
+ calling-authentication-value [12] EXPLICIT Authentication-value OPTIONAL,
+ application-context-name-list
+ [13] IMPLICIT Application-context-name-list OPTIONAL,
+ -- The above field shall only be present if the Application Context Negotiation functional unit is selected
+ implementation-information [29] IMPLICIT Implementation-data OPTIONAL,
+ ...,
+ ...,
+ user-information
+ [30] IMPLICIT Association-information OPTIONAL
+}
+
+AARE-apdu ::= [APPLICATION 1] IMPLICIT SEQUENCE {
+ protocol-version
+ [0] IMPLICIT BIT STRING {version1(0)} DEFAULT {version1},
+ application-context-name [1] Application-context-name,
+ result [2] Associate-result,
+ result-source-diagnostic [3] Associate-source-diagnostic,
+ responding-AP-title [4] AP-title OPTIONAL,
+ responding-AE-qualifier [5] AE-qualifier OPTIONAL,
+ responding-AP-invocation-identifier [6] AP-invocation-identifier OPTIONAL,
+ responding-AE-invocation-identifier [7] AE-invocation-identifier OPTIONAL,
+ -- The following field shall not be present if only the Kernel is used.
+ responder-acse-requirements [8] IMPLICIT ACSE-requirements OPTIONAL,
+ -- The following field shall only be present if the Authentication functional unit is selected.
+ mechanism-name [9] IMPLICIT Mechanism-name OPTIONAL,
+ -- This following field shall only be present if the Authentication functional unit is selected.
+ responding-authentication-value
+ [10] EXPLICIT Authentication-value OPTIONAL,
+ application-context-name-list
+ [11] IMPLICIT Application-context-name-list OPTIONAL,
+ -- The above field shall only be present if the Application Context Negotiation functional unit is selected
+ implementation-information
+ [29] IMPLICIT Implementation-data OPTIONAL,
+ ...,
+ ...,
+ user-information
+ [30] IMPLICIT Association-information OPTIONAL
+}
+
+RLRQ-apdu ::= [APPLICATION 2] IMPLICIT SEQUENCE {
+ reason [0] IMPLICIT Release-request-reason OPTIONAL,
+ ...,
+ ...,
+ user-information [30] IMPLICIT Association-information OPTIONAL
+}
+
+RLRE-apdu ::= [APPLICATION 3] IMPLICIT SEQUENCE {
+ reason [0] IMPLICIT Release-response-reason OPTIONAL,
+ ...,
+ ...,
+ user-information [30] IMPLICIT Association-information OPTIONAL
+}
+
+ABRT-apdu ::= [APPLICATION 4] IMPLICIT SEQUENCE {
+ abort-source [0] IMPLICIT ABRT-source,
+ abort-diagnostic [1] IMPLICIT ABRT-diagnostic OPTIONAL,
+ -- This field shall not be present if only the Kernel is used.
+ ...,
+ ...,
+ user-information [30] IMPLICIT Association-information OPTIONAL
+}
+
+ABRT-diagnostic ::= ENUMERATED {
+ no-reason-given(1), protocol-error(2),
+ authentication-mechanism-name-not-recognized(3),
+ authentication-mechanism-name-required(4), authentication-failure(5),
+ authentication-required(6), ...
+ }
+
+ABRT-source ::= INTEGER {acse-service-user(0), acse-service-provider(1)
+}(0..1, ...)
+
+ACSE-requirements ::= BIT STRING {
+ authentication(0), application-context-negotiation(1)}
+
+Application-context-name-list ::= SEQUENCE OF Application-context-name
+
+Application-context-name ::= OBJECT IDENTIFIER
+
+-- Application-entity title productions follow (not in alphabetical order)
+AP-title ::= CHOICE {
+ ap-title-form1 AP-title-form1,
+ ap-title-form2 AP-title-form2,
+ ...
+}
+
+AE-qualifier ::= CHOICE {
+ ae-qualifier-form1 AE-qualifier-form1,
+ ae-qualifier-form2 AE-qualifier-form2,
+ ...
+}
+
+-- When both AP-title and AE-qualifier data values are present in an AARQ or AARE APDU, both must
+-- have the same form to allow the construction of an AE-title as discussed in CCITT Rec. X.665 |
+-- ISO/IEC 9834-6.
+AP-title-form1 ::=
+ Name
+
+-- The value assigned to AP-title-form1 is The Directory Name of an application-process title.
+AE-qualifier-form1 ::=
+ RelativeDistinguishedName
+
+-- The value assigned to AE-qualifier-form1 is the relative distinguished name of a particular
+-- application-entity of the application-process identified by AP-title-form1.
+AP-title-form2 ::= OBJECT IDENTIFIER
+
+AE-qualifier-form2 ::= INTEGER
+
+AE-title ::= CHOICE {
+ ae-title-form1 AE-title-form1,
+ ae-title-form2 AE-title-form2,
+ ...
+}
+
+-- As defined in CCITT Rec. X.650 | ISO 7498-3, an application-entity title is composed of an application-
+-- process title and an application-entity qualifier. The ACSE protocol provides for the transfer of an
+-- application-entity title value by the transfer of its component values. However, the following data type
+-- is provided for International Standards that reference a single syntactic structure for AE titles.
+AE-title-form1 ::=
+ Name
+
+-- For access to The Directory (ITU-T Rec. X.500-Series | ISO/IEC 9594), an AE title has AE-title-form1.
+-- This value can be constructed from AP-title-form1 and AE-qualifier-form1 values contained in an
+-- AARQ or AARE APDU. A discussion of forming an AE-title-form1 from AP-title-form1 and AE-qualifier-
+-- form1 may be found in CCITT Rec. X.665 | ISO/IEC 9834-6.
+AE-title-form2 ::= OBJECT IDENTIFIER
+
+-- A discussion of forming an AE-title-form2 from AP-title-form2 and AE-qualifier-form2 may be
+-- found in CCITT Rec. X.665 | ISO/IEC 9834-6.
+AE-invocation-identifier ::= INTEGER
+
+AP-invocation-identifier ::= INTEGER
+
+-- End of Application-entity title productions
+Associate-result ::= INTEGER {
+ accepted(0), rejected-permanent(1), rejected-transient(2)}(0..2, ...)
+
+Associate-source-diagnostic ::= CHOICE {
+ acse-service-user
+ [1] INTEGER {null(0), no-reason-given(1),
+ application-context-name-not-supported(2),
+ calling-AP-title-not-recognized(3),
+ calling-AP-invocation-identifier-not-recognized(4),
+ calling-AE-qualifier-not-recognized(5),
+ calling-AE-invocation-identifier-not-recognized(6),
+ called-AP-title-not-recognized(7),
+ called-AP-invocation-identifier-not-recognized(8),
+ called-AE-qualifier-not-recognized(9),
+ called-AE-invocation-identifier-not-recognized(10),
+ authentication-mechanism-name-not-recognized(11),
+ authentication-mechanism-name-required(12),
+ authentication-failure(13), authentication-required(14)}
+ (0..14, ...),
+ acse-service-provider
+ [2] INTEGER {null(0), no-reason-given(1), no-common-acse-version(2)}
+ (0..2, ...)
+}
+
+Association-information ::= SEQUENCE SIZE (1, ..., 0 | 2..MAX) OF EXTERNAL
+
+Authentication-value ::= CHOICE {
+ charstring [0] IMPLICIT GraphicString,
+ bitstring [1] IMPLICIT BIT STRING,
+ external [2] IMPLICIT EXTERNAL,
+ other
+ [3] IMPLICIT SEQUENCE {other-mechanism-name
+ MECHANISM-NAME.&id({ObjectSet}),
+ other-mechanism-value
+ MECHANISM-NAME.&Type
+ ({ObjectSet}{@.other-mechanism-name})}
+}
+
+-- The abstract syntax of (calling/responding) authentication-value is determined by the authentication
+-- mechanism used during association establishment. The authentication mechanism is either explicitly
+-- denoted by the &id field (of type OBJECT IDENTIFIER) for a mechanism belonging to the class
+-- MECHANISM-NAME, or it is known implicitly by
+-- prior agreement between the communicating partners. If the "other" component is chosen, then
+-- the "mechanism-name" component must be present in accordance with
+-- ITU-T Rec. X.680 | ISO/IEC 8824. If the value "mechanism-name" occurs in the AARQ-apdu or the
+-- AARE-apdu, then that value must be the same as the value for "other-mechanism-name"
+Implementation-data ::= GraphicString
+
+Mechanism-name ::= OBJECT IDENTIFIER
+
+MECHANISM-NAME ::= TYPE-IDENTIFIER
+
+ObjectSet MECHANISM-NAME ::=
+ {...}
+
+Release-request-reason ::= INTEGER {normal(0), urgent(1), user-defined(30)
+}(0 | 1 | 30, ...)
+
+Release-response-reason ::= INTEGER {
+ normal(0), not-finished(1), user-defined(30)}(0 | 1 | 30, ...)
+
+END
+
+-- Generated by Asnp, the ASN.1 pretty-printer of France Telecom R&D
+
diff --git a/lib/asn1/test/asn1_SUITE_data/x420/AuthenticationFramework.asn b/lib/asn1/test/asn1_SUITE_data/x420/AuthenticationFramework.asn
new file mode 100644
index 0000000000..5cfa9062f0
--- /dev/null
+++ b/lib/asn1/test/asn1_SUITE_data/x420/AuthenticationFramework.asn
@@ -0,0 +1,290 @@
+-- Module AuthenticationFramework (X.509:08/1997)
+
+AuthenticationFramework {joint-iso-itu-t ds(5) module(1)
+ authenticationFramework(7) 3} DEFINITIONS ::=
+BEGIN
+
+-- EXPORTS All
+-- The types and values defined in this module are exported for use in the other ASN.1 modules contained
+-- within the Directory Specifications, and for the use of other applications which will use them to access
+-- Directory services. Other applications may use them for their own purposes, but this will not constrain
+-- extensions and modifications needed to maintain or improve the Directory service.
+IMPORTS
+ id-at, id-mr, informationFramework, upperBounds, selectedAttributeTypes,
+ basicAccessControl, certificateExtensions
+ FROM UsefulDefinitions {joint-iso-itu-t ds(5) module(1)
+ usefulDefinitions(0) 3}
+ Name, ATTRIBUTE, AttributeType, MATCHING-RULE, Attribute
+ FROM InformationFramework informationFramework
+ ub-user-password
+ FROM UpperBounds upperBounds
+ AuthenticationLevel
+ FROM BasicAccessControl basicAccessControl
+ UniqueIdentifier, octetStringMatch
+ FROM SelectedAttributeTypes selectedAttributeTypes
+ certificateExactMatch, certificatePairExactMatch, certificateListExactMatch,
+ GeneralNames
+ FROM CertificateExtensions certificateExtensions;
+
+-- basic certificate definition
+Certificate ::=
+ SIGNED
+ {SEQUENCE {version [0] Version DEFAULT v1,
+ serialNumber CertificateSerialNumber,
+ signature AlgorithmIdentifier,
+ issuer Name,
+ validity Validity,
+ subject Name,
+ subjectPublicKeyInfo SubjectPublicKeyInfo,
+ issuerUniqueIdentifier [1] IMPLICIT UniqueIdentifier OPTIONAL,
+ -- if present, version must be v2 or v3
+ subjectUniqueIdentifier [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
+
+AlgorithmIdentifier ::= SEQUENCE {
+ algorithm ALGORITHM.&id({SupportedAlgorithms}),
+ parameters ALGORITHM.&Type({SupportedAlgorithms}{@algorithm}) OPTIONAL
+}
+
+-- Definition of the following information object set is deferred, perhaps to standardized
+-- profiles or to protocol implementation conformance statements. The set is required to
+-- specify a table constraint on the parameters component of AlgorithmIdentifier.
+SupportedAlgorithms ALGORITHM ::=
+{...}
+
+Validity ::= SEQUENCE {notBefore Time,
+ notAfter Time
+}
+
+SubjectPublicKeyInfo ::= SEQUENCE {
+ algorithm AlgorithmIdentifier,
+ subjectPublicKey BIT STRING
+}
+
+Time ::= CHOICE {utcTime UTCTime,
+ generalizedTime GeneralizedTime
+}
+
+Extensions ::= SEQUENCE OF Extension
+
+-- For those extensions where ordering of individual extensions within the SEQUENCE is significant, the
+-- specification of those individual extensions shall include the rules for the significance of the order therein
+Extension ::= SEQUENCE {
+ extnId EXTENSION.&id({ExtensionSet}),
+ critical BOOLEAN DEFAULT FALSE,
+ extnValue OCTET STRING-- contains a DER encoding of a value of type &ExtnType
+-- for the extension object identified by extnId
+}
+
+ExtensionSet EXTENSION ::=
+ {...}
+
+EXTENSION ::= CLASS {&id OBJECT IDENTIFIER UNIQUE,
+ &ExtnType
+}WITH SYNTAX {SYNTAX &ExtnType
+ IDENTIFIED BY &id
+}
+
+-- other certificate constructs
+Certificates ::= SEQUENCE {
+ userCertificate Certificate,
+ certificationPath ForwardCertificationPath OPTIONAL
+}
+
+ForwardCertificationPath ::= SEQUENCE OF CrossCertificates
+
+CrossCertificates ::= SET OF Certificate
+
+CertificationPath ::= SEQUENCE {
+ userCertificate Certificate,
+ theCACertificates SEQUENCE OF CertificatePair OPTIONAL
+}
+
+CertificatePair ::= SEQUENCE {
+ issuedByThisCA [0] Certificate OPTIONAL,
+ issuedToThisCA [1] Certificate OPTIONAL
+ -- at least one of the pair shall be present
+}
+
+-- Certificate Revocation List (CRL)
+CertificateList ::=
+ SIGNED
+ {SEQUENCE {version Version OPTIONAL,
+ -- if present, version must be v2
+ signature AlgorithmIdentifier,
+ issuer Name,
+ thisUpdate Time,
+ nextUpdate Time OPTIONAL,
+ revokedCertificates
+ SEQUENCE OF
+ SEQUENCE {userCertificate CertificateSerialNumber,
+ revocationDate Time,
+ crlEntryExtensions Extensions OPTIONAL} OPTIONAL,
+ crlExtensions [0] Extensions OPTIONAL}}
+
+-- attribute certificate
+AttributeCertificationPath ::= SEQUENCE {
+ attributeCertificate AttributeCertificate,
+ acPath SEQUENCE OF ACPathData OPTIONAL
+}
+
+ACPathData ::= SEQUENCE {
+ certificate [0] Certificate OPTIONAL,
+ attributeCertificate [1] AttributeCertificate OPTIONAL
+}
+
+attributeCertificate ATTRIBUTE ::= {
+ WITH SYNTAX AttributeCertificate
+ EQUALITY MATCHING RULE attributeCertificateMatch
+ ID id-at-attributeCertificate
+}
+
+AttributeCertificate ::= SIGNED{AttributeCertificateInfo}
+
+AttributeCertificateInfo ::= SEQUENCE {
+ version Version DEFAULT v1,
+ subject
+ CHOICE {baseCertificateID [0] IssuerSerial, -- associated with a Public Key Certificate--
+ subjectName [1] GeneralNames}, -- associated with a name
+ issuer GeneralNames, -- CA issuing the attribute certificate
+ signature AlgorithmIdentifier,
+ serialNumber CertificateSerialNumber,
+ attCertValidityPeriod AttCertValidityPeriod,
+ attributes SEQUENCE OF Attribute,
+ issuerUniqueID UniqueIdentifier OPTIONAL,
+ extensions Extensions OPTIONAL
+}
+
+IssuerSerial ::= SEQUENCE {
+ issuer GeneralNames,
+ serial CertificateSerialNumber,
+ issuerUID UniqueIdentifier OPTIONAL
+}
+
+AttCertValidityPeriod ::= SEQUENCE {
+ notBeforeTime GeneralizedTime,
+ notAfterTime GeneralizedTime
+}
+
+attributeCertificateMatch MATCHING-RULE ::= {
+ SYNTAX AttributeCertificateAssertion
+ ID id-mr-attributeCertificateMatch
+}
+
+AttributeCertificateAssertion ::= SEQUENCE {
+ subject
+ [0] CHOICE {baseCertificateID [0] IssuerSerial,
+ subjectName [1] Name} OPTIONAL,
+ issuer [1] Name OPTIONAL,
+ attCertValidity [2] GeneralizedTime OPTIONAL,
+ attType [3] SET OF AttributeType OPTIONAL
+}
+
+-- At least one component of the sequence must be present
+-- attribute types
+userPassword ATTRIBUTE ::= {
+ WITH SYNTAX OCTET STRING(SIZE (0..ub-user-password))
+ EQUALITY MATCHING RULE octetStringMatch
+ ID id-at-userPassword
+}
+
+userCertificate ATTRIBUTE ::= {
+ WITH SYNTAX Certificate
+ EQUALITY MATCHING RULE certificateExactMatch
+ ID id-at-userCertificate
+}
+
+cACertificate ATTRIBUTE ::= {
+ WITH SYNTAX Certificate
+ EQUALITY MATCHING RULE certificateExactMatch
+ ID id-at-cAcertificate
+}
+
+crossCertificatePair ATTRIBUTE ::= {
+ WITH SYNTAX CertificatePair
+ EQUALITY MATCHING RULE certificatePairExactMatch
+ ID id-at-crossCertificatePair
+}
+
+authorityRevocationList ATTRIBUTE ::= {
+ WITH SYNTAX CertificateList
+ EQUALITY MATCHING RULE certificateListExactMatch
+ ID id-at-authorityRevocationList
+}
+
+certificateRevocationList ATTRIBUTE ::= {
+ WITH SYNTAX CertificateList
+ EQUALITY MATCHING RULE certificateListExactMatch
+ ID id-at-certificateRevocationList
+}
+
+attributeCertificateRevocationList ATTRIBUTE ::= {
+ WITH SYNTAX CertificateList
+ ID id-at-attributeCertificateRevocationList
+}
+
+-- information object classes
+ALGORITHM ::= TYPE-IDENTIFIER
+
+-- parameterized types
+HASH{ToBeHashed} ::= SEQUENCE {
+ algorithmIdentifier AlgorithmIdentifier,
+ hashValue
+ BIT STRING
+ (CONSTRAINED BY {
+ -- must be the result of applying a hashing procedure to the DER-encoded octets
+ -- of a value of -- ToBeHashed})
+}
+
+ENCRYPTED-HASH{ToBeSigned} ::=
+ BIT STRING
+ (CONSTRAINED BY {
+ -- must be the result of applying a hashing procedure to the DER-encoded octets
+ -- of a value of --ToBeSigned -- and then applying an encipherment procedure to those octets --})
+
+ENCRYPTED{ToBeEnciphered} ::=
+ BIT STRING
+ (CONSTRAINED BY {
+ -- must be the result of applying an encipherment procedure
+ -- to the BER-encoded octets of a value of --ToBeEnciphered})
+
+SIGNATURE{ToBeSigned} ::= SEQUENCE {
+ algorithmIdentifier AlgorithmIdentifier,
+ encrypted ENCRYPTED-HASH{ToBeSigned}
+}
+
+SIGNED{ToBeSigned} ::= SEQUENCE {
+ toBeSigned ToBeSigned,
+ COMPONENTS OF SIGNATURE{ToBeSigned}
+}
+
+-- object identifier assignments
+id-at-userPassword OBJECT IDENTIFIER ::=
+ {id-at 35}
+
+id-at-userCertificate OBJECT IDENTIFIER ::= {id-at 36}
+
+id-at-cAcertificate OBJECT IDENTIFIER ::= {id-at 37}
+
+id-at-authorityRevocationList OBJECT IDENTIFIER ::= {id-at 38}
+
+id-at-certificateRevocationList OBJECT IDENTIFIER ::= {id-at 39}
+
+id-at-crossCertificatePair OBJECT IDENTIFIER ::= {id-at 40}
+
+id-at-attributeCertificate OBJECT IDENTIFIER ::= {id-at 58}
+
+id-at-attributeCertificateRevocationList OBJECT IDENTIFIER ::= {id-at 59}
+
+id-mr-attributeCertificateMatch OBJECT IDENTIFIER ::= {id-mr 42}
+
+END
+
+-- Generated by Asnp, the ASN.1 pretty-printer of France Telecom R&D
+
diff --git a/lib/asn1/test/asn1_SUITE_data/x420/BasicAccessControl.asn b/lib/asn1/test/asn1_SUITE_data/x420/BasicAccessControl.asn
new file mode 100644
index 0000000000..d8b2b687ae
--- /dev/null
+++ b/lib/asn1/test/asn1_SUITE_data/x420/BasicAccessControl.asn
@@ -0,0 +1,184 @@
+-- Module BasicAccessControl (X.501:08/1997)
+BasicAccessControl {joint-iso-itu-t ds(5) module(1) basicAccessControl(24) 3}
+DEFINITIONS ::=
+BEGIN
+
+-- EXPORTS All
+-- The types and values defined in this module are exported for use in the other ASN.1 modules contained
+-- within the Directory Specifications, and for the use of other applications which will use them to access
+-- Directory services. Other applications may use them for their own purposes, but this will not constrain
+-- extensions and modifications needed to maintain or improve the Directory service.
+IMPORTS
+ id-aca, id-acScheme, informationFramework, upperBounds,
+ selectedAttributeTypes, directoryAbstractService
+ FROM UsefulDefinitions {joint-iso-itu-t ds(5) module(1)
+ usefulDefinitions(0) 3}
+ ATTRIBUTE, AttributeType, DistinguishedName, ContextAssertion,
+ SubtreeSpecification, SupportedAttributes, MATCHING-RULE,
+ objectIdentifierMatch, Refinement
+ FROM InformationFramework informationFramework
+ Filter
+ FROM DirectoryAbstractService directoryAbstractService
+ ub-tag
+ FROM UpperBounds upperBounds
+ NameAndOptionalUID, directoryStringFirstComponentMatch, DirectoryString{}
+ FROM SelectedAttributeTypes selectedAttributeTypes;
+
+-- types
+ACIItem ::= SEQUENCE {
+ identificationTag DirectoryString{ub-tag},
+ precedence Precedence,
+ authenticationLevel AuthenticationLevel,
+ itemOrUserFirst
+ CHOICE {itemFirst
+ [0] SEQUENCE {protectedItems ProtectedItems,
+ itemPermissions SET OF ItemPermission},
+ userFirst
+ [1] SEQUENCE {userClasses UserClasses,
+ userPermissions SET OF UserPermission}}
+}
+
+Precedence ::= INTEGER(0..255)
+
+ProtectedItems ::= SEQUENCE {
+ entry [0] NULL OPTIONAL,
+ allUserAttributeTypes [1] NULL OPTIONAL,
+ attributeType
+ [2] SET SIZE (1..MAX) OF AttributeType OPTIONAL,
+ allAttributeValues
+ [3] SET SIZE (1..MAX) OF AttributeType OPTIONAL,
+ allUserAttributeTypesAndValues [4] NULL OPTIONAL,
+ attributeValue
+ [5] SET SIZE (1..MAX) OF AttributeTypeAndValue OPTIONAL,
+ selfValue
+ [6] SET SIZE (1..MAX) OF AttributeType OPTIONAL,
+ rangeOfValues [7] Filter OPTIONAL,
+ maxValueCount
+ [8] SET SIZE (1..MAX) OF MaxValueCount OPTIONAL,
+ maxImmSub [9] INTEGER OPTIONAL,
+ restrictedBy
+ [10] SET SIZE (1..MAX) OF RestrictedValue OPTIONAL,
+ contexts
+ [11] SET SIZE (1..MAX) OF ContextAssertion OPTIONAL,
+ classes [12] Refinement OPTIONAL
+}
+
+MaxValueCount ::= SEQUENCE {type AttributeType,
+ maxCount INTEGER
+}
+
+RestrictedValue ::= SEQUENCE {type AttributeType,
+ valuesIn AttributeType
+}
+
+UserClasses ::= SEQUENCE {
+ allUsers [0] NULL OPTIONAL,
+ thisEntry [1] NULL OPTIONAL,
+ name [2] SET SIZE (1..MAX) OF NameAndOptionalUID OPTIONAL,
+ userGroup [3] SET SIZE (1..MAX) OF NameAndOptionalUID OPTIONAL,
+ -- dn component must be the name of an
+ -- entry of GroupOfUniqueNames
+ subtree [4] SET SIZE (1..MAX) OF SubtreeSpecification OPTIONAL
+}
+
+ItemPermission ::= SEQUENCE {
+ precedence Precedence OPTIONAL,
+ -- defaults to precedence in ACIItem
+ userClasses UserClasses,
+ grantsAndDenials GrantsAndDenials
+}
+
+UserPermission ::= SEQUENCE {
+ precedence Precedence OPTIONAL,
+ -- defaults to precedence in ACIItem
+ protectedItems ProtectedItems,
+ grantsAndDenials GrantsAndDenials
+}
+
+AuthenticationLevel ::= CHOICE {
+ basicLevels
+ SEQUENCE {level ENUMERATED {none(0), simple(1), strong(2)},
+ localQualifier INTEGER OPTIONAL,
+ signed BOOLEAN DEFAULT FALSE},
+ other EXTERNAL
+}
+
+GrantsAndDenials ::= BIT STRING {
+ -- permissions that may be used in conjunction
+ -- with any component of ProtectedItems
+ grantAdd(0), denyAdd(1), grantDiscloseOnError(2), denyDiscloseOnError(3),
+ grantRead(4), denyRead(5), grantRemove(6),
+ denyRemove(7),
+ -- permissions that may be used only in conjunction
+ -- with the entry component
+ grantBrowse(8), denyBrowse(9), grantExport(10), denyExport(11),
+ grantImport(12), denyImport(13), grantModify(14), denyModify(15),
+ grantRename(16), denyRename(17), grantReturnDN(18),
+ denyReturnDN(19),
+ -- permissions that may be used in conjunction
+ -- with any component, except entry, of ProtectedItems
+ grantCompare(20), denyCompare(21), grantFilterMatch(22), denyFilterMatch(23),
+ grantInvoke(24), denyInvoke(25)}
+
+AttributeTypeAndValue ::= SEQUENCE {
+ type ATTRIBUTE.&id({SupportedAttributes}),
+ value ATTRIBUTE.&Type({SupportedAttributes}{@type})
+}
+
+-- attributes
+accessControlScheme ATTRIBUTE ::= {
+ WITH SYNTAX OBJECT IDENTIFIER
+ EQUALITY MATCHING RULE objectIdentifierMatch
+ SINGLE VALUE TRUE
+ USAGE directoryOperation
+ ID id-aca-accessControlScheme
+}
+
+prescriptiveACI ATTRIBUTE ::= {
+ WITH SYNTAX ACIItem
+ EQUALITY MATCHING RULE directoryStringFirstComponentMatch
+ USAGE directoryOperation
+ ID id-aca-prescriptiveACI
+}
+
+entryACI ATTRIBUTE ::= {
+ WITH SYNTAX ACIItem
+ EQUALITY MATCHING RULE directoryStringFirstComponentMatch
+ USAGE directoryOperation
+ ID id-aca-entryACI
+}
+
+subentryACI ATTRIBUTE ::= {
+ WITH SYNTAX ACIItem
+ EQUALITY MATCHING RULE directoryStringFirstComponentMatch
+ USAGE directoryOperation
+ ID id-aca-subentryACI
+}
+
+-- object identifier assignments
+-- attributes
+id-aca-accessControlScheme OBJECT IDENTIFIER ::=
+ {id-aca 1}
+
+id-aca-prescriptiveACI OBJECT IDENTIFIER ::= {id-aca 4}
+
+id-aca-entryACI OBJECT IDENTIFIER ::= {id-aca 5}
+
+id-aca-subentryACI OBJECT IDENTIFIER ::= {id-aca 6}
+
+-- access control schemes -
+basicAccessControlScheme OBJECT IDENTIFIER ::=
+ {id-acScheme 1}
+
+simplifiedAccessControlScheme OBJECT IDENTIFIER ::= {id-acScheme 2}
+
+rule-based-access-control OBJECT IDENTIFIER ::= {id-acScheme 3}
+
+rule-and-basic-access-control OBJECT IDENTIFIER ::= {id-acScheme 4}
+
+rule-and-simple-access-control OBJECT IDENTIFIER ::= {id-acScheme 5}
+
+END -- BasicAccessControl
+
+-- Generated by Asnp, the ASN.1 pretty-printer of France Telecom R&D
+
diff --git a/lib/asn1/test/asn1_SUITE_data/x420/CertificateExtensions.asn b/lib/asn1/test/asn1_SUITE_data/x420/CertificateExtensions.asn
new file mode 100644
index 0000000000..0daf2208e9
--- /dev/null
+++ b/lib/asn1/test/asn1_SUITE_data/x420/CertificateExtensions.asn
@@ -0,0 +1,498 @@
+-- Module CertificateExtensions (X.509:08/1997)
+
+CertificateExtensions {joint-iso-itu-t ds(5) module(1)
+ certificateExtensions(26) 0} DEFINITIONS IMPLICIT TAGS ::=
+BEGIN
+
+-- EXPORTS ALL
+IMPORTS
+ id-at, id-ce, id-mr, informationFramework, authenticationFramework,
+ selectedAttributeTypes, upperBounds
+ FROM UsefulDefinitions {joint-iso-itu-t ds(5) module(1)
+ usefulDefinitions(0) 3}
+ Name, RelativeDistinguishedName, ATTRIBUTE, Attribute, MATCHING-RULE
+ FROM InformationFramework informationFramework
+ CertificateSerialNumber, CertificateList, AlgorithmIdentifier, EXTENSION,
+ Time
+ FROM AuthenticationFramework authenticationFramework
+ DirectoryString{}
+ FROM SelectedAttributeTypes selectedAttributeTypes
+ ub-name
+ FROM UpperBounds upperBounds
+ ORAddress
+ FROM MTSAbstractService {joint-iso-itu-t mhs(6) mts(3) modules(0)
+ mts-abstract-service(1) version-1999(1)};
+
+-- Unless explicitly noted otherwise, there is no significance to the ordering
+-- of components of a SEQUENCE OF construct in this Specification.
+-- Key and policy information extensions
+authorityKeyIdentifier EXTENSION ::= {
+ SYNTAX AuthorityKeyIdentifier
+ IDENTIFIED BY id-ce-authorityKeyIdentifier
+}
+
+AuthorityKeyIdentifier ::= SEQUENCE {
+ keyIdentifier [0] KeyIdentifier OPTIONAL,
+ authorityCertIssuer [1] GeneralNames OPTIONAL,
+ authorityCertSerialNumber [2] CertificateSerialNumber OPTIONAL
+}
+(WITH COMPONENTS {
+ ...,
+ authorityCertIssuer PRESENT,
+ authorityCertSerialNumber PRESENT
+ } |
+ WITH COMPONENTS {
+ ...,
+ authorityCertIssuer ABSENT,
+ authorityCertSerialNumber ABSENT
+ })
+
+KeyIdentifier ::= OCTET STRING
+
+subjectKeyIdentifier EXTENSION ::= {
+ SYNTAX SubjectKeyIdentifier
+ IDENTIFIED BY id-ce-subjectKeyIdentifier
+}
+
+SubjectKeyIdentifier ::= KeyIdentifier
+
+keyUsage EXTENSION ::= {SYNTAX KeyUsage
+ IDENTIFIED BY id-ce-keyUsage
+}
+
+KeyUsage ::= BIT STRING {
+ digitalSignature(0), nonRepudiation(1), keyEncipherment(2),
+ dataEncipherment(3), keyAgreement(4), keyCertSign(5), cRLSign(6),
+ encipherOnly(7), decipherOnly(8)}
+
+extKeyUsage EXTENSION ::= {
+ SYNTAX SEQUENCE SIZE (1..MAX) OF KeyPurposeId
+ IDENTIFIED BY id-ce-extKeyUsage
+}
+
+KeyPurposeId ::= OBJECT IDENTIFIER
+
+privateKeyUsagePeriod EXTENSION ::= {
+ SYNTAX PrivateKeyUsagePeriod
+ IDENTIFIED BY id-ce-privateKeyUsagePeriod
+}
+
+PrivateKeyUsagePeriod ::= SEQUENCE {
+ notBefore [0] GeneralizedTime OPTIONAL,
+ notAfter [1] GeneralizedTime OPTIONAL
+}
+(WITH COMPONENTS {
+ ...,
+ notBefore PRESENT
+ } | WITH COMPONENTS {
+ ...,
+ notAfter PRESENT
+ })
+
+certificatePolicies EXTENSION ::= {
+ SYNTAX CertificatePoliciesSyntax
+ IDENTIFIED BY id-ce-certificatePolicies
+}
+
+CertificatePoliciesSyntax ::= SEQUENCE SIZE (1..MAX) OF PolicyInformation
+
+PolicyInformation ::= SEQUENCE {
+ policyIdentifier CertPolicyId,
+ policyQualifiers SEQUENCE SIZE (1..MAX) OF PolicyQualifierInfo OPTIONAL
+}
+
+CertPolicyId ::= OBJECT IDENTIFIER
+
+PolicyQualifierInfo ::= SEQUENCE {
+ policyQualifierId CERT-POLICY-QUALIFIER.&id({SupportedPolicyQualifiers}),
+ qualifier
+ CERT-POLICY-QUALIFIER.&Qualifier
+ ({SupportedPolicyQualifiers}{@policyQualifierId}) OPTIONAL
+}
+
+SupportedPolicyQualifiers CERT-POLICY-QUALIFIER ::=
+ {...}
+
+CERT-POLICY-QUALIFIER ::= CLASS {
+ &id OBJECT IDENTIFIER UNIQUE,
+ &Qualifier OPTIONAL
+}WITH SYNTAX {POLICY-QUALIFIER-ID &id
+ [QUALIFIER-TYPE &Qualifier]
+}
+
+policyMappings EXTENSION ::= {
+ SYNTAX PolicyMappingsSyntax
+ IDENTIFIED BY id-ce-policyMappings
+}
+
+PolicyMappingsSyntax ::=
+ SEQUENCE SIZE (1..MAX) OF
+ SEQUENCE {issuerDomainPolicy CertPolicyId,
+ subjectDomainPolicy CertPolicyId}
+
+supportedAlgorithms ATTRIBUTE ::= {
+ WITH SYNTAX SupportedAlgorithm
+ EQUALITY MATCHING RULE algorithmIdentifierMatch
+ ID id-at-supportedAlgorithms
+}
+
+SupportedAlgorithm ::= SEQUENCE {
+ algorithmIdentifier AlgorithmIdentifier,
+ intendedUsage [0] KeyUsage OPTIONAL,
+ intendedCertificatePolicies [1] CertificatePoliciesSyntax OPTIONAL
+}
+
+-- Certificate subject and certificate issuer attributes extensions
+subjectAltName EXTENSION ::= {
+ SYNTAX GeneralNames
+ IDENTIFIED BY id-ce-subjectAltName
+}
+
+GeneralNames ::= SEQUENCE SIZE (1..MAX) OF GeneralName
+
+GeneralName ::= CHOICE {
+ otherName [0] INSTANCE OF OTHER-NAME,
+ rfc822Name [1] IA5String,
+ dNSName [2] IA5String,
+ x400Address [3] ORAddress,
+ directoryName [4] Name,
+ ediPartyName [5] EDIPartyName,
+ uniformResourceIdentifier [6] IA5String,
+ iPAddress [7] OCTET STRING,
+ registeredID [8] OBJECT IDENTIFIER
+}
+
+OTHER-NAME ::= TYPE-IDENTIFIER
+
+EDIPartyName ::= SEQUENCE {
+ nameAssigner [0] DirectoryString{ub-name} OPTIONAL,
+ partyName [1] DirectoryString{ub-name}
+}
+
+issuerAltName EXTENSION ::= {
+ SYNTAX GeneralNames
+ IDENTIFIED BY id-ce-issuerAltName
+}
+
+subjectDirectoryAttributes EXTENSION ::= {
+ SYNTAX AttributesSyntax
+ IDENTIFIED BY id-ce-subjectDirectoryAttributes
+}
+
+AttributesSyntax ::= SEQUENCE SIZE (1..MAX) OF Attribute
+
+-- Certification path constraints extensions
+basicConstraints EXTENSION ::= {
+ SYNTAX BasicConstraintsSyntax
+ IDENTIFIED BY id-ce-basicConstraints
+}
+
+BasicConstraintsSyntax ::= SEQUENCE {
+ cA BOOLEAN DEFAULT FALSE,
+ pathLenConstraint INTEGER(0..MAX) OPTIONAL
+}
+
+nameConstraints EXTENSION ::= {
+ SYNTAX NameConstraintsSyntax
+ IDENTIFIED BY id-ce-nameConstraint
+}
+
+NameConstraintsSyntax ::= SEQUENCE {
+ permittedSubtrees [0] GeneralSubtrees OPTIONAL,
+ excludedSubtrees [1] GeneralSubtrees OPTIONAL,
+ requiredNameForms [2] NameForms OPTIONAL
+}
+
+GeneralSubtrees ::= SEQUENCE SIZE (1..MAX) OF GeneralSubtree
+
+GeneralSubtree ::= SEQUENCE {
+ base GeneralName,
+ minimum [0] BaseDistance DEFAULT 0,
+ maximum [1] BaseDistance OPTIONAL
+}
+
+BaseDistance ::= INTEGER(0..MAX)
+
+NameForms ::= SEQUENCE {
+ basicNameForms [0] BasicNameForms OPTIONAL,
+ otherNameForms [1] SEQUENCE SIZE (1..MAX) OF OBJECT IDENTIFIER OPTIONAL
+}(ALL EXCEPT ({ --none; i.e.:at least one component shall be present--}))
+
+BasicNameForms ::= BIT STRING {
+ rfc822Name(0), dNSName(1), x400Address(2), directoryName(3), ediPartyName(4),
+ uniformResourceIdentifier(5), iPAddress(6), registeredID(7)}(SIZE (1..MAX))
+
+policyConstraints EXTENSION ::= {
+ SYNTAX PolicyConstraintsSyntax
+ IDENTIFIED BY id-ce-policyConstraints
+}
+
+PolicyConstraintsSyntax ::= SEQUENCE {
+ requireExplicitPolicy [0] SkipCerts OPTIONAL,
+ inhibitPolicyMapping [1] SkipCerts OPTIONAL
+}
+
+SkipCerts ::= INTEGER(0..MAX)
+
+CertPolicySet ::= SEQUENCE SIZE (1..MAX) OF CertPolicyId
+
+-- Basic CRL extensions
+cRLNumber EXTENSION ::= {
+ SYNTAX CRLNumber
+ IDENTIFIED BY id-ce-cRLNumber
+}
+
+CRLNumber ::= INTEGER(0..MAX)
+
+reasonCode EXTENSION ::= {
+ SYNTAX CRLReason
+ IDENTIFIED BY id-ce-reasonCode
+}
+
+CRLReason ::= ENUMERATED {
+ unspecified(0), keyCompromise(1), cACompromise(2), affiliationChanged(3),
+ superseded(4), cessationOfOperation(5), certificateHold(6), removeFromCRL(8)
+}
+
+instructionCode EXTENSION ::= {
+ SYNTAX HoldInstruction
+ IDENTIFIED BY id-ce-instructionCode
+}
+
+HoldInstruction ::= OBJECT IDENTIFIER
+
+invalidityDate EXTENSION ::= {
+ SYNTAX GeneralizedTime
+ IDENTIFIED BY id-ce-invalidityDate
+}
+
+-- CRL distribution points and delta-CRL extensions
+cRLDistributionPoints EXTENSION ::= {
+ SYNTAX CRLDistPointsSyntax
+ IDENTIFIED BY id-ce-cRLDistributionPoints
+}
+
+CRLDistPointsSyntax ::= SEQUENCE SIZE (1..MAX) OF DistributionPoint
+
+DistributionPoint ::= SEQUENCE {
+ distributionPoint [0] DistributionPointName OPTIONAL,
+ reasons [1] ReasonFlags OPTIONAL,
+ cRLIssuer [2] GeneralNames OPTIONAL
+}
+
+DistributionPointName ::= CHOICE {
+ fullName [0] GeneralNames,
+ nameRelativeToCRLIssuer [1] RelativeDistinguishedName
+}
+
+ReasonFlags ::= BIT STRING {
+ unused(0), keyCompromise(1), caCompromise(2), affiliationChanged(3),
+ superseded(4), cessationOfOperation(5), certificateHold(6)}
+
+issuingDistributionPoint EXTENSION ::= {
+ SYNTAX IssuingDistPointSyntax
+ IDENTIFIED BY id-ce-issuingDistributionPoint
+}
+
+IssuingDistPointSyntax ::= SEQUENCE {
+ distributionPoint [0] DistributionPointName OPTIONAL,
+ onlyContainsUserCerts [1] BOOLEAN DEFAULT FALSE,
+ onlyContainsCACerts [2] BOOLEAN DEFAULT FALSE,
+ onlySomeReasons [3] ReasonFlags OPTIONAL,
+ indirectCRL [4] BOOLEAN DEFAULT FALSE
+}
+
+certificateIssuer EXTENSION ::= {
+ SYNTAX GeneralNames
+ IDENTIFIED BY id-ce-certificateIssuer
+}
+
+deltaCRLIndicator EXTENSION ::= {
+ SYNTAX BaseCRLNumber
+ IDENTIFIED BY id-ce-deltaCRLIndicator
+}
+
+BaseCRLNumber ::= CRLNumber
+
+deltaRevocationList ATTRIBUTE ::= {
+ WITH SYNTAX CertificateList
+ EQUALITY MATCHING RULE certificateListExactMatch
+ ID id-at-deltaRevocationList
+}
+
+-- Matching rules
+certificateExactMatch MATCHING-RULE ::= {
+ SYNTAX CertificateExactAssertion
+ ID id-mr-certificateExactMatch
+}
+
+CertificateExactAssertion ::= SEQUENCE {
+ serialNumber CertificateSerialNumber,
+ issuer Name
+}
+
+certificateMatch MATCHING-RULE ::= {
+ SYNTAX CertificateAssertion
+ ID id-mr-certificateMatch
+}
+
+CertificateAssertion ::= SEQUENCE {
+ serialNumber [0] CertificateSerialNumber OPTIONAL,
+ issuer [1] Name OPTIONAL,
+ subjectKeyIdentifier [2] SubjectKeyIdentifier OPTIONAL,
+ authorityKeyIdentifier [3] AuthorityKeyIdentifier OPTIONAL,
+ certificateValid [4] Time OPTIONAL,
+ privateKeyValid [5] GeneralizedTime OPTIONAL,
+ subjectPublicKeyAlgID [6] OBJECT IDENTIFIER OPTIONAL,
+ keyUsage [7] KeyUsage OPTIONAL,
+ subjectAltName [8] AltNameType OPTIONAL,
+ policy [9] CertPolicySet OPTIONAL,
+ pathToName [10] Name OPTIONAL
+}
+
+AltNameType ::= CHOICE {
+ builtinNameForm
+ ENUMERATED {rfc822Name(1), dNSName(2), x400Address(3), directoryName(4),
+ ediPartyName(5), uniformResourceIdentifier(6), iPAddress(7),
+ registeredId(8)},
+ otherNameForm OBJECT IDENTIFIER
+}
+
+certificatePairExactMatch MATCHING-RULE ::= {
+ SYNTAX CertificatePairExactAssertion
+ ID id-mr-certificatePairExactMatch
+}
+
+CertificatePairExactAssertion ::= SEQUENCE {
+ forwardAssertion [0] CertificateExactAssertion OPTIONAL,
+ reverseAssertion [1] CertificateExactAssertion OPTIONAL
+}
+(WITH COMPONENTS {
+ ...,
+ forwardAssertion PRESENT
+ } | WITH COMPONENTS {
+ ...,
+ reverseAssertion PRESENT
+ })
+
+certificatePairMatch MATCHING-RULE ::= {
+ SYNTAX CertificatePairAssertion
+ ID id-mr-certificatePairMatch
+}
+
+CertificatePairAssertion ::= SEQUENCE {
+ forwardAssertion [0] CertificateAssertion OPTIONAL,
+ reverseAssertion [1] CertificateAssertion OPTIONAL
+}
+(WITH COMPONENTS {
+ ...,
+ forwardAssertion PRESENT
+ } | WITH COMPONENTS {
+ ...,
+ reverseAssertion PRESENT
+ })
+
+certificateListExactMatch MATCHING-RULE ::= {
+ SYNTAX CertificateListExactAssertion
+ ID id-mr-certificateListExactMatch
+}
+
+CertificateListExactAssertion ::= SEQUENCE {
+ issuer Name,
+ thisUpdate Time,
+ distributionPoint DistributionPointName OPTIONAL
+}
+
+certificateListMatch MATCHING-RULE ::= {
+ SYNTAX CertificateListAssertion
+ ID id-mr-certificateListMatch
+}
+
+CertificateListAssertion ::= SEQUENCE {
+ issuer Name OPTIONAL,
+ minCRLNumber [0] CRLNumber OPTIONAL,
+ maxCRLNumber [1] CRLNumber OPTIONAL,
+ reasonFlags ReasonFlags OPTIONAL,
+ dateAndTime Time OPTIONAL,
+ distributionPoint [2] DistributionPointName OPTIONAL
+}
+
+algorithmIdentifierMatch MATCHING-RULE ::= {
+ SYNTAX AlgorithmIdentifier
+ ID id-mr-algorithmIdentifierMatch
+}
+
+-- Object identifier assignments
+id-at-supportedAlgorithms OBJECT IDENTIFIER ::=
+ {id-at 52}
+
+id-at-deltaRevocationList OBJECT IDENTIFIER ::= {id-at 53}
+
+id-ce-subjectDirectoryAttributes OBJECT IDENTIFIER ::= {id-ce 9}
+
+id-ce-subjectKeyIdentifier OBJECT IDENTIFIER ::= {id-ce 14}
+
+id-ce-keyUsage OBJECT IDENTIFIER ::= {id-ce 15}
+
+id-ce-privateKeyUsagePeriod OBJECT IDENTIFIER ::= {id-ce 16}
+
+id-ce-subjectAltName OBJECT IDENTIFIER ::= {id-ce 17}
+
+id-ce-issuerAltName OBJECT IDENTIFIER ::= {id-ce 18}
+
+id-ce-basicConstraints OBJECT IDENTIFIER ::= {id-ce 19}
+
+id-ce-cRLNumber OBJECT IDENTIFIER ::= {id-ce 20}
+
+id-ce-reasonCode OBJECT IDENTIFIER ::= {id-ce 21}
+
+id-ce-instructionCode OBJECT IDENTIFIER ::= {id-ce 23}
+
+id-ce-invalidityDate OBJECT IDENTIFIER ::= {id-ce 24}
+
+id-ce-deltaCRLIndicator OBJECT IDENTIFIER ::= {id-ce 27}
+
+id-ce-issuingDistributionPoint OBJECT IDENTIFIER ::= {id-ce 28}
+
+id-ce-certificateIssuer OBJECT IDENTIFIER ::= {id-ce 29}
+
+id-ce-nameConstraint OBJECT IDENTIFIER ::= {id-ce 30 1}
+
+id-ce-cRLDistributionPoints OBJECT IDENTIFIER ::= {id-ce 31}
+
+id-ce-certificatePolicies OBJECT IDENTIFIER ::= {id-ce 32}
+
+id-ce-policyMappings OBJECT IDENTIFIER ::= {id-ce 33}
+
+-- deprecated OBJECT IDENTIFIER ::= {id-ce 34}
+id-ce-authorityKeyIdentifier OBJECT IDENTIFIER ::=
+ {id-ce 35}
+
+id-ce-policyConstraints OBJECT IDENTIFIER ::= {id-ce 36}
+
+id-ce-extKeyUsage OBJECT IDENTIFIER ::= {id-ce 37}
+
+id-mr-certificateExactMatch OBJECT IDENTIFIER ::= {id-mr 34}
+
+id-mr-certificateMatch OBJECT IDENTIFIER ::= {id-mr 35}
+
+id-mr-certificatePairExactMatch OBJECT IDENTIFIER ::= {id-mr 36}
+
+id-mr-certificatePairMatch OBJECT IDENTIFIER ::= {id-mr 37}
+
+id-mr-certificateListExactMatch OBJECT IDENTIFIER ::= {id-mr 38}
+
+id-mr-certificateListMatch OBJECT IDENTIFIER ::= {id-mr 39}
+
+id-mr-algorithmIdentifierMatch OBJECT IDENTIFIER ::= {id-mr 40}
+
+id-ce-inhibitAnyPolicy OBJECT IDENTIFIER ::= {id-ce 54}
+
+-- The following OBJECT IDENTIFIERS are not used by this Specification:
+-- {id-ce 2}, {id-ce 3}, {id-ce 4}, {id-ce 5}, {id-ce 6}, {id-ce 7},
+-- {id-ce 8}, {id-ce 10}, {id-ce 11}, {id-ce 12}, {id-ce 13},
+-- {id-ce 22}, {id-ce 25}, {id-ce 26}, {id-ce 30}
+END
+
+-- Generated by Asnp, the ASN.1 pretty-printer of France Telecom R&D
+
diff --git a/lib/asn1/test/asn1_SUITE_data/x420/Character-Coding-Attributes.asn b/lib/asn1/test/asn1_SUITE_data/x420/Character-Coding-Attributes.asn
new file mode 100644
index 0000000000..04060cf060
--- /dev/null
+++ b/lib/asn1/test/asn1_SUITE_data/x420/Character-Coding-Attributes.asn
@@ -0,0 +1,17 @@
+-- Module Character-Coding-Attributes (T.416:03/1993)
+
+Character-Coding-Attributes {2 8 1 6 3} DEFINITIONS ::=
+BEGIN
+
+EXPORTS Character-Coding-Attributes;
+
+Character-Coding-Attributes ::= SET {
+}
+
+-- no character coding attributes
+-- are defined in this part of
+-- ITU-T Rec. T.410-Series | ISO/IEC 8613
+END
+
+-- Generated by Asnp, the ASN.1 pretty-printer of France Telecom R&D
+
diff --git a/lib/asn1/test/asn1_SUITE_data/x420/Character-Presentation-Attributes.asn b/lib/asn1/test/asn1_SUITE_data/x420/Character-Presentation-Attributes.asn
new file mode 100644
index 0000000000..aed48ac26b
--- /dev/null
+++ b/lib/asn1/test/asn1_SUITE_data/x420/Character-Presentation-Attributes.asn
@@ -0,0 +1,125 @@
+-- Module Character-Presentation-Attributes (T.416:03/1993)
+
+Character-Presentation-Attributes {2 8 1 6 2} DEFINITIONS ::=
+BEGIN
+
+EXPORTS
+ Character-Attributes, One-Of-Four-Angles, One-Of-Two-Angles, Measure-Pair,
+ Alignment, Layout-Table, Graphic-Rendition, Formatting-Indicator,
+ Character-Fonts, Itemization, Kerning-Offset, Proportional-Line-Spacing,
+ Pairwise-Kerning;
+
+Character-Attributes ::= SET {
+ character-path [0] IMPLICIT One-Of-Four-Angles OPTIONAL,
+ line-progression [1] IMPLICIT One-Of-Two-Angles OPTIONAL,
+ character-orientation [2] IMPLICIT One-Of-Four-Angles OPTIONAL,
+ initial-offset [3] IMPLICIT Measure-Pair OPTIONAL,
+ character-spacing [6] IMPLICIT INTEGER OPTIONAL,
+ line-spacing [7] IMPLICIT INTEGER OPTIONAL,
+ alignment [8] IMPLICIT Alignment OPTIONAL,
+ line-layout-table [9] IMPLICIT Layout-Table OPTIONAL,
+ graphic-rendition [10] IMPLICIT Graphic-Rendition OPTIONAL,
+ formatting-indicator [11] IMPLICIT Formatting-Indicator OPTIONAL,
+ character-fonts [12] IMPLICIT Character-Fonts OPTIONAL,
+ graphic-char-subrepertoire [13] IMPLICIT INTEGER OPTIONAL,
+ itemization [14] IMPLICIT Itemization OPTIONAL,
+ widow-size [15] IMPLICIT INTEGER OPTIONAL,
+ orphan-size [16] IMPLICIT INTEGER OPTIONAL,
+ graphic-character-sets [17] IMPLICIT OCTET STRING OPTIONAL,
+ indentation [19] IMPLICIT INTEGER OPTIONAL,
+ kerning-offset [20] IMPLICIT Kerning-Offset OPTIONAL,
+ proportional-line-spacing [21] IMPLICIT Proportional-Line-Spacing OPTIONAL,
+ pairwise-kerning [22] IMPLICIT Pairwise-Kerning OPTIONAL,
+ first-line-offset [23] IMPLICIT INTEGER OPTIONAL,
+ code-extension-announcers [24] IMPLICIT OCTET STRING OPTIONAL
+}
+
+One-Of-Four-Angles ::= INTEGER {d0(0), d90(1), d180(2), d270(3)}
+
+One-Of-Two-Angles ::= INTEGER {d90(1), d270(3)}
+
+Measure-Pair ::= SEQUENCE {
+ horizontal [0] IMPLICIT INTEGER,
+ vertical [1] IMPLICIT INTEGER
+}
+
+Alignment ::= INTEGER {
+ start-aligned(0), end-aligned(1), centred(2), justified(3)}
+
+Layout-Table ::= SET OF Tabulation-Stop
+
+Tabulation-Stop ::= SET {
+ tabulation-reference [0] IMPLICIT NumericString,
+ tabulation-position [1] IMPLICIT INTEGER,
+ alignment
+ [2] IMPLICIT INTEGER {start-aligned(0), end-aligned(1), centred(2),
+ aligned-around(3)},
+ alignment-character-string [3] IMPLICIT OCTET STRING OPTIONAL
+}
+
+-- string of graphic characters
+-- from the set of graphic elements
+-- specified by the presentation
+-- attributes "graphic character
+-- sets" and "graphic character
+-- subrepertoire"
+Graphic-Rendition ::= SET OF Graphic-Rendition-Aspect
+
+Character-Fonts ::= SET {
+ primary-font [0] IMPLICIT Font-Type OPTIONAL,
+ first-alternative-font [1] IMPLICIT Font-Type OPTIONAL,
+ second-alternative-font [2] IMPLICIT Font-Type OPTIONAL,
+ third-alternative-font [3] IMPLICIT Font-Type OPTIONAL,
+ fourth-alternative-font [4] IMPLICIT Font-Type OPTIONAL,
+ fifth-alternative-font [5] IMPLICIT Font-Type OPTIONAL,
+ sixth-alternative-font [6] IMPLICIT Font-Type OPTIONAL,
+ seventh-alternative-font [7] IMPLICIT Font-Type OPTIONAL,
+ eighth-alternative-font [8] IMPLICIT Font-Type OPTIONAL,
+ ninth-alternative-font [9] IMPLICIT Font-Type OPTIONAL
+}
+
+Font-Type ::= SET {
+ font-size [0] IMPLICIT INTEGER,
+ font-identifier [1] IMPLICIT INTEGER
+}
+
+Graphic-Rendition-Aspect ::= INTEGER {
+ cancel(0), increased-intensity(1), decreased-intensity(2), italicized(3),
+ underlined(4), slowly-blinking(5), rapidly-blinking(6), negative-image(7),
+ crossed-out(9), primary-font(10), first-alternative-font(11),
+ second-alternative-font(12), third-alternative-font(13),
+ fourth-alternative-font(14), fifth-alternative-font(15),
+ sixth-alternative-font(16), seventh-alternative-font(17),
+ eighth-alternative-font(18), ninth-alternative-font(19),
+ doubly-underlined(21), normal-intensity(22), not-italicized(23),
+ not-underlined(24), steady(25), variable-spacing(26), positive-image(27),
+ not-crossed-out(29), black-foreground(30), red-foreground(31),
+ green-foreground(32), yellow-foreground(33), blue-foreground(34),
+ magenta-foreground(35), cyan-foreground(36), white-foreground(37),
+ select-char-foreground-colour(38), black-background(40), red-background(41),
+ green-background(42), yellow-background(43), blue-background(44),
+ magenta-background(45), cyan-background(46), white-background(47),
+ select-char-background-colour(48), not-variable-spacing(50)}
+
+Formatting-Indicator ::= INTEGER {no(0), yes(1)}
+
+Itemization ::= SET {
+ identifier-alignment
+ [0] IMPLICIT INTEGER {no-itemization(0), start-aligned(1), end-aligned(2)},
+ identifier-start-offset [1] IMPLICIT INTEGER OPTIONAL,
+ identifier-end-offset [2] IMPLICIT INTEGER OPTIONAL
+}
+
+Kerning-Offset ::= SET {
+ start-offset [0] IMPLICIT INTEGER,
+ end-offset [1] IMPLICIT INTEGER
+}
+
+Proportional-Line-Spacing ::= INTEGER {no(0), yes(1)}
+
+Pairwise-Kerning ::= INTEGER {no(0), yes(1)}
+
+END
+
+-- Generated by Asnp, the ASN.1 pretty-printer of France Telecom R&D
+
diff --git a/lib/asn1/test/asn1_SUITE_data/x420/Character-Profile-Attributes.asn b/lib/asn1/test/asn1_SUITE_data/x420/Character-Profile-Attributes.asn
new file mode 100644
index 0000000000..7ba5bf194a
--- /dev/null
+++ b/lib/asn1/test/asn1_SUITE_data/x420/Character-Profile-Attributes.asn
@@ -0,0 +1,54 @@
+-- Module Character-Profile-Attributes (T.416:03/1993)
+
+Character-Profile-Attributes {2 8 1 6 4} DEFINITIONS ::=
+BEGIN
+
+EXPORTS
+ Character-Presentation-Feature, Character-Coding-Attribute,
+ Character-Content-Defaults;
+
+IMPORTS
+ Character-Attributes, One-Of-Four-Angles, One-Of-Two-Angles, Measure-Pair,
+ Alignment, Layout-Table, Graphic-Rendition, Formatting-Indicator,
+ Character-Fonts, Itemization, Kerning-Offset, Proportional-Line-Spacing,
+ Pairwise-Kerning
+ FROM Character-Presentation-Attributes;
+
+-- see 11.2
+Character-Presentation-Feature ::= CHOICE {
+ character-path [0] IMPLICIT One-Of-Four-Angles,
+ line-progression [1] IMPLICIT One-Of-Two-Angles,
+ character-orientation [2] IMPLICIT One-Of-Four-Angles,
+ initial-offset [3] IMPLICIT Measure-Pair,
+ character-spacing [6] IMPLICIT INTEGER,
+ line-spacing [7] IMPLICIT INTEGER,
+ alignment [8] IMPLICIT Alignment,
+ line-layout-table [9] IMPLICIT Layout-Table,
+ graphic-rendition [10] IMPLICIT Graphic-Rendition,
+ formatting-indicator [11] IMPLICIT Formatting-Indicator,
+ character-fonts [12] IMPLICIT Character-Fonts,
+ graphic-char-subrepertoire [13] IMPLICIT INTEGER,
+ itemization [14] IMPLICIT Itemization,
+ widow-size [15] IMPLICIT INTEGER,
+ orphan-size [16] IMPLICIT INTEGER,
+ graphic-character-sets [17] IMPLICIT OCTET STRING,
+ indentation [19] IMPLICIT INTEGER,
+ kerning-offset [20] IMPLICIT Kerning-Offset,
+ proportional-line-spacing [21] IMPLICIT Proportional-Line-Spacing,
+ pairwise-kerning [22] IMPLICIT Pairwise-Kerning,
+ first-line-offset [23] IMPLICIT INTEGER,
+ code-extension-announcers [24] IMPLICIT OCTET STRING
+}
+
+Character-Coding-Attribute ::= NULL
+
+-- no character coding attributes
+-- are defined in this part of
+-- ITU-T Rec. T.410-Series | ISO/IEC 8613
+Character-Content-Defaults ::=
+ Character-Attributes
+
+END
+
+-- Generated by Asnp, the ASN.1 pretty-printer of France Telecom R&D
+
diff --git a/lib/asn1/test/asn1_SUITE_data/x420/Colour-Attributes.asn b/lib/asn1/test/asn1_SUITE_data/x420/Colour-Attributes.asn
new file mode 100644
index 0000000000..24c7fafc38
--- /dev/null
+++ b/lib/asn1/test/asn1_SUITE_data/x420/Colour-Attributes.asn
@@ -0,0 +1,192 @@
+-- Module Colour-Attributes (T.415:03/1993)
+
+Colour-Attributes {2 8 1 5 14} DEFINITIONS ::=
+BEGIN
+
+EXPORTS
+ Colour-Expression, Colour-Table, Colour-Spaces-List, Colour-Characteristics;
+
+IMPORTS Character-Data
+ FROM Document-Profile-Descriptor; -- see 7.7
+
+Real-Or-Int ::= CHOICE {a REAL,
+ b INTEGER
+}
+
+Colour-Expression ::= SEQUENCE {
+ colour-access-mode [0] IMPLICIT INTEGER {direct(0), indexed(1)},
+ a
+ [1] CHOICE {direct-colour [0] IMPLICIT Direct-Colour,
+ indexed-colour [1] IMPLICIT Indexed-Colour}
+}
+
+Direct-Colour ::= SET {
+ colour-space-id [0] IMPLICIT INTEGER OPTIONAL,
+ colour-specification [1] Colour-Specification OPTIONAL,
+ colour-tolerance [2] Colour-Tolerance OPTIONAL
+}
+
+Colour-Specification ::= CHOICE {
+ cmyk-colour [0] IMPLICIT CMYK-Colour,
+ rgb-colour [1] IMPLICIT RGB-Colour,
+ cie-colour [2] IMPLICIT CIE-Colour
+}
+
+CMYK-Colour ::= SET {
+ c-value [0] Real-Or-Int,
+ m-value [1] Real-Or-Int,
+ y-value [2] Real-Or-Int,
+ k-value [3] Real-Or-Int OPTIONAL
+}
+
+RGB-Colour ::= SET {
+ r-value [0] Real-Or-Int,
+ g-value [1] Real-Or-Int,
+ b-value [2] Real-Or-Int
+}
+
+CIE-Colour ::= SET {
+ x-value [0] Real-Or-Int,
+ y-value [1] Real-Or-Int,
+ z-value [2] Real-Or-Int
+}
+
+Colour-Tolerance ::= CHOICE {
+ unspecified-tolerance [0] IMPLICIT NULL,
+ specified-tolerance [1] IMPLICIT Specified-Tolerance
+}
+
+Specified-Tolerance ::= SET {
+ tolerance-value [0] Real-Or-Int,
+ tolerance-space [1] IMPLICIT INTEGER {cieluv(3), cielab(4)}
+}
+
+Indexed-Colour ::= SET {index [0] IMPLICIT INTEGER OPTIONAL
+}
+
+Colour-Table ::= SET {
+ colour-space-id [0] IMPLICIT INTEGER,
+ colour-table-entries
+ [1] IMPLICIT SET OF
+ SET {index [0] IMPLICIT INTEGER,
+ colour-coordinates [1] Colour-Specification,
+ colour-tolerance [2] Colour-Tolerance OPTIONAL
+ }
+}
+
+Colour-Characteristics ::= SET {
+ colour-spaces-present
+ [0] IMPLICIT SEQUENCE OF
+ SET {colour-space-type [0] IMPLICIT Colour-Space-Type,
+ colour-calibration-type
+ [1] IMPLICIT Colour-Space-Calibration-Type},
+ colour-modes-present [1] IMPLICIT Colour-Modes-Present,
+ minimum-colour-tolerance [2] Colour-Tolerance OPTIONAL,
+ maximum-colour-table-length [3] IMPLICIT INTEGER OPTIONAL,
+ -- "maximum number of colour table entries"
+ maximum-rgb-lut-length [4] IMPLICIT INTEGER OPTIONAL,
+ -- "maximum number of look-up table entries"
+ maximum-cmy-k-grid-size [5] IMPLICIT INTEGER OPTIONAL
+}
+
+Colour-Space-Type ::= INTEGER {rgb(0), cmyk(1), cmy(2), cieluv(3), cielab(4)}
+
+Colour-Space-Calibration-Type ::= INTEGER {
+ no-calibration(0), matrices(1), lookup-tables(2),
+ matrices-and-lookup-tables(3)}
+
+Colour-Modes-Present ::= INTEGER {direct(0), indexed(1), both(2)}
+
+Colour-Spaces-List ::= SET OF Colour-Space
+
+Colour-Space ::= SET {
+ colour-space-id [0] IMPLICIT INTEGER,
+ colour-space-type [1] IMPLICIT Colour-Space-Type,
+ colour-space-name [2] IMPLICIT Character-Data OPTIONAL,
+ colour-data-scaling [3] Colour-Data-Scaling OPTIONAL,
+ calibration-data [4] Calibration-Data OPTIONAL
+}
+
+Colour-Data-Scaling ::= SET {
+ first-component [0] IMPLICIT Scale-And-Offset,
+ second-component [1] IMPLICIT Scale-And-Offset,
+ third-component [2] IMPLICIT Scale-And-Offset,
+ fourth-component [3] IMPLICIT Scale-And-Offset OPTIONAL
+}
+
+Scale-And-Offset ::= SET {
+ colour-scale [0] Real-Or-Int,
+ colour-offset [1] Real-Or-Int
+}
+
+Calibration-Data ::= CHOICE {
+ rgb [0] IMPLICIT RGB-Calibration,
+ cmyk [1] IMPLICIT CMY-K-Calibration,
+ cmy [2] IMPLICIT CMY-K-Calibration,
+ cieluv [3] IMPLICIT CIE-Calibration,
+ cielab [4] IMPLICIT CIE-Calibration
+}
+
+CIE-Calibration ::= SET {reference-white [0] IMPLICIT CIE-Ref
+}
+
+RGB-Calibration ::= SET {
+ reference-white [0] IMPLICIT CIE-Ref,
+ matrix1 [1] IMPLICIT Three-by-Three-Matrix OPTIONAL,
+ lookup-table [3] IMPLICIT Colour-Lookup-Table OPTIONAL,
+ matrix2 [2] IMPLICIT Three-by-Three-Matrix OPTIONAL
+}
+
+Three-by-Three-Matrix ::= SEQUENCE {
+ row-1 Three-Nums,
+ row-2 Three-Nums,
+ row-3 Three-Nums
+}
+
+Three-Nums ::= SEQUENCE {
+ column-1 Real-Or-Int,
+ column-2 Real-Or-Int,
+ column-3 Real-Or-Int
+}
+
+Colour-Lookup-Table ::= SET {
+ number-of-entries [0] IMPLICIT INTEGER,
+ m [1] IMPLICIT INTEGER,
+ n [2] IMPLICIT INTEGER,
+ colour-table [3] IMPLICIT SET OF Colour-Table-Entry
+}
+
+Colour-Table-Entry ::= SET {
+ index [3] IMPLICIT INTEGER,
+ r [0] Real-Or-Int,
+ g [1] Real-Or-Int,
+ b [2] Real-Or-Int
+}
+
+CMY-K-Calibration ::= SET {
+ reference-white [0] IMPLICIT CIE-Ref,
+ comment [1] IMPLICIT Character-Data OPTIONAL,
+ cmyk-lut [2] IMPLICIT Grid-Specification
+}
+
+Grid-Specification ::=
+ SET OF
+ SET {grid-location [0] IMPLICIT CMYK-Colour,
+ grid-value [1] IMPLICIT Grid-Value}
+
+Grid-Value ::= SET {
+ x-value [0] IMPLICIT REAL,
+ y-value [1] IMPLICIT REAL,
+ z-value [2] IMPLICIT REAL
+}
+
+CIE-Ref ::= SET {
+ xn-value [0] Real-Or-Int,
+ yn-value [1] Real-Or-Int,
+ zn-value [2] Real-Or-Int
+}
+
+END
+
+-- Generated by Asnp, the ASN.1 pretty-printer of France Telecom R&D
+
diff --git a/lib/asn1/test/asn1_SUITE_data/x420/DOR-definition.asn b/lib/asn1/test/asn1_SUITE_data/x420/DOR-definition.asn
new file mode 100644
index 0000000000..cd3330dc56
--- /dev/null
+++ b/lib/asn1/test/asn1_SUITE_data/x420/DOR-definition.asn
@@ -0,0 +1,134 @@
+-- Module DOR-definition (ISO|IEC 10031-2:1991)
+DOR-definition {joint-iso-itu-t dor(4) reference-definition(0)} DEFINITIONS ::=
+BEGIN
+
+EXPORTS
+ AE-Identifier, Altered-value, DOR, dor-abstract-syntax, dor-syntax-asn1,
+ dorx, Extend-QoS, Local-reference, Locational-identifier, Produce-QoS,
+ QoS-level, Quality-of-Service, Requested-QoS-level,
+ Single-use-of-reference, Token;
+
+IMPORTS
+ DistinguishedName
+ FROM InformationFramework {joint-iso-itu-t ds(5) module(1)
+ informationFramework(1) 3}
+ PresentationAddress
+ FROM SelectedAttributeTypes {joint-iso-itu-t ds(5) module(1)
+ selectedAttributeTypes(5) 3};
+
+-- Defined Object Identifiers
+dorx OBJECT IDENTIFIER ::=
+ {joint-iso-itu-t dor(11)}
+
+-- Object identifier for abstract syntax of DOR
+dor-abstract-syntax OBJECT IDENTIFIER ::=
+ {dorx reference-abstract-syntax(1)}
+
+-- Object identifier for abstract syntax of DOR with basic ASN.1 encodings in
+-- EXTERNAL
+dor-syntax-asn1 OBJECT IDENTIFIER ::=
+ {dorx reference-syntax(2) asn1(0)}
+
+-- Definition of DOR type
+DOR ::= SEQUENCE {
+ ae-identifier [0] AE-Identifier OPTIONAL,
+ -- mandatory in case of produce-operations and consume-operations
+ local-reference [1] Local-reference,
+ data-object-type OBJECT IDENTIFIER,
+ -- identifying the abstract syntax and the transfer syntax of the
+ -- referenced data value
+ quality-of-service [2] Quality-of-Service DEFAULT {},
+ token [3] Token OPTIONAL
+}
+
+AE-Identifier ::= SEQUENCE { -- at least one component shall be present
+ locational-identifier [0] Locational-identifier OPTIONAL,
+ direct-logical-identifier [1] DistinguishedName OPTIONAL,
+ indirect-logical-identifier [2] DistinguishedName OPTIONAL
+}
+
+Locational-identifier ::= SEQUENCE {
+ presentation-address [0] PresentationAddress,
+ ae-title [1] AE-title OPTIONAL,
+ -- as defined in ISO 8650:1988/Cor.1:1990
+ application-contexts SET OF OBJECT IDENTIFIER
+}
+
+Local-reference ::= SEQUENCE {
+ application [0] OCTET STRING OPTIONAL,
+ specific-reference [1] OCTET STRING
+}
+
+Quality-of-Service ::= SEQUENCE {
+ qoS-level [0] QoS-level DEFAULT level-1:NULL,
+ usage-of-reference Single-use-of-reference DEFAULT TRUE
+}
+
+QoS-level ::= CHOICE {
+ level-1 [1] IMPLICIT NULL,
+ level-2 [2] IMPLICIT GeneralizedTime,
+ -- specifying the produce time
+ level-3
+ [3] IMPLICIT SEQUENCE {produce-time GeneralizedTime,
+ fidelity-time GeneralizedTime}
+}
+
+Single-use-of-reference ::= BOOLEAN
+
+Token ::= CHOICE {
+ simpletoken OCTET STRING,
+ -- used to validate an access which use this DOR
+ externaltoken EXTERNAL -- for future proxy mechanism
+}
+
+-- Data types for produce-operations
+Produce-QoS ::= SEQUENCE {
+ qoS-level [0] Requested-QoS-level DEFAULT level-1:NULL,
+ usage-of-reference Single-use-of-reference DEFAULT TRUE
+}
+
+Requested-QoS-level ::= CHOICE {
+ level-1 [1] IMPLICIT NULL,
+ level-2 [2] IMPLICIT NULL,
+ level-3 [3] IMPLICIT GeneralizedTime
+ -- specifying the requested fidelity-time
+}
+
+-- Data types for extending a specific QoS
+Extend-QoS ::= SEQUENCE {
+ qoS-level [0] Requested-QoS-level OPTIONAL,
+ -- if omitted, no change required
+ usage-of-reference Single-use-of-reference OPTIONAL
+ -- if omitted, no change required
+}
+
+-- Data types for requesting / indicating value alteration in produce-operation
+-- or access-operation
+Altered-value ::= ENUMERATED {
+ value-not-altered(1), value-altered(2), undefined(3)}
+
+-- dw: definition of AE-title, as defined in ISO 8650:1988/Cor.1:1990
+-- dw: defined in-line here so we don't need to import it, original comments
+-- dw: are as they appear in the 8650:1988 Annex E
+AP-title ::= TYPE-IDENTIFIER.&Type
+
+-- The exact definition and values used for AP-title
+-- should be chosen taking into account the ongoing
+-- work in areas of naming, the Directory, and the
+-- Registration Authority procedures for AE titles,
+-- AE titles, and AE qualifiers
+AE-qualifier ::= TYPE-IDENTIFIER.&Type
+
+-- The exact definition and values used for AE-qualifier
+-- should be chosen taking into account the ongoing
+-- work in areas of naming, the Directory, and the
+-- Registration Authority procedures for AE titles,
+-- AE titles, and AE qualifiers
+AE-title ::= SEQUENCE {ap AP-title,
+ ae AE-qualifier
+}
+
+END -- of DOR-definition
+
+-- Generated by Asnp, the ASN.1 pretty-printer of France Telecom R&D
+
diff --git a/lib/asn1/test/asn1_SUITE_data/x420/DSAOperationalAttributeTypes.asn b/lib/asn1/test/asn1_SUITE_data/x420/DSAOperationalAttributeTypes.asn
new file mode 100644
index 0000000000..df5e8489ea
--- /dev/null
+++ b/lib/asn1/test/asn1_SUITE_data/x420/DSAOperationalAttributeTypes.asn
@@ -0,0 +1,186 @@
+-- Module DSAOperationalAttributeTypes (X.501:08/1997)
+DSAOperationalAttributeTypes {joint-iso-itu-t ds(5) module(1)
+ dsaOperationalAttributeTypes(22) 3} DEFINITIONS ::=
+BEGIN
+
+-- EXPORTS All
+-- The types and values defined in this module are exported for use in the other ASN.1 modules contained
+-- within the Directory Specifications, and for the use of other applications which will use them to access
+-- Directory services. Other applications may use them for their own purposes, but this will not constrain
+-- extensions and modifications needed to maintain or improve the Directory service.
+IMPORTS
+ id-doa, id-kmr, informationFramework, distributedOperations,
+ opBindingManagement, selectedAttributeTypes
+ FROM UsefulDefinitions {joint-iso-itu-t ds(5) module(1)
+ usefulDefinitions(0) 3}
+ ATTRIBUTE, MATCHING-RULE, Name
+ FROM InformationFramework informationFramework
+ OperationalBindingID
+ FROM OperationalBindingManagement opBindingManagement
+ AccessPoint, MasterAndShadowAccessPoints
+ FROM DistributedOperations distributedOperations
+ bitStringMatch
+ FROM SelectedAttributeTypes selectedAttributeTypes;
+
+-- data types
+DSEType ::= BIT STRING {
+ root(0), -- root DSE
+ glue(1), -- represents knowledge of a name only
+ cp(2), -- context prefix
+ entry(3), -- object entry
+ alias(4), -- alias entry
+ subr(5), -- subordinate reference
+ nssr(6), -- non-specific subordinate reference
+ supr(7), -- superior reference
+ xr(8), -- cross reference
+ admPoint(9), -- administrative point
+ subentry(10), -- subentry
+ shadow(11), -- shadow copy
+ immSupr(13), -- immediate superior reference
+ rhob(14), -- rhob information
+ sa(15), -- subordinate reference to alias entry
+ dsSubentry(16), -- DSA Specific subentry
+ familyMember(17)} -- family member
+
+SupplierOrConsumer ::= SET {
+ COMPONENTS OF AccessPoint, -- supplier or consumer
+ agreementID [4] OperationalBindingID
+}
+
+SupplierInformation ::= SET {
+ COMPONENTS OF SupplierOrConsumer, -- supplier
+ supplier-is-master [5] BOOLEAN DEFAULT TRUE,
+ non-supplying-master [6] AccessPoint OPTIONAL
+}
+
+ConsumerInformation ::= SupplierOrConsumer -- consumer
+
+SupplierAndConsumers ::= SET {
+ COMPONENTS OF AccessPoint, -- supplier
+ consumers [4] SET OF AccessPoint
+}
+
+-- attribute types
+dseType ATTRIBUTE ::= {
+ WITH SYNTAX DSEType
+ EQUALITY MATCHING RULE bitStringMatch
+ SINGLE VALUE TRUE
+ NO USER MODIFICATION TRUE
+ USAGE dSAOperation
+ ID id-doa-dseType
+}
+
+myAccessPoint ATTRIBUTE ::= {
+ WITH SYNTAX AccessPoint
+ EQUALITY MATCHING RULE accessPointMatch
+ SINGLE VALUE TRUE
+ NO USER MODIFICATION TRUE
+ USAGE dSAOperation
+ ID id-doa-myAccessPoint
+}
+
+superiorKnowledge ATTRIBUTE ::= {
+ WITH SYNTAX AccessPoint
+ EQUALITY MATCHING RULE accessPointMatch
+ NO USER MODIFICATION TRUE
+ USAGE dSAOperation
+ ID id-doa-superiorKnowledge
+}
+
+specificKnowledge ATTRIBUTE ::= {
+ WITH SYNTAX MasterAndShadowAccessPoints
+ EQUALITY MATCHING RULE masterAndShadowAccessPointsMatch
+ SINGLE VALUE TRUE
+ NO USER MODIFICATION TRUE
+ USAGE distributedOperation
+ ID id-doa-specificKnowledge
+}
+
+nonSpecificKnowledge ATTRIBUTE ::= {
+ WITH SYNTAX MasterAndShadowAccessPoints
+ EQUALITY MATCHING RULE masterAndShadowAccessPointsMatch
+ NO USER MODIFICATION TRUE
+ USAGE distributedOperation
+ ID id-doa-nonSpecificKnowledge
+}
+
+supplierKnowledge ATTRIBUTE ::= {
+ WITH SYNTAX SupplierInformation
+ EQUALITY MATCHING RULE supplierOrConsumerInformationMatch
+ NO USER MODIFICATION TRUE
+ USAGE dSAOperation
+ ID id-doa-supplierKnowledge
+}
+
+consumerKnowledge ATTRIBUTE ::= {
+ WITH SYNTAX ConsumerInformation
+ EQUALITY MATCHING RULE supplierOrConsumerInformationMatch
+ NO USER MODIFICATION TRUE
+ USAGE dSAOperation
+ ID id-doa-consumerKnowledge
+}
+
+secondaryShadows ATTRIBUTE ::= {
+ WITH SYNTAX SupplierAndConsumers
+ EQUALITY MATCHING RULE supplierAndConsumersMatch
+ NO USER MODIFICATION TRUE
+ USAGE dSAOperation
+ ID id-doa-secondaryShadows
+}
+
+-- matching rules
+accessPointMatch MATCHING-RULE ::= {
+ SYNTAX Name
+ ID id-kmr-accessPointMatch
+}
+
+masterAndShadowAccessPointsMatch MATCHING-RULE ::= {
+ SYNTAX SET OF Name
+ ID id-kmr-masterShadowMatch
+}
+
+supplierOrConsumerInformationMatch MATCHING-RULE ::= {
+ SYNTAX
+ SET {ae-title [0] Name,
+ agreement-identifier [2] INTEGER}
+ ID id-kmr-supplierConsumerMatch
+}
+
+supplierAndConsumersMatch MATCHING-RULE ::= {
+ SYNTAX Name
+ ID id-kmr-supplierConsumersMatch
+}
+
+-- object identifier assignments
+-- dsa operational attributes
+id-doa-dseType OBJECT IDENTIFIER ::=
+ {id-doa 0}
+
+id-doa-myAccessPoint OBJECT IDENTIFIER ::= {id-doa 1}
+
+id-doa-superiorKnowledge OBJECT IDENTIFIER ::= {id-doa 2}
+
+id-doa-specificKnowledge OBJECT IDENTIFIER ::= {id-doa 3}
+
+id-doa-nonSpecificKnowledge OBJECT IDENTIFIER ::= {id-doa 4}
+
+id-doa-supplierKnowledge OBJECT IDENTIFIER ::= {id-doa 5}
+
+id-doa-consumerKnowledge OBJECT IDENTIFIER ::= {id-doa 6}
+
+id-doa-secondaryShadows OBJECT IDENTIFIER ::= {id-doa 7}
+
+-- knowledge matching rules
+id-kmr-accessPointMatch OBJECT IDENTIFIER ::=
+ {id-kmr 0}
+
+id-kmr-masterShadowMatch OBJECT IDENTIFIER ::= {id-kmr 1}
+
+id-kmr-supplierConsumerMatch OBJECT IDENTIFIER ::= {id-kmr 2}
+
+id-kmr-supplierConsumersMatch OBJECT IDENTIFIER ::= {id-kmr 3}
+
+END -- DSAOperationalAttributeTypes
+
+-- Generated by Asnp, the ASN.1 pretty-printer of France Telecom R&D
+
diff --git a/lib/asn1/test/asn1_SUITE_data/x420/Default-Value-Lists.asn b/lib/asn1/test/asn1_SUITE_data/x420/Default-Value-Lists.asn
new file mode 100644
index 0000000000..ef1187ba8c
--- /dev/null
+++ b/lib/asn1/test/asn1_SUITE_data/x420/Default-Value-Lists.asn
@@ -0,0 +1,143 @@
+-- Module Default-Value-Lists (T.415:03/1993)
+
+Default-Value-Lists {2 8 1 5 11} DEFINITIONS ::=
+BEGIN
+
+EXPORTS Default-Value-Lists-Logical, Default-Value-Lists-Layout;
+
+IMPORTS
+ Style-Identifier, Category-Name
+ FROM Identifiers-and-Expressions -- see 7.8
+
+ Measure-Pair, One-Of-Four-Angles, Medium-Type, Dimension-Pair, Transparency,
+ Colour, Border, Content-Background-Colour, Content-Foreground-Colour,
+ Sealed
+ FROM Layout-Descriptors -- see 7.9
+
+ Protection
+ FROM Logical-Descriptors -- see 7.10
+
+ Presentation-Attributes
+ FROM Style-Descriptors -- see 7.11
+
+ Colour-Expression, Colour-Table
+ FROM Colour-Attributes; -- see 7.14
+
+Default-Value-Lists-Layout ::= SET {
+ page-set-attributes [1] IMPLICIT Page-Set-Attributes OPTIONAL,
+ page-attributes [2] IMPLICIT Page-Attributes OPTIONAL,
+ frame-attributes [3] IMPLICIT Frame-Attributes OPTIONAL,
+ block-attributes [4] IMPLICIT Block-Attributes OPTIONAL
+}
+
+Default-Value-Lists-Logical ::= SET {
+ composite-logical-attributes
+ [5] IMPLICIT Composite-Logical-Attributes OPTIONAL,
+ basic-logical-attributes [6] IMPLICIT Basic-Logical-Attributes OPTIONAL
+}
+
+Page-Set-Attributes ::= SET {
+ layout-stream-categories layout-stream-categories < Attribute OPTIONAL,
+ layout-stream-sub-categories
+ layout-stream-sub-categories < Attribute OPTIONAL
+}
+
+Page-Attributes ::= SET {
+ dimensions dimensions < Attribute OPTIONAL,
+ transparency transparency < Attribute OPTIONAL,
+ presentation-attributes presentation-attributes < Attribute OPTIONAL,
+ page-position page-position < Attribute OPTIONAL,
+ medium-type medium-type < Attribute OPTIONAL,
+ presentation-style presentation-style < Attribute OPTIONAL,
+ layout-stream-categories layout-stream-categories < Attribute OPTIONAL,
+ layout-stream-sub-categories
+ layout-stream-sub-categories < Attribute OPTIONAL,
+ colour colour < Attribute OPTIONAL,
+ colour-of-layout-object colour-of-layout-object < Attribute OPTIONAL,
+ object-colour-table object-colour-table < Attribute OPTIONAL,
+ content-background-colour content-background-colour < Attribute OPTIONAL,
+ content-foreground-colour content-foreground-colour < Attribute OPTIONAL,
+ content-colour-table content-colour-table < Attribute OPTIONAL,
+ sealed sealed < Attribute OPTIONAL
+}
+
+Frame-Attributes ::= SET {
+ position position < Attribute OPTIONAL,
+ dimensions dimensions < Attribute OPTIONAL,
+ transparency transparency < Attribute OPTIONAL,
+ layout-path layout-path < Attribute OPTIONAL,
+ permitted-categories permitted-categories < Attribute OPTIONAL,
+ layout-stream-categories layout-stream-categories < Attribute OPTIONAL,
+ layout-stream-sub-categories
+ layout-stream-sub-categories < Attribute OPTIONAL,
+ colour colour < Attribute OPTIONAL,
+ colour-of-layout-object colour-of-layout-object < Attribute OPTIONAL,
+ object-colour-table object-colour-table < Attribute OPTIONAL,
+ border border < Attribute OPTIONAL,
+ sealed sealed < Attribute OPTIONAL
+}
+
+Block-Attributes ::= SET {
+ position position < Attribute OPTIONAL,
+ dimensions dimensions < Attribute OPTIONAL,
+ transparency transparency < Attribute OPTIONAL,
+ presentation-attributes presentation-attributes < Attribute OPTIONAL,
+ presentation-style presentation-style < Attribute OPTIONAL,
+ layout-stream-categories layout-stream-categories < Attribute OPTIONAL,
+ layout-stream-sub-categories
+ layout-stream-sub-categories < Attribute OPTIONAL,
+ colou colour < Attribute OPTIONAL,
+ colour-of-layout-object colour-of-layout-object < Attribute OPTIONAL,
+ object-colour-table object-colour-table < Attribute OPTIONAL,
+ content-background-colour content-background-colour < Attribute OPTIONAL,
+ content-foreground-colour content-foreground-colour < Attribute OPTIONAL,
+ content-colour-table content-colour-table < Attribute OPTIONAL,
+ border border < Attribute OPTIONAL,
+ sealed sealed < Attribute OPTIONAL
+}
+
+Composite-Logical-Attributes ::= SET {
+ protection protection < Attribute OPTIONAL,
+ layout-style layout-style < Attribute OPTIONAL,
+ sealed sealed < Attribute OPTIONAL
+}
+
+Basic-Logical-Attributes ::= SET {
+ presentation-attributes presentation-attributes < Attribute OPTIONAL,
+ -- only for use for the attribute content-architecture-class;
+ -- the content architecture specific attributes can only be referenced by
+ -- use of presentation style
+ protection protection < Attribute OPTIONAL,
+ presentation-style presentation-style < Attribute OPTIONAL,
+ layout-style layout-style < Attribute OPTIONAL,
+ sealed sealed < Attribute OPTIONAL
+}
+
+Attribute ::= CHOICE {
+ position [0] IMPLICIT Measure-Pair,
+ dimensions [1] IMPLICIT Dimension-Pair,
+ transparency [2] IMPLICIT Transparency,
+ presentation-attributes [3] IMPLICIT Presentation-Attributes,
+ layout-path [4] IMPLICIT One-Of-Four-Angles,
+ page-position [5] IMPLICIT Measure-Pair,
+ medium-type [6] IMPLICIT Medium-Type,
+ permitted-categories [7] IMPLICIT SET OF Category-Name,
+ layout-stream-categories [19] IMPLICIT SET OF Category-Name,
+ layout-stream-sub-categories [20] IMPLICIT SET OF Category-Name,
+ protection [8] IMPLICIT Protection,
+ presentation-style [9] IMPLICIT Style-Identifier,
+ layout-style [10] IMPLICIT Style-Identifier,
+ colour [11] IMPLICIT Colour,
+ colour-of-layout-object [14] Colour-Expression,
+ object-colour-table [15] IMPLICIT Colour-Table,
+ content-background-colour [16] Content-Background-Colour,
+ content-foreground-colour [17] Content-Foreground-Colour,
+ content-colour-table [18] IMPLICIT Colour-Table,
+ border [12] IMPLICIT Border,
+ sealed [13] IMPLICIT Sealed
+}
+
+END
+
+-- Generated by Asnp, the ASN.1 pretty-printer of France Telecom R&D
+
diff --git a/lib/asn1/test/asn1_SUITE_data/x420/DirectoryAbstractService.asn b/lib/asn1/test/asn1_SUITE_data/x420/DirectoryAbstractService.asn
new file mode 100644
index 0000000000..5a5d310729
--- /dev/null
+++ b/lib/asn1/test/asn1_SUITE_data/x420/DirectoryAbstractService.asn
@@ -0,0 +1,710 @@
+-- Module DirectoryAbstractService (X.511:08/1997)
+DirectoryAbstractService {joint-iso-itu-t ds(5) module(1)
+ directoryAbstractService(2) 3} DEFINITIONS ::=
+BEGIN
+
+-- EXPORTS All
+-- The types and values defined in this module are exported for use in the other ASN.1 modules contained
+-- within the Directory Specifications, and for the use of other applications which will use them to access
+-- Directory services. Other applications may use them for their own purposes, but this will not constrain
+-- extensions and modifications needed to maintain or improve the Directory service.
+IMPORTS
+ informationFramework, distributedOperations, authenticationFramework,
+ dap, directoryShadowAbstractService, basicAccessControl, enhancedSecurity,
+ id-at
+ FROM UsefulDefinitions {joint-iso-itu-t ds(5) module(1)
+ usefulDefinitions(0) 3}
+ AttributeTypeAndValue
+ FROM BasicAccessControl basicAccessControl
+ AgreementID
+ FROM DirectoryShadowAbstractService directoryShadowAbstractService
+ Attribute, AttributeType, AttributeValue, AttributeValueAssertion,
+ DistinguishedName, Name, RelativeDistinguishedName, SupportedAttributes,
+ ATTRIBUTE, MATCHING-RULE, ContextAssertion, AttributeTypeAssertion,
+ OBJECT-CLASS, RelaxationPolicy
+ FROM InformationFramework informationFramework
+ OperationProgress, ReferenceType, Exclusions, AccessPoint,
+ ContinuationReference
+ FROM DistributedOperations distributedOperations
+ CertificationPath, SIGNED{}, SIGNATURE{}, ENCRYPTED{}, AlgorithmIdentifier,
+ AttributeCertificationPath
+ FROM AuthenticationFramework authenticationFramework
+ OPTIONALLY-PROTECTED{}, OPTIONALLY-PROTECTED-SEQ{}
+ FROM EnhancedSecurity enhancedSecurity
+ id-opcode-read, id-opcode-compare, id-opcode-abandon, id-opcode-list,
+ id-opcode-search, id-opcode-addEntry, id-opcode-removeEntry,
+ id-opcode-modifyEntry, id-opcode-modifyDN, id-errcode-abandoned,
+ id-errcode-abandonFailed, id-errcode-attributeError, id-errcode-nameError,
+ id-errcode-referral, id-errcode-securityError, id-errcode-serviceError,
+ id-errcode-updateError
+ FROM DirectoryAccessProtocol dap
+ OPERATION, ERROR, Code
+ FROM Remote-Operations-Information-Objects {joint-iso-itu-t
+ remote-operations(4) informationObjects(5) version1(0)}
+ emptyUnbind
+ FROM Remote-Operations-Useful-Definitions {joint-iso-itu-t
+ remote-operations(4) useful-definitions(7) version1(0)}
+ InvokeId
+ FROM Remote-Operations-Generic-ROS-PDUs {joint-iso-itu-t
+ remote-operations(4) generic-ROS-PDUs(6) version1(0)}
+ --PROTECTED
+ -- FROM Notation { joint-iso-itu-t genericULS (20) modules (1) notation (1) }
+ SPKM-REQ, SPKM-REP-TI, SPKM-ERROR
+ FROM SpkmGssTokens {iso(1) identified-organization(3) dod(6) internet(1)
+ security(5) mechanisms(5) spkm(1) spkmGssTokens(10)};
+
+-- Common data types
+-- Parameterized type for representing optional signing
+OPTIONALLY-SIGNED{Type} ::= CHOICE {unsigned Type,
+ signed SIGNED{Type}
+}
+
+CommonArguments ::= SET {
+ serviceControls [30] ServiceControls DEFAULT {},
+ securityParameters [29] SecurityParameters OPTIONAL,
+ requestor [28] DistinguishedName OPTIONAL,
+ operationProgress
+ [27] OperationProgress DEFAULT {nameResolutionPhase notStarted},
+ aliasedRDNs [26] INTEGER OPTIONAL,
+ criticalExtensions [25] BIT STRING OPTIONAL,
+ referenceType [24] ReferenceType OPTIONAL,
+ entryOnly [23] BOOLEAN DEFAULT TRUE,
+ nameResolveOnMaste [21] BOOLEAN DEFAULT FALSE,
+ operationContexts [20] ContextSelection OPTIONAL,
+ familyGrouping [19] FamilyGrouping DEFAULT entryOnly
+}
+
+FamilyGrouping ::= ENUMERATED {
+ entryOnly(1), compoundEntry(2), strands(3), multiStrand(4)}
+
+CommonResults ::= SET {
+ securityParameters [30] SecurityParameters OPTIONAL,
+ performer [29] DistinguishedName OPTIONAL,
+ aliasDereferenced [28] BOOLEAN DEFAULT FALSE,
+ notification [27] SEQUENCE SIZE (1..MAX) OF Attribute OPTIONAL
+}
+
+CommonResultsSeq ::= SEQUENCE {
+ securityParameters [30] SecurityParameters OPTIONAL,
+ performer [29] DistinguishedName OPTIONAL,
+ aliasDereferenced [28] BOOLEAN DEFAULT FALSE
+}
+
+ServiceControls ::= SET {
+ options [0] ServiceControlOptions DEFAULT {},
+ priority [1] INTEGER {low(0), medium(1), high(2)} DEFAULT medium,
+ timeLimit [2] INTEGER OPTIONAL,
+ sizeLimit [3] INTEGER OPTIONAL,
+ scopeOfReferral [4] INTEGER {dmd(0), country(1)} OPTIONAL,
+ attributeSizeLimit [5] INTEGER OPTIONAL,
+ manageDSAITPlaneRef
+ [6] SEQUENCE {dsaName Name,
+ agreementID AgreementID} OPTIONAL,
+ serviceType [7] OBJECT IDENTIFIER OPTIONAL,
+ userClass [8] INTEGER OPTIONAL
+}
+
+ServiceControlOptions ::= BIT STRING {
+ preferChaining(0), chainingProhibited(1), localScope(2), dontUseCopy(3),
+ dontDereferenceAliases(4), subentries(5), copyShallDo(6),
+ partialNameResolution(7), manageDSAIT(8), noSubtypeMatch(9),
+ noSubtypeSelection(10), countFamily(11)}
+
+EntryInformationSelection ::= SET {
+ attributes
+ CHOICE {allUserAttributes [0] NULL,
+ select [1] SET OF AttributeType
+ -- empty set implies no attributes are requested
+ } DEFAULT allUserAttributes:NULL,
+ infoTypes
+ [2] INTEGER {attributeTypesOnly(0), attributeTypesAndValues(1)}
+ DEFAULT attributeTypesAndValues,
+ extraAttributes
+ CHOICE {allOperationalAttributes [3] NULL,
+ select [4] SET OF AttributeType} OPTIONAL,
+ contextSelection ContextSelection OPTIONAL,
+ returnContexts BOOLEAN DEFAULT FALSE,
+ familyReturn FamilyReturn DEFAULT {memberSelect contributingEntriesOnly}
+}
+
+ContextSelection ::= CHOICE {
+ allContexts NULL,
+ selectedContexts SET OF TypeAndContextAssertion
+}
+
+TypeAndContextAssertion ::= SEQUENCE {
+ type AttributeType,
+ contextAssertions
+ CHOICE {preference SEQUENCE OF ContextAssertion,
+ all SET OF ContextAssertion}
+}
+
+FamilyReturn ::= SEQUENCE {
+ memberSelect
+ ENUMERATED {contributingEntriesOnly(1), participatingEntriesOnly(2),
+ compoundEntry(3)},
+ familySelect SEQUENCE SIZE (1..MAX) OF OBJECT-CLASS.&id OPTIONAL
+}
+
+family-information ATTRIBUTE ::= {
+ WITH SYNTAX FamilyEntries
+ USAGE directoryOperation
+ ID id-at-family-information
+}
+
+FamilyEntries ::= SEQUENCE {
+ family-class OBJECT-CLASS.&id, -- structural object class value
+ familyEntries SEQUENCE OF FamilyEntry
+}
+
+FamilyEntry ::= SEQUENCE {
+ rdn RelativeDistinguishedName,
+ information
+ SEQUENCE OF CHOICE {attributeType AttributeType,
+ attribute Attribute},
+ family-info SEQUENCE SIZE (1..MAX) OF FamilyEntries OPTIONAL
+}
+
+EntryInformation ::= SEQUENCE {
+ name Name,
+ fromEntry BOOLEAN DEFAULT TRUE,
+ information
+ SET SIZE (1..MAX) OF
+ CHOICE {attributeType AttributeType,
+ attribute Attribute} OPTIONAL,
+ incompleteEntry [3] BOOLEAN DEFAULT FALSE, -- not in 1988-edition systems
+ partialNameResolution
+ [4] BOOLEAN DEFAULT FALSE -- not in 1988 or 1993 edition systems --
+}
+
+Filter ::= CHOICE {
+ item [0] FilterItem,
+ and [1] SET OF Filter,
+ or [2] SET OF Filter,
+ not [3] Filter
+}
+
+FilterItem ::= CHOICE {
+ equality [0] AttributeValueAssertion,
+ substrings
+ [1] SEQUENCE {type ATTRIBUTE.&id({SupportedAttributes}),
+ strings
+ SEQUENCE OF
+ CHOICE {initial
+ [0] ATTRIBUTE.&Type
+ ({SupportedAttributes}
+ {@substrings.type}),
+ any
+ [1] ATTRIBUTE.&Type
+ ({SupportedAttributes}
+ {@substrings.type}),
+ final
+ [2] ATTRIBUTE.&Type
+ ({SupportedAttributes}
+ {@substrings.type}),
+ control Attribute -- Used to specify interpretation of following items
+ }},
+ greaterOrEqual [2] AttributeValueAssertion,
+ lessOrEqual [3] AttributeValueAssertion,
+ present [4] AttributeType,
+ approximateMatch [5] AttributeValueAssertion,
+ extensibleMatch [6] MatchingRuleAssertion,
+ contextPresent [7] AttributeTypeAssertion
+}
+
+MatchingRuleAssertion ::= SEQUENCE {
+ matchingRule [1] SET SIZE (1..MAX) OF MATCHING-RULE.&id,
+ type [2] AttributeType OPTIONAL,
+ matchValue
+ [3] MATCHING-RULE.&AssertionType
+ (CONSTRAINED BY {
+ -- matchValue must be a value of type specified by the &AssertionType field of
+ -- one of the MATCHING-RULE information objects identified by matchingRule -- }),
+ dnAttributes [4] BOOLEAN DEFAULT FALSE
+}
+
+PagedResultsRequest ::= CHOICE {
+ newRequest
+ SEQUENCE {pageSize INTEGER,
+ sortKeys SEQUENCE SIZE (1..MAX) OF SortKey OPTIONAL,
+ reverse [1] BOOLEAN DEFAULT FALSE,
+ unmerged [2] BOOLEAN DEFAULT FALSE},
+ queryReference OCTET STRING
+}
+
+SortKey ::= SEQUENCE {
+ type AttributeType,
+ orderingRule MATCHING-RULE.&id OPTIONAL
+}
+
+SecurityParameters ::= SET {
+ certification-path [0] CertificationPath OPTIONAL,
+ name [1] DistinguishedName OPTIONAL,
+ time [2] Time OPTIONAL,
+ random [3] BIT STRING OPTIONAL,
+ target [4] ProtectionRequest OPTIONAL,
+ response [5] BIT STRING OPTIONAL,
+ operationCode [6] Code OPTIONAL,
+ attributeCertificationPath [7] AttributeCertificationPath OPTIONAL,
+ errorProtection [8] ErrorProtectionRequest OPTIONAL,
+ errorCode [9] Code OPTIONAL
+}
+
+ProtectionRequest ::= INTEGER {
+ none(0), signed(1), encrypted(2), signed-encrypted(3)}
+
+Time ::= CHOICE {utcTime UTCTime,
+ generalizedTime GeneralizedTime
+}
+
+ErrorProtectionRequest ::= INTEGER {
+ none(0), signed(1), encrypted(2), signed-encrypted(3)}
+
+-- Bind and unbind operations
+directoryBind OPERATION ::= {
+ ARGUMENT DirectoryBindArgument
+ RESULT DirectoryBindResult
+ ERRORS {directoryBindError}
+}
+
+DirectoryBindArgument ::= SET {
+ credentials [0] Credentials OPTIONAL,
+ versions [1] Versions DEFAULT {v1}
+}
+
+Credentials ::= CHOICE {
+ simple [0] SimpleCredentials,
+ strong [1] StrongCredentials,
+ externalProcedure [2] EXTERNAL,
+ spkm [3] SpkmCredentials
+}
+
+SimpleCredentials ::= SEQUENCE {
+ name [0] DistinguishedName,
+ validity
+ [1] SET {time1 [0] CHOICE {utc UTCTime,
+ gt GeneralizedTime} OPTIONAL,
+ time2 [1] CHOICE {utc UTCTime,
+ gt GeneralizedTime} OPTIONAL,
+ random1 [2] BIT STRING OPTIONAL,
+ random2 [3] BIT STRING OPTIONAL},
+ password
+ [2] CHOICE {unprotected OCTET STRING,
+ protected SIGNATURE{OCTET STRING}} OPTIONAL
+}
+
+StrongCredentials ::= SET {
+ certification-path [0] CertificationPath OPTIONAL,
+ bind-token [1] Token,
+ name [2] DistinguishedName OPTIONAL,
+ attributeCertificationPath [3] AttributeCertificationPath OPTIONAL
+}
+
+SpkmCredentials ::= CHOICE {req [0] SPKM-REQ,
+ rep [1] SPKM-REP-TI
+}
+
+Token ::=
+ SIGNED
+ {SEQUENCE {algorithm [0] AlgorithmIdentifier,
+ name [1] DistinguishedName,
+ time [2] Time,
+ random [3] BIT STRING,
+ response [4] BIT STRING OPTIONAL,
+ bindIntAlgorithm
+ [5] SEQUENCE SIZE (1..MAX) OF AlgorithmIdentifier OPTIONAL,
+ bindIntKeyInfo [6] BindKeyInfo OPTIONAL,
+ bindConfAlgorithm
+ [7] SEQUENCE SIZE (1..MAX) OF AlgorithmIdentifier OPTIONAL,
+ bindConfKeyInfo [8] BindKeyInfo OPTIONAL}}
+
+Versions ::= BIT STRING {v1(0), v2(1)}
+
+DirectoryBindResult ::= DirectoryBindArgument
+
+directoryBindError ERROR ::= {
+ PARAMETER OPTIONALLY-PROTECTED
+ {SET {versions [0] Versions DEFAULT {v1},
+ error
+ CHOICE {serviceError [1] ServiceProblem,
+ securityError [2] SecurityProblem}}}
+}
+
+BindKeyInfo ::= ENCRYPTED{BIT STRING}
+
+directoryUnbind OPERATION ::= emptyUnbind
+
+-- Operations, arguments, and results
+read OPERATION ::= {
+ ARGUMENT ReadArgument
+ RESULT ReadResult
+ ERRORS
+ {attributeError | nameError | serviceError | referral | abandoned |
+ securityError}
+ CODE id-opcode-read
+}
+
+ReadArgument ::=
+ OPTIONALLY-PROTECTED
+ {SET {object [0] Name,
+ selection [1] EntryInformationSelection DEFAULT {},
+ modifyRightsRequest [2] BOOLEAN DEFAULT FALSE,
+ COMPONENTS OF CommonArguments}}
+
+ReadResult ::=
+ OPTIONALLY-PROTECTED
+ {SET {entry [0] EntryInformation,
+ modifyRights [1] ModifyRights OPTIONAL,
+ COMPONENTS OF CommonResults}}
+
+ModifyRights ::=
+ SET OF
+ SEQUENCE {item
+ CHOICE {entry [0] NULL,
+ attribute [1] AttributeType,
+ value [2] AttributeValueAssertion},
+ permission
+ [3] BIT STRING {add(0), remove(1), rename(2), move(3)}
+ }
+
+compare OPERATION ::= {
+ ARGUMENT CompareArgument
+ RESULT CompareResult
+ ERRORS
+ {attributeError | nameError | serviceError | referral | abandoned |
+ securityError}
+ CODE id-opcode-compare
+}
+
+CompareArgument ::=
+ OPTIONALLY-PROTECTED
+ {SET {object [0] Name,
+ purported [1] AttributeValueAssertion,
+ COMPONENTS OF CommonArguments}}
+
+CompareResult ::=
+ OPTIONALLY-PROTECTED
+ {SET {name Name OPTIONAL,
+ matched [0] BOOLEAN,
+ fromEntry [1] BOOLEAN DEFAULT TRUE,
+ matchedSubtype [2] AttributeType OPTIONAL,
+ COMPONENTS OF CommonResults}}
+
+abandon OPERATION ::= {
+ ARGUMENT AbandonArgument
+ RESULT AbandonResult
+ ERRORS {abandonFailed}
+ CODE id-opcode-abandon
+}
+
+AbandonArgument ::=
+ OPTIONALLY-PROTECTED-SEQ{SEQUENCE {invokeID [0] InvokeId}}
+
+AbandonResult ::= CHOICE {
+ null NULL,
+ information
+ OPTIONALLY-PROTECTED-SEQ{SEQUENCE {invokeID InvokeId,
+ COMPONENTS OF CommonResultsSeq
+ }}
+}
+
+list OPERATION ::= {
+ ARGUMENT ListArgument
+ RESULT ListResult
+ ERRORS {nameError | serviceError | referral | abandoned | securityError}
+ CODE id-opcode-list
+}
+
+ListArgument ::=
+ OPTIONALLY-PROTECTED
+ {SET {object [0] Name,
+ pagedResults [1] PagedResultsRequest OPTIONAL,
+ listFamily [2] BOOLEAN DEFAULT FALSE,
+ COMPONENTS OF CommonArguments}}
+
+ListResult ::=
+ OPTIONALLY-PROTECTED
+ {CHOICE {listInfo
+ SET {name Name OPTIONAL,
+ subordinates
+ [1] SET OF
+ SEQUENCE {rdn RelativeDistinguishedName,
+ aliasEntry [0] BOOLEAN DEFAULT FALSE,
+ fromEntry [1] BOOLEAN DEFAULT TRUE
+ },
+ partialOutcomeQualifier
+ [2] PartialOutcomeQualifier OPTIONAL,
+ COMPONENTS OF CommonResults},
+ uncorrelatedListInfo [0] SET OF ListResult}}
+
+PartialOutcomeQualifier ::= SET {
+ limitProblem [0] LimitProblem OPTIONAL,
+ unexplored
+ [1] SET SIZE (1..MAX) OF ContinuationReference OPTIONAL,
+ unavailableCriticalExtensions [2] BOOLEAN DEFAULT FALSE,
+ unknownErrors
+ [3] SET SIZE (1..MAX) OF ABSTRACT-SYNTAX.&Type OPTIONAL,
+ queryReference [4] OCTET STRING OPTIONAL,
+ overspecFilter [5] Filter OPTIONAL,
+ notification
+ [6] SEQUENCE SIZE (1..MAX) OF Attribute OPTIONAL,
+ entryCount
+ CHOICE {bestEstimate [7] INTEGER,
+ lowEstimate [8] INTEGER} OPTIONAL
+}
+
+LimitProblem ::= INTEGER {
+ timeLimitExceeded(0), sizeLimitExceeded(1), administrativeLimitExceeded(2)
+}
+
+search OPERATION ::= {
+ ARGUMENT SearchArgument
+ RESULT SearchResult
+ ERRORS
+ {attributeError | nameError | serviceError | referral | abandoned |
+ securityError}
+ CODE id-opcode-search
+}
+
+SearchArgument ::=
+ OPTIONALLY-PROTECTED
+ {SET {baseObject [0] Name,
+ subset
+ [1] INTEGER {baseObject(0), oneLevel(1), wholeSubtree(2)}
+ DEFAULT baseObject,
+ filter [2] Filter DEFAULT and:{},
+ searchAliases [3] BOOLEAN DEFAULT TRUE,
+ selection [4] EntryInformationSelection DEFAULT {},
+ pagedResults [5] PagedResultsRequest OPTIONAL,
+ matchedValuesOnly [6] BOOLEAN DEFAULT FALSE,
+ extendedFilter [7] Filter OPTIONAL,
+ checkOverspecified [8] BOOLEAN DEFAULT FALSE,
+ relaxation [9] RelaxationPolicy OPTIONAL,
+ extendedArea [10] INTEGER OPTIONAL,
+ hierarchySelections [11] HierarchySelections DEFAULT {self},
+ searchControlOptions
+ [12] SearchControlOptions DEFAULT {searchAliases},
+ COMPONENTS OF CommonArguments}}
+
+HierarchySelections ::= BIT STRING {
+ self(0), children(1), parent(2), hierarchy(3), top(4), subtree(5),
+ siblings(6), siblingChildren(7), siblingSubtree(8), all(9)}
+
+SearchControlOptions ::= BIT STRING {
+ searchAliases(0), matchedValuesOnly(1), checkOverspecified(2),
+ performExactly(3), includeAllAreas(4), noSystemRelaxation(5), dnAttribute(6),
+ matchOnResidualName(7), entryCount(8), useSubset(9),
+ separateFamilyMembers(10), searchFamily(11)}
+
+SearchResult ::=
+ OPTIONALLY-PROTECTED
+ {CHOICE {searchInfo
+ SET {name Name OPTIONAL,
+ entries [0] SET OF EntryInformation,
+ partialOutcomeQualifier
+ [2] PartialOutcomeQualifier OPTIONAL,
+ altMatching [3] BOOLEAN DEFAULT FALSE,
+ COMPONENTS OF CommonResults},
+ uncorrelatedSearchInfo [0] SET OF SearchResult}}
+
+addEntry OPERATION ::= {
+ ARGUMENT AddEntryArgument
+ RESULT AddEntryResult
+ ERRORS
+ {attributeError | nameError | serviceError | referral | securityError |
+ updateError}
+ CODE id-opcode-addEntry
+}
+
+AddEntryArgument ::=
+ OPTIONALLY-PROTECTED
+ {SET {object [0] Name,
+ entry [1] SET OF Attribute,
+ targetSystem [2] AccessPoint OPTIONAL,
+ COMPONENTS OF CommonArguments}}
+
+AddEntryResult ::= CHOICE {
+ null NULL,
+ information
+ OPTIONALLY-PROTECTED-SEQ{SEQUENCE {COMPONENTS OF CommonResultsSeq}}
+}
+
+removeEntry OPERATION ::= {
+ ARGUMENT RemoveEntryArgument
+ RESULT RemoveEntryResult
+ ERRORS {nameError | serviceError | referral | securityError | updateError}
+ CODE id-opcode-removeEntry
+}
+
+RemoveEntryArgument ::=
+ OPTIONALLY-PROTECTED{SET {object [0] Name,
+ COMPONENTS OF CommonArguments}}
+
+RemoveEntryResult ::= CHOICE {
+ null NULL,
+ information
+ OPTIONALLY-PROTECTED-SEQ{SEQUENCE {COMPONENTS OF CommonResultsSeq}}
+}
+
+modifyEntry OPERATION ::= {
+ ARGUMENT ModifyEntryArgument
+ RESULT ModifyEntryResult
+ ERRORS
+ {attributeError | nameError | serviceError | referral | securityError |
+ updateError}
+ CODE id-opcode-modifyEntry
+}
+
+ModifyEntryArgument ::=
+ OPTIONALLY-PROTECTED
+ {SET {object [0] Name,
+ changes [1] SEQUENCE OF EntryModification,
+ selection [2] EntryInformationSelection OPTIONAL,
+ COMPONENTS OF CommonArguments}}
+
+ModifyEntryResult ::= CHOICE {
+ null NULL,
+ information
+ OPTIONALLY-PROTECTED-SEQ{SEQUENCE {entry [0] EntryInformation OPTIONAL,
+ COMPONENTS OF CommonResultsSeq
+ }}
+}
+
+EntryModification ::= CHOICE {
+ addAttribute [0] Attribute,
+ removeAttribute [1] AttributeType,
+ addValues [2] Attribute,
+ removeValues [3] Attribute,
+ alterValues [4] AttributeTypeAndValue,
+ resetValue [5] AttributeType
+}
+
+modifyDN OPERATION ::= {
+ ARGUMENT ModifyDNArgument
+ RESULT ModifyDNResult
+ ERRORS {nameError | serviceError | referral | securityError | updateError}
+ CODE id-opcode-modifyDN
+}
+
+ModifyDNArgument ::=
+ OPTIONALLY-PROTECTED
+ {SET {object [0] DistinguishedName,
+ newRDN [1] RelativeDistinguishedName,
+ deleteOldRDN [2] BOOLEAN DEFAULT FALSE,
+ newSuperior [3] DistinguishedName OPTIONAL,
+ COMPONENTS OF CommonArguments}}
+
+ModifyDNResult ::= CHOICE {
+ null NULL,
+ information
+ OPTIONALLY-PROTECTED-SEQ{SEQUENCE {newRDN RelativeDistinguishedName,
+ COMPONENTS OF CommonResultsSeq
+ }}
+}
+
+-- Errors and parameters
+abandoned ERROR ::= { -- not literally an "error"
+ PARAMETER OPTIONALLY-PROTECTED {SET {COMPONENTS OF CommonResults}}
+ CODE id-errcode-abandoned
+}
+
+abandonFailed ERROR ::= {
+ PARAMETER OPTIONALLY-PROTECTED
+ {SET {problem [0] AbandonProblem,
+ operation [1] InvokeId,
+ COMPONENTS OF CommonResults}}
+ CODE id-errcode-abandonFailed
+}
+
+AbandonProblem ::= INTEGER {noSuchOperation(1), tooLate(2), cannotAbandon(3)}
+
+attributeError ERROR ::= {
+ PARAMETER OPTIONALLY-PROTECTED
+ {SET {object [0] Name,
+ problems
+ [1] SET OF
+ SEQUENCE {problem [0] AttributeProblem,
+ type [1] AttributeType,
+ value [2] AttributeValue OPTIONAL},
+ COMPONENTS OF CommonResults}}
+ CODE id-errcode-attributeError
+}
+
+AttributeProblem ::= INTEGER {
+ noSuchAttributeOrValue(1), invalidAttributeSyntax(2),
+ undefinedAttributeType(3), inappropriateMatching(4), constraintViolation(5),
+ attributeOrValueAlreadyExists(6), contextViolation(7)}
+
+nameError ERROR ::= {
+ PARAMETER OPTIONALLY-PROTECTED
+ {SET {problem [0] NameProblem,
+ matched [1] Name,
+ COMPONENTS OF CommonResults}}
+ CODE id-errcode-nameError
+}
+
+NameProblem ::= INTEGER {
+ noSuchObject(1), aliasProblem(2), invalidAttributeSyntax(3),
+ aliasDereferencingProblem(4), contextProblem(5)}
+
+referral ERROR ::= { -- not literally an "error"
+ PARAMETER OPTIONALLY-PROTECTED
+ {SET {candidate [0] ContinuationReference,
+ COMPONENTS OF CommonResults}}
+ CODE id-errcode-referral
+}
+
+securityError ERROR ::= {
+ PARAMETER OPTIONALLY-PROTECTED
+ {SET {problem [0] SecurityProblem,
+ spkmInfo [1] SPKM-ERROR,
+ COMPONENTS OF CommonResults}}
+ CODE id-errcode-securityError
+}
+
+SecurityProblem ::= INTEGER {
+ inappropriateAuthentication(1), invalidCredentials(2),
+ insufficientAccessRights(3), invalidSignature(4), protectionRequired(5),
+ noInformation(6), blockedCredentials(7), invalidQOPMatch(8), spkmError(9)
+}
+
+serviceError ERROR ::= {
+ PARAMETER OPTIONALLY-PROTECTED
+ {SET {problem [0] ServiceProblem,
+ COMPONENTS OF CommonResults}}
+ CODE id-errcode-serviceError
+}
+
+ServiceProblem ::= INTEGER {
+ busy(1), unavailable(2), unwillingToPerform(3), chainingRequired(4),
+ unableToProceed(5), invalidReference(6), timeLimitExceeded(7),
+ administrativeLimitExceeded(8), loopDetected(9),
+ unavailableCriticalExtension(10), outOfScope(11), ditError(12),
+ invalidQueryReference(13), requestedServiceNotAvailable(14),
+ relaxationNotSupported(15), unavailableRelaxationLevel(16),
+ unsupportedMatchingUse(17), unmatchedKeyAttributes(18),
+ ambiguousKeyAttributes(19)}
+
+updateError ERROR ::= {
+ PARAMETER OPTIONALLY-PROTECTED
+ {SET {problem [0] UpdateProblem,
+ attributeInfo
+ [1] SET SIZE (1..MAX) OF
+ CHOICE {attributeType AttributeType,
+ attribute Attribute} OPTIONAL,
+ COMPONENTS OF CommonResults}}
+ CODE id-errcode-updateError
+}
+
+UpdateProblem ::= INTEGER {
+ namingViolation(1), objectClassViolation(2), notAllowedOnNonLeaf(3),
+ notAllowedOnRDN(4), entryAlreadyExists(5), affectsMultipleDSAs(6),
+ objectClassModificationProhibited(7), notAncestor(8), parentNotAncestor(9),
+ hierarchyRuleViolation(10), familyRuleViolation(11)}
+
+id-at-family-information OBJECT IDENTIFIER ::= {id-at 64}
+
+END -- DirectoryAbstractService
+
+-- Generated by Asnp, the ASN.1 pretty-printer of France Telecom R&D
+
diff --git a/lib/asn1/test/asn1_SUITE_data/x420/DirectoryAccessProtocol.asn b/lib/asn1/test/asn1_SUITE_data/x420/DirectoryAccessProtocol.asn
new file mode 100644
index 0000000000..10d6979f6d
--- /dev/null
+++ b/lib/asn1/test/asn1_SUITE_data/x420/DirectoryAccessProtocol.asn
@@ -0,0 +1,162 @@
+-- Module DirectoryAccessProtocol (X.519 TC2:08/1997)
+
+DirectoryAccessProtocol {joint-iso-itu-t ds(5) module(1) dap(11) 3} DEFINITIONS
+::=
+BEGIN
+
+-- EXPORTS All
+-- The types and values defined in this module are exported for use in the other ASN.1 modules contained
+-- within the Directory Specifications, and for the use of other applications which will use them to access
+-- Directory services. Other applications may use them for their own purposes, but this will not constrain
+-- extensions and modifications needed to maintain or improve the Directory service.
+IMPORTS
+ directoryAbstractService, protocolObjectIdentifiers
+ FROM UsefulDefinitions {joint-iso-itu-t ds(5) module(1)
+ usefulDefinitions(0) 3}
+ ROS-OBJECT-CLASS, CONTRACT, OPERATION-PACKAGE, CONNECTION-PACKAGE,
+ Code, OPERATION
+ FROM Remote-Operations-Information-Objects {joint-iso-itu-t
+ remote-operations(4) informationObjects(5) version1(0)}
+ ROS{}, Bind{}, Unbind{}, InvokeId
+ FROM Remote-Operations-Generic-ROS-PDUs {joint-iso-itu-t
+ remote-operations(4) generic-ROS-PDUs(6) version1(0)}
+ APPLICATION-CONTEXT
+ FROM Remote-Operations-Information-Objects-extensions {joint-iso-itu-t
+ remote-operations(4) informationObjects-extensions(8) version1(0)}
+ acse, pData
+ FROM Remote-Operations-Realizations {joint-iso-itu-t remote-operations(4)
+ realizations(9) version1(0)}
+ acse-abstract-syntax
+ FROM Remote-Operations-Abstract-Syntaxes {joint-iso-itu-t
+ remote-operations(4) remote-operations-abstract-syntaxes(12) version1(0)}
+ id-ac-directoryAccessAC, id-rosObject-dua, id-rosObject-directory,
+ id-rosObject-dapDSA, id-contract-dap, id-package-dapConnection,
+ id-package-read, id-package-search, id-package-modify,
+ id-as-directoryAccessAS
+ FROM ProtocolObjectIdentifiers protocolObjectIdentifiers
+ directoryBind, directoryUnbind, read, compare, abandon, list, search,
+ addEntry, removeEntry, modifyEntry, modifyDN
+ FROM DirectoryAbstractService directoryAbstractService;
+
+-- application contexts
+directoryAccessAC APPLICATION-CONTEXT ::= {
+ CONTRACT dapContract
+ ESTABLISHED BY acse
+ INFORMATION TRANSFER BY pData
+ ABSTRACT SYNTAXES
+ {acse-abstract-syntax | directoryAccessAbstractSyntax}
+ APPLICATION CONTEXT NAME id-ac-directoryAccessAC
+}
+
+-- ROS objects
+dua ROS-OBJECT-CLASS ::= {INITIATES {dapContract}
+ ID id-rosObject-dua
+}
+
+directory ROS-OBJECT-CLASS ::= {
+ RESPONDS {dapContract}
+ ID id-rosObject-directory
+}
+
+dap-dsa ROS-OBJECT-CLASS ::= {
+ RESPONDS {dapContract}
+ ID id-rosObject-dapDSA
+}
+
+-- contracts
+dapContract CONTRACT ::= {
+ CONNECTION dapConnectionPackage
+ INITIATOR CONSUMER OF {readPackage | searchPackage | modifyPackage}
+ ID id-contract-dap
+}
+
+-- connection package
+dapConnectionPackage CONNECTION-PACKAGE ::= {
+ BIND directoryBind
+ UNBIND directoryUnbind
+ ID id-package-dapConnection
+}
+
+-- read package
+readPackage OPERATION-PACKAGE ::= {
+ CONSUMER INVOKES {read | compare | abandon}
+ ID id-package-read
+}
+
+-- search package
+searchPackage OPERATION-PACKAGE ::= {
+ CONSUMER INVOKES {list | search}
+ ID id-package-search
+}
+
+-- modify Package
+modifyPackage OPERATION-PACKAGE ::= {
+ CONSUMER INVOKES {addEntry | removeEntry | modifyEntry | modifyDN}
+ ID id-package-modify
+}
+
+-- abstract syntaxes
+directoryAccessAbstractSyntax ABSTRACT-SYNTAX ::= {
+ DAP-PDUs
+ IDENTIFIED BY id-as-directoryAccessAS
+}
+
+DAP-PDUs ::= CHOICE {
+ basicRos ROS{{DAP-InvokeIDSet}, {DAP-Invokable}, {DAP-Returnable}},
+ bind Bind{directoryBind},
+ unbind Unbind{directoryUnbind}
+}
+
+DAP-InvokeIDSet ::= InvokeId(ALL EXCEPT absent:NULL)
+
+DAP-Invokable OPERATION ::=
+ {read | compare | abandon | list | search | addEntry | removeEntry |
+ modifyEntry | modifyDN}
+
+DAP-Returnable OPERATION ::=
+ {read | compare | abandon | list | search | addEntry | removeEntry |
+ modifyEntry | modifyDN}
+
+-- remote operation codes
+id-opcode-read Code ::= local:1
+
+id-opcode-compare Code ::= local:2
+
+id-opcode-abandon Code ::= local:3
+
+id-opcode-list Code ::= local:4
+
+id-opcode-search Code ::= local:5
+
+id-opcode-addEntry Code ::= local:6
+
+id-opcode-removeEntry Code ::= local:7
+
+id-opcode-modifyEntry Code ::= local:8
+
+id-opcode-modifyDN Code ::= local:9
+
+-- remote error codes
+id-errcode-attributeError Code ::= local:1
+
+id-errcode-nameError Code ::= local:2
+
+id-errcode-serviceError Code ::= local:3
+
+id-errcode-referral Code ::= local:4
+
+id-errcode-abandoned Code ::= local:5
+
+id-errcode-securityError Code ::= local:6
+
+id-errcode-abandonFailed Code ::= local:7
+
+id-errcode-updateError Code ::= local:8
+
+-- remote error code for DSP
+id-errcode-dsaReferral Code ::= local:9
+
+END -- DirectoryAccessProtocol
+
+-- Generated by Asnp, the ASN.1 pretty-printer of France Telecom R&D
+
diff --git a/lib/asn1/test/asn1_SUITE_data/x420/DirectoryInformationShadowProtocol.asn b/lib/asn1/test/asn1_SUITE_data/x420/DirectoryInformationShadowProtocol.asn
new file mode 100644
index 0000000000..91c0a865f7
--- /dev/null
+++ b/lib/asn1/test/asn1_SUITE_data/x420/DirectoryInformationShadowProtocol.asn
@@ -0,0 +1,246 @@
+-- Module DirectoryInformationShadowProtocol (X.519 TC2:08/1997)
+
+DirectoryInformationShadowProtocol {joint-iso-itu-t ds(5) module(1) disp(16) 3}
+DEFINITIONS ::=
+BEGIN
+
+-- EXPORTS All
+-- The types and values defined in this module are exported for use in the other ASN.1 modules contained
+-- within the Directory Specifications, and for the use of other applications which will use them to access
+-- Directory services. Other applications may use them for their own purposes, but this will not constrain
+-- extensions and modifications needed to maintain or improve the Directory service.
+IMPORTS
+ directoryShadowAbstractService, protocolObjectIdentifiers
+ FROM UsefulDefinitions {joint-iso-itu-t ds(5) module(1)
+ usefulDefinitions(0) 3}
+ ROS-OBJECT-CLASS, CONTRACT, OPERATION-PACKAGE, CONNECTION-PACKAGE,
+ Code, OPERATION
+ FROM Remote-Operations-Information-Objects {joint-iso-itu-t
+ remote-operations(4) informationObjects(5) version1(0)}
+ ROS{}, Bind{}, Unbind{}, InvokeId
+ FROM Remote-Operations-Generic-ROS-PDUs {joint-iso-itu-t
+ remote-operations(4) generic-ROS-PDUs(6) version1(0)}
+ APPLICATION-CONTEXT
+ FROM Remote-Operations-Information-Objects-extensions {joint-iso-itu-t
+ remote-operations(4) informationObjects-extensions(8) version1(0)}
+ acse, pData, association-by-RTSE, transfer-by-RTSE
+ FROM Remote-Operations-Realizations {joint-iso-itu-t remote-operations(4)
+ realizations(9) version1(0)}
+ acse-abstract-syntax
+ FROM Remote-Operations-Abstract-Syntaxes {joint-iso-itu-t
+ remote-operations(4) remote-operations-abstract-syntaxes(12) version1(0)}
+ id-ac-shadowSupplierInitiatedAC, id-ac-shadowSupplierInitiatedAsynchronousAC,
+ id-ac-shadowConsumerInitiatedAC,
+ id-ac-shadowConsumerInitiatedAsynchronousAC,
+ id-ac-reliableShadowSupplierInitiatedAC,
+ id-ac-reliableShadowConsumerInitiatedAC,
+ id-rosObject-initiatingConsumerDSA, id-rosObject-respondingSupplierDSA,
+ id-rosObject-initiatingSupplierDSA, id-rosObject-respondingConsumerDSA,
+ id-contract-shadowConsumer, id-contract-shadowSupplier,
+ id-package-dispConnection, id-package-shadowConsumer,
+ id-package-shadowSupplier, id-as-directoryShadowAS,
+ id-as-directoryReliableShadowAS, id-as-reliableShadowBindingAS
+ FROM ProtocolObjectIdentifiers protocolObjectIdentifiers
+ dSAShadowBind, dSAShadowUnbind, requestShadowUpdate, updateShadow,
+ coordinateShadowUpdate
+ FROM DirectoryShadowAbstractService directoryShadowAbstractService
+ RTORQapdu, RTOACapdu, RTORJapdu
+ FROM Reliable-Transfer-APDU {joint-iso-itu-t reliable-transfer(3) apdus(0)};
+
+RTSE-apdus ::= CHOICE {
+ rtorq-apdu [16] IMPLICIT RTORQapdu,
+ rtoac-apdu [17] IMPLICIT RTOACapdu,
+ rtorj-apdu [18] IMPLICIT RTORJapdu,
+ rttp-apdu RTTPapdu,
+ rttr-apdu RTTRapdu,
+ rtab-apdu [22] IMPLICIT RTABapdu
+}
+
+RTTPapdu ::= -- priority-- INTEGER
+
+RTTRapdu ::= OCTET STRING
+
+RTABapdu ::= SET {
+ abortReason [0] IMPLICIT AbortReason OPTIONAL,
+ reflectedParameter [1] IMPLICIT BIT STRING OPTIONAL,
+ -- 8 bits maximum, only if abortReason is invalidParameter
+ userdataAB
+ [2] TYPE-IDENTIFIER.&Type
+ OPTIONAL -- only in normal mode and if abortReason--
+ -- is userError
+}
+
+AbortReason ::= INTEGER {
+ localSystemProblem(0),
+ invalidParameter(1), -- reflectedParameter supplied
+ unrecognizedActivity(2),
+ temporaryProblem(3),
+ -- the RTSE cannot accept a session for a period of time
+ protocolError(4), -- RTSE level protocol error
+ permanentProblem(5), --provider-abort solely in normal mode
+ userError(6), -- user-abort solely in normal mode
+ transferCompleted(7) -- activity can't be discarded--}
+
+-- application contexts
+shadowSupplierInitiatedAC APPLICATION-CONTEXT ::= {
+ CONTRACT shadowSupplierContract
+ ESTABLISHED BY acse
+ INFORMATION TRANSFER BY pData
+ ABSTRACT SYNTAXES
+ {acse-abstract-syntax | directoryShadowAbstractSyntax}
+ APPLICATION CONTEXT NAME id-ac-shadowSupplierInitiatedAC
+}
+
+shadowSupplierInitiatedAsynchronousAC APPLICATION-CONTEXT ::= {
+ CONTRACT shadowSupplierContract
+ ESTABLISHED BY acse
+ INFORMATION TRANSFER BY pData
+ ABSTRACT SYNTAXES
+ {acse-abstract-syntax | directoryShadowAbstractSyntax}
+ APPLICATION CONTEXT NAME id-ac-shadowSupplierInitiatedAsynchronousAC
+}
+
+shadowConsumerInitiatedAC APPLICATION-CONTEXT ::= {
+ CONTRACT shadowConsumerContract
+ ESTABLISHED BY acse
+ INFORMATION TRANSFER BY pData
+ ABSTRACT SYNTAXES
+ {acse-abstract-syntax | directoryShadowAbstractSyntax}
+ APPLICATION CONTEXT NAME id-ac-shadowConsumerInitiatedAC
+}
+
+shadowConsumerInitiatedAsynchronousAC APPLICATION-CONTEXT ::= {
+ CONTRACT shadowConsumerContract
+ ESTABLISHED BY acse
+ INFORMATION TRANSFER BY pData
+ ABSTRACT SYNTAXES
+ {acse-abstract-syntax | directoryShadowAbstractSyntax}
+ APPLICATION CONTEXT NAME id-ac-shadowConsumerInitiatedAsynchronousAC
+}
+
+reliableShadowSupplierInitiatedAC APPLICATION-CONTEXT ::= {
+ CONTRACT shadowSupplierContract
+ ESTABLISHED BY association-by-RTSE
+ INFORMATION TRANSFER BY transfer-by-RTSE
+ ABSTRACT SYNTAXES
+ {acse-abstract-syntax | reliableShadowBindingAbstractSyntax |
+ directoryReliableShadowAbstractSyntax}
+ APPLICATION CONTEXT NAME id-ac-reliableShadowSupplierInitiatedAC
+}
+
+reliableShadowConsumerInitiatedAC APPLICATION-CONTEXT ::= {
+ CONTRACT shadowConsumerContract
+ ESTABLISHED BY association-by-RTSE
+ INFORMATION TRANSFER BY transfer-by-RTSE
+ ABSTRACT SYNTAXES
+ {acse-abstract-syntax | reliableShadowBindingAbstractSyntax |
+ directoryReliableShadowAbstractSyntax}
+ APPLICATION CONTEXT NAME id-ac-reliableShadowConsumerInitiatedAC
+}
+
+-- ROS objects
+initiating-consumer-dsa ROS-OBJECT-CLASS ::= {
+ INITIATES {shadowConsumerContract}
+ ID id-rosObject-initiatingConsumerDSA
+}
+
+responding-supplier-dsa ROS-OBJECT-CLASS ::= {
+ RESPONDS {shadowConsumerContract}
+ ID id-rosObject-respondingSupplierDSA
+}
+
+initiating-supplier-dsa ROS-OBJECT-CLASS ::= {
+ INITIATES {shadowSupplierContract}
+ ID id-rosObject-initiatingSupplierDSA
+}
+
+responding-consumer-dsa ROS-OBJECT-CLASS ::= {
+ RESPONDS {shadowSupplierContract}
+ ID id-rosObject-respondingConsumerDSA
+}
+
+-- contracts
+shadowConsumerContract CONTRACT ::= {
+ CONNECTION dispConnectionPackage
+ INITIATOR CONSUMER OF {shadowConsumerPackage}
+ ID id-contract-shadowConsumer
+}
+
+shadowSupplierContract CONTRACT ::= {
+ CONNECTION dispConnectionPackage
+ RESPONDER CONSUMER OF {shadowSupplierPackage}
+ ID id-contract-shadowSupplier
+}
+
+-- connection package
+dispConnectionPackage CONNECTION-PACKAGE ::= {
+ BIND dSAShadowBind
+ UNBIND dSAShadowUnbind
+ ID id-package-dispConnection
+}
+
+-- packages
+shadowConsumerPackage OPERATION-PACKAGE ::= {
+ CONSUMER INVOKES {requestShadowUpdate}
+ SUPPLIER INVOKES {updateShadow}
+ ID id-package-shadowConsumer
+}
+
+shadowSupplierPackage OPERATION-PACKAGE ::= {
+ SUPPLIER INVOKES {coordinateShadowUpdate | updateShadow}
+ ID id-package-shadowSupplier
+}
+
+-- abstract syntaxes
+directoryShadowAbstractSyntax ABSTRACT-SYNTAX ::= {
+ DISP-PDUs
+ IDENTIFIED BY id-as-directoryShadowAS
+}
+
+directoryReliableShadowAbstractSyntax ABSTRACT-SYNTAX ::= {
+ Reliable-DISP-PDUs
+ IDENTIFIED BY id-as-directoryReliableShadowAS
+}
+
+reliableShadowBindingAbstractSyntax ABSTRACT-SYNTAX ::= {
+ ReliableShadowBinding-PDUs
+ IDENTIFIED BY id-as-reliableShadowBindingAS
+}
+
+DISP-PDUs ::= CHOICE {
+ basicROS ROS{{DISP-InvokeIDSet}, {DISP-Invokable}, {DISP-Returnable}},
+ bind Bind{dSAShadowBind},
+ unbind Unbind{dSAShadowUnbind}
+}
+
+Reliable-DISP-PDUs ::=
+ ROS{{DISP-InvokeIDSet}, {DISP-Invokable}, {DISP-Returnable}}
+
+ReliableShadowBinding-PDUs ::= CHOICE {
+ rTS [0] RTSE-apdus,
+ bind Bind{dSAShadowBind},
+ unbind Unbind{dSAShadowUnbind}
+}
+
+DISP-InvokeIDSet ::= InvokeId(ALL EXCEPT absent:NULL)
+
+DISP-Invokable OPERATION ::=
+ {requestShadowUpdate | updateShadow | coordinateShadowUpdate}
+
+DISP-Returnable OPERATION ::=
+ {requestShadowUpdate | updateShadow | coordinateShadowUpdate}
+
+-- remote operation codes
+id-opcode-requestShadowUpdate Code ::= local:1
+
+id-opcode-updateShadow Code ::= local:2
+
+id-opcode-coordinateShadowUpdate Code ::= local:3
+
+-- remote error codes
+id-errcode-shadowError Code ::= local:1
+
+END -- DirectoryInformationShadowProtocol
+
+-- Generated by Asnp, the ASN.1 pretty-printer of France Telecom R&D
+
diff --git a/lib/asn1/test/asn1_SUITE_data/x420/DirectoryOperationalBindingManagementProtocol.asn b/lib/asn1/test/asn1_SUITE_data/x420/DirectoryOperationalBindingManagementProtocol.asn
new file mode 100644
index 0000000000..e3e1f95621
--- /dev/null
+++ b/lib/asn1/test/asn1_SUITE_data/x420/DirectoryOperationalBindingManagementProtocol.asn
@@ -0,0 +1,117 @@
+-- Module DirectoryOperationalBindingManagementProtocol (X.519 TC2:08/1997)
+
+DirectoryOperationalBindingManagementProtocol {joint-iso-itu-t ds(5)
+ module(1) dop(17) 3} DEFINITIONS ::=
+BEGIN
+
+-- EXPORTS All
+-- The types and values defined in this module are exported for use in the other ASN.1 modules contained
+-- within the Directory Specifications, and for the use of other applications which will use them to access
+-- Directory services. Other applications may use them for their own purposes, but this will not constrain
+-- extensions and modifications needed to maintain or improve the Directory service.
+IMPORTS
+ protocolObjectIdentifiers, directoryAbstractService, opBindingManagement
+ FROM UsefulDefinitions {joint-iso-itu-t ds(5) module(1)
+ usefulDefinitions(0) 3}
+ directoryBind, directoryUnbind
+ FROM DirectoryAbstractService directoryAbstractService
+ ROS-OBJECT-CLASS, CONTRACT, OPERATION-PACKAGE, CONNECTION-PACKAGE,
+ Code, OPERATION
+ FROM Remote-Operations-Information-Objects {joint-iso-itu-t
+ remote-operations(4) informationObjects(5) version1(0)}
+ ROS{}, Bind{}, Unbind{}, InvokeId
+ FROM Remote-Operations-Generic-ROS-PDUs {joint-iso-itu-t
+ remote-operations(4) generic-ROS-PDUs(6) version1(0)}
+ APPLICATION-CONTEXT
+ FROM Remote-Operations-Information-Objects-extensions {joint-iso-itu-t
+ remote-operations(4) informationObjects-extensions(8) version1(0)}
+ acse, pData
+ FROM Remote-Operations-Realizations {joint-iso-itu-t remote-operations(4)
+ realizations(9) version1(0)}
+ acse-abstract-syntax
+ FROM Remote-Operations-Abstract-Syntaxes {joint-iso-itu-t
+ remote-operations(4) remote-operations-abstract-syntaxes(12) version1(0)}
+ id-ac-directoryOperationalBindingManagementAC, id-rosObject-dopDSA,
+ id-contract-dop, id-package-dopConnection,
+ id-package-operationalBindingManagement,
+ id-as-directoryOperationalBindingManagementAS
+ FROM ProtocolObjectIdentifiers protocolObjectIdentifiers
+ establishOperationalBinding, modifyOperationalBinding,
+ terminateOperationalBinding, dSAOperationalBindingManagementBind,
+ dSAOperationalBindingManagementUnbind
+ FROM OperationalBindingManagement opBindingManagement;
+
+-- application contexts
+directoryOperationalBindingManagementAC APPLICATION-CONTEXT ::= {
+ CONTRACT dopContract
+ ESTABLISHED BY acse
+ INFORMATION TRANSFER BY pData
+ ABSTRACT SYNTAXES
+ {acse-abstract-syntax |
+ directoryOperationalBindingManagementAbstractSyntax}
+ APPLICATION CONTEXT NAME id-ac-directoryOperationalBindingManagementAC
+}
+
+-- ROS objects
+dop-dsa ROS-OBJECT-CLASS ::= {BOTH {dopContract}
+ ID id-rosObject-dopDSA
+}
+
+-- contracts
+dopContract CONTRACT ::= {
+ CONNECTION dopConnectionPackage
+ OPERATIONS OF {dopPackage}
+ ID id-contract-dop
+}
+
+-- connection package
+dopConnectionPackage CONNECTION-PACKAGE ::= {
+ BIND dSAOperationalBindingManagementBind
+ UNBIND dSAOperationalBindingManagementUnbind
+ ID id-package-dopConnection
+}
+
+-- packages
+dopPackage OPERATION-PACKAGE ::= {
+ CONSUMER INVOKES
+ {establishOperationalBinding | modifyOperationalBinding |
+ terminateOperationalBinding}
+ ID id-package-operationalBindingManagement
+}
+
+-- abstract syntaxes
+directoryOperationalBindingManagementAbstractSyntax ABSTRACT-SYNTAX ::=
+{DOP-PDUs
+ IDENTIFIED BY id-as-directoryOperationalBindingManagementAS
+}
+
+DOP-PDUs ::= CHOICE {
+ basicRos ROS{{DOP-InvokeIDSet}, {DOP-Invokable}, {DOP-Returnable}},
+ bind Bind{directoryBind},
+ unbind Unbind{directoryUnbind}
+}
+
+DOP-InvokeIDSet ::= InvokeId(ALL EXCEPT absent:NULL)
+
+DOP-Invokable OPERATION ::=
+ {establishOperationalBinding | modifyOperationalBinding |
+ terminateOperationalBinding}
+
+DOP-Returnable OPERATION ::=
+ {establishOperationalBinding | modifyOperationalBinding |
+ terminateOperationalBinding}
+
+-- remote operation codes
+id-op-establishOperationalBinding Code ::= local:100
+
+id-op-modifyOperationalBinding Code ::= local:102
+
+id-op-terminateOperationalBinding Code ::= local:101
+
+-- remote error codes
+id-err-operationalBindingError Code ::= local:100
+
+END -- DirectoryOperationalBindingManagementProtocol
+
+-- Generated by Asnp, the ASN.1 pretty-printer of France Telecom R&D
+
diff --git a/lib/asn1/test/asn1_SUITE_data/x420/DirectoryOperationalBindingTypes.asn b/lib/asn1/test/asn1_SUITE_data/x420/DirectoryOperationalBindingTypes.asn
new file mode 100644
index 0000000000..9df5d2783a
--- /dev/null
+++ b/lib/asn1/test/asn1_SUITE_data/x420/DirectoryOperationalBindingTypes.asn
@@ -0,0 +1,26 @@
+-- Module DirectoryOperationalBindingTypes (X.519 TC2:08/1997)
+
+DirectoryOperationalBindingTypes {joint-iso-itu-t ds(5) module(1)
+ directoryOperationalBindingTypes(25) 3} DEFINITIONS ::=
+BEGIN
+
+-- EXPORTS All
+-- The types and values defined in this module are exported for use in the other ASN.1 modules contained
+-- within the Directory Specifications, and for the use of other applications which will use them to access
+-- Directory services. Other applications may use them for their own purposes, but this will not constrain
+-- extensions and modifications needed to maintain or improve the Directory service.
+IMPORTS
+ id-ob
+ FROM UsefulDefinitions {joint-iso-itu-t ds(5) module(1)
+ usefulDefinitions(0) 3};
+
+id-op-binding-shadow OBJECT IDENTIFIER ::= {id-ob 1}
+
+id-op-binding-hierarchical OBJECT IDENTIFIER ::= {id-ob 2}
+
+id-op-binding-non-specific-hierarchical OBJECT IDENTIFIER ::= {id-ob 3}
+
+END -- DirectoryOperationalBindingTypes
+
+-- Generated by Asnp, the ASN.1 pretty-printer of France Telecom R&D
+
diff --git a/lib/asn1/test/asn1_SUITE_data/x420/DirectoryProtectionMappings.asn b/lib/asn1/test/asn1_SUITE_data/x420/DirectoryProtectionMappings.asn
new file mode 100644
index 0000000000..37c6cac261
--- /dev/null
+++ b/lib/asn1/test/asn1_SUITE_data/x420/DirectoryProtectionMappings.asn
@@ -0,0 +1,70 @@
+-- Module DirectoryProtectionMappings (X.830:04/1995)
+
+DirectoryProtectionMappings {joint-iso-itu-t genericULS(20) modules(1)
+ dirProtectionMappings(4)} DEFINITIONS AUTOMATIC TAGS ::=
+BEGIN
+
+-- These protection mappings generate bit-compatible encodings
+-- to the parameterized types in the Directory Authentication
+-- Framework
+-- EXPORTS All
+IMPORTS
+ notation, gulsSecurityTransformations
+ FROM ObjectIdentifiers {joint-iso-itu-t genericULS(20) modules(1)
+ objectIdentifiers(0)}
+ PROTECTION-MAPPING
+ FROM Notation notation
+ dirEncryptedTransformation, dirSignedTransformation,
+ dirSignatureTransformation
+ FROM GulsSecurityTransformations gulsSecurityTransformations;
+
+-- **************************************
+-- Directory encrypted Protection Mapping
+-- **************************************
+-- This protection mapping enables the notation
+-- PROTECTED {BaseType, encrypted}
+-- to replace the notation
+-- ENCRYPTED {BaseType}
+-- as provided by ITU-T Rec. X.509 | ISO/IEC 9594-8:1994, and to
+-- generate an identical bit-encoding.
+-- Security Service: confidentiality
+encrypted PROTECTION-MAPPING ::= {
+ SECURITY-TRANSFORMATION {dirEncryptedTransformation}
+}
+
+-- ***********************************
+-- Directory signed Protection Mapping
+-- ***********************************
+-- This protection mapping enables the notation
+-- PROTECTED {BaseType, signed}
+-- to replace the notation
+-- SIGNED {BaseType}
+-- as provided by ITU-T Rec. X.509 | ISO/IEC 9594-8:1994, and to
+-- generate an identical bit-encoding.
+-- Security Service: data origin authentication, data integrity and
+-- (in certain situations) non-repudiation.
+signed PROTECTION-MAPPING ::= {
+ SECURITY-TRANSFORMATION {dirSignedTransformation}
+}
+
+-- **************************************
+-- Directory signature Protection Mapping
+-- **************************************
+-- This protection mapping enables the notation
+-- PROTECTED {BaseType, signature}
+-- to provide a functionally-equivalent replacement of the notation
+-- SIGNATURE BaseType
+-- as provided by ITU-T Rec. X.509 | ISO/IEC 9594-8.
+-- Security Service: data origin authentication, data integrity and
+-- (in certain situations) non-repudiation.
+signature PROTECTION-MAPPING ::= {
+ SECURITY-TRANSFORMATION {dirSignatureTransformation}
+}
+
+END
+
+-- Generated by Asnp, the ASN.1 pretty-printer of France Telecom R&D
+
+
+-- content of stack:
+--
diff --git a/lib/asn1/test/asn1_SUITE_data/x420/DirectoryShadowAbstractService.asn b/lib/asn1/test/asn1_SUITE_data/x420/DirectoryShadowAbstractService.asn
new file mode 100644
index 0000000000..acbb692b6f
--- /dev/null
+++ b/lib/asn1/test/asn1_SUITE_data/x420/DirectoryShadowAbstractService.asn
@@ -0,0 +1,324 @@
+-- Module DirectoryShadowAbstractService (X.525:08/1997)
+DirectoryShadowAbstractService {joint-iso-itu-t ds(5) module(1)
+ directoryShadowAbstractService(15) 4} DEFINITIONS IMPLICIT TAGS ::=
+BEGIN
+
+-- EXPORTS All
+-- The types and values defined in this module are exported for use in the other ASN.1 modules contained
+-- within the Directory Specifications, and for the use of other applications which will use them to access
+-- directory services. Other applications may use them for their own purposes, but this will not constrain
+-- extensions and modifications needed to maintain or improve the directory service.
+IMPORTS
+ -- from ITU-T Rec. X.501 | ISO/IEC 9594-2
+ directoryAbstractService, directoryOperationalBindingTypes,
+ informationFramework, disp, distributedOperations,
+ dsaOperationalAttributeTypes, enhancedSecurity, opBindingManagement
+ FROM UsefulDefinitions {joint-iso-itu-t ds(5) module(1)
+ usefulDefinitions(0) 3}
+ Attribute, AttributeType, CONTEXT, DistinguishedName,
+ RelativeDistinguishedName, SubtreeSpecification
+ FROM InformationFramework {joint-iso-itu-t ds(5) module(1)
+ informationFramework(1) 3}
+ OPERATIONAL-BINDING, OperationalBindingID
+ FROM OperationalBindingManagement {joint-iso-itu-t ds(5) module(1)
+ opBindingManagement(18) 3}
+ DSEType, SupplierAndConsumers
+ FROM DSAOperationalAttributeTypes {joint-iso-itu-t ds(5) module(1)
+ dsaOperationalAttributeTypes(22) 3}
+ OPTIONALLY-PROTECTED{}, OPTIONALLY-PROTECTED-SEQ{}
+ FROM EnhancedSecurity {joint-iso-itu-t ds(5) module(1) enhancedSecurity(28)
+ 1}
+ -- from ITU-T Rec. X.511 | ISO/IEC 9594-3
+ CommonResultsSeq, ContextSelection, directoryBind, directoryUnbind,
+ EntryModification, SecurityParameters
+ FROM DirectoryAbstractService {joint-iso-itu-t ds(5) module(1)
+ directoryAbstractService(2) 3}
+ -- from ITU-T Rec. X.518 | ISO/IEC 9594-4
+ AccessPoint
+ FROM DistributedOperations {joint-iso-itu-t ds(5) module(1)
+ distributedOperations(3) 3}
+ -- from ITU-T Rec. X.519 | ISO/IEC 9594-5
+ id-op-binding-shadow
+ FROM DirectoryOperationalBindingTypes {joint-iso-itu-t ds(5) module(1)
+ directoryOperationalBindingTypes(25) 3}
+ id-errcode-shadowError, id-opcode-coordinateShadowUpdate,
+ id-opcode-requestShadowUpdate, id-opcode-updateShadow,
+ reliableShadowSupplierInitiatedAC, reliableShadowConsumerInitiatedAC,
+ shadowConsumerInitiatedAC, shadowSupplierInitiatedAC
+ FROM DirectoryInformationShadowProtocol {joint-iso-itu-t ds(5) module(1)
+ disp(16) 3}
+ -- from ITU-T Rec. X.880 | ISO/IEC 13712-1
+ ERROR, OPERATION
+ FROM Remote-Operations-Information-Objects {joint-iso-itu-t
+ remote-operations(4) informationObjects(5) version1(0)};
+
+-- bind and unbind operations
+dSAShadowBind OPERATION ::= directoryBind
+
+dSAShadowUnbind OPERATION ::= directoryUnbind
+
+-- shadow operational binding
+shadowOperationalBinding OPERATIONAL-BINDING ::= {
+ AGREEMENT ShadowingAgreementInfo
+ APPLICATION CONTEXTS
+ {{shadowSupplierInitiatedAC
+ APPLIES TO {All-operations-supplier-initiated}} |
+ {shadowConsumerInitiatedAC
+ APPLIES TO {All-operations-consumer-initiated}} |
+ {reliableShadowSupplierInitiatedAC
+ APPLIES TO {All-operations-supplier-initiated}} |
+ {reliableShadowConsumerInitiatedAC
+ APPLIES TO {All-operations-consumer-initiated}}}
+ ASYMMETRIC ROLE-A
+ { -- shadow supplier roleESTABLISHMENT-INITIATOR TRUE
+ ESTABLISHMENT-PARAMETER NULL
+ MODIFICATION-INITIATOR TRUE
+ TERMINATION-INITIATOR TRUE}
+ ROLE-B
+ { -- shadow consumer roleESTABLISHMENT-INITIATOR TRUE
+ ESTABLISHMENT-PARAMETER NULL
+ MODIFICATION-INITIATOR TRUE
+ MODIFICATION-PARAMETER ModificationParameter
+ TERMINATION-INITIATOR TRUE}
+ ID id-op-binding-shadow
+}
+
+-- types
+ModificationParameter ::= SEQUENCE {
+ secondaryShadows SET OF SupplierAndConsumers
+}
+
+AgreementID ::= OperationalBindingID
+
+ShadowingAgreementInfo ::= SEQUENCE {
+ shadowSubject UnitOfReplication,
+ updateMode UpdateMode DEFAULT supplierInitiated:onChange:TRUE,
+ master AccessPoint OPTIONAL,
+ secondaryShadows [2] BOOLEAN DEFAULT FALSE
+}
+
+UnitOfReplication ::= SEQUENCE {
+ area AreaSpecification,
+ attributes AttributeSelection,
+ knowledge Knowledge OPTIONAL,
+ subordinates BOOLEAN DEFAULT FALSE,
+ contextSelection ContextSelection OPTIONAL,
+ supplyContexts
+ [0] CHOICE {allContexts NULL,
+ selectedContexts SET SIZE (1..MAX) OF CONTEXT.&id} OPTIONAL
+}
+
+AreaSpecification ::= SEQUENCE {
+ contextPrefix DistinguishedName,
+ replicationArea SubtreeSpecification
+}
+
+Knowledge ::= SEQUENCE {
+ knowledgeType ENUMERATED {master(0), shadow(1), both(2)},
+ extendedKnowledge BOOLEAN DEFAULT FALSE
+}
+
+AttributeSelection ::= SET OF ClassAttributeSelection
+
+ClassAttributeSelection ::= SEQUENCE {
+ class OBJECT IDENTIFIER OPTIONAL,
+ classAttributes ClassAttributes DEFAULT allAttributes:NULL
+}
+
+ClassAttributes ::= CHOICE {
+ allAttributes NULL,
+ include [0] AttributeTypes,
+ exclude [1] AttributeTypes
+}
+
+AttributeTypes ::= SET OF AttributeType
+
+UpdateMode ::= CHOICE {
+ supplierInitiated [0] SupplierUpdateMode,
+ consumerInitiated [1] ConsumerUpdateMode
+}
+
+SupplierUpdateMode ::= CHOICE {
+ onChange BOOLEAN,
+ scheduled SchedulingParameters
+}
+
+ConsumerUpdateMode ::= SchedulingParameters
+
+SchedulingParameters ::= SEQUENCE {
+ periodic PeriodicStrategy OPTIONAL, -- must be present if othertimes is set to FALSE
+ othertimes BOOLEAN DEFAULT FALSE
+}
+
+PeriodicStrategy ::= SEQUENCE {
+ beginTime Time OPTIONAL,
+ windowSize INTEGER,
+ updateInterval INTEGER
+}
+
+Time ::= GeneralizedTime
+
+-- as per 34.2 b) and c) of CCITT Rec. X.208 and ISO/IEC 8824
+-- shadow operations, arguments, and results
+All-operations-consumer-initiated OPERATION ::=
+ {requestShadowUpdate | updateShadow}
+
+All-operations-supplier-initiated OPERATION ::=
+ {coordinateShadowUpdate | updateShadow}
+
+coordinateShadowUpdate OPERATION ::= {
+ ARGUMENT CoordinateShadowUpdateArgument
+ RESULT CoordinateShadowUpdateResult
+ ERRORS {shadowError}
+ CODE id-opcode-coordinateShadowUpdate
+}
+
+CoordinateShadowUpdateArgument ::=
+ OPTIONALLY-PROTECTED
+ {[0] SEQUENCE {agreementID AgreementID,
+ lastUpdate Time OPTIONAL,
+ updateStrategy
+ CHOICE {standard
+ ENUMERATED {noChanges(0), incremental(1),
+ total(2)},
+ other EXTERNAL},
+ securityParameters SecurityParameters OPTIONAL}}
+
+CoordinateShadowUpdateResult ::= CHOICE {
+ null NULL,
+ information
+ OPTIONALLY-PROTECTED{[0] SEQUENCE {greementID AgreementID,
+ lastUpdate Time OPTIONAL,
+ COMPONENTS OF CommonResultsSeq
+ }}
+}
+
+requestShadowUpdate OPERATION ::= {
+ ARGUMENT RequestShadowUpdateArgument
+ RESULT RequestShadowUpdateResult
+ ERRORS {shadowError}
+ CODE id-opcode-requestShadowUpdate
+}
+
+RequestShadowUpdateArgument ::=
+ OPTIONALLY-PROTECTED
+ {[0] SEQUENCE {agreementID AgreementID,
+ lastUpdate Time OPTIONAL,
+ requestedStrategy
+ CHOICE {standard ENUMERATED {incremental(1), total(2)},
+ other EXTERNAL},
+ securityParameters SecurityParameters OPTIONAL}}
+
+RequestShadowUpdateResult ::= CHOICE {
+ null NULL,
+ information
+ OPTIONALLY-PROTECTED{[0] SEQUENCE {agreementID AgreementID,
+ lastUpdate Time OPTIONAL,
+ COMPONENTS OF CommonResultsSeq
+ }}
+}
+
+updateShadow OPERATION ::= {
+ ARGUMENT UpdateShadowArgument
+ RESULT UpdateShadowResult
+ ERRORS {shadowError}
+ CODE id-opcode-updateShadow
+}
+
+UpdateShadowArgument ::=
+ OPTIONALLY-PROTECTED
+ {[0] SEQUENCE {agreementID AgreementID,
+ updateTime Time,
+ updateWindow UpdateWindow OPTIONAL,
+ updatedInfo RefreshInformation,
+ securityParameters SecurityParameters OPTIONAL}}
+
+UpdateShadowResult ::= CHOICE {
+ null NULL,
+ information
+ OPTIONALLY-PROTECTED{[0] SEQUENCE {agreementID AgreementID,
+ lastUpdate Time OPTIONAL,
+ COMPONENTS OF CommonResultsSeq
+ }}
+}
+
+UpdateWindow ::= SEQUENCE {start Time,
+ stop Time
+}
+
+RefreshInformation ::= CHOICE {
+ noRefresh NULL,
+ total [0] TotalRefresh,
+ incremental [1] IncrementalRefresh,
+ otherStrategy EXTERNAL
+}
+
+TotalRefresh ::= SEQUENCE {
+ sDSE SDSEContent OPTIONAL,
+ subtree SET SIZE (1..MAX) OF Subtree OPTIONAL
+}
+
+SDSEContent ::= SEQUENCE {
+ sDSEType SDSEType,
+ subComplete [0] BOOLEAN DEFAULT FALSE,
+ attComplete [1] BOOLEAN OPTIONAL,
+ attributes SET OF Attribute,
+ attValIncomplete SET OF AttributeType DEFAULT {}
+}
+
+SDSEType ::= DSEType
+
+Subtree ::= SEQUENCE {
+ rdn RelativeDistinguishedName,
+ COMPONENTS OF TotalRefresh
+}
+
+IncrementalRefresh ::= SEQUENCE OF IncrementalStepRefresh
+
+IncrementalStepRefresh ::= SEQUENCE {
+ sDSEChanges
+ CHOICE {add [0] SDSEContent,
+ remove NULL,
+ modify [1] ContentChange} OPTIONAL,
+ subordinateUpdates SEQUENCE SIZE (1..MAX) OF SubordinateChanges OPTIONAL
+}
+
+ContentChange ::= SEQUENCE {
+ rename
+ CHOICE {newRDN RelativeDistinguishedName,
+ newDN DistinguishedName} OPTIONAL,
+ attributeChanges
+ CHOICE {replace [0] SET SIZE (1..MAX) OF Attribute,
+ changes [1] SEQUENCE SIZE (1..MAX) OF EntryModification
+ } OPTIONAL,
+ sDSEType SDSEType,
+ subComplete [2] BOOLEAN DEFAULT FALSE,
+ attComplete [3] BOOLEAN OPTIONAL,
+ attValIncomplete SET OF AttributeType DEFAULT {}
+}
+
+SubordinateChanges ::= SEQUENCE {
+ subordinate RelativeDistinguishedName,
+ changes IncrementalStepRefresh
+}
+
+-- errors and parameters
+shadowError ERROR ::= {
+ PARAMETER OPTIONALLY-PROTECTED-SEQ
+ {SEQUENCE {problem ShadowProblem,
+ lastUpdate Time OPTIONAL,
+ updateWindow UpdateWindow OPTIONAL,
+ COMPONENTS OF CommonResultsSeq}}
+ CODE id-errcode-shadowError
+}
+
+ShadowProblem ::= INTEGER {
+ invalidAgreementID(1), inactiveAgreement(2), invalidInformationReceived(3),
+ unsupportedStrategy(4), missedPrevious(5), fullUpdateRequired(6),
+ unwillingToPerform(7), unsuitableTiming(8), updateAlreadyReceived(9),
+ invalidSequencing(10), insufficientResources(11)}
+
+END -- DirectoryShadowAbstractService
+
+-- Generated by Asnp, the ASN.1 pretty-printer of France Telecom R&D
+
diff --git a/lib/asn1/test/asn1_SUITE_data/x420/DirectorySystemProtocol.asn b/lib/asn1/test/asn1_SUITE_data/x420/DirectorySystemProtocol.asn
new file mode 100644
index 0000000000..cace79d109
--- /dev/null
+++ b/lib/asn1/test/asn1_SUITE_data/x420/DirectorySystemProtocol.asn
@@ -0,0 +1,118 @@
+-- Module DirectorySystemProtocol (X.519 TC2:08/1997)
+
+DirectorySystemProtocol {joint-iso-itu-t ds(5) module(1) dsp(12) 3} DEFINITIONS
+::=
+BEGIN
+
+-- EXPORTS All
+-- The types and values defined in this module are exported for use in the other ASN.1 modules contained
+-- within the Directory Specifications, and for the use of other applications which will use them to access
+-- Directory services. Other applications may use them for their own purposes, but this will not constrain
+-- extensions and modifications needed to maintain or improve the Directory service.
+IMPORTS
+ distributedOperations, protocolObjectIdentifiers
+ FROM UsefulDefinitions {joint-iso-itu-t ds(5) module(1)
+ usefulDefinitions(0) 3}
+ ROS-OBJECT-CLASS, CONTRACT, OPERATION-PACKAGE, CONNECTION-PACKAGE,
+ Code, OPERATION
+ FROM Remote-Operations-Information-Objects {joint-iso-itu-t
+ remote-operations(4) informationObjects(5) version1(0)}
+ ROS{}, Bind{}, Unbind{}, InvokeId
+ FROM Remote-Operations-Generic-ROS-PDUs {joint-iso-itu-t
+ remote-operations(4) generic-ROS-PDUs(6) version1(0)}
+ APPLICATION-CONTEXT
+ FROM Remote-Operations-Information-Objects-extensions {joint-iso-itu-t
+ remote-operations(4) informationObjects-extensions(8) version1(0)}
+ acse, pData
+ FROM Remote-Operations-Realizations {joint-iso-itu-t remote-operations(4)
+ realizations(9) version1(0)}
+ acse-abstract-syntax
+ FROM Remote-Operations-Abstract-Syntaxes {joint-iso-itu-t
+ remote-operations(4) remote-operations-abstract-syntaxes(12) version1(0)}
+ id-ac-directorySystemAC, id-rosObject-dspDSA, id-contract-dsp,
+ id-package-dspConnection, id-package-chainedRead, id-package-chainedSearch,
+ id-package-chainedModify, id-as-directorySystemAS
+ FROM ProtocolObjectIdentifiers protocolObjectIdentifiers
+ dSABind, dSAUnbind, chainedRead, chainedCompare, chainedAbandon, chainedList,
+ chainedSearch, chainedAddEntry, chainedRemoveEntry, chainedModifyEntry,
+ chainedModifyDN
+ FROM DistributedOperations distributedOperations;
+
+-- application contexts
+directorySystemAC APPLICATION-CONTEXT ::= {
+ CONTRACT dspContract
+ ESTABLISHED BY acse
+ INFORMATION TRANSFER BY pData
+ ABSTRACT SYNTAXES
+ {acse-abstract-syntax | directorySystemAbstractSyntax}
+ APPLICATION CONTEXT NAME id-ac-directorySystemAC
+}
+
+-- ROS objects
+dsp-dsa ROS-OBJECT-CLASS ::= {BOTH {dspContract}
+ ID id-rosObject-dspDSA
+}
+
+-- contracts
+dspContract CONTRACT ::= {
+ CONNECTION dspConnectionPackage
+ OPERATIONS OF
+ {chainedReadPackage | chainedSearchPackage | chainedModifyPackage}
+ ID id-contract-dsp
+}
+
+-- connection package
+dspConnectionPackage CONNECTION-PACKAGE ::= {
+ BIND dSABind
+ UNBIND dSAUnbind
+ ID id-package-dspConnection
+}
+
+-- chained read package
+chainedReadPackage OPERATION-PACKAGE ::= {
+ OPERATIONS {chainedRead | chainedCompare | chainedAbandon}
+ ID id-package-chainedRead
+}
+
+-- chained search package
+chainedSearchPackage OPERATION-PACKAGE ::= {
+ OPERATIONS {chainedList | chainedSearch}
+ ID id-package-chainedSearch
+}
+
+-- chained modify package
+chainedModifyPackage OPERATION-PACKAGE ::= {
+ OPERATIONS
+ {chainedAddEntry | chainedRemoveEntry | chainedModifyEntry |
+ chainedModifyDN}
+ ID id-package-chainedModify
+}
+
+-- abstract syntaxes
+directorySystemAbstractSyntax ABSTRACT-SYNTAX ::= {
+ DSP-PDUs
+ IDENTIFIED BY id-as-directorySystemAS
+}
+
+DSP-PDUs ::= CHOICE {
+ basicRos ROS{{DSP-InvokeIDSet}, {DSP-Invokable}, {DSP-Returnable}},
+ bind Bind{dSABind},
+ unbind Unbind{dSAUnbind}
+}
+
+DSP-InvokeIDSet ::= InvokeId(ALL EXCEPT absent:NULL)
+
+DSP-Invokable OPERATION ::=
+ {chainedRead | chainedCompare | chainedAbandon | chainedList | chainedSearch
+ | chainedAddEntry | chainedRemoveEntry | chainedModifyEntry |
+ chainedModifyDN}
+
+DSP-Returnable OPERATION ::=
+ {chainedRead | chainedCompare | chainedAbandon | chainedList | chainedSearch
+ | chainedAddEntry | chainedRemoveEntry | chainedModifyEntry |
+ chainedModifyDN}
+
+END -- DirectorySystemProtocol
+
+-- Generated by Asnp, the ASN.1 pretty-printer of France Telecom R&D
+
diff --git a/lib/asn1/test/asn1_SUITE_data/x420/DistributedOperations.asn b/lib/asn1/test/asn1_SUITE_data/x420/DistributedOperations.asn
new file mode 100644
index 0000000000..72e791f10c
--- /dev/null
+++ b/lib/asn1/test/asn1_SUITE_data/x420/DistributedOperations.asn
@@ -0,0 +1,181 @@
+-- Module DistributedOperations (X.518 TC2:08/1997)
+
+DistributedOperations {joint-iso-itu-t ds(5) module(1) distributedOperations(3)
+ 3} DEFINITIONS ::=
+BEGIN
+
+-- EXPORTS All
+-- The types and values defined in this module are exported for use in the other ASN.1 modules contained
+-- within the Directory Specifications, and for the use of other applications which will use them to access
+-- Directory services. Other applications may use them for their own purposes, but this will not constrain
+-- extensions and modifications needed to maintain or improve the Directory service.
+IMPORTS
+ informationFramework, directoryAbstractService, distributedOperations,
+ selectedAttributeTypes, basicAccessControl, dap, enhancedSecurity
+ FROM UsefulDefinitions {joint-iso-itu-t ds(5) module(1)
+ usefulDefinitions(0) 3}
+ DistinguishedName, Name, RDNSequence, SearchRuleId, MRMapping
+ FROM InformationFramework informationFramework
+ PresentationAddress, ProtocolInformation, UniqueIdentifier
+ FROM SelectedAttributeTypes selectedAttributeTypes
+ AuthenticationLevel
+ FROM BasicAccessControl basicAccessControl
+ OPERATION, ERROR
+ FROM Remote-Operations-Information-Objects {joint-iso-itu-t
+ remote-operations(4) informationObjects(5) version1(0)}
+ directoryBind, directoryUnbind, read, compare, abandon, list, search,
+ addEntry, removeEntry, modifyEntry, modifyDN, referral, SecurityParameters,
+ CommonResults
+ FROM DirectoryAbstractService directoryAbstractService
+ OPTIONALLY-PROTECTED{}
+ FROM EnhancedSecurity enhancedSecurity
+ id-errcode-dsaReferral
+ FROM DirectoryAccessProtocol dap;
+
+-- parameterized type for deriving chained operations
+chained{OPERATION:operation} OPERATION ::= {
+ ARGUMENT OPTIONALLY-PROTECTED
+ {SET {chainedArgument ChainingArguments,
+ argument [0] operation.&ArgumentType}}
+ RESULT OPTIONALLY-PROTECTED
+ {SET {chainedResult ChainingResults,
+ result [0] operation.&ResultType}}
+ ERRORS
+ {operation.&Errors EXCEPT referral | dsaReferral}
+ CODE operation.&operationCode
+}
+
+-- bind and unbind operations
+dSABind OPERATION ::= directoryBind
+
+dSAUnbind OPERATION ::= directoryUnbind
+
+-- chained operations
+chainedRead OPERATION ::= chained{read}
+
+chainedCompare OPERATION ::= chained{compare}
+
+chainedAbandon OPERATION ::= abandon
+
+chainedList OPERATION ::= chained{list}
+
+chainedSearch OPERATION ::= chained{search}
+
+chainedAddEntry OPERATION ::= chained{addEntry}
+
+chainedRemoveEntry OPERATION ::= chained{removeEntry}
+
+chainedModifyEntry OPERATION ::= chained{modifyEntry}
+
+chainedModifyDN OPERATION ::= chained{modifyDN}
+
+-- errors and parameters
+dsaReferral ERROR ::= {
+ PARAMETER OPTIONALLY-PROTECTED
+ {SET {reference [0] ContinuationReference,
+ contextPrefix [1] DistinguishedName OPTIONAL,
+ COMPONENTS OF CommonResults}}
+ CODE id-errcode-dsaReferral
+}
+
+-- common arguments and results
+ChainingArguments ::= SET {
+ originator [0] DistinguishedName OPTIONAL,
+ targetObject [1] DistinguishedName OPTIONAL,
+ operationProgress
+ [2] OperationProgress DEFAULT {nameResolutionPhase notStarted},
+ traceInformation [3] TraceInformation,
+ aliasDereferenced [4] BOOLEAN DEFAULT FALSE,
+ aliasedRDNs [5] INTEGER OPTIONAL,
+ -- only present in 1988 systems
+ returnCrossRefs [6] BOOLEAN DEFAULT FALSE,
+ referenceType [7] ReferenceType DEFAULT superior,
+ info [8] DomainInfo OPTIONAL,
+ timeLimit [9] Time OPTIONAL,
+ securityParameters [10] SecurityParameters DEFAULT {},
+ entryOnly [11] BOOLEAN DEFAULT FALSE,
+ uniqueIdentifier [12] UniqueIdentifier OPTIONAL,
+ authenticationLevel [13] AuthenticationLevel OPTIONAL,
+ exclusions [14] Exclusions OPTIONAL,
+ excludeShadows [15] BOOLEAN DEFAULT FALSE,
+ nameResolveOnMaster [16] BOOLEAN DEFAULT FALSE,
+ operationIdentifier [17] INTEGER OPTIONAL,
+ searchRuleId [18] SearchRuleId OPTIONAL,
+ chainedRelaxation [19] MRMapping OPTIONAL
+}
+
+Time ::= CHOICE {utcTime UTCTime,
+ generalizedTime GeneralizedTime
+}
+
+ChainingResults ::= SET {
+ info [0] DomainInfo OPTIONAL,
+ crossReferences [1] SEQUENCE (SIZE (1..MAX)) OF CrossReference OPTIONAL,
+ securityParameters [2] SecurityParameters DEFAULT {},
+ alreadySearched [3] Exclusions OPTIONAL
+}
+
+CrossReference ::= SET {
+ contextPrefix [0] DistinguishedName,
+ accessPoint [1] AccessPointInformation,
+ chainingRequired [2] BOOLEAN DEFAULT FALSE
+}
+
+ReferenceType ::= ENUMERATED {
+ superior(1), subordinate(2), cross(3), nonSpecificSubordinate(4),
+ supplier(5), master(6), immediateSuperior(7), self(8)}
+
+TraceInformation ::= SEQUENCE OF TraceItem
+
+TraceItem ::= SET {
+ dsa [0] Name,
+ targetObject [1] Name OPTIONAL,
+ operationProgress [2] OperationProgress
+}
+
+OperationProgress ::= SET {
+ nameResolutionPhase
+ [0] ENUMERATED {notStarted(1), proceeding(2), completed(3)},
+ nextRDNToBeResolved [1] INTEGER OPTIONAL
+}
+
+DomainInfo ::= ABSTRACT-SYNTAX.&Type
+
+ContinuationReference ::= SET {
+ targetObject [0] Name,
+ aliasedRDNs [1] INTEGER OPTIONAL, -- only present in 1988 systems
+ operationProgress [2] OperationProgress,
+ rdnsResolved [3] INTEGER OPTIONAL,
+ referenceType [4] ReferenceType,
+ accessPoints [5] SET OF AccessPointInformation,
+ entryOnly [6] BOOLEAN DEFAULT FALSE,
+ exclusions [7] Exclusions OPTIONAL,
+ returnToDUA [8] BOOLEAN DEFAULT FALSE,
+ nameResolveOnMaster [9] BOOLEAN DEFAULT FALSE
+}
+
+AccessPoint ::= SET {
+ ae-title [0] Name,
+ address [1] PresentationAddress,
+ protocolInformation [2] SET OF ProtocolInformation OPTIONAL,
+ chainingRequired [3] BOOLEAN DEFAULT FALSE
+}
+
+AccessPointInformation ::= SET {
+ COMPONENTS OF MasterOrShadowAccessPoint,
+ additionalPoints [5] MasterAndShadowAccessPoints OPTIONAL
+}
+
+MasterOrShadowAccessPoint ::= SET {
+ COMPONENTS OF AccessPoint,
+ category [4] ENUMERATED {master(0), shadow(1)} DEFAULT master
+}
+
+MasterAndShadowAccessPoints ::= SET OF MasterOrShadowAccessPoint
+
+Exclusions ::= SET OF RDNSequence
+
+END
+
+-- Generated by Asnp, the ASN.1 pretty-printer of France Telecom R&D
+
diff --git a/lib/asn1/test/asn1_SUITE_data/x420/Document-Profile-Descriptor.asn b/lib/asn1/test/asn1_SUITE_data/x420/Document-Profile-Descriptor.asn
new file mode 100644
index 0000000000..d8c15b7afa
--- /dev/null
+++ b/lib/asn1/test/asn1_SUITE_data/x420/Document-Profile-Descriptor.asn
@@ -0,0 +1,464 @@
+-- Module Document-Profile-Descriptor (T.415:03/1993)
+
+Document-Profile-Descriptor {2 8 1 5 6} DEFINITIONS ::=
+BEGIN
+
+EXPORTS
+ Document-Profile-Descriptor, Character-Data, Document-Reference,
+ Date-and-Time, Dates-and-Times, Personal-Name, Originators,
+ Other-User-Information, Local-File-References, Security-Information,
+ Document-Description,
+ External-References ,
+ Sealed-Doc-Bodyparts, ODA-Version;
+
+IMPORTS
+ Resource-Name, Object-or-Class-Identifier, Protected-Part-Identifier,
+ Style-Identifier
+ FROM Identifiers-and-Expressions -- see 7.8
+
+ Measure-Pair, Transparency, Colour, Dimension-Pair, One-Of-Four-Angles,
+ Border, Medium-Type, Comment-String, Content-Background-Colour,
+ Content-Foreground-Colour
+ FROM Layout-Descriptors -- see 7.9
+
+ Protection
+ FROM Logical-Descriptors -- see 7.10
+
+ Content-Architecture-Class, Content-Type, Block-Alignment, Fill-Order
+ FROM Style-Descriptors -- see 7.11
+
+ Type-Of-Coding
+ FROM Text-Units -- see 7.13
+
+ Colour-Characteristics, Colour-Spaces-List, Colour-Expression, Colour-Table
+ FROM Colour-Attributes -- see 7.14
+
+ Character-Content-Defaults, Character-Presentation-Feature,
+ Character-Coding-Attribute
+ FROM Character-Profile-Attributes {2 8 1 6 4
+ } -- see ITU-T Rec. T.416 | ISO/IEC 8613-6
+ Raster-Gr-Content-Defaults, Ra-Gr-Presentation-Feature,
+ Ra-Gr-Coding-Attribute
+ FROM Raster-Gr-Profile-Attributes {2 8 1 7 4
+ } -- see ITU-T Rec. T.417 | ISO/IEC 8613-7
+ Geo-Gr-Content-Defaults, Geo-Gr-Presentation-Feature, Geo-Gr-Coding-Attribute
+ FROM Geo-Gr-Profile-Attributes {2 8 1 8 4
+ } -- see ITU-T Rec. T.418 | ISO/IEC 8613-8
+ Font-Attribute-Set
+ FROM ISO-STANDARD-9541-FONT-ATTRIBUTE-SET {1 0 9541 2 2
+ } -- see ISO/IEC 9541-2
+ Document-Presentation-Time, Time-Scaling
+ FROM Temporal-Relationships {2 8 1 14 0};
+
+-- See ITU-T Rec. T.424 | ISO/IEC 8613-14
+Document-Profile-Descriptor ::= SET {
+ generic-layout-structure [0] IMPLICIT NumericString OPTIONAL,
+ specific-layout-structure [1] IMPLICIT NumericString OPTIONAL,
+ generic-logical-structure [4] IMPLICIT NumericString OPTIONAL,
+ specific-logical-structure [5] IMPLICIT NumericString OPTIONAL,
+ presentation-styles [6] IMPLICIT NumericString OPTIONAL,
+ layout-styles [7] IMPLICIT NumericString OPTIONAL,
+ sealed-profiles [12] IMPLICIT NumericString OPTIONAL,
+ enciphered-profiles [13] IMPLICIT NumericString OPTIONAL,
+ preenciphered-bodyparts [14] IMPLICIT NumericString OPTIONAL,
+ postenciphered-bodyparts [15] IMPLICIT NumericString OPTIONAL,
+ -- for the generic structures,
+ -- 'partial-generator-set' is represented by "0", 'complete-generator-set'
+ -- is represented by "1", 'factor-set' is represented by "2";
+ -- for the other cases, the numeric string has the value 'present'
+ -- represented by "1"
+ external-document-class [9] Document-Reference OPTIONAL,
+ resource-document [10] Document-Reference OPTIONAL,
+ resources
+ [11] IMPLICIT SET OF
+ SET {resource-identifier Resource-Name,
+ object-class-identifier Object-or-Class-Identifier
+ } OPTIONAL,
+ document-characteristics [2] IMPLICIT Document-Characteristics,
+ document-management-attributes
+ [3] IMPLICIT Document-Management-Attributes OPTIONAL,
+ document-security-attributes
+ [16] IMPLICIT Document-Security-Attributes OPTIONAL,
+ links [17] IMPLICIT NumericString OPTIONAL,
+ link-classes [18] IMPLICIT NumericString OPTIONAL,
+ enciphered-links [19] IMPLICIT NumericString OPTIONAL,
+ temporal-relations [20] IMPLICIT NumericString OPTIONAL
+}
+
+Document-Characteristics ::= SET {
+ document-application-profile
+ CHOICE {a [0] IMPLICIT INTEGER {group-4-facsimile(2)},
+ b [4] IMPLICIT OBJECT IDENTIFIER} OPTIONAL,
+ doc-appl-profile-defaults
+ [10] IMPLICIT Doc-Appl-Profile-Defaults OPTIONAL,
+ document-architecture-class
+ [1] IMPLICIT INTEGER {formatted(0), processable(1),
+ formatted-processable(2)},
+ content-architecture-classes [5] IMPLICIT SET OF OBJECT IDENTIFIER,
+ interchange-format-class [6] IMPLICIT INTEGER {if-a(0), if-b(1)},
+ oda-version [8] IMPLICIT ODA-Version,
+ alternative-feature-sets
+ [11] IMPLICIT SET OF SET OF OBJECT IDENTIFIER OPTIONAL,
+ non-basic-doc-characteristics
+ [2] IMPLICIT Non-Basic-Doc-Characteristics OPTIONAL,
+ non-basic-struc-characteristics
+ [3] IMPLICIT Non-Basic-Struc-Characteristics OPTIONAL,
+ additional-doc-characteristics
+ [9] IMPLICIT Additional-Doc-Characteristics OPTIONAL
+}
+
+ODA-Version ::= SEQUENCE {
+ standard-or-recommendation Character-Data,
+ publication-date Date-and-Time
+}
+
+Doc-Appl-Profile-Defaults ::= SET {
+ document-architecture-defaults
+ [0] IMPLICIT Document-Architecture-Defaults OPTIONAL,
+ character-content-defaults
+ [1] IMPLICIT Character-Content-Defaults OPTIONAL,
+ raster-gr-content-defaults
+ [2] IMPLICIT Raster-Gr-Content-Defaults OPTIONAL,
+ geo-gr-content-defaults
+ [3] IMPLICIT Geo-Gr-Content-Defaults OPTIONAL,
+ -- the following tags are reserved for additional types
+ -- of content defaults:
+ -- [4] videotex, for use in conjunction with CCITT Recommendations
+ -- [5] audio
+ -- [6] dynamic-graphics
+ external-content-architecture-defaults
+ [7] IMPLICIT SEQUENCE OF EXTERNAL OPTIONAL
+}
+
+Document-Architecture-Defaults ::= SET {
+ content-architecture-class
+ CHOICE {a [0] IMPLICIT Content-Architecture-Class,
+ b [1] IMPLICIT Content-Type} OPTIONAL,
+ page-dimensions [2] IMPLICIT Measure-Pair OPTIONAL,
+ transparency [3] IMPLICIT Transparency OPTIONAL,
+ colour [4] IMPLICIT Colour OPTIONAL,
+ colour-of-layout-object [11] Colour-Expression OPTIONAL,
+ object-colour-table [12] IMPLICIT Colour-Table OPTIONAL,
+ content-background-colour [13] Content-Background-Colour OPTIONAL,
+ content-foreground-colour [14] Content-Foreground-Colour OPTIONAL,
+ content-colour-table [15] IMPLICIT Colour-Table OPTIONAL,
+ layout-path [5] IMPLICIT One-Of-Four-Angles OPTIONAL,
+ medium-type [6] IMPLICIT Medium-Type OPTIONAL,
+ block-alignment [7] IMPLICIT Block-Alignment OPTIONAL,
+ border [8] IMPLICIT Border OPTIONAL,
+ page-position [9] IMPLICIT Measure-Pair OPTIONAL,
+ type-of-coding [10] Type-Of-Coding OPTIONAL
+}
+
+Non-Basic-Doc-Characteristics ::= SET {
+ profile-character-sets [5] IMPLICIT OCTET STRING OPTIONAL,
+ comments-character-sets [1] IMPLICIT OCTET STRING OPTIONAL,
+ alternative-repr-char-sets [6] IMPLICIT OCTET STRING OPTIONAL,
+ -- each of these octet strings represents a string of escape sequences
+ page-dimensions [2] IMPLICIT SET OF Dimension-Pair OPTIONAL,
+ medium-types [8] IMPLICIT SET OF Medium-Type OPTIONAL,
+ layout-paths
+ [21] IMPLICIT SET OF One-Of-Four-Angles OPTIONAL,
+ transparencies [22] IMPLICIT SET OF Transparency OPTIONAL,
+ protections [23] IMPLICIT SET OF Protection OPTIONAL,
+ block-alignments
+ [24] IMPLICIT SET OF Block-Alignment OPTIONAL,
+ fill-orders [25] IMPLICIT SET OF Fill-Order OPTIONAL,
+ colours [26] IMPLICIT SET OF Colour OPTIONAL,
+ colours-of-layout-object
+ [30] IMPLICIT SET OF Colour-Expression OPTIONAL,
+ object-colour-tables [31] IMPLICIT SET OF Colour-Table OPTIONAL,
+ content-background-colours
+ [32] IMPLICIT SET OF Content-Background-Colour OPTIONAL,
+ content-foreground-colours
+ [33] IMPLICIT SET OF Content-Foreground-Colour OPTIONAL,
+ content-colour-tables [34] IMPLICIT SET OF Colour-Table OPTIONAL,
+ borders [27] IMPLICIT SET OF Border OPTIONAL,
+ page-positions [28] IMPLICIT SET OF Measure-Pair OPTIONAL,
+ types-of-coding [29] IMPLICIT SET OF Type-Of-Coding OPTIONAL,
+ character-presentation-features
+ [9] IMPLICIT SET OF Character-Presentation-Feature OPTIONAL,
+ ra-gr-presentation-features
+ [4] IMPLICIT SET OF Ra-Gr-Presentation-Feature OPTIONAL,
+ geo-gr-presentation-features
+ [12] IMPLICIT SET OF Geo-Gr-Presentation-Feature OPTIONAL,
+ character-coding-attributes
+ [16] IMPLICIT SET OF Character-Coding-Attribute OPTIONAL,
+ ra-gr-coding-attributes
+ [3] IMPLICIT SET OF Ra-Gr-Coding-Attribute OPTIONAL,
+ geo-gr-coding-attributes
+ [17] IMPLICIT SET OF Geo-Gr-Coding-Attribute OPTIONAL,
+ ext-non-basic-pres-features [10] IMPLICIT SEQUENCE OF EXTERNAL OPTIONAL,
+ ext-non-basic-coding-attributes [11] IMPLICIT SEQUENCE OF EXTERNAL OPTIONAL
+}
+
+Non-Basic-Struc-Characteristics ::= SET {
+ number-of-objects-per-page [0] IMPLICIT INTEGER OPTIONAL
+}
+
+Additional-Doc-Characteristics ::= SET {
+ unit-scaling [3] IMPLICIT SEQUENCE {a INTEGER,
+ b INTEGER} OPTIONAL,
+ fonts-list [2] IMPLICIT Fonts-List OPTIONAL,
+ colour-characteristics [0] IMPLICIT Colour-Characteristics OPTIONAL,
+ colour-spaces-list [1] IMPLICIT Colour-Spaces-List OPTIONAL,
+ assured-reproduction-areas [5] IMPLICIT Assured-Reproduction-Areas OPTIONAL,
+ time-scaling [6] IMPLICIT Time-Scaling OPTIONAL,
+ document-presentation-time [7] IMPLICIT Document-Presentation-Time OPTIONAL
+}
+
+Fonts-List ::=
+ SET OF SET {font-identifier INTEGER,
+ font-reference Font-Reference}
+
+Font-Reference ::= SET {
+ user-visible-name [0] IMPLICIT Comment-String OPTIONAL,
+ user-readable-comment [1] IMPLICIT Comment-String OPTIONAL,
+ reference-properties
+ [2] IMPLICIT SET OF
+ SET {precedence-number [0] IMPLICIT INTEGER OPTIONAL,
+ properties [1] IMPLICIT Font-Attribute-Set,
+ user-readable-comment
+ [2] IMPLICIT Comment-String OPTIONAL}
+}
+
+Assured-Reproduction-Areas ::=
+ SET OF
+ SET {nominal-page-size [0] IMPLICIT Measure-Pair,
+ assured-reproduction-area
+ [1] SET {position [0] IMPLICIT Measure-Pair,
+ dimensions [1] IMPLICIT Measure-Pair}}
+
+Document-Management-Attributes ::= SET {
+ document-description [7] IMPLICIT Document-Description OPTIONAL,
+ dates-and-times [0] IMPLICIT Dates-and-Times OPTIONAL,
+ originators [1] IMPLICIT Originators OPTIONAL,
+ other-user-information [2] IMPLICIT Other-User-Information OPTIONAL,
+ external-references [3] IMPLICIT External-References OPTIONAL,
+ local-file-references [4] IMPLICIT Local-File-References OPTIONAL,
+ content-attributes [5] IMPLICIT Content-Attributes OPTIONAL,
+ security-information [6] IMPLICIT Security-Information OPTIONAL
+}
+
+Document-Description ::= SET {
+ title [0] IMPLICIT Character-Data OPTIONAL,
+ subject [1] IMPLICIT Character-Data OPTIONAL,
+ document-type [2] IMPLICIT Character-Data OPTIONAL,
+ abstract [3] IMPLICIT Character-Data OPTIONAL,
+ keywords [4] IMPLICIT SET OF Character-Data OPTIONAL,
+ document-reference [5] Document-Reference OPTIONAL
+}
+
+Character-Data ::= [APPLICATION 3] IMPLICIT OCTET STRING
+
+-- string of characters from the sets designated by the attribute
+-- "profile character sets", plus space, carriage return and line feed
+Document-Reference ::= CHOICE {
+ unique-reference OBJECT IDENTIFIER,
+ descriptive-reference Character-Data
+}
+
+Dates-and-Times ::= SET {
+ document-date-and-time [0] IMPLICIT Date-and-Time OPTIONAL,
+ creation-date-and-time [1] IMPLICIT Date-and-Time OPTIONAL,
+ local-filing-date-and-time [2] IMPLICIT SEQUENCE OF Date-and-Time OPTIONAL,
+ expiry-date-and-time [3] IMPLICIT Date-and-Time OPTIONAL,
+ start-date-and-time [4] IMPLICIT Date-and-Time OPTIONAL,
+ purge-date-and-time [5] IMPLICIT Date-and-Time OPTIONAL,
+ release-date-and-time [6] IMPLICIT Date-and-Time OPTIONAL,
+ revision-history
+ [7] IMPLICIT SEQUENCE OF
+ SET {revision-date-and-time
+ [0] IMPLICIT Date-and-Time OPTIONAL,
+ version-identifier
+ [1] IMPLICIT Character-Data OPTIONAL,
+ revisers
+ [2] IMPLICIT SET OF
+ SET {names
+ [0] IMPLICIT SET OF
+ Personal-Name
+ OPTIONAL,
+ position
+ [1] IMPLICIT Character-Data
+ OPTIONAL,
+ organization
+ [2] IMPLICIT Character-Data
+ OPTIONAL} OPTIONAL,
+ version-reference
+ [3] Document-Reference OPTIONAL,
+ user-comments
+ [4] IMPLICIT Character-Data OPTIONAL} OPTIONAL
+}
+
+Date-and-Time ::= [APPLICATION 4] IMPLICIT PrintableString
+
+Originators ::= SET {
+ organizations [0] IMPLICIT SET OF Character-Data OPTIONAL,
+ preparers
+ [1] IMPLICIT SEQUENCE OF
+ SET {personal-name [0] IMPLICIT Personal-Name OPTIONAL,
+ organization [1] IMPLICIT Character-Data OPTIONAL
+ } OPTIONAL,
+ owners
+ [2] IMPLICIT SEQUENCE OF
+ SET {personal-name [0] IMPLICIT Personal-Name OPTIONAL,
+ organization [1] IMPLICIT Character-Data OPTIONAL
+ } OPTIONAL,
+ authors
+ [3] IMPLICIT SEQUENCE OF
+ SET {personal-name [0] IMPLICIT Personal-Name OPTIONAL,
+ organization [1] IMPLICIT Character-Data OPTIONAL
+ } OPTIONAL
+}
+
+Personal-Name ::= [APPLICATION 6] IMPLICIT SET {
+ surname [0] IMPLICIT Character-Data,
+ givenname [1] IMPLICIT Character-Data OPTIONAL,
+ initials [2] IMPLICIT Character-Data OPTIONAL,
+ generation-qualifier [3] IMPLICIT Character-Data OPTIONAL
+}
+
+Other-User-Information ::= SET {
+ copyright
+ [0] IMPLICIT SET OF
+ SET {copyright-information
+ [0] IMPLICIT SET OF Character-Data OPTIONAL,
+ copyright-dates
+ [1] IMPLICIT SET OF Date-and-Time OPTIONAL} OPTIONAL,
+ status [1] IMPLICIT Character-Data OPTIONAL,
+ user-specific-codes [2] IMPLICIT SET OF Character-Data OPTIONAL,
+ distribution-list
+ [3] IMPLICIT SEQUENCE OF
+ SET {personal-name [0] IMPLICIT Personal-Name OPTIONAL,
+ organization [1] IMPLICIT Character-Data OPTIONAL
+ } OPTIONAL,
+ additional-information [5] TYPE-IDENTIFIER.&Type OPTIONAL
+}
+
+External-References ::=
+ SET {
+ references-to-other-documents
+ [0] IMPLICIT SET OF Document-Reference OPTIONAL,
+ superseded-documents
+ [1] IMPLICIT SET OF Document-Reference OPTIONAL
+}
+
+Local-File-References ::=
+ SET OF
+ SET {file-name [0] IMPLICIT Character-Data OPTIONAL,
+ location [1] IMPLICIT Character-Data OPTIONAL,
+ user-comments [2] IMPLICIT Character-Data OPTIONAL}
+
+Content-Attributes ::= SET {
+ document-size [1] IMPLICIT INTEGER OPTIONAL,
+ number-of-pages [2] IMPLICIT INTEGER OPTIONAL,
+ languages [4] IMPLICIT SET OF Character-Data OPTIONAL
+}
+
+Security-Information ::= SET {
+ authorization
+ CHOICE {person [0] IMPLICIT Personal-Name,
+ organization [4] IMPLICIT Character-Data} OPTIONAL,
+ security-classification [1] IMPLICIT Character-Data OPTIONAL,
+ access-rights [2] IMPLICIT SET OF Character-Data OPTIONAL
+}
+
+Document-Security-Attributes ::= SET {
+ sealed-info-encoding [7] IMPLICIT OBJECT IDENTIFIER OPTIONAL,
+ oda-security-label [0] IMPLICIT Oda-Security-Label OPTIONAL,
+ sealed-doc-profiles [1] IMPLICIT Sealed-Doc-Profiles OPTIONAL,
+ presealed-doc-bodyparts [2] IMPLICIT Sealed-Doc-Bodyparts OPTIONAL,
+ postsealed-doc-bodyparts [3] IMPLICIT Sealed-Doc-Bodyparts OPTIONAL,
+ enciphered-doc-profiles [4] IMPLICIT Protected-Doc-Parts OPTIONAL,
+ preenciphered-doc-bodyparts [5] IMPLICIT Protected-Doc-Parts OPTIONAL,
+ postenciphered-doc-bodyparts [6] IMPLICIT Protected-Doc-Parts OPTIONAL,
+ sealed-links [8] IMPLICIT Sealed-Doc-Bodyparts OPTIONAL
+}
+
+Oda-Security-Label ::= SEQUENCE {
+ oda-label-text [0] IMPLICIT Character-Data OPTIONAL,
+ oda-label-data [1] IMPLICIT OCTET STRING OPTIONAL
+}
+
+Seal-Data ::= SEQUENCE {
+ seal-method [0] IMPLICIT Seal-Method OPTIONAL,
+ sealed-information [1] IMPLICIT Sealed-Information OPTIONAL,
+ seal [2] IMPLICIT OCTET STRING
+}
+
+Seal-Method ::= SEQUENCE {
+ fingerprint-method [0] IMPLICIT Method-Information OPTIONAL,
+ fingerprint-key-information [1] IMPLICIT Key-Information OPTIONAL,
+ sealing-method [2] IMPLICIT Method-Information OPTIONAL,
+ sealing-key-information [3] IMPLICIT Key-Information OPTIONAL
+}
+
+Sealed-Information ::= SEQUENCE {
+ fingerprint [0] IMPLICIT OCTET STRING OPTIONAL,
+ time [1] IMPLICIT Date-and-Time OPTIONAL,
+ sealing-orig-id [2] IMPLICIT Personal-Name OPTIONAL,
+ location [3] IMPLICIT Location OPTIONAL
+}
+
+Method-Information ::= SEQUENCE {
+ unique-method-info [0] IMPLICIT OBJECT IDENTIFIER OPTIONAL,
+ descriptive-method-info [1] IMPLICIT Character-Data OPTIONAL
+}
+
+Key-Information ::= SEQUENCE {
+ method-information [0] IMPLICIT Method-Information OPTIONAL,
+ additional-information [1] IMPLICIT Additional-Information OPTIONAL
+}
+
+Additional-Information ::= SEQUENCE {
+ descriptive-information [0] IMPLICIT Character-Data OPTIONAL,
+ octet-string [1] IMPLICIT OCTET STRING OPTIONAL
+}
+
+Location ::= SEQUENCE {
+ unique-location [0] IMPLICIT OBJECT IDENTIFIER OPTIONAL,
+ descriptive-location [1] IMPLICIT Character-Data OPTIONAL
+}
+
+Sealed-Doc-Profiles ::=
+ SET OF
+ SEQUENCE {sealed-doc-prof-descriptor-id
+ [0] IMPLICIT Protected-Part-Identifier,
+ privileged-recipients
+ [1] IMPLICIT SET OF Personal-Name OPTIONAL,
+ doc-prof-seal [2] IMPLICIT Seal-Data}
+
+Sealed-Doc-Bodyparts ::=
+ SET OF
+ SEQUENCE {seal-id [0] IMPLICIT INTEGER,
+ sealed-constituents [1] IMPLICIT Sealed-Constituents,
+ privileged-recipients [2] IMPLICIT SET OF Personal-Name OPTIONAL,
+ doc-bodypart-seal [3] IMPLICIT Seal-Data}
+
+Sealed-Constituents ::= SEQUENCE {
+ object-class-identifiers
+ [0] IMPLICIT SEQUENCE OF Object-or-Class-Identifier OPTIONAL,
+ presentation-style-identifiers
+ [1] IMPLICIT SEQUENCE OF Style-Identifier OPTIONAL,
+ layout-style-identifiers
+ [2] IMPLICIT SEQUENCE OF Style-Identifier OPTIONAL,
+ object-identifiers
+ [3] IMPLICIT SEQUENCE OF Object-or-Class-Identifier OPTIONAL
+}
+
+Protected-Doc-Parts ::=
+ SET OF
+ SEQUENCE {protected-doc-part-id [0] IMPLICIT Protected-Part-Identifier,
+ priv-recipients-info [1] IMPLICIT SET OF Priv-Recipients-Info
+ }
+
+Priv-Recipients-Info ::= SEQUENCE {
+ privileged-recipients [0] IMPLICIT SET OF Personal-Name OPTIONAL,
+ encipherment-method-info [1] IMPLICIT Method-Information OPTIONAL,
+ encipherment-key-info [2] IMPLICIT Key-Information OPTIONAL
+}
+
+END
+
+-- Generated by Asnp, the ASN.1 pretty-printer of France Telecom R&D
+
diff --git a/lib/asn1/test/asn1_SUITE_data/x420/EnhancedSecurity.asn b/lib/asn1/test/asn1_SUITE_data/x420/EnhancedSecurity.asn
new file mode 100644
index 0000000000..9991a59454
--- /dev/null
+++ b/lib/asn1/test/asn1_SUITE_data/x420/EnhancedSecurity.asn
@@ -0,0 +1,363 @@
+-- Module EnhancedSecurity (X.501:08/1997)
+EnhancedSecurity {joint-iso-itu-t ds(5) module(1) enhancedSecurity(28) 1}
+DEFINITIONS IMPLICIT TAGS ::=
+BEGIN
+
+-- EXPORTS All
+IMPORTS
+ -- from ITU-T Rec. X.501 | ISO/IEC 9594-2
+ authenticationFramework, basicAccessControl, certificateExtensions,
+ id-at, id-avc, id-mr, informationFramework, upperBounds
+ FROM UsefulDefinitions {joint-iso-itu-t ds(5) module(1)
+ usefulDefinitions(0) 3}
+ Attribute, ATTRIBUTE, AttributeType, Context, CONTEXT, MATCHING-RULE,
+ Name, objectIdentifierMatch, SupportedAttributes
+ FROM InformationFramework informationFramework
+ AttributeTypeAndValue
+ FROM BasicAccessControl basicAccessControl
+ -- from ITU-T Rec. X.509 | ISO/IEC 9594-8
+ AlgorithmIdentifier, CertificateSerialNumber, ENCRYPTED{}, HASH{},
+ SIGNED{}
+ FROM AuthenticationFramework authenticationFramework
+ GeneralName, KeyIdentifier
+ FROM CertificateExtensions certificateExtensions
+ ub-privacy-mark-length
+ FROM UpperBounds upperBounds;
+
+-- from GULS
+-- SECURITY-TRANSFORMATION, PROTECTION-MAPPING, PROTECTED
+-- FROM Notation { joint-iso-ccitt genericULS (20) modules (1) notation (1) }
+--dirSignedTransformation, KEY-INFORMATION
+-- FROM GulsSecurityTransformations { joint-iso-ccitt genericULS (20) modules (1)
+-- gulsSecurityTransformations (3) }
+-- signed
+-- FROM GulsSecurityTransformations { joint-iso-ccitt genericULS (20) modules (1)
+-- dirProtectionMappings (4) };
+-- The "signed" Protection Mapping and associated "dirSignedTransformations" imported
+-- from the Generic Upper Layers Security specification (ITU-T Rec. X.830 | ISO/IEC 11586-1)
+-- results in identical encoding as the same data type used with the SIGNED as defined in
+-- ITU-T REC. X.509 | ISO/IEC 9594-8
+-- The three statements below are provided temporarily to allow signed operations to be supported as in edition 3.
+OPTIONALLY-PROTECTED{Type} ::= CHOICE {unsigned Type,
+ signed SIGNED{Type}
+}
+
+OPTIONALLY-PROTECTED-SEQ{Type} ::= CHOICE {
+ unsigned Type,
+ signed [0] SIGNED{Type}
+}
+
+-- The following out-commented ASN.1 specification are know to be erroneous and are therefore deprecated.
+-- genEncryptedTransform {KEY-INFORMATION: SupportedKIClasses } SECURITY-TRANSFORMATION ::=
+-- {
+-- IDENTIFIER { enhancedSecurity gen-encrypted(2) }
+-- INITIAL-ENCODING-RULES { joint-iso-itu-t asn1(1) ber(1) }
+-- This default for initial encoding rules may be overridden
+-- using a static protected parameter (initEncRules).
+-- XFORMED-DATA-TYPE SEQUENCE {
+-- initEncRules OBJECT IDENTIFIER DEFAULT { joint-iso-itu-t asn1(1) ber(1) },
+-- encAlgorithm AlgorithmIdentifier OPTIONAL, -- -- Identifies the encryption algorithm,
+-- keyInformation SEQUENCE {
+-- kiClass KEY-INFORMATION.&kiClass ({SupportedKIClasses}),
+-- keyInfo KEY-INFORMATION.&KiType ({SupportedKIClasses} {@kiClass})
+-- } OPTIONAL,
+-- Key information may assume various formats, governed by supported members
+-- of the KEY-INFORMATION information object class (defined in ITU-T
+-- Rec. X.830 | ISO/IEC 11586-1)
+-- encData BIT STRING ( CONSTRAINED BY {
+-- the encData value must be generated following
+-- the procedure specified in 17.3.1-- -- })
+-- }
+-- }
+-- encrypted PROTECTION-MAPPING ::= {
+-- SECURITY-TRANSFORMATION { genEncryptedTransform } }
+-- signedAndEncrypt PROTECTION-MAPPING ::= {
+-- SECURITY-TRANSFORMATION { signedAndEncryptedTransform } }
+-- signedAndEncryptedTransform {KEY-INFORMATION: SupportedKIClasses}
+-- SECURITY-TRANSFORMATION ::= {
+-- IDENTIFIER { enhancedSecurity dir-encrypt-sign (1) }
+-- INITIAL-ENCODING-RULES { joint-iso-itu-t asn1 (1) ber-derived (2) distinguished-encoding (1) }
+-- XFORMED-DATA-TYPE
+-- PROTECTED
+-- {
+-- PROTECTED
+-- {
+-- ABSTRACT-SYNTAX.&Type,
+-- signed
+-- },
+-- encrypted
+-- }
+-- }
+-- OPTIONALLY-PROTECTED {ToBeProtected, PROTECTION-MAPPING:generalProtection} ::=
+-- CHOICE {
+-- toBeProtected ToBeProtected,
+--no DIRQOP specified for operation
+-- signed PROTECTED {ToBeProtected, signed},
+--DIRQOP is Signed
+-- protected [APPLICATION 0]
+-- PROTECTED { ToBeProtected, generalProtection } }
+--DIRQOP is other than Signed
+-- defaultDirQop ATTRIBUTE ::= {
+-- WITH SYNTAX OBJECT IDENTIFIER
+-- EQUALITY MATCHING RULE objectIdentifierMatch
+-- USAGE directoryOperation
+-- ID id-at-defaultDirQop }
+-- DIRQOP ::= CLASS
+-- This information object class is used to define the quality of protection
+-- required throughout directory operation.
+-- The Quality Of Protection can be signed, encrypted, signedAndEncrypt
+-- {
+-- &dirqop-Id OBJECT IDENTIFIER UNIQUE,
+-- &dirBindError-QOP PROTECTION-MAPPING:protectionReqd,
+-- &dirErrors-QOP PROTECTION-MAPPING:protectionReqd,
+-- &dapReadArg-QOP PROTECTION-MAPPING:protectionReqd,
+-- &dapReadRes-QOP PROTECTION-MAPPING:protectionReqd,
+-- &dapCompareArg-QOP PROTECTION-MAPPING:protectionReqd,
+-- &dapCompareRes-QOP PROTECTION-MAPPING:protectionReqd,
+-- &dapListArg-QOP PROTECTION-MAPPING:protectionReqd,
+-- &dapListRes-QOP PROTECTION-MAPPING:protectionReqd,
+-- &dapSearchArg-QOP PROTECTION-MAPPING:protectionReqd,
+-- &dapSearchRes-QOP PROTECTION-MAPPING:protectionReqd,
+-- &dapAbandonArg-QOP PROTECTION-MAPPING:protectionReqd,
+-- &dapAbandonRes-QOP PROTECTION-MAPPING:protectionReqd,
+-- &dapAddEntryArg-QOP PROTECTION-MAPPING:protectionReqd,
+-- &dapAddEntryRes-QOP PROTECTION-MAPPING:protectionReqd,
+-- &dapRemoveEntryArg-QOP PROTECTION-MAPPING:protectionReqd,
+-- &dapRemoveEntryRes-QOP PROTECTION-MAPPING:protectionReqd,
+-- &dapModifyEntryArg-QOP PROTECTION-MAPPING:protectionReqd,
+-- &dapModifyEntryRes-QOP PROTECTION-MAPPING:protectionReqd,
+-- &dapModifyDNArg-QOP PROTECTION-MAPPING:protectionReqd,
+-- &dapModifyDNRes-QOP PROTECTION-MAPPING:protectionReqd,
+-- &dspChainedOp-QOP PROTECTION-MAPPING:protectionReqd,
+-- &dispShadowAgreeInfo-QOP PROTECTION-MAPPING:protectionReqd,
+-- &dispCoorShadowArg-QOP PROTECTION-MAPPING:protectionReqd,
+-- &dispCoorShadowRes-QOP PROTECTION-MAPPING:protectionReqd,
+-- &dispUpdateShadowArg-QOP PROTECTION-MAPPING:protectionReqd,
+-- &dispUpdateShadowRes-QOP PROTECTION-MAPPING:protectionReqd,
+-- &dispRequestShadowUpdateArg-QOP PROTECTION-MAPPING:protectionReqd,
+-- &dispRequestShadowUpdateRes-QOP PROTECTION-MAPPING:protectionReqd,
+-- &dopEstablishOpBindArg-QOP PROTECTION-MAPPING:protectionReqd,
+-- &dopEstablishOpBindRes-QOP PROTECTION-MAPPING:protectionReqd,
+-- &dopModifyOpBindArg-QOP PROTECTION-MAPPING:protectionReqd,
+-- &dopModifyOpBindRes-QOP PROTECTION-MAPPING:protectionReqd,
+-- &dopTermOpBindArg-QOP PROTECTION-MAPPING:protectionReqd,
+-- &dopTermOpBindRes-QOP PROTECTION-MAPPING:protectionReqd
+-- }
+-- WITH SYNTAX
+-- {
+-- DIRQOP-ID &dirqop-Id
+-- DIRECTORYBINDERROR-QOP &dirBindError-QOP
+-- DIRERRORS-QOP &dirErrors-QOP
+-- DAPREADARG-QOP &dapReadArg-QOP
+-- DAPREADRES-QOP &dapReadRes-QOP
+-- DAPCOMPAREARG-QOP &dapCompareArg-QOP
+-- DAPCOMPARERES-QOP &dapCompareRes-QOP
+-- DAPLISTARG-QOP &dapListArg-QOP
+-- DAPLISTRES-QOP &dapListRes-QOP
+-- DAPSEARCHARG-QOP &dapSearchArg-QOP
+-- DAPSEARCHRES-QOP &dapSearchRes-QOP
+-- DAPABANDONARG-QOP &dapAbandonArg-QOP
+-- DAPABANDONRES-QOP &dapAbandonRes-QOP
+-- DAPADDENTRYARG-QOP &dapAddEntryArg-QOP
+-- DAPADDENTRYRES-QOP &dapAddEntryRes-QOP
+-- DAPREMOVEENTRYARG-QOP &dapRemoveEntryArg-QOP
+-- DAPREMOVEENTRYRES-QOP &dapRemoveEntryRes-QOP
+-- DAPMODIFYENTRYARG-QOP &dapModifyEntryArg-QOP
+-- DAPMODIFYENTRYRES-QOP &dapModifyEntryRes-QOP
+-- DAPMODIFYDNARG-QOP &dapModifyDNArg-QOP
+-- DAPMODIFYDNRES-QOP &dapModifyDNRes-QOP
+-- DSPCHAINEDOP-QOP &dspChainedOp-QOP
+-- DISPSHADOWAGREEINFO-QOP &dispShadowAgreeInfo-QOP
+-- DISPCOORSHADOWARG-QOP &dispCoorShadowArg-QOP
+-- DISPCOORSHADOWRES-QOP &dispCoorShadowRes-QOP
+-- DISPUPDATESHADOWARG-QOP &dispUpdateShadowArg-QOP
+-- DISPUPDATESHADOWRES-QOP &dispUpdateShadowRes-QOP
+-- DISPREQUESTSHADOWUPDATEARG-QOP &dispRequestShadowUpdateArg-QOP
+-- DISPREQUESTSHADOWUPDATERES-QOP &dispRequestShadowUpdateRes-QOP
+-- DOPESTABLISHOPBINDARG-QOP &dopEstablishOpBindArg-QOP
+-- DOPESTABLISHOPBINDRES-QOP &dopEstablishOpBindRes-QOP
+-- DOPMODIFYOPBINDARG-QOP &dopModifyOpBindArg-QOP
+-- DOPMODIFYOPBINDRES-QOP &dopModifyOpBindRes-QOP
+-- DOPTERMINATEOPBINDARG-QOP &dopTermOpBindArg-QOP
+-- DOPTERMINATEOPBINDRES-QOP &dopTermOpBindRes-QOP
+-- }
+attributeValueSecurityLabelContext CONTEXT ::= {
+ WITH SYNTAX
+ SignedSecurityLabel -- At most one security label context can be assigned to an
+ -- attribute value
+ ID id-avc-attributeValueSecurityLabelContext
+}
+
+SignedSecurityLabel ::=
+ SIGNED
+ {SEQUENCE {attHash HASH{AttributeTypeAndValue},
+ issuer Name OPTIONAL, -- name of labelling authority
+ keyIdentifier KeyIdentifier OPTIONAL,
+ securityLabel SecurityLabel}}
+
+SecurityLabel ::= SET {
+ security-policy-identifier SecurityPolicyIdentifier OPTIONAL,
+ security-classification SecurityClassification OPTIONAL,
+ privacy-mark PrivacyMark OPTIONAL,
+ security-categories SecurityCategories OPTIONAL
+}(ALL EXCEPT ({ --none, at least one component shall be presen--}))
+
+SecurityPolicyIdentifier ::= OBJECT IDENTIFIER
+
+SecurityClassification ::= INTEGER {
+ unmarked(0), unclassified(1), restricted(2), confidential(3), secret(4),
+ top-secret(5)}
+
+PrivacyMark ::= PrintableString(SIZE (1..ub-privacy-mark-length))
+
+SecurityCategories ::= SET SIZE (1..MAX) OF SecurityCategory
+
+clearance ATTRIBUTE ::= {WITH SYNTAX Clearance
+ ID id-at-clearance
+}
+
+Clearance ::= SEQUENCE {
+ policyId OBJECT IDENTIFIER,
+ classList ClassList DEFAULT {unclassified},
+ securityCategories SET SIZE (1..MAX) OF SecurityCategory OPTIONAL
+}
+
+ClassList ::= BIT STRING {
+ unmarked(0), unclassified(1), restricted(2), confidential(3), secret(4),
+ topSecret(5)}
+
+SecurityCategory ::= SEQUENCE {
+ type [0] SECURITY-CATEGORY.&id({SecurityCategoriesTable}),
+ value [1] EXPLICIT SECURITY-CATEGORY.&Type({SecurityCategoriesTable}{@type})
+}
+
+SECURITY-CATEGORY ::= TYPE-IDENTIFIER
+
+SecurityCategoriesTable SECURITY-CATEGORY ::=
+ {...}
+
+attributeIntegrityInfo ATTRIBUTE ::= {
+ WITH SYNTAX AttributeIntegrityInfo
+ ID id-at-attributeIntegrityInfo
+}
+
+AttributeIntegrityInfo ::=
+ SIGNED
+ {SEQUENCE {scope Scope, -- Identifies the attributes protected
+ signer Signer OPTIONAL, -- Authority or data originators name
+ attribsHash AttribsHash}} -- Hash value of protected attributes
+
+Signer ::= CHOICE {
+ thisEntry [0] EXPLICIT ThisEntry,
+ thirdParty [1] SpecificallyIdentified
+}
+
+ThisEntry ::= CHOICE {onlyOne NULL,
+ specific IssuerAndSerialNumber
+}
+
+IssuerAndSerialNumber ::= SEQUENCE {
+ issuer Name,
+ serial CertificateSerialNumber
+}
+
+SpecificallyIdentified ::= SEQUENCE {
+ name GeneralName,
+ issuer GeneralName OPTIONAL,
+ serial CertificateSerialNumber OPTIONAL
+}
+(WITH COMPONENTS {
+ ...,
+ issuer PRESENT,
+ serial PRESENT
+ } | (WITH COMPONENTS {
+ ...,
+ issuer ABSENT,
+ serial ABSENT
+ }))
+
+Scope ::= CHOICE {
+ wholeEntry [0] NULL, -- Signature protects all attribute values in this entry
+ selectedTypes [1] SelectedTypes
+ -- Signature protects all attribute values of the selected attribute types
+}
+
+SelectedTypes ::= SEQUENCE SIZE (1..MAX) OF AttributeType
+
+AttribsHash ::= HASH{SEQUENCE SIZE (1..MAX) OF Attribute}
+
+-- Attribute type and values with associated context values for the selected Scope
+attributeValueIntegrityInfoContext CONTEXT ::= {
+ WITH SYNTAX AttributeValueIntegrityInfo
+ ID id-avc-attributeValueIntegrityInfoContext
+}
+
+AttributeValueIntegrityInfo ::=
+ SIGNED
+ {SEQUENCE {signer Signer OPTIONAL, -- Authority or data originators name
+ aVIHash AVIHash}} -- Hash value of protected attribute
+
+AVIHash ::= HASH{AttributeTypeValueContexts}
+
+-- Attribute type and value with associated context values
+AttributeTypeValueContexts ::= SEQUENCE {
+ type ATTRIBUTE.&id({SupportedAttributes}),
+ value ATTRIBUTE.&Type({SupportedAttributes}{@type}),
+ contextList SET SIZE (1..MAX) OF Context OPTIONAL
+}
+
+-- The following out-commented ASN.1 specification are know to be erroneous and are therefore deprecated.
+-- EncryptedAttributeSyntax {AttributeSyntax} ::= SEQUENCE {
+-- keyInfo SEQUENCE OF KeyIdOrProtectedKey,
+-- encAlg AlgorithmIdentifier,
+-- encValue ENCRYPTED { AttributeSyntax } }
+-- KeyIdOrProtectedKey ::= SEQUENCE {
+-- keyIdentifier [0] KeyIdentifier OPTIONAL,
+-- protectedKeys [1] ProtectedKey OPTIONAL }
+-- At least one key identifier or protected key must be present
+-- ProtectedKey ::= SEQUENCE {
+-- authReaders AuthReaders,-- -- if absent, use attribute in authorized reader entry
+-- keyEncAlg AlgorithmIdentifier OPTIONAL, -- -- algorithm to encrypt encAttrKey
+-- encAttKey EncAttKey }
+-- confidentiality key protected with authorized user's
+-- protection mechanism
+-- AuthReaders ::= SEQUENCE OF Name
+-- EncAttKey ::= PROTECTED {SymmetricKey, keyProtection}
+-- SymmetricKey ::= BIT STRING
+-- keyProtection PROTECTION-MAPPING ::= {
+-- SECURITY-TRANSFORMATION {genEncryption} }
+-- confKeyInfo ATTRIBUTE ::= {
+-- WITH SYNTAX ConfKeyInfo
+-- EQUALITY MATCHING RULE readerAndKeyIDMatch
+-- ID id-at-confKeyInfo }
+-- ConfKeyInfo ::= SEQUENCE {
+-- keyIdentifier KeyIdentifier,
+-- protectedKey ProtectedKey }
+-- readerAndKeyIDMatch MATCHING-RULE ::= {
+-- SYNTAX ReaderAndKeyIDAssertion
+-- ID id-mr-readerAndKeyIDMatch }
+-- ReaderAndKeyIDAssertion ::= SEQUENCE {
+-- keyIdentifier KeyIdentifier,
+-- authReaders AuthReaders OPTIONAL }
+-- Object identifier assignments
+-- attributes
+id-at-clearance OBJECT IDENTIFIER ::=
+ {id-at 55}
+
+-- id-at-defaultDirQop OBJECT IDENTIFIER ::= {id-at 56}
+id-at-attributeIntegrityInfo OBJECT IDENTIFIER ::=
+ {id-at 57}
+
+-- id-at-confKeyInfo OBJECT IDENTIFIER ::= {id-at 60}
+-- matching rules
+-- id-mr-readerAndKeyIDMatch OBJECT IDENTIFIER ::= {id-mr 43}
+-- contexts
+id-avc-attributeValueSecurityLabelContext OBJECT IDENTIFIER ::=
+ {id-avc 3}
+
+id-avc-attributeValueIntegrityInfoContext OBJECT IDENTIFIER ::= {id-avc 4}
+
+END -- EnhancedSecurity
+
+-- Generated by Asnp, the ASN.1 pretty-printer of France Telecom R&D
+
diff --git a/lib/asn1/test/asn1_SUITE_data/x420/External-References.asn b/lib/asn1/test/asn1_SUITE_data/x420/External-References.asn
new file mode 100644
index 0000000000..9a7d4936a6
--- /dev/null
+++ b/lib/asn1/test/asn1_SUITE_data/x420/External-References.asn
@@ -0,0 +1,49 @@
+-- Module External-References (T.422:08/1995)
+
+External-References {2 8 1 12 1} DEFINITIONS IMPLICIT TAGS ::=
+BEGIN
+
+EXPORTS External-References-List, Reference-Name;
+
+IMPORTS
+ Location-Expression
+ FROM Location-Expressions {2 8 1 12 0}
+ -- see 7.4
+ DOR
+ FROM DOR-definition {2 4 0}
+ -- see ISO/IEC 10031-2
+ DistinguishedName
+ FROM InformationFramework {joint-iso-itu-t ds(5) module(1)
+ informationFramework(1) 3};
+
+-- see ITU-T Rec. X.501 � ISO/IEC 9594-2
+External-References-List ::=
+ SET OF
+ SET {reference-name [1] Reference-Name,
+ external-entity [2] External-Entity,
+ location-rule [3] Location-Expression OPTIONAL}
+
+Reference-Name ::= PrintableString
+
+External-Entity ::= CHOICE {
+ external-info [0] External-Information-Name,
+ object-id [1] OBJECT IDENTIFIER,
+ dor [2] DOR,
+ distinguished [3] DistinguishedName,
+ associated-info [4] Associated-Information-Name
+}
+
+External-Information-Name ::= SEQUENCE {
+ string [0] PrintableString,
+ object-id [1] OBJECT IDENTIFIER OPTIONAL
+}
+
+Associated-Information-Name ::= SEQUENCE {
+ string [0] PrintableString,
+ object-id [1] OBJECT IDENTIFIER OPTIONAL
+}
+
+END
+
+-- Generated by Asnp, the ASN.1 pretty-printer of France Telecom R&D
+
diff --git a/lib/asn1/test/asn1_SUITE_data/x420/GULSProtectionMappings.asn b/lib/asn1/test/asn1_SUITE_data/x420/GULSProtectionMappings.asn
new file mode 100644
index 0000000000..9b6a426ca2
--- /dev/null
+++ b/lib/asn1/test/asn1_SUITE_data/x420/GULSProtectionMappings.asn
@@ -0,0 +1,71 @@
+-- Module GULSProtectionMappings (X.830:04/1995)
+
+GULSProtectionMappings {joint-iso-itu-t genericULS(20) modules(1)
+ gulsProtectionMappings(5)} DEFINITIONS AUTOMATIC TAGS ::=
+BEGIN
+
+-- These protection mappings are more versatile that the
+-- preceding protection mappings which were specifically designed
+-- to generate identical bit-encodings as the Directory
+-- Authentication Framework parameterized types.
+-- EXPORTS All
+IMPORTS
+ notation, gulsSecurityTransformations
+ FROM ObjectIdentifiers {joint-iso-itu-t genericULS(20) modules(1)
+ objectIdentifiers(0)}
+ PROTECTION-MAPPING
+ FROM Notation notation
+ dirEncryptedTransformation, gulsSignedTransformation{},
+ gulsSignatureTransformation, symmetricKeyInformation,
+ asymmetricKeyInformation
+ FROM GulsSecurityTransformations gulsSecurityTransformations;
+
+-- **********************************
+-- confidentiality Protection Mapping
+-- **********************************
+-- This protection mapping enables the notation
+-- PROTECTED {BaseType, confidentiality}
+-- to map to either dirEncryptedTransformation or to no transformation
+-- at the choice of the encoding system, dependent upon local security
+-- policy and other local environment considerations.
+-- Security Service: confidentiality
+confidentiality PROTECTION-MAPPING ::= {
+ SECURITY-TRANSFORMATION {dirEncryptedTransformation}
+ BYPASS-PERMITTED TRUE
+}
+
+-- ******************************
+-- GULS signed Protection Mapping
+-- ******************************
+-- This protection mapping causes the notation
+-- PROTECTED {BaseType, signed}
+-- to map to the gulsSignedTransformation.
+-- Security Service: data origin authentication, data integrity and
+-- (in certain situations) non-repudiation.
+signed PROTECTION-MAPPING ::= {
+ SECURITY-TRANSFORMATION
+ {gulsSignedTransformation
+ {{symmetricKeyInformation | asymmetricKeyInformation}}}
+}
+
+-- *********************************
+-- GULS signature Protection Mapping
+-- *********************************
+-- This protection mapping causes the notation
+-- PROTECTED {BaseType, signature}
+-- to map to the gulsSignatureTransformation.
+-- Security Service: data origin authentication, data integrity and
+-- (in certain situations) non-repudiation.
+signature PROTECTION-MAPPING ::= {
+ SECURITY-TRANSFORMATION
+ {gulsSignatureTransformation
+ {{symmetricKeyInformation | asymmetricKeyInformation}}}
+}
+
+END
+
+-- Generated by Asnp, the ASN.1 pretty-printer of France Telecom R&D
+
+
+-- content of stack:
+--
diff --git a/lib/asn1/test/asn1_SUITE_data/x420/GenericProtectingTransferSyntax.asn b/lib/asn1/test/asn1_SUITE_data/x420/GenericProtectingTransferSyntax.asn
new file mode 100644
index 0000000000..c59451dcdb
--- /dev/null
+++ b/lib/asn1/test/asn1_SUITE_data/x420/GenericProtectingTransferSyntax.asn
@@ -0,0 +1,66 @@
+-- Module GenericProtectingTransferSyntax (X.833:04/1995)
+
+GenericProtectingTransferSyntax {joint-iso-itu-t genericULS(20) modules(1)
+ genericProtectingTransferSyntax(7)} DEFINITIONS AUTOMATIC TAGS ::=
+BEGIN
+
+EXPORTS SyntaxStructure{};
+
+IMPORTS
+ notation
+ FROM ObjectIdentifiers {joint-iso-itu-t genericULS(20) modules(1)
+ objectIdentifiers(0)}
+ SECURITY-TRANSFORMATION, ExternalSAID
+ FROM Notation notation;
+
+SyntaxStructure{SECURITY-TRANSFORMATION:ValidSTs} ::= CHOICE {
+ firstPdvExplicit FirstPdvExplicit{{ValidSTs}},
+ -- To be used on the first PDV of a protecting presentation
+ -- context, or a protected PDV sent outside a presentation
+ -- context, in the case of a presentation-context-bound or
+ -- single-item-bound security association.
+ firstPdvExternal FirstPdvExternal{{ValidSTs}},
+ -- To be used on the first PDV of a protecting presentation
+ -- context, or a protected PDV sent outside a presentation
+ -- context, in the case of an externally established
+ -- security association.
+ subsequentPdv SubsequentPdv{{ValidSTs}}
+ -- To be used on a subsequent PDV in a protecting
+ -- presentation context.
+}
+
+FirstPdvExplicit{SECURITY-TRANSFORMATION:ValidSTs} ::= SEQUENCE {
+ transformationId SECURITY-TRANSFORMATION.&sT-Identifier({ValidSTs}),
+ staticUnprotParm
+ SECURITY-TRANSFORMATION.&StaticUnprotectedParm
+ ({ValidSTs}{@transformationId}) OPTIONAL,
+ dynamicUnprotParm
+ SECURITY-TRANSFORMATION.&DynamicUnprotectedParm
+ ({ValidSTs}{@transformationId}) OPTIONAL,
+ xformedData
+ SECURITY-TRANSFORMATION.&XformedDataType({ValidSTs}{@transformationId})
+}
+
+FirstPdvExternal{SECURITY-TRANSFORMATION:ValidSTs} ::= SEQUENCE {
+ externalSAID ExternalSAID,
+ dynamicUnprotParm
+ SECURITY-TRANSFORMATION.&DynamicUnprotectedParm({ValidSTs}) OPTIONAL,
+ -- Actual member of ValidSTs is as implied
+ -- by externalSAID
+ xformedData SECURITY-TRANSFORMATION.&XformedDataType({ValidSTs})
+ -- Actual member of ValidSTs is as implied
+ -- by externalSAID
+}
+
+SubsequentPdv{SECURITY-TRANSFORMATION:ValidSTs} ::= SEQUENCE {
+ dynamicUnprotParm
+ SECURITY-TRANSFORMATION.&DynamicUnprotectedParm({ValidSTs}) OPTIONAL,
+ xformedData SECURITY-TRANSFORMATION.&XformedDataType({ValidSTs})
+ -- Actual member of ValidSTs is implied
+ -- by presentation context
+}
+
+END
+
+-- Generated by Asnp, the ASN.1 pretty-printer of France Telecom R&D
+
diff --git a/lib/asn1/test/asn1_SUITE_data/x420/Geo-Gr-Coding-Attributes.asn b/lib/asn1/test/asn1_SUITE_data/x420/Geo-Gr-Coding-Attributes.asn
new file mode 100644
index 0000000000..60acbb3b5c
--- /dev/null
+++ b/lib/asn1/test/asn1_SUITE_data/x420/Geo-Gr-Coding-Attributes.asn
@@ -0,0 +1,16 @@
+-- Module Geo-Gr-Coding-Attributes (T.418:03/1993)
+
+Geo-Gr-Coding-Attributes {2 8 1 8 3} DEFINITIONS ::=
+BEGIN
+
+EXPORTS Geo-Gr-Coding-Attributes;
+
+Geo-Gr-Coding-Attributes ::= SET {
+}
+
+-- no geometric graphics coding attributes are defined
+-- in this Specification
+END
+
+-- Generated by Asnp, the ASN.1 pretty-printer of France Telecom R&D
+
diff --git a/lib/asn1/test/asn1_SUITE_data/x420/Geo-Gr-Presentation-Attributes.asn b/lib/asn1/test/asn1_SUITE_data/x420/Geo-Gr-Presentation-Attributes.asn
new file mode 100644
index 0000000000..84c1ee9851
--- /dev/null
+++ b/lib/asn1/test/asn1_SUITE_data/x420/Geo-Gr-Presentation-Attributes.asn
@@ -0,0 +1,265 @@
+-- Module Geo-Gr-Presentation-Attributes (T.418:03/1993)
+
+Geo-Gr-Presentation-Attributes {2 8 1 8 2} DEFINITIONS IMPLICIT TAGS ::=
+BEGIN
+
+EXPORTS
+ Geometric-Graphics-Attributes, Line-Rendition, Marker-Rendition,
+ Text-Rendition, Filled-Area-Rendition, Edge-Rendition,
+ Colour-Representations, Transparency-Specification,
+ Transformation-Specification, Region-Of-Interest-Specification,
+ Picture-Orientation, Picture-Dimensions, ASF-Type, VDC-Pair,
+ One-Of-Four-Angles;
+
+Geometric-Graphics-Attributes ::= SET {
+ line-rendition [1] Line-Rendition OPTIONAL,
+ marker-rendition [2] Marker-Rendition OPTIONAL,
+ text-rendition [3] Text-Rendition OPTIONAL,
+ filled-area-rendition [4] Filled-Area-Rendition OPTIONAL,
+ edge-rendition [5] Edge-Rendition OPTIONAL,
+ colour-representations [6] Colour-Representations OPTIONAL,
+ transparency-specification [7] Transparency-Specification OPTIONAL,
+ transformation-specification [8] Transformation-Specification OPTIONAL,
+ region-of-interest-specification
+ [9] Region-Of-Interest-Specification OPTIONAL,
+ picture-orientation [10] Picture-Orientation OPTIONAL,
+ picture-dimensions [11] Picture-Dimensions OPTIONAL
+}
+
+ASF-Type ::= ENUMERATED {bundled(0), individual(1)}
+
+Colour ::= CHOICE {indexed [0] INTEGER,
+ direct [1] RGB
+}
+
+RGB ::= SEQUENCE {red REAL,
+ green REAL,
+ blue REAL
+}
+
+SpecificationMode ::= ENUMERATED {absolute(0), scaled(1)}
+
+Line-Rendition ::= SEQUENCE {
+ line-width-specification-mode [0] SpecificationMode OPTIONAL,
+ line-bundle-index [1] INTEGER OPTIONAL,
+ line-type [2] INTEGER OPTIONAL,
+ line-width [3] Scaled-or-Absolute OPTIONAL,
+ line-colour [4] Colour OPTIONAL,
+ line-aspect-source-flags
+ [5] SEQUENCE {line-type-asf ASF-Type,
+ line-width-asf ASF-Type,
+ line-colour-asf ASF-Type} OPTIONAL,
+ line-bundle-specifications
+ [6] SEQUENCE OF
+ SEQUENCE {line-bundle-index INTEGER,
+ line-bundle-representation
+ SEQUENCE {line-type INTEGER,
+ line-width Scaled-or-Absolute,
+ line-colour Colour}} OPTIONAL
+}
+
+Scaled-or-Absolute ::= CHOICE {
+ absolute
+ [0] CHOICE { -- absolute--vdc-int [0] INTEGER, -- for VDC Type INTEGER--
+ vdc-real [1] REAL}, -- for VDC Type REAL
+ scaled [1] REAL
+} -- scaled
+
+Marker-Rendition ::= SEQUENCE {
+ marker-size-specification-mode [0] SpecificationMode OPTIONAL,
+ marker-bundle-index [1] INTEGER OPTIONAL,
+ marker-type [2] INTEGER OPTIONAL,
+ marker-size [3] Scaled-or-Absolute OPTIONAL,
+ marker-colour [4] Colour OPTIONAL,
+ marker-aspect-source-flags
+ [5] SEQUENCE {marker-type-asf ASF-Type,
+ marker-size-asf ASF-Type,
+ marker-colour-asf ASF-Type} OPTIONAL,
+ marker-bundle-specifications
+ [6] SEQUENCE OF
+ SEQUENCE {marker-bundle-index INTEGER,
+ marker-bundle-representation
+ SEQUENCE {marker-type INTEGER,
+ marker-size Scaled-or-Absolute,
+ marker-colour Colour}} OPTIONAL
+}
+
+Text-Rendition ::= SEQUENCE {
+ font-list [0] SEQUENCE OF GeneralString OPTIONAL,
+ character-set-list
+ [1] SEQUENCE {character-set-type
+ ENUMERATED {n94-char-sets(0), n96-char-sets(1),
+ n94-char-multibyte-sets(2),
+ n96-char-multibyte-sets(3), comp-code(4)},
+ designation-sequence-tail GeneralString} OPTIONAL,
+ character-coding-announcer
+ [2] ENUMERATED {basic-7-bit(0), basic-8-bit(1), extended-7-bit(2),
+ extended-8-bit(3)} OPTIONAL,
+ text-bundle-index [3] INTEGER OPTIONAL,
+ text-font-index [4] INTEGER OPTIONAL,
+ text-precision
+ [5] ENUMERATED {string(0), character(1), stroke(2)} OPTIONAL,
+ character-expansion-factor [6] REAL OPTIONAL,
+ character-spacing [7] REAL OPTIONAL,
+ text-colour [8] Colour OPTIONAL,
+ character-height [9] VDC-Value OPTIONAL,
+ character-orientation [10] SEQUENCE {a VDC-Pair,
+ b VDC-Pair} OPTIONAL,
+ text-path
+ [11] ENUMERATED {right(0), left(1), up(2), down(3)} OPTIONAL,
+ text-alignment
+ [12] SEQUENCE {horizontal-alignment
+ ENUMERATED {normal-horizontal(0), left(1), centre(2),
+ right(3), continuous-horizontal(4)},
+ vertical-alignment
+ ENUMERATED {normal-vertical(0), top(1), cap(2),
+ half(3), base(4), bottom(5),
+ continuous-vertical(6)},
+ continuous-horizontal-alignment [0] REAL OPTIONAL,
+ continuous-vertical-alignment [1] REAL OPTIONAL
+ } OPTIONAL,
+ character-set-index [13] INTEGER OPTIONAL,
+ alternate-character-set-index [14] INTEGER OPTIONAL,
+ text-aspect-source-flags
+ [15] SEQUENCE {text-font-asf ASF-Type,
+ text-precision-asf ASF-Type,
+ character-expansion-factor-asf ASF-Type,
+ character-spacing-asf ASF-Type,
+ text-colour-asf ASF-Type} OPTIONAL,
+ text-bundle-specifications
+ [16] SEQUENCE OF
+ SEQUENCE {text-bundle-index INTEGER,
+ text-bundle-representation
+ SEQUENCE {text-font-index INTEGER,
+ text-precision
+ ENUMERATED {string(0), character(1),
+ stroke(2)},
+ character-expansion-factor REAL,
+ character-spacing REAL,
+ text-colour Colour}
+ } OPTIONAL
+}
+
+VDC-Value ::= CHOICE {a INTEGER,
+ b REAL
+}
+
+VDC-Pair ::= SEQUENCE {x VDC-Value,
+ y VDC-Value
+}
+
+Filled-Area-Rendition ::= SEQUENCE {
+ fill-bundle-index [1] INTEGER OPTIONAL,
+ interior-style
+ [2] ENUMERATED {hollow(0), solid(1), pattern(2), hatch(3), empty(4)}
+ OPTIONAL,
+ fill-colour [3] Colour OPTIONAL,
+ hatch-index [4] INTEGER OPTIONAL,
+ pattern-index [5] INTEGER OPTIONAL,
+ fill-reference-point [6] VDC-Pair OPTIONAL,
+ pattern-size
+ [7] SEQUENCE {height-x-component VDC-Value,
+ height-y-component VDC-Value,
+ width-x-component VDC-Value,
+ width-y-component VDC-Value} OPTIONAL,
+ pattern-table-specifications [8] SEQUENCE OF PatternTableElement OPTIONAL,
+ fill-aspect-source-flags
+ [9] SEQUENCE {interior-style-asf ASF-Type,
+ fill-colour-asf ASF-Type,
+ hatch-index-asf ASF-Type,
+ pattern-index-asf ASF-Type} OPTIONAL,
+ fill-bundle-specifications
+ [10] SEQUENCE {fill-bundle-index INTEGER,
+ fill-bundle-representation
+ SEQUENCE {interior-style
+ ENUMERATED {hollow(0), solid(1), pattern(2),
+ hatch(3), empty(4)},
+ fill-colour Colour,
+ hatch-index INTEGER,
+ patttern-index INTEGER}} OPTIONAL
+}
+
+PatternTableElement ::= SEQUENCE {
+ pattern-table-index INTEGER,
+ nx INTEGER,
+ ny INTEGER,
+ local-colour-precision INTEGER,
+ colour SEQUENCE OF Colour
+}
+
+Edge-Rendition ::= SEQUENCE {
+ edge-width-spec-mode [0] SpecificationMode OPTIONAL,
+ edge-visibility [1] On-or-Off OPTIONAL,
+ edge-bundle-index [2] INTEGER OPTIONAL,
+ edge-type [3] INTEGER OPTIONAL,
+ edge-width [4] Scaled-or-Absolute OPTIONAL,
+ edge-colour [5] Colour OPTIONAL,
+ edge-aspect-source-flags
+ [6] SEQUENCE {edge-type-asf ASF-Type,
+ edge-width-asf ASF-Type,
+ edge-colour-asf ASF-Type} OPTIONAL,
+ edge-bundle-specifications
+ [7] SEQUENCE OF
+ SEQUENCE {edge-bundle-index INTEGER,
+ edge-bundle-representation
+ SEQUENCE {edge-type INTEGER,
+ edge-width Scaled-or-Absolute,
+ edge-colour Colour}} OPTIONAL
+}
+
+On-or-Off ::= ENUMERATED {off(0), on(1)}
+
+Colour-Representations ::= SEQUENCE {
+ background-colour [0] RGB OPTIONAL,
+ colour-table-specification
+ [1] SEQUENCE OF
+ SEQUENCE {starting-index INTEGER,
+ colour-list SEQUENCE OF RGB} OPTIONAL
+}
+
+Transparency-Specification ::= SEQUENCE {
+ transparency [0] On-or-Off OPTIONAL,
+ auxiliary-colour [1] Colour OPTIONAL
+}
+
+Transformation-Specification ::= SEQUENCE {
+ vdc-extent [0] Rectangle OPTIONAL,
+ clip-rectangle [1] Rectangle OPTIONAL,
+ clip-indicator [2] On-or-Off OPTIONAL
+}
+
+Rectangle ::= SEQUENCE {first-corner VDC-Pair,
+ second-corner VDC-Pair
+}
+
+Region-Of-Interest-Specification ::= CHOICE {
+ automatic [0] NULL,
+ rectangle [1] SEQUENCE {a VDC-Pair,
+ b VDC-Pair}
+}
+
+Picture-Orientation ::= One-Of-Four-Angles
+
+One-Of-Four-Angles ::= ENUMERATED {d0(0), d90(1), d180(2), d270(3)}
+
+Picture-Dimensions ::= CHOICE {
+ width-controlled
+ [0] SEQUENCE {minimum-width INTEGER,
+ preferred-width INTEGER},
+ height-controlled
+ [1] SEQUENCE {minimum-height INTEGER,
+ preferred-height INTEGER},
+ area-controlled
+ [2] SEQUENCE {minimum-width INTEGER,
+ preferred-width INTEGER,
+ minimum-height INTEGER,
+ preferred-height INTEGER,
+ aspect-ratio-flag ENUMERATED {fixed(0), variable(1)}
+ },
+ automatic [3] NULL
+}
+
+END
+
+-- Generated by Asnp, the ASN.1 pretty-printer of France Telecom R&D
+
diff --git a/lib/asn1/test/asn1_SUITE_data/x420/Geo-Gr-Profile-Attributes.asn b/lib/asn1/test/asn1_SUITE_data/x420/Geo-Gr-Profile-Attributes.asn
new file mode 100644
index 0000000000..28daa467e1
--- /dev/null
+++ b/lib/asn1/test/asn1_SUITE_data/x420/Geo-Gr-Profile-Attributes.asn
@@ -0,0 +1,44 @@
+-- Module Geo-Gr-Profile-Attributes (T.418:03/1993)
+
+Geo-Gr-Profile-Attributes {2 8 1 8 4} DEFINITIONS IMPLICIT TAGS ::=
+BEGIN
+
+EXPORTS
+ Geo-Gr-Presentation-Feature, Geo-Gr-Coding-Attribute, Geo-Gr-Content-Defaults;
+
+IMPORTS
+ Line-Rendition, Marker-Rendition, Text-Rendition, Filled-Area-Rendition,
+ Edge-Rendition, Colour-Representations, Transparency-Specification,
+ Transformation-Specification, Region-Of-Interest-Specification,
+ Picture-Orientation, Picture-Dimensions, ASF-Type, VDC-Pair,
+ One-Of-Four-Angles
+ FROM Geo-Gr-Presentation-Attributes {2 8 1 8 2}; -- see 10.2
+
+Geo-Gr-Presentation-Feature ::= CHOICE {
+ null NULL,
+ text-rendition [3] Text-Rendition
+}
+
+Geo-Gr-Coding-Attribute ::= NULL
+
+-- no non-basic values are defined for the
+-- geometric graphics coding attributes in this Specification
+Geo-Gr-Content-Defaults ::= SET {
+ line-rendition [1] Line-Rendition OPTIONAL,
+ marker-rendition [2] Marker-Rendition OPTIONAL,
+ text-rendition [3] Text-Rendition OPTIONAL,
+ filled-area-rendition [4] Filled-Area-Rendition OPTIONAL,
+ edge-rendition [5] Edge-Rendition OPTIONAL,
+ colour-representations [6] Colour-Representations OPTIONAL,
+ transparency-specification [7] Transparency-Specification OPTIONAL,
+ transformation-specification [8] Transformation-Specification OPTIONAL,
+ region-of-interest-specification
+ [9] Region-Of-Interest-Specification OPTIONAL,
+ picture-orientation [10] Picture-Orientation OPTIONAL,
+ picture-dimensions [11] Picture-Dimensions OPTIONAL
+}
+
+END
+
+-- Generated by Asnp, the ASN.1 pretty-printer of France Telecom R&D
+
diff --git a/lib/asn1/test/asn1_SUITE_data/x420/GulsSecurityExchanges.asn b/lib/asn1/test/asn1_SUITE_data/x420/GulsSecurityExchanges.asn
new file mode 100644
index 0000000000..336b824174
--- /dev/null
+++ b/lib/asn1/test/asn1_SUITE_data/x420/GulsSecurityExchanges.asn
@@ -0,0 +1,79 @@
+-- Module GulsSecurityExchanges (X.830:04/1995)
+
+GulsSecurityExchanges {joint-iso-itu-t genericULS(20) modules(1)
+ gulsSecurityExchanges(2)} DEFINITIONS AUTOMATIC TAGS ::=
+BEGIN
+
+-- EXPORTS All
+IMPORTS
+ securityExchanges, notation
+ FROM ObjectIdentifiers {joint-iso-itu-t genericULS(20) modules(1)
+ objectIdentifiers(0)}
+ SECURITY-EXCHANGE, SEC-EXCHG-ITEM, SE-ERROR
+ FROM Notation notation
+ Credentials, SecurityProblem
+ FROM DirectoryAbstractService {joint-iso-itu-t ds(5) module(1)
+ directoryAbstractService(2) 3};
+
+-- *******************************************
+-- Directory Authentication Exchange (One-way)
+-- *******************************************
+dirAuthenticationOneWay SECURITY-EXCHANGE ::= {
+ SE-ITEMS {credentials}
+ IDENTIFIER global:{securityExchanges dir-authent-one-way(1)}
+}
+
+credentials SEC-EXCHG-ITEM ::= {
+ ITEM-TYPE DirectoryAbstractService.Credentials
+ ITEM-ID 1
+}
+
+-- *******************************************
+-- Directory Authentication Exchange (Two-way)
+-- *******************************************
+dirAuthenticationTwoWay SECURITY-EXCHANGE ::= {
+ SE-ITEMS {initiatorCredentials | responderCredentials}
+ IDENTIFIER global:{securityExchanges dir-authent-two-way(2)}
+}
+
+initiatorCredentials SEC-EXCHG-ITEM ::= {
+ ITEM-TYPE DirectoryAbstractService.Credentials
+ ITEM-ID 1
+ ERRORS {authenticationFailure}
+}
+
+responderCredentials SEC-EXCHG-ITEM ::= {
+ ITEM-TYPE DirectoryAbstractService.Credentials
+ ITEM-ID 2
+}
+
+authenticationFailure SE-ERROR ::= {
+ PARAMETER DirectoryAbstractService.SecurityProblem
+ ERROR-CODE local:1
+}
+
+-- ***************************
+-- Simple Negotiation Exchange
+-- ***************************
+simpleNegotiationSE SECURITY-EXCHANGE ::= {
+ SE-ITEMS {offeredIds | acceptedIds}
+ IDENTIFIER global:{securityExchanges simple-negotiation-se(3)}
+}
+
+offeredIds SEC-EXCHG-ITEM ::= {ITEM-TYPE Negotiation-SEI
+ ITEM-ID 1
+}
+
+acceptedIds SEC-EXCHG-ITEM ::= {ITEM-TYPE Negotiation-SEI
+ ITEM-ID 2
+}
+
+Negotiation-SEI ::= SEQUENCE OF OBJECT IDENTIFIER
+
+END
+
+-- Generated by Asnp, the ASN.1 pretty-printer of France Telecom R&D
+
+
+-- content of stack:
+--
diff --git a/lib/asn1/test/asn1_SUITE_data/x420/GulsSecurityTransformations.asn b/lib/asn1/test/asn1_SUITE_data/x420/GulsSecurityTransformations.asn
new file mode 100644
index 0000000000..db2725c37d
--- /dev/null
+++ b/lib/asn1/test/asn1_SUITE_data/x420/GulsSecurityTransformations.asn
@@ -0,0 +1,212 @@
+-- Module GulsSecurityTransformations (X.830:04/1995)
+
+GulsSecurityTransformations {joint-iso-itu-t genericULS(20) modules(1)
+ gulsSecurityTransformations(3)} DEFINITIONS AUTOMATIC TAGS ::=
+BEGIN
+
+-- EXPORTS All
+IMPORTS
+ securityTransformations, notation
+ FROM ObjectIdentifiers {joint-iso-itu-t genericULS(20) modules(1)
+ objectIdentifiers(0)}
+ SECURITY-TRANSFORMATION, SecurityIdentity
+ FROM Notation notation
+ AlgorithmIdentifier
+ FROM AuthenticationFramework {joint-iso-itu-t ds(5) module(1)
+ authenticationFramework(7) 3};
+
+-- ***************************************
+-- Notation for specifying key information
+-- ***************************************
+KEY-INFORMATION ::=
+ CLASS
+ -- This information object class definition is for use when
+ -- specifying key information relating to particular classes
+ -- of protection mechanisms (e.g. symmetric, asymmetric).
+ -- It may be useful in defining various security transformations.
+ {
+ &kiClass CHOICE {local INTEGER,
+ -- local objects can only be defined within this
+ -- ASN.1 module.
+ global OBJECT IDENTIFIER
+ -- global objects are defined elsewhere
+ } UNIQUE,
+ &KiType
+}WITH SYNTAX {KEY-INFO-CLASS &kiClass
+ KEY-INFO-TYPE &KiType
+}
+
+symmetricKeyInformation KEY-INFORMATION ::= {
+ KEY-INFO-CLASS local:0
+ KEY-INFO-TYPE
+ SEQUENCE {entityId SecurityIdentity,
+ keyIdentifier INTEGER}
+}
+
+asymmetricKeyInformation KEY-INFORMATION ::= {
+ KEY-INFO-CLASS local:1
+ KEY-INFO-TYPE
+ SEQUENCE {issuerCAName SecurityIdentity OPTIONAL,
+ certSerialNumber INTEGER OPTIONAL,
+ signerName SecurityIdentity OPTIONAL,
+ keyIdentifier BIT STRING OPTIONAL}
+}
+
+-- *******************************************
+-- Directory ENCRYPTED Security Transformation
+-- *******************************************
+dirEncryptedTransformation SECURITY-TRANSFORMATION ::= {
+ IDENTIFIER {securityTransformations dir-encrypted(1)}
+ -- This transformation transforms a string of octets to a
+ -- new bit string using an encipherment process.
+ INITIAL-ENCODING-RULES {joint-iso-itu-t asn1(1) ber(1)}
+ XFORMED-DATA-TYPE BIT STRING
+}
+
+-- ****************************************
+-- Directory SIGNED Security Transformation
+-- ****************************************
+dirSignedTransformation SECURITY-TRANSFORMATION ::= {
+ IDENTIFIER {securityTransformations dir-signed(2)}
+ INITIAL-ENCODING-RULES
+ {joint-iso-itu-t asn1(1) ber-derived(2) distinguished-encoding(1)}
+ XFORMED-DATA-TYPE
+ SEQUENCE {toBeSigned
+ ABSTRACT-SYNTAX.&Type
+ (CONSTRAINED BY {
+
+ -- this type is constrained to being the to-be-signed type -- }),
+ algorithmId AlgorithmIdentifier,
+ -- of the algorithms used to compute the signature
+ encipheredHash BIT STRING}
+}
+
+-- *******************************************
+-- Directory SIGNATURE Security Transformation
+-- *******************************************
+dirSignatureTransformation SECURITY-TRANSFORMATION ::= {
+ IDENTIFIER {securityTransformations dir-signature(3)}
+ INITIAL-ENCODING-RULES
+ {joint-iso-itu-t asn1(1) ber-derived(2) distinguished-encoding(1)}
+ XFORMED-DATA-TYPE
+ SEQUENCE {algorithmId AlgorithmIdentifier,
+ -- of the algorithms used to compute the signature
+ encipheredHash BIT STRING}
+}
+
+-- ***********************************
+-- GULS SIGNED Security Transformation
+-- ***********************************
+gulsSignedTransformation{KEY-INFORMATION:SupportedKIClasses}
+ SECURITY-TRANSFORMATION ::= {
+ IDENTIFIER {securityTransformations guls-signed(4)}
+ INITIAL-ENCODING-RULES
+ {joint-iso-itu-t asn1(1) ber-derived(2) canonical-encoding(0)}
+ -- This default for initial encoding rules may be overridden
+ -- using a static protected parameter (initEncRules).
+ XFORMED-DATA-TYPE
+ SEQUENCE {intermediateValue
+ EMBEDDED PDV
+ (WITH COMPONENTS {
+ identification (WITH COMPONENTS {
+ transfer-syntax (CONSTRAINED BY {
+ -- The transfer syntax to be used is that
+ -- indicated by the initEncRules value within
+ -- the intermediate value -- })PRESENT
+ }),
+ data-value (CONTAINING IntermediateType{{SupportedKIClasses}})
+
+ -- The data value encoded is a value of type
+ -- IntermediateType
+ }),
+ appendix
+ BIT STRING
+ (CONSTRAINED BY {
+ -- the appendix value must be generated following
+ -- the procedure specified in D.4 of DIS 11586-1 -- })
+ }
+}
+
+IntermediateType{KEY-INFORMATION:SupportedKIClasses} ::= SEQUENCE {
+ unprotectedItem ABSTRACT-SYNTAX.&Type-- this type is constrained to being
+ -- the type of the unprotected item, or
+ -- BIT STRING if the unprotected item is
+ -- not derived from an ASN.1 abstract
+ -- syntax --,
+ initEncRules
+ OBJECT IDENTIFIER
+ DEFAULT {joint-iso-itu-t asn1(1) ber-derived(2) canonical-encoding(0)},
+ signOrSealAlgorithm AlgorithmIdentifier OPTIONAL,
+ -- Identifies the signing or
+ -- sealing algorithm, and can convey
+ -- algorithm parameters
+ hashAlgorithm AlgorithmIdentifier OPTIONAL,
+ -- Identifies a hash function,
+ -- for use if a hash function is required
+ -- and the signOrSealAlgorithm identifier
+ -- does not imply a particular hash
+ -- function. Can also convey algorithm
+ -- parameters.
+ keyInformation
+ SEQUENCE {kiClass KEY-INFORMATION.&kiClass({SupportedKIClasses}),
+ keyInfo KEY-INFORMATION.&KiType({SupportedKIClasses}{@.kiClass})
+ } OPTIONAL
+ -- Key information may assume various
+ -- formats, governed by supported members
+ -- of the KEY-INFORMATION information
+ -- object class (defined at start of the
+ -- definitive ASN.1 module)
+}
+
+-- **************************************
+-- GULS SIGNATURE Security Transformation
+-- **************************************
+gulsSignatureTransformation{KEY-INFORMATION:SupportedKIClasses}
+ SECURITY-TRANSFORMATION ::= {
+ IDENTIFIER {securityTransformations guls-signature(5)}
+ INITIAL-ENCODING-RULES
+ {joint-iso-itu-t asn1(1) ber-derived(2) canonical-encoding(0)}
+ -- This default for initial encoding rules may be overridden
+ -- using a static protected parameter (initEncRules).
+ XFORMED-DATA-TYPE
+ SEQUENCE {initEncRules
+ OBJECT IDENTIFIER
+ DEFAULT
+ {joint-iso-itu-t asn1(1) ber-derived(2)
+ canonical-encoding(0)},
+ signOrSealAlgorithm AlgorithmIdentifier OPTIONAL,
+ -- Identifies the signing or
+ -- sealing algorithm, and can convey
+ -- algorithm parameters
+ hashAlgorithm AlgorithmIdentifier OPTIONAL,
+ -- Identifies a hash function,
+ -- for use if a hash function is required
+ -- and the signOrSealAlgorithm identifier
+ -- does not imply a particular hash
+ -- function. Can also convey algorithm parameters.
+ keyInformation
+ SEQUENCE {kiClass
+ KEY-INFORMATION.&kiClass({SupportedKIClasses}),
+ keyInfo
+ KEY-INFORMATION.&KiType
+ ({SupportedKIClasses}{@.kiClass})} OPTIONAL,
+ -- Key information may assume various
+ -- formats, governed by supported members
+ -- of the KEY-INFORMATION information
+ -- object class (defined at start of the
+ -- definitive ASN.1 module)
+ appendix
+ BIT STRING
+ (CONSTRAINED BY {
+ -- the appendix value must be generated following
+ -- the procedure specified in D.5 of DIS 11586-1 -- })
+ }
+}
+
+END
+
+-- Generated by Asnp, the ASN.1 pretty-printer of France Telecom R&D
+
+
+-- content of stack:
+--
diff --git a/lib/asn1/test/asn1_SUITE_data/x420/HierarchicalOperationalBindings.asn b/lib/asn1/test/asn1_SUITE_data/x420/HierarchicalOperationalBindings.asn
new file mode 100644
index 0000000000..4e0084b079
--- /dev/null
+++ b/lib/asn1/test/asn1_SUITE_data/x420/HierarchicalOperationalBindings.asn
@@ -0,0 +1,123 @@
+-- Module HierarchicalOperationalBindings (X.518 TC2:08/1997)
+
+HierarchicalOperationalBindings {joint-iso-itu-t ds(5) module(1)
+ hierarchicalOperationalBindings(20) 3} DEFINITIONS ::=
+BEGIN
+
+-- EXPORTS All
+-- The types and values defined in this module are exported for use in the other ASN.1 modules contained
+-- within the Directory Specifications, and for the use of other applications which will use them to access
+-- Directory services. Other applications may use them for their own purposes, but this will not constrain
+-- extensions and modifications needed to maintain or improve the Directory service.
+IMPORTS
+ informationFramework, distributedOperations,
+ directoryOperationalBindingTypes, opBindingManagement, dsp
+ FROM UsefulDefinitions {joint-iso-itu-t ds(5) module(1)
+ usefulDefinitions(0) 3}
+ Attribute, RelativeDistinguishedName, DistinguishedName
+ FROM InformationFramework informationFramework
+ MasterAndShadowAccessPoints
+ FROM DistributedOperations distributedOperations
+ directorySystemAC
+ FROM DirectorySystemProtocol dsp
+ OPERATIONAL-BINDING
+ FROM OperationalBindingManagement opBindingManagement
+ id-op-binding-hierarchical, id-op-binding-non-specific-hierarchical
+ FROM DirectoryOperationalBindingTypes directoryOperationalBindingTypes;
+
+-- types
+HierarchicalAgreement ::= SEQUENCE {
+ rdn [0] RelativeDistinguishedName,
+ immediateSuperior [1] DistinguishedName
+}
+
+NonSpecificHierarchicalAgreement ::= SEQUENCE {
+ immediateSuperior [1] DistinguishedName
+}
+
+SuperiorToSubordinate ::= SEQUENCE {
+ contextPrefixInfo [0] DITcontext,
+ entryInfo [1] SET (SIZE (1..MAX)) OF Attribute OPTIONAL,
+ immediateSuperiorInfo [2] SET (SIZE (1..MAX)) OF Attribute OPTIONAL
+}
+
+DITcontext ::= SEQUENCE OF Vertex
+
+Vertex ::= SEQUENCE {
+ rdn [0] RelativeDistinguishedName,
+ admPointInfo [1] SET (SIZE (1..MAX)) OF Attribute OPTIONAL,
+ subentries [2] SET (SIZE (1..MAX)) OF SubentryInfo OPTIONAL,
+ accessPoints [3] MasterAndShadowAccessPoints OPTIONAL
+}
+
+SubentryInfo ::= SEQUENCE {
+ rdn [0] RelativeDistinguishedName,
+ info [1] SET OF Attribute
+}
+
+SubordinateToSuperior ::= SEQUENCE {
+ accessPoints [0] MasterAndShadowAccessPoints OPTIONAL,
+ alias [1] BOOLEAN DEFAULT FALSE,
+ entryInfo [2] SET (SIZE (1..MAX)) OF Attribute OPTIONAL,
+ subentries [3] SET (SIZE (1..MAX)) OF SubentryInfo OPTIONAL
+}
+
+SuperiorToSubordinateModification ::=
+ SuperiorToSubordinate(WITH COMPONENTS {
+ ...,
+ entryInfo ABSENT
+ })
+
+NHOBSuperiorToSubordinate ::=
+ SuperiorToSubordinate(WITH COMPONENTS {
+ ...,
+ entryInfo ABSENT
+ })
+
+NHOBSubordinateToSuperior ::= SEQUENCE {
+ accessPoint [0] MasterAndShadowAccessPoints OPTIONAL,
+ subentries [3] SET (SIZE (1..MAX)) OF SubentryInfo OPTIONAL
+}
+
+-- operational binding information objects
+hierarchicalOperationalBinding OPERATIONAL-BINDING ::= {
+ AGREEMENT HierarchicalAgreement
+ -- APPLICATION CONTEXTS {{directorySystemAC}}
+ APPLICATION CONTEXTS {directorySystemAC}
+ ASYMMETRIC ROLE-A
+ { -- superior DSAESTABLISHMENT-INITIATOR TRUE
+ ESTABLISHMENT-PARAMETER SuperiorToSubordinate
+ MODIFICATION-INITIATOR TRUE
+ MODIFICATION-PARAMETER SuperiorToSubordinateModification
+ TERMINATION-INITIATOR TRUE}
+ ROLE-B
+ { -- subordinate DSAESTABLISHMENT-INITIATOR TRUE
+ ESTABLISHMENT-PARAMETER SubordinateToSuperior
+ MODIFICATION-INITIATOR TRUE
+ MODIFICATION-PARAMETER SubordinateToSuperior
+ TERMINATION-INITIATOR TRUE}
+ ID id-op-binding-hierarchical
+}
+
+nonSpecificHierarchicalOperationalBinding OPERATIONAL-BINDING ::= {
+ AGREEMENT NonSpecificHierarchicalAgreement
+ -- APPLICATION CONTEXTS {{directorySystemAC}}
+ APPLICATION CONTEXTS {directorySystemAC}
+ ASYMMETRIC ROLE-A
+ { -- superior DSAESTABLISHMENT-PARAMETER NHOBSuperiorToSubordinate
+ MODIFICATION-INITIATOR TRUE
+ MODIFICATION-PARAMETER NHOBSuperiorToSubordinate
+ TERMINATION-INITIATOR TRUE}
+ ROLE-B
+ { -- subordinate DSAESTABLISHMENT-INITIATOR TRUE
+ ESTABLISHMENT-PARAMETER NHOBSubordinateToSuperior
+ MODIFICATION-INITIATOR TRUE
+ MODIFICATION-PARAMETER NHOBSubordinateToSuperior
+ TERMINATION-INITIATOR TRUE}
+ ID id-op-binding-non-specific-hierarchical
+}
+
+END
+
+-- Generated by Asnp, the ASN.1 pretty-printer of France Telecom R&D
+
diff --git a/lib/asn1/test/asn1_SUITE_data/x420/IPMSAbstractService.asn b/lib/asn1/test/asn1_SUITE_data/x420/IPMSAbstractService.asn
new file mode 100644
index 0000000000..3fec8ae64a
--- /dev/null
+++ b/lib/asn1/test/asn1_SUITE_data/x420/IPMSAbstractService.asn
@@ -0,0 +1,148 @@
+-- Module IPMSAbstractService (X.420:06/1999)
+IPMSAbstractService {joint-iso-itu-t mhs(6) ipms(1) modules(0)
+ abstract-service(3) version-1994(0)} DEFINITIONS IMPLICIT TAGS ::=
+BEGIN
+
+-- Prologue
+-- Exports everything.
+IMPORTS
+ -- IPMS Information Objects
+ AutoForwardComment, Heading, InformationObject, IPM, NRN, ON, RN
+ --==
+ FROM IPMSInformationObjects {joint-iso-itu-t mhs(6) ipms(1) modules(0)
+ information-objects(2) version-1999(1)}
+ -- IPMS Object Identifiers
+ id-pt-management, id-pt-origination, id-pt-reception
+ --==
+ FROM IPMSObjectIdentifiers {joint-iso-itu-t mhs(6) ipms(1) modules(0)
+ object-identifiers(0) version-1999(1)}
+ -- MTS Abstract Service
+ ABSTRACT-ERROR, ABSTRACT-OPERATION, MessageDeliveryEnvelope,
+ MessageSubmissionEnvelope, MessageSubmissionIdentifier,
+ MessageSubmissionTime, ORName, PORT, ProbeSubmissionEnvelope,
+ ProbeSubmissionIdentifier, ProbeSubmissionTime,
+ recipient-improperly-specified, ReportDeliveryEnvelope,
+ SupplementaryInformation
+ --==
+ FROM MTSAbstractService {joint-iso-itu-t mhs(6) mts(3) modules(0)
+ mts-abstract-service(1) version-1999(1)};
+
+-- Ports
+origination PORT ::= {
+ CONSUMER INVOKES
+ {originate-probe | originate-ipm | originate-rn | originate-on}
+ ID id-pt-origination
+}
+
+reception PORT ::= {
+ SUPPLIER INVOKES
+ {receive-report | receive-ipm | receive-rn | receive-nrn | receive-on}
+ ID id-pt-reception
+}
+
+management PORT ::= {
+ CONSUMER INVOKES
+ {change-auto-discard | change-auto-acknowledgment | change-auto-forwarding}
+ ID id-pt-management
+}
+
+-- Origination abstract operations
+originate-probe ABSTRACT-OPERATION ::= {
+ ARGUMENT SET {envelope [0] ProbeSubmissionEnvelope,
+ content [1] IPM}
+ RESULT
+ SET {submission-identifier [0] ProbeSubmissionIdentifier,
+ submission-time [1] ProbeSubmissionTime}
+ ERRORS {subscription-error | recipient-improperly-specified}
+}
+
+originate-ipm ABSTRACT-OPERATION ::= {
+ ARGUMENT SET {envelope [0] MessageSubmissionEnvelope,
+ content [1] IPM}
+ RESULT
+ SET {submission-identifier [0] MessageSubmissionIdentifier,
+ submission-time [1] MessageSubmissionTime}
+ ERRORS {subscription-error | recipient-improperly-specified}
+}
+
+originate-rn ABSTRACT-OPERATION ::= {
+ ARGUMENT SET {envelope [0] MessageSubmissionEnvelope,
+ content [1] RN}
+ RESULT
+ SET {submission-identifier [0] MessageSubmissionIdentifier,
+ submission-time [1] MessageSubmissionTime}
+ ERRORS {subscription-error | recipient-improperly-specified}
+}
+
+originate-on ABSTRACT-OPERATION ::= {
+ ARGUMENT SET {envelope [0] MessageSubmissionEnvelope,
+ content [1] ON}
+ RESULT
+ SET {submission-identifier [0] MessageSubmissionIdentifier,
+ submission-time [1] MessageSubmissionTime}
+ ERRORS {subscription-error | recipient-improperly-specified}
+}
+
+-- Reception abstract operations
+receive-report ABSTRACT-OPERATION ::= {
+ ARGUMENT
+ SET {envelope [0] ReportDeliveryEnvelope,
+ undelivered-object [1] InformationObject OPTIONAL}
+}
+
+receive-ipm ABSTRACT-OPERATION ::= {
+ ARGUMENT SET {envelope [0] MessageDeliveryEnvelope,
+ content [1] IPM}
+}
+
+receive-rn ABSTRACT-OPERATION ::= {
+ ARGUMENT SET {envelope [0] MessageDeliveryEnvelope,
+ content [1] RN}
+}
+
+receive-nrn ABSTRACT-OPERATION ::= {
+ ARGUMENT SET {envelope [0] MessageDeliveryEnvelope,
+ content [1] NRN}
+}
+
+receive-on ABSTRACT-OPERATION ::= {
+ ARGUMENT SET {envelope [0] MessageDeliveryEnvelope,
+ content [1] ON}
+}
+
+-- Management abstract operations
+change-auto-discard ABSTRACT-OPERATION ::= {
+ ARGUMENT
+ SET {auto-discard-expired-IPMs [0] BOOLEAN,
+ auto-discard-obsolete-IPMs [1] BOOLEAN}
+}
+
+change-auto-acknowledgment ABSTRACT-OPERATION ::= {
+ ARGUMENT
+ SET {auto-acknowledge-IPMs [0] BOOLEAN,
+ auto-acknowledge-suppl-receipt-info
+ [1] SupplementaryInformation OPTIONAL}
+ ERRORS {subscription-error}
+}
+
+change-auto-forwarding ABSTRACT-OPERATION ::= {
+ ARGUMENT
+ SET {auto-forward-IPMs [0] BOOLEAN,
+ auto-forward-recipients [1] SEQUENCE OF ORName OPTIONAL,
+ auto-forward-heading [2] Heading OPTIONAL,
+ auto-forward-comment [3] AutoForwardComment OPTIONAL}
+ ERRORS {subscription-error | recipient-improperly-specified}
+}
+
+-- Abstract errors
+subscription-error ABSTRACT-ERROR ::= {
+ PARAMETER SET {problem [0] SubscriptionProblem}
+}
+
+SubscriptionProblem ::= ENUMERATED {
+ ipms-eos-not-subscribed(0), mts-eos-not-subscribed(1)}
+
+END -- of IPMSAbstractService
+
+-- Generated by Asnp, the ASN.1 pretty-printer of France Telecom R&D
+
diff --git a/lib/asn1/test/asn1_SUITE_data/x420/IPMSAutoActionTypes.asn b/lib/asn1/test/asn1_SUITE_data/x420/IPMSAutoActionTypes.asn
new file mode 100644
index 0000000000..8c0c8138e2
--- /dev/null
+++ b/lib/asn1/test/asn1_SUITE_data/x420/IPMSAutoActionTypes.asn
@@ -0,0 +1,234 @@
+-- Module IPMSAutoActionTypes (X.420:06/1999)
+IPMSAutoActionTypes {joint-iso-itu-t mhs(6) ipms(1) modules(0) auto-actions(13)
+ version-1999(1)} DEFINITIONS EXPLICIT TAGS ::=
+BEGIN
+
+-- Prologue
+-- Exports everything.
+IMPORTS
+ -- IPMS Information Objects
+ AdviceNotifications, AutoForwardComment, BodyPart, Heading, IA5TextBodyPart,
+ IPMSExtension, SupplReceiptInfoField
+ --==
+ FROM IPMSInformationObjects {joint-iso-itu-t mhs(6) ipms(1) modules(0)
+ information-objects(2) version-1999(1)}
+ -- IPMS Upper Bounds
+ ub-ipm-identifier-suffix
+ --==
+ FROM IPMSUpperBounds {joint-iso-itu-t mhs(6) ipms(1) modules(0)
+ upper-bounds(10) version-1999(1)}
+ -- IPMS Object Identifiers
+ id-aa-ipm-auto-acknowledgement, id-aa-ipm-auto-advise,
+ id-aa-ipm-auto-correlate, id-aa-ipm-auto-discard,
+ id-aae-auto-discard-error, id-aae-auto-forwarding-loop,
+ id-aae-duplicate-ipn
+ --==
+ FROM IPMSObjectIdentifiers {joint-iso-itu-t mhs(6) ipms(1) modules(0)
+ object-identifiers(0) version-1999(1)}
+ -- Auto-action information object class
+ AUTO-ACTION,
+ AUTO-ACTION-ERROR,
+ -- MS Abstract Service data-types and abstract-errors
+ Filter, EntryInformationSelection, ms-extension-error, MSSubmissionOptions,
+ service-error
+ --==
+ FROM MSAbstractService {joint-iso-itu-t mhs(6) ms(4) modules(0)
+ abstract-service(1) version-1999(1)}
+ -- MS object identifier
+ id-act-ipm-auto-forward
+ --==
+ FROM MSObjectIdentifiers {joint-iso-itu-t mhs(6) ms(4) modules(0)
+ object-identifiers(0) version-1999(1)}
+ -- MTS Abstract Service data-types and abstract-errors
+ ContentIdentifier, DeferredDeliveryTime, element-of-service-not-subscribed,
+ ExplicitConversion, ExtensionField{}, inconsistent-request,
+ MessageSubmissionEnvelope, originator-invalid, OriginatorName,
+ OriginatorReportRequest, PerMessageIndicators,
+ PerMessageSubmissionExtensions, PerRecipientMessageSubmissionExtensions,
+ Priority, recipient-improperly-specified, RecipientName, remote-bind-error,
+ security-error, submission-control-violated, unsupported-critical-function
+ --==
+ FROM MTSAbstractService {joint-iso-itu-t mhs(6) mts(3) modules(0)
+ mts-abstract-service(1) version-1999(1)}
+ -- MTS upper bounds
+ ub-recipients
+ --==
+ FROM MTSUpperBounds {joint-iso-itu-t mhs(6) mts(3) modules(0)
+ upper-bounds(3) version-1999(1)};
+
+-- IPM auto-actions information object set
+IPMAutoActions AUTO-ACTION ::=
+ {ipm-auto-forward, ... -- 1994 extension additions --,
+ ipm-auto-acknowledgement | ipm-auto-correlate | ipm-auto-discard |
+ ipm-auto-advise}
+
+-- Auto-actions
+ipm-auto-forward AUTO-ACTION ::= {
+ REGISTRATION PARAMETER IS
+ CHOICE {ipm-auto-forward-registration-parameter
+ IPMAutoForwardRegistrationParameter-- used in 1994 Application Contexts only -- ,
+ auto-forward-registration-parameter-88
+ AutoForwardRegistrationParameter88
+ } -- used in 1988 Application Contexts only
+ ERRORS
+ {auto-forwarding-loop | element-of-service-not-subscribed |
+ inconsistent-request | ms-extension-error | originator-invalid |
+ recipient-improperly-specified | remote-bind-error | security-error |
+ service-error | submission-control-violated |
+ unsupported-critical-function, ...}
+ IDENTIFIED BY id-act-ipm-auto-forward
+}
+
+-- Auto-forward 1994
+IPMAutoForwardRegistrationParameter ::= SEQUENCE {
+ filter [0] Filter OPTIONAL,
+ forwarding-envelope [1] MessageSubmissionEnvelope,
+ forwarding-heading [2] Heading,
+ forwarding-cover-note [3] BodyPart OPTIONAL,
+ submission-options [4] MSSubmissionOptions OPTIONAL,
+ nrn-comment [5] AutoForwardComment OPTIONAL,
+ ipm-auto-forward-options [6] IPMAutoForwardOptions DEFAULT {}
+}
+
+IPMAutoForwardOptions ::= BIT STRING {
+ forward-all-object-types(0), -- forward-all-object-types 'one', forward IPMs only 'zero'
+ include-returned-content(1), -- include-returned-content 'one', exclude 'zero'
+ include-returned-ipm(2), -- include-returned-ipm 'one', exclude 'zero'
+ forwarded-content-prohibited(3), -- forwarded-content-prohibited 'one', allowed'zero'
+ preserve-retrieval-status(4), -- preserve-retrieval-status 'one', change 'zero'
+ delete-delivered-object(5)
+} -- delete-delivered-object 'one', no deletion 'zero'
+
+-- Auto-forward 1988
+AutoForwardRegistrationParameter88 ::= SET {
+ filter [0] Filter OPTIONAL,
+ auto-forward-arguments [1] AutoForwardArguments,
+ delete-after-auto-forwarding [2] BOOLEAN DEFAULT FALSE,
+ forwarding-information [3] EncodedForwardingInformation
+}
+
+AutoForwardArguments ::= SET {
+ COMPONENTS OF PerMessageAutoForwardFields,
+ per-recipient-fields
+ [1] IMPLICIT SEQUENCE SIZE (1..ub-recipients) OF
+ PerRecipientAutoForwardFields
+}
+
+PerMessageAutoForwardFields ::= SET {
+ originator-name OriginatorName,
+ content-identifier ContentIdentifier OPTIONAL,
+ priority Priority OPTIONAL,
+ per-message-indicators PerMessageIndicators OPTIONAL,
+ deferred-delivery-time [0] IMPLICIT DeferredDeliveryTime OPTIONAL,
+ extensions
+ [2] IMPLICIT SET OF ExtensionField{{PerMessageSubmissionExtensions}}
+ DEFAULT {}
+}
+
+PerRecipientAutoForwardFields ::= SET {
+ recipient-name RecipientName,
+ originator-report-request [0] IMPLICIT OriginatorReportRequest,
+ explicit-conversion [1] IMPLICIT ExplicitConversion OPTIONAL,
+ extensions
+ [2] IMPLICIT SET OF
+ ExtensionField{{PerRecipientMessageSubmissionExtensions}}
+ DEFAULT {}
+}
+
+EncodedForwardingInformation ::=
+ OCTET STRING -- contains ForwardingInformation1988
+
+ForwardingInformation1988 ::= SET {
+ auto-forwarding-comment [0] IMPLICIT AutoForwardComment OPTIONAL,
+ ia5-cover-note [1] IMPLICIT IA5TextBodyPart OPTIONAL,
+ this-ipm-prefix
+ [2] IMPLICIT PrintableString(SIZE (1..ub-ipm-identifier-suffix)) OPTIONAL
+}
+
+--
+ipm-auto-acknowledgement AUTO-ACTION ::= {
+ REGISTRATION PARAMETER IS IPMAutoAcknowledgementRegistrationParameter
+ ERRORS
+ {originator-invalid | submission-control-violated |
+ element-of-service-not-subscribed | recipient-improperly-specified |
+ remote-bind-error | inconsistent-request | security-error |
+ unsupported-critical-function | duplicate-ipn}
+ IDENTIFIED BY id-aa-ipm-auto-acknowledgement
+}
+
+IPMAutoAcknowledgementRegistrationParameter ::= SET {
+ auto-acknowledge-suppl-receipt-info [0] SupplReceiptInfoField OPTIONAL,
+ submission-options [1] MSSubmissionOptions OPTIONAL
+}
+
+--
+ipm-auto-correlate AUTO-ACTION ::= {IDENTIFIED BY id-aa-ipm-auto-correlate
+}
+
+--
+ipm-auto-discard AUTO-ACTION ::= {
+ REGISTRATION PARAMETER IS IPMAutoDiscardRegistrationParameter
+ ERRORS
+ {submission-control-violated | ipm-auto-discard-error | originator-invalid
+ | recipient-improperly-specified | inconsistent-request | security-error
+ | unsupported-critical-function | remote-bind-error |
+ element-of-service-not-subscribed}
+ IDENTIFIED BY id-aa-ipm-auto-discard
+}
+
+IPMAutoDiscardRegistrationParameter ::= SET {
+ filter [0] Filter OPTIONAL,
+ submission-options [1] MSSubmissionOptions OPTIONAL,
+ auto-discard-expired-ipms [2] BOOLEAN,
+ auto-discard-obsoleted-ipms [3] BOOLEAN,
+ restrict-obsoleting-to-originator [4] BOOLEAN
+}
+
+--
+ipm-auto-advise AUTO-ACTION ::= {
+ REGISTRATION PARAMETER IS IPMAutoAdviseRegistrationParameter
+ ERRORS
+ {inconsistent-request | element-of-service-not-subscribed |
+ originator-invalid | recipient-improperly-specified | remote-bind-error |
+ security-error | submission-control-violated |
+ unsupported-critical-function}
+ IDENTIFIED BY id-aa-ipm-auto-advise
+}
+
+IPMAutoAdviseRegistrationParameter ::= SET {
+ enabled [0] BOOLEAN DEFAULT TRUE,
+ filter [1] Filter OPTIONAL,
+ advice-notifications
+ [2] SET OF IPMSExtension{{AdviceNotifications}},
+ suppress-subsequent-notifications [3] BOOLEAN DEFAULT TRUE,
+ use-ipm-if-an-not-supported [4] BOOLEAN DEFAULT FALSE,
+ submission-options [5] MSSubmissionOptions OPTIONAL
+}
+
+-- IPM auto-action-error-table information object set
+IPMAutoActionErrorTable AUTO-ACTION-ERROR ::=
+ {... -- 1994 extension additions --, auto-forwarding-loop | duplicate-ipn |
+ element-of-service-not-subscribed | inconsistent-request |
+ ipm-auto-discard-error | ms-extension-error | originator-invalid |
+ recipient-improperly-specified | remote-bind-error | security-error |
+ service-error | submission-control-violated | unsupported-critical-function}
+
+-- Auto-action-error-types
+auto-forwarding-loop AUTO-ACTION-ERROR ::= {
+ CODE global:id-aae-auto-forwarding-loop
+}
+
+duplicate-ipn AUTO-ACTION-ERROR ::= {CODE global:id-aae-duplicate-ipn
+}
+
+ipm-auto-discard-error AUTO-ACTION-ERROR ::= {
+ PARAMETER SET {problem [0] AutoDiscardProblem}
+ CODE global:id-aae-auto-discard-error
+}
+
+AutoDiscardProblem ::= INTEGER {not-obsoleted-by-originator(0)}
+
+END -- of IPMSAutoActionTypes
+
+-- Generated by Asnp, the ASN.1 pretty-printer of France Telecom R&D
+
diff --git a/lib/asn1/test/asn1_SUITE_data/x420/IPMSExtendedBodyPartTypes.asn b/lib/asn1/test/asn1_SUITE_data/x420/IPMSExtendedBodyPartTypes.asn
new file mode 100644
index 0000000000..9805a6189d
--- /dev/null
+++ b/lib/asn1/test/asn1_SUITE_data/x420/IPMSExtendedBodyPartTypes.asn
@@ -0,0 +1,102 @@
+-- Module IPMSExtendedBodyPartTypes (X.420:06/1999)
+IPMSExtendedBodyPartTypes {joint-iso-itu-t mhs(6) ipms(1) modules(0)
+ extended-body-part-types(7) version-1994(0)} DEFINITIONS IMPLICIT TAGS ::=
+BEGIN
+
+-- Prologue
+-- Exports everything.
+IMPORTS
+ -- IPMS Information Objects
+ BilaterallyDefinedBodyPart, EncryptedData, EncryptedParameters,
+ EXTENDED-BODY-PART-TYPE, G3FacsimileData, G3FacsimileParameters,
+ G4Class1BodyPart, IA5TextData, IA5TextParameters, MessageData,
+ MessageParameters, MixedModeBodyPart, NationallyDefinedBodyPart,
+ TeletexData, TeletexParameters, VideotexData, VideotexParameters
+ --==
+ FROM IPMSInformationObjects {joint-iso-itu-t mhs(6) ipms(1) modules(0)
+ information-objects(2) version-1999(1)}
+ -- IPMS Object Identifiers
+ id-ep-encrypted, id-ep-g3-facsimile, id-ep-ia5-text, id-ep-message,
+ id-ep-teletex, id-ep-videotex, id-et-bilaterally-defined, id-et-encrypted,
+ id-et-g3-facsimile, id-et-g4-class1, id-et-ia5-text, id-et-message,
+ id-et-mixed-mode, id-et-nationally-defined, id-et-teletex, id-et-videotex
+ --==
+ FROM IPMSObjectIdentifiers {joint-iso-itu-t mhs(6) ipms(1) modules(0)
+ object-identifiers(0) version-1999(1)};
+
+-- Extended IA5 Text body part
+ia5-text-body-part EXTENDED-BODY-PART-TYPE ::= {
+ PARAMETERS {IA5TextParameters
+ IDENTIFIED BY id-ep-ia5-text},
+ DATA {IA5TextData
+ IDENTIFIED BY id-et-ia5-text}
+}
+
+-- Extended G3 Facsimile body part
+g3-facsimile-body-part EXTENDED-BODY-PART-TYPE ::= {
+ PARAMETERS {G3FacsimileParameters
+ IDENTIFIED BY id-ep-g3-facsimile},
+ DATA {G3FacsimileData
+ IDENTIFIED BY id-et-g3-facsimile}
+}
+
+-- Extended G4 Class 1 body part
+g4-class1-body-part EXTENDED-BODY-PART-TYPE ::= {
+ DATA {G4Class1BodyPart
+ IDENTIFIED BY id-et-g4-class1}
+}
+
+-- Extended Teletex body part
+teletex-body-part EXTENDED-BODY-PART-TYPE ::= {
+ PARAMETERS {TeletexParameters
+ IDENTIFIED BY id-ep-teletex},
+ DATA {TeletexData
+ IDENTIFIED BY id-et-teletex}
+}
+
+-- Extended Videotex body part
+videotex-body-part EXTENDED-BODY-PART-TYPE ::= {
+ PARAMETERS {VideotexParameters
+ IDENTIFIED BY id-ep-videotex},
+ DATA {VideotexData
+ IDENTIFIED BY id-et-videotex}
+}
+
+-- Extended Encrypted body part
+encrypted-body-part EXTENDED-BODY-PART-TYPE ::= {
+ PARAMETERS {EncryptedParameters
+ IDENTIFIED BY id-ep-encrypted},
+ DATA {EncryptedData
+ IDENTIFIED BY id-et-encrypted}
+}
+
+-- Extended Message body part
+message-body-part EXTENDED-BODY-PART-TYPE ::= {
+ PARAMETERS {MessageParameters
+ IDENTIFIED BY id-ep-message},
+ DATA {MessageData
+ IDENTIFIED BY id-et-message}
+}
+
+-- Extended Mixed-mode body part
+mixed-mode-body-part EXTENDED-BODY-PART-TYPE ::= {
+ DATA {MixedModeBodyPart
+ IDENTIFIED BY id-et-mixed-mode}
+}
+
+-- Extended Bilaterally Defined body part
+bilaterally-defined-body-part EXTENDED-BODY-PART-TYPE ::= {
+ DATA {BilaterallyDefinedBodyPart
+ IDENTIFIED BY id-et-bilaterally-defined}
+}
+
+-- Extended Nationally Defined body part
+nationally-defined-body-part EXTENDED-BODY-PART-TYPE ::= {
+ DATA {NationallyDefinedBodyPart
+ IDENTIFIED BY id-et-nationally-defined}
+}
+
+END -- of IPMSExtendedBodyPartTypes
+
+-- Generated by Asnp, the ASN.1 pretty-printer of France Telecom R&D
+
diff --git a/lib/asn1/test/asn1_SUITE_data/x420/IPMSExtendedBodyPartTypes2.asn b/lib/asn1/test/asn1_SUITE_data/x420/IPMSExtendedBodyPartTypes2.asn
new file mode 100644
index 0000000000..b39e03c3b6
--- /dev/null
+++ b/lib/asn1/test/asn1_SUITE_data/x420/IPMSExtendedBodyPartTypes2.asn
@@ -0,0 +1,37 @@
+-- Module IPMSExtendedBodyPartTypes2 (X.420:06/1999)
+IPMSExtendedBodyPartTypes2 {iso standard mhs(10021) ipms(7) modules(0)
+ extended-body-part-types-2(1)} DEFINITIONS IMPLICIT TAGS ::=
+BEGIN
+
+-- Prologue
+-- Exports everything.
+IMPORTS
+ -- IPMS Information Objects
+ EXTENDED-BODY-PART-TYPE
+ --==
+ FROM IPMSInformationObjects {joint-iso-itu-t mhs(6) ipms(1) modules(0)
+ information-objects(2) version-1999(1)}
+ -- IPMS Object Identifiers
+ id-ep-general-text, id-et-general-text
+ --==
+ FROM IPMSObjectIdentifiers {joint-iso-itu-t mhs(6) ipms(1) modules(0)
+ object-identifiers(0) version-1999(1)};
+
+-- General Text body part
+general-text-body-part EXTENDED-BODY-PART-TYPE ::= {
+ PARAMETERS {GeneralTextParameters
+ IDENTIFIED BY id-ep-general-text},
+ DATA {GeneralTextData
+ IDENTIFIED BY id-et-general-text}
+}
+
+GeneralTextParameters ::= SET OF CharacterSetRegistration
+
+GeneralTextData ::= GeneralString
+
+CharacterSetRegistration ::= INTEGER(1..32767)
+
+END -- of IPMSExtendedBodyPartTypes2
+
+-- Generated by Asnp, the ASN.1 pretty-printer of France Telecom R&D
+
diff --git a/lib/asn1/test/asn1_SUITE_data/x420/IPMSExtendedVoiceBodyPartType.asn b/lib/asn1/test/asn1_SUITE_data/x420/IPMSExtendedVoiceBodyPartType.asn
new file mode 100644
index 0000000000..171f4b4223
--- /dev/null
+++ b/lib/asn1/test/asn1_SUITE_data/x420/IPMSExtendedVoiceBodyPartType.asn
@@ -0,0 +1,39 @@
+-- Module IPMSExtendedVoiceBodyPartType (X.420:06/1999)
+IPMSExtendedVoiceBodyPartType {joint-iso-itu-t mhs(6) ipms(1) modules(0)
+ extended-voice-body-part-type(11)} DEFINITIONS IMPLICIT TAGS ::=
+BEGIN
+
+-- Prologue
+-- Exports everything.
+IMPORTS
+ -- IPMS Information Objects
+ EXTENDED-BODY-PART-TYPE
+ --==
+ FROM IPMSInformationObjects {joint-iso-itu-t mhs(6) ipms(1) modules(0)
+ information-objects(2) version-1999(1)}
+ -- IPMS Object Identifiers
+ id-ep-voice, id-et-voice
+ --==
+ FROM IPMSObjectIdentifiers {joint-iso-itu-t mhs(6) ipms(1) modules(0)
+ object-identifiers(0) version-1999(1)};
+
+-- Extended Voice body part
+voice-body-part EXTENDED-BODY-PART-TYPE ::= {
+ PARAMETERS {VoiceParameters
+ IDENTIFIED BY id-ep-voice},
+ DATA {VoiceData
+ IDENTIFIED BY id-et-voice}
+}
+
+VoiceParameters ::= SEQUENCE {
+ voice-message-duration [0] INTEGER OPTIONAL, -- In seconds
+ voice-encoding-type [1] OBJECT IDENTIFIER,
+ supplementary-information [2] IA5String OPTIONAL
+}
+
+VoiceData ::= OCTET STRING
+
+END -- of IPMSExtendedVoiceBodyPartType
+
+-- Generated by Asnp, the ASN.1 pretty-printer of France Telecom R&D
+
diff --git a/lib/asn1/test/asn1_SUITE_data/x420/IPMSFileTransferBodyPartType.asn b/lib/asn1/test/asn1_SUITE_data/x420/IPMSFileTransferBodyPartType.asn
new file mode 100644
index 0000000000..59de6d1b04
--- /dev/null
+++ b/lib/asn1/test/asn1_SUITE_data/x420/IPMSFileTransferBodyPartType.asn
@@ -0,0 +1,253 @@
+-- Module IPMSFileTransferBodyPartType (X.420:06/1999)
+IPMSFileTransferBodyPartType {joint-iso-itu-t mhs(6) ipms(1) modules(0)
+ file-transfer-body-part-type(9)} DEFINITIONS IMPLICIT TAGS ::=
+BEGIN
+
+-- Prologue
+-- Exports everything.
+IMPORTS
+ -- FTAM Attribute Types
+ Attribute-Extensions, Concurrency-Access, Date-and-Time-Attribute,
+ Legal-Qualification-Attribute, Object-Availability-Attribute,
+ Object-Size-Attribute, Pathname, Permitted-Actions-Attribute,
+ Private-Use-Attribute
+ --==
+ FROM ISO8571-FTAM {iso standard 8571 application-context(1) iso-ftam(1)}
+ -- ACSE definitions of AP-title and AE-qualifier
+ AE-qualifier, AP-title
+ --==
+ FROM ACSE-1 {joint-iso-itu-t association-control(2) modules(0) apdus(0)
+ version1(1)}
+ -- IPMS Information Objects
+ EXTENDED-BODY-PART-TYPE, ExtensionsField
+ --==
+ FROM IPMSInformationObjects {joint-iso-itu-t mhs(6) ipms(1) modules(0)
+ information-objects(2) version-1999(1)}
+ -- IPMS Object Identifiers
+ id-ep-file-transfer, id-et-file-transfer
+ --==
+ FROM IPMSObjectIdentifiers {joint-iso-itu-t mhs(6) ipms(1) modules(0)
+ object-identifiers(0) version-1999(1)}
+ -- MTS Abstract Service
+ ORName
+ --==
+ FROM MTSAbstractService {joint-iso-itu-t mhs(6) mts(3) modules(0)
+ mts-abstract-service(1) version-1999(1)};
+
+-- File Transfer body part
+file-transfer-body-part EXTENDED-BODY-PART-TYPE ::= {
+ PARAMETERS {FileTransferParameters
+ IDENTIFIED BY id-ep-file-transfer},
+ DATA {FileTransferData
+ IDENTIFIED BY id-et-file-transfer}
+}
+
+FileTransferParameters ::= SEQUENCE {
+ related-stored-file [0] RelatedStoredFile OPTIONAL,
+ contents-type
+ [1] ContentsTypeParameter
+ DEFAULT
+ document-type:
+ {document-type-name
+ {iso standard 8571 document-type(5) unstructured-binary(3)}},
+ environment [2] EnvironmentParameter OPTIONAL,
+ compression [3] CompressionParameter OPTIONAL,
+ file-attributes [4] FileAttributes OPTIONAL,
+ extensions [5] ExtensionsField OPTIONAL
+}
+
+FileTransferData ::= SEQUENCE OF EXTERNAL
+
+-- This conveys a sequence of data values representing file contents;
+-- The rules for generating this sequence are implied by the value of the contents-type parameter.
+RelatedStoredFile ::=
+ SET OF
+ SEQUENCE {file-identifier FileIdentifier,
+ relationship
+ Relationship DEFAULT explicit-relationship:unspecified
+ }
+
+FileIdentifier ::= CHOICE {
+ pathname-and-version [0] PathnameandVersion,
+ cross-reference [1] CrossReference
+}
+
+PathnameandVersion ::= SEQUENCE {
+ pathname [0] Pathname-Attribute,
+ file-version [1] GraphicString OPTIONAL
+}
+
+CrossReference ::= SEQUENCE {
+ application-cross-reference [0] OCTET STRING,
+ message-reference [1] MessageReference OPTIONAL,
+ body-part-reference [2] INTEGER OPTIONAL
+}
+
+MessageReference ::= SET {
+ user [0] ORName OPTIONAL,
+ -- Defined in 8.5.5 of ITU-T Rec. X.411 | ISO/IEC 10021-4
+ user-relative-identifier [1] PrintableString
+}
+
+Relationship ::= CHOICE {
+ explicit-relationship [0] ExplicitRelationship,
+ descriptive-relationship [1] GraphicString
+}
+
+ExplicitRelationship ::= INTEGER {
+ unspecified(0), new-file(1), replacement(2), extension(3)}
+
+ContentsTypeParameter ::= Contents-Type-Attribute
+
+Contents-Type-Attribute ::= CHOICE {
+ document-type
+ [0] SEQUENCE {document-type-name Document-Type-Name,
+ parameter [0] DOCUMENT-PARAMETER.&Type OPTIONAL
+ },
+ -- The actual types to be used for values of the parameter field
+ -- are defined in the named document type.
+ constraint-set-and-abstract-syntax
+ [1] SEQUENCE {constraint-set-name Constraint-Set-Name,
+ abstract-syntax-name Abstract-Syntax-Name}
+}
+
+Document-Type-Name ::= OBJECT IDENTIFIER
+
+DOCUMENT-PARAMETER ::= CLASS {&Type
+}
+
+Constraint-Set-Name ::= OBJECT IDENTIFIER
+
+Abstract-Syntax-Name ::= OBJECT IDENTIFIER
+
+EnvironmentParameter ::= SEQUENCE {
+ application-reference [0] GeneralIdentifier OPTIONAL,
+ machine [1] GeneralIdentifier OPTIONAL,
+ operating-system [2] OBJECT IDENTIFIER OPTIONAL,
+ user-visible-string [3] SEQUENCE OF GraphicString OPTIONAL
+}
+
+GeneralIdentifier ::= CHOICE {
+ registered-identifier [0] OBJECT IDENTIFIER,
+ descriptive-identifier [1] SEQUENCE OF GraphicString
+}
+
+CompressionParameter ::= SEQUENCE {
+ compression-algorithm-id
+ [0] COMPRESSION-ALGORITHM.&id({CompressionAlgorithmTable}),
+ compression-algorithm-param
+ [1] COMPRESSION-ALGORITHM.&Type
+ ({CompressionAlgorithmTable}{@compression-algorithm-id})
+}
+
+COMPRESSION-ALGORITHM ::= TYPE-IDENTIFIER
+
+CompressionAlgorithmTable COMPRESSION-ALGORITHM ::=
+ {...}
+
+FileAttributes ::= SEQUENCE {
+ pathname Pathname-Attribute OPTIONAL,
+ permitted-actions
+ [1] Permitted-Actions-Attribute OPTIONAL,
+ storage-account [3] Account-Attribute OPTIONAL,
+ date-and-time-of-creation
+ [4] Date-and-Time-Attribute OPTIONAL,
+ date-and-time-of-last-modification
+ [5] Date-and-Time-Attribute OPTIONAL,
+ date-and-time-of-last-read-access
+ [6] Date-and-Time-Attribute OPTIONAL,
+ date-and-time-of-last-attribute-modification
+ [7] Date-and-Time-Attribute OPTIONAL,
+ identity-of-creator
+ [8] User-Identity-Attribute OPTIONAL,
+ identity-of-last-modifier
+ [9] User-Identity-Attribute OPTIONAL,
+ identity-of-last-reader
+ [10] User-Identity-Attribute OPTIONAL,
+ identity-of-last-attribute-modifier
+ [11] User-Identity-Attribute OPTIONAL,
+ object-availability
+ [12] Object-Availability-Attribute OPTIONAL,
+ object-size
+ [13] Object-Size-Attribute OPTIONAL,
+ future-object-size
+ [14] Object-Size-Attribute OPTIONAL,
+ access-control
+ [15] Access-Control-Attribute OPTIONAL,
+ legal-qualifications
+ [16] Legal-Qualification-Attribute OPTIONAL,
+ private-use
+ [17] Private-Use-Attribute OPTIONAL,
+ attribute-extensions
+ [22] Attribute-Extensions OPTIONAL
+}
+
+Pathname-Attribute ::= CHOICE {
+ incomplete-pathname [0] Pathname,
+ complete-pathname [23] Pathname
+}
+
+Account-Attribute ::= CHOICE {
+ no-value-available [0] NULL,
+ -- Indicates partial support of this attribute
+ actual-values Account
+}
+
+Account ::= GraphicString
+
+User-Identity-Attribute ::= CHOICE {
+ no-value-available [0] NULL,
+ -- Indicates partial support of this attribute.
+ actual-values User-Identity
+}
+
+User-Identity ::= GraphicString
+
+Access-Control-Attribute ::= CHOICE {
+ no-value-available [0] NULL,
+ -- Indicates partial support of this attribute.
+ actual-values [1] SET OF Access-Control-Element
+}
+
+-- The semantics of this attribute are described in ISO 8571-2
+Access-Control-Element ::= SEQUENCE {
+ action-list [0] Access-Request,
+ concurrency-access [1] Concurrency-Access OPTIONAL,
+ identity [2] User-Identity OPTIONAL,
+ passwords [3] Access-Passwords OPTIONAL,
+ location [4] Application-Entity-Title OPTIONAL
+}
+
+Access-Request ::= BIT STRING {
+ read(0), insert(1), replace(2), extend(3), erase(4), read-attribute(5),
+ change-attribute(6), delete-object(7)}
+
+Access-Passwords ::= SEQUENCE {
+ read-password [0] Password,
+ insert-password [1] Password,
+ replace-password [2] Password,
+ extend-password [3] Password,
+ erase-password [4] Password,
+ read-attribute-password [5] Password,
+ change-attribute-password [6] Password,
+ delete-password [7] Password,
+ pass-passwords [8] Pass-Passwords,
+ link-password [9] Password
+}
+
+Password ::= CHOICE {
+ graphic-string GraphicString,
+ octet-string OCTET STRING
+}
+
+Pass-Passwords ::= SEQUENCE OF Password
+
+Application-Entity-Title ::= SEQUENCE {
+ ap-title AP-title,
+ ae-qualifier AE-qualifier
+}
+
+END -- of IPMSFileTransferBodyPartType
+
+-- Generated by Asnp, the ASN.1 pretty-printer of France Telecom R&D
+
diff --git a/lib/asn1/test/asn1_SUITE_data/x420/IPMSForwardedContentBodyPartType.asn b/lib/asn1/test/asn1_SUITE_data/x420/IPMSForwardedContentBodyPartType.asn
new file mode 100644
index 0000000000..57faac6587
--- /dev/null
+++ b/lib/asn1/test/asn1_SUITE_data/x420/IPMSForwardedContentBodyPartType.asn
@@ -0,0 +1,53 @@
+-- Module IPMSForwardedContentBodyPartType (X.420:06/1999)
+IPMSForwardedContentBodyPartType {joint-iso-itu-t mhs(6) ipms(1) modules(0)
+ forwarded-content-body-part-type(15)} DEFINITIONS IMPLICIT TAGS ::=
+BEGIN
+
+-- Prologue
+-- Exports everything.
+IMPORTS
+ -- MTS Abstract Service
+ Content, ExtendedContentType, MessageDeliveryIdentifier, MessageDeliveryTime,
+ MessageSubmissionEnvelope, OriginatingMTACertificate,
+ OtherMessageDeliveryFields, ProofOfSubmission
+ --==
+ FROM MTSAbstractService {joint-iso-itu-t mhs(6) mts(3) modules(0)
+ mts-abstract-service(1) version-1999(1)}
+ -- IPMS Information Objects
+ EXTENDED-BODY-PART-TYPE
+ --==
+ FROM IPMSInformationObjects {joint-iso-itu-t mhs(6) ipms(1) modules(0)
+ information-objects(2) version-1999(1)}
+ -- IPMS Object Identifiers
+ id-ep-content, id-et-content
+ --==
+ FROM IPMSObjectIdentifiers {joint-iso-itu-t mhs(6) ipms(1) modules(0)
+ object-identifiers(0) version-1999(1)};
+
+-- Forwarded Content body part
+content-body-part{ExtendedContentType:content-type} EXTENDED-BODY-PART-TYPE ::=
+ {
+ PARAMETERS
+ {ForwardedContentParameters
+ IDENTIFIED BY {id-ep-content content-type}},
+ DATA {Content
+ IDENTIFIED BY {id-et-content content-type}}
+}
+
+ForwardedContentParameters ::= SET {
+ delivery-time [0] MessageDeliveryTime OPTIONAL,
+ delivery-envelope [1] OtherMessageDeliveryFields OPTIONAL,
+ mts-identifier [2] MessageDeliveryIdentifier OPTIONAL,
+ submission-proof [3] SubmissionProof OPTIONAL
+}
+
+SubmissionProof ::= SET {
+ proof-of-submission [0] ProofOfSubmission,
+ originating-MTA-certificate [1] OriginatingMTACertificate,
+ message-submission-envelope MessageSubmissionEnvelope
+}
+
+END -- of IPMSForwardedContentBodyPartType
+
+-- Generated by Asnp, the ASN.1 pretty-printer of France Telecom R&D
+
diff --git a/lib/asn1/test/asn1_SUITE_data/x420/IPMSForwardedReportBodyPartType.asn b/lib/asn1/test/asn1_SUITE_data/x420/IPMSForwardedReportBodyPartType.asn
new file mode 100644
index 0000000000..4e46c7679b
--- /dev/null
+++ b/lib/asn1/test/asn1_SUITE_data/x420/IPMSForwardedReportBodyPartType.asn
@@ -0,0 +1,41 @@
+-- Module IPMSForwardedReportBodyPartType (X.420:06/1999)
+IPMSForwardedReportBodyPartType {joint-iso-itu-t mhs(6) ipms(1) modules(0)
+ forwarded-report-body-part-type(12)} DEFINITIONS IMPLICIT TAGS ::=
+BEGIN
+
+-- Prologue
+-- Exports everything.
+IMPORTS
+ -- MTS Abstract Service
+ ReportDeliveryArgument
+ --==
+ FROM MTSAbstractService {joint-iso-itu-t mhs(6) mts(3) modules(0)
+ mts-abstract-service(1) version-1999(1)}
+ -- IPMS Information Objects
+ EXTENDED-BODY-PART-TYPE, IPN, MessageParameters
+ --==
+ FROM IPMSInformationObjects {joint-iso-itu-t mhs(6) ipms(1) modules(0)
+ information-objects(2) version-1999(1)}
+ -- IPMS Object Identifiers
+ id-ep-notification, id-et-report, id-et-notification
+ --==
+ FROM IPMSObjectIdentifiers {joint-iso-itu-t mhs(6) ipms(1) modules(0)
+ object-identifiers(0) version-1999(1)};
+
+-- Report body part
+report-body-part EXTENDED-BODY-PART-TYPE ::= {
+ DATA {ReportDeliveryArgument
+ IDENTIFIED BY id-et-report}
+}
+
+-- Notification body part
+notification-body-part EXTENDED-BODY-PART-TYPE ::= {
+ PARAMETERS {MessageParameters
+ IDENTIFIED BY id-ep-notification},
+ DATA {IPN IDENTIFIED BY id-et-notification}
+}
+
+END -- of IPMSForwardedReportBodyPartType
+
+-- Generated by Asnp, the ASN.1 pretty-printer of France Telecom R&D
+
diff --git a/lib/asn1/test/asn1_SUITE_data/x420/IPMSFunctionalObjects.asn b/lib/asn1/test/asn1_SUITE_data/x420/IPMSFunctionalObjects.asn
new file mode 100644
index 0000000000..09ef4de282
--- /dev/null
+++ b/lib/asn1/test/asn1_SUITE_data/x420/IPMSFunctionalObjects.asn
@@ -0,0 +1,47 @@
+-- Module IPMSFunctionalObjects (X.420:06/1999)
+IPMSFunctionalObjects {joint-iso-itu-t mhs(6) ipms(1) modules(0)
+ functional-objects(1) version-1994(0)} DEFINITIONS IMPLICIT TAGS ::=
+BEGIN
+
+-- Prologue
+-- Exports everything.
+IMPORTS
+ -- IPMS Abstract Service
+ management, origination, reception
+ --==
+ FROM IPMSAbstractService {joint-iso-itu-t mhs(6) ipms(1) modules(0)
+ abstract-service(3) version-1994(0)}
+ -- IPMS Object Identifiers
+ id-ot-ipms, id-ot-ipms-user
+ --==
+ FROM IPMSObjectIdentifiers {joint-iso-itu-t mhs(6) ipms(1) modules(0)
+ object-identifiers(0) version-1999(1)}
+ -- MTS Abstract Service
+ MHS-OBJECT
+ --==
+ FROM MTSAbstractService {joint-iso-itu-t mhs(6) mts(3) modules(0)
+ mts-abstract-service(1) version-1999(1)}
+ -- Remote Operations
+ CONTRACT
+ --==
+ FROM Remote-Operations-Information-Objects {joint-iso-itu-t
+ remote-operations(4) informationObjects(5) version1(0)};
+
+-- Primary object types
+ipms-user MHS-OBJECT ::= {
+ INITIATES {ipms-access-contract}
+ ID id-ot-ipms-user
+}
+
+ipms-access-contract CONTRACT ::= {
+ INITIATOR CONSUMER OF {origination | reception | management}
+}
+
+ipms MHS-OBJECT ::= {RESPONDS {ipms-access-contract}
+ ID id-ot-ipms
+}
+
+END -- of IPMSFunctionalObjects
+
+-- Generated by Asnp, the ASN.1 pretty-printer of France Telecom R&D
+
diff --git a/lib/asn1/test/asn1_SUITE_data/x420/IPMSHeadingExtensions.asn b/lib/asn1/test/asn1_SUITE_data/x420/IPMSHeadingExtensions.asn
new file mode 100644
index 0000000000..752e8d05e1
--- /dev/null
+++ b/lib/asn1/test/asn1_SUITE_data/x420/IPMSHeadingExtensions.asn
@@ -0,0 +1,246 @@
+-- Module IPMSHeadingExtensions (X.420:06/1999)
+IPMSHeadingExtensions {joint-iso-itu-t mhs(6) ipms(1) modules(0)
+ heading-extensions(6) version-1999(1)} DEFINITIONS IMPLICIT TAGS ::=
+BEGIN
+
+-- Prologue
+-- Exports everything.
+IMPORTS
+ -- IPMS Information Objects
+ IPMS-EXTENSION, ORDescriptor, RecipientSpecifier, ThisIPMField, BodyPart
+ --==
+ FROM IPMSInformationObjects {joint-iso-itu-t mhs(6) ipms(1) modules(0)
+ information-objects(2) version-1999(1)}
+ -- MTS Abstract Service
+ ExtendedCertificates, SecurityLabel, UniversalOrBMPString{}
+ --==
+ FROM MTSAbstractService {joint-iso-itu-t mhs(6) mts(3) modules(0)
+ mts-abstract-service(1) version-1999(1)}
+ -- Directory Authentication Framework
+ AlgorithmIdentifier, SIGNATURE{}, SIGNED{}
+ --==
+ FROM AuthenticationFramework {joint-iso-itu-t ds(5) module(1)
+ authenticationFramework(7) 3}
+ -- Directory Certificate Extensions
+ CertificateAssertion
+ --==
+ FROM CertificateExtensions {joint-iso-itu-t ds(5) module(1)
+ certificateExtensions(26) 0}
+ -- IPMS upper bounds
+ ub-alpha-code-length, ub-circulation-list-members, ub-distribution-codes,
+ ub-extended-subject-length, ub-information-categories,
+ ub-information-category-length, ub-manual-handling-instruction-length,
+ ub-manual-handling-instructions, ub-originators-reference-length,
+ ub-precedence
+ --==
+ FROM IPMSUpperBounds {joint-iso-itu-t mhs(6) ipms(1) modules(0)
+ upper-bounds(10) version-1999(1)}
+ -- IPMS Object Identifiers
+ id-hex-authorization-time, id-hex-auto-submitted,
+ id-hex-body-part-signatures, id-hex-circulation-list-recipients,
+ id-hex-distribution-codes, id-hex-extended-subject, id-hex-incomplete-copy,
+ id-hex-information-category, id-hex-ipm-security-label, id-hex-languages,
+ id-hex-manual-handling-instructions, id-hex-originators-reference,
+ id-hex-precedence-policy-id, id-rex-circulation-list-indicator,
+ id-rex-precedence
+ --==
+ FROM IPMSObjectIdentifiers {joint-iso-itu-t mhs(6) ipms(1) modules(0)
+ object-identifiers(0) version-1999(1)};
+
+-- Incomplete Copy
+incomplete-copy IPMS-EXTENSION ::= {
+ VALUE IncompleteCopy,
+ IDENTIFIED BY id-hex-incomplete-copy
+}
+
+IncompleteCopy ::= NULL
+
+-- Languages
+languages IPMS-EXTENSION ::= {
+ VALUE SET OF Language,
+ IDENTIFIED BY id-hex-languages
+}
+
+Language ::= PrintableString(SIZE (2 | 5))
+
+-- Auto-submitted
+auto-submitted IPMS-EXTENSION ::= {
+ VALUE AutoSubmitted,
+ IDENTIFIED BY id-hex-auto-submitted
+}
+
+AutoSubmitted ::= ENUMERATED {
+ not-auto-submitted(0), auto-generated(1), auto-replied(2)}
+
+body-part-signatures IPMS-EXTENSION ::= {
+ VALUE BodyPartSignatures,
+ IDENTIFIED BY id-hex-body-part-signatures
+}
+
+BodyPartSignatures ::=
+ SET OF
+ SET {body-part-number BodyPartNumber,
+ body-part-signature BodyPartSignature,
+ originator-certificate-selector [1] CertificateAssertion OPTIONAL,
+ originator-certificates [0] ExtendedCertificates OPTIONAL,
+ ...}
+
+BodyPartNumber ::= INTEGER(1..MAX)
+
+BodyPartSignature ::=
+ SIGNATURE
+ {SEQUENCE {signature-algorithm-identifier AlgorithmIdentifier,
+ body-part BodyPart,
+ body-part-security-label SecurityLabel OPTIONAL
+ }}
+
+ipm-security-label IPMS-EXTENSION ::= {
+ VALUE IPMSecurityLabel,
+ IDENTIFIED BY id-hex-ipm-security-label
+}
+
+IPMSecurityLabel ::= SEQUENCE {
+ content-security-label [0] SecurityLabel,
+ heading-security-label [1] SecurityLabel OPTIONAL,
+ body-part-security-labels [2] SEQUENCE OF BodyPartSecurityLabel OPTIONAL
+}
+
+BodyPartSecurityLabel ::= CHOICE {
+ body-part-unlabelled [0] NULL,
+ body-part-security-label [1] SecurityLabel
+}
+
+-- Authorization Time
+authorization-time IPMS-EXTENSION ::= {
+ VALUE AuthorizationTime,
+ IDENTIFIED BY id-hex-authorization-time
+}
+
+AuthorizationTime ::= GeneralizedTime
+
+-- Circulation List
+circulation-list-recipients IPMS-EXTENSION ::= {
+ VALUE CirculationList,
+ IDENTIFIED BY id-hex-circulation-list-recipients
+}
+
+CirculationList ::=
+ SEQUENCE (SIZE (2..ub-circulation-list-members)) OF CirculationMember
+
+CirculationMember ::= SET {
+ circulation-recipient
+ RecipientSpecifier
+ (WITH COMPONENTS {
+ ...,
+ recipient (WITH COMPONENTS {
+ ...,
+ formal-name PRESENT
+ })
+ }),
+ checked Checkmark OPTIONAL
+}
+
+Checkmark ::= CHOICE {
+ simple NULL,
+ timestamped CirculationTime,
+ signed CirculationSignature
+}
+
+CirculationTime ::= GeneralizedTime
+
+CirculationSignature ::=
+ SIGNED
+ {SEQUENCE {algorithm-identifier CirculationSignatureAlgorithmIdentifier,
+ this-IPM ThisIPMField,
+ timestamp CirculationTime}}
+
+CirculationSignatureAlgorithmIdentifier ::= AlgorithmIdentifier
+
+-- Circulation List Indicator
+circulation-list-indicator IPMS-EXTENSION ::= {
+ VALUE NULL,
+ IDENTIFIED BY id-rex-circulation-list-indicator
+}
+
+-- Distribution Codes
+distribution-codes IPMS-EXTENSION ::= {
+ VALUE DistributionCodes,
+ IDENTIFIED BY id-hex-distribution-codes
+}
+
+DistributionCodes ::=
+ SEQUENCE (SIZE (1..ub-distribution-codes)) OF DistributionCode
+
+DistributionCode ::= SEQUENCE {
+ oid-code OBJECT IDENTIFIER OPTIONAL,
+ alphanumeric-code AlphaCode OPTIONAL,
+ or-descriptor [0] ORDescriptor OPTIONAL
+}
+
+AlphaCode ::= UniversalOrBMPString{ub-alpha-code-length}
+
+-- Extended Subject
+extended-subject IPMS-EXTENSION ::= {
+ VALUE ExtendedSubject,
+ IDENTIFIED BY id-hex-extended-subject
+}
+
+ExtendedSubject ::= UniversalOrBMPString{ub-extended-subject-length}
+
+-- Information category
+information-category IPMS-EXTENSION ::= {
+ VALUE InformationCategories,
+ IDENTIFIED BY id-hex-information-category
+}
+
+InformationCategories ::=
+ SEQUENCE (SIZE (1..ub-information-categories)) OF InformationCategory
+
+InformationCategory ::= SEQUENCE {
+ reference [0] OBJECT IDENTIFIER OPTIONAL,
+ description [1] DescriptionString OPTIONAL
+}
+
+DescriptionString ::= UniversalOrBMPString{ub-information-category-length}
+
+-- Manual handling Instructions
+manual-handling-instructions IPMS-EXTENSION ::= {
+ VALUE ManualHandlingInstructions,
+ IDENTIFIED BY id-hex-manual-handling-instructions
+}
+
+ManualHandlingInstructions ::=
+ SEQUENCE (SIZE (1..ub-manual-handling-instructions)) OF
+ ManualHandlingInstruction
+
+ManualHandlingInstruction ::=
+ UniversalOrBMPString{ub-manual-handling-instruction-length}
+
+-- Originator's Reference
+originators-reference IPMS-EXTENSION ::= {
+ VALUE OriginatorsReference,
+ IDENTIFIED BY id-hex-originators-reference
+}
+
+OriginatorsReference ::= UniversalOrBMPString{ub-originators-reference-length}
+
+-- Precedence Policy Identifier
+precedence-policy-identifier IPMS-EXTENSION ::= {
+ VALUE PrecedencePolicyIdentifier,
+ IDENTIFIED BY id-hex-precedence-policy-id
+}
+
+PrecedencePolicyIdentifier ::= OBJECT IDENTIFIER
+
+-- Precedence
+precedence IPMS-EXTENSION ::= {
+ VALUE Precedence,
+ IDENTIFIED BY id-rex-precedence
+}
+
+Precedence ::= INTEGER(0..ub-precedence)
+
+END -- of IPMSHeadingExtensions
+
+-- Generated by Asnp, the ASN.1 pretty-printer of France Telecom R&D
+
diff --git a/lib/asn1/test/asn1_SUITE_data/x420/IPMSInformationObjects.asn b/lib/asn1/test/asn1_SUITE_data/x420/IPMSInformationObjects.asn
new file mode 100644
index 0000000000..3fb0463ee7
--- /dev/null
+++ b/lib/asn1/test/asn1_SUITE_data/x420/IPMSInformationObjects.asn
@@ -0,0 +1,626 @@
+-- Module IPMSInformationObjects (X.420:06/1999)
+IPMSInformationObjects {joint-iso-itu-t mhs(6) ipms(1) modules(0)
+ information-objects(2) version-1999(1)} DEFINITIONS IMPLICIT TAGS ::=
+BEGIN
+
+-- Prologue
+-- Exports everything.
+IMPORTS
+ -- IPMS Extended Body Parts
+ bilaterally-defined-body-part, encrypted-body-part, g3-facsimile-body-part,
+ g4-class1-body-part, ia5-text-body-part, message-body-part,
+ mixed-mode-body-part, nationally-defined-body-part, teletex-body-part,
+ videotex-body-part
+ --==
+ FROM IPMSExtendedBodyPartTypes {joint-iso-itu-t mhs(6) ipms(1) modules(0)
+ extended-body-part-types(7) version-1994(0)}
+ general-text-body-part
+ --==
+ FROM IPMSExtendedBodyPartTypes2 {iso standard mhs(10021) ipms(7)
+ modules(0) extended-body-part-types-2(1)}
+ file-transfer-body-part
+ --==
+ FROM IPMSFileTransferBodyPartType {joint-iso-itu-t mhs(6) ipms(1)
+ modules(0) file-transfer-body-part-type(9)}
+ voice-body-part
+ --==
+ FROM IPMSExtendedVoiceBodyPartType {joint-iso-itu-t mhs(6) ipms(1)
+ modules(0) extended-voice-body-part-type(11)}
+ notification-body-part, report-body-part
+ --==
+ FROM IPMSForwardedReportBodyPartType {joint-iso-itu-t mhs(6) ipms(1)
+ modules(0) forwarded-report-body-part-type(12)}
+ content-body-part{}
+ --==
+ FROM IPMSForwardedContentBodyPartType {joint-iso-itu-t mhs(6) ipms(1)
+ modules(0) forwarded-content-body-part-type(15)}
+ pkcs7-body-part
+ --==
+ FROM PKCS7BodyPartType {joint-iso-itu-t mhs(6) ipms(1) modules(0)
+ pkcs7-body-part-type(16)}
+ -- IPMS Heading Extensions
+ authorization-time, auto-submitted, body-part-signatures,
+ circulation-list-indicator, circulation-list-recipients,
+ distribution-codes, extended-subject, incomplete-copy,
+ information-category, ipm-security-label, languages,
+ manual-handling-instructions, originators-reference, precedence,
+ precedence-policy-identifier
+ --==
+ FROM IPMSHeadingExtensions {joint-iso-itu-t mhs(6) ipms(1) modules(0)
+ heading-extensions(6) version-1999(1)}
+ -- IPMS Security Extensions
+ body-part-encryption-token, BodyPartTokens, forwarded-content-token,
+ ForwardedContentToken, ipn-security-response, recipient-security-request
+ --==
+ FROM IPMSSecurityExtensions {joint-iso-itu-t mhs(6) ipms(1) modules(0)
+ ipm-security-extensions(14) version-1999(1)}
+ -- IPMS Upper bounds
+ ub-auto-forward-comment, ub-free-form-name, ub-local-ipm-identifier,
+ ub-subject-field, ub-telephone-number
+ --==
+ FROM IPMSUpperBounds {joint-iso-itu-t mhs(6) ipms(1) modules(0)
+ upper-bounds(10) version-1999(1)}
+ -- ODIF
+ Interchange-Data-Element
+ --==
+ FROM Interchange-Data-Elements {2 8 1 5 5}
+ -- MTS Abstract Service
+ EncodedInformationTypes, ExtendedCertificates, EXTENSION,
+ G3FacsimileNonBasicParameters, MessageDeliveryTime, ORName,
+ OtherMessageDeliveryFields, SupplementaryInformation,
+ TeletexNonBasicParameters
+ --==
+ FROM MTSAbstractService {joint-iso-itu-t mhs(6) mts(3) modules(0)
+ mts-abstract-service(1) version-1999(1)}
+ -- MS Abstract Service
+ MS-EXTENSION, SequenceNumber
+ --==
+ FROM MSAbstractService {joint-iso-itu-t mhs(6) ms(4) modules(0)
+ abstract-service(1) version-1999(1)}
+ -- Directory Authentication Framework
+ AlgorithmIdentifier, ENCRYPTED{}
+ --==
+ FROM AuthenticationFramework {joint-iso-itu-t ds(5) module(1)
+ authenticationFramework(7) 3}
+ -- IPMS Object Identifiers
+ id-mst-assembly-capability, id-mst-assembly-instructions,
+ id-mst-invalid-assembly-instructions, id-mst-invalid-ipn,
+ id-mst-originator-body-part-encryption-token,
+ id-mst-originator-forwarded-content-token,
+ id-mst-suspend-auto-acknowledgement, id-mst-prevent-nrn-generation,
+ id-on-absence-advice, id-on-change-of-address-advice
+ --==
+ FROM IPMSObjectIdentifiers {joint-iso-itu-t mhs(6) ipms(1) modules(0)
+ object-identifiers(0) version-1999(1)};
+
+Time ::= UTCTime
+
+-- Information object
+InformationObject ::= CHOICE {ipm [0] IPM,
+ ipn [1] IPN
+}
+
+-- IPM
+IPM ::= SEQUENCE {heading Heading,
+ body Body
+}
+
+-- MTS Extensions
+IPMPerRecipientEnvelopeExtensions EXTENSION ::=
+ {blind-copy-recipients | body-part-encryption-token |
+ forwarded-content-token, ...}
+
+-- IPMS Extensions
+IPMSExtension{IPMS-EXTENSION:ChosenFrom} ::= SEQUENCE {
+ type IPMS-EXTENSION.&id({ChosenFrom}),
+ value IPMS-EXTENSION.&Type({ChosenFrom}{@type}) DEFAULT NULL:NULL
+}
+
+IPMS-EXTENSION ::= CLASS {&id OBJECT IDENTIFIER UNIQUE,
+ &Type DEFAULT NULL
+}WITH SYNTAX {[VALUE &Type,]
+ IDENTIFIED BY &id
+}
+
+PrivateIPMSExtensions IPMS-EXTENSION ::=
+ {...}
+
+-- Heading
+Heading ::= SET {
+ this-IPM ThisIPMField,
+ originator [0] OriginatorField OPTIONAL,
+ authorizing-users [1] AuthorizingUsersField OPTIONAL,
+ primary-recipients [2] PrimaryRecipientsField DEFAULT {},
+ copy-recipients [3] CopyRecipientsField DEFAULT {},
+ blind-copy-recipients [4] BlindCopyRecipientsField OPTIONAL,
+ replied-to-IPM [5] RepliedToIPMField OPTIONAL,
+ obsoleted-IPMs [6] ObsoletedIPMsField DEFAULT {},
+ related-IPMs [7] RelatedIPMsField DEFAULT {},
+ subject [8] EXPLICIT SubjectField OPTIONAL,
+ expiry-time [9] ExpiryTimeField OPTIONAL,
+ reply-time [10] ReplyTimeField OPTIONAL,
+ reply-recipients [11] ReplyRecipientsField OPTIONAL,
+ importance [12] ImportanceField DEFAULT normal,
+ sensitivity [13] SensitivityField OPTIONAL,
+ auto-forwarded [14] AutoForwardedField DEFAULT FALSE,
+ extensions [15] ExtensionsField DEFAULT {}
+}
+
+-- Heading component types
+IPMIdentifier ::= [APPLICATION 11] SET {
+ user ORName OPTIONAL,
+ user-relative-identifier LocalIPMIdentifier
+}
+
+LocalIPMIdentifier ::= PrintableString(SIZE (0..ub-local-ipm-identifier))
+
+RecipientSpecifier ::= SET {
+ recipient [0] ORDescriptor,
+ notification-requests [1] NotificationRequests DEFAULT {},
+ reply-requested [2] BOOLEAN DEFAULT FALSE,
+ recipient-extensions [3] RecipientExtensionsField OPTIONAL
+}
+
+ORDescriptor ::= SET {
+ formal-name ORName OPTIONAL,
+ free-form-name [0] FreeFormName OPTIONAL,
+ telephone-number [1] TelephoneNumber OPTIONAL
+}
+
+FreeFormName ::= TeletexString(SIZE (0..ub-free-form-name))
+
+TelephoneNumber ::= PrintableString(SIZE (0..ub-telephone-number))
+
+NotificationRequests ::= BIT STRING {
+ rn(0), nrn(1), ipm-return(2), an-supported(3), suppress-an(4)}
+
+RecipientExtensionsField ::= SET OF IPMSExtension{{RecipientExtensions}}
+
+RecipientExtensions IPMS-EXTENSION ::=
+ {circulation-list-indicator | precedence | recipient-security-request |
+ PrivateIPMSExtensions, ...}
+
+-- This IPM heading field
+ThisIPMField ::= IPMIdentifier
+
+-- Originator heading field
+OriginatorField ::= ORDescriptor
+
+-- Authorizing Users heading field
+AuthorizingUsersField ::= SEQUENCE OF AuthorizingUsersSubfield
+
+AuthorizingUsersSubfield ::= ORDescriptor
+
+-- Primary Recipients heading field
+PrimaryRecipientsField ::= SEQUENCE OF PrimaryRecipientsSubfield
+
+PrimaryRecipientsSubfield ::= RecipientSpecifier
+
+-- Copy Recipients heading field
+CopyRecipientsField ::= SEQUENCE OF CopyRecipientsSubfield
+
+CopyRecipientsSubfield ::= RecipientSpecifier
+
+-- Blind Copy Recipients heading field
+BlindCopyRecipientsField ::= SEQUENCE OF BlindCopyRecipientsSubfield
+
+BlindCopyRecipientsSubfield ::= RecipientSpecifier
+
+-- Blind Copy Recipients envelope field
+blind-copy-recipients EXTENSION ::= {
+ BlindCopyRecipientsField,
+ IDENTIFIED BY standard-extension:41
+}
+
+-- Replied-to IPM heading field
+RepliedToIPMField ::= IPMIdentifier
+
+-- Obsoleted IPMs heading field
+ObsoletedIPMsField ::= SEQUENCE OF ObsoletedIPMsSubfield
+
+ObsoletedIPMsSubfield ::= IPMIdentifier
+
+-- Related IPMs heading field
+RelatedIPMsField ::= SEQUENCE OF RelatedIPMsSubfield
+
+RelatedIPMsSubfield ::= IPMIdentifier
+
+-- Subject heading field
+SubjectField ::= TeletexString(SIZE (0..ub-subject-field))
+
+-- Expiry Time heading field
+ExpiryTimeField ::= Time
+
+-- Reply Time heading field
+ReplyTimeField ::= Time
+
+-- Reply Recipients heading field
+ReplyRecipientsField ::= SEQUENCE OF ReplyRecipientsSubfield
+
+ReplyRecipientsSubfield ::=
+ ORDescriptor(WITH COMPONENTS {
+ ...,
+ formal-name PRESENT
+ })
+
+-- Importance heading field
+ImportanceField ::= ENUMERATED {low(0), normal(1), high(2)}
+
+-- Sensitivity heading field
+SensitivityField ::= ENUMERATED {
+ personal(1), private(2), company-confidential(3)}
+
+-- Auto-forwarded heading field
+AutoForwardedField ::= BOOLEAN
+
+-- Extensions heading field
+ExtensionsField ::= SET OF IPMSExtension{{HeadingExtensions}}
+
+HeadingExtensions IPMS-EXTENSION ::=
+ {authorization-time | auto-submitted | body-part-signatures |
+ circulation-list-recipients | distribution-codes | extended-subject |
+ incomplete-copy | information-category | ipm-security-label | languages |
+ manual-handling-instructions | originators-reference |
+ precedence-policy-identifier | PrivateIPMSExtensions, ...}
+
+-- Body
+Body ::= SEQUENCE OF BodyPart
+
+BodyPart ::= CHOICE {
+ basic
+ CHOICE {ia5-text [0] IA5TextBodyPart,
+ g3-facsimile [3] G3FacsimileBodyPart,
+ g4-class1 [4] G4Class1BodyPart,
+ teletex [5] TeletexBodyPart,
+ videotex [6] VideotexBodyPart,
+ encrypted [8] EncryptedBodyPart,
+ message [9] MessageBodyPart,
+ mixed-mode [11] MixedModeBodyPart,
+ bilaterally-defined [14] BilaterallyDefinedBodyPart,
+ nationally-defined [7] NationallyDefinedBodyPart},
+ extended [15] ExtendedBodyPart{{IPMBodyPartTable}}
+}
+
+-- Extended body part
+ExtendedBodyPart{EXTENDED-BODY-PART-TYPE:IPMBodyPartTable} ::= SEQUENCE {
+ parameters [0] INSTANCE OF TYPE-IDENTIFIER OPTIONAL,
+ data INSTANCE OF TYPE-IDENTIFIER
+}
+(CONSTRAINED BY { -- must correspond to the &parameters field and &data field of a member of --
+ IPMBodyPartTable})
+
+IPMBodyPartTable EXTENDED-BODY-PART-TYPE ::=
+ {StandardBodyParts | ApplicationSpecificBodyParts}
+
+StandardBodyParts EXTENDED-BODY-PART-TYPE ::=
+ {ia5-text-body-part | g3-facsimile-body-part | g4-class1-body-part |
+ teletex-body-part | videotex-body-part | encrypted-body-part |
+ message-body-part | mixed-mode-body-part | bilaterally-defined-body-part |
+ nationally-defined-body-part | general-text-body-part |
+ file-transfer-body-part | voice-body-part | report-body-part |
+ notification-body-part |
+ content-body-part{{1 2 3 -- RELATIVE-OID to be provided --}} |
+ pkcs7-body-part, ...}
+
+ApplicationSpecificBodyParts EXTENDED-BODY-PART-TYPE ::=
+ {--any body part defined in other Specifications, or for proprietary or private use
+ ...}
+
+EXTENDED-BODY-PART-TYPE ::= CLASS {
+ &parameters TYPE-IDENTIFIER OPTIONAL,
+ &data TYPE-IDENTIFIER
+}WITH SYNTAX {[PARAMETERS &parameters,]
+ DATA &data
+}
+
+-- IA5 Text body part
+IA5TextBodyPart ::= SEQUENCE {
+ parameters IA5TextParameters,
+ data IA5TextData
+}
+
+IA5TextParameters ::= SET {repertoire [0] Repertoire DEFAULT ia5
+}
+
+IA5TextData ::= IA5String
+
+Repertoire ::= ENUMERATED {ita2(2), ia5(5)}
+
+-- G3 Facsimile body part
+G3FacsimileBodyPart ::= SEQUENCE {
+ parameters G3FacsimileParameters,
+ data G3FacsimileData
+}
+
+G3FacsimileParameters ::= SET {
+ number-of-pages [0] INTEGER OPTIONAL,
+ non-basic-parameters [1] G3FacsimileNonBasicParameters OPTIONAL
+}
+
+G3FacsimileData ::= SEQUENCE OF BIT STRING
+
+-- G4 Class 1 and Mixed-mode body parts
+G4Class1BodyPart ::= SEQUENCE OF Interchange-Data-Element
+
+MixedModeBodyPart ::= SEQUENCE OF Interchange-Data-Element
+
+-- Teletex body part
+TeletexBodyPart ::= SEQUENCE {
+ parameters TeletexParameters,
+ data TeletexData
+}
+
+TeletexParameters ::= SET {
+ number-of-pages [0] INTEGER OPTIONAL,
+ telex-compatible [1] BOOLEAN DEFAULT FALSE,
+ non-basic-parameters [2] TeletexNonBasicParameters OPTIONAL
+}
+
+TeletexData ::= SEQUENCE OF TeletexString
+
+-- Videotex body part
+VideotexBodyPart ::= SEQUENCE {
+ parameters VideotexParameters,
+ data VideotexData
+}
+
+VideotexParameters ::= SET {syntax [0] VideotexSyntax OPTIONAL
+}
+
+VideotexSyntax ::= INTEGER {
+ ids(0), data-syntax1(1), data-syntax2(2), data-syntax3(3)}
+
+VideotexData ::= VideotexString
+
+-- Encrypted body part
+EncryptedBodyPart ::= SEQUENCE {
+ parameters EncryptedParameters,
+ data EncryptedData
+}
+
+EncryptedParameters ::= SET {
+ algorithm-identifier AlgorithmIdentifier,
+ originator-certificates ExtendedCertificates OPTIONAL,
+ ...
+}
+
+EncryptedData ::= BIT STRING(CONSTRAINED BY {BodyPart})
+
+-- Message body part
+MessageBodyPart ::= SEQUENCE {
+ parameters MessageParameters,
+ data MessageData
+}
+
+MessageParameters ::= SET {
+ delivery-time [0] MessageDeliveryTime OPTIONAL,
+ delivery-envelope [1] OtherMessageDeliveryFields OPTIONAL
+}
+
+MessageData ::= IPM
+
+-- Bilaterally Defined body part
+BilaterallyDefinedBodyPart ::= OCTET STRING
+
+-- Nationally Defined body part
+NATIONAL-BODY-PARTS ::= CLASS {&Type
+}
+
+NationallyDefinedBodyPart ::= NATIONAL-BODY-PARTS.&Type
+
+-- Provided for Historic reasons. Use is strongly deprecated.
+-- IPN
+IPN ::= SET {
+ -- common-fields --COMPONENTS OF CommonFields,
+ choice
+ [0] CHOICE {non-receipt-fields [0] NonReceiptFields,
+ receipt-fields [1] ReceiptFields,
+ other-notification-type-fields
+ [2] OtherNotificationTypeFields}
+}
+
+RN ::=
+ IPN
+ (WITH COMPONENTS {
+ ...,
+ choice (WITH COMPONENTS {
+ receipt-fields PRESENT
+ })
+ })
+
+NRN ::=
+ IPN
+ (WITH COMPONENTS {
+ ...,
+ choice (WITH COMPONENTS {
+ non-receipt-fields PRESENT
+ })
+ })
+
+ON ::=
+ IPN
+ (WITH COMPONENTS {
+ ...,
+ choice (WITH COMPONENTS {
+ other-notification-type-fields PRESENT
+ })
+ })
+
+CommonFields ::= SET {
+ subject-ipm SubjectIPMField,
+ ipn-originator [1] IPNOriginatorField OPTIONAL,
+ ipm-intended-recipient [2] IPMIntendedRecipientField OPTIONAL,
+ conversion-eits ConversionEITsField OPTIONAL,
+ notification-extensions [3] NotificationExtensionsField OPTIONAL
+}
+
+NonReceiptFields ::= SET {
+ non-receipt-reason [0] NonReceiptReasonField,
+ discard-reason [1] DiscardReasonField OPTIONAL,
+ auto-forward-comment [2] AutoForwardCommentField OPTIONAL,
+ returned-ipm [3] ReturnedIPMField OPTIONAL,
+ nrn-extensions [4] NRNExtensionsField OPTIONAL
+}
+
+ReceiptFields ::= SET {
+ receipt-time [0] ReceiptTimeField,
+ acknowledgment-mode [1] AcknowledgmentModeField DEFAULT manual,
+ suppl-receipt-info [2] SupplReceiptInfoField OPTIONAL,
+ rn-extensions [3] RNExtensionsField OPTIONAL
+}
+
+-- Common fields
+SubjectIPMField ::= IPMIdentifier
+
+IPNOriginatorField ::= ORDescriptor
+
+IPMIntendedRecipientField ::= ORDescriptor
+
+ConversionEITsField ::= EncodedInformationTypes
+
+NotificationExtensionsField ::= SET OF IPMSExtension{{NotificationExtensions}}
+
+NotificationExtensions IPMS-EXTENSION ::=
+ {ipn-security-response | PrivateIPMSExtensions, ...}
+
+-- Non-receipt fields
+NonReceiptReasonField ::= ENUMERATED {
+ ipm-discarded(0), ipm-auto-forwarded(1), ...
+ }
+
+-- ITU-T version:
+DiscardReasonField ::= ENUMERATED {
+ ipm-expired(0), ipm-obsoleted(1), user-subscription-terminated(2),
+ not-used(3)}
+
+-- ISO/IEC version:
+--DiscardReasonField ::= ENUMERATED {
+-- ipm-expired (0),
+-- ipm-obsoleted (1),
+-- user-subscription-terminated (2),
+-- The following value may not be supported by implementations of earlier versions of this Specification
+-- ipm-deleted (3),
+-- ... }
+AutoForwardCommentField ::=
+ AutoForwardComment
+
+AutoForwardComment ::= PrintableString(SIZE (0..ub-auto-forward-comment))
+
+ReturnedIPMField ::= IPM
+
+NRNExtensionsField ::= SET OF IPMSExtension{{NRNExtensions}}
+
+NRNExtensions IPMS-EXTENSION ::= {PrivateIPMSExtensions, ...}
+
+-- Receipt fields
+ReceiptTimeField ::= Time
+
+AcknowledgmentModeField ::= ENUMERATED {manual(0), automatic(1)}
+
+SupplReceiptInfoField ::= SupplementaryInformation
+
+RNExtensionsField ::= SET OF IPMSExtension{{RNExtensions}}
+
+RNExtensions IPMS-EXTENSION ::= {PrivateIPMSExtensions, ...}
+
+-- Other Notification Type fields
+OtherNotificationTypeFields ::= SET OF IPMSExtension{{OtherNotifications}}
+
+OtherNotifications IPMS-EXTENSION ::=
+ {AdviceNotifications | PrivateIPMSExtensions, ...}
+
+AdviceNotifications IPMS-EXTENSION ::=
+ {absence-advice | change-of-address-advice, ...}
+
+-- Advice Notification fields
+absence-advice IPMS-EXTENSION ::= {
+ VALUE AbsenceAdvice,
+ IDENTIFIED BY id-on-absence-advice
+}
+
+AbsenceAdvice ::= SEQUENCE {
+ advice BodyPart OPTIONAL,
+ next-available Time OPTIONAL
+}
+
+-- at least one component shall be present
+change-of-address-advice IPMS-EXTENSION ::= {
+ VALUE ChangeOfAddressAdvice,
+ IDENTIFIED BY id-on-change-of-address-advice
+}
+
+ChangeOfAddressAdvice ::= SEQUENCE {
+ new-address
+ [0] ORDescriptor(WITH COMPONENTS {
+ ...,
+ formal-name PRESENT
+ }),
+ effective-from [1] Time OPTIONAL
+}
+
+-- Message Store Realization
+prevent-nrn-generation MS-EXTENSION ::= {
+ NULL
+ IDENTIFIED BY id-mst-prevent-nrn-generation
+}
+
+suspend-auto-acknowledgement MS-EXTENSION ::= {
+ NULL
+ IDENTIFIED BY id-mst-suspend-auto-acknowledgement
+}
+
+assembly-capability MS-EXTENSION ::= {
+ NULL
+ IDENTIFIED BY id-mst-assembly-capability
+}
+
+IPMSubmissionOptions MS-EXTENSION ::=
+ {ipm-assembly-instructions | originator-body-part-encryption-token |
+ originator-forwarded-content-token, ...} -- For future extension additions
+
+ipm-assembly-instructions MS-EXTENSION ::= {
+ IPMAssemblyInstructions
+ IDENTIFIED BY id-mst-assembly-instructions
+}
+
+IPMAssemblyInstructions ::= SET {assembly-instructions [0] BodyPartReferences
+}
+
+BodyPartReferences ::= SEQUENCE OF BodyPartReference
+
+BodyPartReference ::= CHOICE {
+ stored-entry [0] SequenceNumber,
+ stored-content [1] SequenceNumber,
+ submitted-body-part [2] INTEGER(1..MAX),
+ stored-body-part
+ [3] SEQUENCE {message-entry SequenceNumber,
+ body-part-number INTEGER(1..MAX)}
+}
+
+originator-body-part-encryption-token MS-EXTENSION ::= {
+ BodyPartTokens
+ IDENTIFIED BY id-mst-originator-body-part-encryption-token
+}
+
+originator-forwarded-content-token MS-EXTENSION ::= {
+ ForwardedContentToken
+ IDENTIFIED BY id-mst-originator-forwarded-content-token
+}
+
+IPMSubmissionErrors MS-EXTENSION ::=
+ {invalid-assembly-instructions | invalid-ipn, ...
+ } -- For future extension additions
+
+invalid-assembly-instructions MS-EXTENSION ::= {
+ BodyPartReferences
+ IDENTIFIED BY id-mst-invalid-assembly-instructions
+}
+
+invalid-ipn MS-EXTENSION ::= {NULL
+ IDENTIFIED BY id-mst-invalid-ipn
+}
+
+END -- of IPMSInformationObjects
+
+-- Generated by Asnp, the ASN.1 pretty-printer of France Telecom R&D
+
diff --git a/lib/asn1/test/asn1_SUITE_data/x420/IPMSMessageStoreAttributes.asn b/lib/asn1/test/asn1_SUITE_data/x420/IPMSMessageStoreAttributes.asn
new file mode 100644
index 0000000000..719bca4987
--- /dev/null
+++ b/lib/asn1/test/asn1_SUITE_data/x420/IPMSMessageStoreAttributes.asn
@@ -0,0 +1,1120 @@
+-- Module IPMSMessageStoreAttributes (X.420:06/1999)
+IPMSMessageStoreAttributes {joint-iso-itu-t mhs(6) ipms(1) modules(0)
+ message-store-attributes(8) version-1999(1)} DEFINITIONS IMPLICIT TAGS ::=
+BEGIN
+
+-- Prologue
+-- Exports everything.
+IMPORTS
+ -- IPMS Heading Extensions
+ AuthorizationTime, AutoSubmitted, BodyPartNumber, BodyPartSecurityLabel,
+ BodyPartSignatures, CirculationMember, DistributionCode, ExtendedSubject,
+ IncompleteCopy, InformationCategory, IPMSecurityLabel, Language,
+ ManualHandlingInstruction, OriginatorsReference, Precedence,
+ PrecedencePolicyIdentifier
+ --==
+ FROM IPMSHeadingExtensions {joint-iso-itu-t mhs(6) ipms(1) modules(0)
+ heading-extensions(6) version-1999(1)}
+ -- IPMS Security Extensions
+ BodyPartTokens, ForwardedContentToken
+ --==
+ FROM IPMSSecurityExtensions {joint-iso-itu-t mhs(6) ipms(1) modules(0)
+ ipm-security-extensions(14) version-1999(1)}
+ -- IPMS Information Objects
+ AcknowledgmentModeField, AuthorizingUsersSubfield, AutoForwardCommentField,
+ AutoForwardedField, BilaterallyDefinedBodyPart,
+ BlindCopyRecipientsSubfield, Body, ConversionEITsField,
+ CopyRecipientsSubfield, DiscardReasonField, EncryptedBodyPart,
+ EncryptedData, EncryptedParameters, ExpiryTimeField,
+ EXTENDED-BODY-PART-TYPE, G3FacsimileBodyPart, G3FacsimileData,
+ G3FacsimileParameters, G4Class1BodyPart, Heading, IA5TextBodyPart,
+ IA5TextData, IA5TextParameters, ImportanceField, IPMIdentifier,
+ IPMIntendedRecipientField, IPMSExtension{}, IPNOriginatorField,
+ MessageBodyPart, MessageData, MessageParameters, MixedModeBodyPart,
+ NationallyDefinedBodyPart, NonReceiptReasonField, NotificationExtensions,
+ NRNExtensions, ObsoletedIPMsSubfield, ORDescriptor, OriginatorField,
+ OtherNotifications, PrimaryRecipientsSubfield, ReceiptTimeField,
+ RecipientSpecifier, RelatedIPMsSubfield, RepliedToIPMField,
+ ReplyRecipientsSubfield, ReplyTimeField, ReturnedIPMField, RNExtensions,
+ SensitivityField, SubjectField, SubjectIPMField, SupplReceiptInfoField,
+ TeletexBodyPart, TeletexData, TeletexParameters, ThisIPMField,
+ VideotexBodyPart, VideotexData, VideotexParameters
+ --==
+ FROM IPMSInformationObjects {joint-iso-itu-t mhs(6) ipms(1) modules(0)
+ information-objects(2) version-1999(1)}
+ -- IPMS Object Identifiers
+ id-bat-bilaterally-defined-body-parts, id-bat-body,
+ id-bat-encrypted-body-parts, id-bat-encrypted-data,
+ id-bat-encrypted-parameters, id-bat-extended-body-part-types,
+ id-bat-g3-facsimile-body-parts, id-bat-g3-facsimile-data,
+ id-bat-g3-facsimile-parameters, id-bat-g4-class1-body-parts,
+ id-bat-ia5-text-body-parts, id-bat-ia5-text-data,
+ id-bat-ia5-text-parameters, id-bat-message-body-parts, id-bat-message-data,
+ id-bat-message-parameters, id-bat-mixed-mode-body-parts,
+ id-bat-nationally-defined-body-parts, id-bat-teletex-body-parts,
+ id-bat-teletex-data, id-bat-teletex-parameters, id-bat-videotex-body-parts,
+ id-bat-videotex-data, id-bat-videotex-parameters,
+ id-cat-correlated-delivered-ipns, id-cat-correlated-delivered-replies,
+ id-cat-delivered-ipn-summary, id-cat-delivered-replies-summary,
+ id-cat-forwarded-ipms, id-cat-forwarding-ipms, id-cat-ipm-recipients,
+ id-cat-obsoleted-ipms, id-cat-obsoleting-ipms, id-cat-related-ipms,
+ id-cat-relating-ipms, id-cat-replied-to-ipm, id-cat-recipient-category,
+ id-cat-replying-ipms, id-cat-revised-reply-time, id-cat-subject-ipm,
+ id-cat-submitted-ipn-status, id-cat-submitted-ipns,
+ id-cat-submitted-reply-status, id-hat-authorization-time,
+ id-hat-authorizing-users, id-hat-auto-forwarded, id-hat-auto-submitted,
+ id-hat-blind-copy-recipients, id-hat-body-part-encryption-token,
+ id-hat-body-part-security-label,
+ id-hat-body-part-signature-verification-status,
+ id-hat-body-part-signatures, id-hat-circulation-list-recipients,
+ id-hat-copy-recipients, id-hat-distribution-codes, id-hat-expiry-time,
+ id-hat-extended-subject, id-hat-forwarded-content-token,
+ id-hat-forwarding-token, id-hat-heading, id-hat-importance,
+ id-hat-incomplete-copy, id-hat-information-category,
+ id-hat-ipm-security-label, id-hat-languages,
+ id-hat-manual-handling-instructions, id-hat-nrn-requestors,
+ id-hat-obsoleted-IPMs, id-hat-originator, id-hat-originators-reference,
+ id-hat-precedence, id-hat-precedence-policy-id, id-hat-primary-recipients,
+ id-hat-related-IPMs, id-hat-replied-to-IPM, id-hat-reply-recipients,
+ id-hat-reply-requestors, id-hat-reply-time, id-hat-rn-requestors,
+ id-hat-sensitivity, id-hat-subject, id-hat-this-ipm, id-mr-ipm-identifier,
+ id-mr-ipm-location, id-mr-or-descriptor, id-mr-or-descriptor-elements,
+ id-mr-or-descriptor-single-element, id-mr-or-descriptor-substring-elements,
+ id-mr-circulation-member, id-mr-circulation-member-checkmark,
+ id-mr-circulation-member-elements, id-mr-circulation-member-single-element,
+ id-mr-circulation-member-substring-elements, id-mr-distribution-code,
+ id-mr-information-category, id-mr-recipient-specifier,
+ id-mr-recipient-specifier-elements,
+ id-mr-recipient-specifier-single-element,
+ id-mr-recipient-specifier-substring-elements, id-nat-acknowledgment-mode,
+ id-nat-auto-forward-comment, id-nat-conversion-eits, id-nat-discard-reason,
+ id-nat-ipm-intended-recipient, id-nat-ipn-originator,
+ id-nat-non-receipt-reason, id-nat-notification-extensions,
+ id-nat-nrn-extensions, id-nat-other-notification-type-fields,
+ id-nat-receipt-time, id-nat-returned-ipm, id-nat-rn-extensions,
+ id-nat-subject-ipm, id-nat-suppl-receipt-info, id-sat-body-parts-summary,
+ id-sat-ipm-auto-discarded, id-sat-ipm-entry-type, id-sat-ipm-synopsis
+ --==
+ FROM IPMSObjectIdentifiers {joint-iso-itu-t mhs(6) ipms(1) modules(0)
+ object-identifiers(0) version-1999(1)}
+ -- MS Abstract Service
+ X413ATTRIBUTE, MS-EIT, SequenceNumber
+ --==
+ FROM MSAbstractService {joint-iso-itu-t mhs(6) ms(4) modules(0)
+ abstract-service(1) version-1999(1)}
+ -- MS General Attribute Types
+ SignatureStatus
+ --==
+ FROM MSGeneralAttributeTypes {joint-iso-itu-t mhs(6) ms(4) modules(0)
+ general-attribute-types(2) version-1999(1)}
+ -- MS matching-rules
+ MSString{}, mSStringMatch, mSSubstringsMatch
+ --==
+ FROM MSMatchingRules {joint-iso-itu-t mhs(6) ms(4) modules(0)
+ general-matching-rules(5) version-1999(1)}
+ -- MTS Abstract Service
+ EncodedInformationTypes, MessageToken
+ --==
+ FROM MTSAbstractService {joint-iso-itu-t mhs(6) mts(3) modules(0)
+ mts-abstract-service(1) version-1999(1)}
+ -- Directory Information Framework
+ objectIdentifierMatch, MATCHING-RULE
+ --==
+ FROM InformationFramework {joint-iso-itu-t ds(5) module(1)
+ informationFramework(1) 3}
+ -- Directory Abstract Service
+ booleanMatch, generalizedTimeMatch, generalizedTimeOrderingMatch,
+ integerMatch, integerOrderingMatch, uTCTimeMatch, uTCTimeOrderingMatch
+ --==
+ FROM SelectedAttributeTypes {joint-iso-itu-t ds(5) module(1)
+ selectedAttributeTypes(5) 3}
+ ub-msstring-match
+ FROM MSUpperBounds {joint-iso-itu-t mhs(6) ms(4) modules(0) upper-bounds(4)
+ version-1994(0)};
+
+-- IPMS attribute table information object set
+IPMSAttributeTable X413ATTRIBUTE ::=
+ {acknowledgment-mode | authorizing-users | auto-forward-comment |
+ auto-forwarded | auto-submitted | bilaterally-defined-body-parts |
+ blind-copy-recipients | body | conversion-eits | copy-recipients |
+ discard-reason | encrypted-body-parts | encrypted-data |
+ encrypted-parameters | expiry-time | extended-body-part-types |
+ g3-facsimile-body-parts | g3-facsimile-data | g3-facsimile-parameters |
+ g4-class1-body-parts | heading | ia5-text-body-parts | ia5-text-data |
+ ia5-text-parameters | importance | incomplete-copy | ipm-entry-type |
+ ipm-intended-recipient | ipm-synopsis | ipn-originator | languages |
+ message-body-parts | message-data | message-parameters |
+ mixed-mode-body-parts | nationally-defined-body-parts | non-receipt-reason |
+ nrn-requestors | obsoleted-IPMs | originator | primary-recipients |
+ receipt-time | related-IPMs | replied-to-IPM | reply-recipients |
+ reply-requestors | reply-time | returned-ipm | rn-requestors | sensitivity |
+ subject | subject-ipm | suppl-receipt-info | teletex-body-parts |
+ teletex-data | teletex-parameters | this-ipm | videotex-body-parts |
+ videotex-data | videotex-parameters, ... -- 1994 extension additions --,
+ ac-correlated-delivered-ipns | ac-correlated-delivered-replies |
+ ac-delivered-ipn-summary | ac-delivered-replies-summary | ac-forwarded-ipms
+ | ac-forwarding-ipms | ac-ipm-recipients | ac-obsoleted-ipms |
+ ac-obsoleting-ipms | ac-related-ipms | ac-relating-ipms | ac-replied-to-ipm
+ | ac-replying-ipms | ac-subject-ipm | ac-submitted-ipn-status |
+ ac-submitted-ipns | ac-submitted-reply-status | authorization-time |
+ body-part-encryption-token | body-part-security-label |
+ body-part-signature-verification-status | body-part-signatures |
+ body-parts-summary | circulation-list-recipients | distribution-codes |
+ extended-subject | forwarded-content-token | forwarding-token |
+ information-category | ipm-auto-discarded | ipm-security-label |
+ manual-handling-instructions | notification-extensions | nrn-extensions |
+ originators-reference | other-notification-type-fields | precedence |
+ precedence-policy-identifier | recipient-category | revised-reply-time |
+ rn-extensions}
+
+-- SUMMARY ATTRIBUTES
+-- IPM entry type
+ipm-entry-type X413ATTRIBUTE ::= {
+ WITH ATTRIBUTE-SYNTAX IPMEntryType,
+ EQUALITY MATCHING-RULE integerMatch,
+ NUMERATION single-valued,
+ ID id-sat-ipm-entry-type
+}
+
+IPMEntryType ::= ENUMERATED {ipm(0), rn(1), nrn(2), on(3)}
+
+-- IPM synopsis
+ipm-synopsis X413ATTRIBUTE ::= {
+ WITH ATTRIBUTE-SYNTAX IPMSynopsis,
+ NUMERATION single-valued,
+ ID id-sat-ipm-synopsis
+}
+
+IPMSynopsis ::= SEQUENCE OF BodyPartSynopsis
+
+BodyPartSynopsis ::= CHOICE {
+ message [0] MessageBodyPartSynopsis,
+ non-message [1] NonMessageBodyPartSynopsis
+}
+
+MessageBodyPartSynopsis ::= SEQUENCE {
+ number [0] SequenceNumber,
+ synopsis [1] IPMSynopsis
+}
+
+NonMessageBodyPartSynopsis ::= SEQUENCE {
+ type [0] OBJECT IDENTIFIER,
+ parameters [1] INSTANCE OF TYPE-IDENTIFIER OPTIONAL,
+ size [2] INTEGER,
+ processed [3] BOOLEAN DEFAULT FALSE
+}
+
+-- Body part summary
+body-parts-summary X413ATTRIBUTE ::= {
+ WITH ATTRIBUTE-SYNTAX BodyPartDescriptor,
+ NUMERATION multi-valued,
+ ID id-sat-body-parts-summary
+}
+
+BodyPartDescriptor ::= SEQUENCE {
+ data [0] OBJECT IDENTIFIER,
+ parameters [1] OBJECT IDENTIFIER OPTIONAL,
+ this-child-entry [2] SequenceNumber OPTIONAL,
+ position [3] INTEGER,
+ size [4] INTEGER,
+ processed [5] BOOLEAN DEFAULT FALSE
+}
+
+-- IPM auto discarded
+ipm-auto-discarded X413ATTRIBUTE ::= {
+ WITH ATTRIBUTE-SYNTAX BOOLEAN,
+ EQUALITY MATCHING-RULE booleanMatch,
+ NUMERATION single-valued,
+ ID id-sat-ipm-auto-discarded
+}
+
+-- Body part signature verification status
+body-part-signature-verification-status X413ATTRIBUTE ::= {
+ WITH ATTRIBUTE-SYNTAX BodyPartSignatureVerification,
+ NUMERATION single-valued,
+ ID id-hat-body-part-signature-verification-status
+}
+
+BodyPartSignatureVerification ::=
+ SET OF
+ SET {body-part-sequence-number [0] BodyPartNumber,
+ body-part-signature [1] SignatureStatus}
+
+-- HEADING ATTRIBUTES
+-- Heading
+heading X413ATTRIBUTE ::= {
+ WITH ATTRIBUTE-SYNTAX Heading,
+ NUMERATION single-valued,
+ ID id-hat-heading
+}
+
+-- Heading analyses
+rn-requestors X413ATTRIBUTE ::= {
+ WITH ATTRIBUTE-SYNTAX ORDescriptor,
+ EQUALITY MATCHING-RULE oRDescriptorMatch,
+ NUMERATION multi-valued,
+ ID id-hat-rn-requestors
+}
+
+nrn-requestors X413ATTRIBUTE ::= {
+ WITH ATTRIBUTE-SYNTAX ORDescriptor,
+ EQUALITY MATCHING-RULE oRDescriptorMatch,
+ NUMERATION multi-valued,
+ ID id-hat-nrn-requestors
+}
+
+reply-requestors X413ATTRIBUTE ::= {
+ WITH ATTRIBUTE-SYNTAX ORDescriptor,
+ EQUALITY MATCHING-RULE oRDescriptorMatch,
+ NUMERATION multi-valued,
+ ID id-hat-reply-requestors
+}
+
+-- Heading fields
+this-ipm X413ATTRIBUTE ::= {
+ WITH ATTRIBUTE-SYNTAX ThisIPMField,
+ EQUALITY MATCHING-RULE iPMIdentifierMatch,
+ NUMERATION single-valued,
+ ID id-hat-this-ipm
+}
+
+originator X413ATTRIBUTE ::= {
+ WITH ATTRIBUTE-SYNTAX OriginatorField,
+ EQUALITY MATCHING-RULE oRDescriptorMatch,
+ OTHER MATCHING-RULES
+ {oRDescriptorElementsMatch | oRDescriptorSingleElementMatch |
+ oRDescriptorSubstringElementsMatch, ...},
+ NUMERATION single-valued,
+ ID id-hat-originator
+}
+
+replied-to-IPM X413ATTRIBUTE ::= {
+ WITH ATTRIBUTE-SYNTAX RepliedToIPMField,
+ EQUALITY MATCHING-RULE iPMIdentifierMatch,
+ NUMERATION single-valued,
+ ID id-hat-replied-to-IPM
+}
+
+subject X413ATTRIBUTE ::= {
+ WITH ATTRIBUTE-SYNTAX SubjectField,
+ EQUALITY MATCHING-RULE mSStringMatch,
+ SUBSTRINGS MATCHING-RULE mSSubstringsMatch,
+ NUMERATION single-valued,
+ ID id-hat-subject
+}
+
+expiry-time X413ATTRIBUTE ::= {
+ WITH ATTRIBUTE-SYNTAX ExpiryTimeField,
+ EQUALITY MATCHING-RULE uTCTimeMatch,
+ ORDERING MATCHING-RULE uTCTimeOrderingMatch,
+ NUMERATION single-valued,
+ ID id-hat-expiry-time
+}
+
+reply-time X413ATTRIBUTE ::= {
+ WITH ATTRIBUTE-SYNTAX ReplyTimeField,
+ EQUALITY MATCHING-RULE uTCTimeMatch,
+ ORDERING MATCHING-RULE uTCTimeOrderingMatch,
+ NUMERATION single-valued,
+ ID id-hat-reply-time
+}
+
+importance X413ATTRIBUTE ::= {
+ WITH ATTRIBUTE-SYNTAX ImportanceField,
+ EQUALITY MATCHING-RULE integerMatch,
+ ORDERING MATCHING-RULE
+ integerOrderingMatch, -- not defined for 1988 Application Contexts
+
+ NUMERATION single-valued,
+ ID id-hat-importance
+}
+
+sensitivity X413ATTRIBUTE ::= {
+ WITH ATTRIBUTE-SYNTAX SensitivityField,
+ EQUALITY MATCHING-RULE integerMatch,
+ ORDERING MATCHING-RULE
+ integerOrderingMatch, -- not defined for 1988 Application Contexts
+
+ NUMERATION single-valued,
+ ID id-hat-sensitivity
+}
+
+auto-forwarded X413ATTRIBUTE ::= {
+ WITH ATTRIBUTE-SYNTAX AutoForwardedField,
+ EQUALITY MATCHING-RULE booleanMatch,
+ NUMERATION single-valued,
+ ID id-hat-auto-forwarded
+}
+
+-- Heading sub-fields
+authorizing-users X413ATTRIBUTE ::= {
+ WITH ATTRIBUTE-SYNTAX AuthorizingUsersSubfield,
+ EQUALITY MATCHING-RULE oRDescriptorMatch,
+ OTHER MATCHING-RULES
+ {oRDescriptorElementsMatch | oRDescriptorSingleElementMatch |
+ oRDescriptorSubstringElementsMatch, ...},
+ NUMERATION multi-valued,
+ ID id-hat-authorizing-users
+}
+
+primary-recipients X413ATTRIBUTE ::= {
+ WITH ATTRIBUTE-SYNTAX PrimaryRecipientsSubfield,
+ EQUALITY MATCHING-RULE recipientSpecifierMatch,
+ OTHER MATCHING-RULES
+ {recipientSpecifierElementsMatch | recipientSpecifierSubstringElementsMatch
+ | recipientSpecifierSingleElementMatch, ...},
+ NUMERATION multi-valued,
+ ID id-hat-primary-recipients
+}
+
+copy-recipients X413ATTRIBUTE ::= {
+ WITH ATTRIBUTE-SYNTAX CopyRecipientsSubfield,
+ EQUALITY MATCHING-RULE recipientSpecifierMatch,
+ OTHER MATCHING-RULES
+ {recipientSpecifierElementsMatch | recipientSpecifierSubstringElementsMatch
+ | recipientSpecifierSingleElementMatch, ...},
+ NUMERATION multi-valued,
+ ID id-hat-copy-recipients
+}
+
+blind-copy-recipients X413ATTRIBUTE ::= {
+ WITH ATTRIBUTE-SYNTAX BlindCopyRecipientsSubfield,
+ EQUALITY MATCHING-RULE recipientSpecifierMatch,
+ OTHER MATCHING-RULES
+ {recipientSpecifierElementsMatch | recipientSpecifierSubstringElementsMatch
+ | recipientSpecifierSingleElementMatch, ...},
+ NUMERATION multi-valued,
+ ID id-hat-blind-copy-recipients
+}
+
+obsoleted-IPMs X413ATTRIBUTE ::= {
+ WITH ATTRIBUTE-SYNTAX ObsoletedIPMsSubfield,
+ EQUALITY MATCHING-RULE iPMIdentifierMatch,
+ NUMERATION multi-valued,
+ ID id-hat-obsoleted-IPMs
+}
+
+related-IPMs X413ATTRIBUTE ::= {
+ WITH ATTRIBUTE-SYNTAX RelatedIPMsSubfield,
+ EQUALITY MATCHING-RULE iPMIdentifierMatch,
+ NUMERATION multi-valued,
+ ID id-hat-related-IPMs
+}
+
+reply-recipients X413ATTRIBUTE ::= {
+ WITH ATTRIBUTE-SYNTAX ReplyRecipientsSubfield,
+ EQUALITY MATCHING-RULE oRDescriptorMatch,
+ OTHER MATCHING-RULES
+ {oRDescriptorElementsMatch | oRDescriptorSingleElementMatch |
+ oRDescriptorSubstringElementsMatch, ...},
+ NUMERATION multi-valued,
+ ID id-hat-reply-recipients
+}
+
+-- Heading extensions
+incomplete-copy X413ATTRIBUTE ::= {
+ WITH ATTRIBUTE-SYNTAX IncompleteCopy,
+ NUMERATION
+ single-valued, -- An equality match is specified for 1988
+
+
+ -- Application Contexts
+ ID id-hat-incomplete-copy
+}
+
+languages X413ATTRIBUTE ::= {
+ WITH ATTRIBUTE-SYNTAX Language,
+ EQUALITY MATCHING-RULE mSStringMatch,
+ SUBSTRINGS MATCHING-RULE
+ mSSubstringsMatch, -- Not defined for 1988 Application Contexts
+
+ NUMERATION multi-valued,
+ ID id-hat-languages
+}
+
+auto-submitted X413ATTRIBUTE ::= {
+ WITH ATTRIBUTE-SYNTAX AutoSubmitted,
+ EQUALITY MATCHING-RULE integerMatch,
+ NUMERATION single-valued,
+ ID id-hat-auto-submitted
+}
+
+body-part-signatures X413ATTRIBUTE ::= {
+ WITH ATTRIBUTE-SYNTAX BodyPartSignatures,
+ NUMERATION single-valued,
+ ID id-hat-body-part-signatures
+}
+
+ipm-security-label X413ATTRIBUTE ::= {
+ WITH ATTRIBUTE-SYNTAX IPMSecurityLabel,
+ NUMERATION single-valued,
+ ID id-hat-ipm-security-label
+}
+
+body-part-security-label X413ATTRIBUTE ::= {
+ WITH ATTRIBUTE-SYNTAX BodyPartSecurityLabel,
+ NUMERATION multi-valued,
+ ID id-hat-body-part-security-label
+}
+
+authorization-time X413ATTRIBUTE ::= {
+ WITH ATTRIBUTE-SYNTAX AuthorizationTime,
+ EQUALITY MATCHING-RULE generalizedTimeMatch,
+ ORDERING MATCHING-RULE generalizedTimeOrderingMatch,
+ NUMERATION single-valued,
+ ID id-hat-authorization-time
+}
+
+circulation-list-recipients X413ATTRIBUTE ::= {
+ WITH ATTRIBUTE-SYNTAX CirculationMember,
+ EQUALITY MATCHING-RULE circulationMemberMatch,
+ OTHER MATCHING-RULES
+ {circulationMemberElementsMatch | circulationMemberSubstringElementsMatch |
+ circulationMemberSingleElementMatch | circulationMemberCheckmarkMatch,
+ ...},
+ NUMERATION multi-valued,
+ ID id-hat-circulation-list-recipients
+}
+
+distribution-codes X413ATTRIBUTE ::= {
+ WITH ATTRIBUTE-SYNTAX DistributionCode,
+ EQUALITY MATCHING-RULE distributionCodeMatch,
+ NUMERATION multi-valued,
+ ID id-hat-distribution-codes
+}
+
+extended-subject X413ATTRIBUTE ::= {
+ WITH ATTRIBUTE-SYNTAX ExtendedSubject,
+ EQUALITY MATCHING-RULE mSStringMatch,
+ SUBSTRINGS MATCHING-RULE mSSubstringsMatch,
+ NUMERATION single-valued,
+ ID id-hat-extended-subject
+}
+
+information-category X413ATTRIBUTE ::= {
+ WITH ATTRIBUTE-SYNTAX InformationCategory,
+ EQUALITY MATCHING-RULE informationCategoryMatch,
+ NUMERATION multi-valued,
+ ID id-hat-information-category
+}
+
+manual-handling-instructions X413ATTRIBUTE ::= {
+ WITH ATTRIBUTE-SYNTAX ManualHandlingInstruction,
+ EQUALITY MATCHING-RULE mSStringMatch,
+ NUMERATION multi-valued,
+ ID id-hat-manual-handling-instructions
+}
+
+originators-reference X413ATTRIBUTE ::= {
+ WITH ATTRIBUTE-SYNTAX OriginatorsReference,
+ EQUALITY MATCHING-RULE mSStringMatch,
+ NUMERATION single-valued,
+ ID id-hat-originators-reference
+}
+
+precedence-policy-identifier X413ATTRIBUTE ::= {
+ WITH ATTRIBUTE-SYNTAX PrecedencePolicyIdentifier,
+ EQUALITY MATCHING-RULE objectIdentifierMatch,
+ NUMERATION single-valued,
+ ID id-hat-precedence-policy-id
+}
+
+-- Recipient extensions
+precedence X413ATTRIBUTE ::= {
+ WITH ATTRIBUTE-SYNTAX Precedence,
+ EQUALITY MATCHING-RULE integerMatch,
+ NUMERATION single-valued,
+ ID id-hat-precedence
+}
+
+-- Envelope extensions
+body-part-encryption-token X413ATTRIBUTE ::= {
+ WITH ATTRIBUTE-SYNTAX BodyPartTokens,
+ NUMERATION single-valued,
+ ID id-hat-body-part-encryption-token
+}
+
+forwarded-content-token X413ATTRIBUTE ::= {
+ WITH ATTRIBUTE-SYNTAX ForwardedContentToken,
+ NUMERATION single-valued,
+ ID id-hat-forwarded-content-token
+}
+
+forwarding-token X413ATTRIBUTE ::= {
+ WITH ATTRIBUTE-SYNTAX MessageToken,
+ NUMERATION single-valued,
+ ID id-hat-forwarding-token
+}
+
+-- BODY ATTRIBUTES
+-- Body
+body X413ATTRIBUTE ::= {
+ WITH ATTRIBUTE-SYNTAX Body,
+ NUMERATION single-valued,
+ ID id-bat-body
+}
+
+-- Extended body part types
+extended-body-part-types X413ATTRIBUTE ::= {
+ WITH ATTRIBUTE-SYNTAX OBJECT IDENTIFIER,
+ EQUALITY MATCHING-RULE objectIdentifierMatch,
+ NUMERATION multi-valued,
+ ID id-bat-extended-body-part-types
+}
+
+-- Extended body parts
+-- (These attributes cannot be enumerated. See 19.6.3.3.)
+-- (They may be derived using the following parameterized object assignments:)
+extended-body-part-data-attribute{EXTENDED-BODY-PART-TYPE:ebpt} X413ATTRIBUTE
+ ::= {
+ WITH ATTRIBUTE-SYNTAX [0] EXPLICIT ebpt.&data.&Type,
+ NUMERATION multi-valued,
+ ID ebpt.&data.&id
+}
+
+extended-body-part-parameters-attribute{EXTENDED-BODY-PART-TYPE:ebpt}
+ X413ATTRIBUTE ::= {
+ WITH ATTRIBUTE-SYNTAX [0] EXPLICIT ebpt.&parameters.&Type,
+ NUMERATION multi-valued,
+ ID ebpt.&parameters.&id
+}
+
+-- Basic body parts
+ia5-text-body-parts X413ATTRIBUTE ::= {
+ WITH ATTRIBUTE-SYNTAX IA5TextBodyPart,
+ NUMERATION multi-valued,
+ ID id-bat-ia5-text-body-parts
+}
+
+g3-facsimile-body-parts X413ATTRIBUTE ::= {
+ WITH ATTRIBUTE-SYNTAX G3FacsimileBodyPart,
+ NUMERATION multi-valued,
+ ID id-bat-g3-facsimile-body-parts
+}
+
+g4-class1-body-parts X413ATTRIBUTE ::= {
+ WITH ATTRIBUTE-SYNTAX G4Class1BodyPart,
+ NUMERATION multi-valued,
+ ID id-bat-g4-class1-body-parts
+}
+
+teletex-body-parts X413ATTRIBUTE ::= {
+ WITH ATTRIBUTE-SYNTAX TeletexBodyPart,
+ NUMERATION multi-valued,
+ ID id-bat-teletex-body-parts
+}
+
+videotex-body-parts X413ATTRIBUTE ::= {
+ WITH ATTRIBUTE-SYNTAX VideotexBodyPart,
+ NUMERATION multi-valued,
+ ID id-bat-videotex-body-parts
+}
+
+encrypted-body-parts X413ATTRIBUTE ::= {
+ WITH ATTRIBUTE-SYNTAX EncryptedBodyPart,
+ NUMERATION multi-valued,
+ ID id-bat-encrypted-body-parts
+}
+
+message-body-parts X413ATTRIBUTE ::= {
+ WITH ATTRIBUTE-SYNTAX SequenceNumber,
+ NUMERATION multi-valued,
+ ID id-bat-message-body-parts
+}
+
+mixed-mode-body-parts X413ATTRIBUTE ::= {
+ WITH ATTRIBUTE-SYNTAX MixedModeBodyPart,
+ NUMERATION multi-valued,
+ ID id-bat-mixed-mode-body-parts
+}
+
+bilaterally-defined-body-parts X413ATTRIBUTE ::= {
+ WITH ATTRIBUTE-SYNTAX BilaterallyDefinedBodyPart,
+ NUMERATION multi-valued,
+ ID id-bat-bilaterally-defined-body-parts
+}
+
+nationally-defined-body-parts X413ATTRIBUTE ::= {
+ WITH ATTRIBUTE-SYNTAX NationallyDefinedBodyPart,
+ NUMERATION multi-valued,
+ ID id-bat-nationally-defined-body-parts
+}
+
+-- Basic body part parameters components
+ia5-text-parameters X413ATTRIBUTE ::= {
+ WITH ATTRIBUTE-SYNTAX IA5TextParameters,
+ NUMERATION multi-valued,
+ ID id-bat-ia5-text-parameters
+}
+
+g3-facsimile-parameters X413ATTRIBUTE ::= {
+ WITH ATTRIBUTE-SYNTAX G3FacsimileParameters,
+ NUMERATION multi-valued,
+ ID id-bat-g3-facsimile-parameters
+}
+
+teletex-parameters X413ATTRIBUTE ::= {
+ WITH ATTRIBUTE-SYNTAX TeletexParameters,
+ NUMERATION multi-valued,
+ ID id-bat-teletex-parameters
+}
+
+videotex-parameters X413ATTRIBUTE ::= {
+ WITH ATTRIBUTE-SYNTAX VideotexParameters,
+ NUMERATION multi-valued,
+ ID id-bat-videotex-parameters
+}
+
+encrypted-parameters X413ATTRIBUTE ::= {
+ WITH ATTRIBUTE-SYNTAX EncryptedParameters,
+ NUMERATION multi-valued,
+ ID id-bat-encrypted-parameters
+}
+
+message-parameters X413ATTRIBUTE ::= {
+ WITH ATTRIBUTE-SYNTAX MessageParameters,
+ NUMERATION multi-valued,
+ ID id-bat-message-parameters
+}
+
+-- Basic body part data components
+ia5-text-data X413ATTRIBUTE ::= {
+ WITH ATTRIBUTE-SYNTAX IA5TextData,
+ NUMERATION multi-valued,
+ ID id-bat-ia5-text-data
+}
+
+g3-facsimile-data X413ATTRIBUTE ::= {
+ WITH ATTRIBUTE-SYNTAX G3FacsimileData,
+ NUMERATION multi-valued,
+ ID id-bat-g3-facsimile-data
+}
+
+teletex-data X413ATTRIBUTE ::= {
+ WITH ATTRIBUTE-SYNTAX TeletexData,
+ NUMERATION multi-valued,
+ ID id-bat-teletex-data
+}
+
+videotex-data X413ATTRIBUTE ::= {
+ WITH ATTRIBUTE-SYNTAX VideotexData,
+ NUMERATION multi-valued,
+ ID id-bat-videotex-data
+}
+
+encrypted-data X413ATTRIBUTE ::= {
+ WITH ATTRIBUTE-SYNTAX EncryptedData,
+ NUMERATION multi-valued,
+ ID id-bat-encrypted-data
+}
+
+message-data X413ATTRIBUTE ::= {
+ WITH ATTRIBUTE-SYNTAX MessageData,
+ NUMERATION multi-valued,
+ ID id-bat-message-data
+}
+
+-- NOTIFICATION ATTRIBUTES
+-- Common fields
+subject-ipm X413ATTRIBUTE ::= {
+ WITH ATTRIBUTE-SYNTAX SubjectIPMField,
+ EQUALITY MATCHING-RULE iPMIdentifierMatch,
+ NUMERATION single-valued,
+ ID id-nat-subject-ipm
+}
+
+ipn-originator X413ATTRIBUTE ::= {
+ WITH ATTRIBUTE-SYNTAX IPNOriginatorField,
+ EQUALITY MATCHING-RULE oRDescriptorMatch,
+ OTHER MATCHING-RULES
+ {oRDescriptorElementsMatch | oRDescriptorSingleElementMatch |
+ oRDescriptorSubstringElementsMatch, ...},
+ NUMERATION single-valued,
+ ID id-nat-ipn-originator
+}
+
+ipm-intended-recipient X413ATTRIBUTE ::= {
+ WITH ATTRIBUTE-SYNTAX IPMIntendedRecipientField,
+ EQUALITY MATCHING-RULE oRDescriptorMatch,
+ OTHER MATCHING-RULES
+ {oRDescriptorElementsMatch | oRDescriptorSingleElementMatch |
+ oRDescriptorSubstringElementsMatch, ...},
+ NUMERATION single-valued,
+ ID id-nat-ipm-intended-recipient
+}
+
+conversion-eits X413ATTRIBUTE ::= {
+ WITH ATTRIBUTE-SYNTAX MS-EIT,
+ EQUALITY MATCHING-RULE objectIdentifierMatch,
+ NUMERATION multi-valued,
+ ID id-nat-conversion-eits
+}
+
+notification-extensions X413ATTRIBUTE ::= {
+ WITH ATTRIBUTE-SYNTAX IPMSExtension {{NotificationExtensions}},
+ NUMERATION multi-valued,
+ ID id-nat-notification-extensions
+}
+
+-- Non-receipt fields
+non-receipt-reason X413ATTRIBUTE ::= {
+ WITH ATTRIBUTE-SYNTAX NonReceiptReasonField,
+ EQUALITY MATCHING-RULE integerMatch,
+ NUMERATION single-valued,
+ ID id-nat-non-receipt-reason
+}
+
+discard-reason X413ATTRIBUTE ::= {
+ WITH ATTRIBUTE-SYNTAX DiscardReasonField,
+ EQUALITY MATCHING-RULE integerMatch,
+ NUMERATION single-valued,
+ ID id-nat-discard-reason
+}
+
+auto-forward-comment X413ATTRIBUTE ::= {
+ WITH ATTRIBUTE-SYNTAX AutoForwardCommentField,
+ EQUALITY MATCHING-RULE mSStringMatch,
+ SUBSTRINGS MATCHING-RULE mSSubstringsMatch,
+ NUMERATION single-valued,
+ ID id-nat-auto-forward-comment
+}
+
+returned-ipm X413ATTRIBUTE ::= {
+ WITH ATTRIBUTE-SYNTAX ReturnedIPMField,
+ NUMERATION single-valued,
+ ID id-nat-returned-ipm
+}
+
+nrn-extensions X413ATTRIBUTE ::= {
+ WITH ATTRIBUTE-SYNTAX IPMSExtension {{NRNExtensions}},
+ NUMERATION multi-valued,
+ ID id-nat-nrn-extensions
+}
+
+-- Receipt fields
+receipt-time X413ATTRIBUTE ::= {
+ WITH ATTRIBUTE-SYNTAX ReceiptTimeField,
+ EQUALITY MATCHING-RULE uTCTimeMatch,
+ ORDERING MATCHING-RULE uTCTimeOrderingMatch,
+ NUMERATION single-valued,
+ ID id-nat-receipt-time
+}
+
+acknowledgment-mode X413ATTRIBUTE ::= {
+ WITH ATTRIBUTE-SYNTAX AcknowledgmentModeField,
+ EQUALITY MATCHING-RULE integerMatch,
+ NUMERATION single-valued,
+ ID id-nat-acknowledgment-mode
+}
+
+suppl-receipt-info X413ATTRIBUTE ::= {
+ WITH ATTRIBUTE-SYNTAX SupplReceiptInfoField,
+ EQUALITY MATCHING-RULE mSStringMatch,
+ SUBSTRINGS MATCHING-RULE mSSubstringsMatch,
+ NUMERATION single-valued,
+ ID id-nat-suppl-receipt-info
+}
+
+rn-extensions X413ATTRIBUTE ::= {
+ WITH ATTRIBUTE-SYNTAX IPMSExtension {{RNExtensions}},
+ NUMERATION multi-valued,
+ ID id-nat-rn-extensions
+}
+
+-- Other notification type fields
+other-notification-type-fields X413ATTRIBUTE ::= {
+ WITH ATTRIBUTE-SYNTAX IPMSExtension {{OtherNotifications}},
+ NUMERATION multi-valued,
+ ID id-nat-other-notification-type-fields
+}
+
+-- CORRELATION ATTRIBUTES
+-- Common attributes
+ac-forwarding-ipms X413ATTRIBUTE ::= {
+ WITH ATTRIBUTE-SYNTAX SequenceNumber,
+ EQUALITY MATCHING-RULE integerMatch,
+ ORDERING MATCHING-RULE integerOrderingMatch,
+ NUMERATION multi-valued,
+ ID id-cat-forwarding-ipms
+}
+
+ac-forwarded-ipms X413ATTRIBUTE ::= {
+ WITH ATTRIBUTE-SYNTAX SequenceNumber,
+ EQUALITY MATCHING-RULE integerMatch,
+ ORDERING MATCHING-RULE integerOrderingMatch,
+ NUMERATION multi-valued,
+ ID id-cat-forwarded-ipms
+}
+
+ac-obsoleting-ipms X413ATTRIBUTE ::= {
+ WITH ATTRIBUTE-SYNTAX SequenceNumber,
+ EQUALITY MATCHING-RULE integerMatch,
+ ORDERING MATCHING-RULE integerOrderingMatch,
+ NUMERATION multi-valued,
+ ID id-cat-obsoleting-ipms
+}
+
+ac-obsoleted-ipms X413ATTRIBUTE ::= {
+ WITH ATTRIBUTE-SYNTAX IPMLocation,
+ OTHER MATCHING-RULES {iPMLocationMatch, ...},
+ NUMERATION multi-valued,
+ ID id-cat-obsoleted-ipms
+}
+
+IPMLocation ::= CHOICE {stored SET OF SequenceNumber,
+ absent NULL,
+ ...
+}
+
+ac-relating-ipms X413ATTRIBUTE ::= {
+ WITH ATTRIBUTE-SYNTAX SequenceNumber,
+ EQUALITY MATCHING-RULE integerMatch,
+ ORDERING MATCHING-RULE integerOrderingMatch,
+ NUMERATION multi-valued,
+ ID id-cat-relating-ipms
+}
+
+ac-related-ipms X413ATTRIBUTE ::= {
+ WITH ATTRIBUTE-SYNTAX IPMLocation,
+ OTHER MATCHING-RULES {iPMLocationMatch, ...},
+ NUMERATION multi-valued,
+ ID id-cat-related-ipms
+}
+
+ac-replied-to-ipm X413ATTRIBUTE ::= {
+ WITH ATTRIBUTE-SYNTAX SequenceNumber,
+ EQUALITY MATCHING-RULE integerMatch,
+ ORDERING MATCHING-RULE integerOrderingMatch,
+ NUMERATION multi-valued,
+ ID id-cat-replied-to-ipm
+}
+
+ac-replying-ipms X413ATTRIBUTE ::= {
+ WITH ATTRIBUTE-SYNTAX SequenceNumber,
+ EQUALITY MATCHING-RULE integerMatch,
+ ORDERING MATCHING-RULE integerOrderingMatch,
+ NUMERATION multi-valued,
+ ID id-cat-replying-ipms
+}
+
+ac-subject-ipm X413ATTRIBUTE ::= {
+ WITH ATTRIBUTE-SYNTAX SequenceNumber,
+ EQUALITY MATCHING-RULE integerMatch,
+ ORDERING MATCHING-RULE integerOrderingMatch,
+ NUMERATION multi-valued,
+ ID id-cat-subject-ipm
+}
+
+-- Submitted message correlation
+ac-ipm-recipients X413ATTRIBUTE ::= {
+ WITH ATTRIBUTE-SYNTAX ORDescriptor,
+ EQUALITY MATCHING-RULE oRDescriptorMatch,
+ OTHER MATCHING-RULES
+ {oRDescriptorElementsMatch | oRDescriptorSingleElementMatch |
+ oRDescriptorSubstringElementsMatch, ...},
+ NUMERATION multi-valued,
+ ID id-cat-ipm-recipients
+}
+
+ac-delivered-replies-summary X413ATTRIBUTE ::= {
+ WITH ATTRIBUTE-SYNTAX DeliveredReplyStatus,
+ EQUALITY MATCHING-RULE integerMatch,
+ ORDERING MATCHING-RULE integerOrderingMatch,
+ NUMERATION multi-valued,
+ ID id-cat-delivered-replies-summary
+}
+
+DeliveredReplyStatus ::= INTEGER {
+ no-reply-requested(0) -- reply not requested --,
+ reply-outstanding(1) -- reply requested --, reply-received(2)}
+
+ac-correlated-delivered-replies X413ATTRIBUTE ::= {
+ WITH ATTRIBUTE-SYNTAX CorrelatedDeliveredReplies,
+ NUMERATION multi-valued,
+ ID id-cat-correlated-delivered-replies
+}
+
+CorrelatedDeliveredReplies ::= CHOICE {
+ no-reply-received [0] NULL,
+ received-replies [1] SEQUENCE OF SequenceNumber
+}
+
+ac-delivered-ipn-summary X413ATTRIBUTE ::= {
+ WITH ATTRIBUTE-SYNTAX DeliveredIPNStatus,
+ EQUALITY MATCHING-RULE integerMatch,
+ ORDERING MATCHING-RULE integerOrderingMatch,
+ NUMERATION multi-valued,
+ ID id-cat-delivered-ipn-summary
+}
+
+DeliveredIPNStatus ::= INTEGER {
+ no-ipn-requested(0), an-requested(3), nrn-requested(5), rn-requested(10),
+ an-received(13), ipm-auto-forwarded(15), ipm-discarded(20), rn-received(25)
+}
+
+ac-correlated-delivered-ipns X413ATTRIBUTE ::= {
+ WITH ATTRIBUTE-SYNTAX CorrelatedDeliveredIPNs,
+ NUMERATION multi-valued,
+ ID id-cat-correlated-delivered-ipns
+}
+
+CorrelatedDeliveredIPNs ::= CHOICE {
+ no-ipn-received [0] NULL,
+ ipns-received [1] SEQUENCE OF SequenceNumber
+}
+
+-- Delivered message correlation
+ac-submitted-reply-status X413ATTRIBUTE ::= {
+ WITH ATTRIBUTE-SYNTAX SubmittedReplyStatus,
+ EQUALITY MATCHING-RULE integerMatch,
+ ORDERING MATCHING-RULE integerOrderingMatch,
+ NUMERATION single-valued,
+ ID id-cat-submitted-reply-status
+}
+
+SubmittedReplyStatus ::= INTEGER {
+ no-reply-requested(0), no-reply-intended(1), reply-pending(2), reply-sent(3)
+}
+
+ac-submitted-ipn-status X413ATTRIBUTE ::= {
+ WITH ATTRIBUTE-SYNTAX SubmittedIPNStatus,
+ EQUALITY MATCHING-RULE integerMatch,
+ ORDERING MATCHING-RULE integerOrderingMatch,
+ NUMERATION single-valued,
+ ID id-cat-submitted-ipn-status
+}
+
+SubmittedIPNStatus ::= INTEGER {
+ no-ipn-requested(0), nrn-requested(5), nrn-with-ipm-return-requested(10),
+ rn-requested(15), rn-with-ipm-return-requested(20), ipm-auto-forwarded(25),
+ ipm-discarded(30), rn-sent(35)}
+
+ac-submitted-ipns X413ATTRIBUTE ::= {
+ WITH ATTRIBUTE-SYNTAX SequenceNumber,
+ EQUALITY MATCHING-RULE integerMatch,
+ ORDERING MATCHING-RULE integerOrderingMatch,
+ NUMERATION multi-valued,
+ ID id-cat-submitted-ipns
+}
+
+recipient-category X413ATTRIBUTE ::= {
+ WITH ATTRIBUTE-SYNTAX RecipientCategory,
+ EQUALITY MATCHING-RULE integerMatch,
+ ORDERING MATCHING-RULE integerOrderingMatch,
+ NUMERATION single-valued,
+ ID id-cat-recipient-category
+}
+
+RecipientCategory ::= INTEGER {
+ primary-recipient(0), copy-recipient(1), blind-copy-recipient(2),
+ category-unknown(3), circulation-list(4)}
+
+revised-reply-time X413ATTRIBUTE ::= {
+ WITH ATTRIBUTE-SYNTAX ReplyTimeField,
+ EQUALITY MATCHING-RULE uTCTimeMatch,
+ ORDERING MATCHING-RULE uTCTimeOrderingMatch,
+ NUMERATION single-valued,
+ ID id-cat-revised-reply-time
+}
+
+-- MATCHING-RULES
+IPMMatchingRuleTable MATCHING-RULE ::=
+ {iPMIdentifierMatch | oRDescriptorMatch | recipientSpecifierMatch,
+ ... -- 1994 extension additions --, circulationMemberCheckmarkMatch |
+ circulationMemberElementsMatch | circulationMemberMatch |
+ circulationMemberSingleElementMatch |
+ circulationMemberSubstringElementsMatch | distributionCodeMatch |
+ informationCategoryMatch | iPMLocationMatch | oRDescriptorElementsMatch |
+ oRDescriptorSingleElementMatch | oRDescriptorSubstringElementsMatch |
+ recipientSpecifierElementsMatch | recipientSpecifierSingleElementMatch |
+ recipientSpecifierSubstringElementsMatch}
+
+iPMIdentifierMatch MATCHING-RULE ::= {
+ SYNTAX IPMIdentifier
+ ID id-mr-ipm-identifier
+}
+
+iPMLocationMatch MATCHING-RULE ::= {
+ SYNTAX SequenceNumber
+ ID id-mr-ipm-location
+}
+
+oRDescriptorMatch MATCHING-RULE ::= {
+ SYNTAX ORDescriptor
+ ID id-mr-or-descriptor
+}
+
+oRDescriptorElementsMatch MATCHING-RULE ::= {
+ SYNTAX ORDescriptor
+ ID id-mr-or-descriptor-elements
+}
+
+oRDescriptorSubstringElementsMatch MATCHING-RULE ::= {
+ SYNTAX ORDescriptor
+ ID id-mr-or-descriptor-substring-elements
+}
+
+oRDescriptorSingleElementMatch MATCHING-RULE ::= {
+ SYNTAX MSString {ub-msstring-match}
+ ID id-mr-or-descriptor-single-element
+}
+
+recipientSpecifierMatch MATCHING-RULE ::= {
+ SYNTAX RecipientSpecifier
+ ID id-mr-recipient-specifier
+}
+
+recipientSpecifierElementsMatch MATCHING-RULE ::= {
+ SYNTAX RecipientSpecifier
+ ID id-mr-recipient-specifier-elements
+}
+
+recipientSpecifierSubstringElementsMatch MATCHING-RULE ::= {
+ SYNTAX RecipientSpecifier
+ ID id-mr-recipient-specifier-substring-elements
+}
+
+recipientSpecifierSingleElementMatch MATCHING-RULE ::= {
+ SYNTAX MSString {ub-msstring-match}
+ ID id-mr-recipient-specifier-single-element
+}
+
+circulationMemberMatch MATCHING-RULE ::= {
+ SYNTAX CirculationMember
+ ID id-mr-circulation-member
+}
+
+circulationMemberElementsMatch MATCHING-RULE ::= {
+ SYNTAX CirculationMember
+ ID id-mr-circulation-member-elements
+}
+
+circulationMemberSubstringElementsMatch MATCHING-RULE ::= {
+ SYNTAX CirculationMember
+ ID id-mr-circulation-member-substring-elements
+}
+
+circulationMemberSingleElementMatch MATCHING-RULE ::= {
+ SYNTAX MSString {ub-msstring-match}
+ ID id-mr-circulation-member-single-element
+}
+
+circulationMemberCheckmarkMatch MATCHING-RULE ::= {
+ SYNTAX CirculationMember
+ ID id-mr-circulation-member-checkmark
+}
+
+distributionCodeMatch MATCHING-RULE ::= {
+ SYNTAX DistributionCode
+ ID id-mr-distribution-code
+}
+
+informationCategoryMatch MATCHING-RULE ::= {
+ SYNTAX InformationCategory
+ ID id-mr-information-category
+}
+
+END -- of IPMSMessageStoreAttributes
+
+-- Generated by Asnp, the ASN.1 pretty-printer of France Telecom R&D
+
diff --git a/lib/asn1/test/asn1_SUITE_data/x420/IPMSObjectIdentifiers.asn b/lib/asn1/test/asn1_SUITE_data/x420/IPMSObjectIdentifiers.asn
new file mode 100644
index 0000000000..6e5c01ab40
--- /dev/null
+++ b/lib/asn1/test/asn1_SUITE_data/x420/IPMSObjectIdentifiers.asn
@@ -0,0 +1,507 @@
+-- Module IPMSObjectIdentifiers (X.420:06/1999)
+IPMSObjectIdentifiers {joint-iso-itu-t mhs(6) ipms(1) modules(0)
+ object-identifiers(0) version-1999(1)} DEFINITIONS IMPLICIT TAGS ::=
+BEGIN
+
+-- Prologue
+-- Exports everything.
+IMPORTS -- nothing -- ;
+
+ID ::= OBJECT IDENTIFIER
+
+-- Interpersonal Messaging (not definitive)
+id-ipms ID ::=
+ {joint-iso-itu-t mhs(6) ipms(1)} -- not definitive
+
+-- Categories
+id-mod ID ::= {id-ipms 0} -- modules; not definitive
+
+id-ot ID ::= {id-ipms 1} -- object types
+
+id-pt ID ::= {id-ipms 2} -- port types
+
+id-et ID ::= {id-ipms 4} -- extended body part types
+
+id-hex ID ::= {id-ipms 5} -- heading extensions
+
+id-sat ID ::= {id-ipms 6} -- summary attributes
+
+id-hat ID ::= {id-ipms 7} -- heading attributes
+
+id-bat ID ::= {id-ipms 8} -- body attributes
+
+id-nat ID ::= {id-ipms 9} -- notification attributes
+
+id-mct ID ::= {id-ipms 10} -- message content types
+
+id-ep ID ::= {id-ipms 11} -- extended body part parameters
+
+id-eit ID ::= {id-ipms 12} -- encoded information types
+
+id-cat ID ::= {id-ipms 13} -- correlation attributes
+
+id-mr ID ::= {id-ipms 14} -- matching-rules
+
+id-aa ID ::= {id-ipms 15} -- auto-actions
+
+id-aae ID ::= {id-ipms 16} -- auto-action errors
+
+id-mst ID ::= {id-ipms 17} -- message store types
+
+id-sec ID ::= {id-ipms 18} -- ipm security extensions
+
+id-on ID ::= {id-ipms 19} -- other notification type extensions
+
+id-rex ID ::= {id-ipms 20} -- recipient extensions
+
+-- Modules
+id-mod-object-identifiers ID ::= {id-mod 0} -- not definitive
+
+id-mod-functional-objects ID ::= {id-mod 1} -- not definitive
+
+id-mod-information-objects ID ::= {id-mod 2} -- not definitive
+
+id-mod-abstract-service ID ::= {id-mod 3} -- not definitive
+
+id-mod-heading-extensions ID ::= {id-mod 6} -- not definitive
+
+id-mod-extended-body-part-types ID ::= {id-mod 7} -- not definitive
+
+id-mod-message-store-attributes ID ::= {id-mod 8} -- not definitive
+
+id-mod-file-transfer-body-part-type ID ::= {id-mod 9} -- not definitive
+
+id-mod-upper-bounds ID ::= {id-mod 10} -- not definitive
+
+id-mod-extended-voice-body-part-type ID ::= {id-mod 11} -- not definitive
+
+id-mod-forwarded-report-body-part-type ID ::= {id-mod 12} -- not definitive
+
+id-mod-auto-actions ID ::= {id-mod 13} -- not definitive
+
+id-mod-ipm-security-extensions ID ::= {id-mod 14} -- not definitive
+
+id-mod-forwarded-content-body-part-type ID ::= {id-mod 15} -- not definitive
+
+id-mod-pkcs7-body-part-type ID ::= {id-mod 16} -- not definitive
+
+-- Object types
+id-ot-ipms-user ID ::= {id-ot 1}
+
+id-ot-ipms ID ::= {id-ot 2}
+
+-- Port types
+id-pt-origination ID ::= {id-pt 0}
+
+id-pt-reception ID ::= {id-pt 1}
+
+id-pt-management ID ::= {id-pt 2}
+
+-- Extended body part types
+id-et-ia5-text ID ::= {id-et 0}
+
+id-et-g3-facsimile ID ::= {id-et 2}
+
+id-et-g4-class1 ID ::= {id-et 3}
+
+id-et-teletex ID ::= {id-et 4}
+
+id-et-videotex ID ::= {id-et 5}
+
+id-et-encrypted ID ::= {id-et 6}
+
+id-et-message ID ::= {id-et 7}
+
+id-et-mixed-mode ID ::= {id-et 8}
+
+id-et-bilaterally-defined ID ::= {id-et 9}
+
+id-et-nationally-defined ID ::= {id-et 10}
+
+id-et-general-text ID ::= {id-et 11}
+
+id-et-file-transfer ID ::= {id-et 12}
+
+-- Value {id-et 13} is no longer defined
+id-et-report ID ::= {id-et 14}
+
+id-et-notification ID ::= {id-et 15}
+
+id-et-voice ID ::= {id-et 16}
+
+id-et-content ID ::=
+ {id-et 17} -- This value is not used directly, only as a prefix
+
+id-et-pkcs7 ID ::= {id-et 18}
+
+-- Heading extensions
+id-hex-incomplete-copy ID ::= {id-hex 0}
+
+id-hex-languages ID ::= {id-hex 1}
+
+id-hex-auto-submitted ID ::= {id-hex 2}
+
+id-hex-body-part-signatures ID ::= {id-hex 3}
+
+id-hex-ipm-security-label ID ::= {id-hex 4}
+
+id-hex-authorization-time ID ::= {id-hex 5}
+
+id-hex-circulation-list-recipients ID ::= {id-hex 6}
+
+id-hex-distribution-codes ID ::= {id-hex 7}
+
+id-hex-extended-subject ID ::= {id-hex 8}
+
+id-hex-information-category ID ::= {id-hex 9}
+
+id-hex-manual-handling-instructions ID ::= {id-hex 10}
+
+id-hex-originators-reference ID ::= {id-hex 11}
+
+id-hex-precedence-policy-id ID ::= {id-hex 12}
+
+-- Summary attributes
+id-sat-ipm-entry-type ID ::= {id-sat 0}
+
+id-sat-ipm-synopsis ID ::= {id-sat 1}
+
+id-sat-body-parts-summary ID ::= {id-sat 2}
+
+id-sat-ipm-auto-discarded ID ::= {id-sat 3}
+
+-- Heading attributes
+id-hat-heading ID ::= {id-hat 0}
+
+id-hat-this-ipm ID ::= {id-hat 1}
+
+id-hat-originator ID ::= {id-hat 2}
+
+id-hat-replied-to-IPM ID ::= {id-hat 3}
+
+id-hat-subject ID ::= {id-hat 4}
+
+id-hat-expiry-time ID ::= {id-hat 5}
+
+id-hat-reply-time ID ::= {id-hat 6}
+
+id-hat-importance ID ::= {id-hat 7}
+
+id-hat-sensitivity ID ::= {id-hat 8}
+
+id-hat-auto-forwarded ID ::= {id-hat 9}
+
+id-hat-authorizing-users ID ::= {id-hat 10}
+
+id-hat-primary-recipients ID ::= {id-hat 11}
+
+id-hat-copy-recipients ID ::= {id-hat 12}
+
+id-hat-blind-copy-recipients ID ::= {id-hat 13}
+
+id-hat-obsoleted-IPMs ID ::= {id-hat 14}
+
+id-hat-related-IPMs ID ::= {id-hat 15}
+
+id-hat-reply-recipients ID ::= {id-hat 16}
+
+id-hat-incomplete-copy ID ::= {id-hat 17}
+
+id-hat-languages ID ::= {id-hat 18}
+
+id-hat-rn-requestors ID ::= {id-hat 19}
+
+id-hat-nrn-requestors ID ::= {id-hat 20}
+
+id-hat-reply-requestors ID ::= {id-hat 21}
+
+id-hat-auto-submitted ID ::= {id-hat 22}
+
+id-hat-body-part-signatures ID ::= {id-hat 23}
+
+id-hat-ipm-security-label ID ::= {id-hat 24}
+
+id-hat-body-part-security-label ID ::= {id-hat 25}
+
+id-hat-body-part-encryption-token ID ::= {id-hat 26}
+
+id-hat-authorization-time ID ::= {id-hat 27}
+
+id-hat-circulation-list-recipients ID ::= {id-hat 28}
+
+id-hat-distribution-codes ID ::= {id-hat 29}
+
+id-hat-extended-subject ID ::= {id-hat 30}
+
+id-hat-information-category ID ::= {id-hat 31}
+
+id-hat-manual-handling-instructions ID ::= {id-hat 32}
+
+id-hat-originators-reference ID ::= {id-hat 33}
+
+id-hat-precedence-policy-id ID ::= {id-hat 34}
+
+id-hat-forwarded-content-token ID ::= {id-hat 35}
+
+id-hat-forwarding-token ID ::= {id-hat 36}
+
+id-hat-precedence ID ::= {id-hat 37}
+
+id-hat-body-part-signature-verification-status ID ::= {id-hat 38}
+
+-- Body attributes
+id-bat-body ID ::= {id-bat 0}
+
+id-bat-ia5-text-body-parts ID ::= {id-bat 1}
+
+id-bat-g3-facsimile-body-parts ID ::= {id-bat 3}
+
+id-bat-g4-class1-body-parts ID ::= {id-bat 4}
+
+id-bat-teletex-body-parts ID ::= {id-bat 5}
+
+id-bat-videotex-body-parts ID ::= {id-bat 6}
+
+id-bat-encrypted-body-parts ID ::= {id-bat 7}
+
+id-bat-message-body-parts ID ::= {id-bat 8}
+
+id-bat-mixed-mode-body-parts ID ::= {id-bat 9}
+
+id-bat-bilaterally-defined-body-parts ID ::= {id-bat 10}
+
+id-bat-nationally-defined-body-parts ID ::= {id-bat 11}
+
+id-bat-extended-body-part-types ID ::= {id-bat 12}
+
+id-bat-ia5-text-parameters ID ::= {id-bat 13}
+
+id-bat-g3-facsimile-parameters ID ::= {id-bat 15}
+
+id-bat-teletex-parameters ID ::= {id-bat 16}
+
+id-bat-videotex-parameters ID ::= {id-bat 17}
+
+id-bat-encrypted-parameters ID ::= {id-bat 18}
+
+id-bat-message-parameters ID ::= {id-bat 19}
+
+id-bat-ia5-text-data ID ::= {id-bat 20}
+
+id-bat-g3-facsimile-data ID ::= {id-bat 22}
+
+id-bat-teletex-data ID ::= {id-bat 23}
+
+id-bat-videotex-data ID ::= {id-bat 24}
+
+id-bat-encrypted-data ID ::= {id-bat 25}
+
+id-bat-message-data ID ::= {id-bat 26}
+
+-- Notification attributes
+id-nat-subject-ipm ID ::= {id-nat 0}
+
+id-nat-ipn-originator ID ::= {id-nat 1}
+
+id-nat-ipm-intended-recipient ID ::= {id-nat 2}
+
+id-nat-conversion-eits ID ::= {id-nat 3}
+
+id-nat-non-receipt-reason ID ::= {id-nat 4}
+
+id-nat-discard-reason ID ::= {id-nat 5}
+
+id-nat-auto-forward-comment ID ::= {id-nat 6}
+
+id-nat-returned-ipm ID ::= {id-nat 7}
+
+id-nat-receipt-time ID ::= {id-nat 8}
+
+id-nat-acknowledgment-mode ID ::= {id-nat 9}
+
+id-nat-suppl-receipt-info ID ::= {id-nat 10}
+
+id-nat-notification-extensions ID ::= {id-nat 11}
+
+id-nat-nrn-extensions ID ::= {id-nat 12}
+
+id-nat-rn-extensions ID ::= {id-nat 13}
+
+id-nat-other-notification-type-fields ID ::= {id-nat 14}
+
+-- Correlation attributes
+id-cat-correlated-delivered-ipns ID ::= {id-cat 0}
+
+id-cat-correlated-delivered-replies ID ::= {id-cat 1}
+
+id-cat-delivered-ipn-summary ID ::= {id-cat 2}
+
+id-cat-delivered-replies-summary ID ::= {id-cat 3}
+
+id-cat-forwarded-ipms ID ::= {id-cat 4}
+
+id-cat-forwarding-ipms ID ::= {id-cat 5}
+
+id-cat-ipm-recipients ID ::= {id-cat 6}
+
+id-cat-obsoleted-ipms ID ::= {id-cat 7}
+
+id-cat-obsoleting-ipms ID ::= {id-cat 8}
+
+id-cat-related-ipms ID ::= {id-cat 9}
+
+id-cat-relating-ipms ID ::= {id-cat 10}
+
+id-cat-replied-to-ipm ID ::= {id-cat 11}
+
+id-cat-replying-ipms ID ::= {id-cat 12}
+
+id-cat-revised-reply-time ID ::= {id-cat 13}
+
+id-cat-submitted-ipn-status ID ::= {id-cat 14}
+
+id-cat-submitted-ipns ID ::= {id-cat 15}
+
+id-cat-submitted-reply-status ID ::= {id-cat 16}
+
+id-cat-subject-ipm ID ::= {id-cat 17}
+
+id-cat-recipient-category ID ::= {id-cat 18}
+
+-- Message content types (for use by MS and Directory)
+id-mct-p2-1984 ID ::=
+ {id-mct 0} -- P2 1984
+
+id-mct-p2-1988 ID ::= {id-mct 1} -- P2 1988
+
+-- Extended body part parameters
+id-ep-ia5-text ID ::= {id-ep 0}
+
+id-ep-g3-facsimile ID ::= {id-ep 2}
+
+id-ep-teletex ID ::= {id-ep 4}
+
+id-ep-videotex ID ::= {id-ep 5}
+
+id-ep-encrypted ID ::= {id-ep 6}
+
+id-ep-message ID ::= {id-ep 7}
+
+id-ep-general-text ID ::= {id-ep 11}
+
+id-ep-file-transfer ID ::= {id-ep 12}
+
+-- Value {id-ep 13} is no longer defined
+id-ep-notification ID ::= {id-ep 15}
+
+id-ep-voice ID ::= {id-ep 16}
+
+id-ep-content ID ::=
+ {id-ep 17} -- This value is not used directly, only as a prefix
+
+-- Encoded Information Types
+id-eit-file-transfer ID ::= {id-eit 0}
+
+id-eit-voice ID ::= {id-eit 1}
+
+-- Voice Encoded Information Types
+id-voice-11khz-sample ID ::=
+ {id-eit-voice 0}
+
+id-voice-22khz-sample ID ::= {id-eit-voice 1}
+
+id-voice-cd-quality ID ::= {id-eit-voice 2}
+
+id-voice-g711-mu-law ID ::= {id-eit-voice 3}
+
+id-voice-g726-32k-adpcm ID ::= {id-eit-voice 4}
+
+id-voice-g728-16k-ld-celp ID ::= {id-eit-voice 5}
+
+-- Matching-rules
+id-mr-ipm-identifier ID ::= {id-mr 0}
+
+id-mr-or-descriptor ID ::= {id-mr 1}
+
+id-mr-or-descriptor-elements ID ::= {id-mr 2}
+
+id-mr-or-descriptor-substring-elements ID ::= {id-mr 3}
+
+id-mr-recipient-specifier ID ::= {id-mr 4}
+
+id-mr-recipient-specifier-elements ID ::= {id-mr 5}
+
+id-mr-recipient-specifier-substring-elements ID ::= {id-mr 6}
+
+id-mr-ipm-location ID ::= {id-mr 7}
+
+id-mr-or-descriptor-single-element ID ::= {id-mr 8}
+
+id-mr-recipient-specifier-single-element ID ::= {id-mr 9}
+
+id-mr-circulation-member ID ::= {id-mr 10}
+
+id-mr-circulation-member-elements ID ::= {id-mr 11}
+
+id-mr-circulation-member-substring-elements ID ::= {id-mr 12}
+
+id-mr-circulation-member-single-element ID ::= {id-mr 13}
+
+id-mr-circulation-member-checkmark ID ::= {id-mr 14}
+
+id-mr-distribution-code ID ::= {id-mr 15}
+
+id-mr-information-category ID ::= {id-mr 16}
+
+-- Auto-actions
+id-aa-ipm-auto-acknowledgement ID ::= {id-aa 0}
+
+id-aa-ipm-auto-correlate ID ::= {id-aa 1}
+
+id-aa-ipm-auto-discard ID ::= {id-aa 2}
+
+id-aa-ipm-auto-advise ID ::= {id-aa 3}
+
+-- Auto-action-errors
+id-aae-auto-discard-error ID ::= {id-aae 0}
+
+id-aae-auto-forwarding-loop ID ::= {id-aae 1}
+
+id-aae-duplicate-ipn ID ::= {id-aae 2}
+
+-- Message Store types
+id-mst-invalid-assembly-instructions ID ::= {id-mst 0}
+
+id-mst-invalid-ipn ID ::= {id-mst 1}
+
+id-mst-assembly-instructions ID ::= {id-mst 2}
+
+id-mst-suspend-auto-acknowledgement ID ::= {id-mst 3}
+
+id-mst-prevent-nrn-generation ID ::= {id-mst 4}
+
+id-mst-originator-body-part-encryption-token ID ::= {id-mst 5}
+
+id-mst-originator-forwarded-content-token ID ::= {id-mst 6}
+
+id-mst-assembly-capability ID ::= {id-mst 7}
+
+-- Security extensions
+id-sec-ipm-security-request ID ::= {id-sec 0}
+
+id-sec-security-common-fields ID ::= {id-sec 1}
+
+-- Other notification types
+id-on-absence-advice ID ::= {id-on 0}
+
+id-on-change-of-address-advice ID ::= {id-on 1}
+
+-- Recipient extensions
+id-rex-circulation-list-indicator ID ::= {id-rex 0}
+
+id-rex-precedence ID ::= {id-rex 1}
+
+END -- of IPMSObjectIdentifiers
+
+-- Generated by Asnp, the ASN.1 pretty-printer of France Telecom R&D
+
diff --git a/lib/asn1/test/asn1_SUITE_data/x420/IPMSObjectIdentifiers2.asn b/lib/asn1/test/asn1_SUITE_data/x420/IPMSObjectIdentifiers2.asn
new file mode 100644
index 0000000000..2b46b27b3e
--- /dev/null
+++ b/lib/asn1/test/asn1_SUITE_data/x420/IPMSObjectIdentifiers2.asn
@@ -0,0 +1,33 @@
+-- Module IPMSObjectIdentifiers2 (X.420:06/1999)
+IPMSObjectIdentifiers2 {iso standard mhs(10021) ipms(7) modules(0)
+ object-identifiers(0)} DEFINITIONS IMPLICIT TAGS ::=
+BEGIN
+
+-- Prologue
+-- Exports everything.
+IMPORTS -- nothing -- ;
+
+ID ::= OBJECT IDENTIFIER
+
+-- Interpersonal Messaging (ISO/IEC extensions)
+id-iso-ipms ID ::=
+ {iso standard mhs(10021) ipms(7)}
+
+-- Categories
+id-iso-mod ID ::= {id-iso-ipms 0} -- modules; not definitive
+
+id-iso-cs ID ::= {id-iso-ipms 1} -- character sets
+
+-- Modules
+id-mod-object-identifiers-2 ID ::= {id-iso-mod 0} -- not definitive
+
+id-mod-extended-body-part-types-2 ID ::= {id-iso-mod 1} -- not definitive
+
+-- Registration Authority for General Text Character Set EITs
+id-cs-eit-authority ID ::=
+ {id-iso-cs 0}
+
+END -- of IPMSObjectIdentifiers2
+
+-- Generated by Asnp, the ASN.1 pretty-printer of France Telecom R&D
+
diff --git a/lib/asn1/test/asn1_SUITE_data/x420/IPMSSecurityExtensions.asn b/lib/asn1/test/asn1_SUITE_data/x420/IPMSSecurityExtensions.asn
new file mode 100644
index 0000000000..8c692ccb31
--- /dev/null
+++ b/lib/asn1/test/asn1_SUITE_data/x420/IPMSSecurityExtensions.asn
@@ -0,0 +1,143 @@
+-- Module IPMSSecurityExtensions (X.420:06/1999)
+IPMSSecurityExtensions {joint-iso-itu-t mhs(6) ipms(1) modules(0)
+ ipm-security-extensions(14) version-1999(1)} DEFINITIONS IMPLICIT TAGS ::=
+BEGIN
+
+-- Prologue
+-- Exports everything
+IMPORTS
+ -- MTS Abstract Service
+ Certificates, Content, ContentIntegrityCheck, ExtendedCertificates,
+ EXTENSION, MessageOriginAuthenticationCheck, MessageToken, EncryptionKey
+ --==
+ FROM MTSAbstractService {joint-iso-itu-t mhs(6) mts(3) modules(0)
+ mts-abstract-service(1) version-1999(1)}
+ -- IPMS Information Objects
+ IPMS-EXTENSION
+ --==
+ FROM IPMSInformationObjects {joint-iso-itu-t mhs(6) ipms(1) modules(0)
+ information-objects(2) version-1999(1)}
+ -- IPMS Heading Extensions
+ BodyPartNumber
+ --==
+ FROM IPMSHeadingExtensions {joint-iso-itu-t mhs(6) ipms(1) modules(0)
+ heading-extensions(6) version-1999(1)}
+ -- Directory Authentication Framework
+ AlgorithmIdentifier, ENCRYPTED{}
+ --==
+ FROM AuthenticationFramework {joint-iso-itu-t ds(5) module(1)
+ authenticationFramework(7) 3}
+ -- Directory Certificate Extensions
+ CertificateAssertion
+ --==
+ FROM CertificateExtensions {joint-iso-itu-t ds(5) module(1)
+ certificateExtensions(26) 0}
+ -- IPMS Object Identifiers
+ id-sec-ipm-security-request, id-sec-security-common-fields
+ --==
+ FROM IPMSObjectIdentifiers {joint-iso-itu-t mhs(6) ipms(1) modules(0)
+ object-identifiers(0) version-1999(1)};
+
+-- Recipient Security Request
+recipient-security-request IPMS-EXTENSION ::= {
+ VALUE RecipientSecurityRequest,
+ IDENTIFIED BY id-sec-ipm-security-request
+}
+
+RecipientSecurityRequest ::= BIT STRING {
+ content-non-repudiation(0), content-proof(1), ipn-non-repudiation(2),
+ ipn-proof(3)}
+
+-- IPN Security Response
+ipn-security-response IPMS-EXTENSION ::= {
+ VALUE IpnSecurityResponse,
+ IDENTIFIED BY id-sec-security-common-fields
+}
+
+IpnSecurityResponse ::= SET {
+ content-or-arguments
+ CHOICE {original-content OriginalContent,
+ original-security-arguments
+ SET {original-content-integrity-check
+ [0] OriginalContentIntegrityCheck OPTIONAL,
+ original-message-origin-authentication-check
+ [1] OriginalMessageOriginAuthenticationCheck OPTIONAL,
+ original-message-token
+ [2] OriginalMessageToken OPTIONAL}},
+ security-diagnostic-code SecurityDiagnosticCode OPTIONAL
+}
+
+-- MTS security fields
+OriginalContent ::= Content
+
+OriginalContentIntegrityCheck ::= ContentIntegrityCheck
+
+OriginalMessageOriginAuthenticationCheck ::= MessageOriginAuthenticationCheck
+
+OriginalMessageToken ::= MessageToken
+
+-- Security Diagnostic Codes
+SecurityDiagnosticCode ::= INTEGER {
+ integrity-failure-on-subject-message(0),
+ integrity-failure-on-forwarded-message(1),
+ moac-failure-on-subject-message(2), unsupported-security-policy(3),
+ unsupported-algorithm-identifier(4), decryption-failed(5), token-error(6),
+ unable-to-sign-notification(7), unable-to-sign-message-receipt(8),
+ authentication-failure-on-subject-message(9),
+ security-context-failure-message(10), message-sequence-failure(11),
+ message-security-labelling-failure(12), repudiation-failure-of-message(13),
+ failure-of-proof-of-message(14), signature-key-unobtainable(15),
+ decryption-key-unobtainable(16), key-failure(17),
+ unsupported-request-for-security-service(18),
+ inconsistent-request-for-security-service(19),
+ ipn-non-repudiation-provided-instead-of-content-proof(20),
+ token-decryption-failed(21), double-enveloping-message-restoring-failure(22),
+ unauthorised-dl-member(23), reception-security-failure(24),
+ unsuitable-alternate-recipient(25), security-services-refusal(26),
+ unauthorised-recipient(27), unknown-certification-authority-name(28),
+ unknown-dl-name(29), unknown-originator-name(30), unknown-recipient-name(31),
+ security-policy-violation(32)}
+
+-- Security Envelope Extensions
+body-part-encryption-token EXTENSION ::= {
+ BodyPartTokens,
+ RECOMMENDED CRITICALITY {for-delivery},
+ IDENTIFIED BY standard-extension:43
+}
+
+BodyPartTokens ::=
+ SET OF
+ SET {body-part-number BodyPartNumber,
+ body-part-choice
+ CHOICE {encryption-token EncryptionToken,
+ message-or-content-body-part [0] BodyPartTokens}
+ }
+
+EncryptionToken ::= SET {
+ encryption-algorithm-identifier AlgorithmIdentifier,
+ encrypted-key ENCRYPTED{EncryptionKey},
+ recipient-certificate-selector [0] CertificateAssertion OPTIONAL,
+ recipient-certificate [1] Certificates OPTIONAL,
+ originator-certificate-selector [2] CertificateAssertion OPTIONAL,
+ originator-certificates [3] ExtendedCertificates OPTIONAL,
+ ...
+}
+
+forwarded-content-token EXTENSION ::= {
+ ForwardedContentToken,
+ RECOMMENDED CRITICALITY {for-delivery},
+ IDENTIFIED BY standard-extension:44
+}
+
+ForwardedContentToken ::=
+ SET OF
+ SET {body-part-number BodyPartNumber,
+ body-part-choice
+ CHOICE {forwarding-token MessageToken,
+ message-or-content-body-part ForwardedContentToken
+ }}
+
+END -- of IPMSSecurityExtensions
+
+-- Generated by Asnp, the ASN.1 pretty-printer of France Telecom R&D
+
diff --git a/lib/asn1/test/asn1_SUITE_data/x420/IPMSUpperBounds.asn b/lib/asn1/test/asn1_SUITE_data/x420/IPMSUpperBounds.asn
new file mode 100644
index 0000000000..27324f614f
--- /dev/null
+++ b/lib/asn1/test/asn1_SUITE_data/x420/IPMSUpperBounds.asn
@@ -0,0 +1,46 @@
+-- Module IPMSUpperBounds (X.420:06/1999)
+IPMSUpperBounds {joint-iso-itu-t mhs(6) ipms(1) modules(0) upper-bounds(10)
+ version-1999(1)} DEFINITIONS IMPLICIT TAGS ::=
+BEGIN
+
+-- Prologue
+-- Exports everything.
+IMPORTS -- nothing -- ;
+
+-- Upper bounds
+ub-alpha-code-length INTEGER ::= 16
+
+ub-auto-forward-comment INTEGER ::= 256
+
+ub-circulation-list-members INTEGER ::= 256
+
+ub-distribution-codes INTEGER ::= 16
+
+ub-extended-subject-length INTEGER ::= 256
+
+ub-free-form-name INTEGER ::= 64
+
+ub-information-categories INTEGER ::= 16
+
+ub-information-category-length INTEGER ::= 64
+
+ub-ipm-identifier-suffix INTEGER ::= 2
+
+ub-local-ipm-identifier INTEGER ::= 64
+
+ub-manual-handling-instruction-length INTEGER ::= 128
+
+ub-manual-handling-instructions INTEGER ::= 16
+
+ub-originators-reference-length INTEGER ::= 64
+
+ub-precedence INTEGER ::= 127
+
+ub-subject-field INTEGER ::= 128
+
+ub-telephone-number INTEGER ::= 32
+
+END -- of IPMSUpperBounds
+
+-- Generated by Asnp, the ASN.1 pretty-printer of France Telecom R&D
+
diff --git a/lib/asn1/test/asn1_SUITE_data/x420/ISO-STANDARD-9541-FONT-ATTRIBUTE-SET.asn b/lib/asn1/test/asn1_SUITE_data/x420/ISO-STANDARD-9541-FONT-ATTRIBUTE-SET.asn
new file mode 100644
index 0000000000..b7efd7417e
--- /dev/null
+++ b/lib/asn1/test/asn1_SUITE_data/x420/ISO-STANDARD-9541-FONT-ATTRIBUTE-SET.asn
@@ -0,0 +1,459 @@
+-- Module ISO-STANDARD-9541-FONT-ATTRIBUTE-SET (ISO:1991)
+--
+-- Copyright � ISO/IEC 1991. This version of
+-- this ASN.1 module is part of ISO|IEC 9541-2:1991;
+-- see the ISO|IEC text itself for full legal notices.
+--
+ISO-STANDARD-9541-FONT-ATTRIBUTE-SET {1 0 9541 2 2} DEFINITIONS ::=
+BEGIN
+
+EXPORTS Font-Attribute-Set;
+
+IMPORTS Structured-Name
+ FROM ISO9541-SN {1 0 9541 2 3};
+
+Font-Attribute-Set ::= SEQUENCE {
+ name-prefixes [0] IMPLICIT SET OF Name-Prefix OPTIONAL,
+ iso-standard-9541-fontname [1] IMPLICIT Global-Name OPTIONAL,
+ iso-standard-9541-fontdescription [2] IMPLICIT Font-Description OPTIONAL,
+ iso-standard-9541-wrmodes [3] IMPLICIT Writing-Modes OPTIONAL,
+ non-iso-properties [5] IMPLICIT Property-List OPTIONAL
+}
+
+Font-Description ::= SET {
+ iso-standard-9541-dataversion [0] IMPLICIT Data-Version OPTIONAL,
+ iso-standard-9541-Standardversion [1] IMPLICIT Cardinal OPTIONAL,
+ iso-standard-9541-datasource [2] IMPLICIT Global-Name OPTIONAL,
+ iso-standard-9541-datacopyright [3] Message OPTIONAL,
+ iso-standard-9541-dsnsource [4] IMPLICIT Global-Name OPTIONAL,
+ iso-standard-9541-dsncopyright [5] Message OPTIONAL,
+ iso-standard-9541-relunits [6] IMPLICIT Cardinal DEFAULT 1,
+ iso-standard-9541-typeface [7] Message OPTIONAL,
+ iso-standard-9541-fontfamily [8] Match-String OPTIONAL,
+ iso-standard-9541-posture [9] IMPLICIT Posture-Code OPTIONAL,
+ iso-standard-9541-postureangle [10] IMPLICIT Angle OPTIONAL,
+ iso-standard-9541-weight [11] IMPLICIT Weight-Code OPTIONAL,
+ iso-standard-9541-propwidth [12] IMPLICIT Width-Code OPTIONAL,
+ iso-standard-9541-glyphcomp [13] IMPLICIT Glyph-Complement OPTIONAL,
+ iso-standard-9541-nomwrmode [14] IMPLICIT Global-Name OPTIONAL,
+ iso-standard-9541-dsnsize [15] IMPLICIT Rational OPTIONAL,
+ iso-standard-9541-minsize [16] IMPLICIT Rational OPTIONAL,
+ iso-standard-9541-maxsize [17] IMPLICIT Rational OPTIONAL,
+ iso-standard-9541-capheight [18] IMPLICIT Rel-Rational OPTIONAL,
+ iso-standard-9541-lcheight [19] IMPLICIT Rel-Rational OPTIONAL,
+ iso-standard-9541-dsngroup [20] IMPLICIT Design-Group OPTIONAL,
+ iso-standard-9541-structure [21] IMPLICIT Structure-Code OPTIONAL,
+ iso-standard-9541-minfeatsz [22] IMPLICIT Rel-Rational OPTIONAL,
+ iso-standard-9541-nomcapstemwidth [23] IMPLICIT Rel-Rational OPTIONAL,
+ iso-standard-9541-nomlcstemwidth [24] IMPLICIT Rel-Rational OPTIONAL,
+ non-iso-properties [25] IMPLICIT Property-List OPTIONAL
+}
+
+Name-Prefix ::= SEQUENCE {
+ --see NOTE 3 at the end of 6.1
+ index [0] IMPLICIT Code,
+ prefix [1] IMPLICIT Structured-Name
+}
+
+Data-Version ::= SEQUENCE {
+ major [0] IMPLICIT Cardinal OPTIONAL,
+ minor [1] IMPLICIT Cardinal OPTIONAL,
+ timestamp [2] IMPLICIT UTCTime OPTIONAL
+}
+
+Posture-Code ::= INTEGER {
+ not-applicable(0), upright(1), oblique-forward(2), oblique-backward(3),
+ italic-forward(4), italic-backward(5), other(6)}
+
+Weight-Code ::= INTEGER {
+ not-applicable(0), ultra-light(1), extra-light(2), light(3), semi-light(4),
+ medium(5), semi-bold(6), bold(7), extra-bold(8), ultra-bold(9)}
+
+Width-Code ::= INTEGER {
+ not-applicable(0), ultra-condensed(1), extra-condensed(2), condensed(3),
+ semi-condensed(4), medium(5), semi-expanded(6), expanded(7),
+ extra-expanded(8), ultra-expanded(9)}
+
+Glyph-Complement ::= SEQUENCE {
+ -- at least one included glyph list or at least one
+ -- included glyph collection list is mandatory
+ iso-standard-9541-numglyphs [0] IMPLICIT Cardinal OPTIONAL,
+ iso-standard-9541-incglyphcols [1] IMPLICIT SET OF Global-Name OPTIONAL,
+ -- at least one is required
+ iso-standard-9541-excglyphcols [2] IMPLICIT SET OF Global-Name OPTIONAL,
+ -- at least one is required
+ iso-standard-9541-incglyphs [3] IMPLICIT SET OF Global-Name OPTIONAL,
+ -- at least one is required
+ iso-standard-9541-excglyphs [4] IMPLICIT SET OF Global-Name OPTIONAL,
+ -- at least one is required
+ non-iso-properties [5] IMPLICIT Property-List OPTIONAL
+}
+
+Design-Group ::= SEQUENCE {
+ -- see 9541-1 Annex-A for code values
+ group-code [0] IMPLICIT Code,
+ subgroup-code [1] IMPLICIT Code,
+ specific-group-code [2] IMPLICIT Code
+}
+
+Structure-Code ::= INTEGER {not-applicable(0), solid(1), outline(2)}
+
+Writing-Modes ::= SET {
+ iso-standard-9541-wrmode [0] IMPLICIT SET OF Writing-Mode OPTIONAL,
+ non-iso-properties [1] IMPLICIT Property-List OPTIONAL
+}
+
+Writing-Mode ::= SEQUENCE {
+ iso-standard-9541-wrmodename [0] IMPLICIT Global-Name,
+ wrmode-properties [1] IMPLICIT Modal-Properties
+}
+
+Modal-Properties ::= SET {
+ iso-standard-9541-nomescdir [0] IMPLICIT Angle OPTIONAL,
+ iso-standard-9541-escclass [1] IMPLICIT Esc-Class-Code OPTIONAL,
+ iso-standard-9541-avgescx [2] IMPLICIT Rel-Rational OPTIONAL,
+ iso-standard-9541-avgescy [3] IMPLICIT Rel-Rational OPTIONAL,
+ iso-standard-9541-avglcescx [4] IMPLICIT Rel-Rational OPTIONAL,
+ iso-standard-9541-avglcescy [5] IMPLICIT Rel-Rational OPTIONAL,
+ iso-standard-9541-avgcapescx [6] IMPLICIT Rel-Rational OPTIONAL,
+ iso-standard-9541-avgcapescy [7] IMPLICIT Rel-Rational OPTIONAL,
+ iso-standard-9541-tabescx [8] IMPLICIT Rel-Rational OPTIONAL,
+ iso-standard-9541-tabescy [9] IMPLICIT Rel-Rational OPTIONAL,
+ iso-standard-9541-maxfontext [10] IMPLICIT Max-Extents OPTIONAL,
+ iso-standard-9541-sectors [11] IMPLICIT Sectors OPTIONAL,
+ iso-standard-9541-escadjs [12] IMPLICIT SET OF Adjusts OPTIONAL,
+ iso-standard-9541-minescadjsze [13] IMPLICIT Rational OPTIONAL,
+ iso-standard-9541-maxescadjsze [14] IMPLICIT Rational OPTIONAL,
+ iso-standard-9541-scores [15] IMPLICIT Scores OPTIONAL,
+ iso-standard-9541-vscripts [16] IMPLICIT Variant-Scripts OPTIONAL,
+ iso-standard-9541-minlinesp [17] IMPLICIT Alignment-Spacing OPTIONAL,
+ iso-standard-9541-minanascale [18] IMPLICIT Rational OPTIONAL,
+ iso-standard-9541-maxanascale [19] IMPLICIT Rational OPTIONAL,
+ iso-standard-9541-nomalign [20] IMPLICIT Global-Name OPTIONAL,
+ iso-standard-9541-alignmodes [21] IMPLICIT Alignment-Modes OPTIONAL,
+ iso-standard-9541-copyfits [22] IMPLICIT Copyfits OPTIONAL,
+ iso-standard-9541-dsnwordadd [23] IMPLICIT Rel-Rational OPTIONAL,
+ iso-standard-9541-dsnwordampl [24] IMPLICIT Rational OPTIONAL,
+ iso-standard-9541-minwordadd [25] IMPLICIT Rel-Rational OPTIONAL,
+ iso-standard-9541-minwordampl [26] IMPLICIT Rational OPTIONAL,
+ iso-standard-9541-maxwordadd [27] IMPLICIT Rel-Rational OPTIONAL,
+ iso-standard-9541-maxwordampl [28] IMPLICIT Rational OPTIONAL,
+ iso-standard-9541-dsnletteradd [29] IMPLICIT Rel-Rational OPTIONAL,
+ iso-standard-9541-dsnletterampl [30] IMPLICIT Rational OPTIONAL,
+ iso-standard-9541-minletteradd [31] IMPLICIT Rel-Rational OPTIONAL,
+ iso-standard-9541-minletterampl [32] IMPLICIT Rational OPTIONAL,
+ iso-standard-9541-maxletteradd [33] IMPLICIT Rel-Rational OPTIONAL,
+ iso-standard-9541-maxletterampl [34] IMPLICIT Rational OPTIONAL,
+ iso-standard-9541-glyphmetrics [35] IMPLICIT Glyph-Metrics OPTIONAL,
+ non-iso-properties [36] IMPLICIT Property-List OPTIONAL
+}
+
+Esc-Class-Code ::= INTEGER {not-applicable(0), monospace(1), proportional(2)}
+
+Max-Extents ::= SEQUENCE {
+ max-minx [0] IMPLICIT Rel-Rational,
+ max-miny [1] IMPLICIT Rel-Rational,
+ max-maxx [2] IMPLICIT Rel-Rational,
+ max-maxy [3] IMPLICIT Rel-Rational
+}
+
+Sectors ::= SET {
+ iso-standard-9541-sector [0] IMPLICIT SEQUENCE OF Sector OPTIONAL,
+ non-iso-properties [1] IMPLICIT Property-List OPTIONAL
+}
+
+Sector ::= SEQUENCE {
+ sector-left [0] IMPLICIT Rel-Rational,
+ sector-right [1] IMPLICIT Rel-Rational
+}
+
+Adjusts ::= SET {
+ iso-standard-9541-adjust [0] IMPLICIT SET OF Adjust,
+ non-iso-properties [1] IMPLICIT Property-List OPTIONAL
+}
+
+Adjust ::= SET {
+ iso-standard-9541-escadjname [0] IMPLICIT Global-Name,
+ adjust-properties [1] IMPLICIT Adjust-Properties
+}
+
+Adjust-Properties ::= SET {
+ iso-standard-9541-cpea [0] IMPLICIT CPEA-Properties OPTIONAL,
+ iso-standard-9541-sec [1] IMPLICIT SEC-Properties OPTIONAL,
+ non-iso-properties [2] IMPLICIT Property-List OPTIONAL
+}
+
+CPEA-Properties ::= SET {
+ iso-standard-9541-ncpeaforwd [0] IMPLICIT Cardinal,
+ iso-standard-9541-ncpeabackwd [1] IMPLICIT Cardinal,
+ iso-standard-9541-cpeax [2] SEQUENCE OF Rel-Rational OPTIONAL,
+ -- at least one required
+ iso-standard-9541-cpeay [3] SEQUENCE OF Rel-Rational OPTIONAL,
+ non-iso-properties [4] IMPLICIT Property-List OPTIONAL
+}
+
+SEC-Properties ::= SET {
+ iso-standard-9541-secx
+ [0] SEQUENCE OF
+ SEQUENCE {-- at least one required
+ rational [0] IMPLICIT Rational,
+ rel-rational [1] IMPLICIT Rel-Rational} OPTIONAL,
+ iso-standard-9541-secy
+ [1] SEQUENCE OF
+ SEQUENCE {-- at least one required
+ rational [0] IMPLICIT Rational,
+ rel-rational [1] IMPLICIT Rel-Rational} OPTIONAL,
+ non-iso-properties [2] IMPLICIT Property-List OPTIONAL
+}
+
+Scores ::= SET {
+ iso-standard-9541-Score [0] IMPLICIT SET OF Score OPTIONAL,
+ non-iso-properties [1] IMPLICIT Property-List OPTIONAL
+}
+
+Score ::= SEQUENCE {
+ iso-standard-9541-scorename [0] IMPLICIT Global-Name,
+ score-property-list [1] IMPLICIT Score-Properties
+}
+
+Score-Properties ::= SET {
+ iso-standard-9541-scoreoffsetx [0] IMPLICIT Rel-Rational OPTIONAL,
+ iso-standard-9541-scoreoffsety [1] IMPLICIT Rel-Rational OPTIONAL,
+ iso-standard-9541-scorethick [2] IMPLICIT Rel-Rational OPTIONAL,
+ non-iso-properties [3] IMPLICIT Property-List OPTIONAL
+}
+
+Variant-Scripts ::= SET {
+ iso-standard-9541-vscript [0] IMPLICIT SET OF Vscript OPTIONAL,
+ non-iso-properties [1] IMPLICIT Property-List OPTIONAL
+}
+
+Vscript ::= SEQUENCE {
+ iso-standard-9541-vsname [0] IMPLICIT Global-Name,
+ vscript-property-list [1] IMPLICIT Vscript-Properties
+}
+
+Vscript-Properties ::= SET {
+ iso-standard-9541-vsoffsetx [0] IMPLICIT Rel-Rational OPTIONAL,
+ iso-standard-9541-vsoffsety [1] IMPLICIT Rel-Rational OPTIONAL,
+ iso-standard-9541-vsscalex [2] IMPLICIT Rational OPTIONAL,
+ iso-standard-9541-vsscaley [3] IMPLICIT Rational OPTIONAL,
+ non-iso-properties [4] IMPLICIT Property-List OPTIONAL
+}
+
+Alignment-Spacing ::= SEQUENCE {
+ minlinesp-left [0] IMPLICIT Rel-Rational,
+ minlinesp-right [1] IMPLICIT Rel-Rational
+}
+
+Alignment-Modes ::= SET {
+ iso-standard-9541-align [0] IMPLICIT SET OF Alignment OPTIONAL,
+ non-iso-properties [1] IMPLICIT Property-List OPTIONAL
+}
+
+Alignment ::= SEQUENCE {
+ iso-standard-9541-alignname [0] IMPLICIT Global-Name,
+ alignment-property-list [1] IMPLICIT Align-Properties
+}
+
+Align-Properties ::= SET {
+ iso-standard-9541-alignoffsetx [0] IMPLICIT Rel-Rational OPTIONAL,
+ iso-standard-9541-alignoffsety [1] IMPLICIT Rel-Rational OPTIONAL,
+ iso-standard-9541-alignscalex [2] IMPLICIT Rational OPTIONAL,
+ iso-standard-9541-alignscaley [3] IMPLICIT Rational OPTIONAL,
+ non-iso-properties [4] IMPLICIT Property-List OPTIONAL
+}
+
+Copyfits ::= SET {
+ iso-standard-9541-copyfit [0] IMPLICIT SET OF Copyfit OPTIONAL,
+ non-iso-properties [1] IMPLICIT Property-List OPTIONAL
+}
+
+Copyfit ::= SEQUENCE {
+ iso-standard-9541-copyfitname [0] IMPLICIT Global-Name,
+ copyfit-properties [1] IMPLICIT Copyfit-Properties
+}
+
+Copyfit-Properties ::= SET {
+ iso-standard-9541-copyfitmeasure [0] IMPLICIT Rational OPTIONAL,
+ non-iso-properties [1] IMPLICIT Property-List OPTIONAL
+}
+
+Glyph-Metrics ::= SET {
+ iso-standard-9541-gmetric [0] IMPLICIT SET OF Glyph-Property-List,
+ non-iso-properties [1] IMPLICIT Property-List OPTIONAL
+}
+
+Glyph-Property-List ::= SEQUENCE {
+ iso-standard-9541-gname [0] IMPLICIT Global-Name,
+ glyph-properties [1] IMPLICIT Glyph-Properties
+}
+
+Glyph-Properties ::= SET {
+ iso-standard-9541-px [0] IMPLICIT Rel-Rational OPTIONAL,
+ iso-standard-9541-py [1] IMPLICIT Rel-Rational OPTIONAL,
+ iso-standard-9541-ex [2] IMPLICIT Rel-Rational,
+ iso-standard-9541-ey [3] IMPLICIT Rel-Rational,
+ iso-standard-9541-ext [4] IMPLICIT Extents,
+ iso-standard-9541-lgs [5] IMPLICIT Ligatures OPTIONAL,
+ iso-standard-9541-peas [6] IMPLICIT P-Adjusts OPTIONAL,
+ iso-standard-9541-cpeai [7] IMPLICIT C-Indicator OPTIONAL,
+ iso-standard-9541-eai [8] IMPLICIT E-Code OPTIONAL,
+ iso-standard-9541-minex [9] IMPLICIT Rel-Rational OPTIONAL,
+ iso-standard-9541-miney [10] IMPLICIT Rel-Rational OPTIONAL,
+ iso-standard-9541-maxex [11] IMPLICIT Rel-Rational OPTIONAL,
+ iso-standard-9541-maxey [12] IMPLICIT Rel-Rational OPTIONAL,
+ non-iso-properties [13] IMPLICIT Property-List OPTIONAL
+}
+
+Extents ::= SET {
+ minx [0] IMPLICIT Rel-Rational OPTIONAL,
+ miny [1] IMPLICIT Rel-Rational OPTIONAL,
+ maxx [2] IMPLICIT Rel-Rational OPTIONAL,
+ maxy [3] IMPLICIT Rel-Rational OPTIONAL
+}
+
+Ligatures ::= SET {
+ iso-standard-9541-lg [0] IMPLICIT SET OF Ligature OPTIONAL,
+ non-iso-properties [1] IMPLICIT Property-List OPTIONAL
+}
+
+Ligature ::= SET {
+ iso-standard-9541-lgn [0] IMPLICIT Global-Name,
+ iso-standard-9541-lgsn [1] SEQUENCE OF Global-Name
+}
+
+P-Adjusts ::= SET {
+ iso-standard-9541-pea [0] IMPLICIT SET OF P-Adjust OPTIONAL,
+ non-iso-properties [1] IMPLICIT Property-List OPTIONAL
+}
+
+P-Adjust ::= SEQUENCE {
+ iso-standard-9541-pean [0] IMPLICIT Global-Name,
+ p-adjust-property-list [1] IMPLICIT P-Adjust-Properties
+}
+
+P-Adjust-Properties ::= SET {
+ iso-standard-9541-peax
+ [0] SEQUENCE OF
+ SEQUENCE {-- at least one required
+ global-name [0] IMPLICIT Global-Name,
+ rel-rational [1] IMPLICIT Rel-Rational} OPTIONAL,
+ iso-standard-9541-peay
+ [1] SEQUENCE OF
+ SEQUENCE {-- at least one required
+ global-name [0] IMPLICIT Global-Name,
+ rel-rational [1] IMPLICIT Rel-Rational} OPTIONAL,
+ iso-standard-9541-speaforwdx [2] SEQUENCE OF Rel-Rational OPTIONAL,
+ iso-standard-9541-speaforwdy [3] SEQUENCE OF Rel-Rational OPTIONAL,
+ iso-standard-9541-speabackwdx [4] SEQUENCE OF Rel-Rational OPTIONAL,
+ iso-standard-9541-speabackwdy [5] SEQUENCE OF Rel-Rational OPTIONAL,
+ non-iso-properties [6] IMPLICIT Property-List OPTIONAL
+}
+
+C-Indicator ::= SEQUENCE {
+ c-forward [0] IMPLICIT Cardinal,
+ c-backward [1] IMPLICIT Cardinal
+}
+
+E-Code ::= INTEGER {
+ not-applicable(0), letter-space(1), word-space(2), no-adjust(3)}
+
+-- The following Data Types are used in the above structures
+-- The following Data Types are used in the above structures
+Property ::= SEQUENCE {
+ property-name [0] Global-Name,
+ property-value [1] Property-Value
+}
+
+Property-Value ::= CHOICE {
+ value [0] Value,
+ value-list [1] Value-List,
+ ordered-value-list [2] Ordered-Value-List,
+ property-list [3] Property-List,
+ ordered-property-list [4] Ordered-Property-List
+}
+
+Value-List ::= SET OF Value
+
+Ordered-Value-List ::= SEQUENCE OF Value
+
+Property-List ::= SET OF Property
+
+Ordered-Property-List ::= SEQUENCE OF Property
+
+Value ::= CHOICE {
+ global-Name [0] Global-Name,
+ match-String [1] Match-String,
+ message [2] Message,
+ octetString [3] OCTET STRING,
+ boolean [4] BOOLEAN,
+ integer [5] Integer,
+ cardinal [6] Cardinal,
+ code [7] Code,
+ rational [8] Rational,
+ rel-Rational [9] Rel-Rational,
+ angle [10] Angle,
+ proprietary-Data [11] Proprietary-Data
+}
+
+Global-Name ::= SEQUENCE {
+ -- see global name note at the end of clause 6.1
+ prefix-index [0] IMPLICIT Code OPTIONAL,
+ name-value [1] IMPLICIT Structured-Name
+}
+
+Match-String ::= CHOICE {
+ numeric [0] NumericString,
+ printable [1] PrintableString,
+ teletex [2] TeletexString,
+ videotex [3] VideotexString,
+ visible [4] VisibleString,
+ ia5 [5] IA5String,
+ graphic [6] GraphicString,
+ general [7] GeneralString
+}
+
+Message ::= CHOICE {
+ numeric [0] NumericString,
+ printable [1] PrintableString,
+ teletex [2] TeletexString,
+ videotex [3] VideotexString,
+ visible [4] VisibleString,
+ ia5 [5] IA5String,
+ graphic [6] GraphicString,
+ general [7] GeneralString
+}
+
+Integer ::= INTEGER {first(-2147483648), last(2147483647)}
+
+Cardinal ::= INTEGER {first(0), last(4294967295)}
+
+Code ::= INTEGER {first(0), last(255)}
+
+Rational ::= SEQUENCE {
+ numerator [0] IMPLICIT INTEGER,
+ denominator [1] IMPLICIT INTEGER {first(1), last(2147483647)} OPTIONAL
+}
+
+-- denominator defaults to 1
+Rel-Rational ::= Rational
+
+-- expresses glyph coordinate units
+-- denominator defaults to relunits
+Angle ::=
+ Rational
+
+-- expresses units of degrees, with a
+-- value range of -360 to +360
+-- denominator defaults to 1
+Proprietary-Data ::= SEQUENCE {
+ prop-data-message [0] Message OPTIONAL,
+ prop-data-key [1] IMPLICIT OCTET STRING OPTIONAL,
+ prop-data [2] IMPLICIT OCTET STRING
+}
+
+END
+
+-- Generated by Asnp, the ASN.1 pretty-printer of France Telecom R&D
+
diff --git a/lib/asn1/test/asn1_SUITE_data/x420/ISO8571-FTAM.asn b/lib/asn1/test/asn1_SUITE_data/x420/ISO8571-FTAM.asn
new file mode 100644
index 0000000000..a57a276704
--- /dev/null
+++ b/lib/asn1/test/asn1_SUITE_data/x420/ISO8571-FTAM.asn
@@ -0,0 +1,1453 @@
+-- Module ISO8571-FTAM (ISO 8571-4:1988)
+-- See also the README file
+-- See also the index of all ASN.1 assignments needed in this Recommendation
+
+--
+-- Copyright ? ISO/IEC 1988. This version of
+-- this ASN.1 module is part of ISO/IEC 8571-4:1988;
+-- see the ISO|IEC text itself for full legal notices.
+--
+ISO8571-FTAM {iso standard 8571 application-context(1) iso-ftam(1)} DEFINITIONS
+::=
+BEGIN
+
+PDU ::= CHOICE {
+ fTAM-Regime-PDU FTAM-Regime-PDU,
+ file-PDU File-PDU,
+ bulk-Data-PDU Bulk-Data-PDU,
+ fSM-PDU FSM-PDU
+}
+
+FTAM-Regime-PDU ::= CHOICE {
+ f-initialize-request [0] IMPLICIT F-INITIALIZE-request,
+ f-initialize-response [1] IMPLICIT F-INITIALIZE-response,
+ f-terminate-request [2] IMPLICIT F-TERMINATE-request,
+ f-terminate-response [3] IMPLICIT F-TERMINATE-response,
+ f-u-abort-request [4] IMPLICIT F-U-ABORT-request,
+ f-p-abort-request [5] IMPLICIT F-P-ABORT-request
+}
+
+F-INITIALIZE-request ::= SEQUENCE {
+ protocol-Version Protocol-Version DEFAULT {version-1},
+ implementation-information Implementation-Information OPTIONAL,
+ presentation-tontext-management [2] IMPLICIT BOOLEAN DEFAULT FALSE,
+ service-class Service-Class DEFAULT {transfer-class},
+ -- Only the valid combinations as specified in ISO 8571-3 are allowed.
+ functional-units Functional-Units,
+ attribute-groups Attribute-Groups DEFAULT {},
+ shared-ASE-information Shared-ASE-Information OPTIONAL,
+ ftam-quality-of-Service FTAM-Quality-of-Service,
+ contents-type-list Contents-Type-List OPTIONAL,
+ initiator-identity User-Identity OPTIONAL,
+ account Account OPTIONAL,
+ filestore-password Password OPTIONAL,
+ checkpoint-window [8] IMPLICIT INTEGER DEFAULT 1
+}
+
+-- lf the recovery or restart data transfer functional units are
+-- not available, the Checkpoint-window Parameter shall not be sent.
+F-INITIALIZE-response ::= SEQUENCE {
+ state-result State-Result DEFAULT success,
+ action-result Action-Result DEFAULT success,
+ protocol-Version Protocol-Version DEFAULT {version-1},
+ implementation-information Implementation-Information OPTIONAL,
+ presentation-tontext-management [2] IMPLICIT BOOLEAN DEFAULT FALSE,
+ service-class Service-Class DEFAULT {transfer-class},
+ -- Only the valid combinations as specified in ISO 8571-3 are allowed.
+ functional-units Functional-Units,
+ attribute-groups Attribute-Groups DEFAULT {},
+ shared-ASE-information Shared-ASE-Information OPTIONAL,
+ ftam-quality-of-Service FTAM-Quality-of-Service,
+ contents-type-list Contents-Type-List OPTIONAL,
+ diagnostic Diagnostic OPTIONAL,
+ checkpoint-window [8] IMPLICIT INTEGER DEFAULT 1
+}
+
+-- If the recovery or restart data transfer functional units are
+-- not available, the Checkpoint-window Parameter shall not be sent.
+Protocol-Version ::= [0] IMPLICIT BIT STRING {version-1(0), version-2(1)
+}
+
+Implementation-Information ::= [1] IMPLICIT GraphicString
+
+-- This Parameter is provided solely for the convenience of implementors
+-- needing to distinguish between implernentations of a specific version number
+-- of different equipment, it shall not be the subject of conformance test.
+Service-Class ::= [3] IMPLICIT BIT STRING {
+ unconstrained-class(0), management-class(1), transfer-class(2),
+ transfer-and-management-class(3), access-class(4)}
+
+Functional-Units ::= [4] IMPLICIT BIT STRING {
+ read(2), write(3), file-access(4), limited-file-management(5),
+ enhanced-file-management(6), grouping(7), fadu-locking(8), recovery(9),
+ restart-data-transfer(10), limited-filestore-management(11),
+ enhanced-filestore-management(12), object-manipulation(13),
+ group-manipulation(14), consecutive-access(15), concurrent-access(16)
+}
+
+-- Values 2 to 14 are Chosen to align with numbering scheme used in ISO 8571-3.
+Attribute-Groups ::= [5] IMPLICIT BIT STRING {
+ storage(0), security(1), private(2), extension(3)}
+
+-- The extension bit is defined if and only if the limited-filestore-management
+-- or the group-manipulation functional units are available.
+FTAM-Quality-of-Service ::= [6] IMPLICIT INTEGER {
+ no-recovery(0), class-1-recovery(1), class-2-recovery(2), class-3-recovery(3)
+}
+
+Contents-Type-List ::=
+ [7] IMPLICIT
+ SEQUENCE OF
+ CHOICE {document-type-name Document-Type-Name,
+ abstract-Syntax-name Abstract-Syntax-Name}
+
+F-TERMINATE-request ::= SEQUENCE {
+ shared-ASE-information Shared-ASE-Information OPTIONAL
+}
+
+F-TERMINATE-response ::= SEQUENCE {
+ shared-ASE-information Shared-ASE-Information OPTIONAL,
+ charging Charging OPTIONAL
+}
+
+F-U-ABORT-request ::= SEQUENCE {
+ action-result Action-Result DEFAULT success,
+ diagnostic Diagnostic OPTIONAL
+}
+
+F-P-ABORT-request ::= SEQUENCE {
+ action-result Action-Result DEFAULT success,
+ diagnostic Diagnostic OPTIONAL
+}
+
+File-PDU ::= CHOICE {
+ f-select-request [6] IMPLICIT F-SELECT-request,
+ f-select-response [7] IMPLICIT F-SELECT-response,
+ f-deselect-request [8] IMPLICIT F-DESELECT-request,
+ f-deselect-response [9] IMPLICIT F-DESELECT-response,
+ f-create-request [10] IMPLICIT F-CREATE-request,
+ f-create-response [11] IMPLICIT F-CREATE-response,
+ f-delete-request [12] IMPLICIT F-DELETE-request,
+ f-delete-response [13] IMPLICIT F-DELETE-response,
+ f-read-attrib-request [14] IMPLICIT F-READ-ATTRIB-request,
+ f-read-attrib-response [15] IMPLICIT F-READ-ATTRIB-response,
+ f-Change-attrib-reques [16] IMPLICIT F-CHANGE-ATTRIB-request,
+ f-Change-attrib-respon [17] IMPLICIT F-CHANGE-ATTRIB-response,
+ f-open-request [18] IMPLICIT F-OPEN-request,
+ f-open-response [19] IMPLICIT F-OPEN-response,
+ f-close-request [20] IMPLICIT F-CLOSE-request,
+ f-close-response [21] IMPLICIT F-CLOSE-response,
+ f-begin-group-request [22] IMPLICIT F-BEGIN-GROUP-request,
+ f-begin-group-response [23] IMPLICIT F-BEGIN-GROUP-response,
+ f-end-group-request [24] IMPLICIT F-END-GROUP-request,
+ f-end-group-response [25] IMPLICIT F-END-GROUP-response,
+ f-recover-request [26] IMPLICIT F-RECOVER-request,
+ f-recover-response [27] IMPLICIT F-RECOVER-response,
+ f-locate-request [28] IMPLICIT F-LOCATE-request,
+ f-locate-response [29] IMPLICIT F-LOCATE-response,
+ f-erase-request [30] IMPLICIT F-ERASE-request,
+ f-erase-response [31] IMPLICIT F-ERASE-response
+}
+
+F-SELECT-request ::= SEQUENCE {
+ attributes Select-Attributes,
+ requested-access Access-Request,
+ access-passwords Access-Passwords OPTIONAL,
+ path-access-passwords Path-Access-Passwords OPTIONAL,
+ -- This Parameter tan only be sent when the
+ -- limited-filestore-management or the object-manipulation or
+ -- the group-manipulation functional units are available.
+ concurrency-control Concurrency-Control OPTIONAL,
+ shared-ASE-information Shared-ASE-Information OPTIONAL,
+ account Account OPTIONAL
+}
+
+F-SELECT-response ::= SEQUENCE {
+ state-result State-Result DEFAULT success,
+ action-result Action-Result DEFAULT success,
+ attributes Select-Attributes,
+ referent-indicator Referent-Indicator OPTIONAL,
+ -- This Parameter tan only be sent when the
+ -- limited-filestore-management functional unit is available.
+ shared-ASE-information Shared-ASE-Information OPTIONAL,
+ diagnostic Diagnostic OPTIONAL
+}
+
+F-DESELECT-request ::= SEQUENCE {
+ shared-ASE-information Shared-ASE-Information OPTIONAL
+}
+
+F-DESELECT-response ::= SEQUENCE {
+ action-result Action-Result DEFAULT success,
+ charging Charging OPTIONAL,
+ -- Present if and only if the account field was present on
+ -- the PDU which established the selection regime.
+ shared-ASE-information Shared-ASE-Information OPTIONAL,
+ diagnostic Diagnostic OPTIONAL
+}
+
+F-CREATE-request ::= SEQUENCE {
+ override [0] IMPLICIT Override DEFAULT create-failure,
+ initial-attributes Create-Attributes,
+ create-password Password OPTIONAL,
+ requested-access Access-Request,
+ access-passwords Access-Passwords OPTIONAL,
+ path-access-passwords Path-Access-Passwords OPTIONAL,
+ -- This Parameter tan only be sent when the
+ -- limited-filestore-management or the Object-manipulation or
+ -- the group-manipulation functional units are available.
+ concurrency-control Concurrency-Control OPTIONAL,
+ shared-ASE-information Shared-ASE-Information OPTIONAL,
+ account Account OPTIONAL
+}
+
+F-CREATE-response ::= SEQUENCE {
+ state-result State-Result DEFAULT success,
+ action-result Action-Result DEFAULT success,
+ initial-attributes Create-Attributes,
+ shared-ASE-information Shared-ASE-Information OPTIONAL,
+ diagnostic Diagnostic OPTIONAL
+}
+
+F-DELETE-request ::= SEQUENCE {
+ shared-ASE-information Shared-ASE-Information OPTIONAL
+}
+
+F-DELETE-response ::= SEQUENCE {
+ action-result Action-Result DEFAULT success,
+ shared-ASE-information Shared-ASE-Information OPTIONAL,
+ charging Charging OPTIONAL,
+ diagnostic Diagnostic OPTIONAL
+}
+
+F-READ-ATTRIB-request ::= SEQUENCE {
+ attribute-names [0] IMPLICIT Attribute-Names,
+ attribute-extension-names [1] IMPLICIT Attribute-Extension-Names OPTIONAL
+}
+
+-- This Parameter tan only be sent when the
+-- limited-filestore-management functional unit is available.
+F-READ-ATTRIB-response ::= SEQUENCE {
+ action-result Action-Result DEFAULT success,
+ attributes Read-Attributes OPTIONAL,
+ -- Password values within the access control tan not be read by means
+ -- of the read attribute action. Whether other Parts of the access
+ -- control Object attribute tan be read by means of the read
+ -- attribute action is decided locally by the responding entity, and
+ -- it shall not be the subject of conformance test.
+ diagnostic Diagnostic OPTIONAL
+}
+
+F-CHANGE-ATTRIB-request ::= SEQUENCE {attributes Change-Attributes
+}
+
+F-CHANGE-ATTRIB-response ::= SEQUENCE {
+ action-result Action-Result DEFAULT success,
+ attributes Change-Attributes OPTIONAL,
+ -- Password values within access control attribute are never returned.
+ -- Other attributes are retumed as an implementation choice.
+ diagnostic Diagnostic OPTIONAL
+}
+
+F-OPEN-request ::= SEQUENCE {
+ processing-mode
+ [0] IMPLICIT BIT STRING {f-read(0), f-insert(1), f-replace(2), f-extend(3),
+ f-erase(4)} DEFAULT {f-read},
+ contents-type
+ [1] CHOICE {unknown [0] IMPLICIT NULL,
+ proposed [1] Contents-Type-Attribute},
+ concurrency-control Concurrency-Control OPTIONAL,
+ shared-ASE-information Shared-ASE-Information OPTIONAL,
+ enable-fadu-locking [2] IMPLICIT BOOLEAN DEFAULT FALSE,
+ activity-identifier Activity-Identifier OPTIONAL,
+ -- Only used in the recovery functional unit.
+ recovery-mode
+ [3] IMPLICIT INTEGER {none(0), at-start-of-file(1),
+ at-any-active-Checkpoint(2)} DEFAULT none,
+ remove-contexts [4] IMPLICIT SET OF Abstract-Syntax-Name OPTIONAL,
+ define-contexts [5] IMPLICIT SET OF Abstract-Syntax-Name OPTIONAL,
+ -- The following are conditional on the negotiation of the consecutive overlap or
+ -- concurrent overlap functional units.
+ degree-of-overlap Degree-Of-Overlap OPTIONAL,
+ transfer-window [7] IMPLICIT INTEGER OPTIONAL
+}
+
+F-OPEN-response ::= SEQUENCE {
+ state-result State-Result DEFAULT success,
+ action-result Action-Result DEFAULT success,
+ contents-type [1] Contents-Type-Attribute,
+ concurrency-control Concurrency-Control OPTIONAL,
+ shared-ASE-information Shared-ASE-Information OPTIONAL,
+ diagnostic Diagnostic OPTIONAL,
+ recovery-mode
+ [3] IMPLICIT INTEGER {none(0), at-start-of-file(1),
+ at-any-active-Checkpoint(2)} DEFAULT none,
+ presentation-action [6] IMPLICIT BOOLEAN DEFAULT FALSE,
+ -- This flag is set if the responder is going to follow this response
+ -- by a P-ALTER-CONTEXT exchange.
+ --The following are conditional on the negotiation of the concecutive access
+ -- or concurent access functional units.
+ degree-of-overlap Degree-Of-Overlap OPTIONAL,
+ transfer-window [7] IMPLICIT INTEGER OPTIONAL
+}
+
+F-CLOSE-request ::= SEQUENCE {
+ action-result Action-Result DEFAULT success,
+ shared-ASE-information Shared-ASE-Information OPTIONAL,
+ diagnostic Diagnostic OPTIONAL
+}
+
+F-CLOSE-response ::= SEQUENCE {
+ action-result Action-Result DEFAULT success,
+ shared-ASE-information Shared-ASE-Information OPTIONAL,
+ diagnostic Diagnostic OPTIONAL
+}
+
+F-BEGIN-GROUP-request ::= SEQUENCE {threshold [0] IMPLICIT INTEGER
+}
+
+F-BEGIN-GROUP-response ::= SEQUENCE {
+}
+
+-- No elements defined, shall be empty.
+F-END-GROUP-request ::= SEQUENCE {
+}
+
+-- No elements defined, shall be empty.
+F-END-GROUP-response ::= SEQUENCE {
+}
+
+-- No elements defined, shall be empty.
+F-RECOVER-request ::= SEQUENCE {
+ activity-identifier Activity-Identifier,
+ bulk-transfer-number [0] IMPLICIT INTEGER,
+ -- If concurrent access was in use then this parameter indicates the read bulk
+ -- transfer.
+ requested-access Access-Request,
+ access-passwords Access-Passwords OPTIONAL,
+ recovefy-Point [2] IMPLICIT INTEGER DEFAULT 0,
+ -- Zero indicates beginning of file
+ -- Point after last Checkpoint indicates end of file
+ remove-contexts
+ [3] IMPLICIT SET OF Abstract-Syntax-Name OPTIONAL,
+ define-contexts
+ [4] IMPLICIT SET OF Abstract-Syntax-Name OPTIONAL,
+ -- The following are conditional on the negotiation of overlapped access.
+ concurrent-bulk-transfer-number [7] IMPLICIT INTEGER OPTIONAL,
+ -- conditional on use of concurrent access
+ concurrent-recovery-point [8] IMPLICIT INTEGER OPTIONAL,
+ -- conditional on use of concurrent access. Zero indicates beginning of file
+ -- point after last checkpoint indicates end of file
+ last-transfer-end-read-response [9] IMPLICIT INTEGER OPTIONAL,
+ last-transfer-end-write-response [10] IMPLICIT INTEGER OPTIONAL
+}
+
+F-RECOVER-response ::= SEQUENCE {
+ state-result State-Result DEFAULT success,
+ action-result Action-Result DEFAULT success,
+ contents-type [1] Contents-Type-Attribute,
+ recovety-Point [2] IMPLICIT INTEGER DEFAULT 0,
+ -- Zero indicates beginning of file.
+ -- Point after last Checkpoint indicates end of file.
+ diagnostic Diagnostic OPTIONAL,
+ presentation-action [6] IMPLICIT BOOLEAN DEFAULT FALSE,
+ -- This flag is set if the responder is going to follow this response
+ -- by a P-ALTER-CONTEXT exchange.
+ -- The following are conditional on the negotiation of overlapped access.
+ concurrent-recovery-point [8] IMPLICIT INTEGER OPTIONAL,
+ -- conditional on use of concurrent access. Zero indicates beginning of file; point after
+ -- last checkpoint indicates end of file
+ last-transfer-end-read-request [9] IMPLICIT INTEGER OPTIONAL,
+ last-transfer-end-write-request [10] IMPLICIT INTEGER OPTIONAL
+}
+
+F-LOCATE-request ::= SEQUENCE {
+ file-access-data-unit-identity FADU-Identity,
+ fadu-lock FADU-Lock OPTIONAL
+}
+
+F-LOCATE-response ::= SEQUENCE {
+ action-result Action-Result DEFAULT success,
+ file-access-data-unit-identity FADU-Identity OPTIONAL,
+ diagnostic Diagnostic OPTIONAL
+}
+
+F-ERASE-request ::= SEQUENCE {file-access-data-unit-identity FADU-Identity
+}
+
+F-ERASE-response ::= SEQUENCE {
+ action-result Action-Result DEFAULT success,
+ diagnostic Diagnostic OPTIONAL
+}
+
+Bulk-Data-PDU ::= CHOICE {
+ f-read-request [32] IMPLICIT F-READ-request,
+ f-write-request [33] IMPLICIT F-WRITE-request,
+ -- There is no F-DATA FPDU, the contents of a file
+ -- are transferred in a different presentation context
+ -- and there is therefore no need to define the types
+ -- of file contents in the FTAM PCI abstract Syntax.
+ -- File contents data are carried in values of the
+ -- data type Data-Element as defined in ISO 8571-2.
+ f-data-end-request [34] IMPLICIT F-DATA-END-request,
+ f-transfer-end-request [35] IMPLICIT F-TRANSFER-END-request,
+ f-transfer-end-response [36] IMPLICIT F-TRANSFER-END-response,
+ f-cancel-request [37] IMPLICIT F-CANCEL-request,
+ f-cancel-response [38] IMPLICIT F-CANCEL-response,
+ -- There is no F-CHECK PDU.
+ f-restart-request [39] IMPLICIT F-RESTART-request,
+ f-restart-response [40] IMPLICIT F-RESTART-response
+}
+
+F-READ-request ::= SEQUENCE {
+ file-access-data-unit-identity FADU-Identity,
+ access-context Access-Context,
+ fadu-lock FADU-Lock OPTIONAL,
+ -- The following is conditional on the negotiation of consecutive of concurrent access.
+ transfer-number [0] IMPLICIT INTEGER OPTIONAL
+}
+
+F-WRITE-request ::= SEQUENCE {
+ file-access-data-unit-Operation
+ [0] IMPLICIT INTEGER {insert(0), replace(1), extend(2)},
+ file-access-data-unit-identity FADU-Identity,
+ fadu-lock FADU-Lock OPTIONAL,
+ -- The following is conditional on the negotiation of consecutive or concurrent access.
+ transfer-number [1] IMPLICIT INTEGER OPTIONAL
+}
+
+F-DATA-END-request ::= SEQUENCE {
+ action-result Action-Result DEFAULT success,
+ diagnostic Diagnostic OPTIONAL
+}
+
+F-TRANSFER-END-request ::= SEQUENCE {
+ shared-ASE-information Shared-ASE-Information OPTIONAL,
+ -- The following are conditional on the negotiation of consecutive or concurrent access.
+ request-type Request-Type OPTIONAL,
+ transfer-number [0] IMPLICIT INTEGER OPTIONAL,
+ last-transfer-end-read-response [1] IMPLICIT INTEGER OPTIONAL,
+ last-transfer-end-write-response [2] IMPLICIT INTEGER OPTIONAL
+}
+
+F-TRANSFER-END-response ::= SEQUENCE {
+ action-result Action-Result DEFAULT success,
+ shared-ASE-information Shared-ASE-Information OPTIONAL,
+ diagnostic Diagnostic OPTIONAL,
+ -- The following are conditional on the negotiation of consecutive or concurrent access.
+ request-type Request-Type OPTIONAL,
+ transfer-number [0] IMPLICIT INTEGER OPTIONAL
+}
+
+F-CANCEL-request ::= SEQUENCE {
+ action-result Action-Result DEFAULT success,
+ shared-ASE-information Shared-ASE-Information OPTIONAL,
+ diagnostic Diagnostic OPTIONAL,
+ -- The following are conditional on the negotiation of consecutive or concurrent access.
+ request-type Request-Type,
+ transfer-number [0] IMPLICIT INTEGER OPTIONAL,
+ last-transfer-end-read-request [1] IMPLICIT INTEGER OPTIONAL,
+ last-transfer-end-read-response [2] IMPLICIT INTEGER OPTIONAL,
+ last-transfer-end-write-request [3] IMPLICIT INTEGER OPTIONAL,
+ last-transfer-end-write-response [4] IMPLICIT INTEGER OPTIONAL
+}
+
+F-CANCEL-response ::= SEQUENCE {
+ action-result Action-Result DEFAULT success,
+ shared-ASE-information Shared-ASE-Information OPTIONAL,
+ diagnostic Diagnostic OPTIONAL,
+ -- The following are conditional on the negotiation of consecutive or concurrent access.
+ request-type Request-Type OPTIONAL,
+ transfer-number [0] IMPLICIT INTEGER OPTIONAL,
+ last-transfer-end-read-request [1] IMPLICIT INTEGER OPTIONAL,
+ last-transfer-end-read-response [2] IMPLICIT INTEGER OPTIONAL,
+ last-transfer-end-write-request [3] IMPLICIT INTEGER OPTIONAL,
+ last-transfer-end-write-response [4] IMPLICIT INTEGER OPTIONAL
+}
+
+F-CHECK-request ::= SEQUENCE {
+ checkpoint-identifier [0] IMPLICIT INTEGER,
+ transfer-number [1] IMPLICIT INTEGER
+}
+
+F-CHECK-response ::= SEQUENCE {
+ checkpoint-identifier [0] IMPLICIT INTEGER,
+ transfer-number [1] IMPLICIT INTEGER
+}
+
+F-RESTART-request ::= SEQUENCE {
+ checkpoint-identifier [0] IMPLICIT INTEGER,
+ -- The following are conditional on the negotiation of consecutive or concurrent access.
+ request-type Request-Type OPTIONAL,
+ transfer-number [1] IMPLICIT INTEGER,
+ last-transfer-end-read-request [2] IMPLICIT INTEGER OPTIONAL,
+ last-transfer-end-read-response [3] IMPLICIT INTEGER OPTIONAL,
+ last-transfer-end-write-request [4] IMPLICIT INTEGER OPTIONAL,
+ last-transfer-end-write-response [5] IMPLICIT INTEGER OPTIONAL
+}
+
+F-RESTART-response ::= SEQUENCE {
+ checkpoint-identifier [0] IMPLICIT INTEGER,
+ -- The following are conditional on the negotiation of consecutive or concurrent access.
+ request-type Request-Type OPTIONAL,
+ transfer-number [1] IMPLICIT INTEGER,
+ last-transfer-end-read-request [2] IMPLICIT INTEGER OPTIONAL,
+ last-transfer-end-read-response [3] IMPLICIT INTEGER OPTIONAL,
+ last-transfer-end-write-request [4] IMPLICIT INTEGER OPTIONAL,
+ last-transfer-end-write-response [5] IMPLICIT INTEGER OPTIONAL
+}
+
+Degree-Of-Overlap ::= [APPLICATION 30] IMPLICIT INTEGER {
+ normal(0), consecutive(1), concurrent(2)}
+
+Request-Type ::= [APPLICATION 31] IMPLICIT INTEGER {read(0), write(1)}
+
+Abstract-Syntax-Name ::= [APPLICATION 0] IMPLICIT OBJECT IDENTIFIER
+
+Access-Context ::= [APPLICATION 1] IMPLICIT SEQUENCE {
+ access-context
+ [0] IMPLICIT INTEGER {hierarchical-all-data-units(0),--HA--
+ hierarchical-no-data-units(1),--HN--
+ flat-all-data-units(2),--FA--
+ flat-one-level-data-unit(3),--FL--
+ flat-Single-data-unit(4),--FS--
+ unstructured-all-data-units(5),--UA--
+ unstructured-Single-data-unit(6)}, --US
+ level-number [1] IMPLICIT INTEGER OPTIONAL
+}
+
+-- Present if and only if flat-one-level-data-units
+-- (access context FL) is selected.
+-- As defined in ISO 8571-2.
+Access-Passwords ::= [APPLICATION 2] IMPLICIT SEQUENCE {
+ read-password [0] Password,
+ insert-password [1] Password,
+ replace-password [2] Password,
+ extend-password [3] Password,
+ erase-password [4] Password,
+ read-attribute-password [5] Password,
+ change-attribute-password [6] Password,
+ delete-password [7] Password,
+ pass-passwords [8] IMPLICIT Pass-Passwords OPTIONAL,
+ link-password [9] Password OPTIONAL
+}
+
+-- The pass-passwords and the link-password must be included in the
+-- access-passwords if and only if the limited-filestore-management
+-- or the Object-manipulation or the group-manipulation functional
+-- units are available.
+Access-Request ::= [APPLICATION 3] IMPLICIT BIT STRING {
+ read(0), insert(1), replace(2), extend(3), erase(4), read-attribute(5),
+ change-attribute(6), delete-Object(7)}
+
+Account ::= [APPLICATION 4] IMPLICIT GraphicString
+
+Action-Result ::= [APPLICATION 5] IMPLICIT INTEGER {
+ success(0), transient-error(1), permanent-error(2)}
+
+Activity-Identifier ::= [APPLICATION 6] IMPLICIT INTEGER
+
+Application-Entity-Title ::= [APPLICATION 7] AE-title
+
+-- As defined in ISO 8650.
+Change-Attributes ::= [APPLICATION 8] IMPLICIT SEQUENCE {
+ -- Kerne1 Group
+ pathname Pathname-Attribute OPTIONAL,
+ -- Storage group
+ storage-account [3] Account-Attribute OPTIONAL,
+ object-availability [12] Object-Availability-Attribute OPTIONAL,
+ future-Object-size [14] Object-Size-Attribute OPTIONAL,
+ -- Security group
+ access-control [15] Access-Control-Change-Attribute OPTIONAL,
+ path-access-control [21] Access-Control-Change-Attribute OPTIONAL,
+ -- This Parameter tan only be sent when the
+ -- enhanced-filestore-management functional unit is available.
+ legal-qualification [16] Legal-Qualification-Attribute OPTIONAL,
+ -- Private group
+ private-use [17] Private-Use-Attribute OPTIONAL,
+ -- Attribute Extensions group
+ attribute-extensions [22] IMPLICIT Attribute-Extensions OPTIONAL
+}
+
+-- This Parameter tan only be sent when the
+-- enhanced-filestore-management functional unit is available.
+-- Atleast one attribute shall be present in the Change-Attributes
+-- Parameter on the request PDU.
+Charging ::=
+ [APPLICATION 9] IMPLICIT
+ SEQUENCE OF
+ SEQUENCE {resource-identifier [0] IMPLICIT GraphicString,
+ charging-unit [1] IMPLICIT GraphicString,
+ charging-value [2] IMPLICIT INTEGER}
+
+Concurrency-Control ::= [APPLICATION 10] IMPLICIT SEQUENCE {
+ read [0] IMPLICIT Lock,
+ insert [1] IMPLICIT Lock,
+ replace [2] IMPLICIT Lock,
+ extend [3] IMPLICIT Lock,
+ erase [4] IMPLICIT Lock,
+ read-attribute [5] IMPLICIT Lock,
+ change-attribute [6] IMPLICIT Lock,
+ delete-Object [7] IMPLICIT Lock
+}
+
+Lock ::= INTEGER {not-required(0), shared(1), exclusive(2), no-access(3)}
+
+Constraint-Set-Name ::= [APPLICATION 11] IMPLICIT OBJECT IDENTIFIER
+
+Create-Attributes ::= [APPLICATION 12] IMPLICIT SEQUENCE {
+ -- Kerne1 Group
+ pathname Pathname-Attribute,
+ object-type [18] IMPLICIT Object-Type-Attribute DEFAULT file,
+ -- This Parameter tan be sent if and only if the
+ -- limited-filestore-management functional unit is available.
+ permitted-actions [1] IMPLICIT Permitted-Actions-Attribute,
+ contents-type [2] Contents-Type-Attribute,
+ -- Storage group
+ storage-account [3] Account-Attribute OPTIONAL,
+ object-availability [12] Object-Availability-Attribute OPTIONAL,
+ future-Object-size [14] Object-Size-Attribute OPTIONAL,
+ -- Security group
+ access-control [15] Access-Control-Attribute OPTIONAL,
+ path-access-control [21] Access-Control-Attribute OPTIONAL,
+ -- This Parameter tan be sent if and only if the
+ -- enhanced-filestore-management functional unit is available.
+ legal-qualification [16] Legal-Qualification-Attribute OPTIONAL,
+ -- Private group
+ private-use [17] Private-Use-Attribute OPTIONAL,
+ -- Attribute Extensions group
+ attribute-extensions [22] IMPLICIT Attribute-Extensions OPTIONAL
+}
+
+-- This Parameter tan only be sent when the
+-- limited-filestore-management functional unit is available.
+Diagnostic ::=
+ [APPLICATION 13] IMPLICIT
+ SEQUENCE OF
+ SEQUENCE {diagnostic-type
+ [0] IMPLICIT INTEGER {informative(0), transient(1),
+ permanent(2)},
+ error-identifier [1] IMPLICIT INTEGER,
+ -- As defined in ISO 8571-3.
+ error-observer [2] IMPLICIT Entity-Reference,
+ error-Source [3] IMPLICIT Entity-Reference,
+ suggested-delay [4] IMPLICIT INTEGER OPTIONAL,
+ further-details [5] IMPLICIT GraphicString OPTIONAL
+ }
+
+Entity-Reference ::= INTEGER {
+ no-categorization-possible(0), initiating-file-service-user(1),
+ initiating-file-protocol-machine(2),
+ service-supporting-the-file-protocol-machine(3),
+ responding-file-protocol-machine(4), responding-file-service-user(5)
+}
+
+--NOTE
+-- 1. The values 0 and 3 are only valid as values in error-source.
+-- 2. The value 5 corresponds to the virtual filestore.
+Document-Type-Name ::= [APPLICATION 14] IMPLICIT OBJECT IDENTIFIER
+
+FADU-Identity ::= [APPLICATION 15] CHOICE {
+ first-last [0] IMPLICIT INTEGER {first(0), last(1)},
+ relative [1] IMPLICIT INTEGER {previous(0), current(1), next(2)},
+ begin-end [2] IMPLICIT INTEGER {begin(0), end(1)},
+ single-name [3] IMPLICIT Node-Name,
+ name-list [4] IMPLICIT SEQUENCE OF Node-Name,
+ fadu-number [5] IMPLICIT INTEGER
+}
+
+-- As defined in ISO 8571-2.
+Node-Name ::= EXTERNAL
+
+-- The type to be used for Node-Name is defined in IS08571-FADU.
+FADU-Lock ::= [APPLICATION 16] IMPLICIT INTEGER {off(0), on(1)}
+
+Password ::= [APPLICATION 17] CHOICE {
+ graphicString GraphicString,
+ octetString OCTET STRING
+}
+
+Read-Attributes ::= [APPLICATION 18] IMPLICIT SEQUENCE {
+ -- Kerne1 Group
+ pathname Pathname-Attribute OPTIONAL,
+ object-type
+ [18] IMPLICIT Object-Type-Attribute OPTIONAL,
+ -- This Parameter tan be sent if and only if
+ -- the limited-filestore-management functional unit is available.
+ permitted-actions
+ [1] IMPLICIT Permitted-Actions-Attribute OPTIONAL,
+ contents-type
+ [2] Contents-Type-Attribute OPTIONAL,
+ linked-Object
+ [19] Pathname-Attribute OPTIONAL,
+ -- This Parameter tan be sent if and only if
+ -- the limited-filestore-management functional unit is available.
+ child-objects
+ [23] Child-Objects-Attribute OPTIONAL,
+ -- This Parameter tan be sent if and only if
+ -- the limited-filestore-management functional unit is available.
+ -- Storage group
+ primaty-pathname
+ [20] Pathname-Attribute OPTIONAL,
+ storage-account [3] Account-Attribute OPTIONAL,
+ date-and-time-of-creation
+ [4] Date-and-Time-Attribute OPTIONAL,
+ date-and-time-of-last-modification
+ [5] Date-and-Time-Attribute OPTIONAL,
+ date-and-time-of-last-read-access
+ [6] Date-and-Time-Attribute OPTIONAL,
+ date-and-time-of-last-attribute-modification
+ [7] Date-and-Time-Attribute OPTIONAL,
+ identity-of-creator
+ [8] User-Identity-Attribute OPTIONAL,
+ identity-of-last-modifier
+ [9] User-Identity-Attribute OPTIONAL,
+ identity-of-last-reader
+ [10] User-Identity-Attribute OPTIONAL,
+ identity-last-attribute-modifier
+ [11] User-Identity-Attribute OPTIONAL,
+ object-availability
+ [12] Object-Availability-Attribute OPTIONAL,
+ object-size
+ [13] Object-Size-Attribute OPTIONAL,
+ future-Object-size
+ [14] Object-Size-Attribute OPTIONAL,
+ -- Security group
+ access-control
+ [15] Access-Control-Attribute OPTIONAL,
+ path-access-control
+ [21] Access-Control-Attribute OPTIONAL,
+ -- This Parameter tan be sent if and only if
+ -- the limited-filestore-management functional unit is available.
+ legal-qualification
+ [16] Legal-Qualification-Attribute OPTIONAL,
+ -- Private group
+ private-use
+ [17] Private-Use-Attribute OPTIONAL,
+ -- Attribute Extensions group
+ attribute-extensions
+ [22] IMPLICIT Attribute-Extensions OPTIONAL
+}
+
+-- This Parameter tan be sent if and only if
+-- the limited-filestore-management functional unit is available.
+Select-Attributes ::= [APPLICATION 19] IMPLICIT SEQUENCE {
+ -- Kerne1 Group
+ pathname Pathname-Attribute
+}
+
+Shared-ASE-Information ::= [APPLICATION 20] IMPLICIT EXTERNAL
+
+-- This field may be used to convey commitment control as described
+-- in ISO 8571-3.
+State-Result ::= [APPLICATION 21] IMPLICIT INTEGER {success(0), failure(1)
+}
+
+User-Identity ::= [APPLICATION 22] IMPLICIT GraphicString
+
+Access-Control-Attribute ::= CHOICE {
+ no-value-available [0] IMPLICIT NULL,
+ -- Indicates partial support of this attribute.
+ -- This value shall only appear in response PDUs.
+ actual-values [1] IMPLICIT SET OF Access-Control-Element
+}
+
+-- The semantics of this attribute is described in ISO 8571-2.
+Access-Control-Change-Attribute ::= CHOICE {
+ no-value-available [0] IMPLICIT NULL,
+ -- Indicates partial support of this attribute.
+ -- This value shall only appear in response PDUs.
+ actual-values
+ [1] IMPLICIT SEQUENCE {insert-values
+ [0] IMPLICIT SET OF Access-Control-Element
+ OPTIONAL,
+ -- This field is used by the Change attribute actions to indicate
+ -- new values to be inserted in the access control Object attribute.
+ delete-values
+ [1] IMPLICIT SET OF Access-Control-Element
+ OPTIONAL}
+}
+
+-- This field is used by the Change attribute action to indicate
+-- old values to be removed from the access control Object
+-- attribute.
+-- The semantics of this attribute is described in ISO 8571-2.
+Access-Control-Element ::= SEQUENCE {
+ action-list [0] IMPLICIT Access-Request,
+ concurrency-access [1] IMPLICIT Concurrency-Access OPTIONAL,
+ identity [2] IMPLICIT User-Identity OPTIONAL,
+ passwords [3] IMPLICIT Access-Passwords OPTIONAL,
+ location [4] IMPLICIT Application-Entity-Title OPTIONAL
+}
+
+Concurrency-Access ::= SEQUENCE {
+ read [0] IMPLICIT Concurrency-Key,
+ insert [1] IMPLICIT Concurrency-Key,
+ replace [2] IMPLICIT Concurrency-Key,
+ extend [3] IMPLICIT Concurrency-Key,
+ erase [4] IMPLICIT Concurrency-Key,
+ read-attribute [5] IMPLICIT Concurrency-Key,
+ change-attribute [6] IMPLICIT Concurrency-Key,
+ delete-Object [7] IMPLICIT Concurrency-Key
+}
+
+Concurrency-Key ::= BIT STRING {
+ not-required(0), shared(1), exclusive(2), no-access(3)}
+
+Account-Attribute ::= CHOICE {
+ no-value-available [0] IMPLICIT NULL,
+ -- Indicates partial support of this attribute.
+ -- This value shall only appear in response PDUs.
+ actual-values Account
+}
+
+Contents-Type-Attribute ::= CHOICE {
+ document-type
+ [0] IMPLICIT SEQUENCE {document-type-name Document-Type-Name,
+ parameter
+ [0] TYPE-IDENTIFIER.&Type OPTIONAL},
+ -- The actual types to be used for values of the Parameter field
+ -- are defined in the named document type.
+ constraint-set-and-abstract-Syntax
+ [1] IMPLICIT SEQUENCE {constraint-set-name Constraint-Set-Name,
+ abstract-Syntax-name Abstract-Syntax-Name
+ }
+}
+
+Date-and-Time-Attribute ::= CHOICE {
+ no-value-available [0] IMPLICIT NULL,
+ -- Indicates partial support of this attribute.
+ -- This value shall only appear in response PDUs.
+ actual-values [1] IMPLICIT GeneralizedTime
+}
+
+Object-Availability-Attribute ::= CHOICE {
+ no-value-available [0] IMPLICIT NULL,
+ -- Indicates partial support of this attribute.
+ -- This value shall only appear in response PDUs.
+ actual-values
+ [1] IMPLICIT INTEGER {immediate-availability(0), deferred-availability(1)}
+}
+
+Pathname-Attribute ::= CHOICE {
+ incomplete-pathname [0] IMPLICIT Pathname,
+ complete-pathname [APPLICATION 23] IMPLICIT Pathname
+}
+
+Object-Size-Attribute ::= CHOICE {
+ no-value-available [0] IMPLICIT NULL,
+ -- Indicates partial support of this attribute.
+ -- This value shall only appear in response PDUs.
+ actual-values [1] IMPLICIT INTEGER
+}
+
+Legal-Qualification-Attribute ::= CHOICE {
+ no-value-available [0] IMPLICIT NULL,
+ -- Indicates partial support of this attribute.
+ -- This value shall only appear in response PDUs.
+ actual-values [1] IMPLICIT GraphicString
+}
+
+Permitted-Actions-Attribute ::= BIT STRING -- Actions available
+ {
+ read(0), insert(1), replace(2), extend(3), erase(4), read-attribute(5),
+ change-attribute(6), delete-Object(7), pass(11),
+ link(12),
+ -- FADU-Identity groups available
+ traversal(8), reverse-traversal(9), random-Order(10)}
+
+Private-Use-Attribute ::= CHOICE {
+ no-value-available [0] IMPLICIT NULL,
+ -- Indicates partial support of this attribute.
+ -- This value shall only appear in response PDUs.
+ abstract-Syntax-not-supported [1] IMPLICIT NULL,
+ -- Indicates that abstract Syntax is not available.
+ actual-values [2] IMPLICIT EXTERNAL
+}
+
+Object-Type-Attribute ::= INTEGER {file(0), file-directory(1), reference(2)}
+
+User-Identity-Attribute ::= CHOICE {
+ no-value-available [0] IMPLICIT NULL,
+ -- Indicates partial support of this attribute.
+ -- This value shall only appear in response PDUs.
+ actual-values User-Identity
+}
+
+Child-Objects-Attribute ::= SET OF GraphicString
+
+FSM-PDU ::= CHOICE {
+ f-Change-prefix-request [41] IMPLICIT F-CHANGE-PREFIX-request,
+ f-Change-prefix-response [42] IMPLICIT F-CHANGE-PREFIX-response,
+ f-list-request [43] IMPLICIT F-LIST-request,
+ f-list-response [44] IMPLICIT F-LIST-response,
+ f-group-select-request [45] IMPLICIT F-GROUP-SELECT-request,
+ f-group-select-response [46] IMPLICIT F-GROUP-SELECT-response,
+ f-group-delete-request [47] IMPLICIT F-GROUP-DELETE-request,
+ f-group-delete-response [48] IMPLICIT F-GROUP-DELETE-response,
+ f-group-move-request [49] IMPLICIT F-GROUP-MOVE-request,
+ f-group-move-response [50] IMPLICIT F-GROUP-MOVE-response,
+ f-group-copy-request [51] IMPLICIT F-GROUP-COPY-request,
+ f-group-copy-response [52] IMPLICIT F-GROUP-COPY-response,
+ f-group-list-request [53] IMPLICIT F-GROUP-LIST-request,
+ f-group-list-response [54] IMPLICIT F-GROUP-LIST-response,
+ f-group-Change-attrib-request [55] IMPLICIT F-GROUP-CHANGE-ATTRIB-request,
+ f-group-Change-attrib-response [56] IMPLICIT F-GROUP-CHANGE-ATTRIB-response,
+ f-select-another-request [57] IMPLICIT F-SELECT-ANOTHER-request,
+ f-select-another-response [58] IMPLICIT F-SELECT-ANOTHER-response,
+ f-create-directory-request [59] IMPLICIT F-CREATE-DIRECTORY-request,
+ f-create-directory-response [60] IMPLICIT F-CREATE-DIRECTORY-response,
+ f-link-request [61] IMPLICIT F-LINK-request,
+ f-link-response [62] IMPLICIT F-LINK-response,
+ f-unlink-request [63] IMPLICIT F-UNLINK-request,
+ f-unlink-response [64] IMPLICIT F-UNLINK-response,
+ f-read-link-attrib-request [65] IMPLICIT F-READ-LINK-ATTRIB-request,
+ f-read-link-attrib-response [66] IMPLICIT F-READ-LINK-ATTRIB-response,
+ f-Change-link-attrib-request [67] IMPLICIT F-CHANGE-LINK-ATTRIB-request,
+ f-Change-Iink-attrib-response [68] IMPLICIT F-CHANGE-LINK-ATTRIB-response,
+ f-move-request [69] IMPLICIT F-MOVE-request,
+ f-move-response [70] IMPLICIT F-MOVE-response,
+ f-copy-request [71] IMPLICIT F-COPY-request,
+ f-copy-response [72] IMPLICIT F-COPY-response
+}
+
+F-CHANGE-PREFIX-request ::= SEQUENCE {
+ reset [0] IMPLICIT BOOLEAN DEFAULT FALSE,
+ destination-file-directory Destination-File-Directory,
+ access-passwords Access-Passwords OPTIONAL,
+ path-access-passwords Path-Access-Passwords OPTIONAL
+}
+
+F-CHANGE-PREFIX-response ::= SEQUENCE {
+ action-result Action-Result DEFAULT success,
+ destination-file-directory Destination-File-Directory OPTIONAL,
+ diagnostic Diagnostic OPTIONAL
+}
+
+F-LIST-request ::= SEQUENCE {
+ attribute-value-asset-tions Attribute-Value-Assertions,
+ scope Scope,
+ access-passwords Access-Passwords OPTIONAL,
+ path-access-passwords Path-Access-Passwords OPTIONAL,
+ attribute-names [0] IMPLICIT Attribute-Names,
+ attribute-extension-names [1] IMPLICIT Attribute-Extension-Names OPTIONAL
+}
+
+F-LIST-response ::= SEQUENCE {
+ action-result Action-Result DEFAULT success,
+ objects-attributes-list Objects-Attributes-List OPTIONAL,
+ diagnostic Diagnostic OPTIONAL
+}
+
+F-GROUP-SELECT-request ::= SEQUENCE {
+ attribute-value-assertions Attribute-Value-Assertions,
+ requested-access Access-Request,
+ access-passwords Access-Passwords OPTIONAL,
+ path-access-passwords Path-Access-Passwords OPTIONAL,
+ concurrency-control Concurrency-Control OPTIONAL,
+ maximum-set-size [0] IMPLICIT INTEGER DEFAULT 0,
+ -- 0 implies no limit.
+ scope Scope,
+ account Account OPTIONAL,
+ shared-ASE-information Shared-ASE-Information OPTIONAL
+}
+
+F-GROUP-SELECT-response ::= SEQUENCE {
+ action-result Action-Result DEFAULT success,
+ shared-ASE-information Shared-ASE-Information OPTIONAL,
+ diagnostic Diagnostic OPTIONAL
+}
+
+F-GROUP-DELETE-request ::= SEQUENCE {
+ request-Operation-result Request-Operation-Result OPTIONAL,
+ shared-ASE-information Shared-ASE-Information OPTIONAL
+}
+
+F-GROUP-DELETE-response ::= SEQUENCE {
+ action-result Action-Result DEFAULT success,
+ charging Charging OPTIONAL,
+ operation-result Operation-Result OPTIONAL,
+ shared-ASE-information Shared-ASE-Information OPTIONAL,
+ diagnostic Diagnostic OPTIONAL
+}
+
+F-GROUP-MOVE-request ::= SEQUENCE {
+ destination-file-directory Destination-File-Directory,
+ override [0] IMPLICIT Override DEFAULT create-failure,
+ -- Only the values create-failure (0}
+ -- and delete-and-create-with-new-attributes (3) are allowed.
+ error-action [11] IMPLICIT Error-Action,
+ create-password Password OPTIONAL,
+ access-passwords Access-Passwords OPTIONAL,
+ path-access-passwords Path-Access-Passwords OPTIONAL,
+ request-Operation-result Request-Operation-Result OPTIONAL,
+ attributes Change-Attributes OPTIONAL
+}
+
+F-GROUP-MOVE-response ::= SEQUENCE {
+ action-result Action-Result DEFAULT success,
+ destination-file-directory Destination-File-Directory OPTIONAL,
+ operation-result Operation-Result OPTIONAL,
+ diagnostic Diagnostic OPTIONAL
+}
+
+F-GROUP-COPY-request ::= SEQUENCE {
+ destination-file-directory Destination-File-Directory,
+ override [0] IMPLICIT Override DEFAULT create-failure,
+ -- Only the values create-failure (0)
+ -- and delete-and-create-with-new-attributes (3) are allowed.
+ error-action [1] IMPLICIT Error-Action,
+ create-password Password OPTIONAL,
+ access-passwords Access-Passwords OPTIONAL,
+ path-access-passwords Path-Access-Passwords OPTIONAL,
+ request-Operation-result Request-Operation-Result OPTIONAL,
+ attributes Change-Attributes OPTIONAL
+}
+
+F-GROUP-COPY-response ::= SEQUENCE {
+ action-result Action-Result DEFAULT success,
+ destination-file-directory Destination-File-Directory OPTIONAL,
+ operation-result Operation-Result OPTIONAL,
+ diagnostic Diagnostic OPTIONAL
+}
+
+F-GROUP-LIST-request ::= SEQUENCE {
+ attribute-names [0] IMPLICIT Attribute-Names,
+ attribute-extension-names [2] IMPLICIT Attribute-Extension-Names OPTIONAL
+}
+
+F-GROUP-LIST-response ::= SEQUENCE {
+ action-result Action-Result DEFAULT success,
+ objects-attributes-list Objects-Attributes-List OPTIONAL,
+ diagnostic Diagnostic OPTIONAL
+}
+
+F-GROUP-CHANGE-ATTRIB-request ::= SEQUENCE {
+ attributes Change-Attributes,
+ error-action [1] IMPLICIT Error-Action,
+ request-Operation-result Request-Operation-Result OPTIONAL,
+ shared-ASE-information Shared-ASE-Information OPTIONAL
+}
+
+F-GROUP-CHANGE-ATTRIB-response ::= SEQUENCE {
+ action-result Action-Result DEFAULT success,
+ operation-result Operation-Result OPTIONAL,
+ shared-ASE-information Shared-ASE-Information OPTIONAL,
+ diagnostic Diagnostic OPTIONAL
+}
+
+F-SELECT-ANOTHER-request ::= SEQUENCE {
+ shared-ASE-information Shared-ASE-Information OPTIONAL
+}
+
+F-SELECT-ANOTHER-response ::= SEQUENCE {
+ state-result State-Result DEFAULT success,
+ action-result Action-Result DEFAULT success,
+ last-member-indicator [0] IMPLICIT BOOLEAN DEFAULT FALSE,
+ referent-indicator Referent-Indicator OPTIONAL,
+ shared-ASE-information Shared-ASE-Information OPTIONAL,
+ diagnostic Diagnostic OPTIONAL
+}
+
+F-CREATE-DIRECTORY-request ::= SEQUENCE {
+ initial-attributes Create-Attributes,
+ create-password Password OPTIONAL,
+ requested-access Access-Request,
+ shared-ASE-infonnation Shared-ASE-Information OPTIONAL,
+ account Account OPTIONAL
+}
+
+F-CREATE-DIRECTORY-response ::= SEQUENCE {
+ state-result State-Result DEFAULT success,
+ action-result Action-Result DEFAULT success,
+ initial-attributes Create-Attributes,
+ shared-ASE-information Shared-ASE-Information OPTIONAL,
+ diagnostic Diagnostic OPTIONAL
+}
+
+F-LINK-request ::= SEQUENCE {
+ initial-attributes Create-Attributes,
+ target-object Pathname-Attribute,
+ create-password Password OPTIONAL,
+ requested-access Access-Request,
+ access-passwords Access-Passwords OPTIONAL,
+ path-access-passwords Path-Access-Passwords OPTIONAL,
+ concurrency-control Concurrency-Control OPTIONAL,
+ shared-ASE-information Shared-ASE-Information OPTIONAL,
+ account Account OPTIONAL
+}
+
+F-LINK-response ::= SEQUENCE {
+ state-result State-Result DEFAULT success,
+ action-result Action-Result DEFAULT success,
+ initial-attributes Create-Attributes,
+ target-Object Pathname-Attribute,
+ shared-ASE-information Shared-ASE-Information OPTIONAL,
+ diagnostic Diagnostic OPTIONAL
+}
+
+F-UNLINK-request ::= SEQUENCE {
+ shared-ASE-information Shared-ASE-Information OPTIONAL
+}
+
+F-UNLINK-response ::= SEQUENCE {
+ action-result Action-Result DEFAULT success,
+ shared-ASE-information Shared-ASE-Information OPTIONAL,
+ charging Charging OPTIONAL,
+ diagnostic Diagnostic OPTIONAL
+}
+
+F-READ-LINK-ATTRIB-request ::= SEQUENCE {
+ attribute-names [0] IMPLICIT Attribute-Names,
+ attribute-extension-names [1] IMPLICIT Attribute-Extension-Names OPTIONAL
+}
+
+F-READ-LINK-ATTRIB-response ::= SEQUENCE {
+ action-result Action-Result DEFAULT success,
+ attributes Read-Attributes OPTIONAL,
+ diagnostic Diagnostic OPTIONAL
+}
+
+F-CHANGE-LINK-ATTRIB-request ::= SEQUENCE {attributes Change-Attributes
+}
+
+F-CHANGE-LINK-ATTRIB-response ::= SEQUENCE {
+ action-result Action-Result DEFAULT success,
+ attributes Change-Attributes OPTIONAL,
+ diagnostic Diagnostic OPTIONAL
+}
+
+F-MOVE-request ::= SEQUENCE {
+ destination-file-directory Destination-File-Directory,
+ override [0] IMPLICIT Override DEFAULT create-failure,
+ -- Only the values create-failure (0)
+ -- and delete-and-create-with-new-attributes (3) are ailowed.
+ create-password Password OPTIONAL,
+ access-passwords Access-Passwords OPTIONAL,
+ path-access-passwords Path-Access-Passwords OPTIONAL,
+ attributes Change-Attributes OPTIONAL
+}
+
+F-MOVE-response ::= SEQUENCE {
+ action-result Action-Result DEFAULT success,
+ destination-file-directory Destination-File-Directory OPTIONAL,
+ attributes Change-Attributes OPTIONAL,
+ diagnostic Diagnostic OPTIONAL
+}
+
+F-COPY-request ::= SEQUENCE {
+ destination-file-directory Destination-File-Directory,
+ override [0] IMPLICIT Override DEFAULT create-failure,
+ -- Only the values create-failure (0)
+ -- and delete-and-create-with-new-attributes (3) are allowed.
+ create-password Password OPTIONAL,
+ access-passwords Access-Passwords OPTIONAL,
+ path-access-passwords Path-Access-Passwords OPTIONAL,
+ attributes Change-Attributes OPTIONAL
+}
+
+F-COPY-response ::= SEQUENCE {
+ action-result Action-Result DEFAULT success,
+ destination-file-directory Destination-File-Directory OPTIONAL,
+ attributes Change-Attributes OPTIONAL,
+ diagnostic Diagnostic OPTIONAL
+}
+
+Attribute-Extension-Names ::= SEQUENCE OF Attribute-Extension-Set-Name
+
+Attribute-Extension-Set-Name ::= SEQUENCE {
+ extension-set-identifier [0] IMPLICIT Extension-Set-Identifier,
+ extension-attribute-names [1] SEQUENCE OF Extension-Attribute-identifier
+}
+
+Attribute-Extensions ::= SEQUENCE OF Attribute-Extension-Set
+
+Attribute-Extension-Set ::= SEQUENCE {
+ extension-set-identifier [0] IMPLICIT Extension-Set-Identifier,
+ extension-set-attributes [1] SEQUENCE OF Extension-Attribute
+}
+
+Extension-Attribute ::= SEQUENCE {
+ extension-attribute-identifier
+ TYPE-IDENTIFIER.&id({Extension-Attributes}),
+ extension-attribute
+ TYPE-IDENTIFIER.&Type
+ ({Extension-Attributes}{@extension-attribute-identifier})
+}
+
+Extension-Attributes TYPE-IDENTIFIER ::=
+ {...} -- dynamically extensible
+
+Extension-Set-Identifier ::= OBJECT IDENTIFIER
+
+Extension-Attribute-identifier ::= OBJECT IDENTIFIER
+
+Attribute-Value-Assertions ::= [APPLICATION 26] IMPLICIT OR-Set
+
+Scope ::=
+ [APPLICATION 28] IMPLICIT
+ SEQUENCE OF
+ SEQUENCE {root-directory [0] Pathname-Attribute OPTIONAL,
+ retrieval-scope [1] IMPLICIT INTEGER {child(0), all(1)}
+ }
+
+OR-Set ::= SEQUENCE OF AND-Set
+
+AND-Set ::=
+ SEQUENCE OF
+ CHOICE {-- Kernel group
+ pathname-Pattern
+ [0] IMPLICIT Pathname-Pattern,
+ object-type-Pattern
+ [18] IMPLICIT Integer-Pattern,
+ permitted-actions-Pattern
+ [1] IMPLICIT Bitstring-Pattern,
+ contents-type-Pattern
+ [2] Contents-Type-Pattern,
+ linked-Object-Pattern
+ [19] IMPLICIT Pathname-Pattern,
+ child-objects-Pattern
+ [23] IMPLICIT Pathname-Pattern,
+ -- Storage group
+ primaty-pathname-Pattern
+ [20] IMPLICIT Pathname-Pattern,
+ storage-account-Pattern
+ [3] IMPLICIT String-Pattern,
+ date-and-time-of-creation-Pattern
+ [4] IMPLICIT Date-and-Time-Pattern,
+ date-and-time-of-last-modification-Pattern
+ [5] IMPLICIT Date-and-Time-Pattern,
+ date-and-time-of-last-read-access-Pattern
+ [6] IMPLICIT Date-and-Time-Pattern,
+ date-and-time-of-last-attribute-modification-Pattern
+ [7] IMPLICIT Date-and-Time-Pattern,
+ identity-of-creator-Pattern
+ [8] IMPLICIT User-Identity-Pattern,
+ identity-of-last-modifier-Pattern
+ [9] IMPLICIT User-Identity-Pattern,
+ identity-of-last-reader-Pattern
+ [10] IMPLICIT User-Identity-Pattern,
+ identity-of-last-attribute-modifier-Pattern
+ [11] IMPLICIT User-Identity-Pattern,
+ object-availabiiity-Pattern
+ [12] IMPLICIT Boolean-Pattern,
+ object-size-Pattern
+ [13] IMPLICIT Integer-Pattern,
+ future-object-size-Pattern
+ [14] IMPLICIT Integer-Pattern,
+ -- Security group
+ -- Access control searches are disallowed.
+ legal-quailfication-Pattern
+ [16] IMPLICIT String-Pattern,
+ -- Private group
+ -- Private use searches are disallowed.
+ -- Attribute Extensions group
+ attribute-extensions-pattern
+ [22] IMPLICIT Attribute-Extensions-Pattern}
+
+User-Identity-Pattern ::= String-Pattern
+
+Equality-Comparision ::= BIT STRING {
+ no-value-available-matches(0),
+ -- Set impies ?No Value Available? matches the test.
+ -- Clear implies ?No Value Availabie? fails the test.
+ equals-matches(1)
+
+-- Set implies equal items match the test.
+-- Clear implies equal items fail the test.
+}
+
+Relational-Comparision ::= BIT STRING {
+ no-value-available-matches(0),
+ -- Set impies ?No Value Available? matches the test.
+ -- Clear implies ?No Value Available? fails the test.
+ equals-matches(1),
+ -- Set implies equal items match the test.?
+ -- Clear implies equal items fail the test.
+ less-than-matches(2),
+ -- Set implies a value less than the test cke matches.
+ -- Clear implies a value less than the test case fails.
+ greater-than-matches(3)
+
+-- Set implies a value greater than the test case matches.
+-- Clear implies a value greater than the test case fails.
+}
+
+-- Bits 1 through 3 shall not all have the Same value.
+Pathname-Pattern ::= SEQUENCE {
+ equality-comparision [0] IMPLICIT Equality-Comparision,
+ pathname-value
+ [1] IMPLICIT SEQUENCE OF
+ CHOICE {string-match [2] IMPLICIT String-Pattern,
+ any-match [3] IMPLICIT NULL}
+}
+
+String-Pattern ::= SEQUENCE {
+ equality-comparision [0] IMPLICIT Equality-Comparision,
+ string-value
+ [1] IMPLICIT SEQUENCE OF
+ CHOICE {substring-match
+ [2] IMPLICIT GraphicString,
+ any-match [3] IMPLICIT NULL,
+ number-of-characters-match [4] IMPLICIT INTEGER
+ }
+}
+
+Bitstring-Pattern ::= SEQUENCE {
+ equality-comparision [0] IMPLICIT Equality-Comparision,
+ match-bitstring [1] IMPLICIT BIT STRING,
+ significance-bitstring [2] IMPLICIT BIT STRING
+}
+
+Date-and-Time-Pattern ::= SEQUENCE {
+ relational-camparision [0] IMPLICIT Equality-Comparision,
+ time-and-date-value [1] IMPLICIT GeneralizedTime
+}
+
+Integer-Pattern ::= SEQUENCE {
+ relational-comparision [0] IMPLICIT Relational-Comparision,
+ integer-value [1] IMPLICIT INTEGER
+}
+
+Object-Identifier-Pattern ::= SEQUENCE {
+ equality-comparision [0] IMPLICIT Equality-Comparision,
+ object-identifier-value [1] IMPLICIT OBJECT IDENTIFIER
+}
+
+Boolean-Pattern ::= SEQUENCE {
+ equality-comparision [0] IMPLICIT Equality-Comparision,
+ boolean-value [1] IMPLICIT BOOLEAN
+}
+
+Other-Pattern ::= Equality-Comparision
+
+-- Matches against ?No Value Available?.
+Contents-Type-Pattern ::= CHOICE {
+ document-type-Pattern
+ [0] IMPLICIT Object-Identifier-Pattern,
+ constraint-set-abstract-Syntax-Pattern
+ [1] IMPLICIT SEQUENCE {constraint-Set-Pattern
+ [2] IMPLICIT Object-Identifier-Pattern OPTIONAL,
+ -- Absent implies any Object Identifier is equal.
+ abstract-Syntax-Pattern
+ [3] IMPLICIT Object-Identifier-Pattern OPTIONAL
+ -- Absent implies any Object identifier is equal.
+ }
+}
+
+Attribute-Extensions-Pattern ::=
+ SEQUENCE OF
+ SEQUENCE {extension-set-identifier
+ [0] IMPLICIT Extension-Set-Identifier,
+ extension-set-attribute-Patterns
+ [1] IMPLICIT SEQUENCE OF
+ SEQUENCE {extension-attribute-identifier
+ TYPE-IDENTIFIER.&id
+ ({Extension-attribute-Patterns}),
+ extension-attribute-Pattern
+ TYPE-IDENTIFIER.&Type
+ ({Extension-attribute-Patterns}
+ {@.extension-attribute-identifier})
+ }}
+
+-- conjunction with the extention attribute in Order to
+-- perform Pattern matthing operations on it. it may be
+-- defined in terms of other Patterns within this
+-- Standard.
+Extension-attribute-Patterns TYPE-IDENTIFIER ::=
+ {...} -- dynamically extensible information object set
+
+Destination-File-Directory ::= [APPLICATION 24] Pathname-Attribute
+
+Objects-Attributes-List ::=
+ [APPLICATION 25] IMPLICIT SEQUENCE OF Read-Attributes
+
+Override ::= INTEGER {
+ create-failure(0), select-old-Object(1),
+ delete-and-create-with-old-attributes(2),
+ delete-and-create-with-new-attributes(3)}
+
+Error-Action ::= INTEGER {terminate(0), continue(1)}
+
+Operation-Result ::= [APPLICATION 30] CHOICE {
+ success-Object-count [0] IMPLICIT INTEGER,
+ success-Object-names [1] IMPLICIT SEQUENCE OF Pathname
+}
+
+Pathname ::= SEQUENCE OF GraphicString
+
+Pass-Passwords ::= SEQUENCE OF Password
+
+-- There is a one-to-one correspondence between the elements of
+-- Pass-Passwords and the non-terminal elements of the specified
+-- Pathname.
+Path-Access-Passwords ::=
+ [APPLICATION 27] IMPLICIT
+ SEQUENCE OF
+ SEQUENCE {read-password [0] Password,
+ insert-password [1] Password,
+ replace-password [2] Password,
+ extend-password [3] Password,
+ erase-password [4] Password,
+ read-attribute-password [5] Password,
+ change-attribute-password [6] Password,
+ delete-password [7] Password,
+ pass-passwords [8] IMPLICIT Pass-Passwords,
+ link-password [9] Password}
+
+-- There is a one-to-one correspondence between the elements of
+-- Path-Access-Passwords and the non-terminal elements sf the
+-- specified Pathname.
+Request-Operation-Result ::= [APPLICATION 31] IMPLICIT INTEGER {
+ summary(0), fiii-list(1)}
+
+Attribute-Names ::= BIT STRING -- Kernel group
+ {
+ read-pathname(0), read-Object-type(18), read-permitted-actions(1),
+ read-contents-type(2), read-linked-Object(19),
+ read-Child-objects(23),
+ -- Storage group
+ read-primary-pathname(20), read-storage-account(3),
+ read-date-and-time-of-creation(4),
+ read-date-and-time-of-last-modification(5),
+ read-date-and-time-of-last-read-access(6),
+ read-date-and-time-of-last-attribute-modification(7),
+ read-identity-of-creator(8), read-identity-of-last-modifier(9),
+ read-identity-of-last-reader(10),
+ read-identity-of-last-attribute-modifier(11), read-Object-availability(12),
+ read-Object-size(13),
+ read-future-Object-size(14),
+ -- Security group
+ read-access-control(15), read-path-access-control(21),
+ read-l8gal-qualifiCatiOnS(16),
+ -- Private group
+ read-private-use(17)}
+
+-- Bits 19 through 23 arc defined if and only if the limited-fil8Store-manag8m8nt
+-- or group-manipulation functionat units are available.
+Referent-Indicator ::= [APPLICATION 29] IMPLICIT BOOLEAN
+
+-- dw: definition of AE-title, as defined in ISO 8650:1988/Cor.1:1990
+-- dw: defined in-line here so we don't need to import it, original comments
+-- dw: are as they appear in the 8650:1988 Annex E
+AP-title ::= TYPE-IDENTIFIER.&Type
+
+-- The exact definition and values used for AP-title
+-- should be chosen taking into account the ongoing
+-- work in areas of naming, the Directory, and the
+-- Registration Authority procedures for AE titles,
+-- AE titles, and AE qualifiers
+AE-qualifier ::= TYPE-IDENTIFIER.&Type
+
+-- The exact definition and values used for AE-qualifier
+-- should be chosen taking into account the ongoing
+-- work in areas of naming, the Directory, and the
+-- Registration Authority procedures for AE titles,
+-- AE titles, and AE qualifiers
+AE-title ::= SEQUENCE {ap AP-title,
+ ae AE-qualifier
+}
+
+END
+
+-- Generated by Asnp, the ASN.1 pretty-printer of France Telecom R&D
diff --git a/lib/asn1/test/asn1_SUITE_data/x420/ISO9541-SN.asn b/lib/asn1/test/asn1_SUITE_data/x420/ISO9541-SN.asn
new file mode 100644
index 0000000000..0149602040
--- /dev/null
+++ b/lib/asn1/test/asn1_SUITE_data/x420/ISO9541-SN.asn
@@ -0,0 +1,51 @@
+-- Module ISO9541-SN (ISO:1991)
+--
+-- Copyright � ISO/IEC 1991. This version of
+-- this ASN.1 module is part of ISO|IEC 9541-2:1991;
+-- see the ISO|IEC text itself for full legal notices.
+--
+ISO9541-SN {1 0 9541 2 3} DEFINITIONS ::=
+BEGIN
+
+EXPORTS Structured-Name, Owner-Name, Object-Name-Component;
+
+Structured-Name ::= SEQUENCE {
+ owner-name [0] IMPLICIT Owner-Name OPTIONAL,
+ -- length restricted to 120 characters
+ owner-description [1] Message OPTIONAL,
+ object-name [2] SEQUENCE OF Object-Name-Component OPTIONAL,
+ -- length restricted to 100 characters
+ object-description [3] Message OPTIONAL
+}
+
+Owner-Name ::= SEQUENCE {
+ objectIdentifier [0] IMPLICIT OBJECT IDENTIFIER OPTIONAL,
+ ownerNameComponent [1] SEQUENCE OF Owner-Name-Component OPTIONAL
+}
+
+Owner-Name-Component ::= [0] VisibleString
+
+-- except for "//" and "::"
+Object-Name-Component ::= [0] VisibleString
+
+-- only characters from the following
+-- repertoire: "A-Z", "a-z", "0-9",
+-- Hyphen, and Period. If the name
+-- component is a numeric value,
+-- the first digit is in the range
+-- of 1 to 9
+Message ::= CHOICE {
+ numeric [0] NumericString,
+ printable [1] PrintableString,
+ teletex [2] TeletexString,
+ videotex [3] VideotexString,
+ visible [4] VisibleString,
+ ia5 [5] IA5String,
+ graphic [6] GraphicString,
+ general [7] GeneralString
+}
+
+END
+
+-- Generated by Asnp, the ASN.1 pretty-printer of France Telecom R&D
+
diff --git a/lib/asn1/test/asn1_SUITE_data/x420/Identifiers-and-Expressions.asn b/lib/asn1/test/asn1_SUITE_data/x420/Identifiers-and-Expressions.asn
new file mode 100644
index 0000000000..bd1d8d3c48
--- /dev/null
+++ b/lib/asn1/test/asn1_SUITE_data/x420/Identifiers-and-Expressions.asn
@@ -0,0 +1,126 @@
+-- Module Identifiers-and-Expressions (T.415:03/1993)
+
+Identifiers-and-Expressions {2 8 1 5 7} DEFINITIONS ::=
+BEGIN
+
+EXPORTS
+ Content-Portion-Identifier, Object-or-Class-Identifier, Style-Identifier,
+ Protected-Part-Identifier, Category-Name, Resource-Name, Binding-Name,
+ Construction-Expression, Object-Id-Expression, Numeric-Expression,
+ String-Expression;
+
+IMPORTS
+ Layout-Object-Type
+ FROM Layout-Descriptors -- see 7.9
+
+ Logical-Object-Type
+ FROM Logical-Descriptors; -- see 7.10
+
+Content-Portion-Identifier ::= [APPLICATION 0] IMPLICIT PrintableString
+
+-- only digits and space are used in the present version
+-- of this Specification; other characters are reserved for extensions
+Object-or-Class-Identifier ::= [APPLICATION 1] IMPLICIT PrintableString
+
+-- only digits and space are used in the present version
+-- of this Specification; other characters are reserved for extensions;
+-- a 'null' value is represented by an empty string
+Style-Identifier ::= [APPLICATION 5] IMPLICIT PrintableString
+
+-- only digits and space are used in the present version
+-- of this Specification; other characters are reserved for extensions;
+-- a 'null' value is represented by an empty string
+Protected-Part-Identifier ::= [APPLICATION 7] IMPLICIT PrintableString
+
+-- only digits and space are used in the present version
+-- of this Specification; other characters are reserved for extensions;
+-- a 'null' value is represented by an empty string
+Category-Name ::= PrintableString
+
+-- a 'null' value is represented by an empty string
+Resource-Name ::= PrintableString
+
+Binding-Name ::= PrintableString
+
+Construction-Expression ::= CHOICE {
+ construction-type Construction-Type,
+ single-term-construction [3] Construction-Term
+}
+
+Construction-Type ::= CHOICE {
+ sequence-construction [0] IMPLICIT Term-Sequence,
+ aggregate-construction [1] IMPLICIT Term-Sequence,
+ choice-construction [2] IMPLICIT Term-Sequence
+}
+
+Term-Sequence ::= SEQUENCE OF Construction-Term
+
+Construction-Term ::= CHOICE {
+ required-construction-factor [0] Construction-Factor,
+ optional-construction-factor [1] Construction-Factor,
+ repetitive-construction-factor [2] Construction-Factor,
+ optional-repetitive-factor [3] Construction-Factor
+}
+
+Construction-Factor ::= CHOICE {
+ object-class-identifier Object-or-Class-Identifier,
+ construction-type Construction-Type
+}
+
+Object-Id-Expression ::= CHOICE {
+ current-object-function [0] IMPLICIT NULL,
+ preceding-object-function [1] Object-Id-Expression,
+ superior-object-function [3] Object-Id-Expression,
+ current-instance-function [4] Current-Instance-Function
+}
+
+Numeric-Expression ::= CHOICE {
+ numeric-literal [0] IMPLICIT INTEGER,
+ increment-application [1] Numeric-Expression,
+ decrement-application [2] Numeric-Expression,
+ ordinal-application
+ [3] CHOICE {identifier Object-or-Class-Identifier,
+ expression Object-Id-Expression},
+ binding-reference [4] IMPLICIT Binding-Reference
+}
+
+Binding-Reference ::= SET {
+ object-reference
+ CHOICE {identifier Object-or-Class-Identifier,
+ expression Binding-Selection-Function},
+ binding-identifier Binding-Name
+}
+
+Binding-Selection-Function ::= CHOICE {
+ current-object-function [0] IMPLICIT NULL,
+ preceding-function [1] Object-Id-Expression,
+ superior-function [3] Object-Id-Expression,
+ current-instance-function [4] Current-Instance-Function
+}
+
+Current-Instance-Function ::= SEQUENCE {
+ first-parameter
+ CHOICE {identifier [0] IMPLICIT Object-or-Class-Identifier,
+ layout-object-type [1] IMPLICIT Layout-Object-Type,
+ logical-object-type [2] IMPLICIT Logical-Object-Type},
+ second-parameter
+ CHOICE {identifier Object-or-Class-Identifier,
+ expression Object-Id-Expression}
+}
+
+String-Expression ::= SEQUENCE OF Atomic-String-Expression
+
+Atomic-String-Expression ::= CHOICE {
+ string-literal [0] IMPLICIT OCTET STRING,
+ binding-reference [2] IMPLICIT Binding-Reference,
+ make-string-application [3] Numeric-Expression,
+ upper-alpha-application [4] Numeric-Expression,
+ lower-alpha-application [5] Numeric-Expression,
+ upper-roman-application [6] Numeric-Expression,
+ lower-roman-application [7] Numeric-Expression
+}
+
+END
+
+-- Generated by Asnp, the ASN.1 pretty-printer of France Telecom R&D
+
diff --git a/lib/asn1/test/asn1_SUITE_data/x420/InformationFramework.asn b/lib/asn1/test/asn1_SUITE_data/x420/InformationFramework.asn
new file mode 100644
index 0000000000..813ac9c6a0
--- /dev/null
+++ b/lib/asn1/test/asn1_SUITE_data/x420/InformationFramework.asn
@@ -0,0 +1,868 @@
+-- Module InformationFramework (X.501:08/1997)
+InformationFramework {joint-iso-itu-t ds(5) module(1) informationFramework(1)
+ 3} DEFINITIONS ::=
+BEGIN
+
+-- EXPORTS All -
+-- The types and values defined in this module are exported for use in the other ASN.1 modules contained
+-- within the Directory Specifications, and for the use of other applications which will use them to access
+-- Directory services. Other applications may use them for their own purposes, but this will not constrain
+-- extensions and modifications needed to maintain or improve the Directory service.
+IMPORTS
+ id-oc, id-at, id-mr, id-oa, id-sc, id-ar, id-nf, selectedAttributeTypes,
+ directoryAbstractService, upperBounds
+ FROM UsefulDefinitions {joint-iso-itu-t ds(5) module(1)
+ usefulDefinitions(0) 3}
+ commonName, generalizedTimeMatch, generalizedTimeOrderingMatch, booleanMatch,
+ integerMatch, integerOrderingMatch, objectIdentifierFirstComponentMatch,
+ integerFirstComponentMatch, DirectoryString{}
+ FROM SelectedAttributeTypes selectedAttributeTypes
+ TypeAndContextAssertion, ServiceControlOptions, SearchControlOptions,
+ HierarchySelections, FamilyGrouping, FamilyReturn
+ FROM DirectoryAbstractService directoryAbstractService
+ ub-search
+ FROM UpperBounds upperBounds;
+
+-- attribute data types
+Attribute ::= SEQUENCE {
+ type ATTRIBUTE.&id({SupportedAttributes}),
+ values
+ SET SIZE (0..MAX) OF ATTRIBUTE.&Type({SupportedAttributes}{@type}),
+ valuesWithContext
+ SET SIZE (1..MAX) OF
+ SEQUENCE {value ATTRIBUTE.&Type({SupportedAttributes}{@type}),
+ contextList SET SIZE (1..MAX) OF Context} OPTIONAL
+}
+
+AttributeType ::= ATTRIBUTE.&id
+
+AttributeValue ::= ATTRIBUTE.&Type
+
+Context ::= SEQUENCE {
+ contextType CONTEXT.&id({SupportedContexts}),
+ contextValues
+ SET SIZE (1..MAX) OF CONTEXT.&Type({SupportedContexts}{@contextType}),
+ fallback BOOLEAN DEFAULT FALSE
+}
+
+AttributeValueAssertion ::= SEQUENCE {
+ type ATTRIBUTE.&id({SupportedAttributes}),
+ assertion
+ ATTRIBUTE.&equality-match.&AssertionType({SupportedAttributes}{@type}),
+ assertedContexts
+ CHOICE {allContexts [0] NULL,
+ selectedContexts [1] SET SIZE (1..MAX) OF ContextAssertion
+ } OPTIONAL
+}
+
+ContextAssertion ::= SEQUENCE {
+ contextType CONTEXT.&id({SupportedContexts}),
+ contextValues
+ SET SIZE (1..MAX) OF CONTEXT.&Assertion({SupportedContexts}{@contextType})
+}
+
+AttributeTypeAssertion ::= SEQUENCE {
+ type ATTRIBUTE.&id({SupportedAttributes}),
+ assertedContexts SEQUENCE SIZE (1..MAX) OF ContextAssertion OPTIONAL
+}
+
+-- Definition of the following information object set is deferred, perhaps to standardized
+-- profiles or to protocol implementation conformance statements. The set is required to
+-- specify a table constraint on the values component of Attribute, the value component
+-- of AttributeTypeAndValue, and the assertion component of AttributeValueAssertion.
+SupportedAttributes ATTRIBUTE ::=
+ {objectClass | aliasedEntryName, ...}
+
+-- Definition of the following information object set is deferred, perhaps to standardized
+-- profiles or to protocol implementation conformance statements. The set is required to
+-- specify a table constraint on the context specifications
+SupportedContexts CONTEXT ::=
+ {...}
+
+-- naming data types
+Name ::= CHOICE { -- only one possibility for now --rdnSequence RDNSequence
+}
+
+RDNSequence ::= SEQUENCE OF RelativeDistinguishedName
+
+DistinguishedName ::= RDNSequence
+
+RelativeDistinguishedName ::=
+ SET SIZE (1..MAX) OF AttributeTypeAndDistinguishedValue
+
+AttributeTypeAndDistinguishedValue ::= SEQUENCE {
+ type ATTRIBUTE.&id({SupportedAttributes}),
+ value ATTRIBUTE.&Type({SupportedAttributes}{@type}),
+ primaryDistinguished BOOLEAN DEFAULT TRUE,
+ valuesWithContext
+ SET SIZE (1..MAX) OF
+ SEQUENCE {distingAttrValue
+ [0] ATTRIBUTE.&Type({SupportedAttributes}{@type}) OPTIONAL,
+ contextList SET SIZE (1..MAX) OF Context} OPTIONAL
+}
+
+-- subtree data types
+SubtreeSpecification ::= SEQUENCE {
+ base [0] LocalName DEFAULT {},
+ COMPONENTS OF ChopSpecification,
+ specificationFilter [4] Refinement OPTIONAL
+}
+
+-- empty sequence specifies whole administrative area
+LocalName ::= RDNSequence
+
+ChopSpecification ::= SEQUENCE {
+ specificExclusions
+ [1] SET SIZE (1..MAX) OF
+ CHOICE {chopBefore [0] LocalName,
+ chopAfter [1] LocalName} OPTIONAL,
+ minimum [2] BaseDistance DEFAULT 0,
+ maximum [3] BaseDistance OPTIONAL
+}
+
+BaseDistance ::= INTEGER(0..MAX)
+
+Refinement ::= CHOICE {
+ item [0] OBJECT-CLASS.&id,
+ and [1] SET OF Refinement,
+ or [2] SET OF Refinement,
+ not [3] Refinement
+}
+
+-- OBJECT-CLASS information object class specification
+OBJECT-CLASS ::= CLASS {
+ &Superclasses OBJECT-CLASS OPTIONAL,
+ &kind ObjectClassKind DEFAULT structural,
+ &MandatoryAttributes ATTRIBUTE OPTIONAL,
+ &OptionalAttributes ATTRIBUTE OPTIONAL,
+ &id OBJECT IDENTIFIER UNIQUE
+}
+WITH SYNTAX {
+ [SUBCLASS OF &Superclasses]
+ [KIND &kind]
+ [MUST CONTAIN &MandatoryAttributes]
+ [MAY CONTAIN &OptionalAttributes]
+ ID &id
+}
+
+ObjectClassKind ::= ENUMERATED {abstract(0), structural(1), auxiliary(2)}
+
+-- object classes
+top OBJECT-CLASS ::= {
+ KIND abstract
+ MUST CONTAIN {objectClass}
+ ID id-oc-top
+}
+
+alias OBJECT-CLASS ::= {
+ SUBCLASS OF {top}
+ MUST CONTAIN {aliasedEntryName}
+ ID id-oc-alias
+}
+
+parent OBJECT-CLASS ::= {KIND abstract
+ ID id-oc-parent
+}
+
+child OBJECT-CLASS ::= {KIND auxiliary
+ ID id-oc-child
+}
+
+-- ATTRIBUTE information object class specification
+ATTRIBUTE ::= CLASS {
+ &derivation ATTRIBUTE OPTIONAL,
+ &Type OPTIONAL, -- either &Type or &derivation required
+ &equality-match MATCHING-RULE OPTIONAL,
+ &ordering-match MATCHING-RULE OPTIONAL,
+ &substrings-match MATCHING-RULE OPTIONAL,
+ &single-valued BOOLEAN DEFAULT FALSE,
+ &collective BOOLEAN DEFAULT FALSE,
+ -- operational extensions
+ &no-user-modification BOOLEAN DEFAULT FALSE,
+ &usage AttributeUsage DEFAULT userApplications,
+ &id OBJECT IDENTIFIER UNIQUE
+}
+WITH SYNTAX {
+ [SUBTYPE OF &derivation]
+ [WITH SYNTAX &Type]
+ [EQUALITY MATCHING RULE &equality-match]
+ [ORDERING MATCHING RULE &ordering-match]
+ [SUBSTRINGS MATCHING RULE &substrings-match]
+ [SINGLE VALUE &single-valued]
+ [COLLECTIVE &collective]
+ [NO USER MODIFICATION &no-user-modification]
+ [USAGE &usage]
+ ID &id
+}
+
+AttributeUsage ::= ENUMERATED {
+ userApplications(0), directoryOperation(1), distributedOperation(2),
+ dSAOperation(3)}
+
+-- attributes
+objectClass ATTRIBUTE ::= {
+ WITH SYNTAX OBJECT IDENTIFIER
+ EQUALITY MATCHING RULE objectIdentifierMatch
+ ID id-at-objectClass
+}
+
+aliasedEntryName ATTRIBUTE ::= {
+ WITH SYNTAX DistinguishedName
+ EQUALITY MATCHING RULE distinguishedNameMatch
+ SINGLE VALUE TRUE
+ ID id-at-aliasedEntryName
+}
+
+-- MATCHING-RULE information object class specification
+MATCHING-RULE ::= CLASS {
+ &ParentMatchingRules MATCHING-RULE.&id OPTIONAL,
+ &AssertionType OPTIONAL,
+ &uniqueMatchIndicator ATTRIBUTE.&id OPTIONAL,
+ &id OBJECT IDENTIFIER UNIQUE
+}
+WITH SYNTAX {
+ [PARENT &ParentMatchingRules]
+ [SYNTAX &AssertionType]
+ [UNIQUE-MATCH-INDICATOR &uniqueMatchIndicator]
+ ID &id
+}
+
+-- matching rules
+objectIdentifierMatch MATCHING-RULE ::= {
+ SYNTAX OBJECT IDENTIFIER
+ ID id-mr-objectIdentifierMatch
+}
+
+distinguishedNameMatch MATCHING-RULE ::= {
+ SYNTAX DistinguishedName
+ ID id-mr-distinguishedNameMatch
+}
+
+MAPPING-BASED-MATCHING{SelectedBy, BOOLEAN:combinable, MappingResult,
+ OBJECT IDENTIFIER:matchingRule} ::= CLASS {
+ &selectBy SelectedBy OPTIONAL,
+ &ApplicableTo ATTRIBUTE,
+ &subtypesIncluded BOOLEAN DEFAULT TRUE,
+ &combinable BOOLEAN(combinable),
+ &mappingResults MappingResult OPTIONAL,
+ &userControl BOOLEAN DEFAULT FALSE,
+ &exclusive BOOLEAN DEFAULT TRUE,
+ &matching-rule MATCHING-RULE.&id(matchingRule),
+ &id OBJECT IDENTIFIER UNIQUE
+}
+WITH SYNTAX {
+ [SELECT BY &selectBy]
+ APPLICABLE TO &ApplicableTo
+ [SUBTYPES INCLUDED &subtypesIncluded]
+ COMBINABLE &combinable
+ [MAPPING RESULTS &mappingResults]
+ [USER CONTROL &userControl]
+ [EXCLUSIVE &exclusive]
+ MATCHING RULE &matching-rule
+ ID &id
+}
+
+-- NAME-FORM information object class specification
+NAME-FORM ::= CLASS {
+ &namedObjectClass OBJECT-CLASS,
+ &MandatoryAttributes ATTRIBUTE,
+ &OptionalAttributes ATTRIBUTE OPTIONAL,
+ &id OBJECT IDENTIFIER UNIQUE
+}
+WITH SYNTAX {
+ NAMES &namedObjectClass
+ WITH ATTRIBUTES &MandatoryAttributes
+ [AND OPTIONALLY &OptionalAttributes]
+ ID &id
+}
+
+-- STRUCTURE-RULE class and DIT structure rule data types
+STRUCTURE-RULE ::= CLASS {
+ &nameForm NAME-FORM,
+ &SuperiorStructureRules STRUCTURE-RULE OPTIONAL,
+ &id RuleIdentifier
+}
+WITH SYNTAX {
+ NAME FORM &nameForm
+ [SUPERIOR RULES &SuperiorStructureRules]
+ ID &id
+}
+
+DITStructureRule ::= SEQUENCE {
+ ruleIdentifier RuleIdentifier,
+ -- must be unique within the scope of the subschema
+ nameForm NAME-FORM.&id,
+ superiorStructureRules SET SIZE (1..MAX) OF RuleIdentifier OPTIONAL
+}
+
+RuleIdentifier ::= INTEGER
+
+-- CONTENT-RULE class and DIT content rule data types
+CONTENT-RULE ::= CLASS {
+ &structuralClass OBJECT-CLASS.&id UNIQUE,
+ &Auxiliaries OBJECT-CLASS OPTIONAL,
+ &Mandatory ATTRIBUTE OPTIONAL,
+ &Optional ATTRIBUTE OPTIONAL,
+ &Precluded ATTRIBUTE OPTIONAL
+}
+WITH SYNTAX {
+ STRUCTURAL OBJECT-CLASS &structuralClass
+ [AUXILIARY OBJECT-CLASSES &Auxiliaries]
+ [MUST CONTAIN &Mandatory]
+ [MAY CONTAIN &Optional]
+ [MUST-NOT CONTAIN &Precluded]
+}
+
+DITContentRule ::= SEQUENCE {
+ structuralObjectClass OBJECT-CLASS.&id,
+ auxiliaries SET SIZE (1..MAX) OF OBJECT-CLASS.&id OPTIONAL,
+ mandatory [1] SET SIZE (1..MAX) OF ATTRIBUTE.&id OPTIONAL,
+ optional [2] SET SIZE (1..MAX) OF ATTRIBUTE.&id OPTIONAL,
+ precluded [3] SET SIZE (1..MAX) OF ATTRIBUTE.&id OPTIONAL
+}
+
+CONTEXT ::= CLASS {
+ &Type ,
+ &Assertion OPTIONAL,
+ &id OBJECT IDENTIFIER UNIQUE
+}WITH SYNTAX {WITH SYNTAX &Type
+ [ASSERTED AS &Assertion]
+ ID &id
+}
+
+DITContextUse ::= SEQUENCE {
+ attributeType ATTRIBUTE.&id,
+ mandatoryContexts [1] SET SIZE (1..MAX) OF CONTEXT.&id OPTIONAL,
+ optionalContexts [2] SET SIZE (1..MAX) OF CONTEXT.&id OPTIONAL
+}
+
+DIT-CONTEXT-USE-RULE ::= CLASS {
+ &attributeType ATTRIBUTE.&id UNIQUE,
+ &Mandatory CONTEXT OPTIONAL,
+ &Optional CONTEXT OPTIONAL
+}
+WITH SYNTAX {
+ ATTRIBUTE TYPE &attributeType
+ [MANDATORY CONTEXTS &Mandatory]
+ [OPTIONAL CONTEXTS &Optional]
+}
+
+-- system schema information objects
+-- object classes
+subentry OBJECT-CLASS ::= {
+ SUBCLASS OF {top}
+ KIND structural
+ MUST CONTAIN {commonName | subtreeSpecification}
+ ID id-sc-subentry
+}
+
+subentryNameForm NAME-FORM ::= {
+ NAMES subentry
+ WITH ATTRIBUTES {commonName}
+ ID id-nf-subentryNameForm
+}
+
+accessControlSubentry OBJECT-CLASS ::= {
+ KIND auxiliary
+ ID id-sc-accessControlSubentry
+}
+
+collectiveAttributeSubentry OBJECT-CLASS ::= {
+ KIND auxiliary
+ ID id-sc-collectiveAttributeSubentry
+}
+
+contextAssertionSubentry OBJECT-CLASS ::= {
+ KIND auxiliary
+ MUST CONTAIN {contextAssertionDefaults}
+ ID id-sc-contextAssertionSubentry
+}
+
+serviceAdminSubentry OBJECT-CLASS ::= {
+ KIND auxiliary
+ MUST CONTAIN {searchRules}
+ ID id-sc-serviceAdminSubentry
+}
+
+-- attributes
+createTimestamp ATTRIBUTE ::= {
+ WITH SYNTAX GeneralizedTime
+ -- as per 41.3 b) or c) of ITU-T Rec. X.680 | ISO/IEC 8824-1
+ EQUALITY MATCHING RULE generalizedTimeMatch
+ ORDERING MATCHING RULE generalizedTimeOrderingMatch
+ SINGLE VALUE TRUE
+ NO USER MODIFICATION TRUE
+ USAGE directoryOperation
+ ID id-oa-createTimestamp
+}
+
+modifyTimestamp ATTRIBUTE ::= {
+ WITH SYNTAX GeneralizedTime
+ -- as per 41.3 b) or c) of ITU-T Rec. X.680 | ISO/IEC 8824-1
+ EQUALITY MATCHING RULE generalizedTimeMatch
+ ORDERING MATCHING RULE generalizedTimeOrderingMatch
+ SINGLE VALUE TRUE
+ NO USER MODIFICATION TRUE
+ USAGE directoryOperation
+ ID id-oa-modifyTimestamp
+}
+
+subschemaTimestamp ATTRIBUTE ::= {
+ WITH SYNTAX GeneralizedTime
+ -- as per 41.3 b) or c) of ITU-T Rec.X. 680 | ISO/IEC 8824-1
+ EQUALITY MATCHING RULE generalizedTimeMatch
+ ORDERING MATCHING RULE generalizedTimeOrderingMatch
+ SINGLE VALUE TRUE
+ NO USER MODIFICATION TRUE
+ USAGE directoryOperation
+ ID id-oa-subschemaTimestamp
+}
+
+creatorsName ATTRIBUTE ::= {
+ WITH SYNTAX DistinguishedName
+ EQUALITY MATCHING RULE distinguishedNameMatch
+ SINGLE VALUE TRUE
+ NO USER MODIFICATION TRUE
+ USAGE directoryOperation
+ ID id-oa-creatorsName
+}
+
+modifiersName ATTRIBUTE ::= {
+ WITH SYNTAX DistinguishedName
+ EQUALITY MATCHING RULE distinguishedNameMatch
+ SINGLE VALUE TRUE
+ NO USER MODIFICATION TRUE
+ USAGE directoryOperation
+ ID id-oa-modifiersName
+}
+
+subschemaSubentryList ATTRIBUTE ::= {
+ WITH SYNTAX DistinguishedName
+ EQUALITY MATCHING RULE distinguishedNameMatch
+ SINGLE VALUE TRUE
+ NO USER MODIFICATION TRUE
+ USAGE directoryOperation
+ ID id-oa-subschemaSubentryList
+}
+
+accessControlSubentryList ATTRIBUTE ::= {
+ WITH SYNTAX DistinguishedName
+ EQUALITY MATCHING RULE distinguishedNameMatch
+ NO USER MODIFICATION TRUE
+ USAGE directoryOperation
+ ID id-oa-accessControlSubentryList
+}
+
+collectiveAttributeSubentryList ATTRIBUTE ::= {
+ WITH SYNTAX DistinguishedName
+ EQUALITY MATCHING RULE distinguishedNameMatch
+ NO USER MODIFICATION TRUE
+ USAGE directoryOperation
+ ID id-oa-collectiveAttributeSubentryList
+}
+
+contextDefaultSubentryList ATTRIBUTE ::= {
+ WITH SYNTAX DistinguishedName
+ EQUALITY MATCHING RULE distinguishedNameMatch
+ NO USER MODIFICATION TRUE
+ USAGE directoryOperation
+ ID id-oa-contextDefaultSubentryList
+}
+
+serviceAdminSubentryList ATTRIBUTE ::= {
+ WITH SYNTAX DistinguishedName
+ EQUALITY MATCHING RULE distinguishedNameMatch
+ NO USER MODIFICATION TRUE
+ USAGE directoryOperation
+ ID id-oa-serviceAdminSubentryList
+}
+
+hasSubordinates ATTRIBUTE ::= {
+ WITH SYNTAX BOOLEAN
+ EQUALITY MATCHING RULE booleanMatch
+ SINGLE VALUE TRUE
+ NO USER MODIFICATION TRUE
+ USAGE directoryOperation
+ ID id-oa-hasSubordinates
+}
+
+administrativeRole ATTRIBUTE ::= {
+ WITH SYNTAX OBJECT-CLASS.&id
+ EQUALITY MATCHING RULE objectIdentifierMatch
+ USAGE directoryOperation
+ ID id-oa-administrativeRole
+}
+
+subtreeSpecification ATTRIBUTE ::= {
+ WITH SYNTAX SubtreeSpecification
+ USAGE directoryOperation
+ ID id-oa-subtreeSpecification
+}
+
+collectiveExclusions ATTRIBUTE ::= {
+ WITH SYNTAX OBJECT IDENTIFIER
+ EQUALITY MATCHING RULE objectIdentifierMatch
+ USAGE directoryOperation
+ ID id-oa-collectiveExclusions
+}
+
+contextAssertionDefaults ATTRIBUTE ::= {
+ WITH SYNTAX TypeAndContextAssertion
+ EQUALITY MATCHING RULE objectIdentifierFirstComponentMatch
+ USAGE directoryOperation
+ ID id-oa-contextAssertionDefault
+}
+
+searchRules ATTRIBUTE ::= {
+ WITH SYNTAX SearchRuleDescription
+ EQUALITY MATCHING RULE integerFirstComponentMatch
+ USAGE directoryOperation
+ ID id-oa-searchRules
+}
+
+SearchRuleDescription ::= SEQUENCE {
+ COMPONENTS OF SearchRule,
+ name [28] SET SIZE (1..MAX) OF DirectoryString{ub-search} OPTIONAL,
+ description [29] DirectoryString{ub-search} OPTIONAL,
+ obsolete [30] BOOLEAN DEFAULT FALSE
+}
+
+hierarchyLevel ATTRIBUTE ::= {
+ WITH SYNTAX INTEGER
+ EQUALITY MATCHING RULE integerMatch
+ ORDERING MATCHING RULE integerOrderingMatch
+ SINGLE VALUE TRUE
+ NO USER MODIFICATION TRUE
+ USAGE directoryOperation
+ ID id-oa-hierarchyLevel
+}
+
+hierarchyBelow ATTRIBUTE ::= {
+ WITH SYNTAX BOOLEAN
+ EQUALITY MATCHING RULE booleanMatch
+ SINGLE VALUE TRUE
+ NO USER MODIFICATION TRUE
+ USAGE directoryOperation
+ ID id-oa-hierarchyBelow
+}
+
+hierarchyParent ATTRIBUTE ::= {
+ WITH SYNTAX DistinguishedName
+ EQUALITY MATCHING RULE distinguishedNameMatch
+ SINGLE VALUE TRUE
+ USAGE directoryOperation
+ ID id-oa-hierarchyParent
+}
+
+SearchRule ::= SEQUENCE {
+ COMPONENTS OF SearchRuleId,
+ serviceType [1] OBJECT IDENTIFIER OPTIONAL,
+ userClass [2] INTEGER OPTIONAL,
+ inputAttributeTypes
+ [3] SEQUENCE SIZE (1..MAX) OF RequestAttribute OPTIONAL,
+ attributeCombination [4] AttributeCombination DEFAULT and:{},
+ outputAttributeTypes [5] SEQUENCE SIZE (1..MAX) OF ResultAttribute OPTIONAL,
+ defaultControls [6] ControlOptions OPTIONAL,
+ mandatoryControls [7] ControlOptions OPTIONAL,
+ searchRuleControls [8] ControlOptions OPTIONAL,
+ familyGrouping [9] FamilyGrouping OPTIONAL,
+ familyReturn [10] FamilyReturn OPTIONAL,
+ relaxation [11] RelaxationPolicy OPTIONAL,
+ additionalControl [12] SEQUENCE SIZE (1..MAX) OF AttributeType OPTIONAL,
+ allowedSubset [13] AllowedSubset DEFAULT '111'B,
+ imposedSubset [14] ImposedSubset OPTIONAL,
+ entryLimit [15] EntryLimit OPTIONAL
+}
+
+SearchRuleId ::= SEQUENCE {id INTEGER,
+ dmdId [0] OBJECT IDENTIFIER
+}
+
+AllowedSubset ::= BIT STRING {baseObject(0), oneLevel(1), wholeSubtree(2)}
+
+ImposedSubset ::= ENUMERATED {baseObject(0), oneLevel(1), wholeSubtree(2)}
+
+RequestAttribute ::= SEQUENCE {
+ attributeType ATTRIBUTE.&id({SupportedAttributes}),
+ includeSubtypes [0] BOOLEAN DEFAULT FALSE,
+ selectedValues
+ [1] SEQUENCE SIZE (0..MAX) OF
+ ATTRIBUTE.&Type({SupportedAttributes}{@attributeType}) OPTIONAL,
+ defaultValues
+ [2] SEQUENCE SIZE (0..MAX) OF
+ SEQUENCE {entryType OBJECT-CLASS.&id OPTIONAL,
+ values
+ SEQUENCE OF
+ ATTRIBUTE.&Type({SupportedAttributes}{@attributeType})
+ } OPTIONAL,
+ contexts [3] SEQUENCE SIZE (0..MAX) OF ContextProfile OPTIONAL,
+ contextCombination [4] ContextCombination DEFAULT and:{},
+ matchingUse [5] SEQUENCE SIZE (1..MAX) OF MatchingUse OPTIONAL
+}
+
+ContextProfile ::= SEQUENCE {
+ contextType CONTEXT.&id({SupportedContexts}),
+ contextValue
+ SEQUENCE SIZE (1..MAX) OF
+ CONTEXT.&Assertion({SupportedContexts}{@contextType}) OPTIONAL
+}
+
+ContextCombination ::= CHOICE {
+ context [0] CONTEXT.&id,
+ and [1] SEQUENCE OF ContextCombination,
+ or [2] SEQUENCE OF ContextCombination,
+ not [3] ContextCombination
+}
+
+MatchingUse ::= SEQUENCE {
+ restrictionType MATCHING-RESTRICTION.&id({SupportedMatchingRestrictions}),
+ restrictionValue
+ MATCHING-RESTRICTION.&Restriction
+ ({SupportedMatchingRestrictions}{@restrictionType})
+}
+
+-- Definition of the following information object set is deferred, perhaps to standardized
+-- profiles or to protocol implementation conformance statements. The set is required to
+-- specify a table constraint on the components of SupportedMatchingRestrictions
+SupportedMatchingRestrictions MATCHING-RESTRICTION ::=
+ {...}
+
+AttributeCombination ::= CHOICE {
+ attribute [0] AttributeType,
+ and [1] SEQUENCE OF AttributeCombination,
+ or [2] SEQUENCE OF AttributeCombination,
+ not [3] AttributeCombination
+}
+
+ResultAttribute ::= SEQUENCE {
+ attributeType ATTRIBUTE.&id({SupportedAttributes}),
+ outputValues
+ CHOICE {selectedValues
+ SEQUENCE SIZE (1..MAX) OF
+ ATTRIBUTE.&Type({SupportedAttributes}{@attributeType}),
+ matchedValuesOnly NULL} OPTIONAL,
+ contexts [0] SEQUENCE SIZE (1..MAX) OF ContextProfile OPTIONAL
+}
+
+OutputValues ::= CHOICE {
+ selectedValues
+ SEQUENCE SIZE (1..MAX) OF ATTRIBUTE.&Type({SupportedAttributes}),
+ matchedValuesOnly NULL
+}
+
+ControlOptions ::= SEQUENCE {
+ serviceControls [0] ServiceControlOptions DEFAULT {},
+ searchOptions [1] SearchControlOptions DEFAULT {searchAliases},
+ hierarchyOptions [2] HierarchySelections OPTIONAL
+}
+
+EntryLimit ::= SEQUENCE {default INTEGER,
+ max INTEGER
+}
+
+RelaxationPolicy ::= SEQUENCE {
+ basic [0] MRMapping DEFAULT {},
+ tightenings [1] SEQUENCE SIZE (1..MAX) OF MRMapping OPTIONAL,
+ relaxations [2] SEQUENCE SIZE (1..MAX) OF MRMapping OPTIONAL,
+ maximum [3] INTEGER OPTIONAL, -- mandatory if tightenings is present
+ minimum [4] INTEGER DEFAULT 1
+}
+
+MRMapping ::= SEQUENCE {
+ mapping [0] SEQUENCE SIZE (1..MAX) OF Mapping OPTIONAL,
+ substitution [1] SEQUENCE SIZE (1..MAX) OF MRSubstitution OPTIONAL
+}
+
+Mapping ::= SEQUENCE {
+ mappingFunction
+ OBJECT IDENTIFIER
+ (CONSTRAINED BY {-- shall be an--
+
+ -- object identifier of a mapping-based matching algorithm -- }),
+ level INTEGER DEFAULT 0
+}
+
+MRSubstitution ::= SEQUENCE {
+ attribute AttributeType,
+ oldMatchingRule [0] MATCHING-RULE.&id OPTIONAL,
+ newMatchingRule [1] MATCHING-RULE.&id OPTIONAL
+}
+
+SEARCH-RULE ::= CLASS {
+ &dmdId OBJECT IDENTIFIER,
+ &serviceType OBJECT IDENTIFIER OPTIONAL,
+ &userClass INTEGER OPTIONAL,
+ &InputAttributeTypes REQUEST-ATTRIBUTE OPTIONAL,
+ &combination AttributeCombination OPTIONAL,
+ &OutputAttributeTypes RESULT-ATTRIBUTE OPTIONAL,
+ &defaultControls ControlOptions OPTIONAL,
+ &mandatoryControls ControlOptions OPTIONAL,
+ &searchRuleControls ControlOptions OPTIONAL,
+ &familyGrouping FamilyGrouping OPTIONAL,
+ &familyReturn FamilyReturn OPTIONAL,
+ &additionalControl AttributeType OPTIONAL,
+ &relaxation RelaxationPolicy OPTIONAL,
+ &entryLimit EntryLimit OPTIONAL,
+ &allowedSubset AllowedSubset DEFAULT '111'B,
+ &imposedSubset ImposedSubset OPTIONAL,
+ &id INTEGER UNIQUE
+}
+WITH SYNTAX {
+ DMD ID &dmdId
+ [SERVICE-TYPE &serviceType]
+ [USER-CLASS &userClass]
+ [INPUT ATTRIBUTES &InputAttributeTypes]
+ [COMBINATION &combination]
+ [OUTPUT ATTRIBUTES &OutputAttributeTypes]
+ [DEFAULT CONTROL &defaultControls]
+ [MANDATORY CONTROL &mandatoryControls]
+ [SEARCH-RULE CONTROL &searchRuleControls]
+ [FAMILY-GROUPING &familyGrouping]
+ [FAMILY-RETURN &familyReturn]
+ [ADDITIONAL CONTROL &additionalControl]
+ [RELAXATION &relaxation]
+ [ALLOWED SUBSET &allowedSubset]
+ [IMPOSED SUBSET &imposedSubset]
+ [ENTRY LIMIT &entryLimit]
+ ID &id
+}
+
+REQUEST-ATTRIBUTE ::= CLASS {
+ &attributeType ATTRIBUTE.&id,
+ &SelectedValues ATTRIBUTE.&Type OPTIONAL,
+ &DefaultValues SEQUENCE {entryType OBJECT-CLASS.&id OPTIONAL,
+ values SEQUENCE OF ATTRIBUTE.&Type
+ } OPTIONAL,
+ &contexts SEQUENCE OF ContextProfile OPTIONAL,
+ &contextCombination ContextCombination OPTIONAL,
+ &MatchingUse MatchingUse OPTIONAL,
+ &includeSubtypes BOOLEAN DEFAULT FALSE
+}
+WITH SYNTAX {
+ ATTRIBUTE TYPE &attributeType
+ [SELECTED VALUES &SelectedValues]
+ [DEFAULT VALUES &DefaultValues]
+ [CONTEXTS &contexts]
+ [CONTEXT COMBINATION &contextCombination]
+ [MATCHING USE &MatchingUse]
+ [INCLUDE SUBTYPES &includeSubtypes]
+}
+
+RESULT-ATTRIBUTE ::= CLASS {
+ &attributeType ATTRIBUTE.&id,
+ &outputValues OutputValues OPTIONAL,
+ &contexts ContextProfile OPTIONAL
+}
+WITH SYNTAX {
+ ATTRIBUTE TYPE &attributeType
+ [OUTPUT VALUES &outputValues]
+ [CONTEXTS &contexts]
+}
+
+MATCHING-RESTRICTION ::= CLASS {
+ &Restriction ,
+ &Rules MATCHING-RULE.&id,
+ &id OBJECT IDENTIFIER UNIQUE
+}WITH SYNTAX {RESTRICTION &Restriction
+ RULES &Rules
+ ID &id
+}
+
+-- object identifier assignments
+-- object classes
+id-oc-top OBJECT IDENTIFIER ::=
+ {id-oc 0}
+
+id-oc-alias OBJECT IDENTIFIER ::= {id-oc 1}
+
+id-oc-parent OBJECT IDENTIFIER ::= {id-oc 28}
+
+id-oc-child OBJECT IDENTIFIER ::= {id-oc 29}
+
+-- attributes
+id-at-objectClass OBJECT IDENTIFIER ::= {id-at 0}
+
+id-at-aliasedEntryName OBJECT IDENTIFIER ::= {id-at 1}
+
+-- matching rules
+id-mr-objectIdentifierMatch OBJECT IDENTIFIER ::= {id-mr 0}
+
+id-mr-distinguishedNameMatch OBJECT IDENTIFIER ::= {id-mr 1}
+
+-- operational attributes
+id-oa-excludeAllCollectiveAttributes OBJECT IDENTIFIER ::=
+ {id-oa 0}
+
+id-oa-createTimestamp OBJECT IDENTIFIER ::= {id-oa 1}
+
+id-oa-modifyTimestamp OBJECT IDENTIFIER ::= {id-oa 2}
+
+id-oa-creatorsName OBJECT IDENTIFIER ::= {id-oa 3}
+
+id-oa-modifiersName OBJECT IDENTIFIER ::= {id-oa 4}
+
+id-oa-administrativeRole OBJECT IDENTIFIER ::= {id-oa 5}
+
+id-oa-subtreeSpecification OBJECT IDENTIFIER ::= {id-oa 6}
+
+id-oa-collectiveExclusions OBJECT IDENTIFIER ::= {id-oa 7}
+
+id-oa-subschemaTimestamp OBJECT IDENTIFIER ::= {id-oa 8}
+
+id-oa-hasSubordinates OBJECT IDENTIFIER ::= {id-oa 9}
+
+id-oa-subschemaSubentryList OBJECT IDENTIFIER ::= {id-oa 10}
+
+id-oa-accessControlSubentryList OBJECT IDENTIFIER ::= {id-oa 11}
+
+id-oa-collectiveAttributeSubentryList OBJECT IDENTIFIER ::= {id-oa 12}
+
+id-oa-contextDefaultSubentryList OBJECT IDENTIFIER ::= {id-oa 13}
+
+id-oa-contextAssertionDefault OBJECT IDENTIFIER ::= {id-oa 14}
+
+id-oa-serviceAdminSubentryList OBJECT IDENTIFIER ::= {id-oa 15}
+
+id-oa-searchRules OBJECT IDENTIFIER ::= {id-oa 16}
+
+id-oa-hierarchyLevel OBJECT IDENTIFIER ::= {id-oa 17}
+
+id-oa-hierarchyBelow OBJECT IDENTIFIER ::= {id-oa 18}
+
+id-oa-hierarchyParent OBJECT IDENTIFIER ::= {id-oa 19}
+
+-- subentry classes
+id-sc-subentry OBJECT IDENTIFIER ::= {id-sc 0}
+
+id-sc-accessControlSubentry OBJECT IDENTIFIER ::= {id-sc 1}
+
+id-sc-collectiveAttributeSubentry OBJECT IDENTIFIER ::= {id-sc 2}
+
+id-sc-contextAssertionSubentry OBJECT IDENTIFIER ::= {id-sc 3}
+
+id-sc-serviceAdminSubentry OBJECT IDENTIFIER ::= {id-sc 4}
+
+-- Name forms
+id-nf-subentryNameForm OBJECT IDENTIFIER ::= {id-nf 16}
+
+-- administrative roles
+id-ar-autonomousArea OBJECT IDENTIFIER ::= {id-ar 1}
+
+id-ar-accessControlSpecificArea OBJECT IDENTIFIER ::= {id-ar 2}
+
+id-ar-accessControlInnerArea OBJECT IDENTIFIER ::= {id-ar 3}
+
+id-ar-subschemaAdminSpecificArea OBJECT IDENTIFIER ::= {id-ar 4}
+
+id-ar-collectiveAttributeSpecificArea OBJECT IDENTIFIER ::= {id-ar 5}
+
+id-ar-collectiveAttributeInnerArea OBJECT IDENTIFIER ::= {id-ar 6}
+
+id-ar-contextDefaultSpecificArea OBJECT IDENTIFIER ::= {id-ar 7}
+
+id-ar-serviceSpecificArea OBJECT IDENTIFIER ::= {id-ar 8}
+
+END -- InformationFramework
+
+-- Generated by Asnp, the ASN.1 pretty-printer of France Telecom R&D
+
diff --git a/lib/asn1/test/asn1_SUITE_data/x420/Interchange-Data-Elements.asn b/lib/asn1/test/asn1_SUITE_data/x420/Interchange-Data-Elements.asn
new file mode 100644
index 0000000000..2c78360b7b
--- /dev/null
+++ b/lib/asn1/test/asn1_SUITE_data/x420/Interchange-Data-Elements.asn
@@ -0,0 +1,57 @@
+-- Module Interchange-Data-Elements (T.415:03/1993)
+
+Interchange-Data-Elements {2 8 1 5 5} DEFINITIONS ::=
+BEGIN
+
+EXPORTS Interchange-Data-Element;
+
+IMPORTS
+ Document-Profile-Descriptor
+ FROM Document-Profile-Descriptor -- see 7.7
+
+ Layout-Class-Descriptor, Layout-Object-Descriptor
+ FROM Layout-Descriptors -- see 7.9
+
+ Logical-Class-Descriptor, Logical-Object-Descriptor
+ FROM Logical-Descriptors -- see 7.10
+
+ Presentation-Style-Descriptor, Layout-Style-Descriptor
+ FROM Style-Descriptors -- see 7.11
+
+ Text-Unit
+ FROM Text-Units -- see 7.13
+
+ Sealed-Doc-Prof-Descriptor, Enciphered-Doc-Prof-Descriptor,
+ Preenciphered-Bodypart-Descriptor, Postenciphered-Bodypart-Descriptor
+ FROM Protected-Part-Descriptors -- see 7.15
+
+ Link-Class-Descriptor, Link-Descriptor, Enciphered-Link-Descriptor
+ FROM Link-Descriptors {2 8 1 14 3};
+
+-- See ITU-T Rec. T.424 | ISO/IEC 8613-14
+Interchange-Data-Element ::= CHOICE {
+ document-profile [0] IMPLICIT Document-Profile-Descriptor,
+ layout-object-class [1] IMPLICIT Layout-Class-Descriptor,
+ layout-object [2] IMPLICIT Layout-Object-Descriptor,
+ content-portion [3] IMPLICIT Text-Unit,
+ logical-object-class [5] IMPLICIT Logical-Class-Descriptor,
+ logical-object [6] IMPLICIT Logical-Object-Descriptor,
+ presentation-style
+ [7] IMPLICIT Presentation-Style-Descriptor,
+ layout-style [8] IMPLICIT Layout-Style-Descriptor,
+ sealed-doc-prof-descriptor [9] IMPLICIT Sealed-Doc-Prof-Descriptor,
+ enciphered-doc-prof-descriptor
+ [10] IMPLICIT Enciphered-Doc-Prof-Descriptor,
+ preenciphered-bodypart-descriptor
+ [11] IMPLICIT Preenciphered-Bodypart-Descriptor,
+ postenciphered-bodypart-descriptor
+ [12] IMPLICIT Postenciphered-Bodypart-Descriptor,
+ link-class [13] IMPLICIT Link-Class-Descriptor,
+ link [14] IMPLICIT Link-Descriptor,
+ enciphered-link-descriptor [15] IMPLICIT Enciphered-Link-Descriptor
+}
+
+END
+
+-- Generated by Asnp, the ASN.1 pretty-printer of France Telecom R&D
+
diff --git a/lib/asn1/test/asn1_SUITE_data/x420/Layout-Descriptors.asn b/lib/asn1/test/asn1_SUITE_data/x420/Layout-Descriptors.asn
new file mode 100644
index 0000000000..92c887bb06
--- /dev/null
+++ b/lib/asn1/test/asn1_SUITE_data/x420/Layout-Descriptors.asn
@@ -0,0 +1,268 @@
+-- Module Layout-Descriptors (T.415:03/1993)
+
+Layout-Descriptors {2 8 1 5 8} DEFINITIONS ::=
+BEGIN
+
+EXPORTS
+ Layout-Object-Descriptor, Layout-Class-Descriptor, Layout-Object-Type,
+ Transparency, Comment-String, Binding-Pair, One-Of-Four-Angles,
+ Measure-Pair, Dimension-Pair, Medium-Type, Colour, Border,
+ Content-Background-Colour, Content-Foreground-Colour, Enciphered,
+ Sealed;
+
+IMPORTS
+ Object-or-Class-Identifier, Style-Identifier, Protected-Part-Identifier,
+ Category-Name, Resource-Name, Binding-Name, Construction-Expression,
+ Object-Id-Expression, Numeric-Expression, String-Expression
+ FROM Identifiers-and-Expressions -- see 7.8
+
+ Presentation-Attributes
+ FROM Style-Descriptors -- see 7.11
+
+ Default-Value-Lists-Layout
+ FROM Default-Value-Lists -- see 7.12
+
+ Colour-Expression, Colour-Table
+ FROM Colour-Attributes -- see 7.14
+
+ Presentation-Time
+ FROM Temporal-Relationships {2 8 1 14 0};
+
+-- See ITU-T Rec. T.424 | ISO/IEC 8613-14
+Position-Spec ::= SET {
+ offset
+ [0] IMPLICIT SET {leading [0] IMPLICIT INTEGER OPTIONAL,
+ trailing [1] IMPLICIT INTEGER OPTIONAL,
+ left-hand [2] IMPLICIT INTEGER OPTIONAL,
+ right-hand [3] IMPLICIT INTEGER OPTIONAL} OPTIONAL,
+ separation
+ [1] IMPLICIT SET {leading [0] IMPLICIT INTEGER OPTIONAL,
+ trailing [1] IMPLICIT INTEGER OPTIONAL,
+ centre [2] IMPLICIT INTEGER OPTIONAL} OPTIONAL,
+ alignment
+ [2] IMPLICIT INTEGER {right-hand(0), centred(1), left-hand(2)} OPTIONAL,
+ fill-order [3] IMPLICIT INTEGER {normal(0), reverse(1)} OPTIONAL
+}
+
+Dimension-Pair ::= SEQUENCE {
+ horizontal
+ CHOICE {fixed [0] IMPLICIT INTEGER,
+ not-present [4] IMPLICIT NULL},
+ vertical
+ CHOICE {fixed [0] IMPLICIT INTEGER,
+ variable [1] IMPLICIT INTEGER,
+ not-present [4] IMPLICIT NULL}
+}
+
+-- the choice 'not-present' indicates that the parameter is not present
+Dimension-Spec ::= SEQUENCE {horizontal Dimension,
+ vertical Dimension
+}
+
+Dimension ::= CHOICE {
+ fixed [0] IMPLICIT INTEGER,
+ rule-a
+ [1] IMPLICIT SET {minimum [0] IMPLICIT INTEGER OPTIONAL,
+ maximum [1] IMPLICIT INTEGER OPTIONAL},
+ rule-b
+ [2] IMPLICIT SET {minimum [0] IMPLICIT INTEGER OPTIONAL,
+ maximum [1] IMPLICIT INTEGER OPTIONAL},
+ maximum-size [3] IMPLICIT NULL,
+ not-present [4] IMPLICIT NULL
+}
+
+-- the choice 'not-present' indicates that the parameter is not present
+Transparency ::= INTEGER {transparent(0), opaque(1)}
+
+Comment-String ::= OCTET STRING
+
+-- string of characters from the sets designated by
+-- the document profile attribute "comments character sets",
+-- plus code extension control functions,
+-- space, carriage return and line feed
+Binding-Pair ::= SET {
+ binding-identifier [0] IMPLICIT Binding-Name,
+ binding-value
+ CHOICE {a [1] Object-Id-Expression,
+ b [2] Numeric-Expression,
+ c [3] String-Expression,
+ d [4] IMPLICIT Object-or-Class-Identifier,
+ e [5] IMPLICIT INTEGER,
+ f [6] IMPLICIT OCTET STRING}
+}
+
+One-Of-Four-Angles ::= INTEGER {d0(0), d90(1), d180(2), d270(3)}
+
+Measure-Pair ::= SEQUENCE {
+ horizontal
+ CHOICE {fixed [0] IMPLICIT INTEGER,
+ not-present [4] IMPLICIT NULL},
+ vertical
+ CHOICE {fixed [0] IMPLICIT INTEGER,
+ not-present [4] IMPLICIT NULL}
+}
+
+-- the choice 'not-present' indicates that the parameter is not present
+Medium-Type ::= SEQUENCE {
+ nominal-page-size Measure-Pair OPTIONAL,
+ side-of-sheet INTEGER {unspecified(0), recto(1), verso(2)} OPTIONAL,
+ colour-of-medium [3] Colour-Of-Medium OPTIONAL
+}
+
+Colour ::= INTEGER {colour-of-media(0), coloured(1)}
+
+Border ::= SET {
+ left-hand-edge [0] IMPLICIT Border-Edge OPTIONAL,
+ right-hand-edge [1] IMPLICIT Border-Edge OPTIONAL,
+ trailing-edge [2] IMPLICIT Border-Edge OPTIONAL,
+ leading-edge [3] IMPLICIT Border-Edge OPTIONAL
+}
+
+Border-Edge ::= SET {
+ line-width [0] IMPLICIT INTEGER OPTIONAL,
+ line-type
+ [1] IMPLICIT INTEGER {invisible(0), solid(1), dashed(2), dot(3),
+ dash-dot(4), dash-dot-dot(5)} OPTIONAL,
+ freespace-width [2] IMPLICIT INTEGER OPTIONAL,
+ border-line-colour [3] Border-Line-Colour OPTIONAL
+}
+
+-- a 'null' border edge is represented by an empty set
+Colour-Of-Medium ::= CHOICE {
+ unspecified-colour [3] IMPLICIT NULL,
+ specified-colour Colour-Expression
+}
+
+Border-Line-Colour ::= CHOICE {
+ implementation-defined [3] IMPLICIT NULL,
+ colour-expression Colour-Expression
+}
+
+Content-Background-Colour ::= CHOICE {
+ content-background-transparency [2] IMPLICIT NULL,
+ colour-expression Colour-Expression
+}
+
+Content-Foreground-Colour ::= CHOICE {
+ implementation-defined [3] IMPLICIT NULL,
+ content-foreground-transparency [2] IMPLICIT NULL,
+ colour-expression Colour-Expression
+}
+
+Enciphered ::= SEQUENCE {
+ enciphered-subordinates
+ CHOICE {none-all [0] IMPLICIT INTEGER {none(0), all(1)},
+ partial [1] IMPLICIT SEQUENCE OF NumericString},
+ protected-part-id [2] IMPLICIT Protected-Part-Identifier OPTIONAL
+}
+
+Sealed ::= SEQUENCE {
+ sealed-status [0] IMPLICIT INTEGER {no(0), yes(1)},
+ seal-ids [1] IMPLICIT SET OF INTEGER OPTIONAL
+}
+
+Layout-Object-Descriptor ::= SEQUENCE {
+ object-type Layout-Object-Type OPTIONAL,
+ descriptor-body Layout-Object-Descriptor-Body OPTIONAL
+}
+
+Layout-Object-Type ::= INTEGER {
+ document-layout-root(0), page-set(1), page(2), frame(3), block(4)}
+
+Layout-Object-Descriptor-Body ::= SET {
+ object-identifier Object-or-Class-Identifier OPTIONAL,
+ subordinates [0] IMPLICIT SEQUENCE OF NumericString OPTIONAL,
+ content-portions [1] IMPLICIT SEQUENCE OF NumericString OPTIONAL,
+ object-class
+ [2] IMPLICIT Object-or-Class-Identifier OPTIONAL,
+ position [3] IMPLICIT Measure-Pair OPTIONAL,
+ dimensions [4] IMPLICIT Dimension-Pair OPTIONAL,
+ transparency [5] IMPLICIT Transparency OPTIONAL,
+ presentation-attributes [6] IMPLICIT Presentation-Attributes OPTIONAL,
+ default-value-lists
+ [7] IMPLICIT Default-Value-Lists-Layout OPTIONAL,
+ user-readable-comments [8] IMPLICIT Comment-String OPTIONAL,
+ bindings [9] IMPLICIT SET OF Binding-Pair OPTIONAL,
+ layout-path [11] IMPLICIT One-Of-Four-Angles OPTIONAL,
+ imaging-order
+ [12] IMPLICIT SEQUENCE OF NumericString OPTIONAL,
+ layout-stream-categories [36] IMPLICIT SET OF Category-Name OPTIONAL,
+ layout-stream-sub-categories [37] IMPLICIT SET OF Category-Name OPTIONAL,
+ permitted-categories [13] IMPLICIT SET OF Category-Name OPTIONAL,
+ -- a 'null' value is represented by an empty set
+ user-visible-name [14] IMPLICIT Comment-String OPTIONAL,
+ page-position [15] IMPLICIT Measure-Pair OPTIONAL,
+ medium-type [16] IMPLICIT Medium-Type OPTIONAL,
+ presentation-style [17] IMPLICIT Style-Identifier OPTIONAL,
+ balance
+ [21] IMPLICIT SEQUENCE OF Object-or-Class-Identifier OPTIONAL,
+ -- a 'null' value is represented by an empty sequence
+ colour [22] IMPLICIT Colour OPTIONAL,
+ colour-of-layout-object [29] Colour-Expression OPTIONAL,
+ object-colour-table [30] IMPLICIT Colour-Table OPTIONAL,
+ content-background-colour [31] Content-Background-Colour OPTIONAL,
+ content-foreground-colour [32] Content-Foreground-Colour OPTIONAL,
+ content-colour-table [33] IMPLICIT Colour-Table OPTIONAL,
+ border [23] IMPLICIT Border OPTIONAL,
+ application-comments [25] IMPLICIT OCTET STRING OPTIONAL,
+ primary
+ [27] IMPLICIT Object-or-Class-Identifier OPTIONAL,
+ alternative
+ [28] IMPLICIT Object-or-Class-Identifier OPTIONAL,
+ enciphered [34] IMPLICIT Enciphered OPTIONAL,
+ sealed [35] IMPLICIT Sealed OPTIONAL,
+ presentation-time [52] IMPLICIT Presentation-Time OPTIONAL
+}
+
+Layout-Class-Descriptor ::= SEQUENCE {
+ object-type Layout-Object-Type,
+ descriptor-body Layout-Class-Descriptor-Body
+}
+
+Layout-Class-Descriptor-Body ::= SET {
+ object-class-identifier Object-or-Class-Identifier,
+ generator-for-subordinates [0] Construction-Expression OPTIONAL,
+ content-portions [1] IMPLICIT SEQUENCE OF NumericString OPTIONAL,
+ position
+ CHOICE {fixed-position [3] IMPLICIT Measure-Pair,
+ variable-position [26] IMPLICIT Position-Spec} OPTIONAL,
+ dimensions [4] IMPLICIT Dimension-Spec OPTIONAL,
+ transparency [5] IMPLICIT Transparency OPTIONAL,
+ presentation-attributes [6] IMPLICIT Presentation-Attributes OPTIONAL,
+ default-value-lists
+ [7] IMPLICIT Default-Value-Lists-Layout OPTIONAL,
+ user-readable-comments [8] IMPLICIT Comment-String OPTIONAL,
+ bindings [9] IMPLICIT SET OF Binding-Pair OPTIONAL,
+ content-generator [10] IMPLICIT String-Expression OPTIONAL,
+ layout-path [11] IMPLICIT One-Of-Four-Angles OPTIONAL,
+ layout-stream-categories [36] IMPLICIT SET OF Category-Name OPTIONAL,
+ layout-stream-sub-categories [37] IMPLICIT SET OF Category-Name OPTIONAL,
+ permitted-categories [13] IMPLICIT SET OF Category-Name OPTIONAL,
+ -- a 'null' value is represented by an empty set
+ user-visible-name [14] IMPLICIT Comment-String OPTIONAL,
+ page-position [15] IMPLICIT Measure-Pair OPTIONAL,
+ medium-type [16] IMPLICIT Medium-Type OPTIONAL,
+ presentation-style [17] IMPLICIT Style-Identifier OPTIONAL,
+ logical-source
+ [18] IMPLICIT Object-or-Class-Identifier OPTIONAL,
+ balance
+ [21] IMPLICIT SEQUENCE OF Object-or-Class-Identifier OPTIONAL,
+ -- a 'null' value is represented by an empty sequence
+ colour [22] IMPLICIT Colour OPTIONAL,
+ colour-of-layout-object [29] Colour-Expression OPTIONAL,
+ object-colour-table [30] IMPLICIT Colour-Table OPTIONAL,
+ content-background-colour [31] Content-Background-Colour OPTIONAL,
+ content-foreground-colour [32] Content-Foreground-Colour OPTIONAL,
+ content-colour-table [33] IMPLICIT Colour-Table OPTIONAL,
+ border [23] IMPLICIT Border OPTIONAL,
+ resource [24] IMPLICIT Resource-Name OPTIONAL,
+ application-comments [25] IMPLICIT OCTET STRING OPTIONAL,
+ enciphered [34] IMPLICIT Enciphered OPTIONAL,
+ sealed [35] IMPLICIT Sealed OPTIONAL,
+ presentation-time [52] IMPLICIT Presentation-Time OPTIONAL
+}
+
+END
+
+-- Generated by Asnp, the ASN.1 pretty-printer of France Telecom R&D
+
diff --git a/lib/asn1/test/asn1_SUITE_data/x420/Link-Descriptors.asn b/lib/asn1/test/asn1_SUITE_data/x420/Link-Descriptors.asn
new file mode 100644
index 0000000000..64fc4436e4
--- /dev/null
+++ b/lib/asn1/test/asn1_SUITE_data/x420/Link-Descriptors.asn
@@ -0,0 +1,80 @@
+-- Module Link-Descriptors (T.424:07/1996)
+
+Link-Descriptors {2 8 1 14 3} DEFINITIONS ::=
+BEGIN
+
+EXPORTS
+ Link-Class-Descriptor, Link-Descriptor, Link-or-Link-Class-Identifier,
+ Enciphered-Link-Descriptor;
+
+IMPORTS
+ Reference-Name
+ FROM External-References {2 8 1 12 1}
+ -- see ITU-T Rec. T.422 | ISO/IEC 8613-12
+ Location-Expression
+ FROM Location-Expressions {2 8 1 12 0}
+ -- see ITU-T Rec. T.422 | ISO/IEC 8613-12
+ Style-Identifier, Protected-Part-Identifier
+ FROM Identifiers-and-Expressions {2 8 1 5 7}
+ -- see ITU-T Rec. T.415 | ISO/IEC 8613-5
+ Comment-String, Sealed
+ FROM Layout-Descriptors {2 8 1 5 8}
+ -- see ITU-T Rec. T.415 | ISO/IEC 8613-5
+ Temporal-Relations, Presentation-Time
+ FROM Temporal-Relationships;
+
+-- see 7.5
+Link-or-Link-Class-Identifier ::= [APPLICATION 9] IMPLICIT PrintableString
+
+-- only digits and space are used in the present version of this Recommendation | International Standard;
+-- other characters are reserved for extensions
+Link-Class-Descriptor ::= SET {
+ link-class-identifier Link-or-Link-Class-Identifier,
+ link-roles [1] SEQUENCE OF Link-Role OPTIONAL,
+ user-readable-comments [2] IMPLICIT Comment-String OPTIONAL,
+ user-visible-name [3] IMPLICIT Comment-String OPTIONAL,
+ application-comments [25] IMPLICIT OCTET STRING OPTIONAL,
+ sealed [35] IMPLICIT Sealed OPTIONAL,
+ temporal-relations [38] IMPLICIT Temporal-Relations OPTIONAL,
+ presentation-time [39] IMPLICIT Presentation-Time OPTIONAL
+}
+
+Link-Descriptor ::= SET {
+ link-identifier Link-or-Link-Class-Identifier,
+ link-class [0] IMPLICIT Link-or-Link-Class-Identifier OPTIONAL,
+ link-roles [1] SEQUENCE OF Link-Role OPTIONAL,
+ user-readable-comments [2] IMPLICIT Comment-String OPTIONAL,
+ user-visible-name [3] IMPLICIT Comment-String OPTIONAL,
+ application-comments [25] IMPLICIT OCTET STRING OPTIONAL,
+ sealed [35] IMPLICIT Sealed OPTIONAL,
+ temporal-relations [38] IMPLICIT Temporal-Relations OPTIONAL,
+ presentation-time [39] IMPLICIT Presentation-Time OPTIONAL
+}
+
+Link-Role ::= SET {
+ link-ends SET OF Link-End,
+ user-readable-comments [2] IMPLICIT Comment-String OPTIONAL,
+ user-visible-name [3] IMPLICIT Comment-String OPTIONAL,
+ application-comments [25] IMPLICIT OCTET STRING OPTIONAL
+}
+
+Link-End ::= SET {
+ reference
+ SET {reference-name [0] Reference-Name OPTIONAL,
+ reference-qualifier [1] Location-Expression OPTIONAL},
+ user-readable-comments [2] IMPLICIT Comment-String OPTIONAL,
+ user-visible-name [3] IMPLICIT Comment-String OPTIONAL,
+ presentation-style [17] IMPLICIT Style-Identifier OPTIONAL,
+ layout-style [19] IMPLICIT Style-Identifier OPTIONAL,
+ application-comments [25] IMPLICIT OCTET STRING OPTIONAL
+}
+
+Enciphered-Link-Descriptor ::= SEQUENCE {
+ protected-part-identifier Protected-Part-Identifier,
+ enciphered-information OCTET STRING
+}
+
+END
+
+-- Generated by Asnp, the ASN.1 pretty-printer of France Telecom R&D
+
diff --git a/lib/asn1/test/asn1_SUITE_data/x420/Location-Expressions.asn b/lib/asn1/test/asn1_SUITE_data/x420/Location-Expressions.asn
new file mode 100644
index 0000000000..5de6491621
--- /dev/null
+++ b/lib/asn1/test/asn1_SUITE_data/x420/Location-Expressions.asn
@@ -0,0 +1,338 @@
+-- Module Location-Expressions (T.422:08/1995)
+
+Location-Expressions {2 8 1 12 0} DEFINITIONS IMPLICIT TAGS ::=
+BEGIN
+
+EXPORTS Location-Expression, Basic-Location-Expression, Constituent-Locator;
+
+IMPORTS
+ Object-or-Class-Identifier, Content-Portion-Identifier, Style-Identifier
+ FROM Identifiers-and-Expressions {2 8 1 5 7}
+ -- see ITU-T Rec. T.415 | ISO/IEC 8613-5
+ Layout-Class-Descriptor, Layout-Object-Descriptor
+ FROM Layout-Descriptors {2 8 1 5 8}
+ -- see ITU-T Rec. T.415 | ISO/IEC 8613-5
+ Logical-Class-Descriptor, Logical-Object-Descriptor
+ FROM Logical-Descriptors {2 8 1 5 9}
+ -- see ITU-T Rec. T.415 | ISO/IEC 8613-5
+ Presentation-Style-Descriptor, Layout-Style-Descriptor
+ FROM Style-Descriptors {2 8 1 5 10}
+ -- see ITU-T Rec. T.415 | ISO/IEC 8613-5
+ Text-Unit
+ FROM Text-Units {2 8 1 5 12}
+ -- see ITU-T Rec. T.415 | ISO/IEC 8613-5
+ Subprofile-Descriptor, Subprofile-Identifier
+ FROM Subprofiles {2 8 1 12 2}
+ -- see 9.3
+ Link-Class-Descriptor, Link-Descriptor, Link-or-Link-Class-Identifier
+ FROM Link-Descriptors {2 8 1 14 3};
+
+-- see ITU-T Rec. T.424 | ISO/IEC 8613-14
+-- Location expression
+Location-Expression ::= CHOICE {
+ basic [0] Basic-Location-Expression,
+ composite [1] Composite-Location-Expression
+}
+
+Composite-Location-Expression ::= CHOICE {
+ complement [0] Location-Expression,
+ intersection [1] SEQUENCE OF Location-Expression,
+ union [2] SEQUENCE OF Location-Expression
+}
+
+Basic-Location-Expression ::= CHOICE {
+ region [0] Region-Locator,
+ subtree [1] Subtree-Locator,
+ constituent [2] Constituent-Locator
+}
+
+Region-Locator ::= SEQUENCE {
+ start [0] Start-End-Object-Locator,
+ end [1] Start-End-Object-Locator
+}
+
+Start-End-Object-Locator ::= SEQUENCE {
+ object [0] Object-Locator,
+ not-included [1] BOOLEAN DEFAULT TRUE
+}
+
+Subtree-Locator ::= Object-Locator
+
+Constituent-Locator ::= CHOICE {
+ documentProfile [0] NULL,
+ subprofile [1] Subprofile-Locator,
+ component [2] Component-Locator,
+ contentPortion [3] Content-Portion-Locator,
+ style [4] Style-Locator,
+ link-or-link-class [5] Link-or-Link-Class-Locator,
+ constituent-of-type [6] Constituent-Type
+}
+
+Constituent-Type ::= ENUMERATED {
+ layout-object-class(1), layout-object(2), content-portion(3),
+ logical-object-class(5), logical-object(6), presentation-style(7),
+ layout-style(8), sealed-doc-prof-descriptor(9),
+ enciphered-doc-prof-descriptor(10), preenciphered-bodypart-descriptor(11),
+ postenciphered-bodypart-descriptor(12), link-class(13), link(14),
+ enciphered-link-descriptor(15), subprofile(16)}
+
+-- Subprofile
+Subprofile-Locator ::= CHOICE {
+ subprofile [0] Subprofile-Identifier,
+ subprofile-of [1] Subprofile-of-argument,
+ subprofile-with [2] Subprofile-with-argument
+}
+
+Subprofile-of-argument ::= Constituent-Locator
+
+Subprofile-with-argument ::=
+ AttributeValue-Subprofile-Specification -- The "attribute" and "value"
+
+-- arguments are grouped together
+-- Component locator
+Component-Locator ::= CHOICE {
+ objectClass [0] Object-Class-Locator,
+ object [1] Object-Locator
+}
+
+Object-Class-Locator ::= CHOICE {
+ objectClass [0] Object-or-Class-Identifier,
+ object-class-of [1] Object-Class-of-argument,
+ object-class-with [2] Object-Class-with-argument
+}
+
+Object-Class-of-argument ::= Object-Locator
+
+Object-Class-with-argument ::= SEQUENCE {
+ attributeValueObject [0] AttributeValue-Class-Specification, -- The "attribute" and "value"
+
+ -- arguments are grouped together
+ defaulting [1] BOOLEAN DEFAULT FALSE
+}
+
+-- Object locator
+Object-Locator ::= CHOICE {
+ object [0] Object-or-Class-Identifier,
+ subord [1] Subord-argument,
+ object-with [2] Object-with-argument
+}
+
+Subord-argument ::= SEQUENCE {
+ object [0] Object-Locator,
+ counters [1] CountersType OPTIONAL
+}
+
+Object-with-argument ::= SEQUENCE {
+ attributeValueObject [0] AttributeValue-Object-Specification, -- The "attribute" and "value"
+
+ -- arguments are grouped together
+ object [1] Object-Locator OPTIONAL,
+ counters [2] CountersType OPTIONAL,
+ not-defaulting [3] BOOLEAN DEFAULT FALSE
+}
+
+-- Links
+Link-or-Link-Class-Locator ::= CHOICE {
+ linkClass [0] Link-Class-Locator,
+ link [1] Link-Locator
+}
+
+Link-Class-Locator ::= CHOICE {
+ link [0] Link-or-Link-Class-Identifier,
+ link-class-of [1] Link-Class-of-argument,
+ link-class-with [2] Link-Class-with-arguments
+}
+
+Link-Class-of-argument ::= Link-Locator
+
+Link-Class-with-arguments ::=
+ AttributeValue-Link-Class-Specification -- The "attribute" and "value"
+
+-- arguments are grouped together
+Link-Locator ::= CHOICE {
+ link [0] Link-or-Link-Class-Identifier,
+ link-with [1] Link-with-arguments
+}
+
+Link-with-arguments ::= SEQUENCE {
+ attributeValueLink [0] AttributeValue-Link-Specification, -- The "attribute" and "value"
+
+ -- arguments are grouped together
+ not-defaulting [1] BOOLEAN DEFAULT FALSE
+}
+
+-- Content portion locator
+Content-Portion-Locator ::= CHOICE {
+ contentPortion [0] Content-Portion-Identifier,
+ assoc [1] Assoc-argument,
+ content-with [2] Content-with-argument
+}
+
+Assoc-argument ::= SEQUENCE {
+ component [0] Component-Locator,
+ counters [1] CountersType OPTIONAL
+}
+
+Content-with-argument ::= SEQUENCE {
+ attributeValueContent [0] AttributeValue-Content-Specification, -- The "attribute" and "value"
+
+ -- arguments are grouped together
+ component [1] Component-Locator OPTIONAL,
+ counters [2] CountersType OPTIONAL,
+ not-defaulting [3] BOOLEAN DEFAULT FALSE
+}
+
+-- Styles
+Style-Locator ::= CHOICE {
+ style [0] Style-Identifier,
+ layout-style-of [1] Layout-Style-of-argument,
+ presentation-style-of [2] Presentation-Style-of-argument,
+ layout-style-with [3] Layout-Style-with-argument,
+ presentation-style-with [4] Presentation-Style-with-argument
+}
+
+Layout-Style-of-argument ::= Component-Locator
+
+Presentation-Style-of-argument ::= Component-Locator
+
+Layout-Style-with-argument ::= SEQUENCE {
+ attributeValueLayoutStyle [0] AttributeValue-LayoutStyle-Specification, -- The "attribute" and
+
+ -- "value" arguments are grouped together
+ not-defaulting [1] BOOLEAN DEFAULT FALSE
+}
+
+Presentation-Style-with-argument ::= SEQUENCE {
+ attributeValuePresentationStyle
+ [0] AttributeValue-PresentationStyle-Specification,
+ -- The "attribute" and
+ -- "value" arguments are grouped together
+ not-defaulting [1] BOOLEAN DEFAULT FALSE
+}
+
+-- Counters
+CountersType ::= SEQUENCE {
+ start [0] INTEGER OPTIONAL,
+ end [1] INTEGER OPTIONAL
+}
+
+-- Attribute-Value specifications
+-- Classes
+AttributeValue-Class-Specification ::= CHOICE {
+ value [0] Simple-AttributeValue-Class-Specification,
+ range
+ [1] SEQUENCE {start
+ [0] Simple-AttributeValue-Class-Specification OPTIONAL,
+ end
+ [1] Simple-AttributeValue-Class-Specification OPTIONAL
+ }
+}
+
+Simple-AttributeValue-Class-Specification ::= CHOICE {
+ layout [0] Layout-Class-Descriptor,
+ logical [1] Logical-Class-Descriptor
+}
+
+-- Objects
+AttributeValue-Object-Specification ::= CHOICE {
+ value [0] Simple-AttributeValue-Object-Specification,
+ range
+ [1] SEQUENCE {start
+ [0] Simple-AttributeValue-Object-Specification OPTIONAL,
+ end
+ [1] Simple-AttributeValue-Object-Specification OPTIONAL
+ }
+}
+
+Simple-AttributeValue-Object-Specification ::= CHOICE {
+ layout [0] Layout-Object-Descriptor,
+ logical [1] Logical-Object-Descriptor
+}
+
+-- Link classes
+AttributeValue-Link-Class-Specification ::= CHOICE {
+ value [0] Simple-AttributeValue-Link-Class-Specification,
+ range
+ [1] SEQUENCE {start
+ [0] Simple-AttributeValue-Link-Class-Specification
+ OPTIONAL,
+ end
+ [1] Simple-AttributeValue-Link-Class-Specification
+ OPTIONAL}
+}
+
+Simple-AttributeValue-Link-Class-Specification ::= Link-Class-Descriptor
+
+-- Links
+AttributeValue-Link-Specification ::= CHOICE {
+ value [0] Simple-AttributeValue-Link-Specification,
+ range
+ [1] SEQUENCE {start
+ [0] Simple-AttributeValue-Link-Specification OPTIONAL,
+ end
+ [1] Simple-AttributeValue-Link-Specification OPTIONAL
+ }
+}
+
+Simple-AttributeValue-Link-Specification ::= Link-Descriptor
+
+-- Contents
+AttributeValue-Content-Specification ::= CHOICE {
+ value [0] Simple-AttributeValue-Content-Specification,
+ range
+ [1] SEQUENCE {start
+ [0] Simple-AttributeValue-Content-Specification OPTIONAL,
+ end
+ [1] Simple-AttributeValue-Content-Specification OPTIONAL
+ }
+}
+
+Simple-AttributeValue-Content-Specification ::= Text-Unit
+
+-- Layout Styles
+AttributeValue-LayoutStyle-Specification ::= CHOICE {
+ value [0] Simple-AttributeValue-LayoutStyle-Specification,
+ range
+ [1] SEQUENCE {start
+ [0] Simple-AttributeValue-LayoutStyle-Specification
+ OPTIONAL,
+ end
+ [1] Simple-AttributeValue-LayoutStyle-Specification
+ OPTIONAL}
+}
+
+Simple-AttributeValue-LayoutStyle-Specification ::= Layout-Style-Descriptor
+
+-- Presentation Styles
+AttributeValue-PresentationStyle-Specification ::= CHOICE {
+ value [0] Simple-AttributeValue-PresentationStyle-Specification,
+ range
+ [1] SEQUENCE {start
+ [0] Simple-AttributeValue-PresentationStyle-Specification
+ OPTIONAL,
+ end
+ [1] Simple-AttributeValue-PresentationStyle-Specification
+ OPTIONAL}
+}
+
+Simple-AttributeValue-PresentationStyle-Specification ::=
+ Presentation-Style-Descriptor
+
+-- Subprofiles
+AttributeValue-Subprofile-Specification ::= CHOICE {
+ value [0] Simple-AttributeValue-Subprofile-Specification,
+ range
+ [1] SEQUENCE {start
+ [0] Simple-AttributeValue-Subprofile-Specification
+ OPTIONAL,
+ end
+ [1] Simple-AttributeValue-Subprofile-Specification
+ OPTIONAL}
+}
+
+Simple-AttributeValue-Subprofile-Specification ::= Subprofile-Descriptor
+
+END
+
+-- Generated by Asnp, the ASN.1 pretty-printer of France Telecom R&D
+
diff --git a/lib/asn1/test/asn1_SUITE_data/x420/Logical-Descriptors.asn b/lib/asn1/test/asn1_SUITE_data/x420/Logical-Descriptors.asn
new file mode 100644
index 0000000000..fab36bf12a
--- /dev/null
+++ b/lib/asn1/test/asn1_SUITE_data/x420/Logical-Descriptors.asn
@@ -0,0 +1,95 @@
+-- Module Logical-Descriptors (T.415:03/1993)
+
+Logical-Descriptors {2 8 1 5 9} DEFINITIONS ::=
+BEGIN
+
+EXPORTS
+ Logical-Object-Descriptor, Logical-Class-Descriptor, Logical-Object-Type,
+ Protection;
+
+IMPORTS
+ Object-or-Class-Identifier, Style-Identifier, Resource-Name,
+ Construction-Expression, String-Expression
+ FROM Identifiers-and-Expressions -- see 7.8
+
+ Comment-String, Binding-Pair, Enciphered, Sealed
+ FROM Layout-Descriptors -- see 7.9
+
+ Presentation-Attributes
+ FROM Style-Descriptors -- see 7.11
+
+ Default-Value-Lists-Logical
+ FROM Default-Value-Lists -- see 7.12
+
+ Temporal-Relations
+ FROM Temporal-Relationships {2 8 1 14 0};
+
+-- See ITU-T Rec. T.424 | ISO/IEC 8613-14
+Logical-Object-Descriptor ::= SEQUENCE {
+ object-type Logical-Object-Type OPTIONAL,
+ descriptor-body Logical-Object-Descriptor-Body OPTIONAL
+}
+
+Logical-Object-Type ::= INTEGER {
+ document-logical-root(0), composite-logical-object(1),
+ basic-logical-object(2)}
+
+Logical-Object-Descriptor-Body ::= SET {
+ object-identifier Object-or-Class-Identifier OPTIONAL,
+ subordinates [0] IMPLICIT SEQUENCE OF NumericString OPTIONAL,
+ content-portions [1] IMPLICIT SEQUENCE OF NumericString OPTIONAL,
+ object-class [2] IMPLICIT Object-or-Class-Identifier OPTIONAL,
+ presentation-attributes [6] IMPLICIT Presentation-Attributes OPTIONAL,
+ -- only for use for the attribute content-architecture-class;
+ -- the content architecture specific attributes can only be referenced by
+ -- use of presentation style
+ default-value-lists [7] IMPLICIT Default-Value-Lists-Logical OPTIONAL,
+ user-readable-comments [8] IMPLICIT Comment-String OPTIONAL,
+ bindings [9] IMPLICIT SET OF Binding-Pair OPTIONAL,
+ content-generator [10] IMPLICIT String-Expression OPTIONAL,
+ user-visible-name [14] IMPLICIT Comment-String OPTIONAL,
+ presentation-style [17] IMPLICIT Style-Identifier OPTIONAL,
+ layout-style [19] IMPLICIT Style-Identifier OPTIONAL,
+ protection [20] IMPLICIT Protection OPTIONAL,
+ application-comments [25] IMPLICIT OCTET STRING OPTIONAL,
+ primary [27] IMPLICIT Object-or-Class-Identifier OPTIONAL,
+ alternative [28] IMPLICIT Object-or-Class-Identifier OPTIONAL,
+ enciphered [34] IMPLICIT Enciphered OPTIONAL,
+ sealed [35] IMPLICIT Sealed OPTIONAL,
+ temporal-relations [36] IMPLICIT Temporal-Relations OPTIONAL
+}
+
+Logical-Class-Descriptor ::= SEQUENCE {
+ object-type Logical-Object-Type,
+ descriptor-body Logical-Class-Descriptor-Body
+}
+
+Logical-Class-Descriptor-Body ::= SET {
+ object-class-identifier Object-or-Class-Identifier,
+ generator-for-subordinates [0] Construction-Expression OPTIONAL,
+ content-portions [1] IMPLICIT SEQUENCE OF NumericString OPTIONAL,
+ presentation-attributes [6] IMPLICIT Presentation-Attributes OPTIONAL,
+ -- only for use for the attribute content-architecture-class;
+ -- the content architecture specific attributes can only be referenced by
+ -- use of presentation style
+ default-value-lists [7] IMPLICIT Default-Value-Lists-Logical OPTIONAL,
+ user-readable-comments [8] IMPLICIT Comment-String OPTIONAL,
+ bindings [9] IMPLICIT SET OF Binding-Pair OPTIONAL,
+ content-generator [10] IMPLICIT String-Expression OPTIONAL,
+ user-visible-name [14] IMPLICIT Comment-String OPTIONAL,
+ presentation-style [17] IMPLICIT Style-Identifier OPTIONAL,
+ layout-style [19] IMPLICIT Style-Identifier OPTIONAL,
+ protection [20] IMPLICIT Protection OPTIONAL,
+ resource [24] IMPLICIT Resource-Name OPTIONAL,
+ application-comments [25] IMPLICIT OCTET STRING OPTIONAL,
+ enciphered [34] IMPLICIT Enciphered OPTIONAL,
+ sealed [35] IMPLICIT Sealed OPTIONAL,
+ temporal-relations [36] IMPLICIT Temporal-Relations OPTIONAL
+}
+
+Protection ::= INTEGER {unprotected(0), protected(1)}
+
+END
+
+-- Generated by Asnp, the ASN.1 pretty-printer of France Telecom R&D
+
diff --git a/lib/asn1/test/asn1_SUITE_data/x420/MHSObjectIdentifiers.asn b/lib/asn1/test/asn1_SUITE_data/x420/MHSObjectIdentifiers.asn
new file mode 100644
index 0000000000..187c3c8ad4
--- /dev/null
+++ b/lib/asn1/test/asn1_SUITE_data/x420/MHSObjectIdentifiers.asn
@@ -0,0 +1,187 @@
+-- Module MHSObjectIdentifiers (X.402:06/1999)
+MHSObjectIdentifiers {joint-iso-itu-t mhs(6) arch(5) modules(0)
+ object-identifiers(0) version-1999(1)} DEFINITIONS IMPLICIT TAGS ::=
+BEGIN
+
+-- Prologue
+-- Exports everything.
+IMPORTS -- nothing -- ;
+
+ID ::= OBJECT IDENTIFIER
+
+-- MHS Aspects
+id-mhs-protocols ID ::= {joint-iso-itu-t mhs(6) protocols(0)}
+
+-- MHS Application Contexts and Protocols
+-- See ITU-T Rec. X.419 | ISO/IEC 10021-6.
+id-ipms ID ::=
+ {joint-iso-itu-t mhs(6) ipms(1)}
+
+-- Interpersonal Messaging
+-- See ITU-T Rec. X.420 | ISO/IEC 10021-7.
+-- Value {joint-iso-itu-t mhs(6) 2} is no longer defined
+id-mts ID ::=
+ {joint-iso-itu-t mhs(6) mts(3)}
+
+-- Message Transfer System
+-- See ITU-T Rec. X.411 | ISO/IEC 10021-4.
+id-ms ID ::=
+ {joint-iso-itu-t mhs(6) ms(4)}
+
+-- Message Store
+-- See ITU-T Rec. X.413 | ISO/IEC 10021-5.
+id-arch ID ::=
+ {joint-iso-itu-t mhs(6) arch(5)}
+
+-- Overall Architecture
+-- See this Specification.
+id-group ID ::=
+ {joint-iso-itu-t mhs(6) group(6)}
+
+-- Reserved.
+id-edims ID ::= {joint-iso-itu-t mhs(6) edims(7)}
+
+-- EDI Messaging
+-- See ITU-T Rec. X.435 | ISO/IEC 10021-9.
+id-management ID ::=
+ {joint-iso-itu-t mhs(6) management(9)}
+
+-- MHS Management
+-- See ITU-T Recs. X.460 - X.467 | ISO/IEC 11588.
+id-routing ID ::=
+ {joint-iso-itu-t mhs(6) routing(10)}
+
+-- MHS Routing
+-- See ITU-T Rec. X.412 | ISO/IEC 10021-10.
+-- Categories
+id-mod ID ::=
+ {id-arch 0} -- modules; not definitive
+
+id-oc ID ::= {id-arch 1} -- object classes
+
+id-at ID ::= {id-arch 2} -- attribute types
+
+-- Value {id-arch 3} is no longer defined
+id-mr ID ::=
+ {id-arch 4} -- matching rules
+
+id-con ID ::= {id-arch 5} -- contexts
+
+id-san ID ::= {id-arch 6} -- certificate subject alternative names
+
+-- Modules
+id-object-identifiers ID ::= {id-mod 0} -- not definitive
+
+id-directory-objects-and-attributes ID ::= {id-mod 1} -- not definitive
+
+-- Object classes
+id-oc-mhs-distribution-list ID ::= {id-oc 0}
+
+id-oc-mhs-message-store ID ::= {id-oc 1}
+
+id-oc-mhs-message-transfer-agent ID ::= {id-oc 2}
+
+id-oc-mhs-user ID ::= {id-oc 3}
+
+id-oc-mhs-user-agent ID ::= {id-oc 4}
+
+-- Attributes
+id-at-mhs-maximum-content-length ID ::= {id-at 0}
+
+id-at-mhs-deliverable-content-types ID ::= {id-at 1}
+
+id-at-mhs-exclusively-acceptable-eits ID ::= {id-at 2}
+
+id-at-mhs-dl-members ID ::= {id-at 3}
+
+id-at-mhs-dl-submit-permissions ID ::= {id-at 4}
+
+id-at-mhs-message-store-dn ID ::= {id-at 5}
+
+id-at-mhs-or-addresses ID ::= {id-at 6}
+
+-- Value {id-at 7} is no longer defined
+id-at-mhs-supported-automatic-actions ID ::=
+ {id-at 8}
+
+id-at-mhs-supported-content-types ID ::= {id-at 9}
+
+id-at-mhs-supported-attributes ID ::= {id-at 10}
+
+id-at-mhs-supported-matching-rules ID ::= {id-at 11}
+
+id-at-mhs-dl-archive-service ID ::= {id-at 12}
+
+id-at-mhs-dl-policy ID ::= {id-at 13}
+
+id-at-mhs-dl-related-lists ID ::= {id-at 14}
+
+id-at-mhs-dl-subscription-service ID ::= {id-at 15}
+
+id-at-mhs-or-addresses-with-capabilities ID ::= {id-at 16}
+
+id-at-mhs-acceptable-eits ID ::= {id-at 17}
+
+id-at-mhs-unacceptable-eits ID ::= {id-at 18}
+
+id-at-mhs-deliverable-classes ID ::= {id-at 19}
+
+id-at-encrypted-mhs-maximum-content-length ID ::= {id-at 0 2}
+
+id-at-encrypted-mhs-deliverable-content-types ID ::= {id-at 1 2}
+
+id-at-encrypted-mhs-exclusively-acceptable-eits ID ::= {id-at 2 2}
+
+id-at-encrypted-mhs-dl-members ID ::= {id-at 3 2}
+
+id-at-encrypted-mhs-dl-submit-permissions ID ::= {id-at 4 2}
+
+id-at-encrypted-mhs-message-store-dn ID ::= {id-at 5 2}
+
+id-at-encrypted-mhs-or-addresses ID ::= {id-at 6 2}
+
+id-at-encrypted-mhs-supported-automatic-actions ID ::= {id-at 8 2}
+
+id-at-encrypted-mhs-supported-content-types ID ::= {id-at 9 2}
+
+id-at-encrypted-mhs-supported-attributes ID ::= {id-at 10 2}
+
+id-at-encrypted-mhs-supported-matching-rules ID ::= {id-at 11 2}
+
+id-at-encrypted-mhs-dl-archive-service ID ::= {id-at 12 2}
+
+id-at-encrypted-mhs-dl-policy ID ::= {id-at 13 2}
+
+id-at-encrypted-mhs-dl-related-lists ID ::= {id-at 14 2}
+
+id-at-encrypted-mhs-dl-subscription-service ID ::= {id-at 15 2}
+
+id-at-encrypted-mhs-or-addresses-with-capabilities ID ::= {id-at 16 2}
+
+id-at-encrypted-mhs-acceptable-eits ID ::= {id-at 17 2}
+
+id-at-encrypted-mhs-unacceptable-eits ID ::= {id-at 18 2}
+
+id-at-encrypted-mhs-deliverable-classes ID ::= {id-at 19 2}
+
+-- Matching Rules
+id-mr-orname-exact-match ID ::= {id-mr 0}
+
+id-mr-address-capabilities-match ID ::= {id-mr 1}
+
+id-mr-capability-match ID ::= {id-mr 2}
+
+-- Contexts
+id-con-dl-administrator-annotation ID ::= {id-con 0}
+
+id-con-dl-nested-dl ID ::= {id-con 1}
+
+id-con-dl-reset-originator ID ::= {id-con 2}
+
+-- Certificate subject alternative names
+id-san-mta-name ID ::= {id-san 0}
+
+END -- of MHSObjectIdentifiers
+
+-- Generated by Asnp, the ASN.1 pretty-printer of France Telecom R&D
+
diff --git a/lib/asn1/test/asn1_SUITE_data/x420/MHSProtocolObjectIdentifiers.asn b/lib/asn1/test/asn1_SUITE_data/x420/MHSProtocolObjectIdentifiers.asn
new file mode 100644
index 0000000000..40f53b9458
--- /dev/null
+++ b/lib/asn1/test/asn1_SUITE_data/x420/MHSProtocolObjectIdentifiers.asn
@@ -0,0 +1,112 @@
+-- Module MHSProtocolObjectIdentifiers (X.419:06/1999)
+
+MHSProtocolObjectIdentifiers {joint-iso-itu-t mhs(6) protocols(0) modules(0)
+ object-identifiers(0) version-1994(0)} DEFINITIONS IMPLICIT TAGS ::=
+BEGIN
+
+-- Prologue
+-- Exports Everything
+IMPORTS -- nothing -- ;
+
+ID ::= OBJECT IDENTIFIER
+
+-- MHS Protocols
+id-mhs-protocols ID ::=
+ {joint-iso-itu-t mhs(6) protocols(0)} -- not definitive
+
+-- Categories of Object Identifiers
+id-mod ID ::=
+ {id-mhs-protocols 0} -- modules
+
+id-ac ID ::= {id-mhs-protocols 1} -- application contexts
+
+id-as ID ::= {id-mhs-protocols 2} -- abstract syntaxes
+
+id-ase ID ::= {id-mhs-protocols 3} -- application service elements (obsolete)
+
+-- Modules
+id-mod-object-identifiers ID ::= {id-mod 0} -- not definitive
+
+id-mod-mts-access-protocol ID ::= {id-mod 1} -- not definitive
+
+id-mod-ms-access-protocol ID ::= {id-mod 2} -- not definitive
+
+id-mod-mts-transfer-protocol ID ::= {id-mod 3} -- not definitive
+
+-- Application Contexts
+-- MTS Access Protocol
+id-ac-mts-access-88 ID ::=
+ {id-ac 0}
+
+id-ac-mts-forced-access-88 ID ::= {id-ac 1}
+
+id-ac-mts-reliable-access-88 ID ::= {id-ac 2}
+
+id-ac-mts-forced-reliable-access-88 ID ::= {id-ac 3}
+
+id-ac-mts-access-94 ID ::= {id-ac 7}
+
+id-ac-mts-forced-access-94 ID ::= {id-ac 8}
+
+id-ac-mts-reliable-access-94 ID ::= {id-ac 9}
+
+id-ac-mts-forced-reliable-access-94 ID ::= {id-ac 10}
+
+-- MS Access Protocol
+id-ac-ms-access-88 ID ::= {id-ac 4}
+
+id-ac-ms-reliable-access-88 ID ::= {id-ac 5}
+
+id-ac-ms-access-94 ID ::= {id-ac 11}
+
+id-ac-ms-reliable-access-94 ID ::= {id-ac 12}
+
+-- MTS Transfer Protocol
+id-ac-mts-transfer ID ::= {id-ac 6}
+
+-- Abstract Syntaxes
+id-as-msse ID ::= {id-as 1}
+
+id-as-mdse-88 ID ::= {id-as 2}
+
+id-as-mrse-88 ID ::= {id-as 5}
+
+id-as-mase-88 ID ::= {id-as 6}
+
+id-as-mtse ID ::= {id-as 7}
+
+id-as-mts-rtse ID ::= {id-as 8}
+
+id-as-ms-88 ID ::= {id-as 9}
+
+id-as-ms-rtse ID ::= {id-as 10}
+
+id-as-mts ID ::= {id-as 11}
+
+id-as-mta-rtse ID ::= {id-as 12}
+
+id-as-ms-msse ID ::= {id-as 13}
+
+id-as-mdse-94 ID ::= {id-as 14}
+
+id-as-mrse-94 ID ::= {id-as 15}
+
+id-as-mase-94 ID ::= {id-as 16}
+
+id-as-ms-94 ID ::= {id-as 17}
+
+-- Application Service Elements
+id-ase-msse ID ::= {id-ase 0}
+
+id-ase-mdse ID ::= {id-ase 1}
+
+id-ase-mrse ID ::= {id-ase 2}
+
+id-ase-mase ID ::= {id-ase 3}
+
+id-ase-mtse ID ::= {id-ase 4}
+
+END --of MHSProtocolObjectIdentifiers
+
+-- Generated by Asnp, the ASN.1 pretty-printer of France Telecom R&D
+
diff --git a/lib/asn1/test/asn1_SUITE_data/x420/MSAbstractService.asn b/lib/asn1/test/asn1_SUITE_data/x420/MSAbstractService.asn
new file mode 100644
index 0000000000..052b3b2041
--- /dev/null
+++ b/lib/asn1/test/asn1_SUITE_data/x420/MSAbstractService.asn
@@ -0,0 +1,1085 @@
+-- Module MSAbstractService (X.413:06/1999)
+MSAbstractService {joint-iso-itu-t mhs(6) ms(4) modules(0) abstract-service(1)
+ version-1999(1)} DEFINITIONS ::=
+BEGIN
+
+-- Prologue
+-- Exports everything
+IMPORTS
+ -- MTS information object classes
+ operationObject1, ABSTRACT-ERROR, ABSTRACT-OPERATION, EXTENSION, MHS-OBJECT,
+ PORT,
+ -- MTS objects and ports
+ administration, delivery, mts-user,
+ submission,
+ -- MTS abstract-operations and abstract-errors
+ cancel-deferred-delivery, element-of-service-not-subscribed,
+ inconsistent-request, new-credentials-unacceptable,
+ old-credentials-incorrectly-specified, originator-invalid,
+ recipient-improperly-specified, remote-bind-error, security-error,
+ submission-control, submission-control-violated,
+ unsupported-critical-function,
+ -- MTS abstract-service data-types
+ CertificateSelectors, Credentials, InitiatorCredentials,
+ MessageSubmissionArgument, MessageSubmissionResult, MessageToken,
+ ORAddressAndOrDirectoryName, ProbeSubmissionArgument,
+ ProbeSubmissionResult, ResponderCredentials, SecurityContext, SecurityLabel
+ FROM MTSAbstractService {joint-iso-itu-t mhs(6) mts(3) modules(0)
+ mts-abstract-service(1) version-1999(1)}
+ -- MTS abstract-service 1988 ports
+ administration-88
+ --==
+ FROM MTSAbstractService88 {joint-iso-itu-t mhs(6) mts(3) modules(0)
+ mts-abstract-service(1) version-1988(1988)}
+ -- MTS abstract-service upper bounds
+ ub-content-types, ub-encoded-information-types, ub-labels-and-redirections
+ --==
+ FROM MTSUpperBounds {joint-iso-itu-t mhs(6) mts(3) modules(0)
+ upper-bounds(3) version-1999(1)}
+ -- MS X413ATTRIBUTE table
+ AttributeTable
+ --==
+ FROM MSGeneralAttributeTypes {joint-iso-itu-t mhs(6) ms(4) modules(0)
+ general-attribute-types(2) version-1999(1)}
+ -- MS matching rule table
+ MatchingRuleTable
+ --==
+ FROM MSMatchingRules {joint-iso-itu-t mhs(6) ms(4) modules(0)
+ general-matching-rules(5) version-1999(1)}
+ -- MS auto-action-table and auto-action-error table
+ AutoActionTable, AutoActionErrorTable
+ --==
+ FROM MSGeneralAutoActionTypes {joint-iso-itu-t mhs(6) ms(4) modules(0)
+ general-auto-action-types(3) version-1994(0)}
+ -- MS object-identifiers
+ id-cp-ms-connection, id-crt-ms-access-88, id-crt-ms-access-94,
+ id-ext-modify-capability, id-ext-modify-retrieval-status-capability,
+ id-ext-originator-token, id-ext-originator-certificate-selectors-override,
+ id-ext-protected-change-credentials,
+ id-ext-protected-change-credentials-capability, id-ot-ms, id-ot-ms-user,
+ id-pt-retrieval-88, id-pt-retrieval-94, id-pt-ms-submission
+ --==
+ FROM MSObjectIdentifiers {joint-iso-itu-t mhs(6) ms(4) modules(0)
+ object-identifiers(0) version-1999(1)}
+ -- MS Access abstract-operation and error codes
+ err-attribute-error, err-auto-action-request-error, err-ms-extension-error,
+ err-delete-error, err-entry-class-error, err-fetch-restriction-error,
+ err-invalid-parameters-error, err-message-group-error, err-modify-error,
+ err-range-error, err-security-error, err-sequence-number-error,
+ err-service-error, err-register-ms-error, op-alert, op-delete, op-fetch,
+ op-list, op-modify, op-ms-message-submission, op-ms-probe-submission,
+ op-register-ms, op-summarize
+ --==
+ FROM MSAccessProtocol {joint-iso-itu-t mhs(6) protocols(0) modules(0)
+ ms-access-protocol(2) version-1999(1)}
+ -- MS abstract-service upper bounds
+ ub-attributes-supported, ub-attribute-values, ub-auto-action-errors,
+ ub-auto-actions, ub-auto-registrations, ub-default-registrations,
+ ub-entry-classes, ub-error-reasons, ub-extensions, ub-group-depth,
+ ub-group-descriptor-length, ub-group-part-length, ub-matching-rules,
+ ub-message-groups, ub-messages, ub-modifications, ub-per-entry,
+ ub-per-auto-action, ub-service-information-length, ub-summaries,
+ ub-supplementary-info-length, ub-ua-registration-identifier-length,
+ ub-ua-registrations, ub-restrictions
+ --==
+ FROM MSUpperBounds {joint-iso-itu-t mhs(6) ms(4) modules(0) upper-bounds(4)
+ version-1994(0)}
+ -- MATCHING-RULE information object class
+ MATCHING-RULE
+ --==
+ FROM InformationFramework
+
+ -- Remote Operations
+ CONTRACT, CONNECTION-PACKAGE
+ --==
+ FROM Remote-Operations-Information-Objects {joint-iso-itu-t
+ remote-operations(4) informationObjects(5) version1(0)}
+ emptyUnbind
+ FROM Remote-Operations-Useful-Definitions {joint-iso-itu-t
+ remote-operations(4) useful-definitions(7) version1(0)};
+
+-- MS Abstract Objects
+ms MHS-OBJECT ::= {
+ IS {mts-user}
+ RESPONDS {ms-access-contract-88 | ms-access-contract-94}
+ ID id-ot-ms
+}
+
+ms-user MHS-OBJECT ::= {
+ INITIATES {ms-access-contract-88 | ms-access-contract-94}
+ ID id-ot-ms-user
+}
+
+-- Contracts
+ms-access-contract-94 CONTRACT ::= {
+ CONNECTION ms-connect
+ INITIATOR CONSUMER OF {retrieval | ms-submission | administration}
+ ID id-crt-ms-access-94
+}
+
+ms-access-contract-88 CONTRACT ::= {
+ CONNECTION ms-connect -- with all 1994 extensions omitted
+ INITIATOR CONSUMER OF {retrieval-88 | submission | administration-88}
+ ID id-crt-ms-access-88
+}
+
+-- Connection-package
+ms-connect CONNECTION-PACKAGE ::= {
+ BIND ms-bind
+ UNBIND ms-unbind
+ ID id-cp-ms-connection
+}
+
+-- MS Ports
+retrieval PORT ::= {
+ OPERATIONS {operationObject1, ...}
+ CONSUMER INVOKES
+ {summarize | list | fetch | delete | register-MS,
+ ... -- 1994 extension addition --, modify}
+ SUPPLIER INVOKES {alert}
+ ID id-pt-retrieval-94
+}
+
+retrieval-88 PORT ::= {
+ -- With all 1994 extensions to the abstract-operations absent
+ OPERATIONS {operationObject1, ...}
+ CONSUMER INVOKES {summarize | list | fetch | delete | register-MS}
+ SUPPLIER INVOKES {alert}
+ ID id-pt-retrieval-88
+}
+
+ms-submission PORT ::= {
+ OPERATIONS {operationObject1, ...}
+ CONSUMER INVOKES
+ {ms-message-submission | ms-probe-submission | ms-cancel-deferred-delivery}
+ SUPPLIER INVOKES {ms-submission-control}
+ ID id-pt-ms-submission
+}
+
+-- X413ATTRIBUTE information object class
+X413ATTRIBUTE ::= CLASS {
+ &id AttributeType UNIQUE,
+ &Type ,
+ &equalityMatch MATCHING-RULE OPTIONAL,
+ &substringsMatch MATCHING-RULE OPTIONAL,
+ &orderingMatch MATCHING-RULE OPTIONAL,
+ &numeration ENUMERATED {single-valued(0), multi-valued(1)},
+ -- 1994 extension
+ &OtherMatches MATCHING-RULE OPTIONAL
+}
+WITH SYNTAX {
+ WITH ATTRIBUTE-SYNTAX &Type,
+ [EQUALITY MATCHING-RULE &equalityMatch,]
+ [SUBSTRINGS MATCHING-RULE &substringsMatch,]
+ [ORDERING MATCHING-RULE &orderingMatch,]
+ [OTHER MATCHING-RULES &OtherMatches,]
+ NUMERATION &numeration,
+ ID &id
+}
+
+Attribute ::= SEQUENCE {
+ attribute-type X413ATTRIBUTE.&id({AttributeTable}),
+ attribute-values
+ SEQUENCE SIZE (1..ub-attribute-values) OF
+ X413ATTRIBUTE.&Type({AttributeTable}{@attribute-type})
+}
+
+AttributeType ::= OBJECT IDENTIFIER
+
+-- AUTO-ACTION information object class
+AUTO-ACTION ::= CLASS {
+ &id AutoActionType UNIQUE,
+ &RegistrationParameter OPTIONAL,
+ &Errors AUTO-ACTION-ERROR OPTIONAL
+}
+WITH SYNTAX {
+ [REGISTRATION PARAMETER IS &RegistrationParameter]
+ [ERRORS &Errors]
+ IDENTIFIED BY &id
+}
+
+AutoActionType ::= OBJECT IDENTIFIER
+
+AutoActionRegistration ::= SEQUENCE {
+ auto-action-type AUTO-ACTION.&id({AutoActionTable}),
+ registration-identifier [0] INTEGER(1..ub-per-auto-action) DEFAULT 1,
+ registration-parameter
+ [1] AUTO-ACTION.&RegistrationParameter
+ ({AutoActionTable}{@auto-action-type}) OPTIONAL
+}
+
+-- AUTO-ACTION-ERROR information object class
+AUTO-ACTION-ERROR ::=
+ ABSTRACT-ERROR
+
+AutoActionError ::= SET {
+ error-code [0] AUTO-ACTION-ERROR.&errorCode({AutoActionErrorTable}),
+ error-parameter
+ [1] AUTO-ACTION-ERROR.&ParameterType({AutoActionErrorTable}{@error-code})
+ OPTIONAL
+}
+
+-- MS-EXTENSION information object class
+MS-EXTENSION ::= TYPE-IDENTIFIER
+
+MSExtensionItem ::= INSTANCE OF MS-EXTENSION
+
+MSExtensions ::= SEQUENCE SIZE (1..ub-extensions) OF MSExtensionItem
+
+-- Common data-types related to the information model
+EntryClass ::= INTEGER {
+ delivery(0),
+ -- 1994 extensions
+ submission(1), draft(2), stored-message(3), delivery-log(4),
+ submission-log(5), message-log(6), auto-action-log(7)}(0..ub-entry-classes)
+
+EntryType ::= INTEGER {
+ delivered-message(0), delivered-report(1),
+ returned-content(2),
+ -- 1994 extensions
+ submitted-message(3), submitted-probe(4), draft-message(5),
+ auto-action-event(6)}
+
+SequenceNumber ::= INTEGER(0..ub-messages)
+
+RetrievalStatus ::= INTEGER {new(0), listed(1), processed(2)}
+
+MessageGroupName ::= SEQUENCE SIZE (1..ub-group-depth) OF GroupNamePart
+
+GroupNamePart ::= GeneralString(SIZE (1..ub-group-part-length))
+
+-- MS-bind abstract-operation
+ms-bind ABSTRACT-OPERATION ::= {
+ ARGUMENT MSBindArgument
+ RESULT MSBindResult
+ ERRORS {ms-bind-error}
+}
+
+MSBindArgument ::= SET {
+ initiator-name ORAddressAndOrDirectoryName,
+ initiator-credentials [2] InitiatorCredentials,
+ security-context [3] IMPLICIT SecurityContext OPTIONAL,
+ fetch-restrictions [4] Restrictions OPTIONAL -- default is none--,
+ ms-configuration-request [5] BOOLEAN DEFAULT FALSE,
+ -- 1994 extensions
+ ua-registration-identifier [6] RegistrationIdentifier OPTIONAL,
+ bind-extensions [7] MSExtensions OPTIONAL
+}
+
+Restrictions ::= SET {
+ allowed-content-types
+ [0] SET SIZE (1..ub-content-types) OF OBJECT IDENTIFIER OPTIONAL--default is no restriction--,
+ allowed-EITs [1] MS-EITs OPTIONAL --default is no restriction--,
+ maximum-attribute-length [2] INTEGER OPTIONAL --default is no restriction--
+}
+
+MS-EITs ::= SET SIZE (1..ub-encoded-information-types) OF MS-EIT
+
+MS-EIT ::= OBJECT IDENTIFIER
+
+RegistrationIdentifier ::=
+ PrintableString(SIZE (1..ub-ua-registration-identifier-length))
+
+MSBindResult ::= SET {
+ responder-credentials [2] ResponderCredentials,
+ available-auto-actions
+ [3] SET SIZE (1..ub-auto-actions) OF AUTO-ACTION.&id({AutoActionTable})
+ OPTIONAL,
+ available-attribute-types
+ [4] SET SIZE (1..ub-attributes-supported) OF
+ X413ATTRIBUTE.&id({AttributeTable}) OPTIONAL,
+ alert-indication [5] BOOLEAN DEFAULT FALSE,
+ content-types-supported
+ [6] SET SIZE (1..ub-content-types) OF OBJECT IDENTIFIER OPTIONAL,
+ -- 1994 extensions
+ entry-classes-supported
+ [7] SET SIZE (1..ub-entry-classes) OF EntryClass OPTIONAL,
+ matching-rules-supported
+ [8] SET SIZE (1..ub-matching-rules) OF OBJECT IDENTIFIER OPTIONAL,
+ bind-result-extensions [9] MSExtensions OPTIONAL,
+ message-group-depth [10] INTEGER(1..ub-group-depth) OPTIONAL,
+ auto-action-error-indication [11] AutoActionErrorIndication OPTIONAL,
+ unsupported-extensions
+ [12] SET SIZE (1..ub-extensions) OF OBJECT IDENTIFIER OPTIONAL,
+ ua-registration-id-unknown [13] BOOLEAN DEFAULT FALSE,
+ service-information
+ [14] GeneralString(SIZE (1..ub-service-information-length)) OPTIONAL
+}
+
+modify-capability MS-EXTENSION ::= {
+ NULL
+ IDENTIFIED BY id-ext-modify-capability
+}
+
+modify-retrieval-status-capability MS-EXTENSION ::= {
+ NULL
+ IDENTIFIED BY id-ext-modify-retrieval-status-capability
+}
+
+protected-change-credentials-capability MS-EXTENSION ::= {
+ ChangeCredentialsAlgorithms
+ IDENTIFIED BY id-ext-protected-change-credentials-capability
+}
+
+ChangeCredentialsAlgorithms ::= SET OF OBJECT IDENTIFIER
+
+AutoActionErrorIndication ::= CHOICE {
+ indication-only [0] NULL,
+ auto-action-log-entry [1] SequenceNumber
+}
+
+ms-bind-error ABSTRACT-ERROR ::= {
+ PARAMETER
+ CHOICE {unqualified-error BindProblem,
+ -- 1994 extension
+ qualified-error
+ SET {bind-problem [0] BindProblem,
+ supplementary-information
+ [1] GeneralString(SIZE (1..ub-supplementary-info-length))
+ OPTIONAL,
+ bind-extension-errors
+ [2] SET SIZE (1..ub-extensions) OF OBJECT IDENTIFIER
+ OPTIONAL}}
+}
+
+BindProblem ::= ENUMERATED {
+ authentication-error(0), unacceptable-security-context(1),
+ unable-to-establish-association(2), ... -- 1994 extension addition --,
+ bind-extension-problem(3), inadequate-association-confidentiality(4)
+}
+
+-- MS Unbind abstract-operation
+ms-unbind ABSTRACT-OPERATION ::= emptyUnbind
+
+-- Common data-types
+Range ::= CHOICE {
+ sequence-number-range [0] NumberRange,
+ creation-time-range [1] TimeRange
+}
+
+NumberRange ::= SEQUENCE {
+ from [0] SequenceNumber OPTIONAL -- omitted means no lower bound--,
+ to [1] SequenceNumber OPTIONAL -- omitted means no upper bound--
+}
+
+TimeRange ::= SEQUENCE {
+ from [0] CreationTime OPTIONAL -- omitted means no lower bound--,
+ to [1] CreationTime OPTIONAL -- omitted means no upper bound--
+}
+
+CreationTime ::= UTCTime
+
+Filter ::= CHOICE {
+ item [0] FilterItem,
+ and [1] SET OF Filter,
+ or [2] SET OF Filter,
+ not [3] Filter
+}
+
+FilterItem ::= CHOICE {
+ equality [0] AttributeValueAssertion,
+ substrings
+ [1] SEQUENCE {type X413ATTRIBUTE.&id({AttributeTable}),
+ strings
+ SEQUENCE OF
+ CHOICE {initial
+ [0] X413ATTRIBUTE.&Type
+ ({AttributeTable}{@substrings.type}),
+ any
+ [1] X413ATTRIBUTE.&Type
+ ({AttributeTable}{@substrings.type}),
+ final
+ [2] X413ATTRIBUTE.&Type
+ ({AttributeTable}{@substrings.type})
+ }},
+ greater-or-equal [2] AttributeValueAssertion,
+ less-or-equal [3] AttributeValueAssertion,
+ present [4] X413ATTRIBUTE.&id({AttributeTable}),
+ approximate-match [5] AttributeValueAssertion,
+ -- 1994 extension
+ other-match [6] MatchingRuleAssertion
+}
+
+MatchingRuleAssertion ::= SEQUENCE {
+ matching-rule [0] MATCHING-RULE.&id({MatchingRuleTable}),
+ attribute-type [1] X413ATTRIBUTE.&id,
+ match-value
+ [2] MATCHING-RULE.&AssertionType({MatchingRuleTable}{@matching-rule})
+}
+
+AttributeValueAssertion ::= SEQUENCE {
+ attribute-type X413ATTRIBUTE.&id({AttributeTable}),
+ attribute-value X413ATTRIBUTE.&Type({AttributeTable}{@attribute-type})
+}
+
+Selector ::= SET {
+ child-entries [0] BOOLEAN DEFAULT FALSE,
+ range [1] Range OPTIONAL -- default is unbounded --,
+ filter
+ [2] Filter
+ OPTIONAL -- default is all entries within the specified range --,
+ limit [3] INTEGER(1..ub-messages) OPTIONAL,
+ override [4] OverrideRestrictions OPTIONAL -- by default, --
+ -- any fetch-restrictions in force apply
+}
+
+OverrideRestrictions ::= BIT STRING {
+ override-content-types-restriction(0), override-EITs-restriction(1),
+ override-attribute-length-restriction(2)}(SIZE (1..ub-restrictions))
+
+EntryInformationSelection ::= SET SIZE (0..ub-per-entry) OF AttributeSelection
+
+AttributeSelection ::= SET {
+ type X413ATTRIBUTE.&id({AttributeTable}),
+ from
+ [0] INTEGER(1..ub-attribute-values)
+ OPTIONAL --used if type is multi valued--,
+ count
+ [1] INTEGER(0..ub-attribute-values)
+ OPTIONAL --used if type is multi valued--
+}
+
+EntryInformation ::= SEQUENCE {
+ sequence-number SequenceNumber,
+ attributes SET SIZE (1..ub-per-entry) OF Attribute OPTIONAL,
+ -- 1994 extension
+ value-count-exceeded
+ [0] SET SIZE (1..ub-per-entry) OF AttributeValueCount OPTIONAL
+}
+
+AttributeValueCount ::= SEQUENCE {
+ type [0] X413ATTRIBUTE.&id({AttributeTable}),
+ total [1] INTEGER
+}
+
+MSSubmissionOptions ::= SET {
+ object-entry-class
+ [0] EntryClass(submission | submission-log | draft) OPTIONAL,
+ disable-auto-modify [1] BOOLEAN DEFAULT FALSE,
+ add-message-group-names
+ [2] SET SIZE (1..ub-message-groups) OF MessageGroupName OPTIONAL,
+ ms-submission-extensions [3] MSExtensions OPTIONAL
+}
+
+originator-token MS-EXTENSION ::= {
+ OriginatorToken
+ IDENTIFIED BY id-ext-originator-token
+}
+
+OriginatorToken ::=
+ MessageToken
+ (CONSTRAINED BY {
+
+ -- Must contain an asymmetric-token with an encrypted-data component --})
+
+originator-certificate-selectors-override MS-EXTENSION ::= {
+ CertificateSelectors
+ (WITH COMPONENTS {
+ ...,
+ message-origin-authentication ABSENT
+ })
+ IDENTIFIED BY id-ext-originator-certificate-selectors-override
+}
+
+CommonSubmissionResults ::= SET {
+ created-entry [0] SequenceNumber OPTIONAL,
+ auto-action-error-indication [1] AutoActionErrorIndication OPTIONAL,
+ ms-submission-result-extensions [2] MSExtensions OPTIONAL
+}
+
+-- Retrieval Port abstract-operations
+summarize ABSTRACT-OPERATION ::= {
+ ARGUMENT SummarizeArgument
+ RESULT SummarizeResult
+ ERRORS
+ {attribute-error | invalid-parameters-error | range-error | security-error
+ | service-error, ... -- 1994 extension additions --, entry-class-error |
+ ms-extension-error}
+ LINKED {operationObject1, ...}
+ CODE op-summarize
+}
+
+SummarizeArgument ::= SET {
+ entry-class [0] EntryClass DEFAULT delivery,
+ selector [1] Selector,
+ summary-requests
+ [2] SEQUENCE SIZE (1..ub-summaries) OF X413ATTRIBUTE.&id({AttributeTable})
+ OPTIONAL -- absent if no summaries are requested--,
+ -- 1994 extension
+ summarize-extensions [3] MSExtensions OPTIONAL
+}
+
+SummarizeResult ::= SET {
+ next [0] SequenceNumber OPTIONAL,
+ count
+ [1] INTEGER(0..ub-messages)-- of the entries selected-- ,
+ span [2] Span OPTIONAL -- of the entries selected,---- omitted if count is zero --,
+ summaries
+ [3] SEQUENCE SIZE (1..ub-summaries) OF Summary OPTIONAL,
+ -- 1994 extension
+ summarize-result-extensions [4] MSExtensions OPTIONAL
+}
+
+Span ::= SEQUENCE {lowest [0] SequenceNumber,
+ highest [1] SequenceNumber
+}
+
+Summary ::= SET {
+ absent
+ [0] INTEGER(1..ub-messages)
+ OPTIONAL --count of entries where X413ATTRIBUTE is absent--,
+ present
+ [1] SET SIZE (1..ub-attribute-values)
+ OF--one for each X413ATTRIBUTE value present--
+ SEQUENCE {type X413ATTRIBUTE.&id({AttributeTable}),
+ value X413ATTRIBUTE.&Type({AttributeTable}{@.type}),
+ count INTEGER(1..ub-messages)} OPTIONAL
+}
+
+--
+list ABSTRACT-OPERATION ::= {
+ ARGUMENT ListArgument
+ RESULT ListResult
+ ERRORS
+ {attribute-error | invalid-parameters-error | range-error | security-error
+ | service-error, ... -- 1994 extension additions --, entry-class-error |
+ ms-extension-error}
+ LINKED {operationObject1, ...}
+ CODE op-list
+}
+
+ListArgument ::= SET {
+ entry-class [0] EntryClass DEFAULT delivery,
+ selector [1] Selector,
+ requested-attributes [3] EntryInformationSelection OPTIONAL,
+ -- 1994 extension
+ list-extensions [4] MSExtensions OPTIONAL
+}
+
+ListResult ::= SET {
+ next [0] SequenceNumber OPTIONAL,
+ requested
+ [1] SEQUENCE SIZE (1..ub-messages) OF EntryInformation OPTIONAL--omitted if none found--,
+ -- 1994 extension
+ list-result-extensions [2] MSExtensions OPTIONAL
+}
+
+--
+fetch ABSTRACT-OPERATION ::= {
+ ARGUMENT FetchArgument
+ RESULT FetchResult
+ ERRORS
+ {attribute-error | fetch-restriction-error | invalid-parameters-error |
+ range-error | security-error | sequence-number-error | service-error,
+ ... -- 1994 extension additions --, entry-class-error |
+ ms-extension-error}
+ LINKED {operationObject1, ...}
+ CODE op-fetch
+}
+
+FetchArgument ::= SET {
+ entry-class [0] EntryClass DEFAULT delivery,
+ item
+ CHOICE {search [1] Selector,
+ precise [2] SequenceNumber},
+ requested-attributes [3] EntryInformationSelection OPTIONAL,
+ -- 1994 extension
+ fetch-extensions [4] MSExtensions OPTIONAL
+}
+
+FetchResult ::= SET {
+ entry-information
+ [0] EntryInformation OPTIONAL --if an entry was selected--,
+ list
+ [1] SEQUENCE SIZE (1..ub-messages) OF SequenceNumber OPTIONAL,
+ next [2] SequenceNumber OPTIONAL,
+ -- 1994 extension
+ fetch-result-extensions [3] MSExtensions OPTIONAL
+}
+
+--
+delete ABSTRACT-OPERATION ::= {
+ ARGUMENT DeleteArgument
+ RESULT DeleteResult
+ ERRORS
+ {delete-error | invalid-parameters-error | range-error | security-error |
+ sequence-number-error | service-error,
+ ... -- 1994 extension additions --, entry-class-error |
+ ms-extension-error}
+ LINKED {operationObject1, ...}
+ CODE op-delete
+}
+
+DeleteArgument ::= SET {
+ entry-class [0] EntryClass DEFAULT delivery,
+ items
+ CHOICE {selector [1] Selector,
+ sequence-numbers [2] SET SIZE (1..ub-messages) OF SequenceNumber
+ },
+ -- 1994 extension
+ delete-extensions [3] MSExtensions OPTIONAL
+}
+
+DeleteResult ::= CHOICE {
+ delete-result-88 NULL,
+ -- 1994 extension
+ delete-result-94
+ SET {entries-deleted
+ [0] SEQUENCE SIZE (1..ub-messages) OF SequenceNumber OPTIONAL,
+ delete-result-extensions [1] MSExtensions OPTIONAL}
+}
+
+--
+register-MS ABSTRACT-OPERATION ::= {
+ ARGUMENT Register-MSArgument
+ RESULT Register-MSResult
+ ERRORS
+ {attribute-error | auto-action-request-error | invalid-parameters-error |
+ security-error | service-error | old-credentials-incorrectly-specified |
+ new-credentials-unacceptable, ... -- 1994 extension additions --,
+ message-group-error | ms-extension-error | register-ms-error}
+ LINKED {operationObject1, ...}
+ CODE op-register-ms
+}
+
+Register-MSArgument ::= SET {
+ auto-action-registrations
+ [0] SET SIZE (1..ub-auto-registrations) OF AutoActionRegistration OPTIONAL,
+ auto-action-deregistrations
+ [1] SET SIZE (1..ub-auto-registrations) OF AutoActionDeregistration
+ OPTIONAL,
+ list-attribute-defaults
+ [2] SET SIZE (0..ub-default-registrations) OF
+ X413ATTRIBUTE.&id({AttributeTable}) OPTIONAL,
+ fetch-attribute-defaults
+ [3] SET SIZE (0..ub-default-registrations) OF
+ X413ATTRIBUTE.&id({AttributeTable}) OPTIONAL,
+ change-credentials
+ [4] SEQUENCE {old-credentials
+ [0] Credentials(WITH COMPONENTS {
+ simple
+ }),
+ new-credentials
+ [1] Credentials(WITH COMPONENTS {
+ simple
+ })} OPTIONAL,
+ user-security-labels
+ [5] SET SIZE (1..ub-labels-and-redirections) OF SecurityLabel OPTIONAL,
+ -- 1994 extensions
+ ua-registrations
+ [6] SET SIZE (1..ub-ua-registrations) OF UARegistration OPTIONAL,
+ submission-defaults [7] MSSubmissionOptions OPTIONAL,
+ message-group-registrations [8] MessageGroupRegistrations OPTIONAL,
+ registration-status-request [9] RegistrationTypes OPTIONAL,
+ register-ms-extensions [10] MSExtensions OPTIONAL
+}
+
+AutoActionDeregistration ::= SEQUENCE {
+ auto-action-type AUTO-ACTION.&id({AutoActionTable}),
+ registration-identifier [0] INTEGER(1..ub-per-auto-action) DEFAULT 1
+}
+
+UARegistration ::= SET {
+ ua-registration-identifier [0] RegistrationIdentifier,
+ ua-list-attribute-defaults
+ [1] SET SIZE (0..ub-default-registrations) OF
+ X413ATTRIBUTE.&id({AttributeTable}) OPTIONAL,
+ ua-fetch-attribute-defaults
+ [2] SET SIZE (0..ub-default-registrations) OF
+ X413ATTRIBUTE.&id({AttributeTable}) OPTIONAL,
+ ua-submission-defaults [3] MSSubmissionOptions OPTIONAL,
+ content-specific-defaults [4] MSExtensions OPTIONAL
+}
+
+MessageGroupRegistrations ::=
+ SEQUENCE SIZE (1..ub-default-registrations) OF
+ CHOICE {register-group [0] MessageGroupNameAndDescriptor,
+ deregister-group [1] MessageGroupName,
+ change-descriptors [2] MessageGroupNameAndDescriptor}
+
+MessageGroupNameAndDescriptor ::= SET {
+ message-group-name [0] MessageGroupName,
+ message-group-descriptor
+ [1] GeneralString(SIZE (1..ub-group-descriptor-length)) OPTIONAL
+}
+
+RegistrationTypes ::= SET {
+ registrations
+ [0] BIT STRING {auto-action-registrations(0), list-attribute-defaults(1),
+ fetch-attribute-defaults(2), ua-registrations(3),
+ submission-defaults(4), message-group-registrations(5)}
+ OPTIONAL,
+ extended-registrations [1] SET OF MS-EXTENSION.&id OPTIONAL,
+ restrict-message-groups [2] MessageGroupsRestriction OPTIONAL
+}
+
+MessageGroupsRestriction ::= SET {
+ parent-group [0] MessageGroupName OPTIONAL,
+ immediate-descendants-only [1] BOOLEAN DEFAULT TRUE,
+ omit-descriptors [2] BOOLEAN DEFAULT TRUE
+}
+
+protected-change-credentials MS-EXTENSION ::= {
+ ProtectedChangeCredentials
+ IDENTIFIED BY id-ext-protected-change-credentials
+}
+
+ProtectedChangeCredentials ::= SEQUENCE {
+ algorithm-identifier [0] IMPLICIT OBJECT IDENTIFIER,
+ old-credentials
+ InitiatorCredentials(WITH COMPONENTS {
+ protected PRESENT
+ }),
+ password-delta [2] IMPLICIT BIT STRING
+}
+
+Register-MSResult ::= CHOICE {
+ no-status-information NULL,
+ -- 1994 extension
+ registered-information
+ SET {auto-action-registrations
+ [0] SET SIZE (1..ub-auto-registrations) OF AutoActionRegistration
+ OPTIONAL,
+ list-attribute-defaults
+ [1] SET SIZE (1..ub-default-registrations) OF
+ X413ATTRIBUTE.&id({AttributeTable}) OPTIONAL,
+ fetch-attribute-defaults
+ [2] SET SIZE (1..ub-default-registrations) OF
+ X413ATTRIBUTE.&id({AttributeTable}) OPTIONAL,
+ ua-registrations
+ [3] SET SIZE (1..ub-ua-registrations) OF UARegistration OPTIONAL,
+ submission-defaults [4] MSSubmissionOptions OPTIONAL,
+ message-group-registrations
+ [5] SET SIZE (1..ub-message-groups) OF
+ MessageGroupNameAndDescriptor OPTIONAL,
+ register-ms-result-extensions [6] MSExtensions OPTIONAL}
+}
+
+--
+alert ABSTRACT-OPERATION ::= {
+ ARGUMENT AlertArgument
+ RESULT AlertResult
+ ERRORS {security-error}
+ LINKED {operationObject1, ...}
+ CODE op-alert
+}
+
+AlertArgument ::= SET {
+ alert-registration-identifier [0] INTEGER(1..ub-auto-actions),
+ new-entry [2] EntryInformation OPTIONAL
+}
+
+AlertResult ::= NULL
+
+--
+modify ABSTRACT-OPERATION ::= {
+ ARGUMENT ModifyArgument
+ RESULT ModifyResult
+ ERRORS
+ {attribute-error | invalid-parameters-error | security-error |
+ sequence-number-error | service-error | modify-error |
+ message-group-error | entry-class-error | ms-extension-error,
+ ... -- For future extension additions --}
+ LINKED {operationObject1, ...}
+ CODE op-modify
+}
+
+ModifyArgument ::= SET {
+ entry-class [0] EntryClass DEFAULT delivery,
+ entries
+ CHOICE {selector [1] Selector,
+ specific-entries
+ [2] SEQUENCE SIZE (1..ub-messages) OF SequenceNumber},
+ modifications
+ [3] SEQUENCE SIZE (1..ub-modifications) OF EntryModification,
+ modify-extensions [4] MSExtensions OPTIONAL
+}
+
+EntryModification ::= SET {
+ strict [0] BOOLEAN DEFAULT FALSE,
+ modification
+ CHOICE {add-attribute [1] Attribute,
+ remove-attribute [2] X413ATTRIBUTE.&id({AttributeTable}),
+ add-values [3] OrderedAttribute,
+ remove-values [4] OrderedAttribute}
+}
+
+OrderedAttribute ::= SEQUENCE {
+ attribute-type X413ATTRIBUTE.&id({AttributeTable}),
+ attribute-values
+ SEQUENCE SIZE (1..ub-attribute-values) OF
+ SEQUENCE {-- at least one must be specified
+ value
+ [0] X413ATTRIBUTE.&Type({AttributeTable}{@attribute-type})
+ OPTIONAL,
+ position [1] INTEGER(1..ub-attribute-values) OPTIONAL
+ }
+}
+
+ModifyResult ::= SET {
+ entries-modified
+ [0] SEQUENCE SIZE (1..ub-messages) OF SequenceNumber OPTIONAL,
+ modify-result-extensions [1] MSExtensions OPTIONAL
+}
+
+-- MS-submission Port abstract-operations
+ms-message-submission ABSTRACT-OPERATION ::= {
+ ARGUMENT MSMessageSubmissionArgument
+ RESULT MSMessageSubmissionResult
+ ERRORS
+ {submission-control-violated | element-of-service-not-subscribed |
+ originator-invalid | recipient-improperly-specified |
+ inconsistent-request | security-error | unsupported-critical-function |
+ remote-bind-error, ... -- 1994 extension additions --, ms-extension-error
+ | message-group-error | entry-class-error | service-error}
+ LINKED {operationObject1, ...}
+ CODE op-ms-message-submission
+}
+
+MSMessageSubmissionArgument ::= SEQUENCE {
+ COMPONENTS OF
+ MessageSubmissionArgument -- This imported type has IMPLICIT tags --,
+ -- 1994 extension
+ submission-options [4] MSSubmissionOptions OPTIONAL
+}
+
+forwarding-request EXTENSION ::= {
+ SequenceNumber,
+ IDENTIFIED BY standard-extension:36
+}
+
+MSMessageSubmissionResult ::= CHOICE {
+ mts-result
+ SET {COMPONENTS OF
+ MessageSubmissionResult-- This imported type has IMPLICIT tags -- ,
+ -- 1994 extension
+ ms-message-result [4] CommonSubmissionResults OPTIONAL},
+ -- 1994 extension
+ store-draft-result [4] CommonSubmissionResults
+}
+
+--
+ms-probe-submission ABSTRACT-OPERATION ::= {
+ ARGUMENT MSProbeSubmissionArgument
+ RESULT MSProbeSubmissionResult
+ ERRORS
+ {submission-control-violated | element-of-service-not-subscribed |
+ originator-invalid | recipient-improperly-specified |
+ inconsistent-request | security-error | unsupported-critical-function |
+ remote-bind-error, ... -- 1994 extension additions --, ms-extension-error
+ | message-group-error | entry-class-error | service-error}
+ LINKED {operationObject1, ...}
+ CODE op-ms-probe-submission
+}
+
+MSProbeSubmissionArgument ::= SET {
+ COMPONENTS OF
+ ProbeSubmissionArgument -- This imported type has IMPLICIT tags --,
+ -- 1994 extension
+ submission-options [4] MSSubmissionOptions OPTIONAL
+}
+
+MSProbeSubmissionResult ::= SET {
+ COMPONENTS OF
+ ProbeSubmissionResult -- This imported type has IMPLICIT tags --,
+ -- 1994 extension
+ ms-probe-result [4] CommonSubmissionResults OPTIONAL
+}
+
+ms-cancel-deferred-delivery ABSTRACT-OPERATION ::= cancel-deferred-delivery
+
+ms-submission-control ABSTRACT-OPERATION ::= submission-control
+
+-- Abstract-errors
+attribute-error ABSTRACT-ERROR ::= {
+ PARAMETER
+ SET {problems
+ [0] SET SIZE (1..ub-per-entry) OF
+ SET {problem [0] AttributeProblem,
+ type [1] X413ATTRIBUTE.&id({AttributeTable}),
+ value
+ [2] X413ATTRIBUTE.&Type({AttributeTable}{@.type})
+ OPTIONAL}}
+ CODE err-attribute-error
+}
+
+AttributeProblem ::= INTEGER {
+ invalid-attribute-value(0), unavailable-attribute-type(1),
+ inappropriate-matching(2), attribute-type-not-subscribed(3),
+ inappropriate-for-operation(4),
+ -- 1994 extensions
+ inappropriate-modification(5), single-valued-attribute(6)
+}(0..ub-error-reasons)
+
+--
+auto-action-request-error ABSTRACT-ERROR ::= {
+ PARAMETER
+ SET {problems
+ [0] SET SIZE (1..ub-auto-registrations) OF
+ SET {problem [0] AutoActionRequestProblem,
+ type [1] AUTO-ACTION.&id({AutoActionTable})
+ }}
+ CODE err-auto-action-request-error
+}
+
+AutoActionRequestProblem ::= INTEGER {
+ unavailable-auto-action-type(0),
+ auto-action-type-not-subscribed(1),
+ -- 1994 extension
+ not-willing-to-perform(2)}(0..ub-error-reasons)
+
+--
+delete-error ABSTRACT-ERROR ::= {
+ PARAMETER
+ SET {problems
+ [0] SET SIZE (1..ub-messages) OF
+ SET {problem [0] DeleteProblem,
+ sequence-number [1] SequenceNumber},
+ -- 1994 extension
+ entries-deleted
+ [1] SET SIZE (1..ub-messages) OF SequenceNumber OPTIONAL}
+ CODE err-delete-error
+}
+
+DeleteProblem ::= INTEGER {
+ child-entry-specified(0),
+ delete-restriction-problem(1),
+ -- 1994 extensions
+ new-entry-specified(2), entry-class-restriction(3), stored-message-exists(4)
+}(0..ub-error-reasons)
+
+--
+fetch-restriction-error ABSTRACT-ERROR ::= {
+ PARAMETER
+ SET {problems
+ [0] SET SIZE (1..ub-default-registrations) OF
+ SET {problem [3] FetchRestrictionProblem,
+ restriction
+ CHOICE {content-type [0] OBJECT IDENTIFIER,
+ eit [1] MS-EITs,
+ attribute-length [2] INTEGER}}}
+ CODE err-fetch-restriction-error
+}
+
+FetchRestrictionProblem ::= INTEGER {
+ content-type-problem(1), eit-problem(2), maximum-length-problem(3)
+}(0..ub-error-reasons)
+
+--
+invalid-parameters-error ABSTRACT-ERROR ::= {
+ PARAMETER NULL
+ CODE err-invalid-parameters-error
+}
+
+--
+range-error ABSTRACT-ERROR ::= {
+ PARAMETER SET {problem [0] RangeProblem}
+ CODE err-range-error
+}
+
+RangeProblem ::= INTEGER {reversed(0)}(0..ub-error-reasons)
+
+--
+sequence-number-error ABSTRACT-ERROR ::= {
+ PARAMETER
+ SET {problems
+ [1] SET SIZE (1..ub-messages) OF
+ SET {problem [0] SequenceNumberProblem,
+ sequence-number [1] SequenceNumber}}
+ CODE err-sequence-number-error
+}
+
+SequenceNumberProblem ::= INTEGER {no-such-entry(0)}(0..ub-error-reasons)
+
+--
+service-error ABSTRACT-ERROR ::= {
+ PARAMETER ServiceErrorParameter
+ CODE err-service-error
+}
+
+ServiceErrorParameter ::= SET {
+ problem [0] ServiceProblem,
+ -- 1994 extension
+ supplementary-information
+ [1] GeneralString(SIZE (1..ub-supplementary-info-length)) OPTIONAL
+}
+
+ServiceProblem ::= INTEGER {busy(0), unavailable(1), unwilling-to-perform(2)
+}(0..ub-error-reasons)
+
+--
+message-group-error ABSTRACT-ERROR ::= {
+ PARAMETER MessageGroupErrorParameter
+ CODE err-message-group-error
+}
+
+MessageGroupErrorParameter ::= SET {
+ problem [0] MessageGroupProblem,
+ name [1] MessageGroupName
+}
+
+MessageGroupProblem ::= INTEGER {
+ name-not-registered(0), name-already-registered(1), parent-not-registered(2),
+ group-not-empty(3), name-in-use(4), child-group-registered(5),
+ group-depth-exceeded(6)}(0..ub-error-reasons)
+
+--
+ms-extension-error ABSTRACT-ERROR ::= {
+ PARAMETER MSExtensionErrorParameter
+ CODE err-ms-extension-error
+}
+
+MSExtensionErrorParameter ::= CHOICE {
+ ms-extension-problem [0] MSExtensionItem,
+ unknown-ms-extension [1] OBJECT IDENTIFIER
+}
+
+--
+register-ms-error ABSTRACT-ERROR ::= {
+ PARAMETER
+ SET {problem [0] RegistrationProblem,
+ registration-type [1] RegistrationTypes}
+ CODE err-register-ms-error
+}
+
+RegistrationProblem ::= ENUMERATED {
+ registration-not-supported(0), registration-improperly-specified(1),
+ registration-limit-exceeded(2), ... -- For future extension additions --
+ }
+
+--
+modify-error ABSTRACT-ERROR ::= {
+ PARAMETER ModifyErrorParameter
+ CODE err-modify-error
+}
+
+ModifyErrorParameter ::= SET {
+ entries-modified
+ [0] SEQUENCE SIZE (1..ub-messages) OF SequenceNumber OPTIONAL,
+ failing-entry [1] SequenceNumber,
+ modification-number [2] INTEGER,
+ problem [3] ModifyProblem
+}
+
+ModifyProblem ::= INTEGER {
+ attribute-not-present(0), value-not-present(1),
+ attribute-or-value-already-exists(2), invalid-position(3),
+ modify-restriction-problem(4)}(0..ub-error-reasons)
+
+--
+entry-class-error ABSTRACT-ERROR ::= {
+ PARAMETER EntryClassErrorParameter
+ CODE err-entry-class-error
+}
+
+EntryClassErrorParameter ::= SET {
+ entry-class [0] EntryClass,
+ problem
+ [1] BIT STRING {unsupported-entry-class(0), entry-class-not-subscribed(1),
+ inappropriate-entry-class(2)}
+}
+
+END -- of MS Abstract Service
+
+-- Generated by Asnp, the ASN.1 pretty-printer of France Telecom R&D
+
diff --git a/lib/asn1/test/asn1_SUITE_data/x420/MSAccessProtocol.asn b/lib/asn1/test/asn1_SUITE_data/x420/MSAccessProtocol.asn
new file mode 100644
index 0000000000..b69d72b3ed
--- /dev/null
+++ b/lib/asn1/test/asn1_SUITE_data/x420/MSAccessProtocol.asn
@@ -0,0 +1,259 @@
+-- Module MSAccessProtocol (X.419:06/1999)
+
+MSAccessProtocol {joint-iso-itu-t mhs(6) protocols(0) modules(0)
+ ms-access-protocol(2) version-1999(1)} DEFINITIONS ::=
+BEGIN
+
+-- Prologue
+IMPORTS
+ -- MS Abstract Service
+ ms-access-contract-88, ms-access-contract-94, ms-submission, retrieval,
+ retrieval-88
+ --==
+ FROM MSAbstractService {joint-iso-itu-t mhs(6) ms(4) modules(0)
+ abstract-service(1) version-1999(1)}
+ -- Remote Operations
+ APPLICATION-CONTEXT
+ --==
+ FROM Remote-Operations-Information-Objects-extensions {joint-iso-itu-t
+ remote-operations(4) informationObjects-extensions(8) version1(0)}
+ Code
+ --==
+ FROM Remote-Operations-Information-Objects {joint-iso-itu-t
+ remote-operations(4) informationObjects(5) version1(0)}
+ Bind{}, InvokeId, Unbind{}
+ --==
+ FROM Remote-Operations-Generic-ROS-PDUs {joint-iso-itu-t
+ remote-operations(4) generic-ROS-PDUs(6) version1(0)}
+ ROS-SingleAS{}
+ --==
+ FROM Remote-Operations-Useful-Definitions {joint-iso-itu-t
+ remote-operations(4) useful-definitions(7) version1(0)}
+ acse, association-by-RTSE, pData, transfer-by-RTSE
+ --==
+ FROM Remote-Operations-Realizations {joint-iso-itu-t remote-operations(4)
+ realizations(9) version1(0)}
+ acse-abstract-syntax
+ --==
+ FROM Remote-Operations-Abstract-Syntaxes {joint-iso-itu-t
+ remote-operations(4) remote-operations-abstract-syntaxes(12) version1(0)}
+ -- Reliable Transfer
+ RTORQapdu, RTOACapdu, RTORJapdu
+ FROM Reliable-Transfer-APDU {joint-iso-itu-t reliable-transfer(3) apdus(0)}
+ -- MTS Access Protocol
+ message-administration-abstract-syntax-88,
+ message-administration-abstract-syntax-94,
+ message-submission-abstract-syntax
+ --==
+ FROM MTSAccessProtocol {joint-iso-itu-t mhs(6) protocols(0) modules(0)
+ mts-access-protocol(1) version-1999(1)}
+ -- Object Identifiers
+ id-ac-ms-access-88, id-ac-ms-access-94, id-ac-ms-reliable-access-88,
+ id-ac-ms-reliable-access-94, id-as-ms-msse, id-as-mase-88, id-as-mase-94,
+ id-as-mdse-88, id-as-mdse-94, id-as-mrse-88, id-as-mrse-94, id-as-ms-88,
+ id-as-ms-94, id-as-ms-rtse, id-as-msse
+ --==
+ FROM MHSProtocolObjectIdentifiers {joint-iso-itu-t mhs(6) protocols(0)
+ modules(0) object-identifiers(0) version-1994(0)};
+
+-- Definitions from X.228(11/1988) --
+RTSE-apdus ::= CHOICE {
+ rtorq-apdu [16] IMPLICIT RTORQapdu,
+ rtoac-apdu [17] IMPLICIT RTOACapdu,
+ rtorj-apdu [18] IMPLICIT RTORJapdu,
+ rttp-apdu RTTPapdu,
+ rttr-apdu RTTRapdu,
+ rtab-apdu [22] IMPLICIT RTABapdu
+}
+
+RTTPapdu ::= -- priority-- INTEGER
+
+RTTRapdu ::= OCTET STRING
+
+RTABapdu ::= SET {
+ abortReason [0] IMPLICIT AbortReason OPTIONAL,
+ reflectedParameter [1] IMPLICIT BIT STRING OPTIONAL,
+ -- 8 bits maximum, only if abortReason is invalidParameter
+ userdataAB
+ [2] TYPE-IDENTIFIER.&Type
+ OPTIONAL -- only in normal mode and if abortReason--
+ -- is userError
+}
+
+AbortReason ::= INTEGER {
+ localSystemProblem(0),
+ invalidParameter(1), -- reflectedParameter supplied
+ unrecognizedActivity(2),
+ temporaryProblem(3),
+ -- the RTSE cannot accept a session for a period of time
+ protocolError(4), -- RTSE level protocol error
+ permanentProblem(5), --provider-abort solely in normal mode
+ userError(6), -- user-abort solely in normal mode
+ transferCompleted(7) -- activity can't be discarded--}
+-- end of definitions from X.228 (11/1988) --
+
+-- APPLICATION-CONTEXTS
+-- 1994 Application Context omitting RTSE
+ms-access-94 APPLICATION-CONTEXT ::= {
+ CONTRACT ms-access-contract-94
+ ESTABLISHED BY acse
+ INFORMATION TRANSFER BY pData
+ ABSTRACT SYNTAXES
+ {acse-abstract-syntax | ms-message-submission-abstract-syntax |
+ message-retrieval-abstract-syntax-94 |
+ message-administration-abstract-syntax-94 |
+ ms-bind-unbind-abstract-syntax-94}
+ APPLICATION CONTEXT NAME id-ac-ms-access-94
+}
+
+-- 1994 Application Context including RTSE
+ms-reliable-access-94 APPLICATION-CONTEXT ::= {
+ CONTRACT ms-access-contract-94
+ ESTABLISHED BY association-by-RTSE
+ INFORMATION TRANSFER BY transfer-by-RTSE
+ ABSTRACT SYNTAXES
+ {acse-abstract-syntax | ms-message-submission-abstract-syntax |
+ message-retrieval-abstract-syntax-94 |
+ message-administration-abstract-syntax-94 |
+ ms-bind-unbind-rtse-abstract-syntax}
+ APPLICATION CONTEXT NAME id-ac-ms-reliable-access-94
+}
+
+-- 1988 Application Context omitting RTSE
+ms-access-88 APPLICATION-CONTEXT ::= {
+ CONTRACT ms-access-contract-88
+ ESTABLISHED BY acse
+ INFORMATION TRANSFER BY pData
+ ABSTRACT SYNTAXES
+ {acse-abstract-syntax | message-submission-abstract-syntax |
+ message-retrieval-abstract-syntax-88 |
+ message-administration-abstract-syntax-88 |
+ ms-bind-unbind-abstract-syntax-88}
+ APPLICATION CONTEXT NAME id-ac-ms-access-88
+}
+
+-- 1988 Application Context including RTSE
+ms-reliable-access-88 APPLICATION-CONTEXT ::= {
+ CONTRACT ms-access-contract-88
+ ESTABLISHED BY association-by-RTSE
+ INFORMATION TRANSFER BY transfer-by-RTSE
+ ABSTRACT SYNTAXES
+ {acse-abstract-syntax | message-submission-abstract-syntax |
+ message-retrieval-abstract-syntax-88 |
+ message-administration-abstract-syntax-88 |
+ ms-bind-unbind-rtse-abstract-syntax}
+ APPLICATION CONTEXT NAME id-ac-ms-reliable-access-88
+}
+
+-- ABSTRACT SYNTAXES
+-- Abstract-syntax for 1994 MS-bind and MS-unbind
+ms-bind-unbind-abstract-syntax-94 ABSTRACT-SYNTAX ::= {
+ MSBindUnbindPDUs94
+ IDENTIFIED BY id-as-ms-94
+}
+
+MSBindUnbindPDUs94 ::= CHOICE {
+ bind Bind{ms-access-contract-94.&connection.&bind},
+ unbind Unbind{ms-access-contract-94.&connection.&unbind}
+}
+
+-- Abstract-syntax for 1988 MS-bind and MS-unbind
+ms-bind-unbind-abstract-syntax-88 ABSTRACT-SYNTAX ::= {
+ MSBindUnbindPDUs88
+ IDENTIFIED BY id-as-ms-88
+}
+
+MSBindUnbindPDUs88 ::= CHOICE {
+ bind Bind{ms-access-contract-88.&connection.&bind},
+ unbind Unbind{ms-access-contract-88.&connection.&unbind}
+}
+
+-- Abstract-syntax for MS-bind and MS-unbind with RTSE
+ms-bind-unbind-rtse-abstract-syntax ABSTRACT-SYNTAX ::= {
+ RTSE-apdus -- With MS-bind and MS-unbind --
+ IDENTIFIED BY id-as-ms-rtse
+}
+
+-- Abstract Syntax for MS Message Submission Service Element
+ms-message-submission-abstract-syntax ABSTRACT-SYNTAX ::= {
+ MSMessageSubmissionPDUs
+ IDENTIFIED BY id-as-ms-msse
+}
+
+MSMessageSubmissionPDUs ::= ROS-SingleAS{{MSInvokeIds}, ms-submission}
+
+MSInvokeIds ::= InvokeId(ALL EXCEPT absent:NULL)
+
+-- Abstract Syntax for Message Retrieval Service Element 1994
+message-retrieval-abstract-syntax-94 ABSTRACT-SYNTAX ::= {
+ MessageRetrievalPDUs
+ IDENTIFIED BY id-as-mrse-94
+}
+
+-- Abstract Syntax for Message Retrieval Service Element 1988
+MessageRetrievalPDUs ::=
+ ROS-SingleAS{{MSInvokeIds}, retrieval}
+
+message-retrieval-abstract-syntax-88 ABSTRACT-SYNTAX ::= {
+ MessageRetrievalPDUs88
+ IDENTIFIED BY id-as-mrse-88
+}
+
+MessageRetrievalPDUs88 ::= ROS-SingleAS{{MSInvokeIds}, retrieval-88}
+
+-- Remote Operations
+op-ms-submission-control Code ::= local:2
+
+op-ms-message-submission Code ::= local:3
+
+op-ms-probe-submission Code ::= local:4
+
+op-ms-cancel-deferred-delivery Code ::= local:7
+
+op-summarize Code ::= local:20
+
+op-list Code ::= local:21
+
+op-fetch Code ::= local:22
+
+op-delete Code ::= local:23
+
+op-register-ms Code ::= local:24
+
+op-alert Code ::= local:25
+
+op-modify Code ::= local:26
+
+-- Remote Errors
+err-attribute-error Code ::= local:21
+
+err-auto-action-request-error Code ::= local:22
+
+err-delete-error Code ::= local:23
+
+err-fetch-restriction-error Code ::= local:24
+
+err-range-error Code ::= local:25 -- 1988 Application Contexts only
+
+err-security-error Code ::= local:26
+
+err-service-error Code ::= local:27
+
+err-sequence-number-error Code ::= local:28
+
+err-invalid-parameters-error Code ::= local:29
+
+err-message-group-error Code ::= local:30
+
+err-ms-extension-error Code ::= local:31
+
+err-register-ms-error Code ::= local:32
+
+err-modify-error Code ::= local:33
+
+err-entry-class-error Code ::= local:34
+
+END -- of MSAccessProtocol
+
+-- Generated by Asnp, the ASN.1 pretty-printer of France Telecom R&D
+
diff --git a/lib/asn1/test/asn1_SUITE_data/x420/MSGeneralAttributeTypes.asn b/lib/asn1/test/asn1_SUITE_data/x420/MSGeneralAttributeTypes.asn
new file mode 100644
index 0000000000..99d34b2883
--- /dev/null
+++ b/lib/asn1/test/asn1_SUITE_data/x420/MSGeneralAttributeTypes.asn
@@ -0,0 +1,830 @@
+-- Module MSGeneralAttributeTypes (X.413:06/1999)
+MSGeneralAttributeTypes {joint-iso-itu-t mhs(6) ms(4) modules(0)
+ general-attribute-types(2) version-1999(1)} DEFINITIONS ::=
+BEGIN
+
+-- Prologue
+IMPORTS
+ -- X413ATTRIBUTE information object class
+ X413ATTRIBUTE,
+ -- MS abstract-service data-types
+ AutoActionError, AutoActionType, CreationTime, EntryClassErrorParameter,
+ EntryType, MessageGroupName, MessageGroupErrorParameter, MS-EIT,
+ MSExtensionErrorParameter, RetrievalStatus, SequenceNumber,
+ ServiceErrorParameter
+ FROM MSAbstractService {joint-iso-itu-t mhs(6) ms(4) modules(0)
+ abstract-service(1) version-1999(1)}
+ -- General-attribute-type Object Identifiers
+ id-att-ac-correlated-report-list, id-att-ac-report-subject-entry,
+ id-att-ac-report-summary, id-att-ac-uncorrelated-report-list,
+ id-att-auto-action-error, id-att-auto-action-registration-identifier,
+ id-att-auto-action-subject-entry, id-att-auto-action-type,
+ id-att-certificate-selectors, id-att-child-sequence-numbers,
+ id-att-content, id-att-content-confidentiality-algorithm-identifier,
+ id-att-content-correlator, id-att-content-identifier,
+ id-att-content-integrity-check, id-att-content-length,
+ id-att-content-returned, id-att-content-type,
+ id-att-conversion-with-loss-prohibited, id-att-converted-EITs,
+ id-att-creation-time, id-att-deferred-delivery-cancellation-time,
+ id-att-deferred-delivery-time, id-att-deletion-time, id-att-delivered-EITs,
+ id-att-delivery-flags, id-att-dl-exempted-recipients,
+ id-att-dl-expansion-history, id-att-dl-expansion-prohibited,
+ id-att-entry-type, id-att-internal-trace-information,
+ id-att-latest-delivery-time, id-att-locally-originated,
+ id-att-marked-for-deletion, id-att-message-delivery-envelope,
+ id-att-message-delivery-time, id-att-message-group-name,
+ id-att-message-identifier, id-att-message-notes,
+ id-att-message-origin-authentication-check, id-att-message-security-label,
+ id-att-message-submission-envelope, id-att-message-submission-time,
+ id-att-message-token, id-att-ms-originated, id-att-ms-submission-error,
+ id-att-multiple-originator-certificates, id-att-original-EITs,
+ id-att-originally-intended-recipient-name,
+ id-att-originating-MTA-certificate, id-att-originator-certificate,
+ id-att-originator-name, id-att-originator-report-request,
+ id-att-originator-return-address, id-att-other-recipient-names,
+ id-att-parent-sequence-number, id-att-per-message-indicators,
+ id-att-per-recipient-message-submission-fields,
+ id-att-per-recipient-probe-submission-fields,
+ id-att-per-recipient-report-delivery-fields, id-att-priority,
+ id-att-probe-origin-authentication-check, id-att-probe-submission-envelope,
+ id-att-proof-of-delivery-request, id-att-proof-of-submission,
+ id-att-recipient-certificate, id-att-recipient-names,
+ id-att-recipient-reassignment-prohibited, id-att-redirection-history,
+ id-att-report-delivery-envelope, id-att-reporting-DL-name,
+ id-att-reporting-MTA-certificate,
+ id-att-report-origin-authentication-check, id-att-retrieval-status,
+ id-att-security-classification, id-att-sequence-number,
+ id-att-signature-verification-status, id-att-storage-period,
+ id-att-storage-time, id-att-subject-submission-identifier,
+ id-att-this-recipient-name, id-att-trace-information
+ FROM MSObjectIdentifiers {joint-iso-itu-t mhs(6) ms(4) modules(0)
+ object-identifiers(0) version-1999(1)}
+ -- Message Store matching-rules
+ bitStringMatch, contentCorrelatorMatch, contentIdentifierMatch,
+ mSSingleSubstringListElementsMatch, mSSingleSubstringListMatch,
+ mSSingleSubstringMatch, mSSubstringsMatch, mSStringCaseSensitiveMatch,
+ mSStringListElementsMatch, mSStringListMatch, mSStringMatch,
+ mSStringOrderingMatch, mTSIdentifierMatch, oRAddressElementsMatch,
+ oRAddressMatch, oRAddressSubstringElementsMatch, oRNameElementsMatch,
+ oRNameMatch, oRNameSingleElementMatch, oRNameSubstringElementsMatch,
+ redirectionOrDLExpansionElementsMatch, redirectionOrDLExpansionMatch,
+ redirectionOrDLExpansionSingleElementMatch,
+ redirectionOrDLExpansionSubstringElementsMatch, redirectionReasonMatch,
+ valueCountMatch
+ FROM MSMatchingRules {joint-iso-itu-t mhs(6) ms(4) modules(0)
+ general-matching-rules(5) version-1999(1)}
+ -- MS abstract-service upper bounds
+ ub-entry-types, ub-message-notes-length
+ FROM MSUpperBounds {joint-iso-itu-t mhs(6) ms(4) modules(0) upper-bounds(4)
+ version-1994(0)}
+ -- MTS abstract-service data-types
+ CertificateSelectors, Content, ContentCorrelator, ContentIdentifier,
+ ContentIntegrityCheck, ContentLength, ConversionWithLossProhibited,
+ DeferredDeliveryTime, DeliveryFlags, DLExpansion, DLExpansionProhibited,
+ ExtendedCertificates, ImproperlySpecifiedRecipients, LatestDeliveryTime,
+ MessageDeliveryEnvelope, MessageDeliveryTime,
+ MessageOriginAuthenticationCheck, MessageSecurityLabel,
+ MessageSubmissionEnvelope, MessageSubmissionTime, MessageToken,
+ MTSIdentifier, OriginatingMTACertificate, OriginatorCertificate,
+ OriginatorReportRequest, OriginatorReturnAddress, ORName,
+ PerMessageIndicators, PerRecipientMessageSubmissionFields,
+ PerRecipientProbeSubmissionFields, PerRecipientReportDeliveryFields,
+ Priority, ProbeOriginAuthenticationCheck, ProbeSubmissionEnvelope,
+ ProofOfDeliveryRequest, ProofOfSubmission, RecipientReassignmentProhibited,
+ Redirection, ReportDeliveryEnvelope, ReportingDLName,
+ ReportingMTACertificate, ReportOriginAuthenticationCheck,
+ SecurityClassification, SecurityProblem, SubjectSubmissionIdentifier
+ FROM MTSAbstractService {joint-iso-itu-t mhs(6) mts(3) modules(0)
+ mts-abstract-service(1) version-1999(1)}
+ -- MTS abstract-service upper bound
+ ub-recipients
+ FROM MTSUpperBounds {joint-iso-itu-t mhs(6) mts(3) modules(0)
+ upper-bounds(3) version-1999(1)}
+ -- MTA abstract-service data-types
+ InternalTraceInformationElement, TraceInformationElement
+ FROM MTAAbstractService {joint-iso-itu-t mhs(6) mts(3) modules(0)
+ mta-abstract-service(2) version-1999(1)}
+ -- Directory matching-rules
+ booleanMatch, integerMatch, integerOrderingMatch, uTCTimeMatch,
+ uTCTimeOrderingMatch
+ FROM SelectedAttributeTypes
+ objectIdentifierMatch
+ FROM InformationFramework
+
+ -- Authentication-service data-types
+ AlgorithmIdentifier
+ FROM AuthenticationFramework;
+
+-- X413ATTRIBUTE table
+AttributeTable X413ATTRIBUTE ::=
+ {GeneralAttributes | ContentSpecificAttributes}
+
+GeneralAttributes X413ATTRIBUTE ::=
+ {ms-child-sequence-numbers | mt-content |
+ mt-content-confidentiality-algorithm-identifier | mt-content-correlator |
+ mt-content-identifier | mt-content-integrity-check | ms-content-length |
+ ms-content-returned | mt-content-type | mt-conversion-with-loss-prohibited |
+ mt-converted-EITs | ms-creation-time | ms-delivered-EITs | mt-delivery-flags
+ | mt-dl-expansion-history | ms-entry-type | mt-message-delivery-envelope |
+ mt-message-delivery-time | mt-message-identifier |
+ mt-message-origin-authentication-check | mt-message-security-label |
+ mt-message-submission-time | mt-message-token | mt-original-EITs |
+ mt-originally-intended-recipient-name | mt-originator-certificate |
+ mt-originator-name | mt-other-recipient-names | ms-parent-sequence-number |
+ mt-per-recipient-report-delivery-fields | mt-priority |
+ mt-proof-of-delivery-request | mt-redirection-history |
+ mt-report-delivery-envelope | mt-reporting-DL-name |
+ mt-reporting-MTA-certificate | mt-report-origin-authentication-check |
+ ms-retrieval-status | mt-security-classification | ms-sequence-number |
+ mt-subject-submission-identifier | mt-this-recipient-name,
+ ... -- 1994 extension additions --, ms-ac-correlated-report-list |
+ ms-ac-report-subject-entry | ms-ac-report-summary |
+ ms-ac-uncorrelated-report-list | ms-auto-action-error |
+ ms-auto-action-registration-identifier | ms-auto-action-subject-entry |
+ ms-auto-action-type | mt-certificate-selectors |
+ ms-deferred-delivery-cancellation-time | mt-deferred-delivery-time |
+ ms-deletion-time | mt-dl-exempted-recipients | mt-dl-expansion-prohibited |
+ mt-internal-trace-information | mt-latest-delivery-time |
+ ms-locally-originated | ms-marked-for-deletion | ms-message-group-name |
+ ms-message-notes | mt-message-submission-envelope |
+ mt-multiple-originator-certificates | ms-originated | ms-submission-error |
+ mt-originating-MTA-certificate | mt-originator-report-request |
+ mt-originator-return-address | mt-per-message-indicators |
+ mt-per-recipient-message-submission-fields |
+ mt-per-recipient-probe-submission-fields |
+ mt-probe-origin-authentication-check | mt-probe-submission-envelope |
+ mt-proof-of-submission | mt-recipient-certificate | ms-recipient-names |
+ mt-recipient-reassignment-prohibited | ms-signature-verification-status |
+ ms-storage-period | ms-storage-time | mt-trace-information}
+
+ContentSpecificAttributes X413ATTRIBUTE ::=
+ {...}
+
+-- Attribute-types
+ms-ac-correlated-report-list X413ATTRIBUTE ::= {
+ WITH ATTRIBUTE-SYNTAX ReportLocation,
+ NUMERATION multi-valued,
+ ID id-att-ac-correlated-report-list
+}
+
+ReportLocation ::= CHOICE {
+ no-correlated-reports [0] NULL,
+ location [1] SEQUENCE OF PerRecipientReport
+}
+
+PerRecipientReport ::= SEQUENCE {
+ report-entry [0] SequenceNumber,
+ position [1] INTEGER(1..ub-recipients) DEFAULT 1
+}
+
+ms-ac-report-subject-entry X413ATTRIBUTE ::= {
+ WITH ATTRIBUTE-SYNTAX SequenceNumber,
+ EQUALITY MATCHING-RULE integerMatch,
+ ORDERING MATCHING-RULE integerOrderingMatch,
+ NUMERATION single-valued,
+ ID id-att-ac-report-subject-entry
+}
+
+ms-ac-report-summary X413ATTRIBUTE ::= {
+ WITH ATTRIBUTE-SYNTAX ReportSummary,
+ EQUALITY MATCHING-RULE integerMatch,
+ ORDERING MATCHING-RULE integerOrderingMatch,
+ NUMERATION multi-valued,
+ ID id-att-ac-report-summary
+}
+
+ReportSummary ::= ENUMERATED {
+ no-report-requested(0) -- non-delivery report suppressed --,
+ no-report-received(1) -- non-delivery report requested --,
+ report-outstanding(2) -- delivery report requested --, delivery-cancelled(3),
+ delivery-report-from-another-recipient(4),
+ non-delivery-report-from-another-recipient(5),
+ delivery-report-from-intended-recipient(6),
+ non-delivery-report-from-intended-recipient(7)}
+
+ms-ac-uncorrelated-report-list X413ATTRIBUTE ::= {
+ WITH ATTRIBUTE-SYNTAX PerRecipientReport,
+ NUMERATION multi-valued,
+ ID id-att-ac-uncorrelated-report-list
+}
+
+ms-auto-action-error X413ATTRIBUTE ::= {
+ WITH ATTRIBUTE-SYNTAX AutoActionError,
+ NUMERATION single-valued,
+ ID id-att-auto-action-error
+}
+
+ms-auto-action-registration-identifier X413ATTRIBUTE ::= {
+ WITH ATTRIBUTE-SYNTAX INTEGER,
+ EQUALITY MATCHING-RULE integerMatch,
+ ORDERING MATCHING-RULE integerOrderingMatch,
+ NUMERATION single-valued,
+ ID id-att-auto-action-registration-identifier
+}
+
+ms-auto-action-subject-entry X413ATTRIBUTE ::= {
+ WITH ATTRIBUTE-SYNTAX SequenceNumber,
+ EQUALITY MATCHING-RULE integerMatch,
+ ORDERING MATCHING-RULE integerOrderingMatch,
+ NUMERATION single-valued,
+ ID id-att-auto-action-subject-entry
+}
+
+ms-auto-action-type X413ATTRIBUTE ::= {
+ WITH ATTRIBUTE-SYNTAX AutoActionType,
+ EQUALITY MATCHING-RULE objectIdentifierMatch,
+ NUMERATION single-valued,
+ ID id-att-auto-action-type
+}
+
+mt-certificate-selectors X413ATTRIBUTE ::= {
+ WITH ATTRIBUTE-SYNTAX CertificateSelectors,
+ NUMERATION single-valued,
+ ID id-att-certificate-selectors
+}
+
+ms-child-sequence-numbers X413ATTRIBUTE ::= {
+ WITH ATTRIBUTE-SYNTAX SequenceNumber,
+ NUMERATION multi-valued,
+ ID id-att-child-sequence-numbers
+}
+
+mt-content X413ATTRIBUTE ::= {
+ WITH ATTRIBUTE-SYNTAX Content,
+ NUMERATION single-valued,
+ ID id-att-content
+}
+
+mt-content-confidentiality-algorithm-identifier X413ATTRIBUTE ::= {
+ WITH ATTRIBUTE-SYNTAX AlgorithmIdentifier,
+ NUMERATION single-valued,
+ ID id-att-content-confidentiality-algorithm-identifier
+}
+
+mt-content-correlator X413ATTRIBUTE ::= {
+ WITH ATTRIBUTE-SYNTAX ContentCorrelator,
+ EQUALITY MATCHING-RULE contentCorrelatorMatch,
+ NUMERATION single-valued,
+ ID id-att-content-correlator
+}
+
+mt-content-identifier X413ATTRIBUTE ::= {
+ WITH ATTRIBUTE-SYNTAX ContentIdentifier,
+ EQUALITY MATCHING-RULE contentIdentifierMatch,
+ NUMERATION single-valued,
+ ID id-att-content-identifier
+}
+
+mt-content-integrity-check X413ATTRIBUTE ::= {
+ WITH ATTRIBUTE-SYNTAX ContentIntegrityCheck,
+ NUMERATION single-valued,
+ ID id-att-content-integrity-check
+}
+
+ms-content-length X413ATTRIBUTE ::= {
+ WITH ATTRIBUTE-SYNTAX ContentLength,
+ ORDERING MATCHING-RULE integerOrderingMatch,
+ NUMERATION single-valued,
+ ID id-att-content-length
+}
+
+ms-content-returned X413ATTRIBUTE ::= {
+ WITH ATTRIBUTE-SYNTAX BOOLEAN,
+ EQUALITY MATCHING-RULE booleanMatch,
+ NUMERATION single-valued,
+ ID id-att-content-returned
+}
+
+mt-content-type X413ATTRIBUTE ::= {
+ WITH ATTRIBUTE-SYNTAX OBJECT IDENTIFIER,
+ EQUALITY MATCHING-RULE objectIdentifierMatch,
+ NUMERATION single-valued,
+ ID id-att-content-type
+}
+
+mt-conversion-with-loss-prohibited X413ATTRIBUTE ::= {
+ WITH ATTRIBUTE-SYNTAX ConversionWithLossProhibited,
+ EQUALITY MATCHING-RULE integerMatch,
+ NUMERATION single-valued,
+ ID id-att-conversion-with-loss-prohibited
+}
+
+mt-converted-EITs X413ATTRIBUTE ::= {
+ WITH ATTRIBUTE-SYNTAX MS-EIT,
+ EQUALITY MATCHING-RULE objectIdentifierMatch,
+ NUMERATION multi-valued,
+ ID id-att-converted-EITs
+}
+
+ms-creation-time X413ATTRIBUTE ::= {
+ WITH ATTRIBUTE-SYNTAX CreationTime,
+ EQUALITY MATCHING-RULE uTCTimeMatch,
+ ORDERING MATCHING-RULE uTCTimeOrderingMatch,
+ NUMERATION single-valued,
+ ID id-att-creation-time
+}
+
+ms-deferred-delivery-cancellation-time X413ATTRIBUTE ::= {
+ WITH ATTRIBUTE-SYNTAX DeferredDeliveryCancellationTime,
+ EQUALITY MATCHING-RULE uTCTimeMatch,
+ ORDERING MATCHING-RULE uTCTimeOrderingMatch,
+ NUMERATION single-valued,
+ ID id-att-deferred-delivery-cancellation-time
+}
+
+DeferredDeliveryCancellationTime ::= UTCTime
+
+mt-deferred-delivery-time X413ATTRIBUTE ::= {
+ WITH ATTRIBUTE-SYNTAX DeferredDeliveryTime,
+ EQUALITY MATCHING-RULE uTCTimeMatch,
+ ORDERING MATCHING-RULE uTCTimeOrderingMatch,
+ NUMERATION single-valued,
+ ID id-att-deferred-delivery-time
+}
+
+ms-deletion-time X413ATTRIBUTE ::= {
+ WITH ATTRIBUTE-SYNTAX DeletionTime,
+ EQUALITY MATCHING-RULE uTCTimeMatch,
+ ORDERING MATCHING-RULE uTCTimeOrderingMatch,
+ NUMERATION single-valued,
+ ID id-att-deletion-time
+}
+
+DeletionTime ::= UTCTime
+
+ms-delivered-EITs X413ATTRIBUTE ::= {
+ WITH ATTRIBUTE-SYNTAX MS-EIT,
+ EQUALITY MATCHING-RULE objectIdentifierMatch,
+ NUMERATION multi-valued,
+ ID id-att-delivered-EITs
+}
+
+mt-delivery-flags X413ATTRIBUTE ::= {
+ WITH ATTRIBUTE-SYNTAX DeliveryFlags,
+ EQUALITY MATCHING-RULE bitStringMatch,
+ NUMERATION single-valued,
+ ID id-att-delivery-flags
+}
+
+mt-dl-exempted-recipients X413ATTRIBUTE ::= {
+ WITH ATTRIBUTE-SYNTAX ORName,
+ EQUALITY MATCHING-RULE oRNameMatch,
+ OTHER MATCHING-RULES
+ {oRNameElementsMatch | oRNameSubstringElementsMatch |
+ oRNameSingleElementMatch, ...},
+ NUMERATION multi-valued,
+ ID id-att-dl-exempted-recipients
+}
+
+mt-dl-expansion-history X413ATTRIBUTE ::= {
+ WITH ATTRIBUTE-SYNTAX DLExpansion,
+ OTHER MATCHING-RULES
+ {redirectionOrDLExpansionMatch | redirectionOrDLExpansionElementsMatch |
+ redirectionOrDLExpansionSubstringElementsMatch |
+ redirectionOrDLExpansionSingleElementMatch, ...},
+ NUMERATION multi-valued,
+ ID id-att-dl-expansion-history
+}
+
+mt-dl-expansion-prohibited X413ATTRIBUTE ::= {
+ WITH ATTRIBUTE-SYNTAX DLExpansionProhibited,
+ EQUALITY MATCHING-RULE integerMatch,
+ NUMERATION single-valued,
+ ID id-att-dl-expansion-prohibited
+}
+
+ms-entry-type X413ATTRIBUTE ::= {
+ WITH ATTRIBUTE-SYNTAX EntryType,
+ EQUALITY MATCHING-RULE integerMatch,
+ ORDERING MATCHING-RULE
+ integerOrderingMatch, -- rule not defined in 1988 Application Contexts
+
+ NUMERATION single-valued,
+ ID id-att-entry-type
+}
+
+mt-internal-trace-information X413ATTRIBUTE ::= {
+ WITH ATTRIBUTE-SYNTAX InternalTraceInformationElement,
+ NUMERATION multi-valued,
+ ID id-att-internal-trace-information
+}
+
+mt-latest-delivery-time X413ATTRIBUTE ::= {
+ WITH ATTRIBUTE-SYNTAX LatestDeliveryTime,
+ EQUALITY MATCHING-RULE uTCTimeMatch,
+ ORDERING MATCHING-RULE uTCTimeOrderingMatch,
+ NUMERATION single-valued,
+ ID id-att-latest-delivery-time
+}
+
+ms-locally-originated X413ATTRIBUTE ::= {
+ WITH ATTRIBUTE-SYNTAX NULL,
+ NUMERATION single-valued,
+ ID id-att-locally-originated
+}
+
+ms-marked-for-deletion X413ATTRIBUTE ::= {
+ WITH ATTRIBUTE-SYNTAX NULL,
+ NUMERATION single-valued,
+ ID id-att-marked-for-deletion
+}
+
+mt-message-delivery-envelope X413ATTRIBUTE ::= {
+ WITH ATTRIBUTE-SYNTAX MessageDeliveryEnvelope,
+ NUMERATION single-valued,
+ ID id-att-message-delivery-envelope
+}
+
+mt-message-delivery-time X413ATTRIBUTE ::= {
+ WITH ATTRIBUTE-SYNTAX MessageDeliveryTime,
+ EQUALITY MATCHING-RULE uTCTimeMatch,
+ ORDERING MATCHING-RULE uTCTimeOrderingMatch,
+ NUMERATION single-valued,
+ ID id-att-message-delivery-time
+}
+
+ms-message-group-name X413ATTRIBUTE ::= {
+ WITH ATTRIBUTE-SYNTAX MessageGroupName,
+ EQUALITY MATCHING-RULE mSStringListMatch,
+ OTHER MATCHING-RULES
+ {mSSingleSubstringListMatch | mSStringListElementsMatch |
+ mSSingleSubstringListElementsMatch | valueCountMatch, ...},
+ NUMERATION multi-valued,
+ ID id-att-message-group-name
+}
+
+mt-message-identifier X413ATTRIBUTE ::= {
+ WITH ATTRIBUTE-SYNTAX MTSIdentifier,
+ EQUALITY MATCHING-RULE
+ mTSIdentifierMatch, -- rule not defined in 1988 Application Contexts
+
+ NUMERATION single-valued,
+ ID id-att-message-identifier
+}
+
+ms-message-notes X413ATTRIBUTE ::= {
+ WITH ATTRIBUTE-SYNTAX GeneralString(SIZE (1..ub-message-notes-length)),
+ EQUALITY MATCHING-RULE mSStringMatch,
+ SUBSTRINGS MATCHING-RULE mSSubstringsMatch,
+ NUMERATION multi-valued,
+ ID id-att-message-notes
+}
+
+mt-message-origin-authentication-check X413ATTRIBUTE ::= {
+ WITH ATTRIBUTE-SYNTAX MessageOriginAuthenticationCheck,
+ NUMERATION single-valued,
+ ID id-att-message-origin-authentication-check
+}
+
+mt-message-security-label X413ATTRIBUTE ::= {
+ WITH ATTRIBUTE-SYNTAX MessageSecurityLabel,
+ NUMERATION single-valued,
+ ID id-att-message-security-label
+}
+
+mt-message-submission-envelope X413ATTRIBUTE ::= {
+ WITH ATTRIBUTE-SYNTAX MessageSubmissionEnvelope,
+ NUMERATION single-valued,
+ ID id-att-message-submission-envelope
+}
+
+mt-message-submission-time X413ATTRIBUTE ::= {
+ WITH ATTRIBUTE-SYNTAX MessageSubmissionTime,
+ EQUALITY MATCHING-RULE uTCTimeMatch,
+ ORDERING MATCHING-RULE uTCTimeOrderingMatch,
+ NUMERATION single-valued,
+ ID id-att-message-submission-time
+}
+
+mt-message-token X413ATTRIBUTE ::= {
+ WITH ATTRIBUTE-SYNTAX MessageToken,
+ NUMERATION single-valued,
+ ID id-att-message-token
+}
+
+ms-originated X413ATTRIBUTE ::= {
+ WITH ATTRIBUTE-SYNTAX NULL,
+ NUMERATION single-valued,
+ ID id-att-ms-originated
+}
+
+ms-submission-error X413ATTRIBUTE ::= {
+ WITH ATTRIBUTE-SYNTAX SubmissionError,
+ NUMERATION single-valued,
+ ID id-att-ms-submission-error
+}
+
+SubmissionError ::= CHOICE {
+ submission-control-violated [1] NULL,
+ originator-invalid [2] NULL,
+ recipient-improperly-specified [3] ImproperlySpecifiedRecipients,
+ element-of-service-not-subscribed [4] NULL,
+ inconsistent-request [11] NULL,
+ security-error [12] SecurityProblem,
+ unsupported-critical-function [13] NULL,
+ remote-bind-error [15] NULL,
+ service-error [27] ServiceErrorParameter,
+ message-group-error [30] MessageGroupErrorParameter,
+ ms-extension-error [31] MSExtensionErrorParameter,
+ entry-class-error [34] EntryClassErrorParameter
+}
+
+mt-multiple-originator-certificates X413ATTRIBUTE ::= {
+ WITH ATTRIBUTE-SYNTAX ExtendedCertificates,
+ NUMERATION single-valued,
+ ID id-att-multiple-originator-certificates
+}
+
+mt-original-EITs X413ATTRIBUTE ::= {
+ WITH ATTRIBUTE-SYNTAX MS-EIT,
+ EQUALITY MATCHING-RULE objectIdentifierMatch,
+ NUMERATION multi-valued,
+ ID id-att-original-EITs
+}
+
+mt-originally-intended-recipient-name X413ATTRIBUTE ::= {
+ WITH ATTRIBUTE-SYNTAX ORName,
+ EQUALITY MATCHING-RULE oRNameMatch,
+ OTHER MATCHING-RULES
+ {oRNameElementsMatch | oRNameSubstringElementsMatch |
+ oRNameSingleElementMatch, ...},
+ NUMERATION single-valued,
+ ID id-att-originally-intended-recipient-name
+}
+
+mt-originating-MTA-certificate X413ATTRIBUTE ::= {
+ WITH ATTRIBUTE-SYNTAX OriginatingMTACertificate,
+ NUMERATION single-valued,
+ ID id-att-originating-MTA-certificate
+}
+
+mt-originator-certificate X413ATTRIBUTE ::= {
+ WITH ATTRIBUTE-SYNTAX OriginatorCertificate,
+ NUMERATION single-valued,
+ ID id-att-originator-certificate
+}
+
+mt-originator-name X413ATTRIBUTE ::= {
+ WITH ATTRIBUTE-SYNTAX ORName,
+ EQUALITY MATCHING-RULE oRNameMatch,
+ OTHER MATCHING-RULES
+ {oRNameElementsMatch | oRNameSubstringElementsMatch |
+ oRNameSingleElementMatch, ...},
+ NUMERATION single-valued,
+ ID id-att-originator-name
+}
+
+mt-originator-report-request X413ATTRIBUTE ::= {
+ WITH ATTRIBUTE-SYNTAX OriginatorReportRequest,
+ NUMERATION multi-valued,
+ ID id-att-originator-report-request
+}
+
+mt-originator-return-address X413ATTRIBUTE ::= {
+ WITH ATTRIBUTE-SYNTAX OriginatorReturnAddress,
+ NUMERATION single-valued,
+ ID id-att-originator-return-address
+}
+
+mt-other-recipient-names X413ATTRIBUTE ::= {
+ WITH ATTRIBUTE-SYNTAX ORName,
+ EQUALITY MATCHING-RULE oRNameMatch,
+ OTHER MATCHING-RULES
+ {oRNameElementsMatch | oRNameSubstringElementsMatch |
+ oRNameSingleElementMatch, ...},
+ NUMERATION multi-valued,
+ ID id-att-other-recipient-names
+}
+
+ms-parent-sequence-number X413ATTRIBUTE ::= {
+ WITH ATTRIBUTE-SYNTAX SequenceNumber,
+ EQUALITY MATCHING-RULE integerMatch,
+ ORDERING MATCHING-RULE integerOrderingMatch,
+ NUMERATION single-valued,
+ ID id-att-parent-sequence-number
+}
+
+mt-per-message-indicators X413ATTRIBUTE ::= {
+ WITH ATTRIBUTE-SYNTAX PerMessageIndicators,
+ EQUALITY MATCHING-RULE bitStringMatch,
+ NUMERATION single-valued,
+ ID id-att-per-message-indicators
+}
+
+mt-per-recipient-message-submission-fields X413ATTRIBUTE ::= {
+ WITH ATTRIBUTE-SYNTAX PerRecipientMessageSubmissionFields,
+ NUMERATION multi-valued,
+ ID id-att-per-recipient-message-submission-fields
+}
+
+mt-per-recipient-probe-submission-fields X413ATTRIBUTE ::= {
+ WITH ATTRIBUTE-SYNTAX PerRecipientProbeSubmissionFields,
+ NUMERATION multi-valued,
+ ID id-att-per-recipient-probe-submission-fields
+}
+
+mt-per-recipient-report-delivery-fields X413ATTRIBUTE ::= {
+ WITH ATTRIBUTE-SYNTAX PerRecipientReportDeliveryFields,
+ NUMERATION multi-valued,
+ ID id-att-per-recipient-report-delivery-fields
+}
+
+mt-priority X413ATTRIBUTE ::= {
+ WITH ATTRIBUTE-SYNTAX Priority,
+ EQUALITY MATCHING-RULE integerMatch,
+ ORDERING MATCHING-RULE
+ integerOrderingMatch, -- rule not defined in 1988 Application Contexts
+
+ NUMERATION single-valued,
+ ID id-att-priority
+}
+
+mt-probe-origin-authentication-check X413ATTRIBUTE ::= {
+ WITH ATTRIBUTE-SYNTAX ProbeOriginAuthenticationCheck,
+ NUMERATION single-valued,
+ ID id-att-probe-origin-authentication-check
+}
+
+mt-probe-submission-envelope X413ATTRIBUTE ::= {
+ WITH ATTRIBUTE-SYNTAX ProbeSubmissionEnvelope,
+ NUMERATION single-valued,
+ ID id-att-probe-submission-envelope
+}
+
+mt-proof-of-delivery-request X413ATTRIBUTE ::= {
+ WITH ATTRIBUTE-SYNTAX ProofOfDeliveryRequest,
+ EQUALITY MATCHING-RULE
+ integerMatch, -- rule not defined in 1988 Application Contexts
+
+ NUMERATION single-valued,
+ ID id-att-proof-of-delivery-request
+}
+
+mt-proof-of-submission X413ATTRIBUTE ::= {
+ WITH ATTRIBUTE-SYNTAX ProofOfSubmission,
+ NUMERATION single-valued,
+ ID id-att-proof-of-submission
+}
+
+mt-recipient-certificate X413ATTRIBUTE ::= {
+ WITH ATTRIBUTE-SYNTAX ExtendedCertificates,
+ NUMERATION single-valued,
+ ID id-att-recipient-certificate
+}
+
+ms-recipient-names X413ATTRIBUTE ::= {
+ WITH ATTRIBUTE-SYNTAX ORName,
+ EQUALITY MATCHING-RULE oRNameMatch,
+ OTHER MATCHING-RULES
+ {oRNameElementsMatch | oRNameSubstringElementsMatch |
+ oRNameSingleElementMatch, ...},
+ NUMERATION multi-valued,
+ ID id-att-recipient-names
+}
+
+mt-recipient-reassignment-prohibited X413ATTRIBUTE ::= {
+ WITH ATTRIBUTE-SYNTAX RecipientReassignmentProhibited,
+ EQUALITY MATCHING-RULE integerMatch,
+ NUMERATION single-valued,
+ ID id-att-recipient-reassignment-prohibited
+}
+
+mt-redirection-history X413ATTRIBUTE ::= {
+ WITH ATTRIBUTE-SYNTAX Redirection,
+ OTHER MATCHING-RULES
+ {redirectionOrDLExpansionMatch | redirectionOrDLExpansionElementsMatch |
+ redirectionOrDLExpansionSubstringElementsMatch |
+ redirectionOrDLExpansionSingleElementMatch | redirectionReasonMatch,
+ ...},
+ NUMERATION multi-valued,
+ ID id-att-redirection-history
+}
+
+mt-report-delivery-envelope X413ATTRIBUTE ::= {
+ WITH ATTRIBUTE-SYNTAX ReportDeliveryEnvelope,
+ NUMERATION single-valued,
+ ID id-att-report-delivery-envelope
+}
+
+mt-reporting-DL-name X413ATTRIBUTE ::= {
+ WITH ATTRIBUTE-SYNTAX ReportingDLName,
+ EQUALITY MATCHING-RULE
+ oRNameMatch, -- rule not defined in 1988 Application Contexts
+
+ OTHER MATCHING-RULES
+ {oRNameElementsMatch | oRNameSubstringElementsMatch |
+ oRNameSingleElementMatch, ...},
+ NUMERATION single-valued,
+ ID id-att-reporting-DL-name
+}
+
+mt-reporting-MTA-certificate X413ATTRIBUTE ::= {
+ WITH ATTRIBUTE-SYNTAX ReportingMTACertificate,
+ NUMERATION single-valued,
+ ID id-att-reporting-MTA-certificate
+}
+
+mt-report-origin-authentication-check X413ATTRIBUTE ::= {
+ WITH ATTRIBUTE-SYNTAX ReportOriginAuthenticationCheck,
+ NUMERATION single-valued,
+ ID id-att-report-origin-authentication-check
+}
+
+ms-retrieval-status X413ATTRIBUTE ::= {
+ WITH ATTRIBUTE-SYNTAX RetrievalStatus,
+ EQUALITY MATCHING-RULE integerMatch,
+ NUMERATION single-valued,
+ ID id-att-retrieval-status
+}
+
+mt-security-classification X413ATTRIBUTE ::= {
+ WITH ATTRIBUTE-SYNTAX SecurityClassification,
+ EQUALITY MATCHING-RULE integerMatch,
+ NUMERATION single-valued,
+ ID id-att-security-classification
+}
+
+ms-sequence-number X413ATTRIBUTE ::= {
+ WITH ATTRIBUTE-SYNTAX SequenceNumber,
+ EQUALITY MATCHING-RULE integerMatch,
+ ORDERING MATCHING-RULE integerOrderingMatch,
+ NUMERATION single-valued,
+ ID id-att-sequence-number
+}
+
+ms-signature-verification-status X413ATTRIBUTE ::= {
+ WITH ATTRIBUTE-SYNTAX SignatureVerificationStatus,
+ NUMERATION single-valued,
+ ID id-att-signature-verification-status
+}
+
+SignatureVerificationStatus ::= SET {
+ content-integrity-check
+ [0] SignatureStatus DEFAULT signature-absent,
+ message-origin-authentication-check
+ [1] SignatureStatus DEFAULT signature-absent,
+ message-token
+ [2] SignatureStatus DEFAULT signature-absent,
+ report-origin-authentication-check
+ [3] SignatureStatus DEFAULT signature-absent,
+ proof-of-delivery
+ [4] SignatureStatus DEFAULT signature-absent,
+ proof-of-submission
+ [5] SignatureStatus DEFAULT signature-absent
+}
+
+SignatureStatus ::= INTEGER {
+ signature-absent(0), verification-in-progress(1), verification-succeeded(2),
+ verification-not-possible(3), content-converted(4), signature-encrypted(5),
+ algorithm-not-supported(6), certificate-not-obtainable(7),
+ verification-failed(8)}
+
+ms-storage-period X413ATTRIBUTE ::= {
+ WITH ATTRIBUTE-SYNTAX StoragePeriod,
+ EQUALITY MATCHING-RULE integerMatch,
+ ORDERING MATCHING-RULE integerOrderingMatch,
+ NUMERATION single-valued,
+ ID id-att-storage-period
+}
+
+StoragePeriod ::= INTEGER -- seconds
+
+ms-storage-time X413ATTRIBUTE ::= {
+ WITH ATTRIBUTE-SYNTAX StorageTime,
+ EQUALITY MATCHING-RULE uTCTimeMatch,
+ ORDERING MATCHING-RULE uTCTimeOrderingMatch,
+ NUMERATION single-valued,
+ ID id-att-storage-time
+}
+
+StorageTime ::= UTCTime
+
+mt-subject-submission-identifier X413ATTRIBUTE ::= {
+ WITH ATTRIBUTE-SYNTAX SubjectSubmissionIdentifier,
+ EQUALITY MATCHING-RULE
+ mTSIdentifierMatch, -- rule not defined in 1988 Application Contexts
+
+ NUMERATION single-valued,
+ ID id-att-subject-submission-identifier
+}
+
+mt-this-recipient-name X413ATTRIBUTE ::= {
+ WITH ATTRIBUTE-SYNTAX ORName,
+ EQUALITY MATCHING-RULE oRNameMatch,
+ OTHER MATCHING-RULES
+ {oRNameElementsMatch | oRNameSubstringElementsMatch |
+ oRNameSingleElementMatch, ...},
+ NUMERATION single-valued,
+ ID id-att-this-recipient-name
+}
+
+mt-trace-information X413ATTRIBUTE ::= {
+ WITH ATTRIBUTE-SYNTAX TraceInformationElement,
+ NUMERATION multi-valued,
+ ID id-att-trace-information
+}
+
+END -- of MSGeneralAttributeTypes
+
+-- Generated by Asnp, the ASN.1 pretty-printer of France Telecom R&D
+
diff --git a/lib/asn1/test/asn1_SUITE_data/x420/MSGeneralAutoActionTypes.asn b/lib/asn1/test/asn1_SUITE_data/x420/MSGeneralAutoActionTypes.asn
new file mode 100644
index 0000000000..eceae4ab44
--- /dev/null
+++ b/lib/asn1/test/asn1_SUITE_data/x420/MSGeneralAutoActionTypes.asn
@@ -0,0 +1,118 @@
+-- Module MSGeneralAutoActionTypes (X.413:06/1999)
+MSGeneralAutoActionTypes {joint-iso-itu-t mhs(6) ms(4) modules(0)
+ general-auto-action-types(3) version-1994(0)} DEFINITIONS ::=
+BEGIN
+
+-- Prologue
+-- Exports everything
+IMPORTS
+ -- AUTO-ACTION and AUTO-ACTION-ERROR information object classes
+ AUTO-ACTION,
+ AUTO-ACTION-ERROR,
+ -- MS abstract-service data-types and abstract-errors
+ EntryClass, EntryInformationSelection, EntryModification, Filter,
+ message-group-error, modify-error, service-error, SequenceNumber
+ --==
+ FROM MSAbstractService {joint-iso-itu-t mhs(6) ms(4) modules(0)
+ abstract-service(1) version-1999(1)}
+ -- MS Object Identifiers
+ id-aae-auto-alert-error, id-act-auto-alert, id-act-auto-correlate-reports,
+ id-act-auto-delete, id-act-auto-modify
+ --==
+ FROM MSObjectIdentifiers {joint-iso-itu-t mhs(6) ms(4) modules(0)
+ object-identifiers(0) version-1999(1)}
+ -- MS abstract-service upper bounds
+ ub-alert-addresses, ub-modifications, ub-supplementary-info-length
+ --==
+ FROM MSUpperBounds {joint-iso-itu-t mhs(6) ms(4) modules(0) upper-bounds(4)
+ version-1994(0)}
+ -- MTS abstract-service
+ security-error
+ --==
+ FROM MTSAbstractService {joint-iso-itu-t mhs(6) mts(3) modules(0)
+ mts-abstract-service(1) version-1999(1)};
+
+-- Auto-action table information object set
+AutoActionTable AUTO-ACTION ::=
+ {GeneralAutoActions | ContentSpecificAutoActions}
+
+GeneralAutoActions AUTO-ACTION ::=
+ {auto-alert, ... -- 1994 extension additions --, auto-modify |
+ auto-correlate-reports | auto-delete}
+
+ContentSpecificAutoActions AUTO-ACTION ::=
+ {...}
+
+-- Auto-action error table information object set
+AutoActionErrorTable AUTO-ACTION-ERROR ::=
+ {GeneralAutoActionErrors | ContentSpecificAutoActionErrors}
+
+GeneralAutoActionErrors AUTO-ACTION-ERROR ::=
+ {auto-alert-error | modify-error | service-error | security-error |
+ message-group-error, ... -- For future extension additions --}
+
+ContentSpecificAutoActionErrors AUTO-ACTION-ERROR ::=
+ {...}
+
+-- Auto-action-types
+auto-alert AUTO-ACTION ::= {
+ REGISTRATION PARAMETER IS AutoAlertRegistrationParameter
+ ERRORS {auto-alert-error}
+ IDENTIFIED BY id-act-auto-alert
+}
+
+AutoAlertRegistrationParameter ::= SET {
+ filter [0] Filter OPTIONAL,
+ alert-destinations
+ [1] SEQUENCE SIZE (1..ub-alert-addresses) OF AlertDestination OPTIONAL,
+ requested-attributes [2] EntryInformationSelection OPTIONAL,
+ -- 1994 extension
+ suppress-alert-destinations [3] BOOLEAN DEFAULT TRUE
+}
+
+AlertDestination ::= SEQUENCE {
+ alert-address EXTERNAL,
+ alert-qualifier OCTET STRING OPTIONAL
+}
+
+--
+auto-modify AUTO-ACTION ::= {
+ REGISTRATION PARAMETER IS AutoModifyRegistrationParameter
+ ERRORS
+ {security-error | service-error | modify-error | message-group-error}
+ IDENTIFIED BY id-act-auto-modify
+}
+
+AutoModifyRegistrationParameter ::= SET {
+ entry-class [0] EntryClass DEFAULT delivery,
+ filter [1] Filter OPTIONAL,
+ modifications [2] SEQUENCE SIZE (1..ub-modifications) OF EntryModification
+}
+
+--
+auto-correlate-reports AUTO-ACTION ::= {
+ IDENTIFIED BY id-act-auto-correlate-reports
+}
+
+--
+auto-delete AUTO-ACTION ::= {
+ ERRORS {security-error}
+ IDENTIFIED BY id-act-auto-delete
+}
+
+-- Auto-action errors
+auto-alert-error AUTO-ACTION-ERROR ::= {
+ PARAMETER SEQUENCE SIZE (1..ub-alert-addresses) OF AutoAlertErrorIndication
+ CODE global:id-aae-auto-alert-error
+}
+
+AutoAlertErrorIndication ::= SET {
+ failing-alert-destination [0] AlertDestination OPTIONAL,
+ supplementary-information
+ [1] GeneralString(SIZE (1..ub-supplementary-info-length)) OPTIONAL
+}
+
+END -- of MSGeneralAutoActionTypes
+
+-- Generated by Asnp, the ASN.1 pretty-printer of France Telecom R&D
+
diff --git a/lib/asn1/test/asn1_SUITE_data/x420/MSMatchingRules.asn b/lib/asn1/test/asn1_SUITE_data/x420/MSMatchingRules.asn
new file mode 100644
index 0000000000..37c894da86
--- /dev/null
+++ b/lib/asn1/test/asn1_SUITE_data/x420/MSMatchingRules.asn
@@ -0,0 +1,225 @@
+-- Module MSMatchingRules (X.413:06/1999)
+MSMatchingRules {joint-iso-itu-t mhs(6) ms(4) modules(0)
+ general-matching-rules(5) version-1999(1)} DEFINITIONS ::=
+BEGIN
+
+-- Prologue
+--Exports everything
+IMPORTS
+ -- MATCHING-RULE information object class and Directory matching-rules
+ MATCHING-RULE, objectIdentifierMatch
+ --==
+ FROM InformationFramework
+ bitStringMatch, booleanMatch, generalizedTimeMatch,
+ generalizedTimeOrderingMatch, integerMatch, integerOrderingMatch,
+ uTCTimeMatch, uTCTimeOrderingMatch
+ --==
+ FROM SelectedAttributeTypes
+
+ -- Matching-rule Object Identifiers
+ id-mr-content-correlator-match, id-mr-content-identifier-match,
+ id-mr-ms-single-substring-list-elements-match,
+ id-mr-ms-single-substring-list-match, id-mr-ms-single-substring-match,
+ id-mr-ms-substrings-match, id-mr-msstring-case-sensitive-match,
+ id-mr-msstring-list-elements-match, id-mr-msstring-list-match,
+ id-mr-msstring-match, id-mr-msstring-ordering-match,
+ id-mr-mts-identifier-match, id-mr-oraddress-elements-match,
+ id-mr-oraddress-match, id-mr-oraddress-substring-elements-match,
+ id-mr-orname-elements-match, id-mr-orname-match,
+ id-mr-orname-single-element-match, id-mr-orname-substring-elements-match,
+ id-mr-redirection-or-dl-expansion-elements-match,
+ id-mr-redirection-or-dl-expansion-match,
+ id-mr-redirection-or-dl-expansion-single-element-match,
+ id-mr-redirection-or-dl-expansion-substring-elements-match,
+ id-mr-redirection-reason-match, id-mr-value-count-match
+ --==
+ FROM MSObjectIdentifiers {joint-iso-itu-t mhs(6) ms(4) modules(0)
+ object-identifiers(0) version-1999(1)}
+ -- MS upper bounds
+ ub-attribute-values, ub-msstring-match
+ --==
+ FROM MSUpperBounds {joint-iso-itu-t mhs(6) ms(4) modules(0) upper-bounds(4)
+ version-1994(0)}
+ -- MTS abstract service
+ ContentCorrelator, ContentIdentifier, MTSIdentifier, ORAddress,
+ ORAddressAndOptionalDirectoryName, ORName, RedirectionReason
+ --==
+ FROM MTSAbstractService {joint-iso-itu-t mhs(6) mts(3) modules(0)
+ mts-abstract-service(1) version-1999(1)};
+
+-- Matching rule table information object set
+MatchingRuleTable MATCHING-RULE ::=
+ {GeneralMatchingRules | ContentSpecificMatchingRules}
+
+GeneralMatchingRules MATCHING-RULE ::=
+ {bitStringMatch | booleanMatch | contentIdentifierMatch | integerMatch |
+ integerOrderingMatch | mSStringCaseSensitiveMatch | objectIdentifierMatch |
+ oRNameMatch | uTCTimeMatch | uTCTimeOrderingMatch,
+ ... -- 1994 extension additions --, contentCorrelatorMatch |
+ generalizedTimeMatch | generalizedTimeOrderingMatch | mSSingleSubstringMatch
+ | mSStringCaseSensitiveMatch | mSStringListElementsMatch | mSStringListMatch
+ | mSStringMatch | mSStringOrderingMatch | mSSingleSubstringListElementsMatch
+ | mSSingleSubstringListMatch | mSSubstringsMatch | mTSIdentifierMatch |
+ oRAddressElementsMatch | oRAddressMatch | oRAddressSubstringElementsMatch |
+ oRNameElementsMatch | oRNameMatch | oRNameSingleElementMatch |
+ oRNameSubstringElementsMatch | redirectionOrDLExpansionElementsMatch |
+ redirectionOrDLExpansionMatch | redirectionOrDLExpansionSingleElementMatch |
+ redirectionOrDLExpansionSubstringElementsMatch | redirectionReasonMatch |
+ valueCountMatch}
+
+ContentSpecificMatchingRules MATCHING-RULE ::=
+ {...}
+
+-- MS String assertion-syntax
+MSString{INTEGER:maxSize} ::= CHOICE {
+ printable PrintableString(SIZE (1..maxSize)),
+ teletex TeletexString(SIZE (1..maxSize)),
+ general GeneralString(SIZE (1..maxSize)),
+ universal UniversalString(SIZE (1..maxSize)),
+ bmp BMPString(SIZE (1..maxSize))
+}
+
+-- String matching-rules
+mSStringMatch MATCHING-RULE ::= {
+ SYNTAX MSString {ub-msstring-match}
+ ID id-mr-msstring-match
+}
+
+mSStringOrderingMatch MATCHING-RULE ::= {
+ SYNTAX MSString {ub-msstring-match}
+ ID id-mr-msstring-ordering-match
+}
+
+mSSubstringsMatch MATCHING-RULE ::= {
+ SYNTAX SubstringAssertion
+ ID id-mr-ms-substrings-match
+}
+
+SubstringAssertion ::=
+ SEQUENCE OF
+ CHOICE {initial [0] MSString{ub-msstring-match},
+ any [1] MSString{ub-msstring-match},
+ final [2] MSString{ub-msstring-match}}
+
+-- at most one initial and one final component
+mSSingleSubstringMatch MATCHING-RULE ::= {
+ SYNTAX MSString {ub-msstring-match}
+ ID id-mr-ms-single-substring-match
+}
+
+mSStringCaseSensitiveMatch MATCHING-RULE ::= {
+ SYNTAX MSString {ub-msstring-match}
+ ID id-mr-msstring-case-sensitive-match
+}
+
+mSStringListMatch MATCHING-RULE ::= {
+ SYNTAX SEQUENCE OF MSString{ub-msstring-match}
+ ID id-mr-msstring-list-match
+}
+
+mSStringListElementsMatch MATCHING-RULE ::= {
+ SYNTAX SEQUENCE OF MSString{ub-msstring-match}
+ ID id-mr-msstring-list-elements-match
+}
+
+mSSingleSubstringListMatch MATCHING-RULE ::= {
+ SYNTAX SEQUENCE OF MSString{ub-msstring-match}
+ ID id-mr-ms-single-substring-list-match
+}
+
+mSSingleSubstringListElementsMatch MATCHING-RULE ::= {
+ SYNTAX SEQUENCE OF MSString{ub-msstring-match}
+ ID id-mr-ms-single-substring-list-elements-match
+}
+
+-- Syntax-based matching-rule
+valueCountMatch MATCHING-RULE ::= {
+ SYNTAX INTEGER(1..ub-attribute-values)
+ ID id-mr-value-count-match
+}
+
+-- Matching-rules for complex Message Store attributes
+-- OR-address matching-rules
+oRAddressMatch MATCHING-RULE ::= {
+ SYNTAX ORAddress
+ ID id-mr-oraddress-match
+}
+
+oRAddressElementsMatch MATCHING-RULE ::= {
+ SYNTAX ORAddress
+ ID id-mr-oraddress-elements-match
+}
+
+oRAddressSubstringElementsMatch MATCHING-RULE ::= {
+ SYNTAX ORAddress
+ ID id-mr-oraddress-substring-elements-match
+}
+
+-- OR-name matching-rules
+oRNameMatch MATCHING-RULE ::= {SYNTAX ORName
+ ID id-mr-orname-match
+}
+
+oRNameElementsMatch MATCHING-RULE ::= {
+ SYNTAX ORName
+ ID id-mr-orname-elements-match
+}
+
+oRNameSubstringElementsMatch MATCHING-RULE ::= {
+ SYNTAX ORName
+ ID id-mr-orname-substring-elements-match
+}
+
+oRNameSingleElementMatch MATCHING-RULE ::= {
+ SYNTAX MSString {ub-msstring-match}
+ ID id-mr-orname-single-element-match
+}
+
+-- Redirection or DL-expansion matching rules
+redirectionOrDLExpansionMatch MATCHING-RULE ::= {
+ SYNTAX ORAddressAndOptionalDirectoryName
+ ID id-mr-redirection-or-dl-expansion-match
+}
+
+redirectionOrDLExpansionElementsMatch MATCHING-RULE ::= {
+ SYNTAX ORAddressAndOptionalDirectoryName
+ ID id-mr-redirection-or-dl-expansion-elements-match
+}
+
+redirectionOrDLExpansionSingleElementMatch MATCHING-RULE ::= {
+ SYNTAX MSString {ub-msstring-match}
+ ID id-mr-redirection-or-dl-expansion-single-element-match
+}
+
+redirectionOrDLExpansionSubstringElementsMatch MATCHING-RULE ::= {
+ SYNTAX ORAddressAndOptionalDirectoryName
+ ID id-mr-redirection-or-dl-expansion-substring-elements-match
+}
+
+redirectionReasonMatch MATCHING-RULE ::= {
+ SYNTAX RedirectionReason
+ ID id-mr-redirection-reason-match
+}
+
+-- MTS-identifier matching rule
+mTSIdentifierMatch MATCHING-RULE ::= {
+ SYNTAX MTSIdentifier
+ ID id-mr-mts-identifier-match
+}
+
+-- Content-correlator matching rule
+contentCorrelatorMatch MATCHING-RULE ::= {
+ SYNTAX ContentCorrelator
+ ID id-mr-content-correlator-match
+}
+
+-- Content-identifier matching rule
+contentIdentifierMatch MATCHING-RULE ::= {
+ SYNTAX ContentIdentifier
+ ID id-mr-content-identifier-match
+}
+
+END -- of MSMatchingRules
+
+-- Generated by Asnp, the ASN.1 pretty-printer of France Telecom R&D
+
diff --git a/lib/asn1/test/asn1_SUITE_data/x420/MSObjectIdentifiers.asn b/lib/asn1/test/asn1_SUITE_data/x420/MSObjectIdentifiers.asn
new file mode 100644
index 0000000000..df194f838c
--- /dev/null
+++ b/lib/asn1/test/asn1_SUITE_data/x420/MSObjectIdentifiers.asn
@@ -0,0 +1,322 @@
+-- Module MSObjectIdentifiers (X.413:06/1999)
+MSObjectIdentifiers {joint-iso-itu-t mhs(6) ms(4) modules(0)
+ object-identifiers(0) version-1999(1)} DEFINITIONS ::=
+BEGIN
+
+-- Prologue
+-- Exports everything
+IMPORTS
+ ID, id-ms
+ --==
+ FROM MHSObjectIdentifiers {joint-iso-itu-t mhs(6) arch(5) modules(0)
+ object-identifiers(0) version-1999(1)};
+
+-- Categories
+id-mod -- modules -- ID ::= {id-ms 0}
+
+id-ot -- objects -- ID ::= {id-ms 1}
+
+id-pt -- port types -- ID ::= {id-ms 2}
+
+id-att -- attribute types -- ID ::= {id-ms 3}
+
+id-act -- auto-action types -- ID ::= {id-ms 4}
+
+id-crt -- contracts -- ID ::= {id-ms 5}
+
+id-cp -- connection-packages -- ID ::= {id-ms 6}
+
+id-aae -- auto-action-errors-- ID ::= {id-ms 7}
+
+id-mr -- matching-rules -- ID ::= {id-ms 8}
+
+id-ext -- extensions -- ID ::= {id-ms 9}
+
+id-alg -- algorithms -- ID ::= {id-ms 10}
+
+-- Modules
+id-mod-object-identifiers ID ::= {id-mod 0} -- not definitive
+
+id-mod-abstract-service ID ::= {id-mod 1} -- not definitive
+
+id-mod-attribute-types ID ::= {id-mod 2} -- not definitive
+
+id-mod-action-types ID ::= {id-mod 3} -- not definitive
+
+id-mod-upper-bounds ID ::= {id-mod 4} -- not definitive
+
+id-mod-matching-rules ID ::= {id-mod 5} -- not definitive
+
+-- Objects
+id-ot-ms ID ::= {id-ot 0}
+
+id-ot-ms-user ID ::= {id-ot 1}
+
+-- Port types
+id-pt-retrieval-88 ID ::= {id-pt 0}
+
+id-pt-retrieval-94 ID ::= {id-pt 1}
+
+id-pt-ms-submission ID ::= {id-pt 2}
+
+-- Contracts
+id-crt-ms-access-88 ID ::= {id-crt 0}
+
+id-crt-ms-access-94 ID ::= {id-crt 1}
+
+-- Connection-packages
+id-cp-ms-connection ID ::= {id-cp 0}
+
+-- Attribute-types
+id-att-ac-correlated-report-list ID ::= {id-att 42}
+
+id-att-ac-report-subject-entry ID ::= {id-att 76}
+
+id-att-ac-report-summary ID ::= {id-att 43}
+
+id-att-ac-uncorrelated-report-list ID ::= {id-att 44}
+
+id-att-auto-action-error ID ::= {id-att 46}
+
+id-att-auto-action-registration-identifier ID ::= {id-att 47}
+
+id-att-auto-action-subject-entry ID ::= {id-att 48}
+
+id-att-auto-action-type ID ::= {id-att 49}
+
+id-att-certificate-selectors ID ::= {id-att 80}
+
+id-att-child-sequence-numbers ID ::= {id-att 0}
+
+id-att-content ID ::= {id-att 1}
+
+id-att-content-confidentiality-algorithm-identifier ID ::= {id-att 2}
+
+id-att-content-correlator ID ::= {id-att 3}
+
+id-att-content-identifier ID ::= {id-att 4}
+
+id-att-content-integrity-check ID ::= {id-att 5}
+
+id-att-content-length ID ::= {id-att 6}
+
+id-att-content-returned ID ::= {id-att 7}
+
+id-att-content-type ID ::= {id-att 8}
+
+id-att-conversion-with-loss-prohibited ID ::= {id-att 9}
+
+id-att-converted-EITs ID ::= {id-att 10}
+
+id-att-creation-time ID ::= {id-att 11}
+
+id-att-deferred-delivery-cancellation-time ID ::= {id-att 50}
+
+id-att-deferred-delivery-time ID ::= {id-att 51}
+
+id-att-deletion-time ID ::= {id-att 52}
+
+id-att-delivered-EITs ID ::= {id-att 12}
+
+id-att-delivery-flags ID ::= {id-att 13}
+
+id-att-dl-exempted-recipients ID ::= {id-att 78}
+
+id-att-dl-expansion-history ID ::= {id-att 14}
+
+id-att-dl-expansion-prohibited ID ::= {id-att 53}
+
+id-att-entry-type ID ::= {id-att 16}
+
+id-att-internal-trace-information ID ::= {id-att 54}
+
+id-att-latest-delivery-time ID ::= {id-att 55}
+
+id-att-locally-originated ID ::= {id-att 77}
+
+id-att-marked-for-deletion ID ::= {id-att 56}
+
+id-att-message-delivery-envelope ID ::= {id-att 18}
+
+id-att-message-delivery-time ID ::= {id-att 20}
+
+id-att-message-group-name ID ::= {id-att 57}
+
+id-att-message-identifier ID ::= {id-att 19}
+
+id-att-message-notes ID ::= {id-att 58}
+
+id-att-message-origin-authentication-check ID ::= {id-att 21}
+
+id-att-message-security-label ID ::= {id-att 22}
+
+id-att-message-submission-envelope ID ::= {id-att 59}
+
+id-att-message-submission-time ID ::= {id-att 23}
+
+id-att-message-token ID ::= {id-att 24}
+
+id-att-ms-originated ID ::= {id-att 60}
+
+id-att-ms-submission-error ID ::= {id-att 61}
+
+id-att-multiple-originator-certificates ID ::= {id-att 81}
+
+id-att-original-EITs ID ::= {id-att 25}
+
+id-att-originally-intended-recipient-name ID ::= {id-att 17}
+
+id-att-originating-MTA-certificate ID ::= {id-att 62}
+
+id-att-originator-certificate ID ::= {id-att 26}
+
+id-att-originator-name ID ::= {id-att 27}
+
+id-att-originator-report-request ID ::= {id-att 63}
+
+id-att-originator-return-address ID ::= {id-att 64}
+
+id-att-other-recipient-names ID ::= {id-att 28}
+
+id-att-parent-sequence-number ID ::= {id-att 29}
+
+id-att-per-message-indicators ID ::= {id-att 65}
+
+id-att-per-recipient-message-submission-fields ID ::= {id-att 66}
+
+id-att-per-recipient-probe-submission-fields ID ::= {id-att 67}
+
+id-att-per-recipient-report-delivery-fields ID ::= {id-att 30}
+
+id-att-priority ID ::= {id-att 31}
+
+id-att-probe-origin-authentication-check ID ::= {id-att 68}
+
+id-att-probe-submission-envelope ID ::= {id-att 69}
+
+id-att-proof-of-delivery-request ID ::= {id-att 32}
+
+id-att-proof-of-submission ID ::= {id-att 70}
+
+id-att-recipient-certificate ID ::= {id-att 82}
+
+id-att-recipient-names ID ::= {id-att 71}
+
+id-att-recipient-reassignment-prohibited ID ::= {id-att 72}
+
+id-att-redirection-history ID ::= {id-att 33}
+
+id-att-report-delivery-envelope ID ::= {id-att 34}
+
+id-att-reporting-DL-name ID ::= {id-att 35}
+
+id-att-reporting-MTA-certificate ID ::= {id-att 36}
+
+id-att-report-origin-authentication-check ID ::= {id-att 37}
+
+id-att-retrieval-status ID ::= {id-att 15}
+
+id-att-security-classification ID ::= {id-att 38}
+
+id-att-sequence-number ID ::= {id-att 39}
+
+id-att-signature-verification-status ID ::= {id-att 79}
+
+id-att-storage-period ID ::= {id-att 73}
+
+id-att-storage-time ID ::= {id-att 74}
+
+id-att-subject-submission-identifier ID ::= {id-att 40}
+
+id-att-this-recipient-name ID ::= {id-att 41}
+
+id-att-trace-information ID ::= {id-att 75}
+
+-- Auto-action-types
+id-act-ipm-auto-forward ID ::=
+ {id-act 0} -- Reserved for use in
+
+-- ITU-T Rec. X.420 |
+-- ISO/IEC 10021-7
+id-act-auto-alert ID ::= {id-act 1}
+
+id-act-auto-correlate-reports ID ::= {id-act 2}
+
+id-act-auto-delete ID ::= {id-act 3}
+
+id-act-auto-modify ID ::= {id-act 4}
+
+-- Auto-action errors
+id-aae-auto-alert-error ID ::= {id-aae 0}
+
+-- Matching-rules
+id-mr-content-correlator-match ID ::= {id-mr 1}
+
+id-mr-content-identifier-match ID ::= {id-mr 2}
+
+id-mr-ms-single-substring-list-elements-match ID ::= {id-mr 3}
+
+id-mr-ms-single-substring-list-match ID ::= {id-mr 4}
+
+id-mr-ms-single-substring-match ID ::= {id-mr 5}
+
+id-mr-ms-substrings-match ID ::= {id-mr 6}
+
+id-mr-msstring-case-sensitive-match ID ::= {id-mr 7}
+
+id-mr-msstring-list-elements-match ID ::= {id-mr 8}
+
+id-mr-msstring-list-match ID ::= {id-mr 9}
+
+id-mr-msstring-match ID ::= {id-mr 10}
+
+id-mr-msstring-ordering-match ID ::= {id-mr 11}
+
+id-mr-mts-identifier-match ID ::= {id-mr 12}
+
+id-mr-oraddress-elements-match ID ::= {id-mr 13}
+
+id-mr-oraddress-match ID ::= {id-mr 14}
+
+id-mr-oraddress-substring-elements-match ID ::= {id-mr 15}
+
+id-mr-orname-elements-match ID ::= {id-mr 16}
+
+id-mr-orname-match ID ::= {id-mr 17}
+
+id-mr-orname-single-element-match ID ::= {id-mr 18}
+
+id-mr-orname-substring-elements-match ID ::= {id-mr 19}
+
+id-mr-redirection-or-dl-expansion-elements-match ID ::= {id-mr 20}
+
+id-mr-redirection-or-dl-expansion-match ID ::= {id-mr 21}
+
+id-mr-redirection-or-dl-expansion-single-element-match ID ::= {id-mr 25}
+
+id-mr-redirection-or-dl-expansion-substring-elements-match ID ::= {id-mr 22}
+
+id-mr-redirection-reason-match ID ::= {id-mr 23}
+
+id-mr-value-count-match ID ::= {id-mr 24}
+
+-- Extensions
+id-ext-modify-capability ID ::= {id-ext 0}
+
+id-ext-modify-retrieval-status-capability ID ::= {id-ext 1}
+
+id-ext-originator-certificate-selectors-override ID ::= {id-ext 2}
+
+id-ext-originator-token ID ::= {id-ext 3}
+
+id-ext-protected-change-credentials ID ::= {id-ext 4}
+
+id-ext-protected-change-credentials-capability ID ::= {id-ext 5}
+
+-- Algorithms
+id-alg-password-xor ID ::= {id-alg 0}
+
+END -- of MSObjectIdentifiers
+
+-- Generated by Asnp, the ASN.1 pretty-printer of France Telecom R&D
+
diff --git a/lib/asn1/test/asn1_SUITE_data/x420/MSUpperBounds.asn b/lib/asn1/test/asn1_SUITE_data/x420/MSUpperBounds.asn
new file mode 100644
index 0000000000..6494fbd3ef
--- /dev/null
+++ b/lib/asn1/test/asn1_SUITE_data/x420/MSUpperBounds.asn
@@ -0,0 +1,77 @@
+-- Module MSUpperBounds (X.413:06/1999)
+MSUpperBounds {joint-iso-itu-t mhs(6) ms(4) modules(0) upper-bounds(4)
+ version-1994(0)} DEFINITIONS ::=
+BEGIN
+
+-- Exports everything
+IMPORTS -- nothing -- ;
+
+-- Upper Bounds
+ub-alert-addresses INTEGER ::= 16
+
+ub-attribute-values INTEGER ::= 32767 -- (215 - 1) the largest integer
+
+-- representable in 16 bits
+ub-attributes-supported INTEGER ::= 1024
+
+ub-auto-action-errors INTEGER ::= 32767 -- (215 - 1) the largest integer
+
+-- representable in 16 bits
+ub-auto-actions INTEGER ::= 128
+
+ub-auto-registrations INTEGER ::= 1024
+
+ub-default-registrations INTEGER ::= 1024
+
+ub-entry-classes INTEGER ::= 128
+
+ub-entry-types INTEGER ::= 16
+
+ub-error-reasons INTEGER ::= 16
+
+ub-extensions INTEGER ::= 32
+
+ub-group-depth INTEGER ::= 64
+
+ub-group-descriptor-length INTEGER ::= 256
+
+ub-group-part-length INTEGER ::= 128
+
+ub-information-bases INTEGER ::= 16
+
+ub-matching-rules INTEGER ::= 1024
+
+ub-message-groups INTEGER ::= 8192
+
+ub-message-notes-length INTEGER ::= 1024
+
+ub-messages INTEGER ::= 2147483647 -- (231 - 1) the largest integer
+
+-- representable in 32 bits
+ub-modifications INTEGER ::=
+ 32767 -- (215 - 1) the largest integer
+
+-- representable in 16 bits
+ub-msstring-match INTEGER ::= 512
+
+ub-per-auto-action INTEGER ::= 32767 -- (215 - 1) the largest integer
+
+-- representable in 16 bits
+ub-per-entry INTEGER ::= 1024
+
+ub-service-information-length INTEGER ::= 2048
+
+ub-summaries INTEGER ::= 16
+
+ub-supplementary-info-length INTEGER ::= 256
+
+ub-ua-registration-identifier-length INTEGER ::= 32
+
+ub-ua-registrations INTEGER ::= 128
+
+ub-restrictions INTEGER ::= 16
+
+END -- of MSUpperBounds
+
+-- Generated by Asnp, the ASN.1 pretty-printer of France Telecom R&D
+
diff --git a/lib/asn1/test/asn1_SUITE_data/x420/MTAAbstractService.asn b/lib/asn1/test/asn1_SUITE_data/x420/MTAAbstractService.asn
new file mode 100644
index 0000000000..38035c77ae
--- /dev/null
+++ b/lib/asn1/test/asn1_SUITE_data/x420/MTAAbstractService.asn
@@ -0,0 +1,481 @@
+-- Module MTAAbstractService (X.411:06/1999)
+MTAAbstractService {joint-iso-itu-t mhs(6) mts(3) modules(0)
+ mta-abstract-service(2) version-1999(1)} DEFINITIONS IMPLICIT TAGS ::=
+BEGIN
+
+-- Prologue
+-- Exports everything
+IMPORTS
+ -- Remote Operations
+ CONNECTION-PACKAGE, CONTRACT
+ --==
+ FROM Remote-Operations-Information-Objects {joint-iso-itu-t
+ remote-operations(4) informationObjects(5) version1(0)}
+ emptyUnbind
+ --==
+ FROM Remote-Operations-Useful-Definitions {joint-iso-itu-t
+ remote-operations(4) useful-definitions(7) version1(0)}
+ -- MTS Abstract Service Parameters
+ ABSTRACT-ERROR, ABSTRACT-OPERATION, administration, AdministrationDomainName,
+ certificate-selectors, certificate-selectors-override, Content,
+ ContentIdentifier, ContentLength, ContentType,
+ content-confidentiality-algorithm-identifier, content-correlator,
+ content-integrity-check, conversion-with-loss-prohibited,
+ ConvertedEncodedInformationTypes, CountryName, DeferredDeliveryTime,
+ delivery, dl-exempted-recipients, dl-expansion-history,
+ dl-expansion-prohibited, ExplicitConversion, EXTENSION, ExtensionField{},
+ GlobalDomainIdentifier, InitiatorCredentials, latest-delivery-time,
+ message-origin-authentication-check, message-security-label, message-token,
+ MHS-OBJECT, MTAName, MTSIdentifier, multiple-originator-certificates,
+ ORAddressAndOptionalDirectoryName, OriginalEncodedInformationTypes,
+ originator-and-DL-expansion-history, originator-certificate,
+ originator-return-address, PerMessageIndicators, physical-delivery-modes,
+ physical-delivery-report-request, physical-forwarding-address,
+ physical-forwarding-address-request, physical-forwarding-prohibited,
+ physical-rendition-attributes, PORT, Priority, PrivateDomainIdentifier,
+ PrivateExtensions, probe-origin-authentication-check, proof-of-delivery,
+ proof-of-delivery-request, recipient-certificate,
+ recipient-number-for-advice, recipient-reassignment-prohibited,
+ redirection-history, registered-mail-type, reporting-DL-name,
+ reporting-MTA-certificate, reporting-MTA-name, ReportType,
+ report-origin-authentication-check, requested-delivery-method,
+ ResponderCredentials, SecurityContext, submission,
+ SupplementaryInformation, Time
+ --==
+ FROM MTSAbstractService {joint-iso-itu-t mhs(6) mts(3) modules(0)
+ mts-abstract-service(1) version-1999(1)}
+ -- IPM Information Objects
+ IPMPerRecipientEnvelopeExtensions
+ --==
+ FROM IPMSInformationObjects {joint-iso-itu-t mhs(6) ipms(1) modules(0)
+ information-objects(2) version-1999(1)}
+ -- Object Identifiers
+ id-cp-mta-connect, id-ct-mta-transfer, id-ot-mta, id-pt-transfer
+ --==
+ FROM MTSObjectIdentifiers {joint-iso-itu-t mhs(6) mts(3) modules(0)
+ object-identifiers(0) version-1999(1)}
+ -- Upper Bounds
+ ub-bit-options, ub-integer-options, ub-recipients, ub-transfers
+ --==
+ FROM MTSUpperBounds {joint-iso-itu-t mhs(6) mts(3) modules(0)
+ upper-bounds(3) version-1999(1)};
+
+-- Objects
+mta MHS-OBJECT ::= {BOTH {mta-transfer}
+ ID id-ot-mta
+}
+
+-- Contracts
+mta-transfer CONTRACT ::= {
+ CONNECTION mta-connect
+ OPERATIONS OF {transfer}
+ ID id-ct-mta-transfer
+}
+
+-- Connection package
+mta-connect CONNECTION-PACKAGE ::= {
+ BIND mta-bind
+ UNBIND mta-unbind
+ ID id-cp-mta-connect
+}
+
+-- Ports
+transfer PORT ::= {
+ OPERATIONS {message-transfer | probe-transfer | report-transfer}
+ ID id-pt-transfer
+}
+
+-- MTA-bind and MTA-unbind
+mta-bind ABSTRACT-OPERATION ::= {
+ ARGUMENT MTABindArgument
+ RESULT MTABindResult
+ ERRORS {mta-bind-error}
+}
+
+mta-unbind ABSTRACT-OPERATION ::= emptyUnbind
+
+MTABindArgument ::= CHOICE {
+ unauthenticated NULL, -- if no authentication is required
+ authenticated
+ [1] SET {-- if authentication is required--initiator-name
+ [0] MTAName,
+ initiator-credentials
+ [1] InitiatorCredentials
+ (WITH COMPONENTS {
+ ...,
+ protected ABSENT
+ }),
+ security-context
+ [2] SecurityContext OPTIONAL
+ }
+}
+
+MTABindResult ::= CHOICE {
+ unauthenticated NULL, -- if no authentication is required
+ authenticated
+ [1] SET {-- if authentication is required--responder-name
+ [0] MTAName,
+ responder-credentials
+ [1] ResponderCredentials
+ (WITH COMPONENTS {
+ ...,
+ protected ABSENT
+ })}
+}
+
+mta-bind-error ABSTRACT-ERROR ::= {
+ PARAMETER
+ INTEGER {busy(0), authentication-error(2), unacceptable-dialogue-mode(3),
+ unacceptable-security-context(4),
+ inadequate-association-confidentiality(5)}(0..ub-integer-options)
+}
+
+-- Transfer Port
+message-transfer ABSTRACT-OPERATION ::= {ARGUMENT Message
+}
+
+probe-transfer ABSTRACT-OPERATION ::= {ARGUMENT Probe
+}
+
+report-transfer ABSTRACT-OPERATION ::= {ARGUMENT Report
+}
+
+Message ::= SEQUENCE {envelope MessageTransferEnvelope,
+ content Content
+}
+
+Probe ::= ProbeTransferEnvelope
+
+Report ::= SEQUENCE {
+ envelope ReportTransferEnvelope,
+ content ReportTransferContent
+}
+
+-- Message Transfer Envelope
+MessageTransferEnvelope ::= SET {
+ COMPONENTS OF PerMessageTransferFields,
+ per-recipient-fields
+ [2] SEQUENCE SIZE (1..ub-recipients) OF PerRecipientMessageTransferFields
+}
+
+PerMessageTransferFields ::= SET {
+ message-identifier MessageIdentifier,
+ originator-name OriginatorName,
+ original-encoded-information-types OriginalEncodedInformationTypes OPTIONAL,
+ content-type ContentType,
+ content-identifier ContentIdentifier OPTIONAL,
+ priority Priority DEFAULT normal,
+ per-message-indicators PerMessageIndicators DEFAULT {},
+ deferred-delivery-time [0] DeferredDeliveryTime OPTIONAL,
+ per-domain-bilateral-information
+ [1] SEQUENCE SIZE (1..ub-transfers) OF PerDomainBilateralInformation
+ OPTIONAL,
+ trace-information TraceInformation,
+ extensions
+ [3] SET OF ExtensionField{{MessageTransferExtensions}} DEFAULT {}
+}
+
+MessageTransferExtensions EXTENSION ::=
+ {-- May contain the following extensions, private extensions, and future standardised extensions,
+ -- at most one instance of each extension type:
+ recipient-reassignment-prohibited | dl-expansion-prohibited |
+ conversion-with-loss-prohibited | latest-delivery-time |
+ originator-return-address | originator-certificate |
+ content-confidentiality-algorithm-identifier |
+ message-origin-authentication-check | message-security-label |
+ content-correlator | dl-exempted-recipients | certificate-selectors |
+ multiple-originator-certificates | dl-expansion-history |
+ internal-trace-information | PrivateExtensions, ...}
+
+PerRecipientMessageTransferFields ::= SET {
+ recipient-name RecipientName,
+ originally-specified-recipient-number
+ [0] OriginallySpecifiedRecipientNumber,
+ per-recipient-indicators [1] PerRecipientIndicators,
+ explicit-conversion [2] ExplicitConversion OPTIONAL,
+ extensions
+ [3] SET OF ExtensionField{{PerRecipientMessageTransferExtensions}}
+ DEFAULT {}
+}
+
+PerRecipientMessageTransferExtensions EXTENSION ::=
+ {-- May contain the following extensions, private extensions, and future standardised extensions,
+ -- at most one instance of each extension type:
+ originator-requested-alternate-recipient | requested-delivery-method |
+ physical-forwarding-prohibited | physical-forwarding-address-request |
+ physical-delivery-modes | registered-mail-type | recipient-number-for-advice
+ | physical-rendition-attributes | physical-delivery-report-request |
+ message-token | content-integrity-check | proof-of-delivery-request |
+ certificate-selectors-override | recipient-certificate | redirection-history
+ | IPMPerRecipientEnvelopeExtensions | PrivateExtensions, ...}
+
+-- Probe Transfer Envelope
+ProbeTransferEnvelope ::= SET {
+ COMPONENTS OF PerProbeTransferFields,
+ per-recipient-fields
+ [2] SEQUENCE SIZE (1..ub-recipients) OF PerRecipientProbeTransferFields
+}
+
+PerProbeTransferFields ::= SET {
+ probe-identifier ProbeIdentifier,
+ originator-name OriginatorName,
+ original-encoded-information-types OriginalEncodedInformationTypes OPTIONAL,
+ content-type ContentType,
+ content-identifier ContentIdentifier OPTIONAL,
+ content-length [0] ContentLength OPTIONAL,
+ per-message-indicators PerMessageIndicators DEFAULT {},
+ per-domain-bilateral-information
+ [1] SEQUENCE SIZE (1..ub-transfers) OF PerDomainBilateralInformation
+ OPTIONAL,
+ trace-information TraceInformation,
+ extensions
+ [3] SET OF ExtensionField{{ProbeTransferExtensions}} DEFAULT {}
+}
+
+ProbeTransferExtensions EXTENSION ::=
+ {-- May contain the following extensions, private extensions, and future standardised extensions,
+ -- at most one instance of each extension type:
+ recipient-reassignment-prohibited | dl-expansion-prohibited |
+ conversion-with-loss-prohibited | originator-certificate |
+ message-security-label | content-correlator |
+ probe-origin-authentication-check | internal-trace-information |
+ PrivateExtensions, ...}
+
+PerRecipientProbeTransferFields ::= SET {
+ recipient-name RecipientName,
+ originally-specified-recipient-number
+ [0] OriginallySpecifiedRecipientNumber,
+ per-recipient-indicators [1] PerRecipientIndicators,
+ explicit-conversion [2] ExplicitConversion OPTIONAL,
+ extensions
+ [3] SET OF ExtensionField{{PerRecipientProbeTransferExtensions}}
+ DEFAULT {}
+}
+
+PerRecipientProbeTransferExtensions EXTENSION ::=
+ {-- May contain the following extensions, private extensions, and future standardised extensions,
+ -- at most one instance of each extension type:
+ originator-requested-alternate-recipient | requested-delivery-method |
+ physical-rendition-attributes | redirection-history | PrivateExtensions,
+ ...}
+
+-- Report Transfer Envelope
+ReportTransferEnvelope ::= SET {
+ report-identifier ReportIdentifier,
+ report-destination-name ReportDestinationName,
+ trace-information TraceInformation,
+ extensions
+ [1] SET OF ExtensionField{{ReportTransferEnvelopeExtensions}} DEFAULT {}
+}
+
+ReportTransferEnvelopeExtensions EXTENSION ::=
+ {-- May contain the following extensions, private extensions, and future standardised extensions,
+ -- at most one instance of each extension type:
+ message-security-label | redirection-history |
+ originator-and-DL-expansion-history | reporting-DL-name |
+ reporting-MTA-certificate | report-origin-authentication-check |
+ internal-trace-information | reporting-MTA-name | PrivateExtensions,
+ ...}
+
+-- Report Transfer Content
+ReportTransferContent ::= SET {
+ COMPONENTS OF PerReportTransferFields,
+ per-recipient-fields
+ [0] SEQUENCE SIZE (1..ub-recipients) OF PerRecipientReportTransferFields
+}
+
+PerReportTransferFields ::= SET {
+ subject-identifier SubjectIdentifier,
+ subject-intermediate-trace-information
+ SubjectIntermediateTraceInformation OPTIONAL,
+ original-encoded-information-types
+ OriginalEncodedInformationTypes OPTIONAL,
+ content-type ContentType OPTIONAL,
+ content-identifier ContentIdentifier OPTIONAL,
+ returned-content [1] Content OPTIONAL,
+ additional-information [2] AdditionalInformation OPTIONAL,
+ extensions
+ [3] SET OF ExtensionField{{ReportTransferContentExtensions}} DEFAULT {}
+}
+
+ReportTransferContentExtensions EXTENSION ::=
+ {-- May contain the following extensions, private extensions, and future standardised extensions,
+ -- at most one instance of each extension type:
+ content-correlator | PrivateExtensions, ...}
+
+PerRecipientReportTransferFields ::= SET {
+ actual-recipient-name [0] ActualRecipientName,
+ originally-specified-recipient-number
+ [1] OriginallySpecifiedRecipientNumber,
+ per-recipient-indicators [2] PerRecipientIndicators,
+ last-trace-information [3] LastTraceInformation,
+ originally-intended-recipient-name
+ [4] OriginallyIntendedRecipientName OPTIONAL,
+ supplementary-information [5] SupplementaryInformation OPTIONAL,
+ extensions
+ [6] SET OF ExtensionField{{PerRecipientReportTransferExtensions}}
+ DEFAULT {}
+}
+
+PerRecipientReportTransferExtensions EXTENSION ::=
+ {-- May contain the following extensions, private extensions, and future standardised extensions,
+ -- at most one instance of each extension type:
+ redirection-history | physical-forwarding-address | recipient-certificate |
+ proof-of-delivery | PrivateExtensions, ...}
+
+-- Envelope & Report Content Fields
+MessageIdentifier ::= MTSIdentifier
+
+OriginatorName ::= ORAddressAndOptionalDirectoryName
+
+PerDomainBilateralInformation ::= SEQUENCE {
+ COMPONENTS OF BILATERAL.&id,
+ bilateral-information BILATERAL.&Type
+}
+
+BILATERAL ::= CLASS {&id BilateralDomain UNIQUE,
+ &Type
+}WITH SYNTAX {&Type,
+ IDENTIFIED BY &id
+}
+
+BilateralDomain ::= SEQUENCE {
+ country-name CountryName,
+ domain
+ CHOICE {administration-domain-name AdministrationDomainName,
+ private-domain
+ SEQUENCE {administration-domain-name
+ [0] AdministrationDomainName,
+ private-domain-identifier
+ [1] PrivateDomainIdentifier}}
+}
+
+RecipientName ::= ORAddressAndOptionalDirectoryName
+
+OriginallySpecifiedRecipientNumber ::= INTEGER(1..ub-recipients)
+
+PerRecipientIndicators ::= BIT STRING {
+ responsibility(0),
+ -- responsible 'one', not-responsible 'zero'
+ originating-MTA-report(1),
+ originating-MTA-non-delivery-report(2),
+ -- either originating-MTA-report, or originating-MTA-non-delivery-report,
+ -- or both, shall be 'one':
+ -- originating-MTA-report bit 'one' requests a 'report';
+ -- originating-MTA-non-delivery-report bit 'one' requests a 'non-delivery-report';
+ -- both bits 'one' requests an 'audited-report';
+ -- bits 0 - 2 'don't care' for Report Transfer Content
+ originator-report(3),
+ originator-non-delivery-report(4),
+ -- at most one bit shall be 'one':
+ -- originator-report bit 'one' requests a 'report';
+ -- originator-non-delivery-report bit 'one' requests a 'non-delivery-report';
+ -- both bits 'zero' requests 'no-report'
+ reserved-5(5), reserved-6(6), reserved-7(7)
+
+-- reserved- bits 5 - 7 shall be 'zero' --}(SIZE (8..ub-bit-options))
+
+ProbeIdentifier ::= MTSIdentifier
+
+ReportIdentifier ::= MTSIdentifier
+
+ReportDestinationName ::= ORAddressAndOptionalDirectoryName
+
+SubjectIdentifier ::= MessageOrProbeIdentifier
+
+MessageOrProbeIdentifier ::= MTSIdentifier
+
+SubjectIntermediateTraceInformation ::= TraceInformation
+
+-- AdditionalInformation is retained for backwards compatibility only,
+-- and use in new systems is strongly deprecated
+ADDITIONAL ::= CLASS {&Type
+}
+
+AdditionalInformation ::=
+ ADDITIONAL.&Type -- maximum ub-additional-info octets including all encoding
+
+ActualRecipientName ::= ORAddressAndOptionalDirectoryName
+
+LastTraceInformation ::= SET {
+ arrival-time [0] ArrivalTime,
+ converted-encoded-information-types
+ ConvertedEncodedInformationTypes OPTIONAL,
+ report-type [1] ReportType
+}
+
+OriginallyIntendedRecipientName ::= ORAddressAndOptionalDirectoryName
+
+-- Extension Fields
+originator-requested-alternate-recipient EXTENSION ::= {
+ OriginatorRequestedAlternateRecipient,
+ IDENTIFIED BY standard-extension:2
+}
+
+OriginatorRequestedAlternateRecipient ::= ORAddressAndOptionalDirectoryName
+
+trace-information EXTENSION ::= {
+ TraceInformation,
+ IDENTIFIED BY standard-extension:37
+}
+
+internal-trace-information EXTENSION ::= {
+ InternalTraceInformation,
+ IDENTIFIED BY standard-extension:38
+}
+
+InternalTraceInformation ::=
+ SEQUENCE SIZE (1..ub-transfers) OF InternalTraceInformationElement
+
+InternalTraceInformationElement ::= SEQUENCE {
+ global-domain-identifier GlobalDomainIdentifier,
+ mta-name MTAName,
+ mta-supplied-information MTASuppliedInformation
+}
+
+MTASuppliedInformation ::= SET {
+ arrival-time [0] ArrivalTime,
+ routing-action [2] RoutingAction,
+ attempted CHOICE {mta MTAName,
+ domain GlobalDomainIdentifier} OPTIONAL,
+ -- additional-actions --COMPONENTS OF InternalAdditionalActions
+}
+
+InternalAdditionalActions ::= AdditionalActions
+
+-- Common Parameter Types
+TraceInformation ::=
+ [APPLICATION 9] SEQUENCE SIZE (1..ub-transfers) OF TraceInformationElement
+
+TraceInformationElement ::= SEQUENCE {
+ global-domain-identifier GlobalDomainIdentifier,
+ domain-supplied-information DomainSuppliedInformation
+}
+
+DomainSuppliedInformation ::= SET {
+ arrival-time [0] ArrivalTime,
+ routing-action [2] RoutingAction,
+ attempted-domain GlobalDomainIdentifier OPTIONAL,
+ -- additional-actions --COMPONENTS OF AdditionalActions
+}
+
+AdditionalActions ::= SET {
+ deferred-time [1] DeferredTime OPTIONAL,
+ converted-encoded-information-types
+ ConvertedEncodedInformationTypes OPTIONAL,
+ other-actions [3] OtherActions DEFAULT {}
+}
+
+RoutingAction ::= ENUMERATED {relayed(0), rerouted(1)}
+
+DeferredTime ::= Time
+
+ArrivalTime ::= Time
+
+OtherActions ::= BIT STRING {redirected(0), dl-operation(1)
+}(SIZE (0..ub-bit-options))
+
+END -- of MTA Abstract Service
+
+-- Generated by Asnp, the ASN.1 pretty-printer of France Telecom R&D
+
diff --git a/lib/asn1/test/asn1_SUITE_data/x420/MTSAbstractService.asn b/lib/asn1/test/asn1_SUITE_data/x420/MTSAbstractService.asn
new file mode 100644
index 0000000000..68a5118bc8
--- /dev/null
+++ b/lib/asn1/test/asn1_SUITE_data/x420/MTSAbstractService.asn
@@ -0,0 +1,2366 @@
+-- Module MTSAbstractService (X.411:06/1999)
+MTSAbstractService {joint-iso-itu-t mhs(6) mts(3) modules(0)
+ mts-abstract-service(1) version-1999(1)} DEFINITIONS IMPLICIT TAGS ::=
+BEGIN
+
+-- Prologue
+-- Exports everything
+IMPORTS
+ -- Remote Operations
+ CONNECTION-PACKAGE, CONTRACT, ERROR, OPERATION, OPERATION-PACKAGE,
+ ROS-OBJECT-CLASS
+ --==
+ FROM Remote-Operations-Information-Objects {joint-iso-itu-t
+ remote-operations(4) informationObjects(5) version1(0)}
+ emptyUnbind
+ --==
+ FROM Remote-Operations-Useful-Definitions {joint-iso-itu-t
+ remote-operations(4) useful-definitions(7) version1(0)}
+ -- MTA Abstract Service
+ internal-trace-information, trace-information
+ --==
+ FROM MTAAbstractService {joint-iso-itu-t mhs(6) mts(3) modules(0)
+ mta-abstract-service(2) version-1999(1)}
+ -- MS Abstract Service Extension
+ forwarding-request
+ --==
+ FROM MSAbstractService {joint-iso-itu-t mhs(6) ms(4) modules(0)
+ abstract-service(1) version-1999(1)}
+ -- IPM Information Objects
+ IPMPerRecipientEnvelopeExtensions
+ --==
+ FROM IPMSInformationObjects {joint-iso-itu-t mhs(6) ipms(1) modules(0)
+ information-objects(2) version-1999(1)}
+ -- Object Identifiers
+ id-att-physicalRendition-basic, id-cp-mts-connect, id-ct-mts-access,
+ id-ct-mts-forced-access, id-ot-mts, id-ot-mts-user, id-pt-administration,
+ id-pt-delivery, id-pt-submission, id-tok-asymmetricToken
+ --==
+ FROM MTSObjectIdentifiers {joint-iso-itu-t mhs(6) mts(3) modules(0)
+ object-identifiers(0) version-1999(1)}
+ -- Operation and Error Codes
+ err-control-violates-registration,
+ err-deferred-delivery-cancellation-rejected, err-delivery-control-violated,
+ err-element-of-service-not-subscribed, err-inconsistent-request,
+ err-message-submission-identifier-invalid,
+ err-new-credentials-unacceptable,
+ err-old-credentials-incorrectly-specified, err-operation-refused,
+ err-originator-invalid, err-recipient-improperly-specified,
+ err-register-rejected, err-remote-bind-error, err-security-error,
+ err-submission-control-violated, err-unsupported-critical-function,
+ op-cancel-deferred-delivery, op-change-credentials, op-delivery-control,
+ op-message-delivery, op-message-submission, op-probe-submission,
+ op-register, op-report-delivery, op-submission-control
+ --==
+ FROM MTSAccessProtocol {joint-iso-itu-t mhs(6) protocols(0) modules(0)
+ mts-access-protocol(1) version-1999(1)}
+ -- Directory Definitions
+ Name
+ --==
+ FROM InformationFramework
+ PresentationAddress
+ --==
+ FROM SelectedAttributeTypes
+ ALGORITHM, AlgorithmIdentifier, Certificates, ENCRYPTED{}, SIGNATURE{},
+ SIGNED{}
+ --==
+ FROM AuthenticationFramework
+
+ -- Certificate Extensions
+ CertificateAssertion
+ --==
+ FROM CertificateExtensions
+
+ -- Upper Bounds
+ ub-bit-options, ub-built-in-content-type,
+ ub-built-in-encoded-information-types, ub-certificates,
+ ub-common-name-length, ub-content-id-length, ub-content-length,
+ ub-content-types, ub-country-name-alpha-length,
+ ub-country-name-numeric-length, ub-deliverable-class, ub-diagnostic-codes,
+ ub-dl-expansions, ub-domain-defined-attributes,
+ ub-domain-defined-attribute-type-length,
+ ub-domain-defined-attribute-value-length, ub-domain-name-length,
+ ub-encoded-information-types, ub-extension-attributes, ub-extension-types,
+ ub-e163-4-number-length, ub-e163-4-sub-address-length,
+ ub-generation-qualifier-length, ub-given-name-length, ub-initials-length,
+ ub-integer-options, ub-local-id-length, ub-mta-name-length,
+ ub-mts-user-types, ub-numeric-user-id-length, ub-organization-name-length,
+ ub-organizational-units, ub-organizational-unit-name-length,
+ ub-orig-and-dl-expansions, ub-password-length, ub-pds-name-length,
+ ub-pds-parameter-length, ub-pds-physical-address-lines,
+ ub-postal-code-length, ub-privacy-mark-length, ub-queue-size,
+ ub-reason-codes, ub-recipients, ub-recipient-number-for-advice-length,
+ ub-redirections, ub-redirection-classes, ub-restrictions,
+ ub-security-categories, ub-security-labels, ub-security-problems,
+ ub-supplementary-info-length, ub-surname-length, ub-terminal-id-length,
+ ub-tsap-id-length, ub-unformatted-address-length,
+ ub-universal-generation-qualifier-length, ub-universal-given-name-length,
+ ub-universal-initials-length, ub-universal-surname-length,
+ ub-x121-address-length
+ --==
+ FROM MTSUpperBounds {joint-iso-itu-t mhs(6) mts(3) modules(0)
+ upper-bounds(3) version-1999(1)};
+
+operationObject1 OPERATION ::= {LINKED {operationObject2}
+}
+
+operationObject2 OPERATION ::= {LINKED {operationObject3}
+}
+
+operationObject3 OPERATION ::= {LINKED {operationObject4}
+}
+
+operationObject4 OPERATION ::= {LINKED {...}
+}
+
+-- Objects
+MHS-OBJECT ::= ROS-OBJECT-CLASS
+
+mts MHS-OBJECT ::= {
+ INITIATES {mts-forced-access-contract}
+ RESPONDS {mts-access-contract}
+ ID id-ot-mts
+}
+
+mts-user MHS-OBJECT ::= {
+ INITIATES {mts-access-contract}
+ RESPONDS {mts-forced-access-contract}
+ ID id-ot-mts-user
+}
+
+-- Contracts
+mts-access-contract CONTRACT ::= {
+ CONNECTION mts-connect
+ INITIATOR CONSUMER OF {submission | delivery | administration}
+ ID id-ct-mts-access
+}
+
+mts-forced-access-contract CONTRACT ::= {
+ CONNECTION mts-connect
+ RESPONDER CONSUMER OF {submission | delivery | administration}
+ ID id-ct-mts-forced-access
+}
+
+-- Connection package
+mts-connect CONNECTION-PACKAGE ::= {
+ BIND mts-bind
+ UNBIND mts-unbind
+ ID id-cp-mts-connect
+}
+
+-- Ports
+PORT ::= OPERATION-PACKAGE
+
+submission PORT ::= {
+ OPERATIONS {operationObject1, ...}
+ CONSUMER INVOKES
+ {message-submission | probe-submission | cancel-deferred-delivery, ...}
+ SUPPLIER INVOKES {submission-control, ...}
+ ID id-pt-submission
+}
+
+delivery PORT ::= {
+ OPERATIONS {operationObject1, ...}
+ CONSUMER INVOKES {delivery-control, ...}
+ SUPPLIER INVOKES {message-delivery | report-delivery, ...}
+ ID id-pt-delivery
+}
+
+administration PORT ::= {
+ OPERATIONS {change-credentials, ...}
+ CONSUMER INVOKES {register, ...}
+ SUPPLIER INVOKES {operationObject1, ...}
+ ID id-pt-administration
+}
+
+-- MTS-bind and MTS-unbind
+ABSTRACT-OPERATION ::= OPERATION
+
+ABSTRACT-ERROR ::= ERROR
+
+mts-bind ABSTRACT-OPERATION ::= {
+ ARGUMENT MTSBindArgument
+ RESULT MTSBindResult
+ ERRORS {mts-bind-error}
+}
+
+MTSBindArgument ::= SET {
+ initiator-name ObjectName,
+ messages-waiting [1] EXPLICIT MessagesWaiting OPTIONAL,
+ initiator-credentials [2] InitiatorCredentials,
+ security-context [3] SecurityContext OPTIONAL,
+ ...,
+ extensions
+ [5] SET OF ExtensionField{{MTSBindExtensions}} DEFAULT {}
+}
+
+MTSBindExtensions EXTENSION ::= {PrivateExtensions, ...}
+
+-- May contain private extensions and future standardised extensions
+MTSBindResult ::= SET {
+ responder-name ObjectName,
+ messages-waiting [1] EXPLICIT MessagesWaiting OPTIONAL,
+ responder-credentials [2] ResponderCredentials,
+ ...,
+ extensions
+ [5] SET OF ExtensionField{{MTSBindResultExtensions}} DEFAULT {}
+}
+
+MTSBindResultExtensions EXTENSION ::= {PrivateExtensions, ...}
+
+-- May contain private extensions and future standardised extensions
+mts-bind-error ABSTRACT-ERROR ::= {
+ PARAMETER
+ INTEGER {busy(0), authentication-error(2), unacceptable-dialogue-mode(3),
+ unacceptable-security-context(4),
+ inadequate-association-confidentiality(5)}(0..ub-integer-options)
+}
+
+mts-unbind ABSTRACT-OPERATION ::= emptyUnbind
+
+-- Association Control Parameters
+ObjectName ::= CHOICE {
+ user-agent ORAddressAndOptionalDirectoryName,
+ mTA [0] MTAName,
+ message-store [4] ORAddressAndOptionalDirectoryName
+}
+
+MessagesWaiting ::= SET {
+ urgent [0] DeliveryQueue,
+ normal [1] DeliveryQueue,
+ non-urgent [2] DeliveryQueue
+}
+
+DeliveryQueue ::= SET {
+ messages [0] INTEGER(0..ub-queue-size),
+ octets [1] INTEGER(0..ub-content-length) OPTIONAL
+}
+
+InitiatorCredentials ::= Credentials
+
+ResponderCredentials ::= Credentials
+
+Credentials ::= CHOICE {
+ simple Password,
+ strong [0] StrongCredentials,
+ ...,
+ protected [1] ProtectedPassword
+}
+
+Password ::= CHOICE {
+ ia5-string IA5String(SIZE (0..ub-password-length)),
+ octet-string OCTET STRING(SIZE (0..ub-password-length))
+}
+
+StrongCredentials ::= SET {
+ bind-token [0] Token OPTIONAL,
+ certificate [1] Certificates OPTIONAL,
+ ...,
+ certificate-selector [2] CertificateAssertion OPTIONAL
+}
+
+ProtectedPassword ::= SET {
+ signature
+ SIGNATURE{SET {password Password,
+ time1 [0] UTCTime OPTIONAL,
+ time2 [1] UTCTime OPTIONAL,
+ random1 [2] BIT STRING OPTIONAL,
+ random2 [3] BIT STRING OPTIONAL}},
+ time1 [0] UTCTime OPTIONAL,
+ time2 [1] UTCTime OPTIONAL,
+ random1 [2] BIT STRING OPTIONAL,
+ random2 [3] BIT STRING OPTIONAL
+}
+
+SecurityContext ::= SET SIZE (1..ub-security-labels) OF SecurityLabel
+
+-- Submission Port
+message-submission ABSTRACT-OPERATION ::= {
+ ARGUMENT MessageSubmissionArgument
+ RESULT MessageSubmissionResult
+ ERRORS
+ {submission-control-violated | element-of-service-not-subscribed |
+ originator-invalid | recipient-improperly-specified |
+ inconsistent-request | security-error | unsupported-critical-function |
+ remote-bind-error}
+ LINKED {operationObject1, ...}
+ INVOKE PRIORITY {4 | 6 | 7}
+ CODE op-message-submission
+}
+
+MessageSubmissionArgument ::= SEQUENCE {
+ envelope MessageSubmissionEnvelope,
+ content Content
+}
+
+MessageSubmissionResult ::= SET {
+ message-submission-identifier MessageSubmissionIdentifier,
+ message-submission-time [0] MessageSubmissionTime,
+ content-identifier ContentIdentifier OPTIONAL,
+ extensions
+ [1] SET OF ExtensionField{{MessageSubmissionResultExtensions}} DEFAULT {}
+}
+
+MessageSubmissionResultExtensions EXTENSION ::=
+ {-- May contain the following extensions, private extensions, and future standardised extensions,
+ -- at most one instance of each extension type:
+ originating-MTA-certificate | proof-of-submission | PrivateExtensions,
+ ...}
+
+probe-submission ABSTRACT-OPERATION ::= {
+ ARGUMENT ProbeSubmissionArgument
+ RESULT ProbeSubmissionResult
+ ERRORS
+ {submission-control-violated | element-of-service-not-subscribed |
+ originator-invalid | recipient-improperly-specified |
+ inconsistent-request | security-error | unsupported-critical-function |
+ remote-bind-error}
+ LINKED {operationObject1, ...}
+ INVOKE PRIORITY {5}
+ CODE op-probe-submission
+}
+
+ProbeSubmissionArgument ::= ProbeSubmissionEnvelope
+
+ProbeSubmissionResult ::= SET {
+ probe-submission-identifier ProbeSubmissionIdentifier,
+ probe-submission-time [0] ProbeSubmissionTime,
+ content-identifier ContentIdentifier OPTIONAL,
+ extensions
+ [1] SET OF ExtensionField{{ProbeResultExtensions}} DEFAULT {}
+}
+
+ProbeResultExtensions EXTENSION ::= {PrivateExtensions, ...}
+
+-- May contain private extensions and future standardised extensions,
+-- at most one instance of each extension type
+cancel-deferred-delivery ABSTRACT-OPERATION ::= {
+ ARGUMENT CancelDeferredDeliveryArgument
+ RESULT CancelDeferredDeliveryResult
+ ERRORS
+ {deferred-delivery-cancellation-rejected |
+ message-submission-identifier-invalid | remote-bind-error}
+ LINKED {operationObject1, ...}
+ INVOKE PRIORITY {3}
+ CODE op-cancel-deferred-delivery
+}
+
+CancelDeferredDeliveryArgument ::= MessageSubmissionIdentifier
+
+CancelDeferredDeliveryResult ::= NULL
+
+submission-control ABSTRACT-OPERATION ::= {
+ ARGUMENT SubmissionControlArgument
+ RESULT SubmissionControlResult
+ ERRORS {security-error | remote-bind-error}
+ LINKED {operationObject1, ...}
+ INVOKE PRIORITY {3}
+ CODE op-submission-control
+}
+
+SubmissionControlArgument ::= SubmissionControls
+
+SubmissionControlResult ::= Waiting
+
+submission-control-violated ABSTRACT-ERROR ::= {
+ PARAMETER NULL
+ CODE err-submission-control-violated
+}
+
+element-of-service-not-subscribed ABSTRACT-ERROR ::= {
+ PARAMETER NULL
+ CODE err-element-of-service-not-subscribed
+}
+
+deferred-delivery-cancellation-rejected ABSTRACT-ERROR ::= {
+ PARAMETER NULL
+ CODE err-deferred-delivery-cancellation-rejected
+}
+
+originator-invalid ABSTRACT-ERROR ::= {
+ PARAMETER NULL
+ CODE err-originator-invalid
+}
+
+recipient-improperly-specified ABSTRACT-ERROR ::= {
+ PARAMETER ImproperlySpecifiedRecipients
+ CODE err-recipient-improperly-specified
+}
+
+ImproperlySpecifiedRecipients ::=
+ SEQUENCE SIZE (1..ub-recipients) OF RecipientName
+
+message-submission-identifier-invalid ABSTRACT-ERROR ::= {
+ PARAMETER NULL
+ CODE err-message-submission-identifier-invalid
+}
+
+inconsistent-request ABSTRACT-ERROR ::= {
+ PARAMETER NULL
+ CODE err-inconsistent-request
+}
+
+security-error ABSTRACT-ERROR ::= {
+ PARAMETER SecurityProblem
+ CODE err-security-error
+}
+
+SecurityProblem ::= INTEGER {
+ assemby-instructions-conflict-with-security-services(0),
+ authentication-problem(1), authentication-failure-on-subject-message(2),
+ confidentiality-association-problem(3), decryption-failed(4),
+ decryption-key-unobtainable(5), failure-of-proof-of-message(6),
+ forbidden-user-security-label-register(7),
+ incompatible-change-with-original-security-context(8),
+ integrity-failure-on-subject-message(9), invalid-security-label(10),
+ invalid-security-label-update(11), key-failure(12),
+ mandatory-parameter-absence(13), operation-security-failure(14),
+ redirection-prohibited(15), refused-alternate-recipient-name(16),
+ repudiation-failure-of-message(17),
+ responder-credentials-checking-problem(18), security-context-failure(19),
+ security-context-problem(20), security-policy-violation(21),
+ security-services-refusal(22), token-decryption-failed(23), token-error(24),
+ unable-to-aggregate-security-labels(25), unauthorised-dl-name(26),
+ unauthorised-entry-class(27),
+ unauthorised-originally-intended-recipient-name(28),
+ unauthorised-originator-name(29), unauthorised-recipient-name(30),
+ unauthorised-security-label-update(31), unauthorised-user-name(32),
+ unknown-security-label(33), unsupported-algorithm-identifier(34),
+ unsupported-security-policy(35)}(0..ub-security-problems)
+
+unsupported-critical-function ABSTRACT-ERROR ::= {
+ PARAMETER NULL
+ CODE err-unsupported-critical-function
+}
+
+remote-bind-error ABSTRACT-ERROR ::= {
+ PARAMETER NULL
+ CODE err-remote-bind-error
+}
+
+-- Submission Port Parameters
+MessageSubmissionIdentifier ::= MTSIdentifier
+
+MessageSubmissionTime ::= Time
+
+ProbeSubmissionIdentifier ::= MTSIdentifier
+
+ProbeSubmissionTime ::= Time
+
+SubmissionControls ::=
+ Controls
+ (WITH COMPONENTS {
+ ...,
+ permissible-content-types ABSENT,
+ permissible-encoded-information-types ABSENT
+ })
+
+Waiting ::= SET {
+ waiting-operations [0] Operations DEFAULT {},
+ waiting-messages [1] WaitingMessages DEFAULT {},
+ waiting-content-types
+ [2] SET SIZE (0..ub-content-types) OF ContentType DEFAULT {},
+ waiting-encoded-information-types EncodedInformationTypes OPTIONAL
+}
+
+Operations ::= BIT STRING {
+ probe-submission-or-report-delivery(0),
+ message-submission-or-message-delivery(1)}(SIZE (0..ub-bit-options))
+
+-- holding 'one', not-holding 'zero'
+WaitingMessages ::= BIT STRING {
+ long-content(0), low-priority(1), other-security-labels(2)
+}(SIZE (0..ub-bit-options))
+
+-- Delivery Port
+message-delivery ABSTRACT-OPERATION ::= {
+ ARGUMENT MessageDeliveryArgument
+ RESULT MessageDeliveryResult
+ ERRORS
+ {delivery-control-violated | security-error |
+ unsupported-critical-function}
+ LINKED {operationObject1, ...}
+ INVOKE PRIORITY {4 | 6 | 7}
+ CODE op-message-delivery
+}
+
+MessageDeliveryArgument ::= SEQUENCE {
+ COMPONENTS OF MessageDeliveryEnvelope,
+ content Content
+}
+
+MessageDeliveryResult ::= SET {
+ recipient-certificate [0] RecipientCertificate OPTIONAL,
+ proof-of-delivery [1] IMPLICIT ProofOfDelivery OPTIONAL,
+ ...,
+ extensions
+ [2] SET OF ExtensionField{{MessageDeliveryResultExtensions}} DEFAULT {}
+}
+
+MessageDeliveryResultExtensions EXTENSION ::= {PrivateExtensions, ...}
+
+-- May contain private extensions and future standardised extensions
+report-delivery ABSTRACT-OPERATION ::= {
+ ARGUMENT ReportDeliveryArgument
+ RESULT ReportDeliveryResult
+ ERRORS
+ {delivery-control-violated | security-error |
+ unsupported-critical-function}
+ LINKED {operationObject1, ...}
+ INVOKE PRIORITY {5}
+ CODE op-report-delivery
+}
+
+ReportDeliveryArgument ::= SET {
+ COMPONENTS OF ReportDeliveryEnvelope,
+ returned-content [0] Content OPTIONAL
+}
+
+ReportDeliveryResult ::= CHOICE {
+ empty-result NULL,
+ ...,
+ extensions
+ SET SIZE (1..MAX) OF ExtensionField{{ReportDeliveryResultExtensions}}
+}
+
+ReportDeliveryResultExtensions EXTENSION ::= {PrivateExtensions, ...}
+
+-- May contain private extensions and future standardised extensions
+delivery-control ABSTRACT-OPERATION ::= {
+ ARGUMENT DeliveryControlArgument
+ RESULT DeliveryControlResult
+ ERRORS
+ {control-violates-registration | security-error | operation-refused}
+ LINKED {operationObject1, ...}
+ INVOKE PRIORITY {3}
+ CODE op-delivery-control
+}
+
+DeliveryControlArgument ::= SET {
+ COMPONENTS OF DeliveryControls,
+ extensions
+ [6] SET OF ExtensionField{{DeliveryControlExtensions}} DEFAULT {}
+}
+
+DeliveryControlExtensions EXTENSION ::= {PrivateExtensions, ...}
+
+-- May contain private extensions and future standardised extensions
+DeliveryControlResult ::= SET {
+ COMPONENTS OF Waiting,
+ extensions
+ [6] SET OF ExtensionField{{DeliveryControlResultExtensions}} DEFAULT {}
+}
+
+DeliveryControlResultExtensions EXTENSION ::= {PrivateExtensions, ...}
+
+-- May contain private extensions and future standardised extensions
+delivery-control-violated ABSTRACT-ERROR ::= {
+ PARAMETER NULL
+ CODE err-delivery-control-violated
+}
+
+control-violates-registration ABSTRACT-ERROR ::= {
+ PARAMETER NULL
+ CODE err-control-violates-registration
+}
+
+operation-refused ABSTRACT-ERROR ::= {
+ PARAMETER RefusedOperation
+ CODE err-operation-refused
+}
+
+RefusedOperation ::= SET {
+ refused-argument
+ CHOICE {built-in-argument [1] RefusedArgument,
+ refused-extension EXTENSION.&id},
+ refusal-reason [2] RefusalReason
+}
+
+RefusedArgument ::= INTEGER {
+ user-name(0), user-address(1), deliverable-content-types(2),
+ deliverable-maximum-content-length(3),
+ deliverable-encoded-information-types-constraints(4),
+ deliverable-security-labels(5), recipient-assigned-redirections(6),
+ restricted-delivery(7),
+ retrieve-registrations(8), -- value 9 reserved for possible future extension to Register arguments
+ restrict(10), permissible-operations(11), permissible-lowest-priority(12),
+ permissible-encoded-information-types(13), permissible-content-types(14),
+ permissible-maximum-content-length(15), permissible-security-context(16)
+}(0..ub-integer-options)
+
+RefusalReason ::= INTEGER {
+ facility-unavailable(0), facility-not-subscribed(1),
+ parameter-unacceptable(2)}(0..ub-integer-options)
+
+-- Delivery Port Parameters
+RecipientCertificate ::= Certificates
+
+ProofOfDelivery ::=
+ SIGNATURE
+ {SEQUENCE {algorithm-identifier
+ ProofOfDeliveryAlgorithmIdentifier,
+ delivery-time MessageDeliveryTime,
+ this-recipient-name ThisRecipientName,
+ originally-intended-recipient-name
+ OriginallyIntendedRecipientName OPTIONAL,
+ content Content,
+ content-identifier ContentIdentifier OPTIONAL,
+ message-security-label
+ MessageSecurityLabel OPTIONAL}}
+
+ProofOfDeliveryAlgorithmIdentifier ::= AlgorithmIdentifier
+
+DeliveryControls ::= Controls
+
+Controls ::= SET {
+ restrict [0] BOOLEAN DEFAULT TRUE,
+ -- update 'TRUE', remove 'FALSE'
+ permissible-operations [1] Operations OPTIONAL,
+ permissible-maximum-content-length [2] ContentLength OPTIONAL,
+ permissible-lowest-priority Priority OPTIONAL,
+ permissible-content-types [4] ContentTypes OPTIONAL,
+ permissible-encoded-information-types
+ PermissibleEncodedInformationTypes OPTIONAL,
+ permissible-security-context [5] SecurityContext OPTIONAL
+}
+
+-- Note - The Tags [0], [1] and [2] are altered for the Register operation only.
+PermissibleEncodedInformationTypes ::=
+ EncodedInformationTypesConstraints
+
+-- Administration Port
+register ABSTRACT-OPERATION ::= {
+ ARGUMENT RegisterArgument
+ RESULT RegisterResult
+ ERRORS
+ {register-rejected | remote-bind-error | operation-refused |
+ security-error}
+ LINKED {operationObject1, ...}
+ INVOKE PRIORITY {5}
+ CODE op-register
+}
+
+RegisterArgument ::= SET {
+ user-name UserName OPTIONAL,
+ user-address [0] UserAddress OPTIONAL,
+ deliverable-class
+ SET SIZE (1..ub-deliverable-class) OF DeliverableClass OPTIONAL,
+ default-delivery-controls [2] EXPLICIT DefaultDeliveryControls OPTIONAL,
+ redirections [3] Redirections OPTIONAL,
+ restricted-delivery [4] RestrictedDelivery OPTIONAL,
+ retrieve-registrations [5] RegistrationTypes OPTIONAL,
+ extensions
+ [6] SET OF ExtensionField{{RegisterExtensions}} DEFAULT {}
+}
+
+RegisterExtensions EXTENSION ::= {PrivateExtensions, ...}
+
+-- May contain private extensions and future standardised extensions
+RegisterResult ::= CHOICE {
+ empty-result NULL,
+ non-empty-result
+ SET {registered-information
+ [0] RegisterArgument
+ (WITH COMPONENTS {
+ ...,
+ retrieve-registrations ABSENT
+ }) OPTIONAL,
+ extensions
+ [1] SET OF ExtensionField{{RegisterResultExtensions}} DEFAULT {}
+ }
+}
+
+RegisterResultExtensions EXTENSION ::= {PrivateExtensions, ...}
+
+-- May contain private extensions and future standardised extensions
+change-credentials ABSTRACT-OPERATION ::= {
+ ARGUMENT ChangeCredentialsArgument
+ RESULT NULL
+ ERRORS
+ {new-credentials-unacceptable | old-credentials-incorrectly-specified |
+ remote-bind-error | security-error}
+ LINKED {operationObject1, ...}
+ INVOKE PRIORITY {5}
+ CODE op-change-credentials
+}
+
+ChangeCredentialsArgument ::= SET {
+ old-credentials [0] Credentials(WITH COMPONENTS {
+ simple
+ }),
+ new-credentials [1] Credentials(WITH COMPONENTS {
+ simple
+ })
+}
+
+register-rejected ABSTRACT-ERROR ::= {
+ PARAMETER NULL
+ CODE err-register-rejected
+}
+
+new-credentials-unacceptable ABSTRACT-ERROR ::= {
+ PARAMETER NULL
+ CODE err-new-credentials-unacceptable
+}
+
+old-credentials-incorrectly-specified ABSTRACT-ERROR ::= {
+ PARAMETER NULL
+ CODE err-old-credentials-incorrectly-specified
+}
+
+-- Administration Port Parameters
+UserName ::= ORAddressAndOptionalDirectoryName
+
+UserAddress ::= CHOICE {
+ x121
+ [0] SEQUENCE {x121-address
+ NumericString(SIZE (1..ub-x121-address-length)) OPTIONAL,
+ tsap-id
+ PrintableString(SIZE (1..ub-tsap-id-length)) OPTIONAL
+ },
+ presentation [1] PSAPAddress
+}
+
+PSAPAddress ::= PresentationAddress
+
+DeliverableClass ::=
+ MessageClass
+ (WITH COMPONENTS {
+ ...,
+ priority ABSENT,
+ -- The 'objects' component shall always be defaulted.
+ -- objects ABSENT,
+ -- A component with a DEFAULT clause cannot be ABSENT
+ applies-only-to ABSENT
+ })
+
+DefaultDeliveryControls ::=
+ Controls
+ (WITH COMPONENTS {
+ ...,
+
+ -- The 'restrict' component shall always be defaulted.
+ -- restrict ABSENT,
+ -- A component with a DEFAULT clause cannot be ABSENT
+ permissible-security-context ABSENT
+ })
+
+Redirections ::= SEQUENCE SIZE (1..ub-redirections) OF RecipientRedirection
+
+RecipientRedirection ::= SET {
+ redirection-classes
+ [0] SET SIZE (1..ub-redirection-classes) OF RedirectionClass OPTIONAL,
+ recipient-assigned-alternate-recipient
+ [1] RecipientAssignedAlternateRecipient OPTIONAL
+}
+
+RedirectionClass ::= MessageClass
+
+MessageClass ::= SET {
+ content-types [0] ContentTypes OPTIONAL,
+ maximum-content-length [1] ContentLength OPTIONAL,
+ encoded-information-types-constraints
+ [2] EncodedInformationTypesConstraints OPTIONAL,
+ security-labels [3] SecurityContext OPTIONAL,
+ priority [4] SET OF Priority OPTIONAL,
+ objects
+ [5] ENUMERATED {messages(0), reports(1), both(2), ...
+ } DEFAULT both,
+ applies-only-to [6] SEQUENCE OF Restriction OPTIONAL, -- Not considered in the case of Reports
+ extensions
+ [7] SET OF ExtensionField{{MessageClassExtensions}} DEFAULT {}
+}
+
+EncodedInformationTypesConstraints ::= SEQUENCE {
+ unacceptable-eits [0] ExtendedEncodedInformationTypes OPTIONAL,
+ acceptable-eits [1] ExtendedEncodedInformationTypes OPTIONAL,
+ exclusively-acceptable-eits [2] ExtendedEncodedInformationTypes OPTIONAL
+}
+
+MessageClassExtensions EXTENSION ::= {PrivateExtensions, ...}
+
+-- May contain private extensions and future standardised extensions
+RecipientAssignedAlternateRecipient ::=
+ ORAddressAndOrDirectoryName
+
+RestrictedDelivery ::= SEQUENCE SIZE (1..ub-restrictions) OF Restriction
+
+Restriction ::= SET {
+ permitted BOOLEAN DEFAULT TRUE,
+ source-type
+ BIT STRING {originated-by(0), redirected-by(1), dl-expanded-by(2)}
+ DEFAULT {originated-by, redirected-by, dl-expanded-by},
+ source-name ExactOrPattern OPTIONAL
+}
+
+ExactOrPattern ::= CHOICE {
+ exact-match [0] ORName,
+ pattern-match [1] ORName
+}
+
+RegistrationTypes ::= SEQUENCE {
+ standard-parameters
+ [0] BIT STRING {user-name(0), user-address(1), deliverable-class(2),
+ default-delivery-controls(3), redirections(4),
+ restricted-delivery(5)} OPTIONAL,
+ extensions [1] SET OF EXTENSION.&id({RegisterExtensions}) OPTIONAL
+}
+
+-- Message Submission Envelope
+MessageSubmissionEnvelope ::= SET {
+ COMPONENTS OF PerMessageSubmissionFields,
+ per-recipient-fields
+ [1] SEQUENCE SIZE (1..ub-recipients) OF
+ PerRecipientMessageSubmissionFields
+}
+
+PerMessageSubmissionFields ::= SET {
+ originator-name OriginatorName,
+ original-encoded-information-types OriginalEncodedInformationTypes OPTIONAL,
+ content-type ContentType,
+ content-identifier ContentIdentifier OPTIONAL,
+ priority Priority DEFAULT normal,
+ per-message-indicators PerMessageIndicators DEFAULT {},
+ deferred-delivery-time [0] DeferredDeliveryTime OPTIONAL,
+ extensions
+ [2] SET OF ExtensionField{{PerMessageSubmissionExtensions}} DEFAULT {}
+}
+
+PerMessageSubmissionExtensions EXTENSION ::=
+ {-- May contain the following extensions, private extensions, and future standardised extensions,
+ -- at most one instance of each extension type:
+ recipient-reassignment-prohibited | dl-expansion-prohibited |
+ conversion-with-loss-prohibited | latest-delivery-time |
+ originator-return-address | originator-certificate |
+ content-confidentiality-algorithm-identifier |
+ message-origin-authentication-check | message-security-label |
+ proof-of-submission-request | content-correlator | dl-exempted-recipients |
+ certificate-selectors | multiple-originator-certificates |
+ forwarding-request -- for MS Abstract Service only -- | PrivateExtensions,
+ ...}
+
+PerRecipientMessageSubmissionFields ::= SET {
+ recipient-name RecipientName,
+ originator-report-request [0] OriginatorReportRequest,
+ explicit-conversion [1] ExplicitConversion OPTIONAL,
+ extensions
+ [2] SET OF ExtensionField{{PerRecipientMessageSubmissionExtensions}}
+ DEFAULT {}
+}
+
+PerRecipientMessageSubmissionExtensions EXTENSION ::=
+ {-- May contain the following extensions, private extensions, and future standardised extensions,
+ -- at most one instance of each extension type:
+ originator-requested-alternate-recipient | requested-delivery-method |
+ physical-forwarding-prohibited | physical-forwarding-address-request |
+ physical-delivery-modes | registered-mail-type | recipient-number-for-advice
+ | physical-rendition-attributes | physical-delivery-report-request |
+ message-token | content-integrity-check | proof-of-delivery-request |
+ certificate-selectors-override | recipient-certificate |
+ IPMPerRecipientEnvelopeExtensions | PrivateExtensions, ...}
+
+-- Probe Submission Envelope
+ProbeSubmissionEnvelope ::= SET {
+ COMPONENTS OF PerProbeSubmissionFields,
+ per-recipient-fields
+ [3] SEQUENCE SIZE (1..ub-recipients) OF PerRecipientProbeSubmissionFields
+}
+
+PerProbeSubmissionFields ::= SET {
+ originator-name OriginatorName,
+ original-encoded-information-types OriginalEncodedInformationTypes OPTIONAL,
+ content-type ContentType,
+ content-identifier ContentIdentifier OPTIONAL,
+ content-length [0] ContentLength OPTIONAL,
+ per-message-indicators PerMessageIndicators DEFAULT {},
+ extensions
+ [2] SET OF ExtensionField{{PerProbeSubmissionExtensions}} DEFAULT {}
+}
+
+PerProbeSubmissionExtensions EXTENSION ::=
+ {-- May contain the following extensions, private extensions, and future standardised extensions,
+ -- at most one instance of each extension type:
+ recipient-reassignment-prohibited | dl-expansion-prohibited |
+ conversion-with-loss-prohibited | originator-certificate |
+ message-security-label | content-correlator |
+ probe-origin-authentication-check | PrivateExtensions, ...}
+
+PerRecipientProbeSubmissionFields ::= SET {
+ recipient-name RecipientName,
+ originator-report-request [0] OriginatorReportRequest,
+ explicit-conversion [1] ExplicitConversion OPTIONAL,
+ extensions
+ [2] SET OF ExtensionField{{PerRecipientProbeSubmissionExtensions}}
+ DEFAULT {}
+}
+
+PerRecipientProbeSubmissionExtensions EXTENSION ::=
+ {-- May contain the following extensions, private extensions, and future standardised extensions,
+ -- at most one instance of each extension type:
+ originator-requested-alternate-recipient | requested-delivery-method |
+ physical-rendition-attributes | PrivateExtensions, ...}
+
+-- Message Delivery Envelope
+MessageDeliveryEnvelope ::= SEQUENCE {
+ message-delivery-identifier MessageDeliveryIdentifier,
+ message-delivery-time MessageDeliveryTime,
+ other-fields OtherMessageDeliveryFields
+}
+
+OtherMessageDeliveryFields ::= SET {
+ content-type DeliveredContentType,
+ originator-name DeliveredOriginatorName,
+ original-encoded-information-types
+ [1] OriginalEncodedInformationTypes OPTIONAL,
+ priority Priority DEFAULT normal,
+ delivery-flags [2] DeliveryFlags OPTIONAL,
+ other-recipient-names [3] OtherRecipientNames OPTIONAL,
+ this-recipient-name [4] ThisRecipientName,
+ originally-intended-recipient-name
+ [5] OriginallyIntendedRecipientName OPTIONAL,
+ converted-encoded-information-types
+ [6] ConvertedEncodedInformationTypes OPTIONAL,
+ message-submission-time [7] MessageSubmissionTime,
+ content-identifier [8] ContentIdentifier OPTIONAL,
+ extensions
+ [9] SET OF ExtensionField{{MessageDeliveryExtensions}} DEFAULT {}
+}
+
+MessageDeliveryExtensions EXTENSION ::=
+ {-- May contain the following extensions, private extensions, and future standardised extensions,
+ -- at most one instance of each extension type:
+ conversion-with-loss-prohibited | requested-delivery-method |
+ physical-forwarding-prohibited | physical-forwarding-address-request |
+ physical-delivery-modes | registered-mail-type | recipient-number-for-advice
+ | physical-rendition-attributes | originator-return-address |
+ physical-delivery-report-request | originator-certificate | message-token |
+ content-confidentiality-algorithm-identifier | content-integrity-check |
+ message-origin-authentication-check | message-security-label |
+ proof-of-delivery-request | dl-exempted-recipients | certificate-selectors |
+ certificate-selectors-override | multiple-originator-certificates |
+ recipient-certificate | IPMPerRecipientEnvelopeExtensions |
+ redirection-history | dl-expansion-history | trace-information |
+ internal-trace-information | PrivateExtensions, ...}
+
+-- Report Delivery Envelope
+ReportDeliveryEnvelope ::= SET {
+ COMPONENTS OF PerReportDeliveryFields,
+ per-recipient-fields
+ SEQUENCE SIZE (1..ub-recipients) OF PerRecipientReportDeliveryFields
+}
+
+PerReportDeliveryFields ::= SET {
+ subject-submission-identifier SubjectSubmissionIdentifier,
+ content-identifier ContentIdentifier OPTIONAL,
+ content-type ContentType OPTIONAL,
+ original-encoded-information-types OriginalEncodedInformationTypes OPTIONAL,
+ extensions
+ [1] SET OF ExtensionField{{ReportDeliveryExtensions}} DEFAULT {}
+}
+
+ReportDeliveryExtensions EXTENSION ::=
+ {-- May contain the following extensions, private extensions, and future standardised extensions,
+ -- at most one instance of each extension type:
+ message-security-label | content-correlator | redirection-history |
+ originator-and-DL-expansion-history | reporting-DL-name |
+ reporting-MTA-certificate | report-origin-authentication-check |
+ trace-information | internal-trace-information | reporting-MTA-name |
+ PrivateExtensions, ...}
+
+PerRecipientReportDeliveryFields ::= SET {
+ actual-recipient-name [0] ActualRecipientName,
+ report-type [1] ReportType,
+ converted-encoded-information-types
+ ConvertedEncodedInformationTypes OPTIONAL,
+ originally-intended-recipient-name
+ [2] OriginallyIntendedRecipientName OPTIONAL,
+ supplementary-information [3] SupplementaryInformation OPTIONAL,
+ extensions
+ [4] SET OF ExtensionField{{PerRecipientReportDeliveryExtensions}}
+ DEFAULT {}
+}
+
+PerRecipientReportDeliveryExtensions EXTENSION ::=
+ {-- May contain the following extensions, private extensions, and future standardised extensions,
+ -- at most one instance of each extension type:
+ redirection-history | physical-forwarding-address | recipient-certificate |
+ proof-of-delivery | PrivateExtensions, ...}
+
+ReportType ::= CHOICE {
+ delivery [0] DeliveryReport,
+ non-delivery [1] NonDeliveryReport
+}
+
+DeliveryReport ::= SET {
+ message-delivery-time [0] MessageDeliveryTime,
+ type-of-MTS-user [1] TypeOfMTSUser DEFAULT public
+}
+
+NonDeliveryReport ::= SET {
+ non-delivery-reason-code [0] NonDeliveryReasonCode,
+ non-delivery-diagnostic-code [1] NonDeliveryDiagnosticCode OPTIONAL
+}
+
+-- Envelope Fields
+OriginatorName ::= ORAddressAndOrDirectoryName
+
+DeliveredOriginatorName ::= ORAddressAndOptionalDirectoryName
+
+OriginalEncodedInformationTypes ::= EncodedInformationTypes
+
+ContentTypes ::= SET SIZE (1..ub-content-types) OF ContentType
+
+ContentType ::= CHOICE {
+ built-in BuiltInContentType,
+ extended ExtendedContentType
+}
+
+BuiltInContentType ::= [APPLICATION 6] INTEGER {
+ unidentified(0),
+ external(1), -- identified by the object-identifier of the EXTERNAL content
+ interpersonal-messaging-1984(2), interpersonal-messaging-1988(22),
+ edi-messaging(35), voice-messaging(40)}(0..ub-built-in-content-type)
+
+ExtendedContentType ::= RELATIVE-OID
+
+DeliveredContentType ::= CHOICE {
+ built-in [0] BuiltInContentType,
+ extended ExtendedContentType
+}
+
+ContentIdentifier ::=
+ [APPLICATION 10] PrintableString(SIZE (1..ub-content-id-length))
+
+PerMessageIndicators ::= [APPLICATION 8] BIT STRING {
+ disclosure-of-other-recipients(0), -- disclosure-of-other-recipients-requested 'one',
+
+ -- disclosure-of-other-recipients-prohibited 'zero';
+ -- ignored for Probe-submission
+ implicit-conversion-prohibited(1), -- implicit-conversion-prohibited 'one',
+
+ -- implicit-conversion-allowed 'zero'
+ alternate-recipient-allowed(2), -- alternate-recipient-allowed 'one',
+
+ -- alternate-recipient-prohibited 'zero'
+ content-return-request(3), -- content-return-requested 'one',
+
+ -- content-return-not-requested 'zero';
+ -- ignored for Probe-submission
+ reserved(4), -- bit reserved by MOTIS 1986
+ bit-5(5),
+ bit-6(6), -- notification type-1 : bit 5 'zero' and bit 6 'one'
+
+ -- notification type-2 : bit 5 'one' and bit 6 'zero'
+ -- notification type-3 : bit 5 'one' and bit 6 'one'
+ -- the mapping between notification type 1, 2, 3
+ -- and the content specific notification types are defined
+ -- in relevant content specifications
+ service-message(7) -- the message content is for service purposes;
+
+
+-- it may be a notification related to a service message;
+-- used only by bilateral agreement --}(SIZE (0..ub-bit-options))
+
+RecipientName ::= ORAddressAndOrDirectoryName
+
+OriginatorReportRequest ::= BIT STRING {report(3), non-delivery-report(4)
+
+-- at most one bit shall be 'one':
+-- report bit 'one' requests a 'report';
+-- non-delivery-report bit 'one' requests a 'non-delivery-report';
+-- both bits 'zero' requests 'no-report' --}(SIZE (0..ub-bit-options))
+
+ExplicitConversion ::= INTEGER {
+ ia5-text-to-teletex(0),
+ -- values 1 to 7 are no longer defined
+ ia5-text-to-g3-facsimile(8), ia5-text-to-g4-class-1(9),
+ ia5-text-to-videotex(10), teletex-to-ia5-text(11),
+ teletex-to-g3-facsimile(12), teletex-to-g4-class-1(13),
+ teletex-to-videotex(14),
+ -- value 15 is no longer defined
+ videotex-to-ia5-text(16), videotex-to-teletex(17)}(0..ub-integer-options)
+
+DeferredDeliveryTime ::= Time
+
+Priority ::= [APPLICATION 7] ENUMERATED {normal(0), non-urgent(1), urgent(2)}
+
+ContentLength ::= INTEGER(0..ub-content-length)
+
+MessageDeliveryIdentifier ::= MTSIdentifier
+
+MessageDeliveryTime ::= Time
+
+DeliveryFlags ::= BIT STRING {
+ implicit-conversion-prohibited(1) -- implicit-conversion-prohibited 'one',
+
+ -- implicit-conversion-allowed 'zero' --}(SIZE (0..ub-bit-options))
+
+OtherRecipientNames ::= SEQUENCE SIZE (1..ub-recipients) OF OtherRecipientName
+
+OtherRecipientName ::= ORAddressAndOptionalDirectoryName
+
+ThisRecipientName ::= ORAddressAndOptionalDirectoryName
+
+OriginallyIntendedRecipientName ::= ORAddressAndOptionalDirectoryName
+
+ConvertedEncodedInformationTypes ::= EncodedInformationTypes
+
+SubjectSubmissionIdentifier ::= MTSIdentifier
+
+ActualRecipientName ::= ORAddressAndOrDirectoryName
+
+TypeOfMTSUser ::= INTEGER {
+ public(0), private(1), ms(2), dl(3), pdau(4), physical-recipient(5), other(6)
+}(0..ub-mts-user-types)
+
+NonDeliveryReasonCode ::= INTEGER {
+ transfer-failure(0), unable-to-transfer(1), conversion-not-performed(2),
+ physical-rendition-not-performed(3), physical-delivery-not-performed(4),
+ restricted-delivery(5), directory-operation-unsuccessful(6),
+ deferred-delivery-not-performed(7), transfer-failure-for-security-reason(8)
+}(0..ub-reason-codes)
+
+NonDeliveryDiagnosticCode ::= INTEGER {
+ unrecognised-OR-name(0), ambiguous-OR-name(1), mts-congestion(2),
+ loop-detected(3), recipient-unavailable(4), maximum-time-expired(5),
+ encoded-information-types-unsupported(6), content-too-long(7),
+ conversion-impractical(8), implicit-conversion-prohibited(9),
+ implicit-conversion-not-subscribed(10), invalid-arguments(11),
+ content-syntax-error(12), size-constraint-violation(13),
+ protocol-violation(14), content-type-not-supported(15),
+ too-many-recipients(16), no-bilateral-agreement(17),
+ unsupported-critical-function(18), conversion-with-loss-prohibited(19),
+ line-too-long(20), page-split(21), pictorial-symbol-loss(22),
+ punctuation-symbol-loss(23), alphabetic-character-loss(24),
+ multiple-information-loss(25), recipient-reassignment-prohibited(26),
+ redirection-loop-detected(27), dl-expansion-prohibited(28),
+ no-dl-submit-permission(29), dl-expansion-failure(30),
+ physical-rendition-attributes-not-supported(31),
+ undeliverable-mail-physical-delivery-address-incorrect(32),
+ undeliverable-mail-physical-delivery-office-incorrect-or-invalid(33),
+ undeliverable-mail-physical-delivery-address-incomplete(34),
+ undeliverable-mail-recipient-unknown(35),
+ undeliverable-mail-recipient-deceased(36),
+ undeliverable-mail-organization-expired(37),
+ undeliverable-mail-recipient-refused-to-accept(38),
+ undeliverable-mail-recipient-did-not-claim(39),
+ undeliverable-mail-recipient-changed-address-permanently(40),
+ undeliverable-mail-recipient-changed-address-temporarily(41),
+ undeliverable-mail-recipient-changed-temporary-address(42),
+ undeliverable-mail-new-address-unknown(43),
+ undeliverable-mail-recipient-did-not-want-forwarding(44),
+ undeliverable-mail-originator-prohibited-forwarding(45),
+ secure-messaging-error(46), unable-to-downgrade(47),
+ unable-to-complete-transfer(48), transfer-attempts-limit-reached(49),
+ incorrect-notification-type(50),
+ dl-expansion-prohibited-by-security-policy(51),
+ forbidden-alternate-recipient(52), security-policy-violation(53),
+ security-services-refusal(54), unauthorised-dl-member(55),
+ unauthorised-dl-name(56),
+ unauthorised-originally-intended-recipient-name(57),
+ unauthorised-originator-name(58), unauthorised-recipient-name(59),
+ unreliable-system(60), authentication-failure-on-subject-message(61),
+ decryption-failed(62), decryption-key-unobtainable(63),
+ double-envelope-creation-failure(64),
+ double-enveloping-message-restoring-failure(65),
+ failure-of-proof-of-message(66), integrity-failure-on-subject-message(67),
+ invalid-security-label(68), key-failure(69), mandatory-parameter-absence(70),
+ operation-security-failure(71), repudiation-failure-of-message(72),
+ security-context-failure(73), token-decryption-failed(74), token-error(75),
+ unknown-security-label(76), unsupported-algorithm-identifier(77),
+ unsupported-security-policy(78)}(0..ub-diagnostic-codes)
+
+SupplementaryInformation ::=
+ PrintableString(SIZE (1..ub-supplementary-info-length))
+
+-- Extension Fields
+EXTENSION ::= CLASS {
+ &id ExtensionType UNIQUE,
+ &Type OPTIONAL,
+ &absent &Type OPTIONAL,
+ &recommended Criticality DEFAULT {}
+}
+WITH SYNTAX {
+ [&Type
+ [IF ABSENT &absent],]
+ [RECOMMENDED CRITICALITY &recommended,]
+ IDENTIFIED BY &id
+}
+
+ExtensionType ::= CHOICE {
+ standard-extension [0] INTEGER(0..ub-extension-types),
+ private-extension [3] OBJECT IDENTIFIER
+}
+
+Criticality ::= BIT STRING {for-submission(0), for-transfer(1), for-delivery(2)
+}(SIZE (0..ub-bit-options)) -- critical 'one', non-critical 'zero'
+
+
+ExtensionField{EXTENSION:ChosenFrom} ::= SEQUENCE {
+ type EXTENSION.&id({ChosenFrom}),
+ criticality [1] Criticality DEFAULT {},
+ value [2] EXTENSION.&Type({ChosenFrom}{@type}) DEFAULT NULL:NULL
+}
+
+PrivateExtensions EXTENSION ::=
+ {-- Any value shall be relayed and delivered if not Critical (see Table 27)
+ -- except those values whose semantics the MTA obeys which are defined to be removed when obeyed.
+ -- Shall be IDENTIFIED BY ExtensionType.private-extension --...}
+
+recipient-reassignment-prohibited EXTENSION ::= {
+ RecipientReassignmentProhibited
+ IF ABSENT recipient-reassignment-allowed,
+ RECOMMENDED CRITICALITY {for-delivery},
+ IDENTIFIED BY standard-extension:1
+}
+
+RecipientReassignmentProhibited ::= ENUMERATED {
+ recipient-reassignment-allowed(0), recipient-reassignment-prohibited(1)
+}
+
+originator-requested-alternate-recipient EXTENSION ::= {
+ OriginatorRequestedAlternateRecipient,
+ RECOMMENDED CRITICALITY {for-submission},
+ IDENTIFIED BY standard-extension:2
+}
+
+OriginatorRequestedAlternateRecipient ::= ORAddressAndOrDirectoryName
+
+-- OriginatorRequestedAlternateRecipient as defined here differs from the field of the same name
+-- defined in Figure 4, since on submission the OR-address need not be present, but on
+-- transfer the OR-address must be present.
+dl-expansion-prohibited EXTENSION ::= {
+ DLExpansionProhibited
+ IF ABSENT dl-expansion-allowed,
+ RECOMMENDED CRITICALITY {for-delivery},
+ IDENTIFIED BY standard-extension:3
+}
+
+DLExpansionProhibited ::= ENUMERATED {
+ dl-expansion-allowed(0), dl-expansion-prohibited(1)}
+
+conversion-with-loss-prohibited EXTENSION ::= {
+ ConversionWithLossProhibited
+ IF ABSENT conversion-with-loss-allowed,
+ RECOMMENDED CRITICALITY {for-delivery},
+ IDENTIFIED BY standard-extension:4
+}
+
+ConversionWithLossProhibited ::= ENUMERATED {
+ conversion-with-loss-allowed(0), conversion-with-loss-prohibited(1)
+}
+
+latest-delivery-time EXTENSION ::= {
+ LatestDeliveryTime,
+ RECOMMENDED CRITICALITY {for-delivery},
+ IDENTIFIED BY standard-extension:5
+}
+
+LatestDeliveryTime ::= Time
+
+requested-delivery-method EXTENSION ::= {
+ RequestedDeliveryMethod
+ IF ABSENT {any-delivery-method},
+ IDENTIFIED BY standard-extension:6
+}
+
+RequestedDeliveryMethod ::=
+ SEQUENCE OF INTEGER { -- each different in order of preference,
+ -- most preferred first
+ any-delivery-method(0), mhs-delivery(1), physical-delivery(2),
+ telex-delivery(3), teletex-delivery(4), g3-facsimile-delivery(5),
+ g4-facsimile-delivery(6), ia5-terminal-delivery(7), videotex-delivery(8),
+ telephone-delivery(9)}(0..ub-integer-options)
+
+physical-forwarding-prohibited EXTENSION ::= {
+ PhysicalForwardingProhibited
+ IF ABSENT physical-forwarding-allowed,
+ RECOMMENDED CRITICALITY {for-delivery},
+ IDENTIFIED BY standard-extension:7
+}
+
+PhysicalForwardingProhibited ::= ENUMERATED {
+ physical-forwarding-allowed(0), physical-forwarding-prohibited(1)}
+
+physical-forwarding-address-request EXTENSION ::= {
+ PhysicalForwardingAddressRequest
+ IF ABSENT physical-forwarding-address-not-requested,
+ RECOMMENDED CRITICALITY {for-delivery},
+ IDENTIFIED BY standard-extension:8
+}
+
+PhysicalForwardingAddressRequest ::= ENUMERATED {
+ physical-forwarding-address-not-requested(0),
+ physical-forwarding-address-requested(1)}
+
+physical-delivery-modes EXTENSION ::= {
+ PhysicalDeliveryModes
+ IF ABSENT {ordinary-mail},
+ RECOMMENDED CRITICALITY {for-delivery},
+ IDENTIFIED BY standard-extension:9
+}
+
+PhysicalDeliveryModes ::= BIT STRING {
+ ordinary-mail(0), special-delivery(1), express-mail(2),
+ counter-collection(3), counter-collection-with-telephone-advice(4),
+ counter-collection-with-telex-advice(5),
+ counter-collection-with-teletex-advice(6), bureau-fax-delivery(7)
+
+-- bits 0 to 6 are mutually exclusive
+-- bit 7 can be set independently of any of bits 0 to 6 --}
+(SIZE (0..ub-bit-options))
+
+registered-mail-type EXTENSION ::= {
+ RegisteredMailType
+ IF ABSENT non-registered-mail,
+ RECOMMENDED CRITICALITY {for-delivery},
+ IDENTIFIED BY standard-extension:10
+}
+
+RegisteredMailType ::= INTEGER {
+ non-registered-mail(0), registered-mail(1),
+ registered-mail-to-addressee-in-person(2)}(0..ub-integer-options)
+
+recipient-number-for-advice EXTENSION ::= {
+ RecipientNumberForAdvice,
+ RECOMMENDED CRITICALITY {for-delivery},
+ IDENTIFIED BY standard-extension:11
+}
+
+RecipientNumberForAdvice ::=
+ TeletexString(SIZE (1..ub-recipient-number-for-advice-length))
+
+physical-rendition-attributes EXTENSION ::= {
+ PhysicalRenditionAttributes
+ IF ABSENT id-att-physicalRendition-basic,
+ RECOMMENDED CRITICALITY {for-delivery},
+ IDENTIFIED BY standard-extension:12
+}
+
+PhysicalRenditionAttributes ::= OBJECT IDENTIFIER
+
+originator-return-address EXTENSION ::= {
+ OriginatorReturnAddress,
+ IDENTIFIED BY standard-extension:13
+}
+
+OriginatorReturnAddress ::= ORAddress
+
+physical-delivery-report-request EXTENSION ::= {
+ PhysicalDeliveryReportRequest
+ IF ABSENT return-of-undeliverable-mail-by-PDS,
+ RECOMMENDED CRITICALITY {for-delivery},
+ IDENTIFIED BY standard-extension:14
+}
+
+PhysicalDeliveryReportRequest ::= INTEGER {
+ return-of-undeliverable-mail-by-PDS(0), return-of-notification-by-PDS(1),
+ return-of-notification-by-MHS(2), return-of-notification-by-MHS-and-PDS(3)
+}(0..ub-integer-options)
+
+originator-certificate EXTENSION ::= {
+ OriginatorCertificate,
+ IDENTIFIED BY standard-extension:15
+}
+
+OriginatorCertificate ::= Certificates
+
+message-token EXTENSION ::= {
+ MessageToken,
+ RECOMMENDED CRITICALITY {for-delivery},
+ IDENTIFIED BY standard-extension:16
+}
+
+MessageToken ::= Token
+
+content-confidentiality-algorithm-identifier EXTENSION ::= {
+ ContentConfidentialityAlgorithmIdentifier,
+ RECOMMENDED CRITICALITY {for-delivery},
+ IDENTIFIED BY standard-extension:17
+}
+
+ContentConfidentialityAlgorithmIdentifier ::= AlgorithmIdentifier
+
+content-integrity-check EXTENSION ::= {
+ ContentIntegrityCheck,
+ RECOMMENDED CRITICALITY {for-delivery},
+ IDENTIFIED BY standard-extension:18
+}
+
+ContentIntegrityCheck ::=
+ SIGNATURE
+ {SEQUENCE {algorithm-identifier
+ ContentIntegrityAlgorithmIdentifier OPTIONAL,
+ content Content}}
+
+ContentIntegrityAlgorithmIdentifier ::= AlgorithmIdentifier
+
+message-origin-authentication-check EXTENSION ::= {
+ MessageOriginAuthenticationCheck,
+ RECOMMENDED CRITICALITY {for-delivery},
+ IDENTIFIED BY standard-extension:19
+}
+
+MessageOriginAuthenticationCheck ::=
+ SIGNATURE
+ {SEQUENCE {algorithm-identifier
+ MessageOriginAuthenticationAlgorithmIdentifier,
+ content Content,
+ content-identifier ContentIdentifier OPTIONAL,
+ message-security-label MessageSecurityLabel OPTIONAL}}
+
+MessageOriginAuthenticationAlgorithmIdentifier ::= AlgorithmIdentifier
+
+message-security-label EXTENSION ::= {
+ MessageSecurityLabel,
+ RECOMMENDED CRITICALITY {for-delivery},
+ IDENTIFIED BY standard-extension:20
+}
+
+MessageSecurityLabel ::= SecurityLabel
+
+proof-of-submission-request EXTENSION ::= {
+ ProofOfSubmissionRequest
+ IF ABSENT proof-of-submission-not-requested,
+ RECOMMENDED CRITICALITY {for-submission},
+ IDENTIFIED BY standard-extension:21
+}
+
+ProofOfSubmissionRequest ::= ENUMERATED {
+ proof-of-submission-not-requested(0), proof-of-submission-requested(1)
+}
+
+proof-of-delivery-request EXTENSION ::= {
+ ProofOfDeliveryRequest
+ IF ABSENT proof-of-delivery-not-requested,
+ RECOMMENDED CRITICALITY {for-delivery},
+ IDENTIFIED BY standard-extension:22
+}
+
+ProofOfDeliveryRequest ::= ENUMERATED {
+ proof-of-delivery-not-requested(0), proof-of-delivery-requested(1)}
+
+content-correlator EXTENSION ::= {
+ ContentCorrelator,
+ IDENTIFIED BY standard-extension:23
+}
+
+ContentCorrelator ::= CHOICE {ia5text IA5String,
+ octets OCTET STRING
+}
+
+probe-origin-authentication-check EXTENSION ::= {
+ ProbeOriginAuthenticationCheck,
+ RECOMMENDED CRITICALITY {for-delivery},
+ IDENTIFIED BY standard-extension:24
+}
+
+ProbeOriginAuthenticationCheck ::=
+ SIGNATURE
+ {SEQUENCE {algorithm-identifier
+ ProbeOriginAuthenticationAlgorithmIdentifier,
+ content-identifier ContentIdentifier OPTIONAL,
+ message-security-label MessageSecurityLabel OPTIONAL}}
+
+ProbeOriginAuthenticationAlgorithmIdentifier ::= AlgorithmIdentifier
+
+redirection-history EXTENSION ::= {
+ RedirectionHistory,
+ IDENTIFIED BY standard-extension:25
+}
+
+RedirectionHistory ::= SEQUENCE SIZE (1..ub-redirections) OF Redirection
+
+Redirection ::= SEQUENCE {
+ intended-recipient-name IntendedRecipientName,
+ redirection-reason RedirectionReason
+}
+
+IntendedRecipientName ::= SEQUENCE {
+ intended-recipient ORAddressAndOptionalDirectoryName,
+ redirection-time Time
+}
+
+RedirectionReason ::= ENUMERATED {
+ recipient-assigned-alternate-recipient(0),
+ originator-requested-alternate-recipient(1),
+ recipient-MD-assigned-alternate-recipient(2),
+ -- The following values may not be supported by implementations of earlier versions of this Service Definition
+ directory-look-up(3), alias(4), ...
+ }
+
+dl-expansion-history EXTENSION ::= {
+ DLExpansionHistory,
+ IDENTIFIED BY standard-extension:26
+}
+
+DLExpansionHistory ::= SEQUENCE SIZE (1..ub-dl-expansions) OF DLExpansion
+
+DLExpansion ::= SEQUENCE {
+ dl ORAddressAndOptionalDirectoryName,
+ dl-expansion-time Time
+}
+
+physical-forwarding-address EXTENSION ::= {
+ PhysicalForwardingAddress,
+ IDENTIFIED BY standard-extension:27
+}
+
+PhysicalForwardingAddress ::= ORAddressAndOptionalDirectoryName
+
+recipient-certificate EXTENSION ::= {
+ RecipientCertificate,
+ IDENTIFIED BY standard-extension:28
+}
+
+proof-of-delivery EXTENSION ::= {
+ ProofOfDelivery,
+ IDENTIFIED BY standard-extension:29
+}
+
+originator-and-DL-expansion-history EXTENSION ::= {
+ OriginatorAndDLExpansionHistory,
+ IDENTIFIED BY standard-extension:30
+}
+
+OriginatorAndDLExpansionHistory ::=
+ SEQUENCE SIZE (2..ub-orig-and-dl-expansions) OF OriginatorAndDLExpansion
+
+OriginatorAndDLExpansion ::= SEQUENCE {
+ originator-or-dl-name ORAddressAndOptionalDirectoryName,
+ origination-or-expansion-time Time
+}
+
+reporting-DL-name EXTENSION ::= {
+ ReportingDLName,
+ IDENTIFIED BY standard-extension:31
+}
+
+ReportingDLName ::= ORAddressAndOptionalDirectoryName
+
+reporting-MTA-certificate EXTENSION ::= {
+ ReportingMTACertificate,
+ RECOMMENDED CRITICALITY {for-delivery},
+ IDENTIFIED BY standard-extension:32
+}
+
+ReportingMTACertificate ::= Certificates
+
+report-origin-authentication-check EXTENSION ::= {
+ ReportOriginAuthenticationCheck,
+ RECOMMENDED CRITICALITY {for-delivery},
+ IDENTIFIED BY standard-extension:33
+}
+
+ReportOriginAuthenticationCheck ::=
+ SIGNATURE
+ {SEQUENCE {algorithm-identifier
+ ReportOriginAuthenticationAlgorithmIdentifier,
+ content-identifier ContentIdentifier OPTIONAL,
+ message-security-label MessageSecurityLabel OPTIONAL,
+ per-recipient
+ SEQUENCE SIZE (1..ub-recipients) OF PerRecipientReportFields
+ }}
+
+ReportOriginAuthenticationAlgorithmIdentifier ::= AlgorithmIdentifier
+
+PerRecipientReportFields ::= SEQUENCE {
+ actual-recipient-name ActualRecipientName,
+ originally-intended-recipient-name OriginallyIntendedRecipientName OPTIONAL,
+ report-type
+ CHOICE {delivery [0] PerRecipientDeliveryReportFields,
+ non-delivery [1] PerRecipientNonDeliveryReportFields}
+}
+
+PerRecipientDeliveryReportFields ::= SEQUENCE {
+ message-delivery-time MessageDeliveryTime,
+ type-of-MTS-user TypeOfMTSUser,
+ recipient-certificate [0] RecipientCertificate OPTIONAL,
+ proof-of-delivery [1] ProofOfDelivery OPTIONAL
+}
+
+PerRecipientNonDeliveryReportFields ::= SEQUENCE {
+ non-delivery-reason-code NonDeliveryReasonCode,
+ non-delivery-diagnostic-code NonDeliveryDiagnosticCode OPTIONAL
+}
+
+originating-MTA-certificate EXTENSION ::= {
+ OriginatingMTACertificate,
+ IDENTIFIED BY standard-extension:34
+}
+
+OriginatingMTACertificate ::= Certificates
+
+proof-of-submission EXTENSION ::= {
+ ProofOfSubmission,
+ IDENTIFIED BY standard-extension:35
+}
+
+ProofOfSubmission ::=
+ SIGNATURE
+ {SEQUENCE {algorithm-identifier
+ ProofOfSubmissionAlgorithmIdentifier,
+ message-submission-envelope MessageSubmissionEnvelope,
+ content Content,
+ message-submission-identifier MessageSubmissionIdentifier,
+ message-submission-time MessageSubmissionTime}}
+
+ProofOfSubmissionAlgorithmIdentifier ::= AlgorithmIdentifier
+
+reporting-MTA-name EXTENSION ::= {
+ ReportingMTAName,
+ IDENTIFIED BY standard-extension:39
+}
+
+ReportingMTAName ::= SEQUENCE {
+ domain GlobalDomainIdentifier,
+ mta-name MTAName,
+ mta-directory-name [0] Name OPTIONAL
+}
+
+multiple-originator-certificates EXTENSION ::= {
+ ExtendedCertificates,
+ IDENTIFIED BY standard-extension:40
+}
+
+ExtendedCertificates ::= SET SIZE (1..ub-certificates) OF ExtendedCertificate
+
+ExtendedCertificate ::= CHOICE {
+ directory-entry [0] Name, -- Name of a Directory entry where the certificate can be found
+ certificate [1] Certificates
+}
+
+dl-exempted-recipients EXTENSION ::= {
+ DLExemptedRecipients,
+ IDENTIFIED BY standard-extension:42
+}
+
+DLExemptedRecipients ::= SET OF ORAddressAndOrDirectoryName
+
+certificate-selectors EXTENSION ::= {
+ CertificateSelectors,
+ IDENTIFIED BY standard-extension:45
+}
+
+CertificateSelectors ::= SET {
+ encryption-recipient [0] CertificateAssertion OPTIONAL,
+ encryption-originator [1] CertificateAssertion OPTIONAL,
+ content-integrity-check [2] CertificateAssertion OPTIONAL,
+ token-signature [3] CertificateAssertion OPTIONAL,
+ message-origin-authentication [4] CertificateAssertion OPTIONAL
+}
+
+certificate-selectors-override EXTENSION ::= {
+ CertificateSelectors
+ (WITH COMPONENTS {
+ ...,
+ message-origin-authentication ABSENT
+ }),
+ IDENTIFIED BY standard-extension:46
+}
+
+-- Some standard-extensions are defined elsewhere:
+-- 36 (forwarding-request) in ITU-T Rec. X.413 | ISO/IEC 10021-5;
+-- 37 (trace-information), and 38 (internal-trace-information) in Figure 4;
+-- 41 (blind-copy-recipients), 43 (body-part-encryption-token), and 44 (forwarded-content-token) in
+-- ITU-T Rec. X.420 | ISO/IEC 10021-7
+-- Common Parameter Types
+Content ::=
+ OCTET
+ STRING -- when the content-type has the integer value external, the value of the
+
+-- content octet string is the ASN.1 encoding of the external-content;
+-- an external-content is a data type EXTERNAL
+MTSIdentifier ::= [APPLICATION 4] SEQUENCE {
+ global-domain-identifier GlobalDomainIdentifier,
+ local-identifier LocalIdentifier
+}
+
+LocalIdentifier ::= IA5String(SIZE (1..ub-local-id-length))
+
+GlobalDomainIdentifier ::= [APPLICATION 3] SEQUENCE {
+ country-name CountryName,
+ administration-domain-name AdministrationDomainName,
+ private-domain-identifier PrivateDomainIdentifier OPTIONAL
+}
+
+PrivateDomainIdentifier ::= CHOICE {
+ numeric NumericString(SIZE (1..ub-domain-name-length)),
+ printable PrintableString(SIZE (1..ub-domain-name-length))
+}
+
+MTAName ::= IA5String(SIZE (1..ub-mta-name-length))
+
+Time ::= UTCTime
+
+-- OR Names
+ORAddressAndOrDirectoryName ::= ORName
+
+ORAddressAndOptionalDirectoryName ::= ORName
+
+ORName ::= [APPLICATION 0] SEQUENCE {
+ -- address --COMPONENTS OF ORAddress,
+ directory-name [0] Name OPTIONAL
+}
+
+ORAddress ::= SEQUENCE {
+ built-in-standard-attributes BuiltInStandardAttributes,
+ built-in-domain-defined-attributes BuiltInDomainDefinedAttributes OPTIONAL,
+ -- see also teletex-domain-defined-attributes
+ extension-attributes ExtensionAttributes OPTIONAL
+}
+
+-- The OR-address is semantically absent from the OR-name if the built-in-standard-attribute
+-- sequence is empty and the built-in-domain-defined-attributes and extension-attributes are both omitted.
+-- Built-in Standard Attributes
+BuiltInStandardAttributes ::= SEQUENCE {
+ country-name CountryName OPTIONAL,
+ administration-domain-name AdministrationDomainName OPTIONAL,
+ network-address [0] NetworkAddress OPTIONAL,
+ -- see also extended-network-address
+ terminal-identifier [1] TerminalIdentifier OPTIONAL,
+ private-domain-name [2] PrivateDomainName OPTIONAL,
+ organization-name [3] OrganizationName OPTIONAL,
+ -- see also teletex-organization-name
+ numeric-user-identifier [4] NumericUserIdentifier OPTIONAL,
+ personal-name [5] PersonalName OPTIONAL,
+ -- see also teletex-personal-name
+ organizational-unit-names [6] OrganizationalUnitNames OPTIONAL
+ -- see also teletex-organizational-unit-names
+}
+
+CountryName ::= [APPLICATION 1] CHOICE {
+ x121-dcc-code NumericString(SIZE (ub-country-name-numeric-length)),
+ iso-3166-alpha2-code PrintableString(SIZE (ub-country-name-alpha-length))
+}
+
+AdministrationDomainName ::= [APPLICATION 2] CHOICE {
+ numeric NumericString(SIZE (0..ub-domain-name-length)),
+ printable PrintableString(SIZE (0..ub-domain-name-length))
+}
+
+NetworkAddress ::= X121Address
+
+-- see also extended-network-address
+X121Address ::= NumericString(SIZE (1..ub-x121-address-length))
+
+TerminalIdentifier ::= PrintableString(SIZE (1..ub-terminal-id-length))
+
+PrivateDomainName ::= CHOICE {
+ numeric NumericString(SIZE (1..ub-domain-name-length)),
+ printable PrintableString(SIZE (1..ub-domain-name-length))
+}
+
+OrganizationName ::= PrintableString(SIZE (1..ub-organization-name-length))
+
+-- see also teletex-organization-name
+NumericUserIdentifier ::= NumericString(SIZE (1..ub-numeric-user-id-length))
+
+PersonalName ::= SET {
+ surname [0] PrintableString(SIZE (1..ub-surname-length)),
+ given-name
+ [1] PrintableString(SIZE (1..ub-given-name-length)) OPTIONAL,
+ initials
+ [2] PrintableString(SIZE (1..ub-initials-length)) OPTIONAL,
+ generation-qualifier
+ [3] PrintableString(SIZE (1..ub-generation-qualifier-length)) OPTIONAL
+}
+
+-- see also teletex-personal-name
+OrganizationalUnitNames ::=
+ SEQUENCE SIZE (1..ub-organizational-units) OF OrganizationalUnitName
+
+-- see also teletex-organizational-unit-names
+OrganizationalUnitName ::=
+ PrintableString(SIZE (1..ub-organizational-unit-name-length))
+
+-- Built-in Domain-defined Attributes
+BuiltInDomainDefinedAttributes ::=
+ SEQUENCE SIZE (1..ub-domain-defined-attributes) OF
+ BuiltInDomainDefinedAttribute
+
+BuiltInDomainDefinedAttribute ::= SEQUENCE {
+ type PrintableString(SIZE (1..ub-domain-defined-attribute-type-length)),
+ value PrintableString(SIZE (1..ub-domain-defined-attribute-value-length))
+}
+
+-- Extension Attributes
+ExtensionAttributes ::=
+ SET SIZE (1..ub-extension-attributes) OF ExtensionAttribute
+
+ExtensionAttribute ::= SEQUENCE {
+ extension-attribute-type
+ [0] EXTENSION-ATTRIBUTE.&id({ExtensionAttributeTable}),
+ extension-attribute-value
+ [1] EXTENSION-ATTRIBUTE.&Type
+ ({ExtensionAttributeTable}{@extension-attribute-type})
+}
+
+EXTENSION-ATTRIBUTE ::= CLASS {
+ &id INTEGER(0..ub-extension-attributes) UNIQUE,
+ &Type
+}WITH SYNTAX {&Type
+ IDENTIFIED BY &id
+}
+
+ExtensionAttributeTable EXTENSION-ATTRIBUTE ::=
+ {common-name | teletex-common-name | universal-common-name |
+ teletex-organization-name | universal-organization-name |
+ teletex-personal-name | universal-personal-name |
+ teletex-organizational-unit-names | universal-organizational-unit-names |
+ teletex-domain-defined-attributes | universal-domain-defined-attributes |
+ pds-name | physical-delivery-country-name | postal-code |
+ physical-delivery-office-name | universal-physical-delivery-office-name |
+ physical-delivery-office-number | universal-physical-delivery-office-number
+ | extension-OR-address-components |
+ universal-extension-OR-address-components | physical-delivery-personal-name
+ | universal-physical-delivery-personal-name |
+ physical-delivery-organization-name |
+ universal-physical-delivery-organization-name |
+ extension-physical-delivery-address-components |
+ universal-extension-physical-delivery-address-components |
+ unformatted-postal-address | universal-unformatted-postal-address |
+ street-address | universal-street-address | post-office-box-address |
+ universal-post-office-box-address | poste-restante-address |
+ universal-poste-restante-address | unique-postal-name |
+ universal-unique-postal-name | local-postal-attributes |
+ universal-local-postal-attributes | extended-network-address | terminal-type
+ }
+
+-- Extension Standard Attributes
+common-name EXTENSION-ATTRIBUTE ::= {CommonName
+ IDENTIFIED BY 1
+}
+
+CommonName ::= PrintableString(SIZE (1..ub-common-name-length))
+
+teletex-common-name EXTENSION-ATTRIBUTE ::= {TeletexCommonName
+ IDENTIFIED BY 2
+}
+
+TeletexCommonName ::= TeletexString(SIZE (1..ub-common-name-length))
+
+universal-common-name EXTENSION-ATTRIBUTE ::= {
+ UniversalCommonName
+ IDENTIFIED BY 24
+}
+
+UniversalCommonName ::= UniversalOrBMPString{ub-common-name-length}
+
+teletex-organization-name EXTENSION-ATTRIBUTE ::= {
+ TeletexOrganizationName
+ IDENTIFIED BY 3
+}
+
+TeletexOrganizationName ::=
+ TeletexString(SIZE (1..ub-organization-name-length))
+
+universal-organization-name EXTENSION-ATTRIBUTE ::= {
+ UniversalOrganizationName
+ IDENTIFIED BY 25
+}
+
+UniversalOrganizationName ::= UniversalOrBMPString{ub-organization-name-length}
+
+teletex-personal-name EXTENSION-ATTRIBUTE ::= {
+ TeletexPersonalName
+ IDENTIFIED BY 4
+}
+
+TeletexPersonalName ::= SET {
+ surname [0] TeletexString(SIZE (1..ub-surname-length)),
+ given-name
+ [1] TeletexString(SIZE (1..ub-given-name-length)) OPTIONAL,
+ initials
+ [2] TeletexString(SIZE (1..ub-initials-length)) OPTIONAL,
+ generation-qualifier
+ [3] TeletexString(SIZE (1..ub-generation-qualifier-length)) OPTIONAL
+}
+
+universal-personal-name EXTENSION-ATTRIBUTE ::= {
+ UniversalPersonalName
+ IDENTIFIED BY 26
+}
+
+UniversalPersonalName ::= SET {
+ surname [0] UniversalOrBMPString{ub-universal-surname-length},
+ -- If a language is specified within surname, then that language applies to each of the following
+ -- optional components unless the component specifies another language.
+ given-name
+ [1] UniversalOrBMPString{ub-universal-given-name-length} OPTIONAL,
+ initials
+ [2] UniversalOrBMPString{ub-universal-initials-length} OPTIONAL,
+ generation-qualifier
+ [3] UniversalOrBMPString{ub-universal-generation-qualifier-length}
+ OPTIONAL
+}
+
+teletex-organizational-unit-names EXTENSION-ATTRIBUTE ::= {
+ TeletexOrganizationalUnitNames
+ IDENTIFIED BY 5
+}
+
+TeletexOrganizationalUnitNames ::=
+ SEQUENCE SIZE (1..ub-organizational-units) OF TeletexOrganizationalUnitName
+
+TeletexOrganizationalUnitName ::=
+ TeletexString(SIZE (1..ub-organizational-unit-name-length))
+
+universal-organizational-unit-names EXTENSION-ATTRIBUTE ::= {
+ UniversalOrganizationalUnitNames
+ IDENTIFIED BY 27
+}
+
+UniversalOrganizationalUnitNames ::=
+ SEQUENCE SIZE (1..ub-organizational-units) OF UniversalOrganizationalUnitName
+
+-- If a unit name specifies a language, then that language applies to subordinate unit names unless
+-- the subordinate specifies another language.
+UniversalOrganizationalUnitName ::=
+ UniversalOrBMPString{ub-organizational-unit-name-length}
+
+UniversalOrBMPString{INTEGER:ub-string-length} ::= SET {
+ character-encoding
+ CHOICE {two-octets BMPString(SIZE (1..ub-string-length)),
+ four-octets UniversalString(SIZE (1..ub-string-length))},
+ iso-639-language-code PrintableString(SIZE (2 | 5)) OPTIONAL
+}
+
+pds-name EXTENSION-ATTRIBUTE ::= {PDSName
+ IDENTIFIED BY 7
+}
+
+PDSName ::= PrintableString(SIZE (1..ub-pds-name-length))
+
+physical-delivery-country-name EXTENSION-ATTRIBUTE ::= {
+ PhysicalDeliveryCountryName
+ IDENTIFIED BY 8
+}
+
+PhysicalDeliveryCountryName ::= CHOICE {
+ x121-dcc-code NumericString(SIZE (ub-country-name-numeric-length)),
+ iso-3166-alpha2-code PrintableString(SIZE (ub-country-name-alpha-length))
+}
+
+postal-code EXTENSION-ATTRIBUTE ::= {PostalCode
+ IDENTIFIED BY 9
+}
+
+PostalCode ::= CHOICE {
+ numeric-code NumericString(SIZE (1..ub-postal-code-length)),
+ printable-code PrintableString(SIZE (1..ub-postal-code-length))
+}
+
+physical-delivery-office-name EXTENSION-ATTRIBUTE ::= {
+ PhysicalDeliveryOfficeName
+ IDENTIFIED BY 10
+}
+
+PhysicalDeliveryOfficeName ::= PDSParameter
+
+universal-physical-delivery-office-name EXTENSION-ATTRIBUTE ::= {
+ UniversalPhysicalDeliveryOfficeName
+ IDENTIFIED BY 29
+}
+
+UniversalPhysicalDeliveryOfficeName ::= UniversalPDSParameter
+
+physical-delivery-office-number EXTENSION-ATTRIBUTE ::= {
+ PhysicalDeliveryOfficeNumber
+ IDENTIFIED BY 11
+}
+
+PhysicalDeliveryOfficeNumber ::= PDSParameter
+
+universal-physical-delivery-office-number EXTENSION-ATTRIBUTE ::= {
+ UniversalPhysicalDeliveryOfficeNumber
+ IDENTIFIED BY 30
+}
+
+UniversalPhysicalDeliveryOfficeNumber ::= UniversalPDSParameter
+
+extension-OR-address-components EXTENSION-ATTRIBUTE ::= {
+ ExtensionORAddressComponents
+ IDENTIFIED BY 12
+}
+
+ExtensionORAddressComponents ::= PDSParameter
+
+universal-extension-OR-address-components EXTENSION-ATTRIBUTE ::= {
+ UniversalExtensionORAddressComponents
+ IDENTIFIED BY 31
+}
+
+UniversalExtensionORAddressComponents ::= UniversalPDSParameter
+
+physical-delivery-personal-name EXTENSION-ATTRIBUTE ::= {
+ PhysicalDeliveryPersonalName
+ IDENTIFIED BY 13
+}
+
+PhysicalDeliveryPersonalName ::= PDSParameter
+
+universal-physical-delivery-personal-name EXTENSION-ATTRIBUTE ::= {
+ UniversalPhysicalDeliveryPersonalName
+ IDENTIFIED BY 32
+}
+
+UniversalPhysicalDeliveryPersonalName ::= UniversalPDSParameter
+
+physical-delivery-organization-name EXTENSION-ATTRIBUTE ::= {
+ PhysicalDeliveryOrganizationName
+ IDENTIFIED BY 14
+}
+
+PhysicalDeliveryOrganizationName ::= PDSParameter
+
+universal-physical-delivery-organization-name EXTENSION-ATTRIBUTE ::=
+{UniversalPhysicalDeliveryOrganizationName
+ IDENTIFIED BY 33
+}
+
+UniversalPhysicalDeliveryOrganizationName ::= UniversalPDSParameter
+
+extension-physical-delivery-address-components EXTENSION-ATTRIBUTE ::=
+{ExtensionPhysicalDeliveryAddressComponents
+ IDENTIFIED BY 15
+}
+
+ExtensionPhysicalDeliveryAddressComponents ::= PDSParameter
+
+universal-extension-physical-delivery-address-components EXTENSION-ATTRIBUTE
+ ::= {UniversalExtensionPhysicalDeliveryAddressComponents
+ IDENTIFIED BY 34
+}
+
+UniversalExtensionPhysicalDeliveryAddressComponents ::= UniversalPDSParameter
+
+unformatted-postal-address EXTENSION-ATTRIBUTE ::= {
+ UnformattedPostalAddress
+ IDENTIFIED BY 16
+}
+
+UnformattedPostalAddress ::= SET {
+ printable-address
+ SEQUENCE SIZE (1..ub-pds-physical-address-lines) OF
+ PrintableString(SIZE (1..ub-pds-parameter-length)) OPTIONAL,
+ teletex-string
+ TeletexString(SIZE (1..ub-unformatted-address-length)) OPTIONAL
+}
+
+universal-unformatted-postal-address EXTENSION-ATTRIBUTE ::= {
+ UniversalUnformattedPostalAddress
+ IDENTIFIED BY 35
+}
+
+UniversalUnformattedPostalAddress ::=
+ UniversalOrBMPString{ub-unformatted-address-length}
+
+street-address EXTENSION-ATTRIBUTE ::= {StreetAddress
+ IDENTIFIED BY 17
+}
+
+StreetAddress ::= PDSParameter
+
+universal-street-address EXTENSION-ATTRIBUTE ::= {
+ UniversalStreetAddress
+ IDENTIFIED BY 36
+}
+
+UniversalStreetAddress ::= UniversalPDSParameter
+
+post-office-box-address EXTENSION-ATTRIBUTE ::= {
+ PostOfficeBoxAddress
+ IDENTIFIED BY 18
+}
+
+PostOfficeBoxAddress ::= PDSParameter
+
+universal-post-office-box-address EXTENSION-ATTRIBUTE ::= {
+ UniversalPostOfficeBoxAddress
+ IDENTIFIED BY 37
+}
+
+UniversalPostOfficeBoxAddress ::= UniversalPDSParameter
+
+poste-restante-address EXTENSION-ATTRIBUTE ::= {
+ PosteRestanteAddress
+ IDENTIFIED BY 19
+}
+
+PosteRestanteAddress ::= PDSParameter
+
+universal-poste-restante-address EXTENSION-ATTRIBUTE ::= {
+ UniversalPosteRestanteAddress
+ IDENTIFIED BY 38
+}
+
+UniversalPosteRestanteAddress ::= UniversalPDSParameter
+
+unique-postal-name EXTENSION-ATTRIBUTE ::= {UniquePostalName
+ IDENTIFIED BY 20
+}
+
+UniquePostalName ::= PDSParameter
+
+universal-unique-postal-name EXTENSION-ATTRIBUTE ::= {
+ UniversalUniquePostalName
+ IDENTIFIED BY 39
+}
+
+UniversalUniquePostalName ::= UniversalPDSParameter
+
+local-postal-attributes EXTENSION-ATTRIBUTE ::= {
+ LocalPostalAttributes
+ IDENTIFIED BY 21
+}
+
+LocalPostalAttributes ::= PDSParameter
+
+universal-local-postal-attributes EXTENSION-ATTRIBUTE ::= {
+ UniversalLocalPostalAttributes
+ IDENTIFIED BY 40
+}
+
+UniversalLocalPostalAttributes ::= UniversalPDSParameter
+
+PDSParameter ::= SET {
+ printable-string PrintableString(SIZE (1..ub-pds-parameter-length)) OPTIONAL,
+ teletex-string TeletexString(SIZE (1..ub-pds-parameter-length)) OPTIONAL
+}
+
+UniversalPDSParameter ::= UniversalOrBMPString{ub-pds-parameter-length}
+
+extended-network-address EXTENSION-ATTRIBUTE ::= {
+ ExtendedNetworkAddress
+ IDENTIFIED BY 22
+}
+
+ExtendedNetworkAddress ::= CHOICE {
+ e163-4-address
+ SEQUENCE {number
+ [0] NumericString(SIZE (1..ub-e163-4-number-length)),
+ sub-address
+ [1] NumericString(SIZE (1..ub-e163-4-sub-address-length))
+ OPTIONAL},
+ psap-address [0] PresentationAddress
+}
+
+terminal-type EXTENSION-ATTRIBUTE ::= {TerminalType
+ IDENTIFIED BY 23
+}
+
+TerminalType ::= INTEGER {
+ telex(3), teletex(4), g3-facsimile(5), g4-facsimile(6), ia5-terminal(7),
+ videotex(8)}(0..ub-integer-options)
+
+-- Extension Domain-defined Attributes
+teletex-domain-defined-attributes EXTENSION-ATTRIBUTE ::= {
+ TeletexDomainDefinedAttributes
+ IDENTIFIED BY 6
+}
+
+TeletexDomainDefinedAttributes ::=
+ SEQUENCE SIZE (1..ub-domain-defined-attributes) OF
+ TeletexDomainDefinedAttribute
+
+TeletexDomainDefinedAttribute ::= SEQUENCE {
+ type TeletexString(SIZE (1..ub-domain-defined-attribute-type-length)),
+ value TeletexString(SIZE (1..ub-domain-defined-attribute-value-length))
+}
+
+universal-domain-defined-attributes EXTENSION-ATTRIBUTE ::= {
+ UniversalDomainDefinedAttributes
+ IDENTIFIED BY 28
+}
+
+UniversalDomainDefinedAttributes ::=
+ SEQUENCE SIZE (1..ub-domain-defined-attributes) OF
+ UniversalDomainDefinedAttribute
+
+UniversalDomainDefinedAttribute ::= SEQUENCE {
+ type UniversalOrBMPString{ub-domain-defined-attribute-type-length},
+ value UniversalOrBMPString{ub-domain-defined-attribute-value-length}
+}
+
+-- Encoded Information Types
+EncodedInformationTypes ::= [APPLICATION 5] SET {
+ built-in-encoded-information-types [0] BuiltInEncodedInformationTypes,
+ -- non-basic-parameters --COMPONENTS OF NonBasicParameters,
+ extended-encoded-information-types
+ [4] ExtendedEncodedInformationTypes OPTIONAL
+}
+
+-- Built-in Encoded Information Types
+BuiltInEncodedInformationTypes ::= BIT STRING {
+ unknown(0), ia5-text(2), g3-facsimile(3), g4-class-1(4), teletex(5),
+ videotex(6), voice(7), sfd(8), mixed-mode(9)
+}(SIZE (0..ub-built-in-encoded-information-types))
+
+-- Extended Encoded Information Types
+ExtendedEncodedInformationTypes ::=
+ SET SIZE (1..ub-encoded-information-types) OF ExtendedEncodedInformationType
+
+ExtendedEncodedInformationType ::= OBJECT IDENTIFIER
+
+-- Non-basic Parameters
+NonBasicParameters ::= SET {
+ g3-facsimile [1] G3FacsimileNonBasicParameters DEFAULT {},
+ teletex [2] TeletexNonBasicParameters DEFAULT {}
+}
+
+G3FacsimileNonBasicParameters ::= BIT STRING {
+ two-dimensional(8), -- As defined in ITU-T Recommendation T.30
+ fine-resolution(9), --
+ unlimited-length(20), -- These bit values are chosen such that when
+ b4-length(21), -- encoded using ASN.1 Basic Encoding Rules
+ a3-width(22), -- the resulting octets have the same values
+ b4-width(23), -- as for T.30 encoding
+ t6-coding(25), --
+ uncompressed(30), -- Trailing zero bits are not significant.
+ width-middle-864-of-1728(37), -- It is recommended that implementations
+ width-middle-1216-of-1728(38), -- should not encode more than 32 bits unless
+ resolution-type(44), -- higher numbered bits are non-zero.
+ resolution-400x400(45), resolution-300x300(46), resolution-8x15(47),
+ edi(49), dtm(50), bft(51), mixed-mode(58), character-mode(60),
+ twelve-bits(65), preferred-huffmann(66), full-colour(67), jpeg(68),
+ processable-mode-26(71)}
+
+TeletexNonBasicParameters ::= SET {
+ graphic-character-sets [0] TeletexString OPTIONAL,
+ control-character-sets [1] TeletexString OPTIONAL,
+ page-formats [2] OCTET STRING OPTIONAL,
+ miscellaneous-terminal-capabilities [3] TeletexString OPTIONAL,
+ private-use
+ [4] OCTET STRING
+ OPTIONAL -- maximum ub-teletex-private-use-length octets --
+}
+
+-- as defined in CCITT Recommendation T.62
+-- Token
+Token ::= SEQUENCE {
+ token-type-identifier [0] TOKEN.&id({TokensTable}),
+ token
+ [1] TOKEN.&Type({TokensTable}{@token-type-identifier})
+}
+
+TOKEN ::= TYPE-IDENTIFIER
+
+TokensTable TOKEN ::= {asymmetric-token, ...}
+
+asymmetric-token TOKEN ::= {
+ AsymmetricToken
+ IDENTIFIED BY id-tok-asymmetricToken
+}
+
+AsymmetricToken ::=
+ SIGNED
+ {SEQUENCE {signature-algorithm-identifier AlgorithmIdentifier,
+ name
+ CHOICE {recipient-name RecipientName,
+ mta
+ [3] SEQUENCE {global-domain-identifier
+ GlobalDomainIdentifier OPTIONAL,
+ mta-name MTAName
+ }},
+ time Time,
+ signed-data [0] TokenData OPTIONAL,
+ encryption-algorithm-identifier
+ [1] AlgorithmIdentifier OPTIONAL,
+ encrypted-data
+ [2] ENCRYPTED{TokenData} OPTIONAL}}
+
+TokenData ::= SEQUENCE {
+ type [0] TOKEN-DATA.&id({TokenDataTable}),
+ value [1] TOKEN-DATA.&Type({TokenDataTable}{@type})
+}
+
+TOKEN-DATA ::= CLASS {&id INTEGER UNIQUE,
+ &Type
+}WITH SYNTAX {&Type
+ IDENTIFIED BY &id
+}
+
+TokenDataTable TOKEN-DATA ::=
+ {bind-token-signed-data | message-token-signed-data |
+ message-token-encrypted-data | bind-token-encrypted-data, ...}
+
+bind-token-signed-data TOKEN-DATA ::= {BindTokenSignedData
+ IDENTIFIED BY 1
+}
+
+BindTokenSignedData ::= RandomNumber
+
+RandomNumber ::= BIT STRING
+
+message-token-signed-data TOKEN-DATA ::= {
+ MessageTokenSignedData
+ IDENTIFIED BY 2
+}
+
+MessageTokenSignedData ::= SEQUENCE {
+ content-confidentiality-algorithm-identifier
+ [0] ContentConfidentialityAlgorithmIdentifier OPTIONAL,
+ content-integrity-check
+ [1] ContentIntegrityCheck OPTIONAL,
+ message-security-label
+ [2] MessageSecurityLabel OPTIONAL,
+ proof-of-delivery-request
+ [3] ProofOfDeliveryRequest OPTIONAL,
+ message-sequence-number [4] INTEGER OPTIONAL
+}
+
+message-token-encrypted-data TOKEN-DATA ::= {
+ MessageTokenEncryptedData
+ IDENTIFIED BY 3
+}
+
+MessageTokenEncryptedData ::= SEQUENCE {
+ content-confidentiality-key [0] EncryptionKey OPTIONAL,
+ content-integrity-check [1] ContentIntegrityCheck OPTIONAL,
+ message-security-label [2] MessageSecurityLabel OPTIONAL,
+ content-integrity-key [3] EncryptionKey OPTIONAL,
+ message-sequence-number [4] INTEGER OPTIONAL
+}
+
+EncryptionKey ::= BIT STRING
+
+bind-token-encrypted-data TOKEN-DATA ::= {
+ BindTokenEncryptedData
+ IDENTIFIED BY 4
+}
+
+BindTokenEncryptedData ::= EXTERNAL
+
+-- Security Label
+SecurityLabel ::= SET {
+ security-policy-identifier SecurityPolicyIdentifier OPTIONAL,
+ security-classification SecurityClassification OPTIONAL,
+ privacy-mark PrivacyMark OPTIONAL,
+ security-categories SecurityCategories OPTIONAL
+}
+
+SecurityPolicyIdentifier ::= OBJECT IDENTIFIER
+
+SecurityClassification ::= INTEGER {
+ unmarked(0), unclassified(1), restricted(2), confidential(3), secret(4),
+ top-secret(5)}(0..ub-integer-options)
+
+PrivacyMark ::= PrintableString(SIZE (1..ub-privacy-mark-length))
+
+SecurityCategories ::= SET SIZE (1..ub-security-categories) OF SecurityCategory
+
+SecurityCategory ::= SEQUENCE {
+ type [0] SECURITY-CATEGORY.&id({SecurityCategoriesTable}),
+ value [1] SECURITY-CATEGORY.&Type({SecurityCategoriesTable}{@type})
+}
+
+SECURITY-CATEGORY ::= TYPE-IDENTIFIER
+
+SecurityCategoriesTable SECURITY-CATEGORY ::=
+ {...}
+
+END -- of MTSAbstractService
+
+-- Generated by Asnp, the ASN.1 pretty-printer of France Telecom R&D
+
diff --git a/lib/asn1/test/asn1_SUITE_data/x420/MTSAbstractService88.asn b/lib/asn1/test/asn1_SUITE_data/x420/MTSAbstractService88.asn
new file mode 100644
index 0000000000..f66d117f35
--- /dev/null
+++ b/lib/asn1/test/asn1_SUITE_data/x420/MTSAbstractService88.asn
@@ -0,0 +1,150 @@
+-- Module MTSAbstractService88 (X.411:06/1999)
+MTSAbstractService88 {joint-iso-itu-t mhs(6) mts(3) modules(0)
+ mts-abstract-service(1) version-1988(1988)} DEFINITIONS IMPLICIT TAGS ::=
+BEGIN
+
+-- Prologue
+-- Exports everything
+IMPORTS
+ -- Remote Operations
+ CONTRACT
+ --==
+ FROM Remote-Operations-Information-Objects {joint-iso-itu-t
+ remote-operations(4) informationObjects(5) version1(0)}
+ -- MTS Abstract Service Parameters
+ operationObject1, ABSTRACT-OPERATION, change-credentials, ContentLength,
+ ContentTypes, Controls, control-violates-registration,
+ DefaultDeliveryControls, EncodedInformationTypes, message-delivery,
+ MHS-OBJECT, mts-connect, PORT, RecipientAssignedAlternateRecipient,
+ register-rejected, report-delivery, SecurityLabel, security-error,
+ submission, UserAddress, UserName, Waiting
+ --==
+ FROM MTSAbstractService {joint-iso-itu-t mhs(6) mts(3) modules(0)
+ mts-abstract-service(1) version-1999(1)}
+ -- Object Identifiers
+ id-ct-mts-access, id-ct-mts-forced-access, id-ot-mts, id-ot-mts-user,
+ id-pt-administration, id-pt-delivery
+ --==
+ FROM MTSObjectIdentifiers {joint-iso-itu-t mhs(6) mts(3) modules(0)
+ object-identifiers(0) version-1999(1)}
+ -- Operation Codes
+ op-delivery-control, op-register
+ --==
+ FROM MTSAccessProtocol {joint-iso-itu-t mhs(6) protocols(0) modules(0)
+ mts-access-protocol(1) version-1999(1)}
+ -- Upper Bounds
+ ub-content-types, ub-labels-and-redirections
+ --==
+ FROM MTSUpperBounds {joint-iso-itu-t mhs(6) mts(3) modules(0)
+ upper-bounds(3) version-1999(1)};
+
+-- Objects
+mts-88 MHS-OBJECT ::= {
+ INITIATES {mts-forced-access-contract-88}
+ RESPONDS {mts-access-contract-88}
+ ID {id-ot-mts 88}
+}
+
+mts-user-88 MHS-OBJECT ::= {
+ INITIATES {mts-access-contract-88}
+ RESPONDS {mts-forced-access-contract-88}
+ ID {id-ot-mts-user 88}
+}
+
+-- Contracts
+mts-access-contract-88 CONTRACT ::= {
+ CONNECTION mts-connect
+ INITIATOR CONSUMER OF {submission | delivery-88 | administration-88}
+ ID {id-ct-mts-access 88}
+}
+
+mts-forced-access-contract-88 CONTRACT ::= {
+ CONNECTION mts-connect
+ RESPONDER CONSUMER OF {submission | delivery-88 | administration-88}
+ ID {id-ct-mts-forced-access 88}
+}
+
+-- Ports
+delivery-88 PORT ::= {
+ OPERATIONS
+ {operationObject1,
+ ...} -- This IOS needs to be extensible for Forward{} of X.880
+ CONSUMER INVOKES
+ {delivery-control-88,
+ ...} -- This IOS needs to be extensible for Forward{} of X.880
+ SUPPLIER INVOKES
+ {message-delivery | report-delivery,
+ ...} -- This IOS needs to be extensible for Forward{} of X.880
+ ID {id-pt-delivery 88}
+}
+
+administration-88 PORT ::= {
+ OPERATIONS
+ {change-credentials,
+ ...} -- This IOS needs to be extensible for Forward{} of X.880
+ CONSUMER INVOKES
+ {register-88,
+ ...} -- This IOS needs to be extensible for Forward{} of X.880
+ SUPPLIER INVOKES
+ {operationObject1,
+ ...} -- This IOS needs to be extensible for Forward{} of X.880
+ ID {id-pt-administration 88}
+}
+
+-- Delivery Port
+delivery-control-88 ABSTRACT-OPERATION ::= {
+ ARGUMENT DeliveryControls88
+ RESULT Waiting
+ ERRORS {control-violates-registration | security-error}
+ LINKED
+ {operationObject1,
+ ...} -- This IOS needs to be extensible for Forward{} of X.880
+ INVOKE PRIORITY {3}
+ CODE op-delivery-control
+}
+
+DeliveryControls88 ::= SET {
+ COMPONENTS OF
+ Controls
+ (WITH COMPONENTS {
+ ...,
+ permissible-encoded-information-types ABSENT
+ }),
+ permissible-encoded-information-types-88 EncodedInformationTypes OPTIONAL
+}
+
+-- Administration Port
+register-88 ABSTRACT-OPERATION ::= {
+ ARGUMENT Register88
+ RESULT NULL
+ ERRORS {register-rejected}
+ LINKED {operationObject1, ...}
+ INVOKE PRIORITY {5}
+ CODE op-register
+}
+
+Register88 ::= SET {
+ user-name UserName OPTIONAL,
+ user-address [0] UserAddress OPTIONAL,
+ deliverable-encoded-information-types EncodedInformationTypes OPTIONAL,
+ deliverable-maximum-content-length [1] EXPLICIT ContentLength OPTIONAL,
+ default-delivery-controls
+ [2] EXPLICIT DefaultDeliveryControls OPTIONAL,
+ deliverable-content-types [3] ContentTypes OPTIONAL,
+ labels-and-redirections
+ [4] SET SIZE (1..ub-labels-and-redirections) OF LabelAndRedirection
+ OPTIONAL
+}
+
+LabelAndRedirection ::= SET {
+ user-security-label [0] UserSecurityLabel OPTIONAL,
+ recipient-assigned-alternate-recipient
+ [1] RecipientAssignedAlternateRecipient OPTIONAL
+}
+
+UserSecurityLabel ::= SecurityLabel
+
+END -- of MTSAbstractService88
+
+-- Generated by Asnp, the ASN.1 pretty-printer of France Telecom R&D
+
diff --git a/lib/asn1/test/asn1_SUITE_data/x420/MTSAccessProtocol.asn b/lib/asn1/test/asn1_SUITE_data/x420/MTSAccessProtocol.asn
new file mode 100644
index 0000000000..03181c5951
--- /dev/null
+++ b/lib/asn1/test/asn1_SUITE_data/x420/MTSAccessProtocol.asn
@@ -0,0 +1,321 @@
+-- Module MTSAccessProtocol (X.419:06/1999)
+
+MTSAccessProtocol {joint-iso-itu-t mhs(6) protocols(0) modules(0)
+ mts-access-protocol(1) version-1999(1)} DEFINITIONS IMPLICIT TAGS ::=
+BEGIN
+
+-- Prologue
+IMPORTS
+ -- MTS Abstract Service
+ administration, delivery, mts-access-contract, mts-connect,
+ mts-forced-access-contract, submission
+ --==
+ FROM MTSAbstractService {joint-iso-itu-t mhs(6) mts(3) modules(0)
+ mts-abstract-service(1) version-1999(1)}
+ -- MTS Abstract Service (1988)
+ administration-88, delivery-88, mts-access-contract-88,
+ mts-forced-access-contract-88
+ --==
+ FROM MTSAbstractService88 {joint-iso-itu-t mhs(6) mts(3) modules(0)
+ mts-abstract-service(1) version-1988(1988)}
+ -- Remote Operations
+ APPLICATION-CONTEXT
+ --==
+ FROM Remote-Operations-Information-Objects-extensions {joint-iso-itu-t
+ remote-operations(4) informationObjects-extensions(8) version1(0)}
+ Code
+ --==
+ FROM Remote-Operations-Information-Objects {joint-iso-itu-t
+ remote-operations(4) informationObjects(5) version1(0)}
+ Bind{}, InvokeId, Unbind{}
+ --==
+ FROM Remote-Operations-Generic-ROS-PDUs {joint-iso-itu-t
+ remote-operations(4) generic-ROS-PDUs(6) version1(0)}
+ ROS-SingleAS{}
+ --==
+ FROM Remote-Operations-Useful-Definitions {joint-iso-itu-t
+ remote-operations(4) useful-definitions(7) version1(0)}
+ acse, association-by-RTSE, pData, transfer-by-RTSE
+ --==
+ FROM Remote-Operations-Realizations {joint-iso-itu-t remote-operations(4)
+ realizations(9) version1(0)}
+ acse-abstract-syntax
+ --==
+ FROM Remote-Operations-Abstract-Syntaxes {joint-iso-itu-t
+ remote-operations(4) remote-operations-abstract-syntaxes(12) version1(0)}
+ -- Reliable Transfer
+ RTORQapdu, RTOACapdu, RTORJapdu
+ FROM Reliable-Transfer-APDU {joint-iso-itu-t reliable-transfer(3) apdus(0)}
+ -- Object Identifiers
+ id-ac-mts-access-88, id-ac-mts-access-94, id-ac-mts-forced-access-88,
+ id-ac-mts-forced-access-94, id-ac-mts-forced-reliable-access-88,
+ id-ac-mts-forced-reliable-access-94, id-ac-mts-reliable-access-88,
+ id-ac-mts-reliable-access-94, id-as-mase-88, id-as-mase-94, id-as-mdse-88,
+ id-as-mdse-94, id-as-msse, id-as-mts, id-as-mts-rtse
+ --==
+ FROM MHSProtocolObjectIdentifiers {joint-iso-itu-t mhs(6) protocols(0)
+ modules(0) object-identifiers(0) version-1994(0)};
+
+RTSE-apdus ::= CHOICE {
+ rtorq-apdu [16] IMPLICIT RTORQapdu,
+ rtoac-apdu [17] IMPLICIT RTOACapdu,
+ rtorj-apdu [18] IMPLICIT RTORJapdu,
+ rttp-apdu RTTPapdu,
+ rttr-apdu RTTRapdu,
+ rtab-apdu [22] IMPLICIT RTABapdu
+}
+
+RTTPapdu ::= -- priority-- INTEGER
+
+RTTRapdu ::= OCTET STRING
+
+RTABapdu ::= SET {
+ abortReason [0] IMPLICIT AbortReason OPTIONAL,
+ reflectedParameter [1] IMPLICIT BIT STRING OPTIONAL,
+ -- 8 bits maximum, only if abortReason is invalidParameter
+ userdataAB
+ [2] TYPE-IDENTIFIER.&Type
+ OPTIONAL -- only in normal mode and if abortReason--
+ -- is userError
+}
+
+AbortReason ::= INTEGER {
+ localSystemProblem(0),
+ invalidParameter(1), -- reflectedParameter supplied
+ unrecognizedActivity(2),
+ temporaryProblem(3),
+ -- the RTSE cannot accept a session for a period of time
+ protocolError(4), -- RTSE level protocol error
+ permanentProblem(5), --provider-abort solely in normal mode
+ userError(6), -- user-abort solely in normal mode
+ transferCompleted(7) -- activity can't be discarded--}
+
+-- APPLICATION CONTEXTS
+-- 1994 Application Contexts omitting RTSE
+-- MTS-user initiated
+mts-access-94 APPLICATION-CONTEXT ::= {
+ CONTRACT mts-access-contract
+ ESTABLISHED BY acse
+ INFORMATION TRANSFER BY pData
+ ABSTRACT SYNTAXES
+ {acse-abstract-syntax | message-submission-abstract-syntax |
+ message-delivery-abstract-syntax |
+ message-administration-abstract-syntax-94 |
+ mts-bind-unbind-abstract-syntax}
+ APPLICATION CONTEXT NAME id-ac-mts-access-94
+}
+
+-- MTS initiated
+mts-forced-access-94 APPLICATION-CONTEXT ::= {
+ CONTRACT mts-forced-access-contract
+ ESTABLISHED BY acse
+ INFORMATION TRANSFER BY pData
+ ABSTRACT SYNTAXES
+ {acse-abstract-syntax | message-submission-abstract-syntax |
+ message-delivery-abstract-syntax |
+ message-administration-abstract-syntax-94 |
+ mts-bind-unbind-abstract-syntax}
+ APPLICATION CONTEXT NAME id-ac-mts-forced-access-94
+}
+
+-- 1994 Application Contexts including RTSE in normal mode
+-- MTS-user initiated
+mts-reliable-access-94 APPLICATION-CONTEXT ::= {
+ CONTRACT mts-access-contract
+ ESTABLISHED BY association-by-RTSE
+ INFORMATION TRANSFER BY transfer-by-RTSE
+ ABSTRACT SYNTAXES
+ {acse-abstract-syntax | message-submission-abstract-syntax |
+ message-delivery-abstract-syntax |
+ message-administration-abstract-syntax-94 |
+ mts-bind-unbind-rtse-abstract-syntax}
+ APPLICATION CONTEXT NAME id-ac-mts-reliable-access-94
+}
+
+-- MTS initiated
+mts-forced-reliable-access-94 APPLICATION-CONTEXT ::= {
+ CONTRACT mts-forced-access-contract
+ ESTABLISHED BY association-by-RTSE
+ INFORMATION TRANSFER BY transfer-by-RTSE
+ ABSTRACT SYNTAXES
+ {acse-abstract-syntax | message-submission-abstract-syntax |
+ message-delivery-abstract-syntax |
+ message-administration-abstract-syntax-94 |
+ mts-bind-unbind-rtse-abstract-syntax}
+ APPLICATION CONTEXT NAME id-ac-mts-forced-reliable-access-94
+}
+
+-- 1988 Application Contexts omitting RTSE
+-- MTS-user initiated
+mts-access-88 APPLICATION-CONTEXT ::= {
+ CONTRACT mts-access-contract-88
+ ESTABLISHED BY acse
+ INFORMATION TRANSFER BY pData
+ ABSTRACT SYNTAXES
+ {acse-abstract-syntax | message-submission-abstract-syntax |
+ message-delivery-abstract-syntax-88 |
+ message-administration-abstract-syntax-88 |
+ mts-bind-unbind-abstract-syntax}
+ APPLICATION CONTEXT NAME id-ac-mts-access-88
+}
+
+-- MTS initiated
+mts-forced-access-88 APPLICATION-CONTEXT ::= {
+ CONTRACT mts-forced-access-contract-88
+ ESTABLISHED BY acse
+ INFORMATION TRANSFER BY pData
+ ABSTRACT SYNTAXES
+ {acse-abstract-syntax | message-submission-abstract-syntax |
+ message-delivery-abstract-syntax-88 |
+ message-administration-abstract-syntax-88 |
+ mts-bind-unbind-abstract-syntax}
+ APPLICATION CONTEXT NAME id-ac-mts-forced-access-88
+}
+
+-- 1988 Application Contexts including RTSE in normal mode
+-- MTS-user initiated
+mts-reliable-access-88 APPLICATION-CONTEXT ::= {
+ CONTRACT mts-access-contract-88
+ ESTABLISHED BY association-by-RTSE
+ INFORMATION TRANSFER BY transfer-by-RTSE
+ ABSTRACT SYNTAXES
+ {acse-abstract-syntax | message-submission-abstract-syntax |
+ message-delivery-abstract-syntax-88 |
+ message-administration-abstract-syntax-88 |
+ mts-bind-unbind-rtse-abstract-syntax}
+ APPLICATION CONTEXT NAME id-ac-mts-reliable-access-88
+}
+
+-- MTS initiated
+mts-forced-reliable-access-88 APPLICATION-CONTEXT ::= {
+ CONTRACT mts-forced-access-contract-88
+ ESTABLISHED BY association-by-RTSE
+ INFORMATION TRANSFER BY transfer-by-RTSE
+ ABSTRACT SYNTAXES
+ {acse-abstract-syntax | message-submission-abstract-syntax |
+ message-delivery-abstract-syntax-88 |
+ message-administration-abstract-syntax-88 |
+ mts-bind-unbind-rtse-abstract-syntax}
+ APPLICATION CONTEXT NAME id-ac-mts-forced-reliable-access-88
+}
+
+-- ABSTRACT-SYNTAXES
+-- Abstract Syntax for MTS-Bind and MTS-Unbind
+mts-bind-unbind-abstract-syntax ABSTRACT-SYNTAX ::= {
+ MTSBindUnbindPDUs
+ IDENTIFIED BY id-as-mts
+}
+
+MTSBindUnbindPDUs ::= CHOICE {
+ bind Bind{mts-connect.&bind},
+ unbind Unbind{mts-connect.&unbind}
+}
+
+-- Abstract Syntax for MTS-Bind and MTS-Unbind with RTSE
+mts-bind-unbind-rtse-abstract-syntax ABSTRACT-SYNTAX ::= {
+ RTSE-apdus -- With MTS Bind and MTS Unbind --
+ IDENTIFIED BY id-as-mts-rtse
+}
+
+-- Abstract Syntax for Message Submission Service Element
+message-submission-abstract-syntax ABSTRACT-SYNTAX ::= {
+ MessageSubmissionPDUs
+ IDENTIFIED BY id-as-msse
+}
+
+MessageSubmissionPDUs ::= ROS-SingleAS{{MTSInvokeIds}, submission}
+
+MTSInvokeIds ::= InvokeId(ALL EXCEPT absent:NULL)
+
+-- Remote Operations
+op-message-submission Code ::= local:3
+
+op-probe-submission Code ::= local:4
+
+op-cancel-deferred-delivery Code ::= local:7
+
+op-submission-control Code ::= local:2
+
+-- Remote Errors
+err-submission-control-violated Code ::= local:1
+
+err-element-of-service-not-subscribed Code ::= local:4
+
+err-deferred-delivery-cancellation-rejected Code ::= local:8
+
+err-originator-invalid Code ::= local:2
+
+err-recipient-improperly-specified Code ::= local:3
+
+err-message-submission-identifier-invalid Code ::= local:7
+
+err-inconsistent-request Code ::= local:11
+
+err-security-error Code ::= local:12
+
+err-unsupported-critical-function Code ::= local:13
+
+err-remote-bind-error Code ::= local:15
+
+-- Abstract Syntax for Message Delivery Service Element 1994
+message-delivery-abstract-syntax ABSTRACT-SYNTAX ::= {
+ MessageDeliveryPDUs
+ IDENTIFIED BY id-as-mdse-94
+}
+
+MessageDeliveryPDUs ::= ROS-SingleAS{{MTSInvokeIds}, delivery}
+
+-- Abstract Syntax for Message Delivery Service Element 1988
+message-delivery-abstract-syntax-88 ABSTRACT-SYNTAX ::= {
+ MessageDeliveryPDUs88
+ IDENTIFIED BY id-as-mdse-88
+}
+
+MessageDeliveryPDUs88 ::= ROS-SingleAS{{MTSInvokeIds}, delivery-88}
+
+-- Remote Operations
+op-message-delivery Code ::= local:5
+
+op-report-delivery Code ::= local:6
+
+op-delivery-control Code ::= local:2
+
+-- Remote Errors
+err-delivery-control-violated Code ::= local:1
+
+err-control-violates-registration Code ::= local:14
+
+err-operation-refused Code ::= local:16
+
+-- Abstract Syntax for Message Administration Service Element 1994
+message-administration-abstract-syntax-94 ABSTRACT-SYNTAX ::= {
+ MessageAdministrationPDUs
+ IDENTIFIED BY id-as-mase-94
+}
+
+MessageAdministrationPDUs ::= ROS-SingleAS{{MTSInvokeIds}, administration}
+
+-- Abstract Syntax for Message Administration Service Element 1988
+message-administration-abstract-syntax-88 ABSTRACT-SYNTAX ::= {
+ MessageAdministrationPDUs88
+ IDENTIFIED BY id-as-mase-88
+}
+
+MessageAdministrationPDUs88 ::= ROS-SingleAS{{MTSInvokeIds}, administration-88}
+
+-- Remote Operations
+op-register Code ::= local:1
+
+op-change-credentials Code ::= local:8
+
+-- Remote Errors
+err-register-rejected Code ::= local:10
+
+err-new-credentials-unacceptable Code ::= local:6
+
+err-old-credentials-incorrectly-specified Code ::= local:5
+
+END -- of MTSAccessProtocol
+
+-- Generated by Asnp, the ASN.1 pretty-printer of France Telecom R&D
+
diff --git a/lib/asn1/test/asn1_SUITE_data/x420/MTSObjectIdentifiers.asn b/lib/asn1/test/asn1_SUITE_data/x420/MTSObjectIdentifiers.asn
new file mode 100644
index 0000000000..1615b241ee
--- /dev/null
+++ b/lib/asn1/test/asn1_SUITE_data/x420/MTSObjectIdentifiers.asn
@@ -0,0 +1,116 @@
+-- Module MTSObjectIdentifiers (X.411:06/1999)
+MTSObjectIdentifiers {joint-iso-itu-t mhs(6) mts(3) modules(0)
+ object-identifiers(0) version-1999(1)} DEFINITIONS IMPLICIT TAGS ::=
+BEGIN
+
+-- Prologue
+-- Exports everything
+IMPORTS -- nothing -- ;
+
+ID ::= OBJECT IDENTIFIER
+
+-- Message Transfer System
+id-mts ID ::=
+ {joint-iso-itu-t mhs(6) mts(3)} -- not definitive
+
+-- Categories of Object Identifiers
+id-mod ID ::= {id-mts 0} -- modules
+
+id-ot ID ::= {id-mts 1} -- object types
+
+id-pt ID ::= {id-mts 2} -- port types
+
+id-cont ID ::= {id-mts 3} -- content types
+
+id-eit ID ::= {id-mts 4} -- encoded information types
+
+id-att ID ::= {id-mts 5} -- attributes
+
+id-tok ID ::= {id-mts 6} -- token types
+
+id-sa ID ::= {id-mts 7} -- secure agent types
+
+id-ct ID ::= {id-mts 8} -- contracts
+
+id-cp ID ::= {id-mts 9} -- connection packages
+
+-- Modules
+id-mod-object-identifiers ID ::= {id-mod 0} -- not definitive
+
+id-mod-mts-abstract-service ID ::= {id-mod 1} -- not definitive
+
+id-mod-mta-abstract-service ID ::= {id-mod 2} -- not definitive
+
+id-mod-upper-bounds ID ::= {id-mod 3} -- not definitive
+
+-- Object Types
+id-ot-mts ID ::= {id-ot 0}
+
+id-ot-mts-user ID ::= {id-ot 1}
+
+id-ot-mta ID ::= {id-ot 2}
+
+-- Port Types
+id-pt-submission ID ::= {id-pt 0}
+
+id-pt-delivery ID ::= {id-pt 1}
+
+id-pt-administration ID ::= {id-pt 2}
+
+id-pt-transfer ID ::= {id-pt 3}
+
+-- Content Types
+id-cont-unidentified ID ::=
+ {id-cont 0} -- For use by MS and Directory
+
+id-cont-inner-envelope ID ::= {id-cont 1}
+
+-- Encoded Information Types
+id-eit-unknown ID ::= {id-eit 0}
+
+-- Value { id-eit 1 } is no longer defined
+id-eit-ia5-text ID ::= {id-eit 2}
+
+id-eit-g3-facsimile ID ::= {id-eit 3}
+
+id-eit-g4-class-1 ID ::= {id-eit 4}
+
+id-eit-teletex ID ::= {id-eit 5}
+
+id-eit-videotex ID ::= {id-eit 6}
+
+id-eit-voice ID ::= {id-eit 7}
+
+id-eit-sfd ID ::= {id-eit 8}
+
+id-eit-mixed-mode ID ::= {id-eit 9}
+
+-- Attributes
+id-att-physicalRendition-basic ID ::= {id-att 0}
+
+id-att-physicalRendition-no-cover-page ID ::= {id-att 1}
+
+-- Token Types
+id-tok-asymmetricToken ID ::= {id-tok 0}
+
+-- Secure Agent Types
+id-sa-ua ID ::= {id-sa 0}
+
+id-sa-ms ID ::= {id-sa 1}
+
+-- Contracts
+id-ct-mts-access ID ::= {id-ct 0}
+
+id-ct-mts-forced-access ID ::= {id-ct 1}
+
+id-ct-mta-transfer ID ::= {id-ct 2}
+
+-- Connection Packages
+id-cp-mts-connect ID ::= {id-cp 0}
+
+id-cp-mta-connect ID ::= {id-cp 1}
+
+END -- of MTSObjectIdentifiers
+
+-- Generated by Asnp, the ASN.1 pretty-printer of France Telecom R&D
+
diff --git a/lib/asn1/test/asn1_SUITE_data/x420/MTSUpperBounds.asn b/lib/asn1/test/asn1_SUITE_data/x420/MTSUpperBounds.asn
new file mode 100644
index 0000000000..10eac962cb
--- /dev/null
+++ b/lib/asn1/test/asn1_SUITE_data/x420/MTSUpperBounds.asn
@@ -0,0 +1,146 @@
+-- Module MTSUpperBounds (X.411:06/1999)
+MTSUpperBounds {joint-iso-itu-t mhs(6) mts(3) modules(0) upper-bounds(3)
+ version-1999(1)} DEFINITIONS IMPLICIT TAGS ::=
+BEGIN
+
+-- Prologue
+-- Exports everything
+IMPORTS -- nothing -- ;
+
+-- Upper Bounds
+ub-additional-info INTEGER ::= 1024
+
+ub-bilateral-info INTEGER ::= 1024
+
+ub-bit-options INTEGER ::= 16
+
+ub-built-in-content-type INTEGER ::= 32767
+
+ub-built-in-encoded-information-types INTEGER ::= 32
+
+ub-certificates INTEGER ::= 64
+
+ub-common-name-length INTEGER ::= 64
+
+ub-content-correlator-length INTEGER ::= 512
+
+ub-content-id-length INTEGER ::= 16
+
+ub-content-length INTEGER ::= 2147483647 -- the largest integer in 32 bits
+
+ub-content-types INTEGER ::= 1024
+
+ub-country-name-alpha-length INTEGER ::= 2
+
+ub-country-name-numeric-length INTEGER ::= 3
+
+ub-diagnostic-codes INTEGER ::= 32767
+
+ub-deliverable-class INTEGER ::= 256
+
+ub-dl-expansions INTEGER ::= 512
+
+ub-domain-defined-attributes INTEGER ::= 4
+
+ub-domain-defined-attribute-type-length INTEGER ::= 8
+
+ub-domain-defined-attribute-value-length INTEGER ::= 128
+
+ub-domain-name-length INTEGER ::= 16
+
+ub-encoded-information-types INTEGER ::= 1024
+
+ub-extension-attributes INTEGER ::= 256
+
+ub-extension-types INTEGER ::= 256
+
+ub-e163-4-number-length INTEGER ::= 15
+
+ub-e163-4-sub-address-length INTEGER ::= 40
+
+ub-generation-qualifier-length INTEGER ::= 3
+
+ub-given-name-length INTEGER ::= 16
+
+ub-initials-length INTEGER ::= 5
+
+ub-integer-options INTEGER ::= 256
+
+ub-labels-and-redirections INTEGER ::= 256
+
+ub-local-id-length INTEGER ::= 32
+
+ub-mta-name-length INTEGER ::= 32
+
+ub-mts-user-types INTEGER ::= 256
+
+ub-numeric-user-id-length INTEGER ::= 32
+
+ub-organization-name-length INTEGER ::= 64
+
+ub-organizational-unit-name-length INTEGER ::= 32
+
+ub-organizational-units INTEGER ::= 4
+
+ub-orig-and-dl-expansions INTEGER ::= 513 -- ub-dl-expansions plus one
+
+ub-password-length INTEGER ::= 62
+
+ub-pds-name-length INTEGER ::= 16
+
+ub-pds-parameter-length INTEGER ::= 30
+
+ub-pds-physical-address-lines INTEGER ::= 6
+
+ub-postal-code-length INTEGER ::= 16
+
+ub-privacy-mark-length INTEGER ::= 128
+
+ub-queue-size INTEGER ::= 2147483647 -- the largest integer in 32 bits
+
+ub-reason-codes INTEGER ::= 32767
+
+ub-recipient-number-for-advice-length INTEGER ::= 32
+
+ub-recipients INTEGER ::= 32767
+
+ub-redirection-classes INTEGER ::= 256
+
+ub-redirections INTEGER ::= 512
+
+ub-restrictions INTEGER ::= 1024
+
+ub-security-categories INTEGER ::= 64
+
+ub-security-labels INTEGER ::= 256
+
+ub-security-problems INTEGER ::= 256
+
+ub-supplementary-info-length INTEGER ::= 256
+
+ub-surname-length INTEGER ::= 40
+
+ub-teletex-private-use-length INTEGER ::= 128
+
+ub-terminal-id-length INTEGER ::= 24
+
+ub-transfers INTEGER ::= 512
+
+ub-tsap-id-length INTEGER ::= 16
+
+ub-unformatted-address-length INTEGER ::= 180
+
+ub-universal-generation-qualifier-length INTEGER ::= 16
+
+ub-universal-given-name-length INTEGER ::= 40
+
+ub-universal-initials-length INTEGER ::= 16
+
+ub-universal-surname-length INTEGER ::= 64
+
+ub-x121-address-length INTEGER ::= 16
+
+END -- of MTSUpperBounds
+
+-- Generated by Asnp, the ASN.1 pretty-printer of France Telecom R&D
+
diff --git a/lib/asn1/test/asn1_SUITE_data/x420/Notation.asn b/lib/asn1/test/asn1_SUITE_data/x420/Notation.asn
new file mode 100644
index 0000000000..96dfc39b6a
--- /dev/null
+++ b/lib/asn1/test/asn1_SUITE_data/x420/Notation.asn
@@ -0,0 +1,244 @@
+-- Module Notation (X.830:04/1995)
+
+Notation {joint-iso-itu-t genericULS(20) modules(1) notation(1)} DEFINITIONS
+AUTOMATIC TAGS ::=
+BEGIN
+
+-- EXPORTS All
+IMPORTS
+ -- From Directory Standards:
+ informationFramework, selectedAttributeTypes, authenticationFramework
+ FROM UsefulDefinitions {joint-iso-itu-t ds(5) module(1)
+ usefulDefinitions(0) 3}
+ Name
+ FROM InformationFramework informationFramework
+ UniqueIdentifier
+ FROM SelectedAttributeTypes selectedAttributeTypes
+ AlgorithmIdentifier
+ FROM AuthenticationFramework authenticationFramework
+ -- From Other GULS Modules:
+ genericProtectingTransferSyntax
+ FROM ObjectIdentifiers {joint-iso-itu-t genericULS(20) modules(1)
+ objectIdentifiers(0)}
+ SyntaxStructure{}
+ FROM GenericProtectingTransferSyntax genericProtectingTransferSyntax;
+
+-- *************************************************
+-- Notation for security identity and SA-identifiers
+-- *************************************************
+-- Values of the SecurityIdentity type are used to identify entities
+-- which assign externally-established security association identifiers,
+-- and for other security-related purposes requiring globally-unique
+-- identifiers.
+SecurityIdentity ::= CHOICE {
+ directoryName Name,
+ objectIdentifier OBJECT IDENTIFIER
+}
+
+ExternalSAID ::= SEQUENCE {
+ localSAID INTEGER,
+ assignerIdentity SecurityIdentity OPTIONAL
+ -- Identity of the system which assigned the integer value
+}
+
+-- ******************************************
+-- Notation for specifying security exchanges
+-- ******************************************
+SECURITY-EXCHANGE ::=
+ CLASS
+ -- This information object class definition is for use when
+ -- specifying a particular instance of a security exchange.
+ {
+ &SE-Items SEC-EXCHG-ITEM,
+ -- This is an ASN.1 information object set, comprising a set
+ -- of security exchange items
+ &sE-Identifier Identifier UNIQUE
+ -- A local or global identifier for the particular security
+ -- exchange
+}
+WITH SYNTAX
+ -- The following syntax is used to specify a particular security
+-- exchange.
+{SE-ITEMS &SE-Items
+ IDENTIFIER &sE-Identifier
+}
+
+Identifier ::= CHOICE {local INTEGER,
+ global OBJECT IDENTIFIER
+}
+
+SEC-EXCHG-ITEM ::= CLASS {
+ &ItemType ,
+ -- ASN.1 type for this exchange item
+ &itemId INTEGER,
+ -- Identifier for this item, e.g. 1, 2, 3, ..
+ &Errors SE-ERROR OPTIONAL
+ -- Optional list of errors which may result from
+ -- transfer of this item
+}WITH SYNTAX {ITEM-TYPE &ItemType
+ ITEM-ID &itemId
+ [ERRORS &Errors]
+}
+
+SE-ERROR ::= CLASS {
+ &ParameterType OPTIONAL,
+ -- ASN.1 type of a parameter to accompany the signalling
+ -- of the error condition back to the sender of the SEI
+ &errorCode Identifier UNIQUE
+ -- An identifier used in signalling the error condition
+ -- back to the sender of the SEI
+}WITH SYNTAX {[PARAMETER &ParameterType]
+ ERROR-CODE &errorCode
+}
+
+-- ************************************************
+-- Notation for specifying security transformations
+-- ************************************************
+SECURITY-TRANSFORMATION ::=
+ CLASS
+ -- This information object class definition is for use when
+ -- specifying a particular instance of a security transformation.
+ {
+ &sT-Identifier OBJECT IDENTIFIER UNIQUE,
+ -- Identifier to be used in signalling the application
+ -- of the particular security transformation
+ &initialEncodingRules OBJECT IDENTIFIER DEFAULT {joint-iso-ccitt
+ asn1(1) ber-derived(2)
+ canonical-encoding(0)},
+ -- Default initial encoding rules to generate a bit
+ -- string prior to applying the encoding process of a
+ -- security transformation.
+ &StaticUnprotectedParm OPTIONAL,
+ -- ASN.1 type for conveying static unprotected parameters
+ &DynamicUnprotectedParm OPTIONAL,
+ -- ASN.1 type for conveying dynamic unprotected parameters
+ &XformedDataType ,
+ -- ASN.1 type of the ASN.1 value produced by the security
+ -- transformations encoding process
+ &QualifierType OPTIONAL
+ -- &QualifierType specifies the ASN.1 type of the qualifier
+ -- parameter used with the PROTECTED-Q notation.
+}
+WITH SYNTAX
+ -- The following syntax is used to specify a particular security
+-- transformation.
+{
+ IDENTIFIER &sT-Identifier
+ [INITIAL-ENCODING-RULES &initialEncodingRules]
+ [STATIC-UNPROT-PARM &StaticUnprotectedParm]
+ [DYNAMIC-UNPROT-PARM &DynamicUnprotectedParm]
+ XFORMED-DATA-TYPE &XformedDataType
+ [QUALIFIER-TYPE &QualifierType]
+}
+
+-- **************************************************
+-- Notation for specifying selective field protection
+-- **************************************************
+PROTECTED{BaseType, PROTECTION-MAPPING:protectionReqd} ::= CHOICE {
+ dirEncrypt
+ BIT STRING
+ (CONSTRAINED BY {
+ BaseType-- dirEncrypt is for use only with the
+ -- dirEncryptedTransformation,
+ -- and generates the same encoding as the
+ -- X.509/9594-8 ENCRYPTED type-- }),
+ dirSign
+ SEQUENCE {baseType BaseType OPTIONAL,
+ -- must be present for dirSignedTransformation
+ -- and must be omitted for
+ -- dirSignatureTransformation
+ algorithmId AlgorithmIdentifier,
+ encipheredHash
+ BIT STRING
+ (CONSTRAINED BY {
+ BaseType-- contains enciphered hash--
+ -- of a value of BaseType -- })}-- dirSign is for use only with the
+ -- dirSignedTransformation or
+ -- dirSignatureTransformation, and generates
+ -- the same encoding as the corresponding
+ -- X.509/9594-8 SIGNED or SIGNATURE type--,
+ noTransform [0] BaseType,
+ -- noTransform invokes no security transformation.
+ -- Subject to security policy, noTransform may be used
+ -- if adequate protection is provided by lower layers
+ -- and any application relays through which the data
+ -- may pass are trusted to maintain the required
+ -- protection. This alternative may only be used
+ -- if protectionReqd.&bypassPermitted is TRUE,
+ direct [1] SyntaxStructure{{protectionReqd.&SecurityTransformation}},
+ -- direct generates a protecting transfer syntax
+ -- value, which is encoded using the same encoding
+ -- rules as the surrounding ASN.1 (The type
+ -- SyntaxStructure is imported from Rec. X.833 |
+ -- ISO/IEC 11586-3)
+ embedded
+ [2] EMBEDDED PDV
+ (WITH COMPONENTS {
+ identification (WITH COMPONENTS {
+ presentation-context-id ,
+ context-negotiation (WITH COMPONENTS {
+ transfer-syntax (CONSTRAINED BY {
+ OBJECT
+ IDENTIFIER:
+ protectionReqd.
+ &protTransferSyntax})
+ }),
+ transfer-syntax (CONSTRAINED BY {
+ OBJECT IDENTIFIER:
+ protectionReqd.
+ &protTransferSyntax})
+ }),
+ data-value (CONTAINING BaseType )
+
+ -- The data value encoded is a value of type BaseType
+ })
+}
+
+PROTECTED-Q{BaseType, PROTECTION-MAPPING:protectionReqd,
+ PROTECTION-MAPPING.&SecurityTransformation.&QualifierType:qualifier}
+ ::=
+ PROTECTED{BaseType, protectionReqd}
+ (CONSTRAINED BY {
+ protectionReqd.&SecurityTransformation.&QualifierType:qualifier
+ -- The value of qualifier must be made available to
+ -- the security transformation used
+ })
+
+-- BaseType is the type to be protected, and protectionReqd is an
+-- object of class PROTECTION-MAPPING. The use of PROTECTED requires
+-- the importation into the user's module of the PROTECTED parameterized
+-- type, together with the necessary PROTECTION-MAPPING object
+-- definition.
+-- *******************************************
+-- Notation for specifying protection mappings
+-- *******************************************
+PROTECTION-MAPPING ::= CLASS {
+ &SecurityTransformation SECURITY-TRANSFORMATION,
+ -- &SecurityTransformation specifies an ASN.1 object set of the
+ -- SECURITY-TRANSFORMATION class. Use of the particular
+ -- protection mapping implies use of one of the specified
+ -- transformations, with the choice being left to the
+ -- encoding system. Rules for selecting between these security
+ -- transformations may be specified in comments.
+ &protTransferSyntax OBJECT IDENTIFIER DEFAULT {joint-iso-itu-t
+ genericULS(20)
+ generalTransferSyntax(2)},
+ -- Identifies the particular protecting transfer syntax to
+ -- be used in an EMDEDDED PDV encoding for the embedded
+ -- option.
+ &bypassPermitted BOOLEAN DEFAULT FALSE
+ -- Indicates if bypassing of protection is permitted
+}
+WITH SYNTAX {
+ SECURITY-TRANSFORMATION &SecurityTransformation
+ [PROTECTING-TRANSFER-SYNTAX &protTransferSyntax]
+ [BYPASS-PERMITTED &bypassPermitted]
+}
+
+END
+
+-- Generated by Asnp, the ASN.1 pretty-printer of France Telecom R&D
+
+
+-- content of stack:
+--
diff --git a/lib/asn1/test/asn1_SUITE_data/x420/ObjectIdentifiers.asn b/lib/asn1/test/asn1_SUITE_data/x420/ObjectIdentifiers.asn
new file mode 100644
index 0000000000..b4f91f50c5
--- /dev/null
+++ b/lib/asn1/test/asn1_SUITE_data/x420/ObjectIdentifiers.asn
@@ -0,0 +1,46 @@
+-- Module ObjectIdentifiers (X.830:04/1995)
+
+ObjectIdentifiers {joint-iso-itu-t genericULS(20) modules(1)
+ objectIdentifiers(0)} DEFINITIONS AUTOMATIC TAGS ::=
+BEGIN
+
+-- EXPORTS All
+genericULS OBJECT IDENTIFIER ::=
+ {joint-iso-itu-t genericULS(20)}
+
+-- Categories of information object
+modules OBJECT IDENTIFIER ::=
+ {genericULS 1}
+
+generalTransferSyntax OBJECT IDENTIFIER ::= {genericULS 2}
+
+specificTransferSyntax OBJECT IDENTIFIER ::= {genericULS 3}
+
+securityExchanges OBJECT IDENTIFIER ::= {genericULS 4}
+
+securityTransformations OBJECT IDENTIFIER ::= {genericULS 5}
+
+-- ASN.1 modules
+objectIdentifiers OBJECT IDENTIFIER ::= {modules 0}
+
+notation OBJECT IDENTIFIER ::= {modules 1}
+
+gulsSecurityExchanges OBJECT IDENTIFIER ::= {modules 2}
+
+gulsSecurityTransformations OBJECT IDENTIFIER ::= {modules 3}
+
+dirProtectionMappings OBJECT IDENTIFIER ::= {modules 4}
+
+gulsProtectionMappings OBJECT IDENTIFIER ::= {modules 5}
+
+seseAPDUs OBJECT IDENTIFIER ::= {modules 6}
+
+genericProtectingTransferSyntax OBJECT IDENTIFIER ::= {modules 7}
+
+END
+
+-- Generated by Asnp, the ASN.1 pretty-printer of France Telecom R&D
+
+
+-- content of stack:
+--
diff --git a/lib/asn1/test/asn1_SUITE_data/x420/OperationalBindingManagement.asn b/lib/asn1/test/asn1_SUITE_data/x420/OperationalBindingManagement.asn
new file mode 100644
index 0000000000..2044feb155
--- /dev/null
+++ b/lib/asn1/test/asn1_SUITE_data/x420/OperationalBindingManagement.asn
@@ -0,0 +1,263 @@
+-- Module OperationalBindingManagement (X.501:08/1997)
+OperationalBindingManagement {joint-iso-itu-t ds(5) module(1)
+ opBindingManagement(18) 3} DEFINITIONS ::=
+BEGIN
+
+-- EXPORTS All
+-- The types and values defined in this module are exported for use in the other ASN.1 modules contained
+-- within the Directory Specifications, and for the use of other applications which will use them to access
+-- Directory services. Other applications may use them for their own purposes, but this will not constrain
+-- extensions and modifications needed to maintain or improve the Directory service.
+IMPORTS
+ directoryShadowAbstractService, hierarchicalOperationalBindings, dop,
+ directoryAbstractService, distributedOperations, enhancedSecurity
+ FROM UsefulDefinitions {joint-iso-itu-t ds(5) module(1)
+ usefulDefinitions(0) 3}
+ shadowOperationalBinding
+ FROM DirectoryShadowAbstractService directoryShadowAbstractService
+ hierarchicalOperationalBinding, nonSpecificHierarchicalOperationalBinding
+ FROM HierarchicalOperationalBindings hierarchicalOperationalBindings
+ OPERATION, ERROR
+ FROM Remote-Operations-Information-Objects {joint-iso-itu-t
+ remote-operations(4) informationObjects(5) version1(0)}
+ APPLICATION-CONTEXT
+ FROM Remote-Operations-Information-Objects-extensions {joint-iso-itu-t
+ remote-operations(4) informationObjects-extensions(8) version1(0)}
+ id-op-establishOperationalBinding, id-op-modifyOperationalBinding,
+ id-op-terminateOperationalBinding, id-err-operationalBindingError
+ FROM DirectoryOperationalBindingManagementProtocol dop
+ directoryBind, directoryUnbind, securityError, CommonResultsSeq,
+ SecurityParameters
+ FROM DirectoryAbstractService directoryAbstractService
+ OPTIONALLY-PROTECTED-SEQ{}
+ FROM EnhancedSecurity enhancedSecurity
+ AccessPoint
+ FROM DistributedOperations distributedOperations;
+
+--PROTECTED
+-- FROM Notation { joint-iso-ccitt genericULS (20) modules (1) notation (1) }
+-- bind and unbind
+dSAOperationalBindingManagementBind OPERATION ::=
+ directoryBind
+
+dSAOperationalBindingManagementUnbind OPERATION ::= directoryUnbind
+
+-- operations, arguments and results
+establishOperationalBinding OPERATION ::= {
+ ARGUMENT EstablishOperationalBindingArgument
+ RESULT EstablishOperationalBindingResult
+ ERRORS {operationalBindingError | securityError}
+ CODE id-op-establishOperationalBinding
+}
+
+EstablishOperationalBindingArgument ::=
+ OPTIONALLY-PROTECTED-SEQ
+ {SEQUENCE {bindingType [0] OPERATIONAL-BINDING.&id({OpBindingSet}),
+ bindingID [1] OperationalBindingID OPTIONAL,
+ accessPoint [2] AccessPoint,
+ -- symmetric, Role A initiates, or Role B initiates -
+ initiator
+ CHOICE {symmetric
+ [3] OPERATIONAL-BINDING.&both.&EstablishParam
+ ({OpBindingSet}{@bindingType}),
+ roleA-initiates
+ [4] OPERATIONAL-BINDING.&roleA.&EstablishParam
+ ({OpBindingSet}{@bindingType}),
+ roleB-initiates
+ [5] OPERATIONAL-BINDING.&roleB.&EstablishParam
+ ({OpBindingSet}{@bindingType})} OPTIONAL,
+ agreement
+ [6] OPERATIONAL-BINDING.&Agreement
+ ({OpBindingSet}{@bindingType}),
+ valid [7] Validity DEFAULT {},
+ securityParameters [8] SecurityParameters OPTIONAL}}
+
+OperationalBindingID ::= SEQUENCE {identifier INTEGER,
+ version INTEGER
+}
+
+Validity ::= SEQUENCE {
+ validFrom [0] CHOICE {now [0] NULL,
+ time [1] Time} DEFAULT now:NULL,
+ validUntil
+ [1] CHOICE {explicitTermination [0] NULL,
+ time [1] Time
+ } DEFAULT explicitTermination:NULL
+}
+
+Time ::= CHOICE {utcTime UTCTime,
+ generalizedTime GeneralizedTime
+}
+
+EstablishOperationalBindingResult ::=
+ OPTIONALLY-PROTECTED-SEQ
+ {SEQUENCE {bindingType [0] OPERATIONAL-BINDING.&id({OpBindingSet}),
+ bindingID [1] OperationalBindingID OPTIONAL,
+ accessPoint [2] AccessPoint,
+ -- symmetric, Role A replies , or Role B replies
+ initiator
+ CHOICE {symmetric
+ [3] OPERATIONAL-BINDING.&both.&EstablishParam
+ ({OpBindingSet}{@bindingType}),
+ roleA-replies
+ [4] OPERATIONAL-BINDING.&roleA.&EstablishParam
+ ({OpBindingSet}{@bindingType}),
+ roleB-replies
+ [5] OPERATIONAL-BINDING.&roleB.&EstablishParam
+ ({OpBindingSet}{@bindingType})} OPTIONAL,
+ COMPONENTS OF CommonResultsSeq}}
+
+modifyOperationalBinding OPERATION ::= {
+ ARGUMENT ModifyOperationalBindingArgument
+ RESULT ModifyOperationalBindingResult
+ ERRORS {operationalBindingError | securityError}
+ CODE id-op-modifyOperationalBinding
+}
+
+ModifyOperationalBindingArgument ::=
+ OPTIONALLY-PROTECTED-SEQ
+ {SEQUENCE {bindingType [0] OPERATIONAL-BINDING.&id({OpBindingSet}),
+ bindingID [1] OperationalBindingID,
+ accessPoint [2] AccessPoint OPTIONAL,
+ -- symmetric, Role A initiates, or Role B initiates
+ initiator
+ CHOICE {symmetric
+ [3] OPERATIONAL-BINDING.&both.&ModifyParam
+ ({OpBindingSet}{@bindingType}),
+ roleA-initiates
+ [4] OPERATIONAL-BINDING.&roleA.&ModifyParam
+ ({OpBindingSet}{@bindingType}),
+ roleB-initiates
+ [5] OPERATIONAL-BINDING.&roleB.&ModifyParam
+ ({OpBindingSet}{@bindingType})} OPTIONAL,
+ newBindingID [6] OperationalBindingID,
+ newAgreement
+ [7] OPERATIONAL-BINDING.&Agreement
+ ({OpBindingSet}{@bindingType}) OPTIONAL,
+ valid [8] Validity OPTIONAL,
+ securityParameters [9] SecurityParameters OPTIONAL}}
+
+ModifyOperationalBindingResult ::= CHOICE {
+ null [0] NULL,
+ protected
+ [1] OPTIONALLY-PROTECTED-SEQ{SEQUENCE {newBindingID OperationalBindingID,
+ bindingType
+ OPERATIONAL-BINDING.&id
+ ({OpBindingSet}),
+ newAgreement
+ OPERATIONAL-BINDING.&Agreement
+ ({OpBindingSet}{@bindingType}),
+ valid Validity OPTIONAL,
+ COMPONENTS OF CommonResultsSeq
+ }}
+}
+
+terminateOperationalBinding OPERATION ::= {
+ ARGUMENT TerminateOperationalBindingArgument
+ RESULT TerminateOperationalBindingResult
+ ERRORS {operationalBindingError | securityError}
+ CODE id-op-terminateOperationalBinding
+}
+
+TerminateOperationalBindingArgument ::=
+ OPTIONALLY-PROTECTED-SEQ
+ {SEQUENCE {bindingType [0] OPERATIONAL-BINDING.&id({OpBindingSet}),
+ bindingID [1] OperationalBindingID,
+ -- symmetric, Role A initiates, or Role B initiates
+ initiator
+ CHOICE {symmetric
+ [2] OPERATIONAL-BINDING.&both.&TerminateParam
+ ({OpBindingSet}{@bindingType}),
+ roleA-initiates
+ [3] OPERATIONAL-BINDING.&roleA.&TerminateParam
+ ({OpBindingSet}{@bindingType}),
+ roleB-initiates
+ [4] OPERATIONAL-BINDING.&roleB.&TerminateParam
+ ({OpBindingSet}{@bindingType})} OPTIONAL,
+ terminateAt [5] Time OPTIONAL,
+ securityParameters [6] SecurityParameters OPTIONAL}}
+
+TerminateOperationalBindingResult ::= CHOICE {
+ null [0] NULL,
+ protected
+ [1] OPTIONALLY-PROTECTED-SEQ{SEQUENCE {bindingID OperationalBindingID,
+ bindingType
+ OPERATIONAL-BINDING.&id
+ ({OpBindingSet}),
+ terminateAt
+ GeneralizedTime OPTIONAL,
+ COMPONENTS OF CommonResultsSeq
+ }}
+}
+
+-- errors and parameters
+operationalBindingError ERROR ::= {
+ PARAMETER OPTIONALLY-PROTECTED-SEQ {OpBindingErrorParam}
+ CODE id-err-operationalBindingError
+}
+
+OpBindingErrorParam ::= SEQUENCE {
+ problem
+ [0] ENUMERATED {invalidID(0), duplicateID(1), unsupportedBindingType(2),
+ notAllowedForRole(3), parametersMissing(4),
+ roleAssignment(5), invalidStartTime(6), invalidEndTime(7),
+ invalidAgreement(8), currentlyNotDecidable(9),
+ modificationNotAllowed(10)},
+ bindingType [1] OPERATIONAL-BINDING.&id({OpBindingSet}) OPTIONAL,
+ agreementProposal
+ [2] OPERATIONAL-BINDING.&Agreement({OpBindingSet}{@bindingType}) OPTIONAL,
+ retryAt [3] Time OPTIONAL,
+ COMPONENTS OF CommonResultsSeq
+}
+
+-- information object classes
+OPERATIONAL-BINDING ::= CLASS {
+ &Agreement ,
+ &Cooperation OP-BINDING-COOP,
+ &both OP-BIND-ROLE OPTIONAL,
+ &roleA OP-BIND-ROLE OPTIONAL,
+ &roleB OP-BIND-ROLE OPTIONAL,
+ &id OBJECT IDENTIFIER UNIQUE
+}
+WITH SYNTAX {
+ AGREEMENT &Agreement
+ APPLICATION CONTEXTS &Cooperation
+ [SYMMETRIC &both]
+ [ASYMMETRIC
+ [ROLE-A &roleA]
+ [ROLE-B &roleB]]
+ ID &id
+}
+
+OP-BINDING-COOP ::= CLASS {
+ &applContext APPLICATION-CONTEXT,
+ &Operations OPERATION OPTIONAL
+}WITH SYNTAX {&applContext
+ [APPLIES TO &Operations]
+}
+
+OP-BIND-ROLE ::= CLASS {
+ &establish BOOLEAN DEFAULT FALSE,
+ &EstablishParam OPTIONAL,
+ &modify BOOLEAN DEFAULT FALSE,
+ &ModifyParam OPTIONAL,
+ &terminate BOOLEAN DEFAULT FALSE,
+ &TerminateParam OPTIONAL
+}
+WITH SYNTAX {
+ [ESTABLISHMENT-INITIATOR &establish]
+ [ESTABLISHMENT-PARAMETER &EstablishParam]
+ [MODIFICATION-INITIATOR &modify]
+ [MODIFICATION-PARAMETER &ModifyParam]
+ [TERMINATION-INITIATOR &terminate]
+ [TERMINATION-PARAMETER &TerminateParam]
+}
+
+OpBindingSet OPERATIONAL-BINDING ::=
+ {shadowOperationalBinding | hierarchicalOperationalBinding |
+ nonSpecificHierarchicalOperationalBinding}
+
+END -- OperationalBindingManagement
+
+-- Generated by Asnp, the ASN.1 pretty-printer of France Telecom R&D
+
diff --git a/lib/asn1/test/asn1_SUITE_data/x420/PKCS7.asn b/lib/asn1/test/asn1_SUITE_data/x420/PKCS7.asn
new file mode 100644
index 0000000000..ac449b59c7
--- /dev/null
+++ b/lib/asn1/test/asn1_SUITE_data/x420/PKCS7.asn
@@ -0,0 +1,342 @@
+-- Module PKCS7 (X.420:06/1999)
+-- The ASN.1 in version 1.5 of the PKCS#7 document is not defined in an ASN.1 module. This prevents an IMPORT of it into other ASN.1 modules.
+-- This Annex contains a module of PKCS#7 ASN.1 definitions conforming to current ASN.1 standards rather than the obsolescent (and now deprecated) 1988/90 version of ASN.1 used in version 1.5 of PKCS#7.
+-- Extensions to PKCS#7 defined in RFC 2630 are included.
+-- If differences are found between the ASN.1 in the following module and that in PKCS#7, the latter is definitive.
+PKCS7 {iso member-body usa(840) rsadsi(113549) pkcs(1) 7
+ module(0) -- module not currently defined in PKCS#7 --} DEFINITIONS IMPLICIT
+TAGS ::=
+BEGIN
+
+IMPORTS
+ -- Directory Information Framework
+ Attribute, Name
+ --==
+ FROM InformationFramework {joint-iso-itu-t ds(5) module(1)
+ informationFramework(1) 3}
+ -- Directory Authentication Framework
+ AlgorithmIdentifier, AttributeCertificate, Certificate, CertificateList,
+ CertificateSerialNumber, HASH{}, SIGNED{}
+ --==
+ FROM AuthenticationFramework {joint-iso-itu-t ds(5) module(1)
+ authenticationFramework(7) 3};
+
+-- In PKCS#7 the HASHED parameterised type applies the hash function to the
+-- contents octets component of a DER encoding of a value of the parameter.
+-- The ENCRYPTED parameterised type is redefined here because PKCS#7 encrypted values are
+-- defined as OCTET STRING, instead of BIT STRING as in the Directory Authentication Framework
+ENCRYPTED{ToBeEnciphered} ::=
+ OCTET STRING
+ (CONSTRAINED BY {
+ -- must be the result of applying an encipherment procedure to the contents octets component
+ -- of a definite-length BER-encoding of a value of --ToBeEnciphered})
+
+ContentInfo ::= SEQUENCE {
+ content-type PKCS7-CONTENT-TYPE.&id({PKCS7ContentTable}),
+ pkcs7-content [0] PKCS7-CONTENT-TYPE.&Type({PKCS7ContentTable})
+}
+
+PKCS7-CONTENT-TYPE ::= TYPE-IDENTIFIER
+
+PKCS7ContentTable PKCS7-CONTENT-TYPE ::=
+ {data | signed-data | enveloped-data | signed-and-enveloped-data |
+ digested-data | encrypted-data | authenticated-data, ...}
+
+-- Data
+data PKCS7-CONTENT-TYPE ::= {Data
+ IDENTIFIED BY id-data
+}
+
+Data ::= OCTET STRING
+
+-- Signed Data
+signed-data PKCS7-CONTENT-TYPE ::= {SignedData
+ IDENTIFIED BY id-signed-data
+}
+
+SignedData ::= SEQUENCE {
+ version Version,
+ digestAlgorithms DigestAlgorithmIdentifiers,
+ contentInfo ContentInfo,
+ certificates [0] CertificateSet OPTIONAL,
+ crls [1] CertificateRevocationLists OPTIONAL,
+ signerInfos SignerInfos
+}
+
+Version ::= INTEGER
+
+DigestAlgorithmIdentifiers ::= SET OF DigestAlgorithmIdentifier
+
+DigestAlgorithmIdentifier ::= AlgorithmIdentifier
+
+CertificateSet ::= SET OF CertificateChoice
+
+CertificateChoice ::= CHOICE {
+ certificate Certificate,
+ extendedCertificate [0] ExtendedCertificate, -- Obsolete
+ attributeCertificate [1] AttributeCertificate
+}
+
+CertificateRevocationLists ::= SET OF CertificateList
+
+SignerInfos ::= SET OF SignerInfo
+
+SignerInfo ::= SEQUENCE {
+ version Version,
+ signerIdentifier SignerIdentifier,
+ digestAlgorithm DigestAlgorithmIdentifier,
+ authenticatedAttributes [0] Attributes OPTIONAL,
+ digestEncryptionAlgorithm DigestEncryptionAlgorithmIdentifier,
+ encryptedDigest EncryptedDigest,
+ unauthenticatedAttributes [1] Attributes OPTIONAL
+}
+
+SignerIdentifier ::= CHOICE {
+ issuerAndSerialNumber IssuerAndSerialNumber,
+ subjectKeyIdentifier [2] SubjectKeyIdentifier
+}
+
+IssuerAndSerialNumber ::= SEQUENCE {
+ issuer Name,
+ serialNumber CertificateSerialNumber
+}
+
+SubjectKeyIdentifier ::= OCTET STRING
+
+DigestEncryptionAlgorithmIdentifier ::= AlgorithmIdentifier
+
+EncryptedDigest ::= ENCRYPTED{DigestInfo}
+
+DigestInfo ::= SEQUENCE {
+ digestAlgorithm DigestAlgorithmIdentifier,
+ digest Digest
+}
+
+Digest ::=
+ HASH
+ {CHOICE {content
+ [1] PKCS7-CONTENT-TYPE.&Type({PKCS7ContentTable}),
+ authenticated-attributes [0] EXPLICIT Attributes}}
+
+-- Enveloped Data
+enveloped-data PKCS7-CONTENT-TYPE ::= {
+ EnvelopedData
+ IDENTIFIED BY id-enveloped-data
+}
+
+EnvelopedData ::= SEQUENCE {
+ version Version,
+ originatorInfo [0] OriginatorInfo OPTIONAL,
+ recipientInfos RecipientInfos,
+ encryptedContentInfo EncryptedContentInfo,
+ unprotectedAttributes [1] Attributes OPTIONAL
+}
+
+OriginatorInfo ::= SEQUENCE {
+ certificates [0] CertificateSet OPTIONAL,
+ crls [1] CertificateRevocationLists OPTIONAL
+}
+
+RecipientInfos ::= SET SIZE (1..MAX) OF RecipientInfo
+
+RecipientInfo ::= CHOICE {
+ keyTransportRecipientInfo KeyTransportRecipientInfo,
+ keyAgreementRecipientInfo [1] KeyAgreementRecipientInfo,
+ keyEncryptionKeyRecipientInfo [2] KeyEncryptionKeyRecipientInfo
+}
+
+KeyTransportRecipientInfo ::= SEQUENCE {
+ version Version,
+ recipientIdentifier RecipientIdentifier,
+ keyEncryptionAlgorithm KeyEncryptionAlgorithmIdentifier,
+ encryptedKey EncryptedKey
+}
+
+RecipientIdentifier ::= CHOICE {
+ issuerAndSerialNumber IssuerAndSerialNumber,
+ subjectKeyIdentifier [0] SubjectKeyIdentifier
+}
+
+KeyEncryptionAlgorithmIdentifier ::= AlgorithmIdentifier
+
+EncryptedKey ::= OCTET STRING
+
+KeyAgreementRecipientInfo ::= SEQUENCE {
+ version Version,
+ originator [0] OriginatorIdentifierOrKey,
+ userKeyingMaterial [1] EXPLICIT OCTET STRING OPTIONAL,
+ keyEncryptionAlgorithm KeyEncryptionAlgorithmIdentifier,
+ recipientEncryptedKeys RecipientEncryptedKeys
+}
+
+OriginatorIdentifierOrKey ::= CHOICE {
+ issuerAndSerialNumber IssuerAndSerialNumber,
+ subjectKeyIdentifier [0] SubjectKeyIdentifier,
+ originatorPublicKey [1] OriginatorPublicKey
+}
+
+OriginatorPublicKey ::= SEQUENCE {
+ algorithm AlgorithmIdentifier,
+ publicKey BIT STRING
+}
+
+RecipientEncryptedKeys ::= SEQUENCE OF RecipientEncryptedKey
+
+RecipientEncryptedKey ::= SEQUENCE {
+ recipientIdentifier KeyAgreementRecipientIdentifier,
+ encryptedKey EncryptedKey
+}
+
+KeyAgreementRecipientIdentifier ::= CHOICE {
+ issuerAndSerialNumber IssuerAndSerialNumber,
+ recipientKeyIdentifier [0] RecipientKeyIdentifier
+}
+
+RecipientKeyIdentifier ::= SEQUENCE {
+ subjectKeyIdentifier SubjectKeyIdentifier,
+ date GeneralizedTime OPTIONAL,
+ otherKeyAttribute OtherKeyAttribute OPTIONAL
+}
+
+OtherKeyAttribute ::= SEQUENCE {
+ keyAttributeIdentifier OTHER-KEY-ATTRIBUTE.&id({OtherKeyAttributeTable}),
+ keyAttribute
+ OTHER-KEY-ATTRIBUTE.&Type
+ ({OtherKeyAttributeTable}{@keyAttributeIdentifier}) OPTIONAL
+}
+
+OTHER-KEY-ATTRIBUTE ::= TYPE-IDENTIFIER
+
+OtherKeyAttributeTable OTHER-KEY-ATTRIBUTE ::=
+ {...}
+
+KeyEncryptionKeyRecipientInfo ::= SEQUENCE {
+ version Version,
+ keyEncryptionKeyIdentifier KeyEncryptionKeyIdentifier,
+ keyEncryptionAlgorithm KeyEncryptionAlgorithmIdentifier,
+ encryptedKey EncryptedKey
+}
+
+KeyEncryptionKeyIdentifier ::= SEQUENCE {
+ keyIdentifier OCTET STRING,
+ date GeneralizedTime OPTIONAL,
+ otherKeyAttribute OtherKeyAttribute OPTIONAL
+}
+
+EncryptedContentInfo ::= SEQUENCE {
+ contentType PKCS7-CONTENT-TYPE.&id({PKCS7ContentTable}),
+ contentEncryptionAlgorithm ContentEncryptionAlgorithmIdentifier,
+ encryptedContent
+ [0] ENCRYPTED{PKCS7-CONTENT-TYPE.&Type({PKCS7ContentTable}{@.contentType})}
+ OPTIONAL
+}
+
+ContentEncryptionAlgorithmIdentifier ::= AlgorithmIdentifier
+
+-- Signed and Enveloped Data
+signed-and-enveloped-data PKCS7-CONTENT-TYPE ::= {
+ SignedAndEnvelopedData
+ IDENTIFIED BY id-signed-and-enveloped-data
+}
+
+SignedAndEnvelopedData ::= SEQUENCE {
+ version Version,
+ recipientInfos SET SIZE (1..MAX) OF KeyTransportRecipientInfo,
+ digestAlgorithms DigestAlgorithmIdentifiers,
+ encryptedContentInfo EncryptedContentInfo,
+ certificates [0] CertificateSet OPTIONAL,
+ crls [1] CertificateRevocationLists OPTIONAL,
+ signerInfos
+ SET SIZE (1..MAX) OF
+ SignerInfo
+ (WITH COMPONENTS {
+ ...,
+ signerIdentifier (WITH COMPONENTS {
+ issuerAndSerialNumber PRESENT
+ }),
+ authenticatedAttributes ABSENT,
+ unauthenticatedAttributes ABSENT
+ })
+}
+
+-- Digested Data
+digested-data PKCS7-CONTENT-TYPE ::= {
+ DigestedData
+ IDENTIFIED BY id-digested-data
+}
+
+DigestedData ::= SEQUENCE {
+ version Version,
+ digestAlgorithm DigestAlgorithmIdentifier,
+ contentInfo ContentInfo,
+ digest HASH{PKCS7-CONTENT-TYPE.&Type({PKCS7ContentTable})}
+}
+
+-- Encrypted Data
+encrypted-data PKCS7-CONTENT-TYPE ::= {
+ EncryptedData
+ IDENTIFIED BY id-encrypted-data
+}
+
+EncryptedData ::= SEQUENCE {
+ version Version,
+ encryptedContentInfo EncryptedContentInfo,
+ unprotectedAttributes [1] Attributes OPTIONAL
+}
+
+-- Authenticated Data
+authenticated-data PKCS7-CONTENT-TYPE ::= {
+ AuthenticatedData
+ IDENTIFIED BY id-authenticated-data
+}
+
+AuthenticatedData ::= SEQUENCE {
+ version Version,
+ originatorInfo [0] OriginatorInfo OPTIONAL,
+ recipientInfos RecipientInfos,
+ macAlgorithm MessageAuthenticationCodeAlgorithmIdentifier,
+ digestAlgorithm [1] DigestAlgorithmIdentifier OPTIONAL,
+ contentInfo ContentInfo,
+ authenticatedAttributes [2] Attributes OPTIONAL,
+ messageAuthenticationCode MessageAuthenticationCode,
+ unauthenticatedAttributes [3] Attributes OPTIONAL
+}
+
+MessageAuthenticationCodeAlgorithmIdentifier ::= AlgorithmIdentifier
+
+MessageAuthenticationCode ::= OCTET STRING
+
+-- Object Identifiers
+id-pkcs OBJECT IDENTIFIER ::=
+ {iso member-body usa(840) rsadsi(113549) pkcs(1)}
+
+id-data OBJECT IDENTIFIER ::= {id-pkcs 7 1}
+
+id-signed-data OBJECT IDENTIFIER ::= {id-pkcs 7 2}
+
+id-enveloped-data OBJECT IDENTIFIER ::= {id-pkcs 7 3}
+
+id-signed-and-enveloped-data OBJECT IDENTIFIER ::= {id-pkcs 7 4}
+
+id-digested-data OBJECT IDENTIFIER ::= {id-pkcs 7 5}
+
+id-encrypted-data OBJECT IDENTIFIER ::= {id-pkcs 7 6}
+
+id-authenticated-data OBJECT IDENTIFIER ::= {id-pkcs 9 16 1 2}
+
+-- Definitions from PKCS#6
+ExtendedCertificate ::=
+ SIGNED{ExtendedCertificateInfo}
+
+ExtendedCertificateInfo ::= SEQUENCE {
+ version Version,
+ certificate Certificate,
+ attributes Attributes
+}
+
+Attributes ::= SET OF Attribute
+
+END -- of PKCS#7
+
+-- Generated by Asnp, the ASN.1 pretty-printer of France Telecom R&D
+
diff --git a/lib/asn1/test/asn1_SUITE_data/x420/PKCS7BodyPartType.asn b/lib/asn1/test/asn1_SUITE_data/x420/PKCS7BodyPartType.asn
new file mode 100644
index 0000000000..525ee3c5ec
--- /dev/null
+++ b/lib/asn1/test/asn1_SUITE_data/x420/PKCS7BodyPartType.asn
@@ -0,0 +1,31 @@
+-- Module PKCS7BodyPartType (X.420:06/1999)
+PKCS7BodyPartType {joint-iso-itu-t mhs(6) ipms(1) modules(0)
+ pkcs7-body-part-type(16)} DEFINITIONS IMPLICIT TAGS ::=
+BEGIN
+
+IMPORTS
+ -- PKCS#7
+ ContentInfo
+ FROM PKCS7 {iso(1) member-body(2) usa(840) rsadsi(113549) pkcs(1)
+ 7 module(0)}
+ -- module not formally defined in the PKCS#7document, therefore defined in Annex O
+ -- IPMS Information Objects
+ EXTENDED-BODY-PART-TYPE
+ FROM IPMSInformationObjects {joint-iso-itu-t mhs(6) ipms(1) modules(0)
+ information-objects(2) version-1999(1)}
+ -- IPMS Object Identifiers
+ id-et-pkcs7
+ --==
+ FROM IPMSObjectIdentifiers {joint-iso-itu-t mhs(6) ipms(1) modules(0)
+ object-identifiers(0) version-1999(1)};
+
+-- PKCS7 body part
+pkcs7-body-part EXTENDED-BODY-PART-TYPE ::= {
+ DATA {ContentInfo
+ IDENTIFIED BY id-et-pkcs7}
+}
+
+END -- of PKCS7BodyPartType
+
+-- Generated by Asnp, the ASN.1 pretty-printer of France Telecom R&D
+
diff --git a/lib/asn1/test/asn1_SUITE_data/x420/Protected-Part-Descriptors.asn b/lib/asn1/test/asn1_SUITE_data/x420/Protected-Part-Descriptors.asn
new file mode 100644
index 0000000000..5512f1590b
--- /dev/null
+++ b/lib/asn1/test/asn1_SUITE_data/x420/Protected-Part-Descriptors.asn
@@ -0,0 +1,74 @@
+-- Module Protected-Part-Descriptors (T.415:03/1993)
+
+Protected-Part-Descriptors {2 8 1 5 13} DEFINITIONS ::=
+BEGIN
+
+EXPORTS
+ Sealed-Doc-Prof-Descriptor, Enciphered-Doc-Prof-Descriptor,
+ Preenciphered-Bodypart-Descriptor, Postenciphered-Bodypart-Descriptor;
+
+IMPORTS Protected-Part-Identifier
+ FROM Identifiers-and-Expressions; -- see 7.8
+
+Sealed-Doc-Prof-Descriptor ::= SEQUENCE {
+ sealed-doc-prof-identifier Protected-Part-Identifier,
+ sealed-doc-prof-information Document-Profile-Attribute-Names
+}
+
+Document-Profile-Attribute-Names ::= BIT STRING {
+ generic-layout-structure(0), specific-layout-structure(1),
+ generic-logical-structure(2), specific-logical-structure(3),
+ layout-styles(4), presentation-styles(5), sealed-profiles(6),
+ enciphered-profiles(7), pre-enciphered-body-parts(8),
+ post-enciphered-body-parts(9), external-document-class(10),
+ resource-document(11), resources(12), document-application-profile(13),
+ document-application-profile-defaults(14), document-architecture-class(15),
+ content-architecture-classes(16), interchange-format-class(17),
+ oda-version(18), alternative-feature-sets(19), profile-character-sets(20),
+ comments-character-sets(21), alternative-representation-character-sets(22),
+ page-dimensions(23), medium-types(24), layout-paths(25), protections(26),
+ block-alignments(27), fill-orders(28), transparencies(29), colours(30),
+ colours-of-layout-object(31), object-colour-tables(32),
+ content-background-colours(33), content-foreground-colours(34),
+ content-colour-tables(35), borders(36), page-positions(37),
+ types-of-coding(38), coding-attributes(39), presentation-features(40),
+ number-of-objects-per-page(41), unit-scaling(42), fonts-list(43),
+ colour-characteristics(44), colour-spaces-list(45),
+ assured-reproduction-areas(86), title(46), subject(47),
+ document-reference(48), document-type(49), abstract(50), keywords(51),
+ document-date-and-time(52), creation-date-and-time(53),
+ local-filing-date-and-time(54), expiry-date-and-time(55),
+ start-date-and-time(56), purge-date-and-time(57), release-date-and-time(58),
+ revision-history(59), organizations(60), preparers(61), owners(62),
+ authors(63), copyright(64), status(65), user-specific-codes(66),
+ distribution-list(67), additional-information(68),
+ references-to-other-documents(69), superseded-documents(70),
+ local-file-references(71), document-size(72), number-of-pages(73),
+ languages(74), authorization(75), security-classification(76),
+ access-rights(77), sealed-information-encoding(78), oda-security-label(79),
+ sealed-document-profiles(80), pre-sealed-document-body-parts(81),
+ post-sealed-document-body-parts(82), enciphered-document-profiles(83),
+ pre-enciphered-document-body-parts(84),
+ post-enciphered-document-body-parts(85)}
+
+Enciphered-Doc-Prof-Descriptor ::= SEQUENCE {
+ enciphered-doc-prof-identifier Protected-Part-Identifier,
+ enciphered-doc-prof-information Enciphered-Information
+}
+
+Preenciphered-Bodypart-Descriptor ::= SEQUENCE {
+ preenciphered-bodypart-identifier Protected-Part-Identifier,
+ preenciphered-bodypart-info Enciphered-Information
+}
+
+Postenciphered-Bodypart-Descriptor ::= SEQUENCE {
+ postenciphered-bodypart-identifier Protected-Part-Identifier,
+ postenciphered-bodypart-info Enciphered-Information
+}
+
+Enciphered-Information ::= OCTET STRING
+
+END
+
+-- Generated by Asnp, the ASN.1 pretty-printer of France Telecom R&D
+
diff --git a/lib/asn1/test/asn1_SUITE_data/x420/ProtocolObjectIdentifiers.asn b/lib/asn1/test/asn1_SUITE_data/x420/ProtocolObjectIdentifiers.asn
new file mode 100644
index 0000000000..d6e88a2e47
--- /dev/null
+++ b/lib/asn1/test/asn1_SUITE_data/x420/ProtocolObjectIdentifiers.asn
@@ -0,0 +1,140 @@
+-- Module ProtocolObjectIdentifiers (X.519 TC2:08/1997)
+
+ProtocolObjectIdentifiers {joint-iso-itu-t ds(5) module(1)
+ protocolObjectIdentifiers(4) 3} DEFINITIONS ::=
+BEGIN
+
+-- EXPORTS All
+-- The types and values defined in this module are exported for use in the other ASN.1 modules contained
+-- within the Directory Specifications, and for the use of other applications which will use them to access
+-- Directory services. Other applications may use them for their own purposes, but this will not constrain
+-- extensions and modifications needed to maintain or improve the Directory service.
+IMPORTS
+ id-rosObject, id-contract, id-package, id-ac, id-as
+ FROM UsefulDefinitions {joint-iso-itu-t ds(5) module(1)
+ usefulDefinitions(0) 3};
+
+-- ROS Objects
+id-rosObject-dua OBJECT IDENTIFIER ::= {id-rosObject 1}
+
+id-rosObject-directory OBJECT IDENTIFIER ::= {id-rosObject 2}
+
+id-rosObject-dapDSA OBJECT IDENTIFIER ::= {id-rosObject 3}
+
+id-rosObject-dspDSA OBJECT IDENTIFIER ::= {id-rosObject 4}
+
+id-rosObject-dopDSA OBJECT IDENTIFIER ::= {id-rosObject 7}
+
+id-rosObject-initiatingConsumerDSA OBJECT IDENTIFIER ::= {id-rosObject 8}
+
+id-rosObject-respondingSupplierDSA OBJECT IDENTIFIER ::= {id-rosObject 9}
+
+id-rosObject-initiatingSupplierDSA OBJECT IDENTIFIER ::= {id-rosObject 10}
+
+id-rosObject-respondingConsumerDSA OBJECT IDENTIFIER ::= {id-rosObject 11}
+
+-- contracts
+id-contract-dap OBJECT IDENTIFIER ::= {id-contract 1}
+
+id-contract-dsp OBJECT IDENTIFIER ::= {id-contract 2}
+
+id-contract-shadowConsumer OBJECT IDENTIFIER ::= {id-contract 3}
+
+id-contract-shadowSupplier OBJECT IDENTIFIER ::= {id-contract 4}
+
+id-contract-dop OBJECT IDENTIFIER ::= {id-contract 5}
+
+-- packages
+id-package-read OBJECT IDENTIFIER ::= {id-package 1}
+
+id-package-search OBJECT IDENTIFIER ::= {id-package 2}
+
+id-package-modify OBJECT IDENTIFIER ::= {id-package 3}
+
+id-package-chainedRead OBJECT IDENTIFIER ::= {id-package 4}
+
+id-package-chainedSearch OBJECT IDENTIFIER ::= {id-package 5}
+
+id-package-chainedModify OBJECT IDENTIFIER ::= {id-package 6}
+
+id-package-shadowConsumer OBJECT IDENTIFIER ::= {id-package 7}
+
+id-package-shadowSupplier OBJECT IDENTIFIER ::= {id-package 8}
+
+id-package-operationalBindingManagement OBJECT IDENTIFIER ::= {id-package 9}
+
+id-package-dapConnection OBJECT IDENTIFIER ::= {id-package 10}
+
+id-package-dspConnection OBJECT IDENTIFIER ::= {id-package 11}
+
+id-package-dispConnection OBJECT IDENTIFIER ::= {id-package 12}
+
+id-package-dopConnection OBJECT IDENTIFIER ::= {id-package 13}
+
+-- application contexts
+id-ac-directoryAccessAC OBJECT IDENTIFIER ::=
+ {id-ac 1}
+
+id-ac-directorySystemAC OBJECT IDENTIFIER ::= {id-ac 2}
+
+id-ac-directoryOperationalBindingManagementAC OBJECT IDENTIFIER ::= {id-ac 3}
+
+id-ac-shadowConsumerInitiatedAC OBJECT IDENTIFIER ::= {id-ac 4}
+
+id-ac-shadowSupplierInitiatedAC OBJECT IDENTIFIER ::= {id-ac 5}
+
+id-ac-reliableShadowSupplierInitiatedAC OBJECT IDENTIFIER ::= {id-ac 6}
+
+id-ac-reliableShadowConsumerInitiatedAC OBJECT IDENTIFIER ::= {id-ac 7}
+
+id-ac-shadowSupplierInitiatedAsynchronousAC OBJECT IDENTIFIER ::= {id-ac 8}
+
+id-ac-shadowConsumerInitiatedAsynchronousAC OBJECT IDENTIFIER ::= {id-ac 9}
+
+id-ac-directoryAccessWith2or3seAC OBJECT IDENTIFIER ::= {id-ac 10}
+
+id-ac-directorySystemWith2or3seAC OBJECT IDENTIFIER ::= {id-ac 11}
+
+id-ac-shadowSupplierInitiatedWith2or3seAC OBJECT IDENTIFIER ::= {id-ac 12}
+
+id-ac-shadowConsumerInitiatedWith2or3seAC OBJECT IDENTIFIER ::= {id-ac 13}
+
+id-ac-reliableShadowSupplierInitiatedWith2or3seAC OBJECT IDENTIFIER ::=
+ {id-ac 14}
+
+id-ac-reliableShadowConsumerInitiatedWith2or3seAC OBJECT IDENTIFIER ::=
+ {id-ac 15}
+
+id-ac-directoryOperationalBindingManagementWith2or3seAC OBJECT IDENTIFIER ::=
+ {id-ac 16}
+
+-- ASEs (obsolete)
+-- id-ase-readASE OBJECT IDENTIFIER ::= {id-ase 1}
+-- id-ase-searchASE OBJECT IDENTIFIER ::= {id-ase 2}
+-- id-ase-modifyASE OBJECT IDENTIFIER ::= {id-ase 3}
+-- id-ase-chainedReadASE OBJECT IDENTIFIER ::= {id-ase 4}
+-- id-ase-chainedSearchASE OBJECT IDENTIFIER ::= {id-ase 5}
+-- id-ase-chainedModifyASE OBJECT IDENTIFIER ::= {id-ase 6}
+-- id-ase-operationalBindingManagementASE OBJECT IDENTIFIER ::= {id-ase 7}
+-- id-ase-shadowConsumerASE OBJECT IDENTIFIER ::= {id-ase 8}
+-- id-ase-shadowSupplierASE OBJECT IDENTIFIER ::= {id-ase 9}
+-- abstract syntaxes
+id-as-directoryAccessAS OBJECT IDENTIFIER ::=
+ {id-as 1}
+
+id-as-directorySystemAS OBJECT IDENTIFIER ::= {id-as 2}
+
+id-as-directoryShadowAS OBJECT IDENTIFIER ::= {id-as 3}
+
+id-as-directoryOperationalBindingManagementAS OBJECT IDENTIFIER ::= {id-as 4}
+
+id-as-directoryReliableShadowAS OBJECT IDENTIFIER ::= {id-as 5}
+
+id-as-reliableShadowBindingAS OBJECT IDENTIFIER ::= {id-as 6}
+
+id-as-2or3se OBJECT IDENTIFIER ::= {id-as 7}
+
+END -- ProtocolObjectIdentifiers
+
+-- Generated by Asnp, the ASN.1 pretty-printer of France Telecom R&D
+
diff --git a/lib/asn1/test/asn1_SUITE_data/x420/Raster-Gr-Coding-Attributes.asn b/lib/asn1/test/asn1_SUITE_data/x420/Raster-Gr-Coding-Attributes.asn
new file mode 100644
index 0000000000..258c5f0b23
--- /dev/null
+++ b/lib/asn1/test/asn1_SUITE_data/x420/Raster-Gr-Coding-Attributes.asn
@@ -0,0 +1,75 @@
+-- Module Raster-Gr-Coding-Attributes (T.417:03/1993)
+
+Raster-Gr-Coding-Attributes {2 8 1 7 3} DEFINITIONS ::=
+BEGIN
+
+EXPORTS
+ Raster-Gr-Coding-Attributes, Compression, Tile-Type,
+ Bits-Per-Colour-Component, Subsampling;
+
+IMPORTS Coordinate-Pair
+ FROM Raster-Gr-Presentation-Attributes {2 8 1 7 2};
+
+Raster-Gr-Coding-Attributes ::= SET {
+ number-of-pels-per-line [0] IMPLICIT INTEGER OPTIONAL,
+ number-of-lines [1] IMPLICIT INTEGER OPTIONAL,
+ compression [2] IMPLICIT Compression OPTIONAL,
+ number-of-discarded-pels [3] IMPLICIT INTEGER OPTIONAL,
+ bits-per-colour-component [4] Bits-Per-Colour-Component OPTIONAL,
+ interleaving-format
+ [5] IMPLICIT INTEGER {pel(0), line(1), plane(2), stripe(3)} OPTIONAL,
+ number-of-pels-per-tile-line [6] IMPLICIT INTEGER OPTIONAL,
+ number-of-lines-per-tile [7] IMPLICIT INTEGER OPTIONAL,
+ tiling-offset [8] IMPLICIT Coordinate-Pair OPTIONAL,
+ tile-types [9] IMPLICIT SEQUENCE OF Tile-Type OPTIONAL,
+ subsampling [10] IMPLICIT Subsampling OPTIONAL,
+ jpeg-coding-mode
+ [11] IMPLICIT INTEGER {-- Huffman coding
+ baseline(0), huffman-extended-sequential-DCT(1),
+ huffman-progressive-DCT(2),
+ huffman-spatial-lossless(3),
+ -- arithmetic coding
+ arithmetic-extended-sequential-DCT(9),
+ arithmetic-progressive-DCT(10),
+ arithmetic-spatial-lossless(11)},
+ jpeg-quantization-table
+ [12] IMPLICIT INTEGER {associated(0), default(1)} OPTIONAL,
+ jpeg-huffman-table
+ [13] IMPLICIT INTEGER {associated(0), preferred(1)},
+ -- basic and default value is "associated".
+ jbig-differential-layer
+ [17] IMPLICIT INTEGER {dl-not-present(0), dl-encoded-without-tp-and-dp(1),
+ dl-encoded-with-tp(2), dl-encoded-with-dp(3),
+ dl-encoded-with-dp-and-private-dp-table(4),
+ dl-encoded-with-tp-and-dp(5),
+ dl-encoded-with-tp-dp-and-private-dp-table(6)}
+ OPTIONAL,
+ number-of-lines-per-stripe [18] IMPLICIT INTEGER OPTIONAL
+}
+
+Compression ::= INTEGER {uncompressed(0), compressed(1)}
+
+Tile-Type ::= INTEGER {
+ null-background(0), null-foreground(1), t6-encoded(2),
+ t4-one-dimensional-encoded(3), t4-two-dimensional-encoded(4),
+ bitmap-encoded(5), t6-encoded-msb(6), t4-one-dimensional-encoded-msb(7),
+ t4-two-dimensional-encoded-msb(8), jbig-bits-per-component-eq-1(9),
+ jpeg(10), jbig-bits-per-component-gr-1(11)}
+
+Bits-Per-Colour-Component ::= CHOICE {
+ single-integer INTEGER,
+ component-list SEQUENCE OF INTEGER
+}
+
+Subsampling ::= OCTET STRING
+
+-- The value OCTET STRING shall be chosen from the
+-- following table:
+-- Semantic Meaning JPEG notations Octet strings
+-- 4:1:1 ((2,2),(1,1),(1,1)) '221111'H
+-- 2:1:1 or 4:2:2 ((2,1),(1,1),(1,1)) '211111'H
+-- 1:1:1 ((1,1),(1,1),(1,1)) '111111'H
+END
+
+-- Generated by Asnp, the ASN.1 pretty-printer of France Telecom R&D
+
diff --git a/lib/asn1/test/asn1_SUITE_data/x420/Raster-Gr-Presentation-Attributes.asn b/lib/asn1/test/asn1_SUITE_data/x420/Raster-Gr-Presentation-Attributes.asn
new file mode 100644
index 0000000000..c8f3a2ff33
--- /dev/null
+++ b/lib/asn1/test/asn1_SUITE_data/x420/Raster-Gr-Presentation-Attributes.asn
@@ -0,0 +1,92 @@
+-- Module Raster-Gr-Presentation-Attributes (T.417:03/1993)
+
+Raster-Gr-Presentation-Attributes {2 8 1 7 2} DEFINITIONS ::=
+BEGIN
+
+EXPORTS
+ Raster-Graphics-Attributes, Clipping, Measure-Pair, One-Of-Four-Angles,
+ One-Of-Two-Angles, Pel-Transmission-Density, Pel-Spacing, Spacing-Ratio,
+ Image-Dimensions, Coordinate-Pair;
+
+Raster-Graphics-Attributes ::= SET {
+ pel-path [0] IMPLICIT One-Of-Four-Angles OPTIONAL,
+ line-progression [1] IMPLICIT One-Of-Two-Angles OPTIONAL,
+ pel-transmission-density [2] IMPLICIT Pel-Transmission-Density OPTIONAL,
+ initial-offset [3] IMPLICIT Measure-Pair OPTIONAL,
+ clipping [4] IMPLICIT Clipping OPTIONAL,
+ pel-spacing [5] Pel-Spacing OPTIONAL,
+ spacing-ratio [6] IMPLICIT Spacing-Ratio OPTIONAL,
+ image-dimensions [7] Image-Dimensions OPTIONAL
+}
+
+One-Of-Four-Angles ::= INTEGER {
+ d0(0), -- d0
+ d90(1), -- d90
+ d180(2), --d180
+ d270(3) -- d270--}
+
+One-Of-Two-Angles ::= INTEGER {d90(1), -- d90
+ d270(3) -- d270 --}
+
+Pel-Transmission-Density ::= INTEGER {
+ p5(2), -- 5 BMU (240 pels/25.4 mm)
+ p4(3), -- 4 BMU (300 pels/25.4 mm)
+ p3(4), -- 3 BMU (400 pels/25.4 mm)
+ p2(5), -- 2 BMU (600 pels/25.4 mm)
+ p1(6), -- 1 BMU (1200 pels/25.4 mm)
+ colour-grey-scale-p12(10), -- 12 BMU (100 pels/25.4 mm)
+ colour-grey-scale-p6(11), -- 6 BMU (200 pels/25.4 mm)
+ colour-grey-scale-p4(13), -- 4 BMU (300 pels/25.4 mm)
+ colour-grey-scale-p3(14), -- 3 BMU (400 pels/25.4 mm)
+ colour-grey-scale-p2(15), -- 2 BMU (600 pels/25.4 mm)
+ colour-grey-scale-p1(16), -- 1 BMU (1200 pels/25.4 mm)
+ p6(1)} -- 6 BMU (200 pels/25.4 mm)
+
+-- default and basic value is p6 (1)
+Measure-Pair ::= SEQUENCE {
+ horizontal [0] IMPLICIT INTEGER,
+ vertical [0] IMPLICIT INTEGER
+}
+
+Clipping ::= SEQUENCE {
+ first-coordinate-pair [0] IMPLICIT Coordinate-Pair OPTIONAL,
+ second-coordinate-pair [1] IMPLICIT Coordinate-Pair OPTIONAL
+}
+
+Coordinate-Pair ::= SEQUENCE {x-coordinate INTEGER,
+ y-coordinate INTEGER
+}
+
+Pel-Spacing ::= CHOICE {
+ spacing
+ [0] IMPLICIT SEQUENCE {length [0] INTEGER,
+ pel-spaces [0] INTEGER},
+ null [1] IMPLICIT NULL
+}
+
+Spacing-Ratio ::= SEQUENCE {
+ line-spacing-value INTEGER,
+ pel-spacing-value INTEGER
+}
+
+Image-Dimensions ::= CHOICE {
+ width-controlled
+ [0] IMPLICIT SEQUENCE {minimum-width [0] INTEGER,
+ preferred-width [0] INTEGER},
+ height-controlled
+ [1] IMPLICIT SEQUENCE {minimum-height INTEGER,
+ preferred-height INTEGER},
+ area-controlled
+ [2] IMPLICIT SEQUENCE {minimum-width INTEGER,
+ preferred-width INTEGER,
+ minimum-height INTEGER,
+ preferred-height INTEGER,
+ aspect-ratio-flag INTEGER {fixed(0), variable(1)}
+ },
+ automatic [3] IMPLICIT NULL
+}
+
+END
+
+-- Generated by Asnp, the ASN.1 pretty-printer of France Telecom R&D
+
diff --git a/lib/asn1/test/asn1_SUITE_data/x420/Raster-Gr-Profile-Attributes.asn b/lib/asn1/test/asn1_SUITE_data/x420/Raster-Gr-Profile-Attributes.asn
new file mode 100644
index 0000000000..365144ff35
--- /dev/null
+++ b/lib/asn1/test/asn1_SUITE_data/x420/Raster-Gr-Profile-Attributes.asn
@@ -0,0 +1,76 @@
+-- Module Raster-Gr-Profile-Attributes (T.417:03/1993)
+
+Raster-Gr-Profile-Attributes {2 8 1 7 4} DEFINITIONS ::=
+BEGIN
+
+EXPORTS
+ Ra-Gr-Presentation-Feature, Ra-Gr-Coding-Attribute,
+ Raster-Gr-Content-Defaults;
+
+IMPORTS
+ One-Of-Four-Angles, One-Of-Two-Angles, Pel-Transmission-Density,
+ Measure-Pair, Clipping, Pel-Spacing, Spacing-Ratio, Image-Dimensions,
+ Coordinate-Pair, Raster-Graphics-Attributes
+ FROM Raster-Gr-Presentation-Attributes {2 8 1 7 2}
+ Compression, Tile-Type, Bits-Per-Colour-Component, Subsampling
+ FROM Raster-Gr-Coding-Attributes {2 8 1 7 3};
+
+Ra-Gr-Coding-Attribute ::= CHOICE {
+ compression [0] IMPLICIT Compression,
+ bits-per-colour-component [4] Bits-Per-Colour-Component,
+ interleaving-format
+ [5] IMPLICIT INTEGER {pel(0), line(1), plane(2), stripe(3)},
+ number-of-pels-per-tile-line [6] IMPLICIT INTEGER,
+ number-of-lines-per-tile [7] IMPLICIT INTEGER,
+ tiling-offset [8] IMPLICIT Coordinate-Pair,
+ tiling-types [9] IMPLICIT Tile-Type,
+ subsampling [10] IMPLICIT Subsampling,
+ jpeg-coding-mode
+ [11] IMPLICIT INTEGER {-- Huffman coding
+ huffman-baseline(0),
+ huffman-extended-sequential-DCT(1),
+ huffman-progressive-DCT(2),
+ huffman-spatial-lossless(3),
+ -- arithmetic coding
+ arithmetic-progressive-DCT(10),
+ arithmetic-spatial-lossless(11)},
+ jpeg-quantization-table
+ [12] IMPLICIT INTEGER {associated(0), default(1)},
+ jpeg-huffman-table
+ [13] IMPLICIT INTEGER {associated(0), preferred(1)},
+ jbig-tp-for-base-layer [14] IMPLICIT INTEGER {not-used(0), used(1)},
+ jbig-differential-layer
+ [15] IMPLICIT INTEGER {dl-not-present(0), dl-encoded-without-tp-and-dp(1),
+ dl-encoded-with-tp(2), dl-encoded-with-dp(3),
+ dl-encoded-with-dp-and-private-dp-table(4),
+ dl-encoded-with-tp-and-dp(5),
+ dl-encoded-with-tp-dp-and-private-dp-table(6)},
+ number-of-lines-per-stripe [16] IMPLICIT INTEGER
+}
+
+Ra-Gr-Presentation-Feature ::= CHOICE {
+ initial-offset [3] IMPLICIT Measure-Pair,
+ clipping [4] IMPLICIT Clipping,
+ pel-spacing [5] Pel-Spacing,
+ spacing-ratio [6] IMPLICIT Spacing-Ratio,
+ image-dimensions [7] Image-Dimensions,
+ pel-path [9] IMPLICIT One-Of-Four-Angles,
+ line-progression [10] IMPLICIT One-Of-Two-Angles,
+ pel-transmission-density [11] IMPLICIT Pel-Transmission-Density
+}
+
+-- The tag values used above preserve compatibility
+-- with Group 4 Class I facsimile data streams.
+Raster-Gr-Content-Defaults ::= SET {
+ COMPONENTS OF Raster-Graphics-Attributes,
+ compression [8] IMPLICIT Compression OPTIONAL,
+ number-of-pels-per-tile-line [11] IMPLICIT INTEGER OPTIONAL,
+ number-of-lines-per-tile [12] IMPLICIT INTEGER OPTIONAL,
+ tiling-offset [13] IMPLICIT Coordinate-Pair OPTIONAL,
+ tiling-type [14] IMPLICIT Tile-Type OPTIONAL
+}
+
+END
+
+-- Generated by Asnp, the ASN.1 pretty-printer of France Telecom R&D
+
diff --git a/lib/asn1/test/asn1_SUITE_data/x420/Reliable-Transfer-APDU.asn b/lib/asn1/test/asn1_SUITE_data/x420/Reliable-Transfer-APDU.asn
new file mode 100644
index 0000000000..d00570b7e7
--- /dev/null
+++ b/lib/asn1/test/asn1_SUITE_data/x420/Reliable-Transfer-APDU.asn
@@ -0,0 +1,132 @@
+-- Module Reliable-Transfer-APDU (X.228:11/1988)
+
+Reliable-Transfer-APDU {joint-iso-itu-t reliable-transfer(3) apdus(0)}
+DEFINITIONS ::=
+BEGIN
+
+EXPORTS
+ rTSE, rTSE-abstract-syntax, RTORQapdu, RTOACapdu, RTORJapdu, RTABapdu; -- for use by Presentation Layer only
+
+IMPORTS
+ CONTRACT
+ FROM Remote-Operations-Information-Objects {joint-iso-itu-t
+ remote-operations(4) informationObjects(5) version1(0)};
+
+OPEN ::= CLASS {&Type
+}WITH SYNTAX {TYPE &Type
+}
+
+rTSE-abstract-syntax OBJECT IDENTIFIER ::=
+ {joint-iso-itu-t reliable-transfer(3) abstract-syntax(2)}
+
+rTSE CONTRACT ::= {ID {joint-iso-itu-t reliable-transfer(3) aseID(1)}
+}
+
+RTSE-apdus ::= CHOICE {
+ rtorq-apdu [16] IMPLICIT RTORQapdu,
+ rtoac-apdu [17] IMPLICIT RTOACapdu,
+ rtorj-apdu [18] IMPLICIT RTORJapdu,
+ rttp-apdu RTTPapdu,
+ rttr-apdu RTTRapdu,
+ rtab-apdu [22] IMPLICIT RTABapdu
+}
+
+-- Tags [19], [20], [21] are used by the values of the UNBIND macro of the RO-notation of
+-- Recommendation X.219. Tags [0] to [15] inclusive are reserved for the
+-- use by the APDUs of ROSE (Recommendation X229). Any occurrence of
+-- ANY in this module shall be replaced by a single ASN. 1 type (if any) in an RTSE-user
+-- protocol specification. In addition any RTSE-user protocol sharing a single named
+-- abstract syntax with the RTSE protocol shall use distinct tags for the single
+-- presentation data values in the user data parameters of the RT-CLOSE (if any) and
+-- RT- TRANSFER services. These tags shall be distinct from the tag values [16], [17],
+-- [18] and [22] and from the ASN. 1 types INTEGER and OCTET STRING.
+-- Note - The above conditions are ensured, if the RTSE-user protocol specification uses the
+-- RO-notation of Recommendation X229.
+-- In X.410-1984 mode only the components of RTORQapdu, RTOACapdu, RTORJapdu
+-- and RTABapdu are used by the presentation layer. This has the effect that the following
+-- APDU types appear in the protocol in X.410-1984 mode instead of the alternative types
+-- of the RTSE-apdus type:
+-- RTORQapdu
+-- RTOACapdu
+-- RTORJapdu
+-- RTTPapdu
+-- RTTRapdu
+-- RTABapdu
+RTORQapdu ::= SET {
+ checkpointSize [0] IMPLICIT INTEGER DEFAULT 0,
+ windowSize [1] IMPLICIT INTEGER DEFAULT 3,
+ dialogueMode
+ [2] IMPLICIT INTEGER {monologue(0), twa(1)} DEFAULT monologue,
+ connectionDataRQ [3] ConnectionData,
+ applicationProtocol
+ [4] IMPLICIT INTEGER OPTIONAL --solely in X.410-1984 mode--
+}
+
+RTOACapdu ::= SET {
+ checkpointSize [0] IMPLICIT INTEGER DEFAULT 0,
+ windowSize [1] IMPLICIT INTEGER DEFAULT 3,
+ connectionDataAC [2] ConnectionData
+}
+
+RTORJapdu ::= SET {
+ refuseReason [0] IMPLICIT RefuseReason OPTIONAL, -- only in X.410-1984 mode
+ userDataRJ
+ [1] OPEN.&Type OPTIONAL -- RTSE user data, only in normal mode--
+}
+
+RTTPapdu ::= -- priority-- INTEGER
+
+RTTRapdu ::= OCTET STRING
+
+RTABapdu ::= SET {
+ abortReason [0] IMPLICIT AbortReason OPTIONAL,
+ reflectedParameter [1] IMPLICIT BIT STRING OPTIONAL,
+ -- 8 bits maximum, only if abortReason is invalidParameter
+ userdataAB
+ [2] OPEN.&Type OPTIONAL -- only in normal mode and if abortReason--
+ -- is userError
+}
+
+ConnectionData ::= CHOICE {
+ open [0] OPEN.&Type, -- RTSE user data
+
+ -- this alternative is encoded as [0] IMPLICIT NULL
+ -- in the case of absence of RTSE user data,
+ recover [1] IMPLICIT SessionConnectionIdentifier
+}
+
+SessionConnectionIdentifier ::= SEQUENCE {
+ callingSSuserReference CallingSSuserReference,
+ commonReference CommonReference,
+ additionalReferenceInformation
+ [0] IMPLICIT AdditionalReferenceInformation OPTIONAL
+}
+
+RefuseReason ::= INTEGER {
+ rtsBusy(0), cannotRecover(1), validationFailure(2),
+ unacceptableDialogueMode(3)}
+
+CallingSSuserReference ::= CHOICE {
+ t61String T61String -- solely in X.410-1984 --,
+ octetString OCTET STRING -- solely in normal mode --
+}
+
+CommonReference ::= UTCTime
+
+AdditionalReferenceInformation ::= T61String
+
+AbortReason ::= INTEGER {
+ localSystemProblem(0),
+ invalidParameter(1), -- reflectedParameter supplied
+ unrecognizedActivity(2),
+ temporaryProblem(3),
+ -- the RTSE cannot accept a session for a period of time
+ protocolError(4), -- RTSE level protocol error
+ permanentProblem(5), --provider-abort solely in normal mode
+ userError(6), -- user-abort solely in normal mode
+ transferCompleted(7) -- activity can't be discarded--}
+
+END
+
+-- Generated by Asnp, the ASN.1 pretty-printer of France Telecom R&D
+
diff --git a/lib/asn1/test/asn1_SUITE_data/x420/Remote-Operations-Abstract-Syntaxes.asn b/lib/asn1/test/asn1_SUITE_data/x420/Remote-Operations-Abstract-Syntaxes.asn
new file mode 100644
index 0000000000..4a59cc403b
--- /dev/null
+++ b/lib/asn1/test/asn1_SUITE_data/x420/Remote-Operations-Abstract-Syntaxes.asn
@@ -0,0 +1,103 @@
+-- Module Remote-Operations-Abstract-Syntaxes (X.882:07/1994)
+
+Remote-Operations-Abstract-Syntaxes {joint-iso-itu-t remote-operations(4)
+ remote-operations-abstract-syntaxes(12) version1(0)} DEFINITIONS ::=
+BEGIN
+
+-- exports everything
+IMPORTS
+ OPERATION-PACKAGE
+ FROM Remote-Operations-Information-Objects {joint-iso-itu-t
+ remote-operations(4) informationObjects(5) version1(0)}
+ InvokeId, noInvokeId, ROS{}, Bind{}, Unbind{}
+ FROM Remote-Operations-Generic-ROS-PDUs {joint-iso-itu-t
+ remote-operations(4) generic-ROS-PDUs(6) version1(0)}
+ ACSE-apdu
+ FROM ACSE-1 {joint-iso-itu-t association-control(2) modules(0) apdus(0)
+ version1(1)}
+ RTORQapdu, RTOACapdu, RTORJapdu
+ FROM Reliable-Transfer-APDU {joint-iso-itu-t reliable-transfer(3) apdus(0)}
+ combine{}, AllOperations{}, ConsumerPerforms{}, SupplierPerforms{}
+ FROM Remote-Operations-Useful-Definitions {joint-iso-itu-t
+ remote-operations(4) useful-definitions(7) version1(0)}
+ APPLICATION-CONTEXT
+ FROM Remote-Operations-Information-Objects-extensions {joint-iso-itu-t
+ remote-operations(4) informationObjects-extensions(8) version1(0)};
+
+RTSE-apdus ::= CHOICE {
+ rtorq-apdu [16] IMPLICIT RTORQapdu,
+ rtoac-apdu [17] IMPLICIT RTOACapdu,
+ rtorj-apdu [18] IMPLICIT RTORJapdu,
+ rttp-apdu RTTPapdu,
+ rttr-apdu RTTRapdu,
+ rtab-apdu [22] IMPLICIT RTABapdu
+}
+
+RTTPapdu ::= -- priority-- INTEGER
+
+RTTRapdu ::= OCTET STRING
+
+RTABapdu ::= SET {
+ abortReason [0] IMPLICIT AbortReason OPTIONAL,
+ reflectedParameter [1] IMPLICIT BIT STRING OPTIONAL,
+ -- 8 bits maximum, only if abortReason is invalidParameter
+ userdataAB
+ [2] TYPE-IDENTIFIER.&Type
+ OPTIONAL -- only in normal mode and if abortReason--
+ -- is userError
+}
+
+AbortReason ::= INTEGER {
+ localSystemProblem(0),
+ invalidParameter(1), -- reflectedParameter supplied
+ unrecognizedActivity(2),
+ temporaryProblem(3),
+ -- the RTSE cannot accept a session for a period of time
+ protocolError(4), -- RTSE level protocol error
+ permanentProblem(5), --provider-abort solely in normal mode
+ userError(6), -- user-abort solely in normal mode
+ transferCompleted(7) -- activity can't be discarded--}
+
+acse-abstract-syntax ABSTRACT-SYNTAX ::= {
+ ACSE-apdu
+ IDENTIFIED BY
+ {joint-iso-itu-t association-control(2) abstract-syntax(1) apdus(0)
+ version1(1)}
+}
+
+rtse-abstract-syntax ABSTRACT-SYNTAX ::= {
+ RTSE-apdus
+ IDENTIFIED BY {joint-iso-itu-t reliable-transfer(3) apdus(0)}
+}
+
+AllValues{APPLICATION-CONTEXT:ac} ::= CHOICE {
+ bind Bind{ac.&associationContract.&connection.&bind},
+ unbind Unbind{ac.&associationContract.&connection.&unbind},
+ ros-singleAS
+ ROS-SingleAS{{ROSEInvokeIds},
+ combine{{ac.&associationContract.&OperationsOf |
+ ac.&associationContract.&InitiatorConsumerOf |
+ ac.&associationContract.&ResponderConsumerOf}, {
+ ...},
+ {-- Information Object of class OPERATION-PACKAGE to be defined -- }}}
+}
+
+ROS-SingleAS{InvokeId:ROSEInvokeIds, OPERATION-PACKAGE:package} ::=
+ ROS{{ROSEInvokeIds}, {AllOperations {package}}, {AllOperations {package}}}
+
+ROS-ConsumerAS{InvokeId:ROSEInvokeIds, OPERATION-PACKAGE:package} ::=
+ ROS
+ {{ROSEInvokeIds}, {ConsumerPerforms {package}},
+ {SupplierPerforms {package}}}
+
+ROS-SupplierAS{InvokeId:ROSEInvokeIds, OPERATION-PACKAGE:package} ::=
+ ROS
+ {{ROSEInvokeIds}, {SupplierPerforms {package}},
+ {ConsumerPerforms {package}}}
+
+ROSEInvokeIds InvokeId ::= {ALL EXCEPT noInvokeId}
+
+END -- end of the remote-operations-abstract-syntaxes module
+
+-- Generated by Asnp, the ASN.1 pretty-printer of France Telecom R&D
+
diff --git a/lib/asn1/test/asn1_SUITE_data/x420/Remote-Operations-Generic-ROS-PDUs.asn b/lib/asn1/test/asn1_SUITE_data/x420/Remote-Operations-Generic-ROS-PDUs.asn
new file mode 100644
index 0000000000..e55ea3c05e
--- /dev/null
+++ b/lib/asn1/test/asn1_SUITE_data/x420/Remote-Operations-Generic-ROS-PDUs.asn
@@ -0,0 +1,163 @@
+-- Module Remote-Operations-Generic-ROS-PDUs (X.880:07/1994)
+
+Remote-Operations-Generic-ROS-PDUs {joint-iso-itu-t remote-operations(4)
+ generic-ROS-PDUs(6) version1(0)} DEFINITIONS IMPLICIT TAGS ::=
+BEGIN
+
+-- exports everything
+IMPORTS
+ OPERATION, ERROR
+ FROM Remote-Operations-Information-Objects {joint-iso-itu-t
+ remote-operations(4) informationObjects(5) version1(0)};
+
+ROS{InvokeId:InvokeIdSet, OPERATION:Invokable, OPERATION:Returnable} ::=
+ CHOICE {
+ invoke [1] Invoke{{InvokeIdSet}, {Invokable}},
+ returnResult [2] ReturnResult{{Returnable}},
+ returnError [3] ReturnError{{Errors {{Returnable}}}},
+ reject [4] Reject
+}
+(CONSTRAINED BY { -- must conform to the above definition --} !
+ RejectProblem:general-unrecognizedPDU)
+
+Invoke{InvokeId:InvokeIdSet, OPERATION:Operations} ::= SEQUENCE {
+ invokeId
+ InvokeId(InvokeIdSet)
+ (CONSTRAINED BY { -- must be unambiguous --} !
+ RejectProblem:invoke-duplicateInvocation),
+ linkedId
+ CHOICE {present [0] IMPLICIT present < InvokeId,
+ absent [1] IMPLICIT NULL
+ }
+ (CONSTRAINED BY { -- must identify an outstanding operation --} !
+ RejectProblem:invoke-unrecognizedLinkedId)
+ (CONSTRAINED BY { -- which has one or more linked operations--} !
+ RejectProblem:invoke-linkedResponseUnexpected) OPTIONAL,
+ opcode
+ OPERATION.&operationCode
+ ({Operations} !RejectProblem:invoke-unrecognizedOperation),
+ argument
+ OPERATION.&ArgumentType
+ ({Operations}{@opcode} !RejectProblem:invoke-mistypedArgument) OPTIONAL
+}
+(CONSTRAINED BY { -- must conform to the above definition --} !
+ RejectProblem:general-mistypedPDU)
+(WITH COMPONENTS {
+ ...,
+ linkedId ABSENT
+ } |
+ WITH COMPONENTS {
+ ...,
+ linkedId PRESENT,
+ opcode (CONSTRAINED BY { -- must be in the &Linked field of the associated operation --
+ } !RejectProblem:invoke-unexpectedLinkedOperation)
+ })
+
+-- continued on the next page
+ReturnResult{OPERATION:Operations} ::= SEQUENCE {
+ invokeId
+ InvokeId
+ (CONSTRAINED BY { -- must be that for an outstanding operation --} !
+ RejectProblem:returnResult-unrecognizedInvocation)
+ (CONSTRAINED BY { -- which returns a result --} !
+ RejectProblem:returnResult-resultResponseUnexpected),
+ result
+ SEQUENCE {opcode
+ OPERATION.&operationCode({Operations})
+ (CONSTRAINED BY { -- identified by invokeId --} !
+ RejectProblem:returnResult-unrecognizedInvocation),
+ result
+ OPERATION.&ResultType
+ ({Operations}{@.opcode} !
+ RejectProblem:returnResult-mistypedResult)} OPTIONAL
+}
+(CONSTRAINED BY { -- must conform to the above definition --} !
+ RejectProblem:general-mistypedPDU)
+
+ReturnError{ERROR:Errors} ::= SEQUENCE {
+ invokeId
+ InvokeId
+ (CONSTRAINED BY { -- must be that for an outstanding operation --} !
+ RejectProblem:returnError-unrecognizedInvocation)
+ (CONSTRAINED BY { -- which returns an error --} !
+ RejectProblem:returnError-errorResponseUnexpected),
+ errcode
+ ERROR.&errorCode({Errors} !RejectProblem:returnError-unrecognizedError)
+ (CONSTRAINED BY { -- must be in the &Errors field of the associated operation --
+ } !RejectProblem:returnError-unexpectedError),
+ parameter
+ ERROR.&ParameterType
+ ({Errors}{@errcode} !RejectProblem:returnError-mistypedParameter)
+ OPTIONAL
+}
+(CONSTRAINED BY { -- must conform to the above definition --} !
+ RejectProblem:general-mistypedPDU)
+
+Reject ::= SEQUENCE {
+ invokeId InvokeId,
+ problem
+ CHOICE {general [0] GeneralProblem,
+ invoke [1] InvokeProblem,
+ returnResult [2] ReturnResultProblem,
+ returnError [3] ReturnErrorProblem}
+}
+(CONSTRAINED BY { -- must conform to the above definition --} !
+ RejectProblem:general-mistypedPDU)
+
+GeneralProblem ::= INTEGER {
+ unrecognizedPDU(0), mistypedPDU(1), badlyStructuredPDU(2)}
+
+-- continued on the next page
+InvokeProblem ::= INTEGER {
+ duplicateInvocation(0), unrecognizedOperation(1), mistypedArgument(2),
+ resourceLimitation(3), releaseInProgress(4), unrecognizedLinkedId(5),
+ linkedResponseUnexpected(6), unexpectedLinkedOperation(7)}
+
+ReturnResultProblem ::= INTEGER {
+ unrecognizedInvocation(0), resultResponseUnexpected(1), mistypedResult(2)
+}
+
+ReturnErrorProblem ::= INTEGER {
+ unrecognizedInvocation(0), errorResponseUnexpected(1), unrecognizedError(2),
+ unexpectedError(3), mistypedParameter(4)}
+
+RejectProblem ::= INTEGER {
+ general-unrecognizedPDU(0), general-mistypedPDU(1),
+ general-badlyStructuredPDU(2), invoke-duplicateInvocation(10),
+ invoke-unrecognizedOperation(11), invoke-mistypedArgument(12),
+ invoke-resourceLimitation(13), invoke-releaseInProgress(14),
+ invoke-unrecognizedLinkedId(15), invoke-linkedResponseUnexpected(16),
+ invoke-unexpectedLinkedOperation(17),
+ returnResult-unrecognizedInvocation(20),
+ returnResult-resultResponseUnexpected(21), returnResult-mistypedResult(22),
+ returnError-unrecognizedInvocation(30),
+ returnError-errorResponseUnexpected(31), returnError-unrecognizedError(32),
+ returnError-unexpectedError(33), returnError-mistypedParameter(34)}
+
+InvokeId ::= CHOICE {present INTEGER,
+ absent NULL
+}
+
+noInvokeId InvokeId ::= absent:NULL
+
+NoInvokeId InvokeId ::= {noInvokeId}
+
+Errors{OPERATION:Operations} ERROR ::= {Operations.&Errors}
+
+-- continued on the next page
+Bind{OPERATION:operation} ::= CHOICE {
+ bind-invoke [16] OPERATION.&ArgumentType({operation}),
+ bind-result [17] OPERATION.&ResultType({operation}),
+ bind-error [18] OPERATION.&Errors.&ParameterType({operation})
+}
+
+Unbind{OPERATION:operation} ::= CHOICE {
+ unbind-invoke [19] OPERATION.&ArgumentType({operation}),
+ unbind-result [20] OPERATION.&ResultType({operation}),
+ unbind-error [21] OPERATION.&Errors.&ParameterType({operation})
+}
+
+END -- end of generic ROS PDU definitions
+
+-- Generated by Asnp, the ASN.1 pretty-printer of France Telecom R&D
+
diff --git a/lib/asn1/test/asn1_SUITE_data/x420/Remote-Operations-Information-Objects-extensions.asn b/lib/asn1/test/asn1_SUITE_data/x420/Remote-Operations-Information-Objects-extensions.asn
new file mode 100644
index 0000000000..671cf0e780
--- /dev/null
+++ b/lib/asn1/test/asn1_SUITE_data/x420/Remote-Operations-Information-Objects-extensions.asn
@@ -0,0 +1,36 @@
+-- Module Remote-Operations-Information-Objects-extensions (X.881:07/1994)
+
+Remote-Operations-Information-Objects-extensions {joint-iso-itu-t
+ remote-operations(4) informationObjects-extensions(8) version1(0)}
+DEFINITIONS ::=
+BEGIN
+
+-- exports everything
+IMPORTS
+ CONTRACT
+ FROM Remote-Operations-Information-Objects {joint-iso-itu-t
+ remote-operations(4) informationObjects(5) version1(0)};
+
+APPLICATION-CONTEXT ::= CLASS {
+ &associationContract CONTRACT,
+ &associationRealization REALIZATION OPTIONAL,
+ &transferRealization REALIZATION,
+ &AbstractSyntaxes ABSTRACT-SYNTAX,
+ &applicationContextName OBJECT IDENTIFIER UNIQUE
+}
+WITH SYNTAX {
+ CONTRACT &associationContract
+ [ESTABLISHED BY &associationRealization]
+ INFORMATION TRANSFER BY &transferRealization
+ ABSTRACT SYNTAXES &AbstractSyntaxes
+ APPLICATION CONTEXT NAME &applicationContextName
+}
+
+REALIZATION ::= TYPE-IDENTIFIER
+
+-- information objects ABSTRACT-SYNTAX and TYPE-IDENTIFIER are defined in ITU-T Rec. X.681 |
+-- ISO/IEC 8824-2
+END -- end of the information-objects-extensions module
+
+-- Generated by Asnp, the ASN.1 pretty-printer of France Telecom R&D
+
diff --git a/lib/asn1/test/asn1_SUITE_data/x420/Remote-Operations-Information-Objects.asn b/lib/asn1/test/asn1_SUITE_data/x420/Remote-Operations-Information-Objects.asn
new file mode 100644
index 0000000000..b497e4126b
--- /dev/null
+++ b/lib/asn1/test/asn1_SUITE_data/x420/Remote-Operations-Information-Objects.asn
@@ -0,0 +1,123 @@
+-- Module Remote-Operations-Information-Objects (X.880:07/1994)
+
+Remote-Operations-Information-Objects {joint-iso-itu-t remote-operations(4)
+ informationObjects(5) version1(0)} DEFINITIONS ::=
+BEGIN
+
+-- exports everything
+IMPORTS
+ emptyBind, emptyUnbind
+ FROM Remote-Operations-Useful-Definitions {joint-iso-itu-t
+ remote-operations(4) useful-definitions(7) version1(0)};
+
+OPERATION ::= CLASS {
+ &ArgumentType OPTIONAL,
+ &argumentTypeOptional BOOLEAN OPTIONAL,
+ &returnResult BOOLEAN DEFAULT TRUE,
+ &ResultType OPTIONAL,
+ &resultTypeOptional BOOLEAN OPTIONAL,
+ &Errors ERROR OPTIONAL,
+ &Linked OPERATION OPTIONAL,
+ &synchronous BOOLEAN DEFAULT FALSE,
+ &alwaysReturns BOOLEAN DEFAULT TRUE,
+ &InvokePriority Priority OPTIONAL,
+ &ResultPriority Priority OPTIONAL,
+ &operationCode Code UNIQUE OPTIONAL
+}
+WITH SYNTAX {
+ [ARGUMENT &ArgumentType
+ [OPTIONAL &argumentTypeOptional]]
+ [RESULT &ResultType
+ [OPTIONAL &resultTypeOptional]]
+ [RETURN RESULT &returnResult]
+ [ERRORS &Errors]
+ [LINKED &Linked]
+ [SYNCHRONOUS &synchronous]
+ [ALWAYS RESPONDS &alwaysReturns]
+ [INVOKE PRIORITY &InvokePriority]
+ [RESULT-PRIORITY &ResultPriority]
+ [CODE &operationCode]
+}
+
+ERROR ::= CLASS {
+ &ParameterType OPTIONAL,
+ &parameterTypeOptional BOOLEAN OPTIONAL,
+ &ErrorPriority Priority OPTIONAL,
+ &errorCode Code UNIQUE OPTIONAL
+}
+WITH SYNTAX {
+ [PARAMETER &ParameterType
+ [OPTIONAL &parameterTypeOptional]]
+ [PRIORITY &ErrorPriority]
+ [CODE &errorCode]
+}
+
+OPERATION-PACKAGE ::= CLASS {
+ &Both OPERATION OPTIONAL,
+ &Consumer OPERATION OPTIONAL,
+ &Supplier OPERATION OPTIONAL,
+ &id OBJECT IDENTIFIER UNIQUE OPTIONAL
+}
+-- continued on the next page
+WITH SYNTAX {
+ [OPERATIONS &Both]
+ [CONSUMER INVOKES &Supplier]
+ [SUPPLIER INVOKES &Consumer]
+ [ID &id]
+}
+
+CONNECTION-PACKAGE ::= CLASS {
+ &bind OPERATION DEFAULT emptyBind,
+ &unbind OPERATION DEFAULT emptyUnbind,
+ &responderCanUnbind BOOLEAN DEFAULT FALSE,
+ &unbindCanFail BOOLEAN DEFAULT FALSE,
+ &id OBJECT IDENTIFIER UNIQUE OPTIONAL
+}
+WITH SYNTAX {
+ [BIND &bind]
+ [UNBIND &unbind]
+ [RESPONDER UNBIND &responderCanUnbind]
+ [FAILURE TO UNBIND &unbindCanFail]
+ [ID &id]
+}
+
+CONTRACT ::= CLASS {
+ &connection CONNECTION-PACKAGE OPTIONAL,
+ &OperationsOf OPERATION-PACKAGE OPTIONAL,
+ &InitiatorConsumerOf OPERATION-PACKAGE OPTIONAL,
+ &InitiatorSupplierOf OPERATION-PACKAGE OPTIONAL,
+ &id OBJECT IDENTIFIER UNIQUE OPTIONAL
+}
+WITH SYNTAX {
+ [CONNECTION &connection]
+ [OPERATIONS OF &OperationsOf]
+ [INITIATOR CONSUMER OF &InitiatorConsumerOf]
+ [RESPONDER CONSUMER OF &InitiatorSupplierOf]
+ [ID &id]
+}
+
+ROS-OBJECT-CLASS ::= CLASS {
+ &Is ROS-OBJECT-CLASS OPTIONAL,
+ &Initiates CONTRACT OPTIONAL,
+ &Responds CONTRACT OPTIONAL,
+ &InitiatesAndResponds CONTRACT OPTIONAL,
+ &id OBJECT IDENTIFIER UNIQUE
+}
+WITH SYNTAX {
+ [IS &Is]
+ [BOTH &InitiatesAndResponds]
+ [INITIATES &Initiates]
+ [RESPONDS &Responds]
+ ID &id
+}
+
+Code ::= CHOICE {local INTEGER,
+ global OBJECT IDENTIFIER
+}
+
+Priority ::= INTEGER(0..MAX)
+
+END -- end of Information Object specifications
+
+-- Generated by Asnp, the ASN.1 pretty-printer of France Telecom R&D
+
diff --git a/lib/asn1/test/asn1_SUITE_data/x420/Remote-Operations-Realizations.asn b/lib/asn1/test/asn1_SUITE_data/x420/Remote-Operations-Realizations.asn
new file mode 100644
index 0000000000..73b49c8d7a
--- /dev/null
+++ b/lib/asn1/test/asn1_SUITE_data/x420/Remote-Operations-Realizations.asn
@@ -0,0 +1,81 @@
+-- Module Remote-Operations-Realizations (X.882:07/1994)
+
+Remote-Operations-Realizations {joint-iso-itu-t remote-operations(4)
+ realizations(9) version1(0)} DEFINITIONS ::=
+BEGIN
+
+-- exports everything
+IMPORTS
+ REALIZATION
+ FROM Remote-Operations-Information-Objects-extensions {joint-iso-itu-t
+ remote-operations(4) informationObjects-extensions(8) version1(0)};
+
+RealizationParameter ::= SEQUENCE {
+ realization-type ENUMERATED {association-service(0), transfer-service(1)},
+ concatenation BOOLEAN DEFAULT FALSE
+}
+
+acse REALIZATION ::= {
+ RealizationParameter
+ (WITH COMPONENTS {
+ realization-type (association-service)
+ })
+ IDENTIFIED BY
+ {joint-iso-itu-t remote-operations(4) association-realizations(10)
+ acse-without-concatenation(0)}
+}
+
+acse-with-concatenation REALIZATION ::= {
+ RealizationParameter
+ (WITH COMPONENTS {
+ realization-type (association-service),
+ concatenation (TRUE)
+ })
+ IDENTIFIED BY
+ {joint-iso-itu-t remote-operations(4) association-realizations(10)
+ acse-with-concatenation(1)}
+}
+
+association-by-RTSE REALIZATION ::= {
+ RealizationParameter
+ (WITH COMPONENTS {
+ realization-type (association-service)
+ })
+ IDENTIFIED BY
+ {joint-iso-itu-t remote-operations(4) association-realizations(10)
+ association-by-rtse(2)}
+}
+
+pData REALIZATION ::= {
+ RealizationParameter(WITH COMPONENTS {
+ realization-type (transfer-service)
+ })
+ IDENTIFIED BY
+ {joint-iso-itu-t remote-operations(4) transfer-realizations(11)
+ pData-without-concatenation(0)}
+}
+
+pData-with-concatenation REALIZATION ::= {
+ RealizationParameter
+ (WITH COMPONENTS {
+ realization-type (transfer-service),
+ concatenation (TRUE)
+ })
+ IDENTIFIED BY
+ {joint-iso-itu-t remote-operations(4) transfer-realizations(11)
+ pData-with-concatenation(1)}
+}
+
+transfer-by-RTSE REALIZATION ::= {
+ RealizationParameter(WITH COMPONENTS {
+ realization-type (transfer-service)
+ })
+ IDENTIFIED BY
+ {joint-iso-itu-t remote-operations(4) transfer-realizations(11)
+ rTSE-transfer(2)}
+}
+
+END -- end of the OSI realizations module
+
+-- Generated by Asnp, the ASN.1 pretty-printer of France Telecom R&D
+
diff --git a/lib/asn1/test/asn1_SUITE_data/x420/Remote-Operations-Useful-Definitions.asn b/lib/asn1/test/asn1_SUITE_data/x420/Remote-Operations-Useful-Definitions.asn
new file mode 100644
index 0000000000..e526ff4600
--- /dev/null
+++ b/lib/asn1/test/asn1_SUITE_data/x420/Remote-Operations-Useful-Definitions.asn
@@ -0,0 +1,95 @@
+-- Module Remote-Operations-Useful-Definitions (X.880:07/1994)
+
+Remote-Operations-Useful-Definitions {joint-iso-itu-t remote-operations(4)
+ useful-definitions(7) version1(0)} DEFINITIONS IMPLICIT TAGS ::=
+BEGIN
+
+-- exports everything
+IMPORTS
+ OPERATION, ERROR, OPERATION-PACKAGE, Code
+ FROM Remote-Operations-Information-Objects {joint-iso-itu-t
+ remote-operations(4) informationObjects(5) version1(0)}
+ InvokeId, ROS{}
+ FROM Remote-Operations-Generic-ROS-PDUs {joint-iso-itu-t
+ remote-operations(4) generic-ROS-PDUs(6) version1(0)};
+
+emptyBind OPERATION ::= {ERRORS {refuse}
+ SYNCHRONOUS TRUE
+}
+
+emptyUnbind OPERATION ::= {SYNCHRONOUS TRUE
+}
+
+refuse ERROR ::= {CODE local:-1
+}
+
+no-op OPERATION ::= {ALWAYS RESPONDS FALSE
+ CODE local:-1
+}
+
+Forward{OPERATION:OperationSet} OPERATION ::=
+ {OperationSet | OperationSet.&Linked.&Linked |
+ OperationSet.&Linked.&Linked.&Linked.&Linked}
+
+Reverse{OPERATION:OperationSet} OPERATION ::= {Forward{{OperationSet.&Linked}}}
+
+ConsumerPerforms{OPERATION-PACKAGE:package} OPERATION ::=
+ {Forward{{package.&Consumer}} | Forward{{package.&Both}} |
+ Reverse{{package.&Supplier}} | Reverse{{package.&Both}}}
+
+SupplierPerforms{OPERATION-PACKAGE:package} OPERATION ::=
+ {Forward{{package.&Supplier}} | Forward{{package.&Both}} |
+ Reverse{{package.&Consumer}} | Reverse{{package.&Both}}}
+
+AllOperations{OPERATION-PACKAGE:package} OPERATION ::=
+ {ConsumerPerforms{package} | SupplierPerforms{package}}
+
+-- continued on the next page
+recode{OPERATION:operation, Code:code} OPERATION ::= {
+ ARGUMENT operation.&ArgumentType
+ OPTIONAL operation.&argumentTypeOptional
+ RESULT operation.&ResultType
+ OPTIONAL operation.&resultTypeOptional
+ RETURN RESULT operation.&returnResult
+ ERRORS {operation.&Errors}
+ LINKED {operation.&Linked}
+ SYNCHRONOUS operation.&synchronous
+ ALWAYS RESPONDS operation.&alwaysReturns
+ INVOKE PRIORITY {operation.&InvokePriority}
+ RESULT-PRIORITY {operation.&ResultPriority}
+ CODE code
+}
+
+switch{OPERATION-PACKAGE:package, OBJECT IDENTIFIER:id} OPERATION-PACKAGE ::=
+{
+ OPERATIONS {package.&Both}
+ CONSUMER INVOKES {package.&Consumer}
+ SUPPLIER INVOKES {package.&Supplier}
+ ID id
+}
+
+combine{OPERATION-PACKAGE:ConsumerConsumes, OPERATION-PACKAGE:ConsumerSupplies,
+ OPERATION-PACKAGE:base} OPERATION-PACKAGE ::= {
+ OPERATIONS {ConsumerConsumes.&Both | ConsumerSupplies.&Both}
+ CONSUMER INVOKES {ConsumerConsumes.&Consumer | ConsumerSupplies.&Supplier}
+ SUPPLIER INVOKES {ConsumerConsumes.&Supplier | ConsumerSupplies.&Consumer}
+ ID base.&id
+}
+
+ROS-SingleAS{InvokeId:InvokeIdSet, OPERATION-PACKAGE:package} ::=
+ ROS{{InvokeIdSet}, {AllOperations {package}}, {AllOperations {package}}}
+
+ROS-ConsumerAS{InvokeId:InvokeIdSet, OPERATION-PACKAGE:package} ::=
+ ROS
+ {{InvokeIdSet}, {ConsumerPerforms {package}},
+ {SupplierPerforms {package}}}
+
+ROS-SupplierAS{InvokeId:InvokeIdSet, OPERATION-PACKAGE:package} ::=
+ ROS
+ {{InvokeIdSet}, {SupplierPerforms {package}},
+ {ConsumerPerforms {package}}}
+
+END -- end of useful definitions.
+
+-- Generated by Asnp, the ASN.1 pretty-printer of France Telecom R&D
+
diff --git a/lib/asn1/test/asn1_SUITE_data/x420/SelectedAttributeTypes.asn b/lib/asn1/test/asn1_SUITE_data/x420/SelectedAttributeTypes.asn
new file mode 100644
index 0000000000..07bba30690
--- /dev/null
+++ b/lib/asn1/test/asn1_SUITE_data/x420/SelectedAttributeTypes.asn
@@ -0,0 +1,1466 @@
+-- Module SelectedAttributeTypes (X.520:08/1997)
+
+SelectedAttributeTypes {joint-iso-itu-t ds(5) module(1)
+ selectedAttributeTypes(5) 3} DEFINITIONS ::=
+BEGIN
+
+-- EXPORTS All
+-- The types and values defined in this module are exported for use in the other ASN.1 modules contained
+-- within the Directory Specifications, and for the use of other applications which will use them to access
+-- Directory services. Other applications may use them for their own purposes, but this will not constrain
+-- extensions and modifications needed to maintain or improve the Directory service.
+IMPORTS
+ informationFramework, upperBounds, id-at, id-mr, id-avc,
+ directoryAbstractService, id-pr, id-not, id-cat
+ FROM UsefulDefinitions {joint-iso-itu-t ds(5) module(1)
+ usefulDefinitions(0) 3}
+ Attribute, ATTRIBUTE, MATCHING-RULE, AttributeType, OBJECT-CLASS,
+ DistinguishedName, objectIdentifierMatch, distinguishedNameMatch,
+ CONTEXT, ContextAssertion, AttributeCombination, ContextCombination,
+ MAPPING-BASED-MATCHING, MRMapping, AttributeValueAssertion
+ FROM InformationFramework informationFramework
+ G3FacsimileNonBasicParameters
+ FROM MTSAbstractService {joint-iso-itu-t mhs(6) mts(3) modules(0)
+ mts-abstract-service(1) version-1999(1)}
+ ub-answerback, ub-name, ub-common-name, ub-surname, ub-serial-number,
+ ub-locality-name, ub-state-name, ub-street-address, ub-organization-name,
+ ub-organizational-unit-name, ub-title, ub-description,
+ ub-business-category, ub-postal-line, ub-postal-string, ub-postal-code,
+ ub-post-office-box, ub-physical-office-name, ub-telex-number,
+ ub-country-code, ub-teletex-terminal-id, ub-telephone-number,
+ ub-x121-address, ub-international-isdn-number, ub-destination-indicator,
+ ub-user-password, ub-match, ub-knowledge-information,
+ ub-directory-string-first-component-match, ub-localeContextSyntax,
+ ub-pseudonym
+ FROM UpperBounds upperBounds
+ FilterItem, HierarchySelections, SearchControlOptions, ServiceControlOptions
+ FROM DirectoryAbstractService directoryAbstractService;
+
+-- Directory string type
+DirectoryString{INTEGER:maxSize} ::= CHOICE {
+ teletexString TeletexString(SIZE (1..maxSize)),
+ printableString PrintableString(SIZE (1..maxSize)),
+ universalString UniversalString(SIZE (1..maxSize)),
+ bmpString BMPString(SIZE (1..maxSize)),
+ uTF8String UTF8String(SIZE (1..maxSize))
+}
+
+-- Attribute types
+knowledgeInformation ATTRIBUTE ::= {
+ WITH SYNTAX DirectoryString {ub-knowledge-information}
+ EQUALITY MATCHING RULE caseIgnoreMatch
+ ID id-at-knowledgeInformation
+}
+
+name ATTRIBUTE ::= {
+ WITH SYNTAX DirectoryString {ub-name}
+ EQUALITY MATCHING RULE caseIgnoreMatch
+ SUBSTRINGS MATCHING RULE caseIgnoreSubstringsMatch
+ ID id-at-name
+}
+
+commonName ATTRIBUTE ::= {
+ SUBTYPE OF name
+ WITH SYNTAX DirectoryString {ub-common-name}
+ ID id-at-commonName
+}
+
+surname ATTRIBUTE ::= {
+ SUBTYPE OF name
+ WITH SYNTAX DirectoryString {ub-surname}
+ ID id-at-surname
+}
+
+givenName ATTRIBUTE ::= {
+ SUBTYPE OF name
+ WITH SYNTAX DirectoryString {ub-name}
+ ID id-at-givenName
+}
+
+initials ATTRIBUTE ::= {
+ SUBTYPE OF name
+ WITH SYNTAX DirectoryString {ub-name}
+ ID id-at-initials
+}
+
+generationQualifier ATTRIBUTE ::= {
+ SUBTYPE OF name
+ WITH SYNTAX DirectoryString {ub-name}
+ ID id-at-generationQualifier
+}
+
+uniqueIdentifier ATTRIBUTE ::= {
+ WITH SYNTAX UniqueIdentifier
+ EQUALITY MATCHING RULE bitStringMatch
+ ID id-at-uniqueIdentifier
+}
+
+UniqueIdentifier ::= BIT STRING
+
+dnQualifier ATTRIBUTE ::= {
+ WITH SYNTAX PrintableString
+ EQUALITY MATCHING RULE caseIgnoreMatch
+ ORDERING MATCHING RULE caseIgnoreOrderingMatch
+ SUBSTRINGS MATCHING RULE caseIgnoreSubstringsMatch
+ ID id-at-dnQualifier
+}
+
+serialNumber ATTRIBUTE ::= {
+ WITH SYNTAX PrintableString(SIZE (1..ub-serial-number))
+ EQUALITY MATCHING RULE caseIgnoreMatch
+ SUBSTRINGS MATCHING RULE caseIgnoreSubstringsMatch
+ ID id-at-serialNumber
+}
+
+pseudonym ATTRIBUTE ::= {
+ SUBTYPE OF name
+ WITH SYNTAX DirectoryString {ub-pseudonym}
+ ID id-at-pseudonym
+}
+
+countryName ATTRIBUTE ::= {
+ SUBTYPE OF name
+ WITH SYNTAX CountryName
+ SINGLE VALUE TRUE
+ ID id-at-countryName
+}
+
+CountryName ::= PrintableString(SIZE (2)) -- ISO 3166 codes only
+
+
+localityName ATTRIBUTE ::= {
+ SUBTYPE OF name
+ WITH SYNTAX DirectoryString {ub-locality-name}
+ ID id-at-localityName
+}
+
+collectiveLocalityName ATTRIBUTE ::= {
+ SUBTYPE OF localityName
+ COLLECTIVE TRUE
+ ID id-at-collectiveLocalityName
+}
+
+stateOrProvinceName ATTRIBUTE ::= {
+ SUBTYPE OF name
+ WITH SYNTAX DirectoryString {ub-state-name}
+ ID id-at-stateOrProvinceName
+}
+
+collectiveStateOrProvinceName ATTRIBUTE ::= {
+ SUBTYPE OF stateOrProvinceName
+ COLLECTIVE TRUE
+ ID id-at-collectiveStateOrProvinceName
+}
+
+streetAddress ATTRIBUTE ::= {
+ WITH SYNTAX DirectoryString {ub-street-address}
+ EQUALITY MATCHING RULE caseIgnoreMatch
+ SUBSTRINGS MATCHING RULE caseIgnoreSubstringsMatch
+ ID id-at-streetAddress
+}
+
+collectiveStreetAddress ATTRIBUTE ::= {
+ SUBTYPE OF streetAddress
+ COLLECTIVE TRUE
+ ID id-at-collectiveStreetAddress
+}
+
+houseIdentifier ATTRIBUTE ::= {
+ WITH SYNTAX DirectoryString {ub-name}
+ EQUALITY MATCHING RULE caseIgnoreMatch
+ SUBSTRINGS MATCHING RULE caseIgnoreSubstringsMatch
+ ID id-at-houseIdentifier
+}
+
+organizationName ATTRIBUTE ::= {
+ SUBTYPE OF name
+ WITH SYNTAX DirectoryString {ub-organization-name}
+ ID id-at-organizationName
+}
+
+collectiveOrganizationName ATTRIBUTE ::= {
+ SUBTYPE OF organizationName
+ COLLECTIVE TRUE
+ ID id-at-collectiveOrganizationName
+}
+
+organizationalUnitName ATTRIBUTE ::= {
+ SUBTYPE OF name
+ WITH SYNTAX DirectoryString {ub-organizational-unit-name}
+ ID id-at-organizationalUnitName
+}
+
+collectiveOrganizationalUnitName ATTRIBUTE ::= {
+ SUBTYPE OF organizationalUnitName
+ COLLECTIVE TRUE
+ ID id-at-collectiveOrganizationalUnitName
+}
+
+title ATTRIBUTE ::= {
+ SUBTYPE OF name
+ WITH SYNTAX DirectoryString {ub-title}
+ ID id-at-title
+}
+
+description ATTRIBUTE ::= {
+ WITH SYNTAX DirectoryString {ub-description}
+ EQUALITY MATCHING RULE caseIgnoreMatch
+ SUBSTRINGS MATCHING RULE caseIgnoreSubstringsMatch
+ ID id-at-description
+}
+
+searchGuide ATTRIBUTE ::= {WITH SYNTAX Guide
+ ID id-at-searchGuide
+}
+
+Guide ::= SET {
+ objectClass [0] OBJECT-CLASS.&id OPTIONAL,
+ criteria [1] Criteria
+}
+
+Criteria ::= CHOICE {
+ type [0] CriteriaItem,
+ and [1] SET OF Criteria,
+ or [2] SET OF Criteria,
+ not [3] Criteria
+}
+
+CriteriaItem ::= CHOICE {
+ equality [0] AttributeType,
+ substrings [1] AttributeType,
+ greaterOrEqual [2] AttributeType,
+ lessOrEqual [3] AttributeType,
+ approximateMatch [4] AttributeType
+}
+
+enhancedSearchGuide ATTRIBUTE ::= {
+ WITH SYNTAX EnhancedGuide
+ ID id-at-enhancedSearchGuide
+}
+
+EnhancedGuide ::= SEQUENCE {
+ objectClass [0] OBJECT-CLASS.&id,
+ criteria [1] Criteria,
+ subset
+ [2] INTEGER {baseObject(0), oneLevel(1), wholeSubtree(2)} DEFAULT oneLevel
+}
+
+businessCategory ATTRIBUTE ::= {
+ WITH SYNTAX DirectoryString {ub-business-category}
+ EQUALITY MATCHING RULE caseIgnoreMatch
+ SUBSTRINGS MATCHING RULE caseIgnoreSubstringsMatch
+ ID id-at-businessCategory
+}
+
+postalAddress ATTRIBUTE ::= {
+ WITH SYNTAX PostalAddress
+ EQUALITY MATCHING RULE caseIgnoreListMatch
+ SUBSTRINGS MATCHING RULE caseIgnoreListSubstringsMatch
+ ID id-at-postalAddress
+}
+
+PostalAddress ::=
+ SEQUENCE SIZE (1..ub-postal-line) OF DirectoryString{ub-postal-string}
+
+collectivePostalAddress ATTRIBUTE ::= {
+ SUBTYPE OF postalAddress
+ COLLECTIVE TRUE
+ ID id-at-collectivePostalAddress
+}
+
+postalCode ATTRIBUTE ::= {
+ WITH SYNTAX DirectoryString {ub-postal-code}
+ EQUALITY MATCHING RULE caseIgnoreMatch
+ SUBSTRINGS MATCHING RULE caseIgnoreSubstringsMatch
+ ID id-at-postalCode
+}
+
+collectivePostalCode ATTRIBUTE ::= {
+ SUBTYPE OF postalCode
+ COLLECTIVE TRUE
+ ID id-at-collectivePostalCode
+}
+
+postOfficeBox ATTRIBUTE ::= {
+ WITH SYNTAX DirectoryString {ub-post-office-box}
+ EQUALITY MATCHING RULE caseIgnoreMatch
+ SUBSTRINGS MATCHING RULE caseIgnoreSubstringsMatch
+ ID id-at-postOfficeBox
+}
+
+collectivePostOfficeBox ATTRIBUTE ::= {
+ SUBTYPE OF postOfficeBox
+ COLLECTIVE TRUE
+ ID id-at-collectivePostOfficeBox
+}
+
+physicalDeliveryOfficeName ATTRIBUTE ::= {
+ WITH SYNTAX DirectoryString {ub-physical-office-name}
+ EQUALITY MATCHING RULE caseIgnoreMatch
+ SUBSTRINGS MATCHING RULE caseIgnoreSubstringsMatch
+ ID id-at-physicalDeliveryOfficeName
+}
+
+collectivePhysicalDeliveryOfficeName ATTRIBUTE ::= {
+ SUBTYPE OF physicalDeliveryOfficeName
+ COLLECTIVE TRUE
+ ID id-at-collectivePhysicalDeliveryOfficeName
+}
+
+telephoneNumber ATTRIBUTE ::= {
+ WITH SYNTAX TelephoneNumber
+ EQUALITY MATCHING RULE telephoneNumberMatch
+ SUBSTRINGS MATCHING RULE telephoneNumberSubstringsMatch
+ ID id-at-telephoneNumber
+}
+
+TelephoneNumber ::= PrintableString(SIZE (1..ub-telephone-number))
+
+-- String complying with CCITT Rec. E.123 only
+collectiveTelephoneNumber ATTRIBUTE ::= {
+ SUBTYPE OF telephoneNumber
+ COLLECTIVE TRUE
+ ID id-at-collectiveTelephoneNumber
+}
+
+telexNumber ATTRIBUTE ::= {
+ WITH SYNTAX TelexNumber
+ ID id-at-telexNumber
+}
+
+TelexNumber ::= SEQUENCE {
+ telexNumber PrintableString(SIZE (1..ub-telex-number)),
+ countryCode PrintableString(SIZE (1..ub-country-code)),
+ answerback PrintableString(SIZE (1..ub-answerback))
+}
+
+collectiveTelexNumber ATTRIBUTE ::= {
+ SUBTYPE OF telexNumber
+ COLLECTIVE TRUE
+ ID id-at-collectiveTelexNumber
+}
+
+facsimileTelephoneNumber ATTRIBUTE ::= {
+ WITH SYNTAX FacsimileTelephoneNumber
+ EQUALITY MATCHING RULE facsimileNumberMatch
+ SUBSTRINGS MATCHING RULE facsimileNumberSubstringsMatch
+ ID id-at-facsimileTelephoneNumber
+}
+
+facsimileNumberMatch MATCHING-RULE ::= {
+ SYNTAX TelephoneNumber
+ ID id-mr-facsimileNumberMatch
+}
+
+facsimileNumberSubstringsMatch MATCHING-RULE ::= {
+ SYNTAX SubstringAssertion
+ ID id-mr-facsimileNumberSubstringsMatch
+}
+
+FacsimileTelephoneNumber ::= SEQUENCE {
+ telephoneNumber TelephoneNumber,
+ parameters G3FacsimileNonBasicParameters OPTIONAL
+}
+
+collectiveFacsimileTelephoneNumber ATTRIBUTE ::= {
+ SUBTYPE OF facsimileTelephoneNumber
+ COLLECTIVE TRUE
+ ID id-at-collectiveFacsimileTelephoneNumber
+}
+
+x121Address ATTRIBUTE ::= {
+ WITH SYNTAX X121Address
+ EQUALITY MATCHING RULE numericStringMatch
+ SUBSTRINGS MATCHING RULE numericStringSubstringsMatch
+ ID id-at-x121Address
+}
+
+X121Address ::= NumericString(SIZE (1..ub-x121-address))
+
+-- String as defined by ITU-T Rec. X.121
+internationalISDNNumber ATTRIBUTE ::= {
+ WITH SYNTAX InternationalISDNNumber
+ EQUALITY MATCHING RULE numericStringMatch
+ SUBSTRINGS MATCHING RULE numericStringSubstringsMatch
+ ID id-at-internationalISDNNumber
+}
+
+InternationalISDNNumber ::=
+ NumericString(SIZE (1..ub-international-isdn-number))
+
+-- String complying with ITU-T Rec. E.164 only
+collectiveInternationalISDNNumber ATTRIBUTE ::= {
+ SUBTYPE OF internationalISDNNumber
+ COLLECTIVE TRUE
+ ID id-at-collectiveInternationalISDNNumber
+}
+
+registeredAddress ATTRIBUTE ::= {
+ SUBTYPE OF postalAddress
+ WITH SYNTAX PostalAddress
+ ID id-at-registeredAddress
+}
+
+destinationIndicator ATTRIBUTE ::= {
+ WITH SYNTAX DestinationIndicator
+ EQUALITY MATCHING RULE caseIgnoreMatch
+ SUBSTRINGS MATCHING RULE caseIgnoreSubstringsMatch
+ ID id-at-destinationIndicator
+}
+
+DestinationIndicator ::= PrintableString(SIZE (1..ub-destination-indicator))
+
+communicationsService ATTRIBUTE ::= {
+ WITH SYNTAX OBJECT IDENTIFIER
+ EQUALITY MATCHING RULE objectIdentifierMatch
+ ID id-at-communicationsService
+}
+
+communicationsNetwork ATTRIBUTE ::= {
+ WITH SYNTAX OBJECT IDENTIFIER
+ EQUALITY MATCHING RULE objectIdentifierMatch
+ SINGLE VALUE TRUE
+ ID id-at-communicationsNetwork
+}
+
+-- alphabetical characters only
+preferredDeliveryMethod ATTRIBUTE ::= {
+ WITH SYNTAX PreferredDeliveryMethod
+ SINGLE VALUE TRUE
+ ID id-at-preferredDeliveryMethod
+}
+
+PreferredDeliveryMethod ::=
+ SEQUENCE OF
+ INTEGER {any-delivery-method(0), mhs-delivery(1), physical-delivery(2),
+ telex-delivery(3), teletex-delivery(4), g3-facsimile-delivery(5),
+ g4-facsimile-delivery(6), ia5-terminal-delivery(7),
+ videotex-delivery(8), telephone-delivery(9)}
+
+presentationAddress ATTRIBUTE ::= {
+ WITH SYNTAX PresentationAddress
+ EQUALITY MATCHING RULE presentationAddressMatch
+ SINGLE VALUE TRUE
+ ID id-at-presentationAddress
+}
+
+PresentationAddress ::= SEQUENCE {
+ pSelector [0] OCTET STRING OPTIONAL,
+ sSelector [1] OCTET STRING OPTIONAL,
+ tSelector [2] OCTET STRING OPTIONAL,
+ nAddresses [3] SET SIZE (1..MAX) OF OCTET STRING
+}
+
+supportedApplicationContext ATTRIBUTE ::= {
+ WITH SYNTAX OBJECT IDENTIFIER
+ EQUALITY MATCHING RULE objectIdentifierMatch
+ ID id-at-supportedApplicationContext
+}
+
+protocolInformation ATTRIBUTE ::= {
+ WITH SYNTAX ProtocolInformation
+ EQUALITY MATCHING RULE protocolInformationMatch
+ ID id-at-protocolInformation
+}
+
+ProtocolInformation ::= SEQUENCE {
+ nAddress OCTET STRING,
+ profiles SET OF OBJECT IDENTIFIER
+}
+
+distinguishedName ATTRIBUTE ::= {
+ WITH SYNTAX DistinguishedName
+ EQUALITY MATCHING RULE distinguishedNameMatch
+ ID id-at-distinguishedName
+}
+
+member ATTRIBUTE ::= {SUBTYPE OF distinguishedName
+ ID id-at-member
+}
+
+uniqueMember ATTRIBUTE ::= {
+ WITH SYNTAX NameAndOptionalUID
+ EQUALITY MATCHING RULE uniqueMemberMatch
+ ID id-at-uniqueMember
+}
+
+NameAndOptionalUID ::= SEQUENCE {
+ dn DistinguishedName,
+ uid UniqueIdentifier OPTIONAL
+}
+
+owner ATTRIBUTE ::= {SUBTYPE OF distinguishedName
+ ID id-at-owner
+}
+
+roleOccupant ATTRIBUTE ::= {
+ SUBTYPE OF distinguishedName
+ ID id-at-roleOccupant
+}
+
+seeAlso ATTRIBUTE ::= {SUBTYPE OF distinguishedName
+ ID id-at-seeAlso
+}
+
+dmdName ATTRIBUTE ::= {
+ SUBTYPE OF name
+ WITH SYNTAX DirectoryString {ub-common-name}
+ ID id-at-dmdName
+}
+
+dSAProblem ATTRIBUTE ::= {
+ WITH SYNTAX OBJECT IDENTIFIER
+ EQUALITY MATCHING RULE objectIdentifierMatch
+ ID id-not-dSAProblem
+}
+
+searchServiceProblem ATTRIBUTE ::= {
+ WITH SYNTAX OBJECT IDENTIFIER
+ EQUALITY MATCHING RULE objectIdentifierMatch
+ SINGLE VALUE TRUE
+ ID id-not-searchServiceProblem
+}
+
+serviceType ATTRIBUTE ::= {
+ WITH SYNTAX OBJECT IDENTIFIER
+ EQUALITY MATCHING RULE objectIdentifierMatch
+ SINGLE VALUE TRUE
+ ID id-not-serviceType
+}
+
+attributeTypeList ATTRIBUTE ::= {
+ WITH SYNTAX OBJECT IDENTIFIER
+ EQUALITY MATCHING RULE objectIdentifierMatch
+ ID id-not-attributeTypeList
+}
+
+filterItem ATTRIBUTE ::= {
+ WITH SYNTAX FilterItem
+ ID id-not-filterItem
+}
+
+attributeCombinations ATTRIBUTE ::= {
+ WITH SYNTAX AttributeCombination
+ ID id-not-attributeCombinations
+}
+
+contextTypeList ATTRIBUTE ::= {
+ WITH SYNTAX OBJECT IDENTIFIER
+ EQUALITY MATCHING RULE objectIdentifierMatch
+ ID id-not-contextTypeList
+}
+
+contextList ATTRIBUTE ::= {
+ WITH SYNTAX ContextAssertion
+ ID id-not-contextList
+}
+
+hierarchySelectList ATTRIBUTE ::= {
+ WITH SYNTAX HierarchySelections
+ SINGLE VALUE TRUE
+ ID id-not-hierarchySelectList
+}
+
+searchOptionsList ATTRIBUTE ::= {
+ WITH SYNTAX SearchControlOptions
+ SINGLE VALUE TRUE
+ ID id-not-searchOptionsList
+}
+
+serviceControlOptionsList ATTRIBUTE ::= {
+ WITH SYNTAX ServiceControlOptions
+ SINGLE VALUE TRUE
+ ID id-not-serviceControlOptionsList
+}
+
+multipleMatchingLocalities ATTRIBUTE ::= {
+ WITH SYNTAX MultipleMatchingLocalities
+ ID id-not-multipleMatchingLocalities
+}
+
+MultipleMatchingLocalities ::= SEQUENCE {
+ matchingRuleUsed MATCHING-RULE.&id OPTIONAL,
+ attributeList SEQUENCE OF AttributeValueAssertion
+}
+
+proposedRelaxation ATTRIBUTE ::= {
+ WITH SYNTAX SEQUENCE OF MRMapping
+ ID id-not-proposedRelaxation
+}
+
+appliedRelaxation ATTRIBUTE ::= {
+ WITH SYNTAX OBJECT IDENTIFIER
+ EQUALITY MATCHING RULE objectIdentifierMatch
+ ID id-not-appliedRelaxation
+}
+
+-- Matching rules
+caseIgnoreMatch MATCHING-RULE ::= {
+ SYNTAX DirectoryString {ub-match}
+ ID id-mr-caseIgnoreMatch
+}
+
+caseIgnoreOrderingMatch MATCHING-RULE ::= {
+ SYNTAX DirectoryString {ub-match}
+ ID id-mr-caseIgnoreOrderingMatch
+}
+
+caseIgnoreSubstringsMatch MATCHING-RULE ::= {
+ SYNTAX SubstringAssertion
+ ID id-mr-caseIgnoreSubstringsMatch
+}
+
+SubstringAssertion ::=
+ SEQUENCE OF
+ CHOICE {initial [0] DirectoryString{ub-match},
+ any [1] DirectoryString{ub-match},
+ final [2] DirectoryString{ub-match},
+ control Attribute
+ } -- Used to specify interpretation of the following items
+
+-- at most one initial and one final component
+caseExactMatch MATCHING-RULE ::= {
+ SYNTAX DirectoryString {ub-match}
+ ID id-mr-caseExactMatch
+}
+
+caseExactOrderingMatch MATCHING-RULE ::= {
+ SYNTAX DirectoryString {ub-match}
+ ID id-mr-caseExactOrderingMatch
+}
+
+caseExactSubstringsMatch MATCHING-RULE ::= {
+ SYNTAX SubstringAssertion -- only the PrintableString choice
+ ID id-mr-caseExactSubstringsMatch
+}
+
+numericStringMatch MATCHING-RULE ::= {
+ SYNTAX NumericString
+ ID id-mr-numericStringMatch
+}
+
+numericStringOrderingMatch MATCHING-RULE ::= {
+ SYNTAX NumericString
+ ID id-mr-numericStringOrderingMatch
+}
+
+numericStringSubstringsMatch MATCHING-RULE ::= {
+ SYNTAX SubstringAssertion
+ ID id-mr-numericStringSubstringsMatch
+}
+
+caseIgnoreListMatch MATCHING-RULE ::= {
+ SYNTAX CaseIgnoreListMatch
+ ID id-mr-caseIgnoreListMatch
+}
+
+CaseIgnoreListMatch ::= SEQUENCE OF DirectoryString{ub-match}
+
+caseIgnoreListSubstringsMatch MATCHING-RULE ::= {
+ SYNTAX SubstringAssertion
+ ID id-mr-caseIgnoreListSubstringsMatch
+}
+
+storedPrefixMatch MATCHING-RULE ::= {
+ SYNTAX DirectoryString {ub-match}
+ ID id-mr-storedPrefixMatch
+}
+
+booleanMatch MATCHING-RULE ::= {SYNTAX BOOLEAN
+ ID id-mr-booleanMatch
+}
+
+integerMatch MATCHING-RULE ::= {SYNTAX INTEGER
+ ID id-mr-integerMatch
+}
+
+integerOrderingMatch MATCHING-RULE ::= {
+ SYNTAX INTEGER
+ ID id-mr-integerOrderingMatch
+}
+
+bitStringMatch MATCHING-RULE ::= {
+ SYNTAX BIT STRING
+ ID id-mr-bitStringMatch
+}
+
+octetStringMatch MATCHING-RULE ::= {
+ SYNTAX OCTET STRING
+ ID id-mr-octetStringMatch
+}
+
+octetStringOrderingMatch MATCHING-RULE ::= {
+ SYNTAX OCTET STRING
+ ID id-mr-octetStringOrderingMatch
+}
+
+octetStringSubstringsMatch MATCHING-RULE ::= {
+ SYNTAX OctetSubstringAssertion
+ ID id-mr-octetStringSubstringsMatch
+}
+
+OctetSubstringAssertion ::=
+ SEQUENCE OF
+ CHOICE {initial [0] OCTET STRING,
+ any [1] OCTET STRING,
+ final [2] OCTET STRING}
+
+-- at most one initial and one final component
+telephoneNumberMatch MATCHING-RULE ::= {
+ SYNTAX TelephoneNumber
+ ID id-mr-telephoneNumberMatch
+}
+
+telephoneNumberSubstringsMatch MATCHING-RULE ::= {
+ SYNTAX SubstringAssertion
+ ID id-mr-telephoneNumberSubstringsMatch
+}
+
+presentationAddressMatch MATCHING-RULE ::= {
+ SYNTAX PresentationAddress
+ ID id-mr-presentationAddressMatch
+}
+
+uniqueMemberMatch MATCHING-RULE ::= {
+ SYNTAX NameAndOptionalUID
+ ID id-mr-uniqueMemberMatch
+}
+
+protocolInformationMatch MATCHING-RULE ::= {
+ SYNTAX OCTET STRING
+ ID id-mr-protocolInformationMatch
+}
+
+uTCTimeMatch MATCHING-RULE ::= {SYNTAX UTCTime
+ ID id-mr-uTCTimeMatch
+}
+
+uTCTimeOrderingMatch MATCHING-RULE ::= {
+ SYNTAX UTCTime
+ ID id-mr-uTCTimeOrderingMatch
+}
+
+generalizedTimeMatch MATCHING-RULE ::= {
+ SYNTAX GeneralizedTime
+ -- as per 41.3 b) or c) of ITU-T Rec. X.680 | ISO/IEC 8824-1
+ ID id-mr-generalizedTimeMatch
+}
+
+generalizedTimeOrderingMatch MATCHING-RULE ::= {
+ SYNTAX GeneralizedTime
+ -- as per 41.3 b) or c) of ITU-T Rec. X.680 | ISO/IEC 8824-1
+ ID id-mr-generalizedTimeOrderingMatch
+}
+
+integerFirstComponentMatch MATCHING-RULE ::= {
+ SYNTAX INTEGER
+ ID id-mr-integerFirstComponentMatch
+}
+
+objectIdentifierFirstComponentMatch MATCHING-RULE ::= {
+ SYNTAX OBJECT IDENTIFIER
+ ID id-mr-objectIdentifierFirstComponentMatch
+}
+
+directoryStringFirstComponentMatch MATCHING-RULE ::= {
+ SYNTAX DirectoryString {ub-directory-string-first-component-match}
+ ID id-mr-directoryStringFirstComponentMatch
+}
+
+wordMatch MATCHING-RULE ::= {
+ SYNTAX DirectoryString {ub-match}
+ ID id-mr-wordMatch
+}
+
+keywordMatch MATCHING-RULE ::= {
+ SYNTAX DirectoryString {ub-match}
+ ID id-mr-keywordMatch
+}
+
+systemProposedMatch MATCHING-RULE ::= {ID id-mr-systemProposedMatch
+}
+
+generalWordMatch MATCHING-RULE ::= {
+ SYNTAX SubstringAssertion
+ ID id-mr-generalWordMatch
+}
+
+sequenceMatchType ATTRIBUTE ::= {
+ WITH SYNTAX
+ ENUMERATED {sequenceExact(0), sequenceDeletion(1),
+ sequenceRestrictedDeletion(2), sequencePermutation(3),
+ sequencePermutationAndDeletion(4), sequenceProviderDefined(5)}
+ SINGLE VALUE TRUE
+ ID id-cat-sequenceMatchType
+} -- defaulting to sequenceExact,
+
+wordMatchTypes ATTRIBUTE ::= {
+ WITH SYNTAX
+ ENUMERATED {wordExact(0), wordTruncated(1), wordPhonetic(2),
+ wordProviderDefined(3)}
+ SINGLE VALUE TRUE
+ ID id-cat-wordMatchType
+} -- defaulting to wordExact
+
+characterMatchTypes ATTRIBUTE ::= {
+ WITH SYNTAX
+ ENUMERATED {characterExact(0), characterCaseIgnore(1), characterMapped(2)}
+ SINGLE VALUE TRUE
+ ID id-cat-characterMatchTypes
+}
+
+selectedContexts ATTRIBUTE ::= {
+ WITH SYNTAX ContextAssertion
+ ID id-cat-selectedContexts
+}
+
+approximateStringMatch MATCHING-RULE ::= {ID id-mr-approximateStringMatch
+}
+
+ignoreIfAbsentMatch MATCHING-RULE ::= {ID id-mr-ignoreIfAbsentMatch
+}
+
+nullMatch MATCHING-RULE ::= {ID id-mr-nullMatch
+}
+
+ZONAL-MATCHING ::=
+ MAPPING-BASED-MATCHING{ZonalSelect, TRUE, ZonalResult, zonalMatch.&id}
+
+ZonalSelect ::= SEQUENCE OF AttributeType
+
+ZonalResult ::= ENUMERATED {
+ cannot-select-mapping(0), zero-mappings(2), multiple-mappings(3)}
+
+zonalMatch MATCHING-RULE ::= {
+ UNIQUE-MATCH-INDICATOR multipleMatchingLocalities.&id
+ ID id-mr-zonalMatch
+}
+
+-- Contexts
+languageContext CONTEXT ::= {
+ WITH SYNTAX LanguageContextSyntax
+ ID id-avc-language
+}
+
+LanguageContextSyntax ::= PrintableString(SIZE (2..3)) -- ISO 639-2 codes only
+
+
+temporalContext CONTEXT ::= {
+ WITH SYNTAX TimeSpecification
+ ASSERTED AS TimeAssertion
+ ID id-avc-temporal
+}
+
+TimeSpecification ::= SEQUENCE {
+ time
+ CHOICE {absolute
+ SEQUENCE {startTime [0] GeneralizedTime OPTIONAL,
+ endTime [1] GeneralizedTime OPTIONAL},
+ periodic SET OF Period},
+ notThisTime BOOLEAN DEFAULT FALSE,
+ timeZone TimeZone OPTIONAL
+}
+
+Period ::= SEQUENCE {
+ timesOfDay [0] SET SIZE (1..MAX) OF DayTimeBand OPTIONAL,
+ days
+ [1] CHOICE {intDay SET OF INTEGER,
+ bitDay
+ BIT STRING {sunday(0), monday(1), tuesday(2), wednesday(3),
+ thursday(4), friday(5), saturday(6)},
+ dayOf XDayOf} OPTIONAL,
+ weeks
+ [2] CHOICE {allWeeks NULL,
+ intWeek SET OF INTEGER,
+ bitWeek
+ BIT STRING {week1(0), week2(1), week3(2), week4(3), week5(4)}
+ } OPTIONAL,
+ months
+ [3] CHOICE {allMonths NULL,
+ intMonth SET OF INTEGER,
+ bitMonth
+ BIT STRING {january(0), february(1), march(2), april(3),
+ may(4), june(5), july(6), august(7),
+ september(8), october(9), november(10),
+ december(11)}} OPTIONAL,
+ years [4] SET OF INTEGER(1000..MAX) OPTIONAL
+}
+
+XDayOf ::= CHOICE {
+ first [1] NamedDay,
+ second [2] NamedDay,
+ third [3] NamedDay,
+ fourth [4] NamedDay,
+ fifth [5] NamedDay
+}
+
+NamedDay ::= CHOICE {
+ intNamedDays
+ ENUMERATED {sunday(1), monday(2), tuesday(3), wednesday(4), thursday(5),
+ friday(6), saturday(7)},
+ bitNamedDays
+ BIT STRING {sunday(0), monday(1), tuesday(2), wednesday(3), thursday(4),
+ friday(5), saturday(6)}
+}
+
+DayTimeBand ::= SEQUENCE {
+ startDayTime [0] DayTime DEFAULT {hour 0},
+ endDayTime [1] DayTime DEFAULT {hour 23, minute 59, second 59}
+}
+
+DayTime ::= SEQUENCE {
+ hour [0] INTEGER(0..23),
+ minute [1] INTEGER(0..59) DEFAULT 0,
+ second [2] INTEGER(0..59) DEFAULT 0
+}
+
+TimeZone ::= INTEGER(-12..12)
+
+TimeAssertion ::= CHOICE {
+ now NULL,
+ at GeneralizedTime,
+ between
+ SEQUENCE {startTime [0] GeneralizedTime,
+ endTime [1] GeneralizedTime OPTIONAL,
+ entirely BOOLEAN DEFAULT FALSE}
+}
+
+localeContext CONTEXT ::= {
+ WITH SYNTAX LocaleContextSyntax
+ ID id-avc-locale
+}
+
+LocaleContextSyntax ::= CHOICE {
+ localeID1 OBJECT IDENTIFIER,
+ localeID2 DirectoryString{ub-localeContextSyntax}
+}
+
+-- Object identifier assignments -
+-- object identifiers assigned in other modules are shown in comments
+-- Attributes
+-- id-at-objectClass OBJECT IDENTIFIER ::= {id-at 0}
+-- id-at-aliasedEntryName OBJECT IDENTIFIER ::= {id-at 1}
+id-at-encryptedAliasedEntryName OBJECT IDENTIFIER ::=
+ {id-at 1 2}
+
+id-at-knowledgeInformation OBJECT IDENTIFIER ::= {id-at 2}
+
+id-at-commonName OBJECT IDENTIFIER ::= {id-at 3}
+
+id-at-encryptedCommonName OBJECT IDENTIFIER ::= {id-at 3 2}
+
+id-at-surname OBJECT IDENTIFIER ::= {id-at 4}
+
+id-at-encryptedSurname OBJECT IDENTIFIER ::= {id-at 4 2}
+
+id-at-serialNumber OBJECT IDENTIFIER ::= {id-at 5}
+
+id-at-encryptedSerialNumber OBJECT IDENTIFIER ::= {id-at 5 2}
+
+id-at-countryName OBJECT IDENTIFIER ::= {id-at 6}
+
+id-at-encryptedCountryName OBJECT IDENTIFIER ::= {id-at 6 2}
+
+id-at-localityName OBJECT IDENTIFIER ::= {id-at 7}
+
+id-at-encryptedLocalityName OBJECT IDENTIFIER ::= {id-at 7 2}
+
+id-at-collectiveLocalityName OBJECT IDENTIFIER ::= {id-at 7 1}
+
+id-at-encryptedCollectiveLocalityName OBJECT IDENTIFIER ::= {id-at 7 1 2}
+
+id-at-stateOrProvinceName OBJECT IDENTIFIER ::= {id-at 8}
+
+id-at-encryptedStateOrProvinceName OBJECT IDENTIFIER ::= {id-at 8 2}
+
+id-at-collectiveStateOrProvinceName OBJECT IDENTIFIER ::= {id-at 8 1}
+
+id-at-encryptedCollectiveStateOrProvinceName OBJECT IDENTIFIER ::=
+ {id-at 8 1 2}
+
+id-at-streetAddress OBJECT IDENTIFIER ::= {id-at 9}
+
+id-at-encryptedStreetAddress OBJECT IDENTIFIER ::= {id-at 9 2}
+
+id-at-collectiveStreetAddress OBJECT IDENTIFIER ::= {id-at 9 1}
+
+id-at-encryptedCollectiveStreetAddress OBJECT IDENTIFIER ::= {id-at 9 1 2}
+
+id-at-organizationName OBJECT IDENTIFIER ::= {id-at 10}
+
+id-at-encryptedOrganizationName OBJECT IDENTIFIER ::= {id-at 10 2}
+
+id-at-collectiveOrganizationName OBJECT IDENTIFIER ::= {id-at 10 1}
+
+id-at-encryptedCollectiveOrganizationName OBJECT IDENTIFIER ::= {id-at 10 1 2}
+
+id-at-organizationalUnitName OBJECT IDENTIFIER ::= {id-at 11}
+
+id-at-encryptedOrganizationalUnitName OBJECT IDENTIFIER ::= {id-at 11 2}
+
+id-at-collectiveOrganizationalUnitName OBJECT IDENTIFIER ::= {id-at 11 1}
+
+id-at-encryptedCollectiveOrganizationalUnitName OBJECT IDENTIFIER ::=
+ {id-at 11 1 2}
+
+id-at-title OBJECT IDENTIFIER ::= {id-at 12}
+
+id-at-encryptedTitle OBJECT IDENTIFIER ::= {id-at 12 2}
+
+id-at-description OBJECT IDENTIFIER ::= {id-at 13}
+
+id-at-encryptedDescription OBJECT IDENTIFIER ::= {id-at 13 2}
+
+id-at-searchGuide OBJECT IDENTIFIER ::= {id-at 14}
+
+id-at-encryptedSearchGuide OBJECT IDENTIFIER ::= {id-at 14 2}
+
+id-at-businessCategory OBJECT IDENTIFIER ::= {id-at 15}
+
+id-at-encryptedBusinessCategory OBJECT IDENTIFIER ::= {id-at 15 2}
+
+id-at-postalAddress OBJECT IDENTIFIER ::= {id-at 16}
+
+id-at-encryptedPostalAddress OBJECT IDENTIFIER ::= {id-at 16 2}
+
+id-at-collectivePostalAddress OBJECT IDENTIFIER ::= {id-at 16 1}
+
+id-at-encryptedCollectivePostalAddress OBJECT IDENTIFIER ::= {id-at 16 1 2}
+
+id-at-postalCode OBJECT IDENTIFIER ::= {id-at 17}
+
+id-at-encryptedPostalCode OBJECT IDENTIFIER ::= {id-at 17 2}
+
+id-at-collectivePostalCode OBJECT IDENTIFIER ::= {id-at 17 1}
+
+id-at-encryptedCollectivePostalCode OBJECT IDENTIFIER ::= {id-at 17 1 2}
+
+id-at-postOfficeBox OBJECT IDENTIFIER ::= {id-at 18}
+
+id-at-encryptedPostOfficeBox OBJECT IDENTIFIER ::= {id-at 18 2}
+
+id-at-collectivePostOfficeBox OBJECT IDENTIFIER ::= {id-at 18 1}
+
+id-at-encryptedCollectivePostOfficeBox OBJECT IDENTIFIER ::= {id-at 18 1 2}
+
+id-at-physicalDeliveryOfficeName OBJECT IDENTIFIER ::= {id-at 19}
+
+id-at-encryptedPhysicalDeliveryOfficeName OBJECT IDENTIFIER ::= {id-at 19 2}
+
+id-at-collectivePhysicalDeliveryOfficeName OBJECT IDENTIFIER ::= {id-at 19 1}
+
+id-at-encryptedCollectivePhysicalDeliveryOfficeName OBJECT IDENTIFIER ::=
+ {id-at 19 1 2}
+
+id-at-telephoneNumber OBJECT IDENTIFIER ::= {id-at 20}
+
+id-at-encryptedTelephoneNumber OBJECT IDENTIFIER ::= {id-at 20 2}
+
+id-at-collectiveTelephoneNumber OBJECT IDENTIFIER ::= {id-at 20 1}
+
+id-at-encryptedCollectiveTelephoneNumber OBJECT IDENTIFIER ::= {id-at 20 1 2}
+
+id-at-telexNumber OBJECT IDENTIFIER ::= {id-at 21}
+
+id-at-encryptedTelexNumber OBJECT IDENTIFIER ::= {id-at 21 2}
+
+id-at-collectiveTelexNumber OBJECT IDENTIFIER ::= {id-at 21 1}
+
+id-at-encryptedCollectiveTelexNumber OBJECT IDENTIFIER ::= {id-at 21 1 2}
+
+-- id-at-teletexTerminalIdentifier OBJECT IDENTIFIER ::= {id-at 22}
+-- id-at-encryptedTeletexTerminalIdentifier OBJECT IDENTIFIER ::= {id-at 22 2}
+-- id-at-collectiveTeletexTerminalIdentifier OBJECT IDENTIFIER ::= {id-at 22 1}
+-- id-at-encryptedCollectiveTeletexTerminalIdentifier
+-- OBJECT IDENTIFIER ::= {id-at 22 1 2}
+id-at-facsimileTelephoneNumber OBJECT IDENTIFIER ::=
+ {id-at 23}
+
+id-at-encryptedFacsimileTelephoneNumber OBJECT IDENTIFIER ::= {id-at 23 2}
+
+id-at-collectiveFacsimileTelephoneNumber OBJECT IDENTIFIER ::= {id-at 23 1}
+
+id-at-encryptedCollectiveFacsimileTelephoneNumber OBJECT IDENTIFIER ::=
+ {id-at 23 1 2}
+
+id-at-x121Address OBJECT IDENTIFIER ::= {id-at 24}
+
+id-at-encryptedX121Address OBJECT IDENTIFIER ::= {id-at 24 2}
+
+id-at-internationalISDNNumber OBJECT IDENTIFIER ::= {id-at 25}
+
+id-at-encryptedInternationalISDNNumber OBJECT IDENTIFIER ::= {id-at 25 2}
+
+id-at-collectiveInternationalISDNNumber OBJECT IDENTIFIER ::= {id-at 25 1}
+
+id-at-encryptedCollectiveInternationalISDNNumber OBJECT IDENTIFIER ::=
+ {id-at 25 1 2}
+
+id-at-registeredAddress OBJECT IDENTIFIER ::= {id-at 26}
+
+id-at-encryptedRegisteredAddress OBJECT IDENTIFIER ::= {id-at 26 2}
+
+id-at-destinationIndicator OBJECT IDENTIFIER ::= {id-at 27}
+
+id-at-encryptedDestinationIndicator OBJECT IDENTIFIER ::= {id-at 27 2}
+
+id-at-preferredDeliveryMethod OBJECT IDENTIFIER ::= {id-at 28}
+
+id-at-encryptedPreferredDeliveryMethod OBJECT IDENTIFIER ::= {id-at 28 2}
+
+id-at-presentationAddress OBJECT IDENTIFIER ::= {id-at 29}
+
+id-at-encryptedPresentationAddress OBJECT IDENTIFIER ::= {id-at 29 2}
+
+id-at-supportedApplicationContext OBJECT IDENTIFIER ::= {id-at 30}
+
+id-at-encryptedSupportedApplicationContext OBJECT IDENTIFIER ::= {id-at 30 2}
+
+id-at-member OBJECT IDENTIFIER ::= {id-at 31}
+
+id-at-encryptedMember OBJECT IDENTIFIER ::= {id-at 31 2}
+
+id-at-owner OBJECT IDENTIFIER ::= {id-at 32}
+
+id-at-encryptedOwner OBJECT IDENTIFIER ::= {id-at 32 2}
+
+id-at-roleOccupant OBJECT IDENTIFIER ::= {id-at 33}
+
+id-at-encryptedRoleOccupant OBJECT IDENTIFIER ::= {id-at 33 2}
+
+id-at-seeAlso OBJECT IDENTIFIER ::= {id-at 34}
+
+id-at-encryptedSeeAlso OBJECT IDENTIFIER ::= {id-at 34 2}
+
+-- id-at-userPassword OBJECT IDENTIFIER ::= {id-at 35}
+id-at-encryptedUserPassword OBJECT IDENTIFIER ::=
+ {id-at 35 2}
+
+-- id-at-userCertificate OBJECT IDENTIFIER ::= {id-at 36}
+id-at-encryptedUserCertificate OBJECT IDENTIFIER ::=
+ {id-at 36 2}
+
+-- id-at-cACertificate OBJECT IDENTIFIER ::= {id-at 37}
+id-at-encryptedCACertificate OBJECT IDENTIFIER ::=
+ {id-at 37 2}
+
+-- id-at-authorityRevocationList OBJECT IDENTIFIER ::= {id-at 38}
+id-at-encryptedAuthorityRevocationList OBJECT IDENTIFIER ::=
+ {id-at 38 2}
+
+-- id-at-certificateRevocationList OBJECT IDENTIFIER ::= {id-at 39}
+id-at-encryptedCertificateRevocationList OBJECT IDENTIFIER ::=
+ {id-at 39 2}
+
+-- id-at-crossCertificatePair OBJECT IDENTIFIER ::= {id-at 40}
+id-at-encryptedCrossCertificatePair OBJECT IDENTIFIER ::=
+ {id-at 40 2}
+
+id-at-name OBJECT IDENTIFIER ::= {id-at 41}
+
+id-at-givenName OBJECT IDENTIFIER ::= {id-at 42}
+
+id-at-encryptedGivenName OBJECT IDENTIFIER ::= {id-at 42 2}
+
+id-at-initials OBJECT IDENTIFIER ::= {id-at 43}
+
+id-at-encryptedInitials OBJECT IDENTIFIER ::= {id-at 43 2}
+
+id-at-generationQualifier OBJECT IDENTIFIER ::= {id-at 44}
+
+id-at-encryptedGenerationQualifier OBJECT IDENTIFIER ::= {id-at 44 2}
+
+id-at-uniqueIdentifier OBJECT IDENTIFIER ::= {id-at 45}
+
+id-at-encryptedUniqueIdentifier OBJECT IDENTIFIER ::= {id-at 45 2}
+
+id-at-dnQualifier OBJECT IDENTIFIER ::= {id-at 46}
+
+id-at-encryptedDnQualifier OBJECT IDENTIFIER ::= {id-at 46 2}
+
+id-at-enhancedSearchGuide OBJECT IDENTIFIER ::= {id-at 47}
+
+id-at-encryptedEnhancedSearchGuide OBJECT IDENTIFIER ::= {id-at 47 2}
+
+id-at-protocolInformation OBJECT IDENTIFIER ::= {id-at 48}
+
+id-at-encryptedProtocolInformation OBJECT IDENTIFIER ::= {id-at 48 2}
+
+id-at-distinguishedName OBJECT IDENTIFIER ::= {id-at 49}
+
+id-at-encryptedDistinguishedName OBJECT IDENTIFIER ::= {id-at 49 2}
+
+id-at-uniqueMember OBJECT IDENTIFIER ::= {id-at 50}
+
+id-at-encryptedUniqueMember OBJECT IDENTIFIER ::= {id-at 50 2}
+
+id-at-houseIdentifier OBJECT IDENTIFIER ::= {id-at 51}
+
+id-at-encryptedHouseIdentifier OBJECT IDENTIFIER ::= {id-at 51 2}
+
+--id-at-supportedAlgorithms OBJECT IDENTIFIER ::= {id-at 52}
+id-at-encryptedSupportedAlgorithms OBJECT IDENTIFIER ::=
+ {id-at 52 2}
+
+--id-at-deltaRevocationList OBJECT IDENTIFIER ::= {id-at 53}
+id-at-encryptedDeltaRevocationList OBJECT IDENTIFIER ::=
+ {id-at 53 2}
+
+id-at-dmdName OBJECT IDENTIFIER ::= {id-at 54}
+
+id-at-encryptedDmdName OBJECT IDENTIFIER ::= {id-at 54 2}
+
+-- id-at-clearance OBJECT IDENTIFIER ::= {id-at 55}
+id-at-encryptedClearance OBJECT IDENTIFIER ::=
+ {id-at 55 2}
+
+-- id-at-defaultDirQop OBJECT IDENTIFIER ::= {id-at 56}
+id-at-encryptedDefaultDirQop OBJECT IDENTIFIER ::=
+ {id-at 56 2}
+
+-- id-at-attributeIntegrityInfo OBJECT IDENTIFIER ::= {id-at 57}
+id-at-encryptedAttributeIntegrityInfo OBJECT IDENTIFIER ::=
+ {id-at 57 2}
+
+--id-at-attributeCertificate OBJECT IDENTIFIER ::= {id-at 58}
+id-at-encryptedAttributeCertificate OBJECT IDENTIFIER ::=
+ {id-at 58 2}
+
+-- id-at-attributeCertificateRevocationList OBJECT IDENTIFIER ::= {id-at 59}
+id-at-encryptedAttributeCertificateRevocationList OBJECT IDENTIFIER ::=
+ {id-at 59 2}
+
+-- id-at-confKeyInfo OBJECT IDENTIFIER ::= {id-at 60}
+id-at-encryptedConfKeyInfo OBJECT IDENTIFIER ::=
+ {id-at 60 2}
+
+-- id-at-family-information OBJECT IDENTIFIER {id-at 64}
+id-at-pseudonym OBJECT IDENTIFIER ::=
+ {id-at 65}
+
+id-at-communicationsService OBJECT IDENTIFIER ::= {id-at 66}
+
+id-at-communicationsNetwork OBJECT IDENTIFIER ::= {id-at 67}
+
+-- Matching rules
+-- id-mr-objectIdentifierMatch OBJECT IDENTIFIER ::= {id-mr 0}
+-- id-mr-distinguishedNameMatch OBJECT IDENTIFIER ::= {id-mr 1}
+id-mr-caseIgnoreMatch OBJECT IDENTIFIER ::=
+ {id-mr 2}
+
+id-mr-caseIgnoreOrderingMatch OBJECT IDENTIFIER ::= {id-mr 3}
+
+id-mr-caseIgnoreSubstringsMatch OBJECT IDENTIFIER ::= {id-mr 4}
+
+id-mr-caseExactMatch OBJECT IDENTIFIER ::= {id-mr 5}
+
+id-mr-caseExactOrderingMatch OBJECT IDENTIFIER ::= {id-mr 6}
+
+id-mr-caseExactSubstringsMatch OBJECT IDENTIFIER ::= {id-mr 7}
+
+id-mr-numericStringMatch OBJECT IDENTIFIER ::= {id-mr 8}
+
+id-mr-numericStringOrderingMatch OBJECT IDENTIFIER ::= {id-mr 9}
+
+id-mr-numericStringSubstringsMatch OBJECT IDENTIFIER ::= {id-mr 10}
+
+id-mr-caseIgnoreListMatch OBJECT IDENTIFIER ::= {id-mr 11}
+
+id-mr-caseIgnoreListSubstringsMatch OBJECT IDENTIFIER ::= {id-mr 12}
+
+id-mr-booleanMatch OBJECT IDENTIFIER ::= {id-mr 13}
+
+id-mr-integerMatch OBJECT IDENTIFIER ::= {id-mr 14}
+
+id-mr-integerOrderingMatch OBJECT IDENTIFIER ::= {id-mr 15}
+
+id-mr-bitStringMatch OBJECT IDENTIFIER ::= {id-mr 16}
+
+id-mr-octetStringMatch OBJECT IDENTIFIER ::= {id-mr 17}
+
+id-mr-octetStringOrderingMatch OBJECT IDENTIFIER ::= {id-mr 18}
+
+id-mr-octetStringSubstringsMatch OBJECT IDENTIFIER ::= {id-mr 19}
+
+id-mr-telephoneNumberMatch OBJECT IDENTIFIER ::= {id-mr 20}
+
+id-mr-telephoneNumberSubstringsMatch OBJECT IDENTIFIER ::= {id-mr 21}
+
+id-mr-presentationAddressMatch OBJECT IDENTIFIER ::= {id-mr 22}
+
+id-mr-uniqueMemberMatch OBJECT IDENTIFIER ::= {id-mr 23}
+
+id-mr-protocolInformationMatch OBJECT IDENTIFIER ::= {id-mr 24}
+
+id-mr-uTCTimeMatch OBJECT IDENTIFIER ::= {id-mr 25}
+
+id-mr-uTCTimeOrderingMatch OBJECT IDENTIFIER ::= {id-mr 26}
+
+id-mr-generalizedTimeMatch OBJECT IDENTIFIER ::= {id-mr 27}
+
+id-mr-generalizedTimeOrderingMatch OBJECT IDENTIFIER ::= {id-mr 28}
+
+id-mr-integerFirstComponentMatch OBJECT IDENTIFIER ::= {id-mr 29}
+
+id-mr-objectIdentifierFirstComponentMatch OBJECT IDENTIFIER ::= {id-mr 30}
+
+id-mr-directoryStringFirstComponentMatch OBJECT IDENTIFIER ::= {id-mr 31}
+
+id-mr-wordMatch OBJECT IDENTIFIER ::= {id-mr 32}
+
+id-mr-keywordMatch OBJECT IDENTIFIER ::= {id-mr 33}
+
+-- id-mr-certificateExactMatch OBJECT IDENTIFIER ::= {id-mr 34}
+-- id-mr-certificateMatch OBJECT IDENTIFIER ::= {id-mr 35}
+-- id-mr-certificatePairExactMatch OBJECT IDENTIFIER ::= {id-mr 36}
+-- id-mr-certificatePairMatch OBJECT IDENTIFIER ::= {id-mr 37}
+-- id-mr-certificateListExactMatch OBJECT IDENTIFIER ::= {id-mr 38}
+-- id-mr-certificateListMatch OBJECT IDENTIFIER ::= {id-mr 39}
+-- id-mr-algorithmIdentifierMatch OBJECT IDENTIFIER ::= {id-mr 40}
+id-mr-storedPrefixMatch OBJECT IDENTIFIER ::=
+ {id-mr 41}
+
+-- id-mr-attributeCertificateMatch OBJECT IDENTIFIER ::= {id-mr 42}
+-- id-mr-readerAndKeyIDMatch OBJECT IDENTIFIER ::= {id-mr 43}
+--id-mr-attributeIntegrityMatch OBJECT IDENTIFIER ::= {id-mr 44}
+id-mr-systemProposedMatch OBJECT IDENTIFIER ::=
+ {id-mr 47}
+
+id-mr-generalWordMatch OBJECT IDENTIFIER ::= {id-mr 48}
+
+id-mr-approximateStringMatch OBJECT IDENTIFIER ::= {id-mr 49}
+
+id-mr-ignoreIfAbsentMatch OBJECT IDENTIFIER ::= {id-mr 50}
+
+id-mr-nullMatch OBJECT IDENTIFIER ::= {id-mr 51}
+
+id-mr-zonalMatch OBJECT IDENTIFIER ::= {id-mr 52}
+
+id-mr-facsimileNumberMatch OBJECT IDENTIFIER ::= {id-mr 63}
+
+id-mr-facsimileNumberSubstringsMatch OBJECT IDENTIFIER ::= {id-mr 64}
+
+-- contexts
+id-avc-language OBJECT IDENTIFIER ::= {id-avc 0}
+
+id-avc-temporal OBJECT IDENTIFIER ::= {id-avc 1}
+
+id-avc-locale OBJECT IDENTIFIER ::= {id-avc 2}
+
+--id-avc-attributeValueSecurityLabelContext OBJECT IDENTIFIER ::= {id-avc 3}
+--id-avc-attributeValueIntegrityInfoContext OBJECT IDENTIFIER ::= {id-avc 4}
+-- Problem definitions
+id-pr-targetDsaUnavailable OBJECT IDENTIFIER ::=
+ {id-pr 1}
+
+id-pr-dataSourceUnavailable OBJECT IDENTIFIER ::= {id-pr 2}
+
+id-pr-unidentifiedOperation OBJECT IDENTIFIER ::= {id-pr 3}
+
+id-pr-unavailableOperation OBJECT IDENTIFIER ::= {id-pr 4}
+
+id-pr-searchAttributeViolation OBJECT IDENTIFIER ::= {id-pr 5}
+
+id-pr-searchAttributeCombinationViolation OBJECT IDENTIFIER ::= {id-pr 6}
+
+id-pr-searchValueNotAllowed OBJECT IDENTIFIER ::= {id-pr 7}
+
+id-pr-missingSearchAttribute OBJECT IDENTIFIER ::= {id-pr 8}
+
+id-pr-searchValueViolation OBJECT IDENTIFIER ::= {id-pr 9}
+
+id-pr-attributeNegationViolation OBJECT IDENTIFIER ::= {id-pr 10}
+
+id-pr-searchValueRequired OBJECT IDENTIFIER ::= {id-pr 11}
+
+id-pr-invalidSearchValue OBJECT IDENTIFIER ::= {id-pr 12}
+
+id-pr-searchContextViolation OBJECT IDENTIFIER ::= {id-pr 13}
+
+id-pr-searchContextCombinationViolation OBJECT IDENTIFIER ::= {id-pr 14}
+
+id-pr-missingSearchContext OBJECT IDENTIFIER ::= {id-pr 15}
+
+id-pr-searchContextValueViolation OBJECT IDENTIFIER ::= {id-pr 16}
+
+id-pr-searchContextValueRequired OBJECT IDENTIFIER ::= {id-pr 17}
+
+id-pr-invalidContextSearchValue OBJECT IDENTIFIER ::= {id-pr 18}
+
+id-pr-unsupportedMatchingRule OBJECT IDENTIFIER ::= {id-pr 19}
+
+id-pr-attributeMatchingViolation OBJECT IDENTIFIER ::= {id-pr 20}
+
+id-pr-unsupportedMatchingUse OBJECT IDENTIFIER ::= {id-pr 21}
+
+id-pr-matchingUseViolation OBJECT IDENTIFIER ::= {id-pr 22}
+
+id-pr-hierarchySelectForbidden OBJECT IDENTIFIER ::= {id-pr 23}
+
+id-pr-invalidHierarchySelect OBJECT IDENTIFIER ::= {id-pr 24}
+
+id-pr-unavailableHierarchySelect OBJECT IDENTIFIER ::= {id-pr 25}
+
+id-pr-invalidSearchOptions OBJECT IDENTIFIER ::= {id-pr 26}
+
+id-pr-missingSearchOptions OBJECT IDENTIFIER ::= {id-pr 27}
+
+id-pr-invalidServiceControlOptions OBJECT IDENTIFIER ::= {id-pr 28}
+
+id-pr-missingServiceControlOptions OBJECT IDENTIFIER ::= {id-pr 29}
+
+id-pr-searchSubsetViolation OBJECT IDENTIFIER ::= {id-pr 30}
+
+id-pr-unmatchedKeyAttributes OBJECT IDENTIFIER ::= {id-pr 31}
+
+id-pr-ambiguousKeyAttributes OBJECT IDENTIFIER ::= {id-pr 32}
+
+-- Notification attributes
+id-not-dSAProblem OBJECT IDENTIFIER ::= {id-not 0}
+
+id-not-searchServiceProblem OBJECT IDENTIFIER ::= {id-not 1}
+
+id-not-serviceType OBJECT IDENTIFIER ::= {id-not 2}
+
+id-not-attributeTypeList OBJECT IDENTIFIER ::= {id-not 3}
+
+id-not-matchingRuleList OBJECT IDENTIFIER ::= {id-not 4}
+
+id-not-filterItem OBJECT IDENTIFIER ::= {id-not 5}
+
+id-not-attributeCombinations OBJECT IDENTIFIER ::= {id-not 6}
+
+id-not-contextTypeList OBJECT IDENTIFIER ::= {id-not 7}
+
+id-not-contextList OBJECT IDENTIFIER ::= {id-not 8}
+
+id-not-contextCombinations OBJECT IDENTIFIER ::= {id-not 9}
+
+id-not-hierarchySelectList OBJECT IDENTIFIER ::= {id-not 10}
+
+id-not-searchOptionsList OBJECT IDENTIFIER ::= {id-not 11}
+
+id-not-serviceControlOptionsList OBJECT IDENTIFIER ::= {id-not 12}
+
+id-not-multipleMatchingLocalities OBJECT IDENTIFIER ::= {id-not 13}
+
+id-not-proposedRelaxation OBJECT IDENTIFIER ::= {id-not 14}
+
+id-not-appliedRelaxation OBJECT IDENTIFIER ::= {id-not 15}
+
+id-not-substringRequirements OBJECT IDENTIFIER ::= {id-not 16}
+
+-- Control attributes
+id-cat-sequenceMatchType OBJECT IDENTIFIER ::=
+ {id-cat 1}
+
+id-cat-wordMatchType OBJECT IDENTIFIER ::= {id-cat 2}
+
+id-cat-characterMatchTypes OBJECT IDENTIFIER ::= {id-cat 3}
+
+id-cat-selectedContexts OBJECT IDENTIFIER ::= {id-cat 4}
+
+END -- SelectedAttributeTypes
+
+-- Generated by Asnp, the ASN.1 pretty-printer of France Telecom R&D
+
diff --git a/lib/asn1/test/asn1_SUITE_data/x420/SeseAPDUs.asn b/lib/asn1/test/asn1_SUITE_data/x420/SeseAPDUs.asn
new file mode 100644
index 0000000000..2917122e94
--- /dev/null
+++ b/lib/asn1/test/asn1_SUITE_data/x420/SeseAPDUs.asn
@@ -0,0 +1,116 @@
+-- Module SeseAPDUs (X.832:04/1995)
+
+SeseAPDUs {joint-iso-itu-t genericULS(20) modules(1) seseAPDUs(6)} DEFINITIONS
+AUTOMATIC TAGS ::=
+BEGIN
+
+-- EXPORTS ALL
+IMPORTS
+ notation
+ FROM ObjectIdentifiers {joint-iso-itu-t genericULS(20) modules(1)
+ objectIdentifiers(0)}
+ dirAuthenticationTwoWay
+ FROM GulsSecurityExchanges {joint-iso-itu-t genericULS(20) modules(1)
+ gulsSecurityExchanges(2)}
+ SECURITY-EXCHANGE, SE-ERROR
+ FROM Notation notation;
+
+SESEapdus{SECURITY-EXCHANGE:ValidSEs, InvocationId:InvocationIdSet} ::=
+ CHOICE {
+ se-transfer SETransfer{{ValidSEs}, {InvocationIdSet}},
+ se-u-abort SEUAbort{{ValidSEs}, {InvocationIdSet}},
+ se-p-abort SEPAbort{{ValidSEs}, {InvocationIdSet}}
+}
+
+SETransfer{SECURITY-EXCHANGE:ValidSEs, InvocationId:InvocationIdSet} ::=
+ SEQUENCE {
+ seIdentifier SECURITY-EXCHANGE.&sE-Identifier({ValidSEs}),
+ -- This identifies one of the security-
+ -- exchanges supported by the particular SESE
+ -- abstract syntax
+ itemIdentifier
+ SECURITY-EXCHANGE.&SE-Items.&itemId({ValidSEs}{@seIdentifier}),
+ -- This identifies one of the security-
+ -- exchange-items of the security exchange
+ -- indicated by "seIdentifier"
+ seItem
+ SECURITY-EXCHANGE.&SE-Items.&ItemType
+ ({ValidSEs}{@seIdentifier, @itemIdentifier}),
+ invocationId
+ InvocationId(InvocationIdSet)
+ (CONSTRAINED BY {-- Must be the same as the---- invocationId on an active security exchange--
+
+ -- if start flag is not true -- }) DEFAULT noInvocationId,
+ startFlag BOOLEAN DEFAULT FALSE,
+ -- This field is set only as the first security-
+ -- exchange-item of a security-exchange is
+ -- transferred.
+ endFlag BOOLEAN DEFAULT FALSE-- This field is set as the last security-exchange-
+-- item of a security-exchange is transferred. It is
+-- needed to accommodate those mechanisms requiring
+-- n exchanges, where n is not known a priori
+}
+
+SEUAbort{SECURITY-EXCHANGE:ValidSEs, InvocationId:InvocationIdSet} ::=
+ SEQUENCE {
+ invocationId
+ InvocationId(InvocationIdSet)
+ (CONSTRAINED BY {-- Must be the same as the---- invocationId on an active or just-completed--
+
+ -- security exchange -- }) DEFAULT noInvocationId,
+ itemIdentifier
+ SECURITY-EXCHANGE.&SE-Items.&itemId({ValidSEs.&SE-Items}) OPTIONAL,
+ -- This component will only be present
+ -- when the Abort is generated subsequent
+ -- to receipt of a SETransfer APDU.
+ errors SEQUENCE OF SEerror{{ValidSEs}} OPTIONAL
+ -- needed to handle multiple error codes
+}
+
+SEPAbort{SECURITY-EXCHANGE:ValidSEs, InvocationId:InvocationIdSet} ::=
+ SEQUENCE {
+ invocationId InvocationId(InvocationIdSet) OPTIONAL,
+ itemIdentifier
+ SECURITY-EXCHANGE.&SE-Items.&itemId({ValidSEs.&SE-Items}) OPTIONAL,
+ -- This component will only be present
+ -- when the Abort is generated subsequent
+ -- to receipt of a SETransfer APDU.
+ problemCode ProblemCode
+}
+
+InvocationId ::= CHOICE {present INTEGER,
+ absent NULL
+}
+
+noInvocationId InvocationId ::= absent:NULL
+
+NoInvocationId InvocationId ::= {noInvocationId}
+
+SEerror{SECURITY-EXCHANGE:ValidSEs} ::= SEQUENCE {
+ errorCode SE-ERROR.&errorCode({Errors{{ValidSEs}}}) OPTIONAL,
+ errorParameter
+ SE-ERROR.&ParameterType({Errors{{ValidSEs}}}) OPTIONAL
+}
+
+Errors{SECURITY-EXCHANGE:ValidSEs} SE-ERROR ::= {ValidSEs.&SE-Items.&Errors}
+
+ProblemCode ::= CHOICE {
+ general GeneralProblem,
+ transfer TransferProblem,
+ abort AbortProblem
+}
+
+GeneralProblem ::= ENUMERATED {invalidAPDU(0)}
+
+TransferProblem ::= ENUMERATED {
+ duplicateInvocationId(0), unrecognizedSecurityExchange(1), mistypedItem(2),
+ inappropriateInvocationId(3), alternatingSequenceError(4)}
+
+AbortProblem ::= ENUMERATED {
+ unrecognizedInvocationId(0), abortUnexpected(1), unrecognizedError(2),
+ unexpectedError(3), mistypedErrorParameter(4)}
+
+END
+
+-- Generated by Asnp, the ASN.1 pretty-printer of France Telecom R&D
+
diff --git a/lib/asn1/test/asn1_SUITE_data/x420/SpkmGssTokens.asn b/lib/asn1/test/asn1_SUITE_data/x420/SpkmGssTokens.asn
new file mode 100644
index 0000000000..02205bd64c
--- /dev/null
+++ b/lib/asn1/test/asn1_SUITE_data/x420/SpkmGssTokens.asn
@@ -0,0 +1,257 @@
+-- Module SpkmGssTokens (RFC 2025:10/1996)
+SpkmGssTokens {iso(1) identified-organization(3) dod(6) internet(1) security(5)
+ mechanisms(5) spkm(1) spkmGssTokens(10)}
+--
+-- Copyright (C) The Internet Society (1996). This version of
+-- this ASN.1 module is part of RFC 2025;
+-- see the RFC itself for full legal notices.
+--
+DEFINITIONS IMPLICIT TAGS ::=
+BEGIN
+
+-- EXPORTS ALL
+IMPORTS
+ Name
+ FROM InformationFramework {joint-iso-itu-t(2) ds(5) module(1)
+ informationFramework(1) 3}
+ Certificate, CertificateList, CertificatePair, AlgorithmIdentifier, Validity
+ FROM AuthenticationFramework {joint-iso-itu-t(2) ds(5) module(1)
+ authenticationFramework(7) 3};
+
+-- types
+SPKM-REQ ::= SEQUENCE {
+ requestToken REQ-TOKEN,
+ certif-data [0] CertificationData OPTIONAL,
+ auth-data [1] AuthorizationData OPTIONAL
+}
+
+CertificationData ::= SEQUENCE {
+ certificationPath [0] CertificationPath OPTIONAL,
+ certificateRevocationList [1] CertificateList OPTIONAL
+} -- at least one of the above shall be present
+
+CertificationPath ::= SEQUENCE {
+ userKeyId [0] OCTET STRING OPTIONAL,
+ userCertif [1] Certificate OPTIONAL,
+ verifKeyId [2] OCTET STRING OPTIONAL,
+ userVerifCertif [3] Certificate OPTIONAL,
+ theCACertificates [4] SEQUENCE OF CertificatePair OPTIONAL
+} -- Presence of [2] or [3] implies that [0] or [1] must also be
+
+-- present. Presence of [4] implies that at least one of [0], [1],
+-- [2], and [3] must also be present.
+REQ-TOKEN ::= SEQUENCE {
+ req-contents Req-contents,
+ algId AlgorithmIdentifier,
+ req-integrity Integrity -- "token" is Req-contents
+}
+
+Integrity ::= BIT STRING
+
+-- If corresponding algId specifies a signing algorithm,
+-- "Integrity" holds the result of applying the signing procedure
+-- specified in algId to the BER-encoded octet string which results
+-- from applying the hashing procedure (also specified in algId) to
+-- the DER-encoded octets of "token".
+-- Alternatively, if corresponding algId specifies a MACing
+-- algorithm, "Integrity" holds the result of applying the MACing
+-- procedure specified in algId to the DER-encoded octets of
+-- "token"
+Req-contents ::= SEQUENCE {
+ tok-id INTEGER(256), -- shall contain 0100 (hex)
+ context-id Random-Integer,
+ pvno BIT STRING,
+ timestamp UTCTime OPTIONAL, -- mandatory for SPKM-2
+ randSrc Random-Integer,
+ targ-name Name,
+ src-name [0] Name OPTIONAL,
+ req-data Context-Data,
+ validity [1] Validity OPTIONAL,
+ key-estb-set Key-Estb-Algs,
+ key-estb-req BIT STRING OPTIONAL,
+ key-src-bind OCTET STRING OPTIONAL
+ -- This field must be present for the case of SPKM-2
+ -- unilateral authen. if the K-ALG in use does not provide
+ -- such a binding (but is optional for all other cases).
+ -- The octet string holds the result of applying the
+ -- mandatory hashing procedure (in MANDATORY I-ALG;
+ -- see Section 2.1) as follows: MD5(src || context_key),
+ -- where "src" is the DER-encoded octets of src-name,
+ -- "context-key" is the symmetric key (i.e., the
+ -- unprotected version of what is transmitted in
+ -- key-estb-req), and "||" is the concatenation operation.
+}
+
+Random-Integer ::= BIT STRING
+
+Context-Data ::= SEQUENCE {
+ channelId ChannelId OPTIONAL,
+ seq-number INTEGER OPTIONAL,
+ options Options,
+ conf-alg Conf-Algs,
+ intg-alg Intg-Algs,
+ owf-alg OWF-Algs
+}
+
+ChannelId ::= OCTET STRING
+
+Options ::= BIT STRING {
+ delegation-state(0), mutual-state(1), replay-det-state(2), sequence-state(3),
+ conf-avail(4), integ-avail(5), target-certif-data-required(6)}
+
+Conf-Algs ::= CHOICE {
+ algs [0] SEQUENCE OF AlgorithmIdentifier,
+ null [1] NULL
+}
+
+Intg-Algs ::= SEQUENCE OF AlgorithmIdentifier
+
+OWF-Algs ::= SEQUENCE OF AlgorithmIdentifier
+
+Key-Estb-Algs ::= SEQUENCE OF AlgorithmIdentifier
+
+SPKM-REP-TI ::= SEQUENCE {
+ responseToken REP-TI-TOKEN,
+ certif-data CertificationData OPTIONAL
+ -- present if target-certif-data-required option was
+} -- set to TRUE in SPKM-REQ
+
+REP-TI-TOKEN ::= SEQUENCE {
+ rep-ti-contents Rep-ti-contents,
+ algId AlgorithmIdentifier,
+ rep-ti-integ Integrity -- "token" is Rep-ti-contents
+}
+
+Rep-ti-contents ::= SEQUENCE {
+ tok-id INTEGER(512), -- shall contain 0200 (hex)
+ context-id Random-Integer,
+ pvno [0] BIT STRING OPTIONAL,
+ timestamp UTCTime OPTIONAL, -- mandatory for SPKM-2
+ randTarg Random-Integer,
+ src-name [1] Name OPTIONAL,
+ targ-name Name,
+ randSrc Random-Integer,
+ rep-data Context-Data,
+ validity [2] Validity OPTIONAL,
+ key-estb-id AlgorithmIdentifier OPTIONAL,
+ key-estb-str BIT STRING OPTIONAL
+}
+
+SPKM-REP-IT ::= SEQUENCE {
+ responseToken REP-IT-TOKEN,
+ algId AlgorithmIdentifier,
+ rep-it-integ Integrity -- "token" is REP-IT-TOKEN
+}
+
+REP-IT-TOKEN ::= SEQUENCE {
+ tok-id INTEGER(768), -- shall contain 0300 (hex)
+ context-id Random-Integer,
+ randSrc Random-Integer,
+ randTarg Random-Integer,
+ targ-name Name,
+ src-name Name OPTIONAL,
+ key-estb-rep BIT STRING OPTIONAL
+}
+
+SPKM-ERROR ::= SEQUENCE {
+ errorToken ERROR-TOKEN,
+ algId AlgorithmIdentifier,
+ integrity Integrity -- "token" is ERROR-TOKEN
+}
+
+ERROR-TOKEN ::= SEQUENCE {
+ tok-id INTEGER(1024), -- shall contain 0400 (hex)
+ context-id Random-Integer
+}
+
+SPKM-MIC ::= SEQUENCE {mic-header Mic-Header,
+ int-cksum BIT STRING
+}
+
+Mic-Header ::= SEQUENCE {
+ tok-id INTEGER(257), -- shall contain 0101 (hex)
+ context-id Random-Integer,
+ int-alg [0] AlgorithmIdentifier OPTIONAL,
+ snd-seq [1] SeqNum OPTIONAL
+}
+
+SeqNum ::= SEQUENCE {num INTEGER,
+ dir-ind BOOLEAN
+}
+
+SPKM-WRAP ::= SEQUENCE {wrap-header Wrap-Header,
+ wrap-body Wrap-Body
+}
+
+Wrap-Header ::= SEQUENCE {
+ tok-id INTEGER(513), -- shall contain 0201 (hex)
+ context-id Random-Integer,
+ int-alg [0] AlgorithmIdentifier OPTIONAL,
+ conf-alg [1] Conf-Alg OPTIONAL,
+ snd-seq [2] SeqNum OPTIONAL
+}
+
+Wrap-Body ::= SEQUENCE {int-cksum BIT STRING,
+ data BIT STRING
+}
+
+Conf-Alg ::= CHOICE {algId [0] AlgorithmIdentifier,
+ null [1] NULL
+}
+
+SPKM-DEL ::= SEQUENCE {del-header Del-Header,
+ int-cksum BIT STRING
+}
+
+Del-Header ::= SEQUENCE {
+ tok-id INTEGER(769), -- shall contain 0301 (hex)
+ context-id Random-Integer,
+ int-alg [0] AlgorithmIdentifier OPTIONAL,
+ snd-seq [1] SeqNum OPTIONAL
+}
+
+-- other types
+-- from [RFC-1508]
+MechType ::= OBJECT IDENTIFIER
+
+InitialContextToken ::= [APPLICATION 0] IMPLICIT SEQUENCE {
+ thisMech MechType,
+ innerContextToken SPKMInnerContextToken
+} -- when thisMech is SPKM-1 or SPKM-2
+
+SPKMInnerContextToken ::= CHOICE {
+ req [0] SPKM-REQ,
+ rep-ti [1] SPKM-REP-TI,
+ rep-it [2] SPKM-REP-IT,
+ error [3] SPKM-ERROR,
+ mic [4] SPKM-MIC,
+ wrap [5] SPKM-WRAP,
+ del [6] SPKM-DEL
+}
+
+-- from [RFC-1510]
+AuthorizationData ::=
+ SEQUENCE OF SEQUENCE {ad-type INTEGER,
+ ad-data OCTET STRING}
+
+-- object identifier assignments
+md5-DES-CBC OBJECT IDENTIFIER ::=
+ {iso(1) identified-organization(3) dod(6) internet(1) security(5)
+ integrity(3) md5-DES-CBC(1)}
+
+sum64-DES-CBC OBJECT IDENTIFIER ::=
+ {iso(1) identified-organization(3) dod(6) internet(1) security(5)
+ integrity(3) sum64-DES-CBC(2)}
+
+spkm-1 OBJECT IDENTIFIER ::=
+ {iso(1) identified-organization(3) dod(6) internet(1) security(5)
+ mechanisms(5) spkm(1) spkm-1(1)}
+
+spkm-2 OBJECT IDENTIFIER ::=
+ {iso(1) identified-organization(3) dod(6) internet(1) security(5)
+ mechanisms(5) spkm(1) spkm-2(2)}
+
+END
+
+-- Generated by Asnp, the ASN.1 pretty-printer of France Telecom R&D
+
diff --git a/lib/asn1/test/asn1_SUITE_data/x420/Style-Descriptors.asn b/lib/asn1/test/asn1_SUITE_data/x420/Style-Descriptors.asn
new file mode 100644
index 0000000000..8f033eab6f
--- /dev/null
+++ b/lib/asn1/test/asn1_SUITE_data/x420/Style-Descriptors.asn
@@ -0,0 +1,190 @@
+-- Module Style-Descriptors (T.415:03/1993)
+
+Style-Descriptors {2 8 1 5 10} DEFINITIONS ::=
+BEGIN
+
+EXPORTS
+ Presentation-Style-Descriptor, Presentation-Attributes, Content-Type,
+ Content-Architecture-Class, Layout-Style-Descriptor, Fill-Order,
+ Block-Alignment;
+
+IMPORTS
+ Object-or-Class-Identifier, Style-Identifier, Category-Name,
+ Object-Id-Expression
+ FROM Identifiers-and-Expressions -- see 7.8
+
+ Comment-String, Transparency, Colour, Border, Layout-Object-Type,
+ Content-Background-Colour, Content-Foreground-Colour, Sealed
+ FROM Layout-Descriptors -- see 7.9
+
+ Colour-Expression, Colour-Table
+ FROM Colour-Attributes -- see 7.14
+
+ Character-Attributes
+ FROM Character-Presentation-Attributes {2 8 1 6 2
+ } -- see ITU-T Rec. T.416 | ISO/IEC 8613-6
+ Raster-Graphics-Attributes
+ FROM Raster-Gr-Presentation-Attributes {2 8 1 7 2
+ } -- see ITU-T Rec. T.417 | ISO/IEC 8613-7
+ Geometric-Graphics-Attributes
+ FROM Geo-Gr-Presentation-Attributes {2 8 1 8 2}; -- see ITU-T Rec. T.418 | ISO/IEC 8613-8
+
+Presentation-Style-Descriptor ::= SET {
+ style-identifier Style-Identifier,
+ user-readable-comments [0] IMPLICIT Comment-String OPTIONAL,
+ user-visible-name [1] IMPLICIT Comment-String OPTIONAL,
+ application-comments [25] IMPLICIT OCTET STRING OPTIONAL,
+ transparency [2] IMPLICIT Transparency OPTIONAL,
+ presentation-attributes [3] IMPLICIT Presentation-Attributes OPTIONAL,
+ colour [4] IMPLICIT Colour OPTIONAL,
+ colour-of-layout-object [29] Colour-Expression OPTIONAL,
+ object-colour-table [30] IMPLICIT Colour-Table OPTIONAL,
+ content-background-colour [31] Content-Background-Colour OPTIONAL,
+ content-foreground-colour [32] Content-Foreground-Colour OPTIONAL,
+ content-colour-table [33] IMPLICIT Colour-Table OPTIONAL,
+ border [5] IMPLICIT Border OPTIONAL,
+ sealed [6] IMPLICIT Sealed OPTIONAL,
+ derived-from [7] IMPLICIT Style-Identifier OPTIONAL
+}
+
+Presentation-Attributes ::= SET {
+ content-architecture-class
+ CHOICE {a Content-Architecture-Class,
+ b Content-Type} OPTIONAL,
+ character-attributes [0] IMPLICIT Character-Attributes OPTIONAL,
+ raster-graphics-attributes
+ [1] IMPLICIT Raster-Graphics-Attributes OPTIONAL,
+ geometric-graphics-attributes
+ [2] IMPLICIT Geometric-Graphics-Attributes OPTIONAL,
+ -- the following tags are reserved for additional types
+ -- of presentation attributes:
+ -- [3] videotex, for use in conjunction with CCITT Recommendations
+ -- [4] audio
+ -- [5] dynamic-graphics
+ ext-cont-arch-pres-attributes [6] IMPLICIT SEQUENCE OF EXTERNAL OPTIONAL
+}
+
+Content-Type ::= [APPLICATION 2] IMPLICIT INTEGER {formatted-raster-graphics(1)
+}
+
+-- The integer representation for content architecture class,
+-- Content-Type, is only to be used if the value of the document
+-- profile attribute "document application profile" is an integer.
+-- The value 'formatted-raster-graphics' represents the formatted raster
+-- graphics content architecture as defined in ITU-T Rec. T.417 | ISO/IEC 8613-7.
+Content-Architecture-Class ::= OBJECT IDENTIFIER
+
+Layout-Style-Descriptor ::= SET {
+ style-identifier Style-Identifier,
+ user-readable-comments [0] IMPLICIT Comment-String OPTIONAL,
+ user-visible-name [1] IMPLICIT Comment-String OPTIONAL,
+ application-comments [25] IMPLICIT OCTET STRING OPTIONAL,
+ layout-directives [4] IMPLICIT Layout-Directives OPTIONAL,
+ sealed [6] IMPLICIT Sealed OPTIONAL,
+ derived-from [7] IMPLICIT Style-Identifier OPTIONAL
+}
+
+Layout-Directives ::= SET {
+ indivisibility
+ CHOICE {to-layout-object-class [0] IMPLICIT Object-or-Class-Identifier,
+ to-layout-category [1] IMPLICIT Category-Name,
+ to-layout-object-type [2] IMPLICIT Layout-Object-Type,
+ null [15] IMPLICIT NULL} OPTIONAL,
+ separation [3] IMPLICIT Separation OPTIONAL,
+ offset [4] IMPLICIT Offset OPTIONAL,
+ fill-order [5] IMPLICIT Fill-Order OPTIONAL,
+ concatenation [6] IMPLICIT Concatenation OPTIONAL,
+ new-layout-object
+ CHOICE {to-layout-object-class [7] IMPLICIT Object-or-Class-Identifier,
+ to-layout-category [8] IMPLICIT Category-Name,
+ to-layout-object-type [9] IMPLICIT Layout-Object-Type,
+ null [16] IMPLICIT NULL} OPTIONAL,
+ same-layout-object [10] IMPLICIT Same-Layout-Object OPTIONAL,
+ layout-object-class
+ [11] IMPLICIT Object-or-Class-Identifier OPTIONAL,
+ logical-stream-category [19] IMPLICIT Category-Name OPTIONAL,
+ logical-stream-sub-category [20] IMPLICIT Category-Name OPTIONAL,
+ layout-category [12] IMPLICIT Category-Name OPTIONAL,
+ synchronization
+ CHOICE {a [13] IMPLICIT Object-or-Class-Identifier,
+ b [17] Object-Id-Expression,
+ c [18] IMPLICIT NULL} OPTIONAL,
+ block-alignment [14] IMPLICIT Block-Alignment OPTIONAL,
+ floatability-range [24] IMPLICIT Floatability-Range OPTIONAL
+}
+
+Separation ::= SET {
+ leading [0] IMPLICIT INTEGER OPTIONAL,
+ trailing [1] IMPLICIT INTEGER OPTIONAL,
+ centre [2] IMPLICIT INTEGER OPTIONAL
+}
+
+Offset ::= SET {
+ leading [3] IMPLICIT INTEGER OPTIONAL,
+ trailing [2] IMPLICIT INTEGER OPTIONAL,
+ left-hand [1] IMPLICIT INTEGER OPTIONAL,
+ right-hand [0] IMPLICIT INTEGER OPTIONAL
+}
+
+Fill-Order ::= INTEGER {normal(0), reverse(1)}
+
+Concatenation ::= INTEGER {non-concatenated(0), concatenated(1)}
+
+Same-Layout-Object ::= SET {
+ logical-object
+ CHOICE {a [0] IMPLICIT Object-or-Class-Identifier,
+ b [4] Object-Id-Expression,
+ c [5] IMPLICIT NULL},
+ layout-object
+ CHOICE {d [1] IMPLICIT Object-or-Class-Identifier,
+ to-stream-root-category [6] IMPLICIT Category-Name,
+ to-stream-sub-category [7] IMPLICIT Category-Name,
+ to-layout-category [2] IMPLICIT Category-Name,
+ e [3] IMPLICIT Layout-Object-Type} OPTIONAL
+}
+
+Floatability-Range ::= SET {
+ forward-limit
+ [0] SEQUENCE {logical-object
+ CHOICE {a [2] IMPLICIT Object-or-Class-Identifier,
+ b [3] Object-Id-Expression,
+ c [4] IMPLICIT NULL},
+ layout-object
+ CHOICE {to-layout-object-class
+ [5] IMPLICIT Object-or-Class-Identifier,
+ to-stream-root-category
+ [6] IMPLICIT Category-Name,
+ to-stream-sub-category
+ [7] IMPLICIT Category-Name,
+ to-layout-category
+ [8] IMPLICIT Category-Name,
+ to-layout-object-type
+ [9] IMPLICIT Layout-Object-Type,
+ d [10] IMPLICIT NULL
+ } OPTIONAL} OPTIONAL,
+ backward-limit
+ [1] SEQUENCE {logical-object
+ CHOICE {e [2] IMPLICIT Object-or-Class-Identifier,
+ f [3] Object-Id-Expression,
+ g [4] IMPLICIT NULL},
+ layout-object
+ CHOICE {to-layout-object-class
+ [5] IMPLICIT Object-or-Class-Identifier,
+ to-stream-root-category
+ [6] IMPLICIT Category-Name,
+ to-stream-sub-category
+ [7] IMPLICIT Category-Name,
+ to-layout-category
+ [8] IMPLICIT Category-Name,
+ to-layout-object-type
+ [9] IMPLICIT Layout-Object-Type,
+ h [10] IMPLICIT NULL
+ } OPTIONAL} OPTIONAL
+}
+
+Block-Alignment ::= INTEGER {right-hand(0), left-hand(1), centred(2), null(3)}
+
+END
+
+-- Generated by Asnp, the ASN.1 pretty-printer of France Telecom R&D
+
diff --git a/lib/asn1/test/asn1_SUITE_data/x420/Subprofiles.asn b/lib/asn1/test/asn1_SUITE_data/x420/Subprofiles.asn
new file mode 100644
index 0000000000..bfcd0b5dbc
--- /dev/null
+++ b/lib/asn1/test/asn1_SUITE_data/x420/Subprofiles.asn
@@ -0,0 +1,96 @@
+-- Module Subprofiles (T.422:08/1995)
+
+Subprofiles {2 8 1 12 2} DEFINITIONS IMPLICIT TAGS ::=
+BEGIN
+
+EXPORTS Subprofile-Descriptor, Subprofile-Identifier;
+
+IMPORTS
+ Character-Data, Date-and-Time, Document-Reference, Personal-Name,
+ Originators, Other-User-Information, Local-File-References,
+ Security-Information
+ FROM Document-Profile-Descriptor {2 8 1 5 6}
+ -- see ITU-T Rec. T.415 | ISO/IEC 8613-5
+ Location-Expression
+ FROM Location-Expressions {2 8 1 12 0};
+
+Subprofile-Descriptor ::= SET {
+ subprofile-identifier [0] Subprofile-Identifier,
+ subprofile-reference [1] Subprofile-Reference OPTIONAL,
+ subprofile-precedence [2] INTEGER OPTIONAL,
+ document-fragment-reference [3] Location-Expression,
+ content-architecture-classes
+ [4] SET OF OBJECT IDENTIFIER OPTIONAL, -- shall always
+
+ -- be present, except when used in a location expression
+ document-fragment-management-attributes
+ [5] Document-Fragment-Management-Attributes OPTIONAL
+}
+
+Subprofile-Identifier ::= [APPLICATION 8] PrintableString
+
+-- only digits and spaces are used in the present version of this Specification;
+-- other characters are reserved for extensions
+Subprofile-Reference ::= CHOICE {
+ unique-reference [0] OBJECT IDENTIFIER,
+ descriptive-reference [1] Character-Data
+}
+
+Document-Fragment-Management-Attributes ::= SET {
+ document-fragment-description [0] Document-Fragment-Description OPTIONAL,
+ dates-and-times [1] Dates-and-Times OPTIONAL,
+ originators [2] Originators OPTIONAL,
+ other-user-information [3] Other-User-Information OPTIONAL,
+ external-references [4] External-References2 OPTIONAL,
+ local-file-references [5] Local-File-References OPTIONAL,
+ languages [6] SET OF Character-Data OPTIONAL,
+ security-information [7] Security-Information OPTIONAL
+}
+
+Document-Fragment-Description ::= SET {
+ title [0] Character-Data OPTIONAL,
+ subject [1] Character-Data OPTIONAL,
+ document-fragment-type [2] Character-Data OPTIONAL,
+ abstract [3] Character-Data OPTIONAL,
+ keywords [4] SET OF Character-Data OPTIONAL
+}
+
+Dates-and-Times ::= SET {
+ document-fragment-date-and-time [0] Date-and-Time OPTIONAL,
+ creation-date-and-time [1] Date-and-Time OPTIONAL,
+ local-filing-date-and-time [2] SEQUENCE OF Date-and-Time OPTIONAL,
+ expiry-date-and-time [3] Date-and-Time OPTIONAL,
+ start-date-and-time [4] Date-and-Time OPTIONAL,
+ purge-date-and-time [5] Date-and-Time OPTIONAL,
+ release-date-and-time [6] Date-and-Time OPTIONAL,
+ revision-history
+ [7] SEQUENCE OF
+ SET {revision-date-and-time [0] Date-and-Time OPTIONAL,
+ version-identifier [1] Character-Data OPTIONAL,
+ revisers
+ [2] SET OF
+ SET {names [0] SET OF Personal-Name OPTIONAL,
+ position [1] Character-Data OPTIONAL,
+ organization [2] Character-Data OPTIONAL
+ } OPTIONAL,
+ version-reference
+ [3] Document-or-Document-Fragment-Reference OPTIONAL,
+ user-comments [4] Character-Data OPTIONAL} OPTIONAL
+}
+
+External-References2 ::= SET {
+ references-to-other-documents-or-document-fragments
+ [0] SET OF Document-or-Document-Fragment-Reference OPTIONAL,
+ superseded-documents-or-document-fragments
+ [1] SET OF Document-or-Document-Fragment-Reference OPTIONAL
+}
+
+Document-or-Document-Fragment-Reference ::= CHOICE {
+ document [0] Document-Reference,
+ document-fragment [1] Subprofile-Reference
+}
+
+END
+
+-- Generated by Asnp, the ASN.1 pretty-printer of France Telecom R&D
+
diff --git a/lib/asn1/test/asn1_SUITE_data/x420/Temporal-Relationships.asn b/lib/asn1/test/asn1_SUITE_data/x420/Temporal-Relationships.asn
new file mode 100644
index 0000000000..9633995e3b
--- /dev/null
+++ b/lib/asn1/test/asn1_SUITE_data/x420/Temporal-Relationships.asn
@@ -0,0 +1,92 @@
+-- Module Temporal-Relationships (T.424:07/1996)
+
+Temporal-Relationships {2 8 1 14 0} DEFINITIONS ::=
+BEGIN
+
+EXPORTS
+ Temporal-Relations, Presentation-Time, Document-Presentation-Time,
+ Time-Scaling;
+
+IMPORTS
+ Date-and-Time
+ FROM Document-Profile-Descriptor {2 8 1 5 6}
+ -- see ITU-T Rec. T.415 | ISO/IEC 8613-5 and C.4
+ Object-or-Class-Identifier
+ FROM Identifiers-and-Expressions {2 8 1 5 7};
+
+-- see ITU-T Rec. T.415 | ISO/IEC 8613-5
+Temporal-Relations ::= SET {
+ synchronization-type [0] IMPLICIT Synchronization-Type,
+ subordinate-nodes
+ [1] SEQUENCE OF
+ SET {node-identifier [0] IMPLICIT Node-Identifier,
+ start-time [1] IMPLICIT Time-Delay OPTIONAL,
+ duration [2] Indefinite-or-Time-Delay OPTIONAL,
+ cyclic [3] IMPLICIT Cyclic OPTIONAL,
+ end-time [4] IMPLICIT Time-Delay OPTIONAL,
+ application-comments [5] IMPLICIT OCTET STRING OPTIONAL
+ }
+}
+
+-- The value 'null' is represented by an empty set
+Synchronization-Type ::= INTEGER {
+ parallel-last(0), parallel-first(1), parallel-selective(2), sequential(3)
+}
+
+Node-Identifier ::= PrintableString
+
+-- only digits and spaces are used
+-- the first digit is either 2 for a logical object class or 3 for a logical object
+Cyclic ::= SET {
+ number-of-cycles [0] CHOICE {indefinite Indefinite,
+ a INTEGER},
+ cycle-start-time [1] IMPLICIT Time-Delay OPTIONAL,
+ cycle-duration [2] Indefinite-or-Time-Delay OPTIONAL
+}
+
+Indefinite ::= NULL
+
+Time-Delay ::= INTEGER {indefinite(-1)}
+
+Presentation-Time ::= SET {
+ timing
+ CHOICE {fixed-timing [0] IMPLICIT INTEGER,
+ variable-timing [1] IMPLICIT Time-Spec} OPTIONAL,
+ duration
+ CHOICE {fixed-duration
+ [2] CHOICE {indefinite-or-time-delay Indefinite-or-Time-Delay,
+ object-or-class-identifier
+ Object-or-Class-Identifier},
+ rule-A [3] IMPLICIT Rule-Spec,
+ rule-B [4] IMPLICIT Rule-Spec} OPTIONAL,
+ cyclic [5] Cyclic OPTIONAL
+}
+
+-- The value 'null' is represented by an empty set
+Time-Spec ::= SET {
+ start-offset [0] IMPLICIT INTEGER OPTIONAL,
+ end-offset [1] IMPLICIT INTEGER OPTIONAL,
+ start-separation [2] IMPLICIT INTEGER OPTIONAL,
+ end-separation [3] IMPLICIT INTEGER OPTIONAL
+}
+
+Rule-Spec ::= SET {
+ minimum-duration [0] IMPLICIT INTEGER OPTIONAL,
+ maximum-duration [1] IMPLICIT INTEGER OPTIONAL
+}
+
+Indefinite-or-Time-Delay ::= CHOICE {
+ indefinite [0] IMPLICIT NULL,
+ fixed [1] Time-Delay
+}
+
+Document-Presentation-Time ::= Date-and-Time
+
+Time-Scaling ::= [0] IMPLICIT SEQUENCE {a INTEGER,
+ b INTEGER
+}
+
+END
+
+-- Generated by Asnp, the ASN.1 pretty-printer of France Telecom R&D
+
diff --git a/lib/asn1/test/asn1_SUITE_data/x420/Text-Units.asn b/lib/asn1/test/asn1_SUITE_data/x420/Text-Units.asn
new file mode 100644
index 0000000000..ccc64a52f5
--- /dev/null
+++ b/lib/asn1/test/asn1_SUITE_data/x420/Text-Units.asn
@@ -0,0 +1,72 @@
+-- Module Text-Units (T.415:03/1993)
+
+Text-Units {2 8 1 5 12} DEFINITIONS ::=
+BEGIN
+
+EXPORTS Text-Unit, Type-Of-Coding;
+
+IMPORTS
+ Content-Portion-Identifier
+ FROM Identifiers-and-Expressions -- see 7.8
+
+ Character-Coding-Attributes
+ FROM Character-Coding-Attributes {2 8 1 6 3
+ } -- see ITU-T Rec. T.416 | ISO/IEC 8613-6
+ Raster-Gr-Coding-Attributes
+ FROM Raster-Gr-Coding-Attributes {2 8 1 7 3
+ } -- see ITU-T Rec. T.417 | ISO/IEC 8613-7
+ Geo-Gr-Coding-Attributes
+ FROM Geo-Gr-Coding-Attributes {2 8 1 8 3
+ } -- see ITU-T Rec. T.418 | ISO/IEC 8613-8
+ Videotex-Coding-Attributes
+ FROM Videotex-Coding-Attributes ;
+
+Text-Unit ::= SEQUENCE {
+ content-portion-attributes Content-Portion-Attributes OPTIONAL,
+ content-information Content-Information OPTIONAL
+}
+
+Content-Portion-Attributes ::= SET {
+ content-identifier-layout Content-Portion-Identifier OPTIONAL,
+ content-identifier-logical [4] IMPLICIT Content-Portion-Identifier OPTIONAL,
+ type-of-coding Type-Of-Coding OPTIONAL,
+ coding-attributes
+ CHOICE {character-coding-attributes
+ [1] IMPLICIT Character-Coding-Attributes,
+ raster-gr-coding-attributes
+ [2] IMPLICIT Raster-Gr-Coding-Attributes,
+ geo-gr-coding-attributes
+ [7] IMPLICIT Geo-Gr-Coding-Attributes,
+ videotex-coding-attributes
+ [8] IMPLICIT Videotex-Coding-Attributes,
+ -- the use of the data item "videotex-coding-attributes" is applicable to
+ -- ITU-T Rec. T.410 Series only
+ -- the following tags are reserved for additional types
+ -- of coding attributes:
+ -- [9] audio
+ -- [10] dynamic-graphics
+ ext-cont-arch-coding-attributes [11] IMPLICIT EXTERNAL} OPTIONAL,
+ alternative-representation [3] IMPLICIT Alternative-Representation OPTIONAL
+}
+
+Content-Information ::= CHOICE {
+ content OCTET STRING,
+ tiled-content Tiled-Content
+}
+
+Tiled-Content ::= SEQUENCE OF OCTET STRING
+
+Type-Of-Coding ::= CHOICE {
+ a [0] IMPLICIT INTEGER {t6(1)},
+ b [6] IMPLICIT OBJECT IDENTIFIER
+}
+
+Alternative-Representation ::= OCTET STRING
+
+-- string of characters from the sets designated by the document
+-- profile attribute "alternative representation character sets",
+-- plus carriage return and line feed
+END
+
+-- Generated by Asnp, the ASN.1 pretty-printer of France Telecom R&D
+
diff --git a/lib/asn1/test/asn1_SUITE_data/x420/UpperBounds.asn b/lib/asn1/test/asn1_SUITE_data/x420/UpperBounds.asn
new file mode 100644
index 0000000000..c97c83a569
--- /dev/null
+++ b/lib/asn1/test/asn1_SUITE_data/x420/UpperBounds.asn
@@ -0,0 +1,89 @@
+-- Module UpperBounds (X.520:08/1997)
+
+UpperBounds {joint-iso-itu-t ds(5) module(1) upperBounds(10) 3} DEFINITIONS ::=
+BEGIN
+
+-- EXPORTS All
+-- The types and values defined in this module are exported for use in the other ASN.1 modules contained
+-- within the Directory Specifications, and for the use of other applications which will use them to access
+-- Directory services. Other applications may use them for their own purposes, but this will not constrain
+-- extensions and modifications needed to maintain or improve the Directory service.
+ub-answerback INTEGER ::=
+8
+
+ub-business-category INTEGER ::= 128
+
+ub-common-name INTEGER ::= 64
+
+ub-country-code INTEGER ::= 4
+
+ub-description INTEGER ::= 1024
+
+ub-destination-indicator INTEGER ::= 128
+
+ub-directory-string-first-component-match INTEGER ::= 32768
+
+ub-international-isdn-number INTEGER ::= 16
+
+ub-knowledge-information INTEGER ::= 32768
+
+ub-locality-name INTEGER ::= 128
+
+ub-match INTEGER ::= 128
+
+ub-name INTEGER ::= 64
+
+ub-organization-name INTEGER ::= 64
+
+ub-organizational-unit-name INTEGER ::= 64
+
+ub-physical-office-name INTEGER ::= 128
+
+ub-post-office-box INTEGER ::= 40
+
+ub-postal-code INTEGER ::= 40
+
+ub-postal-line INTEGER ::= 6
+
+ub-postal-string INTEGER ::= 30
+
+ub-privacy-mark-length INTEGER ::= 128
+
+ub-schema INTEGER ::= 1024
+
+ub-search INTEGER ::= 17 --This definition is missing; to be provided --
+
+ub-serial-number INTEGER ::= 64
+
+ub-state-name INTEGER ::= 128
+
+ub-street-address INTEGER ::= 128
+
+ub-surname INTEGER ::= 64
+
+ub-tag INTEGER ::= 64
+
+ub-telephone-number INTEGER ::= 32
+
+ub-teletex-terminal-id INTEGER ::= 1024
+
+ub-telex-number INTEGER ::= 14
+
+ub-title INTEGER ::= 64
+
+ub-user-password INTEGER ::= 128
+
+ub-x121-address INTEGER ::= 15
+
+ub-localeContextSyntax INTEGER ::= 128
+
+ub-locale-context-syntax INTEGER ::= 64
+
+ub-pseudonym INTEGER ::= 128
+
+ub-content INTEGER ::= 32768
+
+END -- UpperBounds
+
+-- Generated by Asnp, the ASN.1 pretty-printer of France Telecom R&D
+
diff --git a/lib/asn1/test/asn1_SUITE_data/x420/UsefulDefinitions.asn b/lib/asn1/test/asn1_SUITE_data/x420/UsefulDefinitions.asn
new file mode 100644
index 0000000000..d9601bb7d0
--- /dev/null
+++ b/lib/asn1/test/asn1_SUITE_data/x420/UsefulDefinitions.asn
@@ -0,0 +1,238 @@
+-- Module UsefulDefinitions (X.501:08/1997)
+UsefulDefinitions {joint-iso-itu-t ds(5) module(1) usefulDefinitions(0) 3}
+DEFINITIONS ::=
+BEGIN
+
+-- EXPORTS All -
+-- The types and values defined in this module are exported for use in the other ASN.1 modules contained
+-- within the Directory Specifications, and for the use of other applications which will use them to access
+-- Directory services. Other applications may use them for their own purposes, but this will not constrain
+-- extensions and modifications needed to maintain or improve the Directory service.
+ID ::= OBJECT IDENTIFIER
+
+ds ID ::= {joint-iso-itu-t ds(5)}
+
+-- categories of information object
+module ID ::= {ds 1}
+
+serviceElement ID ::= {ds 2}
+
+applicationContext ID ::= {ds 3}
+
+attributeType ID ::= {ds 4}
+
+attributeSyntax ID ::= {ds 5}
+
+objectClass ID ::= {ds 6}
+
+-- attributeSet ID ::= {ds 7}
+algorithm ID ::= {ds 8}
+
+abstractSyntax ID ::= {ds 9}
+
+-- object ID ::= {ds 10}
+-- port ID ::= {ds 11}
+dsaOperationalAttribute ID ::=
+ {ds 12}
+
+matchingRule ID ::= {ds 13}
+
+knowledgeMatchingRule ID ::= {ds 14}
+
+nameForm ID ::= {ds 15}
+
+group ID ::= {ds 16}
+
+subentry ID ::= {ds 17}
+
+operationalAttributeType ID ::= {ds 18}
+
+operationalBinding ID ::= {ds 19}
+
+schemaObjectClass ID ::= {ds 20}
+
+schemaOperationalAttribute ID ::= {ds 21}
+
+administrativeRoles ID ::= {ds 23}
+
+accessControlAttribute ID ::= {ds 24}
+
+rosObject ID ::= {ds 25}
+
+contract ID ::= {ds 26}
+
+package ID ::= {ds 27}
+
+accessControlSchemes ID ::= {ds 28}
+
+certificateExtension ID ::= {ds 29}
+
+managementObject ID ::= {ds 30}
+
+attributeValueContext ID ::= {ds 31}
+
+-- securityExchange ID ::= {ds 32}
+idmProtocol ID ::= {ds 33}
+
+problem ID ::= {ds 34}
+
+notification ID ::= {ds 35}
+
+matchingRestriction ID ::=
+ {ds 36} -- None are currently defined by this specification
+
+controlAttributeType ID ::= {ds 37}
+
+-- modules
+usefulDefinitions ID ::= {module usefulDefinitions(0) 3}
+
+informationFramework ID ::= {module informationFramework(1) 3}
+
+directoryAbstractService ID ::= {module directoryAbstractService(2) 3}
+
+distributedOperations ID ::= {module distributedOperations(3) 3}
+
+protocolObjectIdentifiers ID ::= {module protocolObjectIdentifiers(4) 3}
+
+selectedAttributeTypes ID ::= {module selectedAttributeTypes(5) 3}
+
+selectedObjectClasses ID ::= {module selectedObjectClasses(6) 3}
+
+authenticationFramework ID ::= {module authenticationFramework(7) 3}
+
+algorithmObjectIdentifiers ID ::= {module algorithmObjectIdentifiers(8) 3}
+
+directoryObjectIdentifiers ID ::= {module directoryObjectIdentifiers(9) 3}
+
+upperBounds ID ::= {module upperBounds(10) 3}
+
+dap ID ::= {module dap(11) 3}
+
+dsp ID ::= {module dsp(12) 3}
+
+distributedDirectoryOIDs ID ::= {module distributedDirectoryOIDs(13) 3}
+
+directoryShadowOIDs ID ::= {module directoryShadowOIDs(14) 3}
+
+directoryShadowAbstractService ID ::=
+ {module directoryShadowAbstractService(15) 3}
+
+disp ID ::= {module disp(16) 3}
+
+dop ID ::= {module dop(17) 3}
+
+opBindingManagement ID ::= {module opBindingManagement(18) 3}
+
+opBindingOIDs ID ::= {module opBindingOIDs(19) 3}
+
+hierarchicalOperationalBindings ID ::=
+ {module hierarchicalOperationalBindings(20) 3}
+
+dsaOperationalAttributeTypes ID ::= {module dsaOperationalAttributeTypes(22) 3}
+
+schemaAdministration ID ::= {module schemaAdministration(23) 3}
+
+basicAccessControl ID ::= {module basicAccessControl(24) 3}
+
+directoryOperationalBindingTypes ID ::=
+ {module directoryOperationalBindingTypes(25) 3}
+
+certificateExtensions ID ::= {module certificateExtensions(26) 0}
+
+directoryManagement ID ::= {module directoryManagement(27) 1}
+
+enhancedSecurity ID ::= {module enhancedSecurity(28) 1}
+
+iDMProtocolSpecification ID ::= {module iDMProtocolSpecification(30) 4}
+
+directoryIDMProtocols ID ::= {module directoryIDMProtocols(31) 4}
+
+-- directorySecurityExchanges ID ::= {module directorySecurityExchanges (29) 1}
+-- synonyms
+id-oc ID ::=
+ objectClass
+
+id-at ID ::= attributeType
+
+id-as ID ::= abstractSyntax
+
+id-mr ID ::= matchingRule
+
+id-nf ID ::= nameForm
+
+id-sc ID ::= subentry
+
+id-oa ID ::= operationalAttributeType
+
+id-ob ID ::= operationalBinding
+
+id-doa ID ::= dsaOperationalAttribute
+
+id-kmr ID ::= knowledgeMatchingRule
+
+id-soc ID ::= schemaObjectClass
+
+id-soa ID ::= schemaOperationalAttribute
+
+id-ar ID ::= administrativeRoles
+
+id-aca ID ::= accessControlAttribute
+
+id-ac ID ::= applicationContext
+
+id-rosObject ID ::= rosObject
+
+id-contract ID ::= contract
+
+id-package ID ::= package
+
+id-acScheme ID ::= accessControlSchemes
+
+id-ce ID ::= certificateExtension
+
+id-mgt ID ::= managementObject
+
+id-idm ID ::= idmProtocol
+
+id-avc ID ::= attributeValueContext
+
+-- id-se ID ::= securityExchange
+id-pr ID ::= problem
+
+id-not ID ::= notification
+
+id-mre ID ::= matchingRestriction
+
+id-cat ID ::= controlAttributeType
+
+-- obsolete module identifiers
+-- usefulDefinition ID ::= {module 0}
+-- informationFramework ID ::= {module 1}
+-- directoryAbstractService ID ::= {module 2}
+-- distributedOperations ID ::= {module 3}
+-- protocolObjectIdentifiers ID ::= {module 4}
+-- selectedAttributeTypes ID ::= {module 5}
+-- selectedObjectClasses ID ::= {module 6}
+-- authenticationFramework ID ::= {module 7}
+-- algorithmObjectIdentifiers ID ::= {module 8}
+-- directoryObjectIdentifiers ID ::= {module 9}
+-- upperBounds ID ::= {module 10}
+-- dap ID ::= {module 11}
+-- dsp ID ::= {module 12}
+-- distributedDirectoryObjectIdentifiers ID ::= {module 13}
+-- unused module identifiers
+-- directoryShadowOIDs ID ::= {module 14}
+-- directoryShadowAbstractService ID ::= {module 15}
+-- disp ID ::= {module 16}
+-- dop ID ::= {module 17}
+-- opBindingManagement ID ::= {module 18}
+-- opBindingOIDs ID ::= {module 19}
+-- hierarchicalOperationalBindings ID ::= {module 20}
+-- dsaOperationalAttributeTypes ID ::= {module 22}
+-- schemaAdministration ID ::= {module 23}
+-- basicAccessControl ID ::= {module 24}
+-- operationalBindingOIDs ID ::= {module 25}
+END -- UsefulDefinitions
+
+-- Generated by Asnp, the ASN.1 pretty-printer of France Telecom R&D
+
diff --git a/lib/asn1/test/asn1_SUITE_data/x420/Videotex-Coding-Attributes.asn b/lib/asn1/test/asn1_SUITE_data/x420/Videotex-Coding-Attributes.asn
new file mode 100644
index 0000000000..18e51cbc0d
--- /dev/null
+++ b/lib/asn1/test/asn1_SUITE_data/x420/Videotex-Coding-Attributes.asn
@@ -0,0 +1,30 @@
+-- Module Videotex-Coding-Attributes (T.101:11/1994)
+Videotex-Coding-Attributes DEFINITIONS ::=
+BEGIN
+
+EXPORTS Videotex-Coding-Attributes;
+
+Videotex-Coding-Attributes ::= SET {
+ subset [0] IMPLICIT Subset OPTIONAL,
+ rank [1] IMPLICIT Rank OPTIONAL,
+ profile [2] IMPLICIT Profile OPTIONAL
+}
+
+Subset ::= INTEGER {
+ undefined(0), rank1(1), rank2(2), rank3(3), rank4(4), rank5(5), profile1(81),
+ profile2(82), profile3(83), profile4(84), profileX1-1(85), profileX1-2(86),
+ profileX1-3(87), profileX1-4(88), profileX2-1(89), profileX2-2(90),
+ profileX2-3(91), profileX2-4(92)}
+
+Rank ::= INTEGER {
+ undefined(0), rank1(1), rank2(2), rank3(3), rank4(4), rank5(5)}
+
+Profile ::= INTEGER {
+ undefined(0), profile1(81), profile2(82), profile3(83), profile4(84),
+ profileX1-1(85), profileX1-2(86), profileX1-3(87), profileX1-4(88),
+ profileX2-1(89), profileX2-2(90), profileX2-3(91), profileX2-4(92)}
+
+END
+
+-- Generated by Asnp, the ASN.1 pretty-printer of France Telecom R&D
+
diff --git a/lib/asn1/test/asn1_app_test.erl b/lib/asn1/test/asn1_app_test.erl
new file mode 100644
index 0000000000..1ea76426f1
--- /dev/null
+++ b/lib/asn1/test/asn1_app_test.erl
@@ -0,0 +1,253 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 2005-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%
+%%
+%%
+%%----------------------------------------------------------------------
+%% Purpose: Verify the application specifics of the Megaco application
+%%----------------------------------------------------------------------
+-module(asn1_app_test).
+
+-compile(export_all).
+
+%-include("megaco_test_lib.hrl").
+
+
+% t() -> megaco_test_lib:t(?MODULE).
+% t(Case) -> megaco_test_lib:t({?MODULE, Case}).
+
+
+% %% Test server callbacks
+% init_per_testcase(Case, Config) ->
+% megaco_test_lib:init_per_testcase(Case, Config).
+
+% fin_per_testcase(Case, Config) ->
+% megaco_test_lib:fin_per_testcase(Case, Config).
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+all(suite) ->
+ Cases =
+ [
+ fields,
+ modules,
+ exportall,
+ app_depend
+ ],
+ {req, [], {conf, app_init, Cases, app_fin}}.
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+app_init(suite) -> [];
+app_init(doc) -> [];
+app_init(Config) when is_list(Config) ->
+ case is_app(asn1) of
+ {ok, AppFile} ->
+ io:format("AppFile: ~n~p~n", [AppFile]),
+ [{app_file, AppFile}|Config];
+ {error, Reason} ->
+ fail(Reason)
+ end.
+
+is_app(App) ->
+ LibDir = code:lib_dir(App),
+ File = filename:join([LibDir, "ebin", atom_to_list(App) ++ ".app"]),
+ case file:consult(File) of
+ {ok, [{application, App, AppFile}]} ->
+ {ok, AppFile};
+ Error ->
+ {error, {invalid_format, Error}}
+ end.
+
+
+app_fin(suite) -> [];
+app_fin(doc) -> [];
+app_fin(Config) when is_list(Config) ->
+ Config.
+
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+fields(suite) ->
+ [];
+fields(doc) ->
+ [];
+fields(Config) when is_list(Config) ->
+ AppFile = key1search(app_file, Config),
+ Fields = [vsn, description, modules, registered, applications],
+ case check_fields(Fields, AppFile, []) of
+ [] ->
+ ok;
+ Missing ->
+ fail({missing_fields, Missing})
+ end.
+
+check_fields([], _AppFile, Missing) ->
+ Missing;
+check_fields([Field|Fields], AppFile, Missing) ->
+ check_fields(Fields, AppFile, check_field(Field, AppFile, Missing)).
+
+check_field(Name, AppFile, Missing) ->
+ io:format("checking field: ~p~n", [Name]),
+ case lists:keymember(Name, 1, AppFile) of
+ true ->
+ Missing;
+ false ->
+ [Name|Missing]
+ end.
+
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+modules(suite) ->
+ [];
+modules(doc) ->
+ [];
+modules(Config) when is_list(Config) ->
+ AppFile = key1search(app_file, Config),
+ Mods = key1search(modules, AppFile),
+ EbinList = get_ebin_mods(asn1),
+ case missing_modules(Mods, EbinList, []) of
+ [] ->
+ ok;
+ Missing ->
+ throw({error, {missing_modules, Missing}})
+ end,
+ case extra_modules(Mods, EbinList, []) of
+ [] ->
+ ok;
+ Extra ->
+ check_asn1ct_modules(Extra)
+% throw({error, {extra_modules, Extra}})
+ end,
+ {ok, Mods}.
+
+get_ebin_mods(App) ->
+ LibDir = code:lib_dir(App),
+ EbinDir = filename:join([LibDir,"ebin"]),
+ {ok, Files0} = file:list_dir(EbinDir),
+ Files1 = [lists:reverse(File) || File <- Files0],
+ [list_to_atom(lists:reverse(Name)) || [$m,$a,$e,$b,$.|Name] <- Files1].
+
+check_asn1ct_modules(Extra) ->
+ ASN1CTMods = [asn1ct,asn1ct_check,asn1_db,asn1ct_pretty_format,
+ asn1ct_gen,asn1ct_gen_per,asn1ct_gen_per_rt2ct,
+ asn1ct_name,asn1ct_constructed_per,asn1ct_constructed_ber,
+ asn1ct_gen_ber,asn1ct_constructed_ber_bin_v2,
+ asn1ct_gen_ber_bin_v2,asn1ct_value,
+ asn1ct_tok,asn1ct_parser2],
+ case Extra -- ASN1CTMods of
+ [] ->
+ ok;
+ Extra2 ->
+ throw({error, {extra_modules, Extra2}})
+ end.
+
+missing_modules([], _Ebins, Missing) ->
+ Missing;
+missing_modules([Mod|Mods], Ebins, Missing) ->
+ case lists:member(Mod, Ebins) of
+ true ->
+ missing_modules(Mods, Ebins, Missing);
+ false ->
+ io:format("missing module: ~p~n", [Mod]),
+ missing_modules(Mods, Ebins, [Mod|Missing])
+ end.
+
+
+extra_modules(_Mods, [], Extra) ->
+ Extra;
+extra_modules(Mods, [Mod|Ebins], Extra) ->
+ case lists:member(Mod, Mods) of
+ true ->
+ extra_modules(Mods, Ebins, Extra);
+ false ->
+ io:format("supefluous module: ~p~n", [Mod]),
+ extra_modules(Mods, Ebins, [Mod|Extra])
+ end.
+
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+
+exportall(suite) ->
+ [];
+exportall(doc) ->
+ [];
+exportall(Config) when is_list(Config) ->
+ AppFile = key1search(app_file, Config),
+ Mods = key1search(modules, AppFile),
+ check_export_all(Mods).
+
+
+check_export_all([]) ->
+ ok;
+check_export_all([Mod|Mods]) ->
+ case (catch apply(Mod, module_info, [compile])) of
+ {'EXIT', {undef, _}} ->
+ check_export_all(Mods);
+ O ->
+ case lists:keysearch(options, 1, O) of
+ false ->
+ check_export_all(Mods);
+ {value, {options, List}} ->
+ case lists:member(export_all, List) of
+ true ->
+ throw({error, {export_all, Mod}});
+ false ->
+ check_export_all(Mods)
+ end
+ end
+ end.
+
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+app_depend(suite) ->
+ [];
+app_depend(doc) ->
+ [];
+app_depend(Config) when is_list(Config) ->
+ AppFile = key1search(app_file, Config),
+ Apps = key1search(applications, AppFile),
+ check_apps(Apps).
+
+
+check_apps([]) ->
+ ok;
+check_apps([App|Apps]) ->
+ case is_app(App) of
+ {ok, _} ->
+ check_apps(Apps);
+ Error ->
+ throw({error, {missing_app, {App, Error}}})
+ end.
+
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+
+fail(Reason) ->
+ exit({suite_failed, Reason}).
+
+key1search(Key, L) ->
+ case lists:keysearch(Key, 1, L) of
+ undefined ->
+ fail({not_found, Key, L});
+ {value, {Key, Value}} ->
+ Value
+ end.
diff --git a/lib/asn1/test/asn1_appup_test.erl b/lib/asn1/test/asn1_appup_test.erl
new file mode 100644
index 0000000000..96197ed963
--- /dev/null
+++ b/lib/asn1/test/asn1_appup_test.erl
@@ -0,0 +1,418 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 2005-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%
+%%
+%%
+%%----------------------------------------------------------------------
+%% Purpose: Verify the application specifics of the Megaco application
+%%----------------------------------------------------------------------
+-module(asn1_appup_test).
+
+-compile(export_all).
+
+%-include("megaco_test_lib.hrl").
+
+
+%t() -> megaco_test_lib:t(?MODULE).
+%t(Case) -> megaco_test_lib:t({?MODULE, Case}).
+
+
+%% Test server callbacks
+% init_per_testcase(Case, Config) ->
+% megaco_test_lib:init_per_testcase(Case, Config).
+
+% fin_per_testcase(Case, Config) ->
+% megaco_test_lib:fin_per_testcase(Case, Config).
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+all(suite) ->
+ Cases =
+ [
+ appup
+ ],
+ {req, [], {conf, appup_init, Cases, appup_fin}}.
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+appup_init(suite) -> [];
+appup_init(doc) -> [];
+appup_init(Config) when is_list(Config) ->
+ AppFile = file_name(asn1, ".app"),
+ AppupFile = file_name(asn1, ".appup"),
+ [{app_file, AppFile}, {appup_file, AppupFile}|Config].
+
+
+file_name(App, Ext) ->
+ LibDir = code:lib_dir(App),
+ filename:join([LibDir, "ebin", atom_to_list(App) ++ Ext]).
+
+
+appup_fin(suite) -> [];
+appup_fin(doc) -> [];
+appup_fin(Config) when is_list(Config) ->
+ Config.
+
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+appup(suite) ->
+ [];
+appup(doc) ->
+ "perform a simple check of the appup file";
+appup(Config) when is_list(Config) ->
+ AppupFile = key1search(appup_file, Config),
+ AppFile = key1search(app_file, Config),
+ Modules = modules(AppFile),
+ check_appup(AppupFile, Modules).
+
+modules(File) ->
+ case file:consult(File) of
+ {ok, [{application,asn1,Info}]} ->
+ case lists:keysearch(modules,1,Info) of
+ {value, {modules, Modules}} ->
+ Modules;
+ false ->
+ fail({bad_appinfo, Info})
+ end;
+ Error ->
+ fail({bad_appfile, Error})
+ end.
+
+
+check_appup(AppupFile, Modules) ->
+ case file:consult(AppupFile) of
+ {ok, [{V, UpFrom, DownTo}]} ->
+ io:format("V= ~p, UpFrom= ~p, DownTo= ~p, Modules= ~p~n",
+ [V, UpFrom, DownTo, Modules]),
+ check_appup(V, UpFrom, DownTo, Modules);
+ Else ->
+ fail({bad_appupfile, Else})
+ end.
+
+
+check_appup(V, UpFrom, DownTo, Modules) ->
+ check_version(V),
+ check_depends(up, UpFrom, Modules),
+ check_depends(down, DownTo, Modules),
+ ok.
+
+
+check_depends(_, [], _) ->
+ ok;
+check_depends(UpDown, [Dep|Deps], Modules) ->
+ check_depend(UpDown, Dep, Modules),
+ check_depends(UpDown, Deps, Modules).
+
+
+check_depend(up,I={add_application,_App},Modules) ->
+ d("check_instructions(~w) -> entry with"
+ "~n Instruction: ~p"
+ "~n Modules: ~p", [up,I , Modules]),
+ ok;
+check_depend(down,I={remove_application,_App},Modules) ->
+ d("check_instructions(~w) -> entry with"
+ "~n Instruction: ~p"
+ "~n Modules: ~p", [down,I , Modules]),
+ ok;
+check_depend(UpDown, {V, Instructions}, Modules) ->
+ d("check_instructions(~w) -> entry with"
+ "~n V: ~p"
+ "~n Modules: ~p", [UpDown, V, Modules]),
+ check_version(V),
+ case check_instructions(UpDown,
+ Instructions, Instructions, [], [], Modules) of
+ {_Good, []} ->
+ ok;
+ {_, Bad} ->
+ fail({bad_instructions, Bad, UpDown})
+ end.
+
+
+check_instructions(_, [], _, Good, Bad, _) ->
+ {lists:reverse(Good), lists:reverse(Bad)};
+check_instructions(UpDown, [Instr|Instrs], AllInstr, Good, Bad, Modules) ->
+ d("check_instructions(~w) -> entry with"
+ "~n Instr: ~p", [UpDown,Instr]),
+ case (catch check_instruction(UpDown, Instr, AllInstr, Modules)) of
+ ok ->
+ check_instructions(UpDown, Instrs, AllInstr,
+ [Instr|Good], Bad, Modules);
+ {error, Reason} ->
+ d("check_instructions(~w) -> bad instruction: "
+ "~n Reason: ~p", [UpDown,Reason]),
+ check_instructions(UpDown, Instrs, AllInstr, Good,
+ [{Instr, Reason}|Bad], Modules)
+ end.
+
+%% A new module is added
+check_instruction(up, {add_module, Module}, _, Modules)
+ when is_atom(Module) ->
+ d("check_instruction -> entry when up-add_module instruction with"
+ "~n Module: ~p", [Module]),
+ check_module(Module, Modules);
+
+%% An old module is re-added
+check_instruction(down, {add_module, Module}, _, Modules)
+ when is_atom(Module) ->
+ d("check_instruction -> entry when down-add_module instruction with"
+ "~n Module: ~p", [Module]),
+ case (catch check_module(Module, Modules)) of
+ {error, {unknown_module, Module, Modules}} ->
+ ok;
+ ok ->
+ error({existing_readded_module, Module})
+ end;
+
+%% Removing a module on upgrade:
+%% - the module has been removed from the app-file.
+%% - check that no module depends on this (removed) module
+check_instruction(up, {remove, {Module, Pre, Post}}, _, Modules)
+ when is_atom(Module), is_atom(Pre), is_atom(Post) ->
+ d("check_instruction -> entry when up-remove instruction with"
+ "~n Module: ~p"
+ "~n Pre: ~p"
+ "~n Post: ~p", [Module, Pre, Post]),
+ case (catch check_module(Module, Modules)) of
+ {error, {unknown_module, Module, Modules}} ->
+ check_purge(Pre),
+ check_purge(Post);
+ ok ->
+ error({existing_removed_module, Module})
+ end;
+
+%% Removing a module on downgrade: the module exist
+%% in the app-file.
+check_instruction(down, {remove, {Module, Pre, Post}}, AllInstr, Modules)
+ when is_atom(Module), is_atom(Pre), is_atom(Post) ->
+ d("check_instruction -> entry when down-remove instruction with"
+ "~n Module: ~p"
+ "~n Pre: ~p"
+ "~n Post: ~p", [Module, Pre, Post]),
+ case (catch check_module(Module, Modules)) of
+ ok ->
+ check_purge(Pre),
+ check_purge(Post),
+ check_no_remove_depends(Module, AllInstr);
+ {error, {unknown_module, Module, Modules}} ->
+ error({nonexisting_removed_module, Module})
+ end;
+
+check_instruction(_, {load_module, Module, Pre, Post, Depend},
+ AllInstr, Modules)
+ when is_atom(Module), is_atom(Pre), is_atom(Post), is_list(Depend) ->
+ d("check_instruction -> entry when load_module instruction with"
+ "~n Module: ~p"
+ "~n Pre: ~p"
+ "~n Post: ~p"
+ "~n Depend: ~p", [Module, Pre, Post, Depend]),
+ check_module(Module, Modules),
+ check_module_depend(Module, Depend, Modules),
+ check_module_depend(Module, Depend, updated_modules(AllInstr, [])),
+ check_purge(Pre),
+ check_purge(Post);
+
+check_instruction(_, {update, Module, Change, Pre, Post, Depend},
+ AllInstr, Modules)
+ when is_atom(Module), is_atom(Pre), is_atom(Post), is_list(Depend) ->
+ d("check_instruction -> entry when update instruction with"
+ "~n Module: ~p"
+ "~n Change: ~p"
+ "~n Pre: ~p"
+ "~n Post: ~p"
+ "~n Depend: ~p", [Module, Change, Pre, Post, Depend]),
+ check_module(Module, Modules),
+ check_module_depend(Module, Depend, Modules),
+ check_module_depend(Module, Depend, updated_modules(AllInstr, [])),
+ check_change(Change),
+ check_purge(Pre),
+ check_purge(Post);
+
+check_instruction(_, {apply, {Module, Function, Args}},
+ _AllInstr, Modules)
+ when is_atom(Module), is_atom(Function), is_list(Args) ->
+ d("check_instruction -> entry when apply instruction with"
+ "~n Module: ~p"
+ "~n Function: ~p"
+ "~n Args: ~p", [Module, Function, Args]),
+ check_module(Module, Modules),
+ check_apply(Module,Function,Args);
+
+check_instruction(_, Instr, _AllInstr, _Modules) ->
+ d("check_instruction -> entry when unknown instruction with"
+ "~n Instr: ~p", [Instr]),
+ error({error, {unknown_instruction, Instr}}).
+
+
+%% If Module X depends on Module Y, then module Y must have an update
+%% instruction of some sort (otherwise the depend is faulty).
+updated_modules([], Modules) ->
+ d("update_modules -> entry when done with"
+ "~n Modules: ~p", [Modules]),
+ Modules;
+updated_modules([Instr|Instrs], Modules) ->
+ d("update_modules -> entry with"
+ "~n Instr: ~p"
+ "~n Modules: ~p", [Instr,Modules]),
+ Module = instruction_module(Instr),
+ d("update_modules -> Module: ~p", [Module]),
+ updated_modules(Instrs, [Module|Modules]).
+
+instruction_module({add_module, Module}) ->
+ Module;
+instruction_module({remove, {Module, _, _}}) ->
+ Module;
+instruction_module({load_module, Module, _, _, _}) ->
+ Module;
+instruction_module({update, Module, _, _, _, _}) ->
+ Module;
+instruction_module({apply, {Module, _, _}}) ->
+ Module;
+instruction_module(Instr) ->
+ d("instruction_module -> entry when unknown instruction with"
+ "~n Instr: ~p", [Instr]),
+ error({error, {unknown_instruction, Instr}}).
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+check_version(V) when is_list(V) ->
+ ok;
+check_version(V) ->
+ error({bad_version, V}).
+
+
+check_module(M, Modules) when is_atom(M) ->
+ case lists:member(M,Modules) of
+ true ->
+ ok;
+ false ->
+ error({unknown_module, M, Modules})
+ end;
+check_module(M, _) ->
+ error({bad_module, M}).
+
+check_apply(Module,Function,Args) ->
+ case (catch Module:module_info()) of
+ Info when is_list(Info) ->
+ check_exported(Function,Args,Info);
+ {'EXIT',{undef,_}} ->
+ error({not_existing_module,Module})
+ end.
+
+check_exported(Function,Args,Info) ->
+ case lists:keysearch(exports,1,Info) of
+ {value,{exports,FunList}} ->
+ case lists:keysearch(Function,1,FunList) of
+ {value,{_,Arity}} when Arity==length(Args) ->
+ ok;
+ _ ->
+ error({not_exported_function,Function,length(Args)})
+ end;
+ _ ->
+ error({bad_export,Info})
+ end.
+
+check_module_depend(M, [], _) when is_atom(M) ->
+ d("check_module_depend -> entry with"
+ "~n M: ~p", [M]),
+ ok;
+check_module_depend(M, Deps, Modules) when is_atom(M), is_list(Deps) ->
+ d("check_module_depend -> entry with"
+ "~n M: ~p"
+ "~n Deps: ~p"
+ "~n Modules: ~p", [M, Deps, Modules]),
+ case [Dep || Dep <- Deps, lists:member(Dep, Modules) == false] of
+ [] ->
+ ok;
+ Unknown ->
+ error({unknown_depend_modules, Unknown})
+ end;
+check_module_depend(_M, D, _Modules) ->
+ d("check_module_depend -> entry when bad depend with"
+ "~n D: ~p", [D]),
+ error({bad_depend, D}).
+
+
+check_no_remove_depends(_Module, []) ->
+ ok;
+check_no_remove_depends(Module, [Instr|Instrs]) ->
+ check_no_remove_depend(Module, Instr),
+ check_no_remove_depends(Module, Instrs).
+
+check_no_remove_depend(Module, {load_module, Mod, _Pre, _Post, Depend}) ->
+ case lists:member(Module, Depend) of
+ true ->
+ error({removed_module_in_depend, load_module, Mod, Module});
+ false ->
+ ok
+ end;
+check_no_remove_depend(Module, {update, Mod, _Change, _Pre, _Post, Depend}) ->
+ case lists:member(Module, Depend) of
+ true ->
+ error({removed_module_in_depend, update, Mod, Module});
+ false ->
+ ok
+ end;
+check_no_remove_depend(_, _) ->
+ ok.
+
+
+check_change(soft) ->
+ ok;
+check_change({advanced, _Something}) ->
+ ok;
+check_change(Change) ->
+ error({bad_change, Change}).
+
+
+check_purge(soft_purge) ->
+ ok;
+check_purge(brutal_purge) ->
+ ok;
+check_purge(Purge) ->
+ error({bad_purge, Purge}).
+
+
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+error(Reason) ->
+ throw({error, Reason}).
+
+fail(Reason) ->
+ exit({suite_failed, Reason}).
+
+key1search(Key, L) ->
+ case lists:keysearch(Key, 1, L) of
+ undefined ->
+ fail({not_found, Key, L});
+ {value, {Key, Value}} ->
+ Value
+ end.
+
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+d(F, A) ->
+ d(false, F, A).
+
+d(true, F, A) ->
+ io:format(F ++ "~n", A);
+d(_, _, _) ->
+ ok.
+
+
diff --git a/lib/asn1/test/asn1_bin_particular_SUITE.erl.src b/lib/asn1/test/asn1_bin_particular_SUITE.erl.src
new file mode 100644
index 0000000000..0e153238ad
--- /dev/null
+++ b/lib/asn1/test/asn1_bin_particular_SUITE.erl.src
@@ -0,0 +1,2 @@
+
+particular() -> [].
diff --git a/lib/asn1/test/asn1_bin_v2_particular_SUITE.erl.src b/lib/asn1/test/asn1_bin_v2_particular_SUITE.erl.src
new file mode 100644
index 0000000000..abd21b0d78
--- /dev/null
+++ b/lib/asn1/test/asn1_bin_v2_particular_SUITE.erl.src
@@ -0,0 +1,95 @@
+
+particular() -> [smp, ticket7904].
+
+
+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]),
+
+ ?line Msg = {initiatingMessage, testNBAPsystem:cell_setup_req_msg()},
+ ?line ok = testNBAPsystem:compile(Config,per_bin,[optimize]),
+
+ Parent = self(),
+
+ ?line ok = asn1rt:load_driver(),
+
+ smp2(Parent,NumOfProcs,Msg,2),
+
+ N = 10000,
+
+ ?line {Time1,ok} = timer:tc(?MODULE,smp2,[Parent,NumOfProcs,Msg, N]),
+ ?line {Time1S,ok} = timer:tc(?MODULE,sequential,[NumOfProcs * N,Msg]),
+
+ ?line ok = testNBAPsystem:compile(Config,ber_bin,[optimize,driver]),
+ ?line {Time2,ok} = timer:tc(?MODULE,smp2,[Parent,NumOfProcs,Msg, N]),
+
+ ?line {Time2S,ok} = timer:tc(?MODULE,sequential,[NumOfProcs * N,Msg]),
+
+ {comment,lists:flatten(io_lib:format("Encode/decode time parallell with ~p cores: ~p [microsecs]~nEncode/decode time sequential: ~p [microsecs]",[NumOfProcs,Time1+Time2,Time1S+Time2S]))};
+ false ->
+ {skipped,"No smp support"}
+ end.
+
+smp2(Parent,NumOfProcs,Msg, N) ->
+ Pids = [spawn_link(fun() -> worker(Msg,Parent, N) end)
+ || _ <- lists:seq(1,NumOfProcs)],
+ ?line ok = wait_pids(Pids).
+
+worker(Msg, Parent, N) ->
+ %% io:format("smp worker ~p with ~p worker loops.~n",[self(), N]),
+ worker_loop(N, Msg),
+ Parent ! self().
+
+worker_loop(0, _Msg) ->
+ ok;
+worker_loop(N, Msg) ->
+ ?line {ok,B}=asn1_wrapper:encode('NBAP-PDU-Discriptions',
+ 'NBAP-PDU',
+ Msg),
+ ?line {ok,_Msg}=asn1_wrapper:decode('NBAP-PDU-Discriptions',
+ 'NBAP-PDU',
+ B),
+ worker_loop(N - 1, Msg).
+
+
+wait_pids([]) ->
+ ok;
+wait_pids(Pids) ->
+ receive
+ Pid when is_pid(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);
+ Err ->
+ io:format("Err: ~p~n",[Err]),
+ ?line exit(Err)
+ end.
+
+sequential(N,Msg) ->
+ %%io:format("sequential encode/decode with N = ~p~n",[N]),
+ worker_loop(N,Msg).
+
+-record('InitiatingMessage',{procedureCode,criticality,value}).
+-record('Iu-ReleaseCommand',{first,second}).
+
+ticket7904(suite) -> [];
+ticket7904(Config) ->
+ ?line DataDir = ?config(data_dir,Config),
+ ?line OutDir = ?config(priv_dir,Config),
+
+ ?line ok = asn1ct:compile(DataDir ++
+ "RANAPextract1",[per_bin,optimize,{outdir,OutDir}]),
+
+ Val1 = #'InitiatingMessage'{procedureCode=1,
+ criticality=ignore,
+ value=#'Iu-ReleaseCommand'{
+ first=13,
+ second=true}},
+
+ ?line {ok,_} = 'RANAPextract1':encode('InitiatingMessage', Val1),
+ asn1rt:unload_driver(),
+ ?line {ok,_} = 'RANAPextract1':encode('InitiatingMessage', Val1).
diff --git a/lib/asn1/test/asn1_common_SUITE.erl.src b/lib/asn1/test/asn1_common_SUITE.erl.src
new file mode 100644
index 0000000000..99a4f90738
--- /dev/null
+++ b/lib/asn1/test/asn1_common_SUITE.erl.src
@@ -0,0 +1,98 @@
+%%
+%% %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%
+%%
+%%
+
+common() -> [app_test, appup_test,testTimer_ber,testTimer_ber_bin,
+ testTimer_ber_bin_opt, testTimer_ber_bin_opt_driver, testTimer_per,
+ testTimer_per_bin, testTimer_per_bin_opt, testTimer_uper_bin,
+ testComment,testName2Number].
+
+
+app_test(suite) -> [{asn1_app_test,all}].
+appup_test(suite) -> [{asn1_appup_test,all}].
+
+testTimer_ber(suite) -> [];
+testTimer_ber(Config) ->
+ ?line testTimer:compile(Config,ber,[]),
+ ?line testTimer:go(Config,ber).
+
+testTimer_ber_bin(suite) -> [];
+testTimer_ber_bin(Config) ->
+ ?line testTimer:compile(Config,ber_bin,[]),
+ ?line testTimer:go(Config,ber_bin).
+
+testTimer_ber_bin_opt(suite) -> [];
+testTimer_ber_bin_opt(Config) ->
+ ?line testTimer:compile(Config,ber_bin,[optimize]),
+ ?line testTimer:go(Config,ber_bin).
+
+testTimer_ber_bin_opt_driver(suite) -> [];
+testTimer_ber_bin_opt_driver(Config) ->
+ ?line testTimer:compile(Config,ber_bin,[optimize,driver]),
+ ?line testTimer:go(Config,ber_bin).
+
+testTimer_per(suite) -> [];
+testTimer_per(Config) ->
+ ?line testTimer:compile(Config,per,[]),
+ ?line testTimer:go(Config,per).
+
+testTimer_per_bin(suite) -> [];
+testTimer_per_bin(Config) ->
+ ?line testTimer:compile(Config,per_bin,[]),
+ ?line testTimer:go(Config,per_bin).
+
+testTimer_per_bin_opt(suite) -> [];
+testTimer_per_bin_opt(Config) ->
+ ?line testTimer:compile(Config,per_bin,[optimize]),
+ ?line testTimer:go(Config,per_bin).
+
+
+testTimer_uper_bin(suite) -> [];
+testTimer_uper_bin(Config) ->
+ ?line ok=testTimer:compile(Config,uper_bin,[]),
+ ?line {comment,_} = testTimer:go(Config,uper_bin).
+
+%% Test of multiple-line comment, OTP-8043
+testComment(suite) -> [];
+testComment(Config) ->
+ ?line DataDir = ?config(data_dir,Config),
+ ?line OutDir = ?config(priv_dir,Config),
+
+ ?line ok = asn1ct:compile(DataDir ++ "Comment",[{outdir,OutDir}]),
+
+ ?line {ok,Enc} = asn1_wrapper:encode('Comment','Seq',{'Seq',12,true}),
+ ?line {ok,{'Seq',12,true}} = asn1_wrapper:decode('Comment','Seq',Enc),
+ ok.
+
+testName2Number(suite) -> [];
+testName2Number(Config) ->
+ DataDir = ?config(data_dir,Config),
+ OutDir = ?config(priv_dir,Config),
+ N2NOptions = [{n2n,Type}|| Type <-
+ ['CauseMisc','CauseProtocol',
+ %% 'CauseNetwork',
+ 'CauseRadioNetwork',
+ 'CauseTransport','CauseNas']],
+ ?line ok = asn1ct:compile(DataDir ++ "S1AP-IEs",[{outdir,OutDir}]++N2NOptions),
+ ?line true = code:add_patha(OutDir),
+
+ ?line 0 = 'S1AP-IEs':name2num_CauseMisc('control-processing-overload'),
+ ?line 'unknown-PLMN' = 'S1AP-IEs':num2name_CauseMisc(5),
+ ok.
+
diff --git a/lib/asn1/test/asn1_particular_SUITE.erl.src b/lib/asn1/test/asn1_particular_SUITE.erl.src
new file mode 100644
index 0000000000..df76de914d
--- /dev/null
+++ b/lib/asn1/test/asn1_particular_SUITE.erl.src
@@ -0,0 +1,10 @@
+
+particular() -> [ticket_7407].
+
+ticket_7407(suite) -> [];
+ticket_7407(Config) ->
+ ?line ok = asn1_test_lib:ticket_7407_compile(Config,[]),
+ ?line ok = asn1_test_lib:ticket_7407_code(true),
+
+ ?line ok = asn1_test_lib:ticket_7407_compile(Config,[no_final_padding]),
+ ?line ok = asn1_test_lib:ticket_7407_code(false). \ No newline at end of file
diff --git a/lib/asn1/test/asn1_test_lib.erl b/lib/asn1/test/asn1_test_lib.erl
new file mode 100644
index 0000000000..2884c79216
--- /dev/null
+++ b/lib/asn1/test/asn1_test_lib.erl
@@ -0,0 +1,151 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 2008-2010. All Rights Reserved.
+%%
+%% The contents of this file are subject to the Erlang Public License,
+%% Version 1.1, (the "License"); you may not use this file except in
+%% compliance with the License. You should have received a copy of the
+%% Erlang Public License along with this software. If not, it can be
+%% retrieved online at http://www.erlang.org/.
+%%
+%% Software distributed under the License is distributed on an "AS IS"
+%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+%% the License for the specific language governing rights and limitations
+%% under the License.
+%%
+%% %CopyrightEnd%
+%%
+%%
+-module(asn1_test_lib).
+
+-export([ticket_7407_compile/2,ticket_7407_code/1, ticket_7678/2,
+ ticket_7708/2, ticket_7763/1, ticket_7876/3]).
+
+-include("test_server.hrl").
+
+
+ticket_7407_compile(Config,Option) ->
+
+ ?line DataDir = ?config(data_dir,Config),
+ ?line OutDir = ?config(priv_dir,Config),
+
+ ?line ok = asn1ct:compile(DataDir ++ "EUTRA-extract-7407",
+ [uper_bin, {outdir,OutDir}]++Option).
+
+ticket_7708(Config,Option) ->
+ ?line DataDir = ?config(data_dir,Config),
+ ?line OutDir = ?config(priv_dir,Config),
+
+ ?line ok = asn1ct:compile(DataDir ++ "EUTRA-extract-55",
+ [uper_bin, {outdir,OutDir}]++Option).
+
+
+ticket_7407_code(FinalPadding) ->
+ Msg1 = {Type1,_} = eutra1(msg),
+ ?line {ok,B1} = 'EUTRA-extract-7407':encode(Type1,Msg1),
+ ?line B1 = eutra1(result,FinalPadding),
+
+ Msg2 = {Type2,_} = eutra2(msg),
+ ?line {ok,B2} = 'EUTRA-extract-7407':encode(Type2,Msg2),
+ ?line B2 = eutra2(result,FinalPadding),
+ ok.
+
+eutra1(msg) ->
+ {'BCCH-BCH-Message',{'MasterInformationBlock',[0,1,0,1],[1,0,1,0],{'PHICH-Configuration',short,ffs},[1,0,1,0,0,0,0,0]}}.
+eutra1(result,true) ->
+ <<90,80,0>>;
+eutra1(result,false) ->
+ <<90,80,0:1>>.
+
+eutra2(msg) ->
+ {'BCCH-DL-SCH-Message',
+ {c1,
+ {systemInformation1,
+ {'SystemInformationBlockType1',
+ {'SystemInformationBlockType1_cellAccessRelatedInformation',
+ [{'SystemInformationBlockType1_cellAccessRelatedInformation_plmn-IdentityList_SEQOF',{'PLMN-Identity'},true},
+ {'SystemInformationBlockType1_cellAccessRelatedInformation_plmn-IdentityList_SEQOF',{'PLMN-Identity'},false},
+ {'SystemInformationBlockType1_cellAccessRelatedInformation_plmn-IdentityList_SEQOF',{'PLMN-Identity'},true}],
+ {'TrackingAreaCode'},
+ {'CellIdentity'},
+ false,
+ true,
+ true,
+ true
+ },
+ {'SystemInformationBlockType1_cellSelectionInfo',-50},
+ 24,
+ [{'SystemInformationBlockType1_schedulinInformation_SEQOF',
+ {'SystemInformationBlockType1_schedulinInformation_SEQOF_si-MessageType'},
+ ms320,
+ {'SystemInformationBlockType1_schedulinInformation_SEQOF_sib-MappingInfo'}}],
+ 0
+ }
+ }
+ }
+ }.
+eutra2(result,true) ->
+%% 55 5C A5 E0
+ <<85,92,165,224>>;
+eutra2(result,false) ->
+ <<85,92,165,14:4>>.
+
+
+
+ticket_7678(Config, Option) ->
+ ?line DataDir = ?config(data_dir,Config),
+ ?line OutDir = ?config(priv_dir,Config),
+
+ ?line ok = asn1ct:compile(DataDir ++ "UPERDefault",
+ [uper_bin, {outdir,OutDir}]++Option),
+
+ ?line Val = 'UPERDefault':seq(),
+ ?line {ok,<<0,6,0>>} = 'UPERDefault':encode('Seq',Val),
+ ?line {ok,Val} = 'UPERDefault':decode('Seq',<<0,6,0>>),
+ ok.
+
+
+ticket_7763(Config) ->
+ ?line DataDir = ?config(data_dir,Config),
+ ?line OutDir = ?config(priv_dir,Config),
+
+ ?line ok = asn1ct:compile(DataDir ++ "EUTRA-extract-55",
+ [uper_bin, {outdir,OutDir}]),
+ Val = {'Seq',15,lists:duplicate(8,0),[0],lists:duplicate(28,0),15,true},
+ ?line {ok,Bin} = 'EUTRA-extract-55':encode('Seq',Val),
+
+ ?line ok = asn1ct:compile(DataDir ++ "EUTRA-extract-55",
+ [uper_bin,compact_bit_string,{outdir,OutDir}]),
+ CompactVal = {'Seq',15,{0,<<0>>},{7,<<0>>},{4,<<0,0,0,0>>},15,true},
+ {ok,CompactBin} = 'EUTRA-extract-55':encode('Seq',CompactVal),
+
+ ?line Bin = CompactBin,
+
+ io:format("CompactBin:~n~p~nBin:~n~p~nCompactBin == Bin is ~p~n",[CompactBin,Bin,CompactBin == Bin]).
+
+
+ticket_7876(Config,Erule,Options) ->
+ ?line DataDir = ?config(data_dir,Config),
+ ?line OutDir = ?config(priv_dir,Config),
+
+ ?line ok = asn1ct:compile(DataDir ++ "S1AP-CommonDataTypes",
+ [Erule,{outdir,OutDir}|Options]),
+ ?line ok = asn1ct:compile(DataDir ++ "S1AP-Constants",
+ [Erule,{outdir,OutDir}|Options]),
+?line ok = asn1ct:compile(DataDir ++ "S1AP-Containers",
+ [Erule,{outdir,OutDir}|Options]),
+?line ok = asn1ct:compile(DataDir ++ "S1AP-IEs",
+ [Erule,{outdir,OutDir}|Options]),
+?line ok = asn1ct:compile(DataDir ++ "S1AP-PDU-Contents",
+ [Erule,{outdir,OutDir}|Options]),
+?line ok = asn1ct:compile(DataDir ++ "S1AP-PDU-Descriptions",
+ [Erule,{outdir,OutDir}|Options]),
+
+ ticket_7876_encdec(Erule),
+ ok.
+
+ticket_7876_encdec(per) ->
+ ?line {ok,{initiatingMessage,_}} = 'S1AP-PDU-Descriptions':decode('S1AP-PDU', [0,2,64,49,0,0,5,0,0,0,4,128,106,56,197,0,8,0,3,64,2,134,0,100,64,8,0,66,240,153,0,7,192,16,0,67,64,6,0,66,240,153,70,1,0,107,64,5,0,0,0,0,0]);
+ticket_7876_encdec(_) ->
+ ?line {ok,{initiatingMessage,_}} = 'S1AP-PDU-Descriptions':decode('S1AP-PDU', <<0,2,64,49,0,0,5,0,0,0,4,128,106,56,197,0,8,0,3,64,2,134,0,100,64,8,0,66,240,153,0,7,192,16,0,67,64,6,0,66,240,153,70,1,0,107,64,5,0,0,0,0,0>>).
diff --git a/lib/asn1/test/asn1_wrapper.erl b/lib/asn1/test/asn1_wrapper.erl
new file mode 100644
index 0000000000..d515b99ac2
--- /dev/null
+++ b/lib/asn1/test/asn1_wrapper.erl
@@ -0,0 +1,74 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 2001-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(asn1_wrapper).
+-author('kenneth@bilbo').
+
+-compile(export_all).
+%%-export([Function/Arity, ...]).
+
+
+encode(Module,Type,Value) ->
+ case asn1rt:encode(Module,Type,Value) of
+ {ok,X} when is_binary(X) ->
+ {ok, binary_to_list(X)};
+ {ok,X} ->
+ {ok, binary_to_list(list_to_binary(X))};
+ Error ->
+ Error
+ end.
+
+decode(Module,Type,Bytes) ->
+ case Module:encoding_rule() of
+ ber ->
+ asn1rt:decode(Module,Type,Bytes);
+ ber_bin when is_binary(Bytes) ->
+ asn1rt:decode(Module,Type,Bytes);
+ ber_bin ->
+ asn1rt:decode(Module,Type,list_to_binary(Bytes));
+ ber_bin_v2 when is_binary(Bytes) ->
+ asn1rt:decode(Module,Type,Bytes);
+ ber_bin_v2 ->
+ asn1rt:decode(Module,Type,list_to_binary(Bytes));
+ per ->
+ asn1rt:decode(Module,Type,Bytes);
+ per_bin when is_binary(Bytes) ->
+ asn1rt:decode(Module,Type,Bytes);
+ per_bin ->
+ asn1rt:decode(Module,Type,list_to_binary(Bytes));
+ uper_bin when is_binary(Bytes) ->
+ asn1rt:decode(Module,Type,Bytes);
+ uper_bin ->
+ asn1rt:decode(Module,Type,list_to_binary(Bytes))
+ end.
+
+erule(ber) ->
+ ber;
+erule(ber_bin) ->
+ ber;
+erule(ber_bin_v2) ->
+ ber;
+erule(per) ->
+ per;
+erule(per_bin) ->
+ per;
+erule(uper_bin) ->
+ per.
+
+
diff --git a/lib/asn1/test/bench/README b/lib/asn1/test/bench/README
new file mode 100644
index 0000000000..2aa9e4cd70
--- /dev/null
+++ b/lib/asn1/test/bench/README
@@ -0,0 +1,109 @@
+Benchmark framework
+-------------------
+
+This benchmark framework consists of the files:
+bench.erl - see bench module below
+bench.hrl - Defines some useful macros
+all.erl - see all module below
+
+bench module
+-----------
+
+The module bench is a generic module that measures execution time
+of functions in callback modules and writes an html-report on the outcome.
+
+When you execute the function bench:run/0 it will compile and run all
+benchmark modules in the current directory.
+
+all module
+-----------
+
+In the all module there is a function called releases/0 that you can
+edit to contain all your erlang installations and then you can
+run your benchmarks on several erlang versions using only one command i.e.
+all:run().
+
+Requirements on callback modules
+---------------------------------
+
+* A callback module must be named <callbackModuleName>_bm.erl
+
+* The module must export the function benchmarks/0 that must return:
+ {Iterations, [Name1,Name2...]} where Iterations is the number of
+ times each benchmark should be run. Name1, Name2 and so one are the
+ name of exported functions in the module.
+
+* The exported functions Name1 etc. must take one argument i.e. the number
+ of iterations and should return the atom ok.
+
+* The functions in a benchmark module should represent different
+ ways/different sequential algorithms for doing something. And the
+ result will be how fast they are compared to each other.
+
+Files created
+--------------
+
+Files that are created in the current directory are *.bmres and
+index.html. The file(s) with the extension "bmres" are an intermediate
+representation of the benchmark results and is only meant to be read
+by the reporting mechanism defined in bench.erl. The index.html file
+is the report telling you how good the benchmarks are in comparison to
+each other. If you run your test on several erlang releases the
+html-file will include the result for all versions.
+
+
+Pitfalls
+---------
+To get meaningful measurements, you should make sure that:
+
+* The total execution time is at least several seconds.
+
+* That any time spent in setup before entering the measurement loop is very
+ small compared to the total time.
+
+* That time spent by the loop itself is small compared to the total execution
+ time
+
+Consider the following example of a benchmark function that does
+a local function call.
+
+local_call(0) -> ok;
+local_call(Iter) ->
+ foo(), % Local function call
+ local_call(Iter-1).
+
+The problem is that both "foo()" and "local_call(Iter-1)" takes about
+the same amount of time. To get meaningful figures you'll need to make
+sure that the loop overhead will not be visible. In this case we can
+take help of a macro in bench.hrl to repeat the local function call
+many times, making sure that time spent calling the local function is
+relatively much longer than the time spent iterating. Of course, all
+benchmarks in the same module must be repeated the same number of
+times; thus external_call will look like
+
+external_call(0) -> ok;
+external_call(Iter) ->
+ ?rep20(?MODULE:foo()),
+ external_call(Iter-1).
+
+This technique is only necessary if the operation we are testing executes
+really fast.
+
+If you for instance want to test a sort routine we can keep it simple:
+
+sorted(Iter) ->
+ do_sort(Iter, lists:seq(0, 63)).
+
+do_sort(0, List) -> ok;
+do_sort(Iter, List) ->
+ lists:sort(List),
+ do_sort(Iter-1, List).
+
+The call to lists:seq/2 is only done once. The loop overhead in the
+do_sort/2 function is small compared to the execution time of lists:sort/1.
+
+Error handling
+---------------
+
+Any error enforced by a callback module will result in exit of the benchmark
+program and an errormessage that should give a good idea of what is wrong.
diff --git a/lib/asn1/test/bench/RanapASN1.asn b/lib/asn1/test/bench/RanapASN1.asn
new file mode 100644
index 0000000000..b848aadc84
--- /dev/null
+++ b/lib/asn1/test/bench/RanapASN1.asn
@@ -0,0 +1,3146 @@
+RanapASN1 {
+itu-t (0) identified-organization (4) etsi (0) mobileDomain (0)
+umts-Access (20) modules (3) ranap (0) version1 (1) ranap-PDU-Descriptions (0)}
+
+DEFINITIONS AUTOMATIC TAGS ::=
+
+BEGIN
+
+-- **************************************************************
+--
+-- Interface Elementary Procedure Class
+--
+-- **************************************************************
+
+RANAP-ELEMENTARY-PROCEDURE ::= CLASS {
+ &InitiatingMessage ,
+ &SuccessfulOutcome OPTIONAL,
+ &UnsuccessfulOutcome OPTIONAL,
+ &Outcome OPTIONAL,
+ &procedureCode ProcedureCode UNIQUE,
+ &criticality Criticality DEFAULT ignore
+}
+WITH SYNTAX {
+ INITIATING MESSAGE &InitiatingMessage
+ [SUCCESSFUL OUTCOME &SuccessfulOutcome]
+ [UNSUCCESSFUL OUTCOME &UnsuccessfulOutcome]
+ [OUTCOME &Outcome]
+ PROCEDURE CODE &procedureCode
+ [CRITICALITY &criticality]
+}
+
+-- **************************************************************
+--
+-- Interface PDU Definition
+--
+-- **************************************************************
+
+RANAP-PDU ::= CHOICE {
+ initiatingMessage InitiatingMessage,
+ successfulOutcome SuccessfulOutcome,
+ unsuccessfulOutcome UnsuccessfulOutcome,
+ outcome Outcome,
+ ...
+}
+
+InitiatingMessage ::= SEQUENCE {
+ procedureCode RANAP-ELEMENTARY-PROCEDURE.&procedureCode ({RANAP-ELEMENTARY-PROCEDURES}),
+ criticality RANAP-ELEMENTARY-PROCEDURE.&criticality ({RANAP-ELEMENTARY-PROCEDURES}{@procedureCode}),
+ value RANAP-ELEMENTARY-PROCEDURE.&InitiatingMessage ({RANAP-ELEMENTARY-PROCEDURES}{@procedureCode})
+}
+
+SuccessfulOutcome ::= SEQUENCE {
+ procedureCode RANAP-ELEMENTARY-PROCEDURE.&procedureCode ({RANAP-ELEMENTARY-PROCEDURES}),
+ criticality RANAP-ELEMENTARY-PROCEDURE.&criticality ({RANAP-ELEMENTARY-PROCEDURES}{@procedureCode}),
+ value RANAP-ELEMENTARY-PROCEDURE.&SuccessfulOutcome ({RANAP-ELEMENTARY-PROCEDURES}{@procedureCode})
+}
+
+UnsuccessfulOutcome ::= SEQUENCE {
+ procedureCode RANAP-ELEMENTARY-PROCEDURE.&procedureCode ({RANAP-ELEMENTARY-PROCEDURES}),
+ criticality RANAP-ELEMENTARY-PROCEDURE.&criticality ({RANAP-ELEMENTARY-PROCEDURES}{@procedureCode}),
+ value RANAP-ELEMENTARY-PROCEDURE.&UnsuccessfulOutcome ({RANAP-ELEMENTARY-PROCEDURES}{@procedureCode})
+}
+
+Outcome ::= SEQUENCE {
+ procedureCode RANAP-ELEMENTARY-PROCEDURE.&procedureCode ({RANAP-ELEMENTARY-PROCEDURES}),
+ criticality RANAP-ELEMENTARY-PROCEDURE.&criticality ({RANAP-ELEMENTARY-PROCEDURES}{@procedureCode}),
+ value RANAP-ELEMENTARY-PROCEDURE.&Outcome ({RANAP-ELEMENTARY-PROCEDURES}{@procedureCode})
+}
+
+-- **************************************************************
+--
+-- Interface Elementary Procedure List
+--
+-- **************************************************************
+
+RANAP-ELEMENTARY-PROCEDURES RANAP-ELEMENTARY-PROCEDURE ::= {
+ RANAP-ELEMENTARY-PROCEDURES-CLASS-1 |
+ RANAP-ELEMENTARY-PROCEDURES-CLASS-2 |
+ RANAP-ELEMENTARY-PROCEDURES-CLASS-3 ,
+ ...
+}
+
+
+RANAP-ELEMENTARY-PROCEDURES-CLASS-1 RANAP-ELEMENTARY-PROCEDURE ::= {
+ iu-Release |
+ relocationPreparation |
+ relocationResourceAllocation |
+ relocationCancel |
+ sRNS-ContextTransfer |
+ securityModeControl |
+ dataVolumeReport |
+ reset |
+ resetResource ,
+ ...
+}
+
+RANAP-ELEMENTARY-PROCEDURES-CLASS-2 RANAP-ELEMENTARY-PROCEDURE ::= {
+ rAB-ReleaseRequest |
+ iu-ReleaseRequest |
+ relocationDetect |
+ relocationComplete |
+ paging |
+ commonID |
+ cN-InvokeTrace |
+ cN-DeactivateTrace |
+ locationReportingControl |
+ locationReport |
+ initialUE-Message |
+ directTransfer |
+ overloadControl |
+ errorIndication |
+ sRNS-DataForward |
+ forwardSRNS-Context |
+ privateMessage |
+ rANAP-Relocation ,
+ ...
+}
+
+RANAP-ELEMENTARY-PROCEDURES-CLASS-3 RANAP-ELEMENTARY-PROCEDURE ::= {
+ rAB-Assignment ,
+ ...
+}
+
+-- **************************************************************
+--
+-- Interface Elementary Procedures
+--
+-- **************************************************************
+
+iu-Release RANAP-ELEMENTARY-PROCEDURE ::= {
+ INITIATING MESSAGE Iu-ReleaseCommand
+ SUCCESSFUL OUTCOME Iu-ReleaseComplete
+ PROCEDURE CODE id-Iu-Release
+ CRITICALITY reject
+}
+
+relocationPreparation RANAP-ELEMENTARY-PROCEDURE ::= {
+ INITIATING MESSAGE RelocationRequired
+ SUCCESSFUL OUTCOME RelocationCommand
+ UNSUCCESSFUL OUTCOME RelocationPreparationFailure
+ PROCEDURE CODE id-RelocationPreparation
+ CRITICALITY reject
+}
+
+relocationResourceAllocation RANAP-ELEMENTARY-PROCEDURE ::= {
+ INITIATING MESSAGE RelocationRequest
+ SUCCESSFUL OUTCOME RelocationRequestAcknowledge
+ UNSUCCESSFUL OUTCOME RelocationFailure
+ PROCEDURE CODE id-RelocationResourceAllocation
+ CRITICALITY reject
+}
+
+relocationCancel RANAP-ELEMENTARY-PROCEDURE ::= {
+ INITIATING MESSAGE RelocationCancel
+ SUCCESSFUL OUTCOME RelocationCancelAcknowledge
+ PROCEDURE CODE id-RelocationCancel
+ CRITICALITY reject
+}
+
+sRNS-ContextTransfer RANAP-ELEMENTARY-PROCEDURE ::= {
+ INITIATING MESSAGE SRNS-ContextRequest
+ SUCCESSFUL OUTCOME SRNS-ContextResponse
+ PROCEDURE CODE id-SRNS-ContextTransfer
+ CRITICALITY reject
+}
+
+securityModeControl RANAP-ELEMENTARY-PROCEDURE ::= {
+ INITIATING MESSAGE SecurityModeCommand
+ SUCCESSFUL OUTCOME SecurityModeComplete
+ UNSUCCESSFUL OUTCOME SecurityModeReject
+ PROCEDURE CODE id-SecurityModeControl
+ CRITICALITY reject
+}
+
+dataVolumeReport RANAP-ELEMENTARY-PROCEDURE ::= {
+ INITIATING MESSAGE DataVolumeReportRequest
+ SUCCESSFUL OUTCOME DataVolumeReport
+ PROCEDURE CODE id-DataVolumeReport
+ CRITICALITY reject
+}
+
+
+reset RANAP-ELEMENTARY-PROCEDURE ::= {
+ INITIATING MESSAGE Reset
+ SUCCESSFUL OUTCOME ResetAcknowledge
+ PROCEDURE CODE id-Reset
+ CRITICALITY reject
+}
+
+rAB-ReleaseRequest RANAP-ELEMENTARY-PROCEDURE ::= {
+ INITIATING MESSAGE RAB-ReleaseRequest
+ PROCEDURE CODE id-RAB-ReleaseRequest
+ CRITICALITY ignore
+}
+
+iu-ReleaseRequest RANAP-ELEMENTARY-PROCEDURE ::= {
+ INITIATING MESSAGE Iu-ReleaseRequest
+ PROCEDURE CODE id-Iu-ReleaseRequest
+ CRITICALITY ignore
+}
+
+relocationDetect RANAP-ELEMENTARY-PROCEDURE ::= {
+ INITIATING MESSAGE RelocationDetect
+ PROCEDURE CODE id-RelocationDetect
+ CRITICALITY ignore
+}
+
+relocationComplete RANAP-ELEMENTARY-PROCEDURE ::= {
+ INITIATING MESSAGE RelocationComplete
+ PROCEDURE CODE id-RelocationComplete
+ CRITICALITY ignore
+}
+
+paging RANAP-ELEMENTARY-PROCEDURE ::= {
+ INITIATING MESSAGE Paging
+ PROCEDURE CODE id-Paging
+ CRITICALITY ignore
+}
+
+commonID RANAP-ELEMENTARY-PROCEDURE ::= {
+ INITIATING MESSAGE CommonID
+ PROCEDURE CODE id-CommonID
+ CRITICALITY ignore
+}
+
+cN-InvokeTrace RANAP-ELEMENTARY-PROCEDURE ::= {
+ INITIATING MESSAGE CN-InvokeTrace
+ PROCEDURE CODE id-CN-InvokeTrace
+ CRITICALITY ignore
+}
+
+cN-DeactivateTrace RANAP-ELEMENTARY-PROCEDURE ::= {
+ INITIATING MESSAGE CN-DeactivateTrace
+ PROCEDURE CODE id-CN-DeactivateTrace
+ CRITICALITY ignore
+}
+
+locationReportingControl RANAP-ELEMENTARY-PROCEDURE ::= {
+ INITIATING MESSAGE LocationReportingControl
+ PROCEDURE CODE id-LocationReportingControl
+ CRITICALITY ignore
+}
+
+locationReport RANAP-ELEMENTARY-PROCEDURE ::= {
+ INITIATING MESSAGE LocationReport
+ PROCEDURE CODE id-LocationReport
+ CRITICALITY ignore
+}
+
+initialUE-Message RANAP-ELEMENTARY-PROCEDURE ::= {
+ INITIATING MESSAGE InitialUE-Message
+ PROCEDURE CODE id-InitialUE-Message
+ CRITICALITY ignore
+}
+
+directTransfer RANAP-ELEMENTARY-PROCEDURE ::= {
+ INITIATING MESSAGE DirectTransfer
+ PROCEDURE CODE id-DirectTransfer
+ CRITICALITY ignore
+}
+
+overloadControl RANAP-ELEMENTARY-PROCEDURE ::= {
+ INITIATING MESSAGE Overload
+ PROCEDURE CODE id-OverloadControl
+ CRITICALITY ignore
+}
+
+errorIndication RANAP-ELEMENTARY-PROCEDURE ::= {
+ INITIATING MESSAGE ErrorIndication
+ PROCEDURE CODE id-ErrorIndication
+ CRITICALITY ignore
+}
+
+sRNS-DataForward RANAP-ELEMENTARY-PROCEDURE ::= {
+ INITIATING MESSAGE SRNS-DataForwardCommand
+ PROCEDURE CODE id-SRNS-DataForward
+ CRITICALITY ignore
+}
+
+forwardSRNS-Context RANAP-ELEMENTARY-PROCEDURE ::= {
+ INITIATING MESSAGE ForwardSRNS-Context
+ PROCEDURE CODE id-ForwardSRNS-Context
+ CRITICALITY ignore
+}
+
+rAB-Assignment RANAP-ELEMENTARY-PROCEDURE ::= {
+ INITIATING MESSAGE RAB-AssignmentRequest
+ OUTCOME RAB-AssignmentResponse
+ PROCEDURE CODE id-RAB-Assignment
+ CRITICALITY reject
+}
+
+privateMessage RANAP-ELEMENTARY-PROCEDURE ::= {
+ INITIATING MESSAGE PrivateMessage
+
+ PROCEDURE CODE id-privateMessage
+ CRITICALITY ignore
+}
+
+resetResource RANAP-ELEMENTARY-PROCEDURE ::= {
+ INITIATING MESSAGE ResetResource
+ SUCCESSFUL OUTCOME ResetResourceAcknowledge
+ PROCEDURE CODE id-ResetResource
+ CRITICALITY reject
+}
+
+rANAP-Relocation RANAP-ELEMENTARY-PROCEDURE ::= {
+ INITIATING MESSAGE RANAP-RelocationInformation
+ PROCEDURE CODE id-RANAP-Relocation
+ CRITICALITY ignore
+}
+
+
+
+-- **************************************************************
+--
+-- PDU definitions for RANAP.
+--
+-- **************************************************************
+
+
+--BEGIN_2
+
+-- **************************************************************
+--
+-- Common Container Lists
+--
+-- **************************************************************
+
+RAB-IE-ContainerList { RANAP-PROTOCOL-IES : IEsSetParam } ::= ProtocolIE-ContainerList { 1, maxNrOfRABs, {IEsSetParam} }
+RAB-IE-ContainerPairList { RANAP-PROTOCOL-IES-PAIR : IEsSetParam } ::= ProtocolIE-ContainerPairList { 1, maxNrOfRABs, {IEsSetParam} }
+ProtocolError-IE-ContainerList { RANAP-PROTOCOL-IES : IEsSetParam } ::= ProtocolIE-ContainerList { 1, maxNrOfRABs, {IEsSetParam} }
+IuSigConId-IE-ContainerList { RANAP-PROTOCOL-IES : IEsSetParam } ::= ProtocolIE-ContainerList { 1, maxNrOfIuSigConIds, {IEsSetParam} }
+DirectTransfer-IE-ContainerList { RANAP-PROTOCOL-IES : IEsSetParam } ::= ProtocolIE-ContainerList { 1, maxNrOfDTs, {IEsSetParam} }
+
+-- **************************************************************
+--
+-- Iu RELEASE ELEMENTARY PROCEDURE
+--
+-- **************************************************************
+
+-- **************************************************************
+--
+-- Iu Release Command
+--
+-- **************************************************************
+
+Iu-ReleaseCommand ::= SEQUENCE {
+ protocolIEs ProtocolIE-Container { {Iu-ReleaseCommandIEs} },
+ protocolExtensions ProtocolExtensionContainer { {Iu-ReleaseCommandExtensions} } OPTIONAL,
+ ...
+}
+
+Iu-ReleaseCommandIEs RANAP-PROTOCOL-IES ::= {
+ { ID id-Cause CRITICALITY ignore TYPE Cause PRESENCE mandatory },
+ ...
+}
+
+Iu-ReleaseCommandExtensions RANAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+-- **************************************************************
+--
+-- Iu Release Complete
+--
+-- **************************************************************
+
+Iu-ReleaseComplete ::= SEQUENCE {
+ protocolIEs ProtocolIE-Container { {Iu-ReleaseCompleteIEs} },
+ protocolExtensions ProtocolExtensionContainer { {Iu-ReleaseCompleteExtensions} } OPTIONAL,
+ ...
+}
+
+Iu-ReleaseCompleteIEs RANAP-PROTOCOL-IES ::= {
+ { ID id-RAB-DataVolumeReportList CRITICALITY ignore TYPE RAB-DataVolumeReportList PRESENCE conditional
+ -- This group is only present if data volume reporting for PS domain is required -- } |
+ { ID id-RAB-ReleasedList-IuRelComp CRITICALITY ignore TYPE RAB-ReleasedList-IuRelComp PRESENCE conditional
+ -- This group is only present for RABs towards the PS domain when sequence numbers are available and when the release was initiated by UTRAN -- } |
+ { ID id-CriticalityDiagnostics CRITICALITY ignore TYPE CriticalityDiagnostics PRESENCE optional },
+ ...
+}
+
+RAB-DataVolumeReportList ::= RAB-IE-ContainerList { {RAB-DataVolumeReportItemIEs} }
+
+RAB-DataVolumeReportItemIEs RANAP-PROTOCOL-IES ::= {
+ { ID id-RAB-DataVolumeReportItem CRITICALITY ignore TYPE RAB-DataVolumeReportItem PRESENCE mandatory },
+ ...
+}
+
+RAB-DataVolumeReportItem ::= SEQUENCE {
+ rAB-ID RAB-ID,
+ dl-UnsuccessfullyTransmittedDataVolume DataVolumeList OPTIONAL
+ -- This IE is only present if data volume reporting for PS domain is required --,
+ iE-Extensions ProtocolExtensionContainer { {RAB-DataVolumeReportItem-ExtIEs} } OPTIONAL,
+ ...
+}
+
+RAB-DataVolumeReportItem-ExtIEs RANAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+RAB-ReleasedList-IuRelComp ::= RAB-IE-ContainerList { {RAB-ReleasedItem-IuRelComp-IEs} }
+
+RAB-ReleasedItem-IuRelComp-IEs RANAP-PROTOCOL-IES ::= {
+ { ID id-RAB-ReleasedItem-IuRelComp CRITICALITY ignore TYPE RAB-ReleasedItem-IuRelComp PRESENCE mandatory },
+ ...
+}
+
+RAB-ReleasedItem-IuRelComp ::= SEQUENCE {
+ rAB-ID RAB-ID,
+ dL-GTP-PDU-SequenceNumber DL-GTP-PDU-SequenceNumber OPTIONAL
+ --This IE is only present when available--,
+ uL-GTP-PDU-SequenceNumber UL-GTP-PDU-SequenceNumber OPTIONAL
+ --This IE is only present when available--,
+ iE-Extensions ProtocolExtensionContainer { {RAB-ReleasedItem-IuRelComp-ExtIEs} } OPTIONAL,
+ ...
+}
+
+RAB-ReleasedItem-IuRelComp-ExtIEs RANAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+
+Iu-ReleaseCompleteExtensions RANAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+-- **************************************************************
+--
+-- RELOCATION PREPARATION ELEMENTARY PROCEDURE
+--
+-- **************************************************************
+
+-- **************************************************************
+--
+-- Relocation Required
+--
+-- **************************************************************
+
+RelocationRequired ::= SEQUENCE {
+ protocolIEs ProtocolIE-Container { {RelocationRequiredIEs} },
+ protocolExtensions ProtocolExtensionContainer { {RelocationRequiredExtensions} } OPTIONAL,
+ ...
+}
+
+RelocationRequiredIEs RANAP-PROTOCOL-IES ::= {
+ { ID id-RelocationType CRITICALITY reject TYPE RelocationType PRESENCE mandatory } |
+ { ID id-Cause CRITICALITY ignore TYPE Cause PRESENCE mandatory } |
+ { ID id-SourceID CRITICALITY ignore TYPE SourceID PRESENCE mandatory } |
+ { ID id-TargetID CRITICALITY reject TYPE TargetID PRESENCE mandatory } |
+ { ID id-ClassmarkInformation2 CRITICALITY reject TYPE ClassmarkInformation2 PRESENCE conditional
+ -- This is only present when initiating an inter system handover towards GSM BSC -- } |
+ { ID id-ClassmarkInformation3 CRITICALITY ignore TYPE ClassmarkInformation3 PRESENCE conditional
+ -- This is only present when initiating an inter system handover towards GSM BSC -- } |
+ { ID id-SourceRNC-ToTargetRNC-TransparentContainer
+ CRITICALITY reject TYPE SourceRNC-ToTargetRNC-TransparentContainer PRESENCE conditional
+ -- This IE shall be present when initiating relocation of SRNS -- } |
+ { ID id-OldBSS-ToNewBSS-Information CRITICALITY ignore TYPE OldBSS-ToNewBSS-Information PRESENCE conditional
+ -- This is only present when initiating an inter system handover towards GSM BSC -- } ,
+ ...
+}
+
+RelocationRequiredExtensions RANAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+-- **************************************************************
+--
+-- Relocation Command
+--
+-- **************************************************************
+
+RelocationCommand ::= SEQUENCE {
+ protocolIEs ProtocolIE-Container { {RelocationCommandIEs} },
+ protocolExtensions ProtocolExtensionContainer { {RelocationCommandExtensions} } OPTIONAL,
+ ...
+}
+
+RelocationCommandIEs RANAP-PROTOCOL-IES ::= {
+ { ID id-TargetRNC-ToSourceRNC-TransparentContainer
+ CRITICALITY reject TYPE TargetRNC-ToSourceRNC-TransparentContainer PRESENCE conditional
+ -- This IE shall be included if it is received by the CN from the relocation target. -- } |
+ { ID id-L3-Information CRITICALITY ignore TYPE L3-Information PRESENCE conditional
+ -- This IE shall be included if it is received by the CN from the relocation target. -- } |
+ { ID id-RAB-RelocationReleaseList CRITICALITY ignore TYPE RAB-RelocationReleaseList PRESENCE optional } |
+ { ID id-RAB-DataForwardingList CRITICALITY ignore TYPE RAB-DataForwardingList PRESENCE conditional
+ -- This group if applicable is only present for RABs towards the PS domain -- } |
+ { ID id-CriticalityDiagnostics CRITICALITY ignore TYPE CriticalityDiagnostics PRESENCE optional },
+ ...
+}
+
+RAB-RelocationReleaseList ::= RAB-IE-ContainerList { {RAB-RelocationReleaseItemIEs} }
+
+RAB-RelocationReleaseItemIEs RANAP-PROTOCOL-IES ::= {
+ { ID id-RAB-RelocationReleaseItem CRITICALITY ignore TYPE RAB-RelocationReleaseItem PRESENCE mandatory },
+ ...
+}
+
+RAB-RelocationReleaseItem ::= SEQUENCE {
+ rAB-ID RAB-ID,
+ iE-Extensions ProtocolExtensionContainer { {RAB-RelocationReleaseItem-ExtIEs} } OPTIONAL,
+ ...
+}
+
+RAB-RelocationReleaseItem-ExtIEs RANAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+RAB-DataForwardingList ::= RAB-IE-ContainerList { {RAB-DataForwardingItemIEs} }
+
+RAB-DataForwardingItemIEs RANAP-PROTOCOL-IES ::= {
+ { ID id-RAB-DataForwardingItem CRITICALITY ignore TYPE RAB-DataForwardingItem PRESENCE mandatory },
+ ...
+}
+
+RAB-DataForwardingItem ::= SEQUENCE {
+ rAB-ID RAB-ID,
+ transportLayerAddress TransportLayerAddress,
+ iuTransportAssociation IuTransportAssociation,
+ iE-Extensions ProtocolExtensionContainer { {RAB-DataForwardingItem-ExtIEs} } OPTIONAL,
+ ...
+}
+
+RAB-DataForwardingItem-ExtIEs RANAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+RelocationCommandExtensions RANAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+-- **************************************************************
+--
+-- Relocation Preparation Failure
+--
+-- **************************************************************
+
+RelocationPreparationFailure ::= SEQUENCE {
+ protocolIEs ProtocolIE-Container { {RelocationPreparationFailureIEs} },
+ protocolExtensions ProtocolExtensionContainer { {RelocationPreparationFailureExtensions} } OPTIONAL,
+ ...
+}
+
+RelocationPreparationFailureIEs RANAP-PROTOCOL-IES ::= {
+ { ID id-Cause CRITICALITY ignore TYPE Cause PRESENCE mandatory } |
+ { ID id-CriticalityDiagnostics CRITICALITY ignore TYPE CriticalityDiagnostics PRESENCE optional },
+ ...
+}
+
+RelocationPreparationFailureExtensions RANAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+-- **************************************************************
+--
+-- RELOCATION RESOURCE ALLOCATION ELEMENTARY PROCEDURE
+--
+-- **************************************************************
+
+-- **************************************************************
+--
+-- Relocation Request
+--
+-- **************************************************************
+
+RelocationRequest ::= SEQUENCE {
+ protocolIEs ProtocolIE-Container { {RelocationRequestIEs} },
+ protocolExtensions ProtocolExtensionContainer { {RelocationRequestExtensions} } OPTIONAL,
+ ...
+}
+
+RelocationRequestIEs RANAP-PROTOCOL-IES ::= {
+ { ID id-PermanentNAS-UE-ID CRITICALITY ignore TYPE PermanentNAS-UE-ID PRESENCE conditional
+ -- This IE is only present if available at the sending side -- } |
+ { ID id-Cause CRITICALITY ignore TYPE Cause PRESENCE mandatory } |
+ { ID id-CN-DomainIndicator CRITICALITY reject TYPE CN-DomainIndicator PRESENCE mandatory } |
+ { ID id-SourceRNC-ToTargetRNC-TransparentContainer
+ CRITICALITY reject TYPE SourceRNC-ToTargetRNC-TransparentContainer PRESENCE mandatory } |
+ { ID id-RAB-SetupList-RelocReq CRITICALITY reject TYPE RAB-SetupList-RelocReq PRESENCE optional } |
+ { ID id-IntegrityProtectionInformation CRITICALITY ignore TYPE IntegrityProtectionInformation PRESENCE conditional
+ -- This IE is only present if available at the sending side -- } |
+ { ID id-EncryptionInformation CRITICALITY ignore TYPE EncryptionInformation PRESENCE optional } |
+ { ID id-IuSigConId CRITICALITY ignore TYPE IuSignallingConnectionIdentifier PRESENCE mandatory },
+ ...
+}
+
+RAB-SetupList-RelocReq ::= RAB-IE-ContainerList { {RAB-SetupItem-RelocReq-IEs} }
+
+RAB-SetupItem-RelocReq-IEs RANAP-PROTOCOL-IES ::= {
+ { ID id-RAB-SetupItem-RelocReq CRITICALITY reject TYPE RAB-SetupItem-RelocReq PRESENCE mandatory },
+ ...
+}
+
+RAB-SetupItem-RelocReq ::= SEQUENCE {
+ rAB-ID RAB-ID,
+ nAS-SynchronisationIndicator NAS-SynchronisationIndicator OPTIONAL
+ -- This IE is present if the relevant NAS information is provided by the CN --,
+ rAB-Parameters RAB-Parameters,
+ dataVolumeReportingIndication DataVolumeReportingIndication OPTIONAL
+ -- This IE, if applicable, is only present for RABs towards the PS domain --,
+ pDP-TypeInformation PDP-TypeInformation OPTIONAL
+ -- This IE is only present for RABs towards the PS domain --,
+ userPlaneInformation UserPlaneInformation,
+ transportLayerAddress TransportLayerAddress,
+ iuTransportAssociation IuTransportAssociation,
+ service-Handover Service-Handover OPTIONAL,
+ iE-Extensions ProtocolExtensionContainer { {RAB-SetupItem-RelocReq-ExtIEs} } OPTIONAL,
+ ...
+}
+
+RAB-SetupItem-RelocReq-ExtIEs RANAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+UserPlaneInformation ::= SEQUENCE {
+ userPlaneMode UserPlaneMode,
+ uP-ModeVersions UP-ModeVersions,
+ iE-Extensions ProtocolExtensionContainer { {UserPlaneInformation-ExtIEs} } OPTIONAL,
+ ...
+}
+
+UserPlaneInformation-ExtIEs RANAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+RelocationRequestExtensions RANAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+-- **************************************************************
+--
+-- Relocation Request Acknowledge
+--
+-- **************************************************************
+
+RelocationRequestAcknowledge ::= SEQUENCE {
+ protocolIEs ProtocolIE-Container { {RelocationRequestAcknowledgeIEs} },
+ protocolExtensions ProtocolExtensionContainer { {RelocationRequestAcknowledgeExtensions} } OPTIONAL,
+ ...
+}
+
+RelocationRequestAcknowledgeIEs RANAP-PROTOCOL-IES ::= {
+ { ID id-TargetRNC-ToSourceRNC-TransparentContainer
+ CRITICALITY ignore TYPE TargetRNC-ToSourceRNC-TransparentContainer PRESENCE conditional
+ -- Must be included if applicapble and if not sent via the other CN -- } |
+ { ID id-RAB-SetupList-RelocReqAck CRITICALITY ignore TYPE RAB-SetupList-RelocReqAck PRESENCE optional} |
+ { ID id-RAB-FailedList CRITICALITY ignore TYPE RAB-FailedList PRESENCE optional }|
+ { ID id-ChosenIntegrityProtectionAlgorithm CRITICALITY ignore TYPE ChosenIntegrityProtectionAlgorithm PRESENCE conditional
+ -- This IE is only present if available at the sending side -- } |
+ { ID id-ChosenEncryptionAlgorithm CRITICALITY ignore TYPE ChosenEncryptionAlgorithm PRESENCE optional } |
+ { ID id-CriticalityDiagnostics CRITICALITY ignore TYPE CriticalityDiagnostics PRESENCE optional },
+ ...
+}
+
+RAB-SetupList-RelocReqAck ::= RAB-IE-ContainerList { {RAB-SetupItem-RelocReqAck-IEs} }
+
+RAB-SetupItem-RelocReqAck-IEs RANAP-PROTOCOL-IES ::= {
+ { ID id-RAB-SetupItem-RelocReqAck CRITICALITY reject TYPE RAB-SetupItem-RelocReqAck PRESENCE mandatory },
+ ...
+}
+
+RAB-SetupItem-RelocReqAck ::= SEQUENCE {
+ rAB-ID RAB-ID,
+ transportLayerAddress TransportLayerAddress OPTIONAL,
+ --This IE is only present for RABS towards the PS Domain
+ iuTransportAssociation IuTransportAssociation OPTIONAL,
+ --This IE is only present for RABS towards the PS Domain
+ iE-Extensions ProtocolExtensionContainer { {RAB-SetupItem-RelocReqAck-ExtIEs} } OPTIONAL,
+ ...
+}
+
+RAB-SetupItem-RelocReqAck-ExtIEs RANAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+RAB-FailedList ::= RAB-IE-ContainerList { {RAB-FailedItemIEs} }
+
+RAB-FailedItemIEs RANAP-PROTOCOL-IES ::= {
+ { ID id-RAB-FailedItem CRITICALITY ignore TYPE RAB-FailedItem PRESENCE mandatory },
+ ...
+}
+
+RAB-FailedItem ::= SEQUENCE {
+ rAB-ID RAB-ID,
+ cause Cause,
+ iE-Extensions ProtocolExtensionContainer { {RAB-FailedItem-ExtIEs} } OPTIONAL,
+ ...
+}
+
+RAB-FailedItem-ExtIEs RANAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+RelocationRequestAcknowledgeExtensions RANAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+-- **************************************************************
+--
+-- Relocation Failure
+--
+-- **************************************************************
+
+RelocationFailure ::= SEQUENCE {
+ protocolIEs ProtocolIE-Container { {RelocationFailureIEs} },
+ protocolExtensions ProtocolExtensionContainer { {RelocationFailureExtensions} } OPTIONAL,
+ ...
+}
+
+RelocationFailureIEs RANAP-PROTOCOL-IES ::= {
+ { ID id-Cause CRITICALITY ignore TYPE Cause PRESENCE mandatory } |
+ { ID id-CriticalityDiagnostics CRITICALITY ignore TYPE CriticalityDiagnostics PRESENCE optional },
+ ...
+}
+
+RelocationFailureExtensions RANAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+-- **************************************************************
+--
+-- RELOCATION CANCEL ELEMENTARY PROCEDURE
+--
+-- **************************************************************
+
+-- **************************************************************
+--
+-- Relocation Cancel
+--
+-- **************************************************************
+
+RelocationCancel ::= SEQUENCE {
+ protocolIEs ProtocolIE-Container { {RelocationCancelIEs} },
+ protocolExtensions ProtocolExtensionContainer { {RelocationCancelExtensions} } OPTIONAL,
+ ...
+}
+
+RelocationCancelIEs RANAP-PROTOCOL-IES ::= {
+ { ID id-Cause CRITICALITY ignore TYPE Cause PRESENCE mandatory },
+ ...
+}
+
+RelocationCancelExtensions RANAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+-- **************************************************************
+--
+-- Relocation Cancel Acknowledge
+--
+-- **************************************************************
+
+RelocationCancelAcknowledge ::= SEQUENCE {
+ protocolIEs ProtocolIE-Container { {RelocationCancelAcknowledgeIEs} },
+ protocolExtensions ProtocolExtensionContainer { {RelocationCancelAcknowledgeExtensions} } OPTIONAL,
+ ...
+}
+
+RelocationCancelAcknowledgeIEs RANAP-PROTOCOL-IES ::= {
+ { ID id-CriticalityDiagnostics CRITICALITY ignore TYPE CriticalityDiagnostics PRESENCE optional },
+ ...
+}
+
+RelocationCancelAcknowledgeExtensions RANAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+-- **************************************************************
+--
+-- SRNS CONTEXT TRANSFER OPEARATION
+--
+-- **************************************************************
+
+-- **************************************************************
+--
+-- SRNS Context Request
+--
+-- **************************************************************
+
+SRNS-ContextRequest ::= SEQUENCE {
+ protocolIEs ProtocolIE-Container { {SRNS-ContextRequestIEs} },
+ protocolExtensions ProtocolExtensionContainer { {SRNS-ContextRequestExtensions} } OPTIONAL,
+ ...
+}
+
+SRNS-ContextRequestIEs RANAP-PROTOCOL-IES ::= {
+ { ID id-RAB-DataForwardingList-SRNS-CtxReq CRITICALITY ignore TYPE RAB-DataForwardingList-SRNS-CtxReq PRESENCE mandatory },
+ ...
+}
+
+RAB-DataForwardingList-SRNS-CtxReq ::= RAB-IE-ContainerList { {RAB-DataForwardingItem-SRNS-CtxReq-IEs} }
+
+RAB-DataForwardingItem-SRNS-CtxReq-IEs RANAP-PROTOCOL-IES ::= {
+ { ID id-RAB-DataForwardingItem-SRNS-CtxReq CRITICALITY reject TYPE RAB-DataForwardingItem-SRNS-CtxReq PRESENCE mandatory },
+ ...
+}
+
+RAB-DataForwardingItem-SRNS-CtxReq ::= SEQUENCE {
+ rAB-ID RAB-ID,
+ iE-Extensions ProtocolExtensionContainer { {RAB-DataForwardingItem-SRNS-CtxReq-ExtIEs} } OPTIONAL,
+ ...
+}
+
+RAB-DataForwardingItem-SRNS-CtxReq-ExtIEs RANAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+SRNS-ContextRequestExtensions RANAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+-- **************************************************************
+--
+-- SRNS Context Response
+--
+-- **************************************************************
+
+SRNS-ContextResponse ::= SEQUENCE {
+ protocolIEs ProtocolIE-Container { {SRNS-ContextResponseIEs} },
+ protocolExtensions ProtocolExtensionContainer { {SRNS-ContextResponseExtensions} } OPTIONAL,
+ ...
+}
+
+SRNS-ContextResponseIEs RANAP-PROTOCOL-IES ::= {
+ { ID id-RAB-ContextList CRITICALITY ignore TYPE RAB-ContextList PRESENCE conditional
+ -- This group must be present at least when no other group is present, ie. at least one group must be present -- } |
+ { ID id-RAB-ContextFailedtoTransferList CRITICALITY ignore TYPE RAB-ContextFailedtoTransferList PRESENCE conditional
+ -- This group must be present at least when no other group is present, ie. at least one group must be present -- }|
+ { ID id-CriticalityDiagnostics CRITICALITY ignore TYPE CriticalityDiagnostics PRESENCE optional },
+ ...
+}
+
+RAB-ContextList ::= RAB-IE-ContainerList { {RAB-ContextItemIEs} }
+
+RAB-ContextItemIEs RANAP-PROTOCOL-IES ::= {
+ { ID id-RAB-ContextItem CRITICALITY ignore TYPE RAB-ContextItem PRESENCE mandatory },
+ ...
+}
+
+RAB-ContextItem ::= SEQUENCE {
+ rAB-ID RAB-ID,
+ dl-GTP-PDU-SequenceNumber DL-GTP-PDU-SequenceNumber OPTIONAL
+ --This IE is only present when available--,
+ ul-GTP-PDU-SequenceNumber UL-GTP-PDU-SequenceNumber OPTIONAL
+ --This IE is only present when available--,
+ dl-N-PDU-SequenceNumber DL-N-PDU-SequenceNumber OPTIONAL
+ --This IE is only present when available--,
+ ul-N-PDU-SequenceNumber UL-N-PDU-SequenceNumber OPTIONAL
+ --This IE is only present when available--,
+ iE-Extensions ProtocolExtensionContainer { {RAB-ContextItem-ExtIEs} } OPTIONAL,
+ ...
+}
+
+RAB-ContextItem-ExtIEs RANAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+RAB-ContextFailedtoTransferList ::= RAB-IE-ContainerList { {RABs-ContextFailedtoTransferItemIEs} }
+
+RABs-ContextFailedtoTransferItemIEs RANAP-PROTOCOL-IES ::= {
+ { ID id-RAB-ContextFailedtoTransferItem CRITICALITY ignore TYPE RABs-ContextFailedtoTransferItem PRESENCE mandatory },
+ ...
+}
+
+RABs-ContextFailedtoTransferItem::= SEQUENCE {
+ rAB-ID RAB-ID,
+ cause Cause,
+ iE-Extensions ProtocolExtensionContainer { { RABs-ContextFailedtoTransferItem-ExtIEs} } OPTIONAL,
+ ...
+}
+
+
+RABs-ContextFailedtoTransferItem-ExtIEs RANAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+SRNS-ContextResponseExtensions RANAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+-- **************************************************************
+--
+-- SECURITY MODE CONTROL ELEMENTARY PROCEDURE
+--
+-- **************************************************************
+
+-- **************************************************************
+--
+-- Security Mode Command
+--
+-- **************************************************************
+
+SecurityModeCommand ::= SEQUENCE {
+ protocolIEs ProtocolIE-Container { {SecurityModeCommandIEs} },
+ protocolExtensions ProtocolExtensionContainer { {SecurityModeCommandExtensions} } OPTIONAL,
+ ...
+}
+
+SecurityModeCommandIEs RANAP-PROTOCOL-IES ::= {
+ { ID id-IntegrityProtectionInformation CRITICALITY reject TYPE IntegrityProtectionInformation PRESENCE mandatory } |
+ { ID id-EncryptionInformation CRITICALITY ignore TYPE EncryptionInformation PRESENCE optional } |
+ { ID id-KeyStatus CRITICALITY reject TYPE KeyStatus PRESENCE mandatory},
+ ...
+}
+
+SecurityModeCommandExtensions RANAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+-- **************************************************************
+--
+-- Security Mode Complete
+--
+-- **************************************************************
+
+SecurityModeComplete ::= SEQUENCE {
+ protocolIEs ProtocolIE-Container { {SecurityModeCompleteIEs} },
+ protocolExtensions ProtocolExtensionContainer { {SecurityModeCompleteExtensions} } OPTIONAL,
+ ...
+}
+
+SecurityModeCompleteIEs RANAP-PROTOCOL-IES ::= {
+ { ID id-ChosenIntegrityProtectionAlgorithm CRITICALITY reject TYPE ChosenIntegrityProtectionAlgorithm PRESENCE mandatory } |
+ { ID id-ChosenEncryptionAlgorithm CRITICALITY ignore TYPE ChosenEncryptionAlgorithm PRESENCE optional } |
+ { ID id-CriticalityDiagnostics CRITICALITY ignore TYPE CriticalityDiagnostics PRESENCE optional },
+ ...
+}
+
+SecurityModeCompleteExtensions RANAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+-- **************************************************************
+--
+-- Security Mode Reject
+--
+-- **************************************************************
+
+SecurityModeReject ::= SEQUENCE {
+ protocolIEs ProtocolIE-Container { {SecurityModeRejectIEs} },
+ protocolExtensions ProtocolExtensionContainer { {SecurityModeRejectExtensions} } OPTIONAL,
+ ...
+}
+
+SecurityModeRejectIEs RANAP-PROTOCOL-IES ::= {
+ { ID id-Cause CRITICALITY ignore TYPE Cause PRESENCE mandatory } |
+ { ID id-CriticalityDiagnostics CRITICALITY ignore TYPE CriticalityDiagnostics PRESENCE optional },
+ ...
+}
+
+SecurityModeRejectExtensions RANAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+-- **************************************************************
+--
+-- DATA VOLUME REPORT ELEMENTARY PROCEDURE
+--
+-- **************************************************************
+
+-- **************************************************************
+--
+-- Data Volume Report Request
+--
+-- **************************************************************
+
+DataVolumeReportRequest ::= SEQUENCE {
+ protocolIEs ProtocolIE-Container { {DataVolumeReportRequestIEs} },
+ protocolExtensions ProtocolExtensionContainer { {DataVolumeReportRequestExtensions} } OPTIONAL,
+ ...
+}
+
+DataVolumeReportRequestIEs RANAP-PROTOCOL-IES ::= {
+ { ID id-RAB-DataVolumeReportRequestList CRITICALITY ignore TYPE RAB-DataVolumeReportRequestList PRESENCE mandatory },
+ ...
+}
+
+RAB-DataVolumeReportRequestList ::= RAB-IE-ContainerList { {RAB-DataVolumeReportRequestItemIEs} }
+
+RAB-DataVolumeReportRequestItemIEs RANAP-PROTOCOL-IES ::= {
+ { ID id-RAB-DataVolumeReportRequestItem CRITICALITY reject TYPE RAB-DataVolumeReportRequestItem PRESENCE mandatory },
+ ...
+}
+
+RAB-DataVolumeReportRequestItem ::= SEQUENCE {
+ rAB-ID RAB-ID,
+ iE-Extensions ProtocolExtensionContainer { {RAB-DataVolumeReportRequestItem-ExtIEs} } OPTIONAL,
+ ...
+}
+
+RAB-DataVolumeReportRequestItem-ExtIEs RANAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+DataVolumeReportRequestExtensions RANAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+-- **************************************************************
+--
+-- Data Volume Report
+--
+-- **************************************************************
+
+DataVolumeReport ::= SEQUENCE {
+ protocolIEs ProtocolIE-Container { {DataVolumeReportIEs} },
+ protocolExtensions ProtocolExtensionContainer { {DataVolumeReportExtensions} } OPTIONAL,
+ ...
+}
+
+DataVolumeReportIEs RANAP-PROTOCOL-IES ::= {
+ { ID id-RAB-DataVolumeReportList CRITICALITY ignore TYPE RAB-DataVolumeReportList PRESENCE conditional
+ -- This group must be present at least when no other group is present, ie. at least one group must be present -- } |
+ { ID id-RAB-FailedtoReportList CRITICALITY ignore TYPE RAB-FailedtoReportList PRESENCE conditional
+ -- This group must be present at least when no other group is present, ie. at least one group must be present -- } |
+ { ID id-CriticalityDiagnostics CRITICALITY ignore TYPE CriticalityDiagnostics PRESENCE optional },
+ ...
+}
+
+DataVolumeReportExtensions RANAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+RAB-FailedtoReportList ::= RAB-IE-ContainerList { {RABs-failed-to-reportItemIEs} }
+
+RABs-failed-to-reportItemIEs RANAP-PROTOCOL-IES ::= {
+ { ID id-RAB-FailedtoReportItem CRITICALITY ignore TYPE RABs-failed-to-reportItem PRESENCE mandatory },
+ ...
+}
+
+RABs-failed-to-reportItem::= SEQUENCE {
+ rAB-ID RAB-ID,
+ cause Cause,
+ iE-Extensions ProtocolExtensionContainer { { RABs-failed-to-reportItem-ExtIEs} } OPTIONAL,
+ ...
+}
+
+
+RABs-failed-to-reportItem-ExtIEs RANAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+
+-- **************************************************************
+--
+-- RESET ELEMENTARY PROCEDURE
+--
+-- **************************************************************
+
+-- **************************************************************
+--
+-- Reset
+--
+-- **************************************************************
+
+Reset ::= SEQUENCE {
+ protocolIEs ProtocolIE-Container { {ResetIEs} },
+ protocolExtensions ProtocolExtensionContainer { {ResetExtensions} } OPTIONAL,
+ ...
+}
+
+ResetIEs RANAP-PROTOCOL-IES ::= {
+ { ID id-Cause CRITICALITY ignore TYPE Cause PRESENCE mandatory } |
+ { ID id-CN-DomainIndicator CRITICALITY reject TYPE CN-DomainIndicator PRESENCE mandatory } |
+ { ID id-GlobalRNC-ID CRITICALITY ignore TYPE GlobalRNC-ID PRESENCE conditional
+ -- This IE is always used in the uplink direction -- },
+ ...
+}
+
+ResetExtensions RANAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+-- **************************************************************
+--
+-- Reset Acknowledge
+--
+-- **************************************************************
+
+ResetAcknowledge ::= SEQUENCE {
+ protocolIEs ProtocolIE-Container { {ResetAcknowledgeIEs} },
+ protocolExtensions ProtocolExtensionContainer { {ResetAcknowledgeExtensions} } OPTIONAL,
+ ...
+}
+
+ResetAcknowledgeIEs RANAP-PROTOCOL-IES ::= {
+ { ID id-CN-DomainIndicator CRITICALITY reject TYPE CN-DomainIndicator PRESENCE mandatory } |
+ { ID id-CriticalityDiagnostics CRITICALITY ignore TYPE CriticalityDiagnostics PRESENCE optional } |
+ { ID id-GlobalRNC-ID CRITICALITY ignore TYPE GlobalRNC-ID PRESENCE conditional
+ -- This IE is always used in the uplink direction -- },
+ ...
+}
+
+ResetAcknowledgeExtensions RANAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+-- **************************************************************
+--
+-- RESET RESOURCE ELEMENTARY PROCEDURE
+--
+-- **************************************************************
+
+
+-- **************************************************************
+--
+-- Reset Resource
+--
+-- **************************************************************
+
+ResetResource ::= SEQUENCE {
+ protocolIEs ProtocolIE-Container { {ResetResourceIEs} },
+ protocolExtensions ProtocolExtensionContainer { {ResetResourceExtensions} } OPTIONAL,
+ ...
+}
+
+ResetResourceIEs RANAP-PROTOCOL-IES ::= {
+ { ID id-CN-DomainIndicator CRITICALITY reject TYPE CN-DomainIndicator PRESENCE mandatory } |
+ { ID id-Cause CRITICALITY ignore TYPE Cause PRESENCE mandatory } |
+ { ID id-IuSigConIdList CRITICALITY ignore TYPE ResetResourceList PRESENCE mandatory } |
+ { ID id-GlobalRNC-ID CRITICALITY ignore TYPE GlobalRNC-ID PRESENCE conditional
+ -- This IE is always used in the uplink direction -- },
+ ...
+}
+
+ResetResourceList ::= IuSigConId-IE-ContainerList{ {ResetResourceItemIEs} }
+
+ResetResourceItemIEs RANAP-PROTOCOL-IES ::= {
+ { ID id-IuSigConIdItem CRITICALITY reject TYPE ResetResourceItem PRESENCE mandatory },
+ ...
+}
+
+ResetResourceItem ::= SEQUENCE {
+ iuSigConId IuSignallingConnectionIdentifier,
+ iE-Extensions ProtocolExtensionContainer { { ResetResourceItem-ExtIEs} } OPTIONAL,
+ ...
+}
+
+ResetResourceItem-ExtIEs RANAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+ResetResourceExtensions RANAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+-- **************************************************************
+--
+-- Reset Resource Acknowledge
+--
+-- **************************************************************
+
+ResetResourceAcknowledge ::= SEQUENCE {
+ protocolIEs ProtocolIE-Container { {ResetResourceAcknowledgeIEs} },
+ protocolExtensions ProtocolExtensionContainer { {ResetResourceAcknowledgeExtensions} } OPTIONAL,
+ ...
+}
+
+ResetResourceAcknowledgeIEs RANAP-PROTOCOL-IES ::= {
+ { ID id-CN-DomainIndicator CRITICALITY reject TYPE CN-DomainIndicator PRESENCE mandatory } |
+ { ID id-IuSigConIdList CRITICALITY ignore TYPE ResetResourceAckList PRESENCE mandatory } |
+ { ID id-GlobalRNC-ID CRITICALITY ignore TYPE GlobalRNC-ID PRESENCE conditional
+ -- This IE is always used in the uplink direction -- } |
+ { ID id-CriticalityDiagnostics CRITICALITY ignore TYPE CriticalityDiagnostics PRESENCE optional },
+ ...
+}
+ResetResourceAckList ::= IuSigConId-IE-ContainerList{ {ResetResourceAckItemIEs} }
+
+ResetResourceAckItemIEs RANAP-PROTOCOL-IES ::= {
+ { ID id-IuSigConIdItem CRITICALITY reject TYPE ResetResourceAckItem PRESENCE mandatory },
+ ...
+}
+
+ResetResourceAckItem ::= SEQUENCE {
+ iuSigConId IuSignallingConnectionIdentifier,
+ iE-Extensions ProtocolExtensionContainer { { ResetResourceAckItem-ExtIEs} } OPTIONAL,
+ ...
+}
+
+ResetResourceAckItem-ExtIEs RANAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+ResetResourceAcknowledgeExtensions RANAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+-- **************************************************************
+--
+-- RAB RELEASE REQUEST ELEMENTARY PROCEDURE
+--
+-- **************************************************************
+
+-- **************************************************************
+--
+-- RAB Release Request
+--
+-- **************************************************************
+
+RAB-ReleaseRequest ::= SEQUENCE {
+ protocolIEs ProtocolIE-Container { {RAB-ReleaseRequestIEs} },
+ protocolExtensions ProtocolExtensionContainer { {RAB-ReleaseRequestExtensions} } OPTIONAL,
+ ...
+}
+
+RAB-ReleaseRequestIEs RANAP-PROTOCOL-IES ::= {
+ { ID id-RAB-ReleaseList CRITICALITY ignore TYPE RAB-ReleaseList PRESENCE mandatory },
+ ...
+}
+
+RAB-ReleaseList ::= RAB-IE-ContainerList { {RAB-ReleaseItemIEs} }
+
+RAB-ReleaseItemIEs RANAP-PROTOCOL-IES ::= {
+ { ID id-RAB-ReleaseItem CRITICALITY ignore TYPE RAB-ReleaseItem PRESENCE mandatory },
+ ...
+}
+
+RAB-ReleaseItem ::= SEQUENCE {
+ rAB-ID RAB-ID,
+ cause Cause,
+ iE-Extensions ProtocolExtensionContainer { {RAB-ReleaseItem-ExtIEs} } OPTIONAL,
+ ...
+}
+
+RAB-ReleaseItem-ExtIEs RANAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+RAB-ReleaseRequestExtensions RANAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+-- **************************************************************
+--
+-- Iu RELEASE REQUEST ELEMENTARY PROCEDURE
+--
+-- **************************************************************
+
+-- **************************************************************
+--
+-- Iu Release Request
+--
+-- **************************************************************
+
+Iu-ReleaseRequest ::= SEQUENCE {
+ protocolIEs ProtocolIE-Container { {Iu-ReleaseRequestIEs} },
+ protocolExtensions ProtocolExtensionContainer { {Iu-ReleaseRequestExtensions} } OPTIONAL,
+ ...
+}
+
+Iu-ReleaseRequestIEs RANAP-PROTOCOL-IES ::= {
+ { ID id-Cause CRITICALITY ignore TYPE Cause PRESENCE mandatory },
+ ...
+}
+
+Iu-ReleaseRequestExtensions RANAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+-- **************************************************************
+--
+-- RELOCATION DETECT ELEMENTARY PROCEDURE
+--
+-- **************************************************************
+
+-- **************************************************************
+--
+-- Relocation Detect
+--
+-- **************************************************************
+
+RelocationDetect ::= SEQUENCE {
+ protocolIEs ProtocolIE-Container { {RelocationDetectIEs} },
+ protocolExtensions ProtocolExtensionContainer { {RelocationDetectExtensions} } OPTIONAL,
+ ...
+}
+
+RelocationDetectIEs RANAP-PROTOCOL-IES ::= {
+ ...
+}
+
+RelocationDetectExtensions RANAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+-- **************************************************************
+--
+-- RELOCATION COMPLETE ELEMENTARY PROCEDURE
+--
+-- **************************************************************
+
+-- **************************************************************
+--
+-- Relocation Complete
+--
+-- **************************************************************
+
+RelocationComplete ::= SEQUENCE {
+ protocolIEs ProtocolIE-Container { {RelocationCompleteIEs} },
+ protocolExtensions ProtocolExtensionContainer { {RelocationCompleteExtensions} } OPTIONAL,
+ ...
+}
+
+RelocationCompleteIEs RANAP-PROTOCOL-IES ::= {
+ ...
+}
+
+RelocationCompleteExtensions RANAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+-- **************************************************************
+--
+-- PAGING ELEMENTARY PROCEDURE
+--
+-- **************************************************************
+
+-- **************************************************************
+--
+-- Paging
+--
+-- **************************************************************
+
+Paging ::= SEQUENCE {
+ protocolIEs ProtocolIE-Container { {PagingIEs} },
+ protocolExtensions ProtocolExtensionContainer { {PagingExtensions} } OPTIONAL,
+ ...
+}
+
+PagingIEs RANAP-PROTOCOL-IES ::= {
+ { ID id-CN-DomainIndicator CRITICALITY ignore TYPE CN-DomainIndicator PRESENCE mandatory } |
+ { ID id-PermanentNAS-UE-ID CRITICALITY ignore TYPE PermanentNAS-UE-ID PRESENCE mandatory } |
+ { ID id-TemporaryUE-ID CRITICALITY ignore TYPE TemporaryUE-ID PRESENCE optional } |
+ { ID id-PagingAreaID CRITICALITY ignore TYPE PagingAreaID PRESENCE optional } |
+ { ID id-PagingCause CRITICALITY ignore TYPE PagingCause PRESENCE optional } |
+ { ID id-NonSearchingIndication CRITICALITY ignore TYPE NonSearchingIndication PRESENCE optional } |
+ { ID id-DRX-CycleLengthCoefficient CRITICALITY ignore TYPE DRX-CycleLengthCoefficient PRESENCE conditional
+ -- This IE shall be included whenever available for that UE -- } ,
+ ...
+}
+
+PagingExtensions RANAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+-- **************************************************************
+--
+-- COMMON ID ELEMENTARY PROCEDURE
+--
+-- **************************************************************
+
+-- **************************************************************
+--
+-- Common ID
+--
+-- **************************************************************
+
+CommonID ::= SEQUENCE {
+ protocolIEs ProtocolIE-Container { {CommonID-IEs} },
+ protocolExtensions ProtocolExtensionContainer { {CommonIDExtensions} } OPTIONAL,
+ ...
+}
+
+CommonID-IEs RANAP-PROTOCOL-IES ::= {
+ { ID id-PermanentNAS-UE-ID CRITICALITY ignore TYPE PermanentNAS-UE-ID PRESENCE mandatory },
+ ...
+}
+
+CommonIDExtensions RANAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+-- **************************************************************
+--
+-- CN INVOKE TRACE ELEMENTARY PROCEDURE
+--
+-- **************************************************************
+
+-- **************************************************************
+--
+-- CN Invoke Trace
+--
+-- **************************************************************
+
+CN-InvokeTrace ::= SEQUENCE {
+ protocolIEs ProtocolIE-Container { {CN-InvokeTraceIEs} },
+ protocolExtensions ProtocolExtensionContainer { {CN-InvokeTraceExtensions} } OPTIONAL,
+ ...
+}
+
+CN-InvokeTraceIEs RANAP-PROTOCOL-IES ::= {
+ { ID id-TraceType CRITICALITY ignore TYPE TraceType PRESENCE mandatory } |
+ { ID id-TraceReference CRITICALITY ignore TYPE TraceReference PRESENCE mandatory } |
+ { ID id-TriggerID CRITICALITY ignore TYPE TriggerID PRESENCE optional } |
+ { ID id-UE-ID CRITICALITY ignore TYPE UE-ID PRESENCE optional } |
+ { ID id-OMC-ID CRITICALITY ignore TYPE OMC-ID PRESENCE optional },
+ ...
+}
+
+CN-InvokeTraceExtensions RANAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+-- **************************************************************
+--
+-- CN DEACTIVATE TRACE ELEMENTARY PROCEDURE
+--
+-- **************************************************************
+
+-- **************************************************************
+--
+-- CN Deactivate Trace
+--
+-- **************************************************************
+
+CN-DeactivateTrace ::= SEQUENCE {
+ protocolIEs ProtocolIE-Container { {CN-DeactivateTraceIEs} },
+ protocolExtensions ProtocolExtensionContainer { {CN-DeactivateTraceExtensions} } OPTIONAL,
+ ...
+}
+
+CN-DeactivateTraceIEs RANAP-PROTOCOL-IES ::= {
+ { ID id-TraceReference CRITICALITY ignore TYPE TraceReference PRESENCE mandatory } |
+ { ID id-TriggerID CRITICALITY ignore TYPE TriggerID PRESENCE optional },
+ ...
+}
+
+CN-DeactivateTraceExtensions RANAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+-- **************************************************************
+--
+-- LOCATION REPORTING CONTROL ELEMENTARY PROCEDURE
+--
+-- **************************************************************
+
+-- **************************************************************
+--
+-- Location Reporting Control
+--
+-- **************************************************************
+
+LocationReportingControl ::= SEQUENCE {
+ protocolIEs ProtocolIE-Container { {LocationReportingControlIEs} },
+ protocolExtensions ProtocolExtensionContainer { {LocationReportingControlExtensions} } OPTIONAL,
+ ...
+}
+
+LocationReportingControlIEs RANAP-PROTOCOL-IES ::= {
+ { ID id-RequestType CRITICALITY ignore TYPE RequestType PRESENCE mandatory },
+ ...
+}
+
+LocationReportingControlExtensions RANAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+-- **************************************************************
+--
+-- LOCATION REPORT ELEMENTARY PROCEDURE
+--
+-- **************************************************************
+
+-- **************************************************************
+--
+-- Location Report
+--
+-- **************************************************************
+
+LocationReport ::= SEQUENCE {
+ protocolIEs ProtocolIE-Container { {LocationReportIEs} },
+ protocolExtensions ProtocolExtensionContainer { {LocationReportExtensions} } OPTIONAL,
+ ...
+}
+
+LocationReportIEs RANAP-PROTOCOL-IES ::= {
+ { ID id-AreaIdentity CRITICALITY ignore TYPE AreaIdentity PRESENCE optional } |
+ { ID id-Cause CRITICALITY ignore TYPE Cause PRESENCE optional } |
+ { ID id-RequestType CRITICALITY ignore TYPE RequestType PRESENCE conditional
+ -- This IE shall be present when Cause IE is present and has value "Requested Report Type not supported" --} ,
+ ...
+}
+
+LocationReportExtensions RANAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+-- **************************************************************
+--
+-- INITIAL UE MESSAGE ELEMENTARY PROCEDURE
+--
+-- **************************************************************
+
+-- **************************************************************
+--
+-- Initial UE Message
+--
+-- **************************************************************
+
+InitialUE-Message ::= SEQUENCE {
+ protocolIEs ProtocolIE-Container { {InitialUE-MessageIEs} },
+ protocolExtensions ProtocolExtensionContainer { {InitialUE-MessageExtensions} } OPTIONAL,
+ ...
+}
+
+InitialUE-MessageIEs RANAP-PROTOCOL-IES ::= {
+ { ID id-CN-DomainIndicator CRITICALITY ignore TYPE CN-DomainIndicator PRESENCE mandatory } |
+ { ID id-LAI CRITICALITY ignore TYPE LAI PRESENCE mandatory } |
+ { ID id-RAC CRITICALITY ignore TYPE RAC PRESENCE conditional
+ -- This IE is only present for RABs towards the PS domain -- } |
+ { ID id-SAI CRITICALITY ignore TYPE SAI PRESENCE mandatory } |
+ { ID id-NAS-PDU CRITICALITY ignore TYPE NAS-PDU PRESENCE mandatory } |
+ { ID id-IuSigConId CRITICALITY ignore TYPE IuSignallingConnectionIdentifier PRESENCE mandatory } |
+ { ID id-GlobalRNC-ID CRITICALITY ignore TYPE GlobalRNC-ID PRESENCE mandatory },
+
+ ...
+}
+
+InitialUE-MessageExtensions RANAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+-- **************************************************************
+--
+-- DIRECT TRANSFER ELEMENTARY PROCEDURE
+--
+-- **************************************************************
+
+-- **************************************************************
+--
+-- Direct Transfer
+--
+-- **************************************************************
+
+DirectTransfer ::= SEQUENCE {
+ protocolIEs ProtocolIE-Container { {DirectTransferIEs} },
+ protocolExtensions ProtocolExtensionContainer { {DirectTransferExtensions} } OPTIONAL,
+ ...
+}
+
+DirectTransferIEs RANAP-PROTOCOL-IES ::= {
+ { ID id-NAS-PDU CRITICALITY ignore TYPE NAS-PDU PRESENCE mandatory } |
+ { ID id-LAI CRITICALITY ignore TYPE LAI PRESENCE conditional
+ -- This IE is only present if the message is directed to the PS domain -- } |
+ { ID id-RAC CRITICALITY ignore TYPE RAC PRESENCE conditional
+ -- This IE is only present if the message is directed to the PS domain -- } |
+ { ID id-SAI CRITICALITY ignore TYPE SAI PRESENCE conditional
+ -- This IE is only present if the message is directed to the PS domain -- } |
+ { ID id-SAPI CRITICALITY ignore TYPE SAPI PRESENCE conditional
+ -- This IE is always used in downlink direction-- },
+ ...
+}
+
+DirectTransferExtensions RANAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+-- **************************************************************
+--
+-- OVERLOAD CONTROL ELEMENTARY PROCEDURE
+--
+-- **************************************************************
+
+-- **************************************************************
+--
+-- Overload
+--
+-- **************************************************************
+
+Overload ::= SEQUENCE {
+ protocolIEs ProtocolIE-Container { {OverloadIEs} },
+ protocolExtensions ProtocolExtensionContainer { {OverloadExtensions} } OPTIONAL,
+ ...
+}
+
+OverloadIEs RANAP-PROTOCOL-IES ::= {
+ { ID id-NumberOfSteps CRITICALITY ignore TYPE NumberOfSteps PRESENCE optional } |
+ { ID id-GlobalRNC-ID CRITICALITY ignore TYPE GlobalRNC-ID PRESENCE conditional
+ -- This IE is always used in the uplink direction -- },
+ ...
+}
+
+OverloadExtensions RANAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+-- **************************************************************
+--
+-- ERROR INDICATION ELEMENTARY PROCEDURE
+--
+-- **************************************************************
+
+-- **************************************************************
+--
+-- Error Indication
+--
+-- **************************************************************
+
+ErrorIndication ::= SEQUENCE {
+ protocolIEs ProtocolIE-Container { {ErrorIndicationIEs} },
+ protocolExtensions ProtocolExtensionContainer { {ErrorIndicationExtensions} } OPTIONAL,
+ ...
+}
+
+ErrorIndicationIEs RANAP-PROTOCOL-IES ::= {
+ { ID id-Cause CRITICALITY ignore TYPE Cause PRESENCE conditional
+ -- At least either of Cause IE or Criticality IE shall be present -- } |
+ { ID id-CriticalityDiagnostics CRITICALITY ignore TYPE CriticalityDiagnostics PRESENCE conditional
+ -- At least either of Cause IE or Criticality IE shall be present -- } |
+ { ID id-CN-DomainIndicator CRITICALITY ignore TYPE CN-DomainIndicator PRESENCE optional } |
+ { ID id-GlobalRNC-ID CRITICALITY ignore TYPE GlobalRNC-ID PRESENCE conditional
+ -- This IE is always used in the uplink direction when message is sent connectionless -- },
+ ...
+}
+
+ErrorIndicationExtensions RANAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+-- **************************************************************
+--
+-- SRNS DATA FORWARD ELEMENTARY PROCEDURE
+--
+-- **************************************************************
+
+-- **************************************************************
+--
+-- SRNS Data Forward Command
+--
+-- **************************************************************
+
+SRNS-DataForwardCommand ::= SEQUENCE {
+ protocolIEs ProtocolIE-Container { {SRNS-DataForwardCommandIEs} },
+ protocolExtensions ProtocolExtensionContainer { {SRNS-DataForwardCommandExtensions} } OPTIONAL,
+ ...
+}
+
+SRNS-DataForwardCommandIEs RANAP-PROTOCOL-IES ::= {
+ { ID id-RAB-DataForwardingList CRITICALITY ignore TYPE RAB-DataForwardingList PRESENCE conditional
+ -- This group is only present for RABs towards the PS domain -- },
+ ...
+}
+
+SRNS-DataForwardCommandExtensions RANAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+-- **************************************************************
+--
+-- FORWARD SRNS CONTEXT ELEMENTARY PROCEDURE
+--
+-- **************************************************************
+
+-- **************************************************************
+--
+-- Forward SRNS Context
+--
+-- **************************************************************
+
+ForwardSRNS-Context ::= SEQUENCE {
+ protocolIEs ProtocolIE-Container { {ForwardSRNS-ContextIEs} },
+ protocolExtensions ProtocolExtensionContainer { {ForwardSRNS-ContextExtensions} } OPTIONAL,
+ ...
+}
+
+ForwardSRNS-ContextIEs RANAP-PROTOCOL-IES ::= {
+ { ID id-RAB-ContextList CRITICALITY ignore TYPE RAB-ContextList PRESENCE mandatory },
+ ...
+}
+
+ForwardSRNS-ContextExtensions RANAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+-- **************************************************************
+--
+-- RAB ASSIGNMENT ELEMENTARY PROCEDURE
+--
+-- **************************************************************
+
+-- **************************************************************
+--
+-- RAB Assignment Request
+--
+-- **************************************************************
+
+RAB-AssignmentRequest ::= SEQUENCE {
+ protocolIEs ProtocolIE-Container { {RAB-AssignmentRequestIEs} },
+ protocolExtensions ProtocolExtensionContainer { {RAB-AssignmentRequestExtensions} } OPTIONAL,
+ ...
+}
+
+RAB-AssignmentRequestIEs RANAP-PROTOCOL-IES ::= {
+ { ID id-RAB-SetupOrModifyList CRITICALITY ignore TYPE RAB-SetupOrModifyList PRESENCE conditional
+ -- This group must be present at least when no other group is present, ie. at least one group must be present -- } |
+ { ID id-RAB-ReleaseList CRITICALITY ignore TYPE RAB-ReleaseList PRESENCE conditional
+ -- This group must be present at least when no other group is present, ie. at least one group must be present -- },
+ ...
+}
+
+RAB-SetupOrModifyList ::= RAB-IE-ContainerPairList { {RAB-SetupOrModifyItem-IEs} }
+
+RAB-SetupOrModifyItem-IEs RANAP-PROTOCOL-IES-PAIR ::= {
+ { ID id-RAB-SetupOrModifyItem FIRST CRITICALITY reject FIRST TYPE RAB-SetupOrModifyItemFirst
+ SECOND CRITICALITY ignore SECOND TYPE RAB-SetupOrModifyItemSecond
+ PRESENCE mandatory },
+ ...
+}
+
+RAB-SetupOrModifyItemFirst ::= SEQUENCE {
+ rAB-ID RAB-ID,
+ nAS-SynchronisationIndicator NAS-SynchronisationIndicator OPTIONAL
+ -- This IE is present at a RAB modification if the relevant NAS information is provided by the CN --,
+ rAB-Parameters RAB-Parameters OPTIONAL
+ -- This IE is present at a RAB establishment or when any previously set value shall be modified at a RAB modification --,
+ userPlaneInformation UserPlaneInformation OPTIONAL
+ -- This IE is present at a RAB establishment or when any previously set value shall be modified at a RAB modification --,
+ transportLayerInformation TransportLayerInformation OPTIONAL
+ -- This IE is present at a RAB establishment, and may be present at a RAB modification if at least one more IE than the RAB ID IE and the NAS Syncronisation Indicator IE is also included --,
+ service-Handover Service-Handover OPTIONAL,
+ iE-Extensions ProtocolExtensionContainer { {RAB-SetupOrModifyItemFirst-ExtIEs} } OPTIONAL,
+ ...
+}
+
+TransportLayerInformation ::= SEQUENCE {
+ transportLayerAddress TransportLayerAddress,
+ iuTransportAssociation IuTransportAssociation,
+ iE-Extensions ProtocolExtensionContainer { {TransportLayerInformation-ExtIEs} } OPTIONAL,
+ ...
+}
+
+TransportLayerInformation-ExtIEs RANAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+RAB-SetupOrModifyItemFirst-ExtIEs RANAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+RAB-SetupOrModifyItemSecond ::= SEQUENCE {
+ pDP-TypeInformation PDP-TypeInformation OPTIONAL
+ -- This IE is only present for RABs towards the PS domain at RAB establishment --,
+ dataVolumeReportingIndication DataVolumeReportingIndication OPTIONAL
+ -- This IE, if applicable, is only present for RABs towards the PS domain at RAB establishment --,
+ dl-GTP-PDU-SequenceNumber DL-GTP-PDU-SequenceNumber OPTIONAL
+ -- This IE, if available, is only present for RABs towards the PS domain at RAB establishment --,
+ ul-GTP-PDU-SequenceNumber UL-GTP-PDU-SequenceNumber OPTIONAL
+ -- This IE, if available, is only present for RABs towards the PS domain at RAB establishment --,
+ dl-N-PDU-SequenceNumber DL-N-PDU-SequenceNumber OPTIONAL
+ -- This IE, if available, is only present for RABs towards the PS domain at RAB establishment --,
+ ul-N-PDU-SequenceNumber UL-N-PDU-SequenceNumber OPTIONAL
+ -- This IE, if available, is only present for RABs towards the PS domain at RAB establishment --,
+ iE-Extensions ProtocolExtensionContainer { {RAB-SetupOrModifyItemSecond-ExtIEs} } OPTIONAL,
+ ...
+}
+
+RAB-SetupOrModifyItemSecond-ExtIEs RANAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+RAB-AssignmentRequestExtensions RANAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+-- **************************************************************
+--
+-- RAB Assignment Response
+--
+-- **************************************************************
+
+RAB-AssignmentResponse ::= SEQUENCE {
+ protocolIEs ProtocolIE-Container { {RAB-AssignmentResponseIEs} },
+ protocolExtensions ProtocolExtensionContainer { {RAB-AssignmentResponseExtensions} } OPTIONAL,
+ ...
+}
+
+RAB-AssignmentResponseIEs RANAP-PROTOCOL-IES ::= {
+ { ID id-RAB-SetupOrModifiedList CRITICALITY ignore TYPE RAB-SetupOrModifiedList PRESENCE conditional
+ -- This group must be present at least when no other group is present, ie. at least one group must be present -- } |
+ { ID id-RAB-ReleasedList CRITICALITY ignore TYPE RAB-ReleasedList PRESENCE conditional
+ -- This group must be present at least when no other group is present, ie. at least one group must be present -- } |
+
+ { ID id-RAB-QueuedList CRITICALITY ignore TYPE RAB-QueuedList PRESENCE conditional
+ -- This group must be present at least when no other group is present, ie. at least one group must be present -- } |
+ { ID id-RAB-FailedList CRITICALITY ignore TYPE RAB-FailedList PRESENCE conditional
+ -- This group must be present at least when no other group is present, ie. at least one group must be present -- } |
+ { ID id-RAB-ReleaseFailedList CRITICALITY ignore TYPE RAB-ReleaseFailedList PRESENCE conditional
+ -- This group must be present at least when no other group is present, ie. at least one group must be present -- } |
+ { ID id-CriticalityDiagnostics CRITICALITY ignore TYPE CriticalityDiagnostics PRESENCE optional },
+ ...
+}
+
+RAB-SetupOrModifiedList ::= RAB-IE-ContainerList { {RAB-SetupOrModifiedItemIEs} }
+
+RAB-SetupOrModifiedItemIEs RANAP-PROTOCOL-IES ::= {
+ { ID id-RAB-SetupOrModifiedItem CRITICALITY ignore TYPE RAB-SetupOrModifiedItem PRESENCE mandatory },
+ ...
+}
+
+RAB-SetupOrModifiedItem ::= SEQUENCE {
+ rAB-ID RAB-ID,
+ transportLayerAddress TransportLayerAddress OPTIONAL
+ -- This IE is only present for RABs towards the PS domain --,
+ iuTransportAssociation IuTransportAssociation OPTIONAL
+ -- This IE is only present for RABs towards the PS domain --,
+ dl-dataVolumes DataVolumeList OPTIONAL
+ -- This IE is only present if the RAB has been modified and --
+ -- RAB data volume reporting for PS domain is required --,
+ iE-Extensions ProtocolExtensionContainer { {RAB-SetupOrModifiedItem-ExtIEs} } OPTIONAL,
+ ...
+}
+
+RAB-SetupOrModifiedItem-ExtIEs RANAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+RAB-ReleasedList ::= RAB-IE-ContainerList { {RAB-ReleasedItemIEs} }
+
+RAB-ReleasedItemIEs RANAP-PROTOCOL-IES ::= {
+ { ID id-RAB-ReleasedItem CRITICALITY ignore TYPE RAB-ReleasedItem PRESENCE mandatory },
+ ...
+}
+
+RAB-ReleasedItem ::= SEQUENCE {
+ rAB-ID RAB-ID,
+ dl-dataVolumes DataVolumeList OPTIONAL
+ -- This IE is only present if data volume reporting for PS domain is required --,
+ dL-GTP-PDU-SequenceNumber DL-GTP-PDU-SequenceNumber OPTIONAL
+ -- This IE is only present for RABs towards the PS domain when available and when the release is UTRAN initiated -- ,
+ uL-GTP-PDU-SequenceNumber UL-GTP-PDU-SequenceNumber OPTIONAL
+ -- This IE is only present for RABs towards the PS domain when available and when the release is UTRAN initiated -- ,
+ iE-Extensions ProtocolExtensionContainer { {RAB-ReleasedItem-ExtIEs} } OPTIONAL,
+ ...
+}
+
+RAB-ReleasedItem-ExtIEs RANAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+DataVolumeList ::= SEQUENCE (SIZE (1..maxNrOfVol)) OF
+ SEQUENCE {
+ dl-UnsuccessfullyTransmittedDataVolume UnsuccessfullyTransmittedDataVolume,
+ dataVolumeReference DataVolumeReference OPTIONAL,
+ iE-Extensions ProtocolExtensionContainer { {DataVolumeList-ExtIEs} } OPTIONAL,
+ ...
+ }
+
+DataVolumeList-ExtIEs RANAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+RAB-QueuedList ::= RAB-IE-ContainerList { {RAB-QueuedItemIEs} }
+
+RAB-QueuedItemIEs RANAP-PROTOCOL-IES ::= {
+ { ID id-RAB-QueuedItem CRITICALITY ignore TYPE RAB-QueuedItem PRESENCE mandatory },
+ ...
+}
+
+RAB-QueuedItem ::= SEQUENCE {
+ rAB-ID RAB-ID,
+ iE-Extensions ProtocolExtensionContainer { {RAB-QueuedItem-ExtIEs} } OPTIONAL,
+ ...
+}
+
+RAB-QueuedItem-ExtIEs RANAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+RAB-ReleaseFailedList ::= RAB-FailedList
+
+RAB-AssignmentResponseExtensions RANAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+-- **************************************************************
+--
+-- PRIVATE MESSAGE
+--
+-- **************************************************************
+
+PrivateMessage ::= SEQUENCE {
+ privateIEs PrivateIE-Container { {PrivateMessage-IEs } },
+ ...
+}
+
+PrivateMessage-IEs RANAP-PRIVATE-IES ::= {
+ ...
+}
+
+-- **************************************************************
+--
+-- RANAP RELOCATION INFORMATION ELEMENTARY PROCEDURE
+--
+-- **************************************************************
+
+RANAP-RelocationInformation ::= SEQUENCE {
+ protocolIEs ProtocolIE-Container { {RANAP-RelocationInformationIEs} },
+ protocolExtensions ProtocolExtensionContainer { {RANAP-RelocationInformationExtensions} } OPTIONAL,
+ ...
+}
+
+RANAP-RelocationInformationIEs RANAP-PROTOCOL-IES ::= {
+ { ID id-DirectTransferInformationList-RANAP-RelocInf
+ CRITICALITY ignore TYPE DirectTransferInformationList-RANAP-RelocInf
+ PRESENCE optional } |
+ { ID id-RAB-ContextList-RANAP-RelocInf CRITICALITY ignore TYPE RAB-ContextList-RANAP-RelocInf PRESENCE optional },
+ ...
+}
+
+DirectTransferInformationList-RANAP-RelocInf ::= DirectTransfer-IE-ContainerList { {DirectTransferInformationItemIEs-RANAP-RelocInf} }
+
+DirectTransferInformationItemIEs-RANAP-RelocInf RANAP-PROTOCOL-IES ::= {
+ { ID id-DirectTransferInformationItem-RANAP-RelocInf
+ CRITICALITY ignore TYPE DirectTransferInformationItem-RANAP-RelocInf
+ PRESENCE mandatory },
+ ...
+}
+
+DirectTransferInformationItem-RANAP-RelocInf ::= SEQUENCE {
+ nAS-PDU NAS-PDU,
+ sAPI SAPI,
+ cN-DomainIndicator CN-DomainIndicator,
+ iE-Extensions ProtocolExtensionContainer { {RANAP-DirectTransferInformationItem-ExtIEs-RANAP-RelocInf} } OPTIONAL,
+ ...
+}
+
+RANAP-DirectTransferInformationItem-ExtIEs-RANAP-RelocInf RANAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+RAB-ContextList-RANAP-RelocInf ::= RAB-IE-ContainerList { {RAB-ContextItemIEs-RANAP-RelocInf} }
+
+RAB-ContextItemIEs-RANAP-RelocInf RANAP-PROTOCOL-IES ::= {
+ { ID id-RAB-ContextItem-RANAP-RelocInf CRITICALITY ignore TYPE RAB-ContextItem-RANAP-RelocInf PRESENCE mandatory },
+ ...
+}
+
+RAB-ContextItem-RANAP-RelocInf ::= SEQUENCE {
+ rAB-ID RAB-ID,
+ dl-GTP-PDU-SequenceNumber DL-GTP-PDU-SequenceNumber OPTIONAL
+ --This IE is only present when available--,
+ ul-GTP-PDU-SequenceNumber UL-GTP-PDU-SequenceNumber OPTIONAL
+ --This IE is only present when available--,
+ dl-N-PDU-SequenceNumber DL-N-PDU-SequenceNumber OPTIONAL
+ --This IE is only present when available--,
+ ul-N-PDU-SequenceNumber UL-N-PDU-SequenceNumber OPTIONAL
+ --This IE is only present when available--,
+ iE-Extensions ProtocolExtensionContainer { {RAB-ContextItem-ExtIEs-RANAP-RelocInf} } OPTIONAL,
+ ...
+}
+
+RAB-ContextItem-ExtIEs-RANAP-RelocInf RANAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+RANAP-RelocationInformationExtensions RANAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+
+-- **************************************************************
+--
+-- Information Element Definitions
+--
+-- **************************************************************
+
+--BEGIN_3
+
+
+-- A
+
+AllocationOrRetentionPriority ::= SEQUENCE {
+ priorityLevel PriorityLevel,
+ pre-emptionCapability Pre-emptionCapability,
+ pre-emptionVulnerability Pre-emptionVulnerability,
+ queuingAllowed QueuingAllowed,
+ iE-Extensions ProtocolExtensionContainer { {AllocationOrRetentionPriority-ExtIEs} } OPTIONAL,
+ ...
+}
+
+AllocationOrRetentionPriority-ExtIEs RANAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+AreaIdentity ::= CHOICE {
+ sAI SAI,
+ geographicalArea GeographicalArea,
+ ...
+}
+
+-- B
+
+BindingID ::= OCTET STRING (SIZE (4))
+
+-- C
+
+
+Cause ::= CHOICE {
+ radioNetwork CauseRadioNetwork,
+ transmissionNetwork CauseTransmissionNetwork,
+ nAS CauseNAS,
+ protocol CauseProtocol,
+ misc CauseMisc,
+ non-Standard CauseNon-Standard,
+ ...
+}
+
+CauseMisc ::= INTEGER {
+ om-intervention (113),
+ no-resource-available (114),
+ unspecified-failure (115),
+ network-optimisation (116)
+} (113..128)
+
+CauseNAS ::= INTEGER {
+ user-restriction-start-indication (81),
+ user-restriction-end-indication (82),
+ normal-release (83)
+} (81..96)
+
+CauseProtocol ::= INTEGER {
+ transfer-syntax-error (97),
+ semantic-error (98),
+ message-not-compatible-with-receiver-state (99),
+ abstract-syntax-error-reject (100),
+ abstract-syntax-error-ignore-and-notify (101),
+ abstract-syntax-error-falsely-constructed-message (102)
+
+} (97..112)
+
+CauseRadioNetwork ::= INTEGER {
+ rab-pre-empted (1),
+ trelocoverall-expiry (2),
+ trelocprep-expiry (3),
+ treloccomplete-expiry (4),
+ tqueing-expiry (5),
+ relocation-triggered (6),
+ trellocalloc-expiry(7),
+ unable-to-establish-during-relocation (8),
+ unknown-target-rnc (9),
+ relocation-cancelled (10),
+ successful-relocation (11),
+ requested-ciphering-and-or-integrity-protection-algorithms-not-supported (12),
+ change-of-ciphering-and-or-integrity-protection-is-not-supported (13),
+ failure-in-the-radio-interface-procedure (14),
+ release-due-to-utran-generated-reason (15),
+ user-inactivity (16),
+ time-critical-relocation (17),
+ requested-traffic-class-not-available (18),
+ invalid-rab-parameters-value (19),
+ requested-maximum-bit-rate-not-available (20),
+ requested-guaranteed-bit-rate-not-available (21),
+ requested-transfer-delay-not-achievable (22),
+ invalid-rab-parameters-combination (23),
+ condition-violation-for-sdu-parameters (24),
+ condition-violation-for-traffic-handling-priority (25),
+ condition-violation-for-guaranteed-bit-rate (26),
+ user-plane-versions-not-supported (27),
+ iu-up-failure (28),
+ relocation-failure-in-target-CN-RNC-or-target-system(29),
+ invalid-RAB-ID (30),
+ no-remaining-rab (31),
+ interaction-with-other-procedure (32),
+ requested-maximum-bit-rate-for-dl-not-available (33),
+ requested-maximum-bit-rate-for-ul-not-available (34),
+ requested-guaranteed-bit-rate-for-dl-not-available (35),
+ requested-guaranteed-bit-rate-for-ul-not-available (36),
+ repeated-integrity-checking-failure (37),
+ requested-report-type-not-supported (38),
+ request-superseded (39),
+ release-due-to-UE-generated-signalling-connection-release (40),
+ resource-optimisation-relocation (41),
+ requested-information-not-available (42),
+ relocation-desirable-for-radio-reasons (43),
+ relocation-not-supported-in-target-RNC-or-target-system (44),
+ directed-retry (45),
+ radio-connection-with-UE-Lost (46)
+} (1..64)
+
+CauseNon-Standard ::= INTEGER (129..256)
+
+CauseTransmissionNetwork ::= INTEGER {
+ signalling-transport-resource-failure (65),
+ iu-transport-connection-failed-to-establish (66)
+} (65..80)
+
+
+CriticalityDiagnostics ::= SEQUENCE {
+ procedureCode ProcedureCode OPTIONAL,
+ triggeringMessage TriggeringMessage OPTIONAL,
+ procedureCriticality Criticality OPTIONAL,
+ iEsCriticalityDiagnostics CriticalityDiagnostics-IE-List OPTIONAL,
+ iE-Extensions ProtocolExtensionContainer { {CriticalityDiagnostics-ExtIEs} } OPTIONAL,
+ ...
+}
+
+CriticalityDiagnostics-ExtIEs RANAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+CriticalityDiagnostics-IE-List ::= SEQUENCE (SIZE (1..maxNrOfErrors)) OF
+ SEQUENCE {
+ iECriticality Criticality,
+ iE-ID ProtocolIE-ID,
+ repetitionNumber RepetitionNumber OPTIONAL,
+ iE-Extensions ProtocolExtensionContainer { {CriticalityDiagnostics-IE-List-ExtIEs} } OPTIONAL,
+ ...
+ }
+
+CriticalityDiagnostics-IE-List-ExtIEs RANAP-PROTOCOL-EXTENSION ::= {
+ { ID id-MessageStructure CRITICALITY ignore EXTENSION MessageStructure PRESENCE optional },
+ ...
+}
+
+MessageStructure ::= SEQUENCE (SIZE (1..maxNrOfLevels)) OF
+ SEQUENCE {
+ iE-ID ProtocolIE-ID,
+ repetitionNumber RepetitionNumber OPTIONAL,
+ iE-Extensions ProtocolExtensionContainer { {MessageStructure-ExtIEs} } OPTIONAL,
+ ...
+ }
+
+
+MessageStructure-ExtIEs RANAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+CGI ::= SEQUENCE {
+ pLMN-ID PLMN-ID,
+ lAC LAC,
+ cI CI,
+ iE-Extensions ProtocolExtensionContainer { {CGI-ExtIEs} } OPTIONAL
+}
+
+CGI-ExtIEs RANAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+ChosenEncryptionAlgorithm ::= EncryptionAlgorithm
+
+ChosenIntegrityProtectionAlgorithm ::= IntegrityProtectionAlgorithm
+
+CI ::= OCTET STRING (SIZE (2))
+
+ClassmarkInformation2 ::= OCTET STRING
+
+ClassmarkInformation3 ::= OCTET STRING
+
+CN-DomainIndicator ::= ENUMERATED {
+ cs-domain,
+ ps-domain
+}
+
+
+
+-- D
+
+DataVolumeReference ::= INTEGER (0..255)
+
+DataVolumeReportingIndication ::= ENUMERATED {
+ do-report,
+ do-not-report
+}
+
+DCH-ID ::= INTEGER (0..255)
+
+DeliveryOfErroneousSDU ::= ENUMERATED {
+ yes,
+ no,
+ no-error-detection-consideration
+}
+
+DeliveryOrder::= ENUMERATED {
+ delivery-order-requested,
+ delivery-order-not-requested
+}
+
+DL-GTP-PDU-SequenceNumber ::= INTEGER (0..65535)
+-- Reference: xx.xxx
+
+DL-N-PDU-SequenceNumber ::= INTEGER (0..65535)
+-- Reference: xx.xxx
+
+D-RNTI ::= INTEGER (0..1048575)
+
+DRX-CycleLengthCoefficient ::= INTEGER (6..9)
+
+DSCH-ID ::= INTEGER (0..255)
+
+-- E
+
+EncryptionAlgorithm ::= INTEGER { no-encryption (0), standard-UMTS-encryption-algorith-UEA1 (1) } (0..15)
+
+EncryptionInformation ::= SEQUENCE {
+ permittedAlgorithms PermittedEncryptionAlgorithms,
+ key EncryptionKey,
+ iE-Extensions ProtocolExtensionContainer { {EncryptionInformation-ExtIEs} } OPTIONAL
+}
+
+EncryptionInformation-ExtIEs RANAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+EncryptionKey ::= BIT STRING (SIZE (128))
+-- Reference: 33.102
+
+Event ::= ENUMERATED {
+ stop,
+ direct,
+ change-of-servicearea,
+ ...
+}
+
+-- F
+-- G
+
+GeographicalArea ::= CHOICE {
+ point GA-Point,
+ pointWithUnCertainty GA-PointWithUnCertainty,
+ polygon GA-Polygon,
+ ...
+}
+
+GeographicalCoordinates ::= SEQUENCE {
+ latitudeSign ENUMERATED { north, south },
+ latitude INTEGER (0..8388607),
+ longitude INTEGER (-8388608..8388607),
+ iE-Extensions ProtocolExtensionContainer { {GeographicalCoordinates-ExtIEs} } OPTIONAL,
+ ...
+}
+
+GeographicalCoordinates-ExtIEs RANAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+GA-Point ::= SEQUENCE {
+ geographicalCoordinates GeographicalCoordinates,
+ iE-Extensions ProtocolExtensionContainer { {GA-Point-ExtIEs} } OPTIONAL,
+ ...
+}
+
+GA-Point-ExtIEs RANAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+GA-PointWithUnCertainty ::=SEQUENCE {
+ geographicalCoordinates GeographicalCoordinates,
+ iE-Extensions ProtocolExtensionContainer { {GA-PointWithUnCertainty-ExtIEs} } OPTIONAL,
+ uncertaintyCode INTEGER (0..127)
+}
+
+GA-PointWithUnCertainty-ExtIEs RANAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+GA-Polygon ::= SEQUENCE (SIZE (1..maxNrOfPoints)) OF
+ SEQUENCE {
+ geographicalCoordinates GeographicalCoordinates,
+ iE-Extensions ProtocolExtensionContainer { {GA-Polygon-ExtIEs} } OPTIONAL,
+ ...
+ }
+
+GA-Polygon-ExtIEs RANAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+GlobalRNC-ID ::= SEQUENCE {
+ pLMN-ID PLMN-ID,
+ rNC-ID RNC-ID
+}
+
+GTP-TEI ::= OCTET STRING (SIZE (4))
+-- Reference: xx.xxx
+
+GuaranteedBitrate ::= INTEGER (0..16000000)
+-- Unit is bits per sec
+
+-- H
+
+-- I
+
+
+IMEI ::= OCTET STRING (SIZE (8))
+-- Reference: 23.003
+
+IMSI ::= TBCD-STRING (SIZE (3..8))
+-- Reference: 23.003
+
+IntegrityProtectionAlgorithm ::= INTEGER { standard-UMTS-integrity-algorithm-UIA1 (0) } (0..15)
+
+IntegrityProtectionInformation ::= SEQUENCE {
+ permittedAlgorithms PermittedIntegrityProtectionAlgorithms,
+ key IntegrityProtectionKey,
+ iE-Extensions ProtocolExtensionContainer { {IntegrityProtectionInformation-ExtIEs} } OPTIONAL
+}
+
+IntegrityProtectionInformation-ExtIEs RANAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+IntegrityProtectionKey ::= BIT STRING (SIZE (128))
+
+IuSignallingConnectionIdentifier ::= BIT STRING (SIZE (24))
+
+IuTransportAssociation ::= CHOICE {
+ gTP-TEI GTP-TEI,
+ bindingID BindingID,
+ ...
+}
+
+-- J
+-- K
+
+KeyStatus ::= ENUMERATED {
+ old,
+ new,
+ ...
+}
+-- L
+
+LAC ::= OCTET STRING (SIZE (2))
+
+LAI ::= SEQUENCE {
+ pLMN-ID PLMN-ID,
+ lAC LAC,
+ iE-Extensions ProtocolExtensionContainer { {LAI-ExtIEs} } OPTIONAL
+}
+
+LAI-ExtIEs RANAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+L3-Information ::= OCTET STRING
+
+-- M
+
+MaxBitrate ::= INTEGER (1..16000000)
+-- Unit is bits per sec
+
+MaxSDU-Size ::= INTEGER (0..32768)
+-- MaxSDU-Size
+-- Unit is bit
+
+MCC ::= TBCD-STRING (SIZE (2))
+-- Reference: 24.008
+
+MNC ::= TBCD-STRING (SIZE (2))
+-- Reference: 24.008
+
+-- N
+
+
+NAS-PDU ::= OCTET STRING
+
+NAS-SynchronisationIndicator ::= BIT STRING (SIZE (4))
+
+NonSearchingIndication ::= ENUMERATED {
+ non-searching,
+ searching
+}
+
+NumberOfIuInstances ::= INTEGER (1..2)
+
+NumberOfSteps ::= INTEGER (1..16)
+
+-- O
+
+OldBSS-ToNewBSS-Information ::= OCTET STRING
+
+OMC-ID ::= OCTET STRING (SIZE (3..22))
+-- Reference: GSM TS 12.20
+
+-- P
+
+PagingAreaID ::= CHOICE {
+ lAI LAI,
+ rAI RAI,
+ ...
+}
+
+PagingCause ::= ENUMERATED {
+ terminating-conversational-call,
+ terminating-streaming-call,
+ terminating-interactive-call,
+ terminating-background-call,
+ terminating-low-priority-signalling,
+ ...,
+ terminating-high-priority-signalling
+}
+
+PDP-TypeInformation ::= SEQUENCE (SIZE (1..maxNrOfPDPDirections)) OF
+ PDP-Type
+
+PDP-Type ::= ENUMERATED {
+ empty,
+ ppp,
+ osp-ihoss -- this value shall not be used -- ,
+ ipv4,
+ ipv6,
+ ...
+}
+
+PermanentNAS-UE-ID ::= CHOICE {
+ iMSI IMSI,
+ ...
+}
+
+PermittedEncryptionAlgorithms ::= SEQUENCE (SIZE (1..16)) OF
+ EncryptionAlgorithm
+
+PermittedIntegrityProtectionAlgorithms ::= SEQUENCE (SIZE (1..16)) OF
+ IntegrityProtectionAlgorithm
+
+PLMN-ID ::= TBCD-STRING (SIZE (3))
+
+Pre-emptionCapability ::= ENUMERATED {
+ shall-not-trigger-pre-emption,
+ may-trigger-pre-emption
+}
+
+Pre-emptionVulnerability ::= ENUMERATED {
+ not-pre-emptable,
+ pre-emptable
+}
+
+PriorityLevel ::= INTEGER { spare (0), highest (1), lowest (14), no-priority (15) } (0..15)
+
+P-TMSI ::= OCTET STRING (SIZE (4))
+
+-- Q
+
+QueuingAllowed ::= ENUMERATED {
+ queueing-not-allowed,
+ queueing-allowed
+}
+
+-- R
+RAB-AsymmetryIndicator::= ENUMERATED {
+ symmetric-bidirectional,
+ asymmetric-unidirectional-downlink,
+ asymmetric-unidirectional-uplink,
+ asymmetric-bidirectional,
+ ...
+}
+
+RAB-ID ::= BIT STRING (SIZE (8))
+
+RAB-Parameter-GuaranteedBitrateList ::= SEQUENCE (SIZE (1..maxNrOfSeparateTrafficDirections)) OF GuaranteedBitrate
+
+RAB-Parameter-MaxBitrateList ::= SEQUENCE (SIZE (1..maxNrOfSeparateTrafficDirections)) OF MaxBitrate
+
+RAB-Parameters ::= SEQUENCE {
+ trafficClass TrafficClass,
+ rAB-AsymmetryIndicator RAB-AsymmetryIndicator,
+ maxBitrate RAB-Parameter-MaxBitrateList,
+ guaranteedBitRate RAB-Parameter-GuaranteedBitrateList OPTIONAL
+ -- This IE is only present when traffic class indicates Conversational or Streaming --,
+ deliveryOrder DeliveryOrder,
+ maxSDU-Size MaxSDU-Size,
+ sDU-Parameters SDU-Parameters,
+ transferDelay TransferDelay OPTIONAL
+ -- This IE is only present when traffic class indicates Conversational or Streaming --,
+ trafficHandlingPriority TrafficHandlingPriority OPTIONAL
+ -- This IE is only present when traffic class indicates Interactiv --,
+ allocationOrRetentionPriority AllocationOrRetentionPriority OPTIONAL,
+ sourceStatisticsDescriptor SourceStatisticsDescriptor OPTIONAL
+ -- This IE is only present when traffic class indicates Conversational or Streaming --,
+ relocationRequirement RelocationRequirement OPTIONAL
+ -- This IE is only present for RABs towards the PS domain --,
+ iE-Extensions ProtocolExtensionContainer { {RAB-Parameters-ExtIEs} } OPTIONAL,
+ ...
+}
+
+RAB-Parameters-ExtIEs RANAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+RAB-SubflowCombinationBitRate ::= INTEGER (0..16000000)
+
+RAB-TrCH-Mapping ::= SEQUENCE ( SIZE (1..maxNrOfRABs)) OF
+ RAB-TrCH-MappingItem
+
+RAB-TrCH-MappingItem ::= SEQUENCE {
+ rAB-ID RAB-ID,
+ trCH-ID-List TrCH-ID-List,
+ ...
+}
+
+RAC ::= OCTET STRING (SIZE (1))
+
+RAI ::= SEQUENCE {
+ lAI LAI,
+ rAC RAC,
+ iE-Extensions ProtocolExtensionContainer { {RAI-ExtIEs} } OPTIONAL,
+ ...
+}
+
+RAI-ExtIEs RANAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+RateControlAllowed ::= ENUMERATED {
+ not-allowed,
+ allowed
+}
+
+RelocationRequirement ::= ENUMERATED {
+ lossless,
+ none,
+ ...
+}
+
+RelocationType ::= ENUMERATED {
+ ue-not-involved,
+ ue-involved,
+ ...
+}
+
+RepetitionNumber ::= INTEGER (1..256)
+
+ReportArea ::= ENUMERATED {
+ service-area,
+ geographical-coordinates,
+ ...
+}
+
+RequestType ::= SEQUENCE {
+ event Event,
+ reportArea ReportArea,
+ accuracyCode INTEGER (0..127) OPTIONAL,
+ -- To be used if Geographical Coordinates shall be reported with a requested accuracy. --
+ ...
+}
+
+ResidualBitErrorRatio ::= SEQUENCE {
+ mantissa INTEGER (1..9),
+ exponent INTEGER (1..8),
+ iE-Extensions ProtocolExtensionContainer { {ResidualBitErrorRatio-ExtIEs} } OPTIONAL
+}
+-- ResidualBitErrorRatio = mantissa * 10^-exponent
+
+ResidualBitErrorRatio-ExtIEs RANAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+RNC-ID ::= INTEGER (0..4095)
+-- RNC-ID ::= BIT STRING (SIZE (12))
+-- Harmonized with RNSAP and NBAP definitions
+
+RRC-Container ::= OCTET STRING
+
+-- S
+
+SAC ::= OCTET STRING (SIZE (2))
+
+SAI ::= SEQUENCE {
+ pLMN-ID PLMN-ID,
+ lAC LAC,
+ sAC SAC,
+ iE-Extensions ProtocolExtensionContainer { {SAI-ExtIEs} } OPTIONAL
+}
+
+SAI-ExtIEs RANAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+SAPI ::= ENUMERATED {
+ sapi-0,
+ sapi-3,
+ ...
+}
+
+SDU-ErrorRatio ::= SEQUENCE {
+ mantissa INTEGER (1..9),
+ exponent INTEGER (1..6),
+ iE-Extensions ProtocolExtensionContainer { {SDU-ErrorRatio-ExtIEs} } OPTIONAL
+}
+-- SDU-ErrorRatio = mantissa * 10^-exponent
+
+SDU-ErrorRatio-ExtIEs RANAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+SDU-FormatInformationParameters ::= SEQUENCE (SIZE (1..maxRAB-SubflowCombination)) OF
+ SEQUENCE {
+ subflowSDU-Size SubflowSDU-Size OPTIONAL
+ -- This IE is only present for RABs that have predefined SDU size(s) --,
+ rAB-SubflowCombinationBitRate RAB-SubflowCombinationBitRate OPTIONAL
+ -- At least either of subflowSDU-Size or rABsubflowCombinationBitRate --
+ -- shall be present when SDUformatInformationParameter is present --,
+ iE-Extensions ProtocolExtensionContainer { {SDU-FormatInformationParameters-ExtIEs} } OPTIONAL,
+ ...
+ }
+
+SDU-FormatInformationParameters-ExtIEs RANAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+SDU-Parameters ::= SEQUENCE (SIZE (1..maxRAB-Subflows)) OF
+ SEQUENCE {
+ sDU-ErrorRatio SDU-ErrorRatio OPTIONAL
+ -- This IE is not present when DeliveryOfErroneousSDU is set to no-error-detection-consideration --,
+ residualBitErrorRatio ResidualBitErrorRatio,
+ deliveryOfErroneousSDU DeliveryOfErroneousSDU,
+ sDU-FormatInformationParameters SDU-FormatInformationParameters OPTIONAL
+ -- This IE shall be present for RABs with predefined SDU sizes --,
+ iE-Extensions ProtocolExtensionContainer { {SDU-Parameters-ExtIEs} } OPTIONAL,
+ ...
+ }
+
+SDU-Parameters-ExtIEs RANAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+Service-Handover ::= ENUMERATED {
+ handover-to-GSM-should-be-performed,
+ handover-to-GSM-should-not-be-performed,
+ handover-to-GSM-shall-not-be-performed,
+ ...
+}
+
+SourceID ::= CHOICE {
+ sourceRNC-ID SourceRNC-ID, -- If UMTS target
+ sAI SAI, -- if GSM target
+ ...
+}
+
+
+SourceRNC-ID ::= SEQUENCE {
+ pLMN-ID PLMN-ID,
+ rNC-ID RNC-ID,
+ iE-Extensions ProtocolExtensionContainer { {SourceRNC-ID-ExtIEs} } OPTIONAL
+}
+
+SourceRNC-ID-ExtIEs RANAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+SourceRNC-ToTargetRNC-TransparentContainer ::= SEQUENCE {
+ rRC-Container RRC-Container,
+ numberOfIuInstances NumberOfIuInstances,
+ relocationType RelocationType,
+ chosenIntegrityProtectionAlgorithm ChosenIntegrityProtectionAlgorithm OPTIONAL
+ -- Must be present for intra UMTS Handovers if available --,
+ integrityProtectionKey IntegrityProtectionKey OPTIONAL
+ -- Must be present for intra UMTS Handovers if available --,
+ chosenEncryptionAlgorithForSignalling ChosenEncryptionAlgorithm OPTIONAL
+ -- Must be present for intra UMTS Handovers if ciphering is active --,
+ cipheringKey EncryptionKey OPTIONAL
+ -- Must be present for intra UMTS Handovers if ciphering is active --,
+ chosenEncryptionAlgorithForCS ChosenEncryptionAlgorithm OPTIONAL
+ -- Must be present for intra UMTS Handovers if ciphering is active --,
+ chosenEncryptionAlgorithForPS ChosenEncryptionAlgorithm OPTIONAL
+ -- Must be present for intra UMTS Handovers if ciphering is active --,
+ d-RNTI D-RNTI OPTIONAL
+ -- Included for SRNS Relocation without UE involvement --,
+ targetCellId TargetCellId OPTIONAL
+ -- Included for SRNS Relocation with UE involvement --,
+ rAB-TrCH-Mapping RAB-TrCH-Mapping OPTIONAL
+ -- Included for SRNS Relocation without UE involvement and --
+ -- if RABs are carried on DCH, USCH or DSCH transport channels --,
+ iE-Extensions ProtocolExtensionContainer { {SourceRNC-ToTargetRNC-TransparentContainer-ExtIEs} } OPTIONAL,
+ ...
+}
+
+SourceRNC-ToTargetRNC-TransparentContainer-ExtIEs RANAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+SourceStatisticsDescriptor ::= ENUMERATED {
+ speech,
+ unknown,
+ ...
+}
+
+SubflowSDU-Size ::= INTEGER (0..4095)
+-- Unit is bit
+
+
+-- T
+
+TargetCellId ::= INTEGER (0..268435455)
+
+TargetID ::= CHOICE {
+ targetRNC-ID TargetRNC-ID, -- If UMTS target
+ cGI CGI, -- If GSM target
+ ...
+}
+
+
+
+
+TargetRNC-ID ::= SEQUENCE {
+ lAI LAI,
+ rAC RAC OPTIONAL
+ -- Must always be present towards the PS domain and never towards the CS domain --,
+ rNC-ID RNC-ID,
+ iE-Extensions ProtocolExtensionContainer { {TargetRNC-ID-ExtIEs} } OPTIONAL
+}
+
+TargetRNC-ID-ExtIEs RANAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+TargetRNC-ToSourceRNC-TransparentContainer ::= SEQUENCE {
+ rRC-Container RRC-Container,
+ d-RNTI D-RNTI OPTIONAL
+ -- May be included to allow the triggering of the Relocation Detect procedure from the Iur Interface --,
+ iE-Extensions ProtocolExtensionContainer { {TargetRNC-ToSourceRNC-TransparentContainer-ExtIEs} } OPTIONAL,
+ ...
+}
+
+TargetRNC-ToSourceRNC-TransparentContainer-ExtIEs RANAP-PROTOCOL-EXTENSION ::= {
+ ...
+}
+
+TBCD-STRING ::= OCTET STRING
+
+TemporaryUE-ID ::= CHOICE {
+ tMSI TMSI,
+ p-TMSI P-TMSI,
+ ...
+}
+
+TMSI ::= OCTET STRING (SIZE (4))
+
+TraceReference ::= OCTET STRING (SIZE (2..3))
+
+TraceType ::= OCTET STRING (SIZE (1))
+-- Reference: GSM TS 12.08
+
+TrafficClass ::= ENUMERATED {
+ conversational,
+ streaming,
+ interactive,
+ background,
+ ...
+}
+
+TrafficHandlingPriority ::= INTEGER { spare (0), highest (1), lowest (14), no-priority-used (15) } (0..15)
+
+TransferDelay ::= INTEGER (0..65535)
+-- Unit is millisecond
+
+UnsuccessfullyTransmittedDataVolume ::= INTEGER (0..4294967295)
+
+TransportLayerAddress ::= BIT STRING (SIZE (1..160, ...))
+
+TrCH-ID ::= SEQUENCE {
+ dCH-ID DCH-ID OPTIONAL
+ -- At least one of these IEs shall be included --,
+ dSCH-ID DSCH-ID OPTIONAL
+ -- At least one of these IEs shall be included --,
+ uSCH-ID USCH-ID OPTIONAL
+ -- At least one of these IEs shall be included --,
+ ...
+}
+
+TrCH-ID-List ::= SEQUENCE (SIZE (1..maxRAB-Subflows)) OF
+ TrCH-ID
+
+TriggerID ::= OCTET STRING (SIZE (3..22))
+
+-- U
+
+UE-ID ::= CHOICE {
+ imsi IMSI,
+ imei IMEI,
+ ...
+}
+
+UL-GTP-PDU-SequenceNumber ::= INTEGER (0..65535)
+
+UL-N-PDU-SequenceNumber ::= INTEGER (0..65535)
+
+UP-ModeVersions ::= BIT STRING (SIZE (16))
+
+USCH-ID ::= INTEGER (0..255)
+
+UserPlaneMode ::= ENUMERATED {
+ transparent-mode,
+ support-mode-for-predefined-SDU-sizes,
+ ...
+}
+
+
+-- **************************************************************
+--
+-- Common definitions
+--
+-- **************************************************************
+
+--BEGIN_4
+
+Criticality ::= ENUMERATED { reject, ignore, notify }
+
+Presence ::= ENUMERATED { optional, conditional, mandatory }
+
+PrivateIE-ID ::= CHOICE {
+ local INTEGER (0..65535),
+ global OBJECT IDENTIFIER
+}
+
+ProcedureCode ::= INTEGER (0..255)
+
+ProtocolExtensionID ::= INTEGER (0..65535)
+
+ProtocolIE-ID ::= INTEGER (0..65535)
+
+TriggeringMessage ::= ENUMERATED { initiating-message, successful-outcome, unsuccessfull-outcome, outcome }
+
+
+-- **************************************************************
+--
+-- Constant definitions
+--
+-- **************************************************************
+
+--BEGIN_5
+
+-- **************************************************************
+--
+-- Elementary Procedures
+--
+-- **************************************************************
+
+id-RAB-Assignment INTEGER ::= 0
+id-Iu-Release INTEGER ::= 1
+id-RelocationPreparation INTEGER ::= 2
+id-RelocationResourceAllocation INTEGER ::= 3
+id-RelocationCancel INTEGER ::= 4
+id-SRNS-ContextTransfer INTEGER ::= 5
+id-SecurityModeControl INTEGER ::= 6
+id-DataVolumeReport INTEGER ::= 7
+id-Reset INTEGER ::= 9
+id-RAB-ReleaseRequest INTEGER ::= 10
+id-Iu-ReleaseRequest INTEGER ::= 11
+id-RelocationDetect INTEGER ::= 12
+id-RelocationComplete INTEGER ::= 13
+id-Paging INTEGER ::= 14
+id-CommonID INTEGER ::= 15
+id-CN-InvokeTrace INTEGER ::= 16
+id-LocationReportingControl INTEGER ::= 17
+id-LocationReport INTEGER ::= 18
+id-InitialUE-Message INTEGER ::= 19
+id-DirectTransfer INTEGER ::= 20
+id-OverloadControl INTEGER ::= 21
+id-ErrorIndication INTEGER ::= 22
+id-SRNS-DataForward INTEGER ::= 23
+id-ForwardSRNS-Context INTEGER ::= 24
+id-privateMessage INTEGER ::= 25
+id-CN-DeactivateTrace INTEGER ::= 26
+id-ResetResource INTEGER ::= 27
+id-RANAP-Relocation INTEGER ::= 28
+
+-- **************************************************************
+--
+-- Extension constants
+--
+-- **************************************************************
+
+maxPrivateIEs INTEGER ::= 65535
+maxProtocolExtensions INTEGER ::= 65535
+maxProtocolIEs INTEGER ::= 65535
+
+-- **************************************************************
+--
+-- Lists
+--
+-- **************************************************************
+
+maxNrOfDTs INTEGER ::= 15
+maxNrOfErrors INTEGER ::= 256
+maxNrOfIuSigConIds INTEGER ::= 250
+maxNrOfPDPDirections INTEGER ::= 2
+maxNrOfPoints INTEGER ::= 15
+maxNrOfRABs INTEGER ::= 256
+maxNrOfSeparateTrafficDirections INTEGER ::= 2
+maxNrOfVol INTEGER ::= 2
+maxNrOfLevels INTEGER ::= 256
+
+maxRAB-Subflows INTEGER ::= 7
+maxRAB-SubflowCombination INTEGER ::= 64
+
+-- **************************************************************
+--
+-- IEs
+--
+-- **************************************************************
+
+id-AreaIdentity INTEGER ::= 0
+id-CN-DomainIndicator INTEGER ::= 3
+id-Cause INTEGER ::= 4
+id-ChosenEncryptionAlgorithm INTEGER ::= 5
+id-ChosenIntegrityProtectionAlgorithm INTEGER ::= 6
+id-ClassmarkInformation2 INTEGER ::= 7
+id-ClassmarkInformation3 INTEGER ::= 8
+id-CriticalityDiagnostics INTEGER ::= 9
+id-DL-GTP-PDU-SequenceNumber INTEGER ::= 10
+id-EncryptionInformation INTEGER ::= 11
+id-IntegrityProtectionInformation INTEGER ::= 12
+id-IuTransportAssociation INTEGER ::= 13
+id-L3-Information INTEGER ::= 14
+id-LAI INTEGER ::= 15
+id-NAS-PDU INTEGER ::= 16
+id-NonSearchingIndication INTEGER ::= 17
+id-NumberOfSteps INTEGER ::= 18
+id-OMC-ID INTEGER ::= 19
+id-OldBSS-ToNewBSS-Information INTEGER ::= 20
+id-PagingAreaID INTEGER ::= 21
+id-PagingCause INTEGER ::= 22
+id-PermanentNAS-UE-ID INTEGER ::= 23
+id-RAB-ContextItem INTEGER ::= 24
+id-RAB-ContextList INTEGER ::= 25
+id-RAB-DataForwardingItem INTEGER ::= 26
+id-RAB-DataForwardingItem-SRNS-CtxReq INTEGER ::= 27
+id-RAB-DataForwardingList INTEGER ::= 28
+id-RAB-DataForwardingList-SRNS-CtxReq INTEGER ::= 29
+id-RAB-DataVolumeReportItem INTEGER ::= 30
+id-RAB-DataVolumeReportList INTEGER ::= 31
+id-RAB-DataVolumeReportRequestItem INTEGER ::= 32
+id-RAB-DataVolumeReportRequestList INTEGER ::= 33
+id-RAB-FailedItem INTEGER ::= 34
+id-RAB-FailedList INTEGER ::= 35
+id-RAB-ID INTEGER ::= 36
+id-RAB-QueuedItem INTEGER ::= 37
+id-RAB-QueuedList INTEGER ::= 38
+id-RAB-ReleaseFailedList INTEGER ::= 39
+id-RAB-ReleaseItem INTEGER ::= 40
+id-RAB-ReleaseList INTEGER ::= 41
+id-RAB-ReleasedItem INTEGER ::= 42
+id-RAB-ReleasedList INTEGER ::= 43
+id-RAB-ReleasedList-IuRelComp INTEGER ::= 44
+id-RAB-RelocationReleaseItem INTEGER ::= 45
+id-RAB-RelocationReleaseList INTEGER ::= 46
+id-RAB-SetupItem-RelocReq INTEGER ::= 47
+id-RAB-SetupItem-RelocReqAck INTEGER ::= 48
+id-RAB-SetupList-RelocReq INTEGER ::= 49
+id-RAB-SetupList-RelocReqAck INTEGER ::= 50
+id-RAB-SetupOrModifiedItem INTEGER ::= 51
+id-RAB-SetupOrModifiedList INTEGER ::= 52
+id-RAB-SetupOrModifyItem INTEGER ::= 53
+id-RAB-SetupOrModifyList INTEGER ::= 54
+id-RAC INTEGER ::= 55
+id-RelocationType INTEGER ::= 56
+id-RequestType INTEGER ::= 57
+id-SAI INTEGER ::= 58
+id-SAPI INTEGER ::= 59
+id-SourceID INTEGER ::= 60
+id-SourceRNC-ToTargetRNC-TransparentContainer INTEGER ::= 61
+id-TargetID INTEGER ::= 62
+id-TargetRNC-ToSourceRNC-TransparentContainer INTEGER ::= 63
+id-TemporaryUE-ID INTEGER ::= 64
+id-TraceReference INTEGER ::= 65
+id-TraceType INTEGER ::= 66
+id-TransportLayerAddress INTEGER ::= 67
+id-TriggerID INTEGER ::= 68
+id-UE-ID INTEGER ::= 69
+id-UL-GTP-PDU-SequenceNumber INTEGER ::= 70
+id-RAB-FailedtoReportItem INTEGER ::= 71
+id-RAB-FailedtoReportList INTEGER ::= 72
+id-KeyStatus INTEGER ::= 75
+id-DRX-CycleLengthCoefficient INTEGER ::= 76
+id-IuSigConIdList INTEGER ::= 77
+id-IuSigConIdItem INTEGER ::= 78
+id-IuSigConId INTEGER ::= 79
+id-DirectTransferInformationItem-RANAP-RelocInf INTEGER ::= 80
+id-DirectTransferInformationList-RANAP-RelocInf INTEGER ::= 81
+id-RAB-ContextItem-RANAP-RelocInf INTEGER ::= 82
+id-RAB-ContextList-RANAP-RelocInf INTEGER ::= 83
+id-RAB-ContextFailedtoTransferItem INTEGER ::= 84
+id-RAB-ContextFailedtoTransferList INTEGER ::= 85
+id-GlobalRNC-ID INTEGER ::= 86
+id-RAB-ReleasedItem-IuRelComp INTEGER ::= 87
+id-MessageStructure INTEGER ::= 88
+
+
+-- **************************************************************
+--
+-- Container definitions
+--
+-- **************************************************************
+
+--BEGIN_6
+
+-- **************************************************************
+--
+-- Class Definition for Protocol IEs
+--
+-- **************************************************************
+
+RANAP-PROTOCOL-IES ::= CLASS {
+ &id ProtocolIE-ID UNIQUE,
+ &criticality Criticality,
+ &Value,
+ &presence Presence
+}
+WITH SYNTAX {
+ ID &id
+ CRITICALITY &criticality
+ TYPE &Value
+ PRESENCE &presence
+}
+
+-- **************************************************************
+--
+-- Class Definition for Protocol IEs
+--
+-- **************************************************************
+
+RANAP-PROTOCOL-IES-PAIR ::= CLASS {
+ &id ProtocolIE-ID UNIQUE,
+ &firstCriticality Criticality,
+ &FirstValue,
+ &secondCriticality Criticality,
+ &SecondValue,
+ &presence Presence
+}
+WITH SYNTAX {
+ ID &id
+ FIRST CRITICALITY &firstCriticality
+ FIRST TYPE &FirstValue
+ SECOND CRITICALITY &secondCriticality
+ SECOND TYPE &SecondValue
+ PRESENCE &presence
+}
+
+-- **************************************************************
+--
+-- Class Definition for Protocol Extensions
+--
+-- **************************************************************
+
+RANAP-PROTOCOL-EXTENSION ::= CLASS {
+ &id ProtocolExtensionID UNIQUE,
+ &criticality Criticality,
+ &Extension,
+ &presence Presence
+}
+WITH SYNTAX {
+ ID &id
+ CRITICALITY &criticality
+ EXTENSION &Extension
+ PRESENCE &presence
+}
+
+-- **************************************************************
+--
+-- Class Definition for Private IEs
+--
+-- **************************************************************
+
+RANAP-PRIVATE-IES ::= CLASS {
+ &id PrivateIE-ID,
+ &criticality Criticality,
+ &Value,
+ &presence Presence
+}
+WITH SYNTAX {
+ ID &id
+ CRITICALITY &criticality
+ TYPE &Value
+ PRESENCE &presence
+}
+
+-- **************************************************************
+--
+-- Container for Protocol IEs
+--
+-- **************************************************************
+
+ProtocolIE-Container {RANAP-PROTOCOL-IES : IEsSetParam} ::=
+ SEQUENCE (SIZE (0..maxProtocolIEs)) OF
+ ProtocolIE-Field {{IEsSetParam}}
+
+ProtocolIE-Field {RANAP-PROTOCOL-IES : IEsSetParam} ::= SEQUENCE {
+ id RANAP-PROTOCOL-IES.&id ({IEsSetParam}),
+ criticality RANAP-PROTOCOL-IES.&criticality ({IEsSetParam}{@id}),
+ value RANAP-PROTOCOL-IES.&Value ({IEsSetParam}{@id})
+}
+
+-- **************************************************************
+--
+-- Container for Protocol IE Pairs
+--
+-- **************************************************************
+
+ProtocolIE-ContainerPair {RANAP-PROTOCOL-IES-PAIR : IEsSetParam} ::=
+ SEQUENCE (SIZE (0..maxProtocolIEs)) OF
+ ProtocolIE-FieldPair {{IEsSetParam}}
+
+ProtocolIE-FieldPair {RANAP-PROTOCOL-IES-PAIR : IEsSetParam} ::= SEQUENCE {
+ id RANAP-PROTOCOL-IES-PAIR.&id ({IEsSetParam}),
+ firstCriticality RANAP-PROTOCOL-IES-PAIR.&firstCriticality ({IEsSetParam}{@id}),
+ firstValue RANAP-PROTOCOL-IES-PAIR.&FirstValue ({IEsSetParam}{@id}),
+ secondCriticality RANAP-PROTOCOL-IES-PAIR.&secondCriticality ({IEsSetParam}{@id}),
+ secondValue RANAP-PROTOCOL-IES-PAIR.&SecondValue ({IEsSetParam}{@id})
+}
+
+-- **************************************************************
+--
+-- Container Lists for Protocol IE Containers
+--
+-- **************************************************************
+
+ProtocolIE-ContainerList {INTEGER : lowerBound, INTEGER : upperBound, RANAP-PROTOCOL-IES : IEsSetParam} ::=
+ SEQUENCE (SIZE (lowerBound..upperBound)) OF
+ ProtocolIE-Container {{IEsSetParam}}
+
+ProtocolIE-ContainerPairList {INTEGER : lowerBound, INTEGER : upperBound, RANAP-PROTOCOL-IES-PAIR : IEsSetParam} ::=
+ SEQUENCE (SIZE (lowerBound..upperBound)) OF
+ ProtocolIE-ContainerPair {{IEsSetParam}}
+
+-- **************************************************************
+--
+-- Container for Protocol Extensions
+--
+-- **************************************************************
+
+ProtocolExtensionContainer {RANAP-PROTOCOL-EXTENSION : ExtensionSetParam} ::=
+ SEQUENCE (SIZE (1..maxProtocolExtensions)) OF
+ ProtocolExtensionField {{ExtensionSetParam}}
+
+ProtocolExtensionField {RANAP-PROTOCOL-EXTENSION : ExtensionSetParam} ::= SEQUENCE {
+ id RANAP-PROTOCOL-EXTENSION.&id ({ExtensionSetParam}),
+ criticality RANAP-PROTOCOL-EXTENSION.&criticality ({ExtensionSetParam}{@id}),
+ extensionValue RANAP-PROTOCOL-EXTENSION.&Extension ({ExtensionSetParam}{@id})
+}
+
+-- **************************************************************
+--
+-- Container for Private IEs
+--
+-- **************************************************************
+
+PrivateIE-Container {RANAP-PRIVATE-IES : IEsSetParam } ::=
+ SEQUENCE (SIZE (1.. maxPrivateIEs)) OF
+ PrivateIE-Field {{IEsSetParam}}
+
+PrivateIE-Field {RANAP-PRIVATE-IES : IEsSetParam} ::= SEQUENCE {
+ id RANAP-PRIVATE-IES.&id ({IEsSetParam}),
+ criticality RANAP-PRIVATE-IES.&criticality ({IEsSetParam}{@id}),
+ value RANAP-PRIVATE-IES.&Value ({IEsSetParam}{@id})
+}
+
+END
diff --git a/lib/asn1/test/bench/all.erl b/lib/asn1/test/bench/all.erl
new file mode 100644
index 0000000000..0841201e85
--- /dev/null
+++ b/lib/asn1/test/bench/all.erl
@@ -0,0 +1,98 @@
+%%
+%% %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(all).
+
+%% User interface
+-export([run/0]).
+
+%% Interna constants
+-define(NORMAL, 0).
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%%% Interface
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%% run() -> _
+%%
+%% Runs all benchmark modules in the current directory on all erlang
+%% installations specified by releases/0
+run() ->
+ %% Delete previous intermediate test result files.
+ lists:foreach(fun(F) -> file:delete(F) end, filelib:wildcard("*.bmres")),
+ lists:foreach(fun run/1, releases()).
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%%% Internal functions
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+%% run(Release) -> _
+%% Release = string() - Erlang release
+%% Help functions to run/0
+run({Release,Comment}) ->
+ command(Release ++ " -noshell -compile bench -s erlang halt"),
+ command(Release ++ " -noshell -s bench run " ++ Comment ++" -s erlang halt").
+
+%% command(Command) -> _
+%% Command = string() - is the name and arguments of the external
+%% program which will be run
+command(Command) ->
+ io:format("~s\n", [Command]), % Progress info to user
+ Port = open_port({spawn,Command}, [exit_status, in]),
+ print_output(Port).
+
+%% print_output(Port) -> _
+%% Port = port()
+%% Print data from the port i.e. output from external program,
+%% on standard out.
+print_output(Port) ->
+ receive
+ {Port, {data,Bytes}} ->
+ io:put_chars(Bytes),
+ print_output(Port);
+ {Port, {exit_status, ?NORMAL}} ->
+ ok
+ end.
+
+%% run() -> Releases
+%% Releases = [Release |_]
+%% Release = string() - Erlang release
+%% Defines which erlang releases to run on
+%% --- Change this function to reflect your own erlang installations ---
+releases() ->
+ [
+ {"/usr/local/otp/releases/otp_beam_sunos5_r8b_patched/bin/erl","standardr8"},
+ {"/usr/local/otp/releases/otp_beam_sunos5_r8b_patched/bin/erl -pa /clearcase/otp/erts/lib/asn1/ebin", "asn1r9"}
+].
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/lib/asn1/test/bench/bench.erl b/lib/asn1/test/bench/bench.erl
new file mode 100644
index 0000000000..bae7d792a4
--- /dev/null
+++ b/lib/asn1/test/bench/bench.erl
@@ -0,0 +1,454 @@
+%%
+%% %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(bench).
+
+%% User interface
+-export([run/1]).
+
+%% Exported to be used in spawn
+-export([measure/4]).
+
+%% Internal constants
+-define(MAX, 999999999999999).
+-define(RANGE_MAX, 16#7ffffff).
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%%% Interface
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+%% run() -> _
+%%
+%% Compiles and runs all benchmarks in the current directory,
+%% and creates a report
+run([Comment]) ->
+ run(atom_to_list(Comment),compiler_options()).
+
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%%% Generic Benchmark functions
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+%% compiler_options() -> OptionsList
+%% OptionsList = list() - See Erlang/OTP module compile
+compiler_options() ->
+ [report_errors, report_warnings].
+
+%% run(OptionsList) ->
+%% OptionsList = list() - See Erlang/OTP module compile
+%%
+%% Help function to run/0.
+run(Comment,OptionsList) ->
+ Bms = compile_benchmarks(OptionsList),
+ run_benchmarks(Comment,Bms),
+ report().
+
+%% compile_benchmarks(OptionsList) -> [BmInfo| _]
+%% OptionsList = list() - See Erlang/OTP module compile
+%% BmInfo = {Module, Iterations, [BmFunctionName| _]}
+%% Module = atom()
+%% Iterations = integer()
+%% BmFunctionName = atom()
+%%
+%% Compiles all benchmark modules in the current directory and
+%% returns info about the benchmarks.
+compile_benchmarks(OptionsList) ->
+ {ok, FilesInCurrentDir} = file:list_dir("."),
+ BmFiles = [BmFile || BmFile <- lists:sort(FilesInCurrentDir),
+ lists:suffix("_bm.erl", BmFile)],
+
+ lists:foldr(fun(Module, BmInfoAcc) ->
+ BmInfo = bm_compile(Module, OptionsList),
+ [BmInfo | BmInfoAcc]
+ end, [], BmFiles).
+
+
+%% bm_compile(FileName, OptionsList) -> BmInfo
+%% FileName = string()
+%% OptionsList = list() - See Erlang/OTP module compile
+%% BmInfo = {Module, Iterations, [BmFunctionName| _]}
+%% Iterations = integer()
+%% Module = atom()
+%% BmFunctionName = atom()
+%%
+%% Compiles the benchmark module implemented in <FileName> and returns
+%% information about the benchmark tests.
+bm_compile(FileName, OptionsList) ->
+ io:format("Compiling ~s...\n", [FileName]), % Progress info to user
+ case c:c(FileName, OptionsList) of
+ {ok, Mod} ->
+ bm_init(Mod),
+ bm_cases(Mod);
+ %% If compilation fails there is no point in trying to continue
+ error ->
+ Reason =
+ lists:flatten(
+ io_lib:format("Could not compile file ~s", [FileName])),
+ exit(self(), Reason)
+ end.
+
+%% bm_init(Module) -> ok
+%%
+%% calls the Module:init/0 function to let each benchmark make initialisation if
+%% there is need for that.
+%%
+bm_init(Module) ->
+ case catch Module:init() of
+ ok ->
+ ok;
+ Other ->
+ ok % the init function is not mandatory yet
+ end.
+
+
+%% bm_cases(Module) -> {Module, Iter, [BmFunctionName |_]}
+%% Module = atom()
+%% Iter = integer()
+%% BmFunctionName = atom()
+%%
+%% Fetches the number of iterations and the names of the benchmark
+%% functions for the module <Module>.
+bm_cases(Module) ->
+ case catch Module:benchmarks() of
+ {Iter, BmList} when integer(Iter), list(BmList) ->
+ {Module, Iter, BmList};
+ %% The benchmark is incorrect implemented there is no point in
+ %% trying to continue
+ Other ->
+ Reason =
+ lists:flatten(
+ io_lib:format("Incorrect return value: ~p "
+ "from ~p:benchmarks()",
+ [Other, Module])),
+ exit(self(), Reason)
+ end.
+
+%% run_benchmarks(Bms) ->
+%% Bms = [{Module, Iter, [BmFunctionName |_]} | _]
+%% Module = atom()
+%% Iter = integer()
+%% BmFunctionName = atom()
+%%
+%% Runs all the benchmark tests described in <Bms>.
+run_benchmarks(Comment,Bms) ->
+ Ver = erlang:system_info(version),
+ Machine = erlang:system_info(machine),
+ SysInfo = {Ver,Machine,Comment},
+
+ Res = [bms_run(Mod, Tests, Iter, SysInfo) || {Mod,Iter,Tests} <- Bms],
+
+ %% Create an intermediate file that is later used to generate a bench
+ %% mark report.
+ Name = Ver ++ [$.|Machine] ++ Comment ++ ".bmres",
+ {ok, IntermediatFile} = file:open(Name, [write]),
+
+ %% Create mark that identifies version of the benchmark modules
+ io:format(IntermediatFile, "~p.\n", [erlang:phash(Bms, ?RANGE_MAX)]),
+
+ io:format(IntermediatFile, "~p.\n", [Res]),
+ file:close(IntermediatFile).
+
+
+%% bms_run(Module, BmTests, Iter, Info) ->
+%% Module = atom(),
+%% BmTests = [BmFunctionName|_],
+%% BmFunctionName = atom()
+%% Iter = integer(),
+%% SysInfo = {Ver, Machine}
+%% Ver = string()
+%% Machine = string()
+%%
+%% Runs all benchmark tests in module <Module>.
+bms_run(Module, BmTests, Iter, SysInfo) ->
+ io:format("Running ~s:", [Module]), % Progress info to user
+ Res =
+ {Module,{SysInfo,[{Bm, bm_run(Module, Bm, Iter)} || Bm <- BmTests]}},
+ io:nl(),
+ Res.
+
+%% bm_run(Module, BmTest, Iter) -> Elapsed
+%% Module = atom(),
+%% BmTest = atom(),
+%% Iter = integer()
+%% Elapsed = integer() - elapsed time in milliseconds.
+%%
+%% Runs the benchmark Module:BmTest(Iter)
+bm_run(Module, BmTest, Iter) ->
+ io:format(" ~s", [BmTest]), % Progress info to user
+ spawn_link(?MODULE, measure, [self(), Module, BmTest, Iter]),
+ receive
+ {Elapsed, ok} ->
+ Elapsed;
+ {_Elapsed, Fault} ->
+ io:nl(),
+ Reason =
+ lists:flatten(
+ io_lib:format("~w", [Fault])),
+ exit(self(), Reason)
+ end.
+
+%% measure(Parent, Module, BmTest, Iter) -> _
+%% Parent = pid(),
+%% Module = atom(),
+%% BmTest = atom(),
+%% Iter = integer()
+%%
+%% Measures the time it take to execute Module:Bm(Iter)
+%% and send the result to <Parent>.
+measure(Parent, Module, BmTest, Iter) ->
+ statistics(runtime),
+ Res = (catch apply(Module, BmTest, [Iter])),
+ {_TotalRunTime, TimeSinceLastCall} = statistics(runtime),
+ Parent ! {TimeSinceLastCall, Res}.
+
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%%% Report functions
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+%% report() -> _
+%%
+%% Creates a report of the bench marking test that appeals to a human.
+%% Currently this means creating a html-file. (Other formats could be added)
+report() ->
+ {ok, AllFiles} = file:list_dir("."),
+ BmResultFiles = [File || File <- AllFiles, lists:suffix(".bmres", File)],
+
+ Results = fetch_bmres_data(BmResultFiles),
+ create_report(Results).
+
+%% fetch_bmres_data(BmResultFiles) -> Results
+%% BmResultFiles = [FileName | _]
+%% FileName = string()
+%% Results = [[{Bm, Res} | _]]
+%% Bm = atom() - Name of benchmark module
+%% Res = [{VersionInfo, [{Test, Time} | _]}]
+%% VersionInfo = {Ver, Machine}
+%% Ver = string()
+%% Machine = string()
+%% Test = atom()
+%% Time = integer()
+%%
+%% Reads result data from intermediate files
+fetch_bmres_data(BmResultFiles) ->
+ fetch_bmres_data(BmResultFiles, [], undefined).
+
+%% fetch_bmres_data(BmResultFiles, AccResData, Check) -> Results
+%% BmResultFiles = [FileName | _]
+%% FileName = string()
+%% AccResData = see Results fetch_bmres_data/1
+%% Check = integer() | undefined (first time)
+%%
+%% Help function to fetch_bmres_data/1
+fetch_bmres_data([], AccResData, _Check) ->
+ AccResData;
+
+fetch_bmres_data([Name | BmResultFiles], AccResData, Check) ->
+ {DataList, NewCheck} = read_bmres_file(Name, Check),
+ fetch_bmres_data(BmResultFiles, [DataList| AccResData], NewCheck).
+
+
+%% read_bmres_file(Name, Check) ->
+%% Name = string()
+%% Check = integer() | undefined
+%%
+%% Reads the data from the result files. Checks that all result
+%% files where created with the same set of tests.
+read_bmres_file(Name, Check) ->
+ case file:consult(Name) of
+ {ok, [Check1, List]} when Check =:= undefined, integer(Check1) ->
+ {List, Check1};
+ {ok, [Check, List]} when integer(Check) ->
+ {List, Check};
+ {ok, [Check1, List]} when integer(Check1) ->
+ Reason =
+ lists:flatten(
+ io_lib:format("Different test setup, remove old setup "
+ "result by removing *.bmres files and "
+ "try again", [])),
+ exit(self(), Reason);
+ {error, Reason} when atom(Reason) ->
+ exit(self(), Reason);
+ {error, Reason} ->
+ exit(self(), file:format(Reason))
+ end.
+
+%% create_report(Results) ->
+%% Results = see Results fetch_bmres_data/1
+%%
+%% Organizes <Result> so it will be right for create_html_report/1
+%% i.e. group results for the same benchmark test, run on different versions
+%% of erlang.
+create_report(Results) ->
+ Dictionary =
+ lists:foldl(fun(BmResultList, Dict0) ->
+ lists:foldl(fun({Bm, VerResult}, Dict1) ->
+ dict:append(Bm, VerResult,
+ Dict1)
+ end,Dict0, BmResultList)
+ end,
+ dict:new(), Results),
+
+ create_html_report(dict:dict_to_list(Dictionary)).
+
+%% create_html_report(ResultList) -> _
+%% ResultList = [{Bm, Res} | _]
+%% Bm = atom() - Name of benchmark module
+%% Res = [{VersionInfo, [{Test, Time} | _]} | _]
+%% VersionInfo = {Ver, Machine}
+%% Ver = string()
+%% Machine = string()
+%% Test = atom()
+%% Time = integer()
+%%
+%% Writes the result to an html-file
+create_html_report(ResultList) ->
+
+ {ok, OutputFile} = file:open("index.html", [write]),
+
+ %% Create the begining of the result html-file.
+ Head = Title = "Benchmark Results",
+ io:put_chars(OutputFile, "<html>\n"),
+ io:put_chars(OutputFile, "<head>\n"),
+ io:format(OutputFile, "<title>~s</title>\n", [Title]),
+ io:put_chars(OutputFile, "</head>\n"),
+ io:put_chars(OutputFile, "<body bgcolor=\"#FFFFFF\" text=\"#000000\"" ++
+ " link=\"#0000FF\" vlink=\"#800080\" alink=\"#FF0000\">\n"),
+ io:format(OutputFile, "<h1>~s</h1>\n", [Head]),
+
+ %% Add the result tables
+ lists:foreach(fun(Element) ->
+ create_html_table(OutputFile, Element) end,
+ ResultList),
+
+ %% Put in the end-html tags
+ io:put_chars(OutputFile, "</body>\n"),
+ io:put_chars(OutputFile, "</html>\n"),
+
+ file:close(OutputFile).
+
+%% create_html_table(File, {Bm, Res}) -> _
+%% File = file() - html file to write data to.
+%% Bm = atom() - Name of benchmark module
+%% Res = [{VersionInfo, [{Test, Time} | _]}]
+%% VersionInfo = {Ver, Machine}
+%% Ver = string()
+%% Machine = string()
+%% Test = atom()
+%% Time = integer()
+%%
+%% Creates a html table that displays the result of the benchmark <Bm>.
+create_html_table(File, {Bm, Res}) ->
+
+ {MinTime, Order} = min_time_and_sort(Res),
+
+ io:format(File, "<h2>~s</h2>\n" , [Bm]),
+
+ %% Fun that calculates relative measure values and puts them in
+ %% a dictionary
+ RelativeMesureFun = fun({TestName, Time}, Dict1) ->
+ dict:append(TestName, Time/MinTime, Dict1)
+ end,
+
+ %% For all erlang versions that the benchmark tests has been run,
+ %% calculate the relative measure values and put them in a dictionary.
+ ResultDict =
+ lists:foldl(fun({_VerInfo, Bms}, Dict0) ->
+ lists:foldl(RelativeMesureFun, Dict0, Bms) end,
+ dict:new(), Res),
+
+ %% Create the table and its headings
+ io:put_chars(File, "<table border=0 cellpadding=1><tr>"
+ "<td bgcolor=\"#000000\">\n"),
+ io:put_chars(File, "<table cellpadding=3 border=0 cellspacing=1>\n"),
+ io:put_chars(File, "<tr bgcolor=white>"),
+ io:put_chars(File, "<td>Test</td>"),
+ Heads = table_headers(Res),
+ lists:foreach(fun({Ver,Machine,Comment}) ->
+ io:format(File, "<td>~s<br>~s<br>~s</td>",
+ [Ver,Machine,Comment]) end, Heads),
+ io:put_chars(File, "</tr>\n"),
+
+ %% Create table rows
+ lists:foreach(fun(Name) ->
+ create_html_row(File, Name, ResultDict)
+ end, Order),
+
+ %% Tabel end-tags
+ io:put_chars(File, "</table></td></tr></table>\n"),
+
+ %% Create link to benchmark source code
+ io:format(File, "<p><a href=\"~s.erl\">Source for ~s.erl</a>\n",
+ [Bm,Bm]).
+
+%% create_html_row(File, Name, Dict) -> _
+%% File = file() - html file to write data to.
+%% Name = atom() - Name of benchmark test
+%% Dict = dict() - Dictonary where the relative time measures for
+%% the test can be found.
+%%
+%% Creates an actual html table-row.
+create_html_row(File, Name, Dict) ->
+ ReletiveTimes = dict:fetch(Name, Dict),
+ io:put_chars(File, "<tr bgcolor=white>\n"),
+ io:format(File, "<td>~s</td>", [Name]),
+ lists:foreach(fun(Time) ->
+ io:format(File, "<td>~-8.2f</td>", [Time]) end,
+ ReletiveTimes),
+ io:put_chars(File, "</tr>\n").
+
+%% min_time_and_sort(ResultList) -> {MinTime, Order}
+%% ResultList = [{VersionInfo, [{Test, Time} | _]}]
+%% MinTime = integer() - The execution time of the fastes test
+%% Order = [BmFunctionName|_] - the order of the testcases in
+%% increasing execution time.
+%% BmFunctionName = atom()
+min_time_and_sort(ResultList) ->
+
+ %% Use the results from the run on the highest version
+ %% of Erlang as norm.
+ {_, TestRes} =
+ lists:foldl(fun ({Ver, ResList},
+ CurrentVer) when Ver > CurrentVer ->
+ {Ver, ResList};
+ (_, VerAndRes) ->
+ VerAndRes
+ end, {"0", []}, ResultList),
+
+ {lists:foldl(fun ({_, Time0}, Min1) when Time0 < Min1 ->
+ Time0;
+ (_, Min1) ->
+ Min1
+ end, ?MAX, TestRes),
+ [Name || {Name, _} <- lists:keysort(2, TestRes)]}.
+
+
+%% table_headers(VerResultList) -> SysInfo
+%% VerResultList = [{{Ver, Machine},[{BmFunctionName, Time}]} | _]
+%% Ver = string()
+%% Machine = string()
+%% BmFunctionName = atom()
+%% Time = integer()
+%% SysInfo = {Ver, Machine}
+table_headers(VerResultList) ->
+ [SysInfo || {SysInfo, _} <- VerResultList].
+
+
+
diff --git a/lib/asn1/test/bench/bench.hrl b/lib/asn1/test/bench/bench.hrl
new file mode 100644
index 0000000000..7c99447439
--- /dev/null
+++ b/lib/asn1/test/bench/bench.hrl
@@ -0,0 +1,24 @@
+%%
+%% %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%
+%%
+%%
+-define(rep5(X), X, X, X, X, X).
+-define(rep10(X), ?rep5(X), ?rep5(X)).
+-define(rep20(X), ?rep10(X), ?rep10(X)).
+-define(rep40(X), ?rep20(X), ?rep20(X)).
+-define(rep80(X), ?rep40(X), ?rep40(X)).
diff --git a/lib/asn1/test/bench/per_bm.erl b/lib/asn1/test/bench/per_bm.erl
new file mode 100644
index 0000000000..23f8a8f010
--- /dev/null
+++ b/lib/asn1/test/bench/per_bm.erl
@@ -0,0 +1,650 @@
+%%
+%% %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(per_bm).
+
+-define(DATADIR,"/clearcase/otp/erts/lib/asn1/test/asn1_SUITE_data/").
+-include("bench.hrl").
+
+-export([init/0,benchmarks/0]).
+-export([encode/1,decode/1,ranap_enc/1,ranap_dec/1]).
+
+
+init() ->
+ ok = asn1ct:compile(?DATADIR++"H235-SECURITY-MESSAGES",[per_bin]),
+ ok = asn1ct:compile(?DATADIR++"H323-MESSAGES",[per_bin]),
+ ok = asn1ct:compile("RanapASN1",[per_bin]),
+ ok.
+
+
+benchmarks() ->
+ {5000,[encode,decode,ranap_enc,ranap_dec]}.
+
+ranap_dec(N) ->
+ V = ranap_v2(),
+ {ok,Bl} = asn1rt:encode('RanapASN1','RANAP-PDU',V),
+ B = list_to_binary(Bl),
+ ranap_n_dec(N,B),
+ ok.
+
+ranap_n_dec(0,_) ->
+ ok;
+ranap_n_dec(N,B) ->
+ {ok,V}=asn1rt:decode('RanapASN1','RANAP-PDU',B),
+ ranap_n_dec(N-1,B).
+
+ranap_enc(N) ->
+ V = ranap_v2(),
+ ranap_n_enc(N,V),
+ ok.
+
+ranap_n_enc(0,V) ->
+ ok;
+ranap_n_enc(N,V) ->
+ {ok,B} = asn1rt:encode('RanapASN1','RANAP-PDU',V),
+ ranap_n_enc(N-1,V).
+
+
+decode(N) ->
+ V = v1(),
+ {ok,Bl} = asn1rt:encode('H323-MESSAGES','H323-UserInformation',V),
+ B = list_to_binary(Bl),
+ n_decode(N,B),
+ ok.
+
+n_decode(0,_) ->
+ ok;
+n_decode(N,B) ->
+ {ok,V}=asn1rt:decode('H323-MESSAGES','H323-UserInformation',B),
+ n_decode(N-1,B).
+
+
+v1() ->
+ V =
+ {'H323-UserInformation',
+ {'H323-UU-PDU',
+ {callProceeding,
+ {'CallProceeding-UUIE',
+ {0,
+ 7,
+ 180},
+ {'EndpointType',
+ {'NonStandardParameter',
+ {object,
+ {0,
+ 8,
+ 202}},
+ "O"},
+ {'VendorIdentifier',
+ {'H221NonStandard',
+ 55,
+ 55,
+ 14277},
+ "OC",
+ "OC"},
+ {'GatekeeperInfo',
+ {'NonStandardParameter',
+ {object,
+ {0,
+ 9,
+ 232}},
+ "O"}},
+ {'GatewayInfo',
+ [{h320,
+ {'H320Caps',
+ {'NonStandardParameter',
+ {object,
+ {0,
+ 10,
+ 268}},
+ "O"},
+ [{'DataRate',
+ {'NonStandardParameter',
+ {object,
+ {0,
+ 11,
+ 284}},
+ "O"},
+ 1244176737,
+ 75}],
+ [{'SupportedPrefix',
+ {'NonStandardParameter',
+ {object,
+ {0,
+ 12,
+ 304}},
+ "O"},
+ {'h323-ID',
+ "BM"}}]}}],
+ {'NonStandardParameter',
+ {object,
+ {0,
+ 13,
+ 324}},
+ "O"}},
+ {'McuInfo',
+ {'NonStandardParameter',
+ {object,
+ {1,
+ 13,
+ 346,
+ 347}},
+ "OC"}},
+ {'TerminalInfo',
+ {'NonStandardParameter',
+ {object,
+ {1,
+ 14,
+ 363,
+ 363}},
+ "OC"}},
+ true,
+ true},
+ {ipxAddress,
+ {'TransportAddress_ipxAddress',
+ "OCTET ",
+ "OCTE",
+ "OC"}},
+ {'CallIdentifier',
+ "OCTET STRINGOCTE"},
+ {noSecurity,
+ 'NULL'},
+ [
+% {'ClearToken',
+% 1703375497,
+% "BM",
+% {'DHset',
+% [1],
+% [1],
+% [1]},
+% "OCTET STRI",
+% -21825559,
+% {'TypedCertificate',
+% {1,
+% 17,
+% 424,
+% 424},
+% "OC"},
+% "BMP",
+% {'NonStandardParameter',
+% {1,
+% 17,
+% 435,
+% 436},
+% "OC"}},
+ {'ClearToken',
+ 1929575502,
+ "BMP",
+ {'DHset',
+ [1],
+ [1],
+ [1]},
+ "OCTET STRI",
+ -9591354,
+ {'TypedCertificate',
+ {1,
+ 18,
+ 471,
+ 471},
+ "OC"},
+ "BMP",
+ {'NonStandardParameter',
+ {1,
+ 19,
+ 482,
+ 483},
+ "OC"}}],
+ [
+% {cryptoEPCert,
+% {'CryptoH323Token_cryptoEPCert',
+% {'ClearToken',
+% 2227304001,
+% "BMP",
+% {'DHset',
+% [1],
+% [1],
+% [1]},
+% "OCTET STRI",
+% 9574387,
+% {'TypedCertificate',
+% {1,
+% 21,
+% 541,
+% 542},
+% "OCT"},
+% "BMP",
+% {'NonStandardParameter',
+% {1,
+% 22,
+% 552,
+% 553},
+% "OCT"}},
+% {1,
+% 22,
+% 559,
+% 560},
+% {'Params',
+% 18993485,
+% "OCTET ST"},
+% [1,
+% 0,
+% 1]}},
+ {cryptoEPCert,
+ {'CryptoH323Token_cryptoEPCert',
+ {'ClearToken',
+ 2581405450,
+ "BMPS",
+ {'DHset',
+ [1,
+ 0,
+ 1],
+ [1,
+ 0,
+ 1],
+ [1,
+ 0,
+ 1]},
+ "OCTET STRIN",
+ 32050976,
+ {'TypedCertificate',
+ {1,
+ 25,
+ 625,
+ 625},
+ "OCT"},
+ "BMPS",
+ {'NonStandardParameter',
+ {1,
+ 25,
+ 636,
+ 637},
+ "OCT"}},
+ {1,
+ 25,
+ 644,
+ 645},
+ {'Params',
+ 40708757,
+ "OCTET ST"},
+ [1,
+ 0,
+ 1]}}],
+ ["OCT",
+ "OCT",
+ "OCT"]}},
+ {'NonStandardParameter',
+ {h221NonStandard,
+ {'H221NonStandard',
+ 173,
+ 173,
+ 44666}},
+ "OCTE"},
+ ["OCTE",
+ "OCTE",
+ "OCTE",
+ "OCTE"],
+ true,
+ ["OCTE",
+ "OCTE",
+ "OCTE",
+ "OCTE"],
+ [
+% {'NonStandardParameter',
+% {h221NonStandard,
+% {'H221NonStandard',
+% 182,
+% 183,
+% 46981}},
+% "OCTE"},
+% {'NonStandardParameter',
+% {h221NonStandard,
+% {'H221NonStandard',
+% 186,
+% 187,
+% 48016}},
+% "OCTE"},
+% {'NonStandardParameter',
+% {h221NonStandard,
+% {'H221NonStandard',
+% 190,
+% 191,
+% 49026}},
+% "OCTE"},
+ {'NonStandardParameter',
+ {h221NonStandard,
+ {'H221NonStandard',
+ 195,
+ 196,
+ 50303}},
+ "OCTE"}]},
+ {'H323-UserInformation_user-data',
+ 197,
+ "OCTE"}}.
+
+encode(N) ->
+ V = v1(),
+ n_encode(N,V),
+ ok.
+
+n_encode(0,V) ->
+ ok;
+n_encode(N,V) ->
+ {ok,B} = asn1rt:encode('H323-MESSAGES','H323-UserInformation',V),
+ n_encode(N-1,V).
+
+
+ranap_v1() ->
+ {successfulOutcome,
+ {'SuccessfulOutcome',
+ 9,
+ ignore,
+ {'ResetAcknowledge',
+ [{'ProtocolIE-Field',3,ignore,'ps-domain'},
+ {'ProtocolIE-Field',
+ 86,
+ ignore,
+ {'GlobalRNC-ID',"!Ce",2}}],
+ asn1_NOVALUE}}}.
+
+ranap_v2() ->
+ {initiatingMessage,{'InitiatingMessage',
+ 6,
+ {'Criticality',reject},
+ {'SecurityModeCommand',
+ [{'ProtocolIE-Field',
+ 12,
+ {'Criticality',reject},
+ {'IntegrityProtectionInformation',
+ ['standard-UMTS-integrity-algorithm-UIA1'],
+ [0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 1,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0],
+ asn1_NOVALUE}},
+ {'ProtocolIE-Field',
+ 11,
+ {'Criticality',ignore},
+ {'EncryptionInformation',
+ ['no-encryption',
+ 'standard-UMTS-encryption-algorith-UEA1'],
+ [0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 1],
+ asn1_NOVALUE}},
+ {'ProtocolIE-Field',
+ 75,
+ {'Criticality',reject},
+ new}],
+ asn1_NOVALUE}}}.
+
+
+
+
+
+
+
diff --git a/lib/asn1/test/ber_decode_error.erl b/lib/asn1/test/ber_decode_error.erl
new file mode 100644
index 0000000000..aa3b0122fd
--- /dev/null
+++ b/lib/asn1/test/ber_decode_error.erl
@@ -0,0 +1,56 @@
+%%
+%% %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(ber_decode_error).
+
+-export([run/1, compile/3]).
+
+-include("test_server.hrl").
+
+compile(Config,Rules,Options) ->
+
+ ?line DataDir = ?config(data_dir,Config),
+ ?line OutDir = ?config(priv_dir,Config),
+ ?line true = code:add_patha(?config(priv_dir,Config)),
+ ?line ok = asn1ct:compile(DataDir ++ "Constructed",
+ [Rules,{outdir,OutDir}]++Options).
+
+
+run([]) ->
+ ?line {ok,B} = asn1_wrapper:encode('Constructed','S3',{'S3',17}),
+ ?line [T,L|V] = lists:flatten(B),
+ ?line Bytes = [T,L+3|V] ++ [2,1,3],
+ ?line case asn1_wrapper:decode('Constructed','S3',Bytes) of
+ {error,{asn1,{unexpected,_}}} -> ok
+ end,
+ %% Unexpected bytes must be accepted if there is an extensionmark
+ ?line {ok,{'S3ext',17}} = asn1_wrapper:decode('Constructed','S3ext',Bytes),
+ ok;
+run([driver]) ->
+ %% test of OTP-4797, bad indata to driver does not cause an EXIT
+ ?line {error,_Reason} = asn1rt:decode('Constructed','S3',[3,5]),
+ ok.
+
+
+
+
+
+
+
+
diff --git a/lib/asn1/test/choice_extension.erl b/lib/asn1/test/choice_extension.erl
new file mode 100644
index 0000000000..843704ee9e
--- /dev/null
+++ b/lib/asn1/test/choice_extension.erl
@@ -0,0 +1,37 @@
+%%
+%% %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(choice_extension).
+
+-export([run/0, compile/3]).
+
+-include("test_server.hrl").
+
+compile(Config,Rules,Options) ->
+
+ ?line DataDir = ?config(data_dir,Config),
+ ?line OutDir = ?config(priv_dir,Config),
+ ?line true = code:add_patha(?config(priv_dir,Config)),
+ ?line ok = asn1ct:compile(DataDir ++ "ChoExtension",[Rules,{outdir,OutDir}]++Options).
+
+run() ->
+ Val = {str,"abc"},
+ ?line {ok,B} = asn1_wrapper:encode('ChoExtension','ChoExt4',Val),
+ ?line {ok,Val} = asn1_wrapper:decode('ChoExtension','ChoExt4',lists:flatten(B)),
+ ok.
diff --git a/lib/asn1/test/h323test.erl b/lib/asn1/test/h323test.erl
new file mode 100644
index 0000000000..60d2c39be0
--- /dev/null
+++ b/lib/asn1/test/h323test.erl
@@ -0,0 +1,172 @@
+%%
+%% %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(h323test).
+
+-compile(export_all).
+-export([compile/3,run/1]).
+-include("test_server.hrl").
+
+compile(Config,Rules,Options) ->
+ ?line DataDir = ?config(data_dir,Config),
+ ?line OutDir = ?config(priv_dir,Config),
+ ?line true = code:add_patha(?config(priv_dir,Config)),
+ ?line ok = asn1ct:compile(DataDir ++ "H235-SECURITY-MESSAGES",[Rules,{outdir,OutDir}]++Options),
+ ?line ok = asn1ct:compile(DataDir ++ "H323-MESSAGES",[Rules,{outdir,OutDir}]++Options),
+ ?line ok = asn1ct:compile(DataDir ++ "MULTIMEDIA-SYSTEM-CONTROL",[Rules,{outdir,OutDir}]++Options).
+
+run(per_bin) ->
+ run();
+run(per) ->
+ run();
+run(_Rules) ->
+ ok.
+
+run() ->
+ ?line alerting(),
+ ?line connect(),
+ ok.
+
+arq() ->
+ _AdmissionRequest = "27900007086000340036003300320038003700370101805337010180533600AC1F38C60693000D000445367AE75C5740120300AC1F38C6415004E0200100110000D7D22EA88D511C0200AC1F38C6C0580100".
+
+
+t0() ->
+ Setup = "00B8060008914A0001010180533622C000000000074572696373736F6E0356302E3100010180533700AC1F38C206B80045367AE75C5740120300AC1F38C6415000411C110000D7D22EA88D511C0200AC1F3806C0583802150000080E1403001E80800A04000100AC1F38C661A820400000060401004E1403001E80801114000100AC1F38C72EE000AC1F38C72EE00100010063AA34AB"
+,
+ ByteList = hexstr2bytes(Setup),
+ asn1_wrapper:decode('H323-MESSAGES','H323-UU-PDU',ByteList).
+
+t1() ->
+ AdmissionRequest = "27900007086000340036003300320038003700370101805337010180533600AC1F38C60693000D000445367AE75C5740120300AC1F38C6415004E0200100110000D7D22EA88D511C0200AC1F38C6C0580100",
+ ByteList = hexstr2bytes(AdmissionRequest),
+ asn1_wrapper:decode('H323-MESSAGES','RasMessage',ByteList).
+
+t2() ->
+ Cs = "080200040504038090A56C059132303033700591323030347E00930500B8060008914A0001010180533622C000000000074572696373736F6E0356302E3100010180533700AC1F38C206B80045367AE75C5740120300AC1F38C6415000411C110000D7D22EA88D511C0200AC1F3806C0583802150000080E1403001E80800A04000100AC1F38C661A820400000060401004E1403001E80801114000100AC1F38C72EE000AC1F38C72EE00100010063AA34AB",
+ ByteList = hexstr2bytes(Cs),
+ asn1_wrapper:decode('H323-MESSAGES','H323-UU-PDU',ByteList).
+
+t3() ->
+ Cs = "10b8060008914a0002044003004d0067006f006e018085cc22c0b500534c164d6963726f736f6674ae204e65744d656574696e67ae0003332e3000000101808c990088e1293a06b8001689edc5bf23d3118c2d00c04f4b1cd0000c07000a00000204dc40b500534c3c0200000028000000000000001b0000008138427484ccd211b4e300a0c90d0660100000001289edc5bf23d3118c2d00c04f4b1cd00000000000000000a615d9ee",
+ ByteList = hexstr2bytes(Cs),
+ asn1_wrapper:decode('H323-MESSAGES','H323-UU-PDU',ByteList).
+
+dec_alerting() ->
+ Cs = "0380060008914a0002020120110000000000000000000000000000000000",
+ _Slask="E83AE983",
+ ByteList = hexstr2bytes(Cs),
+ asn1_wrapper:decode('H323-MESSAGES','H323-UserInformation',ByteList).
+
+enc_alerting(V) ->
+ asn1_wrapper:encode('H323-MESSAGES','H323-UserInformation',V).
+
+alerting() ->
+ ?line {ok,V} = dec_alerting(),
+ ?line {ok,B} = enc_alerting(V),
+ ?line ByteList = lists:flatten(B),
+ ?line {ok,V} = asn1_wrapper:decode('H323-MESSAGES','H323-UserInformation',ByteList).
+
+
+dec_connect() ->
+ Cs = "02c0060008914a00020088e1293a04a322c0b500534c164d6963726f736f6674ae204e65744d656474696e67ae0003332e3000001689edc5bf23d3118c2d00c04f4b1cd00900110000000000000000000000000000000000",
+ _Slask="2f530a3f",
+ ByteList = hexstr2bytes(Cs),
+ asn1_wrapper:decode('H323-MESSAGES','H323-UserInformation',ByteList).
+
+enc_connect(V) ->
+ asn1_wrapper:encode('H323-MESSAGES','H323-UserInformation',V).
+
+connect() ->
+ ?line {ok,V} = dec_connect(),
+ ?line {ok,B} = enc_connect(V),
+ ?line ByteList = lists:flatten(B),
+ ?line {ok,V} = asn1_wrapper:decode('H323-MESSAGES','H323-UserInformation',ByteList).
+
+dec_h245_TCS() ->
+ Cs ="02700106000881750003"
+ "800d00003c000100000100000100000e"
+ "807fff04b5428080010180000e483060"
+ "0100800c96a88000002020b500534c48"
+ "020000000000f4010000f40101000400"
+ "0000000002000100401f000000100000"
+ "000104002000f4010700000100000002"
+ "00ff00000000c0004000f0000000cc01"
+ "30ff880118ff00008000012040b38000"
+ "0220c0b38000032020b500534c280200"
+ "00000000a0000000a000040010000000"
+ "000070000100401f0000580200000c00"
+ "1000000000008000042020b500534c28"
+ "020000000000a0000000a00004001000"
+ "0000000071000100401f00003a070000"
+ "25001000000000008000052020b50053"
+ "4c280200000000008000000080000500"
+ "14000000000072000100401f00000809"
+ "000025001000000000008000062020b5"
+ "00534c28020000000000800000008000"
+ "050014000000000073000100401f0000"
+ "7f0a00002b0010000000000080000722"
+ "000b40000909a00120390c000a099001"
+ "20390c000b09880120390c000c08a220"
+ "3940000d089220390004800602070007"
+ "00060004000500020001000000030000"
+ "0a00000e800702070007000600040005"
+ "000200010000000300000900000e8008"
+ "02070007000600040005000200010000"
+ "000300000c00000e8009020700070006"
+ "00040005000200010000000300000b00"
+ "000e800a020700070006000400050002"
+ "00010000000300000d00000e0300000b"
+ "01003280299d93369631bc",
+ ByteList = hexstr2bytes(Cs),
+ asn1_wrapper:decode('MULTIMEDIA-SYSTEM-CONTROL',
+ 'MultimediaSystemControlMessage',ByteList).
+
+ hexstr2bytes([D1,D2|T]) ->
+ [dig2num(D1)*16+dig2num(D2)|hexstr2bytes(T)];
+hexstr2bytes([]) ->
+ [].
+
+dig2num(D) when D >= $0, D =< $9 ->
+ D - $0;
+dig2num(D) when D >= $a, D =< $f ->
+ 10 + D - $a;
+dig2num(D) when D >= $A, D =< $F ->
+ 10 + D - $A.
+
+bytes2hexstr(Bytes) ->
+ bytes2hexstr(Bytes,[]).
+
+bytes2hexstr([B|Bytes],Acc) ->
+ D1 = num2dig(B bsr 4),
+ D2 = num2dig(B band 15),
+ bytes2hexstr(Bytes,[D2,D1|Acc]);
+bytes2hexstr([],Acc) ->
+ lists:reverse(Acc).
+
+num2dig(Num) when Num =< 9 ->
+ $0 + Num;
+num2dig(Num) ->
+ $a + Num - 10.
+
+
+
+
+
+
diff --git a/lib/asn1/test/testChoExtension.erl b/lib/asn1/test/testChoExtension.erl
new file mode 100644
index 0000000000..125dfaa3bd
--- /dev/null
+++ b/lib/asn1/test/testChoExtension.erl
@@ -0,0 +1,76 @@
+%%
+%% %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(testChoExtension).
+
+-export([compile/3]).
+-export([extension/1]).
+
+-include("test_server.hrl").
+
+
+compile(Config,Rules,Options) ->
+
+ ?line DataDir = ?config(data_dir,Config),
+ ?line OutDir = ?config(priv_dir,Config),
+ ?line true = code:add_patha(?config(priv_dir,Config)),
+ ?line ok = asn1ct:compile(DataDir ++ "ChoExtension",[Rules,{outdir,OutDir}] ++ Options).
+
+
+
+extension(_Rules) ->
+
+ ?line {ok,Bytes1} = asn1_wrapper:encode('ChoExtension','ChoExt1',{'ChoExt1',{bool,true}}),
+ ?line {ok,{bool,true}} =
+ asn1_wrapper:decode('ChoExtension','ChoExt1',lists:flatten(Bytes1)),
+
+ ?line {ok,Bytes2} = asn1_wrapper:encode('ChoExtension','ChoExt1',{'ChoExt1',{int,33}}),
+ ?line {ok,{int,33}} =
+ asn1_wrapper:decode('ChoExtension','ChoExt1',lists:flatten(Bytes2)),
+
+ %% A trick to encode with another compatible CHOICE type to test reception
+ %% extension alternative
+
+ ?line {ok,Bytes2x} = asn1_wrapper:encode('ChoExtension','ChoExt1x',{str,"abc"}),
+ ?line {ok,Val2x} =
+ asn1_wrapper:decode('ChoExtension','ChoExt1',lists:flatten(Bytes2x)),
+ io:format("Choice extension alternative = ~p~n",[Val2x]),
+
+ ?line {ok,Bytes3} = asn1_wrapper:encode('ChoExtension','ChoExt2',{'ChoExt2',{bool,true}}),
+ ?line {ok,{bool,true}} =
+ asn1_wrapper:decode('ChoExtension','ChoExt2',lists:flatten(Bytes3)),
+
+ ?line {ok,Bytes4} = asn1_wrapper:encode('ChoExtension','ChoExt2',{'ChoExt2',{int,33}}),
+ ?line {ok,{int,33}} =
+ asn1_wrapper:decode('ChoExtension','ChoExt2',lists:flatten(Bytes4)),
+
+ ?line {ok,Bytes5} = asn1_wrapper:encode('ChoExtension','ChoExt3',{'ChoExt3',{bool,true}}),
+ ?line {ok,{bool,true}} =
+ asn1_wrapper:decode('ChoExtension','ChoExt3',lists:flatten(Bytes5)),
+
+ ?line {ok,Bytes6} = asn1_wrapper:encode('ChoExtension','ChoExt3',{'ChoExt3',{int,33}}),
+ ?line {ok,{int,33}} =
+ asn1_wrapper:decode('ChoExtension','ChoExt3',lists:flatten(Bytes6)),
+
+ Val7 = {str,"abc"},
+ ?line {ok,Bytes7} = asn1_wrapper:encode('ChoExtension','ChoExt4',Val7),
+ ?line {ok,Val7} = asn1_wrapper:decode('ChoExtension','ChoExt4',lists:flatten(Bytes7)),
+
+
+ ok.
diff --git a/lib/asn1/test/testChoExternal.erl b/lib/asn1/test/testChoExternal.erl
new file mode 100644
index 0000000000..5f804d9d7f
--- /dev/null
+++ b/lib/asn1/test/testChoExternal.erl
@@ -0,0 +1,99 @@
+%%
+%% %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(testChoExternal).
+
+
+-export([compile/3]).
+-export([external/1]).
+
+-include("test_server.hrl").
+-include("External.hrl").
+
+
+
+compile(Config,Rules,Optimize) ->
+
+ ?line DataDir = ?config(data_dir,Config),
+ ?line OutDir = ?config(priv_dir,Config),
+ ?line true = code:add_patha(?config(priv_dir,Config)),
+ ?line ok = asn1ct:compile(DataDir ++ "ChoExternal",[Rules,{outdir,OutDir}]++Optimize).
+
+
+
+external(_Rules) ->
+
+ ?line {ok,Bytes11} = asn1_wrapper:encode('ChoExternal','ChoXCho',{'ChoXCho',{boolCho,true}}),
+ ?line {ok,{boolCho,true}} = asn1_wrapper:decode('ChoExternal','ChoXCho',lists:flatten(Bytes11)),
+
+
+ ?line {ok,Bytes12} = asn1_wrapper:encode('ChoExternal','ChoXCho',{'ChoXCho',{intCho,77}}),
+ ?line {ok,{intCho,77}} = asn1_wrapper:decode('ChoExternal','ChoXCho',lists:flatten(Bytes12)),
+
+
+
+ ?line {ok,Bytes21} = asn1_wrapper:encode('ChoExternal','ChoXBool',{'ChoXBool',{xbool,true}}),
+ ?line {ok,{xbool,true}} = asn1_wrapper:decode('ChoExternal','ChoXBool',lists:flatten(Bytes21)),
+
+
+ ?line {ok,Bytes22} = asn1_wrapper:encode('ChoExternal','ChoXBool',{'ChoXBool',{xboolImp,true}}),
+ ?line {ok,{xboolImp,true}} = asn1_wrapper:decode('ChoExternal','ChoXBool',lists:flatten(Bytes22)),
+
+
+ ?line {ok,Bytes23} = asn1_wrapper:encode('ChoExternal','ChoXBool',{'ChoXBool',{xboolExp,true}}),
+ ?line {ok,{xboolExp,true}} = asn1_wrapper:decode('ChoExternal','ChoXBool',lists:flatten(Bytes23)),
+
+
+
+ ?line {ok,Bytes31} = asn1_wrapper:encode('ChoExternal','NT',{os,"kalle"}),
+ ?line {ok,{os,"kalle"}} = asn1_wrapper:decode('ChoExternal','NT',lists:flatten(Bytes31)),
+
+ ?line {ok,Bytes32} = asn1_wrapper:encode('ChoExternal','Exp',{os,"kalle"}),
+ ?line {ok,{os,"kalle"}} = asn1_wrapper:decode('ChoExternal','Exp',lists:flatten(Bytes32)),
+
+ ?line {ok,Bytes33} = asn1_wrapper:encode('ChoExternal','NTNT',{os,"kalle"}),
+ ?line {ok,{os,"kalle"}} = asn1_wrapper:decode('ChoExternal','NTNT',lists:flatten(Bytes33)),
+
+ ?line {ok,Bytes34} = asn1_wrapper:encode('ChoExternal','NTExp',{os,"kalle"}),
+ ?line {ok,{os,"kalle"}} = asn1_wrapper:decode('ChoExternal','NTExp',lists:flatten(Bytes34)),
+
+ ?line {ok,Bytes35} = asn1_wrapper:encode('ChoExternal','ExpNT',{os,"kalle"}),
+ ?line {ok,{os,"kalle"}} = asn1_wrapper:decode('ChoExternal','ExpNT',lists:flatten(Bytes35)),
+
+ ?line {ok,Bytes36} = asn1_wrapper:encode('ChoExternal','ExpExp',{os,"kalle"}),
+ ?line {ok,{os,"kalle"}} = asn1_wrapper:decode('ChoExternal','ExpExp',lists:flatten(Bytes36)),
+
+
+
+
+
+ ?line {ok,Bytes41} = asn1_wrapper:encode('ChoExternal','XNTNT',{os,"kalle"}),
+ ?line {ok,{os,"kalle"}} = asn1_wrapper:decode('ChoExternal','XNTNT',lists:flatten(Bytes41)),
+
+ ?line {ok,Bytes42} = asn1_wrapper:encode('ChoExternal','XNTExp',{os,"kalle"}),
+ ?line {ok,{os,"kalle"}} = asn1_wrapper:decode('ChoExternal','XNTExp',lists:flatten(Bytes42)),
+
+ ?line {ok,Bytes43} = asn1_wrapper:encode('ChoExternal','XExpNT',{os,"kalle"}),
+ ?line {ok,{os,"kalle"}} = asn1_wrapper:decode('ChoExternal','XExpNT',lists:flatten(Bytes43)),
+
+ ?line {ok,Bytes44} = asn1_wrapper:encode('ChoExternal','XExpExp',{os,"kalle"}),
+ ?line {ok,{os,"kalle"}} = asn1_wrapper:decode('ChoExternal','XExpExp',lists:flatten(Bytes44)),
+
+ ok.
+
diff --git a/lib/asn1/test/testChoOptional.erl b/lib/asn1/test/testChoOptional.erl
new file mode 100644
index 0000000000..2d969391d0
--- /dev/null
+++ b/lib/asn1/test/testChoOptional.erl
@@ -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%
+%%
+%%
+-module(testChoOptional).
+
+
+-export([compile/3]).
+-export([optional/1]).
+
+%-include("ChoOptional.hrl").
+-include("test_server.hrl").
+-include("External.hrl").
+
+
+-record('Seq1',{bool, int = asn1_NOVALUE, cho = asn1_NOVALUE}).
+-record('Seq2',{int = asn1_NOVALUE, cho = asn1_NOVALUE, bool}).
+-record('Seq3',{cho = asn1_NOVALUE, int = asn1_NOVALUE, bool}).
+
+
+compile(Config,Rules,Options) ->
+
+ ?line DataDir = ?config(data_dir,Config),
+ ?line OutDir = ?config(priv_dir,Config),
+ ?line true = code:add_patha(?config(priv_dir,Config)),
+ ?line ok = asn1ct:compile(DataDir ++ "ChoOptional",[Rules,{outdir,OutDir}]++Options).
+
+
+
+optional(_Rules) ->
+
+ ?line {ok,Bytes11} = asn1_wrapper:encode('ChoOptional','Seq1',#'Seq1'{bool = true}),
+ ?line {ok,{'Seq1',true,asn1_NOVALUE,asn1_NOVALUE}} =
+ asn1_wrapper:decode('ChoOptional','Seq1',lists:flatten(Bytes11)),
+
+ ?line {ok,Bytes12} = asn1_wrapper:encode('ChoOptional','Seq1',#'Seq1'{bool = true,
+ int = 233}),
+ ?line {ok,{'Seq1',true,233,asn1_NOVALUE}} =
+ asn1_wrapper:decode('ChoOptional','Seq1',lists:flatten(Bytes12)),
+
+ ?line {ok,Bytes13} = asn1_wrapper:encode('ChoOptional','Seq1',#'Seq1'{bool = true,
+ cho = {vsCho,"Vs Str"}}),
+ ?line {ok,{'Seq1',true,asn1_NOVALUE,{vsCho,"Vs Str"}}} =
+ asn1_wrapper:decode('ChoOptional','Seq1',lists:flatten(Bytes13)),
+
+ ?line {ok,Bytes14} =
+ asn1_wrapper:encode('ChoOptional','Seq1',#'Seq1'{bool = true,
+ cho = {ocStrCho,"Oct Str"}}),
+ ?line {ok,{'Seq1',true,asn1_NOVALUE,{ocStrCho,"Oct Str"}}} =
+ asn1_wrapper:decode('ChoOptional','Seq1',lists:flatten(Bytes14)),
+
+
+
+ ?line {ok,Bytes21} = asn1_wrapper:encode('ChoOptional','Seq2',#'Seq2'{bool = true}),
+ ?line {ok,{'Seq2',asn1_NOVALUE,asn1_NOVALUE,true}} =
+ asn1_wrapper:decode('ChoOptional','Seq2',lists:flatten(Bytes21)),
+
+ ?line {ok,Bytes22} = asn1_wrapper:encode('ChoOptional','Seq2',#'Seq2'{bool = true,
+ int = 233}),
+ ?line {ok,{'Seq2',233,asn1_NOVALUE,true}} =
+ asn1_wrapper:decode('ChoOptional','Seq2',lists:flatten(Bytes22)),
+
+ ?line {ok,Bytes23} = asn1_wrapper:encode('ChoOptional','Seq2',#'Seq2'{bool = true,
+ cho = {vsCho,"Vs Str"}}),
+ ?line {ok,{'Seq2',asn1_NOVALUE,{vsCho,"Vs Str"},true}} =
+ asn1_wrapper:decode('ChoOptional','Seq2',lists:flatten(Bytes23)),
+
+ ?line {ok,Bytes24} =
+ asn1_wrapper:encode('ChoOptional','Seq2',#'Seq2'{bool = true,
+ cho = {ocStrCho,"Oct Str"}}),
+ ?line {ok,{'Seq2',asn1_NOVALUE,{ocStrCho,"Oct Str"},true}} =
+ asn1_wrapper:decode('ChoOptional','Seq2',lists:flatten(Bytes24)),
+
+
+
+ ?line {ok,Bytes31} = asn1_wrapper:encode('ChoOptional','Seq3',#'Seq3'{bool = true}),
+ ?line {ok,{'Seq3',asn1_NOVALUE,asn1_NOVALUE,true}} =
+ asn1_wrapper:decode('ChoOptional','Seq3',lists:flatten(Bytes31)),
+
+ ?line {ok,Bytes32} = asn1_wrapper:encode('ChoOptional','Seq3',#'Seq3'{bool = true,
+ int = 233}),
+ ?line {ok,{'Seq3',asn1_NOVALUE,233,true}} =
+ asn1_wrapper:decode('ChoOptional','Seq3',lists:flatten(Bytes32)),
+
+ ?line {ok,Bytes33} = asn1_wrapper:encode('ChoOptional','Seq3',#'Seq3'{bool = true,
+ cho = {vsCho,"Vs Str"}}),
+ ?line {ok,{'Seq3',{vsCho,"Vs Str"},asn1_NOVALUE,true}} =
+ asn1_wrapper:decode('ChoOptional','Seq3',lists:flatten(Bytes33)),
+
+ ?line {ok,Bytes34} =
+ asn1_wrapper:encode('ChoOptional','Seq3',#'Seq3'{bool = true,
+ cho = {ocStrCho,"Oct Str"}}),
+ ?line {ok,{'Seq3',{ocStrCho,"Oct Str"},asn1_NOVALUE,true}} =
+ asn1_wrapper:decode('ChoOptional','Seq3',lists:flatten(Bytes34)),
+
+
+
+ ok.
diff --git a/lib/asn1/test/testChoOptionalImplicitTag.erl b/lib/asn1/test/testChoOptionalImplicitTag.erl
new file mode 100644
index 0000000000..30addf2e20
--- /dev/null
+++ b/lib/asn1/test/testChoOptionalImplicitTag.erl
@@ -0,0 +1,113 @@
+%%
+%% %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(testChoOptionalImplicitTag).
+
+
+-export([compile/2]).
+-export([optional/1]).
+
+%-include("ChoOptional.hrl").
+-include("test_server.hrl").
+-include("External.hrl").
+
+
+-record('Seq1',{bool, int = asn1_NOVALUE, cho = asn1_NOVALUE}).
+-record('Seq2',{int = asn1_NOVALUE, cho = asn1_NOVALUE, bool}).
+-record('Seq3',{cho = asn1_NOVALUE, int = asn1_NOVALUE, bool}).
+
+
+compile(Config,Rules) ->
+
+ ?line DataDir = ?config(data_dir,Config),
+ ?line OutDir = ?config(priv_dir,Config),
+ ?line true = code:add_patha(?config(priv_dir,Config)),
+ ?line ok = asn1ct:compile(DataDir ++ "ChoOptionalImplicitTag",[Rules,{outdir,OutDir}]).
+
+
+
+optional(_Rules) ->
+
+ ?line {ok,Bytes11} = asn1_wrapper:encode('ChoOptionalImplicitTag','Seq1',#'Seq1'{bool = true}),
+ ?line {ok,{'Seq1',true,asn1_NOVALUE,asn1_NOVALUE}} =
+ asn1_wrapper:decode('ChoOptionalImplicitTag','Seq1',lists:flatten(Bytes11)),
+
+ ?line {ok,Bytes12} = asn1_wrapper:encode('ChoOptionalImplicitTag','Seq1',#'Seq1'{bool = true,
+ int = 233}),
+ ?line {ok,{'Seq1',true,233,asn1_NOVALUE}} =
+ asn1_wrapper:decode('ChoOptionalImplicitTag','Seq1',lists:flatten(Bytes12)),
+
+ ?line {ok,Bytes13} = asn1_wrapper:encode('ChoOptionalImplicitTag','Seq1',#'Seq1'{bool = true,
+ cho = {vsCho,"Vs Str"}}),
+ ?line {ok,{'Seq1',true,asn1_NOVALUE,{vsCho,"Vs Str"}}} =
+ asn1_wrapper:decode('ChoOptionalImplicitTag','Seq1',lists:flatten(Bytes13)),
+
+ ?line {ok,Bytes14} =
+ asn1_wrapper:encode('ChoOptionalImplicitTag','Seq1',#'Seq1'{bool = true,
+ cho = {ocStrCho,"Oct Str"}}),
+ ?line {ok,{'Seq1',true,asn1_NOVALUE,{ocStrCho,"Oct Str"}}} =
+ asn1_wrapper:decode('ChoOptionalImplicitTag','Seq1',lists:flatten(Bytes14)),
+
+
+
+ ?line {ok,Bytes21} = asn1_wrapper:encode('ChoOptionalImplicitTag','Seq2',#'Seq2'{bool = true}),
+ ?line {ok,{'Seq2',asn1_NOVALUE,asn1_NOVALUE,true}} =
+ asn1_wrapper:decode('ChoOptionalImplicitTag','Seq2',lists:flatten(Bytes21)),
+
+ ?line {ok,Bytes22} = asn1_wrapper:encode('ChoOptionalImplicitTag','Seq2',#'Seq2'{bool = true,
+ int = 233}),
+ ?line {ok,{'Seq2',233,asn1_NOVALUE,true}} =
+ asn1_wrapper:decode('ChoOptionalImplicitTag','Seq2',lists:flatten(Bytes22)),
+
+ ?line {ok,Bytes23} = asn1_wrapper:encode('ChoOptionalImplicitTag','Seq2',#'Seq2'{bool = true,
+ cho = {vsCho,"Vs Str"}}),
+ ?line {ok,{'Seq2',asn1_NOVALUE,{vsCho,"Vs Str"},true}} =
+ asn1_wrapper:decode('ChoOptionalImplicitTag','Seq2',lists:flatten(Bytes23)),
+
+ ?line {ok,Bytes24} =
+ asn1_wrapper:encode('ChoOptionalImplicitTag','Seq2',#'Seq2'{bool = true,
+ cho = {ocStrCho,"Oct Str"}}),
+ ?line {ok,{'Seq2',asn1_NOVALUE,{ocStrCho,"Oct Str"},true}} =
+ asn1_wrapper:decode('ChoOptionalImplicitTag','Seq2',lists:flatten(Bytes24)),
+
+
+
+ ?line {ok,Bytes31} = asn1_wrapper:encode('ChoOptionalImplicitTag','Seq3',#'Seq3'{bool = true}),
+ ?line {ok,{'Seq3',asn1_NOVALUE,asn1_NOVALUE,true}} =
+ asn1_wrapper:decode('ChoOptionalImplicitTag','Seq3',lists:flatten(Bytes31)),
+
+ ?line {ok,Bytes32} = asn1_wrapper:encode('ChoOptionalImplicitTag','Seq3',#'Seq3'{bool = true,
+ int = 233}),
+ ?line {ok,{'Seq3',asn1_NOVALUE,233,true}} =
+ asn1_wrapper:decode('ChoOptionalImplicitTag','Seq3',lists:flatten(Bytes32)),
+
+ ?line {ok,Bytes33} = asn1_wrapper:encode('ChoOptionalImplicitTag','Seq3',#'Seq3'{bool = true,
+ cho = {vsCho,"Vs Str"}}),
+ ?line {ok,{'Seq3',{vsCho,"Vs Str"},asn1_NOVALUE,true}} =
+ asn1_wrapper:decode('ChoOptionalImplicitTag','Seq3',lists:flatten(Bytes33)),
+
+ ?line {ok,Bytes34} =
+ asn1_wrapper:encode('ChoOptionalImplicitTag','Seq3',#'Seq3'{bool = true,
+ cho = {ocStrCho,"Oct Str"}}),
+ ?line {ok,{'Seq3',{ocStrCho,"Oct Str"},asn1_NOVALUE,true}} =
+ asn1_wrapper:decode('ChoOptionalImplicitTag','Seq3',lists:flatten(Bytes34)),
+
+
+
+ ok.
diff --git a/lib/asn1/test/testChoPrim.erl b/lib/asn1/test/testChoPrim.erl
new file mode 100644
index 0000000000..7fa6164b5a
--- /dev/null
+++ b/lib/asn1/test/testChoPrim.erl
@@ -0,0 +1,115 @@
+%%
+%% %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(testChoPrim).
+
+-export([compile/3]).
+-export([bool/1]).
+-export([int/1]).
+
+-include("test_server.hrl").
+
+
+compile(Config,Rules,Options) ->
+
+ ?line DataDir = ?config(data_dir,Config),
+ ?line OutDir = ?config(priv_dir,Config),
+ ?line true = code:add_patha(?config(priv_dir,Config)),
+ ?line ok = asn1ct:compile(DataDir ++ "ChoPrim",[Rules,{outdir,OutDir}]++Options).
+
+
+
+bool(Rules) ->
+
+ ?line {ok,Bytes11} = asn1_wrapper:encode('ChoPrim','ChoCon',{bool0,true}),
+ ?line {ok,{bool0,true}} = asn1_wrapper:decode('ChoPrim','ChoCon',lists:flatten(Bytes11)),
+
+ ?line {ok,Bytes12} = asn1_wrapper:encode('ChoPrim','ChoCon',{bool1,true}),
+ ?line {ok,{bool1,true}} = asn1_wrapper:decode('ChoPrim','ChoCon',lists:flatten(Bytes12)),
+
+ ?line {ok,Bytes13} = asn1_wrapper:encode('ChoPrim','ChoCon',{int2,233}),
+ ?line {ok,{int2,233}} = asn1_wrapper:decode('ChoPrim','ChoCon',lists:flatten(Bytes13)),
+
+ ?line case asn1_wrapper:erule(Rules) of
+ ber ->
+ ?line {error,{asn1,{invalid_choice_type,wrong}}} =
+ case catch asn1_wrapper:encode('ChoPrim','ChoCon',{wrong,233}) of
+ X1 -> X1 end,
+ ?line {error,{asn1,{invalid_choice_tag,_WrongTag}}} =
+ case catch asn1_wrapper:decode('ChoPrim','ChoCon',[131,2,0,233]) of
+ X2 -> X2 end,
+ ok;
+
+ per ->
+ ok
+ end,
+
+ ok.
+
+
+
+int(Rules) ->
+
+ ?line {ok,Bytes21} = asn1_wrapper:encode('ChoPrim','ChoExp',{int10,1}),
+ ?line {ok,{int10,first}} = asn1_wrapper:decode('ChoPrim','ChoExp',lists:flatten(Bytes21)),
+
+ ?line {ok,Bytes22} = asn1_wrapper:encode('ChoPrim','ChoExp',{int10,first}),
+ ?line {ok,{int10,first}} = asn1_wrapper:decode('ChoPrim','ChoExp',lists:flatten(Bytes22)),
+
+ ?line {ok,Bytes23} = asn1_wrapper:encode('ChoPrim','ChoExp',{int10,last}),
+ ?line {ok,{int10,last}} = asn1_wrapper:decode('ChoPrim','ChoExp',lists:flatten(Bytes23)),
+
+ ?line {ok,Bytes24} = asn1_wrapper:encode('ChoPrim','ChoExp',{bool11,true}),
+ ?line {ok,{bool11,true}} = asn1_wrapper:decode('ChoPrim','ChoExp',lists:flatten(Bytes24)),
+
+
+ ?line {ok,Bytes26} = asn1_wrapper:encode('ChoPrim','ChoExp',{enum12,one}),
+ ?line {ok,{enum12,one}} = asn1_wrapper:decode('ChoPrim','ChoExp',lists:flatten(Bytes26)),
+
+ ?line {ok,Bytes25} = asn1_wrapper:encode('ChoPrim','ChoExp',{bool11,true}),
+ ?line {ok,{bool11,true}} =
+ asn1_wrapper:decode('ChoPrim','ChoExp',lists:flatten(Bytes25)),
+
+ ?line {error,{asn1,_}} =
+ case catch asn1_wrapper:encode('ChoPrim','ChoExp',{enum12,four}) of
+ X3 -> X3 end,
+
+ ?line {error,{asn1,_}} =
+ case catch asn1_wrapper:encode('ChoPrim','ChoExp',{wrong,233}) of
+ X4 -> io:format("error reason = ~p~n",[X4]), X4 end,
+
+ ?line case asn1_wrapper:erule(Rules) of
+ ber ->
+ ?line {error,{asn1,_}} =
+ case catch asn1_wrapper:decode('ChoPrim','ChoExp',[107,3,2,1,1]) of
+ X5 -> X5 end,
+ ok;
+
+ per ->
+ ok
+ end,
+ ok.
+
+
+
+
+
+
+
+
diff --git a/lib/asn1/test/testChoRecursive.erl b/lib/asn1/test/testChoRecursive.erl
new file mode 100644
index 0000000000..f8c5e60f55
--- /dev/null
+++ b/lib/asn1/test/testChoRecursive.erl
@@ -0,0 +1,76 @@
+%%
+%% %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(testChoRecursive).
+
+
+-export([compile/3]).
+-export([recursive/1]).
+
+-include("test_server.hrl").
+
+-record('ChoRec_something',{a, b, c}).
+-record('ChoRec2_something',{a, b, c}).
+
+
+compile(Config,Rules,Options) ->
+
+ ?line DataDir = ?config(data_dir,Config),
+ ?line OutDir = ?config(priv_dir,Config),
+ ?line true = code:add_patha(?config(priv_dir,Config)),
+ ?line ok = asn1ct:compile(DataDir ++ "ChoRecursive",[Rules,{outdir,OutDir}]++Options).
+
+
+
+recursive(_Rules) ->
+
+ ?line {ok,Bytes11} = asn1_wrapper:encode('ChoRecursive','ChoRec',{'ChoRec',{something,
+ #'ChoRec_something'{a = 77,
+ b = "some octets here",
+ c = {'ChoRec',{nothing,'NULL'}}}}}),
+ ?line {ok,{something,{'ChoRec_something',77,"some octets here",{nothing,'NULL'}}}} =
+ asn1_wrapper:decode('ChoRecursive','ChoRec',lists:flatten(Bytes11)),
+
+
+ ?line {ok,Bytes12} = asn1_wrapper:encode('ChoRecursive','ChoRec',{'ChoRec',{nothing,'NULL'}}),
+ ?line {ok,{nothing,'NULL'}} =
+ asn1_wrapper:decode('ChoRecursive','ChoRec',lists:flatten(Bytes12)),
+
+
+
+ ?line {ok,Bytes21} =
+ asn1_wrapper:encode('ChoRecursive','ChoRec2',{'ChoRec2',
+ {something,
+ #'ChoRec2_something'{a = 77,
+ b = "some octets here",
+ c = {'ChoRec2',
+ {nothing,'NULL'}}}}}),
+ ?line {ok,{something,{'ChoRec2_something',77,"some octets here",{nothing,'NULL'}}}} =
+ asn1_wrapper:decode('ChoRecursive','ChoRec2',lists:flatten(Bytes21)),
+
+
+ ?line {ok,Bytes22} =
+ asn1_wrapper:encode('ChoRecursive','ChoRec2',{'ChoRec2',{nothing,'NULL'}}),
+ ?line {ok,{nothing,'NULL'}} =
+ asn1_wrapper:decode('ChoRecursive','ChoRec2',lists:flatten(Bytes22)),
+
+
+
+
+ ok.
diff --git a/lib/asn1/test/testChoTypeRefCho.erl b/lib/asn1/test/testChoTypeRefCho.erl
new file mode 100644
index 0000000000..341a77c21b
--- /dev/null
+++ b/lib/asn1/test/testChoTypeRefCho.erl
@@ -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%
+%%
+%%
+-module(testChoTypeRefCho).
+
+-export([compile/3]).
+-export([choice/1]).
+
+-include("test_server.hrl").
+
+
+
+compile(Config,Rules,Options) ->
+
+ ?line DataDir = ?config(data_dir,Config),
+ ?line OutDir = ?config(priv_dir,Config),
+ ?line true = code:add_patha(?config(priv_dir,Config)),
+ ?line ok = asn1ct:compile(DataDir ++ "ChoTypeRefCho",[Rules,{outdir,OutDir}]++Options).
+
+
+
+choice(_Rules) ->
+
+ ?line {ok,Bytes11} = asn1_wrapper:encode('ChoTypeRefCho','ChoTRcho',{choCho,{choInt,88}}),
+ ?line {ok,{choCho,{choInt,88}}} =
+ asn1_wrapper:decode('ChoTypeRefCho','ChoTRcho',lists:flatten(Bytes11)),
+
+ ?line {ok,Bytes12} = asn1_wrapper:encode('ChoTypeRefCho','ChoTRcho',{choChoE,{choInt,88}}),
+ ?line {ok,{choChoE,{choInt,88}}} =
+ asn1_wrapper:decode('ChoTypeRefCho','ChoTRcho',lists:flatten(Bytes12)),
+
+ ?line {ok,Bytes13} = asn1_wrapper:encode('ChoTypeRefCho','ChoTRcho',{'choCho-E',{choInt,88}}),
+ ?line {ok,{'choCho-E',{choInt,88}}} =
+ asn1_wrapper:decode('ChoTypeRefCho','ChoTRcho',lists:flatten(Bytes13)),
+
+ ?line {ok,Bytes14} = asn1_wrapper:encode('ChoTypeRefCho','ChoTRcho',{'choChoE-E',{choInt,88}}),
+ ?line {ok,{'choChoE-E',{choInt,88}}} =
+ asn1_wrapper:decode('ChoTypeRefCho','ChoTRcho',lists:flatten(Bytes14)),
+
+
+
+ ?line {ok,Bytes21} = asn1_wrapper:encode('ChoTypeRefCho','ChoChoInline',{bool1,true}),
+ ?line {ok,{bool1,true}} =
+ asn1_wrapper:decode('ChoTypeRefCho','ChoChoInline',lists:flatten(Bytes21)),
+
+ ?line {ok,Bytes22} = asn1_wrapper:encode('ChoTypeRefCho','ChoChoInline',{'choCho',{bool,true}}),
+ ?line {ok,{'choCho',{bool,true}}} =
+ asn1_wrapper:decode('ChoTypeRefCho','ChoChoInline',lists:flatten(Bytes22)),
+
+ ?line {ok,Bytes23} = asn1_wrapper:encode('ChoTypeRefCho','ChoChoInline',{'choCho',{octStr,"kk"}}),
+ ?line {ok,{'choCho',{octStr,"kk"}}} =
+ asn1_wrapper:decode('ChoTypeRefCho','ChoChoInline',lists:flatten(Bytes23)),
+
+ ?line {ok,Bytes24} = asn1_wrapper:encode('ChoTypeRefCho','ChoChoInline',{'choCho',{int,55}}),
+ ?line {ok,{'choCho',{int,55}}} =
+ asn1_wrapper:decode('ChoTypeRefCho','ChoChoInline',lists:flatten(Bytes24)),
+
+
+
+
+
+ ok.
diff --git a/lib/asn1/test/testChoTypeRefPrim.erl b/lib/asn1/test/testChoTypeRefPrim.erl
new file mode 100644
index 0000000000..1ef221819c
--- /dev/null
+++ b/lib/asn1/test/testChoTypeRefPrim.erl
@@ -0,0 +1,95 @@
+%%
+%% %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(testChoTypeRefPrim).
+
+-export([compile/3]).
+-export([prim/1]).
+
+-include("test_server.hrl").
+
+
+
+compile(Config,Rules,Options) ->
+
+ ?line DataDir = ?config(data_dir,Config),
+ ?line OutDir = ?config(priv_dir,Config),
+ ?line true = code:add_patha(?config(priv_dir,Config)),
+ ?line ok = asn1ct:compile(DataDir ++ "ChoTypeRefPrim",[Rules,{outdir,OutDir}]++Options).
+
+
+
+prim(_Rules) ->
+
+ ?line {ok,Bytes11} = asn1_wrapper:encode('ChoTypeRefPrim','ChoTR',{bool,true}),
+ ?line {ok,{bool,true}} = asn1_wrapper:decode('ChoTypeRefPrim','ChoTR',lists:flatten(Bytes11)),
+
+ ?line {ok,Bytes12} =
+ asn1_wrapper:encode('ChoTypeRefPrim','ChoTR',{octStr,[11,12,13,14,15,16,17]}),
+ ?line {ok,{octStr,[11,12,13,14,15,16,17]}} =
+ asn1_wrapper:decode('ChoTypeRefPrim','ChoTR',lists:flatten(Bytes12)),
+
+ ?line {ok,Bytes13} = asn1_wrapper:encode('ChoTypeRefPrim','ChoTR',{int,233}),
+ ?line {ok,{int,233}} = asn1_wrapper:decode('ChoTypeRefPrim','ChoTR',lists:flatten(Bytes13)),
+
+ ?line {ok,Bytes14} =
+ asn1_wrapper:encode('ChoTypeRefPrim','ChoTR',{octStr,"Stringing in the rain"}),
+ ?line {ok,{octStr,"Stringing in the rain"}} =
+ asn1_wrapper:decode('ChoTypeRefPrim','ChoTR',lists:flatten(Bytes14)),
+
+
+
+ ?line {ok,Bytes21} = asn1_wrapper:encode('ChoTypeRefPrim','ChoTR2',{'octStr',"A string"}),
+ ?line {ok,{'octStr',"A string"}} =
+ asn1_wrapper:decode('ChoTypeRefPrim','ChoTR2',lists:flatten(Bytes21)),
+
+ ?line {ok,Bytes22} = asn1_wrapper:encode('ChoTypeRefPrim','ChoTR2',{'octStrI',"A string"}),
+ ?line {ok,{'octStrI',"A string"}} =
+ asn1_wrapper:decode('ChoTypeRefPrim','ChoTR2',lists:flatten(Bytes22)),
+
+ ?line {ok,Bytes23} = asn1_wrapper:encode('ChoTypeRefPrim','ChoTR2',{'octStrE',"A string"}),
+ ?line {ok,{'octStrE',"A string"}} =
+ asn1_wrapper:decode('ChoTypeRefPrim','ChoTR2',lists:flatten(Bytes23)),
+
+ ?line {ok,Bytes24} = asn1_wrapper:encode('ChoTypeRefPrim','ChoTR2',{'octStr-I',"A string"}),
+ ?line {ok,{'octStr-I',"A string"}} =
+ asn1_wrapper:decode('ChoTypeRefPrim','ChoTR2',lists:flatten(Bytes24)),
+
+ ?line {ok,Bytes25} = asn1_wrapper:encode('ChoTypeRefPrim','ChoTR2',{'octStrI-I',"A string"}),
+ ?line {ok,{'octStrI-I',"A string"}} =
+ asn1_wrapper:decode('ChoTypeRefPrim','ChoTR2',lists:flatten(Bytes25)),
+
+ ?line {ok,Bytes26} = asn1_wrapper:encode('ChoTypeRefPrim','ChoTR2',{'octStrE-I',"A string"}),
+ ?line {ok,{'octStrE-I',"A string"}} =
+ asn1_wrapper:decode('ChoTypeRefPrim','ChoTR2',lists:flatten(Bytes26)),
+
+ ?line {ok,Bytes27} = asn1_wrapper:encode('ChoTypeRefPrim','ChoTR2',{'octStr-E',"A string"}),
+ ?line {ok,{'octStr-E',"A string"}} =
+ asn1_wrapper:decode('ChoTypeRefPrim','ChoTR2',lists:flatten(Bytes27)),
+
+ ?line {ok,Bytes28} = asn1_wrapper:encode('ChoTypeRefPrim','ChoTR2',{'octStrI-E',"A string"}),
+ ?line {ok,{'octStrI-E',"A string"}} =
+ asn1_wrapper:decode('ChoTypeRefPrim','ChoTR2',lists:flatten(Bytes28)),
+
+ ?line {ok,Bytes29} = asn1_wrapper:encode('ChoTypeRefPrim','ChoTR2',{'octStrE-E',"A string"}),
+ ?line {ok,{'octStrE-E',"A string"}} =
+ asn1_wrapper:decode('ChoTypeRefPrim','ChoTR2',lists:flatten(Bytes29)),
+
+
+ ok.
diff --git a/lib/asn1/test/testChoTypeRefSeq.erl b/lib/asn1/test/testChoTypeRefSeq.erl
new file mode 100644
index 0000000000..2e9aa7c411
--- /dev/null
+++ b/lib/asn1/test/testChoTypeRefSeq.erl
@@ -0,0 +1,115 @@
+%%
+%% %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(testChoTypeRefSeq).
+
+-export([compile/3]).
+-export([seq/1]).
+
+-include("test_server.hrl").
+
+-record('ChoSeq',{seqInt, seqOs}).
+-record('ChoSeqImp',{seqInt, seqOs}).
+-record('ChoSeqExp',{seqInt, seqOs}).
+
+
+compile(Config,Rules,Options) ->
+
+ ?line DataDir = ?config(data_dir,Config),
+ ?line OutDir = ?config(priv_dir,Config),
+ ?line true = code:add_patha(?config(priv_dir,Config)),
+ ?line ok = asn1ct:compile(DataDir ++ "ChoTypeRefSeq",[Rules,{outdir,OutDir}]++Options).
+
+
+
+seq(_Rules) ->
+
+ ?line {ok,Bytes1} =
+ asn1_wrapper:encode('ChoTypeRefSeq','ChoTRseq',
+ {choSeq,#'ChoSeq'{seqInt = 88,
+ seqOs = "A string"}}),
+ ?line {ok,{choSeq,{'ChoSeq',88,"A string"}}} =
+ asn1_wrapper:decode('ChoTypeRefSeq','ChoTRseq',lists:flatten(Bytes1)),
+
+
+ ?line {ok,Bytes2} =
+ asn1_wrapper:encode('ChoTypeRefSeq','ChoTRseq',
+ {choSeqI,#'ChoSeq'{seqInt = 88,
+ seqOs = "A string"}}),
+ ?line {ok,{choSeqI,{'ChoSeq',88,"A string"}}} =
+ asn1_wrapper:decode('ChoTypeRefSeq','ChoTRseq',lists:flatten(Bytes2)),
+
+
+ ?line {ok,Bytes3} =
+ asn1_wrapper:encode('ChoTypeRefSeq','ChoTRseq',
+ {choSeqE,#'ChoSeq'{seqInt = 88,
+ seqOs = "A string"}}),
+ ?line {ok,{choSeqE,{'ChoSeq',88,"A string"}}} =
+ asn1_wrapper:decode('ChoTypeRefSeq','ChoTRseq',lists:flatten(Bytes3)),
+
+
+ ?line {ok,Bytes4} =
+ asn1_wrapper:encode('ChoTypeRefSeq','ChoTRseq',
+ {'choSeq-I',#'ChoSeqImp'{seqInt = 88,
+ seqOs = "A string"}}),
+ ?line {ok,{'choSeq-I',{'ChoSeqImp',88,"A string"}}} =
+ asn1_wrapper:decode('ChoTypeRefSeq','ChoTRseq',lists:flatten(Bytes4)),
+
+
+ ?line {ok,Bytes5} =
+ asn1_wrapper:encode('ChoTypeRefSeq','ChoTRseq',
+ {'choSeqI-I',#'ChoSeqImp'{seqInt = 88,
+ seqOs = "A string"}}),
+ ?line {ok,{'choSeqI-I',{'ChoSeqImp',88,"A string"}}} =
+ asn1_wrapper:decode('ChoTypeRefSeq','ChoTRseq',lists:flatten(Bytes5)),
+
+
+ ?line {ok,Bytes6} =
+ asn1_wrapper:encode('ChoTypeRefSeq','ChoTRseq',
+ {'choSeqE-I',#'ChoSeqImp'{seqInt = 88,
+ seqOs = "A string"}}),
+ ?line {ok,{'choSeqE-I',{'ChoSeqImp',88,"A string"}}} =
+ asn1_wrapper:decode('ChoTypeRefSeq','ChoTRseq',lists:flatten(Bytes6)),
+
+
+ ?line {ok,Bytes7} =
+ asn1_wrapper:encode('ChoTypeRefSeq','ChoTRseq',
+ {'choSeq-E',#'ChoSeqExp'{seqInt = 88,
+ seqOs = "A string"}}),
+ ?line {ok,{'choSeq-E',{'ChoSeqExp',88,"A string"}}} =
+ asn1_wrapper:decode('ChoTypeRefSeq','ChoTRseq',lists:flatten(Bytes7)),
+
+
+ ?line {ok,Bytes8} =
+ asn1_wrapper:encode('ChoTypeRefSeq','ChoTRseq',
+ {'choSeqI-E',#'ChoSeqExp'{seqInt = 88,
+ seqOs = "A string"}}),
+ ?line {ok,{'choSeqI-E',{'ChoSeqExp',88,"A string"}}} =
+ asn1_wrapper:decode('ChoTypeRefSeq','ChoTRseq',lists:flatten(Bytes8)),
+
+
+ ?line {ok,Bytes9} =
+ asn1_wrapper:encode('ChoTypeRefSeq','ChoTRseq',
+ {'choSeqE-E',#'ChoSeqExp'{seqInt = 88,
+ seqOs = "A string"}}),
+ ?line {ok,{'choSeqE-E',{'ChoSeqExp',88,"A string"}}} =
+ asn1_wrapper:decode('ChoTypeRefSeq','ChoTRseq',lists:flatten(Bytes9)),
+
+
+ ok.
diff --git a/lib/asn1/test/testChoTypeRefSet.erl b/lib/asn1/test/testChoTypeRefSet.erl
new file mode 100644
index 0000000000..e4db73c1e3
--- /dev/null
+++ b/lib/asn1/test/testChoTypeRefSet.erl
@@ -0,0 +1,116 @@
+%%
+%% %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(testChoTypeRefSet).
+
+-export([compile/3]).
+-export([set/1]).
+
+-include("test_server.hrl").
+
+-record('ChoSet',{setInt, setOs}).
+-record('ChoSetImp',{setInt, setOs}).
+-record('ChoSetExp',{setInt, setOs}).
+
+
+compile(Config,Rules,Options) ->
+
+ ?line DataDir = ?config(data_dir,Config),
+ ?line OutDir = ?config(priv_dir,Config),
+ ?line true = code:add_patha(?config(priv_dir,Config)),
+ ?line ok = asn1ct:compile(DataDir ++ "ChoTypeRefSet",[Rules,{outdir,OutDir}]++Options).
+
+
+
+set(_Rules) ->
+
+ ?line {ok,Bytes1} =
+ asn1_wrapper:encode('ChoTypeRefSet','ChoTRset',
+ {choSet,#'ChoSet'{setInt = 88,
+ setOs = "A string"}}),
+ ?line {ok,{choSet,{'ChoSet',88,"A string"}}} =
+ asn1_wrapper:decode('ChoTypeRefSet','ChoTRset',lists:flatten(Bytes1)),
+
+
+ ?line {ok,Bytes2} =
+ asn1_wrapper:encode('ChoTypeRefSet','ChoTRset',
+ {choSetI,#'ChoSet'{setInt = 88,
+ setOs = "A string"}}),
+ ?line {ok,{choSetI,{'ChoSet',88,"A string"}}} =
+ asn1_wrapper:decode('ChoTypeRefSet','ChoTRset',lists:flatten(Bytes2)),
+
+
+ ?line {ok,Bytes3} =
+ asn1_wrapper:encode('ChoTypeRefSet','ChoTRset',
+ {choSetE,#'ChoSet'{setInt = 88,
+ setOs = "A string"}}),
+ ?line {ok,{choSetE,{'ChoSet',88,"A string"}}} =
+ asn1_wrapper:decode('ChoTypeRefSet','ChoTRset',lists:flatten(Bytes3)),
+
+
+ ?line {ok,Bytes4} =
+ asn1_wrapper:encode('ChoTypeRefSet','ChoTRset',
+ {'choSet-I',#'ChoSetImp'{setInt = 88,
+ setOs = "A string"}}),
+ ?line {ok,{'choSet-I',{'ChoSetImp',88,"A string"}}} =
+ asn1_wrapper:decode('ChoTypeRefSet','ChoTRset',lists:flatten(Bytes4)),
+
+
+ ?line {ok,Bytes5} =
+ asn1_wrapper:encode('ChoTypeRefSet','ChoTRset',
+ {'choSetI-I',#'ChoSetImp'{setInt = 88,
+ setOs = "A string"}}),
+ ?line {ok,{'choSetI-I',{'ChoSetImp',88,"A string"}}} =
+ asn1_wrapper:decode('ChoTypeRefSet','ChoTRset',lists:flatten(Bytes5)),
+
+
+ ?line {ok,Bytes6} =
+ asn1_wrapper:encode('ChoTypeRefSet','ChoTRset',
+ {'choSetE-I',#'ChoSetImp'{setInt = 88,
+ setOs = "A string"}}),
+ ?line {ok,{'choSetE-I',{'ChoSetImp',88,"A string"}}} =
+ asn1_wrapper:decode('ChoTypeRefSet','ChoTRset',lists:flatten(Bytes6)),
+
+
+ ?line {ok,Bytes7} =
+ asn1_wrapper:encode('ChoTypeRefSet','ChoTRset',
+ {'choSet-E',#'ChoSetExp'{setInt = 88,
+ setOs = "A string"}}),
+ ?line {ok,{'choSet-E',{'ChoSetExp',88,"A string"}}} =
+ asn1_wrapper:decode('ChoTypeRefSet','ChoTRset',lists:flatten(Bytes7)),
+
+
+ ?line {ok,Bytes8} =
+ asn1_wrapper:encode('ChoTypeRefSet','ChoTRset',
+ {'choSetI-E',#'ChoSetExp'{setInt = 88,
+ setOs = "A string"}}),
+ ?line {ok,{'choSetI-E',{'ChoSetExp',88,"A string"}}} =
+ asn1_wrapper:decode('ChoTypeRefSet','ChoTRset',lists:flatten(Bytes8)),
+
+
+ ?line {ok,Bytes9} =
+ asn1_wrapper:encode('ChoTypeRefSet','ChoTRset',
+ {'choSetE-E',#'ChoSetExp'{setInt = 88,
+ setOs = "A string"}}),
+ ?line {ok,{'choSetE-E',{'ChoSetExp',88,"A string"}}} =
+ asn1_wrapper:decode('ChoTypeRefSet','ChoTRset',lists:flatten(Bytes9)),
+
+
+
+ ok.
diff --git a/lib/asn1/test/testChoiceIndefinite.erl b/lib/asn1/test/testChoiceIndefinite.erl
new file mode 100644
index 0000000000..5eff4ce5d4
--- /dev/null
+++ b/lib/asn1/test/testChoiceIndefinite.erl
@@ -0,0 +1,55 @@
+%%
+%% %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(testChoiceIndefinite).
+
+-export([compile/3]).
+-export([main/1]).
+
+-include("test_server.hrl").
+
+
+compile(Config,Rules,Options) ->
+
+ ?line DataDir = ?config(data_dir,Config),
+ ?line OutDir = ?config(priv_dir,Config),
+ ?line true = code:add_patha(?config(priv_dir,Config)),
+ ?line ok = asn1ct:compile(DataDir ++ "ChoiceIndef",
+ [Rules,{outdir,OutDir}]++Options).
+
+main(per_bin) -> ok;
+main(per) -> ok;
+main(ber_bin_v2) ->
+ main(ber);
+main(ber_bin) ->
+ main(ber);
+main(ber) ->
+ %% Test case related to OTP-4358
+ %% normal encoding
+ B = [48,8,160,3,128,1,11,129,1,12],
+ %% indefinite length encoding
+ Bi = [48,128,160,128,128,1,11,0,0,129,1,12,0,0],
+ %% the value which is encoded
+ V = {'Seq',{ca,11},12},
+ ?line {ok,V} = asn1_wrapper:decode('ChoiceIndef','Seq',B),
+ ?line {ok,V} = asn1_wrapper:decode('ChoiceIndef','Seq',Bi),
+ ok.
+
+
+
diff --git a/lib/asn1/test/testCompactBitString.erl b/lib/asn1/test/testCompactBitString.erl
new file mode 100644
index 0000000000..12aae260ea
--- /dev/null
+++ b/lib/asn1/test/testCompactBitString.erl
@@ -0,0 +1,279 @@
+%%
+%% %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(testCompactBitString).
+
+-export([compile/3]).
+-export([compact_bit_string/1, bit_string_unnamed/1,otp_4869/1,
+ ticket_7734/1]).
+
+-include("test_server.hrl").
+
+
+compile(Config,Rules,Option) ->
+
+ ?line DataDir = ?config(data_dir,Config),
+ ?line OutDir = ?config(priv_dir,Config),
+ ?line true = code:add_patha(?config(priv_dir,Config)),
+ ?line ok = asn1ct:compile(DataDir ++ "PrimStrings",
+ [Rules,{outdir,OutDir}]++Option),
+ case Rules of
+ per_bin ->
+ ?line ok = asn1ct:compile(DataDir ++ "Constraints",
+ [Rules,{outdir,OutDir}]++Option);
+ _ -> ok
+ end.
+
+
+
+compact_bit_string(Rules) ->
+
+ %%==========================================================
+ %% Bs1 ::= BIT STRING
+ %%==========================================================
+
+ ?line {ok,Bytes1} = asn1_wrapper:encode('PrimStrings','Bs1',0),
+ ?line {ok,{0,<<>>}} =
+ asn1_wrapper:decode('PrimStrings','Bs1',lists:flatten(Bytes1)),
+
+ ?line {ok,Bytes2} = asn1_wrapper:encode('PrimStrings','Bs1',4),
+ ?line {ok,{5,<<32>>}} =
+ asn1_wrapper:decode('PrimStrings','Bs1',lists:flatten(Bytes2)),
+
+ ?line {ok,Bytes3} = asn1_wrapper:encode('PrimStrings','Bs1',15),
+ ?line {ok,{4,<<240>>}} =
+ asn1_wrapper:decode('PrimStrings','Bs1',
+ lists:flatten(Bytes3)),
+
+ ?line {ok,Bytes4} = asn1_wrapper:encode('PrimStrings','Bs1',255),
+ ?line {ok,{0,<<255>>}} =
+ asn1_wrapper:decode('PrimStrings','Bs1',lists:flatten(Bytes4)),
+
+ ?line {ok,Bytes5} = asn1_wrapper:encode('PrimStrings','Bs1',256),
+ ?line {ok,{7,<<0,128>>}} =
+ asn1_wrapper:decode('PrimStrings','Bs1',lists:flatten(Bytes5)),
+
+ ?line {ok,Bytes6} = asn1_wrapper:encode('PrimStrings','Bs1',257),
+ ?line {ok,{7,<<128,128>>}} =
+ asn1_wrapper:decode('PrimStrings','Bs1',
+ lists:flatten(Bytes6)),
+
+ ?line {ok,Bytes7} = asn1_wrapper:encode('PrimStrings','Bs1',444),
+ ?line {ok,{7,<<61,128>>}} =
+ asn1_wrapper:decode('PrimStrings','Bs1',
+ lists:flatten(Bytes7)),
+
+ ?line {ok,Bytes8} = asn1_wrapper:encode('PrimStrings','Bs1',
+ 12345678901234567890),
+ ?line {ok,_} = asn1_wrapper:decode('PrimStrings','Bs1',
+ lists:flatten(Bytes8)),
+
+%% Removed due to beam cannot handle this big integers
+%% Bs1_1 = 123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890,
+%% ?line {ok,Bytes9} = asn1_wrapper:encode('PrimStrings','Bs1',Bs1_1),
+%% ?line {ok,_} = asn1_wrapper:decode('PrimStrings','Bs1',lists:flatten(Bytes9)),
+
+%% Bs1_2 = 12345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890,
+%% ?line {ok,Bytes10} = asn1_wrapper:encode('PrimStrings','Bs1',Bs1_2),
+%% ?line {ok,_} = asn1_wrapper:decode('PrimStrings','Bs1',lists:flatten(Bytes10)),
+
+ ?line {ok,Bytes11} = asn1_wrapper:encode('PrimStrings','Bs1',
+ [1,1,1,1,1,1,1,1]),
+ ?line {ok,{0,<<255>>}} = asn1_wrapper:decode('PrimStrings','Bs1',
+ lists:flatten(Bytes11)),
+
+ ?line {ok,Bytes12} = asn1_wrapper:encode('PrimStrings',
+ 'Bs1',
+ [0,1,0,0,1,0]),
+ ?line {ok,{2,<<72>>}} =
+ asn1_wrapper:decode('PrimStrings','Bs1',
+ lists:flatten(Bytes12)),
+
+ ?line {ok,Bytes13} =
+ asn1_wrapper:encode('PrimStrings', 'Bs1',
+ [1,0,0,0,0,0,0,0,0]),
+ ?line {ok,{7,<<128,0>>}} =
+ asn1_wrapper:decode('PrimStrings','Bs1',
+ lists:flatten(Bytes13)),
+
+
+ ?line {ok,Bytes14} =
+ asn1_wrapper:encode('PrimStrings','Bs1',
+ [0,1,0,0,1,0,1,1,1,1,1,0,0,0,1,0,0,1,1]),
+ ?line {ok,{5,<<75,226,96>>}} =
+ asn1_wrapper:decode('PrimStrings','Bs1',lists:flatten(Bytes14)),
+
+
+ ?line case asn1_wrapper:erule(Rules) of
+ ber ->
+ ?line Bytes15 = [35,8,3,2,0,73,3,2,4,32],
+ ?line {ok,{4,<<73,32>>}} =
+ asn1_wrapper:decode('PrimStrings','Bs1',
+ lists:flatten(Bytes15)),
+
+ ?line Bytes16 = [35,9,3,2,0,234,3,3,7,156,0],
+ ?line {ok,{7,<<234,156,0>>}} =
+ asn1_wrapper:decode('PrimStrings','Bs1',
+ lists:flatten(Bytes16)),
+
+ ?line Bytes17 = [35,128,3,2,0,73,3,2,4,32,0,0],
+ ?line {ok,{4,<<73,32>>}} =
+ asn1_wrapper:decode('PrimStrings','Bs1',
+ lists:flatten(Bytes17)),
+
+ ?line Bytes18 = [35,128,3,2,0,234,3,3,7,156,0,0,0],
+ ?line {ok,{7,<<234,156,0>>}} =
+ asn1_wrapper:decode('PrimStrings','Bs1',
+ lists:flatten(Bytes18)),
+ ok;
+
+ per ->
+ ok
+ end,
+
+ %% The following case to test OTP-4200
+ ?line {ok,Bytes19} =
+ asn1_wrapper:encode('PrimStrings','Bs1',{0,<<0,0,1,1>>}),
+ ?line {ok,{0,<<0,0,1,1>>}} =
+ asn1_wrapper:decode('PrimStrings','Bs1',lists:flatten(Bytes19)),
+
+ %%==========================================================
+ %% Bs2 ::= BIT STRING {su(0), mo(1), tu(2), we(3), th(4), fr(5), sa(6) } (SIZE (7))
+ %%==========================================================
+
+ ?line {ok,Bytes21} = asn1_wrapper:encode('PrimStrings','Bs2',[mo,tu,fr]),
+ ?line {ok,[mo,tu,fr]} = asn1_wrapper:decode('PrimStrings','Bs2',lists:flatten(Bytes21)),
+
+ ?line {ok,Bytes22} = asn1_wrapper:encode('PrimStrings','Bs2',[0,1,1,0,0,1,0]),
+ ?line {ok,[mo,tu,fr]} = asn1_wrapper:decode('PrimStrings','Bs2',lists:flatten(Bytes22)),
+
+ % ?line case asn1_wrapper:erule(Rules) of
+% ber ->
+% ?line {ok,[mo,tu,fr,su,mo,th]} =
+% asn1_wrapper:decode('PrimStrings','Bs2',[35,8,3,2,1,100,3,2,2,200]),
+
+% ?line {ok,[mo,tu,fr,su,mo,th]} =
+% asn1_wrapper:decode('PrimStrings','Bs2',[35,128,3,2,1,100,3,2,2,200,0,0]),
+% ok;
+
+% per ->
+% ok
+% end,
+
+
+
+ %%==========================================================
+ %% Bs3 ::= BIT STRING {su(0), mo(1), tu(2), we(3), th(4), fr(5), sa(6) } (SIZE (1..7))
+ %%==========================================================
+
+ ?line {ok,Bytes31} = asn1_wrapper:encode('PrimStrings','Bs3',[mo,tu,fr]),
+ ?line {ok,[mo,tu,fr]} = asn1_wrapper:decode('PrimStrings','Bs3',lists:flatten(Bytes31)),
+
+ ?line {ok,Bytes32} = asn1_wrapper:encode('PrimStrings','Bs3',[0,1,1,0,0,1,0]),
+ ?line {ok,[mo,tu,fr]} = asn1_wrapper:decode('PrimStrings','Bs3',lists:flatten(Bytes32)),
+
+
+
+ %%==========================================================
+ %% BsPri ::= [PRIVATE 61] BIT STRING
+ %%==========================================================
+
+ ?line {ok,Bytes41} = asn1_wrapper:encode('PrimStrings','BsPri',45),
+ ?line {ok,{2,<<180>>}} =
+ asn1_wrapper:decode('PrimStrings','BsPri',lists:flatten(Bytes41)),
+
+ ?line {ok,Bytes42} = asn1_wrapper:encode('PrimStrings','BsPri',211),
+ ?line {ok,{0,<<203>>}} =
+ asn1_wrapper:decode('PrimStrings','BsPri',lists:flatten(Bytes42)),
+
+ ?line case asn1_wrapper:erule(Rules) of
+ ber ->
+ ?line {ok,{5,<<75,226,96>>}} =
+ asn1_wrapper:decode('PrimStrings','BsPri',
+ [223,61,4,5,75,226,96]),
+
+ ?line {ok,{5,<<75,226,96>>}} =
+ asn1_wrapper:decode('PrimStrings','BsPri',
+ [255,61,128,3,4,5,75,226,96,0,0]),
+
+ ?line {ok,{5,<<75,226,96>>}} =
+ asn1_wrapper:decode('PrimStrings','BsPri',
+ [255,61,9,3,2,0,75,3,3,5,226,96]),
+
+ ?line {ok,{5,<<75,226,96>>}} =
+ asn1_wrapper:decode('PrimStrings','BsPri',
+ [255,61,128,3,2,0,75,3,3,5,226,96,0,0]),
+ ok;
+
+ per ->
+ ok
+ end,
+
+
+
+ %%==========================================================
+ %% BsExpPri ::= [PRIVATE 61] EXPLICIT BIT STRING
+ %%==========================================================
+
+ ?line {ok,Bytes51} = asn1_wrapper:encode('PrimStrings','BsExpPri',45),
+ ?line {ok,{2,<<180>>}} =
+ asn1_wrapper:decode('PrimStrings','BsExpPri',lists:flatten(Bytes51)),
+
+ ?line {ok,Bytes52} = asn1_wrapper:encode('PrimStrings','BsExpPri',211),
+ ?line {ok,{0,<<203>>}} =
+ asn1_wrapper:decode('PrimStrings','BsExpPri',lists:flatten(Bytes52)),
+
+ ?line case asn1_wrapper:erule(Rules) of
+ ber ->
+ ?line {ok,{5,<<75,226,96>>}} =
+ asn1_wrapper:decode('PrimStrings','BsExpPri',[255,61,6,3,4,5,75,226,96]),
+ ok;
+
+ per ->
+ ok
+ end,
+
+ ok.
+
+ticket_7734(per_bin) ->
+ ?line BS = {0,list_to_binary(lists:duplicate(128,0))},
+ ?line {ok,BSEnc} = asn1_wrapper:encode('PrimStrings','BS1024',BS),
+ ?line {ok,BS} = asn1_wrapper:decode('PrimStrings','BS1024',BSEnc).
+
+bit_string_unnamed(Rules) ->
+ case asn1_wrapper:erule(Rules) of
+ ber ->
+ ok;
+ per ->
+ ?line {ok,Bytes1} =
+ asn1_wrapper:encode('PrimStrings','TransportLayerAddress',
+ [0,1,1,0]),
+ ?line {ok,{4,<<96>>}} =
+ asn1_wrapper:decode('PrimStrings','TransportLayerAddress',
+ lists:flatten(Bytes1))
+ end.
+
+otp_4869(per_bin) ->
+ ?line Val1={'IP',[0],{0,<<62,235,90,50,0,0,0,0,0,0,0,0,0,0,0,0>>},asn1_NOVALUE},
+ ?line Val2 = {'IP',[0],[0,0,1,1,1,1,1,0,1,1,1,0,1,0,1,1,0,1,0,1,1,0,1,0,0,0,1,1,0,0,1,0] ++ lists:duplicate(128 - 32,0),asn1_NOVALUE},
+
+ ?line {ok,Bytes1} = asn1_wrapper:encode('Constraints','IP',Val1),
+ ?line {ok,Bytes1} = asn1_wrapper:encode('Constraints','IP',Val2);
+otp_4869(_) ->
+ ok.
diff --git a/lib/asn1/test/testConstraints.erl b/lib/asn1/test/testConstraints.erl
new file mode 100644
index 0000000000..f70089fe82
--- /dev/null
+++ b/lib/asn1/test/testConstraints.erl
@@ -0,0 +1,159 @@
+%%
+%% %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(testConstraints).
+
+-export([compile/3]).
+-export([int_constraints/1,refed_NNL_name/1]).
+
+
+-include("test_server.hrl").
+
+
+
+compile(Config,Rules,Options) ->
+
+ ?line DataDir = ?config(data_dir,Config),
+ ?line OutDir = ?config(priv_dir,Config),
+ ?line true = code:add_patha(?config(priv_dir,Config)),
+ ?line ok = asn1ct:compile(DataDir ++ "Constraints",[Rules,{outdir,OutDir}]++Options).
+
+
+
+
+int_constraints(Rules) ->
+
+ %%==========================================================
+ %% SingleValue ::= INTEGER (1)
+ %%==========================================================
+
+ ?line {ok,Bytes1} = asn1_wrapper:encode('Constraints','SingleValue',1),
+ ?line {ok,1} = asn1_wrapper:decode('Constraints','SingleValue',
+ lists:flatten(Bytes1)),
+
+ ?line case asn1_wrapper:erule(Rules) of
+ ber ->
+ ?line {ok,Bytes2} =
+ asn1_wrapper:encode('Constraints','SingleValue',0),
+ ?line {error,{asn1,{integer_range,_,0}}} =
+ asn1_wrapper:decode('Constraints','SingleValue',
+ lists:flatten(Bytes2)),
+ ?line {ok,Bytes3} =
+ asn1_wrapper:encode('Constraints','SingleValue',1000),
+ ?line {error,{asn1,{integer_range,_,1000}}} =
+ asn1_wrapper:decode('Constraints','SingleValue',
+ lists:flatten(Bytes3));
+ per ->
+ ?line {error,_Reason1} =
+ asn1_wrapper:encode('Constraints','SingleValue',0),
+ ?line {error,_Reason2} =
+ asn1_wrapper:encode('Constraints','SingleValue',1000)
+ end,
+
+
+
+ %%==========================================================
+ %% SingleValue2 ::= INTEGER (1..20)
+ %%==========================================================
+
+ ?line {ok,Bytes4} = asn1_wrapper:encode('Constraints','SingleValue2',1),
+ ?line {ok,1} = asn1_wrapper:decode('Constraints','SingleValue2',
+ lists:flatten(Bytes4)),
+
+ ?line {ok,Bytes5} = asn1_wrapper:encode('Constraints','SingleValue2',20),
+ ?line {ok,20} = asn1_wrapper:decode('Constraints','SingleValue2',
+ lists:flatten(Bytes5)),
+
+ ?line case asn1_wrapper:erule(Rules) of
+ ber ->
+ ?line {ok,Bytes6} =
+ asn1_wrapper:encode('Constraints','SingleValue2',0),
+ ?line {error,{asn1,{integer_range,{1,20},0}}} =
+ asn1_wrapper:decode('Constraints','SingleValue2',
+ lists:flatten(Bytes6)),
+ ?line {ok,Bytes7} =
+ asn1_wrapper:encode('Constraints','SingleValue2',21),
+ ?line {error,{asn1,{integer_range,{1,20},21}}} =
+ asn1_wrapper:decode('Constraints','SingleValue2',
+ lists:flatten(Bytes7));
+ per ->
+ ?line {error,_Reason3} =
+ asn1_wrapper:encode('Constraints','SingleValue',0),
+ ?line {error,_Reason4} =
+ asn1_wrapper:encode('Constraints','SingleValue',1000)
+ end,
+
+
+
+ %%==========================================================
+ %% Range2to19 ::= INTEGER (1<..<20)
+ %%==========================================================
+
+ ?line {ok,Bytes8} = asn1_wrapper:encode('Constraints','Range2to19',2),
+ ?line {ok,2} = asn1_wrapper:decode('Constraints','Range2to19',lists:flatten(Bytes8)),
+
+ ?line {ok,Bytes9} = asn1_wrapper:encode('Constraints','Range2to19',19),
+ ?line {ok,19} = asn1_wrapper:decode('Constraints','Range2to19',lists:flatten(Bytes9)),
+
+ ?line case asn1_wrapper:erule(Rules) of
+ ber ->
+ ?line {ok,Bytes10} =
+ asn1_wrapper:encode('Constraints','Range2to19',1),
+ ?line {error,{asn1,{integer_range,{2,19},1}}} =
+ asn1_wrapper:decode('Constraints','Range2to19',
+ lists:flatten(Bytes10)),
+ ?line {ok,Bytes11} =
+ asn1_wrapper:encode('Constraints','Range2to19',20),
+ ?line {error,{asn1,{integer_range,{2,19},20}}} =
+ asn1_wrapper:decode('Constraints','Range2to19',
+ lists:flatten(Bytes11));
+ per ->
+ ?line {error,_Reason5} =
+ asn1_wrapper:encode('Constraints','Range2to19',1),
+ ?line {error,_Reason6} =
+ asn1_wrapper:encode('Constraints','Range2to19',20)
+ end,
+
+
+ %%==========================================================
+ %% Constraint Combinations (Duboisson p. 285)
+ %% I ::= INTEGER (0|15..269)
+ %%==========================================================
+
+ ?line {ok,Bytes12} = asn1_wrapper:encode('Constraints','I',0),
+ ?line {ok,0} = asn1_wrapper:decode('Constraints','I',Bytes12),
+ ?line {ok,Bytes13} = asn1_wrapper:encode('Constraints','I',20),
+ ?line {ok,20} = asn1_wrapper:decode('Constraints','I',Bytes13),
+
+ %%==========================================================
+ %% SIZE Constraint (Duboisson p. 268)
+ %% T ::= IA5String (SIZE (1|2, ..., SIZE (1|2|3)))
+ %% T2 ::= IA5String (SIZE (1|2, ..., 3))
+ %%==========================================================
+
+ ?line {ok,Bytes14} = asn1_wrapper:encode('Constraints','T',"IA"),
+ ?line {ok,"IA"} = asn1_wrapper:decode('Constraints','T',Bytes14),
+ ?line {ok,Bytes15} = asn1_wrapper:encode('Constraints','T2',"IA"),
+ ?line {ok,"IA"} = asn1_wrapper:decode('Constraints','T2',Bytes15).
+
+
+refed_NNL_name(_Erule) ->
+ ?line {ok,_} = asn1_wrapper:encode('Constraints','AnotherThing',fred),
+ ?line {error,_Reason} =
+ asn1_wrapper:encode('Constraints','AnotherThing',fred3).
diff --git a/lib/asn1/test/testContextSwitchingTypes.erl b/lib/asn1/test/testContextSwitchingTypes.erl
new file mode 100644
index 0000000000..399c9ecaf7
--- /dev/null
+++ b/lib/asn1/test/testContextSwitchingTypes.erl
@@ -0,0 +1,83 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 2001-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(testContextSwitchingTypes).
+
+-export([compile/3]).
+-export([test/0]).
+
+-include("test_server.hrl").
+
+
+compile(Config,Rules,Options) ->
+
+ ?line DataDir = ?config(data_dir,Config),
+ ?line OutDir = ?config(priv_dir,Config),
+ ?line true = code:add_patha(?config(priv_dir,Config)),
+ ?line ok = asn1ct:compile(DataDir ++ "ContextSwitchingTypes",
+ [Rules,{outdir,OutDir}]++Options).
+
+
+test() ->
+ ?line ValT = 'ContextSwitchingTypes':'val1-T'(),
+ ?line {ok,Bytes1} =
+ asn1_wrapper:encode('ContextSwitchingTypes','T',ValT),
+ ?line {ok,Result1} =
+ asn1_wrapper:decode('ContextSwitchingTypes','T',Bytes1),
+ ?line ok = check_EXTERNAL(Result1),
+ ?line {ok,ValT2} = asn1ct:value('ContextSwitchingTypes','T'),
+ ?line {ok,Bytes1_2} =
+ asn1_wrapper:encode('ContextSwitchingTypes','T',ValT2),
+ ?line {ok,Result1_2} =
+ asn1_wrapper:decode('ContextSwitchingTypes','T',Bytes1_2),
+ ?line ok = check_EXTERNAL(Result1_2),
+
+ ?line ValEP = 'ContextSwitchingTypes':'val1-EP'(),
+ ?line {ok,Bytes2} =
+ asn1_wrapper:encode('ContextSwitchingTypes','EP',ValEP),
+ ?line {ok,_Result2} =
+ asn1_wrapper:decode('ContextSwitchingTypes','EP',Bytes2),
+
+ ?line ValCS = 'ContextSwitchingTypes':'val1-CS'(),
+ ?line {ok,Bytes3} =
+ asn1_wrapper:encode('ContextSwitchingTypes','CS',ValCS),
+ ?line {ok,_Result3} =
+ asn1_wrapper:decode('ContextSwitchingTypes','CS',Bytes3).
+
+
+check_EXTERNAL({'EXTERNAL',Identif,DVD,DV})->
+ ?line ok=check_EXTERNAL_Idef(Identif),
+ ?line ok = check_EXTERNAL_DVD(DVD),
+ ?line ok = check_EXTERNAL_DV(DV).
+check_EXTERNAL_Idef({Alt,_}) when Alt=='context-negotiation';
+ Alt=='presentation-context-id';
+ Alt==syntax ->
+ ok;
+check_EXTERNAL_Idef(I) ->
+ {error,"failed on identification alternative",I}.
+check_EXTERNAL_DVD(DVD) when is_list(DVD) ->
+ ok;
+check_EXTERNAL_DVD(asn1_NOVALUE) ->
+ ok;
+check_EXTERNAL_DVD(DVD) ->
+ {error,"failed on data-value-descriptor alternative",DVD}.
+check_EXTERNAL_DV(DV) when is_list(DV) ->
+ ok;
+check_EXTERNAL_DV(DV) ->
+ {error,"failed on data-value alternative",DV}.
diff --git a/lib/asn1/test/testDER.erl b/lib/asn1/test/testDER.erl
new file mode 100644
index 0000000000..970e8dadd4
--- /dev/null
+++ b/lib/asn1/test/testDER.erl
@@ -0,0 +1,59 @@
+%%
+%% %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(testDER).
+
+-export([compile/3]).
+-export([test/0]).
+
+-include("test_server.hrl").
+
+
+compile(Config,Rule,Options) ->
+ ?line DataDir = ?config(data_dir,Config),
+ ?line OutDir = ?config(priv_dir,Config),
+ ?line true = code:add_patha(?config(priv_dir,Config)),
+ ?line ok = asn1ct:compile(DataDir ++ "DERSpec",
+ [Rule,der,{outdir,OutDir}]++Options).
+
+test() ->
+ Val = {'Set',12,{version,214},true},
+ ?line {ok,Bin}=asn1_wrapper:encode('DERSpec','Set',Val),
+ ?line ok = match_value('Set',Bin),
+ ?line {ok,{'Set',12,{version,214},true}} =
+ asn1_wrapper:decode('DERSpec','Set',Bin),
+
+ ValSof = [{version,12},{message,"PrintableString"},{message,"Print"},{version,11}],
+ ?line {ok,BSof} = asn1_wrapper:encode('DERSpec','SetOf',ValSof),
+ ?line ok = match_value('SetOf',BSof),
+ ?line {ok,[{version,11},{version,12},{message,"Print"},{message,"PrintableString"}]} = asn1_wrapper:decode('DERSpec','SetOf',BSof),
+
+ ValSO = [{'Seq2',1,true},{'Seq2',120000,false},{'Seq2',3,true}],
+ ?line {ok,SOB} = asn1_wrapper:encode('DERSpec','SO',ValSO),
+ ?line {ok,ValSO} = asn1_wrapper:decode('DERSpec','SO',SOB).
+
+
+match_value('Set',<<49,12,1,1,255,2,2,0,214,161,3,2,1,12>>) ->
+ ok;
+match_value('Set',[49,12,1,1,255,2,2,0,214,161,3,2,1,12]) ->
+ ok;
+match_value('SetOf',<<49,30,2,1,11,2,1,12,19,5,80,114,105,110,116,19,15,80,114,105,110,116,97,98,108,101,83,116,114,105,110,103>>) -> ok;
+match_value('SetOf',[49,30,2,1,11,2,1,12,19,5,80,114,105,110,116,19,15,80,114,105,110,116,97,98,108,101,83,116,114,105,110,103]) -> ok;
+match_value(_,B) ->
+ {error,B}.
diff --git a/lib/asn1/test/testDeepTConstr.erl b/lib/asn1/test/testDeepTConstr.erl
new file mode 100644
index 0000000000..a185a127e5
--- /dev/null
+++ b/lib/asn1/test/testDeepTConstr.erl
@@ -0,0 +1,107 @@
+%%
+%% %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(testDeepTConstr).
+
+-export([compile/3,main/1]).
+
+-include("test_server.hrl").
+
+compile(Config,Rules,Options) ->
+
+ ?line DataDir = ?config(data_dir,Config),
+ ?line OutDir = ?config(priv_dir,Config),
+ ?line true = code:add_patha(?config(priv_dir,Config)),
+
+ ?line ok = asn1ct:compile(DataDir ++
+ "TConstrChoice",[Rules,{outdir,OutDir}]++Options),
+ ?line ok = asn1ct:compile(DataDir ++
+ "TConstr",[Rules,{outdir,OutDir}]++Options).
+
+
+
+main(_Erule) ->
+ Val1 = {'FilterItem',
+ {substrings,
+ {'FilterItem_substrings',
+ {2,6},
+ [{initial,"SE"},
+ {any,"DK"},
+ {final,"N"}]}}},
+
+ Val2 = {'FilterItem',
+ {substrings,
+ {'FilterItem_substrings',
+ {2,6},
+ [{initial,"SE"},
+ {any,"DK"},
+ {final,"NO"}]}}},
+
+ ?line {ok,Bytes1} =
+ asn1_wrapper:encode('TConstrChoice','FilterItem',Val1),
+
+ ?line {error,Reason} = asn1_wrapper:decode('TConstrChoice','FilterItem',Bytes1),
+
+ io:format("Reason: ~p~n~n",[Reason]),
+
+ ?line {ok,Bytes2} =
+ asn1_wrapper:encode('TConstrChoice','FilterItem',Val2),
+
+ ?line {ok,Res} = asn1_wrapper:decode('TConstrChoice','FilterItem',Bytes2),
+
+
+
+ %% test of OTP-4248.
+ ?line {ok,Bytes3} =
+ asn1_wrapper:encode('TConstrChoice','Seq',{'Seq',3,Bytes2}),
+
+ ?line {ok,{'Seq',3,Bytes4}} =
+ asn1_wrapper:decode('TConstrChoice','Seq',Bytes3),
+
+ ?line {ok,Res} = asn1_wrapper:decode('TConstrChoice','FilterItem',Bytes4),
+
+ %% test of TConstr
+
+ Seq1Val = {'Seq1',{'Seq1_a',12,{2,4}},{'Seq1_b',13,{'Type-object1',14,true}}},
+ ?line {ok,Bytes5} =
+ asn1_wrapper:encode('TConstr','Seq1',Seq1Val),
+
+ ?line {ok,Seq1Val} =
+ asn1_wrapper:decode('TConstr','Seq1',Bytes5),
+
+
+ Seq2Val = {'Seq2',123,{'Seq2_content',{2,6,7},
+ {first,{'Type-object3_first',false,47}},
+ false}},
+
+ ?line {ok,Bytes6} =
+ asn1_wrapper:encode('TConstr','Seq2',Seq2Val),
+
+ ?line {ok,Seq2Val} =
+ asn1_wrapper:decode('TConstr','Seq2',Bytes6),
+
+ InfoVal = {'Info',{'Info_xyz',{1,2}},1234},
+
+ ?line {ok,Bytes7} =
+ asn1_wrapper:encode('TConstr','Info',InfoVal),
+
+ ?line {ok,InfoVal} =
+ asn1_wrapper:decode('TConstr','Info',Bytes7).
diff --git a/lib/asn1/test/testDef.erl b/lib/asn1/test/testDef.erl
new file mode 100644
index 0000000000..aa41f7b678
--- /dev/null
+++ b/lib/asn1/test/testDef.erl
@@ -0,0 +1,128 @@
+%%
+%% %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(testDef).
+
+-export([compile/3]).
+-export([main/1]).
+
+-include("test_server.hrl").
+
+-record('Def1',{bool0,
+ bool1 = asn1_DEFAULT,
+ bool2 = asn1_DEFAULT,
+ bool3 = asn1_DEFAULT}).
+-record('Def2',{bool10,
+ bool11 = asn1_DEFAULT,
+ bool12 = asn1_DEFAULT,
+ bool13}).
+-record('Def3',{bool30 = asn1_DEFAULT,
+ bool31 = asn1_DEFAULT,
+ bool32 = asn1_DEFAULT,
+ bool33 = asn1_DEFAULT}).
+
+
+compile(Config,Rules,Options) ->
+
+ ?line DataDir = ?config(data_dir,Config),
+ ?line OutDir = ?config(priv_dir,Config),
+ ?line true = code:add_patha(?config(priv_dir,Config)),
+ ?line ok = asn1ct:compile(DataDir ++ "Def",[Rules,{outdir,OutDir}]++Options).
+
+
+
+main(_Rules) ->
+
+ ?line {ok,Bytes11} = asn1_wrapper:encode('Def','Def1',#'Def1'{bool0 = true,
+ bool1 = true,
+ bool2 = true,
+ bool3 = true}),
+ ?line {ok,{'Def1',true,true,true,true}} =
+ asn1_wrapper:decode('Def','Def1',lists:flatten(Bytes11)),
+
+ ?line {ok,Bytes12} = asn1_wrapper:encode('Def','Def1',#'Def1'{bool0 = true}),
+ ?line {ok,{'Def1',true,false,false,false}} =
+ asn1_wrapper:decode('Def','Def1',lists:flatten(Bytes12)),
+
+ ?line {ok,Bytes13} = asn1_wrapper:encode('Def','Def1',#'Def1'{bool0 = true,
+ bool2 = false}),
+ ?line {ok,{'Def1',true,false,false,false}} =
+ asn1_wrapper:decode('Def','Def1',lists:flatten(Bytes13)),
+
+ ?line {ok,Bytes14} = asn1_wrapper:encode('Def','Def1',#'Def1'{bool0 = false,
+ bool3 = false}),
+ ?line {ok,{'Def1',false,false,false,false}} =
+ asn1_wrapper:decode('Def','Def1',lists:flatten(Bytes14)),
+
+
+
+
+ ?line {ok,Bytes21} = asn1_wrapper:encode('Def','Def2',#'Def2'{bool10 = false,
+ bool11 = false,
+ bool12 = false,
+ bool13 = false}),
+ ?line {ok,{'Def2',false,false,false,false}} =
+ asn1_wrapper:decode('Def','Def2',lists:flatten(Bytes21)),
+
+ ?line {ok,Bytes22} = asn1_wrapper:encode('Def','Def2',#'Def2'{bool10 = true,
+ bool13 = false}),
+ ?line {ok,{'Def2',true,false,false,false}} =
+ asn1_wrapper:decode('Def','Def2',lists:flatten(Bytes22)),
+
+ ?line {ok,Bytes23} = asn1_wrapper:encode('Def','Def2',#'Def2'{bool10 = true,
+ bool11 = false,
+ bool13 = false}),
+ ?line {ok,{'Def2',true,false,false,false}} =
+ asn1_wrapper:decode('Def','Def2',lists:flatten(Bytes23)),
+
+ ?line {ok,Bytes24} = asn1_wrapper:encode('Def','Def2',#'Def2'{bool10 = false,
+ bool12 = false,
+ bool13 = false}),
+ ?line {ok,{'Def2',false,false,false,false}} =
+ asn1_wrapper:decode('Def','Def2',lists:flatten(Bytes24)),
+
+
+
+
+ ?line {ok,Bytes31} = asn1_wrapper:encode('Def','Def3',#'Def3'{bool30 = false,
+ bool31 = false,
+ bool32 = false,
+ bool33 = false}),
+ ?line {ok,{'Def3',false,false,false,false}} =
+ asn1_wrapper:decode('Def','Def3',lists:flatten(Bytes31)),
+
+ ?line {ok,Bytes32} = asn1_wrapper:encode('Def','Def3',#'Def3'{}),
+ ?line {ok,{'Def3',false,false,false,false}} =
+ asn1_wrapper:decode('Def','Def3',lists:flatten(Bytes32)),
+
+ ?line {ok,Bytes33} = asn1_wrapper:encode('Def','Def3',#'Def3'{bool30 = true}),
+ ?line {ok,{'Def3',true,false,false,false}} =
+ asn1_wrapper:decode('Def','Def3',lists:flatten(Bytes33)),
+
+ ?line {ok,Bytes34} = asn1_wrapper:encode('Def','Def3',#'Def3'{bool32 = false}),
+ ?line {ok,{'Def3',false,false,false,false}} =
+ asn1_wrapper:decode('Def','Def3',lists:flatten(Bytes34)),
+
+ ?line {ok,Bytes35} = asn1_wrapper:encode('Def','Def3',#'Def3'{bool33 = false}),
+ ?line {ok,{'Def3',false,false,false,false}} =
+ asn1_wrapper:decode('Def','Def3',lists:flatten(Bytes35)),
+
+
+
+ ok.
diff --git a/lib/asn1/test/testDoubleEllipses.erl b/lib/asn1/test/testDoubleEllipses.erl
new file mode 100644
index 0000000000..444b06995f
--- /dev/null
+++ b/lib/asn1/test/testDoubleEllipses.erl
@@ -0,0 +1,112 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 2007-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(testDoubleEllipses).
+
+-export([compile/3]).
+-export([main/1]).
+
+-include("test_server.hrl").
+
+-record('Seq',{a, c}).
+-record('SeqV2',{a, b ,c}).
+-record('SeqAlt',{a,d,b,e,c,f,g}).
+-record('SeqAltV2',{a,d,b,e,h,i,c,f,g}).
+
+-record('Set',{a, c}).
+-record('SetV2',{a, b ,c}).
+-record('SetAlt',{a,d,b,e,c,f,g}).
+-record('SetAltV2',{a,d,b,e,h,i,c,f,g}).
+
+
+
+
+compile(Config,Rules,Options) ->
+
+ ?line DataDir = ?config(data_dir,Config),
+ ?line OutDir = ?config(priv_dir,Config),
+ ?line true = code:add_patha(?config(priv_dir,Config)),
+ ?line ok = asn1ct:compile(DataDir ++ "DoubleEllipses",[Rules,{outdir,OutDir}]++Options).
+
+
+main(_Rules) ->
+ %% SEQUENCE
+ ?line {ok,Bytes} =
+ asn1_wrapper:encode('DoubleEllipses','Seq',#'Seq'{a = 10,c = true}),
+ ?line {ok,#'SeqV2'{a=10,b = asn1_NOVALUE, c = true}} =
+ asn1_wrapper:decode('DoubleEllipses','SeqV2',Bytes),
+ ?line {ok,Bytes2} =
+ asn1_wrapper:encode('DoubleEllipses','SeqV2',
+ #'SeqV2'{a=10,b = false, c = true}),
+ ?line {ok,#'Seq'{a = 10, c = true}} =
+ asn1_wrapper:decode('DoubleEllipses','Seq',Bytes2),
+
+ ?line {ok,Bytes3} =
+ asn1_wrapper:encode('DoubleEllipses','SeqAlt',
+ #'SeqAlt'{a = 10, d = 12,
+ b = [1,0,1,0], e = true,
+ c = false, f = 14, g = 16}),
+ ?line {ok,#'SeqAltV2'{a = 10, d = 12,
+ b = [1,0,1,0], e = true,
+ h = asn1_NOVALUE, i = asn1_NOVALUE,
+ c = false, f = 14, g = 16}} =
+ asn1_wrapper:decode('DoubleEllipses','SeqAltV2',Bytes3),
+ ?line {ok,Bytes4} =
+ asn1_wrapper:encode('DoubleEllipses','SeqAltV2',
+ #'SeqAltV2'{a = 10, d = 12,
+ b = [1,0,1,0], e = true,
+ h = "PS", i = 13,
+ c = false, f = 14, g = 16}),
+ ?line {ok,#'SeqAlt'{a = 10, d = 12,
+ b = [1,0,1,0], e = true,
+ c = false, f = 14, g = 16}} =
+ asn1_wrapper:decode('DoubleEllipses','SeqAlt',Bytes4),
+
+ %% SET
+ ?line {ok,Bytes5} =
+ asn1_wrapper:encode('DoubleEllipses','Set',#'Set'{a = 10,c = true}),
+ ?line {ok,#'SetV2'{a=10,b = asn1_NOVALUE, c = true}} =
+ asn1_wrapper:decode('DoubleEllipses','SetV2',Bytes5),
+ ?line {ok,Bytes6} =
+ asn1_wrapper:encode('DoubleEllipses','SetV2',
+ #'SetV2'{a=10,b = false, c = true}),
+ ?line {ok,#'Set'{a = 10, c = true}} =
+ asn1_wrapper:decode('DoubleEllipses','Set',Bytes6),
+
+ ?line {ok,Bytes7} =
+ asn1_wrapper:encode('DoubleEllipses','SetAlt',
+ #'SetAlt'{a = 10, d = 12,
+ b = [1,0,1,0], e = true,
+ c = false, f = 14, g = 16}),
+ ?line {ok,#'SetAltV2'{a = 10, d = 12,
+ b = [1,0,1,0], e = true,
+ h = asn1_NOVALUE, i = asn1_NOVALUE,
+ c = false, f = 14, g = 16}} =
+ asn1_wrapper:decode('DoubleEllipses','SetAltV2',Bytes7),
+ ?line {ok,Bytes8} =
+ asn1_wrapper:encode('DoubleEllipses','SetAltV2',
+ #'SetAltV2'{a = 10, d = 12,
+ b = [1,0,1,0], e = true,
+ h = "PS", i = 13,
+ c = false, f = 14, g = 16}),
+ ?line {ok,#'SetAlt'{a = 10, d = 12,
+ b = [1,0,1,0], e = true,
+ c = false, f = 14, g = 16}} =
+ asn1_wrapper:decode('DoubleEllipses','SetAlt',Bytes8),
+ ok.
diff --git a/lib/asn1/test/testEnumExt.erl b/lib/asn1/test/testEnumExt.erl
new file mode 100644
index 0000000000..7e25aa9b4e
--- /dev/null
+++ b/lib/asn1/test/testEnumExt.erl
@@ -0,0 +1,95 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 1998-2009. All Rights Reserved.
+%%
+%% The contents of this file are subject to the Erlang Public License,
+%% Version 1.1, (the "License"); you may not use this file except in
+%% compliance with the License. You should have received a copy of the
+%% Erlang Public License along with this software. If not, it can be
+%% retrieved online at http://www.erlang.org/.
+%%
+%% Software distributed under the License is distributed on an "AS IS"
+%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+%% the License for the specific language governing rights and limitations
+%% under the License.
+%%
+%% %CopyrightEnd%
+%%
+%%
+-module(testEnumExt).
+
+-export([compile/3]).
+-export([main/1]).
+
+-include("test_server.hrl").
+
+compile(Config,Rules,Options) ->
+
+ ?line DataDir = ?config(data_dir,Config),
+ ?line OutDir = ?config(priv_dir,Config),
+ ?line true = code:add_patha(?config(priv_dir,Config)),
+ ?line ok = asn1ct:compile(DataDir ++ "EnumExt",[Rules,{outdir,OutDir}]++Options).
+
+
+main(Rules) when Rules == per; Rules == per_bin; Rules == uper_bin ->
+ io:format("main(~p)~n",[Rules]),
+ B32=[32],B64=[64],
+ %% ENUMERATED with extensionmark (value is in root set)
+ ?line {ok,B32} = asn1_wrapper:encode('EnumExt','Ext',red),
+ ?line {ok,red} = asn1_wrapper:decode('EnumExt','Ext',B32),
+
+ %% ENUMERATED with extensionmark (value is an extensionvalue)
+ ?line {ok,Or} = asn1_wrapper:encode('EnumExt','Ext1',orange),
+ ?line {ok,orange} = asn1_wrapper:decode('EnumExt','Ext1',Or),
+ %% unknown extensionvalue
+ ?line {ok,{asn1_enum,0}} = asn1_wrapper:decode('EnumExt','Ext',Or),
+
+
+ %% ENUMERATED no extensionmark
+ ?line {ok,B64} = asn1_wrapper:encode('EnumExt','Noext',red),
+ ?line {ok,red} = asn1_wrapper:decode('EnumExt','Noext',B64),
+ ok;
+
+main(ber_bin_v2) ->
+ main(ber);
+main(ber_bin) ->
+ main(ber);
+main(ber) ->
+ io:format("main(ber)~n",[]),
+ %% ENUMERATED with extensionmark (value is in root set)
+ ?line {ok,Bytes1} = asn1_wrapper:encode('EnumExt','Ext',red),
+ ?line {ok,red} = asn1_wrapper:decode('EnumExt','Ext',lists:flatten(Bytes1)),
+
+ %% value is an extensionvalue
+ ?line {ok,Bytes1_1} = asn1_wrapper:encode('EnumExt','Ext1',orange),
+ ?line {ok,{asn1_enum,7}} = asn1_wrapper:decode('EnumExt','Ext',lists:flatten(Bytes1_1)),
+%% ?line {ok,Bytes1_1} = asn1_wrapper:encode('EnumExt','Ext',{asn1_enum,7}),
+
+ %% ENUMERATED no extensionmark
+ ?line {ok,Bytes2} = asn1_wrapper:encode('EnumExt','Noext',red),
+ ?line {ok,red} = asn1_wrapper:decode('EnumExt','Noext',lists:flatten(Bytes2)),
+ ?line {error,{asn1,_}} = (catch asn1_wrapper:encode('EnumExt','Noext',orange)),
+%% ?line {error,{asn1,_}} = (catch asn1_wrapper:encode('EnumExt','Noext',{asn1_enum,7})),
+ ok,
+
+ %% ENUMERATED with atom 'com'
+ ?line {ok,Bytes3} = asn1_wrapper:encode('EnumExt','Globalstate',{'Globalstate',preop}),
+ ?line {ok,preop} = asn1_wrapper:decode('EnumExt','Globalstate',
+ lists:flatten(Bytes3)),
+ ?line {ok,Bytes4} = asn1_wrapper:encode('EnumExt','Globalstate',{'Globalstate',com}),
+ ?line {ok,com} = asn1_wrapper:decode('EnumExt','Globalstate',
+ lists:flatten(Bytes4)).
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/lib/asn1/test/testExternal.erl b/lib/asn1/test/testExternal.erl
new file mode 100644
index 0000000000..3c3dc2ea29
--- /dev/null
+++ b/lib/asn1/test/testExternal.erl
@@ -0,0 +1,35 @@
+%%
+%% %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(testExternal).
+
+-export([compile/3]).
+
+-include("test_server.hrl").
+
+
+compile(Config,Rules,Options) ->
+
+ ?line DataDir = ?config(data_dir,Config),
+ ?line OutDir = ?config(priv_dir,Config),
+ ?line true = code:add_patha(?config(priv_dir,Config)),
+ ?line test_server:format("Rules ~p~n",[Rules]),
+ ?line ok = asn1ct:compile(DataDir ++ "External",[Rules,{outdir,OutDir}]++Options).
+
+
diff --git a/lib/asn1/test/testINSTANCE_OF.erl b/lib/asn1/test/testINSTANCE_OF.erl
new file mode 100644
index 0000000000..7f5b634e06
--- /dev/null
+++ b/lib/asn1/test/testINSTANCE_OF.erl
@@ -0,0 +1,89 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 2003-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(testINSTANCE_OF).
+
+-export([compile/3,main/1]).
+
+-include("test_server.hrl").
+
+
+compile(Config,Rules,Opt) ->
+
+ ?line DataDir = ?config(data_dir,Config),
+ ?line OutDir = ?config(priv_dir,Config),
+ ?line true = code:add_patha(?config(priv_dir,Config)),
+
+ ?line ok = asn1ct:compile(DataDir ++ "INSTANCEOF.asn1",
+ [Rules,{outdir,OutDir}]++Opt).
+
+
+main(Erule) ->
+
+ ?line {ok,Integer} = asn1_wrapper:encode('INSTANCEOF','Int',3),
+ Int = wrap(Erule,Integer),
+ ValotherName = {otherName,{'INSTANCE OF',{2,4},Int}},
+ VallastName1 = {lastName,{'GeneralName_lastName',{2,4},12}},
+ VallastName2 = {lastName,{'GeneralName_lastName',{2,3,4},
+ {'Seq',12,true}}},
+ ?line {ok,BytesoN}=
+ asn1_wrapper:encode('INSTANCEOF','GeneralName',ValotherName),
+ ?line {ok,Res1={otherName,_}} =
+ asn1_wrapper:decode('INSTANCEOF','GeneralName',BytesoN),
+ ?line ok = test_encdec(Erule,Int,Res1),
+
+ ?line {ok,ByteslN1}=
+ asn1_wrapper:encode('INSTANCEOF','GeneralName',VallastName1),
+ ?line {ok,Res2={lastName,_}} =
+ asn1_wrapper:decode('INSTANCEOF','GeneralName',ByteslN1),
+ ?line test_encdec(Erule,Res2),
+
+ ?line {ok,ByteslN2}=
+ asn1_wrapper:encode('INSTANCEOF','GeneralName',VallastName2),
+ ?line {ok,Res3={lastName,_}} =
+ asn1_wrapper:decode('INSTANCEOF','GeneralName',ByteslN2),
+ ?line test_encdec(Erule,Res3).
+
+test_encdec(_Erule,Int,{otherName,{'INSTANCE OF',{2,4},Int}}) ->
+ ok;
+test_encdec(Erule,Int,R={otherName,{'INSTANCE OF',{2,4},_Int2}}) ->
+ {error,{Erule,Int,R}}.
+
+test_encdec(_Erule,{lastName,{'GeneralName_lastName',{2,4},12}}) ->
+ ok;
+test_encdec(_Erule,{lastName,{'GeneralName_lastName',{2,3,4},
+ {'Seq',12,true}}}) ->
+ ok;
+test_encdec(Erule,Res) ->
+ {error,{Erule,Res}}.
+
+wrap(ber,Int) when is_list(Int) ->
+ binary_to_list(list_to_binary(Int));
+wrap(per,Int) when is_list(Int) ->
+ binary_to_list(list_to_binary(Int));
+wrap(ber_bin,Int) when is_list(Int) ->
+ list_to_binary(Int);
+wrap(ber_bin_v2,Int) when is_list(Int) ->
+ list_to_binary(Int);
+wrap(per_bin,Int) when is_list(Int) ->
+ list_to_binary(Int);
+wrap(uper_bin,Int) when is_list(Int) ->
+ list_to_binary(Int);
+wrap(_,Int) ->
+ Int.
diff --git a/lib/asn1/test/testInfObj.erl b/lib/asn1/test/testInfObj.erl
new file mode 100644
index 0000000000..317cd75e4b
--- /dev/null
+++ b/lib/asn1/test/testInfObj.erl
@@ -0,0 +1,104 @@
+%%
+%% %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(testInfObj).
+
+-export([compile/3,main/1,compile_RANAPfiles/3]).
+
+-include("test_server.hrl").
+
+-record('InitiatingMessage',{procedureCode,criticality,value}).
+-record('InitiatingMessage2',{procedureCode,criticality,value}).
+-record('Iu-ReleaseCommand',{first,second}).
+
+compile(Config,Rules,Options) ->
+
+ ?line DataDir = ?config(data_dir,Config),
+ ?line OutDir = ?config(priv_dir,Config),
+ ?line true = code:add_patha(?config(priv_dir,Config)),
+
+ ?line ok = asn1ct:compile(DataDir ++
+ "RANAPextract1",[Rules,{outdir,OutDir}]++Options),
+ ?line ok = asn1ct:compile(DataDir ++ "InfObj",[Rules,{outdir,OutDir}]++Options),
+ %% test case for OTP-4792 optional open type
+ ?line ok = asn1ct:compile(DataDir ++ "MAP-ExtensionDataTypes",[Rules,{outdir,OutDir}]++Options),
+ %% OTP-6707
+ ?line ok = asn1ct:compile(DataDir ++ "Objects",[Rules,{outdir,OutDir}]++Options),
+ %% OTP-6717
+ ?line ok = asn1ct:compile(DataDir ++ "INAPv2extract",[Rules,{outdir,OutDir}]++Options).
+
+
+compile_RANAPfiles(Config,Rules,Options) ->
+ ?line DataDir = ?config(data_dir,Config),
+ ?line OutDir = ?config(priv_dir,Config),
+ ?line true = code:add_patha(?config(priv_dir,Config)),
+
+ ?line ok = asn1ct:compile(DataDir ++ "RANAP-CommonDataTypes",
+ [Rules,{outdir,OutDir}]++Options),
+ ?line ok = asn1ct:compile(DataDir ++ "RANAP-Constants",
+ [Rules,{outdir,OutDir}]++Options),
+ ?line ok = asn1ct:compile(DataDir ++ "RANAP-Containers",
+ [Rules,{outdir,OutDir}]++Options),
+ ?line ok = asn1ct:compile(DataDir ++ "RANAP-IEs",
+ [Rules,{outdir,OutDir}]++Options),
+ ?line ok = asn1ct:compile(DataDir ++ "RANAP-PDU-Contents",
+ [Rules,{outdir,OutDir}]++Options),
+ ?line ok = asn1ct:compile(DataDir ++ "RANAP-PDU-Descriptions",
+ [Rules,{outdir,OutDir}]++Options).
+
+
+main(_Erule) ->
+ Val1 = #'InitiatingMessage'{procedureCode=1,
+ criticality=ignore,
+ value=#'Iu-ReleaseCommand'{
+ first=13,
+ second=true}},
+ ?line {ok,Bytes1} =
+ asn1_wrapper:encode('RANAPextract1','InitiatingMessage',Val1),
+
+ ?line {ok,{'InitiatingMessage',1,ignore,{'Iu-ReleaseCommand',13,true}}}=
+ asn1_wrapper:decode('RANAPextract1','InitiatingMessage',Bytes1),
+
+ ?line {ok,Bytes2} =
+ asn1_wrapper:encode('InfObj','InitiatingMessage',Val1),
+
+ ?line {ok,Val1} =
+ asn1_wrapper:decode('InfObj','InitiatingMessage',Bytes2),
+
+ Val2 = Val1#'InitiatingMessage'{procedureCode=2},
+
+ ?line {error,_R1} =
+ asn1_wrapper:encode('InfObj','InitiatingMessage',Val2),
+
+
+ %% Test case for OTP-4275
+ Val3 = #'InitiatingMessage2'{procedureCode=3,
+ criticality=reject,
+ value=#'Iu-ReleaseCommand'{
+ first=13,
+ second=true}},
+
+ ?line {ok,Bytes3} =
+ asn1_wrapper:encode('RANAPextract1','InitiatingMessage2',Val3),
+
+
+ ?line {ok,{'InitiatingMessage2',3,reject,{'Iu-ReleaseCommand',13,true}}}=
+ asn1_wrapper:decode('RANAPextract1','InitiatingMessage2',Bytes3).
+
diff --git a/lib/asn1/test/testInfObjectClass.erl b/lib/asn1/test/testInfObjectClass.erl
new file mode 100644
index 0000000000..63b332ad0a
--- /dev/null
+++ b/lib/asn1/test/testInfObjectClass.erl
@@ -0,0 +1,67 @@
+%%
+%% %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(testInfObjectClass).
+
+
+-export([compile/3,main/1]).
+
+-include("test_server.hrl").
+
+
+
+
+compile(Config,Rules,Options) ->
+
+ ?line DataDir = ?config(data_dir,Config),
+ ?line OutDir = ?config(priv_dir,Config),
+ ?line true = code:add_patha(?config(priv_dir,Config)),
+ ?line ok = asn1ct:compile(DataDir ++ "ErrorClass",[Rules,{outdir,OutDir}]++Options),
+ ?line ok = asn1ct:compile(DataDir ++ "InfClass",[Rules,{outdir,OutDir}]++Options).
+
+
+main(Rule) ->
+ %% this test is added for OTP-4591, to test that elements in decoded
+ %% value has terms in right order.
+ Val = {'Seq',12,13,2},
+ ?line {ok,Bytes}= asn1_wrapper:encode('InfClass','Seq',Val),
+ ?line {ok,Val} = asn1_wrapper:decode('InfClass','Seq',Bytes),
+
+ %% OTP-5783
+ ?line {error,{asn1,{'Type not compatible with table constraint',
+ {component,'ArgumentType'},
+ {value,_},_}}} = asn1_wrapper:encode('InfClass','Seq',
+ {'Seq',12,13,1}),
+ Bytes2 =
+ if
+ Rule==per;Rule==per_bin ->
+ [1,12,1,11,1,1];
+ Rule == uper_bin ->
+ <<1,12,1,11,1,1>>;
+ true ->
+ [48,9,2,1,12,2,1,11,2,1,1]
+ end,
+ ?line {error,{asn1,{'Type not compatible with table constraint',
+ {{component,_},
+ {value,_B},_}}}} =
+ asn1_wrapper:decode('InfClass','Seq',Bytes2).
+
+
+
diff --git a/lib/asn1/test/testMegaco.erl b/lib/asn1/test/testMegaco.erl
new file mode 100644
index 0000000000..50bc6e7dee
--- /dev/null
+++ b/lib/asn1/test/testMegaco.erl
@@ -0,0 +1,191 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 2001-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(testMegaco).
+
+-export([compile/3,main/2,msg11/0]).
+
+-include("test_server.hrl").
+-define(MID, {ip4Address, #'IP4Address'{address = [124, 124, 124, 222],
+ portNumber = 55555}}).
+-define(A4444, ["11111111"]).
+
+-record('MegacoMessage',
+ {
+ authHeader = asn1_NOVALUE,
+ mess
+ }).
+
+-record('Message',
+ {
+ version,
+ mId,
+ messageBody
+ }). % with extension mark
+
+-record('IP4Address',
+ {
+ address,
+ portNumber = asn1_NOVALUE
+ }).
+
+-record('TransactionRequest',
+ {
+ transactionId,
+ actions = []
+ }). % with extension mark
+
+-record('ActionRequest',
+ {
+ contextId,
+ contextRequest = asn1_NOVALUE,
+ contextAttrAuditReq = asn1_NOVALUE,
+ commandRequests = []
+ }).
+
+-record('CommandRequest',
+ {
+ command,
+ optional = asn1_NOVALUE,
+ wildcardReturn = asn1_NOVALUE
+ }). % with extension mark
+
+-record('NotifyRequest',
+ {
+ terminationID,
+ observedEventsDescriptor,
+ errorDescriptor = asn1_NOVALUE
+ }). % with extension mark
+
+-record('ObservedEventsDescriptor',
+ {
+ requestId,
+ observedEventLst = []
+ }).
+
+-record('ObservedEvent',
+ {
+ eventName,
+ streamID = asn1_NOVALUE,
+ eventParList = [],
+ timeNotation = asn1_NOVALUE
+ }). % with extension mark
+
+-record('EventParameter',
+ {
+ eventParameterName,
+ value
+ }).
+
+-record('TimeNotation',
+ {
+ date,
+ time
+ }).
+
+-record(megaco_term_id, {contains_wildcards = ["f"], id}).
+
+
+compile(_Config,ber,[optimize]) ->
+ {ok,no_module,no_module};
+compile(_Config,per,[optimize]) ->
+ {ok,no_module,no_module};
+compile(Config,Erule,Options) ->
+ ?line DataDir = ?config(data_dir,Config),
+ ?line OutDir = ?config(priv_dir,Config),
+ ?line true = code:add_patha(?config(priv_dir,Config)),
+
+ ?line ok = asn1ct:compile(DataDir ++
+ "MEDIA-GATEWAY-CONTROL.asn",
+ [Erule,{outdir,OutDir}]++Options),
+
+ ?line ok = asn1ct:compile(DataDir ++
+ "OLD-MEDIA-GATEWAY-CONTROL.asn",
+ [Erule,{outdir,OutDir}]++Options),
+ {ok,'OLD-MEDIA-GATEWAY-CONTROL','MEDIA-GATEWAY-CONTROL'}.
+
+
+main(no_module,_) -> ok;
+main('OLD-MEDIA-GATEWAY-CONTROL',_) ->
+% Msg = msg11(),
+ {ok,Msg} = asn1ct:value('OLD-MEDIA-GATEWAY-CONTROL','MegacoMessage'),
+ ?line {ok,Bytes} = asn1_wrapper:encode('OLD-MEDIA-GATEWAY-CONTROL',
+ 'MegacoMessage',Msg),
+ ?line {ok,Msg} = asn1_wrapper:decode('OLD-MEDIA-GATEWAY-CONTROL',
+ 'MegacoMessage',
+ Bytes),
+ ok;
+main(Mod='MEDIA-GATEWAY-CONTROL',Config) ->
+ ?line DataDir = ?config(data_dir,Config),
+ io:format("DataDir:~p~n",[DataDir]),
+ ?line {ok,FilenameList} = file:list_dir(filename:join([DataDir,
+ megacomessages])),
+ %% remove any junk files that may be in the megacomessage directory
+ Pred = fun(X) ->
+ case lists:reverse(X) of
+ [$l,$a,$v,$.|_R] ->true;
+ _ -> false
+ end
+ end,
+ MegacoMsgFilenameList = lists:filter(Pred,FilenameList),
+
+ Fun = fun(F) ->
+ M = read_msg(filename:join([DataDir,megacomessages,F])),
+ {ok,B} = asn1_wrapper:encode(Mod,element(1,M),M),
+ {ok,M} = asn1_wrapper:decode(Mod,element(1,M),B)
+ end,
+ ?line lists:foreach(Fun,MegacoMsgFilenameList),
+ ok.
+
+read_msg(File) ->
+ case file:read_file(File) of
+ {ok,Bin} ->
+ binary_to_term(Bin);
+ _ ->
+ io:format("couldn't read file ~p~n",[File])
+ end.
+
+
+request(Mid, TransId, ContextId, CmdReq) when is_list(CmdReq) ->
+ Actions = [#'ActionRequest'{contextId = ContextId,
+ commandRequests = CmdReq}],
+ Req = {transactions,
+ [{transactionRequest,
+ #'TransactionRequest'{transactionId = TransId,
+ actions = Actions}}]},
+ #'MegacoMessage'{mess = #'Message'{version = 1,
+ mId = Mid,
+ messageBody = Req}}.
+
+msg11() ->
+ TimeStamp = #'TimeNotation'{date = "19990729",
+ time = "22010001"},
+ Parm = #'EventParameter'{eventParameterName = "ds",
+ value = "916135551212"},
+
+ Event = #'ObservedEvent'{eventName = "ddce",
+ timeNotation = TimeStamp,
+ eventParList = [Parm]},
+ Desc = #'ObservedEventsDescriptor'{requestId = 2223,
+ observedEventLst = [Event]},
+ NotifyReq = #'NotifyRequest'{terminationID = [#megaco_term_id{id = ?A4444}],
+ observedEventsDescriptor = Desc},
+ CmdReq = #'CommandRequest'{command = {notifyReq, NotifyReq}},
+ request(?MID, 10002, 0, [CmdReq]).
diff --git a/lib/asn1/test/testMergeCompile.erl b/lib/asn1/test/testMergeCompile.erl
new file mode 100644
index 0000000000..e70ca16b77
--- /dev/null
+++ b/lib/asn1/test/testMergeCompile.erl
@@ -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%
+%%
+%%
+
+-module(testMergeCompile).
+
+-export([compile/3,main/1,mvrasn/1]).
+
+-include("test_server.hrl").
+
+-record('InitiatingMessage',{procedureCode,criticality,value}).
+-record('Iu-ReleaseCommand',{protocolIEs,protocolExtensions}).
+
+compile(Config,Erule,Options) ->
+ ?line DataDir = ?config(data_dir,Config),
+ ?line OutDir = ?config(priv_dir,Config),
+ ?line true = code:add_patha(?config(priv_dir,Config)),
+
+ ?line ok = asn1ct:compile(DataDir ++
+ "MS.set.asn",[Erule,{outdir,OutDir}]++Options),
+
+ ?line ok = asn1ct:compile(DataDir ++
+ "RANAPSET.set.asn1",[Erule,{outdir,OutDir}]++Options),
+
+ ?line ok = asn1ct:compile(filename:join([DataDir,"Mvrasn4.set.asn"]),
+ [Erule,{outdir,OutDir}]++Options),
+
+ ?line ok = asn1ct:compile(filename:join([DataDir,"Mvrasn6.set.asn"]),
+ [Erule,{outdir,OutDir}]++Options).
+
+
+main(Erule) ->
+ %% test of module MS.set.asn that tests OTP-4492: different tagdefault in
+ %% modules and types with same name in modules
+ ?line MSVal = {'Type4M2',8,true,three,"OCTET STRING"},
+ ?line {ok,MSBytes} = asn1_wrapper:encode('MS','Type4M2',MSVal),
+ ?line {ok,MSVal} = asn1_wrapper:decode('MS','Type4M2',MSBytes),
+
+
+ %% test of RANAP.set.asn1
+ ?line _PIEVal = [{'ProtocolIE-Field',4,ignore,{'Cause',{radioNetwork,{'CauseRadioNetwork','rab-pre-empted'}}}}],
+ ?line PIEVal2 = [{'ProtocolIE-Field',4,ignore,{'Cause',{radioNetwork,'rab-pre-empted'}}}],
+ ?line _PEVal = [{'ProtocolExtensionField',[0]}],
+%% ?line EncVal = asn1rt_per_v1:encode_integer([],100),
+ ?line EncVal =
+ case Erule of
+ per ->
+ [1,100];
+ per_bin ->
+ <<1,100>>;
+ uper_bin ->
+ <<1,100>>;
+ ber ->
+ [2,1,1];
+ ber_bin ->
+ <<2,1,1>>;
+ ber_bin_v2 ->
+ <<2,1,1>>
+ end,
+ ?line PEVal2 = [{dummy,1,ignore,EncVal},{dummy,2,reject,EncVal}],
+ ?line Val2 =
+ #'InitiatingMessage'{procedureCode=1,
+ criticality=ignore,
+ value=#'Iu-ReleaseCommand'{protocolIEs=PIEVal2,
+ protocolExtensions=asn1_NOVALUE}},
+
+ ?line {ok,Bytes2} = asn1_wrapper:encode('RANAPSET','InitiatingMessage',Val2),
+ ?line {ok,_Ret2} = asn1_wrapper:decode('RANAPSET','InitiatingMessage',Bytes2),
+
+ ?line Val3 =
+ #'InitiatingMessage'{procedureCode=1,
+ criticality=ignore,
+ value=#'Iu-ReleaseCommand'{protocolIEs=PIEVal2,
+ protocolExtensions=PEVal2}},
+ ?line {ok,Bytes3} = asn1_wrapper:encode('RANAPSET','InitiatingMessage',Val3),
+ ?line {ok,_Ret3} = asn1_wrapper:decode('RANAPSET','InitiatingMessage',Bytes3).
+
+
+mvrasn(Erule) ->
+ case Erule of
+ Ber when Ber == ber;Ber == ber_bin ->
+ ?line ok = test(isd),
+ ?line ok = test(isd2),
+ ?line ok = test(dsd),
+ ?line ok = test(ul_res),
+ ?line ok = test(seqofseq),
+ ?line ok = test('InsertSubscriberDataArg');
+ _ ->
+ ok
+ end,
+ ?line ok = test(mvrasn6,'InsertSubscriberDataArg').
+
+test(isd)->
+ EncPdu = [48,128,129,7,145,148,113,50,1,0,241,131,1,0,176,128,5,0,161,128,48,22,2,1,1,144,2,241,33,145,4,0,1,2,3,146,3,36,131,16,148,2,1,42,48,35,2,1,2,144,2,241,33,145,4,255,255,255,255,146,3,37,147,18,147,0,148,13,7,67,79,77,80,65,78,89,4,67,79,77,53,48,28,2,1,3,144,2,241,33,146,3,26,98,31,148,14,9,67,79,77,80,65,78,89,49,50,3,67,79,77,0,0,0,0,152,1,2,0,0],
+
+ ?line {ok,_} = asn1_wrapper:decode('Mvrasn4',
+ 'InsertSubscriberDataArg',
+ EncPdu),
+ ok;
+
+%
+% Problems with indefinite length encoding !!!
+%
+test(isd2)->
+ EncPdu = [48, 128, 128, 8, 98, 2, 50, 1, 0, 0, 0, 241, 176, 128, 161, 128, 48, 128, 2, 1, 1, 144, 2, 241, 33, 145, 4, 255, 23, 12, 1, 146, 3, 9, 17, 1, 147, 0, 148, 13, 7, 67, 79, 77, 80, 65, 78, 89, 4, 67, 79, 77, 53, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
+
+ ?line {ok,_DecPdu} = asn1_wrapper:decode('Mvrasn4',
+ 'InsertSubscriberDataArg',
+ EncPdu),
+
+ ok;
+
+%
+% Is doing fine, although there is indefinite encoding used... !!!
+%
+test(dsd)->
+ EncPdu = [48, 128, 128, 8, 98, 2, 50, 1, 0, 0, 0, 241, 170, 2, 5, 0, 0, 0, 0, 0],
+
+ ?line {ok,_DecPdu} = asn1_wrapper:decode('Mvrasn4',
+ 'DeleteSubscriberDataArg',
+ EncPdu),
+
+ ok;
+
+%
+% Is doing fine !!!
+%
+test(ul_res)->
+ EncPdu = [48, 9, 4, 7, 145, 148, 113, 66, 16, 17, 241],
+
+ ?line {ok,_DecPdu} = asn1_wrapper:decode('Mvrasn4',
+ 'UpdateGprsLocationRes',
+ EncPdu),
+
+ ok;
+
+test(seqofseq) ->
+ {ok,_V} = asn1_wrapper:decode('Mvrasn4',
+ 'SentParameters',
+ [48,129,190,161,128,4,16,176,197,182,68,41,243,188,205,123,13,9,145,206,200,144,102,4,4,176,197,182,68,4,8,41,243,188,205,123,13,9,145,0,0,161,128,4,16,39,0,3,117,35,189,130,21,42,104,49,194,212,24,151,234,4,4,39,0,3,117,4,8,35,189,130,21,42,104,49,194,0,0,161,128,4,16,62,207,166,59,71,29,37,97,120,25,132,80,144,251,161,123,4,4,62,207,166,59,4,8,71,29,37,97,120,25,132,80,0,0,161,128,4,16,95,183,173,151,17,76,148,146,248,102,127,215,102,224,39,60,4,4,95,183,173,151,4,8,17,76,148,146,248,102,127,215,0,0,161,128,4,16,41,198,247,157,117,190,203,170,91,146,88,91,223,220,188,16,4,4,41,198,247,157,4,8,117,190,203,170,91,146,88,91,0,0]),
+ ok;
+
+test('InsertSubscriberDataArg') ->
+ {ok,_V} =
+ asn1_wrapper:decode('Mvrasn4','InsertSubscriberDataArg',
+ [16#30,16#80,16#81,16#07,16#91,16#94,
+ 16#71,16#92,16#00,16#35,16#80,16#83,
+ 16#01,16#00,16#A6,16#06,16#04,16#01,
+ 16#21,16#04,16#01,16#22,16#B0,16#80,
+ 16#05,16#00,16#A1,16#80,16#30,16#1A,
+ 16#02,16#01,16#01,16#90,16#02,16#F1,
+ 16#21,16#92,16#03,16#0D,16#92,16#1F,
+ 16#94,16#0C,16#03,16#53,16#49,16#4D,
+ 16#03,16#47,16#53,16#4E,16#03,16#4C,
+ 16#4B,16#50,16#00,16#00,16#00,16#00,
+ 16#98,16#01,16#00,16#00,16#00]),
+ ok.
+
+test(mvrasn6,'InsertSubscriberDataArg') ->
+ Val = {'InsertSubscriberDataArg',"IMSI","Address","C",serviceGranted,["abc","cde"],["tele","serv","ice"],asn1_NOVALUE,asn1_NOVALUE,asn1_NOVALUE,asn1_NOVALUE,asn1_NOVALUE,asn1_NOVALUE,asn1_NOVALUE,asn1_NOVALUE,{'NAEA-PreferredCI',"NCC",asn1_NOVALUE},{'GPRSSubscriptionData','NULL',[{'PDP-Context',49,"PT","PDP-Address","QoS",'NULL',"APN",asn1_NOVALUE,asn1_NOVALUE,asn1_NOVALUE}],asn1_NOVALUE},'NULL',onlyMSC,{'LSAInformation','NULL',accessOutsideLSAsAllowed,[{'LSAData',"LSA","L",'NULL',asn1_NOVALUE},{'LSAData',"LSA","L",'NULL',asn1_NOVALUE}],asn1_NOVALUE},'NULL',{'LCSInformation',["Addr","ess","string"],[{'LCS-PrivacyClass',"S","ExtSS",notifyLocationAllowed,[{'ExternalClient',{'LCSClientExternalID',"Addr",asn1_NOVALUE},asn1_NOVALUE,asn1_NOVALUE,asn1_NOVALUE}],[broadcastService,anonymousLocation,targetMSsubscribedService],asn1_NOVALUE}],asn1_NOVALUE},100,"age",{'MC-SS-Info',"S","ExtSS",5,4,asn1_NOVALUE},"C",{'SGSN-CAMEL-SubscriptionInfo',{'GPRS-CSI',[{'GPRS-CamelTDPData',attach,13,"Addr",continueTransaction,asn1_NOVALUE}],11,asn1_NOVALUE,'NULL','NULL'},{'SMS-CSI',[{'SMS-CAMEL-TDP-DataList','sms-CollectedInfo',13,"Addr",continueTransaction,asn1_NOVALUE}],11,asn1_NOVALUE,'NULL','NULL'},asn1_NOVALUE},"ON"},
+
+ {ok,Bytes}=
+ asn1_wrapper:encode('Mvrasn6','InsertSubscriberDataArg',Val),
+
+ {ok,_Res} =
+ asn1_wrapper:decode('Mvrasn6','InsertSubscriberDataArg',Bytes),
+
+ ok.
diff --git a/lib/asn1/test/testMvrasn6.erl b/lib/asn1/test/testMvrasn6.erl
new file mode 100644
index 0000000000..65668f3ed4
--- /dev/null
+++ b/lib/asn1/test/testMvrasn6.erl
@@ -0,0 +1,44 @@
+%%
+%% %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(testMvrasn6).
+
+-export([compile/2]).
+-export([main/0]).
+
+-include("test_server.hrl").
+
+compile(Config,Rules) ->
+
+ ?line DataDir = ?config(data_dir,Config),
+ ?line OutDir = ?config(priv_dir,Config),
+ ?line true = code:add_patha(?config(priv_dir,Config)),
+ ?line Options = [Rules,{outdir,OutDir}],
+ ?line ok = asn1ct:compile(DataDir ++ "Mvrasn-21-4",Options),
+ ?line ok = asn1ct:compile(DataDir ++ "Mvrasn-20-6",Options),
+ ?line ok = asn1ct:compile(DataDir ++ "Mvrasn-19-6",Options),
+ ?line ok = asn1ct:compile(DataDir ++ "Mvrasn-15-6",Options),
+ ?line ok = asn1ct:compile(DataDir ++ "Mvrasn-18-6",Options),
+ ?line ok = asn1ct:compile(DataDir ++ "Mvrasn-14-6",Options),
+ ?line ok = asn1ct:compile(DataDir ++ "Mvrasn-11-6",Options).
+
+
+main() ->
+ ok.
+
diff --git a/lib/asn1/test/testNBAPsystem.erl b/lib/asn1/test/testNBAPsystem.erl
new file mode 100644
index 0000000000..79e553a596
--- /dev/null
+++ b/lib/asn1/test/testNBAPsystem.erl
@@ -0,0 +1,357 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 2005-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(testNBAPsystem).
+
+-export([compile/3,test/2,cell_setup_req_msg/0]).
+
+-include("test_server.hrl").
+
+-record('InitiatingMessage',{
+procedureID, criticality, messageDiscriminator, transactionID, value}).
+-record('AuditRequest',{
+protocolIEs, protocolExtensions = asn1_NOVALUE}).
+-record('ProtocolIE-Field',{
+id, criticality, value}).
+-record('ProcedureID',{
+procedureCode ,ddMode}).
+-record('CellSetupRequestFDD',{
+protocolIEs,protocolExtensions=asn1_NOVALUE}).
+-record('CellSetupRequestFDD_protocolIEs_SEQOF',{
+id, criticality, value}).
+-record('Synchronisation-Configuration-Cell-SetupRqst',{
+'n-INSYNC-IND', 'n-OUTSYNC-IND', 't-RLFAILURE', 'iE-Extensions' = asn1_NOVALUE}).
+-record('PrimarySCH-Information-Cell-SetupRqstFDD',{
+commonPhysicalChannelID, 'primarySCH-Power', 'tSTD-Indicator', 'iE-Extensions' = asn1_NOVALUE}).
+-record('SecondarySCH-Information-Cell-SetupRqstFDD',{
+commonPhysicalChannelID, 'secondarySCH-Power', 'tSTD-Indicator', 'iE-Extensions' = asn1_NOVALUE}).
+-record('PrimaryCCPCH-Information-Cell-SetupRqstFDD',{
+commonPhysicalChannelID, 'bCH-information', 'sTTD-Indicator', 'iE-Extensions' = asn1_NOVALUE}).
+-record('PrimaryCPICH-Information-Cell-SetupRqstFDD',{
+commonPhysicalChannelID, 'primaryCPICH-Power', transmitDiversityIndicator, 'iE-Extensions' = asn1_NOVALUE}).
+-record('BCH-Information-Cell-SetupRqstFDD',{
+commonTransportChannelID, 'bCH-Power', 'iE-Extensions' = asn1_NOVALUE}).
+-record('Limited-power-increase-information-Cell-SetupRqstFDD',{
+powerRaiseLimit, dLPowerAveragingWindowSize, 'iE-Extensions' = asn1_NOVALUE}).
+
+-record('ResourceStatusIndication',{
+ protocolIEs, protocolExtensions = asn1_NOVALUE}).
+%-record('ResourceStatusIndication_protocolIEs_SEQOF',{
+% id, criticality, value}).
+-record('No-Failure-ResourceStatusInd',{
+'local-Cell-InformationList', 'local-Cell-Group-InformationList' = asn1_NOVALUE, 'iE-Extensions' = asn1_NOVALUE}). % with extension mark
+%-record('Local-Cell-InformationList-ResourceStatusInd_SEQOF',{
+% id, criticality, value}).
+-record('Local-Cell-InformationItem-ResourceStatusInd',{
+ 'local-CellID', addorDeleteIndicator,
+ 'dl-or-global-capacityCredit' = asn1_NOVALUE,
+ 'ul-capacityCredit' = asn1_NOVALUE,
+ commonChannelsCapacityConsumptionLaw = asn1_NOVALUE,
+ dedicatedChannelsCapacityConsumptionLaw = asn1_NOVALUE,
+ 'maximumDL-PowerCapability' = asn1_NOVALUE,
+ minSpreadingFactor = asn1_NOVALUE,
+ 'minimumDL-PowerCapability' = asn1_NOVALUE,
+ 'local-Cell-Group-ID' = asn1_NOVALUE,
+ 'iE-Extensions' = asn1_NOVALUE}). % with extension mark
+-record('CommonChannelsCapacityConsumptionLaw_SEQOF',{
+ 'dl-Cost', 'ul-Cost', 'iE-Extensions' = asn1_NOVALUE}). % with extension mark
+-record('DedicatedChannelsCapacityConsumptionLaw_SEQOF',{
+ 'dl-Cost-1', 'dl-Cost-2', 'ul-Cost-1', 'ul-Cost-2',
+ 'iE-Extensions' = asn1_NOVALUE}). % with extension mark
+-record('Local-Cell-InformationItem-ResourceStatusInd_iE-Extensions_SEQOF',{
+ id, criticality, extensionValue}).
+
+
+compile(Config,Rules,Opt) ->
+
+ ?line DataDir = ?config(data_dir,Config),
+ ?line OutDir = ?config(priv_dir,Config),
+ ?line true = code:add_patha(?config(priv_dir,Config)),
+ ?line DataDir2 = filename:join([DataDir,nbapsystem]),
+
+ ?line ok = asn1ct:compile(filename:join([DataDir2,"NBAP-CommonDataTypes.asn"]),[Rules,{outdir,OutDir}]++Opt),
+ ?line ok = asn1ct:compile(filename:join([DataDir2,"NBAP-IEs.asn"]),[Rules,{outdir,OutDir}]++Opt),
+ ?line ok = asn1ct:compile(filename:join([DataDir2,"NBAP-PDU-Contents.asn"]),[Rules,{outdir,OutDir}]++Opt),
+ ?line ok = asn1ct:compile(filename:join([DataDir2,"NBAP-PDU-Discriptions.asn"]),[Rules,{outdir,OutDir}]++Opt),
+ ?line ok = asn1ct:compile(filename:join([DataDir2,"NBAP-Constants.asn"]),[Rules,{outdir,OutDir}]++Opt),
+ ?line ok = asn1ct:compile(filename:join([DataDir2,"NBAP-Containers.asn"]),[Rules,{outdir,OutDir}]++Opt).
+
+
+test(_Erule,Config) ->
+ ?line ok = enc_audit_req_msg(),
+ ?line ok = cell_setup_req_msg_test(),
+ ticket_5812(Config).
+
+ticket_5812(Config) ->
+ ?line Msg = v_5812(),
+ ?line {ok,B2} = asn1_wrapper:encode('NBAP-PDU-Discriptions',
+ 'NBAP-PDU',
+ Msg),
+ V = <<0,28,74,0,3,48,0,0,1,0,123,64,41,0,0,0,126,64,35,95,208,2,89,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,145,0,1,205,0,0,0,0,2,98,64,1,128>>,
+ ?line ok = compare(V,B2),
+ ?line {ok,Msg2} = asn1_wrapper:decode('NBAP-PDU-Discriptions',
+ 'NBAP-PDU',B2),
+ ?line ok = check_record_names(Msg2,Config).
+
+enc_audit_req_msg() ->
+ Msg = {initiatingMessage, audit_req_msg()},
+ ?line {ok,B}=asn1_wrapper:encode('NBAP-PDU-Discriptions',
+ 'NBAP-PDU',
+ Msg),
+ ?line {ok,_Msg}=asn1_wrapper:decode('NBAP-PDU-Discriptions',
+ 'NBAP-PDU',
+ B),
+ ?line {initiatingMessage,
+ #'InitiatingMessage'{value=#'AuditRequest'{protocolIEs=[{_,114,ignore,_}],
+ protocolExtensions = asn1_NOVALUE}}} = _Msg,
+ io:format("Msg: ~n~P~n~n_Msg:~n~P~n",[Msg,15,_Msg,15]),
+ ok.
+
+cell_setup_req_msg_test() ->
+ Msg = {initiatingMessage, cell_setup_req_msg()},
+ ?line {ok,B}=asn1_wrapper:encode('NBAP-PDU-Discriptions',
+ 'NBAP-PDU',
+ Msg),
+ ?line {ok,_Msg}=asn1_wrapper:decode('NBAP-PDU-Discriptions',
+ 'NBAP-PDU',
+ B),
+ io:format("Msg: ~P~n~n_Msg: ~P~n",[Msg,15,_Msg,15]),
+ ok.
+
+audit_req_msg() ->
+ #'InitiatingMessage'{procedureID={'ProcedureID',0,common},
+ criticality=reject,
+ messageDiscriminator=common,
+ transactionID={'longTransActionId',0},
+ value=audit_req()}.
+
+audit_req() ->
+ #'AuditRequest'{
+ protocolIEs =
+ [#'ProtocolIE-Field'{id=114,
+ criticality=ignore,
+ value={'Start-Of-Audit-Sequence-Indicator',
+ 'start-of-audit-sequence' }
+ }
+ ]
+ }.
+
+cell_setup_req_msg() ->
+ #'InitiatingMessage'{
+ procedureID = procedureID(),
+ criticality = reject,
+ messageDiscriminator = common,
+ transactionID = {longTransActionId,0},
+ value = 'CellSetupRequestFDD'()}.
+
+
+
+procedureID() ->
+ #'ProcedureID'{procedureCode = 5,ddMode = fdd}.
+
+'CellSetupRequestFDD'() ->
+ #'CellSetupRequestFDD'{
+ protocolIEs =
+ ['CellSetupRequestFDD_protocolIEs_SEQOF'(124,reject,601),
+ 'CellSetupRequestFDD_protocolIEs_SEQOF'(25,reject,601),
+ 'CellSetupRequestFDD_protocolIEs_SEQOF'(43,reject,10),
+ 'CellSetupRequestFDD_protocolIEs_SEQOF'(276,reject,v1),
+ 'CellSetupRequestFDD_protocolIEs_SEQOF'(282,reject,9750),
+ 'CellSetupRequestFDD_protocolIEs_SEQOF'(281,reject,10700),
+ 'CellSetupRequestFDD_protocolIEs_SEQOF'(131,reject,380),
+ 'CellSetupRequestFDD_protocolIEs_SEQOF'(181,reject,0),
+ 'CellSetupRequestFDD_protocolIEs_SEQOF'(394,reject,
+ 'Synchronisation-Configuration-Cell-SetupRqst'(100,100,100)),
+ 'CellSetupRequestFDD_protocolIEs_SEQOF'(358,reject,5),
+ 'CellSetupRequestFDD_protocolIEs_SEQOF'(180,reject,
+ 'PrimarySCH-Information-Cell-SetupRqstFDD'(11,-18,inactive)),
+ 'CellSetupRequestFDD_protocolIEs_SEQOF'(265,reject,
+ 'SecondarySCH-Information-Cell-SetupRqstFDD'(12,-35,inactive)),
+ 'CellSetupRequestFDD_protocolIEs_SEQOF'(178,reject,
+ 'PrimaryCPICH-Information-Cell-SetupRqstFDD'(13,330,inactive)),
+ 'CellSetupRequestFDD_protocolIEs_SEQOF'(176,reject,'PrimaryCCPCH-Information-Cell-SetupRqstFDD'(15,'BCH-Information-Cell-SetupRqstFDD'(5,-31),inactive)),
+ 'CellSetupRequestFDD_protocolIEs_SEQOF'(369,reject,'Limited-power-increase-information-Cell-SetupRqstFDD'())]}.
+
+
+'CellSetupRequestFDD_protocolIEs_SEQOF'(Id,Criticality,Value) ->
+ #'CellSetupRequestFDD_protocolIEs_SEQOF'{
+ id = Id,
+ criticality = Criticality,
+ value = Value}.
+
+'Limited-power-increase-information-Cell-SetupRqstFDD'() ->
+ #'Limited-power-increase-information-Cell-SetupRqstFDD'{
+ powerRaiseLimit = 5,
+ dLPowerAveragingWindowSize = 30}.
+
+'PrimaryCPICH-Information-Cell-SetupRqstFDD'(Common,Primary,Transmit) ->
+#'PrimaryCPICH-Information-Cell-SetupRqstFDD'{
+ commonPhysicalChannelID = Common,
+ 'primaryCPICH-Power' = Primary,
+ transmitDiversityIndicator = Transmit}.
+
+'BCH-Information-Cell-SetupRqstFDD'(CommonTCID,BCHPower) ->
+ #'BCH-Information-Cell-SetupRqstFDD'{
+ commonTransportChannelID = CommonTCID,
+ 'bCH-Power' = BCHPower}.
+
+'PrimaryCCPCH-Information-Cell-SetupRqstFDD'(CommonPCID,BCHInfo,
+ STTDInd) ->
+ #'PrimaryCCPCH-Information-Cell-SetupRqstFDD'{
+ commonPhysicalChannelID = CommonPCID,
+ 'bCH-information' = BCHInfo,
+ 'sTTD-Indicator' = STTDInd}.
+
+'SecondarySCH-Information-Cell-SetupRqstFDD'(Common,Secondary,TSTDInd) ->
+ #'SecondarySCH-Information-Cell-SetupRqstFDD'{
+ commonPhysicalChannelID = Common,
+ 'secondarySCH-Power' = Secondary,
+ 'tSTD-Indicator' = TSTDInd}.
+
+'PrimarySCH-Information-Cell-SetupRqstFDD'(Common,Primary,TSTDInd) ->
+ #'PrimarySCH-Information-Cell-SetupRqstFDD'{
+ commonPhysicalChannelID = Common,
+ 'primarySCH-Power' = Primary,
+ 'tSTD-Indicator' = TSTDInd}.
+
+'Synchronisation-Configuration-Cell-SetupRqst'(INSYNC,OUTSYNC,RLFAILURE) ->
+ #'Synchronisation-Configuration-Cell-SetupRqst'{
+ 'n-INSYNC-IND' = INSYNC,
+ 'n-OUTSYNC-IND' = OUTSYNC,
+ 't-RLFAILURE' = RLFAILURE}.
+
+v_5812() ->
+ {initiatingMessage,initiatingMessage_051107()}.
+initiatingMessage_051107() ->
+ #'InitiatingMessage'{procedureID = procedureID_051107(),
+ criticality = criticality_051107(),
+ messageDiscriminator = messageDiscriminator_051107(),
+ transactionID = transactionID_051107(),
+ value = value_051107()}.
+procedureID_051107() ->
+ #'ProcedureID'{procedureCode=28,
+ ddMode=common}.
+criticality_051107() -> ignore.
+messageDiscriminator_051107() -> common.
+transactionID_051107() -> {longTransActionId,3}.
+value_051107() ->
+ #'ResourceStatusIndication'{protocolIEs = protocolIEs_051107()}.
+protocolIEs_051107() ->
+ [#'ProtocolIE-Field'{id = 123,
+ criticality = ignore,
+ value = 'IndicationType-ResourceStatusInd_051107'('no-Failure')}].
+
+'IndicationType-ResourceStatusInd_051107'('no-Failure') ->
+ {'no-Failure',#'No-Failure-ResourceStatusInd'{'local-Cell-InformationList' =[#'ProtocolIE-Field'{id = 126,
+ criticality = ignore,
+ value = 'Local-Cell-InformationItem-ResourceStatusInd'()}]}}.
+'Local-Cell-InformationItem-ResourceStatusInd'() ->
+ #'Local-Cell-InformationItem-ResourceStatusInd'{
+ 'local-CellID' = 601,
+ addorDeleteIndicator = add,
+ 'dl-or-global-capacityCredit' = 0,
+ commonChannelsCapacityConsumptionLaw = ['CommonChannelsCapacityConsumptionLaw_051107'()],
+ dedicatedChannelsCapacityConsumptionLaw = ['DedicatedChannelsCapacityConsumptionLaw_SEQOF'()],
+ 'maximumDL-PowerCapability' = 401,
+ minSpreadingFactor = v4,
+ 'minimumDL-PowerCapability' = 461,
+ 'local-Cell-Group-ID' = 0,
+ 'iE-Extensions' = ['Local-Cell-InformationItem-ResourceStatusInd_iE-Extensions_SEQOF'()]}.
+
+'CommonChannelsCapacityConsumptionLaw_051107'() ->
+ #'CommonChannelsCapacityConsumptionLaw_SEQOF'{
+ 'dl-Cost' = 0,
+ 'ul-Cost' = 0}.
+'DedicatedChannelsCapacityConsumptionLaw_SEQOF'() ->
+ #'DedicatedChannelsCapacityConsumptionLaw_SEQOF'{
+ 'dl-Cost-1' = 0,
+ 'dl-Cost-2' = 0,
+ 'ul-Cost-1' = 0,
+ 'ul-Cost-2' = 0}.
+
+'Local-Cell-InformationItem-ResourceStatusInd_iE-Extensions_SEQOF'() ->
+ #'Local-Cell-InformationItem-ResourceStatusInd_iE-Extensions_SEQOF'{
+ id = 610,
+ criticality = ignore,
+ extensionValue = 'hsdpa-non-capable'}.
+
+
+
+
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+compare(V,V) ->
+ ok;
+compare(V,L) when is_list(L) ->
+ compare(V,list_to_binary(L));
+compare(_,_) ->
+ false.
+
+check_record_names(Msg,Config) ->
+ DataDir = ?config(data_dir,Config),
+ OutDir = ?config(priv_dir,Config),
+ io:format("check_record_names: compiling ~p~ninclude directory: ~p~n",
+ [filename:join([DataDir,"test_records"]),OutDir]),
+ ?line {ok,test_records} = compile:file(filename:join([DataDir,"test_records"]),
+ [{i,OutDir}]),
+ io:format("check_record_names: calling test_records:'check_record_names_OTP-5812'/1~n",[]),
+ ?line ok = test_records:'check_record_names_OTP-5812'(Msg).
+
+% check_record_names({initiatingMessage,
+% #'InitiatingMessage'{procedureID = ProcedureID,
+% criticality = _Criticality,
+% messageDiscriminator = _MessageDisc,
+% transactionID = _TransactionID,
+% value = Value}}) ->
+
+% ?line ok = check_record_ProcedureID(ProcedureID),
+% ?line ok = check_record_Value(Value).
+
+% check_record_ProcedureID(#'ProcedureID'{}) ->
+% ok;
+% check_record_ProcedureID(_) -> false.
+
+% check_record_Value(#'ResourceStatusIndication'{protocolIEs = ProtocolIEs}) ->
+% ?line ok = check_record_ProtocolIEs(ProtocolIEs);
+% check_record_Value(_) -> false.
+
+% check_record_ProtocolIEs(#'ProtocolIE-Field'{value =IndicationType}) ->
+% ?line ok = check_record_NFResourceStatusInd(IndicationType);
+% check_record_ProtocolIEs(_) -> false.
+
+% check_record_NFResourceStatusInd({'no-Failure',#'No-Failure-ResourceStatusInd'{'local-Cell-InformationList'=[LCI]}}) ->
+% ?line ok = check_record_LCInfoResourceStatusInd(LCI);
+% check_record_NFResourceStatusInd(_) -> false.
+
+% check_record_LCInfoResourceStatusInd(#'Local-Cell-InformationItem-ResourceStatusInd'{commonChannelsCapacityConsumptionLaw=[CCCCL],dedicatedChannelsCapacityConsumptionLaw=[DCCCL],'iE-Extensions' = [LCIRE]}) ->
+% ?line ok = check_record_CCCCL(CCCCL),
+% ?line ok = check_record_DCCCL(DCCCL),
+% ?line ok = check_record_LCIRE(LCIRE).
+
+% check_record_CCCCL(#'CommonChannelsCapacityConsumptionLaw_SEQOF'{}) ->
+% ok;
+% check_record_CCCCL(_) -> false.
+
+% check_record_DCCCL(#'DedicatedChannelsCapacityConsumptionLaw_SEQOF'{}) ->
+% ok;
+% check_record_DCCCL(_) -> false.
+% check_record_LCIRE(#'ProtocolExtensionField'{}) ->
+% ok;
+% check_record_LCIRE(_) -> false.
diff --git a/lib/asn1/test/testOpenTypeImplicitTag.erl b/lib/asn1/test/testOpenTypeImplicitTag.erl
new file mode 100644
index 0000000000..4300509e07
--- /dev/null
+++ b/lib/asn1/test/testOpenTypeImplicitTag.erl
@@ -0,0 +1,52 @@
+%%
+%% %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(testOpenTypeImplicitTag).
+
+-export([compile/3]).
+-export([main/1]).
+
+-include("test_server.hrl").
+
+
+compile(Config,Rules,Options) ->
+
+ ?line DataDir = ?config(data_dir,Config),
+ ?line OutDir = ?config(priv_dir,Config),
+ ?line true = code:add_patha(?config(priv_dir,Config)),
+ ?line ok = asn1ct:compile(DataDir ++ "OpenTypeImplicitTag",[Rules,{outdir,OutDir}]++Options).
+
+
+
+main(_Rules) ->
+
+ ?line {ok,Bytes1} =
+ asn1_wrapper:encode('OpenTypeImplicitTag','Seq',
+ {'Seq',[1,1,255],[1,1,255],12,[1,1,255]}),
+ ?line {ok,{'Seq',_,_,12,_}} =
+ asn1_wrapper:decode('OpenTypeImplicitTag','Seq',
+ lists:flatten(Bytes1)),
+
+ ?line {ok,Bytes2} =
+ asn1_wrapper:encode('OpenTypeImplicitTag','Seq',
+ {'Seq',[1,1,255],asn1_NOVALUE,12,[1,1,255]}),
+ ?line {ok,{'Seq',_,asn1_NOVALUE,12,_}} =
+ asn1_wrapper:decode('OpenTypeImplicitTag','Seq',
+ lists:flatten(Bytes2)),
+ ok.
diff --git a/lib/asn1/test/testOpt.erl b/lib/asn1/test/testOpt.erl
new file mode 100644
index 0000000000..2967595fd2
--- /dev/null
+++ b/lib/asn1/test/testOpt.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(testOpt).
+
+-export([compile/2]).
+-export([main/1]).
+
+-include("test_server.hrl").
+
+-record('Opt1',{bool0,
+ bool1 = asn1_NOVALUE,
+ bool2 = asn1_NOVALUE,
+ bool3 = asn1_NOVALUE}).
+
+-record('Opt2',{bool10,
+ bool11 = asn1_NOVALUE,
+ bool12 = asn1_NOVALUE,
+ bool13}).
+
+-record('Opt3',{bool30 = asn1_NOVALUE,
+ bool31 = asn1_NOVALUE,
+ bool32 = asn1_NOVALUE,
+ bool33 = asn1_NOVALUE}).
+
+
+compile(Config,Rules) ->
+
+ ?line DataDir = ?config(data_dir,Config),
+ ?line OutDir = ?config(priv_dir,Config),
+ ?line true = code:add_patha(?config(priv_dir,Config)),
+ ?line ok = asn1ct:compile(DataDir ++ "Opt",[Rules,{outdir,OutDir}]).
+
+
+
+main(_Rules) ->
+
+ ?line {ok,Bytes11} = asn1_wrapper:encode('Opt','Opt1',#'Opt1'{bool0 = true,
+ bool1 = true,
+ bool2 = true,
+ bool3 = true}),
+ ?line {ok,{'Opt1',true,true,true,true}} =
+ asn1_wrapper:decode('Opt','Opt1',lists:flatten(Bytes11)),
+
+ ?line {ok,Bytes12} = asn1_wrapper:encode('Opt','Opt1',#'Opt1'{bool0 = true}),
+ ?line {ok,{'Opt1',true,asn1_NOVALUE,asn1_NOVALUE,asn1_NOVALUE}} =
+ asn1_wrapper:decode('Opt','Opt1',lists:flatten(Bytes12)),
+
+ ?line {ok,Bytes13} = asn1_wrapper:encode('Opt','Opt1',#'Opt1'{bool0 = true,
+ bool2 = false}),
+ ?line {ok,{'Opt1',true,asn1_NOVALUE,false,asn1_NOVALUE}} =
+ asn1_wrapper:decode('Opt','Opt1',lists:flatten(Bytes13)),
+
+ ?line {ok,Bytes14} = asn1_wrapper:encode('Opt','Opt1',#'Opt1'{bool0 = false,
+ bool3 = false}),
+ ?line {ok,{'Opt1',false,asn1_NOVALUE,asn1_NOVALUE,false}} =
+ asn1_wrapper:decode('Opt','Opt1',lists:flatten(Bytes14)),
+
+
+
+
+ ?line {ok,Bytes21} = asn1_wrapper:encode('Opt','Opt2',#'Opt2'{bool10 = false,
+ bool11 = false,
+ bool12 = false,
+ bool13 = false}),
+ ?line {ok,{'Opt2',false,false,false,false}} =
+ asn1_wrapper:decode('Opt','Opt2',lists:flatten(Bytes21)),
+
+ ?line {ok,Bytes22} = asn1_wrapper:encode('Opt','Opt2',#'Opt2'{bool10 = true,
+ bool13 = false}),
+ ?line {ok,{'Opt2',true,asn1_NOVALUE,asn1_NOVALUE,false}} =
+ asn1_wrapper:decode('Opt','Opt2',lists:flatten(Bytes22)),
+
+ ?line {ok,Bytes23} = asn1_wrapper:encode('Opt','Opt2',#'Opt2'{bool10 = true,
+ bool11 = false,
+ bool13 = false}),
+ ?line {ok,{'Opt2',true,false,asn1_NOVALUE,false}} =
+ asn1_wrapper:decode('Opt','Opt2',lists:flatten(Bytes23)),
+
+ ?line {ok,Bytes24} = asn1_wrapper:encode('Opt','Opt2',#'Opt2'{bool10 = false,
+ bool12 = false,
+ bool13 = false}),
+ ?line {ok,{'Opt2',false,asn1_NOVALUE,false,false}} =
+ asn1_wrapper:decode('Opt','Opt2',lists:flatten(Bytes24)),
+
+
+
+
+ ?line {ok,Bytes31} = asn1_wrapper:encode('Opt','Opt3',#'Opt3'{bool30 = false,
+ bool31 = false,
+ bool32 = false,
+ bool33 = false}),
+ ?line {ok,{'Opt3',false,false,false,false}} =
+ asn1_wrapper:decode('Opt','Opt3',lists:flatten(Bytes31)),
+
+ ?line {ok,Bytes32} = asn1_wrapper:encode('Opt','Opt3',#'Opt3'{}),
+ ?line {ok,{'Opt3',asn1_NOVALUE,asn1_NOVALUE,asn1_NOVALUE,asn1_NOVALUE}} =
+ asn1_wrapper:decode('Opt','Opt3',lists:flatten(Bytes32)),
+
+ ?line {ok,Bytes33} = asn1_wrapper:encode('Opt','Opt3',#'Opt3'{bool30 = true}),
+ ?line {ok,{'Opt3',true,asn1_NOVALUE,asn1_NOVALUE,asn1_NOVALUE}} =
+ asn1_wrapper:decode('Opt','Opt3',lists:flatten(Bytes33)),
+
+ ?line {ok,Bytes34} = asn1_wrapper:encode('Opt','Opt3',#'Opt3'{bool32 = false}),
+ ?line {ok,{'Opt3',asn1_NOVALUE,asn1_NOVALUE,false,asn1_NOVALUE}} =
+ asn1_wrapper:decode('Opt','Opt3',lists:flatten(Bytes34)),
+
+ ?line {ok,Bytes35} = asn1_wrapper:encode('Opt','Opt3',#'Opt3'{bool33 = false}),
+ ?line {ok,{'Opt3',asn1_NOVALUE,asn1_NOVALUE,asn1_NOVALUE,false}} =
+ asn1_wrapper:decode('Opt','Opt3',lists:flatten(Bytes35)),
+
+
+
+ ok.
diff --git a/lib/asn1/test/testParamBasic.erl b/lib/asn1/test/testParamBasic.erl
new file mode 100644
index 0000000000..172a2881cd
--- /dev/null
+++ b/lib/asn1/test/testParamBasic.erl
@@ -0,0 +1,99 @@
+%%
+%% %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(testParamBasic).
+
+-export([compile/3]).
+-export([compile_der/2]).
+-export([main/1]).
+
+-include("test_server.hrl").
+
+-record('T11',{number, string=asn1_DEFAULT}).
+-record('T12',{number, string=asn1_DEFAULT}).
+-record('T21',{number, string}).
+-record('T22',{number, string}).
+
+
+compile(Config,Rules,Options) ->
+
+ ?line DataDir = ?config(data_dir,Config),
+ ?line OutDir = ?config(priv_dir,Config),
+ ?line true = code:add_patha(?config(priv_dir,Config)),
+ ?line ok = asn1ct:compile(DataDir ++ "ParamBasic",
+ [Rules,{outdir,OutDir}]++Options).
+
+compile_der(Config,Rules) ->
+ ?line DataDir = ?config(data_dir,Config),
+ ?line OutDir = ?config(priv_dir,Config),
+ ?line true = code:add_patha(?config(priv_dir,Config)),
+ ?line ok = asn1ct:compile(DataDir ++ "ParamBasic",
+ [der,Rules,{outdir,OutDir}]).
+
+main(Rules) ->
+
+ ?line {ok,Bytes11} =
+ asn1_wrapper:encode('ParamBasic','T11',
+ #'T11'{number = 11,
+ string = "hello"}),
+ ?line {ok,{'T11',11,"hello"}} =
+ asn1_wrapper:decode('ParamBasic','T11',Bytes11),
+
+ ?line {ok,Bytes12} =
+ asn1_wrapper:encode('ParamBasic','T12',
+ #'T12'{number = 11,
+ string = [1,0,1,0,1]}),
+ ?line {ok,{'T12',11,[1,0,1,0,1]}} =
+ asn1_wrapper:decode('ParamBasic','T12',Bytes12),
+
+ ?line {ok,Bytes13} =
+ asn1_wrapper:encode('ParamBasic','T21',
+ #'T21'{number = 11,
+ string = "hello"}),
+ ?line {ok,{'T21',11,"hello"}} =
+ asn1_wrapper:decode('ParamBasic','T21',Bytes13),
+
+ ?line {ok,Bytes14} =
+ asn1_wrapper:encode('ParamBasic','T22',
+ #'T22'{number = 11,
+ string = [1,0,1,0,1]}),
+ ?line {ok,{'T22',11,[1,0,1,0,1]}} =
+ asn1_wrapper:decode('ParamBasic','T22',Bytes14),
+
+ case Rules of
+ der ->
+
+ ?line {ok,[48,3,128,1,11]} =
+ asn1_wrapper:encode('ParamBasic','T11',
+ #'T11'{number = 11,
+ string = "hej"}),
+ ?line {ok,{'T11',11,"hej"}} =
+ asn1_wrapper:decode('ParamBasic','T11',[48,3,128,1,11]),
+
+ ?line {ok,[48,3,128,1,11]} =
+ asn1_wrapper:encode('ParamBasic','T12',
+ #'T12'{number = 11,
+ string = [1,0,1,0]}),
+
+ ?line {ok,{'T12',11,[1,0,1,0]}} =
+ asn1_wrapper:decode('ParamBasic','T12',[48,3,128,1,11]);
+ _ -> ok
+ end,
+
+ ok.
diff --git a/lib/asn1/test/testParameterizedInfObj.erl b/lib/asn1/test/testParameterizedInfObj.erl
new file mode 100644
index 0000000000..91d160f335
--- /dev/null
+++ b/lib/asn1/test/testParameterizedInfObj.erl
@@ -0,0 +1,114 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 2001-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(testParameterizedInfObj).
+
+-export([compile/3,main/1,ranap/1]).
+
+-include("test_server.hrl").
+
+-record('AllocationOrRetentionPriority',{priorityLevel,iE_Extensions}).
+-record('ProtocolExtensionField',{id,criticality,extensionValue}).
+
+-record('InitiatingMessage',{procedureCode,criticality,value}).
+-record('Iu-ReleaseCommand',{protocolIEs,protocolExtensions}).
+
+
+compile(Config,Rules,Options) ->
+
+ ?line DataDir = ?config(data_dir,Config),
+ ?line OutDir = ?config(priv_dir,Config),
+ ?line true = code:add_patha(?config(priv_dir,Config)),
+
+ ?line ok = asn1ct:compile(DataDir ++ "Param",[Rules,{outdir,OutDir}]++Options).
+% ?line ok = asn1ct:compile(DataDir ++ "RANAP-CommonDataTypes",[Rules,{outdir,OutDir}]++Options).
+
+
+main(Erule) ->
+ PERVal = #'AllocationOrRetentionPriority'
+ {priorityLevel = true,
+ iE_Extensions =
+ [#'ProtocolExtensionField'{id=14,
+ criticality=reject,
+ extensionValue=open_type(Erule,[0])},
+ #'ProtocolExtensionField'{id=2,
+ criticality=ignore,
+ extensionValue=open_type(Erule,[1])}]},
+ BERVal = #'AllocationOrRetentionPriority'
+ {priorityLevel = true,
+ iE_Extensions =
+ [#'ProtocolExtensionField'{id=14,
+ criticality=reject,
+ extensionValue=[2,1,0]},
+ #'ProtocolExtensionField'{id=2,
+ criticality=ignore,
+ extensionValue=[2,1,1]}]},
+ ?line {ok,Bytes1} =
+ case asn1_wrapper:erule(Erule) of
+ per ->
+ asn1_wrapper:encode('Param','AllocationOrRetentionPriority',
+ PERVal);
+ _ ->
+ asn1_wrapper:encode('Param','AllocationOrRetentionPriority',
+ BERVal)
+ end,
+
+ ?line {ok,{'AllocationOrRetentionPriority',true,[_R1,_R2]}} =
+ asn1_wrapper:decode('Param','AllocationOrRetentionPriority',Bytes1),
+
+ %% test code for OTP-4242, ValueFromObject
+
+ case asn1_wrapper:erule(Erule) of
+ ber ->
+ ?line {ok,_Val3} = asn1_wrapper:decode('Param','OS1',[4,2,1,2]),
+ ?line {error,_Reason1} =
+ asn1_wrapper:decode('Param','OS1',[4,4,1,2,3,4]),
+ ?line {error,_Reason2} =
+ asn1_wrapper:decode('Param','OS2',[4,4,1,2,3,4]),
+ ?line {ok,_Val4} = asn1_wrapper:decode('Param','OS1',[4,2,1,2]);
+ per ->
+ ?line {ok,Bytes3} =
+ asn1_wrapper:encode('Param','OS1',[1,2]),
+ ?line {ok,[1,2]} =
+ asn1_wrapper:decode('Param','OS1',Bytes3),
+ ?line {error,_Reason3} =
+ asn1_wrapper:encode('Param','OS1',[1,2,3,4])
+ end,
+
+ ok.
+
+
+ranap(_Erule) ->
+ ?line PIEVal2 = [{'ProtocolIE-Field',4,ignore,{'Cause',{radioNetwork,'rab-pre-empted'}}}],
+ ?line Val2 =
+ #'InitiatingMessage'{procedureCode=1,
+ criticality=ignore,
+ value=#'Iu-ReleaseCommand'{protocolIEs=PIEVal2,
+ protocolExtensions=asn1_NOVALUE}},
+
+ ?line {ok,Bytes2} = asn1_wrapper:encode('RANAP','InitiatingMessage',Val2),
+ ?line {ok,_Ret2} = asn1_wrapper:decode('RANAP','InitiatingMessage',Bytes2),
+
+ ok.
+
+open_type(uper_bin,Val) when is_list(Val) ->
+ list_to_binary(Val);
+open_type(_,Val) ->
+ Val.
diff --git a/lib/asn1/test/testPrim.erl b/lib/asn1/test/testPrim.erl
new file mode 100644
index 0000000000..4ccdd82c13
--- /dev/null
+++ b/lib/asn1/test/testPrim.erl
@@ -0,0 +1,695 @@
+%%
+%% %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(testPrim).
+
+-export([compile/3]).
+-export([bool/1]).
+-export([int/1]).
+-export([enum/1]).
+-export([obj_id/1]).
+-export([rel_oid/1]).
+-export([null/1]).
+-export([real/1]).
+
+-include("test_server.hrl").
+
+
+
+compile(Config,Rules,Opt) ->
+
+ ?line DataDir = ?config(data_dir,Config),
+ ?line OutDir = ?config(priv_dir,Config),
+ ?line true = code:add_patha(?config(priv_dir,Config)),
+ case Opt of
+ [optimize] ->
+ ?line ok = asn1ct:compile(DataDir ++ "Prim",
+ [Rules,optimize,{outdir,OutDir}]),
+ ?line ok = asn1ct:compile(DataDir ++ "Real",
+ [Rules,optimize,{outdir,OutDir}]);
+ __ ->
+ ?line ok = asn1ct:compile(DataDir ++ "Prim",
+ [Rules,{outdir,OutDir}]),
+ ?line ok = asn1ct:compile(DataDir ++ "Real",
+ [Rules,{outdir,OutDir}])
+ end.
+
+
+
+
+bool(Rules) ->
+
+ %%==========================================================
+ %% Bool ::= BOOLEAN
+ %%==========================================================
+
+ ?line {ok,Bytes1} = asn1_wrapper:encode('Prim','Bool',true),
+ ?line {ok,true} = asn1_wrapper:decode('Prim','Bool',lists:flatten(Bytes1)),
+
+ ?line {ok,Bytes2} = asn1_wrapper:encode('Prim','Bool',false),
+ ?line {ok,false} = asn1_wrapper:decode('Prim','Bool',lists:flatten(Bytes2)),
+
+ ?line case asn1_wrapper:erule(Rules) of
+ ber ->
+ ?line {error,{asn1,{encode_boolean,517}}} =
+ (catch asn1_wrapper:encode('Prim','Bool',517)),
+ ok;
+ per ->
+ ok
+ end,
+
+
+
+
+
+ %%==========================================================
+ %% BoolCon ::= [20] BOOLEAN
+ %%==========================================================
+
+
+ ?line {ok,BytesCon1} = asn1_wrapper:encode('Prim','BoolCon',true),
+ ?line {ok,true} = asn1_wrapper:decode('Prim','BoolCon',lists:flatten(BytesCon1)),
+
+ ?line {ok,BytesCon2} = asn1_wrapper:encode('Prim','BoolCon',false),
+ ?line {ok,false} = asn1_wrapper:decode('Prim','BoolCon',lists:flatten(BytesCon2)),
+
+ ?line case asn1_wrapper:erule(Rules) of
+ ber ->
+ ?line {error,{asn1,{encode_boolean,517}}} =
+ (catch asn1_wrapper:encode('Prim','BoolCon',517)),
+ ok;
+ per ->
+ ok
+ end,
+
+
+
+
+
+ %%==========================================================
+ %% BoolPri ::= [PRIVATE 21] BOOLEAN
+ %%==========================================================
+
+ ?line {ok,BytesPri1} = asn1_wrapper:encode('Prim','BoolPri',true),
+ ?line {ok,true} = asn1_wrapper:decode('Prim','BoolPri',lists:flatten(BytesPri1)),
+
+ ?line {ok,BytesPri2} = asn1_wrapper:encode('Prim','BoolPri',false),
+ ?line {ok,false} = asn1_wrapper:decode('Prim','BoolPri',lists:flatten(BytesPri2)),
+
+ ?line case asn1_wrapper:erule(Rules) of
+ ber ->
+ ?line {error,{asn1,{encode_boolean,517}}} =
+ (catch asn1_wrapper:encode('Prim','BoolPri',517)),
+ ok;
+ per ->
+ ok
+ end,
+
+
+ %%==========================================================
+ %% BoolApp ::= [APPLICATION 22] BOOLEAN
+ %%==========================================================
+
+ ?line {ok,BytesApp1} = asn1_wrapper:encode('Prim','BoolApp',true),
+ ?line {ok,true} = asn1_wrapper:decode('Prim','BoolApp',lists:flatten(BytesApp1)),
+
+ ?line {ok,BytesApp2} = asn1_wrapper:encode('Prim','BoolApp',false),
+ ?line {ok,false} = asn1_wrapper:decode('Prim','BoolApp',lists:flatten(BytesApp2)),
+
+ ?line case asn1_wrapper:erule(Rules) of
+ ber ->
+ ?line {error,{asn1,{encode_boolean,517}}} =
+ (catch asn1_wrapper:encode('Prim','BoolApp',517)),
+ ok;
+ per ->
+ ok
+ end,
+
+
+ %%==========================================================
+ %% BoolExpCon ::= [30] EXPLICIT BOOLEAN
+ %%==========================================================
+
+ ?line {ok,BytesExpCon1} = asn1_wrapper:encode('Prim','BoolExpCon',true),
+ ?line {ok,true} = asn1_wrapper:decode('Prim','BoolExpCon',lists:flatten(BytesExpCon1)),
+
+ ?line {ok,BytesExpCon2} = asn1_wrapper:encode('Prim','BoolExpCon',false),
+ ?line {ok,false} = asn1_wrapper:decode('Prim','BoolExpCon',lists:flatten(BytesExpCon2)),
+
+ ?line case asn1_wrapper:erule(Rules) of
+ ber ->
+ ?line {error,{asn1,{encode_boolean,517}}} =
+ (catch asn1_wrapper:encode('Prim','BoolExpCon',517)),
+ ok;
+ per ->
+ ok
+ end,
+
+
+
+ %%==========================================================
+ %% BoolExpPri ::= [PRIVATE 31] EXPLICIT BOOLEAN
+ %%==========================================================
+
+ ?line {ok,BytesExpPri1} = asn1_wrapper:encode('Prim','BoolExpPri',true),
+ ?line {ok,true} = asn1_wrapper:decode('Prim','BoolExpPri',lists:flatten(BytesExpPri1)),
+
+ ?line {ok,BytesExpPri2} = asn1_wrapper:encode('Prim','BoolExpPri',false),
+ ?line {ok,false} = asn1_wrapper:decode('Prim','BoolExpPri',lists:flatten(BytesExpPri2)),
+
+ ?line case asn1_wrapper:erule(Rules) of
+ ber ->
+ ?line {error,{asn1,{encode_boolean,517}}} =
+ (catch asn1_wrapper:encode('Prim','BoolExpPri',517)),
+ ok;
+ per ->
+ ok
+ end,
+
+
+ %%==========================================================
+ %% BoolExpApp ::= [APPLICATION 32] EXPLICIT BOOLEAN
+ %%==========================================================
+
+ ?line {ok,BytesExpApp1} = asn1_wrapper:encode('Prim','BoolExpApp',true),
+ ?line {ok,true} = asn1_wrapper:decode('Prim','BoolExpApp',lists:flatten(BytesExpApp1)),
+
+ ?line {ok,BytesExpApp2} = asn1_wrapper:encode('Prim','BoolExpApp',false),
+ ?line {ok,false} = asn1_wrapper:decode('Prim','BoolExpApp',lists:flatten(BytesExpApp2)),
+
+ ?line case asn1_wrapper:erule(Rules) of
+ ber ->
+ ?line {error,{asn1,{encode_boolean,517}}} =
+ (catch asn1_wrapper:encode('Prim','BoolExpApp',517)),
+ ok;
+ per ->
+ ok
+ end,
+
+ ok.
+
+
+int(Rules) ->
+
+
+ %%==========================================================
+ %% Int ::= INTEGER
+ %%==========================================================
+
+ %% test of OTP-2666 encoding should use minimum number of octets x.690 8.3.2
+ ?line {ok,Bytes0} = asn1_wrapper:encode('Prim','Int',-128),
+ ?line L0 = lists:flatten(Bytes0),
+ ?line {ok,-128} = asn1_wrapper:decode('Prim','Int',lists:flatten(L0)),
+ case asn1_wrapper:erule(Rules) of
+ ber ->
+ ?line [_,1,128] = L0;
+ per -> ok
+ end,
+
+ ?line {ok,Bytes1} = asn1_wrapper:encode('Prim','Int',4),
+ ?line {ok,4} = asn1_wrapper:decode('Prim','Int',lists:flatten(Bytes1)),
+
+ ?line {ok,Bytes2} = asn1_wrapper:encode('Prim','Int',444),
+ ?line {ok,444} = asn1_wrapper:decode('Prim','Int',lists:flatten(Bytes2)),
+
+ ?line {ok,Bytes3} = asn1_wrapper:encode('Prim','Int',123456789),
+ ?line {ok,123456789} = asn1_wrapper:decode('Prim','Int',lists:flatten(Bytes3)),
+
+ ?line {ok,Bytes4} = asn1_wrapper:encode('Prim','Int',12345678901234567890),
+ ?line {ok,12345678901234567890} = asn1_wrapper:decode('Prim','Int',lists:flatten(Bytes4)),
+
+ ?line {ok,Bytes5} = asn1_wrapper:encode('Prim','Int',-100),
+ ?line {ok,-100} = asn1_wrapper:decode('Prim','Int',lists:flatten(Bytes5)),
+
+ ?line {ok,Bytes6} = asn1_wrapper:encode('Prim','Int',-255),
+ ?line {ok,-255} = asn1_wrapper:decode('Prim','Int',lists:flatten(Bytes6)),
+
+ ?line {ok,Bytes7} = asn1_wrapper:encode('Prim','Int',-256),
+ ?line {ok,-256} = asn1_wrapper:decode('Prim','Int',lists:flatten(Bytes7)),
+
+ ?line {ok,Bytes8} = asn1_wrapper:encode('Prim','Int',-257),
+ ?line {ok,-257} = asn1_wrapper:decode('Prim','Int',lists:flatten(Bytes8)),
+
+ ?line {ok,Bytes9} = asn1_wrapper:encode('Prim','Int',-1234567890),
+ ?line {ok,-1234567890} = asn1_wrapper:decode('Prim','Int',lists:flatten(Bytes9)),
+
+ ?line {ok,Bytes10} = asn1_wrapper:encode('Prim','Int',-2147483648),
+ ?line {ok,-2147483648} = asn1_wrapper:decode('Prim','Int',lists:flatten(Bytes10)),
+
+
+
+
+
+ %%==========================================================
+ %% IntCon ::= [40] INTEGER
+ %%==========================================================
+
+ ?line {ok,BytesCon1} = asn1_wrapper:encode('Prim','IntCon',4),
+ ?line {ok,4} = asn1_wrapper:decode('Prim','IntCon',lists:flatten(BytesCon1)),
+
+ ?line {ok,BytesCon2} = asn1_wrapper:encode('Prim','IntCon',444),
+ ?line {ok,444} = asn1_wrapper:decode('Prim','IntCon',lists:flatten(BytesCon2)),
+
+ ?line {ok,BytesCon3} = asn1_wrapper:encode('Prim','IntCon',123456789),
+ ?line {ok,123456789} = asn1_wrapper:decode('Prim','IntCon',lists:flatten(BytesCon3)),
+
+ ?line {ok,BytesCon4} = asn1_wrapper:encode('Prim','IntCon',12345678901234567890),
+ ?line {ok,12345678901234567890} = asn1_wrapper:decode('Prim','IntCon',lists:flatten(BytesCon4)),
+
+ ?line {ok,BytesCon5} = asn1_wrapper:encode('Prim','IntCon',-100),
+ ?line {ok,-100} = asn1_wrapper:decode('Prim','IntCon',lists:flatten(BytesCon5)),
+
+ ?line {ok,BytesCon6} = asn1_wrapper:encode('Prim','IntCon',-255),
+ ?line {ok,-255} = asn1_wrapper:decode('Prim','IntCon',lists:flatten(BytesCon6)),
+
+ ?line {ok,BytesCon7} = asn1_wrapper:encode('Prim','IntCon',-256),
+ ?line {ok,-256} = asn1_wrapper:decode('Prim','IntCon',lists:flatten(BytesCon7)),
+
+ ?line {ok,BytesCon8} = asn1_wrapper:encode('Prim','IntCon',-257),
+ ?line {ok,-257} = asn1_wrapper:decode('Prim','IntCon',lists:flatten(BytesCon8)),
+
+ ?line {ok,BytesCon9} = asn1_wrapper:encode('Prim','IntCon',-1234567890),
+ ?line {ok,-1234567890} = asn1_wrapper:decode('Prim','IntCon',lists:flatten(BytesCon9)),
+
+ ?line {ok,BytesCon10} = asn1_wrapper:encode('Prim','Int',-2147483648),
+ ?line {ok,-2147483648} = asn1_wrapper:decode('Prim','Int',lists:flatten(BytesCon10)),
+
+
+
+ %%==========================================================
+ %% IntPri ::= [PRIVATE 41] INTEGER
+ %%==========================================================
+
+ ?line {ok,BytesPri1} = asn1_wrapper:encode('Prim','IntPri',4),
+ ?line {ok,4} = asn1_wrapper:decode('Prim','IntPri',lists:flatten(BytesPri1)),
+
+ ?line {ok,BytesPri2} = asn1_wrapper:encode('Prim','IntPri',444),
+ ?line {ok,444} = asn1_wrapper:decode('Prim','IntPri',lists:flatten(BytesPri2)),
+
+ ?line {ok,BytesPri3} = asn1_wrapper:encode('Prim','IntPri',123456789),
+ ?line {ok,123456789} = asn1_wrapper:decode('Prim','IntPri',lists:flatten(BytesPri3)),
+
+ ?line {ok,BytesPri4} = asn1_wrapper:encode('Prim','IntPri',12345678901234567890),
+ ?line {ok,12345678901234567890} = asn1_wrapper:decode('Prim','IntPri',lists:flatten(BytesPri4)),
+
+ ?line {ok,BytesPri5} = asn1_wrapper:encode('Prim','IntPri',-100),
+ ?line {ok,-100} = asn1_wrapper:decode('Prim','IntPri',lists:flatten(BytesPri5)),
+
+ ?line {ok,BytesPri6} = asn1_wrapper:encode('Prim','IntPri',-255),
+ ?line {ok,-255} = asn1_wrapper:decode('Prim','IntPri',lists:flatten(BytesPri6)),
+
+ ?line {ok,BytesPri7} = asn1_wrapper:encode('Prim','IntPri',-256),
+ ?line {ok,-256} = asn1_wrapper:decode('Prim','IntPri',lists:flatten(BytesPri7)),
+
+ ?line {ok,BytesPri8} = asn1_wrapper:encode('Prim','IntPri',-257),
+ ?line {ok,-257} = asn1_wrapper:decode('Prim','IntPri',lists:flatten(BytesPri8)),
+
+ ?line {ok,BytesPri9} = asn1_wrapper:encode('Prim','IntPri',-1234567890),
+ ?line {ok,-1234567890} = asn1_wrapper:decode('Prim','IntPri',lists:flatten(BytesPri9)),
+
+ ?line {ok,BytesPri10} = asn1_wrapper:encode('Prim','Int',-2147483648),
+ ?line {ok,-2147483648} = asn1_wrapper:decode('Prim','Int',lists:flatten(BytesPri10)),
+
+
+
+ %%==========================================================
+ %% IntApp ::= [APPLICATION 42] INTEGER
+ %%==========================================================
+
+ ?line {ok,BytesApp1} = asn1_wrapper:encode('Prim','IntApp',4),
+ ?line {ok,4} = asn1_wrapper:decode('Prim','IntApp',lists:flatten(BytesApp1)),
+
+ ?line {ok,BytesApp2} = asn1_wrapper:encode('Prim','IntApp',444),
+ ?line {ok,444} = asn1_wrapper:decode('Prim','IntApp',lists:flatten(BytesApp2)),
+
+ ?line {ok,BytesApp3} = asn1_wrapper:encode('Prim','IntApp',123456789),
+ ?line {ok,123456789} = asn1_wrapper:decode('Prim','IntApp',lists:flatten(BytesApp3)),
+
+ ?line {ok,BytesApp4} = asn1_wrapper:encode('Prim','IntApp',12345678901234567890),
+ ?line {ok,12345678901234567890} = asn1_wrapper:decode('Prim','IntApp',lists:flatten(BytesApp4)),
+
+ ?line {ok,BytesApp5} = asn1_wrapper:encode('Prim','IntApp',-100),
+ ?line {ok,-100} = asn1_wrapper:decode('Prim','IntApp',lists:flatten(BytesApp5)),
+
+ ?line {ok,BytesApp6} = asn1_wrapper:encode('Prim','IntApp',-255),
+ ?line {ok,-255} = asn1_wrapper:decode('Prim','IntApp',lists:flatten(BytesApp6)),
+
+ ?line {ok,BytesApp7} = asn1_wrapper:encode('Prim','IntApp',-256),
+ ?line {ok,-256} = asn1_wrapper:decode('Prim','IntApp',lists:flatten(BytesApp7)),
+
+ ?line {ok,BytesApp8} = asn1_wrapper:encode('Prim','IntApp',-257),
+ ?line {ok,-257} = asn1_wrapper:decode('Prim','IntApp',lists:flatten(BytesApp8)),
+
+ ?line {ok,BytesApp9} = asn1_wrapper:encode('Prim','IntApp',-1234567890),
+ ?line {ok,-1234567890} = asn1_wrapper:decode('Prim','IntApp',lists:flatten(BytesApp9)),
+
+ ?line {ok,BytesApp10} = asn1_wrapper:encode('Prim','Int',-2147483648),
+ ?line {ok,-2147483648} = asn1_wrapper:decode('Prim','Int',lists:flatten(BytesApp10)),
+
+
+ %%==========================================================
+ %% IntExpCon ::= [50] EXPLICIT INTEGER
+ %%==========================================================
+
+ ?line {ok,BytesExpCon1} = asn1_wrapper:encode('Prim','IntExpCon',4),
+ ?line {ok,4} = asn1_wrapper:decode('Prim','IntExpCon',lists:flatten(BytesExpCon1)),
+
+ ?line {ok,BytesExpCon2} = asn1_wrapper:encode('Prim','IntExpCon',444),
+ ?line {ok,444} = asn1_wrapper:decode('Prim','IntExpCon',lists:flatten(BytesExpCon2)),
+
+ ?line {ok,BytesExpCon3} = asn1_wrapper:encode('Prim','IntExpCon',123456789),
+ ?line {ok,123456789} = asn1_wrapper:decode('Prim','IntExpCon',lists:flatten(BytesExpCon3)),
+
+ ?line {ok,BytesExpCon4} = asn1_wrapper:encode('Prim','IntExpCon',12345678901234567890),
+ ?line {ok,12345678901234567890} = asn1_wrapper:decode('Prim','IntExpCon',lists:flatten(BytesExpCon4)),
+
+ ?line {ok,BytesExpCon5} = asn1_wrapper:encode('Prim','IntExpCon',-100),
+ ?line {ok,-100} = asn1_wrapper:decode('Prim','IntExpCon',lists:flatten(BytesExpCon5)),
+
+ ?line {ok,BytesExpCon6} = asn1_wrapper:encode('Prim','IntExpCon',-255),
+ ?line {ok,-255} = asn1_wrapper:decode('Prim','IntExpCon',lists:flatten(BytesExpCon6)),
+
+ ?line {ok,BytesExpCon7} = asn1_wrapper:encode('Prim','IntExpCon',-256),
+ ?line {ok,-256} = asn1_wrapper:decode('Prim','IntExpCon',lists:flatten(BytesExpCon7)),
+
+ ?line {ok,BytesExpCon8} = asn1_wrapper:encode('Prim','IntExpCon',-257),
+ ?line {ok,-257} = asn1_wrapper:decode('Prim','IntExpCon',lists:flatten(BytesExpCon8)),
+
+ ?line {ok,BytesExpCon9} = asn1_wrapper:encode('Prim','IntExpCon',-1234567890),
+ ?line {ok,-1234567890} = asn1_wrapper:decode('Prim','IntExpCon',lists:flatten(BytesExpCon9)),
+
+ ?line {ok,BytesExpCon10} = asn1_wrapper:encode('Prim','Int',-2147483648),
+ ?line {ok,-2147483648} = asn1_wrapper:decode('Prim','Int',lists:flatten(BytesExpCon10)),
+
+ %%==========================================================
+ %% IntExpPri ::= [PRIVATE 51] EXPLICIT INTEGER
+ %%==========================================================
+
+ ?line {ok,BytesExpPri1} = asn1_wrapper:encode('Prim','IntExpPri',4),
+ ?line {ok,4} = asn1_wrapper:decode('Prim','IntExpPri',lists:flatten(BytesExpPri1)),
+
+ ?line {ok,BytesExpPri2} = asn1_wrapper:encode('Prim','IntExpPri',444),
+ ?line {ok,444} = asn1_wrapper:decode('Prim','IntExpPri',lists:flatten(BytesExpPri2)),
+
+ ?line {ok,BytesExpPri3} = asn1_wrapper:encode('Prim','IntExpPri',123456789),
+ ?line {ok,123456789} = asn1_wrapper:decode('Prim','IntExpPri',lists:flatten(BytesExpPri3)),
+
+ ?line {ok,BytesExpPri4} = asn1_wrapper:encode('Prim','IntExpPri',12345678901234567890),
+ ?line {ok,12345678901234567890} = asn1_wrapper:decode('Prim','IntExpPri',lists:flatten(BytesExpPri4)),
+
+ ?line {ok,BytesExpPri5} = asn1_wrapper:encode('Prim','IntExpPri',-100),
+ ?line {ok,-100} = asn1_wrapper:decode('Prim','IntExpPri',lists:flatten(BytesExpPri5)),
+
+ ?line {ok,BytesExpPri6} = asn1_wrapper:encode('Prim','IntExpPri',-255),
+ ?line {ok,-255} = asn1_wrapper:decode('Prim','IntExpPri',lists:flatten(BytesExpPri6)),
+
+ ?line {ok,BytesExpPri7} = asn1_wrapper:encode('Prim','IntExpPri',-256),
+ ?line {ok,-256} = asn1_wrapper:decode('Prim','IntExpPri',lists:flatten(BytesExpPri7)),
+
+ ?line {ok,BytesExpPri8} = asn1_wrapper:encode('Prim','IntExpPri',-257),
+ ?line {ok,-257} = asn1_wrapper:decode('Prim','IntExpPri',lists:flatten(BytesExpPri8)),
+
+ ?line {ok,BytesExpPri9} = asn1_wrapper:encode('Prim','IntExpPri',-1234567890),
+ ?line {ok,-1234567890} = asn1_wrapper:decode('Prim','IntExpPri',lists:flatten(BytesExpPri9)),
+
+ ?line {ok,BytesExpPri10} = asn1_wrapper:encode('Prim','Int',-2147483648),
+ ?line {ok,-2147483648} = asn1_wrapper:decode('Prim','Int',lists:flatten(BytesExpPri10)),
+
+ %%==========================================================
+ %% IntExpApp ::= [APPLICATION 52] EXPLICIT INTEGER
+ %%==========================================================
+
+ ?line {ok,BytesExpApp1} = asn1_wrapper:encode('Prim','IntExpApp',4),
+ ?line {ok,4} = asn1_wrapper:decode('Prim','IntExpApp',lists:flatten(BytesExpApp1)),
+
+ ?line {ok,BytesExpApp2} = asn1_wrapper:encode('Prim','IntExpApp',444),
+ ?line {ok,444} = asn1_wrapper:decode('Prim','IntExpApp',lists:flatten(BytesExpApp2)),
+
+ ?line {ok,BytesExpApp3} = asn1_wrapper:encode('Prim','IntExpApp',123456789),
+ ?line {ok,123456789} = asn1_wrapper:decode('Prim','IntExpApp',lists:flatten(BytesExpApp3)),
+
+ ?line {ok,BytesExpApp4} = asn1_wrapper:encode('Prim','IntExpApp',12345678901234567890),
+ ?line {ok,12345678901234567890} = asn1_wrapper:decode('Prim','IntExpApp',lists:flatten(BytesExpApp4)),
+
+ ?line {ok,BytesExpApp5} = asn1_wrapper:encode('Prim','IntExpApp',-100),
+ ?line {ok,-100} = asn1_wrapper:decode('Prim','IntExpApp',lists:flatten(BytesExpApp5)),
+
+ ?line {ok,BytesExpApp6} = asn1_wrapper:encode('Prim','IntExpApp',-255),
+ ?line {ok,-255} = asn1_wrapper:decode('Prim','IntExpApp',lists:flatten(BytesExpApp6)),
+
+ ?line {ok,BytesExpApp7} = asn1_wrapper:encode('Prim','IntExpApp',-256),
+ ?line {ok,-256} = asn1_wrapper:decode('Prim','IntExpApp',lists:flatten(BytesExpApp7)),
+
+ ?line {ok,BytesExpApp8} = asn1_wrapper:encode('Prim','IntExpApp',-257),
+ ?line {ok,-257} = asn1_wrapper:decode('Prim','IntExpApp',lists:flatten(BytesExpApp8)),
+
+ ?line {ok,BytesExpApp9} = asn1_wrapper:encode('Prim','IntExpApp',-1234567890),
+ ?line {ok,-1234567890} = asn1_wrapper:decode('Prim','IntExpApp',lists:flatten(BytesExpApp9)),
+
+ ?line {ok,BytesExpApp10} = asn1_wrapper:encode('Prim','Int',-2147483648),
+ ?line {ok,-2147483648} = asn1_wrapper:decode('Prim','Int',lists:flatten(BytesExpApp10)),
+
+
+ %%==========================================================
+ %% IntEnum ::= INTEGER {first(1),last(31)}
+ %%==========================================================
+
+ ?line {ok,BytesEnum1} = asn1_wrapper:encode('Prim','IntEnum',4),
+ ?line {ok,4} = asn1_wrapper:decode('Prim','IntEnum',lists:flatten(BytesEnum1)),
+
+ ?line {ok,BytesEnum2} = asn1_wrapper:encode('Prim','IntEnum',444),
+ ?line {ok,444} = asn1_wrapper:decode('Prim','IntEnum',lists:flatten(BytesEnum2)),
+
+ ?line {ok,BytesEnum3} = asn1_wrapper:encode('Prim','IntEnum',123456789),
+ ?line {ok,123456789} = asn1_wrapper:decode('Prim','IntEnum',lists:flatten(BytesEnum3)),
+
+ ?line {ok,BytesEnum4} = asn1_wrapper:encode('Prim','IntEnum',12345678901234567890),
+ ?line {ok,12345678901234567890} = asn1_wrapper:decode('Prim','IntEnum',lists:flatten(BytesEnum4)),
+
+ ?line {ok,BytesEnum5} = asn1_wrapper:encode('Prim','IntEnum',-100),
+ ?line {ok,-100} = asn1_wrapper:decode('Prim','IntEnum',lists:flatten(BytesEnum5)),
+
+ ?line {ok,BytesEnum6} = asn1_wrapper:encode('Prim','IntEnum',-255),
+ ?line {ok,-255} = asn1_wrapper:decode('Prim','IntEnum',lists:flatten(BytesEnum6)),
+
+ ?line {ok,BytesEnum7} = asn1_wrapper:encode('Prim','IntEnum',-256),
+ ?line {ok,-256} = asn1_wrapper:decode('Prim','IntEnum',lists:flatten(BytesEnum7)),
+
+ ?line {ok,BytesEnum8} = asn1_wrapper:encode('Prim','IntEnum',-257),
+ ?line {ok,-257} = asn1_wrapper:decode('Prim','IntEnum',lists:flatten(BytesEnum8)),
+
+ ?line {ok,BytesEnum9} = asn1_wrapper:encode('Prim','IntEnum',-1234567890),
+ ?line {ok,-1234567890} = asn1_wrapper:decode('Prim','IntEnum',lists:flatten(BytesEnum9)),
+
+ ?line {ok,BytesEnum910} = asn1_wrapper:encode('Prim','Int',-2147483648),
+ ?line {ok,-2147483648} = asn1_wrapper:decode('Prim','Int',lists:flatten(BytesEnum910)),
+
+
+ ?line {ok,BytesEnum10} = asn1_wrapper:encode('Prim','IntEnum',first),
+ ?line {ok,first} = asn1_wrapper:decode('Prim','IntEnum',lists:flatten(BytesEnum10)),
+
+ ?line {ok,BytesEnum11} = asn1_wrapper:encode('Prim','IntEnum',last),
+ ?line {ok,last} = asn1_wrapper:decode('Prim','IntEnum',lists:flatten(BytesEnum11)),
+
+
+
+ ok.
+
+
+
+enum(Rules) ->
+
+ %%==========================================================
+ %% Enum ::= ENUMERATED {monday(1),tuesday(2),wednesday(3),thursday(4),
+ %% friday(5),saturday(6),sunday(7)}
+ %%==========================================================
+
+ ?line {ok,BytesEnum1} = asn1_wrapper:encode('Prim','Enum',monday),
+ ?line {ok,monday} = asn1_wrapper:decode('Prim','Enum',lists:flatten(BytesEnum1)),
+
+ ?line {ok,BytesEnum2} = asn1_wrapper:encode('Prim','Enum',thursday),
+ ?line {ok,thursday} = asn1_wrapper:decode('Prim','Enum',lists:flatten(BytesEnum2)),
+
+
+ ?line case asn1_wrapper:erule(Rules) of
+ ber ->
+ ?line {error,{asn1,{_,4}}} =
+ case catch asn1_wrapper:encode('Prim','Enum',4) of Enum -> Enum end,
+ ok;
+ per ->
+ ?line {error,{asn1,{_,4}}} =
+ case catch asn1_wrapper:encode('Prim','Enum',4) of Enum -> Enum end,
+ ok
+ end,
+ ok.
+
+
+
+obj_id(Rules) ->
+
+ %%==========================================================
+ %% ObjId ::= OBJECT IDENTIFIER
+ %%==========================================================
+
+ ?line {ok,Bytes1} = asn1_wrapper:encode('Prim','ObjId',{0,22,3}),
+ ?line {ok,{0,22,3}} = asn1_wrapper:decode('Prim','ObjId',lists:flatten(Bytes1)),
+
+ ?line {ok,Bytes2} = asn1_wrapper:encode('Prim','ObjId',{1,39,3}),
+ ?line {ok,{1,39,3}} = asn1_wrapper:decode('Prim','ObjId',lists:flatten(Bytes2)),
+
+ ?line {ok,Bytes3} = asn1_wrapper:encode('Prim','ObjId',{2,100,3}),
+ ?line {ok,{2,100,3}} = asn1_wrapper:decode('Prim','ObjId',lists:flatten(Bytes3)),
+
+ ?line {ok,Bytes4} = asn1_wrapper:encode('Prim','ObjId',{2,16303,3}),
+ ?line {ok,{2,16303,3}} = asn1_wrapper:decode('Prim','ObjId',lists:flatten(Bytes4)),
+
+ ?line case asn1_wrapper:erule(Rules) of
+ ber ->
+ ?line {ok,Bytes5} = asn1_wrapper:encode('Prim','ObjId',{2,16304,3}),
+ ?line {ok,{2,16304,3}} = asn1_wrapper:decode('Prim','ObjId',lists:flatten(Bytes5)),
+ ok;
+ per ->
+ ?line {ok,Bytes5} = asn1_wrapper:encode('Prim','ObjId',{2,16304,3}),
+ ?line {ok,{2,16304,3}} = asn1_wrapper:decode('Prim','ObjId',lists:flatten(Bytes5)),
+%% ?line test_server:format("~p~n",[Kurt]),
+% ?line {ok,{2,16304,3}} = asn1_wrapper:decode('Prim','ObjId',lists:flatten(Bytes5)),
+ ok
+ end,
+
+
+
+ ok.
+
+rel_oid(_Rules) ->
+
+ %%==========================================================
+ %% RelOid ::= RELATIVE-OID
+ %%==========================================================
+
+ ?line {ok,Bytes1} = asn1_wrapper:encode('Prim','RelOid',{0,22,3}),
+ ?line {ok,{0,22,3}} = asn1_wrapper:decode('Prim','RelOid',lists:flatten(Bytes1)),
+
+ ?line {ok,Bytes2} = asn1_wrapper:encode('Prim','RelOid',{1,39,3}),
+ ?line {ok,{1,39,3}} = asn1_wrapper:decode('Prim','RelOid',lists:flatten(Bytes2)),
+
+ ?line {ok,Bytes3} = asn1_wrapper:encode('Prim','RelOid',{2,100,3}),
+ ?line {ok,{2,100,3}} = asn1_wrapper:decode('Prim','RelOid',lists:flatten(Bytes3)),
+
+ ?line {ok,Bytes4} = asn1_wrapper:encode('Prim','RelOid',{2,16303,3}),
+ ?line {ok,{2,16303,3}} = asn1_wrapper:decode('Prim','RelOid',lists:flatten(Bytes4)),
+
+ ?line {ok,Bytes5} = asn1_wrapper:encode('Prim','RelOid',{2,16304,3}),
+ ?line {ok,{2,16304,3}} = asn1_wrapper:decode('Prim','RelOid',lists:flatten(Bytes5)),
+
+ ?line {ok,Bytes6} = asn1_wrapper:encode('Prim','RelOid',{8,16304,16#ffff}),
+ ?line {ok,{8,16304,16#ffff}} = asn1_wrapper:decode('Prim','RelOid',lists:flatten(Bytes6)),
+
+
+
+ ok.
+
+
+
+
+
+null(_Rules) ->
+
+ %%==========================================================
+ %% Null ::= NULL
+ %%==========================================================
+
+ ?line {ok,Bytes1} = asn1_wrapper:encode('Prim','Null',monday),
+ ?line {ok,'NULL'} = asn1_wrapper:decode('Prim','Null',lists:flatten(Bytes1)),
+
+
+
+ok.
+
+
+
+real(_Rules) ->
+ %%==========================================================
+ %% AngleInRadians ::= REAL
+ %%==========================================================
+
+ %% Base 2
+ ?line {ok,Bytes1} = asn1_wrapper:encode('Real','AngleInRadians',{1,2,1}),
+ ?line {ok,{1,2,1}} = asn1_wrapper:decode('Real','AngleInRadians',Bytes1),
+
+ ?line {ok,Bytes2} = asn1_wrapper:encode('Real','AngleInRadians',{129,2,1}),
+ ?line {ok,{129,2,1}} = asn1_wrapper:decode('Real','AngleInRadians',Bytes2),
+
+ ?line {ok,Bytes3} = asn1_wrapper:encode('Real','AngleInRadians',{128,2,1}),
+ ?line {ok,{1,2,8}} = asn1_wrapper:decode('Real','AngleInRadians',Bytes3),
+
+ ?line {ok,Bytes4} = asn1_wrapper:encode('Real','AngleInRadians',{128,2,-7}),
+ ?line {ok,{1,2,0}} = asn1_wrapper:decode('Real','AngleInRadians',Bytes4),
+
+ ?line {ok,Bytes5} = asn1_wrapper:encode('Real','AngleInRadians',{16#f1f1f1,2,128}),
+ ?line {ok,{16#f1f1f1,2,128}} = asn1_wrapper:decode('Real','AngleInRadians',Bytes5),
+
+ %% Base 10, tuple format
+ ?line {ok,Bytes6} = asn1_wrapper:encode('Real','AngleInRadians',{1,10,1}),
+ ?line {ok,"1.E1"} = asn1_wrapper:decode('Real','AngleInRadians',Bytes6),
+
+ ?line {ok,Bytes7} = asn1_wrapper:encode('Real','AngleInRadians',{100,10,1}),
+ ?line {ok,"1.E3"} = asn1_wrapper:decode('Real','AngleInRadians',Bytes7),
+
+ ?line {ok,Bytes8} = asn1_wrapper:encode('Real','AngleInRadians',{-100,10,1}),
+ ?line {ok,"-1.E3"} = asn1_wrapper:decode('Real','AngleInRadians',Bytes8),
+
+ ?line {ok,Bytes9} = asn1_wrapper:encode('Real','AngleInRadians',{00002,10,1}),
+ ?line {ok,"2.E1"} = asn1_wrapper:decode('Real','AngleInRadians',Bytes9),
+
+ ?line {ok,Bytes10} = asn1_wrapper:encode('Real','AngleInRadians',{123000,10,0}),
+ ?line {ok,"123.E3"} = asn1_wrapper:decode('Real','AngleInRadians',Bytes10),
+
+ ?line {ok,Bytes11} = asn1_wrapper:encode('Real','AngleInRadians',{123456789,10,123456789}),
+ ?line {ok,"123456789.E123456789"} = asn1_wrapper:decode('Real','AngleInRadians',Bytes11),
+
+ ?line {ok,Bytes12} = asn1_wrapper:encode('Real','AngleInRadians',{-12345,10,-12345}),
+ ?line {ok,"-12345.E-12345"} = asn1_wrapper:decode('Real','AngleInRadians',Bytes12),
+
+ %% Base 10, string format NR3
+
+ ?line {ok,Bytes13} = asn1_wrapper:encode('Real','AngleInRadians',"123.123E123"),
+ ?line {ok,"123123.E120"} = asn1_wrapper:decode('Real','AngleInRadians',Bytes13),
+
+ ?line {ok,Bytes14} = asn1_wrapper:encode('Real','AngleInRadians',"0.0E0"),
+ ?line {ok,"0.E+0"} = asn1_wrapper:decode('Real','AngleInRadians',Bytes14),
+
+ ?line {ok,Bytes15} = asn1_wrapper:encode('Real','AngleInRadians',"0.0123"),
+ ?line {ok,"123.E-4"} = asn1_wrapper:decode('Real','AngleInRadians',Bytes15),
+
+ ?line {ok,Bytes16} = asn1_wrapper:encode('Real','AngleInRadians',"0"),
+ ?line {ok,"0.E+0"} = asn1_wrapper:decode('Real','AngleInRadians',Bytes16),
+
+ ?line {ok,Bytes17} = asn1_wrapper:encode('Real','AngleInRadians',"-123.45"),
+ ?line {ok,"-12345.E-2"} = asn1_wrapper:decode('Real','AngleInRadians',Bytes17),
+
+ ?line {ok,Bytes18} =
+ asn1_wrapper:encode('Real','AngleInRadians',"123456789E123456789"),
+ ?line {ok,"123456789.E123456789"} =
+ asn1_wrapper:decode('Real','AngleInRadians',Bytes18),
+
+ ?line {ok,Bytes19} = asn1_wrapper:encode('Real','AngleInRadians',"01.000E1"),
+ ?line {ok,"1.E1"} = asn1_wrapper:decode('Real','AngleInRadians',Bytes19),
+
+ ?line {ok,Bytes20} = asn1_wrapper:encode('Real','AngleInRadians',"120.0001"),
+ ?line {ok,"1200001.E-4"} = asn1_wrapper:decode('Real','AngleInRadians',Bytes20).
diff --git a/lib/asn1/test/testPrimExternal.erl b/lib/asn1/test/testPrimExternal.erl
new file mode 100644
index 0000000000..2a6384009a
--- /dev/null
+++ b/lib/asn1/test/testPrimExternal.erl
@@ -0,0 +1,118 @@
+%%
+%% %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(testPrimExternal).
+
+-export([compile/3]).
+-export([external/1]).
+
+-include("test_server.hrl").
+
+
+compile(Config,Rules,Options) ->
+
+ ?line DataDir = ?config(data_dir,Config),
+ ?line OutDir = ?config(priv_dir,Config),
+ ?line true = code:add_patha(?config(priv_dir,Config)),
+ ?line ok = asn1ct:compile(DataDir ++ "PrimExternal",[Rules,{outdir,OutDir}]++Options).
+
+
+
+external(_Rules) ->
+
+
+ ?line {ok,Bytes10} = asn1_wrapper:encode('PrimExternal','NT',"kalle"),
+ ?line {ok,"kalle"} = asn1_wrapper:decode('PrimExternal','NT',lists:flatten(Bytes10)),
+
+ ?line {ok,Bytes11} = asn1_wrapper:encode('PrimExternal','Imp',"kalle"),
+ ?line {ok,"kalle"} = asn1_wrapper:decode('PrimExternal','Imp',lists:flatten(Bytes11)),
+
+ ?line {ok,Bytes12} = asn1_wrapper:encode('PrimExternal','Exp',"kalle"),
+ ?line {ok,"kalle"} = asn1_wrapper:decode('PrimExternal','Exp',lists:flatten(Bytes12)),
+
+
+ ?line {ok,Bytes13} = asn1_wrapper:encode('PrimExternal','NTNT',"kalle"),
+ ?line {ok,"kalle"} = asn1_wrapper:decode('PrimExternal','NTNT',lists:flatten(Bytes13)),
+
+ ?line {ok,Bytes14} = asn1_wrapper:encode('PrimExternal','NTImp',"kalle"),
+ ?line {ok,"kalle"} = asn1_wrapper:decode('PrimExternal','NTImp',lists:flatten(Bytes14)),
+
+ ?line {ok,Bytes15} = asn1_wrapper:encode('PrimExternal','NTExp',"kalle"),
+ ?line {ok,"kalle"} = asn1_wrapper:decode('PrimExternal','NTExp',lists:flatten(Bytes15)),
+
+
+ ?line {ok,Bytes16} = asn1_wrapper:encode('PrimExternal','ImpNT',"kalle"),
+ ?line {ok,"kalle"} = asn1_wrapper:decode('PrimExternal','ImpNT',lists:flatten(Bytes16)),
+
+ ?line {ok,Bytes17} = asn1_wrapper:encode('PrimExternal','ImpImp',"kalle"),
+ ?line {ok,"kalle"} = asn1_wrapper:decode('PrimExternal','ImpImp',lists:flatten(Bytes17)),
+
+ ?line {ok,Bytes18} = asn1_wrapper:encode('PrimExternal','ImpExp',"kalle"),
+ ?line {ok,"kalle"} = asn1_wrapper:decode('PrimExternal','ImpExp',lists:flatten(Bytes18)),
+
+
+ ?line {ok,Bytes19} = asn1_wrapper:encode('PrimExternal','ExpNT',"kalle"),
+ ?line {ok,"kalle"} = asn1_wrapper:decode('PrimExternal','ExpNT',lists:flatten(Bytes19)),
+
+ ?line {ok,Bytes20} = asn1_wrapper:encode('PrimExternal','ExpImp',"kalle"),
+ ?line {ok,"kalle"} = asn1_wrapper:decode('PrimExternal','ExpImp',lists:flatten(Bytes20)),
+
+ ?line {ok,Bytes21} = asn1_wrapper:encode('PrimExternal','ExpExp',"kalle"),
+ ?line {ok,"kalle"} = asn1_wrapper:decode('PrimExternal','ExpExp',lists:flatten(Bytes21)),
+
+
+
+
+
+ ?line {ok,Bytes31} = asn1_wrapper:encode('PrimExternal','XNTNT',"kalle"),
+ ?line {ok,"kalle"} = asn1_wrapper:decode('PrimExternal','XNTNT',lists:flatten(Bytes31)),
+
+ ?line {ok,Bytes32} = asn1_wrapper:encode('PrimExternal','XNTImp',"kalle"),
+ ?line {ok,"kalle"} = asn1_wrapper:decode('PrimExternal','XNTImp',lists:flatten(Bytes32)),
+
+ ?line {ok,Bytes33} = asn1_wrapper:encode('PrimExternal','XNTExp',"kalle"),
+ ?line {ok,"kalle"} = asn1_wrapper:decode('PrimExternal','XNTExp',lists:flatten(Bytes33)),
+
+
+ ?line {ok,Bytes34} = asn1_wrapper:encode('PrimExternal','XImpNT',"kalle"),
+ ?line {ok,"kalle"} = asn1_wrapper:decode('PrimExternal','XImpNT',lists:flatten(Bytes34)),
+
+ ?line {ok,Bytes35} = asn1_wrapper:encode('PrimExternal','XImpImp',"kalle"),
+ ?line {ok,"kalle"} = asn1_wrapper:decode('PrimExternal','XImpImp',lists:flatten(Bytes35)),
+
+ ?line {ok,Bytes36} = asn1_wrapper:encode('PrimExternal','XImpExp',"kalle"),
+ ?line {ok,"kalle"} = asn1_wrapper:decode('PrimExternal','XImpExp',lists:flatten(Bytes36)),
+
+
+ ?line {ok,Bytes37} = asn1_wrapper:encode('PrimExternal','XExpNT',"kalle"),
+ ?line {ok,"kalle"} = asn1_wrapper:decode('PrimExternal','XExpNT',lists:flatten(Bytes37)),
+
+ ?line {ok,Bytes38} = asn1_wrapper:encode('PrimExternal','XExpImp',"kalle"),
+ ?line {ok,"kalle"} = asn1_wrapper:decode('PrimExternal','XExpImp',lists:flatten(Bytes38)),
+
+ ?line {ok,Bytes39} = asn1_wrapper:encode('PrimExternal','XExpExp',"kalle"),
+ ?line {ok,"kalle"} = asn1_wrapper:decode('PrimExternal','XExpExp',lists:flatten(Bytes39)),
+
+
+
+
+
+
+
+ok.
diff --git a/lib/asn1/test/testPrimStrings.erl b/lib/asn1/test/testPrimStrings.erl
new file mode 100644
index 0000000000..a2252ba99b
--- /dev/null
+++ b/lib/asn1/test/testPrimStrings.erl
@@ -0,0 +1,936 @@
+%%
+%% %CopyrightBegin%
+%%
+%% 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(testPrimStrings).
+
+-export([compile/3]).
+-export([bit_string/1]).
+-export([bit_string_unnamed/1]).
+-export([octet_string/1]).
+-export([numeric_string/1]).
+-export([other_strings/1]).
+-export([more_strings/1]).
+-export([universal_string/1]).
+-export([bmp_string/1]).
+-export([times/1]).
+-export([utf8_string/1]).
+
+-include("test_server.hrl").
+
+
+compile(Config,Rules,Option) ->
+
+ ?line DataDir = ?config(data_dir,Config),
+ ?line OutDir = ?config(priv_dir,Config),
+ ?line true = code:add_patha(?config(priv_dir,Config)),
+ ?line ok = asn1ct:compile(DataDir ++ "PrimStrings",
+ [Rules,{outdir,OutDir}]++Option),
+ ?line {ok,IO} = file:open(test_config,write),
+ io:format(IO,"~p.~n",[Config]),
+ file:close(IO),
+ ?line ok = asn1ct:compile(DataDir ++ "BitStr",
+ [Rules, {outdir,OutDir}]++Option).
+
+
+
+bit_string(Rules) ->
+
+ %%==========================================================
+ %% Bs1 ::= BIT STRING
+ %%==========================================================
+
+ ?line {ok,Bytes1} = asn1_wrapper:encode('PrimStrings','Bs1',0),
+ ?line {ok,[]} = asn1_wrapper:decode('PrimStrings','Bs1',lists:flatten(Bytes1)),
+
+ ?line {ok,Bytes2} = asn1_wrapper:encode('PrimStrings','Bs1',4),
+ ?line {ok,[0,0,1]} = asn1_wrapper:decode('PrimStrings','Bs1',lists:flatten(Bytes2)),
+
+ ?line {ok,Bytes3} = asn1_wrapper:encode('PrimStrings','Bs1',15),
+ ?line {ok,[1,1,1,1]} = asn1_wrapper:decode('PrimStrings','Bs1',lists:flatten(Bytes3)),
+
+ ?line {ok,Bytes4} = asn1_wrapper:encode('PrimStrings','Bs1',255),
+ ?line {ok,[1,1,1,1,1,1,1,1]} = asn1_wrapper:decode('PrimStrings','Bs1',lists:flatten(Bytes4)),
+
+ ?line {ok,Bytes5} = asn1_wrapper:encode('PrimStrings','Bs1',256),
+ ?line {ok,[0,0,0,0,0,0,0,0,1]} = asn1_wrapper:decode('PrimStrings','Bs1',lists:flatten(Bytes5)),
+
+ ?line {ok,Bytes6} = asn1_wrapper:encode('PrimStrings','Bs1',257),
+ ?line {ok,[1,0,0,0,0,0,0,0,1]} = asn1_wrapper:decode('PrimStrings','Bs1',lists:flatten(Bytes6)),
+
+ ?line {ok,Bytes7} = asn1_wrapper:encode('PrimStrings','Bs1',444),
+ ?line {ok,[0,0,1,1,1,1,0,1,1]} = asn1_wrapper:decode('PrimStrings','Bs1',lists:flatten(Bytes7)),
+
+ ?line {ok,Bytes8} = asn1_wrapper:encode('PrimStrings','Bs1',12345678901234567890),
+ ?line {ok,_} = asn1_wrapper:decode('PrimStrings','Bs1',lists:flatten(Bytes8)),
+
+%% Removed due to beam cannot handle this big integers
+%% Bs1_1 = 123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890,
+%% ?line {ok,Bytes9} = asn1_wrapper:encode('PrimStrings','Bs1',Bs1_1),
+%% ?line {ok,_} = asn1_wrapper:decode('PrimStrings','Bs1',lists:flatten(Bytes9)),
+
+%% Bs1_2 = 12345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890,
+%% ?line {ok,Bytes10} = asn1_wrapper:encode('PrimStrings','Bs1',Bs1_2),
+%% ?line {ok,_} = asn1_wrapper:decode('PrimStrings','Bs1',lists:flatten(Bytes10)),
+
+ ?line {ok,Bytes11} = asn1_wrapper:encode('PrimStrings','Bs1',[1,1,1,1,1,1,1,1]),
+ ?line {ok,[1,1,1,1,1,1,1,1]} = asn1_wrapper:decode('PrimStrings','Bs1',lists:flatten(Bytes11)),
+
+ ?line case asn1_wrapper:erule(Rules) of
+ ber ->
+ ?line {ok,Bytes12} = asn1_wrapper:encode('PrimStrings','Bs1',[0,1,0,0,1,0]),
+ ?line {ok,[0,1,0,0,1,0]} =
+ asn1_wrapper:decode('PrimStrings','Bs1',lists:flatten(Bytes12)),
+
+ ?line {ok,Bytes13} = asn1_wrapper:encode('PrimStrings','Bs1',[1,0,0,0,0,0,0,0,0]),
+ ?line {ok,[1,0,0,0,0,0,0,0,0]} =
+ asn1_wrapper:decode('PrimStrings','Bs1',lists:flatten(Bytes13)),
+ ok;
+ per ->
+ ?line {ok,Bytes12} = asn1_wrapper:encode('PrimStrings','Bs1',[0,1,0,0,1,0]),
+ ?line {ok,[0,1,0,0,1,0]} =
+ asn1_wrapper:decode('PrimStrings','Bs1',lists:flatten(Bytes12)),
+
+ ?line {ok,Bytes13} = asn1_wrapper:encode('PrimStrings','Bs1',[1,0,0,0,0,0,0,0,0]),
+ ?line {ok,[1,0,0,0,0,0,0,0,0]} =
+ asn1_wrapper:decode('PrimStrings','Bs1',lists:flatten(Bytes13)),
+ ok
+ end,
+
+ ?line {ok,Bytes14} =
+ asn1_wrapper:encode('PrimStrings','Bs1',[0,1,0,0,1,0,1,1,1,1,1,0,0,0,1,0,0,1,1]),
+ ?line {ok,[0,1,0,0,1,0,1,1,1,1,1,0,0,0,1,0,0,1,1]} =
+ asn1_wrapper:decode('PrimStrings','Bs1',lists:flatten(Bytes14)),
+
+
+ ?line case asn1_wrapper:erule(Rules) of
+ ber ->
+ ?line Bytes15 = [35,8,3,2,0,73,3,2,4,32],
+ ?line {ok,[0,1,0,0,1,0,0,1,0,0,1,0]} =
+ asn1_wrapper:decode('PrimStrings','Bs1',lists:flatten(Bytes15)),
+
+ ?line Bytes16 = [35,9,3,2,0,234,3,3,7,156,0],
+ ?line {ok,[1,1,1,0,1,0,1,0,1,0,0,1,1,1,0,0,0]} =
+ asn1_wrapper:decode('PrimStrings','Bs1',lists:flatten(Bytes16)),
+
+ ?line Bytes17 = [35,128,3,2,0,73,3,2,4,32,0,0],
+ ?line {ok,[0,1,0,0,1,0,0,1,0,0,1,0]} =
+ asn1_wrapper:decode('PrimStrings','Bs1',lists:flatten(Bytes17)),
+
+ ?line Bytes18 = [35,128,3,2,0,234,3,3,7,156,0,0,0],
+ ?line {ok,[1,1,1,0,1,0,1,0,1,0,0,1,1,1,0,0,0]} =
+ asn1_wrapper:decode('PrimStrings','Bs1',lists:flatten(Bytes18)),
+ ok;
+
+ per ->
+ ok
+ end,
+
+
+
+ %%==========================================================
+ %% Bs2 ::= BIT STRING {su(0), mo(1), tu(2), we(3), th(4), fr(5), sa(6) } (SIZE (7))
+ %%==========================================================
+
+ ?line {ok,Bytes21} = asn1_wrapper:encode('PrimStrings','Bs2',[mo,tu,fr]),
+ ?line {ok,[mo,tu,fr]} = asn1_wrapper:decode('PrimStrings','Bs2',lists:flatten(Bytes21)),
+
+ ?line {ok,Bytes22} = asn1_wrapper:encode('PrimStrings','Bs2',[0,1,1,0,0,1,0]),
+ ?line {ok,[mo,tu,fr]} = asn1_wrapper:decode('PrimStrings','Bs2',lists:flatten(Bytes22)),
+ ok,
+%% skip this because it is wrong
+% ?line case asn1_wrapper:erule(Rules) of
+% ber ->
+% ?line {ok,[mo,tu,fr,su,mo,th]} =
+% asn1_wrapper:decode('PrimStrings','Bs2',[35,8,3,2,0,101,3,2,2,200]),
+
+% ?line {ok,[mo,tu,fr,su,mo,th]} =
+% asn1_wrapper:decode('PrimStrings','Bs2',[35,128,3,2,1,100,3,2,2,200,0,0]),
+% ok;
+
+% per ->
+% ok
+% end,
+
+
+
+ %%==========================================================
+ %% Bs3 ::= BIT STRING {su(0), mo(1), tu(2), we(3), th(4), fr(5), sa(6) } (SIZE (1..7))
+ %%==========================================================
+
+ ?line {ok,Bytes31} = asn1_wrapper:encode('PrimStrings','Bs3',[mo,tu,fr]),
+ ?line {ok,[mo,tu,fr]} = asn1_wrapper:decode('PrimStrings','Bs3',lists:flatten(Bytes31)),
+
+ ?line {ok,Bytes32} = asn1_wrapper:encode('PrimStrings','Bs3',[0,1,1,0,0,1,0]),
+ ?line {ok,[mo,tu,fr]} = asn1_wrapper:decode('PrimStrings','Bs3',lists:flatten(Bytes32)),
+
+
+ %%==========================================================
+ %% Bs7 ::= BIT STRING (SIZE (24))
+ %%==========================================================
+
+ ?line {ok,Bytes33} = asn1_wrapper:encode('PrimStrings','Bs7',53245),
+ ?line {ok,[1,0,1,1,1,1,1,1,1,1,1,1,0,0,1,1,0,0,0,0,0,0,0,0]} =
+ asn1_wrapper:decode('PrimStrings','Bs7',Bytes33),
+
+ ?line {ok,Bytes34} = asn1_wrapper:encode('PrimStrings','Bs7',[1,0,1,0]),
+ ?line {ok,[1,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]} =
+ asn1_wrapper:decode('PrimStrings','Bs7',Bytes34),
+
+ %%==========================================================
+ %% BsPri ::= [PRIVATE 61] BIT STRING
+ %%==========================================================
+
+ ?line {ok,Bytes41} = asn1_wrapper:encode('PrimStrings','BsPri',45),
+ ?line {ok,[1,0,1,1,0,1]} = asn1_wrapper:decode('PrimStrings','BsPri',lists:flatten(Bytes41)),
+
+ ?line {ok,Bytes42} = asn1_wrapper:encode('PrimStrings','BsPri',211),
+ ?line {ok,[1,1,0,0,1,0,1,1]} = asn1_wrapper:decode('PrimStrings','BsPri',lists:flatten(Bytes42)),
+
+ ?line case asn1_wrapper:erule(Rules) of
+ ber ->
+ ?line {ok,[0,1,0,0,1,0,1,1,1,1,1,0,0,0,1,0,0,1,1]} =
+ asn1_wrapper:decode('PrimStrings','BsPri',[223,61,4,5,75,226,96]),
+
+ ?line {ok,[0,1,0,0,1,0,1,1,1,1,1,0,0,0,1,0,0,1,1]} =
+ asn1_wrapper:decode('PrimStrings','BsPri',[255,61,128,3,4,5,75,226,96,0,0]),
+
+ ?line {ok,[0,1,0,0,1,0,1,1,1,1,1,0,0,0,1,0,0,1,1]} =
+ asn1_wrapper:decode('PrimStrings','BsPri',[255,61,9,3,2,0,75,3,3,5,226,96]),
+
+ ?line {ok,[0,1,0,0,1,0,1,1,1,1,1,0,0,0,1,0,0,1,1]} =
+ asn1_wrapper:decode('PrimStrings','BsPri',[255,61,128,3,2,0,75,3,3,5,226,96,0,0]),
+ ok;
+
+ per ->
+ ok
+ end,
+
+
+
+ %%==========================================================
+ %% BsExpPri ::= [PRIVATE 61] EXPLICIT BIT STRING
+ %%==========================================================
+
+ ?line {ok,Bytes51} = asn1_wrapper:encode('PrimStrings','BsExpPri',45),
+ ?line {ok,[1,0,1,1,0,1]} =
+ asn1_wrapper:decode('PrimStrings','BsExpPri',lists:flatten(Bytes51)),
+
+ ?line {ok,Bytes52} = asn1_wrapper:encode('PrimStrings','BsExpPri',211),
+ ?line {ok,[1,1,0,0,1,0,1,1]} =
+ asn1_wrapper:decode('PrimStrings','BsExpPri',lists:flatten(Bytes52)),
+
+ ?line case asn1_wrapper:erule(Rules) of
+ ber ->
+ ?line {ok,[0,1,0,0,1,0,1,1,1,1,1,0,0,0,1,0,0,1,1]} =
+ asn1_wrapper:decode('PrimStrings','BsExpPri',[255,61,6,3,4,5,75,226,96]),
+ ok;
+
+ per ->
+ ok
+ end,
+
+ %%==========================================================
+ %% TestS ::= BIT STRING {a(0),b(1)} (SIZE (3..8)), test case for OTP-4353
+ %%==========================================================
+
+ ?line {ok,Bytes53} = asn1_wrapper:encode('PrimStrings','TestS',[a]),
+ ?line {ok,[a]} =
+ asn1_wrapper:decode('PrimStrings','TestS',lists:flatten(Bytes53)),
+
+ %%==========================================================
+ %% PersonalStatus ::= BIT STRING {married(0),employed(1),
+ %% veteran(2), collegeGraduate(3)}, test case for OTP-5710
+ %%==========================================================
+
+ ?line {ok,Bytes54} = asn1_wrapper:encode('BitStr','PersonalStatus',[]),
+ ?line {ok,[]} = asn1_wrapper:decode('BitStr','PersonalStatus',Bytes54),
+
+ %%==========================================================
+ %% BS5932 ::= BIT STRING (SIZE (5..MAX))
+ %% test case for OTP-5932
+ %%==========================================================
+ case asn1_wrapper:erule(Rules) of
+ ber ->
+ ?line {error,_} = asn1_wrapper:encode('PrimStrings','BSMAX',
+ [1,0,1]),
+ ?line {ok,Bytes55} =
+ asn1_wrapper:encode('PrimStrings','BSMAX',[1,0,1,0,1]),
+ ?line {ok,[1,0,1,0,1]} =
+ asn1_wrapper:decode('PrimStrings','BSMAX',Bytes55);
+ _ ->
+ ok
+ end,
+
+ %%==========================================================
+ %% BS255 ::= BIT STRING (SIZE (255))
+ %% BS256 ::= BIT STRING (SIZE (256))
+ %% BS1024 ::= BIT STRING (SIZE (1024))
+ %% test case for OTP-7602
+ %%==========================================================
+ BSmaker =
+ fun(_F,S,S,_,Acc) ->
+ Acc;
+ (F,Ix,S,{A,B},Acc) ->
+ F(F,Ix+1,S,{B,A},[A|Acc])
+ end,
+
+ BSList255 = BSmaker(BSmaker,0,255,{1,0},[]),
+ BSList256 = BSmaker(BSmaker,0,256,{1,0},[]),
+ BSList1024 = BSmaker(BSmaker,0,1024,{1,0},[]),
+ ?line {ok,Bytes56} =
+ asn1_wrapper:encode('PrimStrings','BS255',BSList255),
+ ?line {ok,BSList255} =
+ asn1_wrapper:decode('PrimStrings','BS255',Bytes56),
+ ?line {ok,Bytes57} =
+ asn1_wrapper:encode('PrimStrings','BS256',BSList256),
+ ?line {ok,BSList256} =
+ asn1_wrapper:decode('PrimStrings','BS256',Bytes57),
+ ?line {ok,Bytes58} =
+ asn1_wrapper:encode('PrimStrings','BS1024',BSList1024),
+ ?line {ok,BSList1024} =
+ asn1_wrapper:decode('PrimStrings','BS1024',Bytes58).
+
+
+
+bit_string_unnamed(Rules) ->
+ case asn1_wrapper:erule(Rules) of
+ ber ->
+ ok;
+ per ->
+ ?line {ok,Bytes1} =
+ case catch asn1_wrapper:encode('PrimStrings','TransportLayerAddress',[0,1,1,0]) of
+ Ret = {ok,_} -> Ret;
+ Err ->
+ Config = file:consult(test_config),
+ ?line OutDir = ?config(priv_dir,Config),
+ MyOut = "/home/bertil/daily_build",
+ file:copy(filename:join([OutDir,"PrimStrings.erl"]),
+ filename:join([MyOut,"PrimStrings.erl"])),
+ file:copy(filename:join([OutDir,"PrimStrings.beam"]),
+ filename:join([MyOut,"PrimStrings.beam"])),
+ file:copy(code:which(asn1rt_per_v1),
+ filename:join([MyOut,"asn1rt_per_v1.beam"])),
+ file:copy(filename:join([code:lib_dir(asn1),src,"asn1rt_per_v1.erl"]),filename:join([MyOut,"asn1rt_per_v1.erl"])),
+ io:format("Err: ~p~n",[Err]),
+ Err
+ end,
+ ?line {ok,[0,1,1,0]} = asn1_wrapper:decode('PrimStrings','TransportLayerAddress',lists:flatten(Bytes1))
+ end.
+
+octet_string(Rules) ->
+
+ %%==========================================================
+ %% Os ::= OCTET STRING
+ %%==========================================================
+
+ ?line case asn1_wrapper:erule(Rules) of
+ ber ->
+ ?line {ok,"Jones"} =
+ asn1_wrapper:decode('PrimStrings','Os',[4,5,16#4A,16#6F,16#6E,16#65,16#73]),
+
+ ?line {ok,"Jones"} =
+ asn1_wrapper:decode('PrimStrings','Os',[36,9,4,3,16#4A,16#6F,16#6E,4,2,16#65,16#73]),
+
+ ?line {ok,"Jones"} =
+ asn1_wrapper:decode('PrimStrings','Os',[36,128,4,3,16#4A,16#6F,16#6E,4,2,16#65,16#73,0,0]),
+ ok;
+
+ per ->
+ ok
+ end,
+
+
+
+ ?line {ok,Bytes4} =
+ asn1_wrapper:encode('PrimStrings','Os',[47,23,99,255,1]),
+ ?line {ok,[47,23,99,255,1]} = asn1_wrapper:decode('PrimStrings','Os',lists:flatten(Bytes4)),
+
+ ?line {ok,Bytes5} =
+ asn1_wrapper:encode('PrimStrings','OsCon',[47,23,99,255,1]),
+ ?line {ok,[47,23,99,255,1]} = asn1_wrapper:decode('PrimStrings','OsCon',lists:flatten(Bytes5)),
+
+ ?line {ok,Bytes6} =
+ asn1_wrapper:encode('PrimStrings','OsPri',[47,23,99,255,1]),
+ ?line {ok,[47,23,99,255,1]} = asn1_wrapper:decode('PrimStrings','OsPri',lists:flatten(Bytes6)),
+
+ ?line {ok,Bytes7} =
+ asn1_wrapper:encode('PrimStrings','OsApp',[47,23,99,255,1]),
+ ?line {ok,[47,23,99,255,1]} = asn1_wrapper:decode('PrimStrings','OsApp',lists:flatten(Bytes7)),
+
+ ?line {ok,Bytes8} =
+ asn1_wrapper:encode('PrimStrings','OsExpCon',[47,23,99,255,1]),
+ ?line {ok,[47,23,99,255,1]} = asn1_wrapper:decode('PrimStrings','OsExpCon',lists:flatten(Bytes8)),
+
+ ?line {ok,Bytes9} =
+ asn1_wrapper:encode('PrimStrings','OsExpPri',[47,23,99,255,1]),
+ ?line {ok,[47,23,99,255,1]} = asn1_wrapper:decode('PrimStrings','OsExpPri',lists:flatten(Bytes9)),
+
+ ?line {ok,Bytes10} =
+ asn1_wrapper:encode('PrimStrings','OsExpApp',[47,23,99,255,1]),
+ ?line {ok,[47,23,99,255,1]} = asn1_wrapper:decode('PrimStrings','OsExpApp',lists:flatten(Bytes10)),
+
+ ?line {ok,Bytes11} =
+ asn1_wrapper:encode('PrimStrings','Os',[]),
+ ?line {ok,[]} = asn1_wrapper:decode('PrimStrings','Os',lists:flatten(Bytes11)),
+
+ ?line {ok,Bytes12} =
+ asn1_wrapper:encode('PrimStrings','OsApp',[]),
+ ?line {ok,[]} = asn1_wrapper:decode('PrimStrings','OsApp',lists:flatten(Bytes12)),
+
+ ?line {ok,Bytes13} =
+ asn1_wrapper:encode('PrimStrings','OsExpApp',[]),
+ ?line {ok,[]} = asn1_wrapper:decode('PrimStrings','OsExpApp',lists:flatten(Bytes13)),
+
+
+
+
+
+
+
+ OsR = "12345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890",
+
+ ?line {ok,Bytes21} =
+ asn1_wrapper:encode('PrimStrings','Os',OsR),
+ ?line {ok,Os1} = asn1_wrapper:decode('PrimStrings','Os',lists:flatten(Bytes21)),
+ ?line Os1 = OsR,
+ ?line {ok,Bytes22} =
+ asn1_wrapper:encode('PrimStrings','OsCon',OsR),
+ ?line {ok,Os2} = asn1_wrapper:decode('PrimStrings','OsCon',lists:flatten(Bytes22)),
+ ?line Os2 = OsR,
+ ?line {ok,Bytes23} =
+ asn1_wrapper:encode('PrimStrings','OsExpApp',OsR),
+ ?line {ok,Os3} = asn1_wrapper:decode('PrimStrings','OsExpApp',lists:flatten(Bytes23)),
+ ?line Os3 = OsR,
+
+
+
+ ?line case asn1_wrapper:erule(Rules) of
+ ber ->
+ ?line {ok,"Jones"} = asn1_wrapper:decode('PrimStrings','OsExpApp',[127,62,7,4,5,16#4A,16#6F,16#6E,16#65,16#73]),
+ ?line {ok,"Jones"} = asn1_wrapper:decode('PrimStrings','OsExpApp',[127,62,11,36,9,4,3,16#4A,16#6F,16#6E,4,2,16#65,16#73]),
+ ?line {ok,"Jones"} = asn1_wrapper:decode('PrimStrings','OsExpApp',[127,62,13,36,128,4,3,16#4A,16#6F,16#6E,4,2,16#65,16#73,0,0]),
+ ?line {ok,"Jones"} = asn1_wrapper:decode('PrimStrings','OsExpApp',[127,62,128,36,128,4,3,16#4A,16#6F,16#6E,4,2,16#65,16#73,0,0,0,0]),
+ ?line {ok,"JonesJones"} = asn1_wrapper:decode('PrimStrings','OsExpApp',[127,62,128,36,128,4,3,16#4A,16#6F,16#6E,4,2,16#65,16#73,0,0,36,128,4,3,16#4A,16#6F,16#6E,4,2,16#65,16#73,0,0,0,0]),
+ ok;
+
+ per ->
+ ok
+ end,
+
+
+ ok.
+
+
+
+
+
+numeric_string(Rules) ->
+
+ %%==========================================================
+ %% Ns ::= NumericString
+ %%==========================================================
+
+ ?line {ok,BytesNs2} = asn1_wrapper:encode('PrimStrings','Ns',[]),
+ ?line {ok,[]} = asn1_wrapper:decode('PrimStrings','Ns',lists:flatten(BytesNs2)),
+
+ ?line case asn1_wrapper:erule(Rules) of
+ ber ->
+ ?line {ok,BytesNs1} = asn1_wrapper:encode('PrimStrings','Ns',[48,49,32,51,52]),
+ ?line {ok,[48,49,32,51,52]} = asn1_wrapper:decode('PrimStrings','Ns',lists:flatten(BytesNs1)),
+
+ ?line {ok,"Jones"} = asn1_wrapper:decode('PrimStrings','Ns',[16#12,5,16#4A,16#6F,16#6E,16#65,16#73]),
+ ?line {ok,"Jones"} = asn1_wrapper:decode('PrimStrings','Ns',[16#32,9,18,3,16#4A,16#6F,16#6E,18,2,16#65,16#73]),
+ ?line {ok,"Jones"} = asn1_wrapper:decode('PrimStrings','Ns',[16#32,128,18,3,16#4A,16#6F,16#6E,18,2,16#65,16#73,0,0]),
+ ok;
+
+ per ->
+ ?line {ok,BytesNs1} = asn1_wrapper:encode('PrimStrings','Ns',[48,49,32,51,52]),
+ ?line {ok,"01 34"} = asn1_wrapper:decode('PrimStrings','Ns',lists:flatten(BytesNs1)),
+ ok
+ end,
+
+
+
+
+ %%==========================================================
+ %% NsCon ::= [70] NumericString
+ %%==========================================================
+
+ ?line {ok,BytesNs12} = asn1_wrapper:encode('PrimStrings','NsCon',[]),
+ ?line {ok,[]} = asn1_wrapper:decode('PrimStrings','NsCon',lists:flatten(BytesNs12)),
+
+
+
+ ?line case asn1_wrapper:erule(Rules) of
+ ber ->
+ ?line {ok,BytesNs11} = asn1_wrapper:encode('PrimStrings','NsCon',[48,49,32,51,52]),
+ ?line {ok,[48,49,32,51,52]} = asn1_wrapper:decode('PrimStrings','NsCon',lists:flatten(BytesNs11)),
+
+ ?line {ok,"Jones"} = asn1_wrapper:decode('PrimStrings','NsCon',[16#9F,16#46,5,16#4A,16#6F,16#6E,16#65,16#73]),
+ ?line {ok,"Jones"} = asn1_wrapper:decode('PrimStrings','NsCon',[16#BF,16#46,9,18,3,16#4A,16#6F,16#6E,18,2,16#65,16#73]),
+ ?line {ok,"Jones"} = asn1_wrapper:decode('PrimStrings','NsCon',[16#BF,16#46,128,18,3,16#4A,16#6F,16#6E,18,2,16#65,16#73,0,0]),
+ ok;
+
+ per ->
+ ?line {ok,BytesNs11} = asn1_wrapper:encode('PrimStrings','NsCon',[48,49,32,51,52]),
+ ?line {ok,"01 34"} = asn1_wrapper:decode('PrimStrings','NsCon',lists:flatten(BytesNs11)),
+ ok
+ end,
+
+
+
+ %%==========================================================
+ %% NsExpCon ::= [71] EXPLICIT NumericString
+ %%==========================================================
+
+ ?line {ok,BytesNs22} = asn1_wrapper:encode('PrimStrings','NsExpCon',[]),
+ ?line {ok,[]} = asn1_wrapper:decode('PrimStrings','NsExpCon',lists:flatten(BytesNs22)),
+
+
+
+ ?line case asn1_wrapper:erule(Rules) of
+ ber ->
+ ?line {ok,BytesNs21} = asn1_wrapper:encode('PrimStrings','NsExpCon',[48,49,32,51,52]),
+ ?line {ok,[48,49,32,51,52]} = asn1_wrapper:decode('PrimStrings','NsExpCon',lists:flatten(BytesNs21)),
+
+ ?line {ok,"Jones"} = asn1_wrapper:decode('PrimStrings','NsExpCon',[16#BF,16#47,16#07,16#12,16#05,16#4A,16#6F,16#6E,16#65,16#73]),
+ ?line {ok,"Jones"} = asn1_wrapper:decode('PrimStrings','NsExpCon',[16#BF,16#47,11,16#32,9,18,3,16#4A,16#6F,16#6E,18,2,16#65,16#73]),
+ ?line {ok,"Jones"} = asn1_wrapper:decode('PrimStrings','NsExpCon',[16#BF,16#47,128,16#32,128,18,3,16#4A,16#6F,16#6E,18,2,16#65,16#73,0,0,0,0]),
+ ?line {ok,"JonesJones"} = asn1_wrapper:decode('PrimStrings','NsExpCon',[16#BF,16#47,26,16#32,128,18,3,16#4A,16#6F,16#6E,18,2,16#65,16#73,0,0,16#32,128,18,3,16#4A,16#6F,16#6E,18,2,16#65,16#73,0,0]),
+ ?line {ok,"JonesJones"} = asn1_wrapper:decode('PrimStrings','NsExpCon',[16#BF,16#47,128,16#32,128,18,3,16#4A,16#6F,16#6E,18,2,16#65,16#73,0,0,16#32,128,18,3,16#4A,16#6F,16#6E,18,2,16#65,16#73,0,0,0,0]),
+ ok;
+
+ per ->
+ ?line {ok,BytesNs21} = asn1_wrapper:encode('PrimStrings','NsExpCon',[48,49,32,51,52]),
+ ?line {ok,"01 34"} = asn1_wrapper:decode('PrimStrings','NsExpCon',lists:flatten(BytesNs21)),
+ ok
+ end,
+
+ ok.
+
+
+
+
+
+other_strings(_Rules) ->
+
+ %%==========================================================
+ %% Ps ::= PrintableString
+ %%==========================================================
+
+ ?line {ok,BytesPs1} = asn1_wrapper:encode('PrimStrings','Ps',[47,23,99,75,47]),
+ ?line {ok,[47,23,99,75,47]} =
+ asn1_wrapper:decode('PrimStrings','Ps',lists:flatten(BytesPs1)),
+
+ ?line {ok,BytesPs2} = asn1_wrapper:encode('PrimStrings','Ps',[]),
+ ?line {ok,[]} = asn1_wrapper:decode('PrimStrings','Ps',lists:flatten(BytesPs2)),
+
+
+
+ %%==========================================================
+ %% Vis ::= VisibleString
+ %%==========================================================
+
+ ?line {ok,BytesVis1} = asn1_wrapper:encode('PrimStrings','Vis',[47,23,99,75,47]),
+ ?line {ok,[47,23,99,75,47]} =
+ asn1_wrapper:decode('PrimStrings','Vis',lists:flatten(BytesVis1)),
+
+ ?line {ok,BytesVis2} = asn1_wrapper:encode('PrimStrings','Vis',[]),
+ ?line {ok,[]} = asn1_wrapper:decode('PrimStrings','Vis',lists:flatten(BytesVis2)),
+
+
+
+ %%==========================================================
+ %% IA5 ::= IA5String
+ %%==========================================================
+
+ ?line {ok,BytesIA51} = asn1_wrapper:encode('PrimStrings','IA5',[47,23,99,75,47]),
+ ?line {ok,[47,23,99,75,47]} =
+ asn1_wrapper:decode('PrimStrings','IA5',lists:flatten(BytesIA51)),
+
+ ?line {ok,BytesIA52} = asn1_wrapper:encode('PrimStrings','IA5',[]),
+ ?line {ok,[]} = asn1_wrapper:decode('PrimStrings','IA5',lists:flatten(BytesIA52)),
+
+
+ IA5_1 = "12345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890",
+
+ ?line {ok,BytesIA53} = asn1_wrapper:encode('PrimStrings','IA5',IA5_1),
+ ?line {ok,IA5_1r} = asn1_wrapper:decode('PrimStrings','IA5',lists:flatten(BytesIA53)),
+ ?line IA5_1 = IA5_1r,
+
+
+
+
+ ok.
+
+
+more_strings(_Rules) ->
+ %%==========================================================
+ %% Ts ::= TeletexString
+ %%==========================================================
+
+ ?line {ok,BytesTs1} = asn1_wrapper:encode('PrimStrings','Ts',[47,23,99,75,47]),
+ ?line {ok,[47,23,99,75,47]} =
+ asn1_wrapper:decode('PrimStrings','Ts',lists:flatten(BytesTs1)),
+
+ ?line {ok,BytesTs2} = asn1_wrapper:encode('PrimStrings','Ts',[]),
+ ?line {ok,[]} = asn1_wrapper:decode('PrimStrings','Ts',lists:flatten(BytesTs2)),
+
+
+
+ %%==========================================================
+ %% Vxs ::= VideotexString
+ %%==========================================================
+
+ ?line {ok,BytesVxs1} = asn1_wrapper:encode('PrimStrings','Vxs',[47,23,99,75,47]),
+ ?line {ok,[47,23,99,75,47]} =
+ asn1_wrapper:decode('PrimStrings','Vxs',lists:flatten(BytesVxs1)),
+
+ ?line {ok,BytesVxs2} = asn1_wrapper:encode('PrimStrings','Vxs',[]),
+ ?line {ok,[]} = asn1_wrapper:decode('PrimStrings','Vxs',lists:flatten(BytesVxs2)),
+
+
+
+ %%==========================================================
+ %% Grs ::= GraphicString
+ %%==========================================================
+
+ ?line {ok,BytesGrs1} = asn1_wrapper:encode('PrimStrings','Grs',[47,23,99,75,47]),
+ ?line {ok,[47,23,99,75,47]} =
+ asn1_wrapper:decode('PrimStrings','Grs',lists:flatten(BytesGrs1)),
+
+ ?line {ok,BytesGrs2} = asn1_wrapper:encode('PrimStrings','Grs',[]),
+ ?line {ok,[]} = asn1_wrapper:decode('PrimStrings','Grs',lists:flatten(BytesGrs2)),
+
+
+ %%==========================================================
+ %% ODesc ::= ObjectDescriptor, test case for OTP-4161
+ %%==========================================================
+
+ ?line {ok,BytesODesc1} = asn1_wrapper:encode('PrimStrings','ODesc',[79,98,106,101,99,116,68,101,115,99,114,105,112,116,111,114]),
+ ?line {ok,[79,98,106,101,99,116,68,101,115,99,114,105,112,116,111,114]} =
+ asn1_wrapper:decode('PrimStrings','ODesc',lists:flatten(BytesODesc1)),
+
+ ?line {ok,BytesODesc2} = asn1_wrapper:encode('PrimStrings','ODesc',[]),
+ ?line {ok,[]} = asn1_wrapper:decode('PrimStrings','ODesc',lists:flatten(BytesODesc2)),
+
+ %%==========================================================
+ %% Ges ::= GeneralString
+ %%==========================================================
+
+ ?line {ok,BytesGes1} = asn1_wrapper:encode('PrimStrings','Ges',[47,23,99,75,47]),
+ ?line {ok,[47,23,99,75,47]} =
+ asn1_wrapper:decode('PrimStrings','Ges',lists:flatten(BytesGes1)),
+
+ ?line {ok,BytesGes2} = asn1_wrapper:encode('PrimStrings','Ges',[]),
+ ?line {ok,[]} = asn1_wrapper:decode('PrimStrings','Ges',lists:flatten(BytesGes2)),
+
+ ok.
+
+
+
+universal_string(Rules) ->
+
+
+ %%==========================================================
+ %% Us ::= UniversalString
+ %%==========================================================
+
+ ?line {ok,Bytes1} =
+ asn1_wrapper:encode('PrimStrings','Us',[{47,23,99,47},{0,0,55,66}]),
+ ?line {ok,[{47,23,99,47},{0,0,55,66}]} =
+ asn1_wrapper:decode('PrimStrings','Us',lists:flatten(Bytes1)),
+
+ ?line {ok,Bytes2} =
+ asn1_wrapper:encode('PrimStrings','Us',[{47,23,99,255},{0,0,0,201}]),
+ ?line {ok,[{47,23,99,255},201]} =
+ asn1_wrapper:decode('PrimStrings','Us',lists:flatten(Bytes2)),
+
+ ?line {ok,Bytes3} = asn1_wrapper:encode('PrimStrings','Us',"Universal String"),
+ ?line {ok,"Universal String"} =
+ asn1_wrapper:decode('PrimStrings','Us',lists:flatten(Bytes3)),
+
+ ?line {ok,Bytes4} = asn1_wrapper:encode('PrimStrings','Us',[]),
+ ?line {ok,[]} = asn1_wrapper:decode('PrimStrings','Us',lists:flatten(Bytes4)),
+
+ ?line {ok,Bytes5} = asn1_wrapper:encode('PrimStrings','Us',[{47,23,99,47}]),
+ ?line {ok,[{47,23,99,47}]} =
+ asn1_wrapper:decode('PrimStrings','Us',lists:flatten(Bytes5)),
+
+
+ ?line case asn1_wrapper:erule(Rules) of
+ ber ->
+
+ ?line {ok,[{47,23,99,255},{0,0,2,201}]} =
+ asn1_wrapper:decode('PrimStrings','Us',lists:flatten([16#3C,12,28,4,47,23,99,255,28,4,0,0,2,201])),
+ ?line {ok,[{47,23,99,255},{0,0,2,201}]} =
+ asn1_wrapper:decode('PrimStrings','Us',lists:flatten([16#3C,16#80,28,4,47,23,99,255,28,4,0,0,2,201,0,0]));
+ _ ->
+ ok
+ end,
+
+
+ Us1 = "12345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890",
+ ?line {ok,Bytes15} = asn1_wrapper:encode('PrimStrings','IA5',Us1),
+ ?line {ok,Us1r} = asn1_wrapper:decode('PrimStrings','IA5',lists:flatten(Bytes15)),
+ ?line Us1 = Us1r,
+
+
+
+%%==========================================================
+%% UsCon ::= [70] UniversalString
+%%==========================================================
+
+ ?line {ok,Bytes11} =
+ asn1_wrapper:encode('PrimStrings','UsCon',[{47,23,99,255},{0,0,2,201}]),
+ ?line {ok,[{47,23,99,255},{0,0,2,201}]} =
+ asn1_wrapper:decode('PrimStrings','UsCon',lists:flatten(Bytes11)),
+
+ ?line {ok,Bytes12} =
+ asn1_wrapper:encode('PrimStrings','UsCon',[{47,23,99,255},{0,0,0,201}]),
+ ?line {ok,[{47,23,99,255},201]} =
+ asn1_wrapper:decode('PrimStrings','UsCon',lists:flatten(Bytes12)),
+
+ ?line {ok,Bytes13} = asn1_wrapper:encode('PrimStrings','UsCon',"Universal String"),
+ ?line {ok,"Universal String"} =
+ asn1_wrapper:decode('PrimStrings','UsCon',lists:flatten(Bytes13)),
+
+ ?line {ok,Bytes14} = asn1_wrapper:encode('PrimStrings','UsCon',[]),
+ ?line {ok,[]} = asn1_wrapper:decode('PrimStrings','UsCon',lists:flatten(Bytes14)),
+
+ ?line case asn1_wrapper:erule(Rules) of
+ ber ->
+ ?line {ok,[{47,23,99,255},{0,0,2,201}]} =
+ asn1_wrapper:decode('PrimStrings','UsCon',lists:flatten([16#BF,16#46,12,28,4,47,23,99,255,28,4,0,0,2,201])),
+ ?line {ok,[{47,23,99,255},{0,0,2,201}]} =
+ asn1_wrapper:decode('PrimStrings','UsCon',lists:flatten([16#BF,16#46,16#80,28,4,47,23,99,255,28,4,0,0,2,201,0,0]));
+ _ -> ok
+ end,
+
+
+
+%%==========================================================
+%% UsExpCon ::= [71] EXPLICIT UniversalString
+%%==========================================================
+
+ ?line {ok,Bytes21} =
+ asn1_wrapper:encode('PrimStrings','UsExpCon',[{47,23,99,255},{0,0,2,201}]),
+ ?line {ok,[{47,23,99,255},{0,0,2,201}]} =
+ asn1_wrapper:decode('PrimStrings','UsExpCon',lists:flatten(Bytes21)),
+
+ ?line {ok,Bytes22} =
+ asn1_wrapper:encode('PrimStrings','UsExpCon',[{47,23,99,255},{0,0,0,201}]),
+ ?line {ok,[{47,23,99,255},201]} =
+ asn1_wrapper:decode('PrimStrings','UsExpCon',lists:flatten(Bytes22)),
+
+ ?line {ok,Bytes23} =
+ asn1_wrapper:encode('PrimStrings','UsExpCon',"Universal String"),
+ ?line {ok,"Universal String"} =
+ asn1_wrapper:decode('PrimStrings','UsExpCon',lists:flatten(Bytes23)),
+
+ ?line {ok,Bytes24} =
+ asn1_wrapper:encode('PrimStrings','UsExpCon',[]),
+ ?line {ok,[]} =
+ asn1_wrapper:decode('PrimStrings','UsExpCon',lists:flatten(Bytes24)),
+
+ ?line case asn1_wrapper:erule(Rules) of
+ ber ->
+ ?line {ok,[{47,23,99,255},{0,0,2,201}]} =
+ asn1_wrapper:decode('PrimStrings','UsExpCon',lists:flatten([16#BF,16#47,14,60,12,28,4,47,23,99,255,28,4,0,0,2,201])),
+ ?line {ok,[{47,23,99,255},{0,0,2,201}]} =
+ asn1_wrapper:decode('PrimStrings','UsExpCon',lists:flatten([16#BF,16#47,16,60,16#80,28,4,47,23,99,255,28,4,0,0,2,201,0,0]));
+ _ -> ok
+ end,
+
+
+ok.
+
+
+
+
+
+bmp_string(_Rules) ->
+
+ %%==========================================================
+ %% BMP ::= BMPString
+ %%==========================================================
+
+ ?line {ok,Bytes1} =
+ asn1_wrapper:encode('PrimStrings','BMP',[{0,0,99,48},{0,0,2,201}]),
+ ?line {ok,[{0,0,99,48},{0,0,2,201}]} =
+ asn1_wrapper:decode('PrimStrings','BMP',lists:flatten(Bytes1)),
+
+ ?line {ok,Bytes2} =
+ asn1_wrapper:encode('PrimStrings','BMP',[{0,0,0,48},{0,0,2,201}]),
+ ?line {ok,[48,{0,0,2,201}]} =
+ asn1_wrapper:decode('PrimStrings','BMP',lists:flatten(Bytes2)),
+
+ ?line {ok,Bytes3} = asn1_wrapper:encode('PrimStrings','BMP',"BMP String"),
+ ?line {ok,"BMP String"} =
+ asn1_wrapper:decode('PrimStrings','BMP',lists:flatten(Bytes3)),
+
+ ?line {ok,Bytes4} = asn1_wrapper:encode('PrimStrings','BMP',[]),
+ ?line {ok,[]} = asn1_wrapper:decode('PrimStrings','BMP',lists:flatten(Bytes4)),
+
+
+ BMP1 = "12345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890",
+ ?line {ok,Bytes5} = asn1_wrapper:encode('PrimStrings','BMP',BMP1),
+ ?line {ok,BMP1r} = asn1_wrapper:decode('PrimStrings','BMP',lists:flatten(Bytes5)),
+ ?line BMP1 = BMP1r,
+
+
+ ok.
+
+
+
+
+
+times(_Rules) ->
+
+ %%==========================================================
+ %% Gt ::= GeneralizedTime
+ %%==========================================================
+
+ ?line {ok,Bytes1} = asn1_wrapper:encode('PrimStrings','Gt',"19970923110723.2"),
+ ?line {ok,"19970923110723.2"} =
+ asn1_wrapper:decode('PrimStrings','Gt',lists:flatten(Bytes1)),
+
+ ?line {ok,Bytes2} = asn1_wrapper:encode('PrimStrings','Gt',"19970923110723.2Z"),
+ ?line {ok,"19970923110723.2Z"} =
+ asn1_wrapper:decode('PrimStrings','Gt',lists:flatten(Bytes2)),
+
+ ?line {ok,Bytes3} = asn1_wrapper:encode('PrimStrings','Gt',"19970923110723.2-0500"),
+ ?line {ok,"19970923110723.2-0500"} =
+ asn1_wrapper:decode('PrimStrings','Gt',lists:flatten(Bytes3)),
+
+
+
+
+
+
+
+ %%==========================================================
+ %% UTC ::= UTCTime
+ %%==========================================================
+
+ ?line {ok,Bytes11} = asn1_wrapper:encode('PrimStrings','UTC',"9709211107Z"),
+ ?line {ok,"9709211107Z"} =
+ asn1_wrapper:decode('PrimStrings','UTC',lists:flatten(Bytes11)),
+
+ ?line {ok,Bytes12} = asn1_wrapper:encode('PrimStrings','UTC',"9709211107-0500"),
+ ?line {ok,"9709211107-0500"} =
+ asn1_wrapper:decode('PrimStrings','UTC',lists:flatten(Bytes12)),
+
+ ok.
+
+
+utf8_string(_Rules) ->
+
+ %%==========================================================
+ %% UTF ::= UTF8String
+ %%==========================================================
+
+ %% test values in all ranges
+
+ ValLbR1 = [16#00],
+ ValUbR1 = [16#7f],
+ ValLbR2 = [16#80],
+ ValUbR2 = [16#7ff],
+ ValLbR3 = [16#800],
+ ValUbR3 = [16#ffff],
+ ValLbR4 = [16#10000],
+ ValUbR4 = [16#1fffff],
+ ValLbR5 = [16#200000],
+ ValUbR5 = [16#3ffffff],
+ ValLbR6 = [16#4000000],
+ ValUbR6 = [16#7fffffff],
+
+ ?line {ok,UTF8L1} = asn1rt:utf8_list_to_binary(ValLbR1),
+ ?line {ok,Bytes1} = asn1_wrapper:encode('PrimStrings','UTF',UTF8L1),
+ ?line {ok,Bin1} = asn1_wrapper:decode('PrimStrings','UTF',Bytes1),
+ ?line {ok,ValLbR1} = wrapper_utf8_binary_to_list(Bin1),
+
+ ?line {ok,UTF8L2} = asn1rt:utf8_list_to_binary(ValUbR1),
+ ?line {ok,Bytes2} = asn1_wrapper:encode('PrimStrings','UTF',UTF8L2),
+ ?line {ok,Bin2} = asn1_wrapper:decode('PrimStrings','UTF',Bytes2),
+ ?line {ok,ValUbR1} = wrapper_utf8_binary_to_list(Bin2),
+
+ ?line {ok,UTF8L3} = asn1rt:utf8_list_to_binary(ValLbR2),
+ ?line {ok,Bytes3} = asn1_wrapper:encode('PrimStrings','UTF',UTF8L3),
+ ?line {ok,Bin3} = asn1_wrapper:decode('PrimStrings','UTF',Bytes3),
+ ?line {ok,ValLbR2} = wrapper_utf8_binary_to_list(Bin3),
+
+ ?line {ok,UTF8L4} = asn1rt:utf8_list_to_binary(ValUbR2),
+ ?line {ok,Bytes4} = asn1_wrapper:encode('PrimStrings','UTF',UTF8L4),
+ ?line {ok,Bin4} = asn1_wrapper:decode('PrimStrings','UTF',Bytes4),
+ ?line {ok,ValUbR2} = wrapper_utf8_binary_to_list(Bin4),
+
+ ?line {ok,UTF8L5} = asn1rt:utf8_list_to_binary(ValLbR3),
+ ?line {ok,Bytes5} = asn1_wrapper:encode('PrimStrings','UTF',UTF8L5),
+ ?line {ok,Bin5} = asn1_wrapper:decode('PrimStrings','UTF',Bytes5),
+ ?line {ok,ValLbR3} = wrapper_utf8_binary_to_list(Bin5),
+
+ ?line {ok,UTF8L6} = asn1rt:utf8_list_to_binary(ValUbR3),
+ ?line {ok,Bytes6} = asn1_wrapper:encode('PrimStrings','UTF',UTF8L6),
+ ?line {ok,Bin6} = asn1_wrapper:decode('PrimStrings','UTF',Bytes6),
+ ?line {ok,ValUbR3} = wrapper_utf8_binary_to_list(Bin6),
+
+ ?line {ok,UTF8L7} = asn1rt:utf8_list_to_binary(ValLbR4),
+ ?line {ok,Bytes7} = asn1_wrapper:encode('PrimStrings','UTF',UTF8L7),
+ ?line {ok,Bin7} = asn1_wrapper:decode('PrimStrings','UTF',Bytes7),
+ ?line {ok,ValLbR4} = wrapper_utf8_binary_to_list(Bin7),
+
+ ?line {ok,UTF8L8} = asn1rt:utf8_list_to_binary(ValUbR4),
+ ?line {ok,Bytes8} = asn1_wrapper:encode('PrimStrings','UTF',UTF8L8),
+ ?line {ok,Bin8} = asn1_wrapper:decode('PrimStrings','UTF',Bytes8),
+ ?line {ok,ValUbR4} = wrapper_utf8_binary_to_list(Bin8),
+
+ ?line {ok,UTF8L9} = asn1rt:utf8_list_to_binary(ValLbR5),
+ ?line {ok,Bytes9} = asn1_wrapper:encode('PrimStrings','UTF',UTF8L9),
+ ?line {ok,Bin9} = asn1_wrapper:decode('PrimStrings','UTF',Bytes9),
+ ?line {ok,ValLbR5} = wrapper_utf8_binary_to_list(Bin9),
+
+ ?line {ok,UTF8L10} = asn1rt:utf8_list_to_binary(ValUbR5),
+ ?line {ok,Bytes10} = asn1_wrapper:encode('PrimStrings','UTF',UTF8L10),
+ ?line {ok,Bin10} = asn1_wrapper:decode('PrimStrings','UTF',Bytes10),
+ ?line {ok,ValUbR5} = wrapper_utf8_binary_to_list(Bin10),
+
+ ?line {ok,UTF8L11} = asn1rt:utf8_list_to_binary(ValLbR6),
+ ?line {ok,Bytes11} = asn1_wrapper:encode('PrimStrings','UTF',UTF8L11),
+ ?line {ok,Bin11} = asn1_wrapper:decode('PrimStrings','UTF',Bytes11),
+ ?line {ok,ValLbR6} = wrapper_utf8_binary_to_list(Bin11),
+
+ ?line {ok,UTF8L12} = asn1rt:utf8_list_to_binary(ValUbR6),
+ ?line {ok,Bytes12} = asn1_wrapper:encode('PrimStrings','UTF',UTF8L12),
+ ?line {ok,Bin12} = asn1_wrapper:decode('PrimStrings','UTF',Bytes12),
+ ?line {ok,ValUbR6} = wrapper_utf8_binary_to_list(Bin12),
+
+ LVal = ValLbR1++ValUbR1++ValLbR2++ValUbR2++ValLbR3++ValUbR3++
+ ValLbR4++ValUbR4++ValLbR5++ValUbR5++ValLbR6++ValUbR6,
+ LongVal = LVal++LVal++LVal++LVal++LVal++LVal++LVal++"hello",
+
+ ?line {ok,UTF8L13} = asn1rt:utf8_list_to_binary(LongVal),
+ ?line {ok,Bytes13} = asn1_wrapper:encode('PrimStrings','UTF',UTF8L13),
+ ?line {ok,Bin13} = asn1_wrapper:decode('PrimStrings','UTF',Bytes13),
+ ?line {ok,LongVal} = wrapper_utf8_binary_to_list(Bin13).
+
+wrapper_utf8_binary_to_list(L) when is_list(L) ->
+ asn1rt:utf8_binary_to_list(list_to_binary(L));
+wrapper_utf8_binary_to_list(B) ->
+ asn1rt:utf8_binary_to_list(B).
diff --git a/lib/asn1/test/testRANAP.erl b/lib/asn1/test/testRANAP.erl
new file mode 100644
index 0000000000..7c35674d3a
--- /dev/null
+++ b/lib/asn1/test/testRANAP.erl
@@ -0,0 +1,52 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 2001-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(testRANAP).
+
+-export([compile/3,testobj/1]).
+
+-include("test_server.hrl").
+
+
+compile(Config,Erule,Options) ->
+ ?line DataDir = ?config(data_dir,Config),
+ ?line OutDir = ?config(priv_dir,Config),
+ ?line true = code:add_patha(?config(priv_dir,Config)),
+
+ ?line ok = asn1ct:compile(filename:join(DataDir,"RANAP"),[Erule,{outdir,OutDir}]++Options),
+ ?line {ok,testobj} = compile:file(filename:join(DataDir,"testobj"),[{i,OutDir},{outdir,OutDir}]++Options),
+ ok.
+
+testobj(_Erule) ->
+ ?line ok = testobj:run_com_id(),
+ ?line ok = testobj:run_dir_tsf_2cn(),
+ ?line ok = testobj:run_dir_tsf_2rnc(),
+ ?line ok = testobj:run_init_ue(),
+ ?line ok = testobj:run_iu_rel_cmd(),
+ ?line ok = testobj:run_iu_rel_cmp(),
+ ?line ok = testobj:run_rab_ass_rsp_delete(),
+ ?line ok = testobj:run_rab_ass_rsp_setup(),
+ ?line ok = testobj:run_rab_create(),
+ ?line ok = testobj:run_rab_rel(),
+ ?line ok = testobj:run_reset(),
+ ?line ok = testobj:run_reset_res(),
+ ?line ok = testobj:run_sm_cmd(),
+ ?line ok = testobj:run_sm_cmp(),
+ ?line ok = testobj:run_sm_rej().
diff --git a/lib/asn1/test/testROSE.erl b/lib/asn1/test/testROSE.erl
new file mode 100644
index 0000000000..65851e21fc
--- /dev/null
+++ b/lib/asn1/test/testROSE.erl
@@ -0,0 +1,36 @@
+%%
+%% %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(testROSE).
+
+-export([compile/3]).
+
+-include("test_server.hrl").
+
+
+
+compile(Config,Rules,Opt) ->
+
+ ?line DataDir = ?config(data_dir,Config),
+ ?line OutDir = ?config(priv_dir,Config),
+ ?line true = code:add_patha(?config(priv_dir,Config)),
+
+ ?line ok = asn1ct:compile(DataDir ++ "Remote-Operations-Merged.set.asn1",
+ [Rules,{outdir,OutDir}]++Opt).
+
diff --git a/lib/asn1/test/testSSLspecs.erl b/lib/asn1/test/testSSLspecs.erl
new file mode 100644
index 0000000000..87e5e5fd02
--- /dev/null
+++ b/lib/asn1/test/testSSLspecs.erl
@@ -0,0 +1,179 @@
+%%
+%% %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(testSSLspecs).
+
+-export([compile/3,run/1,compile_inline/2,run_inline/1]).
+
+-include("test_server.hrl").
+
+
+compile(Config,Rules,Options) ->
+
+ ?line DataDir = ?config(data_dir,Config),
+ ?line OutDir = ?config(priv_dir,Config),
+ ?line true = code:add_patha(?config(priv_dir,Config)),
+
+ ?line ok = asn1ct:compile(DataDir ++
+ "SSL-PKIX",[Rules,{outdir,OutDir},{i,DataDir},
+ {i,OutDir}]++Options),
+ ?line ok = asn1ct:compile(DataDir ++ "PKIXAttributeCertificate",
+ [Rules,{outdir,OutDir},{i,DataDir},
+ {i,OutDir}]++Options),
+ %% test case for OTP-4792 optional open type
+ ?line ok = asn1ct:compile(DataDir ++ "PKIX1Algorithms88",
+ [Rules,{outdir,OutDir},{i,DataDir},
+ {i,OutDir}]++Options),
+ ?line ok = asn1ct:compile(DataDir ++ "PKIX1Explicit88",
+ [Rules,{outdir,OutDir},{i,DataDir},
+ {i,OutDir}]++Options),
+ ?line ok = asn1ct:compile(DataDir ++ "PKIX1Implicit88",
+ [Rules,{outdir,OutDir},{i,DataDir},
+ {i,OutDir}]++Options),
+ %% OTP-6698, OTP-6702
+ ?line ok = remove_db_files(OutDir),
+ ?line ok = asn1ct:compile(DataDir ++ "PKIX1Explicit93",
+ [Rules,{outdir,OutDir},{i,DataDir},
+ {i,OutDir}]++Options),
+ ?line ok = asn1ct:compile(DataDir ++ "PKIX1Implicit93",
+ [Rules,{outdir,OutDir},{i,DataDir},
+ {i,OutDir}]++Options).
+
+compile_inline(Config,Rule) ->
+ ?line DataDir = ?config(data_dir,Config),
+ ?line OutDir = ?config(priv_dir,Config),
+ ?line true = code:add_patha(?config(priv_dir,Config)),
+
+ case Rule of
+ BER when BER==ber_bin;BER==ber_bin_v2 ->
+ Options = [der,compact_bit_string,optimize,
+ asn1config,inline],
+ ?line ok = remove_db_file_inline(OutDir),
+ ?line ok = asn1ct:compile(DataDir ++ "OTP-PKIX.set.asn",
+ [Rule,{outdir,OutDir},{i,DataDir},
+ {i,OutDir}]++Options);
+ _ ->
+ ok
+ end.
+
+remove_db_files(Dir) ->
+ ?line ok = remove_db_file(Dir ++ "PKIX1Explicit93.asn1db"),
+ ?line ok = remove_db_file(Dir ++ "PKIX1Implicit93.asn1db").
+remove_db_file(File) ->
+ case file:delete(File) of
+ ok ->
+ ok;
+ {error,enoent} ->
+ ok;
+ Err ->
+ Err
+ end.
+
+remove_db_file_inline(Dir) ->
+ ?line ok = remove_db_file(Dir ++ "OTP-PKIX.asn1db"),
+ ?line ok = remove_db_file(Dir ++ "SSL-PKIX.asn1db"),
+ ?line ok = remove_db_file(Dir ++ "PKIXAttributeCertificate.asn1db"),
+ ?line ok = remove_db_file(Dir ++ "PKIX1Algorithms88.asn1db"),
+ ?line ok = remove_db_file(Dir ++ "PKIX1Explicit88.asn1db"),
+ ?line ok = remove_db_file(Dir ++ "PKIX1Implicit88.asn1db").
+
+run(BER) when BER==ber_bin;BER==ber_bin_v2 ->
+ run1(1);
+run(_) ->
+ ok.
+
+run1(6) ->
+ ?line f1(6),
+ ?line f2(6),
+%% ?line transform3(ex(7)),
+ ?line transform4(ex(7));
+run1(N) ->
+ ?line f1(N),
+ ?line f2(N),
+ run1(N+1).
+
+
+f1(N) ->
+ transform1(ex(N)).
+
+f2(N) ->
+ transform2(ex(N)).
+
+
+transform1(ATAV) ->
+ ?line {ok, ATAVEnc} = 'PKIX1Explicit88':encode('AttributeTypeAndValue',
+ATAV),
+ ?line {ok, _ATAVDec} = 'SSL-PKIX':decode('AttributeTypeAndValue',
+ list_to_binary(ATAVEnc)).
+
+transform2(ATAV) ->
+ ?line {ok, ATAVEnc} = 'PKIX1Explicit88':encode('AttributeTypeAndValue',
+ATAV),
+ ?line {ok, _ATAVDec} = 'PKIX1Explicit88':decode('AttributeTypeAndValue',
+ list_to_binary(ATAVEnc)).
+
+
+transform4(ATAV) ->
+ ?line {ok, ATAVEnc} = 'PKIX1Explicit88':encode('Attribute',
+ATAV),
+ ?line {ok, _ATAVDec} = 'PKIX1Explicit88':decode('Attribute',
+ list_to_binary(ATAVEnc)).
+
+
+ex(1) ->
+ {'AttributeTypeAndValue',
+ {2,5,4,3},
+ <<19,5,111,116,112,67,65>>};
+ex(2) ->
+ {'AttributeTypeAndValue',
+ {2,5,4,11},
+ <<19,10,69,114,108,97,110,103,32,79,84,80>>};
+ex(3) ->
+ {'AttributeTypeAndValue',
+ {2,5,4,10},
+ <<19,11,69,114,105,99,115,115,111,110,32,65,66>>};
+ex(4) ->
+ {'AttributeTypeAndValue',
+ {2,5,4,6},
+ <<19,2,83,69>>};
+ex(5) ->
+ {'AttributeTypeAndValue',
+ {2,5,4,7},
+ <<19,9,83,116,111,99,107,104,111,108,109>>};
+ex(6) ->
+ {'AttributeTypeAndValue',
+ {1,2,840,113549,1,9,1},
+ <<22,22,112,101,116,101,114,64,101,114,105,120,
+ 46,101,114,105,99,115,115,111,110,46,115,101>>};
+ex(7) ->
+ {'Attribute',
+ {1,2,840,113549,1,9,1},
+ [[19,5,111,116,112,67,65]]}.
+
+run_inline(Rule) when Rule==ber_bin;Rule==ber_bin_v2 ->
+ Cert = cert(),
+ ?line {ok,{'CertificatePKIX1Explicit88',{Type,UnDec},_,_}} = 'OTP-PKIX':decode_TBSCert_exclusive(Cert),
+ ?line {ok,_} = 'OTP-PKIX':decode_part(Type,UnDec),
+ ok;
+run_inline(_) ->
+ ok.
+
+cert() ->
+ <<48,130,3,200,48,130,3,49,160,3,2,1,2,2,1,1,48,13,6,9,42,134,72,134,247,13,1,1,5,5,0,48,129,134,49,17,48,15,6,3,85,4,3,19,8,101,114,108,97,110,103,67,65,49,19,48,17,6,3,85,4,11,19,10,69,114,108,97,110,103,32,79,84,80,49,20,48,18,6,3,85,4,10,19,11,69,114,105,99,115,115,111,110,32,65,66,49,18,48,16,6,3,85,4,7,19,9,83,116,111,99,107,104,111,108,109,49,11,48,9,6,3,85,4,6,19,2,83,69,49,37,48,35,6,9,42,134,72,134,247,13,1,9,1,22,22,112,101,116,101,114,64,101,114,105,120,46,101,114,105,99,115,115,111,110,46,115,101,48,30,23,13,48,55,48,53,48,57,49,50,51,52,48,57,90,23,13,49,55,48,51,49,55,49,50,51,52,48,57,90,48,129,131,49,14,48,12,6,3,85,4,3,19,5,111,116,112,67,65,49,19,48,17,6,3,85,4,11,19,10,69,114,108,97,110,103,32,79,84,80,49,20,48,18,6,3,85,4,10,19,11,69,114,105,99,115,115,111,110,32,65,66,49,11,48,9,6,3,85,4,6,19,2,83,69,49,18,48,16,6,3,85,4,7,19,9,83,116,111,99,107,104,111,108,109,49,37,48,35,6,9,42,134,72,134,247,13,1,9,1,22,22,112,101,116,101,114,64,101,114,105,120,46,101,114,105,99,115,115,111,110,46,115,101,48,129,159,48,13,6,9,42,134,72,134,247,13,1,1,1,5,0,3,129,141,0,48,129,137,2,129,129,0,157,223,214,78,61,218,253,253,143,253,54,171,133,60,170,135,118,35,37,238,208,160,209,6,115,228,99,139,202,32,226,243,181,251,216,20,154,56,18,225,158,17,46,210,88,80,0,60,121,125,159,116,98,206,192,243,95,213,5,117,140,217,211,69,105,70,208,53,132,33,120,233,97,86,136,39,245,36,220,204,187,171,125,193,169,250,123,3,63,220,240,216,136,151,176,255,7,53,55,204,234,104,24,222,232,46,29,88,7,239,183,95,210,202,244,125,106,169,225,181,128,13,22,216,15,150,203,147,2,3,1,0,1,163,130,1,69,48,130,1,65,48,15,6,3,85,29,19,1,1,255,4,5,48,3,1,1,255,48,11,6,3,85,29,15,4,4,3,2,1,6,48,29,6,3,85,29,14,4,22,4,20,59,42,225,69,198,245,160,224,205,23,100,154,109,139,92,188,255,177,162,7,48,129,187,6,3,85,29,35,4,129,179,48,129,176,128,20,138,222,66,214,242,39,254,232,217,84,224,143,206,167,0,167,118,166,219,135,161,129,140,164,129,137,48,129,134,49,17,48,15,6,3,85,4,3,19,8,101,114,108,97,110,103,67,65,49,19,48,17,6,3,85,4,11,19,10,69,114,108,97,110,103,32,79,84,80,49,20,48,18,6,3,85,4,10,19,11,69,114,105,99,115,115,111,110,32,65,66,49,18,48,16,6,3,85,4,7,19,9,83,116,111,99,107,104,111,108,109,49,11,48,9,6,3,85,4,6,19,2,83,69,49,37,48,35,6,9,42,134,72,134,247,13,1,9,1,22,22,112,101,116,101,114,64,101,114,105,120,46,101,114,105,99,115,115,111,110,46,115,101,130,9,0,217,241,90,207,3,129,188,250,48,33,6,3,85,29,17,4,26,48,24,129,22,112,101,116,101,114,64,101,114,105,120,46,101,114,105,99,115,115,111,110,46,115,101,48,33,6,3,85,29,18,4,26,48,24,129,22,112,101,116,101,114,64,101,114,105,120,46,101,114,105,99,115,115,111,110,46,115,101,48,13,6,9,42,134,72,134,247,13,1,1,5,5,0,3,129,129,0,0,193,166,44,175,85,39,236,34,138,64,208,1,244,50,147,73,0,236,172,244,6,127,14,70,113,79,176,212,170,65,159,232,153,234,253,158,17,92,249,196,102,83,116,186,67,168,95,132,65,228,190,78,11,64,75,215,73,156,223,193,46,166,11,227,106,39,133,232,175,223,75,14,232,178,210,122,70,245,18,164,65,151,44,129,3,10,20,92,251,69,230,208,30,203,65,238,140,95,48,130,202,173,28,84,253,42,18,56,47,248,152,156,171,214,37,41,155,205,230,251,98,118,164,239,246,216,66>>.
diff --git a/lib/asn1/test/testSelectionTypes.erl b/lib/asn1/test/testSelectionTypes.erl
new file mode 100644
index 0000000000..a3876c259e
--- /dev/null
+++ b/lib/asn1/test/testSelectionTypes.erl
@@ -0,0 +1,45 @@
+%%
+%% %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(testSelectionTypes).
+
+-export([compile/3]).
+-export([test/0]).
+
+-include("test_server.hrl").
+
+
+compile(Config,Rule,Options) ->
+ ?line DataDir = ?config(data_dir,Config),
+ ?line OutDir = ?config(priv_dir,Config),
+ ?line true = code:add_patha(?config(priv_dir,Config)),
+ ?line ok = asn1ct:compile(DataDir ++ "SelectionType",
+ [Rule,{outdir,OutDir}]++Options).
+
+test() ->
+ Val = ["PrintableString","PrintableString","PrintableString"],
+ ?line {ok,Bin}=asn1_wrapper:encode('SelectionType','MendeleyevTable',Val),
+ ?line {ok,Val} = asn1_wrapper:decode('SelectionType','MendeleyevTable',Bin),
+
+ ?line Val2 = ['SelectionType':einsteinium()],
+ ?line ["Es"] = Val2,
+
+ ?line {ok,Bin2}=asn1_wrapper:encode('SelectionType','MendeleyevTable',Val2),
+ ?line {ok,Val2} = asn1_wrapper:decode('SelectionType','MendeleyevTable',Bin2).
+
diff --git a/lib/asn1/test/testSeq2738.erl b/lib/asn1/test/testSeq2738.erl
new file mode 100644
index 0000000000..0f3c4b7bf7
--- /dev/null
+++ b/lib/asn1/test/testSeq2738.erl
@@ -0,0 +1,53 @@
+%%
+%% %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(testSeq2738).
+
+-export([compile/3]).
+-export([main/1]).
+
+-include("test_server.hrl").
+
+%-record('SeqOpt',{int, opt = asn1_NOVALUE}).
+-record('SeqOptFake',{int, opt = asn1_NOVALUE}).
+%-record('OptSeq',{int=17}).
+-record('OptSeqFake',{bool = false}).
+
+
+
+
+compile(Config,Rules,Options) ->
+
+ ?line DataDir = ?config(data_dir,Config),
+ ?line OutDir = ?config(priv_dir,Config),
+ ?line true = code:add_patha(?config(priv_dir,Config)),
+ ?line ok = asn1ct:compile(DataDir ++ "Seq2738",[Rules,{outdir,OutDir}]++Options).
+
+
+main(_Rules) ->
+
+ ?line {ok,Bytes} =
+ asn1_wrapper:encode('Seq2738','SeqOptFake',
+ #'SeqOptFake'{int = 10,
+ opt = #'OptSeqFake'{}}),
+ ?line {ok,#'SeqOptFake'{int=10,opt=#'OptSeqFake'{bool=false}}} =
+ asn1_wrapper:decode('Seq2738','SeqOptFake',lists:flatten(Bytes)),
+ ?line {error,_} =
+ asn1_wrapper:decode('Seq2738','SeqOpt',lists:flatten(Bytes)),
+ ok.
diff --git a/lib/asn1/test/testSeqDefault.erl b/lib/asn1/test/testSeqDefault.erl
new file mode 100644
index 0000000000..a626bfd645
--- /dev/null
+++ b/lib/asn1/test/testSeqDefault.erl
@@ -0,0 +1,190 @@
+%%
+%% %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(testSeqDefault).
+
+-include("External.hrl").
+-export([compile/3]).
+-export([main/1]).
+
+-include("test_server.hrl").
+
+-record('SeqDef1',{bool1 = asn1_DEFAULT, int1, seq1 = asn1_DEFAULT}).
+-record('SeqDef1Imp',{bool1 = asn1_DEFAULT, int1, seq1 = asn1_DEFAULT}).
+-record('SeqDef1Exp',{bool1 = asn1_DEFAULT, int1, seq1 = asn1_DEFAULT}).
+-record('SeqDef2',{seq2 = asn1_DEFAULT, bool2 = asn1_DEFAULT, int2}).
+-record('SeqDef2Imp',{seq2 = asn1_DEFAULT, bool2 = asn1_DEFAULT, int2}).
+-record('SeqDef2Exp',{seq2 = asn1_DEFAULT, bool2, int2}).
+-record('SeqDef3',{bool3 = asn1_DEFAULT, seq3 = asn1_DEFAULT, int3 = asn1_DEFAULT}).
+-record('SeqDef3Imp',{bool3 = asn1_DEFAULT, seq3 = asn1_DEFAULT, int3 = asn1_DEFAULT}).
+-record('SeqDef3Exp',{bool3 = asn1_DEFAULT, seq3 = asn1_DEFAULT, int3 = asn1_DEFAULT}).
+-record('SeqIn',{boolIn, intIn}).
+
+
+compile(Config,Rules,Options) ->
+
+ ?line DataDir = ?config(data_dir,Config),
+ ?line OutDir = ?config(priv_dir,Config),
+ ?line true = code:add_patha(?config(priv_dir,Config)),
+ ?line ok = asn1ct:compile(DataDir ++ "SeqDefault",[Rules,{outdir,OutDir}]++Options).
+
+
+
+main(_Rules) ->
+
+ ?line {ok,Bytes11} =
+ asn1_wrapper:encode('SeqDefault','SeqDef1',#'SeqDef1'{bool1 = true,
+ int1 = 15,
+ seq1 = #'SeqIn'{boolIn = true,
+ intIn = 66}}),
+ ?line {ok,{'SeqDef1',true,15,{'SeqIn',true,66}}} =
+ asn1_wrapper:decode('SeqDefault','SeqDef1',lists:flatten(Bytes11)),
+
+
+ ?line {ok,Bytes12} = asn1_wrapper:encode('SeqDefault','SeqDef1',#'SeqDef1'{int1 = 15}),
+ ?line {ok,{'SeqDef1',true,15,{'SeqIn',asn1_NOVALUE,12}}} =
+ asn1_wrapper:decode('SeqDefault','SeqDef1',lists:flatten(Bytes12)),
+
+
+ ?line {ok,Bytes21} =
+ asn1_wrapper:encode('SeqDefault','SeqDef2',#'SeqDef2'{bool2 = true,
+ int2 = 15,
+ seq2 = #'SeqIn'{boolIn = true,
+ intIn = 66}}),
+ ?line {ok,{'SeqDef2',{'SeqIn',true,66},true,15}} =
+ asn1_wrapper:decode('SeqDefault','SeqDef2',lists:flatten(Bytes21)),
+
+
+ ?line {ok,Bytes22} = asn1_wrapper:encode('SeqDefault','SeqDef2',#'SeqDef2'{int2 = 15}),
+ ?line {ok,{'SeqDef2',{'SeqIn',asn1_NOVALUE,12},true,15}} =
+ asn1_wrapper:decode('SeqDefault','SeqDef2',lists:flatten(Bytes22)),
+
+
+
+ ?line {ok,Bytes31} =
+ asn1_wrapper:encode('SeqDefault','SeqDef3',#'SeqDef3'{bool3 = true,
+ int3 = 15,
+ seq3 = #'SeqIn'{boolIn = true,
+ intIn = 66}}),
+ ?line {ok,{'SeqDef3',true,{'SeqIn',true,66},15}} =
+ asn1_wrapper:decode('SeqDefault','SeqDef3',lists:flatten(Bytes31)),
+
+
+ ?line {ok,Bytes32} = asn1_wrapper:encode('SeqDefault','SeqDef3',#'SeqDef3'{int3 = 15}),
+ ?line {ok,{'SeqDef3',true,{'SeqIn',asn1_NOVALUE,12},15}} =
+ asn1_wrapper:decode('SeqDefault','SeqDef3',lists:flatten(Bytes32)),
+
+
+
+
+
+ ?line {ok,Bytes41} =
+ asn1_wrapper:encode('SeqDefault','SeqDef1Imp',#'SeqDef1Imp'{bool1 = true,
+ int1 = 15,
+ seq1 = #'SeqIn'{boolIn = true,
+ intIn = 66}}),
+ ?line {ok,{'SeqDef1Imp',true,15,{'SeqIn',true,66}}} =
+ asn1_wrapper:decode('SeqDefault','SeqDef1Imp',lists:flatten(Bytes41)),
+
+
+ ?line {ok,Bytes42} = asn1_wrapper:encode('SeqDefault','SeqDef1Imp',#'SeqDef1Imp'{int1 = 15}),
+ ?line {ok,{'SeqDef1Imp',true,15,{'SeqIn',asn1_NOVALUE,12}}} =
+ asn1_wrapper:decode('SeqDefault','SeqDef1Imp',lists:flatten(Bytes42)),
+
+
+ ?line {ok,Bytes51} =
+ asn1_wrapper:encode('SeqDefault','SeqDef2Imp',#'SeqDef2Imp'{bool2 = true,
+ int2 = 15,
+ seq2 = #'SeqIn'{boolIn = true,
+ intIn = 66}}),
+ ?line {ok,{'SeqDef2Imp',{'SeqIn',true,66},true,15}} =
+ asn1_wrapper:decode('SeqDefault','SeqDef2Imp',lists:flatten(Bytes51)),
+
+
+ ?line {ok,Bytes52} = asn1_wrapper:encode('SeqDefault','SeqDef2Imp',#'SeqDef2Imp'{int2 = 15}),
+ ?line {ok,{'SeqDef2Imp',{'SeqIn',asn1_NOVALUE,12},true,15}} =
+ asn1_wrapper:decode('SeqDefault','SeqDef2Imp',lists:flatten(Bytes52)),
+
+
+
+ ?line {ok,Bytes61} =
+ asn1_wrapper:encode('SeqDefault','SeqDef3Imp',#'SeqDef3Imp'{bool3 = true,
+ int3 = 15,
+ seq3 = #'SeqIn'{boolIn = true,
+ intIn = 66}}),
+ ?line {ok,{'SeqDef3Imp',true,{'SeqIn',true,66},15}} =
+ asn1_wrapper:decode('SeqDefault','SeqDef3Imp',lists:flatten(Bytes61)),
+
+
+ ?line {ok,Bytes62} = asn1_wrapper:encode('SeqDefault','SeqDef3Imp',#'SeqDef3Imp'{int3 = 15}),
+ ?line {ok,{'SeqDef3Imp',true,{'SeqIn',asn1_NOVALUE,12},15}} =
+ asn1_wrapper:decode('SeqDefault','SeqDef3Imp',lists:flatten(Bytes62)),
+
+
+
+
+
+
+ ?line {ok,Bytes71} =
+ asn1_wrapper:encode('SeqDefault','SeqDef1Exp',#'SeqDef1Exp'{bool1 = true,
+ int1 = 15,
+ seq1 = #'SeqIn'{boolIn = true,
+ intIn = 66}}),
+ ?line {ok,{'SeqDef1Exp',true,15,{'SeqIn',true,66}}} =
+ asn1_wrapper:decode('SeqDefault','SeqDef1Exp',lists:flatten(Bytes71)),
+
+
+ ?line {ok,Bytes72} = asn1_wrapper:encode('SeqDefault','SeqDef1Exp',#'SeqDef1Exp'{int1 = 15}),
+ ?line {ok,{'SeqDef1Exp',true,15,{'SeqIn',asn1_NOVALUE,12}}} =
+ asn1_wrapper:decode('SeqDefault','SeqDef1Exp',lists:flatten(Bytes72)),
+
+
+ ?line {ok,Bytes81} =
+ asn1_wrapper:encode('SeqDefault','SeqDef2Exp',#'SeqDef2Exp'{bool2 = true,
+ int2 = 15,
+ seq2 = #'SeqIn'{boolIn = true,
+ intIn = 66}}),
+ ?line {ok,{'SeqDef2Exp',{'SeqIn',true,66},true,15}} =
+ asn1_wrapper:decode('SeqDefault','SeqDef2Exp',lists:flatten(Bytes81)),
+
+
+ ?line {ok,Bytes82} = asn1_wrapper:encode('SeqDefault','SeqDef2Exp',#'SeqDef2Exp'{int2 = 15,
+ bool2 = true}),
+ ?line {ok,{'SeqDef2Exp',{'SeqIn',asn1_NOVALUE,12},true,15}} =
+ asn1_wrapper:decode('SeqDefault','SeqDef2Exp',lists:flatten(Bytes82)),
+
+
+
+ ?line {ok,Bytes91} =
+ asn1_wrapper:encode('SeqDefault','SeqDef3Exp',#'SeqDef3Exp'{bool3 = true,
+ int3 = 15,
+ seq3 = #'SeqIn'{boolIn = true,
+ intIn = 66}}),
+ ?line {ok,{'SeqDef3Exp',true,{'SeqIn',true,66},15}} =
+ asn1_wrapper:decode('SeqDefault','SeqDef3Exp',lists:flatten(Bytes91)),
+
+
+ ?line {ok,Bytes92} = asn1_wrapper:encode('SeqDefault','SeqDef3Exp',#'SeqDef3Exp'{int3 = 15}),
+ ?line {ok,{'SeqDef3Exp',true,{'SeqIn',asn1_NOVALUE,12},15}} =
+ asn1_wrapper:decode('SeqDefault','SeqDef3Exp',lists:flatten(Bytes92)),
+
+
+
+
+ ok.
diff --git a/lib/asn1/test/testSeqExtension.erl b/lib/asn1/test/testSeqExtension.erl
new file mode 100644
index 0000000000..4ddaddb8f1
--- /dev/null
+++ b/lib/asn1/test/testSeqExtension.erl
@@ -0,0 +1,108 @@
+%%
+%% %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(testSeqExtension).
+
+-include("External.hrl").
+-export([compile/3]).
+-export([main/1]).
+
+-include("test_server.hrl").
+
+-record('SeqExt1',{}).
+-record('SeqExt2',{bool, int}).
+-record('SeqExt3',{bool, int}).
+-record('SeqExt4',{bool, int}).
+
+
+compile(Config,Rules,Options) ->
+
+ ?line DataDir = ?config(data_dir,Config),
+ ?line OutDir = ?config(priv_dir,Config),
+ ?line true = code:add_patha(?config(priv_dir,Config)),
+ ?line ok = asn1ct:compile(DataDir ++ "SeqExtension",
+ [Rules,{outdir,OutDir}]++Options).
+
+
+
+main(_Rules) ->
+
+ ?line {ok,Bytes11} =
+ asn1_wrapper:encode('SeqExtension','SeqExt1',#'SeqExt1'{}),
+ ?line {ok,{'SeqExt1'}} =
+ asn1_wrapper:decode('SeqExtension','SeqExt1',lists:flatten(Bytes11)),
+
+ ?line {ok,Bytes21} =
+ asn1_wrapper:encode('SeqExtension','SeqExt2',#'SeqExt2'{bool = true,int = 99}),
+ ?line {ok,{'SeqExt2',true,99}} =
+ asn1_wrapper:decode('SeqExtension','SeqExt2',lists:flatten(Bytes21)),
+
+ ?line {ok,Bytes22} =
+ asn1_wrapper:encode('SeqExtension','SeqExt2',#'SeqExt2'{int = 99,bool = true}),
+ ?line {ok,{'SeqExt2',true,99}} =
+ asn1_wrapper:decode('SeqExtension','SeqExt2',lists:flatten(Bytes22)),
+
+ ?line {ok,Bytes31} =
+ asn1_wrapper:encode('SeqExtension','SeqExt3',#'SeqExt3'{bool = true,int = 99}),
+ ?line {ok,{'SeqExt3',true,99}} =
+ asn1_wrapper:decode('SeqExtension','SeqExt3',lists:flatten(Bytes31)),
+
+ ?line {ok,Bytes32} =
+ asn1_wrapper:encode('SeqExtension','SeqExt3',#'SeqExt3'{int = 99,bool = true}),
+ ?line {ok,{'SeqExt3',true,99}} =
+ asn1_wrapper:decode('SeqExtension','SeqExt3',lists:flatten(Bytes32)),
+
+ ?line {ok,Bytes41} =
+ asn1_wrapper:encode('SeqExtension','SeqExt4',#'SeqExt4'{bool = true,int = 99}),
+ ?line {ok,{'SeqExt4',true,99}} =
+ asn1_wrapper:decode('SeqExtension','SeqExt4',lists:flatten(Bytes41)),
+
+ ?line {ok,Bytes42} =
+ asn1_wrapper:encode('SeqExtension','SeqExt4',#'SeqExt4'{int = 99,bool = true}),
+ ?line {ok,{'SeqExt4',true,99}} =
+ asn1_wrapper:decode('SeqExtension','SeqExt4',lists:flatten(Bytes42)),
+
+
+ % test of extension , not ready
+
+ ?line {ok,BytesX11} =
+ asn1_wrapper:encode('SeqExtension','SeqExt1',#'SeqExt1'{}),
+ ?line {ok,{'SeqExt1'}} =
+ asn1_wrapper:decode('SeqExtension','SeqExt1',lists:flatten(BytesX11)),
+
+ ?line {ok,BytesX21} =
+ asn1_wrapper:encode('SeqExtension','SeqExt2',#'SeqExt2'{bool = true,int = 99}),
+ ?line {ok,{'SeqExt2',true,99}} =
+ asn1_wrapper:decode('SeqExtension','SeqExt2',lists:flatten(BytesX21)),
+
+ ?line {ok,BytesX22} =
+ asn1_wrapper:encode('SeqExtension','SeqExt2',#'SeqExt2'{int = 99,bool = true}),
+ ?line {ok,{'SeqExt2',true,99}} =
+ asn1_wrapper:decode('SeqExtension','SeqExt2',lists:flatten(BytesX22)),
+
+
+
+
+
+ ok.
+
+
+
+
+
diff --git a/lib/asn1/test/testSeqExternal.erl b/lib/asn1/test/testSeqExternal.erl
new file mode 100644
index 0000000000..f148d32b21
--- /dev/null
+++ b/lib/asn1/test/testSeqExternal.erl
@@ -0,0 +1,140 @@
+%%
+%% %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(testSeqExternal).
+
+-include("External.hrl").
+-export([compile/3]).
+-export([main/1]).
+
+-include("test_server.hrl").
+
+
+-record('SeqXSet1',{set, bool, int}).
+-record('SeqXSet2',{bool, set, int}).
+-record('SeqXSet3',{bool, int, set}).
+%-record('NT',{os, bool}).
+%-record('Imp',{os, bool}).
+%-record('Exp',{os, bool}).
+
+
+compile(Config,Rules,Options) ->
+
+ ?line DataDir = ?config(data_dir,Config),
+ ?line OutDir = ?config(priv_dir,Config),
+ ?line true = code:add_patha(?config(priv_dir,Config)),
+ ?line ok = asn1ct:compile(DataDir ++ "SeqExternal",
+ [Rules,{outdir,OutDir}]++Options).
+
+
+
+main(_Rules) ->
+
+ ?line {ok,Bytes11} =
+ asn1_wrapper:encode('SeqExternal','XNTNT',#'XSeqNT'{bool = true, os = "kalle"}),
+ ?line {ok,{'XSeqNT',[107,97,108,108,101],true}} =
+ asn1_wrapper:decode('SeqExternal','XNTNT',lists:flatten(Bytes11)),
+
+ ?line {ok,Bytes12} =
+ asn1_wrapper:encode('SeqExternal','XImpNT',#'XSeqNT'{bool = true, os = "kalle"}),
+ ?line {ok,{'XSeqNT',[107,97,108,108,101],true}} =
+ asn1_wrapper:decode('SeqExternal','XImpNT',lists:flatten(Bytes12)),
+
+ ?line {ok,Bytes13} =
+ asn1_wrapper:encode('SeqExternal','XExpNT',#'XSeqNT'{bool = true, os = "kalle"}),
+ ?line {ok,{'XSeqNT',[107,97,108,108,101],true}} =
+ asn1_wrapper:decode('SeqExternal','XExpNT',lists:flatten(Bytes13)),
+
+
+
+ ?line {ok,Bytes21} =
+ asn1_wrapper:encode('SeqExternal','XNTImp',#'XSeqImp'{bool = true, os = "kalle"}),
+ ?line {ok,{'XSeqImp',[107,97,108,108,101],true}} =
+ asn1_wrapper:decode('SeqExternal','XNTImp',lists:flatten(Bytes21)),
+
+ ?line {ok,Bytes22} =
+ asn1_wrapper:encode('SeqExternal','XImpImp',#'XSeqImp'{bool = true, os = "kalle"}),
+ ?line {ok,{'XSeqImp',[107,97,108,108,101],true}} =
+ asn1_wrapper:decode('SeqExternal','XImpImp',lists:flatten(Bytes22)),
+
+ ?line {ok,Bytes23} =
+ asn1_wrapper:encode('SeqExternal','XExpImp',#'XSeqImp'{bool = true, os = "kalle"}),
+ ?line {ok,{'XSeqImp',[107,97,108,108,101],true}} =
+ asn1_wrapper:decode('SeqExternal','XExpImp',lists:flatten(Bytes23)),
+
+
+
+ ?line {ok,Bytes31} =
+ asn1_wrapper:encode('SeqExternal','XNTExp',#'XSeqExp'{bool = true, os = "kalle"}),
+ ?line {ok,{'XSeqExp',[107,97,108,108,101],true}} =
+ asn1_wrapper:decode('SeqExternal','XNTExp',lists:flatten(Bytes31)),
+
+ ?line {ok,Bytes32} =
+ asn1_wrapper:encode('SeqExternal','XImpExp',#'XSeqExp'{bool = true, os = "kalle"}),
+ ?line {ok,{'XSeqExp',[107,97,108,108,101],true}} =
+ asn1_wrapper:decode('SeqExternal','XImpExp',lists:flatten(Bytes32)),
+
+ ?line {ok,Bytes33} =
+ asn1_wrapper:encode('SeqExternal','XExpExp',#'XSeqExp'{bool = true, os = "kalle"}),
+ ?line {ok,{'XSeqExp',[107,97,108,108,101],true}} =
+ asn1_wrapper:decode('SeqExternal','XExpExp',lists:flatten(Bytes33)),
+
+
+
+ ?line {ok,Bytes41} =
+ asn1_wrapper:encode('SeqExternal','SeqXSet1',
+ #'SeqXSet1'{bool = true,
+ int = 66,
+ set = #'XSet1'{bool1 = true,
+ int1 = 77,
+ set1 = #'XSetIn'{boolIn = false,
+ intIn = 88}}}),
+ ?line {ok,{'SeqXSet1',{'XSet1',true,77,{'XSetIn',false,88}},true,66}} =
+ asn1_wrapper:decode('SeqExternal','SeqXSet1',lists:flatten(Bytes41)),
+
+
+
+ ?line {ok,Bytes42} =
+ asn1_wrapper:encode('SeqExternal','SeqXSet2',
+ #'SeqXSet2'{bool = true,
+ int = 66,
+ set = #'XSet1'{bool1 = true,
+ int1 = 77,
+ set1 = #'XSetIn'{boolIn = false,
+ intIn = 88}}}),
+ ?line {ok,{'SeqXSet2',true,{'XSet1',true,77,{'XSetIn',false,88}},66}} =
+ asn1_wrapper:decode('SeqExternal','SeqXSet2',lists:flatten(Bytes42)),
+
+ ?line {ok,Bytes43} =
+ asn1_wrapper:encode('SeqExternal','SeqXSet3',
+ #'SeqXSet3'{bool = true,
+ int = 66,
+ set = #'XSet1'{bool1 = true,
+ int1 = 77,
+ set1 = #'XSetIn'{boolIn = false,
+ intIn = 88}}}),
+ ?line {ok,{'SeqXSet3',true,66,{'XSet1',true,77,{'XSetIn',false,88}}}} =
+ asn1_wrapper:decode('SeqExternal','SeqXSet3',lists:flatten(Bytes43)),
+
+
+
+
+ ok.
+
+
diff --git a/lib/asn1/test/testSeqIndefinite.erl b/lib/asn1/test/testSeqIndefinite.erl
new file mode 100644
index 0000000000..b1b622bdfa
--- /dev/null
+++ b/lib/asn1/test/testSeqIndefinite.erl
@@ -0,0 +1,63 @@
+%%
+%% %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(testSeqIndefinite).
+
+-export([compile/3]).
+-export([main/1]).
+
+-include("test_server.hrl").
+
+
+compile(Config,Rules,Options) ->
+
+ ?line DataDir = ?config(data_dir,Config),
+ ?line OutDir = ?config(priv_dir,Config),
+ ?line true = code:add_patha(?config(priv_dir,Config)),
+ ?line ok = asn1ct:compile(DataDir ++ "SeqSetIndefinite",
+ [Rules,{outdir,OutDir}]++Options).
+
+main(per_bin) -> ok;
+main(per) -> ok;
+main(ber_bin_v2) ->
+ main(ber);
+main(ber_bin) ->
+ main(ber);
+main(ber) ->
+
+ %% normal encoding
+ B = [48,20,1,1,255,48,9,1,1,255,2,4,251,35,238,194,2,4,251,55,236,161],
+ %% indefinite length encoding
+ Bi = [48,22,1,1,255,48,128,1,1,255,2,4,251,35,238,194,0,0,2,4,251,55,236,161],
+ %% the value which is encoded
+ V = {'SeqS3',true,{'SeqS3_seqS3',true,-81531198},-80221023},
+ ?line {ok,V} = asn1_wrapper:decode('SeqSetIndefinite','SeqS3',B),
+ ?line {ok,V} = asn1_wrapper:decode('SeqSetIndefinite','SeqS3',Bi),
+
+ %% normal encoding but with unknown extension component
+ _Be = [48,23,1,1,255,48,12,1,1,255,2,4,251,35,238,194,1,1,255,2,4,251,55,236,161],
+ %% indefinite length encoding but with unknown extension component
+ _Bei = [48,25,1,1,255,48,128,1,1,255,2,4,251,35,238,194,1,1,255,0,0,2,4,251,55,236,161],
+
+ ?line {ok,V} = asn1_wrapper:decode('SeqSetIndefinite','SeqS3',B),
+ ?line {ok,V} = asn1_wrapper:decode('SeqSetIndefinite','SeqS3',Bi),
+ ok.
+
+
+
diff --git a/lib/asn1/test/testSeqOf.erl b/lib/asn1/test/testSeqOf.erl
new file mode 100644
index 0000000000..71556ed746
--- /dev/null
+++ b/lib/asn1/test/testSeqOf.erl
@@ -0,0 +1,242 @@
+%%
+%% %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(testSeqOf).
+
+-export([compile/3]).
+-export([main/1]).
+
+-include("test_server.hrl").
+
+-record('Seq1',{bool1, int1, seq1 = asn1_DEFAULT}).
+-record('Seq2',{seq2 = asn1_DEFAULT, bool2, int2}).
+-record('Seq3',{bool3, seq3 = asn1_DEFAULT, int3}).
+-record('Seq4',{seq41 = asn1_DEFAULT, seq42 = asn1_DEFAULT, seq43 = asn1_DEFAULT}).
+-record('SeqIn',{boolIn, intIn}).
+%-record('SeqCho',{bool1, int1, seq1 = asn1_DEFAULT}).
+%-record('SeqChoInline',{bool1, int1, seq1 = asn1_DEFAULT}).
+%-record('SeqChoOfInline_SEQOF',{bool1, int1, seq1 = asn1_DEFAULT}).
+-record('SeqEmp',{seq1}).
+-record('Empty',{}).
+
+
+compile(Config,Rules,Options) ->
+
+ ?line DataDir = ?config(data_dir,Config),
+ ?line OutDir = ?config(priv_dir,Config),
+ ?line true = code:add_patha(?config(priv_dir,Config)),
+ ?line ok = asn1ct:compile(DataDir ++ "SeqOf",[Rules,{outdir,OutDir}]++Options),
+ ?line ok = asn1ct:compile(DataDir ++ "SeqOfEnum",[Rules,{outdir,OutDir}]++Options),
+ ?line ok = asn1ct:compile(DataDir ++ "XSeqOf",[Rules,{outdir,OutDir}]++Options).
+
+
+
+main(Rules) ->
+
+ ?line {ok,Bytes11} =
+ asn1_wrapper:encode('SeqOf','Seq1',#'Seq1'{bool1 = true,
+ int1 = 17}),
+ ?line {ok,{'Seq1',true,17,[]}} =
+ asn1_wrapper:decode('SeqOf','Seq1',lists:flatten(Bytes11)),
+
+
+ ?line {ok,Bytes12} =
+ asn1_wrapper:encode('SeqOf','Seq1',#'Seq1'{bool1 = true,
+ int1 = 17,
+ seq1 = [#'SeqIn'{boolIn = true,
+ intIn = 25}]}),
+ ?line {ok,{'Seq1',true,17,[{'SeqIn',true,25}]}} =
+ asn1_wrapper:decode('SeqOf','Seq1',lists:flatten(Bytes12)),
+
+
+
+ ?line {ok,Bytes13} =
+ asn1_wrapper:encode('SeqOf','Seq1',#'Seq1'{bool1 = true,
+ int1 = 17,
+ seq1 = [#'SeqIn'{boolIn = true,
+ intIn = 25},
+ #'SeqIn'{boolIn = false,
+ intIn = 125},
+ #'SeqIn'{boolIn = false,
+ intIn = 225}]}),
+ ?line {ok,{'Seq1',true,17,[{'SeqIn',true,25},{'SeqIn',false,125},{'SeqIn',false,225}]}} =
+ asn1_wrapper:decode('SeqOf','Seq1',lists:flatten(Bytes13)),
+
+
+
+
+
+
+ ?line {ok,Bytes21} =
+ asn1_wrapper:encode('SeqOf','Seq2',#'Seq2'{bool2 = true,
+ int2 = 17}),
+
+ ?line {ok,{'Seq2',[],true,17}} =
+ asn1_wrapper:decode('SeqOf','Seq2',lists:flatten(Bytes21)),
+
+
+ ?line {ok,Bytes22} =
+ asn1_wrapper:encode('SeqOf','Seq2',#'Seq2'{bool2 = true,
+ int2 = 17,
+ seq2 = [#'SeqIn'{boolIn = true,
+ intIn = 25}]}),
+ ?line {ok,{'Seq2',[{'SeqIn',true,25}],true,17}} =
+ asn1_wrapper:decode('SeqOf','Seq2',lists:flatten(Bytes22)),
+
+
+ ?line {ok,Bytes23} =
+ asn1_wrapper:encode('SeqOf','Seq2',#'Seq2'{bool2 = true,
+ int2 = 17,
+ seq2 = [#'SeqIn'{boolIn = true,
+ intIn = 25},
+ #'SeqIn'{boolIn = false,
+ intIn = 125},
+ #'SeqIn'{boolIn = false,
+ intIn = 225}]}),
+ ?line {ok,{'Seq2',[{'SeqIn',true,25},{'SeqIn',false,125},{'SeqIn',false,225}],true,17}} =
+ asn1_wrapper:decode('SeqOf','Seq2',lists:flatten(Bytes23)),
+
+
+
+
+
+
+ ?line {ok,Bytes31} =
+ asn1_wrapper:encode('SeqOf','Seq3',#'Seq3'{bool3 = true,
+ int3 = 17}),
+ ?line {ok,{'Seq3',true,[],17}} =
+ asn1_wrapper:decode('SeqOf','Seq3',lists:flatten(Bytes31)),
+
+
+ ?line {ok,Bytes32} =
+ asn1_wrapper:encode('SeqOf','Seq3',#'Seq3'{bool3 = true,
+ int3 = 17,
+ seq3 = [#'SeqIn'{boolIn = true,
+ intIn = 25}]}),
+ ?line {ok,{'Seq3',true,[{'SeqIn',true,25}],17}} =
+ asn1_wrapper:decode('SeqOf','Seq3',lists:flatten(Bytes32)),
+
+
+ ?line {ok,Bytes33} =
+ asn1_wrapper:encode('SeqOf','Seq3',#'Seq3'{bool3 = true,
+ int3 = 17,
+ seq3 = [#'SeqIn'{boolIn = true,
+ intIn = 25},
+ #'SeqIn'{boolIn = false,
+ intIn = 125},
+ #'SeqIn'{boolIn = false,
+ intIn = 225}]}),
+ ?line {ok,{'Seq3',true,[{'SeqIn',true,25},{'SeqIn',false,125},{'SeqIn',false,225}],17}} =
+ asn1_wrapper:decode('SeqOf','Seq3',lists:flatten(Bytes33)),
+
+
+
+
+
+
+
+ ?line {ok,Bytes41} = asn1_wrapper:encode('SeqOf','Seq4',#'Seq4'{}),
+ ?line {ok,{'Seq4',[],[],[]}} = asn1_wrapper:decode('SeqOf','Seq4',lists:flatten(Bytes41)),
+
+
+ ?line {ok,Bytes42} =
+ asn1_wrapper:encode('SeqOf','Seq4',#'Seq4'{seq41 = [#'SeqIn'{boolIn = true,
+ intIn = 25}]}),
+ ?line {ok,{'Seq4',[{'SeqIn',true,25}],[],[]}} =
+ asn1_wrapper:decode('SeqOf','Seq4',lists:flatten(Bytes42)),
+
+
+ ?line {ok,Bytes43} =
+ asn1_wrapper:encode('SeqOf','Seq4',#'Seq4'{seq41 = [#'SeqIn'{boolIn = true,
+ intIn = 25},
+ #'SeqIn'{boolIn = false,
+ intIn = 125},
+ #'SeqIn'{boolIn = false,
+ intIn = 225}]}),
+ ?line {ok,{'Seq4',[{'SeqIn',true,25},{'SeqIn',false,125},{'SeqIn',false,225}],[],[]}} =
+ asn1_wrapper:decode('SeqOf','Seq4',lists:flatten(Bytes43)),
+
+
+ ?line {ok,Bytes44} =
+ asn1_wrapper:encode('SeqOf','Seq4',#'Seq4'{seq42 = [#'SeqIn'{boolIn = true,
+ intIn = 25}]}),
+ ?line {ok,{'Seq4',[],[{'SeqIn',true,25}],[]}} =
+ asn1_wrapper:decode('SeqOf','Seq4',lists:flatten(Bytes44)),
+
+
+ ?line {ok,Bytes45} =
+ asn1_wrapper:encode('SeqOf','Seq4',#'Seq4'{seq42 = [#'SeqIn'{boolIn = true,
+ intIn = 25},
+ #'SeqIn'{boolIn = false,
+ intIn = 125},
+ #'SeqIn'{boolIn = false,
+ intIn = 225}]}),
+ ?line {ok,{'Seq4',[],[{'SeqIn',true,25},{'SeqIn',false,125},{'SeqIn',false,225}],[]}} =
+ asn1_wrapper:decode('SeqOf','Seq4',lists:flatten(Bytes45)),
+
+
+ ?line {ok,Bytes46} =
+ asn1_wrapper:encode('SeqOf','Seq4',#'Seq4'{seq43 = [#'SeqIn'{boolIn = true,
+ intIn = 25}]}),
+ ?line {ok,{'Seq4',[],[],[{'SeqIn',true,25}]}} =
+ asn1_wrapper:decode('SeqOf','Seq4',lists:flatten(Bytes46)),
+
+
+ ?line {ok,Bytes47} =
+ asn1_wrapper:encode('SeqOf','Seq4',#'Seq4'{seq43 = [#'SeqIn'{boolIn = true,
+ intIn = 25},
+ #'SeqIn'{boolIn = false,
+ intIn = 125},
+ #'SeqIn'{boolIn = false,
+ intIn = 225}]}),
+ ?line {ok,{'Seq4',[],[],[{'SeqIn',true,25},{'SeqIn',false,125},{'SeqIn',false,225}]}} =
+ asn1_wrapper:decode('SeqOf','Seq4',lists:flatten(Bytes47)),
+
+
+ ?line {ok,Bytes51} = asn1_wrapper:encode('SeqOf','SeqEmp',#'SeqEmp'{seq1 = [#'Empty'{}]}),
+ ?line {ok,{'SeqEmp',[{'Empty'}]}} = asn1_wrapper:decode('SeqOf','SeqEmp',lists:flatten(Bytes51)),
+
+ case Rules of
+ ber ->
+ ?line {ok,Bytes52} = asn1_wrapper:encode('SeqOfEnum','SeqOfEnum',
+ {'SeqOfEnum',[{'Enum',a},{'Enum',b}]}),
+ ?line {ok,[a,b]} = asn1_wrapper:decode('SeqOfEnum','SeqOfEnum',
+ lists:flatten(Bytes52));
+ _ -> ok
+ end,
+
+ %% tests of OTP-4590
+ case Rules of
+ PER when PER == per; PER == per_bin ->
+ DayNames = ["Monday","Tuesday","Wednesday","Thursday","Friday","Saturday","Sunday"],
+ ?line {ok,Bytes60} = asn1_wrapper:encode('XSeqOf','DayNames2',DayNames),
+ ?line {ok,Bytes60} = asn1_wrapper:encode('XSeqOf','DayNames4',DayNames),
+ ?line {ok,DayNames} = asn1_wrapper:decode('XSeqOf','DayNames2',Bytes60),
+ ?line {ok,DayNames} = asn1_wrapper:decode('XSeqOf','DayNames4',Bytes60),
+ ?line {ok,Bytes61} = asn1_wrapper:encode('XSeqOf','DayNames1',DayNames),
+ ?line {ok,Bytes61} = asn1_wrapper:encode('XSeqOf','DayNames3',DayNames),
+ ?line {ok,DayNames} = asn1_wrapper:decode('XSeqOf','DayNames1',Bytes61),
+ ?line {ok,DayNames} = asn1_wrapper:decode('XSeqOf','DayNames3',Bytes61);
+ _ ->
+ ok
+ end,
+
+ ok.
+
+
diff --git a/lib/asn1/test/testSeqOfCho.erl b/lib/asn1/test/testSeqOfCho.erl
new file mode 100644
index 0000000000..eefb258346
--- /dev/null
+++ b/lib/asn1/test/testSeqOfCho.erl
@@ -0,0 +1,159 @@
+%%
+%% %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(testSeqOfCho).
+
+-export([compile/3]).
+-export([main/1]).
+
+-include("test_server.hrl").
+
+-record('SeqChoDef',{bool1, int1, seq1 = asn1_DEFAULT}).
+-record('SeqChoOpt',{bool1, int1, seq1 = asn1_NOVALUE}).
+-record('SeqChoEmbDef',{bool1, int1, seq1 = asn1_DEFAULT}).
+-record('SeqChoEmbOpt',{bool1, int1, seq1 = asn1_NOVALUE}).
+-record('SeqOfChoEmbDef_SEQOF',{bool1, int1, seq1 = asn1_DEFAULT}).
+-record('SeqOfChoEmbOpt_SEQOF',{bool1, int1, seq1 = asn1_NOVALUE}).
+
+
+
+compile(Config,Rules,Options) ->
+
+ ?line DataDir = ?config(data_dir,Config),
+ ?line OutDir = ?config(priv_dir,Config),
+ ?line true = code:add_patha(?config(priv_dir,Config)),
+ ?line ok = asn1ct:compile(DataDir ++ "SeqOfCho",[Rules,{outdir,OutDir}]++Options).
+
+
+
+main(_Rules) ->
+
+ ?line {ok,Bytes11} =
+ asn1_wrapper:encode('SeqOfCho','SeqChoDef',#'SeqChoDef'{bool1 = true,
+ int1 = 17}),
+ ?line {ok,{'SeqChoDef',true,17,[]}} =
+ asn1_wrapper:decode('SeqOfCho','SeqChoDef',lists:flatten(Bytes11)),
+
+
+ ?line {ok,Bytes12} =
+ asn1_wrapper:encode('SeqOfCho','SeqChoDef',#'SeqChoDef'{bool1 = true,
+ int1 = 17,
+ seq1 = [{boolIn,true},
+ {intIn,25}]}),
+ ?line {ok,{'SeqChoDef',true,17,[{boolIn,true},{intIn,25}]}} =
+ asn1_wrapper:decode('SeqOfCho','SeqChoDef',lists:flatten(Bytes12)),
+
+
+
+ ?line {ok,Bytes15} =
+ asn1_wrapper:encode('SeqOfCho','SeqChoOpt',#'SeqChoOpt'{bool1 = true,
+ int1 = 17}),
+ ?line {ok,{'SeqChoOpt',true,17,asn1_NOVALUE}} =
+ asn1_wrapper:decode('SeqOfCho','SeqChoOpt',lists:flatten(Bytes15)),
+
+
+ ?line {ok,Bytes16} =
+ asn1_wrapper:encode('SeqOfCho','SeqChoOpt',#'SeqChoOpt'{bool1 = true,
+ int1 = 17,
+ seq1 = [{boolIn,true},
+ {intIn,25}]}),
+ ?line {ok,{'SeqChoOpt',true,17,[{boolIn,true},{intIn,25}]}} =
+ asn1_wrapper:decode('SeqOfCho','SeqChoOpt',lists:flatten(Bytes16)),
+
+
+
+
+
+ ?line {ok,Bytes21} =
+ asn1_wrapper:encode('SeqOfCho','SeqChoEmbDef',#'SeqChoEmbDef'{bool1 = true,
+ int1 = 17}),
+ ?line {ok,{'SeqChoEmbDef',true,17,[]}} =
+ asn1_wrapper:decode('SeqOfCho','SeqChoEmbDef',lists:flatten(Bytes21)),
+
+
+ ?line {ok,Bytes22} =
+ asn1_wrapper:encode('SeqOfCho','SeqChoEmbDef',#'SeqChoEmbDef'{bool1 = true,
+ int1 = 17,
+ seq1 = [{boolIn,true},
+ {intIn,25}]}),
+ ?line {ok,{'SeqChoEmbDef',true,17,[{boolIn,true},{intIn,25}]}} =
+ asn1_wrapper:decode('SeqOfCho','SeqChoEmbDef',lists:flatten(Bytes22)),
+
+
+
+ ?line {ok,Bytes25} =
+ asn1_wrapper:encode('SeqOfCho','SeqChoEmbOpt',#'SeqChoEmbOpt'{bool1 = true,
+ int1 = 17}),
+ ?line {ok,{'SeqChoEmbOpt',true,17,asn1_NOVALUE}} =
+ asn1_wrapper:decode('SeqOfCho','SeqChoEmbOpt',lists:flatten(Bytes25)),
+
+
+ ?line {ok,Bytes26} =
+ asn1_wrapper:encode('SeqOfCho','SeqChoEmbOpt',#'SeqChoEmbOpt'{bool1 = true,
+ int1 = 17,
+ seq1 = [{boolIn,true},
+ {intIn,25}]}),
+ ?line {ok,{'SeqChoEmbOpt',true,17,[{boolIn,true},{intIn,25}]}} =
+ asn1_wrapper:decode('SeqOfCho','SeqChoEmbOpt',lists:flatten(Bytes26)),
+
+
+
+
+
+
+ ?line {ok,Bytes31} =
+ asn1_wrapper:encode('SeqOfCho','SeqOfChoEmbDef',[#'SeqOfChoEmbDef_SEQOF'{bool1 = true,
+ int1 = 17}]),
+ ?line {ok,[{'SeqOfChoEmbDef_SEQOF',true,17,[]}]} =
+ asn1_wrapper:decode('SeqOfCho','SeqOfChoEmbDef',lists:flatten(Bytes31)),
+
+
+ ?line {ok,Bytes32} =
+ asn1_wrapper:encode('SeqOfCho','SeqOfChoEmbDef',
+ [#'SeqOfChoEmbDef_SEQOF'{bool1 = true,
+ int1 = 17,
+ seq1 = [{boolIn,true},
+ {intIn,25}]}]),
+ ?line {ok,[{'SeqOfChoEmbDef_SEQOF',true,17,[{boolIn,true},{intIn,25}]}]} =
+ asn1_wrapper:decode('SeqOfCho','SeqOfChoEmbDef',lists:flatten(Bytes32)),
+
+
+
+ ?line {ok,Bytes35} =
+ asn1_wrapper:encode('SeqOfCho','SeqOfChoEmbOpt',[#'SeqOfChoEmbOpt_SEQOF'{bool1 = true,
+ int1 = 17}]),
+ ?line {ok,[{'SeqOfChoEmbOpt_SEQOF',true,17,asn1_NOVALUE}]} =
+ asn1_wrapper:decode('SeqOfCho','SeqOfChoEmbOpt',lists:flatten(Bytes35)),
+
+
+ ?line {ok,Bytes36} =
+ asn1_wrapper:encode('SeqOfCho','SeqOfChoEmbOpt',
+ [#'SeqOfChoEmbOpt_SEQOF'{bool1 = true,
+ int1 = 17,
+ seq1 = [{boolIn,true},
+ {intIn,25}]}]),
+ ?line {ok,[{'SeqOfChoEmbOpt_SEQOF',true,17,[{boolIn,true},{intIn,25}]}]} =
+ asn1_wrapper:decode('SeqOfCho','SeqOfChoEmbOpt',lists:flatten(Bytes36)),
+
+
+
+
+ ok.
+
+
diff --git a/lib/asn1/test/testSeqOfExternal.erl b/lib/asn1/test/testSeqOfExternal.erl
new file mode 100644
index 0000000000..dde36e6949
--- /dev/null
+++ b/lib/asn1/test/testSeqOfExternal.erl
@@ -0,0 +1,171 @@
+%%
+%% %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(testSeqOfExternal).
+
+
+-export([compile/3]).
+-export([main/1]).
+
+-include("test_server.hrl").
+-include("External.hrl").
+
+-record('NT',{os, bool}).
+-record('Imp',{os, bool}).
+-record('Exp',{os, bool}).
+
+
+
+compile(Config,Rules,Options) ->
+
+ ?line DataDir = ?config(data_dir,Config),
+ ?line OutDir = ?config(priv_dir,Config),
+ ?line true = code:add_patha(?config(priv_dir,Config)),
+ ?line ok = asn1ct:compile(DataDir ++ "SeqOfExternal",[Rules,{outdir,OutDir}]++Options).
+
+
+
+main(_Rules) ->
+
+ ?line {ok,Bytes11} =
+ asn1_wrapper:encode('SeqOfExternal','NTNT',[#'NT'{bool = true, os = "kalle"},
+ #'NT'{bool = true, os = "kalle"}]),
+ ?line {ok,[{'NT',[107,97,108,108,101],true},{'NT',[107,97,108,108,101],true}]} =
+ asn1_wrapper:decode('SeqOfExternal','NTNT',lists:flatten(Bytes11)),
+
+ ?line {ok,Bytes12} =
+ asn1_wrapper:encode('SeqOfExternal','ImpNT',[#'NT'{bool = true, os = "kalle"},
+ #'NT'{bool = true, os = "kalle"}]),
+ ?line {ok,[{'NT',[107,97,108,108,101],true},{'NT',[107,97,108,108,101],true}]} =
+ asn1_wrapper:decode('SeqOfExternal','ImpNT',lists:flatten(Bytes12)),
+
+ ?line {ok,Bytes13} =
+ asn1_wrapper:encode('SeqOfExternal','ExpNT',[#'NT'{bool = true, os = "kalle"},
+ #'NT'{bool = true, os = "kalle"}]),
+ ?line {ok,[{'NT',[107,97,108,108,101],true},{'NT',[107,97,108,108,101],true}]} =
+ asn1_wrapper:decode('SeqOfExternal','ExpNT',lists:flatten(Bytes13)),
+
+
+
+ ?line {ok,Bytes21} =
+ asn1_wrapper:encode('SeqOfExternal','NTImp',[#'Imp'{bool = true, os = "kalle"},
+ #'Imp'{bool = true, os = "kalle"}]),
+ ?line {ok,[{'Imp',[107,97,108,108,101],true},{'Imp',[107,97,108,108,101],true}]} =
+ asn1_wrapper:decode('SeqOfExternal','NTImp',lists:flatten(Bytes21)),
+
+ ?line {ok,Bytes22} =
+ asn1_wrapper:encode('SeqOfExternal','ImpImp',[#'Imp'{bool = true, os = "kalle"},
+ #'Imp'{bool = true, os = "kalle"}]),
+ ?line {ok,[{'Imp',[107,97,108,108,101],true},{'Imp',[107,97,108,108,101],true}]} =
+ asn1_wrapper:decode('SeqOfExternal','ImpImp',lists:flatten(Bytes22)),
+
+ ?line {ok,Bytes23} =
+ asn1_wrapper:encode('SeqOfExternal','ExpImp',[#'Imp'{bool = true, os = "kalle"},
+ #'Imp'{bool = true, os = "kalle"}]),
+ ?line {ok,[{'Imp',[107,97,108,108,101],true},{'Imp',[107,97,108,108,101],true}]} =
+ asn1_wrapper:decode('SeqOfExternal','ExpImp',lists:flatten(Bytes23)),
+
+
+
+ ?line {ok,Bytes31} =
+ asn1_wrapper:encode('SeqOfExternal','NTExp',[#'Exp'{bool = true, os = "kalle"},
+ #'Exp'{bool = true, os = "kalle"}]),
+ ?line {ok,[{'Exp',[107,97,108,108,101],true},{'Exp',[107,97,108,108,101],true}]} =
+ asn1_wrapper:decode('SeqOfExternal','NTExp',lists:flatten(Bytes31)),
+
+ ?line {ok,Bytes32} =
+ asn1_wrapper:encode('SeqOfExternal','ImpExp',[#'Exp'{bool = true, os = "kalle"},
+ #'Exp'{bool = true, os = "kalle"}]),
+ ?line {ok,[{'Exp',[107,97,108,108,101],true},{'Exp',[107,97,108,108,101],true}]} =
+ asn1_wrapper:decode('SeqOfExternal','ImpExp',lists:flatten(Bytes32)),
+
+ ?line {ok,Bytes33} =
+ asn1_wrapper:encode('SeqOfExternal','ExpExp',[#'Exp'{bool = true, os = "kalle"},
+ #'Exp'{bool = true, os = "kalle"}]),
+ ?line {ok,[{'Exp',[107,97,108,108,101],true},{'Exp',[107,97,108,108,101],true}]} =
+ asn1_wrapper:decode('SeqOfExternal','ExpExp',lists:flatten(Bytes33)),
+
+
+
+
+
+
+
+ ?line {ok,Bytes41} =
+ asn1_wrapper:encode('SeqOfExternal','XNTNT',[#'XSeqNT'{bool = true, os = "kalle"},
+ #'XSeqNT'{bool = true, os = "kalle"}]),
+ ?line {ok,[{'XSeqNT',[107,97,108,108,101],true},{'XSeqNT',[107,97,108,108,101],true}]} =
+ asn1_wrapper:decode('SeqOfExternal','XNTNT',lists:flatten(Bytes41)),
+
+ ?line {ok,Bytes42} =
+ asn1_wrapper:encode('SeqOfExternal','XImpNT',[#'XSeqNT'{bool = true, os = "kalle"},
+ #'XSeqNT'{bool = true, os = "kalle"}]),
+ ?line {ok,[{'XSeqNT',[107,97,108,108,101],true},{'XSeqNT',[107,97,108,108,101],true}]} =
+ asn1_wrapper:decode('SeqOfExternal','XImpNT',lists:flatten(Bytes42)),
+
+ ?line {ok,Bytes43} =
+ asn1_wrapper:encode('SeqOfExternal','XExpNT',[#'XSeqNT'{bool = true, os = "kalle"},
+ #'XSeqNT'{bool = true, os = "kalle"}]),
+ ?line {ok,[{'XSeqNT',[107,97,108,108,101],true},{'XSeqNT',[107,97,108,108,101],true}]} =
+ asn1_wrapper:decode('SeqOfExternal','XExpNT',lists:flatten(Bytes43)),
+
+
+
+ ?line {ok,Bytes51} =
+ asn1_wrapper:encode('SeqOfExternal','XNTImp',[#'XSeqImp'{bool = true, os = "kalle"},
+ #'XSeqImp'{bool = true, os = "kalle"}]),
+ ?line {ok,[{'XSeqImp',[107,97,108,108,101],true},{'XSeqImp',[107,97,108,108,101],true}]} =
+ asn1_wrapper:decode('SeqOfExternal','XNTImp',lists:flatten(Bytes51)),
+
+ ?line {ok,Bytes52} =
+ asn1_wrapper:encode('SeqOfExternal','XImpImp',[#'XSeqImp'{bool = true, os = "kalle"},
+ #'XSeqImp'{bool = true, os = "kalle"}]),
+ ?line {ok,[{'XSeqImp',[107,97,108,108,101],true},{'XSeqImp',[107,97,108,108,101],true}]} =
+ asn1_wrapper:decode('SeqOfExternal','XImpImp',lists:flatten(Bytes52)),
+
+ ?line {ok,Bytes53} =
+ asn1_wrapper:encode('SeqOfExternal','XExpImp',[#'XSeqImp'{bool = true, os = "kalle"},
+ #'XSeqImp'{bool = true, os = "kalle"}]),
+ ?line {ok,[{'XSeqImp',[107,97,108,108,101],true},{'XSeqImp',[107,97,108,108,101],true}]} =
+ asn1_wrapper:decode('SeqOfExternal','XExpImp',lists:flatten(Bytes53)),
+
+
+
+ ?line {ok,Bytes61} =
+ asn1_wrapper:encode('SeqOfExternal','XNTExp',[#'XSeqExp'{bool = true, os = "kalle"},
+ #'XSeqExp'{bool = true, os = "kalle"}]),
+ ?line {ok,[{'XSeqExp',[107,97,108,108,101],true},{'XSeqExp',[107,97,108,108,101],true}]} =
+ asn1_wrapper:decode('SeqOfExternal','XNTExp',lists:flatten(Bytes61)),
+
+ ?line {ok,Bytes62} =
+ asn1_wrapper:encode('SeqOfExternal','XImpExp',[#'XSeqExp'{bool = true, os = "kalle"},
+ #'XSeqExp'{bool = true, os = "kalle"}]),
+ ?line {ok,[{'XSeqExp',[107,97,108,108,101],true},{'XSeqExp',[107,97,108,108,101],true}]} =
+ asn1_wrapper:decode('SeqOfExternal','XImpExp',lists:flatten(Bytes62)),
+
+ ?line {ok,Bytes63} =
+ asn1_wrapper:encode('SeqOfExternal','XExpExp',[#'XSeqExp'{bool = true, os = "kalle"},
+ #'XSeqExp'{bool = true, os = "kalle"}]),
+ ?line {ok,[{'XSeqExp',[107,97,108,108,101],true},{'XSeqExp',[107,97,108,108,101],true}]} =
+ asn1_wrapper:decode('SeqOfExternal','XExpExp',lists:flatten(Bytes63)),
+
+
+
+
+ ok.
diff --git a/lib/asn1/test/testSeqOfIndefinite.erl b/lib/asn1/test/testSeqOfIndefinite.erl
new file mode 100644
index 0000000000..8e8967572a
--- /dev/null
+++ b/lib/asn1/test/testSeqOfIndefinite.erl
@@ -0,0 +1,329 @@
+%%
+%% %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(testSeqOfIndefinite).
+
+-export([compile/3]).
+-export([main/0]).
+
+-include("test_server.hrl").
+
+%-record('Seq1',{bool1, int1, seq1 = asn1_DEFAULT}).
+%-record('Seq2',{seq2 = asn1_DEFAULT, bool2, int2}).
+%-record('Seq3',{bool3, seq3 = asn1_DEFAULT, int3}).
+%-record('Seq4',{seq41 = asn1_DEFAULT, seq42 = asn1_DEFAULT, seq43 = asn1_DEFAULT}).
+%-record('SeqIn',{boolIn, intIn}).
+%-record('SeqCho',{bool1, int1, seq1 = asn1_DEFAULT}).
+%-record('SeqChoInline',{bool1, int1, seq1 = asn1_DEFAULT}).
+%-record('SeqChoOfInline_SEQOF',{bool1, int1, seq1 = asn1_DEFAULT}).
+%-record('SeqEmp',{seq1}).
+%-record('Empty',{}).
+
+
+
+compile(Config,Rules,Opts) ->
+
+ ?line DataDir = ?config(data_dir,Config),
+ ?line OutDir = ?config(priv_dir,Config),
+ ?line true = code:add_patha(?config(priv_dir,Config)),
+ ?line Options = [Rules,{outdir,OutDir}]++Opts,
+ ?line ok = asn1ct:compile(DataDir ++ "Mvrasn-Constants-1",Options),
+ ?line ok = asn1ct:compile(DataDir ++ "Mvrasn-DataTypes-1",Options),
+ ?line ok = asn1ct:compile(DataDir ++ "Mvrasn-21-4",Options),
+ ?line ok = asn1ct:compile(DataDir ++ "Mvrasn-20-4",Options),
+ ?line ok = asn1ct:compile(DataDir ++ "Mvrasn-19-4",Options),
+ ?line ok = asn1ct:compile(DataDir ++ "Mvrasn-18-4",Options),
+ ?line ok = asn1ct:compile(DataDir ++ "Mvrasn-17-4",Options),
+ ?line ok = asn1ct:compile(DataDir ++ "Mvrasn-15-4",Options),
+ ?line ok = asn1ct:compile(DataDir ++ "Mvrasn-14-4",Options),
+ ?line ok = asn1ct:compile(DataDir ++ "Mvrasn-11-4",Options),
+ ?line ok = asn1ct:compile(DataDir ++ "SeqOf",Options).
+
+main() ->
+ ?line ok = test(isd),
+ ?line ok = test(isd2),
+ ?line ok = test(dsd),
+ ?line ok = test(ul_res),
+ ?line ok = test(prim),
+ ?line ok = test(seqofseq),
+ ?line ok = test('InsertSubscriberDataArg'). % OTP-4232
+
+test(isd)->
+ EncPdu = [48,128,129,7,145,148,113,50,1,0,241,131,1,0,176,128,5,0,161,128,48,22,2,1,1,144,2,241,33,145,4,0,1,2,3,146,3,36,131,16,148,2,1,42,48,35,2,1,2,144,2,241,33,145,4,255,255,255,255,146,3,37,147,18,147,0,148,13,7,67,79,77,80,65,78,89,4,67,79,77,53,48,28,2,1,3,144,2,241,33,146,3,26,98,31,148,14,9,67,79,77,80,65,78,89,49,50,3,67,79,77,0,0,0,0,152,1,2,0,0],
+
+ ?line {ok,_} = asn1_wrapper:decode('Mvrasn-11-4',
+ 'InsertSubscriberDataArg',
+ EncPdu),
+ ok;
+
+%
+% Problems with indefinite length encoding !!!
+%
+test(isd2)->
+ EncPdu = [48, 128, 128, 8, 98, 2, 50, 1, 0, 0, 0, 241, 176, 128, 161, 128, 48, 128, 2, 1, 1, 144, 2, 241, 33, 145, 4, 255, 23, 12, 1, 146, 3, 9, 17, 1, 147, 0, 148, 13, 7, 67, 79, 77, 80, 65, 78, 89, 4, 67, 79, 77, 53, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
+
+ ?line {ok,_DecPdu} = asn1_wrapper:decode('Mvrasn-11-4',
+ 'InsertSubscriberDataArg',
+ EncPdu),
+
+ ok;
+
+%
+% Is doing fine, although there is indefinite encoding used... !!!
+%
+test(dsd)->
+ EncPdu = [48, 128, 128, 8, 98, 2, 50, 1, 0, 0, 0, 241, 170, 2, 5, 0, 0, 0, 0, 0],
+
+ ?line {ok,_DecPdu} = asn1_wrapper:decode('Mvrasn-11-4',
+ 'DeleteSubscriberDataArg',
+ EncPdu),
+
+ ok;
+
+%
+% Is doing fine !!!
+%
+test(ul_res)->
+ EncPdu = [48, 9, 4, 7, 145, 148, 113, 66, 16, 17, 241],
+
+ ?line {ok,_DecPdu} = asn1_wrapper:decode('Mvrasn-11-4',
+ 'UpdateGprsLocationRes',
+ EncPdu),
+
+ ok;
+
+test(prim) ->
+ ?line {ok,Bytes} = asn1_wrapper:encode('SeqOf','SeqOfInt',[10,20,30]),
+ ?line [Tag,_Len|Ints] = lists:flatten(Bytes),
+ ?line {ok,[10,20,30]} =
+ asn1_wrapper:decode('SeqOf','SeqOfInt',[Tag,128|Ints] ++ [0,0]),
+ ok;
+
+test(seqofseq) ->
+ {ok,_V} = asn1_wrapper:decode('Mvrasn-DataTypes-1',
+ 'SentParameters',
+ [48,
+ 129,
+ 190,
+ 161,
+ 128,
+ 4,
+ 16,
+ 176,
+ 197,
+ 182,
+ 68,
+ 41,
+ 243,
+ 188,
+ 205,
+ 123,
+ 13,
+ 9,
+ 145,
+ 206,
+ 200,
+ 144,
+ 102,
+ 4,
+ 4,
+ 176,
+ 197,
+ 182,
+ 68,
+ 4,
+ 8,
+ 41,
+ 243,
+ 188,
+ 205,
+ 123,
+ 13,
+ 9,
+ 145,
+ 0,
+ 0,
+ 161,
+ 128,
+ 4,
+ 16,
+ 39,
+ 0,
+ 3,
+ 117,
+ 35,
+ 189,
+ 130,
+ 21,
+ 42,
+ 104,
+ 49,
+ 194,
+ 212,
+ 24,
+ 151,
+ 234,
+ 4,
+ 4,
+ 39,
+ 0,
+ 3,
+ 117,
+ 4,
+ 8,
+ 35,
+ 189,
+ 130,
+ 21,
+ 42,
+ 104,
+ 49,
+ 194,
+ 0,
+ 0,
+ 161,
+ 128,
+ 4,
+ 16,
+ 62,
+ 207,
+ 166,
+ 59,
+ 71,
+ 29,
+ 37,
+ 97,
+ 120,
+ 25,
+ 132,
+ 80,
+ 144,
+ 251,
+ 161,
+ 123,
+ 4,
+ 4,
+ 62,
+ 207,
+ 166,
+ 59,
+ 4,
+ 8,
+ 71,
+ 29,
+ 37,
+ 97,
+ 120,
+ 25,
+ 132,
+ 80,
+ 0,
+ 0,
+ 161,
+ 128,
+ 4,
+ 16,
+ 95,
+ 183,
+ 173,
+ 151,
+ 17,
+ 76,
+ 148,
+ 146,
+ 248,
+ 102,
+ 127,
+ 215,
+ 102,
+ 224,
+ 39,
+ 60,
+ 4,
+ 4,
+ 95,
+ 183,
+ 173,
+ 151,
+ 4,
+ 8,
+ 17,
+ 76,
+ 148,
+ 146,
+ 248,
+ 102,
+ 127,
+ 215,
+ 0,
+ 0,
+ 161,
+ 128,
+ 4,
+ 16,
+ 41,
+ 198,
+ 247,
+ 157,
+ 117,
+ 190,
+ 203,
+ 170,
+ 91,
+ 146,
+ 88,
+ 91,
+ 223,
+ 220,
+ 188,
+ 16,
+ 4,
+ 4,
+ 41,
+ 198,
+ 247,
+ 157,
+ 4,
+ 8,
+ 117,
+ 190,
+ 203,
+ 170,
+ 91,
+ 146,
+ 88,
+ 91,
+ 0,
+ 0]),
+ ok;
+test('InsertSubscriberDataArg') ->
+ {ok,_V} =
+ asn1_wrapper:decode('Mvrasn-11-4','InsertSubscriberDataArg',
+ [16#30,16#80,16#81,16#07,16#91,16#94,
+ 16#71,16#92,16#00,16#35,16#80,16#83,
+ 16#01,16#00,16#A6,16#06,16#04,16#01,
+ 16#21,16#04,16#01,16#22,16#B0,16#80,
+ 16#05,16#00,16#A1,16#80,16#30,16#1A,
+ 16#02,16#01,16#01,16#90,16#02,16#F1,
+ 16#21,16#92,16#03,16#0D,16#92,16#1F,
+ 16#94,16#0C,16#03,16#53,16#49,16#4D,
+ 16#03,16#47,16#53,16#4E,16#03,16#4C,
+ 16#4B,16#50,16#00,16#00,16#00,16#00,
+ 16#98,16#01,16#00,16#00,16#00]),
+ ok.
diff --git a/lib/asn1/test/testSeqOfTag.erl b/lib/asn1/test/testSeqOfTag.erl
new file mode 100644
index 0000000000..0a4e1397a6
--- /dev/null
+++ b/lib/asn1/test/testSeqOfTag.erl
@@ -0,0 +1,201 @@
+%%
+%% %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(testSeqOfTag).
+
+
+-export([compile/3]).
+-export([main/1]).
+
+-include("test_server.hrl").
+-include("External.hrl").
+
+
+-record('SeqTagNt',{nt}).
+-record('SeqTagNtI',{imp}).
+-record('SeqTagNtE',{exp}).
+-record('SeqTagI',{nt}).
+-record('SeqTagII',{imp}).
+-record('SeqTagIE',{exp}).
+-record('SeqTagE',{nt}).
+-record('SeqTagEI',{imp}).
+-record('SeqTagEE',{exp}).
+-record('SeqTagXNt',{xnt}).
+-record('SeqTagXI',{ximp}).
+-record('SeqTagXE',{xexp}).
+-record('SeqTagImpX',{xnt, ximp, xexp}).
+-record('SeqTagExpX',{xnt, ximp, xexp}).
+-record('NT',{os, bool}).
+-record('Imp',{os, bool}).
+-record('Exp',{os, bool}).
+
+
+
+compile(Config,Rules,Options) ->
+
+ ?line DataDir = ?config(data_dir,Config),
+ ?line OutDir = ?config(priv_dir,Config),
+ ?line true = code:add_patha(?config(priv_dir,Config)),
+ ?line ok = asn1ct:compile(DataDir ++ "SeqOfTag",[Rules,{outdir,OutDir}]++Options).
+
+
+
+main(_Rules) ->
+
+ ?line {ok,Bytes11} =
+ asn1_wrapper:encode('SeqOfTag','SeqTagNt',
+ #'SeqTagNt'{nt = [#'NT'{bool = true, os = "kalle"},
+ #'NT'{bool = true, os = "kalle"}]}),
+ ?line {ok,{'SeqTagNt',
+ [{'NT',[107,97,108,108,101],true},{'NT',[107,97,108,108,101],true}]}} =
+ asn1_wrapper:decode('SeqOfTag','SeqTagNt',lists:flatten(Bytes11)),
+
+ ?line {ok,Bytes12} =
+ asn1_wrapper:encode('SeqOfTag','SeqTagNtI',
+ #'SeqTagNtI'{imp = [#'Imp'{bool = true, os = "kalle"},
+ #'Imp'{bool = true, os = "kalle"}]}),
+ ?line {ok,{'SeqTagNtI',
+ [{'Imp',[107,97,108,108,101],true},{'Imp',[107,97,108,108,101],true}]}} =
+ asn1_wrapper:decode('SeqOfTag','SeqTagNtI',lists:flatten(Bytes12)),
+
+ ?line {ok,Bytes13} =
+ asn1_wrapper:encode('SeqOfTag','SeqTagNtE',
+ #'SeqTagNtE'{exp = [#'Exp'{bool = true, os = "kalle"},
+ #'Exp'{bool = true, os = "kalle"}]}),
+ ?line {ok,{'SeqTagNtE',
+ [{'Exp',[107,97,108,108,101],true},{'Exp',[107,97,108,108,101],true}]}} =
+ asn1_wrapper:decode('SeqOfTag','SeqTagNtE',lists:flatten(Bytes13)),
+
+
+
+ ?line {ok,Bytes21} =
+ asn1_wrapper:encode('SeqOfTag','SeqTagI',
+ #'SeqTagI'{nt = [#'NT'{bool = true, os = "kalle"},
+ #'NT'{bool = true, os = "kalle"}]}),
+ ?line {ok,{'SeqTagI',
+ [{'NT',[107,97,108,108,101],true},{'NT',[107,97,108,108,101],true}]}} =
+ asn1_wrapper:decode('SeqOfTag','SeqTagI',lists:flatten(Bytes21)),
+
+ ?line {ok,Bytes22} =
+ asn1_wrapper:encode('SeqOfTag','SeqTagII',
+ #'SeqTagII'{imp = [#'Imp'{bool = true, os = "kalle"},
+ #'Imp'{bool = true, os = "kalle"}]}),
+ ?line {ok,{'SeqTagII',
+ [{'Imp',[107,97,108,108,101],true},{'Imp',[107,97,108,108,101],true}]}} =
+ asn1_wrapper:decode('SeqOfTag','SeqTagII',lists:flatten(Bytes22)),
+
+ ?line {ok,Bytes23} =
+ asn1_wrapper:encode('SeqOfTag','SeqTagIE',
+ #'SeqTagIE'{exp = [#'Exp'{bool = true, os = "kalle"},
+ #'Exp'{bool = true, os = "kalle"}]}),
+ ?line {ok,{'SeqTagIE',
+ [{'Exp',[107,97,108,108,101],true},{'Exp',[107,97,108,108,101],true}]}} =
+ asn1_wrapper:decode('SeqOfTag','SeqTagIE',lists:flatten(Bytes23)),
+
+
+
+ ?line {ok,Bytes31} =
+ asn1_wrapper:encode('SeqOfTag','SeqTagE',
+ #'SeqTagE'{nt = [#'NT'{bool = true, os = "kalle"},
+ #'NT'{bool = true, os = "kalle"}]}),
+ ?line {ok,{'SeqTagE',
+ [{'NT',[107,97,108,108,101],true},{'NT',[107,97,108,108,101],true}]}} =
+ asn1_wrapper:decode('SeqOfTag','SeqTagE',lists:flatten(Bytes31)),
+
+ ?line {ok,Bytes32} =
+ asn1_wrapper:encode('SeqOfTag','SeqTagEI',
+ #'SeqTagEI'{imp = [#'Imp'{bool = true, os = "kalle"},
+ #'Imp'{bool = true, os = "kalle"}]}),
+ ?line {ok,{'SeqTagEI',
+ [{'Imp',[107,97,108,108,101],true},{'Imp',[107,97,108,108,101],true}]}} =
+ asn1_wrapper:decode('SeqOfTag','SeqTagEI',lists:flatten(Bytes32)),
+
+ ?line {ok,Bytes33} =
+ asn1_wrapper:encode('SeqOfTag','SeqTagEE',
+ #'SeqTagEE'{exp = [#'Exp'{bool = true, os = "kalle"},
+ #'Exp'{bool = true, os = "kalle"}]}),
+ ?line {ok,{'SeqTagEE',
+ [{'Exp',[107,97,108,108,101],true},{'Exp',[107,97,108,108,101],true}]}} =
+ asn1_wrapper:decode('SeqOfTag','SeqTagEE',lists:flatten(Bytes33)),
+
+
+
+
+
+
+
+ ?line {ok,Bytes41} =
+ asn1_wrapper:encode('SeqOfTag','SeqTagXNt',
+ #'SeqTagXNt'{xnt = [#'XSeqNT'{bool = true, os = "kalle"},
+ #'XSeqNT'{bool = true, os = "kalle"}]}),
+ ?line {ok,{'SeqTagXNt',
+ [{'XSeqNT',[107,97,108,108,101],true},{'XSeqNT',[107,97,108,108,101],true}]}} =
+ asn1_wrapper:decode('SeqOfTag','SeqTagXNt',lists:flatten(Bytes41)),
+
+ ?line {ok,Bytes42} =
+ asn1_wrapper:encode('SeqOfTag','SeqTagXI',
+ #'SeqTagXI'{ximp = [#'XSeqImp'{bool = true, os = "kalle"},
+ #'XSeqImp'{bool = true, os = "kalle"}]}),
+ ?line {ok,{'SeqTagXI',
+ [{'XSeqImp',[107,97,108,108,101],true},{'XSeqImp',[107,97,108,108,101],true}]}} =
+ asn1_wrapper:decode('SeqOfTag','SeqTagXI',lists:flatten(Bytes42)),
+
+ ?line {ok,Bytes43} =
+ asn1_wrapper:encode('SeqOfTag','SeqTagXE',
+ #'SeqTagXE'{xexp = [#'XSeqExp'{bool = true, os = "kalle"},
+ #'XSeqExp'{bool = true, os = "kalle"}]}),
+ ?line {ok,{'SeqTagXE',
+ [{'XSeqExp',[107,97,108,108,101],true},{'XSeqExp',[107,97,108,108,101],true}]}} =
+ asn1_wrapper:decode('SeqOfTag','SeqTagXE',lists:flatten(Bytes43)),
+
+
+
+
+
+ ?line {ok,Bytes51} =
+ asn1_wrapper:encode('SeqOfTag','SeqTagImpX',
+ #'SeqTagImpX'{xnt = [#'XSeqNT'{bool = true, os = "kalle"},
+ #'XSeqNT'{bool = true, os = "kalle"}],
+ ximp = [#'XSeqImp'{bool = true, os = "kalle"},
+ #'XSeqImp'{bool = true, os = "kalle"}],
+ xexp = [#'XSeqExp'{bool = true, os = "kalle"},
+ #'XSeqExp'{bool = true, os = "kalle"}]}),
+ ?line {ok,{'SeqTagImpX',
+ [{'XSeqNT',[107,97,108,108,101],true},{'XSeqNT',[107,97,108,108,101],true}],
+ [{'XSeqImp',[107,97,108,108,101],true},{'XSeqImp',[107,97,108,108,101],true}],
+ [{'XSeqExp',[107,97,108,108,101],true},{'XSeqExp',[107,97,108,108,101],true}]}} =
+ asn1_wrapper:decode('SeqOfTag','SeqTagImpX',lists:flatten(Bytes51)),
+
+
+
+ ?line {ok,Bytes52} =
+ asn1_wrapper:encode('SeqOfTag','SeqTagExpX',
+ #'SeqTagExpX'{xnt = [#'XSeqNT'{bool = true, os = "kalle"},
+ #'XSeqNT'{bool = true, os = "kalle"}],
+ ximp = [#'XSeqImp'{bool = true, os = "kalle"},
+ #'XSeqImp'{bool = true, os = "kalle"}],
+ xexp = [#'XSeqExp'{bool = true, os = "kalle"},
+ #'XSeqExp'{bool = true, os = "kalle"}]}),
+ ?line {ok,{'SeqTagExpX',
+ [{'XSeqNT',[107,97,108,108,101],true},{'XSeqNT',[107,97,108,108,101],true}],
+ [{'XSeqImp',[107,97,108,108,101],true},{'XSeqImp',[107,97,108,108,101],true}],
+ [{'XSeqExp',[107,97,108,108,101],true},{'XSeqExp',[107,97,108,108,101],true}]}} =
+ asn1_wrapper:decode('SeqOfTag','SeqTagExpX',lists:flatten(Bytes52)),
+
+ok.
diff --git a/lib/asn1/test/testSeqOptional.erl b/lib/asn1/test/testSeqOptional.erl
new file mode 100644
index 0000000000..7177011427
--- /dev/null
+++ b/lib/asn1/test/testSeqOptional.erl
@@ -0,0 +1,206 @@
+%%
+%% %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(testSeqOptional).
+
+-include("External.hrl").
+-export([compile/3]).
+-export([main/1]).
+
+-include("test_server.hrl").
+
+-record('SeqOpt1',{bool1 = asn1_NOVALUE, int1, seq1 = asn1_NOVALUE}).
+-record('SeqOpt1Imp',{bool1 = asn1_NOVALUE, int1, seq1 = asn1_NOVALUE}).
+-record('SeqOpt1Exp',{bool1 = asn1_NOVALUE, int1, seq1 = asn1_NOVALUE}).
+-record('SeqOpt2',{seq2 = asn1_NOVALUE, bool2, int2}).
+-record('SeqOpt2Imp',{seq2 = asn1_NOVALUE, bool2, int2}).
+-record('SeqOpt2Exp',{seq2 = asn1_NOVALUE, bool2, int2}).
+-record('SeqOpt3',{bool3 = asn1_NOVALUE, seq3 = asn1_NOVALUE, int3 = asn1_NOVALUE}).
+-record('SeqOpt3Imp',{bool3 = asn1_NOVALUE, seq3 = asn1_NOVALUE, int3 = asn1_NOVALUE}).
+-record('SeqOpt3Exp',{bool3 = asn1_NOVALUE, seq3 = asn1_NOVALUE, int3 = asn1_NOVALUE}).
+-record('SeqIn',{boolIn, intIn}).
+-record('SeqChoOpt',{int, cho = asn1_NOVALUE}).
+
+
+compile(Config,Rules,Options) ->
+
+ ?line DataDir = ?config(data_dir,Config),
+ ?line OutDir = ?config(priv_dir,Config),
+ ?line true = code:add_patha(?config(priv_dir,Config)),
+ ?line ok = asn1ct:compile(DataDir ++ "SeqOptional",[Rules,{outdir,OutDir}]++Options).
+
+
+
+main(_Rules) ->
+
+ ?line {ok,Bytes11} =
+ asn1_wrapper:encode('SeqOptional','SeqOpt1',#'SeqOpt1'{bool1 = true,
+ int1 = 15,
+ seq1 = #'SeqIn'{boolIn = true,
+ intIn = 66}}),
+ ?line {ok,{'SeqOpt1',true,15,{'SeqIn',true,66}}} =
+ asn1_wrapper:decode('SeqOptional','SeqOpt1',lists:flatten(Bytes11)),
+
+
+ ?line {ok,Bytes12} = asn1_wrapper:encode('SeqOptional','SeqOpt1',#'SeqOpt1'{int1 = 15}),
+ ?line {ok,{'SeqOpt1',asn1_NOVALUE,15,asn1_NOVALUE}} =
+ asn1_wrapper:decode('SeqOptional','SeqOpt1',lists:flatten(Bytes12)),
+
+
+ ?line {ok,Bytes21} =
+ asn1_wrapper:encode('SeqOptional','SeqOpt2',#'SeqOpt2'{bool2 = true,
+ int2 = 15,
+ seq2 = #'SeqIn'{boolIn = true,
+ intIn = 66}}),
+ ?line {ok,{'SeqOpt2',{'SeqIn',true,66},true,15}} =
+ asn1_wrapper:decode('SeqOptional','SeqOpt2',lists:flatten(Bytes21)),
+
+
+ ?line {ok,Bytes22} = asn1_wrapper:encode('SeqOptional','SeqOpt2',#'SeqOpt2'{int2 = 15,
+ bool2 = true}),
+ ?line {ok,{'SeqOpt2',asn1_NOVALUE,true,15}} =
+ asn1_wrapper:decode('SeqOptional','SeqOpt2',lists:flatten(Bytes22)),
+
+
+
+ ?line {ok,Bytes31} =
+ asn1_wrapper:encode('SeqOptional','SeqOpt3',#'SeqOpt3'{bool3 = true,
+ int3 = 15,
+ seq3 = #'SeqIn'{boolIn = true,
+ intIn = 66}}),
+ ?line {ok,{'SeqOpt3',true,{'SeqIn',true,66},15}} =
+ asn1_wrapper:decode('SeqOptional','SeqOpt3',lists:flatten(Bytes31)),
+
+
+ ?line {ok,Bytes32} = asn1_wrapper:encode('SeqOptional','SeqOpt3',#'SeqOpt3'{int3 = 15}),
+ ?line {ok,{'SeqOpt3',asn1_NOVALUE,asn1_NOVALUE,15}} =
+ asn1_wrapper:decode('SeqOptional','SeqOpt3',lists:flatten(Bytes32)),
+
+
+
+
+
+ ?line {ok,Bytes41} =
+ asn1_wrapper:encode('SeqOptional','SeqOpt1Imp',#'SeqOpt1Imp'{bool1 = true,
+ int1 = 15,
+ seq1 = #'SeqIn'{boolIn = true,
+ intIn = 66}}),
+ ?line {ok,{'SeqOpt1Imp',true,15,{'SeqIn',true,66}}} =
+ asn1_wrapper:decode('SeqOptional','SeqOpt1Imp',lists:flatten(Bytes41)),
+
+
+ ?line {ok,Bytes42} = asn1_wrapper:encode('SeqOptional','SeqOpt1Imp',#'SeqOpt1Imp'{int1 = 15}),
+ ?line {ok,{'SeqOpt1Imp',asn1_NOVALUE,15,asn1_NOVALUE}} =
+ asn1_wrapper:decode('SeqOptional','SeqOpt1Imp',lists:flatten(Bytes42)),
+
+
+ ?line {ok,Bytes51} =
+ asn1_wrapper:encode('SeqOptional','SeqOpt2Imp',#'SeqOpt2Imp'{bool2 = true,
+ int2 = 15,
+ seq2 = #'SeqIn'{boolIn = true,
+ intIn = 66}}),
+ ?line {ok,{'SeqOpt2Imp',{'SeqIn',true,66},true,15}} =
+ asn1_wrapper:decode('SeqOptional','SeqOpt2Imp',lists:flatten(Bytes51)),
+
+
+ ?line {ok,Bytes52} = asn1_wrapper:encode('SeqOptional','SeqOpt2Imp',#'SeqOpt2Imp'{int2 = 15,
+ bool2 = true}),
+ ?line {ok,{'SeqOpt2Imp',asn1_NOVALUE,true,15}} =
+ asn1_wrapper:decode('SeqOptional','SeqOpt2Imp',lists:flatten(Bytes52)),
+
+
+
+ ?line {ok,Bytes61} =
+ asn1_wrapper:encode('SeqOptional','SeqOpt3Imp',#'SeqOpt3Imp'{bool3 = true,
+ int3 = 15,
+ seq3 = #'SeqIn'{boolIn = true,
+ intIn = 66}}),
+ ?line {ok,{'SeqOpt3Imp',true,{'SeqIn',true,66},15}} =
+ asn1_wrapper:decode('SeqOptional','SeqOpt3Imp',lists:flatten(Bytes61)),
+
+
+ ?line {ok,Bytes62} = asn1_wrapper:encode('SeqOptional','SeqOpt3Imp',#'SeqOpt3Imp'{int3 = 15}),
+ ?line {ok,{'SeqOpt3Imp',asn1_NOVALUE,asn1_NOVALUE,15}} =
+ asn1_wrapper:decode('SeqOptional','SeqOpt3Imp',lists:flatten(Bytes62)),
+
+
+
+
+
+
+ ?line {ok,Bytes71} =
+ asn1_wrapper:encode('SeqOptional','SeqOpt1Exp',#'SeqOpt1Exp'{bool1 = true,
+ int1 = 15,
+ seq1 = #'SeqIn'{boolIn = true,
+ intIn = 66}}),
+ ?line {ok,{'SeqOpt1Exp',true,15,{'SeqIn',true,66}}} =
+ asn1_wrapper:decode('SeqOptional','SeqOpt1Exp',lists:flatten(Bytes71)),
+
+
+ ?line {ok,Bytes72} = asn1_wrapper:encode('SeqOptional','SeqOpt1Exp',#'SeqOpt1Exp'{int1 = 15}),
+ ?line {ok,{'SeqOpt1Exp',asn1_NOVALUE,15,asn1_NOVALUE}} =
+ asn1_wrapper:decode('SeqOptional','SeqOpt1Exp',lists:flatten(Bytes72)),
+
+
+ ?line {ok,Bytes81} =
+ asn1_wrapper:encode('SeqOptional','SeqOpt2Exp',#'SeqOpt2Exp'{bool2 = true,
+ int2 = 15,
+ seq2 = #'SeqIn'{boolIn = true,
+ intIn = 66}}),
+ ?line {ok,{'SeqOpt2Exp',{'SeqIn',true,66},true,15}} =
+ asn1_wrapper:decode('SeqOptional','SeqOpt2Exp',lists:flatten(Bytes81)),
+
+
+ ?line {ok,Bytes82} = asn1_wrapper:encode('SeqOptional','SeqOpt2Exp',#'SeqOpt2Exp'{int2 = 15,
+ bool2 = true}),
+ ?line {ok,{'SeqOpt2Exp',asn1_NOVALUE,true,15}} =
+ asn1_wrapper:decode('SeqOptional','SeqOpt2Exp',lists:flatten(Bytes82)),
+
+
+
+ ?line {ok,Bytes91} =
+ asn1_wrapper:encode('SeqOptional','SeqOpt3Exp',#'SeqOpt3Exp'{bool3 = true,
+ int3 = 15,
+ seq3 = #'SeqIn'{boolIn = true,
+ intIn = 66}}),
+ ?line {ok,{'SeqOpt3Exp',true,{'SeqIn',true,66},15}} =
+ asn1_wrapper:decode('SeqOptional','SeqOpt3Exp',lists:flatten(Bytes91)),
+
+
+ ?line {ok,Bytes92} = asn1_wrapper:encode('SeqOptional','SeqOpt3Exp',#'SeqOpt3Exp'{int3 = 15}),
+ ?line {ok,{'SeqOpt3Exp',asn1_NOVALUE,asn1_NOVALUE,15}} =
+ asn1_wrapper:decode('SeqOptional','SeqOpt3Exp',lists:flatten(Bytes92)),
+
+
+
+ ?line {ok,Bytes101} =
+ asn1_wrapper:encode('SeqOptional','SeqChoOpt',#'SeqChoOpt'{int = 15,
+ cho = {boolC,true}}),
+ ?line {ok,{'SeqChoOpt',15,{boolC,true}}} =
+ asn1_wrapper:decode('SeqOptional','SeqChoOpt',lists:flatten(Bytes101)),
+
+
+ ?line {ok,Bytes102} = asn1_wrapper:encode('SeqOptional','SeqChoOpt',#'SeqChoOpt'{int = 15}),
+ ?line {ok,{'SeqChoOpt',15,asn1_NOVALUE}} =
+ asn1_wrapper:decode('SeqOptional','SeqChoOpt',lists:flatten(Bytes102)),
+
+
+
+
+ ok.
diff --git a/lib/asn1/test/testSeqPrim.erl b/lib/asn1/test/testSeqPrim.erl
new file mode 100644
index 0000000000..7ad1de58a1
--- /dev/null
+++ b/lib/asn1/test/testSeqPrim.erl
@@ -0,0 +1,94 @@
+%%
+%% %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(testSeqPrim).
+
+-export([compile/3]).
+-export([main/1]).
+
+-include("test_server.hrl").
+
+-record('Seq',{bool, boolCon, boolPri, boolApp, boolExpCon, boolExpPri, boolExpApp}).
+-record('Empty',{}).
+
+compile(Config,Rules,Options) ->
+
+ ?line DataDir = ?config(data_dir,Config),
+ ?line OutDir = ?config(priv_dir,Config),
+ ?line true = code:add_patha(?config(priv_dir,Config)),
+ ?line ok = asn1ct:compile(DataDir ++ "SeqPrim",[Rules,{outdir,OutDir}]++Options).
+
+
+
+main(_Rules) ->
+
+
+
+ ?line {ok,Bytes11} =
+ asn1_wrapper:encode('SeqPrim','Seq',#'Seq'{bool = true,
+ boolCon = true,
+ boolPri = true,
+ boolApp = true,
+ boolExpCon = true,
+ boolExpPri = true,
+ boolExpApp = true}),
+ ?line {ok,{'Seq',true,true,true,true,true,true,true}} =
+ asn1_wrapper:decode('SeqPrim','Seq',lists:flatten(Bytes11)),
+
+
+
+
+ ?line {ok,Bytes12} =
+ asn1_wrapper:encode('SeqPrim','Seq',#'Seq'{bool = false,
+ boolCon = false,
+ boolPri = false,
+ boolApp = false,
+ boolExpCon = false,
+ boolExpPri = false,
+ boolExpApp = false}),
+ ?line {ok,{'Seq',false,false,false,false,false,false,false}} =
+ asn1_wrapper:decode('SeqPrim','Seq',lists:flatten(Bytes12)),
+
+
+
+
+ ?line {ok,Bytes13} =
+ asn1_wrapper:encode('SeqPrim','Seq',#'Seq'{bool = false,
+ boolCon = true,
+ boolPri = false,
+ boolApp = true,
+ boolExpCon = false,
+ boolExpPri = true,
+ boolExpApp = false}),
+ ?line {ok,{'Seq',false,true,false,true,false,true,false}} =
+ asn1_wrapper:decode('SeqPrim','Seq',lists:flatten(Bytes13)),
+
+
+
+
+
+ ?line {ok,Bytes21} =
+ asn1_wrapper:encode('SeqPrim','Empty',#'Empty'{}),
+ ?line {ok,{'Empty'}} =
+ asn1_wrapper:decode('SeqPrim','Empty',lists:flatten(Bytes21)),
+
+
+
+ ok.
+
diff --git a/lib/asn1/test/testSeqSetDefaultVal.erl b/lib/asn1/test/testSeqSetDefaultVal.erl
new file mode 100644
index 0000000000..1c238fd1b7
--- /dev/null
+++ b/lib/asn1/test/testSeqSetDefaultVal.erl
@@ -0,0 +1,345 @@
+%%
+%% %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(testSeqSetDefaultVal).
+
+-include("External.hrl").
+-export([compile/2]).
+-export([main/1]).
+
+-include("test_server.hrl").
+
+-record('SeqInts',{a = asn1_DEFAULT,
+ b = asn1_DEFAULT,
+ c = asn1_DEFAULT,
+ d = asn1_DEFAULT}).
+-record('SetInts',{a = asn1_DEFAULT,
+ b = asn1_DEFAULT,
+ c = asn1_DEFAULT,
+ d = asn1_DEFAULT}).
+-record('SeqBS',{a = asn1_DEFAULT,
+ b = asn1_DEFAULT,
+ c = asn1_DEFAULT,
+ d = asn1_DEFAULT}).
+-record('SetBS',{a = asn1_DEFAULT,
+ b = asn1_DEFAULT,
+ c = asn1_DEFAULT,
+ d = asn1_DEFAULT}).
+-record('SeqOS',{a = asn1_DEFAULT,
+ b = asn1_DEFAULT,
+ c = asn1_DEFAULT}).
+-record('SetOS',{a = asn1_DEFAULT,
+ b = asn1_DEFAULT,
+ c = asn1_DEFAULT}).
+-record('SeqOI',{a = asn1_DEFAULT,
+ b = asn1_DEFAULT,
+ c = asn1_DEFAULT}).
+-record('SetOI',{a = asn1_DEFAULT,
+ b = asn1_DEFAULT,
+ c = asn1_DEFAULT}).
+-record('SeqEnum',{a = asn1_DEFAULT,
+ b = asn1_DEFAULT}).
+-record('SetEnum',{a = asn1_DEFAULT,
+ b = asn1_DEFAULT}).
+-record('SeqIntBool',{a = asn1_DEFAULT,
+ b = asn1_DEFAULT,
+ c = asn1_DEFAULT}).
+-record('SeqIntBool_a',{aa = asn1_DEFAULT,
+ ab = asn1_DEFAULT}).
+-record('SetIntBool',{a = asn1_DEFAULT,
+ b = asn1_DEFAULT,
+ c = asn1_DEFAULT}).
+-record('SetIntBool_a',{aa = asn1_DEFAULT,
+ ab = asn1_DEFAULT}).
+-record('SeqStrings',{a = asn1_DEFAULT,
+ b1 = asn1_DEFAULT,
+ b2 = asn1_DEFAULT,
+ b3 = asn1_DEFAULT,
+ c = asn1_DEFAULT,
+ d = asn1_DEFAULT}).
+-record('SetStrings',{a = asn1_DEFAULT,
+ b1 = asn1_DEFAULT,
+ b2 = asn1_DEFAULT,
+ b3 = asn1_DEFAULT,
+ c = asn1_DEFAULT,
+ d = asn1_DEFAULT}).
+-record('S1',{a = asn1_DEFAULT,
+ b = asn1_DEFAULT}).
+-record('S1_a',{aa = asn1_DEFAULT,
+ ab = asn1_DEFAULT}).
+-record('S2',{a = asn1_DEFAULT, b=asn1_NOVALUE}).
+-record('S3',{a = asn1_DEFAULT,
+ b = asn1_DEFAULT,
+ c = asn1_DEFAULT,
+ d = asn1_DEFAULT}).
+-record('S3set',{a = asn1_DEFAULT,
+ b = asn1_DEFAULT}).
+-record('S4',{a = asn1_DEFAULT,
+ b = asn1_DEFAULT}).
+-record('S4_b',{ba = asn1_DEFAULT,
+ bb = asn1_DEFAULT}).
+
+
+compile(Config,Rules) ->
+ ?line DataDir = ?config(data_dir,Config),
+ ?line OutDir = ?config(priv_dir,Config),
+ ?line true = code:add_patha(?config(priv_dir,Config)),
+ ?line ok = asn1ct:compile(DataDir ++ "Default",
+ [Rules,der,{outdir,OutDir}]).
+
+main(_Rules) ->
+
+ ?line {ok,[48,0]} =
+ asn1_wrapper:encode('Default','SeqInts',#'SeqInts'{}),
+ ?line {ok,[48,0]} =
+ asn1_wrapper:encode('Default','SeqInts',#'SeqInts'{a=1,b=-1,c=three,
+ d=1}),
+ ?line {ok,{'SeqInts',1,-1,3,1}} =
+ asn1_wrapper:decode('Default','SeqInts',[48,0]),
+
+ ?line {ok,[49,0]} =
+ asn1_wrapper:encode('Default','SetInts',#'SetInts'{}),
+ ?line {ok,[49,0]} =
+ asn1_wrapper:encode('Default','SetInts',#'SetInts'{a=1,b=-1,c=three,
+ d=1}),
+ ?line {ok,{'SetInts',1,-1,3,1}} =
+ asn1_wrapper:decode('Default','SetInts',[49,0]),
+
+
+ ?line {ok,[48,0]} =
+ asn1_wrapper:encode('Default','SeqBS',
+ #'SeqBS'{a=2#1010110,
+ b=16#A8A,
+ c=[second],
+ d=[1,0,0,1]}),
+
+ ?line {ok,[48,0]} =
+ asn1_wrapper:encode('Default','SeqBS',
+ #'SeqBS'{a=[1,0,1,0,1,1,0],
+ b=[1,0,1,0,1,0,0,0,1,0,1,0],
+ c={5,<<64>>},
+ d=9}),
+
+ ?line {ok,[48,3,131,1,0]} =
+ asn1_wrapper:encode('Default','SeqBS',
+ #'SeqBS'{a=[1,0,1,0,1,1,0],
+ b=[1,0,1,0,1,0,0,0,1,0,1,0],
+ c={5,<<64>>},
+ d=0}),
+
+ ?line {ok,{'SeqBS',[1,0,1,0,1,1,0],2698,[second],[]}} =
+ asn1_wrapper:decode('Default','SeqBS',[48,3,131,1,0]),
+
+ ?line {ok,{'SeqBS',[1,0,1,0,1,1,0],2698,[second],[1,0,0,1]}} =
+ asn1_wrapper:decode('Default','SeqBS',[48,0]),
+
+ ?line {ok,[49,0]} =
+ asn1_wrapper:encode('Default','SetBS',
+ #'SetBS'{a=2#1010110,
+ b=16#A8A,
+ c=[second],
+ d=[1,0,0,1]}),
+
+ ?line {ok,[49,0]} =
+ asn1_wrapper:encode('Default','SetBS',
+ #'SetBS'{a=[1,0,1,0,1,1,0],
+ b=[1,0,1,0,1,0,0,0,1,0,1,0],
+ c={5,<<64>>},
+ d=9}),
+
+ ?line {ok,[49,3,131,1,0]} =
+ asn1_wrapper:encode('Default','SetBS',
+ #'SetBS'{a=[1,0,1,0,1,1,0],
+ b=[1,0,1,0,1,0,0,0,1,0,1,0],
+ c={5,<<64>>},
+ d=0}),
+
+ ?line {ok,{'SetBS',[1,0,1,0,1,1,0],2698,[second],[]}} =
+ asn1_wrapper:decode('Default','SetBS',[49,3,131,1,0]),
+
+ ?line {ok,{'SetBS',[1,0,1,0,1,1,0],2698,[second],[1,0,0,1]}} =
+ asn1_wrapper:decode('Default','SetBS',[49,0]),
+
+ ?line {ok,[48,0]} =
+ asn1_wrapper:encode('Default','SeqOS',
+ #'SeqOS'{a=[172],
+ b=[16#A8,16#A0],
+ c='NULL'}),
+
+ ?line {ok,[48,0]} =
+ asn1_wrapper:encode('Default','SeqOS',
+ #'SeqOS'{a=2#10101100,
+ b=16#A8A0,
+ c='NULL'}),
+
+ ?line {ok,{'SeqOS',[172],[16#A8,16#A0],'NULL'}} =
+ asn1_wrapper:decode('Default','SeqOS',[48,0]),
+
+ ?line {ok,[49,0]} =
+ asn1_wrapper:encode('Default','SetOS',
+ #'SetOS'{a=[172],
+ b=[16#A8,16#A0],
+ c='NULL'}),
+
+ ?line {ok,[49,0]} =
+ asn1_wrapper:encode('Default','SetOS',
+ #'SetOS'{a=2#10101100,
+ b=16#A8A0,
+ c='NULL'}),
+
+ ?line {ok,{'SetOS',[172],[16#A8,16#A0],'NULL'}} =
+ asn1_wrapper:decode('Default','SetOS',[49,0]),
+
+ ?line {ok,[48,0]} =
+ asn1_wrapper:encode('Default','SeqOI',
+ #'SeqOI'{a={1,2,14,15},
+ b={iso,'member-body',250,3,4},
+ c={iso,standard,8571,2,250,4}}),
+
+ ?line {ok,{'SeqOI',{1,2,14,15},{1,2,250,3,4},{1,0,8571,2,250,4}}} =
+ asn1_wrapper:decode('Default','SeqOI',[48,0]),
+
+ ?line {ok,[49,0]} =
+ asn1_wrapper:encode('Default','SetOI',
+ #'SetOI'{a={1,2,14,15},
+ b={iso,'member-body',250,3,4},
+ c={iso,standard,8571,2,250,4}}),
+
+ ?line {ok,{'SetOI',{1,2,14,15},{1,2,250,3,4},{1,0,8571,2,250,4}}} =
+ asn1_wrapper:decode('Default','SetOI',[49,0]),
+
+ ?line {ok,[48,0]} =
+ asn1_wrapper:encode('Default','SeqEnum',#'SeqEnum'{a=b4,b=b2}),
+
+ ?line {ok,{'SeqEnum',b4,b2}} =
+ asn1_wrapper:decode('Default','SeqEnum',[48,0]),
+
+ ?line {ok,[49,0]} =
+ asn1_wrapper:encode('Default','SetEnum',#'SetEnum'{a=b4,b=b2}),
+
+ ?line {ok,{'SetEnum',b4,b2}} =
+ asn1_wrapper:decode('Default','SetEnum',[49,0]),
+
+ ?line {ok,[48,0]} =
+ asn1_wrapper:encode('Default','SeqIntBool',
+ #'SeqIntBool'{a=#'SeqIntBool_a'{aa=12,ab=13},
+ b=#'S2'{a=14,b=true},
+ c=#'S2'{a=15,b=false}}),
+
+ ?line {ok,[48,0]} =
+ asn1_wrapper:encode('Default','SeqIntBool',
+ #'SeqIntBool'{}),
+
+ ?line {ok,{'SeqIntBool',{'SeqIntBool_a',12,13},
+ {'S2',14,true},{'S2',15,false}}} =
+ asn1_wrapper:decode('Default','SeqIntBool',[48,0]),
+
+ ?line {ok,[49,0]} =
+ asn1_wrapper:encode('Default','SetIntBool',
+ #'SetIntBool'{a=#'SetIntBool_a'{aa=12,ab=13},
+ b=#'S2'{a=14,b=true},
+ c=#'S2'{a=15,b=false}}),
+
+ ?line {ok,[49,0]} =
+ asn1_wrapper:encode('Default','SetIntBool',
+ #'SetIntBool'{}),
+
+ ?line {ok,{'SetIntBool',{'SetIntBool_a',12,13},
+ {'S2',14,true},{'S2',15,false}}} =
+ asn1_wrapper:decode('Default','SetIntBool',[49,0]),
+
+ ?line {ok,[48,0]} =
+ asn1_wrapper:encode('Default','SeqStrings',
+ #'SeqStrings'{a="123456789",
+ b1="abcdef",
+ b2={0,13},
+ b3={"First line",{0,13},"Second line"},
+ c="Printable string",
+ d={0,0,1,14}}),
+
+ ?line {ok,{'SeqStrings',"123456789","abcdef",[0,13],
+ ["First line",[0,13],"Second line"],"Printable string",
+ [0,0,1,14]}} =
+ asn1_wrapper:decode('Default','SeqStrings',[48,0]),
+
+ ?line {ok,[49,0]} =
+ asn1_wrapper:encode('Default','SetStrings',
+ #'SetStrings'{a="123456789",
+ b1="abcdef",
+ b2={0,13},
+ b3={"First line",{0,13},"Second line"},
+ c="Printable string",
+ d={0,0,1,14}}),
+
+ ?line {ok,{'SetStrings',"123456789","abcdef",[0,13],
+ ["First line",[0,13],"Second line"],"Printable string",
+ [0,0,1,14]}} =
+ asn1_wrapper:decode('Default','SetStrings',[49,0]),
+
+
+ ?line {ok,[48,0]} =
+ asn1_wrapper:encode('Default','S1',
+ #'S1'{a=#'S1_a'{aa=1,
+ ab=#'S2'{a=2,b=true}},
+ b=#'S4'{a=#'S2'{a=2,b=true},
+ b=#'S4_b'{ba=true,
+ bb=5}}}),
+
+ ?line {ok,{'S1',{'S1_a',1,{'S2',2,true}},
+ {'S4',{'S2',2,true},{'S4_b',true,5}}}} =
+ asn1_wrapper:decode('Default','S1',[48,0]),
+
+ ?line {ok,[48,3,129,1,255]} =
+ asn1_wrapper:encode('Default','S2',
+ #'S2'{a=1,b=true}),
+
+ ?line {ok,[48,0]} =
+ asn1_wrapper:encode('Default','S3',
+ #'S3'{a=[11,12,13],
+ b=[{a,11},{b,true},{c,13}],
+ c=[1,2,3,4],
+ d=[#'S2'{a=20,b=true},#'S2'{a=30,b=false}]}),
+
+ ?line {ok,[48,0]} =
+ asn1_wrapper:encode('Default','S3',
+ #'S3'{a=[11,13,12],
+ b=[{b,true},{a,11},{c,13}],
+ c=[3,4,1,2],
+ d=[#'S2'{a=30,b=false},#'S2'{a=20,b=true}]}),
+
+ ?line {ok,[48,0]} = asn1_wrapper:encode('Default','S3',#'S3'{}),
+
+ ?line {ok,[49,0]} =
+ asn1_wrapper:encode('Default','S3set',
+ #'S3set'{a=[{c,#'S2'{a=3,b=true}},
+ {b,17},{a,false}],
+ b=[1,2,3,4]}),
+
+ ?line {ok,[49,0]} =
+ asn1_wrapper:encode('Default','S3set',
+ #'S3set'{a=[{b,17},{c,#'S2'{a=3,b=true}},
+ {a,false}],
+ b=[1,3,4,2]}),
+
+ ?line {ok,[49,0]} = asn1_wrapper:encode('Default','S3set',#'S3set'{}),
+
+ ?line {ok,[48,0]} =
+ asn1_wrapper:encode('Default','S4',#'S4'{a={'S2',1,asn1_NOVALUE},
+ b=#'S4_b'{ba=true,bb=0}}),
+ ok.
diff --git a/lib/asn1/test/testSeqTag.erl b/lib/asn1/test/testSeqTag.erl
new file mode 100644
index 0000000000..ff6d1bbe91
--- /dev/null
+++ b/lib/asn1/test/testSeqTag.erl
@@ -0,0 +1,114 @@
+%%
+%% %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(testSeqTag).
+
+-export([compile/3]).
+-export([main/1]).
+
+-include("test_server.hrl").
+-include("External.hrl").
+
+-record('SeqTag',{nt, imp, exp}).
+-record('SeqTagImp',{nt, imp, exp}).
+-record('SeqTagExp',{nt, imp, exp}).
+-record('SeqTagX',{xnt, ximp, xexp}).
+-record('SeqTagImpX',{xnt, ximp, xexp}).
+-record('SeqTagExpX',{xnt, ximp, xexp}).
+-record('NT',{os, bool}).
+-record('Imp',{os, bool}).
+-record('Exp',{os, bool}).
+
+
+compile(Config,Rules,Options) ->
+
+ ?line DataDir = ?config(data_dir,Config),
+ ?line OutDir = ?config(priv_dir,Config),
+ ?line true = code:add_patha(?config(priv_dir,Config)),
+ ?line ok = asn1ct:compile(DataDir ++ "SeqTag",[Rules,{outdir,OutDir}]++Options).
+
+
+
+main(_Rules) ->
+
+
+ ?line {ok,Bytes11} =
+ asn1_wrapper:encode('SeqTag','SeqTag',#'SeqTag'{nt = #'NT'{bool = true, os = "kalle"},
+ imp = #'Imp'{bool = true, os = "kalle"},
+ exp = #'Exp'{bool = true, os = "kalle"}}),
+ ?line {ok,{'SeqTag',{'NT',"kalle",true},{'Imp',"kalle",true},{'Exp',"kalle",true}}} =
+ asn1_wrapper:decode('SeqTag','SeqTag',lists:flatten(Bytes11)),
+
+
+ ?line {ok,Bytes12} =
+ asn1_wrapper:encode('SeqTag','SeqTagImp',#'SeqTagImp'{nt = #'NT'{bool = true, os = "kalle"},
+ imp = #'Imp'{bool = true, os = "kalle"},
+ exp = #'Exp'{bool = true, os = "kalle"}}),
+ ?line {ok,{'SeqTagImp',{'NT',"kalle",true},{'Imp',"kalle",true},{'Exp',"kalle",true}}} =
+ asn1_wrapper:decode('SeqTag','SeqTagImp',lists:flatten(Bytes12)),
+
+
+ ?line {ok,Bytes13} =
+ asn1_wrapper:encode('SeqTag','SeqTagExp',#'SeqTagExp'{nt = #'NT'{bool = true, os = "kalle"},
+ imp = #'Imp'{bool = true, os = "kalle"},
+ exp = #'Exp'{bool = true, os = "kalle"}}),
+ ?line {ok,{'SeqTagExp',{'NT',"kalle",true},{'Imp',"kalle",true},{'Exp',"kalle",true}}} =
+ asn1_wrapper:decode('SeqTag','SeqTagExp',lists:flatten(Bytes13)),
+
+
+
+
+
+ ?line {ok,Bytes21} =
+ asn1_wrapper:encode('SeqTag','SeqTagX',
+ #'SeqTagX'{xnt = #'XSeqNT'{bool = true, os = "kalle"},
+ ximp = #'XSeqImp'{bool = true, os = "kalle"},
+ xexp = #'XSeqExp'{bool = true, os = "kalle"}}),
+ ?line {ok,{'SeqTagX',{'XSeqNT',"kalle",true},
+ {'XSeqImp',"kalle",true},
+ {'XSeqExp',"kalle",true}}} =
+ asn1_wrapper:decode('SeqTag','SeqTagX',lists:flatten(Bytes21)),
+
+
+ ?line {ok,Bytes22} =
+ asn1_wrapper:encode('SeqTag','SeqTagImpX',
+ #'SeqTagImpX'{xnt = #'XSeqNT'{bool = true, os = "kalle"},
+ ximp = #'XSeqImp'{bool = true, os = "kalle"},
+ xexp = #'XSeqExp'{bool = true, os = "kalle"}}),
+ ?line {ok,{'SeqTagImpX',{'XSeqNT',"kalle",true},
+ {'XSeqImp',"kalle",true},
+ {'XSeqExp',"kalle",true}}} =
+ asn1_wrapper:decode('SeqTag','SeqTagImpX',lists:flatten(Bytes22)),
+
+
+ ?line {ok,Bytes23} =
+ asn1_wrapper:encode('SeqTag','SeqTagExpX',
+ #'SeqTagExpX'{xnt = #'XSeqNT'{bool = true, os = "kalle"},
+ ximp = #'XSeqImp'{bool = true, os = "kalle"},
+ xexp = #'XSeqExp'{bool = true, os = "kalle"}}),
+ ?line {ok,{'SeqTagExpX',{'XSeqNT',"kalle",true},
+ {'XSeqImp',"kalle",true},
+ {'XSeqExp',"kalle",true}}} =
+ asn1_wrapper:decode('SeqTag','SeqTagExpX',lists:flatten(Bytes23)),
+
+
+
+
+
+ ok.
diff --git a/lib/asn1/test/testSeqTypeRefCho.erl b/lib/asn1/test/testSeqTypeRefCho.erl
new file mode 100644
index 0000000000..03933d68ae
--- /dev/null
+++ b/lib/asn1/test/testSeqTypeRefCho.erl
@@ -0,0 +1,54 @@
+%%
+%% %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(testSeqTypeRefCho).
+
+-export([compile/3]).
+-export([main/1]).
+
+-include("test_server.hrl").
+-include("External.hrl").
+
+-record('SeqTRcho',{seqCho, seqChoE, 'seqCho-E', 'seqChoE-E'}).
+
+
+compile(Config,Rules,Options) ->
+
+ ?line DataDir = ?config(data_dir,Config),
+ ?line OutDir = ?config(priv_dir,Config),
+ ?line true = code:add_patha(?config(priv_dir,Config)),
+ ?line ok = asn1ct:compile(DataDir ++ "SeqTypeRefCho",[Rules,{outdir,OutDir}]++Options).
+
+
+
+main(_Rules) ->
+
+
+ ?line {ok,Bytes11} =
+ asn1_wrapper:encode('SeqTypeRefCho','SeqTRcho',
+ #'SeqTRcho'{'seqCho' = {choOs,"A string 1"},
+ 'seqChoE' = {choOs,"A string 3"},
+ 'seqCho-E' = {choOs,"A string 7"},
+ 'seqChoE-E' = {choOs,"A string 9"}}),
+ ?line {ok,{'SeqTRcho',{choOs,"A string 1"},{choOs,"A string 3"},{choOs,"A string 7"},{choOs,"A string 9"}}} =
+ asn1_wrapper:decode('SeqTypeRefCho','SeqTRcho',lists:flatten(Bytes11)),
+
+
+
+ ok.
diff --git a/lib/asn1/test/testSeqTypeRefPrim.erl b/lib/asn1/test/testSeqTypeRefPrim.erl
new file mode 100644
index 0000000000..264fc24f85
--- /dev/null
+++ b/lib/asn1/test/testSeqTypeRefPrim.erl
@@ -0,0 +1,57 @@
+%%
+%% %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(testSeqTypeRefPrim).
+
+-export([compile/3]).
+-export([main/1]).
+
+-include("test_server.hrl").
+
+-record('SeqTR',{octStr, octStrI, octStrE, 'octStr-I', 'octStrI-I', 'octStrE-I', 'octStr-E', 'octStrI-E', 'octStrE-E'}).
+
+
+compile(Config,Rules,Options) ->
+
+ ?line DataDir = ?config(data_dir,Config),
+ ?line OutDir = ?config(priv_dir,Config),
+ ?line true = code:add_patha(?config(priv_dir,Config)),
+ ?line ok = asn1ct:compile(DataDir ++ "SeqTypeRefPrim",[Rules,{outdir,OutDir}]++Options).
+
+
+
+main(_Rules) ->
+
+
+ ?line {ok,Bytes11} =
+ asn1_wrapper:encode('SeqTypeRefPrim','SeqTR',#'SeqTR'{'octStr' = "A string 1",
+ 'octStrI' = "A string 2",
+ 'octStrE' = "A string 3",
+ 'octStr-I' = "A string 4",
+ 'octStrI-I' = "A string 5",
+ 'octStrE-I' = "A string 6",
+ 'octStr-E' = "A string 7",
+ 'octStrI-E' = "A string 8",
+ 'octStrE-E' = "A string 9"}) ,
+ ?line {ok,{'SeqTR',"A string 1","A string 2","A string 3","A string 4","A string 5","A string 6","A string 7","A string 8","A string 9"}} =
+ asn1_wrapper:decode('SeqTypeRefPrim','SeqTR',lists:flatten(Bytes11)),
+
+
+
+ ok.
diff --git a/lib/asn1/test/testSeqTypeRefSeq.erl b/lib/asn1/test/testSeqTypeRefSeq.erl
new file mode 100644
index 0000000000..b01c14ee32
--- /dev/null
+++ b/lib/asn1/test/testSeqTypeRefSeq.erl
@@ -0,0 +1,186 @@
+%%
+%% %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(testSeqTypeRefSeq).
+
+-export([compile/3]).
+-export([main/1]).
+
+-include("test_server.hrl").
+
+-record('Seq1',{bool1, int1, seq1}).
+-record('Seq2',{seq2, bool2, int2}).
+-record('Seq3',{bool3, seq3, int3}).
+-record('Seq4',{seq41, seq42, seq43}).
+-record('SeqIn',{boolIn, intIn}).
+-record('SeqS1',{boolS1, intS1, seqS1}).
+-record('SeqS1_seqS1',{boolIn, intIn}).
+-record('SeqS2',{seqS2, boolS2, intS2}).
+-record('SeqS2_seqS2',{boolIn, intIn}).
+-record('SeqS3',{boolS3, seqS3, intS3}).
+-record('SeqS3_seqS3',{boolIn, intIn}).
+-record('SeqSTag',{seqS1, seqS2, seqS3}).
+-record('SeqSTag_seqS1',{b1, i1}).
+-record('SeqSTag_seqS2',{b2, i2}).
+-record('SeqSTag_seqS3',{b3, i3}).
+-record('SeqTRseq',{seqSeq, seqSeqI, seqSeqE, 'seqSeq-I', 'seqSeqI-I', 'seqSeqE-I', 'seqSeq-E', 'seqSeqI-E', 'seqSeqE-E'}).
+-record('SeqSeq',{seqInt, seqOs}).
+-record('SeqSeqImp',{seqInt, seqOs}).
+-record('SeqSeqExp',{seqInt, seqOs}).
+
+
+
+compile(Config,Rules,Options) ->
+
+ ?line DataDir = ?config(data_dir,Config),
+ ?line OutDir = ?config(priv_dir,Config),
+ ?line true = code:add_patha(?config(priv_dir,Config)),
+ ?line ok = asn1ct:compile(DataDir ++ "SeqTypeRefSeq",[Rules,{outdir,OutDir}]++Options).
+
+
+
+main(_Rules) ->
+
+
+ ?line {ok,Bytes11} =
+ asn1_wrapper:encode('SeqTypeRefSeq','Seq1',#'Seq1'{bool1 = true,
+ int1 = 15,
+ seq1 = #'SeqIn'{boolIn = true,
+ intIn = 66}}),
+ ?line {ok,{'Seq1',true,15,{'SeqIn',true,66}}} =
+ asn1_wrapper:decode('SeqTypeRefSeq','Seq1',lists:flatten(Bytes11)),
+
+
+
+ ?line {ok,Bytes12} =
+ asn1_wrapper:encode('SeqTypeRefSeq','Seq2',#'Seq2'{seq2 = #'SeqIn'{boolIn = true,
+ intIn = 66},
+ bool2 = true,
+ int2 = 15}),
+ ?line {ok,{'Seq2',{'SeqIn',true,66},true,15}} =
+ asn1_wrapper:decode('SeqTypeRefSeq','Seq2',lists:flatten(Bytes12)),
+
+
+ ?line {ok,Bytes13} =
+ asn1_wrapper:encode('SeqTypeRefSeq','Seq3',#'Seq3'{bool3 = true,
+ seq3 = #'SeqIn'{boolIn = true,
+ intIn = 66},
+ int3 = 15}),
+ ?line {ok,{'Seq3',true,{'SeqIn',true,66},15}} =
+ asn1_wrapper:decode('SeqTypeRefSeq','Seq3',lists:flatten(Bytes13)),
+
+
+
+ ?line {ok,Bytes14} =
+ asn1_wrapper:encode('SeqTypeRefSeq','Seq4',#'Seq4'{seq41 = #'SeqIn'{boolIn = true,
+ intIn = 66},
+ seq42 = #'SeqIn'{boolIn = true,
+ intIn = 66},
+ seq43 = #'SeqIn'{boolIn = true,
+ intIn = 66}}),
+ ?line {ok,{'Seq4',{'SeqIn',true,66},{'SeqIn',true,66},{'SeqIn',true,66}}} =
+ asn1_wrapper:decode('SeqTypeRefSeq','Seq4',lists:flatten(Bytes14)),
+
+
+
+
+
+
+
+
+ ?line {ok,Bytes21} =
+ asn1_wrapper:encode('SeqTypeRefSeq','SeqS1',#'SeqS1'{boolS1 = true,
+ intS1 = 15,
+ seqS1 = #'SeqS1_seqS1'{boolIn = true,
+ intIn = 66}}),
+ ?line {ok,{'SeqS1',true,15,{'SeqS1_seqS1',true,66}}} =
+ asn1_wrapper:decode('SeqTypeRefSeq','SeqS1',lists:flatten(Bytes21)),
+
+
+ ?line {ok,Bytes22} =
+ asn1_wrapper:encode('SeqTypeRefSeq','SeqS2',#'SeqS2'{seqS2 = #'SeqS2_seqS2'{boolIn = true,
+ intIn = 66},
+ boolS2 = true,
+ intS2 = 15}),
+ ?line {ok,{'SeqS2',{'SeqS2_seqS2',true,66},true,15}} =
+ asn1_wrapper:decode('SeqTypeRefSeq','SeqS2',lists:flatten(Bytes22)),
+
+
+
+ ?line {ok,Bytes23} =
+ asn1_wrapper:encode('SeqTypeRefSeq','SeqS3',#'SeqS3'{boolS3 = true,
+ seqS3 = #'SeqS3_seqS3'{boolIn = true,
+ intIn = 66},
+ intS3 = 15}),
+ ?line {ok,{'SeqS3',true,{'SeqS3_seqS3',true,66},15}} =
+ asn1_wrapper:decode('SeqTypeRefSeq','SeqS3',lists:flatten(Bytes23)),
+
+
+
+
+
+
+ ?line {ok,Bytes31} =
+ asn1_wrapper:encode('SeqTypeRefSeq','SeqSTag',#'SeqSTag'{seqS1 = #'SeqSTag_seqS1'{b1 = true,
+ i1 = 11},
+ seqS2 = #'SeqSTag_seqS2'{b2 = true,
+ i2 = 22},
+ seqS3 = #'SeqSTag_seqS3'{b3 = true,
+ i3 = 33}}),
+ ?line {ok,{'SeqSTag',{'SeqSTag_seqS1',true,11},
+ {'SeqSTag_seqS2',true,22},
+ {'SeqSTag_seqS3',true,33}}} =
+ asn1_wrapper:decode('SeqTypeRefSeq','SeqSTag',lists:flatten(Bytes31)),
+
+
+
+
+
+ ?line {ok,Bytes41} =
+ asn1_wrapper:encode('SeqTypeRefSeq','SeqTRseq',
+ #'SeqTRseq'{'seqSeq' = #'SeqSeq'{seqOs = "A1",
+ seqInt = 2},
+ 'seqSeqI' = #'SeqSeq'{seqOs = "A2",
+ seqInt = 2},
+ 'seqSeqE' = #'SeqSeq'{seqOs = "A3",
+ seqInt = 2},
+ 'seqSeq-I' = #'SeqSeqImp'{seqOs = "A4",
+ seqInt = 2},
+ 'seqSeqI-I' = #'SeqSeqImp'{seqOs = "A5",
+ seqInt = 2},
+ 'seqSeqE-I' = #'SeqSeqImp'{seqOs = "A6",
+ seqInt = 2},
+ 'seqSeq-E' = #'SeqSeqExp'{seqOs = "A7",
+ seqInt = 2},
+ 'seqSeqI-E' = #'SeqSeqExp'{seqOs = "A8",
+ seqInt = 2},
+ 'seqSeqE-E' = #'SeqSeqExp'{seqOs = "A9",
+ seqInt = 2}}),
+ ?line {ok,{'SeqTRseq',{'SeqSeq',2,"A1"},
+ {'SeqSeq',2,"A2"},
+ {'SeqSeq',2,"A3"},
+ {'SeqSeqImp',2,"A4"},
+ {'SeqSeqImp',2,"A5"},
+ {'SeqSeqImp',2,"A6"},
+ {'SeqSeqExp',2,"A7"},
+ {'SeqSeqExp',2,"A8"},
+ {'SeqSeqExp',2,"A9"}}} =
+ asn1_wrapper:decode('SeqTypeRefSeq','SeqTRseq',lists:flatten(Bytes41)),
+
+ ok.
diff --git a/lib/asn1/test/testSeqTypeRefSet.erl b/lib/asn1/test/testSeqTypeRefSet.erl
new file mode 100644
index 0000000000..92d2cadf28
--- /dev/null
+++ b/lib/asn1/test/testSeqTypeRefSet.erl
@@ -0,0 +1,76 @@
+%%
+%% %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(testSeqTypeRefSet).
+
+-export([compile/3]).
+-export([main/1]).
+
+-include("test_server.hrl").
+
+-record('SeqTRset',{seqSet, seqSetI, seqSetE, 'seqSet-I', 'seqSetI-I', 'seqSetE-I', 'seqSet-E', 'seqSetI-E', 'seqSetE-E'}).
+-record('SeqSet',{setInt, setOs}).
+-record('SeqSetImp',{setInt, setOs}).
+-record('SeqSetExp',{setInt, setOs}).
+
+
+
+compile(Config,Rules,Options) ->
+
+ ?line DataDir = ?config(data_dir,Config),
+ ?line OutDir = ?config(priv_dir,Config),
+ ?line true = code:add_patha(?config(priv_dir,Config)),
+ ?line ok = asn1ct:compile(DataDir ++ "SeqTypeRefSet",[Rules,{outdir,OutDir}]++Options).
+
+
+
+main(_Rules) ->
+
+ ?line {ok,Bytes41} =
+ asn1_wrapper:encode('SeqTypeRefSet','SeqTRset',
+ #'SeqTRset'{'seqSet' = #'SeqSet'{setOs = "A1",
+ setInt = 2},
+ 'seqSetI' = #'SeqSet'{setOs = "A2",
+ setInt = 2},
+ 'seqSetE' = #'SeqSet'{setOs = "A3",
+ setInt = 2},
+ 'seqSet-I' = #'SeqSetImp'{setOs = "A4",
+ setInt = 2},
+ 'seqSetI-I' = #'SeqSetImp'{setOs = "A5",
+ setInt = 2},
+ 'seqSetE-I' = #'SeqSetImp'{setOs = "A6",
+ setInt = 2},
+ 'seqSet-E' = #'SeqSetExp'{setOs = "A7",
+ setInt = 2},
+ 'seqSetI-E' = #'SeqSetExp'{setOs = "A8",
+ setInt = 2},
+ 'seqSetE-E' = #'SeqSetExp'{setOs = "A9",
+ setInt = 2}}),
+ ?line {ok,{'SeqTRset',{'SeqSet',2,"A1"},
+ {'SeqSet',2,"A2"},
+ {'SeqSet',2,"A3"},
+ {'SeqSetImp',2,"A4"},
+ {'SeqSetImp',2,"A5"},
+ {'SeqSetImp',2,"A6"},
+ {'SeqSetExp',2,"A7"},
+ {'SeqSetExp',2,"A8"},
+ {'SeqSetExp',2,"A9"}}} =
+ asn1_wrapper:decode('SeqTypeRefSet','SeqTRset',lists:flatten(Bytes41)),
+
+ ok.
diff --git a/lib/asn1/test/testSetDefault.erl b/lib/asn1/test/testSetDefault.erl
new file mode 100644
index 0000000000..e4b6a0ab82
--- /dev/null
+++ b/lib/asn1/test/testSetDefault.erl
@@ -0,0 +1,94 @@
+%%
+%% %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(testSetDefault).
+
+-export([compile/3]).
+-export([main/1]).
+
+-include("test_server.hrl").
+
+-record('SetDef1',{bool1 = asn1_DEFAULT, int1, set1 = asn1_DEFAULT}).
+-record('SetDef2',{set2 = asn1_DEFAULT, bool2, int2}).
+-record('SetDef3',{bool3 = asn1_DEFAULT, set3 = asn1_DEFAULT, int3 = asn1_DEFAULT}).
+-record('SetIn',{boolIn, intIn}).
+
+
+
+compile(Config,Rules,Options) ->
+
+ ?line DataDir = ?config(data_dir,Config),
+ ?line OutDir = ?config(priv_dir,Config),
+ ?line true = code:add_patha(?config(priv_dir,Config)),
+ ?line ok = asn1ct:compile(DataDir ++ "SetDefault",[Rules,{outdir,OutDir}]++Options).
+
+
+
+main(_Rules) ->
+
+ ?line {ok,Bytes11} =
+ asn1_wrapper:encode('SetDefault','SetDef1',#'SetDef1'{bool1 = true,
+ int1 = 15,
+ set1 = #'SetIn'{boolIn = true,
+ intIn = 66}}),
+ ?line {ok,{'SetDef1',true,15,{'SetIn',true,66}}} =
+ asn1_wrapper:decode('SetDefault','SetDef1',lists:flatten(Bytes11)),
+
+
+ ?line {ok,Bytes12} = asn1_wrapper:encode('SetDefault','SetDef1',#'SetDef1'{int1 = 15}),
+ ?line {ok,{'SetDef1',true,15,{'SetIn',asn1_NOVALUE,12}}} =
+ asn1_wrapper:decode('SetDefault','SetDef1',lists:flatten(Bytes12)),
+
+
+ ?line {ok,Bytes21} =
+ asn1_wrapper:encode('SetDefault','SetDef2',#'SetDef2'{bool2 = true,
+ int2 = 15,
+ set2 = #'SetIn'{boolIn = true,
+ intIn = 66}}),
+ ?line {ok,{'SetDef2',{'SetIn',true,66},true,15}} =
+ asn1_wrapper:decode('SetDefault','SetDef2',lists:flatten(Bytes21)),
+
+
+ ?line {ok,Bytes22} = asn1_wrapper:encode('SetDefault','SetDef2',#'SetDef2'{bool2 = true,
+ int2 = 15}),
+ ?line {ok,{'SetDef2',{'SetIn',asn1_NOVALUE,12},true,15}} =
+ asn1_wrapper:decode('SetDefault','SetDef2',lists:flatten(Bytes22)),
+
+
+
+ ?line {ok,Bytes31} =
+ asn1_wrapper:encode('SetDefault','SetDef3',#'SetDef3'{bool3 = true,
+ int3 = 15,
+ set3 = #'SetIn'{boolIn = true,
+ intIn = 66}}),
+ ?line {ok,{'SetDef3',true,{'SetIn',true,66},15}} =
+ asn1_wrapper:decode('SetDefault','SetDef3',lists:flatten(Bytes31)),
+
+
+ ?line {ok,Bytes32} = asn1_wrapper:encode('SetDefault','SetDef3',#'SetDef3'{int3 = 15}),
+ ?line {ok,{'SetDef3',true,{'SetIn',asn1_NOVALUE,12},15}} =
+ asn1_wrapper:decode('SetDefault','SetDef3',lists:flatten(Bytes32)),
+
+
+
+
+
+
+
+ ok.
diff --git a/lib/asn1/test/testSetExtension.erl b/lib/asn1/test/testSetExtension.erl
new file mode 100644
index 0000000000..85a84e020a
--- /dev/null
+++ b/lib/asn1/test/testSetExtension.erl
@@ -0,0 +1,106 @@
+%%
+%% %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(testSetExtension).
+
+
+-include("External.hrl").
+-export([compile/3]).
+-export([main/1]).
+
+-include("test_server.hrl").
+
+-record('SetExt1',{}).
+-record('SetExt2',{bool, int}).
+-record('SetExt3',{bool, int}).
+-record('SetExt4',{bool, int}).
+
+
+compile(Config,Rules,Options) ->
+
+ ?line DataDir = ?config(data_dir,Config),
+ ?line OutDir = ?config(priv_dir,Config),
+ ?line true = code:add_patha(?config(priv_dir,Config)),
+ ?line ok = asn1ct:compile(DataDir ++ "SetExtension",
+ [Rules,{outdir,OutDir}]++Options).
+
+
+
+main(_Rules) ->
+
+ ?line {ok,Bytes11} =
+ asn1_wrapper:encode('SetExtension','SetExt1',#'SetExt1'{}),
+ ?line {ok,{'SetExt1'}} =
+ asn1_wrapper:decode('SetExtension','SetExt1',lists:flatten(Bytes11)),
+
+ ?line {ok,Bytes21} =
+ asn1_wrapper:encode('SetExtension','SetExt2',#'SetExt2'{bool = true,int = 99}),
+ ?line {ok,{'SetExt2',true,99}} =
+ asn1_wrapper:decode('SetExtension','SetExt2',lists:flatten(Bytes21)),
+
+ ?line {ok,Bytes22} =
+ asn1_wrapper:encode('SetExtension','SetExt2',#'SetExt2'{int = 99,bool = true}),
+ ?line {ok,{'SetExt2',true,99}} =
+ asn1_wrapper:decode('SetExtension','SetExt2',lists:flatten(Bytes22)),
+
+ ?line {ok,Bytes31} =
+ asn1_wrapper:encode('SetExtension','SetExt3',#'SetExt3'{bool = true,int = 99}),
+ ?line {ok,{'SetExt3',true,99}} =
+ asn1_wrapper:decode('SetExtension','SetExt3',lists:flatten(Bytes31)),
+
+ ?line {ok,Bytes32} =
+ asn1_wrapper:encode('SetExtension','SetExt3',#'SetExt3'{int = 99,bool = true}),
+ ?line {ok,{'SetExt3',true,99}} =
+ asn1_wrapper:decode('SetExtension','SetExt3',lists:flatten(Bytes32)),
+
+ ?line {ok,Bytes41} =
+ asn1_wrapper:encode('SetExtension','SetExt4',#'SetExt4'{bool = true,int = 99}),
+ ?line {ok,{'SetExt4',true,99}} =
+ asn1_wrapper:decode('SetExtension','SetExt4',lists:flatten(Bytes41)),
+
+ ?line {ok,Bytes42} =
+ asn1_wrapper:encode('SetExtension','SetExt4',#'SetExt4'{int = 99,bool = true}),
+ ?line {ok,{'SetExt4',true,99}} =
+ asn1_wrapper:decode('SetExtension','SetExt4',lists:flatten(Bytes42)),
+
+
+ %% Test of extension , needs to be improved and extended
+
+ ?line {ok,BytesX11} =
+ asn1_wrapper:encode('SetExtension','SetExt1',#'SetExt1'{}),
+ ?line {ok,{'SetExt1'}} =
+ asn1_wrapper:decode('SetExtension','SetExt1',lists:flatten(BytesX11)),
+
+ ?line {ok,BytesX21} =
+ asn1_wrapper:encode('SetExtension','SetExt2',#'SetExt2'{bool = true,int = 99}),
+ ?line {ok,{'SetExt2',true,99}} =
+ asn1_wrapper:decode('SetExtension','SetExt2',lists:flatten(BytesX21)),
+
+ ?line {ok,BytesX22} =
+ asn1_wrapper:encode('SetExtension','SetExt2',#'SetExt2'{int = 99,bool = true}),
+ ?line {ok,{'SetExt2',true,99}} =
+ asn1_wrapper:decode('SetExtension','SetExt2',lists:flatten(BytesX22)),
+
+
+
+
+
+ ok.
+
+
diff --git a/lib/asn1/test/testSetExternal.erl b/lib/asn1/test/testSetExternal.erl
new file mode 100644
index 0000000000..83974a5499
--- /dev/null
+++ b/lib/asn1/test/testSetExternal.erl
@@ -0,0 +1,140 @@
+%%
+%% %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(testSetExternal).
+
+-include("External.hrl").
+-export([compile/3]).
+-export([main/1]).
+
+-include("test_server.hrl").
+
+
+-record('SetXSeq1',{seq, bool, int}).
+-record('SetXSeq2',{bool, seq, int}).
+-record('SetXSeq3',{bool, int, seq}).
+%-record('NT',{os, bool}).
+%-record('Imp',{os, bool}).
+%-record('Exp',{os, bool}).
+
+
+compile(Config,Rules,Options) ->
+
+ ?line DataDir = ?config(data_dir,Config),
+ ?line OutDir = ?config(priv_dir,Config),
+ ?line true = code:add_patha(?config(priv_dir,Config)),
+ ?line ok = asn1ct:compile(DataDir ++ "SetExternal",
+ [Rules,{outdir,OutDir}]++Options).
+
+
+
+main(_Rules) ->
+
+ ?line {ok,Bytes11} =
+ asn1_wrapper:encode('SetExternal','XNTNT',#'XSetNT'{bool = true, os = "kalle"}),
+ ?line {ok,{'XSetNT',[107,97,108,108,101],true}} =
+ asn1_wrapper:decode('SetExternal','XNTNT',lists:flatten(Bytes11)),
+
+ ?line {ok,Bytes12} =
+ asn1_wrapper:encode('SetExternal','XImpNT',#'XSetNT'{bool = true, os = "kalle"}),
+ ?line {ok,{'XSetNT',[107,97,108,108,101],true}} =
+ asn1_wrapper:decode('SetExternal','XImpNT',lists:flatten(Bytes12)),
+
+ ?line {ok,Bytes13} =
+ asn1_wrapper:encode('SetExternal','XExpNT',#'XSetNT'{bool = true, os = "kalle"}),
+ ?line {ok,{'XSetNT',[107,97,108,108,101],true}} =
+ asn1_wrapper:decode('SetExternal','XExpNT',lists:flatten(Bytes13)),
+
+
+
+ ?line {ok,Bytes21} =
+ asn1_wrapper:encode('SetExternal','XNTImp',#'XSetImp'{bool = true, os = "kalle"}),
+ ?line {ok,{'XSetImp',[107,97,108,108,101],true}} =
+ asn1_wrapper:decode('SetExternal','XNTImp',lists:flatten(Bytes21)),
+
+ ?line {ok,Bytes22} =
+ asn1_wrapper:encode('SetExternal','XImpImp',#'XSetImp'{bool = true, os = "kalle"}),
+ ?line {ok,{'XSetImp',[107,97,108,108,101],true}} =
+ asn1_wrapper:decode('SetExternal','XImpImp',lists:flatten(Bytes22)),
+
+ ?line {ok,Bytes23} =
+ asn1_wrapper:encode('SetExternal','XExpImp',#'XSetImp'{bool = true, os = "kalle"}),
+ ?line {ok,{'XSetImp',[107,97,108,108,101],true}} =
+ asn1_wrapper:decode('SetExternal','XExpImp',lists:flatten(Bytes23)),
+
+
+
+ ?line {ok,Bytes31} =
+ asn1_wrapper:encode('SetExternal','XNTExp',#'XSetExp'{bool = true, os = "kalle"}),
+ ?line {ok,{'XSetExp',[107,97,108,108,101],true}} =
+ asn1_wrapper:decode('SetExternal','XNTExp',lists:flatten(Bytes31)),
+
+ ?line {ok,Bytes32} =
+ asn1_wrapper:encode('SetExternal','XImpExp',#'XSetExp'{bool = true, os = "kalle"}),
+ ?line {ok,{'XSetExp',[107,97,108,108,101],true}} =
+ asn1_wrapper:decode('SetExternal','XImpExp',lists:flatten(Bytes32)),
+
+ ?line {ok,Bytes33} =
+ asn1_wrapper:encode('SetExternal','XExpExp',#'XSetExp'{bool = true, os = "kalle"}),
+ ?line {ok,{'XSetExp',[107,97,108,108,101],true}} =
+ asn1_wrapper:decode('SetExternal','XExpExp',lists:flatten(Bytes33)),
+
+
+
+ ?line {ok,Bytes41} =
+ asn1_wrapper:encode('SetExternal','SetXSeq1',
+ #'SetXSeq1'{bool = true,
+ int = 66,
+ seq = #'XSeq1'{bool1 = true,
+ int1 = 77,
+ seq1 = #'XSeqIn'{boolIn = false,
+ intIn = 88}}}),
+ ?line {ok,{'SetXSeq1',{'XSeq1',true,77,{'XSeqIn',false,88}},true,66}} =
+ asn1_wrapper:decode('SetExternal','SetXSeq1',lists:flatten(Bytes41)),
+
+
+
+ ?line {ok,Bytes42} =
+ asn1_wrapper:encode('SetExternal','SetXSeq2',
+ #'SetXSeq2'{bool = true,
+ int = 66,
+ seq = #'XSeq1'{bool1 = true,
+ int1 = 77,
+ seq1 = #'XSeqIn'{boolIn = false,
+ intIn = 88}}}),
+ ?line {ok,{'SetXSeq2',true,{'XSeq1',true,77,{'XSeqIn',false,88}},66}} =
+ asn1_wrapper:decode('SetExternal','SetXSeq2',lists:flatten(Bytes42)),
+
+ ?line {ok,Bytes43} =
+ asn1_wrapper:encode('SetExternal','SetXSeq3',
+ #'SetXSeq3'{bool = true,
+ int = 66,
+ seq = #'XSeq1'{bool1 = true,
+ int1 = 77,
+ seq1 = #'XSeqIn'{boolIn = false,
+ intIn = 88}}}),
+ ?line {ok,{'SetXSeq3',true,66,{'XSeq1',true,77,{'XSeqIn',false,88}}}} =
+ asn1_wrapper:decode('SetExternal','SetXSeq3',lists:flatten(Bytes43)),
+
+
+
+
+ ok.
+
+
diff --git a/lib/asn1/test/testSetIndefinite.erl b/lib/asn1/test/testSetIndefinite.erl
new file mode 100644
index 0000000000..0e6a86bac4
--- /dev/null
+++ b/lib/asn1/test/testSetIndefinite.erl
@@ -0,0 +1,55 @@
+%%
+%% %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(testSetIndefinite).
+
+-export([compile/3]).
+-export([main/1]).
+
+-include("test_server.hrl").
+
+
+compile(Config,Rules,Options) ->
+
+ ?line DataDir = ?config(data_dir,Config),
+ ?line OutDir = ?config(priv_dir,Config),
+ ?line true = code:add_patha(?config(priv_dir,Config)),
+ ?line ok = asn1ct:compile(DataDir ++ "SeqSetIndefinite",
+ [Rules,{outdir,OutDir}]++Options).
+
+main(per_bin) -> ok;
+main(per) -> ok;
+main(ber_bin_v2) ->
+ main(ber);
+main(ber_bin) ->
+ main(ber);
+main(ber) ->
+
+ %% normal encoding
+ B = [49,20,1,1,255,49,9,1,1,255,2,4,251,35,238,194,2,4,251,55,236,161],
+ %% indefinite length encoding
+ Bi = [49,22,1,1,255,49,128,1,1,255,2,4,251,35,238,194,0,0,2,4,251,55,236,161],
+ %% the value which is encoded
+ V = {'SetS3',true,{'SetS3_setS3',true,-81531198},-80221023},
+ ?line {ok,V} = asn1_wrapper:decode('SeqSetIndefinite','SetS3',B),
+ ?line {ok,V} = asn1_wrapper:decode('SeqSetIndefinite','SetS3',Bi),
+ ok.
+
+
+
diff --git a/lib/asn1/test/testSetOf.erl b/lib/asn1/test/testSetOf.erl
new file mode 100644
index 0000000000..fe68a0705a
--- /dev/null
+++ b/lib/asn1/test/testSetOf.erl
@@ -0,0 +1,235 @@
+%%
+%% %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(testSetOf).
+
+-export([compile/3]).
+-export([main/1]).
+
+-include("test_server.hrl").
+
+-record('Set1',{bool1, int1, set1 = asn1_DEFAULT}).
+-record('Set2',{set2 = asn1_DEFAULT, bool2, int2}).
+-record('Set3',{bool3, set3 = asn1_DEFAULT, int3}).
+-record('Set4',{set41 = asn1_DEFAULT, set42 = asn1_DEFAULT, set43 = asn1_DEFAULT}).
+-record('SetIn',{boolIn, intIn}).
+%-record('SetCho',{bool1, int1, set1 = asn1_DEFAULT}).
+%-record('SetChoInline',{bool1, int1, set1 = asn1_DEFAULT}).
+%-record('SetChoOfInline_SETOF',{bool1, int1, set1 = asn1_DEFAULT}).
+-record('SetEmp',{set1}).
+-record('Empty',{}).
+
+
+
+compile(Config,Rules,Options) ->
+
+ ?line DataDir = ?config(data_dir,Config),
+ ?line OutDir = ?config(priv_dir,Config),
+ ?line true = code:add_patha(?config(priv_dir,Config)),
+ ?line ok = asn1ct:compile(DataDir ++ "SetOf",[Rules,{outdir,OutDir}]++Options).
+
+
+
+main(_Rules) ->
+
+ ?line {ok,Bytes11} =
+ asn1_wrapper:encode('SetOf','Set1',#'Set1'{bool1 = true,
+ int1 = 17}),
+ ?line {ok,{'Set1',true,17,[]}} =
+ asn1_wrapper:decode('SetOf','Set1',lists:flatten(Bytes11)),
+
+
+ ?line {ok,Bytes12} =
+ asn1_wrapper:encode('SetOf','Set1',#'Set1'{bool1 = true,
+ int1 = 17,
+ set1 = [#'SetIn'{boolIn = true,
+ intIn = 25}]}),
+ ?line {ok,{'Set1',true,17,[{'SetIn',true,25}]}} =
+ asn1_wrapper:decode('SetOf','Set1',lists:flatten(Bytes12)),
+
+
+
+ ?line {ok,Bytes13} =
+ asn1_wrapper:encode('SetOf','Set1',#'Set1'{bool1 = true,
+ int1 = 17,
+ set1 = [#'SetIn'{boolIn = true,
+ intIn = 25},
+ #'SetIn'{boolIn = false,
+ intIn = 125},
+ #'SetIn'{boolIn = false,
+ intIn = 225}]}),
+ ?line {ok,{'Set1',true,17,[{'SetIn',true,25},{'SetIn',false,125},{'SetIn',false,225}]}} =
+ asn1_wrapper:decode('SetOf','Set1',lists:flatten(Bytes13)),
+
+
+
+
+
+
+ ?line {ok,Bytes21} =
+ asn1_wrapper:encode('SetOf','Set2',#'Set2'{bool2 = true,
+ int2 = 17}),
+
+ ?line {ok,{'Set2',[],true,17}} =
+ asn1_wrapper:decode('SetOf','Set2',lists:flatten(Bytes21)),
+
+
+ ?line {ok,Bytes22} =
+ asn1_wrapper:encode('SetOf','Set2',#'Set2'{bool2 = true,
+ int2 = 17,
+ set2 = [#'SetIn'{boolIn = true,
+ intIn = 25}]}),
+ ?line {ok,{'Set2',[{'SetIn',true,25}],true,17}} =
+ asn1_wrapper:decode('SetOf','Set2',lists:flatten(Bytes22)),
+
+
+ ?line {ok,Bytes23} =
+ asn1_wrapper:encode('SetOf','Set2',#'Set2'{bool2 = true,
+ int2 = 17,
+ set2 = [#'SetIn'{boolIn = true,
+ intIn = 25},
+ #'SetIn'{boolIn = false,
+ intIn = 125},
+ #'SetIn'{boolIn = false,
+ intIn = 225}]}),
+ ?line {ok,{'Set2',[{'SetIn',true,25},{'SetIn',false,125},{'SetIn',false,225}],true,17}} =
+ asn1_wrapper:decode('SetOf','Set2',lists:flatten(Bytes23)),
+
+
+
+
+
+
+ ?line {ok,Bytes31} =
+ asn1_wrapper:encode('SetOf','Set3',#'Set3'{bool3 = true,
+ int3 = 17}),
+ ?line {ok,{'Set3',true,[],17}} =
+ asn1_wrapper:decode('SetOf','Set3',lists:flatten(Bytes31)),
+
+
+ ?line {ok,Bytes32} =
+ asn1_wrapper:encode('SetOf','Set3',#'Set3'{bool3 = true,
+ int3 = 17,
+ set3 = [#'SetIn'{boolIn = true,
+ intIn = 25}]}),
+ ?line {ok,{'Set3',true,[{'SetIn',true,25}],17}} =
+ asn1_wrapper:decode('SetOf','Set3',lists:flatten(Bytes32)),
+
+
+ ?line {ok,Bytes33} =
+ asn1_wrapper:encode('SetOf','Set3',#'Set3'{bool3 = true,
+ int3 = 17,
+ set3 = [#'SetIn'{boolIn = true,
+ intIn = 25},
+ #'SetIn'{boolIn = false,
+ intIn = 125},
+ #'SetIn'{boolIn = false,
+ intIn = 225}]}),
+ ?line {ok,{'Set3',true,[{'SetIn',true,25},{'SetIn',false,125},{'SetIn',false,225}],17}} =
+ asn1_wrapper:decode('SetOf','Set3',lists:flatten(Bytes33)),
+
+
+
+
+
+
+
+ ?line {ok,Bytes41} = asn1_wrapper:encode('SetOf','Set4',#'Set4'{}),
+ ?line {ok,{'Set4',[],[],[]}} = asn1_wrapper:decode('SetOf','Set4',lists:flatten(Bytes41)),
+
+
+ ?line {ok,Bytes42} =
+ asn1_wrapper:encode('SetOf','Set4',#'Set4'{set41 = [#'SetIn'{boolIn = true,
+ intIn = 25}]}),
+ ?line {ok,{'Set4',[{'SetIn',true,25}],[],[]}} =
+ asn1_wrapper:decode('SetOf','Set4',lists:flatten(Bytes42)),
+
+
+ ?line {ok,Bytes43} =
+ asn1_wrapper:encode('SetOf','Set4',#'Set4'{set41 = [#'SetIn'{boolIn = true,
+ intIn = 25},
+ #'SetIn'{boolIn = false,
+ intIn = 125},
+ #'SetIn'{boolIn = false,
+ intIn = 225}]}),
+ ?line {ok,{'Set4',[{'SetIn',true,25},{'SetIn',false,125},{'SetIn',false,225}],[],[]}} =
+ asn1_wrapper:decode('SetOf','Set4',lists:flatten(Bytes43)),
+
+
+ ?line {ok,Bytes44} =
+ asn1_wrapper:encode('SetOf','Set4',#'Set4'{set42 = [#'SetIn'{boolIn = true,
+ intIn = 25}]}),
+ ?line {ok,{'Set4',[],[{'SetIn',true,25}],[]}} =
+ asn1_wrapper:decode('SetOf','Set4',lists:flatten(Bytes44)),
+
+
+ ?line {ok,Bytes45} =
+ asn1_wrapper:encode('SetOf','Set4',#'Set4'{set42 = [#'SetIn'{boolIn = true,
+ intIn = 25},
+ #'SetIn'{boolIn = false,
+ intIn = 125},
+ #'SetIn'{boolIn = false,
+ intIn = 225}]}),
+ ?line {ok,{'Set4',[],[{'SetIn',true,25},{'SetIn',false,125},{'SetIn',false,225}],[]}} =
+ asn1_wrapper:decode('SetOf','Set4',lists:flatten(Bytes45)),
+
+
+ ?line {ok,Bytes46} =
+ asn1_wrapper:encode('SetOf','Set4',#'Set4'{set43 = [#'SetIn'{boolIn = true,
+ intIn = 25}]}),
+ ?line {ok,{'Set4',[],[],[{'SetIn',true,25}]}} =
+ asn1_wrapper:decode('SetOf','Set4',lists:flatten(Bytes46)),
+
+
+ ?line {ok,Bytes47} =
+ asn1_wrapper:encode('SetOf','Set4',#'Set4'{set43 = [#'SetIn'{boolIn = true,
+ intIn = 25},
+ #'SetIn'{boolIn = false,
+ intIn = 125},
+ #'SetIn'{boolIn = false,
+ intIn = 225}]}),
+ ?line {ok,{'Set4',[],[],[{'SetIn',true,25},{'SetIn',false,125},{'SetIn',false,225}]}} =
+ asn1_wrapper:decode('SetOf','Set4',lists:flatten(Bytes47)),
+
+
+
+
+ ?line {ok,Bytes51} = asn1_wrapper:encode('SetOf','SetOs',["First","Second","Third"]),
+ ?line {ok,["First","Second","Third"]} =
+ asn1_wrapper:decode('SetOf','SetOs',lists:flatten(Bytes51)),
+
+ ?line {ok,Bytes52} = asn1_wrapper:encode('SetOf','SetOsImp',["First","Second","Third"]),
+ ?line {ok,["First","Second","Third"]} =
+ asn1_wrapper:decode('SetOf','SetOsImp',lists:flatten(Bytes52)),
+
+ ?line {ok,Bytes53} = asn1_wrapper:encode('SetOf','SetOsExp',["First","Second","Third"]),
+ ?line {ok,["First","Second","Third"]} =
+ asn1_wrapper:decode('SetOf','SetOsExp',lists:flatten(Bytes53)),
+
+
+
+
+
+
+
+ ?line {ok,Bytes71} = asn1_wrapper:encode('SetOf','SetEmp',#'SetEmp'{set1 = [#'Empty'{}]}),
+ ?line {ok,{'SetEmp',[{'Empty'}]}} = asn1_wrapper:decode('SetOf','SetEmp',lists:flatten(Bytes71)),
+
+ ok.
+
diff --git a/lib/asn1/test/testSetOfCho.erl b/lib/asn1/test/testSetOfCho.erl
new file mode 100644
index 0000000000..f3164273f6
--- /dev/null
+++ b/lib/asn1/test/testSetOfCho.erl
@@ -0,0 +1,159 @@
+%%
+%% %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(testSetOfCho).
+
+-export([compile/3]).
+-export([main/1]).
+
+-include("test_server.hrl").
+
+-record('SetChoDef',{bool1, int1, set1 = asn1_DEFAULT}).
+-record('SetChoOpt',{bool1, int1, set1 = asn1_NOVALUE}).
+-record('SetChoEmbDef',{bool1, int1, set1 = asn1_DEFAULT}).
+-record('SetChoEmbOpt',{bool1, int1, set1 = asn1_NOVALUE}).
+-record('SetOfChoEmbDef_SETOF',{bool1, int1, set1 = asn1_DEFAULT}).
+-record('SetOfChoEmbOpt_SETOF',{bool1, int1, set1 = asn1_NOVALUE}).
+
+
+
+compile(Config,Rules,Options) ->
+
+ ?line DataDir = ?config(data_dir,Config),
+ ?line OutDir = ?config(priv_dir,Config),
+ ?line true = code:add_patha(?config(priv_dir,Config)),
+ ?line ok = asn1ct:compile(DataDir ++ "SetOfCho",[Rules,{outdir,OutDir}]++Options).
+
+
+
+main(_Rules) ->
+
+ ?line {ok,Bytes11} =
+ asn1_wrapper:encode('SetOfCho','SetChoDef',#'SetChoDef'{bool1 = true,
+ int1 = 17}),
+ ?line {ok,{'SetChoDef',true,17,[]}} =
+ asn1_wrapper:decode('SetOfCho','SetChoDef',lists:flatten(Bytes11)),
+
+
+ ?line {ok,Bytes12} =
+ asn1_wrapper:encode('SetOfCho','SetChoDef',#'SetChoDef'{bool1 = true,
+ int1 = 17,
+ set1 = [{boolIn,true},
+ {intIn,25}]}),
+ ?line {ok,{'SetChoDef',true,17,[{boolIn,true},{intIn,25}]}} =
+ asn1_wrapper:decode('SetOfCho','SetChoDef',lists:flatten(Bytes12)),
+
+
+
+ ?line {ok,Bytes15} =
+ asn1_wrapper:encode('SetOfCho','SetChoOpt',#'SetChoOpt'{bool1 = true,
+ int1 = 17}),
+ ?line {ok,{'SetChoOpt',true,17,asn1_NOVALUE}} =
+ asn1_wrapper:decode('SetOfCho','SetChoOpt',lists:flatten(Bytes15)),
+
+
+ ?line {ok,Bytes16} =
+ asn1_wrapper:encode('SetOfCho','SetChoOpt',#'SetChoOpt'{bool1 = true,
+ int1 = 17,
+ set1 = [{boolIn,true},
+ {intIn,25}]}),
+ ?line {ok,{'SetChoOpt',true,17,[{boolIn,true},{intIn,25}]}} =
+ asn1_wrapper:decode('SetOfCho','SetChoOpt',lists:flatten(Bytes16)),
+
+
+
+
+
+ ?line {ok,Bytes21} =
+ asn1_wrapper:encode('SetOfCho','SetChoEmbDef',#'SetChoEmbDef'{bool1 = true,
+ int1 = 17}),
+ ?line {ok,{'SetChoEmbDef',true,17,[]}} =
+ asn1_wrapper:decode('SetOfCho','SetChoEmbDef',lists:flatten(Bytes21)),
+
+
+ ?line {ok,Bytes22} =
+ asn1_wrapper:encode('SetOfCho','SetChoEmbDef',#'SetChoEmbDef'{bool1 = true,
+ int1 = 17,
+ set1 = [{boolIn,true},
+ {intIn,25}]}),
+ ?line {ok,{'SetChoEmbDef',true,17,[{boolIn,true},{intIn,25}]}} =
+ asn1_wrapper:decode('SetOfCho','SetChoEmbDef',lists:flatten(Bytes22)),
+
+
+
+ ?line {ok,Bytes25} =
+ asn1_wrapper:encode('SetOfCho','SetChoEmbOpt',#'SetChoEmbOpt'{bool1 = true,
+ int1 = 17}),
+ ?line {ok,{'SetChoEmbOpt',true,17,asn1_NOVALUE}} =
+ asn1_wrapper:decode('SetOfCho','SetChoEmbOpt',lists:flatten(Bytes25)),
+
+
+ ?line {ok,Bytes26} =
+ asn1_wrapper:encode('SetOfCho','SetChoEmbOpt',#'SetChoEmbOpt'{bool1 = true,
+ int1 = 17,
+ set1 = [{boolIn,true},
+ {intIn,25}]}),
+ ?line {ok,{'SetChoEmbOpt',true,17,[{boolIn,true},{intIn,25}]}} =
+ asn1_wrapper:decode('SetOfCho','SetChoEmbOpt',lists:flatten(Bytes26)),
+
+
+
+
+
+
+ ?line {ok,Bytes31} =
+ asn1_wrapper:encode('SetOfCho','SetOfChoEmbDef',[#'SetOfChoEmbDef_SETOF'{bool1 = true,
+ int1 = 17}]),
+ ?line {ok,[{'SetOfChoEmbDef_SETOF',true,17,[]}]} =
+ asn1_wrapper:decode('SetOfCho','SetOfChoEmbDef',lists:flatten(Bytes31)),
+
+
+ ?line {ok,Bytes32} =
+ asn1_wrapper:encode('SetOfCho','SetOfChoEmbDef',
+ [#'SetOfChoEmbDef_SETOF'{bool1 = true,
+ int1 = 17,
+ set1 = [{boolIn,true},
+ {intIn,25}]}]),
+ ?line {ok,[{'SetOfChoEmbDef_SETOF',true,17,[{boolIn,true},{intIn,25}]}]} =
+ asn1_wrapper:decode('SetOfCho','SetOfChoEmbDef',lists:flatten(Bytes32)),
+
+
+
+ ?line {ok,Bytes35} =
+ asn1_wrapper:encode('SetOfCho','SetOfChoEmbOpt',[#'SetOfChoEmbOpt_SETOF'{bool1 = true,
+ int1 = 17}]),
+ ?line {ok,[{'SetOfChoEmbOpt_SETOF',true,17,asn1_NOVALUE}]} =
+ asn1_wrapper:decode('SetOfCho','SetOfChoEmbOpt',lists:flatten(Bytes35)),
+
+
+ ?line {ok,Bytes36} =
+ asn1_wrapper:encode('SetOfCho','SetOfChoEmbOpt',
+ [#'SetOfChoEmbOpt_SETOF'{bool1 = true,
+ int1 = 17,
+ set1 = [{boolIn,true},
+ {intIn,25}]}]),
+ ?line {ok,[{'SetOfChoEmbOpt_SETOF',true,17,[{boolIn,true},{intIn,25}]}]} =
+ asn1_wrapper:decode('SetOfCho','SetOfChoEmbOpt',lists:flatten(Bytes36)),
+
+
+
+
+ ok.
+
+
diff --git a/lib/asn1/test/testSetOfExternal.erl b/lib/asn1/test/testSetOfExternal.erl
new file mode 100644
index 0000000000..1c59ad0a74
--- /dev/null
+++ b/lib/asn1/test/testSetOfExternal.erl
@@ -0,0 +1,171 @@
+%%
+%% %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(testSetOfExternal).
+
+
+-export([compile/3]).
+-export([main/1]).
+
+-include("test_server.hrl").
+-include("External.hrl").
+
+-record('NT',{os, bool}).
+-record('Imp',{os, bool}).
+-record('Exp',{os, bool}).
+
+
+
+compile(Config,Rules,Options) ->
+
+ ?line DataDir = ?config(data_dir,Config),
+ ?line OutDir = ?config(priv_dir,Config),
+ ?line true = code:add_patha(?config(priv_dir,Config)),
+ ?line ok = asn1ct:compile(DataDir ++ "SetOfExternal",[Rules,{outdir,OutDir}]++Options).
+
+
+
+main(_Rules) ->
+
+ ?line {ok,Bytes11} =
+ asn1_wrapper:encode('SetOfExternal','NTNT',[#'NT'{bool = true, os = "kalle"},
+ #'NT'{bool = true, os = "kalle"}]),
+ ?line {ok,[{'NT',[107,97,108,108,101],true},{'NT',[107,97,108,108,101],true}]} =
+ asn1_wrapper:decode('SetOfExternal','NTNT',lists:flatten(Bytes11)),
+
+ ?line {ok,Bytes12} =
+ asn1_wrapper:encode('SetOfExternal','ImpNT',[#'NT'{bool = true, os = "kalle"},
+ #'NT'{bool = true, os = "kalle"}]),
+ ?line {ok,[{'NT',[107,97,108,108,101],true},{'NT',[107,97,108,108,101],true}]} =
+ asn1_wrapper:decode('SetOfExternal','ImpNT',lists:flatten(Bytes12)),
+
+ ?line {ok,Bytes13} =
+ asn1_wrapper:encode('SetOfExternal','ExpNT',[#'NT'{bool = true, os = "kalle"},
+ #'NT'{bool = true, os = "kalle"}]),
+ ?line {ok,[{'NT',[107,97,108,108,101],true},{'NT',[107,97,108,108,101],true}]} =
+ asn1_wrapper:decode('SetOfExternal','ExpNT',lists:flatten(Bytes13)),
+
+
+
+ ?line {ok,Bytes21} =
+ asn1_wrapper:encode('SetOfExternal','NTImp',[#'Imp'{bool = true, os = "kalle"},
+ #'Imp'{bool = true, os = "kalle"}]),
+ ?line {ok,[{'Imp',[107,97,108,108,101],true},{'Imp',[107,97,108,108,101],true}]} =
+ asn1_wrapper:decode('SetOfExternal','NTImp',lists:flatten(Bytes21)),
+
+ ?line {ok,Bytes22} =
+ asn1_wrapper:encode('SetOfExternal','ImpImp',[#'Imp'{bool = true, os = "kalle"},
+ #'Imp'{bool = true, os = "kalle"}]),
+ ?line {ok,[{'Imp',[107,97,108,108,101],true},{'Imp',[107,97,108,108,101],true}]} =
+ asn1_wrapper:decode('SetOfExternal','ImpImp',lists:flatten(Bytes22)),
+
+ ?line {ok,Bytes23} =
+ asn1_wrapper:encode('SetOfExternal','ExpImp',[#'Imp'{bool = true, os = "kalle"},
+ #'Imp'{bool = true, os = "kalle"}]),
+ ?line {ok,[{'Imp',[107,97,108,108,101],true},{'Imp',[107,97,108,108,101],true}]} =
+ asn1_wrapper:decode('SetOfExternal','ExpImp',lists:flatten(Bytes23)),
+
+
+
+ ?line {ok,Bytes31} =
+ asn1_wrapper:encode('SetOfExternal','NTExp',[#'Exp'{bool = true, os = "kalle"},
+ #'Exp'{bool = true, os = "kalle"}]),
+ ?line {ok,[{'Exp',[107,97,108,108,101],true},{'Exp',[107,97,108,108,101],true}]} =
+ asn1_wrapper:decode('SetOfExternal','NTExp',lists:flatten(Bytes31)),
+
+ ?line {ok,Bytes32} =
+ asn1_wrapper:encode('SetOfExternal','ImpExp',[#'Exp'{bool = true, os = "kalle"},
+ #'Exp'{bool = true, os = "kalle"}]),
+ ?line {ok,[{'Exp',[107,97,108,108,101],true},{'Exp',[107,97,108,108,101],true}]} =
+ asn1_wrapper:decode('SetOfExternal','ImpExp',lists:flatten(Bytes32)),
+
+ ?line {ok,Bytes33} =
+ asn1_wrapper:encode('SetOfExternal','ExpExp',[#'Exp'{bool = true, os = "kalle"},
+ #'Exp'{bool = true, os = "kalle"}]),
+ ?line {ok,[{'Exp',[107,97,108,108,101],true},{'Exp',[107,97,108,108,101],true}]} =
+ asn1_wrapper:decode('SetOfExternal','ExpExp',lists:flatten(Bytes33)),
+
+
+
+
+
+
+
+ ?line {ok,Bytes41} =
+ asn1_wrapper:encode('SetOfExternal','XNTNT',[#'XSetNT'{bool = true, os = "kalle"},
+ #'XSetNT'{bool = true, os = "kalle"}]),
+ ?line {ok,[{'XSetNT',[107,97,108,108,101],true},{'XSetNT',[107,97,108,108,101],true}]} =
+ asn1_wrapper:decode('SetOfExternal','XNTNT',lists:flatten(Bytes41)),
+
+ ?line {ok,Bytes42} =
+ asn1_wrapper:encode('SetOfExternal','XImpNT',[#'XSetNT'{bool = true, os = "kalle"},
+ #'XSetNT'{bool = true, os = "kalle"}]),
+ ?line {ok,[{'XSetNT',[107,97,108,108,101],true},{'XSetNT',[107,97,108,108,101],true}]} =
+ asn1_wrapper:decode('SetOfExternal','XImpNT',lists:flatten(Bytes42)),
+
+ ?line {ok,Bytes43} =
+ asn1_wrapper:encode('SetOfExternal','XExpNT',[#'XSetNT'{bool = true, os = "kalle"},
+ #'XSetNT'{bool = true, os = "kalle"}]),
+ ?line {ok,[{'XSetNT',[107,97,108,108,101],true},{'XSetNT',[107,97,108,108,101],true}]} =
+ asn1_wrapper:decode('SetOfExternal','XExpNT',lists:flatten(Bytes43)),
+
+
+
+ ?line {ok,Bytes51} =
+ asn1_wrapper:encode('SetOfExternal','XNTImp',[#'XSetImp'{bool = true, os = "kalle"},
+ #'XSetImp'{bool = true, os = "kalle"}]),
+ ?line {ok,[{'XSetImp',[107,97,108,108,101],true},{'XSetImp',[107,97,108,108,101],true}]} =
+ asn1_wrapper:decode('SetOfExternal','XNTImp',lists:flatten(Bytes51)),
+
+ ?line {ok,Bytes52} =
+ asn1_wrapper:encode('SetOfExternal','XImpImp',[#'XSetImp'{bool = true, os = "kalle"},
+ #'XSetImp'{bool = true, os = "kalle"}]),
+ ?line {ok,[{'XSetImp',[107,97,108,108,101],true},{'XSetImp',[107,97,108,108,101],true}]} =
+ asn1_wrapper:decode('SetOfExternal','XImpImp',lists:flatten(Bytes52)),
+
+ ?line {ok,Bytes53} =
+ asn1_wrapper:encode('SetOfExternal','XExpImp',[#'XSetImp'{bool = true, os = "kalle"},
+ #'XSetImp'{bool = true, os = "kalle"}]),
+ ?line {ok,[{'XSetImp',[107,97,108,108,101],true},{'XSetImp',[107,97,108,108,101],true}]} =
+ asn1_wrapper:decode('SetOfExternal','XExpImp',lists:flatten(Bytes53)),
+
+
+
+ ?line {ok,Bytes61} =
+ asn1_wrapper:encode('SetOfExternal','XNTExp',[#'XSetExp'{bool = true, os = "kalle"},
+ #'XSetExp'{bool = true, os = "kalle"}]),
+ ?line {ok,[{'XSetExp',[107,97,108,108,101],true},{'XSetExp',[107,97,108,108,101],true}]} =
+ asn1_wrapper:decode('SetOfExternal','XNTExp',lists:flatten(Bytes61)),
+
+ ?line {ok,Bytes62} =
+ asn1_wrapper:encode('SetOfExternal','XImpExp',[#'XSetExp'{bool = true, os = "kalle"},
+ #'XSetExp'{bool = true, os = "kalle"}]),
+ ?line {ok,[{'XSetExp',[107,97,108,108,101],true},{'XSetExp',[107,97,108,108,101],true}]} =
+ asn1_wrapper:decode('SetOfExternal','XImpExp',lists:flatten(Bytes62)),
+
+ ?line {ok,Bytes63} =
+ asn1_wrapper:encode('SetOfExternal','XExpExp',[#'XSetExp'{bool = true, os = "kalle"},
+ #'XSetExp'{bool = true, os = "kalle"}]),
+ ?line {ok,[{'XSetExp',[107,97,108,108,101],true},{'XSetExp',[107,97,108,108,101],true}]} =
+ asn1_wrapper:decode('SetOfExternal','XExpExp',lists:flatten(Bytes63)),
+
+
+
+
+ ok.
diff --git a/lib/asn1/test/testSetOfTag.erl b/lib/asn1/test/testSetOfTag.erl
new file mode 100644
index 0000000000..ff59a329e3
--- /dev/null
+++ b/lib/asn1/test/testSetOfTag.erl
@@ -0,0 +1,201 @@
+%%
+%% %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(testSetOfTag).
+
+
+-export([compile/3]).
+-export([main/1]).
+
+-include("test_server.hrl").
+-include("External.hrl").
+
+
+-record('SetTagNt',{nt}).
+-record('SetTagNtI',{imp}).
+-record('SetTagNtE',{exp}).
+-record('SetTagI',{nt}).
+-record('SetTagII',{imp}).
+-record('SetTagIE',{exp}).
+-record('SetTagE',{nt}).
+-record('SetTagEI',{imp}).
+-record('SetTagEE',{exp}).
+-record('SetTagXNt',{xnt}).
+-record('SetTagXI',{ximp}).
+-record('SetTagXE',{xexp}).
+-record('SetTagImpX',{xnt, ximp, xexp}).
+-record('SetTagExpX',{xnt, ximp, xexp}).
+-record('NT',{os, bool}).
+-record('Imp',{os, bool}).
+-record('Exp',{os, bool}).
+
+
+
+compile(Config,Rules,Options) ->
+
+ ?line DataDir = ?config(data_dir,Config),
+ ?line OutDir = ?config(priv_dir,Config),
+ ?line true = code:add_patha(?config(priv_dir,Config)),
+ ?line ok = asn1ct:compile(DataDir ++ "SetOfTag",[Rules,{outdir,OutDir}]++Options).
+
+
+
+main(_Rules) ->
+
+ ?line {ok,Bytes11} =
+ asn1_wrapper:encode('SetOfTag','SetTagNt',
+ #'SetTagNt'{nt = [#'NT'{bool = true, os = "kalle"},
+ #'NT'{bool = true, os = "kalle"}]}),
+ ?line {ok,{'SetTagNt',
+ [{'NT',[107,97,108,108,101],true},{'NT',[107,97,108,108,101],true}]}} =
+ asn1_wrapper:decode('SetOfTag','SetTagNt',lists:flatten(Bytes11)),
+
+ ?line {ok,Bytes12} =
+ asn1_wrapper:encode('SetOfTag','SetTagNtI',
+ #'SetTagNtI'{imp = [#'Imp'{bool = true, os = "kalle"},
+ #'Imp'{bool = true, os = "kalle"}]}),
+ ?line {ok,{'SetTagNtI',
+ [{'Imp',[107,97,108,108,101],true},{'Imp',[107,97,108,108,101],true}]}} =
+ asn1_wrapper:decode('SetOfTag','SetTagNtI',lists:flatten(Bytes12)),
+
+ ?line {ok,Bytes13} =
+ asn1_wrapper:encode('SetOfTag','SetTagNtE',
+ #'SetTagNtE'{exp = [#'Exp'{bool = true, os = "kalle"},
+ #'Exp'{bool = true, os = "kalle"}]}),
+ ?line {ok,{'SetTagNtE',
+ [{'Exp',[107,97,108,108,101],true},{'Exp',[107,97,108,108,101],true}]}} =
+ asn1_wrapper:decode('SetOfTag','SetTagNtE',lists:flatten(Bytes13)),
+
+
+
+ ?line {ok,Bytes21} =
+ asn1_wrapper:encode('SetOfTag','SetTagI',
+ #'SetTagI'{nt = [#'NT'{bool = true, os = "kalle"},
+ #'NT'{bool = true, os = "kalle"}]}),
+ ?line {ok,{'SetTagI',
+ [{'NT',[107,97,108,108,101],true},{'NT',[107,97,108,108,101],true}]}} =
+ asn1_wrapper:decode('SetOfTag','SetTagI',lists:flatten(Bytes21)),
+
+ ?line {ok,Bytes22} =
+ asn1_wrapper:encode('SetOfTag','SetTagII',
+ #'SetTagII'{imp = [#'Imp'{bool = true, os = "kalle"},
+ #'Imp'{bool = true, os = "kalle"}]}),
+ ?line {ok,{'SetTagII',
+ [{'Imp',[107,97,108,108,101],true},{'Imp',[107,97,108,108,101],true}]}} =
+ asn1_wrapper:decode('SetOfTag','SetTagII',lists:flatten(Bytes22)),
+
+ ?line {ok,Bytes23} =
+ asn1_wrapper:encode('SetOfTag','SetTagIE',
+ #'SetTagIE'{exp = [#'Exp'{bool = true, os = "kalle"},
+ #'Exp'{bool = true, os = "kalle"}]}),
+ ?line {ok,{'SetTagIE',
+ [{'Exp',[107,97,108,108,101],true},{'Exp',[107,97,108,108,101],true}]}} =
+ asn1_wrapper:decode('SetOfTag','SetTagIE',lists:flatten(Bytes23)),
+
+
+
+ ?line {ok,Bytes31} =
+ asn1_wrapper:encode('SetOfTag','SetTagE',
+ #'SetTagE'{nt = [#'NT'{bool = true, os = "kalle"},
+ #'NT'{bool = true, os = "kalle"}]}),
+ ?line {ok,{'SetTagE',
+ [{'NT',[107,97,108,108,101],true},{'NT',[107,97,108,108,101],true}]}} =
+ asn1_wrapper:decode('SetOfTag','SetTagE',lists:flatten(Bytes31)),
+
+ ?line {ok,Bytes32} =
+ asn1_wrapper:encode('SetOfTag','SetTagEI',
+ #'SetTagEI'{imp = [#'Imp'{bool = true, os = "kalle"},
+ #'Imp'{bool = true, os = "kalle"}]}),
+ ?line {ok,{'SetTagEI',
+ [{'Imp',[107,97,108,108,101],true},{'Imp',[107,97,108,108,101],true}]}} =
+ asn1_wrapper:decode('SetOfTag','SetTagEI',lists:flatten(Bytes32)),
+
+ ?line {ok,Bytes33} =
+ asn1_wrapper:encode('SetOfTag','SetTagEE',
+ #'SetTagEE'{exp = [#'Exp'{bool = true, os = "kalle"},
+ #'Exp'{bool = true, os = "kalle"}]}),
+ ?line {ok,{'SetTagEE',
+ [{'Exp',[107,97,108,108,101],true},{'Exp',[107,97,108,108,101],true}]}} =
+ asn1_wrapper:decode('SetOfTag','SetTagEE',lists:flatten(Bytes33)),
+
+
+
+
+
+
+
+ ?line {ok,Bytes41} =
+ asn1_wrapper:encode('SetOfTag','SetTagXNt',
+ #'SetTagXNt'{xnt = [#'XSetNT'{bool = true, os = "kalle"},
+ #'XSetNT'{bool = true, os = "kalle"}]}),
+ ?line {ok,{'SetTagXNt',
+ [{'XSetNT',[107,97,108,108,101],true},{'XSetNT',[107,97,108,108,101],true}]}} =
+ asn1_wrapper:decode('SetOfTag','SetTagXNt',lists:flatten(Bytes41)),
+
+ ?line {ok,Bytes42} =
+ asn1_wrapper:encode('SetOfTag','SetTagXI',
+ #'SetTagXI'{ximp = [#'XSetImp'{bool = true, os = "kalle"},
+ #'XSetImp'{bool = true, os = "kalle"}]}),
+ ?line {ok,{'SetTagXI',
+ [{'XSetImp',[107,97,108,108,101],true},{'XSetImp',[107,97,108,108,101],true}]}} =
+ asn1_wrapper:decode('SetOfTag','SetTagXI',lists:flatten(Bytes42)),
+
+ ?line {ok,Bytes43} =
+ asn1_wrapper:encode('SetOfTag','SetTagXE',
+ #'SetTagXE'{xexp = [#'XSetExp'{bool = true, os = "kalle"},
+ #'XSetExp'{bool = true, os = "kalle"}]}),
+ ?line {ok,{'SetTagXE',
+ [{'XSetExp',[107,97,108,108,101],true},{'XSetExp',[107,97,108,108,101],true}]}} =
+ asn1_wrapper:decode('SetOfTag','SetTagXE',lists:flatten(Bytes43)),
+
+
+
+
+
+ ?line {ok,Bytes51} =
+ asn1_wrapper:encode('SetOfTag','SetTagImpX',
+ #'SetTagImpX'{xnt = [#'XSetNT'{bool = true, os = "kalle"},
+ #'XSetNT'{bool = true, os = "kalle"}],
+ ximp = [#'XSetImp'{bool = true, os = "kalle"},
+ #'XSetImp'{bool = true, os = "kalle"}],
+ xexp = [#'XSetExp'{bool = true, os = "kalle"},
+ #'XSetExp'{bool = true, os = "kalle"}]}),
+ ?line {ok,{'SetTagImpX',
+ [{'XSetNT',[107,97,108,108,101],true},{'XSetNT',[107,97,108,108,101],true}],
+ [{'XSetImp',[107,97,108,108,101],true},{'XSetImp',[107,97,108,108,101],true}],
+ [{'XSetExp',[107,97,108,108,101],true},{'XSetExp',[107,97,108,108,101],true}]}} =
+ asn1_wrapper:decode('SetOfTag','SetTagImpX',lists:flatten(Bytes51)),
+
+
+
+ ?line {ok,Bytes52} =
+ asn1_wrapper:encode('SetOfTag','SetTagExpX',
+ #'SetTagExpX'{xnt = [#'XSetNT'{bool = true, os = "kalle"},
+ #'XSetNT'{bool = true, os = "kalle"}],
+ ximp = [#'XSetImp'{bool = true, os = "kalle"},
+ #'XSetImp'{bool = true, os = "kalle"}],
+ xexp = [#'XSetExp'{bool = true, os = "kalle"},
+ #'XSetExp'{bool = true, os = "kalle"}]}),
+ ?line {ok,{'SetTagExpX',
+ [{'XSetNT',[107,97,108,108,101],true},{'XSetNT',[107,97,108,108,101],true}],
+ [{'XSetImp',[107,97,108,108,101],true},{'XSetImp',[107,97,108,108,101],true}],
+ [{'XSetExp',[107,97,108,108,101],true},{'XSetExp',[107,97,108,108,101],true}]}} =
+ asn1_wrapper:decode('SetOfTag','SetTagExpX',lists:flatten(Bytes52)),
+
+ ok.
diff --git a/lib/asn1/test/testSetOptional.erl b/lib/asn1/test/testSetOptional.erl
new file mode 100644
index 0000000000..3df1ed58bb
--- /dev/null
+++ b/lib/asn1/test/testSetOptional.erl
@@ -0,0 +1,218 @@
+%%
+%% %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(testSetOptional).
+
+-include("External.hrl").
+-export([compile/3]).
+-export([main/1]).
+-export([ticket_7533/1,decoder/4]).
+-include("test_server.hrl").
+
+-record('SetOpt1',{bool1 = asn1_NOVALUE, int1, set1 = asn1_NOVALUE}).
+-record('SetOpt1Imp',{bool1 = asn1_NOVALUE, int1, set1 = asn1_NOVALUE}).
+-record('SetOpt1Exp',{bool1 = asn1_NOVALUE, int1, set1 = asn1_NOVALUE}).
+-record('SetOpt2',{set2 = asn1_NOVALUE, bool2, int2}).
+-record('SetOpt2Imp',{set2 = asn1_NOVALUE, bool2, int2}).
+-record('SetOpt2Exp',{set2 = asn1_NOVALUE, bool2, int2}).
+-record('SetOpt3',{bool3 = asn1_NOVALUE, set3 = asn1_NOVALUE, int3 = asn1_NOVALUE}).
+-record('SetOpt3Imp',{bool3 = asn1_NOVALUE, set3 = asn1_NOVALUE, int3 = asn1_NOVALUE}).
+-record('SetOpt3Exp',{bool3 = asn1_NOVALUE, set3 = asn1_NOVALUE, int3 = asn1_NOVALUE}).
+-record('SetIn',{boolIn, intIn}).
+
+
+compile(Config,Rules,Options) ->
+
+ ?line DataDir = ?config(data_dir,Config),
+ ?line OutDir = ?config(priv_dir,Config),
+ ?line true = code:add_patha(?config(priv_dir,Config)),
+ ?line ok = asn1ct:compile(DataDir ++ "SetOptional",[Rules,{outdir,OutDir}]++Options).
+
+
+
+main(_Rules) ->
+
+ ?line {ok,Bytes11} =
+ asn1_wrapper:encode('SetOptional','SetOpt1',#'SetOpt1'{bool1 = true,
+ int1 = 15,
+ set1 = #'SetIn'{boolIn = true,
+ intIn = 66}}),
+ ?line {ok,{'SetOpt1',true,15,{'SetIn',true,66}}} =
+ asn1_wrapper:decode('SetOptional','SetOpt1',lists:flatten(Bytes11)),
+
+
+ ?line {ok,Bytes12} = asn1_wrapper:encode('SetOptional','SetOpt1',#'SetOpt1'{int1 = 15}),
+ ?line {ok,{'SetOpt1',asn1_NOVALUE,15,asn1_NOVALUE}} =
+ asn1_wrapper:decode('SetOptional','SetOpt1',lists:flatten(Bytes12)),
+
+
+ ?line {ok,Bytes21} =
+ asn1_wrapper:encode('SetOptional','SetOpt2',#'SetOpt2'{bool2 = true,
+ int2 = 15,
+ set2 = #'SetIn'{boolIn = true,
+ intIn = 66}}),
+ ?line {ok,{'SetOpt2',{'SetIn',true,66},true,15}} =
+ asn1_wrapper:decode('SetOptional','SetOpt2',lists:flatten(Bytes21)),
+
+
+ ?line {ok,Bytes22} = asn1_wrapper:encode('SetOptional','SetOpt2',#'SetOpt2'{int2 = 15,
+ bool2 = true}),
+ ?line {ok,{'SetOpt2',asn1_NOVALUE,true,15}} =
+ asn1_wrapper:decode('SetOptional','SetOpt2',lists:flatten(Bytes22)),
+
+
+
+ ?line {ok,Bytes31} =
+ asn1_wrapper:encode('SetOptional','SetOpt3',#'SetOpt3'{bool3 = true,
+ int3 = 15,
+ set3 = #'SetIn'{boolIn = true,
+ intIn = 66}}),
+ ?line {ok,{'SetOpt3',true,{'SetIn',true,66},15}} =
+ asn1_wrapper:decode('SetOptional','SetOpt3',lists:flatten(Bytes31)),
+
+
+ ?line {ok,Bytes32} = asn1_wrapper:encode('SetOptional','SetOpt3',#'SetOpt3'{int3 = 15}),
+ ?line {ok,{'SetOpt3',asn1_NOVALUE,asn1_NOVALUE,15}} =
+ asn1_wrapper:decode('SetOptional','SetOpt3',lists:flatten(Bytes32)),
+
+
+
+
+
+ ?line {ok,Bytes41} =
+ asn1_wrapper:encode('SetOptional','SetOpt1Imp',#'SetOpt1Imp'{bool1 = true,
+ int1 = 15,
+ set1 = #'SetIn'{boolIn = true,
+ intIn = 66}}),
+ ?line {ok,{'SetOpt1Imp',true,15,{'SetIn',true,66}}} =
+ asn1_wrapper:decode('SetOptional','SetOpt1Imp',lists:flatten(Bytes41)),
+
+
+ ?line {ok,Bytes42} = asn1_wrapper:encode('SetOptional','SetOpt1Imp',#'SetOpt1Imp'{int1 = 15}),
+ ?line {ok,{'SetOpt1Imp',asn1_NOVALUE,15,asn1_NOVALUE}} =
+ asn1_wrapper:decode('SetOptional','SetOpt1Imp',lists:flatten(Bytes42)),
+
+
+ ?line {ok,Bytes51} =
+ asn1_wrapper:encode('SetOptional','SetOpt2Imp',#'SetOpt2Imp'{bool2 = true,
+ int2 = 15,
+ set2 = #'SetIn'{boolIn = true,
+ intIn = 66}}),
+ ?line {ok,{'SetOpt2Imp',{'SetIn',true,66},true,15}} =
+ asn1_wrapper:decode('SetOptional','SetOpt2Imp',lists:flatten(Bytes51)),
+
+
+ ?line {ok,Bytes52} = asn1_wrapper:encode('SetOptional','SetOpt2Imp',#'SetOpt2Imp'{int2 = 15,
+ bool2 = true}),
+ ?line {ok,{'SetOpt2Imp',asn1_NOVALUE,true,15}} =
+ asn1_wrapper:decode('SetOptional','SetOpt2Imp',lists:flatten(Bytes52)),
+
+
+
+ ?line {ok,Bytes61} =
+ asn1_wrapper:encode('SetOptional','SetOpt3Imp',#'SetOpt3Imp'{bool3 = true,
+ int3 = 15,
+ set3 = #'SetIn'{boolIn = true,
+ intIn = 66}}),
+ ?line {ok,{'SetOpt3Imp',true,{'SetIn',true,66},15}} =
+ asn1_wrapper:decode('SetOptional','SetOpt3Imp',lists:flatten(Bytes61)),
+
+
+ ?line {ok,Bytes62} = asn1_wrapper:encode('SetOptional','SetOpt3Imp',#'SetOpt3Imp'{int3 = 15}),
+ ?line {ok,{'SetOpt3Imp',asn1_NOVALUE,asn1_NOVALUE,15}} =
+ asn1_wrapper:decode('SetOptional','SetOpt3Imp',lists:flatten(Bytes62)),
+
+
+
+
+
+
+ ?line {ok,Bytes71} =
+ asn1_wrapper:encode('SetOptional','SetOpt1Exp',#'SetOpt1Exp'{bool1 = true,
+ int1 = 15,
+ set1 = #'SetIn'{boolIn = true,
+ intIn = 66}}),
+ ?line {ok,{'SetOpt1Exp',true,15,{'SetIn',true,66}}} =
+ asn1_wrapper:decode('SetOptional','SetOpt1Exp',lists:flatten(Bytes71)),
+
+
+ ?line {ok,Bytes72} = asn1_wrapper:encode('SetOptional','SetOpt1Exp',#'SetOpt1Exp'{int1 = 15}),
+ ?line {ok,{'SetOpt1Exp',asn1_NOVALUE,15,asn1_NOVALUE}} =
+ asn1_wrapper:decode('SetOptional','SetOpt1Exp',lists:flatten(Bytes72)),
+
+
+ ?line {ok,Bytes81} =
+ asn1_wrapper:encode('SetOptional','SetOpt2Exp',#'SetOpt2Exp'{bool2 = true,
+ int2 = 15,
+ set2 = #'SetIn'{boolIn = true,
+ intIn = 66}}),
+ ?line {ok,{'SetOpt2Exp',{'SetIn',true,66},true,15}} =
+ asn1_wrapper:decode('SetOptional','SetOpt2Exp',lists:flatten(Bytes81)),
+
+
+ ?line {ok,Bytes82} = asn1_wrapper:encode('SetOptional','SetOpt2Exp',#'SetOpt2Exp'{int2 = 15,
+ bool2 = true}),
+ ?line {ok,{'SetOpt2Exp',asn1_NOVALUE,true,15}} =
+ asn1_wrapper:decode('SetOptional','SetOpt2Exp',lists:flatten(Bytes82)),
+
+
+
+ ?line {ok,Bytes91} =
+ asn1_wrapper:encode('SetOptional','SetOpt3Exp',#'SetOpt3Exp'{bool3 = true,
+ int3 = 15,
+ set3 = #'SetIn'{boolIn = true,
+ intIn = 66}}),
+ ?line {ok,{'SetOpt3Exp',true,{'SetIn',true,66},15}} =
+ asn1_wrapper:decode('SetOptional','SetOpt3Exp',lists:flatten(Bytes91)),
+
+
+ ?line {ok,Bytes92} = asn1_wrapper:encode('SetOptional','SetOpt3Exp',#'SetOpt3Exp'{int3 = 15}),
+ ?line {ok,{'SetOpt3Exp',asn1_NOVALUE,asn1_NOVALUE,15}} =
+ asn1_wrapper:decode('SetOptional','SetOpt3Exp',lists:flatten(Bytes92)),
+
+
+
+
+ ok.
+
+
+ticket_7533(Ber) when Ber == ber; Ber == ber_bin ->
+ Val = #'SetOpt1'{bool1 = true,int1=12,set1=#'SetIn'{boolIn=false,intIn=13}},
+ ?line {ok,B} = asn1_wrapper:encode('SetOptional','SetOpt1',Val),
+ ?line {ok,Val} = asn1_wrapper:decode('SetOptional','SetOpt1',B),
+
+ CorruptVal = [49,14,1,1,255,2,1,12] ++ lists:duplicate(8,0),
+ Pid = spawn(?MODULE,decoder,[self(),'SetOptional','SetOpt1',CorruptVal]),
+ receive
+ {ok,Pid,Result} ->
+ io:format("Decode result: ~p~n",[Result]),
+ ok
+ after 10000 ->
+ exit(Pid,normal),
+ io:format("Decode timeout~n",[]),
+ error
+ end;
+ticket_7533(_) ->
+ ok.
+
+decoder(Parent,Module,Type,Val) ->
+ io:format("Decoding~n",[]),
+ ?line {ok,Res} = asn1_wrapper:decode(Module,Type,Val),
+ io:format("Decode res: ~p~n",[Res]),
+ Parent ! {ok,self(),Res}.
diff --git a/lib/asn1/test/testSetPrim.erl b/lib/asn1/test/testSetPrim.erl
new file mode 100644
index 0000000000..cb64011dcc
--- /dev/null
+++ b/lib/asn1/test/testSetPrim.erl
@@ -0,0 +1,95 @@
+%%
+%% %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(testSetPrim).
+
+-export([compile/3]).
+-export([main/1]).
+
+-include("test_server.hrl").
+
+-record('Set',{bool, boolCon, boolPri, boolApp, boolExpCon, boolExpPri, boolExpApp}).
+-record('Empty',{}).
+
+compile(Config,Rules,Options) ->
+
+ ?line DataDir = ?config(data_dir,Config),
+ ?line OutDir = ?config(priv_dir,Config),
+ ?line true = code:add_patha(?config(priv_dir,Config)),
+ ?line ok = asn1ct:compile(DataDir ++ "SetPrim",[Rules,{outdir,OutDir}]++Options).
+
+
+
+main(_Rules) ->
+
+
+
+ ?line {ok,Bytes11} =
+ asn1_wrapper:encode('SetPrim','Set',#'Set'{bool = true,
+ boolCon = true,
+ boolPri = true,
+ boolApp = true,
+ boolExpCon = true,
+ boolExpPri = true,
+ boolExpApp = true}),
+ ?line {ok,{'Set',true,true,true,true,true,true,true}} =
+ asn1_wrapper:decode('SetPrim','Set',lists:flatten(Bytes11)),
+
+
+
+
+ ?line {ok,Bytes12} =
+ asn1_wrapper:encode('SetPrim','Set',#'Set'{bool = false,
+ boolCon = false,
+ boolPri = false,
+ boolApp = false,
+ boolExpCon = false,
+ boolExpPri = false,
+ boolExpApp = false}),
+ ?line {ok,{'Set',false,false,false,false,false,false,false}} =
+ asn1_wrapper:decode('SetPrim','Set',lists:flatten(Bytes12)),
+
+
+
+
+ ?line {ok,Bytes13} =
+ asn1_wrapper:encode('SetPrim','Set',#'Set'{bool = false,
+ boolCon = true,
+ boolPri = false,
+ boolApp = true,
+ boolExpCon = false,
+ boolExpPri = true,
+ boolExpApp = false}),
+ ?line {ok,{'Set',false,true,false,true,false,true,false}} =
+ asn1_wrapper:decode('SetPrim','Set',lists:flatten(Bytes13)),
+
+
+
+
+
+ ?line {ok,Bytes21} =
+ asn1_wrapper:encode('SetPrim','Empty',#'Empty'{}),
+ ?line {ok,{'Empty'}} =
+ asn1_wrapper:decode('SetPrim','Empty',lists:flatten(Bytes21)),
+
+
+
+ ok.
+
+
diff --git a/lib/asn1/test/testSetTag.erl b/lib/asn1/test/testSetTag.erl
new file mode 100644
index 0000000000..fcf15dc0f0
--- /dev/null
+++ b/lib/asn1/test/testSetTag.erl
@@ -0,0 +1,114 @@
+%%
+%% %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(testSetTag).
+
+-export([compile/3]).
+-export([main/1]).
+
+-include("test_server.hrl").
+-include("External.hrl").
+
+-record('SetTag',{nt, imp, exp}).
+-record('SetTagImp',{nt, imp, exp}).
+-record('SetTagExp',{nt, imp, exp}).
+-record('SetTagX',{xnt, ximp, xexp}).
+-record('SetTagImpX',{xnt, ximp, xexp}).
+-record('SetTagExpX',{xnt, ximp, xexp}).
+-record('NT',{os, bool}).
+-record('Imp',{os, bool}).
+-record('Exp',{os, bool}).
+
+
+compile(Config,Rules,Options) ->
+
+ ?line DataDir = ?config(data_dir,Config),
+ ?line OutDir = ?config(priv_dir,Config),
+ ?line true = code:add_patha(?config(priv_dir,Config)),
+ ?line ok = asn1ct:compile(DataDir ++ "SetTag",[Rules,{outdir,OutDir}]++Options).
+
+
+
+main(_Rules) ->
+
+
+ ?line {ok,Bytes11} =
+ asn1_wrapper:encode('SetTag','SetTag',#'SetTag'{nt = #'NT'{bool = true, os = "kalle"},
+ imp = #'Imp'{bool = true, os = "kalle"},
+ exp = #'Exp'{bool = true, os = "kalle"}}),
+ ?line {ok,{'SetTag',{'NT',"kalle",true},{'Imp',"kalle",true},{'Exp',"kalle",true}}} =
+ asn1_wrapper:decode('SetTag','SetTag',lists:flatten(Bytes11)),
+
+
+ ?line {ok,Bytes12} =
+ asn1_wrapper:encode('SetTag','SetTagImp',#'SetTagImp'{nt = #'NT'{bool = true, os = "kalle"},
+ imp = #'Imp'{bool = true, os = "kalle"},
+ exp = #'Exp'{bool = true, os = "kalle"}}),
+ ?line {ok,{'SetTagImp',{'NT',"kalle",true},{'Imp',"kalle",true},{'Exp',"kalle",true}}} =
+ asn1_wrapper:decode('SetTag','SetTagImp',lists:flatten(Bytes12)),
+
+
+ ?line {ok,Bytes13} =
+ asn1_wrapper:encode('SetTag','SetTagExp',#'SetTagExp'{nt = #'NT'{bool = true, os = "kalle"},
+ imp = #'Imp'{bool = true, os = "kalle"},
+ exp = #'Exp'{bool = true, os = "kalle"}}),
+ ?line {ok,{'SetTagExp',{'NT',"kalle",true},{'Imp',"kalle",true},{'Exp',"kalle",true}}} =
+ asn1_wrapper:decode('SetTag','SetTagExp',lists:flatten(Bytes13)),
+
+
+
+
+
+ ?line {ok,Bytes21} =
+ asn1_wrapper:encode('SetTag','SetTagX',
+ #'SetTagX'{xnt = #'XSetNT'{bool = true, os = "kalle"},
+ ximp = #'XSetImp'{bool = true, os = "kalle"},
+ xexp = #'XSetExp'{bool = true, os = "kalle"}}),
+ ?line {ok,{'SetTagX',{'XSetNT',"kalle",true},
+ {'XSetImp',"kalle",true},
+ {'XSetExp',"kalle",true}}} =
+ asn1_wrapper:decode('SetTag','SetTagX',lists:flatten(Bytes21)),
+
+
+ ?line {ok,Bytes22} =
+ asn1_wrapper:encode('SetTag','SetTagImpX',
+ #'SetTagImpX'{xnt = #'XSetNT'{bool = true, os = "kalle"},
+ ximp = #'XSetImp'{bool = true, os = "kalle"},
+ xexp = #'XSetExp'{bool = true, os = "kalle"}}),
+ ?line {ok,{'SetTagImpX',{'XSetNT',"kalle",true},
+ {'XSetImp',"kalle",true},
+ {'XSetExp',"kalle",true}}} =
+ asn1_wrapper:decode('SetTag','SetTagImpX',lists:flatten(Bytes22)),
+
+
+ ?line {ok,Bytes23} =
+ asn1_wrapper:encode('SetTag','SetTagExpX',
+ #'SetTagExpX'{xnt = #'XSetNT'{bool = true, os = "kalle"},
+ ximp = #'XSetImp'{bool = true, os = "kalle"},
+ xexp = #'XSetExp'{bool = true, os = "kalle"}}),
+ ?line {ok,{'SetTagExpX',{'XSetNT',"kalle",true},
+ {'XSetImp',"kalle",true},
+ {'XSetExp',"kalle",true}}} =
+ asn1_wrapper:decode('SetTag','SetTagExpX',lists:flatten(Bytes23)),
+
+
+
+
+
+ ok.
diff --git a/lib/asn1/test/testSetTypeRefCho.erl b/lib/asn1/test/testSetTypeRefCho.erl
new file mode 100644
index 0000000000..c2dbf076bd
--- /dev/null
+++ b/lib/asn1/test/testSetTypeRefCho.erl
@@ -0,0 +1,54 @@
+%%
+%% %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(testSetTypeRefCho).
+
+-export([compile/3]).
+-export([main/1]).
+
+-include("test_server.hrl").
+-include("External.hrl").
+
+-record('SetTRcho',{setCho, setChoE, 'setCho-E', 'setChoE-E'}).
+
+
+compile(Config,Rules,Options) ->
+
+ ?line DataDir = ?config(data_dir,Config),
+ ?line OutDir = ?config(priv_dir,Config),
+ ?line true = code:add_patha(?config(priv_dir,Config)),
+ ?line ok = asn1ct:compile(DataDir ++ "SetTypeRefCho",[Rules,{outdir,OutDir}]++Options).
+
+
+
+main(_Rules) ->
+
+
+ ?line {ok,Bytes11} =
+ asn1_wrapper:encode('SetTypeRefCho','SetTRcho',
+ #'SetTRcho'{'setCho' = {choOs,"A string 1"},
+ 'setChoE' = {choOs,"A string 3"},
+ 'setCho-E' = {choOs,"A string 7"},
+ 'setChoE-E' = {choOs,"A string 9"}}),
+ ?line {ok,{'SetTRcho',{choOs,"A string 1"},{choOs,"A string 3"},{choOs,"A string 7"},{choOs,"A string 9"}}} =
+ asn1_wrapper:decode('SetTypeRefCho','SetTRcho',lists:flatten(Bytes11)),
+
+
+
+ ok.
diff --git a/lib/asn1/test/testSetTypeRefPrim.erl b/lib/asn1/test/testSetTypeRefPrim.erl
new file mode 100644
index 0000000000..1f95947168
--- /dev/null
+++ b/lib/asn1/test/testSetTypeRefPrim.erl
@@ -0,0 +1,57 @@
+%%
+%% %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(testSetTypeRefPrim).
+
+-export([compile/3]).
+-export([main/1]).
+
+-include("test_server.hrl").
+
+-record('SetTR',{octStr, octStrI, octStrE, 'octStr-I', 'octStrI-I', 'octStrE-I', 'octStr-E', 'octStrI-E', 'octStrE-E'}).
+
+
+compile(Config,Rules,Options) ->
+
+ ?line DataDir = ?config(data_dir,Config),
+ ?line OutDir = ?config(priv_dir,Config),
+ ?line true = code:add_patha(?config(priv_dir,Config)),
+ ?line ok = asn1ct:compile(DataDir ++ "SetTypeRefPrim",[Rules,{outdir,OutDir}]++Options).
+
+
+
+main(_Rules) ->
+
+
+ ?line {ok,Bytes11} =
+ asn1_wrapper:encode('SetTypeRefPrim','SetTR',#'SetTR'{'octStr' = "A string 1",
+ 'octStrI' = "A string 2",
+ 'octStrE' = "A string 3",
+ 'octStr-I' = "A string 4",
+ 'octStrI-I' = "A string 5",
+ 'octStrE-I' = "A string 6",
+ 'octStr-E' = "A string 7",
+ 'octStrI-E' = "A string 8",
+ 'octStrE-E' = "A string 9"}),
+ ?line {ok,{'SetTR',"A string 1","A string 2","A string 3","A string 4","A string 5","A string 6","A string 7","A string 8","A string 9"}} =
+ asn1_wrapper:decode('SetTypeRefPrim','SetTR',lists:flatten(Bytes11)),
+
+
+
+ ok.
diff --git a/lib/asn1/test/testSetTypeRefSeq.erl b/lib/asn1/test/testSetTypeRefSeq.erl
new file mode 100644
index 0000000000..2f6dfec9c6
--- /dev/null
+++ b/lib/asn1/test/testSetTypeRefSeq.erl
@@ -0,0 +1,76 @@
+%%
+%% %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(testSetTypeRefSeq).
+
+-export([compile/3]).
+-export([main/1]).
+
+-include("test_server.hrl").
+
+-record('SetTRseq',{setSeq, setSeqI, setSeqE, 'setSeq-I', 'setSeqI-I', 'setSeqE-I', 'setSeq-E', 'setSeqI-E', 'setSeqE-E'}).
+-record('SetSeq',{seqInt, seqOs}).
+-record('SetSeqImp',{seqInt, seqOs}).
+-record('SetSeqExp',{seqInt, seqOs}).
+
+
+
+compile(Config,Rules,Options) ->
+
+ ?line DataDir = ?config(data_dir,Config),
+ ?line OutDir = ?config(priv_dir,Config),
+ ?line true = code:add_patha(?config(priv_dir,Config)),
+ ?line ok = asn1ct:compile(DataDir ++ "SetTypeRefSeq",[Rules,{outdir,OutDir}]++Options).
+
+
+
+main(_Rules) ->
+
+ ?line {ok,Bytes41} =
+ asn1_wrapper:encode('SetTypeRefSeq','SetTRseq',
+ #'SetTRseq'{'setSeq' = #'SetSeq'{seqOs = "A1",
+ seqInt = 2},
+ 'setSeqI' = #'SetSeq'{seqOs = "A2",
+ seqInt = 2},
+ 'setSeqE' = #'SetSeq'{seqOs = "A3",
+ seqInt = 2},
+ 'setSeq-I' = #'SetSeqImp'{seqOs = "A4",
+ seqInt = 2},
+ 'setSeqI-I' = #'SetSeqImp'{seqOs = "A5",
+ seqInt = 2},
+ 'setSeqE-I' = #'SetSeqImp'{seqOs = "A6",
+ seqInt = 2},
+ 'setSeq-E' = #'SetSeqExp'{seqOs = "A7",
+ seqInt = 2},
+ 'setSeqI-E' = #'SetSeqExp'{seqOs = "A8",
+ seqInt = 2},
+ 'setSeqE-E' = #'SetSeqExp'{seqOs = "A9",
+ seqInt = 2}}),
+ ?line {ok,{'SetTRseq',{'SetSeq',2,"A1"},
+ {'SetSeq',2,"A2"},
+ {'SetSeq',2,"A3"},
+ {'SetSeqImp',2,"A4"},
+ {'SetSeqImp',2,"A5"},
+ {'SetSeqImp',2,"A6"},
+ {'SetSeqExp',2,"A7"},
+ {'SetSeqExp',2,"A8"},
+ {'SetSeqExp',2,"A9"}}} =
+ asn1_wrapper:decode('SetTypeRefSeq','SetTRseq',lists:flatten(Bytes41)),
+
+ ok.
diff --git a/lib/asn1/test/testSetTypeRefSet.erl b/lib/asn1/test/testSetTypeRefSet.erl
new file mode 100644
index 0000000000..132e5fb3f5
--- /dev/null
+++ b/lib/asn1/test/testSetTypeRefSet.erl
@@ -0,0 +1,186 @@
+%%
+%% %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(testSetTypeRefSet).
+
+-export([compile/3]).
+-export([main/1]).
+
+-include("test_server.hrl").
+
+-record('Set1',{bool1, int1, set1}).
+-record('Set2',{set2, bool2, int2}).
+-record('Set3',{bool3, set3, int3}).
+-record('Set4',{set41, set42, set43}).
+-record('SetIn',{boolIn, intIn}).
+-record('SetS1',{boolS1, intS1, setS1}).
+-record('SetS1_setS1',{boolIn, intIn}).
+-record('SetS2',{setS2, boolS2, intS2}).
+-record('SetS2_setS2',{boolIn, intIn}).
+-record('SetS3',{boolS3, setS3, intS3}).
+-record('SetS3_setS3',{boolIn, intIn}).
+-record('SetSTag',{setS1, setS2, setS3}).
+-record('SetSTag_setS1',{b1, i1}).
+-record('SetSTag_setS2',{b2, i2}).
+-record('SetSTag_setS3',{b3, i3}).
+-record('SetTRset',{setSet, setSetI, setSetE, 'setSet-I', 'setSetI-I', 'setSetE-I', 'setSet-E', 'setSetI-E', 'setSetE-E'}).
+-record('SetSet',{setInt, setOs}).
+-record('SetSetImp',{setInt, setOs}).
+-record('SetSetExp',{setInt, setOs}).
+
+
+
+compile(Config,Rules,Options) ->
+
+ ?line DataDir = ?config(data_dir,Config),
+ ?line OutDir = ?config(priv_dir,Config),
+ ?line true = code:add_patha(?config(priv_dir,Config)),
+ ?line ok = asn1ct:compile(DataDir ++ "SetTypeRefSet",[Rules,{outdir,OutDir}]++Options).
+
+
+
+main(_Rules) ->
+
+
+ ?line {ok,Bytes11} =
+ asn1_wrapper:encode('SetTypeRefSet','Set1',#'Set1'{bool1 = true,
+ int1 = 15,
+ set1 = #'SetIn'{boolIn = true,
+ intIn = 66}}),
+ ?line {ok,{'Set1',true,15,{'SetIn',true,66}}} =
+ asn1_wrapper:decode('SetTypeRefSet','Set1',lists:flatten(Bytes11)),
+
+
+
+ ?line {ok,Bytes12} =
+ asn1_wrapper:encode('SetTypeRefSet','Set2',#'Set2'{set2 = #'SetIn'{boolIn = true,
+ intIn = 66},
+ bool2 = true,
+ int2 = 15}),
+ ?line {ok,{'Set2',{'SetIn',true,66},true,15}} =
+ asn1_wrapper:decode('SetTypeRefSet','Set2',lists:flatten(Bytes12)),
+
+
+ ?line {ok,Bytes13} =
+ asn1_wrapper:encode('SetTypeRefSet','Set3',#'Set3'{bool3 = true,
+ set3 = #'SetIn'{boolIn = true,
+ intIn = 66},
+ int3 = 15}),
+ ?line {ok,{'Set3',true,{'SetIn',true,66},15}} =
+ asn1_wrapper:decode('SetTypeRefSet','Set3',lists:flatten(Bytes13)),
+
+
+
+ ?line {ok,Bytes14} =
+ asn1_wrapper:encode('SetTypeRefSet','Set4',#'Set4'{set41 = #'SetIn'{boolIn = true,
+ intIn = 66},
+ set42 = #'SetIn'{boolIn = true,
+ intIn = 66},
+ set43 = #'SetIn'{boolIn = true,
+ intIn = 66}}),
+ ?line {ok,{'Set4',{'SetIn',true,66},{'SetIn',true,66},{'SetIn',true,66}}} =
+ asn1_wrapper:decode('SetTypeRefSet','Set4',lists:flatten(Bytes14)),
+
+
+
+
+
+
+
+
+ ?line {ok,Bytes21} =
+ asn1_wrapper:encode('SetTypeRefSet','SetS1',#'SetS1'{boolS1 = true,
+ intS1 = 15,
+ setS1 = #'SetS1_setS1'{boolIn = true,
+ intIn = 66}}),
+ ?line {ok,{'SetS1',true,15,{'SetS1_setS1',true,66}}} =
+ asn1_wrapper:decode('SetTypeRefSet','SetS1',lists:flatten(Bytes21)),
+
+
+ ?line {ok,Bytes22} =
+ asn1_wrapper:encode('SetTypeRefSet','SetS2',#'SetS2'{setS2 = #'SetS2_setS2'{boolIn = true,
+ intIn = 66},
+ boolS2 = true,
+ intS2 = 15}),
+ ?line {ok,{'SetS2',{'SetS2_setS2',true,66},true,15}} =
+ asn1_wrapper:decode('SetTypeRefSet','SetS2',lists:flatten(Bytes22)),
+
+
+
+ ?line {ok,Bytes23} =
+ asn1_wrapper:encode('SetTypeRefSet','SetS3',#'SetS3'{boolS3 = true,
+ setS3 = #'SetS3_setS3'{boolIn = true,
+ intIn = 66},
+ intS3 = 15}),
+ ?line {ok,{'SetS3',true,{'SetS3_setS3',true,66},15}} =
+ asn1_wrapper:decode('SetTypeRefSet','SetS3',lists:flatten(Bytes23)),
+
+
+
+
+
+
+ ?line {ok,Bytes31} =
+ asn1_wrapper:encode('SetTypeRefSet','SetSTag',#'SetSTag'{setS1 = #'SetSTag_setS1'{b1 = true,
+ i1 = 11},
+ setS2 = #'SetSTag_setS2'{b2 = true,
+ i2 = 22},
+ setS3 = #'SetSTag_setS3'{b3 = true,
+ i3 = 33}}),
+ ?line {ok,{'SetSTag',{'SetSTag_setS1',true,11},
+ {'SetSTag_setS2',true,22},
+ {'SetSTag_setS3',true,33}}} =
+ asn1_wrapper:decode('SetTypeRefSet','SetSTag',lists:flatten(Bytes31)),
+
+
+
+
+
+ ?line {ok,Bytes41} =
+ asn1_wrapper:encode('SetTypeRefSet','SetTRset',
+ #'SetTRset'{'setSet' = #'SetSet'{setOs = "A1",
+ setInt = 2},
+ 'setSetI' = #'SetSet'{setOs = "A2",
+ setInt = 2},
+ 'setSetE' = #'SetSet'{setOs = "A3",
+ setInt = 2},
+ 'setSet-I' = #'SetSetImp'{setOs = "A4",
+ setInt = 2},
+ 'setSetI-I' = #'SetSetImp'{setOs = "A5",
+ setInt = 2},
+ 'setSetE-I' = #'SetSetImp'{setOs = "A6",
+ setInt = 2},
+ 'setSet-E' = #'SetSetExp'{setOs = "A7",
+ setInt = 2},
+ 'setSetI-E' = #'SetSetExp'{setOs = "A8",
+ setInt = 2},
+ 'setSetE-E' = #'SetSetExp'{setOs = "A9",
+ setInt = 2}}),
+ ?line {ok,{'SetTRset',{'SetSet',2,"A1"},
+ {'SetSet',2,"A2"},
+ {'SetSet',2,"A3"},
+ {'SetSetImp',2,"A4"},
+ {'SetSetImp',2,"A5"},
+ {'SetSetImp',2,"A6"},
+ {'SetSetExp',2,"A7"},
+ {'SetSetExp',2,"A8"},
+ {'SetSetExp',2,"A9"}}} =
+ asn1_wrapper:decode('SetTypeRefSet','SetTRset',lists:flatten(Bytes41)),
+
+ ok.
diff --git a/lib/asn1/test/testTCAP.erl b/lib/asn1/test/testTCAP.erl
new file mode 100644
index 0000000000..3e2c2de371
--- /dev/null
+++ b/lib/asn1/test/testTCAP.erl
@@ -0,0 +1,103 @@
+%%
+%% %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(testTCAP).
+
+-export([compile/3,test/2,compile_asn1config/3,test_asn1config/0]).
+
+-include("test_server.hrl").
+
+
+
+compile(Config,Rules,Opt) ->
+
+ ?line DataDir = ?config(data_dir,Config),
+ ?line OutDir = ?config(priv_dir,Config),
+ ?line true = code:add_patha(?config(priv_dir,Config)),
+
+ ?line ok = asn1ct:compile(DataDir ++ "Remote-Operations-Information-Objects",[Rules,{outdir,OutDir}]++Opt),
+% ?line ok = asn1ct:compile(DataDir ++ "Remote-Operations-Generic-ROS-PDUs",[Rules,{outdir,OutDir}]++Opt),
+% ?line ok = asn1ct:compile(DataDir ++ "Remote-Operations-Useful-Definitions",[Rules,{outdir,OutDir}]++Opt),
+ ?line ok = asn1ct:compile(DataDir ++ "TCAPMessages",[Rules,{outdir,OutDir}]++Opt),
+ ?line ok = asn1ct:compile(DataDir ++ "TCAPMessages-simple",[Rules,{outdir,OutDir}]++Opt),
+ ?line ok = asn1ct:compile(DataDir ++ "TCAPPackage",[Rules,{outdir,OutDir}]++Opt),
+ ?line compile:file(filename:join([DataDir,"TCAPPackage_msg"]),[{i,OutDir},{outdir,OutDir}]).
+
+compile_asn1config(Config,Rules,Opt) ->
+ ?line DataDir = ?config(data_dir,Config),
+ ?line OutDir = ?config(priv_dir,Config),
+ ?line true = code:add_patha(?config(priv_dir,Config)),
+
+ ?line ok = asn1ct:compile(DataDir ++ "TCAPPackage",
+ [Rules,{outdir,OutDir},{i,DataDir}]++Opt).
+
+test(Erule,_Config) when Erule==ber;Erule==ber_bin;Erule==ber_bin_v2 ->
+% ?line OutDir = ?config(priv_dir,Config),
+ %% testing OTP-4798, open type encoded with indefinite length
+ ?line {ok,_Res} = asn1_wrapper:decode('TCAPMessages-simple','MessageType', val_OTP_4798(Erule)),
+ %% testing OTP-4799, absent optional open type
+ ?line {ok,_Res2} = asn1_wrapper:decode('TCAPMessages-simple','MessageType',val_OTP_4799(Erule)),
+ %% testing vance shipley's problems. Parameterized object sets.
+ ?line Val3 = 'TCAPPackage_msg':val('PackageType',unidirectional),
+ ?line {ok,Bytes3} = asn1_wrapper:encode('TCAPPackage','PackageType',Val3),
+ ?line {ok,Res3} = asn1_wrapper:decode('TCAPPackage','PackageType',Bytes3),
+ ?line ok = 'TCAPPackage_msg':check_result('PackageType',unidirectional,Res3),
+%% ?line io:format("Res3:~n~p~n~n",[Res3]),
+
+ ?line Val4 = 'TCAPPackage_msg':val('PackageType',abort),
+ ?line {ok,Bytes4} = asn1_wrapper:encode('TCAPPackage','PackageType',Val4),
+ ?line {ok,Res4} = asn1_wrapper:decode('TCAPPackage','PackageType',Bytes4),
+ ?line ok = 'TCAPPackage_msg':check_result('PackageType',abort,Res4),
+%% ?line io:format("Res4:~n~p~n~n",[Res4]),
+
+ ?line Val5 = 'TCAPPackage_msg':val('PackageType',response),
+ ?line {ok,Bytes5} = asn1_wrapper:encode('TCAPPackage','PackageType',Val5),
+ ?line {ok,Res5} = asn1_wrapper:decode('TCAPPackage','PackageType',Bytes5),
+ ?line ok = 'TCAPPackage_msg':check_result('PackageType',response,Res5).
+%% ?line io:format("Res5:~n~p~n~n",[Res5]).
+
+val_OTP_4798(ber) ->
+ [100,129,176,73,4,57,3,17,80,107,42,40,40,6,7,0,17,134,5,1,1,1,160,29,97,27,128,2,7,128,161,9,6,7,4,0,0,1,0,14,2,162,3,2,1,0,163,5,161,3,2,1,0,108,128,162,120,2,1,0,48,115,2,1,56,48,128,48,34,4,16,203,87,215,196,217,93,235,90,64,131,106,145,39,26,25,236,4,4,197,241,81,112,4,8,78,225,34,196,215,212,200,0,48,34,4,16,145,125,27,67,42,144,6,161,207,112,55,75,200,191,191,28,4,4,226,219,242,123,4,8,72,46,130,28,206,178,168,0,48,34,4,16,1,8,20,29,70,160,218,160,125,188,244,174,113,115,253,245,4,4,26,5,90,160,4,8,252,75,149,98,153,224,140,0,0,0,0,0];
+val_OTP_4798(_) ->
+ <<100,129,176,73,4,57,3,17,80,107,42,40,40,6,7,0,17,134,5,1,1,1,160,29,97,27,128,2,7,128,161,9,6,7,4,0,0,1,0,14,2,162,3,2,1,0,163,5,161,3,2,1,0,108,128,162,120,2,1,0,48,115,2,1,56,48,128,48,34,4,16,203,87,215,196,217,93,235,90,64,131,106,145,39,26,25,236,4,4,197,241,81,112,4,8,78,225,34,196,215,212,200,0,48,34,4,16,145,125,27,67,42,144,6,161,207,112,55,75,200,191,191,28,4,4,226,219,242,123,4,8,72,46,130,28,206,178,168,0,48,34,4,16,1,8,20,29,70,160,218,160,125,188,244,174,113,115,253,245,4,4,26,5,90,160,4,8,252,75,149,98,153,224,140,0,0,0,0,0>>.
+
+val_OTP_4799(ber) ->
+ [100,16,73,4,41,182,36,0,108,8,163,6,2,1,29,2,1,27];
+val_OTP_4799(_) ->
+ <<100,16,73,4,41,182,36,0,108,8,163,6,2,1,29,2,1,27>>.
+
+test_asn1config() ->
+ ?line Val = 'TCAPPackage_msg':val('PackageType',queryWithPerm),
+ ?line {ok,B} = asn1_wrapper:encode('TCAPPackage','PackageType',Val),
+ ?line {ok,ExMsg}='TCAPPackage':decode_PackageType(list_to_binary(B)),
+ ?line {_,{_,_,_,{Key,ExVal}}}=ExMsg,
+ ?line {ok,_Parts}='TCAPPackage':decode_part(Key,ExVal),
+
+ ?line Val2 = 'TCAPPackage_msg':val('TransactionPDU'),
+ ?line {ok,B2} = 'TCAPPackage':encode('TransactionPDU',Val2),
+ ?line {ok,ExMsg2}='TCAPPackage':decode_TransactionPDU(list_to_binary(B2)),
+ ?line {_,_,_,{Key2,ExVal2}}=ExMsg2,
+ ?line {ok,_Parts2}='TCAPPackage':decode_part(Key2,ExVal2),
+
+ ?line Val3 = 'TCAPPackage_msg':val('PackageType',response),
+ ?line {ok,B3} = asn1_wrapper:encode('TCAPPackage','PackageType',Val3),
+ ?line {ok,ExMsg3}='TCAPPackage':decode_PackageType(list_to_binary(B3)),
+ ?line {_,{_,_,_,{Key3,ExVal3}}}=ExMsg3,
+ ?line {ok,_Parts3}='TCAPPackage':decode_part(Key3,ExVal3).
+
diff --git a/lib/asn1/test/testTcapsystem.erl b/lib/asn1/test/testTcapsystem.erl
new file mode 100644
index 0000000000..c48b1b835d
--- /dev/null
+++ b/lib/asn1/test/testTcapsystem.erl
@@ -0,0 +1,72 @@
+%%
+%% %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(testTcapsystem).
+
+-export([compile/3]).
+
+-include("test_server.hrl").
+
+
+
+compile(Config,Rules,Opt) ->
+
+ ?line DataDir = ?config(data_dir,Config),
+ ?line OutDir = ?config(priv_dir,Config),
+ ?line true = code:add_patha(?config(priv_dir,Config)),
+ ?line DataDir2 = filename:join([DataDir,tcapsystem]),
+
+ ?line ok = asn1ct:compile(filename:join([DataDir2,"DialoguePDUs.asn"]),[Rules,{outdir,OutDir}]++Opt),
+ ?line ok = asn1ct:compile(filename:join([DataDir2,"MAP-ApplicationContexts.asn"]),[Rules,{outdir,OutDir}]++Opt),
+ ?line ok = asn1ct:compile(filename:join([DataDir2,"MAP-BS-Code.asn"]),[Rules,{outdir,OutDir}]++Opt),
+ ?line ok = asn1ct:compile(filename:join([DataDir2,"MAP-CallHandlingOperations.asn"]),[Rules,{outdir,OutDir}]++Opt),
+ ?line ok = asn1ct:compile(filename:join([DataDir2,"MAP-CH-DataTypes.asn"]),[Rules,{outdir,OutDir}]++Opt),
+ ?line ok = asn1ct:compile(filename:join([DataDir2,"MAP-CommonDataTypes.asn"]),[Rules,{outdir,OutDir}]++Opt),
+ ?line ok = asn1ct:compile(filename:join([DataDir2,"MAP-DialogueInformation.asn"]),[Rules,{outdir,OutDir}]++Opt),
+ ?line ok = asn1ct:compile(filename:join([DataDir2,"MAP-ER-DataTypes.asn"]),[Rules,{outdir,OutDir}]++Opt),
+ ?line ok = asn1ct:compile(filename:join([DataDir2,"MAP-Errors.asn"]),[Rules,{outdir,OutDir}]++Opt),
+ ?line ok = asn1ct:compile(filename:join([DataDir2,"MAP-ExtensionDataTypes.asn"]),[Rules,{outdir,OutDir}]++Opt),
+ ?line ok = asn1ct:compile(filename:join([DataDir2,"MAP-GR-DataTypes.asn"]),[Rules,{outdir,OutDir}]++Opt),
+ ?line ok = asn1ct:compile(filename:join([DataDir2,"MAP-Group-Call-Operations.asn"]),[Rules,{outdir,OutDir}]++Opt),
+ ?line ok = asn1ct:compile(filename:join([DataDir2,"MAP-LCS-DataTypes.asn"]),[Rules,{outdir,OutDir}]++Opt),
+ ?line ok = asn1ct:compile(filename:join([DataDir2,"MAP-LocationServiceOperations.asn"]),[Rules,{outdir,OutDir}]++Opt),
+ ?line ok = asn1ct:compile(filename:join([DataDir2,"MAP-MobileServiceOperations.asn"]),[Rules,{outdir,OutDir}]++Opt),
+ ?line ok = asn1ct:compile(filename:join([DataDir2,"MAP-MS-DataTypes.asn"]),[Rules,{outdir,OutDir}]++Opt),
+ ?line ok = asn1ct:compile(filename:join([DataDir2,"MAP-OM-DataTypes.asn"]),[Rules,{outdir,OutDir}]++Opt),
+ ?line ok = asn1ct:compile(filename:join([DataDir2,"MAP-OperationAndMaintenanceOperations.asn"]),[Rules,{outdir,OutDir}]++Opt),
+ ?line ok = asn1ct:compile(filename:join([DataDir2,"MAP-Protocol.asn"]),[Rules,{outdir,OutDir}]++Opt),
+ ?line ok = asn1ct:compile(filename:join([DataDir2,"MAP-SecureTransportOperations.asn"]),[Rules,{outdir,OutDir}]++Opt),
+ ?line ok = asn1ct:compile(filename:join([DataDir2,"MAP-ShortMessageServiceOperations.asn"]),[Rules,{outdir,OutDir}]++Opt),
+ ?line ok = asn1ct:compile(filename:join([DataDir2,"MAP-SM-DataTypes.asn"]),[Rules,{outdir,OutDir}]++Opt),
+ ?line ok = asn1ct:compile(filename:join([DataDir2,"MAP-SS-Code.asn"]),[Rules,{outdir,OutDir}]++Opt),
+ ?line ok = asn1ct:compile(filename:join([DataDir2,"MAP-SS-DataTypes.asn"]),[Rules,{outdir,OutDir}]++Opt),
+ ?line ok = asn1ct:compile(filename:join([DataDir2,"MAP-ST-DataTypes.asn"]),[Rules,{outdir,OutDir}]++Opt),
+ ?line ok = asn1ct:compile(filename:join([DataDir2,"MAP-SupplementaryServiceOperations.asn"]),[Rules,{outdir,OutDir}]++Opt),
+ ?line ok = asn1ct:compile(filename:join([DataDir2,"MAP-TS-Code.asn"]),[Rules,{outdir,OutDir}]++Opt),
+ ?line ok = asn1ct:compile(filename:join([DataDir2,"MobileDomainDefinitions.asn"]),[Rules,{outdir,OutDir}]++Opt),
+ ?line ok = asn1ct:compile(filename:join([DataDir2,"Remote-Operations-Generic-ROS-PDUs.asn"]),[Rules,{outdir,OutDir}]++Opt),
+ ?line ok = asn1ct:compile(filename:join([DataDir2,"Remote-Operations-Information-Objects.asn"]),[Rules,{outdir,OutDir}]++Opt),
+ ?line ok = asn1ct:compile(filename:join([DataDir2,"Remote-Operations-Useful-Definitions.asn"]),[Rules,{outdir,OutDir}]++Opt),
+ ?line ok = asn1ct:compile(filename:join([DataDir2,"TCAP-Examples.asn"]),[Rules,{outdir,OutDir}]++Opt),
+ ?line ok = asn1ct:compile(filename:join([DataDir2,"TCAPMessages.asn"]),[Rules,{outdir,OutDir}]++Opt),
+ ?line ok = asn1ct:compile(filename:join([DataDir2,"TCAP-Tools.asn"]),[Rules,{outdir,OutDir}]++Opt),
+ ?line ok = asn1ct:compile(filename:join([DataDir2,"TC-Notation-Extensions.asn"]),[Rules,{outdir,OutDir}]++Opt),
+ ?line ok = asn1ct:compile(filename:join([DataDir2,"UnidialoguePDUs.asn"]),[Rules,{outdir,OutDir}]++Opt).
+
+
diff --git a/lib/asn1/test/testTimer.erl b/lib/asn1/test/testTimer.erl
new file mode 100644
index 0000000000..34b9cf1740
--- /dev/null
+++ b/lib/asn1/test/testTimer.erl
@@ -0,0 +1,222 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 2001-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(testTimer).
+
+-compile(export_all).
+%%-export([Function/Arity, ...]).
+
+-include("test_server.hrl").
+
+-define(times, 5000).
+
+compile(Config,Enc,Options) ->
+ ?line DataDir = ?config(data_dir,Config),
+ ?line OutDir = ?config(priv_dir,Config),
+ ok = asn1ct:compile(DataDir++"H235-SECURITY-MESSAGES",[Enc,{outdir,OutDir}]++Options),
+ ok = asn1ct:compile(DataDir++"H323-MESSAGES",[Enc,{outdir,OutDir}]++Options).
+
+val() ->
+ _Value = {'H323-UserInformation',{'H323-UU-PDU',
+ {callProceeding,
+ {'CallProceeding-UUIE',
+ {0,8,222},
+ {'EndpointType',
+ {'NonStandardParameter',
+ {object,{0,9,237}},
+ "O"},
+ {'VendorIdentifier',
+ {'H221NonStandard',62,63,16282},
+ "OC",
+ "OC"},
+ {'GatekeeperInfo',
+ {'NonStandardParameter',
+ {object,{0,10,260}},
+ "O"}},
+ {'GatewayInfo',
+ [{h320,
+ {'H320Caps',
+ {'NonStandardParameter',
+ {object,{0,11,282}},
+ "O"},
+ [{'DataRate',
+ {'NonStandardParameter',
+ {object,
+ {0,11,295}},
+ "O"},
+ 1290470518,
+ 78}],
+ [{'SupportedPrefix',
+ {'NonStandardParameter',
+ {object,
+ {0,12,312}},
+ "O"},
+ {'h323-ID',"BM"}}]}}],
+ {'NonStandardParameter',
+ {object,{0,13,326}},
+ "O"}},
+ {'McuInfo',
+ {'NonStandardParameter',
+ {object,{1,13,340,340}},
+ "OC"}},
+ {'TerminalInfo',
+ {'NonStandardParameter',
+ {object,{1,14,353,354}},
+ "OC"}},
+ true,
+ true},
+ {ipxAddress,
+ {'TransportAddress_ipxAddress',
+ "OCTET ",
+ "OCTE",
+ "OC"}},
+ {'CallIdentifier',"OCTET STRINGOCTE"},
+ {noSecurity,'NULL'},
+ [{'ClearToken',
+ 1667517741,
+ "BM",
+ {'DHset',[1],[1],[1]},
+ "OCTET STR",
+ -26430296,
+ {'TypedCertificate',
+ {1,16,405,406},
+ "OC"},
+ "BMP",
+ {'NonStandardParameter',
+ {1,16,414,415},
+ "OC"}},
+ {'ClearToken',
+ 1817656756,
+ "BMP",
+ {'DHset',[1],[1],[1]},
+ "OCTET STRI",
+ -16356110,
+ {'TypedCertificate',
+ {1,17,442,443},
+ "OC"},
+ "BMP",
+ {'NonStandardParameter',
+ {1,18,452,452},
+ "OC"}}],
+ [{cryptoGKPwdEncr,
+ {'CryptoH323Token_cryptoGKPwdEncr',
+ {1,18,467,467},
+ {'Params',-7477016,"OCTET ST"},
+ "OC"}},
+ {cryptoGKPwdEncr,
+ {'CryptoH323Token_cryptoGKPwdEncr',
+ {1,19,486,486},
+ {'Params',-2404513,"OCTET ST"},
+ []}}],
+ []}},
+ {'NonStandardParameter',{object,{0,3,84}},[]},
+ [],
+ true,
+ [],
+ []},
+ {'H323-UserInformation_user-data',24,"O"}}.
+
+
+go(Config,Enc) ->
+ ?line true = code:add_patha(?config(priv_dir,Config)),
+
+ Module = 'H323-MESSAGES',
+ Type = 'H323-UserInformation',
+ Value = val(),
+%% ok = asn1ct:compile(HelpModule,[Enc]),
+
+%% ok = asn1ct:compile(Module,[Enc]),
+ ?line {ok,B} = asn1rt:encode(Module,Type,Value),
+ Bytes = case Enc of
+ ber_bin ->
+ list_to_binary(B);
+ per_bin when is_list(B) ->
+ list_to_binary(B);
+ per_bin ->
+ B;
+ uper_bin ->
+ B;
+ _ ->
+ %%lists:flatten(B)
+ list_to_binary(B)
+ end,
+
+ CompileOptions = compile_options(),
+
+ ?line {ValWr, done} = timer:tc(?MODULE, encode, [?times, Module, Type, Value]),
+ ?line io:format("ASN1 encode ~p: ~p micro~n", [CompileOptions, ValWr / ?times]),
+
+ ?line done = decode(2,Module,Type,Bytes,Enc),
+
+ ?line {ValRead, done} = timer:tc(?MODULE, decode, [?times, Module,
+ Type, Bytes,Enc]),
+ ?line io:format("ASN1 decode ~p: ~p micro~n", [CompileOptions, ValRead /?times]),
+
+
+ ?line Comment = "encode: "++integer_to_list(round(ValWr/?times))++
+ " micro, decode: "++integer_to_list(round(ValRead /?times))++
+ " micro. " ++ CompileOptions,
+ {comment,Comment}.
+
+encode(0, _Module,_Type,_Value) ->
+ done;
+encode(N, Module,Type,Value) ->
+ ?line {ok,B} = asn1rt:encode(Module,Type,Value),
+ _B2 = if
+ is_list(B) -> list_to_binary(B);
+ true -> B
+ end,
+ encode(N-1, Module,Type,Value).
+
+decode(0, _Module,_Type,_Value,_Erule) ->
+ done;
+decode(N, Module,Type,Value,Erule) ->
+ case Erule of
+ ber ->
+ ?line {ok,_B} = asn1rt:decode(Module,Type,binary_to_list(Value));
+ per ->
+ ?line {ok,_B} = asn1rt:decode(Module,Type,binary_to_list(Value));
+ _ ->
+ ?line {ok,_B} = asn1rt:decode(Module,Type,Value)
+ end,
+ decode(N-1, Module,Type,Value,Erule).
+
+compile_options() ->
+ ?line {ok,Info} = asn1rt:info('H323-MESSAGES'),
+ case lists:keysearch(options,1,Info) of
+ {_,{_,Opts}} ->
+ Opts2 =
+ case lists:member(ber_bin_v2,Opts) of
+ true ->
+ [ber_bin,optimize] ++ lists:delete(optimize,Opts);
+ _ ->
+ Opts
+ end,
+ Opts3 = [X||X <- Opts2,
+ (X == ber orelse
+ X == ber_bin orelse
+ X == per orelse
+ X == per_bin orelse
+ X == optimize orelse
+ X == driver)],
+ lists:flatten(io_lib:format("~p",[Opts3]));
+ _ ->
+ "[]"
+ end.
+
diff --git a/lib/asn1/test/testTypeValueNotation.erl b/lib/asn1/test/testTypeValueNotation.erl
new file mode 100644
index 0000000000..0fc3dc3197
--- /dev/null
+++ b/lib/asn1/test/testTypeValueNotation.erl
@@ -0,0 +1,78 @@
+%%
+%% %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(testTypeValueNotation).
+
+-export([compile/3]).
+-export([main/2]).
+
+-include("test_server.hrl").
+
+-record('Seq',{octstr, int, bool, enum, bitstr, null, oid, vstr}).
+
+
+compile(Config,Rules,Options) ->
+
+ ?line DataDir = ?config(data_dir,Config),
+ ?line OutDir = ?config(priv_dir,Config),
+ ?line true = code:add_patha(?config(priv_dir,Config)),
+ ?line ok = asn1ct:compile(DataDir ++ "SeqTypeRefPrim",
+ [Rules,{outdir,OutDir}]++Options),
+ %% OTP-6695
+ ?line ok = asn1ct:compile(DataDir ++ "ValueTest",
+ [Rules,{outdir,OutDir}]++Options).
+
+
+main(Rules,Option) ->
+
+ io:format("testTypeValueNotation:main/2 with arguments:~nRules: ~w, Option: ~w~n",[Rules,Option]),
+ Value1 = #'Seq'{octstr = [1,2,3,4],
+ int = 12,
+ bool = true,
+ enum = a,
+ bitstr = [1,0,1,0],
+ null = 'NULL',
+ oid = {1,2,55},
+ vstr = "Hello World"},
+ Value2 = #'Seq'{octstr = {'OctStr',[1,2,3,4]},
+ int = {'Int',12},
+ bool = {'Bool',true},
+ enum = {'Enum',a},
+ bitstr = {'BitStr',[1,0,1,0]},
+ null = {'Null','NULL'},
+ oid = {'OId',{1,2,55}},
+ vstr = {'VStr',"Hello World"}},
+ case Option of
+ optimize when Rules == per_bin; Rules == ber_bin ; Rules == uper_bin; Rules == ber_bin_v2 ->
+ ?line {ok,Bytes} =
+ asn1_wrapper:encode('SeqTypeRefPrim','Seq',Value1),
+ ?line {error,_Reason} =
+ asn1_wrapper:encode('SeqTypeRefPrim','Seq',Value2),
+ ?line {ok,Value1} =
+ asn1_wrapper:decode('SeqTypeRefPrim','Seq',Bytes);
+ _ ->
+ ?line {ok,Bytes} =
+ asn1_wrapper:encode('SeqTypeRefPrim','Seq',Value1),
+ ?line {ok,Bytes} =
+ asn1_wrapper:encode('SeqTypeRefPrim','Seq',Value2),
+ ?line {ok,Value1} =
+ asn1_wrapper:decode('SeqTypeRefPrim','Seq',Bytes)
+ end,
+
+ ok.
diff --git a/lib/asn1/test/testX420.erl b/lib/asn1/test/testX420.erl
new file mode 100644
index 0000000000..314c5c837a
--- /dev/null
+++ b/lib/asn1/test/testX420.erl
@@ -0,0 +1,114 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 2008-2010. All Rights Reserved.
+%%
+%% The contents of this file are subject to the Erlang Public License,
+%% Version 1.1, (the "License"); you may not use this file except in
+%% compliance with the License. You should have received a copy of the
+%% Erlang Public License along with this software. If not, it can be
+%% retrieved online at http://www.erlang.org/.
+%%
+%% Software distributed under the License is distributed on an "AS IS"
+%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+%% the License for the specific language governing rights and limitations
+%% under the License.
+%%
+%% %CopyrightEnd%
+%%
+%%
+%%-------------------------------------------------------------------
+
+-module(testX420).
+
+-export([compile/3, ticket7759/2]).
+
+-include("test_server.hrl").
+
+
+compile(Erule,Options,Config) ->
+
+ Specs = specs(),
+ ?line 99 = length(Specs),
+ ?line ok = compile_loop(Erule,Specs,Options,Config).
+
+
+
+compile_loop(_Erule,[],_Options,_Config) ->
+ ok;
+compile_loop(Erule,[Spec|Specs],Options,Config)
+ when Erule == ber; Erule == ber_bin; Erule == ber_bin_v2;
+ Erule == per ->
+
+ ?line DataDir = ?config(data_dir,Config),
+ ?line OutDir = ?config(priv_dir,Config),
+
+ case asn1ct:compile(DataDir ++ "/x420/" ++ Spec,[Erule,{outdir,OutDir},
+ {i,OutDir}]++Options) of
+ ok ->
+ compile_loop(Erule,Specs,Options,Config);
+ Error ->
+ Error
+ end;
+compile_loop(_Erule,_Specs,_Options,_Config) ->
+ ok.%%{skip,io_lib:format("Not tested for ~p",[Erule])}.
+
+
+specs() ->
+ ["ACSE-1", "AuthenticationFramework", "BasicAccessControl",
+ "CertificateExtensions", "Character-Coding-Attributes",
+ "Character-Presentation-Attributes", "Character-Profile-Attributes",
+ "Colour-Attributes", "DOR-definition", "DSAOperationalAttributeTypes",
+ "Default-Value-Lists", "DirectoryAbstractService",
+ "DirectoryAccessProtocol", "DirectoryInformationShadowProtocol",
+ "DirectoryOperationalBindingManagementProtocol",
+ "DirectoryOperationalBindingTypes", "DirectoryProtectionMappings",
+ "DirectoryShadowAbstractService", "DirectorySystemProtocol",
+ "DistributedOperations", "Document-Profile-Descriptor",
+ "EnhancedSecurity", "External-References", "GULSProtectionMappings",
+ "GenericProtectingTransferSyntax", "Geo-Gr-Coding-Attributes",
+ "Geo-Gr-Presentation-Attributes", "Geo-Gr-Profile-Attributes",
+ "GulsSecurityExchanges", "GulsSecurityTransformations",
+ "HierarchicalOperationalBindings", "IPMSAbstractService",
+ "IPMSAutoActionTypes", "IPMSExtendedBodyPartTypes",
+ "IPMSExtendedBodyPartTypes2", "IPMSExtendedVoiceBodyPartType",
+ "IPMSFileTransferBodyPartType", "IPMSForwardedContentBodyPartType",
+ "IPMSForwardedReportBodyPartType", "IPMSFunctionalObjects",
+ "IPMSHeadingExtensions", "IPMSInformationObjects",
+ "IPMSMessageStoreAttributes", "IPMSObjectIdentifiers",
+ "IPMSObjectIdentifiers2", "IPMSSecurityExtensions", "IPMSUpperBounds",
+ "ISO-STANDARD-9541-FONT-ATTRIBUTE-SET", "ISO8571-FTAM", "ISO9541-SN",
+ "Identifiers-and-Expressions", "InformationFramework",
+ "Interchange-Data-Elements", "Layout-Descriptors", "Link-Descriptors",
+ "Location-Expressions", "Logical-Descriptors", "MHSObjectIdentifiers",
+ "MHSProtocolObjectIdentifiers", "MSAbstractService",
+ "MSAccessProtocol", "MSGeneralAttributeTypes",
+ "MSGeneralAutoActionTypes", "MSMatchingRules", "MSObjectIdentifiers",
+ "MSUpperBounds", "MTAAbstractService", "MTSAbstractService",
+ "MTSAbstractService88", "MTSAccessProtocol", "MTSObjectIdentifiers",
+ "MTSUpperBounds", "Notation", "ObjectIdentifiers",
+ "OperationalBindingManagement", "PKCS7", "PKCS7BodyPartType",
+ "Protected-Part-Descriptors", "ProtocolObjectIdentifiers",
+ "Raster-Gr-Coding-Attributes", "Raster-Gr-Presentation-Attributes",
+ "Raster-Gr-Profile-Attributes", "Reliable-Transfer-APDU",
+ "Remote-Operations-Abstract-Syntaxes",
+ "Remote-Operations-Generic-ROS-PDUs",
+ "Remote-Operations-Information-Objects-extensions",
+ "Remote-Operations-Information-Objects",
+ "Remote-Operations-Realizations",
+ "Remote-Operations-Useful-Definitions", "SelectedAttributeTypes",
+ "SeseAPDUs", "SpkmGssTokens", "Style-Descriptors", "Subprofiles",
+ "Temporal-Relationships", "Text-Units", "UpperBounds",
+ "UsefulDefinitions", "Videotex-Coding-Attributes"].
+
+ticket7759(_Erule,_Config) ->
+ Encoded = encoded_msg(),
+ io:format("Testing ticket7759 ...~n",[]),
+ ?line {ok, ContentInfo} = asn1_wrapper:decode('PKCS7','ContentInfo',Encoded),
+ ?line {'ContentInfo',_Id,PKCS7_content} = ContentInfo,
+ ?line {ok,_} = asn1_wrapper:decode('PKCS7','SignedData',PKCS7_content),
+ ok.
+
+
+encoded_msg() ->
+ <<48,128,6,9,42,134,72,134,247,13,1,7,2,160,128,48,128,2,1,1,49,11,48,9,6,5,43,14,3,2,26,5,0,48,128,6,9,42,134,72,134,247,13,1,7,1,160,128,36,128,0,0,0,0,0,0, 49,130,1,192,48,130,1,188,2,1,1,48,50,48,38,49,17,48,15,6,3,85,4,3,12,8,65,100,109,105,110,67,65,49,49,17,48,15,6,3,85,4,10,12,8,69,82,73,67,83,83,79,78,2,8,15,151,245,186,21,23,240,96,48,9,6,5,43,14,3,2,26,5,0,160,129,229,48,17,6,10,96,134,72,1,134,248,69,1,9,2,49,3,19,1,51,48,17,6,10,96,134,72,1,134,248,69,1,9,3,49,3,19,1,51,48,24,6,9,42,134,72,134,247,13,1,9,3,49,11,6,9,42,134,72,134,247,13,1,7,1,48,28,6,9,42,134,72,134,247,13,1,9,5,49,15,23,13,48,56,49,50,49,48,48,57,53,52,50,51,90,48,28,6,10,96,134,72,1,134,248,69,1,9,7,49,14,19,12,49,53,50,56,49,52,50,52,48,57,53,53,48,32,6,10,96,134,72,1,134,248,69,1,9,5,49,18,4,16,165,115,177,71,78,88,239,113,78,56,98,98,18,202,217,235,48,32,6,10,96,134,72,1,134,248,69,1,9,6,49,18,4,16,227,174,230,251,43,153,252,65,11,93,231,83,34,18,55,46,48,35,6,9,42,134,72,134,247,13,1,9,4,49,22,4,20,218,57,163,238,94,107,75,13,50,85,191,239,149,96,24,144,175,216,7,9,48,13,6,9,42,134,72,134,247,13,1,1,1,5,0,4,129,128,106,233,116,125,140,51,133,173,63,41,54,138,214,211,89,215,169,125,98,77,16,222,216,240,211,79,125,111,87,186,73,63,253,204,107,102,177,63,174,197,224,212,231,172,149,246,33,68,223,67,102,93,64,152,152,5,216,102,247,134,36,197,150,236,57,77,56,138,95,71,204,31,23,149,241,213,78,172,165,249,100,187,12,45,19,57,67,120,54,63,15,239,41,217,127,61,254,60,201,104,68,3,135,214,206,93,253,255,192,94,56,107,68,210,57,61,41,249,47,156,130,244,52,12,163,216,236,69,0,0,0,0,0,0>>.
diff --git a/lib/asn1/test/test_bad_values.erl b/lib/asn1/test/test_bad_values.erl
new file mode 100644
index 0000000000..0190b6ee9a
--- /dev/null
+++ b/lib/asn1/test/test_bad_values.erl
@@ -0,0 +1,29 @@
+%%
+%% %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%
+%%
+%%
+-module(test_bad_values).
+
+-export([tests/1]).
+-include("test_server.hrl").
+
+tests(Config) ->
+ ?line DataDir = ?config(data_dir,Config),
+ ?line OutDir = ?config(priv_dir,Config),
+ ?line {error,_R} = asn1ct:compile(DataDir ++ "BadEnumValue1",[{outdir,OutDir}]),
+ ok.
diff --git a/lib/asn1/test/test_compile_options.erl b/lib/asn1/test/test_compile_options.erl
new file mode 100644
index 0000000000..a6e0caa0f1
--- /dev/null
+++ b/lib/asn1/test/test_compile_options.erl
@@ -0,0 +1,169 @@
+%%
+%% %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%
+%%
+%%
+
+-module(test_compile_options).
+
+-include("test_server.hrl").
+
+
+-export([wrong_path/1,comp/2,path/1,ticket_6143/1,noobj/1,
+ record_name_prefix/1]).
+
+%% OTP-5689
+wrong_path(Config) ->
+ Pid=spawn(?MODULE,comp,[self(),Config]),
+ receive
+ _Err ->
+ ok
+ after 10000 ->
+ exit(Pid,failure),
+ error
+ end.
+
+comp(Parent,Config) ->
+ DataDir = ?config(data_dir,Config),
+ OutDir = ?config(priv_dir,Config),
+ %%?line true = code:add_patha(?config(priv_dir,Config)),
+ io:format("DataDir: ~p~n",[DataDir]),
+ ?line Err=asn1ct:compile(DataDir++"NoImport",[{i,OutDir},{i,filename:join([DataDir,"subdir"])},{outdir,OutDir}]),
+ io:format("compiling process terminated with value: ~p~n",[Err]),
+ Parent!Err.
+
+%% OTP-5701
+
+path(Config) ->
+ DataDir = ?config(data_dir,Config),
+ OutDir = ?config(priv_dir,Config),
+ {ok,CWD} = file:get_cwd(),
+ ?line file:set_cwd(filename:join([DataDir,subdir])),
+
+ %%?line ok=asn1ct:compile(filename:join([DataDir,"../MyMerge.set.asn"]),[{inline,mymerge},{outdir,OutDir}]),
+ ?line ok=asn1ct:compile("../MyMerge.set.asn",[{inline,mymerge},{outdir,OutDir}]),
+
+ ?line ok=outfiles_check(OutDir),
+ ?line outfiles_remove(OutDir),
+
+ file:set_cwd(filename:join([DataDir,subdir,subsubdir])),
+ ?line ok = asn1ct:compile('../../MyMerge.set.asn',[{inline,mymerge},{i,'..'},{outdir,OutDir}]),
+
+ ?line ok=outfiles_check(OutDir,outfiles2()),
+ file:set_cwd(CWD),
+ ok.
+
+ticket_6143(Config) ->
+ DataDir = ?config(data_dir,Config),
+ OutDir = ?config(priv_dir,Config),
+ io:format("DataDir: ~p~n",[DataDir]),
+
+ ?line ok=asn1ct:compile(filename:join([DataDir,"AA1"]),[{i,DataDir},{outdir,OutDir}]),
+ ok.
+
+noobj(Config) ->
+ DataDir = ?config(data_dir,Config),
+ OutDir = ?config(priv_dir,Config),
+
+ code:purge('P-Record'),
+ file:delete(filename:join([OutDir,'P-Record.erl'])),
+ file:delete(filename:join([OutDir,'P-Record.beam'])),
+ ?line ok=asn1ct:compile(filename:join([DataDir,"P-Record"]),
+ [noobj,{outdir,OutDir}]),
+% ?line false = code:is_loaded('P-Record'),
+ ?line {ok,_} = file:read_file_info(filename:join([OutDir,
+ "P-Record.erl"])),
+ ?line {error,enoent} =
+ file:read_file_info(filename:join([OutDir,"P-Record.beam"])),
+ ?line {ok,_} = c:c(filename:join([OutDir,'P-Record']),
+ [{i,OutDir},{outdir,OutDir}]),
+ ?line {file,_} = code:is_loaded('P-Record'),
+
+ code:purge('P-Record'),
+ code:delete('P-Record'),
+ code:purge('p_record'),
+ code:delete('p_record'),
+ file:delete(filename:join([OutDir,'P-Record.erl'])),
+ file:delete(filename:join([OutDir,'P-Record.beam'])),
+ file:delete(filename:join([OutDir,'p_record.erl'])),
+ file:delete(filename:join([OutDir,'p_record.beam'])),
+ ?line ok=asn1ct:compile(filename:join([DataDir,"p_record.set.asn"]),[asn1config,ber_bin,optimize,noobj,{outdir,OutDir}]),
+%% ?line false = code:is_loaded('P-Record'),
+%% ?line false = code:is_loaded('p_record'),
+ ?line {error,enoent} =
+ file:read_file_info(filename:join([OutDir,"P-Record.beam"])),
+ ?line {error,enoent} =
+ file:read_file_info(filename:join([OutDir,"P-Record.erl"])),
+ ?line {error,enoent} =
+ file:read_file_info(filename:join([OutDir,"p_record.beam"])),
+ io:format("read_file_info: p_record.erl~n",[]),
+ ?line {ok,_} =
+ file:read_file_info(filename:join([OutDir,"p_record.erl"])),
+ io:format("c:c: p_record.erl~n",[]),
+ ?line {ok,_} = c:c(filename:join([OutDir,'p_record']),
+ [{i,OutDir},{outdir,OutDir}]),
+ io:format("code:is_loaded: p_record.erl~n",[]),
+ ?line {file,_} = code:is_loaded('p_record'),
+ io:format("file:delete: p_record.erl~n",[]),
+ file:delete(filename:join([OutDir,'p_record.erl'])),
+ file:delete(filename:join([OutDir,'p_record.beam'])).
+
+outfiles_check(OutDir) ->
+ outfiles_check(OutDir,outfiles1()).
+
+
+outfiles_check(_OutDir,[])->
+ ok;
+outfiles_check(OutDir,[H|T]) ->
+ io:format("File: ~p~n",[filename:join([OutDir,H])]),
+ ?line {ok,_}=file:read_file_info(filename:join([OutDir,H])),
+ outfiles_check(OutDir,T).
+
+outfiles1() ->
+ ["mymerge.erl","mymerge.beam","MyMerge.asn1db","MyMerge.beam",
+ "MyMerge.erl","MyMerge.hrl"].
+outfiles2() ->
+ ["MyMerge.beam","mymerge.erl","MyMerge.asn1db","MyMerge.erl",
+ "mymerge.beam"].
+
+outfiles_remove(OutDir) ->
+ lists:foreach(fun(F)-> file:delete(filename:join([OutDir,F])) end,
+ outfiles1()).
+
+record_name_prefix(Config) ->
+ DataDir = ?config(data_dir,Config),
+ OutDir = ?config(priv_dir,Config),
+ ok = b_SeqIn(DataDir,OutDir),
+ ok = a_SeqIn(DataDir,OutDir).
+
+b_SeqIn(DataDir,OutDir) ->
+ asn1ct:compile(filename:join([DataDir,'Seq']),
+ [{record_name_prefix,"b_"},{outdir,OutDir}]),
+ io:format("FileName: ~p~nOutDir:~p~n",
+ [filename:join([DataDir,'b_SeqIn']),OutDir]),
+ ?line {ok,_} = compile:file(filename:join([DataDir,'b_SeqIn']),
+ [{i,OutDir}]),
+ ?line 'b_SeqIn' = b_SeqIn:record_name(),
+ ok.
+
+a_SeqIn(DataDir,OutDir) ->
+ asn1ct:compile(filename:join([DataDir,'Seq']),
+ [{record_name_prefix,"a_"},{outdir,OutDir}]),
+ ?line {ok,_} = compile:file(filename:join([DataDir,'a_SeqIn']),
+ [{i,OutDir}]),
+ ?line 'a_SeqIn' = a_SeqIn:record_name(),
+ ok.
diff --git a/lib/asn1/test/test_driver_load.erl b/lib/asn1/test/test_driver_load.erl
new file mode 100644
index 0000000000..37a7e36a45
--- /dev/null
+++ b/lib/asn1/test/test_driver_load.erl
@@ -0,0 +1,58 @@
+%%
+%% %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(test_driver_load).
+
+-export([compile/2,test/2,encode/0]).
+
+-include("test_server.hrl").
+
+
+test(per_bin,0) ->
+ ok;
+test(per_bin,N) ->
+ spawn(?MODULE,encode,[]),
+ test(per_bin,N-1);
+test(_,_) ->
+ ok.
+
+compile(Config,per_bin) ->
+ ?line DataDir = ?config(data_dir,Config),
+ ?line OutDir = ?config(priv_dir,Config),
+ ?line true = code:add_patha(?config(priv_dir,Config)),
+
+ ?line ok = asn1ct:compile(DataDir ++ "P-Record",
+ [per_bin,optimize,{outdir,OutDir}]);
+compile(_,Erule) ->
+ {skip,lists:concat(["not implemented for version: ",Erule])}.
+
+
+encode() ->
+ ?line Msg = msg(),
+ ?line {ok,_}=asn1_wrapper:encode('P-Record','PersonnelRecord',Msg),
+ ok.
+
+msg() ->
+ {'PersonnelRecord',{'Name',"John","P","Smith"},
+ "Director",
+ 51,
+ "19710917",
+ {'Name',"Mary","T","Smith"},
+ [{'ChildInformation',{'Name',"Ralph","T","Smith"},"19571111"},{'ChildInformation',{'Name',"Susan","B","Jones"},"19590717"}]}.
+
diff --git a/lib/asn1/test/test_inline.erl b/lib/asn1/test/test_inline.erl
new file mode 100644
index 0000000000..aac003baf6
--- /dev/null
+++ b/lib/asn1/test/test_inline.erl
@@ -0,0 +1,285 @@
+%%
+%% %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(test_inline).
+
+-export([compile/3,main/1,inline1/3,performance/1,performance2/0]).
+-export([mvrasn_inlined_encdec/2,mvrasn_encdec/2,
+ mi_encdec/2,m_encdec/2]).
+
+-include("test_server.hrl").
+-define(times, 5000).
+-define(times2, 50000).
+
+compile(Config,_Rules,Opt) ->
+ ?line DataDir = ?config(data_dir,Config),
+ ?line OutDir = ?config(priv_dir,Config),
+ ?line true = code:add_patha(?config(priv_dir,Config)),
+ ?line true = code:add_patha(DataDir),
+
+ ?line ok=asn1ct:compile(DataDir++"Mvrasn.set.asn",[{inline,mvrasn_inlined},{outdir,OutDir}]++Opt),
+ ?line ok=asn1ct:compile(DataDir++"Mvrasn-11-6.asn",[{outdir,OutDir}]++Opt),
+
+ ?line ok=asn1ct:compile(DataDir++"Mod.set.asn",[{inline,m},{outdir,OutDir}]++Opt),
+ ?line ok=remove_inlined_files(OutDir,[filename:join([OutDir,X])||X<-["m.erl","m.beam"]]),
+ ?line ok=asn1ct:compile(DataDir++"Mod.set.asn",[inline,{outdir,OutDir}]++Opt),
+ ?line ok=remove_inlined_files(OutDir,[]).
+
+inline1(Config,Rule,Opt) ->
+ ?line DataDir = ?config(data_dir,Config),
+ ?line OutDir = ?config(priv_dir,Config),
+
+ ?line ok=asn1ct:compile(DataDir++"P-Record",
+ [{inline,'inlined_P_Record'},
+ {outdir,OutDir}]++Opt),
+ ?line test_inline1(),
+
+ ?line ok=remove_inlined_files2(OutDir,ber_bin_v2),
+
+ case Rule of
+ ber_bin_v2 ->
+ ?line ok=asn1ct:compile(DataDir++"P-Record",
+ [inline,asn1config,ber_bin,optimize,
+ {outdir,OutDir}]++Opt),
+ ?line test_inline2(Rule,'P-Record'),
+ ?line remove_inlined_files3(OutDir,Rule),
+ io:format("compiling ~p~nwith ~p~n",
+ [DataDir ++ "p_record.set.asn",
+ [inline,asn1config,ber_bin,optimize,{outdir,OutDir}]++Opt]),
+ ?line ok = asn1ct:compile(DataDir ++ "p_record.set.asn",
+ [inline,asn1config,ber_bin,optimize,
+ {outdir,OutDir}]++Opt),
+ ?line test_inline2(Rule,'p_record'),
+ ?line remove_inlined_files4(OutDir,Rule);
+ _ ->
+ ok
+ end.
+
+main(_Erule) ->
+ ?line Val = val(),
+ ?line {ok,Bytes}=asn1_wrapper:encode(mvrasn_inlined,'InsertSubscriberDataArg',Val),
+ ?line {ok,_Val2}=asn1_wrapper:decode(mvrasn_inlined,'InsertSubscriberDataArg',Bytes).
+
+test_inline1() ->
+ PRecMsg = {'PersonnelRecord',{'Name',"Sven","S","Svensson"},
+ "manager",123,"20000202",{'Name',"Inga","K","Svensson"},
+ asn1_DEFAULT},
+ ?line {ok,Bytes}=asn1_wrapper:encode('inlined_P_Record','PersonnelRecord',
+ PRecMsg),
+ ?line {ok,_}=asn1_wrapper:decode('inlined_P_Record',
+ 'PersonnelRecord',Bytes).
+
+test_inline2(ber_bin_v2,Mod) ->
+ PRecMsg = {'PersonnelRecord',{'Name',"Sven","S","Svensson"},
+ "manager",123,"20000202",{'Name',"Inga","K","Svensson"},
+ asn1_DEFAULT},
+ ?line {ok,Bytes} = Mod:encode('PersonnelRecord',PRecMsg),
+ ?line {ok,_} = Mod:sel_dec(list_to_binary(Bytes));
+test_inline2(_,_) ->
+ ok.
+
+val() ->
+ ?line {ok,Val} = asn1ct:value('Mvrasn-11-6','InsertSubscriberDataArg'),
+ Val.
+
+performance(Config) ->
+ ?line true = code:add_patha(?config(priv_dir,Config)),
+ ?line true = code:add_patha(?config(data_dir,Config)),
+ ?line Val = val(),
+ %% warm up
+ timer:tc(?MODULE,mvrasn_inlined_encdec,[2,Val]),
+ %% performance test
+ ?line {Time1,ok}=timer:tc(?MODULE,mvrasn_inlined_encdec,[?times,Val]),
+ %% warm up
+ timer:tc(?MODULE,mvrasn_encdec,[2,Val]),
+ %% performance test
+ ?line {Time2,ok}=timer:tc(?MODULE,mvrasn_encdec,[?times,Val]),
+
+ ?line Comment = "inlined_code: "++
+ integer_to_list(round(Time1/?times))++
+ " micro,<br>original_code: "++
+ integer_to_list(round(Time2/?times))++
+% " micro,~ninlined_code[inline]: "++
+% integer_to_list(round(Time3/?times))++
+ " micro",
+ {comment,Comment}.
+
+
+mvrasn_inlined_encdec(0,_) ->
+ ok;
+mvrasn_inlined_encdec(N,V) ->
+ ?line {ok,B}=mvrasn_inlined:encode('InsertSubscriberDataArg',V),
+ ?line {ok,_R}=mvrasn_inlined:decode('InsertSubscriberDataArg',B),
+ mvrasn_inlined_encdec(N-1,V).
+
+mvrasn_encdec(0,_) ->
+ ok;
+mvrasn_encdec(N,V) ->
+ ?line {ok,B}='Mvrasn-11-6':encode('InsertSubscriberDataArg',V),
+ ?line {ok,_R}='Mvrasn-11-6':decode('InsertSubscriberDataArg',B),
+ mvrasn_encdec(N-1,V).
+
+%% mvrasn_inlined_i_encdec(0,_) ->
+%% ok;
+%% mvrasn_inlined_i_encdec(N,V) ->
+%% {ok,B}=mvrasn_inlined_i:encode('InsertSubscriberDataArg',V),
+%% {ok,_R}=mvrasn_inlined_i:decode('InsertSubscriberDataArg',B),
+%% mvrasn_inlined_i_encdec(N-1,V).
+
+performance2() ->
+ Val = mval(),
+ %% warm up
+ timer:tc(?MODULE,mi_encdec,[?times,Val]),
+ %% performance test
+ {Time1,_R1}=timer:tc(?MODULE,mi_encdec,[?times2,Val]),
+ %% warm up
+ timer:tc(?MODULE,m_encdec,[?times,Val]),
+ %% performance test
+ {Time2,_R2}=timer:tc(?MODULE,m_encdec,[?times2,Val]),
+ ?line Comment = "inlined_code: "++
+ integer_to_list(round(Time1/?times2))++
+ " micro,<br>original_code: "++
+ integer_to_list(round(Time2/?times2))++
+ " micro<br>"++
+ "The inlined code was "++
+ integer_to_list(round(((Time2-Time1)/Time2)*100))++
+ " % faster than the original code.",
+ {comment,Comment}.
+
+mi_encdec(0,_) ->
+ ok;
+mi_encdec(N,Val) ->
+ {ok,B}=m:encode('L',Val),
+ {ok,_R}=m:decode('L',B),
+% io:format("a"),
+ mi_encdec(N-1,Val).
+
+m_encdec(0,_) ->
+ ok;
+m_encdec(N,Val) ->
+ {ok,B}='Mod1':encode('L',Val),
+ {ok,_R}='Mod1':decode('L',B),
+ m_encdec(N-1,Val).
+
+
+-record('L', {country, region, name}).
+-record('OtherName', {locationName, thingName}).
+-record('FamilyName', {prefix, secondname}).
+-record('Lang', {l}).
+-record('Inhabitant', {name, country}).
+-record('Country', {name, language}).
+-record('PersonName', {name1, name2}).
+-record('LocName', {region, name}).
+-record('Reg', {name, inhabitants}).
+
+
+mval() ->
+ 'L'().
+'L'() ->
+ #'L'{
+ country='Co'(),
+ region='Reg'(),
+ name='Name'(othername)}.
+'Co'() ->
+ 'Country'().
+'Country'()->
+ #'Country'{name='Name'(othername),
+ language='Lang'()}.
+'Lang'()->
+ #'Lang'{l="englsh"}.
+'Reg'() ->
+ #'Reg'{
+ name='Name'(othername),
+ inhabitants='Inhabitants'()}.
+'Inhabitants'()->
+ lists:duplicate(5,'Inhabitant'()).
+'Inhabitant'()->
+ #'Inhabitant'{name='Name'(person),
+ country='Country'()}.
+'Name'(person) ->
+ {person,'PersonName'()};
+'Name'(othername) ->
+ {othername,'OtherName'()}.
+'PersonName'()->
+ #'PersonName'{name1='FirstName'(firstname),
+ name2='FamilyName'()}.
+'OtherName'()->
+ #'OtherName'{locationName='LocName'(),
+ thingName='ThingName'()}.
+'FirstName'(firstname)->
+ {firstname,"Henry"};
+'FirstName'(nickname) ->
+ {nickname,"nick"}.
+'FamilyName'() ->
+ #'FamilyName'{prefix=none,
+ secondname="Lloyd"}.
+'ThingName'()->
+ "Enkoping".
+'LocName'()->
+ #'LocName'{
+ region=svealand,
+ name="Enkoping"}.
+
+remove_inlined_files(Dir,Files) ->
+ ModList=[filename:join([Dir,X])||X<-["Mod"]],
+ FileList=Files++ mods2files(ModList,".asn1db")++
+ mods2files(ModList,".beam")++
+ mods2files(ModList,".erl")++mods2files(ModList,".hrl"),
+ lists:foreach(fun(X) ->
+ io:format("X: ~p~n",[X]),
+ ?line ok=file:delete(X)
+ end,FileList),
+ ok.
+mods2files(ModList,Extension) ->
+ [X++Extension||X<-ModList].
+
+
+remove_inlined_files2(Dir,Rule) ->
+ ?line ok=remove_inlined_files3(Dir,Rule),
+ TargetErl=filename:join([Dir,"inlined_P_Record.erl"]),
+ TargetBeam=filename:join([Dir,"inlined_P_Record.beam"]),
+ lists:foreach(fun(X) ->
+ ?line ok=file:delete(X)
+ end,[TargetErl,TargetBeam]),
+ ok.
+remove_inlined_files3(Dir,ber_bin_v2) ->
+ Erl=filename:join([Dir,"P-Record.erl"]),
+ Beam=filename:join([Dir,"P-Record.beam"]),
+ Asn1DB=filename:join([Dir,"P-Record.asn1db"]),
+ Hrl=filename:join([Dir,"P-Record.hrl"]),
+ lists:foreach(fun(X) ->
+ ?line ok=file:delete(X)
+ end,[Erl,Beam,Asn1DB,Hrl]),
+ ok;
+remove_inlined_files3(_,_) ->
+ ok.
+
+remove_inlined_files4(Dir,ber_bin_v2) ->
+ Erl=filename:join([Dir,"p_record.erl"]),
+ Beam=filename:join([Dir,"p_record.beam"]),
+ Asn1DB=filename:join([Dir,"p_record.asn1db"]),
+ Hrl=filename:join([Dir,"p_record.hrl"]),
+ ErlBak=filename:join([Dir,"p_record.erl.bak"]),
+ file:delete(ErlBak),
+ lists:foreach(fun(X) ->
+ ?line ok=file:delete(X)
+ end,[Erl,Beam,Asn1DB,Hrl]),
+ ok;
+remove_inlined_files4(_,_) ->
+ ok.
diff --git a/lib/asn1/test/test_modified_x420.erl b/lib/asn1/test/test_modified_x420.erl
new file mode 100644
index 0000000000..93fcd73eaf
--- /dev/null
+++ b/lib/asn1/test/test_modified_x420.erl
@@ -0,0 +1,67 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 2008-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(test_modified_x420).
+
+%-compile(export_all).
+-export([compile/1, test_io/1]).
+
+-include("test_server.hrl").
+
+compile(Config) ->
+ ?line DataDir = ?config(data_dir,Config),
+ ?line OutDir = ?config(priv_dir,Config),
+
+ ok = asn1ct:compile(filename:join([DataDir,modified_x420,"PKCS7"]),[der,{outdir,OutDir}]),
+ ok = asn1ct:compile(filename:join([DataDir,modified_x420,"InformationFramework"]),[der,{outdir,OutDir}]),
+ ok = asn1ct:compile(filename:join([DataDir,modified_x420,"AuthenticationFramework"]),[der,{outdir,OutDir}]).
+
+test_io(Config) ->
+ io:format("~p~n~n", [catch test(Config)]).
+
+test(Config) ->
+ ?line DataDir = ?config(data_dir,Config),
+% ?line OutDir = ?config(priv_dir,Config),
+
+ ?line Der = read_pem(filename:join([DataDir,modified_x420,"p7_signed_data.pem"])),
+ ?line {ok, {_,_,SignedData}} = 'PKCS7':decode('ContentInfo', Der),
+ ?line {ok,_} = 'PKCS7':decode('SignedData', SignedData).
+
+read_pem(File) ->
+ ?line {ok, Bin} = file:read_file(File),
+ ?line ssl_base64:join_decode(lists:flatten(extract_base64(Bin))).
+
+
+
+extract_base64(Binary) ->
+ extract_base64_lines(string:tokens(binary_to_list(Binary), "\n")).
+
+extract_base64_lines(["-----BEGIN"++_ | Lines]) ->
+ take_base64_lines(Lines, _Acc = []);
+extract_base64_lines([_|Lines]) ->
+ extract_base64_lines(Lines);
+extract_base64_lines([]) ->
+ [].
+
+take_base64_lines(["-----END"++_|_], Acc) ->
+ lists:reverse(Acc);
+take_base64_lines([L|Lines], Acc) ->
+ take_base64_lines(Lines, [L|Acc]);
+take_base64_lines([], Acc) ->
+ lists:reverse(Acc).
diff --git a/lib/asn1/test/test_partial_incomplete_decode.erl b/lib/asn1/test/test_partial_incomplete_decode.erl
new file mode 100644
index 0000000000..9fd078e952
--- /dev/null
+++ b/lib/asn1/test/test_partial_incomplete_decode.erl
@@ -0,0 +1,253 @@
+%%
+%% %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(test_partial_incomplete_decode).
+
+-export([compile/3,test/2]).
+
+-include("test_server.hrl").
+
+
+
+compile(Config,Rule,Opt) when Rule == ber_bin_v2 ->
+
+ ?line DataDir = ?config(data_dir,Config),
+ ?line OutDir = ?config(priv_dir,Config),
+ ?line true = code:add_patha(?config(priv_dir,Config)),
+
+ ?line ok = asn1ct:compile(DataDir ++ "PartialDecSeq.asn",
+ [Rule,{outdir,OutDir},{i,DataDir},
+ asn1config]++Opt),
+ ?line ok = asn1ct:compile(DataDir ++ "PartialDecSeq2.asn",
+ [Rule,{outdir,OutDir},{i,DataDir},
+ asn1config]++Opt),
+ ?line ok = asn1ct:compile(DataDir ++ "PartialDecSeq3.asn",
+ [Rule,{outdir,OutDir},{i,DataDir},
+ asn1config]++Opt),
+ ?line ok = asn1ct:compile(DataDir ++ "PartialDecMyHTTP.asn",
+ [Rule,{outdir,OutDir},{i,DataDir},
+ asn1config]++Opt),
+ ?line ok = asn1ct:compile(DataDir ++ "MEDIA-GATEWAY-CONTROL.asn",
+ [Rule,{outdir,OutDir},{i,DataDir},
+ asn1config]++Opt),
+ ?line ok = asn1ct:compile(DataDir ++ "P-Record",
+ [Rule,{outdir,OutDir},{i,DataDir},
+ asn1config]++Opt);
+compile(_,Rule,_) ->
+ {skip,lists:concat(["not implemented yet for version: ",Rule])}.
+
+test(ber_bin_v2,Config) ->
+ FMsg = msg('F'),
+ ?line {ok,Bytes} = asn1_wrapper:encode('PartialDecSeq','F',FMsg),
+ ?line {ok,_} = asn1_wrapper:decode('PartialDecSeq','F',Bytes),
+ ?line {ok,IncFMsg} =
+ 'PartialDecSeq':decode_F_fb_incomplete(list_to_binary(Bytes)),
+ ?line decode_parts('F',IncFMsg),
+
+ DMsg = msg('D'),
+ ?line {ok,Bytes2} = asn1_wrapper:encode('PartialDecSeq','D',DMsg),
+ ?line {ok,_} = asn1_wrapper:decode('PartialDecSeq','D',Bytes2),
+ ?line {ok,IncDMsg} =
+ 'PartialDecSeq':decode_D_incomplete(list_to_binary(Bytes2)),
+ ?line decode_parts('D',IncDMsg),
+
+ ?line {ok,IncF2Msg} =
+ 'PartialDecSeq':decode_F_fb_exclusive2(list_to_binary(Bytes)),
+ ?line decode_parts('F2',IncF2Msg),
+
+ F3Msg = msg('F3'),
+ ?line {ok,BytesF3} = asn1_wrapper:encode('PartialDecSeq','F',F3Msg),
+ ?line {ok,_} = asn1_wrapper:decode('PartialDecSeq','F',BytesF3),
+ ?line {ok,IncF3Msg} =
+ 'PartialDecSeq':decode_F_fb_exclusive3(list_to_binary(BytesF3)),
+ ?line decode_parts('F3',IncF3Msg),
+
+
+ AMsg =msg('A'),
+ ?line {ok,Bytes3} = asn1_wrapper:encode('PartialDecSeq2','A',AMsg),
+ ?line {ok,_} = asn1_wrapper:decode('PartialDecSeq2','A',Bytes3),
+ ?line {ok,IncFMsg3} =
+ 'PartialDecSeq2':decode_A_c_b_incomplete(list_to_binary(Bytes3)),
+ ?line decode_parts('A',IncFMsg3),
+
+ MyHTTPMsg = msg('GetRequest'),
+ ?line {ok,Bytes4} = asn1_wrapper:encode('PartialDecMyHTTP',
+ 'GetRequest',MyHTTPMsg),
+ ?line {ok,_} = asn1_wrapper:decode('PartialDecMyHTTP','GetRequest',
+ Bytes4),
+ ?line {ok,IncFMsg4} =
+ 'PartialDecMyHTTP':decode_GetRequest_incomplete(list_to_binary(Bytes4)),
+ ?line decode_parts('GetRequest',IncFMsg4),
+
+ MsgS1_1 = msg('S1_1'),
+ ?line {ok,Bytes5} = asn1_wrapper:encode('PartialDecSeq3','S1',MsgS1_1),
+ ?line {ok,_} = asn1_wrapper:decode('PartialDecSeq3','S1',Bytes5),
+ ?line {ok,IncFMsg5} =
+ 'PartialDecSeq3':decode_S1_incomplete(list_to_binary(Bytes5)),
+ ?line decode_parts('S1_1',IncFMsg5),
+
+ MsgS1_2 = msg('S1_2'),
+ ?line {ok,Bytes6} = asn1_wrapper:encode('PartialDecSeq3','S1',MsgS1_2),
+ ?line {ok,IncFMsg6} =
+ 'PartialDecSeq3':decode_S1_incomplete(list_to_binary(Bytes6)),
+ ?line ok = decode_parts('S1_2',IncFMsg6),
+
+ %% test of MEDIA-GATEWAY-CONTROL
+ test_megaco(Config),
+ ok;
+test(Erule,_) ->
+ {skip,lists:concat(["not implemented yet for version: ",Erule])}.
+
+test_megaco(Config) ->
+ ?line DataDir = ?config(data_dir,Config),
+ Mod='MEDIA-GATEWAY-CONTROL',
+ ?line {ok,FilenameList} = file:list_dir(filename:join([DataDir,
+ megacomessages])),
+ %% remove any junk files that may be in the megacomessage directory
+ Pred = fun(X) ->
+ case lists:reverse(X) of
+ [$l,$a,$v,$.|_R] ->true;
+ _ -> false
+ end
+ end,
+ MegacoMsgFilenameList = lists:filter(Pred,FilenameList),
+ Fun = fun(F) ->
+ M = read_msg(filename:join([DataDir,megacomessages,F])),
+ ?line {ok,B} = asn1_wrapper:encode(Mod,element(1,M),M),
+ ?line exclusive_decode(list_to_binary(B),F)
+ end,
+ ?line lists:foreach(Fun,MegacoMsgFilenameList),
+ ok.
+
+exclusive_decode(Bin,F) ->
+ Mod='MEDIA-GATEWAY-CONTROL',
+ io:format("Encoding message: ~p~n",[F]),
+ ?line {ok,{_,_,{_,_VsnNo,{MsgMidKey,MsgMid},{MsgMBodyKey,MsgMBody}}}}=
+ Mod:decode_MegacoMessage_exclusive(Bin),
+ ?line {ok,_} = Mod:decode_part(MsgMidKey,MsgMid),
+ ?line {ok,_} = Mod:decode_part(MsgMBodyKey,MsgMBody),
+ ok.
+
+
+read_msg(File) ->
+ case file:read_file(File) of
+ {ok,Bin} ->
+ binary_to_term(Bin);
+ _ ->
+ io:format("couldn't read file ~p~n",[File])
+ end.
+
+decode_parts('F',PartDecMsg) ->
+ ?line {fb,{'E',35,{NameE_b,ListBinE_b},false,{NameE_d,BinE_d}}} = PartDecMsg,
+ ?line {ok,[{'D',3,true}|_]} = 'PartialDecSeq':decode_part(NameE_b,ListBinE_b),
+ ?line {ok,{'D',3,true}} = 'PartialDecSeq':decode_part(NameE_b,
+ hd(ListBinE_b)),
+ ?line {ok,{da,[{'A',16,{'D',17,true}}]}} =
+ 'PartialDecSeq':decode_part(NameE_d,BinE_d),
+ ok;
+decode_parts('F2',PartDecMsg) ->
+ ?line {fb,{'E',35,{E_bkey,E_b},false,{da,{E_d_akey,E_d_a}}}} = PartDecMsg,
+ ?line {ok,[{'D',3,true},{'D',4,false},{'D',5,true},{'D',6,true},{'D',7,false},{'D',8,true},{'D',9,true},{'D',10,false},{'D',11,true},{'D',12,true},{'D',13,false},{'D',14,true}]} = 'PartialDecSeq':decode_part(E_bkey,E_b),
+ ?line {ok,[{'A',16,{'D',17,true}}]} = 'PartialDecSeq':decode_part(E_d_akey,E_d_a);
+
+decode_parts('F3',PartDecMsg) ->
+ ?line {fb,{'E',10,{E_bkey,E_b},false,{dc,{'E_d_dc',13,true,{E_d_dc_dcckey,E_d_dc_dcc}}}}} = PartDecMsg,
+ ?line {ok,[{'D',11,true},{'D',12,false}]} = 'PartialDecSeq':decode_part(E_bkey,E_b),
+ ?line {ok,{'E_d_dc_dcc',14,15}} = 'PartialDecSeq':decode_part(E_d_dc_dcckey,E_d_dc_dcc);
+
+
+decode_parts('D',PartDecMsg) ->
+ ?line {'D',{NameD_a,BinD_a},true} = PartDecMsg,
+ ?line {ok,123} = 'PartialDecSeq':decode_part(NameD_a,BinD_a),
+ ok;
+decode_parts('A',PartDecMsg) ->
+ ?line {'A',12,{c,{'S',true,false}},{b,{NameA_c_b,BinA_c_b}}} = PartDecMsg,
+ ?line {ok,{'A_c_b',false,false}} =
+ 'PartialDecSeq2':decode_part(NameA_c_b,BinA_c_b),
+ ok;
+decode_parts('GetRequest',PartDecMsg) ->
+ ?line {'GetRequest',true,false,
+ {'AcceptTypes',[html,'plain-text',gif,jpeg],
+ {NameAcceptTypes_others,ListBinAcceptTypes_others}},
+ "IamfineThankYOu"} = PartDecMsg,
+ ?line {ok,["hell","othe","reho","peyo","uare","fine"]} =
+ 'PartialDecMyHTTP':decode_part(NameAcceptTypes_others,
+ ListBinAcceptTypes_others),
+ ?line {ok,"hell"} =
+ 'PartialDecMyHTTP':decode_part(NameAcceptTypes_others,
+ hd(ListBinAcceptTypes_others)),
+ ok;
+decode_parts('S1_1',PartDecMsg) ->
+ ?line {'S1',14,{'S2',false,12,{NameS2c,BinS2c}},
+ {_,{NameS1c_a,ListBinS1c_a}},{NameS1d,BinS1d}} = PartDecMsg,
+ ?line {ok,[{'S3',10,"PrintableString","OCTETSTRING",
+ [one,two,three,four]}|_Rest1]} =
+ 'PartialDecSeq3':decode_part(NameS2c,BinS2c),
+ ?line {ok,[{'S3',10,"PrintableString","OCTETSTRING",
+ [one,two,three,four]}|_Rest2]} =
+ 'PartialDecSeq3':decode_part(NameS1c_a,ListBinS1c_a),
+ ?line {ok,{'S3',10,"PrintableString","OCTETSTRING",
+ [one,two,three,four]}} =
+ 'PartialDecSeq3':decode_part(NameS1c_a,hd(ListBinS1c_a)),
+ ?line {ok,[{'Name',"Hans","HCA","Andersen"}|_Rest3]} =
+ 'PartialDecSeq3':decode_part(NameS1d,BinS1d),
+ ok;
+decode_parts('S1_2',PartDecMsg) ->
+ ?line {'S1',14,{'S2',false,12,_S2c},S1c_b,{NameS1d,BinS1d}} = PartDecMsg,
+ ?line {b,{'C1_b',11,true,
+ {'S4',{'Name',"Hans","HCA","Andersen"},"MSc"}}}=S1c_b,
+ ?line {ok,[{'Name',"Hans","HCA","Andersen"}|_Rest3]} =
+ 'PartialDecSeq3':decode_part(NameS1d,BinS1d),
+ ok.
+
+
+
+msg('F') ->
+ {'F',{fb,{'E',35,[{'D',3,true},{'D',4,false},{'D',5,true},{'D',6,true},{'D',7,false},{'D',8,true},{'D',9,true},{'D',10,false},{'D',11,true},{'D',12,true},{'D',13,false},{'D',14,true}],false,{da,[{'A',16,{'D',17,true}}]}}}};
+
+msg('F3') ->
+ {fb,{'E',10,[{'D',11,true},{'D',12,false}],false,{dc,{'E_d_dc',13,true,{'E_d_dc_dcc',14,15}}}}};
+
+msg('D') ->
+ {'D',123,true};
+
+msg('A') ->
+ {'A',12,{c,{'S',true,false}},{b,{'A_c_b',false,false}}};
+
+msg('GetRequest') ->
+ {'GetRequest',true,false,{'AcceptTypes',[1,1,1,1],["hell","othe","reho","peyo","uare","fine"]},"IamfineThankYOu"};
+
+msg('S1_1') ->
+ {'S1',14,msg('S2'),msg('C1_a'),msg('SO1')};
+msg('S1_2') ->
+ {'S1',14,msg('S2'),msg('C1_b'),msg('SO1')};
+msg('S2') ->
+ {'S2',false,12,[msg('S3'),msg('S3'),msg('S3')]};
+msg('C1_a') ->
+ {a,[msg('S3'),msg('S3'),msg('S3')]};
+msg('C1_b') ->
+ {b,{'C1_b',11,true,msg('S4')}};
+msg('S3') ->
+ {'S3',10,"PrintableString","OCTETSTRING",[1,1,1,1]};
+msg('S4') ->
+ {'S4',msg('Name'),"MSc"};
+msg('SO1') ->
+ [msg('Name'),msg('Name'),msg('Name')];
+msg('Name') ->
+ {'Name',"Hans","HCA","Andersen"}.
diff --git a/lib/asn1/test/test_selective_decode.erl b/lib/asn1/test/test_selective_decode.erl
new file mode 100644
index 0000000000..94d3d5f34a
--- /dev/null
+++ b/lib/asn1/test/test_selective_decode.erl
@@ -0,0 +1,65 @@
+%%
+%% %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(test_selective_decode).
+
+-export([test/2]).
+
+-include("test_server.hrl").
+
+
+test(ber_bin_v2,_Config) ->
+ FMsg = msg('F'),
+ ?line {ok,Bytes} = asn1_wrapper:encode('PartialDecSeq','F',FMsg),
+ ?line {ok,3} =
+ 'PartialDecSeq':selected_decode_F1(list_to_binary(Bytes)),
+ ?line {ok,[{'D',3,true},{'D',4,false},{'D',5,true},{'D',6,true},{'D',7,false},{'D',8,true},{'D',9,true},{'D',10,false},{'D',11,true},{'D',12,true},{'D',13,false},{'D',14,true}]} = 'PartialDecSeq':selected_decode_F2(list_to_binary(Bytes)),
+ ?line {ok,{'D',3,true}} = 'PartialDecSeq':selected_decode_F3(list_to_binary(Bytes)),
+
+ ?line {ok,17} = 'PartialDecSeq':selected_decode_F4(list_to_binary(Bytes)),
+
+ EMsg = msg('E'),
+ ?line {ok,Bytes2} = asn1_wrapper:encode('PartialDecSeq','E',EMsg),
+ ?line {ok,14} = 'PartialDecSeq':selected_decode_E1(list_to_binary(Bytes2)),
+ MGCMsg = msg('M-G-C'),
+ ?line {ok,Bytes3} = asn1_wrapper:encode('MEDIA-GATEWAY-CONTROL',
+ 'MegacoMessage',MGCMsg),
+ ?line {ok,1} = 'MEDIA-GATEWAY-CONTROL':decode_MegacoMessage_selective(list_to_binary(Bytes3)),
+
+ PRecMsg = {'PersonnelRecord',{'Name',"Sven","S","Svensson"},
+ "manager",123,"20000202",{'Name',"Inga","K","Svensson"},
+ asn1_DEFAULT},
+ ?line {ok,Bytes4} = asn1_wrapper:encode('P-Record','PersonnelRecord',
+ PRecMsg),
+ ?line {ok,_} = 'P-Record':sel_dec(list_to_binary(Bytes4)),
+
+ ok;
+test(Erule,_) ->
+ {skip,lists:concat(["not implemented yet for version: ",Erule])}.
+
+
+
+msg('F') ->
+ {'F',{fb,{'E',35,[{'D',3,true},{'D',4,false},{'D',5,true},{'D',6,true},{'D',7,false},{'D',8,true},{'D',9,true},{'D',10,false},{'D',11,true},{'D',12,true},{'D',13,false},{'D',14,true}],false,{da,[{'A',16,{'D',17,true}}]}}}};
+
+msg('E') ->
+ {'E',10,[{'D',11,true},{'D',12,false}],false,{dc,{'E_d_dc',13,true,{'E_d_dc_dcc',14,15}}}};
+
+msg('M-G-C') ->
+ {'MegacoMessage',asn1_NOVALUE,{'Message',1,{ip4Address,{'IP4Address',[125,125,125,111],55555}},{transactions,[{transactionReply,{'TransactionReply',50007,asn1_NOVALUE,{actionReplies,[{'ActionReply',0,asn1_NOVALUE,asn1_NOVALUE,[{auditValueReply,{auditResult,{'AuditResult',{'TerminationID',[],[255,255,255]},[{mediaDescriptor,{'MediaDescriptor',asn1_NOVALUE,{multiStream,[{'StreamDescriptor',1,{'StreamParms',{'LocalControlDescriptor',sendRecv,asn1_NOVALUE,asn1_NOVALUE,[{'PropertyParm',[0,11,0,7],[[52,48]],asn1_NOVALUE}]},{'LocalRemoteDescriptor',[[{'PropertyParm',[0,0,176,1],[[48]],asn1_NOVALUE},{'PropertyParm',[0,0,176,8],[[73,78,32,73,80,52,32,49,50,53,46,49,50,53,46,49,50,53,46,49,49,49]],asn1_NOVALUE},{'PropertyParm',[0,0,176,15],[[97,117,100,105,111,32,49,49,49,49,32,82,84,80,47,65,86,80,32,32,52]],asn1_NOVALUE},{'PropertyParm',[0,0,176,12],[[112,116,105,109,101,58,51,48]],asn1_NOVALUE}]]},{'LocalRemoteDescriptor',[[{'PropertyParm',[0,0,176,1],[[48]],asn1_NOVALUE},{'PropertyParm',[0,0,176,8],[[73,78,32,73,80,52,32,49,50,52,46,49,50,52,46,49,50,52,46,50,50,50]],asn1_NOVALUE},{'PropertyParm',[0,0,176,15],[[97,117,100,105,111,32,50,50,50,50,32,82,84,80,47,65,86,80,32,32,52]],asn1_NOVALUE},{'PropertyParm',[0,0,176,12],[[112,116,105,109,101,58,51,48]],asn1_NOVALUE}]]}}}]}}},{packagesDescriptor,[{'PackagesItem',[0,11],1},{'PackagesItem',[0,11],1}]},{statisticsDescriptor,[{'StatisticsParameter',[0,12,0,4],[[49,50,48,48]]},{'StatisticsParameter',[0,11,0,2],[[54,50,51,48,48]]},{'StatisticsParameter',[0,12,0,5],[[55,48,48]]},{'StatisticsParameter',[0,11,0,3],[[52,53,49,48,48]]},{'StatisticsParameter',[0,12,0,6],[[48,46,50]]},{'StatisticsParameter',[0,12,0,7],[[50,48]]},{'StatisticsParameter',[0,12,0,8],[[52,48]]}]}]}}}]}]}}}]}}}.
diff --git a/lib/asn1/test/test_special_decode_performance.erl b/lib/asn1/test/test_special_decode_performance.erl
new file mode 100644
index 0000000000..c451d65172
--- /dev/null
+++ b/lib/asn1/test/test_special_decode_performance.erl
@@ -0,0 +1,165 @@
+%%
+%% %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(test_special_decode_performance).
+
+-export([compile/2,go/1,loop2/4,loop1/5]).
+
+-include("test_server.hrl").
+
+
+compile(Config,Rule) when Rule==ber_bin_v2 ->
+ ?line DataDir = ?config(data_dir,Config),
+ ?line OutDir = ?config(priv_dir,Config),
+ ?line true = code:add_patha(?config(priv_dir,Config)),
+
+ ?line asn1ct:compile(DataDir++"MEDIA-GATEWAY-CONTROL",
+ [ber_bin,optimize,asn1config,{outdir,OutDir},
+ {i,DataDir}]),
+ ?line asn1ct:compile(DataDir++"PartialDecSeq",
+ [ber_bin,optimize,asn1config,{outdir,OutDir},
+ {i,DataDir}]);
+compile(_,Rule) ->
+ {skip,lists:concat(["not implemented yet for version: ",Rule])}.
+
+go(all) ->
+ {Time_S_s,Time_S_e,Time_S_c}=go(10000,'PartialDecSeq'),
+ {Time_MGC_s,Time_MGC_e,Time_MGC_c}=go(10000,'MEDIA-GATEWAY-CONTROL'),
+ ?line do_comment({Time_S_s,Time_MGC_s},
+ {Time_S_e,Time_MGC_e},
+ {Time_S_c,Time_MGC_c}).
+
+go(N,Mod) ->
+ ?line Val = val(Mod),
+ ?line {ok,B} = Mod:encode(element(1,Val),Val),
+ ?line go(Mod,list_to_binary(B),N).
+
+go(Mod,Bin,N) ->
+ ?line FsS = get_selective_funcs(Mod),
+ ?line FsE = get_exclusive_funcs(Mod),
+ ?line io:format("~nSize of value for module ~p: ~p bytes.~n~n",[Mod,size(Bin)]),
+ ?line Time_s=go1(selective,Mod,FsS,Bin,N,0),
+ ?line Time_e=go1(exclusive,Mod,FsE,Bin,N,0),
+ ?line Time_c=go1(common,Mod,[decode],Bin,N,0),
+ ?line {Time_s/length(FsS),Time_e/length(FsE),Time_c}.
+
+go1(_,_,[],_,_,AccTime) ->
+ ?line AccTime;
+%% go1 for common decode
+go1(common,Mod,_,Bin,N,_) ->
+ ?line TT=get_top_type(Mod),
+ ?line {Time,Result}=timer:tc(?MODULE,loop1,[Mod,decode,TT,Bin,N]),
+ case Result of
+ {ok,_R1} ->
+ io:format("common Decode ~p:decode, ~p times on time ~p~n",
+ [Mod,N,Time]);
+ Err ->
+ io:format("common Decode ~p:decode failed: ~w~n~n",[Mod,Err])
+ end,
+ Time;
+go1(Dec,Mod,[F|Fs],Bin,N,AccTime) ->
+ ?line {Time,Result}=timer:tc(?MODULE,loop2,[Mod,F,Bin,N]),
+ case Result of
+ {ok,_R1} ->
+ io:format("~p Decode ~p:~p, ~p times on time ~p~n",[Dec,Mod,F,N,Time]);
+ Err ->
+ io:format("~p Decode ~p:~p failed: ~w~n~n",[Dec,Mod,F,Err])
+ end,
+ go1(Dec,Mod,Fs,Bin,N,AccTime+Time).
+
+do_comment({Time_S_s,Time_MGC_s},
+ {Time_S_e,Time_MGC_e},
+ {Time_S_c,Time_MGC_c}) ->
+% io:format("Time_s: ~w, Time_e: ~w, Time_c: ~w~n",[Time_s,Time_e,Time_c]),
+ Time_sofc1 = Time_S_s/Time_S_c,
+ Time_sofc2 = Time_MGC_s/Time_MGC_c,
+ Time_eofc1 = Time_S_e/Time_S_c,
+ Time_eofc2 = Time_MGC_e/Time_MGC_c,
+ Av_proc_sofc =
+ integer_to_list(round(((100*Time_sofc1) + (100*Time_sofc2))/2)),
+ Av_proc_eofc =
+ integer_to_list(round(((100*Time_eofc1) + (100*Time_eofc2))/2)),
+ io:format("Av_proc_sofc = ~w, Av_proc_eofc = ~w~n",
+ [Av_proc_sofc,Av_proc_eofc]),
+ Comment = ["selective decode takes "++
+ Av_proc_sofc ++" % of common decode time",
+ "exclusive decode takes "++ Av_proc_eofc++
+ " % of common decode time"],
+ {comment,Comment}.
+
+val('PartialDecSeq') ->
+ {'F',{fb,{'E',12,[{'D',13,true},{'D',14,false},{'D',15,true},{'D',16,false},{'D',13,true},{'D',14,false},{'D',15,true},{'D',16,false},{'D',13,true},{'D',14,false},{'D',15,true},{'D',16,false}],true,{da,[{'A',17,{'D',18,false}},{'A',19,{'D',20,true}},{'A',21,{'D',22,false}},{'A',17,{'D',18,false}},{'A',19,{'D',20,true}},{'A',21,{'D',22,false}},{'A',17,{'D',18,false}},{'A',19,{'D',20,true}},{'A',21,{'D',22,false}},{'A',17,{'D',18,false}},{'A',19,{'D',20,true}},{'A',21,{'D',22,false}},{'A',17,{'D',18,false}},{'A',19,{'D',20,true}},{'A',21,{'D',22,false}},{'A',17,{'D',18,false}},{'A',19,{'D',20,true}},{'A',21,{'D',22,false}}]}}}};
+
+val('MEDIA-GATEWAY-CONTROL') ->
+ {'MegacoMessage',asn1_NOVALUE,{'Message',1,{ip4Address,{'IP4Address',[125,125,125,111],55555}},{transactions,[{transactionReply,{'TransactionReply',50007,asn1_NOVALUE,{actionReplies,[{'ActionReply',0,asn1_NOVALUE,asn1_NOVALUE,[{auditValueReply,{auditResult,{'AuditResult',{'TerminationID',[],[255,255,255]},[{mediaDescriptor,{'MediaDescriptor',asn1_NOVALUE,{multiStream,[{'StreamDescriptor',1,{'StreamParms',{'LocalControlDescriptor',sendRecv,asn1_NOVALUE,asn1_NOVALUE,[{'PropertyParm',[0,11,0,7],[[52,48]],asn1_NOVALUE}]},{'LocalRemoteDescriptor',[[{'PropertyParm',[0,0,176,1],[[48]],asn1_NOVALUE},{'PropertyParm',[0,0,176,8],[[73,78,32,73,80,52,32,49,50,53,46,49,50,53,46,49,50,53,46,49,49,49]],asn1_NOVALUE},{'PropertyParm',[0,0,176,15],[[97,117,100,105,111,32,49,49,49,49,32,82,84,80,47,65,86,80,32,32,52]],asn1_NOVALUE},{'PropertyParm',[0,0,176,12],[[112,116,105,109,101,58,51,48]],asn1_NOVALUE}]]},{'LocalRemoteDescriptor',[[{'PropertyParm',[0,0,176,1],[[48]],asn1_NOVALUE},{'PropertyParm',[0,0,176,8],[[73,78,32,73,80,52,32,49,50,52,46,49,50,52,46,49,50,52,46,50,50,50]],asn1_NOVALUE},{'PropertyParm',[0,0,176,15],[[97,117,100,105,111,32,50,50,50,50,32,82,84,80,47,65,86,80,32,32,52]],asn1_NOVALUE},{'PropertyParm',[0,0,176,12],[[112,116,105,109,101,58,51,48]],asn1_NOVALUE}]]}}}]}}},{packagesDescriptor,[{'PackagesItem',[0,11],1},{'PackagesItem',[0,11],1}]},{statisticsDescriptor,[{'StatisticsParameter',[0,12,0,4],[[49,50,48,48]]},{'StatisticsParameter',[0,11,0,2],[[54,50,51,48,48]]},{'StatisticsParameter',[0,12,0,5],[[55,48,48]]},{'StatisticsParameter',[0,11,0,3],[[52,53,49,48,48]]},{'StatisticsParameter',[0,12,0,6],[[48,46,50]]},{'StatisticsParameter',[0,12,0,7],[[50,48]]},{'StatisticsParameter',[0,12,0,8],[[52,48]]}]}]}}}]}]}}}]}}}.
+
+%% val('PartialDecSeq') ->
+%% {'F',{fb,{'E',35,[{'D',3,true},{'D',4,false},{'D',5,true},{'D',6,true},{'D',7,false},{'D',8,true},{'D',9,true},{'D',10,false},{'D',11,true},{'D',12,true},{'D',13,false},{'D',14,true}],false,{dc,{'E_d_dc',15,true,{'E_d_dc_dcc',17,4711}}}}}}.
+
+loop1(Mod,decode,TT,Bin,1) ->
+ {ok,_Msg}=Mod:decode(TT,Bin);
+loop1(Mod,decode,TT,Bin,N) ->
+ {ok,_Msg}=Mod:decode(TT,Bin),
+ loop1(Mod,decode,TT,Bin,N-1).
+
+loop2(Mod,FS,Bin,1) ->
+ {ok,_Msg}=Mod:FS(Bin);
+loop2(Mod,FS,Bin,N) ->
+ {ok,_Msg}=Mod:FS(Bin),
+ loop2(Mod,FS,Bin,N-1).
+
+%% loop3(Mod,F,Bin,1) ->
+%% {ok,Msg}=Mod:F(Bin),
+%% decode_parts(Mod,F,Msg);
+%% loop3(Mod,F,Bin,N) ->
+%% {ok,Msg}=Mod:F(Bin),
+%% decode_parts(Mod,F,Msg),
+%% loop3(Mod,F,Bin,N-1).
+
+get_selective_funcs('PartialDecSeq') ->
+% [selected_decode_F1,selected_decode_F2,selected_decode_F3,selected_decode_F4];
+ [selected_decode_F1,selected_decode_F3,selected_decode_F4];
+get_selective_funcs('MEDIA-GATEWAY-CONTROL') ->
+ [decode_MegacoMessage_selective].
+
+get_exclusive_funcs('PartialDecSeq') ->
+ [decode_F_fb_incomplete,decode_F_fb_exclusive2,decode_F_fb_exclusive3];
+get_exclusive_funcs('MEDIA-GATEWAY-CONTROL') ->
+ [decode_MegacoMessage_exclusive].
+
+get_top_type('PartialDecSeq') ->
+ 'F';
+get_top_type('MEDIA-GATEWAY-CONTROL') ->
+ 'MegacoMessage'.
+
+%% decode_parts('PartialDecSeq',decode_F_fb_incomplete,Msg) ->
+%% {fb,{'E',12,{E_bKey,E_bMsg},true,{E_dKey,E_dMsg}}}=Msg,
+%% {ok,_}='Seq':decode_part(E_bKey,E_bMsg),
+%% {ok,_}='Seq':decode_part(E_dKey,E_dMsg);
+%% decode_parts('PartialDecSeq',decode_F_fb_exclusive2,Msg) ->
+%% {fb,{'E',12,{E_bKey,E_bMsg},true,{d,{E_dKey,E_dMsg}}}} = Msg,
+%% {ok,_}='Seq':decode_part(E_bKey,E_bMsg),
+%% {ok,_}='Seq':decode_part(E_dKey,E_dMsg);
+%% decode_parts('MEDIA-GATEWAY-CONTROL',decode_MegacoMessage_exclusive,Msg) ->
+%% {'MegacoMessage',asn1_NOVALUE,{'Message',1,{M_MidKey,M_MidMsg},
+%% {M_mBKey,M_mBMsg}}} = Msg,
+%% {ok,_}='MEDIA-GATEWAY-CONTROL':decode_part(M_MidKey,M_MidMsg),
+%% {ok,_}='MEDIA-GATEWAY-CONTROL':decode_part(M_mBKey,M_mBMsg).
+
+
diff --git a/lib/asn1/test/test_undecoded_rest.erl b/lib/asn1/test/test_undecoded_rest.erl
new file mode 100644
index 0000000000..d2c98e130d
--- /dev/null
+++ b/lib/asn1/test/test_undecoded_rest.erl
@@ -0,0 +1,65 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 2004-2010. All Rights Reserved.
+%%
+%% The contents of this file are subject to the Erlang Public License,
+%% Version 1.1, (the "License"); you may not use this file except in
+%% compliance with the License. You should have received a copy of the
+%% Erlang Public License along with this software. If not, it can be
+%% retrieved online at http://www.erlang.org/.
+%%
+%% Software distributed under the License is distributed on an "AS IS"
+%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+%% the License for the specific language governing rights and limitations
+%% under the License.
+%%
+%% %CopyrightEnd%
+%%
+%%
+-module(test_undecoded_rest).
+
+-export([compile/3,test/1]).
+
+-include("test_server.hrl").
+
+
+%% testing OTP-5104
+
+compile(Config,Rules,Opt) ->
+
+ ?line DataDir = ?config(data_dir,Config),
+ ?line OutDir = ?config(priv_dir,Config),
+ ?line true = code:add_patha(?config(priv_dir,Config)),
+
+ ?line ok = asn1ct:compile(DataDir ++ "P-Record",[Rules,{outdir,OutDir}]++Opt).
+
+
+test(Opt) ->
+ ?line {ok,Msg} = asn1ct:value('P-Record','PersonnelRecord'),
+ ?line {ok,Bytes} = asn1_wrapper:encode('P-Record','PersonnelRecord',Msg),
+ Bytes2 =
+ fun(B) when is_list(B) ->
+ B ++ [55,55,55];
+ (B) when is_binary(B) ->
+ erlang:list_to_binary([B,<<55,55,55>>])
+ end (Bytes),
+
+ case Opt of
+ undec_rest ->
+ ?line {ok,Msg,R}=asn1_wrapper:decode('P-Record','PersonnelRecord',
+ Bytes2),
+ ?line case R of
+ <<55,55,55>> ->ok;
+ [55,55,55] -> ok;
+ BStr when is_bitstring(BStr) ->
+ PadLen = (8 - (bit_size(BStr) rem 8)) rem 8,
+ case <<0:PadLen,BStr/bitstring>> of
+ <<0,55,55,55>> -> ok
+ end
+ end;
+ _ ->
+ ?line {ok,Msg} = asn1_wrapper:decode('P-Record','PersonnelRecord',
+ Bytes2)
+ end,
+ ok.
diff --git a/lib/asn1/test/test_x691.erl b/lib/asn1/test/test_x691.erl
new file mode 100644
index 0000000000..5bf3a4a077
--- /dev/null
+++ b/lib/asn1/test/test_x691.erl
@@ -0,0 +1,227 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 2008-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(test_x691).
+
+-export([compile/3]).
+-export([cases/2]).
+
+-include("test_server.hrl").
+
+
+compile(Config,Rules,Option) ->
+
+ ?line DataDir = ?config(data_dir,Config),
+ ?line OutDir = ?config(priv_dir,Config),
+ ?line true = code:add_patha(?config(priv_dir,Config)),
+ ?line ok = asn1ct:compile(DataDir ++ "P-RecordA1",
+ [Rules, {outdir,OutDir}]++Option),
+ ?line ok = asn1ct:compile(DataDir ++ "P-RecordA2",
+ [Rules, {outdir,OutDir}]++Option),
+ ?line ok = asn1ct:compile(DataDir ++ "P-RecordA3",
+ [Rules, {outdir,OutDir}]++Option).
+
+
+cases(Erule,Variant) ->
+ MsgA1 = a1(),
+ ?line {ok,B1} = asn1_wrapper:encode('P-RecordA1','PersonnelRecord',MsgA1),
+ ?line {ok,MsgA1} = asn1_wrapper:decode('P-RecordA1','PersonnelRecord',B1),
+ io:format("compare_format(~p,B1) ->~p~nencval(a1,~p,binary) ->~p~n",
+ [Erule,
+ compare_format(Erule,B1),
+ Variant,
+ encval(a1,Variant,binary)]),
+ ?line true = (compare_format(Erule,B1) == encval(a1,Variant,binary)),
+
+ MsgA2 = a2(),
+ ?line {ok,B2} = asn1_wrapper:encode('P-RecordA2','PersonnelRecord',MsgA2),
+ ?line {ok,MsgA2} = asn1_wrapper:decode('P-RecordA2','PersonnelRecord',B2),
+ io:format("compare_format(~p,B2) ->~p~nencval(a2,~p,binary) ->~p~n",
+ [Erule,
+ compare_format(Erule,B2),
+ Variant,
+ encval(a2,Variant,binary)]),
+ ?line true = (compare_format(Erule,B2) == encval(a2,Variant,binary)),
+
+ MsgA3 = a3(),
+ ?line {ok,B3} = asn1_wrapper:encode('P-RecordA3','PersonnelRecord',MsgA3),
+ ?line {ok,MsgA3} = asn1_wrapper:decode('P-RecordA3','PersonnelRecord',B3),
+ io:format("compare_format(~p,B3) ->~p~nencval(a3,~p,binary) ->~p~n",
+ [Erule,
+ compare_format(Erule,B3),
+ Variant,
+ encval(a3,Variant,binary)]),
+ ?line true = (compare_format(Erule,B3) == encval(a3,Variant,binary)).
+
+compare_format(Erule,Val) when is_list(Val) ->
+ compare_format(Erule,list_to_binary(Val));
+%% compare_format(per,Val) ->
+%% binary_to_list(Val);
+compare_format(_,Val) ->
+ Val.
+
+a1() ->
+ {'PersonnelRecord',
+ {'Name',"John", "P", "Smith"},
+ "Director",
+ 51,
+ "19710917",
+ {'Name', "Mary", "T", "Smith"},
+ [{'ChildInformation',
+ {'Name', "Ralph", "T", "Smith"},
+ "19571111"},
+ {'ChildInformation',
+ {'Name', "Susan", "B", "Jones"},
+ "19590717"}]}.
+
+a2() ->
+ a1().
+
+a3() ->
+ {'PersonnelRecord',
+ {'Name',"John", "P", "Smith"},
+ "Director",
+ 51,
+ "19710917",
+ {'Name', "Mary", "T", "Smith"},
+ [{'ChildInformation',
+ {'Name', "Ralph", "T", "Smith"},
+ "19571111",
+ asn1_NOVALUE},
+ {'ChildInformation',
+ {'Name', "Susan", "B", "Jones"},
+ "19590717",
+ female}]}.
+
+encval(An,Variant,Encoding) when Encoding == hex; Encoding == binary ->
+ Msg = encval(An,Variant),
+ encoding(Encoding,Msg).
+
+encval(a1,aligned) ->
+ "80044A6F 686E0150 05536D69 74680133 08446972 6563746F 72083139 37313039 3137044D 61727901 5405536D 69746802 0552616C 70680154 05536D69 74680831 39353731 31313105 53757361 6E014205 4A6F6E65 73083139 35393037 3137";
+encval(a1,unaligned) ->
+ "824ADFA3 700D005A 7B74F4D0 02661113 4F2CB8FA 6FE410C5 CB762C1C B16E0937 0F2F2035 0169EDD3 D340102D 2C3B3868 01A80B4F 6E9E9A02 18B96ADD 8B162C41 69F5E787 700C2059 5BF765E6 10C5CB57 2C1BB16E";
+encval(a2,aligned) ->
+ "864A6F68 6E501053 6D697468 01330844 69726563 746F7219 7109170C 4D617279 5410536D 69746802 1052616C 70685410 536D6974 68195711 11105375 73616E42 104A6F6E 65731959 0717";
+encval(a2,unaligned) ->
+ "865D51D2 888A5125 F1809984 44D3CB2E 3E9BF90C B8848B86 7396E8A8 8A5125F1 81089B93 D71AA229 4497C632 AE222222 985CE521 885D54C1 70CAC838 B8";
+encval(a3,aligned) ->
+ "40C04A6F 686E5008 536D6974 68000033 08446972 6563746F 72001971 0917034D 61727954 08536D69 74680100 52616C70 68540853 6D697468 00195711 11820053 7573616E 42084A6F 6E657300 19590717 010140";
+encval(a3,unaligned) ->
+ "40CBAA3A 5108A512 5F180330 889A7965 C7D37F20 CB8848B8 19CE5BA2 A114A24B E3011372 7AE35422 94497C61 95711118 22985CE5 21842EAA 60B832B2 0E2E0202 80".
+
+encoding(binary,Msg) ->
+ list_to_binary(bin(Msg));
+encoding(hex,Msg) ->
+ hex(Msg).
+
+bin(Msg) ->
+ HexList = hex(Msg),
+ Fun = fun([H1,H2|Rest],F) -> [(H1 bsl 4) + H2|F(Rest,F)];([],_) -> [] end,
+ Fun(HexList,Fun).
+
+hex(Msg) ->
+ [to_hex(X)||X <- Msg,X /= $ ].
+
+to_hex(I) when I >= $0, I =< $9 ->
+ I-48;
+to_hex(C) when C >= $A,C =< $F ->
+ C - 55.
+
+%% ex('EUTRA','BCCH-DL-SCH-Message',1) ->
+%% {'BCCH-DL-SCH-Message',
+%% {c1,
+%% {systemInformation1,
+%% {'SystemInformationBlockType1',
+%% {'SystemInformationBlockType1_cellAccessRelatedInformation',
+%% [{'SystemInformationBlockType1_cellAccessRelatedInformation_SOF',
+%% {'PLMN-Identity'},
+%% true},
+%% {'SystemInformationBlockType1_cellAccessRelatedInformation_SOF',
+%% {'PLMN-Identity'},
+%% false},
+%% {'SystemInformationBlockType1_cellAccessRelatedInformation_SOF',
+%% {'PLMN-Identity'},
+%% true}],
+%% {'TrackingAreaCode'},
+%% {'CellIdentity'},
+%% false,
+%% true,
+%% true,
+%% true},
+%% {'SystemInformationBlockType1_cellSelectionInfo',
+%% -50},
+%% 24,
+%% [{'SystemInformationBlockType1_schedulinInformation_SOF',
+%% {'SystemInformationBlockType1_schedulinInformation_SOF_si-MessageType'},
+%% ms320,
+%% {'SystemInformationBlockType1_schedulinInformation_SOF_sib-MappingInfo'}
+%% }],
+%% 0
+%% }
+%% }
+%% }
+%% }.
+
+%% eutra1(msg) ->
+%% {'BCCH-BCH-Message',{'MasterInformationBlock',[0,1,0,1],[1,0,1,0],{'PHICH-Configuration',short,ffs},[1,0,1,0,0,0,0,0]}};
+%% eutra1(result) ->
+%% <<90,80,0>>.
+
+%% eutra2(msg) ->
+%% {'BCCH-DL-SCH-Message',
+%% {c1,
+%% {systemInformation1,
+%% {'SystemInformationBlockType1',
+%% {'SystemInformationBlockType1_cellAccessRelatedInformation',
+%% [{'SystemInformationBlockType1_cellAccessRelatedInformation_plmn-IdentityList_SEQOF',{'PLMN-Identity'},true},
+%% {'SystemInformationBlockType1_cellAccessRelatedInformation_plmn-IdentityList_SEQOF',{'PLMN-Identity'},false},
+%% {'SystemInformationBlockType1_cellAccessRelatedInformation_plmn-IdentityList_SEQOF',{'PLMN-Identity'},true}],
+%% {'TrackingAreaCode'},
+%% {'CellIdentity'},
+%% false,
+%% true,
+%% true,
+%% true
+%% },
+%% {'SystemInformationBlockType1_cellSelectionInfo',-50},
+%% 24,
+%% [{'SystemInformationBlockType1_schedulinInformation_SEQOF',
+%% {'SystemInformationBlockType1_schedulinInformation_SEQOF_si-MessageType'},
+%% ms320,
+%% {'SystemInformationBlockType1_schedulinInformation_SEQOF_sib-MappingInfo'}}],
+%% 0
+%% }
+%% }
+%% }
+%% };
+%% eutra2(result) ->
+%% %% 55 5C A5 E0
+%% <<85,92,165,224>>.
+
+
+
+%% compare([H|T1],[H|T2],Acc) ->
+%% compare(T1,T2,[H|Acc]);
+%% compare([],[],_Acc) ->
+%% ok;
+%% compare(L1,L2,Acc) ->
+%% {miss_match,L1,L2,lists:reverse(Acc)}.
+
+
diff --git a/lib/asn1/vsn.mk b/lib/asn1/vsn.mk
index c79d833320..20ee8ac6ff 100644
--- a/lib/asn1/vsn.mk
+++ b/lib/asn1/vsn.mk
@@ -1,7 +1,10 @@
-#next version number to use is 1.6.13 | 1.7 | 2.0
-ASN1_VSN = 1.6.12
+#next version number to use is 1.6.14 | 1.7 | 2.0
+ASN1_VSN = 1.6.13.2
-TICKETS = OTP-8256
+TICKETS = OTP-8463
+
+TICKETS_1.6.13 = \
+ OTP-8463
TICKETS_1.6.12 = \
OTP-8256
diff --git a/lib/common_test/doc/src/Makefile b/lib/common_test/doc/src/Makefile
index a6ece5af28..a2c014418d 100644
--- a/lib/common_test/doc/src/Makefile
+++ b/lib/common_test/doc/src/Makefile
@@ -1,19 +1,19 @@
#
# %CopyrightBegin%
-#
-# Copyright Ericsson AB 2003-2009. All Rights Reserved.
-#
+#
+# Copyright Ericsson AB 2003-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%
#
@@ -112,18 +112,16 @@ DVIPS_FLAGS +=
CT_SRC_DIR = $(ERL_TOP)/../internal_tools/common_test/src
-EDOC_ARGS=[{preprocess,true},{includes,["$(XMERL_DIR)/include","../../../test_server/include","../../include","../../../../erts/lib/kernel/include","../../../../lib/kernel/include","../../../../erts/lib/snmp/include","../../../../lib/snmp/include"]}]
-
-
$(HTMLDIR)/%.gif: %.gif
$(INSTALL_DATA) $< $@
docs: pdf html man
$(CT_XML_FILES):
- erl -boot start_clean -noshell \
- -eval 'docb_gen:module("../../src/$(@:%.xml=%.erl)",$(EDOC_ARGS))' \
- -s erlang halt
+ escript $(DOCGEN)/priv/bin/xml_from_edoc.escript -preprocess true -i $(XMERL_DIR)/include \
+ -i ../../../test_server/include -i ../../include \
+ -i ../../../../erts/lib/kernel/include -i ../../../../lib/kernel/include \
+ -i ../../../../erts/lib/snmp/include -i ../../../../lib/snmp/include ../../src/$(@:%.xml=%.erl)
$(TOP_PDF_FILE): $(XML_FILES)
diff --git a/lib/common_test/doc/src/example_chapter.xml b/lib/common_test/doc/src/example_chapter.xml
index 028cbf7c8d..f269dba2cd 100644
--- a/lib/common_test/doc/src/example_chapter.xml
+++ b/lib/common_test/doc/src/example_chapter.xml
@@ -4,7 +4,7 @@
<chapter>
<header>
<copyright>
- <year>2003</year><year>2009</year>
+ <year>2003</year><year>2010</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
@@ -13,12 +13,12 @@
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>Examples and Templates</title>
@@ -38,7 +38,7 @@
<code>
-module(db_data_type_SUITE).
--include("ct.hrl").
+-include_lib("common_test/include/ct.hrl").
%% Test server callbacks
-export([suite/0, all/0,
@@ -186,7 +186,7 @@ insert_and_lookup(Key, Value, Config) ->
%% Note: This directive should only be used in test suites.
-compile(export_all).
--include("ct.hrl").
+-include_lib("common_test/include/ct.hrl").
%%--------------------------------------------------------------------
%% COMMON TEST CALLBACK FUNCTIONS
@@ -394,7 +394,7 @@ my_test_case(_Config) ->
-compile(export_all).
--include("ct.hrl").
+-include_lib("common_test/include/ct.hrl").
%%--------------------------------------------------------------------
%% Function: suite() -> Info
diff --git a/lib/common_test/doc/src/notes.xml b/lib/common_test/doc/src/notes.xml
index 3780d8526e..4f5f6caa8c 100644
--- a/lib/common_test/doc/src/notes.xml
+++ b/lib/common_test/doc/src/notes.xml
@@ -4,7 +4,7 @@
<chapter>
<header>
<copyright>
- <year>2004</year><year>2009</year>
+ <year>2004</year><year>2010</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
@@ -13,12 +13,12 @@
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>Common Test Release Notes</title>
@@ -32,6 +32,85 @@
<file>notes.xml</file>
</header>
+<section><title>Common_Test 1.4.7</title>
+
+ <section><title>Fixed Bugs and Malfunctions</title>
+ <list>
+ <item>
+ <p>
+ The auto compilation feature of Common Test did not
+ recognize if a header file included in a test suite was
+ modified (if the dir start flag/option was used). This
+ has been fixed.</p>
+ <p>
+ Own Id: OTP-8396 Aux Id: seq11488, OTP-8311 </p>
+ </item>
+ </list>
+ </section>
+
+
+ <section><title>Improvements and New Features</title>
+ <list>
+ <item>
+ <p>
+ The tc_status value in the Config list for a test case
+ that has failed because of a timetrap timeout, has
+ changed from {tc_status,timeout} to
+ {tc_status,timetrap_timeout}.</p>
+ <p>
+ Own Id: OTP-8302</p>
+ </item>
+ <item>
+ <p>The documentation is now possible to build in an open
+ source environment after a number of bugs are fixed and
+ some features are added in the documentation build
+ process. </p>
+ <p>- The arity calculation is updated.</p>
+ <p>- The module prefix used in the function names for
+ bif's are removed in the generated links so the links
+ will look like
+ "http://www.erlang.org/doc/man/erlang.html#append_element-2"
+ instead of
+ "http://www.erlang.org/doc/man/erlang.html#erlang:append_element-2".</p>
+ <p>- Enhanced the menu positioning in the html
+ documentation when a new page is loaded.</p>
+ <p>- A number of corrections in the generation of man
+ pages (thanks to Sergei Golovan)</p>
+ <p>- The legal notice is taken from the xml book file so
+ OTP's build process can be used for non OTP
+ applications.</p>
+ <p>
+ Own Id: OTP-8343</p>
+ </item>
+ <item>
+ <p>
+ It is now possible to include the <c>ct.hrl</c> using the
+ -include_lib directive. (Thanks to Fred Hebert.)</p>
+ <p>
+ Own Id: OTP-8379</p>
+ </item>
+ <item>
+ <p>
+ The telnet client in Common Test sent [IAC,DO,NOP] to the
+ server in attempt to keep the connection alive. This is
+ not a valid sequence according to the standard, and some
+ telnet servers would terminate the connection because of
+ it. The client has been changed to send [IAC,NOP] every
+ 10 secs instead, which should be a valid sequence. The
+ client does not negotiate this type of "keep alive"
+ message with the server, and if it causes problems, the
+ user may disable the keep alive feature by adding
+ {keep_alive,false} to the telnet configuration data for
+ the server/connection. Please see the ct_telnet and
+ unix_telnet manual pages for details.</p>
+ <p>
+ Own Id: OTP-8450 Aux Id: OTP-8311 </p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
<section><title>Common_Test 1.4.6</title>
<section><title>Fixed Bugs and Malfunctions</title>
diff --git a/lib/common_test/include/ct.hrl b/lib/common_test/include/ct.hrl
index ad3b3374c4..aa1cc832cf 100644
--- a/lib/common_test/include/ct.hrl
+++ b/lib/common_test/include/ct.hrl
@@ -1,22 +1,22 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2003-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 2003-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%
%%
--include("test_server.hrl").
+-include_lib("test_server/include/test_server.hrl").
-compile({parse_transform,ct_line}).
diff --git a/lib/common_test/info b/lib/common_test/info
index 1819ca2aad..6b2778f3e6 100644
--- a/lib/common_test/info
+++ b/lib/common_test/info
@@ -1,2 +1,2 @@
-group: tools
+group: test
short: A portable framework for automatic testing
diff --git a/lib/common_test/src/ct_framework.erl b/lib/common_test/src/ct_framework.erl
index 8456251b29..ed8b564921 100644
--- a/lib/common_test/src/ct_framework.erl
+++ b/lib/common_test/src/ct_framework.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2004-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 2004-2010. All Rights Reserved.
+%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
-%%
+%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
-%%
+%%
%% %CopyrightEnd%
%%
@@ -27,7 +27,7 @@
-export([init_tc/3, end_tc/3, get_suite/2, report/2, warn/1]).
-export([error_notification/4]).
--export([error_in_suite/1]).
+-export([error_in_suite/1, ct_init_per_group/2, ct_end_per_group/2]).
-include("ct_event.hrl").
-include("ct_util.hrl").
@@ -751,8 +751,15 @@ find_group(Mod, Name, Defs) ->
end.
make_conf(Mod, Name, Props, TestSpec) ->
- {conf,[{name,Name}|Props],
- {Mod,init_per_group},TestSpec,{Mod,end_per_group}}.
+ {InitConf,EndConf} =
+ case erlang:function_exported(Mod,init_per_group,2) of
+ true ->
+ {{Mod,init_per_group},{Mod,end_per_group}};
+ false ->
+ {{?MODULE,ct_init_per_group},
+ {?MODULE,ct_end_per_group}}
+ end,
+ {conf,[{name,Name}|Props],InitConf,TestSpec,EndConf}.
get_all(Mod, ConfTests) ->
@@ -916,6 +923,19 @@ check_multiple(Mod,Seq,TCs) ->
error_in_suite(Config) ->
Reason = test_server:lookup_config(error,Config),
exit(Reason).
+
+%% if the group config functions are missing in the suite,
+%% use these instead
+ct_init_per_group(GroupName, Config) ->
+ ct_logs:log("WARNING", "init_per_group/2 for ~w missing in suite, using default.",
+ [GroupName]),
+ Config.
+
+ct_end_per_group(GroupName, _) ->
+ ct_logs:log("WARNING", "end_per_group/2 for ~w missing in suite, using default.",
+ [GroupName]),
+ ok.
+
%%%-----------------------------------------------------------------
%%% @spec report(What,Data) -> ok
diff --git a/lib/common_test/src/ct_run.erl b/lib/common_test/src/ct_run.erl
index a1e2358578..6b1063f74c 100644
--- a/lib/common_test/src/ct_run.erl
+++ b/lib/common_test/src/ct_run.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2004-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 2004-2010. All Rights Reserved.
+%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
-%%
+%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
-%%
+%%
%% %CopyrightEnd%
%%
@@ -1515,7 +1515,7 @@ run_make(Targets, TestDir0, Mod, UserInclude) ->
debug_info],
Result =
if Mod == all ; Targets == helpmods ->
- case (catch ct_make:all([noexec])) of
+ case (catch ct_make:all([noexec|ErlFlags])) of
{'EXIT',_} = Failure ->
Failure;
MakeInfo ->
diff --git a/lib/common_test/src/ct_telnet.erl b/lib/common_test/src/ct_telnet.erl
index c19d312f01..c6f5fd7df4 100644
--- a/lib/common_test/src/ct_telnet.erl
+++ b/lib/common_test/src/ct_telnet.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2003-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 2003-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%
%%
@@ -21,27 +21,28 @@
%%%
%%% <p>Use this module to set up telnet connections, send commands and
%%% perform string matching on the result.
-%%% (See the <code>unix_telnet</code> manual page for information
-%%% about how ct_telnet may be used specifically with unix hosts.)</p>
+%%% See the <c>unix_telnet</c> manual page for information about how to use
+%%% ct_telnet, and configure connections, specifically for unix hosts.</p>
%%% <p>The following default values are defined in ct_telnet:</p>
%%% <pre>
%%% Connection timeout = 10 sec (time to wait for connection)
%%% Command timeout = 10 sec (time to wait for a command to return)
%%% Max no of reconnection attempts = 3
%%% Reconnection interval = 5 sek (time to wait in between reconnection attempts)
-%%% </pre>
+%%% Keep alive = true (will send NOP to the server every 10 sec if connection is idle)</pre>
%%% <p>These parameters can be altered by the user with the following
%%% configuration term:</p>
%%% <pre>
%%% {telnet_settings, [{connect_timeout,Millisec},
%%% {command_timeout,Millisec},
%%% {reconnection_attempts,N},
-%%% {reconnection_interval,Millisec}]}.
-%%% </pre>
+%%% {reconnection_interval,Millisec},
+%%% {keep_alive,Bool}]}.</pre>
%%% <p><code>Millisec = integer(), N = integer()</code></p>
%%% <p>Enter the <code>telnet_settings</code> term in a configuration
%%% file included in the test and ct_telnet will retrieve the information
-%%% automatically.</p>
+%%% automatically. Note that <c>keep_alive</c> may be specified per connection if
+%%% required. See <c>unix_telnet</c> for details.</p></doc>
%%% @type connection_type() = telnet | ts1 | ts2
@@ -88,7 +89,9 @@
buffer=[],
prompt=false,
name,
- target_mod,extra,
+ target_mod,
+ keep_alive,
+ extra,
conn_to=?DEFAULT_TIMEOUT,
com_to=?DEFAULT_TIMEOUT,
reconns=?RECONNS,
@@ -150,7 +153,7 @@ open(KeyOrName,ConnType,TargetMod) ->
%%% name can only be closed with the handle value.</p>
%%%
%%% <p><code>TargetMod</code> is a module which exports the functions
-%%% <code>connect(Ip,Port,Extra)</code> and <code>get_prompt_regexp()</code>
+%%% <code>connect(Ip,Port,KeepAlive,Extra)</code> and <code>get_prompt_regexp()</code>
%%% for the given <code>TargetType</code> (e.g. <code>unix_telnet</code>).</p>
open(KeyOrName,ConnType,TargetMod,Extra) ->
case ct:get_config({KeyOrName,ConnType}) of
@@ -169,9 +172,18 @@ open(KeyOrName,ConnType,TargetMod,Extra) ->
P -> {IP,P}
end
end,
+ KeepAlive =
+ case ct:get_config({KeyOrName,keep_alive}) of
+ undefined ->
+ case ct:get_config({telnet_settings,keep_alive}) of
+ undefined -> true;
+ Bool -> Bool
+ end;
+ Bool -> Bool
+ end,
log(heading(open,{KeyOrName,ConnType}),"Opening connection to: ~p",[Addr1]),
ct_gen_conn:start(KeyOrName,full_addr(Addr1,ConnType),
- {TargetMod,Extra},?MODULE)
+ {TargetMod,KeepAlive,Extra},?MODULE)
end.
%%%-----------------------------------------------------------------
@@ -373,14 +385,14 @@ expect(Connection,Patterns,Opts) ->
%%%=================================================================
%%% Callback functions
%% @hidden
-init(Name,{Ip,Port,Type},{TargetMod,Extra}) ->
+init(Name,{Ip,Port,Type},{TargetMod,KeepAlive,Extra}) ->
S0 = case ct:get_config(telnet_settings) of
undefined ->
#state{};
Settings ->
set_telnet_defaults(Settings,#state{})
end,
- case catch TargetMod:connect(Ip,Port,S0#state.conn_to,Extra) of
+ case catch TargetMod:connect(Ip,Port,S0#state.conn_to,KeepAlive,Extra) of
{ok,TelnPid} ->
log(heading(init,{Name,Type}),
"Opened telnet connection\n"
@@ -389,13 +401,15 @@ init(Name,{Ip,Port,Type},{TargetMod,Extra}) ->
"Command timeout: ~p\n"
"Reconnection attempts: ~p\n"
"Reconnection interval: ~p\n"
- "Connection timeout: ~p",
+ "Connection timeout: ~p\n"
+ "Keep alive: ~w",
[Ip,Port,S0#state.com_to,S0#state.reconns,
- S0#state.reconn_int,S0#state.conn_to]),
+ S0#state.reconn_int,S0#state.conn_to,KeepAlive]),
{ok,TelnPid,S0#state{teln_pid=TelnPid,
type=type(Type),
name={Name,Type},
target_mod=TargetMod,
+ keep_alive=KeepAlive,
extra=Extra,
prx=TargetMod:get_prompt_regexp()}};
{'EXIT',Reason} ->
@@ -415,6 +429,12 @@ set_telnet_defaults([{reconnection_attempts,Rs}|Ss],S) ->
set_telnet_defaults(Ss,S#state{reconns=Rs});
set_telnet_defaults([{reconnection_interval,RInt}|Ss],S) ->
set_telnet_defaults(Ss,S#state{reconn_int=RInt});
+set_telnet_defaults([{keep_alive,_}|Ss],S) ->
+ set_telnet_defaults(Ss,S);
+set_telnet_defaults([Unknown|Ss],S) ->
+ log(heading(set_telnet_defaults,{telnet_settings,Unknown}),
+ "Bad element in telnet_settings: ~p",[Unknown]),
+ set_telnet_defaults(Ss,S);
set_telnet_defaults([],S) ->
S.
@@ -527,10 +547,11 @@ handle_msg({expect,Pattern,Opts},State) ->
reconnect({Ip,Port,_Type},State) ->
reconnect(Ip,Port,State#state.reconns,State).
reconnect(Ip,Port,N,State=#state{target_mod=TargetMod,
+ keep_alive=KeepAlive,
extra=Extra,
conn_to=ConnTo,
reconn_int=ReconnInt}) ->
- case TargetMod:connect(Ip,Port,ConnTo,Extra) of
+ case TargetMod:connect(Ip,Port,ConnTo,KeepAlive,Extra) of
{ok, NewPid} ->
{ok, NewPid, State#state{teln_pid=NewPid}};
Error when N==0 ->
diff --git a/lib/common_test/src/ct_telnet_client.erl b/lib/common_test/src/ct_telnet_client.erl
index e460a50eac..1a12c5e343 100644
--- a/lib/common_test/src/ct_telnet_client.erl
+++ b/lib/common_test/src/ct_telnet_client.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2003-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 2003-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%
%%
@@ -32,13 +32,14 @@
-module(ct_telnet_client).
--export([open/1, open/2, open/3, close/1]).
+-export([open/1, open/2, open/3, open/4, close/1]).
-export([send_data/2, get_data/1]).
-define(DBG, false).
-define(TELNET_PORT, 23).
-define(OPEN_TIMEOUT,10000).
+-define(IDLE_TIMEOUT,10000).
%% telnet control characters
-define(SE, 240).
@@ -65,17 +66,20 @@
-define(TERMINAL_TYPE, 24).
-define(WINDOW_SIZE, 31).
--record(state,{get_data}).
+-record(state,{get_data, keep_alive=true}).
open(Server) ->
- open(Server, ?TELNET_PORT, ?OPEN_TIMEOUT).
+ open(Server, ?TELNET_PORT, ?OPEN_TIMEOUT, true).
open(Server, Port) ->
- open(Server, Port, ?OPEN_TIMEOUT).
+ open(Server, Port, ?OPEN_TIMEOUT, true).
open(Server, Port, Timeout) ->
+ open(Server, Port, Timeout, true).
+
+open(Server, Port, Timeout, KeepAlive) ->
Self = self(),
- Pid = spawn(fun() -> init(Self, Server, Port, Timeout) end),
+ Pid = spawn(fun() -> init(Self, Server, Port, Timeout, KeepAlive) end),
receive
{open,Pid} ->
{ok,Pid};
@@ -100,20 +104,18 @@ get_data(Pid) ->
%%%-----------------------------------------------------------------
%%% Internal functions
-init(Parent, Server, Port, Timeout) ->
+init(Parent, Server, Port, Timeout, KeepAlive) ->
case gen_tcp:connect(Server, Port, [list,{packet,0}], Timeout) of
{ok,Sock} ->
- dbg("Connected to: ~p\n", [Server]),
+ dbg("Connected to: ~p (port: ~w, keep_alive: ~w)\n", [Server,Port,KeepAlive]),
send([?IAC,?DO,?SUPPRESS_GO_AHEAD], Sock),
Parent ! {open,self()},
- loop(#state{get_data=10}, Sock, []),
+ loop(#state{get_data=10, keep_alive=KeepAlive}, Sock, []),
gen_tcp:close(Sock);
Error ->
Parent ! {Error,self()}
end.
-
-
loop(State, Sock, Acc) ->
receive
{tcp_closed,_} ->
@@ -137,21 +139,27 @@ loop(State, Sock, Acc) ->
[] ->
dbg("get_data nodata\n",[]),
erlang:send_after(100,self(),{get_data_delayed,Pid}),
- State#state{get_data=State#state.get_data - 1};
+ if State#state.keep_alive == true ->
+ State#state{get_data=State#state.get_data - 1};
+ State#state.keep_alive == false ->
+ State
+ end;
_ ->
Pid ! {data,lists:reverse(lists:append(Acc))},
State
end,
loop(NewState, Sock, []);
{get_data_delayed,Pid} ->
- NewState = case State#state.get_data of
- 0 ->
- send([?IAC,?DO,?NOP], Sock),
- dbg("delayed after 1000\n",[]),
- State#state{get_data=10};
- _ ->
- State
- end,
+ NewState =
+ case State of
+ #state{keep_alive = true, get_data = 0} ->
+ if Acc == [] -> send([?IAC,?NOP], Sock);
+ true -> ok
+ end,
+ State#state{get_data=10};
+ _ ->
+ State
+ end,
NewAcc =
case erlang:is_process_alive(Pid) of
true ->
@@ -160,29 +168,38 @@ loop(State, Sock, Acc) ->
false ->
Acc
end,
- loop(NewState, Sock, NewAcc);
-
+ loop(NewState, Sock, NewAcc);
close ->
dbg("Closing connection\n", []),
gen_tcp:close(Sock),
ok
- after 1000 ->
- case Acc of
- [] -> % no data buffered
- send([?IAC,?DO,?NOP], Sock),
- dbg("after 1000\n",[]);
- _ ->
- true
+ after wait(State#state.keep_alive,?IDLE_TIMEOUT) ->
+ if
+ Acc == [] -> send([?IAC,?NOP], Sock);
+ true -> ok
end,
loop(State, Sock, Acc)
end.
+wait(true, Time) -> Time;
+wait(false, _) -> infinity.
+
send(Data, Sock) ->
- dbg("Sending: ~p\n", [Data]),
+ case Data of
+ [?IAC|_] = Cmd ->
+ cmd_dbg(Cmd);
+ _ ->
+ dbg("Sending: ~p\n", [Data])
+ end,
gen_tcp:send(Sock, Data),
ok.
-check_msg(Sock,[?IAC | Cs], Acc) ->
+%% [IAC,IAC] = buffer data value 255
+check_msg(Sock, [?IAC,?IAC | T], Acc) ->
+ check_msg(Sock, T, [?IAC|Acc]);
+
+%% respond to a command
+check_msg(Sock, [?IAC | Cs], Acc) ->
case get_cmd(Cs) of
{Cmd,Cs1} ->
dbg("Got ", []),
@@ -192,11 +209,15 @@ check_msg(Sock,[?IAC | Cs], Acc) ->
error ->
Acc
end;
-check_msg(Sock,[H|T],Acc) ->
- check_msg(Sock,T,[H|Acc]);
-check_msg(_Sock,[],Acc) ->
+
+%% buffer a data value
+check_msg(Sock, [H|T], Acc) ->
+ check_msg(Sock, T, [H|Acc]);
+
+check_msg(_Sock, [], Acc) ->
Acc.
+
%% Positive responses (WILL and DO).
respond_cmd([?WILL,?ECHO], Sock) ->
@@ -234,6 +255,11 @@ respond_cmd([?DO | Opt], Sock) ->
cmd_dbg(R),
gen_tcp:send(Sock, R);
+%% Commands without options (which we ignore)
+
+respond_cmd(?NOP, _Sock) ->
+ ok;
+
%% Unexpected messages.
respond_cmd([Cmd | Opt], _Sock) when Cmd >= 240, Cmd =< 255 ->
@@ -246,7 +272,10 @@ respond_cmd([Cmd | Opt], _Sock) ->
get_cmd([Cmd | Rest]) when Cmd == ?SB ->
get_subcmd(Rest, []);
-get_cmd([Cmd,Opt | Rest]) ->
+get_cmd([Cmd | Rest]) when Cmd >= 240, Cmd =< 249 ->
+ {?NOP, Rest};
+
+get_cmd([Cmd,Opt | Rest]) when Cmd >= 251, Cmd =< 254 ->
{[Cmd,Opt], Rest};
get_cmd(_Other) ->
@@ -259,46 +288,34 @@ get_subcmd([Opt | Rest], Acc) ->
get_subcmd(Rest, [Opt | Acc]).
-dbg(_Str,_Args) -> ok.
-% if ?DBG -> io:format(_Str,_Args);
-% true -> ok
-% end.
-
-cmd_dbg(_Cmd) -> ok.
-% if ?DBG ->
-% case _Cmd of
-% [?IAC|Cmd1] ->
-% cmd_dbg(Cmd1);
-% [Ctrl|Opts] ->
-% CtrlStr =
-% case Ctrl of
-% ?DO -> "DO";
-% ?DONT -> "DONT";
-% ?WILL -> "WILL";
-% ?WONT -> "WONT";
-% _ -> "CMD"
-% end,
-% Opts1 =
-% case Opts of
-% [Opt] -> Opt;
-% _ -> Opts
-% end,
-% io:format("~s(~w): ~w\n", [CtrlStr,Ctrl,Opts1]);
-% Any ->
-% io:format("Unexpected in cmd_dbg:~n~w~n",[Any])
-% end;
-% true -> ok
-% end.
-
-
-
-
-
-
-
-
-
-
-
-
+dbg(_Str,_Args) ->
+ if ?DBG -> io:format(_Str,_Args);
+ true -> ok
+ end.
+cmd_dbg(_Cmd) ->
+ if ?DBG ->
+ case _Cmd of
+ [?IAC|Cmd1] ->
+ cmd_dbg(Cmd1);
+ [Ctrl|Opts] ->
+ CtrlStr =
+ case Ctrl of
+ ?DO -> "DO";
+ ?DONT -> "DONT";
+ ?WILL -> "WILL";
+ ?WONT -> "WONT";
+ ?NOP -> "NOP";
+ _ -> "CMD"
+ end,
+ Opts1 =
+ case Opts of
+ [Opt] -> Opt;
+ _ -> Opts
+ end,
+ io:format("~s(~w): ~w\n", [CtrlStr,Ctrl,Opts1]);
+ Any ->
+ io:format("Unexpected in cmd_dbg:~n~w~n",[Any])
+ end;
+ true -> ok
+ end.
diff --git a/lib/common_test/src/ct_testspec.erl b/lib/common_test/src/ct_testspec.erl
index 21a2f82a54..4378ec5a52 100644
--- a/lib/common_test/src/ct_testspec.erl
+++ b/lib/common_test/src/ct_testspec.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2006-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 2006-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%
%%
@@ -231,9 +231,11 @@ collect_tests_from_file(Specs,Nodes,Relaxed) when is_list(Nodes) ->
catch collect_tests_from_file1(Specs,#testspec{nodes=NodeRefs},Relaxed).
collect_tests_from_file1([Spec|Specs],TestSpec,Relaxed) ->
+ SpecDir = filename:dirname(filename:absname(Spec)),
case file:consult(Spec) of
{ok,Terms} ->
- TestSpec1 = collect_tests(Terms,TestSpec,Relaxed),
+ TestSpec1 = collect_tests(Terms,TestSpec#testspec{spec_dir=SpecDir},
+ Relaxed),
collect_tests_from_file1(Specs,TestSpec1,Relaxed);
{error,Reason} ->
throw({error,{Spec,Reason}})
@@ -249,8 +251,11 @@ collect_tests_from_list(Terms,Relaxed) ->
collect_tests_from_list(Terms,[node()],Relaxed).
collect_tests_from_list(Terms,Nodes,Relaxed) when is_list(Nodes) ->
+ {ok,Cwd} = file:get_cwd(),
NodeRefs = lists:map(fun(N) -> {undefined,N} end, Nodes),
- case catch collect_tests(Terms,#testspec{nodes=NodeRefs},Relaxed) of
+ case catch collect_tests(Terms,#testspec{nodes=NodeRefs,
+ spec_dir=Cwd},
+ Relaxed) of
E = {error,_} ->
E;
TS ->
@@ -265,17 +270,51 @@ collect_tests(Terms,TestSpec,Relaxed) ->
put(relaxed,Relaxed),
TestSpec1 = get_global(Terms,TestSpec),
TestSpec2 = get_all_nodes(Terms,TestSpec1),
+ case catch evaluate(Terms,TestSpec2) of
+ {error,{Node,{M,F,A},Reason}} ->
+ io:format("Error! Common Test failed to evaluate ~w:~w/~w on ~w. "
+ "Reason: ~p~n~n", [M,F,A,Node,Reason]);
+ _ -> ok
+ end,
add_tests(Terms,TestSpec2).
+evaluate([{eval,NodeRef,{M,F,Args}}|Ts],Spec) ->
+ Node = ref2node(NodeRef,Spec#testspec.nodes),
+ case rpc:call(Node,M,F,Args) of
+ {badrpc,Reason} ->
+ throw({error,{Node,{M,F,length(Args)},Reason}});
+ _ ->
+ ok
+ end,
+ evaluate(Ts,Spec);
+evaluate([{eval,{M,F,Args}}|Ts],Spec) ->
+ case catch apply(M,F,Args) of
+ {'EXIT',Reason} ->
+ throw({error,{node(),{M,F,length(Args)},Reason}});
+ _ ->
+ ok
+ end,
+ evaluate(Ts,Spec);
+evaluate([],_Spec) ->
+ ok.
+
get_global([{alias,Ref,Dir}|Ts],Spec=#testspec{alias=Refs}) ->
- get_global(Ts,Spec#testspec{alias=[{Ref,get_absname(Dir)}|Refs]});
+ get_global(Ts,Spec#testspec{alias=[{Ref,get_absdir(Dir,Spec)}|Refs]});
get_global([{node,Ref,Node}|Ts],Spec=#testspec{nodes=Refs}) ->
get_global(Ts,Spec#testspec{nodes=[{Ref,Node}|lists:keydelete(Node,2,Refs)]});
get_global([_|Ts],Spec) -> get_global(Ts,Spec);
get_global([],Spec) -> Spec.
-get_absname(TestDir) ->
- AbsName = filename:absname(TestDir),
+get_absfile(FullName,#testspec{spec_dir=SpecDir}) ->
+ File = filename:basename(FullName),
+ Dir = get_absname(filename:dirname(FullName),SpecDir),
+ filename:join(Dir,File).
+
+get_absdir(Dir,#testspec{spec_dir=SpecDir}) ->
+ get_absname(Dir,SpecDir).
+
+get_absname(TestDir,SpecDir) ->
+ AbsName = filename:absname(TestDir,SpecDir),
TestDirName = filename:basename(AbsName),
Path = filename:dirname(AbsName),
TopDir = filename:basename(Path),
@@ -345,16 +384,17 @@ list_nodes(#testspec{nodes=NodeRefs}) ->
%% --- logdir ---
add_tests([{logdir,all_nodes,Dir}|Ts],Spec) ->
Dirs = Spec#testspec.logdir,
- Tests = [{logdir,N,Dir} || N <- list_nodes(Spec),
- lists:keymember(ref2node(N,Spec#testspec.nodes),
- 1,Dirs) == false],
+ Tests = [{logdir,N,get_absdir(Dir,Spec)} ||
+ N <- list_nodes(Spec),
+ lists:keymember(ref2node(N,Spec#testspec.nodes),
+ 1,Dirs) == false],
add_tests(Tests++Ts,Spec);
add_tests([{logdir,Nodes,Dir}|Ts],Spec) when is_list(Nodes) ->
Ts1 = separate(Nodes,logdir,[Dir],Ts,Spec#testspec.nodes),
add_tests(Ts1,Spec);
add_tests([{logdir,Node,Dir}|Ts],Spec) ->
Dirs = Spec#testspec.logdir,
- Dirs1 = [{ref2node(Node,Spec#testspec.nodes),Dir} |
+ Dirs1 = [{ref2node(Node,Spec#testspec.nodes),get_absdir(Dir,Spec)} |
lists:keydelete(ref2node(Node,Spec#testspec.nodes),1,Dirs)],
add_tests(Ts,Spec#testspec{logdir=Dirs1});
add_tests([{logdir,Dir}|Ts],Spec) ->
@@ -369,7 +409,7 @@ add_tests([{cover,Nodes,File}|Ts],Spec) when is_list(Nodes) ->
add_tests(Ts1,Spec);
add_tests([{cover,Node,File}|Ts],Spec) ->
CoverFs = Spec#testspec.cover,
- CoverFs1 = [{ref2node(Node,Spec#testspec.nodes),File} |
+ CoverFs1 = [{ref2node(Node,Spec#testspec.nodes),get_absfile(File,Spec)} |
lists:keydelete(ref2node(Node,Spec#testspec.nodes),1,CoverFs)],
add_tests(Ts,Spec#testspec{cover=CoverFs1});
add_tests([{cover,File}|Ts],Spec) ->
@@ -385,7 +425,8 @@ add_tests([{config,Nodes,Files}|Ts],Spec) when is_list(Nodes) ->
add_tests([{config,Node,[F|Fs]}|Ts],Spec) when is_list(F) ->
Cfgs = Spec#testspec.config,
Node1 = ref2node(Node,Spec#testspec.nodes),
- add_tests([{config,Node,Fs}|Ts],Spec#testspec{config=[{Node1,F}|Cfgs]});
+ add_tests([{config,Node,Fs}|Ts],
+ Spec#testspec{config=[{Node1,get_absfile(F,Spec)}|Cfgs]});
add_tests([{config,_Node,[]}|Ts],Spec) ->
add_tests(Ts,Spec);
add_tests([{config,Node,F}|Ts],Spec) ->
@@ -451,7 +492,8 @@ add_tests([{include,Nodes,InclDirs}|Ts],Spec) when is_list(Nodes) ->
add_tests([{include,Node,[D|Ds]}|Ts],Spec) when is_list(D) ->
Dirs = Spec#testspec.include,
Node1 = ref2node(Node,Spec#testspec.nodes),
- add_tests([{include,Node,Ds}|Ts],Spec#testspec{include=[{Node1,D}|Dirs]});
+ add_tests([{include,Node,Ds}|Ts],
+ Spec#testspec{include=[{Node1,get_absdir(D,Spec)}|Dirs]});
add_tests([{include,_Node,[]}|Ts],Spec) ->
add_tests(Ts,Spec);
add_tests([{include,Node,D}|Ts],Spec) ->
diff --git a/lib/common_test/src/ct_util.hrl b/lib/common_test/src/ct_util.hrl
index 94ae2625cf..c1dc14f943 100644
--- a/lib/common_test/src/ct_util.hrl
+++ b/lib/common_test/src/ct_util.hrl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2003-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 2003-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%
%%
@@ -27,7 +27,8 @@
address,
callback}).
--record(testspec, {nodes=[],
+-record(testspec, {spec_dir,
+ nodes=[],
logdir=["."],
cover=[],
config=[],
diff --git a/lib/common_test/src/unix_telnet.erl b/lib/common_test/src/unix_telnet.erl
index 14a70e9d22..25b9d4d5d2 100644
--- a/lib/common_test/src/unix_telnet.erl
+++ b/lib/common_test/src/unix_telnet.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2004-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 2004-2010. All Rights Reserved.
+%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
-%%
+%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
-%%
+%%
%% %CopyrightEnd%
%%
@@ -23,10 +23,10 @@
%%% <p>It requires the following entry in the config file:</p>
%%% <pre>
%%% {unix,[{telnet,HostNameOrIpAddress},
-%%% {port,PortNum},
+%%% {port,PortNum}, % optional
%%% {username,UserName},
-%%% {password,Password}]}.
-%%% </pre>
+%%% {password,Password},
+%%% {keep_alive,Bool}]}. % optional</pre>
%%%
%%% <p>To talk telnet to the host specified by
%%% <code>HostNameOrIpAddress</code>, use the interface functions in
@@ -38,8 +38,14 @@
%%% <p>or</p>
%%% <pre> ct:require(Name,{unix,[telnet,username,password]}).</pre>
%%%
+%%% <p>The "keep alive" activity (i.e. that Common Test sends NOP to the server
+%%% every 10 seconds if the connection is idle) may be enabled or disabled for one
+%%% particular connection as described here. It may be disabled for all connections
+%%% using <c>telnet_settings</c> (see <c>ct_telnet</c>).</p>
+%%%
%%% <p>Note that the <code>{port,PortNum}</code> tuple is optional and if
-%%% omitted, default telnet port 23 will be used.</p>
+%%% omitted, default telnet port 23 will be used. Also the <c>keep_alive</c> tuple
+%%% is optional, and the value defauls to true (enabled).</p>
%%%
%%% @see ct
%%% @see ct_telnet
@@ -48,7 +54,7 @@
-compile(export_all).
%% Callbacks for ct_telnet.erl
--export([connect/4,get_prompt_regexp/0]).
+-export([connect/5,get_prompt_regexp/0]).
-import(ct_telnet,[start_log/1,cont_log/2,end_log/0]).
-define(username,"login: ").
@@ -70,10 +76,11 @@ get_prompt_regexp() ->
%%%-----------------------------------------------------------------
%%% @hidden
-%%% @spec connect(Ip,Port,Timeout,Extra) -> {ok,Handle} | {error,Reason}
+%%% @spec connect(Ip,Port,Timeout,KeepAlive,Extra) -> {ok,Handle} | {error,Reason}
%%% Ip = string() | {integer(),integer(),integer(),integer()}
%%% Port = integer()
%%% Timeout = integer()
+%%% KeepAlive = bool()
%%% Extra = {Username,Password}
%%% Username = string()
%%% Password = string()
@@ -82,23 +89,23 @@ get_prompt_regexp() ->
%%% @doc Callback for ct_telnet.erl.
%%%
%%% <p>Setup telnet connection to a UNIX host.</p>
-connect(Ip,Port,Timeout,Extra) ->
+connect(Ip,Port,Timeout,KeepAlive,Extra) ->
case Extra of
{Username,Password} ->
- connect(Ip,Port,Timeout,Username,Password);
+ connect1(Ip,Port,Timeout,KeepAlive,Username,Password);
Name ->
case get_username_and_password(Name) of
{ok,{Username,Password}} ->
- connect(Ip,Port,Timeout,Username,Password);
+ connect1(Ip,Port,Timeout,KeepAlive,Username,Password);
Error ->
Error
end
end.
-connect(Ip,Port,Timeout,Username,Password) ->
+connect1(Ip,Port,Timeout,KeepAlive,Username,Password) ->
start_log("unix_telnet:connect"),
Result =
- case ct_telnet_client:open(Ip,Port,Timeout) of
+ case ct_telnet_client:open(Ip,Port,Timeout,KeepAlive) of
{ok,Pid} ->
case ct_telnet:silent_teln_expect(Pid,[],[prompt],?prx,[]) of
{ok,{prompt,?username},_} ->
diff --git a/lib/common_test/test/Makefile b/lib/common_test/test/Makefile
new file mode 100644
index 0000000000..35ba22aa59
--- /dev/null
+++ b/lib/common_test/test/Makefile
@@ -0,0 +1,94 @@
+#
+# %CopyrightBegin%
+#
+# Copyright Ericsson AB 2008-2010. All Rights Reserved.
+#
+# The contents of this file are subject to the Erlang Public License,
+# Version 1.1, (the "License"); you may not use this file except in
+# compliance with the License. You should have received a copy of the
+# Erlang Public License along with this software. If not, it can be
+# retrieved online at http://www.erlang.org/.
+#
+# Software distributed under the License is distributed on an "AS IS"
+# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+# the License for the specific language governing rights and limitations
+# under the License.
+#
+# %CopyrightEnd%
+#
+
+include $(ERL_TOP)/make/target.mk
+include $(ERL_TOP)/make/$(TARGET)/otp.mk
+
+# ----------------------------------------------------
+# Target Specs
+# ----------------------------------------------------
+
+MODULES= \
+ ct_test_support \
+ ct_test_support_eh \
+ ct_smoke_test_SUITE \
+ ct_event_handler_SUITE \
+ ct_groups_test_1_SUITE \
+ ct_groups_test_2_SUITE \
+ ct_skip_SUITE \
+ ct_error_SUITE \
+ ct_test_server_if_1_SUITE
+
+ERL_FILES= $(MODULES:%=%.erl)
+
+TARGET_FILES= $(MODULES:%=$(EBIN)/%.$(EMULATOR))
+INSTALL_PROGS= $(TARGET_FILES)
+
+EMAKEFILE=Emakefile
+COVERFILE=
+
+# ----------------------------------------------------
+# Release directory specification
+# ----------------------------------------------------
+RELSYSDIR = $(RELEASE_PATH)/common_test_test
+
+# ----------------------------------------------------
+# FLAGS
+# ----------------------------------------------------
+
+ERL_MAKE_FLAGS += -pa $(ERL_TOP)/lib/test_server/ebin
+ERL_COMPILE_FLAGS += -I$(ERL_TOP)/lib/test_server/include
+
+EBIN = .
+
+# ----------------------------------------------------
+# Targets
+# ----------------------------------------------------
+
+#.PHONY: make_emakefile
+
+#make_emakefile:
+# $(ERL_TOP)/make/make_emakefile $(ERL_COMPILE_FLAGS) -o$(EBIN) \
+# '*_SUITE_make' > $(EMAKEFILE)
+# $(ERL_TOP)/make/make_emakefile $(ERL_COMPILE_FLAGS) -o$(EBIN) $(MODULES)\
+# >> $(EMAKEFILE)
+
+tests debug opt:
+
+clean:
+ rm -f $(TARGET_FILES)
+ rm -f core
+
+docs:
+
+# ----------------------------------------------------
+# Release Target
+# ----------------------------------------------------
+include $(ERL_TOP)/make/otp_release_targets.mk
+
+release_spec: opt
+
+release_tests_spec:
+ $(INSTALL_DIR) $(RELSYSDIR)
+ $(INSTALL_DATA) $(ERL_FILES) $(COVERFILE) $(RELSYSDIR)
+ $(INSTALL_PROGRAM) common_test.spec $(RELSYSDIR)
+ chmod -f -R u+w $(RELSYSDIR)
+ @tar cf - *_SUITE_data | (cd $(RELSYSDIR); tar xf -)
+
+release_docs_spec:
diff --git a/lib/common_test/test/common_test.spec b/lib/common_test/test/common_test.spec
new file mode 100644
index 0000000000..7619a75b31
--- /dev/null
+++ b/lib/common_test/test/common_test.spec
@@ -0,0 +1 @@
+{topcase, {dir, "../common_test"}}.
diff --git a/lib/common_test/test/ct_error_SUITE.erl b/lib/common_test/test/ct_error_SUITE.erl
new file mode 100644
index 0000000000..be75d768fc
--- /dev/null
+++ b/lib/common_test/test/ct_error_SUITE.erl
@@ -0,0 +1,558 @@
+%%
+%% %CopyrightBegin%
+%%
+%% 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%
+%%
+
+%%%-------------------------------------------------------------------
+%%% File: ct_error_SUITE
+%%%
+%%% Description:
+%%% Test various errors in Common Test suites.
+%%%
+%%% The suites used for the test are located in the data directory.
+%%%-------------------------------------------------------------------
+-module(ct_error_SUITE).
+
+-compile(export_all).
+
+-include_lib("test_server/include/test_server.hrl").
+-include_lib("common_test/include/ct_event.hrl").
+
+-define(eh, ct_test_support_eh).
+
+%%--------------------------------------------------------------------
+%% TEST SERVER CALLBACK FUNCTIONS
+%%--------------------------------------------------------------------
+
+%%--------------------------------------------------------------------
+%% Description: Since Common Test starts another Test Server
+%% instance, the tests need to be performed on a separate node (or
+%% there will be clashes with logging processes etc).
+%%--------------------------------------------------------------------
+init_per_suite(Config) ->
+ Config1 = ct_test_support:init_per_suite(Config),
+ Config1.
+
+end_per_suite(Config) ->
+ ct_test_support:end_per_suite(Config).
+
+init_per_testcase(TestCase, Config) ->
+ ct_test_support:init_per_testcase(TestCase, Config).
+
+end_per_testcase(TestCase, Config) ->
+ ct_test_support:end_per_testcase(TestCase, Config).
+
+all(doc) ->
+ [""];
+
+all(suite) ->
+ [
+ cfg_error,
+ lib_error,
+ no_compile
+ ].
+
+
+%%--------------------------------------------------------------------
+%% TEST CASES
+%%--------------------------------------------------------------------
+
+%%%-----------------------------------------------------------------
+%%%
+cfg_error(Config) when is_list(Config) ->
+ DataDir = ?config(data_dir, Config),
+ Join = fun(D, S) -> filename:join(D, "error/test/"++S) end,
+ Suites = [Join(DataDir, "cfg_error_1_SUITE"),
+ Join(DataDir, "cfg_error_2_SUITE"),
+ Join(DataDir, "cfg_error_3_SUITE"),
+ Join(DataDir, "cfg_error_4_SUITE"),
+ Join(DataDir, "cfg_error_5_SUITE"),
+ Join(DataDir, "cfg_error_6_SUITE"),
+ Join(DataDir, "cfg_error_7_SUITE"),
+ Join(DataDir, "cfg_error_8_SUITE"),
+ Join(DataDir, "cfg_error_9_SUITE")
+ ],
+ {Opts,ERPid} = setup({suite,Suites}, Config),
+ ok = ct_test_support:run(ct, run_test, [Opts], Config),
+ Events = ct_test_support:get_events(ERPid, Config),
+
+ ct_test_support:log_events(cfg_error,
+ reformat(Events, ?eh),
+ ?config(priv_dir, Config)),
+
+ TestEvents = test_events(cfg_error),
+ ok = ct_test_support:verify_events(TestEvents, Events, Config).
+
+
+%%%-----------------------------------------------------------------
+%%%
+lib_error(Config) when is_list(Config) ->
+ DataDir = ?config(data_dir, Config),
+ Join = fun(D, S) -> filename:join(D, "error/test/"++S) end,
+ Suites = [Join(DataDir, "lib_error_1_SUITE")],
+ {Opts,ERPid} = setup({suite,Suites}, Config),
+ ok = ct_test_support:run(ct, run_test, [Opts], Config),
+ Events = ct_test_support:get_events(ERPid, Config),
+
+ ct_test_support:log_events(lib_error,
+ reformat(Events, ?eh),
+ ?config(priv_dir, Config)),
+
+ TestEvents = test_events(lib_error),
+ ok = ct_test_support:verify_events(TestEvents, Events, Config).
+
+
+%%%-----------------------------------------------------------------
+%%%
+no_compile(Config) when is_list(Config) ->
+ DataDir = ?config(data_dir, Config),
+ Join = fun(D, S) -> filename:join(D, "error/test/"++S) end,
+ Suites = [Join(DataDir, "no_compile_SUITE")],
+ {Opts,ERPid} = setup({suite,Suites}, Config),
+ ok = ct_test_support:run(ct, run_test, [Opts], Config),
+ Events = ct_test_support:get_events(ERPid, Config),
+
+ ct_test_support:log_events(no_compile,
+ reformat(Events, ?eh),
+ ?config(priv_dir, Config)),
+
+ TestEvents = test_events(no_compile),
+ ok = ct_test_support:verify_events(TestEvents, Events, Config).
+
+
+%%%-----------------------------------------------------------------
+%%% HELP FUNCTIONS
+%%%-----------------------------------------------------------------
+
+setup(Test, Config) ->
+ Opts0 = ct_test_support:get_opts(Config),
+ Level = ?config(trace_level, Config),
+ EvHArgs = [{cbm,ct_test_support},{trace_level,Level}],
+ Opts = Opts0 ++ [Test,{event_handler,{?eh,EvHArgs}}],
+ ERPid = ct_test_support:start_event_receiver(Config),
+ {Opts,ERPid}.
+
+reformat(Events, EH) ->
+ ct_test_support:reformat(Events, EH).
+%reformat(Events, _EH) ->
+% Events.
+
+%%%-----------------------------------------------------------------
+%%% TEST EVENTS
+%%%-----------------------------------------------------------------
+test_events(cfg_error) ->
+ [
+ {?eh,start_logging,{'DEF','RUNDIR'}},
+ {?eh,test_start,{'DEF',{'START_TIME','LOGDIR'}}},
+ {?eh,start_info,{9,9,33}},
+
+ {?eh,tc_start,{cfg_error_1_SUITE,init_per_suite}},
+ {?eh,tc_done,
+ {cfg_error_1_SUITE,init_per_suite,{failed,{error,init_per_suite_fails}}}},
+ {?eh,tc_auto_skip,
+ {cfg_error_1_SUITE,tc1,{failed,{cfg_error_1_SUITE,init_per_suite,
+ {'EXIT',init_per_suite_fails}}}}},
+ {?eh,test_stats,{0,0,{0,1}}},
+ {?eh,tc_auto_skip,
+ {cfg_error_1_SUITE,tc2,{failed,{cfg_error_1_SUITE,init_per_suite,
+ {'EXIT',init_per_suite_fails}}}}},
+ {?eh,test_stats,{0,0,{0,2}}},
+ {?eh,tc_auto_skip,
+ {cfg_error_1_SUITE,end_per_suite,{failed,{cfg_error_1_SUITE,init_per_suite,
+ {'EXIT',init_per_suite_fails}}}}},
+
+ {?eh,tc_start,{cfg_error_2_SUITE,init_per_suite}},
+ {?eh,tc_done,
+ {cfg_error_2_SUITE,init_per_suite,
+ {failed,{error,{{badmatch,[1,2]},
+ [{cfg_error_2_SUITE,init_per_suite,1},
+ {test_server,my_apply,3},
+ {test_server,ts_tc,3},
+ {test_server,run_test_case_eval1,6},
+ {test_server,run_test_case_eval,8}]}}}}},
+ {?eh,tc_auto_skip,
+ {cfg_error_2_SUITE,tc1,
+ {failed,{cfg_error_2_SUITE,init_per_suite,
+ {'EXIT',{{badmatch,[1,2]},
+ [{cfg_error_2_SUITE,init_per_suite,1},
+ {test_server,my_apply,3},
+ {test_server,ts_tc,3},
+ {test_server,run_test_case_eval1,6},
+ {test_server,run_test_case_eval,8}]}}}}}},
+ {?eh,test_stats,{0,0,{0,3}}},
+ {?eh,tc_auto_skip,
+ {cfg_error_2_SUITE,tc2,
+ {failed,{cfg_error_2_SUITE,init_per_suite,
+ {'EXIT',{{badmatch,[1,2]},
+ [{cfg_error_2_SUITE,init_per_suite,1},
+ {test_server,my_apply,3},
+ {test_server,ts_tc,3},
+ {test_server,run_test_case_eval1,6},
+ {test_server,run_test_case_eval,8}]}}}}}},
+ {?eh,test_stats,{0,0,{0,4}}},
+ {?eh,tc_auto_skip,
+ {cfg_error_2_SUITE,end_per_suite,
+ {failed,{cfg_error_2_SUITE,init_per_suite,
+ {'EXIT',{{badmatch,[1,2]},
+ [{cfg_error_2_SUITE,init_per_suite,1},
+ {test_server,my_apply,3},
+ {test_server,ts_tc,3},
+ {test_server,run_test_case_eval1,6},
+ {test_server,run_test_case_eval,8}]}}}}}},
+
+ {?eh,tc_start,{cfg_error_3_SUITE,init_per_suite}},
+ {?eh,tc_done,
+ {cfg_error_3_SUITE,init_per_suite,{failed,{timetrap_timeout,2000}}}},
+ {?eh,tc_auto_skip,
+ {cfg_error_3_SUITE,tc1,
+ {failed,{cfg_error_3_SUITE,init_per_suite,{timetrap_timeout,2000}}}}},
+ {?eh,test_stats,{0,0,{0,5}}},
+ {?eh,tc_auto_skip,
+ {cfg_error_3_SUITE,tc2,
+ {failed,{cfg_error_3_SUITE,init_per_suite,{timetrap_timeout,2000}}}}},
+ {?eh,test_stats,{0,0,{0,6}}},
+ {?eh,tc_auto_skip,
+ {cfg_error_3_SUITE,end_per_suite,
+ {failed,{cfg_error_3_SUITE,init_per_suite,{timetrap_timeout,2000}}}}},
+
+ {?eh,tc_start,{cfg_error_4_SUITE,init_per_suite}},
+ {?eh,tc_done,{cfg_error_4_SUITE,init_per_suite,ok}},
+ {?eh,tc_auto_skip,
+ {cfg_error_4_SUITE,tc1,
+ {failed,{cfg_error_4_SUITE,init_per_suite,bad_return}}}},
+ {?eh,test_stats,{0,0,{0,7}}},
+ {?eh,tc_auto_skip,
+ {cfg_error_4_SUITE,tc2,
+ {failed,{cfg_error_4_SUITE,init_per_suite,bad_return}}}},
+ {?eh,test_stats,{0,0,{0,8}}},
+ {?eh,tc_auto_skip,
+ {cfg_error_4_SUITE,end_per_suite,
+ {failed,{cfg_error_4_SUITE,init_per_suite,bad_return}}}},
+
+ {?eh,tc_start,{cfg_error_5_SUITE,init_per_suite}},
+ {?eh,tc_done,{cfg_error_5_SUITE,init_per_suite,ok}},
+ {?eh,tc_auto_skip,
+ {cfg_error_5_SUITE,tc1,
+ {failed,{cfg_error_5_SUITE,init_per_suite,bad_return}}}},
+ {?eh,test_stats,{0,0,{0,9}}},
+ {?eh,tc_auto_skip,
+ {cfg_error_5_SUITE,tc2,
+ {failed,{cfg_error_5_SUITE,init_per_suite,bad_return}}}},
+ {?eh,test_stats,{0,0,{0,10}}},
+ {?eh,tc_auto_skip,
+ {cfg_error_5_SUITE,end_per_suite,
+ {failed,{cfg_error_5_SUITE,init_per_suite,bad_return}}}},
+
+ {?eh,tc_start,{cfg_error_6_SUITE,init_per_suite}},
+ {?eh,tc_done,{cfg_error_6_SUITE,init_per_suite,ok}},
+ {?eh,tc_start,{cfg_error_6_SUITE,tc1}},
+ {?eh,tc_done,{cfg_error_6_SUITE,tc1,ok}},
+ {?eh,test_stats,{1,0,{0,10}}},
+ [{?eh,tc_start,{cfg_error_6_SUITE,{init_per_group,g1,[]}}},
+ {?eh,tc_done,{cfg_error_6_SUITE,{init_per_group,g1,[]},ok}},
+ {?eh,tc_start,{cfg_error_6_SUITE,tc2}},
+ {?eh,tc_done,{cfg_error_6_SUITE,tc2,ok}},
+ {?eh,test_stats,{2,0,{0,10}}},
+ {?eh,tc_start,{cfg_error_6_SUITE,{end_per_group,g1,[]}}},
+ {?eh,tc_done,{cfg_error_6_SUITE,{end_per_group,g1,[]},ok}}],
+ {?eh,tc_start,{cfg_error_6_SUITE,end_per_suite}},
+ {?eh,tc_done,{cfg_error_6_SUITE,end_per_suite,
+ {failed,{error,{{badmatch,[1,2]},
+ [{cfg_error_6_SUITE,end_per_suite,1},
+ {test_server,my_apply,3},
+ {test_server,ts_tc,3},
+ {test_server,run_test_case_eval1,6},
+ {test_server,run_test_case_eval,8}]}}}}},
+
+ {?eh,tc_start,{cfg_error_7_SUITE,init_per_suite}},
+ {?eh,tc_done,{cfg_error_7_SUITE,init_per_suite,ok}},
+ {?eh,tc_start,{cfg_error_7_SUITE,tc1}},
+ {?eh,tc_done,{cfg_error_7_SUITE,tc1,ok}},
+ {?eh,test_stats,{3,0,{0,10}}},
+ [{?eh,tc_start,{cfg_error_7_SUITE,{init_per_group,g1,[]}}},
+ {?eh,tc_done,{cfg_error_7_SUITE,{init_per_group,g1,[]},ok}},
+ {?eh,tc_start,{cfg_error_7_SUITE,tc2}},
+ {?eh,tc_done,{cfg_error_7_SUITE,tc2,ok}},
+ {?eh,test_stats,{4,0,{0,10}}},
+ {?eh,tc_start,{cfg_error_7_SUITE,{end_per_group,g1,[]}}},
+ {?eh,tc_done,{cfg_error_7_SUITE,{end_per_group,g1,[]},ok}}],
+ {?eh,tc_start,{cfg_error_7_SUITE,end_per_suite}},
+ {?eh,tc_done,
+ {cfg_error_7_SUITE,end_per_suite,{failed,{timetrap_timeout,2000}}}},
+
+ {?eh,tc_start,{cfg_error_8_SUITE,init_per_suite}},
+ {?eh,tc_done,{cfg_error_8_SUITE,init_per_suite,ok}},
+ [{?eh,tc_start,{cfg_error_8_SUITE,{init_per_group,g1,[]}}},
+ {?eh,tc_done,
+ {cfg_error_8_SUITE,{init_per_group,g1,[]},
+ {failed,{error,{init_per_group_fails,g1}}}}},
+ {?eh,tc_auto_skip,
+ {cfg_error_8_SUITE,tc1,
+ {failed,{cfg_error_8_SUITE,init_per_group,
+ {'EXIT',{init_per_group_fails,g1}}}}}},
+ {?eh,test_stats,{4,0,{0,11}}},
+ {?eh,tc_auto_skip,
+ {cfg_error_8_SUITE,end_per_group,
+ {failed,{cfg_error_8_SUITE,init_per_group,
+ {'EXIT',{init_per_group_fails,g1}}}}}}],
+
+ [{?eh,tc_start,{cfg_error_8_SUITE,{init_per_group,g2,[]}}},
+ {?eh,tc_done,{cfg_error_8_SUITE,
+ {init_per_group,unknown,[]},
+ {failed,{timetrap_timeout,2000}}}},
+ {?eh,tc_auto_skip,{cfg_error_8_SUITE,tc1,
+ {failed,{cfg_error_8_SUITE,init_per_group,
+ {timetrap_timeout,2000}}}}},
+ {?eh,test_stats,{4,0,{0,12}}},
+ {?eh,tc_auto_skip,{cfg_error_8_SUITE,end_per_group,
+ {failed,{cfg_error_8_SUITE,init_per_group,
+ {timetrap_timeout,2000}}}}}],
+
+ [{?eh,tc_start,{cfg_error_8_SUITE,{init_per_group,g3,[]}}},
+ {?eh,tc_done,
+ {cfg_error_8_SUITE,{init_per_group,g3,[]},
+ {failed,{error,{{badmatch,42},
+ [{cfg_error_8_SUITE,init_per_group,2},
+ {cfg_error_8_SUITE,init_per_group,2},
+ {test_server,my_apply,3},
+ {test_server,ts_tc,3},
+ {test_server,run_test_case_eval1,6},
+ {test_server,run_test_case_eval,8}]}}}}},
+ {?eh,tc_auto_skip,
+ {cfg_error_8_SUITE,tc1,
+ {failed,{cfg_error_8_SUITE,init_per_group,
+ {'EXIT',{{badmatch,42},
+ [{cfg_error_8_SUITE,init_per_group,2},
+ {cfg_error_8_SUITE,init_per_group,2},
+ {test_server,my_apply,3},
+ {test_server,ts_tc,3},
+ {test_server,run_test_case_eval1,6},
+ {test_server,run_test_case_eval,8}]}}}}}},
+ {?eh,test_stats,{4,0,{0,13}}},
+ {?eh,tc_auto_skip,
+ {cfg_error_8_SUITE,end_per_group,
+ {failed,{cfg_error_8_SUITE,init_per_group,
+ {'EXIT',{{badmatch,42},
+ [{cfg_error_8_SUITE,init_per_group,2},
+ {cfg_error_8_SUITE,init_per_group,2},
+ {test_server,my_apply,3},
+ {test_server,ts_tc,3},
+ {test_server,run_test_case_eval1,6},
+ {test_server,run_test_case_eval,8}]}}}}}}],
+
+ [{?eh,tc_start,{cfg_error_8_SUITE,{init_per_group,g4,[]}}},
+ {?eh,tc_done,{cfg_error_8_SUITE,{init_per_group,g4,[]},ok}},
+ {?eh,tc_start,{cfg_error_8_SUITE,tc1}},
+ {?eh,tc_done,{cfg_error_8_SUITE,tc1,ok}},
+ {?eh,test_stats,{5,0,{0,13}}},
+ {?eh,tc_start,{cfg_error_8_SUITE,{end_per_group,g4,[]}}},
+ {?eh,tc_done,{cfg_error_8_SUITE,{end_per_group,g4,[]},ok}}],
+
+ [{?eh,tc_start,{cfg_error_8_SUITE,{init_per_group,g5,[]}}},
+ {?eh,tc_done,{cfg_error_8_SUITE,{init_per_group,g5,[]},ok}},
+ {?eh,tc_start,{cfg_error_8_SUITE,tc1}},
+ {?eh,tc_done,{cfg_error_8_SUITE,tc1,ok}},
+ {?eh,test_stats,{6,0,{0,13}}},
+ [{?eh,tc_start,{cfg_error_8_SUITE,{init_per_group,g6,[]}}},
+ {?eh,tc_done,{cfg_error_8_SUITE,{init_per_group,g6,[]},
+ {failed,{error,{sub_group_failed,g6}}}}},
+ {?eh,tc_auto_skip,
+ {cfg_error_8_SUITE,tc2,
+ {failed,{cfg_error_8_SUITE,init_per_group,
+ {'EXIT',{sub_group_failed,g6}}}}}},
+ {?eh,test_stats,{6,0,{0,14}}},
+ {?eh,tc_auto_skip,
+ {cfg_error_8_SUITE,end_per_group,
+ {failed,{cfg_error_8_SUITE,init_per_group,
+ {'EXIT',{sub_group_failed,g6}}}}}}],
+ {?eh,tc_start,{cfg_error_8_SUITE,tc3}},
+ {?eh,tc_done,{cfg_error_8_SUITE,tc3,ok}},
+ {?eh,test_stats,{7,0,{0,14}}},
+ {?eh,tc_start,{cfg_error_8_SUITE,{end_per_group,g5,[]}}},
+ {?eh,tc_done,{cfg_error_8_SUITE,{end_per_group,g5,[]},ok}}],
+
+ [{?eh,tc_start,{cfg_error_8_SUITE,{init_per_group,g11,[]}}},
+ {?eh,tc_done,{cfg_error_8_SUITE,{init_per_group,g11,[]},ok}},
+ {?eh,tc_start,{cfg_error_8_SUITE,tc1}},
+ {?eh,tc_done,{cfg_error_8_SUITE,tc1,ok}},
+ {?eh,test_stats,{8,0,{0,14}}},
+ {?eh,tc_start,{cfg_error_8_SUITE,{end_per_group,g11,[]}}},
+ {?eh,tc_done,{cfg_error_8_SUITE,{end_per_group,g11,[]},
+ {failed,{error,{end_per_group_fails,g5}}}}}],
+
+ [{?eh,tc_start,{cfg_error_8_SUITE,{init_per_group,g12,[]}}},
+ {?eh,tc_done,{cfg_error_8_SUITE,{init_per_group,g12,[]},ok}},
+ {?eh,tc_start,{cfg_error_8_SUITE,tc1}},
+ {?eh,tc_done,{cfg_error_8_SUITE,tc1,ok}},
+ {?eh,test_stats,{9,0,{0,14}}},
+ {?eh,tc_start,{cfg_error_8_SUITE,{end_per_group,g12,[]}}},
+ {?eh,tc_done,{cfg_error_8_SUITE,{end_per_group,unknown,[]},
+ {failed,{timetrap_timeout,2000}}}}],
+
+ {?eh,tc_start,{cfg_error_8_SUITE,end_per_suite}},
+ {?eh,tc_done,{cfg_error_8_SUITE,end_per_suite,ok}},
+
+ {?eh,tc_start,{cfg_error_9_SUITE,init_per_suite}},
+ {?eh,tc_done,{cfg_error_9_SUITE,init_per_suite,ok}},
+ {?eh,tc_start,{cfg_error_9_SUITE,tc1}},
+ {?eh,tc_done,{cfg_error_9_SUITE,tc1,
+ {skipped,{failed,{cfg_error_9_SUITE,init_per_testcase,
+ tc1_should_be_skipped}}}}},
+ {?eh,test_stats,{9,0,{0,15}}},
+ {?eh,tc_start,{cfg_error_9_SUITE,tc2}},
+ {?eh,tc_done,{cfg_error_9_SUITE,tc2,
+ {skipped,{failed,{cfg_error_9_SUITE,init_per_testcase,
+ {timetrap_timeout,2000}}}}}},
+ {?eh,test_stats,{9,0,{0,16}}},
+ {?eh,tc_start,{cfg_error_9_SUITE,tc3}},
+ {?eh,tc_done,{cfg_error_9_SUITE,tc3,
+ {skipped,{failed,{cfg_error_9_SUITE,init_per_testcase,
+ {{badmatch,undefined},
+ [{cfg_error_9_SUITE,init_per_testcase,2},
+ {test_server,my_apply,3},
+ {test_server,init_per_testcase,3},
+ {test_server,run_test_case_eval1,6},
+ {test_server,run_test_case_eval,8}]}}}}}},
+ {?eh,test_stats,{9,0,{0,17}}},
+ {?eh,tc_start,{cfg_error_9_SUITE,tc4}},
+ {?eh,tc_done,
+ {cfg_error_9_SUITE,tc4,
+ {skipped,{failed,{cfg_error_9_SUITE,init_per_testcase,bad_return}}}}},
+ {?eh,test_stats,{9,0,{0,18}}},
+ {?eh,tc_start,{cfg_error_9_SUITE,tc5}},
+ {?eh,tc_done,
+ {cfg_error_9_SUITE,tc5,{failed,{error,fail_this_testcase}}}},
+ {?eh,test_stats,{9,1,{0,18}}},
+ {?eh,tc_start,{cfg_error_9_SUITE,tc6}},
+ %%! we get ok with tc_done since it's only afterwards
+ %%! end_tc failes the testcase
+ {?eh,tc_done,{cfg_error_9_SUITE,tc6,ok}},
+ {?eh,test_stats,{9,2,{0,18}}},
+ {?eh,tc_start,{cfg_error_9_SUITE,tc11}},
+ {?eh,tc_done,{cfg_error_9_SUITE,tc11,
+ {failed,{cfg_error_9_SUITE,end_per_testcase,
+ {'EXIT',warning_should_be_printed}}}}},
+ {?eh,test_stats,{10,2,{0,18}}},
+ {?eh,tc_start,{cfg_error_9_SUITE,tc12}},
+ {?eh,tc_done,{cfg_error_9_SUITE,tc12,
+ {failed,{cfg_error_9_SUITE,end_per_testcase,
+ {timetrap_timeout,2000}}}}},
+ {?eh,test_stats,{11,2,{0,18}}},
+ {?eh,tc_start,{cfg_error_9_SUITE,tc13}},
+ {?eh,tc_done,{cfg_error_9_SUITE,tc13,
+ {failed,{cfg_error_9_SUITE,end_per_testcase,
+ {'EXIT',{{badmatch,undefined},
+ [{cfg_error_9_SUITE,end_per_testcase,2},
+ {test_server,my_apply,3},
+ {test_server,do_end_per_testcase,4},
+ {test_server,run_test_case_eval1,6},
+ {test_server,run_test_case_eval,8}]}}}}}},
+ {?eh,test_stats,{12,2,{0,18}}},
+ {?eh,tc_start,{cfg_error_9_SUITE,tc14}},
+ {?eh,tc_done,
+ {cfg_error_9_SUITE,tc14,{failed,{error,tc14_should_be_failed}}}},
+ {?eh,test_stats,{12,3,{0,18}}},
+
+ {?eh,tc_start,{cfg_error_9_SUITE,end_per_suite}},
+ {?eh,tc_done,{cfg_error_9_SUITE,end_per_suite,ok}},
+
+ {?eh,test_done,{'DEF','STOP_TIME'}},
+ {?eh,stop_logging,[]}
+ ];
+
+test_events(lib_error) ->
+ [
+ {?eh,start_logging,{'DEF','RUNDIR'}},
+ {?eh,test_start,{'DEF',{'START_TIME','LOGDIR'}}},
+ {?eh,start_info,{1,1,14}},
+ {?eh,tc_start,{lib_error_1_SUITE,init_per_suite}},
+ {?eh,tc_done,{lib_error_1_SUITE,init_per_suite,ok}},
+ {?eh,tc_start,{lib_error_1_SUITE,lines_error}},
+ {?eh,tc_done,
+ {lib_error_1_SUITE,lines_error,{failed,
+ {error,
+ {{badmatch,[1,2]},
+ [{lib_lines,do_error,0},
+ {lib_error_1_SUITE,lines_error,1},
+ {test_server,my_apply,3},
+ {test_server,ts_tc,3},
+ {test_server,run_test_case_eval1,6},
+ {test_server,run_test_case_eval,8}]}}}}},
+ {?eh,test_stats,{0,1,{0,0}}},
+ {?eh,tc_start,{lib_error_1_SUITE,lines_exit}},
+ {?eh,tc_done,
+ {lib_error_1_SUITE,lines_exit,{failed,{error,byebye}}}},
+ {?eh,test_stats,{0,2,{0,0}}},
+ {?eh,tc_start,{lib_error_1_SUITE,lines_hang}},
+ {?eh,tc_done,
+ {lib_lines,do_hang,{failed,{timetrap_timeout,3000}}}},
+ {?eh,test_stats,{0,3,{0,0}}},
+ {?eh,tc_start,{lib_error_1_SUITE,lines_throw}},
+ {?eh,tc_done,
+ {lib_error_1_SUITE,lines_throw,
+ {failed,{error,{thrown,catch_me_if_u_can}}}}},
+ {?eh,test_stats,{0,4,{0,0}}},
+ {?eh,tc_start,{lib_error_1_SUITE,no_lines_error}},
+ {?eh,tc_done,
+ {lib_error_1_SUITE,no_lines_error,{failed,
+ {error,
+ {{badmatch,[1,2]},
+ [{lib_no_lines,do_error,0},
+ {lib_error_1_SUITE,no_lines_error,1},
+ {test_server,my_apply,3},
+ {test_server,ts_tc,3},
+ {test_server,run_test_case_eval1,6},
+ {test_server,run_test_case_eval,8}]}}}}},
+ {?eh,test_stats,{0,5,{0,0}}},
+ {?eh,tc_start,{lib_error_1_SUITE,no_lines_exit}},
+ {?eh,tc_done,
+ {lib_error_1_SUITE,no_lines_exit,{failed,{error,byebye}}}},
+ {?eh,test_stats,{0,6,{0,0}}},
+ {?eh,tc_start,{lib_error_1_SUITE,no_lines_hang}},
+ {?eh,tc_done,
+ {lib_error_1_SUITE,no_lines_hang,{failed,{timetrap_timeout,3000}}}},
+ {?eh,test_stats,{0,7,{0,0}}},
+ {?eh,tc_start,{lib_error_1_SUITE,no_lines_throw}},
+ {?eh,tc_done,
+ {lib_error_1_SUITE,no_lines_throw,{failed,{error,{thrown,catch_me_if_u_can}}}}},
+ {?eh,test_stats,{0,8,{0,0}}},
+ {?eh,tc_start,{lib_error_1_SUITE,init_tc_error}},
+ {?eh,tc_done,{lib_error_1_SUITE,init_tc_error,ok}},
+ {?eh,test_stats,{1,8,{0,0}}},
+ {?eh,tc_start,{lib_error_1_SUITE,init_tc_exit}},
+ {?eh,tc_done,{lib_error_1_SUITE,init_tc_exit,ok}},
+ {?eh,test_stats,{2,8,{0,0}}},
+ {?eh,tc_start,{lib_error_1_SUITE,init_tc_throw}},
+ {?eh,tc_done,{lib_error_1_SUITE,init_tc_throw,ok}},
+ {?eh,test_stats,{3,8,{0,0}}},
+ {?eh,tc_start,{lib_error_1_SUITE,end_tc_error}},
+ {?eh,tc_done,{lib_error_1_SUITE,end_tc_error,ok}},
+ {?eh,test_stats,{3,9,{0,0}}},
+ {?eh,tc_start,{lib_error_1_SUITE,end_tc_exit}},
+ {?eh,tc_done,{lib_error_1_SUITE,end_tc_exit,ok}},
+ {?eh,test_stats,{3,10,{0,0}}},
+ {?eh,tc_start,{lib_error_1_SUITE,end_tc_throw}},
+ {?eh,tc_done,{lib_error_1_SUITE,end_tc_throw,ok}},
+ {?eh,test_stats,{3,11,{0,0}}},
+ {?eh,tc_start,{lib_error_1_SUITE,end_per_suite}},
+ {?eh,tc_done,{lib_error_1_SUITE,end_per_suite,ok}},
+ {?eh,test_done,{'DEF','STOP_TIME'}},
+ {?eh,stop_logging,[]}
+ ];
+
+test_events(no_compile) ->
+ [].
diff --git a/lib/common_test/test/ct_error_SUITE_data/error/test/cfg_error_1_SUITE.erl b/lib/common_test/test/ct_error_SUITE_data/error/test/cfg_error_1_SUITE.erl
new file mode 100644
index 0000000000..a9649be9e0
--- /dev/null
+++ b/lib/common_test/test/ct_error_SUITE_data/error/test/cfg_error_1_SUITE.erl
@@ -0,0 +1,116 @@
+%%
+%% %CopyrightBegin%
+%%
+%% 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(cfg_error_1_SUITE).
+
+-compile(export_all).
+
+-include_lib("common_test/include/ct.hrl").
+
+%%--------------------------------------------------------------------
+%% Function: suite() -> Info
+%% Info = [tuple()]
+%%--------------------------------------------------------------------
+suite() ->
+ [{timetrap,{seconds,3}}].
+
+%%--------------------------------------------------------------------
+%% Function: init_per_suite(Config0) ->
+%% Config1 | {skip,Reason} | {skip_and_save,Reason,Config1}
+%% Config0 = Config1 = [tuple()]
+%% Reason = term()
+%%--------------------------------------------------------------------
+init_per_suite(Config) ->
+ exit(init_per_suite_fails),
+ Config.
+
+%%--------------------------------------------------------------------
+%% Function: end_per_suite(Config0) -> void() | {save_config,Config1}
+%% Config0 = Config1 = [tuple()]
+%%--------------------------------------------------------------------
+end_per_suite(_Config) ->
+ ok.
+
+%%--------------------------------------------------------------------
+%% Function: init_per_group(GroupName, Config0) ->
+%% Config1 | {skip,Reason} | {skip_and_save,Reason,Config1}
+%% GroupName = atom()
+%% Config0 = Config1 = [tuple()]
+%% Reason = term()
+%%--------------------------------------------------------------------
+init_per_group(_GroupName, Config) ->
+ Config.
+
+%%--------------------------------------------------------------------
+%% Function: end_per_group(GroupName, Config0) ->
+%% void() | {save_config,Config1}
+%% GroupName = atom()
+%% Config0 = Config1 = [tuple()]
+%%--------------------------------------------------------------------
+end_per_group(_GroupName, _Config) ->
+ ok.
+
+%%--------------------------------------------------------------------
+%% Function: init_per_testcase(TestCase, Config0) ->
+%% Config1 | {skip,Reason} | {skip_and_save,Reason,Config1}
+%% TestCase = atom()
+%% Config0 = Config1 = [tuple()]
+%% Reason = term()
+%%--------------------------------------------------------------------
+init_per_testcase(_TestCase, Config) ->
+ Config.
+
+%%--------------------------------------------------------------------
+%% Function: end_per_testcase(TestCase, Config0) ->
+%% void() | {save_config,Config1}
+%% TestCase = atom()
+%% Config0 = Config1 = [tuple()]
+%%--------------------------------------------------------------------
+end_per_testcase(_TestCase, _Config) ->
+ ok.
+
+%%--------------------------------------------------------------------
+%% Function: groups() -> [Group]
+%% Group = {GroupName,Properties,GroupsAndTestCases}
+%% GroupName = atom()
+%% Properties = [parallel | sequence | Shuffle | {RepeatType,N}]
+%% GroupsAndTestCases = [Group | {group,GroupName} | TestCase]
+%% TestCase = atom()
+%% Shuffle = shuffle | {shuffle,{integer(),integer(),integer()}}
+%% RepeatType = repeat | repeat_until_all_ok | repeat_until_all_fail |
+%% repeat_until_any_ok | repeat_until_any_fail
+%% N = integer() | forever
+%%--------------------------------------------------------------------
+groups() ->
+ [{g1,[],[tc2]}].
+
+%%--------------------------------------------------------------------
+%% Function: all() -> GroupsAndTestCases | {skip,Reason}
+%% GroupsAndTestCases = [{group,GroupName} | TestCase]
+%% GroupName = atom()
+%% TestCase = atom()
+%% Reason = term()
+%%--------------------------------------------------------------------
+all() ->
+ [tc1,{group,g1}].
+
+tc1(_) ->
+ ok.
+
+tc2(_) ->
+ ok.
diff --git a/lib/common_test/test/ct_error_SUITE_data/error/test/cfg_error_2_SUITE.erl b/lib/common_test/test/ct_error_SUITE_data/error/test/cfg_error_2_SUITE.erl
new file mode 100644
index 0000000000..a02090a5e8
--- /dev/null
+++ b/lib/common_test/test/ct_error_SUITE_data/error/test/cfg_error_2_SUITE.erl
@@ -0,0 +1,117 @@
+%%
+%% %CopyrightBegin%
+%%
+%% 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(cfg_error_2_SUITE).
+
+-compile(export_all).
+
+-include_lib("common_test/include/ct.hrl").
+
+%%--------------------------------------------------------------------
+%% Function: suite() -> Info
+%% Info = [tuple()]
+%%--------------------------------------------------------------------
+suite() ->
+ [{timetrap,{seconds,3}}].
+
+%%--------------------------------------------------------------------
+%% Function: init_per_suite(Config0) ->
+%% Config1 | {skip,Reason} | {skip_and_save,Reason,Config1}
+%% Config0 = Config1 = [tuple()]
+%% Reason = term()
+%%--------------------------------------------------------------------
+init_per_suite(Config) ->
+ ct:comment(init_per_suite_fails),
+ ok = lists:seq(1,2),
+ Config.
+
+%%--------------------------------------------------------------------
+%% Function: end_per_suite(Config0) -> void() | {save_config,Config1}
+%% Config0 = Config1 = [tuple()]
+%%--------------------------------------------------------------------
+end_per_suite(_Config) ->
+ ok.
+
+%%--------------------------------------------------------------------
+%% Function: init_per_group(GroupName, Config0) ->
+%% Config1 | {skip,Reason} | {skip_and_save,Reason,Config1}
+%% GroupName = atom()
+%% Config0 = Config1 = [tuple()]
+%% Reason = term()
+%%--------------------------------------------------------------------
+init_per_group(_GroupName, Config) ->
+ Config.
+
+%%--------------------------------------------------------------------
+%% Function: end_per_group(GroupName, Config0) ->
+%% void() | {save_config,Config1}
+%% GroupName = atom()
+%% Config0 = Config1 = [tuple()]
+%%--------------------------------------------------------------------
+end_per_group(_GroupName, _Config) ->
+ ok.
+
+%%--------------------------------------------------------------------
+%% Function: init_per_testcase(TestCase, Config0) ->
+%% Config1 | {skip,Reason} | {skip_and_save,Reason,Config1}
+%% TestCase = atom()
+%% Config0 = Config1 = [tuple()]
+%% Reason = term()
+%%--------------------------------------------------------------------
+init_per_testcase(_TestCase, Config) ->
+ Config.
+
+%%--------------------------------------------------------------------
+%% Function: end_per_testcase(TestCase, Config0) ->
+%% void() | {save_config,Config1}
+%% TestCase = atom()
+%% Config0 = Config1 = [tuple()]
+%%--------------------------------------------------------------------
+end_per_testcase(_TestCase, _Config) ->
+ ok.
+
+%%--------------------------------------------------------------------
+%% Function: groups() -> [Group]
+%% Group = {GroupName,Properties,GroupsAndTestCases}
+%% GroupName = atom()
+%% Properties = [parallel | sequence | Shuffle | {RepeatType,N}]
+%% GroupsAndTestCases = [Group | {group,GroupName} | TestCase]
+%% TestCase = atom()
+%% Shuffle = shuffle | {shuffle,{integer(),integer(),integer()}}
+%% RepeatType = repeat | repeat_until_all_ok | repeat_until_all_fail |
+%% repeat_until_any_ok | repeat_until_any_fail
+%% N = integer() | forever
+%%--------------------------------------------------------------------
+groups() ->
+ [{g1,[],[tc2]}].
+
+%%--------------------------------------------------------------------
+%% Function: all() -> GroupsAndTestCases | {skip,Reason}
+%% GroupsAndTestCases = [{group,GroupName} | TestCase]
+%% GroupName = atom()
+%% TestCase = atom()
+%% Reason = term()
+%%--------------------------------------------------------------------
+all() ->
+ [tc1,{group,g1}].
+
+tc1(_) ->
+ ok.
+
+tc2(_) ->
+ ok.
diff --git a/lib/common_test/test/ct_error_SUITE_data/error/test/cfg_error_3_SUITE.erl b/lib/common_test/test/ct_error_SUITE_data/error/test/cfg_error_3_SUITE.erl
new file mode 100644
index 0000000000..bf01bb52d9
--- /dev/null
+++ b/lib/common_test/test/ct_error_SUITE_data/error/test/cfg_error_3_SUITE.erl
@@ -0,0 +1,116 @@
+%%
+%% %CopyrightBegin%
+%%
+%% 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(cfg_error_3_SUITE).
+
+-compile(export_all).
+
+-include_lib("common_test/include/ct.hrl").
+
+%%--------------------------------------------------------------------
+%% Function: suite() -> Info
+%% Info = [tuple()]
+%%--------------------------------------------------------------------
+suite() ->
+ [{timetrap,{seconds,2}}].
+
+%%--------------------------------------------------------------------
+%% Function: init_per_suite(Config0) ->
+%% Config1 | {skip,Reason} | {skip_and_save,Reason,Config1}
+%% Config0 = Config1 = [tuple()]
+%% Reason = term()
+%%--------------------------------------------------------------------
+init_per_suite(Config) ->
+ timer:sleep(5000),
+ Config.
+
+%%--------------------------------------------------------------------
+%% Function: end_per_suite(Config0) -> void() | {save_config,Config1}
+%% Config0 = Config1 = [tuple()]
+%%--------------------------------------------------------------------
+end_per_suite(_Config) ->
+ ok.
+
+%%--------------------------------------------------------------------
+%% Function: init_per_group(GroupName, Config0) ->
+%% Config1 | {skip,Reason} | {skip_and_save,Reason,Config1}
+%% GroupName = atom()
+%% Config0 = Config1 = [tuple()]
+%% Reason = term()
+%%--------------------------------------------------------------------
+init_per_group(_GroupName, Config) ->
+ Config.
+
+%%--------------------------------------------------------------------
+%% Function: end_per_group(GroupName, Config0) ->
+%% void() | {save_config,Config1}
+%% GroupName = atom()
+%% Config0 = Config1 = [tuple()]
+%%--------------------------------------------------------------------
+end_per_group(_GroupName, _Config) ->
+ ok.
+
+%%--------------------------------------------------------------------
+%% Function: init_per_testcase(TestCase, Config0) ->
+%% Config1 | {skip,Reason} | {skip_and_save,Reason,Config1}
+%% TestCase = atom()
+%% Config0 = Config1 = [tuple()]
+%% Reason = term()
+%%--------------------------------------------------------------------
+init_per_testcase(_TestCase, Config) ->
+ Config.
+
+%%--------------------------------------------------------------------
+%% Function: end_per_testcase(TestCase, Config0) ->
+%% void() | {save_config,Config1}
+%% TestCase = atom()
+%% Config0 = Config1 = [tuple()]
+%%--------------------------------------------------------------------
+end_per_testcase(_TestCase, _Config) ->
+ ok.
+
+%%--------------------------------------------------------------------
+%% Function: groups() -> [Group]
+%% Group = {GroupName,Properties,GroupsAndTestCases}
+%% GroupName = atom()
+%% Properties = [parallel | sequence | Shuffle | {RepeatType,N}]
+%% GroupsAndTestCases = [Group | {group,GroupName} | TestCase]
+%% TestCase = atom()
+%% Shuffle = shuffle | {shuffle,{integer(),integer(),integer()}}
+%% RepeatType = repeat | repeat_until_all_ok | repeat_until_all_fail |
+%% repeat_until_any_ok | repeat_until_any_fail
+%% N = integer() | forever
+%%--------------------------------------------------------------------
+groups() ->
+ [{g1,[],[tc2]}].
+
+%%--------------------------------------------------------------------
+%% Function: all() -> GroupsAndTestCases | {skip,Reason}
+%% GroupsAndTestCases = [{group,GroupName} | TestCase]
+%% GroupName = atom()
+%% TestCase = atom()
+%% Reason = term()
+%%--------------------------------------------------------------------
+all() ->
+ [tc1,{group,g1}].
+
+tc1(_) ->
+ ok.
+
+tc2(_) ->
+ ok.
diff --git a/lib/common_test/test/ct_error_SUITE_data/error/test/cfg_error_4_SUITE.erl b/lib/common_test/test/ct_error_SUITE_data/error/test/cfg_error_4_SUITE.erl
new file mode 100644
index 0000000000..aaf29df65f
--- /dev/null
+++ b/lib/common_test/test/ct_error_SUITE_data/error/test/cfg_error_4_SUITE.erl
@@ -0,0 +1,115 @@
+%%
+%% %CopyrightBegin%
+%%
+%% 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(cfg_error_4_SUITE).
+
+-compile(export_all).
+
+-include_lib("common_test/include/ct.hrl").
+
+%%--------------------------------------------------------------------
+%% Function: suite() -> Info
+%% Info = [tuple()]
+%%--------------------------------------------------------------------
+suite() ->
+ [{timetrap,{seconds,2}}].
+
+%%--------------------------------------------------------------------
+%% Function: init_per_suite(Config0) ->
+%% Config1 | {skip,Reason} | {skip_and_save,Reason,Config1}
+%% Config0 = Config1 = [tuple()]
+%% Reason = term()
+%%--------------------------------------------------------------------
+init_per_suite(Config) ->
+ ok.
+
+%%--------------------------------------------------------------------
+%% Function: end_per_suite(Config0) -> void() | {save_config,Config1}
+%% Config0 = Config1 = [tuple()]
+%%--------------------------------------------------------------------
+end_per_suite(_Config) ->
+ ok.
+
+%%--------------------------------------------------------------------
+%% Function: init_per_group(GroupName, Config0) ->
+%% Config1 | {skip,Reason} | {skip_and_save,Reason,Config1}
+%% GroupName = atom()
+%% Config0 = Config1 = [tuple()]
+%% Reason = term()
+%%--------------------------------------------------------------------
+init_per_group(_GroupName, Config) ->
+ Config.
+
+%%--------------------------------------------------------------------
+%% Function: end_per_group(GroupName, Config0) ->
+%% void() | {save_config,Config1}
+%% GroupName = atom()
+%% Config0 = Config1 = [tuple()]
+%%--------------------------------------------------------------------
+end_per_group(_GroupName, _Config) ->
+ ok.
+
+%%--------------------------------------------------------------------
+%% Function: init_per_testcase(TestCase, Config0) ->
+%% Config1 | {skip,Reason} | {skip_and_save,Reason,Config1}
+%% TestCase = atom()
+%% Config0 = Config1 = [tuple()]
+%% Reason = term()
+%%--------------------------------------------------------------------
+init_per_testcase(_TestCase, Config) ->
+ Config.
+
+%%--------------------------------------------------------------------
+%% Function: end_per_testcase(TestCase, Config0) ->
+%% void() | {save_config,Config1}
+%% TestCase = atom()
+%% Config0 = Config1 = [tuple()]
+%%--------------------------------------------------------------------
+end_per_testcase(_TestCase, _Config) ->
+ ok.
+
+%%--------------------------------------------------------------------
+%% Function: groups() -> [Group]
+%% Group = {GroupName,Properties,GroupsAndTestCases}
+%% GroupName = atom()
+%% Properties = [parallel | sequence | Shuffle | {RepeatType,N}]
+%% GroupsAndTestCases = [Group | {group,GroupName} | TestCase]
+%% TestCase = atom()
+%% Shuffle = shuffle | {shuffle,{integer(),integer(),integer()}}
+%% RepeatType = repeat | repeat_until_all_ok | repeat_until_all_fail |
+%% repeat_until_any_ok | repeat_until_any_fail
+%% N = integer() | forever
+%%--------------------------------------------------------------------
+groups() ->
+ [{g1,[],[tc2]}].
+
+%%--------------------------------------------------------------------
+%% Function: all() -> GroupsAndTestCases | {skip,Reason}
+%% GroupsAndTestCases = [{group,GroupName} | TestCase]
+%% GroupName = atom()
+%% TestCase = atom()
+%% Reason = term()
+%%--------------------------------------------------------------------
+all() ->
+ [tc1,{group,g1}].
+
+tc1(_) ->
+ ok.
+
+tc2(_) ->
+ ok.
diff --git a/lib/common_test/test/ct_error_SUITE_data/error/test/cfg_error_5_SUITE.erl b/lib/common_test/test/ct_error_SUITE_data/error/test/cfg_error_5_SUITE.erl
new file mode 100644
index 0000000000..b421f7d809
--- /dev/null
+++ b/lib/common_test/test/ct_error_SUITE_data/error/test/cfg_error_5_SUITE.erl
@@ -0,0 +1,115 @@
+%%
+%% %CopyrightBegin%
+%%
+%% 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(cfg_error_5_SUITE).
+
+-compile(export_all).
+
+-include_lib("common_test/include/ct.hrl").
+
+%%--------------------------------------------------------------------
+%% Function: suite() -> Info
+%% Info = [tuple()]
+%%--------------------------------------------------------------------
+suite() ->
+ [{timetrap,{seconds,2}}].
+
+%%--------------------------------------------------------------------
+%% Function: init_per_suite(Config0) ->
+%% Config1 | {skip,Reason} | {skip_and_save,Reason,Config1}
+%% Config0 = Config1 = [tuple()]
+%% Reason = term()
+%%--------------------------------------------------------------------
+init_per_suite(Config) ->
+ [bad_data | Config].
+
+%%--------------------------------------------------------------------
+%% Function: end_per_suite(Config0) -> void() | {save_config,Config1}
+%% Config0 = Config1 = [tuple()]
+%%--------------------------------------------------------------------
+end_per_suite(_Config) ->
+ ok.
+
+%%--------------------------------------------------------------------
+%% Function: init_per_group(GroupName, Config0) ->
+%% Config1 | {skip,Reason} | {skip_and_save,Reason,Config1}
+%% GroupName = atom()
+%% Config0 = Config1 = [tuple()]
+%% Reason = term()
+%%--------------------------------------------------------------------
+init_per_group(_GroupName, Config) ->
+ Config.
+
+%%--------------------------------------------------------------------
+%% Function: end_per_group(GroupName, Config0) ->
+%% void() | {save_config,Config1}
+%% GroupName = atom()
+%% Config0 = Config1 = [tuple()]
+%%--------------------------------------------------------------------
+end_per_group(_GroupName, _Config) ->
+ ok.
+
+%%--------------------------------------------------------------------
+%% Function: init_per_testcase(TestCase, Config0) ->
+%% Config1 | {skip,Reason} | {skip_and_save,Reason,Config1}
+%% TestCase = atom()
+%% Config0 = Config1 = [tuple()]
+%% Reason = term()
+%%--------------------------------------------------------------------
+init_per_testcase(_TestCase, Config) ->
+ Config.
+
+%%--------------------------------------------------------------------
+%% Function: end_per_testcase(TestCase, Config0) ->
+%% void() | {save_config,Config1}
+%% TestCase = atom()
+%% Config0 = Config1 = [tuple()]
+%%--------------------------------------------------------------------
+end_per_testcase(_TestCase, _Config) ->
+ ok.
+
+%%--------------------------------------------------------------------
+%% Function: groups() -> [Group]
+%% Group = {GroupName,Properties,GroupsAndTestCases}
+%% GroupName = atom()
+%% Properties = [parallel | sequence | Shuffle | {RepeatType,N}]
+%% GroupsAndTestCases = [Group | {group,GroupName} | TestCase]
+%% TestCase = atom()
+%% Shuffle = shuffle | {shuffle,{integer(),integer(),integer()}}
+%% RepeatType = repeat | repeat_until_all_ok | repeat_until_all_fail |
+%% repeat_until_any_ok | repeat_until_any_fail
+%% N = integer() | forever
+%%--------------------------------------------------------------------
+groups() ->
+ [{g1,[],[tc2]}].
+
+%%--------------------------------------------------------------------
+%% Function: all() -> GroupsAndTestCases | {skip,Reason}
+%% GroupsAndTestCases = [{group,GroupName} | TestCase]
+%% GroupName = atom()
+%% TestCase = atom()
+%% Reason = term()
+%%--------------------------------------------------------------------
+all() ->
+ [tc1,{group,g1}].
+
+tc1(_) ->
+ ok.
+
+tc2(_) ->
+ ok.
diff --git a/lib/common_test/test/ct_error_SUITE_data/error/test/cfg_error_6_SUITE.erl b/lib/common_test/test/ct_error_SUITE_data/error/test/cfg_error_6_SUITE.erl
new file mode 100644
index 0000000000..370ac0839b
--- /dev/null
+++ b/lib/common_test/test/ct_error_SUITE_data/error/test/cfg_error_6_SUITE.erl
@@ -0,0 +1,116 @@
+%%
+%% %CopyrightBegin%
+%%
+%% 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(cfg_error_6_SUITE).
+
+-compile(export_all).
+
+-include_lib("common_test/include/ct.hrl").
+
+%%--------------------------------------------------------------------
+%% Function: suite() -> Info
+%% Info = [tuple()]
+%%--------------------------------------------------------------------
+suite() ->
+ [{timetrap,{seconds,2}}].
+
+%%--------------------------------------------------------------------
+%% Function: init_per_suite(Config0) ->
+%% Config1 | {skip,Reason} | {skip_and_save,Reason,Config1}
+%% Config0 = Config1 = [tuple()]
+%% Reason = term()
+%%--------------------------------------------------------------------
+init_per_suite(Config) ->
+ Config.
+
+%%--------------------------------------------------------------------
+%% Function: end_per_suite(Config0) -> void() | {save_config,Config1}
+%% Config0 = Config1 = [tuple()]
+%%--------------------------------------------------------------------
+end_per_suite(Config) ->
+ ct:comment("this should fail"),
+ badmatch = lists:seq(1,2).
+
+%%--------------------------------------------------------------------
+%% Function: init_per_group(GroupName, Config0) ->
+%% Config1 | {skip,Reason} | {skip_and_save,Reason,Config1}
+%% GroupName = atom()
+%% Config0 = Config1 = [tuple()]
+%% Reason = term()
+%%--------------------------------------------------------------------
+init_per_group(_GroupName, Config) ->
+ Config.
+
+%%--------------------------------------------------------------------
+%% Function: end_per_group(GroupName, Config0) ->
+%% void() | {save_config,Config1}
+%% GroupName = atom()
+%% Config0 = Config1 = [tuple()]
+%%--------------------------------------------------------------------
+end_per_group(_GroupName, _Config) ->
+ ok.
+
+%%--------------------------------------------------------------------
+%% Function: init_per_testcase(TestCase, Config0) ->
+%% Config1 | {skip,Reason} | {skip_and_save,Reason,Config1}
+%% TestCase = atom()
+%% Config0 = Config1 = [tuple()]
+%% Reason = term()
+%%--------------------------------------------------------------------
+init_per_testcase(_TestCase, Config) ->
+ Config.
+
+%%--------------------------------------------------------------------
+%% Function: end_per_testcase(TestCase, Config0) ->
+%% void() | {save_config,Config1}
+%% TestCase = atom()
+%% Config0 = Config1 = [tuple()]
+%%--------------------------------------------------------------------
+end_per_testcase(_TestCase, _Config) ->
+ ok.
+
+%%--------------------------------------------------------------------
+%% Function: groups() -> [Group]
+%% Group = {GroupName,Properties,GroupsAndTestCases}
+%% GroupName = atom()
+%% Properties = [parallel | sequence | Shuffle | {RepeatType,N}]
+%% GroupsAndTestCases = [Group | {group,GroupName} | TestCase]
+%% TestCase = atom()
+%% Shuffle = shuffle | {shuffle,{integer(),integer(),integer()}}
+%% RepeatType = repeat | repeat_until_all_ok | repeat_until_all_fail |
+%% repeat_until_any_ok | repeat_until_any_fail
+%% N = integer() | forever
+%%--------------------------------------------------------------------
+groups() ->
+ [{g1,[],[tc2]}].
+
+%%--------------------------------------------------------------------
+%% Function: all() -> GroupsAndTestCases | {skip,Reason}
+%% GroupsAndTestCases = [{group,GroupName} | TestCase]
+%% GroupName = atom()
+%% TestCase = atom()
+%% Reason = term()
+%%--------------------------------------------------------------------
+all() ->
+ [tc1,{group,g1}].
+
+tc1(_) ->
+ ok.
+
+tc2(_) ->
+ ok.
diff --git a/lib/common_test/test/ct_error_SUITE_data/error/test/cfg_error_7_SUITE.erl b/lib/common_test/test/ct_error_SUITE_data/error/test/cfg_error_7_SUITE.erl
new file mode 100644
index 0000000000..9cd5b6ad29
--- /dev/null
+++ b/lib/common_test/test/ct_error_SUITE_data/error/test/cfg_error_7_SUITE.erl
@@ -0,0 +1,116 @@
+%%
+%% %CopyrightBegin%
+%%
+%% 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(cfg_error_7_SUITE).
+
+-compile(export_all).
+
+-include_lib("common_test/include/ct.hrl").
+
+%%--------------------------------------------------------------------
+%% Function: suite() -> Info
+%% Info = [tuple()]
+%%--------------------------------------------------------------------
+suite() ->
+ [{timetrap,{seconds,2}}].
+
+%%--------------------------------------------------------------------
+%% Function: init_per_suite(Config0) ->
+%% Config1 | {skip,Reason} | {skip_and_save,Reason,Config1}
+%% Config0 = Config1 = [tuple()]
+%% Reason = term()
+%%--------------------------------------------------------------------
+init_per_suite(Config) ->
+ Config.
+
+%%--------------------------------------------------------------------
+%% Function: end_per_suite(Config0) -> void() | {save_config,Config1}
+%% Config0 = Config1 = [tuple()]
+%%--------------------------------------------------------------------
+end_per_suite(Config) ->
+ timer:sleep(5000),
+ ok.
+
+%%--------------------------------------------------------------------
+%% Function: init_per_group(GroupName, Config0) ->
+%% Config1 | {skip,Reason} | {skip_and_save,Reason,Config1}
+%% GroupName = atom()
+%% Config0 = Config1 = [tuple()]
+%% Reason = term()
+%%--------------------------------------------------------------------
+init_per_group(_GroupName, Config) ->
+ Config.
+
+%%--------------------------------------------------------------------
+%% Function: end_per_group(GroupName, Config0) ->
+%% void() | {save_config,Config1}
+%% GroupName = atom()
+%% Config0 = Config1 = [tuple()]
+%%--------------------------------------------------------------------
+end_per_group(_GroupName, _Config) ->
+ ok.
+
+%%--------------------------------------------------------------------
+%% Function: init_per_testcase(TestCase, Config0) ->
+%% Config1 | {skip,Reason} | {skip_and_save,Reason,Config1}
+%% TestCase = atom()
+%% Config0 = Config1 = [tuple()]
+%% Reason = term()
+%%--------------------------------------------------------------------
+init_per_testcase(_TestCase, Config) ->
+ Config.
+
+%%--------------------------------------------------------------------
+%% Function: end_per_testcase(TestCase, Config0) ->
+%% void() | {save_config,Config1}
+%% TestCase = atom()
+%% Config0 = Config1 = [tuple()]
+%%--------------------------------------------------------------------
+end_per_testcase(_TestCase, _Config) ->
+ ok.
+
+%%--------------------------------------------------------------------
+%% Function: groups() -> [Group]
+%% Group = {GroupName,Properties,GroupsAndTestCases}
+%% GroupName = atom()
+%% Properties = [parallel | sequence | Shuffle | {RepeatType,N}]
+%% GroupsAndTestCases = [Group | {group,GroupName} | TestCase]
+%% TestCase = atom()
+%% Shuffle = shuffle | {shuffle,{integer(),integer(),integer()}}
+%% RepeatType = repeat | repeat_until_all_ok | repeat_until_all_fail |
+%% repeat_until_any_ok | repeat_until_any_fail
+%% N = integer() | forever
+%%--------------------------------------------------------------------
+groups() ->
+ [{g1,[],[tc2]}].
+
+%%--------------------------------------------------------------------
+%% Function: all() -> GroupsAndTestCases | {skip,Reason}
+%% GroupsAndTestCases = [{group,GroupName} | TestCase]
+%% GroupName = atom()
+%% TestCase = atom()
+%% Reason = term()
+%%--------------------------------------------------------------------
+all() ->
+ [tc1,{group,g1}].
+
+tc1(_) ->
+ ok.
+
+tc2(_) ->
+ ok.
diff --git a/lib/common_test/test/ct_error_SUITE_data/error/test/cfg_error_8_SUITE.erl b/lib/common_test/test/ct_error_SUITE_data/error/test/cfg_error_8_SUITE.erl
new file mode 100644
index 0000000000..25993833d7
--- /dev/null
+++ b/lib/common_test/test/ct_error_SUITE_data/error/test/cfg_error_8_SUITE.erl
@@ -0,0 +1,152 @@
+%%
+%% %CopyrightBegin%
+%%
+%% 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(cfg_error_8_SUITE).
+
+-compile(export_all).
+
+-include_lib("common_test/include/ct.hrl").
+
+%%--------------------------------------------------------------------
+%% Function: suite() -> Info
+%% Info = [tuple()]
+%%--------------------------------------------------------------------
+suite() ->
+ [{timetrap,{seconds,2}}].
+
+%%--------------------------------------------------------------------
+%% Function: init_per_suite(Config0) ->
+%% Config1 | {skip,Reason} | {skip_and_save,Reason,Config1}
+%% Config0 = Config1 = [tuple()]
+%% Reason = term()
+%%--------------------------------------------------------------------
+init_per_suite(Config) ->
+ Config.
+
+%%--------------------------------------------------------------------
+%% Function: end_per_suite(Config0) -> void() | {save_config,Config1}
+%% Config0 = Config1 = [tuple()]
+%%--------------------------------------------------------------------
+end_per_suite(_Config) ->
+ ok.
+
+%%--------------------------------------------------------------------
+%% Function: init_per_group(GroupName, Config0) ->
+%% Config1 | {skip,Reason} | {skip_and_save,Reason,Config1}
+%% GroupName = atom()
+%% Config0 = Config1 = [tuple()]
+%% Reason = term()
+%%--------------------------------------------------------------------
+init_per_group(g1, Config) ->
+ exit({init_per_group_fails,g1}),
+ Config;
+init_per_group(g2, Config) ->
+ ct:comment("init_per_group(g2) timeout"),
+ timer:sleep(5000),
+ Config;
+init_per_group(g3, _Config) ->
+ badmatch = 42;
+init_per_group(g4, _Config) ->
+ ok;
+init_per_group(g6, Config) ->
+ exit({sub_group_failed,g6}),
+ Config;
+init_per_group(_, Config) ->
+ Config.
+
+%%--------------------------------------------------------------------
+%% Function: end_per_group(GroupName, Config0) ->
+%% void() | {save_config,Config1}
+%% GroupName = atom()
+%% Config0 = Config1 = [tuple()]
+%%--------------------------------------------------------------------
+end_per_group(g11, _Config) ->
+ exit({end_per_group_fails,g5}),
+ ok;
+end_per_group(g12, _Config) ->
+ ct:comment("end_per_group(g6) timeout"),
+ timer:sleep(5000),
+ ok;
+end_per_group(_GroupName, _Config) ->
+ ok.
+
+%%--------------------------------------------------------------------
+%% Function: init_per_testcase(TestCase, Config0) ->
+%% Config1 | {skip,Reason} | {skip_and_save,Reason,Config1}
+%% TestCase = atom()
+%% Config0 = Config1 = [tuple()]
+%% Reason = term()
+%%--------------------------------------------------------------------
+init_per_testcase(_TestCase, Config) ->
+ Config.
+
+%%--------------------------------------------------------------------
+%% Function: end_per_testcase(TestCase, Config0) ->
+%% void() | {save_config,Config1}
+%% TestCase = atom()
+%% Config0 = Config1 = [tuple()]
+%%--------------------------------------------------------------------
+end_per_testcase(_TestCase, _Config) ->
+ ok.
+
+%%--------------------------------------------------------------------
+%% Function: groups() -> [Group]
+%% Group = {GroupName,Properties,GroupsAndTestCases}
+%% GroupName = atom()
+%% Properties = [parallel | sequence | Shuffle | {RepeatType,N}]
+%% GroupsAndTestCases = [Group | {group,GroupName} | TestCase]
+%% TestCase = atom()
+%% Shuffle = shuffle | {shuffle,{integer(),integer(),integer()}}
+%% RepeatType = repeat | repeat_until_all_ok | repeat_until_all_fail |
+%% repeat_until_any_ok | repeat_until_any_fail
+%% N = integer() | forever
+%%--------------------------------------------------------------------
+groups() ->
+ [{g1,[],[tc1]},
+ {g2,[],[tc1]},
+ {g3,[],[tc1]},
+ {g4,[],[tc1]},
+ {g5,[],[tc1,{g6,[],[tc2]},tc3]},
+ {g11,[],[tc1]},
+ {g12,[],[tc1]}].
+
+%%--------------------------------------------------------------------
+%% Function: all() -> GroupsAndTestCases | {skip,Reason}
+%% GroupsAndTestCases = [{group,GroupName} | TestCase]
+%% GroupName = atom()
+%% TestCase = atom()
+%% Reason = term()
+%%--------------------------------------------------------------------
+all() ->
+ [{group,g1},
+ {group,g2},
+ {group,g3},
+ {group,g4},
+ {group,g5},
+ {group,g11},
+ {group,g12}
+ ].
+
+tc1(_) ->
+ ok.
+
+tc2(_) ->
+ ok.
+
+tc3(_) ->
+ ok.
diff --git a/lib/common_test/test/ct_error_SUITE_data/error/test/cfg_error_9_SUITE.erl b/lib/common_test/test/ct_error_SUITE_data/error/test/cfg_error_9_SUITE.erl
new file mode 100644
index 0000000000..d73287ad62
--- /dev/null
+++ b/lib/common_test/test/ct_error_SUITE_data/error/test/cfg_error_9_SUITE.erl
@@ -0,0 +1,185 @@
+%%
+%% %CopyrightBegin%
+%%
+%% 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(cfg_error_9_SUITE).
+
+-compile(export_all).
+
+-include_lib("common_test/include/ct.hrl").
+
+%%--------------------------------------------------------------------
+%% Function: suite() -> Info
+%% Info = [tuple()]
+%%--------------------------------------------------------------------
+suite() ->
+ [{timetrap,{seconds,2}}].
+
+%%--------------------------------------------------------------------
+%% Function: init_per_suite(Config0) ->
+%% Config1 | {skip,Reason} | {skip_and_save,Reason,Config1}
+%% Config0 = Config1 = [tuple()]
+%% Reason = term()
+%%--------------------------------------------------------------------
+init_per_suite(Config) ->
+ Config.
+
+%%--------------------------------------------------------------------
+%% Function: end_per_suite(Config0) -> void() | {save_config,Config1}
+%% Config0 = Config1 = [tuple()]
+%%--------------------------------------------------------------------
+end_per_suite(Config) ->
+ ok.
+
+%%--------------------------------------------------------------------
+%% Function: init_per_group(GroupName, Config0) ->
+%% Config1 | {skip,Reason} | {skip_and_save,Reason,Config1}
+%% GroupName = atom()
+%% Config0 = Config1 = [tuple()]
+%% Reason = term()
+%%--------------------------------------------------------------------
+init_per_group(_GroupName, Config) ->
+ Config.
+
+%%--------------------------------------------------------------------
+%% Function: end_per_group(GroupName, Config0) ->
+%% void() | {save_config,Config1}
+%% GroupName = atom()
+%% Config0 = Config1 = [tuple()]
+%%--------------------------------------------------------------------
+end_per_group(_GroupName, _Config) ->
+ ok.
+
+%%--------------------------------------------------------------------
+%% Function: init_per_testcase(TestCase, Config0) ->
+%% Config1 | {skip,Reason} | {skip_and_save,Reason,Config1}
+%% TestCase = atom()
+%% Config0 = Config1 = [tuple()]
+%% Reason = term()
+%%--------------------------------------------------------------------
+init_per_testcase(tc1, Config) ->
+ exit(tc1_should_be_skipped),
+ Config;
+init_per_testcase(tc2, Config) ->
+ ct:comment("init_per_testcase(tc2) timeout"),
+ timer:sleep(5000),
+ Config;
+init_per_testcase(tc3, Config) ->
+ badmatch = ?config(void, Config),
+ Config;
+init_per_testcase(tc4, _) ->
+ ok;
+init_per_testcase(_, Config) ->
+ Config.
+
+%%--------------------------------------------------------------------
+%% Function: end_per_testcase(TestCase, Config0) ->
+%% void() | {save_config,Config1}
+%% TestCase = atom()
+%% Config0 = Config1 = [tuple()]
+%%--------------------------------------------------------------------
+end_per_testcase(tc11, _Config) ->
+ ct:comment("A warning should be printed"),
+ exit(warning_should_be_printed),
+ done;
+end_per_testcase(tc12, _Config) ->
+ ct:comment("A warning should be printed"),
+ timer:sleep(5000),
+ done;
+end_per_testcase(tc13, Config) ->
+ ct:comment("A warning should be printed"),
+ badmatch = ?config(void, Config),
+ done;
+end_per_testcase(tc14, Config) ->
+ ok = ?config(tc_status, Config),
+ {fail,tc14_should_be_failed};
+end_per_testcase(tc15, Config) ->
+ {failed,byebye} = ?config(tc_status, Config),
+ ok;
+end_per_testcase(_TestCase, _Config) ->
+ done.
+
+%%--------------------------------------------------------------------
+%% Function: groups() -> [Group]
+%% Group = {GroupName,Properties,GroupsAndTestCases}
+%% GroupName = atom()
+%% Properties = [parallel | sequence | Shuffle | {RepeatType,N}]
+%% GroupsAndTestCases = [Group | {group,GroupName} | TestCase]
+%% TestCase = atom()
+%% Shuffle = shuffle | {shuffle,{integer(),integer(),integer()}}
+%% RepeatType = repeat | repeat_until_all_ok | repeat_until_all_fail |
+%% repeat_until_any_ok | repeat_until_any_fail
+%% N = integer() | forever
+%%--------------------------------------------------------------------
+groups() ->
+ [].
+
+%%--------------------------------------------------------------------
+%% Function: all() -> GroupsAndTestCases | {skip,Reason}
+%% GroupsAndTestCases = [{group,GroupName} | TestCase]
+%% GroupName = atom()
+%% TestCase = atom()
+%% Reason = term()
+%%--------------------------------------------------------------------
+all() ->
+ [tc1,tc2,tc3,tc4,tc5,tc6,
+ tc11,tc12,tc13,tc14].
+
+tc1(_) ->
+ fini.
+tc2(_) ->
+ fini.
+tc3(_) ->
+ fini.
+tc4(_) ->
+ fini.
+
+
+tc5() ->
+ put('$test_server_framework_test',
+ fun(init_tc, _Default) -> {fail,fail_this_testcase};
+ (_, Default) -> Default
+ end),
+ [].
+
+tc5(_) ->
+ ct:comment("This one should get failed by init_tc!"),
+ fini.
+
+tc6() ->
+ put('$test_server_framework_test',
+ fun(end_tc, _Default) -> {fail,fail_this_testcase};
+ (_, Default) -> Default
+ end),
+ [].
+
+tc6(_) ->
+ ct:comment("This one should succeed but then get failed by end_tc!"),
+ fini.
+
+tc11(_) ->
+ fini.
+tc12(_) ->
+ ct:comment("It's ok if this doesn't get printed"),
+ fini.
+tc13(_) ->
+ fini.
+tc14(_) ->
+ ct:comment("This one should be failed by eptc"),
+ yes.
+tc15(_) ->
+ exit(byebye).
diff --git a/lib/common_test/test/ct_error_SUITE_data/error/test/lib_error_1_SUITE.erl b/lib/common_test/test/ct_error_SUITE_data/error/test/lib_error_1_SUITE.erl
new file mode 100644
index 0000000000..6e6f83949d
--- /dev/null
+++ b/lib/common_test/test/ct_error_SUITE_data/error/test/lib_error_1_SUITE.erl
@@ -0,0 +1,188 @@
+%%
+%% %CopyrightBegin%
+%%
+%% 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(lib_error_1_SUITE).
+
+-compile(export_all).
+
+-include_lib("common_test/include/ct.hrl").
+
+%%--------------------------------------------------------------------
+%% Function: suite() -> Info
+%% Info = [tuple()]
+%%--------------------------------------------------------------------
+suite() ->
+ [{timetrap,{seconds,3}}].
+
+%%--------------------------------------------------------------------
+%% Function: init_per_suite(Config0) ->
+%% Config1 | {skip,Reason} | {skip_and_save,Reason,Config1}
+%% Config0 = Config1 = [tuple()]
+%% Reason = term()
+%%--------------------------------------------------------------------
+init_per_suite(Config) ->
+ Config.
+
+%%--------------------------------------------------------------------
+%% Function: end_per_suite(Config0) -> void() | {save_config,Config1}
+%% Config0 = Config1 = [tuple()]
+%%--------------------------------------------------------------------
+end_per_suite(_Config) ->
+ ok.
+
+%%--------------------------------------------------------------------
+%% Function: init_per_group(GroupName, Config0) ->
+%% Config1 | {skip,Reason} | {skip_and_save,Reason,Config1}
+%% GroupName = atom()
+%% Config0 = Config1 = [tuple()]
+%% Reason = term()
+%%--------------------------------------------------------------------
+init_per_group(_GroupName, Config) ->
+ Config.
+
+%%--------------------------------------------------------------------
+%% Function: end_per_group(GroupName, Config0) ->
+%% void() | {save_config,Config1}
+%% GroupName = atom()
+%% Config0 = Config1 = [tuple()]
+%%--------------------------------------------------------------------
+end_per_group(_GroupName, _Config) ->
+ ok.
+
+%%--------------------------------------------------------------------
+%% Function: init_per_testcase(TestCase, Config0) ->
+%% Config1 | {skip,Reason} | {skip_and_save,Reason,Config1}
+%% TestCase = atom()
+%% Config0 = Config1 = [tuple()]
+%% Reason = term()
+%%--------------------------------------------------------------------
+init_per_testcase(_TestCase, Config) ->
+ Config.
+
+%%--------------------------------------------------------------------
+%% Function: end_per_testcase(TestCase, Config0) ->
+%% void() | {save_config,Config1}
+%% TestCase = atom()
+%% Config0 = Config1 = [tuple()]
+%%--------------------------------------------------------------------
+end_per_testcase(_TestCase, _Config) ->
+ ok.
+
+%%--------------------------------------------------------------------
+%% Function: groups() -> [Group]
+%% Group = {GroupName,Properties,GroupsAndTestCases}
+%% GroupName = atom()
+%% Properties = [parallel | sequence | Shuffle | {RepeatType,N}]
+%% GroupsAndTestCases = [Group | {group,GroupName} | TestCase]
+%% TestCase = atom()
+%% Shuffle = shuffle | {shuffle,{integer(),integer(),integer()}}
+%% RepeatType = repeat | repeat_until_all_ok | repeat_until_all_fail |
+%% repeat_until_any_ok | repeat_until_any_fail
+%% N = integer() | forever
+%%--------------------------------------------------------------------
+groups() ->
+ [].
+
+%%--------------------------------------------------------------------
+%% Function: all() -> GroupsAndTestCases | {skip,Reason}
+%% GroupsAndTestCases = [{group,GroupName} | TestCase]
+%% GroupName = atom()
+%% TestCase = atom()
+%% Reason = term()
+%%--------------------------------------------------------------------
+all() ->
+ [lines_error, lines_exit, lines_hang, lines_throw,
+ no_lines_error, no_lines_exit, no_lines_hang, no_lines_throw,
+ init_tc_error, init_tc_exit, init_tc_throw,
+ end_tc_error, end_tc_exit, end_tc_throw].
+
+lines_error(_) ->
+ io:format("Calling lib function..."),
+ lib_lines:do_error(),
+ ok.
+
+lines_exit(_) ->
+ io:format("Calling lib function..."),
+ lib_lines:do_exit(),
+ ok.
+
+lines_hang(_) ->
+ io:format("Calling lib function..."),
+ lib_lines:do_hang(),
+ ok.
+
+lines_throw(_) ->
+ io:format("Calling lib function..."),
+ lib_lines:do_throw(),
+ ok.
+
+no_lines_error(_) ->
+ io:format("Calling lib function..."),
+ lib_no_lines:do_error(),
+ ok.
+
+no_lines_exit(_) ->
+ io:format("Calling lib function..."),
+ lib_no_lines:do_exit(),
+ ok.
+
+no_lines_hang(_) ->
+ io:format("Calling lib function..."),
+ lib_no_lines:do_hang(),
+ ok.
+
+no_lines_throw(_) ->
+ io:format("Calling lib function..."),
+ lib_no_lines:do_throw(),
+ ok.
+
+init_tc_error(_) ->
+ put('$test_server_framework_test',
+ fun(init_tc, _Default) -> lib_no_lines:do_error(), ok;
+ (_, Default) -> Default
+ end), ok.
+
+init_tc_exit(_) ->
+ put('$test_server_framework_test',
+ fun(init_tc, _Default) -> lib_no_lines:do_exit(), ok;
+ (_, Default) -> Default
+ end), ok.
+
+init_tc_throw(_) ->
+ put('$test_server_framework_test',
+ fun(init_tc, _Default) -> lib_no_lines:do_throw(), ok;
+ (_, Default) -> Default
+ end), ok.
+
+end_tc_error(_) ->
+ put('$test_server_framework_test',
+ fun(end_tc, _Default) -> lib_no_lines:do_error(), ok;
+ (_, Default) -> Default
+ end), ok.
+
+end_tc_exit(_) ->
+ put('$test_server_framework_test',
+ fun(end_tc, _Default) -> lib_no_lines:do_exit(), ok;
+ (_, Default) -> Default
+ end), ok.
+
+end_tc_throw(_) ->
+ put('$test_server_framework_test',
+ fun(end_tc, _Default) -> lib_no_lines:do_throw(), ok;
+ (_, Default) -> Default
+ end), ok.
diff --git a/lib/common_test/test/ct_error_SUITE_data/error/test/lib_lines.erl b/lib/common_test/test/ct_error_SUITE_data/error/test/lib_lines.erl
new file mode 100644
index 0000000000..b8f5814004
--- /dev/null
+++ b/lib/common_test/test/ct_error_SUITE_data/error/test/lib_lines.erl
@@ -0,0 +1,25 @@
+-module(lib_lines).
+
+-export([do_error/0, do_exit/0, do_hang/0, do_throw/0]).
+
+-include("ct.hrl").
+
+do_error() ->
+ io:format("Here comes an error...~n"),
+ [] = lists:seq(1,2),
+ ok.
+
+do_exit() ->
+ io:format("Here comes an exit...~n"),
+ exit(byebye),
+ ok.
+
+do_hang() ->
+ io:format("Here comes a hang...~n"),
+ receive after infinity -> ok end,
+ ok.
+
+do_throw() ->
+ io:format("Here comes a throw...~n"),
+ throw(catch_me_if_u_can),
+ ok.
diff --git a/lib/common_test/test/ct_error_SUITE_data/error/test/lib_no_lines.erl b/lib/common_test/test/ct_error_SUITE_data/error/test/lib_no_lines.erl
new file mode 100644
index 0000000000..4d2b08be03
--- /dev/null
+++ b/lib/common_test/test/ct_error_SUITE_data/error/test/lib_no_lines.erl
@@ -0,0 +1,23 @@
+-module(lib_no_lines).
+
+-export([do_error/0, do_exit/0, do_hang/0, do_throw/0]).
+
+do_error() ->
+ io:format("Here comes a badmatch error...~n"),
+ [] = lists:seq(1,2),
+ ok.
+
+do_exit() ->
+ io:format("Here comes a byebye exit...~n"),
+ exit(byebye),
+ ok.
+
+do_hang() ->
+ io:format("Here comes a hang...~n"),
+ receive after infinity -> ok end,
+ ok.
+
+do_throw() ->
+ io:format("Here comes a throw...~n"),
+ throw(catch_me_if_u_can),
+ ok.
diff --git a/lib/common_test/test/ct_error_SUITE_data/error/test/no_compile_SUITE.erl b/lib/common_test/test/ct_error_SUITE_data/error/test/no_compile_SUITE.erl
new file mode 100644
index 0000000000..534a8f34af
--- /dev/null
+++ b/lib/common_test/test/ct_error_SUITE_data/error/test/no_compile_SUITE.erl
@@ -0,0 +1,115 @@
+%%
+%% %CopyrightBegin%
+%%
+%% 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(no_compile_SUITE).
+
+-compile(export_all).
+
+-include("ct.hrl")
+
+%%--------------------------------------------------------------------
+%% Function: suite() -> Info
+%% Info = [tuple()]
+%%--------------------------------------------------------------------
+suite() ->
+ [{timetrap,{seconds,2}}].
+
+%%--------------------------------------------------------------------
+%% Function: init_per_suite(Config0) ->
+%% Config1 | {skip,Reason} | {skip_and_save,Reason,Config1}
+%% Config0 = Config1 = [tuple()]
+%% Reason = term()
+%%--------------------------------------------------------------------
+init_per_suite(Config) ->
+ Config.
+
+%%--------------------------------------------------------------------
+%% Function: end_per_suite(Config0) -> void() | {save_config,Config1}
+%% Config0 = Config1 = [tuple()]
+%%--------------------------------------------------------------------
+end_per_suite(_Config) ->
+ ok.
+
+%%--------------------------------------------------------------------
+%% Function: init_per_group(GroupName, Config0) ->
+%% Config1 | {skip,Reason} | {skip_and_save,Reason,Config1}
+%% GroupName = atom()
+%% Config0 = Config1 = [tuple()]
+%% Reason = term()
+%%--------------------------------------------------------------------
+init_per_group(_GroupName, Config) ->
+ Config.
+
+%%--------------------------------------------------------------------
+%% Function: end_per_group(GroupName, Config0) ->
+%% void() | {save_config,Config1}
+%% GroupName = atom()
+%% Config0 = Config1 = [tuple()]
+%%--------------------------------------------------------------------
+end_per_group(_GroupName, _Config) ->
+ ok.
+
+%%--------------------------------------------------------------------
+%% Function: init_per_testcase(TestCase, Config0) ->
+%% Config1 | {skip,Reason} | {skip_and_save,Reason,Config1}
+%% TestCase = atom()
+%% Config0 = Config1 = [tuple()]
+%% Reason = term()
+%%--------------------------------------------------------------------
+init_per_testcase(_TestCase, Config) ->
+ Config.
+
+%%--------------------------------------------------------------------
+%% Function: end_per_testcase(TestCase, Config0) ->
+%% void() | {save_config,Config1}
+%% TestCase = atom()
+%% Config0 = Config1 = [tuple()]
+%%--------------------------------------------------------------------
+end_per_testcase(_TestCase, _Config) ->
+ ok.
+
+%%--------------------------------------------------------------------
+%% Function: groups() -> [Group]
+%% Group = {GroupName,Properties,GroupsAndTestCases}
+%% GroupName = atom()
+%% Properties = [parallel | sequence | Shuffle | {RepeatType,N}]
+%% GroupsAndTestCases = [Group | {group,GroupName} | TestCase]
+%% TestCase = atom()
+%% Shuffle = shuffle | {shuffle,{integer(),integer(),integer()}}
+%% RepeatType = repeat | repeat_until_all_ok | repeat_until_all_fail |
+%% repeat_until_any_ok | repeat_until_any_fail
+%% N = integer() | forever
+%%--------------------------------------------------------------------
+groups() ->
+ [{g1,[],[tc2]}].
+
+%%--------------------------------------------------------------------
+%% Function: all() -> GroupsAndTestCases | {skip,Reason}
+%% GroupsAndTestCases = [{group,GroupName} | TestCase]
+%% GroupName = atom()
+%% TestCase = atom()
+%% Reason = term()
+%%--------------------------------------------------------------------
+all() ->
+ [tc1,{group,g1}].
+
+tc1(_) ->
+ ok.
+
+tc2(_) ->
+ ok.
diff --git a/lib/common_test/test/ct_event_handler_SUITE.erl b/lib/common_test/test/ct_event_handler_SUITE.erl
new file mode 100644
index 0000000000..bafd32f937
--- /dev/null
+++ b/lib/common_test/test/ct_event_handler_SUITE.erl
@@ -0,0 +1,170 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 2008-2010. All Rights Reserved.
+%%
+%% The contents of this file are subject to the Erlang Public License,
+%% Version 1.1, (the "License"); you may not use this file except in
+%% compliance with the License. You should have received a copy of the
+%% Erlang Public License along with this software. If not, it can be
+%% retrieved online at http://www.erlang.org/.
+%%
+%% Software distributed under the License is distributed on an "AS IS"
+%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+%% the License for the specific language governing rights and limitations
+%% under the License.
+%%
+%% %CopyrightEnd%
+%%
+
+%%%-------------------------------------------------------------------
+%%% File: ct_event_handler_SUITE.erl
+%%%
+%%% Description: This suite will install event handlers and run
+%%% some simple tests to check that events are generated according
+%%% to the specification (see Event Handling in CT User's Guide).
+%%%-------------------------------------------------------------------
+-module(ct_event_handler_SUITE).
+
+-compile(export_all).
+
+-include_lib("test_server/include/test_server.hrl").
+
+%-include_lib("common_test/include/ct_event.hrl").
+
+%%--------------------------------------------------------------------
+%% TEST SERVER CALLBACK FUNCTIONS
+%%--------------------------------------------------------------------
+
+init_per_suite(Config) ->
+ DataDir = ?config(data_dir, Config),
+ PrivDir = ?config(priv_dir, Config),
+
+ EH = filename:join(DataDir, "eh_A.erl"),
+ CResult = compile:file(EH, [verbose,report,{outdir,PrivDir}]),
+ test_server:format("~s compilation result: ~p~n", [EH,CResult]),
+
+ Config1 = ct_test_support:init_per_suite(Config, 0),
+ Config1.
+
+end_per_suite(Config) ->
+ ct_test_support:end_per_suite(Config).
+
+init_per_testcase(TestCase, Config) ->
+ ct_test_support:init_per_testcase(TestCase, Config).
+
+end_per_testcase(TestCase, Config) ->
+ ct_test_support:end_per_testcase(TestCase, Config).
+
+all(doc) ->
+ [];
+
+all(suite) ->
+ [start_stop, results].
+
+
+%%--------------------------------------------------------------------
+%% TEST CASES
+%%--------------------------------------------------------------------
+
+start_stop(doc) ->
+ [];
+
+start_stop(suite) ->
+ [];
+
+start_stop(Config) when is_list(Config) ->
+ DataDir = ?config(data_dir, Config),
+
+ TestObj = filename:join(DataDir, "event_handling_1"),
+ Suite1 = filename:join(TestObj, "test/eh_11_SUITE"),
+ Opts0 = ct_test_support:get_opts(Config),
+
+ Level = ?config(trace_level, Config),
+ EvHArgs = [{cbm,ct_test_support},{trace_level,Level}],
+
+ Opts = Opts0 ++ [{suite,Suite1},{testcase,tc1},
+ {event_handler,{eh_A,EvHArgs}}],
+
+ ERPid = ct_test_support:start_event_receiver(Config),
+
+ ok = ct_test_support:run(ct, run_test, [Opts], Config),
+
+ Events = ct_test_support:get_events(ERPid, Config),
+
+ ct_test_support:log_events(start_stop,
+ ct_test_support:reformat(Events, eh_A),
+ ?config(priv_dir, Config)),
+
+ TestEvents =
+ [{eh_A,start_logging,{'DEF','RUNDIR'}},
+ {eh_A,test_start,{'DEF',{'START_TIME','LOGDIR'}}},
+ {eh_A,start_info,{1,1,1}},
+ {eh_A,tc_start,{eh_11_SUITE,init_per_suite}},
+ {eh_A,tc_done,{eh_11_SUITE,init_per_suite,ok}},
+ {eh_A,tc_start,{eh_11_SUITE,tc1}},
+ {eh_A,tc_done,{eh_11_SUITE,tc1,ok}},
+ {eh_A,test_stats,{1,0,{0,0}}},
+ {eh_A,tc_start,{eh_11_SUITE,end_per_suite}},
+ {eh_A,tc_done,{eh_11_SUITE,end_per_suite,ok}},
+ {eh_A,test_done,{'DEF','STOP_TIME'}},
+ {eh_A,stop_logging,[]}],
+
+ ok = ct_test_support:verify_events(TestEvents, Events, Config),
+ {comment,"NOTE! Known problem with test_start event!"}.
+
+
+results(doc) ->
+ [];
+
+results(suite) ->
+ [];
+
+results(Config) when is_list(Config) ->
+ DataDir = ?config(data_dir, Config),
+
+ TestObj = filename:join(DataDir, "event_handling_1"),
+ Suite1 = filename:join(TestObj, "test/eh_11_SUITE"),
+ Opts0 = ct_test_support:get_opts(Config),
+
+ Level = ?config(trace_level, Config),
+ EvHArgs = [{cbm,ct_test_support},{trace_level,Level}],
+
+ Opts = Opts0 ++ [{suite,Suite1},
+ {event_handler,{eh_A,EvHArgs}}],
+
+ ERPid = ct_test_support:start_event_receiver(Config),
+
+ ok = ct_test_support:run(ct, run_test, [Opts], Config),
+
+ Events = ct_test_support:get_events(ERPid, Config),
+
+ ct_test_support:log_events(results,
+ ct_test_support:reformat(Events, eh_A),
+ ?config(priv_dir, Config)),
+
+ TestEvents =
+ [{eh_A,start_logging,{'DEF','RUNDIR'}},
+ {eh_A,test_start,{'DEF',{'START_TIME','LOGDIR'}}},
+ {eh_A,start_info,{1,1,3}},
+ {eh_A,tc_start,{eh_11_SUITE,init_per_suite}},
+ {eh_A,tc_done,{eh_11_SUITE,init_per_suite,ok}},
+ {eh_A,tc_start,{eh_11_SUITE,tc1}},
+ {eh_A,tc_done,{eh_11_SUITE,tc1,ok}},
+ {eh_A,test_stats,{1,0,{0,0}}},
+ {eh_A,tc_start,{eh_11_SUITE,tc2}},
+ {eh_A,tc_done,{eh_11_SUITE,tc2,{skipped,"Skipped"}}},
+ {eh_A,test_stats,{1,0,{1,0}}},
+ {eh_A,tc_start,{eh_11_SUITE,tc3}},
+ {eh_A,tc_done,{eh_11_SUITE,tc3,{failed,{error,'Failing'}}}},
+ {eh_A,test_stats,{1,1,{1,0}}},
+ {eh_A,tc_start,{eh_11_SUITE,end_per_suite}},
+ {eh_A,tc_done,{eh_11_SUITE,end_per_suite,ok}},
+ {eh_A,test_done,{'DEF','STOP_TIME'}},
+ {eh_A,stop_logging,[]}],
+
+ ok = ct_test_support:verify_events(TestEvents, Events, Config).
+
+
+%%%-----------------------------------------------------------------
+%%% HELP FUNCTIONS
diff --git a/lib/common_test/test/ct_event_handler_SUITE_data/eh_A.erl b/lib/common_test/test/ct_event_handler_SUITE_data/eh_A.erl
new file mode 100644
index 0000000000..6e526f15a2
--- /dev/null
+++ b/lib/common_test/test/ct_event_handler_SUITE_data/eh_A.erl
@@ -0,0 +1,127 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 2008-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%
+%%
+
+%%% @doc Event handler module
+%%%
+%%% <p>This is an event handler module used for testing that
+%%% Common Test generates events as expected.</p>
+%%%
+-module(eh_A).
+
+-behaviour(gen_event).
+
+-include_lib("test_server/include/test_server.hrl").
+-include_lib("common_test/include/ct_event.hrl").
+
+%% gen_event callbacks
+-export([init/1, handle_event/2, handle_call/2,
+ handle_info/2, terminate/2, code_change/3]).
+
+-record(state, {cbm=ct_test_support,
+ trace_level=50}).
+
+%%====================================================================
+%% gen_event callbacks
+%%====================================================================
+%%--------------------------------------------------------------------
+%% Function: init(Args) -> {ok, State}
+%% Description: Whenever a new event handler is added to an event manager,
+%% this function is called to initialize the event handler.
+%%--------------------------------------------------------------------
+init(Args) ->
+
+ S1 = case lists:keysearch(cbm, 1, Args) of
+ {_,{cbm,CBM}} ->
+ #state{cbm=CBM};
+ _ ->
+ #state{}
+ end,
+ S2 = case lists:keysearch(trace_level, 1, Args) of
+ {_,{trace_level,Level}} ->
+ S1#state{trace_level=Level};
+ _ ->
+ S1
+ end,
+ print(S2#state.trace_level, "Event Handler ~w started!~n", [?MODULE]),
+ {ok,S2}.
+
+%%--------------------------------------------------------------------
+%% Function:
+%% handle_event(Event, State) -> {ok, State} |
+%% {swap_handler, Args1, State1, Mod2, Args2} |
+%% remove_handler
+%% Description:Whenever an event manager receives an event sent using
+%% gen_event:notify/2 or gen_event:sync_notify/2, this function is called for
+%% each installed event handler to handle the event.
+%%--------------------------------------------------------------------
+handle_event(Event, State=#state{cbm=CBM, trace_level=_Level}) ->
+ % print(_Level, "~p: ~p~n", [Event#event.name,Event#event.data]),
+ CBM:handle_event(?MODULE, Event),
+ {ok,State}.
+
+%%--------------------------------------------------------------------
+%% Function:
+%% handle_call(Request, State) -> {ok, Reply, State} |
+%% {swap_handler, Reply, Args1, State1,
+%% Mod2, Args2} |
+%% {remove_handler, Reply}
+%% Description: Whenever an event manager receives a request sent using
+%% gen_event:call/3,4, this function is called for the specified event
+%% handler to handle the request.
+%%--------------------------------------------------------------------
+handle_call(_Req, State) ->
+ Reply = ok,
+ {ok, Reply, State}.
+
+%%--------------------------------------------------------------------
+%% Function:
+%% handle_info(Info, State) -> {ok, State} |
+%% {swap_handler, Args1, State1, Mod2, Args2} |
+%% remove_handler
+%% Description: This function is called for each installed event handler when
+%% an event manager receives any other message than an event or a synchronous
+%% request (or a system message).
+%%--------------------------------------------------------------------
+handle_info(_Info, State) ->
+ {ok, State}.
+
+%%--------------------------------------------------------------------
+%% Function: terminate(Reason, State) -> void()
+%% Description:Whenever an event handler is deleted from an event manager,
+%% this function is called. It should be the opposite of Module:init/1 and
+%% do any necessary cleaning up.
+%%--------------------------------------------------------------------
+terminate(_Reason, _State) ->
+ ok.
+
+%%--------------------------------------------------------------------
+%% Function: code_change(OldVsn, State, Extra) -> {ok, NewState}
+%% Description: Convert process state when code is changed
+%%--------------------------------------------------------------------
+code_change(_OldVsn, State, _Extra) ->
+ {ok, State}.
+
+%%--------------------------------------------------------------------
+%%% Internal functions
+%%--------------------------------------------------------------------
+
+print(Level, _Str, _Args) ->
+ test_server:format(Level, _Str,_Args).
+
+
diff --git a/lib/common_test/test/ct_event_handler_SUITE_data/event_handling_1/test/eh_11_SUITE.erl b/lib/common_test/test/ct_event_handler_SUITE_data/event_handling_1/test/eh_11_SUITE.erl
new file mode 100644
index 0000000000..16b7129993
--- /dev/null
+++ b/lib/common_test/test/ct_event_handler_SUITE_data/event_handling_1/test/eh_11_SUITE.erl
@@ -0,0 +1,141 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 2008-2010. All Rights Reserved.
+%%
+%% The contents of this file are subject to the Erlang Public License,
+%% Version 1.1, (the "License"); you may not use this file except in
+%% compliance with the License. You should have received a copy of the
+%% Erlang Public License along with this software. If not, it can be
+%% retrieved online at http://www.erlang.org/.
+%%
+%% Software distributed under the License is distributed on an "AS IS"
+%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+%% the License for the specific language governing rights and limitations
+%% under the License.
+%%
+%% %CopyrightEnd%
+%%
+
+%%%-------------------------------------------------------------------
+%%% File : eh_11_SUITE.erl
+%%% Description : Used by ct_event_handler_SUITE to test event handling.
+%%%-------------------------------------------------------------------
+-module(eh_11_SUITE).
+
+%% Note: This directive should only be used in test suites.
+-compile(export_all).
+
+-include_lib("common_test/include/ct.hrl").
+
+%%--------------------------------------------------------------------
+%% COMMON TEST CALLBACK FUNCTIONS
+%%--------------------------------------------------------------------
+
+%%--------------------------------------------------------------------
+%% Function: suite() -> Info
+%%
+%% Info = [tuple()]
+%% List of key/value pairs.
+%%
+%% Description: Returns list of tuples to set default properties
+%% for the suite.
+%%
+%% Note: The suite/0 function is only meant to be used to return
+%% default data values, not perform any other operations.
+%%--------------------------------------------------------------------
+suite() ->
+ [
+ {timetrap,{seconds,10}}
+ ].
+
+%%--------------------------------------------------------------------
+%% Function: init_per_suite(Config0) ->
+%% Config1 | {skip,Reason} | {skip_and_save,Reason,Config1}
+%%
+%% Config0 = Config1 = [tuple()]
+%% A list of key/value pairs, holding the test case configuration.
+%% Reason = term()
+%% The reason for skipping the suite.
+%%
+%% Description: Initialization before the 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) ->
+ Config.
+
+%%--------------------------------------------------------------------
+%% Function: end_per_suite(Config0) -> void() | {save_config,Config1}
+%%
+%% Config0 = Config1 = [tuple()]
+%% A list of key/value pairs, holding the test case configuration.
+%%
+%% Description: Cleanup after the suite.
+%%--------------------------------------------------------------------
+end_per_suite(_Config) ->
+ ok.
+
+%%--------------------------------------------------------------------
+%% Function: init_per_testcase(TestCase, Config0) ->
+%% Config1 | {skip,Reason} | {skip_and_save,Reason,Config1}
+%%
+%% TestCase = atom()
+%% Name of the test case that is about to run.
+%% Config0 = Config1 = [tuple()]
+%% A list of key/value pairs, holding the test case configuration.
+%% Reason = term()
+%% The reason for skipping the test case.
+%%
+%% 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.
+%%--------------------------------------------------------------------
+init_per_testcase(_TestCase, Config) ->
+ Config.
+
+%%--------------------------------------------------------------------
+%% Function: end_per_testcase(TestCase, Config0) ->
+%% void() | {save_config,Config1}
+%%
+%% TestCase = atom()
+%% Name of the test case that is finished.
+%% Config0 = Config1 = [tuple()]
+%% A list of key/value pairs, holding the test case configuration.
+%%
+%% Description: Cleanup after each test case.
+%%--------------------------------------------------------------------
+end_per_testcase(_TestCase, _Config) ->
+ ok.
+
+%%--------------------------------------------------------------------
+%% Function: all() -> TestCases | {skip,Reason}
+%%
+%% TestCases = [TestCase | {sequence,SeqName}]
+%% TestCase = atom()
+%% Name of a test case.
+%% SeqName = atom()
+%% Name of a test case sequence.
+%% Reason = term()
+%% The reason for skipping all test cases.
+%%
+%% Description: Returns the list of test cases that are to be executed.
+%%--------------------------------------------------------------------
+all() ->
+ [tc1, tc2, tc3].
+
+
+%%--------------------------------------------------------------------
+%% TEST CASES
+%%--------------------------------------------------------------------
+
+tc1(_Config) ->
+ ok.
+
+tc2(_Config) ->
+ {skip,"Skipped"}.
+
+tc3(_Config) ->
+ exit('Failing').
diff --git a/lib/common_test/test/ct_groups_test_1_SUITE.erl b/lib/common_test/test/ct_groups_test_1_SUITE.erl
new file mode 100644
index 0000000000..1761b773f5
--- /dev/null
+++ b/lib/common_test/test/ct_groups_test_1_SUITE.erl
@@ -0,0 +1,1226 @@
+%%
+%% %CopyrightBegin%
+%%
+%% 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%
+%%
+
+%%%-------------------------------------------------------------------
+%%% File: ct_groups_test_1_SUITE
+%%%
+%%% Description:
+%%% Test some simple test case group scenarios.
+%%%
+%%% The suites used for the test are located in the data directory.
+%%%-------------------------------------------------------------------
+-module(ct_groups_test_1_SUITE).
+
+-compile(export_all).
+
+-include_lib("test_server/include/test_server.hrl").
+-include_lib("common_test/include/ct_event.hrl").
+
+-define(eh, ct_test_support_eh).
+
+%%--------------------------------------------------------------------
+%% TEST SERVER CALLBACK FUNCTIONS
+%%--------------------------------------------------------------------
+
+%%--------------------------------------------------------------------
+%% Description: Since Common Test starts another Test Server
+%% instance, the tests need to be performed on a separate node (or
+%% there will be clashes with logging processes etc).
+%%--------------------------------------------------------------------
+init_per_suite(Config) ->
+ Config1 = ct_test_support:init_per_suite(Config),
+ Config1.
+
+end_per_suite(Config) ->
+ ct_test_support:end_per_suite(Config).
+
+init_per_testcase(TestCase, Config) ->
+ ct_test_support:init_per_testcase(TestCase, Config).
+
+end_per_testcase(TestCase, Config) ->
+ ct_test_support:end_per_testcase(TestCase, Config).
+
+all(doc) ->
+ ["Run smoke tests of Common Test."];
+
+all(suite) ->
+ [groups_suite_1, groups_suite_2,
+ groups_suites_1, groups_dir_1, groups_dirs_1].
+
+%%--------------------------------------------------------------------
+%% TEST CASES
+%%--------------------------------------------------------------------
+
+%%%-----------------------------------------------------------------
+%%%
+
+groups_suite_1(Config) when is_list(Config) ->
+ DataDir = ?config(data_dir, Config),
+
+ Suite = filename:join(DataDir, "groups_1/test/groups_11_SUITE"),
+
+ {Opts,ERPid} = setup({suite,Suite}, Config),
+ ok = ct_test_support:run(ct, run_test, [Opts], Config),
+ Events = ct_test_support:get_events(ERPid, Config),
+
+ ct_test_support:log_events(groups_suite_1,
+ reformat(Events, ?eh),
+ ?config(priv_dir, Config)),
+
+ TestEvents = test_events(groups_suite_1),
+ ok = ct_test_support:verify_events(TestEvents, Events, Config).
+
+
+%%%-----------------------------------------------------------------
+%%%
+
+groups_suite_2(Config) when is_list(Config) ->
+ DataDir = ?config(data_dir, Config),
+
+ Suite = filename:join(DataDir, "groups_1/test/groups_12_SUITE"),
+
+ {Opts,ERPid} = setup({suite,Suite}, Config),
+ ok = ct_test_support:run(ct, run_test, [Opts], Config),
+ Events = ct_test_support:get_events(ERPid, Config),
+
+ ct_test_support:log_events(groups_suite_2,
+ reformat(Events, ?eh),
+ ?config(priv_dir, Config)),
+
+ TestEvents = test_events(groups_suite_2),
+ ok = ct_test_support:verify_events(TestEvents, Events, Config).
+
+
+%%%-----------------------------------------------------------------
+%%%
+
+groups_suites_1(Config) when is_list(Config) ->
+ DataDir = ?config(data_dir, Config),
+
+ Suites = [filename:join(DataDir, "groups_1/test/groups_11_SUITE"),
+ filename:join(DataDir, "groups_1/test/groups_12_SUITE")],
+
+ {Opts,ERPid} = setup({suite,Suites}, Config),
+ ok = ct_test_support:run(ct, run_test, [Opts], Config),
+ Events = ct_test_support:get_events(ERPid, Config),
+
+ ct_test_support:log_events(groups_suites_1,
+ reformat(Events, ?eh),
+ ?config(priv_dir, Config)),
+
+ TestEvents = test_events(groups_suites_1),
+ ok = ct_test_support:verify_events(TestEvents, Events, Config).
+
+
+%%%-----------------------------------------------------------------
+%%%
+
+groups_dir_1(Config) when is_list(Config) ->
+ DataDir = ?config(data_dir, Config),
+
+ Dir = filename:join(DataDir, "groups_1"),
+
+ {Opts,ERPid} = setup({dir,Dir}, Config),
+ ok = ct_test_support:run(ct, run_test, [Opts], Config),
+ Events = ct_test_support:get_events(ERPid, Config),
+
+ ct_test_support:log_events(groups_dir_1,
+ reformat(Events, ?eh),
+ ?config(priv_dir, Config)),
+
+ TestEvents = test_events(groups_dir_1),
+ ok = ct_test_support:verify_events(TestEvents, Events, Config).
+
+%%%-----------------------------------------------------------------
+%%%
+
+groups_dirs_1(Config) when is_list(Config) ->
+ DataDir = ?config(data_dir, Config),
+
+ Dirs = [filename:join(DataDir, "groups_1"),
+ filename:join(DataDir, "groups_2")],
+
+ {Opts,ERPid} = setup({dir,Dirs}, Config),
+ ok = ct_test_support:run(ct, run_test, [Opts], Config),
+ Events = ct_test_support:get_events(ERPid, Config),
+
+ ct_test_support:log_events(groups_dirs_1,
+ reformat(Events, ?eh),
+ ?config(priv_dir, Config)),
+
+ TestEvents = test_events(groups_dirs_1),
+ ok = ct_test_support:verify_events(TestEvents, Events, Config).
+
+
+%%%-----------------------------------------------------------------
+%%% HELP FUNCTIONS
+%%%-----------------------------------------------------------------
+
+setup(Test, Config) ->
+ Opts0 = ct_test_support:get_opts(Config),
+ Level = ?config(trace_level, Config),
+ EvHArgs = [{cbm,ct_test_support},{trace_level,Level}],
+ Opts = Opts0 ++ [Test,{event_handler,{?eh,EvHArgs}}],
+ ERPid = ct_test_support:start_event_receiver(Config),
+ {Opts,ERPid}.
+
+reformat(Events, EH) ->
+ ct_test_support:reformat(Events, EH).
+%reformat(Events, _EH) ->
+% Events.
+
+%%%-----------------------------------------------------------------
+%%% TEST EVENTS
+%%%-----------------------------------------------------------------
+
+test_events(groups_suite_1) ->
+ [{?eh,start_logging,{'DEF','RUNDIR'}},
+ {?eh,test_start,{'DEF',{'START_TIME','LOGDIR'}}},
+ {?eh,start_info,{1,1,15}},
+ {?eh,tc_start,{groups_11_SUITE,init_per_suite}},
+ {?eh,tc_done,{groups_11_SUITE,init_per_suite,ok}},
+ {?eh,tc_start,{groups_11_SUITE,testcase_1}},
+ {?eh,tc_done,{groups_11_SUITE,testcase_1,ok}},
+ {?eh,test_stats,{1,0,{0,0}}},
+
+ [{?eh,tc_start,{groups_11_SUITE,{init_per_group,test_group_1a,[]}}},
+ {?eh,tc_done,{groups_11_SUITE,{init_per_group,test_group_1a,[]},ok}},
+ {?eh,tc_start,{groups_11_SUITE,testcase_1a}},
+ {?eh,tc_done,{groups_11_SUITE,testcase_1a,ok}},
+ {?eh,test_stats,{2,0,{0,0}}},
+ {?eh,tc_start,{groups_11_SUITE,testcase_1b}},
+ {?eh,tc_done,{groups_11_SUITE,testcase_1b,ok}},
+ {?eh,test_stats,{3,0,{0,0}}},
+ {?eh,tc_start,{groups_11_SUITE,{end_per_group,test_group_1a,[]}}},
+ {?eh,tc_done,{groups_11_SUITE,{end_per_group,test_group_1a,[]},ok}}],
+
+ [{?eh,tc_start,{groups_11_SUITE,{init_per_group,test_group_1b,[]}}},
+ {?eh,tc_done,{groups_11_SUITE,{init_per_group,test_group_1b,[]},ok}},
+ {?eh,tc_start,{groups_11_SUITE,testcase_1a}},
+ {?eh,tc_done,{groups_11_SUITE,testcase_1a,ok}},
+ {?eh,test_stats,{4,0,{0,0}}},
+ {?eh,tc_start,{groups_11_SUITE,testcase_1b}},
+ {?eh,tc_done,{groups_11_SUITE,testcase_1b,ok}},
+ {?eh,test_stats,{5,0,{0,0}}},
+ {?eh,tc_start,{groups_11_SUITE,{end_per_group,test_group_1b,[]}}},
+ {?eh,tc_done,{groups_11_SUITE,{end_per_group,test_group_1b,[]},ok}}],
+
+ {?eh,tc_start,{groups_11_SUITE,testcase_2}},
+ {?eh,tc_done,{groups_11_SUITE,testcase_2,ok}},
+ {?eh,test_stats,{6,0,{0,0}}},
+
+ [{?eh,tc_start,{groups_11_SUITE,{init_per_group,test_group_2,[]}}},
+ {?eh,tc_done,{groups_11_SUITE,{init_per_group,test_group_2,[]},ok}},
+ {?eh,tc_start,{groups_11_SUITE,testcase_2a}},
+ {?eh,tc_done,{groups_11_SUITE,testcase_2a,ok}},
+ {?eh,test_stats,{7,0,{0,0}}},
+ [{?eh,tc_start,{groups_11_SUITE,{init_per_group,test_group_3,[]}}},
+ {?eh,tc_done,{groups_11_SUITE,{init_per_group,test_group_3,[]},ok}},
+ {?eh,tc_start,{groups_11_SUITE,testcase_3a}},
+ {?eh,tc_done,{groups_11_SUITE,testcase_3a,ok}},
+ {?eh,test_stats,{8,0,{0,0}}},
+ {?eh,tc_start,{groups_11_SUITE,testcase_3b}},
+ {?eh,tc_done,{groups_11_SUITE,testcase_3b,ok}},
+ {?eh,test_stats,{9,0,{0,0}}},
+ {?eh,tc_start,{groups_11_SUITE,{end_per_group,test_group_3,[]}}},
+ {?eh,tc_done,{groups_11_SUITE,{end_per_group,test_group_3,[]},ok}}],
+ {?eh,tc_start,{groups_11_SUITE,testcase_2b}},
+ {?eh,tc_done,{groups_11_SUITE,testcase_2b,ok}},
+ {?eh,test_stats,{10,0,{0,0}}},
+ {?eh,tc_start,{groups_11_SUITE,{end_per_group,test_group_2,[]}}},
+ {?eh,tc_done,{groups_11_SUITE,{end_per_group,test_group_2,[]},ok}}],
+
+ {?eh,tc_start,{groups_11_SUITE,testcase_3}},
+ {?eh,tc_done,{groups_11_SUITE,testcase_3,ok}},
+ {?eh,test_stats,{11,0,{0,0}}},
+
+ [{?eh,tc_start,{groups_11_SUITE,{init_per_group,test_group_4,[]}}},
+ {?eh,tc_done,{groups_11_SUITE,{init_per_group,test_group_4,[]},ok}},
+ [{?eh,tc_start,{groups_11_SUITE,{init_per_group,test_group_5,[]}}},
+ {?eh,tc_done,{groups_11_SUITE,{init_per_group,test_group_5,[]},ok}},
+ {?eh,tc_start,{groups_11_SUITE,testcase_5a}},
+ {?eh,tc_done,{groups_11_SUITE,testcase_5a,ok}},
+ {?eh,test_stats,{12,0,{0,0}}},
+ [{?eh,tc_start,{groups_11_SUITE,{init_per_group,test_group_6,[]}}},
+ {?eh,tc_done,{groups_11_SUITE,{init_per_group,test_group_6,[]},ok}},
+ [{?eh,tc_start,{groups_11_SUITE,{init_per_group,test_group_7,[]}}},
+ {?eh,tc_done,{groups_11_SUITE,{init_per_group,test_group_7,[]},ok}},
+ {?eh,tc_start,{groups_11_SUITE,testcase_7a}},
+ {?eh,tc_done,{groups_11_SUITE,testcase_7a,ok}},
+ {?eh,test_stats,{13,0,{0,0}}},
+ {?eh,tc_start,{groups_11_SUITE,testcase_7b}},
+ {?eh,tc_done,{groups_11_SUITE,testcase_7b,ok}},
+ {?eh,test_stats,{14,0,{0,0}}},
+ {?eh,tc_start,{groups_11_SUITE,{end_per_group,test_group_7,[]}}},
+ {?eh,tc_done,{groups_11_SUITE,{end_per_group,test_group_7,[]},ok}}],
+ {?eh,tc_start,{groups_11_SUITE,{end_per_group,test_group_6,[]}}},
+ {?eh,tc_done,{groups_11_SUITE,{end_per_group,test_group_6,[]},ok}}],
+ {?eh,tc_start,{groups_11_SUITE,testcase_5b}},
+ {?eh,tc_done,{groups_11_SUITE,testcase_5b,ok}},
+ {?eh,test_stats,{15,0,{0,0}}},
+ {?eh,tc_start,{groups_11_SUITE,{end_per_group,test_group_5,[]}}},
+ {?eh,tc_done,{groups_11_SUITE,{end_per_group,test_group_5,[]},ok}}],
+ {?eh,tc_start,{groups_11_SUITE,{end_per_group,test_group_4,[]}}},
+ {?eh,tc_done,{groups_11_SUITE,{end_per_group,test_group_4,[]},ok}}],
+
+ {?eh,tc_start,{groups_11_SUITE,end_per_suite}},
+ {?eh,tc_done,{groups_11_SUITE,end_per_suite,init}},
+ {?eh,test_done,{'DEF','STOP_TIME'}},
+ {?eh,stop_logging,[]}];
+
+test_events(groups_suite_2) ->
+ [{?eh,start_logging,{'DEF','RUNDIR'}},
+ {?eh,test_start,{'DEF',{'START_TIME','LOGDIR'}}},
+ {?eh,start_info,{1,1,unknown}},
+ {?eh,tc_start,{groups_12_SUITE,init_per_suite}},
+ {?eh,tc_done,{groups_12_SUITE,init_per_suite,ok}},
+
+ {shuffle,[{?eh,tc_start,{groups_12_SUITE,{init_per_group,test_group_1a,[{shuffle,'_'}]}}},
+ {?eh,tc_done,{groups_12_SUITE,{init_per_group,test_group_1a,[{shuffle,'_'}]},ok}},
+ {?eh,tc_start,{groups_12_SUITE,testcase_1a}},
+ {?eh,tc_done,{groups_12_SUITE,testcase_1a,ok}},
+ {?eh,test_stats,{1,0,{0,0}}},
+ {?eh,tc_start,{groups_12_SUITE,testcase_1b}},
+ {?eh,tc_done,{groups_12_SUITE,testcase_1b,ok}},
+ {?eh,test_stats,{2,0,{0,0}}},
+ {?eh,tc_start,{groups_12_SUITE,testcase_1c}},
+ {?eh,tc_done,{groups_12_SUITE,testcase_1c,ok}},
+ {?eh,test_stats,{3,0,{0,0}}},
+ {?eh,tc_start,{groups_12_SUITE,{end_per_group,test_group_1a,[shuffle]}}},
+ {?eh,tc_done,{groups_12_SUITE,{end_per_group,test_group_1a,[shuffle]},ok}}]},
+
+ {parallel,[{?eh,tc_start,{groups_12_SUITE,{init_per_group,test_group_1b,[parallel]}}},
+ {?eh,tc_done,{groups_12_SUITE,{init_per_group,test_group_1b,[parallel]},ok}},
+ {?eh,tc_start,{groups_12_SUITE,testcase_1a}},
+ {?eh,tc_done,{groups_12_SUITE,testcase_1a,ok}},
+ {?eh,tc_start,{groups_12_SUITE,testcase_1b}},
+ {?eh,tc_done,{groups_12_SUITE,testcase_1b,ok}},
+ {?eh,test_stats,{5,0,{0,0}}},
+ {?eh,tc_start,{groups_12_SUITE,{end_per_group,test_group_1b,[parallel]}}},
+ {?eh,tc_done,{groups_12_SUITE,{end_per_group,test_group_1b,[parallel]},ok}}]},
+
+ {?eh,tc_start,{groups_12_SUITE,testcase_1}},
+ {?eh,tc_done,{groups_12_SUITE,testcase_1,ok}},
+ {?eh,test_stats,{6,0,{0,0}}},
+ {?eh,tc_start,{groups_12_SUITE,testcase_2}},
+ {?eh,tc_done,{groups_12_SUITE,testcase_2,ok}},
+ {?eh,test_stats,{7,0,{0,0}}},
+
+ {parallel,[{?eh,tc_start,{groups_12_SUITE,{init_per_group,test_group_2,[parallel]}}},
+ {?eh,tc_done,{groups_12_SUITE,{init_per_group,test_group_2,[parallel]},ok}},
+ {?eh,tc_start,{groups_12_SUITE,testcase_2a}},
+ {?eh,tc_done,{groups_12_SUITE,testcase_2a,ok}},
+
+ [{?eh,tc_start,{groups_12_SUITE,{init_per_group,test_group_3,[{repeat,1}]}}},
+ {?eh,tc_done,{groups_12_SUITE,{init_per_group,test_group_3,[{repeat,1}]},ok}},
+ {?eh,tc_start,{groups_12_SUITE,testcase_3a}},
+ {?eh,tc_done,{groups_12_SUITE,testcase_3a,ok}},
+ {?eh,tc_start,{groups_12_SUITE,testcase_3b}},
+ {?eh,tc_done,{groups_12_SUITE,testcase_3b,ok}},
+ {?eh,tc_start,{groups_12_SUITE,{end_per_group,test_group_3,[{repeat,1}]}}},
+ {?eh,tc_done,{groups_12_SUITE,{end_per_group,test_group_3,[{repeat,1}]},ok}}],
+
+ [{?eh,tc_start,{groups_12_SUITE,{init_per_group,test_group_3,[]}}},
+ {?eh,tc_done,{groups_12_SUITE,{init_per_group,test_group_3,[]},ok}},
+ {?eh,tc_start,{groups_12_SUITE,testcase_3a}},
+ {?eh,tc_done,{groups_12_SUITE,testcase_3a,ok}},
+ {?eh,tc_start,{groups_12_SUITE,testcase_3b}},
+ {?eh,tc_done,{groups_12_SUITE,testcase_3b,ok}},
+ {?eh,tc_start,{groups_12_SUITE,{end_per_group,test_group_3,[]}}},
+ {?eh,tc_done,{groups_12_SUITE,{end_per_group,test_group_3,[]},ok}}],
+
+ {?eh,tc_start,{groups_12_SUITE,testcase_2b}},
+ {?eh,tc_done,{groups_12_SUITE,testcase_2b,ok}},
+ {?eh,test_stats,{13,0,{0,0}}},
+
+ {?eh,tc_start,{groups_12_SUITE,{end_per_group,test_group_2,[parallel]}}},
+ {?eh,tc_done,{groups_12_SUITE,{end_per_group,test_group_2,[parallel]},ok}}]},
+
+ {?eh,tc_start,{groups_12_SUITE,testcase_3}},
+ {?eh,tc_done,{groups_12_SUITE,testcase_3,ok}},
+ {?eh,test_stats,{14,0,{0,0}}},
+
+ [{?eh,tc_start,{groups_12_SUITE,{init_per_group,test_group_4,[]}}},
+ {?eh,tc_done,{groups_12_SUITE,{init_per_group,test_group_4,[]},ok}},
+
+ {parallel,[{?eh,tc_start,{groups_12_SUITE,{init_per_group,test_group_5,[parallel]}}},
+ {?eh,tc_done,{groups_12_SUITE,{init_per_group,test_group_5,[parallel]},ok}},
+
+ %% the done event could come in during the parallel subgroup
+ %% and we can't test that, yet...
+ %% {?eh,tc_start,{groups_12_SUITE,testcase_5a}},
+ %% {?eh,tc_done,{groups_12_SUITE,testcase_5a,ok}},
+
+ {parallel,[{?eh,tc_start,{groups_12_SUITE,{init_per_group,test_group_6,[parallel]}}},
+ {?eh,tc_done,{groups_12_SUITE,{init_per_group,test_group_6,[parallel]},ok}},
+
+ [{?eh,tc_start,{groups_12_SUITE,{init_per_group,test_group_7,[sequence]}}},
+ {?eh,tc_done,{groups_12_SUITE,{init_per_group,test_group_7,[sequence]},ok}},
+ {?eh,tc_start,{groups_12_SUITE,testcase_7a}},
+ {?eh,tc_done,{groups_12_SUITE,testcase_7a,ok}},
+ {?eh,tc_start,{groups_12_SUITE,testcase_7b}},
+ {?eh,tc_done,{groups_12_SUITE,testcase_7b,ok}},
+ {?eh,tc_start,{groups_12_SUITE,{end_per_group,test_group_7,[sequence]}}},
+ {?eh,tc_done,{groups_12_SUITE,{end_per_group,test_group_7,[sequence]},ok}}],
+
+ {?eh,tc_start,{groups_12_SUITE,{end_per_group,test_group_6,[parallel]}}},
+ {?eh,tc_done,{groups_12_SUITE,{end_per_group,test_group_6,[parallel]},ok}}]},
+
+ {?eh,tc_start,{groups_12_SUITE,testcase_5b}},
+ {?eh,tc_done,{groups_12_SUITE,testcase_5b,ok}},
+ {?eh,test_stats,{18,0,{0,0}}},
+ {?eh,tc_start,{groups_12_SUITE,{end_per_group,test_group_5,[parallel]}}},
+ {?eh,tc_done,{groups_12_SUITE,{end_per_group,test_group_5,[parallel]},ok}}]},
+
+ {?eh,tc_start,{groups_12_SUITE,{end_per_group,test_group_4,[]}}},
+ {?eh,tc_done,{groups_12_SUITE,{end_per_group,test_group_4,[]},ok}}],
+
+ {?eh,tc_start,{groups_12_SUITE,end_per_suite}},
+ {?eh,tc_done,{groups_12_SUITE,end_per_suite,init}},
+ {?eh,test_done,{'DEF','STOP_TIME'}},
+ {?eh,stop_logging,[]}];
+
+test_events(groups_suites_1) ->
+ [{?eh,start_logging,{'DEF','RUNDIR'}},
+ {?eh,test_start,{'DEF',{'START_TIME','LOGDIR'}}},
+ {?eh,start_info,{2,2,unknown}},
+ {?eh,tc_start,{groups_11_SUITE,init_per_suite}},
+ {?eh,tc_done,{groups_11_SUITE,init_per_suite,ok}},
+ {?eh,tc_start,{groups_11_SUITE,testcase_1}},
+ {?eh,tc_done,{groups_11_SUITE,testcase_1,ok}},
+ {?eh,test_stats,{1,0,{0,0}}},
+
+ [{?eh,tc_start,{groups_11_SUITE,{init_per_group,test_group_1a,[]}}},
+ {?eh,tc_done,{groups_11_SUITE,{init_per_group,test_group_1a,[]},ok}},
+ {?eh,tc_start,{groups_11_SUITE,testcase_1a}},
+ {?eh,tc_done,{groups_11_SUITE,testcase_1a,ok}},
+ {?eh,test_stats,{2,0,{0,0}}},
+ {?eh,tc_start,{groups_11_SUITE,testcase_1b}},
+ {?eh,tc_done,{groups_11_SUITE,testcase_1b,ok}},
+ {?eh,test_stats,{3,0,{0,0}}},
+ {?eh,tc_start,{groups_11_SUITE,{end_per_group,test_group_1a,[]}}},
+ {?eh,tc_done,{groups_11_SUITE,{end_per_group,test_group_1a,[]},ok}}],
+
+ [{?eh,tc_start,{groups_11_SUITE,{init_per_group,test_group_1b,[]}}},
+ {?eh,tc_done,{groups_11_SUITE,{init_per_group,test_group_1b,[]},ok}},
+ {?eh,tc_start,{groups_11_SUITE,testcase_1a}},
+ {?eh,tc_done,{groups_11_SUITE,testcase_1a,ok}},
+ {?eh,test_stats,{4,0,{0,0}}},
+ {?eh,tc_start,{groups_11_SUITE,testcase_1b}},
+ {?eh,tc_done,{groups_11_SUITE,testcase_1b,ok}},
+ {?eh,test_stats,{5,0,{0,0}}},
+ {?eh,tc_start,{groups_11_SUITE,{end_per_group,test_group_1b,[]}}},
+ {?eh,tc_done,{groups_11_SUITE,{end_per_group,test_group_1b,[]},ok}}],
+
+ {?eh,tc_start,{groups_11_SUITE,testcase_2}},
+ {?eh,tc_done,{groups_11_SUITE,testcase_2,ok}},
+ {?eh,test_stats,{6,0,{0,0}}},
+
+ [{?eh,tc_start,{groups_11_SUITE,{init_per_group,test_group_2,[]}}},
+ {?eh,tc_done,{groups_11_SUITE,{init_per_group,test_group_2,[]},ok}},
+ {?eh,tc_start,{groups_11_SUITE,testcase_2a}},
+ {?eh,tc_done,{groups_11_SUITE,testcase_2a,ok}},
+ {?eh,test_stats,{7,0,{0,0}}},
+ [{?eh,tc_start,{groups_11_SUITE,{init_per_group,test_group_3,[]}}},
+ {?eh,tc_done,{groups_11_SUITE,{init_per_group,test_group_3,[]},ok}},
+ {?eh,tc_start,{groups_11_SUITE,testcase_3a}},
+ {?eh,tc_done,{groups_11_SUITE,testcase_3a,ok}},
+ {?eh,test_stats,{8,0,{0,0}}},
+ {?eh,tc_start,{groups_11_SUITE,testcase_3b}},
+ {?eh,tc_done,{groups_11_SUITE,testcase_3b,ok}},
+ {?eh,test_stats,{9,0,{0,0}}},
+ {?eh,tc_start,{groups_11_SUITE,{end_per_group,test_group_3,[]}}},
+ {?eh,tc_done,{groups_11_SUITE,{end_per_group,test_group_3,[]},ok}}],
+ {?eh,tc_start,{groups_11_SUITE,testcase_2b}},
+ {?eh,tc_done,{groups_11_SUITE,testcase_2b,ok}},
+ {?eh,test_stats,{10,0,{0,0}}},
+ {?eh,tc_start,{groups_11_SUITE,{end_per_group,test_group_2,[]}}},
+ {?eh,tc_done,{groups_11_SUITE,{end_per_group,test_group_2,[]},ok}}],
+
+ {?eh,tc_start,{groups_11_SUITE,testcase_3}},
+ {?eh,tc_done,{groups_11_SUITE,testcase_3,ok}},
+ {?eh,test_stats,{11,0,{0,0}}},
+
+ [{?eh,tc_start,{groups_11_SUITE,{init_per_group,test_group_4,[]}}},
+ {?eh,tc_done,{groups_11_SUITE,{init_per_group,test_group_4,[]},ok}},
+ [{?eh,tc_start,{groups_11_SUITE,{init_per_group,test_group_5,[]}}},
+ {?eh,tc_done,{groups_11_SUITE,{init_per_group,test_group_5,[]},ok}},
+ {?eh,tc_start,{groups_11_SUITE,testcase_5a}},
+ {?eh,tc_done,{groups_11_SUITE,testcase_5a,ok}},
+ {?eh,test_stats,{12,0,{0,0}}},
+ [{?eh,tc_start,{groups_11_SUITE,{init_per_group,test_group_6,[]}}},
+ {?eh,tc_done,{groups_11_SUITE,{init_per_group,test_group_6,[]},ok}},
+ [{?eh,tc_start,{groups_11_SUITE,{init_per_group,test_group_7,[]}}},
+ {?eh,tc_done,{groups_11_SUITE,{init_per_group,test_group_7,[]},ok}},
+ {?eh,tc_start,{groups_11_SUITE,testcase_7a}},
+ {?eh,tc_done,{groups_11_SUITE,testcase_7a,ok}},
+ {?eh,test_stats,{13,0,{0,0}}},
+ {?eh,tc_start,{groups_11_SUITE,testcase_7b}},
+ {?eh,tc_done,{groups_11_SUITE,testcase_7b,ok}},
+ {?eh,test_stats,{14,0,{0,0}}},
+ {?eh,tc_start,{groups_11_SUITE,{end_per_group,test_group_7,[]}}},
+ {?eh,tc_done,{groups_11_SUITE,{end_per_group,test_group_7,[]},ok}}],
+ {?eh,tc_start,{groups_11_SUITE,{end_per_group,test_group_6,[]}}},
+ {?eh,tc_done,{groups_11_SUITE,{end_per_group,test_group_6,[]},ok}}],
+ {?eh,tc_start,{groups_11_SUITE,testcase_5b}},
+ {?eh,tc_done,{groups_11_SUITE,testcase_5b,ok}},
+ {?eh,test_stats,{15,0,{0,0}}},
+ {?eh,tc_start,{groups_11_SUITE,{end_per_group,test_group_5,[]}}},
+ {?eh,tc_done,{groups_11_SUITE,{end_per_group,test_group_5,[]},ok}}],
+ {?eh,tc_start,{groups_11_SUITE,{end_per_group,test_group_4,[]}}},
+ {?eh,tc_done,{groups_11_SUITE,{end_per_group,test_group_4,[]},ok}}],
+
+ {?eh,tc_start,{groups_11_SUITE,end_per_suite}},
+ {?eh,tc_done,{groups_11_SUITE,end_per_suite,init}},
+
+ {?eh,tc_start,{groups_12_SUITE,init_per_suite}},
+ {?eh,tc_done,{groups_12_SUITE,init_per_suite,ok}},
+
+ {shuffle,[{?eh,tc_start,{groups_12_SUITE,{init_per_group,test_group_1a,[{shuffle,'_'}]}}},
+ {?eh,tc_done,{groups_12_SUITE,{init_per_group,test_group_1a,[{shuffle,'_'}]},ok}},
+ {?eh,tc_start,{groups_12_SUITE,testcase_1c}},
+ {?eh,tc_done,{groups_12_SUITE,testcase_1c,ok}},
+ {?eh,test_stats,{16,0,{0,0}}},
+ {?eh,tc_start,{groups_12_SUITE,testcase_1b}},
+ {?eh,tc_done,{groups_12_SUITE,testcase_1b,ok}},
+ {?eh,test_stats,{17,0,{0,0}}},
+ {?eh,tc_start,{groups_12_SUITE,testcase_1a}},
+ {?eh,tc_done,{groups_12_SUITE,testcase_1a,ok}},
+ {?eh,test_stats,{18,0,{0,0}}},
+ {?eh,tc_start,{groups_12_SUITE,{end_per_group,test_group_1a,[shuffle]}}},
+ {?eh,tc_done,{groups_12_SUITE,{end_per_group,test_group_1a,[shuffle]},ok}}]},
+ {parallel,[{?eh,tc_start,{groups_12_SUITE,{init_per_group,test_group_1b,[parallel]}}},
+ {?eh,tc_done,{groups_12_SUITE,{init_per_group,test_group_1b,[parallel]},ok}},
+ {?eh,tc_start,{groups_12_SUITE,testcase_1a}},
+ {?eh,tc_done,{groups_12_SUITE,testcase_1a,ok}},
+ {?eh,tc_start,{groups_12_SUITE,testcase_1b}},
+ {?eh,tc_done,{groups_12_SUITE,testcase_1b,ok}},
+ {?eh,test_stats,{20,0,{0,0}}},
+ {?eh,tc_start,{groups_12_SUITE,{end_per_group,test_group_1b,[parallel]}}},
+ {?eh,tc_done,{groups_12_SUITE,{end_per_group,test_group_1b,[parallel]},ok}}]},
+ {?eh,tc_start,{groups_12_SUITE,testcase_1}},
+ {?eh,tc_done,{groups_12_SUITE,testcase_1,ok}},
+ {?eh,test_stats,{21,0,{0,0}}},
+ {?eh,tc_start,{groups_12_SUITE,testcase_2}},
+ {?eh,tc_done,{groups_12_SUITE,testcase_2,ok}},
+ {?eh,test_stats,{22,0,{0,0}}},
+
+ {parallel,[{?eh,tc_start,{groups_12_SUITE,{init_per_group,test_group_2,[parallel]}}},
+ {?eh,tc_done,{groups_12_SUITE,{init_per_group,test_group_2,[parallel]},ok}},
+ {?eh,tc_start,{groups_12_SUITE,testcase_2a}},
+ {?eh,tc_done,{groups_12_SUITE,testcase_2a,ok}},
+ [{?eh,tc_start,{groups_12_SUITE,{init_per_group,test_group_3,[{repeat,1}]}}},
+ {?eh,tc_done,{groups_12_SUITE,{init_per_group,test_group_3,[{repeat,1}]},ok}},
+ {?eh,tc_start,{groups_12_SUITE,testcase_3a}},
+ {?eh,tc_done,{groups_12_SUITE,testcase_3a,ok}},
+ {?eh,tc_start,{groups_12_SUITE,testcase_3b}},
+ {?eh,tc_done,{groups_12_SUITE,testcase_3b,ok}},
+ {?eh,tc_start,{groups_12_SUITE,{end_per_group,test_group_3,[{repeat,1}]}}},
+ {?eh,tc_done,{groups_12_SUITE,{end_per_group,test_group_3,[{repeat,1}]},ok}}],
+ [{?eh,tc_start,{groups_12_SUITE,{init_per_group,test_group_3,[]}}},
+ {?eh,tc_done,{groups_12_SUITE,{init_per_group,test_group_3,[]},ok}},
+ {?eh,tc_start,{groups_12_SUITE,testcase_3a}},
+ {?eh,tc_done,{groups_12_SUITE,testcase_3a,ok}},
+ {?eh,tc_start,{groups_12_SUITE,testcase_3b}},
+ {?eh,tc_done,{groups_12_SUITE,testcase_3b,ok}},
+ {?eh,tc_start,{groups_12_SUITE,{end_per_group,test_group_3,[]}}},
+ {?eh,tc_done,{groups_12_SUITE,{end_per_group,test_group_3,[]},ok}}],
+ {?eh,tc_start,{groups_12_SUITE,testcase_2b}},
+ {?eh,tc_done,{groups_12_SUITE,testcase_2b,ok}},
+ {?eh,test_stats,{28,0,{0,0}}},
+ {?eh,tc_start,{groups_12_SUITE,{end_per_group,test_group_2,[parallel]}}},
+ {?eh,tc_done,{groups_12_SUITE,{end_per_group,test_group_2,[parallel]},ok}}]},
+
+ {?eh,tc_start,{groups_12_SUITE,testcase_3}},
+ {?eh,tc_done,{groups_12_SUITE,testcase_3,ok}},
+ {?eh,test_stats,{29,0,{0,0}}},
+
+ [{?eh,tc_start,{groups_12_SUITE,{init_per_group,test_group_4,[]}}},
+ {?eh,tc_done,{groups_12_SUITE,{init_per_group,test_group_4,[]},ok}},
+ {parallel,[{?eh,tc_start,{groups_12_SUITE,{init_per_group,test_group_5,[parallel]}}},
+ {?eh,tc_done,{groups_12_SUITE,{init_per_group,test_group_5,[parallel]},ok}},
+
+ %% the done event could come in during the parallel subgroup
+ %% and we can't test that, yet...
+ %% {?eh,tc_start,{groups_12_SUITE,testcase_5a}},
+ %% {?eh,tc_done,{groups_12_SUITE,testcase_5a,ok}},
+
+ {parallel,[{?eh,tc_start,{groups_12_SUITE,{init_per_group,test_group_6,[parallel]}}},
+ {?eh,tc_done,{groups_12_SUITE,{init_per_group,test_group_6,[parallel]},ok}},
+ [{?eh,tc_start,{groups_12_SUITE,{init_per_group,test_group_7,[sequence]}}},
+ {?eh,tc_done,{groups_12_SUITE,{init_per_group,test_group_7,[sequence]},ok}},
+ {?eh,tc_start,{groups_12_SUITE,testcase_7a}},
+ {?eh,tc_done,{groups_12_SUITE,testcase_7a,ok}},
+ {?eh,tc_start,{groups_12_SUITE,testcase_7b}},
+ {?eh,tc_done,{groups_12_SUITE,testcase_7b,ok}},
+ {?eh,tc_start,{groups_12_SUITE,{end_per_group,test_group_7,[sequence]}}},
+ {?eh,tc_done,{groups_12_SUITE,{end_per_group,test_group_7,[sequence]},ok}}],
+ {?eh,tc_start,{groups_12_SUITE,{end_per_group,test_group_6,[parallel]}}},
+ {?eh,tc_done,{groups_12_SUITE,{end_per_group,test_group_6,[parallel]},ok}}]},
+ {?eh,tc_start,{groups_12_SUITE,testcase_5b}},
+ {?eh,tc_done,{groups_12_SUITE,testcase_5b,ok}},
+ {?eh,test_stats,{33,0,{0,0}}},
+ {?eh,tc_start,{groups_12_SUITE,{end_per_group,test_group_5,[parallel]}}},
+ {?eh,tc_done,{groups_12_SUITE,{end_per_group,test_group_5,[parallel]},ok}}]},
+ {?eh,tc_start,{groups_12_SUITE,{end_per_group,test_group_4,[]}}},
+ {?eh,tc_done,{groups_12_SUITE,{end_per_group,test_group_4,[]},ok}}],
+
+ {?eh,tc_start,{groups_12_SUITE,end_per_suite}},
+ {?eh,tc_done,{groups_12_SUITE,end_per_suite,init}},
+ {?eh,test_done,{'DEF','STOP_TIME'}},
+ {?eh,stop_logging,[]}];
+
+test_events(groups_dir_1) ->
+ [{?eh,start_logging,{'DEF','RUNDIR'}},
+ {?eh,test_start,{'DEF',{'START_TIME','LOGDIR'}}},
+ {?eh,start_info,{1,2,unknown}},
+ {?eh,tc_start,{groups_11_SUITE,init_per_suite}},
+ {?eh,tc_done,{groups_11_SUITE,init_per_suite,ok}},
+ {?eh,tc_start,{groups_11_SUITE,testcase_1}},
+ {?eh,tc_done,{groups_11_SUITE,testcase_1,ok}},
+ {?eh,test_stats,{1,0,{0,0}}},
+
+ [{?eh,tc_start,{groups_11_SUITE,{init_per_group,test_group_1a,[]}}},
+ {?eh,tc_done,{groups_11_SUITE,{init_per_group,test_group_1a,[]},ok}},
+ {?eh,tc_start,{groups_11_SUITE,testcase_1a}},
+ {?eh,tc_done,{groups_11_SUITE,testcase_1a,ok}},
+ {?eh,test_stats,{2,0,{0,0}}},
+ {?eh,tc_start,{groups_11_SUITE,testcase_1b}},
+ {?eh,tc_done,{groups_11_SUITE,testcase_1b,ok}},
+ {?eh,test_stats,{3,0,{0,0}}},
+ {?eh,tc_start,{groups_11_SUITE,{end_per_group,test_group_1a,[]}}},
+ {?eh,tc_done,{groups_11_SUITE,{end_per_group,test_group_1a,[]},ok}}],
+
+ [{?eh,tc_start,{groups_11_SUITE,{init_per_group,test_group_1b,[]}}},
+ {?eh,tc_done,{groups_11_SUITE,{init_per_group,test_group_1b,[]},ok}},
+ {?eh,tc_start,{groups_11_SUITE,testcase_1a}},
+ {?eh,tc_done,{groups_11_SUITE,testcase_1a,ok}},
+ {?eh,test_stats,{4,0,{0,0}}},
+ {?eh,tc_start,{groups_11_SUITE,testcase_1b}},
+ {?eh,tc_done,{groups_11_SUITE,testcase_1b,ok}},
+ {?eh,test_stats,{5,0,{0,0}}},
+ {?eh,tc_start,{groups_11_SUITE,{end_per_group,test_group_1b,[]}}},
+ {?eh,tc_done,{groups_11_SUITE,{end_per_group,test_group_1b,[]},ok}}],
+
+ {?eh,tc_start,{groups_11_SUITE,testcase_2}},
+ {?eh,tc_done,{groups_11_SUITE,testcase_2,ok}},
+ {?eh,test_stats,{6,0,{0,0}}},
+
+ [{?eh,tc_start,{groups_11_SUITE,{init_per_group,test_group_2,[]}}},
+ {?eh,tc_done,{groups_11_SUITE,{init_per_group,test_group_2,[]},ok}},
+ {?eh,tc_start,{groups_11_SUITE,testcase_2a}},
+ {?eh,tc_done,{groups_11_SUITE,testcase_2a,ok}},
+ {?eh,test_stats,{7,0,{0,0}}},
+ [{?eh,tc_start,{groups_11_SUITE,{init_per_group,test_group_3,[]}}},
+ {?eh,tc_done,{groups_11_SUITE,{init_per_group,test_group_3,[]},ok}},
+ {?eh,tc_start,{groups_11_SUITE,testcase_3a}},
+ {?eh,tc_done,{groups_11_SUITE,testcase_3a,ok}},
+ {?eh,test_stats,{8,0,{0,0}}},
+ {?eh,tc_start,{groups_11_SUITE,testcase_3b}},
+ {?eh,tc_done,{groups_11_SUITE,testcase_3b,ok}},
+ {?eh,test_stats,{9,0,{0,0}}},
+ {?eh,tc_start,{groups_11_SUITE,{end_per_group,test_group_3,[]}}},
+ {?eh,tc_done,{groups_11_SUITE,{end_per_group,test_group_3,[]},ok}}],
+ {?eh,tc_start,{groups_11_SUITE,testcase_2b}},
+ {?eh,tc_done,{groups_11_SUITE,testcase_2b,ok}},
+ {?eh,test_stats,{10,0,{0,0}}},
+ {?eh,tc_start,{groups_11_SUITE,{end_per_group,test_group_2,[]}}},
+ {?eh,tc_done,{groups_11_SUITE,{end_per_group,test_group_2,[]},ok}}],
+
+ {?eh,tc_start,{groups_11_SUITE,testcase_3}},
+ {?eh,tc_done,{groups_11_SUITE,testcase_3,ok}},
+ {?eh,test_stats,{11,0,{0,0}}},
+
+ [{?eh,tc_start,{groups_11_SUITE,{init_per_group,test_group_4,[]}}},
+ {?eh,tc_done,{groups_11_SUITE,{init_per_group,test_group_4,[]},ok}},
+ [{?eh,tc_start,{groups_11_SUITE,{init_per_group,test_group_5,[]}}},
+ {?eh,tc_done,{groups_11_SUITE,{init_per_group,test_group_5,[]},ok}},
+ {?eh,tc_start,{groups_11_SUITE,testcase_5a}},
+ {?eh,tc_done,{groups_11_SUITE,testcase_5a,ok}},
+ {?eh,test_stats,{12,0,{0,0}}},
+ [{?eh,tc_start,{groups_11_SUITE,{init_per_group,test_group_6,[]}}},
+ {?eh,tc_done,{groups_11_SUITE,{init_per_group,test_group_6,[]},ok}},
+ [{?eh,tc_start,{groups_11_SUITE,{init_per_group,test_group_7,[]}}},
+ {?eh,tc_done,{groups_11_SUITE,{init_per_group,test_group_7,[]},ok}},
+ {?eh,tc_start,{groups_11_SUITE,testcase_7a}},
+ {?eh,tc_done,{groups_11_SUITE,testcase_7a,ok}},
+ {?eh,test_stats,{13,0,{0,0}}},
+ {?eh,tc_start,{groups_11_SUITE,testcase_7b}},
+ {?eh,tc_done,{groups_11_SUITE,testcase_7b,ok}},
+ {?eh,test_stats,{14,0,{0,0}}},
+ {?eh,tc_start,{groups_11_SUITE,{end_per_group,test_group_7,[]}}},
+ {?eh,tc_done,{groups_11_SUITE,{end_per_group,test_group_7,[]},ok}}],
+ {?eh,tc_start,{groups_11_SUITE,{end_per_group,test_group_6,[]}}},
+ {?eh,tc_done,{groups_11_SUITE,{end_per_group,test_group_6,[]},ok}}],
+ {?eh,tc_start,{groups_11_SUITE,testcase_5b}},
+ {?eh,tc_done,{groups_11_SUITE,testcase_5b,ok}},
+ {?eh,test_stats,{15,0,{0,0}}},
+ {?eh,tc_start,{groups_11_SUITE,{end_per_group,test_group_5,[]}}},
+ {?eh,tc_done,{groups_11_SUITE,{end_per_group,test_group_5,[]},ok}}],
+ {?eh,tc_start,{groups_11_SUITE,{end_per_group,test_group_4,[]}}},
+ {?eh,tc_done,{groups_11_SUITE,{end_per_group,test_group_4,[]},ok}}],
+
+ {?eh,tc_start,{groups_11_SUITE,end_per_suite}},
+ {?eh,tc_done,{groups_11_SUITE,end_per_suite,init}},
+
+ {?eh,tc_start,{groups_12_SUITE,init_per_suite}},
+ {?eh,tc_done,{groups_12_SUITE,init_per_suite,ok}},
+
+ {shuffle,[{?eh,tc_start,{groups_12_SUITE,{init_per_group,test_group_1a,[{shuffle,'_'}]}}},
+ {?eh,tc_done,{groups_12_SUITE,{init_per_group,test_group_1a,[{shuffle,'_'}]},ok}},
+ {?eh,tc_start,{groups_12_SUITE,testcase_1b}},
+ {?eh,tc_done,{groups_12_SUITE,testcase_1b,ok}},
+ {?eh,test_stats,{16,0,{0,0}}},
+ {?eh,tc_start,{groups_12_SUITE,testcase_1c}},
+ {?eh,tc_done,{groups_12_SUITE,testcase_1c,ok}},
+ {?eh,test_stats,{17,0,{0,0}}},
+ {?eh,tc_start,{groups_12_SUITE,testcase_1a}},
+ {?eh,tc_done,{groups_12_SUITE,testcase_1a,ok}},
+ {?eh,test_stats,{18,0,{0,0}}},
+ {?eh,tc_start,{groups_12_SUITE,{end_per_group,test_group_1a,[shuffle]}}},
+ {?eh,tc_done,{groups_12_SUITE,{end_per_group,test_group_1a,[shuffle]},ok}}]},
+ {parallel,[{?eh,tc_start,{groups_12_SUITE,{init_per_group,test_group_1b,[parallel]}}},
+ {?eh,tc_done,{groups_12_SUITE,{init_per_group,test_group_1b,[parallel]},ok}},
+ {?eh,tc_start,{groups_12_SUITE,testcase_1a}},
+ {?eh,tc_done,{groups_12_SUITE,testcase_1a,ok}},
+ {?eh,tc_start,{groups_12_SUITE,testcase_1b}},
+ {?eh,tc_done,{groups_12_SUITE,testcase_1b,ok}},
+ {?eh,test_stats,{20,0,{0,0}}},
+ {?eh,tc_start,{groups_12_SUITE,{end_per_group,test_group_1b,[parallel]}}},
+ {?eh,tc_done,{groups_12_SUITE,{end_per_group,test_group_1b,[parallel]},ok}}]},
+ {?eh,tc_start,{groups_12_SUITE,testcase_1}},
+ {?eh,tc_done,{groups_12_SUITE,testcase_1,ok}},
+ {?eh,test_stats,{21,0,{0,0}}},
+ {?eh,tc_start,{groups_12_SUITE,testcase_2}},
+ {?eh,tc_done,{groups_12_SUITE,testcase_2,ok}},
+ {?eh,test_stats,{22,0,{0,0}}},
+
+ {parallel,[{?eh,tc_start,{groups_12_SUITE,{init_per_group,test_group_2,[parallel]}}},
+ {?eh,tc_done,{groups_12_SUITE,{init_per_group,test_group_2,[parallel]},ok}},
+ {?eh,tc_start,{groups_12_SUITE,testcase_2a}},
+ {?eh,tc_done,{groups_12_SUITE,testcase_2a,ok}},
+ [{?eh,tc_start,{groups_12_SUITE,{init_per_group,test_group_3,[{repeat,1}]}}},
+ {?eh,tc_done,{groups_12_SUITE,{init_per_group,test_group_3,[{repeat,1}]},ok}},
+ {?eh,tc_start,{groups_12_SUITE,testcase_3a}},
+ {?eh,tc_done,{groups_12_SUITE,testcase_3a,ok}},
+ {?eh,tc_start,{groups_12_SUITE,testcase_3b}},
+ {?eh,tc_done,{groups_12_SUITE,testcase_3b,ok}},
+ {?eh,tc_start,{groups_12_SUITE,{end_per_group,test_group_3,[{repeat,1}]}}},
+ {?eh,tc_done,{groups_12_SUITE,{end_per_group,test_group_3,[{repeat,1}]},ok}}],
+ [{?eh,tc_start,{groups_12_SUITE,{init_per_group,test_group_3,[]}}},
+ {?eh,tc_done,{groups_12_SUITE,{init_per_group,test_group_3,[]},ok}},
+ {?eh,tc_start,{groups_12_SUITE,testcase_3a}},
+ {?eh,tc_done,{groups_12_SUITE,testcase_3a,ok}},
+ {?eh,tc_start,{groups_12_SUITE,testcase_3b}},
+ {?eh,tc_done,{groups_12_SUITE,testcase_3b,ok}},
+ {?eh,tc_start,{groups_12_SUITE,{end_per_group,test_group_3,[]}}},
+ {?eh,tc_done,{groups_12_SUITE,{end_per_group,test_group_3,[]},ok}}],
+ {?eh,tc_start,{groups_12_SUITE,testcase_2b}},
+ {?eh,tc_done,{groups_12_SUITE,testcase_2b,ok}},
+ {?eh,test_stats,{28,0,{0,0}}},
+ {?eh,tc_start,{groups_12_SUITE,{end_per_group,test_group_2,[parallel]}}},
+ {?eh,tc_done,{groups_12_SUITE,{end_per_group,test_group_2,[parallel]},ok}}]},
+
+ {?eh,tc_start,{groups_12_SUITE,testcase_3}},
+ {?eh,tc_done,{groups_12_SUITE,testcase_3,ok}},
+ {?eh,test_stats,{29,0,{0,0}}},
+
+ [{?eh,tc_start,{groups_12_SUITE,{init_per_group,test_group_4,[]}}},
+ {?eh,tc_done,{groups_12_SUITE,{init_per_group,test_group_4,[]},ok}},
+ {parallel,[{?eh,tc_start,{groups_12_SUITE,{init_per_group,test_group_5,[parallel]}}},
+ {?eh,tc_done,{groups_12_SUITE,{init_per_group,test_group_5,[parallel]},ok}},
+
+ %% the done event could come in during the parallel subgroup
+ %% and we can't test that, yet...
+ %% {?eh,tc_start,{groups_12_SUITE,testcase_5a}},
+ %% {?eh,tc_done,{groups_12_SUITE,testcase_5a,ok}},
+
+ {parallel,[{?eh,tc_start,{groups_12_SUITE,{init_per_group,test_group_6,[parallel]}}},
+ {?eh,tc_done,{groups_12_SUITE,{init_per_group,test_group_6,[parallel]},ok}},
+ [{?eh,tc_start,{groups_12_SUITE,{init_per_group,test_group_7,[sequence]}}},
+ {?eh,tc_done,{groups_12_SUITE,{init_per_group,test_group_7,[sequence]},ok}},
+ {?eh,tc_start,{groups_12_SUITE,testcase_7a}},
+ {?eh,tc_done,{groups_12_SUITE,testcase_7a,ok}},
+ {?eh,tc_start,{groups_12_SUITE,testcase_7b}},
+ {?eh,tc_done,{groups_12_SUITE,testcase_7b,ok}},
+ {?eh,tc_start,{groups_12_SUITE,{end_per_group,test_group_7,[sequence]}}},
+ {?eh,tc_done,{groups_12_SUITE,{end_per_group,test_group_7,[sequence]},ok}}],
+ {?eh,tc_start,{groups_12_SUITE,{end_per_group,test_group_6,[parallel]}}},
+ {?eh,tc_done,{groups_12_SUITE,{end_per_group,test_group_6,[parallel]},ok}}]},
+ {?eh,tc_start,{groups_12_SUITE,testcase_5b}},
+ {?eh,tc_done,{groups_12_SUITE,testcase_5b,ok}},
+ {?eh,test_stats,{33,0,{0,0}}},
+ {?eh,tc_start,{groups_12_SUITE,{end_per_group,test_group_5,[parallel]}}},
+ {?eh,tc_done,{groups_12_SUITE,{end_per_group,test_group_5,[parallel]},ok}}]},
+ {?eh,tc_start,{groups_12_SUITE,{end_per_group,test_group_4,[]}}},
+ {?eh,tc_done,{groups_12_SUITE,{end_per_group,test_group_4,[]},ok}}],
+
+ {?eh,tc_start,{groups_12_SUITE,end_per_suite}},
+ {?eh,tc_done,{groups_12_SUITE,end_per_suite,init}},
+ {?eh,test_done,{'DEF','STOP_TIME'}},
+ {?eh,stop_logging,[]}];
+
+test_events(groups_dirs_1) ->
+ [{?eh,start_logging,{'DEF','RUNDIR'}},
+ {?eh,test_start,{'DEF',{'START_TIME','LOGDIR'}}},
+ {?eh,start_info,{2,4,unknown}},
+
+ {?eh,tc_start,{groups_11_SUITE,init_per_suite}},
+ {?eh,tc_done,{groups_11_SUITE,init_per_suite,ok}},
+ {?eh,tc_start,{groups_11_SUITE,testcase_1}},
+ {?eh,tc_done,{groups_11_SUITE,testcase_1,ok}},
+ {?eh,test_stats,{1,0,{0,0}}},
+
+ [{?eh,tc_start,{groups_11_SUITE,{init_per_group,test_group_1a,[]}}},
+ {?eh,tc_done,{groups_11_SUITE,{init_per_group,test_group_1a,[]},ok}},
+ {?eh,tc_start,{groups_11_SUITE,testcase_1a}},
+ {?eh,tc_done,{groups_11_SUITE,testcase_1a,ok}},
+ {?eh,test_stats,{2,0,{0,0}}},
+ {?eh,tc_start,{groups_11_SUITE,testcase_1b}},
+ {?eh,tc_done,{groups_11_SUITE,testcase_1b,ok}},
+ {?eh,test_stats,{3,0,{0,0}}},
+ {?eh,tc_start,{groups_11_SUITE,{end_per_group,test_group_1a,[]}}},
+ {?eh,tc_done,{groups_11_SUITE,{end_per_group,test_group_1a,[]},ok}}],
+
+ [{?eh,tc_start,{groups_11_SUITE,{init_per_group,test_group_1b,[]}}},
+ {?eh,tc_done,{groups_11_SUITE,{init_per_group,test_group_1b,[]},ok}},
+ {?eh,tc_start,{groups_11_SUITE,testcase_1a}},
+ {?eh,tc_done,{groups_11_SUITE,testcase_1a,ok}},
+ {?eh,test_stats,{4,0,{0,0}}},
+ {?eh,tc_start,{groups_11_SUITE,testcase_1b}},
+ {?eh,tc_done,{groups_11_SUITE,testcase_1b,ok}},
+ {?eh,test_stats,{5,0,{0,0}}},
+ {?eh,tc_start,{groups_11_SUITE,{end_per_group,test_group_1b,[]}}},
+ {?eh,tc_done,{groups_11_SUITE,{end_per_group,test_group_1b,[]},ok}}],
+
+ {?eh,tc_start,{groups_11_SUITE,testcase_2}},
+ {?eh,tc_done,{groups_11_SUITE,testcase_2,ok}},
+ {?eh,test_stats,{6,0,{0,0}}},
+
+ [{?eh,tc_start,{groups_11_SUITE,{init_per_group,test_group_2,[]}}},
+ {?eh,tc_done,{groups_11_SUITE,{init_per_group,test_group_2,[]},ok}},
+ {?eh,tc_start,{groups_11_SUITE,testcase_2a}},
+ {?eh,tc_done,{groups_11_SUITE,testcase_2a,ok}},
+ {?eh,test_stats,{7,0,{0,0}}},
+ [{?eh,tc_start,{groups_11_SUITE,{init_per_group,test_group_3,[]}}},
+ {?eh,tc_done,{groups_11_SUITE,{init_per_group,test_group_3,[]},ok}},
+ {?eh,tc_start,{groups_11_SUITE,testcase_3a}},
+ {?eh,tc_done,{groups_11_SUITE,testcase_3a,ok}},
+ {?eh,test_stats,{8,0,{0,0}}},
+ {?eh,tc_start,{groups_11_SUITE,testcase_3b}},
+ {?eh,tc_done,{groups_11_SUITE,testcase_3b,ok}},
+ {?eh,test_stats,{9,0,{0,0}}},
+ {?eh,tc_start,{groups_11_SUITE,{end_per_group,test_group_3,[]}}},
+ {?eh,tc_done,{groups_11_SUITE,{end_per_group,test_group_3,[]},ok}}],
+ {?eh,tc_start,{groups_11_SUITE,testcase_2b}},
+ {?eh,tc_done,{groups_11_SUITE,testcase_2b,ok}},
+ {?eh,test_stats,{10,0,{0,0}}},
+ {?eh,tc_start,{groups_11_SUITE,{end_per_group,test_group_2,[]}}},
+ {?eh,tc_done,{groups_11_SUITE,{end_per_group,test_group_2,[]},ok}}],
+
+ {?eh,tc_start,{groups_11_SUITE,testcase_3}},
+ {?eh,tc_done,{groups_11_SUITE,testcase_3,ok}},
+ {?eh,test_stats,{11,0,{0,0}}},
+
+ [{?eh,tc_start,{groups_11_SUITE,{init_per_group,test_group_4,[]}}},
+ {?eh,tc_done,{groups_11_SUITE,{init_per_group,test_group_4,[]},ok}},
+ [{?eh,tc_start,{groups_11_SUITE,{init_per_group,test_group_5,[]}}},
+ {?eh,tc_done,{groups_11_SUITE,{init_per_group,test_group_5,[]},ok}},
+ {?eh,tc_start,{groups_11_SUITE,testcase_5a}},
+ {?eh,tc_done,{groups_11_SUITE,testcase_5a,ok}},
+ {?eh,test_stats,{12,0,{0,0}}},
+ [{?eh,tc_start,{groups_11_SUITE,{init_per_group,test_group_6,[]}}},
+ {?eh,tc_done,{groups_11_SUITE,{init_per_group,test_group_6,[]},ok}},
+ [{?eh,tc_start,{groups_11_SUITE,{init_per_group,test_group_7,[]}}},
+ {?eh,tc_done,{groups_11_SUITE,{init_per_group,test_group_7,[]},ok}},
+ {?eh,tc_start,{groups_11_SUITE,testcase_7a}},
+ {?eh,tc_done,{groups_11_SUITE,testcase_7a,ok}},
+ {?eh,test_stats,{13,0,{0,0}}},
+ {?eh,tc_start,{groups_11_SUITE,testcase_7b}},
+ {?eh,tc_done,{groups_11_SUITE,testcase_7b,ok}},
+ {?eh,test_stats,{14,0,{0,0}}},
+ {?eh,tc_start,{groups_11_SUITE,{end_per_group,test_group_7,[]}}},
+ {?eh,tc_done,{groups_11_SUITE,{end_per_group,test_group_7,[]},ok}}],
+ {?eh,tc_start,{groups_11_SUITE,{end_per_group,test_group_6,[]}}},
+ {?eh,tc_done,{groups_11_SUITE,{end_per_group,test_group_6,[]},ok}}],
+ {?eh,tc_start,{groups_11_SUITE,testcase_5b}},
+ {?eh,tc_done,{groups_11_SUITE,testcase_5b,ok}},
+ {?eh,test_stats,{15,0,{0,0}}},
+ {?eh,tc_start,{groups_11_SUITE,{end_per_group,test_group_5,[]}}},
+ {?eh,tc_done,{groups_11_SUITE,{end_per_group,test_group_5,[]},ok}}],
+ {?eh,tc_start,{groups_11_SUITE,{end_per_group,test_group_4,[]}}},
+ {?eh,tc_done,{groups_11_SUITE,{end_per_group,test_group_4,[]},ok}}],
+
+ {?eh,tc_start,{groups_11_SUITE,end_per_suite}},
+ {?eh,tc_done,{groups_11_SUITE,end_per_suite,init}},
+
+ {?eh,tc_start,{groups_12_SUITE,init_per_suite}},
+ {?eh,tc_done,{groups_12_SUITE,init_per_suite,ok}},
+
+ {shuffle,[{?eh,tc_start,{groups_12_SUITE,{init_per_group,test_group_1a,[{shuffle,'_'}]}}},
+ {?eh,tc_done,{groups_12_SUITE,{init_per_group,test_group_1a,[{shuffle,'_'}]},ok}},
+ {?eh,tc_start,{groups_12_SUITE,testcase_1b}},
+ {?eh,tc_done,{groups_12_SUITE,testcase_1b,ok}},
+ {?eh,test_stats,{16,0,{0,0}}},
+ {?eh,tc_start,{groups_12_SUITE,testcase_1c}},
+ {?eh,tc_done,{groups_12_SUITE,testcase_1c,ok}},
+ {?eh,test_stats,{17,0,{0,0}}},
+ {?eh,tc_start,{groups_12_SUITE,testcase_1a}},
+ {?eh,tc_done,{groups_12_SUITE,testcase_1a,ok}},
+ {?eh,test_stats,{18,0,{0,0}}},
+ {?eh,tc_start,{groups_12_SUITE,{end_per_group,test_group_1a,[shuffle]}}},
+ {?eh,tc_done,{groups_12_SUITE,{end_per_group,test_group_1a,[shuffle]},ok}}]},
+ {parallel,[{?eh,tc_start,{groups_12_SUITE,{init_per_group,test_group_1b,[parallel]}}},
+ {?eh,tc_done,{groups_12_SUITE,{init_per_group,test_group_1b,[parallel]},ok}},
+ {?eh,tc_start,{groups_12_SUITE,testcase_1a}},
+ {?eh,tc_done,{groups_12_SUITE,testcase_1a,ok}},
+ {?eh,tc_start,{groups_12_SUITE,testcase_1b}},
+ {?eh,tc_done,{groups_12_SUITE,testcase_1b,ok}},
+ {?eh,test_stats,{20,0,{0,0}}},
+ {?eh,tc_start,{groups_12_SUITE,{end_per_group,test_group_1b,[parallel]}}},
+ {?eh,tc_done,{groups_12_SUITE,{end_per_group,test_group_1b,[parallel]},ok}}]},
+ {?eh,tc_start,{groups_12_SUITE,testcase_1}},
+ {?eh,tc_done,{groups_12_SUITE,testcase_1,ok}},
+ {?eh,test_stats,{21,0,{0,0}}},
+ {?eh,tc_start,{groups_12_SUITE,testcase_2}},
+ {?eh,tc_done,{groups_12_SUITE,testcase_2,ok}},
+ {?eh,test_stats,{22,0,{0,0}}},
+
+ {parallel,[{?eh,tc_start,{groups_12_SUITE,{init_per_group,test_group_2,[parallel]}}},
+ {?eh,tc_done,{groups_12_SUITE,{init_per_group,test_group_2,[parallel]},ok}},
+ {?eh,tc_start,{groups_12_SUITE,testcase_2a}},
+ {?eh,tc_done,{groups_12_SUITE,testcase_2a,ok}},
+ [{?eh,tc_start,{groups_12_SUITE,{init_per_group,test_group_3,[{repeat,1}]}}},
+ {?eh,tc_done,{groups_12_SUITE,{init_per_group,test_group_3,[{repeat,1}]},ok}},
+ {?eh,tc_start,{groups_12_SUITE,testcase_3a}},
+ {?eh,tc_done,{groups_12_SUITE,testcase_3a,ok}},
+ {?eh,tc_start,{groups_12_SUITE,testcase_3b}},
+ {?eh,tc_done,{groups_12_SUITE,testcase_3b,ok}},
+ {?eh,tc_start,{groups_12_SUITE,{end_per_group,test_group_3,[{repeat,1}]}}},
+ {?eh,tc_done,{groups_12_SUITE,{end_per_group,test_group_3,[{repeat,1}]},ok}}],
+ [{?eh,tc_start,{groups_12_SUITE,{init_per_group,test_group_3,[]}}},
+ {?eh,tc_done,{groups_12_SUITE,{init_per_group,test_group_3,[]},ok}},
+ {?eh,tc_start,{groups_12_SUITE,testcase_3a}},
+ {?eh,tc_done,{groups_12_SUITE,testcase_3a,ok}},
+ {?eh,tc_start,{groups_12_SUITE,testcase_3b}},
+ {?eh,tc_done,{groups_12_SUITE,testcase_3b,ok}},
+ {?eh,tc_start,{groups_12_SUITE,{end_per_group,test_group_3,[]}}},
+ {?eh,tc_done,{groups_12_SUITE,{end_per_group,test_group_3,[]},ok}}],
+ {?eh,tc_start,{groups_12_SUITE,testcase_2b}},
+ {?eh,tc_done,{groups_12_SUITE,testcase_2b,ok}},
+ {?eh,test_stats,{28,0,{0,0}}},
+ {?eh,tc_start,{groups_12_SUITE,{end_per_group,test_group_2,[parallel]}}},
+ {?eh,tc_done,{groups_12_SUITE,{end_per_group,test_group_2,[parallel]},ok}}]},
+
+ {?eh,tc_start,{groups_12_SUITE,testcase_3}},
+ {?eh,tc_done,{groups_12_SUITE,testcase_3,ok}},
+ {?eh,test_stats,{29,0,{0,0}}},
+
+ [{?eh,tc_start,{groups_12_SUITE,{init_per_group,test_group_4,[]}}},
+ {?eh,tc_done,{groups_12_SUITE,{init_per_group,test_group_4,[]},ok}},
+ {parallel,[{?eh,tc_start,{groups_12_SUITE,{init_per_group,test_group_5,[parallel]}}},
+ {?eh,tc_done,{groups_12_SUITE,{init_per_group,test_group_5,[parallel]},ok}},
+
+ %% the done event could come in during the parallel subgroup
+ %% and we can't test that, yet...
+ %% {?eh,tc_start,{groups_12_SUITE,testcase_5a}},
+ %% {?eh,tc_done,{groups_12_SUITE,testcase_5a,ok}},
+
+ {parallel,[{?eh,tc_start,{groups_12_SUITE,{init_per_group,test_group_6,[parallel]}}},
+ {?eh,tc_done,{groups_12_SUITE,{init_per_group,test_group_6,[parallel]},ok}},
+ [{?eh,tc_start,{groups_12_SUITE,{init_per_group,test_group_7,[sequence]}}},
+ {?eh,tc_done,{groups_12_SUITE,{init_per_group,test_group_7,[sequence]},ok}},
+ {?eh,tc_start,{groups_12_SUITE,testcase_7a}},
+ {?eh,tc_done,{groups_12_SUITE,testcase_7a,ok}},
+ {?eh,tc_start,{groups_12_SUITE,testcase_7b}},
+ {?eh,tc_done,{groups_12_SUITE,testcase_7b,ok}},
+ {?eh,tc_start,{groups_12_SUITE,{end_per_group,test_group_7,[sequence]}}},
+ {?eh,tc_done,{groups_12_SUITE,{end_per_group,test_group_7,[sequence]},ok}}],
+ {?eh,tc_start,{groups_12_SUITE,{end_per_group,test_group_6,[parallel]}}},
+ {?eh,tc_done,{groups_12_SUITE,{end_per_group,test_group_6,[parallel]},ok}}]},
+ {?eh,tc_start,{groups_12_SUITE,testcase_5b}},
+ {?eh,tc_done,{groups_12_SUITE,testcase_5b,ok}},
+ {?eh,test_stats,{33,0,{0,0}}},
+ {?eh,tc_start,{groups_12_SUITE,{end_per_group,test_group_5,[parallel]}}},
+ {?eh,tc_done,{groups_12_SUITE,{end_per_group,test_group_5,[parallel]},ok}}]},
+ {?eh,tc_start,{groups_12_SUITE,{end_per_group,test_group_4,[]}}},
+ {?eh,tc_done,{groups_12_SUITE,{end_per_group,test_group_4,[]},ok}}],
+
+ {?eh,tc_start,{groups_12_SUITE,end_per_suite}},
+ {?eh,tc_done,{groups_12_SUITE,end_per_suite,init}},
+
+ {?eh,tc_start,{groups_21_SUITE,init_per_suite}},
+ {?eh,tc_done,{groups_21_SUITE,init_per_suite,ok}},
+ {?eh,tc_start,{groups_21_SUITE,testcase_1}},
+ {?eh,tc_done,{groups_21_SUITE,testcase_1,ok}},
+ {?eh,test_stats,{34,0,{0,0}}},
+
+ [{?eh,tc_start,
+ {groups_21_SUITE,{init_per_group,test_group_1a,[]}}},
+ {?eh,tc_done,
+ {groups_21_SUITE,{init_per_group,test_group_1a,[]},ok}},
+ {?eh,tc_start,{groups_21_SUITE,testcase_1a}},
+ {?eh,tc_done,{groups_21_SUITE,testcase_1a,ok}},
+ {?eh,test_stats,{35,0,{0,0}}},
+ {?eh,tc_start,{groups_21_SUITE,testcase_1b}},
+ {?eh,tc_done,{groups_21_SUITE,testcase_1b,ok}},
+ {?eh,test_stats,{36,0,{0,0}}},
+ {?eh,tc_start,
+ {groups_21_SUITE,{end_per_group,test_group_1a,[]}}},
+ {?eh,tc_done,
+ {groups_21_SUITE,{end_per_group,test_group_1a,[]},ok}}],
+
+ [{?eh,tc_start,
+ {groups_21_SUITE,{init_per_group,test_group_1b,[]}}},
+ {?eh,tc_done,
+ {groups_21_SUITE,{init_per_group,test_group_1b,[]},ok}},
+ {?eh,tc_start,{groups_21_SUITE,testcase_1a}},
+ {?eh,tc_done,{groups_21_SUITE,testcase_1a,ok}},
+ {?eh,test_stats,{37,0,{0,0}}},
+ {?eh,tc_start,{groups_21_SUITE,testcase_1b}},
+ {?eh,tc_done,{groups_21_SUITE,testcase_1b,ok}},
+ {?eh,test_stats,{38,0,{0,0}}},
+ {?eh,tc_start,
+ {groups_21_SUITE,{end_per_group,test_group_1b,[]}}},
+ {?eh,tc_done,
+ {groups_21_SUITE,{end_per_group,test_group_1b,[]},ok}}],
+ {?eh,tc_start,{groups_21_SUITE,testcase_2}},
+ {?eh,tc_done,{groups_21_SUITE,testcase_2,ok}},
+ {?eh,test_stats,{39,0,{0,0}}},
+
+ [{?eh,tc_start,
+ {groups_21_SUITE,{init_per_group,test_group_2,[]}}},
+ {?eh,tc_done,
+ {groups_21_SUITE,{init_per_group,test_group_2,[]},ok}},
+ {?eh,tc_start,{groups_21_SUITE,testcase_2a}},
+ {?eh,tc_done,{groups_21_SUITE,testcase_2a,ok}},
+ {?eh,test_stats,{40,0,{0,0}}},
+ [{?eh,tc_start,
+ {groups_21_SUITE,{init_per_group,test_group_3,[]}}},
+ {?eh,tc_done,
+ {groups_21_SUITE,{init_per_group,test_group_3,[]},ok}},
+ {?eh,tc_start,{groups_21_SUITE,testcase_3a}},
+ {?eh,tc_done,{groups_21_SUITE,testcase_3a,ok}},
+ {?eh,test_stats,{41,0,{0,0}}},
+ {?eh,tc_start,{groups_21_SUITE,testcase_3b}},
+ {?eh,tc_done,{groups_21_SUITE,testcase_3b,ok}},
+ {?eh,test_stats,{42,0,{0,0}}},
+ {?eh,tc_start,
+ {groups_21_SUITE,{end_per_group,test_group_3,[]}}},
+ {?eh,tc_done,
+ {groups_21_SUITE,{end_per_group,test_group_3,[]},ok}}],
+ {?eh,tc_start,{groups_21_SUITE,testcase_2b}},
+ {?eh,tc_done,{groups_21_SUITE,testcase_2b,ok}},
+ {?eh,test_stats,{43,0,{0,0}}},
+ {?eh,tc_start,
+ {groups_21_SUITE,{end_per_group,test_group_2,[]}}},
+ {?eh,tc_done,
+ {groups_21_SUITE,{end_per_group,test_group_2,[]},ok}}],
+
+ {?eh,tc_start,{groups_21_SUITE,testcase_3}},
+ {?eh,tc_done,{groups_21_SUITE,testcase_3,ok}},
+ {?eh,test_stats,{44,0,{0,0}}},
+
+ [{?eh,tc_start,
+ {groups_21_SUITE,{init_per_group,test_group_4,[]}}},
+ {?eh,tc_done,
+ {groups_21_SUITE,{init_per_group,test_group_4,[]},ok}},
+ [{?eh,tc_start,
+ {groups_21_SUITE,{init_per_group,test_group_5,[]}}},
+ {?eh,tc_done,
+ {groups_21_SUITE,{init_per_group,test_group_5,[]},ok}},
+ {?eh,tc_start,{groups_21_SUITE,testcase_5a}},
+ {?eh,tc_done,{groups_21_SUITE,testcase_5a,ok}},
+ {?eh,test_stats,{45,0,{0,0}}},
+ [{?eh,tc_start,
+ {groups_21_SUITE,{init_per_group,test_group_6,[]}}},
+ {?eh,tc_done,
+ {groups_21_SUITE,{init_per_group,test_group_6,[]},ok}},
+ [{?eh,tc_start,
+ {groups_21_SUITE,{init_per_group,test_group_7,[]}}},
+ {?eh,tc_done,
+ {groups_21_SUITE,{init_per_group,test_group_7,[]},ok}},
+ {?eh,tc_start,{groups_21_SUITE,testcase_7a}},
+ {?eh,tc_done,{groups_21_SUITE,testcase_7a,ok}},
+ {?eh,test_stats,{46,0,{0,0}}},
+ {?eh,tc_start,{groups_21_SUITE,testcase_7b}},
+ {?eh,tc_done,{groups_21_SUITE,testcase_7b,ok}},
+ {?eh,test_stats,{47,0,{0,0}}},
+ {?eh,tc_start,
+ {groups_21_SUITE,{end_per_group,test_group_7,[]}}},
+ {?eh,tc_done,
+ {groups_21_SUITE,{end_per_group,test_group_7,[]},ok}}],
+ {?eh,tc_start,
+ {groups_21_SUITE,{end_per_group,test_group_6,[]}}},
+ {?eh,tc_done,
+ {groups_21_SUITE,{end_per_group,test_group_6,[]},ok}}],
+ {?eh,tc_start,{groups_21_SUITE,testcase_5b}},
+ {?eh,tc_done,{groups_21_SUITE,testcase_5b,ok}},
+ {?eh,test_stats,{48,0,{0,0}}},
+ {?eh,tc_start,
+ {groups_21_SUITE,{end_per_group,test_group_5,[]}}},
+ {?eh,tc_done,
+ {groups_21_SUITE,{end_per_group,test_group_5,[]},ok}}],
+ {?eh,tc_start,
+ {groups_21_SUITE,{end_per_group,test_group_4,[]}}},
+ {?eh,tc_done,
+ {groups_21_SUITE,{end_per_group,test_group_4,[]},ok}}],
+
+ {?eh,tc_start,{groups_21_SUITE,end_per_suite}},
+ {?eh,tc_done,{groups_21_SUITE,end_per_suite,init}},
+
+ {?eh,tc_start,{groups_22_SUITE,init_per_suite}},
+ {?eh,tc_done,{groups_22_SUITE,init_per_suite,ok}},
+
+ {shuffle,
+ [{?eh,tc_start,
+ {groups_22_SUITE,
+ {init_per_group,test_group_1a,[{shuffle,'_'}]}}},
+ {?eh,tc_done,
+ {groups_22_SUITE,
+ {init_per_group,test_group_1a,[{shuffle,'_'}]},
+ ok}},
+ {?eh,tc_start,{groups_22_SUITE,testcase_1a}},
+ {?eh,tc_done,{groups_22_SUITE,testcase_1a,ok}},
+ {?eh,tc_start,{groups_22_SUITE,testcase_1b}},
+ {?eh,tc_done,{groups_22_SUITE,testcase_1b,ok}},
+ {?eh,tc_start,{groups_22_SUITE,testcase_1c}},
+ {?eh,tc_done,{groups_22_SUITE,testcase_1c,ok}},
+ {?eh,test_stats,{51,0,{0,0}}},
+ {?eh,tc_start,
+ {groups_22_SUITE,{end_per_group,test_group_1a,[shuffle]}}},
+ {?eh,tc_done,
+ {groups_22_SUITE,{end_per_group,test_group_1a,[shuffle]},ok}}]},
+
+ {parallel,
+ [{?eh,tc_start,
+ {groups_22_SUITE,{init_per_group,test_group_1b,[parallel]}}},
+ {?eh,tc_done,
+ {groups_22_SUITE,{init_per_group,test_group_1b,[parallel]},ok}},
+ {?eh,tc_start,{groups_22_SUITE,testcase_1a}},
+ {?eh,tc_done,{groups_22_SUITE,testcase_1a,ok}},
+ {?eh,tc_start,{groups_22_SUITE,testcase_1b}},
+ {?eh,tc_done,{groups_22_SUITE,testcase_1b,ok}},
+ {?eh,test_stats,{53,0,{0,0}}},
+ {?eh,tc_start,
+ {groups_22_SUITE,{end_per_group,test_group_1b,[parallel]}}},
+ {?eh,tc_done,
+ {groups_22_SUITE,{end_per_group,test_group_1b,[parallel]},ok}}]},
+
+ {?eh,tc_start,{groups_22_SUITE,testcase_1}},
+ {?eh,tc_done,{groups_22_SUITE,testcase_1,ok}},
+ {?eh,test_stats,{54,0,{0,0}}},
+ {?eh,tc_start,{groups_22_SUITE,testcase_2}},
+ {?eh,tc_done,{groups_22_SUITE,testcase_2,ok}},
+ {?eh,test_stats,{55,0,{0,0}}},
+
+ {parallel,
+ [{?eh,tc_start,
+ {groups_22_SUITE,{init_per_group,test_group_2,[parallel]}}},
+ {?eh,tc_done,
+ {groups_22_SUITE,{init_per_group,test_group_2,[parallel]},ok}},
+ {?eh,tc_start,{groups_22_SUITE,testcase_2a}},
+ {?eh,tc_done,{groups_22_SUITE,testcase_2a,ok}},
+ [{?eh,tc_start,
+ {groups_22_SUITE,{init_per_group,test_group_3,[{repeat,1}]}}},
+ {?eh,tc_done,
+ {groups_22_SUITE,{init_per_group,test_group_3,[{repeat,1}]},ok}},
+ {?eh,tc_start,{groups_22_SUITE,testcase_3a}},
+ {?eh,tc_done,{groups_22_SUITE,testcase_3a,ok}},
+ {?eh,tc_start,{groups_22_SUITE,testcase_3b}},
+ {?eh,tc_done,{groups_22_SUITE,testcase_3b,ok}},
+ {?eh,tc_start,
+ {groups_22_SUITE,{end_per_group,test_group_3,[{repeat,1}]}}},
+ {?eh,tc_done,
+ {groups_22_SUITE,{end_per_group,test_group_3,[{repeat,1}]},ok}}],
+ [{?eh,tc_start,
+ {groups_22_SUITE,{init_per_group,test_group_3,[]}}},
+ {?eh,tc_done,
+ {groups_22_SUITE,{init_per_group,test_group_3,[]},ok}},
+ {?eh,tc_start,{groups_22_SUITE,testcase_3a}},
+ {?eh,tc_done,{groups_22_SUITE,testcase_3a,ok}},
+ {?eh,tc_start,{groups_22_SUITE,testcase_3b}},
+ {?eh,tc_done,{groups_22_SUITE,testcase_3b,ok}},
+ {?eh,tc_start,
+ {groups_22_SUITE,{end_per_group,test_group_3,[]}}},
+ {?eh,tc_done,
+ {groups_22_SUITE,{end_per_group,test_group_3,[]},ok}}],
+ {?eh,tc_start,{groups_22_SUITE,testcase_2b}},
+ {?eh,tc_done,{groups_22_SUITE,testcase_2b,ok}},
+ {?eh,test_stats,{61,0,{0,0}}},
+ {?eh,tc_start,
+ {groups_22_SUITE,{end_per_group,test_group_2,[parallel]}}},
+ {?eh,tc_done,
+ {groups_22_SUITE,{end_per_group,test_group_2,[parallel]},ok}}]},
+ {?eh,tc_start,{groups_22_SUITE,testcase_3}},
+ {?eh,tc_done,{groups_22_SUITE,testcase_3,ok}},
+ {?eh,test_stats,{62,0,{0,0}}},
+ [{?eh,tc_start,
+ {groups_22_SUITE,{init_per_group,test_group_4,[]}}},
+ {?eh,tc_done,
+ {groups_22_SUITE,{init_per_group,test_group_4,[]},ok}},
+
+ {parallel,
+ [{?eh,tc_start,
+ {groups_22_SUITE,{init_per_group,test_group_5,[parallel]}}},
+ {?eh,tc_done,
+ {groups_22_SUITE,{init_per_group,test_group_5,[parallel]},ok}},
+
+ %% the done event could come in during the parallel subgroup
+ %% and we can't test that, yet...
+ %% {?eh,tc_start,{groups_22_SUITE,testcase_5a}},
+ %% {?eh,tc_done,{groups_22_SUITE,testcase_5a,ok}},
+
+ {parallel,
+ [{?eh,tc_start,
+ {groups_22_SUITE,{init_per_group,test_group_6,[parallel]}}},
+ {?eh,tc_done,
+ {groups_22_SUITE,{init_per_group,test_group_6,[parallel]},ok}},
+ [{?eh,tc_start,
+ {groups_22_SUITE,{init_per_group,test_group_7,[sequence]}}},
+ {?eh,tc_done,
+ {groups_22_SUITE,{init_per_group,test_group_7,[sequence]},ok}},
+ {?eh,tc_start,{groups_22_SUITE,testcase_7a}},
+ {?eh,tc_done,{groups_22_SUITE,testcase_7a,ok}},
+ {?eh,tc_start,{groups_22_SUITE,testcase_7b}},
+ {?eh,tc_done,{groups_22_SUITE,testcase_7b,ok}},
+ {?eh,tc_start,
+ {groups_22_SUITE,{end_per_group,test_group_7,[sequence]}}},
+ {?eh,tc_done,
+ {groups_22_SUITE,{end_per_group,test_group_7,[sequence]},ok}}],
+ {?eh,tc_start,
+ {groups_22_SUITE,{end_per_group,test_group_6,[parallel]}}},
+ {?eh,tc_done,
+ {groups_22_SUITE,{end_per_group,test_group_6,[parallel]},ok}}]},
+ {?eh,tc_start,{groups_22_SUITE,testcase_5b}},
+ {?eh,tc_done,{groups_22_SUITE,testcase_5b,ok}},
+ {?eh,test_stats,{66,0,{0,0}}},
+ {?eh,tc_start,
+ {groups_22_SUITE,{end_per_group,test_group_5,[parallel]}}},
+ {?eh,tc_done,
+ {groups_22_SUITE,{end_per_group,test_group_5,[parallel]},ok}}]},
+ {?eh,tc_start,
+ {groups_22_SUITE,{end_per_group,test_group_4,[]}}},
+ {?eh,tc_done,
+ {groups_22_SUITE,{end_per_group,test_group_4,[]},ok}}],
+
+ {?eh,tc_start,{groups_22_SUITE,end_per_suite}},
+ {?eh,tc_done,{groups_22_SUITE,end_per_suite,init}},
+ {?eh,test_done,{'DEF','STOP_TIME'}},
+ {?eh,stop_logging,[]}].
diff --git a/lib/common_test/test/ct_groups_test_1_SUITE_data/groups_1/test/groups_11_SUITE.erl b/lib/common_test/test/ct_groups_test_1_SUITE_data/groups_1/test/groups_11_SUITE.erl
new file mode 100644
index 0000000000..c6d50443d0
--- /dev/null
+++ b/lib/common_test/test/ct_groups_test_1_SUITE_data/groups_1/test/groups_11_SUITE.erl
@@ -0,0 +1,280 @@
+%%
+%% %CopyrightBegin%
+%%
+%% 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(groups_11_SUITE).
+
+-compile(export_all).
+
+-include_lib("common_test/include/ct.hrl").
+
+%%====================================================================
+%% COMMON TEST CALLBACK FUNCTIONS
+%%====================================================================
+
+suite() ->
+ [{timetrap,{minutes,1}}].
+
+groups() ->
+ [
+ {test_group_1a, [testcase_1a,testcase_1b]},
+
+ {test_group_1b, [], [testcase_1a,testcase_1b]},
+
+ {test_group_2, [], [testcase_2a,
+
+ {test_group_3, [], [testcase_3a,
+ testcase_3b]},
+ testcase_2b]},
+
+ {test_group_4, [{test_group_5, [], [testcase_5a,
+
+ {group, test_group_6},
+
+ testcase_5b]}]},
+
+ {test_group_6, [{group, test_group_7}]},
+
+ {test_group_7, [testcase_7a,testcase_7b]}
+ ].
+
+all() ->
+ [testcase_1,
+ {group, test_group_1a},
+ {group, test_group_1b},
+ testcase_2,
+ {group, test_group_2},
+ testcase_3,
+ {group, test_group_4}].
+
+%% this func only for internal test purposes
+grs_and_tcs() ->
+ {[
+ test_group_1a, test_group_1b,
+ test_group_2, test_group_3,
+ test_group_4, test_group_5,
+ test_group_6, test_group_7
+ ],
+ [
+ testcase_1,
+ testcase_1a, testcase_1b,
+ testcase_2,
+ testcase_2a, testcase_2b,
+ testcase_3a, testcase_3b,
+ testcase_3,
+ testcase_5a, testcase_5b,
+ testcase_7a, testcase_7b
+ ]}.
+
+%%--------------------------------------------------------------------
+%% Suite Configuration
+%%--------------------------------------------------------------------
+
+init_per_suite(Config) ->
+ [{suite,init}|Config].
+
+end_per_suite(Config) ->
+ init = ?config(suite,Config).
+
+%%--------------------------------------------------------------------
+%% Group Configuration
+%%--------------------------------------------------------------------
+
+init_per_group(Group, Config) ->
+ [{name,Group}] = ?config(tc_group_properties,Config),
+ {Grs,_} = grs_and_tcs(),
+ case lists:member(Group, Grs) of
+ true ->
+ init = ?config(suite,Config),
+ [{Group,Group} | Config];
+ false ->
+ ct:fail({bad_group,Group})
+ end.
+
+end_per_group(Group, Config) ->
+ {Grs,_} = grs_and_tcs(),
+ case lists:member(Group, Grs) of
+ true ->
+ init = ?config(suite,Config),
+ Group = ?config(Group,Config),
+ ok;
+ false ->
+ ct:fail({bad_group,Group})
+ end.
+
+%%--------------------------------------------------------------------
+%% Testcase Configuration
+%%--------------------------------------------------------------------
+
+init_per_testcase(TestCase, Config) ->
+ {_,TCs} = grs_and_tcs(),
+ case lists:member(TestCase, TCs) of
+ true ->
+ init = ?config(suite,Config),
+ [{TestCase,TestCase} | Config];
+ false ->
+ ct:fail({unknown_testcase,TestCase})
+ end.
+
+end_per_testcase(TestCase, Config) ->
+ {_,TCs} = grs_and_tcs(),
+ case lists:member(TestCase, TCs) of
+ true ->
+ init = ?config(suite,Config),
+ TestCase = ?config(TestCase,Config),
+ ok;
+ false ->
+ ct:fail({unknown_testcase,TestCase})
+ end.
+
+
+%%--------------------------------------------------------------------
+%% Testcases
+%%--------------------------------------------------------------------
+
+testcase_1() ->
+ [].
+testcase_1(Config) ->
+ init = ?config(suite,Config),
+ testcase_1 = ?config(testcase_1,Config),
+ ok.
+
+testcase_1a() ->
+ [].
+testcase_1a(Config) ->
+ init = ?config(suite,Config),
+ case ?config(test_group_1a,Config) of
+ test_group_1a -> ok;
+ _ ->
+ case ?config(test_group_1b,Config) of
+ test_group_1b -> ok;
+ _ -> ct:fail(no_group_data)
+ end
+ end,
+ testcase_1a = ?config(testcase_1a,Config),
+ ok.
+testcase_1b() ->
+ [].
+testcase_1b(Config) ->
+ init = ?config(suite,Config),
+ case ?config(test_group_1a,Config) of
+ test_group_1a -> ok;
+ _ ->
+ case ?config(test_group_1b,Config) of
+ test_group_1b -> ok;
+ _ -> ct:fail(no_group_data)
+ end
+ end,
+ undefined = ?config(testcase_1a,Config),
+ testcase_1b = ?config(testcase_1b,Config),
+ ok.
+
+testcase_2() ->
+ [].
+testcase_2(Config) ->
+ init = ?config(suite,Config),
+ undefined = ?config(test_group_1a,Config),
+ undefined = ?config(test_group_1b,Config),
+ testcase_2 = ?config(testcase_2,Config),
+ ok.
+
+testcase_2a() ->
+ [].
+testcase_2a(Config) ->
+ init = ?config(suite,Config),
+ test_group_2 = ?config(test_group_2,Config),
+ testcase_2a = ?config(testcase_2a,Config),
+ ok.
+testcase_2b() ->
+ [].
+testcase_2b(Config) ->
+ init = ?config(suite,Config),
+ test_group_2 = ?config(test_group_2,Config),
+ undefined = ?config(testcase_2a,Config),
+ testcase_2b = ?config(testcase_2b,Config),
+ ok.
+
+testcase_3a() ->
+ [].
+testcase_3a(Config) ->
+ init = ?config(suite,Config),
+ test_group_2 = ?config(test_group_2,Config),
+ test_group_3 = ?config(test_group_3,Config),
+ undefined = ?config(testcase_2b,Config),
+ testcase_3a = ?config(testcase_3a,Config),
+ ok.
+testcase_3b() ->
+ [].
+testcase_3b(Config) ->
+ init = ?config(suite,Config),
+ test_group_2 = ?config(test_group_2,Config),
+ test_group_3 = ?config(test_group_3,Config),
+ undefined = ?config(testcase_3a,Config),
+ testcase_3b = ?config(testcase_3b,Config),
+ ok.
+
+testcase_3() ->
+ [].
+testcase_3(Config) ->
+ init = ?config(suite,Config),
+ undefined = ?config(test_group_2,Config),
+ undefined = ?config(test_group_3,Config),
+ testcase_3 = ?config(testcase_3,Config),
+ ok.
+
+testcase_5a() ->
+ [].
+testcase_5a(Config) ->
+ init = ?config(suite,Config),
+ undefined = ?config(test_group_3,Config),
+ test_group_4 = ?config(test_group_4,Config),
+ test_group_5 = ?config(test_group_5,Config),
+ undefined = ?config(testcase_3,Config),
+ testcase_5a = ?config(testcase_5a,Config),
+ ok.
+testcase_5b() ->
+ [].
+testcase_5b(Config) ->
+ init = ?config(suite,Config),
+ test_group_4 = ?config(test_group_4,Config),
+ test_group_5 = ?config(test_group_5,Config),
+ undefined = ?config(testcase_5a,Config),
+ testcase_5b = ?config(testcase_5b,Config),
+ ok.
+
+testcase_7a() ->
+ [].
+testcase_7a(Config) ->
+ init = ?config(suite,Config),
+ undefined = ?config(test_group_3,Config),
+ test_group_4 = ?config(test_group_4,Config),
+ test_group_5 = ?config(test_group_5,Config),
+ test_group_6 = ?config(test_group_6,Config),
+ test_group_7 = ?config(test_group_7,Config),
+ testcase_7a = ?config(testcase_7a,Config),
+ ok.
+testcase_7b() ->
+ [].
+testcase_7b(Config) ->
+ init = ?config(suite,Config),
+ test_group_4 = ?config(test_group_4,Config),
+ test_group_5 = ?config(test_group_5,Config),
+ test_group_6 = ?config(test_group_6,Config),
+ test_group_7 = ?config(test_group_7,Config),
+ undefined = ?config(testcase_7a,Config),
+ testcase_7b = ?config(testcase_7b,Config),
+ ok.
diff --git a/lib/common_test/test/ct_groups_test_1_SUITE_data/groups_1/test/groups_12_SUITE.erl b/lib/common_test/test/ct_groups_test_1_SUITE_data/groups_1/test/groups_12_SUITE.erl
new file mode 100644
index 0000000000..b261ef581f
--- /dev/null
+++ b/lib/common_test/test/ct_groups_test_1_SUITE_data/groups_1/test/groups_12_SUITE.erl
@@ -0,0 +1,310 @@
+%%
+%% %CopyrightBegin%
+%%
+%% 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(groups_12_SUITE).
+
+-compile(export_all).
+
+-include_lib("common_test/include/ct.hrl").
+
+%%====================================================================
+%% COMMON TEST CALLBACK FUNCTIONS
+%%====================================================================
+
+suite() ->
+ [{timetrap,{minutes,1}}].
+
+groups() ->
+ [
+ {test_group_1a, [shuffle], [testcase_1a,testcase_1b,testcase_1c]},
+
+ {test_group_1b, [parallel], [testcase_1a,testcase_1b]},
+
+ {test_group_2, [parallel], [testcase_2a,
+
+ {test_group_3, [{repeat,1}],
+ [testcase_3a, testcase_3b]},
+
+ testcase_2b]},
+
+ {test_group_4, [{test_group_5, [parallel], [testcase_5a,
+
+ {group, test_group_6},
+
+ testcase_5b]}]},
+
+ {test_group_6, [parallel], [{group, test_group_7}]},
+
+ {test_group_7, [sequence], [testcase_7a,testcase_7b]}
+ ].
+
+all() ->
+ [{group, test_group_1a},
+ {group, test_group_1b},
+ testcase_1,
+ testcase_2,
+ {group, test_group_2},
+ testcase_3,
+ {group, test_group_4}].
+
+%% this func only for internal test purposes
+grs_and_tcs() ->
+ {[
+ test_group_1a, test_group_1b,
+ test_group_2, test_group_3,
+ test_group_4, test_group_5,
+ test_group_6, test_group_7
+ ],
+ [
+ testcase_1a, testcase_1b, testcase_1c,
+ testcase_1,
+ testcase_2,
+ testcase_2a, testcase_2b,
+ testcase_3a, testcase_3b,
+ testcase_3,
+ testcase_5a, testcase_5b,
+ testcase_7a, testcase_7b
+ ]}.
+
+%%--------------------------------------------------------------------
+%% Suite Configuration
+%%--------------------------------------------------------------------
+
+init_per_suite(Config) ->
+ [{suite,init}|Config].
+
+end_per_suite(Config) ->
+ init = ?config(suite,Config).
+
+%%--------------------------------------------------------------------
+%% Group Configuration
+%%--------------------------------------------------------------------
+
+init_per_group(Group, Config) ->
+ Cmt =
+ case {Group,?config(tc_group_properties,Config)} of
+ {test_group_1a,[{shuffle,S},{name,test_group_1a}]} ->
+ io_lib:format("shuffled, ~w", [S]);
+ {test_group_1b,[{name,test_group_1b},parallel]} -> "parallel";
+ {test_group_2,[{name,test_group_2},parallel]} -> "parallel";
+ {test_group_3,[{name,test_group_3},{repeat,1}]} -> "repeat 1";
+ {test_group_3,[{name,test_group_3}]} -> "repeat 0";
+ {test_group_4,[{name,test_group_4}]} -> ok;
+ {test_group_5,[{name,test_group_5},parallel]} -> "parallel";
+ {test_group_6,[{name,test_group_6},parallel]} -> "parallel";
+ {test_group_7,[{name,test_group_7},sequence]} -> "sequence"
+ end,
+ {Grs,_} = grs_and_tcs(),
+ case lists:member(Group, Grs) of
+ true ->
+ init = ?config(suite,Config),
+ ct:comment(io_lib:format("~w, ~s", [Group,Cmt])),
+ [{Group,Group} | Config];
+ false ->
+ ct:fail({bad_group,Group})
+ end.
+
+end_per_group(Group, Config) ->
+ {Grs,_} = grs_and_tcs(),
+ case lists:member(Group, Grs) of
+ true ->
+ init = ?config(suite,Config),
+ Group = ?config(Group,Config),
+ ok;
+ false ->
+ ct:fail({bad_group,Group})
+ end.
+
+%%--------------------------------------------------------------------
+%% Testcase Configuration
+%%--------------------------------------------------------------------
+
+init_per_testcase(TestCase, Config) ->
+ {_,TCs} = grs_and_tcs(),
+ case lists:member(TestCase, TCs) of
+ true ->
+ init = ?config(suite,Config),
+ [{TestCase,TestCase} | Config];
+ false ->
+ ct:fail({unknown_testcase,TestCase})
+ end.
+
+end_per_testcase(TestCase, Config) ->
+ {_,TCs} = grs_and_tcs(),
+ case lists:member(TestCase, TCs) of
+ true ->
+ init = ?config(suite,Config),
+ TestCase = ?config(TestCase,Config),
+ ok;
+ false ->
+ ct:fail({unknown_testcase,TestCase})
+ end.
+
+
+%%--------------------------------------------------------------------
+%% Testcases
+%%--------------------------------------------------------------------
+
+testcase_1a() ->
+ [].
+testcase_1a(Config) ->
+ init = ?config(suite,Config),
+ case ?config(test_group_1a,Config) of
+ test_group_1a -> ok;
+ _ ->
+ case ?config(test_group_1b,Config) of
+ test_group_1b -> ok;
+ _ -> ct:fail(no_group_data)
+ end
+ end,
+ testcase_1a = ?config(testcase_1a,Config),
+ ok.
+testcase_1b() ->
+ [].
+testcase_1b(Config) ->
+ init = ?config(suite,Config),
+ case ?config(test_group_1a,Config) of
+ test_group_1a -> ok;
+ _ ->
+ case ?config(test_group_1b,Config) of
+ test_group_1b -> ok;
+ _ -> ct:fail(no_group_data)
+ end
+ end,
+ undefined = ?config(testcase_1a,Config),
+ testcase_1b = ?config(testcase_1b,Config),
+ ok.
+
+testcase_1c() ->
+ [].
+testcase_1c(Config) ->
+ init = ?config(suite,Config),
+ case ?config(test_group_1a,Config) of
+ test_group_1a -> ok;
+ _ ->
+ case ?config(test_group_1b,Config) of
+ test_group_1b -> ok;
+ _ -> ct:fail(no_group_data)
+ end
+ end,
+ undefined = ?config(testcase_1b,Config),
+ testcase_1c = ?config(testcase_1c,Config),
+ ok.
+
+testcase_1() ->
+ [].
+testcase_1(Config) ->
+ init = ?config(suite,Config),
+ testcase_1 = ?config(testcase_1,Config),
+ ok.
+
+testcase_2() ->
+ [].
+testcase_2(Config) ->
+ init = ?config(suite,Config),
+ undefined = ?config(test_group_1a,Config),
+ undefined = ?config(test_group_1b,Config),
+ testcase_2 = ?config(testcase_2,Config),
+ ok.
+
+testcase_2a() ->
+ [].
+testcase_2a(Config) ->
+ init = ?config(suite,Config),
+ test_group_2 = ?config(test_group_2,Config),
+ testcase_2a = ?config(testcase_2a,Config),
+ ok.
+testcase_2b() ->
+ [].
+testcase_2b(Config) ->
+ init = ?config(suite,Config),
+ test_group_2 = ?config(test_group_2,Config),
+ undefined = ?config(testcase_2a,Config),
+ testcase_2b = ?config(testcase_2b,Config),
+ ok.
+
+testcase_3a() ->
+ [].
+testcase_3a(Config) ->
+ init = ?config(suite,Config),
+ test_group_2 = ?config(test_group_2,Config),
+ test_group_3 = ?config(test_group_3,Config),
+ undefined = ?config(testcase_2b,Config),
+ testcase_3a = ?config(testcase_3a,Config),
+ ok.
+testcase_3b() ->
+ [].
+testcase_3b(Config) ->
+ init = ?config(suite,Config),
+ test_group_2 = ?config(test_group_2,Config),
+ test_group_3 = ?config(test_group_3,Config),
+ undefined = ?config(testcase_3a,Config),
+ testcase_3b = ?config(testcase_3b,Config),
+ ok.
+
+testcase_3() ->
+ [].
+testcase_3(Config) ->
+ init = ?config(suite,Config),
+ undefined = ?config(test_group_2,Config),
+ undefined = ?config(test_group_3,Config),
+ testcase_3 = ?config(testcase_3,Config),
+ ok.
+
+testcase_5a() ->
+ [].
+testcase_5a(Config) ->
+ init = ?config(suite,Config),
+ undefined = ?config(test_group_3,Config),
+ test_group_4 = ?config(test_group_4,Config),
+ test_group_5 = ?config(test_group_5,Config),
+ undefined = ?config(testcase_3,Config),
+ testcase_5a = ?config(testcase_5a,Config),
+ ok.
+testcase_5b() ->
+ [].
+testcase_5b(Config) ->
+ init = ?config(suite,Config),
+ test_group_4 = ?config(test_group_4,Config),
+ test_group_5 = ?config(test_group_5,Config),
+ undefined = ?config(testcase_5a,Config),
+ testcase_5b = ?config(testcase_5b,Config),
+ ok.
+
+testcase_7a() ->
+ [].
+testcase_7a(Config) ->
+ init = ?config(suite,Config),
+ undefined = ?config(test_group_3,Config),
+ test_group_4 = ?config(test_group_4,Config),
+ test_group_5 = ?config(test_group_5,Config),
+ test_group_6 = ?config(test_group_6,Config),
+ test_group_7 = ?config(test_group_7,Config),
+ testcase_7a = ?config(testcase_7a,Config),
+ ok.
+testcase_7b() ->
+ [].
+testcase_7b(Config) ->
+ init = ?config(suite,Config),
+ test_group_4 = ?config(test_group_4,Config),
+ test_group_5 = ?config(test_group_5,Config),
+ test_group_6 = ?config(test_group_6,Config),
+ test_group_7 = ?config(test_group_7,Config),
+ undefined = ?config(testcase_7a,Config),
+ testcase_7b = ?config(testcase_7b,Config),
+ ok.
diff --git a/lib/common_test/test/ct_groups_test_1_SUITE_data/groups_2/test/groups_21_SUITE.erl b/lib/common_test/test/ct_groups_test_1_SUITE_data/groups_2/test/groups_21_SUITE.erl
new file mode 100644
index 0000000000..42b10d1803
--- /dev/null
+++ b/lib/common_test/test/ct_groups_test_1_SUITE_data/groups_2/test/groups_21_SUITE.erl
@@ -0,0 +1,280 @@
+%%
+%% %CopyrightBegin%
+%%
+%% 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(groups_21_SUITE).
+
+-compile(export_all).
+
+-include_lib("common_test/include/ct.hrl").
+
+%%====================================================================
+%% COMMON TEST CALLBACK FUNCTIONS
+%%====================================================================
+
+suite() ->
+ [{timetrap,{minutes,1}}].
+
+groups() ->
+ [
+ {test_group_1a, [testcase_1a,testcase_1b]},
+
+ {test_group_1b, [], [testcase_1a,testcase_1b]},
+
+ {test_group_2, [], [testcase_2a,
+
+ {test_group_3, [], [testcase_3a,
+ testcase_3b]},
+ testcase_2b]},
+
+ {test_group_4, [{test_group_5, [], [testcase_5a,
+
+ {group, test_group_6},
+
+ testcase_5b]}]},
+
+ {test_group_6, [{group, test_group_7}]},
+
+ {test_group_7, [testcase_7a,testcase_7b]}
+ ].
+
+all() ->
+ [testcase_1,
+ {group, test_group_1a},
+ {group, test_group_1b},
+ testcase_2,
+ {group, test_group_2},
+ testcase_3,
+ {group, test_group_4}].
+
+%% this func only for internal test purposes
+grs_and_tcs() ->
+ {[
+ test_group_1a, test_group_1b,
+ test_group_2, test_group_3,
+ test_group_4, test_group_5,
+ test_group_6, test_group_7
+ ],
+ [
+ testcase_1,
+ testcase_1a, testcase_1b,
+ testcase_2,
+ testcase_2a, testcase_2b,
+ testcase_3a, testcase_3b,
+ testcase_3,
+ testcase_5a, testcase_5b,
+ testcase_7a, testcase_7b
+ ]}.
+
+%%--------------------------------------------------------------------
+%% Suite Configuration
+%%--------------------------------------------------------------------
+
+init_per_suite(Config) ->
+ [{suite,init}|Config].
+
+end_per_suite(Config) ->
+ init = ?config(suite,Config).
+
+%%--------------------------------------------------------------------
+%% Group Configuration
+%%--------------------------------------------------------------------
+
+init_per_group(Group, Config) ->
+ [{name,Group}] = ?config(tc_group_properties,Config),
+ {Grs,_} = grs_and_tcs(),
+ case lists:member(Group, Grs) of
+ true ->
+ init = ?config(suite,Config),
+ [{Group,Group} | Config];
+ false ->
+ ct:fail({bad_group,Group})
+ end.
+
+end_per_group(Group, Config) ->
+ {Grs,_} = grs_and_tcs(),
+ case lists:member(Group, Grs) of
+ true ->
+ init = ?config(suite,Config),
+ Group = ?config(Group,Config),
+ ok;
+ false ->
+ ct:fail({bad_group,Group})
+ end.
+
+%%--------------------------------------------------------------------
+%% Testcase Configuration
+%%--------------------------------------------------------------------
+
+init_per_testcase(TestCase, Config) ->
+ {_,TCs} = grs_and_tcs(),
+ case lists:member(TestCase, TCs) of
+ true ->
+ init = ?config(suite,Config),
+ [{TestCase,TestCase} | Config];
+ false ->
+ ct:fail({unknown_testcase,TestCase})
+ end.
+
+end_per_testcase(TestCase, Config) ->
+ {_,TCs} = grs_and_tcs(),
+ case lists:member(TestCase, TCs) of
+ true ->
+ init = ?config(suite,Config),
+ TestCase = ?config(TestCase,Config),
+ ok;
+ false ->
+ ct:fail({unknown_testcase,TestCase})
+ end.
+
+
+%%--------------------------------------------------------------------
+%% Testcases
+%%--------------------------------------------------------------------
+
+testcase_1() ->
+ [].
+testcase_1(Config) ->
+ init = ?config(suite,Config),
+ testcase_1 = ?config(testcase_1,Config),
+ ok.
+
+testcase_1a() ->
+ [].
+testcase_1a(Config) ->
+ init = ?config(suite,Config),
+ case ?config(test_group_1a,Config) of
+ test_group_1a -> ok;
+ _ ->
+ case ?config(test_group_1b,Config) of
+ test_group_1b -> ok;
+ _ -> ct:fail(no_group_data)
+ end
+ end,
+ testcase_1a = ?config(testcase_1a,Config),
+ ok.
+testcase_1b() ->
+ [].
+testcase_1b(Config) ->
+ init = ?config(suite,Config),
+ case ?config(test_group_1a,Config) of
+ test_group_1a -> ok;
+ _ ->
+ case ?config(test_group_1b,Config) of
+ test_group_1b -> ok;
+ _ -> ct:fail(no_group_data)
+ end
+ end,
+ undefined = ?config(testcase_1a,Config),
+ testcase_1b = ?config(testcase_1b,Config),
+ ok.
+
+testcase_2() ->
+ [].
+testcase_2(Config) ->
+ init = ?config(suite,Config),
+ undefined = ?config(test_group_1a,Config),
+ undefined = ?config(test_group_1b,Config),
+ testcase_2 = ?config(testcase_2,Config),
+ ok.
+
+testcase_2a() ->
+ [].
+testcase_2a(Config) ->
+ init = ?config(suite,Config),
+ test_group_2 = ?config(test_group_2,Config),
+ testcase_2a = ?config(testcase_2a,Config),
+ ok.
+testcase_2b() ->
+ [].
+testcase_2b(Config) ->
+ init = ?config(suite,Config),
+ test_group_2 = ?config(test_group_2,Config),
+ undefined = ?config(testcase_2a,Config),
+ testcase_2b = ?config(testcase_2b,Config),
+ ok.
+
+testcase_3a() ->
+ [].
+testcase_3a(Config) ->
+ init = ?config(suite,Config),
+ test_group_2 = ?config(test_group_2,Config),
+ test_group_3 = ?config(test_group_3,Config),
+ undefined = ?config(testcase_2b,Config),
+ testcase_3a = ?config(testcase_3a,Config),
+ ok.
+testcase_3b() ->
+ [].
+testcase_3b(Config) ->
+ init = ?config(suite,Config),
+ test_group_2 = ?config(test_group_2,Config),
+ test_group_3 = ?config(test_group_3,Config),
+ undefined = ?config(testcase_3a,Config),
+ testcase_3b = ?config(testcase_3b,Config),
+ ok.
+
+testcase_3() ->
+ [].
+testcase_3(Config) ->
+ init = ?config(suite,Config),
+ undefined = ?config(test_group_2,Config),
+ undefined = ?config(test_group_3,Config),
+ testcase_3 = ?config(testcase_3,Config),
+ ok.
+
+testcase_5a() ->
+ [].
+testcase_5a(Config) ->
+ init = ?config(suite,Config),
+ undefined = ?config(test_group_3,Config),
+ test_group_4 = ?config(test_group_4,Config),
+ test_group_5 = ?config(test_group_5,Config),
+ undefined = ?config(testcase_3,Config),
+ testcase_5a = ?config(testcase_5a,Config),
+ ok.
+testcase_5b() ->
+ [].
+testcase_5b(Config) ->
+ init = ?config(suite,Config),
+ test_group_4 = ?config(test_group_4,Config),
+ test_group_5 = ?config(test_group_5,Config),
+ undefined = ?config(testcase_5a,Config),
+ testcase_5b = ?config(testcase_5b,Config),
+ ok.
+
+testcase_7a() ->
+ [].
+testcase_7a(Config) ->
+ init = ?config(suite,Config),
+ undefined = ?config(test_group_3,Config),
+ test_group_4 = ?config(test_group_4,Config),
+ test_group_5 = ?config(test_group_5,Config),
+ test_group_6 = ?config(test_group_6,Config),
+ test_group_7 = ?config(test_group_7,Config),
+ testcase_7a = ?config(testcase_7a,Config),
+ ok.
+testcase_7b() ->
+ [].
+testcase_7b(Config) ->
+ init = ?config(suite,Config),
+ test_group_4 = ?config(test_group_4,Config),
+ test_group_5 = ?config(test_group_5,Config),
+ test_group_6 = ?config(test_group_6,Config),
+ test_group_7 = ?config(test_group_7,Config),
+ undefined = ?config(testcase_7a,Config),
+ testcase_7b = ?config(testcase_7b,Config),
+ ok.
diff --git a/lib/common_test/test/ct_groups_test_1_SUITE_data/groups_2/test/groups_22_SUITE.erl b/lib/common_test/test/ct_groups_test_1_SUITE_data/groups_2/test/groups_22_SUITE.erl
new file mode 100644
index 0000000000..2e19cf6310
--- /dev/null
+++ b/lib/common_test/test/ct_groups_test_1_SUITE_data/groups_2/test/groups_22_SUITE.erl
@@ -0,0 +1,310 @@
+%%
+%% %CopyrightBegin%
+%%
+%% 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(groups_22_SUITE).
+
+-compile(export_all).
+
+-include_lib("common_test/include/ct.hrl").
+
+%%====================================================================
+%% COMMON TEST CALLBACK FUNCTIONS
+%%====================================================================
+
+suite() ->
+ [{timetrap,{minutes,1}}].
+
+groups() ->
+ [
+ {test_group_1a, [shuffle], [testcase_1a,testcase_1b,testcase_1c]},
+
+ {test_group_1b, [parallel], [testcase_1a,testcase_1b]},
+
+ {test_group_2, [parallel], [testcase_2a,
+
+ {test_group_3, [{repeat,1}],
+ [testcase_3a, testcase_3b]},
+
+ testcase_2b]},
+
+ {test_group_4, [{test_group_5, [parallel], [testcase_5a,
+
+ {group, test_group_6},
+
+ testcase_5b]}]},
+
+ {test_group_6, [parallel], [{group, test_group_7}]},
+
+ {test_group_7, [sequence], [testcase_7a,testcase_7b]}
+ ].
+
+all() ->
+ [{group, test_group_1a},
+ {group, test_group_1b},
+ testcase_1,
+ testcase_2,
+ {group, test_group_2},
+ testcase_3,
+ {group, test_group_4}].
+
+%% this func only for internal test purposes
+grs_and_tcs() ->
+ {[
+ test_group_1a, test_group_1b,
+ test_group_2, test_group_3,
+ test_group_4, test_group_5,
+ test_group_6, test_group_7
+ ],
+ [
+ testcase_1a, testcase_1b, testcase_1c,
+ testcase_1,
+ testcase_2,
+ testcase_2a, testcase_2b,
+ testcase_3a, testcase_3b,
+ testcase_3,
+ testcase_5a, testcase_5b,
+ testcase_7a, testcase_7b
+ ]}.
+
+%%--------------------------------------------------------------------
+%% Suite Configuration
+%%--------------------------------------------------------------------
+
+init_per_suite(Config) ->
+ [{suite,init}|Config].
+
+end_per_suite(Config) ->
+ init = ?config(suite,Config).
+
+%%--------------------------------------------------------------------
+%% Group Configuration
+%%--------------------------------------------------------------------
+
+init_per_group(Group, Config) ->
+ Cmt =
+ case {Group,?config(tc_group_properties,Config)} of
+ {test_group_1a,[{shuffle,S},{name,test_group_1a}]} ->
+ io_lib:format("shuffled, ~w", [S]);
+ {test_group_1b,[{name,test_group_1b},parallel]} -> "parallel";
+ {test_group_2,[{name,test_group_2},parallel]} -> "parallel";
+ {test_group_3,[{name,test_group_3},{repeat,1}]} -> "repeat 1";
+ {test_group_3,[{name,test_group_3}]} -> "repeat 0";
+ {test_group_4,[{name,test_group_4}]} -> ok;
+ {test_group_5,[{name,test_group_5},parallel]} -> "parallel";
+ {test_group_6,[{name,test_group_6},parallel]} -> "parallel";
+ {test_group_7,[{name,test_group_7},sequence]} -> "sequence"
+ end,
+ {Grs,_} = grs_and_tcs(),
+ case lists:member(Group, Grs) of
+ true ->
+ init = ?config(suite,Config),
+ ct:comment(io_lib:format("~w, ~s", [Group,Cmt])),
+ [{Group,Group} | Config];
+ false ->
+ ct:fail({bad_group,Group})
+ end.
+
+end_per_group(Group, Config) ->
+ {Grs,_} = grs_and_tcs(),
+ case lists:member(Group, Grs) of
+ true ->
+ init = ?config(suite,Config),
+ Group = ?config(Group,Config),
+ ok;
+ false ->
+ ct:fail({bad_group,Group})
+ end.
+
+%%--------------------------------------------------------------------
+%% Testcase Configuration
+%%--------------------------------------------------------------------
+
+init_per_testcase(TestCase, Config) ->
+ {_,TCs} = grs_and_tcs(),
+ case lists:member(TestCase, TCs) of
+ true ->
+ init = ?config(suite,Config),
+ [{TestCase,TestCase} | Config];
+ false ->
+ ct:fail({unknown_testcase,TestCase})
+ end.
+
+end_per_testcase(TestCase, Config) ->
+ {_,TCs} = grs_and_tcs(),
+ case lists:member(TestCase, TCs) of
+ true ->
+ init = ?config(suite,Config),
+ TestCase = ?config(TestCase,Config),
+ ok;
+ false ->
+ ct:fail({unknown_testcase,TestCase})
+ end.
+
+
+%%--------------------------------------------------------------------
+%% Testcases
+%%--------------------------------------------------------------------
+
+testcase_1a() ->
+ [].
+testcase_1a(Config) ->
+ init = ?config(suite,Config),
+ case ?config(test_group_1a,Config) of
+ test_group_1a -> ok;
+ _ ->
+ case ?config(test_group_1b,Config) of
+ test_group_1b -> ok;
+ _ -> ct:fail(no_group_data)
+ end
+ end,
+ testcase_1a = ?config(testcase_1a,Config),
+ ok.
+testcase_1b() ->
+ [].
+testcase_1b(Config) ->
+ init = ?config(suite,Config),
+ case ?config(test_group_1a,Config) of
+ test_group_1a -> ok;
+ _ ->
+ case ?config(test_group_1b,Config) of
+ test_group_1b -> ok;
+ _ -> ct:fail(no_group_data)
+ end
+ end,
+ undefined = ?config(testcase_1a,Config),
+ testcase_1b = ?config(testcase_1b,Config),
+ ok.
+
+testcase_1c() ->
+ [].
+testcase_1c(Config) ->
+ init = ?config(suite,Config),
+ case ?config(test_group_1a,Config) of
+ test_group_1a -> ok;
+ _ ->
+ case ?config(test_group_1b,Config) of
+ test_group_1b -> ok;
+ _ -> ct:fail(no_group_data)
+ end
+ end,
+ undefined = ?config(testcase_1b,Config),
+ testcase_1c = ?config(testcase_1c,Config),
+ ok.
+
+testcase_1() ->
+ [].
+testcase_1(Config) ->
+ init = ?config(suite,Config),
+ testcase_1 = ?config(testcase_1,Config),
+ ok.
+
+testcase_2() ->
+ [].
+testcase_2(Config) ->
+ init = ?config(suite,Config),
+ undefined = ?config(test_group_1a,Config),
+ undefined = ?config(test_group_1b,Config),
+ testcase_2 = ?config(testcase_2,Config),
+ ok.
+
+testcase_2a() ->
+ [].
+testcase_2a(Config) ->
+ init = ?config(suite,Config),
+ test_group_2 = ?config(test_group_2,Config),
+ testcase_2a = ?config(testcase_2a,Config),
+ ok.
+testcase_2b() ->
+ [].
+testcase_2b(Config) ->
+ init = ?config(suite,Config),
+ test_group_2 = ?config(test_group_2,Config),
+ undefined = ?config(testcase_2a,Config),
+ testcase_2b = ?config(testcase_2b,Config),
+ ok.
+
+testcase_3a() ->
+ [].
+testcase_3a(Config) ->
+ init = ?config(suite,Config),
+ test_group_2 = ?config(test_group_2,Config),
+ test_group_3 = ?config(test_group_3,Config),
+ undefined = ?config(testcase_2b,Config),
+ testcase_3a = ?config(testcase_3a,Config),
+ ok.
+testcase_3b() ->
+ [].
+testcase_3b(Config) ->
+ init = ?config(suite,Config),
+ test_group_2 = ?config(test_group_2,Config),
+ test_group_3 = ?config(test_group_3,Config),
+ undefined = ?config(testcase_3a,Config),
+ testcase_3b = ?config(testcase_3b,Config),
+ ok.
+
+testcase_3() ->
+ [].
+testcase_3(Config) ->
+ init = ?config(suite,Config),
+ undefined = ?config(test_group_2,Config),
+ undefined = ?config(test_group_3,Config),
+ testcase_3 = ?config(testcase_3,Config),
+ ok.
+
+testcase_5a() ->
+ [].
+testcase_5a(Config) ->
+ init = ?config(suite,Config),
+ undefined = ?config(test_group_3,Config),
+ test_group_4 = ?config(test_group_4,Config),
+ test_group_5 = ?config(test_group_5,Config),
+ undefined = ?config(testcase_3,Config),
+ testcase_5a = ?config(testcase_5a,Config),
+ ok.
+testcase_5b() ->
+ [].
+testcase_5b(Config) ->
+ init = ?config(suite,Config),
+ test_group_4 = ?config(test_group_4,Config),
+ test_group_5 = ?config(test_group_5,Config),
+ undefined = ?config(testcase_5a,Config),
+ testcase_5b = ?config(testcase_5b,Config),
+ ok.
+
+testcase_7a() ->
+ [].
+testcase_7a(Config) ->
+ init = ?config(suite,Config),
+ undefined = ?config(test_group_3,Config),
+ test_group_4 = ?config(test_group_4,Config),
+ test_group_5 = ?config(test_group_5,Config),
+ test_group_6 = ?config(test_group_6,Config),
+ test_group_7 = ?config(test_group_7,Config),
+ testcase_7a = ?config(testcase_7a,Config),
+ ok.
+testcase_7b() ->
+ [].
+testcase_7b(Config) ->
+ init = ?config(suite,Config),
+ test_group_4 = ?config(test_group_4,Config),
+ test_group_5 = ?config(test_group_5,Config),
+ test_group_6 = ?config(test_group_6,Config),
+ test_group_7 = ?config(test_group_7,Config),
+ undefined = ?config(testcase_7a,Config),
+ testcase_7b = ?config(testcase_7b,Config),
+ ok.
diff --git a/lib/common_test/test/ct_groups_test_2_SUITE.erl b/lib/common_test/test/ct_groups_test_2_SUITE.erl
new file mode 100644
index 0000000000..5a60d855b7
--- /dev/null
+++ b/lib/common_test/test/ct_groups_test_2_SUITE.erl
@@ -0,0 +1,110 @@
+%%
+%% %CopyrightBegin%
+%%
+%% 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%
+%%
+
+%%%-------------------------------------------------------------------
+%%% File: ct_groups_test_2_SUITE
+%%%
+%%% Description:
+%%% Test some simple test case group scenarios.
+%%%
+%%% The suites used for the test are located in the data directory.
+%%%-------------------------------------------------------------------
+-module(ct_groups_test_2_SUITE).
+
+-compile(export_all).
+
+-include_lib("test_server/include/test_server.hrl").
+-include_lib("common_test/include/ct_event.hrl").
+
+-define(eh, ct_test_support_eh).
+
+%%--------------------------------------------------------------------
+%% TEST SERVER CALLBACK FUNCTIONS
+%%--------------------------------------------------------------------
+
+%%--------------------------------------------------------------------
+%% Description: Since Common Test starts another Test Server
+%% instance, the tests need to be performed on a separate node (or
+%% there will be clashes with logging processes etc).
+%%--------------------------------------------------------------------
+init_per_suite(Config) ->
+ Config1 = ct_test_support:init_per_suite(Config),
+ Config1.
+
+end_per_suite(Config) ->
+ ct_test_support:end_per_suite(Config).
+
+init_per_testcase(TestCase, Config) ->
+ ct_test_support:init_per_testcase(TestCase, Config).
+
+end_per_testcase(TestCase, Config) ->
+ ct_test_support:end_per_testcase(TestCase, Config).
+
+all(doc) ->
+ ["Run smoke tests of Common Test."];
+
+all(suite) ->
+ [missing_conf].
+
+%%--------------------------------------------------------------------
+%% TEST CASES
+%%--------------------------------------------------------------------
+
+%%%-----------------------------------------------------------------
+%%%
+
+missing_conf(Config) when is_list(Config) ->
+ DataDir = ?config(data_dir, Config),
+
+ Suite = filename:join(DataDir, "groups_1/missing_conf_SUITE"),
+
+ {Opts,ERPid} = setup({suite,Suite}, Config),
+ ok = ct_test_support:run(ct, run_test, [Opts], Config),
+ Events = ct_test_support:get_events(ERPid, Config),
+
+ ct_test_support:log_events(missing_conf_SUITE,
+ reformat(Events, ?eh),
+ ?config(priv_dir, Config)),
+
+ TestEvents = test_events(missing_conf),
+ ok = ct_test_support:verify_events(TestEvents, Events, Config).
+
+%%%-----------------------------------------------------------------
+%%% HELP FUNCTIONS
+%%%-----------------------------------------------------------------
+
+setup(Test, Config) ->
+ Opts0 = ct_test_support:get_opts(Config),
+ Level = ?config(trace_level, Config),
+ EvHArgs = [{cbm,ct_test_support},{trace_level,Level}],
+ Opts = Opts0 ++ [Test,{event_handler,{?eh,EvHArgs}}],
+ ERPid = ct_test_support:start_event_receiver(Config),
+ {Opts,ERPid}.
+
+reformat(Events, EH) ->
+ ct_test_support:reformat(Events, EH).
+%reformat(Events, _EH) ->
+% Events.
+
+%%%-----------------------------------------------------------------
+%%% TEST EVENTS
+%%%-----------------------------------------------------------------
+
+test_events(missing_conf) ->
+ exit(must_handle_this).
diff --git a/lib/common_test/test/ct_groups_test_2_SUITE_data/groups_1/missing_conf_SUITE.erl b/lib/common_test/test/ct_groups_test_2_SUITE_data/groups_1/missing_conf_SUITE.erl
new file mode 100644
index 0000000000..e7f48daaee
--- /dev/null
+++ b/lib/common_test/test/ct_groups_test_2_SUITE_data/groups_1/missing_conf_SUITE.erl
@@ -0,0 +1,62 @@
+%%
+%% %CopyrightBegin%
+%%
+%% 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(missing_conf_SUITE).
+
+-compile(export_all).
+
+-include_lib("common_test/include/ct.hrl").
+
+%%--------------------------------------------------------------------
+%% Function: suite() -> Info
+%% Info = [tuple()]
+%%--------------------------------------------------------------------
+suite() ->
+ [{timetrap,{seconds,30}}].
+
+
+%%--------------------------------------------------------------------
+%% Function: groups() -> [Group]
+%% Group = {GroupName,Properties,GroupsAndTestCases}
+%% GroupName = atom()
+%% Properties = [parallel | sequence | Shuffle | {RepeatType,N}]
+%% GroupsAndTestCases = [Group | {group,GroupName} | TestCase]
+%% TestCase = atom()
+%% Shuffle = shuffle | {shuffle,{integer(),integer(),integer()}}
+%% RepeatType = repeat | repeat_until_all_ok | repeat_until_all_fail |
+%% repeat_until_any_ok | repeat_until_any_fail
+%% N = integer() | forever
+%%--------------------------------------------------------------------
+groups() ->
+ [{group1,[],[tc1,tc2]}].
+
+%%--------------------------------------------------------------------
+%% Function: all() -> GroupsAndTestCases | {skip,Reason}
+%% GroupsAndTestCases = [{group,GroupName} | TestCase]
+%% GroupName = atom()
+%% TestCase = atom()
+%% Reason = term()
+%%--------------------------------------------------------------------
+all() ->
+ [{group,group1}].
+
+tc1(_) ->
+ ok.
+
+tc2(_) ->
+ ok.
diff --git a/lib/common_test/test/ct_skip_SUITE.erl b/lib/common_test/test/ct_skip_SUITE.erl
new file mode 100644
index 0000000000..9f428723f5
--- /dev/null
+++ b/lib/common_test/test/ct_skip_SUITE.erl
@@ -0,0 +1,565 @@
+%%
+%% %CopyrightBegin%
+%%
+%% 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%
+%%
+
+%%%-------------------------------------------------------------------
+%%% File: ct_skip_SUITE
+%%%
+%%% Description:
+%%% Test auto- and user-skip functionality
+%%%
+%%% The suites used for the test are located in the data directory.
+%%%-------------------------------------------------------------------
+-module(ct_skip_SUITE).
+
+-compile(export_all).
+
+-include_lib("test_server/include/test_server.hrl").
+-include_lib("common_test/include/ct_event.hrl").
+
+-define(eh, ct_test_support_eh).
+
+%%--------------------------------------------------------------------
+%% TEST SERVER CALLBACK FUNCTIONS
+%%--------------------------------------------------------------------
+
+%%--------------------------------------------------------------------
+%% Description: Since Common Test starts another Test Server
+%% instance, the tests need to be performed on a separate node (or
+%% there will be clashes with logging processes etc).
+%%--------------------------------------------------------------------
+init_per_suite(Config) ->
+ Config1 = ct_test_support:init_per_suite(Config),
+ Config1.
+
+end_per_suite(Config) ->
+ ct_test_support:end_per_suite(Config).
+
+init_per_testcase(TestCase, Config) ->
+ ct_test_support:init_per_testcase(TestCase, Config).
+
+end_per_testcase(TestCase, Config) ->
+ ct_test_support:end_per_testcase(TestCase, Config).
+
+all(doc) ->
+ [""];
+
+all(suite) ->
+ [
+ auto_skip,
+ user_skip
+ ].
+
+
+%%--------------------------------------------------------------------
+%% TEST CASES
+%%--------------------------------------------------------------------
+
+%%%-----------------------------------------------------------------
+%%%
+auto_skip(Config) when is_list(Config) ->
+ DataDir = ?config(data_dir, Config),
+ Join = fun(D, S) -> filename:join(D, "skip/test/"++S) end,
+ Suites = [Join(DataDir, "auto_skip_1_SUITE"),
+ Join(DataDir, "auto_skip_2_SUITE"),
+ Join(DataDir, "auto_skip_3_SUITE"),
+ Join(DataDir, "auto_skip_4_SUITE"),
+ Join(DataDir, "auto_skip_5_SUITE"),
+ Join(DataDir, "auto_skip_6_SUITE"),
+ Join(DataDir, "auto_skip_7_SUITE"),
+ Join(DataDir, "auto_skip_8_SUITE"),
+ Join(DataDir, "auto_skip_9_SUITE"),
+ Join(DataDir, "auto_skip_10_SUITE"),
+ Join(DataDir, "auto_skip_11_SUITE")
+ ],
+
+ {Opts,ERPid} = setup({suite,Suites}, Config),
+ ok = ct_test_support:run(ct, run_test, [Opts], Config),
+ Events = ct_test_support:get_events(ERPid, Config),
+
+ ct_test_support:log_events(auto_skip,
+ reformat(Events, ?eh),
+ ?config(priv_dir, Config)),
+
+ TestEvents = test_events(auto_skip),
+ ok = ct_test_support:verify_events(TestEvents, Events, Config).
+
+
+%%%-----------------------------------------------------------------
+%%%
+user_skip(Config) when is_list(Config) ->
+ DataDir = ?config(data_dir, Config),
+ Join = fun(D, S) -> filename:join(D, "skip/test/"++S) end,
+ Suites = [Join(DataDir, "user_skip_1_SUITE"),
+ Join(DataDir, "user_skip_2_SUITE"),
+ Join(DataDir, "user_skip_3_SUITE"),
+ Join(DataDir, "user_skip_4_SUITE"),
+ Join(DataDir, "user_skip_5_SUITE")],
+
+ {Opts,ERPid} = setup({suite,Suites}, Config),
+ ok = ct_test_support:run(ct, run_test, [Opts], Config),
+ Events = ct_test_support:get_events(ERPid, Config),
+
+ ct_test_support:log_events(user_skip,
+ reformat(Events, ?eh),
+ ?config(priv_dir, Config)),
+
+ TestEvents = test_events(user_skip),
+ ok = ct_test_support:verify_events(TestEvents, Events, Config).
+
+%%%-----------------------------------------------------------------
+%%% HELP FUNCTIONS
+%%%-----------------------------------------------------------------
+
+setup(Test, Config) ->
+ Opts0 = ct_test_support:get_opts(Config),
+ Level = ?config(trace_level, Config),
+ EvHArgs = [{cbm,ct_test_support},{trace_level,Level}],
+ Opts = Opts0 ++ [Test,{event_handler,{?eh,EvHArgs}}],
+ ERPid = ct_test_support:start_event_receiver(Config),
+ {Opts,ERPid}.
+
+reformat(Events, EH) ->
+ ct_test_support:reformat(Events, EH).
+%reformat(Events, _EH) ->
+% Events.
+
+%%%-----------------------------------------------------------------
+%%% TEST EVENTS
+%%%-----------------------------------------------------------------
+test_events(auto_skip) ->
+ [
+ {?eh,start_logging,{'DEF','RUNDIR'}},
+ {?eh,test_start,{'DEF',{'START_TIME','LOGDIR'}}},
+ {?eh,start_info,{11,11,34}},
+
+ {?eh,tc_start,{auto_skip_1_SUITE,init_per_suite}},
+ {?eh,tc_done,
+ {auto_skip_1_SUITE,init_per_suite,{failed,{error,init_per_suite_failed}}}},
+ {?eh,tc_auto_skip,
+ {auto_skip_1_SUITE,tc1,{failed,{auto_skip_1_SUITE,init_per_suite,
+ {'EXIT',init_per_suite_failed}}}}},
+ {?eh,test_stats,{0,0,{0,1}}},
+ {?eh,tc_auto_skip,
+ {auto_skip_1_SUITE,tc2,{failed,{auto_skip_1_SUITE,init_per_suite,
+ {'EXIT',init_per_suite_failed}}}}},
+ {?eh,test_stats,{0,0,{0,2}}},
+ {?eh,tc_auto_skip,
+ {auto_skip_1_SUITE,end_per_suite,{failed,{auto_skip_1_SUITE,init_per_suite,
+ {'EXIT',init_per_suite_failed}}}}},
+
+ {?eh,tc_start,{auto_skip_2_SUITE,init_per_suite}},
+ {?eh,tc_done,
+ {auto_skip_2_SUITE,init_per_suite,{failed,{error,init_per_suite_failed}}}},
+ {?eh,tc_auto_skip,
+ {auto_skip_2_SUITE,tc1,{failed,{auto_skip_2_SUITE,init_per_suite,
+ {'EXIT',init_per_suite_failed}}}}},
+ {?eh,test_stats,{0,0,{0,3}}},
+ {?eh,tc_auto_skip,
+ {auto_skip_2_SUITE,end_per_suite,{failed,{auto_skip_2_SUITE,init_per_suite,
+ {'EXIT',init_per_suite_failed}}}}},
+
+ {?eh,tc_start,{auto_skip_3_SUITE,init_per_suite}},
+ {?eh,tc_done,{auto_skip_3_SUITE,init_per_suite,ok}},
+ {?eh,tc_start,{auto_skip_3_SUITE,tc1}},
+ {?eh,tc_done,
+ {auto_skip_3_SUITE,tc1,
+ {skipped,{failed,{auto_skip_3_SUITE,init_per_testcase,
+ {init_per_testcase,tc1,failed}}}}}},
+ {?eh,test_stats,{0,0,{0,4}}},
+ {?eh,tc_start,{auto_skip_3_SUITE,tc2}},
+ {?eh,tc_done,{auto_skip_3_SUITE,tc2,ok}},
+ {?eh,test_stats,{1,0,{0,4}}},
+ {?eh,tc_start,{auto_skip_3_SUITE,end_per_suite}},
+ {?eh,tc_done,{auto_skip_3_SUITE,end_per_suite,ok}},
+
+ {?eh,tc_start,{auto_skip_4_SUITE,init_per_suite}},
+ {?eh,tc_done,{auto_skip_4_SUITE,init_per_suite,ok}},
+ {?eh,tc_start,{auto_skip_4_SUITE,tc1}},
+ {?eh,tc_done,{auto_skip_4_SUITE,tc1,
+ {skipped,{failed,{auto_skip_4_SUITE,init_per_testcase,
+ {timetrap_timeout,1000}}}}}},
+ {?eh,test_stats,{1,0,{0,5}}},
+ {?eh,tc_start,{auto_skip_4_SUITE,tc2}},
+ {?eh,tc_done,{auto_skip_4_SUITE,tc2,ok}},
+ {?eh,test_stats,{2,0,{0,5}}},
+ {?eh,tc_start,{auto_skip_4_SUITE,end_per_suite}},
+ {?eh,tc_done,{auto_skip_4_SUITE,end_per_suite,ok}},
+
+ {?eh,tc_start,{auto_skip_5_SUITE,init_per_suite}},
+ {?eh,tc_done,{auto_skip_5_SUITE,init_per_suite,ok}},
+ [{?eh,tc_start,{auto_skip_5_SUITE,{init_per_group,g1,[]}}},
+ {?eh,tc_done,
+ {auto_skip_5_SUITE,{init_per_group,g1,[]},{failed,{error,{group,g1,failed}}}}},
+ {?eh,tc_auto_skip,
+ {auto_skip_5_SUITE,tc1,{failed,{auto_skip_5_SUITE,init_per_group,
+ {'EXIT',{group,g1,failed}}}}}},
+ {?eh,test_stats,{2,0,{0,6}}},
+ {?eh,tc_auto_skip,
+ {auto_skip_5_SUITE,tc2,{failed,{auto_skip_5_SUITE,init_per_group,
+ {'EXIT',{group,g1,failed}}}}}},
+ {?eh,test_stats,{2,0,{0,7}}},
+ {?eh,tc_auto_skip,
+ {auto_skip_5_SUITE,end_per_group,{failed,{auto_skip_5_SUITE,init_per_group,
+ {'EXIT',{group,g1,failed}}}}}}],
+
+ {?eh,tc_start,{auto_skip_5_SUITE,end_per_suite}},
+ {?eh,tc_done,{auto_skip_5_SUITE,end_per_suite,ok}},
+
+ {?eh,tc_start,{auto_skip_6_SUITE,init_per_suite}},
+ {?eh,tc_done,{auto_skip_6_SUITE,init_per_suite,ok}},
+ [{?eh,tc_start,{auto_skip_6_SUITE,{init_per_group,g1,[]}}},
+ {?eh,tc_done,
+ {auto_skip_6_SUITE,{init_per_group,g1,[]},{failed,{error,{group,g1,failed}}}}},
+ {?eh,tc_auto_skip,
+ {auto_skip_6_SUITE,tc1,{failed,{auto_skip_6_SUITE,init_per_group,
+ {'EXIT',{group,g1,failed}}}}}},
+ {?eh,test_stats,{2,0,{0,8}}},
+ {?eh,tc_auto_skip,
+ {auto_skip_6_SUITE,tc3,{failed,{auto_skip_6_SUITE,init_per_group,
+ {'EXIT',{group,g1,failed}}}}}},
+ {?eh,test_stats,{2,0,{0,9}}},
+ {?eh,tc_auto_skip,
+ {auto_skip_6_SUITE,tc4,{failed,{auto_skip_6_SUITE,init_per_group,
+ {'EXIT',{group,g1,failed}}}}}},
+ {?eh,test_stats,{2,0,{0,10}}},
+ {?eh,tc_auto_skip,
+ {auto_skip_6_SUITE,tc2,{failed,{auto_skip_6_SUITE,init_per_group,
+ {'EXIT',{group,g1,failed}}}}}},
+ {?eh,test_stats,{2,0,{0,11}}},
+ {?eh,tc_auto_skip,
+ {auto_skip_6_SUITE,end_per_group,{failed,{auto_skip_6_SUITE,init_per_group,
+ {'EXIT',{group,g1,failed}}}}}}],
+
+ [{?eh,tc_start,{auto_skip_6_SUITE,{init_per_group,g3,[]}}},
+ {?eh,tc_done,{auto_skip_6_SUITE,{init_per_group,g3,[]},ok}},
+ {?eh,tc_start,{auto_skip_6_SUITE,tc1}},
+ {?eh,tc_done,{auto_skip_6_SUITE,tc1,ok}},
+ {?eh,test_stats,{3,0,{0,11}}},
+ [{?eh,tc_start,{auto_skip_6_SUITE,{init_per_group,g4,[]}}},
+ {?eh,tc_done,{auto_skip_6_SUITE,{init_per_group,g4,[]},
+ {failed,{error,{group,g4,failed}}}}},
+ {?eh,tc_auto_skip,
+ {auto_skip_6_SUITE,tc3,{failed,{auto_skip_6_SUITE,init_per_group,
+ {'EXIT',{group,g4,failed}}}}}},
+ {?eh,test_stats,{3,0,{0,12}}},
+ {?eh,tc_auto_skip,
+ {auto_skip_6_SUITE,tc4,{failed,{auto_skip_6_SUITE,init_per_group,
+ {'EXIT',{group,g4,failed}}}}}},
+ {?eh,test_stats,{3,0,{0,13}}},
+ {?eh,tc_auto_skip,
+ {auto_skip_6_SUITE,end_per_group,{failed,{auto_skip_6_SUITE,init_per_group,
+ {'EXIT',{group,g4,failed}}}}}}],
+ {?eh,tc_start,{auto_skip_6_SUITE,tc2}},
+ {?eh,tc_done,{auto_skip_6_SUITE,tc2,ok}},
+ {?eh,test_stats,{4,0,{0,13}}},
+ {?eh,tc_start,{auto_skip_6_SUITE,{end_per_group,g3,[]}}},
+ {?eh,tc_done,{auto_skip_6_SUITE,{end_per_group,g3,[]},ok}}],
+
+ {?eh,tc_start,{auto_skip_6_SUITE,end_per_suite}},
+ {?eh,tc_done,{auto_skip_6_SUITE,end_per_suite,ok}},
+
+ {?eh,tc_start,{auto_skip_7_SUITE,init_per_suite}},
+ {?eh,tc_done,{auto_skip_7_SUITE,init_per_suite,ok}},
+ {?eh,tc_auto_skip,
+ {auto_skip_7_SUITE,tc1,{failed,{auto_skip_7_SUITE,init_per_suite,bad_return}}}},
+ {?eh,test_stats,{4,0,{0,14}}},
+ {?eh,tc_auto_skip,
+ {auto_skip_7_SUITE,tc2,{failed,{auto_skip_7_SUITE,init_per_suite,bad_return}}}},
+ {?eh,test_stats,{4,0,{0,15}}},
+ {?eh,tc_auto_skip,
+ {auto_skip_7_SUITE,end_per_suite,{failed,{auto_skip_7_SUITE,init_per_suite,bad_return}}}},
+
+ {?eh,tc_start,{auto_skip_8_SUITE,init_per_suite}},
+ {?eh,tc_done,{auto_skip_8_SUITE,init_per_suite,ok}},
+ {?eh,tc_auto_skip,
+ {auto_skip_8_SUITE,tc1,{failed,{auto_skip_8_SUITE,init_per_suite,bad_return}}}},
+ {?eh,test_stats,{4,0,{0,16}}},
+ {?eh,tc_auto_skip,
+ {auto_skip_8_SUITE,tc2,{failed,{auto_skip_8_SUITE,init_per_suite,bad_return}}}},
+ {?eh,test_stats,{4,0,{0,17}}},
+ {?eh,tc_auto_skip,
+ {auto_skip_8_SUITE,end_per_suite,{failed,{auto_skip_8_SUITE,init_per_suite,bad_return}}}},
+
+ {?eh,tc_start,{auto_skip_9_SUITE,init_per_suite}},
+ {?eh,tc_done,{auto_skip_9_SUITE,init_per_suite,ok}},
+ {?eh,tc_start,{auto_skip_9_SUITE,tc1}},
+ {?eh,tc_done,{auto_skip_9_SUITE,tc1,ok}},
+ {?eh,test_stats,{5,0,{0,17}}},
+ {?eh,tc_start,{auto_skip_9_SUITE,tc2}},
+ {?eh,tc_done,{auto_skip_9_SUITE,tc2,
+ {skipped,{failed,{auto_skip_9_SUITE,init_per_testcase,bad_return}}}}},
+ {?eh,test_stats,{5,0,{0,18}}},
+
+ [{?eh,tc_start,{auto_skip_9_SUITE,{init_per_group,g1,[]}}},
+ {?eh,tc_done,{auto_skip_9_SUITE,{init_per_group,g1,[]},ok}},
+ {?eh,tc_start,{auto_skip_9_SUITE,tc3}},
+ {?eh,tc_done,{auto_skip_9_SUITE,tc3,ok}},
+ {?eh,test_stats,{6,0,{0,18}}},
+ {?eh,tc_start,{auto_skip_9_SUITE,{end_per_group,g1,[]}}},
+ {?eh,tc_done,{auto_skip_9_SUITE,{end_per_group,g1,[]},ok}}],
+
+ [{?eh,tc_start,{auto_skip_9_SUITE,{init_per_group,g2,[]}}},
+ {?eh,tc_done,{auto_skip_9_SUITE,{init_per_group,g2,[]},ok}},
+ {?eh,tc_start,{auto_skip_9_SUITE,tc4}},
+ {?eh,tc_done,{auto_skip_9_SUITE,tc4,ok}},
+ {?eh,test_stats,{7,0,{0,18}}},
+ {?eh,tc_start,{auto_skip_9_SUITE,{end_per_group,g2,[]}}},
+ {?eh,tc_done,{auto_skip_9_SUITE,{end_per_group,g2,[]},ok}}],
+
+ [{?eh,tc_start,{auto_skip_9_SUITE,{init_per_group,g3,[]}}},
+ {?eh,tc_done,{auto_skip_9_SUITE,{init_per_group,g3,[]},ok}},
+ {?eh,tc_start,{auto_skip_9_SUITE,tc5}},
+ {?eh,tc_done,{auto_skip_9_SUITE,tc5,
+ {skipped,{failed,{auto_skip_9_SUITE,init_per_testcase,bad_return}}}}},
+ {?eh,test_stats,{7,0,{0,19}}},
+ {?eh,tc_start,{auto_skip_9_SUITE,{end_per_group,g3,[]}}},
+ {?eh,tc_done,{auto_skip_9_SUITE,{end_per_group,g3,[]},ok}}],
+
+ {parallel,
+ [{?eh,tc_start,
+ {auto_skip_9_SUITE,{init_per_group,g4,[parallel]}}},
+ {?eh,tc_done,
+ {auto_skip_9_SUITE,{init_per_group,g4,[parallel]},ok}},
+ {?eh,tc_start,{auto_skip_9_SUITE,tc6}},
+ {?eh,tc_done,{auto_skip_9_SUITE,tc6,ok}},
+ {parallel,
+ [{?eh,tc_start,
+ {auto_skip_9_SUITE,{init_per_group,g5,[parallel]}}},
+ {?eh,tc_done,
+ {auto_skip_9_SUITE,{init_per_group,g5,[parallel]},ok}},
+ {?eh,tc_start,{auto_skip_9_SUITE,tc8}},
+ {?eh,tc_done,
+ {auto_skip_9_SUITE,tc8,
+ {skipped,{failed,{auto_skip_9_SUITE,init_per_testcase,
+ {{badmatch,undefined},
+ [{auto_skip_9_SUITE,init_per_testcase,2},
+ {test_server,my_apply,3},
+ {test_server,init_per_testcase,3},
+ {test_server,run_test_case_eval1,6},
+ {test_server,run_test_case_eval,8}]}}}}}},
+ {?eh,tc_start,
+ {auto_skip_9_SUITE,{end_per_group,g5,[parallel]}}},
+ {?eh,tc_done,
+ {auto_skip_9_SUITE,{end_per_group,g5,[parallel]},ok}}]},
+
+ {?eh,tc_start,{auto_skip_9_SUITE,tc7}},
+ {?eh,tc_done,{auto_skip_9_SUITE,tc7,ok}},
+ {?eh,test_stats,{9,0,{0,20}}},
+ {?eh,tc_start,
+ {auto_skip_9_SUITE,{end_per_group,g4,[parallel]}}},
+ {?eh,tc_done,
+ {auto_skip_9_SUITE,{end_per_group,g4,[parallel]},ok}}]},
+
+ {?eh,tc_start,{auto_skip_9_SUITE,end_per_suite}},
+ {?eh,tc_done,{auto_skip_9_SUITE,end_per_suite,ok}},
+
+ {?eh,tc_start,{auto_skip_10_SUITE,init_per_suite}},
+ {?eh,tc_done,{auto_skip_10_SUITE,init_per_suite,
+ {skipped,
+ {require_failed_in_suite0,
+ {not_available,undefined_config_variable}}}}},
+ {?eh,tc_auto_skip,
+ {auto_skip_10_SUITE,tc1,
+ {require_failed_in_suite0,{not_available,undefined_config_variable}}}},
+ {?eh,test_stats,{9,0,{0,21}}},
+ {?eh,tc_auto_skip,
+ {auto_skip_10_SUITE,tc2,
+ {require_failed_in_suite0,{not_available,undefined_config_variable}}}},
+ {?eh,test_stats,{9,0,{0,22}}},
+ {?eh,tc_auto_skip,
+ {auto_skip_10_SUITE,end_per_suite,
+ {require_failed_in_suite0,{not_available,undefined_config_variable}}}},
+
+ {?eh,tc_start,{auto_skip_11_SUITE,init_per_suite}},
+ {?eh,tc_done,{auto_skip_11_SUITE,init_per_suite,ok}},
+ {?eh,tc_start,{auto_skip_11_SUITE,tc1}},
+ {?eh,tc_done,{auto_skip_11_SUITE,tc1,
+ {skipped,{require_failed,{not_available,undefined_config_variable}}}}},
+ {?eh,test_stats,{9,0,{0,23}}},
+ {?eh,tc_start,{auto_skip_11_SUITE,tc2}},
+ {?eh,tc_done,{auto_skip_11_SUITE,tc2,ok}},
+ {?eh,test_stats,{10,0,{0,23}}},
+
+ {parallel,
+ [{?eh,tc_start,
+ {auto_skip_11_SUITE,{init_per_group,g1,[parallel]}}},
+ {?eh,tc_done,
+ {auto_skip_11_SUITE,{init_per_group,g1,[parallel]},ok}},
+ {parallel,
+ [{?eh,tc_start,
+ {auto_skip_11_SUITE,{init_per_group,g2,[parallel]}}},
+ {?eh,tc_done,
+ {auto_skip_11_SUITE,{init_per_group,g2,[parallel]},ok}},
+ {?eh,tc_start,{auto_skip_11_SUITE,tc3}},
+ {?eh,tc_done,
+ {auto_skip_11_SUITE,tc3,
+ {skipped,{require_failed,{not_available,undefined_config_variable}}}}},
+ {?eh,test_stats,{10,0,{0,24}}},
+ {?eh,tc_start,
+ {auto_skip_11_SUITE,{end_per_group,g2,[parallel]}}},
+ {?eh,tc_done,
+ {auto_skip_11_SUITE,{end_per_group,g2,[parallel]},ok}}]},
+ {?eh,tc_start,
+ {auto_skip_11_SUITE,{end_per_group,g1,[parallel]}}},
+ {?eh,tc_done,
+ {auto_skip_11_SUITE,{end_per_group,g1,[parallel]},ok}}]},
+
+ {?eh,tc_start,{auto_skip_11_SUITE,end_per_suite}},
+ {?eh,tc_done,{auto_skip_11_SUITE,end_per_suite,ok}},
+
+ {?eh,test_done,{'DEF','STOP_TIME'}},
+ {?eh,stop_logging,[]}
+ ];
+
+test_events(user_skip) ->
+ [{?eh,start_logging,{'DEF','RUNDIR'}},
+ {?eh,test_start,{'DEF',{'START_TIME','LOGDIR'}}},
+ {?eh,start_info,{5,5,27}},
+
+ {?eh,tc_start,{user_skip_1_SUITE,init_per_suite}},
+ {?eh,tc_done,
+ {user_skip_1_SUITE,init_per_suite,{skipped,"Whole suite skipped"}}},
+ {?eh,tc_auto_skip,
+ {user_skip_1_SUITE,tc1,"Whole suite skipped"}},
+ {?eh,test_stats,{0,0,{0,1}}},
+ {?eh,tc_auto_skip,
+ {user_skip_1_SUITE,tc2,"Whole suite skipped"}},
+ {?eh,test_stats,{0,0,{0,2}}},
+ {?eh,tc_auto_skip,
+ {user_skip_1_SUITE,tc3,"Whole suite skipped"}},
+ {?eh,test_stats,{0,0,{0,3}}},
+ {?eh,tc_auto_skip,
+ {user_skip_1_SUITE,tc4,"Whole suite skipped"}},
+ {?eh,test_stats,{0,0,{0,4}}},
+ {?eh,tc_auto_skip,
+ {user_skip_1_SUITE,end_per_suite,"Whole suite skipped"}},
+
+ {?eh,tc_start,{user_skip_2_SUITE,init_per_suite}},
+ {?eh,tc_done,{user_skip_2_SUITE,init_per_suite,ok}},
+ {?eh,tc_start,{user_skip_2_SUITE,tc1}},
+ {?eh,tc_done,{user_skip_2_SUITE,tc1,{skipped,{tc1,skipped}}}},
+ {?eh,test_stats,{0,0,{1,4}}},
+
+ [{?eh,tc_start,{user_skip_2_SUITE,{init_per_group,g1,[]}}},
+ {?eh,tc_done,{user_skip_2_SUITE,{init_per_group,g1,[]},ok}},
+ {?eh,tc_start,{user_skip_2_SUITE,tc2}},
+ {?eh,tc_done,{user_skip_2_SUITE,tc2,ok}},
+ {?eh,test_stats,{1,0,{1,4}}},
+ {?eh,tc_start,{user_skip_2_SUITE,tc3}},
+ {?eh,tc_done,{user_skip_2_SUITE,tc3,{skipped,{tc3,skipped}}}},
+ {?eh,test_stats,{1,0,{2,4}}},
+ {?eh,tc_start,{user_skip_2_SUITE,{end_per_group,g1,[]}}},
+ {?eh,tc_done,{user_skip_2_SUITE,{end_per_group,g1,[]},ok}}],
+
+ {?eh,tc_start,{user_skip_2_SUITE,tc4}},
+ {?eh,tc_done,{user_skip_2_SUITE,tc4,ok}},
+ {?eh,test_stats,{2,0,{2,4}}},
+ {?eh,tc_start,{user_skip_2_SUITE,end_per_suite}},
+ {?eh,tc_done,{user_skip_2_SUITE,end_per_suite,ok}},
+
+ {?eh,tc_start,{user_skip_3_SUITE,init_per_suite}},
+ {?eh,tc_done,{user_skip_3_SUITE,init_per_suite,ok}},
+ {?eh,tc_start,{user_skip_3_SUITE,tc1}},
+ {?eh,tc_done,{user_skip_3_SUITE,tc1,{skipped,"Test case skipped"}}},
+ {?eh,test_stats,{2,0,{3,4}}},
+
+ [{?eh,tc_start,{user_skip_3_SUITE,{init_per_group,g1,[]}}},
+ {?eh,tc_done,{user_skip_3_SUITE,{init_per_group,g1,[]},ok}},
+ {?eh,tc_start,{user_skip_3_SUITE,tc2}},
+ {?eh,tc_done,{user_skip_3_SUITE,tc2,ok}},
+ {?eh,test_stats,{3,0,{3,4}}},
+ {?eh,tc_start,{user_skip_3_SUITE,tc3}},
+ {?eh,tc_done,{user_skip_3_SUITE,tc3,{skipped,"Test case skipped"}}},
+ {?eh,test_stats,{3,0,{4,4}}},
+ {?eh,tc_start,{user_skip_3_SUITE,{end_per_group,g1,[]}}},
+ {?eh,tc_done,{user_skip_3_SUITE,{end_per_group,g1,[]},ok}}],
+
+ {?eh,tc_start,{user_skip_3_SUITE,tc4}},
+ {?eh,tc_done,{user_skip_3_SUITE,tc4,
+ {skipped,{proc_info,{{current_function,{user_skip_3_SUITE,tc4,1}},
+ {initial_call,{erlang,apply,2}}}}}}},
+ {?eh,test_stats,{3,0,{5,4}}},
+ {?eh,tc_start,{user_skip_3_SUITE,end_per_suite}},
+ {?eh,tc_done,{user_skip_3_SUITE,end_per_suite,ok}},
+
+ {?eh,tc_start,{user_skip_4_SUITE,init_per_suite}},
+ {?eh,tc_done,{user_skip_4_SUITE,init_per_suite,ok}},
+
+ [{?eh,tc_start,{user_skip_4_SUITE,{init_per_group,g1,[]}}},
+ {?eh,tc_done,{user_skip_4_SUITE,{init_per_group,g1,[]},{skipped,"Group skipped"}}},
+ {?eh,tc_auto_skip,{user_skip_4_SUITE,tc1,"Group skipped"}},
+ {?eh,test_stats,{3,0,{5,5}}},
+ {?eh,tc_auto_skip,{user_skip_4_SUITE,tc2,"Group skipped"}},
+ {?eh,test_stats,{3,0,{5,6}}},
+ {?eh,tc_auto_skip,{user_skip_4_SUITE,end_per_group,"Group skipped"}}],
+
+ [{?eh,tc_start,{user_skip_4_SUITE,{init_per_group,g2,[]}}},
+ {?eh,tc_done,{user_skip_4_SUITE,{init_per_group,g2,[]},ok}},
+ {?eh,tc_start,{user_skip_4_SUITE,tc3}},
+ {?eh,tc_done,{user_skip_4_SUITE,tc3,ok}},
+ {?eh,test_stats,{4,0,{5,6}}},
+ {?eh,tc_start,{user_skip_4_SUITE,tc4}},
+ {?eh,tc_done,{user_skip_4_SUITE,tc4,ok}},
+ {?eh,test_stats,{5,0,{5,6}}},
+ {?eh,tc_start,{user_skip_4_SUITE,{end_per_group,g2,[]}}},
+ {?eh,tc_done,{user_skip_4_SUITE,{end_per_group,g2,[]},ok}}],
+
+ [{?eh,tc_start,{user_skip_4_SUITE,{init_per_group,g3,[]}}},
+ {?eh,tc_done,{user_skip_4_SUITE,{init_per_group,g3,[]},{skipped,"Group skipped"}}},
+ {?eh,tc_auto_skip,{user_skip_4_SUITE,tc5,"Group skipped"}},
+ {?eh,tc_auto_skip,{user_skip_4_SUITE,tc6,"Group skipped"}},
+ {?eh,tc_auto_skip,{user_skip_4_SUITE,tc7,"Group skipped"}},
+ {?eh,tc_auto_skip,{user_skip_4_SUITE,tc8,"Group skipped"}},
+ {?eh,test_stats,{5,0,{5,10}}},
+ {?eh,tc_auto_skip,{user_skip_4_SUITE,end_per_group,"Group skipped"}}],
+
+ [{?eh,tc_start,{user_skip_4_SUITE,{init_per_group,g5,[]}}},
+ {?eh,tc_done,{user_skip_4_SUITE,{init_per_group,g5,[]},ok}},
+ {?eh,tc_start,{user_skip_4_SUITE,tc9}},
+ {?eh,tc_done,{user_skip_4_SUITE,tc9,ok}},
+ {?eh,test_stats,{6,0,{5,10}}},
+ [{?eh,tc_start,{user_skip_4_SUITE,{init_per_group,g6,[]}}},
+ {?eh,tc_done,{user_skip_4_SUITE,{init_per_group,g6,[]},{skipped,"Group skipped"}}},
+ {?eh,tc_auto_skip,{user_skip_4_SUITE,tc10,"Group skipped"}},
+ {?eh,test_stats,{6,0,{5,11}}},
+ {?eh,tc_auto_skip,{user_skip_4_SUITE,tc11,"Group skipped"}},
+ {?eh,test_stats,{6,0,{5,12}}},
+ {?eh,tc_auto_skip,{user_skip_4_SUITE,end_per_group,"Group skipped"}}],
+ {?eh,tc_start,{user_skip_4_SUITE,{end_per_group,g5,[]}}},
+ {?eh,tc_done,{user_skip_4_SUITE,{end_per_group,g5,[]},ok}}],
+
+ {?eh,tc_start,{user_skip_4_SUITE,end_per_suite}},
+ {?eh,tc_done,{user_skip_4_SUITE,end_per_suite,ok}},
+
+ {ct_test_support_eh,tc_start,{user_skip_5_SUITE,init_per_suite}},
+ {?eh,tc_done,{user_skip_5_SUITE,init_per_suite,
+ {skipped,{bad,'Whole suite skipped'}}}},
+ {?eh,tc_auto_skip,{user_skip_5_SUITE,tc1,{bad,'Whole suite skipped'}}},
+ {?eh,test_stats,{6,0,{5,13}}},
+ {?eh,tc_auto_skip,{user_skip_5_SUITE,tc2,{bad,'Whole suite skipped'}}},
+ {?eh,test_stats,{6,0,{5,14}}},
+ {?eh,tc_auto_skip,{user_skip_5_SUITE,tc3,{bad,'Whole suite skipped'}}},
+ {?eh,test_stats,{6,0,{5,15}}},
+ {?eh,tc_auto_skip,{user_skip_5_SUITE,tc4,{bad,'Whole suite skipped'}}},
+ {?eh,test_stats,{6,0,{5,16}}},
+ {?eh,tc_auto_skip,{user_skip_5_SUITE,end_per_suite,{bad,'Whole suite skipped'}}},
+
+ {?eh,test_done,{'DEF','STOP_TIME'}},
+ {?eh,stop_logging,[]}
+ ].
diff --git a/lib/common_test/test/ct_skip_SUITE_data/skip/test/auto_skip_10_SUITE.erl b/lib/common_test/test/ct_skip_SUITE_data/skip/test/auto_skip_10_SUITE.erl
new file mode 100644
index 0000000000..b93c68e126
--- /dev/null
+++ b/lib/common_test/test/ct_skip_SUITE_data/skip/test/auto_skip_10_SUITE.erl
@@ -0,0 +1,130 @@
+%%
+%% %CopyrightBegin%
+%%
+%% 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(auto_skip_10_SUITE).
+
+-compile(export_all).
+
+-include_lib("common_test/include/ct.hrl").
+
+%%--------------------------------------------------------------------
+%% Function: suite() -> Info
+%% Info = [tuple()]
+%%--------------------------------------------------------------------
+suite() ->
+ [{require,undefined_config_variable}].
+
+%%--------------------------------------------------------------------
+%% Function: init_per_suite(Config0) ->
+%% Config1 | {skip,Reason} | {skip_and_save,Reason,Config1}
+%% Config0 = Config1 = [tuple()]
+%% Reason = term()
+%%--------------------------------------------------------------------
+init_per_suite(Config) ->
+ Config.
+
+%%--------------------------------------------------------------------
+%% Function: end_per_suite(Config0) -> void() | {save_config,Config1}
+%% Config0 = Config1 = [tuple()]
+%%--------------------------------------------------------------------
+end_per_suite(_Config) ->
+ ok.
+
+%%--------------------------------------------------------------------
+%% Function: init_per_group(GroupName, Config0) ->
+%% Config1 | {skip,Reason} | {skip_and_save,Reason,Config1}
+%% GroupName = atom()
+%% Config0 = Config1 = [tuple()]
+%% Reason = term()
+%%--------------------------------------------------------------------
+init_per_group(_GroupName, Config) ->
+ Config.
+
+%%--------------------------------------------------------------------
+%% Function: end_per_group(GroupName, Config0) ->
+%% void() | {save_config,Config1}
+%% GroupName = atom()
+%% Config0 = Config1 = [tuple()]
+%%--------------------------------------------------------------------
+end_per_group(_GroupName, _Config) ->
+ ok.
+
+%%--------------------------------------------------------------------
+%% Function: init_per_testcase(TestCase, Config0) ->
+%% Config1 | {skip,Reason} | {skip_and_save,Reason,Config1}
+%% TestCase = atom()
+%% Config0 = Config1 = [tuple()]
+%% Reason = term()
+%%--------------------------------------------------------------------
+init_per_testcase(_TestCase, Config) ->
+ Config.
+
+%%--------------------------------------------------------------------
+%% Function: end_per_testcase(TestCase, Config0) ->
+%% void() | {save_config,Config1}
+%% TestCase = atom()
+%% Config0 = Config1 = [tuple()]
+%%--------------------------------------------------------------------
+end_per_testcase(_TestCase, _Config) ->
+ ok.
+
+%%--------------------------------------------------------------------
+%% Function: groups() -> [Group]
+%% Group = {GroupName,Properties,GroupsAndTestCases}
+%% GroupName = atom()
+%% Properties = [parallel | sequence | Shuffle | {RepeatType,N}]
+%% GroupsAndTestCases = [Group | {group,GroupName} | TestCase]
+%% TestCase = atom()
+%% Shuffle = shuffle | {shuffle,{integer(),integer(),integer()}}
+%% RepeatType = repeat | repeat_until_all_ok | repeat_until_all_fail |
+%% repeat_until_any_ok | repeat_until_any_fail
+%% N = integer() | forever
+%%--------------------------------------------------------------------
+groups() ->
+ [].
+
+%%--------------------------------------------------------------------
+%% Function: all() -> GroupsAndTestCases | {skip,Reason}
+%% GroupsAndTestCases = [{group,GroupName} | TestCase]
+%% GroupName = atom()
+%% TestCase = atom()
+%% Reason = term()
+%%--------------------------------------------------------------------
+all() ->
+ [tc1,tc2].
+
+%%--------------------------------------------------------------------
+%% Function: TestCase() -> Info
+%% Info = [tuple()]
+%%--------------------------------------------------------------------
+tc1() ->
+ [].
+
+%%--------------------------------------------------------------------
+%% Function: TestCase(Config0) ->
+%% ok | exit() | {skip,Reason} | {comment,Comment} |
+%% {save_config,Config1} | {skip_and_save,Reason,Config1}
+%% Config0 = Config1 = [tuple()]
+%% Reason = term()
+%% Comment = term()
+%%--------------------------------------------------------------------
+tc1(_Config) ->
+ ok.
+
+tc2(_Config) ->
+ ok.
diff --git a/lib/common_test/test/ct_skip_SUITE_data/skip/test/auto_skip_11_SUITE.erl b/lib/common_test/test/ct_skip_SUITE_data/skip/test/auto_skip_11_SUITE.erl
new file mode 100644
index 0000000000..c0a662f4b2
--- /dev/null
+++ b/lib/common_test/test/ct_skip_SUITE_data/skip/test/auto_skip_11_SUITE.erl
@@ -0,0 +1,136 @@
+%%
+%% %CopyrightBegin%
+%%
+%% 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(auto_skip_11_SUITE).
+
+-compile(export_all).
+
+-include_lib("common_test/include/ct.hrl").
+
+%%--------------------------------------------------------------------
+%% Function: suite() -> Info
+%% Info = [tuple()]
+%%--------------------------------------------------------------------
+suite() ->
+ [].
+
+%%--------------------------------------------------------------------
+%% Function: init_per_suite(Config0) ->
+%% Config1 | {skip,Reason} | {skip_and_save,Reason,Config1}
+%% Config0 = Config1 = [tuple()]
+%% Reason = term()
+%%--------------------------------------------------------------------
+init_per_suite(Config) ->
+ Config.
+
+%%--------------------------------------------------------------------
+%% Function: end_per_suite(Config0) -> void() | {save_config,Config1}
+%% Config0 = Config1 = [tuple()]
+%%--------------------------------------------------------------------
+end_per_suite(_Config) ->
+ ok.
+
+%%--------------------------------------------------------------------
+%% Function: init_per_group(GroupName, Config0) ->
+%% Config1 | {skip,Reason} | {skip_and_save,Reason,Config1}
+%% GroupName = atom()
+%% Config0 = Config1 = [tuple()]
+%% Reason = term()
+%%--------------------------------------------------------------------
+init_per_group(_GroupName, Config) ->
+ Config.
+
+%%--------------------------------------------------------------------
+%% Function: end_per_group(GroupName, Config0) ->
+%% void() | {save_config,Config1}
+%% GroupName = atom()
+%% Config0 = Config1 = [tuple()]
+%%--------------------------------------------------------------------
+end_per_group(_GroupName, _Config) ->
+ ok.
+
+%%--------------------------------------------------------------------
+%% Function: init_per_testcase(TestCase, Config0) ->
+%% Config1 | {skip,Reason} | {skip_and_save,Reason,Config1}
+%% TestCase = atom()
+%% Config0 = Config1 = [tuple()]
+%% Reason = term()
+%%--------------------------------------------------------------------
+init_per_testcase(_TestCase, Config) ->
+ Config.
+
+%%--------------------------------------------------------------------
+%% Function: end_per_testcase(TestCase, Config0) ->
+%% void() | {save_config,Config1}
+%% TestCase = atom()
+%% Config0 = Config1 = [tuple()]
+%%--------------------------------------------------------------------
+end_per_testcase(_TestCase, _Config) ->
+ ok.
+
+%%--------------------------------------------------------------------
+%% Function: groups() -> [Group]
+%% Group = {GroupName,Properties,GroupsAndTestCases}
+%% GroupName = atom()
+%% Properties = [parallel | sequence | Shuffle | {RepeatType,N}]
+%% GroupsAndTestCases = [Group | {group,GroupName} | TestCase]
+%% TestCase = atom()
+%% Shuffle = shuffle | {shuffle,{integer(),integer(),integer()}}
+%% RepeatType = repeat | repeat_until_all_ok | repeat_until_all_fail |
+%% repeat_until_any_ok | repeat_until_any_fail
+%% N = integer() | forever
+%%--------------------------------------------------------------------
+groups() ->
+ [{g1,[parallel],[{g2,[parallel],[tc3]}]}].
+
+%%--------------------------------------------------------------------
+%% Function: all() -> GroupsAndTestCases | {skip,Reason}
+%% GroupsAndTestCases = [{group,GroupName} | TestCase]
+%% GroupName = atom()
+%% TestCase = atom()
+%% Reason = term()
+%%--------------------------------------------------------------------
+all() ->
+ [tc1,tc2,{group,g1}].
+
+%%--------------------------------------------------------------------
+%% Function: TestCase() -> Info
+%% Info = [tuple()]
+%%--------------------------------------------------------------------
+tc1() ->
+ [{require,undefined_config_variable}].
+
+tc3() ->
+ [{require,undefined_config_variable}].
+
+%%--------------------------------------------------------------------
+%% Function: TestCase(Config0) ->
+%% ok | exit() | {skip,Reason} | {comment,Comment} |
+%% {save_config,Config1} | {skip_and_save,Reason,Config1}
+%% Config0 = Config1 = [tuple()]
+%% Reason = term()
+%% Comment = term()
+%%--------------------------------------------------------------------
+tc1(_Config) ->
+ exit(should_be_auto_skipped).
+
+tc2(_Config) ->
+ ok.
+
+tc3(_Config) ->
+ exit(should_be_auto_skipped).
diff --git a/lib/common_test/test/ct_skip_SUITE_data/skip/test/auto_skip_1_SUITE.erl b/lib/common_test/test/ct_skip_SUITE_data/skip/test/auto_skip_1_SUITE.erl
new file mode 100644
index 0000000000..247e478fa3
--- /dev/null
+++ b/lib/common_test/test/ct_skip_SUITE_data/skip/test/auto_skip_1_SUITE.erl
@@ -0,0 +1,130 @@
+%%
+%% %CopyrightBegin%
+%%
+%% 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(auto_skip_1_SUITE).
+
+-compile(export_all).
+
+-include_lib("common_test/include/ct.hrl").
+
+%%--------------------------------------------------------------------
+%% Function: suite() -> Info
+%% Info = [tuple()]
+%%--------------------------------------------------------------------
+suite() ->
+ [{timetrap,{seconds,30}}].
+
+%%--------------------------------------------------------------------
+%% Function: init_per_suite(Config0) ->
+%% Config1 | {skip,Reason} | {skip_and_save,Reason,Config1}
+%% Config0 = Config1 = [tuple()]
+%% Reason = term()
+%%--------------------------------------------------------------------
+init_per_suite(_Config) ->
+ exit(init_per_suite_failed).
+
+%%--------------------------------------------------------------------
+%% Function: end_per_suite(Config0) -> void() | {save_config,Config1}
+%% Config0 = Config1 = [tuple()]
+%%--------------------------------------------------------------------
+end_per_suite(_Config) ->
+ ok.
+
+%%--------------------------------------------------------------------
+%% Function: init_per_group(GroupName, Config0) ->
+%% Config1 | {skip,Reason} | {skip_and_save,Reason,Config1}
+%% GroupName = atom()
+%% Config0 = Config1 = [tuple()]
+%% Reason = term()
+%%--------------------------------------------------------------------
+init_per_group(_GroupName, Config) ->
+ Config.
+
+%%--------------------------------------------------------------------
+%% Function: end_per_group(GroupName, Config0) ->
+%% void() | {save_config,Config1}
+%% GroupName = atom()
+%% Config0 = Config1 = [tuple()]
+%%--------------------------------------------------------------------
+end_per_group(_GroupName, _Config) ->
+ ok.
+
+%%--------------------------------------------------------------------
+%% Function: init_per_testcase(TestCase, Config0) ->
+%% Config1 | {skip,Reason} | {skip_and_save,Reason,Config1}
+%% TestCase = atom()
+%% Config0 = Config1 = [tuple()]
+%% Reason = term()
+%%--------------------------------------------------------------------
+init_per_testcase(_TestCase, Config) ->
+ Config.
+
+%%--------------------------------------------------------------------
+%% Function: end_per_testcase(TestCase, Config0) ->
+%% void() | {save_config,Config1}
+%% TestCase = atom()
+%% Config0 = Config1 = [tuple()]
+%%--------------------------------------------------------------------
+end_per_testcase(_TestCase, _Config) ->
+ ok.
+
+%%--------------------------------------------------------------------
+%% Function: groups() -> [Group]
+%% Group = {GroupName,Properties,GroupsAndTestCases}
+%% GroupName = atom()
+%% Properties = [parallel | sequence | Shuffle | {RepeatType,N}]
+%% GroupsAndTestCases = [Group | {group,GroupName} | TestCase]
+%% TestCase = atom()
+%% Shuffle = shuffle | {shuffle,{integer(),integer(),integer()}}
+%% RepeatType = repeat | repeat_until_all_ok | repeat_until_all_fail |
+%% repeat_until_any_ok | repeat_until_any_fail
+%% N = integer() | forever
+%%--------------------------------------------------------------------
+groups() ->
+ [].
+
+%%--------------------------------------------------------------------
+%% Function: all() -> GroupsAndTestCases | {skip,Reason}
+%% GroupsAndTestCases = [{group,GroupName} | TestCase]
+%% GroupName = atom()
+%% TestCase = atom()
+%% Reason = term()
+%%--------------------------------------------------------------------
+all() ->
+ [tc1,tc2].
+
+%%--------------------------------------------------------------------
+%% Function: TestCase() -> Info
+%% Info = [tuple()]
+%%--------------------------------------------------------------------
+tc1() ->
+ [].
+
+%%--------------------------------------------------------------------
+%% Function: TestCase(Config0) ->
+%% ok | exit() | {skip,Reason} | {comment,Comment} |
+%% {save_config,Config1} | {skip_and_save,Reason,Config1}
+%% Config0 = Config1 = [tuple()]
+%% Reason = term()
+%% Comment = term()
+%%--------------------------------------------------------------------
+tc1(_Config) ->
+ ok.
+
+tc2(_Config) ->
+ ok.
diff --git a/lib/common_test/test/ct_skip_SUITE_data/skip/test/auto_skip_2_SUITE.erl b/lib/common_test/test/ct_skip_SUITE_data/skip/test/auto_skip_2_SUITE.erl
new file mode 100644
index 0000000000..3d332d2a28
--- /dev/null
+++ b/lib/common_test/test/ct_skip_SUITE_data/skip/test/auto_skip_2_SUITE.erl
@@ -0,0 +1,127 @@
+%%
+%% %CopyrightBegin%
+%%
+%% 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(auto_skip_2_SUITE).
+
+-compile(export_all).
+
+-include_lib("common_test/include/ct.hrl").
+
+%%--------------------------------------------------------------------
+%% Function: suite() -> Info
+%% Info = [tuple()]
+%%--------------------------------------------------------------------
+suite() ->
+ [{timetrap,{seconds,30}}].
+
+%%--------------------------------------------------------------------
+%% Function: init_per_suite(Config0) ->
+%% Config1 | {skip,Reason} | {skip_and_save,Reason,Config1}
+%% Config0 = Config1 = [tuple()]
+%% Reason = term()
+%%--------------------------------------------------------------------
+init_per_suite(_Config) ->
+ exit(init_per_suite_failed).
+
+%%--------------------------------------------------------------------
+%% Function: end_per_suite(Config0) -> void() | {save_config,Config1}
+%% Config0 = Config1 = [tuple()]
+%%--------------------------------------------------------------------
+end_per_suite(_Config) ->
+ ok.
+
+%%--------------------------------------------------------------------
+%% Function: init_per_group(GroupName, Config0) ->
+%% Config1 | {skip,Reason} | {skip_and_save,Reason,Config1}
+%% GroupName = atom()
+%% Config0 = Config1 = [tuple()]
+%% Reason = term()
+%%--------------------------------------------------------------------
+init_per_group(_GroupName, Config) ->
+ Config.
+
+%%--------------------------------------------------------------------
+%% Function: end_per_group(GroupName, Config0) ->
+%% void() | {save_config,Config1}
+%% GroupName = atom()
+%% Config0 = Config1 = [tuple()]
+%%--------------------------------------------------------------------
+end_per_group(_GroupName, _Config) ->
+ ok.
+
+%%--------------------------------------------------------------------
+%% Function: init_per_testcase(TestCase, Config0) ->
+%% Config1 | {skip,Reason} | {skip_and_save,Reason,Config1}
+%% TestCase = atom()
+%% Config0 = Config1 = [tuple()]
+%% Reason = term()
+%%--------------------------------------------------------------------
+init_per_testcase(_TestCase, Config) ->
+ Config.
+
+%%--------------------------------------------------------------------
+%% Function: end_per_testcase(TestCase, Config0) ->
+%% void() | {save_config,Config1}
+%% TestCase = atom()
+%% Config0 = Config1 = [tuple()]
+%%--------------------------------------------------------------------
+end_per_testcase(_TestCase, _Config) ->
+ ok.
+
+%%--------------------------------------------------------------------
+%% Function: groups() -> [Group]
+%% Group = {GroupName,Properties,GroupsAndTestCases}
+%% GroupName = atom()
+%% Properties = [parallel | sequence | Shuffle | {RepeatType,N}]
+%% GroupsAndTestCases = [Group | {group,GroupName} | TestCase]
+%% TestCase = atom()
+%% Shuffle = shuffle | {shuffle,{integer(),integer(),integer()}}
+%% RepeatType = repeat | repeat_until_all_ok | repeat_until_all_fail |
+%% repeat_until_any_ok | repeat_until_any_fail
+%% N = integer() | forever
+%%--------------------------------------------------------------------
+groups() ->
+ [{g1,[],[tc1]}].
+
+%%--------------------------------------------------------------------
+%% Function: all() -> GroupsAndTestCases | {skip,Reason}
+%% GroupsAndTestCases = [{group,GroupName} | TestCase]
+%% GroupName = atom()
+%% TestCase = atom()
+%% Reason = term()
+%%--------------------------------------------------------------------
+all() ->
+ [{group,g1}].
+
+%%--------------------------------------------------------------------
+%% Function: TestCase() -> Info
+%% Info = [tuple()]
+%%--------------------------------------------------------------------
+tc1() ->
+ [].
+
+%%--------------------------------------------------------------------
+%% Function: TestCase(Config0) ->
+%% ok | exit() | {skip,Reason} | {comment,Comment} |
+%% {save_config,Config1} | {skip_and_save,Reason,Config1}
+%% Config0 = Config1 = [tuple()]
+%% Reason = term()
+%% Comment = term()
+%%--------------------------------------------------------------------
+tc1(_Config) ->
+ ok.
diff --git a/lib/common_test/test/ct_skip_SUITE_data/skip/test/auto_skip_3_SUITE.erl b/lib/common_test/test/ct_skip_SUITE_data/skip/test/auto_skip_3_SUITE.erl
new file mode 100644
index 0000000000..cb64cb76c5
--- /dev/null
+++ b/lib/common_test/test/ct_skip_SUITE_data/skip/test/auto_skip_3_SUITE.erl
@@ -0,0 +1,132 @@
+%%
+%% %CopyrightBegin%
+%%
+%% 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(auto_skip_3_SUITE).
+
+-compile(export_all).
+
+-include_lib("common_test/include/ct.hrl").
+
+%%--------------------------------------------------------------------
+%% Function: suite() -> Info
+%% Info = [tuple()]
+%%--------------------------------------------------------------------
+suite() ->
+ [{timetrap,{seconds,30}}].
+
+%%--------------------------------------------------------------------
+%% Function: init_per_suite(Config0) ->
+%% Config1 | {skip,Reason} | {skip_and_save,Reason,Config1}
+%% Config0 = Config1 = [tuple()]
+%% Reason = term()
+%%--------------------------------------------------------------------
+init_per_suite(Config) ->
+ Config.
+
+%%--------------------------------------------------------------------
+%% Function: end_per_suite(Config0) -> void() | {save_config,Config1}
+%% Config0 = Config1 = [tuple()]
+%%--------------------------------------------------------------------
+end_per_suite(_Config) ->
+ ok.
+
+%%--------------------------------------------------------------------
+%% Function: init_per_group(GroupName, Config0) ->
+%% Config1 | {skip,Reason} | {skip_and_save,Reason,Config1}
+%% GroupName = atom()
+%% Config0 = Config1 = [tuple()]
+%% Reason = term()
+%%--------------------------------------------------------------------
+init_per_group(_GroupName, Config) ->
+ Config.
+
+%%--------------------------------------------------------------------
+%% Function: end_per_group(GroupName, Config0) ->
+%% void() | {save_config,Config1}
+%% GroupName = atom()
+%% Config0 = Config1 = [tuple()]
+%%--------------------------------------------------------------------
+end_per_group(_GroupName, _Config) ->
+ ok.
+
+%%--------------------------------------------------------------------
+%% Function: init_per_testcase(TestCase, Config0) ->
+%% Config1 | {skip,Reason} | {skip_and_save,Reason,Config1}
+%% TestCase = atom()
+%% Config0 = Config1 = [tuple()]
+%% Reason = term()
+%%--------------------------------------------------------------------
+init_per_testcase(tc1, _Config) ->
+ exit({init_per_testcase,tc1,failed});
+init_per_testcase(_TestCase, Config) ->
+ Config.
+
+%%--------------------------------------------------------------------
+%% Function: end_per_testcase(TestCase, Config0) ->
+%% void() | {save_config,Config1}
+%% TestCase = atom()
+%% Config0 = Config1 = [tuple()]
+%%--------------------------------------------------------------------
+end_per_testcase(_TestCase, _Config) ->
+ ok.
+
+%%--------------------------------------------------------------------
+%% Function: groups() -> [Group]
+%% Group = {GroupName,Properties,GroupsAndTestCases}
+%% GroupName = atom()
+%% Properties = [parallel | sequence | Shuffle | {RepeatType,N}]
+%% GroupsAndTestCases = [Group | {group,GroupName} | TestCase]
+%% TestCase = atom()
+%% Shuffle = shuffle | {shuffle,{integer(),integer(),integer()}}
+%% RepeatType = repeat | repeat_until_all_ok | repeat_until_all_fail |
+%% repeat_until_any_ok | repeat_until_any_fail
+%% N = integer() | forever
+%%--------------------------------------------------------------------
+groups() ->
+ [].
+
+%%--------------------------------------------------------------------
+%% Function: all() -> GroupsAndTestCases | {skip,Reason}
+%% GroupsAndTestCases = [{group,GroupName} | TestCase]
+%% GroupName = atom()
+%% TestCase = atom()
+%% Reason = term()
+%%--------------------------------------------------------------------
+all() ->
+ [tc1,tc2].
+
+%%--------------------------------------------------------------------
+%% Function: TestCase() -> Info
+%% Info = [tuple()]
+%%--------------------------------------------------------------------
+tc1() ->
+ [].
+
+%%--------------------------------------------------------------------
+%% Function: TestCase(Config0) ->
+%% ok | exit() | {skip,Reason} | {comment,Comment} |
+%% {save_config,Config1} | {skip_and_save,Reason,Config1}
+%% Config0 = Config1 = [tuple()]
+%% Reason = term()
+%% Comment = term()
+%%--------------------------------------------------------------------
+tc1(_Config) ->
+ ok.
+
+tc2(_Config) ->
+ ok.
diff --git a/lib/common_test/test/ct_skip_SUITE_data/skip/test/auto_skip_4_SUITE.erl b/lib/common_test/test/ct_skip_SUITE_data/skip/test/auto_skip_4_SUITE.erl
new file mode 100644
index 0000000000..825846cd55
--- /dev/null
+++ b/lib/common_test/test/ct_skip_SUITE_data/skip/test/auto_skip_4_SUITE.erl
@@ -0,0 +1,126 @@
+%%
+%% %CopyrightBegin%
+%%
+%% 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(auto_skip_4_SUITE).
+
+-compile(export_all).
+
+-include_lib("common_test/include/ct.hrl").
+
+%%--------------------------------------------------------------------
+%% Function: suite() -> Info
+%% Info = [tuple()]
+%%--------------------------------------------------------------------
+suite() ->
+ [{timetrap,{seconds,1}}].
+
+%%--------------------------------------------------------------------
+%% Function: init_per_suite(Config0) ->
+%% Config1 | {skip,Reason} | {skip_and_save,Reason,Config1}
+%% Config0 = Config1 = [tuple()]
+%% Reason = term()
+%%--------------------------------------------------------------------
+init_per_suite(Config) ->
+ Config.
+
+%%--------------------------------------------------------------------
+%% Function: end_per_suite(Config0) -> void() | {save_config,Config1}
+%% Config0 = Config1 = [tuple()]
+%%--------------------------------------------------------------------
+end_per_suite(_Config) ->
+ ok.
+
+%%--------------------------------------------------------------------
+%% Function: init_per_group(GroupName, Config0) ->
+%% Config1 | {skip,Reason} | {skip_and_save,Reason,Config1}
+%% GroupName = atom()
+%% Config0 = Config1 = [tuple()]
+%% Reason = term()
+%%--------------------------------------------------------------------
+init_per_group(_GroupName, Config) ->
+ Config.
+
+%%--------------------------------------------------------------------
+%% Function: end_per_group(GroupName, Config0) ->
+%% void() | {save_config,Config1}
+%% GroupName = atom()
+%% Config0 = Config1 = [tuple()]
+%%--------------------------------------------------------------------
+end_per_group(_GroupName, _Config) ->
+ ok.
+
+%%--------------------------------------------------------------------
+%% Function: init_per_testcase(TestCase, Config0) ->
+%% Config1 | {skip,Reason} | {skip_and_save,Reason,Config1}
+%% TestCase = atom()
+%% Config0 = Config1 = [tuple()]
+%% Reason = term()
+%%--------------------------------------------------------------------
+init_per_testcase(tc1, Config) ->
+ timer:sleep(5000),
+ Config;
+init_per_testcase(_TestCase, Config) ->
+ Config.
+
+%%--------------------------------------------------------------------
+%% Function: end_per_testcase(TestCase, Config0) ->
+%% void() | {save_config,Config1}
+%% TestCase = atom()
+%% Config0 = Config1 = [tuple()]
+%%--------------------------------------------------------------------
+end_per_testcase(_TestCase, _Config) ->
+ ok.
+
+%%--------------------------------------------------------------------
+%% Function: groups() -> [Group]
+%% Group = {GroupName,Properties,GroupsAndTestCases}
+%% GroupName = atom()
+%% Properties = [parallel | sequence | Shuffle | {RepeatType,N}]
+%% GroupsAndTestCases = [Group | {group,GroupName} | TestCase]
+%% TestCase = atom()
+%% Shuffle = shuffle | {shuffle,{integer(),integer(),integer()}}
+%% RepeatType = repeat | repeat_until_all_ok | repeat_until_all_fail |
+%% repeat_until_any_ok | repeat_until_any_fail
+%% N = integer() | forever
+%%--------------------------------------------------------------------
+groups() ->
+ [].
+
+%%--------------------------------------------------------------------
+%% Function: all() -> GroupsAndTestCases | {skip,Reason}
+%% GroupsAndTestCases = [{group,GroupName} | TestCase]
+%% GroupName = atom()
+%% TestCase = atom()
+%% Reason = term()
+%%--------------------------------------------------------------------
+all() ->
+ [tc1,tc2].
+
+%%--------------------------------------------------------------------
+%% Function: TestCase(Config0) ->
+%% ok | exit() | {skip,Reason} | {comment,Comment} |
+%% {save_config,Config1} | {skip_and_save,Reason,Config1}
+%% Config0 = Config1 = [tuple()]
+%% Reason = term()
+%% Comment = term()
+%%--------------------------------------------------------------------
+tc1(_Config) ->
+ ok.
+
+tc2(_Config) ->
+ ok.
diff --git a/lib/common_test/test/ct_skip_SUITE_data/skip/test/auto_skip_5_SUITE.erl b/lib/common_test/test/ct_skip_SUITE_data/skip/test/auto_skip_5_SUITE.erl
new file mode 100644
index 0000000000..2cf07928bb
--- /dev/null
+++ b/lib/common_test/test/ct_skip_SUITE_data/skip/test/auto_skip_5_SUITE.erl
@@ -0,0 +1,123 @@
+%%
+%% %CopyrightBegin%
+%%
+%% 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(auto_skip_5_SUITE).
+
+-compile(export_all).
+
+-include_lib("common_test/include/ct.hrl").
+
+%%--------------------------------------------------------------------
+%% Function: suite() -> Info
+%% Info = [tuple()]
+%%--------------------------------------------------------------------
+suite() ->
+ [{timetrap,{seconds,1}}].
+
+%%--------------------------------------------------------------------
+%% Function: init_per_suite(Config0) ->
+%% Config1 | {skip,Reason} | {skip_and_save,Reason,Config1}
+%% Config0 = Config1 = [tuple()]
+%% Reason = term()
+%%--------------------------------------------------------------------
+init_per_suite(Config) ->
+ Config.
+
+%%--------------------------------------------------------------------
+%% Function: end_per_suite(Config0) -> void() | {save_config,Config1}
+%% Config0 = Config1 = [tuple()]
+%%--------------------------------------------------------------------
+end_per_suite(_Config) ->
+ ok.
+
+%%--------------------------------------------------------------------
+%% Function: init_per_group(GroupName, Config0) ->
+%% Config1 | {skip,Reason} | {skip_and_save,Reason,Config1}
+%% GroupName = atom()
+%% Config0 = Config1 = [tuple()]
+%% Reason = term()
+%%--------------------------------------------------------------------
+init_per_group(GroupName, _Config) ->
+ exit({group,GroupName,failed}).
+
+%%--------------------------------------------------------------------
+%% Function: end_per_group(GroupName, Config0) ->
+%% void() | {save_config,Config1}
+%% GroupName = atom()
+%% Config0 = Config1 = [tuple()]
+%%--------------------------------------------------------------------
+end_per_group(_GroupName, _Config) ->
+ ok.
+
+%%--------------------------------------------------------------------
+%% Function: init_per_testcase(TestCase, Config0) ->
+%% Config1 | {skip,Reason} | {skip_and_save,Reason,Config1}
+%% TestCase = atom()
+%% Config0 = Config1 = [tuple()]
+%% Reason = term()
+%%--------------------------------------------------------------------
+init_per_testcase(_TestCase, Config) ->
+ Config.
+
+%%--------------------------------------------------------------------
+%% Function: end_per_testcase(TestCase, Config0) ->
+%% void() | {save_config,Config1}
+%% TestCase = atom()
+%% Config0 = Config1 = [tuple()]
+%%--------------------------------------------------------------------
+end_per_testcase(_TestCase, _Config) ->
+ ok.
+
+%%--------------------------------------------------------------------
+%% Function: groups() -> [Group]
+%% Group = {GroupName,Properties,GroupsAndTestCases}
+%% GroupName = atom()
+%% Properties = [parallel | sequence | Shuffle | {RepeatType,N}]
+%% GroupsAndTestCases = [Group | {group,GroupName} | TestCase]
+%% TestCase = atom()
+%% Shuffle = shuffle | {shuffle,{integer(),integer(),integer()}}
+%% RepeatType = repeat | repeat_until_all_ok | repeat_until_all_fail |
+%% repeat_until_any_ok | repeat_until_any_fail
+%% N = integer() | forever
+%%--------------------------------------------------------------------
+groups() ->
+ [{g1,[],[tc1,tc2]}].
+
+%%--------------------------------------------------------------------
+%% Function: all() -> GroupsAndTestCases | {skip,Reason}
+%% GroupsAndTestCases = [{group,GroupName} | TestCase]
+%% GroupName = atom()
+%% TestCase = atom()
+%% Reason = term()
+%%--------------------------------------------------------------------
+all() ->
+ [{group,g1}].
+
+%%--------------------------------------------------------------------
+%% Function: TestCase(Config0) ->
+%% ok | exit() | {skip,Reason} | {comment,Comment} |
+%% {save_config,Config1} | {skip_and_save,Reason,Config1}
+%% Config0 = Config1 = [tuple()]
+%% Reason = term()
+%% Comment = term()
+%%--------------------------------------------------------------------
+tc1(_Config) ->
+ ok.
+
+tc2(_Config) ->
+ ok.
diff --git a/lib/common_test/test/ct_skip_SUITE_data/skip/test/auto_skip_6_SUITE.erl b/lib/common_test/test/ct_skip_SUITE_data/skip/test/auto_skip_6_SUITE.erl
new file mode 100644
index 0000000000..c950fed6b7
--- /dev/null
+++ b/lib/common_test/test/ct_skip_SUITE_data/skip/test/auto_skip_6_SUITE.erl
@@ -0,0 +1,136 @@
+%%
+%% %CopyrightBegin%
+%%
+%% 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(auto_skip_6_SUITE).
+
+-compile(export_all).
+
+-include_lib("common_test/include/ct.hrl").
+
+%%--------------------------------------------------------------------
+%% Function: suite() -> Info
+%% Info = [tuple()]
+%%--------------------------------------------------------------------
+suite() ->
+ [{timetrap,{seconds,1}}].
+
+%%--------------------------------------------------------------------
+%% Function: init_per_suite(Config0) ->
+%% Config1 | {skip,Reason} | {skip_and_save,Reason,Config1}
+%% Config0 = Config1 = [tuple()]
+%% Reason = term()
+%%--------------------------------------------------------------------
+init_per_suite(Config) ->
+ Config.
+
+%%--------------------------------------------------------------------
+%% Function: end_per_suite(Config0) -> void() | {save_config,Config1}
+%% Config0 = Config1 = [tuple()]
+%%--------------------------------------------------------------------
+end_per_suite(_Config) ->
+ ok.
+
+%%--------------------------------------------------------------------
+%% Function: init_per_group(GroupName, Config0) ->
+%% Config1 | {skip,Reason} | {skip_and_save,Reason,Config1}
+%% GroupName = atom()
+%% Config0 = Config1 = [tuple()]
+%% Reason = term()
+%%--------------------------------------------------------------------
+init_per_group(g1, _Config) ->
+ exit({group,g1,failed});
+init_per_group(g2, Config) ->
+ Config;
+init_per_group(g3, Config) ->
+ Config;
+init_per_group(g4, _Config) ->
+ exit({group,g4,failed}).
+
+%%--------------------------------------------------------------------
+%% Function: end_per_group(GroupName, Config0) ->
+%% void() | {save_config,Config1}
+%% GroupName = atom()
+%% Config0 = Config1 = [tuple()]
+%%--------------------------------------------------------------------
+end_per_group(_GroupName, _Config) ->
+ ok.
+
+%%--------------------------------------------------------------------
+%% Function: init_per_testcase(TestCase, Config0) ->
+%% Config1 | {skip,Reason} | {skip_and_save,Reason,Config1}
+%% TestCase = atom()
+%% Config0 = Config1 = [tuple()]
+%% Reason = term()
+%%--------------------------------------------------------------------
+init_per_testcase(_TestCase, Config) ->
+ Config.
+
+%%--------------------------------------------------------------------
+%% Function: end_per_testcase(TestCase, Config0) ->
+%% void() | {save_config,Config1}
+%% TestCase = atom()
+%% Config0 = Config1 = [tuple()]
+%%--------------------------------------------------------------------
+end_per_testcase(_TestCase, _Config) ->
+ ok.
+
+%%--------------------------------------------------------------------
+%% Function: groups() -> [Group]
+%% Group = {GroupName,Properties,GroupsAndTestCases}
+%% GroupName = atom()
+%% Properties = [parallel | sequence | Shuffle | {RepeatType,N}]
+%% GroupsAndTestCases = [Group | {group,GroupName} | TestCase]
+%% TestCase = atom()
+%% Shuffle = shuffle | {shuffle,{integer(),integer(),integer()}}
+%% RepeatType = repeat | repeat_until_all_ok | repeat_until_all_fail |
+%% repeat_until_any_ok | repeat_until_any_fail
+%% N = integer() | forever
+%%--------------------------------------------------------------------
+groups() ->
+ [{g1,[],[tc1,{g2,[],[tc3,tc4]},tc2]},
+ {g3,[],[tc1,{g4,[],[tc3,tc4]},tc2]}].
+
+%%--------------------------------------------------------------------
+%% Function: all() -> GroupsAndTestCases | {skip,Reason}
+%% GroupsAndTestCases = [{group,GroupName} | TestCase]
+%% GroupName = atom()
+%% TestCase = atom()
+%% Reason = term()
+%%--------------------------------------------------------------------
+all() ->
+ [{group,g1},{group,g3}].
+
+%%--------------------------------------------------------------------
+%% Function: TestCase(Config0) ->
+%% ok | exit() | {skip,Reason} | {comment,Comment} |
+%% {save_config,Config1} | {skip_and_save,Reason,Config1}
+%% Config0 = Config1 = [tuple()]
+%% Reason = term()
+%% Comment = term()
+%%--------------------------------------------------------------------
+tc1(_Config) ->
+ ok.
+
+tc2(_Config) ->
+ ok.
+
+tc3(_Config) ->
+ ok.
+
+tc4(_Config) ->
+ ok.
diff --git a/lib/common_test/test/ct_skip_SUITE_data/skip/test/auto_skip_7_SUITE.erl b/lib/common_test/test/ct_skip_SUITE_data/skip/test/auto_skip_7_SUITE.erl
new file mode 100644
index 0000000000..6146459bf2
--- /dev/null
+++ b/lib/common_test/test/ct_skip_SUITE_data/skip/test/auto_skip_7_SUITE.erl
@@ -0,0 +1,130 @@
+%%
+%% %CopyrightBegin%
+%%
+%% 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(auto_skip_7_SUITE).
+
+-compile(export_all).
+
+-include_lib("common_test/include/ct.hrl").
+
+%%--------------------------------------------------------------------
+%% Function: suite() -> Info
+%% Info = [tuple()]
+%%--------------------------------------------------------------------
+suite() ->
+ [{timetrap,{seconds,30}}].
+
+%%--------------------------------------------------------------------
+%% Function: init_per_suite(Config0) ->
+%% Config1 | {skip,Reason} | {skip_and_save,Reason,Config1}
+%% Config0 = Config1 = [tuple()]
+%% Reason = term()
+%%--------------------------------------------------------------------
+init_per_suite(_Config) ->
+ ok.
+
+%%--------------------------------------------------------------------
+%% Function: end_per_suite(Config0) -> void() | {save_config,Config1}
+%% Config0 = Config1 = [tuple()]
+%%--------------------------------------------------------------------
+end_per_suite(_Config) ->
+ ok.
+
+%%--------------------------------------------------------------------
+%% Function: init_per_group(GroupName, Config0) ->
+%% Config1 | {skip,Reason} | {skip_and_save,Reason,Config1}
+%% GroupName = atom()
+%% Config0 = Config1 = [tuple()]
+%% Reason = term()
+%%--------------------------------------------------------------------
+init_per_group(_GroupName, Config) ->
+ Config.
+
+%%--------------------------------------------------------------------
+%% Function: end_per_group(GroupName, Config0) ->
+%% void() | {save_config,Config1}
+%% GroupName = atom()
+%% Config0 = Config1 = [tuple()]
+%%--------------------------------------------------------------------
+end_per_group(_GroupName, _Config) ->
+ ok.
+
+%%--------------------------------------------------------------------
+%% Function: init_per_testcase(TestCase, Config0) ->
+%% Config1 | {skip,Reason} | {skip_and_save,Reason,Config1}
+%% TestCase = atom()
+%% Config0 = Config1 = [tuple()]
+%% Reason = term()
+%%--------------------------------------------------------------------
+init_per_testcase(_TestCase, Config) ->
+ Config.
+
+%%--------------------------------------------------------------------
+%% Function: end_per_testcase(TestCase, Config0) ->
+%% void() | {save_config,Config1}
+%% TestCase = atom()
+%% Config0 = Config1 = [tuple()]
+%%--------------------------------------------------------------------
+end_per_testcase(_TestCase, _Config) ->
+ ok.
+
+%%--------------------------------------------------------------------
+%% Function: groups() -> [Group]
+%% Group = {GroupName,Properties,GroupsAndTestCases}
+%% GroupName = atom()
+%% Properties = [parallel | sequence | Shuffle | {RepeatType,N}]
+%% GroupsAndTestCases = [Group | {group,GroupName} | TestCase]
+%% TestCase = atom()
+%% Shuffle = shuffle | {shuffle,{integer(),integer(),integer()}}
+%% RepeatType = repeat | repeat_until_all_ok | repeat_until_all_fail |
+%% repeat_until_any_ok | repeat_until_any_fail
+%% N = integer() | forever
+%%--------------------------------------------------------------------
+groups() ->
+ [].
+
+%%--------------------------------------------------------------------
+%% Function: all() -> GroupsAndTestCases | {skip,Reason}
+%% GroupsAndTestCases = [{group,GroupName} | TestCase]
+%% GroupName = atom()
+%% TestCase = atom()
+%% Reason = term()
+%%--------------------------------------------------------------------
+all() ->
+ [tc1,tc2].
+
+%%--------------------------------------------------------------------
+%% Function: TestCase() -> Info
+%% Info = [tuple()]
+%%--------------------------------------------------------------------
+tc1() ->
+ [].
+
+%%--------------------------------------------------------------------
+%% Function: TestCase(Config0) ->
+%% ok | exit() | {skip,Reason} | {comment,Comment} |
+%% {save_config,Config1} | {skip_and_save,Reason,Config1}
+%% Config0 = Config1 = [tuple()]
+%% Reason = term()
+%% Comment = term()
+%%--------------------------------------------------------------------
+tc1(_Config) ->
+ ok.
+
+tc2(_Config) ->
+ ok.
diff --git a/lib/common_test/test/ct_skip_SUITE_data/skip/test/auto_skip_8_SUITE.erl b/lib/common_test/test/ct_skip_SUITE_data/skip/test/auto_skip_8_SUITE.erl
new file mode 100644
index 0000000000..462d6b4e79
--- /dev/null
+++ b/lib/common_test/test/ct_skip_SUITE_data/skip/test/auto_skip_8_SUITE.erl
@@ -0,0 +1,130 @@
+%%
+%% %CopyrightBegin%
+%%
+%% 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(auto_skip_8_SUITE).
+
+-compile(export_all).
+
+-include_lib("common_test/include/ct.hrl").
+
+%%--------------------------------------------------------------------
+%% Function: suite() -> Info
+%% Info = [tuple()]
+%%--------------------------------------------------------------------
+suite() ->
+ [{timetrap,{seconds,30}}].
+
+%%--------------------------------------------------------------------
+%% Function: init_per_suite(Config0) ->
+%% Config1 | {skip,Reason} | {skip_and_save,Reason,Config1}
+%% Config0 = Config1 = [tuple()]
+%% Reason = term()
+%%--------------------------------------------------------------------
+init_per_suite(Config) ->
+ [{x,y,z}|Config].
+
+%%--------------------------------------------------------------------
+%% Function: end_per_suite(Config0) -> void() | {save_config,Config1}
+%% Config0 = Config1 = [tuple()]
+%%--------------------------------------------------------------------
+end_per_suite(_Config) ->
+ ok.
+
+%%--------------------------------------------------------------------
+%% Function: init_per_group(GroupName, Config0) ->
+%% Config1 | {skip,Reason} | {skip_and_save,Reason,Config1}
+%% GroupName = atom()
+%% Config0 = Config1 = [tuple()]
+%% Reason = term()
+%%--------------------------------------------------------------------
+init_per_group(_GroupName, Config) ->
+ Config.
+
+%%--------------------------------------------------------------------
+%% Function: end_per_group(GroupName, Config0) ->
+%% void() | {save_config,Config1}
+%% GroupName = atom()
+%% Config0 = Config1 = [tuple()]
+%%--------------------------------------------------------------------
+end_per_group(_GroupName, _Config) ->
+ ok.
+
+%%--------------------------------------------------------------------
+%% Function: init_per_testcase(TestCase, Config0) ->
+%% Config1 | {skip,Reason} | {skip_and_save,Reason,Config1}
+%% TestCase = atom()
+%% Config0 = Config1 = [tuple()]
+%% Reason = term()
+%%--------------------------------------------------------------------
+init_per_testcase(_TestCase, Config) ->
+ Config.
+
+%%--------------------------------------------------------------------
+%% Function: end_per_testcase(TestCase, Config0) ->
+%% void() | {save_config,Config1}
+%% TestCase = atom()
+%% Config0 = Config1 = [tuple()]
+%%--------------------------------------------------------------------
+end_per_testcase(_TestCase, _Config) ->
+ ok.
+
+%%--------------------------------------------------------------------
+%% Function: groups() -> [Group]
+%% Group = {GroupName,Properties,GroupsAndTestCases}
+%% GroupName = atom()
+%% Properties = [parallel | sequence | Shuffle | {RepeatType,N}]
+%% GroupsAndTestCases = [Group | {group,GroupName} | TestCase]
+%% TestCase = atom()
+%% Shuffle = shuffle | {shuffle,{integer(),integer(),integer()}}
+%% RepeatType = repeat | repeat_until_all_ok | repeat_until_all_fail |
+%% repeat_until_any_ok | repeat_until_any_fail
+%% N = integer() | forever
+%%--------------------------------------------------------------------
+groups() ->
+ [].
+
+%%--------------------------------------------------------------------
+%% Function: all() -> GroupsAndTestCases | {skip,Reason}
+%% GroupsAndTestCases = [{group,GroupName} | TestCase]
+%% GroupName = atom()
+%% TestCase = atom()
+%% Reason = term()
+%%--------------------------------------------------------------------
+all() ->
+ [tc1,tc2].
+
+%%--------------------------------------------------------------------
+%% Function: TestCase() -> Info
+%% Info = [tuple()]
+%%--------------------------------------------------------------------
+tc1() ->
+ [].
+
+%%--------------------------------------------------------------------
+%% Function: TestCase(Config0) ->
+%% ok | exit() | {skip,Reason} | {comment,Comment} |
+%% {save_config,Config1} | {skip_and_save,Reason,Config1}
+%% Config0 = Config1 = [tuple()]
+%% Reason = term()
+%% Comment = term()
+%%--------------------------------------------------------------------
+tc1(_Config) ->
+ ok.
+
+tc2(_Config) ->
+ ok.
diff --git a/lib/common_test/test/ct_skip_SUITE_data/skip/test/auto_skip_9_SUITE.erl b/lib/common_test/test/ct_skip_SUITE_data/skip/test/auto_skip_9_SUITE.erl
new file mode 100644
index 0000000000..e2d6bcf7d6
--- /dev/null
+++ b/lib/common_test/test/ct_skip_SUITE_data/skip/test/auto_skip_9_SUITE.erl
@@ -0,0 +1,166 @@
+%%
+%% %CopyrightBegin%
+%%
+%% 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(auto_skip_9_SUITE).
+
+-compile(export_all).
+
+-include_lib("common_test/include/ct.hrl").
+
+%%--------------------------------------------------------------------
+%% Function: suite() -> Info
+%% Info = [tuple()]
+%%--------------------------------------------------------------------
+suite() ->
+ [{timetrap,{seconds,30}}].
+
+%%--------------------------------------------------------------------
+%% Function: init_per_suite(Config0) ->
+%% Config1 | {skip,Reason} | {skip_and_save,Reason,Config1}
+%% Config0 = Config1 = [tuple()]
+%% Reason = term()
+%%--------------------------------------------------------------------
+init_per_suite(Config) ->
+ Config.
+
+%%--------------------------------------------------------------------
+%% Function: end_per_suite(Config0) -> void() | {save_config,Config1}
+%% Config0 = Config1 = [tuple()]
+%%--------------------------------------------------------------------
+end_per_suite(_Config) ->
+ ok.
+
+%%--------------------------------------------------------------------
+%% Function: init_per_group(GroupName, Config0) ->
+%% Config1 | {skip,Reason} | {skip_and_save,Reason,Config1}
+%% GroupName = atom()
+%% Config0 = Config1 = [tuple()]
+%% Reason = term()
+%%--------------------------------------------------------------------
+init_per_group(g1, Config) ->
+ ok;
+init_per_group(g2, Config) ->
+ [{x,y,z}|Config];
+init_per_group(_, Config) ->
+ Config.
+
+%%--------------------------------------------------------------------
+%% Function: end_per_group(GroupName, Config0) ->
+%% void() | {save_config,Config1}
+%% GroupName = atom()
+%% Config0 = Config1 = [tuple()]
+%%--------------------------------------------------------------------
+end_per_group(_GroupName, _Config) ->
+ ok.
+
+%%--------------------------------------------------------------------
+%% Function: init_per_testcase(TestCase, Config0) ->
+%% Config1 | {skip,Reason} | {skip_and_save,Reason,Config1}
+%% TestCase = atom()
+%% Config0 = Config1 = [tuple()]
+%% Reason = term()
+%%--------------------------------------------------------------------
+init_per_testcase(tc2, Config) ->
+ {ok,Config};
+init_per_testcase(tc5, Config) ->
+ ok;
+init_per_testcase(tc8, Config) ->
+ huh = ?config(void, Config),
+ Config;
+init_per_testcase(_, Config) ->
+ Config.
+
+%%--------------------------------------------------------------------
+%% Function: end_per_testcase(TestCase, Config0) ->
+%% void() | {save_config,Config1}
+%% TestCase = atom()
+%% Config0 = Config1 = [tuple()]
+%%--------------------------------------------------------------------
+end_per_testcase(_TestCase, _Config) ->
+ ok.
+
+%%--------------------------------------------------------------------
+%% Function: groups() -> [Group]
+%% Group = {GroupName,Properties,GroupsAndTestCases}
+%% GroupName = atom()
+%% Properties = [parallel | sequence | Shuffle | {RepeatType,N}]
+%% GroupsAndTestCases = [Group | {group,GroupName} | TestCase]
+%% TestCase = atom()
+%% Shuffle = shuffle | {shuffle,{integer(),integer(),integer()}}
+%% RepeatType = repeat | repeat_until_all_ok | repeat_until_all_fail |
+%% repeat_until_any_ok | repeat_until_any_fail
+%% N = integer() | forever
+%%--------------------------------------------------------------------
+groups() ->
+ [{g1,[],[tc3]},
+ {g2,[],[tc4]},
+ {g3,[],[tc5]},
+ {g4,[parallel],[tc6,{group,g5},tc7]},
+ {g5,[parallel],[tc8]}].
+
+%%--------------------------------------------------------------------
+%% Function: all() -> GroupsAndTestCases | {skip,Reason}
+%% GroupsAndTestCases = [{group,GroupName} | TestCase]
+%% GroupName = atom()
+%% TestCase = atom()
+%% Reason = term()
+%%--------------------------------------------------------------------
+all() ->
+ [tc1,tc2,{group,g1},{group,g2},{group,g3},{group,g4}].
+
+%%--------------------------------------------------------------------
+%% Function: TestCase() -> Info
+%% Info = [tuple()]
+%%--------------------------------------------------------------------
+tc1() ->
+ [].
+
+%%--------------------------------------------------------------------
+%% Function: TestCase(Config0) ->
+%% ok | exit() | {skip,Reason} | {comment,Comment} |
+%% {save_config,Config1} | {skip_and_save,Reason,Config1}
+%% Config0 = Config1 = [tuple()]
+%% Reason = term()
+%% Comment = term()
+%%--------------------------------------------------------------------
+tc1(_Config) ->
+ ct:comment("Should be ok"),
+ true.
+
+tc2(_Config) ->
+ exit("Should fail in init_per_testcase").
+
+tc3(Config) ->
+ ?config(data_dir, Config).
+
+tc4(Config) ->
+ ?config(data_dir, Config).
+
+tc5(_Config) ->
+ exit("Should fail in init_per_testcase").
+
+tc6(_Config) ->
+ done.
+
+tc7(_Config) ->
+ done.
+
+tc8(_Config) ->
+ exit("Should fail in init_per_testcase").
+
+
diff --git a/lib/common_test/test/ct_skip_SUITE_data/skip/test/user_skip_1_SUITE.erl b/lib/common_test/test/ct_skip_SUITE_data/skip/test/user_skip_1_SUITE.erl
new file mode 100644
index 0000000000..60fc0f1122
--- /dev/null
+++ b/lib/common_test/test/ct_skip_SUITE_data/skip/test/user_skip_1_SUITE.erl
@@ -0,0 +1,131 @@
+%%
+%% %CopyrightBegin%
+%%
+%% 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(user_skip_1_SUITE).
+
+-compile(export_all).
+
+-include_lib("common_test/include/ct.hrl").
+
+%%--------------------------------------------------------------------
+%% Function: suite() -> Info
+%% Info = [tuple()]
+%%--------------------------------------------------------------------
+suite() ->
+ [{timetrap,{seconds,30}}].
+
+%%--------------------------------------------------------------------
+%% Function: init_per_suite(Config0) ->
+%% Config1 | {skip,Reason} | {skip_and_save,Reason,Config1}
+%% Config0 = Config1 = [tuple()]
+%% Reason = term()
+%%--------------------------------------------------------------------
+init_per_suite(_Config) ->
+ {skip,"Whole suite skipped"}.
+
+%%--------------------------------------------------------------------
+%% Function: end_per_suite(Config0) -> void() | {save_config,Config1}
+%% Config0 = Config1 = [tuple()]
+%%--------------------------------------------------------------------
+end_per_suite(_Config) ->
+ ok.
+
+%%--------------------------------------------------------------------
+%% Function: init_per_group(GroupName, Config0) ->
+%% Config1 | {skip,Reason} | {skip_and_save,Reason,Config1}
+%% GroupName = atom()
+%% Config0 = Config1 = [tuple()]
+%% Reason = term()
+%%--------------------------------------------------------------------
+init_per_group(_GroupName, Config) ->
+ Config.
+
+%%--------------------------------------------------------------------
+%% Function: end_per_group(GroupName, Config0) ->
+%% void() | {save_config,Config1}
+%% GroupName = atom()
+%% Config0 = Config1 = [tuple()]
+%%--------------------------------------------------------------------
+end_per_group(_GroupName, _Config) ->
+ ok.
+
+%%--------------------------------------------------------------------
+%% Function: init_per_testcase(TestCase, Config0) ->
+%% Config1 | {skip,Reason} | {skip_and_save,Reason,Config1}
+%% TestCase = atom()
+%% Config0 = Config1 = [tuple()]
+%% Reason = term()
+%%--------------------------------------------------------------------
+init_per_testcase(_TestCase, Config) ->
+ Config.
+
+%%--------------------------------------------------------------------
+%% Function: end_per_testcase(TestCase, Config0) ->
+%% void() | {save_config,Config1}
+%% TestCase = atom()
+%% Config0 = Config1 = [tuple()]
+%%--------------------------------------------------------------------
+end_per_testcase(_TestCase, _Config) ->
+ ok.
+
+%%--------------------------------------------------------------------
+%% Function: groups() -> [Group]
+%% Group = {GroupName,Properties,GroupsAndTestCases}
+%% GroupName = atom()
+%% Properties = [parallel | sequence | Shuffle | {RepeatType,N}]
+%% GroupsAndTestCases = [Group | {group,GroupName} | TestCase]
+%% TestCase = atom()
+%% Shuffle = shuffle | {shuffle,{integer(),integer(),integer()}}
+%% RepeatType = repeat | repeat_until_all_ok | repeat_until_all_fail |
+%% repeat_until_any_ok | repeat_until_any_fail
+%% N = integer() | forever
+%%--------------------------------------------------------------------
+groups() ->
+ [{g1,[],[tc2,tc3]}].
+
+%%--------------------------------------------------------------------
+%% Function: all() -> GroupsAndTestCases | {skip,Reason}
+%% GroupsAndTestCases = [{group,GroupName} | TestCase]
+%% GroupName = atom()
+%% TestCase = atom()
+%% Reason = term()
+%%--------------------------------------------------------------------
+all() ->
+ [tc1, {group,g1}, tc4].
+
+
+%%--------------------------------------------------------------------
+%% Function: TestCase(Config0) ->
+%% ok | exit() | {skip,Reason} | {comment,Comment} |
+%% {save_config,Config1} | {skip_and_save,Reason,Config1}
+%% Config0 = Config1 = [tuple()]
+%% Reason = term()
+%% Comment = term()
+%%--------------------------------------------------------------------
+tc1(_) ->
+ ok.
+
+tc2(_) ->
+ ok.
+
+tc3(_) ->
+ ok.
+
+tc4(_) ->
+ ok.
+
diff --git a/lib/common_test/test/ct_skip_SUITE_data/skip/test/user_skip_2_SUITE.erl b/lib/common_test/test/ct_skip_SUITE_data/skip/test/user_skip_2_SUITE.erl
new file mode 100644
index 0000000000..91a046a531
--- /dev/null
+++ b/lib/common_test/test/ct_skip_SUITE_data/skip/test/user_skip_2_SUITE.erl
@@ -0,0 +1,135 @@
+%%
+%% %CopyrightBegin%
+%%
+%% 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(user_skip_2_SUITE).
+
+-compile(export_all).
+
+-include_lib("common_test/include/ct.hrl").
+
+%%--------------------------------------------------------------------
+%% Function: suite() -> Info
+%% Info = [tuple()]
+%%--------------------------------------------------------------------
+suite() ->
+ [{timetrap,{seconds,30}}].
+
+%%--------------------------------------------------------------------
+%% Function: init_per_suite(Config0) ->
+%% Config1 | {skip,Reason} | {skip_and_save,Reason,Config1}
+%% Config0 = Config1 = [tuple()]
+%% Reason = term()
+%%--------------------------------------------------------------------
+init_per_suite(Config) ->
+ Config.
+
+%%--------------------------------------------------------------------
+%% Function: end_per_suite(Config0) -> void() | {save_config,Config1}
+%% Config0 = Config1 = [tuple()]
+%%--------------------------------------------------------------------
+end_per_suite(_Config) ->
+ ok.
+
+%%--------------------------------------------------------------------
+%% Function: init_per_group(GroupName, Config0) ->
+%% Config1 | {skip,Reason} | {skip_and_save,Reason,Config1}
+%% GroupName = atom()
+%% Config0 = Config1 = [tuple()]
+%% Reason = term()
+%%--------------------------------------------------------------------
+init_per_group(_GroupName, Config) ->
+ Config.
+
+%%--------------------------------------------------------------------
+%% Function: end_per_group(GroupName, Config0) ->
+%% void() | {save_config,Config1}
+%% GroupName = atom()
+%% Config0 = Config1 = [tuple()]
+%%--------------------------------------------------------------------
+end_per_group(_GroupName, _Config) ->
+ ok.
+
+%%--------------------------------------------------------------------
+%% Function: init_per_testcase(TestCase, Config0) ->
+%% Config1 | {skip,Reason} | {skip_and_save,Reason,Config1}
+%% TestCase = atom()
+%% Config0 = Config1 = [tuple()]
+%% Reason = term()
+%%--------------------------------------------------------------------
+init_per_testcase(tc1, _Config) ->
+ {skip,{tc1,skipped}};
+init_per_testcase(tc3, _Config) ->
+ {skip,{tc3,skipped}};
+init_per_testcase(_, Config) ->
+ Config.
+
+%%--------------------------------------------------------------------
+%% Function: end_per_testcase(TestCase, Config0) ->
+%% void() | {save_config,Config1}
+%% TestCase = atom()
+%% Config0 = Config1 = [tuple()]
+%%--------------------------------------------------------------------
+end_per_testcase(_TestCase, _Config) ->
+ ok.
+
+%%--------------------------------------------------------------------
+%% Function: groups() -> [Group]
+%% Group = {GroupName,Properties,GroupsAndTestCases}
+%% GroupName = atom()
+%% Properties = [parallel | sequence | Shuffle | {RepeatType,N}]
+%% GroupsAndTestCases = [Group | {group,GroupName} | TestCase]
+%% TestCase = atom()
+%% Shuffle = shuffle | {shuffle,{integer(),integer(),integer()}}
+%% RepeatType = repeat | repeat_until_all_ok | repeat_until_all_fail |
+%% repeat_until_any_ok | repeat_until_any_fail
+%% N = integer() | forever
+%%--------------------------------------------------------------------
+groups() ->
+ [{g1,[],[tc2,tc3]}].
+
+%%--------------------------------------------------------------------
+%% Function: all() -> GroupsAndTestCases | {skip,Reason}
+%% GroupsAndTestCases = [{group,GroupName} | TestCase]
+%% GroupName = atom()
+%% TestCase = atom()
+%% Reason = term()
+%%--------------------------------------------------------------------
+all() ->
+ [tc1, {group,g1}, tc4].
+
+
+%%--------------------------------------------------------------------
+%% Function: TestCase(Config0) ->
+%% ok | exit() | {skip,Reason} | {comment,Comment} |
+%% {save_config,Config1} | {skip_and_save,Reason,Config1}
+%% Config0 = Config1 = [tuple()]
+%% Reason = term()
+%% Comment = term()
+%%--------------------------------------------------------------------
+tc1(_) ->
+ ok.
+
+tc2(_) ->
+ ok.
+
+tc3(_) ->
+ ok.
+
+tc4(_) ->
+ ok.
+
diff --git a/lib/common_test/test/ct_skip_SUITE_data/skip/test/user_skip_3_SUITE.erl b/lib/common_test/test/ct_skip_SUITE_data/skip/test/user_skip_3_SUITE.erl
new file mode 100644
index 0000000000..c362117bba
--- /dev/null
+++ b/lib/common_test/test/ct_skip_SUITE_data/skip/test/user_skip_3_SUITE.erl
@@ -0,0 +1,132 @@
+%%
+%% %CopyrightBegin%
+%%
+%% 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(user_skip_3_SUITE).
+
+-compile(export_all).
+
+-include_lib("common_test/include/ct.hrl").
+
+%%--------------------------------------------------------------------
+%% Function: suite() -> Info
+%% Info = [tuple()]
+%%--------------------------------------------------------------------
+suite() ->
+ [{timetrap,{seconds,30}}].
+
+%%--------------------------------------------------------------------
+%% Function: init_per_suite(Config0) ->
+%% Config1 | {skip,Reason} | {skip_and_save,Reason,Config1}
+%% Config0 = Config1 = [tuple()]
+%% Reason = term()
+%%--------------------------------------------------------------------
+init_per_suite(Config) ->
+ Config.
+
+%%--------------------------------------------------------------------
+%% Function: end_per_suite(Config0) -> void() | {save_config,Config1}
+%% Config0 = Config1 = [tuple()]
+%%--------------------------------------------------------------------
+end_per_suite(_Config) ->
+ ok.
+
+%%--------------------------------------------------------------------
+%% Function: init_per_group(GroupName, Config0) ->
+%% Config1 | {skip,Reason} | {skip_and_save,Reason,Config1}
+%% GroupName = atom()
+%% Config0 = Config1 = [tuple()]
+%% Reason = term()
+%%--------------------------------------------------------------------
+init_per_group(_GroupName, Config) ->
+ Config.
+
+%%--------------------------------------------------------------------
+%% Function: end_per_group(GroupName, Config0) ->
+%% void() | {save_config,Config1}
+%% GroupName = atom()
+%% Config0 = Config1 = [tuple()]
+%%--------------------------------------------------------------------
+end_per_group(_GroupName, _Config) ->
+ ok.
+
+%%--------------------------------------------------------------------
+%% Function: init_per_testcase(TestCase, Config0) ->
+%% Config1 | {skip,Reason} | {skip_and_save,Reason,Config1}
+%% TestCase = atom()
+%% Config0 = Config1 = [tuple()]
+%% Reason = term()
+%%--------------------------------------------------------------------
+init_per_testcase(_, Config) ->
+ Config.
+
+%%--------------------------------------------------------------------
+%% Function: end_per_testcase(TestCase, Config0) ->
+%% void() | {save_config,Config1}
+%% TestCase = atom()
+%% Config0 = Config1 = [tuple()]
+%%--------------------------------------------------------------------
+end_per_testcase(_TestCase, _Config) ->
+ ok.
+
+%%--------------------------------------------------------------------
+%% Function: groups() -> [Group]
+%% Group = {GroupName,Properties,GroupsAndTestCases}
+%% GroupName = atom()
+%% Properties = [parallel | sequence | Shuffle | {RepeatType,N}]
+%% GroupsAndTestCases = [Group | {group,GroupName} | TestCase]
+%% TestCase = atom()
+%% Shuffle = shuffle | {shuffle,{integer(),integer(),integer()}}
+%% RepeatType = repeat | repeat_until_all_ok | repeat_until_all_fail |
+%% repeat_until_any_ok | repeat_until_any_fail
+%% N = integer() | forever
+%%--------------------------------------------------------------------
+groups() ->
+ [{g1,[],[tc2,tc3]}].
+
+%%--------------------------------------------------------------------
+%% Function: all() -> GroupsAndTestCases | {skip,Reason}
+%% GroupsAndTestCases = [{group,GroupName} | TestCase]
+%% GroupName = atom()
+%% TestCase = atom()
+%% Reason = term()
+%%--------------------------------------------------------------------
+all() ->
+ [tc1, {group,g1}, tc4].
+
+
+%%--------------------------------------------------------------------
+%% Function: TestCase(Config0) ->
+%% ok | exit() | {skip,Reason} | {comment,Comment} |
+%% {save_config,Config1} | {skip_and_save,Reason,Config1}
+%% Config0 = Config1 = [tuple()]
+%% Reason = term()
+%% Comment = term()
+%%--------------------------------------------------------------------
+tc1(_) ->
+ {skip,"Test case skipped"}.
+
+tc2(_) ->
+ ok.
+
+tc3(_) ->
+ {skip,"Test case skipped"}.
+
+tc4(_) ->
+ {skip,{proc_info,{process_info(self(),current_function),
+ process_info(self(),initial_call)}}}.
+
diff --git a/lib/common_test/test/ct_skip_SUITE_data/skip/test/user_skip_4_SUITE.erl b/lib/common_test/test/ct_skip_SUITE_data/skip/test/user_skip_4_SUITE.erl
new file mode 100644
index 0000000000..77fd5a2b5b
--- /dev/null
+++ b/lib/common_test/test/ct_skip_SUITE_data/skip/test/user_skip_4_SUITE.erl
@@ -0,0 +1,152 @@
+%%
+%% %CopyrightBegin%
+%%
+%% 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(user_skip_4_SUITE).
+
+-compile(export_all).
+
+-include_lib("common_test/include/ct.hrl").
+
+%%--------------------------------------------------------------------
+%% Function: suite() -> Info
+%% Info = [tuple()]
+%%--------------------------------------------------------------------
+suite() ->
+ [{timetrap,{seconds,30}}].
+
+%%--------------------------------------------------------------------
+%% Function: init_per_suite(Config0) ->
+%% Config1 | {skip,Reason} | {skip_and_save,Reason,Config1}
+%% Config0 = Config1 = [tuple()]
+%% Reason = term()
+%%--------------------------------------------------------------------
+init_per_suite(Config) ->
+ Config.
+
+%%--------------------------------------------------------------------
+%% Function: end_per_suite(Config0) -> void() | {save_config,Config1}
+%% Config0 = Config1 = [tuple()]
+%%--------------------------------------------------------------------
+end_per_suite(_Config) ->
+ ok.
+
+%%--------------------------------------------------------------------
+%% Function: init_per_group(GroupName, Config0) ->
+%% Config1 | {skip,Reason} | {skip_and_save,Reason,Config1}
+%% GroupName = atom()
+%% Config0 = Config1 = [tuple()]
+%% Reason = term()
+%%--------------------------------------------------------------------
+init_per_group(g1, _Config) ->
+ {skip,"Group skipped"};
+init_per_group(g3, _Config) ->
+ {skip,"Group skipped"};
+init_per_group(g6, _Config) ->
+ {skip,"Group skipped"};
+init_per_group(_, Config) ->
+ Config.
+
+%%--------------------------------------------------------------------
+%% Function: end_per_group(GroupName, Config0) ->
+%% void() | {save_config,Config1}
+%% GroupName = atom()
+%% Config0 = Config1 = [tuple()]
+%%--------------------------------------------------------------------
+end_per_group(_GroupName, _Config) ->
+ ok.
+
+%%--------------------------------------------------------------------
+%% Function: init_per_testcase(TestCase, Config0) ->
+%% Config1 | {skip,Reason} | {skip_and_save,Reason,Config1}
+%% TestCase = atom()
+%% Config0 = Config1 = [tuple()]
+%% Reason = term()
+%%--------------------------------------------------------------------
+init_per_testcase(_, Config) ->
+ Config.
+
+%%--------------------------------------------------------------------
+%% Function: end_per_testcase(TestCase, Config0) ->
+%% void() | {save_config,Config1}
+%% TestCase = atom()
+%% Config0 = Config1 = [tuple()]
+%%--------------------------------------------------------------------
+end_per_testcase(_TestCase, _Config) ->
+ ok.
+
+%%--------------------------------------------------------------------
+%% Function: groups() -> [Group]
+%% Group = {GroupName,Properties,GroupsAndTestCases}
+%% GroupName = atom()
+%% Properties = [parallel | sequence | Shuffle | {RepeatType,N}]
+%% GroupsAndTestCases = [Group | {group,GroupName} | TestCase]
+%% TestCase = atom()
+%% Shuffle = shuffle | {shuffle,{integer(),integer(),integer()}}
+%% RepeatType = repeat | repeat_until_all_ok | repeat_until_all_fail |
+%% repeat_until_any_ok | repeat_until_any_fail
+%% N = integer() | forever
+%%--------------------------------------------------------------------
+groups() ->
+ [{g1,[],[tc1,tc2]},
+ {g2,[],[tc3,tc4]},
+ {g3,[],[tc5,{g4,[],[tc6,tc7]},tc8]},
+ {g5,[],[tc9,{g6,[],[tc10,tc11]}]}].
+
+%%--------------------------------------------------------------------
+%% Function: all() -> GroupsAndTestCases | {skip,Reason}
+%% GroupsAndTestCases = [{group,GroupName} | TestCase]
+%% GroupName = atom()
+%% TestCase = atom()
+%% Reason = term()
+%%--------------------------------------------------------------------
+all() ->
+ [{group,g1}, {group,g2}, {group,g3}, {group,g5}].
+
+
+%%--------------------------------------------------------------------
+%% Function: TestCase(Config0) ->
+%% ok | exit() | {skip,Reason} | {comment,Comment} |
+%% {save_config,Config1} | {skip_and_save,Reason,Config1}
+%% Config0 = Config1 = [tuple()]
+%% Reason = term()
+%% Comment = term()
+%%--------------------------------------------------------------------
+tc1(_) ->
+ ok.
+tc2(_) ->
+ ok.
+tc3(_) ->
+ ok.
+tc4(_) ->
+ ok.
+tc5(_) ->
+ ok.
+tc6(_) ->
+ ok.
+tc7(_) ->
+ ok.
+tc8(_) ->
+ ok.
+tc9(_) ->
+ ok.
+tc10(_) ->
+ ok.
+tc11(_) ->
+ ok.
+
+
diff --git a/lib/common_test/test/ct_skip_SUITE_data/skip/test/user_skip_5_SUITE.erl b/lib/common_test/test/ct_skip_SUITE_data/skip/test/user_skip_5_SUITE.erl
new file mode 100644
index 0000000000..4bffa202d6
--- /dev/null
+++ b/lib/common_test/test/ct_skip_SUITE_data/skip/test/user_skip_5_SUITE.erl
@@ -0,0 +1,131 @@
+%%
+%% %CopyrightBegin%
+%%
+%% 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(user_skip_5_SUITE).
+
+-compile(export_all).
+
+-include_lib("common_test/include/ct.hrl").
+
+%%--------------------------------------------------------------------
+%% Function: suite() -> Info
+%% Info = [tuple()]
+%%--------------------------------------------------------------------
+suite() ->
+ [{timetrap,{seconds,30}}].
+
+%%--------------------------------------------------------------------
+%% Function: init_per_suite(Config0) ->
+%% Config1 | {skip,Reason} | {skip_and_save,Reason,Config1}
+%% Config0 = Config1 = [tuple()]
+%% Reason = term()
+%%--------------------------------------------------------------------
+init_per_suite(_Config) ->
+ {skip,{bad,'Whole suite skipped'}}.
+
+%%--------------------------------------------------------------------
+%% Function: end_per_suite(Config0) -> void() | {save_config,Config1}
+%% Config0 = Config1 = [tuple()]
+%%--------------------------------------------------------------------
+end_per_suite(_Config) ->
+ ok.
+
+%%--------------------------------------------------------------------
+%% Function: init_per_group(GroupName, Config0) ->
+%% Config1 | {skip,Reason} | {skip_and_save,Reason,Config1}
+%% GroupName = atom()
+%% Config0 = Config1 = [tuple()]
+%% Reason = term()
+%%--------------------------------------------------------------------
+init_per_group(_GroupName, Config) ->
+ Config.
+
+%%--------------------------------------------------------------------
+%% Function: end_per_group(GroupName, Config0) ->
+%% void() | {save_config,Config1}
+%% GroupName = atom()
+%% Config0 = Config1 = [tuple()]
+%%--------------------------------------------------------------------
+end_per_group(_GroupName, _Config) ->
+ ok.
+
+%%--------------------------------------------------------------------
+%% Function: init_per_testcase(TestCase, Config0) ->
+%% Config1 | {skip,Reason} | {skip_and_save,Reason,Config1}
+%% TestCase = atom()
+%% Config0 = Config1 = [tuple()]
+%% Reason = term()
+%%--------------------------------------------------------------------
+init_per_testcase(_TestCase, Config) ->
+ Config.
+
+%%--------------------------------------------------------------------
+%% Function: end_per_testcase(TestCase, Config0) ->
+%% void() | {save_config,Config1}
+%% TestCase = atom()
+%% Config0 = Config1 = [tuple()]
+%%--------------------------------------------------------------------
+end_per_testcase(_TestCase, _Config) ->
+ ok.
+
+%%--------------------------------------------------------------------
+%% Function: groups() -> [Group]
+%% Group = {GroupName,Properties,GroupsAndTestCases}
+%% GroupName = atom()
+%% Properties = [parallel | sequence | Shuffle | {RepeatType,N}]
+%% GroupsAndTestCases = [Group | {group,GroupName} | TestCase]
+%% TestCase = atom()
+%% Shuffle = shuffle | {shuffle,{integer(),integer(),integer()}}
+%% RepeatType = repeat | repeat_until_all_ok | repeat_until_all_fail |
+%% repeat_until_any_ok | repeat_until_any_fail
+%% N = integer() | forever
+%%--------------------------------------------------------------------
+groups() ->
+ [{g1,[],[tc2,tc3]}].
+
+%%--------------------------------------------------------------------
+%% Function: all() -> GroupsAndTestCases | {skip,Reason}
+%% GroupsAndTestCases = [{group,GroupName} | TestCase]
+%% GroupName = atom()
+%% TestCase = atom()
+%% Reason = term()
+%%--------------------------------------------------------------------
+all() ->
+ [tc1, {group,g1}, tc4].
+
+
+%%--------------------------------------------------------------------
+%% Function: TestCase(Config0) ->
+%% ok | exit() | {skip,Reason} | {comment,Comment} |
+%% {save_config,Config1} | {skip_and_save,Reason,Config1}
+%% Config0 = Config1 = [tuple()]
+%% Reason = term()
+%% Comment = term()
+%%--------------------------------------------------------------------
+tc1(_) ->
+ ok.
+
+tc2(_) ->
+ ok.
+
+tc3(_) ->
+ ok.
+
+tc4(_) ->
+ ok.
+
diff --git a/lib/common_test/test/ct_smoke_test_SUITE.erl b/lib/common_test/test/ct_smoke_test_SUITE.erl
new file mode 100644
index 0000000000..f1c695f614
--- /dev/null
+++ b/lib/common_test/test/ct_smoke_test_SUITE.erl
@@ -0,0 +1,569 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 2008-2010. All Rights Reserved.
+%%
+%% The contents of this file are subject to the Erlang Public License,
+%% Version 1.1, (the "License"); you may not use this file except in
+%% compliance with the License. You should have received a copy of the
+%% Erlang Public License along with this software. If not, it can be
+%% retrieved online at http://www.erlang.org/.
+%%
+%% Software distributed under the License is distributed on an "AS IS"
+%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+%% the License for the specific language governing rights and limitations
+%% under the License.
+%%
+%% %CopyrightEnd%
+%%
+
+%%%-------------------------------------------------------------------
+%%% File: ct_smoke_test_SUITE.erl
+%%%
+%%% Description: The purpose of this suite is to test that Common Test
+%%% can be started properly and that simple dummy test suites are
+%%% executed without unexpected crashes or hangings. The suites used
+%%% for the test are located in the data directory.
+%%%-------------------------------------------------------------------
+-module(ct_smoke_test_SUITE).
+
+-compile(export_all).
+
+-include_lib("test_server/include/test_server.hrl").
+-include_lib("common_test/include/ct_event.hrl").
+
+-define(eh, ct_test_support_eh).
+
+%%--------------------------------------------------------------------
+%% TEST SERVER CALLBACK FUNCTIONS
+%%--------------------------------------------------------------------
+
+%%--------------------------------------------------------------------
+%% Function: init_per_suite(Config0) -> Config1 | {skip,Reason}
+%%
+%% Config0 = Config1 = [tuple()]
+%% A list of key/value pairs, holding the test case configuration.
+%% Reason = term()
+%% The reason for skipping the suite.
+%%
+%% Description: Since Common Test starts another Test Server
+%% instance, the tests need to be performed on a separate node (or
+%% there will be clashes with logging processes etc).
+%%--------------------------------------------------------------------
+init_per_suite(Config) ->
+ Config1 = ct_test_support:init_per_suite(Config),
+ Config1.
+
+%%--------------------------------------------------------------------
+%% Function: end_per_suite(Config) -> void()
+%%
+%% Config = [tuple()]
+%% A list of key/value pairs, holding the test case configuration.
+%%
+%% Description: Cleanup after the suite.
+%%--------------------------------------------------------------------
+end_per_suite(Config) ->
+ ct_test_support:end_per_suite(Config).
+
+%%--------------------------------------------------------------------
+%% Function: init_per_testcase(TestCase, Config0) -> Config1 |
+%% {skip,Reason}
+%% TestCase = atom()
+%% Name of the test case that is about to run.
+%% Config0 = Config1 = [tuple()]
+%% A list of key/value pairs, holding the test case configuration.
+%% Reason = term()
+%% The reason for skipping the test case.
+%%
+%% 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.
+%%--------------------------------------------------------------------
+init_per_testcase(TestCase, Config) ->
+ ct_test_support:init_per_testcase(TestCase, Config).
+
+%%--------------------------------------------------------------------
+%% Function: end_per_testcase(TestCase, Config) -> void()
+%%
+%% TestCase = atom()
+%% Name of the test case that is finished.
+%% Config = [tuple()]
+%% A list of key/value pairs, holding the test case configuration.
+%%
+%% Description: Cleanup after each test case.
+%%--------------------------------------------------------------------
+end_per_testcase(TestCase, Config) ->
+ ct_test_support:end_per_testcase(TestCase, Config).
+
+%%--------------------------------------------------------------------
+%% Function: all(Clause) -> Descr | TestCases | {skip,Reason}
+%%
+%% Clause = doc | suite
+%% Indicates expected return value.
+%% Descr = [string()] | []
+%% String that describes the test suite.
+%% TestCases = [TestCase]
+%% TestCase = atom()
+%% Name of a test case.
+%% Reason = term()
+%% The reason for skipping the test suite.
+%%
+%% Description: Returns a description of the test suite (doc) and a
+%% list of all test cases in the suite (suite).
+%%--------------------------------------------------------------------
+all(doc) ->
+ ["Run smoke tests of Common Test."];
+
+all(suite) ->
+ [dir1, dir2, dir1_2,
+ suite11, suite21, suite11_21,
+ tc111, tc211, tc111_112].
+
+
+%%--------------------------------------------------------------------
+%% TEST CASES
+%%--------------------------------------------------------------------
+
+%%--------------------------------------------------------------------
+%% Function: TestCase(Arg) -> Descr | Spec | ok | exit() | {skip,Reason}
+%%
+%% Arg = doc | suite | Config
+%% Indicates expected behaviour and return value.
+%% Config = [tuple()]
+%% A list of key/value pairs, holding the test case configuration.
+%% Descr = [string()] | []
+%% String that describes the test case.
+%% Spec = [tuple()] | []
+%% A test specification.
+%% Reason = term()
+%% The reason for skipping the test case.
+%%
+%% Description: Test case function. Returns a description of the test
+%% case (doc), then returns a test specification (suite),
+%% or performs the actual test (Config).
+%%--------------------------------------------------------------------
+
+%%%-----------------------------------------------------------------
+%%%
+
+dir1(doc) ->
+ [];
+dir1(suite) ->
+ [];
+dir1(Config) when is_list(Config) ->
+ DataDir = ?config(data_dir, Config),
+
+ Happy1 = filename:join(DataDir, "happy_1"),
+ Happy1Cfg = filename:join(Happy1, "cfg/config1.cfg"),
+
+ Opts0 = ct_test_support:get_opts(Config),
+ Opts = eh_opts(Config) ++ Opts0 ++ [{config,Happy1Cfg}, {dir,Happy1}],
+
+ ERPid = ct_test_support:start_event_receiver(Config),
+
+ ok = ct_test_support:run(ct, run_test, [Opts], Config),
+
+ Events = ct_test_support:get_events(ERPid, Config),
+
+ ct_test_support:log_events(dir1,
+ ct_test_support:reformat(Events, ?eh),
+ ?config(priv_dir, Config)),
+
+ TestEvents = test_events(dir1),
+ ok = ct_test_support:verify_events(TestEvents, Events, Config).
+
+%%%-----------------------------------------------------------------
+%%%
+
+dir2(doc) ->
+ [];
+dir2(suite) ->
+ [];
+dir2(Config) when is_list(Config) ->
+ DataDir = ?config(data_dir, Config),
+
+ Happy2 = filename:join(DataDir, "happy_2_test"),
+ Happy2Cfg = filename:join(DataDir, "happy_2_cfg/config1.cfg"),
+
+ Opts0 = ct_test_support:get_opts(Config),
+ Opts = eh_opts(Config) ++ Opts0 ++ [{config,Happy2Cfg}, {dir,Happy2}],
+
+ ERPid = ct_test_support:start_event_receiver(Config),
+
+ ok = ct_test_support:run(ct, run_test, [Opts], Config),
+
+ Events = ct_test_support:get_events(ERPid, Config),
+
+ ct_test_support:log_events(dir2,
+ ct_test_support:reformat(Events, ?eh),
+ ?config(priv_dir, Config)),
+
+ TestEvents = test_events(dir2),
+ ok = ct_test_support:verify_events(TestEvents, Events, Config).
+
+%%%-----------------------------------------------------------------
+%%%
+
+dir1_2(doc) ->
+ [];
+dir1_2(suite) ->
+ [];
+dir1_2(Config) when is_list(Config) ->
+ DataDir = ?config(data_dir, Config),
+
+ Happy1 = filename:join(DataDir, "happy_1"),
+ Happy2 = filename:join(DataDir, "happy_2_test"),
+ Happy1Cfg = filename:join(Happy1, "cfg/config1.cfg"),
+
+ Opts0 = ct_test_support:get_opts(Config),
+ Opts = eh_opts(Config) ++ Opts0 ++ [{config,Happy1Cfg}, {dir,[Happy1,Happy2]}],
+
+ ERPid = ct_test_support:start_event_receiver(Config),
+
+ ok = ct_test_support:run(ct, run_test, [Opts], Config),
+
+ Events = ct_test_support:get_events(ERPid, Config),
+
+ ct_test_support:log_events(dir1_2,
+ ct_test_support:reformat(Events, ?eh),
+ ?config(priv_dir, Config)),
+
+ TestEvents = test_events(dir1_2),
+ ok = ct_test_support:verify_events(TestEvents, Events, Config).
+
+%%%-----------------------------------------------------------------
+%%%
+
+suite11(doc) ->
+ [];
+suite11(suite) ->
+ [];
+suite11(Config) when is_list(Config) ->
+ DataDir = ?config(data_dir, Config),
+
+ Happy1 = filename:join(DataDir, "happy_1"),
+ Suite = filename:join(Happy1, "test/happy_11_SUITE"),
+ Happy1Cfg = filename:join(Happy1, "cfg/config1.cfg"),
+
+ Opts0 = ct_test_support:get_opts(Config),
+ Opts = eh_opts(Config) ++ Opts0 ++ [{config,Happy1Cfg}, {suite,Suite}],
+
+ ERPid = ct_test_support:start_event_receiver(Config),
+
+ ok = ct_test_support:run(ct, run_test, [Opts], Config),
+
+ Events = ct_test_support:get_events(ERPid, Config),
+
+ ct_test_support:log_events(suite11,
+ ct_test_support:reformat(Events, ?eh),
+ ?config(priv_dir, Config)),
+
+ TestEvents = test_events(suite11),
+ ok = ct_test_support:verify_events(TestEvents, Events, Config).
+
+%%%-----------------------------------------------------------------
+%%%
+
+suite21(doc) ->
+ [];
+suite21(suite) ->
+ [];
+suite21(Config) when is_list(Config) ->
+ DataDir = ?config(data_dir, Config),
+
+ Suite = filename:join(DataDir, "happy_2_test/happy_21_SUITE"),
+ Happy2Cfg = filename:join(DataDir, "happy_2_cfg/config1.cfg"),
+
+ Opts0 = ct_test_support:get_opts(Config),
+ Opts = eh_opts(Config) ++ Opts0 ++ [{config,Happy2Cfg}, {suite,Suite}],
+
+ ERPid = ct_test_support:start_event_receiver(Config),
+
+ ok = ct_test_support:run(ct, run_test, [Opts], Config),
+
+ Events = ct_test_support:get_events(ERPid, Config),
+
+ ct_test_support:log_events(suite21,
+ ct_test_support:reformat(Events, ?eh),
+ ?config(priv_dir, Config)),
+
+ TestEvents = test_events(suite21),
+ ok = ct_test_support:verify_events(TestEvents, Events, Config).
+
+%%%-----------------------------------------------------------------
+%%%
+
+suite11_21(doc) ->
+ [];
+suite11_21(suite) ->
+ [];
+suite11_21(Config) when is_list(Config) ->
+ DataDir = ?config(data_dir, Config),
+
+ Happy1 = filename:join(DataDir, "happy_1"),
+ Suite11 = filename:join(Happy1, "test/happy_11_SUITE"),
+ Happy1Cfg = filename:join(Happy1, "cfg/config1.cfg"),
+ Suite21 = filename:join(DataDir, "happy_2_test/happy_21_SUITE"),
+
+ Opts0 = ct_test_support:get_opts(Config),
+ Opts = eh_opts(Config) ++ Opts0 ++ [{config,Happy1Cfg}, {suite,[Suite11,Suite21]}],
+
+ ERPid = ct_test_support:start_event_receiver(Config),
+
+ ok = ct_test_support:run(ct, run_test, [Opts], Config),
+
+ Events = ct_test_support:get_events(ERPid, Config),
+
+ ct_test_support:log_events(suite11_21,
+ ct_test_support:reformat(Events, ?eh),
+ ?config(priv_dir, Config)),
+
+ TestEvents = test_events(suite11_21),
+ ok = ct_test_support:verify_events(TestEvents, Events, Config).
+
+%%%-----------------------------------------------------------------
+%%%
+
+tc111(doc) ->
+ [];
+tc111(suite) ->
+ [];
+tc111(Config) when is_list(Config) ->
+ DataDir = ?config(data_dir, Config),
+
+ Happy1 = filename:join(DataDir, "happy_1"),
+ Suite = filename:join(Happy1, "test/happy_11_SUITE"),
+ Happy1Cfg = filename:join(Happy1, "cfg/config1.cfg"),
+
+ Opts0 = ct_test_support:get_opts(Config),
+ Opts = eh_opts(Config) ++ Opts0 ++ [{config,Happy1Cfg}, {suite,Suite},
+ {testcase,tc1}],
+
+ ERPid = ct_test_support:start_event_receiver(Config),
+
+ ok = ct_test_support:run(ct, run_test, [Opts], Config),
+
+ Events = ct_test_support:get_events(ERPid, Config),
+
+ ct_test_support:log_events(tc111,
+ ct_test_support:reformat(Events, ?eh),
+ ?config(priv_dir, Config)),
+
+ TestEvents = test_events(tc111),
+ ok = ct_test_support:verify_events(TestEvents, Events, Config).
+
+%%%-----------------------------------------------------------------
+%%%
+
+tc211(doc) ->
+ [];
+tc211(suite) ->
+ [];
+tc211(Config) when is_list(Config) ->
+ DataDir = ?config(data_dir, Config),
+
+ Suite = filename:join(DataDir, "happy_2_test/happy_21_SUITE"),
+ Happy2Cfg = filename:join(DataDir, "happy_2_cfg/config1.cfg"),
+
+ Opts0 = ct_test_support:get_opts(Config),
+ Opts = eh_opts(Config) ++ Opts0 ++ [{config,Happy2Cfg}, {suite,Suite},
+ {testcase,tc1}],
+
+ ERPid = ct_test_support:start_event_receiver(Config),
+
+ ok = ct_test_support:run(ct, run_test, [Opts], Config),
+
+ Events = ct_test_support:get_events(ERPid, Config),
+
+ ct_test_support:log_events(tc211,
+ ct_test_support:reformat(Events, ?eh),
+ ?config(priv_dir, Config)),
+
+ TestEvents = test_events(tc211),
+ ok = ct_test_support:verify_events(TestEvents, Events, Config).
+
+%%%-----------------------------------------------------------------
+%%%
+
+tc111_112(doc) ->
+ [];
+tc111_112(suite) ->
+ [];
+tc111_112(Config) when is_list(Config) ->
+ DataDir = ?config(data_dir, Config),
+
+ Happy1 = filename:join(DataDir, "happy_1"),
+ Suite = filename:join(Happy1, "test/happy_11_SUITE"),
+ Happy1Cfg = filename:join(Happy1, "cfg/config1.cfg"),
+
+ Opts0 = ct_test_support:get_opts(Config),
+ Opts = eh_opts(Config) ++ Opts0 ++ [{config,Happy1Cfg}, {suite,Suite},
+ {testcase,[tc1,tc2]}],
+
+ ERPid = ct_test_support:start_event_receiver(Config),
+
+ ok = ct_test_support:run(ct, run_test, [Opts], Config),
+
+ Events = ct_test_support:get_events(ERPid, Config),
+
+ ct_test_support:log_events(tc111_112,
+ ct_test_support:reformat(Events, ?eh),
+ ?config(priv_dir, Config)),
+
+ TestEvents = test_events(tc111_112),
+ ok = ct_test_support:verify_events(TestEvents, Events, Config).
+
+
+%%%-----------------------------------------------------------------
+%%% HELP FUNCTIONS
+%%%-----------------------------------------------------------------
+
+eh_opts(Config) ->
+ Level = ?config(trace_level, Config),
+ [{event_handler,{?eh,[{cbm,ct_test_support},{trace_level,Level}]}}].
+
+
+test_events(Test) when Test == dir1 ; Test == dir2 ;
+ Test == suite11 ; Test == suite21 ->
+ Suite = if Test == dir1 ; Test == suite11 -> happy_11_SUITE;
+ true -> happy_21_SUITE
+ end,
+ [
+ {?eh,start_logging,{'DEF','RUNDIR'}},
+ {?eh,test_start,{'DEF',{'START_TIME','LOGDIR'}}},
+ {?eh,start_info,{1,1,8}},
+ {?eh,tc_start,{Suite,init_per_suite}},
+ {?eh,tc_done,{Suite,init_per_suite,ok}},
+ {?eh,tc_start,{Suite,tc1}},
+ {?eh,tc_done,{Suite,tc1,ok}},
+ {?eh,test_stats,{1,0,{0,0}}},
+ {?eh,tc_start,{Suite,tc2}},
+ {?eh,tc_done,{Suite,tc2,ok}},
+ {?eh,test_stats,{2,0,{0,0}}},
+ {?eh,tc_start,{Suite,seq1_tc1}},
+ {?eh,tc_done,{Suite,seq1_tc1,ok}},
+ {?eh,test_stats,{3,0,{0,0}}},
+ {?eh,tc_start,{Suite,seq1_tc2}},
+ {?eh,tc_done,{Suite,seq1_tc2,ok}},
+ {?eh,test_stats,{4,0,{0,0}}},
+ {?eh,tc_start,{Suite,tc3}},
+ {?eh,tc_done,{Suite,tc3,ok}},
+ {?eh,test_stats,{5,0,{0,0}}},
+ {?eh,tc_start,{Suite,seq2_tc1}},
+ {?eh,tc_done,{Suite,seq2_tc1,ok}},
+ {?eh,test_stats,{6,0,{0,0}}},
+ {?eh,tc_start,{Suite,seq2_tc2}},
+ {?eh,tc_done,{Suite,seq2_tc2,ok}},
+ {?eh,test_stats,{7,0,{0,0}}},
+ {?eh,tc_start,{Suite,tc4}},
+ {?eh,tc_done,
+ {Suite,tc4,{skipped,"Skipping this one"}}},
+ {?eh,test_stats,{7,0,{1,0}}},
+ {?eh,tc_start,{Suite,end_per_suite}},
+ {?eh,tc_done,{Suite,end_per_suite,ips_data}},
+ {?eh,test_done,{'DEF','STOP_TIME'}},
+ {?eh,stop_logging,[]}
+ ];
+test_events(Test) when Test == dir1_2 ; Test == suite11_21 ->
+ [
+ {?eh,start_logging,{'DEF','RUNDIR'}},
+ {?eh,test_start,{'DEF',{'START_TIME','LOGDIR'}}},
+ {?eh,start_info,{2,2,16}},
+ {?eh,tc_start,{happy_11_SUITE,init_per_suite}},
+ {?eh,tc_done,{happy_11_SUITE,init_per_suite,ok}},
+ {?eh,tc_start,{happy_11_SUITE,tc1}},
+ {?eh,tc_done,{happy_11_SUITE,tc1,ok}},
+ {?eh,test_stats,{1,0,{0,0}}},
+ {?eh,tc_start,{happy_11_SUITE,tc2}},
+ {?eh,tc_done,{happy_11_SUITE,tc2,ok}},
+ {?eh,test_stats,{2,0,{0,0}}},
+ {?eh,tc_start,{happy_11_SUITE,seq1_tc1}},
+ {?eh,tc_done,{happy_11_SUITE,seq1_tc1,ok}},
+ {?eh,test_stats,{3,0,{0,0}}},
+ {?eh,tc_start,{happy_11_SUITE,seq1_tc2}},
+ {?eh,tc_done,{happy_11_SUITE,seq1_tc2,ok}},
+ {?eh,test_stats,{4,0,{0,0}}},
+ {?eh,tc_start,{happy_11_SUITE,tc3}},
+ {?eh,tc_done,{happy_11_SUITE,tc3,ok}},
+ {?eh,test_stats,{5,0,{0,0}}},
+ {?eh,tc_start,{happy_11_SUITE,seq2_tc1}},
+ {?eh,tc_done,{happy_11_SUITE,seq2_tc1,ok}},
+ {?eh,test_stats,{6,0,{0,0}}},
+ {?eh,tc_start,{happy_11_SUITE,seq2_tc2}},
+ {?eh,tc_done,{happy_11_SUITE,seq2_tc2,ok}},
+ {?eh,test_stats,{7,0,{0,0}}},
+ {?eh,tc_start,{happy_11_SUITE,tc4}},
+ {?eh,tc_done,
+ {happy_11_SUITE,tc4,{skipped,"Skipping this one"}}},
+ {?eh,test_stats,{7,0,{1,0}}},
+ {?eh,tc_start,{happy_11_SUITE,end_per_suite}},
+ {?eh,tc_done,{happy_11_SUITE,end_per_suite,ips_data}},
+ {?eh,tc_start,{happy_21_SUITE,init_per_suite}},
+ {?eh,tc_done,{happy_21_SUITE,init_per_suite,ok}},
+ {?eh,tc_start,{happy_21_SUITE,tc1}},
+ {?eh,tc_done,{happy_21_SUITE,tc1,ok}},
+ {?eh,test_stats,{8,0,{1,0}}},
+ {?eh,tc_start,{happy_21_SUITE,tc2}},
+ {?eh,tc_done,{happy_21_SUITE,tc2,ok}},
+ {?eh,test_stats,{9,0,{1,0}}},
+ {?eh,tc_start,{happy_21_SUITE,seq1_tc1}},
+ {?eh,tc_done,{happy_21_SUITE,seq1_tc1,ok}},
+ {?eh,test_stats,{10,0,{1,0}}},
+ {?eh,tc_start,{happy_21_SUITE,seq1_tc2}},
+ {?eh,tc_done,{happy_21_SUITE,seq1_tc2,ok}},
+ {?eh,test_stats,{11,0,{1,0}}},
+ {?eh,tc_start,{happy_21_SUITE,tc3}},
+ {?eh,tc_done,{happy_21_SUITE,tc3,ok}},
+ {?eh,test_stats,{12,0,{1,0}}},
+ {?eh,tc_start,{happy_21_SUITE,seq2_tc1}},
+ {?eh,tc_done,{happy_21_SUITE,seq2_tc1,ok}},
+ {?eh,test_stats,{13,0,{1,0}}},
+ {?eh,tc_start,{happy_21_SUITE,seq2_tc2}},
+ {?eh,tc_done,{happy_21_SUITE,seq2_tc2,ok}},
+ {?eh,test_stats,{14,0,{1,0}}},
+ {?eh,tc_start,{happy_21_SUITE,tc4}},
+ {?eh,tc_done,
+ {happy_21_SUITE,tc4,{skipped,"Skipping this one"}}},
+ {?eh,test_stats,{14,0,{2,0}}},
+ {?eh,tc_start,{happy_21_SUITE,end_per_suite}},
+ {?eh,tc_done,{happy_21_SUITE,end_per_suite,ips_data}},
+ {?eh,test_done,{'DEF','STOP_TIME'}},
+ {?eh,stop_logging,[]}
+ ];
+
+test_events(Test) when Test == tc111 ; Test == tc211 ->
+ Suite = if Test == tc111 -> happy_11_SUITE; true -> happy_21_SUITE end,
+ [
+ {?eh,start_logging,{'DEF','RUNDIR'}},
+ {?eh,test_start,{'DEF',{'START_TIME','LOGDIR'}}},
+ {?eh,start_info,{1,1,1}},
+ {?eh,tc_start,{Suite,init_per_suite}},
+ {?eh,tc_done,{Suite,init_per_suite,ok}},
+ {?eh,tc_start,{Suite,tc1}},
+ {?eh,tc_done,{Suite,tc1,ok}},
+ {?eh,test_stats,{1,0,{0,0}}},
+ {?eh,tc_start,{Suite,end_per_suite}},
+ {?eh,tc_done,{Suite,end_per_suite,ips_data}},
+ {?eh,test_done,{'DEF','STOP_TIME'}},
+ {?eh,stop_logging,[]}
+ ];
+
+test_events(tc111_112) ->
+ [
+ {?eh,start_logging,{'DEF','RUNDIR'}},
+ {?eh,test_start,{'DEF',{'START_TIME','LOGDIR'}}},
+ {?eh,start_info,{1,1,2}},
+ {?eh,tc_start,{happy_11_SUITE,init_per_suite}},
+ {?eh,tc_done,{happy_11_SUITE,init_per_suite,ok}},
+ {?eh,tc_start,{happy_11_SUITE,tc1}},
+ {?eh,tc_done,{happy_11_SUITE,tc1,ok}},
+ {?eh,test_stats,{1,0,{0,0}}},
+ {?eh,tc_start,{happy_11_SUITE,tc2}},
+ {?eh,tc_done,{happy_11_SUITE,tc2,ok}},
+ {?eh,test_stats,{2,0,{0,0}}},
+ {?eh,tc_start,{happy_11_SUITE,end_per_suite}},
+ {?eh,tc_done,{happy_11_SUITE,end_per_suite,ips_data}},
+ {?eh,test_done,{'DEF','STOP_TIME'}},
+ {?eh,stop_logging,[]}
+ ].
diff --git a/lib/common_test/test/ct_smoke_test_SUITE_data/happy_1/cfg/config1.cfg b/lib/common_test/test/ct_smoke_test_SUITE_data/happy_1/cfg/config1.cfg
new file mode 100644
index 0000000000..3d6e5622f5
--- /dev/null
+++ b/lib/common_test/test/ct_smoke_test_SUITE_data/happy_1/cfg/config1.cfg
@@ -0,0 +1,5 @@
+{v1, apple}.
+{v2, plum}.
+{v3, [{v31, cherry},
+ {v32, banana},
+ {v33, coconut}]}.
diff --git a/lib/common_test/test/ct_smoke_test_SUITE_data/happy_1/test/happy_11_SUITE.erl b/lib/common_test/test/ct_smoke_test_SUITE_data/happy_1/test/happy_11_SUITE.erl
new file mode 100644
index 0000000000..f33f0934cb
--- /dev/null
+++ b/lib/common_test/test/ct_smoke_test_SUITE_data/happy_1/test/happy_11_SUITE.erl
@@ -0,0 +1,196 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 2008-2010. All Rights Reserved.
+%%
+%% The contents of this file are subject to the Erlang Public License,
+%% Version 1.1, (the "License"); you may not use this file except in
+%% compliance with the License. You should have received a copy of the
+%% Erlang Public License along with this software. If not, it can be
+%% retrieved online at http://www.erlang.org/.
+%%
+%% Software distributed under the License is distributed on an "AS IS"
+%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+%% the License for the specific language governing rights and limitations
+%% under the License.
+%%
+%% %CopyrightEnd%
+%%
+
+%%%-------------------------------------------------------------------
+%%% File : happy_11_SUITE.erl
+%%% Description : Happy test of all common_test callback functions.
+%%%-------------------------------------------------------------------
+-module(happy_11_SUITE).
+
+%% Note: This directive should only be used in test suites.
+-compile(export_all).
+
+-include_lib("common_test/include/ct.hrl").
+
+%%--------------------------------------------------------------------
+%% COMMON TEST CALLBACK FUNCTIONS
+%%--------------------------------------------------------------------
+
+%%--------------------------------------------------------------------
+%% Function: suite() -> Info
+%%
+%% Info = [tuple()]
+%% List of key/value pairs.
+%%
+%% Description: Returns list of tuples to set default properties
+%% for the suite.
+%%
+%% Note: The suite/0 function is only meant to be used to return
+%% default data values, not perform any other operations.
+%%--------------------------------------------------------------------
+suite() ->
+ [
+ {timetrap,{seconds,10}},
+ {require, v1},
+ {userdata, {info,"Happy test of CT callback functions."}}
+ ].
+
+%%--------------------------------------------------------------------
+%% Function: init_per_suite(Config0) ->
+%% Config1 | {skip,Reason} | {skip_and_save,Reason,Config1}
+%%
+%% Config0 = Config1 = [tuple()]
+%% A list of key/value pairs, holding the test case configuration.
+%% Reason = term()
+%% The reason for skipping the suite.
+%%
+%% Description: Initialization before the 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) ->
+ [{ips,ips_data} | Config].
+
+%%--------------------------------------------------------------------
+%% Function: end_per_suite(Config0) -> void() | {save_config,Config1}
+%%
+%% Config0 = Config1 = [tuple()]
+%% A list of key/value pairs, holding the test case configuration.
+%%
+%% Description: Cleanup after the suite.
+%%--------------------------------------------------------------------
+end_per_suite(Config) ->
+ ips_data = ?config(ips, Config).
+
+%%--------------------------------------------------------------------
+%% Function: init_per_testcase(TestCase, Config0) ->
+%% Config1 | {skip,Reason} | {skip_and_save,Reason,Config1}
+%%
+%% TestCase = atom()
+%% Name of the test case that is about to run.
+%% Config0 = Config1 = [tuple()]
+%% A list of key/value pairs, holding the test case configuration.
+%% Reason = term()
+%% The reason for skipping the test case.
+%%
+%% 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.
+%%--------------------------------------------------------------------
+init_per_testcase(TestCase, Config) ->
+ [{TestCase,{TestCase,data}} | Config].
+
+%%--------------------------------------------------------------------
+%% Function: end_per_testcase(TestCase, Config0) ->
+%% void() | {save_config,Config1}
+%%
+%% TestCase = atom()
+%% Name of the test case that is finished.
+%% Config0 = Config1 = [tuple()]
+%% A list of key/value pairs, holding the test case configuration.
+%%
+%% Description: Cleanup after each test case.
+%%--------------------------------------------------------------------
+end_per_testcase(TestCase, Config) ->
+ {TestCase,data} = ?config(TestCase, Config).
+
+%%--------------------------------------------------------------------
+%% Function: sequences() -> Sequences
+%%
+%% Sequences = [{SeqName,TestCases}]
+%% SeqName = atom()
+%% Name of a sequence.
+%% TestCases = [atom()]
+%% List of test cases that are part of the sequence
+%%
+%% Description: Specifies test case sequences.
+%%--------------------------------------------------------------------
+sequences() ->
+ [{seq1,[seq1_tc1, seq1_tc2]},
+ {seq2,[seq2_tc1, seq2_tc2]}].
+
+%%--------------------------------------------------------------------
+%% Function: all() -> TestCases | {skip,Reason}
+%%
+%% TestCases = [TestCase | {sequence,SeqName}]
+%% TestCase = atom()
+%% Name of a test case.
+%% SeqName = atom()
+%% Name of a test case sequence.
+%% Reason = term()
+%% The reason for skipping all test cases.
+%%
+%% Description: Returns the list of test cases that are to be executed.
+%%--------------------------------------------------------------------
+all() ->
+ [tc1,
+ tc2,
+ seq1,
+ tc3,
+ seq2,
+ tc4].
+
+
+%%--------------------------------------------------------------------
+%% TEST CASES
+%%--------------------------------------------------------------------
+
+tc1() ->
+ [{userdata,{info, "This is a testcase"}}].
+
+tc1(Config) ->
+ ips_data = ?config(ips, Config),
+ {tc1,data} = ?config(tc1, Config),
+ apple = ct:get_config(v1),
+ ok.
+
+tc2() ->
+ [{timetrap,5000},
+ {require,v2}].
+
+tc2(Config) ->
+ ips_data = ?config(ips, Config),
+ undefined = ?config(tc1, Config),
+ {tc2,data} = ?config(tc2, Config),
+ plum = ct:get_config(v2),
+ ok.
+
+tc3() ->
+ [{timetrap,{minutes,1}}].
+
+tc3(_Config) ->
+ ok = ct:require(v3),
+ [{v31, cherry},{v32, banana},{v33, coconut}] = ct:get_config(v3),
+ banana = ct:get_config({v3,v32}),
+ ok.
+
+tc4(Config) ->
+ {skip,"Skipping this one"}.
+
+seq1_tc1(_) ->
+ ok.
+seq1_tc2(_) ->
+ ok.
+
+seq2_tc1(_) ->
+ ok.
+seq2_tc2(_) ->
+ ok.
diff --git a/lib/common_test/test/ct_smoke_test_SUITE_data/happy_2_cfg/config1.cfg b/lib/common_test/test/ct_smoke_test_SUITE_data/happy_2_cfg/config1.cfg
new file mode 100644
index 0000000000..3d6e5622f5
--- /dev/null
+++ b/lib/common_test/test/ct_smoke_test_SUITE_data/happy_2_cfg/config1.cfg
@@ -0,0 +1,5 @@
+{v1, apple}.
+{v2, plum}.
+{v3, [{v31, cherry},
+ {v32, banana},
+ {v33, coconut}]}.
diff --git a/lib/common_test/test/ct_smoke_test_SUITE_data/happy_2_test/happy_21_SUITE.erl b/lib/common_test/test/ct_smoke_test_SUITE_data/happy_2_test/happy_21_SUITE.erl
new file mode 100644
index 0000000000..33d18006f9
--- /dev/null
+++ b/lib/common_test/test/ct_smoke_test_SUITE_data/happy_2_test/happy_21_SUITE.erl
@@ -0,0 +1,196 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 2008-2010. All Rights Reserved.
+%%
+%% The contents of this file are subject to the Erlang Public License,
+%% Version 1.1, (the "License"); you may not use this file except in
+%% compliance with the License. You should have received a copy of the
+%% Erlang Public License along with this software. If not, it can be
+%% retrieved online at http://www.erlang.org/.
+%%
+%% Software distributed under the License is distributed on an "AS IS"
+%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+%% the License for the specific language governing rights and limitations
+%% under the License.
+%%
+%% %CopyrightEnd%
+%%
+
+%%%-------------------------------------------------------------------
+%%% File : happy_21_SUITE.erl
+%%% Description : Happy test of all common_test callback functions.
+%%%-------------------------------------------------------------------
+-module(happy_21_SUITE).
+
+%% Note: This directive should only be used in test suites.
+-compile(export_all).
+
+-include_lib("common_test/include/ct.hrl").
+
+%%--------------------------------------------------------------------
+%% COMMON TEST CALLBACK FUNCTIONS
+%%--------------------------------------------------------------------
+
+%%--------------------------------------------------------------------
+%% Function: suite() -> Info
+%%
+%% Info = [tuple()]
+%% List of key/value pairs.
+%%
+%% Description: Returns list of tuples to set default properties
+%% for the suite.
+%%
+%% Note: The suite/0 function is only meant to be used to return
+%% default data values, not perform any other operations.
+%%--------------------------------------------------------------------
+suite() ->
+ [
+ {timetrap,{seconds,10}},
+ {require, v1},
+ {userdata, {info,"Happy test of CT callback functions."}}
+ ].
+
+%%--------------------------------------------------------------------
+%% Function: init_per_suite(Config0) ->
+%% Config1 | {skip,Reason} | {skip_and_save,Reason,Config1}
+%%
+%% Config0 = Config1 = [tuple()]
+%% A list of key/value pairs, holding the test case configuration.
+%% Reason = term()
+%% The reason for skipping the suite.
+%%
+%% Description: Initialization before the 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) ->
+ [{ips,ips_data} | Config].
+
+%%--------------------------------------------------------------------
+%% Function: end_per_suite(Config0) -> void() | {save_config,Config1}
+%%
+%% Config0 = Config1 = [tuple()]
+%% A list of key/value pairs, holding the test case configuration.
+%%
+%% Description: Cleanup after the suite.
+%%--------------------------------------------------------------------
+end_per_suite(Config) ->
+ ips_data = ?config(ips, Config).
+
+%%--------------------------------------------------------------------
+%% Function: init_per_testcase(TestCase, Config0) ->
+%% Config1 | {skip,Reason} | {skip_and_save,Reason,Config1}
+%%
+%% TestCase = atom()
+%% Name of the test case that is about to run.
+%% Config0 = Config1 = [tuple()]
+%% A list of key/value pairs, holding the test case configuration.
+%% Reason = term()
+%% The reason for skipping the test case.
+%%
+%% 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.
+%%--------------------------------------------------------------------
+init_per_testcase(TestCase, Config) ->
+ [{TestCase,{TestCase,data}} | Config].
+
+%%--------------------------------------------------------------------
+%% Function: end_per_testcase(TestCase, Config0) ->
+%% void() | {save_config,Config1}
+%%
+%% TestCase = atom()
+%% Name of the test case that is finished.
+%% Config0 = Config1 = [tuple()]
+%% A list of key/value pairs, holding the test case configuration.
+%%
+%% Description: Cleanup after each test case.
+%%--------------------------------------------------------------------
+end_per_testcase(TestCase, Config) ->
+ {TestCase,data} = ?config(TestCase, Config).
+
+%%--------------------------------------------------------------------
+%% Function: sequences() -> Sequences
+%%
+%% Sequences = [{SeqName,TestCases}]
+%% SeqName = atom()
+%% Name of a sequence.
+%% TestCases = [atom()]
+%% List of test cases that are part of the sequence
+%%
+%% Description: Specifies test case sequences.
+%%--------------------------------------------------------------------
+sequences() ->
+ [{seq1,[seq1_tc1, seq1_tc2]},
+ {seq2,[seq2_tc1, seq2_tc2]}].
+
+%%--------------------------------------------------------------------
+%% Function: all() -> TestCases | {skip,Reason}
+%%
+%% TestCases = [TestCase | {sequence,SeqName}]
+%% TestCase = atom()
+%% Name of a test case.
+%% SeqName = atom()
+%% Name of a test case sequence.
+%% Reason = term()
+%% The reason for skipping all test cases.
+%%
+%% Description: Returns the list of test cases that are to be executed.
+%%--------------------------------------------------------------------
+all() ->
+ [tc1,
+ tc2,
+ seq1,
+ tc3,
+ seq2,
+ tc4].
+
+
+%%--------------------------------------------------------------------
+%% TEST CASES
+%%--------------------------------------------------------------------
+
+tc1() ->
+ [{userdata,{info, "This is a testcase"}}].
+
+tc1(Config) ->
+ ips_data = ?config(ips, Config),
+ {tc1,data} = ?config(tc1, Config),
+ apple = ct:get_config(v1),
+ ok.
+
+tc2() ->
+ [{timetrap,5000},
+ {require,v2}].
+
+tc2(Config) ->
+ ips_data = ?config(ips, Config),
+ undefined = ?config(tc1, Config),
+ {tc2,data} = ?config(tc2, Config),
+ plum = ct:get_config(v2),
+ ok.
+
+tc3() ->
+ [{timetrap,{minutes,1}}].
+
+tc3(_Config) ->
+ ok = ct:require(v3),
+ [{v31, cherry},{v32, banana},{v33, coconut}] = ct:get_config(v3),
+ banana = ct:get_config({v3,v32}),
+ ok.
+
+tc4(Config) ->
+ {skip,"Skipping this one"}.
+
+seq1_tc1(_) ->
+ ok.
+seq1_tc2(_) ->
+ ok.
+
+seq2_tc1(_) ->
+ ok.
+seq2_tc2(_) ->
+ ok.
diff --git a/lib/common_test/test/ct_test_server_if_1_SUITE.erl b/lib/common_test/test/ct_test_server_if_1_SUITE.erl
new file mode 100644
index 0000000000..069f8c75fc
--- /dev/null
+++ b/lib/common_test/test/ct_test_server_if_1_SUITE.erl
@@ -0,0 +1,253 @@
+%%
+%% %CopyrightBegin%
+%%
+%% 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%
+%%
+
+%%%-------------------------------------------------------------------
+%%% File: ct_test_server_if_SUITE
+%%%
+%%% Description:
+%%% Test the test_server -> framework interface.
+%%%
+%%% The suites used for the test are located in the data directory.
+%%%-------------------------------------------------------------------
+-module(ct_test_server_if_1_SUITE).
+
+-compile(export_all).
+
+-include_lib("test_server/include/test_server.hrl").
+-include_lib("common_test/include/ct_event.hrl").
+
+-define(eh, ct_test_support_eh).
+
+%%--------------------------------------------------------------------
+%% TEST SERVER CALLBACK FUNCTIONS
+%%--------------------------------------------------------------------
+
+%%--------------------------------------------------------------------
+%% Description: Since Common Test starts another Test Server
+%% instance, the tests need to be performed on a separate node (or
+%% there will be clashes with logging processes etc).
+%%--------------------------------------------------------------------
+init_per_suite(Config) ->
+ Config1 = ct_test_support:init_per_suite(Config),
+ Config1.
+
+end_per_suite(Config) ->
+ ct_test_support:end_per_suite(Config).
+
+init_per_testcase(TestCase, Config) ->
+ ct_test_support:init_per_testcase(TestCase, Config).
+
+end_per_testcase(TestCase, Config) ->
+ ct_test_support:end_per_testcase(TestCase, Config).
+
+all(doc) ->
+ [""];
+
+all(suite) ->
+ [
+ ts_if_1
+ ].
+
+
+%%--------------------------------------------------------------------
+%% TEST CASES
+%%--------------------------------------------------------------------
+
+%%%-----------------------------------------------------------------
+%%%
+ts_if_1(Config) when is_list(Config) ->
+ DataDir = ?config(data_dir, Config),
+ PrivDir = ?config(priv_dir, Config),
+ TODir = filename:join(DataDir, "test_server_if"),
+ Level = ?config(trace_level, Config),
+ TestSpec = [
+ {event_handler,?eh,[{cbm,ct_test_support},{trace_level,Level}]},
+ {suites,TODir,[ts_if_1_SUITE,ts_if_2_SUITE,ts_if_3_SUITE,
+ ts_if_4_SUITE,ts_if_5_SUITE,ts_if_6_SUITE,
+ ts_if_7_SUITE,ts_if_8_SUITE]},
+ {skip_suites,TODir,[skipped_by_spec_1_SUITE],"should be skipped"},
+ {skip_cases,TODir,skipped_by_spec_2_SUITE,[tc1],"should be skipped"}
+ ],
+
+ TestSpecName = ct_test_support:write_testspec(TestSpec, PrivDir, "ts_if_1_spec"),
+ {Opts,ERPid} = setup({spec,TestSpecName}, Config),
+ ok = ct_test_support:run(ct, run_test, [Opts], Config),
+ Events = ct_test_support:get_events(ERPid, Config),
+
+ ct_test_support:log_events(ts_if_1,
+ reformat(Events, ?eh),
+ PrivDir),
+
+ TestEvents = test_events(ts_if_1),
+ ok = ct_test_support:verify_events(TestEvents, Events, Config).
+
+
+%%%-----------------------------------------------------------------
+%%% HELP FUNCTIONS
+%%%-----------------------------------------------------------------
+
+setup(Test, Config) ->
+ Opts0 = ct_test_support:get_opts(Config),
+% Level = ?config(trace_level, Config),
+% EvHArgs = [{cbm,ct_test_support},{trace_level,Level}],
+% Opts = Opts0 ++ [Test,{event_handler,{?eh,EvHArgs}}],
+ Opts = [Test | Opts0],
+ ERPid = ct_test_support:start_event_receiver(Config),
+ {Opts,ERPid}.
+
+reformat(Events, EH) ->
+ ct_test_support:reformat(Events, EH).
+%reformat(Events, _EH) ->
+% Events.
+
+%%%-----------------------------------------------------------------
+%%% TEST EVENTS
+%%%-----------------------------------------------------------------
+test_events(ts_if_1) ->
+ [
+ {?eh,start_logging,{'DEF','RUNDIR'}},
+ {?eh,test_start,{'DEF',{'START_TIME','LOGDIR'}}},
+ {?eh,start_info,{10,6,26}},
+ {?eh,tc_start,{ts_if_1_SUITE,init_per_suite}},
+ {?eh,tc_done,{ts_if_1_SUITE,init_per_suite,ok}},
+ {?eh,tc_start,{ts_if_1_SUITE,tc1}},
+ {?eh,tc_done,{ts_if_1_SUITE,tc1,{skipped,
+ {failed,
+ {ts_if_1_SUITE,init_per_testcase,
+ {timetrap_timeout,2000}}}}}},
+ {?eh,test_stats,{0,0,{0,1}}},
+ {?eh,tc_start,{ts_if_1_SUITE,tc2}},
+ {?eh,tc_done,{ts_if_1_SUITE,tc2,
+ {failed,{ts_if_1_SUITE,end_per_testcase,{timetrap_timeout,2000}}}}},
+ {?eh,test_stats,{1,0,{0,1}}},
+ {?eh,tc_start,{ts_if_1_SUITE,tc3}},
+ {?eh,tc_done,{ts_if_1_SUITE,tc3,{failed,{timetrap_timeout,2000}}}},
+ {?eh,test_stats,{1,1,{0,1}}},
+ {?eh,tc_start,{ts_if_1_SUITE,tc4}},
+ {?eh,tc_done,{ts_if_1_SUITE,tc4,{failed,{error,failed_on_purpose}}}},
+ {?eh,test_stats,{1,2,{0,1}}},
+ {?eh,tc_done,{ts_if_1_SUITE,tc5,{skipped,{sequence_failed,seq1,tc4}}}},
+ {?eh,test_stats,{1,2,{1,1}}},
+
+ [{?eh,tc_start,{ts_if_1_SUITE,{init_per_group,seq2,[sequence]}}},
+ {?eh,tc_done,{ts_if_1_SUITE,{init_per_group,seq2,[sequence]},ok}},
+ {?eh,tc_start,{ts_if_1_SUITE,tc4}},
+ {?eh,tc_done,{ts_if_1_SUITE,tc4,{failed,{error,failed_on_purpose}}}},
+ {?eh,test_stats,{1,3,{1,1}}},
+ {?eh,tc_auto_skip,{ts_if_1_SUITE,tc5,{failed,{ts_if_1_SUITE,tc4}}}},
+ {?eh,test_stats,{1,3,{1,2}}},
+ {?eh,tc_start,{ts_if_1_SUITE,{end_per_group,seq2,[sequence]}}},
+ {?eh,tc_done,{ts_if_1_SUITE,{end_per_group,seq2,[sequence]},ok}}],
+
+ {?eh,tc_start,{ts_if_1_SUITE,tc6}},
+ {?eh,tc_done,{ts_if_1_SUITE,tc6,{skipped,{require_failed,{not_available,void}}}}},
+ {?eh,test_stats,{1,3,{1,3}}},
+ {?eh,tc_start,{ts_if_1_SUITE,tc7}},
+ {?eh,tc_done,{ts_if_1_SUITE,tc7,ok}},
+ {?eh,test_stats,{2,3,{1,3}}},
+ {?eh,tc_start,{ts_if_1_SUITE,tc8}},
+ {?eh,tc_done,{ts_if_1_SUITE,tc8,{skipped,"tc8 skipped"}}},
+ {?eh,test_stats,{2,3,{2,3}}},
+ {?eh,tc_start,{ts_if_1_SUITE,tc9}},
+ {?eh,tc_done,{ts_if_1_SUITE,tc9,{skipped,'tc9 skipped'}}},
+ {?eh,test_stats,{2,3,{3,3}}},
+ {?eh,tc_start,{ts_if_1_SUITE,tc10}},
+ {?eh,tc_done,{ts_if_1_SUITE,tc10,{failed,{error,{function_clause,'_'}}}}},
+ {?eh,test_stats,{2,4,{3,3}}},
+ {?eh,tc_start,{ts_if_1_SUITE,tc11}},
+ {?eh,tc_done,{ts_if_1_SUITE,tc11,
+ {skipped,{failed,{ts_if_1_SUITE,init_per_testcase,bad_return}}}}},
+ {?eh,test_stats,{2,4,{3,4}}},
+
+ [{?eh,tc_start,{ts_if_1_SUITE,{init_per_group,g1,[]}}},
+ {?eh,tc_done,{ts_if_1_SUITE,{init_per_group,g1,[]},{skipped,g1_got_skipped}}},
+ {?eh,tc_auto_skip,{ts_if_1_SUITE,gtc1,g1_got_skipped}},
+ {?eh,test_stats,{2,4,{3,5}}},
+ {?eh,tc_auto_skip,{ts_if_1_SUITE,end_per_group,g1_got_skipped}}],
+
+ {parallel,
+ [{?eh,tc_start,{ts_if_1_SUITE,{init_per_group,g2,[parallel]}}},
+ {?eh,tc_done,{ts_if_1_SUITE,{init_per_group,g2,[parallel]},ok}},
+ [{?eh,tc_start,{ts_if_1_SUITE,{init_per_group,g3,[]}}},
+ {?eh,tc_done,{ts_if_1_SUITE,{init_per_group,g3,[]},{skipped,g3_got_skipped}}},
+ {?eh,tc_auto_skip,{ts_if_1_SUITE,gtc2,g3_got_skipped}},
+ {?eh,test_stats,{2,4,{3,6}}},
+ {?eh,tc_auto_skip,{ts_if_1_SUITE,end_per_group,g3_got_skipped}}],
+ {?eh,tc_start,{ts_if_1_SUITE,{end_per_group,g2,[parallel]}}},
+ {?eh,tc_done,{ts_if_1_SUITE,{end_per_group,g2,[parallel]},ok}}]},
+
+ {?eh,tc_start,{ts_if_1_SUITE,tc12}},
+ {?eh,tc_done,{undefined,undefined,{testcase_aborted,{abort_current_testcase,tc12},'_'}}},
+ {?eh,test_stats,{2,5,{3,6}}},
+ {?eh,tc_start,{ts_if_1_SUITE,tc13}},
+ {?eh,tc_done,{ts_if_1_SUITE,tc13,ok}},
+ {?eh,test_stats,{3,5,{3,6}}},
+ {?eh,tc_start,{ts_if_1_SUITE,end_per_suite}},
+ {?eh,tc_done,{ts_if_1_SUITE,end_per_suite,ok}},
+%%!
+ {?eh,tc_start,{ts_if_2_SUITE,init_per_suite}},
+ {?eh,tc_done,{ts_if_2_SUITE,init_per_suite,
+ {failed,{error,{suite0_failed,{exited,suite0_goes_boom}}}}}},
+ {?eh,tc_auto_skip,{ts_if_2_SUITE,my_test_case,
+ {failed,{error,{suite0_failed,{exited,suite0_goes_boom}}}}}},
+ {?eh,test_stats,{3,5,{3,7}}},
+ {?eh,tc_auto_skip,{ts_if_2_SUITE,end_per_suite,
+ {failed,{error,{suite0_failed,{exited,suite0_goes_boom}}}}}},
+
+ {?eh,tc_start,{ct_framework,error_in_suite}},
+ {?eh,test_stats,{3,6,{3,7}}},
+
+ {?eh,tc_start,{ct_framework,error_in_suite}},
+ {?eh,test_stats,{3,7,{3,7}}},
+
+ {?eh,tc_start,{ts_if_5_SUITE,init_per_suite}},
+ {?eh,tc_done,{ts_if_5_SUITE,init_per_suite,
+ {skipped,{require_failed_in_suite0,{not_available,undef_variable}}}}},
+ {?eh,tc_auto_skip,{ts_if_5_SUITE,my_test_case,
+ {require_failed_in_suite0,{not_available,undef_variable}}}},
+ {?eh,test_stats,{3,7,{3,8}}},
+ {?eh,tc_auto_skip,{ts_if_5_SUITE,end_per_suite,
+ {require_failed_in_suite0,{not_available,undef_variable}}}},
+
+ {?eh,tc_start,{ts_if_6_SUITE,tc1}},
+ {?eh,tc_done,{ts_if_6_SUITE,tc1,{failed,{error,{suite0_failed,{exited,suite0_byebye}}}}}},
+ {?eh,test_stats,{3,7,{4,8}}},
+
+ {?eh,tc_start,{ts_if_7_SUITE,tc1}},
+ {?eh,tc_done,{ts_if_7_SUITE,tc1,ok}},
+ {?eh,test_stats,{4,7,{4,8}}},
+
+ {?eh,tc_start,{ts_if_8_SUITE,tc1}},
+ {?eh,tc_done,{ts_if_8_SUITE,tc1,{failed,{error,failed_on_purpose}}}},
+ {?eh,test_stats,{4,8,{4,8}}},
+
+ {?eh,tc_user_skip,{skipped_by_spec_1_SUITE,all,"should be skipped"}},
+ {?eh,test_stats,{4,8,{5,8}}},
+
+ {?eh,tc_start,{skipped_by_spec_2_SUITE,init_per_suite}},
+ {?eh,tc_done,{skipped_by_spec_2_SUITE,init_per_suite,ok}},
+ {?eh,tc_user_skip,{skipped_by_spec_2_SUITE,tc1,"should be skipped"}},
+ {?eh,test_stats,{4,8,{6,8}}},
+ {?eh,tc_start,{skipped_by_spec_2_SUITE,end_per_suite}},
+ {?eh,tc_done,{skipped_by_spec_2_SUITE,end_per_suite,ok}},
+
+ {?eh,test_done,{'DEF','STOP_TIME'}},
+ {?eh,stop_logging,[]}
+ ].
+
diff --git a/lib/common_test/test/ct_test_server_if_1_SUITE_data/test_server_if/test/skipped_by_spec_1_SUITE.erl b/lib/common_test/test/ct_test_server_if_1_SUITE_data/test_server_if/test/skipped_by_spec_1_SUITE.erl
new file mode 100644
index 0000000000..e77e304834
--- /dev/null
+++ b/lib/common_test/test/ct_test_server_if_1_SUITE_data/test_server_if/test/skipped_by_spec_1_SUITE.erl
@@ -0,0 +1,127 @@
+%%
+%% %CopyrightBegin%
+%%
+%% 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(skipped_by_spec_1_SUITE).
+
+-compile(export_all).
+
+-include_lib("common_test/include/ct.hrl").
+
+%%--------------------------------------------------------------------
+%% Function: suite() -> Info
+%% Info = [tuple()]
+%%--------------------------------------------------------------------
+suite() ->
+ [{timetrap,{seconds,30}}].
+
+%%--------------------------------------------------------------------
+%% Function: init_per_suite(Config0) ->
+%% Config1 | {skip,Reason} | {skip_and_save,Reason,Config1}
+%% Config0 = Config1 = [tuple()]
+%% Reason = term()
+%%--------------------------------------------------------------------
+init_per_suite(Config) ->
+ Config.
+
+%%--------------------------------------------------------------------
+%% Function: end_per_suite(Config0) -> void() | {save_config,Config1}
+%% Config0 = Config1 = [tuple()]
+%%--------------------------------------------------------------------
+end_per_suite(_Config) ->
+ ok.
+
+%%--------------------------------------------------------------------
+%% Function: init_per_group(GroupName, Config0) ->
+%% Config1 | {skip,Reason} | {skip_and_save,Reason,Config1}
+%% GroupName = atom()
+%% Config0 = Config1 = [tuple()]
+%% Reason = term()
+%%--------------------------------------------------------------------
+init_per_group(_GroupName, Config) ->
+ Config.
+
+%%--------------------------------------------------------------------
+%% Function: end_per_group(GroupName, Config0) ->
+%% void() | {save_config,Config1}
+%% GroupName = atom()
+%% Config0 = Config1 = [tuple()]
+%%--------------------------------------------------------------------
+end_per_group(_GroupName, _Config) ->
+ ok.
+
+%%--------------------------------------------------------------------
+%% Function: init_per_testcase(TestCase, Config0) ->
+%% Config1 | {skip,Reason} | {skip_and_save,Reason,Config1}
+%% TestCase = atom()
+%% Config0 = Config1 = [tuple()]
+%% Reason = term()
+%%--------------------------------------------------------------------
+init_per_testcase(_TestCase, Config) ->
+ Config.
+
+%%--------------------------------------------------------------------
+%% Function: end_per_testcase(TestCase, Config0) ->
+%% void() | {save_config,Config1}
+%% TestCase = atom()
+%% Config0 = Config1 = [tuple()]
+%%--------------------------------------------------------------------
+end_per_testcase(_TestCase, _Config) ->
+ ok.
+
+%%--------------------------------------------------------------------
+%% Function: groups() -> [Group]
+%% Group = {GroupName,Properties,GroupsAndTestCases}
+%% GroupName = atom()
+%% Properties = [parallel | sequence | Shuffle | {RepeatType,N}]
+%% GroupsAndTestCases = [Group | {group,GroupName} | TestCase]
+%% TestCase = atom()
+%% Shuffle = shuffle | {shuffle,{integer(),integer(),integer()}}
+%% RepeatType = repeat | repeat_until_all_ok | repeat_until_all_fail |
+%% repeat_until_any_ok | repeat_until_any_fail
+%% N = integer() | forever
+%%--------------------------------------------------------------------
+groups() ->
+ [].
+
+%%--------------------------------------------------------------------
+%% Function: all() -> GroupsAndTestCases | {skip,Reason}
+%% GroupsAndTestCases = [{group,GroupName} | TestCase]
+%% GroupName = atom()
+%% TestCase = atom()
+%% Reason = term()
+%%--------------------------------------------------------------------
+all() ->
+ [tc1].
+
+%%--------------------------------------------------------------------
+%% Function: TestCase() -> Info
+%% Info = [tuple()]
+%%--------------------------------------------------------------------
+tc1() ->
+ [].
+
+%%--------------------------------------------------------------------
+%% Function: TestCase(Config0) ->
+%% ok | exit() | {skip,Reason} | {comment,Comment} |
+%% {save_config,Config1} | {skip_and_save,Reason,Config1}
+%% Config0 = Config1 = [tuple()]
+%% Reason = term()
+%% Comment = term()
+%%--------------------------------------------------------------------
+tc1(_Config) ->
+ ok.
diff --git a/lib/common_test/test/ct_test_server_if_1_SUITE_data/test_server_if/test/skipped_by_spec_2_SUITE.erl b/lib/common_test/test/ct_test_server_if_1_SUITE_data/test_server_if/test/skipped_by_spec_2_SUITE.erl
new file mode 100644
index 0000000000..384182e778
--- /dev/null
+++ b/lib/common_test/test/ct_test_server_if_1_SUITE_data/test_server_if/test/skipped_by_spec_2_SUITE.erl
@@ -0,0 +1,127 @@
+%%
+%% %CopyrightBegin%
+%%
+%% 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(skipped_by_spec_2_SUITE).
+
+-compile(export_all).
+
+-include_lib("common_test/include/ct.hrl").
+
+%%--------------------------------------------------------------------
+%% Function: suite() -> Info
+%% Info = [tuple()]
+%%--------------------------------------------------------------------
+suite() ->
+ [{timetrap,{seconds,30}}].
+
+%%--------------------------------------------------------------------
+%% Function: init_per_suite(Config0) ->
+%% Config1 | {skip,Reason} | {skip_and_save,Reason,Config1}
+%% Config0 = Config1 = [tuple()]
+%% Reason = term()
+%%--------------------------------------------------------------------
+init_per_suite(Config) ->
+ Config.
+
+%%--------------------------------------------------------------------
+%% Function: end_per_suite(Config0) -> void() | {save_config,Config1}
+%% Config0 = Config1 = [tuple()]
+%%--------------------------------------------------------------------
+end_per_suite(_Config) ->
+ ok.
+
+%%--------------------------------------------------------------------
+%% Function: init_per_group(GroupName, Config0) ->
+%% Config1 | {skip,Reason} | {skip_and_save,Reason,Config1}
+%% GroupName = atom()
+%% Config0 = Config1 = [tuple()]
+%% Reason = term()
+%%--------------------------------------------------------------------
+init_per_group(_GroupName, Config) ->
+ Config.
+
+%%--------------------------------------------------------------------
+%% Function: end_per_group(GroupName, Config0) ->
+%% void() | {save_config,Config1}
+%% GroupName = atom()
+%% Config0 = Config1 = [tuple()]
+%%--------------------------------------------------------------------
+end_per_group(_GroupName, _Config) ->
+ ok.
+
+%%--------------------------------------------------------------------
+%% Function: init_per_testcase(TestCase, Config0) ->
+%% Config1 | {skip,Reason} | {skip_and_save,Reason,Config1}
+%% TestCase = atom()
+%% Config0 = Config1 = [tuple()]
+%% Reason = term()
+%%--------------------------------------------------------------------
+init_per_testcase(_TestCase, Config) ->
+ Config.
+
+%%--------------------------------------------------------------------
+%% Function: end_per_testcase(TestCase, Config0) ->
+%% void() | {save_config,Config1}
+%% TestCase = atom()
+%% Config0 = Config1 = [tuple()]
+%%--------------------------------------------------------------------
+end_per_testcase(_TestCase, _Config) ->
+ ok.
+
+%%--------------------------------------------------------------------
+%% Function: groups() -> [Group]
+%% Group = {GroupName,Properties,GroupsAndTestCases}
+%% GroupName = atom()
+%% Properties = [parallel | sequence | Shuffle | {RepeatType,N}]
+%% GroupsAndTestCases = [Group | {group,GroupName} | TestCase]
+%% TestCase = atom()
+%% Shuffle = shuffle | {shuffle,{integer(),integer(),integer()}}
+%% RepeatType = repeat | repeat_until_all_ok | repeat_until_all_fail |
+%% repeat_until_any_ok | repeat_until_any_fail
+%% N = integer() | forever
+%%--------------------------------------------------------------------
+groups() ->
+ [].
+
+%%--------------------------------------------------------------------
+%% Function: all() -> GroupsAndTestCases | {skip,Reason}
+%% GroupsAndTestCases = [{group,GroupName} | TestCase]
+%% GroupName = atom()
+%% TestCase = atom()
+%% Reason = term()
+%%--------------------------------------------------------------------
+all() ->
+ [tc1].
+
+%%--------------------------------------------------------------------
+%% Function: TestCase() -> Info
+%% Info = [tuple()]
+%%--------------------------------------------------------------------
+tc1() ->
+ [].
+
+%%--------------------------------------------------------------------
+%% Function: TestCase(Config0) ->
+%% ok | exit() | {skip,Reason} | {comment,Comment} |
+%% {save_config,Config1} | {skip_and_save,Reason,Config1}
+%% Config0 = Config1 = [tuple()]
+%% Reason = term()
+%% Comment = term()
+%%--------------------------------------------------------------------
+tc1(_Config) ->
+ ok.
diff --git a/lib/common_test/test/ct_test_server_if_1_SUITE_data/test_server_if/test/ts_if_1_SUITE.erl b/lib/common_test/test/ct_test_server_if_1_SUITE_data/test_server_if/test/ts_if_1_SUITE.erl
new file mode 100644
index 0000000000..8e90df21ce
--- /dev/null
+++ b/lib/common_test/test/ct_test_server_if_1_SUITE_data/test_server_if/test/ts_if_1_SUITE.erl
@@ -0,0 +1,191 @@
+%%
+%% %CopyrightBegin%
+%%
+%% 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(ts_if_1_SUITE).
+
+-compile(export_all).
+
+-include_lib("common_test/include/ct.hrl").
+
+%%--------------------------------------------------------------------
+%% Function: suite() -> Info
+%% Info = [tuple()]
+%%--------------------------------------------------------------------
+suite() ->
+ [{timetrap,{seconds,2}}].
+
+%%--------------------------------------------------------------------
+%% Function: init_per_suite(Config0) ->
+%% Config1 | {skip,Reason} | {skip_and_save,Reason,Config1}
+%% Config0 = Config1 = [tuple()]
+%% Reason = term()
+%%--------------------------------------------------------------------
+init_per_suite(Config) ->
+ Config.
+
+%%--------------------------------------------------------------------
+%% Function: end_per_suite(Config0) -> void() | {save_config,Config1}
+%% Config0 = Config1 = [tuple()]
+%%--------------------------------------------------------------------
+end_per_suite(_Config) ->
+ ok.
+
+%%--------------------------------------------------------------------
+%% Function: init_per_group(GroupName, Config0) ->
+%% Config1 | {skip,Reason} | {skip_and_save,Reason,Config1}
+%% GroupName = atom()
+%% Config0 = Config1 = [tuple()]
+%% Reason = term()
+%%--------------------------------------------------------------------
+init_per_group(g1, _Config) ->
+ {skip,g1_got_skipped};
+init_per_group(g3, _Config) ->
+ {skip,g3_got_skipped};
+init_per_group(_GroupName, Config) ->
+ Config.
+
+%%--------------------------------------------------------------------
+%% Function: end_per_group(GroupName, Config0) ->
+%% void() | {save_config,Config1}
+%% GroupName = atom()
+%% Config0 = Config1 = [tuple()]
+%%--------------------------------------------------------------------
+end_per_group(_GroupName, _Config) ->
+ ok.
+
+%%--------------------------------------------------------------------
+%% Function: init_per_testcase(TestCase, Config0) ->
+%% Config1 | {skip,Reason} | {skip_and_save,Reason,Config1}
+%% TestCase = atom()
+%% Config0 = Config1 = [tuple()]
+%% Reason = term()
+%%--------------------------------------------------------------------
+init_per_testcase(tc1, Config) ->
+ timer:sleep(5000),
+ Config;
+init_per_testcase(tc8, _Config) ->
+ {skip,"tc8 skipped"};
+init_per_testcase(tc11, Config) ->
+ bad_format;
+init_per_testcase(_TestCase, Config) ->
+ Config.
+
+%%--------------------------------------------------------------------
+%% Function: end_per_testcase(TestCase, Config0) ->
+%% void() | {save_config,Config1}
+%% TestCase = atom()
+%% Config0 = Config1 = [tuple()]
+%%--------------------------------------------------------------------
+end_per_testcase(tc2, Config) ->
+ timer:sleep(5000);
+end_per_testcase(_TestCase, _Config) ->
+ ok.
+
+%%--------------------------------------------------------------------
+%% Function: groups() -> [Group]
+%% Group = {GroupName,Properties,GroupsAndTestCases}
+%% GroupName = atom()
+%% Properties = [parallel | sequence | Shuffle | {RepeatType,N}]
+%% GroupsAndTestCases = [Group | {group,GroupName} | TestCase]
+%% TestCase = atom()
+%% Shuffle = shuffle | {shuffle,{integer(),integer(),integer()}}
+%% RepeatType = repeat | repeat_until_all_ok | repeat_until_all_fail |
+%% repeat_until_any_ok | repeat_until_any_fail
+%% N = integer() | forever
+%%--------------------------------------------------------------------
+groups() ->
+ [{g1,[],[gtc1]},
+ {g2,[parallel],[{g3,[],[gtc2]}]},
+
+ {seq2,[sequence],[tc4,tc5]}].
+
+sequences() ->
+ [{seq1,[tc4,tc5]}].
+
+%%--------------------------------------------------------------------
+%% Function: all() -> GroupsAndTestCases | {skip,Reason}
+%% GroupsAndTestCases = [{group,GroupName} | TestCase]
+%% GroupName = atom()
+%% TestCase = atom()
+%% Reason = term()
+%%--------------------------------------------------------------------
+all() ->
+ [tc1, tc2, tc3,
+ {sequence,seq1},
+ {group,seq2},
+ tc6, tc7,
+ tc8, tc9, tc10,
+ tc11,
+ {group,g1},
+ {group,g2},
+ tc12, tc13].
+
+tc1(_) ->
+ exit(should_have_been_skipped).
+
+tc2(_) ->
+ exit(should_have_been_skipped).
+
+tc3(_) ->
+ timer:sleep(5000).
+
+tc4(_) ->
+ exit(failed_on_purpose).
+
+tc5(_) ->
+ exit(should_have_been_skipped).
+
+tc6() ->
+ [{require,void}].
+tc6(_) ->
+ exit(should_have_been_skipped).
+
+tc7() ->
+ bad_format.
+tc7(_) ->
+ done.
+
+tc8(_) ->
+ exit(should_have_been_skipped).
+
+tc9(_) ->
+ {skip,'tc9 skipped'}.
+
+tc10(config) ->
+ done.
+
+tc11(_) ->
+ exit(should_have_been_skipped).
+
+
+gtc1(_) ->
+ exit(should_have_been_skipped).
+
+gtc2(_) ->
+ exit(should_have_been_skipped).
+
+tc12(_) ->
+ F = fun() -> ct:abort_current_testcase({abort_current_testcase,tc12}) end,
+ spawn(F),
+ timer:sleep(500),
+ exit(should_have_been_aborted).
+
+tc13(_) ->
+ success.
+
+
diff --git a/lib/common_test/test/ct_test_server_if_1_SUITE_data/test_server_if/test/ts_if_2_SUITE.erl b/lib/common_test/test/ct_test_server_if_1_SUITE_data/test_server_if/test/ts_if_2_SUITE.erl
new file mode 100644
index 0000000000..386b4402e6
--- /dev/null
+++ b/lib/common_test/test/ct_test_server_if_1_SUITE_data/test_server_if/test/ts_if_2_SUITE.erl
@@ -0,0 +1,127 @@
+%%
+%% %CopyrightBegin%
+%%
+%% 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(ts_if_2_SUITE).
+
+-compile(export_all).
+
+-include_lib("common_test/include/ct.hrl").
+
+%%--------------------------------------------------------------------
+%% Function: suite() -> Info
+%% Info = [tuple()]
+%%--------------------------------------------------------------------
+suite() ->
+ exit(suite0_goes_boom).
+
+%%--------------------------------------------------------------------
+%% Function: init_per_suite(Config0) ->
+%% Config1 | {skip,Reason} | {skip_and_save,Reason,Config1}
+%% Config0 = Config1 = [tuple()]
+%% Reason = term()
+%%--------------------------------------------------------------------
+init_per_suite(Config) ->
+ Config.
+
+%%--------------------------------------------------------------------
+%% Function: end_per_suite(Config0) -> void() | {save_config,Config1}
+%% Config0 = Config1 = [tuple()]
+%%--------------------------------------------------------------------
+end_per_suite(_Config) ->
+ ok.
+
+%%--------------------------------------------------------------------
+%% Function: init_per_group(GroupName, Config0) ->
+%% Config1 | {skip,Reason} | {skip_and_save,Reason,Config1}
+%% GroupName = atom()
+%% Config0 = Config1 = [tuple()]
+%% Reason = term()
+%%--------------------------------------------------------------------
+init_per_group(_GroupName, Config) ->
+ Config.
+
+%%--------------------------------------------------------------------
+%% Function: end_per_group(GroupName, Config0) ->
+%% void() | {save_config,Config1}
+%% GroupName = atom()
+%% Config0 = Config1 = [tuple()]
+%%--------------------------------------------------------------------
+end_per_group(_GroupName, _Config) ->
+ ok.
+
+%%--------------------------------------------------------------------
+%% Function: init_per_testcase(TestCase, Config0) ->
+%% Config1 | {skip,Reason} | {skip_and_save,Reason,Config1}
+%% TestCase = atom()
+%% Config0 = Config1 = [tuple()]
+%% Reason = term()
+%%--------------------------------------------------------------------
+init_per_testcase(_TestCase, Config) ->
+ Config.
+
+%%--------------------------------------------------------------------
+%% Function: end_per_testcase(TestCase, Config0) ->
+%% void() | {save_config,Config1}
+%% TestCase = atom()
+%% Config0 = Config1 = [tuple()]
+%%--------------------------------------------------------------------
+end_per_testcase(_TestCase, _Config) ->
+ ok.
+
+%%--------------------------------------------------------------------
+%% Function: groups() -> [Group]
+%% Group = {GroupName,Properties,GroupsAndTestCases}
+%% GroupName = atom()
+%% Properties = [parallel | sequence | Shuffle | {RepeatType,N}]
+%% GroupsAndTestCases = [Group | {group,GroupName} | TestCase]
+%% TestCase = atom()
+%% Shuffle = shuffle | {shuffle,{integer(),integer(),integer()}}
+%% RepeatType = repeat | repeat_until_all_ok | repeat_until_all_fail |
+%% repeat_until_any_ok | repeat_until_any_fail
+%% N = integer() | forever
+%%--------------------------------------------------------------------
+groups() ->
+ [].
+
+%%--------------------------------------------------------------------
+%% Function: all() -> GroupsAndTestCases | {skip,Reason}
+%% GroupsAndTestCases = [{group,GroupName} | TestCase]
+%% GroupName = atom()
+%% TestCase = atom()
+%% Reason = term()
+%%--------------------------------------------------------------------
+all() ->
+ [my_test_case].
+
+%%--------------------------------------------------------------------
+%% Function: TestCase() -> Info
+%% Info = [tuple()]
+%%--------------------------------------------------------------------
+my_test_case() ->
+ [].
+
+%%--------------------------------------------------------------------
+%% Function: TestCase(Config0) ->
+%% ok | exit() | {skip,Reason} | {comment,Comment} |
+%% {save_config,Config1} | {skip_and_save,Reason,Config1}
+%% Config0 = Config1 = [tuple()]
+%% Reason = term()
+%% Comment = term()
+%%--------------------------------------------------------------------
+my_test_case(_Config) ->
+ ok.
diff --git a/lib/common_test/test/ct_test_server_if_1_SUITE_data/test_server_if/test/ts_if_3_SUITE.erl b/lib/common_test/test/ct_test_server_if_1_SUITE_data/test_server_if/test/ts_if_3_SUITE.erl
new file mode 100644
index 0000000000..70191d31ed
--- /dev/null
+++ b/lib/common_test/test/ct_test_server_if_1_SUITE_data/test_server_if/test/ts_if_3_SUITE.erl
@@ -0,0 +1,128 @@
+%%
+%% %CopyrightBegin%
+%%
+%% 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(ts_if_3_SUITE).
+
+-compile(export_all).
+
+-include_lib("common_test/include/ct.hrl").
+
+%%--------------------------------------------------------------------
+%% Function: suite() -> Info
+%% Info = [tuple()]
+%%--------------------------------------------------------------------
+suite() ->
+ [].
+
+%%--------------------------------------------------------------------
+%% Function: init_per_suite(Config0) ->
+%% Config1 | {skip,Reason} | {skip_and_save,Reason,Config1}
+%% Config0 = Config1 = [tuple()]
+%% Reason = term()
+%%--------------------------------------------------------------------
+init_per_suite(Config) ->
+ Config.
+
+%%--------------------------------------------------------------------
+%% Function: end_per_suite(Config0) -> void() | {save_config,Config1}
+%% Config0 = Config1 = [tuple()]
+%%--------------------------------------------------------------------
+end_per_suite(_Config) ->
+ ok.
+
+%%--------------------------------------------------------------------
+%% Function: init_per_group(GroupName, Config0) ->
+%% Config1 | {skip,Reason} | {skip_and_save,Reason,Config1}
+%% GroupName = atom()
+%% Config0 = Config1 = [tuple()]
+%% Reason = term()
+%%--------------------------------------------------------------------
+init_per_group(_GroupName, Config) ->
+ Config.
+
+%%--------------------------------------------------------------------
+%% Function: end_per_group(GroupName, Config0) ->
+%% void() | {save_config,Config1}
+%% GroupName = atom()
+%% Config0 = Config1 = [tuple()]
+%%--------------------------------------------------------------------
+end_per_group(_GroupName, _Config) ->
+ ok.
+
+%%--------------------------------------------------------------------
+%% Function: init_per_testcase(TestCase, Config0) ->
+%% Config1 | {skip,Reason} | {skip_and_save,Reason,Config1}
+%% TestCase = atom()
+%% Config0 = Config1 = [tuple()]
+%% Reason = term()
+%%--------------------------------------------------------------------
+init_per_testcase(_TestCase, Config) ->
+ Config.
+
+%%--------------------------------------------------------------------
+%% Function: end_per_testcase(TestCase, Config0) ->
+%% void() | {save_config,Config1}
+%% TestCase = atom()
+%% Config0 = Config1 = [tuple()]
+%%--------------------------------------------------------------------
+end_per_testcase(_TestCase, _Config) ->
+ ok.
+
+%%--------------------------------------------------------------------
+%% Function: groups() -> [Group]
+%% Group = {GroupName,Properties,GroupsAndTestCases}
+%% GroupName = atom()
+%% Properties = [parallel | sequence | Shuffle | {RepeatType,N}]
+%% GroupsAndTestCases = [Group | {group,GroupName} | TestCase]
+%% TestCase = atom()
+%% Shuffle = shuffle | {shuffle,{integer(),integer(),integer()}}
+%% RepeatType = repeat | repeat_until_all_ok | repeat_until_all_fail |
+%% repeat_until_any_ok | repeat_until_any_fail
+%% N = integer() | forever
+%%--------------------------------------------------------------------
+groups() ->
+ [].
+
+%%--------------------------------------------------------------------
+%% Function: all() -> GroupsAndTestCases | {skip,Reason}
+%% GroupsAndTestCases = [{group,GroupName} | TestCase]
+%% GroupName = atom()
+%% TestCase = atom()
+%% Reason = term()
+%%--------------------------------------------------------------------
+%% No all/0!!
+%%all() ->
+%% [].
+
+%%--------------------------------------------------------------------
+%% Function: TestCase() -> Info
+%% Info = [tuple()]
+%%--------------------------------------------------------------------
+my_test_case() ->
+ [].
+
+%%--------------------------------------------------------------------
+%% Function: TestCase(Config0) ->
+%% ok | exit() | {skip,Reason} | {comment,Comment} |
+%% {save_config,Config1} | {skip_and_save,Reason,Config1}
+%% Config0 = Config1 = [tuple()]
+%% Reason = term()
+%% Comment = term()
+%%--------------------------------------------------------------------
+my_test_case(_Config) ->
+ ok.
diff --git a/lib/common_test/test/ct_test_server_if_1_SUITE_data/test_server_if/test/ts_if_4_SUITE.erl b/lib/common_test/test/ct_test_server_if_1_SUITE_data/test_server_if/test/ts_if_4_SUITE.erl
new file mode 100644
index 0000000000..4b566fea5d
--- /dev/null
+++ b/lib/common_test/test/ct_test_server_if_1_SUITE_data/test_server_if/test/ts_if_4_SUITE.erl
@@ -0,0 +1,127 @@
+%%
+%% %CopyrightBegin%
+%%
+%% 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(ts_if_4_SUITE).
+
+-compile(export_all).
+
+-include_lib("common_test/include/ct.hrl").
+
+%%--------------------------------------------------------------------
+%% Function: suite() -> Info
+%% Info = [tuple()]
+%%--------------------------------------------------------------------
+suite() ->
+ [].
+
+%%--------------------------------------------------------------------
+%% Function: init_per_suite(Config0) ->
+%% Config1 | {skip,Reason} | {skip_and_save,Reason,Config1}
+%% Config0 = Config1 = [tuple()]
+%% Reason = term()
+%%--------------------------------------------------------------------
+init_per_suite(Config) ->
+ Config.
+
+%%--------------------------------------------------------------------
+%% Function: end_per_suite(Config0) -> void() | {save_config,Config1}
+%% Config0 = Config1 = [tuple()]
+%%--------------------------------------------------------------------
+end_per_suite(_Config) ->
+ ok.
+
+%%--------------------------------------------------------------------
+%% Function: init_per_group(GroupName, Config0) ->
+%% Config1 | {skip,Reason} | {skip_and_save,Reason,Config1}
+%% GroupName = atom()
+%% Config0 = Config1 = [tuple()]
+%% Reason = term()
+%%--------------------------------------------------------------------
+init_per_group(_GroupName, Config) ->
+ Config.
+
+%%--------------------------------------------------------------------
+%% Function: end_per_group(GroupName, Config0) ->
+%% void() | {save_config,Config1}
+%% GroupName = atom()
+%% Config0 = Config1 = [tuple()]
+%%--------------------------------------------------------------------
+end_per_group(_GroupName, _Config) ->
+ ok.
+
+%%--------------------------------------------------------------------
+%% Function: init_per_testcase(TestCase, Config0) ->
+%% Config1 | {skip,Reason} | {skip_and_save,Reason,Config1}
+%% TestCase = atom()
+%% Config0 = Config1 = [tuple()]
+%% Reason = term()
+%%--------------------------------------------------------------------
+init_per_testcase(_TestCase, Config) ->
+ Config.
+
+%%--------------------------------------------------------------------
+%% Function: end_per_testcase(TestCase, Config0) ->
+%% void() | {save_config,Config1}
+%% TestCase = atom()
+%% Config0 = Config1 = [tuple()]
+%%--------------------------------------------------------------------
+end_per_testcase(_TestCase, _Config) ->
+ ok.
+
+%%--------------------------------------------------------------------
+%% Function: groups() -> [Group]
+%% Group = {GroupName,Properties,GroupsAndTestCases}
+%% GroupName = atom()
+%% Properties = [parallel | sequence | Shuffle | {RepeatType,N}]
+%% GroupsAndTestCases = [Group | {group,GroupName} | TestCase]
+%% TestCase = atom()
+%% Shuffle = shuffle | {shuffle,{integer(),integer(),integer()}}
+%% RepeatType = repeat | repeat_until_all_ok | repeat_until_all_fail |
+%% repeat_until_any_ok | repeat_until_any_fail
+%% N = integer() | forever
+%%--------------------------------------------------------------------
+groups() ->
+ [].
+
+%%--------------------------------------------------------------------
+%% Function: all() -> GroupsAndTestCases | {skip,Reason}
+%% GroupsAndTestCases = [{group,GroupName} | TestCase]
+%% GroupName = atom()
+%% TestCase = atom()
+%% Reason = term()
+%%--------------------------------------------------------------------
+all() ->
+ bad_format.
+
+%%--------------------------------------------------------------------
+%% Function: TestCase() -> Info
+%% Info = [tuple()]
+%%--------------------------------------------------------------------
+my_test_case() ->
+ [].
+
+%%--------------------------------------------------------------------
+%% Function: TestCase(Config0) ->
+%% ok | exit() | {skip,Reason} | {comment,Comment} |
+%% {save_config,Config1} | {skip_and_save,Reason,Config1}
+%% Config0 = Config1 = [tuple()]
+%% Reason = term()
+%% Comment = term()
+%%--------------------------------------------------------------------
+my_test_case(_Config) ->
+ ok.
diff --git a/lib/common_test/test/ct_test_server_if_1_SUITE_data/test_server_if/test/ts_if_5_SUITE.erl b/lib/common_test/test/ct_test_server_if_1_SUITE_data/test_server_if/test/ts_if_5_SUITE.erl
new file mode 100644
index 0000000000..c7b6b054fb
--- /dev/null
+++ b/lib/common_test/test/ct_test_server_if_1_SUITE_data/test_server_if/test/ts_if_5_SUITE.erl
@@ -0,0 +1,128 @@
+%%
+%% %CopyrightBegin%
+%%
+%% 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(ts_if_5_SUITE).
+
+-compile(export_all).
+
+-include_lib("common_test/include/ct.hrl").
+
+%%--------------------------------------------------------------------
+%% Function: suite() -> Info
+%% Info = [tuple()]
+%%--------------------------------------------------------------------
+suite() ->
+ [{timetrap,{seconds,30}},
+ {require,undef_variable}].
+
+%%--------------------------------------------------------------------
+%% Function: init_per_suite(Config0) ->
+%% Config1 | {skip,Reason} | {skip_and_save,Reason,Config1}
+%% Config0 = Config1 = [tuple()]
+%% Reason = term()
+%%--------------------------------------------------------------------
+init_per_suite(Config) ->
+ Config.
+
+%%--------------------------------------------------------------------
+%% Function: end_per_suite(Config0) -> void() | {save_config,Config1}
+%% Config0 = Config1 = [tuple()]
+%%--------------------------------------------------------------------
+end_per_suite(_Config) ->
+ ok.
+
+%%--------------------------------------------------------------------
+%% Function: init_per_group(GroupName, Config0) ->
+%% Config1 | {skip,Reason} | {skip_and_save,Reason,Config1}
+%% GroupName = atom()
+%% Config0 = Config1 = [tuple()]
+%% Reason = term()
+%%--------------------------------------------------------------------
+init_per_group(_GroupName, Config) ->
+ Config.
+
+%%--------------------------------------------------------------------
+%% Function: end_per_group(GroupName, Config0) ->
+%% void() | {save_config,Config1}
+%% GroupName = atom()
+%% Config0 = Config1 = [tuple()]
+%%--------------------------------------------------------------------
+end_per_group(_GroupName, _Config) ->
+ ok.
+
+%%--------------------------------------------------------------------
+%% Function: init_per_testcase(TestCase, Config0) ->
+%% Config1 | {skip,Reason} | {skip_and_save,Reason,Config1}
+%% TestCase = atom()
+%% Config0 = Config1 = [tuple()]
+%% Reason = term()
+%%--------------------------------------------------------------------
+init_per_testcase(_TestCase, Config) ->
+ Config.
+
+%%--------------------------------------------------------------------
+%% Function: end_per_testcase(TestCase, Config0) ->
+%% void() | {save_config,Config1}
+%% TestCase = atom()
+%% Config0 = Config1 = [tuple()]
+%%--------------------------------------------------------------------
+end_per_testcase(_TestCase, _Config) ->
+ ok.
+
+%%--------------------------------------------------------------------
+%% Function: groups() -> [Group]
+%% Group = {GroupName,Properties,GroupsAndTestCases}
+%% GroupName = atom()
+%% Properties = [parallel | sequence | Shuffle | {RepeatType,N}]
+%% GroupsAndTestCases = [Group | {group,GroupName} | TestCase]
+%% TestCase = atom()
+%% Shuffle = shuffle | {shuffle,{integer(),integer(),integer()}}
+%% RepeatType = repeat | repeat_until_all_ok | repeat_until_all_fail |
+%% repeat_until_any_ok | repeat_until_any_fail
+%% N = integer() | forever
+%%--------------------------------------------------------------------
+groups() ->
+ [].
+
+%%--------------------------------------------------------------------
+%% Function: all() -> GroupsAndTestCases | {skip,Reason}
+%% GroupsAndTestCases = [{group,GroupName} | TestCase]
+%% GroupName = atom()
+%% TestCase = atom()
+%% Reason = term()
+%%--------------------------------------------------------------------
+all() ->
+ [my_test_case].
+
+%%--------------------------------------------------------------------
+%% Function: TestCase() -> Info
+%% Info = [tuple()]
+%%--------------------------------------------------------------------
+my_test_case() ->
+ [].
+
+%%--------------------------------------------------------------------
+%% Function: TestCase(Config0) ->
+%% ok | exit() | {skip,Reason} | {comment,Comment} |
+%% {save_config,Config1} | {skip_and_save,Reason,Config1}
+%% Config0 = Config1 = [tuple()]
+%% Reason = term()
+%% Comment = term()
+%%--------------------------------------------------------------------
+my_test_case(_Config) ->
+ ok.
diff --git a/lib/common_test/test/ct_test_server_if_1_SUITE_data/test_server_if/test/ts_if_6_SUITE.erl b/lib/common_test/test/ct_test_server_if_1_SUITE_data/test_server_if/test/ts_if_6_SUITE.erl
new file mode 100644
index 0000000000..43440386e6
--- /dev/null
+++ b/lib/common_test/test/ct_test_server_if_1_SUITE_data/test_server_if/test/ts_if_6_SUITE.erl
@@ -0,0 +1,111 @@
+%%
+%% %CopyrightBegin%
+%%
+%% 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(ts_if_6_SUITE).
+
+-compile(export_all).
+
+-include_lib("common_test/include/ct.hrl").
+
+%%--------------------------------------------------------------------
+%% Function: suite() -> Info
+%% Info = [tuple()]
+%%--------------------------------------------------------------------
+suite() ->
+ exit(suite0_byebye).
+
+%%--------------------------------------------------------------------
+%% Function: init_per_group(GroupName, Config0) ->
+%% Config1 | {skip,Reason} | {skip_and_save,Reason,Config1}
+%% GroupName = atom()
+%% Config0 = Config1 = [tuple()]
+%% Reason = term()
+%%--------------------------------------------------------------------
+init_per_group(_GroupName, Config) ->
+ Config.
+
+%%--------------------------------------------------------------------
+%% Function: end_per_group(GroupName, Config0) ->
+%% void() | {save_config,Config1}
+%% GroupName = atom()
+%% Config0 = Config1 = [tuple()]
+%%--------------------------------------------------------------------
+end_per_group(_GroupName, _Config) ->
+ ok.
+
+%%--------------------------------------------------------------------
+%% Function: init_per_testcase(TestCase, Config0) ->
+%% Config1 | {skip,Reason} | {skip_and_save,Reason,Config1}
+%% TestCase = atom()
+%% Config0 = Config1 = [tuple()]
+%% Reason = term()
+%%--------------------------------------------------------------------
+init_per_testcase(_TestCase, Config) ->
+ Config.
+
+%%--------------------------------------------------------------------
+%% Function: end_per_testcase(TestCase, Config0) ->
+%% void() | {save_config,Config1}
+%% TestCase = atom()
+%% Config0 = Config1 = [tuple()]
+%%--------------------------------------------------------------------
+end_per_testcase(_TestCase, _Config) ->
+ ok.
+
+%%--------------------------------------------------------------------
+%% Function: groups() -> [Group]
+%% Group = {GroupName,Properties,GroupsAndTestCases}
+%% GroupName = atom()
+%% Properties = [parallel | sequence | Shuffle | {RepeatType,N}]
+%% GroupsAndTestCases = [Group | {group,GroupName} | TestCase]
+%% TestCase = atom()
+%% Shuffle = shuffle | {shuffle,{integer(),integer(),integer()}}
+%% RepeatType = repeat | repeat_until_all_ok | repeat_until_all_fail |
+%% repeat_until_any_ok | repeat_until_any_fail
+%% N = integer() | forever
+%%--------------------------------------------------------------------
+groups() ->
+ [].
+
+%%--------------------------------------------------------------------
+%% Function: all() -> GroupsAndTestCases | {skip,Reason}
+%% GroupsAndTestCases = [{group,GroupName} | TestCase]
+%% GroupName = atom()
+%% TestCase = atom()
+%% Reason = term()
+%%--------------------------------------------------------------------
+all() ->
+ [tc1].
+
+%%--------------------------------------------------------------------
+%% Function: TestCase() -> Info
+%% Info = [tuple()]
+%%--------------------------------------------------------------------
+tc1() ->
+ [].
+
+%%--------------------------------------------------------------------
+%% Function: TestCase(Config0) ->
+%% ok | exit() | {skip,Reason} | {comment,Comment} |
+%% {save_config,Config1} | {skip_and_save,Reason,Config1}
+%% Config0 = Config1 = [tuple()]
+%% Reason = term()
+%% Comment = term()
+%%--------------------------------------------------------------------
+tc1(_Config) ->
+ ok.
diff --git a/lib/common_test/test/ct_test_server_if_1_SUITE_data/test_server_if/test/ts_if_7_SUITE.erl b/lib/common_test/test/ct_test_server_if_1_SUITE_data/test_server_if/test/ts_if_7_SUITE.erl
new file mode 100644
index 0000000000..a2254848d0
--- /dev/null
+++ b/lib/common_test/test/ct_test_server_if_1_SUITE_data/test_server_if/test/ts_if_7_SUITE.erl
@@ -0,0 +1,93 @@
+%%
+%% %CopyrightBegin%
+%%
+%% 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(ts_if_7_SUITE).
+
+-compile(export_all).
+
+-include_lib("common_test/include/ct.hrl").
+
+%%--------------------------------------------------------------------
+%% Function: init_per_group(GroupName, Config0) ->
+%% Config1 | {skip,Reason} | {skip_and_save,Reason,Config1}
+%% GroupName = atom()
+%% Config0 = Config1 = [tuple()]
+%% Reason = term()
+%%--------------------------------------------------------------------
+init_per_group(_GroupName, Config) ->
+ Config.
+
+%%--------------------------------------------------------------------
+%% Function: end_per_group(GroupName, Config0) ->
+%% void() | {save_config,Config1}
+%% GroupName = atom()
+%% Config0 = Config1 = [tuple()]
+%%--------------------------------------------------------------------
+end_per_group(_GroupName, _Config) ->
+ ok.
+
+%%--------------------------------------------------------------------
+%% Function: init_per_testcase(TestCase, Config0) ->
+%% Config1 | {skip,Reason} | {skip_and_save,Reason,Config1}
+%% TestCase = atom()
+%% Config0 = Config1 = [tuple()]
+%% Reason = term()
+%%--------------------------------------------------------------------
+init_per_testcase(_TestCase, Config) ->
+ Config.
+
+%%--------------------------------------------------------------------
+%% Function: end_per_testcase(TestCase, Config0) ->
+%% void() | {save_config,Config1}
+%% TestCase = atom()
+%% Config0 = Config1 = [tuple()]
+%%--------------------------------------------------------------------
+end_per_testcase(_TestCase, _Config) ->
+ ok.
+
+%%--------------------------------------------------------------------
+%% Function: groups() -> [Group]
+%% Group = {GroupName,Properties,GroupsAndTestCases}
+%% GroupName = atom()
+%% Properties = [parallel | sequence | Shuffle | {RepeatType,N}]
+%% GroupsAndTestCases = [Group | {group,GroupName} | TestCase]
+%% TestCase = atom()
+%% Shuffle = shuffle | {shuffle,{integer(),integer(),integer()}}
+%% RepeatType = repeat | repeat_until_all_ok | repeat_until_all_fail |
+%% repeat_until_any_ok | repeat_until_any_fail
+%% N = integer() | forever
+%%--------------------------------------------------------------------
+groups() ->
+ [].
+
+%%--------------------------------------------------------------------
+%% Function: all() -> GroupsAndTestCases | {skip,Reason}
+%% GroupsAndTestCases = [{group,GroupName} | TestCase]
+%% GroupName = atom()
+%% TestCase = atom()
+%% Reason = term()
+%%--------------------------------------------------------------------
+all() ->
+ [tc1].
+
+tc1() ->
+ exit(tc1_byebye).
+
+tc1(_) ->
+ done.
+
diff --git a/lib/common_test/test/ct_test_server_if_1_SUITE_data/test_server_if/test/ts_if_8_SUITE.erl b/lib/common_test/test/ct_test_server_if_1_SUITE_data/test_server_if/test/ts_if_8_SUITE.erl
new file mode 100644
index 0000000000..990669cd4c
--- /dev/null
+++ b/lib/common_test/test/ct_test_server_if_1_SUITE_data/test_server_if/test/ts_if_8_SUITE.erl
@@ -0,0 +1,52 @@
+%%
+%% %CopyrightBegin%
+%%
+%% 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(ts_if_8_SUITE).
+
+-compile(export_all).
+
+-include_lib("common_test/include/ct.hrl").
+
+%%--------------------------------------------------------------------
+%% Function: groups() -> [Group]
+%% Group = {GroupName,Properties,GroupsAndTestCases}
+%% GroupName = atom()
+%% Properties = [parallel | sequence | Shuffle | {RepeatType,N}]
+%% GroupsAndTestCases = [Group | {group,GroupName} | TestCase]
+%% TestCase = atom()
+%% Shuffle = shuffle | {shuffle,{integer(),integer(),integer()}}
+%% RepeatType = repeat | repeat_until_all_ok | repeat_until_all_fail |
+%% repeat_until_any_ok | repeat_until_any_fail
+%% N = integer() | forever
+%%--------------------------------------------------------------------
+groups() ->
+ [].
+
+%%--------------------------------------------------------------------
+%% Function: all() -> GroupsAndTestCases | {skip,Reason}
+%% GroupsAndTestCases = [{group,GroupName} | TestCase]
+%% GroupName = atom()
+%% TestCase = atom()
+%% Reason = term()
+%%--------------------------------------------------------------------
+all() ->
+ [tc1].
+
+tc1(_) ->
+ exit(failed_on_purpose).
+
diff --git a/lib/common_test/test/ct_test_support.erl b/lib/common_test/test/ct_test_support.erl
new file mode 100644
index 0000000000..6148e3280e
--- /dev/null
+++ b/lib/common_test/test/ct_test_support.erl
@@ -0,0 +1,976 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 2008-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%
+%%
+
+%%% @doc Test support functions
+%%%
+%%% <p>This is a support module for testing the Common Test Framework.</p>
+%%%
+-module(ct_test_support).
+
+-include("test_server.hrl").
+-include_lib("common_test/include/ct_event.hrl").
+
+-export([init_per_suite/1, init_per_suite/2, end_per_suite/1,
+ init_per_testcase/2, end_per_testcase/2, write_testspec/3,
+ run/4, get_opts/1, wait_for_ct_stop/1]).
+
+-export([handle_event/2, start_event_receiver/1, get_events/2,
+ verify_events/3, reformat/2, log_events/3]).
+
+-include_lib("kernel/include/file.hrl").
+
+%%%-----------------------------------------------------------------
+%%% init_per_suite/1
+
+init_per_suite(Config) ->
+ init_per_suite(Config, 50).
+
+init_per_suite(Config, Level) ->
+ case delete_old_logs(os:type(), Config) of
+ {'EXIT',DelLogsReason} ->
+ test_server:format(0, "Failed to delete old log directories: ~p~n",
+ [DelLogsReason]);
+ _ ->
+ ok
+ end,
+ [_,Host] = string:tokens(atom_to_list(node()), "@"),
+ case slave:start(Host, ct, []) of
+ {error,Reason} ->
+ test_server:fail(Reason);
+ {ok,CTNode} ->
+ test_server:format(0, "Node ~p started~n", [CTNode]),
+ DataDir = ?config(data_dir, Config),
+ PrivDir = ?config(priv_dir, Config),
+
+ %% PrivDir as well as directory of Test Server suites
+ %% have to be in code path on Common Test node.
+ true = rpc:call(CTNode, code, add_patha, [PrivDir]),
+ [_ | Parts] = lists:reverse(filename:split(DataDir)),
+ TSDir = filename:join(lists:reverse(Parts)),
+ true = rpc:call(CTNode, code, add_patha, [TSDir]),
+ test_server:format(Level, "Dirs added to code path (on ~w):~n"
+ "~s~n~s~n", [CTNode,TSDir,PrivDir]),
+
+ TraceFile = filename:join(DataDir, "ct.trace"),
+ case file:read_file_info(TraceFile) of
+ {ok,_} ->
+ [{trace_level,0},
+ {ct_opts,[{ct_trace,TraceFile}]},
+ {ct_node,CTNode} | Config];
+ _ ->
+ [{trace_level,Level},
+ {ct_opts,[]},
+ {ct_node,CTNode} | Config]
+ end
+ end.
+
+%%%-----------------------------------------------------------------
+%%% end_per_suite/1
+
+end_per_suite(Config) ->
+ CTNode = ?config(ct_node, Config),
+ PrivDir = ?config(priv_dir, Config),
+ true = rpc:call(CTNode, code, del_path, [filename:join(PrivDir,"")]),
+ slave:stop(CTNode),
+ ok.
+
+%%%-----------------------------------------------------------------
+%%% init_per_testcase/2
+
+init_per_testcase(_TestCase, Config) ->
+ {_,{_,LogDir}} = lists:keysearch(logdir, 1, get_opts(Config)),
+ test_server:format("See Common Test logs here:\n"
+ "<a href=\"file://~s/all_runs.html\">~s/all_runs.html</a>",
+ [LogDir,LogDir]),
+ Config.
+
+%%%-----------------------------------------------------------------
+%%% end_per_testcase/2
+
+end_per_testcase(_TestCase, Config) ->
+ CTNode = ?config(ct_node, Config),
+ wait_for_ct_stop(CTNode),
+ ok.
+
+
+%%%-----------------------------------------------------------------
+%%%
+
+write_testspec(TestSpec, Dir, Name) ->
+ TSFile = filename:join(Dir, Name),
+ {ok,Dev} = file:open(TSFile, [write]),
+ [io:format(Dev, "~p.~n", [Entry]) || Entry <- TestSpec],
+ file:close(Dev),
+ io:format("Test specification written to: ~p~n", [TSFile]),
+ io:format(user, "Test specification written to: ~p~n", [TSFile]),
+ TSFile.
+
+
+%%%-----------------------------------------------------------------
+%%%
+
+get_opts(Config) ->
+ PrivDir = ?config(priv_dir, Config),
+ TempDir = case os:getenv("TMP") of
+ false ->
+ case os:getenv("TEMP") of
+ false ->
+ undefined;
+ Tmp ->
+ create_tmp_logdir(Tmp)
+ end;
+ Tmp ->
+ create_tmp_logdir(Tmp)
+ end,
+ LogDir =
+ case os:getenv("CT_USE_TMP_DIR") of
+ false ->
+ case os:type() of
+ {win32,_} ->
+ if TempDir == undefined -> PrivDir;
+ true -> TempDir
+ end;
+ _ ->
+ PrivDir
+ end;
+ _ ->
+ TempDir
+ end,
+ InitOpts = ?config(ct_opts, Config),
+ [{logdir,LogDir} | InitOpts].
+
+
+%%%-----------------------------------------------------------------
+%%%
+run(M, F, A, Config) ->
+ CTNode = ?config(ct_node, Config),
+ Level = ?config(trace_level, Config),
+ test_server:format(Level, "Calling ~w:~w(~p) on ~p~n",
+ [M, F, A, CTNode]),
+ rpc:call(CTNode, M, F, A).
+
+
+%%%-----------------------------------------------------------------
+%%% wait_for_ct_stop/1
+
+wait_for_ct_stop(CTNode) ->
+ %% Give CT at least 15 sec to stop (in case of bad make).
+ wait_for_ct_stop(5, CTNode).
+
+wait_for_ct_stop(0, CTNode) ->
+ test_server:format(0, "Giving up! Stopping ~p.", [CTNode]),
+ ok;
+wait_for_ct_stop(Retries, CTNode) ->
+ case rpc:call(CTNode, erlang, whereis, [ct_util_server]) of
+ undefined ->
+ ok;
+ Pid ->
+ test_server:format(0, "Waiting for CT (~p) to finish (~p)...",
+ [Pid,Retries]),
+ timer:sleep(5000),
+ wait_for_ct_stop(Retries-1, CTNode)
+ end.
+
+%%%-----------------------------------------------------------------
+%%% EVENT HANDLING
+
+handle_event(EH, Event) ->
+ event_receiver ! {self(),{event,EH,Event}},
+ receive {event_receiver,ok} -> ok end,
+ ok.
+
+start_event_receiver(Config) ->
+ CTNode = ?config(ct_node, Config),
+ spawn_link(CTNode, fun() -> er() end).
+
+get_events(_, Config) ->
+ CTNode = ?config(ct_node, Config),
+ {event_receiver,CTNode} ! {self(),get_events},
+ Events = receive {event_receiver,Evs} -> Evs end,
+ {event_receiver,CTNode} ! stop,
+ Events.
+
+er() ->
+ register(event_receiver, self()),
+ er_loop([]).
+
+er_loop(Evs) ->
+ receive
+ {From,{event,EH,Ev}} ->
+ From ! {event_receiver,ok},
+ er_loop([{EH,Ev} | Evs]);
+ {From,get_events} ->
+ From ! {event_receiver,lists:reverse(Evs)},
+ er_loop(Evs);
+ stop ->
+ ok
+ end.
+
+verify_events(TEvs, Evs, Config) ->
+ Node = ?config(ct_node, Config),
+ case catch verify_events1(TEvs, Evs, Node, Config) of
+ {'EXIT',Reason} ->
+ Reason;
+ _ ->
+ ok
+ end.
+
+verify_events1(TEvs = [TestEv | TestEvs], Evs = [_|Events], Node, Config) ->
+%% test_server:format("Next expected event: ~p~n", [TestEv]),
+ case catch locate(TestEv, Node, Evs, Config) of
+ nomatch ->
+ verify_events1(TEvs, Events, Node, Config);
+ {'EXIT',Reason} ->
+ test_server:format("Failed to find ~p in ~p~n"
+ "Reason: ~p~n", [TestEv,Evs,Reason]),
+ exit(Reason);
+ {Config1,Events1} ->
+ if is_list(TestEv) ->
+ ok;
+ element(1,TestEv) == parallel ; element(1,TestEv) == shuffle ->
+ ok;
+ true ->
+ test_server:format("Found ~p!", [TestEv])
+ end,
+ verify_events1(TestEvs, Events1, Node, Config1)
+ end;
+
+verify_events1([TestEv|_], [], _, _) ->
+ test_server:format("Failed to find ~p in the list of events!~n", [TestEv]),
+ exit({event_not_found,TestEv});
+
+verify_events1([], Evs, _, Config) ->
+ {Config,Evs}.
+
+%%%----------------------------------------------------------------------------
+%%% locate({TEHandler,TEName,TEData}, TENode, Events, Config) -> {Config1,Evs1}
+%%%
+%%% A group is represented as either:
+%%% {parallel,ListOfCasesAndGroups},
+%%% {shuffle,ListOfCasesAndGroups}, or
+%%% ListOfCasesAndGroups.
+%%%
+%%% The two first and two last events in a group *may* be tc_start and tc_done
+%%% for init_per_group and end_per_group.
+
+%% group (not parallel or shuffle)
+locate(TEvs, Node, Evs, Config) when is_list(TEvs) ->
+ case TEvs of
+ [InitStart = {TEH,tc_start,{M,{init_per_group,GroupName,Props}}},
+ InitDone = {TEH,tc_done,{M,{init_per_group,GroupName,Props},R}} | TEvs1] ->
+ case Evs of
+ [{TEH,#event{name=tc_start,
+ node=Node,
+ data={M,{init_per_group,GroupName,Props}}}},
+ {TEH,#event{name=tc_done,
+ node=Node,
+ data={M,{init_per_group,GroupName,Props},R}}} | Evs1] ->
+ test_server:format("Found ~p!", [InitStart]),
+ test_server:format("Found ~p!", [InitDone]),
+ verify_events1(TEvs1, Evs1, Node, Config);
+ _ ->
+ nomatch
+ end;
+ _ ->
+ verify_events1(TEvs, Evs, Node, Config)
+ end;
+
+%% Parallel events: Each test case in the group should be specified in a list
+%% with the tc_start, followed by the tc_done event. The order of the cases
+%% is irrelevant, but it must be checked that every test case exists and
+%% that tc_done comes after tc_start.
+locate({parallel,TEvs}, Node, Evs, Config) ->
+ Start =
+ case TEvs of
+ [InitStart = {TEH,tc_start,{M,{init_per_group,GroupName,Props}}},
+ InitDone = {TEH,tc_done,{M,{init_per_group,GroupName,Props},R}} | TEs] ->
+ case Evs of
+ [{TEH,#event{name=tc_start,
+ node=Node,
+ data={M,{init_per_group,GroupName,Props}}}},
+ {TEH,#event{name=tc_done,
+ node=Node,
+ data={M,{init_per_group,GroupName,Props},R}}} | Es] ->
+ test_server:format("Found ~p!", [InitStart]),
+ test_server:format("Found ~p!", [InitDone]),
+ {TEs,Es};
+ _ ->
+ nomatch
+ end;
+ _ ->
+ {TEvs,Evs}
+ end,
+ case Start of
+ nomatch ->
+ nomatch;
+ {TEvs1,Evs1} ->
+ {TcDoneEvs,RemainEvs,_} =
+ lists:foldl(
+ %% tc_start event for a parallel test case
+ fun(TEv={TEH,tc_start,{M,F}}, {Done,RemEvs,RemSize}) ->
+ %% drop events until TEv is found
+ Evs2 = lists:dropwhile(
+ fun({EH,#event{name=tc_start,
+ node=EvNode,
+ data={Mod,Func}}}) when
+ EH == TEH, EvNode == Node,
+ Mod == M, Func == F ->
+ false;
+ (_) ->
+ true
+ end, Evs1),
+ %% split the list at the tc_done event and record the smallest
+ %% list of remaining events (Evs) as possible
+ RemEvs1 =
+ lists:dropwhile(
+ fun({EH,#event{name=tc_done,
+ node=EvNode,
+ data={Mod,Func,_}}}) when
+ EH == TEH, EvNode == Node,
+ Mod == M, Func == F ->
+ false;
+ (_) ->
+ true
+ end, Evs2),
+ case RemEvs1 of
+ [] when Evs2 == [] ->
+ exit({unmatched,TEv});
+ [] ->
+ test_server:format("Found ~p!", [TEv]),
+ exit({tc_done_not_found,TEv});
+ [TcDone|Evs3] ->
+ test_server:format("Found ~p!", [TEv]),
+ RemSize1 = length(Evs3),
+ if RemSize1 < RemSize ->
+ {[TcDone|Done],Evs3,RemSize1};
+ true ->
+ {[TcDone|Done],RemEvs,RemSize}
+ end
+ end;
+ %% tc_done event for a parallel test case
+ (TEv={TEH,tc_done,{M,F,R}}, {Done,RemEvs,RemSize}) ->
+ case [E || E={EH,#event{name=tc_done,
+ node=EvNode,
+ data={Mod,Func,Result}}} <- Done,
+ EH == TEH, EvNode == Node, Mod == M,
+ Func == F, Result == R] of
+ [TcDone|_] ->
+ test_server:format("Found ~p!", [TEv]),
+ {lists:delete(TcDone, Done),RemEvs,RemSize};
+ [] ->
+ exit({unmatched,TEv})
+ end;
+ %% tc_start event for end_per_group
+ (TEv={TEH,tc_start,{M,{end_per_group,GroupName,Props}}},
+ {Done,RemEvs,_RemSize}) ->
+ RemEvs1 =
+ lists:dropwhile(
+ fun({EH,#event{name=tc_start,
+ node=EvNode,
+ data={Mod,{end_per_group,
+ EvGName,EvProps}}}}) when
+ EH == TEH, EvNode == Node, Mod == M,
+ EvGName == GroupName, EvProps == Props ->
+ false;
+ (_) ->
+ true
+ end, RemEvs),
+ case RemEvs1 of
+ [] ->
+ exit({end_per_group_not_found,TEv});
+ [_ | RemEvs2] ->
+ test_server:format("Found ~p!", [TEv]),
+ {Done,RemEvs2,length(RemEvs2)}
+ end;
+ %% tc_done event for end_per_group
+ (TEv={TEH,tc_done,{M,{end_per_group,GroupName,Props},R}},
+ {Done,RemEvs,_RemSize}) ->
+ RemEvs1 =
+ lists:dropwhile(
+ fun({EH,#event{name=tc_done,
+ node=EvNode,
+ data={Mod,{end_per_group,
+ EvGName,EvProps},Res}}}) when
+ EH == TEH, EvNode == Node, Mod == M,
+ EvGName == GroupName, EvProps == Props, Res == R ->
+ false;
+ (_) ->
+ true
+ end, RemEvs),
+ case RemEvs1 of
+ [] ->
+ exit({end_per_group_not_found,TEv});
+ [_ | RemEvs2] ->
+ test_server:format("Found ~p!", [TEv]),
+ {Done,RemEvs2,length(RemEvs2)}
+ end;
+ %% end_per_group auto skipped
+ (TEv={TEH,tc_auto_skip,{M,end_per_group,R}}, {Done,RemEvs,_RemSize}) ->
+ RemEvs1 =
+ lists:dropwhile(
+ fun({EH,#event{name=tc_auto_skip,
+ node=EvNode,
+ data={Mod,end_per_group,Reason}}}) when
+ EH == TEH, EvNode == Node, Mod == M, Reason == R ->
+ false;
+ (_) ->
+ true
+ end, RemEvs),
+ case RemEvs1 of
+ [] ->
+ exit({end_per_group_not_found,TEv});
+ [_AutoSkip | RemEvs2] ->
+ {Done,RemEvs2,length(RemEvs2)}
+ end;
+ %% match other event than test case
+ (TEv={TEH,N,D}, Acc) when D == '_' ->
+ case [E || E={EH,#event{name=Name,
+ node=EvNode,
+ data=_}} <- Evs1,
+ EH == TEH, EvNode == Node, Name == N] of
+ [] ->
+ exit({unmatched,TEv});
+ _ ->
+ test_server:format("Found ~p!", [TEv]),
+ Acc
+ end;
+ (TEv={TEH,N,D}, Acc) ->
+ case [E || E={EH,#event{name=Name,
+ node=EvNode,
+ data=Data}} <- Evs1,
+ EH == TEH, EvNode == Node, Name == N, Data == D] of
+ [] ->
+ exit({unmatched,TEv});
+ _ ->
+ test_server:format("Found ~p!", [TEv]),
+ Acc
+ end;
+ %% start of a sub-group
+ (SubGroupTEvs, Acc) when is_list(SubGroupTEvs) ->
+ verify_events1(SubGroupTEvs, Evs1, Node, Config),
+ Acc;
+ (TEv={Prop,_SubGroupTEvs}, Acc) when
+ Prop == shuffle ; Prop == parallel ->
+ verify_events1([TEv], Evs1, Node, Config),
+ Acc
+ end, {[],Evs1,length(Evs1)}, TEvs1),
+ case TcDoneEvs of
+ [] ->
+ test_server:format("Found all parallel events!", []),
+ {Config,RemainEvs};
+ _ ->
+ exit({unexpected_events,TcDoneEvs})
+ end
+ end;
+
+%% Shuffled events: Each test case in the group should be specified in a list
+%% with the tc_start, followed by the tc_done event. The order of the cases
+%% is irrelevant, but it must be checked that every test case exists and
+%% that the tc_done event follows the tc_start.
+locate({shuffle,TEvs}, Node, Evs, Config) ->
+ Start =
+ case TEvs of
+ [InitStart = {TEH,tc_start,{M,{init_per_group,GroupName,Props}}},
+ InitDone = {TEH,tc_done,{M,{init_per_group,GroupName,Props},R}} | TEs] ->
+ case Evs of
+ [{TEH,#event{name=tc_start,
+ node=Node,
+ data={M,{init_per_group,GroupName,EvProps}}}},
+ {TEH,#event{name=tc_done,
+ node=Node,
+ data={M,{init_per_group,GroupName,EvProps},R}}} | Es] ->
+ case proplists:get_value(shuffle, Props) of
+ '_' ->
+ case proplists:get_value(shuffle, EvProps) of
+ false ->
+ exit({no_shuffle_prop_found,{M,init_per_group,
+ GroupName,EvProps}});
+ _ ->
+ PropsCmp = proplists:delete(shuffle, EvProps),
+ PropsCmp = proplists:delete(shuffle, Props)
+ end;
+ _ ->
+ Props = EvProps
+ end,
+ test_server:format("Found ~p!", [InitStart]),
+ test_server:format("Found ~p!", [InitDone]),
+ {TEs,Es};
+ _ ->
+ nomatch
+ end;
+ _ ->
+ {TEvs,Evs}
+ end,
+ case Start of
+ nomatch ->
+ nomatch;
+ {TEvs1,Evs1} ->
+ {TcDoneEvs,RemainEvs,_} =
+ lists:foldl(
+ %% tc_start event for a test case
+ fun(TEv={TEH,tc_start,{M,F}}, {Done,RemEvs,RemSize}) ->
+ %% drop events until TEv is found
+ Evs2 = lists:dropwhile(
+ fun({EH,#event{name=tc_start,
+ node=EvNode,
+ data={Mod,Func}}}) when
+ EH == TEH, EvNode == Node,
+ Mod == M, Func == F ->
+ false;
+ (_) ->
+ true
+ end, Evs1),
+ %% verify the tc_done event comes next in Evs
+ case Evs2 of
+ [] ->
+ exit({unmatched,TEv});
+ [_TcStart, TcDone={TEH,#event{name=tc_done,
+ node=Node,
+ data={M,F,_}}} | Evs3] ->
+ test_server:format("Found ~p!", [TEv]),
+ RemSize1 = length(Evs3),
+ if RemSize1 < RemSize ->
+ {[TcDone|Done],Evs3,RemSize1};
+ true ->
+ {[TcDone|Done],RemEvs,RemSize}
+ end
+ end;
+ %% tc_done event for a test case
+ (TEv={TEH,tc_done,{M,F,R}}, {Done,RemEvs,RemSize}) ->
+ case [E || E={EH,#event{name=tc_done,
+ node=EvNode,
+ data={Mod,Func,Result}}} <- Done,
+ EH == TEH, EvNode == Node, Mod == M,
+ Func == F, Result == R] of
+ [TcDone|_] ->
+ test_server:format("Found ~p!", [TEv]),
+ {lists:delete(TcDone, Done),RemEvs,RemSize};
+ [] ->
+ exit({unmatched,TEv})
+ end;
+ %% tc_start event for end_per_group
+ (TEv={TEH,tc_start,{M,{end_per_group,GroupName,Props}}},
+ {Done,RemEvs,_RemSize}) ->
+ RemEvs1 =
+ lists:dropwhile(
+ fun({EH,#event{name=tc_start,
+ node=EvNode,
+ data={Mod,{end_per_group,
+ EvGName,_}}}}) when
+ EH == TEH, EvNode == Node, Mod == M,
+ EvGName == GroupName ->
+ false;
+ (_) ->
+ true
+ end, RemEvs),
+ case RemEvs1 of
+ [] ->
+ exit({end_per_group_not_found,TEv});
+ [{_,#event{data={_,{_,_,EvProps1}}}} | RemEvs2] ->
+ case proplists:get_value(shuffle, Props) of
+ '_' ->
+ case proplists:get_value(shuffle, EvProps1) of
+ false ->
+ exit({no_shuffle_prop_found,
+ {M,end_per_group,GroupName,EvProps1}});
+ _ ->
+ PropsCmp1 = proplists:delete(shuffle, EvProps1),
+ PropsCmp1 = proplists:delete(shuffle, Props)
+ end;
+ _ ->
+ Props = EvProps1
+ end,
+ test_server:format("Found ~p!", [TEv]),
+ {Done,RemEvs2,length(RemEvs2)}
+ end;
+ %% tc_done event for end_per_group
+ (TEv={TEH,tc_done,{M,{end_per_group,GroupName,Props},R}},
+ {Done,RemEvs,_RemSize}) ->
+ RemEvs1 =
+ lists:dropwhile(
+ fun({EH,#event{name=tc_done,
+ node=EvNode,
+ data={Mod,{end_per_group,
+ EvGName,_},Res}}}) when
+ EH == TEH, EvNode == Node, Mod == M,
+ EvGName == GroupName, Res == R ->
+ false;
+ (_) ->
+ true
+ end, RemEvs),
+ case RemEvs1 of
+ [] ->
+ exit({end_per_group_not_found,TEv});
+ [{_,#event{data={_,{_,_,EvProps1},_}}} | RemEvs2] ->
+ case proplists:get_value(shuffle, Props) of
+ '_' ->
+ case proplists:get_value(shuffle, EvProps1) of
+ false ->
+ exit({no_shuffle_prop_found,
+ {M,end_per_group,GroupName,EvProps1}});
+ _ ->
+ PropsCmp1 = proplists:delete(shuffle, EvProps1),
+ PropsCmp1 = proplists:delete(shuffle, Props)
+ end;
+ _ ->
+ Props = EvProps1
+ end,
+ test_server:format("Found ~p!", [TEv]),
+ {Done,RemEvs2,length(RemEvs2)}
+ end;
+ %% end_per_group auto skipped
+ (TEv={TEH,tc_auto_skip,{M,end_per_group,R}}, {Done,RemEvs,_RemSize}) ->
+ RemEvs1 =
+ lists:dropwhile(
+ fun({EH,#event{name=tc_auto_skip,
+ node=EvNode,
+ data={Mod,end_per_group,Reason}}}) when
+ EH == TEH, EvNode == Node, Mod == M, Reason == R ->
+ false;
+ (_) ->
+ true
+ end, RemEvs),
+ case RemEvs1 of
+ [] ->
+ exit({end_per_group_not_found,TEv});
+ [_AutoSkip | RemEvs2] ->
+ {Done,RemEvs2,length(RemEvs2)}
+ end;
+ %% match other event than test case
+ (TEv={TEH,N,D}, Acc) when D == '_' ->
+ case [E || E={EH,#event{name=Name,
+ node=EvNode,
+ data=_}} <- Evs1,
+ EH == TEH, EvNode == Node, Name == N] of
+ [] ->
+ exit({unmatched,TEv});
+ _ ->
+ test_server:format("Found ~p!", [TEv]),
+ Acc
+ end;
+ (TEv={TEH,N,D}, Acc) ->
+ case [E || E={EH,#event{name=Name,
+ node=EvNode,
+ data=Data}} <- Evs1,
+ EH == TEH, EvNode == Node, Name == N, Data == D] of
+ [] ->
+ exit({unmatched,TEv});
+ _ ->
+ test_server:format("Found ~p!", [TEv]),
+ Acc
+ end;
+ %% start of a sub-group
+ (SubGroupTEvs, Acc) when is_list(SubGroupTEvs) ->
+ verify_events1(SubGroupTEvs, Evs1, Node, Config),
+ Acc;
+ (TEv={Prop,_SubGroupTEvs}, Acc) when
+ Prop == shuffle ; Prop == parallel ->
+ verify_events1([TEv], Evs1, Node, Config),
+ Acc
+ end, {[],Evs1,length(Evs1)}, TEvs1),
+ case TcDoneEvs of
+ [] ->
+ test_server:format("Found all shuffled events!", []),
+ {Config,RemainEvs};
+ _ ->
+ exit({unexpected_events,TcDoneEvs})
+ end
+ end;
+
+locate({TEH,Name,{'DEF','RUNDIR'}}, Node, [Ev|Evs], Config) ->
+ case Ev of
+ {TEH,#event{name=Name, node=Node, data=EvData}} ->
+ {_,{_,LogDir}} = lists:keysearch(logdir, 1, get_opts(Config)),
+ D = filename:join(LogDir, "ct_run." ++ atom_to_list(Node)),
+ case string:str(EvData, D) of
+ 0 -> exit({badmatch,EvData});
+ _ -> ok
+ end,
+ {Config,Evs};
+ _ ->
+ nomatch
+ end;
+
+locate({TEH,Name,{'DEF',{'START_TIME','LOGDIR'}}}, Node, [Ev|Evs], Config) ->
+ case Ev of
+ {TEH,#event{name=Name, node=Node, data=EvData}} ->
+ case EvData of
+ {DT={{_,_,_},{_,_,_}},Dir} when is_list(Dir) ->
+ {_,{_,LogDir}} = lists:keysearch(logdir, 1, get_opts(Config)),
+ D = filename:join(LogDir, "ct_run." ++ atom_to_list(Node)),
+ case string:str(Dir, D) of
+ 0 -> exit({badmatch,Dir});
+ _ -> ok
+ end,
+ {[{start_time,DT}|Config],Evs};
+ Data ->
+ exit({badmatch,Data})
+ end;
+ _ ->
+ nomatch
+ end;
+
+locate({TEH,Name,{'DEF','STOP_TIME'}}, Node, [Ev|Evs], Config) ->
+ case Ev of
+ {TEH,#event{name=Name, node=Node, data=EvData}} ->
+ case EvData of
+ DT={{_,_,_},{_,_,_}} ->
+ {[{stop_time,DT}|Config],Evs};
+ Data ->
+ exit({badmatch,Data})
+ end;
+ _ ->
+ nomatch
+ end;
+
+%% to match variable data as a result of a failed test case
+locate({TEH,tc_done,{Mod,Func,{failed,{error,{Slogan,'_'}}}}}, Node, [Ev|Evs], Config) ->
+ case Ev of
+ {TEH,#event{name=tc_done, node=Node,
+ data={Mod,Func,{failed,{error,{Slogan,_}}}}}} ->
+ {Config,Evs};
+ _ ->
+ nomatch
+ end;
+
+%% to match variable data as a result of an aborted test case
+locate({TEH,tc_done,{undefined,undefined,{testcase_aborted,
+ {abort_current_testcase,Func},'_'}}},
+ Node, [Ev|Evs], Config) ->
+ case Ev of
+ {TEH,#event{name=tc_done, node=Node,
+ data={undefined,undefined,
+ {testcase_aborted,{abort_current_testcase,Func},_}}}} ->
+ {Config,Evs};
+ _ ->
+ nomatch
+ end;
+
+%% matches any event of type Name
+locate({TEH,Name,Data}, Node, [Ev|Evs], Config) when Data == '_' ->
+ case Ev of
+ {TEH,#event{name=Name, node=Node}} ->
+ {Config,Evs};
+ _ ->
+ nomatch
+ end;
+
+locate({TEH,Name,Data}, Node, [Ev|Evs], Config) ->
+ case Ev of
+ {TEH,#event{name=Name, node=Node, data=Data}} ->
+ {Config,Evs};
+ _ ->
+ nomatch
+ end.
+
+log_events(TC, Events, PrivDir) ->
+ LogFile = filename:join(PrivDir, atom_to_list(TC)++".events"),
+ {ok,Dev} = file:open(LogFile, [write]),
+ io:format(Dev, "[~n", []),
+ log_events1(Events, Dev, " "),
+ file:close(Dev),
+ io:format("Events written to logfile: ~p~n", [LogFile]),
+ io:format(user, "Events written to logfile: ~p~n", [LogFile]).
+
+log_events1(Evs, Dev, "") ->
+ log_events1(Evs, Dev, " ");
+log_events1([E={_EH,tc_start,{_M,{init_per_group,_GrName,Props}}} | Evs], Dev, Ind) ->
+ case get_prop(Props) of
+ undefined ->
+ io:format(Dev, "~s[~p,~n", [Ind,E]),
+ log_events1(Evs, Dev, Ind++" ");
+ Prop ->
+ io:format(Dev, "~s{~w,~n~s[~p,~n", [Ind,Prop,Ind++" ",E]),
+ log_events1(Evs, Dev, Ind++" ")
+ end;
+log_events1([E={_EH,tc_done,{_M,{init_per_group,_GrName,_Props},_R}} | Evs], Dev, Ind) ->
+ io:format(Dev, "~s~p,~n", [Ind,E]),
+ log_events1(Evs, Dev, Ind++" ");
+log_events1([E={_EH,tc_start,{_M,{end_per_group,_GrName,_Props}}} | Evs], Dev, Ind) ->
+ Ind1 = Ind -- " ",
+ io:format(Dev, "~s~p,~n", [Ind1,E]),
+ log_events1(Evs, Dev, Ind1);
+log_events1([E={_EH,tc_done,{_M,{end_per_group,_GrName,Props},_R}} | Evs], Dev, Ind) ->
+ case get_prop(Props) of
+ undefined ->
+ io:format(Dev, "~s~p],~n", [Ind,E]),
+ log_events1(Evs, Dev, Ind--" ");
+ _Prop ->
+ io:format(Dev, "~s~p]},~n", [Ind,E]),
+ log_events1(Evs, Dev, Ind--" ")
+ end;
+log_events1([E={_EH,tc_auto_skip,{_M,end_per_group,_Reason}} | Evs], Dev, Ind) ->
+ io:format(Dev, "~s~p],~n", [Ind,E]),
+ log_events1(Evs, Dev, Ind--" ");
+log_events1([E], Dev, Ind) ->
+ io:format(Dev, "~s~p~n].~n", [Ind,E]),
+ ok;
+log_events1([E | Evs], Dev, Ind) ->
+ io:format(Dev, "~s~p,~n", [Ind,E]),
+ log_events1(Evs, Dev, Ind);
+log_events1([], _Dev, _Ind) ->
+ ok.
+
+get_prop(Props) ->
+ case lists:member(parallel, Props) of
+ true -> parallel;
+ false -> case lists:member(shuffle, Props) of
+ true -> shuffle;
+ false -> case lists:keysearch(shuffle, 1, Props) of
+ {value,_} -> shuffle;
+ _ -> undefined
+ end
+ end
+ end.
+
+reformat([{_EH,#event{name=start_write_file,data=_}} | Events], EH) ->
+ reformat(Events, EH);
+reformat([{_EH,#event{name=finished_write_file,data=_}} | Events], EH) ->
+ reformat(Events, EH);
+reformat([{_EH,#event{name=start_make,data=_}} | Events], EH) ->
+ reformat(Events, EH);
+reformat([{_EH,#event{name=finished_make,data=_}} | Events], EH) ->
+ reformat(Events, EH);
+reformat([{_EH,#event{name=start_logging,data=_}} | Events], EH) ->
+ [{EH,start_logging,{'DEF','RUNDIR'}} | reformat(Events, EH)];
+reformat([{_EH,#event{name=test_start,data=_}} | Events], EH) ->
+ [{EH,test_start,{'DEF',{'START_TIME','LOGDIR'}}} | reformat(Events, EH)];
+reformat([{_EH,#event{name=test_done,data=_}} | Events], EH) ->
+ [{EH,test_done,{'DEF','STOP_TIME'}} | reformat(Events, EH)];
+reformat([{_EH,#event{name=test_stats,data=Data}} | Events], EH) ->
+ [{EH,test_stats,Data} | reformat(Events, EH)];
+%% use this to only print the last test_stats event:
+%% case [N || {_,#event{name=N}} <- Events, N == test_stats] of
+%% [] -> % last stats event
+%% [{EH,test_stats,Data} | reformat(Events, EH)];
+%% _ ->
+%% reformat(Events, EH)
+%% end;
+reformat([{_EH,#event{name=Name,data=Data}} | Events], EH) ->
+ [{EH,Name,Data} | reformat(Events, EH)];
+reformat([], _EH) ->
+ [].
+
+
+%%%-----------------------------------------------------------------
+%%% MISC HELP FUNCTIONS
+
+create_tmp_logdir(Tmp) ->
+ LogDir = filename:join(Tmp,"ct"),
+ file:make_dir(LogDir),
+ LogDir.
+
+delete_old_logs({win32,_}, Config) ->
+ case {?config(priv_dir, Config),?config(logdir, get_opts(Config))} of
+ {LogDir,LogDir} ->
+ ignore;
+ {_,LogDir} -> % using tmp for logs
+ catch delete_dirs(LogDir)
+ end;
+
+delete_old_logs(_, Config) ->
+ case os:getenv("CT_USE_TMP_DIR") of
+ false ->
+ ignore;
+ _ ->
+ catch delete_dirs(?config(logdir, get_opts(Config)))
+ end.
+
+delete_dirs(LogDir) ->
+ Now = calendar:datetime_to_gregorian_seconds(calendar:local_time()),
+ SaveTime = case os:getenv("CT_SAVE_OLD_LOGS") of
+ false ->
+ 28800;
+ SaveTime0 ->
+ list_to_integer(SaveTime0)
+ end,
+ Deadline = Now - SaveTime,
+ Dirs = filelib:wildcard(filename:join(LogDir,"ct_run*")),
+ Dirs2Del =
+ lists:foldl(fun(Dir, Del) ->
+ [S,Mi,H,D,Mo,Y|_] =
+ lists:reverse(string:tokens(Dir, [$.,$-,$_])),
+ S2I = fun(Str) -> list_to_integer(Str) end,
+ DT = {{S2I(Y),S2I(Mo),S2I(D)}, {S2I(H),S2I(Mi),S2I(S)}},
+ Then = calendar:datetime_to_gregorian_seconds(DT),
+ if Then > Deadline ->
+ Del;
+ true ->
+ [Dir | Del]
+ end
+ end, [], Dirs),
+ case length(Dirs2Del) of
+ 0 ->
+ test_server:format(0, "No log directories older than ~w secs.", [SaveTime]);
+ N ->
+ test_server:format(0, "Deleting ~w directories older than ~w secs.", [N,SaveTime])
+ end,
+ delete_dirs(LogDir, Dirs2Del).
+
+delete_dirs(_, []) ->
+ ok;
+delete_dirs(LogDir, [Dir | Dirs]) ->
+ test_server:format(0, "Removing old log directory: ~s", [Dir]),
+ case catch rm_rec(Dir) of
+ {_,Reason} ->
+ test_server:format(0, "Delete failed! (~p)", [Reason]);
+ ok ->
+ ok
+ end,
+ delete_dirs(LogDir, Dirs).
+
+rm_rec(Dir) ->
+ %% ensure we're removing the ct_run directory
+ case lists:reverse(filename:split(Dir)) of
+ [[$c,$t,$_,$r,$u,$n,$.|_]|_] ->
+ rm_dir(filename:absname(Dir));
+ _ ->
+ {error,{invalid_logdir,Dir}}
+ end.
+
+rm_dir(Dir) ->
+ case file:list_dir(Dir) of
+ {error,Errno} ->
+ exit({ls_failed,Dir,Errno});
+ {ok,Files} ->
+ rm_files([filename:join(Dir, F) || F <- Files]),
+ file:del_dir(Dir)
+ end.
+
+rm_files([F | Fs]) ->
+ Base = filename:basename(F),
+ if Base == "." ; Base == ".." ->
+ rm_files(Fs);
+ true ->
+ case file:read_file_info(F) of
+ {ok,#file_info{type=directory}} ->
+ rm_dir(F),
+ rm_files(Fs);
+ {ok,_Regular} ->
+ case file:delete(F) of
+ ok ->
+ rm_files(Fs);
+ {error,Errno} ->
+ exit({del_failed,F,Errno})
+ end
+ end
+ end;
+rm_files([]) ->
+ ok.
+
diff --git a/lib/common_test/test/ct_test_support_eh.erl b/lib/common_test/test/ct_test_support_eh.erl
new file mode 100644
index 0000000000..fd3ae18746
--- /dev/null
+++ b/lib/common_test/test/ct_test_support_eh.erl
@@ -0,0 +1,127 @@
+%%
+%% %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%
+%%
+
+%%% @doc Event handler module
+%%%
+%%% <p>This is an event handler module used for testing that
+%%% Common Test generates events as expected.</p>
+%%%
+-module(ct_test_support_eh).
+
+-behaviour(gen_event).
+
+-include_lib("test_server/include/test_server.hrl").
+-include_lib("common_test/include/ct_event.hrl").
+
+%% gen_event callbacks
+-export([init/1, handle_event/2, handle_call/2,
+ handle_info/2, terminate/2, code_change/3]).
+
+-record(state, {cbm=ct_test_support,
+ trace_level=50}).
+
+%%====================================================================
+%% gen_event callbacks
+%%====================================================================
+%%--------------------------------------------------------------------
+%% Function: init(Args) -> {ok, State}
+%% Description: Whenever a new event handler is added to an event manager,
+%% this function is called to initialize the event handler.
+%%--------------------------------------------------------------------
+init(Args) ->
+
+ S1 = case lists:keysearch(cbm, 1, Args) of
+ {_,{cbm,CBM}} ->
+ #state{cbm=CBM};
+ _ ->
+ #state{}
+ end,
+ S2 = case lists:keysearch(trace_level, 1, Args) of
+ {_,{trace_level,Level}} ->
+ S1#state{trace_level=Level};
+ _ ->
+ S1
+ end,
+ print(S2#state.trace_level, "Event Handler ~w started!~n", [?MODULE]),
+ {ok,S2}.
+
+%%--------------------------------------------------------------------
+%% Function:
+%% handle_event(Event, State) -> {ok, State} |
+%% {swap_handler, Args1, State1, Mod2, Args2} |
+%% remove_handler
+%% Description:Whenever an event manager receives an event sent using
+%% gen_event:notify/2 or gen_event:sync_notify/2, this function is called for
+%% each installed event handler to handle the event.
+%%--------------------------------------------------------------------
+handle_event(Event, State=#state{cbm=CBM, trace_level=_Level}) ->
+ % print(_Level, "~p: ~p~n", [Event#event.name,Event#event.data]),
+ CBM:handle_event(?MODULE, Event),
+ {ok,State}.
+
+%%--------------------------------------------------------------------
+%% Function:
+%% handle_call(Request, State) -> {ok, Reply, State} |
+%% {swap_handler, Reply, Args1, State1,
+%% Mod2, Args2} |
+%% {remove_handler, Reply}
+%% Description: Whenever an event manager receives a request sent using
+%% gen_event:call/3,4, this function is called for the specified event
+%% handler to handle the request.
+%%--------------------------------------------------------------------
+handle_call(_Req, State) ->
+ Reply = ok,
+ {ok, Reply, State}.
+
+%%--------------------------------------------------------------------
+%% Function:
+%% handle_info(Info, State) -> {ok, State} |
+%% {swap_handler, Args1, State1, Mod2, Args2} |
+%% remove_handler
+%% Description: This function is called for each installed event handler when
+%% an event manager receives any other message than an event or a synchronous
+%% request (or a system message).
+%%--------------------------------------------------------------------
+handle_info(_Info, State) ->
+ {ok, State}.
+
+%%--------------------------------------------------------------------
+%% Function: terminate(Reason, State) -> void()
+%% Description:Whenever an event handler is deleted from an event manager,
+%% this function is called. It should be the opposite of Module:init/1 and
+%% do any necessary cleaning up.
+%%--------------------------------------------------------------------
+terminate(_Reason, _State) ->
+ ok.
+
+%%--------------------------------------------------------------------
+%% Function: code_change(OldVsn, State, Extra) -> {ok, NewState}
+%% Description: Convert process state when code is changed
+%%--------------------------------------------------------------------
+code_change(_OldVsn, State, _Extra) ->
+ {ok, State}.
+
+%%--------------------------------------------------------------------
+%%% Internal functions
+%%--------------------------------------------------------------------
+
+print(Level, _Str, _Args) ->
+ test_server:format(Level, _Str,_Args).
+
+
diff --git a/lib/common_test/vsn.mk b/lib/common_test/vsn.mk
index 8b5d74016a..ee07350c55 100644
--- a/lib/common_test/vsn.mk
+++ b/lib/common_test/vsn.mk
@@ -1,3 +1,3 @@
-COMMON_TEST_VSN = 1.4.6
+COMMON_TEST_VSN = 1.4.7
diff --git a/lib/compiler/doc/src/compile.xml b/lib/compiler/doc/src/compile.xml
index c39c9b25eb..bbd3f1043d 100644
--- a/lib/compiler/doc/src/compile.xml
+++ b/lib/compiler/doc/src/compile.xml
@@ -4,7 +4,7 @@
<erlref>
<header>
<copyright>
- <year>1996</year><year>2009</year>
+ <year>1996</year><year>2010</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
@@ -13,12 +13,12 @@
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>compile</title>
@@ -212,6 +212,12 @@
success.</p>
</item>
+ <tag><c>warnings_as_errors</c></tag>
+ <item>
+ <p>Causes warnings to be treated as errors. This option is supported
+ since R13B04.</p>
+ </item>
+
<tag><c>return</c></tag>
<item>
<p>This is a short form for both <c>return_errors</c> and
@@ -726,7 +732,7 @@ pi() -> 3.1416.
<p>A string describing the error is obtained with the following
call:</p>
<code>
-apply(Module, format_error, ErrorDescriptor)
+Module:format_error(ErrorDescriptor)
</code>
</section>
diff --git a/lib/compiler/doc/src/notes.xml b/lib/compiler/doc/src/notes.xml
index 7d1913d740..7ea000a895 100644
--- a/lib/compiler/doc/src/notes.xml
+++ b/lib/compiler/doc/src/notes.xml
@@ -4,7 +4,7 @@
<chapter>
<header>
<copyright>
- <year>2004</year><year>2009</year>
+ <year>2004</year><year>2010</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
@@ -13,12 +13,12 @@
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>Compiler Release Notes</title>
@@ -31,6 +31,69 @@
<p>This document describes the changes made to the Compiler
application.</p>
+<section><title>Compiler 4.6.5</title>
+
+ <section><title>Fixed Bugs and Malfunctions</title>
+ <list>
+ <item>
+ <p>
+ Using complex boolean expressions in ifs could cause the
+ compiler to either crash or teminate with an internal
+ error. (Thanks to Simon Cornish.)</p>
+ <p>
+ Own Id: OTP-8338</p>
+ </item>
+ <item>
+ <p>Bit string comprehensions can now be used in
+ parameterized modules. (Thanks to Jebu Ittiachen.)</p>
+ <p>
+ Own Id: OTP-8447</p>
+ </item>
+ </list>
+ </section>
+
+
+ <section><title>Improvements and New Features</title>
+ <list>
+ <item>
+ <p>
+ The expected return value for an on_load function has
+ been changed. (See the section about code loading in the
+ Reference manual.)</p>
+ <p>
+ *** POTENTIAL INCOMPATIBILITY ***</p>
+ <p>
+ Own Id: OTP-8339</p>
+ </item>
+ <item>
+ <p>
+ In rare circumstances when using garbaging collecting
+ guard BIFs, the validation pass (beam_validator) would
+ signal that the code was unsafe, when it in fact was
+ correct. (Thanks to Kiran Khaladkar.)</p>
+ <p>
+ Own Id: OTP-8378</p>
+ </item>
+ <item>
+ <p>
+ The <c>-Werror</c> option for <c>erlc</c> and the
+ compiler option <c>warnings_as_errors</c> will cause
+ warnings to be treated as errors. (Thanks to Christopher
+ Faulet.)</p>
+ <p>
+ Own Id: OTP-8382</p>
+ </item>
+ <item>
+ <p>Macros overloading has been implemented. (Thanks to
+ Christopher Faulet.)</p>
+ <p>
+ Own Id: OTP-8388</p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
<section><title>Compiler 4.6.4</title>
<section><title>Fixed Bugs and Malfunctions</title>
diff --git a/lib/compiler/src/Makefile b/lib/compiler/src/Makefile
index fde2b1a655..70ddd54145 100644
--- a/lib/compiler/src/Makefile
+++ b/lib/compiler/src/Makefile
@@ -1,19 +1,19 @@
#
# %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
# 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%
#
@@ -45,46 +45,46 @@ RELSYSDIR = $(RELEASE_PATH)/lib/compiler-$(VSN)
# Target Specs
# ----------------------------------------------------
MODULES = \
- compile \
- sys_pre_attributes \
- sys_pre_expand \
- sys_expand_pmod \
- v3_core \
- sys_core_fold \
- sys_core_inline \
- sys_core_dsetel \
- core_lib \
- core_scan \
- core_parse \
- core_lint \
- core_pp \
- v3_kernel \
- v3_kernel_pp \
- v3_life \
- v3_codegen \
+ beam_asm \
beam_block \
beam_bool \
- beam_dead \
- beam_jump \
- beam_type \
- beam_clean \
- beam_peep \
beam_bsm \
- beam_trim \
+ beam_clean \
+ beam_dead \
+ beam_dict \
+ beam_disasm \
beam_flatten \
+ beam_jump \
beam_listing \
- beam_asm \
- beam_dict \
beam_opcodes \
- beam_disasm \
+ beam_peep \
+ beam_trim \
+ beam_type \
beam_utils \
beam_validator \
- erl_bifs \
cerl \
cerl_clauses \
cerl_inline \
cerl_trees \
- rec_env
+ compile \
+ core_lib \
+ core_lint \
+ core_parse \
+ core_pp \
+ core_scan \
+ erl_bifs \
+ rec_env \
+ sys_core_dsetel \
+ sys_core_fold \
+ sys_core_inline \
+ sys_expand_pmod \
+ sys_pre_attributes \
+ sys_pre_expand \
+ v3_codegen \
+ v3_core \
+ v3_kernel \
+ v3_kernel_pp \
+ v3_life
BEAM_H = $(wildcard ../priv/beam_h/*.h)
@@ -114,6 +114,9 @@ APPUP_TARGET= $(EBIN)/$(APPUP_FILE)
# FLAGS
# ----------------------------------------------------
+ifeq ($(NATIVE_LIBS_ENABLED),yes)
+ERL_COMPILE_FLAGS += +native
+endif
ERL_COMPILE_FLAGS += +inline +warn_unused_import -I../../stdlib/include -I$(EGEN) -W
# ----------------------------------------------------
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/src/beam_validator.erl b/lib/compiler/src/beam_validator.erl
index 08ba9c3ee4..1fd61831e0 100644
--- a/lib/compiler/src/beam_validator.erl
+++ b/lib/compiler/src/beam_validator.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2004-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 2004-2010. All Rights Reserved.
+%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
-%%
+%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
-%%
+%%
%% %CopyrightEnd%
-module(beam_validator).
@@ -604,9 +604,9 @@ valfun_4({gc_bif,Op,{f,Fail},Live,Src,Dst}, #vst{current=St0}=Vst0) ->
St = kill_heap_allocation(St0),
Vst1 = Vst0#vst{current=St},
verify_live(Live, Vst1),
- Vst2 = prune_x_regs(Live, Vst1),
- validate_src(Src, Vst2),
- Vst = branch_state(Fail, Vst2),
+ Vst2 = branch_state(Fail, Vst1),
+ Vst = prune_x_regs(Live, Vst2),
+ validate_src(Src, Vst),
Type = bif_type(Op, Src, Vst),
set_type_reg(Type, Dst, Vst);
valfun_4(return, #vst{current=#st{numy=none}}=Vst) ->
diff --git a/lib/compiler/src/compile.erl b/lib/compiler/src/compile.erl
index e725083a9f..b853800d73 100644
--- a/lib/compiler/src/compile.erl
+++ b/lib/compiler/src/compile.erl
@@ -1,19 +1,19 @@
%%
%% %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
%% 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: Run the Erlang compiler.
@@ -187,9 +187,9 @@ format_error(no_crypto_key) ->
format_error({native, E}) ->
io_lib:fwrite("native-code compilation failed with reason: ~P.",
[E, 25]);
-format_error({native_crash, E}) ->
- io_lib:fwrite("native-code compilation crashed with reason: ~P.",
- [E, 25]);
+format_error({native_crash,E,Stk}) ->
+ io_lib:fwrite("native-code compilation crashed with reason: ~P.\n~P\n",
+ [E,25,Stk,25]);
format_error({open,E}) ->
io_lib:format("open error '~s'", [file:format_error(E)]);
format_error({epp,E}) ->
@@ -302,7 +302,7 @@ os_process_size() ->
list_to_integer(lib:nonl(Size));
_ ->
0
- end.
+ end.
run_tc({Name,Fun}, St) ->
Before0 = statistics(runtime),
@@ -318,17 +318,30 @@ run_tc({Name,Fun}, St) ->
Val.
comp_ret_ok(#compile{code=Code,warnings=Warn0,module=Mod,options=Opts}=St) ->
- Warn = messages_per_file(Warn0),
- report_warnings(St#compile{warnings = Warn}),
- Ret1 = case member(binary, Opts) andalso not member(no_code_generation, Opts) of
- true -> [Code];
- false -> []
- end,
- Ret2 = case member(return_warnings, Opts) of
- true -> Ret1 ++ [Warn];
- false -> Ret1
- end,
- list_to_tuple([ok,Mod|Ret2]).
+ case member(warnings_as_errors, Opts) andalso length(Warn0) > 0 of
+ true ->
+ case member(report_warnings, Opts) of
+ true ->
+ io:format("~p: warnings being treated as errors\n",
+ [?MODULE]);
+ false ->
+ ok
+ end,
+ comp_ret_err(St);
+ false ->
+ Warn = messages_per_file(Warn0),
+ report_warnings(St#compile{warnings = Warn}),
+ Ret1 = case member(binary, Opts) andalso
+ not member(no_code_generation, Opts) of
+ true -> [Code];
+ false -> []
+ end,
+ Ret2 = case member(return_warnings, Opts) of
+ true -> Ret1 ++ [Warn];
+ false -> Ret1
+ end,
+ list_to_tuple([ok,Mod|Ret2])
+ end.
comp_ret_err(#compile{warnings=Warn0,errors=Err0,options=Opts}=St) ->
Warn = messages_per_file(Warn0),
@@ -344,18 +357,18 @@ comp_ret_err(#compile{warnings=Warn0,errors=Err0,options=Opts}=St) ->
messages_per_file(Ms) ->
T = lists:sort([{File,M} || {File,Messages} <- Ms, M <- Messages]),
PrioMs = [erl_scan, epp, erl_parse],
- {Prio0, Rest} =
+ {Prio0, Rest} =
lists:mapfoldl(fun(M, A) ->
lists:partition(fun({_,{_,Mod,_}}) -> Mod =:= M;
(_) -> false
end, A)
end, T, PrioMs),
- Prio = lists:sort(fun({_,{L1,_,_}}, {_,{L2,_,_}}) -> L1 =< L2 end,
+ Prio = lists:sort(fun({_,{L1,_,_}}, {_,{L2,_,_}}) -> L1 =< L2 end,
lists:append(Prio0)),
flatmap(fun mpf/1, [Prio, Rest]).
mpf(Ms) ->
- [{File,[M || {F,M} <- Ms, F =:= File]} ||
+ [{File,[M || {F,M} <- Ms, F =:= File]} ||
File <- lists:usort([F || {F,_} <- Ms])].
%% passes(form|file, [Option]) -> [{Name,PassFun}]
@@ -495,14 +508,14 @@ select_passes([List|Ps], Opts) when is_list(List) ->
select_cond(Flag, ShouldBe, Pass, Ps, Opts) ->
ShouldNotBe = not ShouldBe,
- case member(Flag, Opts) of
+ case member(Flag, Opts) of
ShouldBe -> select_passes([Pass|Ps], Opts);
ShouldNotBe -> select_passes(Ps, Opts)
end.
%% select_list_passes([Pass], Opts) -> {done,[Pass]} | {not_done,[Pass]}
%% Evaluate all conditions having to do with listings in the list of
-%% passes.
+%% passes.
select_list_passes(Ps, Opts) ->
select_list_passes_1(Ps, Opts, []).
@@ -704,7 +717,7 @@ read_beam_file(St) ->
case file:read_file(St#compile.ifile) of
{ok,Beam} ->
Infile = St#compile.ifile,
- case is_too_old(Infile) of
+ case no_native_compilation(Infile, St) of
true ->
{ok,St#compile{module=none,code=none}};
false ->
@@ -717,12 +730,15 @@ read_beam_file(St) ->
{error,St#compile{errors=St#compile.errors ++ Es}}
end.
-is_too_old(BeamFile) ->
+no_native_compilation(BeamFile, #compile{options=Opts0}) ->
case beam_lib:chunks(BeamFile, ["CInf"]) of
{ok,{_,[{"CInf",Term0}]}} ->
Term = binary_to_term(Term0),
- Opts = proplists:get_value(options, Term, []),
- lists:member(no_new_funs, Opts);
+
+ %% Compiler options in the beam file will override
+ %% options passed to the compiler.
+ Opts = proplists:get_value(options, Term, []) ++ Opts0,
+ member(no_new_funs, Opts) orelse not is_native_enabled(Opts);
_ -> false
end.
@@ -782,7 +798,7 @@ clean_parse_transforms_1([F|Fs], Acc) ->
clean_parse_transforms_1(Fs, [F|Acc]);
clean_parse_transforms_1([], Acc) -> reverse(Acc).
-transforms(Os) -> [ M || {parse_transform,M} <- Os ].
+transforms(Os) -> [ M || {parse_transform,M} <- Os ].
transform_module(#compile{options=Opt,code=Code0}=St0) ->
%% Extract compile options from code into options field.
@@ -815,7 +831,7 @@ foldl_transform(St, [T|Ts]) ->
end;
foldl_transform(St, []) -> {ok,St}.
-get_core_transforms(Opts) -> [M || {core_transform,M} <- Opts].
+get_core_transforms(Opts) -> [M || {core_transform,M} <- Opts].
core_transforms(St) ->
%% The options field holds the complete list of options at this
@@ -1033,7 +1049,14 @@ beam_asm(#compile{ifile=File,code=Code0,abstract_code=Abst,options=Opts0}=St) ->
test_native(#compile{options=Opts}) ->
%% This test is done late, in case some other option has turned off native.
- member(native, Opts).
+ %% 'native' given on the command line can be overridden by
+ %% 'no_native' in the module itself.
+ is_native_enabled(Opts).
+
+is_native_enabled([native|_]) -> true;
+is_native_enabled([no_native|_]) -> false;
+is_native_enabled([_|Opts]) -> is_native_enabled(Opts);
+is_native_enabled([]) -> false.
native_compile(#compile{code=none}=St) -> {ok,St};
native_compile(St) ->
@@ -1057,25 +1080,27 @@ native_compile_1(St) ->
St#compile.core_code,
St#compile.code,
Opts) of
- {ok, {_Type,Bin} = T} when is_binary(Bin) ->
- {ok, embed_native_code(St, T)};
- {error, R} ->
+ {ok,{_Type,Bin}=T} when is_binary(Bin) ->
+ {ok,embed_native_code(St, T)};
+ {error,R} ->
case IgnoreErrors of
true ->
- Ws = [{St#compile.ifile,[{none,?MODULE,{native,R}}]}],
- {ok, St#compile{warnings=St#compile.warnings ++ Ws}};
+ Ws = [{St#compile.ifile,[{?MODULE,{native,R}}]}],
+ {ok,St#compile{warnings=St#compile.warnings ++ Ws}};
false ->
- Es = [{St#compile.ifile,[{none,?MODULE,{native,R}}]}],
- {error, St#compile{errors=St#compile.errors ++ Es}}
+ Es = [{St#compile.ifile,[{?MODULE,{native,R}}]}],
+ {error,St#compile{errors=St#compile.errors ++ Es}}
end
catch
- error:R ->
+ Class:R ->
+ Stk = erlang:get_stacktrace(),
case IgnoreErrors of
true ->
- Ws = [{St#compile.ifile,[{none,?MODULE,{native_crash,R}}]}],
- {ok, St#compile{warnings=St#compile.warnings ++ Ws}};
+ Ws = [{St#compile.ifile,
+ [{?MODULE,{native_crash,R,Stk}}]}],
+ {ok,St#compile{warnings=St#compile.warnings ++ Ws}};
false ->
- exit(R)
+ erlang:raise(Class, R, Stk)
end
end.
@@ -1264,7 +1289,7 @@ listing(Ext, St) ->
listing(LFun, Ext, St) ->
Lfile = outfile(St#compile.base, Ext, St#compile.options),
case file:open(Lfile, [write,delayed_write]) of
- {ok,Lf} ->
+ {ok,Lf} ->
Code = restore_expanded_types(Ext, St#compile.code),
LFun(Lf, Code),
ok = file:close(Lf),
diff --git a/lib/compiler/src/sys_expand_pmod.erl b/lib/compiler/src/sys_expand_pmod.erl
index dbd5c1ec2f..4fee26f2a6 100644
--- a/lib/compiler/src/sys_expand_pmod.erl
+++ b/lib/compiler/src/sys_expand_pmod.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2004-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 2004-2010. All Rights Reserved.
+%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
-%%
+%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
-%%
+%%
%% %CopyrightEnd%
%%
-module(sys_expand_pmod).
@@ -283,9 +283,13 @@ expr({cons,Line,H0,T0},St) ->
T1 = expr(T0,St),
{cons,Line,H1,T1};
expr({lc,Line,E0,Qs0},St) ->
- Qs1 = lc_quals(Qs0,St),
+ Qs1 = lc_bc_quals(Qs0,St),
E1 = expr(E0,St),
{lc,Line,E1,Qs1};
+expr({bc,Line,E0,Qs0},St) ->
+ Qs1 = lc_bc_quals(Qs0,St),
+ E1 = expr(E0,St),
+ {bc,Line,E1,Qs1};
expr({tuple,Line,Es0},St) ->
Es1 = expr_list(Es0,St),
{tuple,Line,Es1};
@@ -391,14 +395,18 @@ icr_clauses([C0|Cs],St) ->
[C1|icr_clauses(Cs,St)];
icr_clauses([],_St) -> [].
-lc_quals([{generate,Line,P0,E0}|Qs],St) ->
+lc_bc_quals([{generate,Line,P0,E0}|Qs],St) ->
+ E1 = expr(E0,St),
+ P1 = pattern(P0,St),
+ [{generate,Line,P1,E1}|lc_bc_quals(Qs,St)];
+lc_bc_quals([{b_generate,Line,P0,E0}|Qs],St) ->
E1 = expr(E0,St),
P1 = pattern(P0,St),
- [{generate,Line,P1,E1}|lc_quals(Qs,St)];
-lc_quals([E0|Qs],St) ->
+ [{b_generate,Line,P1,E1}|lc_bc_quals(Qs,St)];
+lc_bc_quals([E0|Qs],St) ->
E1 = expr(E0,St),
- [E1|lc_quals(Qs,St)];
-lc_quals([],_St) -> [].
+ [E1|lc_bc_quals(Qs,St)];
+lc_bc_quals([],_St) -> [].
fun_clauses([C0|Cs],St) ->
C1 = clause(C0,St),
diff --git a/lib/compiler/src/sys_pre_expand.erl b/lib/compiler/src/sys_pre_expand.erl
index 78dd73e0a2..f80d03dfac 100644
--- a/lib/compiler/src/sys_pre_expand.erl
+++ b/lib/compiler/src/sys_pre_expand.erl
@@ -1,19 +1,19 @@
%%
%% %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
%% 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 : Expand some source Erlang constructions. This is part of the
@@ -114,7 +114,7 @@ expand_pmod(Fs0, St0) ->
St1 = St0#expand{exports=Xs, defined=Ds},
{Fs2,St2} = add_instance(Ps, Fs1, St1),
{Fs3,St3} = ensure_new(Base, Ps0, Fs2, St2),
- {Fs3,St3#expand{attributes = [{abstract, [true]}
+ {Fs3,St3#expand{attributes = [{abstract, 0, [true]}
| St3#expand.attributes]}}
end.
@@ -173,7 +173,7 @@ define_functions(Forms, #expand{defined=Predef}=St) ->
St#expand{defined=ordsets:from_list(Fs)}.
module_attrs(St) ->
- {[{attribute,0,Name,Val} || {Name,Val} <- St#expand.attributes],St}.
+ {[{attribute,Line,Name,Val} || {Name,Line,Val} <- St#expand.attributes],St}.
module_predef_funcs(St) ->
PreDef = [{module_info,0},{module_info,1}],
@@ -197,8 +197,8 @@ module_predef_funcs(St) ->
forms([{attribute,_,file,_File}=F|Fs0], St0) ->
{Fs,St1} = forms(Fs0, St0),
{[F|Fs],St1};
-forms([{attribute,_,Name,Val}|Fs0], St0) ->
- St1 = attribute(Name, Val, St0),
+forms([{attribute,Line,Name,Val}|Fs0], St0) ->
+ St1 = attribute(Name, Val, Line, St0),
forms(Fs0, St1);
forms([{function,L,N,A,Cs}|Fs0], St0) ->
{Ff,St1} = function(L, N, A, Cs, St0),
@@ -207,30 +207,30 @@ forms([{function,L,N,A,Cs}|Fs0], St0) ->
forms([_|Fs], St) -> forms(Fs, St);
forms([], St) -> {[],St}.
-%% attribute(Attribute, Value, State) -> State'.
+%% attribute(Attribute, Value, Line, State) -> State'.
%% Process an attribute, this just affects the state.
-attribute(module, {Module, As}, St) ->
+attribute(module, {Module, As}, _L, St) ->
M = package_to_string(Module),
St#expand{module=list_to_atom(M),
- package = packages:strip_last(M),
+ package=packages:strip_last(M),
parameters=As};
-attribute(module, Module, St) ->
+attribute(module, Module, _L, St) ->
M = package_to_string(Module),
St#expand{module=list_to_atom(M),
- package = packages:strip_last(M)};
-attribute(export, Es, St) ->
+ package=packages:strip_last(M)};
+attribute(export, Es, _L, St) ->
St#expand{exports=union(from_list(Es), St#expand.exports)};
-attribute(import, Is, St) ->
+attribute(import, Is, _L, St) ->
import(Is, St);
-attribute(compile, C, St) when is_list(C) ->
+attribute(compile, C, _L, St) when is_list(C) ->
St#expand{compile=St#expand.compile ++ C};
-attribute(compile, C, St) ->
+attribute(compile, C, _L, St) ->
St#expand{compile=St#expand.compile ++ [C]};
-attribute(Name, Val, St) when is_list(Val) ->
- St#expand{attributes=St#expand.attributes ++ [{Name,Val}]};
-attribute(Name, Val, St) ->
- St#expand{attributes=St#expand.attributes ++ [{Name,[Val]}]}.
+attribute(Name, Val, Line, St) when is_list(Val) ->
+ St#expand{attributes=St#expand.attributes ++ [{Name,Line,Val}]};
+attribute(Name, Val, Line, St) ->
+ St#expand{attributes=St#expand.attributes ++ [{Name,Line,[Val]}]}.
function(L, N, A, Cs0, St0) ->
{Cs,St} = clauses(Cs0, St0#expand{func=N,arity=A,fcount=0}),
@@ -299,10 +299,10 @@ pattern({match,Line,Pat1, Pat2}, St0) ->
{TT,St2} = pattern(Pat1, St1),
{{match,Line,TT,TH},St2};
%% Compile-time pattern expressions, including unary operators.
-pattern({op,Line,Op,A}, St) ->
- {erl_eval:partial_eval({op,Line,Op,A}),St};
-pattern({op,Line,Op,L,R}, St) ->
- {erl_eval:partial_eval({op,Line,Op,L,R}),St}.
+pattern({op,_Line,_Op,_A}=Op, St) ->
+ {erl_eval:partial_eval(Op),St};
+pattern({op,_Line,_Op,_L,_R}=Op, St) ->
+ {erl_eval:partial_eval(Op),St}.
pattern_list([P0|Ps0], St0) ->
{P,St1} = pattern(P0, St0),
@@ -400,18 +400,18 @@ expr({'receive',Line,Cs0,To0,ToEs0}, St0) ->
{{'receive',Line,Cs,To,ToEs},St3};
expr({'fun',Line,Body}, St) ->
fun_tq(Line, Body, St);
-expr({call,Line,{atom,La,N},As0}, St0) ->
+expr({call,Line,{atom,La,N}=Atom,As0}, St0) ->
{As,St1} = expr_list(As0, St0),
Ar = length(As),
case erl_internal:bif(N, Ar) of
true ->
- {{call,Line,{remote,La,{atom,La,erlang},{atom,La,N}},As},St1};
+ {{call,Line,{remote,La,{atom,La,erlang},Atom},As},St1};
false ->
case imported(N, Ar, St1) of
{yes,Mod} ->
- {{call,Line,{remote,La,{atom,La,Mod},{atom,La,N}},As},St1};
+ {{call,Line,{remote,La,{atom,La,Mod},Atom},As},St1};
no ->
- {{call,Line,{atom,La,N},As},St1}
+ {{call,Line,Atom,As},St1}
end
end;
expr({call,Line,{record_field,_,_,_}=M,As0}, St0) ->
diff --git a/lib/compiler/src/v3_core.erl b/lib/compiler/src/v3_core.erl
index a39a3c538f..dfe15de4ff 100644
--- a/lib/compiler/src/v3_core.erl
+++ b/lib/compiler/src/v3_core.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 1999-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 1999-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%
%%
%% Purpose : Transform normal Erlang to Core Erlang
@@ -164,8 +164,8 @@ form({attribute,_,file,{File,_Line}}, {Fs,As,Es,Ws,_}, _Opts) ->
form({attribute,_,_,_}=F, {Fs,As,Es,Ws,File}, _Opts) ->
{Fs,[attribute(F)|As],Es,Ws,File}.
-attribute({attribute,_,Name,Val}) ->
- {#c_literal{val=Name},#c_literal{val=Val}}.
+attribute({attribute,Line,Name,Val}) ->
+ {#c_literal{val=Name, anno=[Line]}, #c_literal{val=Val, anno=[Line]}}.
function({function,_,Name,Arity,Cs0}, Es0, Ws0, File, Opts) ->
%%ok = io:fwrite("~p - ", [{Name,Arity}]),
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/beam_validator_SUITE.erl b/lib/compiler/test/beam_validator_SUITE.erl
index ef8feb8a27..74b5d7c7eb 100644
--- a/lib/compiler/test/beam_validator_SUITE.erl
+++ b/lib/compiler/test/beam_validator_SUITE.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2004-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 2004-2010. All Rights Reserved.
+%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
-%%
+%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
-%%
+%%
%% %CopyrightEnd%
%%
-module(beam_validator_SUITE).
@@ -28,7 +28,7 @@
freg_range/1,freg_uninit/1,freg_state/1,
bin_match/1,bin_aligned/1,bad_dsetel/1,
state_after_fault_in_catch/1,no_exception_in_catch/1,
- undef_label/1,illegal_instruction/1]).
+ undef_label/1,illegal_instruction/1,failing_gc_guard_bif/1]).
-include("test_server.hrl").
@@ -52,13 +52,13 @@ all(suite) ->
freg_range,freg_uninit,freg_state,
bin_match,bin_aligned,
bad_dsetel,state_after_fault_in_catch,no_exception_in_catch,
- undef_label,illegal_instruction].
+ undef_label,illegal_instruction,failing_gc_guard_bif].
beam_files(Config) when is_list(Config) ->
?line {ok,Cwd} = file:get_cwd(),
?line Parent = filename:dirname(Cwd),
?line Wc = filename:join([Parent,"*","*.beam"]),
- %% Must have at least two files here, or there will could be
+ %% Must have at least two files here, or there will be
%% a grammatical error in the output of the io:format/2 call below. ;-)
?line [_,_|_] = Fs = filelib:wildcard(Wc),
?line io:format("~p files\n", [length(Fs)]),
@@ -356,6 +356,36 @@ illegal_instruction(Config) when is_list(Config) ->
{{'_',y,0},{[],0,illegal_instruction}}] = Errors,
ok.
+%% The beam_validator used to assume that a GC guard BIF could
+%% do a garbage collection even if it failed. That assumption
+%% is not correct, and will cause the beam_validator to reject
+%% valid programs such as this test case.
+%%
+%% (Thanks to Kiran Khaladkar.)
+%%
+failing_gc_guard_bif(Config) when is_list(Config) ->
+ ?line ok = process_request(lists:seq(1, 36)),
+ ?line error = process_request([]),
+ ?line error = process_request(not_a_list),
+ ok.
+
+process_request(ConfId) ->
+ case process_request_foo(ConfId) of
+ false ->
+ if
+ length(ConfId) == 36 ->
+ Response = ok;
+ true ->
+ Response = error
+ end
+ end,
+ process_request_bar(self(), [Response]).
+
+process_request_foo(_) ->
+ false.
+
+process_request_bar(Pid, [Response]) when is_pid(Pid) ->
+ Response.
%%%-------------------------------------------------------------------------
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/compiler/test/error_SUITE.erl b/lib/compiler/test/error_SUITE.erl
index 477730c3ac..cdd2434b25 100644
--- a/lib/compiler/test/error_SUITE.erl
+++ b/lib/compiler/test/error_SUITE.erl
@@ -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%
%%
-module(error_SUITE).
@@ -21,11 +21,11 @@
-include("test_server.hrl").
-export([all/1,
- head_mismatch_line/1,r11b_binaries/1]).
+ head_mismatch_line/1,r11b_binaries/1,warnings_as_errors/1]).
all(suite) ->
test_lib:recompile(?MODULE),
- [head_mismatch_line,r11b_binaries].
+ [head_mismatch_line,r11b_binaries,warnings_as_errors].
%% Tests that a head mismatch is reported on the correct line (OTP-2125).
head_mismatch_line(Config) when is_list(Config) ->
@@ -73,6 +73,20 @@ r11b_binaries(Config) when is_list(Config) ->
?line [] = run(Config, Ts),
ok.
+warnings_as_errors(Config) when is_list(Config) ->
+ Ts = [{warnings_as_errors,
+ <<"
+ t() ->
+ A = unused,
+ ok.
+ ">>,
+ [warnings_as_errors],
+ {error,
+ [],
+ [{3,erl_lint,{unused_var,'A'}}]} }],
+ ?line [] = run(Config, Ts),
+ ok.
+
run(Config, Tests) ->
F = fun({N,P,Ws,E}, BadL) ->
@@ -104,6 +118,8 @@ run_test(Conf, Test0, Warnings) ->
%% Test result of compilation.
?line Res = case compile:file(File, Opts) of
{error,[{_File,Es}],Ws} ->
+ {error,Es,Ws};
+ {error,Es,[{_File,Ws}]} ->
{error,Es,Ws}
end,
file:delete(File),
diff --git a/lib/compiler/test/pmod_SUITE.erl b/lib/compiler/test/pmod_SUITE.erl
index c8919e5539..293e110c45 100644
--- a/lib/compiler/test/pmod_SUITE.erl
+++ b/lib/compiler/test/pmod_SUITE.erl
@@ -1,31 +1,31 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2004-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 2004-2010. All Rights Reserved.
+%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
-%%
+%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
-%%
+%%
%% %CopyrightEnd%
%%
-module(pmod_SUITE).
-export([all/1,init_per_testcase/2,fin_per_testcase/2,
- basic/1]).
+ basic/1, otp_8447/1]).
-include("test_server.hrl").
all(suite) ->
test_lib:recompile(?MODULE),
- [basic].
+ [basic, otp_8447].
init_per_testcase(Case, Config) when is_atom(Case), is_list(Config) ->
Dog = test_server:timetrap(?t:minutes(1)),
@@ -38,8 +38,8 @@ fin_per_testcase(Case, Config) when is_atom(Case), is_list(Config) ->
basic(Config) when is_list(Config) ->
?line basic_1(Config, []),
- ?line basic_1(Config, [inline]),
- ?line basic_1(Config, [{inline,500}]),
+% ?line basic_1(Config, [inline]),
+% ?line basic_1(Config, [{inline,500},inline]),
ok.
basic_1(Config, Opts) ->
@@ -78,6 +78,12 @@ basic_1(Config, Opts) ->
ok.
+otp_8447(Config) when is_list(Config) ->
+ ?line P = pmod_basic:new(foo),
+ ?line [0,0,1,1,1,0,0,1] = P:bc1(),
+ ?line <<10:4>> = P:bc2(),
+ ok.
+
compile_load(Module, Conf, Opts) ->
?line Dir = ?config(data_dir,Conf),
?line Src = filename:join(Dir, atom_to_list(Module)),
diff --git a/lib/compiler/test/pmod_SUITE_data/pmod_basic.erl b/lib/compiler/test/pmod_SUITE_data/pmod_basic.erl
index e6f4c63421..0d46cffe00 100644
--- a/lib/compiler/test/pmod_SUITE_data/pmod_basic.erl
+++ b/lib/compiler/test/pmod_SUITE_data/pmod_basic.erl
@@ -1,25 +1,26 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2004-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 2004-2010. All Rights Reserved.
+%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
-%%
+%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
-%%
+%%
%% %CopyrightEnd%
%%
-module(pmod_basic, [Props]).
-export([lookup/1,or_props/1,prepend/1,append/1,stupid_sum/0]).
-export([bar/1,bar_bar/1]).
+-export([bc1/0, bc2/0]).
lookup(Key) ->
proplists:lookup(Key, Props).
@@ -70,3 +71,9 @@ bar(S) when S#s.a == 0 -> ok.
bar_bar(S) when is_record(S, s) -> ok;
bar_bar(_) -> error.
+
+bc1() ->
+ [A || <<A:1>> <= <<"9">> ].
+
+bc2() ->
+ << <<A:1>> || A <- [1,0,1,0] >>.
diff --git a/lib/compiler/vsn.mk b/lib/compiler/vsn.mk
index 72abcdde10..a5e6de7b5f 100644
--- a/lib/compiler/vsn.mk
+++ b/lib/compiler/vsn.mk
@@ -1 +1 @@
-COMPILER_VSN = 4.6.4
+COMPILER_VSN = 4.6.5
diff --git a/lib/configure.in b/lib/configure.in
deleted file mode 100644
index 7732556c46..0000000000
--- a/lib/configure.in
+++ /dev/null
@@ -1,37 +0,0 @@
-dnl Turn of caching
-define([AC_CACHE_LOAD], )dnl
-define([AC_CACHE_SAVE], )dnl
-
-dnl Process this file with autoconf to produce a configure script.
-AC_INIT
-
-dnl
-dnl This is just to run configure in all applications that need it.
-dnl
-
-if test -z "$ERL_TOP" || test ! -d $ERL_TOP ; then
- AC_MSG_ERROR(You need to set the environment variable ERL_TOP!)
-fi
-erl_top=${ERL_TOP}
-AC_CONFIG_AUX_DIRS($erl_top/erts/autoconf)
-
-dnl Version 2.55 of autoconf generate code that assume a
-dnl sub directory isn't a link. Internally at Ericsson
-dnl some OTP application directories are soft links.
-dnl An added "/." solves this problem.
-dnl
-dnl The arguments to AC_CONFIG_SUBDIRS should be literals
-dnl but a bug in autoconf 2.13 breaks conditional use
-dnl of multiple AC_CONFIG_SUBDIRS so we do it the "wrong"
-dnl way to force correct code.
-
-appdirs=""
-for d in * ; do
- if test -f "$d/configure" ; then
- appdirs="$appdirs $d/."
- fi
-done
-
-AC_CONFIG_SUBDIRS($appdirs)
-
-AC_OUTPUT
diff --git a/lib/configure.in.src b/lib/configure.in.src
new file mode 100644
index 0000000000..792a7f932a
--- /dev/null
+++ b/lib/configure.in.src
@@ -0,0 +1,61 @@
+dnl
+dnl %CopyrightBegin%
+dnl
+dnl Copyright Ericsson AB 1999-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 Software distributed under the License is distributed on an "AS IS"
+dnl basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+dnl the License for the specific language governing rights and limitations
+dnl under the License.
+dnl
+dnl %CopyrightEnd%
+dnl
+
+dnl Turn of caching
+define([AC_CACHE_LOAD], )dnl
+define([AC_CACHE_SAVE], )dnl
+
+dnl Process this file with autoconf to produce a configure script.
+AC_INIT
+
+dnl
+dnl This is just to run configure in all applications that need it.
+dnl
+
+if test -z "$ERL_TOP" || test ! -d $ERL_TOP ; then
+ AC_MSG_ERROR(You need to set the environment variable ERL_TOP!)
+fi
+erl_top=${ERL_TOP}
+AC_CONFIG_AUX_DIRS($erl_top/erts/autoconf)
+
+AC_ARG_ENABLE(bootstrap-only,
+[ --enable-bootstrap-only enable bootstrap only configuration],
+[ if test "X$enableval" = "Xyes"; then
+ bootstrap_only=yes
+ else
+ bootstrap_only=no
+ fi
+],
+bootstrap_only=no)
+
+# Multiple versions of autoconf generates code that
+# don't work on all platforms (e.g. SunOS 5.8) if
+# sub directories are soft links. Internally at Ericsson
+# some OTP application directories are soft links.
+# An added "/." solves this problem.
+
+@BOOTSTRAP_CONFIGURE_APPS@
+
+if test $bootstrap_only = no; then
+
+@NON_BOOTSTRAP_CONFIGURE_APPS@
+
+fi
+
+AC_OUTPUT
diff --git a/lib/cosEvent/doc/src/CosEventChannelAdmin.xml b/lib/cosEvent/doc/src/CosEventChannelAdmin.xml
index 25f2dc805b..c599a92ff1 100644
--- a/lib/cosEvent/doc/src/CosEventChannelAdmin.xml
+++ b/lib/cosEvent/doc/src/CosEventChannelAdmin.xml
@@ -4,23 +4,21 @@
<erlref>
<header>
<copyright>
- <year>1997</year>
- <year>2007</year>
- <holder>Ericsson AB, All Rights Reserved</holder>
+ <year>1997</year><year>2010</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/.
+ The 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.
+ 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>CosEventChannelAdmin</title>
@@ -73,8 +71,6 @@
<item>SupplierAdmin</item>
<item>EventChannel</item>
</list>
- <p>IDL specification for CosEventChannelAdmin:</p>
- <codeinclude file="../../src/CosEventChannelAdmin.idl" tag="" type="c"></codeinclude>
</description>
</erlref>
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..78299a38dc 100644
--- a/lib/cosEvent/doc/src/notes.xml
+++ b/lib/cosEvent/doc/src/notes.xml
@@ -4,7 +4,7 @@
<chapter>
<header>
<copyright>
- <year>1999</year><year>2009</year>
+ <year>1999</year><year>2010</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
@@ -13,12 +13,12 @@
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>cosEvent Release Notes</title>
@@ -33,6 +33,32 @@
</header>
<section>
+ <title>cosEvent 2.1.8</title>
+
+ <section>
+ <title>Improvements and New Features</title>
+ <list type="bulleted">
+ <item>
+ <p>
+ Removed the usage of the codeinclude tag in the documentation.</p>
+ <p>
+ Own Id: OTP-8409 Aux Id:</p>
+ </item>
+ </list>
+ </section>
+
+ <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/test/Makefile b/lib/cosEvent/test/Makefile
new file mode 100644
index 0000000000..3d95075ee1
--- /dev/null
+++ b/lib/cosEvent/test/Makefile
@@ -0,0 +1,154 @@
+#
+# %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 $(ERL_TOP)/make/target.mk
+include $(ERL_TOP)/make/$(TARGET)/otp.mk
+
+# ----------------------------------------------------
+# Application version
+# ----------------------------------------------------
+include ../vsn.mk
+VSN=$(COSEVENT_VSN)
+# ----------------------------------------------------
+# Release directory specification
+# ----------------------------------------------------
+RELSYSDIR = $(RELEASE_PATH)/cosEvent_test
+
+# ----------------------------------------------------
+# Target Specs
+# ----------------------------------------------------
+TEST_SPEC_FILE = cosEvent.spec
+
+
+IDL_FILES = \
+ event_test_server.idl \
+
+IDLOUTDIR = idl_output
+
+MODULES = \
+ event_test_PushC_impl \
+ event_test_PullC_impl \
+ event_test_PushS_impl \
+ event_test_PullS_impl \
+ event_channel_SUITE \
+ generated_SUITE
+
+GEN_MOD_COS = \
+ event_test_PullC \
+ event_test_PushS \
+ event_test_PullS \
+ oe_event_test_server \
+ event_test_PushC
+
+GEN_HRL_COS = \
+ event_test.hrl \
+ event_test_PushC.hrl \
+ event_test_PullC.hrl \
+ event_test_PushS.hrl \
+ event_test_PullS.hrl \
+ oe_event_test_server.hrl
+
+
+GEN_MODULES = $(GEN_MOD_COS)
+
+ERL_FILES = $(MODULES:%=%.erl)
+
+HRL_FILES =
+
+GEN_HRL_FILES = $(GEN_HRL_COS)
+
+GEN_FILES = \
+ $(GEN_HRL_FILES:%=$(IDLOUTDIR)/%) \
+ $(GEN_MODULES:%=$(IDLOUTDIR)/%.erl)
+
+GEN_TARGET_FILES = $(GEN_MODULES:%=$(IDLOUTDIR)/%.$(EMULATOR))
+
+SUITE_TARGET_FILES = $(MODULES:%=%.$(EMULATOR))
+
+TARGET_FILES = \
+ $(GEN_TARGET_FILES) \
+ $(SUITE_TARGET_FILES)
+
+# ----------------------------------------------------
+# PROGRAMS
+# ----------------------------------------------------
+# ----------------------------------------------------
+# FLAGS
+# ----------------------------------------------------
+ERL_IDL_FLAGS += -pa $(ERL_TOP)/lib/orber/ebin -pa $(ERL_TOP)/lib/ic/ebin
+
+ERL_COMPILE_FLAGS += $(ERL_IDL_FLAGS) \
+ -pa $(ERL_TOP)/lib/test_server/ebin \
+ -pa $(ERL_TOP)/lib/cosEvent/ebin \
+ -pa $(ERL_TOP)/lib/cosEvent/test/idl_output \
+ -I$(ERL_TOP)/lib/cosEvent \
+ -I$(ERL_TOP)/lib/cosEvent/test/$(IDLOUTDIR) \
+ -I$(ERL_TOP)/lib/test_server/include
+
+# ----------------------------------------------------
+# Targets
+# ----------------------------------------------------
+tests debug opt: $(TARGET_FILES)
+
+clean:
+ rm -f idl_output/*
+ rm -rf java_initial_reference_idl java_cos_naming_idl
+ rm -rf java_iiop_module_idl java_output/*
+ rm -f $(TARGET_FILES)
+ rm -f errs core *~
+
+
+docs:
+
+# ----------------------------------------------------
+# Special Targets
+# ----------------------------------------------------
+
+#
+# Each IDL file produces many target files so no pattern
+# rule can be used.
+#
+TGT_COS = \
+ $(GEN_HRL_COS:%=$(IDLOUTDIR)/%) \
+ $(GEN_MOD_COS:%=$(IDLOUTDIR)/%.erl)
+
+
+$(TGT_COS): event_test_server.idl
+ erlc $(ERL_IDL_FLAGS) -o$(IDLOUTDIR) event_test_server.idl
+
+# ----------------------------------------------------
+# Release Targets
+# ----------------------------------------------------
+# We don't copy generated intermediate erlang and hrl files
+
+include $(ERL_TOP)/make/otp_release_targets.mk
+
+release_spec:
+
+release_docs_spec:
+
+release_tests_spec: tests
+ $(INSTALL_DIR) $(RELSYSDIR)
+ $(INSTALL_DATA) $(IDL_FILES) $(TEST_SPEC_FILE) \
+ $(ERL_FILES) $(RELSYSDIR)
+ $(INSTALL_DATA) $(SUITE_TARGET_FILES) $(RELSYSDIR)
+ $(INSTALL_DIR) $(RELSYSDIR)/$(IDLOUTDIR)
+ $(INSTALL_DATA) $(GEN_TARGET_FILES) $(GEN_FILES) \
+ $(RELSYSDIR)/$(IDLOUTDIR)
+
diff --git a/lib/cosEvent/test/cosEvent.spec b/lib/cosEvent/test/cosEvent.spec
new file mode 100644
index 0000000000..910f7a7c28
--- /dev/null
+++ b/lib/cosEvent/test/cosEvent.spec
@@ -0,0 +1,19 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 1999-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%
+%%
+{topcase, {dir, "../cosEvent_test"}}.
diff --git a/lib/cosEvent/test/event_channel_SUITE.erl b/lib/cosEvent/test/event_channel_SUITE.erl
new file mode 100644
index 0000000000..2b0cf1fe30
--- /dev/null
+++ b/lib/cosEvent/test/event_channel_SUITE.erl
@@ -0,0 +1,316 @@
+%%-----------------------------------------------------------------
+%%
+%% %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(event_channel_SUITE).
+
+-include("test_server.hrl").
+-include_lib("orber/include/corba.hrl").
+-include_lib("orber/COSS/CosNaming/CosNaming.hrl").
+-include_lib("orber/src/orber_iiop.hrl").
+
+%%-----------------------------------------------------------------
+%% Macros
+%%-----------------------------------------------------------------
+
+-define(default_timeout, ?t:minutes(5)).
+
+
+-define(match(ExpectedRes, Expr),
+ fun() ->
+ AcTuAlReS = (catch (Expr)),
+ case AcTuAlReS of
+ ExpectedRes ->
+ io:format("------ CORRECT RESULT ------~n~p~n",
+ [AcTuAlReS]),
+ AcTuAlReS;
+ _ ->
+ io:format("###### ERROR ERROR ######~n~p~n",
+ [AcTuAlReS]),
+ ?line exit(AcTuAlReS)
+ end
+ end()).
+
+
+%%-----------------------------------------------------------------
+%% External exports
+%%-----------------------------------------------------------------
+-export([all/1, event_objects_api/1, events_api/1, events_sync_api/1,
+ cases/0, init_all/1, finish_all/1,
+ init_per_testcase/2, fin_per_testcase/2, app_test/1]).
+
+%%-----------------------------------------------------------------
+%% Internal exports
+%%-----------------------------------------------------------------
+
+all(doc) -> ["API tests for the cosEvent interfaces", ""];
+all(suite) -> {req,
+ [mnesia, orber],
+ {conf, init_all, cases(), finish_all}}.
+
+cases() ->
+ [events_api, events_sync_api, event_objects_api, app_test].
+
+%%-----------------------------------------------------------------
+%% Init and cleanup functions.
+%%-----------------------------------------------------------------
+
+init_per_testcase(_Case, Config) ->
+ ?line Dog=test_server:timetrap(?default_timeout),
+ [{watchdog, Dog}|Config].
+
+
+fin_per_testcase(_Case, Config) ->
+ Dog = ?config(watchdog, Config),
+ test_server:timetrap_cancel(Dog),
+ ok.
+
+init_all(Config) when is_list(Config) ->
+ Path = code:which(?MODULE),
+ code:add_pathz(filename:join(filename:dirname(Path), "idl_output")),
+ mnesia:delete_schema([node()]),
+ mnesia:create_schema([node()]),
+ orber:install([node()]),
+ application:start(mnesia),
+ application:start(orber),
+ cosEventApp:install(),
+ cosEventApp:start(),
+ oe_event_test_server:oe_register(),
+ Config.
+
+finish_all(Config) when is_list(Config) ->
+ oe_event_test_server:oe_unregister(),
+ cosEventApp:stop(),
+ cosEventApp:uninstall(),
+ application:stop(orber),
+ application:stop(mnesia),
+ mnesia:delete_schema([node()]),
+ Path = code:which(?MODULE),
+ code:del_path(filename:join(filename:dirname(Path), "idl_output")),
+ Config.
+
+%%-----------------------------------------------------------------
+%% Tests app file
+%%-----------------------------------------------------------------
+app_test(doc) -> [];
+app_test(suite) -> [];
+app_test(_Config) ->
+ ok=test_server:app_test(cosEvent),
+ ok.
+
+
+
+event_objects_api(doc) -> ["Testing the CosEvent API to setup a complete service", ""];
+event_objects_api(suite) -> [];
+event_objects_api(_Config) ->
+
+ Ch = ?match({_,key,_,_,_,_}, cosEventApp:start_channel([{typecheck, true},
+ {pull_interval, 300}])),
+
+ AC=?match({_,key,_,_,_,_},
+ 'CosEventChannelAdmin_EventChannel':for_consumers(Ch)),
+ AS=?match({_,key,_,_,_,_},
+ 'CosEventChannelAdmin_EventChannel':for_suppliers(Ch)),
+
+ PPushS=?match({_,key,_,_,_,_},
+ 'CosEventChannelAdmin_ConsumerAdmin':obtain_push_supplier(AC)),
+ PPullS=?match({_,key,_,_,_,_},
+ 'CosEventChannelAdmin_ConsumerAdmin':obtain_pull_supplier(AC)),
+
+ PPushC=?match({_,key,_,_,_,_},
+ 'CosEventChannelAdmin_SupplierAdmin':obtain_push_consumer(AS)),
+ PPullC=?match({_,key,_,_,_,_},
+ 'CosEventChannelAdmin_SupplierAdmin':obtain_pull_consumer(AS)),
+
+ PushC=?match({_,key,_,_,_,_},
+ 'event_test_PushC':oe_create([])),
+ PullC=?match({_,key,_,_,_,_},
+ 'event_test_PullC':oe_create(PPullC)),
+
+ PushS=?match({_,key,_,_,_,_},
+ 'event_test_PushS':oe_create(PPushC)),
+
+ PullS=?match({_,key,_,_,_,_},
+ 'event_test_PullS':oe_create([])),
+
+ NIL = corba:create_nil_objref(),
+
+ ?match({'EXCEPTION',{'BAD_PARAM',_,_,_}},
+ 'CosEventChannelAdmin_ProxyPushSupplier':connect_push_consumer(PPushS, NIL)),
+ ?match({'EXCEPTION',{'BAD_PARAM',_,_,_}},
+ 'CosEventChannelAdmin_ProxyPushSupplier':connect_push_consumer(PPushS, PullS)),
+ ?match(ok, 'CosEventChannelAdmin_ProxyPushSupplier':connect_push_consumer(PPushS, PushC)),
+ ?match({'EXCEPTION',{'CosEventChannelAdmin_AlreadyConnected',_}},
+ 'CosEventChannelAdmin_ProxyPushSupplier':connect_push_consumer(PPushS, PushC)),
+
+ ?match(ok, 'CosEventChannelAdmin_ProxyPullSupplier':connect_pull_consumer(PPullS, NIL)),
+ ?match({'EXCEPTION',{'BAD_PARAM',_,_,_}},
+ 'CosEventChannelAdmin_ProxyPullSupplier':connect_pull_consumer(PPullS, PullS)),
+ ?match(ok, 'CosEventChannelAdmin_ProxyPullSupplier':connect_pull_consumer(PPullS, PullC)),
+ ?match({'EXCEPTION',{'CosEventChannelAdmin_AlreadyConnected',_}},
+ 'CosEventChannelAdmin_ProxyPullSupplier':connect_pull_consumer(PPullS, PullC)),
+
+ ?match(ok, 'CosEventChannelAdmin_ProxyPushConsumer':connect_push_supplier(PPushC, NIL)),
+ ?match({'EXCEPTION',{'BAD_PARAM',_,_,_}},
+ 'CosEventChannelAdmin_ProxyPushConsumer':connect_push_supplier(PPushC, PullS)),
+ ?match(ok, 'CosEventChannelAdmin_ProxyPushConsumer':connect_push_supplier(PPushC, PushS)),
+ ?match({'EXCEPTION',{'CosEventChannelAdmin_AlreadyConnected',_}},
+ 'CosEventChannelAdmin_ProxyPushConsumer':connect_push_supplier(PPushC, PushS)),
+
+ ?match({'EXCEPTION',{'BAD_PARAM',_,_,_}},
+ 'CosEventChannelAdmin_ProxyPullConsumer':connect_pull_supplier(PPullC, NIL)),
+ ?match({'EXCEPTION',{'BAD_PARAM',_,_,_}},
+ 'CosEventChannelAdmin_ProxyPullConsumer':connect_pull_supplier(PPullC, PushS)),
+ ?match(ok, 'CosEventChannelAdmin_ProxyPullConsumer':connect_pull_supplier(PPullC, PullS)),
+ ?match({'EXCEPTION',{'CosEventChannelAdmin_AlreadyConnected',_}},
+ 'CosEventChannelAdmin_ProxyPullConsumer':connect_pull_supplier(PPullC, PullS)),
+
+
+ catch corba:dispose(AC),
+ %% Wait a couple of seconds to be sure all data removed from DB.
+ timer:sleep(2000),
+
+ %% Since we terminated ConsumerAdmin only the Supplier Proxies should be terminated.
+ ?match(true, corba_object:non_existent(AC)),
+ ?match(true, corba_object:non_existent(PPushS)),
+ ?match(true, corba_object:non_existent(PPullS)),
+
+ ?match(false, corba_object:non_existent(Ch)),
+ ?match(false, corba_object:non_existent(AS)),
+ ?match(false, corba_object:non_existent(PPullC)),
+ ?match(false, corba_object:non_existent(PPushC)),
+
+ %% Terminate a proxy and check that its admin is unaffected.
+ catch corba:dispose(PPullC),
+ timer:sleep(2000),
+ ?match(false, corba_object:non_existent(AS)),
+ ?match(true, corba_object:non_existent(PPullC)),
+
+ catch corba:dispose(Ch),
+ timer:sleep(2000),
+
+ ?match(true, corba_object:non_existent(Ch)),
+ ?match(true, corba_object:non_existent(AS)),
+ ?match(true, corba_object:non_existent(PPullC)),
+ ?match(true, corba_object:non_existent(PPushC)),
+
+ %% The client should be notified; wait for a couple of seconds and check it.
+ timer:sleep(2000),
+ ?match(true, corba_object:non_existent(PushC)),
+ ?match(true, corba_object:non_existent(PullC)),
+ ?match(true, corba_object:non_existent(PushS)),
+ ?match(true, corba_object:non_existent(PullS)),
+
+ ok.
+
+events_api(doc) -> ["Testing the CosEvent API for sending events asynchronous", ""];
+events_api(suite) -> [];
+events_api(_Config) ->
+
+ Ch = ?match({_,key,_,_,_,_}, cosEventApp:start_channel([{typecheck, true},
+ {pull_interval, 2},
+ {blocking, false}])),
+ event_sender(Ch).
+
+
+events_sync_api(doc) -> ["Testing the CosEvent API for sending events synchronous", ""];
+events_sync_api(suite) -> [];
+events_sync_api(_Config) ->
+
+ Ch = ?match({_,key,_,_,_,_}, cosEventApp:start_channel([{typecheck, true},
+ {pull_interval, 2},
+ {blocking, true}])),
+ event_sender(Ch).
+
+event_sender(Ch) ->
+ Event1 = #any{typecode=tk_long, value = 1},
+ Event2 = #any{typecode=tk_long, value = 2},
+ Event3 = #any{typecode=tk_long, value = 3},
+ Event4 = #any{typecode=tk_long, value = 4},
+ Event5 = #any{typecode=tk_long, value = 5},
+ Event6 = #any{typecode=tk_long, value = 6},
+
+ AC=?match({_,key,_,_,_,_},
+ 'CosEventChannelAdmin_EventChannel':for_consumers(Ch)),
+ AS=?match({_,key,_,_,_,_},
+ 'CosEventChannelAdmin_EventChannel':for_suppliers(Ch)),
+
+ PPushS=?match({_,key,_,_,_,_},
+ 'CosEventChannelAdmin_ConsumerAdmin':obtain_push_supplier(AC)),
+ PPullS=?match({_,key,_,_,_,_},
+ 'CosEventChannelAdmin_ConsumerAdmin':obtain_pull_supplier(AC)),
+
+ PPushC=?match({_,key,_,_,_,_},
+ 'CosEventChannelAdmin_SupplierAdmin':obtain_push_consumer(AS)),
+ PPullC=?match({_,key,_,_,_,_},
+ 'CosEventChannelAdmin_SupplierAdmin':obtain_pull_consumer(AS)),
+
+ PushC=?match({_,key,_,_,_,_}, 'event_test_PushC':oe_create([])),
+ PullC=?match({_,key,_,_,_,_}, 'event_test_PullC':oe_create(PPullS)),
+
+ PushS=?match({_,key,_,_,_,_}, 'event_test_PushS':oe_create(PPushC)),
+
+ PullS=?match({_,key,_,_,_,_}, 'event_test_PullS':oe_create([])),
+
+ ?match(ok, 'CosEventChannelAdmin_ProxyPushSupplier':connect_push_consumer(PPushS, PushC)),
+ ?match(ok, 'CosEventChannelAdmin_ProxyPullSupplier':connect_pull_consumer(PPullS, PullC)),
+ ?match(ok, 'CosEventChannelAdmin_ProxyPushConsumer':connect_push_supplier(PPushC, PushS)),
+ ?match(ok, 'CosEventChannelAdmin_ProxyPullConsumer':connect_pull_supplier(PPullC, PullS)),
+
+ %% No events should be available at the consumer side at this point.
+ ?match({_, false}, event_test_PullC:do_try_pull(PullC)),
+ ?match([], event_test_PushC:get_data(PushC)),
+
+ %% Push an event and wait to be sure it have reached the destination.
+ ?match(ok, event_test_PushS:do_push(PushS, Event1)),
+ ?match(ok, event_test_PushS:do_push(PushS, Event2)),
+ ?match(ok, event_test_PushS:do_push(PushS, Event3)),
+ timer:sleep(2000),
+ ?match({Event1, true}, event_test_PullC:do_try_pull(PullC)),
+ ?match({Event2, true}, event_test_PullC:do_try_pull(PullC)),
+ ?match({Event3, true}, event_test_PullC:do_try_pull(PullC)),
+ ?match({_, false}, event_test_PullC:do_try_pull(PullC)),
+ ?match([Event1, Event2, Event3], event_test_PushC:get_data(PushC)),
+
+ ?match(ok, event_test_PullS:add_event(PullS, Event4)),
+ ?match(ok, event_test_PullS:add_event(PullS, Event5)),
+ ?match(ok, event_test_PullS:add_event(PullS, Event6)),
+
+ %% Since the pull operation is blocking we do not need to "sleep".
+ %% The ProxyPullConsumer will pull for events according to the pull_interval
+ %% parameter given when started the channel.
+ ?match(Event4, event_test_PullC:do_pull(PullC)),
+ ?match(Event5, event_test_PullC:do_pull(PullC)),
+ ?match(Event6, event_test_PullC:do_pull(PullC)),
+
+ timer:sleep(2000),
+ ?match([Event4, Event5, Event6], event_test_PushC:get_data(PushC)),
+
+
+ catch corba:dispose(Ch),
+ %% The client should be notified; wait for a couple of seconds and check it.
+ timer:sleep(2000),
+ ?match(true, corba_object:non_existent(PushC)),
+ ?match(true, corba_object:non_existent(PullC)),
+ ?match(true, corba_object:non_existent(PushS)),
+ ?match(true, corba_object:non_existent(PullS)),
+
+ ok.
diff --git a/lib/cosEvent/test/event_test_PullC_impl.erl b/lib/cosEvent/test/event_test_PullC_impl.erl
new file mode 100644
index 0000000000..186d1cbd51
--- /dev/null
+++ b/lib/cosEvent/test/event_test_PullC_impl.erl
@@ -0,0 +1,43 @@
+%%------------------------------------------------------------------------
+%%
+%% %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%
+%%
+%%
+%%------------------------------------------------------------------------
+%% Description: a very simple implementation of PullConsumer interface
+%%------------------------------------------------------------------------
+-module(event_test_PullC_impl).
+
+-export([init/1, terminate/2, disconnect_pull_consumer/1, do_pull/1, do_try_pull/1]).
+
+init(Proxy) ->
+ {ok, Proxy}.
+
+terminate(_From, _Reason) ->
+ ok.
+
+disconnect_pull_consumer(Proxy) ->
+ io:format("event_test_PullC terminates~n",[]),
+ {stop, normal, ok, Proxy}.
+
+do_pull(Proxy) ->
+ {reply, 'CosEventComm_PullSupplier':pull(Proxy), Proxy}.
+
+do_try_pull(Proxy) ->
+ {reply, 'CosEventComm_PullSupplier':try_pull(Proxy), Proxy}.
+
diff --git a/lib/cosEvent/test/event_test_PullS_impl.erl b/lib/cosEvent/test/event_test_PullS_impl.erl
new file mode 100644
index 0000000000..b7fa0c34f0
--- /dev/null
+++ b/lib/cosEvent/test/event_test_PullS_impl.erl
@@ -0,0 +1,57 @@
+%%------------------------------------------------------------------------
+%%
+%% %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%
+%%
+%%
+%%------------------------------------------------------------------------
+%% Description: a very simple implementation of Pull Supplier interface
+%%------------------------------------------------------------------------
+-module(event_test_PullS_impl).
+
+-include_lib("orber/include/corba.hrl").
+
+-export([init/1, terminate/2, pull/1, try_pull/1, disconnect_pull_supplier/1,
+ add_event/2]).
+
+init(_) ->
+ {ok, []}.
+
+terminate(_From, _Reason) ->
+ ok.
+
+pull([]) ->
+ corba:raise(#'INTERNAL'{completion_status = ?COMPLETED_NO});
+pull([Event|Events]) ->
+ {reply, Event, Events}.
+
+try_pull([]) ->
+ {reply, {#any{typecode=tk_null, value = null}, false}, []};
+try_pull([Event|Events]) ->
+ {reply, {Event, true}, Events}.
+
+disconnect_pull_supplier(Events) ->
+ io:format("event_test_PullS terminates ~p~n", [Events]),
+ {stop, normal, ok, Events}.
+
+
+add_event(Events, Event) ->
+ %% Store in FIFO order; don't really care if we use '++' since
+ %% this operation is used in tests only.
+ {reply, ok, Events ++ [Event]}.
+
+
diff --git a/lib/cosEvent/test/event_test_PushC_impl.erl b/lib/cosEvent/test/event_test_PushC_impl.erl
new file mode 100644
index 0000000000..6eadf74a31
--- /dev/null
+++ b/lib/cosEvent/test/event_test_PushC_impl.erl
@@ -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%
+%%
+%%
+%%------------------------------------------------------------------------
+%% Description: a very simple implementation of Push Consumer interface
+%%------------------------------------------------------------------------
+
+-module(event_test_PushC_impl).
+
+-export([init/1, terminate/2, push/2, disconnect_push_consumer/1, get_data/1]).
+
+init(_) ->
+ {ok, []}.
+
+terminate(_From, _Reason) ->
+ ok.
+
+push(Events, Event) ->
+ {reply, ok, [Event|Events]}.
+
+disconnect_push_consumer(Events) ->
+ io:format("event_test_PushC terminates: ~p~n", [Events]),
+ {stop, normal, ok, Events}.
+
+
+get_data(Events) ->
+ %% Returns Events in FIFO order and reset state.
+ {reply, lists:reverse(Events), []}.
+
diff --git a/lib/cosEvent/test/event_test_PushS_impl.erl b/lib/cosEvent/test/event_test_PushS_impl.erl
new file mode 100644
index 0000000000..da82e97211
--- /dev/null
+++ b/lib/cosEvent/test/event_test_PushS_impl.erl
@@ -0,0 +1,41 @@
+%%------------------------------------------------------------------------
+%%
+%% %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%
+%%
+%%
+%%------------------------------------------------------------------------
+%% Description: a very simple implementation of Push Supplier interface
+%%------------------------------------------------------------------------
+
+-module(event_test_PushS_impl).
+
+-export([init/1, terminate/2, disconnect_push_supplier/1, do_push/2]).
+
+init(Proxy) ->
+ {ok, Proxy}.
+
+terminate(_From, _Reason) ->
+ ok.
+
+disconnect_push_supplier(Proxy) ->
+ io:format("event_test_PullC terminates~n",[]),
+ {stop, normal, ok, Proxy}.
+
+do_push(Proxy, Event) ->
+ {reply, 'CosEventComm_PushConsumer':push(Proxy, Event), Proxy}.
+
diff --git a/lib/cosEvent/test/event_test_server.idl b/lib/cosEvent/test/event_test_server.idl
new file mode 100644
index 0000000000..1719401ccd
--- /dev/null
+++ b/lib/cosEvent/test/event_test_server.idl
@@ -0,0 +1,47 @@
+//
+// %CopyrightBegin%
+//
+// Copyright Ericsson AB 2001-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%
+//
+
+#ifndef _EVENT_TEST_SERVER_IDL
+#define _EVENT_TEST_SERVER_IDL
+
+#include <../src/CosEventComm.idl>
+
+module event_test {
+
+ interface PushC : CosEventComm::PushConsumer {
+ typedef sequence<any> AnySeq;
+ AnySeq get_data();
+ };
+ interface PullC : CosEventComm::PullConsumer {
+ any do_pull();
+ any do_try_pull(out boolean has_event);
+ };
+
+ interface PushS : CosEventComm::PushSupplier {
+ void do_push(in any Event);
+ };
+ interface PullS : CosEventComm::PullSupplier {
+ void add_event(in any Event);
+ };
+
+};
+
+#endif
+
+
diff --git a/lib/cosEvent/test/generated_SUITE.erl b/lib/cosEvent/test/generated_SUITE.erl
new file mode 100644
index 0000000000..2d75b18451
--- /dev/null
+++ b/lib/cosEvent/test/generated_SUITE.erl
@@ -0,0 +1,487 @@
+%%-----------------------------------------------------------------
+%%
+%% %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%
+%%
+%%
+%%-----------------------------------------------------------------
+%% File : generated_SUITE.erl
+%% Purpose :
+%%-----------------------------------------------------------------
+
+-module(generated_SUITE).
+
+-include("test_server.hrl").
+-include_lib("orber/include/corba.hrl").
+
+-define(default_timeout, ?t:minutes(3)).
+
+-define(match(ExpectedRes, Expr),
+ fun() ->
+ AcTuAlReS = (catch (Expr)),
+ case AcTuAlReS of
+ ExpectedRes ->
+ AcTuAlReS;
+ _ ->
+ io:format("###### ERROR ERROR ######~n~p~n",
+ [AcTuAlReS]),
+ ?line exit(AcTuAlReS)
+ end
+ end()).
+
+-define(nomatch(Not, Expr),
+ fun() ->
+ AcTuAlReS = (catch (Expr)),
+ case AcTuAlReS of
+ Not ->
+ io:format("###### ERROR ERROR ######~n~p~n",
+ [AcTuAlReS]),
+ ?line exit(AcTuAlReS);
+ _ ->
+ AcTuAlReS
+ end
+ end()).
+
+
+-define(checktc(_Op),
+ fun(TC) ->
+ case orber_tc:check_tc(TC) of
+ false ->
+ io:format("###### ERROR ERROR ######~n~p - ~p~n", [Op, TC]),
+ ?line exit(TC);
+ true ->
+ true
+ end
+ end).
+
+%%-----------------------------------------------------------------
+%% External exports
+%%-----------------------------------------------------------------
+-export([all/1]).
+
+%%-----------------------------------------------------------------
+%% Internal exports
+%%-----------------------------------------------------------------
+-export([]).
+-compile(export_all).
+
+%%-----------------------------------------------------------------
+%% Func: all/1
+%% Args:
+%% Returns:
+%%-----------------------------------------------------------------
+all(doc) -> ["This suite is for testing IC generated files"];
+all(suite) ->
+ ['CosEventChannelAdmin_AlreadyConnected', 'CosEventChannelAdmin_TypeError',
+ 'CosEventComm_Disconnected',
+ 'CosEventChannelAdmin_ConsumerAdmin', 'CosEventChannelAdmin_EventChannel',
+ 'CosEventChannelAdmin_ProxyPullConsumer', 'CosEventChannelAdmin_ProxyPullSupplier',
+ 'CosEventChannelAdmin_ProxyPushConsumer', 'CosEventChannelAdmin_ProxyPushSupplier',
+ 'CosEventChannelAdmin_SupplierAdmin', oe_CosEventComm_CAdmin,
+ oe_CosEventComm_Channel, oe_CosEventComm_Event, oe_CosEventComm_PullerS,
+ oe_CosEventComm_PusherS, 'CosEventComm_PullConsumer',
+ 'CosEventComm_PullSupplier', 'CosEventComm_PushConsumer',
+ 'CosEventComm_PushSupplier'].
+
+%%-----------------------------------------------------------------
+%% Init and cleanup functions.
+%%-----------------------------------------------------------------
+init_per_testcase(_Case, Config) ->
+ ?line Dog=test_server:timetrap(?default_timeout),
+ [{watchdog, Dog}|Config].
+
+
+fin_per_testcase(_Case, Config) ->
+ Dog = ?config(watchdog, Config),
+ test_server:timetrap_cancel(Dog),
+ ok.
+
+
+%%-----------------------------------------------------------------
+%% Test Case: 'CosEventChannelAdmin_AlreadyConnected'
+%% Description:
+%%-----------------------------------------------------------------
+'CosEventChannelAdmin_AlreadyConnected'(doc) -> [""];
+'CosEventChannelAdmin_AlreadyConnected'(suite) -> [];
+'CosEventChannelAdmin_AlreadyConnected'(_) ->
+ ?match(true, orber_tc:check_tc('CosEventChannelAdmin_AlreadyConnected':tc())),
+ ?match("IDL:omg.org/CosEventChannelAdmin/AlreadyConnected:1.0",
+ 'CosEventChannelAdmin_AlreadyConnected':id()),
+ ?match("CosEventChannelAdmin_AlreadyConnected",
+ 'CosEventChannelAdmin_AlreadyConnected':name()),
+ ok.
+
+
+%%-----------------------------------------------------------------
+%% Test Case: 'CosEventChannelAdmin_TypeError'
+%% Description:
+%%-----------------------------------------------------------------
+'CosEventChannelAdmin_TypeError'(doc) -> [""];
+'CosEventChannelAdmin_TypeError'(suite) -> [];
+'CosEventChannelAdmin_TypeError'(_) ->
+ ?match(true, orber_tc:check_tc('CosEventChannelAdmin_TypeError':tc())),
+ ?match("IDL:omg.org/CosEventChannelAdmin/TypeError:1.0",
+ 'CosEventChannelAdmin_TypeError':id()),
+ ?match("CosEventChannelAdmin_TypeError",
+ 'CosEventChannelAdmin_TypeError':name()),
+ ok.
+
+
+%%-----------------------------------------------------------------
+%% Test Case: 'CosEventComm_Disconnected'
+%% Description:
+%%-----------------------------------------------------------------
+'CosEventComm_Disconnected'(doc) -> [""];
+'CosEventComm_Disconnected'(suite) -> [];
+'CosEventComm_Disconnected'(_) ->
+ ?match(true, orber_tc:check_tc('CosEventComm_Disconnected':tc())),
+ ?match("IDL:omg.org/CosEventComm/Disconnected:1.0",
+ 'CosEventComm_Disconnected':id()),
+ ?match("CosEventComm_Disconnected", 'CosEventComm_Disconnected':name()),
+ ok.
+
+
+%%-----------------------------------------------------------------
+%% Test Case: 'CosEventChannelAdmin_ConsumerAdmin'
+%% Description:
+%%-----------------------------------------------------------------
+'CosEventChannelAdmin_ConsumerAdmin'(doc) -> [""];
+'CosEventChannelAdmin_ConsumerAdmin'(suite) -> [];
+'CosEventChannelAdmin_ConsumerAdmin'(_) ->
+ ?nomatch(undefined, 'CosEventChannelAdmin_ConsumerAdmin':oe_tc(obtain_push_supplier)),
+ ?nomatch(undefined, 'CosEventChannelAdmin_ConsumerAdmin':oe_tc(obtain_pull_supplier)),
+ ?match(undefined, 'CosEventChannelAdmin_ConsumerAdmin':oe_tc(undefined)),
+ ?match([_|_], 'CosEventChannelAdmin_ConsumerAdmin':oe_get_interface()),
+ ?match("IDL:omg.org/CosEventChannelAdmin/ConsumerAdmin:1.0",
+ 'CosEventChannelAdmin_ConsumerAdmin':typeID()),
+ check_tc('CosEventChannelAdmin_ConsumerAdmin':oe_get_interface()),
+ ?match(true, 'CosEventChannelAdmin_ConsumerAdmin':oe_is_a('CosEventChannelAdmin_ConsumerAdmin':typeID())),
+ ?match(false, 'CosEventChannelAdmin_ConsumerAdmin':oe_is_a("wrong")),
+ ok.
+
+%%-----------------------------------------------------------------
+%% Test Case: 'CosEventChannelAdmin_EventChannel'
+%% Description:
+%%-----------------------------------------------------------------
+'CosEventChannelAdmin_EventChannel'(doc) -> [""];
+'CosEventChannelAdmin_EventChannel'(suite) -> [];
+'CosEventChannelAdmin_EventChannel'(_) ->
+ ?nomatch(undefined, 'CosEventChannelAdmin_EventChannel':oe_tc(for_consumers)),
+ ?nomatch(undefined, 'CosEventChannelAdmin_EventChannel':oe_tc(for_suppliers)),
+ ?nomatch(undefined, 'CosEventChannelAdmin_EventChannel':oe_tc(destroy)),
+ ?match(undefined, 'CosEventChannelAdmin_EventChannel':oe_tc(undefined)),
+ ?match([_|_], 'CosEventChannelAdmin_EventChannel':oe_get_interface()),
+ ?match("IDL:omg.org/CosEventChannelAdmin/EventChannel:1.0",
+ 'CosEventChannelAdmin_EventChannel':typeID()),
+ check_tc('CosEventChannelAdmin_EventChannel':oe_get_interface()),
+ ?match(true, 'CosEventChannelAdmin_EventChannel':oe_is_a('CosEventChannelAdmin_EventChannel':typeID())),
+ ?match(false, 'CosEventChannelAdmin_EventChannel':oe_is_a("wrong")),
+ ok.
+
+%%-----------------------------------------------------------------
+%% Test Case: 'CosEventChannelAdmin_ProxyPullConsumer'
+%% Description:
+%%-----------------------------------------------------------------
+'CosEventChannelAdmin_ProxyPullConsumer'(doc) -> [""];
+'CosEventChannelAdmin_ProxyPullConsumer'(suite) -> [];
+'CosEventChannelAdmin_ProxyPullConsumer'(_) ->
+ ?nomatch(undefined, 'CosEventChannelAdmin_ProxyPullConsumer':oe_tc(connect_pull_supplier)),
+ ?nomatch(undefined, 'CosEventChannelAdmin_ProxyPullConsumer':oe_tc(disconnect_pull_consumer)),
+ ?match(undefined, 'CosEventChannelAdmin_ProxyPullConsumer':oe_tc(undefined)),
+ ?match([_|_], 'CosEventChannelAdmin_ProxyPullConsumer':oe_get_interface()),
+ ?match("IDL:omg.org/CosEventChannelAdmin/ProxyPullConsumer:1.0",
+ 'CosEventChannelAdmin_ProxyPullConsumer':typeID()),
+ check_tc('CosEventChannelAdmin_ProxyPullConsumer':oe_get_interface()),
+ ?match(true, 'CosEventChannelAdmin_ProxyPullConsumer':oe_is_a('CosEventChannelAdmin_ProxyPullConsumer':typeID())),
+ ?match(true, 'CosEventChannelAdmin_ProxyPullConsumer':oe_is_a('CosEventComm_PullConsumer':typeID())),
+ ?match(false, 'CosEventChannelAdmin_ProxyPullConsumer':oe_is_a("wrong")),
+ ok.
+
+%%-----------------------------------------------------------------
+%% Test Case: 'CosEventChannelAdmin_ProxyPullSupplier'
+%% Description:
+%%-----------------------------------------------------------------
+'CosEventChannelAdmin_ProxyPullSupplier'(doc) -> [""];
+'CosEventChannelAdmin_ProxyPullSupplier'(suite) -> [];
+'CosEventChannelAdmin_ProxyPullSupplier'(_) ->
+ ?nomatch(undefined, 'CosEventChannelAdmin_ProxyPullSupplier':oe_tc(connect_pull_consumer)),
+ ?nomatch(undefined, 'CosEventChannelAdmin_ProxyPullSupplier':oe_tc(pull)),
+ ?nomatch(undefined, 'CosEventChannelAdmin_ProxyPullSupplier':oe_tc(try_pull)),
+ ?nomatch(undefined, 'CosEventChannelAdmin_ProxyPullSupplier':oe_tc(disconnect_pull_supplier)),
+ ?match(undefined, 'CosEventChannelAdmin_ProxyPullSupplier':oe_tc(undefined)),
+ ?match([_|_], 'CosEventChannelAdmin_ProxyPullSupplier':oe_get_interface()),
+ ?match("IDL:omg.org/CosEventChannelAdmin/ProxyPullSupplier:1.0",
+ 'CosEventChannelAdmin_ProxyPullSupplier':typeID()),
+ check_tc('CosEventChannelAdmin_ProxyPullSupplier':oe_get_interface()),
+ ?match(true, 'CosEventChannelAdmin_ProxyPullSupplier':oe_is_a('CosEventChannelAdmin_ProxyPullSupplier':typeID())),
+ ?match(true, 'CosEventChannelAdmin_ProxyPullSupplier':oe_is_a('CosEventComm_PullSupplier':typeID())),
+ ?match(false, 'CosEventChannelAdmin_ProxyPullSupplier':oe_is_a("wrong")),
+ ok.
+
+%%-----------------------------------------------------------------
+%% Test Case: 'CosEventChannelAdmin_ProxyPushConsumer'
+%% Description:
+%%-----------------------------------------------------------------
+'CosEventChannelAdmin_ProxyPushConsumer'(doc) -> [""];
+'CosEventChannelAdmin_ProxyPushConsumer'(suite) -> [];
+'CosEventChannelAdmin_ProxyPushConsumer'(_) ->
+ ?nomatch(undefined, 'CosEventChannelAdmin_ProxyPushConsumer':oe_tc(connect_push_supplier)),
+ ?nomatch(undefined, 'CosEventChannelAdmin_ProxyPushConsumer':oe_tc(push)),
+ ?nomatch(undefined, 'CosEventChannelAdmin_ProxyPushConsumer':oe_tc(disconnect_push_consumer)),
+ ?match(undefined, 'CosEventChannelAdmin_ProxyPushConsumer':oe_tc(undefined)),
+ ?match([_|_], 'CosEventChannelAdmin_ProxyPushConsumer':oe_get_interface()),
+ ?match("IDL:omg.org/CosEventChannelAdmin/ProxyPushConsumer:1.0",
+ 'CosEventChannelAdmin_ProxyPushConsumer':typeID()),
+ check_tc('CosEventChannelAdmin_ProxyPushConsumer':oe_get_interface()),
+ ?match(true, 'CosEventChannelAdmin_ProxyPushConsumer':oe_is_a('CosEventChannelAdmin_ProxyPushConsumer':typeID())),
+ ?match(true, 'CosEventChannelAdmin_ProxyPushConsumer':oe_is_a('CosEventComm_PushConsumer':typeID())),
+ ?match(false, 'CosEventChannelAdmin_ProxyPushConsumer':oe_is_a("wrong")),
+ ok.
+
+%%-----------------------------------------------------------------
+%% Test Case: 'CosEventChannelAdmin_ProxyPushSupplier'
+%% Description:
+%%-----------------------------------------------------------------
+'CosEventChannelAdmin_ProxyPushSupplier'(doc) -> [""];
+'CosEventChannelAdmin_ProxyPushSupplier'(suite) -> [];
+'CosEventChannelAdmin_ProxyPushSupplier'(_) ->
+ ?nomatch(undefined, 'CosEventChannelAdmin_ProxyPushSupplier':oe_tc(connect_push_consumer)),
+ ?nomatch(undefined, 'CosEventChannelAdmin_ProxyPushSupplier':oe_tc(disconnect_push_supplier)),
+ ?match(undefined, 'CosEventChannelAdmin_ProxyPushSupplier':oe_tc(undefined)),
+ ?match([_|_], 'CosEventChannelAdmin_ProxyPushSupplier':oe_get_interface()),
+ ?match("IDL:omg.org/CosEventChannelAdmin/ProxyPushSupplier:1.0",
+ 'CosEventChannelAdmin_ProxyPushSupplier':typeID()),
+ check_tc('CosEventChannelAdmin_ProxyPushSupplier':oe_get_interface()),
+ ?match(true, 'CosEventChannelAdmin_ProxyPushSupplier':oe_is_a('CosEventChannelAdmin_ProxyPushSupplier':typeID())),
+ ?match(true, 'CosEventChannelAdmin_ProxyPushSupplier':oe_is_a('CosEventComm_PushSupplier':typeID())),
+ ?match(false, 'CosEventChannelAdmin_ProxyPushSupplier':oe_is_a("wrong")),
+ ok.
+
+%%-----------------------------------------------------------------
+%% Test Case: 'CosEventChannelAdmin_SupplierAdmin'
+%% Description:
+%%-----------------------------------------------------------------
+'CosEventChannelAdmin_SupplierAdmin'(doc) -> [""];
+'CosEventChannelAdmin_SupplierAdmin'(suite) -> [];
+'CosEventChannelAdmin_SupplierAdmin'(_) ->
+ ?nomatch(undefined, 'CosEventChannelAdmin_SupplierAdmin':oe_tc(obtain_push_consumer)),
+ ?nomatch(undefined, 'CosEventChannelAdmin_SupplierAdmin':oe_tc(obtain_pull_consumer)),
+ ?match(undefined, 'CosEventChannelAdmin_SupplierAdmin':oe_tc(undefined)),
+ ?match([_|_], 'CosEventChannelAdmin_SupplierAdmin':oe_get_interface()),
+ ?match("IDL:omg.org/CosEventChannelAdmin/SupplierAdmin:1.0",
+ 'CosEventChannelAdmin_SupplierAdmin':typeID()),
+ check_tc('CosEventChannelAdmin_SupplierAdmin':oe_get_interface()),
+ ?match(true, 'CosEventChannelAdmin_SupplierAdmin':oe_is_a('CosEventChannelAdmin_SupplierAdmin':typeID())),
+ ?match(false, 'CosEventChannelAdmin_SupplierAdmin':oe_is_a("wrong")),
+ ok.
+
+%%-----------------------------------------------------------------
+%% Test Case: 'oe_CosEventComm_CAdmin'
+%% Description:
+%%-----------------------------------------------------------------
+'oe_CosEventComm_CAdmin'(doc) -> [""];
+'oe_CosEventComm_CAdmin'(suite) -> [];
+'oe_CosEventComm_CAdmin'(_) ->
+ ?nomatch(undefined, 'oe_CosEventComm_CAdmin':oe_tc(obtain_push_supplier)),
+ ?nomatch(undefined, 'oe_CosEventComm_CAdmin':oe_tc(obtain_pull_supplier)),
+ ?nomatch(undefined, 'oe_CosEventComm_CAdmin':oe_tc(send)),
+ ?nomatch(undefined, 'oe_CosEventComm_CAdmin':oe_tc(send_sync)),
+ ?match(undefined, 'oe_CosEventComm_CAdmin':oe_tc(undefined)),
+ ?match([_|_], 'oe_CosEventComm_CAdmin':oe_get_interface()),
+ ?match("IDL:oe_CosEventComm/CAdmin:1.0",
+ 'oe_CosEventComm_CAdmin':typeID()),
+ check_tc('oe_CosEventComm_CAdmin':oe_get_interface()),
+ ?match(true, 'oe_CosEventComm_CAdmin':oe_is_a('oe_CosEventComm_CAdmin':typeID())),
+ ?match(true, 'oe_CosEventComm_CAdmin':oe_is_a('CosEventChannelAdmin_ConsumerAdmin':typeID())),
+ ?match(true, 'oe_CosEventComm_CAdmin':oe_is_a('oe_CosEventComm_Event':typeID())),
+ ?match(false, 'oe_CosEventComm_CAdmin':oe_is_a("wrong")),
+ ok.
+
+%%-----------------------------------------------------------------
+%% Test Case: 'oe_CosEventComm_Channel'
+%% Description:
+%%-----------------------------------------------------------------
+'oe_CosEventComm_Channel'(doc) -> [""];
+'oe_CosEventComm_Channel'(suite) -> [];
+'oe_CosEventComm_Channel'(_) ->
+ ?nomatch(undefined, 'oe_CosEventComm_Channel':oe_tc(for_consumers)),
+ ?nomatch(undefined, 'oe_CosEventComm_Channel':oe_tc(for_suppliers)),
+ ?nomatch(undefined, 'oe_CosEventComm_Channel':oe_tc(destroy)),
+ ?nomatch(undefined, 'oe_CosEventComm_Channel':oe_tc(send)),
+ ?nomatch(undefined, 'oe_CosEventComm_Channel':oe_tc(send_sync)),
+ ?match(undefined, 'oe_CosEventComm_Channel':oe_tc(undefined)),
+ ?match([_|_], 'oe_CosEventComm_Channel':oe_get_interface()),
+ ?match("IDL:oe_CosEventComm/Channel:1.0",
+ 'oe_CosEventComm_Channel':typeID()),
+ check_tc('oe_CosEventComm_Channel':oe_get_interface()),
+ ?match(true, 'oe_CosEventComm_Channel':oe_is_a('oe_CosEventComm_Channel':typeID())),
+ ?match(true, 'oe_CosEventComm_Channel':oe_is_a('CosEventChannelAdmin_EventChannel':typeID())),
+ ?match(true, 'oe_CosEventComm_Channel':oe_is_a('oe_CosEventComm_Event':typeID())),
+ ?match(false, 'oe_CosEventComm_Channel':oe_is_a("wrong")),
+ ok.
+
+%%-----------------------------------------------------------------
+%% Test Case: 'oe_CosEventComm_Event'
+%% Description:
+%%-----------------------------------------------------------------
+'oe_CosEventComm_Event'(doc) -> [""];
+'oe_CosEventComm_Event'(suite) -> [];
+'oe_CosEventComm_Event'(_) ->
+ ?nomatch(undefined, 'oe_CosEventComm_Event':oe_tc(send)),
+ ?nomatch(undefined, 'oe_CosEventComm_Event':oe_tc(send_sync)),
+ ?match(undefined, 'oe_CosEventComm_Event':oe_tc(undefined)),
+ ?match([_|_], 'oe_CosEventComm_Event':oe_get_interface()),
+ ?match("IDL:oe_CosEventComm/Event:1.0",
+ 'oe_CosEventComm_Event':typeID()),
+ check_tc('oe_CosEventComm_Event':oe_get_interface()),
+ ?match(true, 'oe_CosEventComm_Event':oe_is_a('oe_CosEventComm_Event':typeID())),
+ ?match(false, 'oe_CosEventComm_Event':oe_is_a("wrong")),
+ ok.
+
+%%-----------------------------------------------------------------
+%% Test Case: 'oe_CosEventComm_PullerS'
+%% Description:
+%%-----------------------------------------------------------------
+'oe_CosEventComm_PullerS'(doc) -> [""];
+'oe_CosEventComm_PullerS'(suite) -> [];
+'oe_CosEventComm_PullerS'(_) ->
+ ?nomatch(undefined, 'oe_CosEventComm_PullerS':oe_tc(connect_pull_consumer)),
+ ?nomatch(undefined, 'oe_CosEventComm_PullerS':oe_tc(pull)),
+ ?nomatch(undefined, 'oe_CosEventComm_PullerS':oe_tc(try_pull)),
+ ?nomatch(undefined, 'oe_CosEventComm_PullerS':oe_tc(disconnect_pull_supplier)),
+ ?nomatch(undefined, 'oe_CosEventComm_PullerS':oe_tc(send)),
+ ?nomatch(undefined, 'oe_CosEventComm_PullerS':oe_tc(send_sync)),
+ ?match(undefined, 'oe_CosEventComm_PullerS':oe_tc(undefined)),
+ ?match([_|_], 'oe_CosEventComm_PullerS':oe_get_interface()),
+ ?match("IDL:oe_CosEventComm/PullerS:1.0",
+ 'oe_CosEventComm_PullerS':typeID()),
+ check_tc('oe_CosEventComm_PullerS':oe_get_interface()),
+ ?match(true, 'oe_CosEventComm_PullerS':oe_is_a('oe_CosEventComm_PullerS':typeID())),
+ ?match(true, 'oe_CosEventComm_PullerS':oe_is_a('CosEventChannelAdmin_ProxyPullSupplier':typeID())),
+ ?match(true, 'oe_CosEventComm_PullerS':oe_is_a('CosEventComm_PullSupplier':typeID())),
+ ?match(true, 'oe_CosEventComm_PullerS':oe_is_a('oe_CosEventComm_Event':typeID())),
+ ?match(false, 'oe_CosEventComm_PullerS':oe_is_a("wrong")),
+ ok.
+
+%%-----------------------------------------------------------------
+%% Test Case: 'oe_CosEventComm_PusherS'
+%% Description:
+%%-----------------------------------------------------------------
+'oe_CosEventComm_PusherS'(doc) -> [""];
+'oe_CosEventComm_PusherS'(suite) -> [];
+'oe_CosEventComm_PusherS'(_) ->
+ ?nomatch(undefined, 'oe_CosEventComm_PusherS':oe_tc(connect_push_consumer)),
+ ?nomatch(undefined, 'oe_CosEventComm_PusherS':oe_tc(disconnect_push_supplier)),
+ ?nomatch(undefined, 'oe_CosEventComm_PusherS':oe_tc(send)),
+ ?nomatch(undefined, 'oe_CosEventComm_PusherS':oe_tc(send_sync)),
+ ?match(undefined, 'oe_CosEventComm_PusherS':oe_tc(undefined)),
+ ?match([_|_], 'oe_CosEventComm_PusherS':oe_get_interface()),
+ ?match("IDL:oe_CosEventComm/PusherS:1.0",
+ 'oe_CosEventComm_PusherS':typeID()),
+ check_tc('oe_CosEventComm_PusherS':oe_get_interface()),
+ ?match(true, 'oe_CosEventComm_PusherS':oe_is_a('oe_CosEventComm_PusherS':typeID())),
+ ?match(true, 'oe_CosEventComm_PusherS':oe_is_a('CosEventChannelAdmin_ProxyPushSupplier':typeID())),
+ ?match(true, 'oe_CosEventComm_PusherS':oe_is_a('CosEventComm_PushSupplier':typeID())),
+ ?match(true, 'oe_CosEventComm_PusherS':oe_is_a('oe_CosEventComm_Event':typeID())),
+ ?match(false, 'oe_CosEventComm_PusherS':oe_is_a("wrong")),
+ ok.
+
+%%-----------------------------------------------------------------
+%% Test Case: 'CosEventComm_PullConsumer'
+%% Description:
+%%-----------------------------------------------------------------
+'CosEventComm_PullConsumer'(doc) -> [""];
+'CosEventComm_PullConsumer'(suite) -> [];
+'CosEventComm_PullConsumer'(_) ->
+ ?nomatch(undefined, 'CosEventComm_PullConsumer':oe_tc(disconnect_pull_consumer)),
+ ?match(undefined, 'CosEventComm_PullConsumer':oe_tc(undefined)),
+ ?match([_|_], 'CosEventComm_PullConsumer':oe_get_interface()),
+ ?match("IDL:omg.org/CosEventComm/PullConsumer:1.0",
+ 'CosEventComm_PullConsumer':typeID()),
+ check_tc('CosEventComm_PullConsumer':oe_get_interface()),
+ ?match(true, 'CosEventComm_PullConsumer':oe_is_a('CosEventComm_PullConsumer':typeID())),
+ ?match(false, 'CosEventComm_PullConsumer':oe_is_a("wrong")),
+ ok.
+
+%%-----------------------------------------------------------------
+%% Test Case: 'CosEventComm_PullSupplier'
+%% Description:
+%%-----------------------------------------------------------------
+'CosEventComm_PullSupplier'(doc) -> [""];
+'CosEventComm_PullSupplier'(suite) -> [];
+'CosEventComm_PullSupplier'(_) ->
+ ?nomatch(undefined, 'CosEventComm_PullSupplier':oe_tc(pull)),
+ ?nomatch(undefined, 'CosEventComm_PullSupplier':oe_tc(try_pull)),
+ ?nomatch(undefined, 'CosEventComm_PullSupplier':oe_tc(disconnect_pull_supplier)),
+ ?match(undefined, 'CosEventComm_PullSupplier':oe_tc(undefined)),
+ ?match([_|_], 'CosEventComm_PullSupplier':oe_get_interface()),
+ ?match("IDL:omg.org/CosEventComm/PullSupplier:1.0",
+ 'CosEventComm_PullSupplier':typeID()),
+ check_tc('CosEventComm_PullSupplier':oe_get_interface()),
+ ?match(true, 'CosEventComm_PullSupplier':oe_is_a('CosEventComm_PullSupplier':typeID())),
+ ?match(false, 'CosEventComm_PullSupplier':oe_is_a("wrong")),
+ ok.
+
+%%-----------------------------------------------------------------
+%% Test Case: 'CosEventComm_PushConsumer'
+%% Description:
+%%-----------------------------------------------------------------
+'CosEventComm_PushConsumer'(doc) -> [""];
+'CosEventComm_PushConsumer'(suite) -> [];
+'CosEventComm_PushConsumer'(_) ->
+ ?nomatch(undefined, 'CosEventComm_PushConsumer':oe_tc(push)),
+ ?nomatch(undefined, 'CosEventComm_PushConsumer':oe_tc(disconnect_push_consumer)),
+ ?match(undefined, 'CosEventComm_PushConsumer':oe_tc(undefined)),
+ ?match([_|_], 'CosEventComm_PushConsumer':oe_get_interface()),
+ ?match("IDL:omg.org/CosEventComm/PushConsumer:1.0",
+ 'CosEventComm_PushConsumer':typeID()),
+ check_tc('CosEventComm_PushConsumer':oe_get_interface()),
+ ?match(true, 'CosEventComm_PushConsumer':oe_is_a('CosEventComm_PushConsumer':typeID())),
+ ?match(false, 'CosEventComm_PushConsumer':oe_is_a("wrong")),
+ ok.
+
+%%-----------------------------------------------------------------
+%% Test Case: 'CosEventComm_PushSupplier'
+%% Description:
+%%-----------------------------------------------------------------
+'CosEventComm_PushSupplier'(doc) -> [""];
+'CosEventComm_PushSupplier'(suite) -> [];
+'CosEventComm_PushSupplier'(_) ->
+ ?nomatch(undefined, 'CosEventComm_PushSupplier':oe_tc(disconnect_push_supplier)),
+ ?match(undefined, 'CosEventComm_PushSupplier':oe_tc(undefined)),
+ ?match([_|_], 'CosEventComm_PushSupplier':oe_get_interface()),
+ ?match("IDL:omg.org/CosEventComm/PushSupplier:1.0",
+ 'CosEventComm_PushSupplier':typeID()),
+ check_tc('CosEventComm_PushSupplier':oe_get_interface()),
+ ?match(true, 'CosEventComm_PushSupplier':oe_is_a('CosEventComm_PushSupplier':typeID())),
+ ?match(false, 'CosEventComm_PushSupplier':oe_is_a("wrong")),
+ ok.
+
+
+
+%%-----------------------------------------------------------------
+%% MISC functions
+%%-----------------------------------------------------------------
+check_tc([]) ->
+ ok;
+check_tc([{Op, {RetType, InParameters, OutParameters}}|T]) ->
+ io:format("checked - ~s~n", [Op]),
+ lists:all(?checktc(Op), [RetType|InParameters]),
+ lists:all(?checktc(Op), OutParameters),
+ check_tc(T).
+
+
diff --git a/lib/cosEvent/test/idl_output/.gitignore b/lib/cosEvent/test/idl_output/.gitignore
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/lib/cosEvent/test/idl_output/.gitignore
diff --git a/lib/cosEvent/vsn.mk b/lib/cosEvent/vsn.mk
index 953e5fc8c9..8915903bbe 100644
--- a/lib/cosEvent/vsn.mk
+++ b/lib/cosEvent/vsn.mk
@@ -1,7 +1,10 @@
-COSEVENT_VSN = 2.1.7
+COSEVENT_VSN = 2.1.8
-TICKETS = OTP-8201
+TICKETS = OTP-8355 \
+ OTP-8409
+
+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/test/Makefile b/lib/cosEventDomain/test/Makefile
new file mode 100644
index 0000000000..9893b05b8c
--- /dev/null
+++ b/lib/cosEventDomain/test/Makefile
@@ -0,0 +1,104 @@
+#
+# %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_TOP)/make/target.mk
+include $(ERL_TOP)/make/$(TARGET)/otp.mk
+
+# ----------------------------------------------------
+# Application version
+# ----------------------------------------------------
+include ../vsn.mk
+VSN=$(COSEVENTDOMAIN_VSN)
+# ----------------------------------------------------
+# Release directory specification
+# ----------------------------------------------------
+RELSYSDIR = $(RELEASE_PATH)/cosEventDomain_test
+
+# ----------------------------------------------------
+# Target Specs
+# ----------------------------------------------------
+TEST_SPEC_FILE = cosEventDomain.spec
+
+
+MODULES = \
+ event_domain_SUITE \
+ generated_SUITE
+
+ERL_FILES = $(MODULES:%=%.erl)
+
+HRL_FILES =
+
+SUITE_TARGET_FILES = $(MODULES:%=%.$(EMULATOR))
+
+TARGET_FILES = \
+ $(SUITE_TARGET_FILES)
+
+# ----------------------------------------------------
+# PROGRAMS
+# ----------------------------------------------------
+# ----------------------------------------------------
+# FLAGS
+# ----------------------------------------------------
+ERL_IDL_FLAGS += -pa $(ERL_TOP)/lib/orber/ebin -pa $(ERL_TOP)/lib/ic/ebin
+
+ERL_COMPILE_FLAGS += \
+ $(ERL_IDL_FLAGS) \
+ -pa $(ERL_TOP)/lib/test_server/ebin \
+ -pa $(ERL_TOP)/lib/cosEventDomain/ebin \
+ -pa $(ERL_TOP)/lib/cosEventDomain/include \
+ -pa $(ERL_TOP)/lib/cosNotification/ebin \
+ -pa $(ERL_TOP)/lib/cosNotification/include \
+ -I$(ERL_TOP)/lib/cosEventDomain/include \
+ -I$(ERL_TOP)/lib/cosNotification/include \
+ -I$(ERL_TOP)/lib/cosNotification/ebin \
+ -I$(ERL_TOP)/lib/test_server/include
+
+# ----------------------------------------------------
+# Targets
+# ----------------------------------------------------
+tests debug opt: $(TARGET_FILES)
+
+clean:
+ rm -f $(TARGET_FILES)
+ rm -f errs core *~
+
+
+docs:
+
+# ----------------------------------------------------
+# Special Targets
+# ----------------------------------------------------
+
+# ----------------------------------------------------
+# Release Targets
+# ----------------------------------------------------
+# We don't copy generated intermediate erlang and hrl files
+
+include $(ERL_TOP)/make/otp_release_targets.mk
+
+release_spec:
+
+release_docs_spec:
+
+release_tests_spec: tests
+ $(INSTALL_DIR) $(RELSYSDIR)
+ $(INSTALL_DATA) $(TEST_SPEC_FILE) \
+ $(ERL_FILES) $(RELSYSDIR)
+ $(INSTALL_DATA) $(SUITE_TARGET_FILES) $(RELSYSDIR)
+
diff --git a/lib/cosEventDomain/test/cosEventDomain.spec b/lib/cosEventDomain/test/cosEventDomain.spec
new file mode 100644
index 0000000000..0d3e307071
--- /dev/null
+++ b/lib/cosEventDomain/test/cosEventDomain.spec
@@ -0,0 +1,19 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 2001-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%
+%%
+{topcase, {dir, "../cosEventDomain_test"}}.
diff --git a/lib/cosEventDomain/test/event_domain_SUITE.erl b/lib/cosEventDomain/test/event_domain_SUITE.erl
new file mode 100644
index 0000000000..ddf0af3489
--- /dev/null
+++ b/lib/cosEventDomain/test/event_domain_SUITE.erl
@@ -0,0 +1,456 @@
+%%-----------------------------------------------------------------
+%%
+%% %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(event_domain_SUITE).
+
+-include("test_server.hrl").
+-include_lib("orber/include/corba.hrl").
+-include_lib("cosNotification/include/CosNotifyChannelAdmin.hrl").
+-include_lib("cosNotification/include/CosNotification.hrl").
+
+-include_lib("cosEventDomain/include/CosEventDomainAdmin.hrl").
+-include_lib("cosEventDomain/src/cosEventDomainApp.hrl").
+
+%%-----------------------------------------------------------------
+%% Macros
+%%-----------------------------------------------------------------
+
+-define(default_timeout, ?t:minutes(5)).
+
+
+-define(match(ExpectedRes, Expr),
+ fun() ->
+ AcTuAlReS = (catch (Expr)),
+ case AcTuAlReS of
+ ExpectedRes ->
+ io:format("------ CORRECT RESULT ------~n~p~n",
+ [AcTuAlReS]),
+ AcTuAlReS;
+ _ ->
+ io:format("###### ERROR ERROR ######~n~p~n",
+ [AcTuAlReS]),
+ ?line exit(AcTuAlReS)
+ end
+ end()).
+
+
+%%-----------------------------------------------------------------
+%% External exports
+%%-----------------------------------------------------------------
+-export([all/1, event_domain_api/1, event_domain_factory_api/1,
+ cases/0, init_all/1, finish_all/1,
+ init_per_testcase/2, fin_per_testcase/2, app_test/1]).
+
+%%-----------------------------------------------------------------
+%% Internal exports
+%%-----------------------------------------------------------------
+
+all(doc) -> ["API tests for the cosEventDomain interfaces", ""];
+all(suite) -> {req,
+ [mnesia, orber, cosNotification],
+ {conf, init_all, cases(), finish_all}}.
+
+cases() ->
+ [event_domain_api, event_domain_factory_api, app_test].
+
+%%-----------------------------------------------------------------
+%% Init and cleanup functions.
+%%-----------------------------------------------------------------
+
+init_per_testcase(_Case, Config) ->
+ ?line Dog=test_server:timetrap(?default_timeout),
+ [{watchdog, Dog}|Config].
+
+
+fin_per_testcase(_Case, Config) ->
+ Dog = ?config(watchdog, Config),
+ test_server:timetrap_cancel(Dog),
+ ok.
+
+init_all(Config) when is_list(Config) ->
+ mnesia:delete_schema([node()]),
+ mnesia:create_schema([node()]),
+ ok = corba:orb_init([{flags, 16#02},
+ {orber_debug_level, 10}]),
+ orber:install([node()]),
+ application:start(mnesia),
+ application:start(orber),
+ cosEventApp:install(),
+ cosEventApp:start(),
+ cosNotificationApp:install(),
+ cosNotificationApp:start(),
+ cosEventDomainApp:install(),
+ cosEventDomainApp:start(),
+ Config.
+
+finish_all(Config) when is_list(Config) ->
+ cosEventDomainApp:stop(),
+ cosEventDomainApp:uninstall(),
+ cosNotificationApp:stop(),
+ cosNotificationApp:uninstall(),
+ cosEventApp:stop(),
+ cosEventApp:uninstall(),
+ application:stop(orber),
+ application:stop(mnesia),
+ mnesia:delete_schema([node()]),
+ Config.
+
+%%-----------------------------------------------------------------
+%% Tests app file
+%%-----------------------------------------------------------------
+app_test(doc) -> [];
+app_test(suite) -> [];
+app_test(_Config) ->
+ ok=test_server:app_test(cosEventDomain),
+ ok.
+
+
+event_domain_api(doc) -> ["Testing the CosEventDomain Domain API", ""];
+event_domain_api(suite) -> [];
+event_domain_api(_Config) ->
+
+ %% We will setup a cluster looking like:
+ %% 7-8--->
+ %% /
+ %% 2 - 4 6->
+ %% \ /
+ %% 5---9-1-3
+
+ %% 2-4
+ %% 4-1
+ %% 1-3
+ %% 3-6
+ %% 5-9
+ %% 9-1
+ %% 4-7
+ %% 7-8
+
+
+ ChFac = ?match({_,key,_,_,_,_},
+ cosNotificationApp:start_global_factory([{pullInterval,1}])),
+ {Ch0,_} = ?match({{_,key,_,_,_,_}, _},
+ 'CosNotifyChannelAdmin_EventChannelFactory':create_channel(ChFac, [], [])),
+ Fac = ?match({_,key,_,_,_,_},
+ cosEventDomainApp:start_factory()),
+ {ED, _} = ?match({{_,key,_,_,_,_}, _},
+ 'CosEventDomainAdmin_EventDomainFactory':create_event_domain(Fac, [], [])),
+ ID0 = 'CosEventDomainAdmin_EventDomain':add_channel(ED, Ch0),
+ ?match(Ch0, 'CosEventDomainAdmin_EventDomain':get_channel(ED, ID0)),
+ ?match([0], 'CosEventDomainAdmin_EventDomain':get_all_channels(ED)),
+ ?match({'EXCEPTION',{'CosNotifyChannelAdmin_ChannelNotFound',_}},
+ 'CosEventDomainAdmin_EventDomain':get_channel(ED, 100)),
+ ?match({'EXCEPTION',{'CosNotifyChannelAdmin_ChannelNotFound',_}},
+ 'CosEventDomainAdmin_EventDomain':remove_channel(ED, 100)),
+ ?match(ok, 'CosEventDomainAdmin_EventDomain':remove_channel(ED, 0)),
+ ?match([], 'CosEventDomainAdmin_EventDomain':get_all_channels(ED)),
+ ?match({'EXCEPTION',{'CosNotifyChannelAdmin_ChannelNotFound',_}},
+ 'CosEventDomainAdmin_EventDomain':remove_channel(ED, 0)),
+
+ %% Create a new event channel.
+ {Ch1,_} = ?match({{_,key,_,_,_,_}, _},
+ 'CosNotifyChannelAdmin_EventChannelFactory':create_channel(ChFac, [], [])),
+ {Ch2,_} = ?match({{_,key,_,_,_,_}, _},
+ 'CosNotifyChannelAdmin_EventChannelFactory':create_channel(ChFac, [], [])),
+ {Ch3,_} = ?match({{_,key,_,_,_,_}, _},
+ 'CosNotifyChannelAdmin_EventChannelFactory':create_channel(ChFac, [], [])),
+ {Ch4,_} = ?match({{_,key,_,_,_,_}, _},
+ 'CosNotifyChannelAdmin_EventChannelFactory':create_channel(ChFac, [], [])),
+ {Ch5,_} = ?match({{_,key,_,_,_,_}, _},
+ 'CosNotifyChannelAdmin_EventChannelFactory':create_channel(ChFac, [], [])),
+ {Ch6,_} = ?match({{_,key,_,_,_,_}, _},
+ 'CosNotifyChannelAdmin_EventChannelFactory':create_channel(ChFac, [], [])),
+ {Ch7,_} = ?match({{_,key,_,_,_,_}, _},
+ 'CosNotifyChannelAdmin_EventChannelFactory':create_channel(ChFac, [], [])),
+ {Ch8,_} = ?match({{_,key,_,_,_,_}, _},
+ 'CosNotifyChannelAdmin_EventChannelFactory':create_channel(ChFac, [], [])),
+ {Ch9,_} = ?match({{_,key,_,_,_,_}, _},
+ 'CosNotifyChannelAdmin_EventChannelFactory':create_channel(ChFac, [], [])),
+
+ ID1 = 'CosEventDomainAdmin_EventDomain':add_channel(ED, Ch1),
+ ID2 = 'CosEventDomainAdmin_EventDomain':add_channel(ED, Ch2),
+ ID3 = 'CosEventDomainAdmin_EventDomain':add_channel(ED, Ch3),
+ ID4 = 'CosEventDomainAdmin_EventDomain':add_channel(ED, Ch4),
+ ID5 = 'CosEventDomainAdmin_EventDomain':add_channel(ED, Ch5),
+ ID6 = 'CosEventDomainAdmin_EventDomain':add_channel(ED, Ch6),
+ ID7 = 'CosEventDomainAdmin_EventDomain':add_channel(ED, Ch7),
+ ID8 = 'CosEventDomainAdmin_EventDomain':add_channel(ED, Ch8),
+ ID9 = 'CosEventDomainAdmin_EventDomain':add_channel(ED, Ch9),
+ ?match([_,_,_,_,_,_,_,_,_],
+ 'CosEventDomainAdmin_EventDomain':get_all_channels(ED)),
+
+ ?match([], 'CosEventDomainAdmin_EventDomain':get_all_connections(ED)),
+ C1 = #'CosEventDomainAdmin_Connection'{supplier_id=ID2,
+ consumer_id=ID4,
+ ctype='STRUCTURED_EVENT',
+ notification_style='Pull'},
+ C2 = #'CosEventDomainAdmin_Connection'{supplier_id=ID4,
+ consumer_id=ID1,
+ ctype='ANY_EVENT',
+ notification_style='Push'},
+ C3 = #'CosEventDomainAdmin_Connection'{supplier_id=ID1,
+ consumer_id=ID3,
+ ctype='ANY_EVENT',
+ notification_style='Pull'},
+ C4 = #'CosEventDomainAdmin_Connection'{supplier_id=ID3,
+ consumer_id=ID6,
+ ctype='STRUCTURED_EVENT',
+ notification_style='Push'},
+ C5 = #'CosEventDomainAdmin_Connection'{supplier_id=ID5,
+ consumer_id=ID9,
+ ctype='ANY_EVENT',
+ notification_style='Pull'},
+ C6 = #'CosEventDomainAdmin_Connection'{supplier_id=ID9,
+ consumer_id=ID1,
+ ctype='ANY_EVENT',
+ notification_style='Push'},
+ C7 = #'CosEventDomainAdmin_Connection'{supplier_id=ID4,
+ consumer_id=ID7,
+ ctype='STRUCTURED_EVENT',
+ notification_style='Pull'},
+ C8 = #'CosEventDomainAdmin_Connection'{supplier_id=ID7,
+ consumer_id=ID8,
+ ctype='ANY_EVENT',
+ notification_style='Push'},
+ C9 = #'CosEventDomainAdmin_Connection'{supplier_id=ID8,
+ consumer_id=ID4,
+ ctype='ANY_EVENT',
+ notification_style='Pull'},
+ C10 = #'CosEventDomainAdmin_Connection'{supplier_id=ID5,
+ consumer_id=ID4,
+ ctype='ANY_EVENT',
+ notification_style='Pull'},
+ C11 = #'CosEventDomainAdmin_Connection'{supplier_id=ID4,
+ consumer_id=ID6,
+ ctype='ANY_EVENT',
+ notification_style='Pull'},
+ C12 = #'CosEventDomainAdmin_Connection'{supplier_id=ID8,
+ consumer_id=ID6,
+ ctype='ANY_EVENT',
+ notification_style='Pull'},
+
+ CID1 = 'CosEventDomainAdmin_EventDomain':add_connection(ED, C1),
+ ?match([CID1], 'CosEventDomainAdmin_EventDomain':get_all_connections(ED)),
+ _CID2 = 'CosEventDomainAdmin_EventDomain':add_connection(ED, C2),
+ ?match([_,_],
+ 'CosEventDomainAdmin_EventDomain':get_all_connections(ED)),
+ _CID3 = 'CosEventDomainAdmin_EventDomain':add_connection(ED, C3),
+ ?match([_,_,_],
+ 'CosEventDomainAdmin_EventDomain':get_all_connections(ED)),
+ _CID4 = 'CosEventDomainAdmin_EventDomain':add_connection(ED, C4),
+ ?match([_,_,_,_],
+ 'CosEventDomainAdmin_EventDomain':get_all_connections(ED)),
+ _CID5 = 'CosEventDomainAdmin_EventDomain':add_connection(ED, C5),
+ ?match([_,_,_,_,_],
+ 'CosEventDomainAdmin_EventDomain':get_all_connections(ED)),
+ _CID6 = 'CosEventDomainAdmin_EventDomain':add_connection(ED, C6),
+ ?match([_,_,_,_,_,_],
+ 'CosEventDomainAdmin_EventDomain':get_all_connections(ED)),
+ CID7 = 'CosEventDomainAdmin_EventDomain':add_connection(ED, C7),
+ ?match([_,_,_,_,_,_,_],
+ 'CosEventDomainAdmin_EventDomain':get_all_connections(ED)),
+ _CID8 = 'CosEventDomainAdmin_EventDomain':add_connection(ED, C8),
+ ?match([_,_,_,_,_,_,_,_],
+ 'CosEventDomainAdmin_EventDomain':get_all_connections(ED)),
+
+ ?match({'EXCEPTION',{'CosEventDomainAdmin_AlreadyExists', _}},
+ 'CosEventDomainAdmin_EventDomain':add_connection(ED, C8)),
+ %% No cycles should exist.
+ ?match([], 'CosEventDomainAdmin_EventDomain':get_cycles(ED)),
+
+ ?match([_, _], 'CosEventDomainAdmin_EventDomain':get_qos(ED)),
+ AllowCyclic = #'CosNotification_Property'{name=?CycleDetection,
+ value=any:create(orber_tc:short(),
+ ?AuthorizeCycles)},
+ ?match({'EXCEPTION',{'CosNotification_UnsupportedQoS',_,_}},
+ 'CosEventDomainAdmin_EventDomain':set_qos(ED, [AllowCyclic])),
+ ForbidCyclic = #'CosNotification_Property'{name=?CycleDetection,
+ value=any:create(orber_tc:short(),
+ ?ForbidCycles)},
+ %% The same as before; must work.
+ ?match(ok, 'CosEventDomainAdmin_EventDomain':set_qos(ED, [ForbidCyclic])),
+
+ AllowDiamonds = #'CosNotification_Property'{name=?DiamondDetection,
+ value=any:create(orber_tc:short(),
+ ?AuthorizeDiamonds)},
+ %% Since no diamonds allowed before this is always ok.
+ ?match(ok, 'CosEventDomainAdmin_EventDomain':set_qos(ED, [AllowDiamonds])),
+
+ ?match([_, _], 'CosEventDomainAdmin_EventDomain':get_qos(ED)),
+
+ ForbidDiamonds = #'CosNotification_Property'{name=?DiamondDetection,
+ value=any:create(orber_tc:short(),
+ ?ForbidDiamonds)},
+ %% No diamonds created before. Hence, will work.
+ ?match(ok, 'CosEventDomainAdmin_EventDomain':set_qos(ED, [ForbidDiamonds])),
+
+ ?match([_, _], 'CosEventDomainAdmin_EventDomain':get_qos(ED)),
+
+ ?match({ok, [_]}, 'CosEventDomainAdmin_EventDomain':validate_qos(ED,
+ [ForbidDiamonds,
+ ForbidCyclic])),
+ %% No diamonds exists, hence, this is ok.
+ ?match({ok, [_]}, 'CosEventDomainAdmin_EventDomain':validate_qos(ED,
+ [AllowDiamonds,
+ ForbidCyclic])),
+ ?match({'EXCEPTION',{'CosNotification_UnsupportedQoS',_,_}},
+ 'CosEventDomainAdmin_EventDomain':validate_qos(ED, [ForbidDiamonds,
+ AllowCyclic])),
+
+ %% Since the ED is started is asyclic we may not succeed with this invokation.
+ ?match({'EXCEPTION',{'CosEventDomainAdmin_CycleCreationForbidden',_,_}},
+ 'CosEventDomainAdmin_EventDomain':add_connection(ED, C9)),
+ ?match([], 'CosEventDomainAdmin_EventDomain':get_offer_channels(ED, ID2)),
+
+ ?match([2], 'CosEventDomainAdmin_EventDomain':get_offer_channels(ED, ID4)),
+ ?match([_,_,_], 'CosEventDomainAdmin_EventDomain':get_offer_channels(ED, ID8)),
+ ?match({'EXCEPTION',{'CosNotifyChannelAdmin_ChannelNotFound',_}},
+ 'CosEventDomainAdmin_EventDomain':get_offer_channels(ED, 100)),
+ ?match([], 'CosEventDomainAdmin_EventDomain':get_subscription_channels(ED, ID8)),
+ ?match([_,_,_,_,_],
+ 'CosEventDomainAdmin_EventDomain':get_subscription_channels(ED, ID4)),
+ ?match([_,_,_,_,_,_],
+ 'CosEventDomainAdmin_EventDomain':get_subscription_channels(ED, ID2)),
+ ?match({'EXCEPTION',{'CosNotifyChannelAdmin_ChannelNotFound',_}},
+ 'CosEventDomainAdmin_EventDomain':get_subscription_channels(ED, 100)),
+ Nil = corba:create_nil_objref(),
+
+ P2=?match({_,key,_,_,_,_},
+ 'CosEventDomainAdmin_EventDomain':connect_push_supplier_with_id(ED, Nil, ID2)),
+ P7=?match({_,key,_,_,_,_},
+ 'CosEventDomainAdmin_EventDomain':connect_push_supplier_with_id(ED, Nil, ID7)),
+ P8=?match({_,key,_,_,_,_},
+ 'CosEventDomainAdmin_EventDomain':connect_pull_consumer_with_id(ED, Nil, ID8)),
+ P6=?match({_,key,_,_,_,_},
+ 'CosEventDomainAdmin_EventDomain':connect_pull_consumer_with_id(ED, Nil, ID6)),
+ E1 = #any{typecode=tk_long, value=1},
+ E2 = #any{typecode=tk_long, value=2},
+
+ ?match(ok, 'CosNotifyChannelAdmin_ProxyPushConsumer':push(P2, E1)),
+ ?match(E1, 'CosNotifyChannelAdmin_ProxyPullSupplier':pull(P8)),
+ ?match(E1, 'CosNotifyChannelAdmin_ProxyPullSupplier':pull(P6)),
+ ?match(ok, 'CosNotifyChannelAdmin_ProxyPushConsumer':push(P7, E2)),
+ ?match(E2, 'CosNotifyChannelAdmin_ProxyPullSupplier':pull(P8)),
+ timer:sleep(10000),
+ ?match({_,false}, 'CosNotifyChannelAdmin_ProxyPullSupplier':try_pull(P6)),
+
+ ?match(ok, 'CosEventDomainAdmin_EventDomain':remove_connection(ED, CID7)),
+
+ ?match({'EXCEPTION',{'CosEventDomainAdmin_ConnectionNotFound',_}},
+ 'CosEventDomainAdmin_EventDomain':remove_connection(ED, CID7)),
+
+ ?match({'EXCEPTION',{'CosEventDomainAdmin_ConnectionNotFound',_}},
+ 'CosEventDomainAdmin_EventDomain':remove_connection(ED, 100)),
+
+ ?match([], 'CosEventDomainAdmin_EventDomain':get_offer_channels(ED, ID7)),
+ ?match([2], 'CosEventDomainAdmin_EventDomain':get_offer_channels(ED, ID4)),
+
+ ?match([8], 'CosEventDomainAdmin_EventDomain':get_subscription_channels(ED, ID7)),
+ ?match([_,_,_], 'CosEventDomainAdmin_EventDomain':get_subscription_channels(ED, ID4)),
+
+ CID10 = ?match(8, 'CosEventDomainAdmin_EventDomain':add_connection(ED, C7)),
+
+ %% Now we'll check diamond management.
+ %% Currently it should not be possible to create a diamond (due to QoS-setting).
+ ?match({'EXCEPTION',{'CosEventDomainAdmin_DiamondCreationForbidden',_,_}},
+ 'CosEventDomainAdmin_EventDomain':add_connection(ED, C11)),
+ ?match({'EXCEPTION',{'CosEventDomainAdmin_DiamondCreationForbidden',_,_}},
+ 'CosEventDomainAdmin_EventDomain':add_connection(ED, C10)),
+ ?match({'EXCEPTION',{'CosEventDomainAdmin_DiamondCreationForbidden',_,_}},
+ 'CosEventDomainAdmin_EventDomain':add_connection(ED, C12)),
+ ?match(ok, 'CosEventDomainAdmin_EventDomain':set_qos(ED, [AllowDiamonds])),
+
+ CID11 = ?match(9, 'CosEventDomainAdmin_EventDomain':add_connection(ED, C10)),
+ ?match([_,_,_,_,_,_,_,_,_],
+ 'CosEventDomainAdmin_EventDomain':get_all_connections(ED)),
+ ?match([_], 'CosEventDomainAdmin_EventDomain':get_diamonds(ED)),
+
+ CID12 = ?match(10, 'CosEventDomainAdmin_EventDomain':add_connection(ED, C11)),
+ ?match([_, _, _], 'CosEventDomainAdmin_EventDomain':get_diamonds(ED)),
+
+ CID13 = ?match(11, 'CosEventDomainAdmin_EventDomain':add_connection(ED, C12)),
+
+ ?match([_, _, _], 'CosEventDomainAdmin_EventDomain':get_diamonds(ED)),
+
+ ?match({'EXCEPTION',{'CosNotification_UnsupportedQoS',_,_}},
+ 'CosEventDomainAdmin_EventDomain':set_qos(ED, [ForbidDiamonds])),
+
+ ?match(ok, 'CosEventDomainAdmin_EventDomain':remove_connection(ED, CID10)),
+ ?match(ok, 'CosEventDomainAdmin_EventDomain':remove_connection(ED, CID11)),
+ ?match(ok, 'CosEventDomainAdmin_EventDomain':remove_connection(ED, CID12)),
+ ?match(ok, 'CosEventDomainAdmin_EventDomain':remove_connection(ED, CID13)),
+ ?match(ok, 'CosEventDomainAdmin_EventDomain':set_qos(ED, [ForbidDiamonds])),
+ ?match([_, _], 'CosEventDomainAdmin_EventDomain':get_qos(ED)),
+ ?match({'EXCEPTION',{'CosEventDomainAdmin_DiamondCreationForbidden',_,_}},
+ 'CosEventDomainAdmin_EventDomain':add_connection(ED, C10)),
+
+ ?match(ok, 'CosEventDomainAdmin_EventDomain':destroy(ED)),
+
+ ok.
+
+event_domain_factory_api(doc) -> ["Testing the CosEventDomain Factory API", ""];
+event_domain_factory_api(suite) -> [];
+event_domain_factory_api(_Config) ->
+
+ Cyclic = #'CosNotification_Property'{name=?CycleDetection,
+ value=any:create(orber_tc:short(),
+ ?ForbidCycles)},
+
+ BadProp = #'CosNotification_Property'{name="Wrong",
+ value=any:create(orber_tc:short(),
+ ?ForbidCycles)},
+
+ BadQoSVal = #'CosNotification_Property'{name=?CycleDetection,
+ value=any:create(orber_tc:short(),
+ 10)},
+
+ Fac = ?match({_,key,_,_,_,_},
+ cosEventDomainApp:start_factory()),
+ ?match([], 'CosEventDomainAdmin_EventDomainFactory':get_all_domains(Fac)),
+ ?match({'EXCEPTION',{'CosEventDomainAdmin_DomainNotFound',_}},
+ 'CosEventDomainAdmin_EventDomainFactory':get_event_domain(Fac, 0)),
+ {ED,_} = 'CosEventDomainAdmin_EventDomainFactory':create_event_domain(Fac, [Cyclic], []),
+ ?match([0], 'CosEventDomainAdmin_EventDomainFactory':get_all_domains(Fac)),
+ ED = 'CosEventDomainAdmin_EventDomainFactory':get_event_domain(Fac, 0),
+ ?match({'EXCEPTION',{'CosEventDomainAdmin_DomainNotFound',_}},
+ 'CosEventDomainAdmin_EventDomainFactory':get_event_domain(Fac, 1)),
+ corba:dispose(ED),
+ timer:sleep(3000),
+ ?match([], 'CosEventDomainAdmin_EventDomainFactory':get_all_domains(Fac)),
+ ?match({'EXCEPTION',{'CosEventDomainAdmin_DomainNotFound',_}},
+ 'CosEventDomainAdmin_EventDomainFactory':get_event_domain(Fac, 0)),
+ {ED2,_} = ?match({{_,key,_,_,_,_}, _},
+ 'CosEventDomainAdmin_EventDomainFactory':create_event_domain(Fac, [], [])),
+ ?match([1], 'CosEventDomainAdmin_EventDomainFactory':get_all_domains(Fac)),
+ ?match(ED2, 'CosEventDomainAdmin_EventDomainFactory':get_event_domain(Fac, 1)),
+ corba:dispose(ED2),
+
+ ?match({'EXCEPTION', {'CosNotification_UnsupportedQoS',_,_}},
+ 'CosEventDomainAdmin_EventDomainFactory':create_event_domain(Fac, [BadProp], [])),
+ ?match({'EXCEPTION',{'CosNotification_UnsupportedAdmin',_,_}},
+ 'CosEventDomainAdmin_EventDomainFactory':create_event_domain(Fac, [], [BadProp])),
+ ?match({'EXCEPTION',{'CosNotification_UnsupportedQoS',_,_}},
+ 'CosEventDomainAdmin_EventDomainFactory':create_event_domain(Fac, [BadQoSVal], [])),
+ ?match({'EXCEPTION',{'CosNotification_UnsupportedAdmin',_,_}},
+ 'CosEventDomainAdmin_EventDomainFactory':create_event_domain(Fac, [], [BadQoSVal])),
+
+ corba:dispose(Fac),
+ ok.
diff --git a/lib/cosEventDomain/test/generated_SUITE.erl b/lib/cosEventDomain/test/generated_SUITE.erl
new file mode 100644
index 0000000000..6c6996ca79
--- /dev/null
+++ b/lib/cosEventDomain/test/generated_SUITE.erl
@@ -0,0 +1,390 @@
+%%-----------------------------------------------------------------
+%%
+%% %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%
+%%
+%%
+%%-----------------------------------------------------------------
+%% File : generated_SUITE.erl
+%% Purpose :
+%%-----------------------------------------------------------------
+
+-module(generated_SUITE).
+
+-include("test_server.hrl").
+-include_lib("orber/include/corba.hrl").
+
+-define(default_timeout, ?t:minutes(3)).
+
+-define(match(ExpectedRes, Expr),
+ fun() ->
+ AcTuAlReS = (catch (Expr)),
+ case AcTuAlReS of
+ ExpectedRes ->
+ AcTuAlReS;
+ _ ->
+ io:format("###### ERROR ERROR ######~n~p~n",
+ [AcTuAlReS]),
+ ?line exit(AcTuAlReS)
+ end
+ end()).
+
+-define(nomatch(Not, Expr),
+ fun() ->
+ AcTuAlReS = (catch (Expr)),
+ case AcTuAlReS of
+ Not ->
+ io:format("###### ERROR ERROR ######~n~p~n",
+ [AcTuAlReS]),
+ ?line exit(AcTuAlReS);
+ _ ->
+ AcTuAlReS
+ end
+ end()).
+
+
+-define(checktc(_Op),
+ fun(TC) ->
+ case orber_tc:check_tc(TC) of
+ false ->
+ io:format("###### ERROR ERROR ######~n~p - ~p~n", [Op, TC]),
+ ?line exit(TC);
+ true ->
+ true
+ end
+ end).
+
+%%-----------------------------------------------------------------
+%% External exports
+%%-----------------------------------------------------------------
+-export([all/1]).
+
+%%-----------------------------------------------------------------
+%% Internal exports
+%%-----------------------------------------------------------------
+-export([]).
+-compile(export_all).
+
+%%-----------------------------------------------------------------
+%% Func: all/1
+%% Args:
+%% Returns:
+%%-----------------------------------------------------------------
+all(doc) -> ["This suite is for testing IC generated files"];
+all(suite) ->
+ ['CosEventDomainAdmin', 'CosEventDomainAdmin_DiamondSeq',
+ 'CosEventDomainAdmin_AlreadyExists', 'CosEventDomainAdmin_DomainIDSeq',
+ 'CosEventDomainAdmin_Connection', 'CosEventDomainAdmin_ConnectionIDSeq',
+ 'CosEventDomainAdmin_ConnectionNotFound', 'CosEventDomainAdmin_CycleCreationForbidden',
+ 'CosEventDomainAdmin_CycleSeq', 'CosEventDomainAdmin_DiamondCreationForbidden',
+ 'CosEventDomainAdmin_DomainNotFound', 'CosEventDomainAdmin_MemberIDSeq',
+ 'CosEventDomainAdmin_RouteSeq', 'CosEventDomainAdmin_EventDomainFactory',
+ 'CosEventDomainAdmin_EventDomain'].
+
+%%-----------------------------------------------------------------
+%% Init and cleanup functions.
+%%-----------------------------------------------------------------
+init_per_testcase(_Case, Config) ->
+ ?line Dog=test_server:timetrap(?default_timeout),
+ [{watchdog, Dog}|Config].
+
+
+fin_per_testcase(_Case, Config) ->
+ Dog = ?config(watchdog, Config),
+ test_server:timetrap_cancel(Dog),
+ ok.
+
+
+%%-----------------------------------------------------------------
+%% Test Case: 'CosEventDomainAdmin'
+%% Description:
+%%-----------------------------------------------------------------
+'CosEventDomainAdmin'(doc) -> ["CosEventDomainAdmin"];
+'CosEventDomainAdmin'(suite) -> [];
+'CosEventDomainAdmin'(_) ->
+ ?match("CycleDetection", 'CosEventDomainAdmin':'CycleDetection'()),
+ ?match(0, 'CosEventDomainAdmin':'AuthorizeCycles'()),
+ ?match(1, 'CosEventDomainAdmin':'ForbidCycles'()),
+ ?match("DiamondDetection", 'CosEventDomainAdmin':'DiamondDetection'()),
+ ?match(0, 'CosEventDomainAdmin':'AuthorizeDiamonds'()),
+ ?match(1, 'CosEventDomainAdmin':'ForbidDiamonds'()),
+ ok.
+
+%%-----------------------------------------------------------------
+%% Test Case: 'CosEventDomainAdmin_DiamondSeq'
+%% Description:
+%%-----------------------------------------------------------------
+'CosEventDomainAdmin_DiamondSeq'(doc) -> ["CosEventDomainAdmin_DiamondSeq"];
+'CosEventDomainAdmin_DiamondSeq'(suite) -> [];
+'CosEventDomainAdmin_DiamondSeq'(_) ->
+ ?match(true, orber_tc:check_tc('CosEventDomainAdmin_DiamondSeq':tc())),
+ ?match("IDL:omg.org/CosEventDomainAdmin/DiamondSeq:1.0",
+ 'CosEventDomainAdmin_DiamondSeq':id()),
+ ?match("CosEventDomainAdmin_DiamondSeq",
+ 'CosEventDomainAdmin_DiamondSeq':name()),
+ ok.
+
+%%-----------------------------------------------------------------
+%% Test Case: 'CosEventDomainAdmin_AlreadyExists'
+%% Description:
+%%-----------------------------------------------------------------
+'CosEventDomainAdmin_AlreadyExists'(doc) -> ["CosEventDomainAdmin_AlreadyExists"];
+'CosEventDomainAdmin_AlreadyExists'(suite) -> [];
+'CosEventDomainAdmin_AlreadyExists'(_) ->
+ ?match(true, orber_tc:check_tc('CosEventDomainAdmin_AlreadyExists':tc())),
+ ?match("IDL:omg.org/CosEventDomainAdmin/AlreadyExists:1.0",
+ 'CosEventDomainAdmin_AlreadyExists':id()),
+ ?match("CosEventDomainAdmin_AlreadyExists",
+ 'CosEventDomainAdmin_AlreadyExists':name()),
+ ok.
+
+%%-----------------------------------------------------------------
+%% Test Case: 'CosEventDomainAdmin_DomainIDSeq'
+%% Description:
+%%-----------------------------------------------------------------
+'CosEventDomainAdmin_DomainIDSeq'(doc) -> ["CosEventDomainAdmin_DomainIDSeq"];
+'CosEventDomainAdmin_DomainIDSeq'(suite) -> [];
+'CosEventDomainAdmin_DomainIDSeq'(_) ->
+ ?match(true, orber_tc:check_tc('CosEventDomainAdmin_DomainIDSeq':tc())),
+ ?match("IDL:omg.org/CosEventDomainAdmin/DomainIDSeq:1.0",
+ 'CosEventDomainAdmin_DomainIDSeq':id()),
+ ?match("CosEventDomainAdmin_DomainIDSeq",
+ 'CosEventDomainAdmin_DomainIDSeq':name()),
+ ok.
+
+%%-----------------------------------------------------------------
+%% Test Case: 'CosEventDomainAdmin_Connection'
+%% Description:
+%%-----------------------------------------------------------------
+'CosEventDomainAdmin_Connection'(doc) -> ["CosEventDomainAdmin_Connection"];
+'CosEventDomainAdmin_Connection'(suite) -> [];
+'CosEventDomainAdmin_Connection'(_) ->
+ ?match(true, orber_tc:check_tc('CosEventDomainAdmin_Connection':tc())),
+ ?match("IDL:omg.org/CosEventDomainAdmin/Connection:1.0",
+ 'CosEventDomainAdmin_Connection':id()),
+ ?match("CosEventDomainAdmin_Connection",
+ 'CosEventDomainAdmin_Connection':name()),
+ ok.
+
+%%-----------------------------------------------------------------
+%% Test Case: 'CosEventDomainAdmin_ConnectionIDSeq'
+%% Description:
+%%-----------------------------------------------------------------
+'CosEventDomainAdmin_ConnectionIDSeq'(doc) -> ["CosEventDomainAdmin_ConnectionIDSeq"];
+'CosEventDomainAdmin_ConnectionIDSeq'(suite) -> [];
+'CosEventDomainAdmin_ConnectionIDSeq'(_) ->
+ ?match(true, orber_tc:check_tc('CosEventDomainAdmin_ConnectionIDSeq':tc())),
+ ?match("IDL:omg.org/CosEventDomainAdmin/ConnectionIDSeq:1.0",
+ 'CosEventDomainAdmin_ConnectionIDSeq':id()),
+ ?match("CosEventDomainAdmin_ConnectionIDSeq",
+ 'CosEventDomainAdmin_ConnectionIDSeq':name()),
+ ok.
+
+%%-----------------------------------------------------------------
+%% Test Case: 'CosEventDomainAdmin_ConnectionNotFound'
+%% Description:
+%%-----------------------------------------------------------------
+'CosEventDomainAdmin_ConnectionNotFound'(doc) -> ["CosEventDomainAdmin_ConnectionNotFound"];
+'CosEventDomainAdmin_ConnectionNotFound'(suite) -> [];
+'CosEventDomainAdmin_ConnectionNotFound'(_) ->
+ ?match(true, orber_tc:check_tc('CosEventDomainAdmin_ConnectionNotFound':tc())),
+ ?match("IDL:omg.org/CosEventDomainAdmin/ConnectionNotFound:1.0",
+ 'CosEventDomainAdmin_ConnectionNotFound':id()),
+ ?match("CosEventDomainAdmin_ConnectionNotFound",
+ 'CosEventDomainAdmin_ConnectionNotFound':name()),
+ ok.
+
+%%-----------------------------------------------------------------
+%% Test Case: 'CosEventDomainAdmin_CycleCreationForbidden'
+%% Description:
+%%-----------------------------------------------------------------
+'CosEventDomainAdmin_CycleCreationForbidden'(doc) -> ["CosEventDomainAdmin_CycleCreationForbidden"];
+'CosEventDomainAdmin_CycleCreationForbidden'(suite) -> [];
+'CosEventDomainAdmin_CycleCreationForbidden'(_) ->
+ ?match(true, orber_tc:check_tc('CosEventDomainAdmin_CycleCreationForbidden':tc())),
+ ?match("IDL:omg.org/CosEventDomainAdmin/CycleCreationForbidden:1.0",
+ 'CosEventDomainAdmin_CycleCreationForbidden':id()),
+ ?match("CosEventDomainAdmin_CycleCreationForbidden",
+ 'CosEventDomainAdmin_CycleCreationForbidden':name()),
+ ok.
+
+%%-----------------------------------------------------------------
+%% Test Case: 'CosEventDomainAdmin_CycleSeq'
+%% Description:
+%%-----------------------------------------------------------------
+'CosEventDomainAdmin_CycleSeq'(doc) -> ["CosEventDomainAdmin_CycleSeq"];
+'CosEventDomainAdmin_CycleSeq'(suite) -> [];
+'CosEventDomainAdmin_CycleSeq'(_) ->
+ ?match(true, orber_tc:check_tc('CosEventDomainAdmin_CycleSeq':tc())),
+ ?match("IDL:omg.org/CosEventDomainAdmin/CycleSeq:1.0",
+ 'CosEventDomainAdmin_CycleSeq':id()),
+ ?match("CosEventDomainAdmin_CycleSeq",
+ 'CosEventDomainAdmin_CycleSeq':name()),
+ ok.
+
+%%-----------------------------------------------------------------
+%% Test Case: 'CosEventDomainAdmin_DiamondCreationForbidden'
+%% Description:
+%%-----------------------------------------------------------------
+'CosEventDomainAdmin_DiamondCreationForbidden'(doc) -> ["CosEventDomainAdmin_DiamondCreationForbidden"];
+'CosEventDomainAdmin_DiamondCreationForbidden'(suite) -> [];
+'CosEventDomainAdmin_DiamondCreationForbidden'(_) ->
+ ?match(true, orber_tc:check_tc('CosEventDomainAdmin_DiamondCreationForbidden':tc())),
+ ?match("IDL:omg.org/CosEventDomainAdmin/DiamondCreationForbidden:1.0",
+ 'CosEventDomainAdmin_DiamondCreationForbidden':id()),
+ ?match("CosEventDomainAdmin_DiamondCreationForbidden",
+ 'CosEventDomainAdmin_DiamondCreationForbidden':name()),
+ ok.
+
+%%-----------------------------------------------------------------
+%% Test Case: 'CosEventDomainAdmin_DomainNotFound'
+%% Description:
+%%-----------------------------------------------------------------
+'CosEventDomainAdmin_DomainNotFound'(doc) -> ["CosEventDomainAdmin_DomainNotFound"];
+'CosEventDomainAdmin_DomainNotFound'(suite) -> [];
+'CosEventDomainAdmin_DomainNotFound'(_) ->
+ ?match(true, orber_tc:check_tc('CosEventDomainAdmin_DomainNotFound':tc())),
+ ?match("IDL:omg.org/CosEventDomainAdmin/DomainNotFound:1.0",
+ 'CosEventDomainAdmin_DomainNotFound':id()),
+ ?match("CosEventDomainAdmin_DomainNotFound",
+ 'CosEventDomainAdmin_DomainNotFound':name()),
+ ok.
+
+%%-----------------------------------------------------------------
+%% Test Case: 'CosEventDomainAdmin_MemberIDSeq'
+%% Description:
+%%-----------------------------------------------------------------
+'CosEventDomainAdmin_MemberIDSeq'(doc) -> ["CosEventDomainAdmin_MemberIDSeq"];
+'CosEventDomainAdmin_MemberIDSeq'(suite) -> [];
+'CosEventDomainAdmin_MemberIDSeq'(_) ->
+ ?match(true, orber_tc:check_tc('CosEventDomainAdmin_MemberIDSeq':tc())),
+ ?match("IDL:omg.org/CosEventDomainAdmin/MemberIDSeq:1.0",
+ 'CosEventDomainAdmin_MemberIDSeq':id()),
+ ?match("CosEventDomainAdmin_MemberIDSeq",
+ 'CosEventDomainAdmin_MemberIDSeq':name()),
+ ok.
+
+%%-----------------------------------------------------------------
+%% Test Case: 'CosEventDomainAdmin_RouteSeq'
+%% Description:
+%%-----------------------------------------------------------------
+'CosEventDomainAdmin_RouteSeq'(doc) -> ["CosEventDomainAdmin_RouteSeq"];
+'CosEventDomainAdmin_RouteSeq'(suite) -> [];
+'CosEventDomainAdmin_RouteSeq'(_) ->
+ ?match(true, orber_tc:check_tc('CosEventDomainAdmin_RouteSeq':tc())),
+ ?match("IDL:omg.org/CosEventDomainAdmin/RouteSeq:1.0",
+ 'CosEventDomainAdmin_RouteSeq':id()),
+ ?match("CosEventDomainAdmin_RouteSeq",
+ 'CosEventDomainAdmin_RouteSeq':name()),
+ ok.
+
+%%-----------------------------------------------------------------
+%% Test Case: 'CosEventDomainAdmin_EventDomainFactory'
+%% Description:
+%%-----------------------------------------------------------------
+'CosEventDomainAdmin_EventDomainFactory'(doc) -> ["CosEventDomainAdmin_EventDomainFactory"];
+'CosEventDomainAdmin_EventDomainFactory'(suite) -> [];
+'CosEventDomainAdmin_EventDomainFactory'(_) ->
+ ?nomatch(undefined, 'CosEventDomainAdmin_EventDomainFactory':oe_tc(create_event_domain)),
+ ?nomatch(undefined, 'CosEventDomainAdmin_EventDomainFactory':oe_tc(get_all_domains)),
+ ?nomatch(undefined, 'CosEventDomainAdmin_EventDomainFactory':oe_tc(get_event_domain)),
+ ?match(undefined, 'CosEventDomainAdmin_EventDomainFactory':oe_tc(undefined)),
+ ?match([_|_], 'CosEventDomainAdmin_EventDomainFactory':oe_get_interface()),
+ ?match("IDL:omg.org/CosEventDomainAdmin/EventDomainFactory:1.0",
+ 'CosEventDomainAdmin_EventDomainFactory':typeID()),
+ check_tc('CosEventDomainAdmin_EventDomainFactory':oe_get_interface()),
+ ?match(true, 'CosEventDomainAdmin_EventDomainFactory':oe_is_a('CosEventDomainAdmin_EventDomainFactory':typeID())),
+ ?match(false, 'CosEventDomainAdmin_EventDomainFactory':oe_is_a("wrong")),
+ ok.
+
+
+%%-----------------------------------------------------------------
+%% Test Case: 'CosEventDomainAdmin_EventDomain'
+%% Description:
+%%-----------------------------------------------------------------
+'CosEventDomainAdmin_EventDomain'(doc) -> ["CosEventDomainAdmin_EventDomain"];
+'CosEventDomainAdmin_EventDomain'(suite) -> [];
+'CosEventDomainAdmin_EventDomain'(_) ->
+ ?nomatch(undefined, 'CosEventDomainAdmin_EventDomain':oe_tc(add_channel)),
+ ?nomatch(undefined, 'CosEventDomainAdmin_EventDomain':oe_tc(get_all_channels)),
+ ?nomatch(undefined, 'CosEventDomainAdmin_EventDomain':oe_tc(get_channel)),
+ ?nomatch(undefined, 'CosEventDomainAdmin_EventDomain':oe_tc(remove_channel)),
+ ?nomatch(undefined, 'CosEventDomainAdmin_EventDomain':oe_tc(add_connection)),
+ ?nomatch(undefined, 'CosEventDomainAdmin_EventDomain':oe_tc(get_all_connections)),
+ ?nomatch(undefined, 'CosEventDomainAdmin_EventDomain':oe_tc(get_connection)),
+ ?nomatch(undefined, 'CosEventDomainAdmin_EventDomain':oe_tc(remove_connection)),
+ ?nomatch(undefined, 'CosEventDomainAdmin_EventDomain':oe_tc(get_offer_channels)),
+ ?nomatch(undefined, 'CosEventDomainAdmin_EventDomain':oe_tc(get_subscription_channels)),
+ ?nomatch(undefined, 'CosEventDomainAdmin_EventDomain':oe_tc(destroy)),
+ ?nomatch(undefined, 'CosEventDomainAdmin_EventDomain':oe_tc(get_cycles)),
+ ?nomatch(undefined, 'CosEventDomainAdmin_EventDomain':oe_tc(get_diamonds)),
+ ?nomatch(undefined, 'CosEventDomainAdmin_EventDomain':oe_tc(set_default_consumer_channel)),
+ ?nomatch(undefined, 'CosEventDomainAdmin_EventDomain':oe_tc(set_default_supplier_channel)),
+ ?nomatch(undefined, 'CosEventDomainAdmin_EventDomain':oe_tc(connect_push_consumer)),
+ ?nomatch(undefined, 'CosEventDomainAdmin_EventDomain':oe_tc(connect_pull_consumer)),
+ ?nomatch(undefined, 'CosEventDomainAdmin_EventDomain':oe_tc(connect_push_supplier)),
+ ?nomatch(undefined, 'CosEventDomainAdmin_EventDomain':oe_tc(connect_pull_supplier)),
+ ?nomatch(undefined, 'CosEventDomainAdmin_EventDomain':oe_tc(connect_structured_push_consumer)),
+ ?nomatch(undefined, 'CosEventDomainAdmin_EventDomain':oe_tc(connect_structured_pull_consumer)),
+ ?nomatch(undefined, 'CosEventDomainAdmin_EventDomain':oe_tc(connect_structured_push_supplier)),
+ ?nomatch(undefined, 'CosEventDomainAdmin_EventDomain':oe_tc(connect_structured_pull_supplier)),
+ ?nomatch(undefined, 'CosEventDomainAdmin_EventDomain':oe_tc(connect_sequence_push_consumer)),
+ ?nomatch(undefined, 'CosEventDomainAdmin_EventDomain':oe_tc(connect_sequence_pull_consumer)),
+ ?nomatch(undefined, 'CosEventDomainAdmin_EventDomain':oe_tc(connect_sequence_push_supplier)),
+ ?nomatch(undefined, 'CosEventDomainAdmin_EventDomain':oe_tc(connect_sequence_pull_supplier)),
+ ?nomatch(undefined, 'CosEventDomainAdmin_EventDomain':oe_tc(connect_push_consumer_with_id)),
+ ?nomatch(undefined, 'CosEventDomainAdmin_EventDomain':oe_tc(connect_pull_consumer_with_id)),
+ ?nomatch(undefined, 'CosEventDomainAdmin_EventDomain':oe_tc(connect_push_supplier_with_id)),
+ ?nomatch(undefined, 'CosEventDomainAdmin_EventDomain':oe_tc(connect_pull_supplier_with_id)),
+ ?nomatch(undefined, 'CosEventDomainAdmin_EventDomain':oe_tc(connect_structured_push_consumer_with_id)),
+ ?nomatch(undefined, 'CosEventDomainAdmin_EventDomain':oe_tc(connect_structured_pull_consumer_with_id)),
+ ?nomatch(undefined, 'CosEventDomainAdmin_EventDomain':oe_tc(connect_structured_push_supplier_with_id)),
+ ?nomatch(undefined, 'CosEventDomainAdmin_EventDomain':oe_tc(connect_structured_pull_supplier_with_id)),
+ ?nomatch(undefined, 'CosEventDomainAdmin_EventDomain':oe_tc(connect_sequence_push_consumer_with_id)),
+ ?nomatch(undefined, 'CosEventDomainAdmin_EventDomain':oe_tc(connect_sequence_pull_consumer_with_id)),
+ ?nomatch(undefined, 'CosEventDomainAdmin_EventDomain':oe_tc(connect_sequence_push_supplier_with_id)),
+ ?nomatch(undefined, 'CosEventDomainAdmin_EventDomain':oe_tc(connect_sequence_pull_supplier_with_id)),
+ ?nomatch(undefined, 'CosEventDomainAdmin_EventDomain':oe_tc(get_qos)),
+ ?nomatch(undefined, 'CosEventDomainAdmin_EventDomain':oe_tc(set_qos)),
+ ?nomatch(undefined, 'CosEventDomainAdmin_EventDomain':oe_tc(validate_qos)),
+ ?nomatch(undefined, 'CosEventDomainAdmin_EventDomain':oe_tc(get_admin)),
+ ?nomatch(undefined, 'CosEventDomainAdmin_EventDomain':oe_tc(set_admin)),
+ ?match(undefined, 'CosEventDomainAdmin_EventDomain':oe_tc(undefined)),
+ ?match([_|_], 'CosEventDomainAdmin_EventDomain':oe_get_interface()),
+ ?match("IDL:omg.org/CosEventDomainAdmin/EventDomain:1.0",
+ 'CosEventDomainAdmin_EventDomain':typeID()),
+ check_tc('CosEventDomainAdmin_EventDomain':oe_get_interface()),
+ ?match(true, 'CosEventDomainAdmin_EventDomain':oe_is_a('CosEventDomainAdmin_EventDomain':typeID())),
+ ?match(true, 'CosEventDomainAdmin_EventDomain':oe_is_a('CosNotification_QoSAdmin':typeID())),
+ ?match(true, 'CosEventDomainAdmin_EventDomain':oe_is_a('CosNotification_AdminPropertiesAdmin':typeID())),
+ ?match(false, 'CosEventDomainAdmin_EventDomain':oe_is_a("wrong")),
+ ok.
+
+
+
+%%-----------------------------------------------------------------
+%% MISC functions
+%%-----------------------------------------------------------------
+check_tc([]) ->
+ ok;
+check_tc([{Op, {RetType, InParameters, OutParameters}}|T]) ->
+ io:format("checked - ~s~n", [Op]),
+ lists:all(?checktc(Op), [RetType|InParameters]),
+ lists:all(?checktc(Op), OutParameters),
+ check_tc(T).
+
+
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..48d0c04236 100644
--- a/lib/cosFileTransfer/doc/src/notes.xml
+++ b/lib/cosFileTransfer/doc/src/notes.xml
@@ -4,7 +4,7 @@
<chapter>
<header>
<copyright>
- <year>2000</year><year>2009</year>
+ <year>2000</year><year>2010</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
@@ -13,12 +13,12 @@
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>cosFileTransfer Release Notes</title>
@@ -31,6 +31,32 @@
</header>
<section>
+ <title>cosFileTransfer 1.1.10</title>
+
+ <section>
+ <title>Improvements and New Features</title>
+ <list type="bulleted">
+ <item>
+ <p>
+ Removed obsolete SSL dependency.</p>
+ <p>
+ Own Id: OTP-8374 Aux Id:</p>
+ </item>
+ </list>
+ </section>
+
+ <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/test/Makefile b/lib/cosFileTransfer/test/Makefile
new file mode 100644
index 0000000000..60f72644bd
--- /dev/null
+++ b/lib/cosFileTransfer/test/Makefile
@@ -0,0 +1,132 @@
+#
+# %CopyrightBegin%
+#
+# Copyright Ericsson AB 2000-2010. All Rights Reserved.
+#
+# The contents of this file are subject to the Erlang Public License,
+# Version 1.1, (the "License"); you may not use this file except in
+# compliance with the License. You should have received a copy of the
+# Erlang Public License along with this software. If not, it can be
+# retrieved online at http://www.erlang.org/.
+#
+# Software distributed under the License is distributed on an "AS IS"
+# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+# the License for the specific language governing rights and limitations
+# under the License.
+#
+# %CopyrightEnd%
+#
+#
+include $(ERL_TOP)/make/target.mk
+include $(ERL_TOP)/make/$(TARGET)/otp.mk
+
+# ----------------------------------------------------
+# Application version
+# ----------------------------------------------------
+include ../vsn.mk
+VSN=$(COSFILETRANSFER_VSN)
+# ----------------------------------------------------
+# Release directory specification
+# ----------------------------------------------------
+RELSYSDIR = $(RELEASE_PATH)/cosFileTransfer_test
+
+# ----------------------------------------------------
+# Target Specs
+# ----------------------------------------------------
+TEST_SPEC_FILE = cosFileTransfer.spec
+
+
+IDL_FILES =
+
+IDLOUTDIR = idl_output
+
+MODULES = \
+ fileTransfer_SUITE \
+
+GEN_MODULES = \
+
+GEN_HRL_FILES = \
+
+ERL_FILES = $(MODULES:%=%.erl)
+
+HRL_FILES =
+
+GEN_FILES = \
+ $(GEN_HRL_FILES:%=$(IDLOUTDIR)/%) \
+ $(GEN_MODULES:%=$(IDLOUTDIR)/%.erl)
+
+GEN_TARGET_FILES = $(GEN_MODULES:%=$(IDLOUTDIR)/%.$(EMULATOR))
+
+SUITE_TARGET_FILES = $(MODULES:%=%.$(EMULATOR))
+
+TARGET_FILES = \
+ $(GEN_TARGET_FILES) \
+ $(SUITE_TARGET_FILES)
+
+
+# ----------------------------------------------------
+# PROGRAMS
+# ----------------------------------------------------
+LOCAL_CLASSPATH = $(ERL_TOP)lib/cosFileTransfer/priv:$(ERL_TOP)lib/cosFileTransfer/test
+# ----------------------------------------------------
+# FLAGS
+# ----------------------------------------------------
+ERL_IDL_FLAGS += -pa $(ERL_TOP)/lib/cosFileTransfer/ebin \
+ -pa $(ERL_TOP)/lib/cosFileTransfer/src \
+ -pa $(ERL_TOP)/lib/cosFileTransfer/include \
+ -pa $(ERL_TOP)/lib/cosProperty/ebin \
+ -pa $(ERL_TOP)/lib/cosProperty/include \
+ -pa $(ERL_TOP)/lib/orber/ebin \
+ -pa $(ERL_TOP)/lib/ic/ebin
+
+ERL_COMPILE_FLAGS += \
+ $(ERL_IDL_FLAGS) \
+ -pa $(ERL_TOP)/lib/orber/include \
+ -pa $(ERL_TOP)/lib/cosProperty/include \
+ -pa $(ERL_TOP)/internal_tools/test_server/ebin \
+ -pa $(ERL_TOP)/lib/cosFileTransfer/ebin \
+ -pa $(ERL_TOP)/lib/cosFileTransfer/include \
+ -pa $(ERL_TOP)/lib/cosFileTransfer/test/idl_output \
+ -I$(ERL_TOP)/lib/orber/include \
+ -I$(ERL_TOP)/lib/cosProperty/include \
+ -I$(ERL_TOP)/lib/cosFileTransfer/src \
+ -I$(ERL_TOP)/lib/cosFileTransfer/include \
+ -I$(ERL_TOP)/lib/cosFileTransfer \
+ -I$(ERL_TOP)/lib/cosFileTransfer/test/$(IDLOUTDIR) \
+ -I$(ERL_TOP)/lib/test_server/include
+
+# ----------------------------------------------------
+# Targets
+# ----------------------------------------------------
+
+
+tests debug opt: $(TARGET_FILES)
+
+clean:
+ rm -f idl_output/*
+ rm -f $(TARGET_FILES)
+ rm -f errs core *~
+
+docs:
+
+# ----------------------------------------------------
+# Special Targets
+# ----------------------------------------------------
+
+# ----------------------------------------------------
+# Release Targets
+# ----------------------------------------------------
+# We don't copy generated intermediate erlang and hrl files
+
+include $(ERL_TOP)/make/otp_release_targets.mk
+
+release_spec:
+
+release_docs_spec:
+
+release_tests_spec: tests
+ $(INSTALL_DIR) $(RELSYSDIR)
+ $(INSTALL_DATA) $(IDL_FILES) $(TEST_SPEC_FILE) \
+ $(ERL_FILES) $(RELSYSDIR)
+ $(INSTALL_DATA) $(SUITE_TARGET_FILES) $(RELSYSDIR)
+ chmod -f -R u+w $(RELSYSDIR)
diff --git a/lib/cosFileTransfer/test/cosFileTransfer.spec b/lib/cosFileTransfer/test/cosFileTransfer.spec
new file mode 100644
index 0000000000..80fe919f2a
--- /dev/null
+++ b/lib/cosFileTransfer/test/cosFileTransfer.spec
@@ -0,0 +1 @@
+{topcase, {dir, "../cosFileTransfer_test"}}.
diff --git a/lib/cosFileTransfer/test/fileTransfer_SUITE.erl b/lib/cosFileTransfer/test/fileTransfer_SUITE.erl
new file mode 100644
index 0000000000..f877e3ceda
--- /dev/null
+++ b/lib/cosFileTransfer/test/fileTransfer_SUITE.erl
@@ -0,0 +1,954 @@
+%%-----------------------------------------------------------------------
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 2000-2010. All Rights Reserved.
+%%
+%% The contents of this file are subject to the Erlang Public License,
+%% Version 1.1, (the "License"); you may not use this file except in
+%% compliance with the License. You should have received a copy of the
+%% Erlang Public License along with this software. If not, it can be
+%% retrieved online at http://www.erlang.org/.
+%%
+%% Software distributed under the License is distributed on an "AS IS"
+%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+%% the License for the specific language governing rights and limitations
+%% under the License.
+%%
+%% %CopyrightEnd%
+%%
+%%
+%%----------------------------------------------------------------------
+%% File : fileTransfer_SUITE.erl
+%% Purpose :
+%%----------------------------------------------------------------------
+
+-module(fileTransfer_SUITE).
+
+
+
+%%--------------- INCLUDES -----------------------------------
+-include_lib("cosFileTransfer/src/cosFileTransferApp.hrl").
+
+-include("test_server.hrl").
+
+%%--------------- DEFINES ------------------------------------
+-define(default_timeout, ?t:minutes(20)).
+-define(match(ExpectedRes, Expr),
+ fun() ->
+ AcTuAlReS = (catch (Expr)),
+ case AcTuAlReS of
+ ExpectedRes ->
+ io:format("------ CORRECT RESULT ------~n~p~n",
+ [AcTuAlReS]),
+ AcTuAlReS;
+ _ ->
+ io:format("###### ERROR ERROR ######~n~p~n",
+ [AcTuAlReS]),
+ exit(AcTuAlReS)
+ end
+ end()).
+
+-define(matchnopr(ExpectedRes, Expr),
+ fun() ->
+ AcTuAlReS = (catch (Expr)),
+ case AcTuAlReS of
+ ExpectedRes ->
+ io:format("------ CORRECT RESULT (~p) ------~n", [?LINE]),
+ AcTuAlReS;
+ _ ->
+ io:format("###### ERROR ERROR ######~n~p~n",
+ [AcTuAlReS]),
+ exit(AcTuAlReS)
+ end
+ end()).
+
+
+
+
+
+%%-----------------------------------------------------------------
+%% External exports
+%%-----------------------------------------------------------------
+-export([all/1,
+ cases/0,
+ init_all/1,
+ finish_all/1,
+ fileIterator_api/1,
+ fts_ftp_file_api/1,
+ fts_ftp_file_ssl_api/1,
+ fts_ftp_dir_api/1,
+ fts_native_file_api/1,
+ fts_native_file_ssl_api/1,
+ fts_native_dir_api/1,
+ init_per_testcase/2,
+ fin_per_testcase/2,
+ install_data/2,
+ uninstall_data/1,
+ slave_sup/0,
+ app_test/1]).
+
+%%-----------------------------------------------------------------
+%% Func: all/1
+%% Args:
+%% Returns:
+%%-----------------------------------------------------------------
+all(doc) -> ["API tests for the cosFileTransfer interfaces", ""];
+all(suite) -> {req,
+ [mnesia, orber],
+ {conf, init_all, cases(), finish_all}}.
+
+cases() ->
+ [fts_ftp_dir_api, fts_ftp_file_api, fts_ftp_file_ssl_api,
+ fts_native_dir_api, fts_native_file_api, fts_native_file_ssl_api,
+ fileIterator_api, app_test].
+
+%%-----------------------------------------------------------------
+%% Init and cleanup functions.
+%%-----------------------------------------------------------------
+
+init_per_testcase(_Case, Config) ->
+ ?line Dog=test_server:timetrap(?default_timeout),
+ [{watchdog, Dog}|Config].
+
+
+fin_per_testcase(_Case, Config) ->
+ Dog = ?config(watchdog, Config),
+ test_server:timetrap_cancel(Dog),
+ ok.
+
+init_all(Config) ->
+ orber:jump_start(),
+ cosProperty:install(),
+ cosProperty:start(),
+ Dir = filename:join([code:lib_dir(ssl), "examples", "certs", "etc"]),
+ %% Client
+ cosFileTransferApp:configure(ssl_client_certfile,
+ filename:join([Dir, "client", "cert.pem"])),
+ cosFileTransferApp:configure(ssl_client_cacertfile,
+ filename:join([Dir, "client", "cacerts.pem"])),
+ cosFileTransferApp:configure(ssl_client_verify, 1),
+ cosFileTransferApp:configure(ssl_client_depth, 0),
+ %% Server
+ cosFileTransferApp:configure(ssl_server_certfile,
+ filename:join([Dir, "server", "cert.pem"])),
+ cosFileTransferApp:configure(ssl_server_cacertfile,
+ filename:join([Dir, "server", "cacerts.pem"])),
+ cosFileTransferApp:configure(ssl_server_verify, 1),
+ cosFileTransferApp:configure(ssl_server_depth, 0),
+ crypto:start(),
+ ssl:start(),
+ cosFileTransferApp:install(),
+ cosFileTransferApp:start(),
+ if
+ is_list(Config) ->
+ Config;
+ true ->
+ exit("Config not a list")
+ end.
+
+finish_all(Config) ->
+ ssl:stop(),
+ crypto:stop(),
+ cosFileTransferApp:stop(),
+ cosProperty:stop(),
+ cosProperty:uninstall(),
+ cosFileTransferApp:uninstall(),
+ orber:jump_stop(),
+ Config.
+
+%%-----------------------------------------------------------------
+%% Local definitions
+%%-----------------------------------------------------------------
+-define(FTP_USER, "anonymous").
+-define(FTP_PASS, "fileTransfer_SUITE@localhost").
+-define(TEST_DIR,["/", "incoming"]).
+
+
+-define(FTP_PORT, 21).
+-define(FTP_ACC, "anonymous").
+
+-define(BAD_HOST, "badhostname").
+-define(BAD_USER, "baduser").
+-define(BAD_DIR, "baddirectory").
+
+-define(TEST_FILE_DATA, "If this file exists after a completed test an error occurred.").
+-define(TEST_FILE_DATA2, "1234567890123").
+
+
+%%-----------------------------------------------------------------
+%% aoo-file test
+%%-----------------------------------------------------------------
+app_test(doc) -> [];
+app_test(suite) -> [];
+app_test(_Config) ->
+ ?line ok=?t:app_test(cosFileTransfer),
+ ok.
+
+%%-----------------------------------------------------------------
+%% FileIterator API tests
+%%-----------------------------------------------------------------
+fileIterator_api(doc) -> ["CosFileTransfer FileIterator API tests.", ""];
+fileIterator_api(suite) -> [];
+fileIterator_api(Config) ->
+ case ftp_host(Config) of
+ {skipped, SkippedReason} ->
+ {skipped, SkippedReason};
+ Host ->
+
+ ?line {ok, Node} = create_node("fileIterator_api", 4008, normal),
+ ?line ?match(ok, remote_apply(Node, ?MODULE, install_data,
+ [tcp, {{'NATIVE',
+ 'cosFileTransferNATIVE_file'}, Host,
+ "fileIterator_api"}])),
+
+ %% Create a Virtual File System.
+%% ?line VFS = ?match({_,_,_,_,_,_},
+%% cosFileTransferApp:create_VFS({'NATIVE',
+%% 'cosFileTransferNATIVE_file'},
+%% [], Host, ?FTP_PORT)),
+ ?line VFS = ?matchnopr({'IOP_IOR',"IDL:omg.org/CosFileTransfer/VirtualFileSystem:1.0",_},
+ corba:string_to_object("corbaname::1.2@localhost:4008/NameService#fileIterator_api")),
+
+ %% Start two File Transfer Sessions (Source and Target).
+ ?line {FS, Dir} = ?matchnopr({{_,_,_},{_,_,_}},
+ 'CosFileTransfer_VirtualFileSystem':login(VFS,
+ ?FTP_USER,
+ ?FTP_PASS,
+ ?FTP_ACC)),
+
+ %% Do some basic test on one of the Directories attributes.
+ ?line ?match([_H|_], 'CosFileTransfer_Directory':'_get_name'(Dir)),
+ ?line ?match([_H|_], 'CosFileTransfer_Directory':'_get_complete_file_name'(Dir)),
+ ?line ?match({'IOP_IOR',[],[]}, 'CosFileTransfer_Directory':'_get_parent'(Dir)),
+ ?line ?matchnopr(FS, 'CosFileTransfer_Directory':'_get_associated_session'(Dir)),
+ {ok,[],FileIter} = ?match({ok,[],_}, 'CosFileTransfer_Directory':list(Dir, 0)),
+ %% Usually the working directory for the test is not empty so no need for
+ %% creating files of our own?!
+ #any{value=Children} = ?match({any, _, _},
+ 'CosPropertyService_PropertySet':
+ get_property_value(Dir, "num_children")),
+
+ if
+ Children > 5 ->
+ ?line ?matchnopr({true, _}, 'CosFileTransfer_FileIterator':next_one(FileIter)),
+ ?line ?matchnopr({true, _}, 'CosFileTransfer_FileIterator':next_n(FileIter, 3)),
+ ?line ?matchnopr({true, _}, 'CosFileTransfer_FileIterator':next_n(FileIter,
+ Children)),
+ ?line ?matchnopr({false, _}, 'CosFileTransfer_FileIterator':next_one(FileIter)),
+ ?line ?match({false, []}, 'CosFileTransfer_FileIterator':next_n(FileIter, 1)),
+ ok;
+ true ->
+ ok
+ end,
+ ?line ?match(ok, 'CosFileTransfer_FileIterator':destroy(FileIter)),
+ ?line ?match(false, corba_object:non_existent(FS)),
+ ?line ?match(ok, 'CosFileTransfer_FileTransferSession':logout(FS)),
+ %% To make sure Orber can remove it from mnesia.
+ timer:sleep(1000),
+ ?line ?match(true, corba_object:non_existent(FS)),
+ ?line ?match(ok, remote_apply(Node, ?MODULE, uninstall_data, ["fileIterator_api"])),
+ stop_orber_remote(Node, normal),
+ ok
+ end.
+
+
+%%-----------------------------------------------------------------
+%% FileTransferSession API tests
+%%-----------------------------------------------------------------
+fts_ftp_file_api(doc) -> ["CosFileTransfer FTP FileTransferSession API tests.", ""];
+fts_ftp_file_api(suite) -> [];
+fts_ftp_file_api(Config) ->
+ ?line {ok, Node} = create_node("ftp_file_api", 4004, normal),
+ file_helper(Config, 'FTP', ?TEST_DIR, Node, 4004, "ftp_file_api", tcp).
+
+fts_ftp_file_ssl_api(doc) -> ["CosFileTransfer FTP FileTransferSession API tests.", ""];
+fts_ftp_file_ssl_api(suite) -> [];
+fts_ftp_file_ssl_api(Config) ->
+ case os:type() of
+ vxworks ->
+ {skipped, "No SSL-support for VxWorks."};
+ _ ->
+ ?line {ok, Node} = create_node("ftp_file_api_ssl", {4005, 1}, ssl),
+ file_helper(Config, 'FTP', ?TEST_DIR, Node, 4005, "ftp_file_api_ssl", ssl)
+ end.
+
+fts_native_file_api(doc) -> ["CosFileTransfer NATIVE FileTransferSession API tests.", ""];
+fts_native_file_api(suite) -> [];
+fts_native_file_api(Config) ->
+ ?line {ok, Node} = create_node("native_file_api", 4006, normal),
+ {ok, Pwd} = file:get_cwd(),
+ file_helper(Config,{'NATIVE', 'cosFileTransferNATIVE_file'},filename:split(Pwd),
+ Node, 4006, "native_file_api", tcp).
+
+fts_native_file_ssl_api(doc) -> ["CosFileTransfer NATIVE FileTransferSession API tests.", ""];
+fts_native_file_ssl_api(suite) -> [];
+fts_native_file_ssl_api(Config) ->
+ case os:type() of
+ vxworks ->
+ {skipped, "No SSL-support for VxWorks."};
+ _ ->
+ ?line {ok, Node} = create_node("native_file_ssl_api", {4007, 1}, ssl),
+ {ok, Pwd} = file:get_cwd(),
+ file_helper(Config,{'NATIVE', 'cosFileTransferNATIVE_file'},filename:split(Pwd),
+ Node, 4007, "native_file_ssl_api", ssl)
+ end.
+
+
+
+file_helper(Config, WhichType, TEST_DIR, Node, Port, Name, Type) ->
+ case ftp_host(Config) of
+ {skipped, SkippedReason} ->
+ {skipped, SkippedReason};
+ Host ->
+ TEST_SOURCE = TEST_DIR ++ [create_name(remove_me_source)],
+ TEST_SOURCE2 = TEST_DIR ++ [create_name(remove_me_source)],
+ TEST_TARGET = TEST_DIR ++ [create_name(remove_me_target)],
+
+ io:format("<<<<<< CosFileTransfer Testing Configuration >>>>>>~n",[]),
+ io:format("Source: ~p~nTarget: ~p~n", [TEST_SOURCE, TEST_TARGET]),
+
+ ?line ?match(ok, remote_apply(Node, ?MODULE, install_data,
+ [Type, {WhichType, Host, Name}])),
+
+ ?line VFST = ?match({'IOP_IOR',"IDL:omg.org/CosFileTransfer/VirtualFileSystem:1.0",_},
+ corba:string_to_object("corbaname::1.2@localhost:"++integer_to_list(Port)++"/NameService#"++Name)),
+
+
+ %% Create a Virtual File System.
+ ?line VFS = ?match({_,_,_,_,_,_},
+ cosFileTransferApp:create_VFS(WhichType, [], Host, ?FTP_PORT,
+ [{protocol, Type}])),
+ %% Start two File Transfer Sessions (Source and Target).
+ ?line {FST, _DirT} = ?match({{_,_,_},{_,_,_}},
+ 'CosFileTransfer_VirtualFileSystem':login(VFST,
+ ?FTP_USER,
+ ?FTP_PASS,
+ ?FTP_ACC)),
+ ?line {FSS, DirS} = ?match({{_,_,_,_,_,_},{_,_,_,_,_,_}},
+ 'CosFileTransfer_VirtualFileSystem':login(VFS,
+ ?FTP_USER,
+ ?FTP_PASS,
+ ?FTP_ACC)),
+
+ %% Do some basic test on one of the Directories attributes.
+ ?line ?match([_H|_], 'CosFileTransfer_Directory':'_get_name'(DirS)),
+ ?line ?match([_H|_], 'CosFileTransfer_Directory':'_get_complete_file_name'(DirS)),
+ ?line ?match({'IOP_IOR',[],[]}, 'CosFileTransfer_Directory':'_get_parent'(DirS)),
+ ?line ?match(FSS, 'CosFileTransfer_Directory':'_get_associated_session'(DirS)),
+
+ %% Get a FileList before we create any new Files
+ ?line #'CosFileTransfer_FileWrapper'{the_file = Dir} =
+ ?match({'CosFileTransfer_FileWrapper', _, ndirectory},
+ 'CosFileTransfer_FileTransferSession':get_file(FSS, TEST_DIR)),
+ ?line {ok,FileList, Iter1} = ?match({ok,_,_}, 'CosFileTransfer_Directory':list(Dir, 10)),
+ ?line loop_files(FileList),
+
+ case Iter1 of
+ {'IOP_IOR',[],[]} ->
+ ok;
+ _->
+ ?line ?match(ok, 'CosFileTransfer_FileIterator':destroy(Iter1))
+ end,
+
+ #any{value=Count1} = ?match({any, _, _}, 'CosPropertyService_PropertySet':
+ get_property_value(Dir, "num_children")),
+
+ %% Now we want to transfer a file from source to target. First, we'll create
+ %% a a file to work with.
+ ?line create_file_on_source_node(WhichType, Config, Host,
+ filename:join(TEST_SOURCE), TEST_DIR,
+ ?TEST_FILE_DATA),
+ ?line create_file_on_source_node(WhichType, Config, Host,
+ filename:join(TEST_SOURCE2), TEST_DIR,
+ ?TEST_FILE_DATA2),
+
+ ?line #'CosFileTransfer_FileWrapper'{the_file = FileS} =
+ ?matchnopr({'CosFileTransfer_FileWrapper', _, nfile},
+ 'CosFileTransfer_FileTransferSession':get_file(FSS, TEST_SOURCE)),
+ ?line #'CosFileTransfer_FileWrapper'{the_file = FileS2} =
+ ?matchnopr({'CosFileTransfer_FileWrapper', _, nfile},
+ 'CosFileTransfer_FileTransferSession':get_file(FSS, TEST_SOURCE2)),
+
+ #any{value=Count2} = ?match({any, _, _}, 'CosPropertyService_PropertySet':
+ get_property_value(Dir, "num_children")),
+ timer:sleep(2000),
+ ?match(true, (Count1+2 == Count2)),
+
+ %% Create a target File
+ ?line FileT = ?matchnopr({_,_,_},
+ 'CosFileTransfer_FileTransferSession':create_file(FST, TEST_TARGET)),
+ %% Try to delete the non-existing file.
+ ?line ?match({'EXCEPTION', _},
+ 'CosFileTransfer_FileTransferSession':delete(FST, FileT)),
+
+ ?line ?match(ok, 'CosFileTransfer_FileTransferSession':transfer(FSS, FileS, FileT)),
+
+ %% Remove this test when ftp supports append.
+ case WhichType of
+ {'NATIVE', 'cosFileTransferNATIVE_file'} ->
+ ?line ?match(ok, 'CosFileTransfer_FileTransferSession':append(FSS, FileS, FileT)),
+ ?line ?match(ok, 'CosFileTransfer_FileTransferSession':insert(FSS, FileS2, FileT, 7));
+ _->
+ ok
+ end,
+
+ %% Delete source and target files
+ ?line ?match(ok, 'CosFileTransfer_FileTransferSession':delete(FSS, FileS)),
+ ?line ?match(ok, 'CosFileTransfer_FileTransferSession':delete(FSS, FileS2)),
+ ?line ?match(ok, 'CosFileTransfer_FileTransferSession':delete(FST, FileT)),
+
+ %% Should be back where we started.
+ timer:sleep(2000),
+ #any{value=Count3} = ?match({any, _, _}, 'CosPropertyService_PropertySet':
+ get_property_value(Dir, "num_children")),
+ ?match(true, (Count1 == Count3)),
+
+
+ ?line ?match(false, corba_object:non_existent(FSS)),
+ ?line ?match(false, corba_object:non_existent(FST)),
+ ?line ?match(ok, 'CosFileTransfer_FileTransferSession':logout(FSS)),
+ ?line ?match(ok, 'CosFileTransfer_FileTransferSession':logout(FST)),
+ %% To make sure Orber can remove it from mnesia.
+ timer:sleep(2000),
+ ?line ?match(true, corba_object:non_existent(FSS)),
+ ?line ?match(true, corba_object:non_existent(FST)),
+ ?line ?match(ok, remote_apply(Node, ?MODULE, uninstall_data, [Name])),
+ stop_orber_remote(Node, normal),
+ ok
+ end.
+
+%%-----------------------------------------------------------------
+%% FileTransferSession API tests
+%%-----------------------------------------------------------------
+fts_ftp_dir_api(doc) -> ["CosFileTransfer FTP FileTransferSession API tests.", ""];
+fts_ftp_dir_api(suite) -> [];
+fts_ftp_dir_api(Config) ->
+ ?line {ok, Node} = create_node("ftp_dir_api", 4009, normal),
+ dir_helper(Config, 'FTP', ?TEST_DIR, Node, 4009, "ftp_dir_api").
+
+
+fts_native_dir_api(doc) -> ["CosFileTransfer NATIVE FileTransferSession API tests.", ""];
+fts_native_dir_api(suite) -> [];
+fts_native_dir_api(Config) ->
+ ?line {ok, Node} = create_node("native_dir_api", 4010, normal),
+ {ok, Pwd} = file:get_cwd(),
+ dir_helper(Config, {'NATIVE', 'cosFileTransferNATIVE_file'},
+ filename:split(Pwd), Node, 4010, "native_dir_api").
+
+dir_helper(Config, WhichType, TEST_DIR, Node, Port, Name) ->
+ case ftp_host(Config) of
+ {skipped, SkippedReason} ->
+ {skipped, SkippedReason};
+ Host ->
+ TEST_DIR_LEVEL1 = TEST_DIR ++ [create_name(remove_me_dir1)],
+ TEST_DIR_LEVEL2 = TEST_DIR_LEVEL1 ++ [create_name(remove_me_dir2)],
+
+ io:format("<<<<<< CosFileTransfer Testing Configuration >>>>>>~n",[]),
+ io:format("Top Dir: ~p~nLevel2 Dir: ~p~n", [TEST_DIR_LEVEL1, TEST_DIR_LEVEL2]),
+
+ ?line ?match(ok, remote_apply(Node, ?MODULE, install_data,
+ [tcp, {WhichType, Host, Name}])),
+
+ ?line VFS = ?matchnopr({'IOP_IOR',"IDL:omg.org/CosFileTransfer/VirtualFileSystem:1.0",_},
+ corba:string_to_object("corbaname::1.2@localhost:"++integer_to_list(Port)++"/NameService#"++Name)),
+
+ %% Start two File Transfer Sessions (Source and Target).
+ ?line {FS, DirS} = ?matchnopr({{'IOP_IOR',_,_}, _},
+ 'CosFileTransfer_VirtualFileSystem':login(VFS,
+ ?FTP_USER,
+ ?FTP_PASS,
+ ?FTP_ACC)),
+
+ %% Do some basic test on one of the Directories attributes.
+ ?line ?match([_H|_], 'CosFileTransfer_Directory':'_get_name'(DirS)),
+ ?line ?match([_H|_], 'CosFileTransfer_Directory':'_get_complete_file_name'(DirS)),
+ ?line ?match({'IOP_IOR',[],[]}, 'CosFileTransfer_Directory':'_get_parent'(DirS)),
+ ?line ?matchnopr(FS, 'CosFileTransfer_Directory':'_get_associated_session'(DirS)),
+
+ %% Create a Root Directory. Currently we only need to create one but
+ %% later on, when supporting other protocols than FTP it's not enough.
+ ?line Dir1 = 'CosFileTransfer_FileTransferSession':create_directory(FS,
+ TEST_DIR_LEVEL1),
+ io:format("<<<<<< CosFileTransfer Testing Properties >>>>>>~n",[]),
+ ?line ?match({ok, [tk_long, tk_boolean]},
+ 'CosFileTransfer_Directory':get_allowed_property_types(Dir1)),
+ ?line ?match({ok, [_,_]},
+ 'CosFileTransfer_Directory':get_allowed_properties(Dir1)),
+ ?line ?match({'EXCEPTION', _},
+ 'CosFileTransfer_Directory':define_property_with_mode(Dir1,
+ "num_children",
+ #any{typecode=tk_long, value=0},
+ fixed_readonly)),
+ ?line ?match({'EXCEPTION', _},
+ 'CosFileTransfer_Directory':define_property_with_mode(Dir1,
+ "wrong",
+ #any{typecode=tk_long, value=0},
+ fixed_readonly)),
+ ?line ?match({'EXCEPTION', _},
+ 'CosFileTransfer_Directory':define_property_with_mode(Dir1,
+ "num_children",
+ #any{typecode=tk_short, value=0},
+ fixed_readonly)),
+ ?line ?match({'EXCEPTION', _},
+ 'CosFileTransfer_Directory':define_property_with_mode(Dir1,
+ "num_children",
+ #any{typecode=tk_long, value=0},
+ fixed_normal)),
+ ?line ?match({'EXCEPTION', _},
+ 'CosFileTransfer_Directory':define_properties_with_modes(Dir1,
+ [#'CosPropertyService_PropertyDef'
+ {property_name = "num_children",
+ property_value = #any{typecode=tk_long, value=0},
+ property_mode = fixed_readonly}])),
+ ?line ?match(fixed_readonly,
+ 'CosFileTransfer_Directory':get_property_mode(Dir1, "num_children")),
+ ?line ?match({true,
+ [#'CosPropertyService_PropertyMode'{property_name = "num_children",
+ property_mode = fixed_readonly}]},
+ 'CosFileTransfer_Directory':get_property_modes(Dir1, ["num_children"])),
+ ?line ?match({'EXCEPTION', _},
+ 'CosFileTransfer_Directory':set_property_mode(Dir1, "num_children", fixed_readonly)),
+
+ ?line ?match({'EXCEPTION', _},
+ 'CosFileTransfer_Directory':
+ set_property_modes(Dir1,
+ [#'CosPropertyService_PropertyMode'
+ {property_name = "num_children",
+ property_mode = fixed_readonly}])),
+ ?line ?match({'EXCEPTION', _},
+ 'CosFileTransfer_Directory':
+ set_property_modes(Dir1,
+ [#'CosPropertyService_PropertyMode'
+ {property_name = "wrong",
+ property_mode = fixed_readonly}])),
+ ?line ?match({'EXCEPTION', _},
+ 'CosFileTransfer_Directory':
+ set_property_modes(Dir1,
+ [#'CosPropertyService_PropertyMode'
+ {property_name = "num_children",
+ property_mode = fixed_normal}])),
+ ?line ?match({'EXCEPTION', _},
+ 'CosFileTransfer_Directory':define_property(Dir1,
+ "num_children",
+ #any{typecode=tk_long, value=0})),
+ ?line ?match({'EXCEPTION', _},
+ 'CosFileTransfer_Directory':define_property(Dir1,
+ "wrong",
+ #any{typecode=tk_long, value=0})),
+ ?line ?match({'EXCEPTION', _},
+ 'CosFileTransfer_Directory':define_property(Dir1,
+ "num_children",
+ #any{typecode=tk_short, value=0})),
+
+ ?line ?match({'EXCEPTION', _},
+ 'CosFileTransfer_Directory':define_property(Dir1,
+ "num_children",
+ #any{typecode=tk_long, value=0})),
+
+ ?line ?match({'EXCEPTION', _},
+ 'CosFileTransfer_Directory':
+ define_properties(Dir1,
+ [#'CosPropertyService_Property'
+ {property_name = "num_children",
+ property_value = #any{typecode=tk_long,
+ value=0}}])),
+ ?line ?match({'EXCEPTION', _},
+ 'CosFileTransfer_Directory':
+ define_properties(Dir1,
+ [#'CosPropertyService_Property'
+ {property_name = "wrong",
+ property_value = #any{typecode=tk_long,
+ value=0}}])),
+ ?line ?match({'EXCEPTION', _},
+ 'CosFileTransfer_Directory':
+ define_properties(Dir1,
+ [#'CosPropertyService_Property'
+ {property_name = "num_children",
+ property_value = #any{typecode=tk_short,
+ value=0}}])),
+ ?line ?match(2, 'CosFileTransfer_Directory':get_number_of_properties(Dir1)),
+
+ ?line ?match({ok, ["num_children", "is_directory"], {'IOP_IOR',[],[]}},
+ 'CosFileTransfer_Directory':get_all_property_names(Dir1, 2)),
+ ?line ?match({ok, ["is_directory"], _},
+ 'CosFileTransfer_Directory':get_all_property_names(Dir1, 1)),
+
+ ?line ?match(#any{},
+ 'CosFileTransfer_Directory':get_property_value(Dir1, "num_children")),
+ ?line ?match(#any{},
+ 'CosFileTransfer_Directory':get_property_value(Dir1, "is_directory")),
+ ?line ?match({'EXCEPTION', _},
+ 'CosFileTransfer_Directory':get_property_value(Dir1, "wrong")),
+
+ ?line ?match({true,
+ [#'CosPropertyService_Property'{property_name = "num_children"}]},
+ 'CosFileTransfer_Directory':get_properties(Dir1, ["num_children"])),
+ ?line ?match({false,
+ [#'CosPropertyService_Property'{property_name = "wrong"}]},
+ 'CosFileTransfer_Directory':get_properties(Dir1, ["wrong"])),
+
+ ?line ?match({ok, [_],_},
+ 'CosFileTransfer_Directory':get_all_properties(Dir1, 1)),
+ ?line ?match({ok, [_,_], {'IOP_IOR',[],[]}},
+ 'CosFileTransfer_Directory':get_all_properties(Dir1, 2)),
+
+ ?line ?match({'EXCEPTION', _},
+ 'CosFileTransfer_Directory':delete_property(Dir1, "num_children")),
+ ?line ?match({'EXCEPTION', _},
+ 'CosFileTransfer_Directory':delete_property(Dir1, "wrong")),
+
+
+ ?line ?match({'EXCEPTION', _},
+ 'CosFileTransfer_Directory':delete_properties(Dir1, ["num_children"])),
+ ?line ?match({'EXCEPTION', _},
+ 'CosFileTransfer_Directory':delete_properties(Dir1, ["wrong"])),
+ ?line ?match(false, 'CosFileTransfer_Directory':delete_all_properties(Dir1)),
+ ?line ?match(true,
+ 'CosFileTransfer_Directory':is_property_defined(Dir1, "num_children")),
+ ?line ?match(false,
+ 'CosFileTransfer_Directory':is_property_defined(Dir1, "wrong")),
+
+ %% The Top Dir should be empty and ...
+ ?line ?match({ok,[],_}, 'CosFileTransfer_Directory':list(Dir1, 1000)),
+ ?line ?match( #any{value=0},
+ 'CosPropertyService_PropertySet':get_property_value(Dir1, "num_children")),
+ %% Create a sub-directory.
+ ?line Dir2 = 'CosFileTransfer_FileTransferSession':create_directory(FS,
+ TEST_DIR_LEVEL2),
+ ?line ?match( #any{value=1},
+ 'CosPropertyService_PropertySet':get_property_value(Dir1, "num_children")),
+
+ ?line ?match({ok, [_,_], {'IOP_IOR',[],[]}},
+ 'CosFileTransfer_Directory':get_all_properties(Dir1, 2)),
+ ?line {_,_,Iterator1} = ?match({ok, [_], _},
+ 'CosFileTransfer_Directory':get_all_properties(Dir1, 1)),
+ ?line ?match({false, [_]},
+ 'CosPropertyService_PropertiesIterator':next_n(Iterator1,4)),
+
+ ?line {_,_,Iterator0} = ?match({ok, [], _},
+ 'CosFileTransfer_Directory':get_all_properties(Dir1, 0)),
+
+ ?line ?match({false, [_, {'CosPropertyService_Property',
+ "num_children",{any,tk_long,1}}]},
+ 'CosPropertyService_PropertiesIterator':next_n(Iterator0,4)),
+
+ ?line ?match({true,
+ [#'CosPropertyService_Property'{property_name = "num_children"}]},
+ 'CosFileTransfer_Directory':get_properties(Dir1, ["num_children"])),
+
+ %% The Top Directory is not emtpy any more and ...
+ ?line {ok,[#'CosFileTransfer_FileWrapper'{the_file = DirRef}],_} =
+ ?matchnopr({ok,[{'CosFileTransfer_FileWrapper', _, ndirectory}],_},
+ 'CosFileTransfer_Directory':list(Dir1, 1000)),
+ %% ... its name eq. to 'TEST_DIR_LEVEL2'
+ ?line ?match(TEST_DIR_LEVEL2,
+ 'CosFileTransfer_Directory':'_get_complete_file_name'(DirRef)),
+
+ ?line #'CosFileTransfer_FileWrapper'{the_file = Dir3} =
+ ?matchnopr({'CosFileTransfer_FileWrapper', _, ndirectory},
+ 'CosFileTransfer_FileTransferSession':get_file(FS, TEST_DIR_LEVEL1)),
+
+ %% Must get the same result for the 'get_file' operation.
+ ?line {ok,[#'CosFileTransfer_FileWrapper'{the_file = DirRef2}],_} =
+ ?matchnopr({ok,[{'CosFileTransfer_FileWrapper', _, ndirectory}],_},
+ 'CosFileTransfer_Directory':list(Dir3,1000)),
+ ?line ?match(TEST_DIR_LEVEL2,
+ 'CosFileTransfer_Directory':'_get_complete_file_name'(DirRef2)),
+
+ %% Since the top directory isn't empty deleting it must fail.
+ ?line ?match({'EXCEPTION', _},
+ 'CosFileTransfer_FileTransferSession':delete(FS, Dir1)),
+
+ %% Delete the sub-directory and ...
+ ?line ?match(ok, 'CosFileTransfer_FileTransferSession':delete(FS, Dir2)),
+ %% ... see if the top directory realyy is empty.
+ ?line ?match({ok,[],_}, 'CosFileTransfer_Directory':list(Dir1, 1000)),
+
+ ?line ?match(ok, 'CosFileTransfer_FileTransferSession':delete(FS, Dir1)),
+ %% Test if the top directory been removed as intended.
+ ?line ?match({'EXCEPTION', {'CosFileTransfer_FileNotFoundException', _, _}},
+ 'CosFileTransfer_FileTransferSession':get_file(FS, TEST_DIR_LEVEL1)),
+
+ ?line ?match(false, corba_object:non_existent(FS)),
+ ?line ?match(ok, 'CosFileTransfer_FileTransferSession':logout(FS)),
+ %% To make sure Orber can remove it from mnesia.
+ timer:sleep(1000),
+ ?line ?match(true, corba_object:non_existent(FS)),
+ ?line ?match(ok, remote_apply(Node, ?MODULE, uninstall_data, [Name])),
+ stop_orber_remote(Node, normal),
+ ok
+ end.
+
+
+%%-----------------------------------------------------------------
+%% Internal functions
+%%-----------------------------------------------------------------
+ftp_host(Config) ->
+ case ?config(ftp_remote_host, Config) of
+ undefined ->
+ {skipped, "The configuration parameter 'ftp_remote_host' not defined."};
+ Host ->
+ Host
+ end.
+
+loop_files([]) ->
+ io:format("@@@ DONE @@@~n", []);
+loop_files([#'CosFileTransfer_FileWrapper'{the_file = H}|T]) ->
+ FullName = 'CosFileTransfer_File':'_get_complete_file_name'(H),
+ Name = 'CosFileTransfer_File':'_get_name'(H),
+ io:format("FULL NAME: ~p SHORT NAME: ~p~n", [FullName, Name]),
+ loop_files(T).
+
+
+create_file_on_source_node('FTP', _Config, Host, FileName, Path, Data) ->
+ io:format("<<<<<< CosFileTransfer Testing File >>>>>>~n",[]),
+ io:format("Host: ~p~nPath: ~p~nFile: ~p~n", [Host, Path, FileName]),
+ {ok, Pid} = ?match({ok, _}, inets:start(ftpc, [{host, Host}], stand_alone)),
+ ?match(ok, ftp:user(Pid, ?FTP_USER, ?FTP_PASS)),
+ ?match(ok, ftp:cd(Pid, Path)),
+ ?match(ok, ftp:send_bin(Pid, list_to_binary(Data), FileName)),
+ ?match(ok, inets:stop(ftpc, Pid));
+create_file_on_source_node({'NATIVE', _}, _Config, Host, FileName, Path, Data) ->
+ io:format("<<<<<< CosFileTransfer Testing File >>>>>>~n",[]),
+ io:format("Host: ~p~nPath: ~p~nFile: ~p~n", [Host, Path, FileName]),
+ ?match(ok, file:write_file(FileName, list_to_binary(Data))).
+
+create_name(Type) ->
+ {MSec, Sec, USec} = erlang:now(),
+ lists:concat([Type,'_',MSec, '_', Sec, '_', USec]).
+
+
+
+
+%%------------------------------------------------------------
+%% function : create_node/4
+%% Arguments: Name - the name of the new node (atom())
+%% Port - which iiop_port (integer())
+%% Domain - which domain.
+%% Type - if /4 used the types defines the extra arguments
+%% to be used.
+%% Returns : {ok, Node} | {error, _}
+%% Effect : Starts a new slave-node with given (optinally)
+%% extra arguments. If fails it retries 'Retries' times.
+%%------------------------------------------------------------
+create_node(Name, Port, normal) ->
+ Args = basic_args(Name),
+ create_node(Name, Port, 10, normal, Args, []);
+create_node(Name, {Port, _Depth}, ssl) ->
+ Dir = filename:join([code:lib_dir(ssl), "examples", "certs", "etc"]),
+ Args = basic_args(Name),
+ {ok, Node} = create_node(list_to_atom(Name), Port, 10, ssl, Args, []),
+ %% Client
+ rpc:call(Node, application, set_env, [cosFileTransfer, ssl_client_certfile,
+ filename:join([Dir, "client", "cert.pem"])]),
+ rpc:call(Node, application, set_env, [cosFileTransfer, ssl_client_cacertfile,
+ filename:join([Dir, "client", "cacerts.pem"])]),
+ rpc:call(Node, application, set_env, [cosFileTransfer, ssl_client_keyfile,
+ filename:join([Dir, "client", "key.pem"])]),
+ rpc:call(Node, application, set_env, [cosFileTransfer, ssl_client_verify, 1]),
+ rpc:call(Node, application, set_env, [cosFileTransfer, ssl_client_depth, 0]),
+
+ %% Server
+ rpc:call(Node, application, set_env, [cosFileTransfer, ssl_server_certfile,
+ filename:join([Dir, "server", "cert.pem"])]),
+ rpc:call(Node, application, set_env, [cosFileTransfer, ssl_server_cacertfile,
+ filename:join([Dir, "server", "cacerts.pem"])]),
+ rpc:call(Node, application, set_env, [cosFileTransfer, ssl_server_keyfile,
+ filename:join([Dir, "server", "key.pem"])]),
+ rpc:call(Node, application, set_env, [cosFileTransfer, ssl_server_verify, 1]),
+ rpc:call(Node, application, set_env, [cosFileTransfer, ssl_server_depth, 0]),
+ {ok, Node}.
+
+%create_node(Name, {Port, Depth}, ssl) ->
+% TestLibs = filename:join(filename:dirname(code:which(?MODULE)), "ssl_data"),
+% Args = basic_args(Name),
+% SArgs = basic_ssl_args(TestLibs, Args),
+% LArgs = level_based_ssl(Depth, TestLibs, SArgs),
+% create_node(list_to_atom(Name), Port, 10, ssl, LArgs, [{sslpath, TestLibs}]).
+
+create_node(Name, Port, Retries, Type, Args, Options) ->
+ [_, Host] = ?match([_,_],string:tokens(atom_to_list(node()), [$@])),
+ case starter(Host, Name, Args) of
+ {ok, NewNode} ->
+ ?line ?match(pong, net_adm:ping(NewNode)),
+ {ok, Cwd} = file:get_cwd(),
+ Path = code:get_path(),
+ ?line ?match(ok, rpc:call(NewNode, file, set_cwd, [Cwd])),
+ true = rpc:call(NewNode, code, set_path, [Path]),
+ ?match(ok, start_orber_remote(NewNode, Type, Options, Port)),
+ spawn_link(NewNode, ?MODULE, slave_sup, []),
+ rpc:multicall([node() | nodes()], global, sync, []),
+ {ok, NewNode};
+ {error, Reason} when Retries == 0->
+ {error, Reason};
+ {error, Reason} ->
+ io:format("Could not start slavenode ~p ~p retrying~n",
+ [{Host, Name, Args}, Reason]),
+ timer:sleep(500),
+ create_node(Name, Port, Retries - 1, Type, Args, Options)
+ end.
+
+starter(Host, Name, Args) ->
+ case os:type() of
+ vxworks ->
+ test_server:start_node(Name, slave, [{args,Args}]);
+ _ ->
+ slave:start(Host, Name, Args)
+ end.
+
+slave_sup() ->
+ process_flag(trap_exit, true),
+ receive
+ {'EXIT', _, _} ->
+ case os:type() of
+ vxworks ->
+ erlang:halt();
+ _ ->
+ ignore
+ end
+ end.
+
+
+%%------------------------------------------------------------
+%% function : destroy_node
+%% Arguments: Node - which node to destroy.
+%% Type - normal | ssl
+%% Returns :
+%% Effect :
+%%------------------------------------------------------------
+-ifdef(false).
+destroy_node(Node, Type) ->
+ stopper(Node, Type).
+
+stopper(Node, Type) ->
+ catch stop_orber_remote(Node, Type),
+ case os:type() of
+ vxworks ->
+ test_server:stop_node(Node);
+ _ ->
+ slave:stop(Node)
+ end.
+-endif.
+
+%%------------------------------------------------------------
+%% function : remote_apply
+%% Arguments: N - Node, M - Module,
+%% F - Function, A - Arguments (list)
+%% Returns :
+%% Effect :
+%%------------------------------------------------------------
+remote_apply(N, M,F,A) ->
+ case rpc:call(N, M, F, A) of
+ {badrpc, Reason} ->
+ exit(Reason);
+ Other ->
+ Other
+ end.
+
+%%------------------------------------------------------------
+%% function : stop_orber_remote
+%% Arguments: Node - which node to stop orber on.
+%% Type - normal | ssl | light | .......
+%% Returns : ok
+%% Effect : Stops orber on given node and, if specified,
+%% other applications or programs.
+%%------------------------------------------------------------
+stop_orber_remote(Node, ssl) ->
+ rpc:call(Node, ssl, stop, []),
+ rpc:call(Node, crypto, stop, []),
+ orb_rpc_blast(Node, ssl);
+stop_orber_remote(Node, Type) ->
+ orb_rpc_blast(Node, Type).
+
+orb_rpc_blast(Node, _) ->
+ rpc:call(Node, cosFileTransferApp, stop, []),
+ rpc:call(Node, cosProperty, stop, []),
+ rpc:call(Node, cosFileTransferApp, uninstall, []),
+ rpc:call(Node, cosProperty, uninstall, []),
+ rpc:call(Node, orber, jump_stop, []).
+
+%%------------------------------------------------------------
+%% function : start_orber_remote
+%% Arguments: Node - which node to start orber on.
+%% Type - normal | ssl | light | .......
+%% Returns : ok
+%% Effect : Starts orber on given node and, if specified,
+%% other applications or programs.
+%%------------------------------------------------------------
+start_orber_remote(Node, ssl, _Options, Port) ->
+ rpc:call(Node, ssl, start, []),
+ rpc:call(Node, crypto, start, []),
+ rpc:call(Node, ssl, seed, ["testing"]),
+ orb_rpc_setup(Node, ssl, Port);
+start_orber_remote(Node, Type, _, Port) ->
+ orb_rpc_setup(Node, Type, Port).
+
+orb_rpc_setup(Node, _, Port) ->
+ rpc:call(Node, orber, jump_start, [Port]),
+ rpc:call(Node, cosProperty, install, []),
+ rpc:call(Node, cosProperty, start, []),
+ rpc:call(Node, cosFileTransferApp, install, []).
+
+%%--------------- MISC FUNCTIONS -----------------------------
+basic_args(_Name) ->
+ TestLibs = filename:dirname(code:which(?MODULE)),
+ " -orber orber_debug_level 10" ++
+ " -pa " ++
+ TestLibs ++
+ " -pa " ++
+ filename:join(TestLibs, "all_SUITE_data") ++
+ " -pa " ++
+ filename:dirname(code:which(cosFileTransferApp)).
+
+-ifdef(false).
+basic_ssl_args(TestLibs, Args) ->
+% Args ++
+% " -cosFileTransfer ssl_client_certfile \\\"" ++
+% filename:join(TestLibs, "ssl_client_cert.pem") ++
+% "\\\" -cosFileTransfer ssl_server_certfile \\\""++
+% filename:join(TestLibs, "ssl_server_cert.pem")++"\\\"".
+
+ io:format("<<<<<< SSL LIBS ~p >>>>>>~n",[TestLibs]),
+ NewArgs = Args ++
+ " -cosFileTransfer ssl_client_certfile \\\"" ++
+ filename:join(TestLibs, "ssl_client_cert.pem") ++
+ "\\\" -cosFileTransfer ssl_server_certfile \\\""++
+ filename:join(TestLibs, "ssl_server_cert.pem")++"\\\"",
+ io:format("<<<<<< SSL LIBS ARGS ~p >>>>>>~n",[NewArgs]),
+ NewArgs.
+
+level_based_ssl(1, _TestLibs, Args) ->
+ Args;
+level_based_ssl(2, _TestLibs, Args) ->
+ Args.% ++
+% " -cosFileTransfer ssl_server_depth 2 " ++
+% " -cosFileTransfer ssl_client_depth 2 " ++
+% " -cosFileTransfer ssl_server_verify " ++
+% " -cosFileTransfer ssl_client_verify " ++
+% " -cosFileTransfer ssl_server_cacertfile " ++
+% " -cosFileTransfer ssl_client_cacertfile " ++
+
+-endif.
+
+install_data(Protocol, {WhichType, Host, Name}) ->
+ io:format("<<<<<< Starting ~p/~p VFS at ~p/~p>>>>>>~n",
+ [Protocol, WhichType, Host, Name]),
+ %% Create a Virtual File System.
+ ?line VFS = ?match({_,_,_,_,_,_},
+ cosFileTransferApp:create_VFS(WhichType, [], Host, ?FTP_PORT,
+ [{protocol, Protocol}])),
+ NS = corba:resolve_initial_references("NameService"),
+ NC1 = lname_component:set_id(lname_component:create(), Name),
+ N = lname:insert_component(lname:create(), 1, NC1),
+ 'CosNaming_NamingContext':rebind(NS, N, VFS).
+
+uninstall_data(Name) ->
+ ?line VFS = ?match({_,_,_,_,_,_},
+ corba:string_to_object("corbaname:rir:/NameService#"++Name)),
+ ?line ?match(ok, corba:dispose(VFS)),
+ ok.
+
+
+
+%%------------------- EOF MODULE-----------------------------------
diff --git a/lib/cosFileTransfer/vsn.mk b/lib/cosFileTransfer/vsn.mk
index dd92b53904..2700ecb3e3 100644
--- a/lib/cosFileTransfer/vsn.mk
+++ b/lib/cosFileTransfer/vsn.mk
@@ -1,9 +1,12 @@
-COSFILETRANSFER_VSN = 1.1.9
+COSFILETRANSFER_VSN = 1.1.10
TICKETS = \
- OTP-8201
+ OTP-8355 \
+ OTP-8374
+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..dfbabadfa2 100644
--- a/lib/cosNotification/doc/src/notes.xml
+++ b/lib/cosNotification/doc/src/notes.xml
@@ -4,7 +4,7 @@
<chapter>
<header>
<copyright>
- <year>2000</year><year>2009</year>
+ <year>2000</year><year>2010</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
@@ -31,6 +31,68 @@
<file>notes.xml</file>
</header>
+ <section><title>cosNotification 1.1.15</title>
+
+ <section><title>Improvements and New Features</title>
+ <list>
+ <item>
+ <p>
+ Switched from using the deprecated regexp to re instead.</p>
+ <p>
+ Own Id: OTP-8846</p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
+<section>
+ <title>cosNotification 1.1.14</title>
+ <section>
+ <title>Improvements and New Features</title>
+ <list type="bulleted">
+ <item>
+ <p>
+ Test suites published.</p>
+ <p>
+ Own Id: OTP-8543 Aux Id:</p>
+ </item>
+ </list>
+ </section>
+
+ <section>
+ <title>Fixed Bugs and Malfunctions</title>
+ <list type="bulleted">
+ <item>
+ <p>Added missing trailing bracket to define in hrl-file.</p>
+ <p>Own Id: OTP-8489 Aux Id:</p>
+ </item>
+ </list>
+ </section>
+ </section>
+
+ <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>
@@ -57,7 +119,7 @@
<item>
<p>Obsolete guards, e.g. record vs is_record, has been changed
to avoid compiler warnings.</p>
- <p>Own id: OTP-7987</p>
+ <p>Own Id: OTP-7987</p>
</item>
</list>
</section>
@@ -71,7 +133,7 @@
<list type="bulleted">
<item>
<p>Updated file headers.</p>
- <p>Own id: OTP-7837 Aux Id:</p>
+ <p>Own Id: OTP-7837 Aux Id:</p>
</item>
</list>
</section>
@@ -85,7 +147,7 @@
<list type="bulleted">
<item>
<p>Documentation source included in open source releases.</p>
- <p>Own id: OTP-7595 Aux Id:</p>
+ <p>Own Id: OTP-7595 Aux Id:</p>
</item>
</list>
</section>
@@ -100,7 +162,7 @@
<item>
<p>The CosNotification proxy objects ignored the gcLimit option, instead
the gcTime value was used.</p>
- <p>Own id: OTP-7553 Aux Id:</p>
+ <p>Own Id: OTP-7553 Aux Id:</p>
</item>
</list>
</section>
@@ -114,7 +176,7 @@
<list type="bulleted">
<item>
<p>Updated file headers.</p>
- <p>Own id: OTP-7011</p>
+ <p>Own Id: OTP-7011</p>
</item>
</list>
</section>
@@ -128,7 +190,7 @@
<list type="bulleted">
<item>
<p>The documentation source has been converted from SGML to XML.</p>
- <p>Own id: OTP-6754</p>
+ <p>Own Id: OTP-6754</p>
</item>
</list>
</section>
@@ -142,7 +204,7 @@
<list type="bulleted">
<item>
<p>Minor Makefile changes.</p>
- <p>Own id: OTP-6701</p>
+ <p>Own Id: OTP-6701</p>
</item>
</list>
</section>
@@ -156,7 +218,7 @@
<list type="bulleted">
<item>
<p>Removed some unused code.</p>
- <p>Own id: OTP-6527</p>
+ <p>Own Id: OTP-6527</p>
</item>
</list>
</section>
@@ -172,7 +234,7 @@
<p>A user can now define the QoS EventReliability to be
Persistent. Note, this is only a lightweight version
and events will be lost if a proxy is terminated.</p>
- <p>Own id: OTP-5923</p>
+ <p>Own Id: OTP-5923</p>
</item>
</list>
</section>
@@ -188,7 +250,7 @@
<p>Possible to configure cosNotification not to type check,
by invoking corba_object:is_a/2, supplied IOR:s. When
a type check fails, the feedback has been improved.</p>
- <p>Own id: OTP-5823 Aux Id: seq10143</p>
+ <p>Own Id: OTP-5823 Aux Id: seq10143</p>
</item>
</list>
</section>
@@ -202,7 +264,7 @@
<list type="bulleted">
<item>
<p>The app-file contained duplicated modules.</p>
- <p>Own id: OTP-4976</p>
+ <p>Own Id: OTP-4976</p>
</item>
</list>
</section>
@@ -221,7 +283,7 @@
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>
+ <p>Own Id: OTP-4576</p>
</item>
</list>
</section>
diff --git a/lib/cosNotification/src/CosNotification_Definitions.hrl b/lib/cosNotification/src/CosNotification_Definitions.hrl
index 755b07cd5d..9f4989838a 100644
--- a/lib/cosNotification/src/CosNotification_Definitions.hrl
+++ b/lib/cosNotification/src/CosNotification_Definitions.hrl
@@ -2,7 +2,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1999-2009. All Rights Reserved.
+%% Copyright Ericsson AB 1999-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
@@ -162,7 +162,7 @@
low_val=any:create(orber_tc:long(), ?not_MinConsumerEvents),
high_val=any:create(orber_tc:long(), ?not_MaxConsumerEvents)
}}
-].
+]).
diff --git a/lib/cosNotification/src/cosNotification_Filter.erl b/lib/cosNotification/src/cosNotification_Filter.erl
index dd3b5beb93..7201f7d6e2 100644
--- a/lib/cosNotification/src/cosNotification_Filter.erl
+++ b/lib/cosNotification/src/cosNotification_Filter.erl
@@ -2,7 +2,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1999-2009. All Rights Reserved.
+%% Copyright Ericsson AB 1999-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
@@ -877,9 +877,9 @@ check_wildcard(Types, Which, WC, Domain, Type) ->
end,
check_types(Types, Which, NewWC).
-%% Change '*' to '.*', see regexp:parse/2 documentation.
+%% Change '*' to '.*', see re:compile/1 documentation.
convert_wildcard([], Acc) ->
- case regexp:parse(lists:reverse(Acc)) of
+ case re:compile(lists:reverse(Acc)) of
{ok, Expr} ->
Expr;
_ ->
@@ -900,37 +900,37 @@ match_types(_, _, []) ->
false;
match_types(Domain, Type, [{domain, WCDomain, Type}|T]) ->
L=length(Domain),
- case catch regexp:matches(Domain, WCDomain) of
- {match, []} ->
+ case catch re:run(Domain, WCDomain) of
+ nomatch ->
match_types(Domain, Type, T);
- {match, [{1, L}]} ->
+ {match, [{0, L}]} ->
true;
_->
match_types(Domain, Type, T)
end;
match_types(Domain, Type, [{type, Domain, WCType}|T]) ->
L=length(Type),
- case catch regexp:matches(Type, WCType) of
- {match, []} ->
+ case catch re:run(Type, WCType) of
+ nomatch ->
match_types(Domain, Type, T);
- {match, [{1, L}]} ->
+ {match, [{0, L}]} ->
true;
_->
match_types(Domain, Type, T)
end;
match_types(Domain, Type, [{both, WCDomain, WCType}|T]) ->
L1=length(Domain),
- case catch regexp:matches(Domain, WCDomain) of
- {match, []} ->
+ case catch re:run(Domain, WCDomain) of
+ nomatch ->
match_types(Domain, Type, T);
- {match, [{1, L1}]} ->
+ {match, [{0, L1}]} ->
L2=length(Type),
- case catch regexp:matches(Type, WCType) of
- {match, []} ->
+ case catch re:run(Type, WCType) of
+ nomatch ->
match_types(Domain, Type, T);
- {match, [{1, L2}]} ->
+ {match, [{0, L2}]} ->
true;
- _->
+ _ ->
match_types(Domain, Type, T)
end;
_->
diff --git a/lib/cosNotification/test/Makefile b/lib/cosNotification/test/Makefile
new file mode 100644
index 0000000000..df8f9e919b
--- /dev/null
+++ b/lib/cosNotification/test/Makefile
@@ -0,0 +1,190 @@
+#
+# %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 $(ERL_TOP)/make/target.mk
+include $(ERL_TOP)/make/$(TARGET)/otp.mk
+
+# ----------------------------------------------------
+# Application version
+# ----------------------------------------------------
+include ../vsn.mk
+VSN=$(COSNOTIFICATION_VSN)
+# ----------------------------------------------------
+# Release directory specification
+# ----------------------------------------------------
+RELSYSDIR = $(RELEASE_PATH)/cosNotification_test
+
+# ----------------------------------------------------
+# Target Specs
+# ----------------------------------------------------
+TEST_SPEC_FILE = cosNotification.spec
+
+
+IDL_FILES =
+
+IDLOUTDIR = idl_output
+
+MODULES = \
+ notification_SUITE \
+ grammar_SUITE \
+ eventDB_SUITE \
+ generated_SUITE \
+ notify_test_impl
+
+GEN_MODULES = \
+ oe_notify_test_server \
+ notify_test_data \
+ notify_test_computer \
+ notify_test_studies \
+ notify_test_ShortArray \
+ notify_test_uni1 \
+ notify_test_uni2 \
+ notify_test_X \
+ notify_test_K \
+ notify_test_SeqPushC \
+ notify_test_StrPushC \
+ notify_test_AnyPushC \
+ notify_test_SeqPullC \
+ notify_test_StrPullC \
+ notify_test_AnyPullC \
+ notify_test_SeqPushS \
+ notify_test_StrPushS \
+ notify_test_AnyPushS \
+ notify_test_SeqPullS \
+ notify_test_StrPullS \
+ notify_test_AnyPullS \
+ notify_test_funcs
+
+GEN_HRL_FILES = \
+ oe_notify_test_server.hrl \
+ notify_test_SeqPushC.hrl \
+ notify_test_StrPushC.hrl \
+ notify_test_AnyPushC.hrl \
+ notify_test_SeqPullC.hrl \
+ notify_test_StrPullC.hrl \
+ notify_test_AnyPullC.hrl \
+ notify_test_SeqPushS.hrl \
+ notify_test_StrPushS.hrl \
+ notify_test_AnyPushS.hrl \
+ notify_test_SeqPullS.hrl \
+ notify_test_StrPullS.hrl \
+ notify_test_AnyPullS.hrl \
+ notify_test.hrl \
+ notify_test_funcs.hrl
+
+ERL_FILES = $(MODULES:%=%.erl)
+
+HRL_FILES =
+
+GEN_FILES = \
+ $(GEN_HRL_FILES:%=$(IDLOUTDIR)/%) \
+ $(GEN_MODULES:%=$(IDLOUTDIR)/%.erl)
+
+GEN_TARGET_FILES = $(GEN_MODULES:%=$(IDLOUTDIR)/%.$(EMULATOR))
+
+SUITE_TARGET_FILES = $(MODULES:%=%.$(EMULATOR))
+
+TARGET_FILES = \
+ $(GEN_TARGET_FILES) \
+ $(SUITE_TARGET_FILES)
+
+
+# ----------------------------------------------------
+# PROGRAMS
+# ----------------------------------------------------
+LOCAL_CLASSPATH = $(ERL_TOP)lib/cosNotification/priv:$(ERL_TOP)lib/cosNotification/test
+# ----------------------------------------------------
+# FLAGS
+# ----------------------------------------------------
+ERL_IDL_FLAGS += \
+ -pa $(ERL_TOP)/lib/cosNotification/ebin \
+ -pa $(ERL_TOP)/lib/cosNotification/src \
+ -pa $(ERL_TOP)/lib/cosTime/ebin \
+ -pa $(ERL_TOP)/lib/cosTime/include \
+ -pa $(ERL_TOP)/lib/orber/ebin \
+ -pa $(ERL_TOP)/lib/ic/ebin \
+ -pa $(ERL_TOP)/lib/cosNotification/include \
+ -I$(ERL_TOP)/lib/cosEvent/src \
+ -I$(ERL_TOP)/lib/cosNotification/include \
+
+ERL_COMPILE_FLAGS += \
+ $(ERL_IDL_FLAGS) \
+ -pa $(ERL_TOP)/lib/orber/include \
+ -pa $(ERL_TOP)/internal_tools/test_server/ebin \
+ -pa $(ERL_TOP)/lib/cosNotification/ebin \
+ -pa $(ERL_TOP)/lib/cosNotification/test/idl_output \
+ -pa $(ERL_TOP)/lib/cosTime/ebin \
+ -pa $(ERL_TOP)/lib/cosTime/include \
+ -pa $(ERL_TOP)/lib/cosNotification/include \
+ -pa $(ERL_TOP)/lib/ic/ebin \
+ -I$(ERL_TOP)/lib/cosTime/ebin \
+ -I$(ERL_TOP)/lib/cosTime/include \
+ -I$(ERL_TOP)/lib/orber/include \
+ -I$(ERL_TOP)/lib/cosNotification/src \
+ -I$(ERL_TOP)/lib/cosNotification/include \
+ -I$(ERL_TOP)/lib/cosNotification \
+ -I$(ERL_TOP)/lib/cosNotification/test/$(IDLOUTDIR) \
+ -I$(ERL_TOP)/lib/test_server/include
+
+# ----------------------------------------------------
+# Targets
+# ----------------------------------------------------
+
+
+tests debug opt: $(TARGET_FILES)
+
+clean:
+ rm -f idl_output/*
+ rm -f $(TARGET_FILES)
+ rm -f errs core *~
+
+docs:
+
+# ----------------------------------------------------
+# Special Targets
+# ----------------------------------------------------
+
+TGT_TEST = \
+ $(GEN_HRL_FILES:%=$(IDLOUTDIR)/%) \
+ $(GEN_MODULES:%=$(IDLOUTDIR)/%.erl)
+
+$(TGT_TEST): notify_test_server.idl
+ erlc $(ERL_COMPILE_FLAGS) -o$(IDLOUTDIR) \
+ +'{cfgfile,"notify_test_server.cfg"}' notify_test_server.idl
+
+# ----------------------------------------------------
+# Release Targets
+# ----------------------------------------------------
+# We don't copy generated intermediate erlang and hrl files
+
+include $(ERL_TOP)/make/otp_release_targets.mk
+
+release_spec:
+
+release_docs_spec:
+
+release_tests_spec: tests
+ $(INSTALL_DIR) $(RELSYSDIR)
+ $(INSTALL_DATA) $(IDL_FILES) $(TEST_SPEC_FILE) \
+ $(ERL_FILES) $(RELSYSDIR)
+ $(INSTALL_DIR) $(RELSYSDIR)/$(IDLOUTDIR)
+ $(INSTALL_DATA) $(GEN_TARGET_FILES) $(GEN_FILES) \
+ $(RELSYSDIR)/$(IDLOUTDIR)
+ $(INSTALL_DATA) $(SUITE_TARGET_FILES) $(RELSYSDIR)
+
diff --git a/lib/cosNotification/test/cosNotification.spec b/lib/cosNotification/test/cosNotification.spec
new file mode 100644
index 0000000000..8df89e7908
--- /dev/null
+++ b/lib/cosNotification/test/cosNotification.spec
@@ -0,0 +1,19 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 1999-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%
+%%
+{topcase, {dir, "../cosNotification_test"}}.
diff --git a/lib/cosNotification/test/eventDB_SUITE.erl b/lib/cosNotification/test/eventDB_SUITE.erl
new file mode 100644
index 0000000000..9ddfb3d902
--- /dev/null
+++ b/lib/cosNotification/test/eventDB_SUITE.erl
@@ -0,0 +1,902 @@
+%%--------------------------------------------------------------------
+%%
+%% %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%
+%%
+%%
+%%--------------------------------------------------------------------
+%% File : eventDB_SUITE.erl
+%% Purpose :
+%%--------------------------------------------------------------------
+
+-module(eventDB_SUITE).
+%%--------------- INCLUDES -----------------------------------
+-include_lib("orber/include/corba.hrl").
+-include_lib("orber/include/ifr_types.hrl").
+%% cosEvent files.
+-include_lib("cosEvent/include/CosEventChannelAdmin.hrl").
+%% cosTime files.
+-include_lib("cosTime/include/TimeBase.hrl").
+%% Application files
+-include_lib("cosNotification/include/CosNotification.hrl").
+-include_lib("cosNotification/include/CosNotifyChannelAdmin.hrl").
+-include_lib("cosNotification/include/CosNotifyComm.hrl").
+-include_lib("cosNotification/include/CosNotifyFilter.hrl").
+
+-include_lib("cosNotification/src/CosNotification_Definitions.hrl").
+
+-include("idl_output/notify_test.hrl").
+
+-include("test_server.hrl").
+
+%%--------------- DEFINES ------------------------------------
+-define(default_timeout, ?t:minutes(20)).
+-define(match(ExpectedRes, Expr),
+ fun() ->
+ AcTuAlReS = (catch (Expr)),
+ case AcTuAlReS of
+ ExpectedRes ->
+ io:format("------ CORRECT RESULT ------~n~p~n",
+ [AcTuAlReS]),
+ AcTuAlReS;
+ _ ->
+ io:format("###### ERROR ERROR ######~n~p~n",
+ [AcTuAlReS]),
+ ?line exit(AcTuAlReS)
+ end
+ end()).
+
+
+-define(EVENT1, ?not_CreateSE("","event1","",
+ [#'CosNotification_Property'
+ {name="Priority",
+ value=any:create(orber_tc:short(), 0)},
+ #'CosNotification_Property'
+ {name="StartTime",
+ value=any:create('TimeBase_UtcT':tc(),
+ #'TimeBase_UtcT'
+ {time=900000000,
+ inacclo=0, inacchi=0, tdf=2})},
+ #'CosNotification_Property'
+ {name="StopTime",
+ value=any:create('TimeBase_UtcT':tc(),
+ #'TimeBase_UtcT'
+ {time=900000000,
+ inacclo=0, inacchi=0, tdf=2})},
+ #'CosNotification_Property'
+ {name="Timeout",
+ value=any:create(orber_tc:unsigned_long_long(), 900000000)}],
+ [], any:create(orber_tc:null(), null))).
+-define(EVENT2, ?not_CreateSE("","event2","",
+ [#'CosNotification_Property'
+ {name="Priority",
+ value=any:create(orber_tc:short(), 0)},
+ #'CosNotification_Property'
+ {name="StartTime",
+ value=any:create('TimeBase_UtcT':tc(),
+ #'TimeBase_UtcT'
+ {time=800000000,
+ inacclo=0, inacchi=0, tdf=2})},
+ #'CosNotification_Property'
+ {name="StopTime",
+ value=any:create('TimeBase_UtcT':tc(),
+ #'TimeBase_UtcT'
+ {time=800000000,
+ inacclo=0, inacchi=0, tdf=2})},
+ #'CosNotification_Property'
+ {name="Timeout",
+ value=any:create(orber_tc:unsigned_long_long(), 800000000)}],
+ [], any:create(orber_tc:null(), null))).
+-define(EVENT3, ?not_CreateSE("","event3","",
+ [#'CosNotification_Property'
+ {name="Priority",
+ value=any:create(orber_tc:short(), 0)},
+ #'CosNotification_Property'
+ {name="StartTime",
+ value=any:create('TimeBase_UtcT':tc(),
+ #'TimeBase_UtcT'
+ {time=700000000,
+ inacclo=0, inacchi=0, tdf=2})},
+ #'CosNotification_Property'
+ {name="StopTime",
+ value=any:create('TimeBase_UtcT':tc(),
+ #'TimeBase_UtcT'
+ {time=700000000,
+ inacclo=0, inacchi=0, tdf=2})},
+ #'CosNotification_Property'
+ {name="Timeout",
+ value=any:create(orber_tc:unsigned_long_long(), 700000000)}],
+ [], any:create(orber_tc:null(), null))).
+-define(EVENT4, ?not_CreateSE("","event4","",
+ [#'CosNotification_Property'
+ {name="Priority",
+ value=any:create(orber_tc:short(), 2)},
+ #'CosNotification_Property'
+ {name="StartTime",
+ value=any:create('TimeBase_UtcT':tc(),
+ #'TimeBase_UtcT'
+ {time=300000000,
+ inacclo=0, inacchi=0, tdf=2})},
+ #'CosNotification_Property'
+ {name="StopTime",
+ value=any:create('TimeBase_UtcT':tc(),
+ #'TimeBase_UtcT'
+ {time=300000000,
+ inacclo=0, inacchi=0, tdf=2})},
+ #'CosNotification_Property'
+ {name="Timeout",
+ value=any:create(orber_tc:unsigned_long_long(), 300000000)}],
+ [], any:create(orber_tc:null(), null))).
+-define(EVENT5, ?not_CreateSE("","event5","",
+ [#'CosNotification_Property'
+ {name="Priority",
+ value=any:create(orber_tc:short(), 2)},
+ #'CosNotification_Property'
+ {name="StartTime",
+ value=any:create('TimeBase_UtcT':tc(),
+ #'TimeBase_UtcT'
+ {time=200000000,
+ inacclo=0, inacchi=0, tdf=2})},
+ #'CosNotification_Property'
+ {name="StopTime",
+ value=any:create('TimeBase_UtcT':tc(),
+ #'TimeBase_UtcT'
+ {time=200000000,
+ inacclo=0, inacchi=0, tdf=2})},
+ #'CosNotification_Property'
+ {name="Timeout",
+ value=any:create(orber_tc:unsigned_long_long(), 200000000)}],
+ [], any:create(orber_tc:null(), null))).
+-define(EVENT6, ?not_CreateSE("","event6","",
+ [#'CosNotification_Property'
+ {name="Priority",
+ value=any:create(orber_tc:short(), 0)},
+ #'CosNotification_Property'
+ {name="StartTime",
+ value=any:create('TimeBase_UtcT':tc(),
+ #'TimeBase_UtcT'
+ {time=500000000,
+ inacclo=0, inacchi=0, tdf=2})},
+ #'CosNotification_Property'
+ {name="StopTime",
+ value=any:create('TimeBase_UtcT':tc(),
+ #'TimeBase_UtcT'
+ {time=500000000,
+ inacclo=0, inacchi=0, tdf=2})},
+ #'CosNotification_Property'
+ {name="Timeout",
+ value=any:create(orber_tc:unsigned_long_long(), 500000000)}],
+ [], any:create(orber_tc:null(), null))).
+-define(EVENT7, ?not_CreateSE("","event7","",
+ [#'CosNotification_Property'
+ {name="Priority",
+ value=any:create(orber_tc:short(), -1)},
+ #'CosNotification_Property'
+ {name="StartTime",
+ value=any:create('TimeBase_UtcT':tc(),
+ #'TimeBase_UtcT'
+ {time=400000000,
+ inacclo=0, inacchi=0, tdf=2})},
+ #'CosNotification_Property'
+ {name="StopTime",
+ value=any:create('TimeBase_UtcT':tc(),
+ #'TimeBase_UtcT'
+ {time=400000000,
+ inacclo=0, inacchi=0, tdf=2})},
+ #'CosNotification_Property'
+ {name="Timeout",
+ value=any:create(orber_tc:unsigned_long_long(), 400000000)}],
+ [], any:create(orber_tc:null(), null))).
+-define(EVENT8, ?not_CreateSE("","event8","",
+ [#'CosNotification_Property'
+ {name="Priority",
+ value=any:create(orber_tc:short(), -1)},
+ #'CosNotification_Property'
+ {name="StartTime",
+ value=any:create('TimeBase_UtcT':tc(),
+ #'TimeBase_UtcT'
+ {time=600000000,
+ inacclo=0, inacchi=0, tdf=2})},
+ #'CosNotification_Property'
+ {name="StopTime",
+ value=any:create('TimeBase_UtcT':tc(),
+ #'TimeBase_UtcT'
+ {time=600000000,
+ inacclo=0, inacchi=0, tdf=2})},
+ #'CosNotification_Property'
+ {name="Timeout",
+ value=any:create(orber_tc:unsigned_long_long(), 600000000)}],
+ [], any:create(orber_tc:null(), null))).
+-define(EVENT9, ?not_CreateSE("","event9","",
+ [#'CosNotification_Property'
+ {name="Priority",
+ value=any:create(orber_tc:short(), 0)},
+ #'CosNotification_Property'
+ {name="StartTime",
+ value=any:create('TimeBase_UtcT':tc(),
+ #'TimeBase_UtcT'
+ {time=100000000,
+ inacclo=0, inacchi=0, tdf=2})},
+ #'CosNotification_Property'
+ {name="StopTime",
+ value=any:create('TimeBase_UtcT':tc(),
+ #'TimeBase_UtcT'
+ {time=100000000,
+ inacclo=0, inacchi=0, tdf=2})},
+ #'CosNotification_Property'
+ {name="Timeout",
+ value=any:create(orber_tc:unsigned_long_long(), 100000000)}],
+ [], any:create(orber_tc:null(), null))).
+
+-define(EVENTS, [?EVENT1, ?EVENT2, ?EVENT3, ?EVENT4, ?EVENT5, ?EVENT6, ?EVENT7,
+ ?EVENT8, ?EVENT9]).
+
+
+-define(PRIOORDER, [?EVENT4, ?EVENT5, ?EVENT1, ?EVENT2, ?EVENT3, ?EVENT6, ?EVENT9,
+ ?EVENT7, ?EVENT8]).
+
+-define(FIFOORDER, ?EVENTS).
+
+-define(DEADLINEORDER, [?EVENT9, ?EVENT5, ?EVENT4, ?EVENT7, ?EVENT6, ?EVENT8, ?EVENT3,
+ ?EVENT2, ?EVENT1]).
+
+-define(NO_OF_EVENTS, 9).
+
+%%-----------------------------------------------------------------
+%% External exports
+%%-----------------------------------------------------------------
+-export([all/1, cases/0, init_all/1, finish_all/1, reorder_api/1, lookup_api/1,
+ discard_api/1, max_events_api/1, gc_api/1, auto_gc_api/1,
+ start_stop_time_api/1, mapping_filter_api/1, persisten_event_api/1,
+ init_per_testcase/2, fin_per_testcase/2]).
+
+%%-----------------------------------------------------------------
+%% Func: all/1
+%% Args:
+%% Returns:
+%%-----------------------------------------------------------------
+all(doc) -> ["API tests for the cosNotification interfaces", ""];
+all(suite) -> {req,
+ [mnesia, orber],
+ {conf, init_all, cases(), finish_all}}.
+
+cases() ->
+ [persisten_event_api, start_stop_time_api, mapping_filter_api,
+ max_events_api, discard_api, reorder_api, lookup_api, gc_api,
+ auto_gc_api].
+
+
+
+%%-----------------------------------------------------------------
+%% Init and cleanup functions.
+%%-----------------------------------------------------------------
+
+init_per_testcase(_Case, Config) ->
+ ?line Dog=test_server:timetrap(?default_timeout),
+ [{watchdog, Dog}|Config].
+
+
+fin_per_testcase(_Case, Config) ->
+ Dog = ?config(watchdog, Config),
+ test_server:timetrap_cancel(Dog),
+ ok.
+
+init_all(Config) ->
+ Path = code:which(?MODULE),
+ code:add_pathz(filename:join(filename:dirname(Path), "idl_output")),
+ orber:jump_start(),
+ cosTime:install_time(),
+ cosTime:start(),
+ if
+ is_list(Config) ->
+ Config;
+ true ->
+ exit("Config not a list")
+ end.
+
+finish_all(Config) ->
+ Path = code:which(?MODULE),
+ code:del_path(filename:join(filename:dirname(Path), "idl_output")),
+ cosTime:stop(),
+ cosTime:uninstall_time(),
+ orber:jump_stop(),
+ Config.
+
+
+%%-----------------------------------------------------------------
+%% cosNotification_eventDB lookup API tests
+%%-----------------------------------------------------------------
+mapping_filter_api(doc) -> ["The event DB is used to store events which cannot be",
+ "delivered at once. This case is supposed to test",
+ "that the events are delivered in the correct order",
+ "if a MappingFilter have benn associated.",
+ ""];
+mapping_filter_api(suite) -> [];
+mapping_filter_api(_Config) ->
+ InitQoS = ?not_CreateInitQoS(),
+ InitQoS2 = ?not_SetMaxEventsPerConsumer(InitQoS,100),
+ InitQoS3 = ?not_SetStartTimeSupported(InitQoS2, false),
+ InitQoS4 = ?not_SetStopTimeSupported(InitQoS3, true),
+ QoS = ?not_SetDiscardPolicy(InitQoS4, ?not_AnyOrder),
+
+ PriorityQoS = ?not_SetOrderPolicy(QoS, ?not_PriorityOrder),
+ DeadlineQoS = ?not_SetOrderPolicy(QoS, ?not_DeadlineOrder),
+
+ %% "Calculate" data once:
+ %% NOTE! Even though the an Event do not match any of the constarints the
+ %% default value will be used. Hence, the events will not be stored in the
+ %% way described in the definitions above. For example, when using deadline order
+ %% all the events will be stored in FIFO order since the usag of a MappingFilter
+ %% all evnts will have the same deadline (except event6).
+ Events = ?EVENTS,
+ PrioOrder = [?EVENT6, ?EVENT1, ?EVENT2, ?EVENT3, ?EVENT4, ?EVENT5, ?EVENT7,
+ ?EVENT8, ?EVENT9],
+ DeadlineOrder = [?EVENT1, ?EVENT2, ?EVENT3, ?EVENT4, ?EVENT5, ?EVENT7, ?EVENT8,
+ ?EVENT9],
+
+
+ FiFac = 'CosNotifyFilter_FilterFactory':oe_create(),
+ ?match({_,key,_,_,_,_}, FiFac),
+
+ PrioFilter = 'CosNotifyFilter_FilterFactory':
+ create_mapping_filter(FiFac, "EXTENDED_TCL", any:create(orber_tc:short(), 0)),
+ DLFilter = 'CosNotifyFilter_FilterFactory':
+ create_mapping_filter(FiFac, "EXTENDED_TCL", any:create(orber_tc:unsigned_long_long(), 1000000000)),
+
+ ?match([_],
+ 'CosNotifyFilter_MappingFilter':add_mapping_constraints(PrioFilter,
+ [#'CosNotifyFilter_MappingConstraintPair'
+ {constraint_expression = #'CosNotifyFilter_ConstraintExp'
+ {event_types = [#'CosNotification_EventType'
+ {domain_name = "",
+ type_name = "event6"}],
+ constraint_expr = "2==2"},
+ result_to_set = any:create(orber_tc:short(), 10)}])),
+ ?match([_],
+ 'CosNotifyFilter_MappingFilter':add_mapping_constraints(DLFilter,
+ [#'CosNotifyFilter_MappingConstraintPair'
+ {constraint_expression = #'CosNotifyFilter_ConstraintExp'
+ {event_types = [#'CosNotification_EventType'
+ {domain_name = "",
+ type_name = "event6"}],
+ constraint_expr = "2==2"},
+ result_to_set = any:create(orber_tc:unsigned_long_long(), 200000000)}])),
+
+
+ do_lookup(PriorityQoS, Events, PrioOrder, "Priority Order", undefined, PrioFilter, 0),
+ do_lookup(DeadlineQoS, Events, DeadlineOrder, "Deadline Order", DLFilter, undefined, 23000),
+ ok.
+
+do_lookup(QoS, Events, Return, Txt, DLFilter, PrioFilter, Timeout) ->
+ io:format("#################### ~s ###################~n", [Txt]),
+ Ref = cosNotification_eventDB:create_db(QoS, 60, 50, undefined),
+ create_loop(Events, Ref, DLFilter, PrioFilter),
+ timer:sleep(Timeout),
+ ?match({Return,_}, cosNotification_eventDB:get_events(Ref, ?NO_OF_EVENTS)),
+ cosNotification_eventDB:destroy_db(Ref).
+
+%%-----------------------------------------------------------------
+%% cosNotification_eventDB discard API tests
+%%-----------------------------------------------------------------
+discard_api(doc) -> ["The event DB is used to store events which cannot be",
+ "delivered at once. If MaxEvents limit is reached there",
+ "different ways we can discard the. This case will test",
+ "all permutations of order and discard policies.",
+ ""];
+discard_api(suite) -> [];
+discard_api(_Config) ->
+ InitQoS1 = ?not_CreateInitQoS(),
+ InitQoS2 = ?not_SetPriority(InitQoS1, 10),
+ InitQoS3 = ?not_SetStartTimeSupported(InitQoS2, false),
+ QoS = ?not_SetMaxEventsPerConsumer(InitQoS3, 5),
+ %% The different order policies. To each order we must apply every possible
+ %% discard policy to each order policy setting. We also have to test and
+ %% change the policies for each setting.
+ AnyQoS = ?not_SetOrderPolicy(QoS, ?not_AnyOrder),
+ PriorityQoS = ?not_SetOrderPolicy(QoS, ?not_PriorityOrder),
+ FifoQoS = ?not_SetOrderPolicy(QoS, ?not_FifoOrder),
+ DeadlineQoS = ?not_SetOrderPolicy(QoS, ?not_DeadlineOrder),
+
+ Events = ?EVENTS,
+
+ %% Test using Any discard policy
+ do_discard(Events, ?not_SetDiscardPolicy(AnyQoS, ?not_AnyOrder),
+ [?EVENT4, ?EVENT5, ?EVENT1, ?EVENT2, ?EVENT3],
+ "Discard and Order eq. Any"),
+ do_discard(Events, ?not_SetDiscardPolicy(PriorityQoS, ?not_AnyOrder),
+ [?EVENT4, ?EVENT5, ?EVENT1, ?EVENT2, ?EVENT3],
+ "Discard Any and Order Priority"),
+ do_discard(Events, ?not_SetDiscardPolicy(FifoQoS, ?not_AnyOrder),
+ [?EVENT1, ?EVENT2, ?EVENT3, ?EVENT4, ?EVENT5],
+ "Discard Any and Order Fifo"),
+ do_discard(Events, ?not_SetDiscardPolicy(DeadlineQoS, ?not_AnyOrder),
+ [?EVENT5, ?EVENT4, ?EVENT3, ?EVENT2, ?EVENT1],
+ "Discard Any and Order Deadline"),
+
+ %% Test using RejectNewEvents discard policy
+ do_discard(Events, ?not_SetDiscardPolicy(AnyQoS, ?not_RejectNewEvents),
+ [?EVENT4, ?EVENT5, ?EVENT1, ?EVENT2, ?EVENT3],
+ "Discard RejectNewEvents and Order Any"),
+ do_discard(Events, ?not_SetDiscardPolicy(PriorityQoS, ?not_RejectNewEvents),
+ [?EVENT4, ?EVENT5, ?EVENT1, ?EVENT2, ?EVENT3],
+ "Discard RejectNewEvents and Order Priority"),
+ do_discard(Events, ?not_SetDiscardPolicy(FifoQoS, ?not_RejectNewEvents),
+ [?EVENT1, ?EVENT2, ?EVENT3, ?EVENT4, ?EVENT5],
+ "Discard RejectNewEvents and Order Fifo"),
+ do_discard(Events, ?not_SetDiscardPolicy(DeadlineQoS, ?not_RejectNewEvents),
+ [?EVENT5, ?EVENT4, ?EVENT3, ?EVENT2, ?EVENT1],
+ "Discard RejectNewEvents and Order Deadline"),
+
+ %% Test using Lifo discard policy
+ do_discard(Events, ?not_SetDiscardPolicy(AnyQoS, ?not_LifoOrder),
+ [?EVENT4, ?EVENT5, ?EVENT1, ?EVENT2, ?EVENT3],
+ "Discard Lifo and Order Any"),
+ do_discard(Events, ?not_SetDiscardPolicy(PriorityQoS, ?not_LifoOrder),
+ [?EVENT4, ?EVENT5, ?EVENT1, ?EVENT2, ?EVENT3],
+ "Discard Lifo and Order Priority"),
+ do_discard(Events, ?not_SetDiscardPolicy(FifoQoS, ?not_LifoOrder),
+ [?EVENT1, ?EVENT2, ?EVENT3, ?EVENT4, ?EVENT5],
+ "Discard Lifo and Order Fifo"),
+ do_discard(Events, ?not_SetDiscardPolicy(DeadlineQoS, ?not_LifoOrder),
+ [?EVENT5, ?EVENT4, ?EVENT3, ?EVENT2, ?EVENT1],
+ "Discard Lifo and Order Deadline"),
+
+ %% Test using Fifo discard policy
+ do_discard(Events, ?not_SetDiscardPolicy(AnyQoS, ?not_FifoOrder),
+ [?EVENT5, ?EVENT6, ?EVENT9, ?EVENT7, ?EVENT8],
+ "Discard Fifo and Order Any"),
+ do_discard(Events, ?not_SetDiscardPolicy(PriorityQoS, ?not_FifoOrder),
+ [?EVENT5, ?EVENT6, ?EVENT9, ?EVENT7, ?EVENT8],
+ "Discard Fifo and Order Priority"),
+ do_discard(Events, ?not_SetDiscardPolicy(FifoQoS, ?not_FifoOrder),
+ [?EVENT5, ?EVENT6, ?EVENT7, ?EVENT8, ?EVENT9],
+ "Discard Fifo and Order Fifo"),
+ do_discard(Events, ?not_SetDiscardPolicy(DeadlineQoS, ?not_FifoOrder),
+ [?EVENT9, ?EVENT5, ?EVENT7, ?EVENT6, ?EVENT8],
+ "Discard Fifo and Order Deadline"),
+
+ %% Test using Priority discard policy
+ do_discard(Events, ?not_SetDiscardPolicy(AnyQoS, ?not_PriorityOrder),
+ [?EVENT4, ?EVENT5, ?EVENT1, ?EVENT2, ?EVENT3],
+ "Discard Priority and Order Any"),
+ do_discard(Events, ?not_SetDiscardPolicy(PriorityQoS, ?not_PriorityOrder),
+ [?EVENT4, ?EVENT5, ?EVENT1, ?EVENT2, ?EVENT3],
+ "Discard Priority and Order Priority"),
+ do_discard(Events, ?not_SetDiscardPolicy(FifoQoS, ?not_PriorityOrder),
+ [?EVENT1, ?EVENT2, ?EVENT3, ?EVENT4, ?EVENT5],
+ "Discard Priority and Order Fifo"),
+ do_discard(Events, ?not_SetDiscardPolicy(DeadlineQoS, ?not_PriorityOrder),
+ [?EVENT5, ?EVENT4, ?EVENT3, ?EVENT2, ?EVENT1],
+ "Discard Priority and Order Deadline"),
+
+ %% Test using Deadline discard policy
+ do_discard(Events, ?not_SetDiscardPolicy(AnyQoS, ?not_DeadlineOrder),
+ [?EVENT1, ?EVENT2, ?EVENT3, ?EVENT6, ?EVENT8],
+ "Discard Deadline and Order Any"),
+ do_discard(Events, ?not_SetDiscardPolicy(PriorityQoS, ?not_DeadlineOrder),
+ [?EVENT1, ?EVENT2, ?EVENT3, ?EVENT6, ?EVENT8],
+ "Discard Deadline and Order Priority"),
+ do_discard(Events, ?not_SetDiscardPolicy(FifoQoS, ?not_DeadlineOrder),
+ [?EVENT1, ?EVENT2, ?EVENT3, ?EVENT6, ?EVENT8],
+ "Discard Deadline and Order Fifo"),
+ do_discard(Events, ?not_SetDiscardPolicy(DeadlineQoS, ?not_DeadlineOrder),
+ [?EVENT6, ?EVENT8, ?EVENT3, ?EVENT2, ?EVENT1],
+ "Discard Deadline and Order Deadline"),
+
+ ok.
+
+do_discard(Events, QoS, Reply, Txt) ->
+ io:format("################# ~s #################~n", [Txt]),
+ Ref = cosNotification_eventDB:create_db(QoS, 60, 50, undefined),
+ create_loop(Events, Ref),
+ ?match({Reply,_}, cosNotification_eventDB:get_events(Ref, ?NO_OF_EVENTS)),
+ cosNotification_eventDB:destroy_db(Ref).
+
+
+%%-----------------------------------------------------------------
+%% cosNotification_eventDB lookup API tests
+%%-----------------------------------------------------------------
+lookup_api(doc) -> ["The event DB is used to store events which cannot be",
+ "delivered at once. This case is supposed to test",
+ "that the events are delivered in the correct order.",
+ ""];
+lookup_api(suite) -> [];
+lookup_api(_Config) ->
+ InitQoS = ?not_CreateInitQoS(),
+ InitQoS2 = ?not_SetMaxEventsPerConsumer(InitQoS,100),
+ InitQoS3 = ?not_SetStartTimeSupported(InitQoS2, false),
+ QoS = ?not_SetDiscardPolicy(InitQoS3, ?not_AnyOrder),
+
+ AnyQoS = ?not_SetOrderPolicy(QoS, ?not_AnyOrder),
+ PriorityQoS = ?not_SetOrderPolicy(QoS, ?not_PriorityOrder),
+ FifoQoS = ?not_SetOrderPolicy(QoS, ?not_FifoOrder),
+ DeadlineQoS = ?not_SetOrderPolicy(QoS, ?not_DeadlineOrder),
+
+ %% "Calculate" data once:
+ Events = ?EVENTS,
+ PrioOrder = ?PRIOORDER,
+ FifoOrder = ?FIFOORDER,
+ DeadlineOrder = ?DEADLINEORDER,
+
+ do_lookup(PriorityQoS, Events, PrioOrder, "Priority Order"),
+ do_lookup(FifoQoS, Events, FifoOrder, "Fifo Order"),
+ do_lookup(DeadlineQoS, Events, DeadlineOrder, "Deadline Order"),
+ do_lookup(AnyQoS, Events, PrioOrder, "Any Order"),
+ ok.
+
+do_lookup(QoS, Events, Return, Txt) ->
+ io:format("#################### ~s ###################~n", [Txt]),
+ Ref = cosNotification_eventDB:create_db(QoS, 60, 50, undefined),
+ create_loop(Events, Ref),
+ ?match({Return,_}, cosNotification_eventDB:get_events(Ref, ?NO_OF_EVENTS)),
+ cosNotification_eventDB:destroy_db(Ref).
+
+
+%%-----------------------------------------------------------------
+%% cosNotification_eventDB max events API tests
+%%-----------------------------------------------------------------
+max_events_api(doc) -> ["The event DB is used to store events which cannot be",
+ "delivered at once. If the MaxEvents QoS is updated we must be",
+ "able to reduce the amount of stored events.",
+ ""];
+max_events_api(suite) -> [];
+max_events_api(_Config) ->
+
+ QoS1 = ?not_CreateInitQoS(),
+ QoS2 = ?not_SetOrderPolicy(QoS1, ?not_FifoOrder),
+ QoS3 = ?not_SetDiscardPolicy(QoS2, ?not_RejectNewEvents),
+ QoS4 = ?not_SetStartTimeSupported(QoS3, false),
+ QoS_NO_OF_EVENTS = ?not_SetMaxEventsPerConsumer(QoS4, ?NO_OF_EVENTS),
+ QoS_5_EVENTS = ?not_SetMaxEventsPerConsumer(QoS4, 5),
+
+ Events = ?EVENTS,
+ Events5 = [?EVENT1, ?EVENT2, ?EVENT3, ?EVENT4, ?EVENT5],
+
+ %% Initiate DB and 'NO_OF_EVENTS' events.
+ Ref1 = cosNotification_eventDB:create_db(QoS_NO_OF_EVENTS, 60, 50, undefined),
+ create_loop(Events, Ref1),
+
+ %% Reduce the limit to 5 and extract all and see if it's ok.
+ Ref2 = cosNotification_eventDB:update(Ref1, QoS_5_EVENTS),
+ ?match({Events5, true}, cosNotification_eventDB:get_events(Ref2, ?NO_OF_EVENTS)),
+
+ %% Add 'NO_OF_EVENTS' events. Since the only allow 5 events the DB will only
+ %% contain 5 events.
+ create_loop(Events, Ref2),
+ Ref3 = cosNotification_eventDB:update(Ref2, QoS_NO_OF_EVENTS),
+
+ ?match({Events5, true}, cosNotification_eventDB:get_events(Ref3, ?NO_OF_EVENTS)),
+ create_loop(Events, Ref3),
+ ?match({Events, true}, cosNotification_eventDB:get_events(Ref3, ?NO_OF_EVENTS)),
+ cosNotification_eventDB:destroy_db(Ref3),
+ ok.
+
+
+%%-----------------------------------------------------------------
+%% cosNotification_eventDB persisten events API tests
+%%-----------------------------------------------------------------
+persisten_event_api(doc) -> ["The event DB is used to store events which cannot be",
+ "delivered at once.",
+ ""];
+persisten_event_api(suite) -> [];
+persisten_event_api(_Config) ->
+
+ QoS1 = ?not_CreateInitQoS(),
+ QoS2 = ?not_SetOrderPolicy(QoS1, ?not_FifoOrder),
+ QoS3 = ?not_SetDiscardPolicy(QoS2, ?not_RejectNewEvents),
+ QoS4 = ?not_SetStartTimeSupported(QoS3, false),
+ QoS = ?not_SetMaxEventsPerConsumer(QoS4, ?NO_OF_EVENTS),
+
+ Event1 = ?EVENT1,
+
+ Ref = cosNotification_eventDB:create_db(QoS, 60, 50, undefined),
+ %% Clean DB, should be empty
+ ?match(0, cosNotification_eventDB:status(Ref, eventCounter)),
+ cosNotification_eventDB:add_event(Ref, Event1),
+ ?match(1, cosNotification_eventDB:status(Ref, eventCounter)),
+ %% Get event without removing it. Should still be one event stored
+ ?match({[Event1], _, _}, cosNotification_eventDB:get_events(Ref, 2, false)),
+ ?match(1, cosNotification_eventDB:status(Ref, eventCounter)),
+ {_, _, Keys} =
+ ?match({Event1, _, _}, cosNotification_eventDB:get_event(Ref, false)),
+ ?match(1, cosNotification_eventDB:status(Ref, eventCounter)),
+ %% Clear the events and check that the DB is empty.
+ cosNotification_eventDB:delete_events(Keys),
+ ?match(0, cosNotification_eventDB:status(Ref, eventCounter)),
+ ?match({[], _, []}, cosNotification_eventDB:get_event(Ref, false)),
+ ?match({[], _, []}, cosNotification_eventDB:get_events(Ref, 2, false)),
+
+ cosNotification_eventDB:destroy_db(Ref),
+ ok.
+
+%%-----------------------------------------------------------------
+%% cosNotification_eventDB gc API tests
+%%-----------------------------------------------------------------
+gc_api(doc) -> ["The event DB is used to store events which cannot be",
+ "delivered at once. If Deadline defined the events that",
+ "are older must be discarded.",
+ ""];
+gc_api(suite) -> [];
+gc_api(_Config) ->
+
+ QoS1 = ?not_CreateInitQoS(),
+ QoS2 = ?not_SetOrderPolicy(QoS1, ?not_FifoOrder),
+ QoS3 = ?not_SetDiscardPolicy(QoS2, ?not_RejectNewEvents),
+ QoS4 = ?not_SetStartTimeSupported(QoS3, false),
+ QoS_NO_OF_EVENTS = ?not_SetMaxEventsPerConsumer(QoS4, ?NO_OF_EVENTS),
+
+ Events = ?EVENTS,
+ Events6 = [?EVENT1, ?EVENT2, ?EVENT3, ?EVENT4, ?EVENT6, ?EVENT7, ?EVENT8],
+ %% Initiate DB and 'NO_OF_EVENTS' events.
+ Ref = cosNotification_eventDB:create_db(QoS_NO_OF_EVENTS, 60, 50, undefined),
+ create_loop(Events, Ref),
+
+ %% Sleep so some events will get 'old'.
+ timer:sleep(23000),
+
+ %% Reduce the limit to 5 and extract all and see if it's ok.
+ cosNotification_eventDB:gc_events(Ref, high),
+
+ %% Since gc is done by another process we must wait so it will have a chance
+ %% to complete the job.
+ timer:sleep(2000),
+
+ ?match({Events6, true}, cosNotification_eventDB:get_events(Ref, ?NO_OF_EVENTS)),
+
+ create_loop(Events, Ref),
+ timer:sleep(23000),
+ ?match({Events6, true}, cosNotification_eventDB:get_events(Ref, ?NO_OF_EVENTS)),
+ cosNotification_eventDB:destroy_db(Ref),
+ ok.
+
+
+%%-----------------------------------------------------------------
+%% cosNotification_eventDB gc API tests
+%%-----------------------------------------------------------------
+auto_gc_api(doc) -> ["The event DB is used to store events which cannot be",
+ "delivered at once. If Deadline defined the events that",
+ "are older must be discarded.",
+ ""];
+auto_gc_api(suite) -> [];
+auto_gc_api(_Config) ->
+
+ QoS1 = ?not_CreateInitQoS(),
+ QoS2 = ?not_SetOrderPolicy(QoS1, ?not_FifoOrder),
+ QoS3 = ?not_SetDiscardPolicy(QoS2, ?not_RejectNewEvents),
+ QoS4 = ?not_SetStopTimeSupported(QoS3, true),
+ QoS5 = ?not_SetStartTimeSupported(QoS4, false),
+ QoS_NO_OF_EVENTS = ?not_SetMaxEventsPerConsumer(QoS5, ?NO_OF_EVENTS),
+
+ Events6 = [?EVENT1, ?EVENT2, ?EVENT3, ?EVENT7, ?EVENT8, ?EVENT9],
+ %% Initiate DB
+ Ref = cosNotification_eventDB:create_db(QoS_NO_OF_EVENTS, 50, 50, undefined),
+ create_loop([?EVENT1, ?EVENT2, ?EVENT3, ?EVENT4, ?EVENT6], Ref),
+
+ %% Sleep so some events will get 'old'.
+ timer:sleep(60000),
+ create_loop([?EVENT7, ?EVENT8, ?EVENT9], Ref),
+
+ %% Since gc is done by another process we must wait so it will have a chance
+ %% to complete the job.
+ timer:sleep(2000),
+
+ ?match({Events6, true}, cosNotification_eventDB:get_events(Ref, ?NO_OF_EVENTS)),
+
+ cosNotification_eventDB:destroy_db(Ref),
+
+ ok.
+
+
+%%-----------------------------------------------------------------
+%% cosNotification_eventDB start- and stop-time API tests
+%%-----------------------------------------------------------------
+start_stop_time_api(doc) -> ["The event DB is used to store events which cannot be",
+ "delivered at once. If Deadline defined the events that",
+ "are older must be discarded.",
+ ""];
+start_stop_time_api(suite) -> [];
+start_stop_time_api(_Config) ->
+
+ QoS1 = ?not_CreateInitQoS(),
+ QoS2 = ?not_SetOrderPolicy(QoS1, ?not_FifoOrder),
+ QoS3 = ?not_SetDiscardPolicy(QoS2, ?not_RejectNewEvents),
+ QoS4 = ?not_SetStopTimeSupported(QoS3, true),
+ QoS5 = ?not_SetStartTimeSupported(QoS4, true),
+ QoS_NO_OF_EVENTS = ?not_SetMaxEventsPerConsumer(QoS5, ?NO_OF_EVENTS),
+
+ %% Initiate DB
+ TimeService = cosTime:start_time_service(2, 0),
+ Ref = cosNotification_eventDB:create_db(QoS_NO_OF_EVENTS, 50, 50, TimeService),
+
+ T1 = 'CosTime_UTO':'_get_utc_time'('CosTime_UTO':
+ absolute_time('CosTime_TimeService':
+ new_universal_time(TimeService,
+ 100000000, 0, 2))),
+ T2 = 'CosTime_UTO':'_get_utc_time'('CosTime_UTO':
+ absolute_time('CosTime_TimeService':
+ new_universal_time(TimeService,
+ 200000000, 0, 2))),
+ T3 = 'CosTime_UTO':'_get_utc_time'('CosTime_UTO':
+ absolute_time('CosTime_TimeService':
+ new_universal_time(TimeService,
+ 300000000, 0, 2))),
+ T4 = 'CosTime_UTO':'_get_utc_time'('CosTime_UTO':
+ absolute_time('CosTime_TimeService':
+ new_universal_time(TimeService,
+ 400000000, 0, 2))),
+ %% Delivered after 10 seconds discarded after 20.
+ EVENT1 = ?not_CreateSE("","event1","",
+ [#'CosNotification_Property'
+ {name="Priority",
+ value=any:create(orber_tc:short(), 1)},
+ #'CosNotification_Property'
+ {name="StartTime",
+ value=any:create('TimeBase_UtcT':tc(), T1)},
+ #'CosNotification_Property'
+ {name="StopTime",
+ value=any:create('TimeBase_UtcT':tc(), T2)}],
+ [], any:create(orber_tc:null(), null)),
+
+ %% Delivered after 30 seconds discarded after 10, i.e., always discarded.
+ EVENT2 = ?not_CreateSE("","event2","",
+ [#'CosNotification_Property'
+ {name="Priority",
+ value=any:create(orber_tc:short(), 3)},
+ #'CosNotification_Property'
+ {name="StartTime",
+ value=any:create('TimeBase_UtcT':tc(), T3)},
+ #'CosNotification_Property'
+ {name="StopTime",
+ value=any:create('TimeBase_UtcT':tc(), T1)}],
+ [], any:create(orber_tc:null(), null)),
+
+ %% Delivered after 20 seconds discarded after 40
+ EVENT3 = ?not_CreateSE("","event3","",
+ [#'CosNotification_Property'
+ {name="Priority",
+ value=any:create(orber_tc:short(), 2)},
+ #'CosNotification_Property'
+ {name="StartTime",
+ value=any:create('TimeBase_UtcT':tc(), T2)},
+ #'CosNotification_Property'
+ {name="StopTime",
+ value=any:create('TimeBase_UtcT':tc(), T4)}],
+ [], any:create(orber_tc:null(), null)),
+
+
+
+
+ create_loop([EVENT1, EVENT2, EVENT3], Ref),
+
+ ?match({[], false}, cosNotification_eventDB:get_events(Ref, ?NO_OF_EVENTS)),
+
+ %% Sleep so some events will get 'old'.
+ timer:sleep(12000),
+
+ ?match({[EVENT1], true}, cosNotification_eventDB:get_events(Ref, ?NO_OF_EVENTS)),
+
+ ?match({[], false}, cosNotification_eventDB:get_events(Ref, ?NO_OF_EVENTS)),
+
+ timer:sleep(10000),
+
+ ?match({[EVENT3], true}, cosNotification_eventDB:get_events(Ref, ?NO_OF_EVENTS)),
+
+ timer:sleep(20000),
+
+ %% See if EVENT2 really have been discarded.
+ ?match({[], false}, cosNotification_eventDB:get_events(Ref, ?NO_OF_EVENTS)),
+
+ cosNotification_eventDB:destroy_db(Ref),
+
+ cosTime:stop_time_service(TimeService),
+
+ ok.
+
+
+%%-----------------------------------------------------------------
+%% cosNotification_eventDB order API tests
+%%-----------------------------------------------------------------
+reorder_api(doc) -> ["The event DB is used to store events which cannot be",
+ "delivered at once. If the QoS is updated we must be",
+ "able to change the ordering of events as the discard",
+ "and order policies tells us.",
+ ""];
+reorder_api(suite) -> [];
+reorder_api(_Config) ->
+ %% We need to test switching between:
+ %% * Priority -> Fifo
+ %% * Priority -> Deadline
+ %% * Fifo -> Priority
+ %% * Fifo -> Deadline
+ %% * Deadline -> Priority
+ %% * Deadline -> Fifo
+ QoS = ?not_CreateInitQoS(),
+ QoS2 = ?not_SetMaxEventsPerConsumer(QoS,100),
+ QoS3 = ?not_SetPriority(QoS2, 10),
+ QoS4 = ?not_SetStartTimeSupported(QoS3, false),
+ QoS5 = ?not_SetOrderPolicy(QoS4, ?not_AnyOrder),
+
+
+ %% Test all order policies using Any order discard policy.
+ reorder_helper(?not_SetDiscardPolicy(QoS5, ?not_AnyOrder), "Discard Any"),
+ reorder_helper(?not_SetDiscardPolicy(QoS5, ?not_PriorityOrder), "Discard Priority"),
+ reorder_helper(?not_SetDiscardPolicy(QoS5, ?not_DeadlineOrder), "Discard Deadline"),
+ reorder_helper(?not_SetDiscardPolicy(QoS5, ?not_FifoOrder), "Discard Fifo"),
+ reorder_helper(?not_SetDiscardPolicy(QoS5, ?not_LifoOrder), "Discard Lifo"),
+ reorder_helper(?not_SetDiscardPolicy(QoS5, ?not_RejectNewEvents), "Reject New Events"),
+
+ ok.
+
+
+reorder_helper(QoS, Txt) ->
+ io:format("$$$$$$$$$$$$$$$$$$$$ ~s $$$$$$$$$$$$$$$$$$$~n", [Txt]),
+ %% Create a DB with the above settings.
+ Ref = cosNotification_eventDB:create_db(QoS, 60, 50, undefined),
+
+ Events = ?EVENTS,
+ PrioOrder = ?PRIOORDER,
+ FifoOrder = ?FIFOORDER,
+ DeadlineOrder = ?DEADLINEORDER,
+
+ %% Test all order policies using Any order discard policy.
+ Ref2 = do_reorder(Ref, Events, ?not_SetOrderPolicy(QoS, ?not_FifoOrder),
+ FifoOrder, "Priority -> Fifo"),
+ Ref3 = do_reorder(Ref2, Events, ?not_SetOrderPolicy(QoS, ?not_PriorityOrder),
+ PrioOrder, "Fifo -> Priority"),
+ Ref4 = do_reorder(Ref3, Events, ?not_SetOrderPolicy(QoS, ?not_DeadlineOrder),
+ DeadlineOrder, "Priority -> Deadline"),
+
+ Ref5 = do_reorder(Ref4, Events, ?not_SetOrderPolicy(QoS, ?not_PriorityOrder),
+ PrioOrder, "Deadline -> Priority"),
+
+ Ref6 = do_reorder(Ref5, Events, ?not_SetOrderPolicy(QoS, ?not_FifoOrder),
+ FifoOrder, "Priority -> Fifo"),
+
+ Ref7 = do_reorder(Ref6, Events, ?not_SetOrderPolicy(QoS, ?not_DeadlineOrder),
+ DeadlineOrder, "Fifo -> Deadline"),
+
+ Ref8 = do_reorder(Ref7, Events, ?not_SetOrderPolicy(QoS, ?not_FifoOrder),
+ FifoOrder, "Deadline -> Fifo"),
+ cosNotification_eventDB:destroy_db(Ref8),
+ ok.
+
+
+
+do_reorder(Ref, Events, QoS, Reply, Txt) ->
+ create_loop(Events, Ref),
+ io:format("################# ~s #################~n", [Txt]),
+ NewRef = cosNotification_eventDB:update(Ref, QoS),
+ ?match({Reply,_}, cosNotification_eventDB:get_events(NewRef, ?NO_OF_EVENTS)),
+ NewRef.
+
+%%-----------------------------------------------------------------
+%% Internal functions
+%%-----------------------------------------------------------------
+%% This functions takes as argument a list of structured events.
+create_loop([], _Ref) ->
+ ok;
+create_loop([H|T], Ref) ->
+ catch cosNotification_eventDB:add_event(Ref, H),
+ create_loop(T, Ref).
+
+create_loop([], _Ref, _Life, _Prio) ->
+ ok;
+create_loop([H|T], Ref, Life, Prio) ->
+ catch cosNotification_eventDB:add_event(Ref, H, Life, Prio),
+ create_loop(T, Ref, Life, Prio).
+
+%%-------------------- End of Module ------------------------------
diff --git a/lib/cosNotification/test/generated_SUITE.erl b/lib/cosNotification/test/generated_SUITE.erl
new file mode 100644
index 0000000000..34b84041f0
--- /dev/null
+++ b/lib/cosNotification/test/generated_SUITE.erl
@@ -0,0 +1,2042 @@
+%%-----------------------------------------------------------------
+%%
+%% %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%
+%%
+%%
+%%-----------------------------------------------------------------
+%% File : generated_SUITE.erl
+%% Purpose :
+%%-----------------------------------------------------------------
+
+-module(generated_SUITE).
+
+-include("test_server.hrl").
+-include_lib("orber/include/corba.hrl").
+
+-define(default_timeout, ?t:minutes(3)).
+
+-define(match(ExpectedRes, Expr),
+ fun() ->
+ AcTuAlReS = (catch (Expr)),
+ case AcTuAlReS of
+ ExpectedRes ->
+ AcTuAlReS;
+ _ ->
+ io:format("###### ERROR ERROR ######~n~p~n",
+ [AcTuAlReS]),
+ ?line exit(AcTuAlReS)
+ end
+ end()).
+
+-define(nomatch(Not, Expr),
+ fun() ->
+ AcTuAlReS = (catch (Expr)),
+ case AcTuAlReS of
+ Not ->
+ io:format("###### ERROR ERROR ######~n~p~n",
+ [AcTuAlReS]),
+ ?line exit(AcTuAlReS);
+ _ ->
+ AcTuAlReS
+ end
+ end()).
+
+
+-define(checktc(_Op),
+ fun(TC) ->
+ case orber_tc:check_tc(TC) of
+ false ->
+ io:format("###### ERROR ERROR ######~n~p - ~p~n", [Op, TC]),
+ ?line exit(TC);
+ true ->
+ true
+ end
+ end).
+
+%%-----------------------------------------------------------------
+%% External exports
+%%-----------------------------------------------------------------
+-export([all/1]).
+
+%%-----------------------------------------------------------------
+%% Internal exports
+%%-----------------------------------------------------------------
+-export([]).
+-compile(export_all).
+
+%%-----------------------------------------------------------------
+%% Func: all/1
+%% Args:
+%% Returns:
+%%-----------------------------------------------------------------
+all(doc) -> ["This suite is for testing IC generated files"];
+all(suite) ->
+ ['CosNotification', 'CosNotification_AdminPropertiesAdmin',
+ 'CosNotification_EventHeader', 'CosNotification_EventType',
+ 'CosNotification_FixedEventHeader', 'CosNotification_NamedPropertyRange',
+ 'CosNotification_Property', 'CosNotification_PropertyError',
+ 'CosNotification_PropertyRange', 'CosNotification_QoSAdmin',
+ 'CosNotification_StructuredEvent', 'CosNotification_UnsupportedAdmin',
+ 'CosNotification_UnsupportedQoS', 'CosNotification_EventBatch',
+ 'CosNotification_EventTypeSeq', 'CosNotification_NamedPropertyRangeSeq',
+ 'CosNotification_PropertyErrorSeq', 'CosNotifyChannelAdmin_AdminLimit',
+ 'CosNotifyChannelAdmin_AdminNotFound', 'CosNotifyChannelAdmin_ChannelNotFound',
+ 'CosNotifyChannelAdmin_ConnectionAlreadyActive', 'CosNotifyChannelAdmin_ConnectionAlreadyInactive',
+ 'CosNotifyChannelAdmin_NotConnected', 'CosNotifyChannelAdmin_AdminIDSeq',
+ 'CosNotifyChannelAdmin_ChannelIDSeq', 'CosNotifyChannelAdmin_ProxyIDSeq',
+ 'CosNotifyFilter_CallbackNotFound', 'CosNotifyFilter_ConstraintExp',
+ 'CosNotifyFilter_ConstraintInfo', 'CosNotifyFilter_ConstraintNotFound',
+ 'CosNotifyFilter_DuplicateConstraintID', 'CosNotifyFilter_FilterNotFound',
+ 'CosNotifyFilter_InvalidConstraint', 'CosNotifyFilter_InvalidGrammar',
+ 'CosNotifyFilter_InvalidValue', 'CosNotifyFilter_MappingConstraintInfo',
+ 'CosNotifyFilter_MappingConstraintPair', 'CosNotifyFilter_UnsupportedFilterableData',
+ 'CosNotifyFilter_CallbackIDSeq', 'CosNotifyFilter_ConstraintExpSeq',
+ 'CosNotifyFilter_ConstraintIDSeq', 'CosNotifyFilter_ConstraintInfoSeq',
+ 'CosNotifyFilter_FilterIDSeq', 'CosNotifyFilter_MappingConstraintInfoSeq',
+ 'CosNotifyFilter_MappingConstraintPairSeq', 'CosNotifyComm_InvalidEventType',
+ 'CosNotifyChannelAdmin_ConsumerAdmin', 'CosNotifyChannelAdmin_EventChannel',
+ 'CosNotifyChannelAdmin_EventChannelFactory', 'CosNotifyChannelAdmin_ProxyConsumer',
+ 'CosNotifyChannelAdmin_ProxyNotFound', 'CosNotifyChannelAdmin_ProxyPullConsumer',
+ 'CosNotifyChannelAdmin_ProxyPullSupplier', 'CosNotifyChannelAdmin_ProxyPushConsumer',
+ 'CosNotifyChannelAdmin_ProxyPushSupplier', 'CosNotifyChannelAdmin_ProxySupplier',
+ 'CosNotifyChannelAdmin_SequenceProxyPullConsumer', 'CosNotifyChannelAdmin_SequenceProxyPullSupplier',
+ 'CosNotifyChannelAdmin_SequenceProxyPushConsumer', 'CosNotifyChannelAdmin_SequenceProxyPushSupplier',
+ 'CosNotifyChannelAdmin_StructuredProxyPullConsumer', 'CosNotifyChannelAdmin_StructuredProxyPullSupplier',
+ 'CosNotifyChannelAdmin_StructuredProxyPushConsumer', 'CosNotifyChannelAdmin_StructuredProxyPushSupplier',
+ 'CosNotifyChannelAdmin_SupplierAdmin', 'CosNotifyFilter_Filter',
+ 'CosNotifyFilter_FilterAdmin', 'CosNotifyFilter_FilterFactory',
+ 'CosNotifyFilter_MappingFilter', 'CosNotifyComm_NotifyPublish',
+ 'CosNotifyComm_NotifySubscribe', 'CosNotifyComm_PullConsumer',
+ 'CosNotifyComm_PullSupplier', 'CosNotifyComm_PushConsumer',
+ 'CosNotifyComm_PushSupplier', 'CosNotifyComm_SequencePullConsumer',
+ 'CosNotifyComm_SequencePullSupplier', 'CosNotifyComm_SequencePushConsumer',
+ 'CosNotifyComm_SequencePushSupplier', 'CosNotifyComm_StructuredPullConsumer',
+ 'CosNotifyComm_StructuredPullSupplier', 'CosNotifyComm_StructuredPushConsumer',
+ 'CosNotifyComm_StructuredPushSupplier', 'oe_CosNotificationComm_Event',
+ 'CosNotification_PropertySeq'].
+
+%%-----------------------------------------------------------------
+%% Init and cleanup functions.
+%%-----------------------------------------------------------------
+init_per_testcase(_Case, Config) ->
+ ?line Dog=test_server:timetrap(?default_timeout),
+ [{watchdog, Dog}|Config].
+
+
+fin_per_testcase(_Case, Config) ->
+ Dog = ?config(watchdog, Config),
+ test_server:timetrap_cancel(Dog),
+ ok.
+
+%%-----------------------------------------------------------------
+%% Test Case: 'CosNotification'
+%% Description:
+%%-----------------------------------------------------------------
+'CosNotification'(doc) -> ["CosNotification"];
+'CosNotification'(suite) -> [];
+'CosNotification'(_) ->
+ ?match("EventReliability", 'CosNotification':'EventReliability'()),
+ ?match(0, 'CosNotification':'BestEffort'()),
+ ?match(1, 'CosNotification':'Persistent'()),
+ ?match("ConnectionReliability", 'CosNotification':'ConnectionReliability'()),
+ ?match("Priority", 'CosNotification':'Priority'()),
+ ?match(-32767, 'CosNotification':'LowestPriority'()),
+ ?match(32767, 'CosNotification':'HighestPriority'()),
+ ?match(0, 'CosNotification':'DefaultPriority'()),
+ ?match("StartTime", 'CosNotification':'StartTime'()),
+ ?match("StopTime", 'CosNotification':'StopTime'()),
+ ?match("Timeout", 'CosNotification':'Timeout'()),
+ ?match("OrderPolicy", 'CosNotification':'OrderPolicy'()),
+ ?match(0, 'CosNotification':'AnyOrder'()),
+ ?match(1, 'CosNotification':'FifoOrder'()),
+ ?match(2, 'CosNotification':'PriorityOrder'()),
+ ?match(3, 'CosNotification':'DeadlineOrder'()),
+ ?match("DiscardPolicy", 'CosNotification':'DiscardPolicy'()),
+ ?match(4, 'CosNotification':'LifoOrder'()),
+ ?match(5, 'CosNotification':'RejectNewEvents'()),
+ ?match("MaximumBatchSize", 'CosNotification':'MaximumBatchSize'()),
+ ?match("PacingInterval", 'CosNotification':'PacingInterval'()),
+ ?match("StartTimeSupported", 'CosNotification':'StartTimeSupported'()),
+ ?match("StopTimeSupported", 'CosNotification':'StopTimeSupported'()),
+ ?match("MaxEventsPerConsumer", 'CosNotification':'MaxEventsPerConsumer'()),
+ ?match("MaxQueueLength", 'CosNotification':'MaxQueueLength'()),
+ ?match("MaxConsumers", 'CosNotification':'MaxConsumers'()),
+ ?match("MaxSuppliers", 'CosNotification':'MaxSuppliers'()),
+ ok.
+
+%%-----------------------------------------------------------------
+%% Test Case: 'CosNotification_EventHeader'
+%% Description:
+%%-----------------------------------------------------------------
+'CosNotification_EventHeader'(doc) -> ["CosNotification_EventHeader"];
+'CosNotification_EventHeader'(suite) -> [];
+'CosNotification_EventHeader'(_) ->
+ ?match(true, orber_tc:check_tc('CosNotification_EventHeader':tc())),
+ ?match("IDL:omg.org/CosNotification/EventHeader:1.0",
+ 'CosNotification_EventHeader':id()),
+ ?match("CosNotification_EventHeader",
+ 'CosNotification_EventHeader':name()),
+ ok.
+
+
+%%-----------------------------------------------------------------
+%% Test Case: 'CosNotification_EventType'
+%% Description:
+%%-----------------------------------------------------------------
+'CosNotification_EventType'(doc) -> ["CosNotification_EventType"];
+'CosNotification_EventType'(suite) -> [];
+'CosNotification_EventType'(_) ->
+ ?match(true, orber_tc:check_tc('CosNotification_EventType':tc())),
+ ?match("IDL:omg.org/CosNotification/EventType:1.0",
+ 'CosNotification_EventType':id()),
+ ?match("CosNotification_EventType",
+ 'CosNotification_EventType':name()),
+ ok.
+
+
+%%-----------------------------------------------------------------
+%% Test Case: 'CosNotification_FixedEventHeader'
+%% Description:
+%%-----------------------------------------------------------------
+'CosNotification_FixedEventHeader'(doc) -> ["CosNotification_FixedEventHeader"];
+'CosNotification_FixedEventHeader'(suite) -> [];
+'CosNotification_FixedEventHeader'(_) ->
+ ?match(true, orber_tc:check_tc('CosNotification_FixedEventHeader':tc())),
+ ?match("IDL:omg.org/CosNotification/FixedEventHeader:1.0",
+ 'CosNotification_FixedEventHeader':id()),
+ ?match("CosNotification_FixedEventHeader",
+ 'CosNotification_FixedEventHeader':name()),
+ ok.
+
+
+%%-----------------------------------------------------------------
+%% Test Case: 'CosNotification_NamedPropertyRange'
+%% Description:
+%%-----------------------------------------------------------------
+'CosNotification_NamedPropertyRange'(doc) -> ["CosNotification_NamedPropertyRange"];
+'CosNotification_NamedPropertyRange'(suite) -> [];
+'CosNotification_NamedPropertyRange'(_) ->
+ ?match(true, orber_tc:check_tc('CosNotification_NamedPropertyRange':tc())),
+ ?match("IDL:omg.org/CosNotification/NamedPropertyRange:1.0",
+ 'CosNotification_NamedPropertyRange':id()),
+ ?match("CosNotification_NamedPropertyRange",
+ 'CosNotification_NamedPropertyRange':name()),
+ ok.
+
+
+%%-----------------------------------------------------------------
+%% Test Case: 'CosNotification_Property'
+%% Description:
+%%-----------------------------------------------------------------
+'CosNotification_Property'(doc) -> ["CosNotification_Property"];
+'CosNotification_Property'(suite) -> [];
+'CosNotification_Property'(_) ->
+ ?match(true, orber_tc:check_tc('CosNotification_Property':tc())),
+ ?match("IDL:omg.org/CosNotification/Property:1.0",
+ 'CosNotification_Property':id()),
+ ?match("CosNotification_Property",
+ 'CosNotification_Property':name()),
+ ok.
+
+
+%%-----------------------------------------------------------------
+%% Test Case: 'CosNotification_PropertyError'
+%% Description:
+%%-----------------------------------------------------------------
+'CosNotification_PropertyError'(doc) -> ["CosNotification_PropertyError"];
+'CosNotification_PropertyError'(suite) -> [];
+'CosNotification_PropertyError'(_) ->
+ ?match(true, orber_tc:check_tc('CosNotification_PropertyError':tc())),
+ ?match("IDL:omg.org/CosNotification/PropertyError:1.0",
+ 'CosNotification_PropertyError':id()),
+ ?match("CosNotification_PropertyError",
+ 'CosNotification_PropertyError':name()),
+ ok.
+
+
+%%-----------------------------------------------------------------
+%% Test Case: 'CosNotification_PropertyRange'
+%% Description:
+%%-----------------------------------------------------------------
+'CosNotification_PropertyRange'(doc) -> [""];
+'CosNotification_PropertyRange'(suite) -> [];
+'CosNotification_PropertyRange'(_) ->
+ ?match(true, orber_tc:check_tc('CosNotification_PropertyRange':tc())),
+ ?match("IDL:omg.org/CosNotification/PropertyRange:1.0",
+ 'CosNotification_PropertyRange':id()),
+ ?match("CosNotification_PropertyRange",
+ 'CosNotification_PropertyRange':name()),
+ ok.
+
+
+%%-----------------------------------------------------------------
+%% Test Case: 'CosNotification_StructuredEvent'
+%% Description:
+%%-----------------------------------------------------------------
+'CosNotification_StructuredEvent'(doc) -> ["CosNotification_StructuredEvent"];
+'CosNotification_StructuredEvent'(suite) -> [];
+'CosNotification_StructuredEvent'(_) ->
+ ?match(true, orber_tc:check_tc('CosNotification_StructuredEvent':tc())),
+ ?match("IDL:omg.org/CosNotification/StructuredEvent:1.0",
+ 'CosNotification_StructuredEvent':id()),
+ ?match("CosNotification_StructuredEvent",
+ 'CosNotification_StructuredEvent':name()),
+ ok.
+
+
+%%-----------------------------------------------------------------
+%% Test Case: 'CosNotification_UnsupportedAdmin'
+%% Description:
+%%-----------------------------------------------------------------
+'CosNotification_UnsupportedAdmin'(doc) -> ["CosNotification_UnsupportedAdmin"];
+'CosNotification_UnsupportedAdmin'(suite) -> [];
+'CosNotification_UnsupportedAdmin'(_) ->
+ ?match(true, orber_tc:check_tc('CosNotification_UnsupportedAdmin':tc())),
+ ?match("IDL:omg.org/CosNotification/UnsupportedAdmin:1.0",
+ 'CosNotification_UnsupportedAdmin':id()),
+ ?match("CosNotification_UnsupportedAdmin",
+ 'CosNotification_UnsupportedAdmin':name()),
+ ok.
+
+
+%%-----------------------------------------------------------------
+%% Test Case: 'CosNotification_UnsupportedQoS'
+%% Description:
+%%-----------------------------------------------------------------
+'CosNotification_UnsupportedQoS'(doc) -> ["CosNotification_UnsupportedQoS"];
+'CosNotification_UnsupportedQoS'(suite) -> [];
+'CosNotification_UnsupportedQoS'(_) ->
+ ?match(true, orber_tc:check_tc('CosNotification_UnsupportedQoS':tc())),
+ ?match("IDL:omg.org/CosNotification/UnsupportedQoS:1.0",
+ 'CosNotification_UnsupportedQoS':id()),
+ ?match("CosNotification_UnsupportedQoS",
+ 'CosNotification_UnsupportedQoS':name()),
+ ok.
+
+
+%%-----------------------------------------------------------------
+%% Test Case: 'CosNotification_EventBatch'
+%% Description:
+%%-----------------------------------------------------------------
+'CosNotification_EventBatch'(doc) -> ["CosNotification_EventBatch"];
+'CosNotification_EventBatch'(suite) -> [];
+'CosNotification_EventBatch'(_) ->
+ ?match(true, orber_tc:check_tc('CosNotification_EventBatch':tc())),
+ ?match("IDL:omg.org/CosNotification/EventBatch:1.0",
+ 'CosNotification_EventBatch':id()),
+ ?match("CosNotification_EventBatch",
+ 'CosNotification_EventBatch':name()),
+ ok.
+
+
+%%-----------------------------------------------------------------
+%% Test Case: 'CosNotification_EventTypeSeq'
+%% Description:
+%%-----------------------------------------------------------------
+'CosNotification_EventTypeSeq'(doc) -> ["CosNotification_EventTypeSeq"];
+'CosNotification_EventTypeSeq'(suite) -> [];
+'CosNotification_EventTypeSeq'(_) ->
+ ?match(true, orber_tc:check_tc('CosNotification_EventTypeSeq':tc())),
+ ?match("IDL:omg.org/CosNotification/EventTypeSeq:1.0",
+ 'CosNotification_EventTypeSeq':id()),
+ ?match("CosNotification_EventTypeSeq",
+ 'CosNotification_EventTypeSeq':name()),
+ ok.
+
+
+%%-----------------------------------------------------------------
+%% Test Case: 'CosNotification_NamedPropertyRangeSeq'
+%% Description:
+%%-----------------------------------------------------------------
+'CosNotification_NamedPropertyRangeSeq'(doc) -> ["CosNotification_NamedPropertyRangeSeq"];
+'CosNotification_NamedPropertyRangeSeq'(suite) -> [];
+'CosNotification_NamedPropertyRangeSeq'(_) ->
+ ?match(true, orber_tc:check_tc('CosNotification_NamedPropertyRangeSeq':tc())),
+ ?match("IDL:omg.org/CosNotification/NamedPropertyRangeSeq:1.0",
+ 'CosNotification_NamedPropertyRangeSeq':id()),
+ ?match("CosNotification_NamedPropertyRangeSeq",
+ 'CosNotification_NamedPropertyRangeSeq':name()),
+ ok.
+
+
+%%-----------------------------------------------------------------
+%% Test Case: 'CosNotification_PropertyErrorSeq'
+%% Description:
+%%-----------------------------------------------------------------
+'CosNotification_PropertyErrorSeq'(doc) -> ["CosNotification_PropertyErrorSeq"];
+'CosNotification_PropertyErrorSeq'(suite) -> [];
+'CosNotification_PropertyErrorSeq'(_) ->
+ ?match(true, orber_tc:check_tc('CosNotification_PropertyErrorSeq':tc())),
+ ?match("IDL:omg.org/CosNotification/PropertyErrorSeq:1.0",
+ 'CosNotification_PropertyErrorSeq':id()),
+ ?match("CosNotification_PropertyErrorSeq",
+ 'CosNotification_PropertyErrorSeq':name()),
+ ok.
+
+
+%%-----------------------------------------------------------------
+%% Test Case: 'CosNotification_PropertySeq'
+%% Description:
+%%-----------------------------------------------------------------
+'CosNotification_PropertySeq'(doc) -> ["CosNotification_PropertySeq"];
+'CosNotification_PropertySeq'(suite) -> [];
+'CosNotification_PropertySeq'(_) ->
+ ?match(true, orber_tc:check_tc('CosNotification_PropertySeq':tc())),
+ ?match("IDL:omg.org/CosNotification/PropertySeq:1.0",
+ 'CosNotification_PropertySeq':id()),
+ ?match("CosNotification_PropertySeq",
+ 'CosNotification_PropertySeq':name()),
+ ok.
+
+
+%%-----------------------------------------------------------------
+%% Test Case: 'CosNotifyChannelAdmin_AdminLimit'
+%% Description:
+%%-----------------------------------------------------------------
+'CosNotifyChannelAdmin_AdminLimit'(doc) -> ["CosNotifyChannelAdmin_AdminLimit"];
+'CosNotifyChannelAdmin_AdminLimit'(suite) -> [];
+'CosNotifyChannelAdmin_AdminLimit'(_) ->
+ ?match(true, orber_tc:check_tc('CosNotifyChannelAdmin_AdminLimit':tc())),
+ ?match("IDL:omg.org/CosNotifyChannelAdmin/AdminLimit:1.0",
+ 'CosNotifyChannelAdmin_AdminLimit':id()),
+ ?match("CosNotifyChannelAdmin_AdminLimit",
+ 'CosNotifyChannelAdmin_AdminLimit':name()),
+ ok.
+
+
+%%-----------------------------------------------------------------
+%% Test Case: 'CosNotifyChannelAdmin_AdminLimitExceeded'
+%% Description:
+%%-----------------------------------------------------------------
+'CosNotifyChannelAdmin_AdminLimitExceeded'(doc) -> ["CosNotifyChannelAdmin_AdminLimitExceeded"];
+'CosNotifyChannelAdmin_AdminLimitExceeded'(suite) -> [];
+'CosNotifyChannelAdmin_AdminLimitExceeded'(_) ->
+ ?match(true, orber_tc:check_tc('CosNotifyChannelAdmin_AdminLimitExceeded':tc())),
+ ?match("IDL:omg.org/CosNotifyChannelAdmin/AdminLimitExceeded:1.0",
+ 'CosNotifyChannelAdmin_AdminLimitExceeded':id()),
+ ?match("CosNotifyChannelAdmin_AdminLimitExceeded",
+ 'CosNotifyChannelAdmin_AdminLimitExceeded':name()),
+ ok.
+
+
+%%-----------------------------------------------------------------
+%% Test Case: 'CosNotifyChannelAdmin_AdminNotFound'
+%% Description:
+%%-----------------------------------------------------------------
+'CosNotifyChannelAdmin_AdminNotFound'(doc) -> ["CosNotifyChannelAdmin_AdminNotFound"];
+'CosNotifyChannelAdmin_AdminNotFound'(suite) -> [];
+'CosNotifyChannelAdmin_AdminNotFound'(_) ->
+ ?match(true, orber_tc:check_tc('CosNotifyChannelAdmin_AdminNotFound':tc())),
+ ?match("IDL:omg.org/CosNotifyChannelAdmin/AdminNotFound:1.0",
+ 'CosNotifyChannelAdmin_AdminNotFound':id()),
+ ?match("CosNotifyChannelAdmin_AdminNotFound",
+ 'CosNotifyChannelAdmin_AdminNotFound':name()),
+ ok.
+
+
+%%-----------------------------------------------------------------
+%% Test Case: 'CosNotifyChannelAdmin_ChannelNotFound'
+%% Description:
+%%-----------------------------------------------------------------
+'CosNotifyChannelAdmin_ChannelNotFound'(doc) -> ["CosNotifyChannelAdmin_ChannelNotFound"];
+'CosNotifyChannelAdmin_ChannelNotFound'(suite) -> [];
+'CosNotifyChannelAdmin_ChannelNotFound'(_) ->
+ ?match(true, orber_tc:check_tc('CosNotifyChannelAdmin_ChannelNotFound':tc())),
+ ?match("IDL:omg.org/CosNotifyChannelAdmin/ChannelNotFound:1.0",
+ 'CosNotifyChannelAdmin_ChannelNotFound':id()),
+ ?match("CosNotifyChannelAdmin_ChannelNotFound",
+ 'CosNotifyChannelAdmin_ChannelNotFound':name()),
+ ok.
+
+
+%%-----------------------------------------------------------------
+%% Test Case: 'CosNotifyChannelAdmin_ConnectionAlreadyActive'
+%% Description:
+%%-----------------------------------------------------------------
+'CosNotifyChannelAdmin_ConnectionAlreadyActive'(doc) -> ["CosNotifyChannelAdmin_ConnectionAlreadyActive"];
+'CosNotifyChannelAdmin_ConnectionAlreadyActive'(suite) -> [];
+'CosNotifyChannelAdmin_ConnectionAlreadyActive'(_) ->
+ ?match(true, orber_tc:check_tc('CosNotifyChannelAdmin_ConnectionAlreadyActive':tc())),
+ ?match("IDL:omg.org/CosNotifyChannelAdmin/ConnectionAlreadyActive:1.0",
+ 'CosNotifyChannelAdmin_ConnectionAlreadyActive':id()),
+ ?match("CosNotifyChannelAdmin_ConnectionAlreadyActive",
+ 'CosNotifyChannelAdmin_ConnectionAlreadyActive':name()),
+ ok.
+
+
+%%-----------------------------------------------------------------
+%% Test Case: 'CosNotifyChannelAdmin_ConnectionAlreadyInactive'
+%% Description:
+%%-----------------------------------------------------------------
+'CosNotifyChannelAdmin_ConnectionAlreadyInactive'(doc) -> ["CosNotifyChannelAdmin_ConnectionAlreadyInactive"];
+'CosNotifyChannelAdmin_ConnectionAlreadyInactive'(suite) -> [];
+'CosNotifyChannelAdmin_ConnectionAlreadyInactive'(_) ->
+ ?match(true, orber_tc:check_tc('CosNotifyChannelAdmin_ConnectionAlreadyInactive':tc())),
+ ?match("IDL:omg.org/CosNotifyChannelAdmin/ConnectionAlreadyInactive:1.0",
+ 'CosNotifyChannelAdmin_ConnectionAlreadyInactive':id()),
+ ?match("CosNotifyChannelAdmin_ConnectionAlreadyInactive",
+ 'CosNotifyChannelAdmin_ConnectionAlreadyInactive':name()),
+ ok.
+
+%%-----------------------------------------------------------------
+%% Test Case: 'CosNotifyChannelAdmin_NotConnected'
+%% Description:
+%%-----------------------------------------------------------------
+'CosNotifyChannelAdmin_NotConnected'(doc) -> ["CosNotifyChannelAdmin_NotConnected"];
+'CosNotifyChannelAdmin_NotConnected'(suite) -> [];
+'CosNotifyChannelAdmin_NotConnected'(_) ->
+ ?match(true, orber_tc:check_tc('CosNotifyChannelAdmin_NotConnected':tc())),
+ ?match("IDL:omg.org/CosNotifyChannelAdmin/NotConnected:1.0",
+ 'CosNotifyChannelAdmin_NotConnected':id()),
+ ?match("CosNotifyChannelAdmin_NotConnected",
+ 'CosNotifyChannelAdmin_NotConnected':name()),
+ ok.
+
+%%-----------------------------------------------------------------
+%% Test Case: 'CosNotifyChannelAdmin_AdminIDSeq'
+%% Description:
+%%-----------------------------------------------------------------
+'CosNotifyChannelAdmin_AdminIDSeq'(doc) -> ["CosNotifyChannelAdmin_AdminIDSeq"];
+'CosNotifyChannelAdmin_AdminIDSeq'(suite) -> [];
+'CosNotifyChannelAdmin_AdminIDSeq'(_) ->
+ ?match(true, orber_tc:check_tc('CosNotifyChannelAdmin_AdminIDSeq':tc())),
+ ?match("IDL:omg.org/CosNotifyChannelAdmin/AdminIDSeq:1.0",
+ 'CosNotifyChannelAdmin_AdminIDSeq':id()),
+ ?match("CosNotifyChannelAdmin_AdminIDSeq",
+ 'CosNotifyChannelAdmin_AdminIDSeq':name()),
+ ok.
+
+%%-----------------------------------------------------------------
+%% Test Case: 'CosNotifyChannelAdmin_ChannelIDSeq'
+%% Description:
+%%-----------------------------------------------------------------
+'CosNotifyChannelAdmin_ChannelIDSeq'(doc) -> ["CosNotifyChannelAdmin_ChannelIDSeq"];
+'CosNotifyChannelAdmin_ChannelIDSeq'(suite) -> [];
+'CosNotifyChannelAdmin_ChannelIDSeq'(_) ->
+ ?match(true, orber_tc:check_tc('CosNotifyChannelAdmin_ChannelIDSeq':tc())),
+ ?match("IDL:omg.org/CosNotifyChannelAdmin/ChannelIDSeq:1.0",
+ 'CosNotifyChannelAdmin_ChannelIDSeq':id()),
+ ?match("CosNotifyChannelAdmin_ChannelIDSeq",
+ 'CosNotifyChannelAdmin_ChannelIDSeq':name()),
+ ok.
+
+%%-----------------------------------------------------------------
+%% Test Case: 'CosNotifyChannelAdmin_ProxyIDSeq'
+%% Description:
+%%-----------------------------------------------------------------
+'CosNotifyChannelAdmin_ProxyIDSeq'(doc) -> ["CosNotifyChannelAdmin_ProxyIDSeq"];
+'CosNotifyChannelAdmin_ProxyIDSeq'(suite) -> [];
+'CosNotifyChannelAdmin_ProxyIDSeq'(_) ->
+ ?match(true, orber_tc:check_tc('CosNotifyChannelAdmin_ProxyIDSeq':tc())),
+ ?match("IDL:omg.org/CosNotifyChannelAdmin/ProxyIDSeq:1.0",
+ 'CosNotifyChannelAdmin_ProxyIDSeq':id()),
+ ?match("CosNotifyChannelAdmin_ProxyIDSeq",
+ 'CosNotifyChannelAdmin_ProxyIDSeq':name()),
+ ok.
+
+%%-----------------------------------------------------------------
+%% Test Case: 'CosNotifyFilter_CallbackNotFound'
+%% Description:
+%%-----------------------------------------------------------------
+'CosNotifyFilter_CallbackNotFound'(doc) -> ["CosNotifyFilter_CallbackNotFound"];
+'CosNotifyFilter_CallbackNotFound'(suite) -> [];
+'CosNotifyFilter_CallbackNotFound'(_) ->
+ ?match(true, orber_tc:check_tc('CosNotifyFilter_CallbackNotFound':tc())),
+ ?match("IDL:omg.org/CosNotifyFilter/CallbackNotFound:1.0",
+ 'CosNotifyFilter_CallbackNotFound':id()),
+ ?match("CosNotifyFilter_CallbackNotFound",
+ 'CosNotifyFilter_CallbackNotFound':name()),
+ ok.
+
+%%-----------------------------------------------------------------
+%% Test Case: 'CosNotifyFilter_ConstraintExp'
+%% Description:
+%%-----------------------------------------------------------------
+'CosNotifyFilter_ConstraintExp'(doc) -> ["CosNotifyFilter_ConstraintExp"];
+'CosNotifyFilter_ConstraintExp'(suite) -> [];
+'CosNotifyFilter_ConstraintExp'(_) ->
+ ?match(true, orber_tc:check_tc('CosNotifyFilter_ConstraintExp':tc())),
+ ?match("IDL:omg.org/CosNotifyFilter/ConstraintExp:1.0",
+ 'CosNotifyFilter_ConstraintExp':id()),
+ ?match("CosNotifyFilter_ConstraintExp",
+ 'CosNotifyFilter_ConstraintExp':name()),
+ ok.
+
+%%-----------------------------------------------------------------
+%% Test Case: 'CosNotifyFilter_ConstraintInfo'
+%% Description:
+%%-----------------------------------------------------------------
+'CosNotifyFilter_ConstraintInfo'(doc) -> ["CosNotifyFilter_ConstraintInfo"];
+'CosNotifyFilter_ConstraintInfo'(suite) -> [];
+'CosNotifyFilter_ConstraintInfo'(_) ->
+ ?match(true, orber_tc:check_tc('CosNotifyFilter_ConstraintInfo':tc())),
+ ?match("IDL:omg.org/CosNotifyFilter/ConstraintInfo:1.0",
+ 'CosNotifyFilter_ConstraintInfo':id()),
+ ?match("CosNotifyFilter_ConstraintInfo",
+ 'CosNotifyFilter_ConstraintInfo':name()),
+ ok.
+
+%%-----------------------------------------------------------------
+%% Test Case: 'CosNotifyFilter_ConstraintNotFound'
+%% Description:
+%%-----------------------------------------------------------------
+'CosNotifyFilter_ConstraintNotFound'(doc) -> ["CosNotifyFilter_ConstraintNotFound"];
+'CosNotifyFilter_ConstraintNotFound'(suite) -> [];
+'CosNotifyFilter_ConstraintNotFound'(_) ->
+ ?match(true, orber_tc:check_tc('CosNotifyFilter_ConstraintNotFound':tc())),
+ ?match("IDL:omg.org/CosNotifyFilter/ConstraintNotFound:1.0",
+ 'CosNotifyFilter_ConstraintNotFound':id()),
+ ?match("CosNotifyFilter_ConstraintNotFound",
+ 'CosNotifyFilter_ConstraintNotFound':name()),
+ ok.
+
+%%-----------------------------------------------------------------
+%% Test Case: 'CosNotifyFilter_DuplicateConstraintID'
+%% Description:
+%%-----------------------------------------------------------------
+'CosNotifyFilter_DuplicateConstraintID'(doc) -> ["CosNotifyFilter_DuplicateConstraintID"];
+'CosNotifyFilter_DuplicateConstraintID'(suite) -> [];
+'CosNotifyFilter_DuplicateConstraintID'(_) ->
+ ?match(true, orber_tc:check_tc('CosNotifyFilter_DuplicateConstraintID':tc())),
+ ?match("IDL:omg.org/CosNotifyFilter/DuplicateConstraintID:1.0",
+ 'CosNotifyFilter_DuplicateConstraintID':id()),
+ ?match("CosNotifyFilter_DuplicateConstraintID",
+ 'CosNotifyFilter_DuplicateConstraintID':name()),
+ ok.
+
+%%-----------------------------------------------------------------
+%% Test Case: 'CosNotifyFilter_FilterNotFound'
+%% Description:
+%%-----------------------------------------------------------------
+'CosNotifyFilter_FilterNotFound'(doc) -> ["CosNotifyFilter_FilterNotFound"];
+'CosNotifyFilter_FilterNotFound'(suite) -> [];
+'CosNotifyFilter_FilterNotFound'(_) ->
+ ?match(true, orber_tc:check_tc('CosNotifyFilter_FilterNotFound':tc())),
+ ?match("IDL:omg.org/CosNotifyFilter/FilterNotFound:1.0",
+ 'CosNotifyFilter_FilterNotFound':id()),
+ ?match("CosNotifyFilter_FilterNotFound",
+ 'CosNotifyFilter_FilterNotFound':name()),
+ ok.
+
+%%-----------------------------------------------------------------
+%% Test Case: 'CosNotifyFilter_InvalidConstraint'
+%% Description:
+%%-----------------------------------------------------------------
+'CosNotifyFilter_InvalidConstraint'(doc) -> ["CosNotifyFilter_InvalidConstraint"];
+'CosNotifyFilter_InvalidConstraint'(suite) -> [];
+'CosNotifyFilter_InvalidConstraint'(_) ->
+ ?match(true, orber_tc:check_tc('CosNotifyFilter_InvalidConstraint':tc())),
+ ?match("IDL:omg.org/CosNotifyFilter/InvalidConstraint:1.0",
+ 'CosNotifyFilter_InvalidConstraint':id()),
+ ?match("CosNotifyFilter_InvalidConstraint",
+ 'CosNotifyFilter_InvalidConstraint':name()),
+ ok.
+
+%%-----------------------------------------------------------------
+%% Test Case: 'CosNotifyFilter_InvalidGrammar'
+%% Description:
+%%-----------------------------------------------------------------
+'CosNotifyFilter_InvalidGrammar'(doc) -> ["CosNotifyFilter_InvalidGrammar"];
+'CosNotifyFilter_InvalidGrammar'(suite) -> [];
+'CosNotifyFilter_InvalidGrammar'(_) ->
+ ?match(true, orber_tc:check_tc('CosNotifyFilter_InvalidGrammar':tc())),
+ ?match("IDL:omg.org/CosNotifyFilter/InvalidGrammar:1.0",
+ 'CosNotifyFilter_InvalidGrammar':id()),
+ ?match("CosNotifyFilter_InvalidGrammar",
+ 'CosNotifyFilter_InvalidGrammar':name()),
+ ok.
+
+%%-----------------------------------------------------------------
+%% Test Case: 'CosNotifyFilter_InvalidValue'
+%% Description:
+%%-----------------------------------------------------------------
+'CosNotifyFilter_InvalidValue'(doc) -> ["CosNotifyFilter_InvalidValue"];
+'CosNotifyFilter_InvalidValue'(suite) -> [];
+'CosNotifyFilter_InvalidValue'(_) ->
+ ?match(true, orber_tc:check_tc('CosNotifyFilter_InvalidValue':tc())),
+ ?match("IDL:omg.org/CosNotifyFilter/InvalidValue:1.0",
+ 'CosNotifyFilter_InvalidValue':id()),
+ ?match("CosNotifyFilter_InvalidValue",
+ 'CosNotifyFilter_InvalidValue':name()),
+ ok.
+
+%%-----------------------------------------------------------------
+%% Test Case: 'CosNotifyFilter_MappingConstraintInfo'
+%% Description:
+%%-----------------------------------------------------------------
+'CosNotifyFilter_MappingConstraintInfo'(doc) -> ["CosNotifyFilter_MappingConstraintInfo"];
+'CosNotifyFilter_MappingConstraintInfo'(suite) -> [];
+'CosNotifyFilter_MappingConstraintInfo'(_) ->
+ ?match(true, orber_tc:check_tc('CosNotifyFilter_MappingConstraintInfo':tc())),
+ ?match("IDL:omg.org/CosNotifyFilter/MappingConstraintInfo:1.0",
+ 'CosNotifyFilter_MappingConstraintInfo':id()),
+ ?match("CosNotifyFilter_MappingConstraintInfo",
+ 'CosNotifyFilter_MappingConstraintInfo':name()),
+ ok.
+
+%%-----------------------------------------------------------------
+%% Test Case: 'CosNotifyFilter_MappingConstraintPair'
+%% Description:
+%%-----------------------------------------------------------------
+'CosNotifyFilter_MappingConstraintPair'(doc) -> ["CosNotifyFilter_MappingConstraintPair"];
+'CosNotifyFilter_MappingConstraintPair'(suite) -> [];
+'CosNotifyFilter_MappingConstraintPair'(_) ->
+ ?match(true, orber_tc:check_tc('CosNotifyFilter_MappingConstraintPair':tc())),
+ ?match("IDL:omg.org/CosNotifyFilter/MappingConstraintPair:1.0",
+ 'CosNotifyFilter_MappingConstraintPair':id()),
+ ?match("CosNotifyFilter_MappingConstraintPair",
+ 'CosNotifyFilter_MappingConstraintPair':name()),
+ ok.
+
+%%-----------------------------------------------------------------
+%% Test Case: 'CosNotifyFilter_UnsupportedFilterableData'
+%% Description:
+%%-----------------------------------------------------------------
+'CosNotifyFilter_UnsupportedFilterableData'(doc) -> ["CosNotifyFilter_UnsupportedFilterableData"];
+'CosNotifyFilter_UnsupportedFilterableData'(suite) -> [];
+'CosNotifyFilter_UnsupportedFilterableData'(_) ->
+ ?match(true, orber_tc:check_tc('CosNotifyFilter_UnsupportedFilterableData':tc())),
+ ?match("IDL:omg.org/CosNotifyFilter/UnsupportedFilterableData:1.0",
+ 'CosNotifyFilter_UnsupportedFilterableData':id()),
+ ?match("CosNotifyFilter_UnsupportedFilterableData",
+ 'CosNotifyFilter_UnsupportedFilterableData':name()),
+ ok.
+
+%%-----------------------------------------------------------------
+%% Test Case: 'CosNotifyFilter_CallbackIDSeq'
+%% Description:
+%%-----------------------------------------------------------------
+'CosNotifyFilter_CallbackIDSeq'(doc) -> ["CosNotifyFilter_CallbackIDSeq"];
+'CosNotifyFilter_CallbackIDSeq'(suite) -> [];
+'CosNotifyFilter_CallbackIDSeq'(_) ->
+ ?match(true, orber_tc:check_tc('CosNotifyFilter_CallbackIDSeq':tc())),
+ ?match("IDL:omg.org/CosNotifyFilter/CallbackIDSeq:1.0",
+ 'CosNotifyFilter_CallbackIDSeq':id()),
+ ?match("CosNotifyFilter_CallbackIDSeq",
+ 'CosNotifyFilter_CallbackIDSeq':name()),
+ ok.
+
+
+%%-----------------------------------------------------------------
+%% Test Case: 'CosNotifyFilter_ConstraintExpSeq'
+%% Description:
+%%-----------------------------------------------------------------
+'CosNotifyFilter_ConstraintExpSeq'(doc) -> ["CosNotifyFilter_ConstraintExpSeq"];
+'CosNotifyFilter_ConstraintExpSeq'(suite) -> [];
+'CosNotifyFilter_ConstraintExpSeq'(_) ->
+ ?match(true, orber_tc:check_tc('CosNotifyFilter_ConstraintExpSeq':tc())),
+ ?match("IDL:omg.org/CosNotifyFilter/ConstraintExpSeq:1.0",
+ 'CosNotifyFilter_ConstraintExpSeq':id()),
+ ?match("CosNotifyFilter_ConstraintExpSeq",
+ 'CosNotifyFilter_ConstraintExpSeq':name()),
+ ok.
+
+
+%%-----------------------------------------------------------------
+%% Test Case: 'CosNotifyFilter_ConstraintIDSeq'
+%% Description:
+%%-----------------------------------------------------------------
+'CosNotifyFilter_ConstraintIDSeq'(doc) -> ["CosNotifyFilter_ConstraintIDSeq"];
+'CosNotifyFilter_ConstraintIDSeq'(suite) -> [];
+'CosNotifyFilter_ConstraintIDSeq'(_) ->
+ ?match(true, orber_tc:check_tc('CosNotifyFilter_ConstraintIDSeq':tc())),
+ ?match("IDL:omg.org/CosNotifyFilter/ConstraintIDSeq:1.0",
+ 'CosNotifyFilter_ConstraintIDSeq':id()),
+ ?match("CosNotifyFilter_ConstraintIDSeq",
+ 'CosNotifyFilter_ConstraintIDSeq':name()),
+ ok.
+
+
+%%-----------------------------------------------------------------
+%% Test Case: 'CosNotifyFilter_ConstraintInfoSeq'
+%% Description:
+%%-----------------------------------------------------------------
+'CosNotifyFilter_ConstraintInfoSeq'(doc) -> ["CosNotifyFilter_ConstraintInfoSeq"];
+'CosNotifyFilter_ConstraintInfoSeq'(suite) -> [];
+'CosNotifyFilter_ConstraintInfoSeq'(_) ->
+ ?match(true, orber_tc:check_tc('CosNotifyFilter_ConstraintInfoSeq':tc())),
+ ?match("IDL:omg.org/CosNotifyFilter/ConstraintInfoSeq:1.0",
+ 'CosNotifyFilter_ConstraintInfoSeq':id()),
+ ?match("CosNotifyFilter_ConstraintInfoSeq",
+ 'CosNotifyFilter_ConstraintInfoSeq':name()),
+ ok.
+
+
+%%-----------------------------------------------------------------
+%% Test Case: 'CosNotifyFilter_FilterIDSeq'
+%% Description:
+%%-----------------------------------------------------------------
+'CosNotifyFilter_FilterIDSeq'(doc) -> ["CosNotifyFilter_FilterIDSeq"];
+'CosNotifyFilter_FilterIDSeq'(suite) -> [];
+'CosNotifyFilter_FilterIDSeq'(_) ->
+ ?match(true, orber_tc:check_tc('CosNotifyFilter_FilterIDSeq':tc())),
+ ?match("IDL:omg.org/CosNotifyFilter/FilterIDSeq:1.0",
+ 'CosNotifyFilter_FilterIDSeq':id()),
+ ?match("CosNotifyFilter_FilterIDSeq",
+ 'CosNotifyFilter_FilterIDSeq':name()),
+ ok.
+
+
+%%-----------------------------------------------------------------
+%% Test Case: 'CosNotifyFilter_MappingConstraintInfoSeq'
+%% Description:
+%%-----------------------------------------------------------------
+'CosNotifyFilter_MappingConstraintInfoSeq'(doc) -> ["CosNotifyFilter_MappingConstraintInfoSeq"];
+'CosNotifyFilter_MappingConstraintInfoSeq'(suite) -> [];
+'CosNotifyFilter_MappingConstraintInfoSeq'(_) ->
+ ?match(true, orber_tc:check_tc('CosNotifyFilter_MappingConstraintInfoSeq':tc())),
+ ?match("IDL:omg.org/CosNotifyFilter/MappingConstraintInfoSeq:1.0",
+ 'CosNotifyFilter_MappingConstraintInfoSeq':id()),
+ ?match("CosNotifyFilter_MappingConstraintInfoSeq",
+ 'CosNotifyFilter_MappingConstraintInfoSeq':name()),
+ ok.
+
+
+%%-----------------------------------------------------------------
+%% Test Case: 'CosNotifyFilter_MappingConstraintPairSeq'
+%% Description:
+%%-----------------------------------------------------------------
+'CosNotifyFilter_MappingConstraintPairSeq'(doc) -> ["CosNotifyFilter_MappingConstraintPairSeq"];
+'CosNotifyFilter_MappingConstraintPairSeq'(suite) -> [];
+'CosNotifyFilter_MappingConstraintPairSeq'(_) ->
+ ?match(true, orber_tc:check_tc('CosNotifyFilter_MappingConstraintPairSeq':tc())),
+ ?match("IDL:omg.org/CosNotifyFilter/MappingConstraintPairSeq:1.0",
+ 'CosNotifyFilter_MappingConstraintPairSeq':id()),
+ ?match("CosNotifyFilter_MappingConstraintPairSeq",
+ 'CosNotifyFilter_MappingConstraintPairSeq':name()),
+ ok.
+
+
+%%-----------------------------------------------------------------
+%% Test Case: 'CosNotifyComm_InvalidEventType'
+%% Description:
+%%-----------------------------------------------------------------
+'CosNotifyComm_InvalidEventType'(doc) -> ["CosNotifyComm_InvalidEventType"];
+'CosNotifyComm_InvalidEventType'(suite) -> [];
+'CosNotifyComm_InvalidEventType'(_) ->
+ ?match(true, orber_tc:check_tc('CosNotifyComm_InvalidEventType':tc())),
+ ?match("IDL:omg.org/CosNotifyComm/InvalidEventType:1.0",
+ 'CosNotifyComm_InvalidEventType':id()),
+ ?match("CosNotifyComm_InvalidEventType",
+ 'CosNotifyComm_InvalidEventType':name()),
+ ok.
+
+
+%%-----------------------------------------------------------------
+%% Test Case: 'CosNotifyChannelAdmin_ProxyNotFound'
+%% Description:
+%%-----------------------------------------------------------------
+'CosNotifyChannelAdmin_ProxyNotFound'(doc) -> ["CosNotifyChannelAdmin_ProxyNotFound"];
+'CosNotifyChannelAdmin_ProxyNotFound'(suite) -> [];
+'CosNotifyChannelAdmin_ProxyNotFound'(_) ->
+ ?match(true, orber_tc:check_tc('CosNotifyChannelAdmin_ProxyNotFound':tc())),
+ ?match("IDL:omg.org/CosNotifyChannelAdmin/ProxyNotFound:1.0",
+ 'CosNotifyChannelAdmin_ProxyNotFound':id()),
+ ?match("CosNotifyChannelAdmin_ProxyNotFound",
+ 'CosNotifyChannelAdmin_ProxyNotFound':name()),
+ ok.
+
+
+%%-----------------------------------------------------------------
+%% Test Case: 'CosNotification_AdminPropertiesAdmin'
+%% Description:
+%%-----------------------------------------------------------------
+'CosNotification_AdminPropertiesAdmin'(doc) -> ["CosNotification_AdminPropertiesAdmin"];
+'CosNotification_AdminPropertiesAdmin'(suite) -> [];
+'CosNotification_AdminPropertiesAdmin'(_) ->
+ ?nomatch(undefined, 'CosNotification_AdminPropertiesAdmin':oe_tc(get_admin)),
+ ?nomatch(undefined, 'CosNotification_AdminPropertiesAdmin':oe_tc(set_admin)),
+ ?match(undefined, 'CosNotification_AdminPropertiesAdmin':oe_tc(undefined)),
+ ?match([_|_], 'CosNotification_AdminPropertiesAdmin':oe_get_interface()),
+ ?match("IDL:omg.org/CosNotification/AdminPropertiesAdmin:1.0",
+ 'CosNotification_AdminPropertiesAdmin':typeID()),
+ check_tc('CosNotification_AdminPropertiesAdmin':oe_get_interface()),
+ ?match(true, 'CosNotification_AdminPropertiesAdmin':oe_is_a('CosNotification_AdminPropertiesAdmin':typeID())),
+ ?match(false, 'CosNotification_AdminPropertiesAdmin':oe_is_a("wrong")),
+ ok.
+
+%%-----------------------------------------------------------------
+%% Test Case: 'CosNotification_QoSAdmin'
+%% Description:
+%%-----------------------------------------------------------------
+'CosNotification_QoSAdmin'(doc) -> ["CosNotification_QoSAdmin"];
+'CosNotification_QoSAdmin'(suite) -> [];
+'CosNotification_QoSAdmin'(_) ->
+ ?nomatch(undefined, 'CosNotification_QoSAdmin':oe_tc(get_qos)),
+ ?nomatch(undefined, 'CosNotification_QoSAdmin':oe_tc(set_qos)),
+ ?nomatch(undefined, 'CosNotification_QoSAdmin':oe_tc(validate_qos)),
+ ?match(undefined, 'CosNotification_QoSAdmin':oe_tc(undefined)),
+ ?match([_|_], 'CosNotification_QoSAdmin':oe_get_interface()),
+ ?match("IDL:omg.org/CosNotification/QoSAdmin:1.0",
+ 'CosNotification_QoSAdmin':typeID()),
+ check_tc('CosNotification_QoSAdmin':oe_get_interface()),
+ ?match(true, 'CosNotification_QoSAdmin':oe_is_a('CosNotification_QoSAdmin':typeID())),
+ ?match(false, 'CosNotification_QoSAdmin':oe_is_a("wrong")),
+ ok.
+
+%%-----------------------------------------------------------------
+%% Test Case: 'CosNotifyChannelAdmin_ConsumerAdmin'
+%% Description:
+%%-----------------------------------------------------------------
+'CosNotifyChannelAdmin_ConsumerAdmin'(doc) -> ["CosNotifyChannelAdmin_ConsumerAdmin"];
+'CosNotifyChannelAdmin_ConsumerAdmin'(suite) -> [];
+'CosNotifyChannelAdmin_ConsumerAdmin'(_) ->
+ ?nomatch(undefined, 'CosNotifyChannelAdmin_ConsumerAdmin':oe_tc('_get_MyID')),
+ ?nomatch(undefined, 'CosNotifyChannelAdmin_ConsumerAdmin':oe_tc('_get_MyChannel')),
+ ?nomatch(undefined, 'CosNotifyChannelAdmin_ConsumerAdmin':oe_tc('_get_MyOperator')),
+ ?nomatch(undefined, 'CosNotifyChannelAdmin_ConsumerAdmin':oe_tc('_get_priority_filter')),
+ ?nomatch(undefined, 'CosNotifyChannelAdmin_ConsumerAdmin':oe_tc('_set_priority_filter')),
+ ?nomatch(undefined, 'CosNotifyChannelAdmin_ConsumerAdmin':oe_tc('_get_lifetime_filter')),
+ ?nomatch(undefined, 'CosNotifyChannelAdmin_ConsumerAdmin':oe_tc('_set_lifetime_filter')),
+ ?nomatch(undefined, 'CosNotifyChannelAdmin_ConsumerAdmin':oe_tc('_get_pull_suppliers')),
+ ?nomatch(undefined, 'CosNotifyChannelAdmin_ConsumerAdmin':oe_tc('_get_push_suppliers')),
+ ?nomatch(undefined, 'CosNotifyChannelAdmin_ConsumerAdmin':oe_tc(get_proxy_supplier)),
+ ?nomatch(undefined, 'CosNotifyChannelAdmin_ConsumerAdmin':oe_tc(obtain_notification_pull_supplier)),
+ ?nomatch(undefined, 'CosNotifyChannelAdmin_ConsumerAdmin':oe_tc(obtain_notification_push_supplier)),
+ ?nomatch(undefined, 'CosNotifyChannelAdmin_ConsumerAdmin':oe_tc(destroy)),
+ ?nomatch(undefined, 'CosNotifyChannelAdmin_ConsumerAdmin':oe_tc(get_qos)),
+ ?nomatch(undefined, 'CosNotifyChannelAdmin_ConsumerAdmin':oe_tc(set_qos)),
+ ?nomatch(undefined, 'CosNotifyChannelAdmin_ConsumerAdmin':oe_tc(validate_qos)),
+ ?nomatch(undefined, 'CosNotifyChannelAdmin_ConsumerAdmin':oe_tc(subscription_change)),
+ ?nomatch(undefined, 'CosNotifyChannelAdmin_ConsumerAdmin':oe_tc(add_filter)),
+ ?nomatch(undefined, 'CosNotifyChannelAdmin_ConsumerAdmin':oe_tc(remove_filter)),
+ ?nomatch(undefined, 'CosNotifyChannelAdmin_ConsumerAdmin':oe_tc(get_filter)),
+ ?nomatch(undefined, 'CosNotifyChannelAdmin_ConsumerAdmin':oe_tc(get_all_filters)),
+ ?nomatch(undefined, 'CosNotifyChannelAdmin_ConsumerAdmin':oe_tc(remove_all_filters)),
+ ?nomatch(undefined, 'CosNotifyChannelAdmin_ConsumerAdmin':oe_tc(obtain_push_supplier)),
+ ?nomatch(undefined, 'CosNotifyChannelAdmin_ConsumerAdmin':oe_tc(obtain_pull_supplier)),
+ ?nomatch(undefined, 'CosNotifyChannelAdmin_ConsumerAdmin':oe_tc(callSeq)),
+ ?nomatch(undefined, 'CosNotifyChannelAdmin_ConsumerAdmin':oe_tc(callAny)),
+ ?match(undefined, 'CosNotifyChannelAdmin_ConsumerAdmin':oe_tc(undefined)),
+ ?match([_|_], 'CosNotifyChannelAdmin_ConsumerAdmin':oe_get_interface()),
+ ?match("IDL:omg.org/CosNotifyChannelAdmin/ConsumerAdmin:1.0",
+ 'CosNotifyChannelAdmin_ConsumerAdmin':typeID()),
+ check_tc('CosNotifyChannelAdmin_ConsumerAdmin':oe_get_interface()),
+ ?match(true, 'CosNotifyChannelAdmin_ConsumerAdmin':oe_is_a('CosNotifyChannelAdmin_ConsumerAdmin':typeID())),
+ ?match(true, 'CosNotifyChannelAdmin_ConsumerAdmin':oe_is_a('CosNotification_QoSAdmin':typeID())),
+ ?match(true, 'CosNotifyChannelAdmin_ConsumerAdmin':oe_is_a('CosNotifyComm_NotifySubscribe':typeID())),
+ ?match(true, 'CosNotifyChannelAdmin_ConsumerAdmin':oe_is_a('CosNotifyFilter_FilterAdmin':typeID())),
+ ?match(true, 'CosNotifyChannelAdmin_ConsumerAdmin':oe_is_a('CosEventChannelAdmin_ConsumerAdmin':typeID())),
+ ?match(true, 'CosNotifyChannelAdmin_ConsumerAdmin':oe_is_a('oe_CosNotificationComm_Event':typeID())),
+ ?match(false, 'CosNotifyChannelAdmin_ConsumerAdmin':oe_is_a("wrong")),
+ ok.
+
+%%-----------------------------------------------------------------
+%% Test Case: 'CosNotifyChannelAdmin_EventChannel'
+%% Description:
+%%-----------------------------------------------------------------
+'CosNotifyChannelAdmin_EventChannel'(doc) -> ["CosNotifyChannelAdmin_EventChannel"];
+'CosNotifyChannelAdmin_EventChannel'(suite) -> [];
+'CosNotifyChannelAdmin_EventChannel'(_) ->
+ ?nomatch(undefined, 'CosNotifyChannelAdmin_EventChannel':oe_tc('_get_MyFactory')),
+ ?nomatch(undefined, 'CosNotifyChannelAdmin_EventChannel':oe_tc('_get_default_consumer_admin')),
+ ?nomatch(undefined, 'CosNotifyChannelAdmin_EventChannel':oe_tc('_get_default_supplier_admin')),
+ ?nomatch(undefined, 'CosNotifyChannelAdmin_EventChannel':oe_tc('_get_default_filter_factory')),
+ ?nomatch(undefined, 'CosNotifyChannelAdmin_EventChannel':oe_tc(new_for_consumers)),
+ ?nomatch(undefined, 'CosNotifyChannelAdmin_EventChannel':oe_tc(new_for_suppliers)),
+ ?nomatch(undefined, 'CosNotifyChannelAdmin_EventChannel':oe_tc(get_consumeradmin)),
+ ?nomatch(undefined, 'CosNotifyChannelAdmin_EventChannel':oe_tc(get_supplieradmin)),
+ ?nomatch(undefined, 'CosNotifyChannelAdmin_EventChannel':oe_tc(get_all_consumeradmins)),
+ ?nomatch(undefined, 'CosNotifyChannelAdmin_EventChannel':oe_tc(get_all_supplieradmins)),
+ ?nomatch(undefined, 'CosNotifyChannelAdmin_EventChannel':oe_tc(get_qos)),
+ ?nomatch(undefined, 'CosNotifyChannelAdmin_EventChannel':oe_tc(set_qos)),
+ ?nomatch(undefined, 'CosNotifyChannelAdmin_EventChannel':oe_tc(validate_qos)),
+ ?nomatch(undefined, 'CosNotifyChannelAdmin_EventChannel':oe_tc(get_admin)),
+ ?nomatch(undefined, 'CosNotifyChannelAdmin_EventChannel':oe_tc(set_admin)),
+ ?nomatch(undefined, 'CosNotifyChannelAdmin_EventChannel':oe_tc(for_consumers)),
+ ?nomatch(undefined, 'CosNotifyChannelAdmin_EventChannel':oe_tc(for_suppliers)),
+ ?nomatch(undefined, 'CosNotifyChannelAdmin_EventChannel':oe_tc(destroy)),
+ ?nomatch(undefined, 'CosNotifyChannelAdmin_EventChannel':oe_tc(callSeq)),
+ ?nomatch(undefined, 'CosNotifyChannelAdmin_EventChannel':oe_tc(callAny)),
+ ?match(undefined, 'CosNotifyChannelAdmin_EventChannel':oe_tc(undefined)),
+ ?match([_|_], 'CosNotifyChannelAdmin_EventChannel':oe_get_interface()),
+ ?match("IDL:omg.org/CosNotifyChannelAdmin/EventChannel:1.0",
+ 'CosNotifyChannelAdmin_EventChannel':typeID()),
+ check_tc('CosNotifyChannelAdmin_EventChannel':oe_get_interface()),
+ ?match(true, 'CosNotifyChannelAdmin_EventChannel':oe_is_a('CosNotifyChannelAdmin_EventChannel':typeID())),
+ ?match(true, 'CosNotifyChannelAdmin_EventChannel':oe_is_a('CosNotification_QoSAdmin':typeID())),
+ ?match(true, 'CosNotifyChannelAdmin_EventChannel':oe_is_a('CosNotification_AdminPropertiesAdmin':typeID())),
+ ?match(true, 'CosNotifyChannelAdmin_EventChannel':oe_is_a('CosEventChannelAdmin_EventChannel':typeID())),
+ ?match(true, 'CosNotifyChannelAdmin_EventChannel':oe_is_a('oe_CosNotificationComm_Event':typeID())),
+ ?match(false, 'CosNotifyChannelAdmin_EventChannel':oe_is_a("wrong")),
+ ok.
+
+%%-----------------------------------------------------------------
+%% Test Case: 'CosNotifyChannelAdmin_EventChannelFactory'
+%% Description:
+%%-----------------------------------------------------------------
+'CosNotifyChannelAdmin_EventChannelFactory'(doc) -> ["CosNotifyChannelAdmin_EventChannelFactory"];
+'CosNotifyChannelAdmin_EventChannelFactory'(suite) -> [];
+'CosNotifyChannelAdmin_EventChannelFactory'(_) ->
+ ?nomatch(undefined, 'CosNotifyChannelAdmin_EventChannelFactory':oe_tc(create_channel)),
+ ?nomatch(undefined, 'CosNotifyChannelAdmin_EventChannelFactory':oe_tc(get_all_channels)),
+ ?nomatch(undefined, 'CosNotifyChannelAdmin_EventChannelFactory':oe_tc(get_event_channel)),
+ ?match(undefined, 'CosNotifyChannelAdmin_EventChannelFactory':oe_tc(undefined)),
+ ?match([_|_], 'CosNotifyChannelAdmin_EventChannelFactory':oe_get_interface()),
+ ?match("IDL:omg.org/CosNotifyChannelAdmin/EventChannelFactory:1.0",
+ 'CosNotifyChannelAdmin_EventChannelFactory':typeID()),
+ check_tc('CosNotifyChannelAdmin_EventChannelFactory':oe_get_interface()),
+ ?match(true, 'CosNotifyChannelAdmin_EventChannelFactory':oe_is_a('CosNotifyChannelAdmin_EventChannelFactory':typeID())),
+ ?match(false, 'CosNotifyChannelAdmin_EventChannelFactory':oe_is_a("wrong")),
+ ok.
+
+%%-----------------------------------------------------------------
+%% Test Case: 'CosNotifyChannelAdmin_ProxyConsumer'
+%% Description:
+%%-----------------------------------------------------------------
+'CosNotifyChannelAdmin_ProxyConsumer'(doc) -> ["CosNotifyChannelAdmin_ProxyConsumer"];
+'CosNotifyChannelAdmin_ProxyConsumer'(suite) -> [];
+'CosNotifyChannelAdmin_ProxyConsumer'(_) ->
+ ?nomatch(undefined, 'CosNotifyChannelAdmin_ProxyConsumer':oe_tc('_get_MyType')),
+ ?nomatch(undefined, 'CosNotifyChannelAdmin_ProxyConsumer':oe_tc('_get_MyAdmin')),
+ ?nomatch(undefined, 'CosNotifyChannelAdmin_ProxyConsumer':oe_tc(obtain_subscription_types)),
+ ?nomatch(undefined, 'CosNotifyChannelAdmin_ProxyConsumer':oe_tc(validate_event_qos)),
+ ?nomatch(undefined, 'CosNotifyChannelAdmin_ProxyConsumer':oe_tc(get_qos)),
+ ?nomatch(undefined, 'CosNotifyChannelAdmin_ProxyConsumer':oe_tc(set_qos)),
+ ?nomatch(undefined, 'CosNotifyChannelAdmin_ProxyConsumer':oe_tc(validate_qos)),
+ ?nomatch(undefined, 'CosNotifyChannelAdmin_ProxyConsumer':oe_tc(add_filter)),
+ ?nomatch(undefined, 'CosNotifyChannelAdmin_ProxyConsumer':oe_tc(remove_filter)),
+ ?nomatch(undefined, 'CosNotifyChannelAdmin_ProxyConsumer':oe_tc(get_filter)),
+ ?nomatch(undefined, 'CosNotifyChannelAdmin_ProxyConsumer':oe_tc(get_all_filters)),
+ ?nomatch(undefined, 'CosNotifyChannelAdmin_ProxyConsumer':oe_tc(remove_all_filters)),
+ ?match(undefined, 'CosNotifyChannelAdmin_ProxyConsumer':oe_tc(undefined)),
+ ?match([_|_], 'CosNotifyChannelAdmin_ProxyConsumer':oe_get_interface()),
+ ?match("IDL:omg.org/CosNotifyChannelAdmin/ProxyConsumer:1.0",
+ 'CosNotifyChannelAdmin_ProxyConsumer':typeID()),
+ check_tc('CosNotifyChannelAdmin_ProxyConsumer':oe_get_interface()),
+ ?match(true, 'CosNotifyChannelAdmin_ProxyConsumer':oe_is_a('CosNotifyChannelAdmin_ProxyConsumer':typeID())),
+ ?match(true, 'CosNotifyChannelAdmin_ProxyConsumer':oe_is_a('CosNotification_QoSAdmin':typeID())),
+ ?match(true, 'CosNotifyChannelAdmin_ProxyConsumer':oe_is_a('CosNotifyFilter_FilterAdmin':typeID())),
+ ?match(false, 'CosNotifyChannelAdmin_ProxyConsumer':oe_is_a("wrong")),
+ ok.
+
+%%-----------------------------------------------------------------
+%% Test Case: 'CosNotifyChannelAdmin_ProxyPullConsumer'
+%% Description:
+%%-----------------------------------------------------------------
+'CosNotifyChannelAdmin_ProxyPullConsumer'(doc) -> ["CosNotifyChannelAdmin_ProxyPullConsumer"];
+'CosNotifyChannelAdmin_ProxyPullConsumer'(suite) -> [];
+'CosNotifyChannelAdmin_ProxyPullConsumer'(_) ->
+ ?nomatch(undefined, 'CosNotifyChannelAdmin_ProxyPullConsumer':oe_tc(connect_any_pull_supplier)),
+ ?nomatch(undefined, 'CosNotifyChannelAdmin_ProxyPullConsumer':oe_tc(suspend_connection)),
+ ?nomatch(undefined, 'CosNotifyChannelAdmin_ProxyPullConsumer':oe_tc(resume_connection)),
+ ?nomatch(undefined, 'CosNotifyChannelAdmin_ProxyPullConsumer':oe_tc('_get_MyType')),
+ ?nomatch(undefined, 'CosNotifyChannelAdmin_ProxyPullConsumer':oe_tc('_get_MyAdmin')),
+ ?nomatch(undefined, 'CosNotifyChannelAdmin_ProxyPullConsumer':oe_tc(obtain_subscription_types)),
+ ?nomatch(undefined, 'CosNotifyChannelAdmin_ProxyPullConsumer':oe_tc(validate_event_qos)),
+ ?nomatch(undefined, 'CosNotifyChannelAdmin_ProxyPullConsumer':oe_tc(get_qos)),
+ ?nomatch(undefined, 'CosNotifyChannelAdmin_ProxyPullConsumer':oe_tc(set_qos)),
+ ?nomatch(undefined, 'CosNotifyChannelAdmin_ProxyPullConsumer':oe_tc(validate_qos)),
+ ?nomatch(undefined, 'CosNotifyChannelAdmin_ProxyPullConsumer':oe_tc(add_filter)),
+ ?nomatch(undefined, 'CosNotifyChannelAdmin_ProxyPullConsumer':oe_tc(remove_filter)),
+ ?nomatch(undefined, 'CosNotifyChannelAdmin_ProxyPullConsumer':oe_tc(get_filter)),
+ ?nomatch(undefined, 'CosNotifyChannelAdmin_ProxyPullConsumer':oe_tc(get_all_filters)),
+ ?nomatch(undefined, 'CosNotifyChannelAdmin_ProxyPullConsumer':oe_tc(remove_all_filters)),
+ ?nomatch(undefined, 'CosNotifyChannelAdmin_ProxyPullConsumer':oe_tc(offer_change)),
+ ?nomatch(undefined, 'CosNotifyChannelAdmin_ProxyPullConsumer':oe_tc(disconnect_pull_consumer)),
+ ?nomatch(undefined, 'CosNotifyChannelAdmin_ProxyPullConsumer':oe_tc(connect_pull_supplier)),
+ ?match(undefined, 'CosNotifyChannelAdmin_ProxyPullConsumer':oe_tc(undefined)),
+ ?match([_|_], 'CosNotifyChannelAdmin_ProxyPullConsumer':oe_get_interface()),
+ ?match("IDL:omg.org/CosNotifyChannelAdmin/ProxyPullConsumer:1.0",
+ 'CosNotifyChannelAdmin_ProxyPullConsumer':typeID()),
+ check_tc('CosNotifyChannelAdmin_ProxyPullConsumer':oe_get_interface()),
+ ?match(true, 'CosNotifyChannelAdmin_ProxyPullConsumer':oe_is_a('CosNotifyChannelAdmin_ProxyPullConsumer':typeID())),
+ ?match(true, 'CosNotifyChannelAdmin_ProxyPullConsumer':oe_is_a('CosNotifyChannelAdmin_ProxyConsumer':typeID())),
+ ?match(true, 'CosNotifyChannelAdmin_ProxyPullConsumer':oe_is_a('CosNotification_QoSAdmin':typeID())),
+ ?match(true, 'CosNotifyChannelAdmin_ProxyPullConsumer':oe_is_a('CosNotifyFilter_FilterAdmin':typeID())),
+ ?match(true, 'CosNotifyChannelAdmin_ProxyPullConsumer':oe_is_a('CosNotifyComm_PullConsumer':typeID())),
+ ?match(true, 'CosNotifyChannelAdmin_ProxyPullConsumer':oe_is_a('CosNotifyComm_NotifyPublish':typeID())),
+ ?match(true, 'CosNotifyChannelAdmin_ProxyPullConsumer':oe_is_a('CosEventComm_PullConsumer':typeID())),
+ ?match(true, 'CosNotifyChannelAdmin_ProxyPullConsumer':oe_is_a('CosEventChannelAdmin_ProxyPullConsumer':typeID())),
+ ?match(false, 'CosNotifyChannelAdmin_ProxyPullConsumer':oe_is_a("wrong")),
+ ok.
+
+%%-----------------------------------------------------------------
+%% Test Case: 'CosNotifyChannelAdmin_ProxyPullSupplier'
+%% Description:
+%%-----------------------------------------------------------------
+'CosNotifyChannelAdmin_ProxyPullSupplier'(doc) -> ["CosNotifyChannelAdmin_ProxyPullSupplier"];
+'CosNotifyChannelAdmin_ProxyPullSupplier'(suite) -> [];
+'CosNotifyChannelAdmin_ProxyPullSupplier'(_) ->
+ ?nomatch(undefined, 'CosNotifyChannelAdmin_ProxyPullSupplier':oe_tc('_get_MyType')),
+ ?nomatch(undefined, 'CosNotifyChannelAdmin_ProxyPullSupplier':oe_tc('_get_MyAdmin')),
+ ?nomatch(undefined, 'CosNotifyChannelAdmin_ProxyPullSupplier':oe_tc('_get_priority_filter')),
+ ?nomatch(undefined, 'CosNotifyChannelAdmin_ProxyPullSupplier':oe_tc('_set_priority_filter')),
+ ?nomatch(undefined, 'CosNotifyChannelAdmin_ProxyPullSupplier':oe_tc('_get_lifetime_filter')),
+ ?nomatch(undefined, 'CosNotifyChannelAdmin_ProxyPullSupplier':oe_tc('_set_lifetime_filter')),
+ ?nomatch(undefined, 'CosNotifyChannelAdmin_ProxyPullSupplier':oe_tc(obtain_offered_types)),
+ ?nomatch(undefined, 'CosNotifyChannelAdmin_ProxyPullSupplier':oe_tc(validate_event_qos)),
+ ?nomatch(undefined, 'CosNotifyChannelAdmin_ProxyPullSupplier':oe_tc(get_qos)),
+ ?nomatch(undefined, 'CosNotifyChannelAdmin_ProxyPullSupplier':oe_tc(set_qos)),
+ ?nomatch(undefined, 'CosNotifyChannelAdmin_ProxyPullSupplier':oe_tc(validate_qos)),
+ ?nomatch(undefined, 'CosNotifyChannelAdmin_ProxyPullSupplier':oe_tc(add_filter)),
+ ?nomatch(undefined, 'CosNotifyChannelAdmin_ProxyPullSupplier':oe_tc(remove_filter)),
+ ?nomatch(undefined, 'CosNotifyChannelAdmin_ProxyPullSupplier':oe_tc(get_filter)),
+ ?nomatch(undefined, 'CosNotifyChannelAdmin_ProxyPullSupplier':oe_tc(get_all_filters)),
+ ?nomatch(undefined, 'CosNotifyChannelAdmin_ProxyPullSupplier':oe_tc(remove_all_filters)),
+ ?nomatch(undefined, 'CosNotifyChannelAdmin_ProxyPullSupplier':oe_tc(subscription_change)),
+ ?nomatch(undefined, 'CosNotifyChannelAdmin_ProxyPullSupplier':oe_tc(pull)),
+ ?nomatch(undefined, 'CosNotifyChannelAdmin_ProxyPullSupplier':oe_tc(try_pull)),
+ ?nomatch(undefined, 'CosNotifyChannelAdmin_ProxyPullSupplier':oe_tc(disconnect_pull_supplier)),
+ ?nomatch(undefined, 'CosNotifyChannelAdmin_ProxyPullSupplier':oe_tc(connect_pull_consumer)),
+ ?nomatch(undefined, 'CosNotifyChannelAdmin_ProxyPullSupplier':oe_tc(callSeq)),
+ ?nomatch(undefined, 'CosNotifyChannelAdmin_ProxyPullSupplier':oe_tc(callAny)),
+ ?match(undefined, 'CosNotifyChannelAdmin_ProxyPullSupplier':oe_tc(undefined)),
+ ?match([_|_], 'CosNotifyChannelAdmin_ProxyPullSupplier':oe_get_interface()),
+ ?match("IDL:omg.org/CosNotifyChannelAdmin/ProxyPullSupplier:1.0",
+ 'CosNotifyChannelAdmin_ProxyPullSupplier':typeID()),
+ check_tc('CosNotifyChannelAdmin_ProxyPullSupplier':oe_get_interface()),
+ ?match(true, 'CosNotifyChannelAdmin_ProxyPullSupplier':oe_is_a('CosNotifyChannelAdmin_ProxyPullSupplier':typeID())),
+ ?match(true, 'CosNotifyChannelAdmin_ProxyPullSupplier':oe_is_a('CosNotifyChannelAdmin_ProxySupplier':typeID())),
+ ?match(true, 'CosNotifyChannelAdmin_ProxyPullSupplier':oe_is_a('CosNotification_QoSAdmin':typeID())),
+ ?match(true, 'CosNotifyChannelAdmin_ProxyPullSupplier':oe_is_a('CosNotifyFilter_FilterAdmin':typeID())),
+ ?match(true, 'CosNotifyChannelAdmin_ProxyPullSupplier':oe_is_a('CosNotifyComm_PullSupplier':typeID())),
+ ?match(true, 'CosNotifyChannelAdmin_ProxyPullSupplier':oe_is_a('CosNotifyComm_NotifySubscribe':typeID())),
+ ?match(true, 'CosNotifyChannelAdmin_ProxyPullSupplier':oe_is_a('CosEventComm_PullSupplier':typeID())),
+ ?match(true, 'CosNotifyChannelAdmin_ProxyPullSupplier':oe_is_a('CosEventChannelAdmin_ProxyPullSupplier':typeID())),
+ ?match(true, 'CosNotifyChannelAdmin_ProxyPullSupplier':oe_is_a('oe_CosNotificationComm_Event':typeID())),
+ ?match(false, 'CosNotifyChannelAdmin_ProxyPullSupplier':oe_is_a("wrong")),
+ ok.
+
+%%-----------------------------------------------------------------
+%% Test Case: 'CosNotifyChannelAdmin_ProxyPushConsumer'
+%% Description:
+%%-----------------------------------------------------------------
+'CosNotifyChannelAdmin_ProxyPushConsumer'(doc) -> ["CosNotifyChannelAdmin_ProxyPushConsumer"];
+'CosNotifyChannelAdmin_ProxyPushConsumer'(suite) -> [];
+'CosNotifyChannelAdmin_ProxyPushConsumer'(_) ->
+ ?nomatch(undefined, 'CosNotifyChannelAdmin_ProxyPushConsumer':oe_tc(connect_any_push_supplier)),
+ ?nomatch(undefined, 'CosNotifyChannelAdmin_ProxyPushConsumer':oe_tc('_get_MyType')),
+ ?nomatch(undefined, 'CosNotifyChannelAdmin_ProxyPushConsumer':oe_tc('_get_MyAdmin')),
+ ?nomatch(undefined, 'CosNotifyChannelAdmin_ProxyPushConsumer':oe_tc(obtain_subscription_types)),
+ ?nomatch(undefined, 'CosNotifyChannelAdmin_ProxyPushConsumer':oe_tc(validate_event_qos)),
+ ?nomatch(undefined, 'CosNotifyChannelAdmin_ProxyPushConsumer':oe_tc(get_qos)),
+ ?nomatch(undefined, 'CosNotifyChannelAdmin_ProxyPushConsumer':oe_tc(set_qos)),
+ ?nomatch(undefined, 'CosNotifyChannelAdmin_ProxyPushConsumer':oe_tc(validate_qos)),
+ ?nomatch(undefined, 'CosNotifyChannelAdmin_ProxyPushConsumer':oe_tc(add_filter)),
+ ?nomatch(undefined, 'CosNotifyChannelAdmin_ProxyPushConsumer':oe_tc(remove_filter)),
+ ?nomatch(undefined, 'CosNotifyChannelAdmin_ProxyPushConsumer':oe_tc(get_filter)),
+ ?nomatch(undefined, 'CosNotifyChannelAdmin_ProxyPushConsumer':oe_tc(get_all_filters)),
+ ?nomatch(undefined, 'CosNotifyChannelAdmin_ProxyPushConsumer':oe_tc(remove_all_filters)),
+ ?nomatch(undefined, 'CosNotifyChannelAdmin_ProxyPushConsumer':oe_tc(offer_change)),
+ ?nomatch(undefined, 'CosNotifyChannelAdmin_ProxyPushConsumer':oe_tc(push)),
+ ?nomatch(undefined, 'CosNotifyChannelAdmin_ProxyPushConsumer':oe_tc(disconnect_push_consumer)),
+ ?nomatch(undefined, 'CosNotifyChannelAdmin_ProxyPushConsumer':oe_tc(connect_push_supplier)),
+ ?match(undefined, 'CosNotifyChannelAdmin_ProxyPushConsumer':oe_tc(undefined)),
+ ?match([_|_], 'CosNotifyChannelAdmin_ProxyPushConsumer':oe_get_interface()),
+ ?match("IDL:omg.org/CosNotifyChannelAdmin/ProxyPushConsumer:1.0",
+ 'CosNotifyChannelAdmin_ProxyPushConsumer':typeID()),
+ check_tc('CosNotifyChannelAdmin_ProxyPushConsumer':oe_get_interface()),
+ ?match(true, 'CosNotifyChannelAdmin_ProxyPushConsumer':oe_is_a('CosNotifyChannelAdmin_ProxyPushConsumer':typeID())),
+ ?match(true, 'CosNotifyChannelAdmin_ProxyPushConsumer':oe_is_a('CosNotifyChannelAdmin_ProxyConsumer':typeID())),
+ ?match(true, 'CosNotifyChannelAdmin_ProxyPushConsumer':oe_is_a('CosNotification_QoSAdmin':typeID())),
+ ?match(true, 'CosNotifyChannelAdmin_ProxyPushConsumer':oe_is_a('CosNotifyFilter_FilterAdmin':typeID())),
+ ?match(true, 'CosNotifyChannelAdmin_ProxyPushConsumer':oe_is_a('CosNotifyComm_PushConsumer':typeID())),
+ ?match(true, 'CosNotifyChannelAdmin_ProxyPushConsumer':oe_is_a('CosNotifyComm_NotifyPublish':typeID())),
+ ?match(true, 'CosNotifyChannelAdmin_ProxyPushConsumer':oe_is_a('CosEventComm_PushConsumer':typeID())),
+ ?match(true, 'CosNotifyChannelAdmin_ProxyPushConsumer':oe_is_a('CosEventChannelAdmin_ProxyPushConsumer':typeID())),
+ ?match(false, 'CosNotifyChannelAdmin_ProxyPushConsumer':oe_is_a("wrong")),
+ ok.
+
+%%-----------------------------------------------------------------
+%% Test Case: 'CosNotifyChannelAdmin_ProxyPushSupplier'
+%% Description:
+%%-----------------------------------------------------------------
+'CosNotifyChannelAdmin_ProxyPushSupplier'(doc) -> ["CosNotifyChannelAdmin_ProxyPushSupplier"];
+'CosNotifyChannelAdmin_ProxyPushSupplier'(suite) -> [];
+'CosNotifyChannelAdmin_ProxyPushSupplier'(_) ->
+ ?nomatch(undefined, 'CosNotifyChannelAdmin_ProxyPushSupplier':oe_tc(connect_any_push_consumer)),
+ ?nomatch(undefined, 'CosNotifyChannelAdmin_ProxyPushSupplier':oe_tc(suspend_connection)),
+ ?nomatch(undefined, 'CosNotifyChannelAdmin_ProxyPushSupplier':oe_tc(resume_connection)),
+ ?nomatch(undefined, 'CosNotifyChannelAdmin_ProxyPushSupplier':oe_tc('_get_MyType')),
+ ?nomatch(undefined, 'CosNotifyChannelAdmin_ProxyPushSupplier':oe_tc('_get_MyAdmin')),
+ ?nomatch(undefined, 'CosNotifyChannelAdmin_ProxyPushSupplier':oe_tc('_get_priority_filter')),
+ ?nomatch(undefined, 'CosNotifyChannelAdmin_ProxyPushSupplier':oe_tc('_set_priority_filter')),
+ ?nomatch(undefined, 'CosNotifyChannelAdmin_ProxyPushSupplier':oe_tc('_get_lifetime_filter')),
+ ?nomatch(undefined, 'CosNotifyChannelAdmin_ProxyPushSupplier':oe_tc('_set_lifetime_filter')),
+ ?nomatch(undefined, 'CosNotifyChannelAdmin_ProxyPushSupplier':oe_tc(obtain_offered_types)),
+ ?nomatch(undefined, 'CosNotifyChannelAdmin_ProxyPushSupplier':oe_tc(validate_event_qos)),
+ ?nomatch(undefined, 'CosNotifyChannelAdmin_ProxyPushSupplier':oe_tc(get_qos)),
+ ?nomatch(undefined, 'CosNotifyChannelAdmin_ProxyPushSupplier':oe_tc(set_qos)),
+ ?nomatch(undefined, 'CosNotifyChannelAdmin_ProxyPushSupplier':oe_tc(validate_qos)),
+ ?nomatch(undefined, 'CosNotifyChannelAdmin_ProxyPushSupplier':oe_tc(add_filter)),
+ ?nomatch(undefined, 'CosNotifyChannelAdmin_ProxyPushSupplier':oe_tc(remove_filter)),
+ ?nomatch(undefined, 'CosNotifyChannelAdmin_ProxyPushSupplier':oe_tc(get_filter)),
+ ?nomatch(undefined, 'CosNotifyChannelAdmin_ProxyPushSupplier':oe_tc(get_all_filters)),
+ ?nomatch(undefined, 'CosNotifyChannelAdmin_ProxyPushSupplier':oe_tc(remove_all_filters)),
+ ?nomatch(undefined, 'CosNotifyChannelAdmin_ProxyPushSupplier':oe_tc(subscription_change)),
+ ?nomatch(undefined, 'CosNotifyChannelAdmin_ProxyPushSupplier':oe_tc(disconnect_push_supplier)),
+ ?nomatch(undefined, 'CosNotifyChannelAdmin_ProxyPushSupplier':oe_tc(connect_push_consumer)),
+ ?nomatch(undefined, 'CosNotifyChannelAdmin_ProxyPushSupplier':oe_tc(callSeq)),
+ ?nomatch(undefined, 'CosNotifyChannelAdmin_ProxyPushSupplier':oe_tc(callAny)),
+ ?match(undefined, 'CosNotifyChannelAdmin_ProxyPushSupplier':oe_tc(undefined)),
+ ?match([_|_], 'CosNotifyChannelAdmin_ProxyPushSupplier':oe_get_interface()),
+ ?match("IDL:omg.org/CosNotifyChannelAdmin/ProxyPushSupplier:1.0",
+ 'CosNotifyChannelAdmin_ProxyPushSupplier':typeID()),
+ check_tc('CosNotifyChannelAdmin_ProxyPushSupplier':oe_get_interface()),
+ ?match(true, 'CosNotifyChannelAdmin_ProxyPushSupplier':oe_is_a('CosNotifyChannelAdmin_ProxyPushSupplier':typeID())),
+ ?match(true, 'CosNotifyChannelAdmin_ProxyPushSupplier':oe_is_a('CosNotifyChannelAdmin_ProxySupplier':typeID())),
+ ?match(true, 'CosNotifyChannelAdmin_ProxyPushSupplier':oe_is_a('CosNotification_QoSAdmin':typeID())),
+ ?match(true, 'CosNotifyChannelAdmin_ProxyPushSupplier':oe_is_a('CosNotifyFilter_FilterAdmin':typeID())),
+ ?match(true, 'CosNotifyChannelAdmin_ProxyPushSupplier':oe_is_a('CosNotifyComm_PushSupplier':typeID())),
+ ?match(true, 'CosNotifyChannelAdmin_ProxyPushSupplier':oe_is_a('CosNotifyComm_NotifySubscribe':typeID())),
+ ?match(true, 'CosNotifyChannelAdmin_ProxyPushSupplier':oe_is_a('CosEventComm_PushSupplier':typeID())),
+ ?match(true, 'CosNotifyChannelAdmin_ProxyPushSupplier':oe_is_a('CosEventChannelAdmin_ProxyPushSupplier':typeID())),
+ ?match(true, 'CosNotifyChannelAdmin_ProxyPushSupplier':oe_is_a('oe_CosNotificationComm_Event':typeID())),
+ ?match(false, 'CosNotifyChannelAdmin_ProxyPushSupplier':oe_is_a("wrong")),
+ ok.
+
+%%-----------------------------------------------------------------
+%% Test Case: 'CosNotifyChannelAdmin_ProxySupplier'
+%% Description:
+%%-----------------------------------------------------------------
+'CosNotifyChannelAdmin_ProxySupplier'(doc) -> ["CosNotifyChannelAdmin_ProxySupplier"];
+'CosNotifyChannelAdmin_ProxySupplier'(suite) -> [];
+'CosNotifyChannelAdmin_ProxySupplier'(_) ->
+ ?nomatch(undefined, 'CosNotifyChannelAdmin_ProxySupplier':oe_tc('_get_MyType')),
+ ?nomatch(undefined, 'CosNotifyChannelAdmin_ProxySupplier':oe_tc('_get_MyAdmin')),
+ ?nomatch(undefined, 'CosNotifyChannelAdmin_ProxySupplier':oe_tc('_get_priority_filter')),
+ ?nomatch(undefined, 'CosNotifyChannelAdmin_ProxySupplier':oe_tc('_set_priority_filter')),
+ ?nomatch(undefined, 'CosNotifyChannelAdmin_ProxySupplier':oe_tc('_get_lifetime_filter')),
+ ?nomatch(undefined, 'CosNotifyChannelAdmin_ProxySupplier':oe_tc('_set_lifetime_filter')),
+ ?nomatch(undefined, 'CosNotifyChannelAdmin_ProxySupplier':oe_tc(obtain_offered_types)),
+ ?nomatch(undefined, 'CosNotifyChannelAdmin_ProxySupplier':oe_tc(validate_event_qos)),
+ ?nomatch(undefined, 'CosNotifyChannelAdmin_ProxySupplier':oe_tc(get_qos)),
+ ?nomatch(undefined, 'CosNotifyChannelAdmin_ProxySupplier':oe_tc(set_qos)),
+ ?nomatch(undefined, 'CosNotifyChannelAdmin_ProxySupplier':oe_tc(validate_qos)),
+ ?nomatch(undefined, 'CosNotifyChannelAdmin_ProxySupplier':oe_tc(add_filter)),
+ ?nomatch(undefined, 'CosNotifyChannelAdmin_ProxySupplier':oe_tc(remove_filter)),
+ ?nomatch(undefined, 'CosNotifyChannelAdmin_ProxySupplier':oe_tc(get_filter)),
+ ?nomatch(undefined, 'CosNotifyChannelAdmin_ProxySupplier':oe_tc(get_all_filters)),
+ ?nomatch(undefined, 'CosNotifyChannelAdmin_ProxySupplier':oe_tc(remove_all_filters)),
+ ?match(undefined, 'CosNotifyChannelAdmin_ProxySupplier':oe_tc(undefined)),
+ ?match([_|_], 'CosNotifyChannelAdmin_ProxySupplier':oe_get_interface()),
+ ?match("IDL:omg.org/CosNotifyChannelAdmin/ProxySupplier:1.0",
+ 'CosNotifyChannelAdmin_ProxySupplier':typeID()),
+ check_tc('CosNotifyChannelAdmin_ProxySupplier':oe_get_interface()),
+ ?match(true, 'CosNotifyChannelAdmin_ProxySupplier':oe_is_a('CosNotifyChannelAdmin_ProxySupplier':typeID())),
+ ?match(true, 'CosNotifyChannelAdmin_ProxySupplier':oe_is_a('CosNotification_QoSAdmin':typeID())),
+ ?match(true, 'CosNotifyChannelAdmin_ProxySupplier':oe_is_a('CosNotifyFilter_FilterAdmin':typeID())),
+ ?match(false, 'CosNotifyChannelAdmin_ProxySupplier':oe_is_a("wrong")),
+ ok.
+
+
+%%-----------------------------------------------------------------
+%% Test Case: 'CosNotifyChannelAdmin_SequenceProxyPullConsumer'
+%% Description:
+%%-----------------------------------------------------------------
+'CosNotifyChannelAdmin_SequenceProxyPullConsumer'(doc) -> ["CosNotifyChannelAdmin_SequenceProxyPullConsumer"];
+'CosNotifyChannelAdmin_SequenceProxyPullConsumer'(suite) -> [];
+'CosNotifyChannelAdmin_SequenceProxyPullConsumer'(_) ->
+ ?nomatch(undefined, 'CosNotifyChannelAdmin_SequenceProxyPullConsumer':oe_tc(connect_sequence_pull_supplier)),
+ ?nomatch(undefined, 'CosNotifyChannelAdmin_SequenceProxyPullConsumer':oe_tc(suspend_connection)),
+ ?nomatch(undefined, 'CosNotifyChannelAdmin_SequenceProxyPullConsumer':oe_tc(resume_connection)),
+ ?nomatch(undefined, 'CosNotifyChannelAdmin_SequenceProxyPullConsumer':oe_tc('_get_MyType')),
+ ?nomatch(undefined, 'CosNotifyChannelAdmin_SequenceProxyPullConsumer':oe_tc('_get_MyAdmin')),
+ ?nomatch(undefined, 'CosNotifyChannelAdmin_SequenceProxyPullConsumer':oe_tc(obtain_subscription_types)),
+ ?nomatch(undefined, 'CosNotifyChannelAdmin_SequenceProxyPullConsumer':oe_tc(validate_event_qos)),
+ ?nomatch(undefined, 'CosNotifyChannelAdmin_SequenceProxyPullConsumer':oe_tc(get_qos)),
+ ?nomatch(undefined, 'CosNotifyChannelAdmin_SequenceProxyPullConsumer':oe_tc(set_qos)),
+ ?nomatch(undefined, 'CosNotifyChannelAdmin_SequenceProxyPullConsumer':oe_tc(validate_qos)),
+ ?nomatch(undefined, 'CosNotifyChannelAdmin_SequenceProxyPullConsumer':oe_tc(add_filter)),
+ ?nomatch(undefined, 'CosNotifyChannelAdmin_SequenceProxyPullConsumer':oe_tc(remove_filter)),
+ ?nomatch(undefined, 'CosNotifyChannelAdmin_SequenceProxyPullConsumer':oe_tc(get_filter)),
+ ?nomatch(undefined, 'CosNotifyChannelAdmin_SequenceProxyPullConsumer':oe_tc(get_all_filters)),
+ ?nomatch(undefined, 'CosNotifyChannelAdmin_SequenceProxyPullConsumer':oe_tc(remove_all_filters)),
+ ?nomatch(undefined, 'CosNotifyChannelAdmin_SequenceProxyPullConsumer':oe_tc(disconnect_sequence_pull_consumer)),
+ ?nomatch(undefined, 'CosNotifyChannelAdmin_SequenceProxyPullConsumer':oe_tc(offer_change)),
+ ?match(undefined, 'CosNotifyChannelAdmin_SequenceProxyPullConsumer':oe_tc(undefined)),
+ ?match([_|_], 'CosNotifyChannelAdmin_SequenceProxyPullConsumer':oe_get_interface()),
+ ?match("IDL:omg.org/CosNotifyChannelAdmin/SequenceProxyPullConsumer:1.0",
+ 'CosNotifyChannelAdmin_SequenceProxyPullConsumer':typeID()),
+ check_tc('CosNotifyChannelAdmin_SequenceProxyPullConsumer':oe_get_interface()),
+ ?match(true, 'CosNotifyChannelAdmin_SequenceProxyPullConsumer':oe_is_a('CosNotifyChannelAdmin_SequenceProxyPullConsumer':typeID())),
+ ?match(true, 'CosNotifyChannelAdmin_SequenceProxyPullConsumer':oe_is_a('CosNotifyChannelAdmin_ProxyConsumer':typeID())),
+ ?match(true, 'CosNotifyChannelAdmin_SequenceProxyPullConsumer':oe_is_a('CosNotification_QoSAdmin':typeID())),
+ ?match(true, 'CosNotifyChannelAdmin_SequenceProxyPullConsumer':oe_is_a('CosNotifyFilter_FilterAdmin':typeID())),
+ ?match(true, 'CosNotifyChannelAdmin_SequenceProxyPullConsumer':oe_is_a('CosNotifyComm_SequencePullConsumer':typeID())),
+ ?match(true, 'CosNotifyChannelAdmin_SequenceProxyPullConsumer':oe_is_a('CosNotifyComm_NotifyPublish':typeID())),
+ ?match(false, 'CosNotifyChannelAdmin_SequenceProxyPullConsumer':oe_is_a("wrong")),
+ ok.
+
+
+%%-----------------------------------------------------------------
+%% Test Case: 'CosNotifyChannelAdmin_SequenceProxyPullSupplier'
+%% Description:
+%%-----------------------------------------------------------------
+'CosNotifyChannelAdmin_SequenceProxyPullSupplier'(doc) -> ["CosNotifyChannelAdmin_SequenceProxyPullSupplier"];
+'CosNotifyChannelAdmin_SequenceProxyPullSupplier'(suite) -> [];
+'CosNotifyChannelAdmin_SequenceProxyPullSupplier'(_) ->
+ ?nomatch(undefined, 'CosNotifyChannelAdmin_SequenceProxyPullSupplier':oe_tc(connect_sequence_pull_consumer)),
+ ?nomatch(undefined, 'CosNotifyChannelAdmin_SequenceProxyPullSupplier':oe_tc('_get_MyType')),
+ ?nomatch(undefined, 'CosNotifyChannelAdmin_SequenceProxyPullSupplier':oe_tc('_get_MyAdmin')),
+ ?nomatch(undefined, 'CosNotifyChannelAdmin_SequenceProxyPullSupplier':oe_tc('_get_priority_filter')),
+ ?nomatch(undefined, 'CosNotifyChannelAdmin_SequenceProxyPullSupplier':oe_tc('_set_priority_filter')),
+ ?nomatch(undefined, 'CosNotifyChannelAdmin_SequenceProxyPullSupplier':oe_tc('_get_lifetime_filter')),
+ ?nomatch(undefined, 'CosNotifyChannelAdmin_SequenceProxyPullSupplier':oe_tc('_set_lifetime_filter')),
+ ?nomatch(undefined, 'CosNotifyChannelAdmin_SequenceProxyPullSupplier':oe_tc(obtain_offered_types)),
+ ?nomatch(undefined, 'CosNotifyChannelAdmin_SequenceProxyPullSupplier':oe_tc(validate_event_qos)),
+ ?nomatch(undefined, 'CosNotifyChannelAdmin_SequenceProxyPullSupplier':oe_tc(get_qos)),
+ ?nomatch(undefined, 'CosNotifyChannelAdmin_SequenceProxyPullSupplier':oe_tc(set_qos)),
+ ?nomatch(undefined, 'CosNotifyChannelAdmin_SequenceProxyPullSupplier':oe_tc(validate_qos)),
+ ?nomatch(undefined, 'CosNotifyChannelAdmin_SequenceProxyPullSupplier':oe_tc(add_filter)),
+ ?nomatch(undefined, 'CosNotifyChannelAdmin_SequenceProxyPullSupplier':oe_tc(remove_filter)),
+ ?nomatch(undefined, 'CosNotifyChannelAdmin_SequenceProxyPullSupplier':oe_tc(get_filter)),
+ ?nomatch(undefined, 'CosNotifyChannelAdmin_SequenceProxyPullSupplier':oe_tc(get_all_filters)),
+ ?nomatch(undefined, 'CosNotifyChannelAdmin_SequenceProxyPullSupplier':oe_tc(remove_all_filters)),
+ ?nomatch(undefined, 'CosNotifyChannelAdmin_SequenceProxyPullSupplier':oe_tc(pull_structured_events)),
+ ?nomatch(undefined, 'CosNotifyChannelAdmin_SequenceProxyPullSupplier':oe_tc(try_pull_structured_events)),
+ ?nomatch(undefined, 'CosNotifyChannelAdmin_SequenceProxyPullSupplier':oe_tc(disconnect_sequence_pull_supplier)),
+ ?nomatch(undefined, 'CosNotifyChannelAdmin_SequenceProxyPullSupplier':oe_tc(subscription_change)),
+ ?nomatch(undefined, 'CosNotifyChannelAdmin_SequenceProxyPullSupplier':oe_tc(callSeq)),
+ ?nomatch(undefined, 'CosNotifyChannelAdmin_SequenceProxyPullSupplier':oe_tc(callAny)),
+ ?match(undefined, 'CosNotifyChannelAdmin_SequenceProxyPullSupplier':oe_tc(undefined)),
+ ?match([_|_], 'CosNotifyChannelAdmin_SequenceProxyPullSupplier':oe_get_interface()),
+ ?match("IDL:omg.org/CosNotifyChannelAdmin/SequenceProxyPullSupplier:1.0",
+ 'CosNotifyChannelAdmin_SequenceProxyPullSupplier':typeID()),
+ check_tc('CosNotifyChannelAdmin_SequenceProxyPullSupplier':oe_get_interface()),
+ ?match(true, 'CosNotifyChannelAdmin_SequenceProxyPullSupplier':oe_is_a('CosNotifyChannelAdmin_SequenceProxyPullSupplier':typeID())),
+ ?match(true, 'CosNotifyChannelAdmin_SequenceProxyPullSupplier':oe_is_a('CosNotifyChannelAdmin_ProxySupplier':typeID())),
+ ?match(true, 'CosNotifyChannelAdmin_SequenceProxyPullSupplier':oe_is_a('CosNotification_QoSAdmin':typeID())),
+ ?match(true, 'CosNotifyChannelAdmin_SequenceProxyPullSupplier':oe_is_a('CosNotifyFilter_FilterAdmin':typeID())),
+ ?match(true, 'CosNotifyChannelAdmin_SequenceProxyPullSupplier':oe_is_a('CosNotifyComm_SequencePullSupplier':typeID())),
+ ?match(true, 'CosNotifyChannelAdmin_SequenceProxyPullSupplier':oe_is_a('CosNotifyComm_NotifySubscribe':typeID())),
+ ?match(true, 'CosNotifyChannelAdmin_SequenceProxyPullSupplier':oe_is_a('oe_CosNotificationComm_Event':typeID())),
+ ?match(false, 'CosNotifyChannelAdmin_SequenceProxyPullSupplier':oe_is_a("wrong")),
+ ok.
+
+
+%%-----------------------------------------------------------------
+%% Test Case: 'CosNotifyChannelAdmin_SequenceProxyPushConsumer'
+%% Description:
+%%-----------------------------------------------------------------
+'CosNotifyChannelAdmin_SequenceProxyPushConsumer'(doc) -> ["CosNotifyChannelAdmin_SequenceProxyPushConsumer"];
+'CosNotifyChannelAdmin_SequenceProxyPushConsumer'(suite) -> [];
+'CosNotifyChannelAdmin_SequenceProxyPushConsumer'(_) ->
+ ?nomatch(undefined, 'CosNotifyChannelAdmin_SequenceProxyPushConsumer':oe_tc(connect_sequence_push_supplier)),
+ ?nomatch(undefined, 'CosNotifyChannelAdmin_SequenceProxyPushConsumer':oe_tc('_get_MyType')),
+ ?nomatch(undefined, 'CosNotifyChannelAdmin_SequenceProxyPushConsumer':oe_tc('_get_MyAdmin')),
+ ?nomatch(undefined, 'CosNotifyChannelAdmin_SequenceProxyPushConsumer':oe_tc(obtain_subscription_types)),
+ ?nomatch(undefined, 'CosNotifyChannelAdmin_SequenceProxyPushConsumer':oe_tc(validate_event_qos)),
+ ?nomatch(undefined, 'CosNotifyChannelAdmin_SequenceProxyPushConsumer':oe_tc(get_qos)),
+ ?nomatch(undefined, 'CosNotifyChannelAdmin_SequenceProxyPushConsumer':oe_tc(set_qos)),
+ ?nomatch(undefined, 'CosNotifyChannelAdmin_SequenceProxyPushConsumer':oe_tc(validate_qos)),
+ ?nomatch(undefined, 'CosNotifyChannelAdmin_SequenceProxyPushConsumer':oe_tc(add_filter)),
+ ?nomatch(undefined, 'CosNotifyChannelAdmin_SequenceProxyPushConsumer':oe_tc(remove_filter)),
+ ?nomatch(undefined, 'CosNotifyChannelAdmin_SequenceProxyPushConsumer':oe_tc(get_filter)),
+ ?nomatch(undefined, 'CosNotifyChannelAdmin_SequenceProxyPushConsumer':oe_tc(get_all_filters)),
+ ?nomatch(undefined, 'CosNotifyChannelAdmin_SequenceProxyPushConsumer':oe_tc(remove_all_filters)),
+ ?nomatch(undefined, 'CosNotifyChannelAdmin_SequenceProxyPushConsumer':oe_tc(push_structured_events)),
+ ?nomatch(undefined, 'CosNotifyChannelAdmin_SequenceProxyPushConsumer':oe_tc(disconnect_sequence_push_consumer)),
+ ?nomatch(undefined, 'CosNotifyChannelAdmin_SequenceProxyPushConsumer':oe_tc(offer_change)),
+ ?match(undefined, 'CosNotifyChannelAdmin_SequenceProxyPushConsumer':oe_tc(undefined)),
+ ?match([_|_], 'CosNotifyChannelAdmin_SequenceProxyPushConsumer':oe_get_interface()),
+ ?match("IDL:omg.org/CosNotifyChannelAdmin/SequenceProxyPushConsumer:1.0",
+ 'CosNotifyChannelAdmin_SequenceProxyPushConsumer':typeID()),
+ check_tc('CosNotifyChannelAdmin_SequenceProxyPushConsumer':oe_get_interface()),
+ ?match(true, 'CosNotifyChannelAdmin_SequenceProxyPushConsumer':oe_is_a('CosNotifyChannelAdmin_SequenceProxyPushConsumer':typeID())),
+ ?match(true, 'CosNotifyChannelAdmin_SequenceProxyPushConsumer':oe_is_a('CosNotifyChannelAdmin_ProxyConsumer':typeID())),
+ ?match(true, 'CosNotifyChannelAdmin_SequenceProxyPushConsumer':oe_is_a('CosNotification_QoSAdmin':typeID())),
+ ?match(true, 'CosNotifyChannelAdmin_SequenceProxyPushConsumer':oe_is_a('CosNotifyFilter_FilterAdmin':typeID())),
+ ?match(true, 'CosNotifyChannelAdmin_SequenceProxyPushConsumer':oe_is_a('CosNotifyComm_SequencePushConsumer':typeID())),
+ ?match(true, 'CosNotifyChannelAdmin_SequenceProxyPushConsumer':oe_is_a('CosNotifyComm_NotifyPublish':typeID())),
+ ?match(false, 'CosNotifyChannelAdmin_SequenceProxyPushConsumer':oe_is_a("wrong")),
+ ok.
+
+
+%%-----------------------------------------------------------------
+%% Test Case: 'CosNotifyChannelAdmin_SequenceProxyPushSupplier'
+%% Description:
+%%-----------------------------------------------------------------
+'CosNotifyChannelAdmin_SequenceProxyPushSupplier'(doc) -> ["CosNotifyChannelAdmin_SequenceProxyPushSupplier"];
+'CosNotifyChannelAdmin_SequenceProxyPushSupplier'(suite) -> [];
+'CosNotifyChannelAdmin_SequenceProxyPushSupplier'(_) ->
+ ?nomatch(undefined, 'CosNotifyChannelAdmin_SequenceProxyPushSupplier':oe_tc(connect_sequence_push_consumer)),
+ ?nomatch(undefined, 'CosNotifyChannelAdmin_SequenceProxyPushSupplier':oe_tc(suspend_connection)),
+ ?nomatch(undefined, 'CosNotifyChannelAdmin_SequenceProxyPushSupplier':oe_tc(resume_connection)),
+ ?nomatch(undefined, 'CosNotifyChannelAdmin_SequenceProxyPushSupplier':oe_tc('_get_MyType')),
+ ?nomatch(undefined, 'CosNotifyChannelAdmin_SequenceProxyPushSupplier':oe_tc('_get_MyAdmin')),
+ ?nomatch(undefined, 'CosNotifyChannelAdmin_SequenceProxyPushSupplier':oe_tc('_get_priority_filter')),
+ ?nomatch(undefined, 'CosNotifyChannelAdmin_SequenceProxyPushSupplier':oe_tc('_set_priority_filter')),
+ ?nomatch(undefined, 'CosNotifyChannelAdmin_SequenceProxyPushSupplier':oe_tc('_get_lifetime_filter')),
+ ?nomatch(undefined, 'CosNotifyChannelAdmin_SequenceProxyPushSupplier':oe_tc('_set_lifetime_filter')),
+ ?nomatch(undefined, 'CosNotifyChannelAdmin_SequenceProxyPushSupplier':oe_tc(obtain_offered_types)),
+ ?nomatch(undefined, 'CosNotifyChannelAdmin_SequenceProxyPushSupplier':oe_tc(validate_event_qos)),
+ ?nomatch(undefined, 'CosNotifyChannelAdmin_SequenceProxyPushSupplier':oe_tc(get_qos)),
+ ?nomatch(undefined, 'CosNotifyChannelAdmin_SequenceProxyPushSupplier':oe_tc(set_qos)),
+ ?nomatch(undefined, 'CosNotifyChannelAdmin_SequenceProxyPushSupplier':oe_tc(validate_qos)),
+ ?nomatch(undefined, 'CosNotifyChannelAdmin_SequenceProxyPushSupplier':oe_tc(add_filter)),
+ ?nomatch(undefined, 'CosNotifyChannelAdmin_SequenceProxyPushSupplier':oe_tc(remove_filter)),
+ ?nomatch(undefined, 'CosNotifyChannelAdmin_SequenceProxyPushSupplier':oe_tc(get_filter)),
+ ?nomatch(undefined, 'CosNotifyChannelAdmin_SequenceProxyPushSupplier':oe_tc(get_all_filters)),
+ ?nomatch(undefined, 'CosNotifyChannelAdmin_SequenceProxyPushSupplier':oe_tc(remove_all_filters)),
+ ?nomatch(undefined, 'CosNotifyChannelAdmin_SequenceProxyPushSupplier':oe_tc(disconnect_sequence_push_supplier)),
+ ?nomatch(undefined, 'CosNotifyChannelAdmin_SequenceProxyPushSupplier':oe_tc(subscription_change)),
+ ?nomatch(undefined, 'CosNotifyChannelAdmin_SequenceProxyPushSupplier':oe_tc(callSeq)),
+ ?nomatch(undefined, 'CosNotifyChannelAdmin_SequenceProxyPushSupplier':oe_tc(callAny)),
+ ?match(undefined, 'CosNotifyChannelAdmin_SequenceProxyPushSupplier':oe_tc(undefined)),
+ ?match([_|_], 'CosNotifyChannelAdmin_SequenceProxyPushSupplier':oe_get_interface()),
+ ?match("IDL:omg.org/CosNotifyChannelAdmin/SequenceProxyPushSupplier:1.0",
+ 'CosNotifyChannelAdmin_SequenceProxyPushSupplier':typeID()),
+ check_tc('CosNotifyChannelAdmin_SequenceProxyPushSupplier':oe_get_interface()),
+ ?match(true, 'CosNotifyChannelAdmin_SequenceProxyPushSupplier':oe_is_a('CosNotifyChannelAdmin_SequenceProxyPushSupplier':typeID())),
+ ?match(true, 'CosNotifyChannelAdmin_SequenceProxyPushSupplier':oe_is_a('CosNotifyChannelAdmin_ProxySupplier':typeID())),
+ ?match(true, 'CosNotifyChannelAdmin_SequenceProxyPushSupplier':oe_is_a('CosNotification_QoSAdmin':typeID())),
+ ?match(true, 'CosNotifyChannelAdmin_SequenceProxyPushSupplier':oe_is_a('CosNotifyFilter_FilterAdmin':typeID())),
+ ?match(true, 'CosNotifyChannelAdmin_SequenceProxyPushSupplier':oe_is_a('CosNotifyComm_SequencePushSupplier':typeID())),
+ ?match(true, 'CosNotifyChannelAdmin_SequenceProxyPushSupplier':oe_is_a('CosNotifyComm_NotifySubscribe':typeID())),
+ ?match(true, 'CosNotifyChannelAdmin_SequenceProxyPushSupplier':oe_is_a('oe_CosNotificationComm_Event':typeID())),
+ ?match(false, 'CosNotifyChannelAdmin_SequenceProxyPushSupplier':oe_is_a("wrong")),
+ ok.
+
+
+%%-----------------------------------------------------------------
+%% Test Case: 'CosNotifyChannelAdmin_StructuredProxyPullConsumer'
+%% Description:
+%%-----------------------------------------------------------------
+'CosNotifyChannelAdmin_StructuredProxyPullConsumer'(doc) -> ["CosNotifyChannelAdmin_StructuredProxyPullConsumer"];
+'CosNotifyChannelAdmin_StructuredProxyPullConsumer'(suite) -> [];
+'CosNotifyChannelAdmin_StructuredProxyPullConsumer'(_) ->
+ ?nomatch(undefined, 'CosNotifyChannelAdmin_StructuredProxyPullConsumer':oe_tc(connect_structured_pull_supplier)),
+ ?nomatch(undefined, 'CosNotifyChannelAdmin_StructuredProxyPullConsumer':oe_tc(suspend_connection)),
+ ?nomatch(undefined, 'CosNotifyChannelAdmin_StructuredProxyPullConsumer':oe_tc(resume_connection)),
+ ?nomatch(undefined, 'CosNotifyChannelAdmin_StructuredProxyPullConsumer':oe_tc('_get_MyType')),
+ ?nomatch(undefined, 'CosNotifyChannelAdmin_StructuredProxyPullConsumer':oe_tc('_get_MyAdmin')),
+ ?nomatch(undefined, 'CosNotifyChannelAdmin_StructuredProxyPullConsumer':oe_tc(obtain_subscription_types)),
+ ?nomatch(undefined, 'CosNotifyChannelAdmin_StructuredProxyPullConsumer':oe_tc(validate_event_qos)),
+ ?nomatch(undefined, 'CosNotifyChannelAdmin_StructuredProxyPullConsumer':oe_tc(get_qos)),
+ ?nomatch(undefined, 'CosNotifyChannelAdmin_StructuredProxyPullConsumer':oe_tc(set_qos)),
+ ?nomatch(undefined, 'CosNotifyChannelAdmin_StructuredProxyPullConsumer':oe_tc(validate_qos)),
+ ?nomatch(undefined, 'CosNotifyChannelAdmin_StructuredProxyPullConsumer':oe_tc(add_filter)),
+ ?nomatch(undefined, 'CosNotifyChannelAdmin_StructuredProxyPullConsumer':oe_tc(remove_filter)),
+ ?nomatch(undefined, 'CosNotifyChannelAdmin_StructuredProxyPullConsumer':oe_tc(get_filter)),
+ ?nomatch(undefined, 'CosNotifyChannelAdmin_StructuredProxyPullConsumer':oe_tc(get_all_filters)),
+ ?nomatch(undefined, 'CosNotifyChannelAdmin_StructuredProxyPullConsumer':oe_tc(remove_all_filters)),
+ ?nomatch(undefined, 'CosNotifyChannelAdmin_StructuredProxyPullConsumer':oe_tc(disconnect_structured_pull_consumer)),
+ ?nomatch(undefined, 'CosNotifyChannelAdmin_StructuredProxyPullConsumer':oe_tc(offer_change)),
+ ?match(undefined, 'CosNotifyChannelAdmin_StructuredProxyPullConsumer':oe_tc(undefined)),
+ ?match([_|_], 'CosNotifyChannelAdmin_StructuredProxyPullConsumer':oe_get_interface()),
+ ?match("IDL:omg.org/CosNotifyChannelAdmin/StructuredProxyPullConsumer:1.0",
+ 'CosNotifyChannelAdmin_StructuredProxyPullConsumer':typeID()),
+ check_tc('CosNotifyChannelAdmin_StructuredProxyPullConsumer':oe_get_interface()),
+ ?match(true, 'CosNotifyChannelAdmin_StructuredProxyPullConsumer':oe_is_a('CosNotifyChannelAdmin_StructuredProxyPullConsumer':typeID())),
+ ?match(true, 'CosNotifyChannelAdmin_StructuredProxyPullConsumer':oe_is_a('CosNotifyChannelAdmin_ProxyConsumer':typeID())),
+ ?match(true, 'CosNotifyChannelAdmin_StructuredProxyPullConsumer':oe_is_a('CosNotification_QoSAdmin':typeID())),
+ ?match(true, 'CosNotifyChannelAdmin_StructuredProxyPullConsumer':oe_is_a('CosNotifyFilter_FilterAdmin':typeID())),
+ ?match(true, 'CosNotifyChannelAdmin_StructuredProxyPullConsumer':oe_is_a('CosNotifyComm_StructuredPullConsumer':typeID())),
+ ?match(true, 'CosNotifyChannelAdmin_StructuredProxyPullConsumer':oe_is_a('CosNotifyComm_NotifyPublish':typeID())),
+ ?match(false, 'CosNotifyChannelAdmin_StructuredProxyPullConsumer':oe_is_a("wrong")),
+ ok.
+
+
+%%-----------------------------------------------------------------
+%% Test Case: 'CosNotifyChannelAdmin_StructuredProxyPullSupplier'
+%% Description:
+%%-----------------------------------------------------------------
+'CosNotifyChannelAdmin_StructuredProxyPullSupplier'(doc) -> ["CosNotifyChannelAdmin_StructuredProxyPullSupplier"];
+'CosNotifyChannelAdmin_StructuredProxyPullSupplier'(suite) -> [];
+'CosNotifyChannelAdmin_StructuredProxyPullSupplier'(_) ->
+ ?nomatch(undefined, 'CosNotifyChannelAdmin_StructuredProxyPullSupplier':oe_tc(connect_structured_pull_consumer)),
+ ?nomatch(undefined, 'CosNotifyChannelAdmin_StructuredProxyPullSupplier':oe_tc('_get_MyType')),
+ ?nomatch(undefined, 'CosNotifyChannelAdmin_StructuredProxyPullSupplier':oe_tc('_get_MyAdmin')),
+ ?nomatch(undefined, 'CosNotifyChannelAdmin_StructuredProxyPullSupplier':oe_tc('_get_priority_filter')),
+ ?nomatch(undefined, 'CosNotifyChannelAdmin_StructuredProxyPullSupplier':oe_tc('_set_priority_filter')),
+ ?nomatch(undefined, 'CosNotifyChannelAdmin_StructuredProxyPullSupplier':oe_tc('_get_lifetime_filter')),
+ ?nomatch(undefined, 'CosNotifyChannelAdmin_StructuredProxyPullSupplier':oe_tc('_set_lifetime_filter')),
+ ?nomatch(undefined, 'CosNotifyChannelAdmin_StructuredProxyPullSupplier':oe_tc(obtain_offered_types)),
+ ?nomatch(undefined, 'CosNotifyChannelAdmin_StructuredProxyPullSupplier':oe_tc(validate_event_qos)),
+ ?nomatch(undefined, 'CosNotifyChannelAdmin_StructuredProxyPullSupplier':oe_tc(get_qos)),
+ ?nomatch(undefined, 'CosNotifyChannelAdmin_StructuredProxyPullSupplier':oe_tc(set_qos)),
+ ?nomatch(undefined, 'CosNotifyChannelAdmin_StructuredProxyPullSupplier':oe_tc(validate_qos)),
+ ?nomatch(undefined, 'CosNotifyChannelAdmin_StructuredProxyPullSupplier':oe_tc(add_filter)),
+ ?nomatch(undefined, 'CosNotifyChannelAdmin_StructuredProxyPullSupplier':oe_tc(remove_filter)),
+ ?nomatch(undefined, 'CosNotifyChannelAdmin_StructuredProxyPullSupplier':oe_tc(get_filter)),
+ ?nomatch(undefined, 'CosNotifyChannelAdmin_StructuredProxyPullSupplier':oe_tc(get_all_filters)),
+ ?nomatch(undefined, 'CosNotifyChannelAdmin_StructuredProxyPullSupplier':oe_tc(remove_all_filters)),
+ ?nomatch(undefined, 'CosNotifyChannelAdmin_StructuredProxyPullSupplier':oe_tc(pull_structured_event)),
+ ?nomatch(undefined, 'CosNotifyChannelAdmin_StructuredProxyPullSupplier':oe_tc(try_pull_structured_event)),
+ ?nomatch(undefined, 'CosNotifyChannelAdmin_StructuredProxyPullSupplier':oe_tc(disconnect_structured_pull_supplier)),
+ ?nomatch(undefined, 'CosNotifyChannelAdmin_StructuredProxyPullSupplier':oe_tc(subscription_change)),
+ ?nomatch(undefined, 'CosNotifyChannelAdmin_StructuredProxyPullSupplier':oe_tc(callSeq)),
+ ?nomatch(undefined, 'CosNotifyChannelAdmin_StructuredProxyPullSupplier':oe_tc(callAny)),
+ ?match(undefined, 'CosNotifyChannelAdmin_StructuredProxyPullSupplier':oe_tc(undefined)),
+ ?match([_|_], 'CosNotifyChannelAdmin_StructuredProxyPullSupplier':oe_get_interface()),
+ ?match("IDL:omg.org/CosNotifyChannelAdmin/StructuredProxyPullSupplier:1.0",
+ 'CosNotifyChannelAdmin_StructuredProxyPullSupplier':typeID()),
+ check_tc('CosNotifyChannelAdmin_StructuredProxyPullSupplier':oe_get_interface()),
+ ?match(true, 'CosNotifyChannelAdmin_StructuredProxyPullSupplier':oe_is_a('CosNotifyChannelAdmin_StructuredProxyPullSupplier':typeID())),
+ ?match(true, 'CosNotifyChannelAdmin_StructuredProxyPullSupplier':oe_is_a('CosNotifyChannelAdmin_ProxySupplier':typeID())),
+ ?match(true, 'CosNotifyChannelAdmin_StructuredProxyPullSupplier':oe_is_a('CosNotification_QoSAdmin':typeID())),
+ ?match(true, 'CosNotifyChannelAdmin_StructuredProxyPullSupplier':oe_is_a('CosNotifyFilter_FilterAdmin':typeID())),
+ ?match(true, 'CosNotifyChannelAdmin_StructuredProxyPullSupplier':oe_is_a('CosNotifyComm_StructuredPullSupplier':typeID())),
+ ?match(true, 'CosNotifyChannelAdmin_StructuredProxyPullSupplier':oe_is_a('CosNotifyComm_NotifySubscribe':typeID())),
+ ?match(true, 'CosNotifyChannelAdmin_StructuredProxyPullSupplier':oe_is_a('oe_CosNotificationComm_Event':typeID())),
+ ?match(false, 'CosNotifyChannelAdmin_StructuredProxyPullSupplier':oe_is_a("wrong")),
+ ok.
+
+
+%%-----------------------------------------------------------------
+%% Test Case: 'CosNotifyChannelAdmin_StructuredProxyPushConsumer'
+%% Description:
+%%-----------------------------------------------------------------
+'CosNotifyChannelAdmin_StructuredProxyPushConsumer'(doc) -> ["CosNotifyChannelAdmin_StructuredProxyPushConsumer"];
+'CosNotifyChannelAdmin_StructuredProxyPushConsumer'(suite) -> [];
+'CosNotifyChannelAdmin_StructuredProxyPushConsumer'(_) ->
+ ?nomatch(undefined, 'CosNotifyChannelAdmin_StructuredProxyPushConsumer':oe_tc(connect_structured_push_supplier)),
+ ?nomatch(undefined, 'CosNotifyChannelAdmin_StructuredProxyPushConsumer':oe_tc('_get_MyType')),
+ ?nomatch(undefined, 'CosNotifyChannelAdmin_StructuredProxyPushConsumer':oe_tc('_get_MyAdmin')),
+ ?nomatch(undefined, 'CosNotifyChannelAdmin_StructuredProxyPushConsumer':oe_tc(obtain_subscription_types)),
+ ?nomatch(undefined, 'CosNotifyChannelAdmin_StructuredProxyPushConsumer':oe_tc(validate_event_qos)),
+ ?nomatch(undefined, 'CosNotifyChannelAdmin_StructuredProxyPushConsumer':oe_tc(get_qos)),
+ ?nomatch(undefined, 'CosNotifyChannelAdmin_StructuredProxyPushConsumer':oe_tc(set_qos)),
+ ?nomatch(undefined, 'CosNotifyChannelAdmin_StructuredProxyPushConsumer':oe_tc(validate_qos)),
+ ?nomatch(undefined, 'CosNotifyChannelAdmin_StructuredProxyPushConsumer':oe_tc(add_filter)),
+ ?nomatch(undefined, 'CosNotifyChannelAdmin_StructuredProxyPushConsumer':oe_tc(remove_filter)),
+ ?nomatch(undefined, 'CosNotifyChannelAdmin_StructuredProxyPushConsumer':oe_tc(get_filter)),
+ ?nomatch(undefined, 'CosNotifyChannelAdmin_StructuredProxyPushConsumer':oe_tc(get_all_filters)),
+ ?nomatch(undefined, 'CosNotifyChannelAdmin_StructuredProxyPushConsumer':oe_tc(remove_all_filters)),
+ ?nomatch(undefined, 'CosNotifyChannelAdmin_StructuredProxyPushConsumer':oe_tc(push_structured_event)),
+ ?nomatch(undefined, 'CosNotifyChannelAdmin_StructuredProxyPushConsumer':oe_tc(disconnect_structured_push_consumer)),
+ ?nomatch(undefined, 'CosNotifyChannelAdmin_StructuredProxyPushConsumer':oe_tc(offer_change)),
+ ?match(undefined, 'CosNotifyChannelAdmin_StructuredProxyPushConsumer':oe_tc(undefined)),
+ ?match([_|_], 'CosNotifyChannelAdmin_StructuredProxyPushConsumer':oe_get_interface()),
+ ?match("IDL:omg.org/CosNotifyChannelAdmin/StructuredProxyPushConsumer:1.0",
+ 'CosNotifyChannelAdmin_StructuredProxyPushConsumer':typeID()),
+ check_tc('CosNotifyChannelAdmin_StructuredProxyPushConsumer':oe_get_interface()),
+ ?match(true, 'CosNotifyChannelAdmin_StructuredProxyPushConsumer':oe_is_a('CosNotifyChannelAdmin_StructuredProxyPushConsumer':typeID())),
+ ?match(true, 'CosNotifyChannelAdmin_StructuredProxyPushConsumer':oe_is_a('CosNotifyChannelAdmin_ProxyConsumer':typeID())),
+ ?match(true, 'CosNotifyChannelAdmin_StructuredProxyPushConsumer':oe_is_a('CosNotification_QoSAdmin':typeID())),
+ ?match(true, 'CosNotifyChannelAdmin_StructuredProxyPushConsumer':oe_is_a('CosNotifyFilter_FilterAdmin':typeID())),
+ ?match(true, 'CosNotifyChannelAdmin_StructuredProxyPushConsumer':oe_is_a('CosNotifyComm_StructuredPushConsumer':typeID())),
+ ?match(true, 'CosNotifyChannelAdmin_StructuredProxyPushConsumer':oe_is_a('CosNotifyComm_NotifyPublish':typeID())),
+ ?match(false, 'CosNotifyChannelAdmin_StructuredProxyPushConsumer':oe_is_a("wrong")),
+ ok.
+
+
+%%-----------------------------------------------------------------
+%% Test Case: 'CosNotifyChannelAdmin_StructuredProxyPushSupplier'
+%% Description:
+%%-----------------------------------------------------------------
+'CosNotifyChannelAdmin_StructuredProxyPushSupplier'(doc) -> ["CosNotifyChannelAdmin_StructuredProxyPushSupplier"];
+'CosNotifyChannelAdmin_StructuredProxyPushSupplier'(suite) -> [];
+'CosNotifyChannelAdmin_StructuredProxyPushSupplier'(_) ->
+ ?nomatch(undefined, 'CosNotifyChannelAdmin_StructuredProxyPushSupplier':oe_tc(connect_structured_push_consumer)),
+ ?nomatch(undefined, 'CosNotifyChannelAdmin_StructuredProxyPushSupplier':oe_tc(suspend_connection)),
+ ?nomatch(undefined, 'CosNotifyChannelAdmin_StructuredProxyPushSupplier':oe_tc(resume_connection)),
+ ?nomatch(undefined, 'CosNotifyChannelAdmin_StructuredProxyPushSupplier':oe_tc('_get_MyType')),
+ ?nomatch(undefined, 'CosNotifyChannelAdmin_StructuredProxyPushSupplier':oe_tc('_get_MyAdmin')),
+ ?nomatch(undefined, 'CosNotifyChannelAdmin_StructuredProxyPushSupplier':oe_tc('_get_priority_filter')),
+ ?nomatch(undefined, 'CosNotifyChannelAdmin_StructuredProxyPushSupplier':oe_tc('_set_priority_filter')),
+ ?nomatch(undefined, 'CosNotifyChannelAdmin_StructuredProxyPushSupplier':oe_tc('_get_lifetime_filter')),
+ ?nomatch(undefined, 'CosNotifyChannelAdmin_StructuredProxyPushSupplier':oe_tc('_set_lifetime_filter')),
+ ?nomatch(undefined, 'CosNotifyChannelAdmin_StructuredProxyPushSupplier':oe_tc(obtain_offered_types)),
+ ?nomatch(undefined, 'CosNotifyChannelAdmin_StructuredProxyPushSupplier':oe_tc(validate_event_qos)),
+ ?nomatch(undefined, 'CosNotifyChannelAdmin_StructuredProxyPushSupplier':oe_tc(get_qos)),
+ ?nomatch(undefined, 'CosNotifyChannelAdmin_StructuredProxyPushSupplier':oe_tc(set_qos)),
+ ?nomatch(undefined, 'CosNotifyChannelAdmin_StructuredProxyPushSupplier':oe_tc(validate_qos)),
+ ?nomatch(undefined, 'CosNotifyChannelAdmin_StructuredProxyPushSupplier':oe_tc(add_filter)),
+ ?nomatch(undefined, 'CosNotifyChannelAdmin_StructuredProxyPushSupplier':oe_tc(remove_filter)),
+ ?nomatch(undefined, 'CosNotifyChannelAdmin_StructuredProxyPushSupplier':oe_tc(get_filter)),
+ ?nomatch(undefined, 'CosNotifyChannelAdmin_StructuredProxyPushSupplier':oe_tc(get_all_filters)),
+ ?nomatch(undefined, 'CosNotifyChannelAdmin_StructuredProxyPushSupplier':oe_tc(remove_all_filters)),
+ ?nomatch(undefined, 'CosNotifyChannelAdmin_StructuredProxyPushSupplier':oe_tc(disconnect_structured_push_supplier)),
+ ?nomatch(undefined, 'CosNotifyChannelAdmin_StructuredProxyPushSupplier':oe_tc(subscription_change)),
+ ?nomatch(undefined, 'CosNotifyChannelAdmin_StructuredProxyPushSupplier':oe_tc(callSeq)),
+ ?nomatch(undefined, 'CosNotifyChannelAdmin_StructuredProxyPushSupplier':oe_tc(callAny)),
+ ?match(undefined, 'CosNotifyChannelAdmin_StructuredProxyPushSupplier':oe_tc(undefined)),
+ ?match([_|_], 'CosNotifyChannelAdmin_StructuredProxyPushSupplier':oe_get_interface()),
+ ?match("IDL:omg.org/CosNotifyChannelAdmin/StructuredProxyPushSupplier:1.0",
+ 'CosNotifyChannelAdmin_StructuredProxyPushSupplier':typeID()),
+ check_tc('CosNotifyChannelAdmin_StructuredProxyPushSupplier':oe_get_interface()),
+ ?match(true, 'CosNotifyChannelAdmin_StructuredProxyPushSupplier':oe_is_a('CosNotifyChannelAdmin_StructuredProxyPushSupplier':typeID())),
+ ?match(true, 'CosNotifyChannelAdmin_StructuredProxyPushSupplier':oe_is_a('CosNotifyChannelAdmin_ProxySupplier':typeID())),
+ ?match(true, 'CosNotifyChannelAdmin_StructuredProxyPushSupplier':oe_is_a('CosNotification_QoSAdmin':typeID())),
+ ?match(true, 'CosNotifyChannelAdmin_StructuredProxyPushSupplier':oe_is_a('CosNotifyFilter_FilterAdmin':typeID())),
+ ?match(true, 'CosNotifyChannelAdmin_StructuredProxyPushSupplier':oe_is_a('CosNotifyComm_StructuredPushSupplier':typeID())),
+ ?match(true, 'CosNotifyChannelAdmin_StructuredProxyPushSupplier':oe_is_a('CosNotifyComm_NotifySubscribe':typeID())),
+ ?match(true, 'CosNotifyChannelAdmin_StructuredProxyPushSupplier':oe_is_a('oe_CosNotificationComm_Event':typeID())),
+ ?match(false, 'CosNotifyChannelAdmin_StructuredProxyPushSupplier':oe_is_a("wrong")),
+ ok.
+
+
+%%-----------------------------------------------------------------
+%% Test Case: 'CosNotifyChannelAdmin_SupplierAdmin'
+%% Description:
+%%-----------------------------------------------------------------
+'CosNotifyChannelAdmin_SupplierAdmin'(doc) -> ["CosNotifyChannelAdmin_SupplierAdmin"];
+'CosNotifyChannelAdmin_SupplierAdmin'(suite) -> [];
+'CosNotifyChannelAdmin_SupplierAdmin'(_) ->
+ ?nomatch(undefined, 'CosNotifyChannelAdmin_SupplierAdmin':oe_tc('_get_MyID')),
+ ?nomatch(undefined, 'CosNotifyChannelAdmin_SupplierAdmin':oe_tc('_get_MyChannel')),
+ ?nomatch(undefined, 'CosNotifyChannelAdmin_SupplierAdmin':oe_tc('_get_MyOperator')),
+ ?nomatch(undefined, 'CosNotifyChannelAdmin_SupplierAdmin':oe_tc('_get_pull_consumers')),
+ ?nomatch(undefined, 'CosNotifyChannelAdmin_SupplierAdmin':oe_tc('_get_push_consumers')),
+ ?nomatch(undefined, 'CosNotifyChannelAdmin_SupplierAdmin':oe_tc(get_proxy_consumer)),
+ ?nomatch(undefined, 'CosNotifyChannelAdmin_SupplierAdmin':oe_tc(obtain_notification_pull_consumer)),
+ ?nomatch(undefined, 'CosNotifyChannelAdmin_SupplierAdmin':oe_tc(obtain_notification_push_consumer)),
+ ?nomatch(undefined, 'CosNotifyChannelAdmin_SupplierAdmin':oe_tc(destroy)),
+ ?nomatch(undefined, 'CosNotifyChannelAdmin_SupplierAdmin':oe_tc(get_qos)),
+ ?nomatch(undefined, 'CosNotifyChannelAdmin_SupplierAdmin':oe_tc(set_qos)),
+ ?nomatch(undefined, 'CosNotifyChannelAdmin_SupplierAdmin':oe_tc(validate_qos)),
+ ?nomatch(undefined, 'CosNotifyChannelAdmin_SupplierAdmin':oe_tc(offer_change)),
+ ?nomatch(undefined, 'CosNotifyChannelAdmin_SupplierAdmin':oe_tc(add_filter)),
+ ?nomatch(undefined, 'CosNotifyChannelAdmin_SupplierAdmin':oe_tc(remove_filter)),
+ ?nomatch(undefined, 'CosNotifyChannelAdmin_SupplierAdmin':oe_tc(get_filter)),
+ ?nomatch(undefined, 'CosNotifyChannelAdmin_SupplierAdmin':oe_tc(get_all_filters)),
+ ?nomatch(undefined, 'CosNotifyChannelAdmin_SupplierAdmin':oe_tc(remove_all_filters)),
+ ?nomatch(undefined, 'CosNotifyChannelAdmin_SupplierAdmin':oe_tc(obtain_push_consumer)),
+ ?nomatch(undefined, 'CosNotifyChannelAdmin_SupplierAdmin':oe_tc(obtain_pull_consumer)),
+ ?nomatch(undefined, 'CosNotifyChannelAdmin_SupplierAdmin':oe_tc(callSeq)),
+ ?nomatch(undefined, 'CosNotifyChannelAdmin_SupplierAdmin':oe_tc(callAny)),
+ ?match(undefined, 'CosNotifyChannelAdmin_SupplierAdmin':oe_tc(undefined)),
+ ?match([_|_], 'CosNotifyChannelAdmin_SupplierAdmin':oe_get_interface()),
+ ?match("IDL:omg.org/CosNotifyChannelAdmin/SupplierAdmin:1.0",
+ 'CosNotifyChannelAdmin_SupplierAdmin':typeID()),
+ check_tc('CosNotifyChannelAdmin_SupplierAdmin':oe_get_interface()),
+ ?match(true, 'CosNotifyChannelAdmin_SupplierAdmin':oe_is_a('CosNotifyChannelAdmin_SupplierAdmin':typeID())),
+ ?match(true, 'CosNotifyChannelAdmin_SupplierAdmin':oe_is_a('CosNotification_QoSAdmin':typeID())),
+ ?match(true, 'CosNotifyChannelAdmin_SupplierAdmin':oe_is_a('CosNotifyComm_NotifyPublish':typeID())),
+ ?match(true, 'CosNotifyChannelAdmin_SupplierAdmin':oe_is_a('CosNotifyFilter_FilterAdmin':typeID())),
+ ?match(true, 'CosNotifyChannelAdmin_SupplierAdmin':oe_is_a('CosEventChannelAdmin_SupplierAdmin':typeID())),
+ ?match(true, 'CosNotifyChannelAdmin_SupplierAdmin':oe_is_a('oe_CosNotificationComm_Event':typeID())),
+ ?match(false, 'CosNotifyChannelAdmin_SupplierAdmin':oe_is_a("wrong")),
+ ok.
+
+
+%%-----------------------------------------------------------------
+%% Test Case: 'CosNotifyFilter_Filter'
+%% Description:
+%%-----------------------------------------------------------------
+'CosNotifyFilter_Filter'(doc) -> ["CosNotifyFilter_Filter"];
+'CosNotifyFilter_Filter'(suite) -> [];
+'CosNotifyFilter_Filter'(_) ->
+ ?nomatch(undefined, 'CosNotifyFilter_Filter':oe_tc('_get_constraint_grammar')),
+ ?nomatch(undefined, 'CosNotifyFilter_Filter':oe_tc(add_constraints)),
+ ?nomatch(undefined, 'CosNotifyFilter_Filter':oe_tc(modify_constraints)),
+ ?nomatch(undefined, 'CosNotifyFilter_Filter':oe_tc(get_constraints)),
+ ?nomatch(undefined, 'CosNotifyFilter_Filter':oe_tc(get_all_constraints)),
+ ?nomatch(undefined, 'CosNotifyFilter_Filter':oe_tc(remove_all_constraints)),
+ ?nomatch(undefined, 'CosNotifyFilter_Filter':oe_tc(destroy)),
+ ?nomatch(undefined, 'CosNotifyFilter_Filter':oe_tc(match)),
+ ?nomatch(undefined, 'CosNotifyFilter_Filter':oe_tc(match_structured)),
+ ?nomatch(undefined, 'CosNotifyFilter_Filter':oe_tc(match_typed)),
+ ?nomatch(undefined, 'CosNotifyFilter_Filter':oe_tc(attach_callback)),
+ ?nomatch(undefined, 'CosNotifyFilter_Filter':oe_tc(detach_callback)),
+ ?nomatch(undefined, 'CosNotifyFilter_Filter':oe_tc(get_callbacks)),
+ ?match(undefined, 'CosNotifyFilter_Filter':oe_tc(undefined)),
+ ?match([_|_], 'CosNotifyFilter_Filter':oe_get_interface()),
+ ?match("IDL:omg.org/CosNotifyFilter/Filter:1.0",
+ 'CosNotifyFilter_Filter':typeID()),
+ check_tc('CosNotifyFilter_Filter':oe_get_interface()),
+ ?match(true, 'CosNotifyFilter_Filter':oe_is_a('CosNotifyFilter_Filter':typeID())),
+ ?match(false, 'CosNotifyFilter_Filter':oe_is_a("wrong")),
+ ok.
+
+
+%%-----------------------------------------------------------------
+%% Test Case: 'CosNotifyFilter_FilterAdmin'
+%% Description:
+%%-----------------------------------------------------------------
+'CosNotifyFilter_FilterAdmin'(doc) -> ["CosNotifyFilter_FilterAdmin"];
+'CosNotifyFilter_FilterAdmin'(suite) -> [];
+'CosNotifyFilter_FilterAdmin'(_) ->
+ ?nomatch(undefined, 'CosNotifyFilter_FilterAdmin':oe_tc(add_filter)),
+ ?nomatch(undefined, 'CosNotifyFilter_FilterAdmin':oe_tc(remove_filter)),
+ ?nomatch(undefined, 'CosNotifyFilter_FilterAdmin':oe_tc(get_filter)),
+ ?nomatch(undefined, 'CosNotifyFilter_FilterAdmin':oe_tc(get_all_filters)),
+ ?nomatch(undefined, 'CosNotifyFilter_FilterAdmin':oe_tc(remove_all_filters)),
+ ?match(undefined, 'CosNotifyFilter_FilterAdmin':oe_tc(undefined)),
+ ?match([_|_], 'CosNotifyFilter_FilterAdmin':oe_get_interface()),
+ ?match("IDL:omg.org/CosNotifyFilter/FilterAdmin:1.0",
+ 'CosNotifyFilter_FilterAdmin':typeID()),
+ check_tc('CosNotifyFilter_FilterAdmin':oe_get_interface()),
+ ?match(true, 'CosNotifyFilter_FilterAdmin':oe_is_a('CosNotifyFilter_FilterAdmin':typeID())),
+ ?match(false, 'CosNotifyFilter_FilterAdmin':oe_is_a("wrong")),
+ ok.
+
+
+%%-----------------------------------------------------------------
+%% Test Case: 'CosNotifyFilter_FilterFactory'
+%% Description:
+%%-----------------------------------------------------------------
+'CosNotifyFilter_FilterFactory'(doc) -> ["CosNotifyFilter_FilterFactory"];
+'CosNotifyFilter_FilterFactory'(suite) -> [];
+'CosNotifyFilter_FilterFactory'(_) ->
+ ?nomatch(undefined, 'CosNotifyFilter_FilterFactory':oe_tc(create_filter)),
+ ?nomatch(undefined, 'CosNotifyFilter_FilterFactory':oe_tc(create_mapping_filter)),
+ ?match(undefined, 'CosNotifyFilter_FilterFactory':oe_tc(undefined)),
+ ?match([_|_], 'CosNotifyFilter_FilterFactory':oe_get_interface()),
+ ?match("IDL:omg.org/CosNotifyFilter/FilterFactory:1.0",
+ 'CosNotifyFilter_FilterFactory':typeID()),
+ check_tc('CosNotifyFilter_FilterFactory':oe_get_interface()),
+ ?match(true, 'CosNotifyFilter_FilterFactory':oe_is_a('CosNotifyFilter_FilterFactory':typeID())),
+ ?match(false, 'CosNotifyFilter_FilterFactory':oe_is_a("wrong")),
+ ok.
+
+
+%%-----------------------------------------------------------------
+%% Test Case: 'CosNotifyFilter_MappingFilter'
+%% Description:
+%%-----------------------------------------------------------------
+'CosNotifyFilter_MappingFilter'(doc) -> ["CosNotifyFilter_MappingFilter"];
+'CosNotifyFilter_MappingFilter'(suite) -> [];
+'CosNotifyFilter_MappingFilter'(_) ->
+ ?nomatch(undefined, 'CosNotifyFilter_MappingFilter':oe_tc('_get_constraint_grammar')),
+ ?nomatch(undefined, 'CosNotifyFilter_MappingFilter':oe_tc('_get_value_type')),
+ ?nomatch(undefined, 'CosNotifyFilter_MappingFilter':oe_tc('_get_default_value')),
+ ?nomatch(undefined, 'CosNotifyFilter_MappingFilter':oe_tc(add_mapping_constraints)),
+ ?nomatch(undefined, 'CosNotifyFilter_MappingFilter':oe_tc(modify_mapping_constraints)),
+ ?nomatch(undefined, 'CosNotifyFilter_MappingFilter':oe_tc(get_mapping_constraints)),
+ ?nomatch(undefined, 'CosNotifyFilter_MappingFilter':oe_tc(get_all_mapping_constraints)),
+ ?nomatch(undefined, 'CosNotifyFilter_MappingFilter':oe_tc(remove_all_mapping_constraints)),
+ ?nomatch(undefined, 'CosNotifyFilter_MappingFilter':oe_tc(destroy)),
+ ?nomatch(undefined, 'CosNotifyFilter_MappingFilter':oe_tc(match)),
+ ?nomatch(undefined, 'CosNotifyFilter_MappingFilter':oe_tc(match_structured)),
+ ?nomatch(undefined, 'CosNotifyFilter_MappingFilter':oe_tc(match_typed)),
+ ?match(undefined, 'CosNotifyFilter_MappingFilter':oe_tc(undefined)),
+ ?match([_|_], 'CosNotifyFilter_MappingFilter':oe_get_interface()),
+ ?match("IDL:omg.org/CosNotifyFilter/MappingFilter:1.0",
+ 'CosNotifyFilter_MappingFilter':typeID()),
+ check_tc('CosNotifyFilter_MappingFilter':oe_get_interface()),
+ ?match(true, 'CosNotifyFilter_MappingFilter':oe_is_a('CosNotifyFilter_MappingFilter':typeID())),
+ ?match(false, 'CosNotifyFilter_MappingFilter':oe_is_a("wrong")),
+ ok.
+
+
+%%-----------------------------------------------------------------
+%% Test Case: 'CosNotifyComm_NotifyPublish'
+%% Description:
+%%-----------------------------------------------------------------
+'CosNotifyComm_NotifyPublish'(doc) -> ["CosNotifyComm_NotifyPublish"];
+'CosNotifyComm_NotifyPublish'(suite) -> [];
+'CosNotifyComm_NotifyPublish'(_) ->
+ ?nomatch(undefined, 'CosNotifyComm_NotifyPublish':oe_tc(offer_change)),
+ ?match(undefined, 'CosNotifyComm_NotifyPublish':oe_tc(undefined)),
+ ?match([_|_], 'CosNotifyComm_NotifyPublish':oe_get_interface()),
+ ?match("IDL:omg.org/CosNotifyComm/NotifyPublish:1.0",
+ 'CosNotifyComm_NotifyPublish':typeID()),
+ check_tc('CosNotifyComm_NotifyPublish':oe_get_interface()),
+ ?match(true, 'CosNotifyComm_NotifyPublish':oe_is_a('CosNotifyComm_NotifyPublish':typeID())),
+ ?match(false, 'CosNotifyComm_NotifyPublish':oe_is_a("wrong")),
+ ok.
+
+
+%%-----------------------------------------------------------------
+%% Test Case: 'CosNotifyComm_NotifySubscribe'
+%% Description:
+%%-----------------------------------------------------------------
+'CosNotifyComm_NotifySubscribe'(doc) -> ["CosNotifyComm_NotifySubscribe"];
+'CosNotifyComm_NotifySubscribe'(suite) -> [];
+'CosNotifyComm_NotifySubscribe'(_) ->
+ ?nomatch(undefined, 'CosNotifyComm_NotifySubscribe':oe_tc(subscription_change)),
+ ?match(undefined, 'CosNotifyComm_NotifySubscribe':oe_tc(undefined)),
+ ?match([_|_], 'CosNotifyComm_NotifySubscribe':oe_get_interface()),
+ ?match("IDL:omg.org/CosNotifyComm/NotifySubscribe:1.0",
+ 'CosNotifyComm_NotifySubscribe':typeID()),
+ check_tc('CosNotifyComm_NotifySubscribe':oe_get_interface()),
+ ?match(true, 'CosNotifyComm_NotifySubscribe':oe_is_a('CosNotifyComm_NotifySubscribe':typeID())),
+ ?match(false, 'CosNotifyComm_NotifySubscribe':oe_is_a("wrong")),
+ ok.
+
+
+%%-----------------------------------------------------------------
+%% Test Case: 'CosNotifyComm_PullConsumer'
+%% Description:
+%%-----------------------------------------------------------------
+'CosNotifyComm_PullConsumer'(doc) -> ["CosNotifyComm_PullConsumer"];
+'CosNotifyComm_PullConsumer'(suite) -> [];
+'CosNotifyComm_PullConsumer'(_) ->
+ ?nomatch(undefined, 'CosNotifyComm_PullConsumer':oe_tc(offer_change)),
+ ?nomatch(undefined, 'CosNotifyComm_PullConsumer':oe_tc(disconnect_pull_consumer)),
+ ?match(undefined, 'CosNotifyComm_PullConsumer':oe_tc(undefined)),
+ ?match([_|_], 'CosNotifyComm_PullConsumer':oe_get_interface()),
+ ?match("IDL:omg.org/CosNotifyComm/PullConsumer:1.0",
+ 'CosNotifyComm_PullConsumer':typeID()),
+ check_tc('CosNotifyComm_PullConsumer':oe_get_interface()),
+ ?match(true, 'CosNotifyComm_PullConsumer':oe_is_a('CosNotifyComm_PullConsumer':typeID())),
+ ?match(true, 'CosNotifyComm_PullConsumer':oe_is_a('CosNotifyComm_NotifyPublish':typeID())),
+ ?match(true, 'CosNotifyComm_PullConsumer':oe_is_a('CosEventComm_PullConsumer':typeID())),
+ ?match(false, 'CosNotifyComm_PullConsumer':oe_is_a("wrong")),
+ ok.
+
+
+%%-----------------------------------------------------------------
+%% Test Case: 'CosNotifyComm_PullSupplier'
+%% Description:
+%%-----------------------------------------------------------------
+'CosNotifyComm_PullSupplier'(doc) -> ["CosNotifyComm_PullSupplier"];
+'CosNotifyComm_PullSupplier'(suite) -> [];
+'CosNotifyComm_PullSupplier'(_) ->
+ ?nomatch(undefined, 'CosNotifyComm_PullSupplier':oe_tc(subscription_change)),
+ ?nomatch(undefined, 'CosNotifyComm_PullSupplier':oe_tc(pull)),
+ ?nomatch(undefined, 'CosNotifyComm_PullSupplier':oe_tc(try_pull)),
+ ?nomatch(undefined, 'CosNotifyComm_PullSupplier':oe_tc(disconnect_pull_supplier)),
+ ?match(undefined, 'CosNotifyComm_PullSupplier':oe_tc(undefined)),
+ ?match([_|_], 'CosNotifyComm_PullSupplier':oe_get_interface()),
+ ?match("IDL:omg.org/CosNotifyComm/PullSupplier:1.0",
+ 'CosNotifyComm_PullSupplier':typeID()),
+ check_tc('CosNotifyComm_PullSupplier':oe_get_interface()),
+ ?match(true, 'CosNotifyComm_PullSupplier':oe_is_a('CosNotifyComm_PullSupplier':typeID())),
+ ?match(true, 'CosNotifyComm_PullSupplier':oe_is_a('CosNotifyComm_NotifySubscribe':typeID())),
+ ?match(true, 'CosNotifyComm_PullSupplier':oe_is_a('CosEventComm_PullSupplier':typeID())),
+ ?match(false, 'CosNotifyComm_PullSupplier':oe_is_a("wrong")),
+ ok.
+
+
+%%-----------------------------------------------------------------
+%% Test Case: 'CosNotifyComm_PushConsumer'
+%% Description:
+%%-----------------------------------------------------------------
+'CosNotifyComm_PushConsumer'(doc) -> ["CosNotifyComm_PushConsumer"];
+'CosNotifyComm_PushConsumer'(suite) -> [];
+'CosNotifyComm_PushConsumer'(_) ->
+ ?nomatch(undefined, 'CosNotifyComm_PushConsumer':oe_tc(offer_change)),
+ ?nomatch(undefined, 'CosNotifyComm_PushConsumer':oe_tc(push)),
+ ?nomatch(undefined, 'CosNotifyComm_PushConsumer':oe_tc(disconnect_push_consumer)),
+ ?match(undefined, 'CosNotifyComm_PushConsumer':oe_tc(undefined)),
+ ?match([_|_], 'CosNotifyComm_PushConsumer':oe_get_interface()),
+ ?match("IDL:omg.org/CosNotifyComm/PushConsumer:1.0",
+ 'CosNotifyComm_PushConsumer':typeID()),
+ check_tc('CosNotifyComm_PushConsumer':oe_get_interface()),
+ ?match(true, 'CosNotifyComm_PushConsumer':oe_is_a('CosNotifyComm_PushConsumer':typeID())),
+ ?match(true, 'CosNotifyComm_PushConsumer':oe_is_a('CosNotifyComm_NotifyPublish':typeID())),
+ ?match(true, 'CosNotifyComm_PushConsumer':oe_is_a('CosEventComm_PushConsumer':typeID())),
+ ?match(false, 'CosNotifyComm_PushConsumer':oe_is_a("wrong")),
+ ok.
+
+
+%%-----------------------------------------------------------------
+%% Test Case: 'CosNotifyComm_PushSupplier'
+%% Description:
+%%-----------------------------------------------------------------
+'CosNotifyComm_PushSupplier'(doc) -> ["CosNotifyComm_PushSupplier"];
+'CosNotifyComm_PushSupplier'(suite) -> [];
+'CosNotifyComm_PushSupplier'(_) ->
+ ?nomatch(undefined, 'CosNotifyComm_PushSupplier':oe_tc(subscription_change)),
+ ?nomatch(undefined, 'CosNotifyComm_PushSupplier':oe_tc(disconnect_push_supplier)),
+ ?match(undefined, 'CosNotifyComm_PushSupplier':oe_tc(undefined)),
+ ?match([_|_], 'CosNotifyComm_PushSupplier':oe_get_interface()),
+ ?match("IDL:omg.org/CosNotifyComm/PushSupplier:1.0",
+ 'CosNotifyComm_PushSupplier':typeID()),
+ check_tc('CosNotifyComm_PushSupplier':oe_get_interface()),
+ ?match(true, 'CosNotifyComm_PushSupplier':oe_is_a('CosNotifyComm_PushSupplier':typeID())),
+ ?match(true, 'CosNotifyComm_PushSupplier':oe_is_a('CosNotifyComm_NotifySubscribe':typeID())),
+ ?match(true, 'CosNotifyComm_PushSupplier':oe_is_a('CosEventComm_PushSupplier':typeID())),
+ ?match(false, 'CosNotifyComm_PushSupplier':oe_is_a("wrong")),
+ ok.
+
+
+%%-----------------------------------------------------------------
+%% Test Case: 'CosNotifyComm_SequencePullConsumer'
+%% Description:
+%%-----------------------------------------------------------------
+'CosNotifyComm_SequencePullConsumer'(doc) -> ["CosNotifyComm_SequencePullConsumer"];
+'CosNotifyComm_SequencePullConsumer'(suite) -> [];
+'CosNotifyComm_SequencePullConsumer'(_) ->
+ ?nomatch(undefined, 'CosNotifyComm_SequencePullConsumer':oe_tc(disconnect_sequence_pull_consumer)),
+ ?nomatch(undefined, 'CosNotifyComm_SequencePullConsumer':oe_tc(offer_change)),
+ ?match(undefined, 'CosNotifyComm_SequencePullConsumer':oe_tc(undefined)),
+ ?match([_|_], 'CosNotifyComm_SequencePullConsumer':oe_get_interface()),
+ ?match("IDL:omg.org/CosNotifyComm/SequencePullConsumer:1.0",
+ 'CosNotifyComm_SequencePullConsumer':typeID()),
+ check_tc('CosNotifyComm_SequencePullConsumer':oe_get_interface()),
+ ?match(true, 'CosNotifyComm_SequencePullConsumer':oe_is_a('CosNotifyComm_SequencePullConsumer':typeID())),
+ ?match(true, 'CosNotifyComm_SequencePullConsumer':oe_is_a('CosNotifyComm_NotifyPublish':typeID())),
+ ?match(false, 'CosNotifyComm_SequencePullConsumer':oe_is_a("wrong")),
+ ok.
+
+
+%%-----------------------------------------------------------------
+%% Test Case: 'CosNotifyComm_SequencePullSupplier'
+%% Description:
+%%-----------------------------------------------------------------
+'CosNotifyComm_SequencePullSupplier'(doc) -> ["CosNotifyComm_SequencePullSupplier"];
+'CosNotifyComm_SequencePullSupplier'(suite) -> [];
+'CosNotifyComm_SequencePullSupplier'(_) ->
+ ?nomatch(undefined, 'CosNotifyComm_SequencePullSupplier':oe_tc(pull_structured_events)),
+ ?nomatch(undefined, 'CosNotifyComm_SequencePullSupplier':oe_tc(try_pull_structured_events)),
+ ?nomatch(undefined, 'CosNotifyComm_SequencePullSupplier':oe_tc(disconnect_sequence_pull_supplier)),
+ ?nomatch(undefined, 'CosNotifyComm_SequencePullSupplier':oe_tc(subscription_change)),
+ ?match(undefined, 'CosNotifyComm_SequencePullSupplier':oe_tc(undefined)),
+ ?match([_|_], 'CosNotifyComm_SequencePullSupplier':oe_get_interface()),
+ ?match("IDL:omg.org/CosNotifyComm/SequencePullSupplier:1.0",
+ 'CosNotifyComm_SequencePullSupplier':typeID()),
+ check_tc('CosNotifyComm_SequencePullSupplier':oe_get_interface()),
+ ?match(true, 'CosNotifyComm_SequencePullSupplier':oe_is_a('CosNotifyComm_SequencePullSupplier':typeID())),
+ ?match(true, 'CosNotifyComm_SequencePullSupplier':oe_is_a('CosNotifyComm_NotifySubscribe':typeID())),
+ ?match(false, 'CosNotifyComm_SequencePullSupplier':oe_is_a("wrong")),
+ ok.
+
+
+%%-----------------------------------------------------------------
+%% Test Case: 'CosNotifyComm_SequencePushConsumer'
+%% Description:
+%%-----------------------------------------------------------------
+'CosNotifyComm_SequencePushConsumer'(doc) -> ["CosNotifyComm_SequencePushConsumer"];
+'CosNotifyComm_SequencePushConsumer'(suite) -> [];
+'CosNotifyComm_SequencePushConsumer'(_) ->
+ ?nomatch(undefined, 'CosNotifyComm_SequencePushConsumer':oe_tc(push_structured_events)),
+ ?nomatch(undefined, 'CosNotifyComm_SequencePushConsumer':oe_tc(disconnect_sequence_push_consumer)),
+ ?nomatch(undefined, 'CosNotifyComm_SequencePushConsumer':oe_tc(offer_change)),
+ ?match(undefined, 'CosNotifyComm_SequencePushConsumer':oe_tc(undefined)),
+ ?match([_|_], 'CosNotifyComm_SequencePushConsumer':oe_get_interface()),
+ ?match("IDL:omg.org/CosNotifyComm/SequencePushConsumer:1.0",
+ 'CosNotifyComm_SequencePushConsumer':typeID()),
+ check_tc('CosNotifyComm_SequencePushConsumer':oe_get_interface()),
+ ?match(true, 'CosNotifyComm_SequencePushConsumer':oe_is_a('CosNotifyComm_SequencePushConsumer':typeID())),
+ ?match(true, 'CosNotifyComm_SequencePushConsumer':oe_is_a('CosNotifyComm_NotifyPublish':typeID())),
+ ?match(false, 'CosNotifyComm_SequencePushConsumer':oe_is_a("wrong")),
+ ok.
+
+
+%%-----------------------------------------------------------------
+%% Test Case: 'CosNotifyComm_SequencePushSupplier'
+%% Description:
+%%-----------------------------------------------------------------
+'CosNotifyComm_SequencePushSupplier'(doc) -> ["CosNotifyComm_SequencePushSupplier"];
+'CosNotifyComm_SequencePushSupplier'(suite) -> [];
+'CosNotifyComm_SequencePushSupplier'(_) ->
+ ?nomatch(undefined, 'CosNotifyComm_SequencePushSupplier':oe_tc(disconnect_sequence_push_supplier)),
+ ?nomatch(undefined, 'CosNotifyComm_SequencePushSupplier':oe_tc(subscription_change)),
+ ?match(undefined, 'CosNotifyComm_SequencePushSupplier':oe_tc(undefined)),
+ ?match([_|_], 'CosNotifyComm_SequencePushSupplier':oe_get_interface()),
+ ?match("IDL:omg.org/CosNotifyComm/SequencePushSupplier:1.0",
+ 'CosNotifyComm_SequencePushSupplier':typeID()),
+ check_tc('CosNotifyComm_SequencePushSupplier':oe_get_interface()),
+ ?match(true, 'CosNotifyComm_SequencePushSupplier':oe_is_a('CosNotifyComm_SequencePushSupplier':typeID())),
+ ?match(true, 'CosNotifyComm_SequencePushSupplier':oe_is_a('CosNotifyComm_NotifySubscribe':typeID())),
+ ?match(false, 'CosNotifyComm_SequencePushSupplier':oe_is_a("wrong")),
+ ok.
+
+
+%%-----------------------------------------------------------------
+%% Test Case: 'CosNotifyComm_StructuredPullConsumer'
+%% Description:
+%%-----------------------------------------------------------------
+'CosNotifyComm_StructuredPullConsumer'(doc) -> ["CosNotifyComm_StructuredPullConsumer"];
+'CosNotifyComm_StructuredPullConsumer'(suite) -> [];
+'CosNotifyComm_StructuredPullConsumer'(_) ->
+ ?nomatch(undefined, 'CosNotifyComm_StructuredPullConsumer':oe_tc(disconnect_structured_pull_consumer)),
+ ?nomatch(undefined, 'CosNotifyComm_StructuredPullConsumer':oe_tc(offer_change)),
+ ?match(undefined, 'CosNotifyComm_StructuredPullConsumer':oe_tc(undefined)),
+ ?match([_|_], 'CosNotifyComm_StructuredPullConsumer':oe_get_interface()),
+ ?match("IDL:omg.org/CosNotifyComm/StructuredPullConsumer:1.0",
+ 'CosNotifyComm_StructuredPullConsumer':typeID()),
+ check_tc('CosNotifyComm_StructuredPullConsumer':oe_get_interface()),
+ ?match(true, 'CosNotifyComm_StructuredPullConsumer':oe_is_a('CosNotifyComm_StructuredPullConsumer':typeID())),
+ ?match(true, 'CosNotifyComm_StructuredPullConsumer':oe_is_a('CosNotifyComm_NotifyPublish':typeID())),
+ ?match(false, 'CosNotifyComm_StructuredPullConsumer':oe_is_a("wrong")),
+ ok.
+
+
+%%-----------------------------------------------------------------
+%% Test Case: 'CosNotifyComm_StructuredPullSupplier'
+%% Description:
+%%-----------------------------------------------------------------
+'CosNotifyComm_StructuredPullSupplier'(doc) -> ["CosNotifyComm_StructuredPullSupplier"];
+'CosNotifyComm_StructuredPullSupplier'(suite) -> [];
+'CosNotifyComm_StructuredPullSupplier'(_) ->
+ ?nomatch(undefined, 'CosNotifyComm_StructuredPullSupplier':oe_tc(pull_structured_event)),
+ ?nomatch(undefined, 'CosNotifyComm_StructuredPullSupplier':oe_tc(try_pull_structured_event)),
+ ?nomatch(undefined, 'CosNotifyComm_StructuredPullSupplier':oe_tc(disconnect_structured_pull_supplier)),
+ ?nomatch(undefined, 'CosNotifyComm_StructuredPullSupplier':oe_tc(subscription_change)),
+ ?match(undefined, 'CosNotifyComm_StructuredPullSupplier':oe_tc(undefined)),
+ ?match([_|_], 'CosNotifyComm_StructuredPullSupplier':oe_get_interface()),
+ ?match("IDL:omg.org/CosNotifyComm/StructuredPullSupplier:1.0",
+ 'CosNotifyComm_StructuredPullSupplier':typeID()),
+ check_tc('CosNotifyComm_StructuredPullSupplier':oe_get_interface()),
+ ?match(true, 'CosNotifyComm_StructuredPullSupplier':oe_is_a('CosNotifyComm_StructuredPullSupplier':typeID())),
+ ?match(true, 'CosNotifyComm_StructuredPullSupplier':oe_is_a('CosNotifyComm_NotifySubscribe':typeID())),
+ ?match(false, 'CosNotifyComm_StructuredPullSupplier':oe_is_a("wrong")),
+ ok.
+
+
+%%-----------------------------------------------------------------
+%% Test Case: 'CosNotifyComm_StructuredPushConsumer'
+%% Description:
+%%-----------------------------------------------------------------
+'CosNotifyComm_StructuredPushConsumer'(doc) -> ["CosNotifyComm_StructuredPushConsumer"];
+'CosNotifyComm_StructuredPushConsumer'(suite) -> [];
+'CosNotifyComm_StructuredPushConsumer'(_) ->
+ ?nomatch(undefined, 'CosNotifyComm_StructuredPushConsumer':oe_tc(push_structured_event)),
+ ?nomatch(undefined, 'CosNotifyComm_StructuredPushConsumer':oe_tc(disconnect_structured_push_consumer)),
+ ?nomatch(undefined, 'CosNotifyComm_StructuredPushConsumer':oe_tc(offer_change)),
+ ?match(undefined, 'CosNotifyComm_StructuredPushConsumer':oe_tc(undefined)),
+ ?match([_|_], 'CosNotifyComm_StructuredPushConsumer':oe_get_interface()),
+ ?match("IDL:omg.org/CosNotifyComm/StructuredPushConsumer:1.0",
+ 'CosNotifyComm_StructuredPushConsumer':typeID()),
+ check_tc('CosNotifyComm_StructuredPushConsumer':oe_get_interface()),
+ ?match(true, 'CosNotifyComm_StructuredPushConsumer':oe_is_a('CosNotifyComm_StructuredPushConsumer':typeID())),
+ ?match(true, 'CosNotifyComm_StructuredPushConsumer':oe_is_a('CosNotifyComm_NotifyPublish':typeID())),
+ ?match(false, 'CosNotifyComm_StructuredPushConsumer':oe_is_a("wrong")),
+ ok.
+
+
+%%-----------------------------------------------------------------
+%% Test Case: 'CosNotifyComm_StructuredPushSupplier'
+%% Description:
+%%-----------------------------------------------------------------
+'CosNotifyComm_StructuredPushSupplier'(doc) -> ["CosNotifyComm_StructuredPushSupplier"];
+'CosNotifyComm_StructuredPushSupplier'(suite) -> [];
+'CosNotifyComm_StructuredPushSupplier'(_) ->
+ ?nomatch(undefined, 'CosNotifyComm_StructuredPushSupplier':oe_tc(disconnect_structured_push_supplier)),
+ ?nomatch(undefined, 'CosNotifyComm_StructuredPushSupplier':oe_tc(subscription_change)),
+ ?match(undefined, 'CosNotifyComm_StructuredPushSupplier':oe_tc(undefined)),
+ ?match([_|_], 'CosNotifyComm_StructuredPushSupplier':oe_get_interface()),
+ ?match("IDL:omg.org/CosNotifyComm/StructuredPushSupplier:1.0",
+ 'CosNotifyComm_StructuredPushSupplier':typeID()),
+ check_tc('CosNotifyComm_StructuredPushSupplier':oe_get_interface()),
+ ?match(true, 'CosNotifyComm_StructuredPushSupplier':oe_is_a('CosNotifyComm_StructuredPushSupplier':typeID())),
+ ?match(true, 'CosNotifyComm_StructuredPushSupplier':oe_is_a('CosNotifyComm_NotifySubscribe':typeID())),
+ ?match(false, 'CosNotifyComm_StructuredPushSupplier':oe_is_a("wrong")),
+ ok.
+
+
+%%-----------------------------------------------------------------
+%% Test Case: 'oe_CosNotificationComm_Event'
+%% Description:
+%%-----------------------------------------------------------------
+'oe_CosNotificationComm_Event'(doc) -> ["oe_CosNotificationComm_Event"];
+'oe_CosNotificationComm_Event'(suite) -> [];
+'oe_CosNotificationComm_Event'(_) ->
+ ?nomatch(undefined, 'oe_CosNotificationComm_Event':oe_tc(callSeq)),
+ ?nomatch(undefined, 'oe_CosNotificationComm_Event':oe_tc(callAny)),
+ ?match(undefined, 'oe_CosNotificationComm_Event':oe_tc(undefined)),
+ ?match([_|_], 'oe_CosNotificationComm_Event':oe_get_interface()),
+ ?match("IDL:oe_CosNotificationComm/Event:1.0",
+ 'oe_CosNotificationComm_Event':typeID()),
+ check_tc('oe_CosNotificationComm_Event':oe_get_interface()),
+ ?match(true, 'oe_CosNotificationComm_Event':oe_is_a('oe_CosNotificationComm_Event':typeID())),
+ ?match(false, 'oe_CosNotificationComm_Event':oe_is_a("wrong")),
+ ok.
+
+
+
+
+%%-----------------------------------------------------------------
+%% MISC functions
+%%-----------------------------------------------------------------
+check_tc([]) ->
+ ok;
+check_tc([{Op, {RetType, InParameters, OutParameters}}|T]) ->
+ io:format("checked - ~s~n", [Op]),
+ lists:all(?checktc(Op), [RetType|InParameters]),
+ lists:all(?checktc(Op), OutParameters),
+ check_tc(T).
+
+
diff --git a/lib/cosNotification/test/grammar_SUITE.erl b/lib/cosNotification/test/grammar_SUITE.erl
new file mode 100644
index 0000000000..30aec89e5f
--- /dev/null
+++ b/lib/cosNotification/test/grammar_SUITE.erl
@@ -0,0 +1,1094 @@
+%%--------------------------------------------------------------------
+%%
+%% %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%
+%%
+%%
+%%--------------------------------------------------------------------
+%% File : grammar_SUITE.erl
+%% Purpose : Testing the CosNotification BNF grammar.
+%%--------------------------------------------------------------------
+
+-module(grammar_SUITE).
+
+
+
+%%--------------- INCLUDES -----------------------------------
+-include_lib("orber/include/corba.hrl").
+-include_lib("orber/include/ifr_types.hrl").
+%% cosEvent files.
+-include_lib("cosEvent/include/CosEventChannelAdmin.hrl").
+%% Application files
+-include_lib("cosNotification/include/CosNotification.hrl").
+-include_lib("cosNotification/include/CosNotifyChannelAdmin.hrl").
+-include_lib("cosNotification/include/CosNotifyComm.hrl").
+-include_lib("cosNotification/include/CosNotifyFilter.hrl").
+
+-include_lib("cosNotification/src/CosNotification_Definitions.hrl").
+
+-include("idl_output/notify_test.hrl").
+
+-include("test_server.hrl").
+
+%%--------------- DEFINES ------------------------------------
+-define(default_timeout, ?t:minutes(20)).
+-define(match(ExpectedRes, Expr),
+ fun() ->
+ AcTuAlReS = (catch (Expr)),
+ case AcTuAlReS of
+ ExpectedRes ->
+ io:format("------ CORRECT RESULT ------~n~p~n",
+ [AcTuAlReS]),
+ AcTuAlReS;
+ _ ->
+ io:format("###### ERROR ERROR ######~n~p~n",
+ [AcTuAlReS]),
+ ?line exit(AcTuAlReS)
+ end
+ end()).
+
+%%-----------------------------------------------------------------
+%% External exports
+%%-----------------------------------------------------------------
+-export([all/1, cases/0, init_all/1, finish_all/1,
+ union_api/1, enum_api/1, simple_types_api/1,
+ components_api/1, positional_api/1, variable_api/1,
+ init_per_testcase/2, fin_per_testcase/2]).
+
+-import(cosNotification_Filter, [create_filter/1, eval/2]).
+
+%%-----------------------------------------------------------------
+%% Func: all/1
+%% Args:
+%% Returns:
+%%-----------------------------------------------------------------
+all(doc) -> ["API tests for the cosNotification interfaces", ""];
+all(suite) -> {req,
+ [],
+ {conf, init_all, cases(), finish_all}}.
+
+cases() ->
+ [variable_api, union_api, enum_api, simple_types_api, components_api,
+ positional_api].
+
+%%-----------------------------------------------------------------
+%% Init and cleanup functions.
+%%-----------------------------------------------------------------
+
+init_per_testcase(_Case, Config) ->
+ Path = code:which(?MODULE),
+ code:add_pathz(filename:join(filename:dirname(Path), "idl_output")),
+ ?line Dog=test_server:timetrap(?default_timeout),
+ [{watchdog, Dog}|Config].
+
+
+fin_per_testcase(_Case, Config) ->
+ Path = code:which(?MODULE),
+ code:del_path(filename:join(filename:dirname(Path), "idl_output")),
+ Dog = ?config(watchdog, Config),
+ test_server:timetrap_cancel(Dog),
+ ok.
+
+init_all(Config) ->
+ Path = code:which(?MODULE),
+ code:add_pathz(filename:join(filename:dirname(Path), "idl_output")),
+ if
+ is_list(Config) ->
+ Config;
+ true ->
+ exit("Config not a list")
+ end.
+
+finish_all(Config) ->
+ Path = code:which(?MODULE),
+ code:del_path(filename:join(filename:dirname(Path), "idl_output")),
+ Config.
+
+
+%%-----------------------------------------------------------------
+%% simple types grammar tests
+%%-----------------------------------------------------------------
+simple_types_api(doc) -> ["CosNotification simple types grammar tests", ""];
+simple_types_api(suite) -> [];
+simple_types_api(_Config) ->
+ %% Will always be true, no matter what kind of event we receive.
+ {ok,T1} = ?match({ok, _}, create_filter("2==2 and 3<4")),
+ ?match(true, eval(T1, ?not_CreateSE("DomainName","TypeName","EventName",
+ [],[], any:create(orber_tc:null(), null)))),
+
+ %% Will always be true, no matter what kind of event we receive.
+ {ok,T2} = ?match({ok, _}, create_filter("")),
+ ?match(true, eval(T2, ?not_CreateSE("DomainName","TypeName","EventName",
+ [],[], any:create(orber_tc:null(), null)))),
+
+ %% Check if $variable works
+ {ok,T3} = ?match({ok, _}, create_filter("$city == \'Berlin\'")),
+ ?match(true, eval(T3, ?not_CreateSE("DomainName","TypeName","EventName",
+ [#'CosNotification_Property'{name="city",
+ value=any:create(orber_tc:string(0), "Berlin")}],
+ [], any:create(orber_tc:null(), null)))),
+ ?match(false, eval(T3, ?not_CreateSE("DomainName","TypeName", "EventName",
+ [#'CosNotification_Property'{name="city",
+ value=any:create(orber_tc:string(0), "Dallas")}],
+
+ [], any:create(orber_tc:null(), null)))),
+
+
+ {ok,T4} = ?match({ok, _}, create_filter("$zip == 44")),
+ ?match(true, eval(T4, ?not_CreateSE("DomainName","TypeName", "EventName",
+ [#'CosNotification_Property'{name="zip",
+ value=any:create(orber_tc:short(), 44)}],
+
+ [], any:create(orber_tc:null(), null)))),
+ ?match(true, eval(T4, ?not_CreateSE("DomainName","TypeName", "EventName",
+ [],[],
+ any:create('CosNotification_Property':tc(),
+ #'CosNotification_Property'
+ {name="zip",
+ value=any:create(orber_tc:short(),
+ 44)})))),
+ ?match(false, eval(T4, ?not_CreateSE("DomainName","TypeName", "EventName",
+ [#'CosNotification_Property'{name="zip",
+ value=any:create(orber_tc:short(), 33)}],
+
+ [], any:create(orber_tc:null(), null)))),
+
+ %% Will always be true, no matter what kind of event we receive.
+ {ok,T5} = ?match({ok, _}, create_filter("\'oo'\~\'foobar\'")),
+ ?match(true, eval(T5, ?not_CreateSE("DomainName","TypeName","EventName",
+ [],[], any:create(orber_tc:null(), null)))),
+ %% Will always be false, no matter what kind of event we receive.
+ {ok,T6} = ?match({ok, _}, create_filter("\'o1'\~\'foobar\'")),
+ ?match(false, eval(T6, ?not_CreateSE("DomainName","TypeName","EventName",
+ [],[], any:create(orber_tc:null(), null)))),
+
+ %% Can we apply the ~ operation as above using a variable
+ {ok,T7} = ?match({ok, _}, create_filter("$str~\'foobar\'")),
+ ?match(true, eval(T7, ?not_CreateSE("DomainName","TypeName","EventName",
+ [#'CosNotification_Property'{name="str",
+ value=any:create(orber_tc:string(0), "oo")}],
+ [], any:create(orber_tc:null(), null)))),
+ ?match(false, eval(T7, ?not_CreateSE("DomainName","TypeName","EventName",
+ [#'CosNotification_Property'{name="str",
+ value=any:create(orber_tc:string(0), "ok")}],
+ [], any:create(orber_tc:null(), null)))),
+
+
+
+ {ok,_T8} = ?match({ok, _}, create_filter("$\\zip == 44444")),
+
+ ok.
+
+%%-----------------------------------------------------------------
+%% enum grammar tests
+%%-----------------------------------------------------------------
+enum_api(doc) -> ["CosNotification enum grammar tests", ""];
+enum_api(suite) -> [];
+enum_api(_Config) ->
+ %% Accept events whose 'in' enum is set to the value 'HOUSE' or 'CAR'.
+ {ok,T1} = ?match({ok, _}, create_filter("$.\\in == HOUSE or $.\\in == CAR")),
+
+ ?match(true, eval(T1, any:create(orber_tc:alias("IFRId","in",tk_any),
+ any:create({tk_enum, "IFRId", "in", ["HOUSE", "CAR"]},
+ 'HOUSE')))),
+ ?match(false, eval(T1, any:create(orber_tc:alias("IFRId","in",tk_any),
+ any:create({tk_enum, "IFRId", "in", ["HOUSE", "CAR"]},
+ 'GARAGE')))),
+ ok.
+
+
+%%-----------------------------------------------------------------
+%% Union grammar tests
+%%-----------------------------------------------------------------
+union_api(doc) -> ["CosNotification union grammar tests", ""];
+union_api(suite) -> [];
+union_api(_Config) ->
+ {ok,T1} = ?match({ok, _}, create_filter("exist $.uni1._d and $.uni1._d == 1 and $.uni1.(1) == 10")),
+ {ok,T2} = ?match({ok, _}, create_filter("default $.uni1._d and $.uni1.() == 10")),
+ {ok,T3} = ?match({ok, _}, create_filter("default $.uni1._d and $.uni1.(999) == 10")),
+ ?match(true, eval(T1, ?not_CreateSE("DomainName","CommunicationsAlarm",
+ "EventName",[],[],
+ any:create(orber_tc:alias("IDL:notify_test/namedAny:1.0",
+ "uni1",
+ tk_any),
+ any:create(notify_test_uni1:tc(),
+ #notify_test_uni1{label= 1,
+ value=10}))))),
+ ?match(true, eval(T2, ?not_CreateSE("DomainName","CommunicationsAlarm",
+ "EventName",[],[],
+ any:create(orber_tc:alias("IDL:notify_test/namedAny:1.0",
+ "uni1",
+ tk_any),
+ any:create(notify_test_uni1:tc(),
+ #notify_test_uni1{label= 100,
+ value=10}))))),
+ ?match(true, eval(T3, ?not_CreateSE("DomainName","CommunicationsAlarm",
+ "EventName",[],[],
+ any:create(orber_tc:alias("IDL:notify_test/namedAny:1.0",
+ "uni1",
+ tk_any),
+ any:create(notify_test_uni1:tc(),
+ #notify_test_uni1{label= 100,
+ value=10}))))),
+ ?match(true, eval(T1, any:create(orber_tc:alias("IDL:notify_test/namedAny:1.0",
+ "uni1",
+ tk_any),
+ any:create(notify_test_uni1:tc(),
+ #notify_test_uni1{label= 1,
+ value=10})))),
+ ?match(false, eval(T2, any:create(orber_tc:alias("IDL:notify_test/namedAny:1.0",
+ "uni1",
+ tk_any),
+ any:create(notify_test_uni1:tc(),
+ #notify_test_uni1{label= 1,
+ value=10})))),
+ ?match(false, eval(T3, any:create(orber_tc:alias("IDL:notify_test/namedAny:1.0",
+ "uni1",
+ tk_any),
+ any:create(notify_test_uni1:tc(),
+ #notify_test_uni1{label= 1,
+ value=10})))),
+ ?match(true, eval(T1, ?not_CreateSE("DomainName","CommunicationsAlarm",
+ "EventName",[],[],
+ any:create(notify_test_studies:tc(), #notify_test_studies
+ {uni1 = #notify_test_uni1{label= 1, value=10},
+ gpa = 90,
+ tests = [#'CosNotification_Property'
+ {name="midterm", value=any:create(orber_tc:short(), 70)},
+ #'CosNotification_Property'
+ {name="final", value=any:create(orber_tc:short(), 60)}],
+ monthly_attendance = {0,1,2,10}})))),
+ ?match(false, eval(T2, ?not_CreateSE("DomainName","CommunicationsAlarm",
+ "EventName",[],[],
+ any:create(notify_test_studies:tc(), #notify_test_studies
+ {uni1 = #notify_test_uni1{label= 1, value=10},
+ gpa = 90,
+ tests = [#'CosNotification_Property'
+ {name="midterm", value=any:create(orber_tc:short(), 70)},
+ #'CosNotification_Property'
+ {name="final", value=any:create(orber_tc:short(), 60)}],
+ monthly_attendance = {0,1,2,10}})))),
+ ?match(false, eval(T3, ?not_CreateSE("DomainName","CommunicationsAlarm",
+ "EventName",[],[],
+ any:create(notify_test_studies:tc(), #notify_test_studies
+ {uni1 = #notify_test_uni1{label= 1, value=10},
+ gpa = 90,
+ tests = [#'CosNotification_Property'
+ {name="midterm", value=any:create(orber_tc:short(), 70)},
+ #'CosNotification_Property'
+ {name="final", value=any:create(orber_tc:short(), 60)}],
+ monthly_attendance = {0,1,2,10}})))),
+ ?match(true, eval(T1, any:create(notify_test_studies:tc(), #notify_test_studies
+ {uni1 = #notify_test_uni1{label= 1, value=10},
+ gpa = 90,
+ tests = [#'CosNotification_Property'
+ {name="midterm", value=any:create(orber_tc:short(), 70)},
+ #'CosNotification_Property'
+ {name="final", value=any:create(orber_tc:short(), 60)}],
+ monthly_attendance = {0,1,2,10}}))),
+ ?match(false, eval(T2, any:create(notify_test_studies:tc(), #notify_test_studies
+ {uni1 = #notify_test_uni1{label= 1, value=10},
+ gpa = 90,
+ tests = [#'CosNotification_Property'
+ {name="midterm", value=any:create(orber_tc:short(), 70)},
+ #'CosNotification_Property'
+ {name="final", value=any:create(orber_tc:short(), 60)}],
+ monthly_attendance = {0,1,2,10}}))),
+ ?match(false, eval(T3, any:create(notify_test_studies:tc(), #notify_test_studies
+ {uni1 = #notify_test_uni1{label= 1, value=10},
+ gpa = 90,
+ tests = [#'CosNotification_Property'
+ {name="midterm", value=any:create(orber_tc:short(), 70)},
+ #'CosNotification_Property'
+ {name="final", value=any:create(orber_tc:short(), 60)}],
+ monthly_attendance = {0,1,2,10}}))),
+
+ {ok,T4} = ?match({ok, _}, create_filter("exist $.alias.uni1._d and $.alias.uni1._d == 1 and $.alias.uni1.(1) == 10")),
+ ?match(true, eval(T4, ?not_CreateSE("DomainName","CommunicationsAlarm",
+ "EventName",[],[],
+ any:create(orber_tc:alias(notify_test_studies:id(),
+ "alias",
+ notify_test_studies:tc()),
+ #notify_test_studies
+ {uni1 = #notify_test_uni1{label= 1, value=10},
+ gpa = 90, tests = [],
+ monthly_attendance = {0,1,2,10}})))),
+ ?match(true, eval(T4, any:create(orber_tc:alias(notify_test_studies:id(),
+ "alias",
+ notify_test_studies:tc()),
+ #notify_test_studies
+ {uni1 = #notify_test_uni1{label= 1, value=10},
+ gpa = 90, tests = [],
+ monthly_attendance = {0,1,2,10}}))),
+ %% Accept events with a default union discriminator set to the value 2.
+ {ok,T5} = ?match({ok, _}, create_filter("default $._d and $.defvalue == 2")),
+ ?match(true, eval(T5, any:create(notify_test_uni1:tc(),
+ #notify_test_uni1{label= 100, value=2}))),
+ %% label not default.
+ ?match(false, eval(T5, any:create(notify_test_uni1:tc(),
+ #notify_test_uni1{label= 2, value=2}))),
+ %% Default does not exist (nor the component defvalue)
+ ?match(false, eval(T5, any:create(notify_test_uni2:tc(),
+ #notify_test_uni2{label= 100, value=2}))),
+ %% Both wrong
+ ?match(false, eval(T5, any:create(notify_test_uni2:tc(),
+ #notify_test_uni2{label= 2, value=2}))),
+
+ {ok,T6} = ?match({ok, _}, create_filter("default $._d and $.(-8) == 2")),
+ ?match(true, eval(T6, any:create(notify_test_uni1:tc(),
+ #notify_test_uni1{label= 100, value=2}))),
+ %% label not default.
+ ?match(false, eval(T6, any:create(notify_test_uni1:tc(),
+ #notify_test_uni1{label= 2, value=2}))),
+ %% Default does not exist (nor the component defvalue)
+ ?match(false, eval(T6, any:create(notify_test_uni2:tc(),
+ #notify_test_uni2{label= 100, value=2}))),
+ %% Both wrong
+ ?match(false, eval(T6, any:create(notify_test_uni2:tc(),
+ #notify_test_uni2{label= 2, value=2}))),
+ %% the same as the above, but we try to access a label that is not default
+ {ok,T7} = ?match({ok, _}, create_filter("default $._d and $.(2) == 2")),
+ ?match({error, _}, eval(T7, any:create(notify_test_uni1:tc(),
+ #notify_test_uni1{label= 100, value=2}))),
+
+ %% Must be a default-union with its 'defvalue' set to 2.
+ {ok,T8} = ?match({ok, _}, create_filter("default $._d and $.('defvalue') == 2")),
+ ?match(true, eval(T8, any:create(notify_test_uni1:tc(),
+ #notify_test_uni1{label= 100, value=2}))),
+ %% label not default.
+ ?match(false, eval(T8, any:create(notify_test_uni1:tc(),
+ #notify_test_uni1{label= 2, value=2}))),
+ %% Default does not exist (nor the component defvalue)
+ ?match(false, eval(T8, any:create(notify_test_uni2:tc(),
+ #notify_test_uni2{label= 100, value=2}))),
+ %% Both wrong
+ ?match(false, eval(T8, any:create(notify_test_uni2:tc(),
+ #notify_test_uni2{label= 2, value=2}))),
+
+ %% Must be a default-union with its value set to 2.
+ {ok,T9} = ?match({ok, _}, create_filter("default $._d and $.(+100) == 2")),
+ ?match(true, eval(T9, any:create(notify_test_uni1:tc(),
+ #notify_test_uni1{label= 100, value=2}))),
+ %% label not default.
+ ?match(false, eval(T9, any:create(notify_test_uni1:tc(),
+ #notify_test_uni1{label= 2, value=2}))),
+ %% Default does not exist (nor the component defvalue)
+ ?match(false, eval(T9, any:create(notify_test_uni2:tc(),
+ #notify_test_uni2{label= 100, value=2}))),
+ %% Both wrong
+ ?match(false, eval(T9, any:create(notify_test_uni2:tc(),
+ #notify_test_uni2{label= 2, value=2}))),
+
+ %% So far, we have only tested to access the union itself. No will use more
+ %% complex union members.
+ %% T10 and T11 is "equal"
+ {ok,T10} = ?match({ok, _}, create_filter("$.M < 54")),
+ {ok,T11} = ?match({ok, _}, create_filter("$.(5) < 54")),
+ ?match(false, eval(T10, any:create(notify_test_K:tc(),
+ #notify_test_K{label= 5, value=54}))),
+ ?match(false, eval(T11, any:create(notify_test_K:tc(),
+ #notify_test_K{label= 5, value=54}))),
+ ?match(true, eval(T10, any:create(notify_test_K:tc(),
+ #notify_test_K{label= 5, value=50}))),
+ ?match(true, eval(T11, any:create(notify_test_K:tc(),
+ #notify_test_K{label= 5, value=50}))),
+ ?match({error,_}, eval(T10, any:create(notify_test_K:tc(),
+ #notify_test_K{label= -1, value=50}))),
+ ?match({error,_}, eval(T11, any:create(notify_test_K:tc(),
+ #notify_test_K{label= -1, value=50}))),
+
+ %% T12 and T13 is "equal"
+ {ok,T12} = ?match({ok, _}, create_filter("$.L.C < 128")),
+ {ok,T13} = ?match({ok, _}, create_filter("$.(3).2 < 128")),
+ ?match(true, eval(T12, any:create(notify_test_K:tc(),
+ #notify_test_K{label= 3, value=
+ #notify_test_X{'A' = 1,
+ 'B' = "string",
+ 'C' = 120}}))),
+ ?match(true, eval(T13, any:create(notify_test_K:tc(),
+ #notify_test_K{label= 3, value=
+ #notify_test_X{'A' = 1,
+ 'B' = "string",
+ 'C' = 120}}))),
+ ?match(false, eval(T12, any:create(notify_test_K:tc(),
+ #notify_test_K{label= 3, value=
+ #notify_test_X{'A' = 1,
+ 'B' = "string",
+ 'C' = 200}}))),
+ ?match(false, eval(T13, any:create(notify_test_K:tc(),
+ #notify_test_K{label= 3, value=
+ #notify_test_X{'A' = 1,
+ 'B' = "string",
+ 'C' = 200}}))),
+
+ %% Test if 'putty' is a substring of K
+ {ok,T15} = ?match({ok, _}, create_filter("'putty' ~ $.(2)")),
+ {ok,T16} = ?match({ok, _}, create_filter("'putty' ~ $.K")),
+ ?match(true, eval(T15, any:create(notify_test_K:tc(),
+ #notify_test_K{label= 2, value= "isputtyok"}))),
+ ?match(true, eval(T16, any:create(notify_test_K:tc(),
+ #notify_test_K{label= 2, value= "isputtyok"}))),
+ ?match(false, eval(T15, any:create(notify_test_K:tc(),
+ #notify_test_K{label= 2, value= "notputtok"}))),
+ ?match(false, eval(T16, any:create(notify_test_K:tc(),
+ #notify_test_K{label= 2, value= "notputtok"}))),
+
+ {ok,_T17} = ?match({ok, _}, create_filter("'putty' ~ $.(3).1")),
+ {ok,_T18} = ?match({ok, _}, create_filter("'putty' ~ $.L.B")),
+ ?match(true, eval(T12, any:create(notify_test_K:tc(),
+ #notify_test_K{label= 3, value=
+ #notify_test_X{'A' = 1,
+ 'B' = "isputtyok",
+ 'C' = 120}}))),
+ ?match(true, eval(T13, any:create(notify_test_K:tc(),
+ #notify_test_K{label= 3, value=
+ #notify_test_X{'A' = 1,
+ 'B' = "isputtyok",
+ 'C' = 120}}))),
+ ?match(false, eval(T12, any:create(notify_test_K:tc(),
+ #notify_test_K{label= 3, value=
+ #notify_test_X{'A' = 1,
+ 'B' = "notputtok",
+ 'C' = 200}}))),
+ ?match(false, eval(T13, any:create(notify_test_K:tc(),
+ #notify_test_K{label= 3, value=
+ #notify_test_X{'A' = 1,
+ 'B' = "notputtok",
+ 'C' = 200}}))),
+
+ %% Please observe that the switch 0 and 2 is defined to be equivalent.
+ {ok,T19} = ?match({ok, _}, create_filter("$._d == 2 and $.(0) != 'hoob'")),
+ {ok,T20} = ?match({ok, _}, create_filter("$._d == 2 and $.(2) != 'hoob'")),
+ ?match(true, eval(T19, any:create(notify_test_K:tc(),
+ #notify_test_K{label= 2, value= "nothoob"}))),
+ ?match(true, eval(T20, any:create(notify_test_K:tc(),
+ #notify_test_K{label= 2, value= "nothoob"}))),
+ ?match(false, eval(T19, any:create(notify_test_K:tc(),
+ #notify_test_K{label= 2, value= "hoob"}))),
+ ?match(false, eval(T20, any:create(notify_test_K:tc(),
+ #notify_test_K{label= 2, value= "hoob"}))),
+
+ ?match(false, eval(T19, any:create(notify_test_K:tc(),
+ #notify_test_K{label= 5, value= 55}))),
+ ?match(false, eval(T20, any:create(notify_test_K:tc(),
+ #notify_test_K{label= 5, value= 55}))),
+
+ ?match(false, eval(T19, any:create(notify_test_K:tc(),
+ #notify_test_K{label= 100, value= "nothoob"}))),
+ ?match(false, eval(T20, any:create(notify_test_K:tc(),
+ #notify_test_K{label= 100, value= "nothoob"}))),
+
+ {ok,T21} = ?match({ok, _}, create_filter("exist $.K")),
+ {ok,T22} = ?match({ok, _}, create_filter("exist $.(0) or exist $.(2)")),
+ ?match(true, eval(T21, any:create(notify_test_K:tc(),
+ #notify_test_K{label= 0, value= "hoob"}))),
+ ?match(true, eval(T22, any:create(notify_test_K:tc(),
+ #notify_test_K{label= 0, value= "hoob"}))),
+ ?match(true, eval(T21, any:create(notify_test_K:tc(),
+ #notify_test_K{label= 2, value= "hoob"}))),
+ ?match(true, eval(T22, any:create(notify_test_K:tc(),
+ #notify_test_K{label= 2, value= "hoob"}))),
+ ?match(false, eval(T21, any:create(notify_test_K:tc(),
+ #notify_test_K{label= 5, value= 55}))),
+ ?match(false, eval(T22, any:create(notify_test_K:tc(),
+ #notify_test_K{label= 5, value= 55}))),
+
+
+ %% Please observe that the switch 0 and 2 is defined to be equivalent.
+ {ok,T23} = ?match({ok, _}, create_filter("exist $.(2)")),
+ {ok,T24} = ?match({ok, _}, create_filter("exist $.(0)")),
+ ?match(true, eval(T23, any:create(notify_test_K:tc(),
+ #notify_test_K{label= 2, value= "hoob"}))),
+ ?match(false, eval(T24, any:create(notify_test_K:tc(),
+ #notify_test_K{label= 2, value= "hoob"}))),
+ ?match(false, eval(T23, any:create(notify_test_K:tc(),
+ #notify_test_K{label= 0, value= "hoob"}))),
+ ?match(true, eval(T24, any:create(notify_test_K:tc(),
+ #notify_test_K{label= 0, value= "hoob"}))),
+ ?match(false, eval(T23, any:create(notify_test_K:tc(),
+ #notify_test_K{label= 5, value= 55}))),
+ ?match(false, eval(T24, any:create(notify_test_K:tc(),
+ #notify_test_K{label= 5, value= 55}))),
+
+ ok.
+
+%%-----------------------------------------------------------------
+%% Variables grammar tests
+%%-----------------------------------------------------------------
+variable_api(doc) -> ["CosNotification variables grammar tests", ""];
+variable_api(suite) -> [];
+variable_api(_Config) ->
+ %% Accept all "CommunicationsAlarm" events
+ {ok,T0} = ?match({ok, _}, create_filter("$type_name == 'CommunicationsAlarm'")),
+
+ ?match(true, eval(T0, ?not_CreateSE("DomainName","CommunicationsAlarm",
+ "EventName",[],[],
+ any:create(orber_tc:null(), null)))),
+ ?match(false, eval(T0, ?not_CreateSE("DomainName","CommunicationsOK",
+ "EventName", [],[],
+ any:create(orber_tc:null(), null)))),
+ ?match(true, eval(T0, ?not_CreateSE("DomainName","CommunicationsAlarm",
+ "EventName", [],[],
+ any:create(orber_tc:alias("IFRId", "type_name",
+ orber_tc:string(0)),
+ "CommunicationsOK")))),
+
+ ?match(true, eval(T0, any:create(orber_tc:alias("IFRId", "type_name",
+ orber_tc:string(0)),
+ "CommunicationsAlarm"))),
+ ?match(false, eval(T0, any:create(orber_tc:alias("IFRId", "type_name",
+ orber_tc:string(0)),
+ "CommunicationsOK"))),
+
+
+ %% Accept all "CommunicationsAlarm" events but no "lost_packet" messages.
+ {ok,T1} = ?match({ok, _}, create_filter("$type_name == 'CommunicationsAlarm' and not ($event_name == 'lost_packet')")),
+
+ ?match(true, eval(T1, ?not_CreateSE("DomainName","CommunicationsAlarm",
+ "EventName",[],[],
+ any:create(orber_tc:null(), null)))),
+ ?match(false, eval(T1, ?not_CreateSE("DomainName","CommunicationsAlarm",
+ "lost_packet", [],[],
+ any:create(orber_tc:null(), null)))),
+ ?match(true,
+ eval(T1, any:create(orber_tc:sequence('CosNotification_Property':tc(),0),
+ [#'CosNotification_Property'{name="type_name",
+ value=any:create(orber_tc:string(0), "CommunicationsAlarm")},
+ #'CosNotification_Property'{name="event_name",
+ value=any:create(orber_tc:string(0), "EventName")}]))),
+ ?match(false,
+ eval(T1, any:create(orber_tc:sequence('CosNotification_Property':tc(),0),
+ [#'CosNotification_Property'{name="type_name",
+ value=any:create(orber_tc:string(0), "CommunicationsAlarm")},
+ #'CosNotification_Property'{name="event_name",
+ value=any:create(orber_tc:string(0), "lost_packet")}]))),
+
+
+ %% Accept "CommunicationsAlarm" events with priorities ranging from 1 to 5.
+ {ok,T2} = ?match({ok, _}, create_filter("$type_name == 'CommunicationsAlarm' and $priority >= 1 and $priority <= 5")),
+ ?match(true, eval(T2, ?not_CreateSE("DomainName","CommunicationsAlarm",
+ "EventName",
+ [#'CosNotification_Property'{name="priority",
+ value=any:create(orber_tc:short(), 2)}],
+ [], any:create(orber_tc:null(), null)))),
+ ?match(false, eval(T2, ?not_CreateSE("DomainName","CommunicationsAlarm",
+ "EventName",
+ [#'CosNotification_Property'{name="priority",
+ value=any:create(orber_tc:short(), 20)}],
+ [], any:create(orber_tc:null(), null)))),
+
+ %% Select "MOVIE" events featuring at least 3 of the Marx Brothers.
+ {ok,T3} = ?match({ok, _}, create_filter("$type_name == 'MOVIE' and (('groucho' in $starlist) + ('chico' in $starlist) + ('harpo' in $starlist) + ('zeppo' in $starlist) + ('gummo' in $starlist)) > 2")),
+ ?match(true, eval(T3, ?not_CreateSE("DomainName","MOVIE",
+ "EventName",
+ [#'CosNotification_Property'{name="starlist",
+ value=any:create(orber_tc:sequence(orber_tc:string(0),0),
+ ["groucho", "harpo", "sam", "gummo"])}],
+ [], any:create(orber_tc:null(), null)))),
+ ?match(false, eval(T3, ?not_CreateSE("DomainName","MOVIE",
+ "EventName",
+ [#'CosNotification_Property'{name="starlist",
+ value=any:create(orber_tc:sequence(orber_tc:string(0),0),
+ ["frodo", "bilbo", "sam", "gummo"])}],
+ [], any:create(orber_tc:null(), null)))),
+ %% Accept students that took all 3 tests and had an average score of at least 80%.
+ {ok,T4} = ?match({ok, _}, create_filter("$test._length == 3 and ($test[0].score + $test[1].score + $test[2].score)/3 >=80")),
+ ?match(true, eval(T4, ?not_CreateSE("DomainName","TypeName",
+ "EventName", [],
+ [#'CosNotification_Property'{name="test",
+ value=any:create(orber_tc:array(notify_test_data:tc(),0),
+ {#notify_test_data{score=75},
+ #notify_test_data{score=80},
+ #notify_test_data{score=85}})}],
+ any:create(orber_tc:null(), null)))),
+ ?match(false, eval(T4, ?not_CreateSE("DomainName","TypeName",
+ "EventName", [],
+ [#'CosNotification_Property'{name="test",
+ value=any:create(orber_tc:array(notify_test_data:tc(),0),
+ {#notify_test_data{score=75},
+ #notify_test_data{score=80},
+ #notify_test_data{score=80}})}],
+ any:create(orber_tc:null(), null)))),
+ ?match(false, eval(T4, ?not_CreateSE("DomainName","TypeName",
+ "EventName", [],
+ [#'CosNotification_Property'{name="test",
+ value=any:create(orber_tc:array(notify_test_data:tc(),0),
+ {#notify_test_data{score=75},
+ #notify_test_data{score=85}})}],
+ any:create(orber_tc:null(), null)))),
+ %% Select processes that exceed a certain usage threshold.
+ {ok,T5} = ?match({ok, _}, create_filter("$memsize / 5.5 + $cputime * 1275.0 + $filesize * 1.25 > 500000.0")),
+ ?match(true, eval(T5, ?not_CreateSE("DomainName","TypeName",
+ "EventName", [],
+ [#'CosNotification_Property'{name="memsize",
+ value=any:create(orber_tc:float(), 5.5)},
+ #'CosNotification_Property'{name="cputime",
+ value=any:create(orber_tc:float(), 0.00078431137)},
+ #'CosNotification_Property'{name="filesize",
+ value=any:create(orber_tc:float(), 500000)}],
+ any:create(orber_tc:null(), null)))),
+ ?match(false, eval(T5, ?not_CreateSE("DomainName","TypeName",
+ "EventName", [],
+ [#'CosNotification_Property'{name="memsize",
+ value=any:create(orber_tc:float(), 5.5)},
+ #'CosNotification_Property'{name="cputime",
+ value=any:create(orber_tc:float(), 0.00078431137)},
+ #'CosNotification_Property'{name="filesize",
+ value=any:create(orber_tc:float(), 500)}],
+ any:create(orber_tc:null(), null)))),
+ ?match({error, _}, eval(T5, ?not_CreateSE("DomainName","TypeName",
+ "EventName", [],
+ [#'CosNotification_Property'{name="memsize",
+ value=any:create(orber_tc:float(), 5.5)},
+ #'CosNotification_Property'{name="filesize",
+ value=any:create(orber_tc:float(), 500)}],
+ any:create(orber_tc:null(), null)))),
+
+ ?match(true, eval(T5, ?not_CreateSE("DomainName","TypeName",
+ "EventName", [], [],
+ any:create(orber_tc:sequence('CosNotification_Property':tc(),0),
+ [#'CosNotification_Property'{name="memsize",
+ value=any:create(orber_tc:float(), 5.5)},
+ #'CosNotification_Property'{name="cputime",
+ value=any:create(orber_tc:float(), 0.00078431137)},
+ #'CosNotification_Property'{name="filesize",
+ value=any:create(orber_tc:float(), 500000)}])))),
+ ?match(false, eval(T5, ?not_CreateSE("DomainName","TypeName",
+ "EventName", [], [],
+ any:create(orber_tc:sequence('CosNotification_Property':tc(),0),
+ [#'CosNotification_Property'{name="memsize",
+ value=any:create(orber_tc:float(), 5.5)},
+ #'CosNotification_Property'{name="cputime",
+ value=any:create(orber_tc:float(), 0.00078431137)},
+ #'CosNotification_Property'{name="filesize",
+ value=any:create(orber_tc:float(), 500)}])))),
+ ?match({error, _}, eval(T5, ?not_CreateSE("DomainName","TypeName",
+ "EventName", [], [],
+ any:create(orber_tc:sequence('CosNotification_Property':tc(),0),
+ [#'CosNotification_Property'{name="memsize",
+ value=any:create(orber_tc:float(), 5.5)},
+ #'CosNotification_Property'{name="filesize",
+ value=any:create(orber_tc:float(), 500)}])))),
+
+ ?match(true, eval(T5, any:create(orber_tc:sequence('CosNotification_Property':tc(),0),
+ [#'CosNotification_Property'{name="memsize",
+ value=any:create(orber_tc:float(), 5.5)},
+ #'CosNotification_Property'{name="cputime",
+ value=any:create(orber_tc:float(), 0.00078431137)},
+ #'CosNotification_Property'{name="filesize",
+ value=any:create(orber_tc:float(), 500000)}]))),
+ ?match(false, eval(T5, any:create(orber_tc:sequence('CosNotification_Property':tc(),0),
+ [#'CosNotification_Property'{name="memsize",
+ value=any:create(orber_tc:float(), 5.5)},
+ #'CosNotification_Property'{name="cputime",
+ value=any:create(orber_tc:float(), 0.00078431137)},
+ #'CosNotification_Property'{name="filesize",
+ value=any:create(orber_tc:float(), 500)}]))),
+ ?match({error, _}, eval(T5, any:create(orber_tc:sequence('CosNotification_Property':tc(),0),
+ [#'CosNotification_Property'{name="memsize",
+ value=any:create(orber_tc:float(), 5.5)},
+ #'CosNotification_Property'{name="filesize",
+ value=any:create(orber_tc:float(), 500)}]))),
+
+ %% Accept events where a threshold has the unscoped type name 'data'.
+ {ok,T6} = ?match({ok, _}, create_filter("exist $threshold._type_id and $threshold._type_id == 'data'")),
+ ?match(true, eval(T6, any:create(orber_tc:alias(notify_test_data:id(),
+ "threshold",
+ notify_test_data:tc()),
+ #notify_test_data{score = 10, name = "Erlang"}))),
+
+
+
+ ?match(true, eval(T6, ?not_CreateSE("DomainName","TypeName",
+ "EventName", [],
+ [#'CosNotification_Property'
+ {name="threshold",
+ value=any:create(notify_test_data:tc(),
+ #notify_test_data
+ {score = 10,
+ name = "Erlang"})}],
+ any:create(orber_tc:null(), null)))),
+
+
+ ?match(true, eval(T6, ?not_CreateSE("DomainName","TypeName",
+ "EventName", [],
+ [#'CosNotification_Property'
+ {name="NotThreshold",
+ value=any:create(notify_test_data:tc(),
+ #notify_test_data
+ {score = 10,
+ name = "Erlang"})}],
+ any:create(orber_tc:alias(notify_test_data:id(),
+ "threshold",
+ notify_test_data:tc()),
+ #notify_test_data{score = 10, name = "Erlang"})))),
+
+
+
+ %% Accept events with a serviceUser property of the correct standard type.
+ {ok,T7} = ?match({ok, _}, create_filter("$violation(TestData)._repos_id == 'IDL:notify_test/data:1.0'")),
+ ?match(true, eval(T7, ?not_CreateSE("DomainName","TypeName",
+ "EventName", [],
+ [#'CosNotification_Property'
+ {name="violation",
+ value=any:create(orber_tc:array('CosNotification_Property':tc(),0),
+ [#'CosNotification_Property'
+ {name="TestData",
+ value=any:create(notify_test_data:tc(),
+ #notify_test_data
+ {score=100,
+ name="perfect score"})}])}],
+ any:create(orber_tc:null(), null)))),
+
+ {ok,T8} = ?match({ok, _}, create_filter("$type_name == 'CommunicationsAlarm' and $event_name == 'lost_packet' and $priority < 2")),
+ %% All correct
+ Event1 = ?not_CreateSE("DomainName","CommunicationsAlarm",
+ "lost_packet",
+ [#'CosNotification_Property'{name="priority",
+ value=any:create(orber_tc:short(), 1)}],
+ [], any:create(orber_tc:null(), null)),
+ %% Priority to high
+ Event2 = ?not_CreateSE("DomainName","CommunicationsAlarm",
+ "lost_packet",
+ [#'CosNotification_Property'{name="priority",
+ value=any:create(orber_tc:short(), 2)}],
+ [], any:create(orber_tc:null(), null)),
+ %% Misspell event_name, i.e., lost_packets instead of lost_packet
+ Event3 = ?not_CreateSE("DomainName","CommunicationsAlarm",
+ "lost_packets",
+ [#'CosNotification_Property'{name="priority",
+ value=any:create(orber_tc:short(), 1)}],
+ [], any:create(orber_tc:null(), null)),
+ %% Another type_name
+ Event4 = ?not_CreateSE("DomainName","TemperatureAlarm",
+ "lost_packets",
+ [#'CosNotification_Property'{name="priority",
+ value=any:create(orber_tc:short(), 1)}],
+ [], any:create(orber_tc:null(), null)),
+
+ ?match(true, eval(T8, Event1)),
+ ?match(false, eval(T8, Event2)),
+ ?match(false, eval(T8, Event3)),
+ ?match(false, eval(T8, Event4)),
+
+ {ok,T9} = ?match({ok, _}, create_filter("$gpa < 80 or $tests(midterm) > $tests(final) or $monthly_attendance[3] < 10")),
+
+ %% midterm > final yields true, the others false
+ Event5 = ?not_CreateSE("DomainName","TypeName",
+ "EventName", [],
+ [#'CosNotification_Property'
+ {name="tests",
+ value=any:create(orber_tc:array('CosNotification_Property':tc(),0),
+ [#'CosNotification_Property'{name="midterm",
+ value=any:create(orber_tc:short(), 70)},
+ #'CosNotification_Property'{name="final",
+ value=any:create(orber_tc:short(), 60)}])},
+ #'CosNotification_Property'{name="monthly_attendance",
+ value=any:create(orber_tc:array(orber_tc:short(), 0),
+ {0,1,2,10})},
+ #'CosNotification_Property'{name="gpa",
+ value=any:create(orber_tc:short(), 90)}],
+ any:create(orber_tc:null(), null)),
+
+ %% monthly_attendance[3] < 10 yields true, the others false
+ Event6 = ?not_CreateSE("DomainName","TypeName",
+ "EventName", [],
+ [#'CosNotification_Property'{name="tests",
+ value=any:create(orber_tc:array('CosNotification_Property':tc(),0),
+ [#'CosNotification_Property'{name="midterm",
+ value=any:create(orber_tc:short(), 70)},
+ #'CosNotification_Property'{name="final",
+ value=any:create(orber_tc:short(), 80)}])},
+ #'CosNotification_Property'{name="monthly_attendance",
+ value=any:create(orber_tc:array(orber_tc:short(), 0),
+ {0,1,2,9})},
+ #'CosNotification_Property'{name="gpa",
+ value=any:create(orber_tc:short(), 90)}],
+ any:create(orber_tc:null(), null)),
+
+ %% gpa < 80 true, rest false.
+ Event7 = ?not_CreateSE("DomainName","TypeName",
+ "EventName", [],
+ [#'CosNotification_Property'{name="tests",
+ value=any:create(orber_tc:array('CosNotification_Property':tc(),0),
+ [#'CosNotification_Property'{name="midterm",
+ value=any:create(orber_tc:short(), 70)},
+ #'CosNotification_Property'{name="final",
+ value=any:create(orber_tc:short(), 80)}])},
+ #'CosNotification_Property'{name="monthly_attendance",
+ value=any:create(orber_tc:array(orber_tc:short(), 0),
+ {0,1,2,10})},
+ #'CosNotification_Property'{name="gpa",
+ value=any:create(orber_tc:short(), 70)}],
+ any:create(orber_tc:null(), null)),
+
+ %% All false
+ Event8 = ?not_CreateSE("DomainName","TypeName",
+ "EventName", [],
+ [#'CosNotification_Property'{name="tests",
+ value=any:create(orber_tc:array('CosNotification_Property':tc(),0),
+ [#'CosNotification_Property'{name="midterm",
+ value=any:create(orber_tc:short(), 70)},
+ #'CosNotification_Property'{name="final",
+ value=any:create(orber_tc:short(), 80)}])},
+ #'CosNotification_Property'{name="monthly_attendance",
+ value=any:create(orber_tc:array(orber_tc:short(), 0),
+ {0,1,2,10})},
+ #'CosNotification_Property'{name="gpa",
+ value=any:create(orber_tc:short(), 80)}],
+ any:create(orber_tc:null(), null)),
+
+ ?match(true, eval(T9, Event5)),
+ ?match(true, eval(T9, Event6)),
+ ?match(true, eval(T9, Event7)),
+ ?match(false, eval(T9, Event8)),
+ ok.
+
+%%-----------------------------------------------------------------
+%% Misc grammar tests
+%%-----------------------------------------------------------------
+positional_api(doc) -> ["CosNotification positional notation grammar tests", ""];
+positional_api(suite) -> [];
+positional_api(_Config) ->
+ {ok,T1} = ?match({ok, _}, create_filter("$.3 < 80 or $.1(midterm) > $.1(final) or $.2[3] < 10")),
+
+ %% midterm > final yields true, the others false
+ Event1 = any:create(notify_test_studies:tc(), #notify_test_studies
+ {gpa = 90,
+ tests = [#'CosNotification_Property'
+ {name="midterm", value=any:create(orber_tc:short(), 70)},
+ #'CosNotification_Property'
+ {name="final", value=any:create(orber_tc:short(), 60)}],
+ monthly_attendance = {0,1,2,10}}),
+ %% monthly_attendance[3] < 10 yields true, the others false
+ Event2 = any:create(notify_test_studies:tc(), #notify_test_studies
+ {gpa = 90,
+ tests = [#'CosNotification_Property'
+ {name="midterm", value=any:create(orber_tc:short(), 70)},
+ #'CosNotification_Property'
+ {name="final", value=any:create(orber_tc:short(), 80)}],
+ monthly_attendance = {0,1,2,9}}),
+ %% gpa < 80 true, rest false.
+ Event3 = any:create(notify_test_studies:tc(), #notify_test_studies
+ {gpa = 70,
+ tests = [#'CosNotification_Property'
+ {name="midterm", value=any:create(orber_tc:short(), 70)},
+ #'CosNotification_Property'
+ {name="final", value=any:create(orber_tc:short(), 80)}],
+ monthly_attendance = {0,1,2,10}}),
+ %% All false
+ Event4 = any:create(notify_test_studies:tc(), #notify_test_studies
+ {gpa = 80,
+ tests = [#'CosNotification_Property'
+ {name="midterm", value=any:create(orber_tc:short(), 70)},
+ #'CosNotification_Property'
+ {name="final", value=any:create(orber_tc:short(), 80)}],
+ monthly_attendance = {0,1,2,10}}),
+
+ ?match(true, eval(T1, Event1)),
+ ?match(true, eval(T1, Event2)),
+ ?match(true, eval(T1, Event3)),
+ ?match(false, eval(T1, Event4)),
+
+ {ok,T2} = ?match({ok, _}, create_filter("$.0.0.0.1 == 'CommunicationsAlarm'")),
+
+ Event5 = ?not_CreateSE("DomainName","CommunicationsAlarm",
+ "lost_packet", [], [],
+ any:create(orber_tc:null(), null)),
+
+ ?match(true, eval(T2, Event5)),
+
+ ok.
+
+%%-----------------------------------------------------------------
+%% Components grammar tests
+%%-----------------------------------------------------------------
+components_api(doc) -> ["CosNotification components grammar tests", ""];
+components_api(suite) -> [];
+components_api(_Config) ->
+ {ok,T1} = ?match({ok, _}, create_filter("$ == 2")),
+ ?match(true, eval(T1, ?not_CreateSE("DomainName","TypeName","EventName",
+ [],[], any:create(orber_tc:short(), 2)))),
+ ?match(true, eval(T1, any:create(orber_tc:short(), 2))),
+ ?match(false, eval(T1, ?not_CreateSE("DomainName","TypeName","EventName",
+ [],[], any:create(orber_tc:short(), 3)))),
+ ?match(false, eval(T1, any:create(orber_tc:short(), 3))),
+
+ %% Select "MOVIE" events featuring at least 3 of the Marx Brothers.
+ {ok,T2} = ?match({ok, _}, create_filter("$type_name == 'MOVIE' and (('groucho' in $.starlist) + ('chico' in $.starlist) + ('harpo' in $.starlist) + ('zeppo' in $.starlist) + ('gummo' in $.starlist)) > 2")),
+ ?match(true, eval(T2, ?not_CreateSE("DomainName","MOVIE", "EventName", [], [],
+ any:create(orber_tc:alias("IFRId","starlist",tk_any),
+ any:create(orber_tc:sequence(orber_tc:string(0),0),
+ ["groucho", "harpo", "sam", "gummo"]))))),
+ ?match(false, eval(T2, ?not_CreateSE("DomainName","MOVIE", "EventName", [], [],
+ any:create(orber_tc:alias("IFRId","starlist",tk_any),
+ any:create(orber_tc:sequence(orber_tc:string(0),0),
+ ["frodo", "bilbo", "sam", "gummo"]))))),
+
+ %% Accept only recent events (e.g., generated within the last 15 minutes or so).
+ {ok,_T3} = ?match({ok, _}, create_filter("$origination_timestamp.high + 2 < $curtime.high")),
+
+
+ %% Accept students that took all 3 tests and had an average score of at least 80%.
+ {ok,T4} = ?match({ok, _}, create_filter("$.test._length == 3 and ($.test[0].score + $.test[1].score + $.test[2].score)/3 >=80")),
+ ?match(true, eval(T4, ?not_CreateSE("DomainName","TypeName", "EventName", [], [],
+ any:create(orber_tc:alias("IFRId","test",tk_any),
+ any:create(orber_tc:array(notify_test_data:tc(),0),
+ {#notify_test_data{score=75},
+ #notify_test_data{score=80},
+ #notify_test_data{score=85}}))))),
+ ?match(false, eval(T4, ?not_CreateSE("DomainName","TypeName", "EventName", [], [],
+ any:create(orber_tc:alias("IFRId","test",tk_any),
+ any:create(orber_tc:array(notify_test_data:tc(),0),
+ {#notify_test_data{score=75},
+ #notify_test_data{score=80},
+ #notify_test_data{score=80}}))))),
+ ?match(false, eval(T4, ?not_CreateSE("DomainName","TypeName", "EventName", [], [],
+ any:create(orber_tc:alias("IFRId","test",tk_any),
+ any:create(orber_tc:array(notify_test_data:tc(),0),
+ {#notify_test_data{score=75},
+ #notify_test_data{score=80}}))))),
+
+ %% Select processes that exceed a certain usage threshold.
+ {ok,T5} = ?match({ok, _}, create_filter("$.memsize / 5.5 + $.cputime * 1275.0 + $.filesize * 1.25 > 500000.0")),
+ ?match(true, eval(T5, ?not_CreateSE("DomainName","TypeName", "EventName", [], [],
+ any:create(notify_test_computer:tc(),
+ #notify_test_computer
+ {memsize=5.5,
+ cputime = 0.00078431137,
+ filesize = 500000})))),
+ ?match(false, eval(T5, ?not_CreateSE("DomainName","TypeName", "EventName", [], [],
+ any:create(notify_test_computer:tc(),
+ #notify_test_computer
+ {memsize=5.5,
+ cputime = 0.00078431137,
+ filesize = 500})))),
+ ?match({error,_}, eval(T5, ?not_CreateSE("DomainName","TypeName", "EventName", [], [],
+ any:create(notify_test_computer:tc(),
+ #notify_test_computer
+ {memsize=5.5,
+ cputime = 0.00078431137})))),
+
+ %% Accept only Notification Service structured events.
+ {ok,T6} = ?match({ok, _}, create_filter("$._repos_id == 'IDL:omg.org/CosNotification/StructuredEvent:1.0'")),
+ ?match(true, eval(T6, ?not_CreateSE("DomainName","CommunicationsAlarm",
+ "EventName",
+ [], [], any:create(orber_tc:null(), null)))),
+
+
+
+ %% Accept only those events that have a specified security "rights list".
+ {ok,T7} = ?match({ok, _}, create_filter("exist $.header.variable_header(required_rights)")),
+ ?match(false, eval(T7, ?not_CreateSE("DomainName","CommunicationsAlarm",
+ "lost_packet",
+ [#'CosNotification_Property'{name="priority",
+ value=any:create(orber_tc:short(), 1)}],
+ [], any:create(orber_tc:null(), null)))),
+ ?match(true, eval(T7, ?not_CreateSE("DomainName","CommunicationsAlarm",
+ "lost_packet",
+ [#'CosNotification_Property'{name="required_rights",
+ value=any:create(orber_tc:short(), 1)}],
+ [], any:create(orber_tc:null(), null)))),
+
+
+ {ok,T8} = ?match({ok, _}, create_filter("$.header.fixed_header.event_type.type_name == 'CommunicationsAlarm' and $.header.fixed_header.event_name == 'lost_packet' and $.header.variable_header(priority) < 2")),
+ %% All correct
+ Event1 = ?not_CreateSE("DomainName","CommunicationsAlarm",
+ "lost_packet",
+ [#'CosNotification_Property'{name="priority",
+ value=any:create(orber_tc:short(), 1)}],
+ [], any:create(orber_tc:null(), null)),
+ %% Priority to high
+ Event2 = ?not_CreateSE("DomainName","CommunicationsAlarm",
+ "lost_packet",
+ [#'CosNotification_Property'{name="priority",
+ value=any:create(orber_tc:short(), 2)}],
+ [], any:create(orber_tc:null(), null)),
+ %% Misspell event_name, i.e., lost_packets instead of lost_packet
+ Event3 = ?not_CreateSE("DomainName","CommunicationsAlarm",
+ "lost_packets",
+ [#'CosNotification_Property'{name="priority",
+ value=any:create(orber_tc:short(), 1)}],
+ [], any:create(orber_tc:null(), null)),
+ %% Another type_name
+ Event4 = ?not_CreateSE("DomainName","TemperatureAlarm",
+ "lost_packets",
+ [#'CosNotification_Property'{name="priority",
+ value=any:create(orber_tc:short(), 1)}],
+ [], any:create(orber_tc:null(), null)),
+
+ ?match(true, eval(T8, Event1)),
+ ?match(false, eval(T8, Event2)),
+ ?match(false, eval(T8, Event3)),
+ ?match(false, eval(T8, Event4)),
+
+
+ {ok,T9} = ?match({ok, _}, create_filter("$.gpa < 80 or $.tests(midterm) > $.tests(final) or $.monthly_attendance[3] < 10")),
+
+ %% midterm > final yields true, the others false
+ Event5 = ?not_CreateSE("DomainName","TypeName",
+ "EventName", [], [],
+ any:create(notify_test_studies:tc(), #notify_test_studies
+ {gpa = 90,
+ tests = [#'CosNotification_Property'
+ {name="midterm", value=any:create(orber_tc:short(), 70)},
+ #'CosNotification_Property'
+ {name="final", value=any:create(orber_tc:short(), 60)}],
+ monthly_attendance = {0,1,2,10}})),
+ %% monthly_attendance[3] < 10 yields true, the others false
+ Event6 = ?not_CreateSE("DomainName","TypeName",
+ "EventName", [], [],
+ any:create(notify_test_studies:tc(), #notify_test_studies
+ {gpa = 90,
+ tests = [#'CosNotification_Property'
+ {name="midterm", value=any:create(orber_tc:short(), 70)},
+ #'CosNotification_Property'
+ {name="final", value=any:create(orber_tc:short(), 80)}],
+ monthly_attendance = {0,1,2,9}})),
+ %% gpa < 80 true, rest false.
+ Event7 = ?not_CreateSE("DomainName","TypeName",
+ "EventName", [], [],
+ any:create(notify_test_studies:tc(), #notify_test_studies
+ {gpa = 70,
+ tests = [#'CosNotification_Property'
+ {name="midterm", value=any:create(orber_tc:short(), 70)},
+ #'CosNotification_Property'
+ {name="final", value=any:create(orber_tc:short(), 80)}],
+ monthly_attendance = {0,1,2,10}})),
+ %% All false
+ Event8 = ?not_CreateSE("DomainName","TypeName",
+ "EventName", [], [],
+ any:create(notify_test_studies:tc(), #notify_test_studies
+ {gpa = 80,
+ tests = [#'CosNotification_Property'
+ {name="midterm", value=any:create(orber_tc:short(), 70)},
+ #'CosNotification_Property'
+ {name="final", value=any:create(orber_tc:short(), 80)}],
+ monthly_attendance = {0,1,2,10}})),
+
+ ?match(true, eval(T9, Event5)),
+ ?match(true, eval(T9, Event6)),
+ ?match(true, eval(T9, Event7)),
+ ?match(false, eval(T9, Event8)),
+ ok.
+
+
+%%-----------------------------------------------------------------
+%% Internal functions
+%%-----------------------------------------------------------------
+
+%%-------------------- End of Module ------------------------------
diff --git a/lib/cosNotification/test/notification_SUITE.erl b/lib/cosNotification/test/notification_SUITE.erl
new file mode 100644
index 0000000000..e2c560e4de
--- /dev/null
+++ b/lib/cosNotification/test/notification_SUITE.erl
@@ -0,0 +1,2185 @@
+%%--------------------------------------------------------------------
+%%
+%% %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%
+%%
+%%
+%%--------------------------------------------------------------------
+%% File : notification_SUITE.erl
+%% Purpose :
+%%--------------------------------------------------------------------
+
+-module(notification_SUITE).
+
+%%--------------- INCLUDES -----------------------------------
+-include_lib("orber/include/corba.hrl").
+-include_lib("orber/include/ifr_types.hrl").
+%% cosEvent files.
+-include_lib("cosEvent/include/CosEventChannelAdmin.hrl").
+%% Application files
+-include_lib("cosNotification/include/CosNotification.hrl").
+-include_lib("cosNotification/include/CosNotifyChannelAdmin.hrl").
+-include_lib("cosNotification/include/CosNotifyComm.hrl").
+-include_lib("cosNotification/include/CosNotifyFilter.hrl").
+
+-include_lib("cosNotification/src/CosNotification_Definitions.hrl").
+
+-include("idl_output/notify_test.hrl").
+
+-include("test_server.hrl").
+
+%%--------------- DEFINES ------------------------------------
+-define(default_timeout, ?t:minutes(20)).
+-define(match(ExpectedRes, Expr),
+ fun() ->
+ AcTuAlReS = (catch (Expr)),
+ case AcTuAlReS of
+ ExpectedRes ->
+ io:format("------ CORRECT RESULT ------~n~p~n",
+ [AcTuAlReS]),
+ AcTuAlReS;
+ _ ->
+ io:format("###### ERROR ERROR ######~n~p~n",
+ [AcTuAlReS]),
+ ?line exit(AcTuAlReS)
+ end
+ end()).
+
+-define(defaultQoS,
+ [#'CosNotification_Property'{name='CosNotification':'MaximumBatchSize'(),
+ value=any:create(orber_tc:long(), 100)},
+ #'CosNotification_Property'{name='CosNotification':'PacingInterval'(),
+ value=any:create(orber_tc:unsigned_long_long(),
+ 20000000)},
+ #'CosNotification_Property'{name='CosNotification':'OrderPolicy'(),
+ value=any:create(orber_tc:short(),
+ 'CosNotification':'AnyOrder'())},
+ #'CosNotification_Property'{name='CosNotification':'EventReliability'(),
+ value=any:create(orber_tc:short(),
+ 'CosNotification':'BestEffort'())},
+ #'CosNotification_Property'{name='CosNotification':'ConnectionReliability'(),
+ value=any:create(orber_tc:short(),
+ 'CosNotification':'BestEffort'())},
+ #'CosNotification_Property'{name='CosNotification':'DiscardPolicy'(),
+ value=any:create(orber_tc:short(),
+ 'CosNotification':'AnyOrder'())},
+ #'CosNotification_Property'{name='CosNotification':'StartTimeSupported'(),
+ value=any:create(orber_tc:boolean(), false)},
+ #'CosNotification_Property'{name='CosNotification':'StopTimeSupported'(),
+ value=any:create(orber_tc:boolean(), false)},
+ #'CosNotification_Property'{name='CosNotification':'Priority'(),
+ value=any:create(orber_tc:short(),
+ 'CosNotification':'DefaultPriority'())}]).
+-define(defaultQoS2,
+ [#'CosNotification_Property'{name='CosNotification':'MaximumBatchSize'(),
+ value=any:create(orber_tc:long(), 1)},
+ #'CosNotification_Property'{name='CosNotification':'PacingInterval'(),
+ value=any:create(orber_tc:unsigned_long_long(),
+ 0)},
+ #'CosNotification_Property'{name='CosNotification':'OrderPolicy'(),
+ value=any:create(orber_tc:short(),
+ 'CosNotification':'AnyOrder'())},
+ #'CosNotification_Property'{name='CosNotification':'EventReliability'(),
+ value=any:create(orber_tc:short(),
+ 'CosNotification':'BestEffort'())},
+ #'CosNotification_Property'{name='CosNotification':'ConnectionReliability'(),
+ value=any:create(orber_tc:short(),
+ 'CosNotification':'BestEffort'())},
+ #'CosNotification_Property'{name='CosNotification':'DiscardPolicy'(),
+ value=any:create(orber_tc:short(),
+ 'CosNotification':'AnyOrder'())},
+ #'CosNotification_Property'{name='CosNotification':'StartTimeSupported'(),
+ value=any:create(orber_tc:boolean(), false)},
+ #'CosNotification_Property'{name='CosNotification':'StopTimeSupported'(),
+ value=any:create(orber_tc:boolean(), false)},
+ #'CosNotification_Property'{name='CosNotification':'Priority'(),
+ value=any:create(orber_tc:short(),
+ 'CosNotification':'DefaultPriority'())}]).
+-define(defaultAdm,
+ [#'CosNotification_Property'{name='CosNotification':'MaxQueueLength'(),
+ value=any:create(orber_tc:long(), 100)},
+ #'CosNotification_Property'{name='CosNotification':'MaxConsumers'(),
+ value=any:create(orber_tc:long(), 100)},
+ #'CosNotification_Property'{name='CosNotification':'MaxSuppliers'(),
+ value=any:create(orber_tc:long(), 100)}]).
+
+-define(FAC_OPT, []).
+
+
+%%-----------------------------------------------------------------
+%% External exports
+%%-----------------------------------------------------------------
+-export([all/1, cases/0, init_all/1, finish_all/1, qos_api/1, adm_api/1,
+ cosevent_api/1, filter_adm_api/1, events_api/1, events2_api/1,
+ event_qos_api/1, filter_api/1, mapping_filter_api/1, subscription_api/1,
+ init_per_testcase/2, fin_per_testcase/2, persistent_max_events_api/1,
+ persistent_timeout_events_api/1, persistent_recover_events_api/1,
+ app_test/1]).
+
+-export([terminated/1]).
+
+%%-----------------------------------------------------------------
+%% Func: all/1
+%% Args:
+%% Returns:
+%%-----------------------------------------------------------------
+all(doc) -> ["API tests for the cosNotification interfaces", ""];
+all(suite) -> {req,
+ [mnesia, orber],
+ {conf, init_all, cases(), finish_all}}.
+
+cases() ->
+ [persistent_max_events_api, persistent_timeout_events_api,
+ persistent_recover_events_api, mapping_filter_api, filter_api, filter_adm_api,
+ event_qos_api, qos_api, adm_api, cosevent_api, subscription_api,
+ events_api, events2_api, app_test].
+
+
+
+%%-----------------------------------------------------------------
+%% Init and cleanup functions.
+%%-----------------------------------------------------------------
+
+init_per_testcase(_Case, Config) ->
+ Path = code:which(?MODULE),
+ code:add_pathz(filename:join(filename:dirname(Path), "idl_output")),
+ ?line Dog=test_server:timetrap(?default_timeout),
+ [{watchdog, Dog}|Config].
+
+
+fin_per_testcase(_Case, Config) ->
+ Path = code:which(?MODULE),
+ code:del_path(filename:join(filename:dirname(Path), "idl_output")),
+ Dog = ?config(watchdog, Config),
+ test_server:timetrap_cancel(Dog),
+ ok.
+
+init_all(Config) ->
+ Path = code:which(?MODULE),
+ code:add_pathz(filename:join(filename:dirname(Path), "idl_output")),
+ ok = corba:orb_init([{flags, 16#02}, {orber_debug_level, 10}]),
+ orber:jump_start(),
+ cosNotificationApp:install_event(),
+ cosNotificationApp:install(),
+ 'oe_notify_test_server':'oe_register'(),
+ cosNotificationApp:start(),
+ if
+ is_list(Config) ->
+ Config;
+ true ->
+ exit("Config not a list")
+ end.
+
+finish_all(Config) ->
+ cosNotificationApp:stop(),
+ Path = code:which(?MODULE),
+ code:del_path(filename:join(filename:dirname(Path), "idl_output")),
+ 'oe_notify_test_server':'oe_unregister'(),
+ cosNotificationApp:uninstall(),
+ cosNotificationApp:uninstall_event(),
+ orber:jump_stop(),
+ Config.
+
+
+%%-----------------------------------------------------------------
+%% Tests app file
+%%-----------------------------------------------------------------
+app_test(doc) -> [];
+app_test(suite) -> [];
+app_test(_Config) ->
+ ok=test_server:app_test(cosNotification),
+ ok.
+
+
+%%-----------------------------------------------------------------
+%% Persistent events max limit
+%%-----------------------------------------------------------------
+persistent_max_events_api(doc) -> ["CosNotification QoS EventReliability Persistent",
+ ""];
+persistent_max_events_api(suite) -> [];
+persistent_max_events_api(_Config) ->
+ QoSPersistent =
+ [#'CosNotification_Property'{name='CosNotification':'ConnectionReliability'(),
+ value=any:create(orber_tc:short(),
+ 'CosNotification':'Persistent'())}],
+ QoSEventPersistent =
+ [#'CosNotification_Property'{name='CosNotification':'EventReliability'(),
+ value=any:create(orber_tc:short(),
+ 'CosNotification':'Persistent'())}],
+ application:set_env(cosNotification, notify, ?MODULE),
+ application:set_env(cosNotification, max_events, 2),
+ application:set_env(cosNotification, timeout_events, 300000),
+ application:set_env(cosNotification, interval_events, 10000),
+ %% Initialize the application.
+ Fac = (catch cosNotificationApp:start_global_factory(?FAC_OPT)),
+ ?match({_,key,_,_,_,_}, Fac),
+ {Ch, _Id1} = (catch 'CosNotifyChannelAdmin_EventChannelFactory':create_channel(Fac, ?defaultQoS2, ?defaultAdm)),
+ ?match({_,key,_,_,_,_}, Ch),
+
+ ?match(ok, 'CosNotification_QoSAdmin':set_qos(Ch, QoSEventPersistent)),
+ ?match(ok, 'CosNotification_QoSAdmin':set_qos(Ch, QoSPersistent)),
+
+ %% Create the Admin objects
+ {AdminSupplier, _ASID}=?match({{_,key,_,_,_,_},_},
+ 'CosNotifyChannelAdmin_EventChannel':new_for_suppliers(Ch,'AND_OP')),
+ {AdminConsumer, _ACID}=?match({{_,key,_,_,_,_},_},
+ 'CosNotifyChannelAdmin_EventChannel':new_for_consumers(Ch,'AND_OP')),
+
+ %% Create Proxies and clients
+ {SequenceProxyPushSupplier,_ID}=?match({{_,key,_,_,_,_},_},
+ 'CosNotifyChannelAdmin_ConsumerAdmin':obtain_notification_push_supplier(AdminConsumer, 'SEQUENCE_EVENT')),
+ PushSeqC=?match({_,key,_,_,_,_}, 'notify_test_SeqPushC':oe_create(['PUSH_SEQUENCE',SequenceProxyPushSupplier],
+ [{local_typecheck, false}])),
+ ?match(ok, 'CosNotifyChannelAdmin_SequenceProxyPushSupplier':connect_sequence_push_consumer(SequenceProxyPushSupplier, PushSeqC)),
+
+ {SequenceProxyPushConsumer,_ID}=?match({{_,key,_,_,_,_},_},
+ 'CosNotifyChannelAdmin_SupplierAdmin':obtain_notification_push_consumer(AdminSupplier, 'SEQUENCE_EVENT')),
+ PushSeqS=?match({_,key,_,_,_,_}, 'notify_test_SeqPushS':oe_create(['PUSH_SEQUENCE',SequenceProxyPushConsumer],
+ [{local_typecheck, false}])),
+ ?match(ok, 'CosNotifyChannelAdmin_SequenceProxyPushConsumer':connect_sequence_push_supplier(SequenceProxyPushConsumer, PushSeqS)),
+
+ %% Create a couple of Events to test with.
+ Event = ?not_CreateSE("DomainName","CommunicationsAlarm",
+ "lost_packet",
+ [#'CosNotification_Property'{name="priority",
+ value=any:create(orber_tc:short(), 1)}],
+ [], any:create(orber_tc:null(), null)),
+
+ ?match(ok, 'notify_test_SeqPushC':doAction(PushSeqC, {action, action})),
+
+ %% Push and check the state.
+ ?match(ok,'CosNotifyChannelAdmin_SequenceProxyPushConsumer':push_structured_events(SequenceProxyPushConsumer, [Event])),
+ ?match([], 'notify_test_SeqPushC':doAction(PushSeqC, return_data)),
+ ?match(false, corba_object:non_existent(SequenceProxyPushSupplier)),
+
+ ?match(ok,'CosNotifyChannelAdmin_SequenceProxyPushConsumer':push_structured_events(SequenceProxyPushConsumer, [Event])),
+ ?match([], 'notify_test_SeqPushC':doAction(PushSeqC, return_data)),
+ ?match(false, corba_object:non_existent(SequenceProxyPushSupplier)),
+ %% Now we've reached the limit. This call will terminate the proxy.
+ %% We cannot check for data at this point since the broken connection
+ %% will result in that the client terminates.
+ ?match(ok,'CosNotifyChannelAdmin_SequenceProxyPushConsumer':push_structured_events(SequenceProxyPushConsumer, [Event])),
+ timer:sleep(5000),
+ ?match(true, corba_object:non_existent(SequenceProxyPushSupplier)),
+ ?match(true, corba_object:non_existent(PushSeqC)),
+
+
+ catch corba:dispose(SequenceProxyPushConsumer),
+ catch corba:dispose(SequenceProxyPushSupplier),
+ catch corba:dispose(AdminConsumer),
+ catch corba:dispose(AdminSupplier),
+ catch corba:dispose(Ch),
+ catch cosNotificationApp:stop_factory(Fac),
+ catch corba:dispose(PushSeqS),
+ catch corba:dispose(PushSeqC),
+ application:set_env(cosNotification, notify, undefined),
+ application:set_env(cosNotification, max_events, undefined),
+ application:set_env(cosNotification, timeout_events, undefined),
+ application:set_env(cosNotification, interval_events, undefined),
+ ok.
+
+terminated(Items) ->
+ io:format("Proxy terminated due to: ~p~n", [Items]).
+
+%%-----------------------------------------------------------------
+%% Persistent events timeout
+%%-----------------------------------------------------------------
+persistent_timeout_events_api(doc) ->
+ ["CosNotification QoS EventReliability Persistent",
+ ""];
+persistent_timeout_events_api(suite) -> [];
+persistent_timeout_events_api(_Config) ->
+ QoSPersistent =
+ [#'CosNotification_Property'{name='CosNotification':'ConnectionReliability'(),
+ value=any:create(orber_tc:short(),
+ 'CosNotification':'Persistent'())}],
+ QoSEventPersistent =
+ [#'CosNotification_Property'{name='CosNotification':'EventReliability'(),
+ value=any:create(orber_tc:short(),
+ 'CosNotification':'Persistent'())}],
+ application:set_env(cosNotification, notify, ?MODULE),
+ application:set_env(cosNotification, max_events, 1000),
+ application:set_env(cosNotification, timeout_events, 4000),
+ application:set_env(cosNotification, interval_events, 1000),
+ %% Initialize the application.
+ Fac = (catch cosNotificationApp:start_global_factory(?FAC_OPT)),
+ ?match({_,key,_,_,_,_}, Fac),
+ {Ch, _Id1} = (catch 'CosNotifyChannelAdmin_EventChannelFactory':create_channel(Fac, ?defaultQoS2, ?defaultAdm)),
+ ?match({_,key,_,_,_,_}, Ch),
+
+ ?match(ok, 'CosNotification_QoSAdmin':set_qos(Ch, QoSEventPersistent)),
+ ?match(ok, 'CosNotification_QoSAdmin':set_qos(Ch, QoSPersistent)),
+
+ %% Create the Admin objects
+ {AdminSupplier, _ASID}=?match({{_,key,_,_,_,_},_},
+ 'CosNotifyChannelAdmin_EventChannel':new_for_suppliers(Ch,'AND_OP')),
+ {AdminConsumer, _ACID}=?match({{_,key,_,_,_,_},_},
+ 'CosNotifyChannelAdmin_EventChannel':new_for_consumers(Ch,'AND_OP')),
+
+ %% Create Proxies and clients
+ {SequenceProxyPushSupplier,_ID}=?match({{_,key,_,_,_,_},_},
+ 'CosNotifyChannelAdmin_ConsumerAdmin':obtain_notification_push_supplier(AdminConsumer, 'SEQUENCE_EVENT')),
+ PushSeqC=?match({_,key,_,_,_,_}, 'notify_test_SeqPushC':oe_create(['PUSH_SEQUENCE',SequenceProxyPushSupplier],
+ [{local_typecheck, false}])),
+ ?match(ok, 'CosNotifyChannelAdmin_SequenceProxyPushSupplier':connect_sequence_push_consumer(SequenceProxyPushSupplier, PushSeqC)),
+
+ {SequenceProxyPushConsumer,_ID}=?match({{_,key,_,_,_,_},_},
+ 'CosNotifyChannelAdmin_SupplierAdmin':obtain_notification_push_consumer(AdminSupplier, 'SEQUENCE_EVENT')),
+ PushSeqS=?match({_,key,_,_,_,_}, 'notify_test_SeqPushS':oe_create(['PUSH_SEQUENCE',SequenceProxyPushConsumer],
+ [{local_typecheck, false}])),
+ ?match(ok, 'CosNotifyChannelAdmin_SequenceProxyPushConsumer':connect_sequence_push_supplier(SequenceProxyPushConsumer, PushSeqS)),
+
+ %% Create a couple of Events to test with.
+ Event = ?not_CreateSE("DomainName","CommunicationsAlarm",
+ "lost_packet",
+ [#'CosNotification_Property'{name="priority",
+ value=any:create(orber_tc:short(), 1)}],
+ [], any:create(orber_tc:null(), null)),
+
+ ?match(ok, 'notify_test_SeqPushC':doAction(PushSeqC, {action, action})),
+
+ %% Push and check the state.
+ ?match(ok,'CosNotifyChannelAdmin_SequenceProxyPushConsumer':push_structured_events(SequenceProxyPushConsumer, [Event])),
+ ?match([], 'notify_test_SeqPushC':doAction(PushSeqC, return_data)),
+ ?match(false, corba_object:non_existent(SequenceProxyPushSupplier)),
+
+ %% Now we've reached the limit. This call will terminate the proxy.
+ %% We cannot check for data at this point since the broken connection
+ %% will result in that the client terminates.
+ ?match(ok,'CosNotifyChannelAdmin_SequenceProxyPushConsumer':push_structured_events(SequenceProxyPushConsumer, [Event])),
+ timer:sleep(10000),
+ ?match(true, corba_object:non_existent(SequenceProxyPushSupplier)),
+ ?match(true, corba_object:non_existent(PushSeqC)),
+
+
+ catch corba:dispose(SequenceProxyPushConsumer),
+ catch corba:dispose(SequenceProxyPushSupplier),
+ catch corba:dispose(AdminConsumer),
+ catch corba:dispose(AdminSupplier),
+ catch corba:dispose(Ch),
+ catch cosNotificationApp:stop_factory(Fac),
+ catch corba:dispose(PushSeqS),
+ catch corba:dispose(PushSeqC),
+ application:set_env(cosNotification, notify, undefined),
+ application:set_env(cosNotification, max_events, undefined),
+ application:set_env(cosNotification, timeout_events, undefined),
+ application:set_env(cosNotification, interval_events, undefined),
+ ok.
+
+%%-----------------------------------------------------------------
+%% Persistent events max limit
+%%-----------------------------------------------------------------
+persistent_recover_events_api(doc) ->
+ ["CosNotification QoS EventReliability Persistent",
+ ""];
+persistent_recover_events_api(suite) -> [];
+persistent_recover_events_api(_Config) ->
+ QoSPersistent =
+ [#'CosNotification_Property'{name='CosNotification':'ConnectionReliability'(),
+ value=any:create(orber_tc:short(),
+ 'CosNotification':'Persistent'())}],
+ QoSEventPersistent =
+ [#'CosNotification_Property'{name='CosNotification':'EventReliability'(),
+ value=any:create(orber_tc:short(),
+ 'CosNotification':'Persistent'())}],
+ application:set_env(cosNotification, notify, ?MODULE),
+ application:set_env(cosNotification, max_events, 1000),
+ application:set_env(cosNotification, timeout_events, 100000),
+ application:set_env(cosNotification, interval_events, 1000),
+ %% Initialize the application.
+ Fac = (catch cosNotificationApp:start_global_factory(?FAC_OPT)),
+ ?match({_,key,_,_,_,_}, Fac),
+ {Ch, _Id1} = (catch 'CosNotifyChannelAdmin_EventChannelFactory':create_channel(Fac, ?defaultQoS2, ?defaultAdm)),
+ ?match({_,key,_,_,_,_}, Ch),
+
+ ?match(ok, 'CosNotification_QoSAdmin':set_qos(Ch, QoSEventPersistent)),
+ ?match(ok, 'CosNotification_QoSAdmin':set_qos(Ch, QoSPersistent)),
+
+ %% Create the Admin objects
+ {AdminSupplier, _ASID}=?match({{_,key,_,_,_,_},_},
+ 'CosNotifyChannelAdmin_EventChannel':new_for_suppliers(Ch,'AND_OP')),
+ {AdminConsumer, _ACID}=?match({{_,key,_,_,_,_},_},
+ 'CosNotifyChannelAdmin_EventChannel':new_for_consumers(Ch,'AND_OP')),
+
+ %% Create Proxies and clients
+ {SequenceProxyPushSupplier,_ID}=?match({{_,key,_,_,_,_},_},
+ 'CosNotifyChannelAdmin_ConsumerAdmin':obtain_notification_push_supplier(AdminConsumer, 'SEQUENCE_EVENT')),
+ PushSeqC=?match({_,key,_,_,_,_}, 'notify_test_SeqPushC':oe_create(['PUSH_SEQUENCE',SequenceProxyPushSupplier],
+ [{local_typecheck, false}])),
+ ?match(ok, 'CosNotifyChannelAdmin_SequenceProxyPushSupplier':connect_sequence_push_consumer(SequenceProxyPushSupplier, PushSeqC)),
+
+ {SequenceProxyPushConsumer,_ID}=?match({{_,key,_,_,_,_},_},
+ 'CosNotifyChannelAdmin_SupplierAdmin':obtain_notification_push_consumer(AdminSupplier, 'SEQUENCE_EVENT')),
+ PushSeqS=?match({_,key,_,_,_,_}, 'notify_test_SeqPushS':oe_create(['PUSH_SEQUENCE',SequenceProxyPushConsumer],
+ [{local_typecheck, false}])),
+ ?match(ok, 'CosNotifyChannelAdmin_SequenceProxyPushConsumer':connect_sequence_push_supplier(SequenceProxyPushConsumer, PushSeqS)),
+
+ %% Create a couple of Events to test with.
+ Event = ?not_CreateSE("DomainName","CommunicationsAlarm",
+ "lost_packet",
+ [#'CosNotification_Property'{name="priority",
+ value=any:create(orber_tc:short(), 1)}],
+ [], any:create(orber_tc:null(), null)),
+
+ ?match(ok, 'notify_test_SeqPushC':doAction(PushSeqC, {action, action})),
+
+ %% Push and check the state.
+ ?match(ok,'CosNotifyChannelAdmin_SequenceProxyPushConsumer':push_structured_events(SequenceProxyPushConsumer, [Event])),
+ ?match([], 'notify_test_SeqPushC':doAction(PushSeqC, return_data)),
+ ?match(false, corba_object:non_existent(SequenceProxyPushSupplier)),
+ %% Allow the proxy to try a few times and then change the client behavior
+ timer:sleep(4000),
+ ?match(ok, 'notify_test_SeqPushC':doAction(PushSeqC, {action, undefined})),
+ %% Wait some time so that the proxy timeout has kicked in.
+ timer:sleep(4000),
+
+ %% Now the communication should work again.
+ ?match([Event], 'notify_test_SeqPushC':doAction(PushSeqC, return_data)),
+ ?match(false, corba_object:non_existent(SequenceProxyPushSupplier)),
+
+ ?match(ok,'CosNotifyChannelAdmin_SequenceProxyPushConsumer':push_structured_events(SequenceProxyPushConsumer, [Event])),
+ timer:sleep(4000),
+ ?match([Event], 'notify_test_SeqPushC':doAction(PushSeqC, return_data)),
+
+ catch corba:dispose(SequenceProxyPushConsumer),
+ catch corba:dispose(SequenceProxyPushSupplier),
+ catch corba:dispose(AdminConsumer),
+ catch corba:dispose(AdminSupplier),
+ catch corba:dispose(Ch),
+ catch cosNotificationApp:stop_factory(Fac),
+ catch corba:dispose(PushSeqS),
+ catch corba:dispose(PushSeqC),
+ application:set_env(cosNotification, notify, undefined),
+ application:set_env(cosNotification, max_events, undefined),
+ application:set_env(cosNotification, timeout_events, undefined),
+ application:set_env(cosNotification, interval_events, undefined),
+ ok.
+
+
+%%-----------------------------------------------------------------
+%% CosNotifyFilter::Filter API tests
+%%-----------------------------------------------------------------
+mapping_filter_api(doc) -> ["CosNotifyFilter::MappingFilter API tests.", ""];
+mapping_filter_api(suite) -> [];
+mapping_filter_api(_Config) ->
+ FiFac = 'CosNotifyFilter_FilterFactory':oe_create(),
+ ?match({_,key,_,_,_,_}, FiFac),
+
+ Filter = 'CosNotifyFilter_FilterFactory':create_mapping_filter(FiFac,
+ "EXTENDED_TCL",
+ any:create(orber_tc:short(), 10)),
+ ?match({_,key,_,_,_,_}, Filter),
+
+ ?match("EXTENDED_TCL", 'CosNotifyFilter_MappingFilter':'_get_constraint_grammar'(Filter)),
+
+ %% Test before we add any constarints.
+ ?match([], 'CosNotifyFilter_MappingFilter':get_all_mapping_constraints(Filter)),
+ ?match({'EXCEPTION', {'CosNotifyFilter_ConstraintNotFound', _, 1}},
+ 'CosNotifyFilter_MappingFilter':get_mapping_constraints(Filter, [1])),
+ ?match(ok, 'CosNotifyFilter_MappingFilter':remove_all_mapping_constraints(Filter)),
+
+ %% Try adding an incorrect constraint_expr
+ ?match({'EXCEPTION',{'CosNotifyFilter_InvalidConstraint',_,_}},
+ 'CosNotifyFilter_MappingFilter':add_mapping_constraints(Filter,
+ [#'CosNotifyFilter_MappingConstraintPair'
+ {constraint_expression = #'CosNotifyFilter_ConstraintExp'
+ {event_types = [#'CosNotification_EventType'
+ {domain_name = "name",
+ type_name = "type"}],
+ constraint_expr = "2==2 and 3<"},
+ result_to_set = any:create(orber_tc:short(), 10)}])),
+ %% Try adding two correct constraint_expr
+ ?line[{_,_,CID1,_},{_,_,CID2,_}]=
+ ?match([{'CosNotifyFilter_MappingConstraintInfo',_,_,_}, {'CosNotifyFilter_MappingConstraintInfo',_,_,_}],
+ 'CosNotifyFilter_MappingFilter':add_mapping_constraints(Filter,
+ [#'CosNotifyFilter_MappingConstraintPair'
+ {constraint_expression = #'CosNotifyFilter_ConstraintExp'
+ {event_types = [#'CosNotification_EventType'
+ {domain_name = "name",
+ type_name = "type"}],
+ constraint_expr = "2==2 and 3<4"},
+ result_to_set = any:create(orber_tc:short(), 10)},
+ #'CosNotifyFilter_MappingConstraintPair'
+ {constraint_expression = #'CosNotifyFilter_ConstraintExp'
+ {event_types = [#'CosNotification_EventType'
+ {domain_name = "name2",
+ type_name = "type2"}],
+ constraint_expr = "$.test._length == 3 and ($.test[0].score + $.test[1].score + $.test[2].score)/3 >=80"},
+ result_to_set = any:create(orber_tc:short(), 10)}])),
+
+ ?match([{'CosNotifyFilter_MappingConstraintInfo',_,CID2,_}, {'CosNotifyFilter_MappingConstraintInfo',_,CID1,_}],
+ 'CosNotifyFilter_MappingFilter':get_all_mapping_constraints(Filter)),
+ ?match([{'CosNotifyFilter_MappingConstraintInfo',_,CID1,_}],
+ 'CosNotifyFilter_MappingFilter':get_mapping_constraints(Filter, [CID1])),
+ ?match(ok, 'CosNotifyFilter_MappingFilter':remove_all_mapping_constraints(Filter)),
+ ?match([], 'CosNotifyFilter_MappingFilter':get_all_mapping_constraints(Filter)),
+
+ %% Try adding a constraint_expr with using invalid value, i.e., not short.
+ ?match({'EXCEPTION',{'CosNotifyFilter_InvalidValue',_,_,_}},
+ 'CosNotifyFilter_MappingFilter':add_mapping_constraints(Filter,
+ [#'CosNotifyFilter_MappingConstraintPair'
+ {constraint_expression = #'CosNotifyFilter_ConstraintExp'
+ {event_types = [#'CosNotification_EventType'
+ {domain_name = "name",
+ type_name = "type"}],
+ constraint_expr = "2==2 and 3<8"},
+ result_to_set = any:create(orber_tc:long(), 10)}])),
+
+ %% Try adding one correct and one incorrect constraint_expr
+ ?match({'EXCEPTION',{'CosNotifyFilter_InvalidConstraint',_,_}},
+ 'CosNotifyFilter_MappingFilter':add_mapping_constraints(Filter,
+ [#'CosNotifyFilter_MappingConstraintPair'
+ {constraint_expression = #'CosNotifyFilter_ConstraintExp'
+ {event_types = [#'CosNotification_EventType'
+ {domain_name = "name",
+ type_name = "type"}],
+ constraint_expr = "2==2 and 3<"},
+ result_to_set = any:create(orber_tc:short(), 10)},
+ #'CosNotifyFilter_MappingConstraintPair'
+ {constraint_expression = #'CosNotifyFilter_ConstraintExp'
+ {event_types = [#'CosNotification_EventType'
+ {domain_name = "name2",
+ type_name = "type2"}],
+ constraint_expr = "$.test._length == 3 and ($.test[0].score + $.test[1].score + $.test[2].score)/3 >=80"},
+ result_to_set = any:create(orber_tc:short(), 10)}])),
+
+ %% Following testcases test different domain_name and type_name, e.g.,
+ %% wildcards etc.
+ [{_,ConInfoData,CID3,_}] =
+ ?match([{'CosNotifyFilter_MappingConstraintInfo',_,_,_}],
+ 'CosNotifyFilter_MappingFilter':add_mapping_constraints(Filter,
+ [#'CosNotifyFilter_MappingConstraintPair'
+ {constraint_expression = #'CosNotifyFilter_ConstraintExp'
+ {event_types = [#'CosNotification_EventType'
+ {domain_name = "domain",
+ type_name = ""},
+ #'CosNotification_EventType'
+ {domain_name = "*",
+ type_name = "type"}],
+ constraint_expr = "2==2 and 3<4"},
+ result_to_set = any:create(orber_tc:short(), 10)}])),
+
+ %% Try removing a constraint
+ ?match(ok, 'CosNotifyFilter_MappingFilter':modify_mapping_constraints(Filter,[CID3],[])),
+ ?match([], 'CosNotifyFilter_MappingFilter':get_all_mapping_constraints(Filter)),
+
+ %% Add e new constraint
+ [{_,_,CID4,_}] =
+ ?match([{'CosNotifyFilter_MappingConstraintInfo',_,_,_}],
+ 'CosNotifyFilter_MappingFilter':add_mapping_constraints(Filter,
+ [#'CosNotifyFilter_MappingConstraintPair'
+ {constraint_expression = #'CosNotifyFilter_ConstraintExp'
+ {event_types = [#'CosNotification_EventType'
+ {domain_name = "domain1",
+ type_name = ""},
+ #'CosNotification_EventType'
+ {domain_name = "domain2",
+ type_name = "*"}],
+ constraint_expr = "2==2 and 3<4"},
+ result_to_set = any:create(orber_tc:short(), 10)}])),
+
+ %% Try to update the constraint associated with CID4 to equal CID3.
+ ?match(ok, 'CosNotifyFilter_MappingFilter':modify_mapping_constraints(Filter,[],
+ [#'CosNotifyFilter_MappingConstraintInfo'
+ {constraint_expression=
+ #'CosNotifyFilter_ConstraintExp'
+ {event_types =[#'CosNotification_EventType'
+ {domain_name = "domain",
+ type_name = ""},
+ #'CosNotification_EventType'
+ {domain_name = "*",
+ type_name = "type"}],
+ constraint_expr = "2==2 and 3<4"},
+ constraint_id=CID4,
+ value = any:create(orber_tc:short(), 10)}])),
+
+ ?match([{_,ConInfoData,CID4,_}], 'CosNotifyFilter_MappingFilter':get_all_mapping_constraints(Filter)),
+
+ ?match({'EXCEPTION', {'CosNotifyFilter_ConstraintNotFound', _, CID3}},
+ 'CosNotifyFilter_MappingFilter':get_mapping_constraints(Filter, [CID3])),
+ ?match(ok, 'CosNotifyFilter_MappingFilter':remove_all_mapping_constraints(Filter)),
+ ?match([], 'CosNotifyFilter_MappingFilter':get_all_mapping_constraints(Filter)),
+
+ ?match([{'CosNotifyFilter_MappingConstraintInfo',_,_,_}],
+ 'CosNotifyFilter_MappingFilter':add_mapping_constraints(Filter,
+ [#'CosNotifyFilter_MappingConstraintPair'
+ {constraint_expression = #'CosNotifyFilter_ConstraintExp'
+ {event_types = [#'CosNotification_EventType'
+ {domain_name = "",
+ type_name = "type1"},
+ #'CosNotification_EventType'
+ {domain_name = "*",
+ type_name = "type2"}],
+ constraint_expr = "2==2 and 3<4"},
+ result_to_set = any:create(orber_tc:short(), 10)}])),
+
+ ?match([{'CosNotifyFilter_MappingConstraintInfo',_,_,_}],
+ 'CosNotifyFilter_MappingFilter':add_mapping_constraints(Filter,
+ [#'CosNotifyFilter_MappingConstraintPair'
+ {constraint_expression = #'CosNotifyFilter_ConstraintExp'
+ {event_types = [#'CosNotification_EventType'
+ {domain_name = "domain1",
+ type_name = "type1"},
+ #'CosNotification_EventType'
+ {domain_name = "domain2",
+ type_name = "type2"}],
+ constraint_expr = "2==2 and 3<4"},
+ result_to_set = any:create(orber_tc:short(), 10)}])),
+
+ ?match([{'CosNotifyFilter_MappingConstraintInfo',_,_,_}],
+ 'CosNotifyFilter_MappingFilter':add_mapping_constraints(Filter,
+ [#'CosNotifyFilter_MappingConstraintPair'
+ {constraint_expression = #'CosNotifyFilter_ConstraintExp'
+ {event_types = [#'CosNotification_EventType'
+ {domain_name = "dom*",
+ type_name = "type1"},
+ #'CosNotification_EventType'
+ {domain_name = "domain2",
+ type_name = "typ*"}],
+ constraint_expr = "2==2 and 3<4"},
+ result_to_set = any:create(orber_tc:short(), 10)}])),
+
+ ?match([{'CosNotifyFilter_MappingConstraintInfo',_,_,_}],
+ 'CosNotifyFilter_MappingFilter':add_mapping_constraints(Filter,
+ [#'CosNotifyFilter_MappingConstraintPair'
+ {constraint_expression = #'CosNotifyFilter_ConstraintExp'
+ {event_types = [#'CosNotification_EventType'
+ {domain_name = "dom*1",
+ type_name = "type1"},
+ #'CosNotification_EventType'
+ {domain_name = "domain2",
+ type_name = "typ*2"}],
+ constraint_expr = "2==2 and 3<4"},
+ result_to_set = any:create(orber_tc:short(), 10)}])),
+
+ catch corba:dispose(FiFac),
+ catch corba:dispose(Filter),
+ ok.
+
+
+%%-----------------------------------------------------------------
+%% CosNotifyFilter::Filter API tests
+%%-----------------------------------------------------------------
+filter_api(doc) -> ["CosNotifyFilter::Filter API tests.", ""];
+filter_api(suite) -> [];
+filter_api(_Config) ->
+ Fac = cosNotificationApp:start_global_factory(?FAC_OPT),
+ ?match({_,key,_,_,_,_}, Fac),
+ {Ch, _Id1} = 'CosNotifyChannelAdmin_EventChannelFactory':create_channel(Fac, ?defaultQoS, ?defaultAdm),
+ AC= 'CosNotifyChannelAdmin_EventChannel':for_consumers(Ch),
+
+ FiFac = 'CosNotifyFilter_FilterFactory':oe_create(),
+ ?match({_,key,_,_,_,_}, FiFac),
+
+ Filter = 'CosNotifyFilter_FilterFactory':create_filter(FiFac,"EXTENDED_TCL"),
+ ?match({_,key,_,_,_,_}, Filter),
+
+ ?match("EXTENDED_TCL", 'CosNotifyFilter_Filter':'_get_constraint_grammar'(Filter)),
+
+ %% Test Callback management.
+ ?match({'EXCEPTION',{'BAD_PARAM',_,_,_}},
+ 'CosNotifyFilter_Filter':attach_callback(Filter, Ch)),
+ ?match([], 'CosNotifyFilter_Filter':get_callbacks(Filter)),
+ ?match({'EXCEPTION',{'CosNotifyFilter_CallbackNotFound',_}},
+ 'CosNotifyFilter_Filter':detach_callback(Filter, 0)),
+ ID='CosNotifyFilter_Filter':attach_callback(Filter, AC),
+ ?match([ID], 'CosNotifyFilter_Filter':get_callbacks(Filter)),
+ ?match(ok, 'CosNotifyFilter_Filter':detach_callback(Filter, ID)),
+ ?match([], 'CosNotifyFilter_Filter':get_callbacks(Filter)),
+
+ %% This callback is just attached so we can test that we can call notify_subscribe.
+ _ID2='CosNotifyFilter_Filter':attach_callback(Filter, AC),
+
+ %% Test before we add any constarints.
+ ?match([], 'CosNotifyFilter_Filter':get_all_constraints(Filter)),
+ ?match({'EXCEPTION', {'CosNotifyFilter_ConstraintNotFound', _, 1}},
+ 'CosNotifyFilter_Filter':get_constraints(Filter, [1])),
+ ?match(ok, 'CosNotifyFilter_Filter':remove_all_constraints(Filter)),
+
+ %% Try adding an incorrect constraint_expr
+ ?match({'EXCEPTION',{'CosNotifyFilter_InvalidConstraint',_,_}},
+ 'CosNotifyFilter_Filter':add_constraints(Filter,
+ [#'CosNotifyFilter_ConstraintExp'{event_types =
+ [#'CosNotification_EventType'{
+ domain_name = "name",
+ type_name = "type"}],
+ constraint_expr = "2==2 and 3<"}])),
+ %% Try adding two correct constraint_expr
+ ?line[{_,_,CID1},{_,_,CID2}]=
+ ?match([{'CosNotifyFilter_ConstraintInfo',_,_}, {'CosNotifyFilter_ConstraintInfo',_,_}],
+ 'CosNotifyFilter_Filter':add_constraints(Filter,
+ [#'CosNotifyFilter_ConstraintExp'{event_types =
+ [#'CosNotification_EventType'{
+ domain_name = "name",
+ type_name = "type"}],
+ constraint_expr = "2==2 and 3<4"},
+ #'CosNotifyFilter_ConstraintExp'{event_types =
+ [#'CosNotification_EventType'{
+ domain_name = "name2",
+ type_name = "type2"}],
+ constraint_expr = "$.test._length == 3 and ($.test[0].score + $.test[1].score + $.test[2].score)/3 >=80"}])),
+
+ ?match([{'CosNotifyFilter_ConstraintInfo',_,CID2}, {'CosNotifyFilter_ConstraintInfo',_,CID1}],
+ 'CosNotifyFilter_Filter':get_all_constraints(Filter)),
+ ?match([{'CosNotifyFilter_ConstraintInfo',_,CID1}],
+ 'CosNotifyFilter_Filter':get_constraints(Filter, [CID1])),
+ ?match(ok, 'CosNotifyFilter_Filter':remove_all_constraints(Filter)),
+ ?match([], 'CosNotifyFilter_Filter':get_all_constraints(Filter)),
+
+ %% Try adding one correct and one incorrect constraint_expr
+ ?match({'EXCEPTION',{'CosNotifyFilter_InvalidConstraint',_,_}},
+ 'CosNotifyFilter_Filter':add_constraints(Filter,
+ [#'CosNotifyFilter_ConstraintExp'{event_types =
+ [#'CosNotification_EventType'{
+ domain_name = "name",
+ type_name = "type"}],
+ constraint_expr = "2==2 and 3<"},
+ #'CosNotifyFilter_ConstraintExp'{event_types =
+ [#'CosNotification_EventType'{
+ domain_name = "name2",
+ type_name = "type2"}],
+ constraint_expr = "$.test._length == 3 and ($.test[0].score + $.test[1].score + $.test[2].score)/3 >=80"}])),
+
+ %% Following testcases test different domain_name and type_name, e.g.,
+ %% wildcards etc.
+ [{_,ConInfoData,CID3}] =
+ ?match([{'CosNotifyFilter_ConstraintInfo',_,_}],
+ 'CosNotifyFilter_Filter':add_constraints(Filter,
+ [#'CosNotifyFilter_ConstraintExp'{event_types =
+ [#'CosNotification_EventType'{
+ domain_name = "domain",
+ type_name = ""},
+ #'CosNotification_EventType'{
+ domain_name = "*",
+ type_name = "type"}],
+ constraint_expr = "2==2 and 3<4"}])),
+
+ %% Try removing a constraint
+ ?match(ok, 'CosNotifyFilter_Filter':modify_constraints(Filter,[CID3],[])),
+ ?match([], 'CosNotifyFilter_Filter':get_all_constraints(Filter)),
+
+ %% Add e new constraint
+ [{_,_,CID4}] =
+ ?match([{'CosNotifyFilter_ConstraintInfo',_,_}],
+ 'CosNotifyFilter_Filter':add_constraints(Filter,
+ [#'CosNotifyFilter_ConstraintExp'{event_types =
+ [#'CosNotification_EventType'{
+ domain_name = "domain1",
+ type_name = ""},
+ #'CosNotification_EventType'{
+ domain_name = "domain2",
+ type_name = "*"}],
+ constraint_expr = "2==2 and 3<4"}])),
+
+ %% Try to update the constraint associated with CID4 to equal CID3.
+ ?match(ok, 'CosNotifyFilter_Filter':modify_constraints(Filter,[],
+ [#'CosNotifyFilter_ConstraintInfo'{constraint_expression=
+ #'CosNotifyFilter_ConstraintExp'{event_types =
+ [#'CosNotification_EventType'{
+ domain_name = "domain",
+ type_name = ""},
+ #'CosNotification_EventType'{
+ domain_name = "*",
+ type_name = "type"}],
+ constraint_expr = "2==2 and 3<4"},
+ constraint_id=CID4}])),
+
+ ?match([{_,ConInfoData,CID4}], 'CosNotifyFilter_Filter':get_all_constraints(Filter)),
+
+ ?match({'EXCEPTION', {'CosNotifyFilter_ConstraintNotFound', _, CID3}},
+ 'CosNotifyFilter_Filter':get_constraints(Filter, [CID3])),
+ ?match(ok, 'CosNotifyFilter_Filter':remove_all_constraints(Filter)),
+ ?match([], 'CosNotifyFilter_Filter':get_all_constraints(Filter)),
+
+ ?match([{'CosNotifyFilter_ConstraintInfo',_,_}],
+ 'CosNotifyFilter_Filter':add_constraints(Filter,
+ [#'CosNotifyFilter_ConstraintExp'{event_types =
+ [#'CosNotification_EventType'{
+ domain_name = "",
+ type_name = "type1"},
+ #'CosNotification_EventType'{
+ domain_name = "*",
+ type_name = "type2"}],
+ constraint_expr = "2==2 and 3<4"}])),
+
+ ?match([{'CosNotifyFilter_ConstraintInfo',_,_}],
+ 'CosNotifyFilter_Filter':add_constraints(Filter,
+ [#'CosNotifyFilter_ConstraintExp'{event_types =
+ [#'CosNotification_EventType'{
+ domain_name = "domain1",
+ type_name = "type1"},
+ #'CosNotification_EventType'{
+ domain_name = "domain2",
+ type_name = "type2"}],
+ constraint_expr = "2==2 and 3<4"}])),
+
+ ?match([{'CosNotifyFilter_ConstraintInfo',_,_}],
+ 'CosNotifyFilter_Filter':add_constraints(Filter,
+ [#'CosNotifyFilter_ConstraintExp'{event_types =
+ [#'CosNotification_EventType'{
+ domain_name = "dom*",
+ type_name = "type1"},
+ #'CosNotification_EventType'{
+ domain_name = "domain2",
+ type_name = "typ*"}],
+ constraint_expr = "2==2 and 3<4"}])),
+
+ ?match([{'CosNotifyFilter_ConstraintInfo',_,_}],
+ 'CosNotifyFilter_Filter':add_constraints(Filter,
+ [#'CosNotifyFilter_ConstraintExp'{event_types =
+ [#'CosNotification_EventType'{
+ domain_name = "dom*1",
+ type_name = "type1"},
+ #'CosNotification_EventType'{
+ domain_name = "domain2",
+ type_name = "typ*2"}],
+ constraint_expr = "2==2 and 3<4"}])),
+
+ catch corba:dispose(FiFac),
+ catch corba:dispose(Filter),
+ catch corba:dispose(AC),
+ catch corba:dispose(Ch),
+ catch corba:dispose(Fac),
+ ok.
+
+%%-----------------------------------------------------------------
+%% Subscription handling API tests
+%%-----------------------------------------------------------------
+subscription_api(doc) -> ["CosNotification subscription handling", ""];
+subscription_api(suite) -> [];
+subscription_api(_Config) ->
+ %% Initialize the application.
+ Fac = (catch cosNotificationApp:start_global_factory(?FAC_OPT)),
+ ?match({_,key,_,_,_,_}, Fac),
+ {Ch, _Id1} = (catch 'CosNotifyChannelAdmin_EventChannelFactory':create_channel(Fac, ?defaultQoS, ?defaultAdm)),
+ ?match({_,key,_,_,_,_}, Ch),
+
+ %% Create the Admin objects
+ {AdminSupplier, _ASID}=?match({{_,key,_,_,_,_},_},
+ 'CosNotifyChannelAdmin_EventChannel':new_for_suppliers(Ch,'OR_OP')),
+ {AdminConsumer, _ACID}=?match({{_,key,_,_,_,_},_},
+ 'CosNotifyChannelAdmin_EventChannel':new_for_consumers(Ch,'OR_OP')),
+
+ %% Create Suppliers Proxies
+ {StructuredProxyPullSupplier,_}=?match({{_,key,_,_,_,_},_},
+ 'CosNotifyChannelAdmin_ConsumerAdmin':obtain_notification_pull_supplier(AdminConsumer, 'STRUCTURED_EVENT')),
+ {StructuredProxyPushSupplier,_}=?match({{_,key,_,_,_,_},_},
+ 'CosNotifyChannelAdmin_ConsumerAdmin':obtain_notification_push_supplier(AdminConsumer, 'STRUCTURED_EVENT')),
+
+ %% Now we must create a Client for each proxy and connect them.
+ PushStrC=?match({_,key,_,_,_,_}, 'notify_test_StrPushC':oe_create(['PUSH_STRUCTURED',StructuredProxyPushSupplier],
+ [{local_typecheck, false}])),
+ ?match(ok, 'CosNotifyChannelAdmin_StructuredProxyPushSupplier':connect_structured_push_consumer(StructuredProxyPushSupplier, PushStrC)),
+ PullStrC=?match({_,key,_,_,_,_}, 'notify_test_StrPullC':oe_create(['PULL_STRUCTURED',StructuredProxyPullSupplier],
+ [{local_typecheck, false}])),
+ ?match(ok, 'CosNotifyChannelAdmin_StructuredProxyPullSupplier':connect_structured_pull_consumer(StructuredProxyPullSupplier, PullStrC)),
+
+ %% Create Consumers Proxies
+ {StructuredProxyPullConsumer,_}=?match({{_,key,_,_,_,_},_},
+ 'CosNotifyChannelAdmin_SupplierAdmin':obtain_notification_pull_consumer(AdminSupplier, 'STRUCTURED_EVENT')),
+ {StructuredProxyPushConsumer,_}=?match({{_,key,_,_,_,_},_},
+ 'CosNotifyChannelAdmin_SupplierAdmin':obtain_notification_push_consumer(AdminSupplier, 'STRUCTURED_EVENT')),
+
+ %% Now we must create a Client for each proxy and connect them.
+ PushStrS=?match({_,key,_,_,_,_}, 'notify_test_StrPushS':oe_create(['PUSH_STRUCTURED',StructuredProxyPushConsumer],
+ [{local_typecheck, false}])),
+ ?match(ok, 'CosNotifyChannelAdmin_StructuredProxyPushConsumer':connect_structured_push_supplier(StructuredProxyPushConsumer, PushStrS)),
+
+ PullStrS=?match({_,key,_,_,_,_}, 'notify_test_StrPullS':oe_create(['PULL_STRUCTURED',StructuredProxyPullConsumer],
+ [{local_typecheck, false}])),
+ ?match(ok, 'CosNotifyChannelAdmin_StructuredProxyPullConsumer':connect_structured_pull_supplier(StructuredProxyPullConsumer, PullStrS)),
+
+ ES1=[#'CosNotification_EventType'{domain_name = "name1", type_name = "type1"},
+ #'CosNotification_EventType'{domain_name = "name2", type_name = "type2"}],
+ ES2=[#'CosNotification_EventType'{domain_name = "name3", type_name = "type3"},
+ #'CosNotification_EventType'{domain_name = "name4", type_name = "type4"}],
+
+ %% Initially it should have no associated types. Test that and set that
+ %% all updates should be forwarded to client.
+ ?match([], 'CosNotifyChannelAdmin_StructuredProxyPushConsumer':
+ obtain_subscription_types(StructuredProxyPushConsumer,
+ 'ALL_NOW_UPDATES_ON')),
+ ?match([], 'CosNotifyChannelAdmin_StructuredProxyPullConsumer':
+ obtain_subscription_types(StructuredProxyPullConsumer,
+ 'ALL_NOW_UPDATES_ON')),
+
+ %% Update the offered types.
+ ?match(ok, 'CosNotifyChannelAdmin_StructuredProxyPushConsumer':
+ offer_change(StructuredProxyPushConsumer, ES1, [])),
+ ?match(ok, 'CosNotifyChannelAdmin_StructuredProxyPullConsumer':
+ offer_change(StructuredProxyPullConsumer, ES1, [])),
+
+ %% To be sure, wait a couple of seconds.
+ timer:sleep(5000),
+ ?match([{'CosNotification_EventType',_,_},
+ {'CosNotification_EventType',_,_}],
+ 'notify_test_StrPushC':doAction(PushStrS, return_data)),
+ ?match([{'CosNotification_EventType',_,_},
+ {'CosNotification_EventType',_,_}],
+ 'notify_test_StrPullC':doAction(PullStrS, return_data)),
+
+ %% Update the offered types. Remove ES1 and add ES2.
+ ?match(ok, 'CosNotifyChannelAdmin_StructuredProxyPushConsumer':
+ offer_change(StructuredProxyPushConsumer, ES2, ES1)),
+ ?match(ok, 'CosNotifyChannelAdmin_StructuredProxyPullConsumer':
+ offer_change(StructuredProxyPullConsumer, ES2, ES1)),
+
+ %% To be sure, wait a couple of seconds.
+ timer:sleep(5000),
+ ?match([{'CosNotification_EventType',_,_},
+ {'CosNotification_EventType',_,_}],
+ 'notify_test_StrPushC':doAction(PushStrS, return_data)),
+ ?match([{'CosNotification_EventType',_,_},
+ {'CosNotification_EventType',_,_}],
+ 'notify_test_StrPullC':doAction(PullStrS, return_data)),
+
+ %% Now, the objects should only contain 'ES2'. Test it.
+ ?match([{'CosNotification_EventType',_,_},
+ {'CosNotification_EventType',_,_}],
+ 'CosNotifyChannelAdmin_StructuredProxyPushConsumer':
+ obtain_subscription_types(StructuredProxyPushConsumer,
+ 'ALL_NOW_UPDATES_ON')),
+ ?match([{'CosNotification_EventType',_,_},
+ {'CosNotification_EventType',_,_}],
+ 'CosNotifyChannelAdmin_StructuredProxyPullConsumer':
+ obtain_subscription_types(StructuredProxyPullConsumer,
+ 'ALL_NOW_UPDATES_ON')),
+
+ %% Now we will use wildcards, empty strings and test if they really
+ %% are ignored if so requested.
+ ES3=[#'CosNotification_EventType'{domain_name = "name1", type_name = "*"},
+ #'CosNotification_EventType'{domain_name = "*", type_name = "type2"}],
+ ES4=[#'CosNotification_EventType'{domain_name = "name1", type_name = "*"},
+ #'CosNotification_EventType'{domain_name = "name2", type_name = ""}],
+ ES5=[#'CosNotification_EventType'{domain_name = "na*", type_name = "type1"}],
+ ES6=[#'CosNotification_EventType'{domain_name = "n*1", type_name = "type1"}],
+ ES7=[#'CosNotification_EventType'{domain_name = "*1", type_name = "type1"}],
+ ES8=[#'CosNotification_EventType'{domain_name = "n*m*1", type_name = "type1"}],
+ ES9=[#'CosNotification_EventType'{domain_name = "n**1", type_name = "type1"}],
+ ES10=[#'CosNotification_EventType'{domain_name = "nam*1", type_name = "type1"}],
+
+ Event1 = ?not_CreateSE("name1","type1",
+ "event_name",
+ [#'CosNotification_Property'{name="property_name",
+ value=any:create(orber_tc:short(), 1)}],
+ [], any:create(orber_tc:null(), null)),
+ Event2 = ?not_CreateSE("name2","type1",
+ "event_name",
+ [#'CosNotification_Property'{name="property_name",
+ value=any:create(orber_tc:short(), 1)}],
+ [], any:create(orber_tc:null(), null)),
+ Event3 = ?not_CreateSE("mame1","type1",
+ "event_name",
+ [#'CosNotification_Property'{name="property_name",
+ value=any:create(orber_tc:short(), 1)}],
+ [], any:create(orber_tc:null(), null)),
+ Event4 = ?not_CreateSE("naame1","type1",
+ "event_name",
+ [#'CosNotification_Property'{name="property_name",
+ value=any:create(orber_tc:short(), 1)}],
+ [], any:create(orber_tc:null(), null)),
+ Event5 = ?not_CreateSE("nname1","type1",
+ "event_name",
+ [#'CosNotification_Property'{name="property_name",
+ value=any:create(orber_tc:short(), 1)}],
+ [], any:create(orber_tc:null(), null)),
+ Event6 = ?not_CreateSE("name12","type1",
+ "event_name",
+ [#'CosNotification_Property'{name="property_name",
+ value=any:create(orber_tc:short(), 1)}],
+ [], any:create(orber_tc:null(), null)),
+
+ ?match(ok, 'CosNotifyChannelAdmin_StructuredProxyPullSupplier':
+ subscription_change(StructuredProxyPullSupplier, ES3, [])),
+
+ ?match(ok,'CosNotifyChannelAdmin_StructuredProxyPushConsumer':push_structured_event(StructuredProxyPushConsumer, Event1)),
+
+ ?match(Event1, 'notify_test_StrPullC':doAction(PullStrC, pull_str)),
+
+ ?match(ok, 'CosNotifyChannelAdmin_StructuredProxyPullSupplier':
+ subscription_change(StructuredProxyPullSupplier, ES4, ES3)),
+ ?match(ok,'CosNotifyChannelAdmin_StructuredProxyPushConsumer':push_structured_event(StructuredProxyPushConsumer, Event1)),
+ ?match(Event1, 'notify_test_StrPullC':doAction(PullStrC, pull_str)),
+
+ ?match(ok, 'CosNotifyChannelAdmin_StructuredProxyPullSupplier':
+ subscription_change(StructuredProxyPullSupplier, ES5, ES4)),
+ ?match(ok,'CosNotifyChannelAdmin_StructuredProxyPushConsumer':push_structured_event(StructuredProxyPushConsumer, Event1)),
+ ?match(Event1, 'notify_test_StrPullC':doAction(PullStrC, pull_str)),
+
+ ?match(ok, 'CosNotifyChannelAdmin_StructuredProxyPullSupplier':
+ subscription_change(StructuredProxyPullSupplier, ES6, ES5)),
+ ?match(ok,'CosNotifyChannelAdmin_StructuredProxyPushConsumer':push_structured_event(StructuredProxyPushConsumer, Event1)),
+ ?match(Event1, 'notify_test_StrPullC':doAction(PullStrC, pull_str)),
+
+ ?match(ok, 'CosNotifyChannelAdmin_StructuredProxyPullSupplier':
+ subscription_change(StructuredProxyPullSupplier, ES7, ES6)),
+ ?match(ok,'CosNotifyChannelAdmin_StructuredProxyPushConsumer':push_structured_event(StructuredProxyPushConsumer, Event1)),
+ ?match(Event1, 'notify_test_StrPullC':doAction(PullStrC, pull_str)),
+
+ ?match(ok, 'CosNotifyChannelAdmin_StructuredProxyPullSupplier':
+ subscription_change(StructuredProxyPullSupplier, ES8, ES7)),
+ ?match(ok,'CosNotifyChannelAdmin_StructuredProxyPushConsumer':push_structured_event(StructuredProxyPushConsumer, Event1)),
+ ?match(Event1, 'notify_test_StrPullC':doAction(PullStrC, pull_str)),
+
+ ?match(ok, 'CosNotifyChannelAdmin_StructuredProxyPullSupplier':
+ subscription_change(StructuredProxyPullSupplier, ES9, ES8)),
+ ?match(ok,'CosNotifyChannelAdmin_StructuredProxyPushConsumer':push_structured_event(StructuredProxyPushConsumer, Event1)),
+ ?match(Event1, 'notify_test_StrPullC':doAction(PullStrC, pull_str)),
+
+ ?match(ok,'CosNotifyChannelAdmin_StructuredProxyPushConsumer':push_structured_event(StructuredProxyPushConsumer, Event2)),
+ ?match(ok,'CosNotifyChannelAdmin_StructuredProxyPushConsumer':push_structured_event(StructuredProxyPushConsumer, Event3)),
+
+ timer:sleep(5000),
+ ?match({_NilStrEvent,false}, 'notify_test_StrPullC':doAction(PullStrC, try_pull_str)),
+
+ ?match(ok, 'CosNotifyChannelAdmin_StructuredProxyPullSupplier':
+ subscription_change(StructuredProxyPullSupplier, ES10, ES9)),
+ ?match(ok,'CosNotifyChannelAdmin_StructuredProxyPushConsumer':push_structured_event(StructuredProxyPushConsumer, Event1)),
+ ?match(Event1, 'notify_test_StrPullC':doAction(PullStrC, pull_str)),
+
+ ?match(ok,'CosNotifyChannelAdmin_StructuredProxyPushConsumer':push_structured_event(StructuredProxyPushConsumer, Event4)),
+ ?match(ok,'CosNotifyChannelAdmin_StructuredProxyPushConsumer':push_structured_event(StructuredProxyPushConsumer, Event5)),
+ ?match(ok,'CosNotifyChannelAdmin_StructuredProxyPushConsumer':push_structured_event(StructuredProxyPushConsumer, Event6)),
+
+ timer:sleep(5000),
+ ?match({_NilStrEvent,false}, 'notify_test_StrPullC':doAction(PullStrC, try_pull_str)),
+
+
+ catch corba:dispose(StructuredProxyPushConsumer),
+ catch corba:dispose(StructuredProxyPullConsumer),
+ catch corba:dispose(StructuredProxyPushSupplier),
+ catch corba:dispose(StructuredProxyPullSupplier),
+ catch corba:dispose(AdminConsumer),
+ catch corba:dispose(AdminSupplier),
+ catch corba:dispose(Ch),
+ catch cosNotificationApp:stop_factory(Fac),
+
+ timer:sleep(5000),
+ ?match(true, corba_object:non_existent(PullStrS)),
+ ?match(true, corba_object:non_existent(PushStrS)),
+ ?match(true, corba_object:non_existent(PullStrC)),
+ ?match(true, corba_object:non_existent(PushStrC)),
+
+ ok.
+
+%%-----------------------------------------------------------------
+%% Filter admin API tests
+%%-----------------------------------------------------------------
+filter_adm_api(doc) -> ["CosNotification filter admin tests", ""];
+filter_adm_api(suite) -> [];
+filter_adm_api(_Config) ->
+ Fac = (catch cosNotificationApp:start_global_factory(?FAC_OPT)),
+ ?match({_,key,_,_,_,_}, Fac),
+ {Ch, _Id1} = (catch 'CosNotifyChannelAdmin_EventChannelFactory':create_channel(Fac, ?defaultQoS, ?defaultAdm)),
+ ?match({_,key,_,_,_,_}, Ch),
+
+ FiFac = 'CosNotifyFilter_FilterFactory':oe_create(),
+ ?match({_,key,_,_,_,_}, FiFac),
+
+ Filter = 'CosNotifyFilter_FilterFactory':create_filter(FiFac,"EXTENDED_TCL"),
+ ?match({_,key,_,_,_,_}, Filter),
+
+ AC=?match({_,key,_,_,_,_},
+ 'CosNotifyChannelAdmin_EventChannel':for_consumers(Ch)),
+ filter_tests('CosNotifyChannelAdmin_ConsumerAdmin', AC, Filter, Ch),
+
+ AS=?match({_,key,_,_,_,_},
+ 'CosNotifyChannelAdmin_EventChannel':for_suppliers(Ch)),
+ filter_tests('CosNotifyChannelAdmin_SupplierAdmin', AS, Filter, Ch),
+
+ PushS=?match({_,key,_,_,_,_},
+ 'CosNotifyChannelAdmin_ConsumerAdmin':obtain_push_supplier(AC)),
+ filter_tests('CosNotifyChannelAdmin_ProxyPushSupplier', PushS, Filter, Ch),
+
+ PullS=?match({_,key,_,_,_,_},
+ 'CosNotifyChannelAdmin_ConsumerAdmin':obtain_pull_supplier(AC)),
+ filter_tests('CosNotifyChannelAdmin_ProxyPullSupplier', PullS, Filter, Ch),
+
+ PushC=?match({_,key,_,_,_,_},
+ 'CosNotifyChannelAdmin_SupplierAdmin':obtain_push_consumer(AS)),
+ filter_tests('CosNotifyChannelAdmin_ProxyPushConsumer', PushC, Filter, Ch),
+
+ PullC=?match({_,key,_,_,_,_},
+ 'CosNotifyChannelAdmin_SupplierAdmin':obtain_pull_consumer(AS)),
+ filter_tests('CosNotifyChannelAdmin_ProxyPullConsumer', PullC, Filter, Ch),
+
+ catch corba:dispose(FiFac),
+ catch corba:dispose(Filter),
+ catch corba:dispose(PushS),
+ catch corba:dispose(PullS),
+ catch corba:dispose(PushC),
+ catch corba:dispose(PullC),
+ catch corba:dispose(AC),
+ catch corba:dispose(AS),
+ catch corba:dispose(Ch),
+ catch cosNotificationApp:stop_factory(Fac),
+ ok.
+
+filter_tests(Mod, Obj, Filter, Ch) ->
+ io:format("############ TESTING MODULE ~p FILTER ############~n", [Mod]),
+ %% No filter added.
+ ?match([], Mod:get_all_filters(Obj)),
+ ?match(ok, Mod:remove_all_filters(Obj)),
+ ?match({'EXCEPTION',{'CosNotifyFilter_FilterNotFound',_}},
+ Mod:get_filter(Obj, 0)),
+ %% Try add a Filter which is not a filter.
+ ?match({'EXCEPTION',{'BAD_PARAM',_,_,_}}, Mod:add_filter(Obj, Ch)),
+ %% Try to remove a single filter.
+ ?match({'EXCEPTION',{'CosNotifyFilter_FilterNotFound',_}},
+ Mod:remove_filter(Obj, 0)),
+ ID = Mod:add_filter(Obj, Filter),
+ ?match([ID], Mod:get_all_filters(Obj)),
+ ?match(Filter, Mod:get_filter(Obj, ID)),
+ ?match(ok, Mod:remove_filter(Obj, ID)),
+ ?match([], Mod:get_all_filters(Obj)),
+ ID2 = Mod:add_filter(Obj, Filter),
+ ?match([ID2], Mod:get_all_filters(Obj)),
+ ?match(ok, Mod:remove_all_filters(Obj)),
+ ?match([], Mod:get_all_filters(Obj)),
+ ok.
+
+%%-----------------------------------------------------------------
+%% Creating different event pushing and pulling API tests
+%%-----------------------------------------------------------------
+events_api(doc) -> ["CosNotification event pushing and pulling tests", ""];
+events_api(suite) -> [];
+events_api(_Config) ->
+ %% Initialize the application.
+ Fac = (catch cosNotificationApp:start_global_factory(?FAC_OPT)),
+ ?match({_,key,_,_,_,_}, Fac),
+ {Ch, Id1} = (catch 'CosNotifyChannelAdmin_EventChannelFactory':create_channel(Fac, ?defaultQoS, ?defaultAdm)),
+ ?match({_,key,_,_,_,_}, Ch),
+ events_api_helper(Fac, Ch, Id1).
+
+events2_api(doc) -> ["CosNotification event pushing and pulling tests II", ""];
+events2_api(suite) -> [];
+events2_api(_Config) ->
+ %% Initialize the application.
+ Fac = (catch cosNotificationApp:start_global_factory(?FAC_OPT)),
+ ?match({_,key,_,_,_,_}, Fac),
+ {Ch, Id1} = (catch 'CosNotifyChannelAdmin_EventChannelFactory':create_channel(Fac, ?defaultQoS2, ?defaultAdm)),
+ ?match({_,key,_,_,_,_}, Ch),
+ events_api_helper(Fac, Ch, Id1).
+
+events_api_helper(Fac, Ch, _Id1) ->
+ %% Now we will set up a test environment, with the following structure:
+ %%
+ %% Channel
+ %% / \
+ %% Supplier Adm Consumer Adm
+ %% / \
+ %% 1 proxy of each possible type
+ %% To each proxy we will connect a test client
+ %% The events will flow in ===>> direction.
+ %%
+ %% For the supplier Admins this include:
+ %% - ProxyPushConsumer
+ %% - SequenceProxyPushConsumer
+ %% - StructuredProxyPushConsumer
+ %% - ProxyPullConsumer
+ %% - SequenceProxyPullConsumer
+ %% - StructuredProxyPullConsumer
+ %%
+ %% For the consumer Admins this include:
+ %% - ProxyPushSupplier
+ %% - SequenceProxyPushSupplier
+ %% - StructuredProxyPushSupplier
+ %% - ProxyPullSupplier
+ %% - SequenceProxyPullSupplier
+ %% - StructuredProxyPullSupplier
+ %%
+ %%
+ %% We will not use any Filters to begin with, just want to make sure we can
+ %% deliver events from all start- to end-points.
+
+ %% Create the Admin objects
+ {AdminSupplier, _ASID}=?match({{_,key,_,_,_,_},_},
+ 'CosNotifyChannelAdmin_EventChannel':new_for_suppliers(Ch,'AND_OP')),
+ {AdminConsumer, _ACID}=?match({{_,key,_,_,_,_},_},
+ 'CosNotifyChannelAdmin_EventChannel':new_for_consumers(Ch,'AND_OP')),
+
+ %% Create Suppliers Proxies
+ {ProxyPullSupplier,_ID1}=?match({{_,key,_,_,_,_},_},
+ 'CosNotifyChannelAdmin_ConsumerAdmin':obtain_notification_pull_supplier(AdminConsumer, 'ANY_EVENT')),
+ {StructuredProxyPullSupplier,_ID2}=?match({{_,key,_,_,_,_},_},
+ 'CosNotifyChannelAdmin_ConsumerAdmin':obtain_notification_pull_supplier(AdminConsumer, 'STRUCTURED_EVENT')),
+ {SequenceProxyPullSupplier,_ID3}=?match({{_,key,_,_,_,_},_},
+ 'CosNotifyChannelAdmin_ConsumerAdmin':obtain_notification_pull_supplier(AdminConsumer, 'SEQUENCE_EVENT')),
+
+ {ProxyPushSupplier,_I4D}=?match({{_,key,_,_,_,_},_},
+ 'CosNotifyChannelAdmin_ConsumerAdmin':obtain_notification_push_supplier(AdminConsumer, 'ANY_EVENT')),
+ {StructuredProxyPushSupplier,_ID5}=?match({{_,key,_,_,_,_},_},
+ 'CosNotifyChannelAdmin_ConsumerAdmin':obtain_notification_push_supplier(AdminConsumer, 'STRUCTURED_EVENT')),
+ {SequenceProxyPushSupplier,_ID6}=?match({{_,key,_,_,_,_},_},
+ 'CosNotifyChannelAdmin_ConsumerAdmin':obtain_notification_push_supplier(AdminConsumer, 'SEQUENCE_EVENT')),
+
+ %% Now we must create a Client for each proxy and connect them.
+ PushAnyC=?match({_,key,_,_,_,_}, 'notify_test_AnyPushC':oe_create(['PUSH_ANY', ProxyPushSupplier],
+ [{local_typecheck, false}])),
+ ?match(ok, 'CosNotifyChannelAdmin_ProxyPushSupplier':connect_any_push_consumer(ProxyPushSupplier, PushAnyC)),
+
+ PushStrC=?match({_,key,_,_,_,_}, 'notify_test_StrPushC':oe_create(['PUSH_STRUCTURED',StructuredProxyPushSupplier],
+ [{local_typecheck, false}])),
+ ?match(ok, 'CosNotifyChannelAdmin_StructuredProxyPushSupplier':connect_structured_push_consumer(StructuredProxyPushSupplier, PushStrC)),
+
+ PushSeqC=?match({_,key,_,_,_,_}, 'notify_test_SeqPushC':oe_create(['PUSH_SEQUENCE',SequenceProxyPushSupplier],
+ [{local_typecheck, false}])),
+ ?match(ok, 'CosNotifyChannelAdmin_SequenceProxyPushSupplier':connect_sequence_push_consumer(SequenceProxyPushSupplier, PushSeqC)),
+
+ PullAnyC=?match({_,key,_,_,_,_}, 'notify_test_AnyPullC':oe_create(['PULL_ANY', ProxyPullSupplier],
+ [{local_typecheck, false}])),
+ ?match(ok, 'CosNotifyChannelAdmin_ProxyPullSupplier':connect_any_pull_consumer(ProxyPullSupplier, PullAnyC)),
+
+ PullStrC=?match({_,key,_,_,_,_}, 'notify_test_StrPullC':oe_create(['PULL_STRUCTURED',StructuredProxyPullSupplier],
+ [{local_typecheck, false}])),
+ ?match(ok, 'CosNotifyChannelAdmin_StructuredProxyPullSupplier':connect_structured_pull_consumer(StructuredProxyPullSupplier, PullStrC)),
+
+ PullSeqC=?match({_,key,_,_,_,_}, 'notify_test_SeqPullC':oe_create(['PULL_SEQUENCE',SequenceProxyPullSupplier],
+ [{local_typecheck, false}])),
+ ?match(ok, 'CosNotifyChannelAdmin_SequenceProxyPullSupplier':connect_sequence_pull_consumer(SequenceProxyPullSupplier, PullSeqC)),
+
+
+ %% Create Consumers Proxies
+ {ProxyPullConsumer,_ID7}=?match({{_,key,_,_,_,_},_},
+ 'CosNotifyChannelAdmin_SupplierAdmin':obtain_notification_pull_consumer(AdminSupplier, 'ANY_EVENT')),
+ {StructuredProxyPullConsumer,_ID8}=?match({{_,key,_,_,_,_},_},
+ 'CosNotifyChannelAdmin_SupplierAdmin':obtain_notification_pull_consumer(AdminSupplier, 'STRUCTURED_EVENT')),
+ {SequenceProxyPullConsumer,_ID9}=?match({{_,key,_,_,_,_},_},
+ 'CosNotifyChannelAdmin_SupplierAdmin':obtain_notification_pull_consumer(AdminSupplier, 'SEQUENCE_EVENT')),
+
+ {ProxyPushConsumer,_ID10}=?match({{_,key,_,_,_,_},_},
+ 'CosNotifyChannelAdmin_SupplierAdmin':obtain_notification_push_consumer(AdminSupplier, 'ANY_EVENT')),
+ {StructuredProxyPushConsumer,_ID11}=?match({{_,key,_,_,_,_},_},
+ 'CosNotifyChannelAdmin_SupplierAdmin':obtain_notification_push_consumer(AdminSupplier, 'STRUCTURED_EVENT')),
+ {SequenceProxyPushConsumer,_ID12}=?match({{_,key,_,_,_,_},_},
+ 'CosNotifyChannelAdmin_SupplierAdmin':obtain_notification_push_consumer(AdminSupplier, 'SEQUENCE_EVENT')),
+
+ %% Now we must create a Client for each proxy and connect them.
+ PushAnyS=?match({_,key,_,_,_,_}, 'notify_test_AnyPushS':oe_create(['PUSH_ANY', ProxyPushConsumer],
+ [{local_typecheck, false}])),
+ ?match(ok, 'CosNotifyChannelAdmin_ProxyPushConsumer':connect_any_push_supplier(ProxyPushConsumer, PushAnyS)),
+
+ PushStrS=?match({_,key,_,_,_,_}, 'notify_test_StrPushS':oe_create(['PUSH_STRUCTURED',StructuredProxyPushConsumer],
+ [{local_typecheck, false}])),
+ ?match(ok, 'CosNotifyChannelAdmin_StructuredProxyPushConsumer':connect_structured_push_supplier(StructuredProxyPushConsumer, PushStrS)),
+
+ PushSeqS=?match({_,key,_,_,_,_}, 'notify_test_SeqPushS':oe_create(['PUSH_SEQUENCE',SequenceProxyPushConsumer],
+ [{local_typecheck, false}])),
+ ?match(ok, 'CosNotifyChannelAdmin_SequenceProxyPushConsumer':connect_sequence_push_supplier(SequenceProxyPushConsumer, PushSeqS)),
+
+ PullAnyS=?match({_,key,_,_,_,_}, 'notify_test_AnyPullS':oe_create(['PULL_ANY', ProxyPullConsumer],
+ [{local_typecheck, false}])),
+ ?match(ok, 'CosNotifyChannelAdmin_ProxyPullConsumer':connect_any_pull_supplier(ProxyPullConsumer, PullAnyS)),
+
+ PullStrS=?match({_,key,_,_,_,_}, 'notify_test_StrPullS':oe_create(['PULL_STRUCTURED',StructuredProxyPullConsumer],
+ [{local_typecheck, false}])),
+ ?match(ok, 'CosNotifyChannelAdmin_StructuredProxyPullConsumer':connect_structured_pull_supplier(StructuredProxyPullConsumer, PullStrS)),
+
+ PullSeqS=?match({_,key,_,_,_,_}, 'notify_test_SeqPullS':oe_create(['PULL_SEQUENCE',SequenceProxyPullConsumer],
+ [{local_typecheck, false}])),
+ ?match(ok, 'CosNotifyChannelAdmin_SequenceProxyPullConsumer':connect_sequence_pull_supplier(SequenceProxyPullConsumer, PullSeqS)),
+
+
+ %% Create a couple of Events to test with.
+ Event = ?not_CreateSE("DomainName","CommunicationsAlarm",
+ "lost_packet",
+ [#'CosNotification_Property'{name="priority",
+ value=any:create(orber_tc:short(), 1)}],
+ [], any:create(orber_tc:null(), null)),
+
+ Event2 = ?not_CreateSE("DomainName","TemperatureAlarm",
+ "over_heated",
+ [#'CosNotification_Property'{name="priority",
+ value=any:create(orber_tc:short(), 10)}],
+ [], any:create(orber_tc:null(), null)),
+
+
+ AnyEvent = any:create(orber_tc:long(), 100),
+
+ StrEvent = ?not_CreateSE("","%ANY","",[],[],AnyEvent),
+ NilAnyEvent = any:create(orber_tc:null(), null),
+ NilStrEvent = ?not_CreateSE("","","",[],[],NilAnyEvent),
+
+ ConvertedStr = any:create('CosNotification_StructuredEvent':tc(), Event),
+
+ io:format("###################### PUSH STRUCTURED ########################"),
+
+ %% Test with pushing a structured event.
+ ?match(ok,'CosNotifyChannelAdmin_StructuredProxyPushConsumer':push_structured_event(StructuredProxyPushConsumer, Event)),
+
+ %% Wait for a while so we are sure that all events have been delivered as far
+ %% as the Notification service can automatically.
+ timer:sleep(5000),
+
+ %% Check if the Clients have received and stored the events.
+ ?match([{any,_,Event}], 'notify_test_AnyPushC':doAction(PushAnyC, return_data)),
+ ?match([Event], 'notify_test_StrPushC':doAction(PushStrC, return_data)),
+ ?match([Event], 'notify_test_SeqPushC':doAction(PushSeqC, return_data)),
+
+ %% Instruct the Clients to pull the events and check if they match.
+ ?match({any,_,Event}, 'notify_test_AnyPullC':doAction(PullAnyC, pull_any)),
+ ?match(Event, 'notify_test_StrPullC':doAction(PullStrC, pull_str)),
+ ?match([Event], 'notify_test_SeqPullC':doAction(PullSeqC, {pull_seq,1})),
+
+ io:format("###################### PUSH SEQUENCE ########################"),
+
+ %% Create an Event Sequence and push it.
+ EventSeq = [Event, Event2],
+
+ %% Test with pushing a event sequence.
+ ?match(ok,'CosNotifyChannelAdmin_SequenceProxyPushConsumer':push_structured_events(SequenceProxyPushConsumer, EventSeq)),
+
+ %% Wait for a while so we are sure that all events have been delivered as far
+ %% as the Notification service can automatically.
+ timer:sleep(5000),
+
+ %% Instruct the Clients to pull the events and check if they match.
+ ?match({any,_,Event}, 'notify_test_AnyPullC':doAction(PullAnyC, pull_any)),
+ ?match(Event, 'notify_test_StrPullC':doAction(PullStrC, pull_str)),
+ ?match([Event,Event2], 'notify_test_SeqPullC':doAction(PullSeqC, {pull_seq,2})),
+ ?match({any,_,Event2}, 'notify_test_AnyPullC':doAction(PullAnyC, pull_any)),
+ ?match(Event2, 'notify_test_StrPullC':doAction(PullStrC, pull_str)),
+
+ %% Check if the Push Clients have received and stored the events.
+ ?match([{any,_,Event}, {any,_,Event2}], 'notify_test_AnyPushC':doAction(PushAnyC, return_data)),
+ ?match([Event, Event2], 'notify_test_StrPushC':doAction(PushStrC, return_data)),
+ ?match([Event, Event2], 'notify_test_SeqPushC':doAction(PushSeqC, return_data)),
+
+ io:format("###################### PUSH ANY ########################"),
+
+ %% Test with pushing an any event.
+ ?match(ok,'CosEventChannelAdmin_ProxyPushConsumer':push(ProxyPushConsumer, AnyEvent)),
+
+ %% Wait for a while so we are sure that all events have been delivered as far
+ %% as the Notification service can automatically.
+ timer:sleep(5000),
+
+ %% Check if the Clients have received and stored the events.
+ ?match([AnyEvent], 'notify_test_AnyPushC':doAction(PushAnyC, return_data)),
+ ?match([StrEvent], 'notify_test_StrPushC':doAction(PushStrC, return_data)),
+ ?match([StrEvent], 'notify_test_SeqPushC':doAction(PushSeqC, return_data)),
+
+ %% Instruct the Clients to pull the events and check if they match.
+ ?match(AnyEvent, 'notify_test_AnyPullC':doAction(PullAnyC, pull_any)),
+ ?match(StrEvent, 'notify_test_StrPullC':doAction(PullStrC, pull_str)),
+ ?match([StrEvent], 'notify_test_SeqPullC':doAction(PullSeqC, {pull_seq,10})),
+
+
+
+ io:format("###################### PUSH CONVERTED ANY #############"),
+
+ %% Test with pushing a structured event.
+ ?match(ok,'CosNotifyChannelAdmin_StructuredProxyPushConsumer':push_structured_event(StructuredProxyPushConsumer, StrEvent)),
+
+ %% Wait for a while so we are sure that all events have been delivered as far
+ %% as the Notification service can automatically.
+ timer:sleep(5000),
+
+ %% Check if the Clients have received and stored the events.
+ ?match([AnyEvent], 'notify_test_AnyPushC':doAction(PushAnyC, return_data)),
+ ?match([StrEvent], 'notify_test_StrPushC':doAction(PushStrC, return_data)),
+ ?match([StrEvent], 'notify_test_SeqPushC':doAction(PushSeqC, return_data)),
+
+ %% Instruct the Clients to pull the events and check if they match.
+ ?match(AnyEvent, 'notify_test_AnyPullC':doAction(PullAnyC, pull_any)),
+ ?match(StrEvent, 'notify_test_StrPullC':doAction(PullStrC, pull_str)),
+ ?match([StrEvent], 'notify_test_SeqPullC':doAction(PullSeqC, {pull_seq,1})),
+
+
+ io:format("###################### PUSH CONVERTED STRUCTURED ########"),
+
+ %% Test with pushing an any event.
+ ?match(ok,'CosEventChannelAdmin_ProxyPushConsumer':push(ProxyPushConsumer, ConvertedStr)),
+
+ %% Wait for a while so we are sure that all events have been delivered as far
+ %% as the Notification service can automatically.
+ timer:sleep(5000),
+
+ %% Check if the Clients have received and stored the events.
+ ?match([ConvertedStr], 'notify_test_AnyPushC':doAction(PushAnyC, return_data)),
+ ?match([Event], 'notify_test_StrPushC':doAction(PushStrC, return_data)),
+ ?match([Event], 'notify_test_SeqPushC':doAction(PushSeqC, return_data)),
+
+ %% Instruct the Clients to pull the events and check if they match.
+ ?match(ConvertedStr, 'notify_test_AnyPullC':doAction(PullAnyC, pull_any)),
+ ?match(Event, 'notify_test_StrPullC':doAction(PullStrC, pull_str)),
+ ?match([Event], 'notify_test_SeqPullC':doAction(PullSeqC, {pull_seq,10})),
+
+
+ io:format("###################### TRY PULL ########################"),
+
+ %% Now we will push an any event after a delay. This means that try_pull-functions,
+ %% since it's not blocking, will return, [], NilAny or NilStructured events and
+ %% the Boolean false.
+ spawn(notify_test_impl, delay, [ProxyPushConsumer, AnyEvent, 20000,
+ 'CosEventChannelAdmin_ProxyPushConsumer',push]),
+ ?match([], 'notify_test_AnyPushC':doAction(PushAnyC, return_data)),
+ ?match([], 'notify_test_StrPushC':doAction(PushStrC, return_data)),
+ ?match([], 'notify_test_SeqPushC':doAction(PushSeqC, return_data)),
+
+ %% Instruct the Clients to pull the events and check if they match.
+ ?match({NilAnyEvent,false}, 'notify_test_AnyPullC':doAction(PullAnyC, try_pull_any)),
+ ?match({NilStrEvent,false}, 'notify_test_StrPullC':doAction(PullStrC, try_pull_str)),
+ ?match({[],false}, 'notify_test_SeqPullC':doAction(PullSeqC, {try_pull_seq,10})),
+
+
+ %% Instruct the Clients to pull the events and check if they match.
+ %% Pull is blocking so in the print-out we should see that nothing
+ %% is returned until the pushed event reaches the end proxies.
+ ?match(AnyEvent, 'notify_test_AnyPullC':doAction(PullAnyC, pull_any)),
+ ?match(StrEvent, 'notify_test_StrPullC':doAction(PullStrC, pull_str)),
+ ?match([StrEvent], 'notify_test_SeqPullC':doAction(PullSeqC, {pull_seq,1})),
+
+ %% To make sure there are no other circumstanses which lead to a delay we
+ %% hold for some time.
+ timer:sleep(5000),
+ %% Check if the Clients have received and stored the events.
+ ?match([AnyEvent], 'notify_test_AnyPushC':doAction(PushAnyC, return_data)),
+ ?match([StrEvent], 'notify_test_StrPushC':doAction(PushStrC, return_data)),
+ ?match([StrEvent], 'notify_test_SeqPushC':doAction(PushSeqC, return_data)),
+
+ %% Test with pushing a event sequence but only pull sequences of length 1.
+ ?match(ok,'CosNotifyChannelAdmin_SequenceProxyPushConsumer':push_structured_events(SequenceProxyPushConsumer, EventSeq)),
+
+ %% Wait for a while so we are sure that all events have been delivered as far
+ %% as the Notification service can automatically.
+ timer:sleep(5000),
+ %% Pull 1 event at a time.
+ ?match([Event], 'notify_test_SeqPullC':doAction(PullSeqC, {pull_seq,1})),
+ ?match([Event2], 'notify_test_SeqPullC':doAction(PullSeqC, {pull_seq,1})),
+
+ %% Following cases already tested; done for clean up.
+ ?match({any,_,Event}, 'notify_test_AnyPullC':doAction(PullAnyC, pull_any)),
+ ?match(Event, 'notify_test_StrPullC':doAction(PullStrC, pull_str)),
+ ?match({any,_,Event2}, 'notify_test_AnyPullC':doAction(PullAnyC, pull_any)),
+ ?match(Event2, 'notify_test_StrPullC':doAction(PullStrC, pull_str)),
+ ?match([{any,_,Event}, {any,_,Event2}], 'notify_test_AnyPushC':doAction(PushAnyC, return_data)),
+ ?match([Event, Event2], 'notify_test_StrPushC':doAction(PushStrC, return_data)),
+ ?match([Event, Event2], 'notify_test_SeqPushC':doAction(PushSeqC, return_data)),
+ %% clean up done
+
+
+ io:format("###################### PROXY PULLER ########################"),
+
+ %% Now we will just add Events to a cleint and wait for the Notification service
+ %% to pull the events and forward them to the consumer clients.
+ ?match(ok, 'notify_test_SeqPushC':doAction(PullAnyS, {set_data, [AnyEvent]})),
+
+
+ %% Instruct the Clients to pull the events and check if they match.
+ %% Pull is blocking so in the print-out we should see that nothing
+ %% is returned until the pushed event reaches the end proxies.
+ ?match(AnyEvent, 'notify_test_AnyPullC':doAction(PullAnyC, pull_any)),
+ ?match(StrEvent, 'notify_test_StrPullC':doAction(PullStrC, pull_str)),
+ ?match([StrEvent], 'notify_test_SeqPullC':doAction(PullSeqC, {pull_seq,10})),
+
+ %% To make sure there are no other circumstanses which lead to a delay we
+ %% hold for some time.
+ timer:sleep(5000),
+ %% Check if the Clients have received and stored the events.
+ ?match([AnyEvent], 'notify_test_AnyPushC':doAction(PushAnyC, return_data)),
+ ?match([StrEvent], 'notify_test_StrPushC':doAction(PushStrC, return_data)),
+ ?match([StrEvent], 'notify_test_SeqPushC':doAction(PushSeqC, return_data)),
+
+ io:format("###################### SUSPENDED CONNECTION ################"),
+
+
+ %% Suspend the connections
+ ?match(ok,'CosNotifyChannelAdmin_SequenceProxyPushSupplier':suspend_connection(SequenceProxyPushSupplier)),
+ ?match(ok,'CosNotifyChannelAdmin_StructuredProxyPushSupplier':suspend_connection(StructuredProxyPushSupplier)),
+
+ %% Test with pushing a event sequence.
+ ?match(ok,'CosNotifyChannelAdmin_SequenceProxyPushConsumer':push_structured_events(SequenceProxyPushConsumer, EventSeq)),
+
+ %% Wait for a while so we are sure that all events have been delivered as far
+ %% as the Notification service can automatically.
+ timer:sleep(5000),
+
+ %% Instruct the Clients to pull the events and check if they match.
+ ?match({any,_,Event}, 'notify_test_AnyPullC':doAction(PullAnyC, pull_any)),
+ ?match(Event, 'notify_test_StrPullC':doAction(PullStrC, pull_str)),
+ ?match([Event,Event2], 'notify_test_SeqPullC':doAction(PullSeqC, {pull_seq,2})),
+ ?match({any,_,Event2}, 'notify_test_AnyPullC':doAction(PullAnyC, pull_any)),
+ ?match(Event2, 'notify_test_StrPullC':doAction(PullStrC, pull_str)),
+
+ %% Check if the Any Client have received and stored the events.
+ ?match([{any,_,Event}, {any,_,Event2}], 'notify_test_AnyPushC':doAction(PushAnyC, return_data)),
+
+ %% Check if the other Clients have received any events. Error if have.
+ ?match([], 'notify_test_StrPushC':doAction(PushStrC, return_data)),
+ ?match([], 'notify_test_SeqPushC':doAction(PushSeqC, return_data)),
+
+ ?match(ok,'CosNotifyChannelAdmin_SequenceProxyPushSupplier':resume_connection(SequenceProxyPushSupplier)),
+ ?match(ok,'CosNotifyChannelAdmin_StructuredProxyPushSupplier':resume_connection(StructuredProxyPushSupplier)),
+
+ %% To be sure the test case don't fail due to time-race, sleep.
+ timer:sleep(5000),
+
+ ?match([Event, Event2], 'notify_test_StrPushC':doAction(PushStrC, return_data)),
+ ?match([Event, Event2], 'notify_test_SeqPushC':doAction(PushSeqC, return_data)),
+
+
+ io:format("###################### FILTER EVENTS #######################"),
+
+ %% Now we will add filters and see if the system behaves correctly.
+ FiFac = 'CosNotifyFilter_FilterFactory':oe_create(),
+ Filter = 'CosNotifyFilter_FilterFactory':create_filter(FiFac,"EXTENDED_TCL"),
+ %% Add constraints to the Filter
+ ?line[{_,_,CID1},{_,_,CID2}]=
+ ?match([{'CosNotifyFilter_ConstraintInfo',_,_}, {'CosNotifyFilter_ConstraintInfo',_,_}],
+ 'CosNotifyFilter_Filter':add_constraints(Filter,
+ [#'CosNotifyFilter_ConstraintExp'{event_types =
+ [#'CosNotification_EventType'{
+ domain_name = "Spare*",
+ type_name = "MOVIE"}],
+ constraint_expr = "$type_name == 'MOVIE' and (('groucho' in $starlist) + ('chico' in $starlist) + ('harpo' in $starlist) + ('zeppo' in $starlist) + ('gummo' in $starlist)) > 2"},
+ #'CosNotifyFilter_ConstraintExp'{event_types =
+ [#'CosNotification_EventType'{
+ domain_name = "*",
+ type_name = "TestResults"}],
+ constraint_expr = "$test._length == 3 and ($test[0].score + $test[1].score + $test[2].score)/3 >=80"}])),
+
+ ?match([{'CosNotifyFilter_ConstraintInfo',_,CID2}, {'CosNotifyFilter_ConstraintInfo',_,CID1}],
+ 'CosNotifyFilter_Filter':get_all_constraints(Filter)),
+ ?match([{'CosNotifyFilter_ConstraintInfo',_,CID1}],
+ 'CosNotifyFilter_Filter':get_constraints(Filter, [CID1])),
+
+ %% Associate the Filter with different objects.
+ %% Since we use the same filter for both objects the events will never reach the admin.
+ _FilterID = 'CosNotifyChannelAdmin_ConsumerAdmin':add_filter(AdminConsumer, Filter),
+
+ _FilterID2 = 'CosNotifyChannelAdmin_StructuredProxyPushConsumer':add_filter(StructuredProxyPushConsumer, Filter),
+ event_filtering(FiFac, Filter, AdminConsumer, StructuredProxyPushConsumer, PushAnyC,
+ PushStrC, PushSeqC, PullAnyC, PullStrC, PullSeqC),
+ %% Remove the proxy filter so we can check if the events are filtered correctly by the admin.
+ ?match(ok, 'CosNotifyChannelAdmin_StructuredProxyPushConsumer':remove_all_filters(StructuredProxyPushConsumer)),
+ event_filtering(FiFac, Filter, AdminConsumer, StructuredProxyPushConsumer, PushAnyC,
+ PushStrC, PushSeqC, PullAnyC, PullStrC, PullSeqC),
+
+
+ catch corba:dispose(Filter),
+ catch corba:dispose(FiFac),
+ catch corba:dispose(SequenceProxyPushConsumer),
+ catch corba:dispose(StructuredProxyPushConsumer),
+ catch corba:dispose(ProxyPushConsumer),
+ catch corba:dispose(SequenceProxyPullConsumer),
+ catch corba:dispose(StructuredProxyPullConsumer),
+ catch corba:dispose(ProxyPullConsumer),
+ catch corba:dispose(SequenceProxyPushSupplier),
+ catch corba:dispose(StructuredProxyPushSupplier),
+ catch corba:dispose(ProxyPushSupplier),
+ catch corba:dispose(SequenceProxyPullSupplier),
+ catch corba:dispose(StructuredProxyPullSupplier),
+ catch corba:dispose(ProxyPullSupplier),
+ catch corba:dispose(AdminConsumer),
+ catch corba:dispose(AdminSupplier),
+ catch corba:dispose(Ch),
+ catch cosNotificationApp:stop_factory(Fac),
+ %% The Clients should have terminated by now. Check if it is so.
+ timer:sleep(5000),
+ ?match(true, corba_object:non_existent(PullSeqS)),
+ ?match(true, corba_object:non_existent(PullStrS)),
+ ?match(true, corba_object:non_existent(PullAnyS)),
+ ?match(true, corba_object:non_existent(PushSeqS)),
+ ?match(true, corba_object:non_existent(PushStrS)),
+ ?match(true, corba_object:non_existent(PushAnyS)),
+ ?match(true, corba_object:non_existent(PullSeqC)),
+ ?match(true, corba_object:non_existent(PullStrC)),
+ ?match(true, corba_object:non_existent(PullAnyC)),
+ ?match(true, corba_object:non_existent(PushSeqC)),
+ ?match(true, corba_object:non_existent(PushStrC)),
+ ?match(true, corba_object:non_existent(PushAnyC)),
+ ok.
+
+event_filtering(_FiFac, _Filter, _AdminConsumer, StructuredProxyPushConsumer, PushAnyC, PushStrC, PushSeqC, PullAnyC, PullStrC, PullSeqC) ->
+ NilAnyEvent = any:create(orber_tc:null(), null),
+ NilStrEvent = ?not_CreateSE("","","",[],[],NilAnyEvent),
+
+ TrueEvent1 = ?not_CreateSE("SpareTime","MOVIE",
+ "EventName",
+ [#'CosNotification_Property'{name="starlist",
+ value=any:create(orber_tc:sequence(orber_tc:string(0),0),
+ ["groucho", "harpo", "sam", "gummo"])}],
+ [], any:create(orber_tc:null(), null)),
+ TrueEvent2 = ?not_CreateSE("Studies","TestResults",
+ "EventName", [],
+ [#'CosNotification_Property'{name="test",
+ value=any:create(orber_tc:array(notify_test_data:tc(),3),
+ {#notify_test_data{score=75,
+ name="name"},
+ #notify_test_data{score=80,
+ name="name"},
+ #notify_test_data{score=85,
+ name="name"}})}],
+ any:create(orber_tc:null(), null)),
+
+ FalseEvent1 = ?not_CreateSE("SpareTime","MOVIE",
+ "EventName",
+ [#'CosNotification_Property'{name="starlist",
+ value=any:create(orber_tc:sequence(orber_tc:string(0),0),
+ ["frodo", "bilbo", "sam", "gummo"])}],
+ [], any:create(orber_tc:null(), null)),
+ FalseEvent2 = ?not_CreateSE("Studies","TestResults",
+ "EventName", [],
+ [#'CosNotification_Property'{name="test",
+ value=any:create(orber_tc:array(notify_test_data:tc(),3),
+ {#notify_test_data{score=75,
+ name="name"},
+ #notify_test_data{score=80,
+ name="name"},
+ #notify_test_data{score=80,
+ name="name"}})}],
+ any:create(orber_tc:null(), null)),
+ %% Test with pushing the first structured event that should not be filtered away.
+ ?match(ok,'CosNotifyChannelAdmin_StructuredProxyPushConsumer':push_structured_event(StructuredProxyPushConsumer, TrueEvent1)),
+
+ %% Wait for a while so we are sure that all events have been delivered as far
+ %% as the Notification service can automatically.
+ timer:sleep(5000),
+
+ %% Check if the Clients have received and stored the events.
+ ?match([{any,_,TrueEvent1}], 'notify_test_AnyPushC':doAction(PushAnyC, return_data)),
+ ?match([TrueEvent1], 'notify_test_StrPushC':doAction(PushStrC, return_data)),
+ ?match([TrueEvent1], 'notify_test_SeqPushC':doAction(PushSeqC, return_data)),
+
+ %% Instruct the Clients to pull the events and check if they match.
+ ?match({any,_,TrueEvent1}, 'notify_test_AnyPullC':doAction(PullAnyC, pull_any)),
+ ?match(TrueEvent1, 'notify_test_StrPullC':doAction(PullStrC, pull_str)),
+ ?match([TrueEvent1], 'notify_test_SeqPullC':doAction(PullSeqC, {pull_seq,1})),
+
+ %% Test with pushing the second structured event that should not be filtered away.
+ ?match(ok,'CosNotifyChannelAdmin_StructuredProxyPushConsumer':push_structured_event(StructuredProxyPushConsumer, TrueEvent2)),
+
+ %% Wait for a while so we are sure that all events have been delivered as far
+ %% as the Notification service can automatically.
+ timer:sleep(5000),
+
+ %% Check if the Clients have received and stored the events.
+ ?match([{any,_,TrueEvent2}], 'notify_test_AnyPushC':doAction(PushAnyC, return_data)),
+ ?match([TrueEvent2], 'notify_test_StrPushC':doAction(PushStrC, return_data)),
+ ?match([TrueEvent2], 'notify_test_SeqPushC':doAction(PushSeqC, return_data)),
+
+ %% Instruct the Clients to pull the events and check if they match.
+ ?match({any,_,TrueEvent2}, 'notify_test_AnyPullC':doAction(PullAnyC, pull_any)),
+ ?match(TrueEvent2, 'notify_test_StrPullC':doAction(PullStrC, pull_str)),
+ ?match([TrueEvent2], 'notify_test_SeqPullC':doAction(PullSeqC, {pull_seq,1})),
+
+ %% Test with pushing the first structured event that should be filtered away.
+ ?match(ok,'CosNotifyChannelAdmin_StructuredProxyPushConsumer':push_structured_event(StructuredProxyPushConsumer, FalseEvent1)),
+
+ %% Wait for a while so we are sure that all events have been delivered as far
+ %% as the Notification service can automatically.
+ timer:sleep(5000),
+
+ %% Check if the Clients have received and stored the events.
+ ?match([], 'notify_test_AnyPushC':doAction(PushAnyC, return_data)),
+ ?match([], 'notify_test_StrPushC':doAction(PushStrC, return_data)),
+ ?match([], 'notify_test_SeqPushC':doAction(PushSeqC, return_data)),
+
+ %% Instruct the Clients to pull the events and check if they match.
+ ?match({NilAnyEvent,false}, 'notify_test_AnyPullC':doAction(PullAnyC, try_pull_any)),
+ ?match({NilStrEvent,false}, 'notify_test_StrPullC':doAction(PullStrC, try_pull_str)),
+ ?match({[],false}, 'notify_test_SeqPullC':doAction(PullSeqC, {try_pull_seq,10})),
+
+ %% Test with pushing the second structured event that should be filtered away.
+ ?match(ok,'CosNotifyChannelAdmin_StructuredProxyPushConsumer':push_structured_event(StructuredProxyPushConsumer, FalseEvent2)),
+
+ %% Wait for a while so we are sure that all events have been delivered as far
+ %% as the Notification service can automatically.
+ timer:sleep(5000),
+
+ %% Check if the Clients have received and stored the events.
+ ?match([], 'notify_test_AnyPushC':doAction(PushAnyC, return_data)),
+ ?match([], 'notify_test_StrPushC':doAction(PushStrC, return_data)),
+ ?match([], 'notify_test_SeqPushC':doAction(PushSeqC, return_data)),
+
+ %% Instruct the Clients to pull the events and check if they match.
+ ?match({NilAnyEvent,false}, 'notify_test_AnyPullC':doAction(PullAnyC, try_pull_any)),
+ ?match({NilStrEvent,false}, 'notify_test_StrPullC':doAction(PullStrC, try_pull_str)),
+ ?match({[],false}, 'notify_test_SeqPullC':doAction(PullSeqC, {try_pull_seq,10})).
+
+
+
+%%-----------------------------------------------------------------
+%% Creating different cosEvent API tests
+%%-----------------------------------------------------------------
+cosevent_api(doc) -> ["CosNotification Objects tested with CosEvent API", ""];
+cosevent_api(suite) -> [];
+cosevent_api(_Config) ->
+ Fac = (catch cosNotificationApp:start_global_factory(?FAC_OPT)),
+ ?match({_,key,_,_,_,_}, Fac),
+ {Ch, _Id1} = (catch 'CosNotifyChannelAdmin_EventChannelFactory':create_channel(Fac, ?defaultQoS, ?defaultAdm)),
+ ?match({_,key,_,_,_,_}, Ch),
+ AC=?match({_,key,_,_,_,_},
+ 'CosEventChannelAdmin_EventChannel':for_consumers(Ch)),
+ AS=?match({_,key,_,_,_,_},
+ 'CosEventChannelAdmin_EventChannel':for_suppliers(Ch)),
+
+ PushS=?match({_,key,_,_,_,_},
+ 'CosEventChannelAdmin_ConsumerAdmin':obtain_push_supplier(AC)),
+ PullS=?match({_,key,_,_,_,_},
+ 'CosEventChannelAdmin_ConsumerAdmin':obtain_pull_supplier(AC)),
+
+ PushC=?match({_,key,_,_,_,_},
+ 'CosEventChannelAdmin_SupplierAdmin':obtain_push_consumer(AS)),
+ PullC=?match({_,key,_,_,_,_},
+ 'CosEventChannelAdmin_SupplierAdmin':obtain_pull_consumer(AS)),
+
+ PushAnyC=?match({_,key,_,_,_,_},
+ 'notify_test_AnyPushC':oe_create(['PUSH_ANY', PushC],
+ [{local_typecheck, false}])),
+ PushStrC=?match({_,key,_,_,_,_},
+ 'notify_test_StrPushC':oe_create(['PUSH_STRUCTURED',false],
+ [{local_typecheck, false}])),
+ PushSeqC=?match({_,key,_,_,_,_},
+ 'notify_test_SeqPushC':oe_create(['PUSH_SEQUENCE',false],
+ [{local_typecheck, false}])),
+
+ PullAnyC=?match({_,key,_,_,_,_},
+ 'notify_test_AnyPullC':oe_create(['PULL_ANY', PullC],
+ [{local_typecheck, false}])),
+ PullStrC=?match({_,key,_,_,_,_},
+ 'notify_test_StrPullC':oe_create(['PULL_STRUCTURED',false],
+ [{local_typecheck, false}])),
+ PullSeqC=?match({_,key,_,_,_,_},
+ 'notify_test_SeqPullC':oe_create(['PULL_SEQUENCE',false],
+ [{local_typecheck, false}])),
+
+ PushAnyS=?match({_,key,_,_,_,_},
+ 'notify_test_AnyPushS':oe_create(['PUSH_ANY', PushC],
+ [{local_typecheck, false}])),
+ PushStrS=?match({_,key,_,_,_,_},
+ 'notify_test_StrPushS':oe_create(['PUSH_STRUCTURED',false],
+ [{local_typecheck, false}])),
+ PushSeqS=?match({_,key,_,_,_,_},
+ 'notify_test_SeqPushS':oe_create(['PUSH_SEQUENCE',false],
+ [{local_typecheck, false}])),
+
+ PullAnyS=?match({_,key,_,_,_,_},
+ 'notify_test_AnyPullS':oe_create(['PULL_ANY', PullS],
+ [{local_typecheck, false}])),
+ PullStrS=?match({_,key,_,_,_,_},
+ 'notify_test_StrPullS':oe_create(['PULL_STRUCTURED',false],
+ [{local_typecheck, false}])),
+ PullSeqS=?match({_,key,_,_,_,_},
+ 'notify_test_SeqPullS':oe_create(['PULL_SEQUENCE',false],
+ [{local_typecheck, false}])),
+
+ %% In the OMG specification Proxies do not inherrit from CosEvent. Must use
+ %% Notify interface.
+ ?match({'EXCEPTION',{'BAD_PARAM',_,_,_}},
+ 'CosEventChannelAdmin_ProxyPullConsumer':connect_pull_supplier(PullC, PushStrS)),
+
+ ?match(ok,
+ 'CosEventChannelAdmin_ProxyPushSupplier':connect_push_consumer(PushS, PushAnyC)),
+ ?match(ok,
+ 'CosEventChannelAdmin_ProxyPullSupplier':connect_pull_consumer(PullS, PullAnyC)),
+
+ ?match(ok,
+ 'CosEventChannelAdmin_ProxyPushConsumer':connect_push_supplier(PushC, PushAnyS)),
+ ?match(ok,
+ 'CosEventChannelAdmin_ProxyPullConsumer':connect_pull_supplier(PullC, PullAnyS)),
+
+ ?match({'EXCEPTION',{'CosEventChannelAdmin_AlreadyConnected',_}},
+ 'CosEventChannelAdmin_ProxyPullConsumer':connect_pull_supplier(PullC, PullAnyS)),
+
+ ?match({'EXCEPTION',{'CosEventChannelAdmin_AlreadyConnected',_}},
+ 'CosNotifyChannelAdmin_ProxyPullConsumer':connect_pull_supplier(PullC, PullAnyS)),
+
+ ?match(true, corba_object:is_a(PushS, "IDL:omg.org/CosNotifyChannelAdmin/ProxyPushSupplier:1.0")),
+ ?match(true, corba_object:is_a(PushS, "IDL:omg.org/CosEventChannelAdmin/ProxyPushSupplier:1.0")),
+
+ catch corba:dispose(PushStrC),
+ catch corba:dispose(PushSeqC),
+ catch corba:dispose(PullStrC),
+ catch corba:dispose(PullSeqC),
+ catch corba:dispose(PushStrS),
+ catch corba:dispose(PushSeqS),
+ catch corba:dispose(PullStrS),
+ catch corba:dispose(PullSeqS),
+ catch corba:dispose(PushS),
+ catch corba:dispose(PullS),
+ catch corba:dispose(PushC),
+ catch corba:dispose(PullC),
+ catch corba:dispose(AC),
+ catch corba:dispose(AS),
+ catch corba:dispose(Ch),
+ catch cosNotificationApp:stop_factory(Fac),
+
+ %% The Clients should have terminated by now. Check if it is so.
+ timer:sleep(5000),
+ ?match(true, corba_object:non_existent(PullAnyS)),
+ ?match(true, corba_object:non_existent(PushAnyS)),
+ ?match(true, corba_object:non_existent(PullAnyC)),
+ ?match(true, corba_object:non_existent(PushAnyC)),
+
+
+ ok.
+
+%%-----------------------------------------------------------------
+%% AdminPropertiesAdmin API tests
+%%-----------------------------------------------------------------
+adm_api(doc) -> ["CosNotification AdminPropertiesAdmin tests", ""];
+adm_api(suite) -> [];
+adm_api(_Config) ->
+ Fac = (catch cosNotificationApp:start_global_factory(?FAC_OPT)),
+ ?match({_,key,_,_,_,_}, Fac),
+
+ %% We need a few AdminProp:s to "play" with.
+ MQ0 = [#'CosNotification_Property'{name='CosNotification':'MaxQueueLength'(),
+ value=any:create(orber_tc:long(), 0)}],
+ MC0 = [#'CosNotification_Property'{name='CosNotification':'MaxConsumers'(),
+ value=any:create(orber_tc:long(), 0)}],
+ MS0 = [#'CosNotification_Property'{name='CosNotification':'MaxSuppliers'(),
+ value=any:create(orber_tc:long(), 0)}],
+ MQError1 = [#'CosNotification_Property'{name='CosNotification':'MaxQueueLength'(),
+ value=any:create(orber_tc:'float'(), 1.5)}],
+ MQError2 = [#'CosNotification_Property'{name='CosNotification':'MaxQueueLength'(),
+ value=any:create(orber_tc:long(), -1)}],
+
+ {Ch, _Id1} = (catch 'CosNotifyChannelAdmin_EventChannelFactory':create_channel(Fac, ?defaultQoS, ?defaultAdm)),
+ ?match({_,key,_,_,_,_}, Ch),
+
+ %% Set new admin
+ ?match(ok, 'CosNotification_AdminPropertiesAdmin':set_admin(Ch, MQ0)),
+ %% It should be a list of three items. If we support more admin:s this
+ %% must be updated.
+ ?match([_,_,_], 'CosNotification_AdminPropertiesAdmin':get_admin(Ch)),
+
+ %% Try to set admin with an uncorrect value, i.e., not integer >= 0.
+ ?match({'EXCEPTION',{'CosNotification_UnsupportedAdmin',_,_}},
+ 'CosNotification_AdminPropertiesAdmin':set_admin(Ch, MQError1)),
+ ?match({'EXCEPTION',{'CosNotification_UnsupportedAdmin',_,_}},
+ 'CosNotification_AdminPropertiesAdmin':set_admin(Ch, MQError2)),
+
+ %% Try setting the other two admins and chech if the value is correct.
+ ?match(ok, 'CosNotification_AdminPropertiesAdmin':set_admin(Ch, MC0)),
+ ?match([_,_,_], 'CosNotification_AdminPropertiesAdmin':get_admin(Ch)),
+
+ ?match(ok, 'CosNotification_AdminPropertiesAdmin':set_admin(Ch, MS0)),
+ ?match([_,_,_], 'CosNotification_AdminPropertiesAdmin':get_admin(Ch)),
+
+ catch corba:dispose(Ch),
+ catch cosNotificationApp:stop_factory(Fac),
+ ok.
+
+
+%%-----------------------------------------------------------------
+%% QoSAdm API tests
+%%-----------------------------------------------------------------
+qos_api(doc) -> ["CosNotification QoSAdmin tests", ""];
+qos_api(suite) -> [];
+qos_api(_Config) ->
+ Fac = (catch cosNotificationApp:start_global_factory(?FAC_OPT)),
+ ?match({_,key,_,_,_,_}, Fac),
+
+ {Ch, _Id1} = (catch 'CosNotifyChannelAdmin_EventChannelFactory':create_channel(Fac, ?defaultQoS, ?defaultAdm)),
+ ?match({_,key,_,_,_,_}, Ch),
+
+
+ QoSPersistent = [#'CosNotification_Property'{name='CosNotification':'ConnectionReliability'(),
+ value=any:create(orber_tc:short(),
+ 'CosNotification':'Persistent'())}],
+ QoSBestEffort = [#'CosNotification_Property'{name='CosNotification':'ConnectionReliability'(),
+ value=any:create(orber_tc:short(),
+ 'CosNotification':'BestEffort'())}],
+
+ QoSEventPersistent = [#'CosNotification_Property'{name='CosNotification':'EventReliability'(),
+ value=any:create(orber_tc:short(),
+ 'CosNotification':'Persistent'())}],
+ QoSEventBestEffort = [#'CosNotification_Property'{name='CosNotification':'EventReliability'(),
+ value=any:create(orber_tc:short(),
+ 'CosNotification':'BestEffort'())}],
+
+ QoSOKMaxBatchSize = [#'CosNotification_Property'{name='CosNotification':'MaximumBatchSize'(),
+ value=any:create(orber_tc:long(), 200)}],
+ QoSToHighMaxBatchSize = [#'CosNotification_Property'{name='CosNotification':'MaximumBatchSize'(),
+ value=any:create(orber_tc:long(), 100000000)}],
+
+ QoSToLowMaxBatchSize = [#'CosNotification_Property'{name='CosNotification':'MaximumBatchSize'(),
+ value=any:create(orber_tc:long(), -1)}],
+
+ QoSOKStopTimeSupp = [#'CosNotification_Property'{name='CosNotification':'StopTimeSupported'(),
+ value=any:create(orber_tc:boolean(), true)}],
+ QoSWrongStopTimeSupp = [#'CosNotification_Property'{name="StopTimeSupp",
+ value=any:create(orber_tc:boolean(), true)}],
+
+ QoSOKStartTimeSupp = [#'CosNotification_Property'{name='CosNotification':'StartTimeSupported'(),
+ value=any:create(orber_tc:boolean(), true)}],
+ QoSWrongStartTimeSupp = [#'CosNotification_Property'{name="StartTimeSupp",
+ value=any:create(orber_tc:boolean(), true)}],
+ QoSOKTimout = [#'CosNotification_Property'{name='CosNotification':'Timeout'(),
+ value=any:create(orber_tc:unsigned_long_long(), 100)}],
+
+
+ %% The most complex QoS to set is ConnectionReliability, and the reason for this
+ %% is that we cannot set the Channel to offer best effort while its children
+ %% offer persistent. A child may only offer Persistent if its parent do, which
+ %% is why we must check the following:
+ %%
+ %% # Persistent Change to Best Effort
+ %% _____
+ %% | | (1) -> Check if children BE
+ %% |Chann| (2) ok <-
+ %% -----
+ %% |
+ %% _____
+ %% | | (3) -> Check if children BE
+ %% |Admin| (4) Check if parent Pers. <-
+ %% -----
+ %% |
+ %% _____
+ %% | | (5) -> ok
+ %% |Proxy| (6) Check if parent Pers. <-
+ %% -----
+ %% NOTE: a parent always exists but we may change the QoS before creating any
+ %% childrens. The cases (2) and (5) is always ok, i.e., no need to confirm
+ %% with parent or children.
+
+ %% We only have a channel. At the moment we can set ConnectionReliability
+ %% without asking anyone.
+ Q1='CosNotification_QoSAdmin':get_qos(Ch),
+ ?match({ok, _}, 'CosNotification_QoSAdmin':validate_qos(Ch, QoSBestEffort)),
+
+ ?match(ok, 'CosNotification_QoSAdmin':set_qos(Ch, QoSPersistent)),
+ %% Match if no problems occur if we try to set QoS as is.
+ ?match(ok, 'CosNotification_QoSAdmin':set_qos(Ch, QoSPersistent)),
+
+ %% Check validate.
+ ?match(ok, 'CosNotification_QoSAdmin':set_qos(Ch, QoSEventPersistent)),
+ ?match({ok, _}, 'CosNotification_QoSAdmin':validate_qos(Ch, QoSOKTimout)),
+ ?match({ok, _}, 'CosNotification_QoSAdmin':validate_qos(Ch, QoSEventBestEffort)),
+ ?match(ok, 'CosNotification_QoSAdmin':set_qos(Ch, QoSEventBestEffort)),
+ ?match({ok, _}, 'CosNotification_QoSAdmin':validate_qos(Ch, QoSOKTimout)),
+
+ Q2='CosNotification_QoSAdmin':get_qos(Ch),
+ ?match(ok, 'CosNotification_QoSAdmin':set_qos(Ch, QoSBestEffort)),
+ ?match(Q1, 'CosNotification_QoSAdmin':get_qos(Ch)),
+
+ %% Now we add an Admin object. An Admin object cannot switch ConnectionReliability
+ %% to BestEffort without checking with its children or Persistent without
+ %% confirming this with its Parent. At the moment, however, we only have a parent.
+ {CAdm, Id2} = 'CosNotifyChannelAdmin_EventChannel':new_for_consumers(Ch, 'AND_OP'),
+ ?match(Q1,'CosNotification_QoSAdmin':get_qos(CAdm)),
+ ?match({'EXCEPTION',{'CosNotification_UnsupportedQoS',_,_}},
+ 'CosNotification_QoSAdmin':set_qos(CAdm, QoSPersistent)),
+ ?match(Q1, 'CosNotification_QoSAdmin':get_qos(CAdm)),
+ ?match(ok, 'CosNotification_QoSAdmin':set_qos(CAdm, QoSBestEffort)),
+ ?match(Q1, 'CosNotification_QoSAdmin':get_qos(CAdm)),
+
+ %% Check if we can extract the Admin from the channel correctly.
+ ?match([0,Id2],'CosNotifyChannelAdmin_EventChannel':get_all_consumeradmins(Ch)),
+ ?match(CAdm,'CosNotifyChannelAdmin_EventChannel':get_consumeradmin(Ch, Id2)),
+ ?match(Ch, 'CosNotifyChannelAdmin_ConsumerAdmin':'_get_MyChannel'(CAdm)),
+ ?match(Id2, 'CosNotifyChannelAdmin_ConsumerAdmin':'_get_MyID'(CAdm)),
+
+ %% Change the channel to provide Persistent service. Now we can set the
+ %% Admin service to Persistent to. (4)
+ ?match(ok, 'CosNotification_QoSAdmin':set_qos(Ch, QoSPersistent)),
+ ?match(ok, 'CosNotification_QoSAdmin':set_qos(CAdm, QoSPersistent)),
+ ?match(Q2, 'CosNotification_QoSAdmin':get_qos(CAdm)),
+
+ %% Since the Admin object now provide Persistent the Channel cannot switch
+ %% to BestEffort. (1)
+ ?match({'EXCEPTION',{'CosNotification_UnsupportedQoS',_,_}},
+ 'CosNotification_QoSAdmin':set_qos(Ch, QoSBestEffort)),
+ %% Should still match Persistent.
+ ?match(Q2, 'CosNotification_QoSAdmin':get_qos(Ch)),
+ {PSup, _Id3} = 'CosNotifyChannelAdmin_ConsumerAdmin':obtain_notification_push_supplier(CAdm, 'ANY_EVENT'),
+ ?match(Q2, 'CosNotification_QoSAdmin':get_qos(CAdm)),
+ ?match('PUSH_ANY', 'CosNotifyChannelAdmin_ProxyPushConsumer':'_get_MyType'(PSup)),
+ ?match(CAdm, 'CosNotifyChannelAdmin_ProxyPushConsumer':'_get_MyAdmin'(PSup)),
+ ?match(Q2, 'CosNotification_QoSAdmin':get_qos(PSup)),
+
+ %% At this point they all offer persistent connection, which means we have
+ %% to start with the proxy if we want to change to Best Effort. Hence,
+ %% the following two cases will fail.
+ ?match({'EXCEPTION',{'CosNotification_UnsupportedQoS',_,_}},
+ 'CosNotification_QoSAdmin':set_qos(Ch, QoSBestEffort)),
+ ?match({'EXCEPTION',{'CosNotification_UnsupportedQoS',_,_}},
+ 'CosNotification_QoSAdmin':set_qos(CAdm, QoSBestEffort)),
+ ?match(ok, 'CosNotification_QoSAdmin':set_qos(PSup, QoSBestEffort)),
+ %% Still not possible to change channel to Best Effort.
+ ?match({'EXCEPTION',{'CosNotification_UnsupportedQoS',_,_}},
+ 'CosNotification_QoSAdmin':set_qos(Ch, QoSBestEffort)),
+ ?match(ok, 'CosNotification_QoSAdmin':set_qos(CAdm, QoSBestEffort)),
+ %% Now we change the channel to Best Effort.
+ ?match(ok, 'CosNotification_QoSAdmin':set_qos(Ch, QoSBestEffort)),
+
+ %% Test if really are Best Effort
+ ?match(Q1, 'CosNotification_QoSAdmin':get_qos(Ch)),
+ ?match(Q1, 'CosNotification_QoSAdmin':get_qos(CAdm)),
+ ?match(Q1, 'CosNotification_QoSAdmin':get_qos(PSup)),
+
+ %% Testing MaximumBatchSize (The highest value is defined in
+ %% CosNotification_Common.erl
+ ?match(ok, 'CosNotification_QoSAdmin':set_qos(Ch, QoSOKMaxBatchSize)),
+ ?match({'EXCEPTION',{'CosNotification_UnsupportedQoS',_,_}},
+ 'CosNotification_QoSAdmin':set_qos(Ch, QoSToHighMaxBatchSize)),
+ ?match({'EXCEPTION',{'CosNotification_UnsupportedQoS',_,_}},
+ 'CosNotification_QoSAdmin':set_qos(Ch, QoSToLowMaxBatchSize)),
+
+ ?match(ok, 'CosNotification_QoSAdmin':set_qos(Ch, QoSOKStartTimeSupp)),
+ ?match(ok, 'CosNotification_QoSAdmin':set_qos(Ch, QoSOKStopTimeSupp)),
+ ?match({'EXCEPTION',{'CosNotification_UnsupportedQoS',_,_}},
+ 'CosNotification_QoSAdmin':set_qos(Ch, QoSWrongStartTimeSupp)),
+ ?match({'EXCEPTION',{'CosNotification_UnsupportedQoS',_,_}},
+ 'CosNotification_QoSAdmin':set_qos(Ch, QoSWrongStopTimeSupp)),
+
+ catch corba:dispose(CAdm),
+ catch corba:dispose(PSup),
+ catch corba:dispose(Ch),
+ cosNotificationApp:stop_factory(Fac),
+ ok.
+
+%%-----------------------------------------------------------------
+%% QoSAdm API tests
+%%-----------------------------------------------------------------
+event_qos_api(doc) -> ["CosNotification QoSAdmin tests", ""];
+event_qos_api(suite) -> [];
+event_qos_api(_Config) ->
+ Fac = (catch cosNotificationApp:start_global_factory(?FAC_OPT)),
+ ?match({_,key,_,_,_,_}, Fac),
+
+ %% Create some objects to test with. We start with default settings.
+ {Ch, _Id1} = (catch 'CosNotifyChannelAdmin_EventChannelFactory':create_channel(Fac, ?defaultQoS, ?defaultAdm)),
+ {CAdm, _Id2} = 'CosNotifyChannelAdmin_EventChannel':new_for_consumers(Ch, 'AND_OP'),
+ {PSup, _Id3} = 'CosNotifyChannelAdmin_ConsumerAdmin':obtain_notification_push_supplier(CAdm, 'ANY_EVENT'),
+
+ %% Try setting an unsupported QoS.
+ ?match({'EXCEPTION',{'CosNotification_UnsupportedQoS',_,_}},
+ 'CosNotifyChannelAdmin_ProxyConsumer':
+ validate_event_qos(PSup,
+ [#'CosNotification_Property'{name="Unsupported QoS",
+ value=any:create(orber_tc:short(), 1)}])),
+ %% Try setting min and max priority.
+ ?match({ok, _}, 'CosNotifyChannelAdmin_ProxyConsumer':
+ validate_event_qos(PSup,
+ [#'CosNotification_Property'{name=?not_Priority,
+ value=any:create(orber_tc:short(),
+ ?not_LowestPriority)},
+ #'CosNotification_Property'{name=?not_Priority,
+ value=any:create(orber_tc:short(),
+ ?not_HighestPriority)}])),
+ %% Try setting priority values which are 1 to high and 1 to low respectively.
+ ?match({'EXCEPTION',{'MARSHAL',_,_,_}},
+ 'CosNotifyChannelAdmin_ProxyConsumer':
+ validate_event_qos(PSup,
+ [#'CosNotification_Property'{name=?not_Priority,
+ value=any:create(orber_tc:short(),
+ ?not_LowestPriority-1)},
+ #'CosNotification_Property'{name=?not_Priority,
+ value=any:create(orber_tc:short(),
+ ?not_HighestPriority+1)}])),
+ %% Try setting start- and stop-time (false default). Note the value associated
+ %% with this property is not really a short but that is not what we are testing
+ %% here so...
+ ?match({'EXCEPTION',{'CosNotification_UnsupportedQoS',_,_}},
+ 'CosNotifyChannelAdmin_ProxyConsumer':
+ validate_event_qos(PSup,
+ [#'CosNotification_Property'{name=?not_StartTime,
+ value=any:create(orber_tc:short(), 0)}])),
+ ?match({'EXCEPTION',{'CosNotification_UnsupportedQoS',_,_}},
+ 'CosNotifyChannelAdmin_ProxyConsumer':
+ validate_event_qos(PSup,
+ [#'CosNotification_Property'{name=?not_StopTime,
+ value=any:create(orber_tc:short(), 0)}])),
+ %% Allow StopTime
+ ?match(ok, 'CosNotification_QoSAdmin':set_qos(PSup, [#'CosNotification_Property'{name='CosNotification':'StopTimeSupported'(),
+ value=any:create(orber_tc:boolean(), true)}])),
+ ?match({ok,_},
+ 'CosNotifyChannelAdmin_ProxyConsumer':
+ validate_event_qos(PSup,
+ [#'CosNotification_Property'{name=?not_StopTime,
+ value=any:create(orber_tc:short(), 0)}])),
+ %% Allow StartTime
+ ?match(ok, 'CosNotification_QoSAdmin':set_qos(PSup, [#'CosNotification_Property'{name='CosNotification':'StartTimeSupported'(),
+ value=any:create(orber_tc:boolean(), true)}])),
+ ?match({ok,_},
+ 'CosNotifyChannelAdmin_ProxyConsumer':
+ validate_event_qos(PSup,
+ [#'CosNotification_Property'{name=?not_StopTime,
+ value=any:create(orber_tc:short(), 0)},
+ #'CosNotification_Property'{name=?not_StartTime,
+ value=any:create(orber_tc:short(), 0)}])),
+
+ %% We must reset StopTime since we cannot guarantee that an event will be delivered
+ %% if risk beeing discarded due to a delay.
+ ?match(ok, 'CosNotification_QoSAdmin':set_qos(PSup, [#'CosNotification_Property'{name='CosNotification':'StopTimeSupported'(),
+ value=any:create(orber_tc:boolean(), false)}])),
+ %% Does it accept Best Effort EventReliability? Must always be true.
+ ?match({ok,_},
+ 'CosNotifyChannelAdmin_ProxyConsumer':
+ validate_event_qos(PSup,
+ [#'CosNotification_Property'{name=?not_EventReliability,
+ value=any:create(orber_tc:short(), ?not_BestEffort)}])),
+ %% Default is Best Effort; test if we can set Persistent EventReliability.
+ ?match({'EXCEPTION',{'CosNotification_UnsupportedQoS',_,_}},
+ 'CosNotifyChannelAdmin_ProxyConsumer':
+ validate_event_qos(PSup,
+ [#'CosNotification_Property'{name=?not_EventReliability,
+ value=any:create(orber_tc:short(), ?not_Persistent)}])),
+
+ %% Set Persistent
+ QoSPersistent = [#'CosNotification_Property'{name='CosNotification':'ConnectionReliability'(),
+ value=any:create(orber_tc:short(),
+ 'CosNotification':'Persistent'())}],
+ ?match(ok, 'CosNotification_QoSAdmin':set_qos(Ch, QoSPersistent)),
+ ?match(ok, 'CosNotification_QoSAdmin':set_qos(CAdm, QoSPersistent)),
+ ?match(ok, 'CosNotification_QoSAdmin':set_qos(PSup, QoSPersistent)),
+
+ %% Does it accept Best Effort EventReliability? Must always be true.
+ ?match({ok, _},
+ 'CosNotifyChannelAdmin_ProxyConsumer':
+ validate_event_qos(PSup,
+ [#'CosNotification_Property'{name=?not_EventReliability,
+ value=any:create(orber_tc:short(), ?not_BestEffort)}])),
+ %% Test if we can use Persistent EventReliability.
+ ?match({'EXCEPTION',{'CosNotification_UnsupportedQoS',_,_}},
+ 'CosNotifyChannelAdmin_ProxyConsumer':
+ validate_event_qos(PSup,
+ [#'CosNotification_Property'{name=?not_EventReliability,
+ value=any:create(orber_tc:short(), ?not_Persistent)}])),
+ QoSEventPersistent = [#'CosNotification_Property'{name='CosNotification':'EventReliability'(),
+ value=any:create(orber_tc:short(),
+ 'CosNotification':'Persistent'())}],
+ ?match(ok, 'CosNotification_QoSAdmin':set_qos(Ch, QoSEventPersistent)),
+ ?match({'EXCEPTION',{'CosNotification_UnsupportedQoS',_,_}},
+ 'CosNotification_QoSAdmin':set_qos(CAdm, QoSEventPersistent)),
+ ?match({'EXCEPTION',{'CosNotification_UnsupportedQoS',_,_}},
+ 'CosNotification_QoSAdmin':set_qos(PSup, QoSEventPersistent)),
+
+ ?match(ok, 'CosNotification_QoSAdmin':set_qos(PSup, [#'CosNotification_Property'{name='CosNotification':'StopTimeSupported'(),
+ value=any:create(orber_tc:boolean(), true)}])),
+ ?match({ok,_},
+ 'CosNotifyChannelAdmin_ProxyConsumer':
+ validate_event_qos(PSup,
+ [#'CosNotification_Property'{name=?not_StopTime,
+ value=any:create(orber_tc:short(), 0)},
+ #'CosNotification_Property'{name=?not_StartTime,
+ value=any:create(orber_tc:short(), 0)}])),
+ catch corba:dispose(CAdm),
+ catch corba:dispose(PSup),
+ catch corba:dispose(Ch),
+ cosNotificationApp:stop_factory(Fac),
+ ok.
+
+%%-----------------------------------------------------------------
+%% Internal functions
+%%-----------------------------------------------------------------
+
+%%-------------------- End of Module ------------------------------
diff --git a/lib/cosNotification/test/notify_test_impl.erl b/lib/cosNotification/test/notify_test_impl.erl
new file mode 100644
index 0000000000..483610befd
--- /dev/null
+++ b/lib/cosNotification/test/notify_test_impl.erl
@@ -0,0 +1,299 @@
+%%
+%% %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%
+%%
+%%
+%%----------------------------------------------------------------------
+%% File : notify_test_impl.erl
+%%----------------------------------------------------------------------
+
+-module(notify_test_impl).
+
+-include_lib("orber/include/corba.hrl").
+-include("idl_output/notify_test.hrl").
+
+%%--------------- specified functions ------------------------
+-export([stop_normal/2,
+ stop_brutal/2,
+ print/2,
+ doAction/3,
+ delay/5,
+ %% Exports from CosNotifyComm::StructuredPushConsumer
+ push_structured_event/3, disconnect_structured_push_consumer/2,
+ %% Exports from "CosNotifyComm::SequencePushConsumer"
+ push_structured_events/3, disconnect_sequence_push_consumer/2,
+ %% Exports from CosEventComm::PushConsumer
+ push/3, disconnect_push_consumer/2,
+ %% Exports from CosNotifyComm::NotifyPublish
+ disconnect_sequence_pull_consumer/2,
+ %% Exports from CosNotifyComm::StructuredPullConsumer
+ disconnect_structured_pull_consumer/2,
+ %% Exports from CosEventComm::PullConsumer
+ disconnect_pull_consumer/2,
+ %% Exports from CosNotifyComm::SequencePushSupplier
+ disconnect_sequence_push_supplier/2,
+ %% Exports from CosNotifyComm::StructuredPushSupplier
+ disconnect_structured_push_supplier/2,
+ %% Exports from CosEventComm::PushSupplier
+ disconnect_push_supplier/2,
+ %% Exports from CosNotifyComm::SequencePullSupplier
+ pull_structured_events/3,
+ try_pull_structured_events/3,
+ disconnect_sequence_pull_supplier/2,
+ %% Exports from CosNotifyComm::StructuredPullSupplier
+ pull_structured_event/2,
+ try_pull_structured_event/2,
+ disconnect_structured_pull_supplier/2,
+ %% Exports from CosEventComm::PullSupplier
+ pull/2,
+ try_pull/2,
+ disconnect_pull_supplier/2,
+ %% Exports from CosNotifyComm::SequencePullConsumer
+ offer_change/4,
+ %% Exports from CosNotifyComm::NotifySubscribe
+ subscription_change/4]).
+
+%%--------------- gen_server specific ------------------------
+-export([init/1, terminate/2]).
+-export([handle_call/3, handle_cast/2, handle_info/2, code_change/3]).
+%% Data structures
+-record(state, {myType, proxy, data, action}).
+
+%%--------------- LOCAL DATA ---------------------------------
+
+%%------------------------------------------------------------
+%% function : init, terminate
+%%------------------------------------------------------------
+init([MyType, Proxy]) ->
+ process_flag(trap_exit,true),
+ {ok, #state{myType=MyType, proxy=Proxy, data=[]}}.
+
+terminate(Reason, State) ->
+ io:format("notify_test:terminate(~p ~p)~n",[Reason, State#state.myType]),
+ ok.
+
+code_change(_OldVsn, State, _Extra) ->
+ {ok, State}.
+handle_call(_,_, State) ->
+ {noreply, State}.
+handle_cast(_, State) ->
+ {noreply, State}.
+handle_info(_Info, State) ->
+ {noreply, State}.
+
+%%--------------- SERVER FUNCTIONS ---------------------------
+
+print(Self, State) ->
+ io:format("notify_test:print(~p ~p)~n",[Self, State]),
+ {reply, ok, State}.
+
+doAction(_Self, State, {set_data, Data}) ->
+ io:format("notify_test:doAction(add_data) ~p~n",[Data]),
+ {reply, ok, State#state{data=Data}};
+doAction(_Self, State, {add_data, Data}) ->
+ io:format("notify_test:doAction(add_data) ~p~n",[Data]),
+ {reply, ok, State#state{data=State#state.data++Data}};
+doAction(_Self, State, return_data) ->
+ io:format("notify_test:doAction(return_data)~n",[]),
+ {reply, State#state.data, State#state{data=[]}};
+doAction(_Self, State, clear_data) ->
+ io:format("notify_test:doAction(return_data)~n",[]),
+ {reply, ok, State#state{data=[]}};
+doAction(_Self, State, pull_any) ->
+ io:format("notify_test:doAction(pull_any)~n",[]),
+ Event='CosNotifyChannelAdmin_ProxyPullSupplier':pull(State#state.proxy),
+ {reply, Event, State};
+doAction(_Self, State, {pull_seq, Max}) ->
+ io:format("notify_test:doAction(pull_sequence)~n",[]),
+ Event='CosNotifyChannelAdmin_SequenceProxyPullSupplier':pull_structured_events(State#state.proxy, Max),
+ {reply, Event, State};
+doAction(_Self, State, pull_str) ->
+ Event='CosNotifyChannelAdmin_StructuredProxyPullSupplier':pull_structured_event(State#state.proxy),
+ io:format("notify_test:doAction(pull_structured)~n",[]),
+ {reply, Event, State};
+doAction(_Self, State, try_pull_any) ->
+ io:format("notify_test:doAction(try_pull_any)~n",[]),
+ Event='CosNotifyChannelAdmin_ProxyPullSupplier':try_pull(State#state.proxy),
+ {reply, Event, State};
+doAction(_Self, State, {try_pull_seq, Max}) ->
+ io:format("notify_test:doAction(try_pull_sequence)~n",[]),
+ Event='CosNotifyChannelAdmin_SequenceProxyPullSupplier':try_pull_structured_events(State#state.proxy, Max),
+ {reply, Event, State};
+doAction(_Self, State, try_pull_str) ->
+ Event='CosNotifyChannelAdmin_StructuredProxyPullSupplier':try_pull_structured_event(State#state.proxy),
+ io:format("notify_test:doAction(try_pull_structured)~n",[]),
+ {reply, Event, State};
+doAction(_Self, State, {action, Action}) ->
+ io:format("notify_test:doAction(~p)~n",[Action]),
+ {reply, ok, State#state{action = Action}};
+
+doAction(_, State, _) ->
+ {reply, nop, State}.
+
+stop_normal(_Self, State) ->
+ {stop, normal, ok, State}.
+
+stop_brutal(_Self, _State) ->
+ exit("killed_brutal").
+
+
+
+%%--------------- CosNotifyComm::NotifyPublish --------
+offer_change(_Self, State, Added, Removed) ->
+ ND=loop(Removed, State#state.data),
+ ND2=Added++ND,
+ {reply, ok, State#state{data=ND2}}.
+
+loop([],Data) ->
+ Data;
+loop([H|T], Data) ->
+ ND=lists:delete(H,Data),
+ loop(T, ND).
+
+%%--------------- CosNotifyComm::NotifySubscribe --------
+subscription_change(_Self, State, Added, Removed) ->
+ ND=loop(Removed, State#state.data),
+ ND2=Added++ND,
+ {reply, ok, State#state{data=ND2}}.
+
+%%--------------- CosNotifyComm::SequencePushConsumer --------
+push_structured_events(_Self, #state{action = undefined} = State, Event) ->
+ io:format("notify_test:push_structured_events(~p)~n",[Event]),
+ {reply, ok, State#state{data=State#state.data++Event}};
+push_structured_events(_Self, #state{action = Action} = State, Event) ->
+ io:format("notify_test:push_structured_events(~p)~nAction: ~p~n",
+ [Event, Action]),
+ corba:raise(#'INTERNAL'{completion_status=?COMPLETED_NO}),
+ {reply, ok, State#state{data=State#state.data++Event}}.
+disconnect_sequence_push_consumer(_Self, State) ->
+ io:format("disconnect_sequence_push_consumer~n",[]),
+ {stop, normal, ok, State}.
+
+%%--------------- CosNotifyComm::StructuredPushConsumer --------
+push_structured_event(_Self, State, Event) ->
+ io:format("notify_test:push_structured_event(~p)~n",[Event]),
+ {reply, ok, State#state{data=State#state.data++[Event]}}.
+disconnect_structured_push_consumer(_Self, State) ->
+ io:format("disconnect_structured_push_consumer~n",[]),
+ {stop, normal, ok, State}.
+
+%%--------------- CosEventComm::PushConsumer --------
+push(_Self, State, Event) ->
+ io:format("notify_test:push(~p)~n",[Event]),
+ {reply, ok, State#state{data=State#state.data++[Event]}}.
+disconnect_push_consumer(_Self, State) ->
+ io:format("disconnect_push_consumer~n",[]),
+ {stop, normal, ok, State}.
+
+%%--------------- CosNotifyComm::SequencePullConsumer --------
+disconnect_sequence_pull_consumer(_Self, State) ->
+ io:format("disconnect_sequence_pull_consumer~n",[]),
+ {stop, normal, ok, State}.
+
+%%--------------- CosNotifyComm::StructuredPullConsumer --------
+disconnect_structured_pull_consumer(_Self, State) ->
+ io:format("disconnect_structured_pull_consumer~n",[]),
+ {stop, normal, ok, State}.
+
+%%--------------- CosEventComm::PullConsumer --------
+disconnect_pull_consumer(_Self, State) ->
+ io:format("disconnect_pull_consumer~n",[]),
+ {stop, normal, ok, State}.
+
+%%--------------- CosNotifyComm::SequencePushSupplier --------
+disconnect_sequence_push_supplier(_Self, State) ->
+ io:format("disconnect_sequence_push_supplier~n",[]),
+ {stop, normal, ok, State}.
+
+%%--------------- CosNotifyComm::StructuredPushSupplier --------
+disconnect_structured_push_supplier(_Self, State) ->
+ io:format("disconnect_structured_push_supplier~n",[]),
+ {stop, normal, ok, State}.
+
+%%--------------- CosEventComm::PushSupplier --------
+disconnect_push_supplier(_Self, State) ->
+ io:format("disconnect_push_supplier~n",[]),
+ {stop, normal, ok, State}.
+
+%%--------------- CosNotifyComm::SequencePullSupplier --------
+pull_structured_events(_Self, State, _Max) ->
+ io:format("notify_test:pullstructured_events()~n",[]),
+ {reply, ok, State}.
+try_pull_structured_events(_Self, State, Max) ->
+ io:format("notify_test:try_pull_structured_events()~n",[]),
+ case State#state.data of
+ [] ->
+ {reply, {[],false}, State};
+ List ->
+ R = split(List,Max),
+ {reply, {lists:sublist(List, Max), true}, State#state{data=R}}
+ end.
+
+split([],_) ->
+ [];
+split(R,0) ->
+ R;
+split([_H|T],Max) ->
+ split(T, Max-1).
+
+disconnect_sequence_pull_supplier(_Self, State) ->
+ io:format("disconnect_sequence_pull_supplier~n",[]),
+ {stop, normal, ok, State}.
+
+%%--------------- CosNotifyComm::StructuredPullSupplier --------
+pull_structured_event(_Self, State) ->
+ io:format("notify_test:pull_structured_event()~n",[]),
+ {reply, ok, State}.
+try_pull_structured_event(_Self, State) ->
+ io:format("notify_test:try_pull_structured_event()~n",[]),
+ case State#state.data of
+ [] ->
+ {reply, {[],false}, State};
+ [H|T] ->
+ {reply, {H, true}, State#state{data=T}}
+ end.
+disconnect_structured_pull_supplier(_Self, State) ->
+ io:format("disconnect_structured_pull_supplier~n",[]),
+ {stop, normal, ok, State}.
+
+%%--------------- CosEventComm::PullSupplier --------
+pull(_Self, State) ->
+ io:format("notify_test:pull()~n",[]),
+ {reply, 'CosEventComm_PullSupplier':pull(State#state.proxy), State}.
+try_pull(_Self, State) ->
+ io:format("notify_test:try_pull()~n",[]),
+ case State#state.data of
+ [] ->
+ {reply, {[],false}, State};
+ [H|T] ->
+ {reply, {H, true}, State#state{data=T}}
+ end.
+disconnect_pull_supplier(_Self, State) ->
+ io:format("disconnect_pull_supplier~n",[]),
+ {stop, normal, ok, State}.
+
+%%--------------- LOCAL FUNCTIONS ----------------------------
+
+delay(Obj, Event, Time, Mod, F) ->
+ io:format("notify_test:delay(~p) TIME: ~p~n",[Event, now()]),
+ timer:sleep(Time),
+ Mod:F(Obj, Event),
+ io:format("notify_test:delay() DONE: ~p~n",[now()]),
+ ok.
+
+%%--------------- END OF MODULE ------------------------------
+
diff --git a/lib/cosNotification/test/notify_test_server.cfg b/lib/cosNotification/test/notify_test_server.cfg
new file mode 100644
index 0000000000..8621327b57
--- /dev/null
+++ b/lib/cosNotification/test/notify_test_server.cfg
@@ -0,0 +1,54 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 1999-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%
+%%
+{this, "notify_test::SeqPushC"}.
+{{handle_info, "notify_test::SeqPushC"}, true}.
+{{impl, "notify_test::SeqPushC"}, "notify_test_impl"}.
+{this, "notify_test::StrPushC"}.
+{{handle_info, "notify_test::StrPushC"}, true}.
+{{impl, "notify_test::StrPushC"}, "notify_test_impl"}.
+{this, "notify_test::AnyPushC"}.
+{{handle_info, "notify_test::AnyPushC"}, true}.
+{{impl, "notify_test::AnyPushC"}, "notify_test_impl"}.
+{this, "notify_test::SeqPullC"}.
+{{handle_info, "notify_test::SeqPullC"}, true}.
+{{impl, "notify_test::SeqPullC"}, "notify_test_impl"}.
+{this, "notify_test::StrPullC"}.
+{{handle_info, "notify_test::StrPullC"}, true}.
+{{impl, "notify_test::StrPullC"}, "notify_test_impl"}.
+{this, "notify_test::AnyPullC"}.
+{{handle_info, "notify_test::AnyPullC"}, true}.
+{{impl, "notify_test::AnyPullC"}, "notify_test_impl"}.
+{this, "notify_test::SeqPushS"}.
+{{handle_info, "notify_test::SeqPushS"}, true}.
+{{impl, "notify_test::SeqPushS"}, "notify_test_impl"}.
+{this, "notify_test::StrPushS"}.
+{{handle_info, "notify_test::StrPushS"}, true}.
+{{impl, "notify_test::StrPushS"}, "notify_test_impl"}.
+{this, "notify_test::AnyPushS"}.
+{{handle_info, "notify_test::AnyPushS"}, true}.
+{{impl, "notify_test::AnyPushS"}, "notify_test_impl"}.
+{this, "notify_test::SeqPullS"}.
+{{handle_info, "notify_test::SeqPullS"}, true}.
+{{impl, "notify_test::SeqPullS"}, "notify_test_impl"}.
+{this, "notify_test::StrPullS"}.
+{{handle_info, "notify_test::StrPullS"}, true}.
+{{impl, "notify_test::StrPullS"}, "notify_test_impl"}.
+{this, "notify_test::AnyPullS"}.
+{{handle_info, "notify_test::AnyPullS"}, true}.
+{{impl, "notify_test::AnyPullS"}, "notify_test_impl"}.
diff --git a/lib/cosNotification/test/notify_test_server.idl b/lib/cosNotification/test/notify_test_server.idl
new file mode 100644
index 0000000000..4dc0202890
--- /dev/null
+++ b/lib/cosNotification/test/notify_test_server.idl
@@ -0,0 +1,113 @@
+//
+// %CopyrightBegin%
+//
+// Copyright Ericsson AB 1999-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%
+//
+
+#ifndef _NOTIFY_TEST_SERVER_IDL
+#define _NOTIFY_TEST_SERVER_IDL
+
+#include <CosNotification.idl>
+#include <CosNotifyComm.idl>
+
+module notify_test {
+
+ enum action {PULL_SEQ, PULL_STR, PULL_ANY, PUSH_SEQ, PUSH_STR, PUSH_ANY};
+
+ struct data {
+ short score;
+ string name;
+ };
+
+ struct computer {
+ float memsize;
+ float cputime;
+ float filesize;
+ };
+
+ struct X {
+ long A;
+ string B;
+ short C;
+ };
+
+
+ union K switch(short) {
+ case -1: short neg;
+ case 0:
+ case 2: string K;
+ case 3: X L;
+ case 5: long M;
+ default: short N;
+ };
+
+ union uni1 switch(long) {
+ case 1:
+ case 2: long lo;
+ case 3: short sh;
+ default: short defvalue;
+ };
+
+ union uni2 switch(long) {
+ case 1:
+ case 2: long lo;
+ case 3: short sh;
+ };
+
+ typedef any namedAny;
+ typedef short ShortArray[4];
+ struct studies {
+ uni1 uni1;
+ CosNotification::PropertySeq tests;
+ ShortArray monthly_attendance;
+ short gpa;
+ };
+
+ interface funcs {
+ void print();
+ void doAction(in action Act);
+ };
+
+ // interface server
+ interface SeqPushC : funcs, CosNotifyComm::SequencePushConsumer {
+ };
+ interface StrPushC : funcs, CosNotifyComm::StructuredPushConsumer {
+ };
+ interface AnyPushC : funcs, CosEventComm::PushConsumer {
+ };
+ interface SeqPullC : funcs, CosNotifyComm::SequencePullConsumer {
+ };
+ interface StrPullC : funcs, CosNotifyComm::StructuredPullConsumer {
+ };
+ interface AnyPullC : funcs, CosEventComm::PullConsumer {
+ };
+
+ interface SeqPushS : funcs, CosNotifyComm::SequencePushSupplier {
+ };
+ interface StrPushS : funcs, CosNotifyComm::StructuredPushSupplier {
+ };
+ interface AnyPushS : funcs, CosEventComm::PushSupplier {
+ };
+ interface SeqPullS : funcs, CosNotifyComm::SequencePullSupplier {
+ };
+ interface StrPullS : funcs, CosNotifyComm::StructuredPullSupplier {
+ };
+ interface AnyPullS : funcs, CosEventComm::PullSupplier {
+ };
+
+};
+
+#endif
diff --git a/lib/cosNotification/vsn.mk b/lib/cosNotification/vsn.mk
index 65f9812f31..be7aa56e15 100644
--- a/lib/cosNotification/vsn.mk
+++ b/lib/cosNotification/vsn.mk
@@ -1,6 +1,10 @@
-COSNOTIFICATION_VSN = 1.1.12
+COSNOTIFICATION_VSN = 1.1.15
-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/test/Makefile b/lib/cosProperty/test/Makefile
new file mode 100644
index 0000000000..ac0f4e298d
--- /dev/null
+++ b/lib/cosProperty/test/Makefile
@@ -0,0 +1,129 @@
+#
+# %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_TOP)/make/target.mk
+include $(ERL_TOP)/make/$(TARGET)/otp.mk
+
+# ----------------------------------------------------
+# Application version
+# ----------------------------------------------------
+include ../vsn.mk
+VSN=$(COSPROPERTY_VSN)
+# ----------------------------------------------------
+# Release directory specification
+# ----------------------------------------------------
+RELSYSDIR = $(RELEASE_PATH)/cosProperty_test
+
+# ----------------------------------------------------
+# Target Specs
+# ----------------------------------------------------
+TEST_SPEC_FILE = cosProperty.spec
+
+
+IDL_FILES =
+
+IDLOUTDIR = idl_output
+
+MODULES = \
+ property_SUITE \
+ generated_SUITE
+
+GEN_MODULES = \
+
+GEN_HRL_FILES = \
+
+ERL_FILES = $(MODULES:%=%.erl)
+
+HRL_FILES =
+
+GEN_FILES = \
+ $(GEN_HRL_FILES:%=$(IDLOUTDIR)/%) \
+ $(GEN_MODULES:%=$(IDLOUTDIR)/%.erl)
+
+GEN_TARGET_FILES = $(GEN_MODULES:%=$(IDLOUTDIR)/%.$(EMULATOR))
+
+SUITE_TARGET_FILES = $(MODULES:%=%.$(EMULATOR))
+
+TARGET_FILES = \
+ $(GEN_TARGET_FILES) \
+ $(SUITE_TARGET_FILES)
+
+
+# ----------------------------------------------------
+# PROGRAMS
+# ----------------------------------------------------
+LOCAL_CLASSPATH = $(ERL_TOP)lib/cosProperty/priv:$(ERL_TOP)lib/cosProperty/test
+# ----------------------------------------------------
+# FLAGS
+# ----------------------------------------------------
+ERL_IDL_FLAGS += -pa $(ERL_TOP)/lib/cosProperty/ebin \
+ -pa $(ERL_TOP)/lib/cosProperty/src \
+ -pa $(ERL_TOP)/lib/orber/ebin \
+ -pa $(ERL_TOP)/lib/ic/ebin
+
+ERL_COMPILE_FLAGS += \
+ $(ERL_IDL_FLAGS) \
+ -pa $(ERL_TOP)/lib/orber/include \
+ -pa $(ERL_TOP)/internal_tools/test_server/ebin \
+ -pa $(ERL_TOP)/lib/cosProperty/ebin \
+ -pa $(ERL_TOP)/lib/cosProperty/test/idl_output \
+ -I$(ERL_TOP)/lib/orber/include \
+ -I$(ERL_TOP)/lib/cosProperty/src \
+ -I$(ERL_TOP)/lib/cosProperty \
+ -I$(ERL_TOP)/lib/cosProperty/test/$(IDLOUTDIR) \
+ -I$(ERL_TOP)/lib/test_server/include
+
+# ----------------------------------------------------
+# Targets
+# ----------------------------------------------------
+
+
+tests debug opt: $(TARGET_FILES)
+
+clean:
+ rm -f idl_output/*
+ rm -f $(TARGET_FILES)
+ rm -f errs core *~
+
+docs:
+
+# ----------------------------------------------------
+# Special Targets
+# ----------------------------------------------------
+
+# ----------------------------------------------------
+# Release Targets
+# ----------------------------------------------------
+# We don't copy generated intermediate erlang and hrl files
+
+include $(ERL_TOP)/make/otp_release_targets.mk
+
+release_spec:
+
+release_docs_spec:
+
+release_tests_spec: tests
+ $(INSTALL_DIR) $(RELSYSDIR)
+ $(INSTALL_DATA) $(IDL_FILES) $(TEST_SPEC_FILE) \
+ $(ERL_FILES) $(RELSYSDIR)
+ $(INSTALL_DATA) $(SUITE_TARGET_FILES) $(RELSYSDIR)
+# $(INSTALL_DIR) $(RELSYSDIR)/$(IDLOUTDIR)
+# $(INSTALL_DATA) $(GEN_TARGET_FILES) $(GEN_FILES) \
+# $(RELSYSDIR)/$(IDLOUTDIR)
+
diff --git a/lib/cosProperty/test/cosProperty.spec b/lib/cosProperty/test/cosProperty.spec
new file mode 100644
index 0000000000..d3e0001eef
--- /dev/null
+++ b/lib/cosProperty/test/cosProperty.spec
@@ -0,0 +1,20 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 2000-2010. All Rights Reserved.
+%%
+%% The contents of this file are subject to the Erlang Public License,
+%% Version 1.1, (the "License"); you may not use this file except in
+%% compliance with the License. You should have received a copy of the
+%% Erlang Public License along with this software. If not, it can be
+%% retrieved online at http://www.erlang.org/.
+%%
+%% Software distributed under the License is distributed on an "AS IS"
+%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+%% the License for the specific language governing rights and limitations
+%% under the License.
+%%
+%% %CopyrightEnd%
+%%
+{topcase, {dir, "../cosProperty_test"}}.
+
diff --git a/lib/cosProperty/test/generated_SUITE.erl b/lib/cosProperty/test/generated_SUITE.erl
new file mode 100644
index 0000000000..80a7953949
--- /dev/null
+++ b/lib/cosProperty/test/generated_SUITE.erl
@@ -0,0 +1,571 @@
+%%-----------------------------------------------------------------
+%%
+%% %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%
+%%
+%%
+%%-----------------------------------------------------------------
+%% File : generated_SUITE.erl
+%% Purpose :
+%%-----------------------------------------------------------------
+
+-module(generated_SUITE).
+
+-include("test_server.hrl").
+-include_lib("orber/include/corba.hrl").
+
+-define(default_timeout, ?t:minutes(3)).
+
+-define(match(ExpectedRes, Expr),
+ fun() ->
+ AcTuAlReS = (catch (Expr)),
+ case AcTuAlReS of
+ ExpectedRes ->
+ AcTuAlReS;
+ _ ->
+ io:format("###### ERROR ERROR ######~n~p~n",
+ [AcTuAlReS]),
+ ?line exit(AcTuAlReS)
+ end
+ end()).
+
+-define(nomatch(Not, Expr),
+ fun() ->
+ AcTuAlReS = (catch (Expr)),
+ case AcTuAlReS of
+ Not ->
+ io:format("###### ERROR ERROR ######~n~p~n",
+ [AcTuAlReS]),
+ ?line exit(AcTuAlReS);
+ _ ->
+ AcTuAlReS
+ end
+ end()).
+
+
+-define(checktc(_Op),
+ fun(TC) ->
+ case orber_tc:check_tc(TC) of
+ false ->
+ io:format("###### ERROR ERROR ######~n~p - ~p~n", [Op, TC]),
+ ?line exit(TC);
+ true ->
+ true
+ end
+ end).
+
+%%-----------------------------------------------------------------
+%% External exports
+%%-----------------------------------------------------------------
+-export([all/1]).
+
+%%-----------------------------------------------------------------
+%% Internal exports
+%%-----------------------------------------------------------------
+-export([]).
+-compile(export_all).
+
+%%-----------------------------------------------------------------
+%% Func: all/1
+%% Args:
+%% Returns:
+%%-----------------------------------------------------------------
+all(doc) -> ["This suite is for testing IC generated files"];
+all(suite) ->
+ ['CosPropertyService_ConflictingProperty', 'CosPropertyService_ConstraintNotSupported',
+ 'CosPropertyService_FixedProperty', 'CosPropertyService_InvalidPropertyName',
+ 'CosPropertyService_MultipleExceptions', 'CosPropertyService_Properties',
+ 'CosPropertyService_Property', 'CosPropertyService_PropertyDef',
+ 'CosPropertyService_PropertyDefs', 'CosPropertyService_PropertyException',
+ 'CosPropertyService_PropertyExceptions', 'CosPropertyService_PropertyMode',
+ 'CosPropertyService_PropertyModes', 'CosPropertyService_PropertyNames',
+ 'CosPropertyService_PropertyNotFound', 'CosPropertyService_PropertyTypes',
+ 'CosPropertyService_ReadOnlyProperty', 'CosPropertyService_UnsupportedMode',
+ 'CosPropertyService_UnsupportedProperty', 'CosPropertyService_UnsupportedTypeCode',
+ 'CosPropertyService_PropertyNamesIterator', 'CosPropertyService_PropertiesIterator',
+ 'CosPropertyService_PropertySet', 'CosPropertyService_PropertySetDef',
+ 'CosPropertyService_PropertySetDefFactory', 'CosPropertyService_PropertySetFactory'].
+
+
+%%-----------------------------------------------------------------
+%% Init and cleanup functions.
+%%-----------------------------------------------------------------
+init_per_testcase(_Case, Config) ->
+ ?line Dog=test_server:timetrap(?default_timeout),
+ [{watchdog, Dog}|Config].
+
+
+fin_per_testcase(_Case, Config) ->
+ Dog = ?config(watchdog, Config),
+ test_server:timetrap_cancel(Dog),
+ ok.
+
+
+
+
+%%-----------------------------------------------------------------
+%% Test Case: 'CosPropertyService_ConflictingProperty'
+%% Description:
+%%-----------------------------------------------------------------
+'CosPropertyService_ConflictingProperty'(doc) -> ["CosPropertyService_ConflictingProperty"];
+'CosPropertyService_ConflictingProperty'(suite) -> [];
+'CosPropertyService_ConflictingProperty'(_) ->
+ ?match(true, orber_tc:check_tc('CosPropertyService_ConflictingProperty':tc())),
+ ?match("IDL:omg.org/CosPropertyService/ConflictingProperty:1.0",
+ 'CosPropertyService_ConflictingProperty':id()),
+ ?match("CosPropertyService_ConflictingProperty",
+ 'CosPropertyService_ConflictingProperty':name()),
+ ok.
+
+
+%%-----------------------------------------------------------------
+%% Test Case: 'CosPropertyService_ConstraintNotSupported'
+%% Description:
+%%-----------------------------------------------------------------
+'CosPropertyService_ConstraintNotSupported'(doc) -> ["CosPropertyService_ConstraintNotSupported"];
+'CosPropertyService_ConstraintNotSupported'(suite) -> [];
+'CosPropertyService_ConstraintNotSupported'(_) ->
+ ?match(true, orber_tc:check_tc('CosPropertyService_ConstraintNotSupported':tc())),
+ ?match("IDL:omg.org/CosPropertyService/ConstraintNotSupported:1.0",
+ 'CosPropertyService_ConstraintNotSupported':id()),
+ ?match("CosPropertyService_ConstraintNotSupported",
+ 'CosPropertyService_ConstraintNotSupported':name()),
+ ok.
+
+
+%%-----------------------------------------------------------------
+%% Test Case: 'CosPropertyService_FixedProperty'
+%% Description:
+%%-----------------------------------------------------------------
+'CosPropertyService_FixedProperty'(doc) -> ["CosPropertyService_FixedProperty"];
+'CosPropertyService_FixedProperty'(suite) -> [];
+'CosPropertyService_FixedProperty'(_) ->
+ ?match(true, orber_tc:check_tc('CosPropertyService_FixedProperty':tc())),
+ ?match("IDL:omg.org/CosPropertyService/FixedProperty:1.0",
+ 'CosPropertyService_FixedProperty':id()),
+ ?match("CosPropertyService_FixedProperty",
+ 'CosPropertyService_FixedProperty':name()),
+ ok.
+
+
+%%-----------------------------------------------------------------
+%% Test Case: 'CosPropertyService_InvalidPropertyName'
+%% Description:
+%%-----------------------------------------------------------------
+'CosPropertyService_InvalidPropertyName'(doc) -> ["CosPropertyService_InvalidPropertyName"];
+'CosPropertyService_InvalidPropertyName'(suite) -> [];
+'CosPropertyService_InvalidPropertyName'(_) ->
+ ?match(true, orber_tc:check_tc('CosPropertyService_InvalidPropertyName':tc())),
+ ?match("IDL:omg.org/CosPropertyService/InvalidPropertyName:1.0",
+ 'CosPropertyService_InvalidPropertyName':id()),
+ ?match("CosPropertyService_InvalidPropertyName",
+ 'CosPropertyService_InvalidPropertyName':name()),
+ ok.
+
+
+%%-----------------------------------------------------------------
+%% Test Case: 'CosPropertyService_MultipleExceptions'
+%% Description:
+%%-----------------------------------------------------------------
+'CosPropertyService_MultipleExceptions'(doc) -> ["CosPropertyService_MultipleExceptions"];
+'CosPropertyService_MultipleExceptions'(suite) -> [];
+'CosPropertyService_MultipleExceptions'(_) ->
+ ?match(true, orber_tc:check_tc('CosPropertyService_MultipleExceptions':tc())),
+ ?match("IDL:omg.org/CosPropertyService/MultipleExceptions:1.0",
+ 'CosPropertyService_MultipleExceptions':id()),
+ ?match("CosPropertyService_MultipleExceptions",
+ 'CosPropertyService_MultipleExceptions':name()),
+ ok.
+
+
+%%-----------------------------------------------------------------
+%% Test Case: 'CosPropertyService_Properties'
+%% Description:
+%%-----------------------------------------------------------------
+'CosPropertyService_Properties'(doc) -> ["CosPropertyService_Properties"];
+'CosPropertyService_Properties'(suite) -> [];
+'CosPropertyService_Properties'(_) ->
+ ?match(true, orber_tc:check_tc('CosPropertyService_Properties':tc())),
+ ?match("IDL:omg.org/CosPropertyService/Properties:1.0",
+ 'CosPropertyService_Properties':id()),
+ ?match("CosPropertyService_Properties",
+ 'CosPropertyService_Properties':name()),
+ ok.
+
+
+%%-----------------------------------------------------------------
+%% Test Case: 'CosPropertyService_Property'
+%% Description:
+%%-----------------------------------------------------------------
+'CosPropertyService_Property'(doc) -> ["CosPropertyService_Property"];
+'CosPropertyService_Property'(suite) -> [];
+'CosPropertyService_Property'(_) ->
+ ?match(true, orber_tc:check_tc('CosPropertyService_Property':tc())),
+ ?match("IDL:omg.org/CosPropertyService/Property:1.0",
+ 'CosPropertyService_Property':id()),
+ ?match("CosPropertyService_Property",
+ 'CosPropertyService_Property':name()),
+ ok.
+
+
+%%-----------------------------------------------------------------
+%% Test Case: 'CosPropertyService_PropertyDef'
+%% Description:
+%%-----------------------------------------------------------------
+'CosPropertyService_PropertyDef'(doc) -> ["CosPropertyService_PropertyDef"];
+'CosPropertyService_PropertyDef'(suite) -> [];
+'CosPropertyService_PropertyDef'(_) ->
+ ?match(true, orber_tc:check_tc('CosPropertyService_PropertyDef':tc())),
+ ?match("IDL:omg.org/CosPropertyService/PropertyDef:1.0",
+ 'CosPropertyService_PropertyDef':id()),
+ ?match("CosPropertyService_PropertyDef",
+ 'CosPropertyService_PropertyDef':name()),
+ ok.
+
+
+%%-----------------------------------------------------------------
+%% Test Case: 'CosPropertyService_PropertyDefs'
+%% Description:
+%%-----------------------------------------------------------------
+'CosPropertyService_PropertyDefs'(doc) -> ["CosPropertyService_PropertyDefs"];
+'CosPropertyService_PropertyDefs'(suite) -> [];
+'CosPropertyService_PropertyDefs'(_) ->
+ ?match(true, orber_tc:check_tc('CosPropertyService_PropertyDefs':tc())),
+ ?match("IDL:omg.org/CosPropertyService/PropertyDefs:1.0",
+ 'CosPropertyService_PropertyDefs':id()),
+ ?match("CosPropertyService_PropertyDefs",
+ 'CosPropertyService_PropertyDefs':name()),
+ ok.
+
+
+%%-----------------------------------------------------------------
+%% Test Case: 'CosPropertyService_PropertyException'
+%% Description:
+%%-----------------------------------------------------------------
+'CosPropertyService_PropertyException'(doc) -> ["CosPropertyService_PropertyException"];
+'CosPropertyService_PropertyException'(suite) -> [];
+'CosPropertyService_PropertyException'(_) ->
+ ?match(true, orber_tc:check_tc('CosPropertyService_PropertyException':tc())),
+ ?match("IDL:omg.org/CosPropertyService/PropertyException:1.0",
+ 'CosPropertyService_PropertyException':id()),
+ ?match("CosPropertyService_PropertyException",
+ 'CosPropertyService_PropertyException':name()),
+ ok.
+
+
+%%-----------------------------------------------------------------
+%% Test Case: 'CosPropertyService_PropertyExceptions'
+%% Description:
+%%-----------------------------------------------------------------
+'CosPropertyService_PropertyExceptions'(doc) -> ["CosPropertyService_PropertyExceptions"];
+'CosPropertyService_PropertyExceptions'(suite) -> [];
+'CosPropertyService_PropertyExceptions'(_) ->
+ ?match(true, orber_tc:check_tc('CosPropertyService_PropertyExceptions':tc())),
+ ?match("IDL:omg.org/CosPropertyService/PropertyExceptions:1.0",
+ 'CosPropertyService_PropertyExceptions':id()),
+ ?match("CosPropertyService_PropertyExceptions",
+ 'CosPropertyService_PropertyExceptions':name()),
+ ok.
+
+
+%%-----------------------------------------------------------------
+%% Test Case: 'CosPropertyService_PropertyMode'
+%% Description:
+%%-----------------------------------------------------------------
+'CosPropertyService_PropertyMode'(doc) -> ["CosPropertyService_PropertyMode"];
+'CosPropertyService_PropertyMode'(suite) -> [];
+'CosPropertyService_PropertyMode'(_) ->
+ ?match(true, orber_tc:check_tc('CosPropertyService_PropertyMode':tc())),
+ ?match("IDL:omg.org/CosPropertyService/PropertyMode:1.0",
+ 'CosPropertyService_PropertyMode':id()),
+ ?match("CosPropertyService_PropertyMode",
+ 'CosPropertyService_PropertyMode':name()),
+ ok.
+
+
+%%-----------------------------------------------------------------
+%% Test Case: 'CosPropertyService_PropertyModes'
+%% Description:
+%%-----------------------------------------------------------------
+'CosPropertyService_PropertyModes'(doc) -> ["CosPropertyService_PropertyModes"];
+'CosPropertyService_PropertyModes'(suite) -> [];
+'CosPropertyService_PropertyModes'(_) ->
+ ?match(true, orber_tc:check_tc('CosPropertyService_PropertyModes':tc())),
+ ?match("IDL:omg.org/CosPropertyService/PropertyModes:1.0",
+ 'CosPropertyService_PropertyModes':id()),
+ ?match("CosPropertyService_PropertyModes",
+ 'CosPropertyService_PropertyModes':name()),
+ ok.
+
+
+%%-----------------------------------------------------------------
+%% Test Case: 'CosPropertyService_PropertyNames'
+%% Description:
+%%-----------------------------------------------------------------
+'CosPropertyService_PropertyNames'(doc) -> ["CosPropertyService_PropertyNames"];
+'CosPropertyService_PropertyNames'(suite) -> [];
+'CosPropertyService_PropertyNames'(_) ->
+ ?match(true, orber_tc:check_tc('CosPropertyService_PropertyNames':tc())),
+ ?match("IDL:omg.org/CosPropertyService/PropertyNames:1.0",
+ 'CosPropertyService_PropertyNames':id()),
+ ?match("CosPropertyService_PropertyNames",
+ 'CosPropertyService_PropertyNames':name()),
+ ok.
+
+%%-----------------------------------------------------------------
+%% Test Case: 'CosPropertyService_PropertyNotFound'
+%% Description:
+%%-----------------------------------------------------------------
+'CosPropertyService_PropertyNotFound'(doc) -> ["CosPropertyService_PropertyNotFound"];
+'CosPropertyService_PropertyNotFound'(suite) -> [];
+'CosPropertyService_PropertyNotFound'(_) ->
+ ?match(true, orber_tc:check_tc('CosPropertyService_PropertyNotFound':tc())),
+ ?match("IDL:omg.org/CosPropertyService/PropertyNotFound:1.0",
+ 'CosPropertyService_PropertyNotFound':id()),
+ ?match("CosPropertyService_PropertyNotFound",
+ 'CosPropertyService_PropertyNotFound':name()),
+ ok.
+
+%%-----------------------------------------------------------------
+%% Test Case: 'CosPropertyService_PropertyTypes'
+%% Description:
+%%-----------------------------------------------------------------
+'CosPropertyService_PropertyTypes'(doc) -> ["CosPropertyService_PropertyTypes"];
+'CosPropertyService_PropertyTypes'(suite) -> [];
+'CosPropertyService_PropertyTypes'(_) ->
+ ?match(true, orber_tc:check_tc('CosPropertyService_PropertyTypes':tc())),
+ ?match("IDL:omg.org/CosPropertyService/PropertyTypes:1.0",
+ 'CosPropertyService_PropertyTypes':id()),
+ ?match("CosPropertyService_PropertyTypes",
+ 'CosPropertyService_PropertyTypes':name()),
+ ok.
+
+%%-----------------------------------------------------------------
+%% Test Case: 'CosPropertyService_ReadOnlyProperty'
+%% Description:
+%%-----------------------------------------------------------------
+'CosPropertyService_ReadOnlyProperty'(doc) -> ["CosPropertyService_ReadOnlyProperty"];
+'CosPropertyService_ReadOnlyProperty'(suite) -> [];
+'CosPropertyService_ReadOnlyProperty'(_) ->
+ ?match(true, orber_tc:check_tc('CosPropertyService_ReadOnlyProperty':tc())),
+ ?match("IDL:omg.org/CosPropertyService/ReadOnlyProperty:1.0",
+ 'CosPropertyService_ReadOnlyProperty':id()),
+ ?match("CosPropertyService_ReadOnlyProperty",
+ 'CosPropertyService_ReadOnlyProperty':name()),
+ ok.
+
+%%-----------------------------------------------------------------
+%% Test Case: 'CosPropertyService_UnsupportedMode'
+%% Description:
+%%-----------------------------------------------------------------
+'CosPropertyService_UnsupportedMode'(doc) -> ["CosPropertyService_UnsupportedMode"];
+'CosPropertyService_UnsupportedMode'(suite) -> [];
+'CosPropertyService_UnsupportedMode'(_) ->
+ ?match(true, orber_tc:check_tc('CosPropertyService_UnsupportedMode':tc())),
+ ?match("IDL:omg.org/CosPropertyService/UnsupportedMode:1.0",
+ 'CosPropertyService_UnsupportedMode':id()),
+ ?match("CosPropertyService_UnsupportedMode",
+ 'CosPropertyService_UnsupportedMode':name()),
+ ok.
+
+%%-----------------------------------------------------------------
+%% Test Case: 'CosPropertyService_UnsupportedProperty'
+%% Description:
+%%-----------------------------------------------------------------
+'CosPropertyService_UnsupportedProperty'(doc) -> ["CosPropertyService_UnsupportedProperty"];
+'CosPropertyService_UnsupportedProperty'(suite) -> [];
+'CosPropertyService_UnsupportedProperty'(_) ->
+ ?match(true, orber_tc:check_tc('CosPropertyService_UnsupportedProperty':tc())),
+ ?match("IDL:omg.org/CosPropertyService/UnsupportedProperty:1.0",
+ 'CosPropertyService_UnsupportedProperty':id()),
+ ?match("CosPropertyService_UnsupportedProperty",
+ 'CosPropertyService_UnsupportedProperty':name()),
+ ok.
+
+%%-----------------------------------------------------------------
+%% Test Case: 'CosPropertyService_UnsupportedTypeCode'
+%% Description:
+%%-----------------------------------------------------------------
+'CosPropertyService_UnsupportedTypeCode'(doc) -> ["CosPropertyService_UnsupportedTypeCode"];
+'CosPropertyService_UnsupportedTypeCode'(suite) -> [];
+'CosPropertyService_UnsupportedTypeCode'(_) ->
+ ?match(true, orber_tc:check_tc('CosPropertyService_UnsupportedTypeCode':tc())),
+ ?match("IDL:omg.org/CosPropertyService/UnsupportedTypeCode:1.0",
+ 'CosPropertyService_UnsupportedTypeCode':id()),
+ ?match("CosPropertyService_UnsupportedTypeCode",
+ 'CosPropertyService_UnsupportedTypeCode':name()),
+ ok.
+
+%%-----------------------------------------------------------------
+%% Test Case: 'CosPropertyService_PropertyNamesIterator'
+%% Description:
+%%-----------------------------------------------------------------
+'CosPropertyService_PropertyNamesIterator'(doc) -> ["CosPropertyService_PropertyNamesIterator"];
+'CosPropertyService_PropertyNamesIterator'(suite) -> [];
+'CosPropertyService_PropertyNamesIterator'(_) ->
+ ?nomatch(undefined, 'CosPropertyService_PropertyNamesIterator':oe_tc(reset)),
+ ?nomatch(undefined, 'CosPropertyService_PropertyNamesIterator':oe_tc(next_one)),
+ ?nomatch(undefined, 'CosPropertyService_PropertyNamesIterator':oe_tc(next_n)),
+ ?nomatch(undefined, 'CosPropertyService_PropertyNamesIterator':oe_tc(destroy)),
+ ?match(undefined, 'CosPropertyService_PropertyNamesIterator':oe_tc(undefined)),
+ ?match([_|_], 'CosPropertyService_PropertyNamesIterator':oe_get_interface()),
+ ?match("IDL:omg.org/CosPropertyService/PropertyNamesIterator:1.0",
+ 'CosPropertyService_PropertyNamesIterator':typeID()),
+ check_tc('CosPropertyService_PropertyNamesIterator':oe_get_interface()),
+ ?match(true, 'CosPropertyService_PropertyNamesIterator':oe_is_a('CosPropertyService_PropertyNamesIterator':typeID())),
+ ?match(false, 'CosPropertyService_PropertyNamesIterator':oe_is_a("wrong")),
+ ok.
+
+%%-----------------------------------------------------------------
+%% Test Case: 'CosPropertyService_PropertiesIterator'
+%% Description:
+%%-----------------------------------------------------------------
+'CosPropertyService_PropertiesIterator'(doc) -> ["CosPropertyService_PropertiesIterator"];
+'CosPropertyService_PropertiesIterator'(suite) -> [];
+'CosPropertyService_PropertiesIterator'(_) ->
+ ?nomatch(undefined, 'CosPropertyService_PropertiesIterator':oe_tc(reset)),
+ ?nomatch(undefined, 'CosPropertyService_PropertiesIterator':oe_tc(next_one)),
+ ?nomatch(undefined, 'CosPropertyService_PropertiesIterator':oe_tc(next_n)),
+ ?nomatch(undefined, 'CosPropertyService_PropertiesIterator':oe_tc(destroy)),
+ ?match(undefined, 'CosPropertyService_PropertiesIterator':oe_tc(undefined)),
+ ?match([_|_], 'CosPropertyService_PropertiesIterator':oe_get_interface()),
+ ?match("IDL:omg.org/CosPropertyService/PropertiesIterator:1.0",
+ 'CosPropertyService_PropertiesIterator':typeID()),
+ check_tc('CosPropertyService_PropertiesIterator':oe_get_interface()),
+ ?match(true, 'CosPropertyService_PropertiesIterator':oe_is_a('CosPropertyService_PropertiesIterator':typeID())),
+ ?match(false, 'CosPropertyService_PropertiesIterator':oe_is_a("wrong")),
+ ok.
+
+
+%%-----------------------------------------------------------------
+%% Test Case: 'CosPropertyService_PropertySet'
+%% Description:
+%%-----------------------------------------------------------------
+'CosPropertyService_PropertySet'(doc) -> ["CosPropertyService_PropertySet"];
+'CosPropertyService_PropertySet'(suite) -> [];
+'CosPropertyService_PropertySet'(_) ->
+ ?nomatch(undefined, 'CosPropertyService_PropertySet':oe_tc(define_property)),
+ ?nomatch(undefined, 'CosPropertyService_PropertySet':oe_tc(define_properties)),
+ ?nomatch(undefined, 'CosPropertyService_PropertySet':oe_tc(get_number_of_properties)),
+ ?nomatch(undefined, 'CosPropertyService_PropertySet':oe_tc(get_all_property_names)),
+ ?nomatch(undefined, 'CosPropertyService_PropertySet':oe_tc(get_property_value)),
+ ?nomatch(undefined, 'CosPropertyService_PropertySet':oe_tc(get_properties)),
+ ?nomatch(undefined, 'CosPropertyService_PropertySet':oe_tc(get_all_properties)),
+ ?nomatch(undefined, 'CosPropertyService_PropertySet':oe_tc(delete_property)),
+ ?nomatch(undefined, 'CosPropertyService_PropertySet':oe_tc(delete_properties)),
+ ?nomatch(undefined, 'CosPropertyService_PropertySet':oe_tc(delete_all_properties)),
+ ?nomatch(undefined, 'CosPropertyService_PropertySet':oe_tc(is_property_defined)),
+ ?match(undefined, 'CosPropertyService_PropertySet':oe_tc(undefined)),
+ ?match([_|_], 'CosPropertyService_PropertySet':oe_get_interface()),
+ ?match("IDL:omg.org/CosPropertyService/PropertySet:1.0",
+ 'CosPropertyService_PropertySet':typeID()),
+ check_tc('CosPropertyService_PropertySet':oe_get_interface()),
+ ?match(true, 'CosPropertyService_PropertySet':oe_is_a('CosPropertyService_PropertySet':typeID())),
+ ?match(false, 'CosPropertyService_PropertySet':oe_is_a("wrong")),
+ ok.
+
+
+%%-----------------------------------------------------------------
+%% Test Case: 'CosPropertyService_PropertySetDef'
+%% Description:
+%%-----------------------------------------------------------------
+'CosPropertyService_PropertySetDef'(doc) -> ["CosPropertyService_PropertySetDef"];
+'CosPropertyService_PropertySetDef'(suite) -> [];
+'CosPropertyService_PropertySetDef'(_) ->
+ ?nomatch(undefined, 'CosPropertyService_PropertySetDef':oe_tc(get_allowed_property_types)),
+ ?nomatch(undefined, 'CosPropertyService_PropertySetDef':oe_tc(get_allowed_properties)),
+ ?nomatch(undefined, 'CosPropertyService_PropertySetDef':oe_tc(define_property_with_mode)),
+ ?nomatch(undefined, 'CosPropertyService_PropertySetDef':oe_tc(define_properties_with_modes)),
+ ?nomatch(undefined, 'CosPropertyService_PropertySetDef':oe_tc(get_property_mode)),
+ ?nomatch(undefined, 'CosPropertyService_PropertySetDef':oe_tc(get_property_modes)),
+ ?nomatch(undefined, 'CosPropertyService_PropertySetDef':oe_tc(set_property_mode)),
+ ?nomatch(undefined, 'CosPropertyService_PropertySetDef':oe_tc(set_property_modes)),
+ ?nomatch(undefined, 'CosPropertyService_PropertySetDef':oe_tc(define_property)),
+ ?nomatch(undefined, 'CosPropertyService_PropertySetDef':oe_tc(define_properties)),
+ ?nomatch(undefined, 'CosPropertyService_PropertySetDef':oe_tc(get_number_of_properties)),
+ ?nomatch(undefined, 'CosPropertyService_PropertySetDef':oe_tc(get_all_property_names)),
+ ?nomatch(undefined, 'CosPropertyService_PropertySetDef':oe_tc(get_property_value)),
+ ?nomatch(undefined, 'CosPropertyService_PropertySetDef':oe_tc(get_properties)),
+ ?nomatch(undefined, 'CosPropertyService_PropertySetDef':oe_tc(get_all_properties)),
+ ?nomatch(undefined, 'CosPropertyService_PropertySetDef':oe_tc(delete_property)),
+ ?nomatch(undefined, 'CosPropertyService_PropertySetDef':oe_tc(delete_properties)),
+ ?nomatch(undefined, 'CosPropertyService_PropertySetDef':oe_tc(delete_all_properties)),
+ ?nomatch(undefined, 'CosPropertyService_PropertySetDef':oe_tc(is_property_defined)),
+ ?match(undefined, 'CosPropertyService_PropertySetDef':oe_tc(undefined)),
+ ?match([_|_], 'CosPropertyService_PropertySetDef':oe_get_interface()),
+ ?match("IDL:omg.org/CosPropertyService/PropertySetDef:1.0",
+ 'CosPropertyService_PropertySetDef':typeID()),
+ check_tc('CosPropertyService_PropertySetDef':oe_get_interface()),
+ ?match(true, 'CosPropertyService_PropertySetDef':oe_is_a('CosPropertyService_PropertySetDef':typeID())),
+ ?match(true, 'CosPropertyService_PropertySetDef':oe_is_a('CosPropertyService_PropertySet':typeID())),
+ ?match(false, 'CosPropertyService_PropertySetDef':oe_is_a("wrong")),
+ ok.
+
+
+%%-----------------------------------------------------------------
+%% Test Case: 'CosPropertyService_PropertySetDefFactory'
+%% Description:
+%%-----------------------------------------------------------------
+'CosPropertyService_PropertySetDefFactory'(doc) -> ["CosPropertyService_PropertySetDefFactory"];
+'CosPropertyService_PropertySetDefFactory'(suite) -> [];
+'CosPropertyService_PropertySetDefFactory'(_) ->
+ ?nomatch(undefined, 'CosPropertyService_PropertySetDefFactory':oe_tc(create_propertysetdef)),
+ ?nomatch(undefined, 'CosPropertyService_PropertySetDefFactory':oe_tc(create_constrained_propertysetdef)),
+ ?nomatch(undefined, 'CosPropertyService_PropertySetDefFactory':oe_tc(create_initial_propertysetdef)),
+ ?match(undefined, 'CosPropertyService_PropertySetDefFactory':oe_tc(undefined)),
+ ?match([_|_], 'CosPropertyService_PropertySetDefFactory':oe_get_interface()),
+ ?match("IDL:omg.org/CosPropertyService/PropertySetDefFactory:1.0",
+ 'CosPropertyService_PropertySetDefFactory':typeID()),
+ check_tc('CosPropertyService_PropertySetDefFactory':oe_get_interface()),
+ ?match(true, 'CosPropertyService_PropertySetDefFactory':oe_is_a('CosPropertyService_PropertySetDefFactory':typeID())),
+ ?match(false, 'CosPropertyService_PropertySetDefFactory':oe_is_a("wrong")),
+ ok.
+
+
+%%-----------------------------------------------------------------
+%% Test Case: 'CosPropertyService_PropertySetFactory'
+%% Description:
+%%-----------------------------------------------------------------
+'CosPropertyService_PropertySetFactory'(doc) -> ["CosPropertyService_PropertySetFactory"];
+'CosPropertyService_PropertySetFactory'(suite) -> [];
+'CosPropertyService_PropertySetFactory'(_) ->
+ ?nomatch(undefined, 'CosPropertyService_PropertySetFactory':oe_tc(create_propertyset)),
+ ?nomatch(undefined, 'CosPropertyService_PropertySetFactory':oe_tc(create_constrained_propertyset)),
+ ?nomatch(undefined, 'CosPropertyService_PropertySetFactory':oe_tc(create_initial_propertyset)),
+ ?match(undefined, 'CosPropertyService_PropertySetFactory':oe_tc(undefined)),
+ ?match([_|_], 'CosPropertyService_PropertySetFactory':oe_get_interface()),
+ ?match("IDL:omg.org/CosPropertyService/PropertySetFactory:1.0",
+ 'CosPropertyService_PropertySetFactory':typeID()),
+ check_tc('CosPropertyService_PropertySetFactory':oe_get_interface()),
+ ?match(true, 'CosPropertyService_PropertySetFactory':oe_is_a('CosPropertyService_PropertySetFactory':typeID())),
+ ?match(false, 'CosPropertyService_PropertySetFactory':oe_is_a("wrong")),
+ ok.
+
+
+
+%%-----------------------------------------------------------------
+%% MISC functions
+%%-----------------------------------------------------------------
+check_tc([]) ->
+ ok;
+check_tc([{Op, {RetType, InParameters, OutParameters}}|T]) ->
+ io:format("checked - ~s~n", [Op]),
+ lists:all(?checktc(Op), [RetType|InParameters]),
+ lists:all(?checktc(Op), OutParameters),
+ check_tc(T).
+
+
diff --git a/lib/cosProperty/test/property_SUITE.erl b/lib/cosProperty/test/property_SUITE.erl
new file mode 100644
index 0000000000..8fed3128ef
--- /dev/null
+++ b/lib/cosProperty/test/property_SUITE.erl
@@ -0,0 +1,747 @@
+%%----------------------------------------------------------------------
+%%
+%% %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%
+%%
+%%
+%%----------------------------------------------------------------------
+%% File : property_SUITE.erl
+%% Description :
+%%
+%%----------------------------------------------------------------------
+-module(property_SUITE).
+
+
+%%--------------- INCLUDES -----------------------------------
+-include_lib("orber/include/corba.hrl").
+-include_lib("orber/src/orber_iiop.hrl").
+-include_lib("cosProperty/src/cosProperty.hrl").
+-include_lib("cosProperty/include/CosPropertyService.hrl").
+
+-include("test_server.hrl").
+
+%%--------------- DEFINES ------------------------------------
+-define(default_timeout, ?t:minutes(20)).
+-define(match(ExpectedRes, Expr),
+ fun() ->
+ AcTuAlReS = (catch (Expr)),
+ case AcTuAlReS of
+ ExpectedRes ->
+ io:format("------ CORRECT RESULT ------~n~p~n",
+ [AcTuAlReS]),
+ AcTuAlReS;
+ _ ->
+ io:format("###### ERROR ERROR ######~n~p~n",
+ [AcTuAlReS]),
+ exit(AcTuAlReS)
+ end
+ end()).
+
+-define(match_inverse(NotExpectedRes, Expr),
+ fun() ->
+ AcTuAlReS = (catch (Expr)),
+ case AcTuAlReS of
+ NotExpectedRes ->
+ io:format("###### ERROR ERROR ######~n ~p~n",
+ [AcTuAlReS]),
+ exit(AcTuAlReS);
+ _ ->
+ io:format("------ CORRECT RESULT ------~n~p~n",
+ [AcTuAlReS]),
+ AcTuAlReS
+ end
+ end()).
+
+
+-define(val1, #any{typecode=tk_short, value=1}).
+-define(val2, #any{typecode=tk_short, value=2}).
+-define(val3, #any{typecode=tk_short, value=3}).
+-define(val4, #any{typecode=tk_short, value=4}).
+-define(val5, #any{typecode=tk_long, value=5}).
+-define(badval, #any{typecode=tk_shirt, value=5}).
+
+-define(id1, "id1").
+-define(id2, "id2").
+-define(id3, "id3").
+-define(id4, "id4").
+-define(id5, "id5").
+-define(badid, "").
+
+
+%%-----------------------------------------------------------------
+%% External exports
+%%-----------------------------------------------------------------
+%% Fixed exports
+-export([all/1, cases/0, init_all/1, finish_all/1,
+ init_per_testcase/2, fin_per_testcase/2]).
+%% Test cases
+-export([create_setdef_api/1, create_set_api/1, define_with_mode_api/1,
+ define_api/1, names_iterator_api/1, properties_iterator_api/1,
+ app_test/1]).
+
+%%-----------------------------------------------------------------
+%% Func: all/1
+%% Args:
+%% Returns:
+%%-----------------------------------------------------------------
+all(doc) -> ["API tests for the cosProperty interfaces", ""];
+all(suite) -> {req,
+ [mnesia, orber],
+ {conf, init_all, cases(), finish_all}}.
+
+cases() ->
+ [create_setdef_api, create_set_api, define_with_mode_api, define_api,
+ names_iterator_api, properties_iterator_api, app_test].
+
+
+
+%%-----------------------------------------------------------------
+%% Init and cleanup functions.
+%%-----------------------------------------------------------------
+
+init_per_testcase(_Case, Config) ->
+ Path = code:which(?MODULE),
+ code:add_pathz(filename:join(filename:dirname(Path), "idl_output")),
+ ?line Dog=test_server:timetrap(?default_timeout),
+ [{watchdog, Dog}|Config].
+
+
+fin_per_testcase(_Case, Config) ->
+ Path = code:which(?MODULE),
+ code:del_path(filename:join(filename:dirname(Path), "idl_output")),
+ Dog = ?config(watchdog, Config),
+ test_server:timetrap_cancel(Dog),
+ ok.
+
+init_all(Config) ->
+ Path = code:which(?MODULE),
+ code:add_pathz(filename:join(filename:dirname(Path), "idl_output")),
+ orber:jump_start(),
+ cosProperty:install(),
+ cosProperty:install_db(),
+ ?line ?match(ok, application:start(cosProperty)),
+ if
+ is_list(Config) ->
+ Config;
+ true ->
+ exit("Config not a list")
+ end.
+
+finish_all(Config) ->
+ Path = code:which(?MODULE),
+ code:del_path(filename:join(filename:dirname(Path), "idl_output")),
+ application:stop(cosProperty),
+ cosProperty:uninstall_db(),
+ cosProperty:uninstall(),
+ orber:jump_stop(),
+ Config.
+
+%%-----------------------------------------------------------------
+%% Tests app file
+%%-----------------------------------------------------------------
+app_test(doc) -> [];
+app_test(suite) -> [];
+app_test(_Config) ->
+ ok=test_server:app_test(cosProperty),
+ ok.
+
+
+%%-----------------------------------------------------------------
+%% CosPropertyService_PropertySetDefFactory API tests
+%%-----------------------------------------------------------------
+create_setdef_api(doc) -> ["CosPropertyService_PropertySetDefFactory API tests.",
+ ""];
+create_setdef_api(suite) -> [];
+create_setdef_api(_Config) ->
+
+ ValidDefs = [#'CosPropertyService_PropertyDef'
+ {property_name = ?id1,
+ property_value = ?val1,
+ property_mode = normal},
+ #'CosPropertyService_PropertyDef'
+ {property_name = ?id2,
+ property_value = ?val2,
+ property_mode = normal}],
+ InvalidDefs = [#'CosPropertyService_PropertyDef'
+ {property_name = ?id1,
+ property_value = ?val1,
+ property_mode = normal},
+ #'CosPropertyService_PropertyDef'
+ {property_name = ?badid,
+ property_value = ?badval,
+ property_mode = normal}],
+
+ Fac = ?match({_,pseudo,_,_,_,_}, cosProperty:start_SetDefFactory()),
+
+ Obj1 = ?match({_,pseudo,_,_,_,_}, 'CosPropertyService_PropertySetDefFactory':
+ create_propertysetdef(Fac)),
+ 'CosPropertyService_PropertySetDef_impl':dump(),
+ corba:dispose(Obj1),
+
+
+ Obj2 = ?match({_,pseudo,_,_,_,_}, 'CosPropertyService_PropertySetDefFactory':
+ create_constrained_propertysetdef(Fac, [tk_short], ValidDefs)),
+ 'CosPropertyService_PropertySetDef_impl':dump(),
+ corba:dispose(Obj2),
+
+ %% Both arguments correct but 'ValidDefs' contain other TC:s than
+ %% tk_null.
+ ?match({'EXCEPTION', _}, 'CosPropertyService_PropertySetDefFactory':
+ create_constrained_propertysetdef(Fac, [tk_null], ValidDefs)),
+ 'CosPropertyService_PropertySetDef_impl':dump(),
+
+ ?match({'EXCEPTION', _}, 'CosPropertyService_PropertySetDefFactory':
+ create_constrained_propertysetdef(Fac, [tk_null], InvalidDefs)),
+ 'CosPropertyService_PropertySetDef_impl':dump(),
+
+ %% The allowed TC not supported.
+ ?match({'EXCEPTION', _}, 'CosPropertyService_PropertySetDefFactory':
+ create_constrained_propertysetdef(Fac, [tk_noll], ValidDefs)),
+ 'CosPropertyService_PropertySetDef_impl':dump(),
+
+ Obj4 = ?match({_,pseudo,_,_,_,_}, 'CosPropertyService_PropertySetDefFactory':
+ create_initial_propertysetdef(Fac, ValidDefs)),
+ 'CosPropertyService_PropertySetDef_impl':dump(),
+ corba:dispose(Obj4),
+
+ ?match({'EXCEPTION', _}, 'CosPropertyService_PropertySetDefFactory':
+ create_initial_propertysetdef(Fac, InvalidDefs)),
+
+ ?match(ok, cosProperty:stop_SetDefFactory(Fac)),
+
+ ok.
+
+
+%%-----------------------------------------------------------------
+%% CosPropertyService_PropertySetFactory API tests
+%%-----------------------------------------------------------------
+create_set_api(doc) -> ["CosPropertyService_PropertySetFactory API tests.",
+ ""];
+create_set_api(suite) -> [];
+create_set_api(_Config) ->
+ Valid = [#'CosPropertyService_Property'
+ {property_name = ?id1,
+ property_value = ?val1},
+ #'CosPropertyService_Property'
+ {property_name = ?id2,
+ property_value = ?val2}],
+ Invalid = [#'CosPropertyService_Property'
+ {property_name = ?id1,
+ property_value = ?val1},
+ #'CosPropertyService_Property'
+ {property_name = ?badid,
+ property_value = ?badval}],
+
+ Fac = ?match({_,pseudo,_,_,_,_}, cosProperty:start_SetFactory()),
+ Obj1 = ?match({_,pseudo,_,_,_,_}, 'CosPropertyService_PropertySetFactory':
+ create_propertyset(Fac)),
+ 'CosPropertyService_PropertySetDef_impl':dump(),
+ corba:dispose(Obj1),
+
+
+ Obj2 = ?match({_,pseudo,_,_,_,_}, 'CosPropertyService_PropertySetFactory':
+ create_constrained_propertyset(Fac, [tk_short], Valid)),
+ 'CosPropertyService_PropertySetDef_impl':dump(),
+ corba:dispose(Obj2),
+
+ %% Both arguments correct but 'Valid' contain other TC:s than
+ %% tk_null.
+ ?match({'EXCEPTION', _}, 'CosPropertyService_PropertySetFactory':
+ create_constrained_propertyset(Fac, [tk_null], Valid)),
+ 'CosPropertyService_PropertySetDef_impl':dump(),
+
+ ?match({'EXCEPTION', _}, 'CosPropertyService_PropertySetFactory':
+ create_constrained_propertyset(Fac, [tk_null], Invalid)),
+ 'CosPropertyService_PropertySetDef_impl':dump(),
+
+ %% The allowed TC not supported.
+ ?match({'EXCEPTION', _}, 'CosPropertyService_PropertySetFactory':
+ create_constrained_propertyset(Fac, [tk_noll], Valid)),
+ 'CosPropertyService_PropertySetDef_impl':dump(),
+
+ Obj4 = ?match({_,pseudo,_,_,_,_}, 'CosPropertyService_PropertySetFactory':
+ create_initial_propertyset(Fac, Valid)),
+ 'CosPropertyService_PropertySetDef_impl':dump(),
+ corba:dispose(Obj4),
+
+ ?match({'EXCEPTION', _}, 'CosPropertyService_PropertySetFactory':
+ create_initial_propertyset(Fac, Invalid)),
+ ?match(ok, cosProperty:stop_SetFactory(Fac)),
+ ok.
+
+%%-----------------------------------------------------------------
+%% CosPropertyService_PropertySetDef API tests
+%%-----------------------------------------------------------------
+define_api(doc) -> ["CosPropertyService_PropertySet API tests.",
+ ""];
+define_api(suite) -> [];
+define_api(_Config) ->
+ ValidDefs = [#'CosPropertyService_Property'
+ {property_name = ?id1,
+ property_value = ?val1},
+ #'CosPropertyService_Property'
+ {property_name = ?id2,
+ property_value = ?val2},
+ #'CosPropertyService_Property'
+ {property_name = ?id3,
+ property_value = ?val3}],
+
+ Fac = ?match({_,pseudo,_,_,_,_}, cosProperty:start_SetFactory()),
+
+ io:format("@@@@ Testing PropertySet returned by the factory operation create_propertyset/1 @@@@", []),
+ Obj = ?match({_,pseudo,_,_,_,_}, 'CosPropertyService_PropertySetFactory':
+ create_propertyset(Fac)),
+ ?match(ok, 'CosPropertyService_PropertySet':define_property(Obj, ?id1, ?val1)),
+ ?match(ok, 'CosPropertyService_PropertySet':define_property(Obj, ?id1, ?val1)),
+
+ ?match(1, 'CosPropertyService_PropertySet':get_number_of_properties(Obj)),
+ ?match(ok, 'CosPropertyService_PropertySet':
+ define_properties(Obj, [#'CosPropertyService_Property'{property_name = ?id2,
+ property_value = ?val2},
+ #'CosPropertyService_Property'{property_name = ?id3,
+ property_value = ?val3}])),
+
+ ?match(3, 'CosPropertyService_PropertySet':get_number_of_properties(Obj)),
+
+ ?match({true, [_]}, 'CosPropertyService_PropertySet':get_properties(Obj, [?id1])),
+ ?match({true, [_, _, _]}, 'CosPropertyService_PropertySet':get_properties(Obj, [?id1, ?id2, ?id3])),
+ ?match({false,[_, _, _]}, 'CosPropertyService_PropertySet':get_properties(Obj, [?id1, "wrong", ?id3])),
+
+ ?match(?val2, 'CosPropertyService_PropertySet':get_property_value(Obj, ?id2)),
+ ?match(ok, 'CosPropertyService_PropertySet':delete_property(Obj, ?id1)),
+
+ ?match(2, 'CosPropertyService_PropertySet':get_number_of_properties(Obj)),
+
+ ?match(ok, 'CosPropertyService_PropertySet':define_property(Obj, ?id1, ?val1)),
+ ?match(ok, 'CosPropertyService_PropertySet':define_property(Obj, ?id2, ?val2)),
+ ?match(ok, 'CosPropertyService_PropertySet':define_property(Obj, ?id3, ?val3)),
+
+ ?match(true, 'CosPropertyService_PropertySet':delete_all_properties(Obj)),
+ ?match(0, 'CosPropertyService_PropertySet':get_number_of_properties(Obj)),
+
+ ?match(ok, 'CosPropertyService_PropertySet':
+ define_properties(Obj, [#'CosPropertyService_Property'{property_name = ?id1,
+ property_value = ?val1},
+ #'CosPropertyService_Property'{property_name = ?id2,
+ property_value = ?val2},
+ #'CosPropertyService_Property'{property_name = ?id3,
+ property_value = ?val3}])),
+
+ ?match(3, 'CosPropertyService_PropertySet':get_number_of_properties(Obj)),
+ ?match(?val2, 'CosPropertyService_PropertySet':get_property_value(Obj, ?id2)),
+
+ ?match({'EXCEPTION',{'CosPropertyService_PropertyNotFound',_}},
+ 'CosPropertyService_PropertySet':get_property_value(Obj, "wrongID")),
+ ?match({'EXCEPTION',{'CosPropertyService_InvalidPropertyName',_}},
+ 'CosPropertyService_PropertySet':get_property_value(Obj, "")),
+ ?match({'EXCEPTION',{'CosPropertyService_InvalidPropertyName',_}},
+ 'CosPropertyService_PropertySet':is_property_defined(Obj, "")),
+ ?match(false, 'CosPropertyService_PropertySet':is_property_defined(Obj, "wrongID")),
+ ?match(true, 'CosPropertyService_PropertySet':is_property_defined(Obj, ?id1)),
+
+ %% This function is not supported by PropertySet.
+ ?match({'EXCEPTION',{'NO_IMPLEMENT',_,_,_}},
+ 'CosPropertyService_PropertySetDef':get_property_modes(Obj, [?id1, ?id2, ?id3])),
+
+ ?match({'EXCEPTION',{'CosPropertyService_MultipleExceptions',_,_}},
+ 'CosPropertyService_PropertySet':delete_properties(Obj, [?id1, ?id2, ?id3, "wrongID"])),
+ ?match(0, 'CosPropertyService_PropertySet':get_number_of_properties(Obj)),
+ corba:dispose(Obj),
+
+ io:format("@@@@ Testing PropertySet returned by the factory operation create_constrained_propertyset/3 @@@@", []),
+ Obj2 = ?match({_,pseudo,_,_,_,_}, 'CosPropertyService_PropertySetFactory':
+ create_constrained_propertyset(Fac, [tk_short], ValidDefs)),
+
+ ?match(0, 'CosPropertyService_PropertySet':get_number_of_properties(Obj2)),
+ ?match({'EXCEPTION', {'CosPropertyService_UnsupportedProperty',_}},
+ 'CosPropertyService_PropertySet':define_property(Obj2, ?id4, ?val4)),
+ ?match({'EXCEPTION', {'CosPropertyService_UnsupportedTypeCode',_}},
+ 'CosPropertyService_PropertySet':define_property(Obj2, ?id1, ?val5)),
+ ?match(ok, 'CosPropertyService_PropertySet':define_property(Obj2, ?id1, ?val1)),
+ ?match(1, 'CosPropertyService_PropertySet':get_number_of_properties(Obj2)),
+ ?match({'EXCEPTION',{'CosPropertyService_MultipleExceptions',_,_}},
+ 'CosPropertyService_PropertySet':
+ define_properties(Obj2, [#'CosPropertyService_Property'{property_name = ?id2,
+ property_value = ?val2},
+ #'CosPropertyService_Property'{property_name = ?id3,
+ property_value = ?val3},
+ #'CosPropertyService_Property'{property_name = "wrongId",
+ property_value = ?val2}])),
+ ?match(ok,'CosPropertyService_PropertySet':
+ define_properties(Obj2, [#'CosPropertyService_Property'{property_name = ?id2,
+ property_value = ?val2},
+ #'CosPropertyService_Property'{property_name = ?id3,
+ property_value = ?val3}])),
+ ?match(3, 'CosPropertyService_PropertySet':get_number_of_properties(Obj2)),
+ ?match({'EXCEPTION',{'CosPropertyService_PropertyNotFound',_}},
+ 'CosPropertyService_PropertySet':get_property_value(Obj2, "wrongID")),
+ ?match(?val2, 'CosPropertyService_PropertySet':get_property_value(Obj2, ?id2)),
+ ?match({'EXCEPTION',{'CosPropertyService_InvalidPropertyName',_}},
+ 'CosPropertyService_PropertySet':get_property_value(Obj2, "")),
+ ?match({'EXCEPTION',{'CosPropertyService_InvalidPropertyName',_}},
+ 'CosPropertyService_PropertySet':is_property_defined(Obj2, "")),
+ ?match(false, 'CosPropertyService_PropertySet':is_property_defined(Obj2, "wrongID")),
+ ?match(true, 'CosPropertyService_PropertySet':is_property_defined(Obj2, ?id1)),
+
+
+ ?match({'EXCEPTION',{'CosPropertyService_PropertyNotFound',_}},
+ 'CosPropertyService_PropertySet':delete_property(Obj2, "wrongID")),
+ ?match(3, 'CosPropertyService_PropertySet':get_number_of_properties(Obj2)),
+ ?match(ok, 'CosPropertyService_PropertySet':delete_property(Obj2, ?id1)),
+ ?match(2, 'CosPropertyService_PropertySet':get_number_of_properties(Obj2)),
+
+ ?match(ok, 'CosPropertyService_PropertySet':delete_properties(Obj2, [?id2])),
+ ?match(1, 'CosPropertyService_PropertySet':get_number_of_properties(Obj2)),
+
+ ?match({'EXCEPTION',{'CosPropertyService_MultipleExceptions',_,_}},
+ 'CosPropertyService_PropertySet':delete_properties(Obj2, [?id3, "wrongID"])),
+ ?match(0, 'CosPropertyService_PropertySet':get_number_of_properties(Obj2)),
+ corba:dispose(Obj2),
+
+ io:format("@@@@ Testing PropertySet returned by the factory operation create_initial_propertyset/2 @@@@", []),
+ Obj3 = ?match({_,pseudo,_,_,_,_}, 'CosPropertyService_PropertySetFactory':
+ create_initial_propertyset(Fac, ValidDefs)),
+ ?match(3, 'CosPropertyService_PropertySet':get_number_of_properties(Obj3)),
+
+ ?match(ok, 'CosPropertyService_PropertySet':define_property(Obj3, ?id4, ?val4)),
+ ?match(4, 'CosPropertyService_PropertySet':get_number_of_properties(Obj3)),
+
+ ?match(ok,'CosPropertyService_PropertySet':
+ define_properties(Obj3, [#'CosPropertyService_Property'{property_name = ?id5,
+ property_value = ?val5}])),
+
+ ?match(5, 'CosPropertyService_PropertySet':get_number_of_properties(Obj3)),
+
+ ?match({'EXCEPTION',{'CosPropertyService_PropertyNotFound',_}},
+ 'CosPropertyService_PropertySet':get_property_value(Obj3, "wrongID")),
+ ?match(?val2, 'CosPropertyService_PropertySet':get_property_value(Obj3, ?id2)),
+ ?match({'EXCEPTION',{'CosPropertyService_InvalidPropertyName',_}},
+ 'CosPropertyService_PropertySet':get_property_value(Obj3, "")),
+ ?match({'EXCEPTION',{'CosPropertyService_InvalidPropertyName',_}},
+ 'CosPropertyService_PropertySet':is_property_defined(Obj3, "")),
+ ?match(false, 'CosPropertyService_PropertySet':is_property_defined(Obj3, "wrongID")),
+ ?match(true, 'CosPropertyService_PropertySet':is_property_defined(Obj3, ?id1)),
+
+ ?match({'EXCEPTION',{'CosPropertyService_PropertyNotFound',_}},
+ 'CosPropertyService_PropertySet':delete_property(Obj3, "wrongId")),
+ ?match(ok, 'CosPropertyService_PropertySet':delete_property(Obj3, ?id5)),
+ ?match(4, 'CosPropertyService_PropertySet':get_number_of_properties(Obj3)),
+
+ ?match({'EXCEPTION',{'CosPropertyService_MultipleExceptions',_,_}},
+ 'CosPropertyService_PropertySet':delete_properties(Obj3, [?id1, ?id2, ?id3, "wrongID"])),
+ ?match(1, 'CosPropertyService_PropertySet':get_number_of_properties(Obj3)),
+
+ ?match(true, 'CosPropertyService_PropertySet':delete_all_properties(Obj3)),
+ ?match(0, 'CosPropertyService_PropertySet':get_number_of_properties(Obj3)),
+
+ corba:dispose(Obj3),
+ ?match(ok, cosProperty:stop_SetFactory(Fac)),
+
+ ok.
+
+%%-----------------------------------------------------------------
+%% CosPropertyService_PropertySetDef API tests
+%%-----------------------------------------------------------------
+define_with_mode_api(doc) -> ["CosPropertyService_PropertySetDef API tests.",
+ ""];
+define_with_mode_api(suite) -> [];
+define_with_mode_api(_Config) ->
+ ValidDefs = [#'CosPropertyService_PropertyDef'
+ {property_name = ?id1,
+ property_value = ?val1,
+ property_mode = normal},
+ #'CosPropertyService_PropertyDef'
+ {property_name = ?id2,
+ property_value = ?val2,
+ property_mode = normal},
+ #'CosPropertyService_PropertyDef'
+ {property_name = ?id3,
+ property_value = ?val3,
+ property_mode = normal}],
+
+ Fac = ?match({_,pseudo,_,_,_,_}, cosProperty:start_SetDefFactory()),
+
+ io:format("@@@@ Testing PropertySetDef returned by the factory operation create_propertysetdef/1 @@@@", []),
+ Obj = ?match({_,pseudo,_,_,_,_}, 'CosPropertyService_PropertySetDefFactory':
+ create_propertysetdef(Fac)),
+
+ %% Initally no prop's created and no restrictions at all
+ ?match(0, 'CosPropertyService_PropertySetDef':get_number_of_properties(Obj)),
+ ?match({ok, []}, 'CosPropertyService_PropertySetDef':get_allowed_property_types(Obj)),
+ ?match({ok, []}, 'CosPropertyService_PropertySetDef':get_allowed_properties(Obj)),
+
+ %% Add two properties.
+ ?match(ok, 'CosPropertyService_PropertySetDef':define_property_with_mode(Obj, ?id4, ?val4, read_only)),
+ ?match(ok, 'CosPropertyService_PropertySetDef':define_property_with_mode(Obj, ?id5, ?val5, normal)),
+ %% Try to add the same property again (shouldn't add another since using the sam Id).
+ ?match(ok, 'CosPropertyService_PropertySetDef':define_property_with_mode(Obj, ?id5, ?val5, normal)),
+
+ %% Try to add another identical proprty with wrong TC.
+ ?match({'EXCEPTION',{'CosPropertyService_ConflictingProperty',_}},
+ 'CosPropertyService_PropertySetDef':define_property_with_mode(Obj, ?id5, ?val4, normal)),
+
+
+ %% Should be two now.
+ ?match(2, 'CosPropertyService_PropertySetDef':get_number_of_properties(Obj)),
+
+ ?match(read_only, 'CosPropertyService_PropertySetDef':get_property_mode(Obj, ?id4)),
+ ?match(normal, 'CosPropertyService_PropertySetDef':get_property_mode(Obj, ?id5)),
+ ?match(ok, 'CosPropertyService_PropertySetDef':
+ define_properties_with_modes(Obj,
+ [#'CosPropertyService_PropertyDef'{property_name = ?id1,
+ property_value = ?val1,
+ property_mode = normal},
+ #'CosPropertyService_PropertyDef'{property_name = ?id2,
+ property_value = ?val2,
+ property_mode = normal},
+ #'CosPropertyService_PropertyDef'{property_name = ?id3,
+ property_value = ?val3,
+ property_mode = normal}])),
+ %% Should be five now.
+ ?match(5, 'CosPropertyService_PropertySetDef':get_number_of_properties(Obj)),
+ ?match({true, [_,_]}, 'CosPropertyService_PropertySetDef':get_property_modes(Obj, [?id1, ?id3])),
+ ?match({false, [_,_,_]}, 'CosPropertyService_PropertySetDef':get_property_modes(Obj, [?id1, ?id3, "wrongID"])),
+
+ ?match(ok, 'CosPropertyService_PropertySetDef':set_property_mode(Obj, ?id1, read_only)),
+ ?match(read_only, 'CosPropertyService_PropertySetDef':get_property_mode(Obj, ?id1)),
+
+ ?match({'EXCEPTION',{'CosPropertyService_PropertyNotFound',_}},
+ 'CosPropertyService_PropertySetDef':set_property_mode(Obj, "wrongID", read_only)),
+
+ ?match({'EXCEPTION',{'CosPropertyService_MultipleExceptions',_,_}},
+ 'CosPropertyService_PropertySetDef':
+ set_property_modes(Obj,
+ [#'CosPropertyService_PropertyMode'{property_name = ?id2,
+ property_mode = read_only},
+ #'CosPropertyService_PropertyMode'{property_name = ?id3,
+ property_mode = read_only},
+ #'CosPropertyService_PropertyMode'{property_name = "wrongID",
+ property_mode = read_only}])),
+ ?match(normal, 'CosPropertyService_PropertySetDef':get_property_mode(Obj, ?id2)),
+ ?match(ok,
+ 'CosPropertyService_PropertySetDef':
+ set_property_modes(Obj,
+ [#'CosPropertyService_PropertyMode'{property_name = ?id2,
+ property_mode = read_only},
+ #'CosPropertyService_PropertyMode'{property_name = ?id3,
+ property_mode = read_only}])),
+ ?match(read_only, 'CosPropertyService_PropertySetDef':get_property_mode(Obj, ?id2)),
+
+ corba:dispose(Obj),
+
+
+ io:format("@@@@ Testing PropertySetDef returned by the factory operation create_constrained_propertysetdef/3 @@@@", []),
+ Obj2 = ?match({_,pseudo,_,_,_,_}, 'CosPropertyService_PropertySetDefFactory':
+ create_constrained_propertysetdef(Fac, [tk_short], ValidDefs)),
+
+ %% Initally no prop's created and the restrictions that only Properties eq. to ValidDefs
+ %% may be handled.
+ ?match(0, 'CosPropertyService_PropertySetDef':get_number_of_properties(Obj2)),
+ ?match({ok, [tk_short]}, 'CosPropertyService_PropertySetDef':get_allowed_property_types(Obj2)),
+ %% We cannot be sure in which order it's returned. Hmm, that's not really true but it
+ %% may change in the future.
+ ?match({ok, [_,_,_]}, 'CosPropertyService_PropertySetDef':get_allowed_properties(Obj2)),
+ %% Try to add a Property with and Id not eq. to ?id1, ?id2 or ?id3; must fail.
+ ?match({'EXCEPTION', {'CosPropertyService_UnsupportedProperty',_}},
+ 'CosPropertyService_PropertySetDef':define_property_with_mode(Obj2, ?id4, ?val4, read_only)),
+ %% To be sure that nothing was updated.
+ ?match(0, 'CosPropertyService_PropertySetDef':get_number_of_properties(Obj2)),
+ %% Add a valid Property.
+ ?match(ok, 'CosPropertyService_PropertySetDef':define_property_with_mode(Obj2, ?id1, ?val1, normal)),
+ ?match(1, 'CosPropertyService_PropertySetDef':get_number_of_properties(Obj2)),
+ %% Add a sequence of 1 valid and one invalid Prop's
+ ?match({'EXCEPTION', {'CosPropertyService_MultipleExceptions',_,_}},
+ 'CosPropertyService_PropertySetDef':
+ define_properties_with_modes(Obj2,
+ [#'CosPropertyService_PropertyDef'{property_name = ?id2,
+ property_value = ?val2,
+ property_mode = normal},
+ #'CosPropertyService_PropertyDef'{property_name = "wrongID",
+ property_value = ?val2,
+ property_mode = normal}])),
+ %% One should be added.
+ ?match(1, 'CosPropertyService_PropertySetDef':get_number_of_properties(Obj2)),
+ ?match(ok, 'CosPropertyService_PropertySetDef':
+ define_properties_with_modes(Obj2,
+ [#'CosPropertyService_PropertyDef'{property_name = ?id3,
+ property_value = ?val3,
+ property_mode = normal}])),
+ %% Add a sequence of 1 valid Prop.
+ ?match(2, 'CosPropertyService_PropertySetDef':get_number_of_properties(Obj2)),
+ ?match(normal, 'CosPropertyService_PropertySetDef':get_property_mode(Obj2, ?id1)),
+ ?match(normal, 'CosPropertyService_PropertySetDef':get_property_mode(Obj2, ?id3)),
+
+
+ ?match({true, [_,_]}, 'CosPropertyService_PropertySetDef':get_property_modes(Obj2, [?id1, ?id3])),
+ ?match({false, [_,_,_]}, 'CosPropertyService_PropertySetDef':get_property_modes(Obj2, [?id1, ?id3, "wrongID"])),
+
+ ?match(ok, 'CosPropertyService_PropertySetDef':set_property_mode(Obj2, ?id1, read_only)),
+ ?match(read_only, 'CosPropertyService_PropertySetDef':get_property_mode(Obj2, ?id1)),
+ ?match(ok, 'CosPropertyService_PropertySetDef':
+ set_property_modes(Obj2,
+ [#'CosPropertyService_PropertyMode'{property_name = ?id1,
+ property_mode = read_only},
+ #'CosPropertyService_PropertyMode'{property_name = ?id3,
+ property_mode = read_only}])),
+ ?match(read_only, 'CosPropertyService_PropertySetDef':get_property_mode(Obj2, ?id1)),
+ ?match(read_only, 'CosPropertyService_PropertySetDef':get_property_mode(Obj2, ?id3)),
+ ?match({'EXCEPTION',{'CosPropertyService_MultipleExceptions',_,_}},
+ 'CosPropertyService_PropertySetDef':
+ set_property_modes(Obj2,
+ [#'CosPropertyService_PropertyMode'{property_name = ?id1,
+ property_mode = normal},
+ #'CosPropertyService_PropertyMode'{property_name = ?id3,
+ property_mode = normal},
+ #'CosPropertyService_PropertyMode'{property_name = "wrongID",
+ property_mode = normal}])),
+
+ ?match(read_only, 'CosPropertyService_PropertySetDef':get_property_mode(Obj2, ?id1)),
+ ?match(read_only, 'CosPropertyService_PropertySetDef':get_property_mode(Obj2, ?id3)),
+ corba:dispose(Obj2),
+
+ io:format("@@@@ Testing PropertySetDef returned by the factory operation create_initial_propertysetdef/2 @@@@", []),
+ Obj3 = ?match({_,pseudo,_,_,_,_}, 'CosPropertyService_PropertySetDefFactory':
+ create_initial_propertysetdef(Fac, ValidDefs)),
+
+ %% Initally the supplied prop's are created and no restrictions.
+ ?match(3, 'CosPropertyService_PropertySetDef':get_number_of_properties(Obj3)),
+ ?match({ok, []}, 'CosPropertyService_PropertySetDef':get_allowed_property_types(Obj3)),
+ ?match({ok, []}, 'CosPropertyService_PropertySetDef':get_allowed_properties(Obj3)),
+
+ %% Add a new properties an test if they have been inserted.
+ ?match(ok, 'CosPropertyService_PropertySetDef':define_property_with_mode(Obj3, ?id4, ?val4, read_only)),
+ ?match(4, 'CosPropertyService_PropertySetDef':get_number_of_properties(Obj3)),
+ ?match(ok, 'CosPropertyService_PropertySetDef':define_property_with_mode(Obj3, ?id5, ?val5, read_only)),
+ ?match(5, 'CosPropertyService_PropertySetDef':get_number_of_properties(Obj3)),
+
+ %% Lookup each Property's mode.
+ ?match(normal, 'CosPropertyService_PropertySetDef':get_property_mode(Obj3, ?id1)),
+ ?match(normal, 'CosPropertyService_PropertySetDef':get_property_mode(Obj3, ?id2)),
+ ?match(normal, 'CosPropertyService_PropertySetDef':get_property_mode(Obj3, ?id3)),
+ ?match(read_only, 'CosPropertyService_PropertySetDef':get_property_mode(Obj3, ?id4)),
+ ?match(read_only, 'CosPropertyService_PropertySetDef':get_property_mode(Obj3, ?id5)),
+
+ ?match({true, [_,_,_,_,_]},
+ 'CosPropertyService_PropertySetDef':get_property_modes(Obj3, [?id1, ?id2, ?id3, ?id4, ?id5])),
+ ?match({false, [_,_]},
+ 'CosPropertyService_PropertySetDef':get_property_modes(Obj3, [?id1, "wrongID"])),
+ ?match(ok, 'CosPropertyService_PropertySetDef':set_property_mode(Obj3, ?id4, normal)),
+ ?match(normal, 'CosPropertyService_PropertySetDef':get_property_mode(Obj3, ?id4)),
+
+ ?match(ok, 'CosPropertyService_PropertySetDef':
+ set_property_modes(Obj3,
+ [#'CosPropertyService_PropertyMode'{property_name = ?id1,
+ property_mode = read_only},
+ #'CosPropertyService_PropertyMode'{property_name = ?id2,
+ property_mode = read_only}])),
+ ?match(read_only, 'CosPropertyService_PropertySetDef':get_property_mode(Obj3, ?id1)),
+ ?match(read_only, 'CosPropertyService_PropertySetDef':get_property_mode(Obj3, ?id2)),
+ ?match({'EXCEPTION',{'CosPropertyService_MultipleExceptions',_,_}},
+ 'CosPropertyService_PropertySetDef':
+ set_property_modes(Obj3,
+ [#'CosPropertyService_PropertyMode'{property_name = ?id3,
+ property_mode = read_only},
+ #'CosPropertyService_PropertyMode'{property_name = ?id4,
+ property_mode = read_only},
+ #'CosPropertyService_PropertyMode'{property_name = "wrongID",
+ property_mode = read_only}])),
+
+ ?match(normal, 'CosPropertyService_PropertySetDef':get_property_mode(Obj3, ?id3)),
+ ?match(normal, 'CosPropertyService_PropertySetDef':get_property_mode(Obj3, ?id4)),
+
+ corba:dispose(Obj3),
+
+ ?match(ok, cosProperty:stop_SetDefFactory(Fac)),
+
+ ok.
+
+
+
+%%-----------------------------------------------------------------
+%% CosPropertyService_PropertyNamesIterator API tests
+%%-----------------------------------------------------------------
+names_iterator_api(doc) -> ["CosPropertyService_PropertyNamesIterator API tests.",
+ ""];
+names_iterator_api(suite) -> [];
+names_iterator_api(_Config) ->
+ Fac = ?match({_,pseudo,_,_,_,_}, cosProperty:start_SetFactory()),
+ Obj = ?match({_,pseudo,_,_,_,_}, 'CosPropertyService_PropertySetFactory':
+ create_propertyset(Fac)),
+ ?match(ok, 'CosPropertyService_PropertySet':
+ define_properties(Obj, [#'CosPropertyService_Property'{property_name = ?id1,
+ property_value = ?val1},
+ #'CosPropertyService_Property'{property_name = ?id2,
+ property_value = ?val2},
+ #'CosPropertyService_Property'{property_name = ?id3,
+ property_value = ?val3}])),
+
+ ?match(3, 'CosPropertyService_PropertySetDef':get_number_of_properties(Obj)),
+ {_, _,ItObj} = ?match({ok, [], _}, 'CosPropertyService_PropertySetDef':get_all_property_names(Obj, 0)),
+ ?match({false, [_,_,_]}, 'CosPropertyService_PropertyNamesIterator':next_n(ItObj,3)),
+ ?match(ok, 'CosPropertyService_PropertyNamesIterator':reset(ItObj)),
+ ?match({false, [_,_,_]}, 'CosPropertyService_PropertyNamesIterator':next_n(ItObj,4)),
+ ?match(ok, 'CosPropertyService_PropertyNamesIterator':reset(ItObj)),
+ ?match({true, [_]}, 'CosPropertyService_PropertyNamesIterator':next_n(ItObj,1)),
+ ?match({true, _}, 'CosPropertyService_PropertyNamesIterator':next_one(ItObj)),
+ ?match({true, _}, 'CosPropertyService_PropertyNamesIterator':next_one(ItObj)),
+ ?match({false, _}, 'CosPropertyService_PropertyNamesIterator':next_one(ItObj)),
+ ?match(ok, 'CosPropertyService_PropertyNamesIterator':destroy(ItObj)),
+
+ corba:dispose(Obj),
+ ok.
+
+%%-----------------------------------------------------------------
+%% CosPropertyService_PropertiesIterator API tests
+%%-----------------------------------------------------------------
+properties_iterator_api(doc) -> ["CosPropertyService_PropertiesIterator API tests.",
+ ""];
+properties_iterator_api(suite) -> [];
+properties_iterator_api(_Config) ->
+ Fac = ?match({_,pseudo,_,_,_,_}, cosProperty:start_SetFactory()),
+ Obj = ?match({_,pseudo,_,_,_,_}, 'CosPropertyService_PropertySetFactory':
+ create_propertyset(Fac)),
+
+ ?match(ok, 'CosPropertyService_PropertySet':
+ define_properties(Obj, [#'CosPropertyService_Property'{property_name = ?id1,
+ property_value = ?val1},
+ #'CosPropertyService_Property'{property_name = ?id2,
+ property_value = ?val2},
+ #'CosPropertyService_Property'{property_name = ?id3,
+ property_value = ?val3}])),
+
+ ?match(3, 'CosPropertyService_PropertySetDef':get_number_of_properties(Obj)),
+ {_, _,ItObj} = ?match({ok, [], _},
+ 'CosPropertyService_PropertySetDef':get_all_properties(Obj, 0)),
+ ?match({false, [_,_,_]}, 'CosPropertyService_PropertiesIterator':next_n(ItObj,3)),
+ ?match(ok, 'CosPropertyService_PropertiesIterator':reset(ItObj)),
+ ?match({false, [_,_,_]}, 'CosPropertyService_PropertiesIterator':next_n(ItObj,4)),
+ ?match(ok, 'CosPropertyService_PropertiesIterator':reset(ItObj)),
+ ?match({true, [_]}, 'CosPropertyService_PropertiesIterator':next_n(ItObj,1)),
+ ?match({true, {'CosPropertyService_Property',_,_}},
+ 'CosPropertyService_PropertiesIterator':next_one(ItObj)),
+ ?match({true, {'CosPropertyService_Property',_,_}},
+ 'CosPropertyService_PropertiesIterator':next_one(ItObj)),
+ ?match({false, {'CosPropertyService_Property',_,_}},
+ 'CosPropertyService_PropertiesIterator':next_one(ItObj)),
+ ?match(ok, 'CosPropertyService_PropertiesIterator':destroy(ItObj)),
+ corba:dispose(Obj),
+ ok.
+
+
+%%-----------------------------------------------------------------
+%% END OF MODULE
+%%-----------------------------------------------------------------
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/test/Makefile b/lib/cosTime/test/Makefile
new file mode 100644
index 0000000000..fde5c4facc
--- /dev/null
+++ b/lib/cosTime/test/Makefile
@@ -0,0 +1,135 @@
+#
+# %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_TOP)/make/target.mk
+include $(ERL_TOP)/make/$(TARGET)/otp.mk
+
+# ----------------------------------------------------
+# Application version
+# ----------------------------------------------------
+include ../vsn.mk
+VSN=$(COSTIME_VSN)
+# ----------------------------------------------------
+# Release directory specification
+# ----------------------------------------------------
+RELSYSDIR = $(RELEASE_PATH)/cosTime_test
+
+# ----------------------------------------------------
+# Target Specs
+# ----------------------------------------------------
+TEST_SPEC_FILE = cosTime.spec
+
+
+IDL_FILES =
+
+IDLOUTDIR = idl_output
+
+MODULES = \
+ time_SUITE \
+ generated_SUITE
+
+GEN_MODULES = \
+
+GEN_HRL_FILES = \
+
+ERL_FILES = $(MODULES:%=%.erl)
+
+HRL_FILES =
+
+GEN_FILES = \
+ $(GEN_HRL_FILES:%=$(IDLOUTDIR)/%) \
+ $(GEN_MODULES:%=$(IDLOUTDIR)/%.erl)
+
+GEN_TARGET_FILES = $(GEN_MODULES:%=$(IDLOUTDIR)/%.$(EMULATOR))
+
+SUITE_TARGET_FILES = $(MODULES:%=%.$(EMULATOR))
+
+TARGET_FILES = \
+ $(GEN_TARGET_FILES) \
+ $(SUITE_TARGET_FILES)
+
+
+# ----------------------------------------------------
+# PROGRAMS
+# ----------------------------------------------------
+LOCAL_CLASSPATH = $(ERL_TOP)lib/cosTime/priv:$(ERL_TOP)lib/cosTime/test
+# ----------------------------------------------------
+# FLAGS
+# ----------------------------------------------------
+ERL_IDL_FLAGS += -pa $(ERL_TOP)/lib/cosTime/ebin \
+ -pa $(ERL_TOP)/lib/cosTime/src \
+ -pa $(ERL_TOP)/lib/cosTime/include \
+ -pa $(ERL_TOP)/lib/cosNotification/ebin \
+ -pa $(ERL_TOP)/lib/orber/ebin \
+ -pa $(ERL_TOP)/lib/ic/ebin
+
+ERL_COMPILE_FLAGS += \
+ $(ERL_IDL_FLAGS) \
+ -pa $(ERL_TOP)/lib/orber/include \
+ -pa $(ERL_TOP)/lib/cosNotification/include \
+ -pa $(ERL_TOP)/internal_tools/test_server/ebin \
+ -pa $(ERL_TOP)/lib/cosTime/ebin \
+ -pa $(ERL_TOP)/lib/cosTime/include \
+ -pa $(ERL_TOP)/lib/cosTime/test/idl_output \
+ -I$(ERL_TOP)/lib/orber/include \
+ -I$(ERL_TOP)/lib/cosNotification/include \
+ -I$(ERL_TOP)/lib/cosTime/src \
+ -I$(ERL_TOP)/lib/cosTime/include \
+ -I$(ERL_TOP)/lib/cosTime \
+ -I$(ERL_TOP)/lib/cosTime/test/$(IDLOUTDIR) \
+ -I$(ERL_TOP)/lib/test_server/include
+
+# ----------------------------------------------------
+# Targets
+# ----------------------------------------------------
+
+
+tests debug opt: $(TARGET_FILES)
+
+clean:
+ rm -f idl_output/*
+ rm -f $(TARGET_FILES)
+ rm -f errs core *~
+
+docs:
+
+# ----------------------------------------------------
+# Special Targets
+# ----------------------------------------------------
+
+# ----------------------------------------------------
+# Release Targets
+# ----------------------------------------------------
+# We don't copy generated intermediate erlang and hrl files
+
+include $(ERL_TOP)/make/otp_release_targets.mk
+
+release_spec:
+
+release_docs_spec:
+
+release_tests_spec: tests
+ $(INSTALL_DIR) $(RELSYSDIR)
+ $(INSTALL_DATA) $(IDL_FILES) $(TEST_SPEC_FILE) \
+ $(ERL_FILES) $(RELSYSDIR)
+ $(INSTALL_DATA) $(SUITE_TARGET_FILES) $(RELSYSDIR)
+# $(INSTALL_DIR) $(RELSYSDIR)/$(IDLOUTDIR)
+# $(INSTALL_DATA) $(GEN_TARGET_FILES) $(GEN_FILES) \
+# $(RELSYSDIR)/$(IDLOUTDIR)
+
diff --git a/lib/cosTime/test/cosTime.spec b/lib/cosTime/test/cosTime.spec
new file mode 100644
index 0000000000..3f50946043
--- /dev/null
+++ b/lib/cosTime/test/cosTime.spec
@@ -0,0 +1,19 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 2000-2010. All Rights Reserved.
+%%
+%% The contents of this file are subject to the Erlang Public License,
+%% Version 1.1, (the "License"); you may not use this file except in
+%% compliance with the License. You should have received a copy of the
+%% Erlang Public License along with this software. If not, it can be
+%% retrieved online at http://www.erlang.org/.
+%%
+%% Software distributed under the License is distributed on an "AS IS"
+%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+%% the License for the specific language governing rights and limitations
+%% under the License.
+%%
+%% %CopyrightEnd%
+%%
+{topcase, {dir, "../cosTime_test"}}.
diff --git a/lib/cosTime/test/generated_SUITE.erl b/lib/cosTime/test/generated_SUITE.erl
new file mode 100644
index 0000000000..3a2153528f
--- /dev/null
+++ b/lib/cosTime/test/generated_SUITE.erl
@@ -0,0 +1,288 @@
+%%-----------------------------------------------------------------
+%%
+%% %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%
+%%
+%%
+%%-----------------------------------------------------------------
+%% File : generated_SUITE.erl
+%% Purpose :
+%%-----------------------------------------------------------------
+
+-module(generated_SUITE).
+
+-include("test_server.hrl").
+-include_lib("orber/include/corba.hrl").
+
+-define(default_timeout, ?t:minutes(3)).
+
+-define(match(ExpectedRes, Expr),
+ fun() ->
+ AcTuAlReS = (catch (Expr)),
+ case AcTuAlReS of
+ ExpectedRes ->
+ AcTuAlReS;
+ _ ->
+ io:format("###### ERROR ERROR ######~n~p~n",
+ [AcTuAlReS]),
+ ?line exit(AcTuAlReS)
+ end
+ end()).
+
+-define(nomatch(Not, Expr),
+ fun() ->
+ AcTuAlReS = (catch (Expr)),
+ case AcTuAlReS of
+ Not ->
+ io:format("###### ERROR ERROR ######~n~p~n",
+ [AcTuAlReS]),
+ ?line exit(AcTuAlReS);
+ _ ->
+ AcTuAlReS
+ end
+ end()).
+
+
+-define(checktc(_Op),
+ fun(TC) ->
+ case orber_tc:check_tc(TC) of
+ false ->
+ io:format("###### ERROR ERROR ######~n~p - ~p~n", [Op, TC]),
+ ?line exit(TC);
+ true ->
+ true
+ end
+ end).
+
+%%-----------------------------------------------------------------
+%% External exports
+%%-----------------------------------------------------------------
+-export([all/1]).
+
+%%-----------------------------------------------------------------
+%% Internal exports
+%%-----------------------------------------------------------------
+-export([]).
+-compile(export_all).
+
+%%-----------------------------------------------------------------
+%% Func: all/1
+%% Args:
+%% Returns:
+%%-----------------------------------------------------------------
+all(doc) -> ["This suite is for testing IC generated files"];
+all(suite) ->
+ ['TimeBase_IntervalT', 'TimeBase_UtcT', 'CosTime_TimeUnavailable',
+ 'CosTimerEvent_TimerEventT', 'CosTime_TIO', 'CosTime_TimeService',
+ 'CosTime_UTO', 'CosTimerEvent_TimerEventHandler',
+ 'CosTimerEvent_TimerEventService'].
+
+%%-----------------------------------------------------------------
+%% Init and cleanup functions.
+%%-----------------------------------------------------------------
+init_per_testcase(_Case, Config) ->
+ ?line Dog=test_server:timetrap(?default_timeout),
+ [{watchdog, Dog}|Config].
+
+
+fin_per_testcase(_Case, Config) ->
+ Dog = ?config(watchdog, Config),
+ test_server:timetrap_cancel(Dog),
+ ok.
+
+%%-----------------------------------------------------------------
+%% Test Case: 'TimeBase_IntervalT'
+%% Description:
+%%-----------------------------------------------------------------
+'TimeBase_IntervalT'(doc) -> ["TimeBase_IntervalT"];
+'TimeBase_IntervalT'(suite) -> [];
+'TimeBase_IntervalT'(_) ->
+ ?match(true, orber_tc:check_tc('TimeBase_IntervalT':tc())),
+ ?match("IDL:omg.org/TimeBase/IntervalT:1.0",
+ 'TimeBase_IntervalT':id()),
+ ?match("TimeBase_IntervalT",
+ 'TimeBase_IntervalT':name()),
+ ok.
+
+
+%%-----------------------------------------------------------------
+%% Test Case: 'TimeBase_UtcT'
+%% Description:
+%%-----------------------------------------------------------------
+'TimeBase_UtcT'(doc) -> ["TimeBase_UtcT"];
+'TimeBase_UtcT'(suite) -> [];
+'TimeBase_UtcT'(_) ->
+ ?match(true, orber_tc:check_tc('TimeBase_UtcT':tc())),
+ ?match("IDL:omg.org/TimeBase/UtcT:1.0",
+ 'TimeBase_UtcT':id()),
+ ?match("TimeBase_UtcT",
+ 'TimeBase_UtcT':name()),
+ ok.
+
+
+%%-----------------------------------------------------------------
+%% Test Case: 'CosTime_TimeUnavailable'
+%% Description:
+%%-----------------------------------------------------------------
+'CosTime_TimeUnavailable'(doc) -> ["CosTime_TimeUnavailable"];
+'CosTime_TimeUnavailable'(suite) -> [];
+'CosTime_TimeUnavailable'(_) ->
+ ?match(true, orber_tc:check_tc('CosTime_TimeUnavailable':tc())),
+ ?match("IDL:omg.org/CosTime/TimeUnavailable:1.0",
+ 'CosTime_TimeUnavailable':id()),
+ ?match("CosTime_TimeUnavailable",
+ 'CosTime_TimeUnavailable':name()),
+ ok.
+
+
+%%-----------------------------------------------------------------
+%% Test Case: 'CosTimerEvent_TimerEventT'
+%% Description:
+%%-----------------------------------------------------------------
+'CosTimerEvent_TimerEventT'(doc) -> ["CosTimerEvent_TimerEventT"];
+'CosTimerEvent_TimerEventT'(suite) -> [];
+'CosTimerEvent_TimerEventT'(_) ->
+ ?match(true, orber_tc:check_tc('CosTimerEvent_TimerEventT':tc())),
+ ?match("IDL:omg.org/CosTimerEvent/TimerEventT:1.0",
+ 'CosTimerEvent_TimerEventT':id()),
+ ?match("CosTimerEvent_TimerEventT",
+ 'CosTimerEvent_TimerEventT':name()),
+ ok.
+
+
+%%-----------------------------------------------------------------
+%% Test Case: 'CosTime_TIO'
+%% Description:
+%%-----------------------------------------------------------------
+'CosTime_TIO'(doc) -> ["CosTime_TIO"];
+'CosTime_TIO'(suite) -> [];
+'CosTime_TIO'(_) ->
+ ?nomatch(undefined, 'CosTime_TIO':oe_tc('_get_time_interval')),
+ ?nomatch(undefined, 'CosTime_TIO':oe_tc(spans)),
+ ?nomatch(undefined, 'CosTime_TIO':oe_tc(overlaps)),
+ ?nomatch(undefined, 'CosTime_TIO':oe_tc(time)),
+ ?match(undefined, 'CosTime_TIO':oe_tc(undefined)),
+ ?match([_|_], 'CosTime_TIO':oe_get_interface()),
+ ?match("IDL:omg.org/CosTime/TIO:1.0", 'CosTime_TIO':typeID()),
+ check_tc('CosTime_TIO':oe_get_interface()),
+ ?match(true, 'CosTime_TIO':oe_is_a('CosTime_TIO':typeID())),
+ ?match(false, 'CosTime_TIO':oe_is_a("wrong")),
+ ok.
+
+
+%%-----------------------------------------------------------------
+%% Test Case: 'CosTime_TimeService'
+%% Description:
+%%-----------------------------------------------------------------
+'CosTime_TimeService'(doc) -> ["CosTime_TimeService"];
+'CosTime_TimeService'(suite) -> [];
+'CosTime_TimeService'(_) ->
+ ?nomatch(undefined, 'CosTime_TimeService':oe_tc(universal_time)),
+ ?nomatch(undefined, 'CosTime_TimeService':oe_tc(secure_universal_time)),
+ ?nomatch(undefined, 'CosTime_TimeService':oe_tc(new_universal_time)),
+ ?nomatch(undefined, 'CosTime_TimeService':oe_tc(uto_from_utc)),
+ ?nomatch(undefined, 'CosTime_TimeService':oe_tc(new_interval)),
+ ?match(undefined, 'CosTime_TimeService':oe_tc(undefined)),
+ ?match([_|_], 'CosTime_TimeService':oe_get_interface()),
+ ?match("IDL:omg.org/CosTime/TimeService:1.0",
+ 'CosTime_TimeService':typeID()),
+ check_tc('CosTime_TimeService':oe_get_interface()),
+ ?match(true, 'CosTime_TimeService':oe_is_a('CosTime_TimeService':typeID())),
+ ?match(false, 'CosTime_TimeService':oe_is_a("wrong")),
+ ok.
+
+
+%%-----------------------------------------------------------------
+%% Test Case: 'CosTime_UTO'
+%% Description:
+%%-----------------------------------------------------------------
+'CosTime_UTO'(doc) -> ["CosTime_UTO"];
+'CosTime_UTO'(suite) -> [];
+'CosTime_UTO'(_) ->
+ ?nomatch(undefined, 'CosTime_UTO':oe_tc('_get_time')),
+ ?nomatch(undefined, 'CosTime_UTO':oe_tc('_get_inaccuracy')),
+ ?nomatch(undefined, 'CosTime_UTO':oe_tc('_get_tdf')),
+ ?nomatch(undefined, 'CosTime_UTO':oe_tc('_get_utc_time')),
+ ?nomatch(undefined, 'CosTime_UTO':oe_tc(absolute_time)),
+ ?nomatch(undefined, 'CosTime_UTO':oe_tc(compare_time)),
+ ?nomatch(undefined, 'CosTime_UTO':oe_tc(time_to_interval)),
+ ?nomatch(undefined, 'CosTime_UTO':oe_tc(interval)),
+ ?match(undefined, 'CosTime_UTO':oe_tc(undefined)),
+ ?match([_|_], 'CosTime_UTO':oe_get_interface()),
+ ?match("IDL:omg.org/CosTime/UTO:1.0", 'CosTime_UTO':typeID()),
+ check_tc('CosTime_UTO':oe_get_interface()),
+ ?match(true, 'CosTime_UTO':oe_is_a('CosTime_UTO':typeID())),
+ ?match(false, 'CosTime_UTO':oe_is_a("wrong")),
+ ok.
+
+
+%%-----------------------------------------------------------------
+%% Test Case: 'CosTimerEvent_TimerEventHandler'
+%% Description:
+%%-----------------------------------------------------------------
+'CosTimerEvent_TimerEventHandler'(doc) -> ["CosTimerEvent_TimerEventHandler"];
+'CosTimerEvent_TimerEventHandler'(suite) -> [];
+'CosTimerEvent_TimerEventHandler'(_) ->
+ ?nomatch(undefined, 'CosTimerEvent_TimerEventHandler':oe_tc('_get_status')),
+ ?nomatch(undefined, 'CosTimerEvent_TimerEventHandler':oe_tc(time_set)),
+ ?nomatch(undefined, 'CosTimerEvent_TimerEventHandler':oe_tc(set_timer)),
+ ?nomatch(undefined, 'CosTimerEvent_TimerEventHandler':oe_tc(cancel_timer)),
+ ?nomatch(undefined, 'CosTimerEvent_TimerEventHandler':oe_tc(set_data)),
+ ?match(undefined, 'CosTimerEvent_TimerEventHandler':oe_tc(undefined)),
+ ?match([_|_], 'CosTimerEvent_TimerEventHandler':oe_get_interface()),
+ ?match("IDL:omg.org/CosTimerEvent/TimerEventHandler:1.0",
+ 'CosTimerEvent_TimerEventHandler':typeID()),
+ check_tc('CosTimerEvent_TimerEventHandler':oe_get_interface()),
+ ?match(true, 'CosTimerEvent_TimerEventHandler':oe_is_a('CosTimerEvent_TimerEventHandler':typeID())),
+ ?match(false, 'CosTimerEvent_TimerEventHandler':oe_is_a("wrong")),
+ ok.
+
+
+%%-----------------------------------------------------------------
+%% Test Case: 'CosTimerEvent_TimerEventService'
+%% Description:
+%%-----------------------------------------------------------------
+'CosTimerEvent_TimerEventService'(doc) -> ["CosTimerEvent_TimerEventService"];
+'CosTimerEvent_TimerEventService'(suite) -> [];
+'CosTimerEvent_TimerEventService'(_) ->
+ ?nomatch(undefined, 'CosTimerEvent_TimerEventService':oe_tc(register)),
+ ?nomatch(undefined, 'CosTimerEvent_TimerEventService':oe_tc(unregister)),
+ ?nomatch(undefined, 'CosTimerEvent_TimerEventService':oe_tc(event_time)),
+ ?match(undefined, 'CosTimerEvent_TimerEventService':oe_tc(undefined)),
+ ?match([_|_], 'CosTimerEvent_TimerEventService':oe_get_interface()),
+ ?match("IDL:omg.org/CosTimerEvent/TimerEventService:1.0",
+ 'CosTimerEvent_TimerEventService':typeID()),
+ check_tc('CosTimerEvent_TimerEventService':oe_get_interface()),
+ ?match(true, 'CosTimerEvent_TimerEventService':oe_is_a('CosTimerEvent_TimerEventService':typeID())),
+ ?match(false, 'CosTimerEvent_TimerEventService':oe_is_a("wrong")),
+ ok.
+
+
+
+
+%%-----------------------------------------------------------------
+%% MISC functions
+%%-----------------------------------------------------------------
+check_tc([]) ->
+ ok;
+check_tc([{Op, {RetType, InParameters, OutParameters}}|T]) ->
+ io:format("checked - ~s~n", [Op]),
+ lists:all(?checktc(Op), [RetType|InParameters]),
+ lists:all(?checktc(Op), OutParameters),
+ check_tc(T).
+
+
diff --git a/lib/cosTime/test/time_SUITE.erl b/lib/cosTime/test/time_SUITE.erl
new file mode 100644
index 0000000000..bb00395885
--- /dev/null
+++ b/lib/cosTime/test/time_SUITE.erl
@@ -0,0 +1,295 @@
+%%--------------------------------------------------------------------
+%%
+%% %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%
+%%
+%%
+%%----------------------------------------------------------------------
+%% File : time_SUITE.erl
+%% Purpose :
+%%----------------------------------------------------------------------
+
+-module(time_SUITE).
+
+
+%%--------------- INCLUDES -----------------------------------
+-include("../src/cosTimeApp.hrl").
+
+-include("test_server.hrl").
+
+%%--------------- DEFINES ------------------------------------
+-define(default_timeout, ?t:minutes(20)).
+-define(match(ExpectedRes, Expr),
+ fun() ->
+ AcTuAlReS = (catch (Expr)),
+ case AcTuAlReS of
+ ExpectedRes ->
+ io:format("------ CORRECT RESULT ------~n~p~n",
+ [AcTuAlReS]),
+ AcTuAlReS;
+ _ ->
+ io:format("###### ERROR ERROR ######~n~p~n",
+ [AcTuAlReS]),
+ exit(AcTuAlReS)
+ end
+ end()).
+
+-define(match_inverse(NotExpectedRes, Expr),
+ fun() ->
+ AcTuAlReS = (catch (Expr)),
+ case AcTuAlReS of
+ NotExpectedRes ->
+ io:format("###### ERROR ERROR ######~n ~p~n",
+ [AcTuAlReS]),
+ exit(AcTuAlReS);
+ _ ->
+ io:format("------ CORRECT RESULT ------~n~p~n",
+ [AcTuAlReS]),
+ AcTuAlReS
+ end
+ end()).
+
+
+%%-----------------------------------------------------------------
+%% External exports
+%%-----------------------------------------------------------------
+-export([all/1, cases/0, init_all/1, finish_all/1, time_api/1, timerevent_api/1,
+ init_per_testcase/2, fin_per_testcase/2,
+ app_test/1]).
+
+%%-----------------------------------------------------------------
+%% Func: all/1
+%% Args:
+%% Returns:
+%%-----------------------------------------------------------------
+all(doc) -> ["API tests for the cosTime interfaces", ""];
+all(suite) -> {req,
+ [mnesia, orber],
+ {conf, init_all, cases(), finish_all}}.
+
+cases() ->
+ [time_api, timerevent_api, app_test].
+
+
+
+%%-----------------------------------------------------------------
+%% Init and cleanup functions.
+%%-----------------------------------------------------------------
+
+init_per_testcase(_Case, Config) ->
+ Path = code:which(?MODULE),
+ code:add_pathz(filename:join(filename:dirname(Path), "idl_output")),
+ ?line Dog=test_server:timetrap(?default_timeout),
+ [{watchdog, Dog}|Config].
+
+
+fin_per_testcase(_Case, Config) ->
+ Path = code:which(?MODULE),
+ code:del_path(filename:join(filename:dirname(Path), "idl_output")),
+ Dog = ?config(watchdog, Config),
+ test_server:timetrap_cancel(Dog),
+ ok.
+
+init_all(Config) ->
+ Path = code:which(?MODULE),
+ code:add_pathz(filename:join(filename:dirname(Path), "idl_output")),
+ mnesia:delete_schema([node()]),
+ mnesia:create_schema([node()]),
+ orber:install([node()]),
+ application:start(mnesia),
+ application:start(orber),
+ cosNotificationApp:install_event(),
+ cosNotificationApp:install(),
+ cosTime:install_time(),
+ cosTime:install_timerevent(),
+ if
+ is_list(Config) ->
+ Config;
+ true ->
+ exit("Config not a list")
+ end.
+
+finish_all(Config) ->
+ Path = code:which(?MODULE),
+ code:del_path(filename:join(filename:dirname(Path), "idl_output")),
+ cosTime:uninstall_time(),
+ cosTime:uninstall_timerevent(),
+ cosNotificationApp:uninstall(),
+ cosNotificationApp:uninstall_event(),
+ application:stop(orber),
+ application:stop(mnesia),
+ mnesia:delete_schema([node()]),
+ Config.
+
+%%-----------------------------------------------------------------
+%% Tests app file
+%%-----------------------------------------------------------------
+app_test(doc) -> [];
+app_test(suite) -> [];
+app_test(_Config) ->
+ ok=test_server:app_test(cosTime),
+ ok.
+
+%%-----------------------------------------------------------------
+%% CosTime API tests
+%%-----------------------------------------------------------------
+time_api(doc) -> ["CosTime API tests.", ""];
+time_api(suite) -> [];
+time_api(_Config) ->
+ ?line ?match(ok, application:start(cosTime)),
+ TS=cosTime:start_time_service(0, 500),
+ Time=calendar:datetime_to_gregorian_seconds({{1582,1,1},{0,0,0}}),
+ Inaccuracy = 1000,
+ Tdf =1,
+ Utc = #'TimeBase_UtcT'{time=Time, inacclo = ?low_TimeT(Inaccuracy),
+ inacchi = ?high_TimeT(Inaccuracy), tdf = Tdf},
+ ?line UTO1='CosTime_TimeService':new_universal_time(TS, Time, Inaccuracy, Tdf),
+ ?line UTO2='CosTime_TimeService':uto_from_utc(TS, Utc),
+ ?line ?match(Time, 'CosTime_UTO':'_get_time'(UTO1)),
+ ?line ?match(Inaccuracy, 'CosTime_UTO':'_get_inaccuracy'(UTO1)),
+ ?line ?match(Tdf, 'CosTime_UTO':'_get_tdf'(UTO1)),
+ ?line ?match(Utc, 'CosTime_UTO':'_get_utc_time'(UTO1)),
+
+ ?line ?match(Time, 'CosTime_UTO':'_get_time'(UTO2)),
+ ?line ?match(Inaccuracy, 'CosTime_UTO':'_get_inaccuracy'(UTO2)),
+ ?line ?match(Tdf, 'CosTime_UTO':'_get_tdf'(UTO2)),
+ ?line ?match(Utc, 'CosTime_UTO':'_get_utc_time'(UTO2)),
+
+ TIO1='CosTime_TimeService':new_interval(TS, 2, 5),
+ _TIO2='CosTime_TimeService':new_interval(TS, 3, 6),
+ TIO3='CosTime_TimeService':new_interval(TS, 1, 3),
+ TIO4='CosTime_TimeService':new_interval(TS, 3, 4),
+ TIO5='CosTime_TimeService':new_interval(TS, 7, 8),
+ TIO6='CosTime_TimeService':new_interval(TS, 2, 6),
+ TIO7='CosTime_TimeService':new_interval(TS, 3, 7),
+
+ ?line {_,TIO8} = ?match({'OTContained', _}, 'CosTime_TIO':overlaps(TIO1, TIO6)),
+ ?line {_,TIO9} = ?match({'OTContainer', _}, 'CosTime_TIO':overlaps(TIO1, TIO1)),
+ ?line {_,TIO10} = ?match({'OTContainer', _}, 'CosTime_TIO':overlaps(TIO1, TIO4)),
+ ?line {_,TIO11} = ?match({'OTOverlap', _}, 'CosTime_TIO':overlaps(TIO1, TIO3)),
+ ?line {_,TIO12} = ?match({'OTOverlap', _}, 'CosTime_TIO':overlaps(TIO1, TIO7)),
+ ?line {_,TIO13} = ?match({'OTNoOverlap', _}, 'CosTime_TIO':overlaps(TIO1, TIO5)),
+
+ ?line ?match({'TimeBase_IntervalT',2,5},'CosTime_TIO':'_get_time_interval'(TIO8)),
+ ?line ?match({'TimeBase_IntervalT',2,5},'CosTime_TIO':'_get_time_interval'(TIO9)),
+ ?line ?match({'TimeBase_IntervalT',3,4},'CosTime_TIO':'_get_time_interval'(TIO10)),
+ ?line ?match({'TimeBase_IntervalT',2,3},'CosTime_TIO':'_get_time_interval'(TIO11)),
+ ?line ?match({'TimeBase_IntervalT',3,5},'CosTime_TIO':'_get_time_interval'(TIO12)),
+ ?line ?match({'TimeBase_IntervalT',5,7},'CosTime_TIO':'_get_time_interval'(TIO13)),
+
+ ?line UTO3='CosTime_TimeService':new_universal_time(TS, 4, 2, 0), %% 2-6
+ ?line UTO4='CosTime_TimeService':new_universal_time(TS, 2, 1, 0), %% 1-3
+ ?line UTO5='CosTime_TimeService':new_universal_time(TS, 3, 0, 0), %% 3-3
+ ?line UTO6='CosTime_TimeService':new_universal_time(TS, 9, 1, 0), %% 8-10
+ ?line UTO7='CosTime_TimeService':new_universal_time(TS, 4, 3, 0), %% 1-7
+ ?line UTO8='CosTime_TimeService':new_universal_time(TS, 5, 2, 0), %% 3-7
+
+ ?line {_,TIO14} = ?match({'OTContained', _}, 'CosTime_TIO':spans(TIO1, UTO7)),
+ ?line {_,TIO15} = ?match({'OTContainer', _}, 'CosTime_TIO':spans(TIO1, UTO5)),
+ ?line {_,TIO16} = ?match({'OTOverlap', _}, 'CosTime_TIO':spans(TIO1, UTO4)),
+ ?line {_,TIO17} = ?match({'OTOverlap', _}, 'CosTime_TIO':spans(TIO1, UTO8)),
+ ?line {_,TIO18} = ?match({'OTNoOverlap', _}, 'CosTime_TIO':spans(TIO1, UTO6)),
+ ?line {_,TIO19} = ?match({'OTContained', _}, 'CosTime_TIO':spans(TIO1, UTO3)),
+
+ ?line ?match({'TimeBase_IntervalT',2,5},'CosTime_TIO':'_get_time_interval'(TIO14)),
+ ?line ?match({'TimeBase_IntervalT',3,3},'CosTime_TIO':'_get_time_interval'(TIO15)),
+ ?line ?match({'TimeBase_IntervalT',2,3},'CosTime_TIO':'_get_time_interval'(TIO16)),
+ ?line ?match({'TimeBase_IntervalT',3,5},'CosTime_TIO':'_get_time_interval'(TIO17)),
+ ?line ?match({'TimeBase_IntervalT',5,8},'CosTime_TIO':'_get_time_interval'(TIO18)),
+ ?line ?match({'TimeBase_IntervalT',2,5},'CosTime_TIO':'_get_time_interval'(TIO19)),
+
+
+ cosTime:stop_time_service(TS),
+ application:stop(cosTime),
+ ok.
+
+
+%%-----------------------------------------------------------------
+%% CosTimerEvent API tests
+%%-----------------------------------------------------------------
+timerevent_api(doc) -> ["CosTimerEvent API tests.", ""];
+timerevent_api(suite) -> [];
+timerevent_api(_Config) ->
+ %% Init cosTime apps.
+ ?line ?match(ok, application:start(cosTime)),
+ ?line TS=cosTime:start_time_service(0, 500),
+ ?line TES=cosTime:start_timerevent_service(TS),
+
+ %%----- Initialize the cosNotification application. -----
+ ?line cosNotificationApp:start(),
+ ?line Fac = (catch cosNotificationApp:start_factory([])),
+ ?line {Ch, _Id1} = (catch 'CosNotifyChannelAdmin_EventChannelFactory':create_channel(Fac, [], [])),
+ %% Create the Admin objects
+ ?line {AdminSupplier, _ASID}= ?match({{_,key,_,_,_,_},_},
+ 'CosNotifyChannelAdmin_EventChannel':new_for_suppliers(Ch,'OR_OP')),
+ ?line {AdminConsumer, _ACID}= ?match({{_,key,_,_,_,_},_},
+ 'CosNotifyChannelAdmin_EventChannel':new_for_consumers(Ch,'OR_OP')),
+
+ %% Create a push consumer TimerEventService will push events to.
+ ?line {ProxyPushConsumer,_ID10}= ?match({{_,key,_,_,_,_},_},
+ 'CosNotifyChannelAdmin_SupplierAdmin':obtain_notification_push_consumer(AdminSupplier, 'ANY_EVENT')),
+
+ %% Create a pull suppliers so we can check we actually got the event.
+ ?line {ProxyPullSupplier,_ID1} = ?match({{_,key,_,_,_,_},_},
+ 'CosNotifyChannelAdmin_ConsumerAdmin':obtain_notification_pull_supplier(AdminConsumer, 'ANY_EVENT')),
+
+ AnyEvent = any:create(orber_tc:long(), 100),
+ ?line UTO=?match({_,pseudo,_,_,_,_}, 'CosTime_TimeService':new_universal_time(TS, 10*10000000,1,1)),
+ ?line EH=?match({_,key,_,_,_,_}, 'CosTimerEvent_TimerEventService':register(TES, ProxyPushConsumer, AnyEvent)),
+
+ ?line ?match('ESTimeCleared','CosTimerEvent_TimerEventHandler':'_get_status'(EH)),
+ ?line ?match({false,_},'CosTimerEvent_TimerEventHandler':time_set(EH)),
+ ?line ?match(ok,'CosTimerEvent_TimerEventHandler':set_timer(EH, 'TTRelative', UTO)),
+ ?line ?match({true,_},'CosTimerEvent_TimerEventHandler':time_set(EH)),
+ ?line ?match('ESTimeSet','CosTimerEvent_TimerEventHandler':'_get_status'(EH)),
+
+ ?line ?match({{any,tk_null,null}, false},
+ 'CosNotifyChannelAdmin_ProxyPullSupplier':try_pull(ProxyPullSupplier)),
+
+ ?line ?match(AnyEvent, 'CosNotifyChannelAdmin_ProxyPullSupplier':pull(ProxyPullSupplier)),
+ ?line ?match('ESTriggered','CosTimerEvent_TimerEventHandler':'_get_status'(EH)),
+
+ %% It's allowed to send an UTO with time eq. to 0 if the server is TTRelative.
+ %% When TTAbsolute BAD_PARAM is raised.
+ ?line UTO2=?match({_,pseudo,_,_,_,_}, 'CosTime_TimeService':new_universal_time(TS, 0,1,1)),
+ ?line ?match({'EXCEPTION',_},'CosTimerEvent_TimerEventHandler':set_timer(EH, 'TTAbsolute', UTO2)),
+ ?line ?match(ok,'CosTimerEvent_TimerEventHandler':set_timer(EH, 'TTRelative', UTO2)),
+ ?line ?match(AnyEvent, 'CosNotifyChannelAdmin_ProxyPullSupplier':pull(ProxyPullSupplier)),
+
+ %% TTPeriodic is defined to be relative, i.e., we can use the tactic as above.
+ ?line ?match(ok,'CosTimerEvent_TimerEventHandler':set_timer(EH, 'TTPeriodic', UTO2)),
+
+ %% Sleep for UTO*2+4 secs. At this point the Timer should have delivered 2 events.
+ timer:sleep(24000),
+ %% Cancel the timer so no more events will be delivered.
+ ?line ?match(true,'CosTimerEvent_TimerEventHandler':cancel_timer(EH)),
+
+ ?line ?match({AnyEvent, true}, 'CosNotifyChannelAdmin_ProxyPullSupplier':try_pull(ProxyPullSupplier)),
+ ?line ?match({AnyEvent, true}, 'CosNotifyChannelAdmin_ProxyPullSupplier':try_pull(ProxyPullSupplier)),
+ ?line ?match({{any,tk_null,null}, false},
+ 'CosNotifyChannelAdmin_ProxyPullSupplier':try_pull(ProxyPullSupplier)),
+
+
+
+ %% Clean up.
+ cosNotificationApp:stop(),
+ cosTime:stop_timerevent_service(TES),
+ cosTime:stop_time_service(TS),
+ application:stop(cosTime),
+ ok.
+
+
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/test/Makefile b/lib/cosTransactions/test/Makefile
new file mode 100644
index 0000000000..8b1264d404
--- /dev/null
+++ b/lib/cosTransactions/test/Makefile
@@ -0,0 +1,150 @@
+#
+# %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 $(ERL_TOP)/make/target.mk
+include $(ERL_TOP)/make/$(TARGET)/otp.mk
+
+#ifeq ($(TYPE),debug)
+#ERL_COMPILE_FLAGS += -Ddebug -W
+#endif
+
+# ----------------------------------------------------
+# Application version
+# ----------------------------------------------------
+include ../vsn.mk
+VSN=$(COSTRANSACTIONS_VSN)
+# ----------------------------------------------------
+# Release directory specification
+# ----------------------------------------------------
+RELSYSDIR = $(RELEASE_PATH)/cosTransactions_test
+
+# ----------------------------------------------------
+# Target Specs
+# ----------------------------------------------------
+TEST_SPEC_FILE = cosTransactions.spec
+
+
+IDL_FILES = \
+ etrap_test.idl
+
+IDLOUTDIR = idl_output
+
+MODULES = \
+ transactions_SUITE \
+ etrap_test_server_impl \
+ etrap_test_lib \
+ generated_SUITE
+
+GEN_MODULES = \
+ oe_etrap_test \
+ etrap_test_server
+
+GEN_HRL_FILES = \
+ oe_etrap_test.hrl \
+ etrap_test_server.hrl
+
+ERL_FILES = $(MODULES:%=%.erl)
+
+HRL_FILES = \
+ etrap_test_lib.hrl
+
+GEN_FILES = \
+ $(GEN_HRL_FILES:%=$(IDLOUTDIR)/%) \
+ $(GEN_MODULES:%=$(IDLOUTDIR)/%.erl)
+
+GEN_TARGET_FILES = $(GEN_MODULES:%=$(IDLOUTDIR)/%.$(EMULATOR))
+
+SUITE_TARGET_FILES = $(MODULES:%=%.$(EMULATOR))
+
+TARGET_FILES = \
+ $(GEN_TARGET_FILES) \
+ $(SUITE_TARGET_FILES)
+
+
+# ----------------------------------------------------
+# PROGRAMS
+# ----------------------------------------------------
+LOCAL_CLASSPATH = $(ERL_TOP)/lib/cosTransactions/priv:$(ERL_TOP)/lib/cosTransactions/test
+# ----------------------------------------------------
+# FLAGS
+# ----------------------------------------------------
+ERL_IDL_FLAGS += -pa $(ERL_TOP)/lib/cosTransactions/ebin\
+ -pa $(ERL_TOP)/lib/orber/ebin \
+ -pa $(ERL_TOP)/lib/ic/ebin
+
+ERL_COMPILE_FLAGS += \
+ $(ERL_IDL_FLAGS) \
+ -pa $(ERL_TOP)/lib/orber/include \
+ -pa $(ERL_TOP)/lib/test_server/ebin \
+ -pa $(ERL_TOP)/lib/cosTransactions/ebin \
+ -pa $(ERL_TOP)/lib/cosTransactions/test/idl_output \
+ -I$(ERL_TOP)/lib/orber/include \
+ -I$(ERL_TOP)/lib/cosTransactions \
+ -I$(ERL_TOP)/lib/cosTransactions/test/$(IDLOUTDIR) \
+ -I$(ERL_TOP)/lib/test_server/include
+
+# ----------------------------------------------------
+# Targets
+# ----------------------------------------------------
+
+
+tests debug opt: $(TARGET_FILES)
+
+clean:
+ rm -f idl_output/*
+ rm -f $(TARGET_FILES)
+ rm -f errs core *~
+
+#debug:
+# @${MAKE} TYPE=debug
+
+docs:
+
+# ----------------------------------------------------
+# Special Targets
+# ----------------------------------------------------
+
+TGT_TEST = \
+ $(GEN_HRL_FILES:%=$(IDLOUTDIR)/%) \
+ $(GEN_MODULES:%=$(IDLOUTDIR)/%.erl)
+
+$(TGT_TEST): etrap_test.idl
+ erlc $(ERL_IDL_FLAGS) -o$(IDLOUTDIR) \
+ +'{cfgfile,"etrap_test.cfg"}' etrap_test.idl
+
+# ----------------------------------------------------
+# Release Targets
+# ----------------------------------------------------
+# We don't copy generated intermediate erlang and hrl files
+
+include $(ERL_TOP)/make/otp_release_targets.mk
+
+release_spec:
+
+release_docs_spec:
+
+release_tests_spec: tests
+ $(INSTALL_DIR) $(RELSYSDIR)
+ $(INSTALL_DATA) $(IDL_FILES) $(TEST_SPEC_FILE) \
+ $(ERL_FILES) $(HRL_FILES) $(RELSYSDIR)
+ $(INSTALL_DATA) $(SUITE_TARGET_FILES) $(RELSYSDIR)
+ $(INSTALL_DIR) $(RELSYSDIR)/$(IDLOUTDIR)
+ $(INSTALL_DATA) $(GEN_TARGET_FILES) $(GEN_FILES) \
+ $(RELSYSDIR)/$(IDLOUTDIR)
+
diff --git a/lib/cosTransactions/test/cosTransactions.spec b/lib/cosTransactions/test/cosTransactions.spec
new file mode 100644
index 0000000000..8ad9259964
--- /dev/null
+++ b/lib/cosTransactions/test/cosTransactions.spec
@@ -0,0 +1,19 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 1999-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%
+%%
+{topcase, {dir, "../cosTransactions_test"}}.
diff --git a/lib/cosTransactions/test/etrap_test.cfg b/lib/cosTransactions/test/etrap_test.cfg
new file mode 100644
index 0000000000..4f2b9e125d
--- /dev/null
+++ b/lib/cosTransactions/test/etrap_test.cfg
@@ -0,0 +1,20 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 1999-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%
+%%
+{this, "etrap_test::server"}.
+{{handle_info, "etrap_test::server"}, true}.
diff --git a/lib/cosTransactions/test/etrap_test.idl b/lib/cosTransactions/test/etrap_test.idl
new file mode 100644
index 0000000000..7573cc1a36
--- /dev/null
+++ b/lib/cosTransactions/test/etrap_test.idl
@@ -0,0 +1,38 @@
+//
+// %CopyrightBegin%
+//
+// Copyright Ericsson AB 1999-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%
+//
+
+#ifndef _TEST_IDL
+#define _TEST_IDL
+#include <../src/CosTransactions.idl>
+module etrap_test {
+
+ // interface server
+ interface server :
+ CosTransactions::Coordinator, CosTransactions::SubtransactionAwareResource,
+ CosTransactions::RecoveryCoordinator, CosTransactions::Control {
+ };
+// interface Server :
+// CosTransactions::Coordinator, CosTransactions::SubtransactionAwareResource,
+// CosTransactions::RecoveryCoordinator, CosTransactions::Control,
+// CosTransactions::Synchronization {
+// };
+
+}; // End of test Module
+
+#endif
diff --git a/lib/cosTransactions/test/etrap_test_lib.erl b/lib/cosTransactions/test/etrap_test_lib.erl
new file mode 100644
index 0000000000..913a94510f
--- /dev/null
+++ b/lib/cosTransactions/test/etrap_test_lib.erl
@@ -0,0 +1,125 @@
+%%
+%% %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(etrap_test_lib).
+
+%%--------------- INCLUDES ---------------------------------------------
+-include("etrap_test_lib.hrl").
+-include_lib("cosTransactions/src/ETraP_Common.hrl").
+
+%%--------------- EXPORTS ----------------------------------------------
+-export([scratch_debug_fun/0,
+ activate_debug_fun/5,
+ update_debug_info/1,
+ deactivate_debug_fun/3,
+ eval_debug_fun/4,
+ set_debug_context/4]).
+
+%%--------------- CONSTANTS/DEFINITIONS --------------------------------
+-define(DEBUG_TAB, etrap_debug).
+-record(debug_info, {id, function, type, file, line}).
+
+%%--------------- DEBUG FUNCTIONS --------------------------------------
+%% Managing conditional debug functions
+%%
+%% The main idea with the debug_fun's is to allow test programs
+%% to control the internal behaviour of CosTransactions.
+%%
+%% First should calls to ?eval_debug_fun be inserted at well
+%% defined places in CosTransaction's code. E.g. in critical situations
+%% of startup, transaction commit, backups etc.
+%%
+%% Then compile CosTransactions with the compiler option 'debug'.
+%%
+%% In test programs ?activate_debug_fun should be called
+%% in order to bind a fun to the debug identifier stated
+%% in the call to ?eval_debug_fun.
+
+scratch_debug_fun() ->
+ catch ets:delete(?DEBUG_TAB),
+ ets:new(?DEBUG_TAB,
+ [set, public, named_table, {keypos, 2}]).
+
+activate_debug_fun(FunId, Fun, Type, File, Line) ->
+ io:format("Activiating ~p RETRIES: ~p WAIT: ~p~n",
+ [FunId, ?tr_max_retries, ?tr_comm_failure_wait]),
+ Info = #debug_info{id = FunId,
+ function = Fun,
+ type = Type,
+ file = File,
+ line = Line},
+ update_debug_info(Info).
+
+update_debug_info(Info) ->
+ case catch ets:insert(?DEBUG_TAB, Info) of
+ {'EXIT', _} ->
+ scratch_debug_fun(),
+ ets:insert(?DEBUG_TAB, Info);
+ _ ->
+ ok
+ end,
+ ok.
+
+deactivate_debug_fun(FunId, _File, _Line) ->
+ catch ets:delete(?DEBUG_TAB, FunId),
+ ok.
+
+eval_debug_fun(FunId, Env, File, Line) ->
+ case catch ets:lookup(?DEBUG_TAB, FunId) of
+ [] ->
+ ok;
+ [Info] ->
+ Fun = Info#debug_info.function,
+ case Info#debug_info.type of
+ transient ->
+ deactivate_debug_fun(FunId, File, Line);
+ _->
+ ok
+ end,
+ io:format("Running debug fun ~p:~p (LINE: ~p)~n", [File, FunId, Line]),
+ Fun(Env);
+ {'EXIT', _R} ->
+ ok
+ end.
+
+
+set_debug_context([], [], _, _)-> ok;
+set_debug_context([], _, _, _)->
+ ets:delete(?DEBUG_TAB),
+ exit("failed transactions_SUITE. Bad configuration.");
+set_debug_context(_, [], _, _)->
+ ets:delete(?DEBUG_TAB),
+ exit("failed transactions_SUITE Bad configuration.");
+set_debug_context([RHead|RTail], [CHead|CTail], File, Line)->
+ write_context(RHead, CHead, File, Line),
+ set_debug_context(RTail, CTail, File, Line).
+
+write_context(_Resource, [], _, _)-> ok;
+write_context(Resource, [{Func, Fun, Type}|PTail], File, Line)->
+ etrap_test_lib:activate_debug_fun({Resource, Func},
+ Fun, Type,
+ File, Line),
+ write_context(Resource, PTail, File, Line);
+write_context(_,_, _, _) ->
+ ets:delete(?DEBUG_TAB),
+ exit("failed transactions_SUITE. Bad configuration.").
+
+
+%%--------------- END OF MODULE ----------------------------------------
diff --git a/lib/cosTransactions/test/etrap_test_lib.hrl b/lib/cosTransactions/test/etrap_test_lib.hrl
new file mode 100644
index 0000000000..d488bf9d12
--- /dev/null
+++ b/lib/cosTransactions/test/etrap_test_lib.hrl
@@ -0,0 +1,100 @@
+%%
+%% %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%
+%%
+%%
+
+-ifndef(ETRAP_TEST_LIB_HRL).
+-define(ETRAP_TEST_LIB_HRL, true).
+
+-define(match(ExpectedRes, Expr, Msg),
+ fun() ->
+ AcTuAlReS = (catch (Expr)),
+ case AcTuAlReS of
+ ExpectedRes ->
+ io:format("~n------ CORRECT RESULT ------~n~p~n~p~n",
+ [AcTuAlReS, Msg]),
+ ok;
+ _ ->
+ io:format("~n###### ERROR ERROR ######~n~p~n~p~n",
+ [AcTuAlReS, Msg]),
+ exit(AcTuAlReS)
+ end
+ end()).
+
+-define(match_inverse(NotExpectedRes, Expr, Msg),
+ fun() ->
+ AcTuAlReS = (catch (Expr)),
+ case AcTuAlReS of
+ NotExpectedRes ->
+ io:format("~n###### ERROR ERROR ######~n ~p~n~p~n",
+ [AcTuAlReS, Msg]),
+ exit(AcTuAlReS);
+ _ ->
+ io:format("~n------ CORRECT RESULT ------~n~p~n~p~n",
+ [AcTuAlReS, Msg]),
+ ok
+ end
+ end()).
+
+
+-define(crash_and_recover, fun(_Env)-> exit(crash_and_burn) end).
+
+-define(crash_no_recovery, fun(Env)-> throw({stop,normal,{Env,state}}) end).
+
+-define(delay(Time), fun(_Id) -> timer:sleep(Time*1000) end).
+
+-define(TIMEOUT, 4).
+-define(SUP_TEST(Env, Name),
+ ['etrap_test_server', Env,
+ [{sup_child, true}, {persistent, true},
+ {regname, {global, Name}}]]).
+
+-define(no_context, [[],[],[], []]).
+-define(nop, []).
+-define(delay_transient(Tag, Ti),
+ [{Tag, ?delay(Ti), transient}]).
+-define(crash_transient(Tag),
+ [{Tag, ?crash_and_recover, transient}]).
+-define(crash_permanent(Tag),
+ [{Tag, ?crash_no_recovery, permanent}]).
+
+%%-----------------------------------------------------------
+%% Definition of 'Resource' action.
+%% function action reply
+%%-----------------------------------------------------------
+%% raise #'CosTransactions_HeuristicMixed' {}
+-define(rollback_mix, [{rollback, exc, ?tr_mixed}]).
+-define(commit_mix, [{commit, exc, ?tr_mixed}]).
+-define(prepare_mix, [{prepare, exc, ?tr_mixed}]).
+%% raise #'CosTransactions_HeuristicRollback' {}
+-define(rollback_rb, [{rollback, exc, ?tr_rollback}]).
+-define(commit_rb, [{commit, exc, ?tr_rollback}]).
+%% raise #'CosTransactions_HeuristicCommit' {}
+-define(rollback_cm, [{rollback, exc, ?tr_commit}]).
+-define(commit_cm, [{commit, exc, ?tr_commit}]).
+%% delay reply
+-define(rollback_delay, [{rollback, delay, ?TIMEOUT*2}]).
+-define(commit_delay, [{commit, delay, ?TIMEOUT*2}]).
+-define(prepare_delay, [{prepare, delay, ?TIMEOUT*2}]).
+%% other reply than default
+-define(prepare_commit, [{prepare, reply, 'VoteCommit'}]).
+-define(prepare_rollback, [{prepare, stop_reply, 'VoteRollback'}]).
+
+-endif.
+
+%%-------------- EOF ---------------------------------------------------
diff --git a/lib/cosTransactions/test/etrap_test_server_impl.erl b/lib/cosTransactions/test/etrap_test_server_impl.erl
new file mode 100644
index 0000000000..69c823f3ca
--- /dev/null
+++ b/lib/cosTransactions/test/etrap_test_server_impl.erl
@@ -0,0 +1,210 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 1999-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(etrap_test_server_impl).
+
+%%--------------- INCLUDES -----------------------------------
+-include_lib("orber/include/corba.hrl").
+-include_lib("orber/include/ifr_types.hrl").
+%% Local
+-include_lib("cosTransactions/src/ETraP_Common.hrl").
+-include_lib("cosTransactions/include/CosTransactions.hrl").
+%%--------------- IMPORTS-------------------------------------
+%%--------------- EXPORTS-------------------------------------
+-export([prepare/2,
+ rollback/2,
+ commit/2,
+ commit_one_phase/2,
+ forget/2,
+% before_completion/2,
+% after_completion/3,
+ commit_subtransaction/3,
+ rollback_subtransaction/2]).
+
+
+%%--------------- gen_server specific ------------------------
+-export([init/1, terminate/2]).
+-export([handle_call/3, handle_cast/2, handle_info/2, code_change/3]).
+
+%%------------------------------------------------------------
+%% function : init, terminate
+%%------------------------------------------------------------
+init(State) ->
+ process_flag(trap_exit,true),
+ io:format("etrap_test_server:init ~p~n", [State]),
+ ?debug_print("STARTING etrap_test_server( ~p )~n", [State]),
+ {ok, State}.
+
+terminate(Reason, _State) ->
+ io:format("etrap_test_server:terminate ~p~n", [Reason]),
+ ?debug_print("STOPREASON etrap_test_server( ~p )~n", [Reason]),
+ ok.
+
+code_change(_OldVsn, State, _Extra) ->
+ {ok, State}.
+handle_call(_,_, State) ->
+ {noreply, State}.
+handle_cast(_, State) ->
+ {noreply, State}.
+handle_info(_Info, State) ->
+ {noreply, State}.
+
+%%-- Inherit from CosTransactions::SubtransactionAwareResource --
+prepare(_Self, State) ->
+ case ?is_debug_compiled of
+ true ->
+ io:format("etrap_test_server:prepare ~p~n", [State]);
+ _->
+ ok
+ end,
+% ?debug_print("etrap_test_server:prepare ~p~n", [State]),
+ action(prepare, State, {reply, 'VoteCommit', State}).
+
+rollback(_Self, State) ->
+ case ?is_debug_compiled of
+ true ->
+ io:format("etrap_test_server:rollback ~p~n", [State]);
+ _->
+ ok
+ end,
+% ?debug_print("etrap_test_server:rollback ~p~n", [State]),
+ case sync_test(State) of
+ true ->
+ action(rollback, State, {reply, ok, State});
+ _->
+ action(rollback, State, {stop, normal, ok, State})
+ end.
+
+commit(_Self, State) ->
+ case ?is_debug_compiled of
+ true ->
+ io:format("etrap_test_server:commit ~p~n", [State]);
+ _->
+ ok
+ end,
+% ?debug_print("etrap_test_server:commit ~p~n", [State]),
+ case sync_test(State) of
+ true ->
+ action(commit, State, {reply, ok, State});
+ _->
+ action(commit, State, {stop, normal, ok, State})
+ end.
+
+commit_one_phase(_Self, State) ->
+ case ?is_debug_compiled of
+ true ->
+ io:format("etrap_test_server:commit_one_phase ~p~n", [State]);
+ _->
+ ok
+ end,
+% ?debug_print("etrap_test_server:commit_one_phase ~p~n", [State]),
+ case sync_test(State) of
+ true ->
+ {reply, ok, State};
+ _->
+ {stop, normal, ok, State}
+ end.
+
+forget(_Self, State) ->
+ case ?is_debug_compiled of
+ true ->
+ io:format("etrap_test_server:forget ~p~n", [State]);
+ _->
+ ok
+ end,
+% ?debug_print("etrap_test_server:forget ~p~n", [State]),
+ case sync_test(State) of
+ true ->
+ {reply, ok, State};
+ _->
+ {stop, normal, ok, State}
+ end.
+
+commit_subtransaction(_Self, State, Parent) ->
+ case ?is_debug_compiled of
+ true ->
+ io:format("etrap_test_server:commit_subtransaction( ~p )~n", [Parent]);
+ _->
+ ok
+ end,
+% ?debug_print("etrap_test_server:commit_subtransaction( ~p )~n", [Parent]),
+ {reply, ok, State}.
+rollback_subtransaction(_Self, State) ->
+ case ?is_debug_compiled of
+ true ->
+ io:format("etrap_test_server:rollback_subtransaction()~n", []);
+ _->
+ ok
+ end,
+% ?debug_print("etrap_test_server:rollback_subtransaction()~n", []),
+ {reply, ok, State}.
+
+%before_completion(_Self, State) ->
+% case ?is_debug_compiled of
+% true ->
+% io:format("etrap_test_server:before_completion()~n", []);
+% _->
+% ok
+% end,
+%% ?debug_print("etrap_test_server:before_completion()~n", []),
+% {reply, ok, State}.
+%after_completion(_Self, State, Status) ->
+% case ?is_debug_compiled of
+% true ->
+% io:format("etrap_test_server:after_completion( ~p )~n", [Status]);
+% _->
+% ok
+% end,
+%% ?debug_print("etrap_test_server:after_completion( ~p )~n", [Status]),
+% {stop, normal, ok, State}.
+
+%%--------------- LOCAL FUNCTIONS ----------------------------
+action(Key, State, Default) ->
+ case catch lists:keysearch(Key, 1, State) of
+ {value,{Key, stop_reply, R}} ->
+ case sync_test(State) of
+ true ->
+ {reply, R, State};
+ _->
+ {stop, normal, R, State}
+ end;
+ {value,{Key, reply, R}} ->
+ {reply, R, State};
+ {value,{Key, exc, E}} ->
+ corba:raise(E);
+ {value,{Key, delay, Time}} ->
+ timer:sleep(Time*1000),
+ Default;
+ {value,{Key,Value}} ->
+ Value;
+ _ ->
+ Default
+ end.
+
+sync_test(State) ->
+ case catch lists:keysearch(sync, 1, State) of
+ {value,{sync, true}} ->
+ true;
+ _ ->
+ false
+ end.
+
+
+%%--------------- END OF MODULE ------------------------------
+
diff --git a/lib/cosTransactions/test/generated_SUITE.erl b/lib/cosTransactions/test/generated_SUITE.erl
new file mode 100644
index 0000000000..cc54eb168e
--- /dev/null
+++ b/lib/cosTransactions/test/generated_SUITE.erl
@@ -0,0 +1,564 @@
+%%-----------------------------------------------------------------
+%%
+%% %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%
+%%
+%%
+%%-----------------------------------------------------------------
+%% File : generated_SUITE.erl
+%% Purpose :
+%% Created : 27 Jan 2004
+%%-----------------------------------------------------------------
+
+-module(generated_SUITE).
+
+-include("test_server.hrl").
+-include_lib("orber/include/corba.hrl").
+
+-define(default_timeout, ?t:minutes(3)).
+
+-define(match(ExpectedRes, Expr),
+ fun() ->
+ AcTuAlReS = (catch (Expr)),
+ case AcTuAlReS of
+ ExpectedRes ->
+ AcTuAlReS;
+ _ ->
+ io:format("###### ERROR ERROR ######~n~p~n",
+ [AcTuAlReS]),
+ ?line exit(AcTuAlReS)
+ end
+ end()).
+
+-define(nomatch(Not, Expr),
+ fun() ->
+ AcTuAlReS = (catch (Expr)),
+ case AcTuAlReS of
+ Not ->
+ io:format("###### ERROR ERROR ######~n~p~n",
+ [AcTuAlReS]),
+ ?line exit(AcTuAlReS);
+ _ ->
+ AcTuAlReS
+ end
+ end()).
+
+
+-define(checktc(_Op),
+ fun(TC) ->
+ case orber_tc:check_tc(TC) of
+ false ->
+ io:format("###### ERROR ERROR ######~n~p - ~p~n", [Op, TC]),
+ ?line exit(TC);
+ true ->
+ true
+ end
+ end).
+
+%%-----------------------------------------------------------------
+%% External exports
+%%-----------------------------------------------------------------
+-export([all/1]).
+
+%%-----------------------------------------------------------------
+%% Internal exports
+%%-----------------------------------------------------------------
+-export([]).
+-compile(export_all).
+
+%%-----------------------------------------------------------------
+%% Func: all/1
+%% Args:
+%% Returns:
+%%-----------------------------------------------------------------
+all(doc) -> ["This suite is for testing IC generated files"];
+all(suite) ->
+ ['CosTransactions_Control', 'CosTransactions_Coordinator',
+ 'CosTransactions_HeuristicCommit', 'CosTransactions_HeuristicHazard',
+ 'CosTransactions_HeuristicMixed', 'CosTransactions_HeuristicRollback',
+ 'CosTransactions_Inactive', 'CosTransactions_InvalidControl',
+ 'CosTransactions_NoTransaction', 'CosTransactions_NotPrepared',
+ 'CosTransactions_NotSubtransaction', 'CosTransactions_RecoveryCoordinator',
+ 'CosTransactions_Resource', 'CosTransactions_SubtransactionAwareResource',
+ 'CosTransactions_SubtransactionsUnavailable', 'CosTransactions_Terminator',
+ 'CosTransactions_TransactionFactory', 'CosTransactions_Unavailable',
+ 'CosTransactions_SynchronizationUnavailable', 'CosTransactions_TransIdentity',
+ 'CosTransactions_PropagationContext', 'CosTransactions_otid_t',
+ 'CosTransactions_WrongTransaction', 'ETraP_Server'].
+
+%%-----------------------------------------------------------------
+%% Init and cleanup functions.
+%%-----------------------------------------------------------------
+init_per_testcase(_Case, Config) ->
+ ?line Dog=test_server:timetrap(?default_timeout),
+ [{watchdog, Dog}|Config].
+
+
+fin_per_testcase(_Case, Config) ->
+ Dog = ?config(watchdog, Config),
+ test_server:timetrap_cancel(Dog),
+ ok.
+
+
+%%-----------------------------------------------------------------
+%% Test Case: 'CosTransactions_HeuristicCommit'
+%% Description:
+%%-----------------------------------------------------------------
+'CosTransactions_HeuristicCommit'(doc) -> ["CosTransactions_HeuristicCommit"];
+'CosTransactions_HeuristicCommit'(suite) -> [];
+'CosTransactions_HeuristicCommit'(_) ->
+ ?match(true, orber_tc:check_tc('CosTransactions_HeuristicCommit':tc())),
+ ?match("IDL:omg.org/CosTransactions/HeuristicCommit:1.0",
+ 'CosTransactions_HeuristicCommit':id()),
+ ?match("CosTransactions_HeuristicCommit",
+ 'CosTransactions_HeuristicCommit':name()),
+ ok.
+
+
+%%-----------------------------------------------------------------
+%% Test Case: 'CosTransactions_HeuristicHazard'
+%% Description:
+%%-----------------------------------------------------------------
+'CosTransactions_HeuristicHazard'(doc) -> ["CosTransactions_HeuristicHazard"];
+'CosTransactions_HeuristicHazard'(suite) -> [];
+'CosTransactions_HeuristicHazard'(_) ->
+ ?match(true, orber_tc:check_tc('CosTransactions_HeuristicHazard':tc())),
+ ?match("IDL:omg.org/CosTransactions/HeuristicHazard:1.0",
+ 'CosTransactions_HeuristicHazard':id()),
+ ?match("CosTransactions_HeuristicHazard",
+ 'CosTransactions_HeuristicHazard':name()),
+ ok.
+
+
+%%-----------------------------------------------------------------
+%% Test Case: 'CosTransactions_HeuristicMixed'
+%% Description:
+%%-----------------------------------------------------------------
+'CosTransactions_HeuristicMixed'(doc) -> ["CosTransactions_HeuristicMixed"];
+'CosTransactions_HeuristicMixed'(suite) -> [];
+'CosTransactions_HeuristicMixed'(_) ->
+ ?match(true, orber_tc:check_tc('CosTransactions_HeuristicMixed':tc())),
+ ?match("IDL:omg.org/CosTransactions/HeuristicMixed:1.0",
+ 'CosTransactions_HeuristicMixed':id()),
+ ?match("CosTransactions_HeuristicMixed",
+ 'CosTransactions_HeuristicMixed':name()),
+ ok.
+
+
+%%-----------------------------------------------------------------
+%% Test Case: 'CosTransactions_HeuristicRollback'
+%% Description:
+%%-----------------------------------------------------------------
+'CosTransactions_HeuristicRollback'(doc) -> ["CosTransactions_HeuristicRollback"];
+'CosTransactions_HeuristicRollback'(suite) -> [];
+'CosTransactions_HeuristicRollback'(_) ->
+ ?match(true, orber_tc:check_tc('CosTransactions_HeuristicRollback':tc())),
+ ?match("IDL:omg.org/CosTransactions/HeuristicRollback:1.0",
+ 'CosTransactions_HeuristicRollback':id()),
+ ?match("CosTransactions_HeuristicRollback",
+ 'CosTransactions_HeuristicRollback':name()),
+ ok.
+
+
+%%-----------------------------------------------------------------
+%% Test Case: 'CosTransactions_Inactive'
+%% Description:
+%%-----------------------------------------------------------------
+'CosTransactions_Inactive'(doc) -> ["CosTransactions_Inactive"];
+'CosTransactions_Inactive'(suite) -> [];
+'CosTransactions_Inactive'(_) ->
+ ?match(true, orber_tc:check_tc('CosTransactions_Inactive':tc())),
+ ?match("IDL:omg.org/CosTransactions/Inactive:1.0",
+ 'CosTransactions_Inactive':id()),
+ ?match("CosTransactions_Inactive",
+ 'CosTransactions_Inactive':name()),
+ ok.
+
+
+%%-----------------------------------------------------------------
+%% Test Case: 'CosTransactions_InvalidControl'
+%% Description:
+%%-----------------------------------------------------------------
+'CosTransactions_InvalidControl'(doc) -> ["CosTransactions_InvalidControl"];
+'CosTransactions_InvalidControl'(suite) -> [];
+'CosTransactions_InvalidControl'(_) ->
+ ?match(true, orber_tc:check_tc('CosTransactions_InvalidControl':tc())),
+ ?match("IDL:omg.org/CosTransactions/InvalidControl:1.0",
+ 'CosTransactions_InvalidControl':id()),
+ ?match("CosTransactions_InvalidControl",
+ 'CosTransactions_InvalidControl':name()),
+ ok.
+
+
+%%-----------------------------------------------------------------
+%% Test Case: 'CosTransactions_NoTransaction'
+%% Description:
+%%-----------------------------------------------------------------
+'CosTransactions_NoTransaction'(doc) -> ["CosTransactions_NoTransaction"];
+'CosTransactions_NoTransaction'(suite) -> [];
+'CosTransactions_NoTransaction'(_) ->
+ ?match(true, orber_tc:check_tc('CosTransactions_NoTransaction':tc())),
+ ?match("IDL:omg.org/CosTransactions/NoTransaction:1.0",
+ 'CosTransactions_NoTransaction':id()),
+ ?match("CosTransactions_NoTransaction",
+ 'CosTransactions_NoTransaction':name()),
+ ok.
+
+
+%%-----------------------------------------------------------------
+%% Test Case: 'CosTransactions_NotPrepared'
+%% Description:
+%%-----------------------------------------------------------------
+'CosTransactions_NotPrepared'(doc) -> ["CosTransactions_NotPrepared"];
+'CosTransactions_NotPrepared'(suite) -> [];
+'CosTransactions_NotPrepared'(_) ->
+ ?match(true, orber_tc:check_tc('CosTransactions_NotPrepared':tc())),
+ ?match("IDL:omg.org/CosTransactions/NotPrepared:1.0",
+ 'CosTransactions_NotPrepared':id()),
+ ?match("CosTransactions_NotPrepared",
+ 'CosTransactions_NotPrepared':name()),
+ ok.
+
+
+%%-----------------------------------------------------------------
+%% Test Case: 'CosTransactions_NotSubtransaction'
+%% Description:
+%%-----------------------------------------------------------------
+'CosTransactions_NotSubtransaction'(doc) -> ["CosTransactions_NotSubtransaction"];
+'CosTransactions_NotSubtransaction'(suite) -> [];
+'CosTransactions_NotSubtransaction'(_) ->
+ ?match(true, orber_tc:check_tc('CosTransactions_NotSubtransaction':tc())),
+ ?match("IDL:omg.org/CosTransactions/NotSubtransaction:1.0",
+ 'CosTransactions_NotSubtransaction':id()),
+ ?match("CosTransactions_NotSubtransaction",
+ 'CosTransactions_NotSubtransaction':name()),
+ ok.
+
+
+%%-----------------------------------------------------------------
+%% Test Case: 'CosTransactions_SubtransactionsUnavailable'
+%% Description:
+%%-----------------------------------------------------------------
+'CosTransactions_SubtransactionsUnavailable'(doc) -> ["CosTransactions_SubtransactionsUnavailable"];
+'CosTransactions_SubtransactionsUnavailable'(suite) -> [];
+'CosTransactions_SubtransactionsUnavailable'(_) ->
+ ?match(true, orber_tc:check_tc('CosTransactions_SubtransactionsUnavailable':tc())),
+ ?match("IDL:omg.org/CosTransactions/SubtransactionsUnavailable:1.0",
+ 'CosTransactions_SubtransactionsUnavailable':id()),
+ ?match("CosTransactions_SubtransactionsUnavailable",
+ 'CosTransactions_SubtransactionsUnavailable':name()),
+ ok.
+
+
+%%-----------------------------------------------------------------
+%% Test Case: 'CosTransactions_Unavailable'
+%% Description:
+%%-----------------------------------------------------------------
+'CosTransactions_Unavailable'(doc) -> ["CosTransactions_Unavailable"];
+'CosTransactions_Unavailable'(suite) -> [];
+'CosTransactions_Unavailable'(_) ->
+ ?match(true, orber_tc:check_tc('CosTransactions_Unavailable':tc())),
+ ?match("IDL:omg.org/CosTransactions/Unavailable:1.0",
+ 'CosTransactions_Unavailable':id()),
+ ?match("CosTransactions_Unavailable",
+ 'CosTransactions_Unavailable':name()),
+ ok.
+
+
+%%-----------------------------------------------------------------
+%% Test Case: 'CosTransactions_SynchronizationUnavailable'
+%% Description:
+%%-----------------------------------------------------------------
+'CosTransactions_SynchronizationUnavailable'(doc) -> ["CosTransactions_SynchronizationUnavailable"];
+'CosTransactions_SynchronizationUnavailable'(suite) -> [];
+'CosTransactions_SynchronizationUnavailable'(_) ->
+ ?match(true, orber_tc:check_tc('CosTransactions_SynchronizationUnavailable':tc())),
+ ?match("IDL:omg.org/CosTransactions/SynchronizationUnavailable:1.0",
+ 'CosTransactions_SynchronizationUnavailable':id()),
+ ?match("CosTransactions_SynchronizationUnavailable",
+ 'CosTransactions_SynchronizationUnavailable':name()),
+ ok.
+
+%%-----------------------------------------------------------------
+%% Test Case: 'CosTransactions_TransIdentity'
+%% Description:
+%%-----------------------------------------------------------------
+'CosTransactions_TransIdentity'(doc) -> ["CosTransactions_TransIdentity"];
+'CosTransactions_TransIdentity'(suite) -> [];
+'CosTransactions_TransIdentity'(_) ->
+ ?match(true, orber_tc:check_tc('CosTransactions_TransIdentity':tc())),
+ ?match("IDL:omg.org/CosTransactions/TransIdentity:1.0",
+ 'CosTransactions_TransIdentity':id()),
+ ?match("CosTransactions_TransIdentity",
+ 'CosTransactions_TransIdentity':name()),
+ ok.
+
+%%-----------------------------------------------------------------
+%% Test Case: 'CosTransactions_PropagationContext'
+%% Description:
+%%-----------------------------------------------------------------
+'CosTransactions_PropagationContext'(doc) -> ["CosTransactions_PropagationContext"];
+'CosTransactions_PropagationContext'(suite) -> [];
+'CosTransactions_PropagationContext'(_) ->
+ ?match(true, orber_tc:check_tc('CosTransactions_PropagationContext':tc())),
+ ?match("IDL:omg.org/CosTransactions/PropagationContext:1.0",
+ 'CosTransactions_PropagationContext':id()),
+ ?match("CosTransactions_PropagationContext",
+ 'CosTransactions_PropagationContext':name()),
+ ok.
+
+%%-----------------------------------------------------------------
+%% Test Case: 'CosTransactions_otid_t'
+%% Description:
+%%-----------------------------------------------------------------
+'CosTransactions_otid_t'(doc) -> ["CosTransactions_otid_t"];
+'CosTransactions_otid_t'(suite) -> [];
+'CosTransactions_otid_t'(_) ->
+ ?match(true, orber_tc:check_tc('CosTransactions_otid_t':tc())),
+ ?match("IDL:omg.org/CosTransactions/otid_t:1.0",
+ 'CosTransactions_otid_t':id()),
+ ?match("CosTransactions_otid_t",
+ 'CosTransactions_otid_t':name()),
+ ok.
+
+%%-----------------------------------------------------------------
+%% Test Case: 'CosTransactions_WrongTransaction'
+%% Description:
+%%-----------------------------------------------------------------
+'CosTransactions_WrongTransaction'(doc) -> ["CosTransactions_WrongTransaction"];
+'CosTransactions_WrongTransaction'(suite) -> [];
+'CosTransactions_WrongTransaction'(_) ->
+ ?match(true, orber_tc:check_tc('CosTransactions_WrongTransaction':tc())),
+ ?match("IDL:omg.org/CosTransactions/WrongTransaction:1.0",
+ 'CosTransactions_WrongTransaction':id()),
+ ?match("CosTransactions_WrongTransaction",
+ 'CosTransactions_WrongTransaction':name()),
+ ok.
+
+
+%%-----------------------------------------------------------------
+%% Test Case: 'CosTransactions_Control'
+%% Description:
+%%-----------------------------------------------------------------
+'CosTransactions_Control'(doc) -> ["CosTransactions_Control"];
+'CosTransactions_Control'(suite) -> [];
+'CosTransactions_Control'(_) ->
+ ?nomatch(undefined, 'CosTransactions_Control':oe_tc(get_terminator)),
+ ?nomatch(undefined, 'CosTransactions_Control':oe_tc(get_coordinator)),
+ ?match(undefined, 'CosTransactions_Control':oe_tc(undefined)),
+ ?match([_|_], 'CosTransactions_Control':oe_get_interface()),
+ ?match("IDL:omg.org/CosTransactions/Control:1.0",
+ 'CosTransactions_Control':typeID()),
+ check_tc('CosTransactions_Control':oe_get_interface()),
+ ?match(true, 'CosTransactions_Control':oe_is_a('CosTransactions_Control':typeID())),
+ ?match(false, 'CosTransactions_Control':oe_is_a("wrong")),
+ ok.
+
+
+%%-----------------------------------------------------------------
+%% Test Case: 'CosTransactions_Coordinator'
+%% Description:
+%%-----------------------------------------------------------------
+'CosTransactions_Coordinator'(doc) -> ["CosTransactions_Coordinator"];
+'CosTransactions_Coordinator'(suite) -> [];
+'CosTransactions_Coordinator'(_) ->
+ ?nomatch(undefined, 'CosTransactions_Coordinator':oe_tc(get_status)),
+ ?nomatch(undefined, 'CosTransactions_Coordinator':oe_tc(get_parent_status)),
+ ?nomatch(undefined, 'CosTransactions_Coordinator':oe_tc(get_top_level_status)),
+ ?nomatch(undefined, 'CosTransactions_Coordinator':oe_tc(is_same_transaction)),
+ ?nomatch(undefined, 'CosTransactions_Coordinator':oe_tc(is_related_transaction)),
+ ?nomatch(undefined, 'CosTransactions_Coordinator':oe_tc(is_ancestor_transaction)),
+ ?nomatch(undefined, 'CosTransactions_Coordinator':oe_tc(is_descendant_transaction)),
+ ?nomatch(undefined, 'CosTransactions_Coordinator':oe_tc(is_top_level_transaction)),
+ ?nomatch(undefined, 'CosTransactions_Coordinator':oe_tc(hash_transaction)),
+ ?nomatch(undefined, 'CosTransactions_Coordinator':oe_tc(hash_top_level_tran)),
+ ?nomatch(undefined, 'CosTransactions_Coordinator':oe_tc(register_resource)),
+ ?nomatch(undefined, 'CosTransactions_Coordinator':oe_tc(register_subtran_aware)),
+ ?nomatch(undefined, 'CosTransactions_Coordinator':oe_tc(rollback_only)),
+ ?nomatch(undefined, 'CosTransactions_Coordinator':oe_tc(get_transaction_name)),
+ ?nomatch(undefined, 'CosTransactions_Coordinator':oe_tc(create_subtransaction)),
+ ?nomatch(undefined, 'CosTransactions_Coordinator':oe_tc(get_txcontext)),
+ ?match(undefined, 'CosTransactions_Coordinator':oe_tc(undefined)),
+ ?match([_|_], 'CosTransactions_Coordinator':oe_get_interface()),
+ ?match("IDL:omg.org/CosTransactions/Coordinator:1.0",
+ 'CosTransactions_Coordinator':typeID()),
+ check_tc('CosTransactions_Coordinator':oe_get_interface()),
+ ?match(true, 'CosTransactions_Coordinator':oe_is_a('CosTransactions_Coordinator':typeID())),
+ ?match(false, 'CosTransactions_Coordinator':oe_is_a("wrong")),
+ ok.
+
+
+%%-----------------------------------------------------------------
+%% Test Case: 'CosTransactions_RecoveryCoordinator'
+%% Description:
+%%-----------------------------------------------------------------
+'CosTransactions_RecoveryCoordinator'(doc) -> ["CosTransactions_RecoveryCoordinator"];
+'CosTransactions_RecoveryCoordinator'(suite) -> [];
+'CosTransactions_RecoveryCoordinator'(_) ->
+ ?nomatch(undefined, 'CosTransactions_RecoveryCoordinator':oe_tc(replay_completion)),
+ ?match(undefined, 'CosTransactions_RecoveryCoordinator':oe_tc(undefined)),
+ ?match([_|_], 'CosTransactions_RecoveryCoordinator':oe_get_interface()),
+ ?match("IDL:omg.org/CosTransactions/RecoveryCoordinator:1.0",
+ 'CosTransactions_RecoveryCoordinator':typeID()),
+ check_tc('CosTransactions_RecoveryCoordinator':oe_get_interface()),
+ ?match(true, 'CosTransactions_RecoveryCoordinator':oe_is_a('CosTransactions_RecoveryCoordinator':typeID())),
+ ?match(false, 'CosTransactions_RecoveryCoordinator':oe_is_a("wrong")),
+ ok.
+
+
+%%-----------------------------------------------------------------
+%% Test Case: 'CosTransactions_Resource'
+%% Description:
+%%-----------------------------------------------------------------
+'CosTransactions_Resource'(doc) -> ["CosTransactions_Resource"];
+'CosTransactions_Resource'(suite) -> [];
+'CosTransactions_Resource'(_) ->
+ ?nomatch(undefined, 'CosTransactions_Resource':oe_tc(prepare)),
+ ?nomatch(undefined, 'CosTransactions_Resource':oe_tc(rollback)),
+ ?nomatch(undefined, 'CosTransactions_Resource':oe_tc(commit)),
+ ?nomatch(undefined, 'CosTransactions_Resource':oe_tc(commit_one_phase)),
+ ?nomatch(undefined, 'CosTransactions_Resource':oe_tc(forget)),
+ ?match(undefined, 'CosTransactions_Resource':oe_tc(undefined)),
+ ?match([_|_], 'CosTransactions_Resource':oe_get_interface()),
+ ?match("IDL:omg.org/CosTransactions/Resource:1.0",
+ 'CosTransactions_Resource':typeID()),
+ check_tc('CosTransactions_Resource':oe_get_interface()),
+ ?match(true, 'CosTransactions_Resource':oe_is_a('CosTransactions_Resource':typeID())),
+ ?match(false, 'CosTransactions_Resource':oe_is_a("wrong")),
+ ok.
+
+
+%%-----------------------------------------------------------------
+%% Test Case: 'CosTransactions_SubtransactionAwareResource'
+%% Description:
+%%-----------------------------------------------------------------
+'CosTransactions_SubtransactionAwareResource'(doc) -> ["CosTransactions_SubtransactionAwareResource"];
+'CosTransactions_SubtransactionAwareResource'(suite) -> [];
+'CosTransactions_SubtransactionAwareResource'(_) ->
+ ?nomatch(undefined, 'CosTransactions_SubtransactionAwareResource':oe_tc(commit_subtransaction)),
+ ?nomatch(undefined, 'CosTransactions_SubtransactionAwareResource':oe_tc(rollback_subtransaction)),
+ ?nomatch(undefined, 'CosTransactions_SubtransactionAwareResource':oe_tc(prepare)),
+ ?nomatch(undefined, 'CosTransactions_SubtransactionAwareResource':oe_tc(rollback)),
+ ?nomatch(undefined, 'CosTransactions_SubtransactionAwareResource':oe_tc(commit)),
+ ?nomatch(undefined, 'CosTransactions_SubtransactionAwareResource':oe_tc(commit_one_phase)),
+ ?nomatch(undefined, 'CosTransactions_SubtransactionAwareResource':oe_tc(forget)),
+ ?match(undefined, 'CosTransactions_SubtransactionAwareResource':oe_tc(undefined)),
+ ?match([_|_], 'CosTransactions_SubtransactionAwareResource':oe_get_interface()),
+ ?match("IDL:omg.org/CosTransactions/SubtransactionAwareResource:1.0",
+ 'CosTransactions_SubtransactionAwareResource':typeID()),
+ check_tc('CosTransactions_SubtransactionAwareResource':oe_get_interface()),
+ ?match(true, 'CosTransactions_SubtransactionAwareResource':oe_is_a('CosTransactions_SubtransactionAwareResource':typeID())),
+ ?match(true, 'CosTransactions_SubtransactionAwareResource':oe_is_a('CosTransactions_Resource':typeID())),
+ ?match(false, 'CosTransactions_SubtransactionAwareResource':oe_is_a("wrong")),
+ ok.
+
+
+%%-----------------------------------------------------------------
+%% Test Case: 'CosTransactions_Terminator'
+%% Description:
+%%-----------------------------------------------------------------
+'CosTransactions_Terminator'(doc) -> ["CosTransactions_Terminator"];
+'CosTransactions_Terminator'(suite) -> [];
+'CosTransactions_Terminator'(_) ->
+ ?nomatch(undefined, 'CosTransactions_Terminator':oe_tc(commit)),
+ ?nomatch(undefined, 'CosTransactions_Terminator':oe_tc(rollback)),
+ ?match(undefined, 'CosTransactions_Terminator':oe_tc(undefined)),
+ ?match([_|_], 'CosTransactions_Terminator':oe_get_interface()),
+ ?match("IDL:omg.org/CosTransactions/Terminator:1.0",
+ 'CosTransactions_Terminator':typeID()),
+ check_tc('CosTransactions_Terminator':oe_get_interface()),
+ ?match(true, 'CosTransactions_Terminator':oe_is_a('CosTransactions_Terminator':typeID())),
+ ?match(false, 'CosTransactions_Terminator':oe_is_a("wrong")),
+ ok.
+
+
+%%-----------------------------------------------------------------
+%% Test Case: 'CosTransactions_TransactionFactory'
+%% Description:
+%%-----------------------------------------------------------------
+'CosTransactions_TransactionFactory'(doc) -> ["CosTransactions_TransactionFactory"];
+'CosTransactions_TransactionFactory'(suite) -> [];
+'CosTransactions_TransactionFactory'(_) ->
+ ?nomatch(undefined, 'CosTransactions_TransactionFactory':oe_tc(create)),
+ ?nomatch(undefined, 'CosTransactions_TransactionFactory':oe_tc(recreate)),
+ ?match(undefined, 'CosTransactions_TransactionFactory':oe_tc(undefined)),
+ ?match([_|_], 'CosTransactions_TransactionFactory':oe_get_interface()),
+ ?match("IDL:omg.org/CosTransactions/TransactionFactory:1.0",
+ 'CosTransactions_TransactionFactory':typeID()),
+ check_tc('CosTransactions_TransactionFactory':oe_get_interface()),
+ ?match(true, 'CosTransactions_TransactionFactory':oe_is_a('CosTransactions_TransactionFactory':typeID())),
+ ?match(false, 'CosTransactions_TransactionFactory':oe_is_a("wrong")),
+ ok.
+
+
+%%-----------------------------------------------------------------
+%% Test Case: 'ETraP_Server'
+%% Description:
+%%-----------------------------------------------------------------
+'ETraP_Server'(doc) -> ["ETraP_Server"];
+'ETraP_Server'(suite) -> [];
+'ETraP_Server'(_) ->
+ ?nomatch(undefined, 'ETraP_Server':oe_tc(get_status)),
+ ?nomatch(undefined, 'ETraP_Server':oe_tc(get_parent_status)),
+ ?nomatch(undefined, 'ETraP_Server':oe_tc(get_top_level_status)),
+ ?nomatch(undefined, 'ETraP_Server':oe_tc(is_same_transaction)),
+ ?nomatch(undefined, 'ETraP_Server':oe_tc(is_related_transaction)),
+ ?nomatch(undefined, 'ETraP_Server':oe_tc(is_ancestor_transaction)),
+ ?nomatch(undefined, 'ETraP_Server':oe_tc(is_descendant_transaction)),
+ ?nomatch(undefined, 'ETraP_Server':oe_tc(is_top_level_transaction)),
+ ?nomatch(undefined, 'ETraP_Server':oe_tc(hash_transaction)),
+ ?nomatch(undefined, 'ETraP_Server':oe_tc(hash_top_level_tran)),
+ ?nomatch(undefined, 'ETraP_Server':oe_tc(register_resource)),
+ ?nomatch(undefined, 'ETraP_Server':oe_tc(register_subtran_aware)),
+ ?nomatch(undefined, 'ETraP_Server':oe_tc(rollback_only)),
+ ?nomatch(undefined, 'ETraP_Server':oe_tc(get_transaction_name)),
+ ?nomatch(undefined, 'ETraP_Server':oe_tc(create_subtransaction)),
+ ?nomatch(undefined, 'ETraP_Server':oe_tc(get_txcontext)),
+ ?nomatch(undefined, 'ETraP_Server':oe_tc(prepare)),
+ ?nomatch(undefined, 'ETraP_Server':oe_tc(rollback)),
+ ?nomatch(undefined, 'ETraP_Server':oe_tc(commit)),
+ ?nomatch(undefined, 'ETraP_Server':oe_tc(commit_one_phase)),
+ ?nomatch(undefined, 'ETraP_Server':oe_tc(forget)),
+ ?nomatch(undefined, 'ETraP_Server':oe_tc(replay_completion)),
+ ?nomatch(undefined, 'ETraP_Server':oe_tc(get_terminator)),
+ ?nomatch(undefined, 'ETraP_Server':oe_tc(get_coordinator)),
+ ?match(undefined, 'ETraP_Server':oe_tc(undefined)),
+ ?match([_|_], 'ETraP_Server':oe_get_interface()),
+ ?match("IDL:omg.org/ETraP/Server:1.0",
+ 'ETraP_Server':typeID()),
+ check_tc('ETraP_Server':oe_get_interface()),
+ ?match(true, 'ETraP_Server':oe_is_a('ETraP_Server':typeID())),
+ ?match(true, 'ETraP_Server':oe_is_a('CosTransactions_Coordinator':typeID())),
+ ?match(true, 'ETraP_Server':oe_is_a('CosTransactions_Resource':typeID())),
+ ?match(true, 'ETraP_Server':oe_is_a('CosTransactions_RecoveryCoordinator':typeID())),
+ ?match(true, 'ETraP_Server':oe_is_a('CosTransactions_Control':typeID())),
+ ?match(false, 'ETraP_Server':oe_is_a("wrong")),
+ ok.
+
+
+%%-----------------------------------------------------------------
+%% MISC functions
+%%-----------------------------------------------------------------
+check_tc([]) ->
+ ok;
+check_tc([{Op, {RetType, InParameters, OutParameters}}|T]) ->
+ io:format("checked - ~s~n", [Op]),
+ lists:all(?checktc(Op), [RetType|InParameters]),
+ lists:all(?checktc(Op), OutParameters),
+ check_tc(T).
+
+
diff --git a/lib/cosTransactions/test/transactions_SUITE.erl b/lib/cosTransactions/test/transactions_SUITE.erl
new file mode 100644
index 0000000000..8385d5a0fb
--- /dev/null
+++ b/lib/cosTransactions/test/transactions_SUITE.erl
@@ -0,0 +1,395 @@
+%%
+%% %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(transactions_SUITE).
+
+%%--------------- INCLUDES -----------------------------------
+-include_lib("orber/include/corba.hrl").
+-include_lib("orber/include/ifr_types.hrl").
+
+%% Local
+-include_lib("cosTransactions/src/ETraP_Common.hrl").
+-include_lib("cosTransactions/include/CosTransactions.hrl").
+-include("etrap_test_lib.hrl").
+
+-include("test_server.hrl").
+
+-define(default_timeout, ?t:minutes(20)).
+
+
+%%-----------------------------------------------------------------
+%% External exports
+%%-----------------------------------------------------------------
+-export([all/1, cases/0, init_all/1, finish_all/1, resource_api/1, etrap_api/1,
+ init_per_testcase/2, fin_per_testcase/2, app_test/1]).
+
+%%-----------------------------------------------------------------
+%% Func: all/1
+%% Args:
+%% Returns:
+%%-----------------------------------------------------------------
+all(doc) -> ["API tests for the cosTransactions interfaces", ""];
+all(suite) -> {req,
+ [mnesia, orber],
+ {conf, init_all, cases(), finish_all}}.
+
+cases() ->
+ [etrap_api, resource_api, app_test].
+
+
+
+%%-----------------------------------------------------------------
+%% Init and cleanup functions.
+%%-----------------------------------------------------------------
+
+init_per_testcase(_Case, Config) ->
+ Path = code:which(?MODULE),
+ code:add_pathz(filename:join(filename:dirname(Path), "idl_output")),
+ 'oe_CosTransactions':'oe_register'(),
+ 'oe_etrap_test':'oe_register'(),
+ ?line Dog=test_server:timetrap(?default_timeout),
+ [{watchdog, Dog}|Config].
+
+
+fin_per_testcase(_Case, Config) ->
+ 'oe_etrap_test':'oe_unregister'(),
+ 'oe_CosTransactions':'oe_unregister'(),
+ Path = code:which(?MODULE),
+ code:del_path(filename:join(filename:dirname(Path), "idl_output")),
+ Dog = ?config(watchdog, Config),
+ test_server:timetrap_cancel(Dog),
+ ok.
+
+init_all(Config) ->
+ mnesia:delete_schema([node()]),
+ mnesia:create_schema([node()]),
+ orber:install([node()]),
+ application:start(mnesia),
+ application:start(orber),
+ if
+ is_list(Config) ->
+ Config;
+ true ->
+ exit("Config not a list")
+ end.
+
+finish_all(Config) ->
+ application:stop(orber),
+ application:stop(mnesia),
+ mnesia:delete_schema([node()]),
+ Config.
+
+%%-----------------------------------------------------------------
+%% Tests app file
+%%-----------------------------------------------------------------
+app_test(doc) -> [];
+app_test(suite) -> [];
+app_test(_Config) ->
+ ok=test_server:app_test(cosTransactions),
+ ok.
+
+%%-----------------------------------------------------------------
+%% API tests
+%%-----------------------------------------------------------------
+etrap_api(doc) -> ["ETraP_Server tests", ""];
+etrap_api(suite) -> [];
+etrap_api(_Config) ->
+ ?line ?match(ok, application:start(cosTransactions),
+ "Starting the cosTransactions application"),
+ ?line TrFac = cosTransactions:start_factory(),
+ %% Start a new transaction:
+ %% RootCoord
+ %% / \
+ %% SubCoord1 SubCoord2
+ Control = 'CosTransactions_TransactionFactory':create(TrFac, 0),
+ Term = 'CosTransactions_Control':get_terminator(Control),
+ Coord = 'CosTransactions_Control':get_coordinator(Control),
+ SubCont1 = 'CosTransactions_Coordinator':create_subtransaction(Coord),
+ SubCont2 = 'CosTransactions_Coordinator':create_subtransaction(Coord),
+ SubCoord1 = 'CosTransactions_Control':get_coordinator(SubCont1),
+ SubCoord2 = 'CosTransactions_Control':get_coordinator(SubCont2),
+
+
+ %%------ Test CosTransactions::Coordinator ------
+ ?line ?match(true,
+ 'CosTransactions_Coordinator':is_same_transaction(Coord, Coord),
+ "'CosTransactions_Coordinator':is_same_transaction"),
+ ?line ?match(false,
+ 'CosTransactions_Coordinator':is_same_transaction(Coord, SubCoord1),
+ "'CosTransactions_Coordinator':is_same_transaction"),
+ ?line ?match(true,
+ 'CosTransactions_Coordinator':is_descendant_transaction(Coord, Coord),
+ "'CosTransactions_Coordinator':is_descendant_transaction"),
+ ?line ?match(false,
+ 'CosTransactions_Coordinator':is_descendant_transaction(Coord, SubCoord1),
+ "'CosTransactions_Coordinator':is_descendant_transaction"),
+ ?line ?match(true,
+ 'CosTransactions_Coordinator':is_descendant_transaction(SubCoord1, Coord),
+ "'CosTransactions_Coordinator':is_descendant_transaction"),
+ ?line ?match(false,
+ 'CosTransactions_Coordinator':is_descendant_transaction(SubCoord1, SubCoord2),
+ "'CosTransactions_Coordinator':is_descendant_transaction"),
+ ?line ?match(true,
+ 'CosTransactions_Coordinator':is_top_level_transaction(Coord),
+ "'CosTransactions_Coordinator':is_top_level_transaction"),
+ ?line ?match(false,
+ 'CosTransactions_Coordinator':is_top_level_transaction(SubCoord2),
+ "'CosTransactions_Coordinator':is_top_level_transaction"),
+
+ RootHash = 'CosTransactions_Coordinator':hash_transaction(Coord),
+ RepeatHash= 'CosTransactions_Coordinator':hash_transaction(Coord),
+ RootHash2 = 'CosTransactions_Coordinator':hash_top_level_tran(SubCoord1),
+ RootHash3 = 'CosTransactions_Coordinator':hash_top_level_tran(Coord),
+ _SubHash = 'CosTransactions_Coordinator':hash_transaction(SubCoord2),
+ ?line ?match(RootHash, RepeatHash,
+ "'CosTransactions_Coordinator':hash_transaction"),
+ ?line ?match(RootHash, RootHash2,
+ "'CosTransactions_Coordinator':hash_top_level_tran"),
+ ?line ?match(RootHash, RootHash3,
+ "'CosTransactions_Coordinator':hash_top_level_tran"),
+% ?line ?match_inverse(RootHash, SubHash,
+% "'CosTransactions_Coordinator':hash_transaction"),
+
+ ?line ?match('StatusActive',
+ 'CosTransactions_Coordinator':get_status(Coord),
+ "'CosTransactions_Coordinator':get_status"),
+ ?line ?match('StatusActive',
+ 'CosTransactions_Coordinator':get_status(SubCoord1),
+ "'CosTransactions_Coordinator':get_status"),
+ ?line ?match('StatusActive',
+ 'CosTransactions_Coordinator':get_parent_status(Coord),
+ "'CosTransactions_Coordinator':get_parent_status"),
+ ?line ?match('StatusActive',
+ 'CosTransactions_Coordinator':get_parent_status(SubCoord1),
+ "'CosTransactions_Coordinator':get_parent_status"),
+ ?line ?match('StatusActive',
+ 'CosTransactions_Coordinator':get_top_level_status(Coord),
+ "'CosTransactions_Coordinator':get_top_level_status"),
+ ?line ?match('StatusActive',
+ 'CosTransactions_Coordinator':get_top_level_status(SubCoord1),
+ "'CosTransactions_Coordinator':get_top_level_status"),
+
+ %% Create a CosTransactions::Resource to experiments with.
+ %% Start a new transaction:
+ %% RootCoord
+ %% / \
+ %% SubCoord1 SubCoord2
+ %% /
+ %% Resource
+ N1 = 'ETraP_Common':create_name("test"),
+ O1 = etrap_test_server:oe_create(?nop, {global, N1}),
+ _RC1 = 'CosTransactions_Coordinator':register_resource(SubCoord1, O1),
+% 'CosTransactions_Coordinator':register_synchronization(SubCoord1, O1),
+
+ ?line ?match('VoteCommit',
+ 'CosTransactions_Resource':prepare(SubCoord1),
+ "'CosTransactions_Coordinator':prepare"),
+ %% The Transaction are no longer in 'StatusActive' state. No new
+ %% "members" allowed.
+ ?line ?match('StatusPrepared',
+ 'CosTransactions_Coordinator':get_status(SubCoord1),
+ "'CosTransactions_Coordinator':get_status"),
+% ?line ?match({'EXCEPTION', ?tr_inactive},
+% 'CosTransactions_Coordinator':register_synchronization(SubCoord1, O1),
+% "'CosTransactions_Coordinator':register_synchronization"),
+ ?line ?match({'EXCEPTION', ?tr_inactive},
+ 'CosTransactions_Coordinator':register_resource(SubCoord1, O1),
+ "'CosTransactions_Coordinator':register_resource"),
+ ?line ?match({'EXCEPTION', ?tr_inactive},
+ 'CosTransactions_Coordinator':create_subtransaction(SubCoord1),
+ "'CosTransactions_Coordinator':create_subtransaction"),
+
+ catch corba:dispose(SubCoord1),
+ catch corba:dispose(SubCoord2),
+ catch corba:dispose(SubCont1),
+ catch corba:dispose(SubCont2),
+ catch corba:dispose(Term),
+ catch corba:dispose(Control),
+ catch corba:dispose(Coord),
+ catch corba:dispose(O1),
+
+ ?line cosTransactions:stop_factory(TrFac),
+ ?line application:stop(cosTransactions),
+ ok.
+
+%%-----------------------------------------------------------------
+%% API tests
+%%-----------------------------------------------------------------
+resource_api(doc) -> ["cosTransactions API tests", ""];
+resource_api(suite) -> [];
+resource_api(_Config) ->
+ ?line ?match(ok, application:start(cosTransactions),
+ "Starting the cosTransactions application"),
+ ?line TrFac = cosTransactions:start_factory([{typecheck, true}]),
+
+ ?line ?match({'EXCEPTION', #'TRANSACTION_ROLLEDBACK'{completion_status=?COMPLETED_YES}},
+ run(TrFac, 0, {?nop, ?nop, ?nop, ?prepare_rollback}),
+ "TESTCASE #1: Prepare rollback Resource 4"),
+ ?line ?match({'EXCEPTION', ?tr_mixed},
+ run(TrFac, 0, {?nop, ?nop, ?commit_mix, ?nop}),
+ "TESTCASE #2: Heuristic Mixed exception Resource 3"),
+ ?line ?match(ok,
+ run(TrFac, 0, {?nop, ?nop, ?nop, ?nop}),
+ "TESTCASE #3: Normal completion. No errors."),
+ ?line ?match(ok,
+ run(TrFac, 0, {?nop, ?nop, ?nop, ?commit_cm}),
+ "TESTCASE #4: Heuristic Commit Exception Resource 4"),
+ ?line ?match({'EXCEPTION', #'TRANSACTION_ROLLEDBACK'{completion_status=?COMPLETED_YES}},
+ run(TrFac, 0, {?nop, ?rollback_rb, ?nop, ?prepare_rollback}),
+ "TESTCASE #5: Heuristic Rollbac Resource 2, Resource 4 reply 'VoteRollback'"),
+ ?line ?match({'EXCEPTION', #'TRANSACTION_ROLLEDBACK'{completion_status=?COMPLETED_YES}},
+ run(TrFac, 0, {?nop, ?nop, ?prepare_rollback, ?rollback_rb}),
+ "TESTCASE #6: Heuristic Rollbac Resource 4, Resource 3 reply 'VoteRollback'"),
+ ?line ?match(ok,
+ run(TrFac, 0, {?nop, ?nop, ?commit_delay, ?nop}),
+ "TESTCASE #7: Resource 3 delay during commit. No timeout."),
+ ?line ?match(ok,
+ run(TrFac, 0, {?nop, ?nop, ?prepare_delay, ?nop}),
+ "TESTCASE #8: Resource 3 delay during prepare. No timeout."),
+ ?line ?match(ok,
+ run(TrFac, ?TIMEOUT, {?nop, ?commit_delay, ?nop, ?nop}),
+ "TESTCASE #9: Resource 3 delay during commit. Timeout."),
+ ?line ?match({'EXCEPTION', #'TRANSACTION_ROLLEDBACK'{completion_status=?COMPLETED_YES}},
+ run(TrFac, ?TIMEOUT, {?nop, ?prepare_delay, ?nop, ?nop}),
+ "TESTCASE #10: Resource 3 delay during prepare. Timeout."),
+ case ?is_debug_compiled of
+ true ->
+ %% Testing the Coordinators (root and sub).
+ ?line ?match(ok,
+ run(TrFac, 0, {?nop, ?nop, ?nop, ?nop, [?nop, ?nop,?crash_transient(commit), ?nop]}),
+ "TESTCASE #11: SubCoord 3 crash transient during commit."),
+ ?line ?match({'EXCEPTION', #'TRANSACTION_ROLLEDBACK'{}},
+ run(TrFac, 0, {?nop, ?nop, ?nop, ?nop, [?nop, ?nop,?crash_transient(send_prepare), ?nop]}),
+ "TESTCASE #12: SubCoord 3 crash transient during send prepare."),
+ ?line ?match({'EXCEPTION', ?tr_hazard},
+ run(TrFac, 0, {?nop, ?nop, ?nop, ?nop, [?nop, ?nop,?crash_permanent(commit), ?nop]}),
+ "TESTCASE #13: SubCoord 3 crash permanent during commit."),
+ ?line ?match({'EXCEPTION', #'TRANSACTION_ROLLEDBACK'{}},
+ run(TrFac, 0, {?nop, ?nop, ?nop, ?nop, [?nop, ?nop,?crash_permanent(send_prepare), ?nop]}),
+ "TESTCASE #14: SubCoord 3 crash permanent during prepare."),
+ ?line ?match({'EXCEPTION', #'TRANSACTION_ROLLEDBACK'{}},
+ run(TrFac, 0, {?nop, ?nop, ?nop, ?nop, [?nop, ?crash_transient(send_prepare), ?crash_transient(commit), ?nop]}),
+ "TESTCASE #15: SubCoord 2 crash transient during prepare. SubCoord 3 crash transient during commit"),
+ ?line ?match({'EXCEPTION', #'TRANSACTION_ROLLEDBACK'{completion_status=?COMPLETED_YES}},
+ run(TrFac, 0, {?nop, ?nop, ?nop, ?nop, [?crash_transient(send_prepare), ?nop, ?nop, ?nop]}),
+ "TESTCASE #16: RootCoord crash transient during send prepare."),
+ ?line ?match({'EXCEPTION', #'TRANSACTION_ROLLEDBACK'{}},
+ run(TrFac, 0, {?nop, ?nop, ?nop, ?nop, [?nop, ?crash_transient(prepare1), ?nop, ?nop]}),
+ "TESTCASE #17: SubCoord 1 crash transient during prepare1."),
+ ?line ?match({'EXCEPTION', ?tr_mixed},
+ run(TrFac, 0, {?nop, ?prepare_mix, ?nop, ?nop, [?nop, ?nop, ?crash_transient(prepare2), ?nop]}),
+ "TESTCASE #18: SubCoord 3 crash transient during prepare2. Resource 2 raise Heuristic Mixed during prepare"),
+ ?line ?match({'EXCEPTION', ?tr_mixed},
+ run(TrFac, 0, {?nop, ?commit_mix, ?nop, ?nop, [?nop, ?nop, ?crash_transient(commit2), ?nop]}),
+ "TESTCASE #19: Resource 2 raise Heurist mixed during commit. SubCoord crash transient commit2"),
+ ?line ?match({'EXCEPTION', ?tr_mixed},
+ run(TrFac, 0, {?nop, ?rollback_cm, ?nop, ?prepare_rollback, [?nop, ?crash_transient(rollback2), ?nop, ?nop]}),
+ "TESTCASE #20: Resource 2 raise Heuristic Commit during rollback. Resource 4 'VoteRollback'. SubCoord 2 crash transient rollback2."),
+ ?line ?match({'EXCEPTION', ?tr_mixed},
+ run(TrFac, 0, {?nop, ?nop, ?nop, ?commit_mix, [?nop, ?nop, ?crash_transient(send_forget1), ?nop]}),
+ "TESTCASE #21: Resource 4 raise Heuristic Mixed during commit. SubCoord 2 crash transient send_forget1."),
+ ?line ?match({'EXCEPTION', ?tr_mixed},
+ run(TrFac, 0, {?nop, ?nop, ?nop, ?commit_mix, [?crash_transient(send_forget1), ?nop, ?nop, ?nop]}),
+ "TESTCASE #22: Resource 4 raise Heuristic Mixed during commit. Root Coord crash transient send_forget1."),
+ ?line ?match({'EXCEPTION', ?tr_mixed},
+ run(TrFac, 0, {?nop, ?nop, ?nop, ?commit_mix, [?crash_transient(send_forget3), ?nop, ?crash_transient(send_forget1), ?nop]}),
+ "TESTCASE #23: Resource 4 raise Heuristic Mixed during commit. Root Coord crash transient send_forget3. SubCoord 3 crash transient send_forget1."),
+ ?line ?match({'EXCEPTION', #'TRANSACTION_ROLLEDBACK'{completion_status=?COMPLETED_YES}},
+ run(TrFac, ?TIMEOUT, {?nop, ?nop, ?nop, ?nop, [?delay_transient(root_delay, ?TIMEOUT*2), ?nop, ?nop, ?nop]}),
+ "TESTCASE #24: Delay RootCoord. Timeout."),
+ %% Testing the Terminator.
+ ?line ?match({'EXCEPTION', ?tr_mixed},
+ run(TrFac, ?TIMEOUT, {?nop, ?prepare_mix, ?nop, ?nop, [?nop, ?nop, ?nop, ?crash_transient(commit_heuristic1)]}),
+ "TESTCASE #25: Terminator crash transient after received and logged Heuristic mix."),
+ ?line ?match(ok,
+ run(TrFac, ?TIMEOUT, {?nop, ?nop, ?nop, ?nop, [?nop, ?nop, ?nop, ?crash_transient(commit_ok2)]}),
+ "TESTCASE #26: Terminator crash transient after received and logged 'ok'.");
+ _ ->
+ ok
+ end,
+
+ ?line cosTransactions:stop_factory(TrFac),
+ ?line application:stop(cosTransactions),
+ ok.
+
+%%-----------------------------------------------------------------
+%% Internal functions
+%%-----------------------------------------------------------------
+
+run(TrFac, Time, Spec) ->
+ Control = 'CosTransactions_TransactionFactory':create(TrFac, Time),
+ Term = 'CosTransactions_Control':get_terminator(Control),
+ Coord = 'CosTransactions_Control':get_coordinator(Control),
+ SubCont1 = 'CosTransactions_Coordinator':create_subtransaction(Coord),
+ SubCont2 = 'CosTransactions_Coordinator':create_subtransaction(Coord),
+ SubCoord1 = 'CosTransactions_Control':get_coordinator(SubCont1),
+ SubCoord2 = 'CosTransactions_Control':get_coordinator(SubCont2),
+ %% Start resources/participants.
+ {O1, O2, O3, O4, Ctx} = start_resources(Spec),
+
+ %% Get generated names to use for debugging.
+ CoordN = 'CosTransactions_Coordinator':get_transaction_name(Coord),
+ SubC1N = 'CosTransactions_Coordinator':get_transaction_name(SubCoord1),
+ SubC2N = 'CosTransactions_Coordinator':get_transaction_name(SubCoord2),
+
+ ?set_debug_context([CoordN, SubC1N, SubC2N, Term], Ctx),
+
+ %% Register the resources as participants.
+ _RC1 = 'CosTransactions_Coordinator':register_resource(SubCoord1, O1),
+ _RC2 = 'CosTransactions_Coordinator':register_resource(SubCoord1, O2),
+ _RC3 = 'CosTransactions_Coordinator':register_resource(SubCoord2, O3),
+ _RC4 = 'CosTransactions_Coordinator':register_resource(SubCoord2, O4),
+
+ 'CosTransactions_Coordinator':register_subtran_aware(SubCoord1, O4),
+% 'CosTransactions_Coordinator':register_synchronization(SubCoord1, O2),
+
+% Reply = (catch 'CosTransactions_Terminator':commit(Term, true)),
+ Reply = (catch 'ETraP_Common':send_stubborn('CosTransactions_Terminator',
+ commit, [Term, true],
+ ?tr_max_retries,
+ ?tr_comm_failure_wait)),
+
+ catch corba:dispose(SubCoord1),
+ catch corba:dispose(SubCoord2),
+ catch corba:dispose(SubCont1),
+ catch corba:dispose(SubCont2),
+ catch corba:dispose(Term),
+ catch corba:dispose(Control),
+ catch corba:dispose(Coord),
+ catch corba:dispose(O1),
+ catch corba:dispose(O2),
+ catch corba:dispose(O3),
+ catch corba:dispose(O4),
+ Reply.
+
+
+
+start_resources({A1, A2, A3, A4})->
+ start_resources({A1, A2, A3, A4, ?no_context});
+start_resources({A1, A2, A3, A4, Ctx})->
+ N1 = 'ETraP_Common':create_name("test"),
+ N2 = 'ETraP_Common':create_name("test"),
+ N3 = 'ETraP_Common':create_name("test"),
+ N4 = 'ETraP_Common':create_name("test"),
+ {_,_,O1} = supervisor:start_child(?SUPERVISOR_NAME, ?SUP_TEST(A1, N1)),
+ {_,_,O2} = supervisor:start_child(?SUPERVISOR_NAME, ?SUP_TEST(A2, N2)),
+% {_,_,O2} = supervisor:start_child(?SUPERVISOR_NAME, ?SUP_TEST([{sync,true}|A2], N2)),
+ {_,_,O3} = supervisor:start_child(?SUPERVISOR_NAME, ?SUP_TEST(A3, N3)),
+ {_,_,O4} = supervisor:start_child(?SUPERVISOR_NAME, ?SUP_TEST(A4, N4)),
+ {O1, O2, O3, O4, Ctx}.
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/Makefile.in b/lib/crypto/c_src/Makefile.in
index 29263d7ac7..18040a3b26 100644
--- a/lib/crypto/c_src/Makefile.in
+++ b/lib/crypto/c_src/Makefile.in
@@ -1,19 +1,19 @@
#
# %CopyrightBegin%
-#
-# Copyright Ericsson AB 1999-2009. All Rights Reserved.
-#
+#
+# Copyright Ericsson AB 1999-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%
#
include $(ERL_TOP)/make/target.mk
@@ -81,20 +81,12 @@ ifeq ($(HOST_OS),)
HOST_OS := $(shell $(ERL_TOP)/erts/autoconf/config.guess)
endif
DYNAMIC_CRYPTO_LIB=@SSL_DYNAMIC_ONLY@
-LD_R_FLAG=@DED_LD_FLAG_RUNTIME_LIBRARY_PATH@
-ifeq ($(strip $(LD_R_FLAG)),)
-LD_R_OPT =
-else
-ifeq ($(DYNAMIC_CRYPTO_LIB),yes)
-LD_R_OPT = $(LD_R_FLAG)$(SSL_LIBDIR)
-else
-LD_R_OPT =
-endif
-endif
ifeq ($(DYNAMIC_CRYPTO_LIB),yes)
-CRYPTO_LINK_LIB=-L$(SSL_LIBDIR) -lcrypto
+SSL_DED_LD_RUNTIME_LIBRARY_PATH = @SSL_DED_LD_RUNTIME_LIBRARY_PATH@
+CRYPTO_LINK_LIB=$(SSL_DED_LD_RUNTIME_LIBRARY_PATH) -L$(SSL_LIBDIR) -lcrypto
else
+SSL_DED_LD_RUNTIME_LIBRARY_PATH=
CRYPTO_LINK_LIB=$(SSL_LIBDIR)/libcrypto.a
endif
@@ -116,11 +108,11 @@ $(OBJDIR)/%.o: %.c
$(LIBDIR)/crypto_drv.so: $(OBJS)
$(INSTALL_DIR) $(LIBDIR)
- $(LD) $(LDFLAGS) $(LD_R_OPT) -o $@ $^ $(LDLIBS) $(CRYPTO_LINK_LIB)
+ $(LD) $(LDFLAGS) -o $@ $^ $(LDLIBS) $(CRYPTO_LINK_LIB)
$(LIBDIR)/crypto_drv.dll: $(OBJS)
$(INSTALL_DIR) $(LIBDIR)
- $(LD) $(LDFLAGS) -o $@ -L$(SSL_LIBDIR) $(OBJS) -llibeay32
+ $(LD) $(LDFLAGS) -o $@ $(SSL_DED_LD_RUNTIME_LIBRARY_PATH) -L$(SSL_LIBDIR) $(OBJS) -llibeay32
clean:
rm -f $(DYN_DRIVER) $(OBJS)
@@ -136,7 +128,7 @@ include $(ERL_TOP)/make/otp_release_targets.mk
release_spec: opt
$(INSTALL_DIR) $(RELSYSDIR)/priv/obj
$(INSTALL_DIR) $(RELSYSDIR)/priv/lib
- $(INSTALL_PROGRAM) $(DRV_MAKEFILE) $(RELSYSDIR)/priv/obj
+ $(INSTALL_DATA) $(DRV_MAKEFILE) $(RELSYSDIR)/priv/obj
$(INSTALL_PROGRAM) $(OBJS) $(RELSYSDIR)/priv/obj
$(INSTALL_PROGRAM) $(DYN_DRIVER) $(RELSYSDIR)/priv/lib
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/Makefile b/lib/crypto/doc/src/Makefile
index d2cec9b11b..03aaba939b 100644
--- a/lib/crypto/doc/src/Makefile
+++ b/lib/crypto/doc/src/Makefile
@@ -42,6 +42,9 @@ XML_CHAPTER_FILES = notes.xml licenses.xml
BOOK_FILES = book.xml
+XML_FILES = $(BOOK_FILES) $(XML_APPLICATION_FILES) $(XML_REF3_FILES) $(XML_REF6_FILES) \
+ $(XML_PART_FILES) $(XML_CHAPTER_FILES)
+
GIF_FILES =
# ----------------------------------------------------
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/doc/src/notes.xml b/lib/crypto/doc/src/notes.xml
index bbdd2d873b..6b9d1f56f1 100644
--- a/lib/crypto/doc/src/notes.xml
+++ b/lib/crypto/doc/src/notes.xml
@@ -4,7 +4,7 @@
<chapter>
<header>
<copyright>
- <year>1999</year><year>2009</year>
+ <year>1999</year><year>2010</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
@@ -13,12 +13,12 @@
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>Crypto Release Notes</title>
@@ -30,6 +30,98 @@
</header>
<p>This document describes the changes made to the Crypto application.</p>
+<section><title>Crypto 1.6.4</title>
+
+ <section><title>Improvements and New Features</title>
+ <list>
+ <item>
+ <p>Cross compilation improvements and other build system
+ improvements.</p>
+ <p>Most notable:</p> <list><item> Lots of cross
+ compilation improvements. The old cross compilation
+ support was more or less non-existing as well as broken.
+ Please, note that the cross compilation support should
+ still be considered as experimental. Also note that old
+ cross compilation configurations cannot be used without
+ modifications. For more information on cross compiling
+ Erlang/OTP see the <c>$ERL_TOP/INSTALL-CROSS.md</c> file.
+ </item><item> Support for staged install using <url
+ href="http://www.gnu.org/prep/standards/html_node/DESTDIR.html">DESTDIR</url>.
+ The old broken <c>INSTALL_PREFIX</c> has also been fixed.
+ For more information see the <c>$ERL_TOP/INSTALL.md</c>
+ file. </item><item> Documentation of the <c>release</c>
+ target of the top <c>Makefile</c>. For more information
+ see the <c>$ERL_TOP/INSTALL.md</c> file. </item><item>
+ <c>make install</c> now by default creates relative
+ symbolic links instead of absolute ones. For more
+ information see the <c>$ERL_TOP/INSTALL.md</c> file.
+ </item><item> <c>$ERL_TOP/configure --help=recursive</c>
+ now works and prints help for all applications with
+ <c>configure</c> scripts. </item><item> Doing <c>make
+ install</c>, or <c>make release</c> directly after
+ <c>make all</c> no longer triggers miscellaneous
+ rebuilds. </item><item> Existing bootstrap system is now
+ used when doing <c>make install</c>, or <c>make
+ release</c> without a preceding <c>make all</c>.
+ </item><item> The <c>crypto</c> and <c>ssl</c>
+ applications use the same runtime library path when
+ dynamically linking against <c>libssl.so</c> and
+ <c>libcrypto.so</c>. The runtime library search path has
+ also been extended. </item><item> The <c>configure</c>
+ scripts of <c>erl_interface</c> and <c>odbc</c> now
+ search for thread libraries and thread library quirks the
+ same way as <c>erts</c> do. </item><item> The
+ <c>configure</c> script of the <c>odbc</c> application
+ now also looks for odbc libraries in <c>lib64</c> and
+ <c>lib/64</c> directories when building on a 64-bit
+ system. </item><item> The <c>config.h.in</c> file in the
+ <c>erl_interface</c> application is now automatically
+ generated in instead of statically updated which reduces
+ the risk of <c>configure</c> tests without any effect.
+ </item></list>
+ <p>(Thanks to Henrik Riomar for suggestions and
+ testing)</p>
+ <p>(Thanks to Winston Smith for the AVR32-Linux cross
+ configuration and testing)</p>
+ <p>
+ *** POTENTIAL INCOMPATIBILITY ***</p>
+ <p>
+ Own Id: OTP-8323</p>
+ </item>
+ <item>
+ <p>
+ The crypto module now supports Blowfish in ECB, CBC and
+ OFB modes. (Thanks to Paul Oliver.)</p>
+ <p>
+ Own Id: OTP-8331</p>
+ </item>
+ <item>
+ <p>The documentation is now possible to build in an open
+ source environment after a number of bugs are fixed and
+ some features are added in the documentation build
+ process. </p>
+ <p>- The arity calculation is updated.</p>
+ <p>- The module prefix used in the function names for
+ bif's are removed in the generated links so the links
+ will look like
+ "http://www.erlang.org/doc/man/erlang.html#append_element-2"
+ instead of
+ "http://www.erlang.org/doc/man/erlang.html#erlang:append_element-2".</p>
+ <p>- Enhanced the menu positioning in the html
+ documentation when a new page is loaded.</p>
+ <p>- A number of corrections in the generation of man
+ pages (thanks to Sergei Golovan)</p>
+ <p>- The legal notice is taken from the xml book file so
+ OTP's build process can be used for non OTP
+ applications.</p>
+ <p>
+ Own Id: OTP-8343</p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
<section><title>Crypto 1.6.3</title>
<section><title>Fixed Bugs and Malfunctions</title>
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/crypto/vsn.mk b/lib/crypto/vsn.mk
index f2a9b4fe24..68eecfe759 100644
--- a/lib/crypto/vsn.mk
+++ b/lib/crypto/vsn.mk
@@ -1 +1 @@
-CRYPTO_VSN = 1.6.3
+CRYPTO_VSN = 1.6.4
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/notes.xml b/lib/debugger/doc/src/notes.xml
index a046eb8af0..afd49e8593 100644
--- a/lib/debugger/doc/src/notes.xml
+++ b/lib/debugger/doc/src/notes.xml
@@ -4,7 +4,7 @@
<chapter>
<header>
<copyright>
- <year>2004</year><year>2009</year>
+ <year>2004</year><year>2010</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
@@ -13,12 +13,12 @@
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>
@@ -32,6 +32,34 @@
<p>This document describes the changes made to the Debugger
application.</p>
+<section><title>Debugger 3.2.2</title>
+
+ <section><title>Fixed Bugs and Malfunctions</title>
+ <list>
+ <item>
+ <p>
+ Bugs have been fixed in the evaluation of comprehensions
+ and short-circuit expressions in guards.</p>
+ <p>
+ Own Id: OTP-8310</p>
+ </item>
+ </list>
+ </section>
+
+ <section><title>Improvements and New Features</title>
+ <list>
+ <item>
+ <p>
+ Miscellaneous corrections of the WX version of the
+ debugger.</p>
+ <p>
+ Own Id: OTP-8346</p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
<section><title>Debugger 3.2.1</title>
<section><title>Improvements and New Features</title>
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_ieval.erl b/lib/debugger/src/dbg_ieval.erl
index 47d4ecaaf8..c13fda7ac1 100644
--- a/lib/debugger/src/dbg_ieval.erl
+++ b/lib/debugger/src/dbg_ieval.erl
@@ -25,8 +25,6 @@
-include("dbg_ieval.hrl").
--import(lists, [foldl/3,flatmap/2]).
-
%%====================================================================
%% External exports
%%====================================================================
@@ -1142,18 +1140,13 @@ eval_lc(E, Qs, Bs, Ieval) ->
eval_lc1(E, [{generate,Line,P,L0}|Qs], Bs0, Ieval0) ->
Ieval = Ieval0#ieval{line=Line},
{value,L1,Bs1} = expr(L0, Bs0, Ieval#ieval{last_call=false}),
- flatmap(fun (V) ->
- case catch match1(P, V, [], Bs0) of
- {match,Bsn} ->
- Bs2 = add_bindings(Bsn, Bs1),
- eval_lc1(E, Qs, Bs2, Ieval);
- nomatch -> []
- end end,L1);
+ CompFun = fun(NewBs) -> eval_lc1(E, Qs, NewBs, Ieval) end,
+ eval_generate(L1, P, Bs1, CompFun, Ieval);
eval_lc1(E, [{b_generate,Line,P,L0}|Qs], Bs0, Ieval0) ->
Ieval = Ieval0#ieval{line=Line},
{value,Bin,_} = expr(L0, Bs0, Ieval#ieval{last_call=false}),
CompFun = fun(NewBs) -> eval_lc1(E, Qs, NewBs, Ieval) end,
- eval_b_generate(Bin, P, Bs0, CompFun);
+ eval_b_generate(Bin, P, Bs0, CompFun, Ieval);
eval_lc1(E, [{guard,Q}|Qs], Bs0, Ieval) ->
case guard(Q, Bs0) of
true -> eval_lc1(E, Qs, Bs0, Ieval);
@@ -1162,7 +1155,8 @@ eval_lc1(E, [{guard,Q}|Qs], Bs0, Ieval) ->
eval_lc1(E, [Q|Qs], Bs0, Ieval) ->
case expr(Q, Bs0, Ieval#ieval{last_call=false}) of
{value,true,Bs} -> eval_lc1(E, Qs, Bs, Ieval);
- _ -> []
+ {value,false,_Bs} -> [];
+ {value,V,Bs} -> exception(error, {bad_filter,V}, Bs, Ieval)
end;
eval_lc1(E, [], Bs, Ieval) ->
{value,V,_} = expr(E, Bs, Ieval#ieval{last_call=false}),
@@ -1179,18 +1173,13 @@ eval_bc(E, Qs, Bs, Ieval) ->
eval_bc1(E, [{generate,Line,P,L0}|Qs], Bs0, Ieval0) ->
Ieval = Ieval0#ieval{line=Line},
{value,L1,Bs1} = expr(L0, Bs0, Ieval#ieval{last_call=false}),
- flatmap(fun (V) ->
- case catch match1(P, V, [], Bs0) of
- {match,Bsn} ->
- Bs2 = add_bindings(Bsn, Bs1),
- eval_bc1(E, Qs, Bs2, Ieval);
- nomatch -> []
- end end, L1);
+ CompFun = fun(NewBs) -> eval_bc1(E, Qs, NewBs, Ieval) end,
+ eval_generate(L1, P, Bs1, CompFun, Ieval);
eval_bc1(E, [{b_generate,Line,P,L0}|Qs], Bs0, Ieval0) ->
Ieval = Ieval0#ieval{line=Line},
{value,Bin,_} = expr(L0, Bs0, Ieval#ieval{last_call=false}),
CompFun = fun(NewBs) -> eval_bc1(E, Qs, NewBs, Ieval) end,
- eval_b_generate(Bin, P, Bs0, CompFun);
+ eval_b_generate(Bin, P, Bs0, CompFun, Ieval);
eval_bc1(E, [{guard,Q}|Qs], Bs0, Ieval) ->
case guard(Q, Bs0) of
true -> eval_bc1(E, Qs, Bs0, Ieval);
@@ -1199,24 +1188,40 @@ eval_bc1(E, [{guard,Q}|Qs], Bs0, Ieval) ->
eval_bc1(E, [Q|Qs], Bs0, Ieval) ->
case expr(Q, Bs0, Ieval#ieval{last_call=false}) of
{value,true,Bs} -> eval_bc1(E, Qs, Bs, Ieval);
- _ -> []
+ {value,false,_Bs} -> [];
+ {value,V,Bs} -> exception(error, {bad_filter,V}, Bs, Ieval)
end;
eval_bc1(E, [], Bs, Ieval) ->
{value,V,_} = expr(E, Bs, Ieval#ieval{last_call=false}),
[V].
-eval_b_generate(<<_/bitstring>>=Bin, P, Bs0, CompFun) ->
+eval_generate([V|Rest], P, Bs0, CompFun, Ieval) ->
+ case catch match1(P, V, erl_eval:new_bindings(), Bs0) of
+ {match,Bsn} ->
+ Bs2 = add_bindings(Bsn, Bs0),
+ CompFun(Bs2) ++ eval_generate(Rest, P, Bs2, CompFun, Ieval);
+ nomatch ->
+ eval_generate(Rest, P, Bs0, CompFun, Ieval)
+ end;
+eval_generate([], _P, _Bs0, _CompFun, _Ieval) ->
+ [];
+eval_generate(Term, _P, Bs, _CompFun, Ieval) ->
+ exception(error, {bad_generator,Term}, Bs, Ieval).
+
+eval_b_generate(<<_/bitstring>>=Bin, P, Bs0, CompFun, Ieval) ->
Mfun = fun(L, R, Bs) -> match1(L, R, Bs, Bs0) end,
Efun = fun(Exp, Bs) -> expr(Exp, Bs, #ieval{}) end,
case eval_bits:bin_gen(P, Bin, erl_eval:new_bindings(), Bs0, Mfun, Efun) of
{match,Rest,Bs1} ->
Bs2 = add_bindings(Bs1, Bs0),
- CompFun(Bs2) ++ eval_b_generate(Rest, P, Bs0, CompFun);
+ CompFun(Bs2) ++ eval_b_generate(Rest, P, Bs0, CompFun, Ieval);
{nomatch,Rest} ->
- eval_b_generate(Rest, P, Bs0, CompFun);
+ eval_b_generate(Rest, P, Bs0, CompFun, Ieval);
done ->
[]
- end.
+ end;
+eval_b_generate(Term, _P, Bs, _CompFun, Ieval) ->
+ exception(error, {bad_generator,Term}, Bs, Ieval).
module_info(Mod, module) -> Mod;
module_info(_Mod, compile) -> [];
@@ -1519,7 +1524,7 @@ guard_expr({'andalso',_,E1,E2}, Bs) ->
{value,false}=Res -> Res;
{value,true} ->
case guard_expr(E2, Bs) of
- {value,Bool}=Res when is_boolean(Bool) -> Res
+ {value,_Val}=Res -> Res
end
end;
guard_expr({'orelse',_,E1,E2}, Bs) ->
@@ -1527,7 +1532,7 @@ guard_expr({'orelse',_,E1,E2}, Bs) ->
{value,true}=Res -> Res;
{value,false} ->
case guard_expr(E2, Bs) of
- {value,Bool}=Res when is_boolean(Bool) -> Res
+ {value,_Val}=Res -> Res
end
end;
guard_expr({dbg,_,self,[]}, _) ->
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/debugger/test/Makefile b/lib/debugger/test/Makefile
new file mode 100644
index 0000000000..ac929038f7
--- /dev/null
+++ b/lib/debugger/test/Makefile
@@ -0,0 +1,106 @@
+#
+# %CopyrightBegin%
+#
+# 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%
+#
+include $(ERL_TOP)/make/target.mk
+include $(ERL_TOP)/make/$(TARGET)/otp.mk
+
+# ----------------------------------------------------
+# Target Specs
+# ----------------------------------------------------
+
+MODULES= \
+ andor_SUITE \
+ bs_bincomp_SUITE \
+ bs_construct_SUITE \
+ bs_match_bin_SUITE \
+ bs_match_int_SUITE \
+ bs_match_misc_SUITE \
+ bs_match_tail_SUITE \
+ bs_utf_SUITE \
+ bug_SUITE \
+ erl_eval_SUITE \
+ dbg_ui_SUITE \
+ debugger_SUITE \
+ int_SUITE \
+ int_break_SUITE \
+ int_eval_SUITE \
+ guard_SUITE \
+ exception_SUITE \
+ fun_SUITE \
+ lc_SUITE \
+ record_SUITE \
+ trycatch_SUITE \
+ test_lib \
+ cleanup
+
+ERL_FILES= $(MODULES:%=%.erl)
+
+TARGET_FILES= $(MODULES:%=$(EBIN)/%.$(EMULATOR))
+INSTALL_PROGS= $(TARGET_FILES)
+
+EMAKEFILE=Emakefile
+
+# ----------------------------------------------------
+# Release directory specification
+# ----------------------------------------------------
+RELSYSDIR = $(RELEASE_PATH)/debugger_test
+
+# ----------------------------------------------------
+# FLAGS
+# ----------------------------------------------------
+
+ERL_MAKE_FLAGS +=
+ERL_COMPILE_FLAGS += -I$(ERL_TOP)/lib/test_server/include
+
+EBIN = .
+
+# ----------------------------------------------------
+# Targets
+# ----------------------------------------------------
+
+make_emakefile:
+ $(ERL_TOP)/make/make_emakefile $(ERL_COMPILE_FLAGS) -o$(EBIN) $(MODULES) \
+ > $(EMAKEFILE)
+ $(ERL_TOP)/make/make_emakefile $(ERL_COMPILE_FLAGS) -o$(EBIN) '*_SUITE_make' \
+ >> $(EMAKEFILE)
+
+tests debug opt: make_emakefile
+ erl $(ERL_MAKE_FLAGS) -make
+
+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: opt
+
+release_tests_spec: make_emakefile
+ $(INSTALL_DIR) $(RELSYSDIR)
+ $(INSTALL_DATA) $(EMAKEFILE) $(ERL_FILES) $(RELSYSDIR)
+ $(INSTALL_DATA) debugger.spec $(RELSYSDIR)
+ chmod -f -R u+w $(RELSYSDIR)
+ @tar cf - *_SUITE_data | (cd $(RELSYSDIR); tar xf -)
+
+release_docs_spec:
diff --git a/lib/debugger/test/andor_SUITE.erl b/lib/debugger/test/andor_SUITE.erl
new file mode 100644
index 0000000000..3482a22a34
--- /dev/null
+++ b/lib/debugger/test/andor_SUITE.erl
@@ -0,0 +1,305 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 2006-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(andor_SUITE).
+
+-export([all/1,init_per_testcase/2,fin_per_testcase/2,init_all/1,finish_all/1,
+ t_andalso/1,t_orelse/1,inside/1,overlap/1,
+ combined/1,in_case/1]).
+
+-include("test_server.hrl").
+
+all(suite) ->
+ [{conf,init_all,cases(),finish_all}].
+
+init_per_testcase(_Case, Config) ->
+ test_lib:interpret(?MODULE),
+ ?line Dog = test_server:timetrap(?t:minutes(1)),
+ [{watchdog,Dog}|Config].
+
+fin_per_testcase(_Case, Config) ->
+ Dog = ?config(watchdog, Config),
+ ?t:timetrap_cancel(Dog),
+ ok.
+
+init_all(Config) when is_list(Config) ->
+ ?line test_lib:interpret(?MODULE),
+ ?line true = lists:member(?MODULE, int:interpreted()),
+ ok.
+
+finish_all(Config) when is_list(Config) ->
+ ok.
+
+cases() ->
+ [t_andalso,t_orelse,inside,overlap,combined,in_case].
+
+t_andalso(Config) when is_list(Config) ->
+ Bs = [true,false],
+ Ps = [{X,Y} || X <- Bs, Y <- Bs],
+ lists:foreach(fun (P) -> t_andalso_1(P) end, Ps),
+
+ ?line true = true andalso true,
+ ?line false = true andalso false,
+ ?line false = false andalso true,
+ ?line false = false andalso false,
+
+ ?line false = false andalso glurf,
+ ?line false = false andalso exit(exit_now),
+
+ ?line true = not id(false) andalso not id(false),
+ ?line false = not id(false) andalso not id(true),
+ ?line false = not id(true) andalso not id(false),
+ ?line false = not id(true) andalso not id(true),
+
+ ?line {'EXIT',{badarg,_}} = (catch not id(glurf) andalso id(true)),
+ ?line {'EXIT',{badarg,_}} = (catch not id(false) andalso not id(glurf)),
+ ?line false = id(false) andalso not id(glurf),
+ ?line false = false andalso not id(glurf),
+
+ ok.
+
+t_orelse(Config) when is_list(Config) ->
+ Bs = [true,false],
+ Ps = [{X,Y} || X <- Bs, Y <- Bs],
+ lists:foreach(fun (P) -> t_orelse_1(P) end, Ps),
+
+ ?line true = true orelse true,
+ ?line true = true orelse false,
+ ?line true = false orelse true,
+ ?line false = false orelse false,
+
+ ?line true = true orelse glurf,
+ ?line true = true orelse exit(exit_now),
+
+ ?line true = not id(false) orelse not id(false),
+ ?line true = not id(false) orelse not id(true),
+ ?line true = not id(true) orelse not id(false),
+ ?line false = not id(true) orelse not id(true),
+
+ ?line {'EXIT',{badarg,_}} = (catch not id(glurf) orelse id(true)),
+ ?line {'EXIT',{badarg,_}} = (catch not id(true) orelse not id(glurf)),
+ ?line true = id(true) orelse not id(glurf),
+ ?line true = true orelse not id(glurf),
+
+ ok.
+
+t_andalso_1({X,Y}) ->
+ io:fwrite("~w andalso ~w: ",[X,Y]),
+ V1 = echo(X) andalso echo(Y),
+ V1 = if
+ X andalso Y -> true;
+ true -> false
+ end,
+ check(V1, X and Y).
+
+t_orelse_1({X,Y}) ->
+ io:fwrite("~w orelse ~w: ",[X,Y]),
+ V1 = echo(X) orelse echo(Y),
+ V1 = if
+ X orelse Y -> true;
+ true -> false
+ end,
+ check(V1, X or Y).
+
+inside(Config) when is_list(Config) ->
+ ?line true = inside(-8, 1),
+ ?line false = inside(-53.5, -879798),
+ ?line false = inside(1.0, -879),
+ ?line false = inside(59, -879),
+ ?line false = inside(-11, 1.0),
+ ?line false = inside(100, 0.2),
+ ?line false = inside(100, 1.2),
+ ?line false = inside(-53.5, 4),
+ ?line false = inside(1.0, 5.3),
+ ?line false = inside(59, 879),
+ ok.
+
+inside(Xm, Ym) ->
+ X = -10.0,
+ Y = -2.0,
+ W = 20.0,
+ H = 4.0,
+ Res = inside(Xm, Ym, X, Y, W, H),
+ Res = if
+ X =< Xm andalso Xm < X+W andalso Y =< Ym andalso Ym < Y+H -> true;
+ true -> false
+ end,
+ case not id(Res) of
+ Outside ->
+ Outside = if
+ not(X =< Xm andalso Xm < X+W andalso Y =< Ym andalso Ym < Y+H) -> true;
+ true -> false
+ end
+ end,
+ {Res,Xm,Ym,X,Y,W,H} = inside_guard(Xm, Ym, X, Y, W, H),
+ io:format("~p =< ~p andalso ~p < ~p andalso ~p =< ~p andalso ~p < ~p ==> ~p",
+ [X,Xm,Xm,X+W,Y,Ym,Ym,Y+H,Res]),
+ Res.
+
+inside(Xm, Ym, X, Y, W, H) ->
+ X =< Xm andalso Xm < X+W andalso Y =< Ym andalso Ym < Y+H.
+
+inside_guard(Xm, Ym, X, Y, W, H) when X =< Xm andalso Xm < X+W
+ andalso Y =< Ym andalso Ym < Y+H ->
+ {true,Xm,Ym,X,Y,W,H};
+inside_guard(Xm, Ym, X, Y, W, H) ->
+ {false,Xm,Ym,X,Y,W,H}.
+
+overlap(Config) when is_list(Config) ->
+ ?line true = overlap(7.0, 2.0, 8.0, 0.5),
+ ?line true = overlap(7.0, 2.0, 8.0, 2.5),
+ ?line true = overlap(7.0, 2.0, 5.3, 2),
+ ?line true = overlap(7.0, 2.0, 0.0, 100.0),
+
+ ?line false = overlap(-1, 2, -35, 0.5),
+ ?line false = overlap(-1, 2, 777, 0.5),
+ ?line false = overlap(-1, 2, 2, 10),
+ ?line false = overlap(2, 10, 12, 55.3),
+ ok.
+
+overlap(Pos1, Len1, Pos2, Len2) ->
+ Res = case Pos1 of
+ Pos1 when (Pos2 =< Pos1 andalso Pos1 < Pos2+Len2)
+ orelse (Pos1 =< Pos2 andalso Pos2 < Pos1+Len1) ->
+ true;
+ Pos1 -> false
+ end,
+ Res = (Pos2 =< Pos1 andalso Pos1 < Pos2+Len2)
+ orelse (Pos1 =< Pos2 andalso Pos2 < Pos1+Len1),
+ Res = case Pos1 of
+ Pos1 when (Pos2 =< Pos1 andalso Pos1 < Pos2+Len2)
+ orelse (Pos1 =< Pos2 andalso Pos2 < Pos1+Len1) ->
+ true;
+ Pos1 -> false
+ end,
+ id(Res).
+
+
+-define(COMB(A,B,C), (A andalso B orelse C)).
+
+combined(Config) when is_list(Config) ->
+ ?line false = comb(false, false, false),
+ ?line true = comb(false, false, true),
+ ?line false = comb(false, true, false),
+ ?line true = comb(false, true, true),
+
+ ?line false = comb(true, false, false),
+ ?line true = comb(true, true, false),
+ ?line true = comb(true, false, true),
+ ?line true = comb(true, true, true),
+
+ ?line false = comb(false, blurf, false),
+ ?line true = comb(false, blurf, true),
+ ?line true = comb(true, true, blurf),
+
+ ?line false = ?COMB(false, false, false),
+ ?line true = ?COMB(false, false, true),
+ ?line false = ?COMB(false, true, false),
+ ?line true = ?COMB(false, true, true),
+
+ ?line false = ?COMB(true, false, false),
+ ?line true = ?COMB(true, true, false),
+ ?line true = ?COMB(true, false, true),
+ ?line true = ?COMB(true, true, true),
+
+ ?line false = ?COMB(false, blurf, false),
+ ?line true = ?COMB(false, blurf, true),
+ ?line true = ?COMB(true, true, blurf),
+
+ ok.
+-undef(COMB).
+
+comb(A, B, C) ->
+ Res = A andalso B orelse C,
+ Res = if
+ A andalso B orelse C -> true;
+ true -> false
+ end,
+ NotRes = if
+ not(A andalso B orelse C) -> true;
+ true -> false
+ end,
+ NotRes = id(not Res),
+ Res = A andalso B orelse C,
+ Res = if
+ A andalso B orelse C -> true;
+ true -> false
+ end,
+ NotRes = id(not Res),
+ Res = if
+ A andalso B orelse C -> true;
+ true -> false
+ end,
+ id(Res).
+
+%% Test that a boolean expression in a case expression is properly
+%% optimized (in particular, that the error behaviour is correct).
+in_case(Config) when is_list(Config) ->
+ ?line edge_rings = in_case_1(1, 1, 1, 1, 1),
+ ?line not_loop = in_case_1(0.5, 1, 1, 1, 1),
+ ?line loop = in_case_1(0.5, 0.9, 1.1, 1, 4),
+ ?line {'EXIT',{badarith,_}} = (catch in_case_1(1, 1, 1, 1, 0)),
+ ?line {'EXIT',{badarith,_}} = (catch in_case_1(1, 1, 1, 1, nan)),
+ ?line {'EXIT',{badarg,_}} = (catch in_case_1(1, 1, 1, blurf, 1)),
+ ?line {'EXIT',{badarith,_}} = (catch in_case_1([nan], 1, 1, 1, 1)),
+ ok.
+
+in_case_1(LenUp, LenDw, LenN, Rotation, Count) ->
+ Res = in_case_1_body(LenUp, LenDw, LenN, Rotation, Count),
+ Res = in_case_1_guard(LenUp, LenDw, LenN, Rotation, Count),
+ Res.
+
+in_case_1_body(LenUp, LenDw, LenN, Rotation, Count) ->
+ case (LenUp/Count > 0.707) and (LenN/Count > 0.707) and
+ (abs(Rotation) > 0.707) of
+ true ->
+ edge_rings;
+ false ->
+ case (LenUp >= 1) or (LenDw >= 1) or
+ (LenN =< 1) or (Count < 4) of
+ true ->
+ not_loop;
+ false ->
+ loop
+ end
+ end.
+
+in_case_1_guard(LenUp, LenDw, LenN, Rotation, Count) ->
+ case (LenUp/Count > 0.707) andalso (LenN/Count > 0.707) andalso
+ (abs(Rotation) > 0.707) of
+ true -> edge_rings;
+ false when LenUp >= 1 orelse LenDw >= 1 orelse
+ LenN =< 1 orelse Count < 4 -> not_loop;
+ false -> loop
+ end.
+
+check(V1, V0) ->
+ if V1 /= V0 ->
+ io:fwrite("error: ~w.\n", [V1]),
+ ?t:fail();
+ true ->
+ io:fwrite("ok: ~w.\n", [V1])
+ end.
+
+echo(X) ->
+ io:fwrite("eval(~w); ",[X]),
+ X.
+
+id(I) -> I.
diff --git a/lib/debugger/test/bs_bincomp_SUITE.erl b/lib/debugger/test/bs_bincomp_SUITE.erl
new file mode 100644
index 0000000000..8ca2b36f1c
--- /dev/null
+++ b/lib/debugger/test/bs_bincomp_SUITE.erl
@@ -0,0 +1,106 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 2007-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%
+%%
+
+%%
+%% Originally based on Per Gustafsson's test suite.
+%%
+
+-module(bs_bincomp_SUITE).
+
+-export([all/1,init_per_testcase/2,fin_per_testcase/2,
+ byte_aligned/1,bit_aligned/1,extended_byte_aligned/1,
+ extended_bit_aligned/1,mixed/1]).
+
+-include("test_server.hrl").
+
+init_per_testcase(_Case, Config) ->
+ test_lib:interpret(?MODULE),
+ Dog = test_server:timetrap(?t:minutes(1)),
+ [{watchdog,Dog}|Config].
+
+fin_per_testcase(_Case, Config) ->
+ Dog = ?config(watchdog, Config),
+ ?t:timetrap_cancel(Dog),
+ ok.
+
+all(suite) ->
+ [byte_aligned,bit_aligned,extended_byte_aligned,
+ extended_bit_aligned,mixed].
+
+
+byte_aligned(Config) when is_list(Config) ->
+ ?line <<"abcdefg">> = << <<(X+32)>> || <<X>> <= <<"ABCDEFG">> >>,
+ ?line <<1:32/little,2:32/little,3:32/little,4:32/little>> =
+ << <<X:32/little>> || <<X:32>> <= <<1:32,2:32,3:32,4:32>> >>,
+ ?line <<1:32/little,2:32/little,3:32/little,4:32/little>> =
+ << <<X:32/little>> || <<X:16>> <= <<1:16,2:16,3:16,4:16>> >>,
+ ok.
+
+bit_aligned(Config) when is_list(Config) ->
+ ?line <<$a:7,$b:7,$c:7,$d:7,$e:7,$f:7,$g:7>> =
+ << <<(X+32):7>> || <<X>> <= <<"ABCDEFG">> >>,
+ ?line <<"ABCDEFG">> =
+ << <<(X-32)>> || <<X:7>> <= <<$a:7,$b:7,$c:7,$d:7,$e:7,$f:7,$g:7>> >>,
+ ?line <<1:31/little,2:31/little,3:31/little,4:31/little>> =
+ << <<X:31/little>> || <<X:31>> <= <<1:31,2:31,3:31,4:31>> >>,
+ ?line <<1:31/little,2:31/little,3:31/little,4:31/little>> =
+ << <<X:31/little>> || <<X:15>> <= <<1:15,2:15,3:15,4:15>> >>,
+ ok.
+
+extended_byte_aligned(Config) when is_list(Config) ->
+ ?line <<"abcdefg">> = << <<(X+32)>> || X <- "ABCDEFG" >>,
+ ?line "abcdefg" = [(X+32) || <<X>> <= <<"ABCDEFG">>],
+ ?line <<1:32/little,2:32/little,3:32/little,4:32/little>> =
+ << <<X:32/little>> || X <- [1,2,3,4] >>,
+ ?line [256,512,768,1024] =
+ [X || <<X:16/little>> <= <<1:16,2:16,3:16,4:16>>],
+ ok.
+
+extended_bit_aligned(Config) when is_list(Config) ->
+ ?line <<$a:7,$b:7,$c:7,$d:7,$e:7,$f:7,$g:7>> =
+ << <<(X+32):7>> || X <- "ABCDEFG" >>,
+ ?line "ABCDEFG" = [(X-32) || <<X:7>> <= <<$a:7,$b:7,$c:7,$d:7,$e:7,$f:7,$g:7>>],
+ ?line <<1:31/little,2:31/little,3:31/little,4:31/little>> =
+ << <<X:31/little>> || X <- [1,2,3,4] >>,
+ ?line [256,512,768,1024] =
+ [X || <<X:15/little>> <= <<1:15,2:15,3:15,4:15>>],
+ ok.
+
+mixed(Config) when is_list(Config) ->
+ ?line <<2,3,3,4,4,5,5,6>> =
+ << <<(X+Y)>> || <<X>> <= <<1,2,3,4>>, <<Y>> <= <<1,2>> >>,
+ ?line <<2,3,3,4,4,5,5,6>> =
+ << <<(X+Y)>> || <<X>> <= <<1,2,3,4>>, Y <- [1,2] >>,
+ ?line <<2,3,3,4,4,5,5,6>> =
+ << <<(X+Y)>> || X <- [1,2,3,4], Y <- [1,2] >>,
+ ?line [2,3,3,4,4,5,5,6] =
+ [(X+Y) || <<X>> <= <<1,2,3,4>>, <<Y>> <= <<1,2>>],
+ ?line [2,3,3,4,4,5,5,6] =
+ [(X+Y) || <<X>> <= <<1,2,3,4>>, Y <- [1,2]],
+ ?line <<2:3,3:3,3:3,4:3,4:3,5:3,5:3,6:3>> =
+ << <<(X+Y):3>> || <<X:3>> <= <<1:3,2:3,3:3,4:3>>, <<Y:3>> <= <<1:3,2:3>> >>,
+ ?line <<2:3,3:3,3:3,4:3,4:3,5:3,5:3,6:3>> =
+ << <<(X+Y):3>> || <<X:3>> <= <<1:3,2:3,3:3,4:3>>, Y <- [1,2] >>,
+ ?line <<2:3,3:3,3:3,4:3,4:3,5:3,5:3,6:3>> =
+ << <<(X+Y):3>> || X <- [1,2,3,4], Y <- [1,2] >>,
+ ?line [2,3,3,4,4,5,5,6] =
+ [(X+Y) || <<X:3>> <= <<1:3,2:3,3:3,4:3>>, <<Y:3>> <= <<1:3,2:3>>],
+ ?line [2,3,3,4,4,5,5,6] =
+ [(X+Y) || <<X:3>> <= <<1:3,2:3,3:3,4:3>>, Y <- [1,2]],
+ ok.
diff --git a/lib/debugger/test/bs_construct_SUITE.erl b/lib/debugger/test/bs_construct_SUITE.erl
new file mode 100644
index 0000000000..efc125c582
--- /dev/null
+++ b/lib/debugger/test/bs_construct_SUITE.erl
@@ -0,0 +1,432 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 2000-2010. All Rights Reserved.
+%%
+%% The contents of this file are subject to the Erlang Public License,
+%% Version 1.1, (the "License"); you may not use this file except in
+%% compliance with the License. You should have received a copy of the
+%% Erlang Public License along with this software. If not, it can be
+%% retrieved online at http://www.erlang.org/.
+%%
+%% Software distributed under the License is distributed on an "AS IS"
+%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+%% the License for the specific language governing rights and limitations
+%% under the License.
+%%
+%% %CopyrightEnd%
+%%
+
+-module(bs_construct_SUITE).
+
+-export([all/1,init_per_testcase/2,fin_per_testcase/2,init_all/1,finish_all/1,
+ test1/1, test2/1, test3/1, test4/1, test5/1, testf/1, not_used/1, in_guard/1,
+ coerce_to_float/1]).
+
+-include("test_server.hrl").
+
+all(suite) ->
+ [{conf,init_all,cases(),finish_all}].
+
+cases() ->
+ [test1, test2, test3, test4, test5, testf,
+ not_used, in_guard, coerce_to_float].
+
+init_per_testcase(_Case, Config) ->
+ test_lib:interpret(?MODULE),
+ Dog = test_server:timetrap(?t:minutes(1)),
+ [{watchdog,Dog}|Config].
+
+fin_per_testcase(_Case, Config) ->
+ Dog = ?config(watchdog, Config),
+ ?t:timetrap_cancel(Dog),
+ ok.
+
+init_all(Config) when is_list(Config) ->
+ ?line test_lib:interpret(?MODULE),
+ ?line true = lists:member(?MODULE, int:interpreted()),
+ ok.
+
+finish_all(Config) when is_list(Config) ->
+ ok.
+
+big(1) ->
+ 57285702734876389752897683.
+
+i(X) -> X.
+
+r(L) ->
+ lists:reverse(L).
+
+-define(T(B, L), {B, ??B, L}).
+-define(N(B), {B, ??B, unknown}).
+
+-define(FAIL(Expr), ?line {'EXIT',{badarg,_}} = (catch Expr)).
+
+l(I_13, I_big1) ->
+ [
+ ?T(<<-43>>,
+ [256-43]),
+ ?T(<<56>>,
+ [56]),
+ ?T(<<1,2>>,
+ [1, 2]),
+ ?T(<<4:4, 7:4>>,
+ [4*16+7]),
+ ?T(<<777:16/big>>,
+ [3, 9]),
+ ?T(<<777:16/little>>,
+ [9, 3]),
+ ?T(<<0.0:32/float>>,
+ [0,0,0,0]),
+ ?T(<<0.125:32/float>>,
+ [62,0,0,0]),
+ ?T(<<0.125:32/little-float>>,
+ [0,0,0,62]),
+ ?T(<<I_big1:32>>,
+ [138, 99, 0, 147]),
+ ?T(<<57285702734876389752897684:32>>,
+ [138, 99, 0, 148]),
+ ?T(<<I_big1:32/little>>,
+ r([138, 99, 0, 147])),
+ ?T(<<-1:17/unit:8>>,
+ lists:duplicate(17, 255)),
+
+ ?T(<<I_13>>,
+ [13]),
+
+ ?T(<<4:8/unit:2,5:2/unit:8>>,
+ [0, 4, 0, 5]),
+
+ ?T(<<1:1, 0:6, 1:1>>,
+ [129]),
+ ?T(<<1:1/little, 0:6/little, 1:1/little>>,
+ [129]),
+
+ ?T(<<<<1,2>>/binary>>,
+ [1, 2]),
+ ?T(<<<<1,2>>:1/binary>>,
+ [1]),
+ ?T(<<4,3,<<1,2>>:1/binary>>,
+ [4,3,1]),
+
+ ?T(<<(256*45+47)>>,
+ [47]),
+
+ ?T(<<57:0>>,
+ []),
+
+ ?T(<<"apa">>,
+ "apa"),
+
+ ?T(<<1:3,"string",9:5>>,
+ [46,110,142,77,45,204,233]),
+
+ ?T(<<>>,
+ []),
+
+ ?T(<<37.98:64/native-float>>,
+ native_3798()),
+
+ ?T(<<32978297842987249827298387697777669766334937:128/native-integer>>,
+ native_bignum())
+
+ ].
+
+native_3798() ->
+ case <<1:16/native>> of
+ <<0,1>> -> [64,66,253,112,163,215,10,61];
+ <<1,0>> -> [61,10,215,163,112,253,66,64]
+ end.
+
+native_bignum() ->
+ case <<1:16/native>> of
+ <<0,1>> -> [129,205,18,177,1,213,170,101,39,231,109,128,176,11,73,217];
+ <<1,0>> -> [217,73,11,176,128,109,231,39,101,170,213,1,177,18,205,129]
+ end.
+
+evaluate(Str, Vars) ->
+ {ok,Tokens,_} =
+ erl_scan:string(Str ++ " . "),
+ {ok, [Expr]} = erl_parse:parse_exprs(Tokens),
+ case erl_eval:expr(Expr, Vars) of
+ {value, Result, _} ->
+ Result
+ end.
+
+eval_list([], _Vars) ->
+ [];
+eval_list([{C_bin, Str, Bytes} | Rest], Vars) ->
+ case catch evaluate(Str, Vars) of
+ {'EXIT', Error} ->
+ io:format("Evaluation error: ~p, ~p, ~p~n", [Str, Vars, Error]),
+ exit(Error);
+ E_bin ->
+ [{C_bin, E_bin, Str, Bytes} | eval_list(Rest, Vars)]
+ end.
+
+one_test({C_bin, E_bin, Str, Bytes}) when list(Bytes) ->
+ io:format(" ~s, ~p~n", [Str, Bytes]),
+ Bin = list_to_binary(Bytes),
+ if
+ C_bin == Bin ->
+ ok;
+ true ->
+ io:format("ERROR: Compiled: ~p. Expected ~p. Got ~p.~n",
+ [Str, Bytes, binary_to_list(C_bin)]),
+ test_server:fail(comp)
+ end,
+ if
+ E_bin == Bin ->
+ ok;
+ true ->
+ io:format("ERROR: Interpreted: ~p. Expected ~p. Got ~p.~n",
+ [Str, Bytes, binary_to_list(E_bin)]),
+ test_server:fail(comp)
+ end;
+one_test({C_bin, E_bin, Str, Result}) ->
+ io:format(" ~s ~p~n", [Str, C_bin]),
+ if
+ C_bin == E_bin ->
+ ok;
+ true ->
+ Arbitrary = case Result of
+ unknown ->
+ size(C_bin);
+ _ ->
+ Result
+ end,
+ case equal_lists(binary_to_list(C_bin),
+ binary_to_list(E_bin),
+ Arbitrary) of
+ false ->
+ io:format("ERROR: Compiled not equal to interpreted:"
+ "~n ~p, ~p.~n",
+ [binary_to_list(C_bin), binary_to_list(E_bin)]),
+ test_server:fail(comp);
+ 0 ->
+ ok;
+ %% For situations where the final bits may not matter, like
+ %% for floats:
+ N when integer(N) ->
+ io:format("Info: compiled and interpreted differ in the"
+ " last bytes:~n ~p, ~p.~n",
+ [binary_to_list(C_bin), binary_to_list(E_bin)]),
+ ok
+ end
+ end.
+
+equal_lists([], [], _) ->
+ 0;
+equal_lists([], _, _) ->
+ false;
+equal_lists(_, [], _) ->
+ false;
+equal_lists([A|AR], [A|BR], R) ->
+ equal_lists(AR, BR, R);
+equal_lists(A, B, R) ->
+ if
+ length(A) /= length(B) ->
+ false;
+ length(A) =< R ->
+ R;
+ true ->
+ false
+ end.
+
+%%% Simple working cases
+test1(suite) -> [];
+test1(Config) when list(Config) ->
+ ?line I_13 = i(13),
+ ?line I_big1 = big(1),
+ ?line Vars = [{'I_13', I_13},
+ {'I_big1', I_big1}],
+ ?line lists:foreach(fun one_test/1, eval_list(l(I_13, I_big1), Vars)).
+
+%%% Misc
+
+%%% <<A:S, A:(N-S)>>
+comp(N, A, S) ->
+ M1 = (1 bsl S) - 1,
+ M2 = (1 bsl (N-S)) - 1,
+ [((A band M1) bsl (N-S)) bor (A band M2)].
+
+gen(N, S, A) ->
+ [?T(<<A:S, A:(N-S)>>, comp(N, A, S))].
+
+gen_l(N, S, A) ->
+ [?T(<<A:S/little, A:(N-S)/little>>, comp(N, A, S))].
+
+test2(suite) -> [];
+test2(Config) when list(Config) ->
+ ?line test2(0, 8, 2#10101010101010101),
+ ?line test2(0, 8, 2#1111111111).
+
+test2(End, End, _) ->
+ ok;
+test2(I, End, A) ->
+ test2(I, A),
+ test2(I+1, End, A).
+
+test2(S, A) ->
+ N = 8,
+ Vars = [{'A',A}, {'N',N}, {'S',S}],
+ io:format("Vars: ~p\n", [Vars]),
+ lists:foreach(fun one_test/1, eval_list(gen(N, S, A), Vars)),
+ lists:foreach(fun one_test/1, eval_list(gen_l(N, S, A), Vars)).
+
+%%% Tests without facit
+
+t3() ->
+ [?N(<<4711:13, 9876:13, 3:6>>),
+ ?N(<<4.57:64/float>>),
+ ?N(<<4.57:32/float>>),
+
+ ?N(<<>>)
+ ].
+
+test3(suite) -> [];
+test3(Config) when list(Config) ->
+ ?line Vars = [],
+ ?line lists:foreach(fun one_test/1, eval_list(t3(), Vars)).
+
+gen_u(N, S, A) ->
+ [?N(<<A:S, A:(N-S)>>)].
+
+gen_u_l(N, S, A) ->
+ [?N(<<A:S/little, A:(N-S)/little>>)].
+
+test4(suite) -> [];
+test4(Config) when list(Config) ->
+ ?line test4(0, 16, 2#10101010101010101),
+ ?line test4(0, 16, 2#1111111111).
+
+test4(End, End, _) ->
+ ok;
+test4(I, End, A) ->
+ test4(I, A),
+ test4(I+1, End, A).
+
+test4(S, A) ->
+ N = 16,
+ Vars = [{'A', A}, {'N', 16}, {'S', S}],
+ lists:foreach(fun one_test/1, eval_list(gen_u(N, S, A), Vars)),
+ lists:foreach(fun one_test/1, eval_list(gen_u_l(N, S, A), Vars)).
+
+gen_b(N, S, A) ->
+ [?T(<<A:S/binary-unit:1, A:(N-S)/binary-unit:1>>,
+ binary_to_list(<<A:S/binary-unit:1, A:(N-S)/binary-unit:1>>))].
+
+test5(suite) -> [];
+test5(doc) -> ["OTP-3995"];
+test5(Config) when list(Config) ->
+ ?line test5(0, 8, <<73>>),
+ ?line test5(0, 8, <<68>>).
+
+test5(End, End, _) ->
+ ok;
+test5(I, End, A) ->
+ test5(I, A),
+ test5(I+1, End, A).
+
+test5(S, A) ->
+ N = 8,
+ Vars = [{'A', A}, {'N', 8}, {'S', S}],
+ lists:foreach(fun one_test/1, eval_list(gen_b(N, S, A), Vars)).
+
+%%% Failure cases
+testf(suite) -> [];
+testf(Config) when list(Config) ->
+ ?FAIL(<<3.14>>),
+ ?FAIL(<<<<1,2>>>>),
+
+ ?FAIL(<<2.71/binary>>),
+ ?FAIL(<<24334/binary>>),
+ ?FAIL(<<24334344294788947129487129487219847/binary>>),
+
+ ?FAIL(<<<<1,2,3>>/float>>),
+
+ %% Negative field widths.
+ testf_1(-8, <<1,2,3,4,5>>),
+
+ ?FAIL(<<42:(-16)>>),
+ ?FAIL(<<3.14:(-8)/float>>),
+ ?FAIL(<<<<23,56,0,2>>:(-16)/binary>>),
+ ?FAIL(<<<<23,56,0,2>>:(2.5)/binary>>),
+ ?FAIL(<<<<23,56,0,2>>:(anka)>>),
+
+ ok.
+
+testf_1(W, B) ->
+ ?FAIL(<<42:W>>),
+ ?FAIL(<<3.14:W/float>>),
+ ?FAIL(<<B:W/binary>>).
+
+not_used(doc) ->
+ "Test that constructed binaries that are not used will still give an exception.";
+not_used(Config) when is_list(Config) ->
+ ?line ok = not_used1(3, <<"dum">>),
+ ?line ?FAIL(not_used1(3, "dum")),
+ ?line ?FAIL(not_used2(444, -2)),
+ ?line ?FAIL(not_used2(444, anka)),
+ ?line ?FAIL(not_used3(444)),
+ ok.
+
+not_used1(I, BinString) ->
+ <<I:32,BinString/binary>>,
+ ok.
+
+not_used2(I, Sz) ->
+ <<I:Sz>>,
+ ok.
+
+not_used3(I) ->
+ <<I:(-8)>>,
+ ok.
+
+in_guard(Config) when list(Config) ->
+ ?line 1 = in_guard(<<16#74ad:16>>, 16#e95, 5),
+ ?line 2 = in_guard(<<16#3A,16#F7,"hello">>, 16#3AF7, <<"hello">>),
+ ?line 3 = in_guard(<<16#FBCD:14,3.1415/float,3:2>>, 16#FBCD, 3.1415),
+ nope = in_guard(<<1>>, 42, b),
+ nope = in_guard(<<1>>, a, b),
+ nope = in_guard(<<1,2>>, 1, 1),
+ nope = in_guard(<<4,5>>, 1, 2.71),
+ nope = in_guard(<<4,5>>, 1, <<12,13>>),
+ ok.
+
+in_guard(Bin, A, B) when <<A:13,B:3>> == Bin -> 1;
+in_guard(Bin, A, B) when <<A:16,B/binary>> == Bin -> 2;
+in_guard(Bin, A, B) when <<A:14,B/float,3:2>> == Bin -> 3;
+in_guard(Bin, A, B) when {a,b,<<A:14,B/float,3:2>>} == Bin -> cant_happen;
+in_guard(_, _, _) -> nope.
+
+-define(COF(Int0),
+ ?line (fun(Int) ->
+ true = <<Int:32/float>> =:= <<(float(Int)):32/float>>,
+ true = <<Int:64/float>> =:= <<(float(Int)):64/float>>
+ end)(nonliteral(Int0)),
+ ?line true = <<Int0:32/float>> =:= <<(float(Int0)):32/float>>,
+ ?line true = <<Int0:64/float>> =:= <<(float(Int0)):64/float>>).
+
+-define(COF64(Int0),
+ ?line (fun(Int) ->
+ true = <<Int:64/float>> =:= <<(float(Int)):64/float>>
+ end)(nonliteral(Int0)),
+ ?line true = <<Int0:64/float>> =:= <<(float(Int0)):64/float>>).
+
+nonliteral(X) -> X.
+
+coerce_to_float(Config) when list(Config) ->
+ ?COF(0),
+ ?COF(-1),
+ ?COF(1),
+ ?COF(42),
+ ?COF(255),
+ ?COF(-255),
+ ?COF(38474),
+ ?COF(387498738948729893849444444443),
+ ?COF(-37489378937773899999999999999993),
+ ?COF64(298748888888888888888888888883478264866528467367364766666666666666663),
+ ?COF64(-367546729879999999999947826486652846736736476555566666663),
+ ok.
diff --git a/lib/debugger/test/bs_match_bin_SUITE.erl b/lib/debugger/test/bs_match_bin_SUITE.erl
new file mode 100644
index 0000000000..3966dc41ef
--- /dev/null
+++ b/lib/debugger/test/bs_match_bin_SUITE.erl
@@ -0,0 +1,114 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 2000-2010. All Rights Reserved.
+%%
+%% The contents of this file are subject to the Erlang Public License,
+%% Version 1.1, (the "License"); you may not use this file except in
+%% compliance with the License. You should have received a copy of the
+%% Erlang Public License along with this software. If not, it can be
+%% retrieved online at http://www.erlang.org/.
+%%
+%% Software distributed under the License is distributed on an "AS IS"
+%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+%% the License for the specific language governing rights and limitations
+%% under the License.
+%%
+%% %CopyrightEnd%
+%%
+
+
+-module(bs_match_bin_SUITE).
+
+-author('[email protected]').
+-export([all/1,init_per_testcase/2,fin_per_testcase/2,init_all/1,finish_all/1,
+ byte_split_binary/1,bit_split_binary/1]).
+
+-include("test_server.hrl").
+
+all(suite) ->
+ [{conf,init_all,cases(),finish_all}].
+
+cases() ->
+ [byte_split_binary,bit_split_binary].
+
+init_per_testcase(_Case, Config) ->
+ test_lib:interpret(?MODULE),
+ Dog = test_server:timetrap(?t:minutes(1)),
+ [{watchdog,Dog}|Config].
+
+fin_per_testcase(_Case, Config) ->
+ Dog = ?config(watchdog, Config),
+ ?t:timetrap_cancel(Dog),
+ ok.
+
+init_all(Config) when is_list(Config) ->
+ ?line test_lib:interpret(?MODULE),
+ ?line true = lists:member(?MODULE, int:interpreted()),
+ ok.
+
+finish_all(Config) when is_list(Config) ->
+ ok.
+
+byte_split_binary(doc) -> "Tries to split a binary at all byte-aligned positions.";
+byte_split_binary(suite) -> [];
+byte_split_binary(Config) when list(Config) ->
+ ?line L = lists:seq(0, 57),
+ ?line B = mkbin(L),
+ ?line byte_split(L, B, size(B)).
+
+byte_split(L, B, Pos) when Pos >= 0 ->
+ ?line Sz1 = Pos,
+ ?line Sz2 = size(B) - Pos,
+ ?line <<B1:Sz1/binary,B2:Sz2/binary>> = B,
+ ?line B1 = list_to_binary(lists:sublist(L, 1, Pos)),
+ ?line B2 = list_to_binary(lists:nthtail(Pos, L)),
+ ?line byte_split(L, B, Pos-1);
+byte_split(_L, _B, _) -> ok.
+
+bit_split_binary(doc) -> "Tries to split a binary at all positions.";
+bit_split_binary(suite) -> [];
+bit_split_binary(Config) when list(Config) ->
+ Fun = fun(Bin, List, SkipBef, N) ->
+ ?line SkipAft = 8*size(Bin) - N - SkipBef,
+ io:format("~p, ~p, ~p", [SkipBef,N,SkipAft]),
+ ?line <<_I1:SkipBef,OutBin:N/binary-unit:1,_I2:SkipAft>> = Bin,
+ ?line OutBin = make_bin_from_list(List, N)
+ end,
+ ?line bit_split_binary1(Fun, erlang:md5(<<1,2,3>>)),
+ ok.
+
+bit_split_binary1(Action, Bin) ->
+ BitList = bits_to_list(binary_to_list(Bin), 16#80),
+ bit_split_binary2(Action, Bin, BitList, 0).
+
+bit_split_binary2(Action, Bin, [_|T]=List, Bef) ->
+ bit_split_binary3(Action, Bin, List, Bef, size(Bin)*8),
+ bit_split_binary2(Action, Bin, T, Bef+1);
+bit_split_binary2(_Action, _Bin, [], _Bef) -> ok.
+
+bit_split_binary3(Action, Bin, List, Bef, Aft) when Bef =< Aft ->
+ Action(Bin, List, Bef, (Aft-Bef) div 8 * 8),
+ bit_split_binary3(Action, Bin, List, Bef, Aft-8);
+bit_split_binary3(_, _, _, _, _) -> ok.
+
+make_bin_from_list(_List, 0) ->
+ mkbin([]);
+make_bin_from_list(List, N) ->
+ list_to_binary([make_int(List, 8, 0),
+ make_bin_from_list(lists:nthtail(8, List), N-8)]).
+
+
+make_int(_List, 0, Acc) -> Acc;
+make_int([H|T], N, Acc) -> make_int(T, N-1, Acc bsl 1 bor H).
+
+bits_to_list([_H|T], 0) -> bits_to_list(T, 16#80);
+bits_to_list([H|_]=List, Mask) ->
+ [case H band Mask of
+ 0 -> 0;
+ _ -> 1
+ end|bits_to_list(List, Mask bsr 1)];
+bits_to_list([], _) -> [].
+
+
+mkbin(L) when list(L) -> list_to_binary(L).
diff --git a/lib/debugger/test/bs_match_int_SUITE.erl b/lib/debugger/test/bs_match_int_SUITE.erl
new file mode 100644
index 0000000000..1159ac9ef8
--- /dev/null
+++ b/lib/debugger/test/bs_match_int_SUITE.erl
@@ -0,0 +1,230 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 2000-2010. All Rights Reserved.
+%%
+%% The contents of this file are subject to the Erlang Public License,
+%% Version 1.1, (the "License"); you may not use this file except in
+%% compliance with the License. You should have received a copy of the
+%% Erlang Public License along with this software. If not, it can be
+%% retrieved online at http://www.erlang.org/.
+%%
+%% Software distributed under the License is distributed on an "AS IS"
+%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+%% the License for the specific language governing rights and limitations
+%% under the License.
+%%
+%% %CopyrightEnd%
+%%
+
+-module(bs_match_int_SUITE).
+
+-author('[email protected]').
+-export([all/1,init_per_testcase/2,fin_per_testcase/2,init_all/1,finish_all/1,
+ integer/1,signed_integer/1,dynamic/1,more_dynamic/1,mml/1]).
+
+-include("test_server.hrl").
+
+-import(lists, [seq/2]).
+
+all(suite) ->
+ [{conf,init_all,cases(),finish_all}].
+
+cases() ->
+ [integer,signed_integer,dynamic,more_dynamic,mml].
+
+init_per_testcase(_Case, Config) ->
+ test_lib:interpret(?MODULE),
+ Dog = test_server:timetrap(?t:minutes(4)),
+ [{watchdog,Dog}|Config].
+
+fin_per_testcase(_Case, Config) ->
+ Dog = ?config(watchdog, Config),
+ ?t:timetrap_cancel(Dog),
+ ok.
+
+init_all(Config) when is_list(Config) ->
+ ?line test_lib:interpret(?MODULE),
+ ?line true = lists:member(?MODULE, int:interpreted()),
+ ok.
+
+finish_all(Config) when is_list(Config) ->
+ ok.
+
+integer(suite) -> [];
+integer(Config) when list(Config) ->
+ ?line 0 = get_int(mkbin([])),
+ ?line 0 = get_int(mkbin([0])),
+ ?line 42 = get_int(mkbin([42])),
+ ?line 255 = get_int(mkbin([255])),
+ ?line 256 = get_int(mkbin([1,0])),
+ ?line 257 = get_int(mkbin([1,1])),
+ ?line 258 = get_int(mkbin([1,2])),
+ ?line 258 = get_int(mkbin([1,2])),
+ ?line 65534 = get_int(mkbin([255,254])),
+ ?line 16776455 = get_int(mkbin([255,253,7])),
+ ?line 4245492555 = get_int(mkbin([253,13,19,75])),
+ ?line Eight = [200,1,19,128,222,42,97,111],
+ ?line cmp128(Eight, uint(Eight)),
+ ?line fun_clause(catch get_int(mkbin(seq(1,5)))),
+ ok.
+
+get_int(<<I:0>>) -> I;
+get_int(<<I:8>>) -> I;
+get_int(<<I:16>>) -> I;
+get_int(<<I:24>>) -> I;
+get_int(<<I:32>>) -> I.
+
+cmp128(<<I:128>>, I) -> equal;
+cmp128(_B, _I) -> not_equal.
+
+signed_integer(suite) -> [];
+signed_integer(Config) when list(Config) ->
+ ?line {no_match,_} = sint(mkbin([])),
+ ?line {no_match,_} = sint(mkbin([1,2,3])),
+ ?line 127 = sint(mkbin([127])),
+ ?line -1 = sint(mkbin([255])),
+ ?line -128 = sint(mkbin([128])),
+ ?line 42 = sint(mkbin([42,255])),
+ ?line 127 = sint(mkbin([127,255])).
+
+sint(Bin) ->
+ case Bin of
+ <<I:8/signed>> -> I;
+ <<I:8/signed,_:3,_:5>> -> I;
+ Other -> {no_match,Other}
+ end.
+
+uint(L) -> uint(L, 0).
+uint([H|T], Acc) -> uint(T, Acc bsl 8 bor H);
+uint([], Acc) -> Acc.
+
+dynamic(Config) when list(Config) ->
+ dynamic(mkbin([255]), 8),
+ dynamic(mkbin([255,255]), 16),
+ dynamic(mkbin([255,255,255]), 24),
+ dynamic(mkbin([255,255,255,255]), 32),
+ ok.
+
+dynamic(Bin, S1) when S1 >= 0 ->
+ S2 = size(Bin) * 8 - S1,
+ dynamic(Bin, S1, S2, (1 bsl S1) - 1, (1 bsl S2) - 1),
+ dynamic(Bin, S1-1);
+dynamic(_Bin, _) -> ok.
+
+dynamic(Bin, S1, S2, A, B) ->
+% io:format("~p ~p ~p ~p\n", [S1,S2,A,B]),
+ case Bin of
+ <<A:S1,B:S2>> ->
+ io:format("~p ~p ~p ~p\n", [S1,S2,A,B]),
+ ok;
+ _Other ->
+ erlang:error(badmatch, [Bin,S1,S2,A,B])
+ end.
+
+more_dynamic(doc) -> "Extract integers at different alignments and of different sizes.";
+more_dynamic(Config) when list(Config) ->
+
+ % Unsigned big-endian numbers.
+ Unsigned = fun(Bin, List, SkipBef, N) ->
+ SkipAft = 8*size(Bin) - N - SkipBef,
+ <<_I1:SkipBef,Int:N,_I2:SkipAft>> = Bin,
+ Int = make_int(List, N, 0)
+ end,
+ ?line more_dynamic1(Unsigned, funny_binary(42)),
+
+ % Signed big-endian numbers.
+ Signed = fun(Bin, List, SkipBef, N) ->
+ SkipAft = 8*size(Bin) - N - SkipBef,
+ <<_I1:SkipBef,Int:N/signed,_I2:SkipAft>> = Bin,
+ case make_signed_int(List, N) of
+ Int -> ok;
+ Other ->
+ io:format("Bin = ~p,", [Bin]),
+ io:format("SkipBef = ~p, N = ~p", [SkipBef,N]),
+ io:format("Expected ~p, got ~p", [Int,Other]),
+ ?t:fail()
+ end
+ end,
+ ?line more_dynamic1(Signed, funny_binary(43)),
+
+ % Unsigned little-endian numbers.
+ UnsLittle = fun(Bin, List, SkipBef, N) ->
+ SkipAft = 8*size(Bin) - N - SkipBef,
+ <<_I1:SkipBef,Int:N/little,_I2:SkipAft>> = Bin,
+ Int = make_int(big_to_little(List, N), N, 0)
+ end,
+ ?line more_dynamic1(UnsLittle, funny_binary(44)),
+
+ % Signed little-endian numbers.
+ SignLittle = fun(Bin, List, SkipBef, N) ->
+ SkipAft = 8*size(Bin) - N - SkipBef,
+ <<_I1:SkipBef,Int:N/signed-little,_I2:SkipAft>> = Bin,
+ Little = big_to_little(List, N),
+ Int = make_signed_int(Little, N)
+ end,
+ ?line more_dynamic1(SignLittle, funny_binary(45)),
+
+ ok.
+
+funny_binary(N) ->
+ B0 = erlang:md5([N]),
+ {B1,_B2} = split_binary(B0, size(B0) div 2),
+ B1.
+
+more_dynamic1(Action, Bin) ->
+ BitList = bits_to_list(binary_to_list(Bin), 16#80),
+ more_dynamic2(Action, Bin, BitList, 0).
+
+more_dynamic2(Action, Bin, [_|T]=List, Bef) ->
+ more_dynamic3(Action, Bin, List, Bef, size(Bin)*8),
+ more_dynamic2(Action, Bin, T, Bef+1);
+more_dynamic2(_Action, _Bin, [], _Bef) -> ok.
+
+more_dynamic3(Action, Bin, List, Bef, Aft) when Bef =< Aft ->
+%% io:format("~p, ~p", [Bef,Aft-Bef]),
+ Action(Bin, List, Bef, Aft-Bef),
+ more_dynamic3(Action, Bin, List, Bef, Aft-1);
+more_dynamic3(_, _, _, _, _) -> ok.
+
+big_to_little(List, N) -> big_to_little(List, N, []).
+
+big_to_little([B0,B1,B2,B3,B4,B5,B6,B7|T], N, Acc) when N >= 8 ->
+ big_to_little(T, N-8, [B0,B1,B2,B3,B4,B5,B6,B7|Acc]);
+big_to_little(List, N, Acc) -> lists:sublist(List, 1, N) ++ Acc.
+
+make_signed_int(_List, 0) -> 0;
+make_signed_int([0|_T]=List, N) -> make_int(List, N, 0);
+make_signed_int([1|_T]=List0, N) ->
+ List1 = reversed_sublist(List0, N, []),
+ List2 = two_complement_and_reverse(List1, 1, []),
+ -make_int(List2, length(List2), 0).
+
+reversed_sublist(_List, 0, Acc) -> Acc;
+reversed_sublist([H|T], N, Acc) -> reversed_sublist(T, N-1, [H|Acc]).
+
+two_complement_and_reverse([H|T], Carry, Acc) ->
+ Sum = 1-H+Carry,
+ two_complement_and_reverse(T, Sum div 2, [Sum rem 2|Acc]);
+two_complement_and_reverse([], Carry, Acc) -> [Carry|Acc].
+
+make_int(_List, 0, Acc) -> Acc;
+make_int([H|T], N, Acc) -> make_int(T, N-1, Acc bsl 1 bor H).
+
+bits_to_list([_H|T], 0) -> bits_to_list(T, 16#80);
+bits_to_list([H|_]=List, Mask) ->
+ [case H band Mask of
+ 0 -> 0;
+ _ -> 1
+ end|bits_to_list(List, Mask bsr 1)];
+bits_to_list([], _) -> [].
+
+fun_clause({'EXIT',{function_clause,_}}) -> ok.
+mkbin(L) when list(L) -> list_to_binary(L).
+
+mml(Config) when list(Config) ->
+ ?line single_byte_binary = mml_choose(<<42>>),
+ ?line multi_byte_binary = mml_choose(<<42,43>>).
+
+mml_choose(<<_A:8>>) -> single_byte_binary;
+mml_choose(<<_A:8, _T/binary>>) -> multi_byte_binary.
diff --git a/lib/debugger/test/bs_match_misc_SUITE.erl b/lib/debugger/test/bs_match_misc_SUITE.erl
new file mode 100644
index 0000000000..5e1160a8e9
--- /dev/null
+++ b/lib/debugger/test/bs_match_misc_SUITE.erl
@@ -0,0 +1,152 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 2000-2010. All Rights Reserved.
+%%
+%% The contents of this file are subject to the Erlang Public License,
+%% Version 1.1, (the "License"); you may not use this file except in
+%% compliance with the License. You should have received a copy of the
+%% Erlang Public License along with this software. If not, it can be
+%% retrieved online at http://www.erlang.org/.
+%%
+%% Software distributed under the License is distributed on an "AS IS"
+%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+%% the License for the specific language governing rights and limitations
+%% under the License.
+%%
+%% %CopyrightEnd%
+%%
+
+-module(bs_match_misc_SUITE).
+
+-author('[email protected]').
+-export([all/1,init_per_testcase/2,fin_per_testcase/2,init_all/1,finish_all/1,
+ bound_var/1,bound_tail/1,t_float/1,little_float/1,sean/1]).
+
+-include("test_server.hrl").
+
+all(suite) ->
+ [{conf,init_all,cases(),finish_all}].
+
+cases() ->
+ [bound_var,bound_tail,t_float,little_float,sean].
+
+init_per_testcase(_Case, Config) ->
+ test_lib:interpret(?MODULE),
+ Dog = test_server:timetrap(?t:minutes(1)),
+ [{watchdog,Dog}|Config].
+
+fin_per_testcase(_Case, Config) ->
+ Dog = ?config(watchdog, Config),
+ ?t:timetrap_cancel(Dog),
+ ok.
+
+init_all(Config) when is_list(Config) ->
+ ?line test_lib:interpret(?MODULE),
+ ?line true = lists:member(?MODULE, int:interpreted()),
+ ok.
+
+finish_all(Config) when is_list(Config) ->
+ ok.
+
+bound_var(doc) -> "Test matching of bound variables.";
+bound_var(Config) when list(Config) ->
+ ?line ok = bound_var(42, 13, <<42,13>>),
+ ?line nope = bound_var(42, 13, <<42,255>>),
+ ?line nope = bound_var(42, 13, <<154,255>>),
+ ok.
+
+bound_var(A, B, <<A:8,B:8>>) -> ok;
+bound_var(_, _, _) -> nope.
+
+bound_tail(doc) -> "Test matching of a bound tail.";
+bound_tail(Config) when list(Config) ->
+ ?line ok = bound_tail(<<>>, <<13,14>>),
+ ?line ok = bound_tail(<<2,3>>, <<1,1,2,3>>),
+ ?line nope = bound_tail(<<2,3>>, <<1,1,2,7>>),
+ ?line nope = bound_tail(<<2,3>>, <<1,1,2,3,4>>),
+ ?line nope = bound_tail(<<2,3>>, <<>>),
+ ok.
+
+bound_tail(T, <<_:16,T/binary>>) -> ok;
+bound_tail(_, _) -> nope.
+
+t_float(Config) when list(Config) ->
+ F = f1(),
+ G = f_one(),
+
+ ?line G = match_float(<<63,128,0,0>>, 32, 0),
+ ?line G = match_float(<<63,240,0,0,0,0,0,0>>, 64, 0),
+
+ ?line fcmp(F, match_float(<<F:32/float>>, 32, 0)),
+ ?line fcmp(F, match_float(<<F:64/float>>, 64, 0)),
+ ?line fcmp(F, match_float(<<1:1,F:32/float,127:7>>, 32, 1)),
+ ?line fcmp(F, match_float(<<1:1,F:64/float,127:7>>, 64, 1)),
+ ?line fcmp(F, match_float(<<1:13,F:32/float,127:3>>, 32, 13)),
+ ?line fcmp(F, match_float(<<1:13,F:64/float,127:3>>, 64, 13)),
+ ok.
+
+
+fcmp(F1, F2) when (F1 - F2) / F2 < 0.0000001 -> ok.
+
+match_float(Bin0, Fsz, I) ->
+ Bin = make_sub_bin(Bin0),
+ Bsz = size(Bin) * 8,
+ Tsz = Bsz - Fsz - I,
+ <<_:I,F:Fsz/float,_:Tsz>> = Bin,
+ F.
+
+little_float(Config) when list(Config) ->
+ F = f2(),
+ G = f_one(),
+
+ ?line G = match_float_little(<<0,0,0,0,0,0,240,63>>, 64, 0),
+ ?line G = match_float_little(<<0,0,128,63>>, 32, 0),
+
+ ?line fcmp(F, match_float_little(<<F:32/float-little>>, 32, 0)),
+ ?line fcmp(F, match_float_little(<<F:64/float-little>>, 64, 0)),
+ ?line fcmp(F, match_float_little(<<1:1,F:32/float-little,127:7>>, 32, 1)),
+ ?line fcmp(F, match_float_little(<<1:1,F:64/float-little,127:7>>, 64, 1)),
+ ?line fcmp(F, match_float_little(<<1:13,F:32/float-little,127:3>>, 32, 13)),
+ ?line fcmp(F, match_float_little(<<1:13,F:64/float-little,127:3>>, 64, 13)),
+
+ ok.
+
+match_float_little(Bin0, Fsz, I) ->
+ Bin = make_sub_bin(Bin0),
+ Bsz = size(Bin) * 8,
+ Tsz = Bsz - Fsz - I,
+ <<_:I,F:Fsz/float-little,_:Tsz>> = Bin,
+ F.
+
+
+make_sub_bin(Bin0) ->
+ Sz = size(Bin0),
+ Bin1 = <<37,Bin0/binary,38,39>>,
+ <<_:8,Bin:Sz/binary,_:8,_:8>> = Bin1,
+ Bin.
+
+f1() ->
+ 3.1415.
+
+f2() ->
+ 2.7133.
+
+f_one() ->
+ 1.0.
+
+sean(Config) when list(Config) ->
+ ?line small = sean1(<<>>),
+ ?line small = sean1(<<1>>),
+ ?line small = sean1(<<1,2>>),
+ ?line small = sean1(<<1,2,3>>),
+ ?line large = sean1(<<1,2,3,4>>),
+
+ ?line small = sean1(<<4>>),
+ ?line small = sean1(<<4,5>>),
+ ?line small = sean1(<<4,5,6>>),
+ ?line {'EXIT',{function_clause,_}} = (catch sean1(<<4,5,6,7>>)),
+ ok.
+
+sean1(<<B/binary>>) when size(B) < 4 -> small;
+sean1(<<1, _B/binary>>) -> large.
diff --git a/lib/debugger/test/bs_match_tail_SUITE.erl b/lib/debugger/test/bs_match_tail_SUITE.erl
new file mode 100644
index 0000000000..7fa16b3c6a
--- /dev/null
+++ b/lib/debugger/test/bs_match_tail_SUITE.erl
@@ -0,0 +1,106 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 2000-2010. All Rights Reserved.
+%%
+%% The contents of this file are subject to the Erlang Public License,
+%% Version 1.1, (the "License"); you may not use this file except in
+%% compliance with the License. You should have received a copy of the
+%% Erlang Public License along with this software. If not, it can be
+%% retrieved online at http://www.erlang.org/.
+%%
+%% Software distributed under the License is distributed on an "AS IS"
+%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+%% the License for the specific language governing rights and limitations
+%% under the License.
+%%
+%% %CopyrightEnd%
+%%
+
+-module(bs_match_tail_SUITE).
+
+-author('[email protected]').
+-export([all/1,init_per_testcase/2,fin_per_testcase/2,init_all/1,finish_all/1,
+ aligned/1,unaligned/1,zero_tail/1]).
+
+-include("test_server.hrl").
+
+all(suite) ->
+ [{conf,init_all,cases(),finish_all}].
+
+cases() ->
+ [aligned,unaligned,zero_tail].
+
+init_per_testcase(_Case, Config) ->
+ test_lib:interpret(?MODULE),
+ Dog = test_server:timetrap(?t:minutes(1)),
+ [{watchdog,Dog}|Config].
+
+fin_per_testcase(_Case, Config) ->
+ Dog = ?config(watchdog, Config),
+ ?t:timetrap_cancel(Dog),
+ ok.
+
+init_all(Config) when is_list(Config) ->
+ ?line test_lib:interpret(?MODULE),
+ ?line true = lists:member(?MODULE, int:interpreted()),
+ ok.
+
+finish_all(Config) when is_list(Config) ->
+ ok.
+
+aligned(doc) -> "Test aligned tails.";
+aligned(Config) when list(Config) ->
+ ?line Tail1 = mkbin([]),
+ ?line {258,Tail1} = al_get_tail_used(mkbin([1,2])),
+ ?line Tail2 = mkbin(lists:seq(1, 127)),
+ ?line {35091,Tail2} = al_get_tail_used(mkbin([137,19|Tail2])),
+
+ ?line 64896 = al_get_tail_unused(mkbin([253,128])),
+ ?line 64895 = al_get_tail_unused(mkbin([253,127|lists:seq(42, 255)])),
+
+ ?line Tail3 = mkbin(lists:seq(0, 19)),
+ ?line {0,Tail1} = get_dyn_tail_used(Tail1, 0),
+ ?line {0,Tail3} = get_dyn_tail_used(mkbin([Tail3]), 0),
+ ?line {73,Tail3} = get_dyn_tail_used(mkbin([73|Tail3]), 8),
+
+ ?line 0 = get_dyn_tail_unused(mkbin([]), 0),
+ ?line 233 = get_dyn_tail_unused(mkbin([233]), 8),
+ ?line 23 = get_dyn_tail_unused(mkbin([23,22,2]), 8),
+ ok.
+
+al_get_tail_used(<<A:16,T/binary>>) -> {A,T}.
+al_get_tail_unused(<<A:16,_T/binary>>) -> A.
+
+unaligned(doc) -> "Test that an non-aligned tail cannot be matched out.";
+unaligned(Config) when list(Config) ->
+ ?line {'EXIT',{function_clause,_}} = (catch get_tail_used(mkbin([42]))),
+ ?line {'EXIT',{{badmatch,_},_}} = (catch get_dyn_tail_used(mkbin([137]), 3)),
+ ?line {'EXIT',{function_clause,_}} = (catch get_tail_unused(mkbin([42,33]))),
+ ?line {'EXIT',{{badmatch,_},_}} = (catch get_dyn_tail_unused(mkbin([44]), 7)),
+ ok.
+
+get_tail_used(<<A:1,T/binary>>) -> {A,T}.
+
+get_tail_unused(<<A:15,_/binary>>) -> A.
+
+get_dyn_tail_used(Bin, Sz) ->
+ <<A:Sz,T/binary>> = Bin,
+ {A,T}.
+
+get_dyn_tail_unused(Bin, Sz) ->
+ <<A:Sz,_T/binary>> = Bin,
+ A.
+
+zero_tail(doc) -> "Test that zero tails are tested correctly.";
+zero_tail(Config) when list(Config) ->
+ ?line 7 = (catch test_zero_tail(mkbin([7]))),
+ ?line {'EXIT',{function_clause,_}} = (catch test_zero_tail(mkbin([1,2]))),
+ ?line {'EXIT',{function_clause,_}} = (catch test_zero_tail2(mkbin([1,2,3]))),
+ ok.
+
+test_zero_tail(<<A:8>>) -> A.
+
+test_zero_tail2(<<_A:4,_B:4>>) -> ok.
+
+mkbin(L) when list(L) -> list_to_binary(L).
diff --git a/lib/debugger/test/bs_utf_SUITE.erl b/lib/debugger/test/bs_utf_SUITE.erl
new file mode 100644
index 0000000000..3d69d2a101
--- /dev/null
+++ b/lib/debugger/test/bs_utf_SUITE.erl
@@ -0,0 +1,292 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 2008-2010. All Rights Reserved.
+%%
+%% The contents of this file are subject to the Erlang Public License,
+%% Version 1.1, (the "License"); you may not use this file except in
+%% compliance with the License. You should have received a copy of the
+%% Erlang Public License along with this software. If not, it can be
+%% retrieved online at http://www.erlang.org/.
+%%
+%% Software distributed under the License is distributed on an "AS IS"
+%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+%% the License for the specific language governing rights and limitations
+%% under the License.
+%%
+%% %CopyrightEnd%
+%%
+
+%%
+
+-module(bs_utf_SUITE).
+
+-export([all/1,init_all/1,finish_all/1,
+ init_per_testcase/2,fin_per_testcase/2,
+ utf8_roundtrip/1,unused_utf_char/1,utf16_roundtrip/1,
+ utf32_roundtrip/1,guard/1,extreme_tripping/1]).
+
+-include("test_server.hrl").
+-compile([no_jopt,time]).
+
+all(suite) ->
+ [{conf,init_all,cases(),finish_all}].
+
+cases() ->
+ [utf8_roundtrip,unused_utf_char,utf16_roundtrip,
+ utf32_roundtrip,guard,extreme_tripping].
+
+init_per_testcase(_Case, Config) ->
+ test_lib:interpret(?MODULE),
+ Dog = test_server:timetrap(?t:minutes(1)),
+ [{watchdog,Dog}|Config].
+
+fin_per_testcase(_Case, Config) ->
+ Dog = ?config(watchdog, Config),
+ ?t:timetrap_cancel(Dog),
+ ok.
+
+init_all(Config) when is_list(Config) ->
+ ?line test_lib:interpret(?MODULE),
+ ?line true = lists:member(?MODULE, int:interpreted()),
+ ok.
+
+finish_all(Config) when is_list(Config) ->
+ ok.
+
+utf8_roundtrip(Config) when is_list(Config) ->
+ ?line [utf8_roundtrip_1(P) || P <- utf_data()],
+ ok.
+
+utf8_roundtrip_1({Str,Bin,Bin}) ->
+ ?line Str = utf8_to_list(Bin),
+ ?line Bin = list_to_utf8(Str),
+ ?line [ok = utf8_guard(C, <<42,C/utf8>>) || C <- Str],
+ ?line [error = utf8_guard(C, <<C/utf8>>) || C <- Str],
+ ok.
+
+utf8_guard(C, Bin) when <<42,C/utf8>> =:= Bin -> ok;
+utf8_guard(_, _) -> error.
+
+utf8_to_list(<<C/utf8,T/binary>>) ->
+ [C|utf8_to_list(T)];
+utf8_to_list(<<>>) -> [].
+
+list_to_utf8(L) ->
+ list_to_utf8(L, <<>>).
+
+list_to_utf8([H|T], Bin) ->
+ list_to_utf8(T, <<Bin/binary,H/utf8>>);
+list_to_utf8([], Bin) -> Bin.
+
+unused_utf_char(Config) when is_list(Config) ->
+ [true = utf8_len(Utf8) =:= length(Str) ||
+ {Str,Utf8} <- utf_data()],
+ ok.
+
+utf8_len(B) ->
+ utf8_len(B, 0).
+
+utf8_len(<<_/utf8,T/binary>>, N) ->
+ utf8_len(T, N+1);
+utf8_len(<<>>, N) -> N.
+
+utf16_roundtrip(Config) when is_list(Config) ->
+ ?line {Str,Big,Big,Little,Little} = utf16_data(),
+ ?line 4 = utf16_big_len(Big),
+ ?line 4 = utf16_little_len(Little),
+ ?line Str = big_utf16_to_list(Big),
+ ?line Str = little_utf16_to_list(Little),
+
+ ?line Big = list_to_big_utf16(Str),
+ ?line Little = list_to_little_utf16(Str),
+
+ ok.
+
+utf16_big_len(B) ->
+ utf16_big_len(B, 0).
+
+utf16_big_len(<<_/utf16,T/binary>>, N) ->
+ utf16_big_len(T, N+1);
+utf16_big_len(<<>>, N) -> N.
+
+utf16_little_len(B) ->
+ utf16_little_len(B, 0).
+
+utf16_little_len(<<_/little-utf16,T/binary>>, N) ->
+ utf16_little_len(T, N+1);
+utf16_little_len(<<>>, N) -> N.
+
+list_to_big_utf16(List) ->
+ list_to_big_utf16(List, <<>>).
+
+list_to_big_utf16([H|T], Bin) ->
+ list_to_big_utf16(T, <<Bin/binary,H/utf16>>);
+list_to_big_utf16([], Bin) -> Bin.
+
+list_to_little_utf16(List) ->
+ list_to_little_utf16(List, <<>>).
+
+list_to_little_utf16([H|T], Bin) ->
+ list_to_little_utf16(T, <<Bin/binary,H/little-utf16>>);
+list_to_little_utf16([], Bin) -> Bin.
+
+big_utf16_to_list(<<H/utf16,T/binary>>) ->
+ [H|big_utf16_to_list(T)];
+big_utf16_to_list(<<>>) -> [].
+
+little_utf16_to_list(<<H/little-utf16,T/binary>>) ->
+ [H|little_utf16_to_list(T)];
+little_utf16_to_list(<<>>) -> [].
+
+utf32_roundtrip(Config) when is_list(Config) ->
+ ?line {Str,Big,Big,Little,Little} = utf32_data(),
+ ?line 4 = utf32_big_len(Big),
+ ?line 4 = utf32_little_len(Little),
+ ?line Str = big_utf32_to_list(Big),
+ ?line Str = little_utf32_to_list(Little),
+
+ ?line Big = list_to_big_utf32(Str),
+ ?line Little = list_to_little_utf32(Str),
+
+ ok.
+
+utf32_big_len(B) ->
+ utf32_big_len(B, 0).
+
+utf32_big_len(<<_/utf32,T/binary>>, N) ->
+ utf32_big_len(T, N+1);
+utf32_big_len(<<>>, N) -> N.
+
+utf32_little_len(B) ->
+ utf32_little_len(B, 0).
+
+utf32_little_len(<<_/little-utf32,T/binary>>, N) ->
+ utf32_little_len(T, N+1);
+utf32_little_len(<<>>, N) -> N.
+
+list_to_big_utf32(List) ->
+ list_to_big_utf32(List, <<>>).
+
+list_to_big_utf32([H|T], Bin) ->
+ list_to_big_utf32(T, <<Bin/binary,H/utf32>>);
+list_to_big_utf32([], Bin) -> Bin.
+
+list_to_little_utf32(List) ->
+ list_to_little_utf32(List, <<>>).
+
+list_to_little_utf32([H|T], Bin) ->
+ list_to_little_utf32(T, <<Bin/binary,H/little-utf32>>);
+list_to_little_utf32([], Bin) -> Bin.
+
+big_utf32_to_list(<<H/utf32,T/binary>>) ->
+ [H|big_utf32_to_list(T)];
+big_utf32_to_list(<<>>) -> [].
+
+little_utf32_to_list(<<H/little-utf32,T/binary>>) ->
+ [H|little_utf32_to_list(T)];
+little_utf32_to_list(<<>>) -> [].
+
+
+guard(Config) when is_list(Config) ->
+ ?line error = do_guard(16#D800),
+ ok.
+
+do_guard(C) when byte_size(<<C/utf8>>) =/= 42 -> ok;
+do_guard(C) when byte_size(<<C/utf16>>) =/= 42 -> ok;
+do_guard(C) when byte_size(<<C/utf32>>) =/= 42 -> ok;
+do_guard(_) -> error.
+
+%% The purpose of this test is to make sure that
+%% the delayed creation of sub-binaries works.
+
+extreme_tripping(Config) when is_list(Config) ->
+ ?line Unicode = lists:seq(0, 1024),
+ ?line Utf8 = unicode_to_utf8(Unicode, <<>>),
+ ?line Utf16 = utf8_to_utf16(Utf8, <<>>),
+ ?line Utf32 = utf8_to_utf32(Utf8, <<>>),
+ ?line Utf32 = utf16_to_utf32(Utf16, <<>>),
+ ?line Utf8 = utf32_to_utf8(Utf32, <<>>),
+ ?line Unicode = utf32_to_unicode(Utf32),
+ ok.
+
+unicode_to_utf8([C|T], Bin) ->
+ unicode_to_utf8(T, <<Bin/bytes,C/utf8>>);
+unicode_to_utf8([], Bin) -> Bin.
+
+utf8_to_utf16(<<C/utf8,T/binary>>, Bin) ->
+ utf8_to_utf16(T, <<Bin/bytes,C/utf16>>);
+utf8_to_utf16(<<>>, Bin) -> Bin.
+
+utf16_to_utf32(<<C/utf16,T/binary>>, Bin) ->
+ utf16_to_utf32(T, <<Bin/bytes,C/utf32>>);
+utf16_to_utf32(<<>>, Bin) -> Bin.
+
+utf8_to_utf32(<<C/utf8,T/binary>>, Bin) ->
+ utf8_to_utf32(T, <<Bin/bytes,C/utf32>>);
+utf8_to_utf32(<<>>, Bin) -> Bin.
+
+utf32_to_utf8(<<C/utf32,T/binary>>, Bin) ->
+ utf32_to_utf8(T, <<Bin/bytes,C/utf8>>);
+utf32_to_utf8(<<>>, Bin) -> Bin.
+
+utf32_to_unicode(<<C/utf32,T/binary>>) ->
+ [C|utf32_to_unicode(T)];
+utf32_to_unicode(<<>>) -> [].
+
+utf_data() ->
+%% From RFC-3629.
+
+ %% Give the compiler a change to do some constant propagation.
+ NotIdentical = 16#2262,
+
+ [
+ %% "A<NOT IDENTICAL TO><ALPHA>."
+ {[16#0041,NotIdentical,16#0391,16#002E],
+ <<16#0041/utf8,NotIdentical/utf8,16#0391/utf8,16#002E/utf8>>,
+ <<16#41,16#E2,16#89,16#A2,16#CE,16#91,16#2E>>},
+
+ %% Korean "hangugeo" (meaning "the Korean language")
+ {[16#D55C,16#AD6D,16#C5B4],
+ <<16#D55C/utf8,16#AD6D/utf8,16#C5B4/utf8>>,
+ <<16#ED,16#95,16#9C,16#EA,16#B5,16#AD,16#EC,16#96,16#B4>>},
+
+ %% Japanese "nihongo" (meaning "the Japanese language").
+ {[16#65E5,16#672C,16#8A9E],
+ <<16#65E5/utf8,16#672C/utf8,16#8A9E/utf8>>,
+ <<16#E6,16#97,16#A5,16#E6,16#9C,16#AC,16#E8,16#AA,16#9E>>}
+ ].
+
+utf16_data() ->
+ %% Example from RFC-2781. "*=Ra", where "*" represents a
+ %% hypothetical Ra hieroglyph (code point 16#12345).
+
+ %% Give the compiler a change to do some constant propagation.
+ RaHieroglyph = 16#12345,
+
+ %% First as a list of Unicode characters.
+ {[RaHieroglyph,16#3D,16#52,16#61],
+
+ %% Big endian (the two binaries should be equal).
+ <<RaHieroglyph/big-utf16,16#3D/big-utf16,16#52/big-utf16,16#61/big-utf16>>,
+ <<16#D8,16#08,16#DF,16#45,16#00,16#3D,16#00,16#52,16#00,16#61>>,
+
+ %% Little endian (the two binaries should be equal).
+ <<RaHieroglyph/little-utf16,16#3D/little-utf16,
+ 16#52/little-utf16,16#61/little-utf16>>,
+ <<16#08,16#D8,16#45,16#DF,16#3D,16#00,16#52,16#00,16#61,16#00>>}.
+
+utf32_data() ->
+ %% "A<NOT IDENTICAL TO><ALPHA>."
+ NotIdentical = 16#2262,
+ {[16#0041,NotIdentical,16#0391,16#002E],
+
+ %% Big endian.
+ <<16#0041/utf32,NotIdentical/utf32,16#0391/utf32,16#002E/utf32>>,
+ <<16#41:32,NotIdentical:32,16#0391:32,16#2E:32>>,
+
+ %% Little endian.
+ <<16#0041/little-utf32,NotIdentical/little-utf32,
+ 16#0391/little-utf32,16#002E/little-utf32>>,
+ <<16#41:32/little,NotIdentical:32/little,
+ 16#0391:32/little,16#2E:32/little>>}.
diff --git a/lib/debugger/test/bug_SUITE.erl b/lib/debugger/test/bug_SUITE.erl
new file mode 100644
index 0000000000..cf732c8115
--- /dev/null
+++ b/lib/debugger/test/bug_SUITE.erl
@@ -0,0 +1,79 @@
+%%
+%% %CopyrightBegin%
+%%
+%% 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%
+%%
+
+%%
+-module(bug_SUITE).
+
+-include("test_server.hrl").
+
+-export([all/1]).
+
+-export([ticket_tests/1]).
+
+-export([otp2163/1, otp4845/1]).
+
+all(suite) -> [ticket_tests].
+
+ticket_tests(doc) -> ["Tests tickets regarding bugs"];
+ticket_tests(suite) -> [otp2163, otp4845].
+
+otp2163(doc) -> ["BIF exit reason"];
+otp2163(suite) -> [];
+otp2163(Config) when list(Config) ->
+ ?line DataDir = ?config(data_dir, Config),
+
+ %% First compile and get the expected results:
+
+ ?line FileName = filename:join(DataDir, "otp2163"),
+ ?line {module,otp2163} = code:load_abs(FileName),
+
+ ?line {'EXIT',{badarg,[ApplyRes|_]}} = (catch otp2163:apply_test()),
+ ?line {'EXIT',{badarg,[ListRes|_]}} = (catch otp2163:list_to_atom_test()),
+
+ %% Then interpret, and check if the results are OK.
+ ?line {module,otp2163} = int:i(FileName),
+
+ ?line ok = io:format("Expecting ~p", [ApplyRes]),
+ ?line {'EXIT',{badarg,[ApplyRes|_]}} = (catch otp2163:apply_test()),
+ ?line ok = io:format("Expecting ~p", [ListRes]),
+ ?line {'EXIT',{badarg,[ListRes|_]}} = (catch otp2163:list_to_atom_test()),
+ ok.
+
+
+otp4845(doc) -> ["BIF not loading and not bug compatible, OTP-4845 OTP-4859"];
+otp4845(suite) -> [];
+otp4845(Config) when list(Config) ->
+ ?line DataDir = ?config(data_dir, Config),
+
+ %% First compile and get the expected results:
+
+ ?line FileName = filename:join(DataDir, "otp4845"),
+ ?line {module,otp4845} = code:load_abs(FileName),
+
+ ?line CompiledRes = (catch otp4845:test()),
+ ?line ok = io:format("Compiled ~p", [CompiledRes]),
+
+ %% Then interpret, and check if the results are OK.
+ ?line {module,otp4845} = int:i(FileName),
+
+ ?line IntRes = (catch otp4845:test()),
+ ?line ok = io:format("Interpreted ~p", [IntRes]),
+
+ ?line CompiledRes = IntRes,
+ ok.
diff --git a/lib/debugger/test/bug_SUITE_data/Makefile.src b/lib/debugger/test/bug_SUITE_data/Makefile.src
new file mode 100644
index 0000000000..792b3299e1
--- /dev/null
+++ b/lib/debugger/test/bug_SUITE_data/Makefile.src
@@ -0,0 +1,25 @@
+#
+# %CopyrightBegin%
+#
+# Copyright Ericsson AB 2000-2010. All Rights Reserved.
+#
+# The contents of this file are subject to the Erlang Public License,
+# Version 1.1, (the "License"); you may not use this file except in
+# compliance with the License. You should have received a copy of the
+# Erlang Public License along with this software. If not, it can be
+# retrieved online at http://www.erlang.org/.
+#
+# Software distributed under the License is distributed on an "AS IS"
+# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+# the License for the specific language governing rights and limitations
+# under the License.
+#
+# %CopyrightEnd%
+#
+all: otp2163.@EMULATOR@ otp4845.@EMULATOR@
+EFLAGS=+debug_info
+
+otp2163.@EMULATOR@: otp2163.erl
+ erlc $(EFLAGS) otp2163.erl
+otp4845.@EMULATOR@: otp4845.erl
+ erlc $(EFLAGS) otp4845.erl
diff --git a/lib/debugger/test/bug_SUITE_data/otp2163.erl b/lib/debugger/test/bug_SUITE_data/otp2163.erl
new file mode 100644
index 0000000000..4e3c487ef7
--- /dev/null
+++ b/lib/debugger/test/bug_SUITE_data/otp2163.erl
@@ -0,0 +1,60 @@
+%%
+%% %CopyrightBegin%
+%%
+%% 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%
+%%
+
+%%
+%%% Purpose : Test OTP-2163
+
+-module(otp2163).
+
+
+-export([apply_test/0, list_to_atom_test/0, error/1]).
+-export([test/0]).
+
+apply_test() ->
+ M = {},
+ apply(M,dummy,[]).
+
+list_to_atom_test() ->
+ list_to_atom(id({1,2})).
+
+id(I) -> I.
+
+%% OTP-4845 OTP 4859
+-record(sune, {a,sd,g,s}).
+-record(error, {a,sd,g,s}).
+
+test() ->
+ sune = error(#sune{}),
+ {false,false} = error(false),
+ {true,true} = error(true),
+ error(#error{}).
+
+error(X) ->
+ if
+ is_record(X, sune) ->
+ sune;
+ X ->
+ {true, X};
+ not X ->
+ {false, X};
+ not is_record(X, error) ->
+ error;
+ true ->
+ ok
+ end.
diff --git a/lib/debugger/test/bug_SUITE_data/otp4845.erl b/lib/debugger/test/bug_SUITE_data/otp4845.erl
new file mode 100644
index 0000000000..18ca08b977
--- /dev/null
+++ b/lib/debugger/test/bug_SUITE_data/otp4845.erl
@@ -0,0 +1,52 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 2004-2010. All Rights Reserved.
+%%
+%% The contents of this file are subject to the Erlang Public License,
+%% Version 1.1, (the "License"); you may not use this file except in
+%% compliance with the License. You should have received a copy of the
+%% Erlang Public License along with this software. If not, it can be
+%% retrieved online at http://www.erlang.org/.
+%%
+%% Software distributed under the License is distributed on an "AS IS"
+%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+%% the License for the specific language governing rights and limitations
+%% under the License.
+%%
+%% %CopyrightEnd%
+%%
+
+%%
+%%% Purpose : Test OTP-4845
+
+-module(otp4845).
+
+
+%%-export([error/1]).
+-export([test/0]).
+
+%% OTP-4845 OTP 4859
+-record(sune, {a,sd,g,s}).
+-record(error, {a,sd,g,s}).
+
+test() ->
+ R1 = error(#sune{}),
+ R2 = error(false),
+ R3 = error(true),
+ R4 = error(#error{}),
+ {R1,R2,R3,R4}.
+
+error(X) ->
+ if
+ is_record(X, sune) ->
+ sune;
+ X ->
+ {true, X};
+ not X ->
+ {false, X};
+ not is_record(X, error) ->
+ error;
+ true ->
+ ok
+ end.
diff --git a/lib/debugger/test/cleanup.erl b/lib/debugger/test/cleanup.erl
new file mode 100644
index 0000000000..59b4c35ac7
--- /dev/null
+++ b/lib/debugger/test/cleanup.erl
@@ -0,0 +1,45 @@
+%%
+%% %CopyrightBegin%
+%%
+%% 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%
+%%
+
+%%
+-module(cleanup).
+
+-export([all/1, cleanup/1]).
+
+-include("test_server.hrl").
+
+all(suite) -> {req, [interpreter], [cleanup]}.
+
+cleanup(suite) -> [];
+cleanup(_) ->
+ ?line Mods = int:interpreted(),
+ ?line ok = int:n(Mods),
+ case whereis(interpret) of
+ undefined ->
+ ok;
+ Pid ->
+ exit(Pid, kill)
+ end,
+ case whereis(int_db) of
+ undefined ->
+ ok;
+ Pid2 ->
+ exit(Pid2, kill)
+ end,
+ ok.
diff --git a/lib/debugger/test/dbg_ui_SUITE.erl b/lib/debugger/test/dbg_ui_SUITE.erl
new file mode 100644
index 0000000000..629aac9fd6
--- /dev/null
+++ b/lib/debugger/test/dbg_ui_SUITE.erl
@@ -0,0 +1,288 @@
+%%
+%% %CopyrightBegin%
+%%
+%% 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%
+%%
+
+%%
+-module(dbg_ui_SUITE).
+
+
+-include("test_server.hrl").
+
+
+% Test server specific exports
+-export([all/1]).
+-export([function_tests/1]).
+
+
+% Test cases must be exported.
+-export ([dbg_ui/1]).
+
+
+
+
+
+% Manual test suites/cases exports
+-export([manual_tests/1]).
+-export([start1/1, interpret1/1, quit1/1,
+ start2/1, interpret2/1, break2/1, options2/1, quit2/1,
+ interpret3/1, all_step3/1,all_next3/1,save3/1,restore3/1,finish3/1,
+ killinit3/1, killone3/1, killall3/1, deleteone3/1, deleteall3/1,
+ viewbreak4/1, delete4/1,
+ attach5/1, normal5/1, exit5/1, options5/1,
+ distsetup6/1, all_step6/1, all_next6/1]).
+
+
+
+
+-export([init_per_testcase/2, fin_per_testcase/2]).
+
+
+
+init_per_testcase(_Func, Config) ->
+ Dog=test_server:timetrap(60*1000),
+ [{watchdog, Dog}|Config].
+
+fin_per_testcase(_Func, Config) ->
+ Dog=?config(watchdog, Config),
+ test_server:timetrap_cancel(Dog).
+
+
+all (suite)->
+ {req, [debugger], [function_tests, manual_tests]}.
+
+
+function_tests (doc) ->
+ ["Tests documented functions"];
+
+function_tests (suite) ->
+ [dbg_ui].
+
+
+
+dbg_ui (doc) ->
+ ["Debugger GUI"];
+
+dbg_ui (suite) ->
+ [];
+
+dbg_ui (_Config) ->
+ case os:getenv("DISPLAY") of
+ false ->
+ {skipped,"No display"};
+ Other when list(Other) ->
+% ?line {ok, Pid} = debugger:start (),
+% ?line ok = is_pid (Pid),
+% ?line true = erlang:is_process_alive(Pid),
+% ?line ok = debugger:stop(),
+% ?line false = erlang:is_process_alive(Pid)
+ {skipped,"Gunilla: Workaround"}
+ end.
+
+
+
+
+
+
+%% check/2 - returns the result for the specified testcase.
+%% pass - means the user has run the case, and it passed
+%% fail - means the user has run the case, and it failed
+%% unknown - means the user has (tried to) run the case, and the result is unclear.
+%% skip - means the user has not yet run the case.
+
+check(Case, Config) ->
+
+ ?line DataDir = ?config(data_dir, Config),
+ ?line ResultFileName = filename:join([DataDir, "manual_results.erl"]),
+ case file:consult(ResultFileName) of
+ {ok, Results} ->
+ ?line io:format("Results: ~p~n",[Results]),
+ case Results of
+ [] ->
+ no_result;
+ %% Incomplete "sanity" check of file contents.
+ [{_Key,_Value}|_Rest] ->
+ case lists:keysearch(Case, 1, Results) of
+ {value, {Case, Value}} ->
+ Value; % pass, fail, unknown
+ false ->
+ no_result; % skip
+ _Otherwise ->
+ {error, "Contents of results file not valid"}
+ end;
+ _Otherwise2 ->
+ {error, "Contents of results file not valid"}
+ end;
+ _Otherwise3 ->
+ {error, "Problems reading results file"}
+ end.
+
+
+
+
+
+
+-define(MAN_CASE(Name,Doc, Description),
+ Name(doc) -> [Doc];
+ Name(suite) -> [];
+ Name(Config) ->
+ ?line io:format("Checking ~p~n",[Name]),
+ ?line io:format("Config = ~p~n",[Config]),
+ case check(Name, Config) of
+ pass ->
+ ?line ok;
+ fail ->
+ ?line test_server:fail("Manual test failed");
+ unknown ->
+ ?line {skipped, "Manual test result unknown"};
+
+ no_result ->
+ ?line {skipped, Description};
+
+ {error, _Reason} ->
+%% Text = lists:flatten(
+%% io_lib:format("[File problem: ~s]~s",
+%% [Reason,Description])),
+ ?line {skipped, Description}
+ end
+ ).
+
+
+
+
+manual_tests(doc) -> ["Manual tests"];
+manual_tests(suite) -> [start1, interpret1, quit1,
+ start2, interpret2, break2, options2,
+ interpret3, all_step3,all_next3,save3,restore3,finish3,
+ killinit3, killone3, killall3, deleteone3, deleteall3,
+ viewbreak4, delete4,
+ attach5, normal5, exit5, options5,
+ distsetup6, all_step6, all_next6
+ ].
+
+
+
+
+
+
+%% SET 1
+?MAN_CASE(start1, "Start the debugger from the toolbar",
+ "Before proceeding with the test cases, please move or remove
+the directory .erlang_tools/debugger in your home directory. Next,
+please start the debugger from the toolbar").
+
+?MAN_CASE(interpret1, "Interpreting modules",
+ "In this test case and all of the ones following, the source code
+files to use can be found in the test data directory for this debugger test
+ suite (probably in
+/clearcase/otp/tools/debugger/test/dbg_ui_SUITE_data/manual_data/src ).
+Interpret one module").
+
+?MAN_CASE(quit1, "Quit the debugger",
+"Quit the debugger using File->Exit in the main window").
+
+
+%% SET 2
+?MAN_CASE(start2, "Start the debugger from the shell",
+"Start the debugger from the shell. Use debugger:start()").
+
+?MAN_CASE(interpret2, "Interpret all modules",
+"Interpret all modules").
+
+?MAN_CASE(break2, "Set break points",
+"Set break points").
+
+?MAN_CASE(options2, "Set options to attach on break",
+"Set options to attach on break").
+
+?MAN_CASE(quit2, "Quit the debugger",
+"Quit the debugger using the close box in the main window title frame").
+
+
+%% SET3
+?MAN_CASE(interpret3, "Test attach options",
+"Start the debugger and interpret the modules [test, lists1, ordsets1]. Close the Interpret dialog. Set Attach on First Call and Attach on Break.").
+
+?MAN_CASE(all_step3, "Click Step through all evaluation",
+"In the shell, call test:test1(). Use the Step button, the Process->Step menu item and the ctrl-s shortcut to step through the *entire* execution of the call. (Approx 36 steps). Then close the Attach window. The result printed in the shell should be: {\"peter\",[1,2,4,a,b,c],\"olin\"}").
+
+?MAN_CASE(all_next3,"Click Next through all evaluation",
+"Again call test:test1() in the shell. This time Use the Next button, the Process->Next menu and the ctrl-n shortcut to quickly step over the execution of the four lines in the test1-function. The result printed in the shell should be: {\"peter\",[1,2,4,a,b,c],\"olin\"}").
+
+?MAN_CASE(save3, "Save the debugger state",
+"Use File->Save Settings to save the debugger state with the name 'three.state'").
+
+?MAN_CASE(restore3,"Quit the debugger, restart and restore the state",
+"Quit the debugger. Start it again. Use File->Load Settings to restore the state saved in 'three.state'. Check that the Attach-options are the same as what you set them to in the interpret3 test case. Check that the three modules [test,lists1,ordsets1] are interpreted.").
+
+
+?MAN_CASE(finish3, "Finish the current function body",
+"Call the fucntion test:test1() from the shell. Press Finish to evaluate the remaining lines in the function. The result printed in the shell should be: {\"peter\",[1,2,4,a,b,c],\"olin\"}").
+
+?MAN_CASE(killinit3,"Set up for killing and clearing processes",
+"Call test:test2() from the shell. Set a break point at the last line of test:test2. Click Continue. This should open three new attach windows. One for each spawn called in test:test2/0. ").
+
+?MAN_CASE(killone3, "Kill a process and clear it",
+"In one of the newly openend Attach windows: select Process->Kill. A message should appear above the Code Area in the Attach window. Use Windows->Monitor to verify that the Monitor window also shows that the process has been killed. In the Monitor window: select Edit->Clear. This should do two things: 1) close/remove the window of the killed process. 2) Remove the entry of the killed process from the monitor window.").
+
+?MAN_CASE(killall3,"KIll all processes, and clear them",
+"In the Monitor window: Select Edit->Kill All. Verify that all processes have been killed (in their respective windows and in the monitor window). Windows will be raised as their processes die. Next select, Edit->Clear. All attach windows should now be closed. Their entris should also disappear from the monitor window. The shell should have reported: ** exited: killed **").
+
+?MAN_CASE(deleteone3,"Delete/uniterpret one module",
+"In the Monitor window: Select Module->test->Delete. This should remove the breakpoints set in the test module, and the test module should disappear from the Module menu.").
+
+?MAN_CASE(deleteall3,"Delete/uniterpret all modules",
+"In the Monitor window: Select Module->Delete All Modules. This should remove all modules from the Module menu. ").
+
+%% SET 4
+
+
+
+?MAN_CASE(viewbreak4, "Test the View window",
+"Restore the settings from the three.state file again. In the Monitor window: Use Module->test->View to view the source code of the test module. In the View window, select Break->Line Break and set a break at line 53. Check that it appears in the View window and in the Monitor Window Break-menu. Also in the View window, select Break->Function Break and set a break at function test:test4. Check that the break (at line 59) appears in the View Window and in the Monitor Window Break-menu.").
+
+?MAN_CASE(delete4, "Remove breaks",
+"Use the Break->Delete All function in the View window to remove all breaks in the test module. Check that they are all removed. Close the View window.").
+
+%% SET 5
+
+?MAN_CASE(attach5,"Set attach options",
+"Set the attach options to only attach on exit").
+
+?MAN_CASE(normal5, "Test normal exit",
+"Call test:test12(normal) in the shell. This should return the atom 'done', and no windows should be opened.").
+
+?MAN_CASE(exit5, "Test abnormal exit",
+"Call test:test12(crash) in the shell. This should give the error message ** exited: crash **, and an attach window should be opened highlighting the last line in the test12-function.").
+
+?MAN_CASE(options5, "Experiment with the frames in the attach window",
+"Try all possible configurations of the [Button, Evaluator, Bindings, Trace] Frames in the attach window and see that the expected frames are shown/hidden.").
+
+
+%% SET 6 (Distribution)
+
+?MAN_CASE(distsetup6,"Set up distribution",
+"Start two erlang systems [foo,bar] (with option -sname), make them aware of eachother using net_adm:ping/1. Start the debugger on foo. Interpret the modules [test, lists1, ordsets1]. Set attach on First call. ").
+
+
+
+
+?MAN_CASE(all_step6, "Click Step through all evaluation",
+"In the bar shell, call test:test1().This should open an attach window. Use the Step button, the Process->Step menu item and the ctrl-s shortcut to step through the *entire* execution of the call. (Approx 36 steps). Then close the Attach window. The result printed in the bar shell should be: {\"peter\",[1,2,4,a,b,c],\"olin\"}").
+
+?MAN_CASE(all_next6,"Click Next through all evaluation",
+"Again, in the bar shell, call test:test1(). This time Use the Next button, the Process->Next menu and the ctrl-n shortcut to quickly step over the execution of the four lines in the test1-function. The result printed in the shell should be: {\"peter\",[1,2,4,a,b,c],\"olin\"}").
diff --git a/lib/debugger/test/dbg_ui_SUITE_data/manual_data/src/lists1.erl b/lib/debugger/test/dbg_ui_SUITE_data/manual_data/src/lists1.erl
new file mode 100644
index 0000000000..0214983c11
--- /dev/null
+++ b/lib/debugger/test/dbg_ui_SUITE_data/manual_data/src/lists1.erl
@@ -0,0 +1,469 @@
+%%
+%% %CopyrightBegin%
+%%
+%% 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%
+%%
+
+%%
+%% Purpose : Basic lists processing functions.
+
+-module(lists1).
+
+
+-export([member/2, append/2, append/1, subtract/2, reverse/1, reverse/2,
+ nth/2, nthtail/2, prefix/2, suffix/2, last/1,
+ seq/2, seq/3, sum/1, duplicate/2, min/1, max/1, sublist/2, sublist/3,
+ delete/2, sort/1, merge/2, concat/1,
+ flatten/1, flatten/2, flat_length/1, flatlength/1,
+ keymember/3, keysearch/3, keydelete/3, keyreplace/4,
+ keysort/2, keymerge/3, keymap/3, keymap/4]).
+
+-export([all/2,any/2,map/2,flatmap/2,foldl/3,foldr/3,filter/2,zf/2,
+ mapfoldl/3,mapfoldr/3,foreach/2,takewhile/2,dropwhile/2,splitwith/2]).
+-export([all/3,any/3,map/3,flatmap/3,foldl/4,foldr/4,filter/3,zf/3,
+ mapfoldl/4,mapfoldr/4,foreach/3]).
+
+%% member(X, L) -> (true | false)
+%% test if X is a member of the list L
+
+member(X, [X|_]) -> true;
+member(X, [_|Y]) ->
+ member(X, Y);
+member(X, []) -> false.
+
+%% append(X, Y) appends lists X and Y
+
+append(L1, L2) -> L1 ++ L2.
+
+%% append(L) appends the list of lists L
+
+append([E]) -> E;
+append([H|T]) -> H ++ append(T);
+append([]) -> [].
+
+%% subtract(List1, List2) subtract elements in List2 form List1.
+
+subtract(L1, L2) -> L1 -- L2.
+
+%% reverse(L) reverse all elements in the list L
+
+reverse(X) -> reverse(X, []).
+
+reverse([H|T], Y) ->
+ reverse(T, [H|Y]);
+reverse([], X) -> X.
+
+%% nth(N, L) returns the N`th element of the list L
+%% nthtail(N, L) returns the N`th tail of the list L
+
+nth(1, [H|T]) -> H;
+nth(N, [_|T]) when N > 1 ->
+ nth(N - 1, T).
+
+nthtail(1, [H|T]) -> T;
+nthtail(N, [H|T]) when N > 1 ->
+ nthtail(N - 1, T);
+nthtail(0, L) when list(L) -> L.
+
+%% prefix(Prefix, List) -> (true | false)
+
+prefix([X|PreTail], [X|Tail]) ->
+ prefix(PreTail, Tail);
+prefix([], List) -> true;
+prefix(_,_) -> false.
+
+
+%% suffix(Suffix, List) -> (true | false)
+
+suffix(Suffix, Suffix) -> true;
+suffix(Suffix, [_|Tail]) ->
+ suffix(Suffix, Tail);
+suffix(Suffix, []) -> false.
+
+%% last(List) returns the last element in a list.
+
+last([E]) -> E;
+last([E|Es]) ->
+ last(Es).
+
+%% seq(Min, Max) -> [Min,Min+1, ..., Max]
+%% seq(Min, Max, Incr) -> [Min,Min+Incr, ..., Max]
+%% returns the sequence Min..Max
+%% Min <= Max and Min and Max must be integers
+
+seq(Min, Max) when integer(Min), integer(Max), Min =< Max ->
+ seq(Min, Max, 1, []).
+
+seq(Min, Max, Incr) ->
+ seq(Min, Min + ((Max-Min) div Incr) * Incr, Incr, []).
+
+seq(Min, Min, I, L) -> [Min|L];
+seq(Min, Max, I, L) -> seq(Min, Max-I, I, [Max|L]).
+
+%% sum(L) suns the sum of the elements in L
+
+sum(L) -> sum(L, 0).
+sum([H|T], Sum) -> sum(T, Sum + H);
+sum([], Sum) -> Sum.
+
+%% duplicate(N, X) -> [X,X,X,.....,X] (N times)
+%% return N copies of X
+
+duplicate(N, X) when integer(N), N >= 0 -> duplicate(N, X, []).
+
+duplicate(0, _, L) -> L;
+duplicate(N, X, L) -> duplicate(N-1, X, [X|L]).
+
+
+%% min(L) -> returns the minimum element of the list L
+
+min([H|T]) -> min(T, H).
+
+min([H|T], Min) when H < Min -> min(T, H);
+min([_|T], Min) -> min(T, Min);
+min([], Min) -> Min.
+
+%% max(L) -> returns the maximum element of the list L
+
+max([H|T]) -> max(T, H).
+
+max([H|T], Max) when H > Max -> max(T, H);
+max([_|T], Max) -> max(T, Max);
+max([], Max) -> Max.
+
+%% sublist(List, Start, Length)
+%% Returns the sub-list starting at Start of length Length.
+
+sublist(List, S, L) when L >= 0 ->
+ sublist(nthtail(S-1, List), L).
+
+sublist([H|T], L) when L > 0 ->
+ [H|sublist(T, L-1)];
+sublist(List, L) -> [].
+
+%% delete(Item, List) -> List'
+%% Delete the first occurance of Item from the list L.
+
+delete(Item, [Item|Rest]) -> Rest;
+delete(Item, [H|Rest]) ->
+ [H|delete(Item, Rest)];
+delete(Item, []) -> [].
+
+%% sort(L) -> sorts the list L
+
+sort([X]) -> [X];
+sort([]) -> [];
+sort(X) -> split_and_sort(X, [], []).
+
+split_and_sort([A,B|T], X, Y) ->
+ split_and_sort(T, [A|X], [B|Y]);
+split_and_sort([H], X, Y) ->
+ split_and_sort([], [H|X], Y);
+split_and_sort([], X, Y) ->
+ merge(sort(X), sort(Y), []).
+
+%% merge(X, Y) -> L
+%% merges two sorted lists X and Y
+
+merge(X, Y) -> merge(X, Y, []).
+
+merge([H1|T1], [H2|T2], L) when H1 < H2 ->
+ merge(T1, [H2|T2], [H1|L]);
+merge(T1, [H2|T2], L) ->
+ merge(T1, T2, [H2|L]);
+merge([H|T], T2, L) ->
+ merge(T, T2, [H|L]);
+merge([], [], L) ->
+ reverse(L).
+
+%% concat(L) concatinate the list representation of the elements
+%% in L - the elements in L can be atoms, integers of strings.
+%% Returns a list of characters.
+
+concat(List) ->
+ flatmap(fun thing_to_list/1, List).
+
+thing_to_list(X) when integer(X) -> integer_to_list(X);
+thing_to_list(X) when float(X) -> float_to_list(X);
+thing_to_list(X) when atom(X) -> atom_to_list(X);
+thing_to_list(X) when list(X) -> X. %Assumed to be a string
+
+%% flatten(List)
+%% flatten(List, Tail)
+%% Flatten a list, adding optional tail.
+
+flatten(List) ->
+ flatten(List, [], []).
+
+flatten(List, Tail) ->
+ flatten(List, [], Tail).
+
+flatten([H|T], Cont, Tail) when list(H) ->
+ flatten(H, [T|Cont], Tail);
+flatten([H|T], Cont, Tail) ->
+ [H|flatten(T, Cont, Tail)];
+flatten([], [H|Cont], Tail) ->
+ flatten(H, Cont, Tail);
+flatten([], [], Tail) ->
+ Tail.
+
+%% flat_length(List) (undocumented can be rmove later)
+%% Calculate the length of a list of lists.
+
+flat_length(List) -> flatlength(List).
+
+%% flatlength(List)
+%% Calculate the length of a list of lists.
+
+flatlength(List) ->
+ flatlength(List, 0).
+
+flatlength([H|T], L) when list(H) ->
+ flatlength(H, flatlength(T, L));
+flatlength([H|T], L) ->
+ flatlength(T, L + 1);
+flatlength([], L) -> L.
+
+%% keymember(Key, Index, [Tuple])
+%% keysearch(Key, Index, [Tuple])
+%% keydelete(Key, Index, [Tuple])
+%% keyreplace(Key, Index, [Tuple], NewTuple)
+%% keysort(Index, [Tuple])
+%% keymerge(Index, [Tuple], [Tuple])
+%% keymap(Function, Index, [Tuple])
+%% keymap(Function, ExtraArgs, Index, [Tuple])
+
+keymember(Key, N, [T|Ts]) when element(N, T) == Key -> true;
+keymember(Key, N, [T|Ts]) ->
+ keymember(Key, N, Ts);
+keymember(Key, N, []) -> false.
+
+keysearch(Key, N, [H|T]) when element(N, H) == Key ->
+ {value, H};
+keysearch(Key, N, [H|T]) ->
+ keysearch(Key, N, T);
+keysearch(Key, N, []) -> false.
+
+keydelete(Key, N, [H|T]) when element(N, H) == Key -> T;
+keydelete(Key, N, [H|T]) ->
+ [H|keydelete(Key, N, T)];
+keydelete(Key, N, []) -> [].
+
+keyreplace(Key, Pos, [Tup|Tail], New) when element(Pos, Tup) == Key ->
+ [New|Tail];
+keyreplace(Key, Pos, [H|T], New) ->
+ [H|keyreplace(Key, Pos, T, New)];
+keyreplace(Key, Pos, [], New) -> [].
+
+keysort(Index, [X]) -> [X];
+keysort(Index, []) -> [];
+keysort(Index, X) -> split_and_keysort(X, [], [], Index).
+
+split_and_keysort([A,B|T], X, Y, Index) ->
+ split_and_keysort(T, [A|X], [B|Y], Index);
+split_and_keysort([H], X, Y, Index) ->
+ split_and_keysort([], [H|X], Y, Index);
+split_and_keysort([], X, Y, Index) ->
+ keymerge(Index, keysort(Index, X), keysort(Index, Y), []).
+
+keymerge(Index, X, Y) -> keymerge(Index, X, Y, []).
+
+keymerge(I, [H1|T1], [H2|T2], L) when element(I, H1) < element(I, H2) ->
+ keymerge(I, T1, [H2|T2], [H1|L]);
+keymerge(Index, T1, [H2|T2], L) ->
+ keymerge(Index,T1, T2, [H2|L]);
+keymerge(Index,[H|T], T2, L) ->
+ keymerge(Index,T, T2, [H|L]);
+keymerge(Index, [], [], L) ->
+ reverse(L).
+
+keymap(Fun, Index, [Tup|Tail]) ->
+ [setelement(Index, Tup, Fun(element(Index, Tup)))|keymap(Fun, Index, Tail)];
+keymap( _, _ , []) -> [].
+
+keymap(Fun, ExtraArgs, Index, [Tup|Tail]) ->
+ [setelement(Index, Tup, apply(Fun, [element(Index, Tup)|ExtraArgs]))|
+ keymap(Fun, ExtraArgs, Index, Tail)];
+keymap( _, _ , _, []) -> [].
+
+%% all(Predicate, List)
+%% any(Predicate, List)
+%% map(Function, List)
+%% flatmap(Function, List)
+%% foldl(Function, First, List)
+%% foldr(Function, Last, List)
+%% filter(Predicate, List)
+%% zf(Function, List)
+%% mapfoldl(Function, First, List)
+%% mapfoldr(Function, Last, List)
+%% foreach(Function, List)
+%% takewhile(Predicate, List)
+%% dropwhile(Predicate, List)
+%% splitwith(Predicate, List)
+%% for list programming. Function here is either a 'fun' or a tuple
+%% {Module,Name} and we use apply/2 to evaluate. The name zf is a joke!
+%%
+%% N.B. Unless where the functions actually needs it only foreach/2/3,
+%% which is meant to be used for its side effects, has a defined order
+%% of evaluation.
+%%
+%% There are also versions with an extra argument, ExtraArgs, which is a
+%% list of extra arguments to each call.
+
+all(Pred, [Hd|Tail]) ->
+ case Pred(Hd) of
+ true -> all(Pred, Tail);
+ false -> false
+ end;
+all(Pred, []) -> true.
+
+any(Pred, [Hd|Tail]) ->
+ case Pred(Hd) of
+ true -> true;
+ false -> any(Pred, Tail)
+ end;
+any(Pred, []) -> false.
+
+map(F, List) -> [ F(E) || E <- List ].
+
+flatmap(F, [Hd|Tail]) ->
+ F(Hd) ++ flatmap(F, Tail);
+flatmap(F, []) -> [].
+
+foldl(F, Accu, [Hd|Tail]) ->
+ foldl(F, F(Hd, Accu), Tail);
+foldl(F, Accu, []) -> Accu.
+
+foldr(F, Accu, [Hd|Tail]) ->
+ F(Hd, foldr(F, Accu, Tail));
+foldr(F, Accu, []) -> Accu.
+
+filter(Pred, List) -> [ E || E <- List, Pred(E) ].
+
+zf(F, [Hd|Tail]) ->
+ case F(Hd) of
+ true ->
+ [Hd|zf(F, Tail)];
+ {true,Val} ->
+ [Val|zf(F, Tail)];
+ false ->
+ zf(F, Tail)
+ end;
+zf(F, []) -> [].
+
+foreach(F, [Hd|Tail]) ->
+ F(Hd),
+ foreach(F, Tail);
+foreach(F, []) -> ok.
+
+mapfoldl(F, Accu0, [Hd|Tail]) ->
+ {R,Accu1} = F(Hd, Accu0),
+ {Rs,Accu2} = mapfoldl(F, Accu1, Tail),
+ {[R|Rs],Accu2};
+mapfoldl(F, Accu, []) -> {[],Accu}.
+
+mapfoldr(F, Accu0, [Hd|Tail]) ->
+ {Rs,Accu1} = mapfoldr(F, Accu0, Tail),
+ {R,Accu2} = F(Hd, Accu1),
+ {[R|Rs],Accu2};
+mapfoldr(F, Accu, []) -> {[],Accu}.
+
+takewhile(Pred, [Hd|Tail]) ->
+ case Pred(Hd) of
+ true -> [Hd|takewhile(Pred, Tail)];
+ false -> []
+ end;
+takewhile(Pred, []) -> [].
+
+dropwhile(Pred, [Hd|Tail]) ->
+ case Pred(Hd) of
+ true -> dropwhile(Pred, Tail);
+ false -> [Hd|Tail]
+ end;
+dropwhile(Pred, []) -> [].
+
+splitwith(Pred, List) -> splitwith(Pred, List, []).
+
+splitwith(Pred, [Hd|Tail], Taken) ->
+ case Pred(Hd) of
+ true -> splitwith(Pred, Tail, [Hd|Taken]);
+ false -> {reverse(Taken), [Hd|Tail]}
+ end;
+splitwith(Pred, [], Taken) -> {reverse(Taken),[]}.
+
+%% Versions of the above functions with extra arguments.
+
+all(Pred, Eas, [Hd|Tail]) ->
+ case apply(Pred, [Hd|Eas]) of
+ true -> all(Pred, Eas, Tail);
+ false -> false
+ end;
+all(Pred, Eas, []) -> true.
+
+any(Pred, Eas, [Hd|Tail]) ->
+ case apply(Pred, [Hd|Eas]) of
+ true -> true;
+ false -> any(Pred, Eas, Tail)
+ end;
+any(Pred, Eas, []) -> false.
+
+map(F, Eas, List) -> [ apply(F, [E|Eas]) || E <- List ].
+
+flatmap(F, Eas, [Hd|Tail]) ->
+ apply(F, [Hd|Eas]) ++ flatmap(F, Eas, Tail);
+flatmap(F, Eas, []) -> [].
+
+foldl(F, Eas, Accu, [Hd|Tail]) ->
+ foldl(F, Eas, apply(F, [Hd,Accu|Eas]), Tail);
+foldl(F, Eas, Accu, []) -> Accu.
+
+foldr(F, Eas, Accu, [Hd|Tail]) ->
+ apply(F, [Hd,foldr(F, Eas, Accu, Tail)|Eas]);
+foldr(F, Eas, Accu, []) ->
+ Accu.
+
+filter(Pred, Eas, List) -> [ E || E <- List, apply(Pred, [E|Eas]) ].
+
+zf(F, Eas, [Hd|Tail]) ->
+ case apply(F, [Hd|Eas]) of
+ true ->
+ [Hd|zf(F, Eas, Tail)];
+ {true,Val} ->
+ [Val|zf(F, Eas, Tail)];
+ false ->
+ zf(F, Eas, Tail)
+ end;
+zf(F, Eas, []) -> [].
+
+foreach(F, Eas, [Hd|Tail]) ->
+ apply(F, [Hd|Eas]),
+ foreach(F, Eas, Tail);
+foreach(F, Eas, []) -> ok.
+
+mapfoldl(F, Eas, Accu0, [Hd|Tail]) ->
+ {R,Accu1} = apply(F, [Hd,Accu0|Eas]),
+ {Rs,Accu2} = mapfoldl(F, Eas, Accu1, Tail),
+ {[R|Rs],Accu2};
+mapfoldl(F, Eas, Accu, []) -> {[],Accu}.
+
+mapfoldr(F, Eas, Accu0, [Hd|Tail]) ->
+ {Rs,Accu1} = mapfoldr(F, Eas, Accu0, Tail),
+ {R,Accu2} = apply(F, [Hd,Accu1|Eas]),
+ {[R|Rs],Accu2};
+mapfoldr(F, Eas, Accu, []) -> {[],Accu}.
+
+%% takewhile/2, dropwhile/2 and splitwith/2 do not have versions with
+%% extra arguments as this going to be discontinued.
diff --git a/lib/debugger/test/dbg_ui_SUITE_data/manual_data/src/ordsets1.erl b/lib/debugger/test/dbg_ui_SUITE_data/manual_data/src/ordsets1.erl
new file mode 100644
index 0000000000..ea72150bca
--- /dev/null
+++ b/lib/debugger/test/dbg_ui_SUITE_data/manual_data/src/ordsets1.erl
@@ -0,0 +1,188 @@
+%%
+%% %CopyrightBegin%
+%%
+%% 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%
+%%
+
+%%
+%% Purpose : Functions for manipulating sets as ordered lists.
+
+%% As yet some of these are not very efficiently written.
+
+-module(ordsets1).
+
+-export([new_set/0,is_set/1,set_to_list/1,list_to_set/1]).
+-export([is_element/2,add_element/2,del_element/2]).
+-export([union/2,union/1,intersection/2,intersection/1]).
+-export([subtract/2,subset/2]).
+
+%% new_set()
+%% Return a new empty ordered set.
+
+new_set() ->
+ [].
+
+%% is_set(Set)
+%% Return 'true' if Set is an ordered set of elements, else 'false'.
+
+is_set([E|Es]) ->
+ is_set(Es, E);
+is_set([]) ->
+ true.
+
+is_set([E2|Es], E1) when E1 < E2 ->
+ is_set(Es, E2);
+is_set([E2|Es], E1) ->
+ false;
+is_set([], E1) ->
+ true.
+
+%% set_to_list(OrdSet)
+%% Return the elements in OrdSet as a list.
+
+set_to_list(S) ->
+ S.
+
+%% list_to_set(List)
+%% Build an ordered set from the elements in List.
+
+list_to_set([E|Es]) ->
+ add_element(E, list_to_set(Es));
+list_to_set([]) ->
+ [].
+
+%% is_element(Element, OrdSet)
+%% Return 'true' if Element is an element of OrdSet, else 'false'.
+
+is_element(E, [H|Es]) when E < H ->
+ false;
+is_element(E, [H|Es]) when E == H ->
+ true;
+is_element(E, [H|Es]) when E > H ->
+ is_element(E, Es);
+is_element(E, []) ->
+ false.
+
+%% add_element(Element, OrdSet)
+%% Return OrdSet with Element inserted in it.
+
+add_element(E, [H|Es]) when E < H ->
+ [E,H|Es];
+add_element(E, [H|Es]) when E == H ->
+ [H|Es];
+add_element(E, [H|Es]) when E > H ->
+ [H|add_element(E, Es)];
+add_element(E, []) ->
+ [E].
+
+%% del_element(Element, OrdSet)
+%% Return OrdSet but with Element removed.
+
+del_element(E, [H|Es]) when E < H ->
+ [H|Es];
+del_element(E, [H|Es]) when E == H ->
+ Es;
+del_element(E, [H|Es]) when E > H ->
+ [H|del_element(E, Es)];
+del_element(E, []) ->
+ [].
+
+%% union(Set1, Set2)
+%% Return the union of Set1 and Set2.
+
+union([H1|Es1], [H2|Es2]) when H1 < H2 ->
+ [H1|union(Es1, [H2|Es2])];
+union([H1|Es1], [H2|Es2]) when H1 == H2 ->
+ [H1|union(Es1, Es2)];
+union([H1|Es1], [H2|Es2]) when H1 > H2 ->
+ [H2|union([H1|Es1], Es2)];
+union([], Es2) ->
+ Es2;
+union(Es1, []) ->
+ Es1.
+
+%% union(OrdSets)
+%% Return the union of the list of sets.
+
+union([S1,S2|Ss]) ->
+ union1(union(S1,S2), Ss);
+union([S]) ->
+ S;
+union([]) ->
+ [].
+
+union1(S1, [S2|Ss]) ->
+ union1(union(S1, S2), Ss);
+union1(S1, []) ->
+ S1.
+
+%% intersection(Set1, Set2)
+%% Return the intersection of Set1 and Set2.
+
+intersection([H1|Es1], [H2|Es2]) when H1 < H2 ->
+ intersection(Es1, [H2|Es2]);
+intersection([H1|Es1], [H2|Es2]) when H1 == H2 ->
+ [H1|intersection(Es1, Es2)];
+intersection([H1|Es1], [H2|Es2]) when H1 > H2 ->
+ intersection([H1|Es1], Es2);
+intersection([], Es2) ->
+ [];
+intersection(Es1, []) ->
+ [].
+
+%% intersection(OrdSets)
+%% Return the intersection of the list of sets.
+
+intersection([S1,S2|Ss]) ->
+ intersection1(intersection(S1,S2), Ss);
+intersection([S]) ->
+ S;
+intersection([]) ->
+ [].
+
+intersection1(S1, [S2|Ss]) ->
+ intersection1(intersection(S1, S2), Ss);
+intersection1(S1, []) ->
+ S1.
+
+%% subtract(Set1, Set2)
+%% Return all and only the elements of Set1 which are not also in Set2.
+
+subtract([H1|Es1], [H2|Es2]) when H1 < H2 ->
+ [H1|subtract(Es1, [H2|Es2])];
+subtract([H1|Es1], [H2|Es2]) when H1 == H2 ->
+ subtract(Es1, Es2);
+subtract([H1|Es1], [H2|Es2]) when H1 > H2 ->
+ subtract([H1|Es1], Es2);
+subtract([], Es2) ->
+ [];
+subtract(Es1, []) ->
+ Es1.
+
+%% subset(Set1, Set2)
+%% Return 'true' when every element of Set1 is also a member of Set2,
+%% else 'false'.
+
+subset([H1|Es1], [H2|Es2]) when H1 < H2 -> %H1 not in Set2
+ false;
+subset([H1|Es1], [H2|Es2]) when H1 == H2 ->
+ subset(Es1, Es2);
+subset([H1|Es1], [H2|Es2]) when H1 > H2 ->
+ subset([H1|Es1], Es2);
+subset([], Es2) ->
+ true;
+subset(Es1, []) ->
+ false.
diff --git a/lib/debugger/test/dbg_ui_SUITE_data/manual_data/src/test.erl b/lib/debugger/test/dbg_ui_SUITE_data/manual_data/src/test.erl
new file mode 100644
index 0000000000..a48a7e112f
--- /dev/null
+++ b/lib/debugger/test/dbg_ui_SUITE_data/manual_data/src/test.erl
@@ -0,0 +1,157 @@
+%%
+%% %CopyrightBegin%
+%%
+%% 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%
+%%
+
+%%
+-module(test).
+
+%%-compile(export_all).
+-export([test1/0,
+ test2/0,
+ test3/0,
+ test4/0,
+ test5/0,
+ test6/1,
+ test7/0,
+ test8/1,
+ test9/0,
+ test10/0,
+ test11/0,
+ test12/1
+ ]).
+
+
+-export([test9_server/1]).
+
+
+test1() ->
+ R1 = lists1:reverse("retep"),
+ R2 = ordsets1:list_to_set([b,c,a,2,4,1]),
+ R3 = lists1:reverse("nilo"),
+ {R1,R2, R3}.
+
+test2() ->
+ R1 = spawn(lists1,reverse,["retep"]),
+ R2 = spawn(ordsets1,list_to_set,[[b,c,a,2,4,1]]),
+ R3 = spawn(lists1,reverse,["nilo"]),
+ {R1,R2, R3}.
+
+
+test3() ->
+ A = a,
+ Pid = spawn(?MODULE, test1,[]),
+ B = b,
+ {A, B, Pid}.
+
+test4() ->
+ Pid = spawn(?MODULE, test1,[]),
+ A = a,
+ B = b,
+ {A, B, Pid}.
+test5() ->
+ L1 = [a,b,c],
+ L = length(L1),
+ A = a,
+ B = b,
+ {A, B, L, L1}.
+
+
+
+test6(0) ->
+ ok;
+test6(N) when N>0 ->
+ spawn(lists1,reverse,["adolfiparisrorsirapifloda"]),
+ test6(N-1).
+
+
+test7() ->
+ CurDirReturn = file:get_cwd(),
+ {ok, CurDir} = CurDirReturn,
+ DirListReturn = file:list_dir(CurDir),
+ {ok, DirList} = DirListReturn,
+ io:format("~w~n",[DirList]).
+
+
+test8(List) ->
+ %% foo
+ %%bar
+ %% foo
+ %%bar
+ %% foo
+ %%bar
+ %% foo
+ %%bar
+
+ L2 = [gamma|List],
+ {L2, List}.
+
+test9() ->
+ S1 = spawn(?MODULE, test9_server,[self()]),
+ S2 = spawn(?MODULE, test9_server,[bongo]),
+ S3 = spawn(?MODULE, test9_server,[42]),
+
+ test9_loop(S1,S2,S3).
+
+test9_loop(S1,S2,S3) ->
+ receive
+ {S1, hej} ->
+ io:format("S1 ~n"),
+ test9_loop(S1,S2,S3);
+ {S2, hej} ->
+ io:format("S2 ~n"),
+ test9_loop(S1,S2,S3);
+ {S3, hej} ->
+ io:format("S3 ~n"),
+ test9_loop(S1,S2,S3)
+ end.
+
+
+test9_server(Pid) ->
+ io:format("started server: ~p~n",[Pid]),
+ test9_server1(Pid).
+
+test9_server1(Pid) ->
+ Pad = {pad, Pid},
+ test9_server2(Pad).
+
+test9_server2(Pad) ->
+ {pad, Pid} = Pad,
+ Pid ! {self(), hej}.
+
+
+
+
+
+test10() ->
+ receive
+ X ->
+ done
+ after 20000 ->
+ timeout
+ end.
+
+test11() ->
+ receive
+ X ->
+ done
+ end.
+
+test12(normal) ->
+ done;
+test12(crash) ->
+ exit(crash).
diff --git a/lib/debugger/test/debugger.spec b/lib/debugger/test/debugger.spec
new file mode 100644
index 0000000000..cc8a5aff37
--- /dev/null
+++ b/lib/debugger/test/debugger.spec
@@ -0,0 +1 @@
+{topcase, {dir, "../debugger_test"}}.
diff --git a/lib/debugger/test/debugger_SUITE.erl b/lib/debugger/test/debugger_SUITE.erl
new file mode 100644
index 0000000000..4bd9057f98
--- /dev/null
+++ b/lib/debugger/test/debugger_SUITE.erl
@@ -0,0 +1,123 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 2001-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(debugger_SUITE).
+
+%% Test break points.
+
+-include("test_server.hrl").
+
+-export([all/1,init_per_testcase/2,fin_per_testcase/2,
+ app_test/1,erts_debug/1,encrypted_debug_info/1,
+ no_abstract_code/1]).
+
+all(suite) ->
+ [app_test,erts_debug,no_abstract_code,encrypted_debug_info].
+
+init_per_testcase(_Case, Config) ->
+ Dog=test_server:timetrap(?t:minutes(0.5)),
+ [{watchdog, Dog}|Config].
+fin_per_testcase(_Case, Config) ->
+ Dog=?config(watchdog, Config),
+ test_server:timetrap_cancel(Dog),
+ ok.
+
+app_test(Config) when is_list(Config) ->
+ ?line ?t:app_test(debugger),
+ ok.
+
+erts_debug(Config) when is_list(Config) ->
+ c:l(erts_debug),
+ ok.
+
+no_abstract_code(Config) when is_list(Config) ->
+ ?line PrivDir = ?config(priv_dir, Config),
+ ?line Simple = filename:join(PrivDir, "simple"),
+ ?line Source = Simple ++ ".erl",
+ ?line BeamFile = Simple ++ ".beam",
+ ?line simple_file(Source),
+
+ %% Compile module without abstract code.
+ CompileFlags = [{outdir,PrivDir}],
+ ?line {ok,_} = compile:file(Source, CompileFlags),
+ ?line error = int:i(Simple),
+
+ %% Cleanup.
+ ?line ok = file:delete(Source),
+ ?line ok = file:delete(BeamFile),
+
+ ok.
+
+encrypted_debug_info(Config) when is_list(Config) ->
+ try begin crypto:start(), crypto:info(), crypto:stop(), ok end of
+ ok ->
+ encrypted_debug_info_1(Config)
+ catch
+ error:_ ->
+ {skip,"The crypto application is missing or broken"}
+ end.
+
+encrypted_debug_info_1(Config) ->
+ ?line PrivDir = ?config(priv_dir, Config),
+ ?line Simple = filename:join(PrivDir, "simple"),
+ ?line Source = Simple ++ ".erl",
+ ?line BeamFile = Simple ++ ".beam",
+ ?line simple_file(Source),
+
+ %% Compile module.
+ Key = "_This a Crypto Key_",
+ CompileFlags = [{outdir,PrivDir},debug_info,{debug_info_key,Key}],
+ ?line {ok,_} = compile:file(Source, CompileFlags),
+
+ %% Interpret module
+ ?line ok = beam_lib:crypto_key_fun(simple_crypto_fun(Key)),
+ ?line {module,simple} = int:i(Simple),
+
+ %% Remove key.
+ ?line {ok,_} = beam_lib:clear_crypto_key_fun(),
+ ?line error = int:i(Simple),
+
+ %% Cleanup.
+ ?line ok = file:delete(Source),
+ ?line ok = file:delete(BeamFile),
+
+ ok.
+
+simple_crypto_fun(Key) ->
+ fun(init) -> ok;
+ ({debug_info, des3_cbc, simple, _}) -> Key
+ end.
+
+
+simple_file(File) ->
+ simple_file(File, simple).
+
+simple_file(File, Module) ->
+ simple_file(File, Module, member).
+
+simple_file(File, Module, F) ->
+ B = list_to_binary(["-module(", atom_to_list(Module), "). "
+ "-export([t/0]). "
+ "t() -> "
+ " t([]). "
+ "t(L) -> "
+ " lists:",
+ atom_to_list(F), "(a, L). "]),
+ ok = file:write_file(File, B).
diff --git a/lib/debugger/test/debugger_test.erl b/lib/debugger/test/debugger_test.erl
new file mode 100644
index 0000000000..a64bed5db1
--- /dev/null
+++ b/lib/debugger/test/debugger_test.erl
@@ -0,0 +1,154 @@
+%%
+%% %CopyrightBegin%
+%%
+%% 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%
+%%
+
+%%
+%%%----------------------------------------------------------------------
+%%% Purpose : This is the test module to be used in with the test cases
+%%% in the debugger test document.
+%%%----------------------------------------------------------------------
+
+-module(debugger_test).
+
+
+-export ([installation_ok/0,
+ list/0,
+ fac/1,
+ c_break/1]).
+
+
+-define (INT_DIR, "misc"). % The directory of the Interpreter directory
+-define (INT, "interpreter"). % The Interpreter directory name.
+-define (DBG, "debugger"). % Debugger name
+
+
+%%% installation_ok /0
+%%%
+
+installation_ok () ->
+ debugger_ok (),
+ interpreter_ok ().
+
+
+
+%%% debugger_ok /0
+%%%
+
+debugger_ok () ->
+ L = code:get_path (),
+
+ case debugger_in_codepath (L) of
+ {true, Msg} ->
+ out_put (Msg);
+
+ Other ->
+ out_put (Other)
+ end.
+
+
+
+%%% debugger_in_codepath /2
+%%%
+
+debugger_in_codepath ([]) ->
+ Msg = io_lib:format ("False: ~s not in code path", [?DBG]),
+ lists:flatten (Msg);
+
+debugger_in_codepath ([Path | T]) ->
+ case string:str (Path, ?DBG) =/= 0 of
+ true ->
+ Msg = io_lib:format ("Ok: ~s in code path (~s)", [?DBG, Path]),
+ Msg1 = lists:flatten (Msg),
+ {true, Msg1};
+
+ _Other ->
+ debugger_in_codepath (T)
+ end.
+
+
+
+%%% interpreter_ok /0
+%%%
+
+interpreter_ok () ->
+ Root_dir = code:root_dir (),
+ Misc_dir = filename:join (Root_dir, ?INT_DIR),
+
+ In_misc = case file:list_dir (Misc_dir) of
+ {ok, L} ->
+ lists:member (?INT, L);
+
+ Other ->
+ Other
+ end,
+
+ case In_misc of
+ true ->
+ Msg = io_lib:format ("Ok: ~s is in ~s", [?INT, ?INT_DIR]),
+ Msg1 = lists:flatten (Msg),
+ out_put (Msg1);
+
+ Other1 ->
+ Msg = io_lib:format ("Error: interpreter in misc - ~s", [Other1]),
+ Msg1 = lists:flatten (Msg),
+ out_put (Msg1)
+ end.
+
+
+
+%%% list /0
+%%%
+
+list () ->
+ A = [1, 2, 3, 4, 5],
+ B = [a, b, c, d, e],
+ lists:append (A, B).
+
+
+
+%%% fac /1
+%%%
+
+fac (0) ->
+ 1;
+
+
+fac (N) ->
+ N * fac (N - 1).
+
+
+
+%%% c_break /1
+%%%
+
+c_break (Bindings) ->
+ case int:get_binding ('N', Bindings) of
+ {value, 3} ->
+ true;
+
+ _Other ->
+ false
+ end.
+
+
+
+%%% out_put /1
+%%%
+
+out_put (X) ->
+ io:format ("~n~p~n", [X]).
diff --git a/lib/debugger/test/debugger_testdoc.fm5 b/lib/debugger/test/debugger_testdoc.fm5
new file mode 100644
index 0000000000..56882b8bd5
--- /dev/null
+++ b/lib/debugger/test/debugger_testdoc.fm5
Binary files differ
diff --git a/lib/debugger/test/erl_eval_SUITE.erl b/lib/debugger/test/erl_eval_SUITE.erl
new file mode 100644
index 0000000000..fd4d28b2c7
--- /dev/null
+++ b/lib/debugger/test/erl_eval_SUITE.erl
@@ -0,0 +1,1388 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 2003-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(erl_eval_SUITE).
+-export([all/1]).
+
+-export([guard_1/1, guard_2/1,
+ match_pattern/1,
+ match_bin/1,
+ string_plusplus/1,
+ pattern_expr/1,
+ guard_3/1, guard_4/1,
+ lc/1,
+ simple_cases/1,
+ unary_plus/1,
+ apply_atom/1,
+ otp_5269/1,
+ otp_6539/1,
+ otp_6543/1,
+ otp_6787/1,
+ otp_6977/1,
+ otp_7550/1,
+ otp_8133/1,
+ funs/1,
+ try_catch/1,
+ eval_expr_5/1]).
+
+%%
+%% Define to run outside of test server
+%%
+%%-define(STANDALONE,1).
+
+-import(lists,[concat/1, sort/1]).
+
+-export([count_down/2, count_down_fun/0, do_apply/2,
+ local_func/3, local_func_value/2]).
+
+-ifdef(STANDALONE).
+-define(config(A,B),config(A,B)).
+-export([config/2]).
+-define(line, noop, ).
+config(priv_dir,_) ->
+ ".".
+-else.
+-include("test_server.hrl").
+-export([init_per_testcase/2, fin_per_testcase/2]).
+% Default timetrap timeout (set in init_per_testcase).
+-define(default_timeout, ?t:minutes(1)).
+init_per_testcase(_Case, Config) ->
+ ?line Dog = ?t:timetrap(?default_timeout),
+ [{watchdog, Dog} | Config].
+fin_per_testcase(_Case, Config) ->
+ Dog = ?config(watchdog, Config),
+ test_server:timetrap_cancel(Dog),
+ ok.
+-endif.
+
+all(doc) ->
+ ["Test cases for the 'erl_eval' module."];
+all(suite) ->
+ [guard_1, guard_2, match_pattern, string_plusplus, pattern_expr,
+ match_bin, guard_3, guard_4,
+ lc, simple_cases, unary_plus, apply_atom, otp_5269, otp_6539, otp_6543,
+ otp_6787, otp_6977, otp_7550, otp_8133, funs, try_catch, eval_expr_5].
+
+guard_1(doc) ->
+ ["(OTP-2405)"];
+guard_1(suite) ->
+ [];
+guard_1(Config) when is_list(Config) ->
+ ?line {ok,Tokens ,_} =
+ erl_scan:string("if a+4 == 4 -> yes; true -> no end. "),
+ ?line {ok, [Expr]} = erl_parse:parse_exprs(Tokens),
+ ?line no = guard_1_compiled(),
+ ?line {value, no, []} = erl_eval:expr(Expr, []),
+ ok.
+
+guard_1_compiled() ->
+ if a+4 == 4 -> yes; true -> no end.
+
+guard_2(doc) ->
+ ["Similar to guard_1, but type-correct"];
+guard_2(suite) ->
+ [];
+guard_2(Config) when is_list(Config) ->
+ ?line {ok,Tokens ,_} =
+ erl_scan:string("if 6+4 == 4 -> yes; true -> no end. "),
+ ?line {ok, [Expr]} = erl_parse:parse_exprs(Tokens),
+ ?line no = guard_2_compiled(),
+ ?line {value, no, []} = erl_eval:expr(Expr, []),
+ ok.
+
+guard_2_compiled() ->
+ if 6+4 == 4 -> yes; true -> no end.
+
+string_plusplus(doc) ->
+ ["OTP-3069: syntactic sugar string ++ ..."];
+string_plusplus(suite) ->
+ [];
+string_plusplus(Config) when is_list(Config) ->
+ ?line check(fun() -> case "abc" of "ab" ++ L -> L end end,
+ "case \"abc\" of \"ab\" ++ L -> L end. ",
+ "c"),
+ ?line check(fun() -> case "abcde" of "ab" ++ "cd" ++ L -> L end end,
+ "case \"abcde\" of \"ab\" ++ \"cd\" ++ L -> L end. ",
+ "e"),
+ ?line check(fun() -> case "abc" of [97, 98] ++ L -> L end end,
+ "case \"abc\" of [97, 98] ++ L -> L end. ",
+ "c"),
+ ok.
+
+match_pattern(doc) ->
+ ["OTP-2983: match operator in pattern"];
+match_pattern(suite) ->
+ [];
+match_pattern(Config) when is_list(Config) ->
+ ?line check(fun() -> case {a, b} of {a, _X}=Y -> {x,Y} end end,
+ "case {a, b} of {a, X}=Y -> {x,Y} end. ",
+ {x, {a, b}}),
+ ?line check(fun() -> case {a, b} of Y={a, _X} -> {x,Y} end end,
+ "case {a, b} of Y={a, X} -> {x,Y} end. ",
+ {x, {a, b}}),
+ ?line check(fun() -> case {a, b} of Y={a, _X}=Z -> {Z,Y} end end,
+ "case {a, b} of Y={a, X}=Z -> {Z,Y} end. ",
+ {{a, b}, {a, b}}),
+ ?line check(fun() -> A = 4, B = 28, <<13:(A+(X=B))>>, X end,
+ "begin A = 4, B = 28, <<13:(A+(X=B))>>, X end.",
+ 28),
+ ok.
+
+match_bin(doc) ->
+ ["binary match problems"];
+match_bin(suite) ->
+ [];
+match_bin(Config) when is_list(Config) ->
+ ?line check(fun() -> <<"abc">> = <<"abc">> end,
+ "<<\"abc\">> = <<\"abc\">>. ",
+ <<"abc">>),
+ ?line check(fun() ->
+ <<Size,B:Size/binary,Rest/binary>> = <<2,"AB","CD">>,
+ {Size,B,Rest}
+ end,
+ "begin <<Size,B:Size/binary,Rest/binary>> = <<2,\"AB\",\"CD\">>, "
+ "{Size,B,Rest} end. ",
+ {2,<<"AB">>,<<"CD">>}),
+ ok.
+
+pattern_expr(doc) ->
+ ["OTP-3144: compile-time expressions in pattern"];
+pattern_expr(suite) ->
+ [];
+pattern_expr(Config) when is_list(Config) ->
+ ?line check(fun() -> case 4 of 2+2 -> ok end end,
+ "case 4 of 2+2 -> ok end. ",
+ ok),
+ ?line check(fun() -> case 2 of +2 -> ok end end,
+ "case 2 of +2 -> ok end. ",
+ ok),
+ ok.
+
+guard_3(doc) ->
+ ["OTP-4518."];
+guard_3(suite) ->
+ [];
+guard_3(Config) when is_list(Config) ->
+ ?line check(fun() -> if false -> false; true -> true end end,
+ "if false -> false; true -> true end.",
+ true),
+ ?line check(fun() -> if <<"hej">> == <<"hopp">> -> true;
+ true -> false end end,
+ "begin if <<\"hej\">> == <<\"hopp\">> -> true;
+ true -> false end end.",
+ false),
+ ?line check(fun() -> if <<"hej">> == <<"hej">> -> true;
+ true -> false end end,
+ "begin if <<\"hej\">> == <<\"hej\">> -> true;
+ true -> false end end.",
+ true),
+ ok.
+
+guard_4(doc) ->
+ ["OTP-4885."];
+guard_4(suite) ->
+ [];
+guard_4(Config) when is_list(Config) ->
+ ?line check(fun() -> if {erlang,'+'}(3,a) -> true ; true -> false end end,
+ "if {erlang,'+'}(3,a) -> true ; true -> false end.",
+ false),
+ ?line check(fun() -> if {erlang,is_integer}(3) -> true ; true -> false end
+ end,
+ "if {erlang,is_integer}(3) -> true ; true -> false end.",
+ true),
+ ?line check(fun() -> [X || X <- [1,2,3], erlang:is_integer(X)] end,
+ "[X || X <- [1,2,3], erlang:is_integer(X)].",
+ [1,2,3]),
+ ?line check(fun() -> if is_atom(is_integer(a)) -> true ; true -> false end
+ end,
+ "if is_atom(is_integer(a)) -> true ; true -> false end.",
+ true),
+ ?line check(fun() -> if {erlang,is_atom}({erlang,is_integer}(a)) -> true;
+ true -> false end end,
+ "if {erlang,is_atom}({erlang,is_integer}(a)) -> true; "
+ "true -> false end.",
+ true),
+ ?line check(fun() -> if is_atom(3+a) -> true ; true -> false end end,
+ "if is_atom(3+a) -> true ; true -> false end.",
+ false),
+ ?line check(fun() -> if erlang:is_atom(3+a) -> true ; true -> false end
+ end,
+ "if erlang:is_atom(3+a) -> true ; true -> false end.",
+ false),
+ ok.
+
+
+lc(doc) ->
+ ["OTP-4518."];
+lc(suite) ->
+ [];
+lc(Config) when is_list(Config) ->
+ ?line check(fun() -> X = 32, [X || X <- [1,2,3]] end,
+ "begin X = 32, [X || X <- [1,2,3]] end.",
+ [1,2,3]),
+ ?line check(fun() -> X = 32,
+ [X || <<X:X>> <- [<<1:32>>,<<2:32>>,<<3:8>>]] end,
+ %% "binsize variable" ^
+ "begin X = 32,
+ [X || <<X:X>> <- [<<1:32>>,<<2:32>>,<<3:8>>]] end.",
+ [1,2]),
+ ?line check(fun() -> Y = 13,[X || {X,Y} <- [{1,2}]] end,
+ "begin Y = 13,[X || {X,Y} <- [{1,2}]] end.",
+ [1]),
+ ?line error_check("begin [A || X <- [{1,2}], 1 == A] end.",
+ {unbound_var,'A'}),
+ ?line error_check("begin X = 32,
+ [{Y,W} || X <- [1,2,32,Y=4], Z <- [1,2,W=3]] end.",
+ {unbound_var,'Y'}),
+ ?line error_check("begin X = 32,<<A:B>> = <<100:X>> end.",
+ {unbound_var,'B'}),
+ ?line check(fun() -> [X || X <- [1,2,3,4], not (X < 2)] end,
+ "begin [X || X <- [1,2,3,4], not (X < 2)] end.",
+ [2,3,4]),
+ ?line check(fun() -> [X || X <- [true,false], X] end,
+ "[X || X <- [true,false], X].", [true]),
+ ok.
+
+simple_cases(doc) ->
+ ["Simple cases, just to cover some code."];
+simple_cases(suite) ->
+ [];
+simple_cases(Config) when is_list(Config) ->
+ ?line check(fun() -> A = $C end, "A = $C.", $C),
+ %% ?line check(fun() -> A = 3.14 end, "A = 3.14.", 3.14),
+ ?line check(fun() -> self() ! a, A = receive a -> true end end,
+ "begin self() ! a, A = receive a -> true end end.",
+ true),
+ ?line check(fun() -> c:flush(), self() ! a, self() ! b, self() ! c,
+ receive b -> b end,
+ {messages, [a,c]} =
+ erlang:process_info(self(), messages),
+ c:flush() end,
+ "begin c:flush(), self() ! a, self() ! b, self() ! c,"
+ "receive b -> b end,"
+ "{messages, [a,c]} ="
+ " erlang:process_info(self(), messages), c:flush() end.",
+ ok),
+ ?line check(fun() -> self() ! a, A = receive a -> true
+ after 0 -> false end end,
+ "begin self() ! a, A = receive a -> true"
+ " after 0 -> false end end.",
+ true),
+ ?line check(fun() -> c:flush(), self() ! a, self() ! b, self() ! c,
+ receive b -> b after 0 -> true end,
+ {messages, [a,c]} =
+ erlang:process_info(self(), messages),
+ c:flush() end,
+ "begin c:flush(), self() ! a, self() ! b, self() ! c,"
+ "receive b -> b after 0 -> true end,"
+ "{messages, [a,c]} ="
+ " erlang:process_info(self(), messages), c:flush() end.",
+ ok),
+ ?line check(fun() -> receive _ -> true after 10 -> false end end,
+ "receive _ -> true after 10 -> false end.",
+ false),
+ ?line check(fun() -> F = fun(A) -> A end, true = 3 == F(3) end,
+ "begin F = fun(A) -> A end, true = 3 == F(3) end.",
+ true),
+ ?line check(fun() -> F = fun(A) -> A end, true = 3 == apply(F, [3]) end,
+ "begin F = fun(A) -> A end, true = 3 == apply(F,[3]) end.",
+ true),
+ ?line check(fun() -> catch throw(a) end, "catch throw(a).", a),
+ ?line check(fun() -> catch a end, "catch a.", a),
+ ?line check(fun() -> 4 == 3 end, "4 == 3.", false),
+ ?line check(fun() -> not true end, "not true.", false),
+ ?line check(fun() -> -3 end, "-3.", -3),
+
+ ?line error_check("3.0 = 4.0.", {badmatch,4.0}),
+ ?line check(fun() -> <<(3.0+2.0):32/float>> = <<5.0:32/float>> end,
+ "<<(3.0+2.0):32/float>> = <<5.0:32/float>>.",
+ <<5.0:32/float>>),
+
+ ?line check(fun() -> false andalso kludd end, "false andalso kludd.",
+ false),
+ ?line check(fun() -> true andalso true end, "true andalso true.",
+ true),
+ ?line check(fun() -> true andalso false end, "true andalso false.",
+ false),
+ ?line check(fun() -> true andalso kludd end, "true andalso kludd.",
+ kludd),
+ ?line error_check("kladd andalso kludd.", {badarg,kladd}),
+
+ ?line check(fun() -> if false andalso kludd -> a; true -> b end end,
+ "if false andalso kludd -> a; true -> b end.",
+ b),
+ ?line check(fun() -> if true andalso true -> a; true -> b end end,
+ "if true andalso true -> a; true -> b end.",
+ a),
+ ?line check(fun() -> if true andalso false -> a; true -> b end end,
+ "if true andalso false -> a; true -> b end.",
+ b),
+
+ ?line check(fun() -> true orelse kludd end,
+ "true orelse kludd.", true),
+ ?line check(fun() -> false orelse false end,
+ "false orelse false.", false),
+ ?line check(fun() -> false orelse true end,
+ "false orelse true.", true),
+ ?line check(fun() -> false orelse kludd end,
+ "false orelse kludd.", kludd),
+ ?line error_check("kladd orelse kludd.", {badarg,kladd}),
+ ?line error_check("[X || X <- [1,2,3], begin 1 end].",{bad_filter,1}),
+ ?line error_check("[X || X <- a].",{bad_generator,a}),
+
+ ?line check(fun() -> if true orelse kludd -> a; true -> b end end,
+ "if true orelse kludd -> a; true -> b end.", a),
+ ?line check(fun() -> if false orelse false -> a; true -> b end end,
+ "if false orelse false -> a; true -> b end.", b),
+ ?line check(fun() -> if false orelse true -> a; true -> b end end,
+ "if false orelse true -> a; true -> b end.", a),
+
+ ?line check(fun() -> [X || X <- [1,2,3], X+2] end,
+ "[X || X <- [1,2,3], X+2].", []),
+
+ ?line check(fun() -> [X || X <- [1,2,3], [X] == [X || X <- [2]]] end,
+ "[X || X <- [1,2,3], [X] == [X || X <- [2]]].",
+ [2]),
+ ?line check(fun() -> F = fun(1) -> ett; (2) -> zwei end,
+ ett = F(1), zwei = F(2) end,
+ "begin F = fun(1) -> ett; (2) -> zwei end,
+ ett = F(1), zwei = F(2) end.",
+ zwei),
+ ?line check(fun() -> F = fun(X) when X == 1 -> ett;
+ (X) when X == 2 -> zwei end,
+ ett = F(1), zwei = F(2) end,
+ "begin F = fun(X) when X == 1 -> ett;
+ (X) when X == 2 -> zwei end,
+ ett = F(1), zwei = F(2) end.",
+ zwei),
+ ?line error_check("begin F = fun(1) -> ett end, zwei = F(2) end.",
+ function_clause),
+ ?line check(fun() -> if length([1]) == 1 -> yes;
+ true -> no end end,
+ "if length([1]) == 1 -> yes;
+ true -> no end.",
+ yes),
+ ?line check(fun() -> if is_integer(3) -> true; true -> false end end,
+ "if is_integer(3) -> true; true -> false end.", true),
+ ?line check(fun() -> if integer(3) -> true; true -> false end end,
+ "if integer(3) -> true; true -> false end.", true),
+ ?line check(fun() -> if is_float(3) -> true; true -> false end end,
+ "if is_float(3) -> true; true -> false end.", false),
+ ?line check(fun() -> if float(3) -> true; true -> false end end,
+ "if float(3) -> true; true -> false end.", false),
+ ?line check(fun() -> if is_number(3) -> true; true -> false end end,
+ "if is_number(3) -> true; true -> false end.", true),
+ ?line check(fun() -> if number(3) -> true; true -> false end end,
+ "if number(3) -> true; true -> false end.", true),
+ ?line check(fun() -> if is_atom(a) -> true; true -> false end end,
+ "if is_atom(a) -> true; true -> false end.", true),
+ ?line check(fun() -> if atom(a) -> true; true -> false end end,
+ "if atom(a) -> true; true -> false end.", true),
+ ?line check(fun() -> if is_list([]) -> true; true -> false end end,
+ "if is_list([]) -> true; true -> false end.", true),
+ ?line check(fun() -> if list([]) -> true; true -> false end end,
+ "if list([]) -> true; true -> false end.", true),
+ ?line check(fun() -> if is_tuple({}) -> true; true -> false end end,
+ "if is_tuple({}) -> true; true -> false end.", true),
+ ?line check(fun() -> if tuple({}) -> true; true -> false end end,
+ "if tuple({}) -> true; true -> false end.", true),
+ ?line check(fun() -> if is_pid(self()) -> true; true -> false end end,
+ "if is_pid(self()) -> true; true -> false end.", true),
+ ?line check(fun() -> if pid(self()) -> true; true -> false end end,
+ "if pid(self()) -> true; true -> false end.", true),
+ ?line check(fun() -> R = make_ref(), if is_reference(R) -> true;
+ true -> false end end,
+ "begin R = make_ref(), if is_reference(R) -> true;"
+ "true -> false end end.", true),
+ ?line check(fun() -> R = make_ref(), if reference(R) -> true;
+ true -> false end end,
+ "begin R = make_ref(), if reference(R) -> true;"
+ "true -> false end end.", true),
+ ?line check(fun() -> if is_port(a) -> true; true -> false end end,
+ "if is_port(a) -> true; true -> false end.", false),
+ ?line check(fun() -> if port(a) -> true; true -> false end end,
+ "if port(a) -> true; true -> false end.", false),
+ ?line check(fun() -> if is_function(a) -> true; true -> false end end,
+ "if is_function(a) -> true; true -> false end.", false),
+ ?line check(fun() -> if function(a) -> true; true -> false end end,
+ "if function(a) -> true; true -> false end.", false),
+ ?line check(fun() -> if is_binary(<<>>) -> true; true -> false end end,
+ "if is_binary(<<>>) -> true; true -> false end.", true),
+ ?line check(fun() -> if binary(<<>>) -> true; true -> false end end,
+ "if binary(<<>>) -> true; true -> false end.", true),
+ ?line check(fun() -> if is_integer(a) == true -> yes;
+ true -> no end end,
+ "if is_integer(a) == true -> yes;
+ true -> no end.",
+ no),
+ ?line check(fun() -> if [] -> true; true -> false end end,
+ "if [] -> true; true -> false end.", false),
+ ?line error_check("if lists:member(1,[1]) -> true; true -> false end.",
+ illegal_guard_expr),
+ ?line error_check("if false -> true end.", if_clause),
+ ?line check(fun() -> if a+b -> true; true -> false end end,
+ "if a + b -> true; true -> false end.", false),
+ ?line check(fun() -> if + b -> true; true -> false end end,
+ "if + b -> true; true -> false end.", false),
+ ?line error_check("case foo of bar -> true end.", {case_clause,foo}),
+ ?line error_check("case 4 of 2+a -> true; _ -> false end.",
+ illegal_pattern),
+ ?line error_check("case 4 of +a -> true; _ -> false end.",
+ illegal_pattern),
+ ?line check(fun() -> case a of
+ X when X == b -> one;
+ X when X == a -> two
+ end end,
+ "begin case a of
+ X when X == b -> one;
+ X when X == a -> two
+ end end.", two),
+ ?line error_check("3 = 4.", {badmatch,4}),
+ ?line error_check("a = 3.", {badmatch,3}),
+ %% ?line error_check("3.1 = 2.7.",{badmatch,2.7}),
+ ?line error_check("$c = 4.", {badmatch,4}),
+ ?line check(fun() -> $c = $c end, "$c = $c.", $c),
+ ?line check(fun() -> _ = bar end, "_ = bar.", bar),
+ ?line check(fun() -> A = 14, A = 14 end,
+ "begin A = 14, A = 14 end.", 14),
+ ?line error_check("begin A = 14, A = 16 end.", {badmatch,16}),
+ ?line error_check("\"hej\" = \"san\".", {badmatch,"san"}),
+ ?line check(fun() -> "hej" = "hej" end,
+ "\"hej\" = \"hej\".", "hej"),
+ ?line error_check("[] = [a].", {badmatch,[a]}),
+ ?line check(fun() -> [] = [] end, "[] = [].", []),
+ ?line error_check("[a] = [].", {badmatch,[]}),
+ ?line error_check("{a,b} = 34.", {badmatch,34}),
+ ?line check(fun() -> <<X:7>> = <<8:7>>, X end,
+ "begin <<X:7>> = <<8:7>>, X end.", 8),
+ ?line error_check("<<34:32>> = \"hej\".", {badmatch,"hej"}),
+ ?line check(fun() -> trunc((1 * 3 div 3 + 4 - 3) / 1) rem 2 end,
+ "begin trunc((1 * 3 div 3 + 4 - 3) / 1) rem 2 end.", 0),
+ ?line check(fun() -> (2#101 band 2#10101) bor (2#110 bxor 2#010) end,
+ "(2#101 band 2#10101) bor (2#110 bxor 2#010).", 5),
+ ?line check(fun() -> (2#1 bsl 4) + (2#10000 bsr 3) end,
+ "(2#1 bsl 4) + (2#10000 bsr 3).", 18),
+ ?line check(fun() -> ((1<3) and ((1 =:= 2) or (1 =/= 2))) xor (1=<2) end,
+ "((1<3) and ((1 =:= 2) or (1 =/= 2))) xor (1=<2).", false),
+ ?line check(fun() -> (a /= b) or (2 > 4) or (3 >= 3) end,
+ "(a /= b) or (2 > 4) or (3 >= 3).", true),
+ ?line check(fun() -> "hej" ++ "san" =/= "hejsan" -- "san" end,
+ "\"hej\" ++ \"san\" =/= \"hejsan\" -- \"san\".", true),
+ ?line check(fun() -> (bnot 1) < -0 end, "(bnot (+1)) < -0.", true),
+ ok.
+
+unary_plus(doc) ->
+ ["OTP-4929. Unary plus rejects non-numbers."];
+unary_plus(suite) ->
+ [];
+unary_plus(Config) when is_list(Config) ->
+ ?line check(fun() -> F = fun(X) -> + X end,
+ true = -1 == F(-1) end,
+ "begin F = fun(X) -> + X end,"
+ " true = -1 == F(-1) end.", true, ['F'], none, none),
+ ?line error_check("+a.", badarith),
+ ok.
+
+apply_atom(doc) ->
+ ["OTP-5064. Can no longer apply atoms."];
+apply_atom(suite) ->
+ [];
+apply_atom(Config) when is_list(Config) ->
+ ?line error_check("[X || X <- [[1],[2]],
+ begin L = length, L(X) =:= 1 end].",
+ {badfun,length}),
+ ok.
+
+otp_5269(doc) ->
+ ["OTP-5269. Bugs in the bit syntax."];
+otp_5269(suite) ->
+ [];
+otp_5269(Config) when is_list(Config) ->
+ ?line check(fun() -> L = 8,
+ F = fun(<<A:L,B:A>>) -> B end,
+ F(<<16:8, 7:16>>)
+ end,
+ "begin
+ L = 8, F = fun(<<A:L,B:A>>) -> B end, F(<<16:8, 7:16>>)
+ end.",
+ 7),
+ ?line check(fun() -> L = 8,
+ F = fun(<<L:L,B:L>>) -> B end,
+ F(<<16:8, 7:16>>)
+ end,
+ "begin
+ L = 8, F = fun(<<L:L,B:L>>) -> B end, F(<<16:8, 7:16>>)
+ end.",
+ 7),
+ ?line check(fun() -> L = 8, <<A:L,B:A>> = <<16:8, 7:16>>, B end,
+ "begin L = 8, <<A:L,B:A>> = <<16:8, 7:16>>, B end.",
+ 7),
+ ?line error_check("begin L = 8, <<L:L,B:L>> = <<16:8, 7:16>> end.",
+ {badmatch,<<16:8,7:16>>}),
+
+ ?line error_check("begin <<L:16,L:L>> = <<16:16,8:16>>, L end.",
+ {badmatch, <<16:16,8:16>>}),
+ ?line check(fun() -> U = 8, (fun(<<U:U>>) -> U end)(<<32:8>>) end,
+ "begin U = 8, (fun(<<U:U>>) -> U end)(<<32:8>>) end.",
+ 32),
+ ?line check(fun() -> U = 8, [U || <<U:U>> <- [<<32:8>>]] end,
+ "begin U = 8, [U || <<U:U>> <- [<<32:8>>]] end.",
+ [32]),
+ ?line error_check("(fun({3,<<A:32,A:32>>}) -> a end)
+ ({3,<<17:32,19:32>>}).",
+ function_clause),
+ ?line check(fun() -> [X || <<A:8,
+ B:A>> <- [<<16:8,19:16>>],
+ <<X:8>> <- [<<B:8>>]] end,
+ "[X || <<A:8,
+ B:A>> <- [<<16:8,19:16>>],
+ <<X:8>> <- [<<B:8>>]].",
+ [19]),
+ ok.
+
+otp_6539(doc) ->
+ ["OTP-6539. try/catch bugs."];
+otp_6539(suite) ->
+ [];
+otp_6539(Config) when is_list(Config) ->
+ ?line check(fun() ->
+ F = fun(A,B) ->
+ try A+B
+ catch _:_ -> dontthinkso
+ end
+ end,
+ lists:zipwith(F, [1,2], [2,3])
+ end,
+ "begin
+ F = fun(A,B) ->
+ try A+B
+ catch _:_ -> dontthinkso
+ end
+ end,
+ lists:zipwith(F, [1,2], [2,3])
+ end.",
+ [3, 5]),
+ ok.
+
+otp_6543(doc) ->
+ ["OTP-6543. bitlevel binaries."];
+otp_6543(suite) ->
+ [];
+otp_6543(Config) when is_list(Config) ->
+ ?line check(fun() ->
+ << <<X>> || <<X>> <- [1,2,3] >>
+ end,
+ "<< <<X>> || <<X>> <- [1,2,3] >>.",
+ <<>>),
+ ?line check(fun() ->
+ << <<X>> || X <- [1,2,3] >>
+ end,
+ "<< <<X>> || X <- [1,2,3] >>.",
+ <<1,2,3>>),
+ ?line check(fun() ->
+ << <<X:8>> || <<X:2>> <= <<"hej">> >>
+ end,
+ "<< <<X:8>> || <<X:2>> <= <<\"hej\">> >>.",
+ <<1,2,2,0,1,2,1,1,1,2,2,2>>),
+ ?line check(fun() ->
+ << <<X:8>> ||
+ <<65,X:4>> <= <<65,7:4,65,3:4,66,8:4>> >>
+ end,
+ "<< <<X:8>> ||
+ <<65,X:4>> <= <<65,7:4,65,3:4,66,8:4>> >>.",
+ <<7,3>>),
+ ?line check(fun() -> <<34:18/big>> end,
+ "<<34:18/big>>.",
+ <<0,8,2:2>>),
+ ?line check(fun() -> <<34:18/big-unit:2>> end,
+ "<<34:18/big-unit:2>>.",
+ <<0,0,0,2,2:4>>),
+ ?line check(fun() -> <<34:18/little>> end,
+ "<<34:18/little>>.",
+ <<34,0,0:2>>),
+ ?line case eval_string("<<34:18/native>>.") of
+ <<0,8,2:2>> -> ok;
+ <<34,0,0:2>> -> ok
+ end,
+ ?line check(fun() -> <<34:18/big-signed>> end,
+ "<<34:18/big-signed>>.",
+ <<0,8,2:2>>),
+ ?line check(fun() -> <<34:18/little-signed>> end,
+ "<<34:18/little-signed>>.",
+ <<34,0,0:2>>),
+ ?line case eval_string("<<34:18/native-signed>>.") of
+ <<0,8,2:2>> -> ok;
+ <<34,0,0:2>> -> ok
+ end,
+ ?line check(fun() -> <<34:18/big-unsigned>> end,
+ "<<34:18/big-unsigned>>.",
+ <<0,8,2:2>>),
+ ?line check(fun() -> <<34:18/little-unsigned>> end,
+ "<<34:18/little-unsigned>>.",
+ <<34,0,0:2>>),
+ ?line case eval_string("<<34:18/native-unsigned>>.") of
+ <<0,8,2:2>> -> ok;
+ <<34,0,0:2>> -> ok
+ end,
+ ?line check(fun() -> <<3.14:32/float-big>> end,
+ "<<3.14:32/float-big>>.",
+ <<64,72,245,195>>),
+ ?line check(fun() -> <<3.14:32/float-little>> end,
+ "<<3.14:32/float-little>>.",
+ <<195,245,72,64>>),
+ ?line case eval_string("<<3.14:32/float-native>>.") of
+ <<64,72,245,195>> -> ok;
+ <<195,245,72,64>> -> ok
+ end,
+ ?line error_check("<<(<<17,3:2>>)/binary>>.", badarg),
+ ?line check(fun() -> <<(<<17,3:2>>)/bitstring>> end,
+ "<<(<<17,3:2>>)/bitstring>>.",
+ <<17,3:2>>),
+ ?line check(fun() -> <<(<<17,3:2>>):10/bitstring>> end,
+ "<<(<<17,3:2>>):10/bitstring>>.",
+ <<17,3:2>>),
+ ?line check(fun() -> <<<<344:17>>/binary-unit:17>> end,
+ "<<<<344:17>>/binary-unit:17>>.",
+ <<344:17>>),
+
+ ?line check(fun() -> <<X:18/big>> = <<34:18/big>>, X end,
+ "begin <<X:18/big>> = <<34:18/big>>, X end.",
+ 34),
+ ?line check(fun() -> <<X:18/big-unit:2>> = <<34:18/big-unit:2>>, X end,
+ "begin <<X:18/big-unit:2>> = <<34:18/big-unit:2>>, X end.",
+ 34),
+ ?line check(fun() -> <<X:18/little>> = <<34:18/little>>, X end,
+ "begin <<X:18/little>> = <<34:18/little>>, X end.",
+ 34),
+ ?line check(fun() -> <<X:18/native>> = <<34:18/native>>, X end,
+ "begin <<X:18/native>> = <<34:18/native>>, X end.",
+ 34),
+ ?line check(fun() -> <<X:18/big-signed>> = <<34:18/big-signed>>, X end,
+ "begin <<X:18/big-signed>> = <<34:18/big-signed>>, X end.",
+ 34),
+ ?line check(fun() -> <<X:18/little-signed>> = <<34:18/little-signed>>,
+ X end,
+ "begin <<X:18/little-signed>> = <<34:18/little-signed>>,
+ X end.",
+ 34),
+ ?line check(fun() -> <<X:18/native-signed>> = <<34:18/native-signed>>,
+ X end,
+ "begin <<X:18/native-signed>> = <<34:18/native-signed>>,
+ X end.",
+ 34),
+ ?line check(fun() -> <<X:18/big-unsigned>> = <<34:18/big-unsigned>>,
+ X end,
+ "begin <<X:18/big-unsigned>> = <<34:18/big-unsigned>>,
+ X end.",
+ 34),
+ ?line check(fun() ->
+ <<X:18/little-unsigned>> = <<34:18/little-unsigned>>,
+ X end,
+ "begin <<X:18/little-unsigned>> = <<34:18/little-unsigned>>,
+ X end.",
+ 34),
+ ?line check(fun() ->
+ <<X:18/native-unsigned>> = <<34:18/native-unsigned>>,
+ X end,
+ "begin <<X:18/native-unsigned>> = <<34:18/native-unsigned>>,
+ X end.",
+ 34),
+ ?line check(fun() -> <<X:32/float-big>> = <<2.0:32/float-big>>, X end,
+ "begin <<X:32/float-big>> = <<2.0:32/float-big>>,
+ X end.",
+ 2.0),
+ ?line check(fun() -> <<X:32/float-little>> = <<2.0:32/float-little>>,
+ X end,
+ "begin <<X:32/float-little>> = <<2.0:32/float-little>>,
+ X end.",
+ 2.0),
+ ?line check(fun() -> <<X:32/float-native>> = <<2.0:32/float-native>>,
+ X end,
+ "begin <<X:32/float-native>> = <<2.0:32/float-native>>,
+ X end.",
+ 2.0),
+
+ ?line check(
+ fun() ->
+ [X || <<"hej",X:8>> <= <<"hej",8,"san",9,"hej",17,"hej">>]
+ end,
+ "[X || <<\"hej\",X:8>> <=
+ <<\"hej\",8,\"san\",9,\"hej\",17,\"hej\">>].",
+ [8,17]),
+ ?line check(
+ fun() ->
+ L = 8, << <<B:32>> || <<L:L,B:L>> <= <<16:8, 7:16>> >>
+ end,
+ "begin L = 8, << <<B:32>> || <<L:L,B:L>> <= <<16:8, 7:16>> >>
+ end.",
+ <<0,0,0,7>>),
+ %% Test the Value part of a binary segment.
+ %% "Old" bugs have been fixed (partial_eval is called on Value).
+ ?line check(fun() -> [ 3 || <<17/float>> <= <<17.0/float>>] end,
+ "[ 3 || <<17/float>> <= <<17.0/float>>].",
+ [3]),
+ ?line check(fun() -> [ 3 || <<17/float>> <- [<<17.0/float>>]] end,
+ "[ 3 || <<17/float>> <- [<<17.0/float>>]].",
+ [3]),
+ ?line check(fun() -> [ X || <<17/float,X:3>> <= <<17.0/float,2:3>>] end,
+ "[ X || <<17/float,X:3>> <= <<17.0/float,2:3>>].",
+ [2]),
+ ?line check(fun() ->
+ [ foo || <<(1 bsl 1023)/float>> <= <<(1 bsl 1023)/float>>]
+ end,
+ "[ foo || <<(1 bsl 1023)/float>> <= <<(1 bsl 1023)/float>>].",
+ [foo]),
+ ?line check(fun() ->
+ [ foo || <<(1 bsl 1023)/float>> <- [<<(1 bsl 1023)/float>>]]
+ end,
+ "[ foo || <<(1 bsl 1023)/float>> <- [<<(1 bsl 1023)/float>>]].",
+ [foo]),
+ ?line error_check("[ foo || <<(1 bsl 1024)/float>> <-
+ [<<(1 bsl 1024)/float>>]].",
+ badarg),
+ ?line check(fun() ->
+ [ foo || <<(1 bsl 1024)/float>> <- [<<(1 bsl 1023)/float>>]]
+ end,
+ "[ foo || <<(1 bsl 1024)/float>> <-
+ [<<(1 bsl 1023)/float>>]].",
+ []),
+ ?line check(fun() ->
+ [ foo || <<(1 bsl 1024)/float>> <= <<(1 bsl 1023)/float>>]
+ end,
+ "[ foo || <<(1 bsl 1024)/float>> <=
+ <<(1 bsl 1023)/float>>].",
+ []),
+ ?line check(fun() ->
+ L = 8,
+ [{L,B} || <<L:L,B:L/float>> <= <<32:8,7:32/float>>]
+ end,
+ "begin L = 8,
+ [{L,B} || <<L:L,B:L/float>> <= <<32:8,7:32/float>>]
+ end.",
+ [{32,7.0}]),
+ ?line check(fun() ->
+ L = 8,
+ [{L,B} || <<L:L,B:L/float>> <- [<<32:8,7:32/float>>]]
+ end,
+ "begin L = 8,
+ [{L,B} || <<L:L,B:L/float>> <- [<<32:8,7:32/float>>]]
+ end.",
+ [{32,7.0}]),
+ ?line check(fun() ->
+ [foo || <<"s">> <= <<"st">>]
+ end,
+ "[foo || <<\"s\">> <= <<\"st\">>].",
+ [foo]),
+ ?line check(fun() -> <<_:32>> = <<17:32>> end,
+ "<<_:32>> = <<17:32>>.",
+ <<17:32>>),
+ ?line check(fun() -> [foo || <<_:32>> <= <<17:32,20:32>>] end,
+ "[foo || <<_:32>> <= <<17:32,20:32>>].",
+ [foo,foo]),
+
+ ?line check(fun() -> << <<X:32>> || X <- [1,2,3], X > 1 >> end,
+ "<< <<X:32>> || X <- [1,2,3], X > 1 >>.",
+ <<0,0,0,2,0,0,0,3>>),
+ ?line error_check("[X || <<X>> <= [a,b]].",{bad_generator,[a,b]}),
+ ok.
+
+otp_6787(doc) ->
+ ["OTP-6787. bitlevel binaries."];
+otp_6787(suite) ->
+ [];
+otp_6787(Config) when is_list(Config) ->
+ ?line check(
+ fun() -> <<16:(1024*1024)>> = <<16:(1024*1024)>> end,
+ "<<16:(1024*1024)>> = <<16:(1024*1024)>>.",
+ <<16:1048576>>),
+ ok.
+
+otp_6977(doc) ->
+ ["OTP-6977. ++ bug."];
+otp_6977(suite) ->
+ [];
+otp_6977(Config) when is_list(Config) ->
+ ?line check(
+ fun() -> (fun([$X] ++ _) -> ok end)("X") end,
+ "(fun([$X] ++ _) -> ok end)(\"X\").",
+ ok),
+ ok.
+
+otp_7550(doc) ->
+ ["OTP-7550. Support for UTF-8, UTF-16, UTF-32."];
+otp_7550(Config) when is_list(Config) ->
+
+ %% UTF-8.
+ ?line check(
+ fun() -> <<65>> = <<65/utf8>> end,
+ "<<65>> = <<65/utf8>>.",
+ <<65>>),
+ ?line check(
+ fun() -> <<350/utf8>> = <<197,158>> end,
+ "<<350/utf8>> = <<197,158>>.",
+ <<197,158>>),
+ ?line check(
+ fun() -> <<$b,$j,$\303,$\266,$r,$n>> = <<"bj\366rn"/utf8>> end,
+ "<<$b,$j,$\303,$\266,$r,$n>> = <<\"bj\366rn\"/utf8>>.",
+ <<$b,$j,$\303,$\266,$r,$n>>),
+
+ %% UTF-16.
+ ?line check(
+ fun() -> <<0,65>> = <<65/utf16>> end,
+ "<<0,65>> = <<65/utf16>>.",
+ <<0,65>>),
+ ?line check(
+ fun() -> <<16#D8,16#08,16#DF,16#45>> = <<16#12345/utf16>> end,
+ "<<16#D8,16#08,16#DF,16#45>> = <<16#12345/utf16>>.",
+ <<16#D8,16#08,16#DF,16#45>>),
+ ?line check(
+ fun() -> <<16#08,16#D8,16#45,16#DF>> = <<16#12345/little-utf16>> end,
+ "<<16#08,16#D8,16#45,16#DF>> = <<16#12345/little-utf16>>.",
+ <<16#08,16#D8,16#45,16#DF>>),
+
+ ?line check(
+ fun() -> <<350/utf16>> = <<1,94>> end,
+ "<<350/utf16>> = <<1,94>>.",
+ <<1,94>>),
+ ?line check(
+ fun() -> <<350/little-utf16>> = <<94,1>> end,
+ "<<350/little-utf16>> = <<94,1>>.",
+ <<94,1>>),
+ ?line check(
+ fun() -> <<16#12345/utf16>> = <<16#D8,16#08,16#DF,16#45>> end,
+ "<<16#12345/utf16>> = <<16#D8,16#08,16#DF,16#45>>.",
+ <<16#D8,16#08,16#DF,16#45>>),
+ ?line check(
+ fun() -> <<16#12345/little-utf16>> = <<16#08,16#D8,16#45,16#DF>> end,
+ "<<16#12345/little-utf16>> = <<16#08,16#D8,16#45,16#DF>>.",
+ <<16#08,16#D8,16#45,16#DF>>),
+
+ %% UTF-32.
+ ?line check(
+ fun() -> <<16#12345/utf32>> = <<16#0,16#01,16#23,16#45>> end,
+ "<<16#12345/utf32>> = <<16#0,16#01,16#23,16#45>>.",
+ <<16#0,16#01,16#23,16#45>>),
+ ?line check(
+ fun() -> <<16#0,16#01,16#23,16#45>> = <<16#12345/utf32>> end,
+ "<<16#0,16#01,16#23,16#45>> = <<16#12345/utf32>>.",
+ <<16#0,16#01,16#23,16#45>>),
+ ?line check(
+ fun() -> <<16#12345/little-utf32>> = <<16#45,16#23,16#01,16#00>> end,
+ "<<16#12345/little-utf32>> = <<16#45,16#23,16#01,16#00>>.",
+ <<16#45,16#23,16#01,16#00>>),
+ ?line check(
+ fun() -> <<16#12345/little-utf32>> end,
+ "<<16#12345/little-utf32>>.",
+ <<16#45,16#23,16#01,16#00>>),
+
+ %% Mixed.
+ ?line check(
+ fun() -> <<16#41,16#12345/utf32,16#0391:16,16#2E:8>> end,
+ "<<16#41,16#12345/utf32,16#0391:16,16#2E:8>>.",
+ <<16#41,16#00,16#01,16#23,16#45,16#03,16#91,16#2E>>),
+ ok.
+
+
+otp_8133(doc) ->
+ ["OTP-8133. Bit comprehension bug."];
+otp_8133(suite) ->
+ [];
+otp_8133(Config) when is_list(Config) ->
+ ?line check(
+ fun() ->
+ E = fun(N) ->
+ if
+ is_integer(N) -> <<N/integer>>;
+ true -> throw(foo)
+ end
+ end,
+ try << << (E(V))/binary >> || V <- [1,2,3,a] >>
+ catch foo -> ok
+ end
+ end,
+ "begin
+ E = fun(N) ->
+ if is_integer(N) -> <<N/integer>>;
+ true -> throw(foo)
+ end
+ end,
+ try << << (E(V))/binary >> || V <- [1,2,3,a] >>
+ catch foo -> ok
+ end
+ end.",
+ ok),
+ ?line check(
+ fun() ->
+ E = fun(N) ->
+ if
+ is_integer(N) -> <<N/integer>>;
+ true -> erlang:error(foo)
+ end
+ end,
+ try << << (E(V))/binary >> || V <- [1,2,3,a] >>
+ catch error:foo -> ok
+ end
+ end,
+ "begin
+ E = fun(N) ->
+ if is_integer(N) -> <<N/integer>>;
+ true -> erlang:error(foo)
+ end
+ end,
+ try << << (E(V))/binary >> || V <- [1,2,3,a] >>
+ catch error:foo -> ok
+ end
+ end.",
+ ok),
+ ok.
+
+funs(doc) ->
+ ["Simple cases, just to cover some code."];
+funs(suite) ->
+ [];
+funs(Config) when is_list(Config) ->
+ do_funs(none, none),
+ do_funs(lfh(), none),
+ do_funs(lfh(), efh()),
+
+ ?line error_check("nix:foo().", {access_not_allowed,nix}, lfh(), efh()),
+ ?line error_check("bar().", undef, none, none),
+
+ ?line check(fun() -> F1 = fun(F,N) -> ?MODULE:count_down(F, N) end,
+ F1(F1, 1000) end,
+ "begin F1 = fun(F,N) -> count_down(F, N) end,"
+ "F1(F1,1000) end.",
+ 0, ['F1'], lfh(), none),
+
+ ?line check(fun() -> F1 = fun(F,N) -> ?MODULE:count_down(F, N) end,
+ F1(F1, 1000) end,
+ "begin F1 = fun(F,N) -> count_down(F, N) end,"
+ "F1(F1,1000) end.",
+ 0, ['F1'], lfh_value(), none),
+
+ ?line check(fun() -> F1 = fun(F,N) -> ?MODULE:count_down(F, N) end,
+ F1(F1, 1000) end,
+ "begin F1 = fun(F,N) -> count_down(F, N) end,"
+ "F1(F1,1000) end.",
+ 0, ['F1'], lfh_value_extra(), none),
+
+ ?line check(fun() -> F1 = fun(F,N) -> ?MODULE:count_down(F, N) end,
+ F1(F1, 1000) end,
+ "begin F1 = fun(F,N) -> count_down(F, N) end,"
+ "F1(F1,1000) end.",
+ 0, ['F1'], {?MODULE,local_func_value}, none),
+ %% This is not documented, and only for backward compatibility (good!).
+ B0 = erl_eval:new_bindings(),
+ ?line check(fun() -> is_function(?MODULE:count_down_fun()) end,
+ "begin is_function(count_down_fun()) end.",
+ true, [], {?MODULE,local_func,[B0]},none),
+
+ EF = fun({timer,sleep}, As) when length(As) == 1 -> exit({got_it,sleep});
+ ({M,F}, As) -> apply(M, F, As)
+ end,
+ EFH = {value, EF},
+ ?line error_check("apply(timer, sleep, [1]).", got_it, none, EFH),
+ ?line error_check("begin F = fun(T) -> timer:sleep(T) end,F(1) end.",
+ got_it, none, EFH),
+ ?line error_check("fun c/1.", undef),
+ ?line error_check("fun a:b/0().", undef),
+
+ MaxArgs = 20,
+ ?line [true] =
+ lists:usort([run_many_args(SAs) || SAs <- many_args(MaxArgs)]),
+ ?line {'EXIT',{{argument_limit,_},_}} =
+ (catch run_many_args(many_args1(MaxArgs+1))),
+ ok.
+
+run_many_args({S, As}) ->
+ apply(eval_string(S), As) =:= As.
+
+many_args(N) ->
+ [many_args1(I) || I <- lists:seq(1, N)].
+
+many_args1(N) ->
+ F = fun(L, P) ->
+ tl(lists:flatten([","++P++integer_to_list(E) || E <- L]))
+ end,
+ L = lists:seq(1, N),
+ T = F(L, "V"),
+ S = lists:flatten(io_lib:format("fun(~s) -> [~s] end.", [T, T])),
+ {S, L}.
+
+do_funs(LFH, EFH) ->
+ %% LFH is not really used by these examples...
+
+ %% These tests do not prove that tail recursive functions really
+ %% work (that the process does not grow); one should also run them
+ %% manually with 1000 replaced by 1000000.
+
+ M = atom_to_list(?MODULE),
+ ?line check(fun() -> F1 = fun(F,N) -> ?MODULE:count_down(F, N) end,
+ F1(F1, 1000) end,
+ concat(["begin F1 = fun(F,N) -> ", M,
+ ":count_down(F, N) end, F1(F1,1000) end."]),
+ 0, ['F1'], LFH, EFH),
+ ?line check(fun() -> F1 = fun(F,N) -> apply(?MODULE,count_down,[F,N])
+ end, F1(F1, 1000) end,
+ concat(["begin F1 = fun(F,N) -> apply(", M,
+ ",count_down,[F, N]) end, F1(F1,1000) end."]),
+ 0, ['F1'], LFH, EFH),
+ ?line check(fun() -> F1 = fun(F,N) -> {?MODULE,count_down}(F,N)
+ end, F1(F1, 1000) end,
+ concat(["begin F1 = fun(F,N) -> {", M,
+ ",count_down}(F, N) end, F1(F1,1000) end."]),
+ 0, ['F1'], LFH, EFH),
+ ?line check(fun() -> F = fun(F,N) when N > 0 -> apply(F,[F,N-1]);
+ (_F,0) -> ok end,
+ F(F, 1000)
+ end,
+ "begin F = fun(F,N) when N > 0 -> apply(F,[F,N-1]);"
+ "(_F,0) -> ok end,"
+ "F(F, 1000) end.",
+ ok, ['F'], LFH, EFH),
+ ?line check(fun() -> F = fun(F,N) when N > 0 ->
+ apply(erlang,apply,[F,[F,N-1]]);
+ (_F,0) -> ok end,
+ F(F, 1000)
+ end,
+ "begin F = fun(F,N) when N > 0 ->"
+ "apply(erlang,apply,[F,[F,N-1]]);"
+ "(_F,0) -> ok end,"
+ "F(F, 1000) end.",
+ ok, ['F'], LFH, EFH),
+ ?line check(fun() -> F = count_down_fun(),
+ SF = fun(SF, F1, N) -> F(SF, F1, N) end,
+ SF(SF, F, 1000) end,
+ concat(["begin F = ", M, ":count_down_fun(),"
+ "SF = fun(SF, F1, N) -> F(SF, F1, N) end,"
+ "SF(SF, F, 1000) end."]),
+ ok, ['F','SF'], LFH, EFH),
+
+
+ ?line check(fun() -> F = fun(X) -> A = 1+X, {X,A} end,
+ true = {2,3} == F(2) end,
+ "begin F = fun(X) -> A = 1+X, {X,A} end,
+ true = {2,3} == F(2) end.", true, ['F'], LFH, EFH),
+ ?line check(fun() -> F = fun(X) -> {erlang,'+'}(X,2) end,
+ true = 3 == F(1) end,
+ "begin F = fun(X) -> {erlang,'+'}(X,2) end,"
+ " true = 3 == F(1) end.", true, ['F'],
+ LFH, EFH),
+ ?line check(fun() -> F = fun(X) -> byte_size(X) end,
+ ?MODULE:do_apply(F,<<"hej">>) end,
+ concat(["begin F = fun(X) -> size(X) end,",
+ M,":do_apply(F,<<\"hej\">>) end."]),
+ 3, ['F'], LFH, EFH),
+
+ ?line check(fun() -> F1 = fun(X, Z) -> {X,Z} end,
+ Z = 5,
+ F2 = fun(X, Y) -> F1(Z,{X,Y}) end,
+ F3 = fun(X, Y) -> {a,F1(Z,{X,Y})} end,
+ {5,{x,y}} = F2(x,y),
+ {a,{5,{y,x}}} = F3(y,x),
+ {5,{5,y}} = F2(Z,y),
+ true = {5,{x,5}} == F2(x,Z) end,
+ "begin F1 = fun(X, Z) -> {X,Z} end,
+ Z = 5,
+ F2 = fun(X, Y) -> F1(Z,{X,Y}) end,
+ F3 = fun(X, Y) -> {a,F1(Z,{X,Y})} end,
+ {5,{x,y}} = F2(x,y),
+ {a,{5,{y,x}}} = F3(y,x),
+ {5,{5,y}} = F2(Z,y),
+ true = {5,{x,5}} == F2(x,Z) end.",
+ true, ['F1','Z','F2','F3'], LFH, EFH),
+ ?line check(fun() -> F = fun(X) -> byte_size(X) end,
+ F2 = fun(Y) -> F(Y) end,
+ ?MODULE:do_apply(F2,<<"hej">>) end,
+ concat(["begin F = fun(X) -> size(X) end,",
+ "F2 = fun(Y) -> F(Y) end,",
+ M,":do_apply(F2,<<\"hej\">>) end."]),
+ 3, ['F','F2'], LFH, EFH),
+ ?line check(fun() -> Z = 5, F = fun(X) -> {Z,X} end,
+ F2 = fun(Z) -> F(Z) end, F2(3) end,
+ "begin Z = 5, F = fun(X) -> {Z,X} end,
+ F2 = fun(Z) -> F(Z) end, F2(3) end.",
+ {5,3},['F','F2','Z'], LFH, EFH),
+ ?line check(fun() -> F = fun(Z) -> Z end,
+ F2 = fun(X) -> F(X), Z = {X,X}, Z end,
+ {1,1} = F2(1), Z = 7, Z end,
+ "begin F = fun(Z) -> Z end,
+ F2 = fun(X) -> F(X), Z = {X,X}, Z end,
+ {1,1} = F2(1), Z = 7, Z end.", 7, ['F','F2','Z'],
+ LFH, EFH),
+ ?line check(fun() -> F = fun(F, N) -> [?MODULE:count_down(F,N) || X <-[1]]
+ end, F(F,2) end,
+ concat(["begin F = fun(F, N) -> [", M,
+ ":count_down(F,N) || X <-[1]] end, F(F,2) end."]),
+ [[[0]]], ['F'], LFH, EFH),
+ ok.
+
+count_down(F, N) when N > 0 ->
+ F(F, N-1);
+count_down(_F, N) ->
+ N.
+
+count_down_fun() ->
+ fun(SF,F,N) when N > 0 -> SF(SF,F,N-1);
+ (_SF,_F,_N) -> ok
+ end.
+
+do_apply(F, V) ->
+ F(V).
+
+lfh() ->
+ {eval, fun(F, As, Bs) -> local_func(F, As, Bs) end}.
+
+local_func(F, As0, Bs0) when is_atom(F) ->
+ {As,Bs} = erl_eval:expr_list(As0, Bs0, {eval,lfh()}),
+ case erlang:function_exported(?MODULE, F, length(As)) of
+ true ->
+ {value,apply(?MODULE, F, As),Bs};
+ false ->
+ {value,apply(shell_default, F, As),Bs}
+ end.
+
+lfh_value_extra() ->
+ %% Not documented.
+ {value, fun(F, As) -> local_func_value(F, As) end, []}.
+
+lfh_value() ->
+ {value, fun(F, As) -> local_func_value(F, As) end}.
+
+local_func_value(F, As) when is_atom(F) ->
+ case erlang:function_exported(?MODULE, F, length(As)) of
+ true ->
+ apply(?MODULE, F, As);
+ false ->
+ apply(shell_default, F, As)
+ end.
+
+efh() ->
+ {value, fun(F, As) -> external_func(F, As) end}.
+
+external_func({M,_}, _As) when M == nix ->
+ exit({{access_not_allowed,M},[mfa]});
+external_func(F, As) when is_function(F) ->
+ apply(F, As);
+external_func({M,F}, As) ->
+ apply(M, F, As).
+
+
+
+try_catch(doc) ->
+ ["Test try-of-catch-after-end statement"];
+try_catch(suite) ->
+ [];
+try_catch(Config) when is_list(Config) ->
+ %% Match in of with catch
+ ?line check(fun() -> try 1 of 1 -> 2 catch _:_ -> 3 end end,
+ "try 1 of 1 -> 2 catch _:_ -> 3 end.", 2),
+ ?line check(fun() -> try 1 of 1 -> 2; 3 -> 4 catch _:_ -> 5 end end,
+ "try 1 of 1 -> 2; 3 -> 4 catch _:_ -> 5 end.", 2),
+ ?line check(fun() -> try 3 of 1 -> 2; 3 -> 4 catch _:_ -> 5 end end,
+ "try 3 of 1 -> 2; 3 -> 4 catch _:_ -> 5 end.", 4),
+ %% Just after
+ ?line check(fun () -> X = try 1 after put(try_catch, 2) end,
+ {X,get(try_catch)} end,
+ "begin X = try 1 after put(try_catch, 2) end, "
+ "{X,get(try_catch)} end.", {1,2}),
+ %% Match in of with after
+ ?line check(fun() -> X = try 1 of 1 -> 2 after put(try_catch, 3) end,
+ {X,get(try_catch)} end,
+ "begin X = try 1 of 1 -> 2 after put(try_catch, 3) end, "
+ "{X,get(try_catch)} end.", {2,3}),
+ ?line check(fun() -> X = try 1 of 1 -> 2; 3 -> 4
+ after put(try_catch, 5) end,
+ {X,get(try_catch)} end,
+ "begin X = try 1 of 1 -> 2; 3 -> 4 "
+ " after put(try_catch, 5) end, "
+ " {X,get(try_catch)} end.", {2,5}),
+ ?line check(fun() -> X = try 3 of 1 -> 2; 3 -> 4
+ after put(try_catch, 5) end,
+ {X,get(try_catch)} end,
+ "begin X = try 3 of 1 -> 2; 3 -> 4 "
+ " after put(try_catch, 5) end, "
+ " {X,get(try_catch)} end.", {4,5}),
+ %% Nomatch in of
+ ?line error_check("try 1 of 2 -> 3 catch _:_ -> 4 end.",
+ {try_clause,1}),
+ %% Nomatch in of with after
+ ?line check(fun () -> {'EXIT',{{try_clause,1},_}} =
+ begin catch try 1 of 2 -> 3
+ after put(try_catch, 4) end end,
+ get(try_catch) end,
+ "begin {'EXIT',{{try_clause,1},_}} = "
+ " begin catch try 1 of 2 -> 3 "
+ " after put(try_catch, 4) end end, "
+ " get(try_catch) end. ", 4),
+ %% Exception in try
+ ?line check(fun () -> try 1=2 catch error:{badmatch,2} -> 3 end end,
+ "try 1=2 catch error:{badmatch,2} -> 3 end.", 3),
+ ?line check(fun () -> try 1=2 of 3 -> 4
+ catch error:{badmatch,2} -> 5 end end,
+ "try 1=2 of 3 -> 4 "
+ "catch error:{badmatch,2} -> 5 end.", 5),
+ %% Exception in try with after
+ ?line check(fun () -> X = try 1=2
+ catch error:{badmatch,2} -> 3
+ after put(try_catch, 4) end,
+ {X,get(try_catch)} end,
+ "begin X = try 1=2 "
+ " catch error:{badmatch,2} -> 3 "
+ " after put(try_catch, 4) end, "
+ " {X,get(try_catch)} end. ", {3,4}),
+ ?line check(fun () -> X = try 1=2 of 3 -> 4
+ catch error:{badmatch,2} -> 5
+ after put(try_catch, 6) end,
+ {X,get(try_catch)} end,
+ "begin X = try 1=2 of 3 -> 4"
+ " catch error:{badmatch,2} -> 5 "
+ " after put(try_catch, 6) end, "
+ " {X,get(try_catch)} end. ", {5,6}),
+ %% Uncaught exception
+ ?line error_check("try 1=2 catch error:undefined -> 3 end. ",
+ {badmatch,2}),
+ ?line error_check("try 1=2 of 3 -> 4 catch error:undefined -> 5 end. ",
+ {badmatch,2}),
+ %% Uncaught exception with after
+ ?line check(fun () -> {'EXIT',{{badmatch,2},_}} =
+ begin catch try 1=2
+ after put(try_catch, 3) end end,
+ get(try_catch) end,
+ "begin {'EXIT',{{badmatch,2},_}} = "
+ " begin catch try 1=2 "
+ " after put(try_catch, 3) end end, "
+ " get(try_catch) end. ", 3),
+ ?line check(fun () -> {'EXIT',{{badmatch,2},_}} =
+ begin catch try 1=2 of 3 -> 4
+ after put(try_catch, 5) end end,
+ get(try_catch) end,
+ "begin {'EXIT',{{badmatch,2},_}} = "
+ " begin catch try 1=2 of 3 -> 4"
+ " after put(try_catch, 5) end end, "
+ " get(try_catch) end. ", 5),
+ ?line check(fun () -> {'EXIT',{{badmatch,2},_}} =
+ begin catch try 1=2 catch error:undefined -> 3
+ after put(try_catch, 4) end end,
+ get(try_catch) end,
+ "begin {'EXIT',{{badmatch,2},_}} = "
+ " begin catch try 1=2 catch error:undefined -> 3 "
+ " after put(try_catch, 4) end end, "
+ " get(try_catch) end. ", 4),
+ ?line check(fun () -> {'EXIT',{{badmatch,2},_}} =
+ begin catch try 1=2 of 3 -> 4
+ catch error:undefined -> 5
+ after put(try_catch, 6) end end,
+ get(try_catch) end,
+ "begin {'EXIT',{{badmatch,2},_}} = "
+ " begin catch try 1=2 of 3 -> 4 "
+ " catch error:undefined -> 5 "
+ " after put(try_catch, 6) end end, "
+ " get(try_catch) end. ", 6),
+ ok.
+
+
+eval_expr_5(doc) ->
+ ["(OTP-7933)"];
+eval_expr_5(suite) ->
+ [];
+eval_expr_5(Config) when is_list(Config) ->
+ ?line {ok,Tokens ,_} =
+ erl_scan:string("if a+4 == 4 -> yes; true -> no end. "),
+ ?line {ok, [Expr]} = erl_parse:parse_exprs(Tokens),
+ ?line {value, no, []} = erl_eval:expr(Expr, [], none, none, none),
+ ?line no = erl_eval:expr(Expr, [], none, none, value),
+ try
+ erl_eval:expr(Expr, [], none, none, 4711),
+ ?line function_clause = should_never_reach_here
+ catch
+ error:function_clause ->
+ ok
+ end.
+
+%% Check the string in different contexts: as is; in fun; from compiled code.
+check(F, String, Result) ->
+ check1(F, String, Result),
+ FunString = concat(["fun() -> ", no_final_dot(String), " end(). "]),
+ check1(F, FunString, Result),
+ CompileString = concat(["hd(lists:map(fun(_) -> ", no_final_dot(String),
+ " end, [foo])). "]),
+ check1(F, CompileString, Result).
+
+check1(F, String, Result) ->
+ Result = F(),
+ case catch parse_and_run(String) of
+ {value, Result, _} ->
+ ok;
+ Other ->
+ test_server:fail({eval, Other, Result})
+ end.
+
+check(F, String, Result, BoundVars, LFH, EFH) ->
+ Result = F(),
+ case catch parse_and_run(String, LFH, EFH) of
+ {value, Result, Bs} ->
+ %% We just assume that Bs is an orddict...
+ Keys = orddict:fetch_keys(Bs),
+ case sort(BoundVars) == Keys of
+ true ->
+ ok;
+ false ->
+ test_server:fail({check, BoundVars, Keys})
+ end,
+ ok;
+ Other ->
+ test_server:fail({check, Other, Result})
+ end.
+
+error_check(String, Result) ->
+ case catch parse_and_run(String) of
+ {'EXIT', {Result,_}} ->
+ ok;
+ Other ->
+ test_server:fail({eval, Other, Result})
+ end.
+
+error_check(String, Result, LFH, EFH) ->
+ case catch parse_and_run(String, LFH, EFH) of
+ {'EXIT', {Result,_}} ->
+ ok;
+ Other ->
+ test_server:fail({eval, Other, Result})
+ end.
+
+eval_string(String) ->
+ {value, Result, _} = parse_and_run(String),
+ Result.
+
+parse_and_run(String) ->
+ {ok,Tokens,_} = erl_scan:string(String),
+ {ok, [Expr]} = erl_parse:parse_exprs(Tokens),
+ erl_eval:expr(Expr, []).
+
+parse_and_run(String, LFH, EFH) ->
+ {ok,Tokens,_} = erl_scan:string(String),
+ {ok, [Expr]} = erl_parse:parse_exprs(Tokens),
+ erl_eval:expr(Expr, [], LFH, EFH).
+
+no_final_dot(S) ->
+ case lists:reverse(S) of
+ " ." ++ R -> lists:reverse(R);
+ "." ++ R -> lists:reverse(R);
+ _ -> S
+ end.
diff --git a/lib/debugger/test/exception_SUITE.erl b/lib/debugger/test/exception_SUITE.erl
new file mode 100644
index 0000000000..a74a93fd22
--- /dev/null
+++ b/lib/debugger/test/exception_SUITE.erl
@@ -0,0 +1,256 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 1999-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(exception_SUITE).
+
+-export([all/1,init_per_testcase/2,fin_per_testcase/2,init_all/1,finish_all/1,
+ badmatch/1,pending_errors/1,nil_arith/1]).
+
+-export([bad_guy/2]).
+
+-include("test_server.hrl").
+
+all(suite) ->
+ [{conf,init_all,cases(),finish_all}].
+
+cases() ->
+ [badmatch, pending_errors, nil_arith].
+
+-define(try_match(E),
+ catch ?MODULE:bar(),
+ {'EXIT', {{badmatch, nomatch}, _}} = (catch E = nomatch)).
+
+init_per_testcase(_Case, Config) ->
+ test_lib:interpret(?MODULE),
+ Dog = test_server:timetrap(?t:minutes(1)),
+ [{watchdog,Dog}|Config].
+
+fin_per_testcase(_Case, Config) ->
+ Dog = ?config(watchdog, Config),
+ ?t:timetrap_cancel(Dog),
+ ok.
+
+init_all(Config) when is_list(Config) ->
+ ?line test_lib:interpret(?MODULE),
+ ?line true = lists:member(?MODULE, int:interpreted()),
+ ok.
+
+finish_all(Config) when is_list(Config) ->
+ ok.
+
+badmatch(doc) -> "Test that deliberately bad matches are reported correctly.";
+badmatch(suite) -> [];
+badmatch(Config) when list(Config) ->
+ ?line ?try_match(a),
+ ?line ?try_match(42),
+ ?line ?try_match({a, b, c}),
+ ?line ?try_match([]),
+ ?line ?try_match(1.0),
+ ok.
+
+pending_errors(doc) ->
+ ["Test various exceptions, in the presence of a previous error suppressed ",
+ "in a guard."];
+pending_errors(suite) -> [];
+pending_errors(Config) when list(Config) ->
+ ?line pending(e_badmatch, {badmatch, b}),
+ ?line pending(x, function_clause),
+ ?line pending(e_case, {case_clause, xxx}),
+ ?line pending(e_if, if_clause),
+ ?line pending(e_badarith, badarith),
+ ?line pending(e_undef, undef),
+ ?line pending(e_timeoutval, timeout_value),
+ ?line pending(e_badarg, badarg),
+ ?line pending(e_badarg_spawn, badarg),
+ ok.
+
+bad_guy(pe_badarith, Other) when Other+1 == 0 -> % badarith (suppressed)
+ ok;
+bad_guy(pe_badarg, Other) when length(Other) > 0 -> % badarg (suppressed)
+ ok;
+bad_guy(_, e_case) ->
+ case xxx of
+ ok -> ok
+ end; % case_clause
+bad_guy(_, e_if) ->
+ if
+ a == b -> ok
+ end; % if_clause
+bad_guy(_, e_badarith) ->
+ 1+b; % badarith
+bad_guy(_, e_undef) ->
+ non_existing_module:foo(); % undef
+bad_guy(_, e_timeoutval) ->
+ receive
+ after arne -> % timeout_value
+ ok
+ end;
+bad_guy(_, e_badarg) ->
+ node(xxx); % badarg
+bad_guy(_, e_badarg_spawn) ->
+ spawn({}, {}, {}); % badarg
+bad_guy(_, e_badmatch) ->
+ a = b. % badmatch
+
+pending(Arg, Expected) ->
+ pending(pe_badarith, Arg, Expected),
+ pending(pe_badarg, Arg, Expected).
+
+pending(First, Second, Expected) ->
+ pending_catched(First, Second, Expected),
+ pending_exit_message([First, Second], Expected).
+
+pending_catched(First, Second, Expected) ->
+ ok = io:format("Catching bad_guy(~p, ~p)", [First, Second]),
+ case catch bad_guy(First, Second) of
+ {'EXIT', Reason} ->
+ pending(Reason, bad_guy, [First, Second], Expected);
+ Other ->
+ test_server:fail({not_exit, Other})
+ end.
+
+pending_exit_message(Args, Expected) ->
+ ok = io:format("Trapping EXITs from spawn_link(~p, ~p, ~p)",
+ [?MODULE, bad_guy, Args]),
+ process_flag(trap_exit, true),
+ Pid = spawn_link(?MODULE, bad_guy, Args),
+ receive
+ {'EXIT', Pid, Reason} ->
+ pending(Reason, bad_guy, Args, Expected);
+ Other ->
+ test_server:fail({unexpected_message, Other})
+ after 10000 ->
+ test_server:fail(timeout)
+ end,
+ process_flag(trap_exit, false).
+
+pending({badarg,[{erlang,Bif,BifArgs},{?MODULE,Func,Arity}|_]}, Func, Args, _Code)
+ when atom(Bif), list(BifArgs), length(Args) == Arity -> %Threaded code.
+ ok;
+pending({badarg,[{erlang,Bif,BifArgs},{?MODULE,Func,Args}|_]}, Func, Args, _Code)
+ when atom(Bif), list(BifArgs) -> %From interpreted code.
+ ok;
+pending({undef,[{non_existing_module,foo,[]}|_]}, _, _, _) ->
+ ok;
+pending({function_clause,[{?MODULE,Func,Args}|_]}, Func, Args, _Code) ->
+ ok;
+pending({Code,[{?MODULE,Func,Arity}|_]}, Func, Args, Code) when length(Args) == Arity -> %Threaded code
+ ok;
+pending({Code,[{?MODULE,Func,Args}|_]}, Func, Args, Code) -> %From interpreted code.
+ ok;
+pending(Reason, Func, Args, Code) ->
+ test_server:fail({bad_exit_reason,Reason,{Func,Args,Code}}).
+
+nil_arith(doc) ->
+ "Test that doing arithmetics on [] gives a badarith EXIT and not a crash.";
+nil_arith(suite) ->
+ [];
+nil_arith(Config) when list(Config) ->
+ ?line ba_plus_minus_times([], []),
+
+ ?line ba_plus_minus_times([], 0),
+ ?line ba_plus_minus_times([], 42),
+ ?line ba_plus_minus_times([], 38724978123478923784),
+ ?line ba_plus_minus_times([], 38.72),
+
+ ?line ba_plus_minus_times(0, []),
+ ?line ba_plus_minus_times(334, []),
+ ?line ba_plus_minus_times(387249797813478923784, []),
+ ?line ba_plus_minus_times(344.22, []),
+
+ ?line ba_div_rem([], []),
+
+ ?line ba_div_rem([], 0),
+ ?line ba_div_rem([], 1),
+ ?line ba_div_rem([], 42),
+ ?line ba_div_rem([], 38724978123478923784),
+ ?line ba_div_rem(344.22, []),
+
+ ?line ba_div_rem(0, []),
+ ?line ba_div_rem(1, []),
+ ?line ba_div_rem(334, []),
+ ?line ba_div_rem(387249797813478923784, []),
+ ?line ba_div_rem(344.22, []),
+
+ ?line ba_div_rem(344.22, 0.0),
+ ?line ba_div_rem(1, 0.0),
+ ?line ba_div_rem(392873498733971, 0.0),
+
+ ?line ba_bop([], []),
+ ?line ba_bop(0, []),
+ ?line ba_bop(42, []),
+ ?line ba_bop(-42342742987343, []),
+ ?line ba_bop(238.342, []),
+ ?line ba_bop([], 0),
+ ?line ba_bop([], -243),
+ ?line ba_bop([], 243),
+ ?line ba_bop([], 2438724982478933),
+ ?line ba_bop([], 3987.37),
+
+ ?line ba_bnot([]),
+ ?line ba_bnot(23.33),
+
+ ?line ba_shift([], []),
+ ?line ba_shift([], 0),
+ ?line ba_shift([], 4),
+ ?line ba_shift([], -4),
+ ?line ba_shift([], 2343333333333),
+ ?line ba_shift([], -333333333),
+ ?line ba_shift([], 234.00),
+ ?line ba_shift(23, []),
+ ?line ba_shift(0, []),
+ ?line ba_shift(-3433443433433323, []),
+ ?line ba_shift(433443433433323, []),
+ ?line ba_shift(343.93, []),
+ ok.
+
+ba_plus_minus_times(A, B) ->
+ io:format("~p + ~p", [A, B]),
+ {'EXIT', {badarith, _}} = (catch A + B),
+ io:format("~p - ~p", [A, B]),
+ {'EXIT', {badarith, _}} = (catch A - B),
+ io:format("~p * ~p", [A, B]),
+ {'EXIT', {badarith, _}} = (catch A * B).
+
+ba_div_rem(A, B) ->
+ io:format("~p / ~p", [A, B]),
+ {'EXIT', {badarith, _}} = (catch A / B),
+ io:format("~p div ~p", [A, B]),
+ {'EXIT', {badarith, _}} = (catch A div B),
+ io:format("~p rem ~p", [A, B]),
+ {'EXIT', {badarith, _}} = (catch A rem B).
+
+ba_bop(A, B) ->
+ io:format("~p band ~p", [A, B]),
+ {'EXIT', {badarith, _}} = (catch A band B),
+ io:format("~p bor ~p", [A, B]),
+ {'EXIT', {badarith, _}} = (catch A bor B),
+ io:format("~p bxor ~p", [A, B]),
+ {'EXIT', {badarith, _}} = (catch A bxor B).
+
+ba_shift(A, B) ->
+ io:format("~p bsl ~p", [A, B]),
+ {'EXIT', {badarith, _}} = (catch A bsl B),
+ io:format("~p bsr ~p", [A, B]),
+ {'EXIT', {badarith, _}} = (catch A bsr B).
+
+ba_bnot(A) ->
+ io:format("bnot ~p", [A]),
+ {'EXIT', {badarith, _}} = (catch bnot A).
diff --git a/lib/debugger/test/fun_SUITE.erl b/lib/debugger/test/fun_SUITE.erl
new file mode 100644
index 0000000000..721048b6b6
--- /dev/null
+++ b/lib/debugger/test/fun_SUITE.erl
@@ -0,0 +1,233 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 1999-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(fun_SUITE).
+
+-export([all/1,
+ init_per_testcase/2,end_per_testcase/2,
+ init_all/1,finish_all/1,
+ good_call/1,bad_apply/1,bad_fun_call/1,badarity/1,
+ ext_badarity/1,otp_6061/1]).
+-export([nothing/0]).
+
+-include("test_server.hrl").
+
+all(suite) ->
+ [{conf,init_all,cases(),finish_all}].
+
+cases() ->
+ [good_call,bad_apply,bad_fun_call,badarity,ext_badarity,otp_6061].
+
+init_per_testcase(_Case, Config) ->
+ test_lib:interpret(?MODULE),
+ Dog = test_server:timetrap(?t:minutes(1)),
+ [{watchdog,Dog}|Config].
+
+end_per_testcase(_Case, Config) ->
+ Dog = ?config(watchdog, Config),
+ ?t:timetrap_cancel(Dog),
+ ok.
+
+init_all(Config) when is_list(Config) ->
+ ?line test_lib:interpret(?MODULE),
+ ?line true = lists:member(?MODULE, int:interpreted()),
+ ok.
+
+finish_all(Config) when is_list(Config) ->
+ ok.
+
+good_call(Config) when is_list(Config) ->
+ ?line F = fun() -> ok end,
+ ?line ok = F(),
+ ?line FF = fun ?MODULE:nothing/0,
+ ?line ok = FF(),
+ ok.
+
+bad_apply(doc) ->
+ "Test that the correct EXIT code is returned for all types of bad funs.";
+bad_apply(suite) -> [];
+bad_apply(Config) when is_list(Config) ->
+ ?line bad_apply_fc(42, [0]),
+ ?line bad_apply_fc(xx, [1]),
+ ?line bad_apply_fc({}, [2]),
+ ?line bad_apply_fc({1}, [3]),
+ ?line bad_apply_fc({1,2,3}, [4]),
+ ?line bad_apply_fc({1,2,3}, [5]),
+ ?line bad_apply_fc({1,2,3,4}, [6]),
+ ?line bad_apply_fc({1,2,3,4,5,6}, [7]),
+ ?line bad_apply_fc({1,2,3,4,5}, [8]),
+ ?line bad_apply_badarg({1,2}, [9]),
+ ok.
+
+bad_apply_fc(Fun, Args) ->
+ Res = (catch apply(Fun, Args)),
+ erlang:garbage_collect(),
+ erlang:yield(),
+ case Res of
+ {'EXIT',{{badfun,Fun},_Where}} ->
+ ok = io:format("apply(~p, ~p) -> ~p\n", [Fun,Args,Res]);
+ Other ->
+ ok = io:format("apply(~p, ~p) -> ~p\n", [Fun,Args,Res]),
+ ?t:fail({bad_result,Other})
+ end.
+
+bad_apply_badarg(Fun, Args) ->
+ Res = (catch apply(Fun, Args)),
+ erlang:garbage_collect(),
+ erlang:yield(),
+ case Res of
+ {'EXIT',{{badfun,Fun},_Where}} ->
+ ok = io:format("apply(~p, ~p) -> ~p\n", [Fun,Args,Res]);
+ Other ->
+ ok = io:format("apply(~p, ~p) -> ~p\n", [Fun,Args,Res]),
+ ?t:fail({bad_result, Other})
+ end.
+
+bad_fun_call(doc) ->
+ "Try directly calling bad funs.";
+bad_fun_call(suite) -> [];
+bad_fun_call(Config) when is_list(Config) ->
+ ?line bad_call_fc(42),
+ ?line bad_call_fc(xx),
+ ?line bad_call_fc({}),
+ ?line bad_call_fc({1}),
+ ?line bad_call_fc({1,2,3}),
+ ?line bad_call_fc({1,2,3}),
+ ?line bad_call_fc({1,2,3,4}),
+ ?line bad_call_fc({1,2,3,4,5,6}),
+ ?line bad_call_fc({1,2,3,4,5}),
+ ?line bad_call_fc({1,2}),
+ ok.
+
+bad_call_fc(Fun) ->
+ Args = [some,stupid,args],
+ Res = (catch Fun(Args)),
+ case Res of
+ {'EXIT',{{badfun,Fun},_Where}} ->
+ ok = io:format("~p(~p) -> ~p\n", [Fun,Args,Res]);
+ Other ->
+ ok = io:format("~p(~p) -> ~p\n", [Fun,Args,Res]),
+ ?t:fail({bad_result,Other})
+ end.
+
+%% Call and apply valid external funs with wrong number of arguments.
+
+badarity(Config) when is_list(Config) ->
+ ?line Fun = fun() -> ok end,
+ ?line Stupid = {stupid,arguments},
+ ?line Args = [some,{stupid,arguments},here],
+
+ %% Simple call.
+
+ ?line Res = (catch Fun(some, Stupid, here)),
+ erlang:garbage_collect(),
+ erlang:yield(),
+ case Res of
+ {'EXIT',{{badarity,{Fun,Args}},[_|_]}} ->
+ ?line ok = io:format("~p(~p) -> ~p\n", [Fun,Args,Res]);
+ _ ->
+ ?line ok = io:format("~p(~p) -> ~p\n", [Fun,Args,Res]),
+ ?line ?t:fail({bad_result,Res})
+ end,
+
+ %% Apply.
+
+ ?line Res2 = (catch apply(Fun, Args)),
+ erlang:garbage_collect(),
+ erlang:yield(),
+ case Res2 of
+ {'EXIT',{{badarity,{Fun,Args}},[_|_]}} ->
+ ?line ok = io:format("apply(~p, ~p) -> ~p\n", [Fun,Args,Res2]);
+ _ ->
+ ?line ok = io:format("apply(~p, ~p) -> ~p\n", [Fun,Args,Res2]),
+ ?line ?t:fail({bad_result,Res2})
+ end,
+ ok.
+
+%% Call and apply valid external funs with wrong number of arguments.
+
+ext_badarity(Config) when is_list(Config) ->
+ ?line Fun = fun ?MODULE:nothing/0,
+ ?line Stupid = {stupid,arguments},
+ ?line Args = [some,{stupid,arguments},here],
+
+ %% Simple call.
+
+ ?line Res = (catch Fun(some, Stupid, here)),
+ erlang:garbage_collect(),
+ erlang:yield(),
+ case Res of
+ {'EXIT',{{badarity,{Fun,Args}},_}} ->
+ ?line ok = io:format("~p(~p) -> ~p\n", [Fun,Args,Res]);
+ _ ->
+ ?line ok = io:format("~p(~p) -> ~p\n", [Fun,Args,Res]),
+ ?line ?t:fail({bad_result,Res})
+ end,
+
+ %% Apply.
+
+ ?line Res2 = (catch apply(Fun, Args)),
+ erlang:garbage_collect(),
+ erlang:yield(),
+ case Res2 of
+ {'EXIT',{{badarity,{Fun,Args}},_}} ->
+ ?line ok = io:format("apply(~p, ~p) -> ~p\n", [Fun,Args,Res2]);
+ _ ->
+ ?line ok = io:format("apply(~p, ~p) -> ~p\n", [Fun,Args,Res2]),
+ ?line ?t:fail({bad_result,Res2})
+ end,
+ ok.
+
+nothing() ->
+ ok.
+
+otp_6061(suite) ->
+ [];
+otp_6061(doc) ->
+ ["Test handling of fun expression referring to uninterpreted code"];
+otp_6061(Config) when is_list(Config) ->
+
+ ?line OrigFlag = process_flag(trap_exit, true),
+
+ ?line Self = self(),
+ ?line Pid = spawn_link(fun() -> test_otp_6061(Self) end),
+
+ receive
+ working ->
+ ?line ok;
+ not_working ->
+ ?line ?t:fail(not_working);
+ {'EXIT', Pid, Reason} ->
+ ?line ?t:fail({crash, Reason})
+ after
+ 5000 ->
+ ?line ?t:fail(timeout)
+ end,
+
+ ?line process_flag(trap_exit, OrigFlag),
+
+ ok.
+
+test_otp_6061(Starter) ->
+ Passes = [2],
+ PassesF = [fun() -> Starter ! not_working end,
+ fun() -> Starter ! working end,
+ fun() -> Starter ! not_working end],
+ lists:foreach(fun(P)->(lists:nth(P,PassesF))() end,Passes).
diff --git a/lib/debugger/test/guard_SUITE.erl b/lib/debugger/test/guard_SUITE.erl
new file mode 100644
index 0000000000..b5269989c8
--- /dev/null
+++ b/lib/debugger/test/guard_SUITE.erl
@@ -0,0 +1,1479 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 1999-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(guard_SUITE).
+
+-export([all/1,init_per_testcase/2,fin_per_testcase/2,init_all/1,finish_all/1,
+ bad_arith/1,bad_tuple/1,test_heap_guards/1,guard_bifs/1,
+ type_tests/1,const_guard/1,
+ const_cond/1,basic_not/1,complex_not/1,
+ semicolon/1,complex_semicolon/1,comma/1,
+ or_guard/1,more_or_guards/1,
+ complex_or_guards/1,and_guard/1,
+ xor_guard/1,more_xor_guards/1,
+ old_guard_tests/1,
+ build_in_guard/1,gbif/1,
+ t_is_boolean/1,is_function_2/1,
+ tricky/1,rel_ops/1,
+ basic_andalso_orelse/1,traverse_dcd/1,
+ check_qlc_hrl/1]).
+
+-include("test_server.hrl").
+
+-export([init/4]).
+-import(lists, [member/2]).
+
+all(suite) ->
+ [{conf,init_all,cases(),finish_all}].
+
+cases() ->
+ [bad_arith,bad_tuple,test_heap_guards,guard_bifs,type_tests,const_guard,
+ const_cond,basic_not,complex_not,
+ semicolon,complex_semicolon,
+ comma,or_guard,more_or_guards,
+ complex_or_guards,and_guard,
+ xor_guard,more_xor_guards,
+ build_in_guard,old_guard_tests,gbif,
+ t_is_boolean,is_function_2,tricky,rel_ops,
+ basic_andalso_orelse,traverse_dcd,check_qlc_hrl].
+
+init_per_testcase(_Case, Config) ->
+ test_lib:interpret(?MODULE),
+ ?line Dog = test_server:timetrap(?t:minutes(1)),
+ [{watchdog,Dog}|Config].
+
+fin_per_testcase(_Case, Config) ->
+ Dog = ?config(watchdog, Config),
+ ?t:timetrap_cancel(Dog),
+ ok.
+
+init_all(Config) when is_list(Config) ->
+ ?line test_lib:interpret(?MODULE),
+ ?line true = lists:member(?MODULE, int:interpreted()),
+ ok.
+
+finish_all(Config) when is_list(Config) ->
+ ok.
+
+bad_arith(doc) -> "Test that a bad arithmetic operation in a guard works correctly.";
+bad_arith(suite) -> [];
+bad_arith(Config) when list(Config) ->
+ ?line 5 = bad_arith1(2, 3),
+ ?line 10 = bad_arith1(1, infinity),
+ ?line 10 = bad_arith1(infinity, 1),
+ ?line 42 = bad_div(24, 0),
+ ok.
+
+bad_arith1(T1, T2) when T1+T2 < 10 ->
+ T1+T2;
+bad_arith1(_, _) ->
+ 10.
+
+bad_div(A, B) when A/B > 0 ->
+ A/B;
+bad_div(A, B) when A div B > 0 ->
+ A div B;
+bad_div(_A, _B) ->
+ 42.
+
+bad_tuple(doc) -> "Test that bad arguments to element/2 are handled correctly.";
+bad_tuple(suite) -> [];
+bad_tuple(Config) when list(Config) ->
+ ?line error = bad_tuple1(a),
+ ?line error = bad_tuple1({a, b}),
+ ?line x = bad_tuple1({x, b}),
+ ?line y = bad_tuple1({a, b, y}),
+ ok.
+
+bad_tuple1(T) when element(1, T) == x -> x;
+bad_tuple1(T) when element(3, T) == y -> y;
+bad_tuple1(_) -> error.
+
+test_heap_guards(doc) -> "";
+test_heap_guards(suite) -> [];
+test_heap_guards(Config) when list(Config) ->
+ ?line process_flag(trap_exit, true),
+ ?line Tuple = {a, tuple, is, built, here, xxx},
+ ?line List = [a, list, is, built, here],
+
+ ?line try_fun(fun a_case/1, [Tuple], [Tuple]),
+ ?line try_fun(fun a_case/1, [List], [List, List]),
+ ?line try_fun(fun a_case/1, [a], [a]),
+
+ ?line try_fun(fun an_if/1, [Tuple], [Tuple]),
+ ?line try_fun(fun an_if/1, [List], [List, List]),
+ ?line try_fun(fun an_if/1, [a], [a]),
+
+ ?line try_fun(fun receive_test/1, [Tuple], [Tuple]),
+ ?line try_fun(fun receive_test/1, [List], [List, List]),
+ ?line try_fun(fun receive_test/1, [a], [a]),
+ ok.
+
+a_case(V) ->
+ case V of
+ T when T == {a, tuple, is, built, here, xxx} ->
+ [T];
+ L when L == [a, list, is, built, here] ->
+ [L, L];
+ a ->
+ [a]
+ end.
+
+an_if(V) ->
+ if
+ V == {a, tuple, is, built, here, xxx} ->
+ [V];
+ V == [a, list, is, built, here] ->
+ [V, V];
+ V == a ->
+ [a]
+ end.
+
+receive_test(V) ->
+ self() ! V,
+ a_receive().
+
+a_receive() ->
+ receive
+ T when T == {a, tuple, is, built, here, xxx} ->
+ [T];
+ L when L == [a, list, is, built, here] ->
+ [L, L];
+ a ->
+ [a]
+ end.
+
+try_fun(Fun, Args, Result) ->
+ try_fun(16, Fun, Args, Result, []).
+
+try_fun(0, _, _, _, _) ->
+ ok;
+try_fun(Iter, Fun, Args, Result, Filler) ->
+ Pid = spawn_link(?MODULE, init, [self(),Fun,Args,list_to_tuple(Filler)]),
+ receive
+ {'EXIT',Pid,{result,Result}} ->
+ ?line try_fun(Iter-1, Fun, Args, Result, [0|Filler]);
+ {'EXIT',Pid,{result,Other}} ->
+ ?line io:format("Expected ~p; got ~p~n", [Result,Other]),
+ ?line test_server:fail();
+ Other ->
+ ?line test_server:fail({unexpected_message,Other})
+ end.
+
+init(_ReplyTo, Fun, Args, Filler) ->
+ Result = {result, apply(Fun, Args)},
+ dummy(Filler),
+ io:format("~p: result = ~p\n", [?LINE,Result]),
+ exit(Result).
+
+dummy(_) ->
+ ok.
+
+guard_bifs(doc) -> "Test all guard bifs with nasty (but legal arguments).";
+guard_bifs(suite) -> [];
+guard_bifs(Config) when list(Config) ->
+ ?line Big = -237849247829874297658726487367328971246284736473821617265433,
+ ?line Float = 387924.874,
+
+ %% Succeding use of guard bifs.
+
+ ?line try_gbif('abs/1', Big, -Big),
+ ?line try_gbif('float/1', Big, float(Big)),
+ ?line try_gbif('trunc/1', Float, 387924.0),
+ ?line try_gbif('round/1', Float, 387925.0),
+ ?line try_gbif('length/1', [], 0),
+
+ ?line try_gbif('length/1', [a], 1),
+ ?line try_gbif('length/1', [a, b], 2),
+ ?line try_gbif('length/1', lists:seq(0, 31), 32),
+
+ ?line try_gbif('hd/1', [a], a),
+ ?line try_gbif('hd/1', [a, b], a),
+
+ ?line try_gbif('tl/1', [a], []),
+ ?line try_gbif('tl/1', [a, b], [b]),
+ ?line try_gbif('tl/1', [a, b, c], [b, c]),
+
+ ?line try_gbif('size/1', {}, 0),
+ ?line try_gbif('size/1', {a}, 1),
+ ?line try_gbif('size/1', {a, b}, 2),
+ ?line try_gbif('size/1', {a, b, c}, 3),
+ ?line try_gbif('size/1', list_to_binary([]), 0),
+ ?line try_gbif('size/1', list_to_binary([1]), 1),
+ ?line try_gbif('size/1', list_to_binary([1, 2]), 2),
+ ?line try_gbif('size/1', list_to_binary([1, 2, 3]), 3),
+
+ ?line try_gbif('element/2', {x}, {1, x}),
+ ?line try_gbif('element/2', {x, y}, {1, x}),
+ ?line try_gbif('element/2', {x, y}, {2, y}),
+
+ ?line try_gbif('self/0', 0, self()),
+ ?line try_gbif('node/0', 0, node()),
+ ?line try_gbif('node/1', self(), node()),
+
+ %% Failing use of guard bifs.
+
+ ?line try_fail_gbif('abs/1', Big, 1),
+ ?line try_fail_gbif('abs/1', [], 1),
+
+ ?line try_fail_gbif('float/1', Big, 42),
+ ?line try_fail_gbif('float/1', [], 42),
+
+ ?line try_fail_gbif('trunc/1', Float, 0.0),
+ ?line try_fail_gbif('trunc/1', [], 0.0),
+
+ ?line try_fail_gbif('round/1', Float, 1.0),
+ ?line try_fail_gbif('round/1', [], a),
+
+ ?line try_fail_gbif('length/1', [], 1),
+ ?line try_fail_gbif('length/1', [a], 0),
+ ?line try_fail_gbif('length/1', a, 0),
+ ?line try_fail_gbif('length/1', {a}, 0),
+
+ ?line try_fail_gbif('hd/1', [], 0),
+ ?line try_fail_gbif('hd/1', [a], x),
+ ?line try_fail_gbif('hd/1', x, x),
+
+ ?line try_fail_gbif('tl/1', [], 0),
+ ?line try_fail_gbif('tl/1', [a], x),
+ ?line try_fail_gbif('tl/1', x, x),
+
+ ?line try_fail_gbif('size/1', {}, 1),
+ ?line try_fail_gbif('size/1', [], 0),
+ ?line try_fail_gbif('size/1', [a], 1),
+
+ ?line try_fail_gbif('element/2', {}, {1, x}),
+ ?line try_fail_gbif('element/2', {x}, {1, y}),
+ ?line try_fail_gbif('element/2', [], {1, z}),
+
+ ?line try_fail_gbif('self/0', 0, list_to_pid("<0.0.0>")),
+ ?line try_fail_gbif('node/0', 0, xxxx),
+ ?line try_fail_gbif('node/1', self(), xxx),
+ ?line try_fail_gbif('node/1', yyy, xxx),
+ ok.
+
+try_gbif(Id, X, Y) ->
+ case guard_bif(Id, X, Y) of
+ {Id, X, Y} ->
+ io:format("guard_bif(~p, ~p, ~p) -- ok", [Id, X, Y]);
+ Other ->
+ ?line ok = io:format("guard_bif(~p, ~p, ~p) -- bad result: ~p\n",
+ [Id, X, Y, Other]),
+ ?line test_server:fail()
+ end.
+
+try_fail_gbif(Id, X, Y) ->
+ case catch guard_bif(Id, X, Y) of
+ {'EXIT', {function_clause,{?MODULE,guard_bif,[Id,X,Y]}}} -> %Jam
+ io:format("guard_bif(~p, ~p, ~p) -- ok", [Id,X,Y]);
+ {'EXIT', {function_clause,[{?MODULE,guard_bif,[Id,X,Y]}|_]}} -> %Beam
+ io:format("guard_bif(~p, ~p, ~p) -- ok", [Id,X,Y]);
+ Other ->
+ ?line ok = io:format("guard_bif(~p, ~p, ~p) -- bad result: ~p\n",
+ [Id, X, Y, Other]),
+ ?line test_server:fail()
+ end.
+
+guard_bif('abs/1', X, Y) when abs(X) == Y ->
+ {'abs/1', X, Y};
+guard_bif('float/1', X, Y) when float(X) == Y ->
+ {'float/1', X, Y};
+guard_bif('trunc/1', X, Y) when trunc(X) == Y ->
+ {'trunc/1', X, Y};
+guard_bif('round/1', X, Y) when round(X) == Y ->
+ {'round/1', X, Y};
+guard_bif('length/1', X, Y) when length(X) == Y ->
+ {'length/1', X, Y};
+guard_bif('hd/1', X, Y) when hd(X) == Y ->
+ {'hd/1', X, Y};
+guard_bif('tl/1', X, Y) when tl(X) == Y ->
+ {'tl/1', X, Y};
+guard_bif('size/1', X, Y) when size(X) == Y ->
+ {'size/1', X, Y};
+guard_bif('element/2', X, {Pos, Expected}) when element(Pos, X) == Expected ->
+ {'element/2', X, {Pos, Expected}};
+guard_bif('self/0', X, Y) when self() == Y ->
+ {'self/0', X, Y};
+guard_bif('node/0', X, Y) when node() == Y ->
+ {'node/0', X, Y};
+guard_bif('node/1', X, Y) when node(X) == Y ->
+ {'node/1', X, Y}.
+
+type_tests(doc) -> "Test the type tests.";
+type_tests(suite) -> [];
+type_tests(Config) when list(Config) ->
+ ?line Types = all_types(),
+ ?line Tests = type_test_desc(),
+ ?line put(errors, 0),
+ ?line put(violations, 0),
+ ?line type_tests(Tests, Types),
+ ?line case {get(errors), get(violations)} of
+ {0, 0} ->
+ ok;
+ {0, N} ->
+ {comment, integer_to_list(N) ++ " standard violation(s)"};
+ {Errors, Violations} ->
+ io:format("~p sub test(s) failed, ~p violation(s)",
+ [Errors, Violations]),
+ ?line test_server:fail()
+ end.
+
+type_tests([{Test, AllowedTypes}| T], AllTypes) ->
+ type_tests(Test, AllTypes, AllowedTypes),
+ type_tests(T, AllTypes);
+type_tests([], _) ->
+ ok.
+
+type_tests(Test, [Type|T], Allowed) ->
+ {TypeTag, Value} = Type,
+ case member(TypeTag, Allowed) of
+ true ->
+ case catch type_test(Test, Value) of
+ Test ->
+ ok;
+ _Other ->
+ io:format("Test ~p(~p) failed", [Test, Value]),
+ put(errors, get(errors) + 1)
+ end;
+ false ->
+ case catch type_test(Test, Value) of
+ {'EXIT', {function_clause, {?MODULE, type_test, [Test, Value]}}} ->
+ ok;
+ {'EXIT', {function_clause,[{?MODULE,type_test,[Test,Value]}|_]}} ->
+ ok;
+ {'EXIT',Other} ->
+ ?line test_server:fail({unexpected_error_reason,Other});
+ tuple when function(Value) ->
+ io:format("Standard violation: Test ~p(~p) should fail",
+ [Test, Value]),
+ put(violations, get(violations) + 1);
+ _Other ->
+ io:format("Test ~p(~p) succeeded (should fail)", [Test, Value]),
+ put(errors, get(errors) + 1)
+ end
+ end,
+ type_tests(Test, T, Allowed);
+type_tests(_, [], _) ->
+ ok.
+
+all_types() ->
+ [{small, 42},
+ {big, 392742928742947293873938792874019287447829874290742},
+ {float, 3.14156},
+ {nil, []},
+ {cons, [a]},
+ {tuple, {a, b}},
+ {atom, xxxx},
+ {ref, make_ref()},
+ {pid, self()},
+ {port, open_port({spawn, efile}, [])},
+ {function, fun(X) -> X+1, "" end},
+ {binary, list_to_binary([])}].
+
+type_test_desc() ->
+ [{integer, [small, big]},
+ {float, [float]},
+ {number, [small, big, float]},
+ {atom, [atom]},
+ {list, [cons, nil]},
+ {nonempty_list, [cons]},
+ {nil, [nil]},
+ {tuple, [tuple]},
+ {pid, [pid]},
+ {port, [port]},
+ {reference, [ref]},
+ {function, [function]}].
+
+type_test(integer, X) when integer(X) ->
+ integer;
+type_test(float, X) when float(X) ->
+ float;
+type_test(number, X) when number(X) ->
+ number;
+type_test(atom, X) when atom(X) ->
+ atom;
+type_test(list, X) when list(X) ->
+ list;
+type_test(nonempty_list, [_]) ->
+ nonempty_list;
+type_test(nil, []) ->
+ nil;
+type_test(tuple, X) when tuple(X) ->
+ tuple;
+type_test(pid, X) when pid(X) ->
+ pid;
+type_test(reference, X) when reference(X) ->
+ reference;
+type_test(port, X) when port(X) ->
+ port;
+type_test(binary, X) when binary(X) ->
+ binary;
+type_test(function, X) when function(X) ->
+ function.
+
+const_guard(Config) when is_list(Config) ->
+ ?line if
+ (0 == 0) and ((0 == 0) or (0 == 0)) ->
+ ok
+ end.
+
+
+const_cond(Config) when is_list(Config) ->
+ ?line ok = const_cond({}, 0),
+ ?line ok = const_cond({a}, 1),
+ ?line error = const_cond({a,b}, 3),
+ ?line error = const_cond({a}, 0),
+ ?line error = const_cond({a,b}, 1),
+ ok.
+
+const_cond(T, Sz) ->
+ case T of
+ _X when false -> never;
+ _X when tuple(T), eq == eq, size(T) == Sz -> ok;
+ _X when tuple(T), eq == leq, size(T) =< Sz -> ok;
+ _X -> error
+ end.
+
+basic_not(Config) when is_list(Config) ->
+ True = id(true),
+ False = id(false),
+ Glurf = id(glurf),
+ A = id(5),
+ B = id(37.5),
+ C = id(-1),
+ D = id(5),
+ ATuple = {False,True,Glurf},
+
+ ?line check(fun() -> if not false -> ok; true -> error end end, ok),
+ ?line check(fun() -> if not true -> ok; true -> error end end, error),
+ ?line check(fun() -> if not False -> ok; true -> error end end, ok),
+ ?line check(fun() -> if not True -> ok; true -> error end end, error),
+
+ ?line check(fun() -> if A > B -> gt; A < B -> lt; A == B -> eq end end, lt),
+ ?line check(fun() -> if A > C -> gt; A < C -> lt; A == C -> eq end end, gt),
+ ?line check(fun() -> if A > D -> gt; A < D -> lt; A == D -> eq end end, eq),
+
+ ?line check(fun() -> if not (7 > 453) -> le; not (7 < 453) -> ge;
+ not (7 == 453) -> ne; true -> eq end end, le),
+ ?line check(fun() -> if not (7 > -8) -> le; not (7 < -8) -> ge;
+ not (7 == -8) -> ne; true -> eq end end, ge),
+ ?line check(fun() -> if not (7 > 7) -> le; not (7 < 7) -> ge;
+ not (7 == 7) -> ne; true -> eq end end, le),
+
+ ?line check(fun() -> if not (A > B) -> le; not (A < B) -> ge;
+ not (A == B) -> ne; true -> eq end end, le),
+ ?line check(fun() -> if not (A > C) -> le; not (A < C) -> ge;
+ not (A == C) -> ne; true -> eq end end, ge),
+ ?line check(fun() -> if not (A > D) -> le; not (A < D) -> ge;
+ not (A == D) -> ne; true -> eq end end, le),
+
+ ?line check(fun() -> if not element(1, ATuple) -> ok; true -> error end end, ok),
+ ?line check(fun() -> if not element(2, ATuple) -> ok; true -> error end end, error),
+ ?line check(fun() -> if not element(3, ATuple) -> ok; true -> error end end, error),
+
+ ?line check(fun() -> if not glurf -> ok; true -> error end end, error),
+ ?line check(fun() -> if not Glurf -> ok; true -> error end end, error),
+
+ ok.
+
+complex_not(Config) when is_list(Config) ->
+ ATuple = id({false,true,gurka}),
+ ?line check(fun() -> if not(element(1, ATuple)) -> ok; true -> error end end, ok),
+ ?line check(fun() -> if not(element(2, ATuple)) -> ok; true -> error end end, error),
+
+ ?line check(fun() -> if not(element(3, ATuple) == gurka) -> ok;
+ true -> error end end, error),
+ ?line check(fun() -> if not(element(3, ATuple) =/= gurka) -> ok;
+ true -> error end end, ok),
+
+ ?line check(fun() -> if {a,not(element(2, ATuple))} == {a,false} -> ok;
+ true -> error end end, ok),
+ ?line check(fun() -> if {a,not(element(1, ATuple))} == {a,false} -> ok;
+ true -> error end end, error),
+
+ ?line check(fun() -> if not(element(1, ATuple) or element(3, ATuple)) -> ok;
+ true -> error end end, error),
+
+ %% orelse
+ ?line check(fun() -> if not(element(1, ATuple) orelse element(3, ATuple)) -> ok;
+ true -> error end end, error),
+
+ ok.
+
+semicolon(Config) when is_list(Config) ->
+
+ %% True/false combined using ';' (literal atoms).
+
+ ?line check(fun() -> if true; false -> ok end end, ok),
+ ?line check(fun() -> if false; true -> ok end end, ok),
+ ?line check(fun() -> if true; true -> ok end end, ok),
+ ?line check(fun() -> if false; false -> ok; true -> error end end, error),
+ ?line check(fun() ->
+ {'EXIT',{if_clause,_}} = (catch if false; false -> ok end),
+ exit
+ end, exit),
+
+ %% True/false combined used ';'.
+
+ True = id(true),
+ False = id(false),
+
+ ?line check(fun() -> if True; False -> ok end end, ok),
+ ?line check(fun() -> if False; True -> ok end end, ok),
+ ?line check(fun() -> if True; True -> ok end end, ok),
+ ?line check(fun() -> if False; False -> ok; true -> error end end, error),
+ ?line check(fun() ->
+ {'EXIT',{if_clause,_}} = (catch if False; False -> ok end),
+ exit
+ end, exit),
+
+ %% Combine true/false with a non-boolean value.
+ Glurf = id(glurf),
+
+
+ ?line check(fun() -> if True; Glurf -> ok end end, ok),
+ ?line check(fun() -> if Glurf; True -> ok end end, ok),
+ ?line check(fun() -> if Glurf; Glurf -> ok; true -> error end end, error),
+ ?line check(fun() -> if False; Glurf -> ok; true -> error end end, error),
+ ?line check(fun() -> if Glurf; False -> ok; true -> error end end, error),
+ ?line check(fun() ->
+ {'EXIT',{if_clause,_}} = (catch if Glurf; Glurf -> ok end),
+ exit
+ end, exit),
+
+ %% Combine true/false with errors.
+
+ ATuple = id({false,true,gurka}),
+
+ ?line check(fun() -> if True; element(42, ATuple) -> ok end end, ok),
+ ?line check(fun() -> if element(42, ATuple); True -> ok end end, ok),
+ ?line check(fun() -> if element(42, ATuple); element(42, ATuple) -> ok;
+ true -> error end end, error),
+ ?line check(fun() -> if False; element(42, ATuple) -> ok;
+ true -> error end end, error),
+ ?line check(fun() -> if element(42, ATuple);
+ False -> ok; true -> error end end, error),
+ ?line check(fun() ->
+ {'EXIT',{if_clause,_}} =
+ (catch if element(42, ATuple);
+ element(42, ATuple) -> ok end),
+ exit
+ end, exit),
+
+ ok.
+
+complex_semicolon(Config) when is_list(Config) ->
+ ?line ok = csemi1(int, {blurf}),
+ ?line ok = csemi1(string, {blurf}),
+ ?line ok = csemi1(float, [a]),
+ ?line error = csemi1(35, 42),
+
+ %% 2
+ ?line ok = csemi2({}, {a,b,c}),
+ ?line ok = csemi2({1,3.5}, {a,b,c}),
+ ?line ok = csemi2(dum, {a,b,c}),
+
+ ?line ok = csemi2({45,-19.3}, {}),
+ ?line ok = csemi2({45,-19.3}, {dum}),
+ ?line ok = csemi2({45,-19.3}, {dum,dum}),
+
+ ?line error = csemi2({45}, {dum}),
+ ?line error = csemi2([], {dum}),
+ ?line error = csemi2({dum}, []),
+ ?line error = csemi2([], []),
+
+ %% 3
+ ?line csemi3(fun csemi3a/4),
+ ?line csemi3(fun csemi3b/4),
+ ?line csemi3(fun csemi3c/4),
+
+ %% 4
+ ?line csemi4(fun csemi4a/4),
+ ?line csemi4(fun csemi4b/4),
+ ?line csemi4(fun csemi4c/4),
+ ?line csemi4(fun csemi4d/4),
+
+ %% 4, 'orelse' instead of 'or'
+ ?line csemi4_orelse(fun csemi4_orelse_a/4),
+ ?line csemi4_orelse(fun csemi4_orelse_b/4),
+ ?line csemi4_orelse(fun csemi4_orelse_c/4),
+ ?line csemi4_orelse(fun csemi4_orelse_d/4),
+
+ ok.
+
+csemi1(Type, Val) when is_list(Val), Type == float;
+ Type == int; Type == string -> ok;
+csemi1(_, _) -> error.
+
+csemi2(A, B) when size(A) > 1; size(B) > 2 -> ok;
+csemi2(_, _) -> error.
+
+csemi3(Csemi3) ->
+ ok = Csemi3({}, {a,b,c}, [0], [0]),
+ ok = Csemi3({1,3.5}, {a,b,c}, -1, -1),
+ ok = Csemi3(dum, {a,b,c}, 0.0, 0.0),
+ ok = Csemi3(dum, {c}, b, a),
+ ok = Csemi3(dum, <<1,2,3>>, 0.0, 0.0),
+ ok = Csemi3(<<3.5/float>>, {a,b,c}, -1, -1),
+
+ ok = Csemi3({45,-19.3}, {}, [], []),
+ ok = Csemi3({45,-19.3}, {dum}, 42, 42),
+ ok = Csemi3({45,-19.3}, {dum,dum}, 33, 33),
+
+ ok = Csemi3({45}, {dum}, 1.0, 0),
+ ok = Csemi3([a], {dum}, 1.0, 0),
+ ok = Csemi3({dum}, [], 1.0, 0),
+ ok = Csemi3([], [], 1.0, 0),
+ ok = Csemi3(blurf, {dum}, 1.0, 0),
+ ok = Csemi3({a}, blurf, 1.0, 0),
+ ok = Csemi3([a], [dum], 1.0, 0),
+ ok = Csemi3({dum}, [], 1.0, 0),
+ ok = Csemi3([], [], 1.0, 0),
+
+ error = Csemi3({45}, {dum}, 0, 0),
+ error = Csemi3([a], {dum}, 0, 0),
+ error = Csemi3({dum}, [], 0, 0),
+ error = Csemi3([], [], 0, 0),
+ ok.
+
+csemi3a(A, B, X, Y) when X > Y; size(A) > 1; size(B) > 2 -> ok;
+csemi3a(_, _, _, _) -> error.
+
+csemi3b(A, B, X, Y) when size(A) > 1; X > Y; size(B) > 2 -> ok;
+csemi3b(_, _, _, _) -> error.
+
+csemi3c(A, B, X, Y) when size(A) > 1; size(B) > 2; X > Y -> ok;
+csemi3c(_, _, _, _) -> error.
+
+
+csemi4(Test) ->
+ ok = Test({a,b}, 2, {c,d}, 2),
+ ok = Test({1,2,3}, 0, [], 0),
+ ok = Test({}, 2, blurf, 0),
+ ok = Test({}, 2, {1}, 2),
+
+ error = Test([], 4, {}, 0),
+ error = Test({}, 0, [a,b], 4),
+ error = Test({}, 0, [a,b], 0),
+ error = Test([], 0, {}, 0),
+ error = Test({}, 0, {}, 0),
+
+ ok.
+
+csemi4a(A, X, B, Y) when (size(A) > 1) or (X > 1);
+ (size(B) > 1) or (Y > 1) -> ok;
+csemi4a(_, _, _, _) -> error.
+
+csemi4b(A, X, B, Y) when (X > 1) or (size(A) > 1);
+ (size(B) > 1) or (Y > 1) -> ok;
+csemi4b(_, _, _, _) -> error.
+
+csemi4c(A, X, B, Y) when (size(A) > 1) or (X > 1);
+ (Y > 1) or (size(B) > 1) -> ok;
+csemi4c(_, _, _, _) -> error.
+
+csemi4d(A, X, B, Y) when (X > 1) or (size(A) > 1);
+ (Y > 1) or (size(B) > 1) -> ok;
+csemi4d(_, _, _, _) -> error.
+
+
+csemi4_orelse(Test) ->
+ ok = Test({a,b}, 2, {c,d}, 2),
+ ok = Test({1,2,3}, 0, [], 0),
+ ok = Test({}, 2, blurf, 0),
+ ok = Test({}, 2, {1}, 2),
+
+ ?line error = Test([], 1, {}, 0),
+
+ ok.
+
+csemi4_orelse_a(A, X, B, Y) when (size(A) > 1) orelse (X > 1);
+ (size(B) > 1) orelse (Y > 1) -> ok;
+csemi4_orelse_a(_, _, _, _) -> error.
+
+csemi4_orelse_b(A, X, B, Y) when (X > 1) orelse (size(A) > 1);
+ (size(B) > 1) orelse (Y > 1) -> ok;
+csemi4_orelse_b(_, _, _, _) -> error.
+
+csemi4_orelse_c(A, X, B, Y) when (size(A) > 1) orelse (X > 1);
+ (Y > 1) orelse (size(B) > 1) -> ok;
+csemi4_orelse_c(_, _, _, _) -> error.
+
+csemi4_orelse_d(A, X, B, Y) when (X > 1) or (size(A) > 1);
+ (Y > 1) or (size(B) > 1) -> ok;
+csemi4_orelse_d(_, _, _, _) -> error.
+
+
+comma(Config) when is_list(Config) ->
+
+ %% ',' combinations of literal true/false.
+
+ ?line check(fun() -> if true, false -> ok; true -> error end end, error),
+ ?line check(fun() -> if false, true -> ok; true -> error end end, error),
+ ?line check(fun() -> if true, true -> ok end end, ok),
+ ?line check(fun() -> if false, false -> ok; true -> error end end, error),
+ ?line check(fun() ->
+ {'EXIT',{if_clause,_}} =
+ (catch if true, false -> ok;
+ false, true -> ok;
+ false, false -> ok
+ end),
+ exit
+ end, exit),
+
+ %% ',' combinations of true/false in variables.
+
+ True = id(true),
+ False = id(false),
+
+ ?line check(fun() -> if True, False -> ok; true -> error end end, error),
+ ?line check(fun() -> if False, True -> ok; true -> error end end, error),
+ ?line check(fun() -> if True, True -> ok end end, ok),
+ ?line check(fun() -> if False, False -> ok; true -> error end end, error),
+ ?line check(fun() ->
+ {'EXIT',{if_clause,_}} =
+ (catch if True, False -> ok;
+ False, True -> ok;
+ False, False -> ok
+ end),
+ exit
+ end, exit),
+
+ %% ',' combinations of true/false, and non-boolean in variables.
+
+ Glurf = id(glurf),
+
+ ?line check(fun() -> if True, Glurf -> ok; true -> error end end, error),
+ ?line check(fun() -> if Glurf, True -> ok; true -> error end end, error),
+ ?line check(fun() -> if True, True -> ok end end, ok),
+ ?line check(fun() -> if Glurf, Glurf -> ok; true -> error end end, error),
+ ?line check(fun() ->
+ {'EXIT',{if_clause,_}} =
+ (catch if True, Glurf -> ok;
+ Glurf, True -> ok;
+ Glurf, Glurf -> ok
+ end),
+ exit
+ end, exit),
+
+ %% ',' combinations of true/false with errors.
+ ATuple = id({a,b,c}),
+
+ ?line check(fun() -> if True, element(42, ATuple) -> ok;
+ true -> error end end, error),
+ ?line check(fun() -> if element(42, ATuple), True -> ok;
+ true -> error end end, error),
+ ?line check(fun() -> if True, True -> ok end end, ok),
+ ?line check(fun() -> if element(42, ATuple), element(42, ATuple) -> ok;
+ true -> error end end, error),
+ ?line check(fun() ->
+ {'EXIT',{if_clause,_}} =
+ (catch if True, element(42, ATuple) -> ok;
+ element(42, ATuple), True -> ok;
+ element(42, ATuple), element(42, ATuple) -> ok
+ end),
+ exit
+ end, exit),
+
+ ok.
+
+or_guard(Config) when is_list(Config) ->
+ True = id(true),
+ False = id(false),
+ Glurf = id(glurf),
+
+ %% 'or' combinations of literal true/false.
+ ?line check(fun() -> if true or false -> ok end end, ok),
+ ?line check(fun() -> if false or true -> ok end end, ok),
+ ?line check(fun() -> if true or true -> ok end end, ok),
+ ?line check(fun() -> if false or false -> ok; true -> error end end, error),
+
+ ?line check(fun() -> if glurf or true -> ok; true -> error end end, error),
+ ?line check(fun() -> if true or glurf -> ok; true -> error end end, error),
+ ?line check(fun() -> if glurf or glurf -> ok; true -> error end end, error),
+
+ ?line check(fun() ->
+ {'EXIT',{if_clause,_}} = (catch if false or false -> ok end),
+ exit
+ end, exit),
+
+
+ %% 'or' combinations using variables containing true/false.
+ ?line check(fun() -> if True or False -> ok end end, ok),
+ ?line check(fun() -> if False or True -> ok end end, ok),
+ ?line check(fun() -> if True or True -> ok end end, ok),
+ ?line check(fun() -> if False or False -> ok; true -> error end end, error),
+
+ ?line check(fun() -> if True or Glurf -> ok; true -> error end end, error),
+ ?line check(fun() -> if Glurf or True -> ok; true -> error end end, error),
+ ?line check(fun() -> if Glurf or Glurf -> ok; true -> error end end, error),
+
+ ?line check(fun() ->
+ {'EXIT',{if_clause,_}} = (catch if False or False -> ok end),
+ exit
+ end, exit),
+
+ ok.
+
+more_or_guards(Config) when is_list(Config) ->
+ True = id(true),
+ False = id(false),
+ ATuple = id({false,true,gurka}),
+
+ ?line check(fun() ->
+ if element(42, ATuple) or False -> ok;
+ true -> error end
+ end, error),
+
+ ?line check(fun() ->
+ if False or element(42, ATuple) -> ok;
+ true -> error end
+ end, error),
+
+ ?line check(fun() ->
+ if element(18, ATuple) or element(42, ATuple) -> ok;
+ true -> error end
+ end, error),
+
+ ?line check(fun() ->
+ if True or element(42, ATuple) -> ok;
+ true -> error end
+ end, error),
+
+ ?line check(fun() ->
+ if element(42, ATuple) or True -> ok;
+ true -> error end
+ end, error),
+
+ ?line check(fun() ->
+ if element(1, ATuple) or element(42, ATuple) or True -> ok;
+ true -> error end
+ end, error),
+
+ ?line check(fun() ->
+ if element(1, ATuple) or True or element(42, ATuple) -> ok;
+ true -> error end
+ end, error),
+
+ ?line check(fun() ->
+ if
+ (<<False:8>> == <<0>>) or element(2, ATuple) -> ok;
+ true -> error end
+ end, error),
+
+ ?line check(fun() ->
+ if
+ element(2, ATuple) or (<<True:8>> == <<1>>) -> ok;
+ true -> error end
+ end, error),
+
+ ?line check(fun() ->
+ if element(2, ATuple) or element(42, ATuple) -> ok;
+ true -> error end
+ end, error),
+
+ ?line check(fun() ->
+ if
+ element(1, ATuple) or
+ element(2, ATuple) or
+ element(19, ATuple) -> ok;
+ true -> error end
+ end, error),
+ ok.
+
+complex_or_guards(Config) when is_list(Config) ->
+ %% complex_or_1/2
+ ?line ok = complex_or_1({a,b,c,d}, {1,2,3}),
+ ?line ok = complex_or_1({a,b,c,d}, {1}),
+ ?line ok = complex_or_1({a}, {1,2,3}),
+ ?line error = complex_or_1({a}, {1}),
+
+ ?line error = complex_or_1(1, 2),
+ ?line error = complex_or_1([], {a,b,c,d}),
+ ?line error = complex_or_1({a,b,c,d}, []),
+
+
+ %% complex_or_2/1
+ ?line ok = complex_or_2({true,{}}),
+ ?line ok = complex_or_2({false,{a}}),
+ ?line ok = complex_or_2({false,{a,b,c}}),
+ ?line ok = complex_or_2({true,{a,b,c,d}}),
+
+ ?line error = complex_or_2({blurf,{a,b,c}}),
+
+ ?line error = complex_or_2({true}),
+ ?line error = complex_or_2({true,no_tuple}),
+ ?line error = complex_or_2({true,[]}),
+
+ %% complex_or_3/2
+ ?line ok = complex_or_3({true}, {}),
+ ?line ok = complex_or_3({false}, {a}),
+ ?line ok = complex_or_3({false}, {a,b,c}),
+ ?line ok = complex_or_3({true}, {a,b,c,d}),
+ ?line ok = complex_or_3({false}, <<1,2,3>>),
+ ?line ok = complex_or_3({true}, <<1,2,3,4>>),
+
+ ?line error = complex_or_3(blurf, {a,b,c}),
+
+ ?line error = complex_or_3({false}, <<1,2,3,4>>),
+ ?line error = complex_or_3([], <<1,2>>),
+ ?line error = complex_or_3({true}, 45),
+ ?line error = complex_or_3(<<>>, <<>>),
+
+ %% complex_or_4/2
+ ?line ok = complex_or_4(<<1,2,3>>, {true}),
+ ?line ok = complex_or_4(<<1,2,3>>, {false}),
+ ?line ok = complex_or_4(<<1,2,3>>, {true}),
+ ?line ok = complex_or_4({1,2,3}, {true}),
+ ?line error = complex_or_4({1,2,3,4}, {false}),
+
+ ?line error = complex_or_4(<<1,2,3,4>>, []),
+ ?line error = complex_or_4([], {true}),
+
+ %% complex_or_5/2
+ ?line ok = complex_or_5(<<1>>, {false}),
+ ?line ok = complex_or_5(<<1,2,3>>, {true}),
+ ?line ok = complex_or_5(<<1,2,3,4>>, {false}),
+ ?line ok = complex_or_5({1,2,3}, {false}),
+ ?line ok = complex_or_5({1,2,3,4}, {false}),
+
+ ?line error = complex_or_5(blurf, {false}),
+ ?line error = complex_or_5(<<1>>, klarf),
+ ?line error = complex_or_5(blurf, klarf),
+
+ %% complex_or_6/2
+ ?line ok = complex_or_6({true,true}, {1,2,3,4}),
+ ?line ok = complex_or_6({true,true}, <<1,2,3,4>>),
+ ?line ok = complex_or_6({false,false}, <<1,2,3,4>>),
+ ?line ok = complex_or_6({false,true}, <<1>>),
+ ?line ok = complex_or_6({true,false}, {1}),
+ ?line ok = complex_or_6({true,true}, {1}),
+
+ ?line error = complex_or_6({false,false}, {1}),
+
+ ?line error = complex_or_6({true}, {1,2,3,4}),
+ ?line error = complex_or_6({}, {1,2,3,4}),
+ ?line error = complex_or_6([], {1,2,3,4}),
+ ?line error = complex_or_6([], {1,2,3,4}),
+ ?line error = complex_or_6({true,false}, klurf),
+
+ ok.
+
+complex_or_1(A, B) ->
+ if
+ ((3 < size(A)) and (size(A) < 9)) or
+ ((2 < size(B)) and (size(B) < 7)) -> ok;
+ true -> error
+ end.
+
+complex_or_2(Tuple) ->
+ if
+ element(1, Tuple) or not (size(element(2, Tuple)) > 3) -> ok;
+ true -> error
+ end.
+
+complex_or_3(A, B) ->
+ if
+ not (size(B) > 3) or element(1, A) -> ok;
+ true -> error
+ end.
+
+complex_or_4(A, B) ->
+ if
+ not (is_tuple(A) and (size(A) > 3)) or element(1, B) -> ok;
+ true -> error
+ end.
+
+complex_or_5(A, B) ->
+ if
+ not (is_tuple(A) or (size(A) > 3)) or not element(1, B) -> ok;
+ true -> error
+ end.
+
+complex_or_6(A, B) ->
+ if
+ not (not element(1, A) and not element(2, A)) or
+ not (not (size(B) > 3)) -> ok;
+ true -> error
+ end.
+
+and_guard(Config) when is_list(Config) ->
+
+ %% 'and' combinations of literal true/false.
+
+ ?line check(fun() -> if true and false -> ok; true -> error end end, error),
+ ?line check(fun() -> if false and true -> ok; true -> error end end, error),
+ ?line check(fun() -> if true and true -> ok end end, ok),
+ ?line check(fun() -> if false and false -> ok; true -> error end end, error),
+
+ ?line check(fun() -> if glurf and true -> ok; true -> error end end, error),
+ ?line check(fun() -> if true and glurf -> ok; true -> error end end, error),
+ ?line check(fun() -> if glurf and glurf -> ok; true -> error end end, error),
+
+ ?line check(fun() ->
+ {'EXIT',{if_clause,_}} =
+ (catch if true and false -> ok;
+ false and true -> ok;
+ false and false -> ok
+ end),
+ exit
+ end, exit),
+
+ %% 'and' combinations of true/false in variables.
+
+ True = id(true),
+ False = id(false),
+
+ ?line check(fun() -> if True and False -> ok; true -> error end end, error),
+ ?line check(fun() -> if False and True -> ok; true -> error end end, error),
+ ?line check(fun() -> if True and True -> ok end end, ok),
+ ?line check(fun() -> if False and False -> ok; true -> error end end, error),
+ ?line check(fun() ->
+ {'EXIT',{if_clause,_}} =
+ (catch if True and False -> ok;
+ False and True -> ok;
+ False and False -> ok
+ end),
+ exit
+ end, exit),
+
+ %% 'and' combinations of true/false and a non-boolean in variables.
+
+ Glurf = id(glurf),
+
+ ?line check(fun() -> if True and Glurf -> ok; true -> error end end, error),
+ ?line check(fun() -> if Glurf and True -> ok; true -> error end end, error),
+ ?line check(fun() -> if True and True -> ok end end, ok),
+ ?line check(fun() -> if Glurf and Glurf -> ok; true -> error end end, error),
+ ?line check(fun() ->
+ {'EXIT',{if_clause,_}} =
+ (catch if True and Glurf -> ok;
+ Glurf and True -> ok;
+ Glurf and Glurf -> ok
+ end),
+ exit
+ end, exit),
+
+ %% 'and' combinations of true/false with errors.
+ ATuple = id({a,b,c}),
+
+ ?line check(fun() -> if True and element(42, ATuple) -> ok;
+ true -> error end end, error),
+ ?line check(fun() -> if element(42, ATuple) and True -> ok;
+ true -> error end end, error),
+ ?line check(fun() -> if True and True -> ok end end, ok),
+ ?line check(fun() -> if element(42, ATuple) and element(42, ATuple) -> ok;
+ true -> error end end, error),
+ ?line check(fun() ->
+ {'EXIT',{if_clause,_}} =
+ (catch if True and element(42, ATuple) -> ok;
+ element(42, ATuple) and True -> ok;
+ element(42, ATuple) and element(42, ATuple) -> ok
+ end),
+ exit
+ end, exit),
+
+ ?line ok = relprod({'Set',a,b}, {'Set',a,b}),
+
+ ok.
+
+relprod(R1, R2) when (erlang:size(R1) =:= 3) and (erlang:element(1,R1) =:= 'Set'), (erlang:size(R2) =:= 3) and (erlang:element(1,R2) =:= 'Set') ->
+ ok.
+
+
+xor_guard(Config) when is_list(Config) ->
+
+ %% 'xor' combinations of literal true/false.
+ ?line check(fun() -> if true xor false -> ok end end, ok),
+ ?line check(fun() -> if false xor true -> ok end end, ok),
+ ?line check(fun() -> if true xor true -> ok; true -> error end end, error),
+ ?line check(fun() -> if false xor false -> ok; true -> error end end, error),
+ ?line check(fun() ->
+ {'EXIT',{if_clause,_}} = (catch if false xor false -> ok end),
+ exit
+ end, exit),
+ ?line check(fun() ->
+ {'EXIT',{if_clause,_}} = (catch if true xor true -> ok end),
+ exit
+ end, exit),
+
+
+ %% 'xor' combinations using variables containing true/false.
+
+ True = id(true),
+ False = id(false),
+
+ ?line check(fun() -> if True xor False -> ok end end, ok),
+ ?line check(fun() -> if False xor True -> ok end end, ok),
+ ?line check(fun() -> if True xor True -> ok; true -> error end end, error),
+ ?line check(fun() -> if False xor False -> ok; true -> error end end, error),
+ ?line check(fun() ->
+ {'EXIT',{if_clause,_}} = (catch if False xor False -> ok end),
+ exit
+ end, exit),
+ ?line check(fun() ->
+ {'EXIT',{if_clause,_}} = (catch if True xor True -> ok end),
+ exit
+ end, exit),
+
+ ok.
+
+more_xor_guards(Config) when is_list(Config) ->
+ True = id(true),
+ False = id(false),
+ ATuple = id({false,true,gurka}),
+
+ ?line check(fun() ->
+ if element(42, ATuple) xor False -> ok;
+ true -> error end
+ end, error),
+
+ ?line check(fun() ->
+ if False xor element(42, ATuple) xor False -> ok;
+ true -> error end
+ end, error),
+
+ ?line check(fun() ->
+ if element(18, ATuple) xor element(42, ATuple) -> ok;
+ true -> error end
+ end, error),
+
+ ?line check(fun() ->
+ if True xor element(42, ATuple) -> ok;
+ true -> error end
+ end, error),
+
+ ?line check(fun() ->
+ if element(42, ATuple) xor True -> ok;
+ true -> error end
+ end, error),
+ ok.
+
+build_in_guard(Config) when is_list(Config) ->
+ SubBin = <<5.0/float>>,
+ ?line B = <<1,SubBin/binary,3.5/float>>,
+ ?line if
+ B =:= <<1,SubBin/binary,3.5/float>> -> ok
+ end.
+
+old_guard_tests(Config) when list(Config) ->
+ %% Check that all the old guard tests are still recognized.
+ ?line list = og(Config),
+ ?line atom = og(an_atom),
+ ?line binary = og(<<1,2>>),
+ ?line float = og(3.14),
+ ?line integer = og(43),
+ ?line a_function = og(fun() -> ok end),
+ ?line pid = og(self()),
+ ?line reference = og(make_ref()),
+ ?line tuple = og({}),
+
+ ?line number = on(45.333),
+ ?line number = on(-19),
+ ok.
+
+og(V) when atom(V) -> atom;
+og(V) when binary(V) -> binary;
+og(V) when float(V) -> float;
+og(V) when integer(V) -> integer;
+og(V) when function(V) -> a_function;
+og(V) when list(V) -> list;
+og(V) when pid(V) -> pid;
+og(V) when port(V) -> port;
+og(V) when reference(V) -> reference;
+og(V) when tuple(V) -> tuple;
+og(_) -> what.
+
+on(V) when number(V) -> number;
+on(_) -> not_number.
+
+gbif(Config) when is_list(Config) ->
+ ?line error = gbif_1(1, {false,true}),
+ ?line ok = gbif_1(2, {false,true}),
+ ok.
+
+gbif_1(P, T) when element(P, T) -> ok;
+gbif_1(_, _) -> error.
+
+
+t_is_boolean(Config) when is_list(Config) ->
+ ?line true = is_boolean(true),
+ ?line true = is_boolean(false),
+ ?line true = is_boolean(id(true)),
+ ?line true = is_boolean(id(false)),
+
+ ?line false = is_boolean(glurf),
+ ?line false = is_boolean(id(glurf)),
+
+ ?line false = is_boolean([]),
+ ?line false = is_boolean(id([])),
+ ?line false = is_boolean(42),
+ ?line false = is_boolean(id(-42)),
+
+ ?line false = is_boolean(math:pi()),
+ ?line false = is_boolean(384793478934378924978439789873478934897),
+
+ ?line false = is_boolean(id(self())),
+ ?line false = is_boolean(id({x,y,z})),
+ ?line false = is_boolean(id([a,b,c])),
+ ?line false = is_boolean(id(make_ref())),
+ ?line false = is_boolean(id(<<1,2,3>>)),
+
+ ?line ok = bool(true),
+ ?line ok = bool(false),
+ ?line ok = bool(id(true)),
+ ?line ok = bool(id(false)),
+
+ ?line error = bool(glurf),
+ ?line error = bool(id(glurf)),
+
+ ?line error = bool([]),
+ ?line error = bool(id([])),
+ ?line error = bool(42),
+ ?line error = bool(id(-42)),
+
+ ?line error = bool(math:pi()),
+ ?line error = bool(384793478934378924978439789873478934897),
+
+ ?line error = bool(id(self())),
+ ?line error = bool(id({x,y,z})),
+ ?line error = bool(id([a,b,c])),
+ ?line error = bool(id(make_ref())),
+ ?line error = bool(id(<<1,2,3>>)),
+
+ ok.
+
+bool(X) when is_boolean(X) -> ok;
+bool(_) -> error.
+
+
+is_function_2(Config) when is_list(Config) ->
+ true = is_function(id(fun ?MODULE:all/1), 1),
+ true = is_function(id(fun() -> ok end), 0),
+ false = is_function(id(fun ?MODULE:all/1), 0),
+ false = is_function(id(fun() -> ok end), 1),
+
+ F = fun(_) -> ok end,
+ if
+ is_function(F, 1) -> ok
+ end.
+
+tricky(Config) when is_list(Config) ->
+ ?line not_ok = tricky_1(1, 2),
+ ?line not_ok = tricky_1(1, blurf),
+ ?line not_ok = tricky_1(foo, 2),
+ ?line not_ok = tricky_1(a, b),
+
+ ?line false = rb(100000, [1], 42),
+ ?line true = rb(100000, [], 42),
+ ?line true = rb(555, [a,b,c], 19),
+ ok.
+
+tricky_1(X, Y) when abs((X == 1) or (Y == 2)) -> ok;
+tricky_1(_, _) -> not_ok.
+
+%% From dets_v9:read_buckets/11, simplified.
+
+rb(Size, ToRead, SoFar) when SoFar + Size < 81920; ToRead == [] -> true;
+rb(_, _, _) -> false.
+
+
+-define(T(Op,A,B),
+ ok = if A Op B -> ok; true -> error end,
+ ok = if not (A Op B) -> error; true -> ok end,
+ (fun(X, Y, True, False) ->
+ ok = if X Op Y -> ok; true -> error end,
+ ok = if False; X Op Y; False -> ok; true -> error end,
+ ok = if X Op Y, True -> ok; true -> error end,
+ ok = if not (X Op Y) -> error; true -> ok end,
+ ok = if False; not (X Op Y); False -> error; true -> ok end
+ end)(id(A), id(B), id(true), id(false))).
+
+-define(F(Op,A,B),
+ ok = if A Op B -> error; true -> ok end,
+ ok = if not (A Op B) -> ok; true -> error end,
+ (fun(X, Y, True, False) ->
+ ok = if X Op Y -> error; true -> ok end,
+ ok = if False; X Op Y; False -> error; true -> ok end,
+ ok = if not (X Op Y); False -> ok; true -> error end,
+ ok = if not (X Op Y), True -> ok; true -> error end
+ end)(id(A), id(B), id(true), id(false))).
+
+
+rel_ops(Config) when is_list(Config) ->
+ ?line ?T(=/=, 1, 1.0),
+ ?line ?F(=/=, 2, 2),
+ ?line ?F(=/=, {a}, {a}),
+
+ ?line ?F(/=, a, a),
+ ?line ?F(/=, 0, 0.0),
+ ?line ?T(/=, 0, 1),
+ ?line ?F(/=, {a}, {a}),
+
+ ?line ?T(==, 1, 1.0),
+ ?line ?F(==, a, {}),
+
+ ?line ?F(=:=, 1, 1.0),
+ ?line ?T(=:=, 42.0, 42.0),
+
+ ?line ?F(>, a, b),
+ ?line ?T(>, 42, 1.0),
+ ?line ?F(>, 42, 42.0),
+
+ ?line ?T(<, a, b),
+ ?line ?F(<, 42, 1.0),
+ ?line ?F(<, 42, 42.0),
+
+ ?line ?T(=<, 1.5, 5),
+ ?line ?F(=<, -9, -100.344),
+ ?line ?T(=<, 42, 42.0),
+
+ ?line ?T(>=, 42, 42.0),
+ ?line ?F(>=, a, b),
+ ?line ?T(>=, 1.0, 0),
+
+ ok.
+
+-undef(TestOp).
+
+basic_andalso_orelse(Config) when is_list(Config) ->
+ ?line T = id({type,integers,23,42}),
+ ?line 65 = if
+ ((element(1, T) =:= type) andalso (size(T) =:= 4) andalso
+ element(2, T) == integers) ->
+ element(3, T) + element(4, T);
+ true -> error
+ end,
+ ?line 65 = case [] of
+ [] when ((element(1, T) =:= type) andalso (size(T) =:= 4) andalso
+ element(2, T) == integers) ->
+ element(3, T) + element(4, T)
+ end,
+
+ ?line 42 = basic_rt({type,integers,40,2}),
+ ?line 5.0 = basic_rt({vector,{3.0,4.0}}),
+ ?line 20 = basic_rt(['+',3,7]),
+ ?line {'Set',a,b} = basic_rt({{'Set',a,b},{'Set',a,b}}),
+ ?line 12 = basic_rt({klurf,4}),
+
+ ?line error = basic_rt({type,integers,40,2,3}),
+ ?line error = basic_rt({kalle,integers,40,2}),
+ ?line error = basic_rt({kalle,integers,40,2}),
+ ?line error = basic_rt({1,2}),
+ ?line error = basic_rt([]),
+
+ RelProdBody =
+ fun(R1, R2) ->
+ if
+ (erlang:size(R1) =:= 3) andalso (erlang:element(1,R1) =:= 'Set'),
+ (erlang:size(R2) =:= 3) andalso (erlang:element(1,R2) =:= 'Set') ->
+ ok
+ end
+ end,
+
+ ?line ok = RelProdBody({'Set',a,b}, {'Set',a,b}),
+ ok.
+
+basic_rt(T) when is_tuple(T) andalso size(T) =:= 4 andalso element(1, T) =:= type andalso
+ element(2, T) == integers ->
+ element(3, T) + element(4, T);
+basic_rt(T) when is_tuple(T) andalso size(T) =:= 2 andalso element(1, T) =:= vector ->
+ {X,Y} = element(2, T),
+ if
+ is_float(X), is_float(Y) ->
+ math:sqrt(X*X+Y*Y)
+ end;
+basic_rt(['+',A,B]) ->
+ 2*id(A+B);
+basic_rt({R1,R2}) when erlang:size(R1) =:= 3 andalso erlang:element(1,R1) =:= 'Set',
+ erlang:size(R2) =:= 3 andalso erlang:element(1,R2) =:= 'Set' ->
+ R1 = id(R1),
+ R2 = id(R2),
+ R1;
+basic_rt(T) when is_tuple(T) andalso size(T) =:= 2 andalso element(1, T) =:= klurf ->
+ 3*id(element(2, T));
+basic_rt(_) ->
+ error.
+
+traverse_dcd(Config) when is_list(Config) ->
+ L0 = [{log_header,dcd_log,"1.0",a,b,c},{log_header,dcd_log,"2.0",a,b,c},
+ {log_header,dcd_log,"0.0",a,b,c},blurf],
+ {cont,[{log_header,dcd_log,"0.0",a,b,c},blurf],log,funny} =
+ traverse_dcd({cont,L0}, log, funny),
+ L1 = [{log_header,dcd_log,"1.0"}],
+ {cont,L1,log,funny} = traverse_dcd({cont,L1}, log, funny),
+ L2 = [{a,tuple}],
+ {cont,L2,log,funny} = traverse_dcd({cont,L2}, log, funny),
+ ok.
+
+%% The function starts out with 3 arguments in {x,0}, {x,1}, {x,2}.
+%% The outer match of a two tuple will places the first element in {x,3} and
+%% second in {x,4}. The guard for the first clause must make ensure that all of those
+%% registers are restored befor entering the second clause.
+%%
+%% (From mnesia_checkpoint.erl, modified.)
+
+traverse_dcd({Cont,[LogH|Rest]},Log,Fun)
+ when is_tuple(LogH) andalso size(LogH) =:= 6 andalso element(1, LogH) =:= log_header
+andalso erlang:element(2,LogH) == dcd_log,
+is_tuple(LogH) andalso size(LogH) =:= 6 andalso element(1, LogH) =:= log_header
+andalso erlang:element(3,LogH) >= "1.0" ->
+ traverse_dcd({Cont,Rest},Log,Fun);
+traverse_dcd({Cont,Recs},Log,Fun) ->
+ {Cont,Recs,Log,Fun}.
+
+
+check_qlc_hrl(Config) when is_list(Config) ->
+ St = {r1,false,dum},
+ ?line foo = cqlc(qlc, q, [{lc,1,2,3}], St),
+ ?line foo = cqlc(qlc, q, [{lc,1,2,3},b], St),
+ ?line St = cqlc(qlc, q, [], St),
+ ?line St = cqlc(qlc, blurf, [{lc,1,2,3},b], St),
+ ?line St = cqlc(q, q, [{lc,1,2,3},b], St),
+ ?line St = cqlc(qlc, q, [{lc,1,2,3},b,c], St),
+ ?line St = cqlc(qlc, q, [a,b], St),
+ ?line {r1,true,kalle} = cqlc(qlc, q, [{lc,1,2,3},b], {r1,true,kalle}),
+ ok.
+
+%% From erl_lint.erl; original name was check_qlc_hrl/4.
+cqlc(M, F, As, St) ->
+ Arity = length(As),
+ case As of
+ [{lc,_L,_E,_Qs}|_] when M =:= qlc, F =:= q,
+ Arity < 3,
+ not (((element(1, St) =:= r1) orelse fail) and (size(St) =:= 3) and element(2, St)) ->
+ foo;
+ _ ->
+ St
+ end.
+
+
+
+%% Call this function to turn off constant propagation.
+id(I) -> I.
+
+check(F, Result) ->
+ case F() of
+ Result -> ok;
+ Other ->
+ io:format("Expected: ~p\n", [Result]),
+ io:format(" Got: ~p\n", [Other]),
+ test_server:fail()
+ end.
diff --git a/lib/debugger/test/int_SUITE.erl b/lib/debugger/test/int_SUITE.erl
new file mode 100644
index 0000000000..0326325888
--- /dev/null
+++ b/lib/debugger/test/int_SUITE.erl
@@ -0,0 +1,277 @@
+%%
+%% %CopyrightBegin%
+%%
+%% 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%
+%%
+
+%%
+-module(int_SUITE).
+-include("test_server.hrl").
+
+%% Test server specific exports
+-export([all/1]).
+-export([init_per_testcase/2, end_per_testcase/2]).
+
+%% Test cases
+-export([interpret/1, guards/1, list_suite/1, interpretable/1]).
+-export([append/1, append_1/1, append_2/1, member/1, reverse/1]).
+
+%% Default timetrap timeout (set in init_per_testcase)
+-define(default_timeout, ?t:minutes(1)).
+
+init_per_testcase(interpretable, Config) ->
+ ?line Dog=test_server:timetrap(?default_timeout),
+ [{watchdog, Dog}|Config];
+init_per_testcase(_Case, Config) ->
+
+ %% Interpret some existing and non-existing modules
+ ?line DataDir = ?config(data_dir, Config),
+ ?line {module, lists1} = int:i(filename:join([DataDir,lists1])),
+ ?line {module, guards} = int:i(filename:join([DataDir,guards])),
+
+ ?line Dog=test_server:timetrap(?default_timeout),
+ [{watchdog, Dog}|Config].
+
+end_per_testcase(interpretable, Config) ->
+ ?line Dog=?config(watchdog, Config),
+ ?line test_server:timetrap_cancel(Dog),
+ ok;
+end_per_testcase(_Case, Config) ->
+
+ %% Quit interpreting
+ ?line ok = int:n(lists1),
+ ?line ok = int:n(guards),
+
+ ?line Dog=?config(watchdog, Config),
+ ?line test_server:timetrap_cancel(Dog),
+ ?line ok.
+
+all(suite)->
+ [interpret, guards, list_suite, interpretable].
+
+interpret(suite) ->
+ [];
+interpret(doc) ->
+ ["Interpreting modules"];
+interpret(Config) when is_list(Config) ->
+ ?line int:n(int:interpreted()),
+
+ %% Interpret some existing and non-existing modules
+ ?line DataDir = ?config(data_dir, Config),
+ ?line {module, lists1} = int:i(filename:join([DataDir,lists1])),
+ ?line {module, ordsets1} = int:i(filename:join([DataDir,ordsets1])),
+ ?line error = int:i(non_existent_module),
+
+ %% Check that the interpreter has the right view.
+ ?line ExpectedResult = lists:sort([lists1, ordsets1]),
+ ?line Result = int:interpreted(),
+ ?line ExpectedResult = lists:sort(Result),
+
+ %% Uniterpret the modules.
+ ?line ok = int:n(non_existent_module),
+ ?line ok = int:n(lists1),
+ ?line [ordsets1] = int:interpreted(),
+ ?line ok = int:n("ordsets1"),
+ ?line [] = int:interpreted(),
+
+ ok.
+
+guards(suite) ->
+ [];
+guards(doc) ->
+ "Evaluate guards.";
+guards(Config) when is_list(Config) ->
+ ok = guards:guards().
+
+
+list_suite(suite) ->
+ [append, reverse, member].
+
+append(doc) ->
+ ["Tests lists1:append/1 & lists1:append/2"];
+append(suite) ->
+ [append_1, append_2].
+
+append_1(suite) ->
+ [];
+append_1(doc) ->
+ [];
+append_1(Config) when is_list(Config) ->
+ ?line test_server:format("In append_1~n"),
+ ?line test_server:format("code:which(lists1)=~p~n",
+ [code:which(lists1)]),
+ ?line test_server:format("lists1:append([a],[b])=~p~n",
+ [spawn_eval(lists1,append,[[a],[b]])]),
+
+ ?line "abcdef"=spawn_eval(lists1,append,[["abc","def"]]),
+ ?line [hej, du,[glade, [bagare]]]=
+ spawn_eval(lists1,append,[[[hej], [du], [[glade, [bagare]]]]]),
+ ?line [10, [elem]]=spawn_eval(lists1,append,[[[10], [[elem]]]]),
+ ok.
+
+append_2(suite) ->
+ [];
+append_2(doc) ->
+ [];
+append_2(Config) when is_list(Config) ->
+ ?line test_server:format("In append_2~n"),
+ ?line test_server:format("code:which(lists1)=~p~n",
+ [code:which(lists1)]),
+
+ ?line "abcdef"=spawn_eval(lists1,append,["abc", "def"]),
+ ?line [hej, du]=spawn_eval(lists1,append,[[hej], [du]]),
+ ?line [10, [elem]]=spawn_eval(lists1,append,[[10], [[elem]]]),
+ ok.
+
+reverse(suite) ->
+ [];
+reverse(doc) ->
+ [];
+reverse(Config) when is_list(Config) ->
+ ?line ok=reverse_test(0),
+ ?line ok=reverse_test(1),
+ ?line ok=reverse_test(2),
+ ?line ok=reverse_test(537),
+ ok.
+
+reverse_test(0) ->
+ case spawn_eval(lists1,reverse,[[]]) of
+ [] ->
+ ok;
+ _Other ->
+ error
+ end;
+reverse_test(Num) ->
+ List=spawn_eval(lists1,reverse,
+ [['The Element'|lists1:duplicate(Num, 'Ele')]]),
+ case spawn_eval(lists1,reverse,[List]) of
+ ['The Element'|_Rest] ->
+ ok;
+ _Other ->
+ error
+ end.
+
+member(suite) ->
+ [];
+member(doc) ->
+ ["Tests the lists1:member() implementation. The function "
+ "is `non-blocking', and only processes 2000 elements "
+ "at a time.",
+ "This test case depends on lists1:reverse() to work, "
+ "wich is tested in a separate test case."];
+member(Config) when list(Config) ->
+ ?line ok=member_test(0),
+ ?line ok=member_test(1),
+ ?line ok=member_test(100),
+ ?line ok=member_test(537),
+ ok.
+
+member_test(0) ->
+ case spawn_eval(lists1,member,['The Element', []]) of
+ false ->
+ ok;
+ true ->
+ {error, 'Found (!?)'}
+ end;
+member_test(Num) ->
+ List=spawn_eval(lists1,reverse,
+ [['The Element'|spawn_eval(lists1,duplicate,
+ [Num, 'Elem'])]]),
+ case spawn_eval(lists1,member,['The Element', List]) of
+ true ->
+ ok;
+ false ->
+ {error, not_found}
+ end.
+
+spawn_eval(M,F,A) ->
+ Self = self(),
+ spawn(fun() -> evaluator(Self, M,F,A) end),
+ receive
+ Result ->
+ Result
+ end.
+
+evaluator(Pid, M,F,A) ->
+ Pid ! (catch apply(M,F,A)).
+
+interpretable(suite) ->
+ [];
+interpretable(doc) ->
+ ["Test int:interpretable/1"];
+interpretable(Config) when is_list(Config) ->
+
+ %% First make sure that 'lists1' is not loaded
+ case code:is_loaded(lists1) of
+ {file, _Loaded} ->
+ ?line code:purge(lists1),
+ ?line code:delete(lists1),
+ ?line code:purge(lists1);
+ false -> ignore
+ end,
+
+ %% true
+ ?line DataDir = filename:dirname(?config(data_dir, Config)),
+ ?line true = code:add_patha(DataDir),
+ ?line true = int:interpretable(lists1),
+ ?line true = int:interpretable(filename:join([DataDir,lists1])),
+ ?line true = code:del_path(DataDir),
+
+ %% {error, no_src}
+ ?line PrivDir = filename:join(?config(priv_dir, Config), ""),
+ ?line {ok, _} = file:copy(filename:join([DataDir,"lists1.beam"]),
+ filename:join([PrivDir,"lists1.beam"])),
+ ?line true = code:add_patha(PrivDir),
+
+ ?line {error, no_src} = int:interpretable(lists1),
+ ?line ok = file:delete(filename:join([PrivDir,"lists1.beam"])),
+
+ %% {error, no_beam}
+ Src = filename:join([PrivDir,"lists1.erl"]),
+ ?line {ok, _} = file:copy(filename:join([DataDir,"lists1.erl"]),
+ Src),
+ ?line {error, no_beam} = int:interpretable(Src),
+
+ %% {error, no_debug_info}
+ ?line {ok, _} = compile:file(Src, [{outdir,PrivDir}]),
+ ?line {error, no_debug_info} = int:interpretable(Src),
+ ?line {error, no_debug_info} = int:interpretable(lists1),
+ ?line ok = file:delete(Src),
+ ?line true = code:del_path(PrivDir),
+
+ %% {error, badarg}
+ ?line {error, badarg} = int:interpretable(pride),
+ ?line {error, badarg} = int:interpretable("prejudice.erl"),
+
+ %% {error, {app,App}}
+ ?line {error, {app,_}} = int:interpretable(file),
+ ?line {error, {app,_}} = int:interpretable(lists),
+ ?line {error, {app,_}} = int:interpretable(gs),
+ ?line case int:interpretable(dbg_ieval) of
+ {error, {app,_}} ->
+ ok;
+ {error, badarg} ->
+ case code:which(dbg_ieval) of
+ cover_compiled ->
+ ok;
+ Other1 ->
+ ?line ?t:fail({unexpected_result, Other1})
+ end;
+ Other2 ->
+ ?line ?t:fail({unexpected_result, Other2})
+ end,
+
+ ok.
diff --git a/lib/debugger/test/int_SUITE_data/Makefile.src b/lib/debugger/test/int_SUITE_data/Makefile.src
new file mode 100644
index 0000000000..95b96b5d00
--- /dev/null
+++ b/lib/debugger/test/int_SUITE_data/Makefile.src
@@ -0,0 +1,39 @@
+#
+# %CopyrightBegin%
+#
+# Copyright Ericsson AB 2000-2010. All Rights Reserved.
+#
+# The contents of this file are subject to the Erlang Public License,
+# Version 1.1, (the "License"); you may not use this file except in
+# compliance with the License. You should have received a copy of the
+# Erlang Public License along with this software. If not, it can be
+# retrieved online at http://www.erlang.org/.
+#
+# Software distributed under the License is distributed on an "AS IS"
+# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+# the License for the specific language governing rights and limitations
+# under the License.
+#
+# %CopyrightEnd%
+#
+EFLAGS=+debug_info
+all: guards.@EMULATOR@ lists1.@EMULATOR@ my_lists.@EMULATOR@ \
+ ordsets1.@EMULATOR@ test.@EMULATOR@ test1.@EMULATOR@
+
+guards.@EMULATOR@: guards.erl
+ erlc $(EFLAGS) guards.erl
+
+lists1.@EMULATOR@: lists1.erl
+ erlc $(EFLAGS) lists1.erl
+
+my_lists.@EMULATOR@: my_lists.erl
+ erlc $(EFLAGS) my_lists.erl
+
+ordsets1.@EMULATOR@: ordsets1.erl
+ erlc $(EFLAGS) ordsets1.erl
+
+test.@EMULATOR@: test.erl
+ erlc $(EFLAGS) test.erl
+
+test1.@EMULATOR@: test1.erl
+ erlc $(EFLAGS) test1.erl
diff --git a/lib/debugger/test/int_SUITE_data/guards.erl b/lib/debugger/test/int_SUITE_data/guards.erl
new file mode 100644
index 0000000000..c847bb6a8c
--- /dev/null
+++ b/lib/debugger/test/int_SUITE_data/guards.erl
@@ -0,0 +1,108 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 1999-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(guards).
+
+-export([guards/0]).
+
+guards() ->
+ ok = t(),
+ ok = f(),
+ ok = ct(1),
+ ok = multi(1),
+ ok = multi(2),
+ ok = multi(3).
+
+%% The following tests are always true.
+t() when integer(42) ->
+ ok;
+t() when float(2.0) ->
+ ok;
+t() when number(7) ->
+ ok;
+t() when number(3.14) ->
+ ok;
+t() when atom(error) ->
+ ok;
+t() when list([a]) ->
+ ok;
+t() when tuple({}) ->
+ ok;
+t() when tuple({1, 2}) ->
+ ok.
+
+%% The following tests are always false.
+f() when integer(a) ->
+ ok;
+f() when float(b) ->
+ ok;
+f() when number(c) ->
+ ok;
+f() when atom(42) ->
+ ok;
+f() when list(33) ->
+ ok;
+f() when list({}) ->
+ ok;
+f() when list({1, 2}) ->
+ ok;
+f() when tuple(33) ->
+ ok;
+f() when tuple([a]) ->
+ ok;
+f() when tuple([]) ->
+ ok;
+f() when tuple(35) ->
+ ok;
+f() ->
+ ok.
+
+%% The following tests are always true.
+ct(X) ->
+ case X of
+ Y when integer(42) ->
+ ok;
+ Y when float(2.0) ->
+ ok;
+ Y when number(7) ->
+ ok;
+ Y when number(3.14) ->
+ ok;
+ Y when atom(error) ->
+ ok;
+ Y when list([a]) ->
+ ok;
+ Y when tuple({}) ->
+ ok;
+ Y when tuple({1, 2}) ->
+ ok
+ end.
+
+multi(X) ->
+ case X of
+ Y when float(Y) ; integer(Y) ->
+ ok;
+ Y when Y > 1, Y < 10 ; atom(Y) ->
+ ok;
+ Y when Y == 4, number(Y) ; list(Y) ->
+ pannkaka;
+ Y when Y==3 ; Y==5 ; Y==6 ->
+ ok
+ end.
diff --git a/lib/debugger/test/int_SUITE_data/lists1.erl b/lib/debugger/test/int_SUITE_data/lists1.erl
new file mode 100644
index 0000000000..0214983c11
--- /dev/null
+++ b/lib/debugger/test/int_SUITE_data/lists1.erl
@@ -0,0 +1,469 @@
+%%
+%% %CopyrightBegin%
+%%
+%% 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%
+%%
+
+%%
+%% Purpose : Basic lists processing functions.
+
+-module(lists1).
+
+
+-export([member/2, append/2, append/1, subtract/2, reverse/1, reverse/2,
+ nth/2, nthtail/2, prefix/2, suffix/2, last/1,
+ seq/2, seq/3, sum/1, duplicate/2, min/1, max/1, sublist/2, sublist/3,
+ delete/2, sort/1, merge/2, concat/1,
+ flatten/1, flatten/2, flat_length/1, flatlength/1,
+ keymember/3, keysearch/3, keydelete/3, keyreplace/4,
+ keysort/2, keymerge/3, keymap/3, keymap/4]).
+
+-export([all/2,any/2,map/2,flatmap/2,foldl/3,foldr/3,filter/2,zf/2,
+ mapfoldl/3,mapfoldr/3,foreach/2,takewhile/2,dropwhile/2,splitwith/2]).
+-export([all/3,any/3,map/3,flatmap/3,foldl/4,foldr/4,filter/3,zf/3,
+ mapfoldl/4,mapfoldr/4,foreach/3]).
+
+%% member(X, L) -> (true | false)
+%% test if X is a member of the list L
+
+member(X, [X|_]) -> true;
+member(X, [_|Y]) ->
+ member(X, Y);
+member(X, []) -> false.
+
+%% append(X, Y) appends lists X and Y
+
+append(L1, L2) -> L1 ++ L2.
+
+%% append(L) appends the list of lists L
+
+append([E]) -> E;
+append([H|T]) -> H ++ append(T);
+append([]) -> [].
+
+%% subtract(List1, List2) subtract elements in List2 form List1.
+
+subtract(L1, L2) -> L1 -- L2.
+
+%% reverse(L) reverse all elements in the list L
+
+reverse(X) -> reverse(X, []).
+
+reverse([H|T], Y) ->
+ reverse(T, [H|Y]);
+reverse([], X) -> X.
+
+%% nth(N, L) returns the N`th element of the list L
+%% nthtail(N, L) returns the N`th tail of the list L
+
+nth(1, [H|T]) -> H;
+nth(N, [_|T]) when N > 1 ->
+ nth(N - 1, T).
+
+nthtail(1, [H|T]) -> T;
+nthtail(N, [H|T]) when N > 1 ->
+ nthtail(N - 1, T);
+nthtail(0, L) when list(L) -> L.
+
+%% prefix(Prefix, List) -> (true | false)
+
+prefix([X|PreTail], [X|Tail]) ->
+ prefix(PreTail, Tail);
+prefix([], List) -> true;
+prefix(_,_) -> false.
+
+
+%% suffix(Suffix, List) -> (true | false)
+
+suffix(Suffix, Suffix) -> true;
+suffix(Suffix, [_|Tail]) ->
+ suffix(Suffix, Tail);
+suffix(Suffix, []) -> false.
+
+%% last(List) returns the last element in a list.
+
+last([E]) -> E;
+last([E|Es]) ->
+ last(Es).
+
+%% seq(Min, Max) -> [Min,Min+1, ..., Max]
+%% seq(Min, Max, Incr) -> [Min,Min+Incr, ..., Max]
+%% returns the sequence Min..Max
+%% Min <= Max and Min and Max must be integers
+
+seq(Min, Max) when integer(Min), integer(Max), Min =< Max ->
+ seq(Min, Max, 1, []).
+
+seq(Min, Max, Incr) ->
+ seq(Min, Min + ((Max-Min) div Incr) * Incr, Incr, []).
+
+seq(Min, Min, I, L) -> [Min|L];
+seq(Min, Max, I, L) -> seq(Min, Max-I, I, [Max|L]).
+
+%% sum(L) suns the sum of the elements in L
+
+sum(L) -> sum(L, 0).
+sum([H|T], Sum) -> sum(T, Sum + H);
+sum([], Sum) -> Sum.
+
+%% duplicate(N, X) -> [X,X,X,.....,X] (N times)
+%% return N copies of X
+
+duplicate(N, X) when integer(N), N >= 0 -> duplicate(N, X, []).
+
+duplicate(0, _, L) -> L;
+duplicate(N, X, L) -> duplicate(N-1, X, [X|L]).
+
+
+%% min(L) -> returns the minimum element of the list L
+
+min([H|T]) -> min(T, H).
+
+min([H|T], Min) when H < Min -> min(T, H);
+min([_|T], Min) -> min(T, Min);
+min([], Min) -> Min.
+
+%% max(L) -> returns the maximum element of the list L
+
+max([H|T]) -> max(T, H).
+
+max([H|T], Max) when H > Max -> max(T, H);
+max([_|T], Max) -> max(T, Max);
+max([], Max) -> Max.
+
+%% sublist(List, Start, Length)
+%% Returns the sub-list starting at Start of length Length.
+
+sublist(List, S, L) when L >= 0 ->
+ sublist(nthtail(S-1, List), L).
+
+sublist([H|T], L) when L > 0 ->
+ [H|sublist(T, L-1)];
+sublist(List, L) -> [].
+
+%% delete(Item, List) -> List'
+%% Delete the first occurance of Item from the list L.
+
+delete(Item, [Item|Rest]) -> Rest;
+delete(Item, [H|Rest]) ->
+ [H|delete(Item, Rest)];
+delete(Item, []) -> [].
+
+%% sort(L) -> sorts the list L
+
+sort([X]) -> [X];
+sort([]) -> [];
+sort(X) -> split_and_sort(X, [], []).
+
+split_and_sort([A,B|T], X, Y) ->
+ split_and_sort(T, [A|X], [B|Y]);
+split_and_sort([H], X, Y) ->
+ split_and_sort([], [H|X], Y);
+split_and_sort([], X, Y) ->
+ merge(sort(X), sort(Y), []).
+
+%% merge(X, Y) -> L
+%% merges two sorted lists X and Y
+
+merge(X, Y) -> merge(X, Y, []).
+
+merge([H1|T1], [H2|T2], L) when H1 < H2 ->
+ merge(T1, [H2|T2], [H1|L]);
+merge(T1, [H2|T2], L) ->
+ merge(T1, T2, [H2|L]);
+merge([H|T], T2, L) ->
+ merge(T, T2, [H|L]);
+merge([], [], L) ->
+ reverse(L).
+
+%% concat(L) concatinate the list representation of the elements
+%% in L - the elements in L can be atoms, integers of strings.
+%% Returns a list of characters.
+
+concat(List) ->
+ flatmap(fun thing_to_list/1, List).
+
+thing_to_list(X) when integer(X) -> integer_to_list(X);
+thing_to_list(X) when float(X) -> float_to_list(X);
+thing_to_list(X) when atom(X) -> atom_to_list(X);
+thing_to_list(X) when list(X) -> X. %Assumed to be a string
+
+%% flatten(List)
+%% flatten(List, Tail)
+%% Flatten a list, adding optional tail.
+
+flatten(List) ->
+ flatten(List, [], []).
+
+flatten(List, Tail) ->
+ flatten(List, [], Tail).
+
+flatten([H|T], Cont, Tail) when list(H) ->
+ flatten(H, [T|Cont], Tail);
+flatten([H|T], Cont, Tail) ->
+ [H|flatten(T, Cont, Tail)];
+flatten([], [H|Cont], Tail) ->
+ flatten(H, Cont, Tail);
+flatten([], [], Tail) ->
+ Tail.
+
+%% flat_length(List) (undocumented can be rmove later)
+%% Calculate the length of a list of lists.
+
+flat_length(List) -> flatlength(List).
+
+%% flatlength(List)
+%% Calculate the length of a list of lists.
+
+flatlength(List) ->
+ flatlength(List, 0).
+
+flatlength([H|T], L) when list(H) ->
+ flatlength(H, flatlength(T, L));
+flatlength([H|T], L) ->
+ flatlength(T, L + 1);
+flatlength([], L) -> L.
+
+%% keymember(Key, Index, [Tuple])
+%% keysearch(Key, Index, [Tuple])
+%% keydelete(Key, Index, [Tuple])
+%% keyreplace(Key, Index, [Tuple], NewTuple)
+%% keysort(Index, [Tuple])
+%% keymerge(Index, [Tuple], [Tuple])
+%% keymap(Function, Index, [Tuple])
+%% keymap(Function, ExtraArgs, Index, [Tuple])
+
+keymember(Key, N, [T|Ts]) when element(N, T) == Key -> true;
+keymember(Key, N, [T|Ts]) ->
+ keymember(Key, N, Ts);
+keymember(Key, N, []) -> false.
+
+keysearch(Key, N, [H|T]) when element(N, H) == Key ->
+ {value, H};
+keysearch(Key, N, [H|T]) ->
+ keysearch(Key, N, T);
+keysearch(Key, N, []) -> false.
+
+keydelete(Key, N, [H|T]) when element(N, H) == Key -> T;
+keydelete(Key, N, [H|T]) ->
+ [H|keydelete(Key, N, T)];
+keydelete(Key, N, []) -> [].
+
+keyreplace(Key, Pos, [Tup|Tail], New) when element(Pos, Tup) == Key ->
+ [New|Tail];
+keyreplace(Key, Pos, [H|T], New) ->
+ [H|keyreplace(Key, Pos, T, New)];
+keyreplace(Key, Pos, [], New) -> [].
+
+keysort(Index, [X]) -> [X];
+keysort(Index, []) -> [];
+keysort(Index, X) -> split_and_keysort(X, [], [], Index).
+
+split_and_keysort([A,B|T], X, Y, Index) ->
+ split_and_keysort(T, [A|X], [B|Y], Index);
+split_and_keysort([H], X, Y, Index) ->
+ split_and_keysort([], [H|X], Y, Index);
+split_and_keysort([], X, Y, Index) ->
+ keymerge(Index, keysort(Index, X), keysort(Index, Y), []).
+
+keymerge(Index, X, Y) -> keymerge(Index, X, Y, []).
+
+keymerge(I, [H1|T1], [H2|T2], L) when element(I, H1) < element(I, H2) ->
+ keymerge(I, T1, [H2|T2], [H1|L]);
+keymerge(Index, T1, [H2|T2], L) ->
+ keymerge(Index,T1, T2, [H2|L]);
+keymerge(Index,[H|T], T2, L) ->
+ keymerge(Index,T, T2, [H|L]);
+keymerge(Index, [], [], L) ->
+ reverse(L).
+
+keymap(Fun, Index, [Tup|Tail]) ->
+ [setelement(Index, Tup, Fun(element(Index, Tup)))|keymap(Fun, Index, Tail)];
+keymap( _, _ , []) -> [].
+
+keymap(Fun, ExtraArgs, Index, [Tup|Tail]) ->
+ [setelement(Index, Tup, apply(Fun, [element(Index, Tup)|ExtraArgs]))|
+ keymap(Fun, ExtraArgs, Index, Tail)];
+keymap( _, _ , _, []) -> [].
+
+%% all(Predicate, List)
+%% any(Predicate, List)
+%% map(Function, List)
+%% flatmap(Function, List)
+%% foldl(Function, First, List)
+%% foldr(Function, Last, List)
+%% filter(Predicate, List)
+%% zf(Function, List)
+%% mapfoldl(Function, First, List)
+%% mapfoldr(Function, Last, List)
+%% foreach(Function, List)
+%% takewhile(Predicate, List)
+%% dropwhile(Predicate, List)
+%% splitwith(Predicate, List)
+%% for list programming. Function here is either a 'fun' or a tuple
+%% {Module,Name} and we use apply/2 to evaluate. The name zf is a joke!
+%%
+%% N.B. Unless where the functions actually needs it only foreach/2/3,
+%% which is meant to be used for its side effects, has a defined order
+%% of evaluation.
+%%
+%% There are also versions with an extra argument, ExtraArgs, which is a
+%% list of extra arguments to each call.
+
+all(Pred, [Hd|Tail]) ->
+ case Pred(Hd) of
+ true -> all(Pred, Tail);
+ false -> false
+ end;
+all(Pred, []) -> true.
+
+any(Pred, [Hd|Tail]) ->
+ case Pred(Hd) of
+ true -> true;
+ false -> any(Pred, Tail)
+ end;
+any(Pred, []) -> false.
+
+map(F, List) -> [ F(E) || E <- List ].
+
+flatmap(F, [Hd|Tail]) ->
+ F(Hd) ++ flatmap(F, Tail);
+flatmap(F, []) -> [].
+
+foldl(F, Accu, [Hd|Tail]) ->
+ foldl(F, F(Hd, Accu), Tail);
+foldl(F, Accu, []) -> Accu.
+
+foldr(F, Accu, [Hd|Tail]) ->
+ F(Hd, foldr(F, Accu, Tail));
+foldr(F, Accu, []) -> Accu.
+
+filter(Pred, List) -> [ E || E <- List, Pred(E) ].
+
+zf(F, [Hd|Tail]) ->
+ case F(Hd) of
+ true ->
+ [Hd|zf(F, Tail)];
+ {true,Val} ->
+ [Val|zf(F, Tail)];
+ false ->
+ zf(F, Tail)
+ end;
+zf(F, []) -> [].
+
+foreach(F, [Hd|Tail]) ->
+ F(Hd),
+ foreach(F, Tail);
+foreach(F, []) -> ok.
+
+mapfoldl(F, Accu0, [Hd|Tail]) ->
+ {R,Accu1} = F(Hd, Accu0),
+ {Rs,Accu2} = mapfoldl(F, Accu1, Tail),
+ {[R|Rs],Accu2};
+mapfoldl(F, Accu, []) -> {[],Accu}.
+
+mapfoldr(F, Accu0, [Hd|Tail]) ->
+ {Rs,Accu1} = mapfoldr(F, Accu0, Tail),
+ {R,Accu2} = F(Hd, Accu1),
+ {[R|Rs],Accu2};
+mapfoldr(F, Accu, []) -> {[],Accu}.
+
+takewhile(Pred, [Hd|Tail]) ->
+ case Pred(Hd) of
+ true -> [Hd|takewhile(Pred, Tail)];
+ false -> []
+ end;
+takewhile(Pred, []) -> [].
+
+dropwhile(Pred, [Hd|Tail]) ->
+ case Pred(Hd) of
+ true -> dropwhile(Pred, Tail);
+ false -> [Hd|Tail]
+ end;
+dropwhile(Pred, []) -> [].
+
+splitwith(Pred, List) -> splitwith(Pred, List, []).
+
+splitwith(Pred, [Hd|Tail], Taken) ->
+ case Pred(Hd) of
+ true -> splitwith(Pred, Tail, [Hd|Taken]);
+ false -> {reverse(Taken), [Hd|Tail]}
+ end;
+splitwith(Pred, [], Taken) -> {reverse(Taken),[]}.
+
+%% Versions of the above functions with extra arguments.
+
+all(Pred, Eas, [Hd|Tail]) ->
+ case apply(Pred, [Hd|Eas]) of
+ true -> all(Pred, Eas, Tail);
+ false -> false
+ end;
+all(Pred, Eas, []) -> true.
+
+any(Pred, Eas, [Hd|Tail]) ->
+ case apply(Pred, [Hd|Eas]) of
+ true -> true;
+ false -> any(Pred, Eas, Tail)
+ end;
+any(Pred, Eas, []) -> false.
+
+map(F, Eas, List) -> [ apply(F, [E|Eas]) || E <- List ].
+
+flatmap(F, Eas, [Hd|Tail]) ->
+ apply(F, [Hd|Eas]) ++ flatmap(F, Eas, Tail);
+flatmap(F, Eas, []) -> [].
+
+foldl(F, Eas, Accu, [Hd|Tail]) ->
+ foldl(F, Eas, apply(F, [Hd,Accu|Eas]), Tail);
+foldl(F, Eas, Accu, []) -> Accu.
+
+foldr(F, Eas, Accu, [Hd|Tail]) ->
+ apply(F, [Hd,foldr(F, Eas, Accu, Tail)|Eas]);
+foldr(F, Eas, Accu, []) ->
+ Accu.
+
+filter(Pred, Eas, List) -> [ E || E <- List, apply(Pred, [E|Eas]) ].
+
+zf(F, Eas, [Hd|Tail]) ->
+ case apply(F, [Hd|Eas]) of
+ true ->
+ [Hd|zf(F, Eas, Tail)];
+ {true,Val} ->
+ [Val|zf(F, Eas, Tail)];
+ false ->
+ zf(F, Eas, Tail)
+ end;
+zf(F, Eas, []) -> [].
+
+foreach(F, Eas, [Hd|Tail]) ->
+ apply(F, [Hd|Eas]),
+ foreach(F, Eas, Tail);
+foreach(F, Eas, []) -> ok.
+
+mapfoldl(F, Eas, Accu0, [Hd|Tail]) ->
+ {R,Accu1} = apply(F, [Hd,Accu0|Eas]),
+ {Rs,Accu2} = mapfoldl(F, Eas, Accu1, Tail),
+ {[R|Rs],Accu2};
+mapfoldl(F, Eas, Accu, []) -> {[],Accu}.
+
+mapfoldr(F, Eas, Accu0, [Hd|Tail]) ->
+ {Rs,Accu1} = mapfoldr(F, Eas, Accu0, Tail),
+ {R,Accu2} = apply(F, [Hd,Accu1|Eas]),
+ {[R|Rs],Accu2};
+mapfoldr(F, Eas, Accu, []) -> {[],Accu}.
+
+%% takewhile/2, dropwhile/2 and splitwith/2 do not have versions with
+%% extra arguments as this going to be discontinued.
diff --git a/lib/debugger/test/int_SUITE_data/my_lists.erl b/lib/debugger/test/int_SUITE_data/my_lists.erl
new file mode 100644
index 0000000000..98eb4396e3
--- /dev/null
+++ b/lib/debugger/test/int_SUITE_data/my_lists.erl
@@ -0,0 +1,5681 @@
+%%
+%% %CopyrightBegin%
+%%
+%% 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%
+%%
+
+%%
+%%% A rather large file to test the attach delay.
+%%% Use only the ordinary lists commands.
+
+-module(my_lists).
+
+
+-export([member/2, append/2, append/1, subtract/2, reverse/1, reverse/2,
+ nth/2, nthtail/2, prefix/2, suffix/2, last/1,
+ seq/2, seq/3, sum/1, duplicate/2, min/1, max/1, sublist/2, sublist/3,
+ delete/2, sort/1, merge/2, concat/1,
+ flatten/1, flatten/2, flat_length/1, flatlength/1,
+ keymember/3, keysearch/3, keydelete/3, keyreplace/4,
+ keysort/2, keymerge/3, keymap/3, keymap/4]).
+
+-export([all/2,any/2,map/2,flatmap/2,foldl/3,foldr/3,filter/2,zf/2,
+ mapfoldl/3,mapfoldr/3,foreach/2,takewhile/2,dropwhile/2,splitwith/2]).
+-export([all/3,any/3,map/3,flatmap/3,foldl/4,foldr/4,filter/3,zf/3,
+ mapfoldl/4,mapfoldr/4,foreach/3]).
+
+%% member(X, L) -> (true | false)
+%% test if X is a member of the list L
+
+member(X, [X|_]) -> true;
+member(X, [_|Y]) ->
+ member(X, Y);
+member(X, []) -> false.
+
+%% append(X, Y) appends lists X and Y
+
+append(L1, L2) -> L1 ++ L2.
+
+%% append(L) appends the list of lists L
+
+append([E]) -> E;
+append([H|T]) -> H ++ append(T);
+append([]) -> [].
+
+%% subtract(List1, List2) subtract elements in List2 form List1.
+
+subtract(L1, L2) -> L1 -- L2.
+
+%% reverse(L) reverse all elements in the list L
+
+reverse(X) -> reverse(X, []).
+
+reverse([H|T], Y) ->
+ reverse(T, [H|Y]);
+reverse([], X) -> X.
+
+%% nth(N, L) returns the N`th element of the list L
+%% nthtail(N, L) returns the N`th tail of the list L
+
+nth(1, [H|T]) -> H;
+nth(N, [_|T]) when N > 1 ->
+ nth(N - 1, T).
+
+nthtail(1, [H|T]) -> T;
+nthtail(N, [H|T]) when N > 1 ->
+ nthtail(N - 1, T);
+nthtail(0, L) when list(L) -> L.
+
+%% prefix(Prefix, List) -> (true | false)
+
+prefix([X|PreTail], [X|Tail]) ->
+ prefix(PreTail, Tail);
+prefix([], List) -> true;
+prefix(_,_) -> false.
+
+
+%% suffix(Suffix, List) -> (true | false)
+
+suffix(Suffix, Suffix) -> true;
+suffix(Suffix, [_|Tail]) ->
+ suffix(Suffix, Tail);
+suffix(Suffix, []) -> false.
+
+%% last(List) returns the last element in a list.
+
+last([E]) -> E;
+last([E|Es]) ->
+ last(Es).
+
+%% seq(Min, Max) -> [Min,Min+1, ..., Max]
+%% seq(Min, Max, Incr) -> [Min,Min+Incr, ..., Max]
+%% returns the sequence Min..Max
+%% Min <= Max and Min and Max must be integers
+
+seq(Min, Max) when integer(Min), integer(Max), Min =< Max ->
+ seq(Min, Max, 1, []).
+
+seq(Min, Max, Incr) ->
+ seq(Min, Min + ((Max-Min) div Incr) * Incr, Incr, []).
+
+seq(Min, Min, I, L) -> [Min|L];
+seq(Min, Max, I, L) -> seq(Min, Max-I, I, [Max|L]).
+
+%% sum(L) suns the sum of the elements in L
+
+sum(L) -> sum(L, 0).
+sum([H|T], Sum) -> sum(T, Sum + H);
+sum([], Sum) -> Sum.
+
+%% duplicate(N, X) -> [X,X,X,.....,X] (N times)
+%% return N copies of X
+
+duplicate(N, X) when integer(N), N >= 0 -> duplicate(N, X, []).
+
+duplicate(0, _, L) -> L;
+duplicate(N, X, L) -> duplicate(N-1, X, [X|L]).
+
+
+%% min(L) -> returns the minimum element of the list L
+
+min([H|T]) -> min(T, H).
+
+min([H|T], Min) when H < Min -> min(T, H);
+min([_|T], Min) -> min(T, Min);
+min([], Min) -> Min.
+
+%% max(L) -> returns the maximum element of the list L
+
+max([H|T]) -> max(T, H).
+
+max([H|T], Max) when H > Max -> max(T, H);
+max([_|T], Max) -> max(T, Max);
+max([], Max) -> Max.
+
+%% sublist(List, Start, Length)
+%% Returns the sub-list starting at Start of length Length.
+
+sublist(List, S, L) when L >= 0 ->
+ sublist(nthtail(S-1, List), L).
+
+sublist([H|T], L) when L > 0 ->
+ [H|sublist(T, L-1)];
+sublist(List, L) -> [].
+
+%% delete(Item, List) -> List'
+%% Delete the first occurance of Item from the list L.
+
+delete(Item, [Item|Rest]) -> Rest;
+delete(Item, [H|Rest]) ->
+ [H|delete(Item, Rest)];
+delete(Item, []) -> [].
+
+%% sort(L) -> sorts the list L
+
+sort([X]) -> [X];
+sort([]) -> [];
+sort(X) -> split_and_sort(X, [], []).
+
+split_and_sort([A,B|T], X, Y) ->
+ split_and_sort(T, [A|X], [B|Y]);
+split_and_sort([H], X, Y) ->
+ split_and_sort([], [H|X], Y);
+split_and_sort([], X, Y) ->
+ merge(sort(X), sort(Y), []).
+
+%% merge(X, Y) -> L
+%% merges two sorted lists X and Y
+
+merge(X, Y) -> merge(X, Y, []).
+
+merge([H1|T1], [H2|T2], L) when H1 < H2 ->
+ merge(T1, [H2|T2], [H1|L]);
+merge(T1, [H2|T2], L) ->
+ merge(T1, T2, [H2|L]);
+merge([H|T], T2, L) ->
+ merge(T, T2, [H|L]);
+merge([], [], L) ->
+ reverse(L).
+
+%% concat(L) concatinate the list representation of the elements
+%% in L - the elements in L can be atoms, integers of strings.
+%% Returns a list of characters.
+
+concat(List) ->
+ flatmap(fun thing_to_list/1, List).
+
+thing_to_list(X) when integer(X) -> integer_to_list(X);
+thing_to_list(X) when float(X) -> float_to_list(X);
+thing_to_list(X) when atom(X) -> atom_to_list(X);
+thing_to_list(X) when list(X) -> X. %Assumed to be a string
+
+%% flatten(List)
+%% flatten(List, Tail)
+%% Flatten a list, adding optional tail.
+
+flatten(List) ->
+ flatten(List, [], []).
+
+flatten(List, Tail) ->
+ flatten(List, [], Tail).
+
+flatten([H|T], Cont, Tail) when list(H) ->
+ flatten(H, [T|Cont], Tail);
+flatten([H|T], Cont, Tail) ->
+ [H|flatten(T, Cont, Tail)];
+flatten([], [H|Cont], Tail) ->
+ flatten(H, Cont, Tail);
+flatten([], [], Tail) ->
+ Tail.
+
+%% flat_length(List) (undocumented can be rmove later)
+%% Calculate the length of a list of lists.
+
+flat_length(List) -> flatlength(List).
+
+%% flatlength(List)
+%% Calculate the length of a list of lists.
+
+flatlength(List) ->
+ flatlength(List, 0).
+
+flatlength([H|T], L) when list(H) ->
+ flatlength(H, flatlength(T, L));
+flatlength([H|T], L) ->
+ flatlength(T, L + 1);
+flatlength([], L) -> L.
+
+%% keymember(Key, Index, [Tuple])
+%% keysearch(Key, Index, [Tuple])
+%% keydelete(Key, Index, [Tuple])
+%% keyreplace(Key, Index, [Tuple], NewTuple)
+%% keysort(Index, [Tuple])
+%% keymerge(Index, [Tuple], [Tuple])
+%% keymap(Function, Index, [Tuple])
+%% keymap(Function, ExtraArgs, Index, [Tuple])
+
+keymember(Key, N, [T|Ts]) when element(N, T) == Key -> true;
+keymember(Key, N, [T|Ts]) ->
+ keymember(Key, N, Ts);
+keymember(Key, N, []) -> false.
+
+keysearch(Key, N, [H|T]) when element(N, H) == Key ->
+ {value, H};
+keysearch(Key, N, [H|T]) ->
+ keysearch(Key, N, T);
+keysearch(Key, N, []) -> false.
+
+keydelete(Key, N, [H|T]) when element(N, H) == Key -> T;
+keydelete(Key, N, [H|T]) ->
+ [H|keydelete(Key, N, T)];
+keydelete(Key, N, []) -> [].
+
+keyreplace(Key, Pos, [Tup|Tail], New) when element(Pos, Tup) == Key ->
+ [New|Tail];
+keyreplace(Key, Pos, [H|T], New) ->
+ [H|keyreplace(Key, Pos, T, New)];
+keyreplace(Key, Pos, [], New) -> [].
+
+keysort(Index, [X]) -> [X];
+keysort(Index, []) -> [];
+keysort(Index, X) -> split_and_keysort(X, [], [], Index).
+
+split_and_keysort([A,B|T], X, Y, Index) ->
+ split_and_keysort(T, [A|X], [B|Y], Index);
+split_and_keysort([H], X, Y, Index) ->
+ split_and_keysort([], [H|X], Y, Index);
+split_and_keysort([], X, Y, Index) ->
+ keymerge(Index, keysort(Index, X), keysort(Index, Y), []).
+
+keymerge(Index, X, Y) -> keymerge(Index, X, Y, []).
+
+keymerge(I, [H1|T1], [H2|T2], L) when element(I, H1) < element(I, H2) ->
+ keymerge(I, T1, [H2|T2], [H1|L]);
+keymerge(Index, T1, [H2|T2], L) ->
+ keymerge(Index,T1, T2, [H2|L]);
+keymerge(Index,[H|T], T2, L) ->
+ keymerge(Index,T, T2, [H|L]);
+keymerge(Index, [], [], L) ->
+ reverse(L).
+
+keymap(Fun, Index, [Tup|Tail]) ->
+ [setelement(Index, Tup, Fun(element(Index, Tup)))|keymap(Fun, Index, Tail)];
+keymap( _, _ , []) -> [].
+
+keymap(Fun, ExtraArgs, Index, [Tup|Tail]) ->
+ [setelement(Index, Tup, apply(Fun, [element(Index, Tup)|ExtraArgs]))|
+ keymap(Fun, ExtraArgs, Index, Tail)];
+keymap( _, _ , _, []) -> [].
+
+%% all(Predicate, List)
+%% any(Predicate, List)
+%% map(Function, List)
+%% flatmap(Function, List)
+%% foldl(Function, First, List)
+%% foldr(Function, Last, List)
+%% filter(Predicate, List)
+%% zf(Function, List)
+%% mapfoldl(Function, First, List)
+%% mapfoldr(Function, Last, List)
+%% foreach(Function, List)
+%% takewhile(Predicate, List)
+%% dropwhile(Predicate, List)
+%% splitwith(Predicate, List)
+%% for list programming. Function here is either a 'fun' or a tuple
+%% {Module,Name} and we use apply/2 to evaluate. The name zf is a joke!
+%%
+%% N.B. Unless where the functions actually needs it only foreach/2/3,
+%% which is meant to be used for its side effects, has a defined order
+%% of evaluation.
+%%
+%% There are also versions with an extra argument, ExtraArgs, which is a
+%% list of extra arguments to each call.
+
+all(Pred, [Hd|Tail]) ->
+ case Pred(Hd) of
+ true -> all(Pred, Tail);
+ false -> false
+ end;
+all(Pred, []) -> true.
+
+any(Pred, [Hd|Tail]) ->
+ case Pred(Hd) of
+ true -> true;
+ false -> any(Pred, Tail)
+ end;
+any(Pred, []) -> false.
+
+map(F, List) -> [ F(E) || E <- List ].
+
+flatmap(F, [Hd|Tail]) ->
+ F(Hd) ++ flatmap(F, Tail);
+flatmap(F, []) -> [].
+
+foldl(F, Accu, [Hd|Tail]) ->
+ foldl(F, F(Hd, Accu), Tail);
+foldl(F, Accu, []) -> Accu.
+
+foldr(F, Accu, [Hd|Tail]) ->
+ F(Hd, foldr(F, Accu, Tail));
+foldr(F, Accu, []) -> Accu.
+
+filter(Pred, List) -> [ E || E <- List, Pred(E) ].
+
+zf(F, [Hd|Tail]) ->
+ case F(Hd) of
+ true ->
+ [Hd|zf(F, Tail)];
+ {true,Val} ->
+ [Val|zf(F, Tail)];
+ false ->
+ zf(F, Tail)
+ end;
+zf(F, []) -> [].
+
+foreach(F, [Hd|Tail]) ->
+ F(Hd),
+ foreach(F, Tail);
+foreach(F, []) -> ok.
+
+mapfoldl(F, Accu0, [Hd|Tail]) ->
+ {R,Accu1} = F(Hd, Accu0),
+ {Rs,Accu2} = mapfoldl(F, Accu1, Tail),
+ {[R|Rs],Accu2};
+mapfoldl(F, Accu, []) -> {[],Accu}.
+
+mapfoldr(F, Accu0, [Hd|Tail]) ->
+ {Rs,Accu1} = mapfoldr(F, Accu0, Tail),
+ {R,Accu2} = F(Hd, Accu1),
+ {[R|Rs],Accu2};
+mapfoldr(F, Accu, []) -> {[],Accu}.
+
+takewhile(Pred, [Hd|Tail]) ->
+ case Pred(Hd) of
+ true -> [Hd|takewhile(Pred, Tail)];
+ false -> []
+ end;
+takewhile(Pred, []) -> [].
+
+dropwhile(Pred, [Hd|Tail]) ->
+ case Pred(Hd) of
+ true -> dropwhile(Pred, Tail);
+ false -> [Hd|Tail]
+ end;
+dropwhile(Pred, []) -> [].
+
+splitwith(Pred, List) -> splitwith(Pred, List, []).
+
+splitwith(Pred, [Hd|Tail], Taken) ->
+ case Pred(Hd) of
+ true -> splitwith(Pred, Tail, [Hd|Taken]);
+ false -> {reverse(Taken), [Hd|Tail]}
+ end;
+splitwith(Pred, [], Taken) -> {reverse(Taken),[]}.
+
+%% Versions of the above functions with extra arguments.
+
+all(Pred, Eas, [Hd|Tail]) ->
+ case apply(Pred, [Hd|Eas]) of
+ true -> all(Pred, Eas, Tail);
+ false -> false
+ end;
+all(Pred, Eas, []) -> true.
+
+any(Pred, Eas, [Hd|Tail]) ->
+ case apply(Pred, [Hd|Eas]) of
+ true -> true;
+ false -> any(Pred, Eas, Tail)
+ end;
+any(Pred, Eas, []) -> false.
+
+map(F, Eas, List) -> [ apply(F, [E|Eas]) || E <- List ].
+
+flatmap(F, Eas, [Hd|Tail]) ->
+ apply(F, [Hd|Eas]) ++ flatmap(F, Eas, Tail);
+flatmap(F, Eas, []) -> [].
+
+foldl(F, Eas, Accu, [Hd|Tail]) ->
+ foldl(F, Eas, apply(F, [Hd,Accu|Eas]), Tail);
+foldl(F, Eas, Accu, []) -> Accu.
+
+foldr(F, Eas, Accu, [Hd|Tail]) ->
+ apply(F, [Hd,foldr(F, Eas, Accu, Tail)|Eas]);
+foldr(F, Eas, Accu, []) ->
+ Accu.
+
+filter(Pred, Eas, List) -> [ E || E <- List, apply(Pred, [E|Eas]) ].
+
+zf(F, Eas, [Hd|Tail]) ->
+ case apply(F, [Hd|Eas]) of
+ true ->
+ [Hd|zf(F, Eas, Tail)];
+ {true,Val} ->
+ [Val|zf(F, Eas, Tail)];
+ false ->
+ zf(F, Eas, Tail)
+ end;
+zf(F, Eas, []) -> [].
+
+foreach(F, Eas, [Hd|Tail]) ->
+ apply(F, [Hd|Eas]),
+ foreach(F, Eas, Tail);
+foreach(F, Eas, []) -> ok.
+
+mapfoldl(F, Eas, Accu0, [Hd|Tail]) ->
+ {R,Accu1} = apply(F, [Hd,Accu0|Eas]),
+ {Rs,Accu2} = mapfoldl(F, Eas, Accu1, Tail),
+ {[R|Rs],Accu2};
+mapfoldl(F, Eas, Accu, []) -> {[],Accu}.
+
+mapfoldr(F, Eas, Accu0, [Hd|Tail]) ->
+ {Rs,Accu1} = mapfoldr(F, Eas, Accu0, Tail),
+ {R,Accu2} = apply(F, [Hd,Accu1|Eas]),
+ {[R|Rs],Accu2};
+mapfoldr(F, Eas, Accu, []) -> {[],Accu}.
+
+%% takewhile/2, dropwhile/2 and splitwith/2 do not have versions with
+%% extra arguments as this going to be discontinued.
+
+
+
+
+
+%%% +++++++++++++++++++++++++++++++++++++++
+%%%
+%%% Same as above but with "_1" added to the function names
+%%%
+
+
+%% member_1(X, L) -> (true | false)
+%% test if X is a member of the list L
+
+%member_1(X, [X|_]) -> true;
+%member_1(X, [_|Y]) ->
+% member_1(X, Y);
+%member_1(X, []) -> false.
+
+member_1(X, L) when list(L) ->
+ case erlang:member_1(X, L) of
+ L1 when list(L1) ->
+ receive after 1 -> ok end,
+ member_1(X, L1);
+ Boolean ->
+ Boolean
+ end.
+
+%% append_1(X, Y) appends lists X and Y
+
+append_1(L1, L2) -> L1 ++ L2.
+
+%% append_1(L) appends the list of lists L
+
+append_1([E]) -> E;
+append_1([H|T]) -> H ++ append_1(T);
+append_1([]) -> [].
+
+%% subtract_1(List1, List2) subtract elements in List2 form List1.
+
+subtract_1(L1, L2) -> L1 -- L2.
+
+%% reverse_1(L) reverse all elements in the list L
+
+reverse_1(X) -> reverse_1(X, []).
+
+%reverse_1([H|T], Y) ->
+% reverse_1(T, [H|Y]);
+%reverse_1([], X) -> X.
+
+reverse_1(List0, Result0) when list(List0) ->
+ case erlang:reverse_1(List0, Result0) of
+ {List, Result} ->
+ receive after 1 -> ok end,
+ reverse_1(List, Result);
+ Result ->
+ Result
+ end.
+
+
+%% nth_1(N, L) returns the N`th element of the list L
+%% nthtail_1(N, L) returns the N`th tail of the list L
+
+nth_1(1, [H|T]) -> H;
+nth_1(N, [_|T]) when N > 1 ->
+ nth_1(N - 1, T).
+
+nthtail_1(1, [H|T]) -> T;
+nthtail_1(N, [H|T]) when N > 1 ->
+ nthtail_1(N - 1, T);
+nthtail_1(0, L) when list(L) -> L.
+
+%% prefix_1(Prefix, List) -> (true | false)
+
+prefix_1([X|PreTail], [X|Tail]) ->
+ prefix_1(PreTail, Tail);
+prefix_1([], List) -> true;
+prefix_1(_,_) -> false.
+
+
+%% suffix_1(Suffix, List) -> (true | false)
+
+suffix_1(Suffix, Suffix) -> true;
+suffix_1(Suffix, [_|Tail]) ->
+ suffix_1(Suffix, Tail);
+suffix_1(Suffix, []) -> false.
+
+%% last(List) returns the last element in a list.
+
+last_1([E]) -> E;
+last_1([E|Es]) ->
+ last_1(Es).
+
+%% seq(Min, Max) -> [Min,Min+1, ..., Max]
+%% seq(Min, Max, Incr) -> [Min,Min+Incr, ..., Max]
+%% returns the sequence Min..Max
+%% Min <= Max and Min and Max must be integers
+
+seq_1(Min, Max) when integer(Min), integer(Max), Min =< Max ->
+ seq_1(Min, Max, 1, []).
+
+seq_1(Min, Max, Incr) ->
+ seq_1(Min, Min + ((Max-Min) div Incr) * Incr, Incr, []).
+
+seq_1(Min, Min, I, L) -> [Min|L];
+seq_1(Min, Max, I, L) -> seq_1(Min, Max-I, I, [Max|L]).
+
+%% sum(L) suns the sum of the elements in L
+
+sum_1(L) -> sum_1(L, 0).
+sum_1([H|T], Sum) -> sum_1(T, Sum + H);
+sum_1([], Sum) -> Sum.
+
+%% duplicate(N, X) -> [X,X,X,.....,X] (N times)
+%% return N copies of X
+
+duplicate_1(N, X) when integer(N), N >= 0 -> duplicate_1(N, X, []).
+
+duplicate_1(0, _, L) -> L;
+duplicate_1(N, X, L) -> duplicate_1(N-1, X, [X|L]).
+
+
+%% min(L) -> returns the minimum element of the list L
+
+min_1([H|T]) -> min_1(T, H).
+
+min_1([H|T], Min) when H < Min -> min_1(T, H);
+min_1([_|T], Min) -> min_1(T, Min);
+min_1([], Min) -> Min.
+
+%% max(L) -> returns the maximum element of the list L
+
+max_1([H|T]) -> max_1(T, H).
+
+max_1([H|T], Max) when H > Max -> max_1(T, H);
+max_1([_|T], Max) -> max_1(T, Max);
+max_1([], Max) -> Max.
+
+%% sublist(List, Start, Length)
+%% Returns the sub-list starting at Start of length Length.
+
+sublist_1(List, S, L) when L >= 0 ->
+ sublist_1(nthtail_1(S-1, List), L).
+
+sublist_1([H|T], L) when L > 0 ->
+ [H|sublist_1(T, L-1)];
+sublist_1(List, L) -> [].
+
+%% delete(Item, List) -> List'
+%% Delete the first occurance of Item from the list L.
+
+delete_1(Item, [Item|Rest]) -> Rest;
+delete_1(Item, [H|Rest]) ->
+ [H|delete_1(Item, Rest)];
+delete_1(Item, []) -> [].
+
+%% sort(L) -> sorts the list L
+
+sort_1([X]) -> [X];
+sort_1([]) -> [];
+sort_1(X) -> split_and_sort_1(X, [], []).
+
+split_and_sort_1([A,B|T], X, Y) ->
+ split_and_sort_1(T, [A|X], [B|Y]);
+split_and_sort_1([H], X, Y) ->
+ split_and_sort_1([], [H|X], Y);
+split_and_sort_1([], X, Y) ->
+ merge_1(sort_1(X), sort_1(Y), []).
+
+%% merge(X, Y) -> L
+%% merges two sorted lists X and Y
+
+merge_1(X, Y) -> merge_1(X, Y, []).
+
+merge_1([H1|T1], [H2|T2], L) when H1 < H2 ->
+ merge_1(T1, [H2|T2], [H1|L]);
+merge_1(T1, [H2|T2], L) ->
+ merge_1(T1, T2, [H2|L]);
+merge_1([H|T], T2, L) ->
+ merge_1(T, T2, [H|L]);
+merge_1([], [], L) ->
+ reverse_1(L).
+
+%% concat(L) concatinate the list representation of the elements
+%% in L - the elements in L can be atoms, integers of strings.
+%% Returns a list of characters.
+
+concat_1(List) ->
+ flatmap_1(fun thing_to_list/1, List).
+
+thing_to_list_1(X) when integer(X) -> integer_to_list(X);
+thing_to_list_1(X) when float(X) -> float_to_list(X);
+thing_to_list_1(X) when atom(X) -> atom_to_list(X);
+thing_to_list_1(X) when list(X) -> X. %Assumed to be a string
+
+%% flatten(List)
+%% flatten(List, Tail)
+%% Flatten a list, adding optional tail.
+
+flatten_1(List) ->
+ flatten_1(List, [], []).
+
+flatten_1(List, Tail) ->
+ flatten_1(List, [], Tail).
+
+flatten_1([H|T], Cont, Tail) when list(H) ->
+ flatten_1(H, [T|Cont], Tail);
+flatten_1([H|T], Cont, Tail) ->
+ [H|flatten_1(T, Cont, Tail)];
+flatten_1([], [H|Cont], Tail) ->
+ flatten_1(H, Cont, Tail);
+flatten_1([], [], Tail) ->
+ Tail.
+
+%% flat_length(List) (undocumented can be rmove later)
+%% Calculate the length of a list of lists.
+
+flat_length_1(List) -> flatlength_1(List).
+
+%% flatlength(List)
+%% Calculate the length of a list of lists.
+
+flatlength_1(List) ->
+ flatlength_1(List, 0).
+
+flatlength_1([H|T], L) when list(H) ->
+ flatlength_1(H, flatlength_1(T, L));
+flatlength_1([H|T], L) ->
+ flatlength_1(T, L + 1);
+flatlength_1([], L) -> L.
+
+%% keymember(Key, Index, [Tuple])
+%% keysearch(Key, Index, [Tuple])
+%% keydelete(Key, Index, [Tuple])
+%% keyreplace(Key, Index, [Tuple], NewTuple)
+%% keysort(Index, [Tuple])
+%% keymerge(Index, [Tuple], [Tuple])
+%% keymap(Function, Index, [Tuple])
+%% keymap(Function, ExtraArgs, Index, [Tuple])
+
+keymember_1(Key, N, [T|Ts]) when element(N, T) == Key -> true;
+keymember_1(Key, N, [T|Ts]) ->
+ keymember_1(Key, N, Ts);
+keymember_1(Key, N, []) -> false.
+
+keysearch_1(Key, N, [H|T]) when element(N, H) == Key ->
+ {value, H};
+keysearch_1(Key, N, [H|T]) ->
+ keysearch_1(Key, N, T);
+keysearch_1(Key, N, []) -> false.
+
+keydelete_1(Key, N, [H|T]) when element(N, H) == Key -> T;
+keydelete_1(Key, N, [H|T]) ->
+ [H|keydelete_1(Key, N, T)];
+keydelete_1(Key, N, []) -> [].
+
+keyreplace_1(Key, Pos, [Tup|Tail], New) when element(Pos, Tup) == Key ->
+ [New|Tail];
+keyreplace_1(Key, Pos, [H|T], New) ->
+ [H|keyreplace_1(Key, Pos, T, New)];
+keyreplace_1(Key, Pos, [], New) -> [].
+
+keysort_1(Index, [X]) -> [X];
+keysort_1(Index, []) -> [];
+keysort_1(Index, X) -> split_and_keysort_1(X, [], [], Index).
+
+split_and_keysort_1([A,B|T], X, Y, Index) ->
+ split_and_keysort_1(T, [A|X], [B|Y], Index);
+split_and_keysort_1([H], X, Y, Index) ->
+ split_and_keysort_1([], [H|X], Y, Index);
+split_and_keysort_1([], X, Y, Index) ->
+ keymerge_1(Index, keysort_1(Index, X), keysort_1(Index, Y), []).
+
+keymerge_1(Index, X, Y) -> keymerge_1(Index, X, Y, []).
+
+keymerge_1(I, [H1|T1], [H2|T2], L) when element(I, H1) < element(I, H2) ->
+ keymerge_1(I, T1, [H2|T2], [H1|L]);
+keymerge_1(Index, T1, [H2|T2], L) ->
+ keymerge_1(Index,T1, T2, [H2|L]);
+keymerge_1(Index,[H|T], T2, L) ->
+ keymerge_1(Index,T, T2, [H|L]);
+keymerge_1(Index, [], [], L) ->
+ reverse_1(L).
+
+keymap_1(Fun, Index, [Tup|Tail]) ->
+ [setelement(Index, Tup, Fun(element(Index, Tup)))|keymap_1(Fun, Index, Tail)];
+keymap_1( _, _ , []) -> [].
+
+keymap_1(Fun, ExtraArgs, Index, [Tup|Tail]) ->
+ [setelement(Index, Tup, apply(Fun, [element(Index, Tup)|ExtraArgs]))|
+ keymap_1(Fun, ExtraArgs, Index, Tail)];
+keymap_1( _, _ , _, []) -> [].
+
+%% all(Predicate, List)
+%% any(Predicate, List)
+%% map(Function, List)
+%% flatmap(Function, List)
+%% foldl(Function, First, List)
+%% foldr(Function, Last, List)
+%% filter(Predicate, List)
+%% zf(Function, List)
+%% mapfoldl(Function, First, List)
+%% mapfoldr(Function, Last, List)
+%% foreach(Function, List)
+%% takewhile(Predicate, List)
+%% dropwhile(Predicate, List)
+%% splitwith(Predicate, List)
+%% for list programming. Function here is either a 'fun' or a tuple
+%% {Module,Name} and we use apply/2 to evaluate. The name zf is a joke!
+%%
+%% N.B. Unless where the functions actually needs it only foreach/2/3,
+%% which is meant to be used for its side effects, has a defined order
+%% of evaluation.
+%%
+%% There are also versions with an extra argument, ExtraArgs, which is a
+%% list of extra arguments to each call.
+
+all_1(Pred, [Hd|Tail]) ->
+ case Pred(Hd) of
+ true -> all_1(Pred, Tail);
+ false -> false
+ end;
+all_1(Pred, []) -> true.
+
+any_1(Pred, [Hd|Tail]) ->
+ case Pred(Hd) of
+ true -> true;
+ false -> any_1(Pred, Tail)
+ end;
+any_1(Pred, []) -> false.
+
+map_1(F, List) -> [ F(E) || E <- List ].
+
+flatmap_1(F, [Hd|Tail]) ->
+ F(Hd) ++ flatmap_1(F, Tail);
+flatmap_1(F, []) -> [].
+
+foldl_1(F, Accu, [Hd|Tail]) ->
+ foldl_1(F, F(Hd, Accu), Tail);
+foldl_1(F, Accu, []) -> Accu.
+
+foldr_1(F, Accu, [Hd|Tail]) ->
+ F(Hd, foldr_1(F, Accu, Tail));
+foldr_1(F, Accu, []) -> Accu.
+
+filter_1(Pred, List) -> [ E || E <- List, Pred(E) ].
+
+zF(F, [Hd|Tail]) ->
+ case F(Hd) of
+ true ->
+ [Hd|zF(F, Tail)];
+ {true,Val} ->
+ [Val|zF(F, Tail)];
+ false ->
+ zF(F, Tail)
+ end;
+zF(F, []) -> [].
+
+foreach_1(F, [Hd|Tail]) ->
+ F(Hd),
+ foreach_1(F, Tail);
+foreach_1(F, []) -> ok.
+
+mapfoldl_1(F, Accu0, [Hd|Tail]) ->
+ {R,Accu1} = F(Hd, Accu0),
+ {Rs,Accu2} = mapfoldl_1(F, Accu1, Tail),
+ {[R|Rs],Accu2};
+mapfoldl_1(F, Accu, []) -> {[],Accu}.
+
+mapfoldr_1(F, Accu0, [Hd|Tail]) ->
+ {Rs,Accu1} = mapfoldr_1(F, Accu0, Tail),
+ {R,Accu2} = F(Hd, Accu1),
+ {[R|Rs],Accu2};
+mapfoldr_1(F, Accu, []) -> {[],Accu}.
+
+takewhile_1(Pred, [Hd|Tail]) ->
+ case Pred(Hd) of
+ true -> [Hd|takewhile_1(Pred, Tail)];
+ false -> []
+ end;
+takewhile_1(Pred, []) -> [].
+
+dropwhile_1(Pred, [Hd|Tail]) ->
+ case Pred(Hd) of
+ true -> dropwhile_1(Pred, Tail);
+ false -> [Hd|Tail]
+ end;
+dropwhile_1(Pred, []) -> [].
+
+splitwith_1(Pred, List) -> splitwith_1(Pred, List, []).
+
+splitwith_1(Pred, [Hd|Tail], Taken) ->
+ case Pred(Hd) of
+ true -> splitwith_1(Pred, Tail, [Hd|Taken]);
+ false -> {reverse_1(Taken), [Hd|Tail]}
+ end;
+splitwith_1(Pred, [], Taken) -> {reverse_1(Taken),[]}.
+
+%% Versions of the above functions with extra arguments.
+
+all_1(Pred, Eas, [Hd|Tail]) ->
+ case apply(Pred, [Hd|Eas]) of
+ true -> all_1(Pred, Eas, Tail);
+ false -> false
+ end;
+all_1(Pred, Eas, []) -> true.
+
+any_1(Pred, Eas, [Hd|Tail]) ->
+ case apply(Pred, [Hd|Eas]) of
+ true -> true;
+ false -> any_1(Pred, Eas, Tail)
+ end;
+any_1(Pred, Eas, []) -> false.
+
+map_1(F, Eas, List) -> [ apply(F, [E|Eas]) || E <- List ].
+
+flatmap_1(F, Eas, [Hd|Tail]) ->
+ apply(F, [Hd|Eas]) ++ flatmap_1(F, Eas, Tail);
+flatmap_1(F, Eas, []) -> [].
+
+foldl_1(F, Eas, Accu, [Hd|Tail]) ->
+ foldl_1(F, Eas, apply(F, [Hd,Accu|Eas]), Tail);
+foldl_1(F, Eas, Accu, []) -> Accu.
+
+foldr_1(F, Eas, Accu, [Hd|Tail]) ->
+ apply(F, [Hd,foldr_1(F, Eas, Accu, Tail)|Eas]);
+foldr_1(F, Eas, Accu, []) ->
+ Accu.
+
+filter_1(Pred, Eas, List) -> [ E || E <- List, apply(Pred, [E|Eas]) ].
+
+zF(F, Eas, [Hd|Tail]) ->
+ case apply(F, [Hd|Eas]) of
+ true ->
+ [Hd|zF(F, Eas, Tail)];
+ {true,Val} ->
+ [Val|zF(F, Eas, Tail)];
+ false ->
+ zF(F, Eas, Tail)
+ end;
+zF(F, Eas, []) -> [].
+
+foreach_1(F, Eas, [Hd|Tail]) ->
+ apply(F, [Hd|Eas]),
+ foreach_1(F, Eas, Tail);
+foreach_1(F, Eas, []) -> ok.
+
+mapfoldl_1(F, Eas, Accu0, [Hd|Tail]) ->
+ {R,Accu1} = apply(F, [Hd,Accu0|Eas]),
+ {Rs,Accu2} = mapfoldl_1(F, Eas, Accu1, Tail),
+ {[R|Rs],Accu2};
+mapfoldl_1(F, Eas, Accu, []) -> {[],Accu}.
+
+mapfoldr_1(F, Eas, Accu0, [Hd|Tail]) ->
+ {Rs,Accu1} = mapfoldr_1(F, Eas, Accu0, Tail),
+ {R,Accu2} = apply(F, [Hd,Accu1|Eas]),
+ {[R|Rs],Accu2};
+mapfoldr_1(F, Eas, Accu, []) -> {[],Accu}.
+
+%% takewhile/2, dropwhile/2 and splitwith/2 do not have versions with
+%% extra arguments as this going to be discontinued.
+
+
+
+
+
+
+%%% +++++++++++++++++++++
+%%%
+%%% "_2"
+
+
+
+
+
+%% member_2(X, L) -> _2(true | false)
+%% test if X is a member of the list L
+
+%member_2(X, [X|_]) -> true;
+%member_2(X, [_|Y]) ->
+% member_2(X, Y);
+%member_2(X, []) -> false.
+
+member_2(X, L) when list(L) ->
+ case erlang:member_2(X, L) of
+ L1 when list(L1) ->
+ receive after 1 -> ok end,
+ member_2(X, L1);
+ Boolean ->
+ Boolean
+ end.
+
+%% append_2(X, Y) appends lists X and Y
+
+append_2(L1, L2) -> L1 ++ L2.
+
+%% append_2(L) appends the list of lists L
+
+append_2([E]) -> E;
+append_2([H|T]) -> H ++ append_2(T);
+append_2([]) -> [].
+
+%% subtract_2(List1, List2) subtract elements in List2 form List1.
+
+subtract_2(L1, L2) -> L1 -- L2.
+
+%% reverse_2(L) reverse all elements in the list L
+
+reverse_2(X) -> reverse_2(X, []).
+
+%reverse_2([H|T], Y) ->
+% reverse_2(T, [H|Y]);
+%reverse_2([], X) -> X.
+
+reverse_2(List0, Result0) when list(List0) ->
+ case erlang:reverse_2(List0, Result0) of
+ {List, Result} ->
+ receive after 1 -> ok end,
+ reverse_2(List, Result);
+ Result ->
+ Result
+ end.
+
+
+%% nth_2(N, L) returns the N`th element of the list L
+%% nthtail_2(N, L) returns the N`th tail of the list L
+
+nth_2(1, [H|T]) -> H;
+nth_2(N, [_|T]) when N > 1 ->
+ nth_2(N - 1, T).
+
+nthtail_2(1, [H|T]) -> T;
+nthtail_2(N, [H|T]) when N > 1 ->
+ nthtail_2(N - 1, T);
+nthtail_2(0, L) when list(L) -> L.
+
+%% prefix_2(Prefix, List) -> _2(true | false)
+
+prefix_2([X|PreTail], [X|Tail]) ->
+ prefix_2(PreTail, Tail);
+prefix_2([], List) -> true;
+prefix_2(_,_) -> false.
+
+
+%% suffix_2(Suffix, List) -> _2(true | false)
+
+suffix_2(Suffix, Suffix) -> true;
+suffix_2(Suffix, [_|Tail]) ->
+ suffix_2(Suffix, Tail);
+suffix_2(Suffix, []) -> false.
+
+%% last_2(List) returns the last element in a list.
+
+last_2([E]) -> E;
+last_2([E|Es]) ->
+ last_2(Es).
+
+%% seq_2(Min, Max) -> [Min,Min+1, ..., Max]
+%% seq_2(Min, Max, Incr) -> [Min,Min+Incr, ..., Max]
+%% returns the sequence Min..Max
+%% Min <= Max and Min and Max must be integers
+
+seq_2(Min, Max) when integer(Min), integer(Max), Min =< Max ->
+ seq_2(Min, Max, 1, []).
+
+seq_2(Min, Max, Incr) ->
+ seq_2(Min, Min + ((Max-Min) div Incr) * Incr, Incr, []).
+
+seq_2(Min, Min, I, L) -> [Min|L];
+seq_2(Min, Max, I, L) -> seq_2(Min, Max-I, I, [Max|L]).
+
+%% sum_2(L) suns the sum of the elements in L
+
+sum_2(L) -> sum_2(L, 0).
+sum_2([H|T], Sum) -> sum_2(T, Sum + H);
+sum_2([], Sum) -> Sum.
+
+%% duplicate_2(N, X) -> [X,X,X,.....,X] _2(N times)
+%% return N copies of X
+
+duplicate_2(N, X) when integer(N), N >= 0 -> duplicate_2(N, X, []).
+
+duplicate_2(0, _, L) -> L;
+duplicate_2(N, X, L) -> duplicate_2(N-1, X, [X|L]).
+
+
+%% min_2(L) -> returns the minimum element of the list L
+
+min_2([H|T]) -> min_2(T, H).
+
+min_2([H|T], Min) when H < Min -> min_2(T, H);
+min_2([_|T], Min) -> min_2(T, Min);
+min_2([], Min) -> Min.
+
+%% max_2(L) -> returns the maximum element of the list L
+
+max_2([H|T]) -> max_2(T, H).
+
+max_2([H|T], Max) when H > Max -> max_2(T, H);
+max_2([_|T], Max) -> max_2(T, Max);
+max_2([], Max) -> Max.
+
+%% sublist(List, Start, Length)
+%% Returns the sub-list starting at Start of length Length.
+
+sublist_2(List, S, L) when L >= 0 ->
+ sublist_2(nthtail_2(S-1, List), L).
+
+sublist_2([H|T], L) when L > 0 ->
+ [H|sublist_2(T, L-1)];
+sublist_2(List, L) -> [].
+
+%% delete_2(Item, List) -> List'
+%% Delete the first occurance of Item from the list L.
+
+delete_2(Item, [Item|Rest]) -> Rest;
+delete_2(Item, [H|Rest]) ->
+ [H|delete_2(Item, Rest)];
+delete_2(Item, []) -> [].
+
+%% sort_2(L) -> sorts the list L
+
+sort_2([X]) -> [X];
+sort_2([]) -> [];
+sort_2(X) -> split_and_sort_2(X, [], []).
+
+split_and_sort_2([A,B|T], X, Y) ->
+ split_and_sort_2(T, [A|X], [B|Y]);
+split_and_sort_2([H], X, Y) ->
+ split_and_sort_2([], [H|X], Y);
+split_and_sort_2([], X, Y) ->
+ merge_2(sort_2(X), sort_2(Y), []).
+
+%% merge_2(X, Y) -> L
+%% merges two sorted lists X and Y
+
+merge_2(X, Y) -> merge_2(X, Y, []).
+
+merge_2([H1|T1], [H2|T2], L) when H1 < H2 ->
+ merge_2(T1, [H2|T2], [H1|L]);
+merge_2(T1, [H2|T2], L) ->
+ merge_2(T1, T2, [H2|L]);
+merge_2([H|T], T2, L) ->
+ merge_2(T, T2, [H|L]);
+merge_2([], [], L) ->
+ reverse_2(L).
+
+%% concat_2(L) concatinate the list representation of the elements
+%% in L - the elements in L can be atoms, integers of strings.
+%% Returns a list of characters.
+
+concat_2(List) ->
+ flatmap_2(fun thing_to_list/1, List).
+
+thing_to_list_2(X) when integer(X) -> integer_to_list(X);
+thing_to_list_2(X) when float(X) -> float_to_list(X);
+thing_to_list_2(X) when atom(X) -> atom_to_list(X);
+thing_to_list_2(X) when list(X) -> X. %Assumed to be a string
+
+%% flatten_2(List)
+%% flatten_2(List, Tail)
+%% Flatten a list, adding optional tail.
+
+flatten_2(List) ->
+ flatten_2(List, [], []).
+
+flatten_2(List, Tail) ->
+ flatten_2(List, [], Tail).
+
+flatten_2([H|T], Cont, Tail) when list(H) ->
+ flatten_2(H, [T|Cont], Tail);
+flatten_2([H|T], Cont, Tail) ->
+ [H|flatten_2(T, Cont, Tail)];
+flatten_2([], [H|Cont], Tail) ->
+ flatten_2(H, Cont, Tail);
+flatten_2([], [], Tail) ->
+ Tail.
+
+%% flat_length_2(List) _2(undocumented can be rmove later)
+%% Calculate the length of a list of lists.
+
+flat_length_2(List) -> flatlength_2(List).
+
+%% flatlength_2(List)
+%% Calculate the length of a list of lists.
+
+flatlength_2(List) ->
+ flatlength_2(List, 0).
+
+flatlength_2([H|T], L) when list(H) ->
+ flatlength_2(H, flatlength_2(T, L));
+flatlength_2([H|T], L) ->
+ flatlength_2(T, L + 1);
+flatlength_2([], L) -> L.
+
+%% keymember_2(Key, Index, [Tuple])
+%% keysearch_2(Key, Index, [Tuple])
+%% keydelete_2(Key, Index, [Tuple])
+%% keyreplace_2(Key, Index, [Tuple], NewTuple)
+%% keysort_2(Index, [Tuple])
+%% keymerge_2(Index, [Tuple], [Tuple])
+%% keymap_2(Function, Index, [Tuple])
+%% keymap_2(Function, ExtraArgs, Index, [Tuple])
+
+keymember_2(Key, N, [T|Ts]) when element(N, T) == Key -> true;
+keymember_2(Key, N, [T|Ts]) ->
+ keymember_2(Key, N, Ts);
+keymember_2(Key, N, []) -> false.
+
+keysearch_2(Key, N, [H|T]) when element(N, H) == Key ->
+ {value, H};
+keysearch_2(Key, N, [H|T]) ->
+ keysearch_2(Key, N, T);
+keysearch_2(Key, N, []) -> false.
+
+keydelete_2(Key, N, [H|T]) when element(N, H) == Key -> T;
+keydelete_2(Key, N, [H|T]) ->
+ [H|keydelete_2(Key, N, T)];
+keydelete_2(Key, N, []) -> [].
+
+keyreplace_2(Key, Pos, [Tup|Tail], New) when element(Pos, Tup) == Key ->
+ [New|Tail];
+keyreplace_2(Key, Pos, [H|T], New) ->
+ [H|keyreplace_2(Key, Pos, T, New)];
+keyreplace_2(Key, Pos, [], New) -> [].
+
+keysort_2(Index, [X]) -> [X];
+keysort_2(Index, []) -> [];
+keysort_2(Index, X) -> split_and_keysort_2(X, [], [], Index).
+
+split_and_keysort_2([A,B|T], X, Y, Index) ->
+ split_and_keysort_2(T, [A|X], [B|Y], Index);
+split_and_keysort_2([H], X, Y, Index) ->
+ split_and_keysort_2([], [H|X], Y, Index);
+split_and_keysort_2([], X, Y, Index) ->
+ keymerge_2(Index, keysort_2(Index, X), keysort_2(Index, Y), []).
+
+keymerge_2(Index, X, Y) -> keymerge_2(Index, X, Y, []).
+
+keymerge_2(I, [H1|T1], [H2|T2], L) when element(I, H1) < element(I, H2) ->
+ keymerge_2(I, T1, [H2|T2], [H1|L]);
+keymerge_2(Index, T1, [H2|T2], L) ->
+ keymerge_2(Index,T1, T2, [H2|L]);
+keymerge_2(Index,[H|T], T2, L) ->
+ keymerge_2(Index,T, T2, [H|L]);
+keymerge_2(Index, [], [], L) ->
+ reverse_2(L).
+
+keymap_2(Fun, Index, [Tup|Tail]) ->
+ [setelement(Index, Tup, Fun(element(Index, Tup)))|keymap_2(Fun, Index, Tail)];
+keymap_2( _, _ , []) -> [].
+
+keymap_2(Fun, ExtraArgs, Index, [Tup|Tail]) ->
+ [setelement(Index, Tup, apply(Fun, [element(Index, Tup)|ExtraArgs]))|
+ keymap_2(Fun, ExtraArgs, Index, Tail)];
+keymap_2( _, _ , _, []) -> [].
+
+%% all_2(Predicate, List)
+%% any_2(Predicate, List)
+%% map_2(Function, List)
+%% flatmap_2(Function, List)
+%% foldl_2(Function, First, List)
+%% foldr_2(Function, Last, List)
+%% filter_2(Predicate, List)
+%% zF(Function, List)
+%% mapfoldl_2(Function, First, List)
+%% mapfoldr_2(Function, Last, List)
+%% foreach_2(Function, List)
+%% takewhile_2(Predicate, List)
+%% dropwhile_2(Predicate, List)
+%% splitwith_2(Predicate, List)
+%% for list programming. Function here is either a 'fun' or a tuple
+%% {Module,Name} and we use apply/2 to evaluate. The name zf is a joke!
+%%
+%% N.B. Unless where the functions actually needs it only foreach/2/3,
+%% which is meant to be used for its side effects, has a defined order
+%% of evaluation.
+%%
+%% There are also versions with an extra argument, ExtraArgs, which is a
+%% list of extra arguments to each call.
+
+all_2(Pred, [Hd|Tail]) ->
+ case Pred(Hd) of
+ true -> all_2(Pred, Tail);
+ false -> false
+ end;
+all_2(Pred, []) -> true.
+
+any_2(Pred, [Hd|Tail]) ->
+ case Pred(Hd) of
+ true -> true;
+ false -> any_2(Pred, Tail)
+ end;
+any_2(Pred, []) -> false.
+
+map_2(F, List) -> [ F(E) || E <- List ].
+
+flatmap_2(F, [Hd|Tail]) ->
+ F(Hd) ++ flatmap_2(F, Tail);
+flatmap_2(F, []) -> [].
+
+foldl_2(F, Accu, [Hd|Tail]) ->
+ foldl_2(F, F(Hd, Accu), Tail);
+foldl_2(F, Accu, []) -> Accu.
+
+foldr_2(F, Accu, [Hd|Tail]) ->
+ F(Hd, foldr_2(F, Accu, Tail));
+foldr_2(F, Accu, []) -> Accu.
+
+filter_2(Pred, List) -> [ E || E <- List, Pred(E) ].
+
+zF_2(F, [Hd|Tail]) ->
+ case F(Hd) of
+ true ->
+ [Hd|zF_2(F, Tail)];
+ {true,Val} ->
+ [Val|zF_2(F, Tail)];
+ false ->
+ zF_2(F, Tail)
+ end;
+zF_2(F, []) -> [].
+
+foreach_2(F, [Hd|Tail]) ->
+ F(Hd),
+ foreach_2(F, Tail);
+foreach_2(F, []) -> ok.
+
+mapfoldl_2(F, Accu0, [Hd|Tail]) ->
+ {R,Accu1} = F(Hd, Accu0),
+ {Rs,Accu2} = mapfoldl_2(F, Accu1, Tail),
+ {[R|Rs],Accu2};
+mapfoldl_2(F, Accu, []) -> {[],Accu}.
+
+mapfoldr_2(F, Accu0, [Hd|Tail]) ->
+ {Rs,Accu1} = mapfoldr_2(F, Accu0, Tail),
+ {R,Accu2} = F(Hd, Accu1),
+ {[R|Rs],Accu2};
+mapfoldr_2(F, Accu, []) -> {[],Accu}.
+
+takewhile_2(Pred, [Hd|Tail]) ->
+ case Pred(Hd) of
+ true -> [Hd|takewhile_2(Pred, Tail)];
+ false -> []
+ end;
+takewhile_2(Pred, []) -> [].
+
+dropwhile_2(Pred, [Hd|Tail]) ->
+ case Pred(Hd) of
+ true -> dropwhile_2(Pred, Tail);
+ false -> [Hd|Tail]
+ end;
+dropwhile_2(Pred, []) -> [].
+
+splitwith_2(Pred, List) -> splitwith_2(Pred, List, []).
+
+splitwith_2(Pred, [Hd|Tail], Taken) ->
+ case Pred(Hd) of
+ true -> splitwith_2(Pred, Tail, [Hd|Taken]);
+ false -> {reverse_2(Taken), [Hd|Tail]}
+ end;
+splitwith_2(Pred, [], Taken) -> {reverse_2(Taken),[]}.
+
+%% Versions of the above functions with extra arguments.
+
+all_2(Pred, Eas, [Hd|Tail]) ->
+ case apply(Pred, [Hd|Eas]) of
+ true -> all_2(Pred, Eas, Tail);
+ false -> false
+ end;
+all_2(Pred, Eas, []) -> true.
+
+any_2(Pred, Eas, [Hd|Tail]) ->
+ case apply(Pred, [Hd|Eas]) of
+ true -> true;
+ false -> any_2(Pred, Eas, Tail)
+ end;
+any_2(Pred, Eas, []) -> false.
+
+map_2(F, Eas, List) -> [ apply(F, [E|Eas]) || E <- List ].
+
+flatmap_2(F, Eas, [Hd|Tail]) ->
+ apply(F, [Hd|Eas]) ++ flatmap_2(F, Eas, Tail);
+flatmap_2(F, Eas, []) -> [].
+
+foldl_2(F, Eas, Accu, [Hd|Tail]) ->
+ foldl_2(F, Eas, apply(F, [Hd,Accu|Eas]), Tail);
+foldl_2(F, Eas, Accu, []) -> Accu.
+
+foldr_2(F, Eas, Accu, [Hd|Tail]) ->
+ apply(F, [Hd,foldr_2(F, Eas, Accu, Tail)|Eas]);
+foldr_2(F, Eas, Accu, []) ->
+ Accu.
+
+filter_2(Pred, Eas, List) -> [ E || E <- List, apply(Pred, [E|Eas]) ].
+
+zF_2(F, Eas, [Hd|Tail]) ->
+ case apply(F, [Hd|Eas]) of
+ true ->
+ [Hd|zF_2(F, Eas, Tail)];
+ {true,Val} ->
+ [Val|zF_2(F, Eas, Tail)];
+ false ->
+ zF_2(F, Eas, Tail)
+ end;
+zF_2(F, Eas, []) -> [].
+
+foreach_2(F, Eas, [Hd|Tail]) ->
+ apply(F, [Hd|Eas]),
+ foreach_2(F, Eas, Tail);
+foreach_2(F, Eas, []) -> ok.
+
+mapfoldl_2(F, Eas, Accu0, [Hd|Tail]) ->
+ {R,Accu1} = apply(F, [Hd,Accu0|Eas]),
+ {Rs,Accu2} = mapfoldl_2(F, Eas, Accu1, Tail),
+ {[R|Rs],Accu2};
+mapfoldl_2(F, Eas, Accu, []) -> {[],Accu}.
+
+mapfoldr_2(F, Eas, Accu0, [Hd|Tail]) ->
+ {Rs,Accu1} = mapfoldr_2(F, Eas, Accu0, Tail),
+ {R,Accu2} = apply(F, [Hd,Accu1|Eas]),
+ {[R|Rs],Accu2};
+mapfoldr_2(F, Eas, Accu, []) -> {[],Accu}.
+
+%% takewhile/2, dropwhile/2 and splitwith/2 do not have versions with
+%% extra arguments as this going to be discontinued.
+
+
+
+
+
+%%% +++++++++++++++++++
+%%%
+%%% With "_3"
+
+
+
+
+%% member_3(X, L) -> _3(true | false)
+%% test if X is a member of the list L
+
+%member_3(X, [X|_]) -> true;
+%member_3(X, [_|Y]) ->
+% member_3(X, Y);
+%member_3(X, []) -> false.
+
+member_3(X, L) when list(L) ->
+ case erlang:member(X, L) of
+ L1 when list(L1) ->
+ receive after 1 -> ok end,
+ member_3(X, L1);
+ Boolean ->
+ Boolean
+ end.
+
+%% append_3(X, Y) appends lists X and Y
+
+append_3(L1, L2) -> L1 ++ L2.
+
+%% append_3(L) appends the list of lists L
+
+append_3([E]) -> E;
+append_3([H|T]) -> H ++ append_3(T);
+append_3([]) -> [].
+
+%% subtract_3(List1, List2) subtract elements in List2 form List1.
+
+subtract_3(L1, L2) -> L1 -- L2.
+
+%% reverse_3(L) reverse all elements in the list L
+
+reverse_3(X) -> reverse_3(X, []).
+
+%reverse_3([H|T], Y) ->
+% reverse_3(T, [H|Y]);
+%reverse_3([], X) -> X.
+
+reverse_3(List0, Result0) when list(List0) ->
+ case erlang:reverse_3(List0, Result0) of
+ {List, Result} ->
+ receive after 1 -> ok end,
+ reverse_3(List, Result);
+ Result ->
+ Result
+ end.
+
+
+%% nth_3(N, L) returns the N`th element of the list L
+%% nthtail_3(N, L) returns the N`th tail of the list L
+
+nth_3(1, [H|T]) -> H;
+nth_3(N, [_|T]) when N > 1 ->
+ nth_3(N - 1, T).
+
+nthtail_3(1, [H|T]) -> T;
+nthtail_3(N, [H|T]) when N > 1 ->
+ nthtail_3(N - 1, T);
+nthtail_3(0, L) when list(L) -> L.
+
+%% prefix_3(Prefix, List) -> _3(true | false)
+
+prefix_3([X|PreTail], [X|Tail]) ->
+ prefix_3(PreTail, Tail);
+prefix_3([], List) -> true;
+prefix_3(_,_) -> false.
+
+
+%% suffix_3(Suffix, List) -> _3(true | false)
+
+suffix_3(Suffix, Suffix) -> true;
+suffix_3(Suffix, [_|Tail]) ->
+ suffix_3(Suffix, Tail);
+suffix_3(Suffix, []) -> false.
+
+%% last_3(List) returns the last element in a list.
+
+last_3([E]) -> E;
+last_3([E|Es]) ->
+ last_3(Es).
+
+%% seq_3(Min, Max) -> [Min,Min+1, ..., Max]
+%% seq_3(Min, Max, Incr) -> [Min,Min+Incr, ..., Max]
+%% returns the sequence Min..Max
+%% Min <= Max and Min and Max must be integers
+
+seq_3(Min, Max) when integer(Min), integer(Max), Min =< Max ->
+ seq_3(Min, Max, 1, []).
+
+seq_3(Min, Max, Incr) ->
+ seq_3(Min, Min + ((Max-Min) div Incr) * Incr, Incr, []).
+
+seq_3(Min, Min, I, L) -> [Min|L];
+seq_3(Min, Max, I, L) -> seq_3(Min, Max-I, I, [Max|L]).
+
+%% sum_3(L) suns the sum of the elements in L
+
+sum_3(L) -> sum_3(L, 0).
+sum_3([H|T], Sum) -> sum_3(T, Sum + H);
+sum_3([], Sum) -> Sum.
+
+%% duplicate_3(N, X) -> [X,X,X,.....,X] _3(N times)
+%% return N copies of X
+
+duplicate_3(N, X) when integer(N), N >= 0 -> duplicate_3(N, X, []).
+
+duplicate_3(0, _, L) -> L;
+duplicate_3(N, X, L) -> duplicate_3(N-1, X, [X|L]).
+
+
+%% min_3(L) -> returns the minimum element of the list L
+
+min_3([H|T]) -> min_3(T, H).
+
+min_3([H|T], Min) when H < Min -> min_3(T, H);
+min_3([_|T], Min) -> min_3(T, Min);
+min_3([], Min) -> Min.
+
+%% max_3(L) -> returns the maximum element of the list L
+
+max_3([H|T]) -> max_3(T, H).
+
+max_3([H|T], Max) when H > Max -> max_3(T, H);
+max_3([_|T], Max) -> max_3(T, Max);
+max_3([], Max) -> Max.
+
+%% sublist_3(List, Start, Length)
+%% Returns the sub-list starting at Start of length Length.
+
+sublist_3(List, S, L) when L >= 0 ->
+ sublist_3(nthtail_3(S-1, List), L).
+
+sublist_3([H|T], L) when L > 0 ->
+ [H|sublist_3(T, L-1)];
+sublist_3(List, L) -> [].
+
+%% delete_3(Item, List) -> List'
+%% Delete the first occurance of Item from the list L.
+
+delete_3(Item, [Item|Rest]) -> Rest;
+delete_3(Item, [H|Rest]) ->
+ [H|delete_3(Item, Rest)];
+delete_3(Item, []) -> [].
+
+%% sort_3(L) -> sorts the list L
+
+sort_3([X]) -> [X];
+sort_3([]) -> [];
+sort_3(X) -> split_and_sort_3(X, [], []).
+
+split_and_sort_3([A,B|T], X, Y) ->
+ split_and_sort_3(T, [A|X], [B|Y]);
+split_and_sort_3([H], X, Y) ->
+ split_and_sort_3([], [H|X], Y);
+split_and_sort_3([], X, Y) ->
+ merge_3(sort_3(X), sort_3(Y), []).
+
+%% merge_3(X, Y) -> L
+%% merges two sorted lists X and Y
+
+merge_3(X, Y) -> merge_3(X, Y, []).
+
+merge_3([H1|T1], [H2|T2], L) when H1 < H2 ->
+ merge_3(T1, [H2|T2], [H1|L]);
+merge_3(T1, [H2|T2], L) ->
+ merge_3(T1, T2, [H2|L]);
+merge_3([H|T], T2, L) ->
+ merge_3(T, T2, [H|L]);
+merge_3([], [], L) ->
+ reverse_3(L).
+
+%% concat_3(L) concatinate the list representation of the elements
+%% in L - the elements in L can be atoms, integers of strings.
+%% Returns a list of characters.
+
+concat_3(List) ->
+ flatmap_3(fun thing_to_list/1, List).
+
+thing_to_list_3(X) when integer(X) -> integer_to_list(X);
+thing_to_list_3(X) when float(X) -> float_to_list(X);
+thing_to_list_3(X) when atom(X) -> atom_to_list(X);
+thing_to_list_3(X) when list(X) -> X. %Assumed to be a string
+
+%% flatten_3(List)
+%% flatten_3(List, Tail)
+%% Flatten a list, adding optional tail.
+
+flatten_3(List) ->
+ flatten_3(List, [], []).
+
+flatten_3(List, Tail) ->
+ flatten_3(List, [], Tail).
+
+flatten_3([H|T], Cont, Tail) when list(H) ->
+ flatten_3(H, [T|Cont], Tail);
+flatten_3([H|T], Cont, Tail) ->
+ [H|flatten_3(T, Cont, Tail)];
+flatten_3([], [H|Cont], Tail) ->
+ flatten_3(H, Cont, Tail);
+flatten_3([], [], Tail) ->
+ Tail.
+
+%% flat_length_3(List) _3(undocumented can be rmove later)
+%% Calculate the length of a list of lists.
+
+flat_length_3(List) -> flatlength_3(List).
+
+%% flatlength_3(List)
+%% Calculate the length of a list of lists.
+
+flatlength_3(List) ->
+ flatlength_3(List, 0).
+
+flatlength_3([H|T], L) when list(H) ->
+ flatlength_3(H, flatlength_3(T, L));
+flatlength_3([H|T], L) ->
+ flatlength_3(T, L + 1);
+flatlength_3([], L) -> L.
+
+%% keymember_3(Key, Index, [Tuple])
+%% keysearch_3(Key, Index, [Tuple])
+%% keydelete_3(Key, Index, [Tuple])
+%% keyreplace_3(Key, Index, [Tuple], NewTuple)
+%% keysort_3(Index, [Tuple])
+%% keymerge_3(Index, [Tuple], [Tuple])
+%% keymap_3(Function, Index, [Tuple])
+%% keymap_3(Function, ExtraArgs, Index, [Tuple])
+
+keymember_3(Key, N, [T|Ts]) when element(N, T) == Key -> true;
+keymember_3(Key, N, [T|Ts]) ->
+ keymember_3(Key, N, Ts);
+keymember_3(Key, N, []) -> false.
+
+keysearch_3(Key, N, [H|T]) when element(N, H) == Key ->
+ {value, H};
+keysearch_3(Key, N, [H|T]) ->
+ keysearch_3(Key, N, T);
+keysearch_3(Key, N, []) -> false.
+
+keydelete_3(Key, N, [H|T]) when element(N, H) == Key -> T;
+keydelete_3(Key, N, [H|T]) ->
+ [H|keydelete_3(Key, N, T)];
+keydelete_3(Key, N, []) -> [].
+
+keyreplace_3(Key, Pos, [Tup|Tail], New) when element(Pos, Tup) == Key ->
+ [New|Tail];
+keyreplace_3(Key, Pos, [H|T], New) ->
+ [H|keyreplace_3(Key, Pos, T, New)];
+keyreplace_3(Key, Pos, [], New) -> [].
+
+keysort_3(Index, [X]) -> [X];
+keysort_3(Index, []) -> [];
+keysort_3(Index, X) -> split_and_keysort_3(X, [], [], Index).
+
+split_and_keysort_3([A,B|T], X, Y, Index) ->
+ split_and_keysort_3(T, [A|X], [B|Y], Index);
+split_and_keysort_3([H], X, Y, Index) ->
+ split_and_keysort_3([], [H|X], Y, Index);
+split_and_keysort_3([], X, Y, Index) ->
+ keymerge_3(Index, keysort_3(Index, X), keysort_3(Index, Y), []).
+
+keymerge_3(Index, X, Y) -> keymerge_3(Index, X, Y, []).
+
+keymerge_3(I, [H1|T1], [H2|T2], L) when element(I, H1) < element(I, H2) ->
+ keymerge_3(I, T1, [H2|T2], [H1|L]);
+keymerge_3(Index, T1, [H2|T2], L) ->
+ keymerge_3(Index,T1, T2, [H2|L]);
+keymerge_3(Index,[H|T], T2, L) ->
+ keymerge_3(Index,T, T2, [H|L]);
+keymerge_3(Index, [], [], L) ->
+ reverse_3(L).
+
+keymap_3(Fun, Index, [Tup|Tail]) ->
+ [setelement(Index, Tup, Fun(element(Index, Tup)))|keymap_3(Fun, Index, Tail)];
+keymap_3( _, _ , []) -> [].
+
+keymap_3(Fun, ExtraArgs, Index, [Tup|Tail]) ->
+ [setelement(Index, Tup, apply(Fun, [element(Index, Tup)|ExtraArgs]))|
+ keymap_3(Fun, ExtraArgs, Index, Tail)];
+keymap_3( _, _ , _, []) -> [].
+
+%% all_3(Predicate, List)
+%% any_3(Predicate, List)
+%% map_3(Function, List)
+%% flatmap_3(Function, List)
+%% foldl_3(Function, First, List)
+%% foldr_3(Function, Last, List)
+%% filter_3(Predicate, List)
+%% zF(Function, List)
+%% mapfoldl_3(Function, First, List)
+%% mapfoldr_3(Function, Last, List)
+%% foreach_3(Function, List)
+%% takewhile_3(Predicate, List)
+%% dropwhile_3(Predicate, List)
+%% splitwith_3(Predicate, List)
+%% for list programming. Function here is either a 'fun' or a tuple
+%% {Module,Name} and we use apply/2 to evaluate. The name zf is a joke!
+%%
+%% N.B. Unless where the functions actually needs it only foreach/2/3,
+%% which is meant to be used for its side effects, has a defined order
+%% of evaluation.
+%%
+%% There are also versions with an extra argument, ExtraArgs, which is a
+%% list of extra arguments to each call.
+
+all_3(Pred, [Hd|Tail]) ->
+ case Pred(Hd) of
+ true -> all_3(Pred, Tail);
+ false -> false
+ end;
+all_3(Pred, []) -> true.
+
+any_3(Pred, [Hd|Tail]) ->
+ case Pred(Hd) of
+ true -> true;
+ false -> any_3(Pred, Tail)
+ end;
+any_3(Pred, []) -> false.
+
+map_3(F, List) -> [ F(E) || E <- List ].
+
+flatmap_3(F, [Hd|Tail]) ->
+ F(Hd) ++ flatmap_3(F, Tail);
+flatmap_3(F, []) -> [].
+
+foldl_3(F, Accu, [Hd|Tail]) ->
+ foldl_3(F, F(Hd, Accu), Tail);
+foldl_3(F, Accu, []) -> Accu.
+
+foldr_3(F, Accu, [Hd|Tail]) ->
+ F(Hd, foldr_3(F, Accu, Tail));
+foldr_3(F, Accu, []) -> Accu.
+
+filter_3(Pred, List) -> [ E || E <- List, Pred(E) ].
+
+zF_3(F, [Hd|Tail]) ->
+ case F(Hd) of
+ true ->
+ [Hd|zF_3(F, Tail)];
+ {true,Val} ->
+ [Val|zF_3(F, Tail)];
+ false ->
+ zF_3(F, Tail)
+ end;
+zF_3(F, []) -> [].
+
+foreach_3(F, [Hd|Tail]) ->
+ F(Hd),
+ foreach_3(F, Tail);
+foreach_3(F, []) -> ok.
+
+mapfoldl_3(F, Accu0, [Hd|Tail]) ->
+ {R,Accu1} = F(Hd, Accu0),
+ {Rs,Accu2} = mapfoldl_3(F, Accu1, Tail),
+ {[R|Rs],Accu2};
+mapfoldl_3(F, Accu, []) -> {[],Accu}.
+
+mapfoldr_3(F, Accu0, [Hd|Tail]) ->
+ {Rs,Accu1} = mapfoldr_3(F, Accu0, Tail),
+ {R,Accu2} = F(Hd, Accu1),
+ {[R|Rs],Accu2};
+mapfoldr_3(F, Accu, []) -> {[],Accu}.
+
+takewhile_3(Pred, [Hd|Tail]) ->
+ case Pred(Hd) of
+ true -> [Hd|takewhile_3(Pred, Tail)];
+ false -> []
+ end;
+takewhile_3(Pred, []) -> [].
+
+dropwhile_3(Pred, [Hd|Tail]) ->
+ case Pred(Hd) of
+ true -> dropwhile_3(Pred, Tail);
+ false -> [Hd|Tail]
+ end;
+dropwhile_3(Pred, []) -> [].
+
+splitwith_3(Pred, List) -> splitwith_3(Pred, List, []).
+
+splitwith_3(Pred, [Hd|Tail], Taken) ->
+ case Pred(Hd) of
+ true -> splitwith_3(Pred, Tail, [Hd|Taken]);
+ false -> {reverse_3(Taken), [Hd|Tail]}
+ end;
+splitwith_3(Pred, [], Taken) -> {reverse_3(Taken),[]}.
+
+%% Versions of the above functions with extra arguments.
+
+all_3(Pred, Eas, [Hd|Tail]) ->
+ case apply(Pred, [Hd|Eas]) of
+ true -> all_3(Pred, Eas, Tail);
+ false -> false
+ end;
+all_3(Pred, Eas, []) -> true.
+
+any_3(Pred, Eas, [Hd|Tail]) ->
+ case apply(Pred, [Hd|Eas]) of
+ true -> true;
+ false -> any_3(Pred, Eas, Tail)
+ end;
+any_3(Pred, Eas, []) -> false.
+
+map_3(F, Eas, List) -> [ apply(F, [E|Eas]) || E <- List ].
+
+flatmap_3(F, Eas, [Hd|Tail]) ->
+ apply(F, [Hd|Eas]) ++ flatmap_3(F, Eas, Tail);
+flatmap_3(F, Eas, []) -> [].
+
+foldl_3(F, Eas, Accu, [Hd|Tail]) ->
+ foldl_3(F, Eas, apply(F, [Hd,Accu|Eas]), Tail);
+foldl_3(F, Eas, Accu, []) -> Accu.
+
+foldr_3(F, Eas, Accu, [Hd|Tail]) ->
+ apply(F, [Hd,foldr_3(F, Eas, Accu, Tail)|Eas]);
+foldr_3(F, Eas, Accu, []) ->
+ Accu.
+
+filter_3(Pred, Eas, List) -> [ E || E <- List, apply(Pred, [E|Eas]) ].
+
+zF_3(F, Eas, [Hd|Tail]) ->
+ case apply(F, [Hd|Eas]) of
+ true ->
+ [Hd|zF(F, Eas, Tail)];
+ {true,Val} ->
+ [Val|zF(F, Eas, Tail)];
+ false ->
+ zF(F, Eas, Tail)
+ end;
+zF_3(F, Eas, []) -> [].
+
+foreach_3(F, Eas, [Hd|Tail]) ->
+ apply(F, [Hd|Eas]),
+ foreach_3(F, Eas, Tail);
+foreach_3(F, Eas, []) -> ok.
+
+mapfoldl_3(F, Eas, Accu0, [Hd|Tail]) ->
+ {R,Accu1} = apply(F, [Hd,Accu0|Eas]),
+ {Rs,Accu2} = mapfoldl_3(F, Eas, Accu1, Tail),
+ {[R|Rs],Accu2};
+mapfoldl_3(F, Eas, Accu, []) -> {[],Accu}.
+
+mapfoldr_3(F, Eas, Accu0, [Hd|Tail]) ->
+ {Rs,Accu1} = mapfoldr_3(F, Eas, Accu0, Tail),
+ {R,Accu2} = apply(F, [Hd,Accu1|Eas]),
+ {[R|Rs],Accu2};
+mapfoldr_3(F, Eas, Accu, []) -> {[],Accu}.
+
+%% takewhile/2, dropwhile/2 and splitwith/2 do not have versions with
+%% extra arguments as this going to be discontinued.
+
+
+
+
+lots_of_atoms () ->
+
+Aa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Ab = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Ac = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Ad = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Ae = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Af = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Ag = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Ah = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Aaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Aba = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Aca = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Ada = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Aea = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Afa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Aga = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Aha = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Aab = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Abb = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Acb = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Adb = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Aeb = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Afb = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Agb = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Ahb = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Aac = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Abc = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Acc = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Adc = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Aec = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Afc = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Agc = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Ahc = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Aad = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Abd = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Acd = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Add = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Aed = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Afd = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Agd = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Ahd = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Aae = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Abe = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Ace = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Ade = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Aee = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Afe = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Age = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Ahe = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+
+
+Aaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Abaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Acaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Adaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Aeaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Afaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Agaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Ahaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Aaaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Abaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Acaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Adaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Aeaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Afaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Agaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Ahaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Aabaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Abbaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Acbaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Adbaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Aebaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Afbaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Agbaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Ahbaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Aacaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Abcaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Accaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Adcaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Aecaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Afcaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Agcaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Ahcaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Aadaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Abdaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Acdaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Addaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Aedaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Afdaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Agdaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Ahdaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Aaeaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Abeaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Aceaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Adeaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Aeeaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Afeaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Ageaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Aheaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+
+Aaaaaa= 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Abaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Acaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Adaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Aeaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Afaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Agaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Ahaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Aaaaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Abaaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Acaaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Adaaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Aeaaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Afaaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Agaaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Ahaaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Aabaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Abbaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Acbaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Adbaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Aebaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Afbaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Agbaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Ahbaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Aacaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Abcaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Accaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Adcaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Aecaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Afcaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Agcaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Ahcaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Aadaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Abdaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Acdaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Addaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Aedaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Afdaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Agdaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Ahdaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Aaeaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Abeaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Aceaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Adeaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Aeeaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Afeaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Ageaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Aheaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg'.
+
+
+lots_of_atoms1 () ->
+
+Aa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Ab = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Ac = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Ad = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Ae = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Af = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Ag = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Ah = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Aaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Aba = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Aca = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Ada = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Aea = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Afa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Aga = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Aha = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Aab = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Abb = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Acb = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Adb = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Aeb = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Afb = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Agb = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Ahb = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Aac = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Abc = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Acc = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Adc = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Aec = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Afc = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Agc = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Ahc = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Aad = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Abd = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Acd = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Add = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Aed = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Afd = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Agd = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Ahd = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Aae = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Abe = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Ace = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Ade = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Aee = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Afe = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Age = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Ahe = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+
+
+Aaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Abaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Acaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Adaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Aeaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Afaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Agaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Ahaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Aaaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Abaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Acaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Adaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Aeaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Afaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Agaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Ahaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Aabaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Abbaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Acbaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Adbaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Aebaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Afbaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Agbaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Ahbaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Aacaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Abcaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Accaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Adcaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Aecaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Afcaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Agcaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Ahcaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Aadaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Abdaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Acdaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Addaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Aedaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Afdaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Agdaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Ahdaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Aaeaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Abeaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Aceaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Adeaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Aeeaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Afeaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Ageaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Aheaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+
+Aaaaaa= 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Abaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Acaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Adaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Aeaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Afaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Agaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Ahaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Aaaaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Abaaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Acaaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Adaaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Aeaaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Afaaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Agaaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Ahaaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Aabaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Abbaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Acbaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Adbaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Aebaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Afbaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Agbaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Ahbaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Aacaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Abcaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Accaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Adcaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Aecaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Afcaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Agcaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Ahcaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Aadaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Abdaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Acdaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Addaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Aedaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Afdaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Agdaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Ahdaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Aaeaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Abeaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Aceaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Adeaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Aeeaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Afeaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Ageaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Aheaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg'.
+
+
+lots_of_atoms2 () ->
+
+Aa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Ab = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Ac = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Ad = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Ae = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Af = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Ag = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Ah = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Aaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Aba = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Aca = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Ada = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Aea = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Afa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Aga = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Aha = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Aab = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Abb = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Acb = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Adb = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Aeb = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Afb = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Agb = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Ahb = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Aac = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Abc = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Acc = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Adc = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Aec = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Afc = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Agc = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Ahc = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Aad = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Abd = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Acd = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Add = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Aed = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Afd = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Agd = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Ahd = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Aae = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Abe = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Ace = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Ade = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Aee = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Afe = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Age = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Ahe = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+
+
+Aaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Abaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Acaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Adaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Aeaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Afaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Agaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Ahaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Aaaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Abaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Acaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Adaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Aeaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Afaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Agaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Ahaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Aabaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Abbaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Acbaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Adbaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Aebaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Afbaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Agbaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Ahbaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Aacaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Abcaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Accaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Adcaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Aecaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Afcaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Agcaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Ahcaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Aadaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Abdaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Acdaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Addaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Aedaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Afdaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Agdaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Ahdaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Aaeaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Abeaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Aceaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Adeaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Aeeaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Afeaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Ageaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Aheaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+
+Aaaaaa= 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Abaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Acaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Adaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Aeaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Afaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Agaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Ahaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Aaaaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Abaaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Acaaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Adaaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Aeaaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Afaaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Agaaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Ahaaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Aabaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Abbaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Acbaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Adbaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Aebaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Afbaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Agbaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Ahbaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Aacaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Abcaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Accaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Adcaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Aecaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Afcaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Agcaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Ahcaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Aadaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Abdaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Acdaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Addaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Aedaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Afdaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Agdaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Ahdaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Aaeaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Abeaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Aceaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Adeaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Aeeaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Afeaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Ageaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Aheaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg'.
+
+
+lots_of_atoms3 () ->
+
+Aa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Ab = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Ac = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Ad = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Ae = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Af = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Ag = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Ah = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Aaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Aba = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Aca = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Ada = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Aea = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Afa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Aga = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Aha = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Aab = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Abb = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Acb = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Adb = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Aeb = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Afb = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Agb = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Ahb = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Aac = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Abc = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Acc = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Adc = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Aec = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Afc = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Agc = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Ahc = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Aad = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Abd = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Acd = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Add = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Aed = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Afd = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Agd = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Ahd = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Aae = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Abe = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Ace = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Ade = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Aee = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Afe = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Age = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Ahe = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+
+
+Aaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Abaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Acaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Adaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Aeaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Afaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Agaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Ahaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Aaaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Abaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Acaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Adaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Aeaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Afaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Agaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Ahaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Aabaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Abbaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Acbaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Adbaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Aebaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Afbaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Agbaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Ahbaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Aacaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Abcaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Accaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Adcaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Aecaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Afcaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Agcaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Ahcaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Aadaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Abdaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Acdaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Addaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Aedaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Afdaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Agdaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Ahdaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Aaeaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Abeaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Aceaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Adeaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Aeeaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Afeaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Ageaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Aheaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+
+Aaaaaa= 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Abaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Acaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Adaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Aeaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Afaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Agaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Ahaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Aaaaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Abaaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Acaaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Adaaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Aeaaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Afaaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Agaaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Ahaaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Aabaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Abbaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Acbaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Adbaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Aebaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Afbaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Agbaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Ahbaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Aacaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Abcaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Accaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Adcaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Aecaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Afcaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Agcaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Ahcaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Aadaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Abdaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Acdaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Addaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Aedaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Afdaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Agdaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Ahdaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Aaeaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Abeaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Aceaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Adeaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Aeeaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Afeaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Ageaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Aheaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg'.
+
+
+lots_of_atoms4 () ->
+
+Aa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Ab = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Ac = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Ad = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Ae = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Af = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Ag = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Ah = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Aaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Aba = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Aca = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Ada = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Aea = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Afa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Aga = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Aha = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Aab = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Abb = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Acb = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Adb = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Aeb = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Afb = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Agb = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Ahb = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Aac = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Abc = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Acc = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Adc = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Aec = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Afc = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Agc = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Ahc = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Aad = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Abd = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Acd = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Add = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Aed = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Afd = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Agd = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Ahd = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Aae = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Abe = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Ace = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Ade = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Aee = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Afe = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Age = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Ahe = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+
+
+Aaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Abaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Acaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Adaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Aeaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Afaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Agaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Ahaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Aaaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Abaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Acaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Adaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Aeaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Afaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Agaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Ahaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Aabaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Abbaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Acbaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Adbaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Aebaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Afbaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Agbaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Ahbaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Aacaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Abcaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Accaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Adcaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Aecaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Afcaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Agcaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Ahcaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Aadaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Abdaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Acdaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Addaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Aedaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Afdaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Agdaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Ahdaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Aaeaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Abeaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Aceaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Adeaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Aeeaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Afeaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Ageaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Aheaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+
+Aaaaaa= 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Abaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Acaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Adaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Aeaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Afaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Agaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Ahaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Aaaaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Abaaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Acaaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Adaaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Aeaaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Afaaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Agaaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Ahaaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Aabaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Abbaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Acbaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Adbaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Aebaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Afbaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Agbaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Ahbaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Aacaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Abcaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Accaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Adcaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Aecaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Afcaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Agcaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Ahcaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Aadaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Abdaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Acdaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Addaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Aedaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Afdaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Agdaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Ahdaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Aaeaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Abeaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Aceaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Adeaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Aeeaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Afeaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Ageaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Aheaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg'.
+
+
+lots_of_atoms5 () ->
+
+Aa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Ab = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Ac = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Ad = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Ae = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Af = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Ag = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Ah = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Aaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Aba = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Aca = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Ada = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Aea = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Afa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Aga = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Aha = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Aab = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Abb = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Acb = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Adb = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Aeb = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Afb = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Agb = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Ahb = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Aac = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Abc = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Acc = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Adc = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Aec = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Afc = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Agc = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Ahc = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Aad = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Abd = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Acd = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Add = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Aed = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Afd = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Agd = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Ahd = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Aae = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Abe = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Ace = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Ade = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Aee = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Afe = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Age = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Ahe = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+
+
+Aaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Abaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Acaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Adaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Aeaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Afaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Agaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Ahaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Aaaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Abaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Acaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Adaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Aeaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Afaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Agaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Ahaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Aabaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Abbaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Acbaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Adbaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Aebaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Afbaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Agbaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Ahbaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Aacaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Abcaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Accaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Adcaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Aecaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Afcaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Agcaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Ahcaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Aadaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Abdaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Acdaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Addaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Aedaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Afdaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Agdaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Ahdaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Aaeaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Abeaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Aceaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Adeaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Aeeaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Afeaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Ageaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Aheaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+
+Aaaaaa= 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Abaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Acaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Adaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Aeaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Afaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Agaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Ahaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Aaaaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Abaaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Acaaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Adaaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Aeaaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Afaaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Agaaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Ahaaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Aabaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Abbaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Acbaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Adbaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Aebaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Afbaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Agbaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Ahbaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Aacaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Abcaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Accaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Adcaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Aecaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Afcaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Agcaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Ahcaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Aadaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Abdaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Acdaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Addaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Aedaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Afdaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Agdaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Ahdaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Aaeaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Abeaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Aceaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Adeaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Aeeaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Afeaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Ageaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Aheaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg'.
+
+
+lots_of_atoms6 () ->
+
+Aa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Ab = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Ac = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Ad = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Ae = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Af = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Ag = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Ah = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Aaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Aba = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Aca = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Ada = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Aea = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Afa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Aga = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Aha = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Aab = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Abb = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Acb = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Adb = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Aeb = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Afb = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Agb = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Ahb = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Aac = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Abc = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Acc = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Adc = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Aec = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Afc = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Agc = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Ahc = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Aad = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Abd = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Acd = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Add = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Aed = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Afd = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Agd = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Ahd = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Aae = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Abe = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Ace = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Ade = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Aee = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Afe = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Age = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Ahe = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+
+
+Aaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Abaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Acaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Adaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Aeaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Afaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Agaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Ahaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Aaaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Abaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Acaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Adaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Aeaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Afaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Agaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Ahaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Aabaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Abbaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Acbaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Adbaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Aebaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Afbaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Agbaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Ahbaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Aacaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Abcaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Accaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Adcaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Aecaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Afcaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Agcaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Ahcaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Aadaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Abdaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Acdaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Addaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Aedaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Afdaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Agdaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Ahdaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Aaeaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Abeaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Aceaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Adeaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Aeeaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Afeaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Ageaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Aheaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+
+Aaaaaa= 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Abaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Acaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Adaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Aeaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Afaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Agaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Ahaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Aaaaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Abaaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Acaaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Adaaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Aeaaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Afaaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Agaaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Ahaaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Aabaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Abbaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Acbaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Adbaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Aebaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Afbaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Agbaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Ahbaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Aacaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Abcaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Accaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Adcaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Aecaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Afcaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Agcaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Ahcaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Aadaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Abdaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Acdaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Addaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Aedaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Afdaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Agdaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Ahdaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Aaeaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Abeaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Aceaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Adeaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Aeeaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Afeaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Ageaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Aheaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg'.
+
+
+lots_of_atoms7 () ->
+
+Aa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Ab = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Ac = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Ad = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Ae = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Af = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Ag = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Ah = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Aaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Aba = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Aca = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Ada = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Aea = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Afa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Aga = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Aha = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Aab = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Abb = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Acb = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Adb = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Aeb = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Afb = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Agb = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Ahb = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Aac = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Abc = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Acc = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Adc = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Aec = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Afc = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Agc = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Ahc = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Aad = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Abd = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Acd = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Add = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Aed = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Afd = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Agd = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Ahd = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Aae = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Abe = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Ace = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Ade = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Aee = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Afe = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Age = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Ahe = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+
+
+Aaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Abaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Acaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Adaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Aeaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Afaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Agaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Ahaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Aaaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Abaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Acaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Adaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Aeaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Afaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Agaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Ahaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Aabaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Abbaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Acbaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Adbaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Aebaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Afbaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Agbaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Ahbaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Aacaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Abcaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Accaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Adcaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Aecaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Afcaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Agcaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Ahcaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Aadaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Abdaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Acdaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Addaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Aedaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Afdaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Agdaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Ahdaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Aaeaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Abeaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Aceaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Adeaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Aeeaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Afeaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Ageaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Aheaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+
+Aaaaaa= 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Abaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Acaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Adaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Aeaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Afaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Agaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Ahaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Aaaaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Abaaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Acaaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Adaaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Aeaaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Afaaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Agaaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Ahaaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Aabaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Abbaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Acbaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Adbaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Aebaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Afbaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Agbaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Ahbaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Aacaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Abcaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Accaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Adcaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Aecaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Afcaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Agcaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Ahcaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Aadaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Abdaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Acdaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Addaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Aedaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Afdaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Agdaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Ahdaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Aaeaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Abeaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Aceaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Adeaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Aeeaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Afeaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Ageaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Aheaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg'.
+
+
+lots_of_atoms8 () ->
+
+Aa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Ab = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Ac = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Ad = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Ae = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Af = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Ag = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Ah = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Aaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Aba = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Aca = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Ada = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Aea = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Afa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Aga = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Aha = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Aab = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Abb = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Acb = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Adb = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Aeb = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Afb = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Agb = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Ahb = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Aac = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Abc = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Acc = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Adc = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Aec = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Afc = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Agc = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Ahc = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Aad = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Abd = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Acd = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Add = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Aed = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Afd = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Agd = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Ahd = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Aae = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Abe = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Ace = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Ade = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Aee = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Afe = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Age = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Ahe = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+
+
+Aaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Abaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Acaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Adaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Aeaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Afaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Agaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Ahaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Aaaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Abaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Acaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Adaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Aeaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Afaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Agaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Ahaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Aabaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Abbaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Acbaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Adbaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Aebaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Afbaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Agbaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Ahbaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Aacaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Abcaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Accaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Adcaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Aecaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Afcaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Agcaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Ahcaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Aadaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Abdaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Acdaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Addaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Aedaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Afdaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Agdaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Ahdaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Aaeaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Abeaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Aceaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Adeaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Aeeaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Afeaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Ageaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Aheaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+
+Aaaaaa= 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Abaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Acaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Adaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Aeaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Afaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Agaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Ahaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Aaaaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Abaaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Acaaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Adaaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Aeaaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Afaaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Agaaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Ahaaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Aabaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Abbaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Acbaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Adbaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Aebaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Afbaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Agbaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Ahbaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Aacaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Abcaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Accaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Adcaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Aecaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Afcaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Agcaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Ahcaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Aadaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Abdaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Acdaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Addaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Aedaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Afdaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Agdaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Ahdaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Aaeaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Abeaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Aceaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Adeaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Aeeaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Afeaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Ageaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Aheaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg'.
+
+
+lots_of_atoms9 () ->
+
+Aa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Ab = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Ac = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Ad = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Ae = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Af = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Ag = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Ah = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Aaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Aba = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Aca = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Ada = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Aea = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Afa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Aga = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Aha = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Aab = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Abb = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Acb = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Adb = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Aeb = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Afb = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Agb = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Ahb = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Aac = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Abc = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Acc = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Adc = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Aec = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Afc = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Agc = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Ahc = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Aad = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Abd = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Acd = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Add = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Aed = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Afd = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Agd = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Ahd = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Aae = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Abe = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Ace = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Ade = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Aee = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Afe = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Age = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Ahe = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+
+
+Aaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Abaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Acaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Adaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Aeaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Afaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Agaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Ahaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Aaaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Abaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Acaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Adaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Aeaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Afaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Agaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Ahaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Aabaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Abbaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Acbaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Adbaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Aebaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Afbaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Agbaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Ahbaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Aacaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Abcaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Accaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Adcaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Aecaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Afcaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Agcaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Ahcaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Aadaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Abdaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Acdaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Addaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Aedaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Afdaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Agdaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Ahdaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Aaeaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Abeaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Aceaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Adeaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Aeeaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Afeaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Ageaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Aheaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+
+Aaaaaa= 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Abaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Acaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Adaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Aeaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Afaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Agaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Ahaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Aaaaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Abaaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Acaaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Adaaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Aeaaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Afaaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Agaaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Ahaaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Aabaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Abbaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Acbaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Adbaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Aebaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Afbaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Agbaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Ahbaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Aacaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Abcaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Accaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Adcaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Aecaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Afcaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Agcaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Ahcaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Aadaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Abdaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Acdaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Addaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Aedaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Afdaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Agdaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Ahdaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Aaeaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Abeaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Aceaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Adeaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Aeeaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Afeaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Ageaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Aheaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg'.
+
+
+lots_of_atoms10 () ->
+
+Aa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Ab = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Ac = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Ad = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Ae = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Af = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Ag = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Ah = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Aaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Aba = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Aca = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Ada = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Aea = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Afa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Aga = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Aha = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Aab = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Abb = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Acb = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Adb = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Aeb = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Afb = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Agb = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Ahb = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Aac = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Abc = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Acc = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Adc = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Aec = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Afc = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Agc = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Ahc = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Aad = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Abd = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Acd = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Add = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Aed = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Afd = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Agd = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Ahd = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Aae = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Abe = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Ace = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Ade = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Aee = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Afe = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Age = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Ahe = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+
+
+Aaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Abaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Acaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Adaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Aeaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Afaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Agaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Ahaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Aaaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Abaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Acaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Adaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Aeaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Afaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Agaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Ahaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Aabaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Abbaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Acbaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Adbaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Aebaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Afbaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Agbaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Ahbaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Aacaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Abcaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Accaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Adcaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Aecaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Afcaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Agcaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Ahcaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Aadaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Abdaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Acdaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Addaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Aedaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Afdaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Agdaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Ahdaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Aaeaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Abeaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Aceaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Adeaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Aeeaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Afeaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Ageaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Aheaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+
+Aaaaaa= 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Abaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Acaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Adaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Aeaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Afaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Agaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Ahaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Aaaaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Abaaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Acaaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Adaaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Aeaaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Afaaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Agaaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Ahaaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Aabaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Abbaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Acbaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Adbaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Aebaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Afbaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Agbaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Ahbaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Aacaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Abcaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Accaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Adcaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Aecaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Afcaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Agcaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Ahcaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Aadaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Abdaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Acdaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Addaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Aedaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Afdaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Agdaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Ahdaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Aaeaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Abeaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Aceaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Adeaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Aeeaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Afeaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Ageaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Aheaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg'.
+
+
+lots_of_atoms11 () ->
+
+Aa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Ab = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Ac = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Ad = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Ae = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Af = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Ag = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Ah = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Aaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Aba = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Aca = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Ada = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Aea = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Afa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Aga = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Aha = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Aab = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Abb = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Acb = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Adb = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Aeb = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Afb = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Agb = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Ahb = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Aac = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Abc = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Acc = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Adc = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Aec = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Afc = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Agc = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Ahc = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Aad = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Abd = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Acd = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Add = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Aed = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Afd = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Agd = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Ahd = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Aae = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Abe = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Ace = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Ade = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Aee = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Afe = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Age = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Ahe = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+
+
+Aaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Abaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Acaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Adaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Aeaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Afaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Agaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Ahaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Aaaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Abaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Acaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Adaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Aeaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Afaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Agaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Ahaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Aabaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Abbaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Acbaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Adbaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Aebaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Afbaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Agbaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Ahbaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Aacaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Abcaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Accaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Adcaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Aecaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Afcaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Agcaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Ahcaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Aadaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Abdaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Acdaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Addaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Aedaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Afdaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Agdaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Ahdaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Aaeaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Abeaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Aceaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Adeaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Aeeaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Afeaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Ageaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Aheaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+
+Aaaaaa= 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Abaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Acaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Adaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Aeaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Afaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Agaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Ahaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Aaaaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Abaaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Acaaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Adaaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Aeaaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Afaaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Agaaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Ahaaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Aabaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Abbaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Acbaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Adbaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Aebaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Afbaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Agbaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Ahbaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Aacaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Abcaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Accaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Adcaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Aecaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Afcaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Agcaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Ahcaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Aadaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Abdaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Acdaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Addaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Aedaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Afdaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Agdaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Ahdaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Aaeaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Abeaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Aceaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Adeaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Aeeaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Afeaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Ageaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Aheaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg'.
+
+
+lots_of_atoms12 () ->
+
+Aa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Ab = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Ac = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Ad = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Ae = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Af = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Ag = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Ah = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Aaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Aba = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Aca = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Ada = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Aea = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Afa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Aga = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Aha = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Aab = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Abb = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Acb = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Adb = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Aeb = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Afb = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Agb = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Ahb = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Aac = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Abc = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Acc = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Adc = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Aec = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Afc = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Agc = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Ahc = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Aad = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Abd = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Acd = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Add = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Aed = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Afd = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Agd = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Ahd = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Aae = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Abe = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Ace = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Ade = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Aee = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Afe = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Age = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Ahe = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+
+
+Aaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Abaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Acaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Adaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Aeaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Afaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Agaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Ahaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Aaaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Abaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Acaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Adaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Aeaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Afaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Agaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Ahaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Aabaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Abbaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Acbaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Adbaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Aebaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Afbaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Agbaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Ahbaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Aacaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Abcaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Accaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Adcaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Aecaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Afcaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Agcaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Ahcaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Aadaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Abdaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Acdaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Addaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Aedaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Afdaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Agdaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Ahdaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Aaeaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Abeaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Aceaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Adeaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Aeeaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Afeaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Ageaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Aheaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+
+Aaaaaa= 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Abaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Acaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Adaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Aeaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Afaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Agaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Ahaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Aaaaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Abaaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Acaaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Adaaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Aeaaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Afaaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Agaaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Ahaaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Aabaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Abbaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Acbaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Adbaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Aebaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Afbaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Agbaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Ahbaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Aacaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Abcaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Accaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Adcaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Aecaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Afcaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Agcaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Ahcaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Aadaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Abdaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Acdaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Addaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Aedaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Afdaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Agdaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Ahdaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Aaeaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Abeaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Aceaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Adeaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Aeeaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Afeaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Ageaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg',
+
+Aheaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg'.
diff --git a/lib/debugger/test/int_SUITE_data/ordsets1.erl b/lib/debugger/test/int_SUITE_data/ordsets1.erl
new file mode 100644
index 0000000000..a01d35eb51
--- /dev/null
+++ b/lib/debugger/test/int_SUITE_data/ordsets1.erl
@@ -0,0 +1,191 @@
+%%
+%% %CopyrightBegin%
+%%
+%% 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%
+%%
+
+%%
+%% Copyright (C) 1991, Ellemtel Telecommunications Systems Laboratories
+%% File : ordsets.erl
+%% Author : Robert Virding
+%% Purpose : Functions for manipulating sets as ordered lists.
+
+%% As yet some of these are not very efficiently written.
+
+-module(ordsets1).
+
+-export([new_set/0,is_set/1,set_to_list/1,list_to_set/1]).
+-export([is_element/2,add_element/2,del_element/2]).
+-export([union/2,union/1,intersection/2,intersection/1]).
+-export([subtract/2,subset/2]).
+
+%% new_set()
+%% Return a new empty ordered set.
+
+new_set() ->
+ [].
+
+%% is_set(Set)
+%% Return 'true' if Set is an ordered set of elements, else 'false'.
+
+is_set([E|Es]) ->
+ is_set(Es, E);
+is_set([]) ->
+ true.
+
+is_set([E2|Es], E1) when E1 < E2 ->
+ is_set(Es, E2);
+is_set([E2|Es], E1) ->
+ false;
+is_set([], E1) ->
+ true.
+
+%% set_to_list(OrdSet)
+%% Return the elements in OrdSet as a list.
+
+set_to_list(S) ->
+ S.
+
+%% list_to_set(List)
+%% Build an ordered set from the elements in List.
+
+list_to_set([E|Es]) ->
+ add_element(E, list_to_set(Es));
+list_to_set([]) ->
+ [].
+
+%% is_element(Element, OrdSet)
+%% Return 'true' if Element is an element of OrdSet, else 'false'.
+
+is_element(E, [H|Es]) when E < H ->
+ false;
+is_element(E, [H|Es]) when E == H ->
+ true;
+is_element(E, [H|Es]) when E > H ->
+ is_element(E, Es);
+is_element(E, []) ->
+ false.
+
+%% add_element(Element, OrdSet)
+%% Return OrdSet with Element inserted in it.
+
+add_element(E, [H|Es]) when E < H ->
+ [E,H|Es];
+add_element(E, [H|Es]) when E == H ->
+ [H|Es];
+add_element(E, [H|Es]) when E > H ->
+ [H|add_element(E, Es)];
+add_element(E, []) ->
+ [E].
+
+%% del_element(Element, OrdSet)
+%% Return OrdSet but with Element removed.
+
+del_element(E, [H|Es]) when E < H ->
+ [H|Es];
+del_element(E, [H|Es]) when E == H ->
+ Es;
+del_element(E, [H|Es]) when E > H ->
+ [H|del_element(E, Es)];
+del_element(E, []) ->
+ [].
+
+%% union(Set1, Set2)
+%% Return the union of Set1 and Set2.
+
+union([H1|Es1], [H2|Es2]) when H1 < H2 ->
+ [H1|union(Es1, [H2|Es2])];
+union([H1|Es1], [H2|Es2]) when H1 == H2 ->
+ [H1|union(Es1, Es2)];
+union([H1|Es1], [H2|Es2]) when H1 > H2 ->
+ [H2|union([H1|Es1], Es2)];
+union([], Es2) ->
+ Es2;
+union(Es1, []) ->
+ Es1.
+
+%% union(OrdSets)
+%% Return the union of the list of sets.
+
+union([S1,S2|Ss]) ->
+ union1(union(S1,S2), Ss);
+union([S]) ->
+ S;
+union([]) ->
+ [].
+
+union1(S1, [S2|Ss]) ->
+ union1(union(S1, S2), Ss);
+union1(S1, []) ->
+ S1.
+
+%% intersection(Set1, Set2)
+%% Return the intersection of Set1 and Set2.
+
+intersection([H1|Es1], [H2|Es2]) when H1 < H2 ->
+ intersection(Es1, [H2|Es2]);
+intersection([H1|Es1], [H2|Es2]) when H1 == H2 ->
+ [H1|intersection(Es1, Es2)];
+intersection([H1|Es1], [H2|Es2]) when H1 > H2 ->
+ intersection([H1|Es1], Es2);
+intersection([], Es2) ->
+ [];
+intersection(Es1, []) ->
+ [].
+
+%% intersection(OrdSets)
+%% Return the intersection of the list of sets.
+
+intersection([S1,S2|Ss]) ->
+ intersection1(intersection(S1,S2), Ss);
+intersection([S]) ->
+ S;
+intersection([]) ->
+ [].
+
+intersection1(S1, [S2|Ss]) ->
+ intersection1(intersection(S1, S2), Ss);
+intersection1(S1, []) ->
+ S1.
+
+%% subtract(Set1, Set2)
+%% Return all and only the elements of Set1 which are not also in Set2.
+
+subtract([H1|Es1], [H2|Es2]) when H1 < H2 ->
+ [H1|subtract(Es1, [H2|Es2])];
+subtract([H1|Es1], [H2|Es2]) when H1 == H2 ->
+ subtract(Es1, Es2);
+subtract([H1|Es1], [H2|Es2]) when H1 > H2 ->
+ subtract([H1|Es1], Es2);
+subtract([], Es2) ->
+ [];
+subtract(Es1, []) ->
+ Es1.
+
+%% subset(Set1, Set2)
+%% Return 'true' when every element of Set1 is also a member of Set2,
+%% else 'false'.
+
+subset([H1|Es1], [H2|Es2]) when H1 < H2 -> %H1 not in Set2
+ false;
+subset([H1|Es1], [H2|Es2]) when H1 == H2 ->
+ subset(Es1, Es2);
+subset([H1|Es1], [H2|Es2]) when H1 > H2 ->
+ subset([H1|Es1], Es2);
+subset([], Es2) ->
+ true;
+subset(Es1, []) ->
+ false.
diff --git a/lib/debugger/test/int_SUITE_data/test.erl b/lib/debugger/test/int_SUITE_data/test.erl
new file mode 100644
index 0000000000..679b266380
--- /dev/null
+++ b/lib/debugger/test/int_SUITE_data/test.erl
@@ -0,0 +1,152 @@
+%%
+%% %CopyrightBegin%
+%%
+%% 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%
+%%
+
+%%
+
+-module(test).
+
+%%-compile(export_all).
+-export([test1/0,
+ test2/0,
+ test3/0,
+ test4/0,
+ test5/0,
+ test6/1,
+ test7/0,
+ test8/1,
+ test9/0,
+ test10/0,
+ test11/0
+ ]).
+
+
+-export([test9_server/1]).
+
+
+test1() ->
+ R1 = lists1:reverse("retep"),
+ R2 = ordsets1:list_to_set([b,c,a,2,4,1]),
+ R3 = lists1:reverse("nilo"),
+ {R1,R2, R3}.
+
+test2() ->
+ R1 = spawn(lists1,reverse,["retep"]),
+ R2 = spawn(ordsets1,list_to_set,[[b,c,a,2,4,1]]),
+ R3 = spawn(lists1,reverse,["nilo"]),
+ {R1,R2, R3}.
+
+
+test3() ->
+ A = a,
+ Pid = spawn(?MODULE, test1,[]),
+ B = b,
+ {A, B, Pid}.
+
+test4() ->
+ Pid = spawn(?MODULE, test1,[]),
+ A = a,
+ B = b,
+ {A, B, Pid}.
+test5() ->
+ L1 = [a,b,c],
+ L = length(L1),
+ A = a,
+ B = b,
+ {A, B, L, L1}.
+
+
+
+test6(0) ->
+ ok;
+test6(N) when N>0 ->
+ spawn(lists1,reverse,["adolfiparisrorsirapifloda"]),
+ test6(N-1).
+
+
+test7() ->
+ CurDirReturn = file:get_cwd(),
+ {ok, CurDir} = CurDirReturn,
+ DirListReturn = file:list_dir(CurDir),
+ {ok, DirList} = DirListReturn,
+ io:format("~w~n",[DirList]).
+
+
+test8(List) ->
+ %% foo
+ %%bar
+ %% foo
+ %%bar
+ %% foo
+ %%bar
+ %% foo
+ %%bar
+
+ L2 = [gamma|List],
+ {L2, List}.
+
+test9() ->
+ S1 = spawn(?MODULE, test9_server,[self()]),
+ S2 = spawn(?MODULE, test9_server,[bongo]),
+ S3 = spawn(?MODULE, test9_server,[42]),
+
+ test9_loop(S1,S2,S3).
+
+test9_loop(S1,S2,S3) ->
+ receive
+ {S1, hej} ->
+ io:format("S1 ~n"),
+ test9_loop(S1,S2,S3);
+ {S2, hej} ->
+ io:format("S2 ~n"),
+ test9_loop(S1,S2,S3);
+ {S3, hej} ->
+ io:format("S3 ~n"),
+ test9_loop(S1,S2,S3)
+ end.
+
+
+test9_server(Pid) ->
+ io:format("started server: ~p~n",[Pid]),
+ test9_server1(Pid).
+
+test9_server1(Pid) ->
+ Pad = {pad, Pid},
+ test9_server2(Pad).
+
+test9_server2(Pad) ->
+ {pad, Pid} = Pad,
+ Pid ! {self(), hej}.
+
+
+
+
+
+test10() ->
+ receive
+ X ->
+ done
+ after 20000 ->
+ timeout
+ end.
+
+test11() ->
+ receive
+ X ->
+ done
+ end.
diff --git a/lib/debugger/test/int_SUITE_data/test1.erl b/lib/debugger/test/int_SUITE_data/test1.erl
new file mode 100644
index 0000000000..a93416cbac
--- /dev/null
+++ b/lib/debugger/test/int_SUITE_data/test1.erl
@@ -0,0 +1,34 @@
+%%
+%% %CopyrightBegin%
+%%
+%% 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%
+%%
+
+%%
+-module(test1).
+
+-compile(export_all).
+
+
+foo() ->
+ A = [1,2,3],
+ B = [a,b,c],
+ C = [d,e,f],
+ D = my_lists:append(A,B),
+ E = my_lists:append(D,C),
+ F = [1],
+ G = my_lists:append(E,F),
+ {A,B,C,D,E,F,G}.
diff --git a/lib/debugger/test/int_break_SUITE.erl b/lib/debugger/test/int_break_SUITE.erl
new file mode 100644
index 0000000000..b7b3c5598a
--- /dev/null
+++ b/lib/debugger/test/int_break_SUITE.erl
@@ -0,0 +1,92 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 1999-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(int_break_SUITE).
+
+%% Test break points.
+
+-include("test_server.hrl").
+
+-export([all/1,init_per_testcase/2,fin_per_testcase/2,
+ basic/1,cleanup/1]).
+
+-export([auto_attach/1]).
+
+all(suite) ->
+ [basic,cleanup].
+
+init_per_testcase(_Case, Config) ->
+ ?line DataDir = ?config(data_dir, Config),
+ ?line Mod = ordsets1,
+ ?line {module,Mod} = int:i(filename:join(DataDir, Mod)),
+ ?line ok = io:format("Interpreted modules: ~p", [int:interpreted()]),
+ ?line Dog = test_server:timetrap(?t:minutes(0.5)),
+ [{watchdog,Dog}|Config].
+
+fin_per_testcase(_Case, Config) ->
+ ?line ok = io:format("Interpreted modules: ~p", [int:interpreted()]),
+ ?line Dog = ?config(watchdog, Config),
+ ?t:timetrap_cancel(Dog),
+ ok.
+
+basic(doc) -> "Tests setting a few break points.";
+basic(suite) -> [];
+basic(Config) when list(Config) ->
+ ?line int:auto_attach([init], {?MODULE,auto_attach}),
+ ?line S1 = [] = ordsets1:new_set(),
+ ?line ok = i:ib(ordsets1, 86),
+ ?line S2 = [xxx] = ordsets1:add_element(xxx, S1),
+ ?line S3 = [xxx,y] = ordsets1:add_element(y, S2),
+ ?line ok = i:ib(ordsets1, union, 2),
+ ?line [xxx,y,z] = ordsets1:union(S3, [z]),
+ ok.
+
+cleanup(doc) -> "Make sure that the auto-attach flag is turned off.";
+cleanup(suite) -> [];
+cleanup(Config) when list(Config) ->
+ ?line int:auto_attach(false),
+ ok.
+
+auto_attach(Pid) ->
+ {ok, Meta} = int:attached(Pid),
+ io:format("Pid = ~p; Meta = ~p", [Pid,Meta]),
+ link(Meta),
+ attach_loop(Pid, Meta).
+
+attach_loop(Pid, Meta) ->
+ receive
+ Msg ->
+ io:format("attached: ~p", [Msg]),
+ attach_cmd(Msg, Pid, Meta),
+ attach_loop(Pid, Meta)
+ end.
+
+attach_cmd({Meta,{break_at,ordsets1,36,2}}, _Pid, Meta) ->
+ int:meta(Meta, continue);
+attach_cmd({Meta,{break_at,ordsets1,87,_}}, _Pid, Meta) ->
+ int:meta(Meta, continue);
+attach_cmd({Meta,{break_at,ordsets1,89,_}}, _Pid, Meta) ->
+ int:meta(Meta, continue);
+attach_cmd({Meta,{break_at,ordsets1,Line,_}}, _Pid, Meta) when 107 =< Line, Line =< 115 ->
+ int:meta(Meta, finish);
+attach_cmd({Meta,{break_at,_Mod,_Line,_Other}}=Cmd, _Pid, Meta) ->
+ io:format("attached: no action for ~p", [Cmd]);
+attach_cmd(_, _Pid, _Meta) ->
+ ok.
diff --git a/lib/debugger/test/int_break_SUITE_data/Makefile.src b/lib/debugger/test/int_break_SUITE_data/Makefile.src
new file mode 100644
index 0000000000..0d1ee35a67
--- /dev/null
+++ b/lib/debugger/test/int_break_SUITE_data/Makefile.src
@@ -0,0 +1,25 @@
+#
+# %CopyrightBegin%
+#
+# Copyright Ericsson AB 2000-2010. All Rights Reserved.
+#
+# The contents of this file are subject to the Erlang Public License,
+# Version 1.1, (the "License"); you may not use this file except in
+# compliance with the License. You should have received a copy of the
+# Erlang Public License along with this software. If not, it can be
+# retrieved online at http://www.erlang.org/.
+#
+# Software distributed under the License is distributed on an "AS IS"
+# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+# the License for the specific language governing rights and limitations
+# under the License.
+#
+# %CopyrightEnd%
+#
+
+EFLAGS=+debug_info
+
+all: ordsets1.@EMULATOR@
+
+ordsets1.@EMULATOR@: ordsets1.erl
+ erlc $(EFLAGS) ordsets1.erl
diff --git a/lib/debugger/test/int_break_SUITE_data/ordsets1.erl b/lib/debugger/test/int_break_SUITE_data/ordsets1.erl
new file mode 100644
index 0000000000..6300c6097c
--- /dev/null
+++ b/lib/debugger/test/int_break_SUITE_data/ordsets1.erl
@@ -0,0 +1,188 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 1999-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%
+%%
+
+%%
+%% Purpose : Functions for manipulating sets as ordered lists.
+
+%% As yet some of these are not very efficiently written.
+
+-module(ordsets1).
+
+-export([new_set/0,is_set/1,set_to_list/1,list_to_set/1]).
+-export([is_element/2,add_element/2,del_element/2]).
+-export([union/2,union/1,intersection/2,intersection/1]).
+-export([subtract/2,subset/2]).
+
+%% new_set()
+%% Return a new empty ordered set.
+
+new_set() ->
+ [].
+
+%% is_set(Set)
+%% Return 'true' if Set is an ordered set of elements, else 'false'.
+
+is_set([E|Es]) ->
+ is_set(Es, E);
+is_set([]) ->
+ true.
+
+is_set([E2|Es], E1) when E1 < E2 ->
+ is_set(Es, E2);
+is_set([E2|Es], E1) ->
+ false;
+is_set([], E1) ->
+ true.
+
+%% set_to_list(OrdSet)
+%% Return the elements in OrdSet as a list.
+
+set_to_list(S) ->
+ S.
+
+%% list_to_set(List)
+%% Build an ordered set from the elements in List.
+
+list_to_set([E|Es]) ->
+ add_element(E, list_to_set(Es));
+list_to_set([]) ->
+ [].
+
+%% is_element(Element, OrdSet)
+%% Return 'true' if Element is an element of OrdSet, else 'false'.
+
+is_element(E, [H|Es]) when E < H ->
+ false;
+is_element(E, [H|Es]) when E == H ->
+ true;
+is_element(E, [H|Es]) when E > H ->
+ is_element(E, Es);
+is_element(E, []) ->
+ false.
+
+%% add_element(Element, OrdSet)
+%% Return OrdSet with Element inserted in it.
+
+add_element(E, [H|_]=Es) when E < H ->
+ [E|Es];
+add_element(E, [H|_]=Es) when E == H ->
+ Es;
+add_element(E, [H|Es]) when E > H ->
+ [H|add_element(E, Es)];
+add_element(E, []) ->
+ [E].
+
+%% del_element(Element, OrdSet)
+%% Return OrdSet but with Element removed.
+
+del_element(E, [H|_]=Es) when E < H ->
+ Es;
+del_element(E, [H|Es]) when E == H ->
+ Es;
+del_element(E, [H|Es]) when E > H ->
+ [H|del_element(E, Es)];
+del_element(E, []) ->
+ [].
+
+%% union(Set1, Set2)
+%% Return the union of Set1 and Set2.
+
+union([H1|Es1], [H2|_]=Es2) when H1 < H2 ->
+ [H1|union(Es1, Es2)];
+union([H1|Es1], [H2|Es2]) when H1 == H2 ->
+ [H1|union(Es1, Es2)];
+union([H1|_]=Es1, [H2|Es2]) when H1 > H2 ->
+ [H2|union(Es1, Es2)];
+union([], Es2) ->
+ Es2;
+union(Es1, []) ->
+ Es1.
+
+%% union(OrdSets)
+%% Return the union of the list of sets.
+
+union([S1,S2|Ss]) ->
+ union1(union(S1,S2), Ss);
+union([S]) ->
+ S;
+union([]) ->
+ [].
+
+union1(S1, [S2|Ss]) ->
+ union1(union(S1, S2), Ss);
+union1(S1, []) ->
+ S1.
+
+%% intersection(Set1, Set2)
+%% Return the intersection of Set1 and Set2.
+
+intersection([H1|Es1], [H2|_]=Es2) when H1 < H2 ->
+ intersection(Es1, Es2);
+intersection([H1|Es1], [H2|Es2]) when H1 == H2 ->
+ [H1|intersection(Es1, Es2)];
+intersection([H1|_]=Es1, [H2|Es2]) when H1 > H2 ->
+ intersection(Es1, Es2);
+intersection([], Es2) ->
+ [];
+intersection(Es1, []) ->
+ [].
+
+%% intersection(OrdSets)
+%% Return the intersection of the list of sets.
+
+intersection([S1,S2|Ss]) ->
+ intersection1(intersection(S1,S2), Ss);
+intersection([S]) ->
+ S;
+intersection([]) ->
+ [].
+
+intersection1(S1, [S2|Ss]) ->
+ intersection1(intersection(S1, S2), Ss);
+intersection1(S1, []) ->
+ S1.
+
+%% subtract(Set1, Set2)
+%% Return all and only the elements of Set1 which are not also in Set2.
+
+subtract([H1|Es1], [H2|_]=Es2) when H1 < H2 ->
+ [H1|subtract(Es1, Es2)];
+subtract([H1|Es1], [H2|Es2]) when H1 == H2 ->
+ subtract(Es1, Es2);
+subtract([H1|_]=Es1, [H2|Es2]) when H1 > H2 ->
+ subtract(Es1, Es2);
+subtract([], Es2) ->
+ [];
+subtract(Es1, []) ->
+ Es1.
+
+%% subset(Set1, Set2)
+%% Return 'true' when every element of Set1 is also a member of Set2,
+%% else 'false'.
+
+subset([H1|Es1], [H2|Es2]) when H1 < H2 -> %H1 not in Set2
+ false;
+subset([H1|Es1], [H2|Es2]) when H1 == H2 ->
+ subset(Es1, Es2);
+subset([H1|Es1], [H2|Es2]) when H1 > H2 ->
+ subset([H1|Es1], Es2);
+subset([], Es2) ->
+ true;
+subset(Es1, []) ->
+ false.
diff --git a/lib/debugger/test/int_eval_SUITE.erl b/lib/debugger/test/int_eval_SUITE.erl
new file mode 100644
index 0000000000..19b006e750
--- /dev/null
+++ b/lib/debugger/test/int_eval_SUITE.erl
@@ -0,0 +1,277 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 1999-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(int_eval_SUITE).
+
+%% Purpose: Deeper test of the evaluator.
+
+-export([all/1,init_per_testcase/2, fin_per_testcase/2,
+ bifs_outside_erlang/1, spawning/1, applying/1,
+ catch_and_throw/1, external_call/1, test_module_info/1,
+ apply_interpreted_fun/1, apply_uninterpreted_fun/1,
+ interpreted_exit/1, otp_8310/1]).
+
+%% Helpers.
+-export([applier/3]).
+
+-define(IM, my_int_eval_module).
+
+-include("test_server.hrl").
+
+all(suite) ->
+ [bifs_outside_erlang,spawning,applying,catch_and_throw,
+ external_call,test_module_info,
+ apply_interpreted_fun,apply_uninterpreted_fun,
+ interpreted_exit, otp_8310].
+
+init_per_testcase(_Case, Config) ->
+ ?line DataDir = ?config(data_dir, Config),
+ ?line {module,?IM} = int:i(filename:join(DataDir, ?IM)),
+ ?line ok = io:format("Interpreted modules: ~p",[int:interpreted()]),
+ {ok, Dog} = timer:apply_after(timer:minutes(1),
+ erlang, exit, [self(), kill]),
+ [{watchdog,Dog}|Config].
+
+fin_per_testcase(_Case, Config) ->
+ ok = io:format("Interpreted modules: ~p", [int:interpreted()]),
+ Dog = ?config(watchdog, Config),
+ timer:cancel(Dog),
+ ok.
+
+bifs_outside_erlang(doc) ->
+ "Test that BIFs outside the erlang module are correctly evaluated.";
+bifs_outside_erlang(suite) ->
+ [];
+bifs_outside_erlang(Config) when is_list(Config) ->
+ Fun = fun() ->
+ Id = ?IM:ets_new(),
+ Self = self(),
+ ok = io:format("Self: ~p", [Self]),
+ Info = ets:info(Id),
+ {owner,Self} = lists:nth(2, Info),
+ %% Was
+ %% {owner,Self} = element(2, Info),
+ %% in R10B.
+ ?IM:ets_delete(Id),
+ ok
+ end,
+ ?line ok = spawn_eval(Fun),
+ ok.
+
+spawning(doc) ->
+ "Try evalutate spawn_link/3.";
+spawning(suite) ->
+ [];
+spawning(Config) when is_list(Config) ->
+ ?line ok = spawn_eval(fun() -> ?IM:spawn_test() end).
+
+applying(doc) ->
+ "Try various sorts of applies.";
+applying(suite) ->
+ [];
+applying(Config) when is_list(Config) ->
+ Fun = fun({number,X}, {number,Y}) -> X+Y end,
+ ?line ok = spawn_eval(fun() -> ?IM:apply_test(Fun) end).
+
+catch_and_throw(doc) ->
+ "Test catch and throw/1.";
+catch_and_throw(suite) ->
+ [];
+catch_and_throw(Config) when is_list(Config) ->
+ {a,ball} = spawn_eval(fun() -> ok = ?IM:catch_a_ball(),
+ catch ?IM:throw_a_ball() end),
+
+ %% Throw and catch without any extra outer catch.
+
+ ?line process_flag(trap_exit, true),
+ ?line Pid1 = spawn_link(fun() -> exit(?IM:catch_a_ball()) end),
+ receive
+ {'EXIT',Pid1,ok} -> ok;
+ {'EXIT',Pid1,Bad1} -> ?line ?t:fail({bad_message,Bad1})
+ after 5000 ->
+ ?line ?t:fail(timeout)
+ end,
+
+
+ %% Throw without catch.
+
+ ?line Pid2 = spawn_link(fun() -> ?IM:throw_a_ball() end),
+ receive
+ {'EXIT',Pid2,{{nocatch,{a,ball}},[_|_]}} -> ok;
+ {'EXIT',Pid2,Bad2} -> ?line ?t:fail({bad_message,Bad2})
+ after 5000 ->
+ ?line ?t:fail(timeout)
+ end,
+
+ ?line ok = ?IM:more_catch(fun(_) -> ?IM:exit_me() end),
+ ?line ok = ?IM:more_catch(fun(_) -> exit({unint, exit}) end),
+ ?line {a, ball} = ?IM:more_catch(fun(_) -> ?IM:throw_a_ball() end),
+ ?line {b, ball} = ?IM:more_catch(fun(_) -> throw({b,ball}) end),
+
+ ExitInt = {'EXIT',{int,exit}},
+ ExitU = {'EXIT',{unint,exit}},
+
+ ?line ExitInt = (catch ?IM:more_nocatch(fun(_) -> ?IM:exit_me() end)),
+ ?line ExitU = (catch ?IM:more_nocatch(fun(_) -> exit({unint, exit}) end)),
+ ?line {a, ball} = (catch {error, ?IM:more_nocatch(fun(_) -> ?IM:throw_a_ball() end)}),
+ ?line {b, ball} = (catch {error, ?IM:more_nocatch(fun(_) -> throw({b,ball}) end)}),
+ ok.
+
+external_call(doc) ->
+ "Test external calls.";
+external_call(suite) ->
+ [];
+external_call(Config) when is_list(Config) ->
+ ?line ok = spawn_eval(fun() -> ?IM:external_call_test({some,stupid,data}) end).
+
+test_module_info(doc) ->
+ "Test the module_info/0,1 functions.";
+test_module_info(suite) ->
+ [];
+test_module_info(Config) when is_list(Config) ->
+ ?line ModInfo = ?IM:module_info(),
+ ?line {value,{exports,Exp}} = lists:keysearch(exports, 1, ModInfo),
+ ?line {value,{attributes,Attr}} = lists:keysearch(attributes, 1, ModInfo),
+ ?line Exp = ?IM:module_info(exports),
+ ?line Attr = ?IM:module_info(attributes),
+ ?line {value,{stupid_attribute,[{a,b}]}} =
+ lists:keysearch(stupid_attribute, 1, Attr),
+
+ %% Check exports using a list comprehension in the module itself.
+
+ ?line ok = ?IM:check_exports(Exp),
+
+ %% Call module_info/0,1 from the module itself.
+
+ ?line ok = ?IM:check_module_info(ModInfo, Exp),
+
+ ok.
+
+apply_interpreted_fun(doc) ->
+ "Apply a fun defined in interpreted code.";
+apply_interpreted_fun(suite) -> [];
+apply_interpreted_fun(Config) when is_list(Config) ->
+
+ %% Called from uninterpreted code
+ ?line F1 = spawn_eval(fun() -> ?IM:give_me_a_fun_0() end),
+ ?line perfectly_alright = spawn_eval(fun() -> F1() end),
+ ?line ATerm = {a,term},
+ ?line F2 = spawn_eval(fun() -> ?IM:give_me_a_fun_0(ATerm) end),
+ ?line {ok,ATerm} = spawn_eval(fun() -> F2() end),
+
+ %% Called from uninterpreted code, badarity
+ ?line {'EXIT',{{badarity,{F1,[snape]}},[{?MODULE,_,_}|_]}} =
+ spawn_eval(fun() -> F1(snape) end),
+
+ %% Called from uninterpreted code, error in fun
+ ?line F3 = spawn_eval(fun() -> ?IM:give_me_a_bad_fun() end),
+ ?line {'EXIT',{snape,[{?IM,_FunName,_}|_]}} =
+ spawn_eval(fun() -> F3(snape) end),
+
+ %% Called from within interpreted code
+ ?line perfectly_alright = spawn_eval(fun() -> ?IM:do_apply(F1) end),
+
+ %% Called from within interpreted code, badarity
+ ?line {'EXIT',{{badarity,{F1,[snape]}},[{?IM,do_apply,_}|_]}} =
+ spawn_eval(fun() -> ?IM:do_apply(F1, snape) end),
+
+ %% Called from within interpreted code, error in fun
+ ?line {'EXIT',{snape,[{?IM,_FunName,_}|_]}} =
+ spawn_eval(fun() -> ?IM:do_apply(F3, snape) end),
+
+ %% Try some more complex funs.
+ ?line F4 = ?IM:give_me_a_fun_1(14, 42),
+ ?line {false,yes,yeah,false} =
+ F4({{1,nope},{14,yes},{42,yeah},{100,forget_it}}),
+ ?line [this_is_ok,me_too] =
+ F4([{-24,no_way},{15,this_is_ok},{1333,forget_me},{37,me_too}]),
+
+ %% OTP-5837
+ %% Try fun with guard containing variable bound in environment
+ ?line [yes,no,no,no] = ?IM:otp_5837(1),
+
+ ok.
+
+apply_uninterpreted_fun(doc) ->
+ "Apply a fun defined outside interpreted code.";
+apply_uninterpreted_fun(suite) -> [];
+apply_uninterpreted_fun(Config) when is_list(Config) ->
+
+ ?line F1 = fun(snape) ->
+ erlang:error(snape);
+ (_Arg) ->
+ perfectly_alright
+ end,
+
+ %% Ok
+ ?line perfectly_alright =
+ spawn_eval(fun() -> ?IM:do_apply(F1, any_arg) end),
+
+ %% Badarity (evaluated in dbg_debugged, which calls erlang:apply/2)
+ ?line {'EXIT',{{badarity,{F1,[]}},[{erlang,apply,_}|_]}} =
+ spawn_eval(fun() -> ?IM:do_apply(F1) end),
+
+ %% Error in fun
+ ?line {'EXIT',{snape,[{?MODULE,_FunName,_}|_]}} =
+ spawn_eval(fun() -> ?IM:do_apply(F1, snape) end),
+
+ ok.
+
+%%
+%% Try executing an interpreted exit/1 call.
+%%
+
+interpreted_exit(Config) when is_list(Config) ->
+ ?line process_flag(trap_exit, true),
+ ?line Reason = make_ref(),
+ ?line Pid = spawn_link(fun() -> ?IM:please_call_exit(Reason) end),
+ ?line receive
+ {'EXIT',Pid,Reason} ->
+ ok;
+ {'EXIT',Pid,BadReason} ->
+ ?line ?t:fail({bad_message,BadReason})
+ after 10000 ->
+ ?line ?t:fail(timeout)
+ end,
+ ok.
+
+otp_8310(doc) ->
+ "OTP-8310. Bugfixes lc/bc and andalso/orelse.";
+otp_8310(Config) when is_list(Config) ->
+ ?line ok = ?IM:otp_8310(),
+ ok.
+
+applier(M, F, A) ->
+ Res = apply(M, F, A),
+ io:format("~p:~p(~p) => ~p\n", [M,F,A,Res]),
+ Res.
+
+%%
+%% Evaluate in another process, to prevent the test_case process to become
+%% interpreted.
+%%
+
+spawn_eval(Fun) ->
+ Self = self(),
+ spawn_link(fun() -> Self ! (catch Fun()) end),
+ receive
+ Result ->
+ Result
+ end.
diff --git a/lib/debugger/test/int_eval_SUITE_data/Makefile.src b/lib/debugger/test/int_eval_SUITE_data/Makefile.src
new file mode 100644
index 0000000000..28a1432157
--- /dev/null
+++ b/lib/debugger/test/int_eval_SUITE_data/Makefile.src
@@ -0,0 +1,26 @@
+#
+# %CopyrightBegin%
+#
+# Copyright Ericsson AB 2000-2010. All Rights Reserved.
+#
+# The contents of this file are subject to the Erlang Public License,
+# Version 1.1, (the "License"); you may not use this file except in
+# compliance with the License. You should have received a copy of the
+# Erlang Public License along with this software. If not, it can be
+# retrieved online at http://www.erlang.org/.
+#
+# Software distributed under the License is distributed on an "AS IS"
+# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+# the License for the specific language governing rights and limitations
+# under the License.
+#
+# %CopyrightEnd%
+#
+
+
+EFLAGS=+debug_info
+
+all: my_int_eval_module.@EMULATOR@
+
+my_int_eval_module.@EMULATOR@: my_int_eval_module.erl
+ erlc $(EFLAGS) my_int_eval_module.erl
diff --git a/lib/debugger/test/int_eval_SUITE_data/my_int_eval_module.erl b/lib/debugger/test/int_eval_SUITE_data/my_int_eval_module.erl
new file mode 100644
index 0000000000..997ee6e17d
--- /dev/null
+++ b/lib/debugger/test/int_eval_SUITE_data/my_int_eval_module.erl
@@ -0,0 +1,245 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 1999-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(my_int_eval_module).
+-stupid_attribute({a,b}).
+
+-export([ets_new/0,ets_delete/1,spawn_test/0,apply_test/1,external_call_test/1]).
+-export([check_exports/1,check_module_info/2]).
+-export([give_me_a_fun_0/0,give_me_a_fun_0/1,give_me_a_fun_1/2,
+ give_me_a_bad_fun/0, do_apply/1, do_apply/2]).
+-export([please_call_exit/1,i_will_do_the_exit/1]).
+-export([more_catch/1,more_nocatch/1,exit_me/0]).
+-export([f/1, f_try/1, f_catch/1]).
+-export([otp_5837/1, otp_8310/0]).
+
+%% Internal exports.
+-export([echo/2,my_subtract/2,catch_a_ball/0,throw_a_ball/0]).
+-export([i_am_exported/1]).
+
+-import(lists, [member/2]).
+
+-define(line,put(test_server_loc,{?MODULE,?LINE}),).
+-define(t,test_server).
+-define(m,test_server:match).
+-define(config,test_server:lookup_config).
+
+ets_new() ->
+ Id = ets:new(my_int_eval_table, [private]),
+ Id.
+
+ets_delete(Tab) ->
+ ets:delete(Tab).
+
+%% Spawning.
+
+spawn_test() ->
+ Term = {a,tuple},
+ Pid = spawn_link(?MODULE, echo, [self(),Term]),
+ receive
+ {result,Pid,Term} -> ok;
+ Other -> {bad_response,Other}
+ after 5000 ->
+ timeout
+ end.
+
+echo(Parent, Term) ->
+ Parent ! {result,self(),Term}.
+
+%% Applying.
+
+apply_test(Fun) ->
+ 42 = Fun(number(2), number(40)),
+ 12 = apply(Fun, [number(7),number(5)]),
+
+ Mod = module(),
+ Func = func(),
+ [a] = Mod:my_subtract(same([a,b,c]), same([b,c])),
+ [a,b] = Mod:Func(same([a,b,c]), same([c])),
+ [a,b,d] = ?MODULE:Func(same([a,b,c,d]), same([c])),
+ [d,e] = apply(Mod, Func, [same([d,e,f]), same([f])]),
+ [3] = apply(?MODULE, Func, [same([3,4]),same([4])]),
+
+ %% This is obsolete, but it should work anyway.
+ HomeMadeFun = {?MODULE,my_subtract},
+ [a] = HomeMadeFun(same([a,x,c]), same([x,c])),
+ [x] = apply(HomeMadeFun, [[x,y],[y,z]]),
+
+ ok.
+
+number(X) -> {number,X}.
+module() -> ?MODULE.
+func() -> my_subtract.
+same(X) -> X.
+
+my_subtract(X, Y) -> X -- Y.
+
+%% Catch and throw.
+
+catch_a_ball() ->
+ {a,ball} = (catch throw_a_ball()),
+ ok.
+
+throw_a_ball() ->
+ throw({a,ball}),
+ not_ok.
+
+exit_me() ->
+ exit({int,exit}).
+
+more_catch(Fun) ->
+ case catch lists:filter(Fun, [a]) of
+ {'EXIT', {_, exit}} ->
+ ok;
+ Else -> Else
+ end.
+
+more_nocatch(Fun) ->
+ lists:filter(Fun, [a]).
+
+%% External calls.
+
+external_call_test(Data) ->
+ {'EXIT',{undef,[{?MODULE,not_exported,[42,Data]}|_]}} =
+ (catch ?MODULE:not_exported(42, Data)),
+ {yes,Data} = i_am_exported(Data),
+ {yes,Data} = ?MODULE:i_am_exported(Data),
+
+ %% Excercise the function cache in the interpreter.
+
+ {ok,Data,[a,b]} = not_exported(Data, [a,b]),
+ {yes,Data} = i_am_exported(Data),
+ {ok,Data,[a,b]} = not_exported(Data, [a,b]),
+ {'EXIT',{undef,[{?MODULE,not_exported,[7,Data]}|_]}} =
+ (catch ?MODULE:not_exported(7, Data)),
+ {yes,Data} = ?MODULE:i_am_exported(Data),
+ ok.
+
+not_exported(N, D) ->
+ {ok,N,D}.
+
+i_am_exported(D) ->
+ {yes,D}.
+
+%% The module_info/0,1 functions and list comprehensions (funs).
+
+check_exports(Exp) ->
+ %% Check the structure of the export list and that there are more
+ %% than 4 elements.
+
+ Exp = [{F,A} || {F,A} <- Exp, erlang:is_atom(F), erlang:is_integer(A)],
+ case length(Exp) of
+ Len when Len > 4 -> ok
+ end.
+
+check_module_info(ModInfo, Exports) ->
+ ModInfo = module_info(),
+ Exports = module_info(exports),
+ ok.
+
+%% Testcase apply_interpreted_fun/1.
+
+give_me_a_fun_0() ->
+ fun() -> perfectly_alright end.
+
+give_me_a_fun_0(Term) ->
+ fun() -> {ok,Term} end.
+
+give_me_a_fun_1(Min, Max) ->
+ Seq = lists:seq(Min, Max),
+ fun (L) when list(L) ->
+ [Info || {Key,Info} <- L, lists:member(Key, Seq)];
+ (T) when tuple(T) ->
+ L = tuple_to_list(T),
+ F = fun({Key,Info}) ->
+ case lists:member(Key, Seq) of
+ true -> Info;
+ false -> false
+ end
+ end,
+ list_to_tuple(lists:map(F, L))
+ end.
+
+give_me_a_bad_fun() ->
+ fun(Arg) -> erlang:error(Arg) end.
+
+do_apply(Fun) ->
+ Fun().
+do_apply(Fun, Arg) ->
+ Fun(Arg).
+
+
+please_call_exit(Reason) ->
+ put(asked_to_call_exit, Reason),
+ put(will_call_my_good_friend, ''),
+ Res = int_eval_SUITE:applier(?MODULE, i_will_do_the_exit, [Reason]),
+
+ %% We don't want a tail-recursive call above.
+ io:format("Returned from exit/1 -- how strange\n").
+
+i_will_do_the_exit(Reason) ->
+ exit(Reason).
+
+f(Arg) ->
+ g(Arg).
+
+f_try(Arg) ->
+ try g(Arg)
+ catch
+ Class:Reason ->
+ {Class, Reason}
+ end.
+
+f_catch(Arg) ->
+ catch g(Arg).
+
+g({error, Reason}) ->
+ erlang:error(Reason);
+g({exit, Reason}) ->
+ erlang:exit(Reason);
+g({throw, Reason}) ->
+ erlang:throw(Reason);
+g(Value) ->
+ Value.
+
+otp_5837(N) ->
+ n(N).
+
+n(N) ->
+ lists:map(fun(X) when N==X ->
+ yes;
+ (_) ->
+ no
+ end,
+ [1,2,3,4]).
+
+otp_8310() ->
+ a = if (false orelse a) =:= a -> a; true -> b end,
+ F1 = fun() -> a end,
+ {'EXIT',{{bad_filter,a},_}} =
+ (catch {a, [X || X <- [1,2,3], _ = F1()]}),
+ F2 = fun() -> << 3:8 >> end,
+ {'EXIT',{{bad_filter,<<3>>},_}} =
+ (catch {a, << << X >> || << X >> <= << 7:8 >>,_ = F2() >>}),
+ {'EXIT',{{bad_generator,a},_}} =
+ (catch {a, [X || X <- a]}),
+ {'EXIT',{{bad_generator,b},_}} =
+ (catch {a, << <<X>> || << X >> <= b >>}),
+ ok.
diff --git a/lib/debugger/test/lc_SUITE.erl b/lib/debugger/test/lc_SUITE.erl
new file mode 100644
index 0000000000..a22a689ec8
--- /dev/null
+++ b/lib/debugger/test/lc_SUITE.erl
@@ -0,0 +1,74 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 2001-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(lc_SUITE).
+
+-author('[email protected]').
+-export([all/1,init_per_testcase/2,fin_per_testcase/2,init_all/1,finish_all/1,
+ basic/1]).
+
+-include("test_server.hrl").
+
+all(suite) ->
+ [{conf,init_all,cases(),finish_all}].
+
+cases() ->
+ [basic].
+
+init_per_testcase(_Case, Config) ->
+ test_lib:interpret(?MODULE),
+ Dog = test_server:timetrap(?t:minutes(1)),
+ [{watchdog,Dog}|Config].
+
+fin_per_testcase(_Case, Config) ->
+ Dog = ?config(watchdog, Config),
+ ?t:timetrap_cancel(Dog),
+ ok.
+
+init_all(Config) when is_list(Config) ->
+ ?line test_lib:interpret(?MODULE),
+ ?line true = lists:member(?MODULE, int:interpreted()),
+ ok.
+
+finish_all(Config) when is_list(Config) ->
+ ok.
+
+basic(Config) when list(Config) ->
+ ?line L0 = lists:seq(1, 10),
+ ?line L1 = my_map(fun(X) -> {x,X} end, L0),
+ ?line L1 = [{x,X} || X <- L0],
+ ?line L0 = my_map(fun({x,X}) -> X end, L1),
+ ?line [1,2,3,4,5] = [X || X <- L0, X < 6],
+ ?line [4,5,6] = [X || X <- L0, X > 3, X < 7],
+ ?line [] = [X || X <- L0, X > 32, X < 7],
+ ?line [1,3,5,7,9] = [X || X <- L0, odd(X)],
+
+ %% Error cases.
+ ?line [] = [X || X <- L1, X+1 < 2],
+ ?line [] = [{xx,X} || X <- L0, element(2, X) == no_no_no],
+ ?line {'EXIT',_} = (catch [X || X <- L1, odd(X)]),
+
+ ok.
+
+my_map(F, L) ->
+ [F(X) || X <- L].
+
+odd(X) ->
+ X rem 2 == 1.
diff --git a/lib/debugger/test/record_SUITE.erl b/lib/debugger/test/record_SUITE.erl
new file mode 100644
index 0000000000..06fd01555e
--- /dev/null
+++ b/lib/debugger/test/record_SUITE.erl
@@ -0,0 +1,252 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 2004-2010. All Rights Reserved.
+%%
+%% The contents of this file are subject to the Erlang Public License,
+%% Version 1.1, (the "License"); you may not use this file except in
+%% compliance with the License. You should have received a copy of the
+%% Erlang Public License along with this software. If not, it can be
+%% retrieved online at http://www.erlang.org/.
+%%
+%% Software distributed under the License is distributed on an "AS IS"
+%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+%% the License for the specific language governing rights and limitations
+%% under the License.
+%%
+%% %CopyrightEnd%
+%%
+
+%%
+%%% Purpose : Test records.
+
+-module(record_SUITE).
+
+-include("test_server.hrl").
+
+-export([all/1,init_per_testcase/2,fin_per_testcase/2,init_all/1,finish_all/1,
+ errors/1,record_test/1,eval_once/1]).
+
+all(suite) ->
+ [{conf,init_all,cases(),finish_all}].
+
+cases() ->
+ [errors,record_test,eval_once].
+
+init_per_testcase(_Case, Config) ->
+ test_lib:interpret(?MODULE),
+ Dog = test_server:timetrap(?t:minutes(1)),
+ [{watchdog,Dog}|Config].
+
+fin_per_testcase(_Case, Config) ->
+ Dog = ?config(watchdog, Config),
+ ?t:timetrap_cancel(Dog),
+ ok.
+
+init_all(Config) when is_list(Config) ->
+ ?line test_lib:interpret(?MODULE),
+ ?line true = lists:member(?MODULE, int:interpreted()),
+ ok.
+
+finish_all(Config) when is_list(Config) ->
+ ok.
+
+-record(foo, {a,b,c,d}).
+-record(bar, {a,b,c,d}).
+-record(barf, {a,b,c,d,e}).
+
+errors(Config) when is_list(Config) ->
+ Foo = #foo{a=1,b=2,c=3,d=4},
+ ?line #foo{a=19,b=42,c=3,d=4} = update_foo(Foo, 19, 42),
+
+ ?line {'EXIT',{{badrecord,bar},_}} = (catch update_foo_bar(Foo, 19)),
+ ?line {'EXIT',{{badrecord,bar},_}} = (catch update_foo_bar(Foo, 19, 35)),
+ ?line {'EXIT',{{badrecord,bar},_}} = (catch update_foo_bar(Foo, 19, 35, 17)),
+ ?line {'EXIT',{{badrecord,bar},_}} = (catch update_foo_bar(Foo, 19, 35, 17, 42)),
+
+ ?line {'EXIT',{{badrecord,barf},_}} = (catch update_foo_barf(Foo, 19)),
+ ?line {'EXIT',{{badrecord,barf},_}} = (catch update_foo_barf(Foo, 19, 35)),
+ ?line {'EXIT',{{badrecord,barf},_}} = (catch update_foo_barf(Foo, 19, 35, 17)),
+ ?line {'EXIT',{{badrecord,barf},_}} = (catch update_foo_barf(Foo, 19, 35, 17, 42)),
+ ?line {'EXIT',{{badrecord,barf},_}} = (catch update_foo_barf(Foo, 19,
+ 35, 17, 42, -2)),
+
+ ok.
+
+update_foo(#foo{}=R, A, B) ->
+ R#foo{a=A,b=B}.
+
+update_foo_bar(#foo{}=R, A) ->
+ R#bar{a=A}.
+
+update_foo_bar(#foo{}=R, A, _B) ->
+ R#bar{a=A,b=A}.
+
+update_foo_bar(#foo{}=R, A, _B, C) ->
+ R#bar{a=A,b=A,c=C}.
+
+update_foo_bar(#foo{}=R, A, _B, C, D) ->
+ R#bar{a=A,b=A,c=C,d=D}.
+
+update_foo_barf(#foo{}=R, A) ->
+ R#barf{a=A}.
+
+update_foo_barf(#foo{}=R, A, _B) ->
+ R#barf{a=A,b=A}.
+
+update_foo_barf(#foo{}=R, A, _B, C) ->
+ R#barf{a=A,b=A,c=C}.
+
+update_foo_barf(#foo{}=R, A, _B, C, D) ->
+ R#barf{a=A,b=A,c=C,d=D}.
+
+update_foo_barf(#foo{}=R, A, _B, C, D, E) ->
+ R#barf{a=A,b=A,c=C,d=D,e=E}.
+
+
+-define(TrueGuard(Expr), if Expr -> ok; true -> ?t:fail() end).
+-define(FalseGuard(Expr), if Expr -> ?t:fail(); true -> ok end).
+
+record_test(Config) when is_list(Config) ->
+ ?line true = is_record(#foo{}, foo),
+ ?line false = is_record(#foo{}, barf),
+ ?line false = is_record({foo}, foo),
+
+ ?line true = erlang:is_record(#foo{}, foo),
+ ?line false = erlang:is_record(#foo{}, barf),
+ ?line false = erlang:is_record({foo}, foo),
+
+ ?line false = is_record([], foo),
+ ?line false = is_record(Config, foo),
+
+ ?line ?TrueGuard(is_record(#foo{}, foo)),
+ ?line ?FalseGuard(is_record(#foo{}, barf)),
+ ?line ?FalseGuard(is_record({foo}, foo)),
+
+ ?line ?TrueGuard(erlang:is_record(#foo{}, foo)),
+ ?line ?FalseGuard(erlang:is_record(#foo{}, barf)),
+ ?line ?FalseGuard(erlang:is_record({foo}, foo)),
+
+ ?line ?FalseGuard(is_record([], foo)),
+ ?line ?FalseGuard(is_record(Config, foo)),
+
+ %% 'not is_record/2' to test guard optimization.
+
+ ?line ?FalseGuard(not is_record(#foo{}, foo)),
+ ?line ?TrueGuard(not is_record(#foo{}, barf)),
+ ?line ?TrueGuard(not is_record({foo}, foo)),
+
+ ?line ?FalseGuard(not erlang:is_record(#foo{}, foo)),
+ ?line ?TrueGuard(not erlang:is_record(#foo{}, barf)),
+ ?line ?TrueGuard(not erlang:is_record({foo}, foo)),
+
+ Foo = id(#foo{}),
+ ?line ?FalseGuard(not erlang:is_record(Foo, foo)),
+ ?line ?TrueGuard(not erlang:is_record(Foo, barf)),
+
+ ?line ?TrueGuard(not is_record(Config, foo)),
+
+ ?line ?TrueGuard(not is_record(a, foo)),
+ ?line ?TrueGuard(not is_record([], foo)),
+
+ %% Pass non-literal first argument.
+
+ ?line true = is_record(id(#foo{}), foo),
+ ?line false = is_record(id(#foo{}), barf),
+ ?line false = is_record(id({foo}), foo),
+
+ ?line true = erlang:is_record(id(#foo{}), foo),
+ ?line false = erlang:is_record(id(#foo{}), barf),
+ ?line false = erlang:is_record(id({foo}), foo),
+
+ NoRec1 = id(blurf),
+ NoRec2 = id([]),
+
+ ?line ?TrueGuard(not is_record(NoRec1, foo)),
+ ?line ?TrueGuard(not is_record(NoRec2, foo)),
+
+ %% Force the use of guard bifs by using the 'xor' operation.
+
+ False = id(false),
+ ?line ?TrueGuard(is_record(#foo{}, foo) xor False),
+ ?line ?FalseGuard(is_record(#foo{}, barf) xor False),
+ ?line ?FalseGuard(is_record({foo}, foo) xor False ),
+
+ ?line ?TrueGuard(is_record(Foo, foo) xor False),
+ ?line ?FalseGuard(is_record(Foo, barf) xor False),
+
+
+ %% Implicit guards by using a list comprehension.
+
+ List = id([1,#foo{a=2},3,#bar{d=4},5,#foo{a=6},7]),
+
+ ?line [#foo{a=2},#foo{a=6}] = [X || X <- List, is_record(X, foo)],
+ ?line [#bar{d=4}] = [X || X <- List, is_record(X, bar)],
+ ?line [1,#foo{a=2},3,5,#foo{a=6},7] =
+ [X || X <- List, not is_record(X, bar)],
+ ?line [1,3,5,7] =
+ [X || X <- List, ((not is_record(X, bar)) and (not is_record(X, foo)))],
+ ?line [#foo{a=2},#bar{d=4},#foo{a=6}] =
+ [X || X <- List, ((is_record(X, bar)) or (is_record(X, foo)))],
+ ?line [1,3,#bar{d=4}] =
+ [X || X <- List, ((is_record(X, bar)) or (X < 5))],
+
+ ?line MyList = [#foo{a=3},x,[],{a,b}],
+ ?line [#foo{a=3}] = [X || X <- MyList, is_record(X, foo)],
+ ?line [x,[],{a,b}] = [X || X <- MyList, not is_record(X, foo)],
+ ?line [#foo{a=3}] = [X || X <- MyList, begin is_record(X, foo) end],
+ ?line [x,[],{a,b}] = [X || X <- MyList, begin not is_record(X, foo) end],
+ ?line [#foo{a=3},x,[],{a,b}] = [X || X <- MyList, is_record(X, foo) or
+ not is_binary(X)],
+ ?line [#foo{a=3},x,[],{a,b}] = [X || X <- MyList, not is_record(X, foo) or
+ not is_binary(X)],
+ ?line [#foo{a=3}] = [X || X <- MyList, is_record(X, foo) or is_reference(X)],
+ ?line [x,[],{a,b}] = [X || X <- MyList, not is_record(X, foo) or
+ is_reference(X)],
+ ?line [#foo{a=3},x,[],{a,b}] = [X || X <- MyList,
+ begin is_record(X, foo) or
+ not is_binary(X) end],
+ ?line [#foo{a=3},x,[],{a,b}] = [X || X <- MyList,
+ begin not is_record(X, foo) or
+ not is_binary(X) end],
+ ?line [#foo{a=3}] = [X || X <- MyList,
+ begin is_record(X, foo) or is_reference(X) end],
+ ?line [x,[],{a,b}] = [X || X <- MyList,
+ begin not is_record(X, foo) or
+ is_reference(X) end],
+ ok.
+
+eval_once(Config) when is_list(Config) ->
+ ?line once(fun(GetRec) ->
+ true = erlang:is_record(GetRec(), foo)
+ end, #foo{}),
+ ?line once(fun(GetRec) ->
+ (GetRec())#foo{a=1}
+ end, #foo{}),
+ ?line once(fun(GetRec) ->
+ (GetRec())#foo{a=1,b=2}
+ end, #foo{}),
+ ?line once(fun(GetRec) ->
+ (GetRec())#foo{a=1,b=2,c=3}
+ end, #foo{}),
+ ?line once(fun(GetRec) ->
+ (GetRec())#foo{a=1,b=2,c=3,d=4}
+ end, #foo{}),
+ ok.
+
+once(Test, Record) ->
+ put(?MODULE, 0),
+ GetRec = fun() ->
+ put(?MODULE, 1+get(?MODULE)),
+ Record
+ end,
+ Result = Test(GetRec),
+ case get(?MODULE) of
+ 1 -> ok;
+ N ->
+ io:format("Evaluated ~w times\n", [N]),
+ ?t:fail()
+ end,
+ Result.
+
+id(I) -> I.
diff --git a/lib/debugger/test/test_lib.erl b/lib/debugger/test/test_lib.erl
new file mode 100644
index 0000000000..541375e64a
--- /dev/null
+++ b/lib/debugger/test/test_lib.erl
@@ -0,0 +1,29 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 2000-2010. All Rights Reserved.
+%%
+%% The contents of this file are subject to the Erlang Public License,
+%% Version 1.1, (the "License"); you may not use this file except in
+%% compliance with the License. You should have received a copy of the
+%% Erlang Public License along with this software. If not, it can be
+%% retrieved online at http://www.erlang.org/.
+%%
+%% Software distributed under the License is distributed on an "AS IS"
+%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+%% the License for the specific language governing rights and limitations
+%% under the License.
+%%
+%% %CopyrightEnd%
+%%
+
+
+-module(test_lib).
+
+-export([interpret/1]).
+
+interpret(Mod) when atom(Mod) ->
+ case lists:member(Mod, int:interpreted()) of
+ true -> ok;
+ false -> {module,Mod} = i:ii(Mod)
+ end.
diff --git a/lib/debugger/test/trycatch_SUITE.erl b/lib/debugger/test/trycatch_SUITE.erl
new file mode 100644
index 0000000000..5901cdc9e5
--- /dev/null
+++ b/lib/debugger/test/trycatch_SUITE.erl
@@ -0,0 +1,796 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 2003-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(trycatch_SUITE).
+
+-export([all/1,init_per_testcase/2,fin_per_testcase/2,init_all/1,finish_all/1,
+ basic/1,lean_throw/1,try_of/1,try_after/1,%after_bind/1,
+ catch_oops/1,after_oops/1,eclectic/1,rethrow/1,
+ nested_of/1,nested_catch/1,nested_after/1]).
+
+-include("test_server.hrl").
+
+all(suite) ->
+ [{conf,init_all,cases(),finish_all}].
+
+cases() ->
+ [basic,lean_throw,try_of,try_after,%after_bind,
+ catch_oops,after_oops,eclectic,rethrow,
+ nested_of,nested_catch,nested_after].
+
+init_per_testcase(_Case, Config) ->
+ test_lib:interpret(?MODULE),
+ Dog = test_server:timetrap(?t:minutes(1)),
+ [{watchdog,Dog}|Config].
+
+fin_per_testcase(_Case, Config) ->
+ Dog = ?config(watchdog, Config),
+ ?t:timetrap_cancel(Dog),
+ ok.
+
+init_all(Config) when is_list(Config) ->
+ ?line test_lib:interpret(?MODULE),
+ ?line true = lists:member(?MODULE, int:interpreted()),
+ ok.
+
+finish_all(Config) when is_list(Config) ->
+ ok.
+
+basic(Conf) when is_list(Conf) ->
+ ?line 2 =
+ try my_div(4, 2)
+ catch
+ Class:Reason -> {Class,Reason}
+ end,
+ ?line error =
+ try my_div(1, 0)
+ catch
+ error:badarith -> error
+ end,
+ ?line error =
+ try 1/0
+ catch
+ error:badarith -> error
+ end,
+ ?line ok =
+ try my_add(53, atom)
+ catch
+ error:badarith -> ok
+ end,
+ ?line exit_nisse =
+ try exit(nisse)
+ catch
+ exit:nisse -> exit_nisse
+ end,
+ ?line ok =
+ try throw(kalle)
+ catch
+ kalle -> ok
+ end,
+
+ %% Try some stuff where the compiler will optimize away the try.
+
+ V = id({a,variable}),
+ ?line V = try V catch nisse -> error end,
+ ?line 42 = try 42 catch nisse -> error end,
+ ?line [V] = try [V] catch nisse -> error end,
+ ?line {ok,V} = try {ok,V} catch nisse -> error end,
+
+ %% Same idea, but use an after too.
+
+ ?line V = try V catch nisse -> error after after_call() end,
+ ?line after_clean(),
+ ?line 42 = try 42 after after_call() end,
+ ?line after_clean(),
+ ?line [V] = try [V] catch nisse -> error after after_call() end,
+ ?line after_clean(),
+ ?line {ok,V} = try {ok,V} after after_call() end,
+
+ %% Try/of
+ ?line ok = try V of
+ {a,variable} -> ok
+ catch nisse -> erro
+ end,
+
+ ok.
+
+after_call() ->
+ put(basic, after_was_called).
+
+after_clean() ->
+ after_was_called = erase(basic).
+
+lean_throw(Conf) when is_list(Conf) ->
+ ?line {throw,kalle} =
+ try throw(kalle)
+ catch
+ Kalle -> {throw,Kalle}
+ end,
+ ?line {exit,kalle} =
+ try exit(kalle)
+ catch
+ Throw1 -> {throw,Throw1};
+ exit:Reason1 -> {exit,Reason1}
+ end,
+ ?line {exit,kalle} =
+ try exit(kalle)
+ catch
+ exit:Reason2 -> {exit,Reason2};
+ Throw2 -> {throw,Throw2}
+ end,
+ ?line {exit,kalle} =
+ try try exit(kalle)
+ catch
+ Throw3 -> {throw,Throw3}
+ end
+ catch
+ exit:Reason3 -> {exit,Reason3}
+ end,
+ ok.
+
+try_of(Conf) when is_list(Conf) ->
+ ?line {ok,{some,content}} =
+ try_of_1({value,{good,{some,content}}}),
+ ?line {error,[other,content]} =
+ try_of_1({value,{bad,[other,content]}}),
+ ?line {caught,{exit,{ex,it,[reason]}}} =
+ try_of_1({exit,{ex,it,[reason]}}),
+ ?line {caught,{throw,[term,{in,a,{tuple}}]}} =
+ try_of_1({throw,[term,{in,a,{tuple}}]}),
+ ?line {caught,{error,[bad,arg]}} =
+ try_of_1({error,[bad,arg]}),
+ ?line {caught,{error,badarith}} =
+ try_of_1({'div',{1,0}}),
+ ?line {caught,{error,badarith}} =
+ try_of_1({'add',{a,0}}),
+ ?line {caught,{error,badarg}} =
+ try_of_1({'abs',x}),
+ ?line {caught,{error,function_clause}} =
+ try_of_1(illegal),
+ ?line {error,{try_clause,{some,other_garbage}}} =
+ try try_of_1({value,{some,other_garbage}})
+ catch error:Reason -> {error,Reason}
+ end,
+ ok.
+
+try_of_1(X) ->
+ try foo(X) of
+ {good,Y} -> {ok,Y};
+ {bad,Y} -> {error,Y}
+ catch
+ Class:Reason ->
+ {caught,{Class,Reason}}
+ end.
+
+try_after(Conf) when is_list(Conf) ->
+ ?line {{ok,[some,value],undefined},finalized} =
+ try_after_1({value,{ok,[some,value]}},finalized),
+ ?line {{error,badarith,undefined},finalized} =
+ try_after_1({'div',{1,0}},finalized),
+ ?line {{error,badarith,undefined},finalized} =
+ try_after_1({'add',{1,a}},finalized),
+ ?line {{error,badarg,undefined},finalized} =
+ try_after_1({'abs',a},finalized),
+ ?line {{error,[the,{reason}],undefined},finalized} =
+ try_after_1({error,[the,{reason}]},finalized),
+ ?line {{throw,{thrown,[reason]},undefined},finalized} =
+ try_after_1({throw,{thrown,[reason]}},finalized),
+ ?line {{exit,{exited,{reason}},undefined},finalized} =
+ try_after_1({exit,{exited,{reason}}},finalized),
+ ?line {{error,function_clause,undefined},finalized} =
+ try_after_1(function_clause,finalized),
+ ?line ok =
+ try try_after_1({'add',{1,1}}, finalized)
+ catch
+ error:{try_clause,2} -> ok
+ end,
+ ?line finalized = erase(try_after),
+ ?line ok =
+ try try foo({exit,[reaso,{n}]})
+ after put(try_after, finalized)
+ end
+ catch
+ exit:[reaso,{n}] -> ok
+ end,
+ ok.
+
+try_after_1(X, Y) ->
+ erase(try_after),
+ Try =
+ try foo(X) of
+ {ok,Value} -> {ok,Value,get(try_after)}
+ catch
+ Reason -> {throw,Reason,get(try_after)};
+ error:Reason -> {error,Reason,get(try_after)};
+ exit:Reason -> {exit,Reason,get(try_after)}
+ after
+ put(try_after, Y)
+ end,
+ {Try,erase(try_after)}.
+
+-ifdef(begone).
+
+after_bind(Conf) when is_list(Conf) ->
+ V = [make_ref(),self()|value],
+ ?line {value,{value,V}} =
+ after_bind_1({value,V}, V, {value,V}),
+ ok.
+
+after_bind_1(X, V, Y) ->
+ try
+ Try =
+ try foo(X) of
+ V -> value
+ catch
+ C1:V -> {caught,C1}
+ after
+ After = foo(Y)
+ end,
+ {Try,After}
+ of
+ V -> {value,V}
+ catch
+ C:D -> {caught,{C,D}}
+ end.
+
+-endif.
+
+catch_oops(Conf) when is_list(Conf) ->
+ V = {v,[a,l|u],{e},self()},
+ ?line {value,V} = catch_oops_1({value,V}),
+ ?line {value,1} = catch_oops_1({'div',{1,1}}),
+ ?line {error,badarith} = catch_oops_1({'div',{1,0}}),
+ ?line {error,function_clause} = catch_oops_1(function_clause),
+ ?line {throw,V} = catch_oops_1({throw,V}),
+ ?line {exit,V} = catch_oops_1({exit,V}),
+ ok.
+
+catch_oops_1(X) ->
+ Ref = make_ref(),
+ try try foo({error,Ref})
+ catch
+ error:Ref ->
+ foo(X)
+ end of
+ Value -> {value,Value}
+ catch
+ Class:Data -> {Class,Data}
+ end.
+
+
+
+after_oops(Conf) when is_list(Conf) ->
+ V = {self(),make_ref()},
+ ?line {{value,V},V} = after_oops_1({value,V}, {value,V}),
+ ?line {{exit,V},V} = after_oops_1({exit,V}, {value,V}),
+ ?line {{error,V},undefined} = after_oops_1({value,V}, {error,V}),
+ ?line {{error,function_clause},undefined} =
+ after_oops_1({exit,V}, function_clause),
+ ok.
+
+after_oops_1(X, Y) ->
+ erase(after_oops),
+ Try =
+ try try foo(X)
+ after
+ put(after_oops, foo(Y))
+ end of
+ V -> {value,V}
+ catch
+ C:D -> {C,D}
+ end,
+ {Try,erase(after_oops)}.
+
+
+
+eclectic(Conf) when is_list(Conf) ->
+ V = {make_ref(),3.1415926535,[[]|{}]},
+ ?line {{value,{value,V},V},V} =
+ eclectic_1({foo,{value,{value,V}}}, undefined, {value,V}),
+ ?line {{'EXIT',{V,[{?MODULE,foo,_}|_]}},V} =
+ eclectic_1({catch_foo,{error,V}}, undefined, {value,V}),
+ ?line {{error,{exit,V},{'EXIT',V}},V} =
+ eclectic_1({foo,{error,{exit,V}}}, error, {value,V}),
+ ?line {{value,{value,V},V},{'EXIT',{badarith,[{?MODULE,my_add,_}|_]}}} =
+ eclectic_1({foo,{value,{value,V}}}, undefined, {'add',{0,a}}),
+ ?line {{'EXIT',V},V} =
+ eclectic_1({catch_foo,{exit,V}}, undefined, {throw,V}),
+ ?line {{error,{'div',{1,0}},{'EXIT',{badarith,[{?MODULE,my_div,_}|_]}}}, {'EXIT',V}} =
+ eclectic_1({foo,{error,{'div',{1,0}}}}, error, {exit,V}),
+ ?line {{{error,V},{'EXIT',{V,[{?MODULE,foo,_}|_]}}},{'EXIT',V}} =
+ eclectic_1({catch_foo,{throw,{error,V}}}, undefined, {exit,V}),
+ %%
+ ?line {{value,{value,{value,V},V}},V} =
+ eclectic_2({value,{value,V}}, undefined, {value,V}),
+ ?line {{value,{throw,{value,V},V}},V} =
+ eclectic_2({throw,{value,V}}, throw, {value,V}),
+ ?line {{caught,{'EXIT',V}},undefined} =
+ eclectic_2({value,{value,V}}, undefined, {exit,V}),
+ ?line {{caught,{'EXIT',{V,[{?MODULE,foo,_}|_]}}},undefined} =
+ eclectic_2({error,{value,V}}, throw, {error,V}),
+ ?line {{caught,{'EXIT',{badarg,[{erlang,abs,[V]}|_]}}},V} =
+ eclectic_2({value,{'abs',V}}, undefined, {value,V}),
+ ?line {{caught,{'EXIT',{badarith,[{?MODULE,my_add,_}|_]}}},V} =
+ eclectic_2({exit,{'add',{0,a}}}, exit, {value,V}),
+ ?line {{caught,{'EXIT',V}},undefined} =
+ eclectic_2({value,{error,V}}, undefined, {exit,V}),
+ ?line {{caught,{'EXIT',{V,[{?MODULE,foo,_}|_]}}},undefined} =
+ eclectic_2({throw,{'div',{1,0}}}, throw, {error,V}),
+ ok.
+
+eclectic_1(X, C, Y) ->
+ erase(eclectic),
+ Done = make_ref(),
+ Try =
+ try case X of
+ {catch_foo,V} -> catch {Done,foo(V)};
+ {foo,V} -> {Done,foo(V)}
+ end of
+ {Done,D} -> {value,D,catch foo(D)};
+ {'EXIT',_}=Exit -> Exit;
+ D -> {D,catch foo(D)}
+ catch
+ C:D -> {C,D,catch foo(D)}
+ after
+ put(eclectic, catch foo(Y))
+ end,
+ {Try,erase(eclectic)}.
+
+eclectic_2(X, C, Y) ->
+ Done = make_ref(),
+ erase(eclectic),
+ Catch =
+ case
+ catch
+ {Done,
+ try foo(X) of
+ V -> {value,V,foo(V)}
+ catch
+ C:D -> {C,D,foo(D)}
+ after
+ put(eclectic, foo(Y))
+ end} of
+ {Done,Z} -> {value,Z};
+ Z -> {caught,Z}
+ end,
+ {Catch,erase(eclectic)}.
+
+rethrow(Conf) when is_list(Conf) ->
+ V = {a,[b,{c,self()},make_ref]},
+ ?line {value2,value1} =
+ rethrow_1({value,V}, V),
+ ?line {caught2,{error,V}} =
+ rethrow_2({error,V}, undefined),
+ ?line {caught2,{exit,V}} =
+ rethrow_1({exit,V}, error),
+ ?line {caught2,{throw,V}} =
+ rethrow_1({throw,V}, undefined),
+ ?line {caught2,{throw,V}} =
+ rethrow_2({throw,V}, undefined),
+ ?line {caught2,{error,badarith}} =
+ rethrow_1({'add',{0,a}}, throw),
+ ?line {caught2,{error,function_clause}} =
+ rethrow_2(function_clause, undefined),
+ ?line {caught2,{error,{try_clause,V}}} =
+ rethrow_1({value,V}, exit),
+ ?line {value2,{caught1,V}} =
+ rethrow_1({error,V}, error),
+ ?line {value2,{caught1,V}} =
+ rethrow_1({exit,V}, exit),
+ ?line {value2,caught1} =
+ rethrow_2({throw,V}, V),
+ ok.
+
+rethrow_1(X, C1) ->
+ try try foo(X) of
+ C1 -> value1
+ catch
+ C1:D1 -> {caught1,D1}
+ end of
+ V2 -> {value2,V2}
+ catch
+ C2:D2 -> {caught2,{C2,D2}}
+ end.
+
+rethrow_2(X, C1) ->
+ try try foo(X) of
+ C1 -> value1
+ catch
+ C1 -> caught1 % Implicit class throw:
+ end of
+ V2 -> {value2,V2}
+ catch
+ C2:D2 -> {caught2,{C2,D2}}
+ end.
+
+
+
+nested_of(Conf) when is_list(Conf) ->
+ V = {[self()|make_ref()],1.4142136},
+ ?line {{value,{value1,{V,x2}}},
+ {V,x3},
+ {V,x4},
+ finalized} =
+ nested_of_1({{value,{V,x1}},void,{V,x1}},
+ {value,{V,x2}}, {value,{V,x3}}, {value,{V,x4}}),
+ ?line {{caught,{throw,{V,x2}}},
+ {V,x3},
+ {V,x4},
+ finalized} =
+ nested_of_1({{value,{V,x1}},void,{V,x1}},
+ {throw,{V,x2}}, {value,{V,x3}}, {value,{V,x4}}),
+ ?line {{caught,{error,badarith}},
+ undefined,
+ {V,x4},
+ finalized} =
+ nested_of_1({{value,{V,x1}},void,{V,x1}},
+ {throw,{V,x2}}, {'div',{1,0}}, {value,{V,x4}}),
+ ?line {{caught,{error,badarith}},
+ undefined,
+ undefined,
+ finalized} =
+ nested_of_1({{value,{V,x1}},void,{V,x1}},
+ {throw,{V,x2}}, {'div',{1,0}}, {'add',{0,b}}),
+ %%
+ ?line {{caught,{error,{try_clause,{V,x1}}}},
+ {V,x3},
+ {V,x4},
+ finalized} =
+ nested_of_1({{value,{V,x1}},void,try_clause},
+ void, {value,{V,x3}}, {value,{V,x4}}),
+ ?line {{caught,{exit,{V,x3}}},
+ undefined,
+ {V,x4},
+ finalized} =
+ nested_of_1({{value,{V,x1}},void,try_clause},
+ void, {exit,{V,x3}}, {value,{V,x4}}),
+ ?line {{caught,{throw,{V,x4}}},
+ undefined,
+ undefined,
+ finalized} =
+ nested_of_1({{value,{V,x1}},void,try_clause},
+ void, {exit,{V,x3}}, {throw,{V,x4}}),
+ %%
+ ?line {{value,{caught1,{V,x2}}},
+ {V,x3},
+ {V,x4},
+ finalized} =
+ nested_of_1({{error,{V,x1}},error,{V,x1}},
+ {value,{V,x2}}, {value,{V,x3}}, {value,{V,x4}}),
+ ?line {{caught,{error,badarith}},
+ {V,x3},
+ {V,x4},
+ finalized} =
+ nested_of_1({{error,{V,x1}},error,{V,x1}},
+ {'add',{1,c}}, {value,{V,x3}}, {value,{V,x4}}),
+ ?line {{caught,{error,badarith}},
+ undefined,
+ {V,x4},
+ finalized} =
+ nested_of_1({{error,{V,x1}},error,{V,x1}},
+ {'add',{1,c}}, {'div',{17,0}}, {value,{V,x4}}),
+ ?line {{caught,{error,badarg}},
+ undefined,
+ undefined,
+ finalized} =
+ nested_of_1({{error,{V,x1}},error,{V,x1}},
+ {'add',{1,c}}, {'div',{17,0}}, {'abs',V}),
+ %%
+ ?line {{caught,{error,badarith}},
+ {V,x3},
+ {V,x4},
+ finalized} =
+ nested_of_1({{'add',{2,c}},rethrow,void},
+ void, {value,{V,x3}}, {value,{V,x4}}),
+ ?line {{caught,{error,badarg}},
+ undefined,
+ {V,x4},
+ finalized} =
+ nested_of_1({{'add',{2,c}},rethrow,void},
+ void, {'abs',V}, {value,{V,x4}}),
+ ?line {{caught,{error,function_clause}},
+ undefined,
+ undefined,
+ finalized} =
+ nested_of_1({{'add',{2,c}},rethrow,void},
+ void, {'abs',V}, function_clause),
+ ok.
+
+nested_of_1({X1,C1,V1},
+ X2, X3, X4) ->
+ erase(nested3),
+ erase(nested4),
+ erase(nested),
+ Self = self(),
+ Try =
+ try
+ try self()
+ of
+ Self ->
+ try
+ foo(X1)
+ of
+ V1 -> {value1,foo(X2)}
+ catch
+ C1:V1 -> {caught1,foo(X2)}
+ after
+ put(nested3, foo(X3))
+ end
+ after
+ put(nested4, foo(X4))
+ end
+ of
+ V -> {value,V}
+ catch
+ C:D -> {caught,{C,D}}
+ after
+ put(nested, finalized)
+ end,
+ {Try,erase(nested3),erase(nested4),erase(nested)}.
+
+
+
+nested_catch(Conf) when is_list(Conf) ->
+ V = {[make_ref(),1.4142136,self()]},
+ ?line {{value,{value1,{V,x2}}},
+ {V,x3},
+ {V,x4},
+ finalized} =
+ nested_catch_1({{value,{V,x1}},void,{V,x1}},
+ {value,{V,x2}}, {value,{V,x3}}, {value,{V,x4}}),
+ ?line {{caught,{throw,{V,x2}}},
+ {V,x3},
+ {V,x4},
+ finalized} =
+ nested_catch_1({{value,{V,x1}},void,{V,x1}},
+ {throw,{V,x2}}, {value,{V,x3}}, {value,{V,x4}}),
+ ?line {{caught,{error,badarith}},
+ undefined,
+ {V,x4},
+ finalized} =
+ nested_catch_1({{value,{V,x1}},void,{V,x1}},
+ {throw,{V,x2}}, {'div',{1,0}}, {value,{V,x4}}),
+ ?line {{caught,{error,badarith}},
+ undefined,
+ undefined,
+ finalized} =
+ nested_catch_1({{value,{V,x1}},void,{V,x1}},
+ {throw,{V,x2}}, {'div',{1,0}}, {'add',{0,b}}),
+ %%
+ ?line {{caught,{error,{try_clause,{V,x1}}}},
+ {V,x3},
+ {V,x4},
+ finalized} =
+ nested_catch_1({{value,{V,x1}},void,try_clause},
+ void, {value,{V,x3}}, {value,{V,x4}}),
+ ?line {{caught,{exit,{V,x3}}},
+ undefined,
+ {V,x4},
+ finalized} =
+ nested_catch_1({{value,{V,x1}},void,try_clause},
+ void, {exit,{V,x3}}, {value,{V,x4}}),
+ ?line {{caught,{throw,{V,x4}}},
+ undefined,
+ undefined,
+ finalized} =
+ nested_catch_1({{value,{V,x1}},void,try_clause},
+ void, {exit,{V,x3}}, {throw,{V,x4}}),
+ %%
+ ?line {{value,{caught1,{V,x2}}},
+ {V,x3},
+ {V,x4},
+ finalized} =
+ nested_catch_1({{error,{V,x1}},error,{V,x1}},
+ {value,{V,x2}}, {value,{V,x3}}, {value,{V,x4}}),
+ ?line {{caught,{error,badarith}},
+ {V,x3},
+ {V,x4},
+ finalized} =
+ nested_catch_1({{error,{V,x1}},error,{V,x1}},
+ {'add',{1,c}}, {value,{V,x3}}, {value,{V,x4}}),
+ ?line {{caught,{error,badarith}},
+ undefined,
+ {V,x4},
+ finalized} =
+ nested_catch_1({{error,{V,x1}},error,{V,x1}},
+ {'add',{1,c}}, {'div',{17,0}}, {value,{V,x4}}),
+ ?line {{caught,{error,badarg}},
+ undefined,
+ undefined,
+ finalized} =
+ nested_catch_1({{error,{V,x1}},error,{V,x1}},
+ {'add',{1,c}}, {'div',{17,0}}, {'abs',V}),
+ %%
+ ?line {{caught,{error,badarith}},
+ {V,x3},
+ {V,x4},
+ finalized} =
+ nested_catch_1({{'add',{2,c}},rethrow,void},
+ void, {value,{V,x3}}, {value,{V,x4}}),
+ ?line {{caught,{error,badarg}},
+ undefined,
+ {V,x4},
+ finalized} =
+ nested_catch_1({{'add',{2,c}},rethrow,void},
+ void, {'abs',V}, {value,{V,x4}}),
+ ?line {{caught,{error,function_clause}},
+ undefined,
+ undefined,
+ finalized} =
+ nested_catch_1({{'add',{2,c}},rethrow,void},
+ void, {'abs',V}, function_clause),
+ ok.
+
+nested_catch_1({X1,C1,V1},
+ X2, X3, X4) ->
+ erase(nested3),
+ erase(nested4),
+ erase(nested),
+ Throw = make_ref(),
+ Try =
+ try
+ try throw(Throw)
+ catch
+ Throw ->
+ try
+ foo(X1)
+ of
+ V1 -> {value1,foo(X2)}
+ catch
+ C1:V1 -> {caught1,foo(X2)}
+ after
+ put(nested3, foo(X3))
+ end
+ after
+ put(nested4, foo(X4))
+ end
+ of
+ V -> {value,V}
+ catch
+ C:D -> {caught,{C,D}}
+ after
+ put(nested, finalized)
+ end,
+ {Try,erase(nested3),erase(nested4),erase(nested)}.
+
+nested_after(Conf) when is_list(Conf) ->
+ V = [{make_ref(),1.4142136,self()}],
+ ?line {value,
+ {V,x3},
+ {value1,{V,x2}},
+ finalized} =
+ nested_after_1({{value,{V,x1}},void,{V,x1}},
+ {value,{V,x2}}, {value,{V,x3}}),
+ ?line {{caught,{error,{V,x2}}},
+ {V,x3},
+ undefined,
+ finalized} =
+ nested_after_1({{value,{V,x1}},void,{V,x1}},
+ {error,{V,x2}}, {value,{V,x3}}),
+ ?line {{caught,{exit,{V,x3}}},
+ undefined,
+ undefined,
+ finalized} =
+ nested_after_1({{value,{V,x1}},void,{V,x1}},
+ {error,{V,x2}}, {exit,{V,x3}}),
+ %%
+ ?line {{caught,{error,{try_clause,{V,x1}}}},
+ {V,x3},
+ undefined,
+ finalized} =
+ nested_after_1({{value,{V,x1}},void,try_clause},
+ void, {value,{V,x3}}),
+ ?line {{caught,{error,badarith}},
+ undefined,
+ undefined,
+ finalized} =
+ nested_after_1({{value,{V,x1}},void,try_clause},
+ void, {'div',{17,0}}),
+ %%
+ ?line {value,
+ {V,x3},
+ {caught1,{V,x2}},
+ finalized} =
+ nested_after_1({{throw,{V,x1}},throw,{V,x1}},
+ {value,{V,x2}}, {value,{V,x3}}),
+ ?line {{caught,{error,badarith}},
+ {V,x3},
+ undefined,
+ finalized} =
+ nested_after_1({{throw,{V,x1}},throw,{V,x1}},
+ {'add',{a,b}}, {value,{V,x3}}),
+ ?line {{caught,{error,badarg}},
+ undefined,
+ undefined,
+ finalized} =
+ nested_after_1({{throw,{V,x1}},throw,{V,x1}},
+ {'add',{a,b}}, {'abs',V}),
+ %%
+ ?line {{caught,{throw,{V,x1}}},
+ {V,x3},
+ undefined,
+ finalized} =
+ nested_after_1({{throw,{V,x1}},rethrow,void},
+ void, {value,{V,x3}}),
+ ?line {{caught,{error,badarith}},
+ undefined,
+ undefined,
+ finalized} =
+ nested_after_1({{throw,{V,x1}},rethrow,void},
+ void, {'div',{1,0}}),
+ ok.
+
+nested_after_1({X1,C1,V1},
+ X2, X3) ->
+ erase(nested3),
+ erase(nested4),
+ erase(nested),
+ Self = self(),
+ Try =
+ try
+ try self()
+ after
+ After =
+ try
+ foo(X1)
+ of
+ V1 -> {value1,foo(X2)}
+ catch
+ C1:V1 -> {caught1,foo(X2)}
+ after
+ put(nested3, foo(X3))
+ end,
+ put(nested4, After)
+ end
+ of
+ Self -> value
+ catch
+ C:D -> {caught,{C,D}}
+ after
+ put(nested, finalized)
+ end,
+ {Try,erase(nested3),erase(nested4),erase(nested)}.
+
+foo({value,Value}) -> Value;
+foo({'div',{A,B}}) ->
+ my_div(A, B);
+foo({'add',{A,B}}) ->
+ my_add(A, B);
+foo({'abs',X}) ->
+ my_abs(X);
+foo({error,Error}) ->
+ erlang:error(Error);
+foo({throw,Throw}) ->
+ erlang:throw(Throw);
+foo({exit,Exit}) ->
+ erlang:exit(Exit);
+foo({raise,{Class,Reason}}) ->
+ erlang:raise(Class, Reason).
+%%foo(function_clause) -> % must not be defined!
+
+my_div(A, B) ->
+ A div B.
+
+my_add(A, B) ->
+ A + B.
+
+my_abs(X) -> abs(X).
+
+id(I) -> I.
diff --git a/lib/debugger/vsn.mk b/lib/debugger/vsn.mk
index 27bf053b42..5ce37a6bde 100644
--- a/lib/debugger/vsn.mk
+++ b/lib/debugger/vsn.mk
@@ -1 +1 @@
-DEBUGGER_VSN = 3.2.1
+DEBUGGER_VSN = 3.2.2
diff --git a/lib/dialyzer/README b/lib/dialyzer/README
index e9b03883d2..82d0f5ec48 100644
--- a/lib/dialyzer/README
+++ b/lib/dialyzer/README
@@ -3,9 +3,7 @@
## Author(s): Tobias Lindahl <[email protected]>
## Kostis Sagonas <[email protected]>
##
-## Copyright: Held by the authors; all rights reserved (2004 - 2009).
-##
-## $Id$
+## Copyright: Held by the authors; all rights reserved (2004 - 2010).
##----------------------------------------------------------------------------
The DIALYZER, a DIscrepany AnaLYZer for ERlang programs.
diff --git a/lib/dialyzer/RELEASE_NOTES b/lib/dialyzer/RELEASE_NOTES
index 8205acf192..b668142327 100644
--- a/lib/dialyzer/RELEASE_NOTES
+++ b/lib/dialyzer/RELEASE_NOTES
@@ -3,11 +3,25 @@
(in reversed chronological order)
==============================================================================
+Version 2.2.0 (in Erlang/OTP R13B04)
+------------------------------------
+ - Much better support for opaque types (thanks to Manouk Manoukian).
+ - Added support for recursive types (experimental).
+ - Added support for parameterized modules.
+ - Dialyzer now warns when -specs state that a function returns some type
+ when in fact it does not.
+ - Added --no_native (-nn) option so that the user can bypass the native code
+ compilation that dialyzer heuristically performs when dialyzing many files.
+ - Fixed minor bug in the dialyzer script allowing the --wx option to bring
+ up the wx-based GUI regardless of its placement in the options list.
+ - Options --apps and -Wrace_conditions, which were added in the previous
+ version, are now properly documented in the manual.
+
Version 2.1.0 (in Erlang/OTP R13B03)
------------------------------------
- Dialyzer can statically detect some kinds of data races in Erlang programs.
Use the new option -Wrace_conditions to enable the race analysis.
- The technique is described in a paper which is available at:
+ The static analysis technique is described in a paper available at:
http://www.it.uu.se/research/group/hipe/dialyzer/publications/races.pdf
- Added support for packages (thanks to Maria Christakis).
- There has been a major change in the default mode of Dialyzer.
@@ -27,7 +41,7 @@ Version 2.1.0 (in Erlang/OTP R13B03)
The new option can also take absolute file names as well as applications.
Note that the application versions that will be included in the PLT are
those that correspond to the Erlang/OTP system which is used.
- - Dialyzer has a new wxWidgets based GUI (thanks to Elli Frangaki)
+ - Dialyzer has a new wxWidgets based GUI (thanks to Elli Fragkaki)
for platforms where the wx application is available.
Version 2.0.0 (in Erlang/OTP R13B02)
diff --git a/lib/dialyzer/doc/manual.txt b/lib/dialyzer/doc/manual.txt
index f1faed3c79..dac61b74b1 100644
--- a/lib/dialyzer/doc/manual.txt
+++ b/lib/dialyzer/doc/manual.txt
@@ -2,8 +2,6 @@
## File: doc/manual.txt
## Author(s): Tobias Lindahl <[email protected]>
## Kostis Sagonas <[email protected]>
-##
-## $Id$
##----------------------------------------------------------------------------
The DIALYZER, a DIscrepany AnaLYZer for ERlang programs.
@@ -126,22 +124,29 @@ The exit status of the command line version is:
Usage: dialyzer [--help] [--version] [--shell] [--quiet] [--verbose]
[-pa dir]* [--plt plt] [-Ddefine]* [-I include_dir]*
- [--output_plt file] [-Wwarn]* [--src]
- [-c applications] [-r applications] [-o outfile]
- [--build_plt] [--add_to_plt] [--remove_from_plt] [--check_plt]
- [--plt_info] [--get_warnings]
+ [--output_plt file] [-Wwarn]* [--src] [--gui | --wx]
+ [files_or_dirs] [-r dirs] [--apps applications] [-o outfile]
+ [--build_plt] [--add_to_plt] [--remove_from_plt]
+ [--check_plt] [--no_check_plt] [--plt_info] [--get_warnings]
+ [--no_native]
Options:
- -c applications (or --command-line applications)
- Use Dialyzer from the command line (no GUI) to detect defects in the
- specified applications (directories or .erl or .beam files)
- -r applications
- Same as -c only that directories are searched recursively for
- subdirectories containing .erl or .beam files (depending on the
- type of analysis)
- -o outfile (or --output outfile)
- When using Dialyzer from the command line, send the analysis
- results in the specified \"outfile\" rather than in stdout
+ files_or_dirs (for backwards compatibility also as: -c files_or_dirs)
+ Use Dialyzer from the command line to detect defects in the
+ specified files or directories containing .erl or .beam files,
+ depending on the type of the analysis
+ -r dirs
+ Same as the previous but the specified directories are searched
+ recursively for subdirectories containing .erl or .beam files in
+ them, depending on the type of analysis
+ --apps applications
+ Option typically used when building or modifying PLT as in:
+ dialyzer --build_plt --apps erts kernel stdlib mnesia ...
+ to conveniently refer to library applications corresponding to the
+ Erlang/OTP installation. However, the option is general and can also
+ be used during analysis in order to refer to Erlang/OTP applications.
+ In addition, file or directory names can also be included, as in:
+ dialyzer --apps inets ssl ./ebin ../other_lib/ebin/my_module.beam
--raw
When using Dialyzer from the command line, output the raw analysis
results (Erlang terms) instead of the formatted result.
@@ -154,14 +159,14 @@ Options:
When analyzing from source, pass the define to Dialyzer (**)
-I include_dir
When analyzing from source, pass the include_dir to Dialyzer (**)
+ -pa dir
+ Include dir in the path for Erlang (useful when analyzing files
+ that have '-include_lib()' directives)
--output_plt file
Store the plt at the specified file after building it
--plt plt
Use the specified plt as the initial plt (if the plt was built
during setup the files will be checked for consistency)
- -pa dir
- Include dir in the path for Erlang (useful when analyzing files
- that have '-include_lib()' directives)
-Wwarn
A family of options which selectively turn on/off warnings
(for help on the names of warnings use dialyzer -Whelp)
@@ -200,6 +205,19 @@ Options:
--get_warnings
Makes Dialyzer emit warnings even when manipulating the plt. Only
emits warnings for files that are actually analyzed.
+ --dump_callgraph file
+ Dump the call graph into the specified file whose format is determined
+ by the file name extension. Supported extensions are: raw, dot, and ps.
+ If something else is used as file name extension, default format '.raw'
+ will be used.
+ --no_native (or -nn)
+ Bypass the native code compilation of some key files that dialyzer
+ heuristically performs when dialyzing many files; this avoids the
+ compilation time but it may result in (much) longer analysis time.
+ --gui
+ Use the gs-based GUI.
+ --wx
+ Use the wx-based GUI.
Note:
* denotes that multiple occurrences of these options are possible.
@@ -221,14 +239,22 @@ Warning options:
Include warnings for function calls which ignore the return value(s).
-Werror_handling ***
Include warnings for functions that only return by means of an exception.
+ -Wrace_conditions ***
+ Include warnings for possible race conditions.
+ -Wbehaviours ***
+ Include warnings about behaviour callbacks which drift from the published
+ recommended interfaces.
-Wunderspecs ***
Warn about underspecified functions
- (the -spec is strictly more allowing than the success typing)
+ (those whose -spec is strictly more allowing than the success typing).
+
+The following options are also available but their use is not recommended:
+(they are mostly for Dialyzer developers and internal debugging)
-Woverspecs ***
Warn about overspecified functions
- (the -spec is strictly less allowing than the success typing)
+ (those whose -spec is strictly less allowing than the success typing).
-Wspecdiffs ***
- Warn when the -spec is different than the success typing
+ Warn when the -spec is different than the success typing.
Note:
*** These are options that turn on warnings rather than turning them off.
@@ -307,9 +333,7 @@ are using frequently.
The PLT is built using the --build_plt option to dialyzer. The
following command builds the recommended minimal PLT for OTP.
-dialyzer --build_plt -r $ERL_TOP/lib/stdlib/ebin\
- $ERL_TOP/lib/kernel/ebin\
- $ERL_TOP/lib/mnesia/ebin
+ dialyzer --build_plt --apps erts kernel stdlib mnesia
Dialyzer will look if there is an environment variable called
$DIALYZER_PLT and place the PLT at this location. If no such variable
@@ -321,22 +345,22 @@ You can also add information to an existing plt using the --add_to_plt
option. Suppose you want to also include the compiler in the PLT and
place it in a new PLT, then give the command
-dialyzer --add_to_plt -r $ERL_TOP/lib/compiler/ebin --output_plt my.plt
+ dialyzer --add_to_plt --apps compiler --output_plt my.plt
Then you would like to add your favorite application my_app to the new
plt.
-dialyzer --add_to_plt --plt my.plt -r <path>/my_app/ebin
+ dialyzer --add_to_plt --plt my.plt -r <path>/my_app/ebin
But you realize that it is unnecessary to have compiler in this one.
-dialyzer --remove_from_plt --plt my.plt -r $ERL_TOP/lib/compiler/ebin
+ dialyzer --remove_from_plt --plt my.plt ---apps compiler
Later, when you have fixed a bug in your application my_app, you want
to update the plt so that it will be fresh the next time you run
Dialyzer, run the command
-dialyzer --check_plt --plt my.plt
+ dialyzer --check_plt --plt my.plt
Dialyzer will then reanalyze the files that have been changed, and the
files that depend on these files. Note that this consistency check
diff --git a/lib/dialyzer/doc/src/Makefile b/lib/dialyzer/doc/src/Makefile
index 37bcb49de0..45b0ffa5ff 100755
--- a/lib/dialyzer/doc/src/Makefile
+++ b/lib/dialyzer/doc/src/Makefile
@@ -13,8 +13,7 @@
# Portions created by Ericsson are Copyright 1999, Ericsson Utvecklings
# AB. All Rights Reserved.''
#
-# $Id$
-#
+
include $(ERL_TOP)/make/target.mk
include $(ERL_TOP)/make/$(TARGET)/otp.mk
diff --git a/lib/dialyzer/doc/src/notes.xml b/lib/dialyzer/doc/src/notes.xml
index 8e8aab60b8..b6106b928a 100755
--- a/lib/dialyzer/doc/src/notes.xml
+++ b/lib/dialyzer/doc/src/notes.xml
@@ -4,7 +4,7 @@
<chapter>
<header>
<copyright>
- <year>2006</year><year>2009</year>
+ <year>2006</year><year>2010</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
@@ -13,12 +13,12 @@
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>Dialyzer Release Notes</title>
@@ -31,6 +31,35 @@
<p>This document describes the changes made to the Dialyzer
application.</p>
+<section><title>Dialyzer 2.2.0</title>
+
+ <section><title>Improvements and New Features</title>
+ <list>
+ <item>
+ <p>Much better support for opaque types (thanks to Manouk
+ Manoukian).</p>
+ <p>Added support for recursive types (experimental).</p>
+ <p>Added support for parameterized modules.</p>
+ <p>Dialyzer now warns when -specs state that a function
+ returns some type when in fact it does not.</p>
+ <p>Added <c>--no_native</c> (<c>-nn</c>) option so that
+ the user can bypass the native code compilation that
+ dialyzer heuristically performs when dialyzing many
+ files.</p>
+ <p>Fixed minor bug in the dialyzer script allowing the
+ --wx option to bring up the wx-based GUI regardless of
+ its placement in the options list.</p>
+ <p>Options --apps and -Wrace_conditions, which were added
+ in the previous version, are now properly documented in
+ the manual.</p>
+ <p>
+ Own Id: OTP-8464</p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
<section><title>Dialyzer 2.1.0</title>
<section><title>Improvements and New Features</title>
diff --git a/lib/dialyzer/doc/warnings.txt b/lib/dialyzer/doc/warnings.txt
index fd8cc0dc60..5c93f15a47 100644
--- a/lib/dialyzer/doc/warnings.txt
+++ b/lib/dialyzer/doc/warnings.txt
@@ -2,8 +2,6 @@
## File: doc/warnings.txt
## Author(s): Tobias Lindahl <[email protected]>
## Kostis Sagonas <[email protected]>
-##
-## $Id$
##----------------------------------------------------------------------------
diff --git a/lib/dialyzer/src/Makefile b/lib/dialyzer/src/Makefile
index ffdc0c6dcd..810f86dc21 100644
--- a/lib/dialyzer/src/Makefile
+++ b/lib/dialyzer/src/Makefile
@@ -1,19 +1,19 @@
#
# %CopyrightBegin%
-#
-# Copyright Ericsson AB 2006-2009. All Rights Reserved.
-#
+#
+# Copyright Ericsson AB 2006-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%
#
#=============================================================================
@@ -48,6 +48,7 @@ DIALYZER_DIR = $(ERL_TOP)/lib/dialyzer
MODULES = \
dialyzer \
dialyzer_analysis_callgraph \
+ dialyzer_behaviours \
dialyzer_callgraph \
dialyzer_cl \
dialyzer_cl_parse \
@@ -128,6 +129,7 @@ $(APPUP_TARGET): $(APPUP_SRC) ../vsn.mk
$(EBIN)/dialyzer.beam: dialyzer.hrl
$(EBIN)/dialyzer_analysis_callgraph.beam: dialyzer.hrl
$(EBIN)/dialyzer_callgraph.beam: dialyzer.hrl
+$(EBIN)/dialyzer_behaviours.beam: dialyzer.hrl
$(EBIN)/dialyzer_cl.beam: dialyzer.hrl ../../kernel/include/file.hrl
$(EBIN)/dialyzer_cl_parse.beam: dialyzer.hrl
$(EBIN)/dialyzer_codeserver.beam: dialyzer.hrl
diff --git a/lib/dialyzer/src/dialyzer.app.src b/lib/dialyzer/src/dialyzer.app.src
index c1d109812c..9222a28a77 100644
--- a/lib/dialyzer/src/dialyzer.app.src
+++ b/lib/dialyzer/src/dialyzer.app.src
@@ -1,20 +1,20 @@
%% This is an -*- erlang -*- file.
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2006-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 2006-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%
%%
@@ -23,6 +23,7 @@
{vsn, "%VSN%"},
{modules, [dialyzer,
dialyzer_analysis_callgraph,
+ dialyzer_behaviours,
dialyzer_callgraph,
dialyzer_cl,
dialyzer_cl_parse,
@@ -30,7 +31,9 @@
dialyzer_contracts,
dialyzer_dataflow,
dialyzer_dep,
+ dialyzer_explanation,
dialyzer_gui,
+ dialyzer_gui_wx,
dialyzer_options,
dialyzer_plt,
dialyzer_races,
@@ -38,5 +41,5 @@
dialyzer_typesig,
dialyzer_utils]},
{registered, []},
- {applications, [compiler, gs, hipe, kernel, stdlib]},
+ {applications, [compiler, gs, hipe, kernel, stdlib, wx]},
{env, []}]}.
diff --git a/lib/dialyzer/src/dialyzer.erl b/lib/dialyzer/src/dialyzer.erl
index c1897ed892..3b7b68e8c4 100644
--- a/lib/dialyzer/src/dialyzer.erl
+++ b/lib/dialyzer/src/dialyzer.erl
@@ -1,20 +1,20 @@
%% -*- erlang-indent-level: 2 -*-
%%-----------------------------------------------------------------------
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2006-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 2006-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%
%%
@@ -379,7 +379,7 @@ message_to_string({spec_missing_fun, [M, F, A]}) ->
[M, F, A]);
%%----- Warnings for opaque type violations -------------------
message_to_string({call_with_opaque, [M, F, Args, ArgNs, ExpArgs]}) ->
- io_lib:format("The call ~w:~w~s contains ~s when ~s\n",
+ io_lib:format("The call ~w:~w~s contains ~s argument when ~s\n",
[M, F, Args, form_positions(ArgNs), form_expected(ExpArgs)]);
message_to_string({call_without_opaque, [M, F, Args, ExpectedTriples]}) ->
io_lib:format("The call ~w:~w~s does not have ~s\n",
@@ -403,8 +403,25 @@ message_to_string({opaque_type_test, [Fun, Opaque]}) ->
io_lib:format("The type test ~s(~s) breaks the opaqueness of the term ~s\n", [Fun, Opaque, Opaque]);
%%----- Warnings for concurrency errors --------------------
message_to_string({race_condition, [M, F, Args, Reason]}) ->
- io_lib:format("The call ~w:~w~s ~s\n", [M, F, Args, Reason]).
-
+ io_lib:format("The call ~w:~w~s ~s\n", [M, F, Args, Reason]);
+%%----- Warnings for behaviour errors --------------------
+message_to_string({callback_type_mismatch, [B, F, A, O]}) ->
+ io_lib:format("The inferred return type of the ~w/~w callback includes the"
+ " type ~s which is not a valid return for the ~w behaviour\n",
+ [F, A, erl_types:t_to_string(O), B]);
+message_to_string({callback_arg_type_mismatch, [B, F, A, N, O]}) ->
+ io_lib:format("The inferred type of the ~s argument of ~w/~w callback"
+ " includes the type ~s which is not valid for the ~w behaviour"
+ "\n", [ordinal(N), F, A, erl_types:t_to_string(O), B]);
+message_to_string({callback_missing, [B, F, A]}) ->
+ io_lib:format("Undefined callback function ~w/~w (behaviour '~w')\n",
+ [F, A, B]);
+message_to_string({invalid_spec, [B, F, A, R]}) ->
+ io_lib:format("The spec for the ~w:~w/~w callback is not correct: ~s\n",
+ [B, F, A, R]);
+message_to_string({spec_missing, [B, F, A]}) ->
+ io_lib:format("Type info about ~w:~w/~w callback is not available\n",
+ [B, F, A]).
%%-----------------------------------------------------------------------------
%% Auxiliary functions below
@@ -421,8 +438,8 @@ call_or_apply_to_string(ArgNs, FailReason, SigArgs, SigRet,
io_lib:format("will never return since the success typing arguments"
" are ~s\n", [SigArgs]);
false ->
- io_lib:format("will never return since it differs in argument"
- " ~s from the success typing arguments: ~s\n",
+ io_lib:format("will never return since it differs in the ~s argument"
+ " from the success typing arguments: ~s\n",
[PositionString, SigArgs])
end;
only_contract ->
@@ -431,7 +448,7 @@ call_or_apply_to_string(ArgNs, FailReason, SigArgs, SigRet,
%% We do not know which arguments caused the failure
io_lib:format("breaks the contract ~s\n", [Contract]);
false ->
- io_lib:format("breaks the contract ~s in argument ~s\n",
+ io_lib:format("breaks the contract ~s in the ~s argument\n",
[Contract, PositionString])
end;
both ->
@@ -441,22 +458,26 @@ call_or_apply_to_string(ArgNs, FailReason, SigArgs, SigRet,
form_positions(ArgNs) ->
case ArgNs of
- [_] -> "an opaque term in ";
- [_,_|_] -> "opaque terms in "
- end ++ form_position_string(ArgNs).
+ [_] -> "an opaque term as ";
+ [_,_|_] -> "opaque terms as "
+ end ++ form_position_string(ArgNs) ++
+ case ArgNs of
+ [_] -> " argument";
+ [_,_|_] -> " arguments"
+ end.
%% We know which positions N are to blame;
%% the list of triples will never be empty.
form_expected_without_opaque([{N, T, TStr}]) ->
case erl_types:t_is_opaque(T) of
true ->
- io_lib:format("an opaque term of type ~s in ", [TStr]);
+ io_lib:format("an opaque term of type ~s as ", [TStr]);
false ->
- io_lib:format("a term of type ~s (with opaque subterms) in ", [TStr])
- end ++ form_position_string([N]);
+ io_lib:format("a term of type ~s (with opaque subterms) as ", [TStr])
+ end ++ form_position_string([N]) ++ " argument";
form_expected_without_opaque(ExpectedTriples) -> %% TODO: can do much better here
{ArgNs, _Ts, _TStrs} = lists:unzip3(ExpectedTriples),
- "opaque terms in " ++ form_position_string(ArgNs).
+ "opaque terms as " ++ form_position_string(ArgNs) ++ " arguments".
form_expected(ExpectedArgs) ->
case ExpectedArgs of
@@ -472,9 +493,15 @@ form_expected(ExpectedArgs) ->
form_position_string(ArgNs) ->
case ArgNs of
[] -> "";
- [N1] -> io_lib:format("position ~w", [N1]);
+ [N1] -> ordinal(N1);
[_,_|_] ->
- " and"++ArgString = lists:flatten([io_lib:format(" and ~w", [N])
- || N <- ArgNs]),
- "positions" ++ ArgString
+ [Last|Prevs] = lists:reverse(ArgNs),
+ ", " ++ Head = lists:flatten([io_lib:format(", ~s",[ordinal(N)]) ||
+ N <- lists:reverse(Prevs)]),
+ Head ++ " and " ++ ordinal(Last)
end.
+
+ordinal(1) -> "1st";
+ordinal(2) -> "2nd";
+ordinal(3) -> "3rd";
+ordinal(N) when is_integer(N) -> io_lib:format("~wth",[N]).
diff --git a/lib/dialyzer/src/dialyzer.hrl b/lib/dialyzer/src/dialyzer.hrl
index f0f9bd25d7..2da8ed2e5d 100644
--- a/lib/dialyzer/src/dialyzer.hrl
+++ b/lib/dialyzer/src/dialyzer.hrl
@@ -1,20 +1,20 @@
%%% This is an -*- Erlang -*- file.
%%%
%%% %CopyrightBegin%
-%%%
-%%% Copyright Ericsson AB 2006-2009. All Rights Reserved.
-%%%
+%%%
+%%% Copyright Ericsson AB 2006-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%
%%%
%%%-------------------------------------------------------------------
@@ -55,6 +55,7 @@
-define(WARN_CALLGRAPH, warn_callgraph).
-define(WARN_UNMATCHED_RETURN, warn_umatched_return).
-define(WARN_RACE_CONDITION, warn_race_condition).
+-define(WARN_BEHAVIOUR,warn_behaviour).
%%
%% The following type has double role:
@@ -68,7 +69,8 @@
| ?WARN_CONTRACT_TYPES | ?WARN_CONTRACT_SYNTAX
| ?WARN_CONTRACT_NOT_EQUAL | ?WARN_CONTRACT_SUBTYPE
| ?WARN_CONTRACT_SUPERTYPE | ?WARN_CALLGRAPH
- | ?WARN_UNMATCHED_RETURN | ?WARN_RACE_CONDITION.
+ | ?WARN_UNMATCHED_RETURN | ?WARN_RACE_CONDITION
+ | ?WARN_BEHAVIOUR.
%%
%% This is the representation of each warning as they will be returned
@@ -118,6 +120,7 @@
plt :: dialyzer_plt:plt(),
use_contracts = true :: boolean(),
race_detection = false :: boolean(),
+ behaviours_chk = false :: boolean(),
callgraph_file = "" :: file:filename()}).
-record(options, {files = [] :: [file:filename()],
diff --git a/lib/dialyzer/src/dialyzer_analysis_callgraph.erl b/lib/dialyzer/src/dialyzer_analysis_callgraph.erl
index 97d63a1f14..ab1bbe5ade 100644
--- a/lib/dialyzer/src/dialyzer_analysis_callgraph.erl
+++ b/lib/dialyzer/src/dialyzer_analysis_callgraph.erl
@@ -1,20 +1,20 @@
%% -*- erlang-indent-level: 2 -*-
%%--------------------------------------------------------------------
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2006-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 2006-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%
%%
@@ -43,7 +43,8 @@
parent :: pid(),
plt :: dialyzer_plt:plt(),
start_from = byte_code :: start_from(),
- use_contracts = true :: boolean()
+ use_contracts = true :: boolean(),
+ behaviours = {false,[]} :: {boolean(),[atom()]}
}).
-record(server_state, {parent :: pid(), legal_warnings :: [dial_warn_tag()]}).
@@ -56,7 +57,9 @@
start(Parent, LegalWarnings, Analysis) ->
RacesOn = ordsets:is_element(?WARN_RACE_CONDITION, LegalWarnings),
- Analysis0 = Analysis#analysis{race_detection = RacesOn},
+ BehavOn = ordsets:is_element(?WARN_BEHAVIOUR, LegalWarnings),
+ Analysis0 = Analysis#analysis{race_detection = RacesOn,
+ behaviours_chk = BehavOn},
Analysis1 = expand_files(Analysis0),
Analysis2 = run_analysis(Analysis1),
State = #server_state{parent = Parent, legal_warnings = LegalWarnings},
@@ -93,6 +96,9 @@ loop(#server_state{parent = Parent, legal_warnings = LegalWarnings} = State,
end;
{AnalPid, ext_calls, NewExtCalls} ->
loop(State, Analysis, NewExtCalls);
+ {AnalPid, unknown_behaviours, UnknownBehaviour} ->
+ send_unknown_behaviours(Parent, UnknownBehaviour),
+ loop(State, Analysis, ExtCalls);
{AnalPid, mod_deps, ModDeps} ->
send_mod_deps(Parent, ModDeps),
loop(State, Analysis, ExtCalls);
@@ -116,7 +122,9 @@ analysis_start(Parent, Analysis) ->
plt = Plt,
parent = Parent,
start_from = Analysis#analysis.start_from,
- use_contracts = Analysis#analysis.use_contracts
+ use_contracts = Analysis#analysis.use_contracts,
+ behaviours = {Analysis#analysis.behaviours_chk,
+ []}
},
Files = ordsets:from_list(Analysis#analysis.files),
{Callgraph, NoWarn, TmpCServer0} = compile_and_store(Files, State),
@@ -167,11 +175,13 @@ analyze_callgraph(Callgraph, State) ->
State#analysis_state{plt = NewPlt};
succ_typings ->
NoWarn = State#analysis_state.no_warn_unused,
+ {BehavioursChk, _Known} = State#analysis_state.behaviours,
DocPlt = State#analysis_state.doc_plt,
Callgraph1 = dialyzer_callgraph:finalize(Callgraph),
{Warnings, NewPlt, NewDocPlt} =
dialyzer_succ_typings:get_warnings(Callgraph1, Plt, DocPlt,
- Codeserver, NoWarn, Parent),
+ Codeserver, NoWarn, Parent,
+ BehavioursChk),
dialyzer_callgraph:delete(Callgraph1),
send_warnings(State#analysis_state.parent, Warnings),
State#analysis_state{plt = NewPlt, doc_plt = NewDocPlt}
@@ -186,7 +196,9 @@ compile_and_store(Files, #analysis_state{codeserver = CServer,
include_dirs = Dirs,
parent = Parent,
use_contracts = UseContracts,
- start_from = StartFrom} = State) ->
+ start_from = StartFrom,
+ behaviours = {BehChk, _}
+ } = State) ->
send_log(Parent, "Reading files and computing callgraph... "),
{T1, _} = statistics(runtime),
Includes = [{i, D} || D <- Dirs],
@@ -234,18 +246,37 @@ compile_and_store(Files, #analysis_state{codeserver = CServer,
{T2, _} = statistics(runtime),
Msg1 = io_lib:format("done in ~.2f secs\nRemoving edges... ", [(T2-T1)/1000]),
send_log(Parent, Msg1),
- NewCallgraph2 = cleanup_callgraph(State, NewCServer, NewCallgraph1, Modules),
+ {KnownBehaviours, UnknownBehaviours} =
+ dialyzer_behaviours:get_behaviours(Modules, NewCServer),
+ if UnknownBehaviours =:= [] -> ok;
+ true -> send_unknown_behaviours(Parent, UnknownBehaviours)
+ end,
+ State1 = State#analysis_state{behaviours = {BehChk,KnownBehaviours}},
+ NewCallgraph2 = cleanup_callgraph(State1, NewCServer, NewCallgraph1, Modules),
{T3, _} = statistics(runtime),
Msg2 = io_lib:format("done in ~.2f secs\n", [(T3-T2)/1000]),
send_log(Parent, Msg2),
{NewCallgraph2, sets:from_list(NoWarn), NewCServer}.
cleanup_callgraph(#analysis_state{plt = InitPlt, parent = Parent,
- codeserver = CodeServer},
+ codeserver = CodeServer,
+ behaviours = {BehChk, KnownBehaviours}
+ },
CServer, Callgraph, Modules) ->
ModuleDeps = dialyzer_callgraph:module_deps(Callgraph),
send_mod_deps(Parent, ModuleDeps),
{Callgraph1, ExtCalls} = dialyzer_callgraph:remove_external(Callgraph),
+ if BehChk ->
+ RelevantAPICalls =
+ dialyzer_behaviours:get_behaviour_apis(KnownBehaviours),
+ BehaviourAPICalls = [Call || {_From, To} = Call <- ExtCalls,
+ lists:member(To, RelevantAPICalls)],
+ Callgraph2 =
+ dialyzer_callgraph:put_behaviour_api_calls(BehaviourAPICalls,
+ Callgraph1);
+ true ->
+ Callgraph2 = Callgraph1
+ end,
ExtCalls1 = [Call || Call = {_From, To} <- ExtCalls,
not dialyzer_plt:contains_mfa(InitPlt, To)],
{BadCalls1, RealExtCalls} =
@@ -268,7 +299,7 @@ cleanup_callgraph(#analysis_state{plt = InitPlt, parent = Parent,
true ->
send_ext_calls(Parent, lists:usort([To || {_From, To} <- RealExtCalls]))
end,
- Callgraph1.
+ Callgraph2.
compile_src(File, Includes, Defines, Callgraph, CServer, UseContracts) ->
DefaultIncludes = default_includes(filename:dirname(File)),
@@ -445,6 +476,10 @@ send_ext_calls(Parent, ExtCalls) ->
Parent ! {self(), ext_calls, ExtCalls},
ok.
+send_unknown_behaviours(Parent, UnknownBehaviours) ->
+ Parent ! {self(), unknown_behaviours, UnknownBehaviours},
+ ok.
+
send_codeserver_plt(Parent, CServer, Plt ) ->
Parent ! {self(), cserver, CServer, Plt},
ok.
diff --git a/lib/dialyzer/src/dialyzer_behaviours.erl b/lib/dialyzer/src/dialyzer_behaviours.erl
new file mode 100644
index 0000000000..4e8dceaa8e
--- /dev/null
+++ b/lib/dialyzer/src/dialyzer_behaviours.erl
@@ -0,0 +1,324 @@
+%% -*- erlang-indent-level: 2 -*-
+%%-----------------------------------------------------------------------
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 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%
+%%
+
+%%%-------------------------------------------------------------------
+%%% File : dialyzer_behaviours.erl
+%%% Authors : Stavros Aronis <[email protected]>
+%%% Description : Tools for analyzing proper behaviour usage.
+%%%
+%%% Created : 28 Oct 2009 by Stavros Aronis <[email protected]>
+%%%-------------------------------------------------------------------
+%%% NOTE: This module is currently experimental -- do NOT rely on it!
+%%%-------------------------------------------------------------------
+
+-module(dialyzer_behaviours).
+
+-export([check_callbacks/4, get_behaviours/2, get_behaviour_apis/1,
+ translate_behaviour_api_call/5, translatable_behaviours/1,
+ translate_callgraph/3]).
+
+%%--------------------------------------------------------------------
+
+-include("dialyzer.hrl").
+
+%%--------------------------------------------------------------------
+
+-record(state, {plt :: dialyzer_plt:plt(),
+ codeserver :: dialyzer_codeserver:codeserver(),
+ filename :: string(),
+ behlines :: [{atom(), number()}]}).
+
+-spec get_behaviours([module()], dialyzer_codeserver:codeserver()) ->
+ {[atom()], [atom()]}.
+
+get_behaviours(Modules, Codeserver) ->
+ get_behaviours(Modules, Codeserver, [], []).
+
+-spec check_callbacks(module(), [{cerl:cerl(), cerl:cerl()}],
+ dialyzer_plt:plt(),
+ dialyzer_codeserver:codeserver()) -> [dial_warning()].
+
+check_callbacks(Module, Attrs, Plt, Codeserver) ->
+ {Behaviours, BehLines} = get_behaviours(Attrs),
+ case Behaviours of
+ [] -> [];
+ _ -> {_Var,Code} =
+ dialyzer_codeserver:lookup_mfa_code({Module,module_info,0},
+ Codeserver),
+ File = get_file(cerl:get_ann(Code)),
+ State = #state{plt = Plt, codeserver = Codeserver, filename = File,
+ behlines = BehLines},
+ Warnings = get_warnings(Module, Behaviours, State),
+ [add_tag_file_line(Module, W, State) || W <- Warnings]
+ end.
+
+-spec translatable_behaviours(cerl:c_module()) -> [{atom(),[_]}].
+
+translatable_behaviours(Tree) ->
+ Attrs = cerl:module_attrs(Tree),
+ {Behaviours, _BehLines} = get_behaviours(Attrs),
+ [{B, Calls} || B <- Behaviours, (Calls = behaviour_api_calls(B)) =/= []].
+
+-spec get_behaviour_apis([atom()]) -> [mfa()].
+
+get_behaviour_apis(Behaviours) ->
+ get_behaviour_apis(Behaviours, []).
+
+-spec translate_behaviour_api_call(_, _, _, _, _) -> _.
+
+translate_behaviour_api_call(_Fun, _ArgTypes, _Args, _Module, []) ->
+ plain_call;
+translate_behaviour_api_call({Module, Fun, Arity}, ArgTypes, Args,
+ CallbackModule, BehApiInfo) ->
+ case lists:keyfind(Module, 1, BehApiInfo) of
+ false -> plain_call;
+ {Module, Calls} ->
+ case lists:keyfind({Fun, Arity}, 1, Calls) of
+ false -> plain_call;
+ {{Fun, Arity}, {CFun, CArity, COrder}} ->
+ {{CallbackModule, CFun, CArity},
+ [nth_or_0(N, ArgTypes, erl_types:t_any()) || N <-COrder],
+ [nth_or_0(N, Args, bypassed) || N <-COrder]}
+ end
+ end;
+translate_behaviour_api_call(_Fun, _ArgTypes, _Args, _Module, _BehApiInfo) ->
+ plain_call.
+
+-spec translate_callgraph([{atom(), _}], atom(), dialyzer_callgraph:callgraph())
+ -> dialyzer_callgraph:callgraph().
+
+translate_callgraph([{Behaviour,_}|Behaviours], Module, Callgraph) ->
+ UsedCalls = [Call || {_From, {M, _F, _A}} = Call <-
+ dialyzer_callgraph:get_behaviour_api_calls(Callgraph),
+ M =:= Behaviour],
+ Calls = [{{Behaviour, API, Arity}, Callback} ||
+ {{API, Arity}, Callback} <- behaviour_api_calls(Behaviour)],
+ DirectCalls = [{From, {Module, Fun, Arity}} ||
+ {From, To} <- UsedCalls,{API, {Fun, Arity, _Ord}} <- Calls,
+ To =:= API],
+ NewCallgraph = dialyzer_callgraph:add_edges(DirectCalls, Callgraph),
+ translate_callgraph(Behaviours, Module, NewCallgraph);
+translate_callgraph([], _Module, Callgraph) ->
+ Callgraph.
+
+%%--------------------------------------------------------------------
+
+get_behaviours(Attrs) ->
+ BehaviourListsAndLine = [{cerl:concrete(L2), hd(cerl:get_ann(L2))} ||
+ {L1, L2} <- Attrs, cerl:is_literal(L1),
+ cerl:is_literal(L2), cerl:concrete(L1) =:= 'behaviour'],
+ Behaviours = lists:append([Behs || {Behs,_} <- BehaviourListsAndLine]),
+ BehLines = [{B,L} || {L1,L} <- BehaviourListsAndLine, B <- L1],
+ {Behaviours, BehLines}.
+
+get_warnings(Module, Behaviours, State) ->
+ get_warnings(Module, Behaviours, State, []).
+
+get_warnings(_, [], _, Acc) ->
+ Acc;
+get_warnings(Module, [Behaviour|Rest], State, Acc) ->
+ Warnings = check_behaviour(Module, Behaviour, State),
+ get_warnings(Module, Rest, State, Warnings ++ Acc).
+
+check_behaviour(Module, Behaviour, State) ->
+ try
+ Callbacks = Behaviour:behaviour_info(callbacks),
+ Fun = fun({_,_,_}) -> true;
+ (_) -> false
+ end,
+ case lists:any(Fun, Callbacks) of
+ true -> check_all_callbacks(Module, Behaviour, Callbacks, State);
+ false -> []
+ end
+ catch
+ _:_ -> []
+ end.
+
+check_all_callbacks(Module, Behaviour, Callbacks, State) ->
+ check_all_callbacks(Module, Behaviour, Callbacks, State, []).
+
+check_all_callbacks(_Module, _Behaviour, [], _State, Acc) ->
+ Acc;
+check_all_callbacks(Module, Behaviour, [{Fun, Arity, Spec}|Rest], State, Acc) ->
+ Records = dialyzer_codeserver:get_records(State#state.codeserver),
+ case parse_spec(Spec, Records) of
+ {ok, Fun, Type} ->
+ RetType = erl_types:t_fun_range(Type),
+ ArgTypes = erl_types:t_fun_args(Type),
+ Warns = check_callback(Module, Behaviour, Fun, Arity, RetType,
+ ArgTypes, State#state.plt);
+ Else ->
+ Warns = [{invalid_spec, [Behaviour, Fun, Arity, reason_spec_error(Else)]}]
+ end,
+ check_all_callbacks(Module, Behaviour, Rest, State, Warns ++ Acc);
+check_all_callbacks(Module, Behaviour, [{Fun, Arity}|Rest], State, Acc) ->
+ Warns = {spec_missing, [Behaviour, Fun, Arity]},
+ check_all_callbacks(Module, Behaviour, Rest, State, [Warns|Acc]).
+
+parse_spec(String, Records) ->
+ case erl_scan:string(String) of
+ {ok, Tokens, _} ->
+ case erl_parse:parse(Tokens) of
+ {ok, Form} ->
+ case Form of
+ {attribute, _, 'spec', {{Fun, _}, [TypeForm|_Constraint]}} ->
+ MaybeRemoteType = erl_types:t_from_form(TypeForm),
+ try
+ Type = erl_types:t_solve_remote(MaybeRemoteType, Records),
+ {ok, Fun, Type}
+ catch
+ throw:{error,Msg} -> {spec_remote_error, Msg}
+ end;
+ _Other -> not_a_spec
+ end;
+ {error, {Line, _, Msg}} -> {spec_parser_error, Line, Msg}
+ end;
+ _Other ->
+ lexer_error
+ end.
+
+reason_spec_error({spec_remote_error, Msg}) ->
+ io_lib:format("Remote type solver error: ~s. Make sure the behaviour source is included in the analysis or the plt",[Msg]);
+reason_spec_error(not_a_spec) ->
+ "This is not a spec";
+reason_spec_error({spec_parser_error, Line, Msg}) ->
+ io_lib:format("~s line of the spec: ~s", [ordinal(Line),Msg]);
+reason_spec_error(lexer_error) ->
+ "Lexical error".
+
+ordinal(1) -> "1st";
+ordinal(2) -> "2nd";
+ordinal(3) -> "3rd";
+ordinal(N) when is_integer(N) -> io_lib:format("~wth",[N]).
+
+check_callback(Module, Behaviour, Fun, Arity, XRetType, XArgTypes, Plt) ->
+ LookupType = dialyzer_plt:lookup(Plt, {Module, Fun, Arity}),
+ case LookupType of
+ {value, {Type,Args}} ->
+ Warn1 = case unifiable(Type, XRetType) of
+ [] -> [];
+ Offenders ->
+ [{callback_type_mismatch,
+ [Behaviour, Fun, Arity, erl_types:t_sup(Offenders)]}]
+ end,
+ ZipArgs = lists:zip3(lists:seq(1, Arity), Args, XArgTypes),
+ Warn2 = [{callback_arg_type_mismatch,
+ [Behaviour, Fun, Arity, N,
+ erl_types:t_sup(Offenders)]} ||
+ {Offenders, N} <- [check_callback_1(V) || V <- ZipArgs],
+ Offenders =/= []],
+ Warn1 ++ Warn2;
+ _ -> [{callback_missing, [Behaviour, Fun, Arity]}]
+ end.
+
+check_callback_1({N, T1, T2}) ->
+ {unifiable(T1, T2), N}.
+
+unifiable(Type1, Type2) ->
+ List1 = erl_types:t_elements(Type1),
+ List2 = erl_types:t_elements(Type2),
+ [T || T <- List1,
+ lists:all(fun(T1) ->
+ erl_types:t_is_none(erl_types:t_inf(T, T1, opaque))
+ end, List2)].
+
+add_tag_file_line(_Module, {Tag, [B|_R]} = Warn, State)
+ when Tag =:= spec_missing;
+ Tag =:= invalid_spec;
+ Tag =:= callback_missing ->
+ {B, Line} = lists:keyfind(B, 1, State#state.behlines),
+ {?WARN_BEHAVIOUR, {State#state.filename, Line}, Warn};
+add_tag_file_line(Module, {_Tag, [_B, Fun, Arity|_R]} = Warn, State) ->
+ {_A, FunCode} =
+ dialyzer_codeserver:lookup_mfa_code({Module, Fun, Arity},
+ State#state.codeserver),
+ Anns = cerl:get_ann(FunCode),
+ FileLine = {get_file(Anns), get_line(Anns)},
+ {?WARN_BEHAVIOUR, FileLine, Warn}.
+
+get_line([Line|_]) when is_integer(Line) -> Line;
+get_line([_|Tail]) -> get_line(Tail);
+get_line([]) -> -1.
+
+get_file([{file, File}|_]) -> File;
+get_file([_|Tail]) -> get_file(Tail).
+
+%%------------------------------------------------------------------------------
+
+get_behaviours([], _Codeserver, KnownAcc, UnknownAcc) ->
+ {KnownAcc, UnknownAcc};
+get_behaviours([M|Rest], Codeserver, KnownAcc, UnknownAcc) ->
+ Tree = dialyzer_codeserver:lookup_mod_code(M, Codeserver),
+ Attrs = cerl:module_attrs(Tree),
+ {Behaviours, _BehLines} = get_behaviours(Attrs),
+ {Known, Unknown} = call_behaviours(Behaviours),
+ get_behaviours(Rest, Codeserver, Known ++ KnownAcc, Unknown ++ UnknownAcc).
+
+call_behaviours(Behaviours) ->
+ call_behaviours(Behaviours, [], []).
+call_behaviours([], KnownAcc, UnknownAcc) ->
+ {lists:reverse(KnownAcc), lists:reverse(UnknownAcc)};
+call_behaviours([Behaviour|Rest], KnownAcc, UnknownAcc) ->
+ try
+ Callbacks = Behaviour:behaviour_info(callbacks),
+ Fun = fun({_,_,_}) -> true;
+ (_) -> false
+ end,
+ case lists:any(Fun, Callbacks) of
+ false -> call_behaviours(Rest, KnownAcc, [Behaviour | UnknownAcc]);
+ true -> call_behaviours(Rest, [Behaviour | KnownAcc], UnknownAcc)
+ end
+ catch
+ _:_ -> call_behaviours(Rest, KnownAcc, [Behaviour | UnknownAcc])
+ end.
+
+%-------------------------------------------------------------------------------
+
+get_behaviour_apis([], Acc) ->
+ Acc;
+get_behaviour_apis([Behaviour | Rest], Acc) ->
+ MFAs = [{Behaviour, Fun, Arity} ||
+ {{Fun, Arity}, _} <- behaviour_api_calls(Behaviour)],
+ get_behaviour_apis(Rest, MFAs ++ Acc).
+
+%-------------------------------------------------------------------------------
+
+nth_or_0(0, _List, Zero) ->
+ Zero;
+nth_or_0(N, List, _Zero) ->
+ lists:nth(N, List).
+
+%-------------------------------------------------------------------------------
+
+behaviour_api_calls(gen_server) ->
+ [{{start_link, 3}, {init, 1, [2]}},
+ {{start_link, 4}, {init, 1, [3]}},
+ {{start, 3}, {init, 1, [2]}},
+ {{start, 4}, {init, 1, [3]}},
+ {{call, 2}, {handle_call, 3, [2, 0, 0]}},
+ {{call, 3}, {handle_call, 3, [2, 0, 0]}},
+ {{multi_call, 2}, {handle_call, 3, [2, 0, 0]}},
+ {{multi_call, 3}, {handle_call, 3, [3, 0, 0]}},
+ {{multi_call, 4}, {handle_call, 3, [3, 0, 0]}},
+ {{cast, 2}, {handle_cast, 2, [2, 0]}},
+ {{abcast, 2}, {handle_cast, 2, [2, 0]}},
+ {{abcast, 3}, {handle_cast, 2, [3, 0]}}];
+behaviour_api_calls(_Other) ->
+ [].
diff --git a/lib/dialyzer/src/dialyzer_callgraph.erl b/lib/dialyzer/src/dialyzer_callgraph.erl
index 21d31df71c..f932f43548 100644
--- a/lib/dialyzer/src/dialyzer_callgraph.erl
+++ b/lib/dialyzer/src/dialyzer_callgraph.erl
@@ -1,20 +1,20 @@
%% -*- erlang-indent-level: 2 -*-
%%-----------------------------------------------------------------------
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2006-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 2006-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%
%%
@@ -27,7 +27,8 @@
%%%-------------------------------------------------------------------
-module(dialyzer_callgraph).
--export([all_nodes/1,
+-export([add_edges/2,
+ all_nodes/1,
delete/1,
finalize/1,
is_escaping/2,
@@ -54,8 +55,9 @@
-export([cleanup/1, get_digraph/1, get_named_tables/1, get_public_tables/1,
get_race_code/1, get_race_detection/1, race_code_new/1,
- put_race_code/2, put_race_detection/2, put_named_tables/2,
- put_public_tables/2]).
+ put_digraph/2, put_race_code/2, put_race_detection/2,
+ put_named_tables/2, put_public_tables/2, put_behaviour_api_calls/2,
+ get_behaviour_api_calls/1]).
-include("dialyzer.hrl").
@@ -97,7 +99,8 @@
race_code = dict:new() :: dict(),
public_tables = [] :: [label()],
named_tables = [] :: [string()],
- race_detection = false :: boolean()}).
+ race_detection = false :: boolean(),
+ beh_api_calls = [] :: [{mfa(), mfa()}]}).
%% Exported Types
@@ -608,15 +611,17 @@ digraph_reaching_subgraph(Funs, DG) ->
-spec cleanup(callgraph()) -> callgraph().
-cleanup(#callgraph{name_map = NameMap,
- rev_name_map = RevNameMap,
- public_tables = PublicTables,
- named_tables = NamedTables,
- race_code = RaceCode}) ->
- #callgraph{name_map = NameMap,
- rev_name_map = RevNameMap,
- public_tables = PublicTables,
- named_tables = NamedTables,
+cleanup(#callgraph{digraph = Digraph,
+ name_map = NameMap,
+ rev_name_map = RevNameMap,
+ public_tables = PublicTables,
+ named_tables = NamedTables,
+ race_code = RaceCode}) ->
+ #callgraph{digraph = Digraph,
+ name_map = NameMap,
+ rev_name_map = RevNameMap,
+ public_tables = PublicTables,
+ named_tables = NamedTables,
race_code = RaceCode}.
-spec get_digraph(callgraph()) -> digraph().
@@ -649,6 +654,11 @@ get_race_detection(#callgraph{race_detection = RD}) ->
race_code_new(Callgraph) ->
Callgraph#callgraph{race_code = dict:new()}.
+-spec put_digraph(digraph(), callgraph()) -> callgraph().
+
+put_digraph(Digraph, Callgraph) ->
+ Callgraph#callgraph{digraph = Digraph}.
+
-spec put_race_code(dict(), callgraph()) -> callgraph().
put_race_code(RaceCode, Callgraph) ->
@@ -695,3 +705,15 @@ to_ps(#callgraph{} = CG, File, Args) ->
Command = io_lib:format("dot -Tps ~s -o ~s ~s", [Args, File, Dot_File]),
_ = os:cmd(Command),
ok.
+
+%-------------------------------------------------------------------------------
+
+-spec put_behaviour_api_calls([{mfa(), mfa()}], callgraph()) -> callgraph().
+
+put_behaviour_api_calls(Calls, Callgraph) ->
+ Callgraph#callgraph{beh_api_calls = Calls}.
+
+-spec get_behaviour_api_calls(callgraph()) -> [{mfa(), mfa()}].
+
+get_behaviour_api_calls(Callgraph) ->
+ Callgraph#callgraph.beh_api_calls.
diff --git a/lib/dialyzer/src/dialyzer_cl.erl b/lib/dialyzer/src/dialyzer_cl.erl
index ab56a4e6d3..d533e734db 100644
--- a/lib/dialyzer/src/dialyzer_cl.erl
+++ b/lib/dialyzer/src/dialyzer_cl.erl
@@ -1,20 +1,20 @@
%% -*- erlang-indent-level: 2 -*-
%%-------------------------------------------------------------------
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2006-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 2006-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%
%%
@@ -46,7 +46,8 @@
plt_info = none :: 'none' | dialyzer_plt:plt_info(),
report_mode = normal :: rep_mode(),
return_status= ?RET_NOTHING_SUSPICIOUS :: dial_ret(),
- stored_warnings = [] :: [dial_warning()]
+ stored_warnings = [] :: [dial_warning()],
+ unknown_behaviours = [] :: [atom()]
}).
%%--------------------------------------------------------------------
@@ -440,7 +441,9 @@ expand_dependent_modules_1([], Included, _ModDeps) ->
-spec hipe_compile([file:filename()], #options{}) -> 'ok'.
hipe_compile(Files, #options{erlang_mode = ErlangMode} = Options) ->
- case (length(Files) < ?MIN_FILES_FOR_NATIVE_COMPILE) orelse ErlangMode of
+ NoNative = (get(dialyzer_options_native) =:= false),
+ FewFiles = (length(Files) < ?MIN_FILES_FOR_NATIVE_COMPILE),
+ case NoNative orelse FewFiles orelse ErlangMode of
true -> ok;
false ->
case erlang:system_info(hipe_architecture) of
@@ -528,6 +531,9 @@ cl_loop(State, LogCache) ->
{BackendPid, warnings, Warnings} ->
NewState = store_warnings(State, Warnings),
cl_loop(NewState, LogCache);
+ {BackendPid, unknown_behaviours, Behaviours} ->
+ NewState = store_unknown_behaviours(State, Behaviours),
+ cl_loop(NewState, LogCache);
{BackendPid, done, NewPlt, _NewDocPlt} ->
return_value(State, NewPlt);
{BackendPid, ext_calls, ExtCalls} ->
@@ -568,6 +574,11 @@ format_log_cache(LogCache) ->
store_warnings(#cl_state{stored_warnings = StoredWarnings} = St, Warnings) ->
St#cl_state{stored_warnings = StoredWarnings ++ Warnings}.
+-spec store_unknown_behaviours(#cl_state{}, [_]) -> #cl_state{}.
+
+store_unknown_behaviours(#cl_state{unknown_behaviours = Behs} = St, Beh) ->
+ St#cl_state{unknown_behaviours = Beh ++ Behs}.
+
-spec error(string()) -> no_return().
error(Msg) ->
@@ -602,6 +613,7 @@ return_value(State = #cl_state{erlang_mode = ErlangMode,
false ->
print_warnings(State),
print_ext_calls(State),
+ print_unknown_behaviours(State),
maybe_close_output_file(State),
{RetValue, []};
true ->
@@ -637,6 +649,40 @@ do_print_ext_calls(Output, [{M,F,A}|T], Before) ->
do_print_ext_calls(_, [], _) ->
ok.
+%%print_unknown_behaviours(#cl_state{report_mode = quiet}) ->
+%% ok;
+print_unknown_behaviours(#cl_state{output = Output,
+ external_calls = Calls,
+ stored_warnings = Warnings,
+ unknown_behaviours = DupBehaviours,
+ legal_warnings = LegalWarnings,
+ output_format = Format}) ->
+ case ordsets:is_element(?WARN_BEHAVIOUR, LegalWarnings)
+ andalso DupBehaviours =/= [] of
+ false -> ok;
+ true ->
+ Behaviours = lists:usort(DupBehaviours),
+ case Warnings =:= [] andalso Calls =:= [] of
+ true -> io:nl(Output); %% Need to do a newline first
+ false -> ok
+ end,
+ case Format of
+ formatted ->
+ io:put_chars(Output, "Unknown behaviours (behaviour_info(callbacks)"
+ " does not return any specs):\n"),
+ do_print_unknown_behaviours(Output, Behaviours, " ");
+ raw ->
+ io:put_chars(Output, "%% Unknown behaviours:\n"),
+ do_print_unknown_behaviours(Output, Behaviours, "%% ")
+ end
+ end.
+
+do_print_unknown_behaviours(Output, [B|T], Before) ->
+ io:format(Output, "~s~p\n", [Before,B]),
+ do_print_unknown_behaviours(Output, T, Before);
+do_print_unknown_behaviours(_, [], _) ->
+ ok.
+
print_warnings(#cl_state{stored_warnings = []}) ->
ok;
print_warnings(#cl_state{output = Output,
diff --git a/lib/dialyzer/src/dialyzer_cl_parse.erl b/lib/dialyzer/src/dialyzer_cl_parse.erl
index ae466e5c01..9a522e906a 100644
--- a/lib/dialyzer/src/dialyzer_cl_parse.erl
+++ b/lib/dialyzer/src/dialyzer_cl_parse.erl
@@ -1,20 +1,20 @@
%% -*- erlang-indent-level: 2 -*-
%%-----------------------------------------------------------------------
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2006-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 2006-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%
%%
@@ -68,6 +68,11 @@ cl(["-n"|T]) ->
cl(["--no_check_plt"|T]) ->
put(dialyzer_options_check_plt, false),
cl(T);
+cl(["-nn"|T]) ->
+ cl(["--no_native"|T]);
+cl(["--no_native"|T]) ->
+ put(dialyzer_options_native, false),
+ cl(T);
cl(["--plt_info"|T]) ->
put(dialyzer_options_analysis_type, plt_info),
cl(T);
@@ -181,7 +186,7 @@ cl([H|_] = L) ->
NewTail = command_line(L),
cl(NewTail);
false ->
- error("Unknown option: "++H)
+ error("Unknown option: " ++ H)
end;
cl([]) ->
{RetTag, Opts} =
@@ -191,7 +196,7 @@ cl([]) ->
{plt_info, cl_options()};
false ->
case get(dialyzer_options_mode) of
- {gui,_} = GUI -> {GUI, common_options()};
+ {gui, _} = GUI -> {GUI, common_options()};
cl ->
case get(dialyzer_options_analysis_type) =:= plt_check of
true -> {check_init, cl_options()};
@@ -311,17 +316,27 @@ help_message() ->
S = "Usage: dialyzer [--help] [--version] [--shell] [--quiet] [--verbose]
[-pa dir]* [--plt plt] [-Ddefine]* [-I include_dir]*
[--output_plt file] [-Wwarn]* [--src] [--gui | --wx]
- [-c applications] [-r applications] [-o outfile]
+ [files_or_dirs] [-r dirs] [--apps applications] [-o outfile]
[--build_plt] [--add_to_plt] [--remove_from_plt]
- [--check_plt] [--no_check_plt] [--plt_info] [--get_warnings]
-Options:
- -c applications (or --command-line applications)
- Use Dialyzer from the command line (no GUI) to detect defects in the
- specified applications (directories or .erl or .beam files)
- -r applications
- Same as -c only that directories are searched recursively for
- subdirectories containing .erl or .beam files (depending on the
- type of analysis)
+ [--check_plt] [--no_check_plt] [--plt_info] [--get_warnings]
+ [--no_native]
+Options:
+ files_or_dirs (for backwards compatibility also as: -c files_or_dirs)
+ Use Dialyzer from the command line to detect defects in the
+ specified files or directories containing .erl or .beam files,
+ depending on the type of the analysis
+ -r dirs
+ Same as the previous but the specified directories are searched
+ recursively for subdirectories containing .erl or .beam files in
+ them, depending on the type of analysis
+ --apps applications
+ Option typically used when building or modifying a PLT as in:
+ dialyzer --build_plt --apps erts kernel stdlib mnesia ...
+ to conveniently refer to library applications corresponding to the
+ Erlang/OTP installation. However, the option is general and can also
+ be used during analysis in order to refer to Erlang/OTP applications.
+ In addition, file or directory names can also be included, as in:
+ dialyzer --apps inets ssl ./ebin ../other_lib/ebin/my_module.beam
-o outfile (or --output outfile)
When using Dialyzer from the command line, send the analysis
results to the specified \"outfile\" rather than to stdout
@@ -389,6 +404,10 @@ Options:
by the file name extension. Supported extensions are: raw, dot, and ps.
If something else is used as file name extension, default format '.raw'
will be used.
+ --no_native (or -nn)
+ Bypass the native code compilation of some key files that dialyzer
+ heuristically performs when dialyzing many files; this avoids the
+ compilation time but it may result in (much) longer analysis time.
--gui
Use the gs-based GUI.
--wx
@@ -432,6 +451,9 @@ warning_options_msg() ->
Include warnings for functions that only return by means of an exception.
-Wrace_conditions ***
Include warnings for possible race conditions.
+ -Wbehaviours ***
+ Include warnings about behaviour callbacks which drift from the published
+ recommended interfaces.
-Wunderspecs ***
Warn about underspecified functions
(those whose -spec is strictly more allowing than the success typing).
diff --git a/lib/dialyzer/src/dialyzer_codeserver.erl b/lib/dialyzer/src/dialyzer_codeserver.erl
index 624501fc49..3bc5fadc21 100644
--- a/lib/dialyzer/src/dialyzer_codeserver.erl
+++ b/lib/dialyzer/src/dialyzer_codeserver.erl
@@ -1,20 +1,20 @@
%% -*- erlang-indent-level: 2 -*-
%%-----------------------------------------------------------------------
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2006-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 2006-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%
%%
@@ -56,83 +56,83 @@
%%--------------------------------------------------------------------
--record(dialyzer_codeserver, {table_pid :: pid(),
- exports = sets:new() :: set(), % set(mfa())
- next_core_label = 0 :: label(),
- records = dict:new() :: dict(),
- temp_records = dict:new() :: dict(),
- contracts = dict:new() :: dict(),
- temp_contracts = dict:new() :: dict()}).
+-record(codeserver, {table_pid :: pid(),
+ exports = sets:new() :: set(), % set(mfa())
+ next_core_label = 0 :: label(),
+ records = dict:new() :: dict(),
+ temp_records = dict:new() :: dict(),
+ contracts = dict:new() :: dict(),
+ temp_contracts = dict:new() :: dict()}).
--opaque codeserver() :: #dialyzer_codeserver{}.
+-opaque codeserver() :: #codeserver{}.
%%--------------------------------------------------------------------
-spec new() -> codeserver().
new() ->
- #dialyzer_codeserver{table_pid = table__new()}.
+ #codeserver{table_pid = table__new()}.
-spec delete(codeserver()) -> 'ok'.
-delete(#dialyzer_codeserver{table_pid = TablePid}) ->
+delete(#codeserver{table_pid = TablePid}) ->
table__delete(TablePid).
-spec insert(module(), cerl:c_module(), codeserver()) -> codeserver().
insert(Mod, ModCode, CS) ->
- NewTablePid = table__insert(CS#dialyzer_codeserver.table_pid, Mod, ModCode),
- CS#dialyzer_codeserver{table_pid = NewTablePid}.
+ NewTablePid = table__insert(CS#codeserver.table_pid, Mod, ModCode),
+ CS#codeserver{table_pid = NewTablePid}.
-spec insert_exports([mfa()], codeserver()) -> codeserver().
-insert_exports(List, #dialyzer_codeserver{exports = Exports} = CS) ->
+insert_exports(List, #codeserver{exports = Exports} = CS) ->
Set = sets:from_list(List),
NewExports = sets:union(Exports, Set),
- CS#dialyzer_codeserver{exports = NewExports}.
+ CS#codeserver{exports = NewExports}.
-spec is_exported(mfa(), codeserver()) -> boolean().
-is_exported(MFA, #dialyzer_codeserver{exports = Exports}) ->
+is_exported(MFA, #codeserver{exports = Exports}) ->
sets:is_element(MFA, Exports).
-spec get_exports(codeserver()) -> set(). % set(mfa())
-get_exports(#dialyzer_codeserver{exports = Exports}) ->
+get_exports(#codeserver{exports = Exports}) ->
Exports.
-spec lookup_mod_code(module(), codeserver()) -> cerl:c_module().
lookup_mod_code(Mod, CS) when is_atom(Mod) ->
- table__lookup(CS#dialyzer_codeserver.table_pid, Mod).
+ table__lookup(CS#codeserver.table_pid, Mod).
-spec lookup_mfa_code(mfa(), codeserver()) -> {cerl:c_var(), cerl:c_fun()}.
lookup_mfa_code({_M, _F, _A} = MFA, CS) ->
- table__lookup(CS#dialyzer_codeserver.table_pid, MFA).
+ table__lookup(CS#codeserver.table_pid, MFA).
-spec get_next_core_label(codeserver()) -> label().
-get_next_core_label(#dialyzer_codeserver{next_core_label = NCL}) ->
+get_next_core_label(#codeserver{next_core_label = NCL}) ->
NCL.
-spec set_next_core_label(label(), codeserver()) -> codeserver().
set_next_core_label(NCL, CS) ->
- CS#dialyzer_codeserver{next_core_label = NCL}.
+ CS#codeserver{next_core_label = NCL}.
-spec store_records(module(), dict(), codeserver()) -> codeserver().
-store_records(Mod, Dict, #dialyzer_codeserver{records = RecDict} = CS)
+store_records(Mod, Dict, #codeserver{records = RecDict} = CS)
when is_atom(Mod) ->
case dict:size(Dict) =:= 0 of
true -> CS;
- false -> CS#dialyzer_codeserver{records = dict:store(Mod, Dict, RecDict)}
+ false -> CS#codeserver{records = dict:store(Mod, Dict, RecDict)}
end.
-spec lookup_mod_records(module(), codeserver()) -> dict().
-lookup_mod_records(Mod, #dialyzer_codeserver{records = RecDict})
+lookup_mod_records(Mod, #codeserver{records = RecDict})
when is_atom(Mod) ->
case dict:find(Mod, RecDict) of
error -> dict:new();
@@ -141,45 +141,44 @@ lookup_mod_records(Mod, #dialyzer_codeserver{records = RecDict})
-spec get_records(codeserver()) -> dict().
-get_records(#dialyzer_codeserver{records = RecDict}) ->
+get_records(#codeserver{records = RecDict}) ->
RecDict.
-spec store_temp_records(module(), dict(), codeserver()) -> codeserver().
-store_temp_records(Mod, Dict, #dialyzer_codeserver{temp_records = TempRecDict} = CS)
+store_temp_records(Mod, Dict, #codeserver{temp_records = TempRecDict} = CS)
when is_atom(Mod) ->
case dict:size(Dict) =:= 0 of
true -> CS;
- false -> CS#dialyzer_codeserver{temp_records = dict:store(Mod, Dict, TempRecDict)}
+ false -> CS#codeserver{temp_records = dict:store(Mod, Dict, TempRecDict)}
end.
-spec get_temp_records(codeserver()) -> dict().
-get_temp_records(#dialyzer_codeserver{temp_records = TempRecDict}) ->
+get_temp_records(#codeserver{temp_records = TempRecDict}) ->
TempRecDict.
-spec set_temp_records(dict(), codeserver()) -> codeserver().
set_temp_records(Dict, CS) ->
- CS#dialyzer_codeserver{temp_records = Dict}.
+ CS#codeserver{temp_records = Dict}.
-spec finalize_records(dict(), codeserver()) -> codeserver().
finalize_records(Dict, CS) ->
- CS#dialyzer_codeserver{records = Dict, temp_records = dict:new()}.
+ CS#codeserver{records = Dict, temp_records = dict:new()}.
-spec store_contracts(module(), dict(), codeserver()) -> codeserver().
-store_contracts(Mod, Dict, #dialyzer_codeserver{contracts = C} = CS)
- when is_atom(Mod) ->
+store_contracts(Mod, Dict, #codeserver{contracts = C} = CS) when is_atom(Mod) ->
case dict:size(Dict) =:= 0 of
true -> CS;
- false -> CS#dialyzer_codeserver{contracts = dict:store(Mod, Dict, C)}
+ false -> CS#codeserver{contracts = dict:store(Mod, Dict, C)}
end.
-spec lookup_mod_contracts(module(), codeserver()) -> dict().
-lookup_mod_contracts(Mod, #dialyzer_codeserver{contracts = ContDict})
+lookup_mod_contracts(Mod, #codeserver{contracts = ContDict})
when is_atom(Mod) ->
case dict:find(Mod, ContDict) of
error -> dict:new();
@@ -189,7 +188,7 @@ lookup_mod_contracts(Mod, #dialyzer_codeserver{contracts = ContDict})
-spec lookup_mfa_contract(mfa(), codeserver()) ->
'error' | {'ok', dialyzer_contracts:file_contract()}.
-lookup_mfa_contract({M,_F,_A} = MFA, #dialyzer_codeserver{contracts = ContDict}) ->
+lookup_mfa_contract({M,_F,_A} = MFA, #codeserver{contracts = ContDict}) ->
case dict:find(M, ContDict) of
error -> error;
{ok, Dict} -> dict:find(MFA, Dict)
@@ -197,27 +196,27 @@ lookup_mfa_contract({M,_F,_A} = MFA, #dialyzer_codeserver{contracts = ContDict})
-spec get_contracts(codeserver()) -> dict().
-get_contracts(#dialyzer_codeserver{contracts = ContDict}) ->
+get_contracts(#codeserver{contracts = ContDict}) ->
ContDict.
-spec store_temp_contracts(module(), dict(), codeserver()) -> codeserver().
-store_temp_contracts(Mod, Dict, #dialyzer_codeserver{temp_contracts = C} = CS)
+store_temp_contracts(Mod, Dict, #codeserver{temp_contracts = C} = CS)
when is_atom(Mod) ->
case dict:size(Dict) =:= 0 of
true -> CS;
- false -> CS#dialyzer_codeserver{temp_contracts = dict:store(Mod, Dict, C)}
+ false -> CS#codeserver{temp_contracts = dict:store(Mod, Dict, C)}
end.
-spec get_temp_contracts(codeserver()) -> dict().
-get_temp_contracts(#dialyzer_codeserver{temp_contracts = TempContDict}) ->
+get_temp_contracts(#codeserver{temp_contracts = TempContDict}) ->
TempContDict.
-spec finalize_contracts(dict(), codeserver()) -> codeserver().
finalize_contracts(Dict, CS) ->
- CS#dialyzer_codeserver{contracts = Dict, temp_contracts = dict:new()}.
+ CS#codeserver{contracts = Dict, temp_contracts = dict:new()}.
table__new() ->
spawn_link(fun() -> table__loop(none, dict:new()) end).
diff --git a/lib/dialyzer/src/dialyzer_contracts.erl b/lib/dialyzer/src/dialyzer_contracts.erl
index e2680bb03d..3486c72748 100644
--- a/lib/dialyzer/src/dialyzer_contracts.erl
+++ b/lib/dialyzer/src/dialyzer_contracts.erl
@@ -1,20 +1,20 @@
%% -*- erlang-indent-level: 2 -*-
%%-----------------------------------------------------------------------
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2007-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 2007-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%
%%
@@ -196,9 +196,13 @@ check_contract(#contract{contracts = Contracts}, SuccType) ->
ok ->
InfList = [erl_types:t_inf(Contract, SuccType, opaque)
|| Contract <- Contracts2],
- check_contract_inf_list(InfList, SuccType)
+ case check_contract_inf_list(InfList, SuccType) of
+ {error, _} = Invalid -> Invalid;
+ ok -> check_extraneous(Contracts2, SuccType)
+ end
end
- catch throw:{error, _} = Error -> Error
+ catch
+ throw:{error, _} = Error -> Error
end.
check_domains([_]) -> ok;
@@ -233,6 +237,22 @@ check_contract_inf_list([FunType|Left], SuccType) ->
check_contract_inf_list([], _SuccType) ->
{error, invalid_contract}.
+check_extraneous([], _SuccType) -> ok;
+check_extraneous([C|Cs], SuccType) ->
+ case check_extraneous_1(C, SuccType) of
+ ok -> check_extraneous(Cs, SuccType);
+ Error -> Error
+ end.
+
+check_extraneous_1(Contract, SuccType) ->
+ CRngs = erl_types:t_elements(erl_types:t_fun_range(Contract)),
+ STRng = erl_types:t_fun_range(SuccType),
+ %% io:format("CR = ~p\nSR = ~p\n", [CRngs, STRng]),
+ case [CR || CR <- CRngs, erl_types:t_is_none(erl_types:t_inf(CR, STRng, opaque))] of
+ [] -> ok;
+ CRs -> {error, {extra_range, erl_types:t_sup(CRs), STRng}}
+ end.
+
%% This is the heart of the "range function"
-spec process_contracts([contract_pair()], [erl_types:erl_type()]) -> erl_types:erl_type().
@@ -411,6 +431,8 @@ get_invalid_contract_warnings_funs([{MFA, {FileLine, Contract}}|Left],
case check_contract(Contract, Sig) of
{error, invalid_contract} ->
[invalid_contract_warning(MFA, FileLine, Sig, RecDict)|Acc];
+ {error, {extra_range, ExtraRanges, STRange}} ->
+ [extra_range_warning(MFA, FileLine, ExtraRanges, STRange)|Acc];
{error, Msg} ->
[{?WARN_CONTRACT_SYNTAX, FileLine, Msg}|Acc];
ok ->
@@ -442,9 +464,15 @@ get_invalid_contract_warnings_funs([{MFA, {FileLine, Contract}}|Left],
get_invalid_contract_warnings_funs([], _Plt, _RecDict, Acc) ->
Acc.
-invalid_contract_warning({M, F, A}, FileLine, Type, RecDict) ->
+invalid_contract_warning({M, F, A}, FileLine, SuccType, RecDict) ->
+ SuccTypeStr = dialyzer_utils:format_sig(SuccType, RecDict),
+ {?WARN_CONTRACT_TYPES, FileLine, {invalid_contract, [M, F, A, SuccTypeStr]}}.
+
+extra_range_warning({M, F, A}, FileLine, ExtraRanges, STRange) ->
+ ERangesStr = erl_types:t_to_string(ExtraRanges),
+ STRangeStr = erl_types:t_to_string(STRange),
{?WARN_CONTRACT_TYPES, FileLine,
- {invalid_contract, [M, F, A, dialyzer_utils:format_sig(Type, RecDict)]}}.
+ {extra_range, [M, F, A, ERangesStr, STRangeStr]}}.
picky_contract_check(CSig0, Sig0, MFA, FileLine, Contract, RecDict, Acc) ->
CSig = erl_types:t_abstract_records(CSig0, RecDict),
diff --git a/lib/dialyzer/src/dialyzer_dataflow.erl b/lib/dialyzer/src/dialyzer_dataflow.erl
index 178321ea18..a57d9a96c6 100644
--- a/lib/dialyzer/src/dialyzer_dataflow.erl
+++ b/lib/dialyzer/src/dialyzer_dataflow.erl
@@ -1,20 +1,20 @@
%% -*- erlang-indent-level: 2 -*-
%%--------------------------------------------------------------------
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2006-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 2006-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%
%%
@@ -47,7 +47,7 @@
t_cons/0, t_cons/2, t_cons_hd/1, t_cons_tl/1, t_contains_opaque/1,
t_find_opaque_mismatch/2, t_float/0, t_from_range/2, t_from_term/1,
t_fun/0, t_fun/2, t_fun_args/1, t_fun_range/1,
- t_inf/2, t_inf/3, t_inf_lists/2, t_inf_lists/3,
+ t_inf/2, t_inf/3, t_inf_lists/2, t_inf_lists/3, t_inf_lists_masked/3,
t_integer/0, t_integers/1,
t_is_any/1, t_is_atom/1, t_is_atom/2, t_is_boolean/1, t_is_equal/2,
t_is_integer/1, t_is_nil/1, t_is_none/1, t_is_none_or_unit/1,
@@ -93,11 +93,13 @@
tree_map :: dict(),
warning_mode = false :: boolean(),
warnings = [] :: [dial_warning()],
- work :: {[_], [_], set()}}).
+ work :: {[_], [_], set()},
+ module :: module(),
+ behaviour_api_info = [] :: [{atom(),[_]}]}).
%% Exported Types
--type state() :: #state{}.
+-opaque state() :: #state{}.
%%--------------------------------------------------------------------
@@ -263,10 +265,15 @@ analyze_module(Tree, Plt, Callgraph) ->
analyze_module(Tree, Plt, Callgraph, Records, GetWarnings) ->
debug_pp(Tree, false),
Module = cerl:atom_val(cerl:module_name(Tree)),
+ RaceDetection = dialyzer_callgraph:get_race_detection(Callgraph),
+ BehaviourTranslations =
+ case RaceDetection of
+ true -> dialyzer_behaviours:translatable_behaviours(Tree);
+ false -> []
+ end,
TopFun = cerl:ann_c_fun([{label, top}], [], Tree),
- State =
- state__new(dialyzer_callgraph:race_code_new(Callgraph),
- TopFun, Plt, Module, Records),
+ State = state__new(dialyzer_callgraph:race_code_new(Callgraph),
+ TopFun, Plt, Module, Records, BehaviourTranslations),
State1 = state__race_analysis(not GetWarnings, State),
State2 = analyze_loop(State1),
RaceCode = dialyzer_callgraph:get_race_code(Callgraph),
@@ -277,7 +284,24 @@ analyze_module(Tree, Plt, Callgraph, Records, GetWarnings) ->
State3 = state__set_warning_mode(State2),
State4 = analyze_loop(State3),
State5 = state__restore_race_code(RaceCode, State4),
- dialyzer_races:race(State5);
+
+ %% EXPERIMENTAL: Turn all behaviour API calls into calls to the
+ %% respective callback module's functions.
+
+ case BehaviourTranslations of
+ [] -> dialyzer_races:race(State5);
+ Behaviours ->
+ Callgraph2 = State5#state.callgraph,
+ Digraph = dialyzer_callgraph:get_digraph(Callgraph2),
+ TranslatedCallgraph =
+ dialyzer_behaviours:translate_callgraph(Behaviours, Module,
+ Callgraph2),
+ St =
+ dialyzer_races:race(State5#state{callgraph = TranslatedCallgraph}),
+ Callgraph3 = dialyzer_callgraph:put_digraph(Digraph,
+ St#state.callgraph),
+ St#state{callgraph = Callgraph3}
+ end;
false ->
state__restore_race_code(
dict:merge(fun (_K, V1, _V2) -> V1 end,
@@ -567,6 +591,7 @@ handle_apply_or_call([{TypeOfApply, {Fun, Sig, Contr, LocalRet}}|Left],
{M, F, A} = Fun,
case erl_bif_types:is_known(M, F, A) of
true ->
+ IsBIF = true,
BArgs = erl_bif_types:arg_types(M, F, A),
BRange =
fun(FunArgs) ->
@@ -585,9 +610,9 @@ handle_apply_or_call([{TypeOfApply, {Fun, Sig, Contr, LocalRet}}|Left],
erl_bif_types:type(M, F, A, NewFunArgs)
end,
{BArgs, BRange};
- false -> GenSig
+ false -> IsBIF = false, GenSig
end;
- local -> GenSig
+ local -> IsBIF = false, GenSig
end,
{SigArgs, SigRange} =
%% if there is hard-coded or contract information with opaque types,
@@ -601,18 +626,33 @@ handle_apply_or_call([{TypeOfApply, {Fun, Sig, Contr, LocalRet}}|Left],
none -> {AnyArgs, t_any()}
end
end,
- NewArgsSig = t_inf_lists(SigArgs, ArgTypes),
- NewArgsContract = t_inf_lists(CArgs, ArgTypes),
- NewArgsBif = t_inf_lists(BifArgs, ArgTypes),
- NewArgTypes0 = t_inf_lists(NewArgsSig, NewArgsContract),
- NewArgTypes = t_inf_lists(NewArgTypes0, NewArgsBif),
+ ArgModeMask = [case lists:member(Arg, Opaques) of
+ true -> opaque;
+ false -> structured
+ end || Arg <- ArgTypes],
+ NewArgsSig = t_inf_lists_masked(SigArgs, ArgTypes, ArgModeMask),
+ NewArgsContract = t_inf_lists_masked(CArgs, ArgTypes, ArgModeMask),
+ NewArgsBif = t_inf_lists_masked(BifArgs, ArgTypes, ArgModeMask),
+ NewArgTypes0 = t_inf_lists_masked(NewArgsSig, NewArgsContract, ArgModeMask),
+ NewArgTypes = t_inf_lists_masked(NewArgTypes0, NewArgsBif, ArgModeMask),
BifRet = BifRange(NewArgTypes),
- ContrRet = CRange(NewArgTypes),
- Mode = case t_contains_opaque(ContrRet) orelse t_contains_opaque(BifRet) of
+ {TmpArgTypes, TmpArgsContract} =
+ case (TypeOfApply == remote) andalso (not IsBIF) of
+ true ->
+ List1 = lists:zip(CArgs, NewArgTypes),
+ List2 = lists:zip(CArgs, NewArgsContract),
+ {[erl_types:t_unopaque_on_mismatch(T1, T2, Opaques)
+ || {T1, T2} <- List1],
+ [erl_types:t_unopaque_on_mismatch(T1, T2, Opaques)
+ || {T1, T2} <- List2]};
+ false -> {NewArgTypes, NewArgsContract}
+ end,
+ ContrRet = CRange(TmpArgTypes),
+ RetMode = case t_contains_opaque(ContrRet) orelse t_contains_opaque(BifRet) of
true -> opaque;
false -> structured
end,
- RetWithoutLocal = t_inf(t_inf(ContrRet, BifRet, Mode), SigRange, Mode),
+ RetWithoutLocal = t_inf(t_inf(ContrRet, BifRet, RetMode), SigRange, RetMode),
?debug("--------------------------------------------------------\n", []),
?debug("Fun: ~p\n", [Fun]),
?debug("Args: ~s\n", [erl_types:t_to_string(t_product(ArgTypes))]),
@@ -623,7 +663,7 @@ handle_apply_or_call([{TypeOfApply, {Fun, Sig, Contr, LocalRet}}|Left],
?debug("NewArgTypes: ~s\n", [erl_types:t_to_string(t_product(NewArgTypes))]),
?debug("RetWithoutLocal: ~s\n", [erl_types:t_to_string(RetWithoutLocal)]),
?debug("BifRet: ~s\n", [erl_types:t_to_string(BifRange(NewArgTypes))]),
- ?debug("ContrRet: ~s\n", [erl_types:t_to_string(CRange(NewArgTypes))]),
+ ?debug("ContrRet: ~s\n", [erl_types:t_to_string(CRange(TmpArgTypes))]),
?debug("SigRet: ~s\n", [erl_types:t_to_string(SigRange)]),
State1 =
case dialyzer_callgraph:get_race_detection(Callgraph) andalso
@@ -632,8 +672,21 @@ handle_apply_or_call([{TypeOfApply, {Fun, Sig, Contr, LocalRet}}|Left],
Ann = cerl:get_ann(Tree),
File = get_file(Ann),
Line = abs(get_line(Ann)),
- dialyzer_races:store_race_call(Fun, ArgTypes, Args, {File, Line},
- State);
+
+ %% EXPERIMENTAL: Turn a behaviour's API call into a call to the
+ %% respective callback module's function.
+
+ Module = State#state.module,
+ BehApiInfo = State#state.behaviour_api_info,
+ {RealFun, RealArgTypes, RealArgs} =
+ case dialyzer_behaviours:translate_behaviour_api_call(Fun, ArgTypes,
+ Args, Module,
+ BehApiInfo) of
+ plain_call -> {Fun, ArgTypes, Args};
+ BehaviourAPI -> BehaviourAPI
+ end,
+ dialyzer_races:store_race_call(RealFun, RealArgTypes, RealArgs,
+ {File, Line}, State);
false -> State
end,
FailedConj = any_none([RetWithoutLocal|NewArgTypes]),
@@ -643,7 +696,7 @@ handle_apply_or_call([{TypeOfApply, {Fun, Sig, Contr, LocalRet}}|Left],
case FailedConj andalso not (IsFailBif orelse IsFailSig) of
true ->
FailedSig = any_none(NewArgsSig),
- FailedContract = any_none([CRange(NewArgsContract)|NewArgsContract]),
+ FailedContract = any_none([CRange(TmpArgsContract)|NewArgsContract]),
FailedBif = any_none([BifRange(NewArgsBif)|NewArgsBif]),
InfSig = t_inf(t_fun(SigArgs, SigRange),
t_fun(BifArgs, BifRange(BifArgs))),
@@ -786,8 +839,11 @@ expected_arg_triples(ArgNs, ArgTypes, State) ->
add_bif_warnings({erlang, Op, 2}, [T1, T2] = Ts, Tree, State)
when Op =:= '=:='; Op =:= '==' ->
+ Type1 = erl_types:t_unopaque(T1, State#state.opaques),
+ Type2 = erl_types:t_unopaque(T2, State#state.opaques),
Inf = t_inf(T1, T2),
- case t_is_none(Inf) andalso (not any_none(Ts))
+ Inf1 = t_inf(Type1, Type2),
+ case t_is_none(Inf) andalso t_is_none(Inf1) andalso(not any_none(Ts))
andalso (not is_int_float_eq_comp(T1, Op, T2)) of
true ->
Args = case erl_types:t_is_opaque(T1) of
@@ -905,9 +961,9 @@ handle_call(Tree, Map, State) ->
Args = cerl:call_args(Tree),
MFAList = [M, F|Args],
{State1, Map1, [MType0, FType0|As]} = traverse_list(MFAList, Map, State),
- %% Module and function names should be treated as *atoms* even if
- %% they happen to be identical to an atom which is also involved in
- %% the definition of an opaque data type
+ %% Module and function names should be treated as *structured terms*
+ %% even if they happen to be identical to an atom (or tuple) which
+ %% is also involved in the definition of an opaque data type.
MType = t_inf(t_module(), t_unopaque(MType0)),
FType = t_inf(t_atom(), t_unopaque(FType0)),
Map2 = enter_type_lists([M, F], [MType, FType], Map1),
@@ -936,13 +992,18 @@ handle_call(Tree, Map, State) ->
end,
{State2, Map2, t_none()};
false ->
- %% XXX: Consider doing this for all combinations of MF
- case {t_atom_vals(MType), t_atom_vals(FType)} of
- {[MAtom], [FAtom]} ->
- FunInfo = [{remote, state__fun_info({MAtom, FAtom, length(Args)},
- State1)}],
- handle_apply_or_call(FunInfo, Args, As, Map2, Tree, State1);
- {_MAtoms, _FAtoms} ->
+ case t_is_atom(MType) of
+ true ->
+ %% XXX: Consider doing this for all combinations of MF
+ case {t_atom_vals(MType), t_atom_vals(FType)} of
+ {[MAtom], [FAtom]} ->
+ FunInfo = [{remote, state__fun_info({MAtom, FAtom, length(Args)},
+ State1)}],
+ handle_apply_or_call(FunInfo, Args, As, Map2, Tree, State1);
+ {_MAtoms, _FAtoms} ->
+ {State1, Map2, t_any()}
+ end;
+ false ->
{State1, Map2, t_any()}
end
end.
@@ -1481,10 +1542,7 @@ bind_pat_vars([Pat|PatLeft], [Type|TypeLeft], Acc, Map, State, Rev) ->
Cons = t_inf(Type, t_cons()),
case t_is_none(Cons) of
true ->
- case t_find_opaque_mismatch(t_cons(), Type) of
- {ok, T1, T2} -> bind_error([Pat], T1, T2, opaque);
- error -> bind_error([Pat], Type, t_none(), bind)
- end;
+ bind_opaque_pats(t_cons(), Type, Pat, Map, State, Rev);
false ->
{Map1, [HdType, TlType]} =
bind_pat_vars([cerl:cons_hd(Pat), cerl:cons_tl(Pat)],
@@ -1501,18 +1559,7 @@ bind_pat_vars([Pat|PatLeft], [Type|TypeLeft], Acc, Map, State, Rev) ->
end,
case t_is_none(t_inf(LiteralOrOpaque, Type)) of
true ->
- case t_find_opaque_mismatch(Literal, Type) of
- {ok, T1, T2} ->
- case lists:member(T2, State#state.opaques) of
- true ->
- NewType = erl_types:t_struct_from_opaque(Type, T2),
- {Map1, _} =
- bind_pat_vars([Pat], [NewType], [], Map, State, Rev),
- {Map1, T2};
- false -> bind_error([Pat], T1, T2, opaque)
- end;
- error -> bind_error([Pat], Type, t_none(), bind)
- end;
+ bind_opaque_pats(Literal, Type, Pat, Map, State, Rev);
false -> {Map, LiteralOrOpaque}
end;
tuple ->
@@ -1534,18 +1581,7 @@ bind_pat_vars([Pat|PatLeft], [Type|TypeLeft], Acc, Map, State, Rev) ->
Tuple = t_inf(Prototype, Type),
case t_is_none(Tuple) of
true ->
- case t_find_opaque_mismatch(Prototype, Type) of
- {ok, T1, T2} ->
- case lists:member(T2, State#state.opaques) of
- true ->
- NewType = erl_types:t_struct_from_opaque(Type, T2),
- {Map1, _} =
- bind_pat_vars([Pat], [NewType], [], Map, State, Rev),
- {Map1, T2};
- false -> bind_error([Pat], T1, T2, opaque)
- end;
- error -> bind_error([Pat], Type, t_none(), bind)
- end;
+ bind_opaque_pats(Prototype, Type, Pat, Map, State, Rev);
false ->
SubTuples = t_tuple_subtypes(Tuple),
%% Need to call the top function to get the try-catch wrapper
@@ -1689,6 +1725,20 @@ bind_bin_segs([], _BinType, Acc, Map, _State) ->
bind_error(Pats, Type, OpaqueType, Error) ->
throw({error, Error, Pats, Type, OpaqueType}).
+bind_opaque_pats(GenType, Type, Pat, Map, State, Rev) ->
+ case t_find_opaque_mismatch(GenType, Type) of
+ {ok, T1, T2} ->
+ case lists:member(T2, State#state.opaques) of
+ true ->
+ NewType = erl_types:t_struct_from_opaque(Type, [T2]),
+ {Map1, _} =
+ bind_pat_vars([Pat], [NewType], [], Map, State, Rev),
+ {Map1, T2};
+ false -> bind_error([Pat], T1, T2, opaque)
+ end;
+ error -> bind_error([Pat], Type, t_none(), bind)
+ end.
+
%%----------------------------------------
%% Guards
%%
@@ -2296,7 +2346,7 @@ bind_guard_list([G|Gs], Map, Env, Eval, State, Acc) ->
bind_guard_list([], Map, _Env, _Eval, _State, Acc) ->
{Map, lists:reverse(Acc)}.
--spec signal_guard_fail(cerl:c_call(), [erl_types:erl_type()], #state{}) ->
+-spec signal_guard_fail(cerl:c_call(), [erl_types:erl_type()], state()) ->
no_return().
signal_guard_fail(Guard, ArgTypes, State) ->
@@ -2327,7 +2377,7 @@ is_infix_op({erlang, '>=', 2}) -> true;
is_infix_op({M, F, A}) when is_atom(M), is_atom(F),
is_integer(A), 0 =< A, A =< 255 -> false.
--spec signal_guard_fatal_fail(cerl:c_call(), [erl_types:erl_type()], #state{}) ->
+-spec signal_guard_fatal_fail(cerl:c_call(), [erl_types:erl_type()], state()) ->
no_return().
signal_guard_fatal_fail(Guard, ArgTypes, State) ->
@@ -2680,7 +2730,7 @@ determine_mode(Type, Opaques) ->
%%%
%%% ===========================================================================
-state__new(Callgraph, Tree, Plt, Module, Records) ->
+state__new(Callgraph, Tree, Plt, Module, Records, BehaviourTranslations) ->
TreeMap = build_tree_map(Tree),
Funs = dict:fetch_keys(TreeMap),
FunTab = init_fun_tab(Funs, dict:new(), TreeMap, Callgraph, Plt),
@@ -2690,7 +2740,8 @@ state__new(Callgraph, Tree, Plt, Module, Records) ->
erl_types:t_opaque_from_records(Records),
#state{callgraph = Callgraph, envs = Env, fun_tab = FunTab, opaques = Opaques,
plt = Plt, races = dialyzer_races:new(), records = Records,
- warning_mode = false, warnings = [], work = Work, tree_map = TreeMap}.
+ warning_mode = false, warnings = [], work = Work, tree_map = TreeMap,
+ module = Module, behaviour_api_info = BehaviourTranslations}.
state__mark_fun_as_handled(#state{fun_tab = FunTab} = State, Fun0) ->
Fun = get_label(Fun0),
@@ -3197,7 +3248,7 @@ get_file([_|Tail]) -> get_file(Tail).
is_compiler_generated(Ann) ->
lists:member(compiler_generated, Ann) orelse (get_line(Ann) < 1).
--spec format_args([term()], [erl_types:erl_type()], #state{}) ->
+-spec format_args([term()], [erl_types:erl_type()], state()) ->
nonempty_string().
format_args([], [], _State) ->
@@ -3205,7 +3256,7 @@ format_args([], [], _State) ->
format_args(ArgList, TypeList, State) ->
"(" ++ format_args_1(ArgList, TypeList, State) ++ ")".
--spec format_args_1([term(),...], [erl_types:erl_type(),...], #state{}) ->
+-spec format_args_1([term(),...], [erl_types:erl_type(),...], state()) ->
string().
format_args_1([Arg], [Type], State) ->
@@ -3235,12 +3286,12 @@ format_arg(Arg) ->
Default
end.
--spec format_type(erl_types:erl_type(), #state{}) -> string().
+-spec format_type(erl_types:erl_type(), state()) -> string().
format_type(Type, #state{records = R}) ->
t_to_string(Type, R).
--spec format_sig_args(erl_types:erl_type(), #state{}) -> string().
+-spec format_sig_args(erl_types:erl_type(), state()) -> string().
format_sig_args(Type, #state{records = R}) ->
SigArgs = t_fun_args(Type),
diff --git a/lib/dialyzer/src/dialyzer_dep.erl b/lib/dialyzer/src/dialyzer_dep.erl
index 670433f003..febb65b766 100644
--- a/lib/dialyzer/src/dialyzer_dep.erl
+++ b/lib/dialyzer/src/dialyzer_dep.erl
@@ -1,20 +1,20 @@
%% -*- erlang-indent-level: 2 -*-
%%-----------------------------------------------------------------------
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2006-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 2006-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%
%%
@@ -326,7 +326,7 @@ set__filter(#set{set = Set}, Fun) ->
%%
-record(output, {type :: 'single' | 'list',
- content :: 'none' | #set{} | [{output,_,_}]}).
+ content :: 'none' | #set{} | [#output{}]}).
output(none) -> #output{type = single, content = none};
output(S = #set{}) -> #output{type = single, content = S};
diff --git a/lib/dialyzer/src/dialyzer_gui_wx.erl b/lib/dialyzer/src/dialyzer_gui_wx.erl
index 2d97f88680..2e309d7ec1 100644
--- a/lib/dialyzer/src/dialyzer_gui_wx.erl
+++ b/lib/dialyzer/src/dialyzer_gui_wx.erl
@@ -1,20 +1,20 @@
%% -*- erlang-indent-level: 2 -*-
%%------------------------------------------------------------------------
%% %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%
%%
@@ -102,9 +102,9 @@ create_window(Wx, DialyzerOptions) ->
MenuBar = wxMenuBar:new(),
wxMenuBar:append(MenuBar, FileMenu, "File"),
- wxMenuBar:append(MenuBar, WarningsMenu, "Warnings"),
- wxMenuBar:append(MenuBar, PltMenu, "Plt"),
- wxMenuBar:append(MenuBar, OptionsMenu, "Options"),
+ wxMenuBar:append(MenuBar, WarningsMenu, "Warnings"),
+ wxMenuBar:append(MenuBar, PltMenu, "Plt"),
+ wxMenuBar:append(MenuBar, OptionsMenu, "Options"),
wxMenuBar:append(MenuBar, HelpMenu, "Help"),
wxFrame:setMenuBar(Frame, MenuBar),
ok = wxFrame:connect(Frame, command_menu_selected),
@@ -152,8 +152,8 @@ create_window(Wx, DialyzerOptions) ->
AddButton = wxButton:new(Frame, ?Add_Button, [{label, "Add"}]),
AddDirButton = wxButton:new(Frame, ?AddDir_Button, [{label, "Add Dir"}]),
AddRecButton = wxButton:new(Frame, ?AddRec_Button, [{label, "Add Recursively"}]),
- ExplainWarnButton = wxButton:new(Frame, ?ExplWarn_Button, [{label, "Explain Warning"}]),
- ClearWarningsButton = wxButton:new(Frame, ?ClearWarn_Button, [{label, "Clear Warnings"}]),
+ ExplainWarnButton = wxButton:new(Frame, ?ExplWarn_Button, [{label, "Explain Warning"}]),
+ ClearWarningsButton = wxButton:new(Frame, ?ClearWarn_Button, [{label, "Clear Warnings"}]),
RunButton = wxButton:new(Frame, ?Run_Button, [{label, "Run"}]),
StopButton = wxButton:new(Frame, ?Stop_Button, [{label, "Stop"}]),
wxWindow:disable(StopButton),
@@ -170,8 +170,8 @@ create_window(Wx, DialyzerOptions) ->
wxButton:connect(StopButton, command_button_clicked),
%%------------Set Layout ------------
- All = wxBoxSizer:new(?wxVERTICAL),
- Top = wxBoxSizer:new(?wxHORIZONTAL),
+ All = wxBoxSizer:new(?wxVERTICAL),
+ Top = wxBoxSizer:new(?wxHORIZONTAL),
Left = wxBoxSizer:new(?wxVERTICAL),
Right = wxBoxSizer:new(?wxVERTICAL),
RightUp = wxBoxSizer:new(?wxHORIZONTAL),
@@ -390,7 +390,7 @@ gui_loop(#gui_state{backend_pid = BackendPid, doc_plt = DocPlt,
warnings_box = WarningsBox} = State) ->
receive
#wx{event = #wxClose{}} ->
- io:format("~p Closing window ~n", [self()]),
+ %% io:format("~p Closing window ~n", [self()]),
ok = wxFrame:setStatusText(Frame, "Closing...",[]),
wxWindow:destroy(Frame),
?RET_NOTHING_SUSPICIOUS;
@@ -539,7 +539,7 @@ maybe_quit(#gui_state{frame = Frame} = State) ->
%% ------------ Yes/No Question ------------
dialog(#gui_state{frame = Frame}, Message, Title) ->
- MessageWin = wxMessageDialog:new(Frame,Message,[{caption, Title},{style, ?wxYES_NO bor ?wxICON_QUESTION bor ?wxNO_DEFAULT}]),
+ MessageWin = wxMessageDialog:new(Frame, Message, [{caption, Title},{style, ?wxYES_NO bor ?wxICON_QUESTION bor ?wxNO_DEFAULT}]),
case wxDialog:showModal(MessageWin) of
?wxID_YES ->
true;
@@ -563,12 +563,12 @@ search_doc_plt(#gui_state{gui = Wx} = State) ->
Cancel = wxButton:new(Dialog, ?Search_Cancel, [{label, "Cancel"}]),
wxButton:connect(Cancel, command_button_clicked),
- Layout = wxBoxSizer:new(?wxVERTICAL),
- Top = wxBoxSizer:new(?wxHORIZONTAL),
- ModLayout = wxBoxSizer:new(?wxVERTICAL),
- FunLayout = wxBoxSizer:new(?wxVERTICAL),
- ArLayout = wxBoxSizer:new(?wxVERTICAL),
- Buttons = wxBoxSizer:new(?wxHORIZONTAL),
+ Layout = wxBoxSizer:new(?wxVERTICAL),
+ Top = wxBoxSizer:new(?wxHORIZONTAL),
+ ModLayout = wxBoxSizer:new(?wxVERTICAL),
+ FunLayout = wxBoxSizer:new(?wxVERTICAL),
+ ArLayout = wxBoxSizer:new(?wxVERTICAL),
+ Buttons = wxBoxSizer:new(?wxHORIZONTAL),
wxSizer:add(ModLayout, ModLabel, ?BorderOpt),
wxSizer:add(ModLayout,ModText, ?BorderOpt),
@@ -606,7 +606,7 @@ search_plt_loop(State= #gui_state{doc_plt = DocPlt, frame = Frame}, Win, ModText
A = format_search(wxTextCtrl:getValue(ArText)),
if
- (M == '_') or (F == '_') or (A == '_') ->
+ (M =:= '_') orelse (F =:= '_') orelse (A =:= '_') ->
error_sms(State, "Please give:\n Module (atom)\n Function (atom)\n Arity (integer)\n"),
search_plt_loop(State, Win, ModText, FunText, ArText, Search, Cancel);
true ->
@@ -670,7 +670,7 @@ free_editor(#gui_state{gui = Wx, frame = Frame}, Title, Contents0) ->
wxFrame:connect(Win, close_window),
Ok = wxButton:new(Win, ?Message_Ok, [{label, "OK"}]),
wxButton:connect(Ok, command_button_clicked),
- Layout = wxBoxSizer:new(?wxVERTICAL),
+ Layout = wxBoxSizer:new(?wxVERTICAL),
wxSizer:add(Layout, Editor, ?BorderOpt),
wxSizer:add(Layout, Ok, [{flag, ?wxALIGN_CENTER bor ?wxBOTTOM bor ?wxALL}, ?Border]),
@@ -757,7 +757,7 @@ add_files(File, FileList, ChosenBox, Ext) ->
Files.
filter_mods(Mods, Extension) ->
- Fun = fun(X) ->
+ Fun = fun(X) ->
filename:extension(X) =:= Extension
orelse
(filelib:is_dir(X) andalso
@@ -944,9 +944,9 @@ include_dialog(#gui_state{gui = Wx, frame = Frame, options = Options}) ->
Dirs = [io_lib:format("~s", [X])
|| X <- Options#options.include_dirs],
wxListBox:set(Box, Dirs),
- Layout = wxBoxSizer:new(?wxVERTICAL),
- Buttons = wxBoxSizer:new(?wxHORIZONTAL),
- Buttons1 = wxBoxSizer:new(?wxHORIZONTAL),
+ Layout = wxBoxSizer:new(?wxVERTICAL),
+ Buttons = wxBoxSizer:new(?wxHORIZONTAL),
+ Buttons1 = wxBoxSizer:new(?wxHORIZONTAL),
wxSizer:add(Layout, DirLabel, [{flag, ?wxALIGN_CENTER_HORIZONTAL}]),
wxSizer:add(Layout, DirPicker, [{flag, ?wxALIGN_CENTER_HORIZONTAL}]),
@@ -1038,12 +1038,12 @@ macro_dialog(#gui_state{gui = Wx, frame = Frame, options = Options}) ->
|| {X,Y} <- Options#options.defines],
wxListBox:set(Box, Macros),
- Layout = wxBoxSizer:new(?wxVERTICAL),
- Item = wxBoxSizer:new(?wxHORIZONTAL),
- MacroItem = wxBoxSizer:new(?wxVERTICAL),
- TermItem = wxBoxSizer:new(?wxVERTICAL),
- Buttons = wxBoxSizer:new(?wxHORIZONTAL),
- Buttons1 = wxBoxSizer:new(?wxHORIZONTAL),
+ Layout = wxBoxSizer:new(?wxVERTICAL),
+ Item = wxBoxSizer:new(?wxHORIZONTAL),
+ MacroItem = wxBoxSizer:new(?wxVERTICAL),
+ TermItem = wxBoxSizer:new(?wxVERTICAL),
+ Buttons = wxBoxSizer:new(?wxHORIZONTAL),
+ Buttons1 = wxBoxSizer:new(?wxHORIZONTAL),
wxSizer:add(MacroItem, MacroLabel, ?BorderOpt),
wxSizer:add(MacroItem, MacroText, ?BorderOpt),
@@ -1159,7 +1159,8 @@ handle_explanation(#gui_state{rawWarnings = RawWarns,
warnings_box = WarnBox,
expl_pid = ExplPid} = State) ->
case wxListBox:isEmpty(WarnBox) of
- true -> error_sms(State, "\nThere are no warnings.\nRun the dialyzer first.");
+ true ->
+ error_sms(State, "\nThere are no warnings.\nRun the dialyzer first.");
false ->
case wxListBox:getSelections(WarnBox)of
{0, []} ->
@@ -1200,8 +1201,8 @@ show_explanation(#gui_state{gui = Wx} = State, Explanation) ->
wxButton:connect(ExplButton, command_button_clicked),
Ok = wxButton:new(Win, ?ExplOk, [{label, "OK"}]),
wxButton:connect(Ok, command_button_clicked),
- Layout = wxBoxSizer:new(?wxVERTICAL),
- Buttons = wxBoxSizer:new(?wxHORIZONTAL),
+ Layout = wxBoxSizer:new(?wxVERTICAL),
+ Buttons = wxBoxSizer:new(?wxHORIZONTAL),
wxSizer:add(Buttons, ExplButton, ?BorderOpt),
wxSizer:add(Buttons, Ok, ?BorderOpt),
wxSizer:add(Layout, Editor,[{flag, ?wxALIGN_CENTER_HORIZONTAL bor ?wxALL}, ?Border]),
diff --git a/lib/dialyzer/src/dialyzer_options.erl b/lib/dialyzer/src/dialyzer_options.erl
index 6531073072..da0e1f9aaf 100644
--- a/lib/dialyzer/src/dialyzer_options.erl
+++ b/lib/dialyzer/src/dialyzer_options.erl
@@ -1,20 +1,20 @@
%% -*- erlang-indent-level: 2 -*-
%%-----------------------------------------------------------------------
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2006-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 2006-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%
%%
@@ -252,6 +252,8 @@ build_warnings([Opt|Opts], Warnings) ->
ordsets:add_element(?WARN_RETURN_ONLY_EXIT, Warnings);
race_conditions ->
ordsets:add_element(?WARN_RACE_CONDITION, Warnings);
+ behaviours ->
+ ordsets:add_element(?WARN_BEHAVIOUR, Warnings);
specdiffs ->
S = ordsets:from_list([?WARN_CONTRACT_SUBTYPE,
?WARN_CONTRACT_SUPERTYPE,
diff --git a/lib/dialyzer/src/dialyzer_plt.erl b/lib/dialyzer/src/dialyzer_plt.erl
index f2e0fe1e97..e387077a46 100644
--- a/lib/dialyzer/src/dialyzer_plt.erl
+++ b/lib/dialyzer/src/dialyzer_plt.erl
@@ -1,20 +1,20 @@
%% -*- erlang-indent-level: 2 -*-
%%----------------------------------------------------------------------
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2006-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 2006-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%
%%
@@ -70,109 +70,106 @@
%%----------------------------------------------------------------------
--record(dialyzer_plt, {info = table_new() :: dict(),
- types = table_new() :: dict(),
- contracts = table_new() :: dict()}).
--opaque plt() :: #dialyzer_plt{}.
+-record(plt, {info = table_new() :: dict(),
+ types = table_new() :: dict(),
+ contracts = table_new() :: dict()}).
+-opaque plt() :: #plt{}.
-include("dialyzer.hrl").
-type file_md5() :: {file:filename(), binary()}.
-type plt_info() :: {[file_md5()], dict()}.
--record(dialyzer_file_plt, {version = "" :: string(),
- file_md5_list = [] :: [file_md5()],
- info = dict:new() :: dict(),
- contracts = dict:new() :: dict(),
- types = dict:new() :: dict(),
- mod_deps :: mod_deps(),
- implementation_md5 = [] :: [file_md5()]
- }).
+-record(file_plt, {version = "" :: string(),
+ file_md5_list = [] :: [file_md5()],
+ info = dict:new() :: dict(),
+ contracts = dict:new() :: dict(),
+ types = dict:new() :: dict(),
+ mod_deps :: mod_deps(),
+ implementation_md5 = [] :: [file_md5()]}).
%%----------------------------------------------------------------------
-spec new() -> plt().
new() ->
- #dialyzer_plt{}.
+ #plt{}.
-spec delete_module(plt(), module()) -> plt().
-delete_module(#dialyzer_plt{info = Info, types = Types, contracts = Contracts},
- Mod) ->
- #dialyzer_plt{info = table_delete_module(Info, Mod),
- types = table_delete_module2(Types, Mod),
- contracts = table_delete_module(Contracts, Mod)}.
+delete_module(#plt{info = Info, types = Types, contracts = Contracts}, Mod) ->
+ #plt{info = table_delete_module(Info, Mod),
+ types = table_delete_module2(Types, Mod),
+ contracts = table_delete_module(Contracts, Mod)}.
-spec delete_list(plt(), [mfa() | integer()]) -> plt().
-delete_list(#dialyzer_plt{info = Info, types = Types, contracts = Contracts},
- List) ->
- #dialyzer_plt{info = table_delete_list(Info, List),
- types = Types,
- contracts = table_delete_list(Contracts, List)}.
+delete_list(#plt{info = Info, types = Types, contracts = Contracts}, List) ->
+ #plt{info = table_delete_list(Info, List),
+ types = Types,
+ contracts = table_delete_list(Contracts, List)}.
-spec insert_contract_list(plt(), dialyzer_contracts:plt_contracts()) -> plt().
-insert_contract_list(#dialyzer_plt{contracts = Contracts} = PLT, List) ->
- PLT#dialyzer_plt{contracts = table_insert_list(Contracts, List)}.
+insert_contract_list(#plt{contracts = Contracts} = PLT, List) ->
+ PLT#plt{contracts = table_insert_list(Contracts, List)}.
-spec lookup_contract(plt(), mfa_patt()) -> 'none' | {'value', #contract{}}.
-lookup_contract(#dialyzer_plt{contracts = Contracts},
+lookup_contract(#plt{contracts = Contracts},
{M, F, _} = MFA) when is_atom(M), is_atom(F) ->
table_lookup(Contracts, MFA).
-spec delete_contract_list(plt(), [mfa()]) -> plt().
-delete_contract_list(#dialyzer_plt{contracts = Contracts} = PLT, List) ->
- PLT#dialyzer_plt{contracts = table_delete_list(Contracts, List)}.
+delete_contract_list(#plt{contracts = Contracts} = PLT, List) ->
+ PLT#plt{contracts = table_delete_list(Contracts, List)}.
%% -spec insert(plt(), mfa() | integer(), {_, _}) -> plt().
%%
-%% insert(#dialyzer_plt{info = Info} = PLT, Id, Types) ->
-%% PLT#dialyzer_plt{info = table_insert(Info, Id, Types)}.
+%% insert(#plt{info = Info} = PLT, Id, Types) ->
+%% PLT#plt{info = table_insert(Info, Id, Types)}.
-type ret_args_types() :: {erl_types:erl_type(), [erl_types:erl_type()]}.
-spec insert_list(plt(), [{mfa() | integer(), ret_args_types()}]) -> plt().
-insert_list(#dialyzer_plt{info = Info} = PLT, List) ->
- PLT#dialyzer_plt{info = table_insert_list(Info, List)}.
+insert_list(#plt{info = Info} = PLT, List) ->
+ PLT#plt{info = table_insert_list(Info, List)}.
-spec lookup(plt(), integer() | mfa_patt()) ->
'none' | {'value', ret_args_types()}.
-lookup(#dialyzer_plt{info = Info}, {M, F, _} = MFA) when is_atom(M), is_atom(F) ->
+lookup(#plt{info = Info}, {M, F, _} = MFA) when is_atom(M), is_atom(F) ->
table_lookup(Info, MFA);
-lookup(#dialyzer_plt{info = Info}, Label) when is_integer(Label) ->
+lookup(#plt{info = Info}, Label) when is_integer(Label) ->
table_lookup(Info, Label).
-spec insert_types(plt(), dict()) -> plt().
insert_types(PLT, Rec) ->
- PLT#dialyzer_plt{types = Rec}.
+ PLT#plt{types = Rec}.
-spec get_types(plt()) -> dict().
-get_types(#dialyzer_plt{types = Types}) ->
+get_types(#plt{types = Types}) ->
Types.
-type mfa_types() :: {mfa(), erl_types:erl_type(), [erl_types:erl_type()]}.
-spec lookup_module(plt(), module()) -> 'none' | {'value', [mfa_types()]}.
-lookup_module(#dialyzer_plt{info = Info}, M) when is_atom(M) ->
+lookup_module(#plt{info = Info}, M) when is_atom(M) ->
table_lookup_module(Info, M).
-spec contains_module(plt(), module()) -> boolean().
-contains_module(#dialyzer_plt{info = Info, contracts = Cs}, M) when is_atom(M) ->
+contains_module(#plt{info = Info, contracts = Cs}, M) when is_atom(M) ->
table_contains_module(Info, M) orelse table_contains_module(Cs, M).
-spec contains_mfa(plt(), mfa()) -> boolean().
-contains_mfa(#dialyzer_plt{info = Info, contracts = Contracts}, MFA) ->
+contains_mfa(#plt{info = Info, contracts = Contracts}, MFA) ->
(table_lookup(Info, MFA) =/= none)
orelse (table_lookup(Contracts, MFA) =/= none).
@@ -208,14 +205,14 @@ from_file(FileName, ReturnInfo) ->
Msg = io_lib:format("Old PLT file ~s\n", [FileName]),
error(Msg);
ok ->
- Plt = #dialyzer_plt{info = Rec#dialyzer_file_plt.info,
- types = Rec#dialyzer_file_plt.types,
- contracts = Rec#dialyzer_file_plt.contracts},
+ Plt = #plt{info = Rec#file_plt.info,
+ types = Rec#file_plt.types,
+ contracts = Rec#file_plt.contracts},
case ReturnInfo of
false -> Plt;
true ->
- PltInfo = {Rec#dialyzer_file_plt.file_md5_list,
- Rec#dialyzer_file_plt.mod_deps},
+ PltInfo = {Rec#file_plt.file_md5_list,
+ Rec#file_plt.mod_deps},
{Plt, PltInfo}
end
end;
@@ -230,25 +227,25 @@ from_file(FileName, ReturnInfo) ->
included_files(FileName) ->
case get_record_from_file(FileName) of
- {ok, #dialyzer_file_plt{file_md5_list = Md5}} ->
+ {ok, #file_plt{file_md5_list = Md5}} ->
{ok, [File || {File, _} <- Md5]};
{error, _What} = Error ->
Error
end.
-check_version(#dialyzer_file_plt{version=?VSN, implementation_md5=ImplMd5}) ->
+check_version(#file_plt{version = ?VSN, implementation_md5 = ImplMd5}) ->
case compute_new_md5(ImplMd5, [], []) of
ok -> ok;
{differ, _, _} -> error;
{error, _} -> error
end;
-check_version(#dialyzer_file_plt{}) -> error.
+check_version(#file_plt{}) -> error.
get_record_from_file(FileName) ->
case file:read_file(FileName) of
{ok, Bin} ->
try binary_to_term(Bin) of
- #dialyzer_file_plt{} = FilePLT -> {ok, FilePLT};
+ #file_plt{} = FilePLT -> {ok, FilePLT};
_ -> {error, not_valid}
catch
_:_ -> {error, not_valid}
@@ -262,30 +259,30 @@ get_record_from_file(FileName) ->
-spec merge_plts([plt()]) -> plt().
merge_plts(List) ->
- InfoList = [Info || #dialyzer_plt{info = Info} <- List],
- TypesList = [Types || #dialyzer_plt{types = Types} <- List],
- ContractsList = [Contracts || #dialyzer_plt{contracts = Contracts} <- List],
- #dialyzer_plt{info = table_merge(InfoList),
- types = table_merge(TypesList),
- contracts = table_merge(ContractsList)}.
+ InfoList = [Info || #plt{info = Info} <- List],
+ TypesList = [Types || #plt{types = Types} <- List],
+ ContractsList = [Contracts || #plt{contracts = Contracts} <- List],
+ #plt{info = table_merge(InfoList),
+ types = table_merge(TypesList),
+ contracts = table_merge(ContractsList)}.
-spec to_file(file:filename(), plt(), mod_deps(), {[file_md5()], mod_deps()}) -> 'ok'.
to_file(FileName,
- #dialyzer_plt{info = Info, types = Types, contracts = Contracts},
+ #plt{info = Info, types = Types, contracts = Contracts},
ModDeps, {MD5, OldModDeps}) ->
NewModDeps = dict:merge(fun(_Key, OldVal, NewVal) ->
ordsets:union(OldVal, NewVal)
end,
OldModDeps, ModDeps),
ImplMd5 = compute_implementation_md5(),
- Record = #dialyzer_file_plt{version = ?VSN,
- file_md5_list = MD5,
- info = Info,
- contracts = Contracts,
- types = Types,
- mod_deps = NewModDeps,
- implementation_md5 = ImplMd5},
+ Record = #file_plt{version = ?VSN,
+ file_md5_list = MD5,
+ info = Info,
+ contracts = Contracts,
+ types = Types,
+ mod_deps = NewModDeps,
+ implementation_md5 = ImplMd5},
Bin = term_to_binary(Record, [compressed]),
case file:write_file(FileName, Bin) of
ok -> ok;
@@ -307,7 +304,7 @@ to_file(FileName,
check_plt(FileName, RemoveFiles, AddFiles) ->
case get_record_from_file(FileName) of
- {ok, #dialyzer_file_plt{file_md5_list = Md5, mod_deps = ModDeps} = Rec} ->
+ {ok, #file_plt{file_md5_list = Md5, mod_deps = ModDeps} = Rec} ->
case check_version(Rec) of
ok ->
case compute_new_md5(Md5, RemoveFiles, AddFiles) of
@@ -420,18 +417,17 @@ init_md5_list_1(Md5List, [], Acc) ->
-spec get_specs(plt()) -> string().
-get_specs(#dialyzer_plt{info = Info}) ->
+get_specs(#plt{info = Info}) ->
%% TODO: Should print contracts as well.
- List =
- lists:sort([{MFA, Val} || {MFA = {_,_,_}, Val} <- table_to_list(Info)]),
- lists:flatten(create_specs(List, [])).
+ L = lists:sort([{MFA, Val} || {{_,_,_} = MFA, Val} <- table_to_list(Info)]),
+ lists:flatten(create_specs(L, [])).
beam_file_to_module(Filename) ->
list_to_atom(filename:basename(Filename, ".beam")).
-spec get_specs(plt(), module(), atom(), arity_patt()) -> 'none' | string().
-get_specs(#dialyzer_plt{info = Info}, M, F, A) when is_atom(M), is_atom(F) ->
+get_specs(#plt{info = Info}, M, F, A) when is_atom(M), is_atom(F) ->
MFA = {M, F, A},
case table_lookup(Info, MFA) of
none -> none;
@@ -526,9 +522,9 @@ table_merge([H|T]) ->
table_merge([], Acc) ->
Acc;
-table_merge([Plt|Left], Acc) ->
+table_merge([Plt|Plts], Acc) ->
NewAcc = dict:merge(fun(_Key, Val, Val) -> Val end, Plt, Acc),
- table_merge(Left, NewAcc).
+ table_merge(Plts, NewAcc).
%%---------------------------------------------------------------------------
%% Debug utilities.
@@ -538,7 +534,7 @@ table_merge([Plt|Left], Acc) ->
pp_non_returning() ->
PltFile = get_default_plt(),
Plt = from_file(PltFile),
- List = table_to_list(Plt#dialyzer_plt.info),
+ List = table_to_list(Plt#plt.info),
Unit = [{MFA, erl_types:t_fun(Args, Ret)} || {MFA, {Ret, Args}} <- List,
erl_types:t_is_unit(Ret)],
None = [{MFA, erl_types:t_fun(Args, Ret)} || {MFA, {Ret, Args}} <- List,
diff --git a/lib/dialyzer/src/dialyzer_races.erl b/lib/dialyzer/src/dialyzer_races.erl
index 5857f7a03d..4972967960 100644
--- a/lib/dialyzer/src/dialyzer_races.erl
+++ b/lib/dialyzer/src/dialyzer_races.erl
@@ -1,20 +1,20 @@
%% -*- erlang-indent-level: 2 -*-
%%-----------------------------------------------------------------------
%% %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%
%%
@@ -50,8 +50,10 @@
-define(local, 5).
-define(no_arg, no_arg).
-define(no_label, no_label).
+-define(bypassed, bypassed).
-define(WARN_WHEREIS_REGISTER, warn_whereis_register).
+-define(WARN_WHEREIS_UNREGISTER, warn_whereis_unregister).
-define(WARN_ETS_LOOKUP_INSERT, warn_ets_lookup_insert).
-define(WARN_MNESIA_DIRTY_READ_WRITE, warn_mnesia_dirty_read_write).
-define(WARN_NO_WARN, warn_no_warn).
@@ -64,27 +66,29 @@
-type mfa_or_funlbl() :: label() | mfa().
--type label_type() :: label() | [label()] | {label()} | ?no_label.
--type args() :: [label_type() | [string()]].
--type core_vars() :: cerl:cerl() | ?no_arg.
--type var_to_map() :: core_vars() | [cerl:cerl()].
--type core_args() :: [core_vars()] | 'empty'.
--type op() :: 'bind' | 'unbind'.
+-type label_type() :: label() | [label()] | {label()} | ?no_label.
+-type args() :: [label_type() | [string()]].
+-type core_vars() :: cerl:cerl() | ?no_arg | ?bypassed.
+-type var_to_map1() :: core_vars() | [cerl:cerl()].
+-type var_to_map2() :: cerl:cerl() | [cerl:cerl()] | ?bypassed.
+-type core_args() :: [core_vars()] | 'empty'.
+-type op() :: 'bind' | 'unbind'.
-type dep_calls() :: 'whereis' | 'ets_lookup' | 'mnesia_dirty_read'.
--type warn_calls() :: 'register' | 'ets_insert' | 'mnesia_dirty_write'.
--type call() :: 'whereis' | 'register' | 'ets_new' | 'ets_lookup'
- | 'ets_insert' | 'mnesia_dirty_read1'
+-type warn_calls() :: 'register' | 'unregister' | 'ets_insert'
+ | 'mnesia_dirty_write'.
+-type call() :: 'whereis' | 'register' | 'unregister' | 'ets_new'
+ | 'ets_lookup' | 'ets_insert' | 'mnesia_dirty_read1'
| 'mnesia_dirty_read2' | 'mnesia_dirty_write1'
| 'mnesia_dirty_write2' | 'function_call'.
--type race_tag() :: 'whereis_register' | 'ets_lookup_insert'
- | 'mnesia_dirty_read_write'.
+-type race_tag() :: 'whereis_register' | 'whereis_unregister'
+ | 'ets_lookup_insert' | 'mnesia_dirty_read_write'.
--record(beg_clause, {arg :: var_to_map(),
- pats :: var_to_map(),
+-record(beg_clause, {arg :: var_to_map1(),
+ pats :: var_to_map1(),
guard :: cerl:cerl()}).
--record(end_clause, {arg :: var_to_map(),
- pats :: var_to_map(),
+-record(end_clause, {arg :: var_to_map1(),
+ pats :: var_to_map1(),
guard :: cerl:cerl()}).
-record(end_case, {clauses :: [#end_clause{}]}).
-record(curr_fun, {status :: 'in' | 'out',
@@ -98,15 +102,15 @@
args :: args(),
arg_types :: [erl_types:erl_type()],
vars :: [core_vars()],
- state :: _,
+ state :: _, %% XXX: recursive
file_line :: file_line(),
var_map :: dict()}).
-record(fun_call, {caller :: mfa_or_funlbl(),
callee :: mfa_or_funlbl(),
arg_types :: [erl_types:erl_type()],
vars :: [core_vars()]}).
--record(let_tag, {var :: var_to_map(),
- arg :: var_to_map()}).
+-record(let_tag, {var :: var_to_map1(),
+ arg :: var_to_map1()}).
-record(warn_call, {call_name :: warn_calls(),
args :: args(),
var_map :: dict()}).
@@ -180,6 +184,14 @@ store_race_call(Fun, ArgTypes, Args, FileLine, State) ->
fun_mfa = CurrFun, fun_label = CurrFunLabel},
{[#warn_call{call_name = register, args = VarArgs}|
RaceList], RaceListSize + 1, [RaceFun|RaceTags], no_t};
+ {erlang, unregister, 1} ->
+ VarArgs = format_args(Args, ArgTypes, CleanState, unregister),
+ RaceFun = #race_fun{mfa = Fun, args = VarArgs,
+ arg_types = ArgTypes, vars = Args,
+ file_line = FileLine, index = RaceListSize,
+ fun_mfa = CurrFun, fun_label = CurrFunLabel},
+ {[#warn_call{call_name = unregister, args = VarArgs}|
+ RaceList], RaceListSize + 1, [RaceFun|RaceTags], no_t};
{erlang, whereis, 1} ->
VarArgs = format_args(Args, ArgTypes, CleanState, whereis),
{[#dep_call{call_name = whereis, args = VarArgs,
@@ -280,6 +292,7 @@ race(State) ->
RaceWarnTag =
case Fun of
{erlang, register, 2} -> ?WARN_WHEREIS_REGISTER;
+ {erlang, unregister, 1} -> ?WARN_WHEREIS_UNREGISTER;
{ets, insert, 2} -> ?WARN_ETS_LOOKUP_INSERT;
{mnesia, dirty_write, _A} -> ?WARN_MNESIA_DIRTY_READ_WRITE
end,
@@ -287,7 +300,7 @@ race(State) ->
state__renew_curr_fun(CurrFun,
state__renew_curr_fun_label(CurrFunLabel,
state__renew_race_list(lists:nthtail(length(RaceList) - Index,
- RaceList), State))),
+ RaceList), State))),
DepList = fixup_race_list(RaceWarnTag, VarArgs, State1),
{State2, RaceWarn} =
get_race_warn(Fun, Args, ArgTypes, DepList, State),
@@ -309,6 +322,7 @@ fixup_race_list(RaceWarnTag, WarnVarArgs, State) ->
RaceTag =
case RaceWarnTag of
?WARN_WHEREIS_REGISTER -> whereis_register;
+ ?WARN_WHEREIS_UNREGISTER -> whereis_unregister;
?WARN_ETS_LOOKUP_INSERT -> ets_lookup_insert;
?WARN_MNESIA_DIRTY_READ_WRITE -> mnesia_dirty_read_write
end,
@@ -320,11 +334,9 @@ fixup_race_list(RaceWarnTag, WarnVarArgs, State) ->
lists:reverse(NewRaceList), [], CurrFun,
WarnVarArgs, RaceWarnTag, dict:new(),
[], [], [], 2 * ?local, NewState),
- Parents =
- fixup_race_backward(CurrFun, Calls, Calls, [], ?local),
+ Parents = fixup_race_backward(CurrFun, Calls, Calls, [], ?local),
UParents = lists:usort(Parents),
- Filtered =
- filter_parents(UParents, UParents, Digraph),
+ Filtered = filter_parents(UParents, UParents, Digraph),
NewParents =
case lists:member(CurrFun, Filtered) of
true -> Filtered;
@@ -401,8 +413,7 @@ fixup_race_forward_pullout(CurrFun, CurrFunLabel, Calls, Code, RaceList,
false ->
{ok, Fun} = Name,
{ok, Int} = Label,
- case dict:find(Fun,
- dialyzer_callgraph:get_race_code(Callgraph)) of
+ case dict:find(Fun, dialyzer_callgraph:get_race_code(Callgraph)) of
error ->
{NewCurrFun, NewCurrFunLabel, NewCalls, Tail, NewRaceList,
NewRaceVarMap, NewFunDefVars, NewFunCallVars, NewFunArgTypes,
@@ -459,7 +470,8 @@ fixup_race_forward(CurrFun, CurrFunLabel, Calls, Code, RaceList,
case Head of
#dep_call{call_name = whereis} ->
case RaceWarnTag of
- ?WARN_WHEREIS_REGISTER ->
+ WarnWhereis when WarnWhereis =:= ?WARN_WHEREIS_REGISTER orelse
+ WarnWhereis =:= ?WARN_WHEREIS_UNREGISTER ->
{[Head#dep_call{var_map = RaceVarMap}|RaceList],
[], NestingLevel, false};
_Other ->
@@ -493,9 +505,11 @@ fixup_race_forward(CurrFun, CurrFunLabel, Calls, Code, RaceList,
_Other ->
{RaceList, [], NestingLevel, false}
end;
- #warn_call{call_name = register} ->
+ #warn_call{call_name = RegCall} when RegCall =:= register orelse
+ RegCall =:= unregister ->
case RaceWarnTag of
- ?WARN_WHEREIS_REGISTER ->
+ WarnWhereis when WarnWhereis =:= ?WARN_WHEREIS_REGISTER orelse
+ WarnWhereis =:= ?WARN_WHEREIS_UNREGISTER ->
{[Head#warn_call{var_map = RaceVarMap}|RaceList],
[], NestingLevel, false};
_Other ->
@@ -575,6 +589,10 @@ fixup_race_forward(CurrFun, CurrFunLabel, Calls, Code, RaceList,
{[#warn_call{call_name = register, args = WarnVarArgs,
var_map = RaceVarMap}],
NewDepList};
+ whereis_unregister ->
+ {[#warn_call{call_name = unregister, args = WarnVarArgs,
+ var_map = RaceVarMap}],
+ NewDepList};
ets_lookup_insert ->
NewWarnCall =
[#warn_call{call_name = ets_insert, args = WarnVarArgs,
@@ -760,6 +778,19 @@ get_deplist_paths(RaceList, WarnVarArgs, RaceWarnTag, RaceVarMap, CurrLevel,
_ ->
{[Vars, WVA2, WVA3, WVA4], false}
end;
+ ?WARN_WHEREIS_UNREGISTER ->
+ [WVA1, WVA2] = WarnVarArgs1,
+ Vars =
+ lists:flatten(
+ [find_all_bound_vars(V, RaceVarMap1) || V <- WVA1]),
+ case {Vars, CurrLevel} of
+ {[], 0} ->
+ {WarnVarArgs, true};
+ {[], _} ->
+ {WarnVarArgs, false};
+ _ ->
+ {[Vars, WVA2], false}
+ end;
?WARN_ETS_LOOKUP_INSERT ->
[WVA1, WVA2, WVA3, WVA4] = WarnVarArgs1,
Vars1 =
@@ -805,8 +836,9 @@ get_deplist_paths(RaceList, WarnVarArgs, RaceWarnTag, RaceVarMap, CurrLevel,
get_deplist_paths(Tail, WarnVarArgs2, RaceWarnTag, RaceVarMap1,
CurrLevel1, PublicTables, NamedTables)
end;
- #warn_call{call_name = register, args = WarnVarArgs1,
- var_map = RaceVarMap1} ->
+ #warn_call{call_name = RegCall, args = WarnVarArgs1,
+ var_map = RaceVarMap1} when RegCall =:= register orelse
+ RegCall =:= unregister ->
case compare_first_arg(WarnVarArgs, WarnVarArgs1, RaceVarMap1) of
true -> {[], false, false};
NewWarnVarArgs ->
@@ -1416,7 +1448,8 @@ lists_get(N, List) -> lists:nth(N, List).
refine_race(RaceCall, WarnVarArgs, RaceWarnTag, DependencyList, RaceVarMap) ->
case RaceWarnTag of
- ?WARN_WHEREIS_REGISTER ->
+ WarnWhereis when WarnWhereis =:= ?WARN_WHEREIS_REGISTER orelse
+ WarnWhereis =:= ?WARN_WHEREIS_UNREGISTER ->
case RaceCall of
#dep_call{call_name = ets_lookup} ->
DependencyList;
@@ -1660,6 +1693,20 @@ compare_types(VarArgs, WarnVarArgs, RaceWarnTag, RaceVarMap) ->
end
end;
+ ?WARN_WHEREIS_UNREGISTER ->
+ [VA1, VA2] = VarArgs,
+ [WVA1, WVA2] = WarnVarArgs,
+ case any_args(VA2) of
+ true -> compare_var_list(VA1, WVA1, RaceVarMap);
+ false ->
+ case any_args(WVA2) of
+ true -> compare_var_list(VA1, WVA1, RaceVarMap);
+ false ->
+ compare_var_list(VA1, WVA1, RaceVarMap) orelse
+ compare_argtypes(VA2, WVA2)
+
+ end
+ end;
?WARN_ETS_LOOKUP_INSERT ->
[VA1, VA2, VA3, VA4] = VarArgs,
[WVA1, WVA2, WVA3, WVA4] = WarnVarArgs,
@@ -1683,8 +1730,8 @@ compare_types(VarArgs, WarnVarArgs, RaceWarnTag, RaceVarMap) ->
true ->
compare_var_list(VA3, WVA3, RaceVarMap);
false ->
- compare_var_list(VA3, WVA3, RaceVarMap)
- orelse compare_argtypes(VA4, WVA4)
+ compare_var_list(VA3, WVA3, RaceVarMap) orelse
+ compare_argtypes(VA4, WVA4)
end
end);
?WARN_MNESIA_DIRTY_READ_WRITE ->
@@ -1818,6 +1865,7 @@ ets_tuple_argtypes1(Str, Tuple, TupleList, NestingLevel) ->
end
end.
+format_arg(?bypassed) -> ?no_label;
format_arg(Arg) ->
case cerl:type(Arg) of
var -> cerl_trees:get_label(Arg);
@@ -1845,9 +1893,13 @@ format_args_1([Arg], [Type], CleanState) ->
[format_arg(Arg), format_type(Type, CleanState)];
format_args_1([Arg|Args], [Type|Types], CleanState) ->
List =
- case cerl:is_literal(Arg) of
- true -> [?no_label, format_cerl(Arg)];
- false -> [format_arg(Arg), format_type(Type, CleanState)]
+ case Arg =:= ?bypassed of
+ true -> [?no_label, format_type(Type, CleanState)];
+ false ->
+ case cerl:is_literal(Arg) of
+ true -> [?no_label, format_cerl(Arg)];
+ false -> [format_arg(Arg), format_type(Type, CleanState)]
+ end
end,
List ++ format_args_1(Args, Types, CleanState).
@@ -1859,6 +1911,9 @@ format_args_2(StrArgList, Call) ->
register ->
lists_key_replace(2, StrArgList,
string:tokens(lists:nth(2, StrArgList), " |"));
+ unregister ->
+ lists_key_replace(2, StrArgList,
+ string:tokens(lists:nth(2, StrArgList), " |"));
ets_new ->
StrArgList1 = lists_key_replace(2, StrArgList,
string:tokens(lists:nth(2, StrArgList), " |")),
@@ -1919,10 +1974,11 @@ mnesia_tuple_argtypes(TupleStr) ->
[TupleStr2|_T] = string:tokens(TupleStr1, " ,"),
lists:flatten(string:tokens(TupleStr2, " |")).
--spec race_var_map(var_to_map(), cerl:cerl() | [cerl:cerl()], dict(), op()) -> dict().
+-spec race_var_map(var_to_map1(), var_to_map2(), dict(), op()) -> dict().
race_var_map(Vars1, Vars2, RaceVarMap, Op) ->
- case Vars1 =:= ?no_arg of
+ case Vars1 =:= ?no_arg orelse Vars1 =:= ?bypassed
+ orelse Vars2 =:= ?bypassed of
true -> RaceVarMap;
false ->
case is_list(Vars1) andalso is_list(Vars2) of
@@ -2076,7 +2132,7 @@ race_var_map_guard(Arg, Pats, Guard, RaceVarMap, Op) ->
{RaceVarMap1, RemoveClause orelse RemoveClause1}.
race_var_map_guard_helper1(Arg, Pats, RaceVarMap, Op) ->
- case Arg =:= ?no_arg of
+ case Arg =:= ?no_arg orelse Arg =:= ?bypassed of
true -> {RaceVarMap, false};
false ->
case cerl:type(Arg) of
@@ -2139,7 +2195,7 @@ unbind_dict_vars(Var1, Var2, RaceVarMap) ->
true ->
unbind_dict_vars(Var1, Var2,
bind_dict_vars_list(Var1, Labels -- [Var2],
- dict:erase(Var1, RaceVarMap)));
+ dict:erase(Var1, RaceVarMap)));
false ->
unbind_dict_vars_helper(Labels, Var1, Var2, RaceVarMap)
end
@@ -2171,6 +2227,10 @@ var_analysis(FunDefArgs, FunCallArgs, WarnVarArgs, RaceWarnTag) ->
[WVA1, WVA2, WVA3, WVA4] = WarnVarArgs,
ArgNos = lists_key_members_lists(WVA1, FunDefArgs),
[[lists_get(N, FunCallArgs) || N <- ArgNos], WVA2, WVA3, WVA4];
+ ?WARN_WHEREIS_UNREGISTER ->
+ [WVA1, WVA2] = WarnVarArgs,
+ ArgNos = lists_key_members_lists(WVA1, FunDefArgs),
+ [[lists_get(N, FunCallArgs) || N <- ArgNos], WVA2];
?WARN_ETS_LOOKUP_INSERT ->
[WVA1, WVA2, WVA3, WVA4] = WarnVarArgs,
ArgNos1 = lists_key_members_lists(WVA1, FunDefArgs),
@@ -2185,8 +2245,7 @@ var_analysis(FunDefArgs, FunCallArgs, WarnVarArgs, RaceWarnTag) ->
var_type_analysis(FunDefArgs, FunCallTypes, WarnVarArgs, RaceWarnTag,
RaceVarMap, CleanState) ->
- FunVarArgs = format_args(FunDefArgs, FunCallTypes, CleanState,
- function_call),
+ FunVarArgs = format_args(FunDefArgs, FunCallTypes, CleanState, function_call),
case RaceWarnTag of
?WARN_WHEREIS_REGISTER ->
[WVA1, WVA2, WVA3, WVA4] = WarnVarArgs,
@@ -2197,6 +2256,15 @@ var_type_analysis(FunDefArgs, FunCallTypes, WarnVarArgs, RaceWarnTag,
NewWVA2 = string:tokens(lists:nth(N + 1, FunVarArgs), " |"),
[Vars, NewWVA2, WVA3, WVA4]
end;
+ ?WARN_WHEREIS_UNREGISTER ->
+ [WVA1, WVA2] = WarnVarArgs,
+ Vars = find_all_bound_vars(WVA1, RaceVarMap),
+ case lists_key_member_lists(Vars, FunVarArgs) of
+ 0 -> [Vars, WVA2];
+ N when is_integer(N) ->
+ NewWVA2 = string:tokens(lists:nth(N + 1, FunVarArgs), " |"),
+ [Vars, NewWVA2]
+ end;
?WARN_ETS_LOOKUP_INSERT ->
[WVA1, WVA2, WVA3, WVA4] = WarnVarArgs,
Vars1 = find_all_bound_vars(WVA1, RaceVarMap),
@@ -2278,6 +2346,10 @@ get_race_warnings_helper(Warnings, State) ->
get_reason(lists:keysort(7, DepList),
"might fail due to a possible race condition "
"caused by its combination with ");
+ ?WARN_WHEREIS_UNREGISTER ->
+ get_reason(lists:keysort(7, DepList),
+ "might fail due to a possible race condition "
+ "caused by its combination with ");
?WARN_ETS_LOOKUP_INSERT ->
get_reason(lists:keysort(7, DepList),
"might have an unintended effect due to " ++
@@ -2335,7 +2407,7 @@ state__add_race_warning(State, RaceWarn, RaceWarnTag, FileLine) ->
%%%
%%% ===========================================================================
--spec beg_clause_new(var_to_map(), var_to_map(), cerl:cerl()) ->
+-spec beg_clause_new(var_to_map1(), var_to_map1(), cerl:cerl()) ->
#beg_clause{}.
beg_clause_new(Arg, Pats, Guard) ->
@@ -2351,7 +2423,7 @@ cleanup(#races{race_list = RaceList}) ->
end_case_new(Clauses) ->
#end_case{clauses = Clauses}.
--spec end_clause_new(var_to_map(), var_to_map(), cerl:cerl()) ->
+-spec end_clause_new(var_to_map1(), var_to_map1(), cerl:cerl()) ->
#end_clause{}.
end_clause_new(Arg, Pats, Guard) ->
@@ -2387,7 +2459,7 @@ get_race_list(#races{race_list = RaceList}) ->
get_race_list_size(#races{race_list_size = RaceListSize}) ->
RaceListSize.
--spec let_tag_new(var_to_map(), var_to_map()) -> #let_tag{}.
+-spec let_tag_new(var_to_map1(), var_to_map1()) -> #let_tag{}.
let_tag_new(Var, Arg) ->
#let_tag{var = Var, arg = Arg}.
@@ -2422,5 +2494,4 @@ put_race_analysis(Analysis, Races) ->
races().
put_race_list(RaceList, RaceListSize, Races) ->
- Races#races{race_list = RaceList,
- race_list_size = RaceListSize}.
+ Races#races{race_list = RaceList, race_list_size = RaceListSize}.
diff --git a/lib/dialyzer/src/dialyzer_succ_typings.erl b/lib/dialyzer/src/dialyzer_succ_typings.erl
index dd8480f1f2..1ff4783852 100644
--- a/lib/dialyzer/src/dialyzer_succ_typings.erl
+++ b/lib/dialyzer/src/dialyzer_succ_typings.erl
@@ -1,20 +1,20 @@
%% -*- erlang-indent-level: 2 -*-
%%-----------------------------------------------------------------------
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2006-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 2006-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%
%%
@@ -29,7 +29,7 @@
-export([analyze_callgraph/3,
analyze_callgraph/4,
- get_warnings/6]).
+ get_warnings/7]).
%% These are only intended as debug functions.
-export([doit/1,
@@ -106,19 +106,21 @@ get_refined_success_typings(State) ->
-type doc_plt() :: 'undefined' | dialyzer_plt:plt().
-spec get_warnings(dialyzer_callgraph:callgraph(), dialyzer_plt:plt(),
doc_plt(), dialyzer_codeserver:codeserver(), set(),
- pid()) ->
+ pid(), boolean()) ->
{[dial_warning()], dialyzer_plt:plt(), doc_plt()}.
-get_warnings(Callgraph, Plt, DocPlt, Codeserver, NoWarnUnused, Parent) ->
+get_warnings(Callgraph, Plt, DocPlt, Codeserver,
+ NoWarnUnused, Parent, BehavioursChk) ->
InitState = #st{callgraph = Callgraph, codeserver = Codeserver,
no_warn_unused = NoWarnUnused, parent = Parent, plt = Plt},
NewState = get_refined_success_typings(InitState),
Mods = dialyzer_callgraph:modules(NewState#st.callgraph),
CWarns = dialyzer_contracts:get_invalid_contract_warnings(Mods, Codeserver,
NewState#st.plt),
- get_warnings_from_modules(Mods, NewState, DocPlt, CWarns).
+ get_warnings_from_modules(Mods, NewState, DocPlt, BehavioursChk, CWarns).
-get_warnings_from_modules([M|Ms], State, DocPlt, Acc) when is_atom(M) ->
+get_warnings_from_modules([M|Ms], State, DocPlt,
+ BehavioursChk, Acc) when is_atom(M) ->
send_log(State#st.parent, io_lib:format("Getting warnings for ~w\n", [M])),
#st{callgraph = Callgraph, codeserver = Codeserver,
no_warn_unused = NoWarnUnused, plt = Plt} = State,
@@ -131,13 +133,20 @@ get_warnings_from_modules([M|Ms], State, DocPlt, Acc) when is_atom(M) ->
dialyzer_contracts:contracts_without_fun(Contracts, AllFuns, Callgraph),
{Warnings2, FunTypes, RaceCode, PublicTables, NamedTables} =
dialyzer_dataflow:get_warnings(ModCode, Plt, Callgraph, Records, NoWarnUnused),
+ Attrs = cerl:module_attrs(ModCode),
+ Warnings3 = if BehavioursChk ->
+ dialyzer_behaviours:check_callbacks(M, Attrs,
+ Plt, Codeserver);
+ true -> []
+ end,
NewDocPlt = insert_into_doc_plt(FunTypes, Callgraph, DocPlt),
NewCallgraph =
dialyzer_callgraph:renew_race_info(Callgraph, RaceCode, PublicTables,
NamedTables),
State1 = st__renew_state_calls(NewCallgraph, State),
- get_warnings_from_modules(Ms, State1, NewDocPlt, [Warnings1,Warnings2|Acc]);
-get_warnings_from_modules([], #st{plt = Plt}, DocPlt, Acc) ->
+ get_warnings_from_modules(Ms, State1, NewDocPlt, BehavioursChk,
+ [Warnings1, Warnings2, Warnings3|Acc]);
+get_warnings_from_modules([], #st{plt = Plt}, DocPlt, _, Acc) ->
{lists:flatten(Acc), Plt, DocPlt}.
refine_succ_typings(ModulePostorder, State) ->
diff --git a/lib/dialyzer/src/dialyzer_typesig.erl b/lib/dialyzer/src/dialyzer_typesig.erl
index aeb20d4fae..35b283a00a 100644
--- a/lib/dialyzer/src/dialyzer_typesig.erl
+++ b/lib/dialyzer/src/dialyzer_typesig.erl
@@ -1,20 +1,20 @@
%% -*- erlang-indent-level: 2 -*-
%%-----------------------------------------------------------------------
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2006-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 2006-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%
%%
@@ -43,6 +43,7 @@
t_is_float/1, t_is_fun/1,
t_is_integer/1, t_non_neg_integer/0,
t_is_list/1, t_is_nil/1, t_is_none/1, t_is_number/1,
+
t_is_subtype/2, t_limit/2, t_list/0, t_list/1,
t_list_elements/1, t_nonempty_list/1, t_maybe_improper_list/0,
t_module/0, t_number/0, t_number_vals/1,
@@ -51,7 +52,7 @@
t_pid/0, t_port/0, t_product/1, t_reference/0,
t_subst/2, t_subtract/2, t_subtract_list/2, t_sup/1, t_sup/2,
t_timeout/0, t_tuple/0, t_tuple/1,
- t_unify/2, t_var/1, t_var_name/1,
+ t_unify/3, t_var/1, t_var_name/1,
t_none/0, t_unit/0]).
-include("dialyzer.hrl").
@@ -71,14 +72,20 @@
rhs :: fvar_or_type(),
deps :: [dep()]}).
+-type constraint() :: #constraint{}.
+
-record(constraint_list, {type :: 'conj' | 'disj',
- list :: [_], % [constr()] but it needs recursion :-(
+ list :: [constr()],
deps :: [dep()],
id :: {'list', dep()}}).
+-type constraint_list() :: #constraint_list{}.
+
-record(constraint_ref, {id :: type_var(), deps :: [dep()]}).
--type constr() :: #constraint{} | #constraint_list{} | #constraint_ref{}.
+-type constraint_ref() :: #constraint_ref{}.
+
+-type constr() :: constraint() | constraint_list() | constraint_ref().
-type typesig_scc() :: [{mfa(), {cerl:c_var(), cerl:c_fun()}, dict()}].
-type typesig_funmap() :: [{type_var(), type_var()}]. %% Orddict
@@ -90,6 +97,7 @@
fun_arities = dict:new() :: dict(),
in_match = false :: boolean(),
in_guard = false :: boolean(),
+ module :: module(),
name_map = dict:new() :: dict(),
next_label :: label(),
non_self_recs = [] :: [label()],
@@ -98,7 +106,7 @@
records = dict:new() :: dict(),
opaques = [] :: [erl_types:erl_type()],
scc = [] :: [type_var()]}).
-
+
%%-----------------------------------------------------------------------------
-define(TYPE_LIMIT, 4).
@@ -631,6 +639,9 @@ handle_call(Call, DefinedVars, State) ->
get_plt_constr(MFA, Dst, ArgVars, State) ->
Plt = state__plt(State),
PltRes = dialyzer_plt:lookup(Plt, MFA),
+ Opaques = State#state.opaques,
+ Module = State#state.module,
+ {FunModule, _, _} = MFA,
case dialyzer_plt:lookup_contract(Plt, MFA) of
none ->
case PltRes of
@@ -651,7 +662,14 @@ get_plt_constr(MFA, Dst, ArgVars, State) ->
%% Need to combine the contract with the success typing.
{mk_fun_var(
fun(Map) ->
- ArgTypes = lookup_type_list(ArgVars, Map),
+ ArgTypes0 = lookup_type_list(ArgVars, Map),
+ ArgTypes = case FunModule =:= Module of
+ false ->
+ List = lists:zip(PltArgTypes, ArgTypes0),
+ [erl_types:t_unopaque_on_mismatch(T1, T2, Opaques)
+ || {T1, T2} <- List];
+ true -> ArgTypes0
+ end,
CRet = dialyzer_contracts:get_contract_return(C, ArgTypes),
t_inf(CRet, PltRetType, opaque)
end, ArgVars),
@@ -681,8 +699,8 @@ filter_match_fail([]) ->
%% If there is a significant number of clauses, we cannot apply the
%% list subtraction scheme since it causes the analysis to be too
%% slow. Typically, this only affects automatically generated files.
-%% Anyway, and the dataflow analysis doesn't suffer from this, so we
-%% will get some information anyway.
+%% The dataflow analysis doesn't suffer from this, so we will get some
+%% information anyway.
-define(MAX_NOF_CLAUSES, 15).
handle_clauses(Clauses, TopVar, Arg, DefinedVars, State) ->
@@ -843,7 +861,7 @@ get_underapprox_from_guard(Tree, Map) ->
(cerl:is_c_var(Arg2) orelse cerl:is_literal(Arg2))) of
true ->
{Arg1Type, _} = get_underapprox_from_guard(Arg1, Map),
- {Arg2Type, _} = get_underapprox_from_guard(Arg1, Map),
+ {Arg2Type, _} = get_underapprox_from_guard(Arg2, Map),
case (t_is_equal(True, Arg1Type) andalso
t_is_equal(True, Arg2Type)) of
true -> {True, Map};
@@ -1511,13 +1529,21 @@ get_bif_constr({erlang, element, 2} = _BIF, Dst, Args, State) ->
Cs = mk_constraints(Args, sub, ArgTypes),
mk_conj_constraint_list([mk_constraint(Dst, sub, ReturnType)|Cs])
end;
-get_bif_constr({M, F, A} = _BIF, Dst, Args, _State) ->
+get_bif_constr({M, F, A} = _BIF, Dst, Args, State) ->
GenType = erl_bif_types:type(M, F, A),
+ Opaques = State#state.opaques,
case t_is_none(GenType) of
true -> ?debug("Bif: ~w failed\n", [_BIF]), throw(error);
false ->
+ UnopaqueFun =
+ fun(T) -> case lists:member(T, Opaques) of
+ true -> erl_types:t_unopaque(T, [T]);
+ false -> T
+ end
+ end,
ReturnType = mk_fun_var(fun(Map) ->
- TmpArgTypes = lookup_type_list(Args, Map),
+ TmpArgTypes0 = lookup_type_list(Args, Map),
+ TmpArgTypes = [UnopaqueFun(T) || T<- TmpArgTypes0],
erl_bif_types:type(M, F, A, TmpArgTypes)
end, Args),
case erl_bif_types:is_known(M, F, A) of
@@ -1815,7 +1841,7 @@ solve_cs([#constraint_list{} = C|Tail], Map, MapDict, State) ->
{error, _NewMapDict} = Error -> Error
end;
solve_cs([#constraint{} = C|Tail], Map, MapDict, State) ->
- case solve_one_c(C, Map) of
+ case solve_one_c(C, Map, State#state.opaques) of
error ->
?debug("+++++++++++\nFailed: ~s :: ~s ~w ~s :: ~s\n+++++++++++\n",
[format_type(C#constraint.lhs),
@@ -1830,7 +1856,7 @@ solve_cs([#constraint{} = C|Tail], Map, MapDict, State) ->
solve_cs([], Map, MapDict, _State) ->
{ok, MapDict, Map}.
-solve_one_c(#constraint{lhs = Lhs, rhs = Rhs, op = Op}, Map) ->
+solve_one_c(#constraint{lhs = Lhs, rhs = Rhs, op = Op}, Map, Opaques) ->
LhsType = lookup_type(Lhs, Map),
RhsType = lookup_type(Rhs, Map),
Inf = t_inf(LhsType, RhsType, opaque),
@@ -1841,16 +1867,16 @@ solve_one_c(#constraint{lhs = Lhs, rhs = Rhs, op = Op}, Map) ->
true -> error;
false ->
case Op of
- sub -> solve_subtype(Lhs, Inf, Map);
+ sub -> solve_subtype(Lhs, Inf, Map, Opaques);
eq ->
- case solve_subtype(Lhs, Inf, Map) of
+ case solve_subtype(Lhs, Inf, Map, Opaques) of
error -> error;
- {ok, Map1} -> solve_subtype(Rhs, Inf, Map1)
+ {ok, Map1} -> solve_subtype(Rhs, Inf, Map1, Opaques)
end
end
end.
-solve_subtype(Type, Inf, Map) ->
+solve_subtype(Type, Inf, Map, Opaques) ->
%% case cerl:is_literal(Type) of
%% true ->
%% case t_is_subtype(t_from_term(cerl:concrete(Type)), Inf) of
@@ -1858,7 +1884,7 @@ solve_subtype(Type, Inf, Map) ->
%% false -> error
%% end;
%% false ->
- try t_unify(Type, Inf) of
+ try t_unify(Type, Inf, Opaques) of
{_, List} -> {ok, enter_type_list(List, Map)}
catch
throw:{mismatch, _T1, _T2} ->
@@ -2046,7 +2072,7 @@ state__set_rec_dict(State, RecDict) ->
state__set_opaques(#state{records = RecDict} = State, {M, _F, _A}) ->
Opaques =
erl_types:module_builtin_opaques(M) ++ t_opaque_from_records(RecDict),
- State#state{opaques = Opaques}.
+ State#state{opaques = Opaques, module = M}.
state__lookup_record(#state{records = Records}, Tag, Arity) ->
case erl_types:lookup_record(Tag, Arity, Records) of
@@ -2258,7 +2284,7 @@ mk_constraint(Lhs, Op, Rhs) ->
case Deps =:= [] of
true ->
%% This constraint is constant. Solve it immediately.
- case solve_one_c(C, dict:new()) of
+ case solve_one_c(C, dict:new(), []) of
error -> throw(error);
_ ->
%% This is always true, keep it anyway for logistic reasons
diff --git a/lib/dialyzer/src/dialyzer_utils.erl b/lib/dialyzer/src/dialyzer_utils.erl
index fa9ad2eae2..6ea243c26f 100644
--- a/lib/dialyzer/src/dialyzer_utils.erl
+++ b/lib/dialyzer/src/dialyzer_utils.erl
@@ -1,20 +1,20 @@
%% -*- erlang-indent-level: 2 -*-
%%-----------------------------------------------------------------------
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2006-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 2006-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%
%%
@@ -47,6 +47,32 @@
-include("dialyzer.hrl").
+%%-define(DEBUG, true).
+
+-ifdef(DEBUG).
+print_types(RecDict) ->
+ Keys = dict:fetch_keys(RecDict),
+ print_types1(Keys, RecDict).
+
+print_types1([], _) ->
+ ok;
+print_types1([{type, _Name} = Key|T], RecDict) ->
+ {ok, {_Mod, Form, _Args}} = dict:find(Key, RecDict),
+ io:format("\n~w: ~w\n", [Key, erl_types:t_from_form(Form, RecDict)]),
+ print_types1(T, RecDict);
+print_types1([{opaque, _Name} = Key|T], RecDict) ->
+ {ok, {_Mod, Form, _Args}} = dict:find(Key, RecDict),
+ io:format("\n~w: ~w\n", [Key, erl_types:t_from_form(Form, RecDict)]),
+ print_types1(T, RecDict);
+print_types1([{record, _Name} = Key|T], RecDict) ->
+ {ok, [{Arity, Fields} = AF]} = dict:find(Key, RecDict),
+ io:format("~w: ~w\n\n", [Key, AF]),
+ print_types1(T, RecDict).
+-define(debug(D_), print_types(D_)).
+-else.
+-define(debug(D_), ok).
+-endif.
+
%%
%% Types that need to be imported from somewhere else
%%
@@ -61,13 +87,13 @@
%% ============================================================================
-spec get_abstract_code_from_src(atom() | file:filename()) ->
- {'ok', abstract_code()} | {'error', [string()]}.
+ {'ok', abstract_code()} | {'error', [string()]}.
get_abstract_code_from_src(File) ->
get_abstract_code_from_src(File, src_compiler_opts()).
-spec get_abstract_code_from_src(atom() | file:filename(), comp_options()) ->
- {'ok', abstract_code()} | {'error', [string()]}.
+ {'ok', abstract_code()} | {'error', [string()]}.
get_abstract_code_from_src(File, Opts) ->
case compile:file(File, [to_pp, binary|Opts]) of
@@ -137,60 +163,60 @@ get_core_from_abstract_code(AbstrCode, Opts) ->
%% ============================================================================
-spec get_record_and_type_info(abstract_code()) ->
- {'ok', dict()} | {'error', string()}.
+ {'ok', dict()} | {'error', string()}.
get_record_and_type_info(AbstractCode) ->
Module = get_module(AbstractCode),
get_record_and_type_info(AbstractCode, Module, dict:new()).
-spec get_record_and_type_info(abstract_code(), atom(), dict()) ->
- {'ok', dict()} | {'error', string()}.
+ {'ok', dict()} | {'error', string()}.
+
+get_record_and_type_info(AbstractCode, Module, RecDict) ->
+ get_record_and_type_info(AbstractCode, Module, [], RecDict).
get_record_and_type_info([{attribute, _, record, {Name, Fields0}}|Left],
- Module, RecDict) ->
- case get_record_fields(Fields0, RecDict) of
- {ok, Fields} ->
- Arity = length(Fields),
- Fun = fun(OldOrdDict) -> orddict:store(Arity, Fields, OldOrdDict) end,
- NewRecDict = dict:update({record, Name}, Fun, [{Arity, Fields}], RecDict),
- get_record_and_type_info(Left, Module, NewRecDict);
- {error, Error} ->
- {error, lists:flatten(io_lib:format(" Error while parsing #~w{}: ~s\n",
- [Name, Error]))}
- end;
+ Module, Records, RecDict) ->
+ {ok, Fields} = get_record_fields(Fields0, RecDict),
+ Arity = length(Fields),
+ NewRecDict = dict:store({record, Name}, [{Arity, Fields}], RecDict),
+ get_record_and_type_info(Left, Module, [{record, Name}|Records], NewRecDict);
get_record_and_type_info([{attribute, _, type, {{record, Name}, Fields0, []}}
- |Left], Module, RecDict) ->
+ |Left], Module, Records, RecDict) ->
%% This overrides the original record declaration.
- case get_record_fields(Fields0, RecDict) of
- {ok, Fields} ->
- Arity = length(Fields),
- Fun = fun(OldOrdDict) -> orddict:store(Arity, Fields, OldOrdDict) end,
- NewRecDict = dict:update({record, Name}, Fun, [{Arity, Fields}], RecDict),
- get_record_and_type_info(Left, Module, NewRecDict);
- {error, Error} ->
- {error, lists:flatten(io_lib:format(" Error while parsing #~w{}: ~s\n",
- [Name, Error]))}
- end;
+ {ok, Fields} = get_record_fields(Fields0, RecDict),
+ Arity = length(Fields),
+ NewRecDict = dict:store({record, Name}, [{Arity, Fields}], RecDict),
+ get_record_and_type_info(Left, Module, Records, NewRecDict);
get_record_and_type_info([{attribute, _, Attr, {Name, TypeForm}}|Left],
- Module, RecDict) when Attr =:= 'type'; Attr =:= 'opaque' ->
+ Module, Records, RecDict) when Attr =:= 'type';
+ Attr =:= 'opaque' ->
try
NewRecDict = add_new_type(Attr, Name, TypeForm, [], Module, RecDict),
- get_record_and_type_info(Left, Module, NewRecDict)
+ get_record_and_type_info(Left, Module, Records, NewRecDict)
catch
throw:{error, _} = Error -> Error
end;
get_record_and_type_info([{attribute, _, Attr, {Name, TypeForm, Args}}|Left],
- Module, RecDict) when Attr =:= 'type'; Attr =:= 'opaque' ->
+ Module, Records, RecDict) when Attr =:= 'type';
+ Attr =:= 'opaque' ->
try
NewRecDict = add_new_type(Attr, Name, TypeForm, Args, Module, RecDict),
- get_record_and_type_info(Left, Module, NewRecDict)
+ get_record_and_type_info(Left, Module, Records, NewRecDict)
catch
throw:{error, _} = Error -> Error
end;
-get_record_and_type_info([_Other|Left], Module, RecDict) ->
- get_record_and_type_info(Left, Module, RecDict);
-get_record_and_type_info([], _Module, RecDict) ->
- {ok, RecDict}.
+get_record_and_type_info([_Other|Left], Module, Records, RecDict) ->
+ get_record_and_type_info(Left, Module, Records, RecDict);
+get_record_and_type_info([], _Module, Records, RecDict) ->
+ case type_record_fields(lists:reverse(Records), RecDict) of
+ {ok, _NewRecDict} = Ok ->
+ ?debug(NewRecDict),
+ Ok;
+ {Name, {error, Error}} ->
+ {error, lists:flatten(io_lib:format(" Error while parsing #~w{}: ~s\n",
+ [Name, Error]))}
+ end.
add_new_type(TypeOrOpaque, Name, TypeForm, ArgForms, Module, RecDict) ->
case erl_types:type_is_defined(TypeOrOpaque, Name, RecDict) of
@@ -198,7 +224,6 @@ add_new_type(TypeOrOpaque, Name, TypeForm, ArgForms, Module, RecDict) ->
throw({error, io_lib:format("Type already defined: ~w\n", [Name])});
false ->
ArgTypes = [erl_types:t_from_form(X) || X <- ArgForms],
- _Type = erl_types:t_from_form(TypeForm, RecDict),
case lists:all(fun erl_types:t_is_var/1, ArgTypes) of
true ->
ArgNames = [erl_types:t_var_name(X) || X <- ArgTypes],
@@ -219,21 +244,36 @@ get_record_fields([{typed_record_field, OrdRecField, TypeForm}|Left],
{record_field, _Line, Name0} -> erl_parse:normalise(Name0);
{record_field, _Line, Name0, _Init} -> erl_parse:normalise(Name0)
end,
- try
- Type = erl_types:t_from_form(TypeForm, RecDict),
- get_record_fields(Left, RecDict, [{Name, Type}|Acc])
- catch
- throw:{error, _} = Error -> Error
- end;
+ get_record_fields(Left, RecDict, [{Name, TypeForm}|Acc]);
get_record_fields([{record_field, _Line, Name}|Left], RecDict, Acc) ->
- NewAcc = [{erl_parse:normalise(Name), erl_types:t_any()}|Acc],
+ NewAcc = [{erl_parse:normalise(Name), {var, -1, '_'}}|Acc],
get_record_fields(Left, RecDict, NewAcc);
get_record_fields([{record_field, _Line, Name, _Init}|Left], RecDict, Acc) ->
- NewAcc = [{erl_parse:normalise(Name), erl_types:t_any()}|Acc],
+ NewAcc = [{erl_parse:normalise(Name), {var, -1, '_'}}|Acc],
get_record_fields(Left, RecDict, NewAcc);
get_record_fields([], _RecDict, Acc) ->
{ok, lists:reverse(Acc)}.
+type_record_fields([], RecDict) ->
+ {ok, RecDict};
+type_record_fields([RecKey|Recs], RecDict) ->
+ {ok, [{Arity, Fields}]} = dict:find(RecKey, RecDict),
+ try
+ TypedFields =
+ [{FieldName, erl_types:t_from_form(FieldTypeForm, RecDict)}
+ || {FieldName, FieldTypeForm} <- Fields],
+ RecDict1 = dict:store(RecKey, [{Arity, TypedFields}], RecDict),
+ Fun = fun(OldOrdDict) ->
+ orddict:store(Arity, TypedFields, OldOrdDict)
+ end,
+ RecDict2 = dict:update(RecKey, Fun, RecDict1),
+ type_record_fields(Recs, RecDict2)
+ catch
+ throw:{error, _} = Error ->
+ {record, Name} = RecKey,
+ {Name, Error}
+ end.
+
-spec process_record_remote_types(dialyzer_codeserver:codeserver()) -> dialyzer_codeserver:codeserver().
process_record_remote_types(CServer) ->
@@ -269,7 +309,7 @@ merge_records(NewRecords, OldRecords) ->
%% ============================================================================
-spec get_spec_info(module(), abstract_code(), dict()) ->
- {'ok', dict()} | {'error', string()}.
+ {'ok', dict()} | {'error', string()}.
get_spec_info(ModName, AbstractCode, RecordsDict) ->
get_spec_info(AbstractCode, dict:new(), RecordsDict, ModName, "nofile").
diff --git a/lib/dialyzer/vsn.mk b/lib/dialyzer/vsn.mk
index a946959256..e3e3f6d668 100644
--- a/lib/dialyzer/vsn.mk
+++ b/lib/dialyzer/vsn.mk
@@ -1 +1 @@
-DIALYZER_VSN = 2.1.0
+DIALYZER_VSN = 2.2.0
diff --git a/lib/docbuilder/doc/src/inline_tags.xml b/lib/docbuilder/doc/src/inline_tags.xml
index e1d392076a..10afbf143f 100644
--- a/lib/docbuilder/doc/src/inline_tags.xml
+++ b/lib/docbuilder/doc/src/inline_tags.xml
@@ -4,7 +4,7 @@
<chapter>
<header>
<copyright>
- <year>1997</year><year>2009</year>
+ <year>1997</year><year>2010</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
@@ -13,12 +13,12 @@
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>Inline Tags</title>
@@ -157,7 +157,7 @@
<p>The default behaviour can be modified by using the callback
module option to <c>docb_transform:file/1,2</c> and defining a
callback function
- <seealso marker="docb_transform#Module:seealso/1">Module:seealso/1</seealso>.
+ <seealso marker="docb_transform#Module:seealso-1">Module:seealso/1</seealso>.
This possibility is for example used in OTP to resolve cross
references between applications.</p>
</section>
diff --git a/lib/docbuilder/doc/src/notes.xml b/lib/docbuilder/doc/src/notes.xml
index 1131bbaf91..725aae0a68 100644
--- a/lib/docbuilder/doc/src/notes.xml
+++ b/lib/docbuilder/doc/src/notes.xml
@@ -4,7 +4,7 @@
<chapter>
<header>
<copyright>
- <year>2007</year><year>2009</year>
+ <year>2007</year><year>2010</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
@@ -13,12 +13,12 @@
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>DocBuilder Release Notes</title>
@@ -31,6 +31,37 @@
<p>This document describes the changes made to the DocBuilder
application.</p>
+<section><title>Docbuilder 0.9.8.7</title>
+
+ <section><title>Improvements and New Features</title>
+ <list>
+ <item>
+ <p>The documentation is now possible to build in an open
+ source environment after a number of bugs are fixed and
+ some features are added in the documentation build
+ process. </p>
+ <p>- The arity calculation is updated.</p>
+ <p>- The module prefix used in the function names for
+ bif's are removed in the generated links so the links
+ will look like
+ "http://www.erlang.org/doc/man/erlang.html#append_element-2"
+ instead of
+ "http://www.erlang.org/doc/man/erlang.html#erlang:append_element-2".</p>
+ <p>- Enhanced the menu positioning in the html
+ documentation when a new page is loaded.</p>
+ <p>- A number of corrections in the generation of man
+ pages (thanks to Sergei Golovan)</p>
+ <p>- The legal notice is taken from the xml book file so
+ OTP's build process can be used for non OTP
+ applications.</p>
+ <p>
+ Own Id: OTP-8343</p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
<section><title>Docbuilder 0.9.8.6</title>
<section><title>Improvements and New Features</title>
diff --git a/lib/docbuilder/info b/lib/docbuilder/info
index 33ce19fb4b..60daa212c8 100644
--- a/lib/docbuilder/info
+++ b/lib/docbuilder/info
@@ -1,2 +1,2 @@
-group: tools
+group: doc
short: Tool for generating HTML documentation for applications.
diff --git a/lib/docbuilder/vsn.mk b/lib/docbuilder/vsn.mk
index 4c782f7481..2852ebcc8b 100644
--- a/lib/docbuilder/vsn.mk
+++ b/lib/docbuilder/vsn.mk
@@ -1,6 +1,8 @@
-DOCB_VSN = 0.9.8.6
+DOCB_VSN = 0.9.8.7
-TICKETS = OTP-8201
+TICKETS = OTP-8343
+
+TICKETS_0.9.8.6 = OTP-8201
TICKETS_0.9.8.5 = OTP-7851
diff --git a/lib/edoc/Makefile b/lib/edoc/Makefile
index 2b011b55cc..e512e390e3 100644
--- a/lib/edoc/Makefile
+++ b/lib/edoc/Makefile
@@ -86,13 +86,13 @@ SYNTAX_TOOLS_DIR=$(ERL_TOP)/lib/syntax_tools
XMERL_DIR=$(ERL_TOP)/lib/xmerl
INCDIR=$(XMERL_DIR)/include
-docs:
+# The overriding docs target have been removed so the default make rules work properly.
+
+edocs:
erl -noshell -pa $(BINDIR) -pa $(SYNTAX_TOOLS_DIR)/ebin \
-pa $(XMERL_DIR)/ebin -run edoc_run application \
"'$(APPNAME)'" '"."' '$(DOC_OPTS)'
-edocs: docs
-
info:
@echo $(HTML_FILES)
diff --git a/lib/edoc/doc/src/Makefile b/lib/edoc/doc/src/Makefile
index 8d22e1c1da..748691d173 100644
--- a/lib/edoc/doc/src/Makefile
+++ b/lib/edoc/doc/src/Makefile
@@ -103,11 +103,10 @@ html: gifs $(HTML_REF_MAN_FILE)
man: $(MAN3_FILES)
$(XML_REF3_FILES):
- docb_gen -def vsn $(EDOC_VSN) -includes $(INC_DIR) \
- $(SRC_DIR)/$(@:%.xml=%.erl)
+ escript $(DOCGEN)/priv/bin/xml_from_edoc.escript -def vsn $(EDOC_VSN) -i $(ERL_TOP)/lib/edoc/include $(SRC_DIR)/$(@:%.xml=%.erl)
$(XML_CHAPTER_FILES):
- docb_gen -chapter -def vsn $(EDOC_VSN) ../overview.edoc
+ escript $(DOCGEN)/priv/bin/xml_from_edoc.escript -def vsn $(EDOC_VSN) -chapter ../overview.edoc
gifs: $(GIF_FILES:%=$(HTMLDIR)/%)
diff --git a/lib/edoc/doc/src/notes.xml b/lib/edoc/doc/src/notes.xml
index 8fcbc8ec70..74fa2d3ab6 100644
--- a/lib/edoc/doc/src/notes.xml
+++ b/lib/edoc/doc/src/notes.xml
@@ -4,7 +4,7 @@
<chapter>
<header>
<copyright>
- <year>2007</year><year>2009</year>
+ <year>2007</year><year>2010</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
@@ -13,12 +13,12 @@
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>EDoc Release Notes</title>
@@ -31,6 +31,37 @@
<p>This document describes the changes made to the EDoc
application.</p>
+<section><title>Edoc 0.7.6.6</title>
+
+ <section><title>Improvements and New Features</title>
+ <list>
+ <item>
+ <p>The documentation is now possible to build in an open
+ source environment after a number of bugs are fixed and
+ some features are added in the documentation build
+ process. </p>
+ <p>- The arity calculation is updated.</p>
+ <p>- The module prefix used in the function names for
+ bif's are removed in the generated links so the links
+ will look like
+ "http://www.erlang.org/doc/man/erlang.html#append_element-2"
+ instead of
+ "http://www.erlang.org/doc/man/erlang.html#erlang:append_element-2".</p>
+ <p>- Enhanced the menu positioning in the html
+ documentation when a new page is loaded.</p>
+ <p>- A number of corrections in the generation of man
+ pages (thanks to Sergei Golovan)</p>
+ <p>- The legal notice is taken from the xml book file so
+ OTP's build process can be used for non OTP
+ applications.</p>
+ <p>
+ Own Id: OTP-8343</p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
<section><title>Edoc 0.7.6.5</title>
<section><title>Improvements and New Features</title>
diff --git a/lib/edoc/info b/lib/edoc/info
index cb25c1e519..bc52caa78b 100644
--- a/lib/edoc/info
+++ b/lib/edoc/info
@@ -1,3 +1,3 @@
-group: tools
+group: doc Documentation Applications
short: A utility used to generate documentation out of tags in source files.
diff --git a/lib/edoc/src/Makefile b/lib/edoc/src/Makefile
index fd0fbac37d..ca95c4cdad 100644
--- a/lib/edoc/src/Makefile
+++ b/lib/edoc/src/Makefile
@@ -55,6 +55,8 @@ all: $(OBJECTS)
$(OBJECTS): $(HRL_FILES) $(XMERL)/include/xmerl.hrl
+docs:
+
clean:
rm -f $(OBJECTS) edoc_parser.erl
rm -f core *~
diff --git a/lib/edoc/vsn.mk b/lib/edoc/vsn.mk
index 7c7ba58cc9..2de2641b4a 100644
--- a/lib/edoc/vsn.mk
+++ b/lib/edoc/vsn.mk
@@ -1 +1 @@
-EDOC_VSN = 0.7.6.5
+EDOC_VSN = 0.7.6.6
diff --git a/lib/erl_docgen/doc/src/notes.xml b/lib/erl_docgen/doc/src/notes.xml
index caa113df08..ee74e598d9 100644
--- a/lib/erl_docgen/doc/src/notes.xml
+++ b/lib/erl_docgen/doc/src/notes.xml
@@ -29,7 +29,47 @@
<file>notes.xml</file>
</header>
<p>This document describes the changes made to the erl_docgen application.</p>
+ <section><title>Erl_Docgen 0.2</title>
+ <section><title>Improvements and New Features</title>
+ <list>
+ <item>
+ <p>
+ Added an xsl transform from OTP xml documentation to a
+ file (.eix) of erlang terms that can be read by the
+ erldoc application. Erldoc handles the documentation
+ search mechanism at erlang.org. Added generation of eix
+ files to otp_release_targets.mk. Fixed a copyright date
+ error in db_html.xsl .</p>
+ <p>
+ Own Id: OTP-8308</p>
+ </item>
+ <item>
+ <p>The documentation is now possible to build in an open
+ source environment after a number of bugs are fixed and
+ some features are added in the documentation build
+ process. </p>
+ <p>- The arity calculation is updated.</p>
+ <p>- The module prefix used in the function names for
+ bif's are removed in the generated links so the links
+ will look like
+ "http://www.erlang.org/doc/man/erlang.html#append_element-2"
+ instead of
+ "http://www.erlang.org/doc/man/erlang.html#erlang:append_element-2".</p>
+ <p>- Enhanced the menu positioning in the html
+ documentation when a new page is loaded.</p>
+ <p>- A number of corrections in the generation of man
+ pages (thanks to Sergei Golovan)</p>
+ <p>- The legal notice is taken from the xml book file so
+ OTP's build process can be used for non OTP
+ applications.</p>
+ <p>
+ Own Id: OTP-8343</p>
+ </item>
+ </list>
+ </section>
+
+ </section>
<section><title>erl_docgen 0.1</title>
diff --git a/lib/erl_docgen/priv/bin/Makefile b/lib/erl_docgen/priv/bin/Makefile
index bd59675003..95ad36216a 100644
--- a/lib/erl_docgen/priv/bin/Makefile
+++ b/lib/erl_docgen/priv/bin/Makefile
@@ -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%
#
#
@@ -38,7 +38,8 @@ RELSYSDIR = $(RELEASE_PATH)/lib/erl_docgen-$(VSN)
ESCRIPT_FILES= \
- codeline_preprocessing.escript
+ codeline_preprocessing.escript \
+ xml_from_edoc.escript
# ----------------------------------------------------
# FLAGS
diff --git a/lib/erl_docgen/priv/bin/codeline_preprocessing.escript b/lib/erl_docgen/priv/bin/codeline_preprocessing.escript
index 33a678d3a4..592b3985e4 100755
--- a/lib/erl_docgen/priv/bin/codeline_preprocessing.escript
+++ b/lib/erl_docgen/priv/bin/codeline_preprocessing.escript
@@ -1,20 +1,20 @@
#!/usr/bin/env escript
%% -*- erlang -*-
%% %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%
%%----------------------------------------------------------------------
%% File : codeline_preprocessing.escript
@@ -54,13 +54,16 @@ main([InFile, OutFile]) ->
main(_) ->
usage().
+%%======================================================================
+%% Internal functions
+%%======================================================================
%%----------------------------------------------------------------------
-%% Function: main/1
+%% Function: usage/0
%% Description:
%%----------------------------------------------------------------------
usage() ->
- io:format("usage: codeline_preprocessing <infile> <outfile>\n"),
+ io:format("usage: codeline_preprocessing.escript <infile> <outfile>\n"),
halt(1).
diff --git a/lib/erl_docgen/priv/bin/xml_from_edoc.escript b/lib/erl_docgen/priv/bin/xml_from_edoc.escript
new file mode 100755
index 0000000000..ee79e82c3a
--- /dev/null
+++ b/lib/erl_docgen/priv/bin/xml_from_edoc.escript
@@ -0,0 +1,149 @@
+#!/usr/bin/env escript
+%% -*- erlang -*-
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 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%
+%%----------------------------------------------------------------------
+%% File : xml_from_edoc.escript
+%%
+%% Created : 12 Dec 2009 by Lars Thorsen
+%%----------------------------------------------------------------------
+
+
+%%======================================================================
+%% Records
+%%======================================================================
+-record(args, {suffix=".xml",
+ layout=docb_edoc_xml_cb,
+ def=[],
+ includes=[],
+ preprocess=false,
+ sort_functions=true}).
+
+
+%%======================================================================
+%% External functions
+%%======================================================================
+%%----------------------------------------------------------------------
+%% Function: main/1
+%% Description:
+%%----------------------------------------------------------------------
+main(RawOpts) ->
+ case catch parse(RawOpts, erlref, #args{}) of
+ {ok, File, Type, Args} ->
+ case Type of
+ erlref ->
+ module(File, Args);
+ chapter ->
+ users_guide(File, Args)
+ end;
+ {error, Msg} ->
+ io:format("~p\n", [Msg]),
+ usage()
+ end;
+main(_) ->
+ usage().
+
+%%======================================================================
+%% Internal functions
+%%======================================================================
+
+%%----------------------------------------------------------------------
+%% Function: usage/0
+%% Description:
+%%----------------------------------------------------------------------
+usage() ->
+ io:format("usage: xml_from_edoc.escript [<options>] <file> \n"),
+ halt(1).
+
+
+%%----------------------------------------------------------------------
+%% Function: module/2
+%% Description:
+%%----------------------------------------------------------------------
+module(File, Args) ->
+ case filelib:is_regular(File) of
+ true ->
+ Opts = [{def, Args#args.def},
+ {includes, Args#args.includes},
+ {preprocess, Args#args.preprocess},
+ {sort_functions, Args#args.sort_functions},
+
+ {app_default, "OTPROOT"},
+ {file_suffix, Args#args.suffix},
+ {dir, "."},
+ {layout, Args#args.layout}],
+ edoc:file(File, Opts);
+ false ->
+ io:format("~s: not a regular file\n", [File]),
+ usage()
+ end.
+
+
+%%----------------------------------------------------------------------
+%% Function: users_guide/2
+%% Description:
+%%----------------------------------------------------------------------
+users_guide(File, Args) ->
+ case filelib:is_regular(File) of
+ true ->
+ Opts = [{def, Args#args.def},
+ {app_default, "OTPROOT"},
+ {file_suffix, Args#args.suffix},
+ {layout, Args#args.layout}],
+
+ Env = edoc_lib:get_doc_env(Opts),
+
+ {ok, Tags} =
+ edoc_extract:file(File, overview, Env, Opts),
+ Data =
+ edoc_data:overview("Overview", Tags, Env, Opts),
+ F = fun(M) -> M:overview(Data, Opts) end,
+ Text = edoc_lib:run_layout(F, Opts),
+
+ OutFile = "chapter" ++ Args#args.suffix,
+ edoc_lib:write_file(Text, ".", OutFile);
+ false ->
+ io:format("~s: not a regular file\n", [File]),
+ usage()
+ end.
+
+
+
+parse(["-xml" |RawOpts], Type, Args) ->
+ parse(RawOpts, Type, Args); % default, no update of record necessary
+parse(["-sgml" |RawOpts], Type, Args) ->
+ parse(RawOpts, Type, Args#args{suffix=".sgml", layout=docb_edoc_sgml_cb});
+parse(["-chapter" |RawOpts], _Type, Args) ->
+ parse(RawOpts, chapter, Args);
+parse(["-def", Key, Val |RawOpts], Type, Args) ->
+ Args2 = Args#args{def=Args#args.def++[{list_to_atom(Key), Val}]},
+ parse(RawOpts, Type, Args2);
+
+parse(["-i", Dir |RawOpts], Type, Args) ->
+ Args2 = Args#args{includes=Args#args.includes++[Dir]},
+ parse(RawOpts, Type, Args2);
+parse(["-preprocess", Bool |RawOpts], Type, Args) when Bool == "true";
+ Bool == "false" ->
+ parse(RawOpts, Type, Args#args{preprocess=list_to_atom(Bool)});
+parse(["-sort_functions", Bool |RawOpts], Type, Args) when Bool == "true";
+ Bool == "false" ->
+ parse(RawOpts, Type, Args#args{sort_functions=list_to_atom(Bool)});
+parse([File], Type, Args) ->
+ {ok, File, Type, Args};
+parse([Opt | _RawOpts], _Type, _Args) ->
+ {error, io_lib:format("Bad option: ~p", [Opt])}.
+
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..970b85ccb9
--- /dev/null
+++ b/lib/erl_docgen/priv/xsl/db_eix.xsl
@@ -0,0 +1,256 @@
+<?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:variable name="fname1">
+ <xsl:value-of select="substring-before(., '(')"/>
+ </xsl:variable>
+ <xsl:variable name="fname2">
+ <xsl:value-of select="substring-after($fname1, 'erlang:')"/>
+ </xsl:variable>
+ <xsl:choose>
+ <xsl:when test="string-length($fname2) > 0">
+ <xsl:value-of select="$fname2"/>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:value-of select="$fname1"/>
+ </xsl:otherwise>
+ </xsl:choose>
+ </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="str1">
+ <xsl:call-template name="remove-paren-1">
+ <xsl:with-param name="string" select="$string"/>
+ <xsl:with-param name="start">(</xsl:with-param>
+ <xsl:with-param name="end">)</xsl:with-param>
+ </xsl:call-template>
+ </xsl:variable>
+
+ <xsl:variable name="str2">
+ <xsl:call-template name="remove-paren-1">
+ <xsl:with-param name="string" select="$str1"/>
+ <xsl:with-param name="start">{</xsl:with-param>
+ <xsl:with-param name="end">}</xsl:with-param>
+ </xsl:call-template>
+ </xsl:variable>
+
+ <xsl:variable name="str3">
+ <xsl:call-template name="remove-paren-1">
+ <xsl:with-param name="string" select="$str2"/>
+ <xsl:with-param name="start">[</xsl:with-param>
+ <xsl:with-param name="end">]</xsl:with-param>
+ </xsl:call-template>
+ </xsl:variable>
+
+ <xsl:value-of select="$str3"/>
+
+ </xsl:template>
+
+
+ <xsl:template name="remove-paren-1">
+ <xsl:param name="string"/>
+ <xsl:param name="start"/>
+ <xsl:param name="end"/>
+
+ <xsl:variable name="tmp1">
+ <xsl:value-of select="substring-before($string, $start)"/>
+ </xsl:variable>
+
+ <xsl:choose>
+ <xsl:when test="string-length($tmp1) > 0 or starts-with($string, $start)">
+ <xsl:variable name="tmp2">
+ <xsl:value-of select="substring-after($string, $end)"/>
+ </xsl:variable>
+ <xsl:variable name="retstring">
+ <xsl:call-template name="remove-paren">
+ <xsl:with-param name="string" select="$tmp2"/>
+ </xsl:call-template>
+ </xsl:variable>
+ <xsl:value-of select="concat(concat($tmp1, 'x'), $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..5614b02bb7 100644
--- a/lib/erl_docgen/priv/xsl/db_html.xsl
+++ b/lib/erl_docgen/priv/xsl/db_html.xsl
@@ -2,20 +2,20 @@
<!--
#
# %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%
-->
@@ -40,6 +40,46 @@
<div id="container">
<script id="js" type="text/javascript" language="JavaScript" src="{$topdocdir}/js/flipmenu/flipmenu.js"/>
<script id="js2" type="text/javascript" src="{$topdocdir}/js/erlresolvelinks.js"></script>
+ <script language="JavaScript" type="text/javascript">
+ <xsl:text disable-output-escaping="yes"><![CDATA[
+ <!--
+ function getWinHeight() {
+ var myHeight = 0;
+ if( typeof( window.innerHeight ) == 'number' ) {
+ //Non-IE
+ myHeight = window.innerHeight;
+ } else if( document.documentElement && ( document.documentElement.clientWidth ||
+ document.documentElement.clientHeight ) ) {
+ //IE 6+ in 'standards compliant mode'
+ myHeight = document.documentElement.clientHeight;
+ } else if( document.body && ( document.body.clientWidth || document.body.clientHeight ) ) {
+ //IE 4 compatible
+ myHeight = document.body.clientHeight;
+ }
+ return myHeight;
+ }
+
+ function setscrollpos() {
+ var objf=document.getElementById('loadscrollpos');
+ document.getElementById("leftnav").scrollTop = objf.offsetTop - getWinHeight()/2;
+ }
+
+ function addEvent(obj, evType, fn){
+ if (obj.addEventListener){
+ obj.addEventListener(evType, fn, true);
+ return true;
+ } else if (obj.attachEvent){
+ var r = obj.attachEvent("on"+evType, fn);
+ return r;
+ } else {
+ return false;
+ }
+ }
+
+ addEvent(window, 'load', setscrollpos);
+
+ //-->]]></xsl:text>
+ </script>
<!-- Generate menu -->
<xsl:call-template name="menu">
<xsl:with-param name="chapnum" select="$chapnum"/>
@@ -61,7 +101,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>
@@ -543,7 +583,13 @@
<xsl:otherwise>false</xsl:otherwise>
</xsl:choose>
</xsl:variable>
- <li title="{header/title}" expanded="{$expanded}">
+ <xsl:variable name="loadscrollpos">
+ <xsl:choose>
+ <xsl:when test="$chapnum = $curchapnum">loadscrollpos</xsl:when>
+ <xsl:otherwise>no</xsl:otherwise>
+ </xsl:choose>
+ </xsl:variable>
+ <li id="{$loadscrollpos}" title="{header/title}" expanded="{$expanded}">
<xsl:value-of select="header/title"/>
<ul>
<li>
@@ -656,7 +702,7 @@
<!-- Menu.ref -->
<xsl:template name="menu.ref">
- <xsl:param name="$curModule"/>
+ <xsl:param name="curModule"/>
<div id="leftnav">
<div class="innertube">
@@ -731,12 +777,19 @@
</xsl:choose>
</xsl:variable>
+ <xsl:variable name="loadscrollpos">
+ <xsl:choose>
+ <xsl:when test="$curModule = $cval">loadscrollpos</xsl:when>
+ <xsl:otherwise>no</xsl:otherwise>
+ </xsl:choose>
+ </xsl:variable>
+
<xsl:variable name="link_cval"><xsl:value-of select="translate($cval, '&#173;', '')"/></xsl:variable>
<xsl:choose>
<xsl:when test="$genFuncMenu = 'true'">
- <li title="{$cval} " expanded="{$expanded}">
+ <li id="{$loadscrollpos}" title="{$cval} " expanded="{$expanded}">
<xsl:value-of select="$cval"/>
<ul>
<li>
@@ -788,58 +841,73 @@
<xsl:when test="string-length($fname) > 0">
<li title="{$fname}">
<a href="{$basename}.html#{$fname}">
- <xsl:value-of select="$fname"/>()
- </a>
- </li>
- </xsl:when>
- <xsl:otherwise>
- <li title="{name/nametext}">
- <a href="{$basename}.html#{name/nametext}">
- <xsl:value-of select="nametext"/>()
- </a>
- </li>
- </xsl:otherwise>
- </xsl:choose>
- </xsl:when>
-
- <xsl:when test="ancestor::erlref">
-
- <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:value-of select="$fname"/>()
+ </a>
+ </li>
</xsl:when>
<xsl:otherwise>
- <xsl:call-template name="remove-paren">
- <xsl:with-param name="string" select="substring-after(., '(')"/>
- </xsl:call-template>
+ <li title="{name/nametext}">
+ <a href="{$basename}.html#{name/nametext}">
+ <xsl:value-of select="nametext"/>()
+ </a>
+ </li>
</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:value-of select="substring-before(., '(')"/>
- </xsl:variable>
- <li title="{$fname}-{$arity}">
- <a href="{$basename}.html#{$fname}-{$arity}">
- <xsl:value-of select="$fname"/>/<xsl:value-of select="$arity"/>
- </a>
- </li>
- </xsl:when>
- </xsl:choose>
-
+ </xsl:choose>
+ </xsl:when>
+
+ <xsl:when test="ancestor::erlref">
+
+ <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:variable name="fname1">
+ <xsl:value-of select="substring-before(., '(')"/>
+ </xsl:variable>
+ <xsl:variable name="fname2">
+ <xsl:value-of select="substring-after($fname1, 'erlang:')"/>
+ </xsl:variable>
+ <xsl:choose>
+ <xsl:when test="string-length($fname2) > 0">
+ <xsl:value-of select="$fname2"/>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:value-of select="$fname1"/>
+ </xsl:otherwise>
+ </xsl:choose>
+ </xsl:variable>
+
+ <li title="{$fname}-{$arity}">
+ <a href="{$basename}.html#{$fname}-{$arity}">
+ <xsl:value-of select="$fname"/>/<xsl:value-of select="$arity"/>
+ </a>
+ </li>
+ </xsl:when>
+ </xsl:choose>
+
</xsl:for-each>
</xsl:template>
@@ -1065,6 +1133,7 @@
<!-- Funcs -->
<xsl:template match="funcs">
+ <xsl:param name="partnum"/>
<h3>
<xsl:text>EXPORTS</xsl:text>
@@ -1121,11 +1190,26 @@
<a name="{substring-before(nametext, '(')}"><span class="bold_code"><xsl:value-of select="ret"/><xsl:text> </xsl:text><xsl:value-of select="nametext"/></span></a><br/>
</xsl:when>
<xsl:when test="ancestor::erlref">
- <a name="{substring-before(., '(')}-{$arity}"><span class="bold_code"><xsl:value-of select="."/></span></a><br/>
+ <xsl:variable name="fname">
+ <xsl:variable name="fname1">
+ <xsl:value-of select="substring-before(., '(')"/>
+ </xsl:variable>
+ <xsl:variable name="fname2">
+ <xsl:value-of select="substring-after($fname1, 'erlang:')"/>
+ </xsl:variable>
+ <xsl:choose>
+ <xsl:when test="string-length($fname2) > 0">
+ <xsl:value-of select="$fname2"/>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:value-of select="$fname1"/>
+ </xsl:otherwise>
+ </xsl:choose>
+ </xsl:variable>
+ <a name="{$fname}-{$arity}"><span class="bold_code"><xsl:value-of select="."/></span></a><br/>
</xsl:when>
</xsl:choose>
-
</xsl:template>
@@ -1167,6 +1251,7 @@
<!-- Desc -->
<xsl:template match="desc">
+ <xsl:param name="partnum"/>
<div class="REFBODY">
<p>
<xsl:apply-templates>
@@ -1458,29 +1543,65 @@
</xsl:choose>
</xsl:template>
+
<xsl:template name="remove-paren">
<xsl:param name="string"/>
+
+ <xsl:variable name="str1">
+ <xsl:call-template name="remove-paren-1">
+ <xsl:with-param name="string" select="$string"/>
+ <xsl:with-param name="start">(</xsl:with-param>
+ <xsl:with-param name="end">)</xsl:with-param>
+ </xsl:call-template>
+ </xsl:variable>
+
+ <xsl:variable name="str2">
+ <xsl:call-template name="remove-paren-1">
+ <xsl:with-param name="string" select="$str1"/>
+ <xsl:with-param name="start">{</xsl:with-param>
+ <xsl:with-param name="end">}</xsl:with-param>
+ </xsl:call-template>
+ </xsl:variable>
+
+ <xsl:variable name="str3">
+ <xsl:call-template name="remove-paren-1">
+ <xsl:with-param name="string" select="$str2"/>
+ <xsl:with-param name="start">[</xsl:with-param>
+ <xsl:with-param name="end">]</xsl:with-param>
+ </xsl:call-template>
+ </xsl:variable>
+
+ <xsl:value-of select="$str3"/>
+
+ </xsl:template>
+
+
+ <xsl:template name="remove-paren-1">
+ <xsl:param name="string"/>
+ <xsl:param name="start"/>
+ <xsl:param name="end"/>
- <xsl:variable name="bstring">
- <xsl:value-of select="substring-before($string, '(')"/>
+ <xsl:variable name="tmp1">
+ <xsl:value-of select="substring-before($string, $start)"/>
</xsl:variable>
<xsl:choose>
- <xsl:when test="string-length($bstring) > 0">
- <xsl:variable name="astring">
- <xsl:value-of select="substring-after($string, ')')"/>
+ <xsl:when test="string-length($tmp1) > 0 or starts-with($string, $start)">
+ <xsl:variable name="tmp2">
+ <xsl:value-of select="substring-after($string, $end)"/>
</xsl:variable>
<xsl:variable name="retstring">
<xsl:call-template name="remove-paren">
- <xsl:with-param name="string" select="$astring"/>
+ <xsl:with-param name="string" select="$tmp2"/>
</xsl:call-template>
</xsl:variable>
- <xsl:value-of select="concat($bstring, $retstring)"/>
+ <xsl:value-of select="concat(concat($tmp1, 'x'), $retstring)"/>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="$string"/>
</xsl:otherwise>
</xsl:choose>
+
</xsl:template>
</xsl:stylesheet>
diff --git a/lib/erl_docgen/priv/xsl/db_man.xsl b/lib/erl_docgen/priv/xsl/db_man.xsl
index c759a77496..a2b1e755e2 100644
--- a/lib/erl_docgen/priv/xsl/db_man.xsl
+++ b/lib/erl_docgen/priv/xsl/db_man.xsl
@@ -2,20 +2,20 @@
<!--
#
# %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%
-->
@@ -37,14 +37,12 @@
<!-- *ref/Section -->
<xsl:template match="erlref/section|comref/section|cref/section|fileref/section|appref/section">
- <xsl:text>&#10;.RE&#10;</xsl:text>
<xsl:text>&#10;.SH "</xsl:text><xsl:value-of select="translate(title, 'abcdefghijklmnopqrstuvwxyz','ABCDEFGHIJKLMNOPQRSTUVWXYZ')"/><xsl:text>"&#10;</xsl:text>
<xsl:apply-templates/>
</xsl:template>
<!-- *ref/Subsection -->
- <xsl:template match="erlref/section/section|comref/section/section|cref/section/section|fileref/section/section|appref/section/section">
- <xsl:text>&#10;.RE&#10;</xsl:text>
+ <xsl:template match="section/section">
<xsl:text>&#10;.SS "</xsl:text><xsl:value-of select="title"/><xsl:text>"&#10;</xsl:text>
<xsl:apply-templates/>
</xsl:template>
@@ -53,84 +51,76 @@
<!-- Lists -->
<xsl:template match="list">
- <xsl:text>&#10;.RS 2&#10;</xsl:text>
+ <xsl:text>&#10;.RS 2</xsl:text>
<xsl:apply-templates/>
- <xsl:text>&#10;.RE&#10;</xsl:text>
+ <xsl:text>&#10;.RE</xsl:text>
</xsl:template>
<xsl:template match="list/item">
<xsl:text>&#10;.TP 2&#10;</xsl:text>
<xsl:text>*&#10;</xsl:text>
- <xsl:variable name="content">
- <xsl:apply-templates/>
- </xsl:variable>
- <xsl:value-of select="normalize-space($content)"/>
- <xsl:text>&#10;.br&#10;</xsl:text>
- <xsl:text>&#10;.br&#10;</xsl:text>
+ <xsl:apply-templates/>
+ <xsl:text>&#10;.LP&#10;</xsl:text>
</xsl:template>
<xsl:template match="taglist">
- <xsl:text>&#10;.RS 2&#10;</xsl:text>
- <xsl:apply-templates/>
- <xsl:text>&#10;.RE&#10;</xsl:text>
+ <xsl:text>&#10;.RS 2</xsl:text>
+ <xsl:apply-templates select="tag|item"/>
+ <xsl:text>&#10;.RE</xsl:text>
</xsl:template>
<xsl:template match="taglist/tag">
- <xsl:text>&#10;.TP 4&#10;</xsl:text>
+ <xsl:text>&#10;.TP 2&#10;</xsl:text>
<xsl:text>.B&#10;</xsl:text>
- <xsl:apply-templates/>
+ <xsl:apply-templates/><xsl:text>:&#10;</xsl:text>
+ </xsl:template>
+
+ <xsl:template match="taglist/item">
+ <xsl:apply-templates/>
</xsl:template>
<xsl:template match="item/p">
<xsl:variable name="content">
<xsl:apply-templates/>
</xsl:variable>
- <xsl:value-of select="normalize-space($content)"/>
- <xsl:text>&#10;.br&#10;</xsl:text>
- <xsl:text>&#10;.br&#10;</xsl:text>
- </xsl:template>
-
-
- <xsl:template match="taglist/item">
- <xsl:text>&#10;</xsl:text>
- <xsl:apply-templates/>
+ <xsl:choose>
+ <xsl:when test="position() = 1">
+ <xsl:value-of select="$content"/>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:text>&#10;.RS 2</xsl:text>
+ <xsl:text>&#10;.LP&#10;&#10;.LP&#10;</xsl:text>
+ <xsl:value-of select="$content"/>
+ <xsl:text>&#10;.RE</xsl:text>
+ </xsl:otherwise>
+ </xsl:choose>
</xsl:template>
<!-- Note -->
<xsl:template match="note">
- <xsl:text>&#10;.TP 4&#10;.B&#10;Note:&#10;</xsl:text>
+ <xsl:text>&#10;.SS Note:</xsl:text>
<xsl:apply-templates/>
+ <xsl:text>&#10;</xsl:text>
</xsl:template>
<!-- Warning -->
<xsl:template match="warning">
- <xsl:text>&#10;.TP 4&#10;.B&#10;Warning:&#10;</xsl:text>
+ <xsl:text>&#10;.SS Warning:</xsl:text>
<xsl:apply-templates/>
+ <xsl:text>&#10;</xsl:text>
</xsl:template>
- <xsl:template match="warning/p|note/p">
- <xsl:variable name="content">
- <xsl:apply-templates/>
- </xsl:variable>
- <xsl:value-of select="normalize-space($content)"/>
- <xsl:text>&#10;.LP&#10;</xsl:text>
- </xsl:template>
-
-
<!-- Paragraph -->
<xsl:template match="p">
<xsl:text>&#10;.LP&#10;</xsl:text>
- <xsl:variable name="content">
- <xsl:apply-templates/>
- </xsl:variable>
- <xsl:value-of select="normalize-space($content)"/>
+ <xsl:apply-templates/>
</xsl:template>
<!-- Inline elements -->
<xsl:template match="b">
- <xsl:text> \fB</xsl:text>
+ <xsl:text>\fB</xsl:text>
<xsl:apply-templates/>
- <xsl:text>\fR\&amp;</xsl:text>
+ <xsl:text>\fR\&amp; </xsl:text>
</xsl:template>
<xsl:template match="br">
@@ -138,19 +128,20 @@
</xsl:template>
<xsl:template match="c">
- <xsl:text> \fI</xsl:text><xsl:value-of select="text()"/><xsl:text>\fR\&amp;</xsl:text>
+ <xsl:text>\fI</xsl:text><xsl:apply-templates/><xsl:text>\fR\&amp;</xsl:text>
</xsl:template>
<xsl:template match="em">
- <xsl:text> \fI</xsl:text><xsl:value-of select="text()"/><xsl:text>\fR\&amp;</xsl:text>
+ <xsl:text>\fI</xsl:text> <xsl:apply-templates/><xsl:text>\fR\&amp;</xsl:text>
</xsl:template>
<xsl:template match="seealso">
- <xsl:text> \fB</xsl:text><xsl:apply-templates/><xsl:text>\fR\&amp;</xsl:text>
+ <xsl:text>\fB</xsl:text><xsl:apply-templates/><xsl:text>\fR\&amp;</xsl:text>
</xsl:template>
<!-- Code -->
<xsl:template match="code">
+ <xsl:text>&#10;.LP&#10;</xsl:text>
<xsl:text>&#10;.nf&#10;</xsl:text>
<xsl:apply-templates/>
<xsl:text>&#10;.fi&#10;</xsl:text>
@@ -158,6 +149,7 @@
<!-- Pre -->
<xsl:template match="pre">
+ <xsl:text>&#10;.LP&#10;</xsl:text>
<xsl:text>&#10;.nf&#10;</xsl:text>
<xsl:apply-templates/>
<xsl:text>&#10;.fi&#10;</xsl:text>
@@ -168,16 +160,7 @@
<xsl:template match="table">
</xsl:template>
- <!--xsl:template match="row">
- <xsl:apply-templates/>
- </xsl:template>
-
- <xsl:template match="cell">
- <xsl:apply-templates/>
- </xsl:template -->
-
-
- <!-- Image -->
+ <!-- Image -->
<xsl:template match="image">
</xsl:template>
@@ -191,42 +174,78 @@
<!-- Erlref -->
<xsl:template match="/erlref">
- <xsl:text>.TH </xsl:text><xsl:value-of select="module"/><xsl:text> 3 "</xsl:text><xsl:value-of select="$appname"/><xsl:text> </xsl:text><xsl:value-of select="$appver"/><xsl:text>" "Ericsson AB" "Erlang Module Definition"&#10;</xsl:text>
- <xsl:text>.SH MODULE&#10;</xsl:text>
- <xsl:value-of select="module"/><xsl:text> \- </xsl:text><xsl:value-of select="modulesummary"/><xsl:text>&#10;</xsl:text>
- <xsl:apply-templates/>
+ <xsl:variable name="companyname">
+ <xsl:choose>
+ <!-- Workaround until all of OTP's .../holder contents are correct. -->
+ <xsl:when test="starts-with(header/copyright/holder,'Ericsson AB')"><xsl:text>Ericsson AB</xsl:text></xsl:when>
+ <xsl:otherwise><xsl:value-of select="header/copyright/holder"/></xsl:otherwise>
+ </xsl:choose>
+ </xsl:variable>
+
+ <xsl:text>.TH </xsl:text><xsl:value-of select="module"/><xsl:text> 3 "</xsl:text><xsl:value-of select="$appname"/><xsl:text> </xsl:text><xsl:value-of select="$appver"/><xsl:text>" "</xsl:text><xsl:value-of select="$companyname"/><xsl:text>" "Erlang Module Definition"&#10;</xsl:text>
+ <xsl:text>.SH NAME&#10;</xsl:text>
+ <xsl:value-of select="module"/><xsl:text> \- </xsl:text><xsl:value-of select="modulesummary"/><xsl:text>&#10;</xsl:text>
+ <xsl:apply-templates/>
</xsl:template>
<!-- Comref -->
<xsl:template match="/comref">
- <xsl:text>.TH </xsl:text><xsl:value-of select="com"/><xsl:text> 1 "</xsl:text><xsl:value-of select="$appname"/><xsl:text> </xsl:text><xsl:value-of select="$appver"/><xsl:text>" "Ericsson AB" "User Commands"&#10;</xsl:text>
- <xsl:text>.SH NAME&#10;</xsl:text>
- <xsl:value-of select="com"/><xsl:text> \- </xsl:text><xsl:value-of select="comsummary"/><xsl:text>&#10;</xsl:text>
- <xsl:apply-templates/>
+ <xsl:variable name="companyname">
+ <xsl:choose>
+ <!-- Workaround until all of OTP's .../holder contents are correct. -->
+ <xsl:when test="starts-with(header/copyright/holder,'Ericsson AB')"><xsl:text>Ericsson AB</xsl:text></xsl:when>
+ <xsl:otherwise><xsl:value-of select="header/copyright/holder"/></xsl:otherwise>
+ </xsl:choose>
+ </xsl:variable>
+ <xsl:text>.TH </xsl:text><xsl:value-of select="com"/><xsl:text> 1 "</xsl:text><xsl:value-of select="$appname"/><xsl:text> </xsl:text><xsl:value-of select="$appver"/><xsl:text>" "</xsl:text><xsl:value-of select="$companyname"/><xsl:text>" "User Commands"&#10;</xsl:text>
+ <xsl:text>.SH NAME&#10;</xsl:text>
+ <xsl:value-of select="com"/><xsl:text> \- </xsl:text><xsl:value-of select="comsummary"/><xsl:text>&#10;</xsl:text>
+ <xsl:apply-templates/>
</xsl:template>
<!-- Cref -->
<xsl:template match="/cref">
- <xsl:text>.TH </xsl:text><xsl:value-of select="lib"/><xsl:text> 3 "</xsl:text><xsl:value-of select="$appname"/><xsl:text> </xsl:text><xsl:value-of select="$appver"/><xsl:text>" "Ericsson AB" "C Library Functions"&#10;</xsl:text>
- <xsl:text>.SH NAME&#10;</xsl:text>
- <xsl:value-of select="lib"/><xsl:text> \- </xsl:text><xsl:value-of select="libsummary"/><xsl:text>&#10;</xsl:text>
- <xsl:apply-templates/>
+ <xsl:variable name="companyname">
+ <xsl:choose>
+ <!-- Workaround until all of OTP's .../holder contents are correct. -->
+ <xsl:when test="starts-with(header/copyright/holder,'Ericsson AB')"><xsl:text>Ericsson AB</xsl:text></xsl:when>
+ <xsl:otherwise><xsl:value-of select="header/copyright/holder"/></xsl:otherwise>
+ </xsl:choose>
+ </xsl:variable>
+ <xsl:text>.TH </xsl:text><xsl:value-of select="lib"/><xsl:text> 3 "</xsl:text><xsl:value-of select="$appname"/><xsl:text> </xsl:text><xsl:value-of select="$appver"/><xsl:text>" "</xsl:text><xsl:value-of select="$companyname"/><xsl:text>" "C Library Functions"&#10;</xsl:text>
+ <xsl:text>.SH NAME&#10;</xsl:text>
+ <xsl:value-of select="lib"/><xsl:text> \- </xsl:text><xsl:value-of select="libsummary"/><xsl:text>&#10;</xsl:text>
+ <xsl:apply-templates/>
</xsl:template>
<!-- Fileref -->
<xsl:template match="/fileref">
- <xsl:text>.TH </xsl:text><xsl:value-of select="file"/><xsl:text> 4 "</xsl:text><xsl:value-of select="$appname"/><xsl:text> </xsl:text><xsl:value-of select="$appver"/><xsl:text>" "Ericsson AB" "Files"&#10;</xsl:text>
- <xsl:text>.SH NAME&#10;</xsl:text>
- <xsl:value-of select="file"/><xsl:text> \- </xsl:text><xsl:value-of select="filesummary"/><xsl:text>&#10;</xsl:text>
- <xsl:apply-templates/>
+ <xsl:variable name="companyname">
+ <xsl:choose>
+ <!-- Workaround until all of OTP's .../holder contents are correct. -->
+ <xsl:when test="starts-with(header/copyright/holder,'Ericsson AB')"><xsl:text>Ericsson AB</xsl:text></xsl:when>
+ <xsl:otherwise><xsl:value-of select="header/copyright/holder"/></xsl:otherwise>
+ </xsl:choose>
+ </xsl:variable>
+ <xsl:text>.TH </xsl:text><xsl:value-of select="file"/><xsl:text> 5 "</xsl:text><xsl:value-of select="$appname"/><xsl:text> </xsl:text><xsl:value-of select="$appver"/><xsl:text>" "</xsl:text><xsl:value-of select="$companyname"/><xsl:text>" "Files"&#10;</xsl:text>
+ <xsl:text>.SH NAME&#10;</xsl:text>
+ <xsl:value-of select="file"/><xsl:text> \- </xsl:text><xsl:value-of select="filesummary"/><xsl:text>&#10;</xsl:text>
+ <xsl:apply-templates/>
</xsl:template>
<!-- Appref -->
<xsl:template match="/appref">
- <xsl:text>.TH </xsl:text><xsl:value-of select="app"/><xsl:text> 6 "</xsl:text><xsl:value-of select="$appname"/><xsl:text> </xsl:text><xsl:value-of select="$appver"/><xsl:text>" "Ericsson AB" "Erlang Application Definition"&#10;</xsl:text>
- <xsl:text>.SH NAME&#10;</xsl:text>
- <xsl:value-of select="file"/><xsl:text> \- </xsl:text><xsl:value-of select="filesummary"/><xsl:text>&#10;</xsl:text>
- <xsl:apply-templates/>
+ <xsl:variable name="companyname">
+ <xsl:choose>
+ <!-- Workaround until all of OTP's .../holder contents are correct. -->
+ <xsl:when test="starts-with(header/copyright/holder,'Ericsson AB')"><xsl:text>Ericsson AB</xsl:text></xsl:when>
+ <xsl:otherwise><xsl:value-of select="header/copyright/holder"/></xsl:otherwise>
+ </xsl:choose>
+ </xsl:variable>
+ <xsl:text>.TH </xsl:text><xsl:value-of select="app"/><xsl:text> 7 "</xsl:text><xsl:value-of select="$appname"/><xsl:text> </xsl:text><xsl:value-of select="$appver"/><xsl:text>" "</xsl:text><xsl:value-of select="$companyname"/><xsl:text>" "Erlang Application Definition"&#10;</xsl:text>
+ <xsl:text>.SH NAME&#10;</xsl:text>
+ <xsl:value-of select="app"/><xsl:text> \- </xsl:text><xsl:value-of select="appsummary"/><xsl:text>&#10;</xsl:text>
+ <xsl:apply-templates/>
</xsl:template>
<!-- Module|Com|Lib|File|App-->
@@ -297,12 +316,71 @@
<!-- This tag is skipped for now. -->
</xsl:template>
- <!-- xsl:template match="p/text()">
- <xsl:value-of select="normalize-space()"/>
- </xsl:template-->
+
+ <!-- Authors -->
+ <xsl:template match="authors">
+ <xsl:text>&#10;.SH AUTHORS</xsl:text>
+ <xsl:apply-templates/>
+ </xsl:template>
- <xsl:template match="d/text()">
- <xsl:value-of select="normalize-space()"/>
+ <!-- Aname -->
+ <xsl:template match="authors/aname">
+ <xsl:text>&#10;.LP&#10;</xsl:text>
+ <xsl:apply-templates/>
+ </xsl:template>
+
+ <!-- Email -->
+ <xsl:template match="authors/email">
+ <xsl:text>&#10;.I&#10;&lt;</xsl:text>
+ <xsl:apply-templates/>
+ <xsl:text>&gt;</xsl:text>
+ </xsl:template>
+
+ <!-- Replace ' by \&' ans . by \&. -->
+ <xsl:template match="text()">
+ <xsl:variable name="startstring">
+ <xsl:value-of select="normalize-space()"/><xsl:text> </xsl:text>
+ </xsl:variable>
+ <xsl:variable name="rep1">
+ <xsl:call-template name="replace-string">
+ <xsl:with-param name="text" select="$startstring" />
+ <xsl:with-param name="replace" select="&quot;\&quot;" />
+ <xsl:with-param name="with" select="&quot;\\&quot;" />
+ </xsl:call-template>
+ </xsl:variable>
+ <xsl:variable name="rep2">
+ <xsl:call-template name="replace-string">
+ <xsl:with-param name="text" select="$rep1" />
+ <xsl:with-param name="replace" select="&quot;&apos;&quot;" />
+ <xsl:with-param name="with" select="&quot;\&amp;&apos;&quot;" />
+ </xsl:call-template>
+ </xsl:variable>
+ <xsl:call-template name="replace-string">
+ <xsl:with-param name="text" select="$rep2" />
+ <xsl:with-param name="replace" select="&quot;.&quot;" />
+ <xsl:with-param name="with" select="&quot;\&amp;.&quot;" />
+ </xsl:call-template>
+ </xsl:template>
+
+ <!-- Template replace-string is borrowed at http://www.dpawson.co.uk/xsl/sect2/replace.html -->
+ <xsl:template name="replace-string">
+ <xsl:param name="text"/>
+ <xsl:param name="replace"/>
+ <xsl:param name="with"/>
+ <xsl:choose>
+ <xsl:when test="contains($text,$replace)">
+ <xsl:value-of select="substring-before($text,$replace)"/>
+ <xsl:value-of select="$with"/>
+ <xsl:call-template name="replace-string">
+ <xsl:with-param name="text" select="substring-after($text,$replace)"/>
+ <xsl:with-param name="replace" select="$replace"/>
+ <xsl:with-param name="with" select="$with"/>
+ </xsl:call-template>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:value-of select="$text"/>
+ </xsl:otherwise>
+ </xsl:choose>
</xsl:template>
</xsl:stylesheet>
diff --git a/lib/erl_docgen/priv/xsl/db_pdf.xsl b/lib/erl_docgen/priv/xsl/db_pdf.xsl
index bef86277ea..e12b4d219a 100644
--- a/lib/erl_docgen/priv/xsl/db_pdf.xsl
+++ b/lib/erl_docgen/priv/xsl/db_pdf.xsl
@@ -2,20 +2,20 @@
<!--
#
# %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%
-->
@@ -229,7 +229,9 @@
<xsl:value-of select="$companyname"/>
</fo:block>
<fo:block xsl:use-attribute-sets="cover.inner.copyrightnotice">
- The contents of this file are subject to the Erlang Public License,
+ <xsl:value-of select="/book/header/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
@@ -241,6 +243,7 @@
under the License.
The Initial Developer of the Original Code is
+-->
<xsl:value-of select="$companyname"/>.
</fo:block>
<fo:block xsl:use-attribute-sets="cover.inner.date">
@@ -382,7 +385,9 @@
<xsl:choose>
<xsl:when test="ancestor::cref">
<fo:bookmark internal-destination="{generate-id(nametext)}" starting-state="hide">
- <xsl:variable name="fname"><xsl:value-of select="substring-before(nametext, '(')"/></xsl:variable>
+ <xsl:variable name="fname">
+ <xsl:value-of select="substring-before(nametext, '(')"/>
+ </xsl:variable>
<fo:bookmark-title>
<xsl:choose>
<xsl:when test="string-length($fname) > 0">
@@ -422,8 +427,26 @@
<xsl:with-param name="no-of-pars" select="0"/>
</xsl:call-template>
</xsl:variable>
+
+ <xsl:variable name="fname">
+ <xsl:variable name="fname1">
+ <xsl:value-of select="substring-before(., '(')"/>
+ </xsl:variable>
+ <xsl:variable name="fname2">
+ <xsl:value-of select="substring-after($fname1, 'erlang:')"/>
+ </xsl:variable>
+ <xsl:choose>
+ <xsl:when test="string-length($fname2) > 0">
+ <xsl:value-of select="$fname2"/>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:value-of select="$fname1"/>
+ </xsl:otherwise>
+ </xsl:choose>
+ </xsl:variable>
+
<fo:bookmark-title>
- <xsl:value-of select="substring-before(., '(')"/>/<xsl:value-of select="$arity"/>
+ <xsl:value-of select="$fname"/>/<xsl:value-of select="$arity"/>
</fo:bookmark-title>
</fo:bookmark>
</xsl:when>
@@ -668,12 +691,12 @@
<xsl:number level="any" from="part" count="code"/>
</xsl:variable>
- <fo:block xsl:use-attribute-sets="code" margin-left="1.5em">
+ <fo:block xsl:use-attribute-sets="code">
<xsl:apply-templates select="text()"/>
</fo:block>
<xsl:if test="@caption">
- <fo:block xsl:use-attribute-sets="caption" margin-left="1.5em">
+ <fo:block xsl:use-attribute-sets="caption">
Code listing <xsl:value-of select="$partnum"/>.<xsl:value-of select="$codenum"/>:&#160;
<xsl:value-of select="@caption"/>
</fo:block>
@@ -687,12 +710,12 @@
<xsl:number level="any" from="part" count="code"/>
</xsl:variable>
- <fo:block xsl:use-attribute-sets="code" margin-left="1.5em">
+ <fo:block xsl:use-attribute-sets="code">
<xsl:apply-templates/>
</fo:block>
<xsl:if test="@caption">
- <fo:block xsl:use-attribute-sets="caption" margin-left="1.5em">
+ <fo:block xsl:use-attribute-sets="caption">
Code listing <xsl:value-of select="$partnum"/>.<xsl:value-of select="$codenum"/>:&#160;
<xsl:value-of select="@caption"/>
</fo:block>
@@ -862,7 +885,7 @@
<!-- Funcs -->
<xsl:template match="funcs">
-
+ <xsl:param name="partnum"/>
<fo:block xsl:use-attribute-sets="h3">
<xsl:text>Exports</xsl:text>
</fo:block>
@@ -958,6 +981,7 @@
<!-- Desc -->
<xsl:template match="desc">
+ <xsl:param name="partnum"/>
<xsl:apply-templates>
<xsl:with-param name="partnum" select="$partnum"/>
@@ -1103,27 +1127,62 @@
<xsl:template name="remove-paren">
<xsl:param name="string"/>
+
+ <xsl:variable name="str1">
+ <xsl:call-template name="remove-paren-1">
+ <xsl:with-param name="string" select="$string"/>
+ <xsl:with-param name="start">(</xsl:with-param>
+ <xsl:with-param name="end">)</xsl:with-param>
+ </xsl:call-template>
+ </xsl:variable>
+
+ <xsl:variable name="str2">
+ <xsl:call-template name="remove-paren-1">
+ <xsl:with-param name="string" select="$str1"/>
+ <xsl:with-param name="start">{</xsl:with-param>
+ <xsl:with-param name="end">}</xsl:with-param>
+ </xsl:call-template>
+ </xsl:variable>
+
+ <xsl:variable name="str3">
+ <xsl:call-template name="remove-paren-1">
+ <xsl:with-param name="string" select="$str2"/>
+ <xsl:with-param name="start">[</xsl:with-param>
+ <xsl:with-param name="end">]</xsl:with-param>
+ </xsl:call-template>
+ </xsl:variable>
+
+ <xsl:value-of select="$str3"/>
+
+ </xsl:template>
+
+
+ <xsl:template name="remove-paren-1">
+ <xsl:param name="string"/>
+ <xsl:param name="start"/>
+ <xsl:param name="end"/>
- <xsl:variable name="bstring">
- <xsl:value-of select="substring-before($string, '(')"/>
+ <xsl:variable name="tmp1">
+ <xsl:value-of select="substring-before($string, $start)"/>
</xsl:variable>
<xsl:choose>
- <xsl:when test="string-length($bstring) > 0">
- <xsl:variable name="astring">
- <xsl:value-of select="substring-after($string, ')')"/>
+ <xsl:when test="string-length($tmp1) > 0 or starts-with($string, $start)">
+ <xsl:variable name="tmp2">
+ <xsl:value-of select="substring-after($string, $end)"/>
</xsl:variable>
<xsl:variable name="retstring">
<xsl:call-template name="remove-paren">
- <xsl:with-param name="string" select="$astring"/>
+ <xsl:with-param name="string" select="$tmp2"/>
</xsl:call-template>
</xsl:variable>
- <xsl:value-of select="concat($bstring, $retstring)"/>
+ <xsl:value-of select="concat(concat($tmp1, 'x'), $retstring)"/>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="$string"/>
</xsl:otherwise>
</xsl:choose>
+
</xsl:template>
</xsl:stylesheet>
diff --git a/lib/erl_docgen/priv/xsl/db_pdf_params.xsl b/lib/erl_docgen/priv/xsl/db_pdf_params.xsl
index e2e264b90a..7de20f2092 100644
--- a/lib/erl_docgen/priv/xsl/db_pdf_params.xsl
+++ b/lib/erl_docgen/priv/xsl/db_pdf_params.xsl
@@ -2,20 +2,20 @@
<!--
#
# %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%
-->
@@ -110,7 +110,7 @@
<xsl:attribute-set name="cover.inner.copyrightnotice">
<xsl:attribute name="font-size">0.9em</xsl:attribute>
- <xsl:attribute name="font-weight">bold</xsl:attribute>
+ <!-- xsl:attribute name="font-weight">bold</xsl:attribute -->
</xsl:attribute-set>
<xsl:attribute-set name="cover.inner.date">
@@ -248,6 +248,8 @@
<xsl:attribute name="padding-after">1em</xsl:attribute>
<xsl:attribute name="space-after">1em</xsl:attribute>
<xsl:attribute name="space-before">2em</xsl:attribute>
+ <xsl:attribute name="margin-left">0.5em</xsl:attribute>
+ <xsl:attribute name="margin-right">0.5em</xsl:attribute>
<xsl:attribute name="white-space-collapse">false</xsl:attribute>
<xsl:attribute name="white-space-treatment">preserve</xsl:attribute>
<xsl:attribute name="wrap-option">no-wrap</xsl:attribute>
@@ -266,8 +268,10 @@
<xsl:attribute name="text-align">justify</xsl:attribute>
<xsl:attribute name="padding-before">1em</xsl:attribute>
<xsl:attribute name="padding-after">0.3em</xsl:attribute>
- <xsl:attribute name="padding-left">1em</xsl:attribute>
- <xsl:attribute name="padding-right">1em</xsl:attribute>
+ <xsl:attribute name="padding-left">0.5em</xsl:attribute>
+ <xsl:attribute name="padding-right">0.5em</xsl:attribute>
+ <xsl:attribute name="margin-left">0.5em</xsl:attribute>
+ <xsl:attribute name="margin-right">0.5em</xsl:attribute>
<xsl:attribute name="keep-together.within-page">always</xsl:attribute>
</xsl:attribute-set>
@@ -278,8 +282,10 @@
<xsl:attribute name="text-align">justify</xsl:attribute>
<xsl:attribute name="padding-before">1em</xsl:attribute>
<xsl:attribute name="padding-after">0.3em</xsl:attribute>
- <xsl:attribute name="padding-left">1em</xsl:attribute>
- <xsl:attribute name="padding-right">1em</xsl:attribute>
+ <xsl:attribute name="padding-left">0.5em</xsl:attribute>
+ <xsl:attribute name="padding-right">0.5em</xsl:attribute>
+ <xsl:attribute name="margin-left">0.5em</xsl:attribute>
+ <xsl:attribute name="margin-right">0.5em</xsl:attribute>
<xsl:attribute name="keep-together.within-page">always</xsl:attribute>
</xsl:attribute-set>
diff --git a/lib/erl_docgen/vsn.mk b/lib/erl_docgen/vsn.mk
index d0a1c79deb..09090f01c9 100644
--- a/lib/erl_docgen/vsn.mk
+++ b/lib/erl_docgen/vsn.mk
@@ -1,22 +1,3 @@
-#
-# %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%
-#
-
-ERL_DOCGEN_VSN = 0.1
+ERL_DOCGEN_VSN = 0.2
TICKETS =
diff --git a/lib/erl_interface/configure.in b/lib/erl_interface/configure.in
index 80b229c1c3..7728cb97be 100644
--- a/lib/erl_interface/configure.in
+++ b/lib/erl_interface/configure.in
@@ -1,19 +1,19 @@
# -*- Autoconf -*-
# %CopyrightBegin%
-#
-# Copyright Ericsson AB 2000-2009. All Rights Reserved.
-#
+#
+# Copyright Ericsson AB 2000-2010. All Rights Reserved.
+#
# The contents of this file are subject to the Erlang Public License,
# Version 1.1, (the "License"); you may not use this file except in
# compliance with the License. You should have received a copy of the
# Erlang Public License along with this software. If not, it can be
# retrieved online at http://www.erlang.org/.
-#
+#
# Software distributed under the License is distributed on an "AS IS"
# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
# the License for the specific language governing rights and limitations
# under the License.
-#
+#
# %CopyrightEnd%
#
# Process this file with autoconf to produce a configure script.
@@ -65,18 +65,12 @@ fi
TARGET=$host
AC_SUBST(TARGET)
-AC_CONFIG_HEADER([src/$host/config.h:src/auxdir/config.h.in])
+AC_CONFIG_HEADER([src/$host/config.h:config.h.in])
dnl ----------------------------------------------------------------------
dnl Optional features
dnl ----------------------------------------------------------------------
-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
-
# Use --disable-threads to force building single threaded libs even
# if pthreads exists (for test purposes).
AC_ARG_ENABLE(threads,
@@ -95,23 +89,22 @@ AC_PROG_CC
AC_PROG_CPP
dnl AC_PROG_LIBTOOL
AC_PROG_RANLIB
-if test "x$LD" = "x"; then
- AC_CHECK_TOOL([LD],[ld],[ld])
-fi
+AC_CHECK_PROG(LD, ld.sh)
+AC_CHECK_TOOL(LD, ld, '$(CC)')
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"
fi
-AC_CHECK_PROG(AR, ar, ar, false)
-if test "$ac_cv_prog_AR" = false; then
+AC_CHECK_TOOL(AR, ar, false)
+if test "$AR" = false; then
AC_MSG_ERROR([No 'ar' command found in PATH])
fi
@@ -164,7 +157,7 @@ AC_TRY_COMPILE([#include <sys/types.h>
#include <sys/socket.h>],
[socklen_t mylen;],
[AC_MSG_RESULT(yes)
- AC_DEFINE(HAVE_SOCKLEN_T)],
+ AC_DEFINE(HAVE_SOCKLEN_T, [], [Define if you have the `socklen_t' type])],
[AC_MSG_RESULT(no)])
# Checks for library functions.
@@ -209,7 +202,7 @@ if test "x$with_gmp" = "xyes" ;then
AC_CHECK_HEADER($dir/include/gmp.h, ac_cv_gmp=yes, ac_cv_gmp=no)
if test $ac_cv_gmp = yes ; then
CFLAGS="$CFLAGS -I$dir/include -L$dir/lib"
- AC_DEFINE(HAVE_GMP_H)
+ AC_DEFINE(HAVE_GMP_H, [], [Define if you have "gmp.h"])
break
fi
done
@@ -226,7 +219,7 @@ elif test "x$with_gmp" != "xno" -a -n "$with_gmp" ;then
fi
AC_MSG_RESULT(yes)
CFLAGS="$CFLAGS -I$with_gmp/include -L$with_gmp/lib"
- AC_DEFINE(HAVE_GMP_H)
+ AC_DEFINE(HAVE_GMP_H, [], [Define if you have "gmp.h"])
AC_CHECK_LIB(gmp, __gmpz_export)
# FIXME return ERROR if no lib
fi
@@ -279,110 +272,43 @@ AC_SUBST(MIXED_CYGWIN)
dnl
dnl Threads
dnl
-found_threads=no
THR_LIBS=
THR_DEFS=
-EI_THREADS="false"
AC_SUBST(THR_LIBS)
AC_SUBST(THR_DEFS)
AC_SUBST(EI_THREADS)
case "$threads_disabled" in
- no)
- AC_MSG_CHECKING([for native win32 threads])
- if test "X$host_os" = "Xwin32"; then
- THR_DEFS="-DWIN32_THREADS"
- found_threads=yes
- EI_THREADS="true"
- AC_MSG_RESULT([yes])
- AC_MSG_CHECKING([for __declspec(thread) usability])
- if test "X$GCC" = "Xyes"; then
- AC_MSG_RESULT([no])
- else
- THR_DEFS="$THR_DEFS -DUSE_DECLSPEC_THREAD"
- AC_MSG_RESULT([yes])
- fi
+ no)
+ LM_CHECK_THR_LIB
+
+ case "$THR_LIB_NAME" in
+ "")
+ EI_THREADS="false"
+ ;;
+ win32_threads)
+ EI_THREADS="true"
+ AC_MSG_CHECKING([for __declspec(thread) usability])
+ if test "X$GCC" = "Xyes"; then
+ AC_MSG_RESULT([no])
else
- AC_MSG_RESULT(no)
-
- dnl Check for POSIX threads
-
- pthread_lib=""
- AC_CHECK_LIB(pthread,
- pthread_create,
- [found_threads=yes
- EI_THREADS="true"
- THR_LIBS="-lpthread"
- THR_DEFS="-D_REENTRANT -D_THREAD_SAFE -DPOSIX_THREADS"
- pthread_lib=pthread])
-
- # FreeBSD has pthreads in special c library, c_r
- if test $found_threads = no; then
- AC_CHECK_LIB(c_r,
- pthread_create,
- [found_threads=yes
- EI_THREADS="true"
- THR_LIBS="-lc_r"
- THR_DEFS="-D_REENTRANT -D_THREAD_SAFE -DPOSIX_THREADS"
- pthread_lib=c_r])
- fi
-
- if test "x$pthread_lib" != "x"; then
- AC_CHECK_LIB($pthread_lib,pthread_atfork,AC_DEFINE(HAVE_PTHREAD_ATFORK))
- AC_CHECK_HEADER(pthread.h, AC_DEFINE(HAVE_PTHREAD_H))
- dnl Some Linuxes have <pthread/mit/pthread.h> instead of <pthread.h>
- AC_CHECK_HEADER(pthread/mit/pthread.h, AC_DEFINE(HAVE_MIT_PTHREAD_H))
- case $host_os in
- solaris*)
- THR_DEFS="$THR_DEFS -D_POSIX_PTHREAD_SEMANTICS";;
- linux*)
- dnl NPTL test stolen from $ERL_TOP/erts/aclocal.m4
- 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
- AC_MSG_RESULT($nptl)
- if test $nptl = yes; then
- need_nptl_incldir=no
- 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_ws_path=
- save_ifs="$IFS"; IFS=":"
- for dir in $nptl_path; do
- if test "x$dir" != "x"; then
- nptl_ws_path="$nptl_ws_path $dir"
- fi
- done
- IFS=$save_ifs
- nptl_incldir=
- for dir in $nptl_ws_path; do
- AC_CHECK_HEADER($dir/nptl/pthread.h,
- nptl_incldir=$dir/nptl)
- if test "x$nptl_incldir" != "x"; then
- THR_DEFS="$THR_DEFS -isystem $nptl_incldir"
- break
- fi
- done
- if test "x$nptl_incldir" = "x"; then
- AC_MSG_ERROR(Failed to locate nptl system include directory)
- fi
- fi
- fi
-
- ;;
- *)
- ;;
- esac
- fi
+ THR_DEFS="$THR_DEFS -DUSE_DECLSPEC_THREAD"
+ AC_MSG_RESULT([yes])
fi
;;
- yes)
- # Threads disabled
- ;;
+ pthread)
+ EI_THREADS="true"
+ ;;
+ *)
+ EI_THREADS="true"
+ AC_MSG_WARN([Unexpected thread library: $THR_LIB_NAME])
+ ;;
+ esac
+ ;;
+ yes)
+ # Threads disabled
+ EI_THREADS="false"
+ ;;
esac
# ---------------------------------------------------------------------------
@@ -413,12 +339,10 @@ fi
# FIXME We want to use libtool but until then....
# ---------------------------------------------------------------------------
-AC_SUBST(DED_CFLAGS)
-dnl AC_SUBST(DED_LD)
-dnl AC_SUBST(DED_LDFLAGS)
+AC_SUBST(LIB_CFLAGS)
if test "X$host" = "Xwin32"; then
- DED_CFLAGS="$CFLAGS"
+ LIB_CFLAGS="$CFLAGS"
else
case $host_os in
darwin*)
@@ -427,9 +351,9 @@ else
esac
if test "x$GCC" = xyes; then
- DED_CFLAGS="$CFLAGS -fPIC"
+ LIB_CFLAGS="$CFLAGS -fPIC"
else
- DED_CFLAGS="$CFLAGS"
+ LIB_CFLAGS="$CFLAGS"
fi
fi
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/doc/src/erl_eterm.xml b/lib/erl_interface/doc/src/erl_eterm.xml
index ce14549672..f403618c59 100644
--- a/lib/erl_interface/doc/src/erl_eterm.xml
+++ b/lib/erl_interface/doc/src/erl_eterm.xml
@@ -248,7 +248,7 @@ iohead ::= Binary
<v>ETERM *list;</v>
</type>
<desc>
- <p>This function converts an IO list to a '\\0' terminated C
+ <p>This function converts an IO list to a '\0' terminated C
string. </p>
<p><c><![CDATA[list]]></c> is an Erlang term containing an IO list. The IO
list must not contain the integer 0, since C strings may not
diff --git a/lib/erl_interface/doc/src/notes.xml b/lib/erl_interface/doc/src/notes.xml
index f2519fda0b..14aec4a4d9 100644
--- a/lib/erl_interface/doc/src/notes.xml
+++ b/lib/erl_interface/doc/src/notes.xml
@@ -4,7 +4,7 @@
<chapter>
<header>
<copyright>
- <year>2004</year><year>2009</year>
+ <year>2004</year><year>2010</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
@@ -13,12 +13,12 @@
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>Erl_interface Release Notes</title>
@@ -30,6 +30,96 @@
</header>
<p>This document describes the changes made to the Erl_interface application.</p>
+<section><title>Erl_Interface 3.6.5</title>
+
+ <section><title>Improvements and New Features</title>
+ <list>
+ <item>
+ <p>
+ Document debug support.</p>
+ <p>
+ Debug trace output for connection activity could be
+ enabled setting the trace level as an integer to the
+ EI_TRACELEVEL environment variable. This option could
+ also be read and set from a running program using
+ ei_get_tracelevel(void) and ei_set_tracelevel(int).</p>
+ <p>
+ Own Id: OTP-5037</p>
+ </item>
+ <item>
+ <p>Cross compilation improvements and other build system
+ improvements.</p>
+ <p>Most notable:</p> <list><item> Lots of cross
+ compilation improvements. The old cross compilation
+ support was more or less non-existing as well as broken.
+ Please, note that the cross compilation support should
+ still be considered as experimental. Also note that old
+ cross compilation configurations cannot be used without
+ modifications. For more information on cross compiling
+ Erlang/OTP see the <c>$ERL_TOP/INSTALL-CROSS.md</c> file.
+ </item><item> Support for staged install using <url
+ href="http://www.gnu.org/prep/standards/html_node/DESTDIR.html">DESTDIR</url>.
+ The old broken <c>INSTALL_PREFIX</c> has also been fixed.
+ For more information see the <c>$ERL_TOP/INSTALL.md</c>
+ file. </item><item> Documentation of the <c>release</c>
+ target of the top <c>Makefile</c>. For more information
+ see the <c>$ERL_TOP/INSTALL.md</c> file. </item><item>
+ <c>make install</c> now by default creates relative
+ symbolic links instead of absolute ones. For more
+ information see the <c>$ERL_TOP/INSTALL.md</c> file.
+ </item><item> <c>$ERL_TOP/configure --help=recursive</c>
+ now works and prints help for all applications with
+ <c>configure</c> scripts. </item><item> Doing <c>make
+ install</c>, or <c>make release</c> directly after
+ <c>make all</c> no longer triggers miscellaneous
+ rebuilds. </item><item> Existing bootstrap system is now
+ used when doing <c>make install</c>, or <c>make
+ release</c> without a preceding <c>make all</c>.
+ </item><item> The <c>crypto</c> and <c>ssl</c>
+ applications use the same runtime library path when
+ dynamically linking against <c>libssl.so</c> and
+ <c>libcrypto.so</c>. The runtime library search path has
+ also been extended. </item><item> The <c>configure</c>
+ scripts of <c>erl_interface</c> and <c>odbc</c> now
+ search for thread libraries and thread library quirks the
+ same way as <c>erts</c> do. </item><item> The
+ <c>configure</c> script of the <c>odbc</c> application
+ now also looks for odbc libraries in <c>lib64</c> and
+ <c>lib/64</c> directories when building on a 64-bit
+ system. </item><item> The <c>config.h.in</c> file in the
+ <c>erl_interface</c> application is now automatically
+ generated in instead of statically updated which reduces
+ the risk of <c>configure</c> tests without any effect.
+ </item></list>
+ <p>(Thanks to Henrik Riomar for suggestions and
+ testing)</p>
+ <p>(Thanks to Winston Smith for the AVR32-Linux cross
+ configuration and testing)</p>
+ <p>
+ *** POTENTIAL INCOMPATIBILITY ***</p>
+ <p>
+ Own Id: OTP-8323</p>
+ </item>
+ <item>
+ <p>
+ Change erroneous "\\0" in documentation files
+ <c>erl_notes.xml</c> and <c> erl_eterm.xml</c>.</p>
+ <p>
+ Own Id: OTP-8326</p>
+ </item>
+ <item>
+ <p>
+ Allow <c>erl_match()</c> to match <c>ERL_LONGLONG</c> and
+ <c>ERL_U_LONGLONG</c> terms (Thanks to Scott Lystig
+ Fritchie).</p>
+ <p>
+ Own Id: OTP-8400</p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
<section><title>Erl_Interface 3.6.4</title>
<section><title>Improvements and New Features</title>
@@ -336,7 +426,7 @@
from 0 to 255 as a string. If the original list contains
the integer 0, this is considered terminator of the
string. This is incorrect. The function has now been
- modified to not look for '\\0' in a string, but always
+ modified to not look for '\0' in a string, but always
print all characters.</p>
<p>Own Id: OTP-6339 Aux Id: seq10492 </p>
</item>
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/Makefile.in b/lib/erl_interface/src/Makefile.in
index b8ee5c83c7..8ff142a366 100644
--- a/lib/erl_interface/src/Makefile.in
+++ b/lib/erl_interface/src/Makefile.in
@@ -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%
#
@@ -106,7 +106,7 @@ WARNFLAGS = @WFLAGS@
endif
ifneq ($(findstring ose,$(TARGET)),ose)
-CFLAGS = @DED_CFLAGS@ $(WARNFLAGS) $(INCFLAGS) $(TYPE_FLAGS)
+CFLAGS = @LIB_CFLAGS@ $(WARNFLAGS) $(INCFLAGS) $(TYPE_FLAGS)
else
CFLAGS = @CFLAGS@ $(INCFLAGS)
endif
@@ -568,12 +568,14 @@ ifeq ($(findstring vxworks,$(TARGET)),vxworks)
$(TARGET)/config.h:
echo "/* Generated by Makefile */" > $@
echo "#define HAVE_STRERROR 1" >> $@
+ echo "#define HAVE_SOCKLEN_T 1" >> $@
endif
ifeq ($(findstring ose,$(TARGET)),ose)
$(TARGET)/config.h:
echo "/* Generated by Makefile */" > $@
echo "#define HAVE_STRERROR 1" >> $@
+ echo "#define HAVE_SOCKLEN_T 1" >> $@
endif
###########################################################################
diff --git a/lib/erl_interface/src/auxdir/config.h.in b/lib/erl_interface/src/auxdir/config.h.in
deleted file mode 100644
index 523c766993..0000000000
--- a/lib/erl_interface/src/auxdir/config.h.in
+++ /dev/null
@@ -1,277 +0,0 @@
-/* config.h.in. Generated from configure.in by autoheader. */
-
-/* Define to one of `_getb67', `GETB67', `getb67' for Cray-2 and Cray-YMP
- systems. This function is required for `alloca.c' support on those systems.
- */
-#undef CRAY_STACKSEG_END
-
-/* Define to 1 if using `alloca.c'. */
-#undef C_ALLOCA
-
-/* Define to 1 if you have `alloca', as a function or macro. */
-#undef HAVE_ALLOCA
-
-/* Define to 1 if you have <alloca.h> and it should be used (not on Ultrix).
- */
-#undef HAVE_ALLOCA_H
-
-/* Define to 1 if you have the <arpa/inet.h> header file. */
-#undef HAVE_ARPA_INET_H
-
-/* Define to 1 if you have the `clock_gettime' function. */
-#undef HAVE_CLOCK_GETTIME
-
-/* Define to 1 if you have the declaration of `strerror_r', and to 0 if you
- don't. */
-#undef HAVE_DECL_STRERROR_R
-
-/* Define to 1 if you don't have `vprintf' but do have `_doprnt.' */
-#undef HAVE_DOPRNT
-
-/* Define to 1 if you have the `dup2' function. */
-#undef HAVE_DUP2
-
-/* Define to 1 if you have the <fcntl.h> header file. */
-#undef HAVE_FCNTL_H
-
-/* Define to 1 if you have the `fork' function. */
-#undef HAVE_FORK
-
-/* Define to 1 if you have the `gethostbyaddr' function. */
-#undef HAVE_GETHOSTBYADDR
-
-/* Define to 1 if you have the `gethostbyname' function. */
-#undef HAVE_GETHOSTBYNAME
-
-/* Define to 1 if you have the `gethostbyname_r' function. */
-#undef HAVE_GETHOSTBYNAME_R
-
-/* Define to 1 if you have the `gethostname' function. */
-#undef HAVE_GETHOSTNAME
-
-/* Define to 1 if you have the `gethrtime' function. */
-#undef HAVE_GETHRTIME
-
-/* Define to 1 if you have the `gettimeofday' function. */
-#undef HAVE_GETTIMEOFDAY
-
-/* Define to 1 if you have the <gmp.h> header file. */
-#undef HAVE_GMP_H
-
-/* Define to 1 if you have the `inet_ntoa' function. */
-#undef HAVE_INET_NTOA
-
-/* Define to 1 if you have the <inttypes.h> header file. */
-#undef HAVE_INTTYPES_H
-
-/* Define to 1 if you have the `gmp' library (-lgmp). */
-#undef HAVE_LIBGMP
-
-/* Define to 1 if you have the `m' library (-lm). */
-#undef HAVE_LIBM
-
-/* Define to 1 if you have the `nsl' library (-lnsl). */
-#undef HAVE_LIBNSL
-
-/* Define to 1 if you have the `resolv' library (-lresolv). */
-#undef HAVE_LIBRESOLV
-
-/* Define to 1 if you have the `socket' library (-lsocket). */
-#undef HAVE_LIBSOCKET
-
-/* Define to 1 if you have the <limits.h> header file. */
-#undef HAVE_LIMITS_H
-
-/* Define to 1 if your system has a GNU libc compatible `malloc' function, and
- to 0 otherwise. */
-#undef HAVE_MALLOC
-
-/* Define to 1 if you have the <malloc.h> header file. */
-#undef HAVE_MALLOC_H
-
-/* Define to 1 if you have the `memchr' function. */
-#undef HAVE_MEMCHR
-
-/* Define to 1 if you have the `memmove' function. */
-#undef HAVE_MEMMOVE
-
-/* Define to 1 if you have the <memory.h> header file. */
-#undef HAVE_MEMORY_H
-
-/* Define to 1 if you have the `memset' function. */
-#undef HAVE_MEMSET
-
-/* Define to 1 if you have the <netdb.h> header file. */
-#undef HAVE_NETDB_H
-
-/* Define to 1 if you have the <netinet/in.h> header file. */
-#undef HAVE_NETINET_IN_H
-
-/* Define to 1 if you have the <pthread/mit/pthread.h> header file. */
-#undef HAVE_MIT_PTHREAD_H
-
-/* Define to 1 if you have the <pthread.h> header file. */
-#undef HAVE_PTHREAD_H
-
-/* Define to 1 if your system has a GNU libc compatible `realloc' function,
- and to 0 otherwise. */
-#undef HAVE_REALLOC
-
-/* Define if you have the res_gethostbyname function. */
-#undef HAVE_RES_GETHOSTBYNAME
-
-/* Define to 1 if you have the `select' function. */
-#undef HAVE_SELECT
-
-/* Define to 1 if you have the `socket' function. */
-#undef HAVE_SOCKET
-
-/* Define to 1 if you have the <stddef.h> header file. */
-#undef HAVE_STDDEF_H
-
-/* Define to 1 if you have the <stdint.h> header file. */
-#undef HAVE_STDINT_H
-
-/* Define to 1 if you have the <stdlib.h> header file. */
-#undef HAVE_STDLIB_H
-
-/* Define to 1 if you have the `strchr' function. */
-#undef HAVE_STRCHR
-
-/* Define to 1 if you have the `strerror' function. */
-#undef HAVE_STRERROR
-
-/* Define to 1 if you have the `strerror_r' function. */
-#undef HAVE_STRERROR_R
-
-/* Define to 1 if you have the <strings.h> header file. */
-#undef HAVE_STRINGS_H
-
-/* Define to 1 if you have the <string.h> header file. */
-#undef HAVE_STRING_H
-
-/* Define to 1 if you have the `strrchr' function. */
-#undef HAVE_STRRCHR
-
-/* Define to 1 if you have the `strstr' function. */
-#undef HAVE_STRSTR
-
-/* Define to 1 if you have the <sys/param.h> header file. */
-#undef HAVE_SYS_PARAM_H
-
-/* Define to 1 if you have the <sys/select.h> header file. */
-#undef HAVE_SYS_SELECT_H
-
-/* Define to 1 if you have the <sys/socket.h> header file. */
-#undef HAVE_SYS_SOCKET_H
-
-/* Define to 1 if you have the <sys/stat.h> header file. */
-#undef HAVE_SYS_STAT_H
-
-/* Define to 1 if you have the <sys/time.h> header file. */
-#undef HAVE_SYS_TIME_H
-
-/* Define to 1 if you have the <sys/types.h> header file. */
-#undef HAVE_SYS_TYPES_H
-
-/* Define to 1 if you have <sys/wait.h> that is POSIX.1 compatible. */
-#undef HAVE_SYS_WAIT_H
-
-/* Define to 1 if you have the `uname' function. */
-#undef HAVE_UNAME
-
-/* Define to 1 if you have the <unistd.h> header file. */
-#undef HAVE_UNISTD_H
-
-/* Define to 1 if you have the `vfork' function. */
-#undef HAVE_VFORK
-
-/* Define to 1 if you have the <vfork.h> header file. */
-#undef HAVE_VFORK_H
-
-/* Define to 1 if you have the `vprintf' function. */
-#undef HAVE_VPRINTF
-
-/* Define to 1 if `fork' works. */
-#undef HAVE_WORKING_FORK
-
-/* Define to 1 if `vfork' works. */
-#undef HAVE_WORKING_VFORK
-
-/* Define if you have the writev function. */
-#undef HAVE_WRITEV
-
-/* Define if you have the socklen_t datatype */
-#undef HAVE_SOCKLEN_T
-
-/* Define to the address where bug reports for this package should be sent. */
-#undef PACKAGE_BUGREPORT
-
-/* Define to the full name of this package. */
-#undef PACKAGE_NAME
-
-/* Define to the full name and version of this package. */
-#undef PACKAGE_STRING
-
-/* Define to the one symbol short name of this package. */
-#undef PACKAGE_TARNAME
-
-/* Define to the version of this package. */
-#undef PACKAGE_VERSION
-
-/* Define as the return type of signal handlers (`int' or `void'). */
-#undef RETSIGTYPE
-
-/* Define to the type of arg 1 for `select'. */
-#undef SELECT_TYPE_ARG1
-
-/* Define to the type of args 2, 3 and 4 for `select'. */
-#undef SELECT_TYPE_ARG234
-
-/* Define to the type of arg 5 for `select'. */
-#undef SELECT_TYPE_ARG5
-
-/* If using the C implementation of alloca, define if you know the
- direction of stack growth for your system; otherwise it will be
- automatically deduced at run-time.
- STACK_DIRECTION > 0 => grows toward higher addresses
- STACK_DIRECTION < 0 => grows toward lower addresses
- STACK_DIRECTION = 0 => direction of growth unknown */
-#undef STACK_DIRECTION
-
-/* Define to 1 if you have the ANSI C header files. */
-#undef STDC_HEADERS
-
-/* Define to 1 if strerror_r returns char *. */
-#undef STRERROR_R_CHAR_P
-
-/* Define to 1 if you can safely include both <sys/time.h> and <time.h>. */
-#undef TIME_WITH_SYS_TIME
-
-/* Define to empty if `const' does not conform to ANSI C. */
-#undef const
-
-/* Define to `int' if <sys/types.h> doesn't define. */
-#undef gid_t
-
-/* Define to rpl_malloc if the replacement function should be used. */
-#undef malloc
-
-/* Define to `int' if <sys/types.h> does not define. */
-#undef pid_t
-
-/* Define to rpl_realloc if the replacement function should be used. */
-#undef realloc
-
-/* Define to `unsigned' if <sys/types.h> does not define. */
-#undef size_t
-
-/* Define to `int' if <sys/types.h> doesn't define. */
-#undef uid_t
-
-/* Define as `fork' if `vfork' does not work. */
-#undef vfork
-
-/* Define to empty if the keyword `volatile' does not work. Warning: valid
- code using `volatile' can become incorrect without. Disable with care. */
-#undef volatile
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/legacy/erl_eterm.c b/lib/erl_interface/src/legacy/erl_eterm.c
index b685709c02..8d559f0f55 100644
--- a/lib/erl_interface/src/legacy/erl_eterm.c
+++ b/lib/erl_interface/src/legacy/erl_eterm.c
@@ -1,19 +1,19 @@
/*
* %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
* 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%
*/
/*
@@ -786,6 +786,12 @@ ETERM *erl_copy_term(const ETERM *ep)
case ERL_U_SMALL_BIG:
ERL_INT_UVALUE(cp) = ERL_INT_UVALUE(ep);
break;
+ case ERL_LONGLONG:
+ ERL_LL_VALUE(cp) = ERL_LL_VALUE(ep);
+ break;
+ case ERL_U_LONGLONG:
+ ERL_LL_UVALUE(cp) = ERL_LL_UVALUE(ep);
+ break;
case ERL_FLOAT:
ERL_FLOAT_VALUE(cp) = ERL_FLOAT_VALUE(ep);
break;
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/erl_interface/vsn.mk b/lib/erl_interface/vsn.mk
index c5f4c06037..589b9e2f9c 100644
--- a/lib/erl_interface/vsn.mk
+++ b/lib/erl_interface/vsn.mk
@@ -1 +1 @@
-EI_VSN = 3.6.4
+EI_VSN = 3.6.5
diff --git a/lib/et/doc/src/Makefile b/lib/et/doc/src/Makefile
index bcbde437d1..6bb8164e91 100644
--- a/lib/et/doc/src/Makefile
+++ b/lib/et/doc/src/Makefile
@@ -1,19 +1,19 @@
#
# %CopyrightBegin%
-#
-# Copyright Ericsson AB 2002-2009. All Rights Reserved.
-#
+#
+# Copyright Ericsson AB 2002-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%
#
@@ -41,6 +41,9 @@ include files.mk
# ----------------------------------------------------
+XML_FILES = $(BOOK_FILES) $(XML_APPLICATION_FILES) $(XML_REF3_FILES) \
+ $(XML_PART_FILES) $(XML_CHAPTER_FILES)
+
HTML_FILES = $(XML_APPLICATION_FILES:%.xml=$(HTMLDIR)/%.html) \
$(XML_PART_FILES:%.xml=$(HTMLDIR)/%.html)
@@ -60,7 +63,7 @@ XML_FLAGS +=
# ----------------------------------------------------
# Targets
# ----------------------------------------------------
-$(HTMLDIR)/%.gif: %.gif
+$(HTMLDIR)/%: %
$(INSTALL_DATA) $< $@
docs: pdf html man
@@ -69,9 +72,14 @@ $(TOP_PDF_FILE): $(XML_FILES)
pdf: $(TOP_PDF_FILE)
-html: gifs $(HTML_REF_MAN_FILE)
+html: images $(HTML_REF_MAN_FILE)
clean clean_docs:
+ for file in $(XML_FILES); do \
+ if [ -f $$file\src ]; then \
+ rm -f $$file; \
+ fi \
+ done
rm -rf $(HTMLDIR)/*
rm -f $(MAN3DIR)/*
rm -f $(TOP_PDF_FILE) $(TOP_PDF_FILE:%.pdf=%.fo)
@@ -79,7 +87,7 @@ clean clean_docs:
man: $(MAN3_FILES)
-gifs: $(GIF_FILES:%=$(HTMLDIR)/%)
+images: $(IMAGE_FILES:%=$(HTMLDIR)/%)
debug opt:
diff --git a/lib/et/doc/src/book.gif b/lib/et/doc/src/book.gif
deleted file mode 100644
index 94b3868792..0000000000
--- a/lib/et/doc/src/book.gif
+++ /dev/null
Binary files differ
diff --git a/lib/et/doc/src/coffee_order.png b/lib/et/doc/src/coffee_order.png
new file mode 100644
index 0000000000..b3f17e7ead
--- /dev/null
+++ b/lib/et/doc/src/coffee_order.png
Binary files differ
diff --git a/lib/et/doc/src/et.xml b/lib/et/doc/src/et.xml
index 27cc47a4b4..9b170dd7d9 100644
--- a/lib/et/doc/src/et.xml
+++ b/lib/et/doc/src/et.xml
@@ -4,7 +4,7 @@
<erlref>
<header>
<copyright>
- <year>2002</year><year>2009</year>
+ <year>2002</year><year>2010</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
@@ -13,12 +13,12 @@
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>et</title>
@@ -37,30 +37,28 @@
</description>
<funcs>
<func>
- <name>report_event(DetailLevel, FromTo, Label, Contents) -> hopefully_traced</name>
- <name>report_event(DetailLevel, From, To, Label, Contents) -> hopefully_traced</name>
- <name>phone_home(DetailLevel, FromTo, Label, Contents) -> hopefully_traced</name>
- <name>phone_home(DetailLevel, From, To, Label, Contents) -> hopefully_traced</name>
- <fsummary>Reports an event, such as a message</fsummary>
+ <name>trace_me(DetailLevel, From, To, Label, Contents) -> hopefully_traced</name>
+ <fsummary>A function that is intended to be traced.</fsummary>
<type>
<v>DetailLevel = integer(X) when X =&lt; 0, X >= 100</v>
<v>From = actor()</v>
<v>To = actor()</v>
- <v>FromTo = actor()</v>
<v>Label = atom() | string() | term()</v>
<v>Contents = [{Key, Value}] | term()</v>
- <v>actor() = term()</v>
+ <v>actor() = term()</v>
</type>
<desc>
- <p>Reports an event, such as a message.</p>
- <p>These functions are intended to be invoked at strategic places
- in user applications in order to enable simplified tracing.
- The functions are extremely light weight as they do nothing
- besides returning an atom. These functions are designed for
- being traced. The global tracing mechanism in et_collector
- defaults to set its trace pattern to these functions.</p>
- <p>The label is intended to provide a brief summary of the event.
- A simple tag would do.</p>
+ <p>A function that is intended to be traced.</p>
+ <p>This function is intended to be invoked at strategic places
+ in user applications in order to enable simplified
+ tracing. The functions are extremely light weight as they do
+ nothing besides returning an atom. The functions are designed
+ for being traced. The global tracing mechanism in
+ <c>et_collector</c> defaults to set its trace pattern to these
+ functions.</p>
+ <p>The label is intended to provide a brief summary of the
+ event. It is preferred to use an atom but a string would also
+ do.</p>
<p>The contents can be any term but in order to simplify
post processing of the traced events, a plain list
of {Key, Value} tuples is preferred.</p>
@@ -68,6 +66,37 @@
Other events (termed actions) may be undirected and only have one actor.</p>
</desc>
</func>
+
+ <func>
+ <name>trace_me(DetailLevel, FromTo, Label, Contents) -> hopefully_traced</name>
+ <fsummary>A function that is intended to be traced.</fsummary>
+ <desc>
+ <p>Invokes <c>et:trace_me/5</c> with both <c>From</c> and <c>To</c>
+ set to <c>FromTo</c>.</p>
+ </desc>
+ </func>
+
+ <func>
+ <name>phone_home(DetailLevel, FromTo, Label, Contents) -> hopefully_traced</name>
+ <name>phone_home(DetailLevel, From, To, Label, Contents) -> hopefully_traced</name>
+ <fsummary>Send a signal to the outer space</fsummary>
+ <desc>
+ <p>These functions sends a signal to the outer space and the
+ caller hopes that someone is listening. In other words, they
+ invoke <c>et:trace_me/4</c> and <c>et:trace_me/5</c>
+ respectively.</p>
+ </desc>
+ </func>
+ <func>
+ <name>report_event(DetailLevel, FromTo, Label, Contents) -> hopefully_traced</name>
+ <name>report_event(DetailLevel, From, To, Label, Contents) -> hopefully_traced</name>
+ <fsummary>Deprecated functions</fsummary>
+ <desc>
+ <p>Deprecated functions which for the time being are kept for
+ backwards compatibility. Invokes <c>et:trace_me/4</c> and
+ <c>et:trace_me/5</c> respectively.</p>
+ </desc>
+ </func>
</funcs>
</erlref>
diff --git a/lib/et/doc/src/et_architecture.xml b/lib/et/doc/src/et_architecture.xml
deleted file mode 100644
index 44e262db96..0000000000
--- a/lib/et/doc/src/et_architecture.xml
+++ /dev/null
@@ -1,554 +0,0 @@
-<?xml version="1.0" encoding="latin1" ?>
-<!DOCTYPE chapter SYSTEM "chapter.dtd">
-
-<chapter>
- <header>
- <copyright>
- <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.
-
- </legalnotice>
-
- <title>Usage</title>
- <prepared>H&aring;kan Mattsson</prepared>
- <responsible>H&aring;kan Mattsson</responsible>
- <docno></docno>
- <approved>H&aring;kan Mattsson</approved>
- <checked></checked>
- <date></date>
- <rev>%VSN%</rev>
- <file>et_architecture.xml</file>
- </header>
-
- <section>
- <title>Overview</title>
- <p>The two major components of the Event Tracer (ET)
- tool is a graphical sequence chart viewer (<c>et_viewer</c>)
- and its backing storage (<c>et_collector</c>). One collector
- may be used as backing storage for several simultaneous
- viewers where each one may display a different view of
- the same trace data.</p>
- <p>The interface between the collector and its viewers
- is public in order to enable other types of viewers.
- However in the following text we will focus on usage
- of the <c>et_viewer</c>.</p>
- <p>The main start function is <c>et_viewer:start/1</c>.
- It will by default start both an <c>et_collector</c> and
- an <c>et_viewer</c>:</p>
- <p></p>
- <code type="none"><![CDATA[
- % erl -pa et/examples
- Erlang (BEAM) emulator version 2002.10.08 [source]
-
- Eshell V2002.10.08 (abort with ^G)
- 1> {ok, Viewer} = et_viewer:start([]).
- {ok,<0.31.0>}
- ]]></code>
- <p>A viewer gets trace events from its collector
- by polling it regularly for more events to display.
- Trace events are for example reported to the collector with
- <c>et_collector:report_event/6</c>:</p>
- <code type="none"><![CDATA[
- 2> Collector = et_viewer:get_collector_pid(Viewer).
- <0.30.0>
- 3> et_collector:report_event(Collector, 60, my_shell, mnesia_tm, start_outer,
- "Start outer transaction"),
- 3> et_collector:report_event(Collector, 40, mnesia_tm, my_shell, new_tid,
- "New transaction id is 4711"),
- 3> et_collector:report_event(Collector, 20, my_shell, mnesia_locker, try_write_lock,
- "Acquire write lock for {my_tab, key}"),
- 3> et_collector:report_event(Collector, 10, mnesia_locker, my_shell, granted,
- "You got the write lock for {my_tab, key}"),
- 3> et_collector:report_event(Collector, 60, my_shell, do_commit,
- "Perform transaction commit"),
- 3> et_collector:report_event(Collector, 40, my_shell, mnesia_locker, release_tid,
- "Release all locks for transaction 4711"),
- 3> et_collector:report_event(Collector, 60, my_shell, mnesia_tm, delete_transaction,
- "End of outer transaction"),
- 3> et_collector:report_event(Collector, 20, my_shell, end_outer,
- "Transaction returned {atomic, ok}").
- {ok,{table_handle,<0.30.0>,11,trace_ts,#Fun<et_collector.0.83904657>}}
- 4>
- ]]></code>
- <p>This is a simulation of the process events caused by a Mnesia
- transaction that writes a record in a local table:</p>
- <code type="none">
- mnesia:transaction(fun() -> mnesia:write({my_tab, key, val}) end).
- </code>
- <p>At this stage when we have a couple of events, it is time to
- show how it looks like in the graphical interface of
- <c>et_viewer</c>:</p>
- <p></p>
- <image file="sim_trans.gif">
- <icaption>A simulated Mnesia transaction which writes one record</icaption>
- </image>
- <p>In the sequence chart, the actors (which symbolically has performed the
- traced event) are shown as named vertical bars. The order of the
- actors may be altered by dragging (hold mouse button 1 pressed during
- the operation) the name tag of an actor and drop it elsewhere:</p>
- <image file="sim_trans_move_actor.gif">
- <icaption>Two actors has switched places</icaption>
- </image>
- <p>An event may be an action performed by one single actor (blue
- text label) or it may involve two actors and is then depicted as an
- arrow directed from one actor to another (red text label). Details of
- an event can be shown by clicking (press and release the mouse button 1)
- on the event label text or on the arrow:</p>
- <p></p>
- <image file="sim_trans_write_lock.gif">
- <icaption>Details of a write lock message</icaption>
- </image>
- </section>
-
- <section>
- <title>Filters and dictionary</title>
- <p>The Event Tracer (ET) uses named filters in various
- contexts. An Event Trace filter is an <c>Erlang fun</c>
- that takes some trace data as input and returns a possibly
- modified version of it:
- </p>
- <p></p>
- <code type="none">
- filter(TraceData) -> true | {true, NewEvent} | false
-
- TraceData = NewEvent | term()
- NewEvent = record(event)
- </code>
- <p>The interface of the filter function is the same as the the
- filter functions for the good old <c>lists:zf/2</c>. If the filter
- returns <c>false</c> it means that the <c>TraceData</c> should be
- dropped. <c>{true, NewEvent}</c> means that the <c>TraceData</c>
- should be replaced with <c>NewEvent</c>. And <c>true</c> means that the
- <c>TraceData</c> data already is an event record and that it
- should be kept as it is.
- </p>
- <p>The first filter that the trace data is exposed for is
- the collector filter. When a trace event is reported with
- <c>et_collector:report/2</c> (or <c>et_collector:report_event/5,6</c>)
- the first thing that
- happens, is that a message is sent to the collector process
- to fetch a handle that contains some useful stuff, such as
- the collector filter fun and an ets table identifier.
- Then the collector filter fun is applied and if it returns
- <c>true</c> (or <c>{true, NewEvent}</c>), the event will
- be stored in an ets table. As an optimization, subsequent
- calls to <c>et_collector:report</c>-functions can use the handle
- directly instead of the collector pid.
- </p>
- <p>The collector filter (that is the filter named
- <c>collector</c>) is a little bit special, as its input
- may be any Erlang term and is not limited to take an event
- record as the other filter functions.
- </p>
- <p>The collector manages a key/value based dictionary, where
- the filters are stored. Updates of the dictionary is
- propagated to all subscribing processes. When a viewer is
- started it is registered as a subscriber of dictionary updates.
- </p>
- <p>In a viewer there is only one filter that is active
- and all trace events that the viewer gets from the
- collector will pass thru that filter. By writing clever
- filters it is possible to customize how the events
- looks like in the viewer. The following filter replaces
- the actor names <c>mnesia_tm</c> and <c>mnesia_locker</c>
- and leaves everything else in the record as it was:
- </p>
- <p></p>
- <codeinclude file="../../examples/et_demo.erl" tag="%mgr_actors" type="erl"></codeinclude>
- <p>If we now add the filter to the running collector:
- </p>
- <p></p>
- <code type="none"><![CDATA[
- 4> Fun = fun(E) -> et_demo:mgr_actors(E) end.
- #Fun<erl_eval.5.123085357>
- 5> et_collector:dict_insert(Collector, {filter, mgr_actors}, Fun).
- ok
- 6>
- ]]></code>
- <p>you will see that the <c>Filter</c> menu in all viewers have
- got a new entry called <c>mgr_actors</c>. Select it, and a new
- viewer window will pop up:</p>
- <p></p>
- <image file="sim_trans_mgr_actors.gif">
- <icaption>The same trace data in a different view</icaption>
- </image>
- <p>In order to see the nitty gritty details of an event
- you may click on the event in order to start a contents
- viewer for that event. In the contents viewer there is
- also a filter menu in order to enable inspection of the
- event from other views than the one selected in the viewer.
- A click on the <c>new_tid</c> event will cause a contents
- viewer window to pop up, showing the event in the
- <c>mgr_actors</c> view:</p>
- <p></p>
- <image file="sim_trans_contents_viewer_mgr_actors.gif">
- <icaption>The trace event in the mgr_actors view</icaption>
- </image>
- <p>Select the <c>collector</c> entry in the <c>Filters</c>
- menu and a new contents viewer window will pop up
- showing the same trace event in the collectors view:</p>
- <p></p>
- <image file="sim_trans_contents_viewer_collector.gif">
- <icaption>The same trace event in the collectors view</icaption>
- </image>
- </section>
-
- <section>
- <title>Trace clients</title>
- <p>As you have seen it is possible to use the
- <c>et_collector:report</c>-functions explicitly. By using those functions
- you can write your own trace client that reads trace data from any
- source stored in any format and just feed the collector with it. You
- may replace the default collector filter with a filter that converts
- new exciting trace data formats to event-records or you may convert it
- to an event-record before you invoke <c>et_collector:report/2</c> and
- then rely on the default collector filter to handle the new
- format.</p>
- <p>There are also existing functions in the API that reads from
- various sources and calls <c>et_collector:report/2</c>:</p>
- <list type="bulleted">
- <item>
- <p>The trace events that are hosted by the collector may be
- stored to file and later be loaded by selecting <c>save</c>
- and <c>load</c> entries in the viewers <c>File</c>-menu or
- via the <c>et_collector</c> API.</p>
- </item>
- <item>
- <p>It is also possible to perform live tracing of a running
- system by making use of the built-in trace support in
- the Erlang emulator. These Erlang traces can be directed
- to files or to ports. See the reference manual for
- <c>erlang:trace/4</c>, <c>erlang:trace_pattern/3</c>,
- <c>dbg</c> and <c>ttb</c> for more info.</p>
- <p>There are also corresponding trace client types that can
- read the Erlang trace data format from such files or ports.
- The <c>et_collector:start_trace_client/3</c> function makes
- use of these Erlang trace clients and redirects the trace
- data to the collector.</p>
- <p>The default collector filter converts the Erlang trace data
- format into event-records.If you want to perform this
- differently you can of course write your own collector
- filter from scratch. But it may probably save you some
- efforts if you first apply the default filter in
- <c>et_selector:parse_event/2</c> before you apply your
- own conversions of its output.</p>
- </item>
- </list>
- </section>
-
- <section>
- <title>Global tracing and phone home</title>
- <p>Setting up an Erlang tracer on a set of nodes and connecting
- trace clients to the ports of these tracers is not intuitive. In order
- to make this it easier the Event Tracer as a notion of global
- tracing. When used, the <c>et_collector</c> process will monitor
- Erlang nodes and when one connects, an Erlang tracer will
- automatically be started on the other node. A corresponding trace
- client will also be started on the collector node in order to
- automatically forward the trace events to the collector. Set the
- boolean parameter <c>trace_global</c> to <c>true</c> for either the
- <c>et_collector</c> or <c>et_viewer</c> in order to activate the
- global tracing. There is no restriction on how many concurrent
- (anonymous) collectors you can have, but you can only have one global
- collector as its name is registered in <c>global</c>.</p>
- <p>In order to further simplify the tracing you can make use of the
- <c>et:report_event/4,5</c> (or its equivalents
- <c>et:phone_home/4,5</c> :-). These functions are intended to be
- invoked from other applications when there are interesting events,
- in your application that needs to be highlighted. The functions are
- extremely light weight as they do nothing besides returning an atom.
- These functions are
- specifically designed to be traced for. As the caller explicitly
- provides the values for the event-record fields, the default collector
- filter is able to automatically provide a customized event-record
- without any user defined filter functions.</p>
- <p>In normal operation the <c>et:report_event/4,5</c> calls are
- almost for free. When tracing is needed you can either activate
- tracing on these functions explicitly. Or you can combine the usage of
- <c>trace_global</c> with the usage of <c>trace_pattern</c>. When set,
- the <c>trace_pattern</c> will automatically be activated on all
- connected nodes. </p>
- <p>One nice thing with the <c>trace_pattern</c> is that it provides
- a very simple way of minimizing the amount of generated trace data by
- allowing you to explicitly control the detail level of the tracing. As
- you may have seen the <c>et_viewer</c> have a slider called
- <c>"Detail Level"</c> that allows you to control the detail level of the
- trace events displayed in the viewer. On the other hand if you set a
- low detail level in the <c>trace_pattern</c>, lots of the trace data
- will never be generated and thus not sent over the socket to the trace
- client and stored in the collector.</p>
- </section>
-
- <section>
- <title>Viewer window</title>
- <p>Almost all functionality available in the <c>et_viewer</c> is
- also available via shortcuts. Which key that has the same
- effect as selecting a menu entry is shown enclosed in
- parentheses. For example pressing the key <c>r</c> is
- equivalent to selecting the menu entry
- <c>Viewer->Refresh</c>.
- </p>
- <p>File menu:</p>
- <list type="bulleted">
- <item>
- <p>Close Collector and all Viewers - Close the collector
- and all viewers connected to that collector.</p>
- </item>
- <item>
- <p>Close other Viewers, but keep Collector - Keep this viewer
- and its collector, but close all other viewers connected
- to this collector.</p>
- </item>
- <item>
- <p>Close this Viewer, but keep Collector - Close this viewer,
- but all other viewers and the collector.</p>
- </item>
- <item>
- <p>Save Collector to file - Save all events stored in the
- collector to file.</p>
- </item>
- <item>
- <p>Load Collector from file - Load the collector with
- events from a file.</p>
- </item>
- </list>
- <p>Viewer menu:</p>
- <list type="bulleted">
- <item>
- <p>First - Scroll <c>this</c> viewer to the first collector
- event.</p>
- </item>
- <item>
- <p>Prev - Scroll <c>this</c> viewer one "page" backwards.
- Normally this means that the first event displayed in the
- viewer will be the last one and the previous <c>max_events</c>
- events will be read from the collector.</p>
- </item>
- <item>
- <p>Next - Scroll <c>this</c> viewer one "page" forward.
- Normally this means that the last event displayed in the
- viewer will be the first one and <c>max_events</c> more
- events will be read from the collector.</p>
- </item>
- <item>
- <p>Last - Scroll <c>this</c> viewer to the last collector event.</p>
- </item>
- <item>
- <p>Refresh - Clear <c>this</c> viewer and re-read its events
- from the collector.</p>
- </item>
- <item>
- <p>Up 5 - Scroll 5 events backwards.</p>
- </item>
- <item>
- <p>Down 5 - Scroll 5 events forward.</p>
- </item>
- <item>
- <p>Abort search. Display all. - Switch the display mode to
- show all events regardless of any ongoing searches.
- Abort the searches.</p>
- </item>
- </list>
- <p>Collector menu:</p>
- <list type="bulleted">
- <item>
- <p>First - Scroll <c>all</c> viewers to the first collector
- event.</p>
- </item>
- <item>
- <p>Prev - Scroll <c>all</c> viewers one "page" backwards.
- Normally this means that the first event displayed in the
- viewer will be the last one and the previous <c>max_events</c>
- events will be read from the collector.</p>
- </item>
- <item>
- <p>Next - Scroll <c>all</c> viewers one "page" forward.
- Normally this means that the last event displayed in the
- viewer will be the first one and <c>max_events</c> more
- events will be read from the collector.</p>
- </item>
- <item>
- <p>Last - Scroll <c>all</c> viewers to the last collector event.</p>
- </item>
- <item>
- <p>Refresh - Clear <c>all</c> viewers and re-read their
- events from the collector.</p>
- </item>
- </list>
- <p>Filters menu:</p>
- <list type="bulleted">
- <item>
- <p>ActiveFilter (=) - Start a new viewer window with the
- same active filter and scale as the current one.</p>
- </item>
- <item>
- <p>ActiveFilter (+) - Start a new viewer window with
- the same active filter but a larger scale than the
- current one.</p>
- </item>
- <item>
- <p>ActiveFilter (-) - Start a new viewer window with
- the same active filter but a smaller scale than the
- current one.</p>
- </item>
- <item>
- <p>collector (0) - Start a new viewer with the collector
- filter as active filter.</p>
- </item>
- <item>
- <p>AnotherFilter (2) - If more filters are inserted into
- the dictionary, these will turn up here as entries
- in the <c>Filters</c> menu. The second filter will be
- number 2, the next one number 3 etc. The names are sorted.</p>
- </item>
- </list>
- <p>Slider and radio buttons:</p>
- <list type="bulleted">
- <item>
- <p>Freeze - When true, this means that the viewer
- will not read more events from the collector
- until set to false.</p>
- </item>
- <item>
- <p>Hide From=To - When true, this means that the viewer
- will hide all events where the from-actor equals
- to its to-actor.</p>
- </item>
- <item>
- <p>Hide Unknown - When true, this means that the viewer
- will hide all events where either of the from-actor or
- to-actor is <c>UNKNOWN</c>.</p>
- </item>
- <item>
- <p>Detail level - This slider controls the resolution
- of the viewer. Only events with a detail level <c>smaller</c>
- than the selected one (default=100=max) are displayed.</p>
- </item>
- </list>
- <p>Other features:</p>
- <list type="bulleted">
- <item>
- <p>Display details of an event - Click on the event name
- and a new window will pop up, displaying the contents
- of an event.</p>
- </item>
- <item>
- <p>Toggle actor search - Normally the viewer will be in a
- display mode where all events are shown. By clicking
- on an actor name the tool will switch display mode
- to only show events with selected actors.
- </p>
- <p>Click on an actor and only events with that actor
- will be displayed. Click on another actor to include
- that actor to the selected ones. Clicking on an already
- selected actor will remove it from the collections of
- selected actors. When the collection of selected actors
- becomes empty the normal mode where all actors are shown
- will be entered again.</p>
- <p>Abort actor search with the <c>a</c> key or with the
- <c>Viewer->Abort search</c> menu choice.
- </p>
- </item>
- <item>
- <p>Move actor - Drag and drop an actor by first clicking on
- the actor name, keeping the button pressed while moving
- the cursor to a new location and release the button where
- the actor should be moved to.</p>
- </item>
- </list>
- </section>
-
- <section>
- <title>Configuration</title>
- <p>The event-records in the ets-table are ordered by their timestamp.
- Which timestamp that should be used is controlled via the
- <c>event_order</c> parameter. Default is <c>trace_ts</c> which means
- the time when the trace data was generated. <c>event_ts</c> means
- the time when the trace data was parsed (transformed into an
- event-record).</p>
- </section>
-
- <section>
- <title>Contents viewer window</title>
- <p>File menu:</p>
- <list type="bulleted">
- <item>
- <p>Close - Close this window.</p>
- </item>
- <item>
- <p>Save - Save the contents of this window to file.</p>
- </item>
- </list>
- <p>Filters menu:</p>
- <list type="bulleted">
- <item>
- <p>ActiveFilter - Start a new contents viewer window
- with the same active filter.</p>
- </item>
- <item>
- <p>AnotherFilter (2) - If more filters are inserted into
- the dictionary, these will turn up here as entries
- in the <c>Filters</c> menu. The second filter will be
- number 2, the next one number 3 etc. The names are sorted.</p>
- </item>
- </list>
- <p>Hide menu:</p>
- <list type="bulleted">
- <item>
- <p>Hide actor in viewer - Known actors are shown as a
- named vertical bars in the viewer window. By hiding the
- actor, its vertical bar will be removed and the viewer
- will be refreshed.</p>
- <p>Hiding the actor is only useful if the <c>max_actors</c>
- threshold has been reached, as it then will imply that
- the "hidden" actor will be displayed as if it were <c>"UNKNOWN"</c>.
- If the <c>max_actors</c> threshold not have been reached,
- the actor will re-appear as a vertical bar in the viewer.
- </p>
- </item>
- <item>
- <p>Show actor in viewer - This implies that the actor
- will be added as a known actor in the viewer with
- its own vertical bar.</p>
- </item>
- </list>
- <p>Search menu:</p>
- <list type="bulleted">
- <item>
- <p>Forward from this event - Set this event to be the first
- event in the viewer and change its display mode to be
- enter forward search mode. The actor of this event
- (from, to or both) will be added to the list of selected
- actors.
- </p>
- </item>
- <item>
- <p>Reverse from this event - Set this event to be the first
- event in the viewer and change its display mode to be
- enter reverse search mode. The actor of this event
- (from, to or both) will be added to the list of selected
- actors. Observe, that the events will be shown in reverse
- order.
- </p>
- </item>
- <item>
- <p>Abort search. Display all - Switch the display mode
- of the viewer to show all events regardless of any
- ongoing searches. Abort the searches.</p>
- </item>
- </list>
- </section>
-</chapter>
-
diff --git a/lib/et/doc/src/et_collector.xml b/lib/et/doc/src/et_collector.xml
index 01ca7caa5b..88c478c89a 100644
--- a/lib/et/doc/src/et_collector.xml
+++ b/lib/et/doc/src/et_collector.xml
@@ -4,7 +4,7 @@
<erlref>
<header>
<copyright>
- <year>2002</year><year>2009</year>
+ <year>2002</year><year>2010</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
@@ -13,12 +13,12 @@
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>et_collector</title>
@@ -84,11 +84,12 @@
dictionary updates will be propagated to the subscriber processes
matching the pattern {{subscriber, '_'}, '_'} where the first '_'
is interpreted as a pid().</p>
- <p>In global trace mode, the collector will automatically start
- tracing on all connected Erlang nodes. When a node connects, a port
- tracer will be started on that node and a corresponding trace
- client on the collector node. By default the global trace pattern
- is 'max'.</p>
+
+ <p>In global trace mode, the collector will automatically
+ start tracing on all connected Erlang nodes. When a node
+ connects, a port tracer will be started on that node and a
+ corresponding trace client on the collector node.</p>
+
<p>Default values:</p>
<list type="bulleted">
<item>parent_pid - self().</item>
@@ -349,7 +350,7 @@
</type>
<desc>
<p>Iterate over the currently stored events.</p>
- <p>Iterates over the currently stored eventsand applies
+ <p>Iterates over the currently stored events and applies
a function for each event. The iteration may be performed
forwards or backwards and may be limited to a maximum
number of events (abs(Limit)).</p>
diff --git a/lib/et/doc/src/et_desc.xmlsrc b/lib/et/doc/src/et_desc.xmlsrc
new file mode 100644
index 0000000000..c02517ae01
--- /dev/null
+++ b/lib/et/doc/src/et_desc.xmlsrc
@@ -0,0 +1,683 @@
+<?xml version="1.0" encoding="latin1" ?>
+<!DOCTYPE chapter SYSTEM "chapter.dtd">
+
+<chapter>
+ <header>
+ <copyright>
+ <year>2002</year><year>2010</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>Description</title>
+ <prepared>H&aring;kan Mattsson</prepared>
+ <responsible>H&aring;kan Mattsson</responsible>
+ <docno></docno>
+ <approved>H&aring;kan Mattsson</approved>
+ <checked></checked>
+ <date></date>
+ <rev>%VSN%</rev>
+ <file>et_desc.xml</file>
+ </header>
+
+ <section>
+ <title>Overview</title>
+
+ <p>The two major components of the <c>Event Tracer (ET)</c> tool
+ is a graphical sequence chart viewer (<c>et_viewer</c>) and its
+ backing storage (<c>et_collector</c>). One <c>Collector</c> may be
+ used as backing storage for several simultaneous <c>Viewers</c>
+ where each one may display a different view of the same trace
+ data.</p>
+
+ <p>The interface between the <c>Collector</c> and its
+ <c>Viewers</c> is public in order to enable other types of
+ <c>Viewers</c>. However in the following text we will focus on
+ usage of the <c>et_viewer</c>.</p>
+
+ <p>The main start function is <c>et_viewer:start/1</c>. By
+ default it will start both an <c>et_collector</c> and an
+ <c>et_viewer</c>:</p>
+
+ <p></p>
+
+ <code type="none"><![CDATA[
+ % erl -pa et/examples
+ Erlang R13B03 (erts-5.7.4) [64-bit] [smp:4:4] [rq:4]
+ [async-threads:0] [kernel-poll:false]
+
+ Eshell V5.7.4 (abort with ^G)
+ 1> {ok, Viewer} = et_viewer:start([]).
+ {ok,<0.40.0>}]]></code>
+
+ <p>A <c>Viewer</c> gets trace <c>Events</c> from its
+ <c>Collector</c> by polling it regularly for more <c>Events</c> to
+ display. <c>Events</c> are for example reported to the
+ <c>Collector</c> with <c>et_collector:report_event/6</c>:</p>
+
+ <code type="none"><![CDATA[
+ 2> Collector = et_viewer:get_collector_pid(Viewer).
+ <0.39.0>
+ 3> et_collector:report_event(Collector, 60, my_shell, mnesia_tm, start_outer,
+ 3> "Start outer transaction"),
+ 3> et_collector:report_event(Collector, 40, mnesia_tm, my_shell, new_tid,
+ 3> "New transaction id is 4711"),
+ 3> et_collector:report_event(Collector, 20, my_shell, mnesia_locker, try_write_lock,
+ 3> "Acquire write lock for {my_tab, key}"),
+ 3> et_collector:report_event(Collector, 10, mnesia_locker, my_shell, granted,
+ 3> "You got the write lock for {my_tab, key}"),
+ 3> et_collector:report_event(Collector, 60, my_shell, do_commit,
+ 3> "Perform transaction commit"),
+ 3> et_collector:report_event(Collector, 40, my_shell, mnesia_locker, release_tid,
+ 3> "Release all locks for transaction 4711"),
+ 3> et_collector:report_event(Collector, 60, my_shell, mnesia_tm, delete_transaction,
+ 3> "End of outer transaction"),
+ 3> et_collector:report_event(Collector, 20, my_shell, end_outer,
+ 3> "Transaction returned {atomic, ok}").
+ {ok,{table_handle,<0.39.0>,16402,trace_ts,
+ #Fun<et_collector.0.62831470>}}]]></code>
+
+ <p>This actually is a simulation of the process <c>Events</c>
+ caused by a <c>Mnesia</c> transaction that writes a record in a local
+ table:</p>
+
+ <code type="none"><![CDATA[
+ mnesia:transaction(fun() -> mnesia:write({my_tab, key, val}) end).]]></code>
+
+ <p>At this stage when we have a couple of <c>Events</c>, it is time to
+ show how it looks like in the graphical interface of
+ <c>et_viewer</c>:</p>
+
+ <p></p>
+
+ <image file="sim_trans.png">
+ <icaption>A simulated Mnesia transaction which writes one record</icaption>
+ </image>
+
+ <p>In the sequence chart, the actors (which symbolically has
+ performed the <c>Event</c>) are shown as named vertical bars. The
+ order of the actors may be altered by dragging (hold mouse button
+ 1 pressed during the operation) the name tag of an actor and drop
+ it elsewhere:</p>
+
+ <image file="sim_trans_move_actor.png">
+ <icaption>Two actors has switched places</icaption>
+ </image>
+
+ <p>An <c>Event</c> may be an action performed by one single actor
+ (blue text label) or it may involve two actors and is then
+ depicted as an arrow directed from one actor to another (red text
+ label). Details of an <c>Event</c> can be shown by clicking (press
+ and release the mouse button 1) on the event label text or on the
+ arrow. When doing that a <c>Contents Viewer</c> window pops up. It
+ may look like this:</p>
+
+ <p></p>
+
+ <image file="sim_trans_write_lock.png">
+ <icaption>Details of a write lock message</icaption>
+ </image>
+ </section>
+
+ <section>
+ <title>Filters and dictionary</title>
+
+ <p>The <c>Event Tracer (ET)</c> uses named filters in various
+ contexts. An Event Trace filter is an <c>Erlang fun</c> that takes
+ some trace data as input and returns a possibly modified version
+ of it:
+ </p>
+
+ <p></p>
+
+ <code type="none"><![CDATA[
+ filter(TraceData) -> false | true | {true, NewEvent}
+
+ TraceData = Event | erlang_trace_data()
+ Event = #event{}
+ NewEvent = #event{}]]></code>
+
+ <p>The interface of the filter function is the same as the the
+ filter functions for the good old <c>lists:zf/2</c>. If the filter
+ returns <c>false</c> it means that the trace data should silently
+ be dropped. <c>true</c> means that the trace data data already is
+ an <c>Event Record</c> and that it should be kept as it is.
+ <c>true</c> means that the <c>TraceData</c> already is an <c>Event
+ Record</c> and that it should be kept as it is. <c>{true,
+ NewEvent}</c> means that the original trace data should be
+ replaced with <c>Event</c>. This provides means to get rid of
+ unwanted <c>Events</c> as well as enabling alternate views of an
+ <c>Event</c>.</p>
+
+ <p>The first filter that the trace data is exposed for is the
+ <c>Collector Filter</c>. When a trace <c>Event</c> is reported with
+ <c>et_collector:report/2</c> (or
+ <c>et_collector:report_event/5,6</c>) the first thing that
+ happens, is that a message is sent to the <c>Collector</c> process
+ to fetch a handle that contains some useful stuff, such as the
+ <c>Collector Filter Fun</c> and an Ets table identifier. Then the
+ <c>Collector Filter Fun</c> is applied and if it returns
+ <c>true</c> (or <c>{true, NewEvent}</c>), the <c>Event</c> will be stored
+ in an Ets table. As an optimization, subsequent calls to
+ <c>et_collector:report</c>-functions can use the handle directly
+ instead of the <c>Collector Pid</c>.</p>
+
+ <p>All filters (registered in a <c>Collector</c> or in a
+ <c>Viewer</c>) must be able to handle an <c>Event record</c> as
+ input. The <c>Collector Filter</c> (that is the filter named
+ <c>all</c>) is a little bit special, as its input also may be raw
+ <c>Erlang Trace Data</c></p>
+
+ <p>The <c>Collector</c> manages a key/value based dictionary,
+ where the filters are stored. Updates of the dictionary is
+ propagated to all subscribing processes. When a <c>Viewer</c> is
+ started it is registered as a subscriber of dictionary
+ updates.</p>
+
+ <p>In each <c>Viewer</c> there is only one filter that is active
+ and all trace <c>Events</c> that the <c>Viewer</c> gets from the
+ <c>Collector</c> will pass thru that filter. By writing clever
+ filters it is possible to customize how the <c>Events</c> looks
+ like in the viewer. The following filter in
+ <c>et/examples/et_demo.erl</c> replaces the actor names
+ <c>mnesia_tm</c> and <c>mnesia_locker</c> and leaves everything
+ else in the record as it was:</p>
+
+ <p></p>
+
+ <codeinclude file="../../examples/et_demo.erl" tag="%mgr_actors" type="erl"></codeinclude>
+ <p>If we now add the filter to the running <c>Collector</c>:</p>
+
+ <p></p>
+
+ <code type="none"><![CDATA[
+ 4> Fun = fun(E) -> et_demo:mgr_actors(E) end.
+ #Fun<erl_eval.6.13229925>
+ 5> et_collector:dict_insert(Collector, {filter, mgr_actors}, Fun).
+ ok]]></code>
+
+ <p>you will see that the <c>Filter</c> menu in all viewers have
+ got a new entry called <c>mgr_actors</c>. Select it, and a new
+ <c>Viewer</c> window will pop up:</p>
+
+ <p></p>
+
+ <image file="sim_trans_mgr_actors.png">
+ <icaption>The same trace data in a different view</icaption>
+ </image>
+
+ <p>In order to see the nitty gritty details of an <c>Event</c> you
+ may click on the <c>Event</c> in order to start a <c>Contents
+ Viewer</c> for that <c>Event</c>. In the <c>Contents Viewer</c>
+ there also is a filter menu that enables inspection of the
+ <c>Event</c> from other views than the one selected in the
+ viewer. A click on the <c>new_tid</c> <c>Event</c> will cause a
+ <c>Contents Viewer</c> window to pop up, showing the <c>Event</c>
+ in the <c>mgr_actors</c> view:</p>
+
+ <p></p>
+
+ <image file="sim_trans_contents_viewer_mgr_actors.png">
+ <icaption>The trace <c>Event</c> in the mgr_actors view</icaption>
+ </image>
+
+ <p>Select the <c>all</c> entry in the <c>Filters</c> menu
+ and a new <c>Contents Viewer window</c> will pop up showing the
+ same trace <c>Event</c> in the collectors view:</p>
+
+ <p></p>
+
+ <image file="sim_trans_contents_viewer_collector.png">
+ <icaption>The same trace <c>Event</c> in the collectors
+ view</icaption>
+ </image>
+ </section>
+
+ <section>
+ <title>Trace clients</title>
+ <p>As you have seen, it is possible to use the
+ <c>et_collector:report_event/5,6</c> functions explicitly. By
+ using those functions you can write your own trace client that
+ reads trace data from any source stored in any format and just
+ feed the <c>Collector</c> with it. You may replace the default
+ <c>Collector Filter</c> with a filter that converts new exciting
+ trace data formats to <c>Event Records</c> or you may convert it
+ to an <c>Event Record</c> before you invoke
+ <c>et_collector:report/2</c> and then rely on the default
+ <c>Collector Filter</c> to handle the new format.</p>
+
+ <p>There are also existing functions in the API that reads from
+ various sources and calls <c>et_collector:report/2</c>:</p>
+
+ <list type="bulleted">
+ <item>
+ <p>The trace <c>Events</c> that are hosted by the <c>Collector</c> may be
+ stored to file and later be loaded by selecting <c>save</c>
+ and <c>load</c> entries in the <c>Viewers</c> <c>File</c> menu
+ or via the <c>et_collector</c> API.</p>
+ </item>
+
+ <item>
+ <p>It is also possible to perform live tracing of a running
+ system by making use of the built-in trace support in the
+ Erlang emulator. These Erlang traces can be directed to files
+ or to ports. See the reference manual for
+ <c>erlang:trace/4</c>, <c>erlang:trace_pattern/3</c>,
+ <c>dbg</c> and <c>ttb</c> for more info.</p>
+
+ <p>There are also corresponding trace client types that can
+ read the Erlang trace data format from such files or ports.
+ The <c>et_collector:start_trace_client/3</c> function makes
+ use of these Erlang trace clients and redirects the trace data
+ to the <c>Collector</c>.</p>
+
+ <p>The default <c>Collector Filter</c> converts the raw Erlang
+ trace data format into <c>Event Records</c>. If you want to
+ perform this differently you can of course write your own
+ <c>Collector Filter</c> from scratch. But it may probably save
+ you some efforts if you first apply the default filter in
+ <c>et_selector:parse_event/2</c> before you apply your own
+ conversions of its output.</p>
+ </item>
+ </list>
+ </section>
+
+ <section>
+ <title>Global tracing</title>
+
+ <p>Setting up an Erlang tracer on a set of nodes and connecting
+ trace clients to the ports of these tracers is not intuitive. In
+ order to make this it easier the <c>Event Tracer</c> has a notion
+ of global tracing. When used, the <c>et_collector</c> process will
+ monitor Erlang nodes and when one connects, an Erlang tracer will
+ automatically be started on the newly connected node. A
+ corresponding trace client will also be started on the
+ <c>Collector</c> node in order to automatically forward the trace
+ <c>Events</c> to the <c>Collector</c>. Set the boolean parameter
+ <c>trace_global</c> to <c>true</c> for either the
+ <c>et_collector</c> or <c>et_viewer</c> in order to activate the
+ global tracing. There is no restriction on how many concurrent
+ (anonymous) collectors you can have, but you can only have one
+ <b>global</b> <c>Collector</c> as its name is registered in
+ <c>global</c>.</p>
+
+ <p>In order to further simplify the tracing, you can make use of
+ the <c>et:trace_me/4,5</c> functions. These functions are intended
+ to be invoked from other applications when there are interesting
+ <c>Events</c>, in your application that needs to be
+ highlighted. The functions are extremely light weight as they do
+ nothing besides returning an atom. These functions are
+ specifically designed to be traced for. As the caller explicitly
+ provides the values for the <c>Event Record</c> fields, the
+ default <c>Collector Filter</c> is able to automatically provide a
+ customized <c>Event Record</c> without any user defined filter
+ functions.</p>
+
+ <p>In normal operation, the <c>et:trace_me/4,5</c> calls are almost
+ for free. When tracing is needed, you can either activate tracing
+ on these functions explicitly. Or you can combine the usage of
+ <c>trace_global</c> with the usage of <c>trace_pattern</c>. When
+ set, the <c>trace_pattern</c> will automatically be activated on
+ all connected nodes. </p>
+
+ <p>One nice thing with the <c>trace_pattern</c> is that it
+ provides a very simple way of minimizing the amount of generated
+ trace data by allowing you to explicitly control the detail level
+ of the tracing. As you may have seen the <c>et_viewer</c> have a
+ slider called <c>"Detail Level"</c> that allows you to control the
+ detail level of the trace <c>Events</c> displayed in the
+ <c>Viewer</c>. On the other hand if you set a low detail level in
+ the <c>trace_pattern</c>, lots of the trace data will never be
+ generated and thus not sent over the socket to the trace client
+ and stored in the <c>Collector</c>.</p>
+ </section>
+
+ <section>
+ <title>Viewer window</title>
+
+ <p>Almost all functionality available in the <c>et_viewer</c> is
+ also available via shortcuts. Which key that has the same effect
+ as selecting a menu entry is shown enclosed in parentheses. For
+ example pressing the key <c>r</c> is equivalent to selecting the
+ menu entry <c>Viewer->Refresh</c>.</p>
+
+ <p>File menu:</p>
+
+ <list type="bulleted">
+ <item>
+ <p><c>Clear all events in the Collector</c> - Deletes all
+ <c>Events</c> stored in the <c>Collector</c> and notifies all
+ connected <c>Viewers</c> about this.</p>
+ </item>
+
+ <item>
+ <p><c>Load events to the Collector from file</c> - Loads the
+ <c>Collector</c> with <c>Events</c> from a file and notifies
+ all connected <c>Viewers</c> about this.</p>
+ </item>
+
+ <item>
+ <p><c>Save all events in the Collector to file</c> - Saves all
+ <c>Events</c> stored in the <c>Collector</c> to file.</p>
+ </item>
+
+ <item>
+ <p><c>Print setup</c> - Enables editing of printer setting,
+ such as paper and layout.</p>
+ </item>
+
+ <item>
+ <p><c>Print current page</c> - Prints the events on the
+ current page. The page size is dependent of the selected paper
+ type.</p>
+ </item>
+
+ <item>
+ <p><c>Print all pages</c> - Prints all events. The page size
+ is dependent of the selected paper type.</p>
+ </item>
+
+ <item>
+ <p><c>Close this Viewer</c> - Closes this <c>Viewer</c>
+ window, but keeps all other <c>Viewers</c> windows and the
+ <c>Collector</c> process.</p>
+ </item>
+
+ <item>
+ <p><c>Close other Viewers, but this</c> - Keeps this
+ <c>Viewer</c> window and its <c>Collector</c> process, but
+ closes all other <c>Viewers</c> windowsconnected to the same
+ <c>Collector</c>.</p>
+ </item>
+
+ <item>
+ <p><c>Close all Viewers and the Collector</c> - Closes the
+ <c>Collector</c> and all <c>Viewers</c> connected to it.</p>
+ </item>
+ </list>
+
+ <p>Viewer menu:</p>
+
+ <list type="bulleted">
+ <item>
+ <p><c>First</c> - Scrolls <c>this</c> viewer to the first
+ <c>Event</c> in the <c>Collector</c>.</p>
+ </item>
+
+ <item>
+ <p><c>Last</c> - Scrolls <c>this</c> viewer to the last
+ <c>Event</c> in the <c>Collector</c>.</p>
+ </item>
+
+ <item>
+ <p><c>Prev</c> - Scrolls <c>this</c> viewer one page
+ backwards.</p>
+ </item>
+
+ <item>
+ <p><c>Next</c> - Scrolls <c>this</c> viewer one page
+ forward.</p>
+ </item>
+
+ <item>
+ <p><c>Refresh</c> - Clears <c>this</c> viewer and re-read its
+ <c>Events</c> from the <c>Collector</c>.</p>
+ </item>
+
+ <item>
+ <p><c>Up</c> - Scrolls a few <c>Events</c> backwards.</p>
+ </item>
+
+ <item>
+ <p><c>Down</c> - Scrolls a few <c>Events</c> forward.</p>
+ </item>
+
+ <item>
+ <p><c>Display all actors.</c> - Reset the settings for hidden
+ and/or highlighted actors.</p>
+ </item>
+ </list>
+
+ <p>Collector menu:</p>
+
+ <list type="bulleted">
+ <item>
+ <p><c>First</c> - Scrolls<c>all</c> viewers to the first
+ <c>Event</c> in the <c>Collector</c>.</p>
+ </item>
+
+ <item>
+ <p><c>Last</c> - Scrolls <c>all</c> viewers to the last
+ <c>Event</c> in the <c>Collector</c>.</p>
+ </item>
+
+ <item>
+ <p><c>Prev</c> - Scrolls <c>all</c> viewers one page
+ backwards.</p>
+ </item>
+
+ <item>
+ <p><c>Next</c> - Scrolls <c>all</c> viewers one page
+ forward.</p>
+ </item>
+
+ <item>
+ <p><c>Refresh</c> - Clears <c>all</c> viewers and re-read
+ their <c>Events</c> from the <c>Collector</c>.</p>
+ </item>
+ </list>
+
+ <p>Filters and scaling menu:</p>
+
+ <list type="bulleted">
+ <item>
+ <p><c>ActiveFilter (=)</c> - Starts a new <c>Viewer</c> window
+ with the same active filter and scale as the current one.</p>
+ </item>
+
+ <item>
+ <p><c>ActiveFilter (+)</c> - Starts a new <c>Viewer</c> window
+ with the same active filter but a larger scale than the
+ current one.</p>
+ </item>
+
+ <item>
+ <p><c>ActiveFilter (-)</c> - Starts a new <c>Viewer </c>window
+ with the same active filter but a smaller scale than the
+ current one.</p>
+ </item>
+
+ <item>
+ <p><c>all (0)</c> - Starts a new <c>Viewer</c> with the
+ <c>Collector Filter</c> as active filter. It will cause all
+ events in the collector to be viewed.</p>
+ </item>
+
+ <item>
+ <p><c>AnotherFilter (2)</c> - If more filters are inserted
+ into the dictionary, these will turn up here as entries in the
+ <c>Filters</c> menu. The second filter will get the shortcut
+ number 2, the next one number 3 etc. The names are sorted.</p>
+ </item>
+ </list>
+
+ <p>Slider and radio buttons:</p>
+
+ <list type="bulleted">
+ <item>
+ <p><c>Hide From=To</c> - When true, this means that the
+ <c>Viewer</c> will hide all <c>Events</c> where the from-actor
+ equals to its to-actor. These events are sometimes called
+ actions.</p>
+ </item>
+
+ <item>
+ <p><c>Hide (excluded actors)</c> - When true, this means that
+ the <c>Viewer</c> will hide all <c>Events</c> whose actors are
+ marked as excluded. Excluded actors are normally enclosed in
+ round brackets when they are displayed inthe
+ <c>Viewer</c>.</p>
+ </item>
+
+ <item>
+ <p><c>Detail level</c> - This slider controls the resolution
+ of the <c>Viewer</c>. Only <c>Events</c> with a detail level
+ <c>smaller</c> than the selected one (default=100=max) are
+ displayed.</p>
+ </item>
+ </list>
+
+ <p>Other features:</p>
+
+ <list type="bulleted">
+ <item>
+ <p><c>Vertical scroll</c> - Use mouse wheel and up/down arrows
+ to scroll little. Use page up/down and home/end buttons to
+ scroll more.</p>
+ </item>
+
+ <item>
+ <p><c>Display details of an event</c> - Left mouse click on
+ the event label or the arrowand a new <c>Contents Viewer</c>
+ window will pop up, displaying the contents of an
+ <c>Event</c>.</p>
+ </item>
+
+ <item>
+ <p><c>Highlight actor (toggle)</c> - Left mouse click on the
+ actor name tag. The actor name will be enclosed in square
+ brackets <c>[]</c>. When one or more actors are highlighted,
+ only events related to those actors are displayed. All others
+ are hidden.</p>
+ </item>
+
+ <item>
+ <p><c>Exclude actor (toggle)</c> - Right mouse click on the
+ actor name tag. The actor name will be enclosed in round
+ brackets <c>()</c>. When an actor is excluded, all events
+ related to this actor is hidden. If the checkbox <c>Hide
+ (excluded actors)</c> is checked, even the name tags and
+ corresponding vertical line of excluded actors will be
+ hidden.</p>
+ </item>
+
+ <item>
+ <p><c>Move actor</c> - Left mouse button drag and drop on
+ actor name tag. Move the actor by first clicking on the actor
+ name, keeping the button pressed while moving the cursor to a
+ new location and release the button where the actor should be
+ moved to.</p>
+ </item>
+
+ <item>
+ <p><c>Display all actors</c> - Press the 'a' button. Reset the
+ settings for hidden and/or highlighted actors.</p>
+ </item>
+ </list>
+ </section>
+
+ <section>
+ <title>Configuration</title>
+
+ <p>The <c>Event Records</c> in the Ets table are ordered by their
+ timestamp. Which timestamp that should be used is controlled via
+ the <c>event_order</c> parameter. Default is <c>trace_ts</c> which
+ means the time when the trace data was generated. <c>event_ts</c>
+ means the time when the trace data was parsed (transformed into an
+ <c>Event Record</c>).</p>
+ </section>
+
+ <section>
+ <title>Contents viewer window</title>
+
+ <p>File menu:</p>
+
+ <list type="bulleted">
+ <item>
+ <p><c>Close</c> - Close this window.</p>
+ </item>
+
+ <item>
+ <p><c>Save</c> - Save the contents of this window to file.</p>
+ </item>
+ </list>
+
+ <p>Filters menu:</p>
+
+ <list type="bulleted">
+ <item>
+ <p><c>ActiveFilter</c> - Start a new <c>Contents Viewer
+ window</c> with the same active filter.</p>
+ </item>
+
+ <item>
+ <p><c>AnotherFilter (2)</c> - If more filters are inserted
+ into the dictionary, these will turn up here as entries in the
+ <c>Filters</c> menu. The second filter will be number 2, the
+ next one number 3 etc. The names are sorted.</p>
+ </item>
+ </list>
+
+ <p>Hide menu:</p>
+
+ <list type="bulleted">
+ <item>
+ <p><c>Hide actor in viewer</c> - Known actors are shown as a
+ named vertical bars in the <c>Viewer</c> window. By hiding the
+ actor, its vertical bar will be removed and the <c>Viewer</c>
+ will be refreshed.</p>
+
+ <p><c>Hiding the actor</c> is only useful if the
+ <c>max_actors</c> threshold has been reached, as it then will
+ imply that the "hidden" actor will be displayed as if it were
+ <c>"UNKNOWN"</c>. If the <c>max_actors</c> threshold not have
+ been reached, the actor will re-appear as a vertical bar in
+ the <c>Viewer</c>.</p>
+ </item>
+ <item>
+ <p><c>Show actor in viewer</c> - This implies that the actor
+ will be added as a known actor in the <c>Viewer</c> with its
+ own vertical bar.</p>
+ </item>
+ </list>
+
+ <p>Search menu:</p>
+
+ <list type="bulleted">
+ <item>
+ <p><c>Forward from this event</c> - Set this event to be the first
+ event in the viewer and change its display mode to be enter
+ forward search mode. The actor of this event (from, to or
+ both) will be added to the list of selected actors.</p>
+ </item>
+
+ <item>
+ <p><c>Reverse from this event</c> - Set this event to be the
+ first <c>Event</c> in the <c>Viewer</c> and change its display
+ mode to be enter reverse search mode. The actor of this
+ <c>Event</c> (from, to or both) will be added to the list of
+ selected actors. Observe, that the <c>Events</c> will be shown
+ in reverse order.</p>
+ </item>
+
+ <item>
+ <p><c>Abort search. Display all</c> - Switch the display mode
+ of the <c>Viewer</c> to show all <c>Events</c> regardless of
+ any ongoing searches. Abort the searches.</p>
+ </item>
+ </list>
+ </section>
+</chapter>
+
diff --git a/lib/et/doc/src/et_examples.xml b/lib/et/doc/src/et_examples.xml
deleted file mode 100644
index 7627b191a1..0000000000
--- a/lib/et/doc/src/et_examples.xml
+++ /dev/null
@@ -1,311 +0,0 @@
-<?xml version="1.0" encoding="latin1" ?>
-<!DOCTYPE chapter SYSTEM "chapter.dtd">
-
-<chapter>
- <header>
- <copyright>
- <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.
-
- </legalnotice>
-
- <title>Examples</title>
- <prepared>H&aring;kan Mattsson</prepared>
- <responsible>H&aring;kan Mattsson</responsible>
- <docno></docno>
- <approved>H&aring;kan Mattsson</approved>
- <checked></checked>
- <date></date>
- <rev>%VSN%</rev>
- <file>et_examples.xml</file>
- </header>
-
- <section>
- <title>A simulated Mnesia transaction</title>
- <p>The Erlang code for running the simulated Mnesia transaction example
- in the previous chapter is included in the <c>et/examples/et_demo.erl</c> file:
- </p>
- <p></p>
- <codeinclude file="../../examples/et_demo.erl" tag="%sim_trans" type="erl"></codeinclude>
- <p></p>
- <codeinclude file="../../examples/et_demo.erl" tag="%mgr_actors" type="erl"></codeinclude>
- <p>If you invoke the <c>et_demo:sim_trans()</c> function a viewer
- window will pop up and the sequence trace will be almost the same as
- if the following Mnesia transaction would have been run:</p>
- <p></p>
- <code type="none">
- mnesia:transaction(fun() -> mnesia:write({my_tab, key, val}) end).
- </code>
- <p>And the viewer window will look like:</p>
- <p></p>
- <code type="none"><![CDATA[
- $ erl -pa ../examples
- Erlang (BEAM) emulator version 2002.10.08 [source]
-
- Eshell V2002.10.08 (abort with ^G)
- 1> et_demo:sim_trans().
- {ok,{table_handle,<0.30.0>,11,trace_ts,#Fun<et_collector.0.83904657>}}
- 2>
- ]]></code>
- <p></p>
- <image file="sim_trans.gif">
- <icaption>A simulated Mnesia transaction which writes one record</icaption>
- </image>
- </section>
-
- <section>
- <title>Some convenient functions used in the Mnesia transaction example</title>
- <p>The <c>module_as_actor</c> filter converts the event-records so
- the module names becomes actors and the invoked functions becomes
- labels. If the information about who the caller was it will be
- displayed as an arrow directed from the caller to the callee. The
- <c>[{message, {caller}}, {return_trace}]</c> options to <c>dbg:tpl/2</c>
- function will imply the necessary information in the Erlang traces.
- Here follows the <c>module_as_actor</c> filter:</p>
- <p></p>
- <codeinclude file="../../examples/et_demo.erl" tag="%module_as_actor" type="erl"></codeinclude>
- <p>The <c>plain_process_info</c> filter does not alter the event-records.
- It merely ensures that the event not related to processes are skipped:</p>
- <p></p>
- <codeinclude file="../../examples/et_demo.erl" tag="%plain_process_info" type="erl"></codeinclude>
- <p>The <c>plain_process_info_nolink</c> filter does not alter the
- event-records. It do makes use of the <c>plain_process_info</c> , but
- do also ensure that the process info related to linking and unlinking
- is skipped:</p>
- <p></p>
- <codeinclude file="../../examples/et_demo.erl" tag="%plain_process_info_nolink" type="erl"></codeinclude>
- <p>In order to simplify the startup of an <c>et_viewer</c> process
- with the filters mentioned above, plus some others (that also are
- found in <c>et/examples/et_demo.erl</c> src/et_collector.erl the
- <c>et_demo:start/0,1</c> functions can be used:</p>
- <p></p>
- <codeinclude file="../../examples/et_demo.erl" tag="%start" type="erl"></codeinclude>
- <p>A simple one-liner starts the tool:</p>
- <code type="none">
- erl -pa ../examples -s et_demo
- </code>
- <p>The filters are included by the following parameters:</p>
- <p></p>
- <codeinclude file="../../examples/et_demo.erl" tag="%filters" type="erl"></codeinclude>
- </section>
-
- <section>
- <title>Erlang trace of a Mnesia transaction</title>
- <p>The following piece of code <c>et_demo:trace_mnesia/0</c>
- activates call tracing of both local and external function calls for
- all modules in the Mnesia application. The call traces are configured
- cover all processes (both existing and those that are spawned in the
- future) and include timestamps for trace data. It do also activate
- tracing of process related events for Mnesia's static processes plus
- the calling process (that is your shell). Please, observe that the
- <c>whereis/1</c> call in the following code requires that both the
- traced Mnesia application and the <c>et_viewer</c>is running on the
- same node:</p>
- <p></p>
- <codeinclude file="../../examples/et_demo.erl" tag="%trace_mnesia" type="erl"></codeinclude>
- <p>The <c>et_demo:live_trans/0</c> function starts the a global
- controller, starts a viewer, starts Mnesia, creates a local table,
- activates tracing (as described above) and registers the shell
- process is as 'my_shell' for clarity. Finally the a simple Mnesia
- transaction that writes a single record is run:</p>
- <p></p>
- <codeinclude file="../../examples/et_demo.erl" tag="%live_trans" type="erl"></codeinclude>
- <p>Now we run the <c>et_demo:live_trans/0</c> function:</p>
- <p></p>
- <code type="none">
- erl -pa ../examples -s et_demo live_trans
- Erlang (BEAM) emulator version 2002.10.08 [source]
-
- Eshell V2002.10.08 (abort with ^G)
- 1>
- </code>
- <p>Please, explore the different filters in order to see how the traced
- transaction can be seen from different point of views:</p>
- <p></p>
- <image file="live_trans.gif">
- <icaption>A real Mnesia transaction which writes one record</icaption>
- </image>
- </section>
-
- <section>
- <title>Erlang trace of Megaco startup</title>
- <p>The Event Tracer (ET) tool was initially written in order to
- demonstrate how messages where sent over the Megaco protocol. This
- were back in the old days before the standard bodies of IETF and ITU
- had approved Megaco (also called H.248) as an international
- standard.</p>
- <p>In the Megaco application of Erlang/OTP, the code is carefully
- instrumented with calls to <c>et:report_event/5</c>. For call a detail
- level is set in order to dynamically control the trace level in a
- simple manner.</p>
- <p>The <c>megaco_filter</c> module implements a customized filter
- for Megaco messages. It does also make use of <c>trace_global</c>
- combined with usage of the <c>trace_pattern</c>:</p>
- <p></p>
- <code type="none">
- -module(megaco_filter).
- -export([start/0]).
-
- start() ->
- Options =
- [{event_order, event_ts},
- {scale, 3},
- {max_actors, infinity},
- {trace_pattern, {megaco, max}},
- {trace_global, true},
- {dict_insert, {filter, megaco_filter}, fun filter/1},
- {active_filter, megaco_filter},
- {title, "Megaco tracer - Erlang/OTP"}],
- et_viewer:start(Options).
- </code>
- <p>First we start an Erlang node with the a global collector and
- its viewer. The <c>et_viewer: search for: [] ++ ["gateway_tt"]</c>
- printout is caused by a click on the "gateway_tt" actor name in the
- viewer. It means that only events with that actor will be displayed
- in the viewer.</p>
- <p></p>
- <code type="none">
- erl -sname observer -s megaco_filter
- Erlang (BEAM) emulator version 2002.10.08 [source]
-
- Eshell V2002.10.08 (abort with ^G)
- (observer@amrod)1> et_viewer: search for: [] ++ ["gateway_tt"]
- </code>
- <p>Secondly we start another Erlang node which we connect the
- observer node, before we start the application that we want to
- trace. In this case we start a Media Gateway Controller that listens
- for both TCP and UDP on the text and binary ports for Megaco:</p>
- <p></p>
- <code type="none">
- erl -sname mgc -pa ../../megaco/examples/simple
- Erlang (BEAM) emulator version 2002.10.08 [source]
-
- Eshell V2002.10.08 (abort with ^G)
- (mgc@amrod)1> net:ping(observer@amrod).
- pong
- (mgc@amrod)2> megaco:start().
- ok
- (mgc@amrod)3> megaco_simple_mgc:start().
- {ok,[{ok,2944,
- {megaco_receive_handle,{deviceName,"controller"},
- megaco_pretty_text_encoder,
- [],
- megaco_tcp}},
- {ok,2944,
- {megaco_receive_handle,{deviceName,"controller"},
- megaco_pretty_text_encoder,
- [],
- megaco_udp}},
- {ok,2945,
- {megaco_receive_handle,{deviceName,"controller"},
- megaco_binary_encoder,
- [],
- megaco_tcp}},
- {ok,2945,
- {megaco_receive_handle,{deviceName,"controller"},
- megaco_binary_encoder,
- [],
- megaco_udp}}]}
- (mgc@amrod)4>
- </code>
- <p>And finally we start an Erlang node for the Media Gateways and
- connect to the observer node. Each Media Gateway connects to the
- controller and sends an initial Service Change message. The controller
- accepts the gateways and sends a reply to each one using the same
- transport mechanism and message encoding according to the preference
- of each gateway. That is all combinations of TCP/IP transport, UDP/IP
- transport, text encoding and ASN.1 BER encoding:</p>
- <p></p>
- <code type="none">
- erl -sname mg -pa ../../megaco/examples/simple
- Erlang (BEAM) emulator version 2002.10.08 [source]
-
- Eshell V2002.10.08 (abort with ^G)
- (mg@amrod)1> net:ping(observer@amrod).
- pong
- (mg@amrod)2> megaco_simple_mg:start().
- [{{deviceName,"gateway_tt"},{error,{start_user,megaco_not_started}}},
- {{deviceName,"gateway_tb"},{error,{start_user,megaco_not_started}}},
- {{deviceName,"gateway_ut"},{error,{start_user,megaco_not_started}}},
- {{deviceName,"gateway_ub"},{error,{start_user,megaco_not_started}}}]
- (mg@amrod)3> megaco:start().
- ok
- (mg@amrod)4> megaco_simple_mg:start().
- [{{deviceName,"gateway_tt"},
- {1,
- {ok,[{'ActionReply',0,
- asn1_NOVALUE,
- asn1_NOVALUE,
- [{serviceChangeReply,
- {'ServiceChangeReply',
- [{megaco_term_id,false,["root"]}],
- {serviceChangeResParms,
- {'ServiceChangeResParm',
- {deviceName|...},
- asn1_NOVALUE|...}}}}]}]}}},
- {{deviceName,"gateway_tb"},
- {1,
- {ok,[{'ActionReply',0,
- asn1_NOVALUE,
- asn1_NOVALUE,
- [{serviceChangeReply,
- {'ServiceChangeReply',
- [{megaco_term_id,false,["root"]}],
- {serviceChangeResParms,
- {'ServiceChangeResParm',
- {...}|...}}}}]}]}}},
- {{deviceName,"gateway_ut"},
- {1,
- {ok,[{'ActionReply',0,
- asn1_NOVALUE,
- asn1_NOVALUE,
- [{serviceChangeReply,
- {'ServiceChangeReply',
- [{megaco_term_id,false,["root"]}],
- {serviceChangeResParms,
- {'ServiceChangeResParm',{...}|...}}}}]}]}}},
- {{deviceName,"gateway_ub"},
- {1,
- {ok,[{'ActionReply',0,
- asn1_NOVALUE,
- asn1_NOVALUE,
- [{serviceChangeReply,
- {'ServiceChangeReply',
- [{megaco_term_id,false,["root"]}],
- {serviceChangeResParms,
- {'ServiceChangeResParm'|...}}}}]}]}}}]
- (mg@amrod)5>
- </code>
- <p>The Megaco adopted viewer looks like this, when we have clicked
- on the "gateway_tt" actor name in order to only display the events
- regarding that actor:</p>
- <p></p>
- <image file="megaco_tracer.gif">
- <icaption>The viewer adopted for Megaco</icaption>
- </image>
- <p>A pretty printed Megaco message looks like this:</p>
- <p></p>
- <image file="megaco_filter.gif">
- <icaption>A textual Megaco message</icaption>
- </image>
- <p>And the corresponding internal form for the same Megaco message
- looks like this:</p>
- <p></p>
- <image file="megaco_collector.gif">
- <icaption>The internal form of a Megaco message</icaption>
- </image>
- </section>
-</chapter>
-
diff --git a/lib/et/doc/src/et_examples.xmlsrc b/lib/et/doc/src/et_examples.xmlsrc
new file mode 100644
index 0000000000..7678184515
--- /dev/null
+++ b/lib/et/doc/src/et_examples.xmlsrc
@@ -0,0 +1,383 @@
+<?xml version="1.0" encoding="latin1" ?>
+<!DOCTYPE chapter SYSTEM "chapter.dtd">
+
+<chapter>
+ <header>
+ <copyright>
+ <year>2002</year><year>2010</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>Advanced examples</title>
+ <prepared>H&aring;kan Mattsson</prepared>
+ <responsible>H&aring;kan Mattsson</responsible>
+ <docno></docno>
+ <approved>H&aring;kan Mattsson</approved>
+ <checked></checked>
+ <date></date>
+ <rev>%VSN%</rev>
+ <file>et_examples.xml</file>
+ </header>
+
+ <section>
+ <title>A simulated Mnesia transaction</title>
+ <p>The Erlang code for running the simulated <c>Mnesia</c> transaction
+ example in the previous chapter is included in the
+ <c>et/examples/et_demo.erl</c> file:</p>
+
+ <p></p>
+
+ <codeinclude file="../../examples/et_demo.erl" tag="%sim_trans" type="erl"></codeinclude>
+
+ <p></p>
+
+ <codeinclude file="../../examples/et_demo.erl" tag="%mgr_actors" type="erl"></codeinclude>
+
+ <p>If you invoke the <c>et_demo:sim_trans()</c> function, a
+ <c>Viewer</c> window will pop up and the sequence trace will be
+ almost the same as if the following <c>Mnesia</c> transaction
+ would have been run:</p>
+
+ <p></p>
+
+ <code type="none"><![CDATA[
+ mnesia:transaction(fun() -> mnesia:write({my_tab, key, val}) end).]]></code>
+
+ <p>And the viewer window will look like:</p>
+
+ <p></p>
+
+ <code type="none"><![CDATA[
+ Erlang R13B03 (erts-5.7.4) [64-bit] [smp:4:4] [rq:4]
+ [async-threads:0] [kernel-poll:false]
+
+ Eshell V5.7.4 (abort with ^G)
+ 1> {ok, Viewer} = et_viewer:start([]).
+ {ok,<0.40.0>;}
+ 2> et_demo:sim_trans().
+ {ok,{table_handle,<0.45.0>,24596,trace_ts,
+ #Fun<et_collector.0.62831470>}}]]></code>
+
+ <p></p>
+
+ <image file="sim_trans.png">
+ <icaption>A simulated <c>Mnesia</c> transaction which writes one
+ record</icaption>
+ </image>
+
+ </section>
+
+ <section>
+ <title>Some convenient functions used in the <c>Mnesia</c> transaction
+ example</title>
+
+ <p>The <c>module_as_actor</c> filter converts the <c>Event
+ Records</c> so the module names becomes actors and the invoked
+ functions becomes labels. If the information about who the caller
+ was it will be displayed as an arrow directed from the caller to
+ the callee. The <c>[{message, {caller}}, {return_trace}]</c>
+ options to <c>dbg:tpl/2</c> function will imply the necessary
+ information in the Erlang traces. Here follows the
+ <c>module_as_actor</c> filter:</p>
+
+
+ <p></p>
+
+ <codeinclude file="../../examples/et_demo.erl" tag="%module_as_actor" type="erl"></codeinclude>
+
+ <p>The <c>plain_process_info</c> filter does not alter the
+ <c>Event Records</c>. It merely ensures that the event not
+ related to processes are skipped:</p>
+
+ <p></p>
+
+ <codeinclude file="../../examples/et_demo.erl" tag="%plain_process_info" type="erl"></codeinclude>
+
+ <p>The <c>plain_process_info_nolink</c> filter does not alter the
+ <c>Event Records</c>. It do makes use of the
+ <c>plain_process_info</c> , but do also ensure that the process
+ info related to linking and unlinking is skipped:</p>
+
+ <p></p>
+
+ <codeinclude file="../../examples/et_demo.erl" tag="%plain_process_info_nolink" type="erl"></codeinclude>
+
+ <p>In order to simplify the startup of an <c>et_viewer</c> process
+ with the filters mentioned above, plus some others (that also are
+ found in <c>et/examples/et_demo.erl</c> src/et_collector.erl the
+ <c>et_demo:start/0,1</c> functions can be used:</p>
+
+ <p></p>
+
+ <codeinclude file="../../examples/et_demo.erl" tag="%start" type="erl"></codeinclude>
+
+ <p>A simple one-liner starts the tool:</p>
+
+ <code type="none"><![CDATA[
+ erl -pa ../examples -s et_demo]]></code>
+
+ <p>The filters are included by the following parameters:</p>
+
+ <p></p>
+
+ <codeinclude file="../../examples/et_demo.erl" tag="%filters" type="erl"></codeinclude>
+
+ </section>
+
+ <section>
+ <title>Erlang trace of a real Mnesia transaction</title>
+
+ <p>The following piece of code <c>et_demo:trace_mnesia/0</c>
+ activates call tracing of both local and external function calls
+ for all modules in the <c>Mnesia</c> application. The call traces
+ are configured cover all processes (both existing and those that
+ are spawned in the future) and include timestamps for trace
+ data. It do also activate tracing of process related events for
+ <c>Mnesia</c>'s static processes plus the calling process (that is
+ your shell). Please, observe that the <c>whereis/1</c> call in the
+ following code requires that both the traced <c>Mnesia</c>
+ application and the <c>et_viewer</c> is running on the same
+ node:</p>
+
+ <p></p>
+
+ <codeinclude file="../../examples/et_demo.erl" tag="%trace_mnesia" type="erl"></codeinclude>
+
+ <p>The <c>et_demo:live_trans/0</c> function starts the global
+ <c>Collector</c>, starts a <c>Viewer</c>, starts <c>Mnesia</c>,
+ creates a local table, activates tracing (as described above) and
+ registers the shell process is as 'my_shell' for clarity. Finally
+ a simple <c>Mnesia</c> transaction that writes a single record
+ is run:</p>
+
+ <p></p>
+
+ <codeinclude file="../../examples/et_demo.erl" tag="%live_trans" type="erl"></codeinclude>
+
+ <p>Now we run the <c>et_demo:live_trans/0</c> function:</p>
+
+ <p></p>
+
+ <code type="none"><![CDATA[
+ erl -pa ../examples
+ Erlang R13B03 (erts-5.7.4) [64-bit] [smp:4:4] [rq:4]
+ [async-threads:0] [kernel-poll:false]
+
+ Eshell V5.7.4 (abort with ^G)
+ 1> et_demo:live_trans().
+ {atomic,ok}]]></code>
+
+ <p>Please, explore the different filters in order to see how the traced
+ transaction can be seen from different point of views:</p>
+
+ <p></p>
+
+ <image file="live_trans.png">
+ <icaption>A real <c>Mnesia</c> transaction which writes one record</icaption>
+ </image>
+
+ </section>
+
+ <section>
+ <title>Erlang trace of Megaco startup</title>
+
+ <p>The <c>Event Tracer (ET)</c> tool was initially written in
+ order to demonstrate how messages where sent over the
+ <c>Megaco</c> protocol. This were back in the old days before the
+ standard bodies of <c>IETF</c> and <c>ITU</c> had approved
+ <c>Megaco</c> (also called <c>H.248</c>) as an international
+ standard.</p>
+
+ <p>In the <c>Megaco</c> application of Erlang/OTP, the code is
+ carefully instrumented with calls to <c>et:trace_me/5</c>. For
+ each call a detail level is given in order to enable dynamic
+ control of the trace level in a simple manner.</p>
+
+ <p>The <c>megaco_filter</c> module implements a customized filter
+ for <c>Megaco</c> messages. It does also make use of
+ <c>trace_global</c> combined with usage of the
+ <c>trace_pattern</c>:</p>
+
+ <p></p>
+
+ <code type="none"><![CDATA[
+ -module(megaco_filter).
+ -export([start/0]).
+
+ start() ->
+ Options =
+ [{event_order, event_ts},
+ {scale, 3},
+ {max_actors, infinity},
+ {trace_pattern, {megaco, max}},
+ {trace_global, true},
+ {dict_insert, {filter, megaco_filter}, fun filter/1},
+ {active_filter, megaco_filter},
+ {title, "Megaco tracer - Erlang/OTP"}],
+ et_viewer:start(Options).]]></code>
+
+ <p>First we start an Erlang node with a global <c>Collector</c>
+ and its <c>Viewer</c>.</p>
+
+ <p></p>
+
+ <code type="none"><![CDATA[
+ erl -sname observer
+ Erlang R13B03 (erts-5.7.4) [64-bit] [smp:4:4] [rq:4]
+ [async-threads:0] [kernel-poll:false]
+
+ Eshell V5.7.4 (abort with ^G)
+ (observer@falco)1> megaco_filter:start().
+ {ok,<0.48.0>}]]></code>
+
+ <p>Secondly we start another Erlang node which we connect the
+ observer node, before we start the application that we want to
+ trace. In this case we start a Media Gateway Controller that
+ listens for both TCP and UDP on the text and binary ports for
+ Megaco:</p>
+
+ <p></p>
+
+ <code type="none"><![CDATA[
+ erl -sname mgc -pa ../../megaco/examples/simple
+ Erlang R13B03 (erts-5.7.4) [64-bit] [smp:4:4] [rq:4]
+ [async-threads:0] [kernel-poll:false]
+
+ Eshell V5.7.4 (abort with ^G)
+ (mgc@falco)1> net:ping(observer@falco).
+ pong
+ (mgc@falco)2> megaco:start().
+ ok
+ (mgc@falco)3> megaco_simple_mgc:start().
+ {ok,[{ok,2944,
+ {megaco_receive_handle,{deviceName,"controller"},
+ megaco_pretty_text_encoder,[],megaco_tcp,dynamic}},
+ {ok,2944,
+ {megaco_receive_handle,{deviceName,"controller"},
+ megaco_pretty_text_encoder,[],megaco_udp,dynamic}},
+ {ok,2945,
+ {megaco_receive_handle,{deviceName,"controller"},
+ megaco_binary_encoder,[],megaco_tcp,dynamic}},
+ {ok,2945,
+ {megaco_receive_handle,{deviceName,"controller"},
+ megaco_binary_encoder,[],megaco_udp,dynamic}}]}]]></code>
+
+ <p>And finally we start an Erlang node for the Media Gateways and
+ connect to the observer node. Each Media Gateway connects to the
+ controller and sends an initial Service Change message. The
+ controller accepts the gateways and sends a reply to each one
+ using the same transport mechanism and message encoding according
+ to the preference of each gateway. That is all combinations of
+ TCP/IP transport, UDP/IP transport, text encoding and ASN.1 BER
+ encoding:</p>
+
+ <p></p>
+
+ <code type="none"><![CDATA[
+ Erlang R13B03 (erts-5.7.4) [64-bit] [smp:4:4] [rq:4]
+ [async-threads:0] [kernel-poll:false]
+
+ Eshell V5.7.4 (abort with ^G)
+ (mg@falco)1> net:ping(observer@falco).
+ pong
+ (mg@falco)2> megaco_simple_mg:start().
+ [{{deviceName,"gateway_tt"},
+ {error,{start_user,megaco_not_started}}},
+ {{deviceName,"gateway_tb"},
+ {error,{start_user,megaco_not_started}}},
+ {{deviceName,"gateway_ut"},
+ {error,{start_user,megaco_not_started}}},
+ {{deviceName,"gateway_ub"},
+ {error,{start_user,megaco_not_started}}}]
+ (mg@falco)3> megaco:start().
+ ok
+ (mg@falco)4> megaco_simple_mg:start().
+ [{{deviceName,"gateway_tt"},
+ {1,
+ {ok,[{'ActionReply',0,asn1_NOVALUE,asn1_NOVALUE,
+ [{serviceChangeReply,
+ {'ServiceChangeReply',
+ [{megaco_term_id,false,["root"]}],
+ {serviceChangeResParms,
+ {'ServiceChangeResParm',
+ {deviceName,"controller"},
+ asn1_NOVALUE,asn1_NOVALUE,asn1_NOVALUE,
+ asn1_NOVALUE}}}}]}]}}},
+ {{deviceName,"gateway_tb"},
+ {1,
+ {ok,[{'ActionReply',0,asn1_NOVALUE,asn1_NOVALUE,
+ [{serviceChangeReply,
+ {'ServiceChangeReply',
+ [{megaco_term_id,false,["root"]}],
+ {serviceChangeResParms,
+ {'ServiceChangeResParm',
+ {deviceName,"controller"},
+ asn1_NOVALUE,asn1_NOVALUE,asn1_NOVALUE,
+ asn1_NOVALUE}}}}]}]}}},
+ {{deviceName,"gateway_ut"},
+ {1,
+ {ok,[{'ActionReply',0,asn1_NOVALUE,asn1_NOVALUE,
+ [{serviceChangeReply,
+ {'ServiceChangeReply',
+ [{megaco_term_id,false,["root"]}],
+ {serviceChangeResParms,
+ {'ServiceChangeResParm',
+ {deviceName,"controller"},
+ asn1_NOVALUE,asn1_NOVALUE,asn1_NOVALUE,
+ asn1_NOVALUE}}}}]}]}}},
+ {{deviceName,"gateway_ub"},
+ {1,
+ {ok,[{'ActionReply',0,asn1_NOVALUE,asn1_NOVALUE,
+ [{serviceChangeReply,
+ {'ServiceChangeReply',
+ [{megaco_term_id,false,["root"]}],
+ {serviceChangeResParms,
+ {'ServiceChangeResParm',
+ {deviceName,"controller"},
+ asn1_NOVALUE,asn1_NOVALUE,
+ asn1_NOVALUE,...}}}}]}]}}}]]]></code>
+
+ <p>The <c>Megaco</c> adopted viewer looks like this, when we have clicked
+ on the <b>[gateway_tt]</b> actor name in order to only display the events
+ regarding that actor:</p>
+
+ <p></p>
+
+ <image file="megaco_tracer.png">
+ <icaption>The viewer adopted for Megaco</icaption>
+ </image>
+
+ <p>A pretty printed <c>Megaco</c> message looks like this:</p>
+
+ <p></p>
+
+ <image file="megaco_filter.png">
+ <icaption>A textual <c>Megaco</c> message</icaption>
+ </image>
+
+ <p>And the corresponding internal form for the same <c>Megaco</c> message
+ looks like this:</p>
+
+ <p></p>
+
+ <image file="megaco_collector.png">
+ <icaption>The internal form of a <c>Megaco</c> message</icaption>
+ </image>
+
+ </section>
+
+</chapter>
+
diff --git a/lib/et/doc/src/et_intro.xml b/lib/et/doc/src/et_intro.xml
index 8dfa678b11..0c5fb14d55 100644
--- a/lib/et/doc/src/et_intro.xml
+++ b/lib/et/doc/src/et_intro.xml
@@ -4,7 +4,7 @@
<chapter>
<header>
<copyright>
- <year>2002</year><year>2009</year>
+ <year>2002</year><year>2010</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
@@ -13,12 +13,12 @@
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>Introduction</title>
@@ -31,65 +31,89 @@
<rev>%VSN%</rev>
<file>et_intro.xml</file>
</header>
- <p>The Event Tracer (ET) uses the built-in trace mechanism in Erlang
- and provides tools for collection and graphical viewing of trace
- data.</p>
- <p>The viewed trace data is normally collected from Erlang trace ports
- or files.</p>
+
+ <p>The <c>Event Tracer (ET)</c> uses the built-in trace mechanism in
+ Erlang and provides tools for collection and graphical viewing of
+ trace data.</p>
+
+ <p>The viewed trace data is normally collected from Erlang trace
+ ports or files.</p>
<section>
- <title>Scope and Purpose</title>
- <p>This manual describes the Event Tracer (ET) application, as a component
- of the Erlang/Open Telecom Platform development environment. It
- is assumed that the reader is familiar with the Erlang
- Development Environment, which is described in a separate User's
- Guide.</p>
+ <title>Scope and Purpose</title>'
+
+ <p>This manual describes the <c>Event Tracer (ET)</c> application,
+ as a component of the Erlang/Open Telecom Platform development
+ environment. It is assumed that the reader is familiar with the
+ Erlang Development Environment, which is described in a separate
+ User's Guide.</p>
</section>
<section>
<title>Prerequisites</title>
+
<p>The following prerequisites is required for understanding the
- material in the Event Tracer (ET) User's Guide:</p>
+ material in the <c>Event Tracer (ET)</c> User's Guide:</p>
+
<list type="bulleted">
<item>
- <p>familiarity with the Erlang system and Erlang programming in
- general and the especially the art of Erlang tracing.</p>
+ <p>familiarity with the Erlang system and Erlang programming
+ in general and the especially the art of Erlang tracing.</p>
</item>
</list>
- <p>The application requires Erlang/OTP release R7B or later.</p>
+
+ <p>The application requires Erlang/OTP release R13BB or later. If
+ you use the old <c>GS</c> based GUI it does suffice with R7B.</p>
+
</section>
<section>
<title>About This Manual</title>
- <p>In addition to this introductory chapter, the Megaco User's
- Guide contains the following chapters:</p>
+
+ <p>In addition to this introductory chapter, the <c>Event
+ Tracers</c> User's Guide contains the following chapters:</p>
+
<list type="bulleted">
<item>
- <p>Chapter 2: "Usage" describes the architecture
- and typical usage of the application.</p>
+ <p>Chapter 2: "Tutorial" provides a walk-through of the
+ various parts of the application. The tutorial is based on
+ <c>Jayson Vantuyl's</c> article
+ <c>http://souja.net/2009/04/making-sense-of-erlangs-event-tracer.html</c>.</p>
+ </item>
+
+ <item>
+ <p>Chapter 3: "Description" describes the architecture and typical
+ usage of the application.</p>
</item>
+
<item>
- <p>Chapter 3: "Examples" gives some usage examples</p>
+ <p>Chapter 4: "Advanced examples" gives some usage examples</p>
</item>
</list>
+
</section>
<section>
<title>Where to Find More Information</title>
+
<p>Refer to the following documentation for more information about
- Event Tracer (ET) and about the Erlang/OTP development system:</p>
+ <c>Event Tracer (ET)</c> and about the Erlang/OTP development system:</p>
+
<list type="bulleted">
<item>
<p>the Reference Manual of the <c>Event Tracer (ET)</c>.</p>
</item>
+
<item>
- <p>documentation of basic tracing in <c>erlang:trace/4</c> and
- <c>erlang:trace_pattern/3</c> and then the utilities derived from
- these: <c>dbg</c>, <c>observer</c> and <c>et</c>.</p>
+ <p>documentation of basic tracing in <c>erlang:trace/4</c> and
+ <c>erlang:trace_pattern/3</c> and then the utilities derived
+ from these: <c>dbg</c>, <c>observer</c>, <c>invisio</c> and
+ <c>et</c>.</p>
</item>
+
<item>
- <p>Concurrent Programming in Erlang, 2nd Edition (1996),
- Prentice-Hall, ISBN 0-13-508301-X.</p>
+ <p>Programming Erlang: Software for a Concurrent World by Joe
+ Armstrong; ISBN: 978-1-93435-600-5</p>
</item>
</list>
</section>
diff --git a/lib/et/doc/src/et_selector.xml b/lib/et/doc/src/et_selector.xml
index 59b1d3dea9..dd12166d85 100644
--- a/lib/et/doc/src/et_selector.xml
+++ b/lib/et/doc/src/et_selector.xml
@@ -4,7 +4,7 @@
<erlref>
<header>
<copyright>
- <year>2002</year><year>2009</year>
+ <year>2002</year><year>2010</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
@@ -13,12 +13,12 @@
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>et_selector</title>
@@ -35,72 +35,112 @@
<description>
<p></p>
</description>
+
<funcs>
<func>
<name>make_pattern(RawPattern) -> TracePattern</name>
<fsummary>Makes a trace pattern suitable to feed change_pattern/1</fsummary>
+
<type>
<v>RawPattern = detail_level()</v>
<v>TracePattern = erlang_trace_pattern_match_spec()</v>
- <v>detail_level() = min | max | integer(X) when X =&lt; 0, X >= 100</v>
+ <v>detail_level() = min | max | integer(X) when X &gt;= 0, X =&lt; 100</v>
</type>
+
<desc>
<p>Makes a trace pattern suitable to feed change_pattern/1</p>
- <p>Min detail level deactivates tracing of calls to phone_home/4,5</p>
- <p>Max detail level activates tracing of all calls to phone_home/4,5</p>
+ <p>Min detail level deactivates tracing of calls to <c>et:trace_me/4,5</c></p>
+ <p>Max detail level activates tracing of all calls to <c>et:trace_me/4,5</c></p>
<p>integer(X) detail level activates tracing of all calls to
- phone_home/4,5 whose detail level argument is lesser than X.</p>
- <p>See also erlang:trace_pattern/2 for more info about its match_spec()</p>
+ <c>et:trace_me/4,5</c> whose detail level argument is lesser than
+ X.</p>
+ <p>See also <c>erlang:trace_pattern/2</c> for more info about its <c>match_spec()</c></p>
</desc>
</func>
+
<func>
<name>change_pattern(Pattern) -> ok</name>
+
<fsummary>Activates/deactivates tracing by changing the current trace pattern</fsummary>
+
<type>
<v>Pattern = detail_level() | empty_match_spec() | erlang_trace_pattern_match_spec()</v>
- <v>detail_level() = min | max | integer(X) when X =&lt;0, X >= 100</v>
+ <v>detail_level() = min | max | integer(X) when X &gt;= 0, X =&lt; 100</v>
<v>empty_match_spec() = [] </v>
</type>
+
<desc>
<p>Activates/deactivates tracing by changing the current trace pattern.</p>
- <p>Min detail level deactivates tracing of calls to phone_home/4,5</p>
- <p>Max detail level activates tracing of all calls to phone_home/4,5</p>
- <p>integer(X) detail level activates tracing of all calls to
- phone_home/4,5 whose detail level argument is lesser than X.</p>
- <p>An empty match spec deactivates tracing of calls to phone_home/4,5</p>
- <p>Other match specs activates tracing of calls to phone_home/4,5
- accordingly with erlang:trace_pattern/2.</p>
+ <p><c>min</c> detail level deactivates tracing of calls to <c>et:trace_me/4,5</c></p>
+ <p><c>max</c> detail level activates tracing of all calls to <c>et:trace_me/4,5</c></p>
+ <p><c>integer(X)</c> detail level activates tracing of all
+ calls to <c>et:trace_me/4,5</c> whose detail level argument is
+ lesser than <c>X</c>.</p>
+ <p>An empty match spec deactivates tracing of calls to <c>et:trace_me/4,5</c></p>
+ <p>Other match specs activates tracing of calls to
+ <c>et:trace_me/4,5</c> accordingly with
+ <c>erlang:trace_pattern/2</c>.</p>
</desc>
</func>
<func>
<name>parse_event(Mod, ValidTraceData) -> false | true | {true, Event}</name>
+
<fsummary>Transforms trace data and makes an event record out of it</fsummary>
+
<type>
<v>Mod = module_name() | undefined &lt;v>module_name() = atom() &lt;v>ValidTraceData = erlang_trace_data() | record(event)</v>
<v>erlang_trace_data() = {trace, Pid, Label, Info} | {trace, Pid, Label, Info, Extra} | {trace_ts, Pid, Label, Info, ReportedTS} | {trace_ts, Pid, Label, Info, Extra, ReportedTS} | {seq_trace, Label, Info} | {seq_trace, Label, Info, ReportedTS} | {drop, NumberOfDroppedItems}</v>
</type>
+
<desc>
<p>Transforms trace data and makes an event record out of it.</p>
- <p>See erlang:trace/3 for more info about the semantics of
- the trace data.</p>
- <p>An event record consists of the following fields:
- detail_level - Noise has a high level as opposed to essentials.
- trace_ts - Time when the trace was generated.
- Same as event_ts if omitted in trace data.
- event_ts - Time when the event record was created.
- from - From actor, such as sender of a message.
- to - To actor, such as receiver of message.
- label - Label intended to provide a brief event summary.
- contents - All nitty gritty details of the event.</p>
- <p>See et:phone_home/4 and et:phone_home/5 for details.</p>
- <p>Returns:
- {true, Event} - where Event is an #event{} record representing the
- trace data
- true - means that the trace data already is an event
- record and that it is valid as it is.
- No transformation is needed.
- false - means that the trace data is uninteresting and
- should be dropped</p>
+
+ <p>See <c>erlang:trace/3</c> for more info about the semantics of the
+ trace data.</p>
+
+ <p>An event record consists of the following fields:</p>
+ <taglist>
+ <tag><em>detail_level</em></tag>
+ <item><p>Noise has a high level as opposed to essentials.</p></item>
+
+
+ <tag><em>trace_ts</em></tag>
+ <item><p>Time when the trace was generated. Same as
+ event_ts if omitted in trace data.</p></item>
+
+ <tag><em>event_ts</em></tag>
+ <item><p>Time when the event record was created.</p></item>
+
+ <tag><em>from</em></tag>
+ <item><p>From actor, such as sender of a message.</p></item>
+
+ <tag><em>to</em></tag>
+ <item><p>To actor, such as receiver of message.</p></item>
+
+ <tag><em>label</em></tag>
+ <item><p>Label intended to provide a brief event summary.</p></item>
+
+ <tag><em>contents</em></tag>
+ <item><p>All nitty gritty details of the event.</p></item>
+ </taglist>
+
+ <p>See <c>et:trace_me/4</c>and <c>et:trace_me/5</c> for details.</p>
+
+ <p>Returns:</p>
+ <taglist>
+ <tag><em>{true, Event}</em></tag>
+ <item><p>where Event is an #event{} record representing the
+ trace data</p></item>
+
+ <tag><em>true</em></tag>
+ <item><p>means that the trace data already is an event
+ record and that it is valid as it is. No transformation is
+ needed.</p></item>
+
+ <tag><em>false</em></tag>
+ <item><p>means that the trace data is uninteresting and
+ should be dropped</p></item>
+ </taglist>
</desc>
</func>
</funcs>
diff --git a/lib/et/doc/src/et_tutorial.xmlsrc b/lib/et/doc/src/et_tutorial.xmlsrc
new file mode 100644
index 0000000000..c72234a587
--- /dev/null
+++ b/lib/et/doc/src/et_tutorial.xmlsrc
@@ -0,0 +1,273 @@
+<?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.
+
+ </legalnotice>
+
+ <title>Tutorial</title>
+ <prepared>H&aring;kan Mattsson</prepared>
+ <responsible>H&aring;kan Mattsson</responsible>
+ <docno></docno>
+ <approved>H&aring;kan Mattsson</approved>
+ <checked></checked>
+ <date></date>
+ <rev>%VSN%</rev>
+ </header>
+
+ <section>
+ <title>Visualizing Message Sequence Charts</title>
+
+ <p>The easiest way of using <c>ET</c>, is to just use it as a
+ graphical tool for displaying message sequence charts. In order to
+ do that you need to first start a <c>Viewer</c> (which by default
+ starts a <c>Collector</c>):</p>
+
+ <code type="none"><![CDATA[
+ {ok, ViewerPid} = et_viewer:start([{title,"Coffee Order"}]),
+ CollectorPid = et_viewer:get_collector_pid(ViewerPid).]]></code>
+
+ <marker id="report_event"></marker>
+ <p>Then you send events to the <c>Collector</c>
+ with the function <c>et_collector:report_event/6</c> like this:</p>
+
+ <code type="none"><![CDATA[
+ et_collector:report_event(CollectorPid,85,from,to,message,extra_stuff).]]></code>
+
+ <p>The <c>Viewer</c> will automatically pull events from the
+ <c>Collector</c> and display them on the screen.</p>
+
+ <p>The number (in this case 85) is an integer from 1 to 100 that
+ specifies the "detail level" of the message. The higher the
+ number, the more important it is. This provides a crude form of
+ priority filtering.</p>
+
+ <p>The <c>from</c>, <c>to</c>, and <c>message</c> parameters are
+ exactly what they sound like. <c>from</c> and <c>to</c> are
+ visualized in the <c>Viewer</c> as "lifelines", with the message
+ passing from one to the other. If <c>from</c> and <c>to</c> are
+ the same value, then it is displayed next to the lifeline as an
+ "action". The <c>extra_stuff </c>value is simply data that you can
+ attach that will be displayed when someone actually clicks on the
+ action or message in the <c>Viewer</c> window.</p>
+
+ <p>The module <c>et/examples/et_display_demo.erl</c> illustrates
+ how it can be used:</p>
+
+ <codeinclude file="../../examples/et_display_demo.erl" tag="%module" type="erl"></codeinclude>
+
+ <p>When you run the <c>et_display_demo:test().</c> function in the
+ example above, the <c>Viewer</c> window will look like this:</p>.
+
+ <p></p>
+
+ <image file="coffee_order.png">
+ <icaption>Screenshot of the <c>Viewer</c> window</icaption>
+ </image>
+
+ </section>
+
+ <section>
+ <title>Four Modules</title>
+
+ <p>The event tracer framework is made up of four modules:</p>
+
+ <list type="bulleted">
+ <item><p><c>et</c></p></item>
+ <item><p><c>et_collector</c></p></item>
+ <item><p><c>et_viewer</c></p></item>
+ <item><p><c>et_selector</c></p></item>
+ </list>
+
+ <p>In addition, you'll probably want to familiarize yourself with
+ the <c>dbg</c> module and possibly <c>seq_trace</c> module as
+ well.</p>
+ </section>
+
+ <section>
+ <title>The Event Tracer Interface</title>
+
+ <p>The <c>et</c> module is not like other modules. It contains a
+ function called <c>et:trace_me/5</c>. Which is a function that
+ does not do any useful stuff at all. Its sole purpose is to be a
+ function that is easy to trace. A call to it may be something
+ like:</p>
+
+ <code type="none"><![CDATA[
+ et:trace_me(85,from,to,message,extra_stuff).]]></code>
+
+ <p>The parameters to <c>et:trace_me/5</c> are the same as to
+ <seealso
+ marker="#report_event"><c>et_collector:report_event/6</c></seealso>
+ in the previous chapter. The big difference between the two is in
+ the semantics of the two functions. The second actually reports an
+ <c>Event</c> to the <c>Collector</c> while the first does nothing,
+ it just returns the atom <c>hopefully_traced</c>. In order to make
+ the parameters to <c>et:trace_me/5</c> turn up in the
+ <c>Collector</c>, tracing of that function must be activated and
+ the <c>Collector</c> must be registered as a <c>Tracer</c> of the
+ <c>Raw Trace Data</c>.</p>
+
+ <p>Erlang tracing is a seething pile of pain that involves
+ reasonably complex knowledge of clever ports, tracing return
+ formats, and specialized tracing <c>MatchSpecs</c> (which are
+ really their own special kind of hell). The tracing mechanism is
+ very powerful indeed, but it can be hard to grasp.</p>
+
+ <p>Luckily there is a simplified way to start tracing of
+ <c>et:trace_me/5</c> function calls. The idea is that you should
+ instrument your code with calls to <c>et:trace_me/5</c> in
+ strategic places where you have interesting information available
+ in your program. Then you just start the <c>Collector</c> with
+ global tracing enabled:</p>
+
+ <code type="none"><![CDATA[
+ et_viewer:start([{trace_global, true}, {trace_pattern, {et,max}}]).]]></code>
+
+ <p>This will start a <c>Collector</c>, a <c>Viewer</c> and also
+ start the tracing of <c>et:trace_me/5</c> function calls. The
+ <c>Raw Trace Data</c> is collected by the <c>Collector</c> and a
+ view of it is displayed on the screen by the <c>Viewer</c>. You
+ can define your own "views" of the data by implementing your own
+ <c>Filter</c> functions and register them in the
+ <c>Viewer</c>.</p>
+ </section>
+
+ <section>
+ <title>The Collector and Viewer</title>
+
+ <p>These two pieces work in concert. Basically, the
+ <c>Collector</c> receives <c>Raw Trace Data</c> and processes it
+ into <c>Events</c> in a <c>et</c> specific format (defined in
+ <c>et/include/et.hrl</c>). The <c>Viewer</c> interrogates the
+ <c>Collector</c> and displays an interactive representation of the
+ data.</p>
+
+ <p>You might wonder why these aren't just one module. The
+ <c>Collector</c> is a generic full-fledged framework that allows
+ processes to "subscribe" to the <c>Events</c> that it
+ collects. One <c>Collector</c> can serve several
+ <c>Viewers</c>. The typical case is that you have one
+ <c>Viewer</c> that visualizes <c>Events</c> in one flavor and
+ another <c>Viewer</c> that visualizes them in another flavor. If
+ you for example are tracing a text based protocol like <c>HTML</c>
+ (or <c>Megaco/H.248</c>) it would be useful to be able to display
+ the <c>Events</c> as plain text as well as the internal
+ representation of the message. The architecture does also allow
+ you to implement your own <c>Viewer</c> program as long as it
+ complies to the protocol between the <c>Collector/Viewer</c>
+ protocol. Currently two kinds of <c>Viewers</c> exists. That is
+ the old <c>GS</c> based one and the new based on
+ <c>wxWidgets</c>. But if you feel for it you may implement your
+ own <c>Viewer</c>, which for example could display the
+ <c>Events</c> as ASCII art or whatever you feel useful.</p>
+
+ <p>The <c>Viewer</c> will by default create a <c>Collector</c> for
+ you. With a few options and some configuration settings you can
+ start collecting <c>Events</c>.</p>
+
+ <p>The <c>Collector</c> API does also allow you to save the
+ collected <c>Events</c> to file and later load them in a later
+ session.</p>
+
+ </section>
+
+ <section>
+ <title>The Selector</title>
+
+ <p>This is perhaps the most central module in the entirety of the
+ <c>et</c> suite. The <c>Collector</c> needs "filters" to convert
+ the <c>Raw Trace Data</c> into "events" that it can display. The
+ <c>et_selector</c> module provides the default <c>Filter</c> and
+ some API calls to manage the <c>Trace Pattern</c>. The
+ <c>Selector</c> provides various functions that achieve the
+ following:</p>
+
+ <list type="bulleted">
+ <item><p>Convert <c>Raw Trace Data</c> into an appropriate
+ <c>Event</c></p></item>
+ <item><p>Magically notice traces of the <c>et:trace_me/5</c>
+ function and make appropriate <c>Events</c></p></item>
+ <item><p>Carefully prevent translating the <c>Raw Trace Data</c>
+ twice</p></item>
+ <item><p>Manage a <c>Trace Pattern</c></p></item>
+ </list>
+
+ <p>The <c>Trace Pattern</c> is basically a tuple of a
+ <c>module</c> and a <c>detail level</c> (either an integer or the
+ atom max for full detail). In most cases the <c>Trace Pattern</c>
+ <c>{et,max}</c> does suffice. But if you do not want any runtime
+ dependency of <c>et</c> you can implement your own
+ <c>trace_me/5</c> function in some module and refer to that module
+ in the <c>Trace Pattern</c>.</p>
+
+ <p>The specified module flows from your instantiation of the
+ <c>Viewer</c>, to the <c>Collector</c> that it automatically
+ creates, gets stashed in as the <c>Trace Pattern</c>, and
+ eventually goes down into the bowels of the <c>Selector</c>.</p>
+
+ <p>The module that you specify gets passed down (eventually) into
+ <c>Selector</c>'s default <c>Filter</c>. The format of the
+ <c>et:trace_me/5</c> function call is hardcoded in that
+ <c>Filter</c>.</p>
+
+ </section>
+
+ <section>
+ <title>How To Put It Together</title>
+
+ <p>The <c>Collector</c> automatically registers itself to listen
+ for trace <c>Events</c>, so all you have to do is enable them.</p>
+
+ <p>For those people who want to do general tracing, consult the
+ <c>dbg</c> module on how to trace whatever you're interested in
+ and let it work its magic. If you just want <c>et:trace_me/5</c>
+ to work, do the following:</p>
+
+ <list type="ordered">
+ <item><p>Create a <c>Collector</c></p></item>
+ <item><p>Create a <c>Viewer</c> (this can do step #1 for you)</p></item>
+ <item><p>Turn on and pare down debugging</p></item>
+ </list>
+
+ <p>The module <c>et/examples/et_trace_demo.erl</c> achieves this.</p>
+
+ <codeinclude file="../../examples/et_trace_demo.erl" tag="%module" type="erl"></codeinclude>
+
+ <p>Running through the above, the most important points are:</p>
+
+ <list type="bulleted">
+ <item><p>Turn on global tracing</p></item>
+ <item><p>Set a <c>Trace Pattern</c></p></item>
+ <item><p>Tell <c>dbg</c> to trace function Calls</p></item>
+ <item><p>Tell it specifically to trace the <c>et:trace_me/5</c> function</p></item>
+ </list>
+
+ <p>When you run the <c>et_trace_demo:test()</c> function above, the
+ <c>Viewer</c> window will look like this screenshot:</p>.
+
+ <p></p>
+
+ <image file="coffee_order.png">
+ <icaption>Screenshot of the <c>Viewer</c> window</icaption>
+ </image>
+
+ </section>
+
+</chapter>
diff --git a/lib/et/doc/src/et_viewer.xml b/lib/et/doc/src/et_viewer.xml
index a3e34ac06e..c16e5b8869 100644
--- a/lib/et/doc/src/et_viewer.xml
+++ b/lib/et/doc/src/et_viewer.xml
@@ -4,7 +4,7 @@
<erlref>
<header>
<copyright>
- <year>2002</year><year>2009</year>
+ <year>2002</year><year>2010</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
@@ -13,12 +13,12 @@
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>et_viewer</title>
@@ -72,7 +72,7 @@
<fsummary>Start a sequence chart viewer for trace events (messages/actions)</fsummary>
<type>
<v>Options = [option() | collector_option()]</v>
- <v>option() = {parent_pid, extended_pid()} | {title, term()} | {detail_level, detail_level()} | {is_suspended, boolean()} | {scale, integer()} | {width, integer()} | {height, integer()} | {collector_pid, extended_pid()} | {event_order, event_order()} | {active_filter, atom()} | {max_events, extended_integer()} | {max_actors, extended_integer()} | {trace_pattern, et_collector_trace_pattern()} | {trace_port, et_collector_trace_port()} | {trace_global, et_collector_trace_global()} | {trace_client, et_collector_trace_client()} | {dict_insert, {filter, filter_name()}, event_filter_fun()} | {dict_insert, et_collector_dict_key(), et_collector_dict_val()} | {dict_delete, {filter, filter_name()}} | {dict_delete, et_collector_dict_key()} | {actors, actors()} | {first_event, first_key()} | {hide_unknown, boolean()} | {hide_actions, boolean()} | {display_mode, display_mode()}</v>
+ <v>option() = {parent_pid, extended_pid()} | {title, term()} | {detail_level, detail_level()} | {is_suspended, boolean()} | {scale, integer()} | {width, integer()} | {height, integer()} | {collector_pid, extended_pid()} | {event_order, event_order()} | {active_filter, atom()} | {max_actors, extended_integer()} | {trace_pattern, et_collector_trace_pattern()} | {trace_port, et_collector_trace_port()} | {trace_global, et_collector_trace_global()} | {trace_client, et_collector_trace_client()} | {dict_insert, {filter, filter_name()}, event_filter_fun()} | {dict_insert, et_collector_dict_key(), et_collector_dict_val()} | {dict_delete, {filter, filter_name()}} | {dict_delete, et_collector_dict_key()} | {actors, actors()} | {first_event, first_key()} | {hide_unknown, boolean()} | {hide_actions, boolean()} | {display_mode, display_mode()}</v>
<v>extended_pid() = pid() | undefined</v>
<v>detail_level() = min | max | integer(X) when X >=0, X =&lt; 100</v>
<v>event_order() = trace_ts | event_ts</v>
@@ -113,7 +113,6 @@
<item>collector_pid - undefined.</item>
<item>event_order - trace_ts.</item>
<item>active_filter - collector.</item>
- <item>max_events - 100.</item>
<item>max_actors - 5.</item>
<item>actors - ["UNKNOWN"].</item>
<item>first_event - first.</item>
diff --git a/lib/et/doc/src/fascicules.xml b/lib/et/doc/src/fascicules.xml
deleted file mode 100644
index 0678195e07..0000000000
--- a/lib/et/doc/src/fascicules.xml
+++ /dev/null
@@ -1,18 +0,0 @@
-<?xml version="1.0" encoding="latin1" ?>
-<!DOCTYPE fascicules SYSTEM "fascicules.dtd">
-
-<fascicules>
- <fascicule file="part" href="part_frame.html" entry="no">
- User's Guide
- </fascicule>
- <fascicule file="ref_man" href="ref_man_frame.html" entry="yes">
- Reference Manual
- </fascicule>
- <fascicule file="part_notes" href="part_notes_frame.html" entry="no">
- Release Notes
- </fascicule>
- <fascicule file="" href="../../../../doc/print.html" entry="no">
- Off-Print
- </fascicule>
-</fascicules>
-
diff --git a/lib/et/doc/src/files.mk b/lib/et/doc/src/files.mk
index 13d6cf4d74..41fffb83f1 100644
--- a/lib/et/doc/src/files.mk
+++ b/lib/et/doc/src/files.mk
@@ -1,19 +1,19 @@
#-*-makefile-*- ; force emacs to enter makefile-mode
# %CopyrightBegin%
-#
-# Copyright Ericsson AB 2002-2009. All Rights Reserved.
-#
+#
+# Copyright Ericsson AB 2002-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%
XML_APPLICATION_FILES = \
@@ -26,32 +26,27 @@ XML_REF3_FILES = \
et_viewer.xml
XML_PART_FILES = \
- part.xml \
- part_notes.xml
+ part.xml
XML_CHAPTER_FILES = \
et_intro.xml \
- et_architecture.xml \
+ et_tutorial.xml \
+ et_desc.xml \
et_examples.xml \
notes.xml
BOOK_FILES = book.xml
-GIF_FILES = \
- book.gif \
- live_trans.gif \
- megaco_collector.gif \
- megaco_filter.gif \
- megaco_tracer.gif \
- note.gif \
- notes.gif \
- ref_man.gif \
- sim_trans.gif \
- sim_trans_contents_viewer_collector.gif \
- sim_trans_contents_viewer_mgr_actors.gif \
- sim_trans_mgr_actors.gif \
- sim_trans_move_actor.gif \
- sim_trans_write_lock.gif \
- user_guide.gif \
- warning.gif
+IMAGE_FILES = \
+ coffee_order.png \
+ live_trans.png \
+ megaco_collector.png \
+ megaco_filter.png \
+ megaco_tracer.png \
+ sim_trans.png \
+ sim_trans_contents_viewer_collector.png \
+ sim_trans_contents_viewer_mgr_actors.png \
+ sim_trans_mgr_actors.png \
+ sim_trans_move_actor.png \
+ sim_trans_write_lock.png
diff --git a/lib/et/doc/src/live_trans.gif b/lib/et/doc/src/live_trans.gif
deleted file mode 100644
index e2070f89e9..0000000000
--- a/lib/et/doc/src/live_trans.gif
+++ /dev/null
Binary files differ
diff --git a/lib/et/doc/src/live_trans.png b/lib/et/doc/src/live_trans.png
new file mode 100644
index 0000000000..94192697d2
--- /dev/null
+++ b/lib/et/doc/src/live_trans.png
Binary files differ
diff --git a/lib/et/doc/src/live_trans.ps b/lib/et/doc/src/live_trans.ps
deleted file mode 100644
index 8855f2694b..0000000000
--- a/lib/et/doc/src/live_trans.ps
+++ /dev/null
@@ -1,1559 +0,0 @@
-%!PS-Adobe-3.0 EPSF-3.0
-%%Creator: GIMP PostScript file plugin V 1.12 by Peter Kirchgessner
-%%Title: /home/hakan/picts/live_trans.ps
-%%CreationDate: Mon Oct 14 17:29:47 2002
-%%DocumentData: Clean7Bit
-%%LanguageLevel: 2
-%%Pages: 1
-%%BoundingBox: 14 14 429 326
-%%EndComments
-%%BeginProlog
-% Use own dictionary to avoid conflicts
-10 dict begin
-%%EndProlog
-%%Page: 1 1
-% Translate for offset
-14.173228 14.173228 translate
-% Translate to begin of first scanline
-0.000000 310.991634 translate
-414.655512 -310.991634 scale
-% Image geometry
-496 372 8
-% Transformation matrix
-[ 496 0 0 372 0 0 ]
-% Strings to hold RGB-samples per scanline
-/rstr 496 string def
-/gstr 496 string def
-/bstr 496 string def
-{currentfile /ASCII85Decode filter /RunLengthDecode filter rstr readstring pop}
-{currentfile /ASCII85Decode filter /RunLengthDecode filter gstr readstring pop}
-{currentfile /ASCII85Decode filter /RunLengthDecode filter bstr readstring pop}
-true 3
-%%BeginData: 85402 ASCII Bytes
-colorimage
-!AQV60nB=U!.b->!<4eQ3Ih~>
-r'Z)9JH16$RfN@SJ,~>
-"DW"!C3+q+JH16$RfEJ1CAr:)~>
-r]0uYnc&U&JcC<$JcFp5!56GQrr<*\0faa~>
-r^?bdnc&U'JcC<$JcFp5!5?MRrrE$dJ,~>
-rcA)>nc&U&JcC<$JcFp5!56GQrrE%>J,~>
-s"OQTs8VWG!53s6J^o>%kLBRGa56ja!WY5@J,~>
-s$Qngs8VWC!5=$8J_#D'kLKXIa4gR]!WYVVJ,~>
-s)S5As8VWG!53s6J^o>%kLBRGa56ja!W[:_J,~>
-!]^8\n(n&XJ^o>%J^rr6!56A.!lY-oJ,~>
-!^m%gn(IcUJ_#D'J_'#8!5?G+!l=q*J,~>
-!cnAAn(n&XJ^o>%J^rr6!56A.!lY.\J,~>
-!\j]Tn(n&XT%*h[J^s#8!6'N>jOF7D`SL[8!&9!~>
-!^m%gn(IcUT%3qbdXg!7ecEqAdanHHQIZ&M`S(C1!(;>~>
-!cnAAn(n&XT%*h[J^s#8!6'N>jOF7D`SL[8!-<Y~>
-!<E/fh>k7Cec1lXeHNpfe\-<VrfmH5!J>a8eH(S\^t&ILpXKAZH[D":eHLSPe^]nKpXK:sHi;Iq
-UqN;K!57RPpRLp5s.'&Es.'#D!NZ9O~>
-!<E/fg&Sk@f)LlVedTEhf"Q]`R?<W_eq&Cgf)LTBf)Lm,ecWX;I@9*Gs+14$s,m',s+1."!MR5t
-ec<GIg@q$.gAdT>gAdT=g&\>VJ,~>
-!<E/fh>k7Cec1lXeHNpfe\-<VrfmH5!J>a8eH(S\^t&ILpXKAZH[D":eHLSPe^]nKpXK:sHi;Iq
-UqN;K!57RPpRLp5s.'&Es.'#D!NZ9O~>
-!<E/thZ',ChZ',Eh>k7dec0srMuM6.UjIaYec1m+eH*Y&gsm"UHaM=]Hc=O"Ph"<:He$Zc]uAM&
-K6tDas-39.!fMEEiRJ*aHe$Z2PkW]/K7!RI!jm<nS^d_RkMGs'p>5b<s5*^ErS@RV!.Y~>
-!<E/tf)M08f)M0:ec<G]df4^qNW.?-Tm_XZdf5I%dK.4ngsQeOJ[X!dIE'QpOj_[/J^Vu`[`-\p
-J\]_6On[9+NIAglimRjXs3gq0pX9(mrR(bUID29#!5@XIpR1a+rL*]:rL*W8!NlEQ~>
-!<E/thZ',ChZ',Eh>k7dec0srMuM6.UjIaYec1m+eH*Y&gsm"UHaM=]Hc=O"Ph"<:He$Zc]uAM&
-K6tDas-39.!fMEEiRJ*aHe$Z2PkW]/K7!RI!jm<nS^d_RkMGs'p>5b<s5*^ErS@RV!.Y~>
-!<E/uhYiuChYiuDh>k7dec'n!c.1?sH\:&&!J>aSeHLkqe^];!qpbk&He$Z!Hc=M9K6suU!J>aW
-eH(;Lo@3koHi2CpP`)*_!57RPpRLs6pRM3=!NZ9O~>
-!<E/uf);$8f);$9ec<G]df+Xub0n^lI>-D's+/tR"c8MmdXcuHdf4mudf4m;df4m*df4mVdf4mi
-df4mrdK,ViS^IMPkLTBqp=Au+rRM"P!.Y~>
-!<E/uhYiuChYiuDh>k7dec'n!c.1?sH\:&&!J>aSeHLkqe^];!qpbk&He$Z!Hc=M9K6suU!J>aW
-eH(;Lo@3koHi2CpP`)*_!57RPpRLs6pRM3=!NZ9O~>
-!<E/uhY`oDhY`oCh>k7deL>itHaM>BH\6t$eVf@!K6suUe]!GnK='1Z`J](iK>#ffHe$*"H[C[i
-r7(eCrd,^*Mi4Zp`KY^rMoF5sXG_FPMp9ekMgL)`e^]S9XGd&-"MK/qeXZVc#gJ!Ke^];!eYN1k
-s2>D)H\8]UeVf?eMq*H,qpk_)*PI)P[+3-[H[C[ie^]S9]n:[=["E_4e^_WsH\8^)eHDChK6qt?
-ec1O<["F:]e^]S9XGbW1MgLA`rm_pgMgKf/c.0dkH\8]Ue]!GnH\9#^`J](iK>%*2$\NfVeVf@!
-K6suUSGmj=c)chMMlc['s,.5tK6suUeZ=[UMlcp.)2!:deUr5!eVf@!K6suUeUr5!c$QPB]mIGa
-eH!;GhY3Q5hYE]>h>s\XJ,~>
-!<E/uf)1s9f)1s8ec<G]dOBTuIBq;<JUrO'dZ'6tKn6PXd__,pKsK.T_NBCtKsoE\J^VQ#JUNNl
-r6bS=rd>j)NK'co`fYh#NP<ihY).RTM9=8`OaVqhdaF,7V2bH%"M0#md[C)_#g.^LdaE\td\6Yg
-s2#2,I>+uTdZ'6_NREB/qpPM(*P-rUZI6aTJUNNldaF,7[Y9:8[Y9:<daH!pI>,!+dKH+lJUN+E
-df5:;[Xj:TdaF,7V2`p+M1(5`rmD^fM1'f/b0n.hI>+uTd__,tI>,,X_NBCtKspg*s+13us,@2n
-Kn6PXRJqU<b-$SLM6?U$s,@AsKn6PXd]SFTM6?j+s+13us+13us,@Q#Kn6PXdXcttb(6S@[XG`Y
-dK%#Ef(YU*f(ka3ecDoRJ,~>
-!<E/uhY`oDhY`oCh>k7deL>itHaM>BH\6t$eVf@!K6suUe]!GnK='1Z`J](iK>#ffHe$*"H[C[i
-r7(eCrd,^*Mi4Zp`KY^rMoF5sXG_FPMp9ekMgL)`e^]S9XGd&-"MK/qeXZVc#gJ!Ke^];!eYN1k
-s2>D)H\8]UeVf?eMq*H,qpk_)*PI)P[+3-[H[C[ie^]S9]n:[=["E_4e^_WsH\8^)eHDChK6qt?
-ec1O<["F:]e^]S9XGbW1MgLA`rm_pgMgKf/c.0dkH\8]Ue]!GnH\9#^`J](iK>%*2$\NfVeVf@!
-K6suUSGmj=c)chMMlc['s,.5tK6suUeZ=[UMlcp.)2!:deUr5!eVf@!K6suUeUr5!c$QPB]mIGa
-eH!;GhY3Q5hYE]>h>s\XJ,~>
-!<E/teb>U4eH!;[bpe"0H^)dNP_4V5c%CA$S9on5`IifVP^CBoMgMhE[(X_:Hd07*]sN-Er66G)
-H[EHNK6rNP]r\oSH]-.EH],8<UrC<*K>!Lr`Qa$^Mkp<r,+O#!c,G$V^!21Vc-:lfc,G$V]u>VV
-]p*l_c%CA$Us4gMqopL@H]+D@K?_*2]sN-Ec-:lfMk#-@Mk#-Hc,G<f]p*l_c(o]^]mG,$bqF]r
-Pa$NZc-:lfMkmG$PeE<.XNdPfMmTje`PmI^]p*l_c&6qU]sPJtMgMhE[(Z:['n^kXc%CA$S9on5
-`HusFXF$2FP^BM,bpe9lMk#-Hc)c8V]p*lFc-:lfc-:lfc-:lfMk#-Hc-:lfc'4.2c,G%"T$78K
-kLBR&q:,J8o[Wi/qpb_K!.Y~>
-!<E/tdeB1.dK%#Yc7+14I?i*SR>$@?c@LD#Tm_X?b(58XQ$pZtM1)hH[_C%<J^2!4^:&HHr6?M+
-JUPD\JUNBO^952YI>Q7GI>P8<WlE24Kt<Ot`m0-`M5C0r,,'G)cGkE`_Tm^`cH^ulcGkE`_T%.\
-\s7]`c@LD#V9XpSqp$R?I>OYGL!IE8^:&HHcH^uhNM1cKNM1cScH:]l\s7]`cCoZ[^4Ck1c7a`s
-Od1?[cH^uhM5@5#Q+iN3Wm7GhM6aRi`l`jd\s7]`cA?tX^:(c$M1)hH[_DR_s+13q&V5@eTm_X?
-`drQTWdU/HQ$o\-c7+<mM4o?OcDl;X^6O,HcH^ulcH^ulcH^uhM4o?OcH^ulcB4+3cGk:+T$@>M
-kL'?uq9f82o[<W)qpGMJ!.Y~>
-!<E/teb>U4eH!;[bpe"0H^)dNP_4V5c%CA$S9on5`IifVP^CBoMgMhE[(X_:Hd07*]sN-Er66G)
-H[EHNK6rNP]r\oSH]-.EH],8<UrC<*K>!Lr`Qa$^Mkp<r,+O#!c,G$V^!21Vc-:lfc,G$V]u>VV
-]p*l_c%CA$Us4gMqopL@H]+D@K?_*2]sN-Ec-:lfMk#-@Mk#-Hc,G<f]p*l_c(o]^]mG,$bqF]r
-Pa$NZc-:lfMkmG$PeE<.XNdPfMmTje`PmI^]p*l_c&6qU]sPJtMgMhE[(Z:['n^kXc%CA$S9on5
-`HusFXF$2FP^BM,bpe9lMk#-Hc)c8V]p*lFc-:lfc-:lfc-:lfMk#-Hc-:lfc'4.2c,G%"T$78K
-kLBR&q:,J8o[Wi/qpb_K!.Y~>
-!<E/sebPa5eH!;[boM/,P^CZ5["F"Uc%CA^c$Of^XF$J^XF%%nMgLu-rlkIrHiD7l`P$nVqoo:s
-Hd0ffHi;1o`P$nVc%CA^rQPYMH^r?^H`YJEHi)%gP^EDS(k[1[c%CAfc%CAfc%CAfXF$J^XF%%n
-K7!=:"bV0@c$Og:boXj;K7hFnK6tS^H[E`VH[F#=H^r?^H`YJEHc=6^Hhbi$K6tk^H\9SfK6tkf
-K6tS^`I!6^K6tT9bmUV"SB\-^XNcZMSA"pH",hMr^%]bdK6tkfK6tS^H[F#^K6tjqHc=7KH\;+<
-,_LH_c$Of^K6tS^`I!6^c%CAfc%CAfc%CA^c$Of^c%CAEHbKF'!IL'&blGH?eGu-8eGu-3ebbm6
-eH)`OJ,~>
-!<E/sdeT=/dK%#Yc5h>0Ob(Z3ZA""Xc@LD`c@LPlY'm"dY'mIuM1(r3rm(OprltV_^4D"8cMrIq
-c2rQFb5TZk_S1STc@p\`rQYbQIA+fdIBLkHIEMK5!L8*4cMrIqcMrIqcMrIqcMrG'cE;Shb-$/q
-c@LDdpW`qnIE'Q`Jc<q9_S1STcH^uhb0GQdb0GQhcE;Shb-$/qc@p\hc@LQAc5(tZb/Sj\cH^uh
-b0Gil`m2SPM9^g'_YqafY'm"dY'mIuM1(r3rltV&I@\7LcMrIqc4PVU`m0-dcH^ulcA?thcGk9h
-ps(.9IE'Q`J^0+#`m2SPM9aCtJ^2PlJ^2PlIE'Q`J^2PlJZaF<rltOmQ(H8$^?<oERJG82RInr)
-RJYD5XoNt~>
-!<E/sebPa5eH!;[boM/,P^CZ5["F"Uc%CA^c$Of^XF$J^XF%%nMgLu-rlkIrHiD7l`P$nVqoo:s
-Hd0ffHi;1o`P$nVc%CA^rQPYMH^r?^H`YJEHi)%gP^EDS(k[1[c%CAfc%CAfc%CAfXF$J^XF%%n
-K7!=:"bV0@c$Og:boXj;K7hFnK6tS^H[E`VH[F#=H^r?^H`YJEHc=6^Hhbi$K6tk^H\9SfK6tkf
-K6tS^`I!6^K6tT9bmUV"SB\-^XNcZMSA"pH",hMr^%]bdK6tkfK6tS^H[F#^K6tjqHc=7KH\;+<
-,_LH_c$Of^K6tS^`I!6^c%CAfc%CAfc%CA^c$Of^c%CAEHbKF'!IL'&blGH?eGu-8eGu-3ebbm6
-eH)`OJ,~>
-!<E/rebbm6eH!;[bn>B!XF$aic%CYnc%CAfc%CAfV#5QOUs6lCH[C[ac%CAf]n:rqH\;4?&;,>S
-c%CAfc+Sa^MgL*$H[G\8!2TO>"/O1oHi)%gP^EDS%tf5Rc%CAfc%CAfc%CAfV#5QAUs4O=p<=M.
-Hd0ffHd06VK8Y)/c-:lfc-:lfc-:lfc(t8a#GfUkHd0ffHhbhpK6tkfH[F#^K6tkfH[Gb:s*Fgl
-H[G\8!2TO>%]%@gP^@b8^!4N\H[C[aq99J'Hd0ffHd0ffHd0ffHd-narltIiprs(sHd0ffHd-na
-rltIis3271Hd0ffHd0ffHd0ffHd0ffH\6[arlkIjPb-,"^&6C\^%n/u^%TtVSGC\8SFtG.SG^n<
-X8mb~>
-!<E/rdefI0dK%#Yc4YQ%Y'm<ub(YPpc@LPlc@LPlV>P`RV9ZrCI=7*hc@LPl\qP]pI>.RDs+13q
-s+13q#eG_@NI?N+I=;%=!2]UA"/X:oJc!^nQ$rYWs+13qs+13qs+13qs+(3rV>P`DV9XXCp<N\h
-s3CXq'[F:DJW5)3cH^ulcH^ulcH^ulcDCGe#Go^oIEp,hJb[OjJcF$qIK.UmJcF!rJUROCs*Xso
-I=;%=!2]UA%].IfQ$n(?^<XT\I=7*hq9K"ks3CXqs3CXqs3CXq!mZ@Frm(Olps/njs3CXq!mZ@F
-rm(Ols3CXqs3CXqs3CXqs3CXqs3:auI>NNprltOmQ(H8$^AQCZ](q`o](XPPRJG82RJ##(RJbJ6
-XoNt~>
-!<E/rebbm6eH!;[bn>B!XF$aic%CYnc%CAfc%CAfV#5QOUs6lCH[C[ac%CAf]n:rqH\;4?&;,>S
-c%CAfc+Sa^MgL*$H[G\8!2TO>"/O1oHi)%gP^EDS%tf5Rc%CAfc%CAfc%CAfV#5QAUs4O=p<=M.
-Hd0ffHd06VK8Y)/c-:lfc-:lfc-:lfc(t8a#GfUkHd0ffHhbhpK6tkfH[F#^K6tkfH[Gb:s*Fgl
-H[G\8!2TO>%]%@gP^@b8^!4N\H[C[aq99J'Hd0ffHd0ffHd0ffHd-narltIiprs(sHd0ffHd-na
-rltIis3271Hd0ffHd0ffHd0ffHd0ffH\6[arlkIjPb-,"^&6C\^%n/u^%TtVSGC\8SFtG.SG^n<
-X8mb~>
-!<E/qebu$7eH!;[bnPN#`Hurrc%CYnc%CAfc%CAfXF$K6bmhXfH\9RqHd.Iqc-:lnqoo_*Hd0ff
-Hd0fnHd0ffK?]$q^&?1WXF$K8blNHDqoonPHc=7SK6tkfK6tkfK6tkfK6tkEH^t#Y!J>amboD@_
-c-:lfc&6qnc%CYnc%CAfc%CAfc%CAfXF$K8blr`H`Q`aVprsS,Hd0NVK?_YnHd0ffHc=7KH\9Rq
-HbKC&!j$a=qTT,]UjIanblbq\H\;.='n^kXc%CAfc%CAfc%CAfK6tS^`I!74bpe9lc-:lfc%CA^
-c,G$^c-:lfc-:lfc-:lfc-:lfc-:lf[!S%^c,G%"T$78Kr71P3p=0/5q:,J8p=8o-rRCqM!.Y~>
-!<E/qdf#U1dK%#Yc4k]'`dN9#c@pttc@LPlc@LPlY'm#?c4.deI>,stJ^07+b0G]pqp,4ms3CXq
-s3:q1J]c8lL!GC#^AZ=YY'm#AcMrImc5*+%`m2k\J^2PlJ^2PlJ^2PlJ^1EHU&<49JbIChJcF$q
-JJQOjJ]c8lL!ItpJ^2PlJ^2PlJ^1EHU&<1>JUP\`JV!UAs+(m0b'euhc@LPlcA?thcGk9hc@p\\
-rQYJIIA-M_"3.$_L&T@"`h@g7q9K"ks3CXqs3CXqs3CXq#L80S`m2SPM>5BrJcF$qJKrHsIE'RP
-I>Q7pJUu+lJUu+lJUu+lJUu+lJUt7XQ-R[pIA*7X!5ABZpR1a'!1EZ2!1EQ/pR2!.!NlEQ~>
-!<E/qebu$7eH!;[bnPN#`Hurrc%CYnc%CAfc%CAfXF$K6bmhXfH\9RqHd.Iqc-:lnqoo_*Hd0ff
-Hd0fnHd0ffK?]$q^&?1WXF$K8blNHDqoonPHc=7SK6tkfK6tkfK6tkfK6tkEH^t#Y!J>amboD@_
-c-:lfc&6qnc%CYnc%CAfc%CAfc%CAfXF$K8blr`H`Q`aVprsS,Hd0NVK?_YnHd0ffHc=7KH\9Rq
-HbKC&!j$a=qTT,]UjIanblbq\H\;.='n^kXc%CAfc%CAfc%CAfK6tS^`I!74bpe9lc-:lfc%CA^
-c,G$^c-:lfc-:lfc-:lfc-:lfc-:lf[!S%^c,G%"T$78Kr71P3p=0/5q:,J8p=8o-rRCqM!.Y~>
-!<E/pec208eH!;[bpn(9c&6qMc%CYnc%CAfc%CAfc%CA=[&gXZUpRhBH]-.$Hd.IqXK6bq^&6+s
-K6suMK6tkfMgMP,H[EH-H\8E5XMrG:H_e$M[*=5Mqop.pHaM&BK6tkfK6tkfK6tkfK6suEK6sE$
-XL-6)HiD7jMhCoO-\Hcjc%CAfMgMP,H[EHNK6tkfK6tkfK6tkfK6sE$XL-6:H^'bAHhbi=K6t;-
-H_ep2K6tkfXF$2FP^BLVXF#T$]r]2tK6sE$XL-6J[(WhnMp8')]sN-Eq99Y,Hd0ffHd0ffHd0ff
-Hd/X=PeE<.XSC$hK6tkfK6tkEH^)4.H`YK:K6tkfK6tkfK6tkfK6tkfK6tk-HaM&)HbH#q!58<\
-pRLs-!1`l8!1`c5rLEo<rLEi:!NZ9O~>
-!<E/pcMs1*c2bTUasqh5b)(PLb(YPlb(5,db(5,d`eAi;[]ZpYTsDD<I>Q*tJ]`gtWiCJq^AQ+q
-M1)hPJUttdM1)D(I=8i0I>+i4Wkuc0IAOBTZH@`LqoTqjIBL`8JUttdJUttdJUttdM1)hLKmff+
-Y-Q3$Jc<glM>PHqJcEmmJK`0mIB';qID3jTJ]c,dJ]c,dJ]budIAOBTZHAG\Q'$KGpr`Vf/\[p,
-TutN/J]c-8I?hC/IAP)dI>+i4Wkuc0IAOBTZHAlH^9W0Db+Z,[email protected]*b5[%mb5[%mb5[%mb5["t
-b,TlT\s7]?pr`Vfs2t@m,Kd$7Q+E6/V96r3J]c,dJ]c,dJ]c,dJ]c,dJ]a7+Y0*nq[[tVA^AQ:N
-Q1iK'Q2/]*Q1iN%Q2f/.Q2Su/XoNt~>
-!<E/pec208eH!;[bpn(9c&6qMc%CYnc%CAfc%CAfc%CA=[&gXZUpRhBH]-.$Hd.IqXK6bq^&6+s
-K6suMK6tkfMgMP,H[EH-H\8E5XMrG:H_e$M[*=5Mqop.pHaM&BK6tkfK6tkfK6tkfK6suEK6sE$
-XL-6)HiD7jMhCoO-\Hcjc%CAfMgMP,H[EHNK6tkfK6tkfK6tkfK6sE$XL-6:H^'bAHhbi=K6t;-
-H_ep2K6tkfXF$2FP^BLVXF#T$]r]2tK6sE$XL-6J[(WhnMp8')]sN-Eq99Y,Hd0ffHd0ffHd0ff
-Hd/X=PeE<.XSC$hK6tkfK6tkEH^)4.H`YK:K6tkfK6tkfK6tkfK6tkfK6tk-HaM&)HbH#q!58<\
-pRLs-!1`l8!1`c5rLEo<rLEi:!NZ9O~>
-!<E/feH!;[bpn(9c+U4'c%CYnc%CAfc%CAfc,GooH\8EEP_4=0Pf:n"Hd/pMH^pmYSG^VR["E_=
-K6tkf["E^qUjJWVXG_FPMoEr[P^@b0XNcBEqT]%us32C5Hd0ffHd0ffHd0gBK6t;NP^@b0XNcBE
-rlkIrHi)&8K6tkfK6tkMK6s,aH^r?5Hd0ffHd0ffHd0gSP^@b0XNe_BK=$8Xprrekrd+X8rlkIr
-HiD7mXFkkPXT$H_XG_FPMoEr[P^@b0XNcu^H[D!rc'3j-H^)MFbnPeWc-:lfc-:lfc-:lfc-<>B
-H\8Eobm]5Oc-:lfc-<>BH\8F!bnu([c-:lfc-:lfc-:lfc-:lfc,G<f`J]YFblGHTeH!;YS,g7r
-eb>U,ec20<ec20;eH)`OJ,~>
-!<E/fc2bTUasqh5b.=Umb(YPlb(5,db(5,db/0EpI>+iHQ%=@7Q+kClJ]bETI@['[RJb2LZ@RS<
-JUttd[Y9.#Tm`?OWel.PM8%-LQ%=@;Y0)<HqTAhts2t@ms2t@ms2t@ms2kbUJUtDLQ%=@;Y0)<H
-rlY7lqo\qis2t@m+j.6II@['[REC)3b0#9db0#9db0%SdJUN6Tb/0!dY(;0!aom9DI=[gcb5[%l
-aonPpI>+^#ar7::I=6sdb/0EpI>+iHQ%=@7Q+kD+JUN*7^A5qOJcEmmJcEmmJcEmmJcEjqV1j>O
-WqX[9JcEmmJcEjqV1j>OWrC0@JcEmmJcEmmJcEmmJcEmmJHj9:JUth#NLe2l^AQ7V[eZ0g[eA#@
-Q1`H&Q2T#.Q2Jo.XoNt~>
-!<E/feH!;[bpn(9c+U4'c%CYnc%CAfc%CAfc,GooH\8EEP_4=0Pf:n"Hd/pMH^pmYSG^VR["E_=
-K6tkf["E^qUjJWVXG_FPMoEr[P^@b0XNcBEqT]%us32C5Hd0ffHd0ffHd0gBK6t;NP^@b0XNcBE
-rlkIrHi)&8K6tkfK6tkMK6s,aH^r?5Hd0ffHd0ffHd0gSP^@b0XNe_BK=$8Xprrekrd+X8rlkIr
-HiD7mXFkkPXT$H_XG_FPMoEr[P^@b0XNcu^H[D!rc'3j-H^)MFbnPeWc-:lfc-:lfc-:lfc-<>B
-H\8Eobm]5Oc-:lfc-<>BH\8F!bnu([c-:lfc-:lfc-:lfc-:lfc,G<f`J]YFblGHTeH!;YS,g7r
-eb>U,ec20<ec20;eH)`OJ,~>
-!<E/feH!:YblYk:XL$1JHNLm5Hdg79HN:bEc2)be^"^d5XFnK_blGGqeH)`OJ,~>
-!<E/fc2bSSao]G2V6e>@I0.!2J^_d<I/pkDb5-Md]%b@/We&$XaoK/oc2k'JJ,~>
-!<E/feH!:YblYk:XL$1JHNLm5Hdg79HN:bEc2)be^"^d5XFnK_blGGqeH)`OJ,~>
-!<E/fblGGP`<!ZJX2P*lH\TK?UqN;;!56=q!NZ9O~>
-!<E/faoK/N`W<fIX2b0jL;j7f^7<1C^;S.pXoNt~>
-!<E/fblGGP`<!ZJX2P*lH\TK?UqN;;!56=q!NZ9O~>
-!<E/fblGG.`QQ7#XF\?_`;mTiblOmGJ,~>
-!<E/faoK/,`llC%Y(=Tb`W3`kaoSXFJ,~>
-!<E/fblGG.`QQ7#XF\?_`;mTiblOmGJ,~>
-!<E/fblGG.`IZ!Z`TP2?]u8.rX8mb~>
-!<E/faoK/,`du-\`ok>A^;S.pXoNt~>
-!<E/fblGG.`IZ!Z`TP2?]u8.rX8mb~>
-!!%S&JV/N+PCii8J,~>
-!!%S$JUrB'PCW]6J,~>
-!!%S&JV/N+PCii8J,~>
-!<E0!joD3.s+13$s.0/nV#TT>]`<Q~>
-!<E0!joD*+s+13$s.0/nU&X9;\c@6~>
-!<E0!joD3.s+13$s.0/nV#TT>]`<Q~>
-!<E0!joD3.s+13$s.95pK;AP0k.LbF~>
-!<E0!joD*+s+13$s.95pJYE,+k.1PC~>
-!<E0!joD3.s+13$s.95pK;AP0k.LbF~>
-!<E0!joV@Ys+/^OeUc8Eec17*V#TT>]`<Q~>
-!<E0!joV7Vs+/mTg4@tOgAc^-U&X9;\c@6~>
-!<E0!joV@Ys+/^OeUc8Eec17*V#TT>]`<Q~>
-!<E0!joV@Ys+/^OeUc8Eec17*V#TT>]`<Q~>
-!<E0!joV7Vs+/mTg4@tOgAc^-U&X9;\c@6~>
-!<E0!joV@Ys+/^OeUc8Eec17*V#TT>]`<Q~>
-!<E0!joV@Ys+/^OeUc8Eec17*V#TT>]`<Q~>
-!<E0!joV7Vs+/mTg4@tOgAc^-U&X9;\c@6~>
-!<E0!joV@Ys+/^OeUc8Eec17*V#TT>]`<Q~>
-!<E0!joV@Ys+/^OeUc8Eec17*V#TT>]`<Q~>
-!<E0!joV7Vs+/mTg4@tOgAc^-U&X9;\c@6~>
-!<E0!joV@Ys+/^OeUc8Eec17*V#TT>]`<Q~>
-!<E0!joV@Ys+/^OeUc8Eec17*V#TT>]`<Q~>
-!<E0!joV7Vs+/mTg4@tOgAc^-U&X9;\c@6~>
-!<E0!joV@Ys+/^OeUc8Eec17*V#TT>]`<Q~>
-!<E0!joV@Ys+/^OeUc8Eec17*V#TT>]`<Q~>
-!<E0!joV7Vs+/mTg4@tOgAc^-U&X9;\c@6~>
-!<E0!joV@Ys+/^OeUc8Eec17*V#TT>]`<Q~>
-!<E0!joV@Ys+/^OeUc8Eec17*V#TT>]`<Q~>
-!<E0!joV7Vs+/mTg4@tOgAc^-U&X9;\c@6~>
-!<E0!joV@Ys+/^OeUc8Eec17*V#TT>]`<Q~>
-!<E0!joV@Ys8(:A!!:[N!:A>:!<(IH!7TKs!;Y1F!!:[N!:eV>!9Vi-!!^sR!7fU"!9Vi3!<1OK
-!;Y1F!.i[OebI\pK*A(Nk2s>WJ,~>
-!<E0!joV7Vs8(IF!!:jS!:AM?!<(XM!7T[#!;Y@K!!:jS!:eeC!9W#2!!_-W!8?-,!9W#8!<1^P
-!;Y@K!.ijTgA'D%JH_bIk2s5TJ,~>
-!<E0!joV@Ys8(:A!!:[N!:A>:!<(IH!7TKs!;Y1F!!:[N!:eV>!9Vi-!!^sR!7fU"!9Vi3!<1OK
-!;Y1F!.i[OebI\pK*A(Nk2s>WJ,~>
-!<E0!joV@Ys8(:G!;b7G!:A>:!<(IJ!7KEt!<:UL!;b7G!!:[N!:eV>!9Vi3!;b7G!<:UL!9Vi3
-!<1OK!;Y1F!.i[OebI\pK*A(Nk2s>WJ,~>
-!<E0!joV7Vs8(IL!;bFL!:AM?!<(XO!7KU$!<:dQ!;bFL!!:jS!:eeC!9W#8!;bFL!<:dQ!9W#8
-!<1^P!;Y@K!.ijTgA'D%JH_bIk2s5TJ,~>
-!<E0!joV@Ys8(:G!;b7G!:A>:!<(IJ!7KEt!<:UL!;b7G!!:[N!:eV>!9Vi3!;b7G!<:UL!9Vi3
-!<1OK!;Y1F!.i[OebI\pK*A(Nk2s>WJ,~>
-!<E0!joV@Ys8(:G!<(IJ!!LgP!7fWu!:n\?!<:UL!!LgP!7fWu!<:UL!<:UL!<:UL!<:UJ!<:UL
-!!:[N!;+hA!;k=F!<:UL!!LgP!7fWu!<1OI!<:UJ!<:UJ!<:UL!!:[N!;+hA!<(IJ!!CaO!7h#J
-s4.&Js4.,L!n@8No[WsArmh#Ks4.&Js4.,L"k<SQeGoT#eUc9Mec17*V#TT>]`<Q~>
-!<E0!joV7Vs8(IL!<(XO!!M!U!8?0*!:nkD!<:dQ!!M!U!8?0*!<:dQ!<:dQ!<:dQ!<:dO!<:dQ
-!!:jS!;,"F!;kLK!<:dQ!!M!U!8?0*!<1^N!<:dO!<:dO!<:dQ!!:jS!;,"F!<(XO!!CpT!8@AO
-s4[DOs4[JQ!nmVSo\0<Frn@APs4[DOs4[JQ"kiqVg&M,(g4@uWgAc^-U&X9;\c@6~>
-!<E0!joV@Ys8(:G!<(IJ!!LgP!7fWu!:n\?!<:UL!!LgP!7fWu!<:UL!<:UL!<:UL!<:UJ!<:UL
-!!:[N!;+hA!;k=F!<:UL!!LgP!7fWu!<1OI!<:UJ!<:UJ!<:UL!!:[N!;+hA!<(IJ!!CaO!7h#J
-s4.&Js4.,L!n@8No[WsArmh#Ks4.&Js4.,L"k<SQeGoT#eUc9Mec17*V#TT>]`<Q~>
-!<E0!joV@Ys8(:G!<(IJ!"%0U!7_&Le^XX"o@<j@s4.,L*7Y#heGoU"eGoU"!!(R"!!(R"!!(OL
-!7fU"!7guIo[WsAr71fIs4.,L+OpGleGoU"!!(R"!!(OL!7fU"!7fU"!7fU"!7fU"!7guIo[WsA
-rRLoJ&(LX[e^XX"e^XX"e^XX"ebfF>ec,XKec,UVeGoU"eGoU"!!(RK!!:[N!.i[Oec42"K*A(N
-k2s>WJ,~>
-!<E0!joV7Vs8(IL!<(XO!"%?Z!87DQg=cN,o@j3Es4[JQ*81Amg&M-,g&M-,!!(a,!!(a,!!(^Q
-!8?-,!8@>No\0<Fr7_/Ns4[JQ+PHeqg&M-,!!(a,!!(^Q!8?-,!8?-,!8?-,!8?-,!8@>No\0<F
-rS%8O&)%!`g=cN,g=cN,g=cN,gACsCgA_0PgA_-[g&M-,g&M-,!!(aP!!:jS!.ijTgAfn,JH_bI
-k2s5TJ,~>
-!<E0!joV@Ys8(:G!<(IJ!"%0U!7_&Le^XX"o@<j@s4.,L*7Y#heGoU"eGoU"!!(R"!!(R"!!(OL
-!7fU"!7guIo[WsAr71fIs4.,L+OpGleGoU"!!(R"!!(OL!7fU"!7fU"!7fU"!7fU"!7guIo[WsA
-rRLoJ&(LX[e^XX"e^XX"e^XX"ebfF>ec,XKec,UVeGoU"eGoU"!!(RK!!:[N!.i[Oec42"K*A(N
-k2s>WJ,~>
-!<E0!joV@Ys8(:D!"@BX!7_&LeGoU"eGoU@ec,XLec,UheGoU"!!(R"!!(R"!!(OL!7_&Le^XX"
-e^XX"ec#R>ec,XIec,XLec,U[eGoU"!!(OL!7fU"!7_&Lqpk]Hs4.,Ls4.,L!7h&Ko%!X<'%Hs^
-eGoU"eGoU"eGoU"eGoU"rW)N>q>_)W!!(R"!!(OL!7_&Le^XX"J^o>%s4..%"f21\k.LbF~>
-!<E0!joV7Vs8(II!"@Q]!87DQg&M-,g&M-EgA_0QgA_-mg&M-,!!(a,!!(a,!!(^Q!87DQg=cN,
-g=cN,gAV*CgA_0NgA_0QgA_-`g&M-,!!(^Q!8?-,!87DQqqD&Ms4[JQs4[JQ!8@DPo%O!A'&!<c
-g&M-,g&M-,g&M-,g&M-,rW)NCq>_)\!!(a,!!(^Q!87DQg=cN,J_G\/s4[L("ektYk.1PC~>
-!<E0!joV@Ys8(:D!"@BX!7_&LeGoU"eGoU@ec,XLec,UheGoU"!!(R"!!(R"!!(OL!7_&Le^XX"
-e^XX"ec#R>ec,XIec,XLec,U[eGoU"!!(OL!7fU"!7_&Lqpk]Hs4.,Ls4.,L!7h&Ko%!X<'%Hs^
-eGoU"eGoU"eGoU"eGoU"rW)N>q>_)W!!(R"!!(OL!7_&Le^XX"J^o>%s4..%"f21\k.LbF~>
-!<E0!joV@Ys8(:G!<(IJ!!CaO!7grHo$n!Ge^XZMeGoU"qZ-ZHrr<;S!!(OL!7fWs!!:[N!:eV>
-!;tCI!<:UL!!^sR!7_&Leb]=JeGoUHec,XLec,XLec,UNeGoU>ec,XJec,UTeGoU"eGoU"eb]=J
-eGoU>ec,XKec,ULeb]=QeGoU"!!(R"!!%T#J^seNs+:KNs5rIW!.Y~>
-!<E0!joV7Vs8(IL!<(XO!!CpT!8@;Mo%F?Lg=cP\g&M-,qZ-ZMrr<;X!!(^Q!8?0(!!:jS!:eeC
-!;tRN!<:dQ!!_-W!87DQgA:jOg&M-MgA_0QgA_0QgA_-Sg&M-CgA_0OgA_-Yg&M-,g&M-,gA:jO
-g&M-CgA_0PgA_-QgA:jVg&M-,!!(a,!!%T(J_L.Xs+(?Is5rIT!.Y~>
-!<E0!joV@Ys8(:G!<(IJ!!CaO!7grHo$n!Ge^XZMeGoU"qZ-ZHrr<;S!!(OL!7fWs!!:[N!:eV>
-!;tCI!<:UL!!^sR!7_&Leb]=JeGoUHec,XLec,XLec,UNeGoU>ec,XJec,UTeGoU"eGoU"eb]=J
-eGoU>ec,XKec,ULeb]=QeGoU"!!(R"!!%T#J^seNs+:KNs5rIW!.Y~>
-!<E0!joV@Ys8(:G!<(IJ!!UmQ!7_&Lma_79s4.,L!n@8Nqpk]H$.T"UeGoU"eGoUIec,X>ec,XI
-ec,XLec,UTeGoU"!!(OL!;tCI!;k=H!<:UL!<:UL!!:[N!:eV>!<(IJ!".6V!7fU"!7fU"!;tCI
-!:eV>!<1OK!!:[N!;tCI!!^sR!7fU"!.i[Oec42"K*A(Nk2s>WJ,~>
-!<E0!joV7Vs8(IL!<(XO!!V'V!87DQmb7U>s4[JQ!nmVSqqD&M$/,@Zg&M-,g&M-NgA_0CgA_0N
-gA_0QgA_-Yg&M-,!!(^Q!;tRN!;kLM!<:dQ!<:dQ!!:jS!:eeC!<(XO!".E[!8?-,!8?-,!;tRN
-!:eeC!<1^P!!:jS!;tRN!!_-W!8?-,!.ijTgAfn,JH_bIk2s5TJ,~>
-!<E0!joV@Ys8(:G!<(IJ!!UmQ!7_&Lma_79s4.,L!n@8Nqpk]H$.T"UeGoU"eGoUIec,X>ec,XI
-ec,XLec,UTeGoU"!!(OL!;tCI!;k=H!<:UL!<:UL!!:[N!:eV>!<(IJ!".6V!7fU"!7fU"!;tCI
-!:eV>!<1OK!!:[N!;tCI!!^sR!7fU"!.i[Oec42"K*A(Nk2s>WJ,~>
-!<E0!joV@Ys8(:G!<(IJ!"%0U!7_&Le^XX"n^[X>rmh#K#1W\Re^XX"rmh#Ks4.,Lrmh#Ks4.,L
-!n@8NnC@O=s4.&Js4.,L(tATdeGoU"!!(R"!!(OL!7fU"!7fU"!7h&Ks4.,L!n@8Nn^[X>rRLoJ
-#LreSe^XX"ec#RKec,UNeGoU>ec,XKec,UVeGoU"eGoU"!!(RK!!:[N!.i[Oec42"K*A(Nk2s>W
-J,~>
-!<E0!joV7Vs8(IL!<(XO!"%?Z!87DQg=cN,n_4!Crn@AP#20%Wg=cN,rn@APs4[JQrn@APs4[JQ
-!nmVSnCmmBs4[DOs4[JQ(tnrig&M-,!!(a,!!(^Q!8?-,!8?-,!8@DPs4[JQ!nmVSn_4!CrS%8O
-#MK.Xg=cN,gAV*PgA_-Sg&M-CgA_0PgA_-[g&M-,g&M-,!!(aP!!:jS!.ijTgAfn,JH_bIk2s5T
-J,~>
-!<E0!joV@Ys8(:G!<(IJ!"%0U!7_&Le^XX"n^[X>rmh#K#1W\Re^XX"rmh#Ks4.,Lrmh#Ks4.,L
-!n@8NnC@O=s4.&Js4.,L(tATdeGoU"!!(R"!!(OL!7fU"!7fU"!7h&Ks4.,L!n@8Nn^[X>rRLoJ
-#LreSe^XX"ec#RKec,UNeGoU>ec,XKec,UVeGoU"eGoU"!!(RK!!:[N!.i[Oec42"K*A(Nk2s>W
-J,~>
-!<E0!joV@Ys8(:G!<(IJ!!LgP!7fWu!:\P=!<1OK!<:UJ!<(IJ!<:UL!<(IH!<:UL!:SJ:!<:UJ
-!<:UL!!LgP!7fWu!<1OI!<(IJ!<:UJ!<:UL!:eV>!<(IJ!!:[N!<1OK!<:UJ!<:UL!:eV>!<1OK
-!<:UJ!<:UL!!UmQ!7_&LJ^o>%rmh%$"f21\k.LbF~>
-!<E0!joV7Vs8(IL!<(XO!!M!U!8?0*!:\_B!<1^P!<:dO!<(XO!<:dQ!<(XM!<:dQ!:SY?!<:dO
-!<:dQ!!M!U!8?0*!<1^N!<(XO!<:dO!<:dQ!:eeC!<(XO!!:jS!<1^P!<:dO!<:dQ!:eeC!<1^P
-!<:dO!<:dQ!!V'V!87DQJ_G\/rn@C'"ektYk.1PC~>
-!<E0!joV@Ys8(:G!<(IJ!!LgP!7fWu!:\P=!<1OK!<:UJ!<(IJ!<:UL!<(IH!<:UL!:SJ:!<:UJ
-!<:UL!!LgP!7fWu!<1OI!<(IJ!<:UJ!<:UL!:eV>!<(IJ!!:[N!<1OK!<:UJ!<:UL!:eV>!<1OK
-!<:UJ!<:UL!!UmQ!7_&LJ^o>%rmh%$"f21\k.LbF~>
-!<E0!joV@Ys+/_"ec,W#eUc9Jec17*V#TT>]`<Q~>
-!<E0!joV7Vs+/n'gA_/(g4@uTgAc^-U&X9;\c@6~>
-!<E0!joV@Ys+/_"ec,W#eUc9Jec17*V#TT>]`<Q~>
-!<E0!joV@Ys+/_"ec,W#eUc9Jec17*V#TT>]`<Q~>
-!<E0!joV7Vs+/n'gA_/(g4@uTgAc^-U&X9;\c@6~>
-!<E0!joV@Ys+/_"ec,W#eUc9Jec17*V#TT>]`<Q~>
-!<E0!joV@Ys+/_"ec,W#eUc9Jec17*V#TT>]`<Q~>
-!<E0!joV7Vs+/n'gA_/(g4@uTgAc^-U&X9;\c@6~>
-!<E0!joV@Ys+/_"ec,W#eUc9Jec17*V#TT>]`<Q~>
-!<E0!joV@Ys+/^OeUc8Eec17*V#TT>]`<Q~>
-!<E0!joV7Vs+/mTg4@tOgAc^-U&X9;\c@6~>
-!<E0!joV@Ys+/^OeUc8Eec17*V#TT>]`<Q~>
-!<E0!joV@Ys+/^OeUc8Eec17*V#TT>]`<Q~>
-!<E0!joV7Vs+/mTg4@tOgAc^-U&X9;\c@6~>
-!<E0!joV@Ys+/^OeUc8Eec17*V#TT>]`<Q~>
-!<E0!joV@Ys+/^OeUc8Eec17*V#TT>]`<Q~>
-!<E0!joV7Vs+/mTg4@tOgAc^-U&X9;\c@6~>
-!<E0!joV@Ys+/^OeUc8Eec17*V#TT>]`<Q~>
-!<E0!joV@Ys+/^OeUc8Eec17*V#TT>]`<Q~>
-!<E0!joV7Vs+/mTg4@tOgAc^-U&X9;\c@6~>
-!<E0!joV@Ys+/^OeUc8Eec17*V#TT>]`<Q~>
-!<E0!joV@Ys+/^OeUc8Eec17*V#TT>]`<Q~>
-!<E0!joV7Vs+/mTg4@tOgAc^-U&X9;\c@6~>
-!<E0!joV@Ys+/^OeUc8Eec17*V#TT>]`<Q~>
-!<E0!joV@Ys+,fRK7SZIK*A(Nk2s>WJ,~>
-!<E0!joV7Vs+,`PJUrBEJH_bIk2s5TJ,~>
-!<E0!joV@Ys+,fRK7SZIK*A(Nk2s>WJ,~>
-!<E0!joM:XJV/N+JV0PH"f21\k.LbF~>
-!<E0!joM1UJUrB'JUsDD"ektYk.1PC~>
-!<E0!joM:XJV/N+JV0PH"f21\k.LbF~>
-!<E0!joD3.eUc8%eXb4oV#TT>]`<Q~>
-!<E0!joD*+g4@t/g7?q$U&X9;\c@6~>
-!<E0!joD3.eUc8%eXb4oV#TT>]`<Q~>
-!<E0!joD3.eUc8%eXb4oV#TT>]`<Q~>
-!<E0!joD*+g4@t/g7?q$U&X9;\c@6~>
-!<E0!joD3.eUc8%eXb4oV#TT>]`<Q~>
-!<E0!joD3.eUc8%eXb4oV#TT>]`<Q~>
-!<E0!joD*+g4@t/g7?q$U&X9;\c@6~>
-!<E0!joD3.eUc8%eXb4oV#TT>]`<Q~>
-!<E0!joD3.eUc8%eXb4oV#TT>]`<Q~>
-!<E0!joD*+g4@t/g7?q$U&X9;\c@6~>
-!<E0!joD3.eUc8%eXb4oV#TT>]`<Q~>
-!<E0!joD3.eUc8%eXb4oV#TT>]`<Q~>
-!<E0!joD*+g4@t/g7?q$U&X9;\c@6~>
-!<E0!joD3.eUc8%eXb4oV#TT>]`<Q~>
-!<E0!joD3.eUc8%eXb4oV#TT>]`<Q~>
-!<E0!joD*+g4@t/g7?q$U&X9;\c@6~>
-!<E0!joD3.eUc8%eXb4oV#TT>]`<Q~>
-!<E0!joD3.eUc8%eXb4oV#TT>]`<Q~>
-!<E0!joD*+g4@t/g7?q$U&X9;\c@6~>
-!<E0!joD3.eUc8%eXb4oV#TT>]`<Q~>
-!<E0!joD3.eUc8%eXb4oV#TT>]`<Q~>
-!<E0!joD*+g4@t/g7?q$U&X9;\c@6~>
-!<E0!joD3.eUc8%eXb4oV#TT>]`<Q~>
-!<E0!joD3.eUc8%eXb4oV#TT>]`<Q~>
-!<E0!joD*+g4@t/g7?q$U&X9;\c@6~>
-!<E0!joD3.eUc8%eXb4oV#TT>]`<Q~>
-!<E0!joD3.eUc8%eXb4oV#TT>]`<Q~>
-!<E0!joD*+g4@t/g7?q$U&X9;\c@6~>
-!<E0!joD3.eUc8%eXb4oV#TT>]`<Q~>
-!<E0!joD3.e`#'V!;=tC!;P+E!!:[N!;k=H!9_o4!.i[OeHMcKk2s>WJ,~>
-!<E0!joD*+g>Uc`!;>.H!;P:J!!:jS!;kLM!9`)9!.ijTg'+2Mk2s5TJ,~>
-!<E0!joD3.e`#'V!;=tC!;P+E!!:[N!;k=H!9_o4!.i[OeHMcKk2s>WJ,~>
-!<E0!joD3.e`#'Y!<:UL!;G%D!;4nB!;k=H!9_o4!.i[OeHMcKk2s>WJ,~>
-!<E0!joD*+g>Ucc!<:dQ!;G4I!;5(G!;kLM!9`)9!.ijTg'+2Mk2s5TJ,~>
-!<E0!joD3.e`#'Y!<:UL!;G%D!;4nB!;k=H!9_o4!.i[OeHMcKk2s>WJ,~>
-!<E0!joD4Keb9%=eb]?&ec,XKec,XLeboLJeboLJeboLJec,UNeGoUHec,XIeboLJec,XKec,XL
-eboLJec,W#eUc6SV#TT>]`<Q~>
-!<E0!joD+Hg@kRBgA:l+gA_0PgA_0QgAM$OgAM$OgAM$OgA_-Sg&M-MgA_0NgAM$OgA_0PgA_0Q
-gAM$OgA_/(g4@r]U&X9;\c@6~>
-!<E0!joD4Keb9%=eb]?&ec,XKec,XLeboLJeboLJeboLJec,UNeGoUHec,XIeboLJec,XKec,XL
-eboLJec,W#eUc6SV#TT>]`<Q~>
-!<E0!joD4KebB(DKDF't!//o&!<1OK!#X5d!7fU"!7fU"!7fU"!7fU"!7_&LeGoUHec,XJec,XL
-ec,UNeGoUKec,UUeGoU"eGoU"!!%T#J^jq"s5rIW!.Y~>
-!<E0!joD+Hg@tUIJbe%"!/0)+!<1^P!#XDi!8?-,!8?-,!8?-,!8?-,!87DQg&M-MgA_0OgA_0Q
-gA_-Sg&M-PgA_-Zg&M-,g&M-,!!%T(J_C:$s5rIT!.Y~>
-!<E0!joD4KebB(DKDF't!//o&!<1OK!#X5d!7fU"!7fU"!7fU"!7fU"!7_&LeGoUHec,XJec,XL
-ec,UNeGoUKec,UUeGoU"eGoU"!!%T#J^jq"s5rIW!.Y~>
-!<E0!joD4Kec5[Gec19tec,XJec,UOeGoU"r;ciIr;clJquHcIr;`_FrrE&Krr<DV!!(R"!!(R"
-!!)oHrr<5Q!!(OL!;k=H!<(IJ!<:UL!<:UL!"IHY!7fU"!7fU"!7_&LJ^o>%"f21\k.LbF~>
-!<E0!joD+HgAh3LgAca"gA_0OgA_-Tg&M-,r;ciNr;clOquHcNr;`_KrrE&Prr<D[!!(a,!!(a,
-!!)oMrr<5V!!(^Q!;kLM!<(XO!<:dQ!<:dQ!"IW^!8?-,!8?-,!87DQJ_G\/"ektYk.1PC~>
-!<E0!joD4Kec5[Gec19tec,XJec,UOeGoU"r;ciIr;clJquHcIr;`_FrrE&Krr<DV!!(R"!!(R"
-!!)oHrr<5Q!!(OL!;k=H!<(IJ!<:UL!<:UL!"IHY!7fU"!7fU"!7_&LJ^o>%"f21\k.LbF~>
-!<E0!joD4Kec5[Gec19tec,XJebT:Gec,UReGoU"eGoUJec,UReGoU"eGoTIec,XKec,ULeb]@H
-ec,XKebfCNeGoU"!!)oHrrE#JqZ-ZHrr<2P!!(R"qZ$]J!!%T#J^jq"s5rIW!.Y~>
-!<E0!joD+HgAh3LgAca"gA_0OgA1gLgA_-Wg&M-,g&M-OgA_-Wg&M-,g&M,NgA_0PgA_-QgA:mM
-gA_0PgACpSg&M-,!!)oMrrE#OqZ-ZMrr<2U!!(a,qZ$]O!!%T(J_C:$s5rIT!.Y~>
-!<E0!joD4Kec5[Gec19tec,XJebT:Gec,UReGoU"eGoUJec,UReGoU"eGoTIec,XKec,ULeb]@H
-ec,XKebfCNeGoU"!!)oHrrE#JqZ-ZHrr<2P!!(R"qZ$]J!!%T#J^jq"s5rIW!.Y~>
-!<E0!joD4Kec5[Gec19tebfCIec#RKec,XLec,UReGoU"eGoUKec,XLec,XLec,WIec,XKec,UN
-eGoUHec,XLec,XLec,UQeGoU"!!)oHrrE#JrrDoGrW)rJrrDuIrr@W#J^jq"s5rIW!.Y~>
-!<E0!joD+HgAh3LgAca"gACpNgAV*PgA_0QgA_-Wg&M-,g&M-PgA_0QgA_0QgA_/NgA_0PgA_-S
-g&M-MgA_0QgA_0QgA_-Vg&M-,!!)oMrrE#OrrDoLrW)rOrrDuNrr@W(J_C:$s5rIT!.Y~>
-!<E0!joD4Kec5[Gec19tebfCIec#RKec,XLec,UReGoU"eGoUKec,XLec,XLec,WIec,XKec,UN
-eGoUHec,XLec,XLec,UQeGoU"!!)oHrrE#JrrDoGrW)rJrrDuIrr@W#J^jq"s5rIW!.Y~>
-!<E0!joD4Kec5[Gec19tec,XJec,XKeb]=Heb]@GeGoUKeb]?Eec,XLec,XLec,XLec,XLec,UL
-ec#RKec,UQeGoU"!!)oHrrE#JrrE)LrrE&KrW)rJrrE)Lrr<,N!!%T#J^jq"s5rIW!.Y~>
-!<E0!joD+HgAh3LgAca"gA_0OgA_0PgA:jMgA:mLg&M-PgA:lJgA_0QgA_0QgA_0QgA_0QgA_-Q
-gAV*PgA_-Vg&M-,!!)oMrrE#OrrE)QrrE&PrW)rOrrE)Qrr<,S!!%T(J_C:$s5rIT!.Y~>
-!<E0!joD4Kec5[Gec19tec,XJec,XKeb]=Heb]@GeGoUKeb]?Eec,XLec,XLec,XLec,XLec,UL
-ec#RKec,UQeGoU"!!)oHrrE#JrrE)LrrE&KrW)rJrrE)Lrr<,N!!%T#J^jq"s5rIW!.Y~>
-!<E0!joD4Kec5[Gec19tec,XJec,XKec,XIec,XHec,XKec,WEebfFGeboLHec,XLec#OKeboIL
-eGoUHeb]=HeboLGeGoUIeboLJec,W#eUc6SV#TT>]`<Q~>
-!<E0!joD+HgAh3LgAca"gA_0OgA_0PgA_0NgA_0MgA_0PgA_/JgACsLgAM$MgA_0QgAV'PgAM!Q
-g&M-MgA:jMgAM$Lg&M-NgAM$OgA_/(g4@r]U&X9;\c@6~>
-!<E0!joD4Kec5[Gec19tec,XJec,XKec,XIec,XHec,XKec,WEebfFGeboLHec,XLec#OKeboIL
-eGoUHeb]=HeboLGeGoUIeboLJec,W#eUc6SV#TT>]`<Q~>
-!<E0!joD4Kec5[Gec19tec,XJec,XKec,XLec,UUeGoU"eGoU"!!)uJrrE)Lrr@W#J^o>%j4+=/
-s5rIW!.Y~>
-!<E0!joD+HgAh3LgAca"gA_0OgA_0PgA_0QgA_-Zg&M-,g&M-,!!)uOrrE)Qrr@W(J_G\/j4X[1
-s5rIT!.Y~>
-!<E0!joD4Kec5[Gec19tec,XJec,XKec,XLec,UUeGoU"eGoU"!!)uJrrE)Lrr@W#J^o>%j4+=/
-s5rIW!.Y~>
-!<E0!joD4Kec5[Gec19tec,XJec,XJeboLIeboLJebfFIeboK!eUc8%e`,*_V#TT>]`<Q~>
-!<E0!joD+HgAh3LgAca"gA_0OgA_0OgAM$NgAM$OgACsNgAM#&g4@t/g>^fiU&X9;\c@6~>
-!<E0!joD4Kec5[Gec19tec,XJec,XJeboLIeboLJebfFIeboK!eUc8%e`,*_V#TT>]`<Q~>
-!<E0!joD4Kec5[EK7VR(eUc8ZeHMcKk2s>WJ,~>
-!<E0!joD+HgAh3JJUuO+g4@tdg'+2Mk2s5TJ,~>
-!<E0!joD4Kec5[EK7VR(eUc8ZeHMcKk2s>WJ,~>
-!<E0!joD3.eUc8%eXb4oV#TT>]`<Q~>
-!<E0!joD*+g4@t/g7?q$U&X9;\c@6~>
-!<E0!joD3.eUc8%eXb4oV#TT>]`<Q~>
-!<E0!joD3.eUc8%eXb4oV#TT>]`<Q~>
-!<E0!joD*+g4@t/g7?q$U&X9;\c@6~>
-!<E0!joD3.eUc8%eXb4oV#TT>]`<Q~>
-!<E0!joD3.eUc8%eXb4oV#TT>]`<Q~>
-!<E0!joD*+g4@t/g7?q$U&X9;\c@6~>
-!<E0!joD3.eUc8%eXb4oV#TT>]`<Q~>
-!<E0!joD3.eUc8%eXb4oV#TT>]`<Q~>
-!<E0!joD*+g4@t/g7?q$U&X9;\c@6~>
-!<E0!joD3.eUc8%eXb4oV#TT>]`<Q~>
-!<E0!joD3.eUc8dec,XJeboLIeboK!eaM#lV#TT>]`<Q~>
-!<E0!joD*+g4@tngA_0OgAM$NgAM#&g@*`!U&X9;\c@6~>
-!<E0!joD3.eUc8dec,XJeboLIeboK!eaM#lV#TT>]`<Q~>
-!<E0!joD3.eUc8feboLIec,XLec,UReGoU"eGoT#eaV)mV#TT>]`<Q~>
-!<E0!joD*+g4@tpgAM$NgA_0QgA_-Wg&M-,g&M,(g@3f"U&X9;\c@6~>
-!<E0!joD3.eUc8feboLIec,XLec,UReGoU"eGoT#eaV)mV#TT>]`<Q~>
-!<E0!joD3.eUc8dec,XKec,XLec,UReGoU"eGoT#eaV)mV#TT>]`<Q~>
-!<E0!joD*+g4@tngA_0PgA_0QgA_-Wg&M-,g&M,(g@3f"U&X9;\c@6~>
-!<E0!joD3.eUc8dec,XKec,XLec,UReGoU"eGoT#eaV)mV#TT>]`<Q~>
-!<E0!joD3.eUc8dec,XKec,XLec,UReGoU"eGoT#eaV)mV#TT>]`<Q~>
-!<E0!joD*+g4@tngA_0PgA_0QgA_-Wg&M-,g&M,(g@3f"U&X9;\c@6~>
-!<E0!joD3.eUc8dec,XKec,XLec,UReGoU"eGoT#eaV)mV#TT>]`<Q~>
-!<E0!joD3.eUc8dec,XKec,XLec,UReGoU"eGoT#eaV)mV#TT>]`<Q~>
-!<E0!joD*+g4@tngA_0PgA_0QgA_-Wg&M-,g&M,(g@3f"U&X9;\c@6~>
-!<E0!joD3.eUc8dec,XKec,XLec,UReGoU"eGoT#eaV)mV#TT>]`<Q~>
-!<E0!joD3.eUc8dec,XKec,XLec,UReGoU"eGoT#eaV)mV#TT>]`<Q~>
-!<E0!joD*+g4@tngA_0PgA_0QgA_-Wg&M-,g&M,(g@3f"U&X9;\c@6~>
-!<E0!joD3.eUc8dec,XKec,XLec,UReGoU"eGoT#eaV)mV#TT>]`<Q~>
-!<E0!joD4Keb4Xkec,XKec,UNeGoUIec,XAeb]@,ebK2reZ77#!<1OK!<:UL!!^sR!7fU"!.i\i
-eHMcKk2s>WJ,~>
-!<E0!joD+Hg@g*ngA_0PgA_-Sg&M-NgA_0FgA:m1gA(`"g8is-!<1^P!<:dQ!!_-W!8?-,!.ikn
-g'+2Mk2s5TJ,~>
-!<E0!joD4Keb4Xkec,XKec,UNeGoUIec,XAeb]@,ebK2reZ77#!<1OK!<:UL!!^sR!7fU"!.i\i
-eHMcKk2s>WJ,~>
-!<E0!joD4Keb=[rs7t4F!<1OK!;Y1F!;+hA!8Q-)!.i\!ec,XKec,XLec,UReGoU"eGoT#eaV)m
-V#TT>]`<Q~>
-!<E0!joD+Hg@p-us7tCK!<1^P!;Y@K!;,"F!8Q<.!.ik&gA_0PgA_0QgA_-Wg&M-,g&M,(g@3f"
-U&X9;\c@6~>
-!<E0!joD4Keb=[rs7t4F!<1OK!;Y1F!;+hA!8Q-)!.i\!ec,XKec,XLec,UReGoU"eGoT#eaV)m
-V#TT>]`<Q~>
-!<E0!joD4Kec19uXT/=rec,XKec,UWeGoU"eGoU"!!(R"r;c]ErrE#Jrr</O!!(RJ!<:RM!7h&K
-!7h&Kp!s'BrRLiHJ^q!TrrE#Jr;ciIr;_E!n'qT;s5rIW!.Y~>
-!<E0!joD+HgAca#0`V1KgA_0PgA_-\g&M-,g&M-,!!(a,r;c]JrrE#Orr</T!!(aO!<:aR!8@DP
-!8@DPp"KEGrS%2MJ_I?^rrE#Or;ciNr;_E&n(Ir=s5rIT!.Y~>
-!<E0!joD4Kec19u@fQK(ec,XKec,UWeGoU"eGoU"!!(R"r;c]ErrE#Jrr</O!!(RJ!<:RM!7h&K
-!7h&Kp!s'BrRLiHJ^q!TrrE#Jr;ciIr;_E!n'qT;s5rIW!.Y~>
-!<E0!joD4Kec19uXT/=rec,XKec,UReGoU"!!(RK!!^sR!7fU"!;k=H!<(IE!<:UL!".6V!7fU"
-!7fU"!;=tC!<1OK!<:UL!.i[OeW//`V#TT>]`<Q~>
-!<E0!joD+HgAca#0`V1KgA_0PgA_-Wg&M-,!!(aP!!_-W!8?-,!;kLM!<(XJ!<:dQ!".E[!8?-,
-!8?-,!;>.H!<1^P!<:dQ!.ijTg5akjU&X9;\c@6~>
-!<E0!joD4Kec19u@fQK(ec,XKec,UReGoU"!!(RK!!^sR!7fU"!;k=H!<(IE!<:UL!".6V!7fU"
-!7fU"!;=tC!<1OK!<:UL!.i[OeW//`V#TT>]`<Q~>
-!<E0!joD4Kec19uXT/=rebT7WeGoU"!!(R"!!(OL!7fU"!;k=E!!(RK!<:UL!<:UL!"7<W!7fU"
-!7fU"!7grHrRLoJrmh#Ks4.,LJ^o>%Nn"</s5rIW!.Y~>
-!<E0!joD+HgAca#0`V1KgA1d\g&M-,!!(a,!!(^Q!8?-,!;kLJ!!(aP!<:dQ!<:dQ!"7K\!8?-,
-!8?-,!8@;MrS%8Orn@APs4[JQJ_G\/NnOZ1s5rIT!.Y~>
-!<E0!joD4Kec19u@fQK(ebT7WeGoU"!!(R"!!(OL!7fU"!;k=E!!(RK!<:UL!<:UL!"7<W!7fU"
-!7fU"!7grHrRLoJrmh#Ks4.,LJ^o>%Nn"</s5rIW!.Y~>
-!<E0!joD4Kec19uXT/=rec,XKec,UVeGoU"!!(R"!!(RH!;k=H!<(IJ!<1OK!<:UL!".6V!7fU"
-!7fU"!;=tC!<1OK!<:UL!.i[OeW//`V#TT>]`<Q~>
-!<E0!joD+HgAca#0`V1KgA_0PgA_-[g&M-,!!(a,!!(aM!;kLM!<(XO!<1^P!<:dQ!".E[!8?-,
-!8?-,!;>.H!<1^P!<:dQ!.ijTg5akjU&X9;\c@6~>
-!<E0!joD4Kec19u@fQK(ec,XKec,UVeGoU"!!(R"!!(RH!;k=H!<(IJ!<1OK!<:UL!".6V!7fU"
-!7fU"!;=tC!<1OK!<:UL!.i[OeW//`V#TT>]`<Q~>
-!<E0!joD4Kec19uXT/=rec,XKec,UXeGoU"!!(R"!!(OL!;G%D!<(IJ!<1OK!<:UL!"7<W!7fU"
-!7fU"!7grHrRLoJrmh#Ks4.,LJ^o>%Nn"</s5rIW!.Y~>
-!<E0!joD+HgAca#0`V1KgA_0PgA_-]g&M-,!!(a,!!(^Q!;G4I!<(XO!<1^P!<:dQ!"7K\!8?-,
-!8?-,!8@;MrS%8Orn@APs4[JQJ_G\/NnOZ1s5rIT!.Y~>
-!<E0!joD4Kec19u@fQK(ec,XKec,UXeGoU"!!(R"!!(OL!;G%D!<(IJ!<1OK!<:UL!"7<W!7fU"
-!7fU"!7grHrRLoJrmh#Ks4.,LJ^o>%Nn"</s5rIW!.Y~>
-!<E0!joD4Kec19uXT/=rec,XKec,UReGoU"!!(RK!!^sR!7fU"!;k=H!<(IJ!<1OK!<:UL!".6V
-!7fU"!7fU"!;=tC!<1OK!<:UL!.i[OeW//`V#TT>]`<Q~>
-!<E0!joD+HgAca#0`V1KgA_0PgA_-Wg&M-,!!(aP!!_-W!8?-,!;kLM!<(XO!<1^P!<:dQ!".E[
-!8?-,!8?-,!;>.H!<1^P!<:dQ!.ijTg5akjU&X9;\c@6~>
-!<E0!joD4Kec19u@fQK(ec,XKec,UReGoU"!!(RK!!^sR!7fU"!;k=H!<(IJ!<1OK!<:UL!".6V
-!7fU"!7fU"!;=tC!<1OK!<:UL!.i[OeW//`V#TT>]`<Q~>
-!<E0!joD4Kec19uXT/=rec,XKec,UWeGoU"eGoU"!!(R"r;c]ErrE#JrrE#Jr;clJrrE)LrrE)L
-rrDcCrrE#Jr;bI"JV1dkJ^sMF"f21\k.LbF~>
-!<E0!joD+HgAca#0`V1KgA_0PgA_-\g&M-,g&M-,!!(a,r;c]JrrE#OrrE#Or;clOrrE)QrrE)Q
-rrDcHrrE#Or;bI'JUtXgJ_KkP"ektYk.1PC~>
-!<E0!joD4Kec19u@fQK(ec,XKec,UWeGoU"eGoU"!!(R"r;c]ErrE#JrrE#Jr;clJrrE)LrrE)L
-rrDcCrrE#Jr;bI"JV1dkJ^sMF"f21\k.LbF~>
-!<E0!joD4Kec19ss+/]#eU`@iK)kq&eb@StV#TT>]`<Q~>
-!<E0!joD+HgAca!s+/l(g4=glJH5_$g@s;)U&X9;\c@6~>
-!<E0!joD4Kec19ss+/]#eU`@iK)kq&eb@StV#TT>]`<Q~>
-!<E0!joD3.e`YK_K7U_r^#B!Beb@StV#TT>]`<Q~>
-!<E0!joD*+g?72iJUt\u_VtNGg@s;)U&X9;\c@6~>
-!<E0!joD3.e`YK_K7U_r^#B!Beb@StV#TT>]`<Q~>
-!<E0!joD3.e`YK_K7U_r^#]1pKE(t&eb@StV#TT>]`<Q~>
-!<E0!joD*+g?72iJUt\u_W:^uJcGb$g@s;)U&X9;\c@6~>
-!<E0!joD3.e`YK_K7U_r^#]1pKE(t&eb@StV#TT>]`<Q~>
-!<E0!joD3.e`YK_K7U_r^&S-*eH(=&p!s(ps8RZ#pXKGCs5rIW!.Y~>
-!<E0!joD*+g?72iJUt\u_Z0Z/g&Zd)p"KFss8RZ(pY#eEs5rIT!.Y~>
-!<E0!joD3.e`YK_K7U_r^&S-*eH(=&p!s(ps8RZ#pXKGCs5rIW!.Y~>
-!<E0!joD3.e`YK_K7U_r^&S-*eH(=&p!s(ps8RZ#pXKGCs5rIW!.Y~>
-!<E0!joD*+g?72iJUt\u_Z0Z/g&Zd)p"KFss8RZ(pY#eEs5rIT!.Y~>
-!<E0!joD3.e`YK_K7U_r^&S-*eH(=&p!s(ps8RZ#pXKGCs5rIW!.Y~>
-!<E0!joD3.e`YK_K7U_r^&S-*eH(=&p!s(ps8RZ#pXKGCs5rIW!.Y~>
-!<E0!joD*+g?72iJUt\u_Z0Z/g&Zd)p"KFss8RZ(pY#eEs5rIT!.Y~>
-!<E0!joD3.e`YK_K7U_r^&S-*eH(=&p!s(ps8RZ#pXKGCs5rIW!.Y~>
-!<E0!joD3.e`YK_K7U_r^&S-*eH(=&p!s(ps8RZ#pXKGCs5rIW!.Y~>
-!<E0!joD*+g?72iJUt\u_Z0Z/g&Zd)p"KFss8RZ(pY#eEs5rIT!.Y~>
-!<E0!joD3.e`YK_K7U_r^&S-*eH(=&p!s(ps8RZ#pXKGCs5rIW!.Y~>
-!<E0!joD3.e`YK_K7U_r^&S-*eH(=&p!s(ps8RZ#pXKGCs5rIW!.Y~>
-!<E0!joD*+g?72iJUt\u_Z0Z/g&Zd)p"KFss8RZ(pY#eEs5rIT!.Y~>
-!<E0!joD3.e`YK_K7U_r^&S-*eH(=&p!s(ps8RZ#pXKGCs5rIW!.Y~>
-!<E0!joD3.e`YK_K7U_r^&S-*eH(=&p!s(ps8RZ#pXKGCs5rIW!.Y~>
-!<E0!joD*+g?72iJUt\u_Z0Z/g&Zd)p"KFss8RZ(pY#eEs5rIT!.Y~>
-!<E0!joD3.e`YK_K7U_r^&S-*eH(=&p!s(ps8RZ#pXKGCs5rIW!.Y~>
-!<E0!joD3.e`YK_K7U_r^&S-*eH(=&p!s(ps8RZ#pXKGCs5rIW!.Y~>
-!<E0!joD*+g?72iJUt\u_Z0Z/g&Zd)p"KFss8RZ(pY#eEs5rIT!.Y~>
-!<E0!joD3.e`YK_K7U_r^&S-*eH(=&p!s(ps8RZ#pXKGCs5rIW!.Y~>
-!<E0!joD3.e`YK_K7U_r^&S-*eH(=&p!s(ps8RZ#pXKGCs5rIW!.Y~>
-!<E0!joD*+g?72iJUt\u_Z0Z/g&Zd)p"KFss8RZ(pY#eEs5rIT!.Y~>
-!<E0!joD3.e`YK_K7U_r^&S-*eH(=&p!s(ps8RZ#pXKGCs5rIW!.Y~>
-!<E0!joD4Keb9%=ec,XKec,UNeGoUIec,XAec,XKec,XFec,WYec18Q^#Qg+s7OnCKE(Vps+C@O
-J^sMF"f21\k.LbF~>
-!<E0!joD+Hg@kRBgA_0PgA_-Sg&M-NgA_0FgA_0PgA_0KgA_/^gAc_T_W/N5s7P(HJcGDss+14M
-J_KkP"ektYk.1PC~>
-!<E0!joD4Keb9%=ec,XKec,UNeGoUIec,XAec,XKec,XFec,WYec18Q^#Qg+s7OnCKE(Vps+C@O
-J^sMF"f21\k.LbF~>
-!<E0!joD4KebB(DKDF't!<1OK!;Y1F!;+hA!<1OK!;Y1F!4UMYK7U_r^&S-*eH(=&p!s(ps8RZ#
-pXKGCs5rIW!.Y~>
-!<E0!joD+Hg@tUIJbe%"!<1^P!;Y@K!;,"F!<1^P!;Y@K!4U\^JUt\u_Z0Z/g&Zd)p"KFss8RZ(
-pY#eEs5rIT!.Y~>
-!<E0!joD4KebB(DKDF't!<1OK!;Y1F!;+hA!<1OK!;Y1F!4UMYK7U_r^&S-*eH(=&p!s(ps8RZ#
-pXKGCs5rIW!.Y~>
-!<E0!joD4Kec5[Gec19tec,XKec,UWeGoU"eGoU"!!(R"r;c]ErrE&Krr<__!!(OL!7fU"!7fU"
-!7_&LeGoUKeboLJec,XLec,XLec,UQeGoU"!!(a's+>m9j1YKmp!j(qs7OqBKE(t&eb@StV#TT>
-]`<Q~>
-!<E0!joD+HgAh3LgAca"gA_0PgA_-\g&M-,g&M-,!!(a,r;c]JrrE&Prr<_d!!(^Q!8?-,!8?-,
-!87DQg&M-PgAM$OgA_0QgA_0QgA_-Vg&M-,!!(a,s+,a<j21irp"BFts7P+GJcGb$g@s;)U&X9;
-\c@6~>
-!<E0!joD4Kec5[Gec19tec,XKec,UWeGoU"eGoU"!!(R"r;c]ErrE&Krr<__!!(OL!7fU"!7fU"
-!7_&LeGoUKeboLJec,XLec,XLec,UQeGoU"!!(a's+>m9j1YKmp!j(qs7OqBKE(t&eb@StV#TT>
-]`<Q~>
-!<E0!joD4Kec5[Gec19tec,XKec,UReGoU"!!(RK!!^sR!7fU"!;k=H!<1OK!!(RK!".6V!7_&L
-eGoU"ec#O`eGoU"!!(R"!!(OL!7fU"!7fU"!7h&K!n@8NgXZ=VJ\C*Ws8V_D!<;YCs8RZ#pXKGC
-s5rIW!.Y~>
-!<E0!joD+HgAh3LgAca"gA_0PgA_-Wg&M-,!!(aP!!_-W!8?-,!;kLM!<1^P!!(aP!".E[!87DQ
-g&M-,gAV'eg&M-,!!(a,!!(^Q!8?-,!8?-,!8@DP!nmVSgY2[YJ\pHas8V_B!<;YAs8RZ(pY#eE
-s5rIT!.Y~>
-!<E0!joD4Kec5[Gec19tec,XKec,UReGoU"!!(RK!!^sR!7fU"!;k=H!<1OK!!(RK!".6V!7_&L
-eGoU"ec#O`eGoU"!!(R"!!(OL!7fU"!7fU"!7h&K!n@8NgXZ=VJ\C*Ws8V_D!<;YCs8RZ#pXKGC
-s5rIW!.Y~>
-!<E0!joD4Kec5[Gec19tebT7WeGoU"!!(R"!!(OL!7fU"!;k=H!<1OK!!h$S!7fU"!7h#Jrmh#K
-s4.,L(tATde^XX"e^XX"eGoU"!!(R"!!(R"!!(d(s+>m9j1PHmjFdL4J^sMF"f21\k.LbF~>
-!<E0!joD+HgAh3LgAca"gA1d\g&M-,!!(a,!!(^Q!8?-,!;kLM!<1^P!!h3X!8?-,!8@AOrn@AP
-s4[JQ(tnrig=cN,g=cN,g&M-,!!(a,!!(a,!!(d-s+,a<j2(frjFR@2J_KkP"ektYk.1PC~>
-!<E0!joD4Kec5[Gec19tebT7WeGoU"!!(R"!!(OL!7fU"!;k=H!<1OK!!h$S!7fU"!7h#Jrmh#K
-s4.,L(tATde^XX"e^XX"eGoU"!!(R"!!(R"!!(d(s+>m9j1PHmjFdL4J^sMF"f21\k.LbF~>
-!<E0!joD4Kec5[Gec19tec,XKec,UVeGoU"!!(R"!!(RH!;k=H!<1OK!!h$S!7fU"!7h#Jrmh#K
-s4.,L(tATde^XX"e^XX"eGoU"!!(R"!!(R"!!(d(s+>n&_uG;<pXKGCs5rIW!.Y~>
-!<E0!joD+HgAh3LgAca"gA_0PgA_-[g&M-,!!(a,!!(aM!;kLM!<1^P!!h3X!8?-,!8@AOrn@AP
-s4[JQ(tnrig=cN,g=cN,g&M-,!!(a,!!(a,!!(d-s+,b$_uG;ApY#eEs5rIT!.Y~>
-!<E0!joD4Kec5[Gec19tec,XKec,UVeGoU"!!(R"!!(RH!;k=H!<1OK!!h$S!7fU"!7h#Jrmh#K
-s4.,L(tATde^XX"e^XX"eGoU"!!(R"!!(R"!!(d(s+>n&_uG;<pXKGCs5rIW!.Y~>
-!<E0!joD4Kec5[Gec19tec,XKec,UXeGoU"!!(R"!!(OL!;G%D!<1OK!%l_$!7fU"!7_&LeGoU"
-eGoU"eGoU"!!(R"!!(R"!!(OL!7_&Le^XX"e^XX"gXQ:VJcEUeJ^sMF"f21\k.LbF~>
-!<E0!joD+HgAh3LgAca"gA_0PgA_-]g&M-,!!(a,!!(^Q!;G4I!<1^P!%ln)!8?-,!87DQg&M-,
-g&M-,g&M-,!!(a,!!(a,!!(^Q!87DQg=cN,g=cN,gY)XYJcEUeJ_KkP"ektYk.1PC~>
-!<E0!joD4Kec5[Gec19tec,XKec,UXeGoU"!!(R"!!(OL!;G%D!<1OK!%l_$!7fU"!7_&LeGoU"
-eGoU"eGoU"!!(R"!!(R"!!(OL!7_&Le^XX"e^XX"gXQ:VJcEUeJ^sMF"f21\k.LbF~>
-!<E0!joD4Kec5[Gec19tec,XKec,UReGoU"!!(RK!!^sR!7fU"!;b7G!$B_k!7fU"!7fU"!7_&L
-e^XX"eGoU"eGoU"!!(R"!!*#KrrE)LrrE&KrrE)Lrr@W#J^on5"f21\k.LbF~>
-!<E0!joD+HgAh3LgAca"gA_0PgA_-Wg&M-,!!(aP!!_-W!8?-,!;bFL!$Bnp!8?-,!8?-,!87DQ
-g=cN,g&M-,g&M-,!!(a,!!*#PrrE)QrrE&PrrE)Qrr@W(J_H7?"ektYk.1PC~>
-!<E0!joD4Kec5[Gec19tec,XKec,UReGoU"!!(RK!!^sR!7fU"!;b7G!$B_k!7fU"!7fU"!7_&L
-e^XX"eGoU"eGoU"!!(R"!!*#KrrE)LrrE&KrrE)Lrr@W#J^on5"f21\k.LbF~>
-!<E0!joD4Kec5[Gec19tec,XKec,UWeGoU"eGoU"!!(R"r;cZDquHcIrrE)Lrr<,N!!*#Kr;clJ
-rrE)Lr;cfHrrE)LrrE&KrrE)Lrr@W#J^on5"f21\k.LbF~>
-!<E0!joD+HgAh3LgAca"gA_0PgA_-\g&M-,g&M-,!!(a,r;cZIquHcNrrE)Qrr<,S!!*#Pr;clO
-rrE)Qr;cfMrrE)QrrE&PrrE)Qrr@W(J_H7?"ektYk.1PC~>
-!<E0!joD4Kec5[Gec19tec,XKec,UWeGoU"eGoU"!!(R"r;cZDquHcIrrE)Lrr<,N!!*#Kr;clJ
-rrE)Lr;cfHrrE)LrrE&KrrE)Lrr@W#J^on5"f21\k.LbF~>
-!<E0!joD4Kec5[EK7VR(eUc8ZeHMcKk2s>WJ,~>
-!<E0!joD+HgAh3JJUuO+g4@tdg'+2Mk2s5TJ,~>
-!<E0!joD4Kec5[EK7VR(eUc8ZeHMcKk2s>WJ,~>
-!<E0!joD3.eUc8%eXb4oV#TT>]`<Q~>
-!<E0!joD*+g4@t/g7?q$U&X9;\c@6~>
-!<E0!joD3.eUc8%eXb4oV#TT>]`<Q~>
-!<E0!joD3.eUc8%e[F#rKDX1&V#TT>]`<Q~>
-!<E0!joD*+g4@t/g:#`'Jc".)U&X9;\c@6~>
-!<E0!joD3.eUc8%e[F#rKDX1&V#TT>]`<Q~>
-!<E0!joD3.eUc8%e[F#sK)krKeHMcKk2s>WJ,~>
-!<E0!joD*+g4@t/g:#`(JH5`Ig'+2Mk2s5TJ,~>
-!<E0!joD3.eUc8%e[F#sK)krKeHMcKk2s>WJ,~>
-!<E0!joD3.eUc8%e[F$.KDN7]KDN:]s81=MV#TT>]`<Q~>
-!<E0!joD*+g4@t/g:#`8Jbm4`Jbm7`s81LRU&X9;\c@6~>
-!<E0!joD3.eUc8%e[F$.KDN7]KDN:]s81=MV#TT>]`<Q~>
-!<E0!joD3.eUc8%e[F$.KDW=_s+C0]s8VuH"f21\k.LbF~>
-!<E0!joD*+g4@t/g:#`8Jc!:bs+1$`s8VuM"ektYk.1PC~>
-!<E0!joD3.eUc8%e[F$.KDW=_s+C0]s8VuH"f21\k.LbF~>
-!<E0!joD3.eUc8%e[F$.KDW=`s+>t$^&S-0eHMcKk2s>WJ,~>
-!<E0!joD*+g4@t/g:#`8Jc!:cs+,au_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD3.eUc8%e[F$.KDW=`s+>t$^&S-0eHMcKk2s>WJ,~>
-!<E0!joD3.eUc8%e[F$.KD`F_s8R`K^&S-0eHMcKk2s>WJ,~>
-!<E0!joD*+g4@t/g:#`8Jc*Cbs8RZI_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD3.eUc8%e[F$.KD`F_s8R`K^&S-0eHMcKk2s>WJ,~>
-!<E0!joD3.eUc8%e[F$.KD`F_rrU`'KD`F_s81=MV#TT>]`<Q~>
-!<E0!joD*+g4@t/g:#`8Jc*CbrrUo*Jc*Cbs81LRU&X9;\c@6~>
-!<E0!joD3.eUc8%e[F$.KD`F_rrU`'KD`F_s81=MV#TT>]`<Q~>
-!<E0!joD3.eUc8%e[F$.KDiL`s8UXLKD`F_s81=MV#TT>]`<Q~>
-!<E0!joD*+g4@t/g:#`8Jc3Ics8UgQJc*Cbs81LRU&X9;\c@6~>
-!<E0!joD3.eUc8%e[F$.KDiL`s8UXLKD`F_s81=MV#TT>]`<Q~>
-!<E0!joD3.eUc8%e[F$.KDiL`s8LRKKDiL`s81=MV#TT>]`<Q~>
-!<E0!joD*+g4@t/g:#`8Jc3Ics8LaPJc3Ics81LRU&X9;\c@6~>
-!<E0!joD3.eUc8%e[F$.KDiL`s8LRKKDiL`s81=MV#TT>]`<Q~>
-!<E0!joD3.eUc8%e[F$.KDrRas8CLJKDiL`s81=MV#TT>]`<Q~>
-!<E0!joD*+g4@t/g:#`8Jc<Ods8C[OJc3Ics81LRU&X9;\c@6~>
-!<E0!joD3.eUc8%e[F$.KDrRas8CLJKDiL`s81=MV#TT>]`<Q~>
-!<E0!joD3.eUc8%e[F$.KDrRas8:FIKDrRas81=MV#TT>]`<Q~>
-!<E0!joD*+g4@t/g:#`8Jc<Ods8:UNJc<Ods81LRU&X9;\c@6~>
-!<E0!joD3.eUc8%e[F$.KDrRas8:FIKDrRas81=MV#TT>]`<Q~>
-!<E0!joD3.eUc8%e[F$.KE&Xbs81@HKDrRas81=MV#TT>]`<Q~>
-!<E0!joD*+g4@t/g:#`8JcEUes81OMJc<Ods81LRU&X9;\c@6~>
-!<E0!joD3.eUc8%e[F$.KE&Xbs81@HKDrRas81=MV#TT>]`<Q~>
-!<E0!joD3.eUc8%e[F$.KE&Xbs8(:GKE&Xbs81=MV#TT>]`<Q~>
-!<E0!joD*+g4@t/g:#`8JcEUes8(ILJcEUes81LRU&X9;\c@6~>
-!<E0!joD3.eUc8%e[F$.KE&Xbs8(:GKE&Xbs81=MV#TT>]`<Q~>
-!<E0!joD3.e`>9\s7OqBs8CLJs.%U>s7+V>s-qO=s7+Y>s7=e@s68)6K*&ads7t4FKE&Xbs81=M
-V#TT>]`<Q~>
-!<E0!joD*+g>puf!;5(G!<(XO!1_aC!:ebC!1V[B!:eeC!;"qE!9r5;JHE^gs7tCKJcEUes81LR
-U&X9;\c@6~>
-!<E0!joD3.e`>9\!;4nB!<(IJ!1_R>!:eS>!1VL=!:eV>!;"b@!9r&6K*&ads7t4FKE&Xbs81=M
-V#TT>]`<Q~>
-!<E0!joD4Lec5[Lec#LJeboFOec5["s8UXKs8UXLs8UXLrrCUIrrCUKs-hI<s7FhAs8:CIs,5D-
-s,#8+s74\?s68)6K*&ads7k.EK*&ads81=MV#TT>]`<Q~>
-!<E0!joD+IgAe#LgARiJgAIcOg81Y"V5;oFV>o9LV>o9LV#]6IV#]6KV4-*<!;+tF!;tON!/oP2
-!/]D0!:nhD!9r5;JHE^gs7k=JJHE^gs81LRU&X9;\c@6~>
-!<E0!joD4Lec,XLeboIJebfCOeGoU"!!(RK!<:UL!<:UL!!(RI!!(RK!1MF<!;+eA!;t@I!/oA-
-!/]5+!:nY?!9r&6K*&ads7k.EK*&ads81=MV#TT>]`<Q~>
-!<E0!joD4KeIMW0ec41Ms4,["e^a]Ms8LOVs4,["e^a]Mec42"rm_5Qe^a]Mec2r*s8NATs4,["
-s4./LpsoBDs4.,KrRLrJr7(fIr7(fI\(1NY#M&k)ec42"s8CLJs8CLIs8LRKs8LRKs7b(BrrgmP
-s4.._ec5XSec41Ms4./LrRLrJrRLoIrmh&Krmh&Kp!j'BrRLrJrRLrJrm_,Nec5[Kec5[KeH,^#
-rr;fEs+C@Oon*=Zs8VuH"f21\k.LbF~>
-!<E0!joD+Hg('t5g83NWV:sY"g=iCWV>f0VV:sY"g=iCWg83N"rn7RQg=iCWg82+/rr<>Y!8?-,
-!87DQptG]Is4[GPrS%8Or7V,Nr7V,N\(^i^#MK13g&Th,!<(XO!<(XN!<1^P!<1^P!;G4G!!M!U
-!87FdgA_-Xg&Tj\!87DQrS%8OrS%5Nrn@APrn@APp"BBGrS%8OrS%8Orn7GSg&M-PgA_0Pg&V3-
-rW)cJs+14Momm1]s8VuM"ektYk.1PC~>
-!<E0!joD4KeIDT0eH".M!7fU"e^XZM!<1LV!7fU"e^XZMeH","rm_2Qe^XZMeGuo*rr<>T!7fU"
-!7_&Lpso?Ds4.)KrRLoJr7(cIr7(cI\(1KY#Lrh)eH","!<(IJ!<(II!<1OK!<1OK!;G%B!!LgP
-!7_(_ec,USeH".M!7_&LrRLoJrRLlIrmh#Krmh#Kp!j$BrRLoJrRLoJrm_)NeGoUKec,XKeH#[#
-rW)cEs+C@Oon*=Zs8VuH"f21\k.LbF~>
-!<E0!joD4KeIDQ/ec41Ms8UXLe^a^"rRLrJ'@m-5ec41Ms4./"s4./"ec5["s0C/^s4./"s4,["
-e^a]qeH#XIeHu9+ec41Ms4,["rRCoJr7(fI\()/lec42"e^a]Mec41Ms4,["e^a]reH#XIeH#XD
-eH#XKeHGp&s4..`eJ%u5s4./"ec41Ms4,["e^a]Mec5Kr!<;uI!<;cC!<<&K%fb)0s4,["e^a]M
-ec42"rm_,Ne^a^!eH#XCec17%s7:mCs81=MV#TT>]`<Q~>
-!<E0!joD+Hg'sn4g83NWV5;nBg=iC"rS%:J'AB;:g83NWV:qd"V:qd"g81Y"V6\e^!87G,!8?-,
-g=cQ&g&M-Ng'Ic5g&Tj\!8?-,rRq5Or7V,N\(VJqg&Th,g=cP\g&Tj\!8?-,g=cQ'g&M-Ng&M-I
-g&M-Pg&qE0!87Feg(OJ?!87G,g&Tj\!8?-,g=cP\g&V!'!!)rN!!)`H!!*#P%KP5:!8?-,g=cP\
-g&Th,rn7GSg=cQ+g&M-HgAc^(s7:gAs81LRU&X9;\c@6~>
-!<E0!joD4KeI;N/eH".M!!(OLe^XX"rRLoJ'@d*5eH".M!7_)"!7_)"eGoU"!4(,^!7_)"!7fU"
-e^XZqeGoUIeHl6+eH".M!7fU"rRClJr7(cI\(),leH","e^XZMeH".M!7fU"e^XZreGoUIeGoUD
-eGoUKeH>m&!7_(`eIqr5!7_)"eH".M!7fU"e^XZMeH#Hr!!)rI!!)`C!!*#K%KP&0!7fU"e^XZM
-eH","rm_)Ne^X[!eGoUCec17%s7:mCs81=MV#TT>]`<Q~>
-!<E0!joD4KeIMW0ec41Ms4./Le^a]Ms8LO`s4./Le^a]Mec42"ec42"e^a]Ms8TCT$NJZVec41M
-s4,["psoEErm_2Pe^a]Mec,UHeH#XIeH#WYeI;K.s4./"ec41Ms4,[!s8CLJs8:CIs8LRJs7b%D
-s8LOOs4./"s1["ls4./"s4,["e^a]Mec,UIec5[IeH#XKec,UBeH#XKeHZ'(ec41Ms8:FIs8CLI
-s8CIJs7Y"CKCZ_Us81=MV#TT>]`<Q~>
-!<E0!joD+Hg('t5g83NWV:qcBg=iCWV>f0`V:qcBg=iCWg83N"g83N"g=iCWV5:KO$38c[g&Tj\
-!8?-,ptG`Jrn7MUg=cP\gAV*Mg&M-Ng&M,^g'du8!87G,g&Tj\!8?0+!<(XO!;tON!<1^O!;G1I
-!<1[T!87G,[email protected]!87G,!8?-,g=cP\gAV*NgA_0Ng&M-PgAV*Gg&M-Pg'.Q2g&Tj\!;tRN!<(XN
-!<(UO!;>.HJb$\Xs81LRU&X9;\c@6~>
-!<E0!joD4KeIDT0eH".M!7_&Le^XZM!<1L`!7_&Le^XZMeH","eH","e^XZM!!'=T$38TVeH".M
-!7fU"psoBErm_/Pe^XZMec#RHeGoUIeGoTYeI2H.!7_)"eH".M!7fX!!<(IJ!;t@I!<1OJ!;G"D
-!<1LO!7_)"!5?tl!7_)"!7fU"e^XZMec#RIec,XIeGoUKec#RBeGoUKeHQ$(eH".M!;tCI!<(II
-!<(FJ!;=tCKCZ_Us81=MV#TT>]`<Q~>
-!<E0!joD4KeKFnBec41Ms4,["e^a]Mec41Ms4,["e^a]Mec41Ms4./KeH>j%ec2r*$NJZVec41M
-s4,["p=0TOe^a]Mec41Ms4,["rRCoJr7(fI\()&iec42"e^a]Mec41Ms4,["r7(fIrRD,Pe^a]M
-ec5Bo#liH*s8UXLec3A6&HC;\ec41Ms4,["e^a]Mec5Qt!<<#J#636(s4,["p=00Crm_MYe^a]M
-ec41Ms4,["ec5X!"96p%s8LOKs7Y"CKCJp<eHMcKk2s>WJ,~>
-!<E0!joD+Hg*!6Gg83NWV:sY"g=iCWg83NWV:sY"g=iCWg83NWV:qdFg&n2*g82+/$38c[g&Tj\
-!8?-,p=]oTg=cP\g&Tj\!8?-,rRq5Or7V,N\(VAng&Th,g=cP\g&Tj\!8?-,r7V,NrRqGUg=cP\
-g&Um$#QWT4!!(^Qg&Sk@&-1Dag&Tj\!8?-,g=cP\g&V')!!)uO"p!B2!8?-,p=]KHrn7h^g=cP\
-g&Tj\!8?-,g&V-+!s%'/!<1[P!;>.HJai^:g'+2Mk2s5TJ,~>
-!<E0!joD4KeK=kBeH".M!7fU"e^XZMeH".M!7fU"e^XZMeH".M!7_)KeH5g%eGuo*$38TVeH".M
-!7fU"p=0QOe^XZMeH".M!7fU"rRClJr7(cI\()#ieH","e^XZMeH".M!7fU"r7(cIrRD)Pe^XZM
-eH#?o#QWE*!!(OLeH!>6&-15\eH".M!7fU"e^XZMeH#Nt!!)uJ"p!3(!7fU"p=0-Crm_JYe^XZM
-eH".M!7fU"eH#U!!s$m%!<1LK!;=tCKCJp<eHMcKk2s>WJ,~>
-!<E0!joD4Jec5[Lec5[LeH,^#rr<#Krr<#K!<<&Ks8W)K$3/QUe^a^"e^a]*eHu9+s4./Le^a^"
-psoBDs4.,K#1`bRe^a^"rmgrH!7h#I\^^f^ec41trs%$Rs4,["s8LRJs8LRHrrgmPs4./Dec5XR
-ec42"ec5ZaeH>j%s4.&I#1`bRe^a^"rmh#JrmgrH"P*PPec5Hqr;ZfIs8W&Js8W,Ls8N/Ns8W)K
-s8W)KrVuZCs+BqC!e^OQqpbkGs5rIW!.Y~>
-!<E0!joD+GgAe#LgAe#Lg&\&(rh]YKrh]YK!2]\Ks/#_K$)Q@Pg=iC"g=iC/g'Ic5!87DQg=cN,
-ptG]Is4[GP#20%Wg=cN,rn@8M!8@>N\_7,cg&Tk)!!_-W!8?-,!<1^O!<1^M!!M!U!87GIgA_-W
-g&Th,g&M,fg&h?/!8@>N#20%Wg=cN,rn@>Orn@8M"PNhUg&Us&quHcNrrE#OrrE)Qrr<,S!!*#P
-rrE&Pr;cWHs+0eA!eLCOqq;4Is5rIT!.Y~>
-!<E0!joD4Jec,XLec,XLeH#[#rW)uKrW)uK!!*#KrrE&K#lrKUe^XX"e^XZ*eHl6+!7_&Le^XX"
-pso?Ds4.)K#1W\Re^XX"rmgoH!7guI\^^c^eH".t!!^sR!7fU"!<1OJ!<1OH!!LgP!7_)Dec,UR
-eH","eGoTaeH5g%!7guI#1W\Re^XX"rmguJrmgoH"P!JPeH#EqquHcIrrE#JrrE)Lrr<,N!!*#K
-rrE&Kr;cWCs+BqC!e^OQqpbkGs5rIW!.Y~>
-!<E0!joD3.eb%Als+/^Oe\p#<KE(uFec1:%s81=MV#TT>]`<Q~>
-!<E0!joD*+g@X)!!.ijTg;M_FJcGcDgAca(s81LRU&X9;\c@6~>
-!<E0!joD3.eb%Al!.i[Oe\p#<KE(uFec1:%s81=MV#TT>]`<Q~>
-!<E0!joD3.eb7Pns8CLFs+/_pebfB-ebfBsec1:%s7CsDs81=MV#TT>]`<Q~>
-!<E0!joD*+g@j8#!<(XK!.ikugA:l2gA:m#gAca(s7CmBs81LRU&X9;\c@6~>
-!<E0!joD3.eb7Pn!<(IF!.i\peb]?-eb]?sec1:%s7CsDs81=MV#TT>]`<Q~>
-!<E0!joD3.eUc8%e[F$.K)krCKE(uKeHMcKk2s>WJ,~>
-!<E0!joD*+g4@t/g:#`8JH5`AJcGcIg'+2Mk2s5TJ,~>
-!<E0!joD3.eUc8%e[F$.K)krCKE(uKeHMcKk2s>WJ,~>
-!<E0!joD3.eUc8%e[F$.KCZ_Us81=MV#TT>]`<Q~>
-!<E0!joD*+g4@t/g:#`8Jb$\Xs81LRU&X9;\c@6~>
-!<E0!joD3.eUc8%e[F$.KCZ_Us81=MV#TT>]`<Q~>
-!<E0!joD3.eUc8%e[F$.KCZ_Us81=MV#TT>]`<Q~>
-!<E0!joD*+g4@t/g:#`8Jb$\Xs81LRU&X9;\c@6~>
-!<E0!joD3.eUc8%e[F$.KCZ_Us81=MV#TT>]`<Q~>
-!<E0!joD3.eUc8%e[F$.KCZ_Us81=MV#TT>]`<Q~>
-!<E0!joD*+g4@t/g:#`8Jb$\Xs81LRU&X9;\c@6~>
-!<E0!joD3.eUc8%e[F$.KCZ_Us81=MV#TT>]`<Q~>
-!<E0!joD3.eUc8%e[F$.KCZ_Us81=MV#TT>]`<Q~>
-!<E0!joD*+g4@t/g:#`8Jb$\Xs81LRU&X9;\c@6~>
-!<E0!joD3.eUc8%e[F$.KCZ_Us81=MV#TT>]`<Q~>
-!<E0!joD3.eUc8%e[F$.KCZ_Us81=MV#TT>]`<Q~>
-!<E0!joD*+g4@t/g:#`8Jb$\Xs81LRU&X9;\c@6~>
-!<E0!joD3.eUc8%e[F$.KCZ_Us81=MV#TT>]`<Q~>
-!<E0!joD3.eUc8%e[F$.KCZ_Us81=MV#TT>]`<Q~>
-!<E0!joD*+g4@t/g:#`8Jb$\Xs81LRU&X9;\c@6~>
-!<E0!joD3.eUc8%e[F$.KCZ_Us81=MV#TT>]`<Q~>
-!<E0!joD3.eUc8%e[F$.KCZ_Us81=MV#TT>]`<Q~>
-!<E0!joD*+g4@t/g:#`8Jb$\Xs81LRU&X9;\c@6~>
-!<E0!joD3.eUc8%e[F$.KCZ_Us81=MV#TT>]`<Q~>
-!<E0!joD3.eUc8%e[F$.KCZ_Us81=MV#TT>]`<Q~>
-!<E0!joD*+g4@t/g:#`8Jb$\Xs81LRU&X9;\c@6~>
-!<E0!joD3.eUc8%e[F$.KCZ_Us81=MV#TT>]`<Q~>
-!<E0!joD3.eUc8%e[F$.KCZ_Us81=MV#TT>]`<Q~>
-!<E0!joD*+g4@t/g:#`8Jb$\Xs81LRU&X9;\c@6~>
-!<E0!joD3.eUc8%e[F$.KCZ_Us81=MV#TT>]`<Q~>
-!<E0!joD3.eUc8%e[F$.KCZ_Us81=MV#TT>]`<Q~>
-!<E0!joD*+g4@t/g:#`8Jb$\Xs81LRU&X9;\c@6~>
-!<E0!joD3.eUc8%e[F$.KCZ_Us81=MV#TT>]`<Q~>
-!<E0!joD3.eUc8%e[F$.KCZ_Us81=MV#TT>]`<Q~>
-!<E0!joD*+g4@t/g:#`8Jb$\Xs81LRU&X9;\c@6~>
-!<E0!joD3.eUc8%e[F$.KCZ_Us81=MV#TT>]`<Q~>
-!<E0!joD3.eUc8%e[F$.KCZ_Us81=MV#TT>]`<Q~>
-!<E0!joD*+g4@t/g:#`8Jb$\Xs81LRU&X9;\c@6~>
-!<E0!joD3.eUc8%e[F$.KCZ_Us81=MV#TT>]`<Q~>
-!<E0!joD3.eUc8%e[F$.KCZ_Us81=MV#TT>]`<Q~>
-!<E0!joD*+g4@t/g:#`8Jb$\Xs81LRU&X9;\c@6~>
-!<E0!joD3.eUc8%e[F$.KCZ_Us81=MV#TT>]`<Q~>
-!<E0!joD3.eUc8%e[F$.KCZ_Us81=MV#TT>]`<Q~>
-!<E0!joD*+g4@t/g:#`8Jb$\Xs81LRU&X9;\c@6~>
-!<E0!joD3.eUc8%e[F$.KCZ_Us81=MV#TT>]`<Q~>
-!<E0!joD3.eUc8%e[F$.KCZ_Us81=MV#TT>]`<Q~>
-!<E0!joD*+g4@t/g:#`8Jb$\Xs81LRU&X9;\c@6~>
-!<E0!joD3.eUc8%e[F$.KCZ_Us81=MV#TT>]`<Q~>
-!<E0!joD3.eUc8%e[F$.KCZ_Us81=MV#TT>]`<Q~>
-!<E0!joD*+g4@t/g:#`8Jb$\Xs81LRU&X9;\c@6~>
-!<E0!joD3.eUc8%e[F$.KCZ_Us81=MV#TT>]`<Q~>
-!<E0!joD3.eUc8%e[F$.KCZ_Us81=MV#TT>]`<Q~>
-!<E0!joD*+g4@t/g:#`8Jb$\Xs81LRU&X9;\c@6~>
-!<E0!joD3.eUc8%e[F$.KCZ_Us81=MV#TT>]`<Q~>
-!<E0!joD3.eUc8%e[F$.KCZ_Us81=MV#TT>]`<Q~>
-!<E0!joD*+g4@t/g:#`8Jb$\Xs81LRU&X9;\c@6~>
-!<E0!joD3.eUc8%e[F$.KCZ_Us81=MV#TT>]`<Q~>
-!<E0!joD3.eUc8%e[F$.KCZ_Us81=MV#TT>]`<Q~>
-!<E0!joD*+g4@t/g:#`8Jb$\Xs81LRU&X9;\c@6~>
-!<E0!joD3.eUc8%e[F$.KCZ_Us81=MV#TT>]`<Q~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M,1g&M,1g&M,]gAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#X;eH#X=eH#X7eH#WjeH#W,eH#WXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M-@g&M-Bg&M-<g&M,og&M,1g&M,]gAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoU;eGoU=eGoU7eGoTjeGoT,eGoTXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#X;eH#X=eH#X7eH#WjeH#W,eH#WXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M-@g&M-Bg&M-<g&M,og&M,1g&M,]gAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoU;eGoU=eGoU7eGoTjeGoT,eGoTXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#XAec,UKec#OJec5[JeH,^#rr2uKrVuZCs8W,Ls8N5Ps8UX"rVulIs8W)K
-!WU^Ls4>d$s,,>,s0gJXKCZ_Us81=MV#TT>]`<Q~>
-!<E0!joD+?g&Rt,g&M-FgAV*PgAM$OgA_0Og&V3-rVurPr;cWHrrE)Qrr<2U!!(a,r;ciNrrE&P
-!<CjQ!8#p)!/fJ1!4LV]Jb$\Xs81LRU&X9;\c@6~>
-!<E0!joD4BeGoT,eGoUAec#RKeboLJec,XJeH#[#rVurKr;cWCrrE)Lrr<2P!!(R"r;ciIrrE&K
-!<C[L!8#a$!/f;,!4LGXKCZ_Us81=MV#TT>]`<Q~>
-!<E0!joD4BeH#W,eH#XBeH#XHeH#XHeH#XJeH#XIeH#XDeHu9+ec41Ms4,["rm_#KrRD#Me^a^!
-eH#X!eH#W,eH#WXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M-Gg&M-Mg&M-Mg&M-Og&M-Ng&M-Ig'Ic5g&Tj\!8?-,rn7>PrRq>Rg=cQ+
-g&M-&g&M,1g&M,]gAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoUBeGoUHeGoUHeGoUJeGoUIeGoUDeHl6+eH".M!7fU"rm^uKrRCuMe^X[!
-eGoU!eGoT,eGoTXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#XAec5[JeH#XJec,UIeH#XIeH#XDeHu9+ec41Ms4,["rm_#KrRLoIrRCoJ
-eC=R!MU__,[akD1o"G)'qpbkGs5rIW!.Y~>
-!<E0!joD+?g&Rt,g&M-FgA_0Og&M-OgAV*Ng&M-Ng&M-Ig'Ic5g&Tj\!8?-,rn7>PrS%5NrRq5O
-eCjm&MV8%1[bCb4o"tG,qq;4Is5rIT!.Y~>
-!<E0!joD4BeGoT,eGoUAec,XJeGoUJec#RIeGoUIeGoUDeHl6+eH".M!7fU"rm^uKrRLlIrRClJ
-eC=O!MU_\,[akD1o"G)'qpbkGs5rIW!.Y~>
-!<E0!joD4BeH#W,eH#X?eH#XKeHc-)ec5["ec5Tu!<;uI"96p%s8(7Ps4,["e^a]Mec5X!#liH*
-s4./"ec5X!!<:R!!<7r,!<9LXs+BmUs8VuH"f21\k.LbF~>
-!<E0!joD+?g&Rt,g&M-Dg&M-Pg'7W3g&M-,g&V**!!)rN!s%'/!;bCU!8?-,g=cP\g&V-+#QWT4
-!87G,g&V-+!!(O&!!%o1!!'I]s+0aXs8VuM"ektYk.1PC~>
-!<E0!joD4BeGoT,eGoU?eGoUKeHZ*)eGoU"eH#Qu!!)rI!s$m%!;b4P!7fU"e^XZMeH#U!#QWE*
-!7_)"eH#U!!!(O!!!%o,!!'IXs+BmUs8VuH"f21\k.LbF~>
-!<E0!joD4BeH#W,eH#XBec,UHec5[Lec5XOec41MrVuiHs8VlEs8W&Js8N,Ms8LRKs8LRKs8LRI
-s45^#s,,>,s0gJXKCZ_Us81=MV#TT>]`<Q~>
-!<E0!joD+?g&Rt,g&M-GgAV*MgA_0QgA_-Tg&Tj\r;cfMrrDiJrrE#Orr<)R!<1^P!<1^P!<1^N
-!7oj(!/fJ1!4LV]Jb$\Xs81LRU&X9;\c@6~>
-!<E0!joD4BeGoT,eGoUBec#RHec,XLec,UOeH".Mr;cfHrrDiErrE#Jrr<)M!<1OK!<1OK!<1OI
-!7o[#!/f;,!4LGXKCZ_Us81=MV#TT>]`<Q~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M,1g&M,1g&M,]gAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#X%ebfBWeH#W,eH#WXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M-*gA:l\g&M,1g&M,]gAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoU%eb]?WeGoT,eGoTXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M,1g&M,1g&M,]gAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M,1g&M,1g&M,]gAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W5ec,XGeH#W,eH#WXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M,:gA_0Lg&M,1g&M,]gAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT5ec,XGeGoT,eGoTXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W5eboLGeH#W,eH#WXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M,:gAM$Lg&M,1g&M,]gAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT5eboLGeGoT,eGoTXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W4eb]@HeH#W,eH#WXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M,9gA:mMg&M,1g&M,]gAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT4eb]@HeGoT,eGoTXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eVO8+s,,>,s0gJXKCZ_Us81=MV#TT>]`<Q~>
-!<E0!joD+?g&Rt,g5#`dg&M,]gAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eVF3_eGoTXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W4eb]@HeH#W,eH#WXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M,9gA:mMg&M,1g&M,]gAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT4eb]@HeGoT,eGoTXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W4ec#RHeH#W,eH#WXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M,9gAV*Mg&M,1g&M,]gAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT4ec#RHeGoT,eGoTXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W5ec,XGeH#W,eH#WXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M,:gA_0Lg&M,1g&M,]gAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT5ec,XGeGoT,eGoTXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M,1g&M,1g&M,]gAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M,1g&M,1g&M,]gAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M,1g&M,1g&M,]gAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M,1g&M,1g&M,]gAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M,1g&M,1g&M,]gAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M,1g&M,1g&M,]gAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M,1g&M,1g&M,]gAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M,1g&M,1g&M,]gAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M,1g&M,1g&M,]gAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M,1g&M,1g&M,]gAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M,1g&M,1g&M,]gAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M,1g&M,1g&M,]gAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#X)eH#XHeH#XIec5Z`eH#W,eH#WXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M-.g&M-Mg&M-NgA_/eg&M,1g&M,]gAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoU)eGoUHeGoUIec,W`eGoT,eGoTXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#X)eH#XAeH#W`eH#W,eH#WXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M-.g&M-Fg&M,eg&M,1g&M,]gAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoU)eGoUAeGoT`eGoT,eGoTXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#XCeH>j%s8W&Js8W,L"om-Qec5[Gec#OIec5[Jec,T_eH#W,eH#WXec19m
-^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M-Hg&h?/!!)uOrrE)Q"T[6Vg&M-LgAM$NgA_0OgAV)dg&M,1g&M,]gAc`p
-_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoUCeH5g%!!)uJrrE)L"T['QeGoUGeboLIec,XJec#Q_eGoT,eGoTXec19m
-^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#XBeIV]1ec41Ms4,["ec42"ec5Ep!<;rH!<<&K"96p%s1["`s,,>,s0gJX
-KCZ_Us81=MV#TT>]`<Q~>
-!<E0!joD+?g&Rt,g&M-Gg(+2;g&Tj\!8?-,g&Th,g&Up%!!)oM!!*#P!s%'/[email protected]!/fJ1!4LV]
-Jb$\Xs81LRU&X9;\c@6~>
-!<E0!joD4BeGoT,eGoUBeIMZ1eH".M!7fU"eH","eH#Bp!!)oH!!*#K!s$m%!5?t`!/f;,!4LGX
-KCZ_Us81=MV#TT>]`<Q~>
-!<E0!joD4BeH#W,eH#XBeHQ!'ec41Mrr<#K"TR$Pec5Ep!<;rH!<<&K"96p%s1["`s,,>,s0gJX
-KCZ_Us81=MV#TT>]`<Q~>
-!<E0!joD+?g&Rt,g&M-Gg'%K1g&Tj\rW)uP"9@-Ug&Up%!!)oM!!*#P!s%'/[email protected]!/fJ1!4LV]
-Jb$\Xs81LRU&X9;\c@6~>
-!<E0!joD4BeGoT,eGoUBeHGs'eH".MrW)uK"9?sPeH#Bp!!)oH!!*#K!s$m%!5?t`!/f;,!4LGX
-KCZ_Us81=MV#TT>]`<Q~>
-!<E0!joD4BeH#W,eH#XBeIMW0ec41Ms4,["e^a]Ms7b%Gs4,["rm_#Krm_,Ne^a]6eH#W,eH#WX
-ec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M-Gg(",:g&Tj\!8?-,g=cP\!;G1L!8?-,rn7>Prn7GSg=cP@g&M,1g&M,]
-gAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoUBeIDT0eH".M!7fU"e^XZM!;G"G!7fU"rm^uKrm_)Ne^XZ6eGoT,eGoTX
-ec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#XCec,RQec5["ec5[KeH5d$s7Y"Cs8UXIs8UXLrrL[M^XW>aMU__,[akD1
-o"G)'qpbkGs5rIW!.Y~>
-!<E0!joD+?g&Rt,g&M-HgAV'Vg&M-,g&M-Pg&_9.!;>.H!<:dN!<:dQ!!1dR^Y/YfMV8%1[bCb4
-o"tG,qq;4Is5rIT!.Y~>
-!<E0!joD4BeGoT,eGoUCec#OQeGoU"eGoUKeH,a$!;=tC!<:UI!<:UL!!1UM^XW;aMU_\,[akD1
-o"G)'qpbkGs5rIW!.Y~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M,1g&M,1g&M,]gAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#X1ebfBKeH#W,eH#WXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M-6gA:lPg&M,1g&M,]gAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoU1eb]?KeGoT,eGoTXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M,1g&M,1g&M,]gAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M,1g&M,1g&M,]gAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#XGec,W5eH#W,eH#WXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M-LgA_/:g&M,1g&M,]gAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoUGec,W5eGoT,eGoTXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#XJeboK2eH#W,eH#WXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M-OgAM#7g&M,1g&M,]gAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoUJeboK2eGoT,eGoTXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH5d$eb]?0eH#W,eH#WXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&_9.gA:l5g&M,1g&M,]gAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eH,a$eb]?0eGoT,eGoTXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eVO8+s,,>,s0gJXKCZ_Us81=MV#TT>]`<Q~>
-!<E0!joD+?g&Rt,g5#`dg&M,]gAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eVF3_eGoTXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH5d$ebfE0eH#W,eH#WXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&_9.gACr5g&M,1g&M,]gAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eH,a$ebfE0eGoT,eGoTXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#XJeboK2eH#W,eH#WXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M-OgAM#7g&M,1g&M,]gAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoUJeboK2eGoT,eGoTXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#XGec,W5eH#W,eH#WXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M-LgA_/:g&M,1g&M,]gAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoUGec,W5eGoT,eGoTXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M,1g&M,1g&M,]gAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M,1g&M,1g&M,]gAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M,1g&M,1g&M,]gAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M,1g&M,1g&M,]gAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M,1g&M,1g&M,]gAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M,1g&M,1g&M,]gAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M,1g&M,1g&M,]gAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M,1g&M,1g&M,]gAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M,1g&M,1g&M,]gAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M,1g&M,1g&M,]gAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M,1g&M,1g&M,]gAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M,1g&M,1g&M,]gAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#XAeH#X*eH#XJeH#X=ec5[@ec5[2eH#W,eH#WXec19m^&S-0eHMcKk2s>W
-J,~>
-!<E0!joD+?g&Rt,g&M-Fg&M-/g&M-Og&M-BgA_0EgA_07g&M,1g&M,]gAc`p_Z0Z5g'+2Mk2s5T
-J,~>
-!<E0!joD4BeGoT,eGoUAeGoU*eGoUJeGoU=ec,X@ec,X2eGoT,eGoTXec19m^&S-0eHMcKk2s>W
-J,~>
-!<E0!joD4BeH#W,eH#XAeH#X%eH#X<eH#X?eH#X2eH#W,eH#WXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M-Fg&M-*g&M-Ag&M-Dg&M-7g&M,1g&M,]gAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoUAeGoU%eGoU<eGoU?eGoU2eGoT,eGoTXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#XBec#OJeH,^#r;QiKs8VrG#liHTec5["s4.,Ks4./LrmguIrmh&Kp=00C
-rRLrJrRLrJrm_,Nec5[5eH#W,eH#WXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M-GgAM$Og&V3-qu?fP!!)lL#QWQYg&M-,!8@DPs4[JQrn@;Nrn@APp=]KH
-rS%8OrS%8Orn7GSg&M-:g&M,1g&M,]gAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoUBeboLJeH#[#qu?fK!!)lG#QWBTeGoU"!7h&Ks4.,LrmgrIrmh#Kp=0-C
-rRLoJrRLoJrm_)NeGoU5eGoT,eGoTXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#XAeH#XIeH#XJeH>j%ec5Kr"TR$Pec5X!!<;rH!<<#J!<<#J"96p%s7b%D
-s8LOYs4,["e^a]Mec41Ms4./4eH#W,eH#WXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M-Fg&M-Ng&M-Og&h?/g&V!'"9@-Ug&V-+!!)oM!!)uO!!)uO!s%'/!;G1I
-!<1[^!8?-,g=cP\g&Tj\!87G9g&M,1g&M,]gAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoUAeGoUIeGoUJeH5g%eH#Hr"9?sPeH#U!!!)oH!!)uJ!!)uJ!s$m%!;G"D
-!<1LY!7fU"e^XZMeH".M!7_)4eGoT,eGoTXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#XAeH#XIeH#XJeH>j%ec5Kr"TR$Pec5X!!<;rH!<<#J!<<#Jrr;]B!<<&K
-#636(s4,["r71iIk1'J3MU__,[akD1o"G)'qpbkGs5rIW!.Y~>
-!<E0!joD+?g&Rt,g&M-Fg&M-Ng&M-Og&h?/g&V!'"9@-Ug&V-+!!)oM!!)uO!!)uOrW)ZG!!*#P
-"p!B2!8?-,r7_/Nk1Te8MV8%1[bCb4o"tG,qq;4Is5rIT!.Y~>
-!<E0!joD4BeGoT,eGoUAeGoUIeGoUJeH5g%eH#Hr"9?sPeH#U!!!)oH!!)uJ!!)uJrW)ZB!!*#K
-"p!3(!7fU"r71fIk1'G3MU_\,[akD1o"G)'qpbkGs5rIW!.Y~>
-!<E0!joD4BeH#W,eH#XAeHZ'(ec41Ms8CIMs4,["q:,QHec5Tu!<;rH!<<#J#liH*s4./"ec5Bo
-!<<&K%fb)0s4,["e^a]Mec42"kLBS4MU__,[akD1o"G)'qpbkGs5rIW!.Y~>
-!<E0!joD+?g&Rt,g&M-Fg'.Q2g&Tj\!<(UR!8?-,q:YlMg&V**!!)oM!!)uO#QWT4!87G,g&Um$
-!!*#P%KP5:!8?-,g=cP\g&Th,kLon9MV8%1[bCb4o"tG,qq;4Is5rIT!.Y~>
-!<E0!joD4BeGoT,eGoUAeHQ$(eH".M!<(FM!7fU"q:,NHeH#Qu!!)oH!!)uJ#QWE*!7_)"eH#?o
-!!*#K%KP&0!7fU"e^XZMeH","kLBP4MU_\,[akD1o"G)'qpbkGs5rIW!.Y~>
-!<E0!joD4BeH#W,eH#X@ec5[Lec#OIec5[EeH5d$s8LRIs8UXIs8LRKs8LRKs7k.Bs8UXLs8CLJ
-s8UXLrrUaNs6.u5s,,>,s0gJXKCZ_Us81=MV#TT>]`<Q~>
-!<E0!joD+?g&Rt,g&M-EgA_0QgAM$NgA_0Jg&_9.!<1^N!<:dN!<1^P!<1^P!;P:G!<:dQ!<(XO
-!<:dQ!!:jS!9i,:!/fJ1!4LV]Jb$\Xs81LRU&X9;\c@6~>
-!<E0!joD4BeGoT,eGoU@ec,XLeboLIec,XEeH,a$!<1OI!<:UI!<1OK!<1OK!;P+B!<:UL!<(IJ
-!<:UL!!:[N!9hr5!/f;,!4LGXKCZ_Us81=MV#TT>]`<Q~>
-!<E0!joD4BeH#W,eH#X5eH#WFeH#W,eH#WXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M-:g&M,Kg&M,1g&M,]gAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoU5eGoTFeGoT,eGoTXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#X7ec5[JebfC,ebfBoeH#W,eH#WXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M-<gA_0OgA:m1gA:ltg&M,1g&M,]gAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoU7ec,XJeb]@,eb]?oeGoT,eGoTXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M,1g&M,1g&M,]gAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M,1g&M,1g&M,]gAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W5ec,XGeH#WXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M,1g&M,:gA_0Lg&M,]gAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT5ec,XGeGoTXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W5eboLGeH#WXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M,1g&M,:gAM$Lg&M,]gAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT5eboLGeGoTXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W4eb]@HeH#WXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M,1g&M,9gA:mMg&M,]gAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT4eb]@HeGoTXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eU[^_!!*&-ec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g496c!4LV]Jb$\Xs81LRU&X9;\c@6~>
-!<E0!joD4BeGoT,eU[^^!4LGXKCZ_Us81=MV#TT>]`<Q~>
-!<E0!joD4BeH#W,eH#W,eH#W4eb]@HeH#WXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M,1g&M,9gA:mMg&M,]gAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT4eb]@HeGoTXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W4ec#RHeH#WXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M,1g&M,9gAV*Mg&M,]gAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT4ec#RHeGoTXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W5ec,XGeH#WXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M,1g&M,:gA_0Lg&M,]gAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT5ec,XGeGoTXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M,1g&M,1g&M,]gAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M,1g&M,1g&M,]gAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M,1g&M,1g&M,]gAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M,1g&M,1g&M,]gAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M,1g&M,1g&M,]gAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M,1g&M,1g&M,]gAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M,1g&M,1g&M,]gAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M,1g&M,1g&M,]gAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M,1g&M,1g&M,]gAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M,1g&M,1g&M,]gAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M,1g&M,1g&M,]gAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M,1g&M,1g&M,]gAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#X)eH#XBec5Z`eH#W,eH#WXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M-.g&M-GgA_/eg&M,1g&M,]gAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoU)eGoUBec,W`eGoT,eGoTXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#X)eH#XAeH#W`eH#W,eH#WXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M-.g&M-Fg&M,eg&M,1g&M,]gAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoU)eGoUAeGoT`eGoT,eGoTXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#XAec5XPec42"ec,RMec5[KeH>j%s8W)KrVulIs8W&Jrr9^_!<7r,!<9LX
-s+BmUs8VuH"f21\k.LbF~>
-!<E0!joD+?g&Rt,g&M-FgA_-Ug&Th,gAV'Rg&M-Pg&h?/!!*#Pr;ciNrrE#OrW'[d!!%o1!!'I]
-s+0aXs8VuM"ektYk.1PC~>
-!<E0!joD4BeGoT,eGoUAec,UPeH","ec#OMeGoUKeH5g%!!*#Kr;ciIrrE#JrW'[_!!%o,!!'IX
-s+BmUs8VuH"f21\k.LbF~>
-!<E0!joD4BeH#W,eH#XBeH>j%ec5X!!<;rH!<<&K"96p%s8LOKs8CISs4,["e^a]Mec3A6!<7r,
-!<9LXs+BmUs8VuH"f21\k.LbF~>
-!<E0!joD+?g&Rt,g&M-Gg&h?/g&V-+!!)oM!!*#P!s%'/!<1[P!<(UX!8?-,g=cP\g&Sk@!!%o1
-!!'I]s+0aXs8VuM"ektYk.1PC~>
-!<E0!joD4BeGoT,eGoUBeH5g%eH#U!!!)oH!!*#K!s$m%!<1LK!<(FS!7fU"e^XZMeH!>6!!%o,
-!!'IXs+BmUs8VuH"f21\k.LbF~>
-!<E0!joD4BeH#W,eH#XBeH>j%ec5X!!<<#Jrr;uJ"96p%s8LOKs8CLIs8LONs4,["^=<5`MU__,
-[akD1o"G)'qpbkGs5rIW!.Y~>
-!<E0!joD+?g&Rt,g&M-Gg&h?/g&V-+!!)uOrW)rO!s%'/!<1[P!<(XN!<1[S!8?-,^=iPeMV8%1
-[bCb4o"tG,qq;4Is5rIT!.Y~>
-!<E0!joD4BeGoT,eGoUBeH5g%eH#U!!!)uJrW)rJ!s$m%!<1LK!<(II!<1LN!7fU"^=<2`MU_\,
-[akD1o"G)'qpbkGs5rIW!.Y~>
-!<E0!joD4BeH#W,eH#XBeH>j%ec5X!!<<&K"96p%s8LONs4,["rm_MYe^a]Ms4,["e^a]Mec3A6
-!<7r,!<9LXs+BmUs8VuH"f21\k.LbF~>
-!<E0!joD+?g&Rt,g&M-Gg&h?/g&V-+!!*#P!s%'/!<1[S!8?-,rn7h^g=cP\!8?-,g=cP\g&Sk@
-!!%o1!!'I]s+0aXs8VuM"ektYk.1PC~>
-!<E0!joD4BeGoT,eGoUBeH5g%eH#U!!!*#K!s$m%!<1LN!7fU"rm_JYe^XZM!7fU"e^XZMeH!>6
-!!%o,!!'IXs+BmUs8VuH"f21\k.LbF~>
-!<E0!joD4BeH#W,eH#XAec,UKec#OJec5XNec42!rrUaNs8LRKs8LRKs8CLJrrL[M^XW>aMU__,
-[akD1o"G)'qpbkGs5rIW!.Y~>
-!<E0!joD+?g&Rt,g&M-FgAV*PgAM$OgA_-Sg&Tk+!!:jS!<1^P!<1^P!<(XO!!1dR^Y/YfMV8%1
-[bCb4o"tG,qq;4Is5rIT!.Y~>
-!<E0!joD4BeGoT,eGoUAec#RKeboLJec,UNeH"/!!!:[N!<1OK!<1OK!<(IJ!!1UM^XW;aMU_\,
-[akD1o"G)'qpbkGs5rIW!.Y~>
-!<E0!joD4BeH#W,eH#X?eH#W<eH#W,eH#WXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M-Dg&M,Ag&M,1g&M,]gAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoU?eGoT<eGoT,eGoTXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#XBec,T:eH#W,eH#WXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M-GgAV)?g&M,1g&M,]gAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoUBec#Q:eGoT,eGoTXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M,1g&M,1g&M,]gAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M,1g&M,1g&M,]gAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#XGec,W5eH#W,eH#WXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M-LgA_/:g&M,1g&M,]gAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoUGec,W5eGoT,eGoTXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#XJeboK2eH#W,eH#WXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M-OgAM#7g&M,1g&M,]gAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoUJeboK2eGoT,eGoTXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH5d$eb]?0eH#W,eH#WXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&_9.gA:l5g&M,1g&M,]gAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eH,a$eb]?0eGoT,eGoTXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eU[^_!!*&-ec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g496c!4LV]Jb$\Xs81LRU&X9;\c@6~>
-!<E0!joD4BeGoT,eU[^^!4LGXKCZ_Us81=MV#TT>]`<Q~>
-!<E0!joD4BeH#W,eH5d$ebfE0eH#W,eH#WXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&_9.gACr5g&M,1g&M,]gAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eH,a$ebfE0eGoT,eGoTXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#XJeboK2eH#W,eH#WXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M-OgAM#7g&M,1g&M,]gAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoUJeboK2eGoT,eGoTXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#XGec,W5eH#W,eH#WXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M-LgA_/:g&M,1g&M,]gAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoUGec,W5eGoT,eGoTXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M,1g&M,1g&M,]gAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M,1g&M,1g&M,]gAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M,1g&M,1g&M,]gAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M,1g&M,1g&M,]gAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M,1g&M,1g&M,]gAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M,1g&M,1g&M,]gAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M,1g&M,1g&M,]gAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M,1g&M,1g&M,]gAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M,1g&M,1g&M,]gAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M,1g&M,1g&M,]gAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M,1g&M,1g&M,]gAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M,1g&M,1g&M,]gAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#X5ec5[,eH#XHeH#XIec5[#eH#W,eH#WXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M-:gA_01g&M-Mg&M-NgA_0(g&M,1g&M,]gAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoU5ec,X,eGoUHeGoUIec,X#eGoT,eGoTXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#X4eH#X,eH#XAeH#X#eH#W,eH#WXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M-9g&M-1g&M-Fg&M-(g&M,1g&M,]gAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoU4eGoU,eGoUAeGoU#eGoT,eGoTXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#XBeH,^#rr<#Ks8W#I!<<#Js8W)Ks8W#Irr;uJs8VlErVulIs8W&Jrr:R"
-!<7r,!<9LXs+BmUs8VuH"f21\k.LbF~>
-!<E0!joD+?g&Rt,g&M-Gg&V3-rW)uPrrDuN!!)uOrrE&PrrDuNrW)rOrrDiJr;ciNrrE#OrW(O'
-!!%o1!!'I]s+0aXs8VuM"ektYk.1PC~>
-!<E0!joD4BeGoT,eGoUBeH#[#rW)uKrrDuI!!)uJrrE&KrrDuIrW)rJrrDiEr;ciIrrE#JrW(O"
-!!%o,!!'IXs+BmUs8VuH"f21\k.LbF~>
-!<E0!joD4BeH#W,eH#XAeH#XJeH>j%ec5Tu!<<&K"96p%s8CIJs8LOKs8:CLs4,["psfBEqpb]H
-rm_,Ne^a]NeH#W,eH#WXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M-Fg&M-Og&h?/g&V**!!*#P!s%'/!<(UO!<1[P!;tOQ!8?-,pt>]Jqq;#M
-rn7GSg=cPXg&M,1g&M,]gAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoUAeGoUJeH5g%eH#Qu!!*#K!s$m%!<(FJ!<1LK!;t@L!7fU"psf?EqpbZH
-rm_)Ne^XZNeGoT,eGoTXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#XAeH#XJec,UHeH#XKec,UJec,UIec5[Kec,UCeH#XHeH#XKeH>j%ec44N
-!<7r,!<9LXs+BmUs8VuH"f21\k.LbF~>
-!<E0!joD+?g&Rt,g&M-Fg&M-OgAV*Mg&M-PgAV*OgAV*NgA_0PgAV*Hg&M-Mg&M-Pg&h?/g&T^X
-!!%o1!!'I]s+0aXs8VuM"ektYk.1PC~>
-!<E0!joD4BeGoT,eGoUAeGoUJec#RHeGoUKec#RJec#RIec,XKec#RCeGoUHeGoUKeH5g%eH"1N
-!!%o,!!'IXs+BmUs8VuH"f21\k.LbF~>
-!<E0!joD4BeH#W,eH#XAeH#XJeH>j%ec5Tu!<<&K#liH*s4./"ec5Ns#636(s4,["psfKHe^a^!
-eH#XKeH>j%ec44N!<7r,!<9LXs+BmUs8VuH"f21\k.LbF~>
-!<E0!joD+?g&Rt,g&M-Fg&M-Og&h?/g&V**!!*#P#QWT4!87G,g&V$("p!B2!8?-,pt>fMg=cQ+
-g&M-Pg&h?/g&T^X!!%o1!!'I]s+0aXs8VuM"ektYk.1PC~>
-!<E0!joD4BeGoT,eGoUAeGoUJeH5g%eH#Qu!!*#K#QWE*!7_)"eH#Ks"p!3(!7fU"psfHHe^X[!
-eGoUKeH5g%eH"1N!!%o,!!'IXs+BmUs8VuH"f21\k.LbF~>
-!<E0!joD4BeH#W,eH#XBec#OIec5[KeboIIec5[Kec5XOec41Mrr;rIs8VfCs8W,Lr;ZfIs8N,M
-s4>d$s,,>,s0gJXKCZ_Us81=MV#TT>]`<Q~>
-!<E0!joD+?g&Rt,g&M-GgAM$NgA_0PgACsNgA_0PgA_-Tg&Tj\rW)oNrrDcHrrE)QquHcNrr<)R
-!8#p)!/fJ1!4LV]Jb$\Xs81LRU&X9;\c@6~>
-!<E0!joD4BeGoT,eGoUBeboLIec,XKebfFIec,XKec,UOeH".MrW)oIrrDcCrrE)LquHcIrr<)M
-!8#a$!/f;,!4LGXKCZ_Us81=MV#TT>]`<Q~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M,1g&M,1g&M,]gAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#WnebfBceH#W,eH#WXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M,sgA:lhg&M,1g&M,]gAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoTneb]?ceGoT,eGoTXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M,1g&M,1g&M,]gAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M,1g&M,1g&M,]gAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W5ec,XGeH#WXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M,1g&M,:gA_0Lg&M,]gAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT5ec,XGeGoTXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W5eboLGeH#WXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M,1g&M,:gAM$Lg&M,]gAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT5eboLGeGoTXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W4eb]@HeH#WXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M,1g&M,9gA:mMg&M,]gAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT4eb]@HeGoTXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eU[^_!!*&-ec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g496c!4LV]Jb$\Xs81LRU&X9;\c@6~>
-!<E0!joD4BeGoT,eU[^^!4LGXKCZ_Us81=MV#TT>]`<Q~>
-!<E0!joD4BeH#W,eH#W,eH#W4eb]@HeH#WXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M,1g&M,9gA:mMg&M,]gAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT4eb]@HeGoTXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W4ec#RHeH#WXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M,1g&M,9gAV*Mg&M,]gAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT4ec#RHeGoTXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W5ec,XGeH#WXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M,1g&M,:gA_0Lg&M,]gAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT5ec,XGeGoTXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M,1g&M,1g&M,]gAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M,1g&M,1g&M,]gAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M,1g&M,1g&M,]gAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M,1g&M,1g&M,]gAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M,1g&M,1g&M,]gAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M,1g&M,1g&M,]gAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M,1g&M,1g&M,]gAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M,1g&M,1g&M,]gAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M,1g&M,1g&M,]gAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M,1g&M,1g&M,]gAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M,1g&M,1g&M,]gAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M,1g&M,1g&M,]gAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#X@ec5[Eec5[DeH#X=eH#X%eH#XHeH#X@eH#W,eH#WXec19m^&S-0eHMcK
-k2s>WJ,~>
-!<E0!joD+?g&Rt,g&M-EgA_0JgA_0Ig&M-Bg&M-*g&M-Mg&M-Eg&M,1g&M,]gAc`p_Z0Z5g'+2M
-k2s5TJ,~>
-!<E0!joD4BeGoT,eGoU@ec,XEec,XDeGoU=eGoU%eGoUHeGoU@eGoT,eGoTXec19m^&S-0eHMcK
-k2s>WJ,~>
-!<E0!joD4BeH#W,eH#X?eH#XDeH#XDeH#X=eH#X%eH#X9eH#W,eH#WXec19m^&S-0eHMcKk2s>W
-J,~>
-!<E0!joD+?g&Rt,g&M-Dg&M-Ig&M-Ig&M-Bg&M-*g&M->g&M,1g&M,]gAc`p_Z0Z5g'+2Mk2s5T
-J,~>
-!<E0!joD4BeGoT,eGoU?eGoUDeGoUDeGoU=eGoU%eGoU9eGoT,eGoTXec19m^&S-0eHMcKk2s>W
-J,~>
-!<E0!joD4BeH#W,eH#XAec,UJec5[IeH#XJec5[Kec#OIec5[Eec#OJeH,^#rr3&Ms8W)K"96pO
-s8CLIs8UXLs8:FIs8LRIs8LRKs8CLJs8UURs4./Le^a\WeH#WXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M-FgAV*OgA_0Ng&M-OgA_0PgAM$NgA_0JgAM$Og&V3-rW!#R!!*#P!s%$T
-!<(XN!<:dQ!;tRN!<1^N!<1^P!<(XO!<:aW!87DQg=cOag&M,]gAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoUAec#RJec,XIeGoUJec,XKeboLIec,XEeboLJeH#[#rW!#M!!*#K!s$jO
-!<(II!<:UL!;tCI!<1OI!<1OK!<(IJ!<:RR!7_&Le^XYWeGoTXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#XBeHu9+ec41Ms4,["rRCoJrm_,Ne^a^!eH#XJeH>j%ec5Ep!<;uI!<;rH
-!<<&K#636(s4,["qUGTGrm_,Ne^a^!eH#XHeH#XKeI2E-ec41Ms4,["ec1NW!<9LXs+BmUs8VuH
-"f21\k.LbF~>
-!<E0!joD+?g&Rt,g&M-Gg'Ic5g&Tj\!8?-,rRq5Orn7GSg=cQ+g&M-Og&h?/g&Up%!!)rN!!)oM
-!!*#P"p!B2!8?-,qUtoLrn7GSg=cQ+g&M-Mg&M-Pg'[o7g&Tj\!8?-,g&R#a!!'I]s+0aXs8VuM
-"ektYk.1PC~>
-!<E0!joD4BeGoT,eGoUBeHl6+eH".M!7fU"rRClJrm_)Ne^X[!eGoUJeH5g%eH#Bp!!)rI!!)oH
-!!*#K"p!3(!7fU"qUGQGrm_)Ne^X[!eGoUHeGoUKeI)B-eH".M!7fU"eGtKW!!'IXs+BmUs8VuH
-"f21\k.LbF~>
-!<E0!joD4BeH#W,eH#XBeHQ!'ec41Mrr;oH!<<&Krr;rI!<<#Jrr;`C!<;uI!<<#Jrr;uJ"96p%
-s8LRKs8LRJs8LOKs81=Hs81=Hs8LOVs4,["e^a]Mec42"MU__,[akD1o"G)'qpbkGs5rIW!.Y~>
-!<E0!joD+?g&Rt,g&M-Gg'%K1g&Tj\rW)lM!!*#PrW)oN!!)uOrW)]H!!)rN!!)uOrW)rO!s%'/
-!<1^P!<1^O!<1[P!;kIM!;kIM!<1[[!8?-,g=cP\g&Th,MV8%1[bCb4o"tG,qq;4Is5rIT!.Y~>
-!<E0!joD4BeGoT,eGoUBeHGs'eH".MrW)lH!!*#KrW)oI!!)uJrW)]C!!)rI!!)uJrW)rJ!s$m%
-!<1OK!<1OJ!<1LK!;k:H!;k:H!<1LV!7fU"e^XZMeH","MU_\,[akD1o"G)'qpbkGs5rIW!.Y~>
-!<E0!joD4BeH#W,eH#XBeHu9+ec41Ms4,["rRCoJrm_,Ne^a^!eHl3*ec42"e^a]peHZ'(ec41M
-s8LONs4,["rm_,Ne^a]teHQ!'s4,["rm_,Ne^a^!eH>j%ec5X!!<<&K$iec-s4,["e^a]Ms,,>,
-s0gJXKCZ_Us81=MV#TT>]`<Q~>
-!<E0!joD+?g&Rt,g&M-Gg'Ic5g&Tj\!8?-,rRq5Orn7GSg=cQ+g'@]4g&Th,g=cQ%g'.Q2g&Tj\
-!<1[S!8?-,rn7GSg=cQ)g'%K1!8?-,rn7GSg=cQ+g&h?/g&V-+!!*#P$NSo7!8?-,g=cP\!/fJ1
-!4LV]Jb$\Xs81LRU&X9;\c@6~>
-!<E0!joD4BeGoT,eGoUBeHl6+eH".M!7fU"rRClJrm_)Ne^X[!eHc0*eH","e^XZpeHQ$(eH".M
-!<1LN!7fU"rm_)Ne^XZteHGs'!7fU"rm_)Ne^X[!eH5g%eH#U!!!*#K$NS`-!7fU"e^XZM!/f;,
-!4LGXKCZ_Us81=MV#TT>]`<Q~>
-!<E0!joD4BeH#W,eH#XAec5XQec41Ms8W)Kr;ZfIs8W#Is8W)Ks8VfCs8W,LrVuoJs8N/Ns4.,K
-"4dGOec,UJec5XMec5X!s8W#Is8W,Lr;ZfIs8W,Lrr2uKrr7l+!<9LXs+BmUs8VuH"f21\k.LbF~>
-!<E0!joD+?g&Rt,g&M-FgA_-Vg&Tj\!!*#PquHcNrrDuNrrE&PrrDcHrrE)Qr;clOrr<,S!8@DP
-"53_TgAV*OgA_-Rg&V-+rrDuNrrE)QquHcNrrE)QrVurPrW%i0!!'I]s+0aXs8VuM"ektYk.1PC~>
-!<E0!joD4BeGoT,eGoUAec,UQeH".M!!*#KquHcIrrDuIrrE&KrrDcCrrE)Lr;clJrr<,N!7h&K
-"4[AOec#RJec,UMeH#U!rrDuIrrE)LquHcIrrE)LrVurKrW%i+!!'IXs+BmUs8VuH"f21\k.LbF~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M,1g&M,1g&M,]gAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#WtebfB]eH#W,eH#WXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M-$gA:lbg&M,1g&M,]gAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoTteb]?]eGoT,eGoTXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M,1g&M,1g&M,]gAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M,1g&M,1g&M,]gAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W5ec,XGeH#W,eH#WXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M,:gA_0Lg&M,1g&M,]gAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT5ec,XGeGoT,eGoTXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W5eboLGeH#W,eH#WXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M,:gAM$Lg&M,1g&M,]gAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT5eboLGeGoT,eGoTXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W4eb]@HeH#W,eH#WXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M,9gA:mMg&M,1g&M,]gAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT4eb]@HeGoT,eGoTXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eVO8+s,,>,s0gJXKCZ_Us81=MV#TT>]`<Q~>
-!<E0!joD+?g&Rt,g5#`dg&M,]gAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eVF3_eGoTXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W4eb]@HeH#W,eH#WXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M,9gA:mMg&M,1g&M,]gAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT4eb]@HeGoT,eGoTXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W4ec#RHeH#W,eH#WXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M,9gAV*Mg&M,1g&M,]gAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT4ec#RHeGoT,eGoTXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W5ec,XGeH#W,eH#WXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M,:gA_0Lg&M,1g&M,]gAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT5ec,XGeGoT,eGoTXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M,1g&M,1g&M,]gAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M,1g&M,1g&M,]gAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M,1g&M,1g&M,]gAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M,1g&M,1g&M,]gAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M,1g&M,1g&M,]gAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTXec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WXec19ks81=MV#TT>]`<Q~>
-!<E0!joD+?g&Rt,g&M,1g&M,1g&M,]gAc`ns81LRU&X9;\c@6~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTXec19ks81=MV#TT>]`<Q~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WXec17%^%D=+KE(uKeHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M,1g&M,1g&M,]gAc^(_Y!j0JcGcIg'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTXec17%^%D=+KE(uKeHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WXec17'^&S--ec17'^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M,1g&M,1g&M,]gAc^*_Z0Z2gAc^*_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTXec17'^&S--ec17'^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WXec1:%^&S-.ec17'^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M,1g&M,1g&M,]gAca(_Z0Z3gAc^*_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTXec1:%^&S-.ec17'^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WXec1:%^&S-/ec1:%^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M,1g&M,1g&M,]gAca(_Z0Z4gAca(_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTXec1:%^&S-/ec1:%^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WXec1:$^&S-0ec1:%^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M,1g&M,1g&M,]gAca'_Z0Z5gAca(_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTXec1:$^&S-0ec1:%^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WXec1:$^&S-1ec1:$^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M,1g&M,1g&M,]gAca'_Z0Z6gAca'_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTXec1:$^&S-1ec1:$^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WXec1:#^&S-2ec1:$^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M,1g&M,1g&M,]gAca&_Z0Z7gAca'_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTXec1:#^&S-2ec1:$^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WXec1:#^&S-3ec1:#^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M,1g&M,1g&M,]gAca&_Z0Z8gAca&_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTXec1:#^&S-3ec1:#^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WXec1:"^&S-4ec1:#^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M,1g&M,1g&M,]gAca%_Z0Z9gAca&_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTXec1:"^&S-4ec1:#^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WXec1:"^&S*6eUrMP^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M,1g&M,1g&M,]gAca%_Z0W;g4=hQ_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTXec1:"^&S*6eUrMP^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WXec1:!]`A*3KD`F_s81=MV#TT>]`<Q~>
-!<E0!joD+?g&Rt,g&M,1g&M,1g&M,]gAca$_>sW8Jc*Cbs81LRU&X9;\c@6~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTXec1:!]`A*3KD`F_s81=MV#TT>]`<Q~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WXec1:!]`S4dKDW@^s81=MV#TT>]`<Q~>
-!<E0!joD+?g&Rt,g&M,1g&M,1g&M,]gAca$_?0agJc!=as81LRU&X9;\c@6~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTXec1:!]`S4dKDW@^s81=MV#TT>]`<Q~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WXec19u^&N`^^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M,1g&M,1g&M,]gAca#_Z,2a_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTXec19u^&N`^^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WXec19u]`<]]^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M,1g&M,1g&M,]gAca#_>o/`_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTXec19u]`<]]^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WXec19ks81=MV#TT>]`<Q~>
-!<E0!joD+?g&Rt,g&M,1g&M,1g&M,]gAc`ns81LRU&X9;\c@6~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTXec19ks81=MV#TT>]`<Q~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WXeGt6js81=MV#TT>]`<Q~>
-!<E0!joD+?g&Rt,g&M,1g&M,1g&M,]g&Q]ms81LRU&X9;\c@6~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTXeGt6js81=MV#TT>]`<Q~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#W?eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M,1g&M,1g&M,Dg'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoT?eHMcKk2s>WJ,~>
-!<E0!joD3.eUc8%eXb4oV#TT>]`<Q~>
-!<E0!joD*+g4@t/g7?q$U&X9;\c@6~>
-!<E0!joD3.eUc8%eXb4oV#TT>]`<Q~>
-!<E0!joD4SeU`@(K7SZhKBC\fV#TT>]`<Q~>
-!<E0!joD+Pg4=g+JUrBdJ`bYiU&X9;\c@6~>
-!<E0!joD4SeU`@(K7SZhKBC\fV#TT>]`<Q~>
-!<E0!joD4SeU`@(K7SZiK)kr6eHMcKk2s>WJ,~>
-!<E0!joD+Pg4=g+JUrBeJH5`4g'+2Mk2s5TJ,~>
-!<E0!joD4SeU`@(K7SZiK)kr6eHMcKk2s>WJ,~>
-!<E0!joD4Sec19n]`J/HK)^D8J\C!Ts8V`)s8V63"f21\k.LbF~>
-!<E0!joD+PgAc`q_?'\RK)^D=J\p?^s8V`.s8V68"ektYk.1PC~>
-!<E0!joD4Sec19n]`J/HK)^D8J\C!Ts8V`)s8V63"f21\k.LbF~>
-!<E0!joD4Sec19p^&S*5K=up;!/#j9J\C!TrVuT)s8V63"f21\k.LbF~>
-!<E0!joD+PgAc`s_Z0W:J\m'>!.f^<J\p?^rVuT.s8V68"ektYk.1PC~>
-!<E0!joD4Sec19p^&S*5K=up;!/#j9J\C!TrVuT)s8V63"f21\k.LbF~>
-!<Bh3SGUk:KD3(Ys8R]Q^&S+eec18Q]n*lT^&.j)^&S,peHMJVS=BQZJ,~>
-!<B_0RJY_<JbR%\s8RWO_Z0XjgAc_T_L]S^_YaB._Z0Yug'*nUR@+$TJ,~>
-!<Bh3SGUk:KD3(Ys8R]Q^&S+eec18Q]n*lT^&.j)^&S,peHMJVS=BQZJ,~>
-!!)uB!1`r:s+C-\rVm&OK7gl;s+])(K7U^e^#6U(s8UXJs8'G/s5qi8SB\a\S,e'~>
-!!)u?!1E`<s+1!_rVm&TJUt]<s+]8-JUt[h_Vi<2s8UgOs8'V4s5r#=REE+PR/ha~>
-!!)uB!1`r:s+C-\rVm&OK7gl;s+])(K7U^e^#6U(s8UXJs8'G/s5qi8SB\a\S,e'~>
-!<CCD]`=T"ec1:!^&A!1ec17'^&S+eec18Q]n*lT^&S-2ec#OG^&S,peHMJf]tKp9J,~>
-!<C:A\cA/qgAca$_YsN6gAc^*_Z0XjgAc_T_L]S^_Z0Z7gAV'L_Z0Yug'*ne]"4:0J,~>
-!<CCD]`=T"ec1:!^&A!1ec17'^&S+eec18Q]n*lT^&S-2ec#OG^&S,peHMJf]tKp9J,~>
-!<CCD]`=T"ec1:#^&A!/ec17'^&S+eec18Q]n*lT^&S-0ec#OI^&S,peHMJf]tKp9J,~>
-!<C:A\cA/qgAca&_YsN4gAc^*_Z0XjgAc_T_L]S^_Z0Z5gAV'N_Z0Yug'*ne]"4:0J,~>
-!<CCD]`=T"ec1:#^&A!/ec17'^&S+eec18Q]n*lT^&S-0ec#OI^&S,peHMJf]tKp9J,~>
-!<CCD]`=T"ec1:%^&A!-ec17'^&S+eec18Q]n*lT^&S-.ec#LL^&S,peHMJf]tKp9J,~>
-!<C:A\cA/qgAca(_YsN2gAc^*_Z0XjgAc_T_L]S^_Z0Z3gAV$Q_Z0Yug'*ne]"4:0J,~>
-!<CCD]`=T"ec1:%^&A!-ec17'^&S+eec18Q]n*lT^&S-.ec#LL^&S,peHMJf]tKp9J,~>
-!<CCD]`=T"ebb!oec17'^&S+eec18Q]n*lT^&S--ebt.#s5qi8SB\a\S,e'~>
-!<C:A\cA/qgA?HrgAc^*_Z0XjgAc_T_L]S^_Z0Z2gAQU&s5r#=REE+PR/ha~>
-!<CCD]`=T"ebb!oec17'^&S+eec18Q]n*lT^&S--ebt.#s5qi8SB\a\S,e'~>
-!<CCD]`=T"ec1:%^&<T[ec17'^&S+eec18Q]n*lT^&S-.ebt+%^&S,peHMJf]tKp9J,~>
-!<C:A\cA/qgAca(_Yo&^gAc^*_Z0XjgAc_T_L]S^_Z0Z3gAQR(_Z0Yug'*ne]"4:0J,~>
-!<CCD]`=T"ec1:%^&<T[ec17'^&S+eec18Q]n*lT^&S-.ebt+%^&S,peHMJf]tKp9J,~>
-!<CCD]`=T"ec1:#^&<T]ec17'^&S+eec18Q]n*lT^&S-0ebt."^&S,peHMJf]tKp9J,~>
-!<C:A\cA/qgAca&_Yo&`gAc^*_Z0XjgAc_T_L]S^_Z0Z5gAQU%_Z0Yug'*ne]"4:0J,~>
-!<CCD]`=T"ec1:#^&<T]ec17'^&S+eec18Q]n*lT^&S-0ebt."^&S,peHMJf]tKp9J,~>
-!<CCD]`=T"ec1:!^&<T_ec17'^&S+eec18Q]n*lT^&S-2ebt-u^&S,peHMJf]tKp9J,~>
-!<C:A\cA/qgAca$_Yo&bgAc^*_Z0XjgAc_T_L]S^_Z0Z7gAQU#_Z0Yug'*ne]"4:0J,~>
-!<CCD]`=T"ec1:!^&<T_ec17'^&S+eec18Q]n*lT^&S-2ebt-u^&S,peHMJf]tKp9J,~>
-!<CCD]`=T"ec19t^&<QeeUrLfs8Ri(s+>m9J\C!Ts8W,LrIas[s8V63"e<iN]po(Q~>
-!<C:A\cA/qgAca"_Yo#hg4=gls8Ri-s+,a<J\p?^s8W,QrIOg^s8V68"e!NE\sWPK~>
-!<CCD]`=T"ec19t^&<QeeUrLfs8Ri(s+>m9J\C!Ts8W,LrIas[s8V63"e<iN]po(Q~>
-!<CCD]`=T"ec19r^&3Ka^&S+eec18Q]n*lT^&S-2KD<.[s5qi8SB\a\S,e'~>
-!<C:A\cA/qgAc`u_Yerd_Z0XjgAc_T_L]S^_Z0Z7Jb[+^s5r#=REE+PR/ha~>
-!<CCD]`=T"ec19r^&3Ka^&S+eec18Q]n*lT^&S-2KD<.[s5qi8SB\a\S,e'~>
-!<CCD]`=T"ec19p^&EWc^&S+cK7U^e^#6U(s8R`F^&S,peHMJf]tKp9J,~>
-!<C:A\cA/qgAc`s_Z#)f_Z0XhJUt[h_Vi<2s8RZD_Z0Yug'*ne]"4:0J,~>
-!<CCD]`=T"ec19p^&EWc^&S+cK7U^e^#6U(s8R`F^&S,peHMJf]tKp9J,~>
-!<CCD]`=T"ec19n]`Ni"s+>rT]n*lT]`J.coY(;)k1'X*c+Uf\!.Y~>
-!<C:A\cA/qgAc`q_?,;*s+>lR_L]S^_?'[foYUY.k1U!,b.>0P!.Y~>
-!<CCD]`=T"ec19n]`Ni"s+>rT]n*lT]`J.coY(;)k1'X*c+Uf\!.Y~>
-!<CCD]`=T"ec18Qs+13$s1nZseHMJf]tKp9J,~>
-!<C:A\cA/qgAc_Ts+13$s1nZsg'*ne]"4:0J,~>
-!<CCD]`=T"ec18Qs+13$s1nZseHMJf]tKp9J,~>
-!<CCD]`=T"eGt5Qs+13$s1eTreHMJf]tKp9J,~>
-!<C:A\cA/qg&Q\Ts+13$s1eTrg'*ne]"4:0J,~>
-!<CCD]`=T"eGt5Qs+13$s1eTreHMJf]tKp9J,~>
-!<CCD]`=RReUc8%eXb4oSB\a\S,e'~>
-!<C:A\cA.Lg4@t/g7?q$REE+PR/ha~>
-!<CCD]`=RReUc8%eXb4oSB\a\S,e'~>
-!<CCC^%%VDUk,=mUqNQ(^%.Znc2PBWS,e'~>
-!<C:@]()2>Tn/ngTtR-"](26hb5SsQR/ha~>
-!<CCC^%%VDUk,=mUqNQ(^%.Znc2PBWS,e'~>
-!\j]"rOqgI!53s`JcC<$^&RWIrk/B'!',Q~>
-!^m%2rOVUC!4ma]JcC<$^&RWFrji0!!(;>~>
-!cn@drOqgI!53s`JcC<$^&RWIrk/B'!-<Y~>
-!]^8*n%A^kJ`_OGJ`aZ.!6suG!h96FJ,~>
-!^m%2n%&LeJ`_OGJ`aZ.!6XcA!gs$VJ,~>
-!cn@dn%A^kJ`_OGJ`aZ.!6suG!h973J,~>
-">Mn:S=K,_!1\W&J`_OG^#f=>n\+sm!WY5@J,~>
-s$QngR@3TV!1AE#J`_OG^#f=;n[eag!WYVVJ,~>
-"DVuXS=K,_!1\W&J`_OG^#f=>n\+sm!W[:_J,~>
-">Mns!!)MYJ\?WJJ\A_0nXTUZ!]_tqJ,~>
-r^?bdn<nj=J\$ED]XmX$rrE$dJ,~>
-rcA)>n=5'CJ\?WJ]Y3j*rr<+AC3+n~>
-!BDn63Iq0]!.b->!!G#:0f^t=~>
-r'Z)9JH16$RfN@SJ,~>
-!HW#TF+F=B!.b->!;png~>
-%%EndData
-showpage
-%%Trailer
-end
-%%EOF
diff --git a/lib/et/doc/src/make.dep b/lib/et/doc/src/make.dep
deleted file mode 100644
index fae2cd02b3..0000000000
--- a/lib/et/doc/src/make.dep
+++ /dev/null
@@ -1,53 +0,0 @@
-#-*-makefile-*- ; force emacs to enter makefile-mode
-# %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%
-# ----------------------------------------------------
-# >>>> Do not edit this file <<<<
-# This file was automaticly generated by
-# /home/otp/bin/docdepend
-# ----------------------------------------------------
-
-
-# ----------------------------------------------------
-# TeX files that the DVI file depend on
-# ----------------------------------------------------
-
-book.dvi: book.tex et.tex et_architecture.tex et_collector.tex \
- et_examples.tex et_intro.tex et_selector.tex \
- et_viewer.tex part.tex ref_man.tex
-
-# ----------------------------------------------------
-# Source inlined when transforming from source to LaTeX
-# ----------------------------------------------------
-
-book.tex: ref_man.xml
-
-et_architecture.tex: ../../examples/et_demo.erl
-
-et_examples.tex: ../../examples/et_demo.erl
-
-# ----------------------------------------------------
-# Pictures that the DVI file depend on
-# ----------------------------------------------------
-
-book.dvi: sim_trans.ps sim_trans_contents_viewer_collector.ps \
- sim_trans_contents_viewer_mgr_actors.ps sim_trans_mgr_actors.ps \
- sim_trans_move_actor.ps sim_trans_write_lock.ps
-
-book.dvi: live_trans.ps megaco_collector.ps megaco_filter.ps \
- megaco_tracer.ps sim_trans.ps
-
diff --git a/lib/et/doc/src/megaco_collector.gif b/lib/et/doc/src/megaco_collector.gif
deleted file mode 100644
index 56a2c5891e..0000000000
--- a/lib/et/doc/src/megaco_collector.gif
+++ /dev/null
Binary files differ
diff --git a/lib/et/doc/src/megaco_collector.png b/lib/et/doc/src/megaco_collector.png
new file mode 100644
index 0000000000..d5c2cde7e4
--- /dev/null
+++ b/lib/et/doc/src/megaco_collector.png
Binary files differ
diff --git a/lib/et/doc/src/megaco_collector.ps b/lib/et/doc/src/megaco_collector.ps
deleted file mode 100644
index bdc603f087..0000000000
--- a/lib/et/doc/src/megaco_collector.ps
+++ /dev/null
@@ -1,3247 +0,0 @@
-%!PS-Adobe-3.0 EPSF-3.0
-%%Creator: GIMP PostScript file plugin V 1.12 by Peter Kirchgessner
-%%Title: /home/hakan/picts/megaco_collector.ps
-%%CreationDate: Mon Oct 14 18:04:40 2002
-%%DocumentData: Clean7Bit
-%%LanguageLevel: 2
-%%Pages: 1
-%%BoundingBox: 14 14 433 458
-%%EndComments
-%%BeginProlog
-% Use own dictionary to avoid conflicts
-10 dict begin
-%%EndProlog
-%%Page: 1 1
-% Translate for offset
-14.173228 14.173228 translate
-% Translate to begin of first scanline
-0.000000 443.079478 translate
-417.999508 -443.079478 scale
-% Image geometry
-500 530 8
-% Transformation matrix
-[ 500 0 0 530 0 0 ]
-% Strings to hold RGB-samples per scanline
-/rstr 500 string def
-/gstr 500 string def
-/bstr 500 string def
-{currentfile /ASCII85Decode filter /RunLengthDecode filter rstr readstring pop}
-{currentfile /ASCII85Decode filter /RunLengthDecode filter gstr readstring pop}
-{currentfile /ASCII85Decode filter /RunLengthDecode filter bstr readstring pop}
-true 3
-%%BeginData: 194862 ASCII Bytes
-colorimage
-"4bhXB)#L068!gRJNn]M`]jGHoiV;t7J0da:/CXf"%jdo1k5~>
-"5;@eBD>U16Sa3Zq*KWuJO.RI!$q5?!E_b_=TM8npfR\n/42gU~>
-"4bhXB)#L084%l+JQ%+u`_ujnoiV;t7J0da:/CXf"'&!2F+=~>
-"k%V!e`,ckkQ'lHmK'S4JX5tp<L9#;Q^3u(QC!o(QBml'QC!o(QBml'Q^3r(QBml'Q^3r(QC!r(
-Q^3r(QC!o'Q^3u)QC!o'Q^3u)QC!o(Q^3u(QC!o(Q^3u(Q^=#)QBml'Q^=$:QNNP?Q^7T:!1*SM
-J!QFaOckiiP*(oiOckiiP*(oiP*1rjOcbfhP*1rjOckliP*(liOckliP*(liOckihP*(ojOckih
-P*(ojOckiiP*(oiOckiiP*(oiP*1rjOcbfhP*1rjOckliP*(liOckliP*(ojOckihP*(ojOckih
-P*(oiOckiiP"Lk"OcbfhP*1rjOckliP*(liOckliP*(ojOckihP*(ojOckiiP*(oiOckiiP*(oi
-P*1rjOcbfhP*1rjOcbfhP*1rjOc`Z6iVqg:kPjZKlL+*+a6*B\!9=%A"mk[FeD]<aiW/*=kQBYF
--oQS~>
-%bH$2e`5cQk32'qm-_6-MP'sAnXb<&hOOY<qOIVXrLEq[qOIVXrLEq[qOIVXrLF%^SXlANSH,8X
-SH,8[SH,8XSH,8[SH,8XSH,8[SH,8XSH,8[SHGISSY#eN!1s%X!1s.[!1s%X!1s.[!1s%X/=rE'
-?h*%3ioB.^k32'qm-DXRi8EVTjlP[hlKdidiSNMOioK4_kigd*0116~>
-"k%V!e`,ckkQ'lHmK(25J`<$U($"<5j5T+YioB%Yio9"XioB%Yio9"siX"T(ioB%Yio9"si]#oW
-ioB%Yio9"XioB%Yio9"Xj5T(Yio9"Xj5T(YioB%Xj5T(YioB%Xj5T+YioB%Xj5T+YioC!s#ijq(
-j5T+YioC!s2rioWj5T+YioB%Xj5T+YioB%Yio9"XioB%Yio9"Xj5T(Yio9"Xj5T(YioB%Xj5T(Y
-ioB%Xj8IsCj5T(YioB%Xj8IsUj5T(YioB%Xj5T(YioB%Xj5T+YioB%XOn%E0iW/0@kQU8>md%pU
-ro*q<rTFFOmdAT`hu;U8jo+BFh69@gJ,~>
-"H0M7e_C)[#2nV*k3/jIX)J#\d;Nc=EGoi<Df]o;FDu8AE--)>F)Q,?E--&>F)Z8AEcc5BEcH>C
-F*;JGEcQDCF`h\KEH?;AH?=4TDg-DFHZF7SDg?JHIrBOWE.)eLI;aLWF+A4SI<'g]FanFYH?4RX
-G^XR\G]eLVH[A;)Jou9gEI`@WK5uBhF+e^^JoQ?gFbFd_Irg6dG_0sdI!(-aH[p-hG^"d\Isc?k
-FF&IXK6_ZnEdiFYKQMNkEIrL[K5uEiF*!"WH%BseH?Fm]I=H<lG'\a[K6qcqF+/U[Km.fpEe8[]
-L3%cnEeSa`K5uNkFbOpbJT?HiG_C*fI<:0cH\$0iH?Y$_IsuKnG'eg\KR7lrEdiLZKm.ipEeA^^
-Kl_]mF+ng`K5uQkFbXscJ9$?gGS#LJJUMZpFF8X[HqWkWe^iLSh>lL4jorf`e^`:-rn[Y7roO70
-iVq@-f`'_2hrNq^O<oD~>
-%Z[dDf%Jd3hV[>Qk3&pXX*XksJC]'EI"$EjI=-HjI!p?iI!gBiIXQTnI=6TlIXZ]qI"$QmJUMrt
-H[pWoJp`'"H\6itK7/<%I>!'!KRAH(IYE3%K7/H'J:r<(JprN(Jq\W.J:N-(I>*<'MLC,4I>NN*
-M1(,3IYiN+LOG&3JVnl1Kmnu1K8P&6K7Jo/L515:J:`Z+MM-M>I>*K+N.HV>I#<W.NI?M;I>i`/
-Mg^G:IuSo2M1(A9JrP28LOY>6KSt5;KS#54M26YBJ;&r0NJ)kDI>E`/O+;nCI>ir4O+)k1Mgg\=
-K8k><Lk(S:L5UM@KS,;6MMQeDJ;0#3NeN(FIYio2O+E"DI>rr4O+)qCIuf/6NI?e@JWG89MLUY<
-KT1D=LOkM9LPpVAK7f25MhlnEItio2NeE%FIYrr3O+;qCI>(_gdacq%g=tKAioB1_`ST(of@npm
-gtpuKjQ=eHdaQe"g=kB>iSrs\/:[~>
-"H0M7e_C)[#2nV*k30LUX31Iee&m0ab0%rNbKe8Tbfe;Sbg";UbKJ2Rc-4AVb08,QcHFDVb0A/R
-cH=AUb0J2RcH=DWb0\>UccXPXbL"DVcH=JVbg4GYc-4SXcI'k`ccsk]d*U"ac-F_\dEg(bbg4Y[
-dE^%ebgXt`e]cChbgaq`eBH@gbgjtbe'-=fc.'u;dW<X_c-On`eBcCibgFk_e]lFibgXq`e]cFh
-bgk"aeBHCgc.1%be'-=ecIC(edEL.cd*p4gcd(%ada?:hc-Ok_eBcChbgOq`e]lFibgXq`e]cFh
-bgjt`eBHCgc.1%ce'-=ecIC(edEU4cd*p4gcH\i-bgXt`e]lIibgat`[email protected]%d
-d`g7dcd^1fd*:+bdF-7hc-Fh_e'Q@ibgFn`eBZ@hbg)+5e^`7*rn[Y5rT4:(i76B0h>Z72ir8'@
-dc(2U!8.;-"lJD'k)`5d~>
-%VF8Ag=Xj1i8s"NkO#?LqIp"GD//HP!GuWHB`W!co4\8\]P$SF$u19WJCM'BJWe5iCi&BN"cpuB
-\YNp6Bf'aEC2Rg&D/*p'OH"$lD/*p'C2Rd'Chds)DJs90Chn'+E,KE2CMn6/Ec>f=CiXW4GA_;J
-G&)5ACjBr>G&2ABDg6,CFDQ>CF*MMIEGp2@GBReME-$>AIWKFWDL$JCIrTRYCjgACJ8]^XD1?PH
-I;OCSDLcYMHYn7REdqtSG&;hMGC47[F)lkMIX#^`EHltLJol!bDLHeIKQ23dD1ZkKKPu6aD1lqQ
-JSfs\DhN%UG^O@\EclqMJTbpbE-cqLK626lDh<@RMfX5uD23=VM/RroD2NF]L2DZiEf"acIr1$a
-G_^-iH#SX\It2BmFa&UXKmIZqEd`OVLj!rtDM*:RMfO2tD23=WM/RuoD2WI^Kl)TiF,=jeIVjsa
-H%p0jG]AU[It%lDM04&uD2!4,mFBbArn\"?jlY^hlc7r6aD(Tf&o=u<lIFkDe^Au:gt-eLjlX]H
-J,~>
-%VO>Cf[S7'hr<SGk3B-WqK2j_H$8Rt!I8n`FTH]2o5t+r^iSjb%!IJuMq,MXMjr"5G^/Lr"dm\Y
-^8c;PF`2GIG'\CUGBS.RG'S:uQ$7ItG'S:UH$4L[G'nOZI!0j^GCFa_HZsp`H%'scH?XmaI!p3h
-H$XsaJ9uKmG^Y'cJpMcqG_(9eKmA-!GD(?iL3S<#G_^WpKm/<#HAHj!JU!#uItr6'IsQrtK7c71
-M1'l0H&-rqMgL)1G`$ouM0Xl,H&R*%L3ST)I>W?*JpE<&Jr"Z0IXI*#LP'l3I"@-!Mh-58H\R8G
-H&[9'Mg:22H]WW0Lj>&2J;ni4K6iZ-Ko()8J:ET*MM-8:I>!K'NduS>HAR?$OF;b?G`@9&O*c\;
-H&mE+NHpM7I#r]1LM_<tIY!K(N.QD<I"mH&NdlS>HAdE$OaMk?H&dE)Nd?S9H'!H-Mg:;4IZJi4
-KmAc.K8b&7JUNT+Lkg8:IY*Q)N.FsneCN=,gYUiIj6#Of_qrqcB4tsmCMgKAkgA89f$]#7g=LYK
-jQ=NFJ,~>
-%VF8Ag=Xj1i8s"NkO#sXqSWHS`l7>`!QN+Q_u[iso>C^WkJ?N'%)pNDbjOEQbgl$q`l75]"k;qT
-jk7QH`;do.`5op;aMl3>f%%aZa2Q-=`Q6$=`l6$<`lH'>`l6$<a3)BCaMuEBaN;EE`lH9Bb/q]I
-a2lECcH+/P`m)WHc,\#O`m;cKcGn,Oa3VfLbf7rMaj.oNbK%rMbK\&PaiViKbfe&QaNMiJcH=8S
-a3;`IccF8R`m)ZIcH"/QI`B^Ub0J#Ob/hoLbKRuOair,OdE9PYaNi&Md`K\Z`mDoMd`B_Z`mVuO
-dDsVWa3r&RcGn8Sb0e8VbfA2Rc-ODWb/r&OccjDWair)NdE9SYa3W#Md`K\Z`mMuNd`B_Y`mVuP
-d)OGUaO8/ScGn;Tb0e8VbK&&Pc-F>Vs2m:Ja3`&Me&fh[`mMrNdDsSW`mVuQcc4ATajS8Uc,S2R
-bL"8VbK/,QcHXAWaii&Od)q13e^`FRh?r3&k2tmna5GLhC&McZCpiEje`#'/dX[eAf6F7Uk/p)B~>
-%U%fGfQ0d"jlV^nZ0n\eqHj;A]OpS=!arT_pKmueT3V"q!d'MolsC3@ctf]!8!?o@j@,l*?0bi$
-Q0LcbSQ5Jm&n&Cs@UNSQ?XdGNG0tPC?XdDNIpubr@piqV@qB"Z@UWtXAS>Ic@qBIaCM70p@:s=`
-D.R6o?ts@bDdd?t@;ogiE+*U!@rc$lDIIQuAoV6tD.@]uC3!^)C1_ZuEH#E5ASZErG&(];@;p<u
-HY7)=@!?L#Hspr9@X;^%H!ti9AUS-/G[l,<C4'N7F(Tl5DgZh>Hu<\HA9E!*I;!MG@XW61J7NbH
-AUeH3I:@PDBRjW7H";D?Cjol?F(^&8FF%JJD/Fc4HZ`tQAo`6.J8T1Q@sN61JnK(N@Xi?4J7NnK
-Aq=Z8I:@\GC4To=G\)G@Dgc)CF(p5:Fa7MKCi4]3Hus%RATN0.J8K-QIq*eIB7a`9HXhSECOfo?
-G%Q>>EI;5FE,'o6GB[YMBlAE/IWAdcmFBtjh>lL5jp(&;m)S&9b54I:V!II!iRQSL5s^BE5sa/i
-ha2h~>
-%U%iFe8\0oio?7kXm<&jqJ-.Y_/esZ!c>]&pM0i%V.oR;!e?\<lt[&Vd;uS4;4V*hj\`(FC?oX=
-T'K2%U14%9<GZMfDSL^=Ci!s(DJa3>dt2LREGfW6CiFB2Ec,f9CiaQ5FDZ#<D09`8F_l2?DKfr=
-F_uDCEHl;DF)QDCFEqbNEcQMDH$4+TDfpDDIWTUZDL-VMDh2kNIVjUYEe81UI;jg[GCaX_H#eOU
-H[TjcFEW7RJ9l6iDgHnOKQVHjDLd(SLN%QjDhWCXKl;KjEJSU[KPlKhFbamcIrU9cH%^'iH?=s]
-It2KoFEiLWKm[s!Dh!@XMKO0!DM<L[Mf=)sDi&[^Iu%uqIWLKfI"lQsH$>-aK7J!$EdNRZM0a?'
-Dh3L[N,s<$DMW[_Mf4,uEJnsbLi.urFGt-fKQ)flG_p<lIWLKfI>)TsG^#$_KRe*%EI<LZM0X9%
-Dh<O\N,j9#DM`^_Mf4/uEJnpbLi/#rCJjEKg"P3;hr<\YkN_<LhuVHMr]h/a6q!m8lI+M>f9efg
-MJbgMf]h-VJ,~>
-%U%fGfQ0d"jlV^nZ0o;pqRH[Djgslj!kRI0pUL@Tf!k:^!lDd@m(!SAl`&@cMoh:8nrhbQ\Eg[/
-deAjk^oR:AICeLV]=GPe\\5Vd`p(@Q\\5Sd]t(ef]"P\e]Xb_e]>1tj^:M(j]>(nj]Y)(n^VIIt
-]tM=q_83e&]YD@r_nWn']>;=q`4Wh%]>MCr`4Nh%]Z%S"_n3n'^;[b%_S!k$^W*n*_S+%'_Ss1.
-^V@h$`PT=0]YVS!a1oAha1K=.]u[k&`k0:,^;mk(_n=((^rF",_7mt%_o04/]thY"`kf@0]Yh\#
-a1f=/]?%k'ah5R2]ZIq)a1KC/^<+%+`Os=-^rX.._nF1)_oB=1^qaR']>hb%ah>R2]?.n(aLfF0
-]ue"*a1KF/^WF.-`4X4+_8j1/_S4.)`5TC2^VRt&a2>X5]Yh_$ahY^5]>hb%ah>U3]?.k(aLfI1
-]udt)`k0@/^W=(,`4a:,_T0:0_RYBfe_C)[!9!k=#3bLAa5GRlq`tgilgE<^e_$<V6&KJE6.kP]
-6@]~>
-)-Q.ZdS3#*^6hG_K^Pm0<)ckE`PH_hrj5o/<$PYKai/ON^W2XBDT/0rK7X!GEjWoR<4&F>Zt\+W
-KUg-#Ki@tMBS!s2CUef=9mO^pGEJ_;b'/l&DoK_E?,`n#;cK$i>1`"fdrUc7?0:*mUW9H>RC]YP
-cV[Y@A[':qCk9OFLf]Z&5L,g"TuX9AK#Pj,LAfDN]uQUHCrNH&XeA]r<E<:&>$+d1=BILg<Er[,
-?<:<8<af-7@96f@<ao09?WLT=>@^fE>utW@?=R#I>?YW@@U`GU>[V8IBjb.]>%M8p=);/ND-(O^
->B!eZBj#@]?uB+`@p3kWAnkIh?t"%YDIm!n?"[tVEa`?r>A[tUF^8Tt=`RtXFB`Qq=a"4bFBNWr
-?$BRiDHV*kAp7F$B3fjjD/`['@q9ggFD4s+?YjadG[t</>B4I^HXCN1=a+IdH<bH,>'j[lG$0!$
-B4#sjDf8g*@V9pgG%b3/?>a^cH"1E1>'4OaHs^`2>'ORgH!>?)>C9dnFBNj"@X24!Cg)0nC3<['
-Amp!kE,Jj+@;'jfG%Y0/?#OXbH=CN3>'4LaHX:T0>'XUhGZo3'>]E-rg]$%=i8s+`l0[p*`8KIp
-932$n#u[_ima^.Gh9Tj85m9`Bl0dFqJ,~>
-%U%oIcV-W(]U;;YJF9L<rac=ka2Nb2rOQeDAKu'!bK5Ho_oe]fIESM<NK3qaJ[rpsB"P1d\9Qco
-OJBt<O(A6$FcOLcHG59a?AQYAL7PJnc@VLLJ&fZhDTfGOA7_IGB%uU-epa4PB^+N5XN@eaUVXHt
-d:-ZuFh,]9HB6.iQ=u]P:"#bHWl_YeON>YFPl/pl_TJ]kIET!S[&IVPBP2-oC2.?sBPD<qD/!X$
-BP_R!E,',YE+a**B6.a'E+a3,CNF00DJ40-DffZ9D/4B1F)kr=CN+K2G].ADC3=W4HYmbLBmF`7
-Ir':QBmsu?I;4.NCOp>GH>.kJE.<@PI!'1UD0C8?IrTCWCO:5>K5Pj_C4LDEK5>m\C4gJJJSK^W
-DM2kQHtn:RFG"=ZG&;tOH@9O]EcZnLJ9PgbDgHnJKQD0gCk6kIM/R]lC5$bLLM_QgCPZqSK5-'^
-E//:ZHu"LWGD'^aG&E+RI=>seEcm(OK6M0gDL?DQCPHnPKkl9bCl*(WJ80g\Ee\C]H>A=UH%Kdb
-FE*(QIsYseE-R"MKQV3gD16nKLN.KjC4pbJLi.WiCPQqQKkl<bD1>@Gg"P3;hr<\YkN_C!_Vj.h
-8l\qq>#_Ebm*seBg<=7r6UXM2k3CbgJ,~>
-%U%uOdS3#*^6hG_K^QO?rj)jLj5Io)s4F^XZQls5jl*tmiSr4k_!0D8a2\/?^YIksZJjKth7N+H
-`7!]&`NoKLCrbSI^>HiiW5[fU`6m/LkJ5?a^uOIp\*;\iZEr!+S*][WlaG43S+Z3df&PJleDoE(
-lE7J"]A;Q+]#`mjbI#UiNU4H\f&PMoaQ;F/a8b5BiT&Cs_!0Xlg;pS/['[?M\$iWR[^E]R\@?pn
-]!f)Z[CNfU]!]/\[D',\]sYPa\%];_]=#A^\\5D`\[K5\]">Aa\@K;\]XbMc\%[email protected][_TMa
-_RI4m[_]Mb_7%+j[_fPe^UCth\\Y_h]XG\e]YCki]"#Sc^V%"l\@fVc^q.(n\%fVb_R[:p[_]Sc
-_RI7nGIGB!]>:ql]=>ki^qdCt\\#eg_nEP"\A,nh`O`\#\&5qga18q$[`,ki`OE_$[`H(pa0rt$
-\]D:s_m[Ut]uRS"^UV@q^r3\%]Y):n`5&k(\\Q.l`kB"*\&6"iah#7+[`6"laLB%&[`H%o`jWk#
-\]D:t_Bu_4]=l7n`P8t)\\Z1la1T++[`#qjaLT+)[`?%na1'"&\&*d_g]$%=i8s+`l0[p*`8KIp
-932$n#u[_ima^.Gh9Tj85m9`Bl0dFqJ,~>
-)-Q1[hS)lR6:FIikjkW;:/53IQ(tj3pfBl_:*ZFdCL:,tQttW-Fo.?D[SZaEW6'A<>i*DdohE*5
-6gq$\:eL^^FC+']N2Usi:"5N&]781UpQi:(aeFs=@eus"8l!-^8[uW"p25uQ6.M]ZiH<jn[,$"1
-N]g-4[a&>k@H;u]k&$%A4jBOHj*'%<k`8eM9_a(gT5!28DYo\oLsejj;-6Rn<DQ^q;HQas<Dcmr
-='&7(<)cCm:g-pu>u=X+;-m4%?Vk$3;diR+>u4s2=(G39?;tQ<>%CKA>ZPK9?XZoJ='TE9BO=hV
-;dj38C0=hV;JBN?D,XnV;fGuHIrA5"A63eN@;AbZ?!D5FBOt4b=C>uEDdcgh<G,uGF'<!i;fQ;N
-E`Hdf<c_MRE`6si=a!hYD,k[a?ZT.aB39@YAT(Oi?s[nRD/!-t=CuMOG%"^"<,QGQGZeTt;g)YV
-G#`Bp=*IkYE`7*l>^'1`CfYac@WPIhAm0F[Bk2*]G@"^!<,lSSGZJHq<H_bWFB!0m=a4%\E)_!i
-??K7cC05^aA8tOjA6j@YCi!0s>[qeQFCe[#<GHAOG?n[!;fZMSGZI/thVR/LjlYakmdBQ4_r]au
-N8s'_keXChnCQIph>kh"5m:rgmdB($J,~>
-"^0sBhRlhd6k=A%n>]5f>AMl\VnIZU@8[#.,H'@>Bk?.nG2e7+qjG[=>k`cLb^eD]i5hP_=MV^J
-n#g>0<rQ<QCZL;7Y(?(Det&VPM:77PS@imdVO,JEq5I_&>Jle.]u3S;G*qAcf;=8^I,'([gjs%$
-8m>N4dVN];jbeNNH'@Pcd%Z9UIG(+TQ=FT7pP%:sFQ&.'qO(NNdoTm^@U*;K?"@8KA6`YR?=mMQ
-AR/qV?tWbXA7'(X@qT(_s'f,H?"dkYD.$pk?>X7`DI.*n?uTOdDd@?r@[email protected]#CL_Nq
-DK0'/AnZ?pFDYN5?uC$nG\Li8@!$?tHX^f7@!QL"H!k]5@XDX%G@,Z4B7+-/F(Sm0ASZQuHZ!GE
-@<-L"IV3GC?[?[&IpmA@@=N!+I:.>AAV"?1H=;8=C49T:FC]r5E-u)EDJ=W0G]mVLAo<$)IrK(P
-@Wm!+JnT"M@"**.JmrhI@Y&91IUIPEAqFN6H=DD?CM\K/HZWhO@rZj(J8K%O@<m!+Jn8kJ@"3*/
-J73YGA:eH3I:.PDBRsW9G[l;<D15lAEb9o4FEq>HC2AB-HuikO@nc1AgtpuKjQ>[km-j>XinMS5
-i8`n]^8^Mge_Ag4h985S6tbcNmGC3[~>
-)-Q1[hS)lR6:FIikjl6FW2R#g]u\a6s,i`KW$B^RTq.Y?]Vb,,]DoM#e"Zl>akj2aVX`BUqO-<m
-MYY;`R%jSYGd$\Ha3:[^OR'[$f"BtOqnLp[il/XfXoH>)U8[%YT\nCTs.IO*N:"H`m],QTgutf1
-\r3Mcgu"WoU@PFgnZg10M<_mfn#PZfoXC0WT`;"R_kc_5\Gs.&`S[5cWirJ)Y,\Y+WirG)Y,SV*
-Y-4k2XfSh.Ycr2LZ`C77Wj8e/ZDt.5X0\k/ZDt45XgG+6YcG15YdLL>[email protected][BQdB
-X0T(4\?<*HWjo@:];r<IX1GL=\Z30GXh1X?\#R$DYdpdD[]R6EZF['JZELsD\%/WSYd1pB]=+lU
-XgYdA]s4hk]WA]QY.h$G\u`QMZ+R0K\#mBI[(EEPZ`q-E\@A]VYI2!D^9k/ZXh)$F^Tb,YX1l!G
-^9+rVXhV*I]W8`SYeI6L\ui]OZb3BP\$*QL\%8]UZEh0F]=4uYY-tsD^9b,YXLbpE^TY&WXM2'H
-^9+uVY.q3J]W8cSYeI7>\MUG'Z*_0E]sb,ZXgksE^9Y)YXLu$G^TN+RhVR/LjlYakmdBQ4_r]au
-N8s'_keXChnCQIph>kh"5m:rgmdB($J,~>
-)-Q1\j6"3U84n6hp%G:J8kO!_cH!2+p.e3Y8gD'\5Y,&S@nG[>E;)i/[RKn/alC.Y@bZl[p-cBt
-6B0.4M+IS;J%W8&E.7:^jNkiOB&]i0be@B?d_iV(pL-N_9#$?UZarHrDN<d?d?gQp_:!V5\j/eV
-7nQD)Tg;4fqasNUFGT3Dbak3k_9o7[9LVKJp3-:I9\kqLpJ+;2ej2r*9i4e^<)67g9N"\\<)$1f
-9ik.f=%u[m9it.h<D6Ik;-@*u=B&%#:K:Ol>ZFX.:g@4#@T-?9:LI4#@o6H8:M!L-A5Hc<;.id4
-?Vb65=_LWD?;YQ=?tN8N>$,Q<ARJDQ<aKH9C0FYS;e0<6CfanV:ha-6D,b"TIo1#a?>WPU>ublE
-AS+hY=^5fACL:"\<F]]>DH^7^;ef]=EE6O_;/TT@Dc:=Y;fu/ODGbFZ=`dVYAQ*\Q@W54c>uu/K
-C1gIf=^Z5IEF2^h<G6)EFBW!k;fH,DG?/?l;KQ,JF&Qsc<-D>SD,PF[>BEh\A5dYQ@rG4b>uXsL
-<,6)EF]`'k;K?)FG#`6i;fu5NEDgd`<HhJWC/T.W??/t_@8qGO;F'U*hk+1[?=[ZTn+H:ijke4A
-k2tmp`NA\(g>(QAeT!l@7SoiGoAr;h~>
-(g6(ZiSq^Q6pu=[na`VP=BKh1d`Sn>p0%>r,K%5l<bD,C=QG`opJJK4;YG@Yjho;Xh33'V:qX>8
-QHdg?=8l<2=i.bbG_tp$jjM;ZDr[t@cGX>Qf#PF=p1[H-=N6V,\@kZ2G*_5\e=<?(`RTIG]h;C+
-<`iJVVbpK@qGpbnIZ`qec_@'%`RM!e=]JO.p3l^W>Mtuqp/kFVfM,OV>$YE`>%(W@@U!8J>@UoG
-@U!AL?"@/M?s@5J@:WSU?X@GPARo%]?XmeTC11Ib?"dhUD-pgj?#4%YEF3Ep?>s@bE*dHp?ZTUk
-DdINsAoqC"BjZ$mCiNd(An?-nEGJp+@V^$kF_50.?u^$jG[kN3??^'mH!t]2?[?9uG[GW/'k2N!
-E,o?5B5)["GAL]:@rQQtH>$uAH=:u7@=;[)G$fQ/B7"'1E++6-Dg>];C1_p(G&h#?Ao<!(HYd5C
-@ruj$IV<PG@!Z["J7N_F@")g)I:7D>@Y&*2G[Pr7BmsK8EFFB/E-bo>CM/-+G&h#@AoE$'Hu*DE
-@s)m%IqNVG@!c^#J7E\D@")d*I:.A=@Y&'2/U(TOBki')H#I,BARJ0qh;4]0?XR8MZgRDR^u=.o
-NoT9blG9Rjo%2OLhUHTF6j62Um-rt"J,~>
-)-Q1\j6"3U84n6hp%GnTUSG6ehqQ;Ss,NiQUEeXBOJ&QNR%NlV[/Z$;dZsj+j6bFQT^T7ls,,X[
-PJc8=`M*7*Eo57#U:^8gn_i0FVXM[\hV+:`in;\Qs-T@OUZ&MNgXMAcTZ?VZlat71fA`g\e;g2n
-Sti(G^QbCuremKHVo8=akeP11fAagLNLZW=s.oU`U@,V!s,N_dj,^"7V5C2eVl-AjUo1/eWMZYq
-V6$SmGH@X@WMQ_oWN2ksW2?\nWiDntVl6\mXJi&!VQHqrZ)=V*V6HqsZ)4Y*V6Qu!YbeP'VQm&$
-XerD'XL>(6YG\n1YI(49XfJq0Z`p@:Wirh-[B6I<W3W\+\#Z[?VR<S+\#HX<Vmi_/[\pL8W48h2
-Z_t75XF@UU['-C;Wj/q/[]HR>W3ie-\>ld?Vm`_.\#?X<W4T+8\>Qm?X1P@=Z`(L:YdgUAYH#46
-['ZdCXKT14\?DmEWjB+2\ui-GW40"0]W/9GVn0"4\u<'BW4T(8\#6d>XLbC>ZDbC9Z+-^BY,f16
-[BlgDXK]75\Z`$FWW0=lW4K(6\Z!$BWP#7;[AUU<Y.CR@Z)G=8Vge!hhk+1[?=[ZTn+H:ijke4A
-k2tmp`NA\(g>(QAeT!l@7SoiGoAr;h~>
-)-Q1ak2tjI=a0!"p@bCK8kN:7V-RMAoj^\p8gBh^Htd9LR!@S-E:uc0[RKb=XjCKb:YUeIp-c4'
-:ip-]fKoI.(kM2%7YL8&c_auV<6EpCmB0+&Y?k[?p0dkl(7qEqZarKsDN<d?bc$BZF'htQ\Nskq
-r^p>!dWB8FjF`!E?ARl.baj"?G@,IQRV->5nqZ"mGi*RUp.S)NY<boU:f9td:JOk_;Gg.g9i+b^
-=AVgq9NG(e=A;[o9NY.h>>/.!:0^On>>&7&;-m"&>\6cA;H@1"@9?E;:Kq+#@oHK>9k.C*B2;f@
-:M<d3CJSSO;f5K>B2<>J=DL`E@T%)C?"cuL>ZY`<A7JMS<Es65CL1"X;.='5D-("Z:MjN@ED^7[
-;/o`DD,4tW<H:rGBi&bQ><?^uC1C4`;djE:E*QOa:hXB<FB)df:39iHFAQ^c;g;APF&6si=EmbY
-D,YX`?Z]+bB30@WB5UUk?=%u#;/g2LGuS?o;0H;OF]!$j<I%VTEDUge>BWn\CK5U]@WG7e@p+"R
-CMZsp>$uDJFCeR!;e^)IG?eKs:i^2MGuSEp;KlGQF]!*k<d@\VCI%7CjBt8?84lL$p%J!pjl"OH
-k324#`NT"/g>(QDT0Yc%F%T'cp>nVk~>
-)-Q1^ioT=?;g%0koC]%S<E3SZW+K^^okmn2<?n-oK5khbT7Q$HGkOtF\kqsTZI3H#>2><dp.r-9
->^^J+fM2<E(l@\-;iC-Ed]-nm?d7>Zn$Z<@ZY*r\p1XG*(8S$3\%PN0Fd1uXc`N;jH"UKm]M*:8
-r`(GUeU)@_jG\lWB92@Jc_?!QI;"#jTPnjUnrM_*KAq<#p/Y4h[7jh+>$?DV?<C?;=']'5@9?cA
-=(,<:?rpcC=^tQ>@om8K>@puH@9I8J?Y*;O?X.;IAS,+]?!qAKCL^Xe>%MANDdQpi=D_\VF'E9o
->&n(^E`m<p?$0CcDcq0m@WP^jC0bsfAoLmoARTacDf/j*?tXO`F_P6->]"CaG@G-*>'4U:@!Z'p
-EEmd"ATh7!CgVNoCiWa*ARp!gF`(Q6?>F[eHY?r:>B=aiI:6l8>'k$pHsC`6FC'H,C3j'2D.8!#
-EcbT9ASHKpH>d5A?#XslIV*5>>Bk*pJ6m,;>CL6tHs:c6?[uO#G[#T2AURg+EaO<*CO'*3Ch%p!
-F*(`<@qp<nHYm5A?#b!mIV!2>>Bt-qJ6d):>^g<uHs:i7@";U$E_>WRiF;dS+[nnHnal@fj581D
-k3)$q`3&V%g">0>SjYu*DFR1Vo&;rc~>
-)-Q1ak2tjI=a0!"p@c"PS=HG<`LEBorLBJYS0Q2@Z`L:q]smF&YQ'F4dZFC/e)?gfQ0tu^s+f7Z
-RC&gFk)oV4(q]M!NP51Iji3d[S)ib7oZr]ZbaY,ms-N_T(<aU`f[Pr]T>U5RkJk1&VOX%'duLKM
-rg[TPiioPkn?KXoQ,*-IkJ4@kW19pZ_5aW2r35S)\F$&ks,<Jkb);p_T:VRGSXuUJTqS$PT:_sO
-VP0Z[Str-QVOsQYSu/6TVOjTZSu/-RV4FKXTrO]]VOsl]USs`_UnOf[VP\R0WhH2eSuJNYWh-2k
-T<P2hYb/%tTsCAjY+MqrUp-MnX.cemVllYrW2$VjX/r#"USb5eYGe5$TW5)dZ)"8#T<G5gZ(\/!
-TWt>iYb/(uU9^JnYb8A$VR)r"XJ3+sWj/2'W2?qpYH=P,UT(Mj[&Kn/TWYGCTs^\qZCeJ'UpZkt
-YG&A#W3W&$X/!(rXKS;(VPgbmZ)j_/TrYDj[&9e-TWkMl[A'\+T<tPn[%OV)U:$bqZ(JD&V6lnu
-Y+`8!W3W&%Whd%rXfnG+V5U\lZE'b.TrbJk[&0b-T<YJm[\9b(I-f_N?pR+M8kL1Pp%J!pjl"OH
-k324#`NT"/g>(QDT0Yc%F%T'cp>nVk~>
-%U&2]k3)+!h<">'p@kFKr^mE2[(r&2Y-`QTE[,.c^q4H!Zb1rSB[&o9R7!^^@@Y0<>e,&lbsHEk
-IBgMoE+o5k).?peM`l:)4))(;R893V6HFC>@^3_@>g?CL8q1Kq>b%<Nc=)4:4G:anMS?`@R@?Kf
-_ECL`>,&jE@!&rlF?Oug40O?2N4llGEOruP9VT4DZ+PoVABdYJb%XF>:f9td:/4b^;G^(e9i+b^
-=&2Xo9ib.d=ADdp9ik+e>>A=#:0^Rp=AE+#:gQt&>>J^+=("g3<`*@'>[1l:@T-B=:h*U*B2MuB
-:hE[.BMrJL;f,KAB2NGI=DLfH?rCiA?YE;O=]T?;ARSJQ<aBE:C0FVS;e'<8CfanY;Jf]=EE$L]
-;K#ZBD,P.U<,klJBMrbO>AdAS?rV,G@VSbY=]mh);e]]>E)pLe;KH&FFB!$e<-;ARF&R-f=*Rb]
-CK,I]@!#@f@TI_TBl-dk>[DPPE+Dsn=(lMNF^89UF]E?l<HhPWEDgmb>BX"`BN97ZA9(Uj?WhSR
-Chcpm>%2POF(&-p<bcGMG$A?r<,lDKGZSTs;fu>OF]<<k<HqVYE(rU^jQ<CQD/O60_=mTq^uXV/
-DghV;&q@akp=n3Yk1tKWlJm;ro_.B5J,~>
-%U&)VjlYgmguS"sp%P@Sr_Wo?\AF\@YI8u\G9^mu_n0o0[_[ejDU2"MSkGimCSSeQ@_@/,cV&E%
-K<i>(GB!P*)/!NrO@Xc@6u]WQS5u/f9uqiYBXPaO@aAE\;0$NsA"TGectS-K7>Jp-PJFnRSY/T(
-`C<^%@&V#TAUD)+H:NJ)7'VYKOhe\VHG.4`<2I<W[)%eoC<oacb]-Q[<`W+#<)m.$>$"X-<*<F(
->uk!3<*`X+?WC98<+/p2@T?`?<Ff09@T6i?=(YKA@7XF3=^5Q>B3eVS=(5Z?CKb%Y<bYrDDcpXb
-=)D5LD-1R`=`IVVCKGF\?#Wq^Am'1ZAT(Xi?sRhVCM6jl?"@nVEFE'n>&%ea=`n%\E`d<k>'=+c
-Cfkdd@WP[kAQj7]C2[3t?X\.^EG8U%?"n@^G%+j(>B"@]G[>*,=a4F`H<Y?*>'aOgG$0$#?$fgp
-Dd%EoATq=#B3]ghDK/g)@:XUdFD+m*?#4RbG[b-#H!59(>C0[kFBEct@!Z$sCg)-lBQ[I&A6sUe
-E,Jj*?Y=ObG%Fp*>]4RaH!k3->'4I_HX(E-=a=FcGZo3'>C0XlF&PZoiSpbKBk_C#^@V'j^>n5&
-EIE:cJpk?)p=e*UinJsQk2CZgnFYd-J,~>
-%U&2]k3)+!h<">'p@l%Jrf[Sbcdodsc-EWoXWsXXf@-CgcIT(JV;d-J]nseYT>T7)RFe:1ie+;c
-XjGVHTq_Og)5<eTY_TF=J>UWC^6?FXLYS_bU!;0*RcBJ.PA[2QS]/@"j-?t'J[X7/\^]0)_nLr2
-gOk]RSAj+.RAnWcTn9Q(JC1Q^\^T*,VUX5/O2o_Kc.94PU>gs#i1#jmQ^3l(QBdo(R$a2.QC=;.
-SX>b7QCF>/SX5b7Q(=;/SX,b6QCXA3SsH%:Qm&/hSt)+?Q^aV5TUD.?Q_0h8U6qIDQDC+>W0j9S
-Q_p:CJ#A[0TU;[HTV\!PS=?FEUnO3TR\6LEVOa3SRA6IDVjj<UR&6FDX-of[R&c^LWL0ZWR]MpQ
-V3n<RT;e3VTUDmLUo'N[SXujLVkKN[R\QgKWh#Z\RAZdJXIGu`R&cgLX-ol]R]N!QWL0]XS?/-U
-V4"BSTrFH[TUW$OV/)rrX.5i_RAlmKXI>u`RB)mNWgTf[R]MsRW0jWVSZA0VURJ9RU8XH[St)mM
-Vkf`^S"ZgLWh5c^R\lpLX.5i_RAljKXI>u_RB)jMWgTi[R]MsRVj)JkjQ<CQD/O60_=mTq^uXV/
-DghV;&q@akp=n3Yk1tKWlJm;ro_.B5J,~>
-%U&5^k3VO(n+?>Ip\pjJrC$oT4$#Yp:QGF3,@Neu3]f\n3]fVr5<VFr5smat5s.1l697M!4[hRr
-5W_"sO8b"SBL>'I6:F(%76ipq5Xde#697M'5W_"l5Wes6(Irk)6T[S"4%2:s6p<[u4ZY\m4$c:u
-55mu>5s%+i6TmIl6:F%$6om\&4ZY\m4ZY\m6U*^u4Zc&&5='UE4[i"77o2fL:Ie/R85MiM:.A,R
-92e>X:.S>U9i4AY9MBq87oW;V=@uCk7T`M\>"Map8mY7i>=_st9OC@l=@lps;dW(&<_['r=Be@-
-;H.1!@U)ZB:0M*uBNJ,F8mkq!Bi%oA8S;.&BM2]=9l!U0A4^K<;JJj4?VG66=Ck';>Z#?3?Xl`F
-<EEm,B3e>N9jV@&CfXPN8nD=*Dbj^rAP$fB<c:WD@SUr@?#3)P>Z>c;An=\X;d=35DdZLc:1S$4
-F')Ua95S-9FAH@\9QO?>C2cj^@o7>E?u&DU>?>f<Bk1%^;I403Ea;[c9kS'6F&ZF^8oS-:F%p4Y
-:30H?DG+kU;fkcEBh`YN>&R&M@T%;D@;8GV>$,`;C1C(^;.+03?U!f<k3)+!mdKiBpA"O#kiV$k
-mI'E4rq6Ehi7Itj!:'RO!;$3`!U)k#~>
-%U&,Zk3;0umd]oAp\CXTrD3\l84Q?K>aGAN,ABkD7n?EK7n?BO91i#O9i">Q:.RlI:.J)Q8l//O
-9LqZOR/W0bE)02!:/FPU:eXDM9Me;S:.J,W9h7cI9M#.Z(K,pA:.S)R85MoO:eF;S8Ol?J852oQ
-9E%a):.RlH:J+,J:/FPU:Ie/U8kDTM:.RoN:]=%291Vl[9MU7r92S\i;-6ar=]&=(;d31&>>ea-
-<ErF,>#\j.=^4g5>#o*2?!UE><a0!1@p<#F;da!4B3AGM;eKH>C/n\P<,5]DBN&SR=Dh2MBN/kU
-?#3MUAQWqS@qnt^?sR\NBkUUi>@VPMEar?q<bcB!=*._WDcC^f>BEq[CKGXb@W>CfB3TO\BPgdm
-?t"(UE+iEu=_DVPG@Fs(<cDkYH!G!&<Hr(^G?8^"=a=:cFB*Qu?@#[jDch?nAT_!sBjH'fD/`R&
-@:XO^F_Y0/=_i"XH=LE.<c`%\HWt3*<I/1aGZSm%>'jLfFB!QuA7'U`E,Jg*?=n=[G\CE0=Di%Z
-HXLE.<H`(^HWY*(=*e=cG?/g$>^T[hE`RKr@X(ppCg26jBld9g8a56rk3;0un+$#Bp\2D`j6#Oi
-lgF64oChq6f&GcQkj%O&nFH8Gj["C~>
-%U&5^k3VO(n+?>Ip\qLIrJLl9JUrT5O1"tj,F+%:JV8r:JV&`:KnPA8Ll-h<M1^A4Lk1G;KStP8
-L4Xu6\,NQKRYZ`NM2R%@Mhlq8LPpb=Lk1GAM1U;5LP#M`(QGT$M1LG;JW#/7MhH\=KRnc5JVT/:
-L&R!2M1U;4MhZe8MMm.AMLgVBKn4i5L4Ou7MM?e>K7]&BKnlk5Jr>YMN099^P)YQcNg>]fQ&V)l
-O-YchPE(riOd1lkOcPffPEV#qOHZ&kR?N`$NL#l5Ngc&nR#RMtOID/rRZF,,Pb3u,R?=2)R%981
-QB\#&S=5P5OdDW!TU(e7O.Ml(V3@=?Nh`#,UlV(;OJJ,.ToPk8PGF;1Srfb5Q_KM6RZaM/S"Gb;
-QBlTdNhDl)V3.4=Nhi#,UQ;%;Oen5/TT5h8PbX;2S<Bk8S>2+CR['h4Tq@IHQ("M/VONgLOJ&8.
-WKrsKNhr81WK<^FO/\J5VN7ODPGs\8U5l4?Q`#n>Ss$(:S>2+CR?jb3U7[RIPaeJ/Vj`mLO.`.1
-OK"M6UlM=APc9b:Toc7>RAGq?S<Kq7StV4EQ^FY2Un*^KP+A>-STjD^k3)+!mdKiBpA"O#kiV$k
-mI'E4rq6Ehi7Itj!:'RO!;$3`!U)k#~>
-%U&5`m-a<2p%J.Trr8ZQp-\dFhF%6.j?iu;7mYWls$ZlV1.+Q"6q9X86qBO.77KX;84?6A8P2BE
-7n66@91_QK7S?EC:e+&P6r$<A<(9SW6rQWIIoSp7:./,R:/jV_9Lr8T;boea8PN2Q>"hIk7o`DS
->tRjo6s<DX@S'U%6t&eb?U\6t7Ueti=[ZXm9j^@o;FP(g;d)Rs:JG=h>uX4)9N5:d@Sf^-86f1`
-AkZ*07:B%bA4]s,6tK(i?q"I#87b@p=[Zpu;.N+*;FbLr=asgJBMqW>7q,RhCe[u>7;#OnBLlN6
-6u5Uu@mt!/95-t(>=<7&<+SL0<(^mt>[9d5:f:moA5u0993PXjBi.]>7UoIgCeRr=7;,RoBLcK5
-7;P\"@RXp.9kd1+>"!1%<FeO1<(gpt?!Kg6:K(gnAQ;<:93Y[jBi%Z>7V!uK53q@pm-a<2p%J.T
-rqsRqkNVF&n+$,Fp\OpJfB2;^mdBT9p@e:ZlU$+~>
-%U&2^l0Ia*nalJKqYR'XpJ:icrD)6H!)NPg!)M]Qs%rbjfhc9X:f1%c;G^4h:fL=i<)HRm<)6:g
-<DZ^o;-6[q<_upt<*E+$<Dcsu='/:(<)d(!>ZXd1;cm7#?rg97;-d:#@T6K;:gmI*@o?Z=:hEa2
-@8UQ<<+]'9?VtN=>%UWD>?#B;@:;i,CKObR;.j-4CK4eS;/BE=CJneP;K#WDAl3>J=DUoL?r:oG
-?YE;Q>ZYfBAn"VV=^Gi?CgC%Z<G#c=E`uad;/KW<EE-L\:iKTAIVr"u?W(rG@q\\Y>?PoCCLL%]
-=(,i?E*QLc;eol>G$&-g:iTcBF&Zja:j#oJDGY:Y<HM5RAl*SQ?#NPX?W2&IAS=n]>?c&DDI?=a
-=(>r@Ea2df;J]c<G$&3h:iTcCE`6^_:j,uLD,>1W<c_5RAPdMP?>`SX?;u#Hs(3u^FBVpg;/T]2
-l/h*mlgF64oChqTq7c"RkN_C$nFH5Gq"rjsjQGamm-jH8p%S:F6%A~>
-%U&5`m-a<2p%J.Trr9<RpP]*1rJKHjrJKZp!f`4te;XEes,LBDOH#6\NK9'[M2[IUN0'-\P)b]g
-NKoTeQ&V#jNL#TfPDtihO-P]hOc>ZfPE_&oOH>iiQBI5rO->igR$!GsNg>lgT95A.NLZ8qSrf>,
-NLl>tSW0,(O.MH%RTYWDPE_]"SsGG3OdV\uTp1b6Nh)MsUQLq6NM)N!TT>V1NMDZ'SW0;-OeIi*
-R>mr(QCa).Q&q]$R[T54PEqo%U6^n;OIVf"V3@1=NhMc"V3.7<NMMf'GG^FoRuOA1R\Ge;Q]n;.
-T:Cn>PaJ5*UmR=COIi#&Vj3UENMDo(VidOBNM_u,V2_4<O/J/2TT,h7Q)0M7RZ=>1R\>_;Q^"A.
-TUUq>PF8/)UmR=BOIr)'W0E[ENMDl'VidRBNMi&.UlD.;OJe52T8f_6Q7\qnU7$8lk321"mdToC
-p\=ac_!'tGmdBQ6p@e7Ws5;Mkkj%U(nFQAIq#'GEJ,~>
-!(-Umrji*Ark/>d,_7+i+b:fV+TaC+[/IK5\cBAA]`P7B[JmW8\Gj&D]Y2"dZ*^t=[fEu<])TGE
-[Q/j~>
-%RIM/['d<M\%&rZ]"<\JJL?!rfdD=tmNsACZa-pE[C*HP\@B,]];W$@Za@-K[^WcW]">8NZEpmF
-[C3NR\@K2W3.L~>
-!(-Umrji*Ark/>u:4Yfa7"IbG6ipc([/IK5\cBAA]`P7B[JmW8\Gj&D]Y2"dZ*^t=[fEu<])TGE
-[Q/j~>
-"'=dJ]_M@(qLS?kp4;qVp&OjCqZQ#pm+4OR~>
-"'=dJ](l.&qLS?kp4;qVp&OjCqZQ#nm++FP~>
-"'=dJ]_M@)qY,R7JbFZg`qBE-h>7?:^?jH;J,~>
-"^19U^&R>Jj+66Aj-ep2fTs);g-U;~>
-"^19U]Dq5KkCMfIkF(K:g6B)9fg1,~>
-"^19U^&R>Jj+66Aj-ep2fTs);g-U;~>
-"^19U^&Qr?eUc8%eX=qk_h5Mhg-U;~>
-"^19U]DplAg4@t/g6pXua+:_hfg1,~>
-"^19U^&Qr?eUc8%eX=qk_h5Mhg-U;~>
-"^19U^&Qr?eUc8%eX=qk_h5Mhg-U;~>
-"^19U]DplAg4@t/g6pXua+:_hfg1,~>
-"^19U^&Qr?eUc8%eX=qk_h5Mhg-U;~>
-"^19U^&Qr?eUc8%eX=qk_h5Mhg-U;~>
-"^19U]DplAg4@t/g6pXua+:_hfg1,~>
-"^19U^&Qr?eUc8%eX=qk_h5Mhg-U;~>
-"^19U^&QsgeH""p_#_iuo[O>p_U[,OcG@rZe]Gi&eH<\)_9_W$!R/ITeH!km_$.d#`RVlNJ^o>%
-J^sPG"iGu'nCg3Z~>
-"^19U]Dpmig&T\$`<"H-o\']%a4f1be&Bqmg<Rn5g&oC7`RF>1!R]!^g&TS"`<FB0b1anaJ_G\/
-J_KnQ"il2'nC^*X~>
-"^19U^&QsgeH""p_#_iuo[O>p_U[,OcG@rZe]Gi&eH<\)_9_W$!R/ITeH!km_$.d#`RVlNJ^o>%
-J^sPG"iGu'nCg3Z~>
-"^19U^&QsgeH_rO='f3?M$rt+$]#5A^As[._U[1>47q&+SK_B);t/<<H5cM-!J:[W?3PC^0%CVe
-J^o>%J^sPG"iGu'nCg3Z~>
-"^19U]Dpmig&e8S=oMh1N=5C4$]>JJ_uQ<9a4f6O4nRG2Td*u3<Ue]CI2_h5!JUmZ@0Ldf0A7(n
-J_G\/J_KnQ"il2'nC^*X~>
-"^19U^&QsgeH_rO='f3?M$rt+$]#5A^As[._U[1>47q&+SK_B);t/<<H5cM-!J:[W?3PC^0%CVe
-J^o>%J^sPG"iGu'nCg3Z~>
-"^19U^&QsgeI8;T`7:P6M$qF'8k-hreI[NFe\;*H/[]G'9fp3Q8mop>eJ`-[\!SA^<D#WtV`[@m
-W%EcVLI".hH5;0*a8+7%K+c_bKh>r0LB]?M>tR5s=D:BH8P2e"J^o>%L"-@EK=UL*6@]~>
-"^19U]Dpmig'jt]aP*FCN=4$29M!>%g(9/Og;EuV0"Gn1:-HWZ94H<Eg)=`c]UU4m=%l'*X$&q"
-X=fA_MF'[email protected](`4oLeDG8M?bcW?VEW(>&6lQ92&4-J_G\/L"Z^NJ[b.%6%A~>
-"^19U^&QsgeI8;T`7:P6M$qF'8k-hreI[NFe\;*H/[]G'9fp3Q8mop>eJ`-[\!SA^<D#WtV`[@m
-W%EcVLI".hH5;0*a8+7%K+c_bKh>r0LB]?M>tR5s=D:BH8P2e"J^o>%L"-@EK=UL*6@]~>
-"^19U^&QsgeI8;TA8RA.M$nhJeLYD0eI[[email protected]'!/giP.m$Nqd/]R/eJW9PCUAd+eM:W^T;hmL
-!$5eSP,iPJ%@\_^q:-:6$#P$.-"\d['7uGKeNd(m!)b]hUiiPceUc8)eHNjC\a\<>J,~>
-"^19U]Dpmig'jt]B5j"7N=1@Rg+@(8g(9/HE+As/!0.&W/3Qj"ec;68g)4lXDRbK5g,!;iUTOTW
-!$>qVQ*57W%A,%fq:ZX>$#k<5->>-e'8;bQg-Sh"!)kfjW-G=ng4@t3g',NJ\+&':J,~>
-"^19U^&QsgeI8;TA8RA.M$nhJeLYD0eI[[email protected]'!/giP.m$Nqd/]R/eJW9PCUAd+eM:W^T;hmL
-!$5eSP,iPJ%@\_^q:-:6$#P$.-"\d['7uGKeNd(m!)b]hUiiPceUc8)eHNjC\a\<>J,~>
-"^19U^&QsgeI8;TUU$$`M$nh=8hPMeeI[NDZCh2U!/gij=Z]Cr8LL>0eJc04^E";J"\LFmT/Sh3
-MZC'5!g;*aH5b<]D>D]uK+G8rE$]*KeJ!P!!(o"_2bqW9R3b2<J^o>%L"-@EK=UL*6@]~>
-"^19U]Dpmig'jt]Vm_ikN=1@D9J:nkg(9/L[\Nn`!0.&q><Ph$9.6_6g)@iA_]9bR"\^UrUGt@9
-NW?NA"-qToI2^ffE;A3(L(C`)E[GKRg(T1,!),1d3)J&FSL-bHJ_G\/L"Z^NJ[b.%6%A~>
-"^19U^&QsgeI8;TUU$$`M$nh=8hPMeeI[NDZCh2U!/gij=Z]Cr8LL>0eJc04^E";J"\LFmT/Sh3
-MZC'5!g;*aH5b<]D>D]uK+G8rE$]*KeJ!P!!(o"_2bqW9R3b2<J^o>%L"-@EK=UL*6@]~>
-"^19U^&QsgeI8;T`7:%PM$nhJeU*e]eI[NFe\;*B!/giO.Q^Epdq#l^eJ_LPeW0og&(Q,r-u>m`
-MZClL!g9R#H5b<]D>D]uK+c_bE$]*KeJ!O,!7cgc2dOt*Gb>OmJ^o>%L"-@EK=UL*6@]~>
-"^19U]Dpmig'jt]aP)p\N=1@Rg4#[ig(9/Og;EuO!0.&V.m6a!fOh\ig)=-Yg6)Yr&))T).;u?h
-NW@AY"-p$-I2^ffE;A3(L(`4oE[GKRg(T06!8<9o3+(C6H__.!J_G\/L"Z^NJ[b.%6%A~>
-"^19U^&QsgeI8;T`7:%PM$nhJeU*e]eI[NFe\;*B!/giO.Q^Epdq#l^eJ_LPeW0og&(Q,r-u>m`
-MZClL!g9R#H5b<]D>D]uK+c_bE$]*KeJ!O,!7cgc2dOt*Gb>OmJ^o>%L"-@EK=UL*6@]~>
-"^19U^&QsgeI8]:a46n>RlSYm8kI,"eI\01e\j/30Xbt1C0nkA8n?6CeJcFm8j\T^=\;0(W]ad/
-5qpO5NC#mtO$qMoL&'78Ps3aKLJ<7teX8\2@7ic'>C"c@9hJ@,J^o>%L"-@EK=UL*6@]~>
-"^19U]Dpmig'kAEbhApMSiY5#9M<Y+g(9f:g;u+B1:hO;D.1RN94lZKg)A.$9LG#j>>.T3Y!6E9
-6Sd'CO@2F)P"+/%M##a@R6]K[MGJh)g7:RB@n]/1?$k;M:/"[6J_G\/L"Z^NJ[b.%6%A~>
-"^19U^&QsgeI8]:a46n>RlSYm8kI,"eI\01e\j/30Xbt1C0nkA8n?6CeJcFm8j\T^=\;0(W]ad/
-5qpO5NC#mtO$qMoL&'78Ps3aKLJ<7teX8\2@7ic'>C"c@9hJ@,J^o>%L"-@EK=UL*6@]~>
-"^19U^&Qr?eUc8%eX=qk_h5Mhg-U;~>
-"^19U]DplAg4@t/g6pXua+:_hfg1,~>
-"^19U^&Qr?eUc8%eX=qk_h5Mhg-U;~>
-"^19U^&Qr?eUc8%eX=qk_h5Mhg-U;~>
-"^19U]DplAg4@t/g6pXua+:_hfg1,~>
-"^19U^&Qr?eUc8%eX=qk_h5Mhg-U;~>
-"^19U^&Qr?eUc8%eX=qk_h5Mhg-U;~>
-"^19U]DplAg4@t/g6pXua+:_hfg1,~>
-"^19U^&Qr?eUc8%eX=qk_h5Mhg-U;~>
-"^19U^&Qr?eUc8%eX=qk_h5Mhg-U;~>
-"^19U]DplAg4@t/g6pXua+:_hfg1,~>
-"^19U^&Qr?eUc8%eX=qk_h5Mhg-U;~>
-"^19U]AqOpeUc8%eYLahe-4..^@9iCJ,~>
-"^19U\`V_!g4@t/g8*Hrf`fg:]^XT?J,~>
-"^19U]AqOpeUc8%eYLahe-4..^@9iCJ,~>
-"^19U\^e0?Y(<a,Y,8?'dFF$HK*@7R_!p&EJ,~>
-"^19U\D"cM\q.GD\u*%?f@kuRJH^tP^@9fAJ,~>
-"^19U\^eKH\q.GD\u*%?daa-IK*@7R_!p&EJ,~>
-#$LBV\^c7IJSp$VJSqH)"`L*aeVBaqX9#AerN$1XkJ6T@6@]~>
-#$LBV\D!1"JVJ`1JVL+X"Ld%<L7eIK!Nq^dY6E_H^@9fAJ,~>
-#$LBV\^d1/JWPGEJWQgl"ME=9LS"LH!NVLaX9IDB_!p&EJ,~>
-#$LBV\^c7gJZOF(JZPiP"hO-ReVC+&]`R5W\Gj/Fp?06\g-U;~>
-#$LBV\D!1KJ_G\/J_I*W"lfR=g4l[-_?/e]]`,bOpZfK^fg1,~>
-#$LBV\^d1YJ`_OGJ``ro"mc3AeVC+&]`R5W\Gj/Fp?06\g-U;~>
-#$LBV\^c7gY,hr+S"$@XXJ;8SWe%7&XG3ea]'e2#LT%o"d.)pnrk/L/kJ6T@6@]~>
-#$LBV\D!1KY1a30`5L3[g<[^UfR_b-g4n;hir@lhL9&2.eFA9srk\j5lFuc@6%A~>
-#$LBV\^d1YY3$&Hcd1S4k1\/-jFQHEk(`"+li5YgLT%o"d.)pnrk/L/kJ6T@6@]~>
-#?gKW\^c7gD#RcCVQ?$\?NHOOrEff)XCYb=XK8B"?NcmR?XIgKX9NZO?\PS_RJgItO^DY#UL.ej
-rEfYh?XI75X9tq/9hf3#T2nZ\EIk3BXG3ea]'e2#LT%o#l0kp8rk/L/kJ6T@6@]~>
-#?gKW\D!1KM>h`$db;A4GQGXarHJRmg44G"g=k'UGQc$dG^,;Fg'3X`GcBEN_Yn]a\9NMWcZk8E
-rHJFSG^+T,g'ZDM@UalAa_bKrOFc,:g4n;hir@lhL9&2/lLD6<rk\j5lFuc@6%A~>
-#?gKW\^d1YOT'_2hWDiVIf[d'rI5(+k(eHHk2tV$Ig"0*It*g\jp%3&J$S5!c2E+s_LI=&g4,0h
-rI4pdIt*(AjpL*kB4m"^e8o88R"=CNk(`"+li5YgLT%o#l0kp8rk/L/kJ6T@6@]~>
--X#m"\^c7gG=[RI=e_TDM2>,\?u/;R5aSR+3gZqLWeiEdV42BqOnl'sO\9S]XK83WJVdWR<b8A2
-8p-RVM2=0YM(jhcX9"u\q5aq"6`d@OXH$GbX?;'8JZOU-'Y<_aeVC*:`r4f?PGPt+p?06\g-U;~>
--X#m"\D!1KQWpVqER)cjY-)H5H&>ae;8Cna9#007f<.6=dDV#N\G=hs\6b-4g=jkCUTS^&D1UEk
-?'N8iY-(71Xurodg&]C4q:Z2'<8-&"g9bkRg.[(OJ_Gk4']T/Lg4lZFb5L>JP,H16pZfK^fg1,~>
--X#m"\^d1YT4#.;GhL_7\$p7VJ<=0+<m'R1:<M_]j0q:_h9V<q_YN=4_dntWk2tDkXLEPGF,8u;
-@[t_/\$nuQ[m7M&joO&Uq;r%?=m"jCk.Z*&k"pWkJ`_^L'^PePeVC*:`r4f?PGPt+p?06\g-U;~>
-**M^l\^c7gN`rNcIVPrHXEBAcKpl,*I\NolCHVQs!'L7^!K17XX8uXbrN$W%TluHXMd3?X<h-6R
-XEAccX??E^!F$Q>X9tq-='&e2N`iHb4FsSbXG3ej]'e2#LT%oPn(#smOgr*ukJ6T@6@]~>
-**M^l\D!1KZZFjSTSD/og6AbSWP`\`T?Z)^LJ7[#!)3CG!O6eAg&ZE$rRqlfba,WEZ$"dGD8k4&
-g6@uSg._Fu!H]U_g'ZDJDJjdSZuOgR9S(oKg4n;qir@lhL9&2Xn_2^%OhAR*lFuc@6%A~>
-**M^l\^d1Y]m8c&WK$%:k+&p&ZHdX/W7^71O&5f;!)W[W!P3[QjoKn@rT4`!fUfdl\pWYnF3s&G
-k+&.&k"u!<!I?*gjpL'gF`i8t^3Jf&:k@b[k(`"4li5YgLT%oPn(#smOgr*ukJ6T@6@]~>
-&6\G`\^c7gN`rNcIVPrG4<+7#!EbH_X91V:<danJ!'L7^"H-QeXI&db'OHZuVOaeY3#8KpXA>7>
-@B?OV4>Hi:#<])hQ`R9\Q2.KgVFco48?@hSXK4O8XF[I-X;&86f@>YTd/)GGe]j#R^%UX)nCg3Z~>
-&6\G`\D!1KZZFjSTSD/n9HsGh!H>LHg&k*GD4U[[!)3CG"L3+'g;!L<'R-b7d`:'F7i^+6g18($
-HeR1,9KrI0#>Ek*^Y7Da^%p@hdp0Ak>M?H(g=f5Og4@t4g(`QHhV*^beGJ+Vg<ke\_Y<?0nC^*X~>
-&6\G`\^d1Y]m8c&WK$%9:a>r$!Hu9Xjo\M`F/Alu!)W[W"M0!Ck0!P_'RdOSh9tFl9-*$Sk%W)I
-K')2N:dP*C#>jRFb3%j:aSFs*hI4:<@-51Jk2oKkk(2ZLjqR.]g!tkVd/)GGe]j#R^%UX)nCg3Z~>
-*Ehgm\^c7gN`rNcIVPrHXE]McXK5NcXK6VM>[1;.X8kB^X9=GeXK4P\X:AQoXGU>c8"k6fNi\mE
-4T;Dg4KNdMVlW"^X??0W$Dg+kX?<SE=fe\eJZOF(L9(Wkmap!EW9`pNeHi=;^%UX)nCg3Z~>
-*Ehgm\D!1KZZFjSTSD/og6eqRg=gMSg=hj7F`hO"g&OhGg'"['g=f6sg(&>1g95_S>0NG@[+`]-
-9`E`P9\Pkue(RLLg._1n$IMi,g.^5-ESB,?J_G\/L=umls5)IaX6fBTg'FpA_Y<?0nC^*X~>
-*Ehgm\^d1Y]m8c&WK$%:k+T3'k2pj&k2r:^I!fu6joA6Wjoi8Ck2oM:jplgMk.,p&?J)$b^?4!S
-;#]S`;!+IAhr[btk"ta5$JekIk"t3SGin-bJ`_OGL?8a,s4PqXW9`pNeHi=;^%UX)nCg3Z~>
-.9Z*$\^c7gF%(b8>,7fDKS3-OXGfPbRA2`fSV8\ZWe<!XUmPpfKS2A_X<<KnC4p>.U,ICP=EU^G
-@=5/XQnF&F24&tKKS2(]XCX!ZX9tk!KS3($Pur]m;h;$$XG3e]]'e2#LU-TsrPAiRNhlC3_!p&E
-J,~>
-.9Z*$\D!1KP$"W[F3r&jVl+(#g9Ob<_TkZ?a/M,1f;C[-d(tK@Vl*)_g*!_+L8TcMc:+;%E0T)/
-H_&mE^cJBk7),W\Vl)`4g4)-Yg'Z;:Vl+"X]l0gHBn=uhg4n;dir@lhL:$X!rP]&XNMcI8^@9fA
-J,~>
-.9Z*$\^d1YRU*/%H/-q5YcqlDk.=f\c.Ygcd]u$Sj01\NgWPXbYcpgujrh?FNj+OlfgqsDG+@^U
-JYhMkb<<)68'.tuYcpFUk(Z"ojpL!WYcqd&aE=_kDLpr$k(`"'li5YgLU-TsrPAiRNhlC3_!p&E
-J,~>
-#?gKW\^c7gE;jALVQ?*^A.>!/F(Ag=S7H/mAn6@hraZ&#M#CiaGl+QBFo>hOMjsZU#F2BlNgm,O
-M#CiaPPo"pC94LoE;6L@OCVmlXK71fA>XpZJZOU-#.j6SeVDVNqL]!6o&mgXg-U;~>
-#?gKW\D!1KNrFM0e(VP7Igs<LP(.tb`IEBHJq'HDrdOsiXo3_LR/>S;Q2Q15Z,HTj#JJjF[)LbQ
-XSmVK])@*]L>(@bNqh<7[srnIg=iTWJ'ro%J_Gk4#3,[>g4n%OqLJj3o'3sYfg1,~>
-#?gKW\^d1YQMuU?hWDoXL(2GjRYHR-d"[:lM2&"fre:I&[f(p\U&3sPSc+9D]$L>0#KPuh^<l$)
-[Jbg[`VkMoNTTB6QMBSK_1m]lk2s%*L>ILDJ`_^L#4)<BeVDVNqL]!6o&mgXg-U;~>
-#$LBV\^c7gJZOF(JZPiP"hO-ReVCX/b6@\(_!p&EJ,~>
-#$LBV\D!1KJ_G\/J_I*W"lfR=g4m05c3=%/^@9fAJ,~>
-#$LBV\^d1YJ`_OGJ``ro"mc3AeVCX/b6@\(_!p&EJ,~>
-#$LBV\^c7gJZOF(JZPiP"hO-ReVDWLrs%*JkJ6T@6@]~>
-#$LBV\D!1KJ_G\/J_I*W"lfR=g4n&Ors%'IlFuc@6%A~>
-#$LBV\^d1YJ`_OGJ``ro"mc3AeVDWLrs%*JkJ6T@6@]~>
-#$LBV\^c7gJZOF(JZPiP#.j6SeVDWDqpl"nL%"3?nCg3Z~>
-#$LBV\D!1KJ_G\/J_I*W#3,[>g4n&IqqDA"KC8$=nC^*X~>
-#$LBV\^d1YJ`_OGJ``ro#4)<BeVDWDqpl"nL%"3?nCg3Z~>
-$<cfZ\^c7g:HCRbri?cB4,U,@H9+/NG-#I?4?P]Y4??!SX9!g1cE%(_4+VsaJZQ5[#.j6SeVDWD
-qpbqlKCA!=nCg3Z~>
-$<cfZ\D!1KA4fLcrn8$59!?t&Rn6:IQ.h$c9MA*W9M&F0g&[nRcIr>T9;I-mJ_IKb#3,[>g4n&H
-qq;:uJaVg;nC^*X~>
-$<cfZ\^d1YC/.U%roOlH:UoQLUeOZ^T&l&.:f'rl:ekB>joMKqcK51g:T]31J`a?%#4)<BeVDWD
-qpbqlKCA!=nCg3Z~>
-$!H]Y\^c7gXAYA^X8uU:ri?MjXK59cX?<Sc4KP8Hr2]pVI*er0W^BU"SueW&UkjH#XFkA/XJTj#
-D0Z&]"*/6qQhmcoGE8>4VlZtOD47PRM0a$5ri?ERCoj[SENFP)TRj1qXLtV=]'e2#LXYejeHa-I
-n)qLUg-U;~>
-$!H]Y\D!1Kg1S.ug&frMIK%q/9\S34^tMK9g.^5F=T$kRYFX%o("ZGtMTFMqMU/Dsg=iE]NnVs>
-^5A<Wg&mIpMSK#A&!s]FMU^A6V2E1ET!"N>c2QE'SVc(QMN?J^MTUM(J_Icj#3,[>g4n&Hqq;:u
-JaVg;nC^*X~>
-$!H]Y\^d1Yk&&6=joXXlK`:*B;!-nVb2uO_k"t3n?2Wgc\Y[[8(#rG4P1/RFP2!FDk2rk1QKI%e
-ac`@sjo_$7P0*R_&"gVcP2PKbY*.)mVRWCag&C+?VNL$%P*b=.P1G3HJ`aW-#4)<BeVDWDqpbql
-KCA!=nCg3Z~>
-$!H]Y\^c7gXAYA_X:h<s6Dgic3h`6ERB/EB>`>bY7f9=g<ADk%*3)Y8H_IO:4*FtGJ;RobG[[O>
-3.#O`XCcU%=EXJA*,JYVHXEk*Ap[LSH5gaK=f8@&Hu,mb:0XfF321u*JZQMc#.j6SeVDWDqpbql
-KCA!=nCg3Z~>
-$!H]Y\D!1Kg1S.ug(Mb5<79LS9$GLl_:hH(FKsQE=T$kRCd-5"*8"V>SBT^599sjYU9B*;R!dCc
-7\#Bug4>KYE0U4Q*/SNLS9`haJXgN(Rj*f]ER`^rSVc(R@W^=m8'Z\>J_Icj#3,[>g4n&Hqq;:u
-JaVg;nC^*X~>
-$!H]Y\^d1Yk&&6=jq?EQ=l&6&:>"39biVUOHFr=m?2WgcE^A(7*91UUUtFha:S*)sX13q\TRu*,
-8u.Z<k(oP'G+JKl*0G;`UjqO/Lno"GUa2/"GMhQFVNL$&BR8g89A+mYJ`aW-#4)<BeVDWDqpbql
-KCA!=nCg3Z~>
-,?aHs\^c7gXAY@cR?=R4ARIs.X=d"5=/;o?7ldZPU.25cI`nenBn$#^s&8lt%Xqtt7''gPXGpGc
-Ear[-q5aXV-D:@>'d[F&?UgJZXK7=cXK6ecXK71cXE/N8XF[IbX9Q9(f@>Z*nb^iAa+NjD_!p&E
-J,~>
-,?aHs\D!1Kg1S.R_RJ5lJ9k;Ng,`D@DU7#c>"IB$bui]RTZc$iL7nM!!GQ<Ig('d+HWJjIX4jn$
-g6$f6SGCk?Z7sK$g(c8kJ9b;9@bTP?G1tZ@M;$[aHeOXIJ_G\/]@mJKs5)Iaddm:h#Kq\dlFuc@
-6%A~>
-,?aHs\^d1Yk&&6&c,/U=Lk/gnjum$WFPGq.?;0MDfj3b&W6=<(NN)m=!H)iSjpn>GJQq8f[H>/J
-k*^mYV>96T]/%t:jqTY-Lk&gWB]eHgI-0RgOlkf5K'&MmJ`_OG]B0=`s4PqXe+*=c#KMJckJ6T@
-6@]~>
--X#m"\^c7gXAY@cIVOLGK7dNhX?<Sc;4"@HXH?ScU.25c4KPWYT$OJCBn!.VXK5?cri?ZaA:nki
-XC6mcNE`KXKS*ofqQ'^V>lC`6211%-Lmgc2XFk)cXF+j`X9(n\6\2=iXLbJ;]'e2#LXYejeHa-I
-n)qLUg-U;~>
--X#m"\D!1Kg1S.RTSB@oV58F@g.^5SB#*+og:2%Sbui]R9\S4FaNrQFL7m8Dg=g8Srn7p^I\i*+
-g3]mSZZFjFW25*?qUttUFT'o'6_:-MXi+>lg80>Rg7=*"g&bHq<e8tUg:GuBir@lhL=5Yig'>fP
-mcqOUfg1,~>
--X#m"\^d1Yk&&6&WK"-:YHNGek"t4&Cs(m:k/)6&fj3b&;!-one'I.]NN)'kk2pR&roOcsKs-hI
-k(0r&]m8bmZ*0"bqW7gjHi<(:8#EJl\'A:<k-'R&k,+:?joSo7>(Pgek.9[Zli5YgLXYejeHa-I
-n)qLUg-U;~>
--X#m"\^c7gCFi@i7;>4SH$))@M'623<hY!d?="h;==.?\/?GpK.*nt6Lg"+kXIh(AMQEn?=C+cL
-OYp+>=tuaD<aJpfqQ'a$13!5o'TQ=&?$)M[>@(g@XF<MuGH@mC/q\_VJZQGa#.j6SeVDWDqpbql
-KCA!=nCg3Z~>
--X#m"\D!1KLcB'l=,'aNRZp<OXsnR=Cs8S%GBYRGE%lK[383(t1XFboXE&N/g;u?fYM.^=E-GkH
-[mOrbE^.iUD0L!*qUu!j5E>`s'XVh'G*KosF*E&dg7VG=QeL0A3i7J^J_I]h#3,[>g4n&Hqq;:u
-JaVg;nC^*X~>
--X#m"\^d1YO#q3,>`DocU7=ki\1E&VEn@<BI=3]_Fu+Pp46G[?2UCM)[<R+Jk0uM1\E;qhG("*[
-_FAP-Gs^1oF+&8EqW7j'6^@Z5'Y\a=I%8J8H$tA.k,DN[TB>:m4g0G!J`aQ+#4)<BeVDWDqpbql
-KCA!=nCg3Z~>
-#?gKW\^c7gOSt%AT8SSmP_tHkre^cIXI0!E!K3WLM?K!AXI><tX9XrHV6$POMOjaJ%[N!FMP,if
-XH8=<R>Qleq5aXZMN[q>':"H6XI;nHMPmPWR#6cdXK80kUk,UuXLbJ;]'e2#LXYejeHa-In)qLU
-g-U;~>
-#?gKW\D!1K[f*B7ag&%`]W\Z^riZCCg;3cl!O0cGY6;8eg;CJHg'>3mdG!'QYK-Xr%_f-iYKO,W
-g:"38_QU/Uq:YnYYIXVc'>:TTg;II1YLD4Z_6:&Ug=jk^d"0o%g:GuBir@lhL=5Yig'>fPmcqOU
-fg1,~>
-#?gKW\^d1Y_#:eKe[i<5`jre2rj`*Xk03e7!7q+Z"Ma*]cGRri#K=7/k2*YZdf/A=aLTm4f"&QX
-^q&CI\[fcVjoW?/_u8^2aLSqFc=k)*hra(F\[fcCk1XJ&J`_OG]&j4_s4PqXe+*=c#KMJckJ6T@
-6@]~>
-#$LBV\^c7gJZJsT@OG[\X94DX,aa.aJZQGa#.j6SeVDWDqpbqlKCA!=nCg3Z~>
-#$LBV\D!1KJ_C4[I5-0Fg&nWm/\lqkJ_I]h#3,[>g4n&Hqq;:uJaVg;nC^*X~>
-#$LBV\^d1YJ`['sK/A8Vjo`840[#%0J`aQ+#4)<BeVDWDqpbqlKCA!=nCg3Z~>
-#$LBV\^c7gJZJsTR$*d1X952[P,<f3JZQGa#.j6SeVDWDqpbqlKCA!=nCg3Z~>
-#$LBV\D!1KJ_C4[_7@;Tg&oX2\^H&_J_I]h#3,[>g4n&Hqq;:uJaVg;nC^*X~>
-#$LBV\^d1YJ`['sbeqNsjoa;S_qot,J`aQ+#4)<BeVDWDqpbqlKCA!=nCg3Z~>
-#$LBV\^c7gJZOF(JZPiP#.j6SeVDWDqpbqlKCA!=nCg3Z~>
-#$LBV\D!1KJ_G\/J_I*W#3,[>g4n&Hqq;:uJaVg;nC^*X~>
-#$LBV\^d1YJ`_OGJ``ro#4)<BeVDWDqpbqlKCA!=nCg3Z~>
-$<cfZ\^c7gXDp%2ri?ir4?ll#BJV%o-CU/b4Aqc(+ZqklUk,UuXF[ImX9Q9(f@>Z*nb^iAa+NjD
-_!p&EJ,~>
-$<cfZ\D!1Kg5eLRrn8*r9MfT*KL%@\0Z1P%9PDMF.SNNXc[jf$g4@ttg'6R:hV*_4o)%,GbCT*H
-^@9fAJ,~>
-$<cfZ\^d1Yk*JJrroOs3:fVSBMa]Kn1X3p@:i=de/5T/igO\L<k(2[7jp(/Og!tl,nb^iAa+NjD
-_!p&EJ,~>
--X#m"\^c7gXK5T)Uo]P[XJe:4@#.pH;1McHXHlbc4KPVkM6*e%?dPkhAo;(!?$EBO<(E^bXD17^
-8!9rY7p5hm#a%VhC94='7s'<`JZPED#.j6SeVDWDqpbqlKCA!=nCg3Z~>
--X#m"\D!1Kg=gU_ce>[Hg=8omH*)%oAts=og:h7S9\S3FY1hTpGgP.ZJW"o<G*gq:CKf'<g4ie5
->.N@0>&jPq#e4&iL>(*[>*FNkJ_H[K#3,[>g4n&Hqq;:uJaVg;nC^*X~>
--X#m"\^d1Yk2pr.gZH.pk2B1=J@9X:Cohg;k/_H&;!-ni\E;qEJ'd<mM3ER[I@oZaEF7G^k)NfX
-?c2#R?[)M3#f9r*Noo5+?^lW/J``Nc#4)<BeVDWDqpbqlKCA!=nCg3Z~>
-)-QCi\^c7gXHHUrJuj09XK8A"VlEj\VLrCXX9q(k4KPGaPH:j#:=-'dSelYjG#G,>PbD*FC4;jY
-5H0!fTnZsVOBeK1(7S9sTlbF.XF[IEX9Q9(f@>Z*nb^iAa+NjD_!p&EJ,~>
-)-QCi\D!1Kg:;$NV:q5sg=k'-eCSZJe#.Zog'UO-9\S!:]%YkmA'ipRa;pZlQ>"Tb]?G*.L7lb/
-:tD/Abc5sB[rooj*5lU9b`e9Bg4@tLg'6R:hV*_4o)%,GbCT*H^@9fAJ,~>
-)-QCi\^d1Yk/;:rY3)@Ck2tU]hrAmqhQV_5jpFrI;!-Y[`TH<BB[GlcdiY;/So*5-`Rf.SNi:QP
-<T9gcf<^"i_0ae9*RA]Vf:/:]k(2Zdjp(/Og!tl,nb^iAa+NjD_!p&EJ,~>
-%U&5^\^c7gXAUuA1TYe?qlBp&OK=.Gri?8cX>W:2M9DtAV*ghHQ;W_d5<gf84KPW[7'*Ik5;ZTG
-8tN,cK5Z&7X8kA6XF[IEX9Q9(f@>Z*nb^iAa+NjD_!p&EJ,~>
-%U&5^\D!1Kg1NlO6/%Wdqq;0l[b@[/rn7NLg-eb<Y05N?d8\1n^1al':f'6-9\S4I<nc8F:dT6W
-?HCjSVMprBg&Oftg4@tLg'6R:hV*_4o)%,GbCT*H^@9fAJ,~>
-%U&5^\^d1Yk&!^j7-:,.qrS$)^uhqVroOA\k"&KV\'*nTh-&3:a_eaC<E28B;!-oq>NY'i<CM2q
-A(0T&YEYd\joA5/k(2Zdjp(/Og!tl,nb^iAa+NjD_!p&EJ,~>
--X#m"\^c7gN`rE]I;=XHXK7\YXK5NcXHHedXI;nc4K4oPTrb>UJ^CJBV*ghHQ;X)MTrFKG:RJ55
-7''jOWFfA9C4<7cLP'0>XHQY8XF[IEX9Q9(f@>Z*nb^iAa+NjD_!p&EJ,~>
--X#m"\D!1KZuXaKSqsLog=j6]g=gMSg:;:Tg;@FS9\.:$bhCdWUX7^=d8\1n^1b?!bgs\EA\m)o
-<n_r#eq%nrL7d2RX/:F$g:D*Og4@tLg'6R:hV*_4o)%,GbCT*H^@9fAJ,~>
--X#m"\^d1Y^3S\rViS9:k2sb6k2pj&k/2K&k0@Z&:uTlDfB25/XO-)Rh-&3:a_f4Af\t,rC<Yh?
->NURDiJ;dANi;+&[BGAJk/;:kk(2Zdjp(/Og!tl,nb^iAa+NjD_!p&EJ,~>
--X#m"\^c7g73PZI/LIEO4?QN5XA^8uGcZih4AM;t(hp(8=KJT%/C:IB>T/,4INOr<6Te#-Rnl.Q
-7')VD4BE_uXD0j[@]Y/D4B8&*XF[IEX9Q9(f@>Z*nb^iAa+NjD_!p&EJ,~>
--X#m"\D!1K==S*C3AK'b9MB-@g1i'%QeJ]A9Okr;*erC[Dq`oY2pg8&FWmM*TI7R`<D6c6`+;Vd
-<nb/i9PuB%g4i9pI+kDj9Phn'g4@tLg'6R:hV*_4o)%,GbCT*H^@9fAJ,~>
--X#m"\^d1Y>V0rX4>Yp':f)&Yk&2e=T]Wje:h\+X+H>O&Flqh'3md"5HQoO<W%#s*>#8bOcY?:*
->NWn4:in;<k)E26K''44:ib0=k(2Zdjp(/Og!tl,nb^iAa+NjD_!p&EJ,~>
-#$LBV\^c7gTWA0BCOrR<XGj4b]'e2#LXYejeHa-In)qLUg-U;~>
-#$LBV\D!1KT\9F=LOn01g5O_iir@lhL=5Yig'>fPmcqOUfg1,~>
-#$LBV\^d1YT]Q9RO+HGEk)AF,li5YgLXYejeHa-In)qLUg-U;~>
-#$LBV\^c7gUT=QT4?RD1XF[I2X9Q9(f@>Z*nb^iAa+NjD_!p&EJ,~>
-#$LBV\D!1KUY5gR9MC4mg4@t9g'6R:hV*_4o)%,GbCT*H^@9fAJ,~>
-#$LBV\^d1YUZMZg:f*4(k(2ZQjp(/Og!tl,nb^iAa+NjD_!p&EJ,~>
-#$LBV\^c7gJZOF(JZPiP#.j6SeVDWDqpbqlKCA!=nCg3Z~>
-#$LBV\D!1KJ_G\/J_I*W#3,[>g4n&Hqq;:uJaVg;nC^*X~>
-#$LBV\^d1YJ`_OGJ``ro#4)<BeVDWDqpbqlKCA!=nCg3Z~>
-#?gKW\^c7gWVr4iUm[XPX-oEOrL!neR@^LJRB3"ZR/i`QXSnOjTrb#WU7^8C(9;R?4GU#;BKSDC
-XJT5b5bP3R:cqFHqQ'b!ClA:o"H,B)ENAr;!M`QjX9*o+WVNUrKlI!l"#2o#NV]^_K028?XK-J+
-4GN^6"K#Ed5bRqS!I]7mX:La^4CtIm69I@bU9(4r4H'3?#`ga-XJfVk4Igu(NN<>qmap!Ee+*=c
-#KMJckJ6T@6@]~>
-#?gKW\D!1Kf)<Did)*WQftkVQrP8`d_8t?I_V3-2_#VINg&T"h_$/$9cb[oLh:`XtPY=cOg=CpN
-9YT6/F\GZUg<X>(@F"`'!niC6rn7LZ9MCQ#qUttrB`-QcU-.$&g&\15rRq?;9MDehg'OZN9UFJd
-PY=cNqUu)$F\GZUq:Yk@RJtnN_b<aRe_3tr9Kp_TdWA0ern7Xd5el%&I8!>SJ_H+;#3,[>g4n&H
-qq;:uJaVg;nC^*X~>
-#?gKW\^d1YiVgt*gs+(*jil$(rQGN&bgY_!bi[FSbQ-#djoE[*bQZV\g<A7#h<#L7S5<%hk2M=r
-:rqeUHVdbok1aZJB%m+D!p,NTroO?o:f*P?qW7h4DZ&VuX$G\?joMcRrT42K:f+k%jpA7g:nZt4
-SPW.hqW7q;Hr*hoq;q^UU&O0bc;7>mi9"-<:dNarhKi#0roOL%6d"QLKMYLmJ`_sS#4)<BeVDWD
-qpbqlKCA!=nCg3Z~>
-,?aHs\^c7gS0g[#3bg]5XJ[a?K,dZ_-%[<oX>r2?2btDh.Jg+P*_m_J8#'-]<\W@2(8XC"X?<SE
-=fe\eXE\]cUdV:mLTHJ>qQ'a>0S05)"?`ce8Y>m]!i/mHr2]r^5cFO\!e`mHrN#u]pT+[?XK4Uc
-WH5/B4Sl,^G]0[[6i*kcIlqHEX:7:nXC-gbE3--5Suc.Ur2^/d=HKV;A?;jpJZOj4#.j6SeVDWD
-qpbqlKCA!=nCg3Z~>
-,?aHs\D!1K`@tD*8qor*g=/5cVB]Y`0;U0\g.4Wc7:d]T2#>o4-=\?.>0h(tD*?_/(=?+8g.^5-
-ESB,?g6[iRcrSkIX4jn$qUu"64JVo0"AIP'>furt!mkgAr7V3G;:YNs!iT%ArRq6FpY#q5g=f<S
-ere\?9`!HGR>oqJ<VkDNThL1>g'pa0g3TjSNS<)lakCjBr7VEMDn"H!IbNLLJ_H+;#3,[>g4n&H
-qq;:uJaVg;nC^*X~>
-,?aHs\^d1Ycn\mA:5r"=k28L/Y9dpu19N2nk"J>.8STPd2u;YC-tju<?e][;F$SRD(>W-Uk"t3S
-Gin-bk+J%&gfrol[H>/JqW7jJ5cjtI"An7C@Fb8;!o%fUr8n&W<T3f:!jPjVrT4)VpZ;dIk2oS&
-igJrk;#9;WTp=cr=o.7^W_eZRjpb/Lk(0r&Q0.4<eE2(ir8n8]Fi!4FL$%MoJ`_sS#4)<BeVDWD
-qpbqlKCA!=nCg3Z~>
-,?aHs\^c7gXAY@TK62TWXK,fcX?<SQ?^jVtGBS#.:96RZ:AV$u:8pIQ=.)gbS4W^]!@iBSX;7k(
-XIr+cN`iHb4KNdHXJA7cSu&N=BDS\2QY1mKX9:YeX@]&]X9,Ai4T2>`>E(nHqQ'agKjO_Z!],t.
-poFakO[Z:OXI,,?qQ'gEDlfd&qQ'adHtiS]"?`ce@#+`_'9-=tX?;r6Uo^Y8H<?91Un4ZW9nBC*
-X9Q9(f@>Z*nb^iAa+NjD_!p&EJ,~>
-,?aHs\D!1Kg1S.>VN[^-g=UeSg.^5=Gf3j9Q^*]e@bON0@f"db@b+B$DSfo;`E`Dr!B$;)g(r>W
-g<3^SZuOgR9\Phng<`mSaO/_:KDO:'^Or<\g&t+'g0Detg&fjC9`<ZIF0e`oqUu"iWH\<p!^X?8
-pt?"n\6.D;g;1:'qUu(?NS;c[qUu"fSV@'s"AIP'HE@,"'=)i6g.]Dod+[33Rr>did)aq[@=d-l
-g'6R:hV*_4o)%,GbCT*H^@9fAJ,~>
-,?aHs\^d1Yk&&5fYFDPNk2_0&k"t3cJ'VPWT:MD4B]`.RB_pitB]<%GFNnO^cscq9!B6b4jqd%$
-k13r&^3Jf&;!+F:k1j2'e(s/fMYcH:abm2!joeNCk$cg;joXMe;#TMYH+d5:qW7k+Z@;c7!^soO
-puVk/_Hl6bk01\MqW7pSQ0-n*qW7k(VMtN:"An7CJ[PL>'>/bRk"s@?gZIX^UNOE8gskK4B7]3)
-jp(/Og!tl,nb^iAa+NjD_!p&EJ,~>
-*Ehgm\^c7gXAVY:Suf"UXJ84cX>!X,XK5!L<c`<\X8kBWX9bdiXK80t<E5[jX8uRci2dEb<gg%L
-=fe\eXE\]cUdY3`"G16eXEskG"HKRbB7^&`#s>;j8Y<(d<E36%X8kB^X9=kjVEh*UX9"2brN$*'
-=&tR]X9a)Q<i`='DHC6BX9<cdXJJ;[X9!fbri?5bXK5fbri?Q_@]ZXS<``J+UK3gcOT)<_PZFf8
-XGs:c]'e2#LXYejeHa-In)qLUg-U;~>
-*Ehgm\D!1Kg1O_EaP,?Ag<WjSg-'75g=ff5D39t[g&Oh@g'H8+g=jhhCi%5mg&Z?&i7\[gD8P#6
-ESB,?g6[iRcrU/""Jp\'g7/(X"LQn:K;8G"#u'(,>ftc=Ci".kg&OhGg'#3.do"Zkg&\C$rRq?m
-DJd&^g'F-bD;!XsMf*k;g'!h'g<iprg&[n$rn7KKg=gkSrn7g\IG3C(D/OCJcY^U=\,P(_]PZ8O
-g5Xejir@lhL=5Yig'>fPmcqOUfg1,~>
-*Ehgm\^d1Yk&"T_e)odhk1X)&k!3rMk2p*\F.&HqjoA6Pjp9sHk2tB=EcT\/joKhAi8tO)F3Wj]
-Gin-bk+J%&gfsd?"KmRCk+qus"MX$\MQHg>#uKdH@FaL_EcQI)joA6WjoikKhGrP1joMu@rT43*
-FE>Itjp7]'F62QHPB;BPjohBCk1s29joMK@roO>[k2q6&roOZqK]_DJF*)]igN1\`_>`Qu`cL0k
-k)JL-li5YgLXYejeHa-In)qLUg-U;~>
-*Ehgm\^c7gXAXRIQ_1@K9hV%YX>lD=R]&fM='K_EX8kBWX9bdiXK8@\PESPmX;@L2Suf#R=fe\e
-XE\]cUdV;cL1[BcXIfET"J`'"B7^&`#s>;j8Y<)KPEV71X8kB^X9=/PM)1:iX9"2bqlBg6I.s]C
-5-"R_!'L+Z"F+jdV*k'[!Inh_X9:YeXC-h_X:e$sXK47RX?<SR4c)XSXK7dlUOfM*X9Q9(f@>Z*
-nb^iAa+NjD_!p&EJ,~>
-*Ehgm\D!1Kg1R0p^rb<K@UI10g./_a_pr#7DKCs>g&Oh@g'H8+g=k)a]"2/%g)%kLaP,@TESB,?
-g6[iRcrSlSWe&^Sg;s9)"OGfUK;8G"#u'(,>ftd4]"5QRg&OhGg'"<cY!KSng&\C$qq;(,T(gq>
-:>#O!!)37C"IY8'd8g"r!MP5Hg&t+'g3Tk"g(IT5g=em>g.^5>:9I`gg=jA_c@O].g'6R:hV*_4
-o)%,GbCT*H^@9fAJ,~>
-*Ehgm\^d1Yk&%2<bLG\#B4THQk"EX,c/<$\FEs;RjoA6Pjp9sHk2tX9`5H*>jqlNie)of,Gin-b
-k+J%&gfrq'[#!Z&k0s=J"P`)$MQHg>#uKdH@FaMZ`5K[pjoA6Wjoho(\4"40joMu@qrRp@VYB3R
-;WRf=!)WOS"JM+Ch-'R9!NM+XjoeNCk(0r>jq;"Qk2o.fk"t3e;Rg&.k2sj3fn&:Ejp(/Og!tl,
-nb^iAa+NjD_!p&EJ,~>
-&6\G`\^c7gXAY@cIVPsb=C(p-#s>;j;3skHX9EYDX8kBWX9bdiXK7g7R]JXNX8u7ViiEoo<1'b)
-XH$GbX?<S/E3,j'XFk)cRt(78!G?u_X9:YeX@]&[X8kB^X9=u!?R'^hX9"2bri?BEWiTu`XK6qX
-ri?EDXK4UcWH,)A4T;Dk>(WiWG]0[[6`dA^9q2-`!Inh_X9:YeXC-h_X8kB^X:JQpX?<S[?XGKn
-XHlqbXDWTjNN<>qmap!Ee+*=c#KMJckJ6T@6@]~>
-&6\G`\D!1Kg1S.RTSD1RE-D67#u'(,B#%Zog'<c>g&Oh@g'H8+g=jCq_qIf`g&Yrkin>0uCV\Y_
-g9bkRg.^4eNnVi\g80>R`M*+]!J@0Hg&t+'g0Derg&OhGg'#<<GV,3Vg&\C$rn7X<f\2.Qg=i9D
-rn7[;g=f<Ser\V>9`E`TF/@UER>oqJ<SH0M@`A?#!MP5Hg&t+'g3Tk"g&OhGg(/>2g.^5IG^)Aq
-g:hLSg5LU:NS4Trs5)Iaddm:h#Kq\dlFuc@6%A~>
-&6\G`\^d1Yk&&6&WK$'%G('AP#uKdHCs$2:jp.=RjoA6Pjp9sHk2soAc/qk%joKD1ioV$8E6IC.
-k.Z*&k"t35QKHt,k-'R&c`6g'!K*uXjoeNCk$cg9joA6WjoitYIP78fjoMu@roOKPjQ;Q$k2r^l
-roONOk2oS&igAlj;#]SdH*6;lTp=cr=m"ktB[Hb@!NM+XjoeNCk(0r>joA6WjpugNk"t3qIXXP1
-k/hc&k*1GZNTLH2s4PqXe+*=c#KMJckJ6T@6@]~>
-,?aHs\^c7gQnpcc2gVR,IYFl)H8%HD1P7GcXET5sVE?OpQ27QgLcdCZXI`]m4HTQD!A]&^X;7]g
-4?Pj0WG+IWQ`R)j4@#UAF#Z9BDu-OB>r=QYXK7@C4E@M"X9>1Y0Kbg'X9+A9@/?r7F>u*YXK8*Y
-4C>"fXDgE'X9jSC4F+$/G!%mBri@##F0)I@>s(BGXK7m@Q)q'(2`4pCXID=7AZ5U0!*B0$"/fBd
-JGuVUS23pAN\ij\<.V-1X9Q9(f@>Z*nb^iAa+NjD_!p&EJ,~>
-,?aHs\D!1K_*CRc7[r,cTW-Z!RlsG=5c-bcg6\SgdS)et^&$FhX@k`Wg;nGI9XarS!C379g(r1%
-9MA::eqHdk^Y7.Z9Ms'gP"/2:N;D68G!e`Wg=if*9Te!)g'#Sm4\Wfng&eQDH2?5)P=IrWg=jbG
-9R5.Ag5]#/g'O]O9UXVfQ:suQrn88aP1nX=G"bcWg=jM(^"V1t7RMCRg;Q`ZJ^sbR!,qkj"4MBd
-UAijP`^++gZpRM\COt3!g'6R:hV*_4o)%,GbCT*H^@9fAJ,~>
-,?aHs\^d1Yb=#'$8u(P2WNt[KUd7gR7'At%k+Jg<h,$C6aSP$*[ST7nk0n`m:r*(m!CNaDjqci@
-:f(-Rif-c2b3%T/:fc62RS-INPksMLHq-emk2s9P:mpDAjoj:45u>o,joW1]JGSC<RnH1lk2t8n
-:k7Kdk*B!GjpA:h:nd%5Skr7kroP+qRc`biI8Eqrk2t#NaQDWI8k4?mk0Qq$LuJ?q!-S;'"5eH%
-X8_5ed7%a2^.(pqEIm83jp(/Og!tl,nb^iAa+NjD_!p&EJ,~>
-#$LBV\^c7gJZOF(JZPiP#.j6SeVDWDqpbqlKCA!=nCg3Z~>
-#$LBV\D!1KJ_G\/J_I*W#3,[>g4n&Hqq;:uJaVg;nC^*X~>
-#$LBV\^d1YJ`_OGJ``ro#4)<BeVDWDqpbqlKCA!=nCg3Z~>
-#$LBV\^c7gjK&?(r&at2JZOF(JZR+t#.j6SeVDWDqpbqlKCA!=nCg3Z~>
-#$LBV\D!1KjOsTur(I*eJ_G\/J_JB&#3,[>g4n&Hqq;:uJaVg;nC^*X~>
-#$LBV\^d1YjQ6H4r(mBrJ`_OGJ`b5>#4)<BeVDWDqpbqlKCA!=nCg3Z~>
-#$LBV\^c7gJZOF(JZPiP#.j6SeVDWDqpbqlKCA!=nCg3Z~>
-#$LBV\D!1KJ_G\/J_I*W#3,[>g4n&Hqq;:uJaVg;nC^*X~>
-#$LBV\^d1YJ`_OGJ``ro#4)<BeVDWDqpbqlKCA!=nCg3Z~>
-#?gKW\^c7gUA]*8Q?@4gFoJHDIWD4_X9G,7Knc[]rc/!cqQ'[=rc/1"XHIUbL>ApHWa._LDQKR5
-4?S%nRSQ%0M6)n34@YJ0X9,@jJc;_RE]cHgW;<RrOtus:!bW@Kq5aU.?i@&.(d'p?qQ(!=4?QuO
-Wa7eMD>L=:Rnl.1M>=4R>&+&<)1an4<1p=oN](CKXCF@TAZVt@0K`46XG])iXGa.a]'e2#LXYej
-eHa-In)qLUg-U;~>
-#?gKW\D!1Kc2Eb-^6FbBQ2]J=TTRP!g',KYW2eRKrfI2NqUtq5rfIAfg:<?SWnlAEf60h]MqZEm
-9MD&3`+2P;Y1gHk9N\e#g&fi-V#K'NOA&>ieb[u#\Ng#G!eVQEq:Yk"Gl?=u+&#A7qUu729MB]a
-fQU"_MYc$0`+2P;XngZOEeaSI)5Kr"C<P>bZUB8rg3u^hJ_Jh(4\TJAg9=,!g5FYhir@lhL=5Yi
-g'>fPmcqOUfg1,~>
-#?gKW\^d1Yf_q3@aIJZdSc7aQWL;H=jos/#Z*`Ysrg<b^qW7dIrg<r#k/3V&[,'j[j*aa#PNLP>
-:f+(PcY63S\)tV::gLs7joXOJXo@GcQr$V*i;2R:_aF@a!fA,Zq;q^5J,SL3+AbnJqW8*E:f)Z'
-j*aa#P5=;DcY?9T\,#.eG`Mdc)6H_3E7X16]h!k>k(QW.M!!iN5Yu:Zk.+0:k)8@+li5YgLXYej
-eHa-In)qLUg-U;~>
-,?aHs\^c7gN]pZ7<bbQ-F`M&pXFNEmXK8C#F^l2gIkZ"f1&@sX.W[+X8"W_&=Y'KQ!N2sWX;7X%
-XK4OcN`[email protected]>PbE&?q,_HX9:YeX@]&]X9,%q1&\0UWBWYHqQ'a?<aPa+!'L"W
-$&G[a5,tW?XK4P\X9<cdXJJ;\X9*6:C&Y1I4KPVlLTIOREFQ#N4KPVHXK5ccri?0a>r[D:Ml[,o
-map!Ee+*=c#KMJckJ6T@6@]~>
-,?aHs\D!1KZVGUBD2)b6Q'$XOg7h9Ig=k+mQ$s_,TKJL)55Nt>2Ng"W>0:TFE&R^L!S#c]g(r+>
-g=f6SZuOgR9\Phng<`mSIBD50F8FSlH<I$Bg&t+'g0Detg&fH755j1;ekf5oqUu"7Cj5j3!)3.@
-$*Dq8:>"4&g=f6sg'!h'g<ipsg&d.FL&Td>9\S3HXP2??O+#a99\S2og=ghSrn7FaG"7,;MqSBp
-s5)Iaddm:h#Kq\dlFuc@6%A~>
-,?aHs\^d1Y]i'/ZF,b*NSXG;rk,V=lk2tZBSV8-IWBd#F62K^M31;ml?e'(cFufQa!T2qsjqccY
-k2oM&^3Jf&;!+F:k1j2'KXU$VH2?Y)J6o>VjoeNCk$cg;joX.U62fpJi`&q:qW7jKEdmuL!)WFP
-$+B!Y;WQoLk2oM:johBCk1s2:joUZ^N;hrQ;!-nk[H?RfQ\=M`;!-n:k2q0&roO:"I7o.RMrk60
-s4PqXe+*=c#KMJckJ6T@6@]~>
-,?aHs\^c7gR<aNrOFqasXJ84cXHZ[HXK5!cXK6$8U.1u8B)8S8AuS"kD4+/#XChI5!=Nc%X::7n
-XH$GbX?<S/E3,j'rN$$;H24NBB7^&`"?`ce8Y>g[!'L4]"%](MW;3LqMI-7_![_]8poFaTCJ_(5
-XF+ecqQ'gEDlfd&q5aUHC&Y1K4KPVlLTHJ>Kjq-b;JU&HXK5c/CSCa/!'Gh6Ml[,omap!Ee+*=c
-#KMJckJ6T@6@]~>
-,?aHs\D!1K_O@KP[\f@Pg<WjSg:V/og=ffSg=h/4buiDrK)41-K%<cGMS`lWg4K=X!=k"Eg'tK0
-g9bkRg.^4eNnVi\rRq:2RebY<K;8G""AIP'>fulr!)3@F"'`rGebRo"YBTs!!\oJ-pt?"QLM#5n
-g7F(<qUu(?NS;c[q:YkCL&Td@9\S3HXP1"%WI<LSBSV@Wg=gggLX#hP!).stMqSBps5)Iaddm:h
-#Kq\dlFuc@6%A~>
-,?aHs\^d1Yc(_Os^osAsk1X)&k/M@:k2p+&k2qN_fj3FBM>H?@M;hOkP0I_'k)'*"!=k:Mjpf+L
-k.Z*&k"t35QKHt,rT4-FUA<pPMQHg>"An7C@Fb29!)WXV"(9\[iVDU:\:4D=!],nApuVjfO)*k>
-k,+2^qW7pSQ0-n*q;q^XN;hrS;!-nk[H>/JZ@qB&DNBisk2q/5O4aHo!)S7/Mrk60s4PqXe+*=c
-#KMJckJ6T@6@]~>
-)HlLj\^c7gXK7.cXK6V[T3[P[XAXgiENDa(rN$*q(cG+`X9bdiXK8=,4?Si,X9!j@i2d]_=JDmW
-=fe\eXE\]cUdV;cWc*3bXDIku"GX"ZB7^&`#s>;j8Y<(K4?Pt0X8kB^X9=PhWBdEXX9"2brN$*M
-I:.p-X9ao99<5.qMLA=tX9<cdXJJ;[X9!fbri?hsXK5fbXAY@<@]ZY)I=4hkXI"?`;uWiu4FsSl
-X9Q9(f@>Z*nb^iAa+NjD_!p&EJ,~>
-)HlLj\D!1Kg=iQSg=hjHb&t/Hg1[ODOP3s^rRq@u+%0T5g'H8+g=k&%9ME%sg&[qdi7\saE6[+D
-ESB,?g6[iRcrSlSfSuBSg55f&"KL20K;8G"#u'(,>ftbs9MAFbg&OhGg'"g+eksung&\C$rRq@G
-Sp@L7g'G-Y?eF)dYF]>%g'!h'g<iprg&[n$rn8)\g=gkSg1\4"IG3C_St9BEg:s5NC&Zfd9S(oU
-g'6R:hV*_4o)%,GbCT*H^@9fAJ,~>
-)HlLj\^d1Yk2s"&k2r:peU50pk&.SgR-%i-rT448+@p/?jp9sHk2tQN:f,+0joMO/i8tg#G1brk
-Gin-bk+J%&gfrq'jHZP'k)fR="LI7QMQHg>#uKdH@FaL?:f(<ojoA6WjoiGHi`4t5joMu@rT43\
-Vgu;Qjp8c#AE;n8\>O-=johBCk1s29joMK@roOqlk2q6&k&/8GK]_E.Vl+1ik/sU"DuSl!:k@be
-jp(/Og!tl,nb^iAa+NjD_!p&EJ,~>
-)HlLj\^c7gXK7.cXK6V"8RJR#N(ur9=//?ZrN$-r7\Y$Rq5ak$5HLr^KWM7;goLO<=T5B3N`iHb
-4KNdHXJA7cXD`CYX8usbri?5bXK5!cq5aQYri?6T3b'I]q5aUS?Mgf)COGlX!C!O^X8kBZX9<cd
-XJJ;[X9!fbri?VmXK5fbX=n'X3Mrl?XK4P^X8kB^X8kA6XGa.a]'e2#LXYejeHa-In)qLUg-U;~>
-)HlLj\D!1Kg=iQSg=hiU>^4uVZ"%$DDU2S1rRqD!=O!,&q:Z,*:tjXMW7os!gtDe;E;nQ$ZuOgR
-9\Phng<`mSg5VNpg&Zi$rn7KKg=ffSq:YgBrn7LQ8U`=\q:YkQGPg(pLn=@p!D_;Gg&OhCg'!h'
-g<iprg&[n$rn7lVg=gkSg,jam8CQ9dg=f6ug&OhGg&Oftg5FYhir@lhL=5Yig'>fPmcqOUfg1,~>
-)HlLj\^d1Yk2s"&k2r:$@=RG%]4k\^FP:0RrT479?.kdHq;qtB<T`GuZ0(1Fgu\XQG5gV6^3Jf&
-;!+F:k1j2'k*;Y7joL@@roO>[k2p+&q;qZRroO?f9nb<qq;q^fIf&7.OJ_d7!E/"WjoA6SjohBC
-k1s29joMK@roO_fk2q6&k!+Q49]"o.k2oM<joA6WjoA5/k)8@+li5YgLXYejeHa-In)qLUg-U;~>
-,?aHs\^c7gXJ'f<SZHO9XGpVa<-Y++7uER8Q^:sYPs(J#3;T]_V3O$.XI1#^QU^tU!AJl[X;7^%
-NL*MDP$+-<8$%/SQ]b1HEb:YjD>[email protected]=+MX9tto24(;DUP41IJblGXU3T\-XK6!!
-QY(iNXDU3#X9i4"QU@dO?^I*Jri@h8Eic?lBpXuYXK7m=Q)q'[E*T!9X@S\E?AttDKj$a>X@&>@
-6`ctmQ^:1CVjB9-X+@@3X9Q9(f@>Z*nb^iAa+NjD_!p&EJ,~>
-,?aHs\D!1Kg<>h!a4c5sg9Q%PCREAb>-GV[^qb*H]hZAY8,CpGd_&)eg;5)6^fgZj!Bcn3g(r.<
-ZbU5-\T#@">M>^(^pn"1OFb3FMYc$6aE*Heg=fZE^gPC`g'ZHI6bq:,cD[EoU\`[Sc'i@dg=h(k
-^k/E:g5Jc*g'Mu=^fK+<Geh*rrn9(uOP8E]L;:?2g=jJ#^"V2`NciFsg0DG/GHol,W,Y\ag/Yr(
-<SGZI^qa+,eA+Gefn%k:g'6R:hV*_4o)%,GbCT*H^@9fAJ,~>
-,?aHs\^d1Yk1H8HdcQODk.H9#EM1t1?b+7'bKG7pa&:+(9D[cWh8`.3k053Yb?k21!C3L@jqciX
-]ut6S_fs;I@-4DJbJS,XR#&qiP5=;Jds7>4k2osmb@T<&jpL.l8'BoSg9IY;XSV&hfV3<3k2qH?
-bDECak*/aBjp?IZb?EucJ'6#?roPq0R-*P1NQ]4Sk2suIa6)O8Q$h'Ck$cHVI_4aRZ$9=-k#omN
->3=FlbKF5Si6+X6jalQRjp(/Og!tl,nb^iAa+NjD_!p&EJ,~>
-+'J$o\^c7gXF*i@Brk92XK729:f)RI:h?_l:f*.QC]7-1?M^`0N_iPQXJ1#M:nIZf!EP*;X8o3u
-:_$a3XF*i@Uo^Y::fXTuK`4dJJblGSCf!rRXK7mf:kebI!2KNi!1s1k!g6AtqQ'dJ:f(g(X9)9r
-F8i6AJRADX$'e=`Mla"::f*MXX8uU[ri?0@:fRFq%\QXgXK6YC:i*57W)-<9rN$N7:o17S:f*:U
-XFj>GSZJ1W:]RJGXGs:c]'e2#LXYejeHa-In)qLUg-U;~>
-+'J$o\D!1Kg7;hfL"^9Sg=iX6AnIZ\Aq8UHAnJC'M#LudGP^#"Zt<oeg<H+8B#su*!H#%"g&T\&
-Ae&t;g7Dngd+[36Ao$,SVuC9.U\`[NLh:7fg=jMXAuYX\!7(RU!6G/n!kDp%qUu%EAnHYog&br"
-OoF&8Uj;sn$,'q_YhIg6AnJjXg&ZAprn7F7Ao%D"%a/J(g=hp+Ar56qeRiE]rRqd(B$o>@AnJR,
-g88Ioa4e<-AcUG6g5Xejir@lhL=5Yig'>fPmcqOUfg1,~>
-+'J$o\^d1Yk,)s2N95(qk2s(`Ci$#"Ckq/lCi$fIO8`qqIJW(4^2.V,k1QM^Ct&CG!HYg2joFB>
-C^tgSk,)s2gZIXaCiSV"Yl8G=XSV&cODJa-k2t!+CpNp"!87?f!7Ur0!lSo=qW7mZCi"t-joTF:
-RJu=LXag?4$--ju]&r.aCi%8njoKk6roO9KCiKC9%b>IDk2r@RCm!lBi,!5'rT4W;Cu"0gCi$uN
-k-&T;dcS^OC]NIGk)JL-li5YgLXYejeHa-In)qLUg-U;~>
-#$LBV\^c7gjK&?Qr/^oQJZOF(JZR+t#.j6SeVDWDqpbqlKCA!=nCg3Z~>
-#$LBV\D!1KjOsUTr3cUMJ_G\/J_JB&#3,[>g4n&Hqq;:uJaVg;nC^*X~>
-#$LBV\^d1YjQ6Hkr4i<bJ`_OGJ`b5>#4)<BeVDWDqpbqlKCA!=nCg3Z~>
-#$LBV\^c7gjK&?5r)`rYJZOF(JZR+t#.j6SeVDWDqpbqlKCA!=nCg3Z~>
-#$LBV\D!1KjOsU1r,;YAJ_G\/J_JB&#3,[>g4n&Hqq;:uJaVg;nC^*X~>
-#$LBV\^d1YjQ6HGr,r(QJ`_OGJ`b5>#4)<BeVDWDqpbqlKCA!=nCg3Z~>
-#$LBV\^c7gJZOF(JZPiP#.j6SeVDWDqpbqlKCA!=nCg3Z~>
-#$LBV\D!1KJ_G\/J_I*W#3,[>g4n&Hqq;:uJaVg;nC^*X~>
-#$LBV\^d1YJ`_OGJ``ro#4)<BeVDWDqpbqlKCA!=nCg3Z~>
-)-QCi\^c7gXK5MtMheBN9Mqmd9NnN&9VHV.9EItjB`:[2>('(pQ:tqm:]=#kFKC!dHu=M:JZOF(
-f;o1fmap!Ee+*=c#KMJckJ6T@6@]~>
-)-QCi\D!1Kg=gLSYcHK8@;"<>@<1(E@EXo7@00olK`5BcEh6^6^0uZJAH$!@PM2d?SVr'QJ_G\/
-f@gGgs5)Iaddm:h#Kq\dlFuc@6%A~>
-)-QCi\^d1Yk2pi!\[CR_Ao6\aApEHbB%NRPAccZ.MuI;oH)G8TaC^=lC&V]JS*$eaVNZSnJ`_OG
-fB*;'s4PqXe+*=c#KMJckJ6T@6@]~>
-1g08/\^c7gUg9%N1hplSS!R3K="]ej;lWEN4-qk,QTpt/3M[g$UHt0H2jcUg8"3>ECb,Ld!J?nn
-XF[I(XPBl]]'e2#LXYejeHa-In)qLUg-U;~>
-1g08/\D!1Kcule96ACAf`P6?6DEGS.C"HUu9><pL^ei"h8C/i+cVhI17DVO)>/b'lLc57d!N*kf
-g4@t/g>(Bdir@lhL=5Yig'>fPmcqOUfg1,~>
-1g08/\^d1YgjHoa7?*J+d)gF\F?[dJDrY9A:WZ2jb#Ha79\V+Bg/lAX8^'lG?dEN7O?*=&!O0t&
-k(2ZGk1o)'li5YgLXYejeHa-In)qLUg-U;~>
-%9`,]\^c7gN`rNcRZT`3X<VA.?uT)(>HELU6)T46U.1kuJ#kb.Qq3mOJ#PZ2KUGT:XFL5N!=Naq
-XF[I(XPBl]]'e2#LXYejeHa-In)qLUg-U;~>
-%9`,]\D!1KZZFjS_miD>g*;6FH&cXFFP<\B;q%Gobui5RU"W1O_->+:U"3&iVnurtg7eN"!=k!<
-g4@t/g>(Bdir@lhL=5Yig'>fPmcqOUfg1,~>
-%9`,]\^d1Y]m8c&cGNKXjs,bbJ<k/eHKMKi=5U%?fj37!Wod,mb[B#aWo@%:Yg$nEk,SFC!=k9D
-k(2ZGk1o)'li5YgLXYejeHa-In)qLUg-U;~>
-#[-TX\^c7gN`uC_!'L7^#%rHoLKJS$ri?u'VlZto(cG*iX?<CH8>*&cWB[JcX)pHdHN'uHUoApH
-JZOF(goL^kmap!Ee+*=c#KMJckJ6T@6@]~>
-#[-TX\D!1KZZH*!!)3CG#(r[rX)F)Arn85ge(WO#+%0Slg.^!o>KbaSekk)Sfoo*'Rf;"Acdm[$
-J_G\/gtDtls5)Iaddm:h#Kq\dlFuc@6%A~>
-#[-TX\^d1Y]m9S=!)W[W#)]L4[!%g_roP)"hra(S+@p/-k"su:@+OK&i`5.'jdT(CU]0BVgZ!eH
-J`_OGgu\h,s4PqXe+*=c#KMJckJ6T@6@]~>
-#[-TX\^c7gN`uC_!'L7^#%rHoLlON#ri?u'VlZto7])&RX?<S!)PF15WB[JcTQ%!64FsSbXF[J)
-X9Q9(f@>Z*nb^iAa+NjD_!p&EJ,~>
-#[-TX\D!1KZZH*!!)3CG#(r[rXgC]Brn85ge(WO#=OOC%g.^4U+NrKmekk)SbDt<19S(oKg4@u0
-g'6R:hV*_4o)%,GbCT*H^@9fAJ,~>
-#[-TX\^d1Y]m9S=!)W[W#)]L4[_>L_roP)"hra(S?/E,Gk"t3#,1bo=i`5.'es5C[:k@b[k(2[H
-jp(/Og!tl,nb^iAa+NjD_!p&EJ,~>
-1g08/\^c7gXDhrp@tBGCEGoNf5@U]\>HFoL.rL`UHnKDY0TRTDOVjamR;XQtXI1#?EEW:B!=Wgr
-XF[I(XPBl]]'e2#LXYejeHa-In)qLUg-U;~>
-1g08/\D!1Kg5h#NI\X#jOGnkA:jgtrFP>H62iGN+SN;jo4gd&T\0&oJ_MpF;g;5(dOE(9R!=t*>
-g4@t/g>(Bdir@lhL=5Yig'>fPmcqOUfg1,~>
-1g08/\^d1Yk*D'qKrh_4R$<Nc<.j=9HKO@]3g7eMVEL<65ef1n_BILmc':8Zk0530R!8Pl!>(EF
-k(2ZGk1o)'li5YgLXYejeHa-In)qLUg-U;~>
-+'J$o\^c7gXK6hnKrhA4G'U0eG(-NePH:j4G'9=ULAl?.IZel<XGs0[Rs&t$XJV&0G,5,=!IC,a
-XF[I(XPBl]]'e2#LXYejeHa-In)qLUg-U;~>
-+'J$o\D!1Kg=i0bW7ot-QC?OWQCusW]%Yl-QBoGBWrA:rTX^<"g9T8_`0Q^Xg=*I)QI,Wb!LgiU
-g4@t/g>(Bdir@lhL=5Yig'>fPmcqOUfg1,~>
-+'J$o\^d1Yk2rS5Z0(2XStbB)SuCf)`9-3XSt=6iZi6O.WPb=Hk.K[8c^p`'k2*kST%j8,!Mdki
-k(2ZGk1o)'li5YgLXYejeHa-In)qLUg-U;~>
-#$LBV\^c7gJZOF(JZPiP#.j6SeVDWDqpbqlKCA!=nCg3Z~>
-#$LBV\D!1KJ_G\/J_I*W#3,[>g4n&Hqq;:uJaVg;nC^*X~>
-#$LBV\^d1YJ`_OGJ``ro#4)<BeVDWDqpbqlKCA!=nCg3Z~>
-#$LBV\^c7gJZOF(JZPiP#.j6SeVDWDqpbqlKCA!=nCg3Z~>
-#$LBV\D!1KJ_G\/J_I*W#3,[>g4n&Hqq;:uJaVg;nC^*X~>
-#$LBV\^d1YJ`_OGJ``ro#4)<BeVDWDqpbqlKCA!=nCg3Z~>
-#$LBV\^c7gJZOF(JZPiP#.j6SeVDWDqpbqlKCA!=nCg3Z~>
-#$LBV\D!1KJ_G\/J_I*W#3,[>g4n&Hqq;:uJaVg;nC^*X~>
-#$LBV\^d1YJ`_OGJ``ro#4)<BeVDWDqpbqlKCA!=nCg3Z~>
-#$LBV\^c7gJZOF(JZPiP#.j6SeVDWDqpbqlKCA!=nCg3Z~>
-#$LBV\D!1KJ_G\/J_I*W#3,[>g4n&Hqq;:uJaVg;nC^*X~>
-#$LBV\^d1YJ`_OGJ``ro#4)<BeVDWDqpbqlKCA!=nCg3Z~>
-#$LBV\^c7gJZOF(JZPiP#.j6SeVDWDqpbqlKCA!=nCg3Z~>
-#$LBV\D!1KJ_G\/J_I*W#3,[>g4n&Hqq;:uJaVg;nC^*X~>
-#$LBV\^d1YJ`_OGJ``ro#4)<BeVDWDqpbqlKCA!=nCg3Z~>
-#$LBV\^c7gJZOF(JZPiP#.j6SeVDWDqpbqlKCA!=nCg3Z~>
-#$LBV\D!1KJ_G\/J_I*W#3,[>g4n&Hqq;:uJaVg;nC^*X~>
-#$LBV\^d1YJ`_OGJ``ro#4)<BeVDWDqpbqlKCA!=nCg3Z~>
-#$LBV\^c7gJZOF(JZPiP#.j6SeVDWDqpbqlKCA!=nCg3Z~>
-#$LBV\D!1KJ_G\/J_I*W#3,[>g4n&Hqq;:uJaVg;nC^*X~>
-#$LBV\^d1YJ`_OGJ``ro#4)<BeVDWDqpbqlKCA!=nCg3Z~>
-#$LBV\^c7gJZOF(JZPiP#.j6SeVDWDqpbqlKCA!=nCg3Z~>
-#$LBV\D!1KJ_G\/J_I*W#3,[>g4n&Hqq;:uJaVg;nC^*X~>
-#$LBV\^d1YJ`_OGJ``ro#4)<BeVDWDqpbqlKCA!=nCg3Z~>
-#$LBV\^c7gJZOF(JZPiP#.j6SeVDWDqpbqlKCA!=nCg3Z~>
-#$LBV\D!1KJ_G\/J_I*W#3,[>g4n&Hqq;:uJaVg;nC^*X~>
-#$LBV\^d1YJ`_OGJ``ro#4)<BeVDWDqpbqlKCA!=nCg3Z~>
-#$LBV\^c7gJZOF(JZPiP#.j6SeVDWDqpbqlKCA!=nCg3Z~>
-#$LBV\D!1KJ_G\/J_I*W#3,[>g4n&Hqq;:uJaVg;nC^*X~>
-#$LBV\^d1YJ`_OGJ``ro#4)<BeVDWDqpbqlKCA!=nCg3Z~>
-#$LBV\^c7gJZOF(JZPiP#.j6SeVDWDqpbqlKCA!=nCg3Z~>
-#$LBV\D!1KJ_G\/J_I*W#3,[>g4n&Hqq;:uJaVg;nC^*X~>
-#$LBV\^d1YJ`_OGJ``ro#4)<BeVDWDqpbqlKCA!=nCg3Z~>
-#$LBV\^c7gJZOF(JZPiP#.j6SeVDWDqpbqlKCA!=nCg3Z~>
-#$LBV\D!1KJ_G\/J_I*W#3,[>g4n&Hqq;:uJaVg;nC^*X~>
-#$LBV\^d1YJ`_OGJ``ro#4)<BeVDWDqpbqlKCA!=nCg3Z~>
-$X)o[\^c7gXK5#VU]%7oA,!&*B;g]h!/(85"`LKD9fuMVX8tLLri?-mE.P*AXNIUK]'e2#LXYej
-eHa-In)qLUg-U;~>
-$X)o[\D!1Kg=fk,cMcGsIeVOsK%>h5!2f`h"c_6i@8(V=g&XuGrn7CqNe,o8g</+Rir@lhL=5Yi
-g'>fPmcqOUfg1,~>
-$X)o[\^d1Yk2p/MgAU.6K_OU0M;a?S!3cAu"dS64B2EaMjoJC[roO73Q@\1Lk/ufjli5YgLXYej
-eHa-In)qLUg-U;~>
-$!H]Y\^c7gXK4P^X9!6bri?0"+-?H&!G89fX;$;GXI2kc<g'P9Aun4rWDK+dXB^^8XF[IrX9Q9(
-f@>Z*nb^iAa+NjD_!p&EJ,~>
-$!H]Y\D!1Kg=f6ug&[2$rn7Eg-as!-!J8m[g(^Bhg;7CSD7SAsJ_ErOen)hSg3'ZOg4@u$g'6R:
-hV*_4o)%,GbCT*H^@9fAJ,~>
-$!H]Y\^d1Yk2oM<joLaAroO9#.DYoE!K#cmjqP#2k07W&F2R.CLuq[ribHj&k'O^kk(2[<jp(/O
-g!tl,nb^iAa+NjD_!p&EJ,~>
-$!H]Y\^c7gXK4P^X9!6brN$$%OT)<l6oV'GKKXWDCTFP;Ccm!DqlCuBBMWJ;G-%W/4Jf-Y=Zh0n
-Q`*P><iN1%JNRIJXI;76Ei])=1gXQkAQ!BHW(K1CXK#Yj4CkOm;ER$^XK77@?)`K?HTZ&CXHG\F
-A6Q(7?Ta+FTK/3U:oX5k&Qk-r=cK8,BrjOuXClp^XB^^8XF[IrX9Q9(f@>Z*nb^iAa+NjD_!p&E
-J,~>
-$!H]Y\D!1Kg=f6ug&[2$rRq9k[f4tk=%:`oVbNXSLtLG6M+j>jqq<62K4KjGQ.j_e9[VSFED3&r
-^XZ[bD:[FpUeH5[g;?TXOP0Nb1j=7`J7skpeQkkhg=LXE97GUGBM;$]g=i]'Fk<NcRnSUig:Bsm
-Ira8pGYG0lb=K4*A_-Y1&TG24EO4&cL"]ASg4GpMg3'ZOg4@u$g'6R:hV*_4o)%,GbCT*H^@9fA
-J,~>
-$!H]Y\^d1Yk2oM<joL^@rT4-(_#EI,>>!l:YYq5mO6#HaO\he6qrT)DMe\AaS`\j5:u19nG>P;4
-b2Hl-F5l?EX\a^uk06_!R-"5-1k'ssLMi:;iF>^4k2V"h:ke&kDGX)sk2s-LI,hJ/Uem*4k/:)8
-Km;b?Io*N7f1a,LCZ5'N&U(tPGeMn3N94+!k)#ttk'O^kk(2[<jp(/Og!tl,nb^iAa+NjD_!p&E
-J,~>
-$!H]Y\^c7gXK4P^X8uObrN$$%OSu6j6)Ufc2K#U'M6(N@XD`C]X<O&SI3NuDS5Z8c;O(IIXAi#t
-GFbgdAupPrXFq[V=KJTIEr2ppV&Fq+Io;q>SubtUG]9a^D6.0$XI4C9L176B?*#r$XC-jB?*'81
-T<)CVXCR!c?;>^3I/'cT4KPWA8OH15XD2E^.X\>!HYe87JZR%r#.j6SeVDWDqpbqlKCA!=nCg3Z~>
-$!H]Y\D!1Kg=f7!g&frLZi/SYE45`!%TCj1g-gkQGcobWS_B'kqq<72-_DoYGK":Eg1S'>[G#A,
-g6]k6Uk7<qK%d+N[W'sSQB;!t1smJC-)#"qCrtCJ\X/?1e;Dt,X4kF[g8TMSZ$"bhMV<?XY]ea5
-,g+hcY1e?&g3@+o_4CAT&PUp4Y?Y(9\(ZRiK/K7Sg74"Ng4@u$g'6R:hV*_4o)%,GbCT*H^@9fA
-J,~>
-$!H]Y\^d1Yk2oM=joXXj]`$snG/4(=%ThQMk"(]uJ%4X'V<4#:qrT*I.B"hoIF)ogk&&.a^ZKKM
-k+C)aXbl2AMWV/n^inl&Ss]E;1u0CZ-`V%8En'5m_k<=Xi0!/Q[H>`0k-K^&\pWX3P3.;'\pWY[
--Iq7.\)rCLk'h$:bGP's&Q%WP\RAZR_<-`8M`@Trk,"2kk(2[<jp(/Og!tl,nb^iAa+NjD_!p&E
-J,~>
-$!H]Y\^c7gXK4P^X8udbrN$$%OSu6f6)Ufc4KPVkM6&*(49.SBX<*d)P#dHHK-NK@/Tj=[XI)hc
-Ue3a$Aun1rXK7ImL&S.R4Su37V*ghHQ;W_b4?P<9Sl7a:UTBhT4ADZR8iJjp+KR],XC-idOK>NT
-T<&kl4?63=?>T>:&pJ;rXB(LcJnD*cJ:ME_XK6DcJZOF(bH(oZmap!Ee+*=c#KMJckJ6T@6@]~>
-$!H]Y\D!1Kg=f6ug&ZT$rRq9k[f+ne;q'IS9\S3FY1bW09E7ibg)e+@\S\NoV(GA73L!Fqg;.@S
-csBC+K%`uOg=ir_WW(TO9`*Nud8\1n^[email protected]_=FHcJ$*@9OcE'?:IU^.,%AKg3Kf=[bBG?
-b1[q29M&dKG_u.J&snX4g24CSV1I@SU8*O9g=hUSJ_G\/bM!0[s5)Iaddm:h#Kq\dlFuc@6%A~>
-$!H]Y\^d1Yk2oM<joL+@rT4-(_#<C&=5W0&;!-ni\E5XI:]OGkjrVc]_fNA:Y:i^K4IfI7k0.T&
-gga/CM<7ask2sF3ZMrtd;#BB0h-&3:a_eaA:f'EAe8J/ag?-Uh:[email protected]('m`_<0lg
-e`IuN:ebZdIZa?d&tkQQk&\K'Y))6&X/qD[k2r#&J`_OGbN9#ps4PqXe+*=c#KMJckJ6T@6@]~>
-$!H]Y\^c7gXK4P^X9!6brN$$%OSu7>6)Ufc4KPVkM6($?XK6cMXEo;rXI2hH<f14K=Jr6aO].UJ
-B2G[0PH7VnXDW?cXF#S2XK7.cqlDNK6_6o9;O^^]XI,'6P,tHIXG`UMNE`K,F0)HiX?<Sc@#05H
-XICZ2XAtIcW.:sUM>XFUArutm#\AXiXB(LcJnG"`#-(ggXK5ZcrN$$LGCciHXO4*R]'e2#LXYej
-eHa-In)qLUg-U;~>
-$!H]Y\D!1Kg=f6ug&[2$rRq9k[f+o=;q'IS9\S3FY1e-'g=i(Ng7"Veg;7@1D6J/rE7EUR\7rb4
-K4WbP]%UbJg5DHSg75$jg=iNSqq<dP<6/C[BZ4l7g;121\_>D2g9ATNZZFibP1nW[g.^5SH**Zo
-g;Ghjg2+@Se=tZAY5HuSK"(^4#_8f+g24CSV1JX"#1mk)g=g\SrRq:GQ\!kAg<nUYir@lhL=5Yi
-g'>fPmcqOUfg1,~>
-$!H]Y\^d1Yk2oM<joL^@rT4-(_#<CS=5W0&;!-ni\E87Mk2rN&k+ej:k07VXF1H_>G2VN%_JdTZ
-MJD9n`TCunk*)S&k,#8:k2s"'qrTWh=jpm&D:!CXk01T\_rf`Yk.8t&]m8b1Rc`b/k"t4&J@;A;
-k0H!:k&JB&i2c!h\GYIiM8B/Q#`#VGk&\K'Y)*)>#30pEk2q$&rT4-\T7Q-Uk0`;qli5YgLXYej
-eHa-In)qLUg-U;~>
-$!H]Y\^c7gXK4P^X9!6briA:^.Q2OQX@+?rL4ggdTdrR5V-Z8HN3&j2:9:Nq."<[p/"i1o4B8&G
-;*8GeXI2R@@kFRZDEL%(XG/i"@]0+)10l2X-\*V4R79;7SUN4S5F&<c1d"?uXK6S-4DoftBq[%F
-XFE?,3M3CG<BNO4TIVj?ri?0n&9[rQ%;q!'XI2R@:7\Jf5!G82X8uRbri?0u4@+P"JZR8##.j6S
-eVDWDqpbqlKCA!=nCg3Z~>
-$!H]Y\D!1Kg=f6ug&[2$rn9PN2+3ebg/fq"Wi%G'bVrVWd<J>YZ.dSi@bTOM18-Os2Trg49P_hm
-Ak[beg;7#eIQ>j1MbHg0g8[h?IFJ)I13P=I0qpJ?_,sBBaIkXh:qbS<6;1\'g=hfc9T,f#L!2JV
-g7_2L8BTZ0CeR^?b;VbNrn7Fq'pS[N%?.FCg;7#eA&m<W:/8M%g&Z?$rn7G&9N-MrJ_JN*#3,[>
-g4n&Hqq;:uJaVg;nC^*X~>
-$!H]Y\^d1Yk2oM<joL^@roQC_3(T_)k$'Q9['26Df/d1!h0r0s]B7m8B]eGq26&U63S);Q:iY(8
-Cf#q&k0770Kfn5SP>G)Hk-Il\K\u[h141j[1oiOYb["%[e#>Q.<QO<`78RI=k2r42:m8.<N7^0q
-k,M6j9\&:VEDT]Wf/cBiroO:3(7b?c%?n6_k0770B[Z&*;cCa9joKh@roO:=:fi51J`bAB#4)<B
-eVDWDqpbqlKCA!=nCg3Z~>
-$X)o[\^c7gXK3mSV>dOsN*PPI!H^?jX9!-b_lNp-<Mf>h!D$hhX9,+sS,TJjJMF'RXF[J#X9Q9(
-f@>Z*nb^iAa+NjD_!p&EJ,~>
-$X)o[\D!1Kg=eE(dJhi#Z?59`!L-.Dg&[&$_qG1/Csqt0!F(-Ag&fQ:`W"QmUd!:Zg4@u*g'6R:
-hV*_4o)%,GbCT*H^@9fAJ,~>
-$X)o[\^d1Yk2nXJh>ZO;]R/i(!LujPjoLR@_r_$FEo$BM!FU`MjoX4Wd/N//X[:ork(2[Bjp(/O
-g!tl,nb^iAa+NjD_!p&EJ,~>
-$X)o[\^c7gXK7SFWr9"!RHL[OU@PAfJil/Fm]6D*r&at9hQ-fS4AVU@X9"fjm&U5eSGfMiV4`C@
-JZR5"#.j6SeVDWDqpbqlKCA!=nCg3Z~>
-$X)o[\D!1Kg=j*EfDXD'_WTYQcLTZkV+aRUmb.Z!r(I*nhV&'A9Ou<;g&].Dm+MKk`r4TldE@*p
-J_JK)#3,[>g4n&Hqq;:uJaVg;nC^*X~>
-$X)o[\^d1Yk2sRqj8J*?bie-gg%+8-Y#%romcFM4r(mC'hW=oR:heJOjoNfgm,e?-dJ`2.gt%&=
-J`b>A#4)<BeVDWDqpbqlKCA!=nCg3Z~>
-#$LBV\^c7gJZOF(JZPiP#.j6SeVDWDqpbqlKCA!=nCg3Z~>
-#$LBV\D!1KJ_G\/J_I*W#3,[>g4n&Hqq;:uJaVg;nC^*X~>
-#$LBV\^d1YJ`_OGJ``ro#4)<BeVDWDqpbqlKCA!=nCg3Z~>
-#$LBV\^c7gq5aUh=Pp1\F?0/u!0clQ!J,C)X9+k?QLCmZM^5=(Sq`R$X9"bpr2]oVGk8!;X%`/e
-#-3K7XH/+3l)XuYU7A"MX8nIAX9"WdrN$!_r2]s`XHWXb!EYnEXS&Y!]'e2#LXYejeHa-In)qLU
-g-U;~>
-#$LBV\D!1Kq:YkkDr97LP=bT(!5%^R!Mbpkg&f2L^$jYZYV"M]aJuuEg&]*6r7V0=R.K#4fO4@*
-#2-#Yg:"$.l.Q6\c,S*$g&SbBg&\q=rRq7`r7V4ag:R@<!H-&2g@a/(ir@lhL=5Yig'>fPmcqOU
-fg1,~>
-#$LBV\^d1Yq;q_-Fl2<^Rn`_@!6+Eh!N_j'joWjfaRA6q\hN4-e$I0djoNbSr8n#MU%@CIjCRuG
-#3E2"k.n=Yl/i)sf[8FEjoEBXjoNT`rT4+!r8n("k/I>^!HckCk4Rj@li5YgLXYejeHa-In)qLU
-g-U;~>
-#$LBV\^c7gq5aU8H/>V&4Sc&Y4R]?O4LhHn<g)mP"[8rfOBP6GX8uLbr2]pCEV$74X*jQ@#-0op
-XD0;Wl)Xu&I:S$&X8kB?X8tnbrN#u]r2]r^X??K`!HiI7XS&Y!]'e2#LXYejeHa-In)qLUg-U;~>
-#$LBV\D!1Kq:Yk/RGQWt9_mBB9^g[89XrdWD7T)g"]!_([W5[Dg&Z6$r7V1<O7V'+fq.ii#2)c]
-g4hT-l.Q5qSpmX0g&Oh(g&YL$rRq6Fr7V3Gg._M"!L/aug@a/(ir@lhL=5Yig'>fPmcqOUfg1,~>
-#$LBV\^d1Yq;q^BU>G#4;#05R;"*NH:q5WgF2[M/"]FFD^j'>YjoK_@r8n$QQh0>?jeh\4#38\m
-k)DINl/i)/VhMDIjoA68joJr@rT4)Vr8n&Wk"u'>!M#U0k4Rj@li5YgLXYejeHa-In)qLUg-U;~>
-#$LBV\^c7gq5aU8H2al[Ilp7hR?Biu;4W@a@m!qiFXpZYA#]@,(8kP&>rA^W=$/U(XF_0L8Z]"Y
-7QaA5poGc(XK67l<\dTBXI;mHG-%KE4CKLcSl7a9OK>O54@hi,P!M3-SbfE&Ug#rj6EFrb4Dq6!
-5tO1eX?KHG4H0-<)HL0,9UVuC4Zl`:I3r>a?DX`D4ARQ/XK8$cri?3e76H7uX;G-$XK7RO4B6C&
-Wan4pU37T%P9O&/M*"6,X<Es'4C;U"P!M3gXDMWHRSKrL7QaA4N#uXSAgXUW?p%_kqQ(BHI:S#4
-V-Q2l-%DOd4?ek.Hkeb>ri?iT4A_Q%*b_X%*ccTi4CY7%*ef:hB`"k;P8ZABW2tXe4@fCP!^*PH
-ri?-CF+LFcX9Q9(f@>Z*nb^iAa+NjD_!p&EJ,~>
-#$LBV\D!1Kq:Yk/RJtnTThJZj_RWQ<B?-o#IS=e-PW!SVIFe;L(=[Y(G!k!-DbNj1g8,]]>h[oF
-=A3/@pt@#fg=hHID*Vi;g;IGoQ.jT,9RJIeaD"=E\(]Q09NtN5\Pl16`qnC(cZ;d.;qd"#9T.V=
-;I)tfg.l3W9X4HJ)Js^m@)CX*9h]BGShPF`GLG3-9P$6:g=jYSrn7Ie=%oOeg)+k;g=j)99PfdD
-f7-J6cBT`C\gqXOY"Mstg*+7;9R)!>\Pc,*g5CSo_dhE6=\N5?Z7(;QJM>g-H;&M0qUuX>SpmWl
-d</-00;6L&9M`+NSJk14rn8*K9P)5C-A1$B-BO`k9RPBC-E3pjK_sI0\faI9e_6o>9NqGL!_h<A
-rn7C;P(D?[g'6R:hV*_4o)%,GbCT*H^@9fAJ,~>
-#$LBV\^d1Yq;q^BUAj9iWDHu*c,3UZCsoO?Ki!$JS2kjkK];mk(>j[>I7NGOF\koIk,o\#@HQ^m
->u5.XpuWl!k2qgkF$jnOk0@X:S`\^S:kCC%dr/&^_<0m[:gdJN_cKZNdJDu?gNl\L=QYZ@:m:$[
-=(5"(k#6%r:qQSd)KU@(B$KJQ;G_DaV_`j"IGO%R:hi/Sk2t0&roO='>Yq["jqr?Wk2sTa:i_ob
-j+^BSfpsO``%?&m[npH2jrqoW:k+/\_cK[Gk)tX:c=l@]?;P4X]IJafLbe,MJ5C[MqW8KQVhMD<
-gjDqL0ri`B:fG0lVArEHroOr_:i"Ia.#[5a.%$f,:kR_a.'g*+Mu2WC`$.fMiT@?a:ga4a!`8#U
-roO6ORXsVojp(/Og!tl,nb^iAa+NjD_!p&EJ,~>
-#$LBV\^c7gqQ(X::me>cI;>pW0n3?(XHuec3/"A?M6&@iX@T#]X:8QnXG\j8S<9nS4KPVHrN$-Z
-U9&oXq5aUDD>pU[/!26E4K)/HXE/MhN3%alXI,9SUdV;5C94'`Ip&\NQVmU\'jH[!L,WjqXK6_b
-RP:A84KO0!VlW#WX<L\XXFb&cJubtgI&o/\XAtI)G-%&XWiW:o8Z]"^=/2j/K)2Q4SlMGbQ!'uc
[email protected];X?<Sc8tN,cW]dGbU/[_c?sJq!VlX6^D0B*5:99AJXFk)c5^b\F4KMqHXGU<[X:g_c
-OI`IYMl_[kXI,6RVF%Ac4T2>rEHeLO:old\B<44sJZPqFSZFrTX??<[!D/p^X8kB\X9*sSJc;_O
-QVi=8orJA/map!Ee+*=c#KMJckJ6T@6@]~>
-#$LBV\D!1KqUunAB#33TT82.C5G<)Hg:q:S8#Y-dY1c"Eg0;btg'rA0g9<fq`ja[U9\S2orRqCX
-cJ#(Gq:Yk=MuMER2RkQU9\!dog6.\BZ.c3Hg;(DUcrSknL>'g8TlAK7^h3Gs'm$_8WCDZ8g=i$S
-`&u/q9\QC>eCmUmg*1Bcg80ASUtOIXT%ZN5g2"<^QJ0//f\5'$?/"#NDU-seV>An0a_]/S]l;HS
-@#s#kVqSOug.^5S?-1gSfM:/Sc"bASH?Hi>eCo/MMjACYA(n03g89DS;4^CV9\Ofog95\rg(M!7
-[`@*EZ.c6Hg;1GUdT"rS9`<Z[O-eS:B%fr4KA'#QUY=F.aP'>Ag._=r!F<hGg&OhEg&e&'U]/sJ
-^Lr,Op"BW0s5)Iaddm:h#Kq\dlFuc@6%A~>
-#$LBV\^d1YqW8aYCWtr'W/p)l6E57ek/qN&9<mW/\E6#hk$Zd;jpcmMk.*kAdD=u-;!-n:rT46n
-g#fDnq;q^RP5aSe3Q!_p:uH39k*hfe]B6Ikk0(g-gfrp>Nonn[Wd!@_b&$q:'mdOTZUp1Uk2rJ&
-c9TnA;!+u[i9!l4js"l'k,sO&XlSW+VWL@Vk&JA-T'"6QjQ>US@clguFP>l5Y579Ee8j.&a*->%
-AXDP6Yi`]Ek"t4&@asQ&jAP.&fPo@&JU>@[hr]EtP+Hp"B]cnYk-'R&<MrTp;!*;:k.,p:jq>VW
-^sV:l]&pCjk01j-hH8q&;#TMkQ_3E`CZ\IUMWRatXQJYUe)jKhk"tm9!FjRWjoA6UjoVXHXT%>_
-a_cUkp#ZJEs4PqXe+*=c#KMJckJ6T@6@]~>
-#$LBV\^c7gq5ap?H`X;VLod\VKOb"_$p:URXK5ccX?<Sc8>,j]!'L7^#s>;]<'39(XK4P_X9=YR
-4=t1@X9#:bri?JiX?<RHV&)6V4)R1[X:@@oS5;=.7''gPXK8@S@fEG/4Sl,Z4T;DoW'R>_XJ/1Q
-:9:NZXFk&bX???\,$'l.JnD*A4Zk$<X?<Sc<Kg.HXK4UcXK8$cXK7I)4?PZQqQ((*>*#b?@B?PS
-END+u4=`q'MI)'HX/rD&4fk`S9rtFsWIuKY4?A.4H@&gjXHH"7/nM+LW'%.DX=sQ8!)E3g!'L7^
-#s>;Z;*6m+XK4P_X;+De4?PR(>`:e1;lk.)4;sclF`VSHq5aTgTDbhk4SGiWGB&28orJA/map!E
-e+*=c#KMJckJ6T@6@]~>
-#$LBV\D!1Kq:Z15SD)\BXkMLZVgeX!$r#AKg=geSg.^5S>Kcot!)3CG#u''qCJ7Dng=f7!g'"oe
-9K@_#g&]c$rn7`Rg.^3od2bnS98cLCg($g1`F_e7<n_o$g=k)UI/_h"9`!HC9`E`Xe5FcLg<Ed=
-@bTO0g8BGSg._@s,&OmEV1I@(9h[43g.^5SCV+#ng=f<Sg=jYSg=it_9MA'MqUu>1EjaW%HeR2?
-O4m&%9Ij<#YBR$pg"P04:>4F@@G9Gfeu1,n9M)1@S"4V1g::9Y3e5p]eP+[jg-#@.!+Y]U!)3CG
-#u''mB1tlrg=f7!g(e!a9M@q0Fg4WRC"ehG9HhL2P`h,oq:YjTao0on9_R0@Q]H^Op"BW0s5)Ia
-ddm:h#Kq\dlFuc@6%A~>
-#$LBV\^d1Yq;r$IUupfi[cZ`2Y_E)=$rH(_k2q0'k"t4&@+P5;!)W[W#uKd7E)9A*k2oM=joiP*
-:csU1joOI@roOSbk"t2:h&fHi:QnWSjpk5MctcHO>NULEk2tX.KDt!5;#9;S;#]Shi)eguk1O(d
-B]eGRk-0U&k"tp:,'1]bY))5N;,B$Fk"t4&EQ)S:k2oS&k2t0&k2sH.:f'obqW81IGe`CJK')3g
-Qf^m=:b,l7\:1f:jlY^d;Wd,gBBJ@;iit+4:ee3XUnr?Mk/1G#4br0"iDAZ5k!/iA!,2&f!)W[W
-#uKd3Cf!i.k2oM=jqVH!:f'dHHb3+pDs!Wf:a=HOS=5h:q;q]eeG\M0;"j#PT9k,kp#ZJEs4PqX
-e+*=c#KMJckJ6T@6@]~>
-#$LBV\^c7gq5bKQH*"*1<i`9?O]%sTLg[;HX/oWaX?<Sc8"fa\)L68%F"=>EAZKB'XK4ObSoCc2
-PH-ZTXK7.@r2]l\ri@8*X?<RHWEbIaST/[nX)'PmG]9]f6`cGOX/g6&;kg=K?i$i=EHeIa@u"Kn
-X'^^P9rtEYXFk&bX$$6[-<651Jn;#JW2M"iX?<Sc<0N5GX,@^mXK8!bX/r$rS?%^$XK4L?rN$Z9
-Ni\jOU8oncXFOubX(/6)<(E/OX=C55X/r1$PcL*pSl2>aLkfhnX=?uH=-9OEA?8"o4KCTGH#Kaa
-A#ubG>ktHKF*4O#0s#\=X'J&nX?<PNG-$U-X/fa3V&*G]LTEV=P8^!nRSHVHq5alpSuZA&X?<PV
-DY^@7F`[M_!I7@iXS](']'e2#LXYejeHa-In)qLUg-U;~>
-#$LBV\D!1Kq:ZaHRG-B*DV<^'\7j1@XErSog"LYPfhC,R>KZis)OcW<OuD$kJD#HEg=f9Sac>(k
-]%KT)g=iQ&r7WGjg=k4Rg.^3of6+IRa,lFKfnhrIR#]j@<SG!#g"DFrC!PD6H2?50O-ePQIB._J
-fm0a<@bTL/g89ARfhD7r->^6HUk%/qe^Z=Dg.^2RCV$cofruFIg=jVQg"O_g`n@bog=f3&rRqp*
-[+`Z:c.P1=g7s>SfmVT!CKe=Kg+(]Kg"Onp]\1&ea_9#RXK.5Ig,<HpDR\:kJ(d`K9\E+mR>onQ
-IG3D/FSXW<P*FXX52)Hafl^6Ig.^29Q.iHcg"Cf-d2dE\X4g8#\fo,J_dd2pq:Z-]aOu!qg.g8D
-Mtu'-P`l"!!L[>HgABS.ir@lhL=5Yig'>fPmcqOUfg1,~>
-#$LBV\^d1Yq;rT[U?:UUFQMVM_J\)h[XdL:jlV$$j\Y($?e,&9)PWJXRQ9K5LZO:ck2oP&e<T0:
-`8sXJk2s!Lr8o;%k2tc%k"t2:j*\Q%d[-AmjcMpmTU+\b>3<_DjlMfFDqX6\JGSCCQ_3C$KXHEn
-jaXbbBBJ;PjfaF$j\Yg9-?@#dXbZ%=iScPhk"t1%E5]>8jgcDlk2t-%jlY6;d,i$Ck2oLMrT4c<
-^?3saf]>;_k,aL&jb2dKEF6Z`jsoChjlYED`oY=8e8F"%[Bu*ljuI,;FMd-7L?;Lo:utO8U6Od$
-K]_EVHMQ\NR[iK&60=r,ja:1mk#(6aS`[M3jlM0Xg`Lts[,t6I`$<^mc=gn:q;qune)c8Fk#(6k
-PPO>AS=9E=!MO+Vk549Fli5YgLXYejeHa-In)qLUg-U;~>
-#$LBV\^c7gq5aU8H2al[S39#[XK4iR@'##EC8!dbFZk#54^@ib%XC3Z:3ipU4bGtTXJA!Nri??!
-4bZ%rX@k/CX<]p0XDU1O6A7R[XBIb[XK6G*Hp"L3@m,N/O0"m84a4!/7Qk,RX;,_<4f#094["b*
-=?Vsm4aBU^Uh2cGr2^m-4]AFQ4f,5E5_;FQ4`HiQ;ll'D?"IKHJNZ.gri?>u4^"kfKb]LDX8uLb
-ri?Pu4bZ&#XFNGsPcUs+<rT0&M*4!hri?0#4]23[*^r5"W]`_NTPpp5:-F:oKfrjQAmB,QGs+<[
-XIUqGpoFsH4aK5lXCOJJ4cZV84\u'Y'9>:>Krh18Kft[%R6=Pe>-+fYAG</176RTNXJS-OpoFL=
-F8i6BVEI4rXS](']'e2#LXYejeHa-In)qLUg-U;~>
-#$LBV\D!1Kq:Yk/RJtnT`_B0pg=fY'HJ58kL<NA$PYIRV9m$6c%[p+V@[c#+9r:ahg<`Q"rn7Tc
-9rUk8g0Zl<g*BAGg5A\"<2`Qpg2]npg=hZ`SP7bkISHe9[bAbr9paSf=A=)9g(fZC:!hUr9hhnH
-E)"'29po9]d"+omr7W./9ki<d:!qZj;5I?d9od+cC>--kG(>"pUeOQirn7Tb9l\n@W#Mr=g&Z6$
-rn7fa9rUk@g7h;9]\;)$D>r5kY"_Virn7Eg9kXIZ*`l'^fM,B"bDk60@nipsWD._dJTZb%R8$Dp
-g;c6opt?4@9q+i1g4)hr9siWr9kF=X'=LV0WS5irWD1"Y_+ea'En]6FJ+qY%=A@?"g<r]"pt>b5
-P5a/:dS3YkgABS.ir@lhL=5Yig'>fPmcqOUfg1,~>
-#$LBV\^d1Yq;q^BUAj9id8<c6k2ooGJEF(5Nn7-@S5Gut;1&0%%\cgjBVOXL;6Ns-k1igCroOGu
-;6j'Uk%$UPjs3dck*&ZC=g:l7k'9g7k2r(/V,6=:Ki,-Q^uj'B;5!(6>u?.IjqX4[;;:6B;,Osf
-G#?>N;5.Msgk\h8r8o!F;/bT*;;LA6<N]T*;3oL)E9=u6I><I;X\hr*roOGt;0V0bYoU@QjoK_@
-roOYr;6j*^k,V?V`ocEMF8k;([o$"*roO9$;/Q<p*aDQnjAB+Ces5C[BMl'4Z;H4*LjP3FU/=e7
-k0cD:puW'T;5@%Nk(Za=;822B;/6*m'>RIBZKC(BZ;JX(bY`DDGin.mLA0g8>uBSCk2&sCpuVUI
-Rf;FNh,.7)k549Fli5YgLXYejeHa-In)qLUg-U;~>
-#$LBV\^c7gq5aUc<9UC`Vu3=jWp-Sc0V&'B!I/bZX9>T"UhPDKX8o6tU]@@YXSejoV;83R6Ak]B
-!L$^*X9+&JWVNUuX/)P+JE!X6UcG?SXJYok!3>Ri!E,EdX9+kQU4KECX9Q9(f@>Z*nb^iAa+NjD
-_!p&EJ,~>
-#$LBV\D!1Kq:YkeC?X@Oe,7MlfBLui4iR?Q!LT/Eg'$'Sc\8._g&T_%cN)M\gAK7sdG<LW<3Q5R
-!P<Bjg&e0Zf(n#&f[%luU>jl1cq)X>g=#oF!86hp!GKFNg&f2cc%4UGg'6R:hV*_4o)%,GbCT*H
-^@9fAJ,~>
-#$LBV\^d1Yq;q_'E9QEahu)4/j6>\,5g]Gk!MH"Ujojc"gPi6&joFE=gAp0sk5<s6gth)n=Le:k
-!QB<%joVeuiq_^>jP/FLX5`7FgJ$Mek2-$j!9N\3!H-6_joWk)fR`2^jp(/Og!tl,nb^iAa+NjD
-_!p&EJ,~>
-#$LBV\^c7ghQ-]mr'UOKe#WY?6puOmX8n%R6i_GsX8o9u6i^2FX94q[7"4*r"\D*rXK5e,6i`j1
-XPp5b]'e2#LXYejeHa-In)qLUg-U;~>
-#$LBV\D!1KhV%scr)Wm0e(OoA=')*`g&S2O<reTQg&Tb&<rd#pg&o;q=.eI*"^G,_g=gfL<rgBo
-g>U`iir@lhL=5Yig'>fPmcqOUfg1,~>
-#$LBV\^d1YhW=g!r*'0?e)gbX>?e,qjoDge>6(;]joFH>>6&Z%jo`t7>H$NC"^tVok2q0k>6*3)
-k2GG,li5YgLXYejeHa-In)qLUg-U;~>
-#$LBV\^c7gJZQ_i!2BCm!M-+YX8nuTX8o!nX9#>rJZS^L#.j6SeVDWDqpbqlKCA!=nCg3Z~>
-#$LBV\D!1KJ_Iup!6tGq!QNUZg&TBXg&TCrg&]jPJ_KtS#3,[>g4n&Hqq;:uJaVg;nC^*X~>
-#$LBV\^d1YJ`ai3!8.53!R]fqjoF%ojoF'4joOPsJ`cgk#4)<BeVDWDqpbqlKCA!=nCg3Z~>
-#$LBV\^c7gJZQbj!Jk.]X8t>$o;htm4nPf[X'fM?F'tR'X94NMN10.8!.+1:!gR/?ri?0Z@"n0Q
-!d^qori?-#PQ%WbU/db8XS](']'e2#LXYejeHa-In)qLUg-U;~>
-#$LBV\D!1KJ_J#q!N^VFg&Xa*o@a5t:A!6EfQr)%Oa>(4g&ne!Z,H%`!1WN4!k`iLrn7FXHDpDg
-!h7o5rn7Bh])LCbc"tFOgABS.ir@lhL=5Yig'>fPmcqOUfg1,~>
-#$LBV\^d1YJ`al4!OdRWjoJ/BoB$)7;Y9)UjFE$JR=N`Mjo`EA]?fm,!2T/I!loheroO9mJ?nb.
-!i4tSroO6%`;\m#fQ,Dkk549Fli5YgLXYejeHa-In)qLUg-U;~>
-#$LBV\^c7gJZQbj!EtN_X:pnaG&aUbUQhCPTp27KPaebNP_T.<+.8@hTrb>]PcLic(nQ=BV6$&K
-R]N?MUm7^@XK8+[T_YYkCOK`Hri@B4Pbb%TSWoD@Wg'<DR&mB]1mFK2XIPl^Pc(U]Pa%oDXJ(D4
-ri?0kF]87?%@36ZXJD/`R\-[_4KL[EX9!HbrN$$+MLhl+X9Q9(f@>Z*nb^iAa+NjD_!p&EJ,~>
-#$LBV\D!1KJ_J#q!HPRHg(V66QB0bRcFh9QbIl'J]YrOO]W(k`+2Y\;bhCdb]\1tU+3:9RdFuFL
-_qNPOd(Rc>g=jc`bPBioLn9'orn8X5][4sXa1T+>fY#SD_:mVb6+k1jg;V.b][PTb]Y)MCg<?Tl
-rn7FnQ"p9O%DKL.g<[Le_o^Wd9\N2>g&[G$rRq9rYCYF)g'6R:hV*_4o)%,GbCT*H^@9fAJ,~>
-#$LBV\^d1YJ`al4!I2?XjqGkVSsSU%fuDP(f>cG"`m<f&`j>X++3hg[fB25;`oZ<(+k*Slgucf"
-cK<s&gW/$hk2t:8f(nG1O/I]:roPKL`nT2/d`0>ij2Tinbi\';7E3^:k0VT;`o#q:`l?Znk1@"<
-roO:0ST+Pi%EZWOk1du>cID"=;!(URjoM!@rT4-0\:Nf>jp(/Og!tl,nb^iAa+NjD_!p&EJ,~>
-#$LBV\^c7gJZQbj(g;s$XF4&I4`RR%=&`4hJK9?0,\='=;a(,]+bs&s7pN-C<)dq?D/_t5:99%H
-<)nd=+&s=_,HRY@<*#[gX=J(7A;%%cJQ,T8B9Q=p<-Y5n6r[-=XEkmdDQKpT6Z,k4XCbF2<i)n!
-X$-E_!L-O^X:BVW<-,.",)TB$S#e`R4T;D_F`[M_!FCY7XS](']'e2#LXYejeHa-In)qLUg-U;~>
-#$LBV\D!1KJ_J#q(im";g7E%o9on#YDJF%+Ua;kR/V)QaBhnZ]+ffBn>'8PiC2/pcMiLrXA(mbp
-C29u`-Yt)H/DABdC2M,ig+.uNI]1uSUha^DK"Gi6C73I4<bcEJg7'C'N8!!A<JtU?g4=!RD:.(k
-fhMG!!PE1Hg('ZgC6@5U/$E`*`7do=9`E`HP`l"!!I(_ugABS.ir@lhL=5Yig'>fPmcqOUfg1,~>
-#$LBV\^d1YJ`al4(jNdWk,30;;O?P)FDu<HXXC9p0Sef,Dc6Ss+gc6.?[Lq3E,_9.P*TG"B]cI;
-E,iD,.<6eX0BUu0E-'S+jsuLjKsBe&X`8;^MT'UTE1u)Q>B"Sdk+jADPNM"g>*EoXk(mtqF5?!@
-j\c!=!QT0Yjpn8-E1,k$/\,kBcfS'd;#]SXS=9E=!IhP0k549Fli5YgLXYejeHa-In)qLUg-U;~>
-#$LBV\^c7gJZQek5+YcKXGpPdXCZCQ9RDbL6EEhNV,!_cXK"FbXI`7cXFG#D9oG!3Hu4.;G>>62
-NK%^bX?`(5RQRZBI>r\FqQ(O-UnFQcPujocG'$3JXK,ib@WSW3=fe\erN$L*(OW<PB7[.cS4p#c
-X$-E_'9lFsXGfl2NE:M/2I<5PVQ?2eRJs8gR8<d_!KgH7XS](']'e2#LXYejeHa-In)qLUg-U;~>
-#$LBV\D!1KJ_J&r50.Nag9PqSg457<@%=Ns;qbU!d::DSg=T0Sg;mjSg7a;+@^*.TSr9"_QXeaj
-Za,C;g/5RW_bAcgT<b+lqUue1d*'kk]l)BSQBGCqg=^qSI?N<lESB,?rRqb/*hD$%K;7/S`F.ER
-fhMG!'>/)6g9G(iZ>Q5e7!I&$e(V[m_Z&6i_IWW!!P!#ugABS.ir@lhL=5Yig'>fPmcqOUfg1,~>
-#$LBV\^d1YJ`ao551=N(k.H-&k(f;cAYm&?=QX/Bh.YF&k2]G&k0n,&k,OHQB=YZrVNRX(T4mB9
-]tBD]k#KJuc;<Y2VnB!7qW8XIgXb3Ca*$A'Ssj!<k2h<&KUV&<GNS$arT4UF+/\2FMQGt&ct;G&
-j\c!='?>(Sk.>69]QC"48:B:DhWE)Fc2Qi+b\I+=!Q&r0k549Fli5YgLXYejeHa-In)qLUg-U;~>
-#$LBV\^c7gJZQbj$<iIkLLI9cGB']Dr`]P<XGpG<@fEG4W]dGbRn`j_!JE?0>8*-9HAbEkXFFDX
-7V/YdW'%.DX>Bi[!,M8/!K^F^X8kB^X9iWj@YLnE=fe\erN$$r6iO.f>)rT`"?`ceX$-E_"dDre
-XG&M1>69qg4SGiWF`[M_!FCY7XS](']'e2#LXYejeHa-In)qLUg-U;~>
-#$LBV\D!1KJ_J#q$?EN-X*`RSQ]KijrcA<pg9Yk"IK%q(fM:/S`F8`!!N8BbF;)0BS$670g7`P/
-=Ff+&eP+[jg-P^[!/U=%!Om"Gg&OhGg'NM+IAtr.ESB,?rRq;"<W:\QEjYi""AIP'fhMG!"h\U(
-g8RF<F98r*9_R0@P`l"!!I(_ugABS.ir@lhL=5Yig'>fPmcqOUfg1,~>
-#$LBV\^d1YJ`al4$@';I["@H&TU4e6rd"a)k.Q&GK`:*;jAP.&ctE=>!O5/oH5"/YUq1)Mk,ETO
-?&.QBiDAZ5k!]2p!0?g8!PrpWjoA6Wjp@'HKX0aTGNS$arT4.9>5mXbGeX1>"An7Cj\c!="ikTE
-k-@JUH31tG;"j#PS=9E=!IhP0k549Fli5YgLXYejeHa-In)qLUg-U;~>
-#$LBV\^c7gJZQbj6!B;MVdk41/Q]$A=bVQ6XJf#PUTCPiKJ81_Wc!!6GBg#pJ;%lq<FMsr:982R
-Kf2\t0onD[3L,b5KnWg6XA_C[X>m1nH\HNjI;=Og?_^;2XEI%1X@n7cKrg1hLod\P=G;H6Q)pX4
-08HX1Rr^lSXJ]QXKl2X:/qp%pX9!HbrN$$+MZ'UW;a>o8#.j6SeVDWDqpbqlKCA!=nCg3Z~>
-#$LBV\D!1KJ_J#q6#s?de:+*j3H*WgEN,pYg=9k%ce@*rV`_$6f8Q#pQ^H9NU8a'NCO=c8A(l['
-WC17<5.+%q8\MZXWMt'pg1aI\g,RZ;S#MODT89JCGgBfTg6Gagg0^h=W7nLCXkMLRE2fgY^"UZ.
-40.)h`0+$(g=1PEWJmju4/pO#g&[G$rRq9rYPm/UC/KQ9#3,[>g4n&Hqq;:uJaVg;nC^*X~>
-#$LBV\^d1YJ`al46$U-+i.\2:4E]f2GI"N"k2C2Fg?.PKYX#VYj-6.@TV14qX0RqqEJ!=VB]b>H
-Z:JZY6GH=89ut5#ZEeo@k&+5qjuD=YUp?DgW/n6fJ(eLrk+,c7k%1i_Z0&Vd[cZ`*G-\E"a6(sX
-5IBS8c^InHk2:omZBMWD5-il:joM!@rT4-0\GbOjDcMAN#4)<BeVDWDqpbqlKCA!=nCg3Z~>
-#$LBV\^c7gJZQbj!EtN_X:8lRP@L\qO(2[iXK7+sri?3e@q00NX9*EPE;lp[BOc@h@qVm=KWM7m
-A!:Dd@s`QOGCciQ@q246PTFl>X;GeaFf_Zm@qDa=@r/5cA"p&m@sP/WH"1RfX:Lq5@uRLjQ"+<9
-XK7@j@rVFK#AI[oXHI('ReWrbF`[M_!FCZ_X9+V-EIk1q]'e2#LXYejeHa-In)qLUg-U;~>
-#$LBV\D!1KJ_J#q!HPRHg'raa\p`;d[=*JCg=iNhrn7IfI=6_Hg&d@aO8diSKRK?CI=p8#VqTj`
-ICaj<I@H_!Q_`?=I=9>n]-`X6g),]qPhOi_I=U&#I>Q[<IEgK_I@8gCRXKnhg(2>SIBqS\]mY<\
-g=if[I?+<\#D@Mog:;W[_t_pdP`l"!!I(aHg&eo6O+H!hir@lhL=5Yig'>fPmcqOUfg1,~>
-#$LBV\^d1YJ`al4!I2?Xjpd<'`.[:8^P%9fk2rt<roO='KS53]joUp'QN$"fMhIkdKSnpIYib)3
-KZ&P^KVYEBTWR@eKS7t>`[I5Kjqs87S`](4KS\dIKTP>^K\>M4KVIVkU4eO*jq$!qKY6I0aFo5'
-k2s:/KU2W"#E4>2k/2k*cM6N&S=9E=!IhQXjoWONQ\"9'li5YgLXYejeHa-In)qLUg-U;~>
-#$LBV\^c7gJZQbj!N';DX9+B$X1,/2?`<t*!ha8,ri?0]E3"Pk#.j6SeVDWDqpbqlKCA!=nCg3Z~>
-#$LBV\D!1KJ_J#q!Rc;4g&eUAfsfZ9Ggu`H!m?;Lrn7F\NnK!;#3,[>g4n&Hqq;:uJaVg;nC^*X~>
-#$LBV\^d1YJ`al4!Sr=FjoW5_jgX@QJ)L=g!nN=iroO9rQK<\[#4)<BeVDWDqpbqlKCA!=nCg3Z~>
-#$LBV\^c7gJZOF(JZPiP#.j6SeVDWDqpbqlKCA!=nCg3Z~>
-#$LBV\D!1KJ_G\/J_I*W#3,[>g4n&Hqq;:uJaVg;nC^*X~>
-#$LBV\^d1YJ`_OGJ``ro#4)<BeVDWDqpbqlKCA!=nCg3Z~>
-#$LBV\^c7g\Z>gqU4KCsXF[JEX9Q9(f@>Z*nb^iAa+NjD_!p&EJ,~>
-#$LBV\D!1K\_7(qc%4T"g4@uLg'6R:hV*_4o)%,GbCT*H^@9fAJ,~>
-#$LBV\^d1Y\`Nq2fn&::k(2[djp(/Og!tl,nb^iAa+NjD_!p&EJ,~>
-#$LBV\^c7g\uYt(+H:rRJZOF(o;i/-map!Ee+*=c#KMJckJ6T@6@]~>
-#$LBV\D!1K]%R5+.'eEXJ_G\/[email protected])Iaddm:h#Kq\dlFuc@6%A~>
-#$LBV\^d1Y]&j(B._L>pJ`_OGoB$8Cs4PqXe+*=c#KMJckJ6T@6@]~>
-#$LBV\^c7g\uYsD>E+38JZOF(o;i/-map!Ee+*=c#KMJckJ6T@6@]~>
-#$LBV\D!1K]%R48FL$JOJ_G\/[email protected])Iaddm:h#Kq\dlFuc@6%A~>
-#$LBV\^d1Y]&j'KHG"gkJ`_OGoB$8Cs4PqXe+*=c#KMJckJ6T@6@]~>
-#$LBV\^c7g\Z>g9NIe0^XF[JEX9Q9(f@>Z*nb^iAa+NjD_!p&EJ,~>
-#$LBV\D!1K\_7(+Z@U_\g4@uLg'6R:hV*_4o)%,GbCT*H^@9fAJ,~>
-#$LBV\^d1Y\`Np=]Rf3rk(2[djp(/Og!tl,nb^iAa+NjD_!p&EJ,~>
-#$LBV\^c7g\Z>g9NIe0^XF[JEX9Q9(f@>Z*nb^iAa+NjD_!p&EJ,~>
-#$LBV\D!1K\_7(+Z@U_\g4@uLg'6R:hV*_4o)%,GbCT*H^@9fAJ,~>
-#$LBV\^d1Y\`Np=]Rf3rk(2[djp(/Og!tl,nb^iAa+NjD_!p&EJ,~>
-#$LBV\^c7g\Z>g9NW#pZU7d(=JZOF(q5ae3map!Ee+*=c#KMJckJ6T@6@]~>
-#$LBV\D!1K\_7(+ZMiJXc-([lJ_G\/q:Z&4s5)Iaddm:h#Kq\dlFuc@6%A~>
-#$LBV\^d1Y\`Np=]`$snf[bW9J`_OGq;qnIs4PqXe+*=c#KMJckJ6T@6@]~>
-#$LBV\^c7g\uZ!Q1/<W(X8t^FJZOF(JZS[K#.j6SeVDWDqpbqlKCA!=nCg3Z~>
-#$LBV\D!1K]%R7I5[peng&Y8@J_G\/J_KqR#3,[>g4n&Hqq;:uJaVg;nC^*X~>
-#$LBV\^d1Y]&j*\6YNk+joJ[TJ`_OGJ`cdj#4)<BeVDWDqpbqlKCA!=nCg3Z~>
-#$LBV\^c7g\uZ1"M2@_'XGIsXJZOF(JZS[K#.j6SeVDWDqpbqlKCA!=nCg3Z~>
-#$LBV\D!1K]%RG"Xf]Oqg9)a/J_G\/J_KqR#3,[>g4n&Hqq;:uJaVg;nC^*X~>
-#$LBV\^d1Y]&j:8\$s]Gk-l_PJ`_OGJ`cdj#4)<BeVDWDqpbqlKCA!=nCg3Z~>
-#$LBV\^c7g[&a:oM1MaZXF[JJX9Q9(f@>Z*nb^iAa+NjD_!p&EJ,~>
-#$LBV\D!1K[+YPpY(>;Xg4@uQg'6R:hV*_4o)%,GbCT*H^@9fAJ,~>
-#$LBV\^d1Y[,qD1\:Ndnk(2[ijp(/Og!tl,nb^iAa+NjD_!p&EJ,~>
-#$LBV\^c7gJZOF(JZPiP#.j6SeVDWDqpbqlKCA!=nCg3Z~>
-#$LBV\D!1KJ_G\/J_I*W#3,[>g4n&Hqq;:uJaVg;nC^*X~>
-#$LBV\^d1YJ`_OGJ``ro#4)<BeVDWDqpbqlKCA!=nCg3Z~>
-#$LBV\^c7g\?#[LpT+Uq:f)P@XI+\8X9!jAJZOF(OfSbumap!Ee+*=c#KMJckJ6T@6@]~>
-#$LBV\D!1K\CpqCpY#l!AS%Fdg;0]]g&[qfJ_G\/OkL$!s5)Iaddm:h#Kq\dlFuc@6%A~>
-#$LBV\^d1Y\E3dWpZ;_9CMTd/k0("'joML0J`_OGOlcl6s4PqXe+*=c#KMJckJ6T@6@]~>
-#$LBV\^c7g\?#[2pT+TiR$aVLXH.GsX9!.'ri?)kJZOF(Q)k2$map!Ee+*=c#KMJckJ6T@6@]~>
-#$LBV\D!1K\Cpq"pY#jU_84CMg:!.<g&[&Ern7?WJ_G\/Q.cH%s5)Iaddm:h#Kq\dlFuc@6%A~>
-#$LBV\^d1Y\E3d4pZ;]fbKJQ#k.mDZjoLUcroO2hJ`_OGQ0&;:s4PqXe+*=c#KMJckJ6T@6@]~>
-#$LBV\^c7g\uZgC86N$qFCK2[M6*XH)+[c/XE[9eXK5*P859)b%p__qXK6I\88##[88t:o<e7?'
-XIcKt]'e2#LXYejeHa-In)qLUg-U;~>
-#$LBV\D!1K]%S(G>B&<MPC/BpXkM<0+Br[9g6c*>g=fu<>@INb%sD0rg=h]4>D(Y3>E7!5D1UDl
-g7I"&ir@lhL=5Yig'>fPmcqOUfg1,~>
-#$LBV\^d1Y]&jp^@!CbqRt?r6\)uXW,%,HRk+Q1ak2p9c?t]K$%t.j3k2r*V@#F*T@$]JRF+NJ)
-k+:]>li5YgLXYejeHa-In)qLUg-U;~>
-#$LBV\^c7g\u[KaTK90UV&jlS5c^uZ31utHXJUDSXK6@gTUAHSXJ/XSXK86XTVSZf32NZYJ:XeQ
-XIcKt]'e2#LXYejeHa-In)qLUg-U;~>
-#$LBV\D!1K]%Sagb":=@d3b7';VBaG7`rs/g<uU?g=hNAb/.N>g<OE?g=jqDb0Sek7a]k-UOh-M
-g7I"&ir@lhL=5Yig'>fPmcqOUfg1,~>
-#$LBV\^d1Y]&kU*ekP;hh'erI<orGo9%MYWk1uqek2qpcf$.dgk1O[fk2tJlf%]?F9&/KOXF]Mb
-k+:]>li5YgLXYejeHa-In)qLUg-U;~>
-#$LBV\^c7g\?#Zmri?>eXK4RcXK4P^X9aSiXK6YcXJA8`X8uIbri?)^rN$-LCnan$JZOF(Su`.-
-map!Ee+*=c#KMJckJ6T@6@]~>
-#$LBV\D!1K\CppVrn7TNg=f9Sg=f6ug'Fa+g=hmRg<`n"g&Z3$rn7?GrRqCGLs9\VJ_G\/T%XD.
-s5)Iaddm:h#Kq\dlFuc@6%A~>
-#$LBV\^d1Y\E3cfroOG^k2oP&k2oM<jp8>Gk2r>&k1j2?joK\@roO2WrT46[OP"O%J`_OGT&p7C
-s4PqXe+*=c#KMJckJ6T@6@]~>
-#$LBV\^c7g\?#Zmri?>eXK4RcXK4P^X9aSiXK6YcXJA8`X8uIbri?AfXIGWZVGM2Hri?-]JUsnR
-XJ2d#]'e2#LXYejeHa-In)qLUg-U;~>
-#$LBV\D!1K\CppVrn7TNg=f9Sg=f6ug'Fa+g=hmRg<`n"g&Z3$rn7WOg;Lk^dUeAnrn7C\Uk.6N
-g7m:*ir@lhL=5Yig'>fPmcqOUfg1,~>
-#$LBV\^d1Y\E3cfroOG^k2oP&k2oM<jp8>Gk2r>&k1j2?joK\@roOJ_k0M<7hJ8@:roO6rXb#Vc
-k+^uBli5YgLXYejeHa-In)qLUg-U;~>
-#$LBV\^c7g\u[ER4;U,ND&7\[(Lj=*(Hdn_XE$!>=fa8)XBQR'XAg;tGH@l[4AD6FXHYC;X9,Fu
-.=nROXJ2d#]'e2#LXYejeHa-In)qLUg-U;~>
-#$LBV\D!1K]%S[V9H?gHM]JLq*IQ@1*DF*!g5nEJES<N2g2nIFg1i'%QeL/I9Obilg:TNHg&fr<
-1kFA3g7m:*ir@lhL=5Yig'>fPmcqOUfg1,~>
-#$LBV\^d1Y]&kNm:``H\OrgX6++rKJ*`0i<k*SCeGNM+Jk'A5dk&;h<TB>9p:hS#7k/KXbjoXXZ
-2hC+Bk+^uBli5YgLXYejeHa-In)qLUg-U;~>
-#$LBV\^c7gOK8IqJc;_PN$=mFXF[IIX9Q9(f@>Z*nb^iAa+NjD_!p&EJ,~>
-#$LBV\D!1KOP0_fU]/sKZ7="Jg4@tPg'6R:hV*_4o)%,GbCT*H^@9fAJ,~>
-#$LBV\^d1YOQHS$XT%>`].MQak(2Zhjp(/Og!tl,nb^iAa+NjD_!p&EJ,~>
-#$LBV\^c7gOfSUi-p%@/!Mbp2XF[IHX9Q9(f@>Z*nb^iAa+NjD_!p&EJ,~>
-#$LBV\D!1KOkKk[1J7Z#!RAB0g4@tOg'6R:hV*_4o)%,GbCT*H^@9fAJ,~>
-#$LBV\^d1YOlc^m2GX86!SYSFk(2Zgjp(/Og!tl,nb^iAa+NjD_!p&EJ,~>
-#$LBV\^c7gJZOF(JZPiP#.j6SeVDWDqpbqlKCA!=nCg3Z~>
-#$LBV\D!1KJ_G\/J_I*W#3,[>g4n&Hqq;:uJaVg;nC^*X~>
-#$LBV\^d1YJ`_OGJ``ro#4)<BeVDWDqpbqlKCA!=nCg3Z~>
-#$LBV\^c7g\?#^kFk!Jm=6?RaT_kej=6HY#Kf(tS>ca_t4A;NOU-q+HVQ?7L4CtJfX93l54Fd4/
-"K5fm4Iu8K!G.ktX957n4Au0[!*Aor!KhF%X8npeX8uY(JZQkm#.j6SeVDWDqpbqlKCA!=nCg3Z~>
-#$LBV\D!1K\CptiQ.4LfDW]XQbPTunDWf^hW'j<PFkY2S9OZ9$buRMWdb;W59Rt[ig&mp?9VM=:
-"P%rp9ZQq^!J/>eg&oZ29PFFZ!,hPb!P"6jg&T=ig&ZEFJ_J,t#3,[>g4n&Hqq;:uJaVg;nC^*X~>
-#$LBV\^d1Y\E3h*S^cd%FQV]cf)+S0FQ_d%Z:@_eHfj(!:hJGDfNV0rhWE-\:l"$+jo_MX:oaBS
-"Q4u1:t#.$!Jo5"joa@O:i?9p!-Itt!Q(6'joF!+joKqdJ`au7#4)<BeVDWDqpbqlKCA!=nCg3Z~>
-#$LBV\^c7g\?#Zme#WOfk,\PFqlBd9kH#G\Ml`aBXC?pcN`rMWSZI$TX?<Sc@#+T["$EZd4Sl,^
-KOh0c4SYuYH(t)8!F:W]X8m25X9"`@ri?,`WqWRqJ7sM8`iKBUmap!Ee+*=c#KMJckJ6T@6@]~>
-#$LBV\D!1K\CppVe(Oe\k1Tf/qq;%/kLp][YhIK)g3fpSZuXl-a4cl@g.^5SHE?ts"&.G&9`!HG
-W.*IS9_d<BRa(W]!Ht^Fg&R*+g&]$drn7BJf_=)#U4e*O`nCXVs5)Iaddm:h#Kq\dlFuc@6%A~>
-#$LBV\^d1Y\E3cfe)gXpk2lY?qrRmCkN3Pq]&qgOk(9u&^3JdNdcR3hk"t4&J[P@:"&S.B;#9;W
-Z%_?&;#'/RU=f8'!IVKVjoCY?joN]/roO5ZjS.d;X,DPk`o[Kks4PqXe+*=c#KMJckJ6T@6@]~>
-#$LBV\^c7g\?$u=XK68)?:A$pXJ/WUJukn^4Dcm)UfolGS?/fN4A/bFSO5M@U\_&-QTR^<XCat*
-4F=02TM7OeD3?K?>Zdg!X93PZ4BMN`'g=7OXF2s@3G(UZVI)H,XJdn.D+:,lX:nHtXC?pcN`rMW
-SZI$TX?<Sc@#+T[".$$`7Ja(gKOh0c4Sc'49eN!<N%B'5>c"N&+>>pIXH>V<XK5c&<'5`5XE-=<
-XK7<p4$]mB0gr*:0:f1pBS!8)X9Q9(f@>Z*nb^iAa+NjD_!p&EJ,~>
-#$LBV\D!1K\Cr6&g=hH_G?8iug<F>*V:sFL9Su*0cuMfW`nK.P9OD\Ua&PfNchc?2^e@h`g4EIH
-9Ushjb@4/)MRY[cF`5V'g&mNW9Q'j`'i$gDg7CZe8:jgpdWeHKg=8EdMcn0sg(S)6g3fpSZuXl-
-a4cl@g.^5SHE?ts"2<L7=Sg_SW.*IS9_mBr@QMQ`Z8[q?FOAf[.6UADg:'a`g=gd[C.tGWg6+m`
-g=ibM92XEh5$$BF4NH0MKRqjsg'6R:hV*_4o)%,GbCT*H^@9fAJ,~>
-#$LBV\^d1Y\E5)6k2qh.IU%/8k1OZLY3+Yt:m"/HgNZOpdH9T':h=dqdTKCggA9qIb"u@*k)!Dg
-:o*79en7gEOi'<.HZn0@jo_(m:iu^!'iR<Yk,1_09Slm6h1&7ik2A\5P$ZZ5jqDRRk(9u&^3JdN
-dcR3hk"t4&J[P@:"3BWY>l*RcZ%_?&;#06-B0F]*]K2NYHedb*.m["Yk.sl*k2q/*E)<\!k*el+
-k2s5q:K?Q26!NJ_5LS\pMh1$1jp(/Og!tl,nb^iAa+NjD_!p&EJ,~>
-#$LBV\^c7g\Z>gbAH&YR-Aj"-4K2AHXD*/qK<0DVXHJUFUdV;=@B?"KK3"hMO]V=Z!'L7^&0R%8
-4KP;YS#fOoX@Q0HOHB=?!'L.[!'L7^&2J\eJip,AM6(i@XD0tGTmld<'0N@t@YUtE>-(AfXESZc
-4KPVlL\\"QX&bG\X9=2eXK4PZX:.mmXK4[+XDE9cXBgb^X9UkhXJ[2*X??K`!Jt1_X8tJari?E8
-Krg><XK7^gW.D%jX9Q9(f@>Z*nb^iAa+NjD_!p&EJ,~>
-#$LBV\D!1K\_7(^J,\.F0Wlq49\+'og4c5NVV7P,g:=TEcrSl#HeQIqVesi8\8M)q!)3CG&1P$@
-9\Rg0`7epKg080o[^Q%d!)3:D!)3CG&3ldJUeKKeY1f,'g4rLoc(Ojc'27-6I&bo-EnXm@g6[lS
-9\S3HXSLQOfkn=sg'"@'g=f6qg'hN/g=fDag52BSg30^ug':=*g=.Rag._M"!NgYHg&Xt$rn7[,
-WS4b"g=j8XeUcGpg'6R:hV*_4o)%,GbCT*H^@9fAJ,~>
-#$LBV\^d1Y\`NpsLAp<Y1Uo'N:uZQ:k)?<qYNDZNk/4pqgfrpJK'(H=Y]JX__K>S8!)W[W&1bNX
-;!-JQcfT.nk$Vu:_8,p0!)WRT!)W[W&4<B[X\e/0\)s3Lk)NE:fW"Z.'2[iRK!a[SGiiPbk+J('
-;!-nk[JAqdj`AB:johrCk2oM8jpZ"Lk2o[0k)lM&k'Xc<jp+`Fk2.]/k"u'>!OmRXjoJB@roON?
-ZKAoGk2sa+iIU.3jp(/Og!tl,nb^iAa+NjD_!p&EJ,~>
-#$LBV\^c7g\Z>h)8H,[u4KLZH4J`iV4?-h5ri?SlXJ/cY3CKrWLTISKJn"_\!'L%X!'L7^%6U_n
-4KOuHXK8=mX@SEHX8kB[X8kB^X9Leg4KLZH+T=J*:onDJp8esSDQKpKL9-D=X@o+cGB']HXK5fb
-qQ'am=.B#e"GC<eX??9Z$r<:mX?`_cCj`=c?&SW^#<])hVa7Dc4T;D_M-p7`!BmI^X9kRjX@]%c
-XG:;dJZQnn#.j6SeVDWDqpbqlKCA!=nCg3Z~>
-#$LBV\D!1K\_7),>lNFb9\N1o9[OkS9LsV+rn7iUg<FM/864GkX4l:KV0r9r!)31A!)3CG%8>L0
-9\REog=k'"g0:uZg&OhDg&OhGg'17)9\N1o./lmBB%i#sp=^4MMqZm4WnOh#g0_nSQ]Kiog=gkS
-qUu"qDoDJ*"K6e'g._:q$tR6/g/6DSM4NASG-Lnu#>Ek*e5G#S9`E`HXa0p"!D_;Hg'Pu,g0DeS
-g8fYSJ_J/u#3,[>g4n&Hqq;:uJaVg;nC^*X~>
-#$LBV\^d1Y\`NqC@K,Bs;!(U::u*3i:eZR>roO\ek1FfQ9O$Y1[H?W#Y(Q`9!)WIQ!)W[W%8c3L
-;!-&:k2tRPk$YsujoA6TjoA6Wjp"ZE;!(U:/,i?ID!$b?p?!'aPNM"Z[-#)Ik%)p&TU4e;k2q6&
-qW7k3FjKmG"L3[Ck"tj8$u4&Lk#LC&Oeq4&I(K7<#>jRFhcJt&;#]SX[t"D>!E/"XjpBXHk$cg&
-k-Tg&J`b#8#4)<BeVDWDqpbqlKCA!=nCg3Z~>
-#$LBV\^c7g\?#Zmri@8*X?<RHWE>@cTR1C&XEQM&G]9`s7')8PXK6c0<MZ^W=no&u4T;Dk4KPVH
-XJApcXI=^A8>,^Y"$EZMLAn7S4T;Dk4KLZH4KMtGXK6?AC4?)^!F(3TX;Gr$XK5lcXH$Jc9:`/.
-END:(XC-gbXF"LWX92OdXDe*>%:X^dXFt,cX?<ScVGEKUX:.mmXK4[cXDE9cXBgb^X9UkhXJ\@c
-X??K`!Jt1_X9^thWH,)AD,4jEX9!ibrN$$U=+RHsX9Q9(f@>Z*nb^iAa+NjD_!p&EJ,~>
-#$LBV\D!1K\CppVrn8Mhg.^3oeo/1SbFF9[g6Y.[Q]BdP<na^$g=i()Cs^nDEVS5f9`E`T9\S2o
-g<a`Sg;B`?>Kccp"&.F^WrC]P9`E`T9\N1o9\Olog=hP?LS+Lu!Hb4;g),m;g=gqSg9bnS?cUle
-O4m:]g3TjSg73Wkg&l6&g5Z*c%=Fc$g8KJSg.^5Sdq$/jg'hN/g=fESg52BSg30^ug':=*g=0$S
-g._M"!NgYHg'CI+ere\?MI_D>g&[q$rRq:RDLpNcg'6R:hV*_4o)%,GbCT*H^@9fAJ,~>
-#$LBV\^d1Y\E3cfroPA#k"t2:icW6&etn>*k+G0*TU+_t>NWGEk2rJSEnoflGPL;#;#]Sd;!-n:
-k1b"&k0C*k@+P)7"&S.$Zi9(e;#]Sd;!(U:;!*A:k2qrkNi;m<!ICsJjqsGWk2q9&k.Z*&ACBV5
-Qf_-,k(0r&k+m_1jo]_Bk*>r.%>1P?k-9X&k"t4&heC11jpZ"Lk2o\&k)lM&k'Xc<jp+`Fk208&
-k"u'>!OmRXjp4lGigJrkP%fjRjoMN@rT4-gFFiSujp(/Og!tl,nb^iAa+NjD_!p&EJ,~>
-#$LBV\^c7g\?$u=XK67mIl2m5M5=378><(t4E3E`VHc6.0TW;t4?RJ\TgLqFVY[A.QTQraUh2<9
-K.q#@Uea*JUQR>nK(uDbMEFe4XK4T>4H4bCE(+n7HDb164J/Q02f/Jp!gajHrN$icKWM8N:cqFH
-XJ&$E=J`*f4?R2RXJJ*Hri?ej4?PO'XI:;HXK8@14?T19XG7CHri@VE1-0lC0OUn<5-.d@3-;7'
-OZY<[Wa@H>I5#WAF#YsXXK8'X5G5*ZV,*?TX9!ibri?1$:b%$tbcD#[map!Ee+*=c#KMJckJ6T@
-6@]~>
-#$LBV\D!1K\Cr6&g=hHITgPbAY0h#Y>Kt`Q9TMg"dre?O4gj"Q9MC>qbZ.>Vde_Z3^e?jac[n9[
-VEBUecX]^ZcaZ/2V>/a^Y"WQVg=f:a9XC<QN`VHBRac^Y9ZbgP7>Urs!l#qArRr*^VqTkOAkZUY
-g<<SkE73IY9MBueg<iYorn8&[email protected];>Cog=k&*9MEI[g8bsorn8l35=qKQ4aP^I:YK\P8!DZ\
-[nJnXfQfWdSii%eP".fVg=j_E:s7SHd:Bohg&[q$rn7G+AMo%mbh<9\s5)Iaddm:h#Kq\dlFuc@
-6%A~>
-#$LBV\^d1Y\E5)6k2qglW^j<Z\D2(#@+jOu:mOl=hKr(l6,2Qu:f*>8fNM*qh>67Jb"t?"gPJ2&
-YX"31gM'Jtg;?3OY5%,s\57(uk2oT-:q`blQ<]q[UYp`#:t4Gn8W`r6!m2dVrT4rsYib*&CJ\Ws
-k1Em7G2;<,:f)r+k1im:roOn`:f'^Fk0>N;k2tTU:f,R%k-Po9roP_D6;=Dk5_.lb;s&0j9:Y/,
-_,*BnjF9G.Va-R1RS-(mk2t5l<7^3oghFe-joMN@roO:CCH-n-biT,qs4PqXe+*=c#KMJckJ6T@
-6@]~>
-#$LBV\^c7g\?#^JHh"0<F*4Ud!E3UmX9+A=U\Lnk?X!3*!B>\\X9"YbrN$$%OT)<_V'h[^XN[aM
-]'e2#LXYejeHa-In)qLUg-U;~>
-#$LBV\D!1K\Cpt@SFP;6P*E*&!G[2Jg&eTKchQ2pH#iZ5!Cip8g&\s$rRq9j[f4t^d5&Rig<A7T
-ir@lhL=5Yig'>fPmcqOUfg1,~>
-#$LBV\^d1Y\E3gTV"*RJR[gMB!H<nXjoW4dgA'e2IsLeN!D9NEjoNVArT4-(_#EHtgbm?-k02rl
-li5YgLXYejeHa-In)qLUg-U;~>
-#$LBV\^c7g\?#_2Vt@%nR63TSX7*+iK`!q4F6fn-Wr+sZ:#i;UVQ/d[!NN'lX9#6!pT+@ke>rb"
-3]<B)X8o*pX8o)JXNR[L]'e2#LXYejeHa-In)qLUg-U;~>
-#$LBV\D!1K\Cpu9e+D>s_G!Xfg$dVpVu03gOmC^$fDJ;B@cQ/Ce(Eg:!S>fpg&]^TpY#VpeCk"q
-8jpJog&TP!g&]mSJ_J<$#3,[>g4n&Hqq;:uJaVg;nC^*X~>
-#$LBV\^d1Y\E3hQht6%6bYV-+jmV=3Z2@DuRHru8j8;^RBB/+ThW3h]!TW)3joOB"pZ;J2eE-k1
-:.WS-joF38joOT"J`b/<#4)<BeVDWDqpbqlKCA!=nCg3Z~>
-#$LBV\^c7gJZOF(JZPiP#.j6SeVDWDqpbqlKCA!=nCg3Z~>
-#$LBV\D!1KJ_G\/J_I*W#3,[>g4n&Hqq;:uJaVg;nC^*X~>
-#$LBV\^d1YJ`_OGJ``ro#4)<BeVDWDqpbqlKCA!=nCg3Z~>
-#$LBV\^c7g\?#ZopT+UK4?RVbXGCB\X8uOdri?*TJZOF(Q)k2$map!Ee+*=c#KMJckJ6T@6@]~>
-#$LBV\D!1K\CppYpY#kF9MCQ%g8o_sg&Z9'rn7@RJ_G\/Q.cH%s5)Iaddm:h#Kq\dlFuc@6%A~>
-#$LBV\^d1Y\E3cipZ;^Z:f*M@k-]m:joKbCroO3gJ`_OGQ0&;:s4PqXe+*=c#KMJckJ6T@6@]~>
-#$LBV\^c7g\Z?[IKWM8TWN)ntXK8?]W2Qf!Wgo6RXJi1uW;`k/WK!XRXK"=[WN</!WiW.uJZOF(
-Su`.-map!Ee+*=c#KMJckJ6T@6@]~>
-#$LBV\D!1K]%S(UeYq3Uf@JR(f\5'09%DMHg=O?Tg=k*0e^aZQ&(\)3g=k.Ne^iI,e^rO*eq)P+
-g7I"&ir@lhL=5Yig'>fPmcqOUfg1,~>
-#$LBV\^d1Y]&jpmiN_P-j5T+XjQ>U`:>t0ok2Xh+k2tX`iSjdu&)t:Tk2t]!iSs"\iT'%YiIU-B
-k+:]>li5YgLXYejeHa-In)qLUg-U;~>
-#$LBV\^c7g\u[KU5U`_8E$8(D>cakh(-kWrXE64+XK4-H5XL1+XB-R+XK6:T5[pgL(2KWh6@l4h
-XIcKt]'e2#LXYejeHa-In)qLUg-U;~>
-#$LBV\D!1K]%SaX;)?q[N[e[=FkYAC*)U2!g64aJg=e_n;,jOKg28CJg=hK*;1.)s*/Mik;h<YR
-g7I"&ir@lhL=5Yig'>fPmcqOUfg1,~>
-#$LBV\^d1Y]&kTo<As"%Pq?iQI-0?e*`Zn9k*n_ik2o!:<EQQhk&`/hk2qjK<J'A>*fnr,=FoUc
-k+:]>li5YgLXYejeHa-In)qLUg-U;~>
-#$LBV\^c7g\?#Zmri?>YRB/QPXK4P^X9aSiXK6YDXJA8`X8uIbri?)^rN$,hV5mp\JZOF(Su`.-
-map!Ee+*=c#KMJckJ6T@6@]~>
-#$LBV\D!1K\CppVrn7T>_V.`;g=f6ug'Fa+g=hm+g<`n"g&Z3$rn7?GrRqBSdFi`JJ_G\/T%XD.
-s5)Iaddm:h#Kq\dlFuc@6%A~>
-#$LBV\^d1Y\E3cfroOGNbiVdak2oM<jp8>Gk2r=Qk1j2?joK\@roO2WrT45ch;j$rJ`_OGT&p7C
-s4PqXe+*=c#KMJckJ6T@6@]~>
-#$LBV\^c7g\?#Zmri?>eXK4RcXK4P^X9aSiXK6YcXJA8`X8uIbri?)^rN$*r7@Qu%XF[IDX9Q9(
-f@>Z*nb^iAa+NjD_!p&EJ,~>
-#$LBV\D!1K\CppVrn7TNg=f9Sg=f6ug'Fa+g=hmRg<`n"g&Z3$rn7?GrRqA"=2eU!g4@tKg'6R:
-hV*_4o)%,GbCT*H^@9fAJ,~>
-#$LBV\^d1Y\E3cfroOG^k2oP&k2oM<jp8>Gk2r>&k1j2?joK\@roO2WrT449>gR)6k(2Zcjp(/O
-g!tl,nb^iAa+NjD_!p&EJ,~>
-#$LBV\^c7g\u[H_R5LD3Tf&XC2P7%<24:DEXJ0r?Suc^<XI),JXIW.:UTCOaR='ajWb45Tri?-4
-7tIamXJ2d#]'e2#LXYejeHa-In)qLUg-U;~>
-#$LBV\D!1K]%S^e_F)2lbX9b+7*4-!6c.C-g<H"%aP)H!g;$D3g;d`tcJ$uP_O[^\f7HH)rn7C(
->(PCYg7m:*ir@lhL=5Yig'>fPmcqOUfg1,~>
-#$LBV\^d1Y]&kR(bX]n:fLO`R8CZbF8'KoRk1QDKe)l^Fk0$TYk0e"Eg?.O$bbh`/j,$@KroO6;
-?\.?jk+^uBli5YgLXYejeHa-In)qLUg-U;~>
-#$LBV\^c7g\uYn*r_EckGYa*V:N*32:D]D"XF*f>B<5$-XD:UrXCG%%J?5i9:Mg$3!K::_X9+qC
->Cil,XJ2d#]'e2#LXYejeHa-In)qLUg-U;~>
-#$LBV\D!1K]%R/.raZ8VQt38,A<#.=A/E&8g7;bbKA($Mg5':Pg3mLBU>">5A;U<>!O?hHg&f;R
-F+N%rg7m:*ir@lhL=5Yig'>fPmcqOUfg1,~>
-#$LBV\^d1Y]&j"Erb;\gTk_!OC6[]VC)>(Uk+ug-MWShlk)X8sk(IJaX6/Q`C6AMX!PEaXjoWsl
-H@b40k+^uBli5YgLXYejeHa-In)qLUg-U;~>
-#$LBV\^c7gOfSVP=)\)>!g-Q_JZOF(U9"R1map!Ee+*=c#KMJckJ6T@6@]~>
-#$LBV\D!1KOkKlRDN4YL!k<-uJ_G\/U=oh2s5)Iaddm:h#Kq\dlFuc@6%A~>
-#$LBV\^d1YOlc_iFHujf!lB'<J`_OGU?2[Gs4PqXe+*=c#KMJckJ6T@6@]~>
-#$LBV\^c7gOfSV'='pN[JZPBC#.j6SeVDWDqpbqlKCA!=nCg3Z~>
-#$LBV\D!1KOkKksDKp`dJ_HXJ#3,[>g4n&Hqq;:uJaVg;nC^*X~>
-#$LBV\^d1YOlc_2FFSl(J``Kb#4)<BeVDWDqpbqlKCA!=nCg3Z~>
-#$LBV\^c7g\?#anMNNIkJZOF(orJA/map!Ee+*=c#KMJckJ6T@6@]~>
-#$LBV\D!1K\Cq"mY.&u9J_G\/p"BW0s5)Iaddm:h#Kq\dlFuc@6%A~>
-#$LBV\^d1Y\E3k.\AEgZJ`_OGp#ZJEs4PqXe+*=c#KMJckJ6T@6@]~>
-#$LBV\^c7g\Z>m`>@)7EX9+/PG(H`GXF[JQX9Q9(f@>Z*nb^iAa+NjD_!p&EJ,~>
-#$LBV\D!1K\_7.[FEic@g&e?bQ@[b@g4@uXg'6R:hV*_4o)%,GbCT*H^@9fAJ,~>
-#$LBV\^d1Y\`O!pH@D+TjoVr(Sq6$Tk(2[pjp(/Og!tl,nb^iAa+NjD_!p&EJ,~>
-#$LBV\^c7g\uZC"7;@FOXJ(5tSZJohNCs2O"."OjNW-![JqS]VJZOd2#.j6SeVDWDqpbqlKCA!=
-nCg3Z~>
-#$LBV\D!1K]%RY!=,3X$g<?Cia4f7pZX3Xb"2:V.Zi8YZV5JmuJ_H%9#3,[>g4n&Hqq;:uJaVg;
-nC^*X~>
-#$LBV\^d1Y]&jL6>`PuDk1Hi>dcT]J]jq'("3I^K]`.$oY-<K>J`_mQ#4)<BeVDWDqpbqlKCA!=
-nCg3Z~>
-#$LBV\^c7g\uZio2H+4^XB9(H;6-e"Sk?)cRTF*52QWuoAn>k2XF[I3X9Q9(f@>Z*nb^iAa+NjD
-_!p&EJ,~>
-#$LBV\D!1K]%S*g7;@D!g2DOnBA)"maBmTS`,:-W7,$@LJU`W0g4@t:g'6R:hV*_4o)%,GbCT*H
-^@9fAJ,~>
-#$LBV\^d1Y]&js'88j=;k&lK9D<9pBdpqP&cZFu!8ET&oLk_+Ek(2ZRjp(/Og!tl,nb^iAa+NjD
-_!p&EJ,~>
-#$LBV\^c7g\Z>g9NW-!pR<j00X/rCo9!#+\=*f1dXF!ZfH:WX=XF[I4X9Q9(f@>Z*nb^iAa+NjD
-_!p&EJ,~>
-#$LBV\D!1K\_7(+ZMrPn_OI#Rg"P0$?J=,JDk!6?g7)N?RTlV>g4@t;g'6R:hV*_4o)%,GbCT*H
-^@9fAJ,~>
-#$LBV\^d1Y\`Np=]`.%/bbV$qjlY^SA*2prFekhbk+lXcUL:6Uk(2ZSjp(/Og!tl,nb^iAa+NjD
-_!p&EJ,~>
-#$LBV\^c7g\Z>g9NW-!b<Gl\%X/rCo9)bmrN,EN?XE[;8D?-2XXF[I4X9Q9(f@>Z*nb^iAa+NjD
-_!p&EJ,~>
-#$LBV\D!1K\_7(+ZMrP`CQ"**g"P0$?N/X_Z&=Ncg6Z%CMZCbJg4@t;g'6R:hV*_4o)%,GbCT*H
-^@9fAJ,~>
-#$LBV\^d1Y\`Np=]`.%!EKcSCjlY^SA,bTp]9AG.k+H,]P5rs\k(2ZSjp(/Og!tl,nb^iAa+NjD
-_!p&EJ,~>
-#$LBV\^c7g\u[$)4^O5OXAa1L'o&fUBeaq8O$.Q*>cau8F)tWJXH`mKJZOF(OfSbumap!Ee+*=c
-#KMJckJ6T@6@]~>
-#$LBV\D!1K]%S:$9m=)#g1c[t)l_Q*Kg2'\[7udGFkYMrOcagpg:[TsJ_G\/OkL$!s5)Iaddm:h
-#Kq\dlFuc@6%A~>
-#$LBV\^d1Y]&k-9;16:Ck&6Z?*4+eKNC'E&^JUDeHfjFBR@/H;k/[Y?J`_OGOlcl6s4PqXe+*=c
-#KMJckJ6T@6@]~>
-#$LBV\^c7g\uZKqF`ihJXIaQhM287"F`i)5U],B9VuEdtFTm])X@YLKJZOF(OfSbumap!Ee+*=c
-#KMJckJ6T@6@]~>
-#$LBV\D!1K]%RalQ'Jl5g;oPYXfU6kQ'IoocMj(/eGe2%Pm+DGg0I@sJ_G\/OkL$!s5)Iaddm:h
-#Kq\dlFuc@6%A~>
-#$LBV\^d1Y]&jU,SXmX[k0om-\$kGASXlY?g&@NBi;Vm=SHZUek$h-?J`_OGOlcl6s4PqXe+*=c
-#KMJckJ6T@6@]~>
-#$LBV\^c7gS?)^&JZOF(O/rPsmap!Ee+*=c#KMJckJ6T@6@]~>
-#$LBV\D!1KSD!spJ_G\/O4jfts5)Iaddm:h#Kq\dlFuc@6%A~>
-#$LBV\^d1YSE9g.J`_OGO6-Z4s4PqXe+*=c#KMJckJ6T@6@]~>
-#$LBV\^c7gJZOF(JZPiP#.j6SeVDWDqpbqlKCA!=nCg3Z~>
-#$LBV\D!1KJ_G\/J_I*W#3,[>g4n&Hqq;:uJaVg;nC^*X~>
-#$LBV\^d1YJ`_OGJ``ro#4)<BeVDWDqpbqlKCA!=nCg3Z~>
-#$LBV\^c7g\uZgF@q1@sXI<X/P,taH@q2%1XG14pVQ?kI@qU@oJZOd2#.j6SeVDWDqpbqlKCA!=
-nCg3Z~>
-#$LBV\D!1K]%S(KIX\EQg;AAg]%YlHIX];jg8]UNdb<EHIY*.)J_H%9#3,[>g4n&Hqq;:uJaVg;
-nC^*X~>
-#$LBV\^d1Y]&jpbKn["uk08U6`9-3tKn[q:k-ThrhWEsuKo(BCJ`_mQ#4)<BeVDWDqpbqlKCA!=
-nCg3Z~>
-#$LBV\^c7g\uZiWKS3?oXA";#8?8X^KS3($Pur]m;QPO^KRd<YXF[I3X9Q9(f@>Z*nb^iAa+NjD
-_!p&EJ,~>
-#$LBV\D!1K]%S*IW2OLLg0gkX>hRS6W2O1Z]l0jJB\KA6W1nBbg4@t:g'6R:hV*_4o)%,GbCT*H
-^@9fAJ,~>
-#$LBV\^d1Y]&jr\Z*A;ok%1g&@HHBXZ*@s(aEFhnDW\0XZ)`5&k(2ZRjp(/Og!tl,nb^iAa+NjD
-_!p&EJ,~>
-#$LBV\^c7g\#^EGPcR!KX?EV\6`d@OXH$GbX?<S/E3,j'JZOF(N3!5pmap!Ee+*=c#KMJckJ6T@
-6@]~>
-#$LBV\D!1K\(V[6]\6'5g.g8J<8-&"g9bkRg.^4eNnVi\J_G\/N7nKqs5)Iaddm:h#Kq\dlFuc@
-6%A~>
-#$LBV\^d1Y\)nNH`o^+[k#(6r=m"jCk.Z*&k"t35QKHt,J`_OGN91?1s4PqXe+*=c#KMJckJ6T@
-6@]~>
-#$LBV\^c7g\Z?]n4BJ>[4KPVIX//1bX?<SE=fe\eXE\]cUdTd8JZOg3#.j6SeVDWDqpbqlKCA!=
-nCg3Z~>
-#$LBV\D!1K\_7sg9Q&529\S2pg!NdQg.^5-ESB,?g6[iRcrP_OJ_H(:#3,[>g4n&Hqq;:uJaVg;
-nC^*X~>
-#$LBV\^d1Y\`Og':itIS;!-n;jkX)%k"t3SGin-bk+J%&gfo?lJ`_pR#4)<BeVDWDqpbqlKCA!=
-nCg3Z~>
-#$LBV\^c7g\#^EGPcR!KX?EV\6`d@OXH$GbX?<S/E3,j'JZOF(N3!5pmap!Ee+*=c#KMJckJ6T@
-6@]~>
-#$LBV\D!1K\(V[6]\6'5g.g8J<8-&"g9bkRg.^4eNnVi\J_G\/N7nKqs5)Iaddm:h#Kq\dlFuc@
-6%A~>
-#$LBV\^d1Y\)nNH`o^+[k#(6r=m"jCk.Z*&k"t35QKHt,J`_OGN91?1s4PqXe+*=c#KMJckJ6T@
-6@]~>
-#$LBV\^c7g\u[$>XK5BcX?<Sc4fbDHXK4OcN`iHb4KNdHXJA7cXJ^lOJZOF(OfSbumap!Ee+*=c
-#KMJckJ6T@6@]~>
-#$LBV\D!1K]%S:?g=g;Sg.^5S:"dong=f6SZuOgR9\Phng<`mSg=37QJ_G\/OkL$!s5)Iaddm:h
-#Kq\dlFuc@6%A~>
-#$LBV\^d1Y]&k-Uk2pX&k"t4&;<?V:k2oM&^3Jf&;!+F:k1j2'k2<])J`_OGOlcl6s4PqXe+*=c
-#KMJckJ6T@6@]~>
-#$LBV\^c7g\u[#m9heZ^XC=mu=feT)9hf3#T2nZ\EibO)9hg)<XH`dHJZOF(OfSbumap!Ee+*=c
-#KMJckJ6T@6@]~>
-#$LBV\D!1K]%S9c@:=#tg3d=;ES8o^@:=]?a_bHpOP7?]@:Gk_g:[KoJ_G\/OkL$!s5)Iaddm:h
-#Kq\dlFuc@6%A~>
-#$LBV\^d1Y]&k-"AnH,:k(@8XGNIh-AnHh\e8f/5R-)G-An\.*k/RJ:J`_OGOlcl6s4PqXe+*=c
-#KMJckJ6T@6@]~>
-#$LBV\^c7g\uZgMS"$4TXJhVXVQ?krS"$@XXJ;8SX/rCrS"0JZ!]=DcJZOF(OfSbumap!Ee+*=c
-#KMJckJ6T@6@]~>
-#$LBV\D!1K]%S(S`Pp3Xg==0]e(WO(`PpB]g<[aWf\5''`Q%o2!^qCdJ_G\/OkL$!s5)Iaddm:h
-#Kq\dlFuc@6%A~>
-#$LBV\^d1Y]&jpkd*UP0k2=V5hWEtVd*Ub6k1\2/jQ>UVd*_jT!_7k%J`_OGOlcl6s4PqXe+*=c
-#KMJckJ6T@6@]~>
-#$LBV\^c7gS?)^?JZOF(O/rPsmap!Ee+*=c#KMJckJ6T@6@]~>
-#$LBV\D!1KSD!t:J_G\/O4jfts5)Iaddm:h#Kq\dlFuc@6%A~>
-#$LBV\^d1YSE9gOJ`_OGO6-Z4s4PqXe+*=c#KMJckJ6T@6@]~>
-#$LBV\^c7gJZOF(JZPiP#.j6SeVDWDqpbqlKCA!=nCg3Z~>
-#$LBV\D!1KJ_G\/J_I*W#3,[>g4n&Hqq;:uJaVg;nC^*X~>
-#$LBV\^d1YJ`_OGJ``ro#4)<BeVDWDqpbqlKCA!=nCg3Z~>
-#$LBV\^c7g\uZgB4[!tiXH5S.KrhA,4[#%2XE$HeU9(G,4[O_$JZOd2#.j6SeVDWDqpbqlKCA!=
-nCg3Z~>
-#$LBV\D!1K]%S(E:/7,/g9saOW7ot$:/8FTg6#-*cJ%!$:/leuJ_H%9#3,[>g4n&Hqq;:uJaVg;
-nC^*X~>
-#$LBV\^d1Y]&jp\;Gs+Kk.jkmZKC;O;GtKrk*]+Fg#hFN;H\S5J`_mQ#4)<BeVDWDqpbqlKCA!=
-nCg3Z~>
-#$LBV\^c7g\uZi\X/f3aX?<Pa4fbDHX/eCbO'/Na4fimIX.r+7XF[I3X9Q9(f@>Z*nb^iAa+NjD
-_!p&EJ,~>
-#$LBV\D!1K]%S*Of[srOg.g5P:>+&qf[rpP[;jjO:"ktpfZmQLg4@t:g'6R:hV*_4o)%,GbCT*H
-^@9fAJ,~>
-#$LBV\^d1Y]&jrbjQ(:"k#(4#;WZ_<jQ'2#^Nei#;<FO;jP!jik(2ZRjp(/Og!tl,nb^iAa+NjD
-_!p&EJ,~>
-#$LBV\^c7g\Z?^KVGrh^4KPVIX//1bX?<SE=fe\eXE\]cUdTd8JZOg3#.j6SeVDWDqpbqlKCA!=
-nCg3Z~>
-#$LBV\D!1K\_7tQdV?JL9\S2pg!NdQg.^5-ESB,?g6[iRcrP_OJ_H(:#3,[>g4n&Hqq;:uJaVg;
-nC^*X~>
-#$LBV\^d1Y\`OgihJgNt;!-n;jkX)%k"t3SGin-bk+J%&gfo?lJ`_pR#4)<BeVDWDqpbqlKCA!=
-nCg3Z~>
-#$LBV\^c7g\Z?]q6<Bq`4KPVIX//1bX?<SE=fe\eXE\]cUdTd8JZOg3#.j6SeVDWDqpbqlKCA!=
-nCg3Z~>
-#$LBV\D!1K\_7sk<,U"89\S2pg!NdQg.^5-ESB,?g6[iRcrP_OJ_H(:#3,[>g4n&Hqq;:uJaVg;
-nC^*X~>
-#$LBV\^d1Y\`Og*=EN9Z;!-n;jkX)%k"t3SGin-bk+J%&gfo?lJ`_pR#4)<BeVDWDqpbqlKCA!=
-nCg3Z~>
-#$LBV\^c7g\#^EGPcR!KX?EV\6`d@OXH$GbX?<S/E3,j'JZOF(N3!5pmap!Ee+*=c#KMJckJ6T@
-6@]~>
-#$LBV\D!1K\(V[6]\6'5g.g8J<8-&"g9bkRg.^4eNnVi\J_G\/N7nKqs5)Iaddm:h#Kq\dlFuc@
-6%A~>
-#$LBV\^d1Y\)nNH`o^+[k#(6r=m"jCk.Z*&k"t35QKHt,J`_OGN91?1s4PqXe+*=c#KMJckJ6T@
-6@]~>
-#$LBV\^c7g\u[$%XK5BcX?<Sc4fbDHXK4OcN`iHb4KNdHXJA7cXJ00sJZOF(OfSbumap!Ee+*=c
-#KMJckJ6T@6@]~>
-#$LBV\D!1K]%S9tg=g;Sg.^5S:"dong=f6SZuOgR9\Phng<`mSg<G&gJ_G\/OkL$!s5)Iaddm:h
-#Kq\dlFuc@6%A~>
-#$LBV\^d1Y]&k-4k2pX&k"t4&;<?V:k2oM&^3Jf&;!+F:k1j2'k1PF<J`_OGOlcl6s4PqXe+*=c
-#KMJckJ6T@6@]~>
-#$LBV\^c7g\u[$.4?R)NXEH]gCTOOM4?RqkV-c>IM6*@M4?o+4XG7.GJZOF(OfSbumap!Ee+*=c
-#KMJckJ6T@6@]~>
-#$LBV\D!1K]%S:+9MBi_g6PE+Lt^L89MCr0dWnM[Y1h'89MiCUg8b[oJ_G\/OkL$!s5)Iaddm:h
-#Kq\dlFuc@6%A~>
-#$LBV\^d1Y]&k-@:f)f%k+5CGOQPV_:f*qLh1&6t\)u7^:fYQuk-PW:J`_OGOlcl6s4PqXe+*=c
-#KMJckJ6T@6@]~>
-#$LBV\^c7gS?)`FI=\JNXH9Lf]'e2#LXYejeHa-In)qLUg-U;~>
-#$LBV\D!1KSD"!+Sq5UHg5t"mir@lhL=5Yig'>fPmcqOUfg1,~>
-#$LBV\^d1YSE9i;Vh*u]k)e^0li5YgLXYejeHa-In)qLUg-U;~>
-#$LBV\^c7gS?)^XJZOF(O/rPsmap!Ee+*=c#KMJckJ6T@6@]~>
-#$LBV\D!1KSD!tYJ_G\/O4jfts5)Iaddm:h#Kq\dlFuc@6%A~>
-#$LBV\^d1YSE9gpJ`_OGO6-Z4s4PqXe+*=c#KMJckJ6T@6@]~>
-#$LBV\^c7gJZOF(JZPiP#.j6SeVDWDqpbqlKCA!=nCg3Z~>
-#$LBV\D!1KJ_G\/J_I*W#3,[>g4n&Hqq;:uJaVg;nC^*X~>
-#$LBV\^d1YJ`_OGJ``ro#4)<BeVDWDqpbqlKCA!=nCg3Z~>
-#$LBV\^c7gZ`FY&20Z.!,s4:FXHG%q4@/tJ!Gs:]X9t:\4B%oSN]]F0V#%.pE'-7)JZOF(WN6<8
-map!Ee+*=c#KMJckJ6T@6@]~>
-#$LBV\D!1KZe>o'6^QNU02,&)g:B199N1rE!K&`0g'YVp9PV`(ZqO/:d/)GuO%`62J_G\/WS.R9
-s5)Iaddm:h#Kq\dlFuc@6%A~>
-#$LBV\^d1YZfVb>7\Jo#1/Le7k/98V:fmYY!KoD;jpK75:iOtI^/.XSh"p.8Q;CDIJ`_OGWTFEN
-s4PqXe+*=c#KMJckJ6T@6@]~>
-#$LBV\^c7g\#^3g@'$FtE,VhWI]TV5XIk<MX??K`s#g+Y$;-nkG&aU1XK5fcqQ'oaXK4OcU.gu+
-XF[ITX9Q9(f@>Z*nb^iAa+NjD_!p&EJ,~>
-#$LBV\D!1K\(VIaH.ptRNfDcDTA&!mg<-MNg._M"s%N7B$=:g-QB9gjg=ghSqUu0Jg=f6Sc!\A=
-g4@t[g'6R:hV*_4o)%,GbCT*H^@9fAJ,~>
-#$LBV\^d1Y\)n=!JEGuuQBgUlW935=k1-p&k"u'>s%rOR$=hQISs\Z9k2q3&qW8#Zk2oM&fk&BY
-k(2Zsjp(/Og!tl,nb^iAa+NjD_!p&EJ,~>
-#$LBV\^c7g\uZ49J4OOMXFt,/DuHa<Bn-)_##phgX@ApHq5ap5H%9LXXK7k@>E\ia#s>;j4KPQQ
-:L8j.XF[IVX9Q9(f@>Z*nb^iAa+NjD_!p&EJ,~>
-#$LBV\D!1K]%RJ>U0NW!g8KLgNW%Q3KVA@u#&:g)g0)Zoq:Z1)RA,8-g=jK>F1D)##u'(,9\S.=
-A9Y/,g4@t]g'6R:hV*_4o)%,GbCT*H^@9fAJ,~>
-#$LBV\^d1Y]&j=VX'q1Ak-9Z6Q2ThGN2lj=#&qTEk$H\:q;r$;U8s*Ok2ssiH,KL@#uKdH;!-id
-C43OAk(2Zujp(/Og!tl,nb^iAa+NjD_!p&EJ,~>
-#$LBV\^c7g\uYs@BV>@+"':V1DuHa<@YXi_#"tMgN*NGHq5apCAS>A+XK7Ot=I/fb"$EZd4T2>_
-MICm`XF[IWX9Q9(f@>Z*nb^iAa+NjD_!p&EJ,~>
-#$LBV\D!1K]%R43KZa;J")bW:NW%Q3I&d/!#%,F)Z?4eoq:Z1:J:r*Jg=j&iE528'"&.G&9`<ZH
-YBugkg4@t^g'6R:hV*_4o)%,GbCT*H^@9fAJ,~>
-#$LBV\^d1Y]&j'EMq.gh"*DDRQ2ThGK<tO=#%Z0E]R/d;q;r$NLPpPhk2sO=G00UC"&S.B;#TMX
-\Up]0k(2[!jp(/Og!tl,nb^iAa+NjD_!p&EJ,~>
-#$LBV\^c7g\uZ4+4Dg:`X=nft:B%<rSkH*_X9aYjX/pP@GUe^LX9;.eXEJU^X8u^bqQ'c]XK4P`
-X94)Y:oJrHJZQ)W#.j6SeVDWDqpbqlKCA!=nCg3Z~>
-#$LBV\D!1K]%RJ-9T$F8g,k[;@fG'_a^<^"g'Fg,g"Md&Qo22Gg&ta'g6Rj!g&ZK$qUu$Fg=f7"
-g&n0lA^u@cJ_I?^#3,[>g4n&Hqq;:uJaVg;nC^*X~>
-#$LBV\^d1Y]&j=D:m/cZk!#JYB`@,qe7I_?jp8GHjlW4MTfB^]jof2Ck+7t=joL"@qW7lVk2oM>
-jo_f4CZ0j,J`a3!#4)<BeVDWDqpbqlKCA!=nCg3Z~>
-#$LBV\^c7g\?#p^<E-&BE)&t'X9"nbrN%&q@B?Q!E,[1[XK7sTRB3J^Sud*TXCJ?5@#1ncE)ut>
-#X#2i4KP2<AWH_j!CVNjXF[I[X9Q9(f@>Z*nb^iAa+NjD_!p&EJ,~>
-#$LBV\D!1K\Cq1XChh[hNal>ng&]9$rRr<nHeR2kNfGiqg=jS@_V3^MaP)rAg4%c0H*,fSO)=mM
-#Y`t+9\RZ`J@#4.!EQ%Jg4@tbg'6R:hV*_4o)%,GbCT*H^@9fAJ,~>
-#$LBV\^d1Y\E4$lEcC03Q"a\[email protected]')4?Q'F26k2t)hc0".ue)m6hk(Vs[J@=V&Q?3&f
-#Z0[G;!-A,LqWcL!F)^Xk(2[%jp(/Og!tl,nb^iAa+NjD_!p&EJ,~>
-#$LBV\^c7gZE+6r4KGQbUMTn1!L.s0X9XGABWS;+4.6)L#Xpj_XK89]4Dt/"!H;'<X948@4H'$:
-!f7bGJZOF([&aJCmap!Ee+*=c#KMJckJ6T@6@]~>
-#$LBV\D!1KZJ#L]9\J.RcADMR!P=m#g'=QMK\G/#9>^\^#Zj]Eg=jtK9T/o(!KM!qg'4WP9X3=*
-g&0P*XrjKkg4@tbg'6R:hV*_4o)%,GbCT*H^@9fAJ,~>
-#$LBV\^d1YZK;?m;!$j%foZ0p!QCl5jp/1gMrs0M:X&h##[C2Uk2tMs:m1h?!L@d*jp&7j:qGfO
-jo"6B\0.r*k(2[%jp(/Og!tl,nb^iAa+NjD_!p&EJ,~>
-#$LBV\^c7gJZS[K!DIrnXF[IZX9Q9(f@>Z*nb^iAa+NjD_!p&EJ,~>
-#$LBV\D!1KJ_KqR!FVROg4@tag'6R:hV*_4o)%,GbCT*H^@9fAJ,~>
-#$LBV\^d1YJ`cdj!G/6]k(2[$jp(/Og!tl,nb^iAa+NjD_!p&EJ,~>
-#$LBV\^c7gJZOF(JZPiP#.j6SeVDWDqpbqlKCA!=nCg3Z~>
-#$LBV\D!1KJ_G\/J_I*W#3,[>g4n&Hqq;:uJaVg;nC^*X~>
-#$LBV\^d1YJ`_OGJ``ro#4)<BeVDWDqpbqlKCA!=nCg3Z~>
-#$LBV\^c7g\?#_2V7ir2VPrFS"0%i^VYR:rV4aokV#HndVlZWlSH,YgX9"rjq5a[pSXleVX9,)d
-TD5JhSt2YTX9YDpXK8@kSYu:b!Ml`HXL,&5]'e2#LXYejeHa-In)qLUg-U;~>
-#$LBV\D!1K\Cpu8dCn67dam@1"4kN5e+q]#dE:1sci1rdeCr1H`rO]ig&]@Eq:Yr!a2cg-g&fO>
-anXQkaN)U)g'>gKg=k)ta4'k<!RTGLg9fQ<ir@lhL=5Yig'>fPmcqOUfg1,~>
-#$LBV\^d1Y\E3hPgqDhNhVmDT"6.bWhYH::h:C`Ng]#V&hr`SjdK&;+joO#hq;qe8daI1OjoX2`
-eG//-e'ctKjp0Jmk2tXNdbjl_!Sl^dk-X7Tli5YgLXYejeHa-In)qLUg-U;~>
-#$LBV\^c7g\?#^HII4*;HXW3,X9"oLlDt"tKDqqPHhONDM3<XqKDo9ZOnc![B1kmOqQ(C*="CAR
-912E0END)l9.G^uXG&fHqQ'gr=%c2&qQ'g^;+jW9qQ(6V91r3MXK7:H=0/K691rEgqQ'^DD1Sdq
-X9Q9(f@>Z*nb^iAa+NjD_!p&EJ,~>
-#$LBV\D!1K\Cpt>T'b55S9qs:g&]9tlIl8hVZ,9LSG(Y>Y.:UeVZ(oB\G4b[JmVlaqUuY/DDp5&
-?WUT$O4m'1?T"q=g8I_oqUu)"DdQk-qUu(^B4#,FqUuLP?XIN^g=i`2DVEfn?XIg+qUtt>Mh0Th
-g'6R:hV*_4o)%,GbCT*H^@9fAJ,~>
-#$LBV\^d1Y\E3gQVsWUJV1QeUjoNu@lK/,&YQ!YaV=s$S\AP`:YPs+R_YE6qM.C/&qW8LFF?/LG
-A6WS5Qf^nNA2q!Zk-7d:qW7q9F_#$EqW7ptD.I:_qW8?eARo`%k2s0WFQV_>A7ToFqW7gSP(Dc&
-jp(/Og!tl,nb^iAa+NjD_!p&EJ,~>
-#$LBV\^c7g\?#Zmri@*:QBn>JSXu@;VlZ>\R?jkSXHZh3XK%SSXI5BRqlC+)QBn2FXF=!3U\Lo(
-R[0nRVj<jEQDL[QL7YKJTer()poG07E*'--08G<RX/rCmQD^g_Q8Fnsri@!5P!"c+MI&EHXI#of
-E-SIKXK#TcXJf$<@f!//Rn]uc4Sl,^D0i:P:AV%+:8t=2I&s>PFB>QF9!#*YWMr".TDbhk4FsT@
-X9Q9(f@>Z*nb^iAa+NjD_!p&EJ,~>
-#$LBV\D!1K\CppVrn8@@^:qtJ`lZ36eCqga_7nRUg:M9jg=O'Tg;:STqq;A0^:qbDg7MrjcM6*,
-_nO^Ue%WiC^<tZSWlWoJbX0%^pt?F)Nc3Xe40,Def\5&u^=:le^-]QQrn87:\P0EbYBN[og:u4m
-NLAM4g=LPSg=9l"IJVY#`F7KS9`!HGMjrG<A,=mnA(K@jS_D\;P]#4/?J=+/f@EWeb5L#o9S(p)
-g'6R:hV*_4o)%,GbCT*H^@9fAJ,~>
-#$LBV\^d1Y\E3cfroP3WaN3,udF?Oahr`29bfJi,k/DJ9k2XP,k0;!,qrS4GaN2ook,<(:g%a\C
-cH+u,hoO0naP>q)Zd\(!f1*j-puW9;Q?D?45I@e+jQ>UOaPZ.=a@=7troP*R_be,1\U@<:k/u]G
-Q(d?Zk2Um%k2C3HK_jg6ctDM';#9;WP,.6cB_pj*B]A0:V<6faS93oUAEN#Rio3e4ec"V1:k@c9
-jp(/Og!tl,nb^iAa+NjD_!p&EJ,~>
-#$LBV\^c7g\?#Zmri?W<;GpStCEleVA#rW_;c7Q5X9iijXJ@ICXA^XCqlC*E;GpPbXAUTILA@nb
-LK%/bXHt,CF<-FDCbULCXFD6gB_e_JU+eV\TWC8WX?NYcNDrebXIW60;JE56G?7iEX9(Mc4T)8\
-4T2>dS4p#cNE_*GqQ'gh9rtEYqQ'g:HE<Q1poF_#=-K_R:Q\`WX9XtiX/rC<<Fc$0!'Gh6[&aJC
-map!Ee+*=c#KMJckJ6T@6@]~>
-#$LBV\D!1K\CppVrn7m.BP;;:LFd4SIG/EtC1rS*g'Ne,g<_oig1`Liqq;@<BP;5#g1WHZWqk?_
-X(l=$g:o.hP9dQiLcqWhg7]d*K_a=?c94c\bM#YDg.p;SZ>4-$g;dkPBSG0oQ>UR=g&at%9`3TE
-9`<ZM`aINSZZE*oqUu(k@G9F/qUu(1S(bbipt>u*DS"Q=A@QOUg'>9,f\5&8CjuB;!).st[+Y`D
-s5)Iaddm:h#Kq\dlFuc@6%A~>
-#$LBV\^d1Y\E3cfroO`ADJjRXO"PEiK][5;Df1g=jp@?Hk1`(4k&3<4qrS3PDJjL@k&!1tZh`_t
-ZuBo@k/o<4RjPo4O?p)4k,KbGMtuKRfg&:qf&ffkk#1:&]Q%hAk0e,oDN3f@T655SjoSBA;#KGU
-;#TM]d:MJ&]m6o:qW7q-BBJ>QqW7pDUuos9puVhBFN!=dC;P)kjp/nHjQ>TcEeXMT!)S7/[,qSY
-s4PqXe+*=c#KMJckJ6T@6@]~>
-#$LBV\^c7g\Z>gUEW3$YOcGGWX/.bNXG1/D8uSh4FKDQ_Gc[uaHE;U1qQ'pgNfHnkXGgEZX9tLc
-LlQ%^XIE<qQN!rdAV9u`!'L"W';[f_3MWZ4NcoEDV`fcpD.0NI4T;D`MI)#9X93?cX??H_!Lcd^
-X9XYgXK5$cKjsn["Ii,eX???\"DrIdRSN[[#bkFhXK5*cO]VO`!h*8crN$3eC2g8UDL-l8[B'SD
-map!Ee+*=c#KMJckJ6T@6@]~>
-#$LBV\D!1K\_7(NO8diP\?rV.g!N:9g8]P-?IdbmPhOiOR+g8PS(aQiqUu1h['XAGg9Phqg'Yl#
-XL*M5g;IrO^AcgeJ>W>"!)3.@'@BKZ8C-!V[$?^+e5!$NML4(29`E`IYBQrEg&m;&g._J!!Q/FG
-g'=m*g=flSWI=Ws"N=g'g._@s"H/c'_diMr#gRD+g=frS\8M<"!lK!$rRqIeL5t!AMjo:O[FtiE
-s5)Iaddm:h#Kq\dlFuc@6%A~>
-#$LBV\^d1Y\`NpcQN$"c_S3`OjkWP`k-T`SA)ZR=SEAt"T]YC#UZSS8qW8%*^:n<ik.?!8jpKO?
-[_@NXk0J3raSt<&LTg^>!)WFP'AZJo9\\]!^7L\Ri)6nqOb)ZW;#]SY\UCa^jo^jBk"u$=!R5?W
-jp/JFk2p1&Z@r):"OLfDk"tp:"HoSCc=m%9#haCGk2p:&_K>e>!mYu@rT4=&NgAhiPG<]k[H7\Z
-s4PqXe+*=c#KMJckJ6T@6@]~>
-#$LBV\^c7g\?#Zmri?f>>$<&LV*h>cQ;W`GXK6ncXK6Acri?/`X??<[#AmXJ15N#j>kkB$ROS5>
-"bs+[>#hU%X8umbri?)^pT+dt0KUn[X=%1RN3&m#r`TDTXK4P_X9j)P<iiB35Z/VRri?,fV>[Iq
-4T;Db/5e_dV>I=sRn]uc4Sl,^D0i:P:ALsl=-<K`#Vo:H.A*]-=/Z"u!c(eHri?)^JZQ5[#.j6S
-eVDWDqpbqlKCA!=nCg3Z~>
-#$LBV\D!1K\CppVrn8'/EcNS]d8\iR^1alng=i6Sg=hRSrn7EIg._=r#E!PB5HWYFFSOPj`&%C5
-"fg;1F)9J-g&Z`$rn7?GpY$&$4\@cYg+m\eZ.dYXrc/+9g=f7!g'O*aD;*]k;.q5Mrn7BQdJ_c!
-9`E`K2eZ&NdJMW#`F7KS9`!HGMjrG<A,4gZDRf]"#X<!)1s+IcDUeX=!f(T@rn7?GJ_IKb#3,[>
-g4n&Hqq;:uJaVg;nC^*X~>
-#$LBV\^d1Y\E3cfroOoBG^(_"h-&n&a_eb:k2r\&k2qu&roO8Yk"tm9#Ej=V6al-hHhc_(c8PZH
-"gd@RH#hsEjoL7@roO2WpZ;n;5YaJnju%C+]B7s&rceOHk2oM=jp@Z&F6;V:<c07croO5bh#6@8
-;#]S[3c7q^h#$4:ctDM';#9;WP,.6cB_gckFMe%>#X`K82q7!3FPm&Z!fqAUroO2WJ`a?%#4)<B
-eVDWDqpbqlKCA!=nCg3Z~>
-#$LBV\^c7g\?#Zmri@#2L2[lkV&+3-=J1ZrI>1q#XHQ^lQ)q'I.YRW!$;uV.+`ONH=b^.VqlC^9
-D0L_ZGb[]SL-;32O\]SVXK5-NFFL<mH5ca`'O5TYXHtT2V-K1aF)m"`EMeIDL8k0R#c*VGNhVhm
--]e8.!CN^^X8kB^X:Lbc>X53gX@Z*eXIi@EL/.`L,U%92XF"]:Ht'1YNu"4dXA3nm?%T/IQ=`+O
-X?:oc5H:\FI@pJ>!'L1\!>p69XLkP<]'e2#LXYejeHa-In)qLUg-U;~>
-#$LBV\D!1K\CppVrn88tWfA%0d2e@LDp,L8SuQhWg:M9I^"V2J25g9($>HN6.ZW5oEN4-,qq;t?
-MO1?1REns)W_LXi\7C3,g=g#9PG$X`Rj%aa'QoFSg;#ejdWN+RP*)c:O4($iWn.1'#gg+U[EcLa
-0t.)8!EIPGg&OhGg(2*8FA^QAg0J+?g<!s,Wal%^,V"u2g73quSUK5G[2d0>g1$>IG,<p3^4Ai$
-g.\-=:tO8lT$%#c!)3=E!?Rkag:Q&Cir@lhL=5Yig'>fPmcqOUfg1,~>
-#$LBV\^d1Y\E3cfroP,0[$D]Mh&i&lFk48VVmL^&k/DIka6)O!33i;A$?!5N/=#A:GI2\NqrSgW
-P+]1UU"WbIZr,E:_J+kMk2p<`S#PQ4Ua,j#'RQ-gk/op:h0[*%R[LO\Qeo)6[,M#H#i*<o^Y-]4
-1r0+Q!F":WjoA6Wjq#_XHWK(ek$hoak1"4SZt]O%,V5GIk,"*FVM+*o^E1bak%L<mI'2VXaG<LC
-k"r"`<9)t7Vq(b.!)WUU!?e:kk.Ba[li5YgLXYejeHa-In)qLUg-U;~>
-#$LBV\^c7g\?#Zmri@$+@X*9IV*fB7S?.`RCLX-AXF"DcJ#o`D<hK2h$)h<IMeoJrKOTr9X:oP^
-E3,L;G(!haXES,_KWM8G@W_UN!Ad.BX:U5OLTH,;Ni]=/XK6SSCTO3.@K<8"X9+2eM#OIVJ#WCJ
-!.4XF#&@\FXK6brri?3[@Uc#0X8usqri?0F@VPhC"eK2!XK6jL@K;boX9<KOTr_u-@K<J)X8kB]
-X9*5_Q%?$KX9Q9(f@>Z*nb^iAa+NjD_!p&EJ,~>
-#$LBV\D!1K\CppVrn8:-I$gIpd8ZBY`S.\=Lj[Y)g73P<U"\5BCs)S-$.XEWY_h)fW-koGg(TNp
-NnVF!QCiQ:g6R,6VqTkFI$=Q`!C9fcg(:EtXP0P![+a6(g=hg>LYBoMHiVRhg&eC(Xo@#TT[s(q
-!1`u@#)@TSg=i'frn7IYI!j-:g&Zi7rn7F?I"hRR"iu)<g=i1uHiUq\g'!F`bh@dMHiVjqg&OhF
-g&d0_]ReeKg'6R:hV*_4o)%,GbCT*H^@9fAJ,~>
-#$LBV\^d1Y\E3cfroP-DJtT!;h-$;#d,r&eOFl<Nk,!Z]WoiHnEn1!J$/pJp\rc(:Z%BX`jqF&4
-QKHMFSu71Zk+@6WYib)rJt)c%!C^5kjq,&?[H=ZE^?4RSk2r4dO65!lJcOX%joVuC[f5CiWT*m=
-!2]VU#*4Amk2rJ:roO<oJqDSQjoL@TroO9SJrTcl"k/(Xk2rT@JcNsmjoh!%fB/(lJcOm-joA6V
-joU\ta+<Bbjp(/Og!tl,nb^iAa+NjD_!p&EJ,~>
-#$LBV\^c7g\?#^mFo&0@LbXP]X9*B.M>4.UQu5'_XJ5WB!0?iT!0I,.!28YY!EH%^X9!C+rN$$(
-Tn0;VX9Q9(f@>Z*nb^iAa+NjD_!p&EJ,~>
-#$LBV\D!1K\CptlQ2929X?NK[g&d=7Xn^TR_2D%7g<KPh!4DOS!4Mg!!6j]]!Gg2Lg&[AJrRq9n
-b^nKZg'6R:hV*_4o)%,GbCT*H^@9fAJ,~>
-#$LBV\^d1Y\E3h-SbhIM[R.1sjoUlO\+o(hbEGiZk1T[3!5J6i!5SN3!8$Jt!HI%^joLphrT4-+
-fR`1rjp(/Og!tl,nb^iAa+NjD_!p&EJ,~>
-#$LBV\^c7gYH.eSBlF!P!d/4%poFX[Bka9BSc!1%JbH/FK)B<_S:RbmXK/E,]'e2#LXYejeHa-I
-n)qLUg-U;~>
-#$LBV\D!1KYM'&MKoH#b!gJD+pt>nZKn[b)a8CVkU\<CAV>Q#I`IZ`og8ip3ir@lhL=5Yig'>fP
-mcqOUfg1,~>
-#$LBV\^d1YYN>nbNKjG)!h>7CpuVapNK)QPdeo()XS1cVY5F7Zd"1>1k,[VKli5YgLXYejeHa-I
-n)qLUg-U;~>
-#$LBV\^c7gJZOF(JZPiP#.j6SeVDWDqpbqlKCA!=nCg3Z~>
-#$LBV\D!1KJ_G\/J_I*W#3,[>g4n&Hqq;:uJaVg;nC^*X~>
-#$LBV\^d1YJ`_OGJ``ro#4)<BeVDWDqpbqlKCA!=nCg3Z~>
-#$LBV\^c7gOfSS\BS!79XIH9q]'e2#LXYejeHa-In)qLUg-U;~>
-#$LBV\D!1KOkKibKRqj.g7-e#ir@lhL=5Yig'>fPmcqOUfg1,~>
-#$LBV\^d1YOlc]$N.L,Bk*tK;li5YgLXYejeHa-In)qLUg-U;~>
-#$LBV\^c7g];ud2GE@-1I&sE*DjRQ,Q#DP.N3&"WDl<T9#B+XIS?.*VHMOWEHnB8ori?BaDj#g/
-K7n03JZOF(WN6<8map!Ee+*=c#KMJckJ6T@6@]~>
-#$LBV\D!1K]@n%2QaW?hS_Df!NPF3$]T'(cZJ)UDNRRm\#E=kY`nI#DS,(b?SN2\5rn7X_NOl'g
-VPfElJ_G\/WS.R9s5)Iaddm:h#Kq\dlFuc@6%A~>
-#$LBV\^d1Y]B0mIT>726VWR$KQ-&1Na-F04]]QklQ/DT'#F1^sdH7<kV"s-TV*($RroOKuQ,Kr7
-YHX;<J`_OGWTFENs4PqXe+*=c#KMJckJ6T@6@]~>
-#$LBV\^c7g]<!6C,?Q'm26;[CGYt?4;g;UhOdTEuGZh,I@!Hi?Is,UPDKDlUX:Tq:G`Sr-P$E63
-1lN5]GZ1MkXF[IQX9Q9(f@>Z*nb^iAa+NjD_!p&EJ,~>
-#$LBV\D!1K]@nLD/9!"Y6e\_iR:jsnC708k\AE?UR;ps4HC:$NTpCM&Mil]ig(:&CRC:i'\TO<V
-6*VG[R;16&g4@tXg'6R:hV*_4o)%,GbCT*H^@9fAJ,~>
-#$LBV\^d1Y]B1?[/p8ak8*7@5Tl&Z>DkVV,_T[>"Tm,YZJ>&MgWh,<GPF:P0jq+X[TtogQ_gA(t
-7CsUqTlAn?k(2Zpjp(/Og!tl,nb^iAa+NjD_!p&EJ,~>
-#$LBV\^c7g\uZ)uX?<RHX=O9`s#g:^%QphoM.gQ\XE\]cXFl*tri?,tQM[`aUIG-_!'L7^#&()#
-XK8-cJZOF(WiQE9map!Ee+*=c#KMJckJ6T@6@]~>
-#$LBV\D!1K]%R?^g.^3og,Aq`!D?,cg($g1g9$$]7,!ufg=iF"?iJa[B>=>t!RFjGg&OhGg'35a
-9\S4F=b5:Xg8`j2ir@lhL=5Yig'>fPmcqOUfg1,~>
-#$LBV\^d1Y]&j2nk"t2:juNF!s%r^W%T)<M[u6/8k+J%&k-(muroO5uant3$g0FU=!)W[W#)hV?
-k2t?'J`_OGWoaNOs4PqXe+*=c#KMJckJ6T@6@]~>
-#$LBV\^c7g\u[)<X?<RHX>bHUJ;$IeXJInXQ<8Z]2lqCCXK8:f9rY4n;OI?_'Ve*uV5^O`V6$bm
-X>d&YQqsfbT;7%>JZQ#U#.j6SeVDWDqpbqlKCA!=nCg3Z~>
-#$LBV\D!1K]%S?%g.^3og.%O*U8V2>g<iFE^2Ka47G=>hg=jum@b08aBYjT"'[Kk7dFR#OdG!=!
-g-sKE_.D?Sb0Y^nJ_I9\#3,[>g4n&Hqq;:uJaVg;nC^*X~>
-#$LBV\^d1Y]&k25k"t2:k";DLX0Q$ak1r\ma`XYV8`ln3k2tOGBAr"4DTr"?'\ZgSh;[R#gudbO
-k"4Imb\H;&e_>Z;J`a,t#4)<BeVDWDqpbqlKCA!=nCg3Z~>
-#$LBV\^c7g]<!38,(qV)/;o`p?smiM<+&cTXIE6u<?R='D.$aRPCd%I?%2XO&#WB7=.$(X=(#EL
-X;tGO=8o9%,?9;rJZQ#U#.j6SeVDWDqpbqlKCA!=nCg3Z~>
-#$LBV\D!1K]@nI6.]5D033^#6H?tJ!C3jeQg;RrUCFHRDML'Sf];9UqFeJTb&(G??DSb&EDL-V]
-g*L`bDuSGk/8TmkJ_I9\#3,[>g4n&Hqq;:uJaVg;nC^*X~>
-#$LBV\^d1Y]B1<L/[.II41W=RJUs!CE.N-gk0S4$E@S]bP(A1-`NFQ=I&Zu)&)V>WFj&pmFFf"$
-jsPD)FoLM(/olO*J`a,t#4)<BeVDWDqpbqlKCA!=nCg3Z~>
-#$LBV\^c7g]<!0HLma9lNL[)9Lkr.6Sqr@qXK7hGS;Wu?XGD[uXK7J=Nqf[WSVW[4X::SRLoII<
-P_c$7XD]VXJZOF(Y,hi=map!Ee+*=c#KMJckJ6T@6@]~>
-#$LBV\D!1K]@nFJXMV?_ZGtV4XK:.0aK2^Ng=jEF`j!P<g8qBig=j!:[.r>VaK32Vg'tm"XOl0"
-]<'92g5Ir-J_G\/Y1a*>s5)Iaddm:h#Kq\dlFuc@6%A~>
-#$LBV\^d1Y]B19a[EQA1][5f_[C,/Ze$Zkqk2sprdCRfhk-_V<k2sIe^A-gle$[BujpfPB[Gp=F
-`jOI]k*.mNJ`_OGY3#rSs4PqXe+*=c#KMJckJ6T@6@]~>
-#$LBV\^c7gYH.l+=]ndmn#QMWr)j#Cp8e=?+'SWE!JHnmXF[ITX9Q9(f@>Z*nb^iAa+NjD_!p&E
-J,~>
-#$LBV\D!1KYM'-1E,][1n(IcYr,;Y%p=]S8-Z]1>!N3hdg4@t[g'6R:hV*_4o)%,GbCT*H^@9fA
-J,~>
-#$LBV\^d1YYN>uIGB\,Pn)aVpr-&.4p>uFM.<tgR!O9q$k(2Zsjp(/Og!tl,nb^iAa+NjD_!p&E
-J,~>
-#$LBV\^c7gYH.i,O,oh!X8o-qNrYUAX9+iOOFaKaXJ`-(]'e2#LXYejeHa-In)qLUg-U;~>
-#$LBV\D!1KYM'*3[^O0Cg&TS![K+5=g&f1#[Xm.`g8EX/ir@lhL=5Yig'>fPmcqOUfg1,~>
-#$LBV\^d1YYN>rJ^qe=bjoF68^];XQjoWiD^k(X!k,7>Gli5YgLXYejeHa-In)qLUg-U;~>
-#$LBV\^c7gQ)k+1D60gTr_W`bXC2$)"f8<%X&5&VX8nUd;$Cm>XD:\!JZOF(\uZ+Imap!Ee+*=c
-#KMJckJ6T@6@]~>
-#$LBV\D!1KQ.cA)MqZmArau;Lg3N[1"ju&XfOqbkg&SneB*F7Jg4s=TJ_G\/]%RAJs5)Iaddm:h
-#Kq\dlFuc@6%A~>
-#$LBV\^d1YQ0&4=P31ngrbMY\k(*GI"l8>'jD;a1joEO&C^$'ck)X?#J`_OG]&j4_s4PqXe+*=c
-#KMJckJ6T@6@]~>
-#$LBV\^c7g\Z?*KG@R_U4Y/]XP4YgU9)>V+V1khKKOm6HXAkOQ</@VQQ^9t0XK5!$HMX]PNG+ZF
-403OEQWf`WR>ld!JZQSe#.j6SeVDWDqpbqlKCA!=nCg3Z~>
-#$LBV\D!1K\_7@?Q[RTA9fPg?\b+SU?2E7ldAbXLVgqFog1nC;C9?3&^V<Xgg=fhYS,1hJZ@p!-
-9A5Sl^N.*C_6\^HJ_Iil#3,[>g4n&Hqq;:uJaVg;nC^*X~>
-#$LBV\^d1Y\`O3RTS2Ii;*.TN_t<'kA,>=)h6Pu$Y_Q$:k&AJcE44nGb0!`7k2p-(U\a*^]SjqT
-:Ze18b';(kbe/MhJ`a]/#4)<BeVDWDqpbqlKCA!=nCg3Z~>
-#$LBV\^c7g\Z?ZQE*03CJ7u$c4KO9/8X?HI8Y:*7XH"2j:Aq7!Hqn1HXB:QHrN$'p<Ls,j#F/Dh
-XGpG%HM=KLDL/C$H`WW2XG:+RU4KCsXMCnA]'e2#LXYejeHa-In)qLUg-U;~>
-#$LBV\D!1K\_7pCNc<_+UP%:S9\QLP?,#%2?-8@[g9_u.A,Y*dSn!2og2OJorRq=uCWHG.#JG')
-g9PgYS+kVFMji@WSD(hjg8fF'c%4T"g;)DHir@lhL=5Yig'>fPmcqOUfg1,~>
-#$LBV\^d1Y\`OcUQ?MEQXGc6';!,)n@`dcY@b%!&k.W$KB`7&uVJ(Y:k'"O:rT417EROjK#KV)G
-k.H#(U\EmZPG@9&V<6$:k-]VHfR`19k.p*`li5YgLXYejeHa-In)qLUg-U;~>
-#$LBV\^c7g\u[6M+=A8%XFOucX?;>KSt9,MW_?cAKn-*\StE*cQqD.fXK7RcX??H_!Lld]X9XGh
-XK6#cDL2&Y%R?toIV4*u:TUXsSjm4hJZOF(_Q3sQmap!Ee+*=c#KMJckJ6T@6@]~>
-#$LBV\D!1K]%SLQ-o!*hg7s;Sg.\YsaiSS8f3iidW1qg3ai`>k^g;i@g=j&Rg._J!!QALGg'=R*
-g=h+SMjsIp%T1d1T7`b;AD5bha]X&CJ_G\/_V,4Rs5)Iaddm:h#Kq\dlFuc@6%A~>
-#$LBV\^d1Y]&k?h.PrU%k,aL'k"rR?eC8`_j(<e0ZE)nUeCE^Db@?Xck2sR&k"u$=!RPHWjp//F
-k2qK&PG@m7%TVKMW/@NYC$+R;e6[gfJ`_OG_WD'gs4PqXe+*=c#KMJckJ6T@6@]~>
-#$LBV\^c7g\uZ:3,:at/XFM]c6@h8uX9=heXA`m4X8kB]X9+GTFoJHE8tN+HrN$$-L]+:Z=HKVc
-4KNFHpoFa]>H4d+I;4U7rN$&p>,["RJZQ_i#.j6SeVDWDqpbqlKCA!=nCg3Z~>
-#$LBV\D!1K]%RP7/2f$!g7pE%;km%cg'#-'g1c?@g&OhFg&eZgPlBA=?HChorRq9uXSpiXDn"HS
-9\PDopt?"\FP,=$SqjIZrRq<^En,`pJ_Iup#3,[>g4n&Hqq;:uJaVg;nC^*X~>
-#$LBV\^d1Y]&jCN00(W4k,^FB=KG?ujoieCk&-4XjoA6VjoW;.SGqXQA(0R:rT4-3[Jf4mFi!5&
-;!*t:puVjrHK=5NViJ9$rT4/oGi=59J`ai3#4)<BeVDWDqpbqlKCA!=nCg3Z~>
-#$LBV\^c7g\uZRG=DV!<XFOiYVQ=']XK6_cXAbD_X:IFpWf*s[VfP=NV.i"R'o)^h!'L1\!'L7^
-"$8Ul1&e6TJW]o4!IS_]X:'DlXH@9\S#WQkRWsCbJZQhl#.j6SeVDWDqpbqlKCA!=nCg3Z~>
-#$LBV\D!1K]%RhNE/ADag7s/Gdb8lKg=i!Sg1e8!g(-m2f<O&`e<3t#d=k4e)QNej!)3=E!)3CG
-"%u<A55s7:UUU3U!M,)Fg'aI.g:2o3`7N_s_j>r.J_J)s#3,[>g4n&Hqq;:uJaVg;nC^*X~>
-#$LBV\^d1Y]&j[fG*-h,k,a<ohWB3sk2rG&k&/9=jpt;Nj1=C8i0muDh2G-+*4,Y,!)WUU!)W[W
-"&D`L6N6*JXMXqu!N)"WjpS&Jk/*-Tcf=0McCfaNJ`ar6#4)<BeVDWDqpbqlKCA!=nCg3Z~>
-#$LBV\^c7g\Z?HLEETBE3$hk3XK#Pg4Dh0f*]/6CX942>5)K6>#GQ78XK6%MLAn7S4oDA]4oMG`
-W[BS$X8sSIrN$$ID>pU@>Wcf'XH.f-X9!>GJZOF(`N09Tmap!Ee+*=c#KMJckJ6T@6@]~>
-#$LBV\D!1K\_7^>O)`n-7PAr=g=LLA9T.WA-:47%g&n?K:TaTL#L/@Xg=h0!WrC]P:&N]F:&WcI
-fJ,Vig&WdBrRq:CMZ2<6FA.MEg9mRNg&[9?J_G\/`S(OUs5)Iaddm:h#Kq\dlFuc@6%A~>
-#$LBV\^d1Y\`OQPQZqTS8hkbVk2Uhc:m0tb-q:'4jo_qd;n)_f#M>F!k2qOAZi9(e;Z,YW;Z5_Z
-j>94&joI/WrT4-XOoFJIH;K^ck.dkmjoLhTJ`_OG`T@Bjs4PqXe+*=c#KMJckJ6T@6@]~>
-#$LBV\^c7gJZS%9!>gTDXF[IlX9Q9(f@>Z*nb^iAa+NjD_!p&EJ,~>
-#$LBV\D!1KJ_K;@!?S@og4@tsg'6R:hV*_4o)%,GbCT*H^@9fAJ,~>
-#$LBV\^d1YJ`c.X!?\e%k(2[6jp(/Og!tl,nb^iAa+NjD_!p&EJ,~>
-#$LBV\^c7gJZS%9!/lE0JZQek#.j6SeVDWDqpbqlKCA!=nCg3Z~>
-#$LBV\D!1KJ_K;@!3h%.J_J&r#3,[>g4n&Hqq;:uJaVg;nC^*X~>
-#$LBV\^d1YJ`c.X!4maDJ`ao5#4)<BeVDWDqpbqlKCA!=nCg3Z~>
-#$LBV\^c7gJZOF(JZPiP#.j6SeVDWDqpbqlKCA!=nCg3Z~>
-#$LBV\D!1KJ_G\/J_I*W#3,[>g4n&Hqq;:uJaVg;nC^*X~>
-#$LBV\^d1YJ`_OGJ``ro#4)<BeVDWDqpbqlKCA!=nCg3Z~>
-#$LBV\^c7gJZSmQ!Ml^nX9#&rnZ2_anZ2bgVr"KVP;8k`XF[JNX9Q9(f@>Z*nb^iAa+NjD_!p&E
-J,~>
-#$LBV\D!1KJ_L.X!RTErg&]IOn_*uen_+#leDAm\\j4Mkg4@uUg'6R:hV*_4o)%,GbCT*H^@9fA
-J,~>
-#$LBV\^d1YJ`d!p!SlZ4joO/rn`Bi'n`Bl.i83St`'`1.k(2[mjp(/Og!tl,nb^iAa+NjD_!p&E
-J,~>
-#$LBV\^c7gJZSmQ!FCW]X8tkbnZ2^QnZ2b+Ibh(+8tLU8JZSdN#.j6SeVDWDqpbqlKCA!=nCg3Z~>
-#$LBV\D!1KJ_L.X!I1dGg&YF$n_*t:n_+#!TAA3%?-.ZOJ_L%U#3,[>g4n&Hqq;:uJaVg;nC^*X~>
-#$LBV\^d1YJ`d!p!IhQWjoJl@n`BgJn`Bk4W86S:@aotkJ`cmm#4)<BeVDWDqpbqlKCA!=nCg3Z~>
-#$LBV\^c7g]<!3(2JP9b6`d.l4E[a+E]deqEN!J34HceIS30&LM4m^-9VD9a,D7ai4Cb:j8o0)A
-PcUZ`4FF6'+YZ$IXHFG\4K5>:4KML8QM[`uAJI=>XK8C:4D:[p5r+-F@AkJ'4HoTB-_*:`SY@iX
-4A2?KXFE?69!"@A4CY4iLceKuSue_k4F=0'0oTg?Tn0;$X9Q9(f@>Z*nb^iAa+NjD_!p&EJ,~>
-#$LBV\D!1K]@nI#7>FKe<SGlG9U+8aOA($uOO\nU9Y&m2`_96^Xit<L@*AH$,H!\b9RYFE?&>CO
-]@tVO9V'n\.QpJDg:/7q9\7l]9\O5C^AHV!J/V+4g=k,59SD!N;Eq-?I+9l/9Y1&R-cShVa3Hl.
-9OGusg7V,W?J<.f9RYCDXA!2%akG*^9Ush\5-fiMb^nK(g'6R:hV*_4o)%,GbCT*H^@9fAJ,~>
-#$LBV\^d1Y]B1<78WHQ&>3=[k:n6\0Qr&E7Qf*Zr:rMMYcqm`"\(GCkA_-b@,I'P#:k[`g@Zdfi
-`TGs":o3=+/3m%Xk//?8:u^M';<Dg]ant38LE'-Hk2tZa:lOAq=$s8TK&JFF:rN1l-dbdkdb-sP
-:h8/>k,D1!AEM$2:k[`g[SU^<eE5P2:o*7*6+i.gf7E(?jp(/Og!tl,nb^iAa+NjD_!p&EJ,~>
-#$LBV\^c7g\u[)1IP$+5XC$gcF*2MHXG/1*SV!rE4KO]HXJdq"<gg%Z<h]Dl'/t-:Kk%3C057M/
-XBCUcDL/BjM>aLV8>,s`"DrLeR8<X[!'L4]%;UBnIqYpL<f^:^XD34ZX=095XJf0c@SNqa>-**f
-XH=Qa=fe]Z@Y86nQmA9)>)o\%H)t@AJ"2.BXGEq^]'e2#LXYejeHa-In)qLUg-U;~>
-#$LBV\D!1K]%S>lT/rcAg3BdSP*D&og8Zs_a/.MD9\R$og=8KVD8P#HD9_t3'1S>BWI<L+4,)CO
-g2XOSMjrFFY5R&T>Kd$""H&`'_IWJr!)3@F%>US0U4h77D7+35g4u<qg*jOKg=C,THt(g:En[(?
-g:/K:ESB-GIAVPK_(Nj`EjXPZRbE$hTuEm[g5+Geir@lhL=5Yig'>fPmcqOUfg1,~>
-#$LBV\^d1Y]&k2'W'.7Zk'sl&R[fb:k-Hu.d]V`p;!,];k2A_$F3WjpF4gBP'2"q[Z@qAP5)eWm
-k'+T&PG@8h\GbOj@+P>>"HfPCc"["9!)WXV%?IFLWf6)^F2)bWk)QD8js\/gk2CC&JnO5[Giklb
-k/&O\Gin.pKWg0nbV7Q/GeW=)U?6r1WmIr#k(r.(li5YgLXYejeHa-In)qLUg-U;~>
-#$LBV\^c7g\uZ)uX?<RHX<7F(!DkoXX:@@oVIDYM19>_>XK8+\9E)!n;3q*\!'L7^"?`cE9r\,n
-#8fQc3a&OjM>aLV8>,s`"JSAe9:bm[!'L4]!&+=6#skYoLea;<XD34ZX:fb*4?P?R@YUtE>-(Af
-XK7k0GlFcT4B[`HX@f(c)*C#B=KGkRJZOR,#.j6SeVDWDqpbqlKCA!=nCg3Z~>
-#$LBV\D!1K]%R?^g.^3og*lqo!G5%)g($g1dsXn`5MDHag=jca?iJa[B>=>t!)3CG"AIOT@b1P4
-#9QW58o`R0Y5R&T>Kd$""O1*'?cVur!)3@F!'C0R#u]L2X^f-"g4u<qg(Kf.9M@XNI&bo-EnXm@
-g=jH)R/YeM9Q@Jog0MhS+&#@#E8#T'J_Gh3#3,[>g4n&Hqq;:uJaVg;nC^*X~>
-#$LBV\^d1Y]&j2nk"t2:jsp@,!GbO2jpk5Mhh+a%6ft&-k2t::AcCfmD9;\;!)W[W"An6mBB&pQ
-#9Zi>:3YiL\GbOj@+P>>"P@&CACC;9!)WXV!'gHZ$!69O[V3eFk)QD8jq=@E:f'KdK!a[SGiiPb
-k2ssSU&O0b:j9\:k$lj&+])!1G34:GJ`_[K#4)<BeVDWDqpbqlKCA!=nCg3Z~>
-#$LBV\^c7g\u[)<X?<RHXC-gbXDi9'XFr"'N`iH.1oup@XK75;=.$(Z<hfJm#<-e,K4V-C>lC`<
->E,_^Ff\o+XDk8B8>*&'XK6G=@ed#=4KOC'XDN<cXDk8+=--C^XD33cE;HX^PZ4`cLm2A'XH$Jc
-Iqc!cE0+2'XFt,<A#u"@Suc.UXJ^3B?]"]^!EY,/XGj4b]'e2#LXYejeHa-In)qLUg-U;~>
-#$LBV\D!1K]%S?%g.^3og3TjSg5_A\g8Hd\ZuOfe6JB%eg=iX7DSb&GD9_t3#=as3VL[C+FT'o-
-F0jTLQ.gJcg5an@>Kb`\g=hX"I/)D09\QY\g5;BRg5an#DRXE7g4u<SNr%HU]PH6TXh/t\g9bnS
-TnV4SNj`l[g8BG"IG2IeakCgAg=2A@H*."u!H,&kg5O_iir@lhL=5Yig'>fPmcqOUfg1,~>
-#$LBV\^d1Y]&k25k"t2:k(0r&k*DL+k-6f+^3Je67HVR/k2s+cFNimoF4pHQ#>1NKYD;8PHi<(@
-H+i@tS`YC2k*G/l@+OJ+k2r%HKD=RC;!,:+k)uP&k*G/MFhr(Zk)QD&QMT_i`c:/'[`3p+k.Z*&
-WK$'&QG@\+k-0TGK]^E0eE2(ik22]kJ%,@<!Hbi&k)AF,li5YgLXYejeHa-In)qLUg-U;~>
-#$LBV\^c7g]<!3(06'@%5'j,74?T49F?F(mXJokqE&W<KT0,5DVk['N9VVBb#Wm)iAZ2\&104CU
-'W,(s6(k<S:-=N;XIqmBS?/fj;N1CP'RDlJVQ?e74?S\+68XBL@]ZA*4GN[5-(d:^@%B)CX@tC?
-XF`PsGc[>r4CkClM`aj==KJB(4@,X61H9ITX9+Y%H@`/VX9Q9(f@>Z*nb^iAa+NjD_!p&EJ,~>
-#$LBV\D!1K]@nI#4-*C,:Rfj[9MER]P>$Epg=CpNN^]\ra\5BSe'DT!@F"`'#YU=SJCW@[5]$GR
-'[h%r;p3n@@na5_g<3Gh`nK.sBX7Ee'Uh^?e(WE29MDkJ<'mQHI+lq_9W@jA--8hSH,i3Rg0d1d
-g8%D9R+fGO9RkUHYY8YIE8&`]9N''X5t@+;g&er+Rt9:Pg'6R:hV*_4o)%,GbCT*H^@9fAJ,~>
-#$LBV\^d1Y]B1<75F,KD;l&<%:f,['Ro"f2k2D4pQ:\.>e5/tmhqDgAB%d%C#Z$mcLZ%<*6ur:h
-']"%2=4ZNfBi)M*k13X2dH9TMDS5c,'VeKRhr`s^:f+ph=@KM[K'(j.:p]u[-.PjhJC6hlk%7!/
-k,hHVU#sTr:kmoj\km3cG37Y-:fl6"6qa!JjoWRCUOhQdjp(/Og!tl,nb^iAa+NjD_!p&EJ,~>
-#$LBV\^c7gXK2GRBBZDs4QNRETguAh!D%0\XGa.a]'e2#LXYejeHa-In)qLUg-U;~>
-#$LBV\D!1KXP*]MK':ng9]Xn.bZ_:*!F1Y9g5FYhir@lhL=5Yig'>fPmcqOUfg1,~>
-#$LBV\^d1YXQBPbMWj1&:upa>f3bfF!F_:Fk)8@+li5YgLXYejeHa-In)qLUg-U;~>
-#$LBV\^c7gYH.l*4?R8Un#QMQq`Fp:4HSa-"bSloOfY&M49/XOX8l)p492;3X9#/uJZOd2#.j6S
-eVDWDqpbqlKCA!=nCg3Z~>
-#$LBV\D!1KYM'-/9MC&in(IcQqb.&X9Xa-<"f=p[\D"n!9E95#g&Pa_9E<Pog&]USJ_H%9#3,[>
-g4n&Hqq;:uJaVg;nC^*X~>
-#$LBV\^d1YYN>uG:f*&/n)aVhqbR>_:r)8V"g:]k_WK2B:]Pk-joB2p:]TD*joO9!J`_mQ#4)<B
-eVDWDqpbqlKCA!=nCg3Z~>
-#$LBV\^c7gJZOF(JZPiP#.j6SeVDWDqpbqlKCA!=nCg3Z~>
-#$LBV\D!1KJ_G\/J_I*W#3,[>g4n&Hqq;:uJaVg;nC^*X~>
-#$LBV\^d1YJ`_OGJ``ro#4)<BeVDWDqpbqlKCA!=nCg3Z~>
-#$LBV\^c7g\Z?$B13K\"O$#FRXF[I(XSJq%]'e2#LXYejeHa-In)qLUg-U;~>
-#$LBV\D!1K\_7:45F'sV[S08Dg4@t/gA0G,ir@lhL=5Yig'>fPmcqOUfg1,~>
-#$LBV\^d1Y\`O-F6_3B%^edaVk(2ZGk5"-Dli5YgLXYejeHa-In)qLUg-U;~>
-#$LBV\^c7g\Z>g9NVojX4FsSbXF[JKX9Q9(f@>Z*nb^iAa+NjD_!p&EJ,~>
-#$LBV\D!1K\_7(+ZM`DV9S(oKg4@uRg'6R:hV*_4o)%,GbCT*H^@9fAJ,~>
-#$LBV\^d1Y\`Np=]_pml:k@b[k(2[jjp(/Og!tl,nb^iAa+NjD_!p&EJ,~>
-#$LBV\^c7g\Z>g9NVojX4FsSbXF[JKX9Q9(f@>Z*nb^iAa+NjD_!p&EJ,~>
-#$LBV\D!1K\_7(+ZM`DV9S(oKg4@uRg'6R:hV*_4o)%,GbCT*H^@9fAJ,~>
-#$LBV\^d1Y\`Np=]_pml:k@b[k(2[jjp(/Og!tl,nb^iAa+NjD_!p&EJ,~>
-#$LBV\^c7g\Z>g9NVojX4FsSbXF[JKX9Q9(f@>Z*nb^iAa+NjD_!p&EJ,~>
-#$LBV\D!1K\_7(+ZM`DV9S(oKg4@uRg'6R:hV*_4o)%,GbCT*H^@9fAJ,~>
-#$LBV\^d1Y\`Np=]_pml:k@b[k(2[jjp(/Og!tl,nb^iAa+NjD_!p&EJ,~>
-#$LBV\^c7g\Z>g9NVojX4FsSbXF[JKX9Q9(f@>Z*nb^iAa+NjD_!p&EJ,~>
-#$LBV\D!1K\_7(+ZM`DV9S(oKg4@uRg'6R:hV*_4o)%,GbCT*H^@9fAJ,~>
-#$LBV\^d1Y\`Np=]_pml:k@b[k(2[jjp(/Og!tl,nb^iAa+NjD_!p&EJ,~>
-#$LBV\^c7g\Z>g9NVojX4T2>^9O`RSJZOF(s/ZF9map!Ee+*=c#KMJckJ6T@6@]~>
-#$LBV\D!1K\_7(+ZM`DV9`<ZG@=3X[J_G\/s4R\:s5)Iaddm:h#Kq\dlFuc@6%A~>
-#$LBV\^d1Y\`Np=]_pml;#TMWAqPZsJ`_OGs5jOOs4PqXe+*=c#KMJckJ6T@6@]~>
-#$LBV\^c7g\Z>g9NVojX4T;D`NZWFqXF[I(XT,@+]'e2#LXYejeHa-In)qLUg-U;~>
-#$LBV\D!1K\_7(+ZM`DV9`E`IZm_5kg4@t/gAfk2ir@lhL=5Yig'>fPmcqOUfg1,~>
-#$LBV\^d1Y\`Np=]_pml;#]SY^+,_*k(2ZGk5XQJli5YgLXYejeHa-In)qLUg-U;~>
-#$LBV\^c7g\Z?$K2Kc+&O$#r3X9!B\JZOF(JZSjP#.j6SeVDWDqpbqlKCA!=nCg3Z~>
-#$LBV\D!1K\_7:@7$ZK[[S0m(g&[@rJ_G\/J_L+W#3,[>g4n&Hqq;:uJaVg;nC^*X~>
-#$LBV\^d1Y\`O-S8=eo*^eeD;joLp8J`_OGJ`cso#4)<BeVDWDqpbqlKCA!=nCg3Z~>
-#$LBV\^c7gJZOF(JZPiP#.j6SeVDWDqpbqlKCA!=nCg3Z~>
-#$LBV\D!1KJ_G\/J_I*W#3,[>g4n&Hqq;:uJaVg;nC^*X~>
-#$LBV\^d1YJ`_OGJ``ro#4)<BeVDWDqpbqlKCA!=nCg3Z~>
-#$LBV\^c7g\Z>h%VLbh"XF[JEX9Q9(f@>Z*nb^iAa+NjD_!p&EJ,~>
-#$LBV\D!1K\_7)(dXg,'g4@uLg'6R:hV*_4o)%,GbCT*H^@9fAJ,~>
-#$LBV\^d1Y\`Nq?hLXg?k(2[djp(/Og!tl,nb^iAa+NjD_!p&EJ,~>
-#$LBV\^c7g\uYt,.ZK"\JZOF(o;i/-map!Ee+*=c#KMJckJ6T@6@]~>
-#$LBV\D!1K]%R5026qeeJ_G\/[email protected])Iaddm:h#Kq\dlFuc@6%A~>
-#$LBV\^d1Y]&j(G34sh)J`_OGoB$8Cs4PqXe+*=c#KMJckJ6T@6@]~>
-#$LBV\^c7g\uYsA;2p..JZOF(o;i/-map!Ee+*=c#KMJckJ6T@6@]~>
-#$LBV\D!1K]%R43B<m*BJ_G\/[email protected])Iaddm:h#Kq\dlFuc@6%A~>
-#$LBV\^d1Y]&j'FD7kG^J`_OGoB$8Cs4PqXe+*=c#KMJckJ6T@6@]~>
-#$LBV\^c7g\Z>g9NIe0^XF[JEX9Q9(f@>Z*nb^iAa+NjD_!p&EJ,~>
-#$LBV\D!1K\_7(+Z@U_\g4@uLg'6R:hV*_4o)%,GbCT*H^@9fAJ,~>
-#$LBV\^d1Y\`Np=]Rf3rk(2[djp(/Og!tl,nb^iAa+NjD_!p&EJ,~>
-#$LBV\^c7g\Z>g9NIe0^XF[JEX9Q9(f@>Z*nb^iAa+NjD_!p&EJ,~>
-#$LBV\D!1K\_7(+Z@U_\g4@uLg'6R:hV*_4o)%,GbCT*H^@9fAJ,~>
-#$LBV\^d1Y\`Np=]Rf3rk(2[djp(/Og!tl,nb^iAa+NjD_!p&EJ,~>
-#$LBV\^c7g\Z>g9NIe0^XF[JEX9Q9(f@>Z*nb^iAa+NjD_!p&EJ,~>
-#$LBV\D!1K\_7(+Z@U_\g4@uLg'6R:hV*_4o)%,GbCT*H^@9fAJ,~>
-#$LBV\^d1Y\`Np=]Rf3rk(2[djp(/Og!tl,nb^iAa+NjD_!p&EJ,~>
-#$LBV\^c7g\uZ!b5$sHOX8tgLJZOF(JZS[K#.j6SeVDWDqpbqlKCA!=nCg3Z~>
-#$LBV\D!1K]%R7]:3a8Ig&YAFJ_G\/J_KqR#3,[>g4n&Hqq;:uJaVg;nC^*X~>
-#$LBV\^d1Y]&j*r;LcR_joJg[J`_OGJ`cdj#4)<BeVDWDqpbqlKCA!=nCg3Z~>
-#$LBV\^c7g\uZ0gFEEYHXH+6KJZOF(JZS[K#.j6SeVDWDqpbqlKCA!=nCg3Z~>
-#$LBV\D!1K]%RFbPEWK0g9i#rJ_G\/J_KqR#3,[>g4n&Hqq;:uJaVg;nC^*X~>
-#$LBV\^d1Y]&j:"S"%:Wk.`(>J`_OGJ`cdj#4)<BeVDWDqpbqlKCA!=nCg3Z~>
-#$LBV\^c7g[&a:iJUsnRXF[JJX9Q9(f@>Z*nb^iAa+NjD_!p&EJ,~>
-#$LBV\D!1K[+YPiUOh-Mg4@uQg'6R:hV*_4o)%,GbCT*H^@9fAJ,~>
-#$LBV\^d1Y[,qD*XF]Mbk(2[ijp(/Og!tl,nb^iAa+NjD_!p&EJ,~>
-#$LBV\^c7gJZOF(JZPiP#.j6SeVDWDqpbqlKCA!=nCg3Z~>
-#$LBV\D!1KJ_G\/J_I*W#3,[>g4n&Hqq;:uJaVg;nC^*X~>
-#$LBV\^d1YJ`_OGJ``ro#4)<BeVDWDqpbqlKCA!=nCg3Z~>
-#$LBV\^c7gVlTlIJZOF(KWGBhmap!Ee+*=c#KMJckJ6T@6@]~>
-#$LBV\D!1KVqM-CJ_G\/K\?Xis5)Iaddm:h#Kq\dlFuc@6%A~>
-#$LBV\^d1YVrduXJ`_OGK]WL)s4PqXe+*=c#KMJckJ6T@6@]~>
-#$LBV\^c7gWN60#BeB.^.AAX[X@k@@TgLqFVM$U:XElO@QTRj@XCa@KAZVt50pQi6G`jdC4>qbA
-XF[I]X9Q9(f@>Z*nb^iAa+NjD_!p&EJ,~>
-#$LBV\D!1KWS.F)KK8k^.Et.Ng0d1ebZ.>Vd\f3]g7(3e^eA%fg4D^\J(iUm5J<:DRCGFQ9LP\-
-g4@tdg'6R:hV*_4o)%,GbCT*H^@9fAJ,~>
-#$LBV\^d1YWTF9AN'-pu.G7-bk%-s0f32!ph6B2'k+b//b"uR0k(uW"L?@W=6HGZ]Tu0/k:e7^>
-k(2['jp(/Og!tl,nb^iAa+NjD_!p&EJ,~>
-#$LBV\^c7g\uZ+1?!W2dXI/um$*88sEa>09S:<ZrX:/N&K8j*(<MZ^W=faabX9h"jXFaE0XK6Pc
-ri?Kr:9:NZXK4scXE8Q8XF[I]X9Q9(f@>Z*nb^iAa+NjD_!p&EJ,~>
-#$LBV\D!1K]%RA6G'9k=g;3c3$/(T7OESRr`h?*$g'i=*VR(?^Cs^nDES=+cg'LI,g8/Pgg=hgS
-rn7au@bTO0g=fcSg67_Og4@tdg'6R:hV*_4o)%,GbCT*H^@9fAJ,~>
-#$LBV\^d1Y]&j4MI!i9_k0*aO$0@_SR!d6BdAg%<jpZfAYJ#5,EnoflGNMa$jp=lHk,r[6k2r5&
-roOU6B]eGRk2p(&k*qikk(2['jp(/Og!tl,nb^iAa+NjD_!p&EJ,~>
-#$LBV\^c7g\uZELMi1T'X@\>.6E?1aG)JulX8kBXX9N*T</Fh6@fEG>4KOTHXDW?cVc%eIWiU>a
-ri?Kr:9:NZXK4sJ9:hi.XF[I]X9Q9(f@>Z*nb^iAa+NjD_!p&EJ,~>
-#$LBV\D!1K]%R[>Ycqo[g0Lqe<8"]#Q*=Tog&OhAg'2nfC9;QVI/_h19\Qmog5MKSe7b:rf@lLP
-rn7au@bTO0g=fc4?c^HBg4@tdg'6R:hV*_4o)%,GbCT*H^@9fAJ,~>
-#$LBV\^d1Y]&jNQ]"2n*k$kp5=lmF@T"8G2joA6Qjp$C+E4:,!KDt!D;!,N:k*)S&heo0<j5uo#
-roOU6B]eGRk2p'ZACK.]k(2['jp(/Og!tl,nb^iAa+NjD_!p&EJ,~>
-#$LBV\^c7g\uZF:<E1N5XBnn,NNAsDXK4P`X8kBXX9N*g=`@T"@fEGL4KPJ^N`MUMN%S*UT<*0V
-XJ^?4:9:NZXK4ri+K0jmJZQ8\#.j6SeVDWDqpbqlKCA!=nCg3Z~>
-#$LBV\D!1K]%R\>ChtuAg37@LZeEf+g=f7"g&OhAg'2o)EK5+>I/_h?9\S!5Zu*b8Z8ueSb1`,C
-g=2P/@bTO0g=fbC.Fj"'J_INc#3,[>g4n&Hqq;:uJaVg;nC^*X~>
-#$LBV\^d1Y]&jOUEcO.Zk'h>k^#n-Rk2oM>joA6Qjp$CEGF!N\KDt!R;!-\W^2qT^]010ge`NEj
-k22lXB]eGRk2p&f/)c'AJ`aB&#4)<BeVDWDqpbqlKCA!=nCg3Z~>
-#$LBV\^c7g\uZE6P)VDbXH/O-7'!.OXK4P`X8kBXX:ersTIO0*?)ap!8$&e7Amh^A8H+bf9<<8W
-XJ/1Q:9:NZXK4scS:#^cWf!U'XF[IaX9Q9(f@>Z*nb^iAa+NjD_!p&EJ,~>
-#$LBV\D!1K]%R[#]!=c;g9nN'=4tu#g=f7"g&OhAg(Jb5au+7HG1PBk=k_SoJU,u'>Q22L?eUd-
-g<Ed=@bTO0g=fcS`gr[Sf<<PPg4@thg'6R:hV*_4o)%,GbCT*H^@9fAJ,~>
-#$LBV\^d1Y]&jN4`4S[]k.ejQ>NO[Dk2oM>joA6Qjq<6QeMhceIH'DA?KUC?Lk+XM@/e([AEKGN
-k1O(dB]eGRk2p(&d&*]&j1*ipk(2[+jp(/Og!tl,nb^iAa+NjD_!p&EJ,~>
-#$LBV\^c7g\uZWa:/NWFX<^P9=KH0WPCjg$S5("uV#.5$Ub#->>?e1Z:JOiOri@/'XK6ji:5_jd
-:,Ok'8OfLW:/5T+Q68ao20>pn!/#j(JZQGa#.j6SeVDWDqpbqlKCA!=nCg3Z~>
-#$LBV\D!1K]%RmW@qIc>g+HlFE7omk\u-aA`FC*%d/2N)cSo1aF*$'0A7K>`rn8Deg=i2DA$BGe
-@m`Rm?!5Nl@q1;J^+!;s6^-6J!2b>$J_I]h#3,[>g4n&Hqq;:uJaVg;nC^*X~>
-#$LBV\^d1Y]&j`kBP]hRjtLI^G3+W1`NUV`ctF\<g\^+@gH/p-H$SPQC1qP'roP7uk2rTfBY%k&
-BLbL)@U@f2BP<Fga=C\47[rPl!3^t9J`aQ+#4)<BeVDWDqpbqlKCA!=nCg3Z~>
-#$LBV\^c7g\uZLDR[p4FXIP`JVQ?GZVkfcVWW&=dWr&k)Wg]HZWM?PrS!p#KX9P?!XJ;5QVYZ_d
-Trb&YR]3BerL*kdX?TgcJZOF(\uZ+Imap!Ee+*=c#KMJckJ6T@6@]~>
-#$LBV\D!1K]%RbJ_oL'Dg;UtIdb;j]eBl+Yf)EPef_aA0fYb__f$E((`P]jsg'5aSg<[[Sde^id
-bhCF]_q*PlrPJceg/)b=J_G\/]%RAJs5)Iaddm:h#Kq\dlFuc@6%A~>
-#$LBV\^d1Y]&jUbcI1Fqk0VE!hWEA6i7uW2ir74'jSS'HjNc08inNVXd*C2?jp'E!k1\,+hYPM&
-f]Lr6cJn!ErQYQ&k#?N^J`_OG]&j4_s4PqXe+*=c#KMJckJ6T@6@]~>
-#$LBV\^c7gUT=GgrC-c_f;nt$JZOF(\?#nGmap!Ee+*=c#KMJckJ6T@6@]~>
-#$LBV\D!1KUY5]TrE0,3f@g4tJ_G\/\Cq/Hs5)Iaddm:h#Kq\dlFuc@6%A~>
-#$LBV\^d1YUZMPerE]J=fB*(4J`_OG\E4"]s4PqXe+*=c#KMJckJ6T@6@]~>
-#$LBV\^c7gUTFBf!2G+HJZOj4#.j6SeVDWDqpbqlKCA!=nCg3Z~>
-#$LBV\D!1KUY>Xj!7$/LJ_H+;#3,[>g4n&Hqq;:uJaVg;nC^*X~>
-#$LBV\^d1YUZMR0rR_,'J`_OGNTLH2s4PqXe+*=c#KMJckJ6T@6@]~>
-#$LBV\^c7gM6$\gJZOF(U9"R1map!Ee+*=c#KMJckJ6T@6@]~>
-#$LBV\D!1KM:qr[J_G\/U=oh2s5)Iaddm:h#Kq\dlFuc@6%A~>
-#$LBV\^d1YM<4enJ`_OGU?2[Gs4PqXe+*=c#KMJckJ6T@6@]~>
-#$LBV\^c7gM6$\cnuMn./8]s>JZQ5[#.j6SeVDWDqpbqlKCA!=nCg3Z~>
-#$LBV\D!1KM:qrVo%F/#3/W:@J_IKb#3,[>g4n&Hqq;:uJaVg;nC^*X~>
-#$LBV\^d1YM<4eio&^"64-G0WJ`a?%#4)<BeVDWDqpbqlKCA!=nCg3Z~>
-#$LBV\^c7g]<!3(7Wh=B:op^14FsT8IQV@AEN="?4J/^VWB<InNiH#?:TF8m'r*lR3g?_44Ar8^
-Am8YN>A%#P;*:3EX9!]bri?3r4@lIKX:'tIJinNKXIMCIDGl%eJZR+t#.j6SeVDWDqpbqlKCA!=
-nCg3Z~>
-#$LBV\D!1K]@nI#=Hm-PB%kmh9VgCrT1k#POP,Ue9Zl)CekAu3[+B"cACp\3(!fQI8\<]l9PE/6
-Joc3_F+S:aB2$,?g&[b$rn7J!9O$-Gg'b/VUeII[g;Q`pN+ddrJ_JB&#3,[>g4n&Hqq;:uJaVg;
-nC^*X~>
-#$LBV\^d1Y]B1<7?(>GkCZa]7:p&mBW)/LiQfXK/:t=^ji_W^P^>j-.C?,0Q("uJ\9uc><:i>FX
-M0XW%H&6X&D,ACSjoM?AroO=8:gi;[jpSdpX\c$!k0Qq;PAYs6J`b5>#4)<BeVDWDqpbqlKCA!=
-nCg3Z~>
-#$LBV\^c7g\u[)/F"2DsXCm*cB7YMHXF;FrRX)!94KOoHXJ[Fl=d?(V=/>_p"?`ceI$Xc5!'L7^
-()hoDK1;:MQE48MXK6ecXK7XcXIrObqlC,h@l\6cO]SWR+HqAXJZR+t#.j6SeVDWDqpbqlKCA!=
-nCg3Z~>
-#$LBV\D!1K]%S>iOu8V#g4H-SJu##og7L"O_jT649\R<og=.mHE4suBDUA:7"AIP'T"b3X!)3CG
-(*TXuVHLh`^Y3_8g=i*Sg=j2Sg<49Sqq;BRIRo/d\8L$=.(b&aJ_JB&#3,[>g4n&Hqq;:uJaVg;
-nC^*X~>
-#$LBV\^d1Y]&k2$RQ-s:k)$5&M63_:k,9urc(X:^;!,u:k2/"jGK8jiFkcfU"An7CVTAc!!)W[W
-(*^(,Y?oL%al[i^k2rP'k2s[&k14P&qrS5bKhRG%_K=qd/&d)%J`b5>#4)<BeVDWDqpbqlKCA!=
-nCg3Z~>
-#$LBV\^c7g\uZ)uX?<RHX<7F(!CK!KX:@@oWbad[19>_>XK7hO9E)!n;3q*\"G]*%BW;!4!'L7^
-(-JT\U.1SHXK7=cXK6ecXK67h4?OsMqlC,hWB@7EA;%%c<Ki!8JZR+t#.j6SeVDWDqpbqlKCA!=
-nCg3Z~>
-#$LBV\D!1K]%R?^g.^3og*lqo!EDhmg($g1f8**o5MDHag=jEQ?iJa[B>=>t"KP3iK\-4W!)3CG
-(/3=Ubuqtog=icSg=i*[email protected];BRekFdkI](oRCV,/OJ_JB&#3,[>g4n&Hqq;:uJaVg;
-nC^*X~>
-#$LBV\^d1Y]&j2nk"t2:jsp@,!Er>!jpk5Mj,d)66ft&-k2sq)AcCfmD9;\;"LV'&MrXg!!)W[W
-(/X$ifj;s;k2s7&k2rP'k2qdd:f&s]qrS5bi_\c6KsBe&EQ*LkJ`b5>#4)<BeVDWDqpbqlKCA!=
-nCg3Z~>
-#$LBV\^c7g\u[)<X?<RHXBCUcXF4c4XGnd4N`iH92QVpBXK7MF<1U+_<M95j"F[AQ@#4f`!'L7^
-(-JT\U.1S'SZHRTXK6ecXK71cXK7>OqlC8lWB@7EJnD*W0pA]?JU)gJJZR8##.j6SeVDWDqpbql
-KCA!=nCg3Z~>
-#$LBV\D!1K]%S?%g.^3og2OLSg7Etlg9N]lZuOfs7,"tfg=j!ECW>)NCs)Y/"J4?$H*.)"!)3CG
-(/3=UbuqtFaP)BAg=i*Sg=iTRg=idPqq;[email protected]&UR?\eJ_JN*#3,[>g4n&Hqq;:u
-JaVg;nC^*X~>
-#$LBV\^d1Y]&k25k"t2:k'+W'k,4-<k.Ee<^3JeD8ERU2k2sIqEREq!En1'L"K1DEJ@>I>!)W[W
-(/X$ifj;rde)lXhk2rP'k2s(&k2s8(qrSAfi_\c6Y))5k6,i!KXJ1:.J`bAB#4)<BeVDWDqpbql
-KCA!=nCg3Z~>
-#$LBV\^c7g]<!3(,&oM`0m]Qs4?Sb+BKTKTXJK8dALN)1Outj/U74e<8X]FV,""IT>bnHf4<cn`
-Ag2mQK-Yq/8j%[+XD9OB@'$Gf4?QoFr2^Ef,@EuQ6#20:7mW??V`d:rXF[J#X9Q9(f@>Z*nb^iA
-a+NjD_!p&EJ,~>
-#$LBV\D!1K]@nI#/!!,a5F]o:9MDtKKM6GQg<k.=J2<qR\P,\9c,<s_>f-?k,#q<1FjSjX9Iif_
-Jh*cNVCnQ9?;.-Jg4qjPHJ7)W9MBWVr7V[d/:(HM;M_;G>>i)ee4rklg4@u*g'6R:hV*_4o)%,G
-bCT*H^@9fAJ,~>
-#$LBV\^d1Y]B1<7/XAu!6DW7X:f,'jMbn^fk1tJ_LGl3q_ba0Qf[",*@EnZ2,$If>He[]*:b>Mu
-M(PtbY;*%R@o08hk)M_iJ`c++:f)Ppr8nO%/qI;a=-'X`?rt>0hbmI*k(2[Bjp(/Og!tl,nb^iA
-a+NjD_!p&EJ,~>
-#$LBV\^c7gXK2GZ?Iu7ZRSMnE#+nqgXFW('JZOF(dB!P`map!Ee+*=c#KMJckJ6T@6@]~>
-#$LBV\D!1KXP*]XGh:XM`+%c\#0Lf)g8$m]J_G\/dFnfas5)Iaddm:h#Kq\dlFuc@6%A~>
-#$LBV\^d1YXQBPnIb3]_c=l8##1[eEk,go+J`_OGdH1Z!s4PqXe+*=c#KMJckJ6T@6@]~>
-#$LBV\^c7gYH.l*4?QrHn#QMQr&asin>l[j.STH8!1WmK!*oE&#?ErYS?/ffT7O(pXO+$Q]'e2#
-LXYejeHa-In)qLUg-U;~>
-#$LBV\D!1KYM'-/9MB]Yn(IcQr(I*>nCdqZ2IZ42!6"e/!-S1m#Am.>`nK.nb(88tg<eOXir@lh
-L=5Yig'>fPmcqOUfg1,~>
-#$LBV\^d1YYN>uG:f)Vsn)aVhr(mBInE'dk3+hdE!71R>!.4V*#BN^MdH9TGeUck6k0W5pli5Yg
-LXYejeHa-In)qLUg-U;~>
-#$LBV\^c7gJZOF(JZPiP#.j6SeVDWDqpbqlKCA!=nCg3Z~>
-#$LBV\D!1KJ_G\/J_I*W#3,[>g4n&Hqq;:uJaVg;nC^*X~>
-#$LBV\^d1YJ`_OGJ``ro#4)<BeVDWDqpbqlKCA!=nCg3Z~>
-#$LBV\^c7g\Z?$K20H"%O$#m_XF[I(XSJq%]'e2#LXYejeHa-In)qLUg-U;~>
-#$LBV\D!1K\_7:?7$ZK[[S0hTg4@t/gA0G,ir@lhL=5Yig'>fPmcqOUfg1,~>
-#$LBV\^d1Y\`O-R8"Jf)^ee?gk(2ZGk5"-Dli5YgLXYejeHa-In)qLUg-U;~>
-#$LBV\^c7g\Z>g9NVojX4FsSbXF[JKX9Q9(f@>Z*nb^iAa+NjD_!p&EJ,~>
-#$LBV\D!1K\_7(+ZM`DV9S(oKg4@uRg'6R:hV*_4o)%,GbCT*H^@9fAJ,~>
-#$LBV\^d1Y\`Np=]_pml:k@b[k(2[jjp(/Og!tl,nb^iAa+NjD_!p&EJ,~>
-#$LBV\^c7g\Z>g9NVojX4FsSbXF[JKX9Q9(f@>Z*nb^iAa+NjD_!p&EJ,~>
-#$LBV\D!1K\_7(+ZM`DV9S(oKg4@uRg'6R:hV*_4o)%,GbCT*H^@9fAJ,~>
-#$LBV\^d1Y\`Np=]_pml:k@b[k(2[jjp(/Og!tl,nb^iAa+NjD_!p&EJ,~>
-#$LBV\^c7g\Z>g9NVojX4FsSbXF[JKX9Q9(f@>Z*nb^iAa+NjD_!p&EJ,~>
-#$LBV\D!1K\_7(+ZM`DV9S(oKg4@uRg'6R:hV*_4o)%,GbCT*H^@9fAJ,~>
-#$LBV\^d1Y\`Np=]_pml:k@b[k(2[jjp(/Og!tl,nb^iAa+NjD_!p&EJ,~>
-#$LBV\^c7g\Z>g9NVojX4FsSbXF[JKX9Q9(f@>Z*nb^iAa+NjD_!p&EJ,~>
-#$LBV\D!1K\_7(+ZM`DV9S(oKg4@uRg'6R:hV*_4o)%,GbCT*H^@9fAJ,~>
-#$LBV\^d1Y\`Np=]_pml:k@b[k(2[jjp(/Og!tl,nb^iAa+NjD_!p&EJ,~>
-#$LBV\^c7g\Z>g9NVojX4T2>^>A\qmJZOF(s/ZF9map!Ee+*=c#KMJckJ6T@6@]~>
-#$LBV\D!1K\_7(+ZM`DV9`<ZGF,GP&J_G\/s4R\:s5)Iaddm:h#Kq\dlFuc@6%A~>
-#$LBV\^d1Y\`Np=]_pml;#TMWH'3a@J`_OGs5jOOs4PqXe+*=c#KMJckJ6T@6@]~>
-#$LBV\^c7g\Z>g9NVojX4T;D`Pp:'qXF[I(XT,@+]'e2#LXYejeHa-In)qLUg-U;~>
-#$LBV\D!1K\_7(+ZM`DV9`E`I]e"tjg4@t/gAfk2ir@lhL=5Yig'>fPmcqOUfg1,~>
-#$LBV\^d1Y\`Np=]_pml;#]SYa=iU*k(2ZGk5XQJli5YgLXYejeHa-In)qLUg-U;~>
-#$LBV\^c7g\Z?$B13K\"O$#K&X9!-CJZOF(JZSjP#.j6SeVDWDqpbqlKCA!=nCg3Z~>
-#$LBV\D!1K\_7:45F'sV[S0<mg&["QJ_G\/J_L+W#3,[>g4n&Hqq;:uJaVg;nC^*X~>
-#$LBV\^d1Y\`O-G6_3B%^edf*joLQkJ`_OGJ`cso#4)<BeVDWDqpbqlKCA!=nCg3Z~>
-#$LBV\^c7gJZOF(JZPiP#.j6SeVDWDqpbqlKCA!=nCg3Z~>
-#$LBV\D!1KJ_G\/J_I*W#3,[>g4n&Hqq;:uJaVg;nC^*X~>
-#$LBV\^d1YJ`_OGJ``ro#4)<BeVDWDqpbqlKCA!=nCg3Z~>
-#$LBV\^c7gXK2H"T_PSnVk0KZXK87unZ2ekSu[FDJZPZK#.j6SeVDWDqpbqlKCA!=nCg3Z~>
-#$LBV\D!1KXP*^(bP9creB,h`g=k!,n_+&qak;7!J_HpR#3,[>g4n&Hqq;:uJaVg;nC^*X~>
-#$LBV\^d1YXQBQ?f(eA4i7-98k2tL[n`Bo4eE)8DJ``cj#4)<BeVDWDqpbqlKCA!=nCg3Z~>
-#$LBV\^c7gXK2GR-MXYI>"M;LXK5QcnZ2eW+.n+cJZPZK#.j6SeVDWDqpbqlKCA!=nCg3Z~>
-#$LBV\D!1KXP*]N0_j?,Ea;t^g=gPSn_+&X-d%"oJ_HpR#3,[>g4n&Hqq;:uJaVg;nC^*X~>
-#$LBV\^d1YXQBPc1\g);G[b.#k2pm&n`Bno.Fj"3J``cj#4)<BeVDWDqpbqlKCA!=nCg3Z~>
-#$LBV\^c7g];uR=RB3?RWM#cRQ_gdbUmI`:ri?d%Q`@-aQSk,%XK7nEU9(8ZV3dbPX9k\hTWG5n
-Q^gX>JZOF(UoXd3map!Ee+*=c#KMJckJ6T@6@]~>
-#$LBV\D!1K]@mhB_V3SUf#u(U^X:chd(datrn8%'^Y%8g^I,cYg=jNEc.^[^dD*d%g'Q*?bM(\#
-^VsI#J_G\/UtQ%4s5)Iaddm:h#Kq\dlFuc@6%A~>
-#$LBV\^d1Y]B0[Yc0"!-imuN-b1u.AgWJ)DroOm=b2h^@a[XG'k2t$qf]M,7gre+FjpBebf&l,R
-b0XSIJ`_OGUuhmIs4PqXe+*=c#KMJckJ6T@6@]~>
-#$LBV\^c7g]<!iC-`ijdP^+?N;-0iu=&DsIXK7"O;/`Ot;&iGUXK5q^O0"]n;,L;SXJf2t<L^(%
-;,\g6JZOF(UoXd3map!Ee+*=c#KMJckJ6T@6@]~>
-#$LBV\D!1K]@o*@1>9c(]UC3aB5cJSDJ*cCg=iB:B8tWSB-_,Sg=h$6[G&DIB4l"hg=:(RCrP+[
-B500DJ_G\/UtQ%4s5)Iaddm:h#Kq\dlFuc@6%A~>
-#$LBV\^d1Y]B1rU2!34D`hFo&Cj"k!FDPtWk2rgaCmF/!CaNtgk2qCX^ZN]lCi"(,k2:>tEmWs*
-Ci;,[J`_OGUuhmIs4PqXe+*=c#KMJckJ6T@6@]~>
-#$LBV\^c7g\uZc3XK5BcX>HTO4f_AHXIhAOPY$do??N?N4T)8p=c]Yc8rB]nENDl_O+B]3JZP\1
-T7O(pXJDp%]'e2#LXYejeHa-In)qLUg-U;~>
-#$LBV\D!1K]%S#qg=g;Sg-Ws9:"a'og;u_9]3VYLGEgh89`3TYEOFNS?E`(KOP408[\QrVUY=*g
-b(88tg8*F,ir@lhL=5Yig'>fPmcqOUfg1,~>
-#$LBV\^d1Y]&jl,k2pX&k!dh_;<;Q;k0uo``aZNpI@TH^;#KGiGJE;&A%:ZmR-&%Z^o^guXQJ;7
-eUck6k+q,Dli5YgLXYejeHa-In)qLUg-U;~>
-#$LBV\^c7g\uZ9%XK5BcX?<Sc4f^^EX91SdN\:<6",j7^4T)8f=c]Yc8tN,-END/!=U&D=OK>NT
-T7O(pXJDp%]'e2#LXYejeHa-In)qLUg-U;~>
-#$LBV\D!1K]%RNcg=g;Sg.^5S:"`5>g&k%&Zo\2*"0pS69`3TOEOFNS?HCidOP32'E!Cf1[bBG?
-b(88tg8*F,ir@lhL=5Yig'>fPmcqOUfg1,~>
-#$LBV\^d1Y]&jAsk2pX&k"t4&;<:XRjo\HB^-;O?"1mXW;#KG_GJE;&A(0S3R-%$?G6WeF_<0lg
-eUck6k+q,Dli5YgLXYejeHa-In)qLUg-U;~>
-#$LBV\^c7g\uZfGLjL.jQnP&)0U%l,Lh@ftW+LL7FF^'?08]\0)377,S"r*"XC#/4QWf3$>G5/T
-Fr?(:X@Z-;XF[IOX9Q9(f@>Z*nb^iAa+NjD_!p&EJ,~>
-#$LBV\D!1K]%S'5XILT.^c]]^4hJOMXF_h:eUjEpPG6:&4Ke\;)7E\/`6_,Vg3@Yl^N-EWFN\X)
-Q6<9_g0J0=g4@tVg'6R:hV*_4o)%,GbCT*H^@9fAJ,~>
-#$LBV\^d1Y]&joG[A>7Jb<OJ-5fLrk[>HEWiJFM@S#b/K5Ig^T)8KRFceD4%k'qX<b'CD&HIm>J
-Sg(T)k$htSk(2Znjp(/Og!tl,nb^iAa+NjD_!p&EJ,~>
-#$LBV\^c7g\uZgF?u:U:JmaV(@!\o8@"E<NXK6/EFKCa8?tB8<)/rtkLmqdpXCG\?XH$[rS?/;i
-Ee&;6N>m7rXF[IOX9Q9(f@>Z*nb^iAa+NjD_!p&EJ,~>
-#$LBV\D!1K]%S(JHA\\^UjBD]HCNWrHD?P"g=h=.PM3]rH@GkI)39)iXi5UNg4"D&g9c0P`nJL[
-OJA&oZQbrkg4@tVg'6R:hV*_4o)%,GbCT*H^@9fAJ,~>
-#$LBV\^d1Y]&jpbJW[7(Xb"4-JYVABJZP3Ck2q\TS*%bBJVF*c)4#i)[a0Mpk(J?Kk.Q=sdH8o/
-R&lh?]d0G*k(2Znjp(/Og!tl,nb^iAa+NjD_!p&EJ,~>
-#$LBV\^c7gKrb<-GCciHXJ`-(]'e2#LXYejeHa-In)qLUg-U;~>
-#$LBV\D!1KL"ZR)Q\!kAg8EX/ir@lhL=5Yig'>fPmcqOUfg1,~>
-#$LBV\^d1YL#rE?T7Q-Uk,7>Gli5YgLXYejeHa-In)qLUg-U;~>
-#$LBV\^c7gJZOF(JZPiP#.j6SeVDWDqpbqlKCA!=nCg3Z~>
-#$LBV\D!1KJ_G\/J_I*W#3,[>g4n&Hqq;:uJaVg;nC^*X~>
-#$LBV\^d1YJ`_OGJ``ro#4)<BeVDWDqpbqlKCA!=nCg3Z~>
-#$LBV\^c7gXK2GgJ,$)MRWs(LXK7V\nZ2neGc7^6Rt7YlXJ`-(]'e2#LXYejeHa-In)qLUg-U;~>
-#$LBV\D!1KXP*]hU%m=H_jQq7g=j-an_+/iRFU$1`.?Wng8EX/ir@lhL=5Yig'>fPmcqOUfg1,~>
-#$LBV\^d1YXQBQ)Wqb]]cCpr]k2sY:n`C#+U#G.\c[k50k,7>Gli5YgLXYejeHa-In)qLUg-U;~>
-#$LBV\^c7gXK2Gc0DMUR:2b'@XK5QcnZ2nc0;#>6:P#TuXJ`-(]'e2#LXYejeHa-In)qLUg-U;~>
-#$LBV\D!1KXP*]c48@M7@uZJfg=gPSn_+/f4NcBpA:`Hcg8EX/ir@lhL=5Yig'>fPmcqOUfg1,~>
-#$LBV\^d1YXQBQ$55=7FBpFt2k2pm&n`C#(5Lno?C4YMuk,7>Gli5YgLXYejeHa-In)qLUg-U;~>
-#$LBV\^c7g];uR-Gc[WZUl0bZEL3c.Q#V[Dri?cYEMon,E@5a^XK6hhU9'u,QZ7ZWX:1>5Mla"R
-EILKOXK4O8XF[INX9Q9(f@>Z*nb^iAa+NjD_!p&EJ,~>
-#$LBV\D!1K]@mh-R+fiHd'07HO2'E&]oT?jrn8$RO42h#O"uctg=i0[c.^:#^lPAlg'kWTYhIgT
-O.]b#g=f5Og4@tUg'6R:hV*_4o)%,GbCT*H^@9fAJ,~>
-#$LBV\^d1Y]B0[CT]XpogUaGoQceIQa-X>5roOlfQf$rNQSk,<k2rV.f]L\Mb*T=2jp]7r]&r/,
-Q`4EDk2oKkk(2Zmjp(/Og!tl,nb^iAa+NjD_!p&EJ,~>
-#$LBV\^c7g]<!uX0W_$1P`?YiG>,'4;g2OmXK-5WG?h,;G:IfqXK7";O0#!17sAEpXJ/[<?')$f
-GA8"fXK4[cJZOF(W2p37map!Ee+*=c#KMJckJ6T@6@]~>
-#$LBV\D!1K]@o6Y4ke4R]X8o.QXSRnBpX#qg=V@DQZ^p"QSk,7g=iAu[G&ei>*jZ8g<FB!G.6%A
-Q\HX*g=fHSJ_G\/W7hI8s5)Iaddm:h#Kq\dlFuc@6%A~>
-#$LBV\^d1Y]B2)o5j$cp`kNaKT4[3=DkDG2k2_blT7#YFT/`ITk2rgE^ZO*8?_<"Uk1FXFI)4cb
-T8b&Fk2o_&J`_OGW9+<Ms4PqXe+*=c#KMJckJ6T@6@]~>
-#$LBV\^c7g\uZ9%XK5BcX?<Sc4f^^EX9q(kN]1Zd:2-f24T)8f=c]Yc8tN,-END/!BaQIpOK>NT
-T<,,DBn<@:XJi3)]'e2#LXYejeHa-In)qLUg-U;~>
-#$LBV\D!1K]%RNcg=g;Sg.^5S:"`5>g'UO-Zpf\&@tiXj9`3TOEOFNS?HCidOP35(KaKkZ[bBG?
-b1bRCKn7s/g8N^0ir@lhL=5Yig'>fPmcqOUfg1,~>
-#$LBV\^d1Y]&jAsk2pX&k"t4&;<:XRjpFrI^.F<DBT2*9;#KG_GJE;&A(0S3R-%'@N=%jm_<0lg
-e`Q"oN.L,Bk,@DHli5YgLXYejeHa-In)qLUg-U;~>
-#$LBV\^c7g\uZc3XK#!ZX?<Sc4f_#HXJS"ZO[4DFH^1\64T)8s=c]Yc8tN,-ENDKMIt)iQM6*[C
-T<,+Vr2]plV1G_!XKJW/]'e2#LXYejeHa-In)qLUg-U;~>
-#$LBV\D!1K]%S#qg=KcGg.^5S:"`Uog<rOG\5SumS@mS09`3T\EOFNS?HCidOP3["TqS$%XkM?*
-b1bQCr7V1pd=L#&g90-6ir@lhL=5Yig'>fPmcqOUfg1,~>
-#$LBV\^d1Y]&jl,k2U'nk"t4&;<;':k2&eo_H3Y7UrVW[;#KGlGJE;&A(0S3R-%PCWMu_D\)u[Q
-e`Q!jr8n%2gk"U=k-!hNli5YgLXYejeHa-In)qLUg-U;~>
-#$LBV\^c7g\uZf[@U:<jJg-5@,($7e@TXY)XEe,]>_\MP,%^bT(i_<.M45u4X@>LWVc7,7?*%CB
->T[mcX??E^!@(TqXF[IUX9Q9(f@>Z*nb^iAa+NjD_!p&EJ,~>
-#$LBV\D!1K]%S'OI!72lV(8pe/=Y1)HuC=1g7!86FK3$$.tIWQ(m%!qXi3/Ug0%>-e7sAYG1q1g
-FXW4&g._Fu!A&&<g4@t\g'6R:hV*_4o)%,GbCT*H^@9fAJ,~>
-#$LBV\^d1Y]&jobJpf>,Xt@B//u7HFJorHHk+[<VHF(\E/r0Gg(mm^-\'R*tk$;'Nhf+1!I-,p1
-HRb9Bk"u!<!A8DDk(2Ztjp(/Og!tl,nb^iAa+NjD_!p&EJ,~>
-#$LBV\^c7g\uZgJL5hU]Q\M')L6J^0L6msgXK7>7OK>.1L5>i1(lj?*R\Y\"XGDY5XIY*#Uo^DI
-O-Yp0V*k3_!cKQVJZOF(Y,hi=map!Ee+*=c#KMJckJ6T@6@]~>
-#$LBV\D!1K]%S(PWj9IJ^T,>uWk7!+WkYsXg=ig3\(]$*WiZ3R(pp<C_p>?lg8q@/g;g4nd+ZmI
-[D'-(d8g/!!f](SJ_G\/Y1a*>s5)Iaddm:h#Kq\dlFuc@6%A~>
-#$LBV\^d1Y]&jph[(OVsb-]UK[)M1V[)p),k2s7^_<0@V['otr(r!AacJ,_Bk-_SYk0gWDgudG"
-^WF=Sh-0d>!gPaiJ`_OGY3#rSs4PqXe+*=c#KMJckJ6T@6@]~>
-#$LBV\^c7gKrb<9Nr?$[K:7@mJZPuT#.j6SeVDWDqpbqlKCA!=nCg3Z~>
-#$LBV\D!1KL"ZR9[/J\ZVo+)>J_I6[#3,[>g4n&Hqq;:uJaVg;nC^*X~>
-#$LBV\^d1YL#rEO^A[0pYg.g^J`a)s#4)<BeVDWDqpbqlKCA!=nCg3Z~>
-#$LBV\^c7gJZOF(JZPiP#.j6SeVDWDqpbqlKCA!=nCg3Z~>
-#$LBV\D!1KJ_G\/J_I*W#3,[>g4n&Hqq;:uJaVg;nC^*X~>
-#$LBV\^d1YJ`_OGJ``ro#4)<BeVDWDqpbqlKCA!=nCg3Z~>
-#$LBV\^c7gpoFI9aK,A^aK,A^JZOF(VlU*6map!Ee+*=c#KMJckJ6T@6@]~>
-#$LBV\D!1Kpt>_0aP$WUaP$WUJ_G\/VqM@7s5)Iaddm:h#Kq\dlFuc@6%A~>
-#$LBV\^d1YpuVRDaQ<JiaQ<JiJ`_OGVre3Ls4PqXe+*=c#KMJckJ6T@6@]~>
-#$LBV\^c7gq5aU@EW3$?QXB`n"BIN/4!i[`!)!-i!*&Qk"C3<94F?\$!`UY5poFL8LA7hNE#+#+
-JZPcN#.j6SeVDWDqpbqlKCA!=nCg3Z~>
-#$LBV\D!1Kq:Yk9O8di6^j5q5"Dp[^8h\uR!+,QV!,M2["ElFl9Ut_.!bsU(pt>b/Wqb9KNZ<W(
-J_I$U#3,[>g4n&Hqq;:uJaVg;nC^*X~>
-#$LBV\^d1Yq;q^MQi?+Jb(0KR"ER6k:,1Pd!+buh!-.Vm"FMq#:o*^F!cU-;puVUC[.rbaQ6(V>
-J``lm#4)<BeVDWDqpbqlKCA!=nCg3Z~>
-#$LBV\^c7gq5aU8H2alGPZ7X`/4lI"V`_%nEhZ3oXI2^SK<0!+CJ0bjXFNr:?EC5L91u:dXJJQj
-J!t^&94Rt&!DH8fX:Lss97<mb@rY/!XJJ:cX??K`#?OQnXA=^H:]7@'=c]YM94b2"9<>4-JbZ;I
-HTZk\JZPcN#.j6SeVDWDqpbqlKCA!=nCg3Z~>
-#$LBV\D!1Kq:Yk/RJtn@]P@H"/6p=rdnJJJOj.7Lg;@9)VqR,cLL7OEg7hq]GM:c5?XMI>g<j8E
-Tu3?C?[_q-!FTF:g(2A6?_5u:IZRp>g<imRg._M"#B*tqg17BoAGt3jEOFN8?\$j?@+s=eU\NOD
-S4nLfJ_I$U#3,[>g4n&Hqq;:uJaVg;nC^*X~>
-#$LBV\^d1Yq;q^BUAj9U`c1q>/7I(1hb`HmRFu,pk07FIYi_11O(?)hk,W$'IHK[[A7Xc`k1sQh
-Wm.=aA;'sE!G,sDjq$$RA>eR\KpZD\k1s2&k"u'>#BaS3k%VA:CAm9'GJE:^A;B;]A`i-4XSCoY
-V,2a*J``lm#4)<BeVDWDqpbqlKCA!=nCg3Z~>
-#$LBV\^c7gq5aU+LAn7TRVVo(/>K73VkU8[1KL&SXC.Ti8ti!rI@W[*Ro#ZH=0.O,SXi3NRoQ#B
-+H*$SSY?%a0V(/(XI3.\SSN_N*d4)?X//1bR89o[>`bLWRVjLDR9#u^XBCUcWC)oOD.p#PH&VL!
-!'Gh6JZPcN#.j6SeVDWDqpbqlKCA!=nCg3Z~>
-#$LBV\D!1Kq:YjsWrC]Q`/+EH/C3!Je'?[`6#FYgg3Uf[?Hg\8T>sma`+@!0DVDUca2_<9`GET*
-.C%5ga3=P:0ZQZ:g;7aJa,$G9-C2\Ng!NdQ_.D?IFgoD.`/?Ck_JRKMg2XOSelBB:MM0^;R^2\A
-!).stJ_I$U#3,[>g4n&Hqq;:uJaVg;nC^*X~>
-#$LBV\^d1Yq;q^1[/T1gcB%te/DK8fhq@/97<?n-k((n.A(TEVVp\Z/cYLtWFQUH2daDF`cZ7IO
-/%aS.db"K\0[`SUk0.qqdZ:E_.%\jgjkX)%b\H:qHbn-OcBC*5b]D@tk'+T&i`a@aOc/AaU:^0^
-!)S7/J``lm#4)<BeVDWDqpbqlKCA!=nCg3Z~>
-#$LBV\^c7gq5aU%NVBLY6)UfcU+;`4X<*`r6QDc#4KPVHXJK#d6_(6ZDF6cPXDE9cXGrjR4Su2_
-4KPVoL&S.u4KLZHX?EV\)FIGoXH"Mm6S`A#E3--SJ?5hTO0#F;@]WLno;hpSJZOF(VlU*6map!E
-e+*=c#KMJckJ6T@6@]~>
-#$LBV\D!1KqUu#(FL(Yp##j")g<DOprn8F0<E19eg.^5S9\Rm4<E7&mg5K$38_Sukg=imUg._Ct
-"AIP'IB!5",>?fbg=f9Sd32M)a4dmO<E28;Q]BeRKVI2SEOFNSWI3E6^%9qX9S(oKg8EX/ir@lh
-L=5Yig'>fPmcqOUfg1,~>
-#$LBV\^d1YqW7k@HG'"7#$9^Ek1McAroP9F>$<6'k"t4&;!-PU>$B>9k*&tP:?IY8k2s>,k"ts;
-"An7CKX1U>,>dN!k2oP&h'6*BdcS7s>$=7OTU+a&MlZ"&GJE;&Z\.CYa7JEn:k@b[k,7>Gli5Yg
-LXYejeHa-In)qLUg-U;~>
-#$LBV\^c7gq5aU8H2"BD6)UfcU.5*_+[;fj0;,C/XK4OcVMq@J5HKNKV1Uk2Iqc!cPbP6AXIkjY
-X<]p0XEe`cXH?Sc4KPVIX//(XG]BgO<1]qQQ$?'*Wa1UcXBCV`X9)4B>kkB$OG!M5!'L1\!J6Gb
-XF[IUX9Q9(f@>Z*nb^iAa+NjD_!p&EJ,~>
-#$LBV\D!1Kq:Yk/RJ5D=;q'ISbujqu+]-S&43Q>Og=f6Se$@BK:thjtdAKXkTnM.R]?T&'g<%,/
-g*BAGg7!uSg:2%S9\S2pg!N[EQ]Kk9C<4f;]U*-^f64LSg2XP"g&blQFnjYk[\s)X!)3=E!N!;W
-g4@t\g'6R:hV*_4o)%,GbCT*H^@9fAJ,~>
-#$LBV\^d1Yq;q^BUA*dR=5W0&fj4R=+][=A5M"snk2oM&hRhRu<T^Q@gosT:Wf6*&`S'BMk1.WR
-js3dck+\+&k/)6&;!-n;jkWqlTU4faE7<Uba.R,.j*\Q&k'+T>joT=kHhc_(^p*e"!)WUU!Ns:j
-k(2Ztjp(/Og!tl,nb^iAa+NjD_!p&EJ,~>
-#$LBV\^c7gq5aU8H2+HG6l.n=XB?E2riAn74@h,,Aeg)R'l'-V4?R_eSl.[V(5T&?4?QT:XDU-l
-PcUrL'g.MXGW\)iUhpirM\T]+(QPS@ENG-e4A(l`8N]1mXK5AC13]h$S1CK3X8u-Gri?2d'g.HS
-X8sPGJZOF(Y,hi=map!Ee+*=c#KMJckJ6T@6@]~>
-#$LBV\D!1Kq:Yk/RJ>J@<ujo5g2S3<rn:/.9O'\tJK(Ye)hu3S9MCZ(aCe1i*3@kd9MB6Gg5J^1
-]\;(7)bdTlQqU1kd#/j:YT%t4*jjXfOP7$@9O5>u>te%qg=g9i5F:*X`])?@g&Ye@rn7HN)bdO9
-g&Wa@J_G\/Y1a*>s5)Iaddm:h#Kq\dlFuc@6%A~>
-#$LBV\^d1Yq;q^BUA3jU>9?VIk'%tUroR"B:glS1L`Eh+*0/8i:f*\Edqqp0*k(40:f)/`k*/\O
-`ocD]*)O?2TMSI,gQEPV\K-<L+26m0Qfbta:h%J<@Sg"3k2pV46_EN'd5p.ZjoK6TroO;_*)O9H
-joI)TJ`_OGY3#rSs4PqXe+*=c#KMJckJ6T@6@]~>
-#$LBV\^c7gq5aUMA$)g5G]<AX!IeeYX9+>'TD5Jg?9s.DJZPuT#.j6SeVDWDqpbqlKCA!=nCg3Z~>
-#$LBV\D!1Kq:YkJI]_<)Q]Cdn!MG2Bg&eQ/anXQjGZ'+HJ_I6[#3,[>g4n&Hqq;:uJaVg;nC^*X~>
-#$LBV\^d1Yq;q^_KrsJ<TU,<6!ND+SjoW.FeG//,ITD$^J`a)s#4)<BeVDWDqpbqlKCA!=nCg3Z~>
-#$LBV\^c7gpoFIQXfMRY.V&7T")KS<W;3LqU6PDR!L9C1XF[ITX9Q9(f@>Z*nb^iAa+NjD_!p&E
-J,~>
-#$LBV\D!1Kpt>_OXkEh?21G>S",T&pebRo"cF`i)!PH[.g4@t[g'6R:hV*_4o)%,GbCT*H^@9fA
-J,~>
-#$LBV\^d1YpuVReXl][N3/%(h"->](iVDU:fuEdK!QWiDk(2Zsjp(/Og!tl,nb^iAa+NjD_!p&E
-J,~>
-#$LBV\^c7gJZOF(JZPiP#.j6SeVDWDqpbqlKCA!=nCg3Z~>
-#$LBV\D!1KJ_G\/J_I*W#3,[>g4n&Hqq;:uJaVg;nC^*X~>
-#$LBV\^d1YJ`_OGJ``ro#4)<BeVDWDqpbqlKCA!=nCg3Z~>
-#$LBV\^c7gJZSIE!L[BlX<aa7U9'lUXK%e\Uo^>]VQ?M^Vl#uZXK8%aS>E<gSXcdTS>`:_S,fR?
-XF[J=X9Q9(f@>Z*nb^iAa+NjD_!p&EJ,~>
-#$LBV\D!1KJ_K_L!Q09[g*G1fc.U+Xg=XEbd+Zgcdb;sceC)@_g=j]h`mNMoa2ZiW`mrK8`W4VA
-g4@uDg'6R:hV*_4o)%,GbCT*H^@9fAJ,~>
-#$LBV\^d1YJ`cRd!R65ljs8m4f]CN0k2aq;gud><hWEM=hqlc7k2t4AdG<sIda@40dGWjZd/`3X
-k(2[\jp(/Og!tl,nb^iAa+NjD_!p&EJ,~>
-#$LBV\^c7gJZSLF!g$,Hq5c$,*''uO5-/]s9NIj2)MP81)NKSB8Z]"!,sd*`X?&);Af[(e)GEgM
-Q@Z,gXQuql]'e2#LXYejeHa-In)qLUg-U;~>
-#$LBV\D!1KJ_KbM!k2TAq:[:,,=pEK:>1\8?u=,R+fX1S+ge:P?/""U/lSS"g.=K^JL.n(+^e\1
-^4G!hg?[Gsir@lhL=5Yig'>fPmcqOUfg1,~>
-#$LBV\^d1YJ`cUe!l8JUq;s-B,u!;_;Wa6UATQLr,I6Hq,JCKj@clg#0itL>k"S/'M'p6E,@tF?
-aFWK)k3M.6li5YgLXYejeHa-In)qLUg-U;~>
-#$LBV\^c7gKrbr54?S"mWbjj\6EEOd69L^<SsDnAX;O65JSTXSFf_[4:96mZXIW"cXAN8_XK5?b
-ri?KPDlfd&XK4OcSR._8XF[J=X9Q9(f@>Z*nb^iAa+NjD_!p&EJ,~>
-#$LBV\D!1KL"[3/9MD&3f8<6q<8(?'<(t3`ahM$Sg)3_:UPPM)PhOj.A(k&1g;dRSg1GN7g=g;S
-rn7aJNS;c[g=f6Sa*>FOg4@uDg'6R:hV*_4o)%,GbCT*H^@9fAJ,~>
-#$LBV\^d1YL#s&C:f+%Oj,m/7=lrnE=A[<*eB)(mjr%-QXH9<JSEAtYC$&^Sk0df&k%oIZk2pX'
-roOT^Q0-n*k2oM&dXKDkk(2[\jp(/Og!tl,nb^iAa+NjD_!p&EJ,~>
-#$LBV\^c7gKrbr.XK4OcRSKrcEiamJVQ;n]XJ&/ZX9LnJ=_iCqK`8%`4KO*HX?NYcN*M*HXK5?b
-ri?ENDlfd&XK4-Z/V1!SXQcej]'e2#LXYejeHa-In)qLUg-U;~>
-#$LBV\D!1KL"[3&g=f6S`+%HSOkQ]sdb7CKg<<aqg'1BYEJU38VuGB\9\Q:og.p;SZ?3*og=g;S
-rn7[HNS;c[g=e`13J#n8g?I;qir@lhL=5Yig'>fPmcqOUfg1,~>
-#$LBV\^d1YL#s&:k2oM&c=lA&RHC_>hW@Ysk1<u8jp"esGEA\UZ2Wkr;!+m:k#1:&]R-u;k2pX'
-roON\Q0-n*k2o!S4b;aHk3;"4li5YgLXYejeHa-In)qLUg-U;~>
-#$LBV\^c7gKrbr04?ORaWG4OXL9-#<XK4OcXJ&/ZX9Lng:KW!TK`8%o4KPAPH=j7Z@l-;(S?,YR
-XG:kADlfd&XK4CB9:Vr3XF[J=X9Q9(f@>Z*nb^iAa+NjD_!p&EJ,~>
-#$LBV\D!1KL"[3(9M?\beqQjlWnOA#g=f6Sg<<aqg'1C)A8n,hVuGBk9\Rm$Rt9;HI6pUn`S,(>
-g8pI*NS;c[g=f')?cLWIg4@uDg'6R:hV*_4o)%,GbCT*H^@9fAJ,~>
-#$LBV\^d1YL#s&<:f&J#if-c2[-"TIk2oM&k1<u8jp"fEC3HJ.Z2Wl,;!-PDUP\-pKLSd+d,o;f
-k-^YOQ0-n*k2o=OAC0:dk(2[\jp(/Og!tl,nb^iAa+NjD_!p&EJ,~>
-#$LBV\^c7gKrbqMXG\:(UO'#C4KO0GXK4OcXJ&/ZX=QT8VZ;+%?EC5WC94L`<KF5Y6EI8T;63]\
-XFOu/Dlfd&XK4OcXAY@cPYnB1XF[JAX9Q9(f@>Z*nb^iAa+NjD_!p&EJ,~>
-#$LBV\D!1KL"[26g9<*]cC<PA9\QCog=f6Sg<<aqg+6(Oe,Z)DGM:cDL>(@PCUMmF;qfs?BA.+5
-g7j7gNS;c[g=f6Sg1\4S]P#cGg4@uHg'6R:hV*_4o)%,GbCT*H^@9fAJ,~>
-#$LBV\^d1YL#s%Fk.3/,fq[]l;!,!:k2oM&k1<u8jt'KkhuKXaIcfdkNooK#EPLYm=Q\bgD!#]W
-k,XE6Q0-n*k2oM&k&/9&`bj[ck(2[`jp(/Og!tl,nb^iAa+NjD_!p&EJ,~>
-#$LBV\^c7gKrbu74C(KlShN8hNN>K'Uh267K/tYVqQ('`/n(etLTHV#4DLkpX<(BCXBmPKHoWoD
-0f_?SGG\V-5bG-)/j)6NS#g3<VLbh"XRE4p]'e2#LXYejeHa-In)qLUg-U;~>
-#$LBV\D!1KL"[619QjZqaZW<kZJ&;Ed"+6YVFisTqUu=^4*oS;X4k'W9SV-tg)b(ag3>\\SOl"=
-5"J@9QdTtL;9@O^3_W42`7fb`dt-5(g@*`"ir@lhL=5Yig'>fPmcqOUfg1,~>
-#$LBV\^d1YL#s)F:jc]2e3Hi,]]NBcgk\,$Y>.;iqW80t5(VgX[H>>&:laQ7jrSR*k'fL!VG0?Q
-5tk*HTA=ij<Rp6.4]"s@cfU$*hgsp@k3qF:li5YgLXYejeHa-In)qLUg-U;~>
-#$LBV\^c7gJZQSe!@a(\XF[J@X9Q9(f@>Z*nb^iAa+NjD_!p&EJ,~>
-#$LBV\D!1KJ_Iil!Ah08g4@uGg'6R:hV*_4o)%,GbCT*H^@9fAJ,~>
-#$LBV\^d1YJ`a]/!B.`Ek(2[_jp(/Og!tl,nb^iAa+NjD_!p&EJ,~>
-#$LBV\^c7gJZS=A!1WmK!*n-W!2G+HJZS7?#.j6SeVDWDqpbqlKCA!=nCg3Z~>
-#$LBV\D!1KJ_KSH!6"e/!-QoI!7-5MJ_KMF#3,[>g4n&Hqq;:uJaVg;nC^*X~>
-#$LBV\^d1YJ`cF`!71R>!.3>[!8<"dJ`c@^#4)<BeVDWDqpbqlKCA!=nCg3Z~>
-#$LBV\^c7gJZOF(JZPiP#.j6SeVDWDqpbqlKCA!=nCg3Z~>
-#$LBV\D!1KJ_G\/J_I*W#3,[>g4n&Hqq;:uJaVg;nC^*X~>
-#$LBV\^d1YJ`_OGJ``ro#4)<BeVDWDqpbqlKCA!=nCg3Z~>
-#$LBV\^c7gKWG6U@>sfZ!/^TS!E#<XX8n:[Fo[s%X9+6%S,KDh?'"?R!^Af*ri?0s>+5Gl!/^ZU
-!etljpoFIPqlBc_o;hqBrcS:>o;i"?G,b8<!Ka./XO=0S]'e2#LXYejeHa-In)qLUg-U;~>
-#$LBV\D!1KK\?L\Ha31r!3Z4Q!GB@Cg&SMZQ2neng&eFC`VnKkG.$\j!`2Rprn7G#El7n1!3Z:S
-!ihR.pt>_Nqq;$Io@a2>rg!Q5o@a89QIkoc!OgC,g="[Zir@lhL=5Yig'>fPmcqOUfg1,~>
-#$LBV\^d1YK]W?tK"LX:!4Vjf!H$0TjoE-pScI"+joW#`d/E)-I)#%1!`W"-roO:;Gg?<N!4Vph
-!jeKJpuVRcqrRlYoB$%Srgj,IoB$+NT&]V.!PmNBk0iArli5YgLXYejeHa-In)qLUg-U;~>
-#$LBV\^c7gKWG3S55qY_X8T.!Ws#N)40,F]X9,G\VZ*[rWrT7!Wsl(g-us?'X/rD'X/rE$X8]1%
-L.caiX9,G`UA_1nX8]4"X8&ar4T)8]PZ7U_!'L4]!eNdjrN-"!"K\XcX/l6$!NUqQXT#7#XSo4"
-X9<9!EcPFaXT,@$XSo4!X93YuUoaQr#-=l+XK5<cJZR;$#.j6SeVDWDqpbqlKCA!=nCg3Z~>
-#$LBV\D!1KK\?IY:]B&Lg"=sUgAfh)f`Fh!f`'S+fW`g'gAfeAg"P-3g">!3YqhE&A(]Mhg">$4
-f\+p0rn7FR?C1ZF!nk!+rRq;)g&B_)f_F/#9`3TF]5.B!!)3@F!i8nmrRqM/g"G*49A%qsg&]j)
-rS%;(!SQ3+fa$0`g4r7]OELQVs4IA*"5);Zf`'S6QT<FHg">!3f\"p3BYK&Odb4obs5)Iaddm:h
-#Kq\dlFuc@6%A~>
-#$LBV\^d1YK]W<q;uYn\jlGM$k5XNAjT86=jSn9CjLO.Hk5XKYjlY[cjlGOc]/>tCC#nF=jlGRd
-jQ5I`roO9gA=rk`!p%,KroO:DjQ6C'roEk:!)WUU!QB'WjoA6VjoV\hXo7D^j9=Z-j\Ot!roO7B
-Z2Nhbj8nB)roFCGk2q[uR$`7"k5XNBjoa]+jQ-=&%A,c;k2k[ck2bUck&/7kk0iArli5YgLXYej
-eHa-In)qLUg-U;~>
-#$LBV\^c7gKWGie5-1i_=?SfgXK74D4\BgK'g5.fX<:7XR]NTE5!;`3IN)BP<hl`YXK4UcXHcFA
-CTL#d6p5kqX9!<bri?0%+HHH&$"lCpQ`P["4X,[WX8kB\X9"PbrN#u]rN$'p7Qg[O%<"C$/tlkl
-4_CdsTKO\%X;bk:4^G*q.SDp>XH6PcX?<ScKg%_UUE`Su7ZRJL$q-nmL)"Br,<i31;O2m8d]<Ya
-map!Ee+*=c#KMJckJ6T@6@]~>
-#$LBV\D!1KK\@*k:YOONE)'/jg=iZ,:0j'\)bs]<g)slM_qNhD:JPK?T-A2KDU7$1g=f<Sg:Ucf
-LtZ$'<_f+_g&[8$rn7Ei.CB*.$%ku]^Y5AV:+WLBg&OhEg&\g$rRq6FrRq=t=\ShK%?+%f3m<0p
-:4h3Rb"a\jg)G`@:3P<82.'+6g:)"Sg.^5SW(p0hcRi^'=LA(]$s(a/WZ-W:/5P!RBYK&Odb4ob
-s5)Iaddm:h#Kq\dlFuc@6%A~>
-#$LBV\^d1YK]Ws.;s*6!G#D5+k2s*R;IZ-!*E$AGjre=`cK=8p;c7DWW$HL`FP>kRk2oS&k/V"1
-O60eC>>h6qjoLg@roO9&/&)#F$&VVmb3#^%;D,BQjoA6UjoNG@rT4)VrT416?;UX`%?sb"4kGN2
-;MjPuel"@(jr97W;LISU3+PpIk.u3&k"t4&Yu=W.g+R5>?,$=#$sVKKZQ5"X/lUopDTICkdcLc"
-s4PqXe+*=c#KMJckJ6T@6@]~>
-#$LBV\^c7gKWGbpL9.JSN2*./XH-VcXB'PH4Su3*:7A8@@&pAs:TQI:XAtIc3hqC=X/JXUUNC=5
-5,G>sI&sDhGQ"TQ>)o\cB6^288?>+PUQM8GX8kB\X8uLarN$!WrN$E1Km%44E-SIW32*E9qlDG5
-XK6/cXK7@cV_4RB4KOWCUM>=\Lg$OH=c6a"XJ8dcXK4gcXK4^bX'gdcXHB?1XO=0S]'e2#LXYej
-eHa-In)qLUg-U;~>
-#$LBV\D!1KK\@#cWnQ1UZ-LWeg9u.Tg23/09`*NhA&I$'H.gogAD0G]g2"=S8^=8`g!sEBcBF*n
-:XRmQS_DeYQi5VJEjXQSK:'rr>hW-%cF;$ng&OhEg&Z9$rRq7UrRq["W0W1lNgSPD7a0R[qq<\s
-g=h:Sg=ifSe2k\)9\QsicA&(IX`D_2E3Xh@g<XTSg=fTSg=fKSfm9dSg:5R^g="[Zir@lhL=5Yi
-g'>fPmcqOUfg1,~>
-#$LBV\^d1YK]Wl!Zf^E-]@tt6k.l?&k&[0W;#BB#B[5bMJE>q<C?A((k&JB&:"lk+jl'^jg7+2>
-;r-StVWR$-TDdm^GeW>&MP8bC@HLYFg;2G;joA6UjoKb@rT4*krT4N5ZC['<Q(d?k9%`9&qrTP.
-k2qZ&k2s:&h`]HN;!,T4g5W/q[X$QXG.N?]k1an&k2on&k2ob&jajo'k/6#+k0iArli5YgLXYej
-eHa-In)qLUg-U;~>
-#$LBV\^c7gKWGQ]5-1i^=@GY0XFk']X8kB[X9;:eXF"g`X:@@o4KPVaPH5rs:QqlW)ZE/4FcT\,
-XFOucXDrI_X9DdfXK5&Zr^@!lVaX$RSb]>e4T)8]PZ7I[#EqqP79#j[Oo29\4Su2_4KPVZRf9Au
-4JtKHX?<SG,=P_2XEcAr71bPiKrh@SQ)q&TUo^Yo6_-l$XNdgN]'e2#LXYejeHa-In)qLUg-U;~>
-#$LBV\D!1KK\?gc:YOOMDc^"!g8BGug&OhDg&tp'g7+!!g($g19\S39]@nc:A@pRE+oYOMQ*tYc
-g7j8Sg5hU!g(&/1g=fn1='&MXe5o^da8+Eh9`3TF]5.5r#J+GI=)5oq\GY%\9`*NH9\S31_uA@"
-9[ltog.^50/QZl<g6t##<tMihWS6'?]\;(?d+[4$<QAHtg<J=Uir@lhL=5Yig'>fPmcqOUfg1,~>
-#$LBV\^d1YK]W[&;s*5uF^/05k-0U<joA6TjofACk+n1>jpk5M;!-n[`TAdXC;o>l,Q:pTS\TF2
-k,XF&k*M_=jplXMk2p2R>[1Rsi*9N+deW#*;#KGV`Gt_9#K1=]>]J88_YiNr;#BAX;!-nRcMlr9
-:u>@:k"t3V03iYUk+Xs:>S+`)ZKC:fa6)MggZIYR>1-r4k0<#mli5YgLXYejeHa-In)qLUg-U;~>
-#$LBV\^c7gKWJ+P5-1iU:Rc/JUnV"WRs^!m7[oNYXK8!_Ml!(HR[\M@V)G*J9SfH%V4Ub\X(HsQ
-OE$='Ngj(=XJ'6BU9(Gg;1PIDPZsWH?*%+sRpM#SXCt0'X8kB\X9"Pbq5cbiDk`k(J!X<-Rq&:r
-6(<+XXK%aJS#V]VS"!cFS3*XF2PYt%Wg$_aT2h>LGE-,nRu:XNXIVM=VQ?e02jF*=!E`KUXOsTY
-]'e2#LXYejeHa-In)qLUg-U;~>
-#$LBV\D!1KK\BAV:YOOBAAsB\d*6OC`La-a=N.e0g=jVNYgLU0_o7t'd7)C5@BIgDdE67JfRfp<
-[Z@jE[)Hn#g<>,(c.^mnB;3c,]5ts1G1plR`H\W@g4W]/g&OhEg&\g$q:\#\N6TL]TtbTd`I?4g
-;oP-0g=XA5`RhbC`Pm)/`_+b.7F.rDf=Z1Pb%nr7QF)'4`NXX:g;ct$e(WH*7_AHL!H2q.g=Y*`
-ir@lhL=5Yig'>fPmcqOUfg1,~>
-#$LBV\^d1YK]Z4n;s*5iC=&&!gt6ejd&+55?-pHRk2t-!]%tnWc-W,Mh+68ZB"$Dah:6MrjGC"c
-^mDhc^<grIk1GKOf]M>HD6)FR`HfhWIHG\!d!iRgk)3XGjoA6UjoNG@q;skoPhFT-Wl]J3d"U9;
-=4!VQk2al[d,W,kd*R6Ud8&WU8D:@aj2QB#eT&m]T>#tRd(4bak0d/IhWEmT8]CJe!HiR:k1Jf#
-li5YgLXYejeHa-In)qLUg-U;~>
-#$LBV\^c7gKWG3S55qVnJPCMsJ?5hN9l-o4VG1.kX?9]]9nf[M:/,]/KM?`_9ji0>L9.IoXK6#.
-=KIQd>"tcnXDUa,Eic?N9hg)<XHQ@QMl^Ve9m<\?Sh4(CX8kB\X9"PbqQ(@29hf_?9j=]f9hg;B
-XGoqnXK8,p9cTb+Ptau0XD:OnKM?_u9qJGNL9.IN9l[7DH;.]EX9Va"9oH*SN`u4Z!gFjGJZRM*
-#.j6SeVDWDqpbqlKCA!=nCg3Z~>
-#$LBV\D!1KK\?IY:]B&XULB^8U>"=8@>NXkdU@%mg,sFb@Aqo6@ptDOVdZ"6@="8KWS6'ag=h-e
-E8%a>Ead;Jg5KHKOP8E9@:>h_g:C^$YhFe>@@#X$aZ4>=g&OhEg&\g$qUuV8@:>=K@<:/?@:?+g
-g9Y4Jg=jgN@3!AB]jY?Pg5'1JVdZ!<@EI69WS6'8@?9,jRUL@<g';G&@BeJ>ZuYrq!k^"AJ_Jc1
-#3,[>g4n&Hqq;:uJaVg;nC^*X~>
-#$LBV\^d1YK]W<q;uYnhXCe>UX6/P_Aru0;hI^m/juds%B!UR]BkE[nY\'WXAq?RdZf^D6k2qM4
-G36S`G\5[lk*'ChR-*O_AnJ%)k/CqE]&nuaAtJ/Ie3%pQjoA6UjoNG@qW8IPAnIKdApNO`AnJ=1
-k.G;lk2t=qAfT:^a(Aqnk)X,lY\'VYB%5t_Zf^C`As_Y5ULnoQjp,p=B"@'d^3KG8!lcdTJ`bVI
-#4)<BeVDWDqpbqlKCA!=nCg3Z~>
-#$LBV\^c7gKWG6UD2clD!e3n3k,\WH<2fbs!_YY6ri?1!A"(WC"0,@BTD5JhRp'b*X9!f[JZRJ)
-#.j6SeVDWDqpbqlKCA!=nCg3Z~>
-#$LBV\D!1KK\?L\MQtR_!hs)>k1TmHC=N49!aeX*rn7G'IDa:_"5%COb4sZl`H$t5g&[joJ_J`0
-#3,[>g4n&Hqq;:uJaVg;nC^*X~>
-#$LBV\^d1YK]W?tOh9$'!ifkVk2l`^E8^]W!b>-=roO:>K[.g("64BhebJ8.cZk`MjoMH6J`bSH
-#4)<BeVDWDqpbqlKCA!=nCg3Z~>
-#$LBV\^c7gJZR8#!b>8CTr\?m<)e>AX9*<>>_0!#X9Q9(f@>Z*nb^iAa+NjD_!p&EJ,~>
-#$LBV\D!1KJ_JN*!e5!;U"TUrCMTR;g&d7LFFi/ig'6R:hV*_4o)%,GbCT*H^@9fAJ,~>
-#$LBV\^d1YJ`bAB!et]OU#lI5EH.rPjoUffH\(>'jp(/Og!tl,nb^iAa+NjD_!p&EJ,~>
-#$LBV\^c7gJZOp6!f`/+JZPHE#.j6SeVDWDqpbqlKCA!=nCg3Z~>
-#$LBV\D!1KJ_H1=s0;X@J_H^L#3,[>g4n&Hqq;:uJaVg;nC^*X~>
-#$LBV\^d1YJ``$U!kc.gJ``Qd#4)<BeVDWDqpbqlKCA!=nCg3Z~>
-#$LBV\^c7gJZOs7"EIaP=H\6:T<&7.map!Ee+*=c#KMJckJ6T@6@]~>
-#$LBV\D!1KJ_H4>"HdeJDn1GQT@sM/s5)Iaddm:h#Kq\dlFuc@6%A~>
-#$LBV\^d1YJ``'V"IXR_Fi/dmTB6@Ds4PqXe+*=c#KMJckJ6T@6@]~>
-#$LBV\^c7gJZOs7"@/oeCj^f8T<&7.map!Ee+*=c#KMJckJ6T@6@]~>
-#$LBV\D!1KJ_H4>"B!_'M4K4OT@sM/s5)Iaddm:h#Kq\dlFuc@6%A~>
-#$LBV\^d1YJ``'V"BFFCOemWkTB6@Ds4PqXe+*=c#KMJckJ6T@6@]~>
-#$LBV\^c7gJZOs7"@/oeCj^f8T<&7.map!Ee+*=c#KMJckJ6T@6@]~>
-#$LBV\D!1KJ_H4>"B!_'M4K4OT@sM/s5)Iaddm:h#Kq\dlFuc@6%A~>
-#$LBV\^d1YJ``'V"BFFCOemWkTB6@Ds4PqXe+*=c#KMJckJ6T@6@]~>
-#$LBV\^c7gJZOs7"@/oeCj^f8T<&7.map!Ee+*=c#KMJckJ6T@6@]~>
-#$LBV\D!1KJ_H4>"B!_'M4K4OT@sM/s5)Iaddm:h#Kq\dlFuc@6%A~>
-#$LBV\^d1YJ``'V"BFFCOemWkTB6@Ds4PqXe+*=c#KMJckJ6T@6@]~>
-#$LBV\^c7gJZOs7"@/oeCj^f8T<&7.map!Ee+*=c#KMJckJ6T@6@]~>
-#$LBV\D!1KJ_H4>"B!_'M4K4OT@sM/s5)Iaddm:h#Kq\dlFuc@6%A~>
-#$LBV\^d1YJ``'V"BFFCOemWkTB6@Ds4PqXe+*=c#KMJckJ6T@6@]~>
-#$LBV\^c7gJZOs7#\%mu?Aknd?QXj#UT=[2map!Ee+*=c#KMJckJ6T@6@]~>
-#$LBV\D!1KJ_H4>#^hi$GHffTGpe0sUY5q3s5)Iaddm:h#Kq\dlFuc@6%A~>
-#$LBV\^d1YJ``'V#_SV;I_+\(J16'3UZMdHs4PqXe+*=c#KMJckJ6T@6@]~>
-#$LBV\^c7gJZOp6#BY$CXK8$:Aq@%YX9Q9(f@>Z*nb^iAa+NjD_!p&EJ,~>
-#$LBV\D!1KJ_H1=#Et:Og=j[uJUuOMg'6R:hV*_4o)%,GbCT*H^@9fAJ,~>
-#$LBV\^d1YJ``$U#Fh-ik2t2ELk4]`jp(/Og!tl,nb^iAa+NjD_!p&EJ,~>
-#$LBV\^c7gJZOa1!MFF`XJ2d#]'e2#LXYejeHa-In)qLUg-U;~>
-#$LBV\D!1KJ_H"8!R$OTg7m:*ir@lhL=5Yig'>fPmcqOUfg1,~>
-#$LBV\^d1YJ`_jP!S3Tgk+^uBli5YgLXYejeHa-In)qLUg-U;~>
-#$LBV\^c7gJZOF(JZPiP#.j6SeVDWDqpbqlKCA!=nCg3Z~>
-#$LBV\D!1KJ_G\/J_I*W#3,[>g4n&Hqq;:uJaVg;nC^*X~>
-#$LBV\^d1YJ`_OGJ``ro#4)<BeVDWDqpbqlKCA!=nCg3Z~>
-#$LBV\^c7gJZOF(rN$!JJZQ#U#.j6SeVDWDqpbqlKCA!=nCg3Z~>
-#$LBV\D!1KJ_G\/rRq7EJ_I9\#3,[>g4n&Hqq;:uJaVg;nC^*X~>
-#$LBV\^d1YJ`_OGrT4*ZJ`a,t#4)<BeVDWDqpbqlKCA!=nCg3Z~>
-#$LBV\^c7gJZOF(s/Z:&G9-I[-p9&\?87J9;*7OIPVQ=AMD/P<4?BRFFu_?XXK6%gKnV3oU,4hl
-3H'JMi2d-omap!Ee+*=c#KMJckJ6T@6@]~>
-#$LBV\D!1KJ_G\/s4RP-Q6l=[-quSOGWrL]B1u^Z]K^;fY<@<`9M*slQ:O;Wg=h0BWMht5bsFoo
-8<&2Si7\Cps5)Iaddm:h#Kq\dlFuc@6%A~>
-#$LBV\^d1YJ`_OGs5jCET-sEr-rDtbIR1^'Cf"]t`^=k1\Nto,:eg*7SkMRmk2qOeZEZ]RfLAM1
-9U(+ji8t70s4PqXe+*=c#KMJckJ6T@6@]~>
-#$LBV\^c7gJZOp6"^kY`XK82r?4!9UEIM5UXJp2%poG?Y13o``VH9+cS5u=WS?/eSXK7F\J?5i4
->5bN04KPVHXK5fcXGpG8XPg/a]'e2#LXYejeHa-In)qLUg-U;~>
-#$LBV\D!1KJ_H1="aYE`g=jmPGR;QhOJ$j,g=MBZpt?US5FKr!dVlnS`bit.`nK-?g"NfJU>">.
-ErF]!9\S2og=gkSg9PdNg>LZhir@lhL=5Yig'>fPmcqOUfg1,~>
-#$LBV\^d1YJ``$U"b;&uk2tCsIL4W.Q`5GLk2M_(puWHg6_W@=hK@!'d<!rOdH9RgjlX9rX6/QY
-Gl?b3;!-n:k2q6&k.H"kk2>A+li5YgLXYejeHa-In)qLUg-U;~>
-#$LBV\^c7gJZOs7'4luW@th![MMb8sR2p%"8?/bm4SYu^H#H*B6CpgKX:J6pR89o:AZVqBGtt6<
-N`uC_$9YDk4KPVlFBjlsJZRe2#.j6SeVDWDqpbqlKCA!=nCg3Z~>
-#$LBV\D!1KJ_H4>'7m6fI];%3Y-)EO_Bjr>>M%T_9_d<GRZ(:g<68GFg(.o1_.;8sJD/\*R:F_"
-ZuZ-!$;B1-9\S3HPBF:PJ_K&9#3,[>g4n&Hqq;:uJaVg;nC^*X~>
-#$LBV\^d1YJ``'V'8X*,KsKiT\@?@sbpSO]@,pD3;#'/WU6Jm2=O^gZjpuCNb\H:DM!!fQU1iHH
-^3KV=$;fmI;!-nkRsVosJ`bnQ#4)<BeVDWDqpbqlKCA!=nCg3Z~>
-#$LBV\^c7gJZOp6&m89pI&q'a=+[NT4KPVKWN<0`poF[FDfTe`SkB!`*E/6)?A_pHXJI+B0o)ij
->-+fIX?<Sc4KPVl6S+:LXP^)`]'e2#LXYejeHa-In)qLUg-U;~>
-#$LBV\D!1KJ_H1=&o__WS_Ag9DPZ"?9\S2rf@nqPpt>q@N0''!a^+o"*GN1?GHZ%ng<hEg5-*DE
-En]63g.^5S9\S3H<B.F<g>CTgir@lhL=5Yig'>fPmcqOUfg1,~>
-#$LBV\^d1YJ``$U&pJFhV<3e[FKO]f;!-n>io]B"puVdTPaIb=e7/F>*H0!\ICXX:k1hP16F>mh
-Gin.Yk"t4&;!-nk>!'NNk25;*li5YgLXYejeHa-In)qLUg-U;~>
-#$LBV\^c7gJZOs7'2agP7sqD&Oc`\1X?<Sc5H1`c4SYujH#KHB6D7/NXJSsbXGC:]XK5+pOVUKh
-N`rNc4KLZHX?<Sc@#1G7BWS:qT7O*)X9Q9(f@>Z*nb^iAa+NjD_!p&EJ,~>
-#$LBV\D!1KJ_H4>'5"Y]=e49Y\@?Cjg.^5S:Y4=S9_d<SRZ,Ng<6Sk"g='iSg9#^5g=g!7\/&<&
-ZuXmS9\N1og.^5SHE>5pKA,%cb(8:-g'6R:hV*_4o)%,GbCT*H^@9fAJ,~>
-#$LBV\^d1YJ``'V'5YG"?DZf'_SU?8k"t4&<9!'&;#'/cU6OA2=P%9Bk211'k-fkWk2p:T_A6PA
-^3Jf&;!(U:k"t4&J[O%AMrs08eUclDjp(/Og!tl,nb^iAa+NjD_!p&EJ,~>
-#$LBV\^c7gJZOs7'm`YO3^9]$:JY#aGoVR$*GqcO*)DptX9q*HX)^P.MGd5ILAn7q7&6oC*)DMh
-*)AjL:JWgK>Ye.$XJ7=1:I/3dX:8oqXQ6Ge]'e2#LXYejeHa-In)qLUg-U;~>
-#$LBV\D!1KJ_H4>'q8cG8l45+A7TQ#RNniB,`:2a,@nRcg'UP>fo]7fY@qHZWW(Tm<m]R*,@n&i
-,@j_0A7S$\FC\p)g<V`SA5[L&g(B*kg>prlir@lhL=5Yig'>fPmcqOUfg1,~>
-#$LBV\^d1YJ``'V'r,MY:/[email protected]@U*[._-B[;&-#1QujpFsRjdB65\Sc/!Zi9).>MJ;P-#1&,
--#-L?C2-6#HYR;Ck1_srC0,`Djq<]*k2bY/li5YgLXYejeHa-In)qLUg-U;~>
-#$LBV\^c7gJZOp6s-X@nR]N'JRA-dVRA?^JT<%sZ!3#aq$(@9`X.ZPqSXH#HX9P>uXJM>QV>?Sb
-SuefWRAR'crL!e`XAhWbJZRq6#.j6SeVDWDqpbqlKCA!=nCg3Z~>
-#$LBV\D!1KJ_H1=s2#8n_qN/J_Tpl[_U-cKb1Zd2!7^l!$,aX6fur+'a25jpg'5aRg=!jTde^fc
-aP,(Z_UI5krPA]`g1sg<J_K2=#3,[>g4n&Hqq;:uJaVg;nC^*X~>
-#$LBV\^d1YJ``$Us32&/cK<R!bh;.2bhM%!e`HeS!9!_9$-pcWjjrSVd`g,;jp'Duk2"8*h>5>#
-e)oN2bhhLCrQGDuk&F\^J`c%U#4)<BeVDWDqpbqlKCA!=nCg3Z~>
-#$LBV\^c7gJZOF(q5aR"r($gcfW5++VLbi/X9Q9(f@>Z*nb^iAa+NjD_!p&EJ,~>
-#$LBV\D!1KJ_G\/q:Yghr*'0Mf\-A'dt-65g'6R:hV*_4o)%,GbCT*H^@9fAJ,~>
-#$LBV\^d1YJ`_OGq;q[&r*TN^f]E4<hgsqMjp(/Og!tl,nb^iAa+NjD_!p&EJ,~>
-#$LBV\^c7gJZOF(q5aRkr1F%jJZQA_#.j6SeVDWDqpbqlKCA!=nCg3Z~>
-#$LBV\D!1KJ_G\/q:Yhor6#)nJ_IWf#3,[>g4n&Hqq;:uJaVg;nC^*X~>
-#$LBV\^d1YJ`_OGq;q\1r71l0J`aK)#4)<BeVDWDqpbqlKCA!=nCg3Z~>
-#$LBV\^c7gJZOF(rN$!2JZQ#U#.j6SeVDWDqpbqlKCA!=nCg3Z~>
-#$LBV\D!1KJ_G\/rRq7&J_I9\#3,[>g4n&Hqq;:uJaVg;nC^*X~>
-#$LBV\^d1YJ`_OGrT4*9J`a,t#4)<BeVDWDqpbqlKCA!=nCg3Z~>
-#$LBV\^c7gJZOF(s/Z:%?QJpC-ntk)>oAZe83B>'PT<`)MATg#4<^f-Ftt4?XK6%NKnU=VU*D?S
-10oI4i2d-omap!Ee+*=c#KMJckJ6T@6@]~>
-#$LBV\D!1KJ_G\/s4RP,GU<.=-pImfFs+0)>YJ80]Hh7GY9&,A9IecMQ9Zp8g=h0#WMgkkbq2(P
-5B_V3i7\Cps5)Iaddm:h#Kq\dlFuc@6%A~>
-#$LBV\^d1YJ`_OGs5jCDIjb$R-pe*uHm6;E@8L7H`[5Ze\KHR`:b:bkSjP&Kk2qOCZEYL0fIoKd
-6[XIIi8t70s4PqXe+*=c#KMJckJ6T@6@]~>
-#$LBV\^c7gJZOs7'<45YA?2f&4?PZoDcCC4JZPl.4SYuqGtMJA6DIGNXJ8dc:7A8b4fk`7?YcaE
-N`uC_$9YDk4KPVlLoQG?JZRe2#.j6SeVDWDqpbqlKCA!=nCg3Z~>
-#$LBV\D!1KJ_H4>'A$#RJ(`Pr9MA'sN,"#>UY=A'9_d<ZRU1<g<6f1"g<ONS@`7!R:>+?pG_b#,
-ZuZ-!$;B1-9\S3HXOsk&J_K&9#3,[>g4n&Hqq;:uJaVg;nC^*X~>
-#$LBV\^d1YJ``'V'B<"fL?7RG:f'p5P]2OWXQJTQ;#'/jU18`1=P@WBk1Oe&B[5c%;W[&@Iu`[R
-^3KV=$;fmI;!-nk[H+uJJ`bnQ#4)<BeVDWDqpbqlKCA!=nCg3Z~>
-#$LBV\^c7gJZOs7'54DICj`<HXK6Q7X<E+q5H1`c4SYu^H#HNB6CpgKX:J6pX?<S/E3-$CL/X\F
-N`uC_#s>;j4KPVl<]H.kXP^)`]'e2#LXYejeHa-In)qLUg-U;~>
-#$LBV\D!1KJ_H4>'8+ojM4N?og=hh3g+&iN:Y4=S9_d<GRZ(gg<68GFg(.o1g.^4fNnW*+WbKQ.
-ZuZ-!#u'(,9\S3HD+D$cg>CTgir@lhL=5Yig'>fPmcqOUfg1,~>
-#$LBV\^d1YJ``'V'8to5Oeq2:k2r5]jt3Xr<9!'&;#'/WU6KH2=O^gZjpuCNk"t36Q0.(PZZ"@U
-^3KV=#uKdH;!-nkE_F3!k25;*li5YgLXYejeHa-In)qLUg-U;~>
-#$LBV\^c7gJZOs7';[lT-@DnF4?RP^X?<Sc5H1`c4SYu^H#IhA6CpgKX<(<*XDN;YS#i2&4=>`^
-N`rNc>c^&hX?<Sc?suKbVh(r-X9Q9(f@>Z*nb^iAa+NjD_!p&EJ,~>
-#$LBV\D!1KJ_H4>'@BTL0V-pl9MCDtg.^5S:Y4=S9_d<GRZ*Mg<68GFg)at@g5;D0`7i9Z9JN?s
-ZuXmSFP9FBg.^5SH@&`$dt-62g'6R:hV*_4o)%,GbCT*H^@9fAJ,~>
-#$LBV\^d1YJ``'V'AZS`18X-6:f*D;k"t4&<9!'&;#'/WU6M42=O^gZjrSH]k)lKQcfW\):c,<:
-^3Jf&HKJ&dk"t4&JV%.AhgsqJjp(/Og!tl,nb^iAa+NjD_!p&EJ,~>
-#$LBV\^c7gJZOs7'0rLr5^]Y^XK5EbX?<Sc5H1`c4SYujH#KcB6DRSNXIrUcXHH_!XK4P`X;3q"
-N`rNc4KLZHX?<Sc@#1nD>HFo@Ob'UpX9Q9(f@>Z*nb^iAa+NjD_!p&EJ,~>
-#$LBV\D!1KJ_H4>'2d<4;4ZF5g=gASg.^5S:Y4=S9_d<SRZ,rg<7#C"g<4<Sg:;3Tg=f7"g(mB9
-ZuXmS9\N1og.^5SHE>i+F5#?'\:NApg'6R:hV*_4o)%,GbCT*H^@9fAJ,~>
-#$LBV\^d1YJ``'V'34#P<MeiVk2p^&k"t4&<9!'&;#'/cU6Oe2=PIfBk14S&k/2D#k2oM>jq^eU
-^3Jf&;!(U:k"t4&J[OXQHKO@M_L^k1jp(/Og!tl,nb^iAa+NjD_!p&EJ,~>
-#$LBV\^c7gJZOs7"d2#3=ZEM^4:GVpD]sRg,%7H5+ZtqaX9pj;X,KfTRS5h7R/X0.:Sk.H+ZtH@
-+ZqV14?Pj0D`g.$XJ.1#4>^TMTb29qXQ6Ge]'e2#LXYejeHa-In)qLUg-U;~>
-#$LBV\D!1KJ_H4>"h@B'EC\a^9FQ3pN%1L*.sfc?.SRDLg'U5.fs,#?`*c8C_>`.0A^T52.SQg8
-.SN2c9MA79N(cp)g<DK@9L=6_bSH:kg>prlir@lhL=5Yig'>fPmcqOUfg1,~>
-#$LBV\^d1YJ``'V"iF59GY@2u:^hm2PUrfG/V2nX/5X7\jpFXAjh#3gcXfp\bPpWFC>@sW/5WWK
-/5Seo:f(-RPYb2Ak1DX]:e$3%fGBp+k2bY/li5YgLXYejeHa-In)qLUg-U;~>
-#$LBV\^c7gJZOF(afGM7@Y(W@X9Q9(f@>Z*nb^iAa+NjD_!p&EJ,~>
-#$LBV\D!1KJ_G\/ak?c$I"C#3g'6R:hV*_4o)%,GbCT*H^@9fAJ,~>
-#$LBV\^d1YJ`_OGalWV5K7W1Fjp(/Og!tl,nb^iAa+NjD_!p&EJ,~>
-#$LBV\^c7gJZOF(q5aQnr&atVfW5+AWI_/2X9Q9(f@>Z*nb^iAa+NjD_!p&EJ,~>
-#$LBV\D!1KJ_G\/q:Yg\r(I+=f\-ACf7DZ9g'6R:hV*_4o)%,GbCT*H^@9fAJ,~>
-#$LBV\^d1YJ`_OGq;qZnr(mCMf]E4Yj+6@Qjp(/Og!tl,nb^iAa+NjD_!p&EJ,~>
-#$LBV\^c7gJZOF(JZPiP#.j6SeVDWDqpbqlKCA!=nCg3Z~>
-#$LBV\D!1KJ_G\/J_I*W#3,[>g4n&Hqq;:uJaVg;nC^*X~>
-#$LBV\^d1YJ`_OGJ``ro#4)<BeVDWDqpbqlKCA!=nCg3Z~>
-#$LBV\^c7gJZOp6!dl_6rN$$QFQTY*B9Mhe"e(=>Q=ibNX8o$pM?&t6X9,#OR"qaI]'e2#LXYej
-eHa-In)qLUg-U;~>
-#$LBV\D!1KJ_H1=!hMT,rRq:NPNLR"K=UR,"iIOa^4TYPg&TFtY5l?/g&fF#_2$_Kir@lhL=5Yi
-g'>fPmcqOUfg1,~>
-#$LBV\^d1YJ``$U!iA8>rT4-cSEAr7MSo#I"jXX+aGOEgjoF*6\,aYBjoX)CbD53ali5YgLXYej
-eHa-In)qLUg-U;~>
-#$LBV\^c7gJZOp6s)e1?!'KAE!Jd9<X9P1q?<&h`4Q`^KQ6TU?=HW6W!fpGSLTC]kmap!Ee+*=c
-#KMJckJ6T@6@]~>
-#$LBV\D!1KJ_H1=s-*B7!)2M.!NX<5g'5N5GAKV"9]k%4^FaPOE4GPo!jurNLY;sls5)Iaddm:h
-#Kq\dlFuc@6%A~>
-#$LBV\^d1YJ``$Us-rrK!)Ve>!O^DJjp'1RIW@m>;!-mDaY.shG/En6!l&kcLZSg,s4PqXe+*=c
-#KMJckJ6T@6@]~>
-#$LBV\^c7gJZOp6s)e1?!'L7^)Ke/)+f_W6:HWj&RO=,":7F-nX'Hp0XAp[1riA_64Ae/@Wb4Ft
-UT?nZXJ/as02t&PXJfVk4FX@s;aEO*XIW3NAgN_DHot)lX?ibcD0r@_@Q\"pD_bHXBWJ59TLc/c
-9.-3H+b#KR#.j6SeVDWDqpbqlKCA!=nCg3Z~>
-#$LBV\D!1KJ_H1=s-*B7!)3CG)O3ui.bECoA5&?D__JK>@`:_qflemQg2&RSrn9u.9P6rMfRce<
-cIu@Gg<FHf4DRWMg=:XG9VC*:Bi@^3g;df!JM4^jSP3J1g/?GSMOW>LI8"n6NB_DVK\>)5b?N]S
-?S]TZ.A2aU#3,[>g4n&Hqq;:uJaVg;nC^*X~>
-#$LBV\^d1YJ``$Us-rrK!)W[W)P']$/`Z!@C/CPbc8<4\B[B:4jaAbqk&NArroQhB:i&kfjGHcZ
-g?)Yok1F_:5B'Gak2D"j:oWSXDHBZJk0e'BLbZs4VGLmNk#UF&P,.6uKM[0SPsT[kN903aemRY&
-A2MYt/?+]m#4)<BeVDWDqpbqlKCA!=nCg3Z~>
-#$LBV\^c7gJZOp6s)e4@!I\_^X;*k!XFI:M;OOV,G-"Y1NLGrSDlfg&ri?Z8NNB4&Ff^oTXCm*c
-NEWDGr2_k)PcR!KV1l"P4KO5tVQ;n\;O=J%9rrYYXIN7d6)U_\R&jbOXGL;c/!$c^BWS;.8?AnT
-=0/JcNiWGrmap!Ee+*=c#KMJckJ6T@6@]~>
-#$LBV\D!1KJ_H1=s-*E8!M>/Hg(d<8g7d3NBYiDbQ.g"RZGa2?N7u]Zrn7p)ZeF,rPhNl(fn-$R
-ZZFhor7X+a]@os4d\tmR9\QI<e(RLKB>E5Y@G73/g;RgS;Uj?4^tO49g9,\S2mqA6K\G/'>M@f@
-DVEf<NnO]ss5)Iaddm:h#Kq\dlFuc@6%A~>
-#$LBV\^d1YJ``$Us-ruL!N;%XjqU_Tk,RP&DTq72S`Xop]["<ePigh)roOc;^#nIGSE@sJjbg2&
-]m8a:r8osp`o^+[h6H,);!,&Yhr[bsD9D"(BBGtQk0S)&<oE%UbN=Jak-oj&3ksgXN999R@-6Ug
-FQV^^NogQ3s4PqXe+*=c#KMJckJ6T@6@]~>
-#$LBV\^c7gJZOp6s)e4@!N/6_X::%L4CkLj(HafAC91Bori?7%5c[5Jri?H2NNB3TS?/fgX>g,@
-!^s+Pr2_,*XK4OcVdDPK.BJ55XK4Oa5-1iT9rqDO4?PNs5rq/`XK4,T49A0W4T;Di4KPWW8?Anm
-<KpFHNiWGrmap!Ee+*=c#KMJckJ6T@6@]~>
-#$LBV\D!1KJ_H1=s-*E8!Rt$Hg't5Z9RkaF*DB.!LY?OLrn7M+;V4ssrn7^#ZeF,@`nK.og.)'8
-!`n#Kr7WAhg=f6Se9FY\1tnpWg=f6Q:>4F?@G5Wb9M@k#;G'Z`g=e^h9EJST9`E`R9\S4D>M@f`
-CqOMqNnO]ss5)Iaddm:h#Kq\dlFuc@6%A~>
-#$LBV\^d1YJ``$Us-ruL!T7&Yjpegs:kn)h*`,[.Nok>oroO@C<odE>roOQ5^#nHgdH9TIk">VL
-!a=__r8o5#k2oM&i."R"2s.E!k2oM$;Wd,fBBF>(:f'^:<_cMuk2nr.:]b1i;#]Sb;!-ok@-6V4
-ElN(=NogQ3s4PqXe+*=c#KMJckJ6T@6@]~>
-#$LBV\^c7gJZOp6s)e1?!'L7^%:uWB5H1YfNi\jnXAkG_X9+&>@K!8t>E,_cM-m?cAZU>pXK6!7
-E-SIcAZS"qX?<SS9WWFfXG(/cX?<OhN3#uQXGpGcXDOb!VlO'^XE\]cXC\IWJ#m:6XK8'cri?3\
-7TcPeX8tSCPH4u"map!Ee+*=c#KMJckJ6T@6@]~>
-#$LBV\D!1KJ_H1=s-*B7!)3CG%=m0d:Y46@[+`Zag2">!g&e0KHi;YgF0jTSXa/XSJD-ZNg=h)2
-NgSPSJD*]Ng.^5?@+pr)g8TMSg.^1BZ.`r$g9YkSg5=6TeCeuMg6[iRg47m-U"Y-og=j_Srn7I[
-=E)^fg&Y*SPM-6#s5)Iaddm:h#Kq\dlFuc@6%A~>
-#$LBV\^d1YJ``$Us-rrK!)W[W%>X*.<8utc^?3t5k&JB=joVbeK)Oh%H+iA&[t!Q&LZYRqk2qH]
-QD!C&LZVFqk"t3fA`fUEk-B[&k"t/e]B4'Fk.Q'&k)nG"i8o<uk+J%&k(i(NWof2?k2t6&roO<q
-?$>''joJMmPNE)8s4PqXe+*=c#KMJckJ6T@6@]~>
-#$LBV\^c7gJZOp6s)e1?!'L7^%RrQCJZPrR>!,BVRQ<NVrN$#\M#OJI<B<3bXK7CD4G0`:IQT`U
-XK-;&4J?CKKnVR$XEcpJ9Qs&iULuWBX'@c89rtF]4?RtM3af%i@]ZYU4?T%54)$g.XK7"93_97O
-!H*/]X9+1mLQeeD]'e2#LXYejeHa-In)qLUg-U;~>
-#$LBV\D!1KJ_H1=s-*B7!)3CG%TlCuUtXPUE_K`j_b*RkrRq9DXT$pFCe@?cg=il,9W$OtTM/%i
-g=_K[9[&,\WMiCAg6kWq@@(4kc[n`gflTo[@G9GK9MCt^8pT.DI+m;@9ME=W98-'7g=iAs8mMAL
-!K3?Eg&e>oXHV?Bir@lhL=5Yig'>fPmcqOUfg1,~>
-#$LBV\^d1YJ``$Us-rrK!)W[W%UDn-Xled-GYhi0c;%01rT4,U[f5D\E_]E$k2s?R:p9$DWDHF/
-k2hn*:tLS!ZE[,^k+Y\=AtNO-g5/P1ja0h%BBJ?s:f+"$:4VKgKBD<h:f,Bu:Q/,Ok2rgC:1=.a
-!L'5VjoVq1[?K_Wli5YgLXYejeHa-In)qLUg-U;~>
-#$LBV\^c7gJZOp6!d,u(rN$$DFMFm[Wi)b"NUNqMWB-sPX95N$3i`1\!C;I'X9Q9(f@>Z*nb^iA
-a+NjD_!p&EJ,~>
-#$LBV\D!1KJ_H1=!gPWorRq:<PJ>fSf[SDnZgZTLf1OQfg&p$X9%X'r!E5t\g'6R:hV*_4o)%,G
-bCT*H^@9fAJ,~>
-#$LBV\^d1YJ``$U!hD<,rT4-QSA41hjP\sC^$k(bj%eP-joa`':?2?9!EZUjjp(/Og!tl,nb^iA
-a+NjD_!p&EJ,~>
-#$LBV\^c7gJZOF(`2j&p5s^Y$X93K/6)FCY".MSBI#Y33]'e2#LXYejeHa-In)qLUg-U;~>
-#$LBV\D!1KJ_G\/`7b<m;Gt$mg&mF7;UP<o"3"/9SW2>-ir@lhL=5Yig'>fPmcqOUfg1,~>
-#$LBV\^d1YJ`_OG`9%0-<`[**jo^uO<o*T6"41(LV2aUAli5YgLXYejeHa-In)qLUg-U;~>
-#$LBV\^c7gJZOF(n>lVci2csZVXCMdWM"gDo;i/-map!Ee+*=c#KMJckJ6T@6@]~>
-#$LBV\D!1KJ_G\/nCdlhi7\4addGfif#[email protected])Iaddm:h#Kq\dlFuc@6%A~>
-#$LBV\^d1YJ`_OGnE'`*i8t($hX9M,iRWSBoB$8Cs4PqXe+*=c#KMJckJ6T@6@]~>
-#$LBV\^c7gJZOF(nZ2bU<;rs"UPA`K");A1PO5FPPZ..S#+f@JJr:SGk,\YuA7T<DX9,A3CA4e0
-IBT^V]'e2#LXYejeHa-In)qLUg-U;~>
-#$LBV\D!1KJ_G\/n_+#UC]<#gc`6rt",DB;]'\2P]P@#k#0D@ZV6D/nk1TojIt*%@g&flULA0C%
-T<HrQir@lhL=5Yig'>fPmcqOUfg1,~>
-#$LBV\^d1YJ`_OGn`BkkEW5)$g9^b?"-/,S`9l[fa)LV3#1SBtY.>n:k2lc(L5(NUjoXOsNVDQ8
-Vm#4eli5YgLXYejeHa-In)qLUg-U;~>
-#$LBV\^c7gJZOF(nZ2b3G5eQDQVma`)Ie)I/T@emUmRjWXIQ&aR&ZgHV59QPXJ:u=rN&\]R&-X\
-X-f?WXJ/gMEuCW:TpVIRXK%YTU9(&ZTU;RWXJM;WSY<-dS!^4W?rVf1>-+g*R%(1UR&-1AXK8IU
-0s%IOR%gOHSZJnTYH.r>map!Ee+*=c#KMJckJ6T@6@]~>
-#$LBV\D!1KJ_G\/n_+#*QN#S=^M!Q")LS*R3KDhId)!r[g;V@e_:ZrIdF#eRg<[@:rRsr__9pZa
-ftkS[g<OZ8Os%nFbe_HUg=O0Wc.^C^bJDT[g<ma[a3<8k`PL0[H>BFSEn]7!_8Y-Y_9p*?g=k2W
-52+`9_9UTIa4f6@YM'3?s5)Iaddm:h#Kq\dlFuc@6%A~>
-#$LBV\^d1YJ`_OGn`Bk>T)RjQb&..?)M=lk4I,'kgrn=3k0Vf>bN.6th;-9*k1[berT6eubMD":
-jibs3k1Op_RNg<`f?;_,k2XY.g#gr8f#uk2k1n/2db*^EccbA2JT7rsGin/KbL#D0bMC@jk2ta0
-6K[F`bLtgsdcT[gYN?&Ts4PqXe+*=c#KMJckJ6T@6@]~>
-#$LBV\^c7gJZOF(nZ2b3G5eQDQVma`)GH[&OGp9?=&;ndXAW54:iLLrN/S`uXFir?riA;4;,BJt
-XE.38J?2h6XK6TA5upf]Q)nk":fa68+&u->WiB/t<?HOgKMkWbXEnccVa7DcD,=,aR3PO);iq![
-$TtMlJ/j*,,@IUS4Kkgj]'e2#LXYejeHa-In)qLUg-U;~>
-#$LBV\D!1KJ_G\/n_+#*QN#S=^M!Q")IUS=\$=Z<De3b'g1YMUAWDs!ZEYX<g87qdrn9Q/An=f#
-g6-#[U=sOpg=hk@;Jfu\^"SEVASoSZ-Z!@4f[t+RCaY_+Ve9S"g7+#Sdo+oRMIgJ#_C]A2C:=,q
-$V]:.UEcML/:-%(9X!.Sir@lhL=5Yig'>fPmcqOUfg1,~>
-#$LBV\^d1YJ`_OGn`Bk>T)RjQb&..?)J.=Y_7SjhF_c$Dk&#?sCR1G9]XoJ[k-/*0roQDDChm";
-k*g(%X6+Q@k2r8k<c`%ra6&S$CNJ(%.<93HjPtAuE[ddGY\e0?k+e.&hcJt&P&"p?bV*aIE5;J8
-$W-!JX<jmj07i9J:p9!cli5YgLXYejeHa-In)qLUg-U;~>
-#$LBV\^c7gJZOF(nZ2aeRJs8gW13df'q.KP<MHQiI?9%KXH"BYXI$"WUS:6WX:^[qXK7CfWN9f\
-H<ZJj9TN8:rN%_>P,rMIXH\g.8Wp/3T<(8U:me>V1p!!7N0%FgH<cP7R&k::OGcVr9STXC8#r_m
-4T;De8Y;kUT<,,\YH.r>map!Ee+*=c#KMJckJ6T@6@]~>
-#$LBV\D!1KJ_G\/n_+"S_Z&6ie\qI@'uO$FCsLaET!tOsg9`91g:u?DcH]Pkg(Cu4g=iiVf@ktL
-Rrc'F@CC*`rRru(\_;q1g:Xo(>e&KSakBSAB#*-B6JB.YZ+#%BRru2[^tOis\$0&P@B/&,=kVN_
-9`E`N?-1Q+b1bRaYM'3?s5)Iaddm:h#Kq\dlFuc@6%A~>
-#$LBV\^d1YJ`_OGn`Bjdc2Qi+iQqMc(!]uZEnTShVnoN?k.W=Rk/uglg"B[1jq5XQk2s=*j5u>t
-UNs\hB#&Q*rT5h8_rd,Xk/P6R@Dh4seE0ciCWkki7cqg$]>9#dUO0h$bN>.D_7F!tB!g^R?KL>3
-;#]S^@as7Ke`Q#:YN?&Ts4PqXe+*=c#KMJckJ6T@6@]~>
-#$LBV\^c7gJZOF(nZ2b3G583DH_d`fE3)%u<s)p5N`uC_"*\a'GlFcJPZ+ZbKk((_!H(+#<s"jm
-OSu6m6)Uf$H`Us`="KN94KPVKW'('\"$EZI/H/]VML%6`=KJT66iL-nTM1iVX?EVcX??K`"-6T?
-@B6I6]'e2#LXYejeHa-In)qLUg-U;~>
-#$LBV\D!1KJ_G\/n_+#*QMK5=SC#uWNnR#&DZbFAZuZ-!".,(.RJtnD]P?0SWI=a!!K9eQDZ[jq
-\,G"m;UjEXS(`U8D`G8\9\S2seP,tr"&.FY3<!h%Y+%q"E8'#p<W6nCb@/BDg.p;Sg._M""1<-L
-H`Pj)ir@lhL=5Yig'>fPmcqOUfg1,~>
-#$LBV\^d1YJ`_OGn`Bk>T)%LQUtb%*Q0(a=FT[<Z^3KV=".tpFU&O0Xa)L2'Z@r2=!L-O^FTTm3
-_>WL.<oE,'Uum\[FZ[M';!-n?iDBO9"&S-s48s@.\>)Z=G37q@>5iXNen3:kk#1:&k"u'>"2B&f
-JZIo;li5YgLXYejeHa-In)qLUg-U;~>
-#$LBV\^c7gJZOF(nZ2b3G583L9M1.VI&rZ<M2>H<G=[kqXAu&`7&?udST[>\XJTEYM/e9F>)A)J
-Q(V69M-QK*OK2GnXA=\$*da;/SY@p'R95;[+fqVTIYi5s@oo_!=e_WnM2>]39M((]FKDO"0SuU,
-W+J#_poFKV?ad$?]'e2#LXYejeHa-In)qLUg-U;~>
-#$LBV\D!1KJ_G\/n_+#*QMK5E?s]sjS_Cl"XfZ^!QWprug/ZL"<mfXT`g0T4g=(DGXcKL.EilHq
-]utAsX`_QJ\(PYJg17=X-C_k7aNZu[_JlW2.b`F*T<4EPIW*oUER)gKXfZuj@9p!tPM4Zk4KZua
-eU^67pt>a>H+)E2ir@lhL=5Yig'>fPmcqOUfg1,~>
-#$LBV\^d1YJ`_OGn`Bk>T)%LYARi30VWQ$G\$p\GT4#M7k#L2>>MSB'd@OLVk21co\!OGTGdk/=
-a4>FC[sQCh_<#cmk%_B(.&>*Qe(I.,c$$RT/`u#LW4/@tKluM$GM1Vm\$pt:An&6;S*&e@5e#P2
-i.t"XpuVTNJ@=SEli5YgLXYejeHa-In)qLUg-U;~>
-#$LBV\^c7gJZOF(nZ2b3G583AJWX;_ri??b?XK;(CgV/[X9!Tmri?3Z?XI[LX<hFbGH@mE?XJAc
-XI`d+N0dmrX']D=UgInlDLu5SQ="m<O'dB!ri?lM?ZN5Y?`U8hQ`Qrh?\YXULgP>,XJu2+"IlKo
-HYrPZ!eVMH[]B\Emap!Ee+*=c#KMJckJ6T@6@]~>
-#$LBV\D!1KJ_G\/n_+#*QMK5:UUYQ7rn7UaG^.3]M0P'Zg&[Y3rn7IXG^,,Fg*M8oQeL0DG^-%<
-g;nM`Z+kONfQ_l!d!1>FMkt[(^3H%![WnK>rn8-CG`^X.GhLfY^Y6tXGcKJ+XE^#ag=H7J"N9$J
-S;R*q!i@9A[b:rFs5)Iaddm:h#Kq\dlFuc@6%A~>
-#$LBV\^d1YJ`_OGn`Bk>T)%LNXMTIYroOI"It,i-Oai\qjoM3OroO<nIt*X\js>e4TB>:oIt+T_
-k0ng0]?5VrjF;mGgOG6iPHKDIaa^#H^ji@\roOuVJ!fAPJ*#h-b3%E-J$e?M[XXn2k2QAi"OH5m
-UltN8!j<uU[cRe[s4PqXe+*=c#KMJckJ6T@6@]~>
-#$LBV\^c7gJZOF(nZ2bg?Fd-?X+>h4L@;2GUH*IdpoFOR5'cq)!Ha%'X9Q9(f@>Z*nb^iAa+NjD
-_!p&EJ,~>
-#$LBV\D!1KJ_G\/n_+#mGIcE1fqbEnWpeXDcUjA>pt>eP:RV"3!L'Iig'6R:hV*_4o)%,GbCT*H
-^@9fAJ,~>
-#$LBV\^d1YJ`_OGn`Bl/IC\JCjfPY>[.!,Zg.e*`puVXe;kj'L!LpC&jp(/Og!tl,nb^iAa+NjD
-_!p&EJ,~>
-#$LBV\^c7gJZOF(VlU!#B4lkbX95&,B9;ni!cr!sWiQE9map!Ee+*=c#KMJckJ6T@6@]~>
-#$LBV\D!1KJ_G\/VqM7*JqBogg&oEJK"(O/!g8/#WnI[:s5)Iaddm:h#Kq\dlFuc@6%A~>
-#$LBV\^d1YJ`_OGVre*BM2AJ)joa(hM8AuL!h+t:WoaNOs4PqXe+*=c#KMJckJ6T@6@]~>
-#$LBV\^c7gJZOF(g8k@=HC"N2!LfRgX8n1VX9,)AVlZs(]'e2#LXYejeHa-In)qLUg-U;~>
-#$LBV\D!1KJ_G\/g=cV=R_JaS!Q<$fg&SATg&fKee?%@.ir@lhL=5Yig'>fPmcqOUfg1,~>
-#$LBV\^d1YJ`_OGg?&ISUWNJs!RB-&joE!jjoX21i2l&Fli5YgLXYejeHa-In)qLUg-U;~>
-#$LBV\^c7gJZOF(g8k?R@$1Dh!Df-7X9!s5jK&>Dr2]sl0V,;H#.j6SeVDWDqpbqlKCA!=nCg3Z~>
-#$LBV\D!1KJ_G\/g=cUAHFWt.!nh,%f%L/%ZfKg?9`3TGaZ[YFg'6R:hV*_4o)%,GbCT*H^@9fA
-J,~>
-#$LBV\^d1YJ`_OGg?&HSJAV<J!p+.@f&d":^#\;U;#KGWe3VK`jp(/Og!tl,nb^iAa+NjD_!p&E
-J,~>
-#$LBV\^c7gJZOF(g8k<QQMmm&X$*PcJW,&<I$(M3GB0^bXFkP\EhKL\Ee"(i#ao^gL9.7mEf^'u
-"KP'kEh<93%sr>oXIF72KSZRIQu\R7V#.4pWcE7]X9>8<IS665X9Q9(f@>Z*nb^iAa+NjD_!p&E
-J,~>
-#$LBV\D!1KJ_G\/g=cR@^AZb'fhL2SUTpK!S[[>,QBBhRg8:"JOiuIKOeVj/#f;_)WnPm`OgY&>
-"P?plOidUV&"A^0g;T3-W3"O3^lcEpd/2Muf9)?tg'#]`TO5^?g'6R:hV*_4o)%,GbCT*H^@9fA
-J,~>
-#$LBV\^d1YJ`_OGg?&ERaSk6=j\b1&XLkIGV8DBWT:"[$k-(/qR+CDrR&^/J#gJaEZf^,3R(rL[
-"QWs.R+2,t&#>TLk0TLWZ*rSXbF$J?g\^+7j-ZD:jojA)WFaJYjp(/Og!tl,nb^iAa+NjD_!p&E
-J,~>
-#$LBV\^c7gJZOF(g8k<QQMmm3W'IGcGoBg+='M_>EHY]hJ7Wml25,/0G%Z0'W)7_H*3*7eG$11/
-X;@p0<Hb"9X)W!">cO;EJ7DuD6o@1i3gBNC$EA8$XK8C(G%hkcXK2W;map!Ee+*=c#KMJckJ6T@
-6@]~>
-#$LBV\D!1KJ_G\/g=cR@^AZb4e5=rRR3?PrDKFHaOHk+CU4AM16d1dPQ%PR[eRt.o,M.%&Q#XS9
-g)&CJCR*&rfoM&VFk=VkUOINl<^T\U8\=lR$J1P(g=k.tQ%gI%XP*m<s5)Iaddm:h#Kq\dlFuc@
-6%A~>
-#$LBV\^d1YJ`_OGg?&ERaSk6Ji)]"&Td+e0FF*#-R%AffX,!9N7b=/mSr0?+iGG0;-0'?DSp/?S
-jqm)gELt_Cjd2.%HfNL6XG)27>=VXf9ud(m$KI^@k2tZISrFuBXQB`Qs4PqXe+*=c#KMJckJ6T@
-6@]~>
-#$LBV\^c7gJZOF(g8k<QQMmm/AqI+cS4o/GNE_*"C2-=Z5-1iT9rtF=C/STD6)UfcB4cbpX8kBZ
-X9!-bri?Bf2JQu'Aun1,ri?95Kj9R9PkhBd4KPVgNNB3SSZJms]'e2#LXYejeHa-In)qLUg-U;~>
-#$LBV\D!1KJ_G\/g=cR@^AZb0Ju%,S`aHGoZ?*!>LPK,p:>4F?@G9G"LM2.j;UjFSJq9ctg&OhC
-g&[&$rn7Xf7#-P0J_EnLrn7O)W-#=\]D:.d9\S3AZeF,?`iRkuir@lhL=5Yig'>fPmcqOUfg1,~>
-#$LBV\^d1YJ`_OGg?&ERaSk6FM65q&d:L@;]R$k]NfIS7;Wd,fBBJ?HNbsL4<oE-&M28>6joA6S
-joLUAroOL'8</^GLuqWjroOB<Z$X*%`qea&;!-nc^#nHgdB)I7li5YgLXYejeHa-In)qLUg-U;~>
-#$LBV\^c7gJZOF(g8k<QQMmm3X$*PcS4o/GNE_3.I!p:+6)^lJ9rr5PI9:$]8Y<)cUMG:ZXJJ;\
-X:8unXJ;k\5C7g)PcR'Kri?95Kj9R9PkhBh4KPVmLTIIESZJofUTgg(]'e2#LXYejeHa-In)qLU
-g-U;~>
-#$LBV\D!1KJ_G\/g=cR@^AZb4fhL2S`aHGoZ?*-NStDIc;q9U4@G6[$T5T24>fk^Rc\S1Hg<rss
-g'rn0g<\Kb:n=5J]@p'4rn7O)W-#=\]D:.h9\S3IX4l-,`nK.mc`l+-ir@lhL=5Yig'>fPmcqOU
-fg1,~>
-#$LBV\^d1YJ`_OGg?&ERaSk6Jj\b1&d:L@;]R%"mVPp62=Q/D\BBGGFW-*gV@FaN&g5i/ok1s2:
-jpdHMk1\t:<2HOg`TC+ZroOB<Z$X*%`qea*;!-nl[-$@RdH9TFg9B]Dli5YgLXYejeHa-In)qLU
-g-U;~>
-#$LBV\^c7gJZOF(g8k<QQMmm3X$*PcCb18oJMa-C@:NN"M-FI\9rr\K@ll]KXAi\>=0,qB@of/s
-X;6Rr@p5t8H=(/fKU3rmQ)plD<Erd.AG`G<WFI,^S?-(->p+!cX?8VLX9Q9(f@>Z*nb^iAa+NjD
-_!p&EJ,~>
-#$LBV\D!1KJ_G\/g=cR@^AZb4fhL2SM)VCsUI*:iH[Tt>X`Str@G75rI7m/\g1u+bDVBSgI;R%$
-g(p`2I<+&qRs9@(VnXg1]\:h*CNO]7J,@q0f6o2u`S,TcFt&=&g.Y2Eg'6R:hV*_4o)%,GbCT*H
-^@9fAJ,~>
-#$LBV\^d1YJ`_OGg?&ERaSk6Jj\b1&OZKd5X@Cp4JV8<Z[sE^9BBH%?KMP>"k&?!,FQS=2KQGT<
-jqb@OKR)_BUORrEYf\YOa6)8QEI3(PLAU*Cie/q;d,oh2I4LHBk"nmYjp(/Og!tl,nb^iAa+NjD
-_!p&EJ,~>
-#$LBV\^c7gJZOF(g8k?RKVSOJ-*'D1XH/(,Kq=!rXGDRmXK7M;L01OYMhRaVWN;bHKqYTHKnYoh
-X9+K;U].>*MhR4nTnS2nXJpo2RZ!PmqlBdure1]SXJLW1QB/,#)j7G,#.j6SeVDWDqpbqlKCA!=
-nCg3Z~>
-#$LBV\D!1KJ_G\/[email protected];Hg9mp%WQD-hg9%?ag=j$8WGpSFZ)PjEf%S9GWQa)HWN!`/
-g&e^^cMlN.Yc5%abc.Sag=E7,_m.%aqq;&&ri$7Ng<ut,^9u[m,J(,5#3,[>g4n&Hqq;:uJaVg;
-nC^*X~>
-#$LBV\^d1YJ`_OGg?&HSYhK*=-08:dk.e4OZIH2<k-hS4k2sLcZZbKn]!Bhkio\dsZIe6tZEh^L
-joWB)gA^4F]!B*5f<V^4k2N\VcFV34qrRn>riumbk2!>VahQuB,fHqL#4)<BeVDWDqpbqlKCA!=
-nCg3Z~>
-#$LBV\^c7gJZOF(g8k@';2+tM!K<05X94Mf>?pTt!.auO!0ZZL!1Wmj!-e+;!K`8DX9Q9(f@>Z*
-nb^iAa+NjD_!p&EJ,~>
-#$LBV\D!1KJ_G\/g=cV"AuP[^!O9-+g&na)FER$*!2BC5!4hFL!6+kX!1*<3!OoA<g'6R:hV*_4
-o)%,GbCT*H^@9fAJ,~>
-#$LBV\^d1YJ`_OGg?&I6CpEs$!P?2?jo`AEH@5/C!3?$D!5n-b!7:Xi!2&rH!PuCOjp(/Og!tl,
-nb^iAa+NjD_!p&EJ,~>
-#$LBV\^c7gJZOF(`2j'7NK'b%X8nafN<#^=X8o-qN<#<=X9Q9(f@>Z*nb^iAa+NjD_!p&EJ,~>
-#$LBV\D!1KJ_G\/`7b=;ZEhjFg&T(hZ2i/8g&TS!Z2h\6g'6R:hV*_4o)%,GbCT*H^@9fAJ,~>
-#$LBV\^d1YJ`_OG`9%0R]Y*%fjoEa*]E$UMjoF68]E$*Jjp(/Og!tl,nb^iAa+NjD_!p&EJ,~>
-#$LBV\^c7gJZOF(]W;3`<)f`GXR`Fs]'e2#LXYejeHa-In)qLUg-U;~>
-#$LBV\D!1KJ_G\/]\3IZC221Jg@Er%ir@lhL=5Yig'>fPmcqOUfg1,~>
-#$LBV\^d1YJ`_OG]]K<oE,aZbk47X=li5YgLXYejeHa-In)qLUg-U;~>
-#$LBV\^c7gJZOF(]rV?u>*P8OqlBjl4>h\kqlC"5map!Ee+*=c#KMJckJ6T@6@]~>
-#$LBV\D!1KJ_G\/^"NUuF1f0<qq;+p9LFBbqq;86s5)Iaddm:h#Kq\dlFuc@6%A~>
-#$LBV\^d1YJ`_OG^#fI6H,dkbqrRt2:e-*!qrS+Ks4PqXe+*=c#KMJckJ6T@6@]~>
-#$LBV\^c7gJZOF(^8qWh4t00YXK52kDuHa;4T;D^Q2XG\WiW:79U1F8#.j6SeVDWDqpbqlKCA!=
-nCg3Z~>
-#$LBV\D!1KJ_G\/^=imb:,H@Vg=g(FNW%Q29`E`G^&DCCf@nr1@(hBM#3,[>g4n&Hqq;:uJaVg;
-nC^*X~>
-#$LBV\^d1YJ`_OG^?,a";Dr-kk2pAiPl9_E;#]SWa8TZSj6#K]B#oej#4)<BeVDWDqpbqlKCA!=
-nCg3Z~>
-#$LBV\^c7gJZOF(^8q[;IoMr7XCdljBn-,`!'L7^$:C>R<N3$3JXfo.M6$ommap!Ee+*=c#KMJc
-kJ6T@6@]~>
-#$LBV\D!1KJ_G\/^=iq@Tk_Tpg4@,\Kq\M"!)3CG$<5$bCtI?lUW.>eM:r0ns5)Iaddm:h#Kq\d
-lFuc@6%A~>
-#$LBV\^d1YJ`_OG^?,dWWGp5?k(q:/N2lm>!)W[W$<ba&EoQ2;XO)74M<5$.s4PqXe+*=c#KMJc
-kJ6T@6@]~>
-#$LBV\^c7gJZOF(]rV6n>lC`+7mnkSri?)^ri?H>6pud2W#7uk4\pp9#.j6SeVDWDqpbqlKCA!=
-nCg3Z~>
-#$LBV\D!1KJ_G\/^"NLlFoC"r>$!YPrn7?Grn7^2=')EUeK@pp9k9+7#3,[>g4n&Hqq;:uJaVg;
-nC^*X~>
-#$LBV\^d1YJ`_OG^#f@-Hi<(/?X#ReroO2WroOQE>?eGri?DK1;/1sM#4)<BeVDWDqpbqlKCA!=
-nCg3Z~>
-#$LBV\^c7gJZOF(]rV6n>lLf-7\?GGHiC)H4T;DlLnph5WMrLTUn3OHXFQRqX9Q9(f@>Z*nb^iA
-a+NjD_!p&EJ,~>
-#$LBV\D!1KJ_G\/^"NLlFoL(t=j##nS,V+A9`E`UXj><lf%+0@ccEBFg7l9?g'6R:hV*_4o)%,G
-bCT*H^@9fAJ,~>
-#$LBV\^d1YJ`_OG^#[email protected]?.IY9V#KKV;#]Se[bKP=iSn@fgXEdsk,ZO^jp(/Og!tl,nb^iA
-a+NjD_!p&EJ,~>
-#$LBV\^c7gJZOF(^8rH"0d0W"XG/o&7l%0=4V^,LX<B_i?)t&l90GV"XK3:GNN<>qmap!Ee+*=c
-#KMJckJ6T@6@]~>
-#$LBV\D!1KJ_G\/^=j]p5:LL(g8[qD>!Ufb9cHgFg+#fkFkGE]?VOM(g=dZoNS4Trs5)Iaddm:h
-#Kq\dlFuc@6%A~>
-#$LBV\^d1YJ`_OG^?-Q/67d6@k-Iua?:3l+;&iHZjt0G-I,sG2A5QL@k2mk:NTLH2s4PqXe+*=c
-#KMJckJ6T@6@]~>
-#$LBV\^c7gJZOF(]r_46riH.#"0AQ)XT#:#XT#:!XT#:#X8u?nN3!5pmap!Ee+*=c#KMJckJ6T@
-6@]~>
-#$LBV\D!1KJ_G\/^=rP=rn@D*"5;G^gA]e*gA]e(gA]e*g&Z%qN7nKqs5)Iaddm:h#Kq\dlFuc@
-6%A~>
-#$LBV\^d1YJ`_OG^?5CUroX7B"6S_-k5OKBk5OK@k5OKBjoTU5jc/C,li5YgLXYejeHa-In)qLU
-g-U;~>
-#$LBV\^c7gJZOF(TWA0VUl;AZ]'e2#LXYejeHa-In)qLUg-U;~>
-#$LBV\D!1KJ_G\/T\9FVd#?Z_ir@lhL=5Yig'>fPmcqOUfg1,~>
-#$LBV\^d1YJ`_OGT]Q9lgl1A"li5YgLXYejeHa-In)qLUg-U;~>
-#$LBV\^c7gJZOF(JZPiP#.j6SeVDWDqpbqlKCA!=nCg3Z~>
-#$LBV\D!1KJ_G\/J_I*W#3,[>g4n&Hqq;:uJaVg;nC^*X~>
-#$LBV\^d1YJ`_OGJ``ro#4)<BeVDWDqpbqlKCA!=nCg3Z~>
-#$LBV\^c7gJZOF(]rV:"2-0^X!i)ilmAp>bWr9"#UTC6iX9)E[Q2[ic?`*h(!iS4DUoXd3map!E
-e+*=c#KMJckJ6T@6@]~>
-#$LBV\D!1KJ_G\/^"NP#6Z)hV!m]NFmFhTgfDXD)cJ$SCg&c(X]`-UcH.2cH!nBt;UtQ%4s5)Ia
-ddm:h#Kq\dlFuc@6%A~>
-#$LBV\^d1YJ`_OG^#fC97s"[l!nl_imH+H)j8J*Ag?.)fjoTQna8Y3%J):1e!oZsPUuhmIs4PqX
-e+*=c#KMJckJ6T@6@]~>
-#$LBV\^c7gJZOF(]rV6n>lC`*4K1R4X8u=brN$&aW]^6]!F1T_X9!lbr2]l\UoXd3map!Ee+*=c
-#KMJckJ6T@6@]~>
-#$LBV\D!1KJ_G\/^"NLlFoC"q9\*&-g&Z$$rRq<Kf1c.s!HbXHg&[t$r7V-EUtQ%4s5)Iaddm:h
-#Kq\dlFuc@6%A~>
-#$LBV\^d1YJ`_OG^#f@-Hi<(.:uYIAjoKM@rT4/[j&#^:!IMHXjoMQ@r8muUUuhmIs4PqXe+*=c
-#KMJckJ6T@6@]~>
-#$LBV\^c7gJZOF(]rV6n>lC`G4K1QHXArbi4H-@o4?RbfX*$NeK<1L_1H_>3X?NXHrN$$)N;fmZ
-JS4n^!'I'Y#.j6SeVDWDqpbqlKCA!=nCg3Z~>
-#$LBV\D!1KJ_G\/^"NLlFoC#99\*%og1u,C9X<BL9MC](fp#0(VV8s85toJUg/$<orRq9oZMrPY
-UP&Ku!)03B#3,[>g4n&Hqq;:uJaVg;nC^*X~>
-#$LBV\^d1YJ`_OG^#f@-Hi<(K:uYI:k&H'e:qYqo:f*\Djd].DYNF.Z6r;Ltk#:;:rT4--]Dgpn
-XGZr<!)TKR#4)<BeVDWDqpbqlKCA!=nCg3Z~>
-#$LBV\^c7gJZOF(]rV6n>lC`@EN4)]XI:SHXDrc(XK6JcF`XXcBRm0aPPqQaF/s<ZX8uRbri?0d
-=/c)!!'I'Y#.j6SeVDWDqpbqlKCA!=nCg3Z~>
-#$LBV\D!1KJ_G\/^"NLlFoC#2OP#]Lg;>aog5r%^g=h^SP`jbSKVI1:])C=aOk>cog&Z<$rn7Fe
-DUn^>!)03B#3,[>g4n&Hqq;:uJaVg;nC^*X~>
-#$LBV\^d1YJ`_OG^#f@-Hi<(DQfORsk0>o;k*N-,k2r,&S=8U&MlYu\`;Sg"RH0_5joKh@roO:'
-FQ!,[!)TKR#4)<BeVDWDqpbqlKCA!=nCg3Z~>
-#$LBV\^c7gJZOF(]rV6n>kkB)RR!aOXA>8`XT(E^X9=qeXAtJXX8uRbri?0W@B0:-!'I'Y#.j6S
-eVDWDqpbqlKCA!=nCg3Z~>
-#$LBV\D!1KJ_G\/^"NLlFnjYp_c"q:g18)"gAakGg'#9'g2+@og&Z<$rn7FUHeA;N!)03B#3,[>
-g4n&Hqq;:uJaVg;nC^*X~>
-#$LBV\^d1YJ`_OG^#f@-Hhc_-c;rfak%W*>k5S9WjoinCk&SE6joKh@roO9jK&lmm!)TKR#4)<B
-eVDWDqpbqlKCA!=nCg3Z~>
-#$LBV\^c7gJZOF(]rV6n>kkB$RSNj`"+P$dXSm8@X9N?fXAtIcEql^:>`AZ`!J+n]X8kB]X9!c^
-WiQE9map!Ee+*=c#KMJckJ6T@6@]~>
-#$LBV\D!1KJ_G\/^"NLlFnjYk_di]""JLP'g62H!s4R[1U=sFpg5u*`!HbXHg&[t$r7V-ErRq:E
[email protected]@lhL=5Yig'>fPmcqOUfg1,~>
-#$LBV\^d1YJ`_OG^#f@-Hhc_(c=m4>&?:]Ok*hg0S*&jlWoe??k*Yr+!IMHXjoMQ@r8muUrT4-Z
-LoTSAli5YgLXYejeHa-In)qLUg-U;~>
-#$LBV\^c7gJZOF(]rV6n>kkB%<A7/HX:KnF4ER[*F?D[<XK8*e4HfK@!F1T_X9!lbr2]l\ri?0u
-5s;6L#.j6SeVDWDqpbqlKCA!=nCg3Z~>
-#$LBV\D!1KJ_G\/^"NLlFnjYlCHQ&)g(1#R9U"/_P>"ZIg=jbV9Y'rP!HbXHg&[t$r7V-Ern7G%
-;GF1F#3,[>g4n&Hqq;:uJaVg;nC^*X~>
-#$LBV\^d1YJ`_OG^#f@-Hhc_)EBn19jq"Uk:n6Y/Rnuqbk2t9):rE(j!IMHXjoMQ@r8muUroO:=
-=&Q'\#4)<BeVDWDqpbqlKCA!=nCg3Z~>
-#$LBV\^c7gJZOF(]rV9o-t1l3!b!L9ri?-(NrH*]W(S?6X9+G<U8k:!]'e2#LXYejeHa-In)qLU
-g-U;~>
-#$LBV\D!1KJ_G\/^"NOm1OIm1!dc`/rn7Bn[/Sb\emBs,g&eZIc)TJ%ir@lhL=5Yig'>fPmcqOU
-fg1,~>
-#$LBV\^d1YJ`_OG^#fC.2M0]G!eN;AroO6+^Ad6riFFP>joW:bfrF0=li5YgLXYejeHa-In)qLU
-g-U;~>
-#$LBV\^c7gJZOF(]rV:7SY4`=!hc*`ri?*orN$($SY#h^!NDopX9Q9(f@>Z*nb^iAa+NjD_!p&E
-J,~>
-#$LBV\D!1KJ_G\/^"NP=a335k!mAX8rn7@trRq>+a3">7!S>_ug'6R:hV*_4o)%,GbCT*H^@9fA
-J,~>
-#$LBV\^d1YJ`_OG^#fCUdb!79!nYl[roO46rT41Cda\9Y!TVt7jp(/Og!tl,nb^iAa+NjD_!p&E
-J,~>
-#$LBV\^c7gJZOF(JZPiP#.j6SeVDWDqpbqlKCA!=nCg3Z~>
-#$LBV\D!1KJ_G\/J_I*W#3,[>g4n&Hqq;:uJaVg;nC^*X~>
-#$LBV\^d1YJ`_OGJ``ro#4)<BeVDWDqpbqlKCA!=nCg3Z~>
-#$LBV\^c7gJZOF(frP3oHfhC1<13<Y"c[bpMI/g7X8n^gGQ<crX8o0tGQ<<(X9Q9(f@>Z*nb^iA
-a+NjD_!p&EJ,~>
-#$LBV\D!1KJ_G\/g"HIgSEAN+C;TPq"gaT4YBX.2g&T%iQiOMcg&TY%QiNnjg'6R:hV*_4o)%,G
-bCT*H^@9fAJ,~>
-#$LBV\^d1YJ`_OGg#`=%V<6n@E6Rn8"hgSQ\:7cGjoE^+TE)^ujoF?=TE)(&jp(/Og!tl,nb^iA
-a+NjD_!p&EJ,~>
-#$LBV\^c7gJZOF(frP09jfAKAV=UbmO]ud#3iG=+X9Ft=E,]!EorJ=p5?Ml;GIX^Y]'e2#LXYej
-eHa-In)qLUg-U;~>
-#$LBV\D!1KJ_G\/g"HF"jk9a?dIZ&r\9![@8_$]#g',8INfJ.kp"BSu:iMGIQFPWQir@lhL=5Yi
-g'>fPmcqOUfg1,~>
-#$LBV\^d1YJ`_OGg#`92jlQTUh=Kb5_KhG^:#T+7jorpbQBld7p#ZG8<Ha[cT=F"fli5YgLXYej
-eHa-In)qLUg-U;~>
-#$LBV\^c7gJZOF(frP09ri@#I4?OO`XHH(9EibHCN_iE9-S_]#)jRL"*16`,$Xl.n/$,UM4BA5Y
-4T;EUA#LkM4DLsm<]iKiX>*4.5)65'83BinS?-Ee9:)_BXK5lcXJ/]W=f8?24?OO`XC6mcN`r&Q
-4?S.qKGp(H;ii)#**4&NLH[gIHI&Ys]'e2#LXYejeHa-In)qLUg-U;~>
-#$LBV\D!1KJ_G\/g"HF"rn89=9M?V`g:1<[OkRAhZt3[\0g=<),/)]?,JjB5$[YQX2VQSu9Pr)/
-9`Ea>Iap;_9S_?ID+mWlg-/\7:93*[>>/f[`nH,?@)(Dhg=gqRg<FG-ERWWi9M?V`g3]mSZuX9&
-9MD58W$8l[BsoC(,]4aHX%l>CRa9[lir@lhL=5Yig'>fPmcqOUfg1,~>
-#$LBV\^d1YJ`_OGg#`92roP,P:f&D!k/1P&RHDF3^2%?&1dU8A,ff%\--Q;M$\D2i3Tf1A:ik@Q
-;#]TNK]+n$:la\kF&5]-k!EEP;RGT)?r1ekdH6BaA]a(2k2q<&k1F]NGMhP9:f&@uk(9u&^3S4G
-:f+7UYp77tDnmf@-?LH]Zr9dWUX/',li5YgLXYejeHa-In)qLUg-U;~>
-#$LBV\^c7gJZOF(g8k<pG5eQX5GY*2XJ&FXUi(:U8Oo/<RW3PQQVma`&5\aqXC6mcR51jFLnoo.
-X??H_9;jG5X?<S[NhiI4XEmR@Va7(TTWE$5XD)mSPtA#=UmtJYXAk+RLKLWBUnigJXC6[UM-cm<
-Ung,SX>X%MQ(_;t;0>I&7\?K@S^4AA]'e2#LXYejeHa-In)qLUg-U;~>
-#$LBV\D!1KJ_G\/g=cRhQN#SQ:XIIig<=*Ed#4(@?!G.a`/g5<^M!Q"&7r]3g3]mS_EZamXO+.d
-g._J!9@Z#Cg.^5I[*[/mg7)O(do+M(bM%kmg4ks@]j9;bd)BkFg1mk=X)Qcgd*SlJg3]UAX`qsu
-d*PG>g-obu^!(GRAsHZD=j#+(a3WHDir@lhL=5Yig'>fPmcqOUfg1,~>
-#$LBV\^d1YJ`_OGg?&F'T)Rje<8?9:k1==lgln5i@UI=*cBk0ca_h%>&8TJOk(9u&bsUW9[bSE5
-k"u$=9Ar"]k"t3p^>.L>k+cPMhcJNJf&i0>k)H%ha(".,gsC,nk&@oe[!(S2gt]="k(9\i[slrG
-gtY`gk"0OAa4GKuCn5%b?IdiNda.%[li5YgLXYejeHa-In)qLUg-U;~>
-#$LBV\^c7gJZOF(frP09ri?<_6ptIbS0%Yt"+.+@TDbhm4KL[DX9DFfXK4^crN#uRr^6fiX??H_
-)5og%X?<SX<^]>1XEnccVa6qHXK7LcX@teV6jKbP6q;s4X=F3;'ORr#6ptFaXC3tS<ihij6ps#9
-X??H_$<WBeQV!gN7mp4Ac`@>^map!Ee+*=c#KMJckJ6T@6@]~>
-#$LBV\D!1KJ_G\/g"HF"rn7R]<`XP#`[:[c".\(Nao0op9\N2=g')'(g=fHSrRq68r`0)=g._J!
-):_U<g.^5FD,s\$g7+#Sdo+=ng=iuRg0mbU<X7;J<a)KVg,8k1'R8?;<`XP#g3Z1fD;*$F<`V`E
-g._J!$?3Fc^g5(9>#o7Oce8T_s5)Iaddm:h#Kq\dlFuc@6%A~>
-#$LBV\^d1YJ`_OGg#`92roOEs>?c[@d4"uu"/P'geG\M2;!(UQjooPDk2o_&rT4)Gr`]GIk"u$=
-)<"TXk"t3mF'Dj8k+e.&hcJ?:k2sL'k%7Nj>6j7_>@+VtjuE?E'S#8X>?cX?k(6*-F6:ni>?ab_
-k"u$=$?j4$b$rl_?X%?jcfPGts4PqXe+*=c#KMJckJ6T@6@]~>
-#$LBV\^c7gJZOF(frP09ri?T/SXi'JW+(RRMg)-fOJ`#Y!f/CGriB\'8W'CHOBnEJ?EAcmSXj2j
-FEO.FA"G`[VDb67=.NtUVJp(ISNEWWL7L_7XHQkZSR/0OU8VRYXF+oVSRS["SXi'JX&s_EXK7:e
-SRF=PV`(*EXK#*N;2n/4?(%6uI]TVl5LZ\<]'e2#LXYejeHa-In)qLUg-U;~>
-#$LBV\D!1KJ_G\/g"HF"rn7it`l:s2eU4L=Ya<p@\'t?1!j"A@rn:r+>d)T0[s#d2GhT$I`l<>Y
-PEa),IE5%2dRDKoDT7;gdZ/h2a%Od-WlA(Xg:MFG`d#p#cII?Gg7=/A`dHKU`l:s2fPm>,g=i]T
-`d9u"dm_:,g=Kr9B!YdUG/D7RT\A+^:t+,&ir@lhL=5Yig'>fPmcqOUfg1,~>
-#$LBV\^d1YJ`_OGg#`92roO]0dEu%XiIeSd\t@qa_;>1R!k(1UroReB@Cb4V_0jYXIcdhldF!O-
-S".mRK[W]Sh+?A?FO>t.hNilXdSJYO[*`*$k/DVnd=0qDg#7Unk,+?id=UM#dEu%XjE@?Rk2s1(
-d=OdDhau5Sk2U9`CqX;uI*ButWTN?2<7Bt6li5YgLXYejeHa-In)qLUg-U;~>
-#$LBV\^c7gJZOF(frP09ri?2t91t?FX9W-+?*'>b98EMJ!iJ\UriAXp91so=XGokGOK>O691thW
-XE.$-WbY7iKM-QkHV8lhKi(LDC.j_k@S;/PXK7XZ98\X#ENH6YXK6_@9;ARb91t>IUe=@,ri?u[
-98?<$MG$U+XIi-kH!tf,E(`iAXK83T9%0jG]'e2#LXYejeHa-In)qLUg-U;~>
-#$LBV\D!1KJ_G\/g"HF"rn7Hb?XL5?g';n1G1sZ;?`X1[!n1Mgrn9na?XK_bg9Y-n\(]Q1?XLk-
-g6,fMf8!_CVdGhFS6r%-W+TJiL0qIEHs`Obg=j/G?`pV?O4r<Fg=i$'?dIG;?XL4pcX1%Jrn86S
-?`R_AY?tYKg<!]FR<t0LNaH.Pg=jnA?IRU4ir@lhL=5Yig'>fPmcqOUfg1,~>
-#$LBV\^d1YJ`_OGg#`92roO;tAS&XUjp-EJI-/O^A[VO"!oIS/roQasAS&+.k.P>;_<0m\AS'<P
-k*fjmj,[cgY[sKiV.H`KZ#""4Nb-,jJn:p)k2sWoA[o<_QKI=mk2rFMA_Q9^AS&X=gLXrkroP)h
-A[H3`\7K6jk1!siTn8ejQ=XWkk2tGhA(0QEli5YgLXYejeHa-In)qLUg-U;~>
-#$LBV\^c7gJZOF(frY4#^T7R4Q'GL@bH(c98Ysn;#.j6SeVDWDqpbqlKCA!=nCg3Z~>
-#$LBV\D!1KJ_G\/g"QIr^Y/h9]tJC&bM!$<?.%-T#3,[>g4n&Hqq;:uJaVg;nC^*X~>
-#$LBV\^d1YJ`_OGg#i=2^ZG[Pa2`DLbN8lS@bfGp#4)<BeVDWDqpbqlKCA!=nCg3Z~>
-#$LBV\^c7gJZOF(Q)k(B;cB3SX9Q9(f@>Z*nb^iAa+NjD_!p&EJ,~>
-#$LBV\D!1KJ_G\/Q.c>?BkbPSg'6R:hV*_4o)%,GbCT*H^@9fAJ,~>
-#$LBV\^d1YJ`_OGQ0&1UDf=!jjp(/Og!tl,nb^iAa+NjD_!p&EJ,~>
-#$LBV\^c7gJZOF(_5mX(i2csVT'iZ\U5ktL#.j6SeVDWDqpbqlKCA!=nCg3Z~>
-#$LBV\D!1KJ_G\/_:en*i7\4[aR7a_c*a;"#3,[>g4n&Hqq;:uJaVg;nC^*X~>
-#$LBV\^d1YJ`_OG_<(a@i8t'se*c?!fY4*B#4)<BeVDWDqpbqlKCA!=nCg3Z~>
-#$LBV\^c7gJZOF(_Q3co@/d5.RtCU?"&r3WP3o=OM-fbS"dMr$Ef_L,XSu&s>4\fqB`:j/T'`TZ
-EU'V0]'e2#LXYejeHa-In)qLUg-U;~>
-#$LBV\D!1KJ_G\/_V,$lHN)V!`23Fd");PS\aA)OY'BNk"heQ*OL?_&g&Th*B)luDg&Qg*B)p$?
-g&R3!g'6R:hV*_4o)%,GbCT*H^@9fAJ,~>
-#$LBV\^d1YJ`_OG_WCm,Jc=d4c`[6/")r1i_sQRe\:4#2"itPCR(t?:joFNBD#ehPjoC>=D#i&P
-joCb5jp(/Og!tl,nb^iAa+NjD_!p&EJ,~>
-#$LBV\^c7gJZOF(_Q3cNJc;_ON*Q@`)GZK]-@;hqRtd?4XGWOAL9$JlTq$k(XI4X%rN%o3LRt6A
-VhU/3XI!+VHki\ESVEH3XJU`,S#hm;PD5a3XIFs3N1-iLM2&(4@;;*c=KJU#L5u87*f#K)Tra5@
-QBk%BUP=MpXK.)LS;OD-R>dVmS?/eSlDt3$map!Ee+*=c#KMJckJ6T@6@]~>
-#$LBV\D!1KJ_G\/_V,$BV#K'KZ$$'")Ip@l0UpeM`2UW-g98N?WS+h]bf6Wtg;9YqrRs00X2rQ>
-e>]_,g:q[CSK$3Ta/Qf,g<ut"`S/#8\uEm,g;U&-ZGYDMY,U(-H\T;=E8'$nWO2ZY*il9>bhB@'
-^V<q*c`*nbg=`IL`in+&_Qh%_`nK-?lIlI%s5)Iaddm:h#Kq\dlFuc@6%A~>
-#$LBV\^d1YJ`_OG_WClUXo@G`]6jP>)JI(01Sj0qca1jXk.&gkZfT*2f[7%Jk00sErT=-e1t1+>
-i3U&Xk/qqjV&\Pmd^.'Xk2!AMd,rBc`O".Xk0UHX][#[%\$P/XJrRm_G37rCZbHG$*ji8[fB0_L
-aiRlOg9\-7k2ir$dCA>Pbe)32dH9RflK/<:s4PqXe+*=c#KMJckJ6T@6@]~>
-#$LBV\^c7gJZOF(_Q3cNJc;_ON*Q@`)F::&OdE/D<FT""XA`\3@VU-5Q]32BXG9PWriB7>@UUm;
-XCG^GI&p#2XK6fM3)a9gQE4G&@T9+P)d6]NXJ8a(<Z[+!FC8QlXD`BcS4p#c?Xd;mXD_NV5C0E#
-9rtEYXBT.C;lQf]F];am@O4Yq87em(4R0!P]'e2#LXYejeHa-In)qLUg-U;~>
-#$LBV\D!1KJ_G\/_V,$BV#K'KZ$$'")H,)=\A-bBCj^*?g1c(TI#"(A^p>Phg8e_.rn:M5I![oG
-g4"EnS_@Mkg=i.O7qm?h^=mj[Hu%'%,'&'Ig<XP^DC2L>PBqV1g5VNS`aINSG^OY1g5UH,:n$+V
-@bTO0g2hXhC"M!5P\PK0HnSh_>CbG]9^:=9ir@lhL=5Yig'>fPmcqOUfg1,~>
-#$LBV\^d1YJ`_OG_WClUXo@G`]6jP>)HPeY_TM#nEJ&>\k&6#sK8uTZb.TF4k-SiOroR@HK7Z7a
-k(SG:VWML;k2rQ&95fH*al\,+K5oVF,^=r^k1am.F==W\Rt63Ok*;Y&ct;G&IY3$Nk*:ON<28U%
-BBJ>Qk';T3Dr]nWS8a"MK/$pq@#*n,;!R0Ili5YgLXYejeHa-In)qLUg-U;~>
-#$LBV\^c7gJZOF(_lNp:;4[]f!NDsqX;.Kp4B.rS5B_L"4KO/[S?/Kb9V7_Kri?]g?EC5WC94LY
-M.p1CHp3iiS,KEZ4/8ldL9-knIQ*h!32`i?X@/kcV)bW67X]_`G&LK3<hug(@X`Y`TO)toMQ!VG
-3IZEUXI+Hc0;tsh0r1kGP#$m7JRtpaU["ob]'e2#LXYejeHa-In)qLUg-U;~>
-#$LBV\D!1KJ_G\/_qG1?B?1#*!S>d!g(hq09P_c(:R7Z?9\Q?q`S/Vg@*6>srn7seGhUlEL>(=E
-Y(^tjSPQt.`VnL]9@)=>WS5=aTLQrT8(?6dg/cSSdRi/q=Iu1!Q&TaUD:%!^IA!*#bBKMMY1;7E
-8>)Vig;0GT4Oi)B51%s/\R_gZUk%1QcKa*fir@lhL=5Yig'>fPmcqOUfg1,~>
-#$LBV\^d1YJ`_OG_r_$WCsr=F!TMr7jqZTL:iOqH<1^(];!+r7d,s'AA_#">roOg&IcfdlNTT>l
-\;bg6VGkQJd/E)t:YY#aZf]T5WCkS#9&Jc-k$-U&h+d%@?)OZ>Ss=JuF55o-KW1b>epaHp\DcSr
-9W>"/k00g(5N([e6/1JU_eQW$XbZ'$g?Rf)li5YgLXYejeHa-In)qLUg-U;~>
-#$LBV\^c7gJZOF(_Q3cNJbcAOC8n:OH`T+(C'/[]K4Y"_")N?qKDqqUM-d9bH>`\_!Fo%,C'(/(
-S,KE#4KPVnL9+WpC+c'Y4KPVHX??K`"$EZ>4T9($Q#B90<iiB)=T3%LVlX]L>`GhS05>6qXB94P
-.&a4aHiC)MP#dHHK4X5I#.j6SeVDWDqpbqlKCA!=nCg3Z~>
-#$LBV\D!1KJ_G\/_V,$BV"r^KL=Y(9S(^7/L'*aqVL\X!",WRuVuGBRY'A[SRu@7!!Ie\\L'#Y/
-`VnL&9\S3JWS2HKL-*E/9\S2og._M""&.FK9`BbP]o??QD;*]_E;kS+eCob6FL0]>4GJU8g2D_#
-1=Y$8SGq4G\S\NoVL[j`#3,[>g4n&Hqq;:uJaVg;nC^*X~>
-#$LBV\^d1YJ`_OG_WClUXnh)`NoK2aUuk2HN<>g8YD<)="-KI8Yl<bg\:3T&UQbZ=!JPCiN<7gG
-d/E)=;!-nmZfZUoNBYbP;!-n:k"u'>"&S-d;#ZF[aH^7pF6;V.G5dI8hr^#[HG/Ie5E1ZTk&lZC
-2;mV[V#KK[_fNA:YD;<'#4)<BeVDWDqpbqlKCA!=nCg3Z~>
-#$LBV\^c7gJZOF(_Q3cNJbcAW5tuN0MQE=KG'7)k?q,nMXA5cO8ZSqoO^CD-XK#`QG$p</>BY0m
-S>]G2G#=YVMl9$RXB'LZ)L@>kR@,L^SlKr;.BKRbEctuI9ie?d<hZKpG'6l\7<<WZM6(qZIf?D\
-;KcXfKr[jHN3'+!4+]_G7]H9d!gs7OnZ2r+map!Ee+*=c#KMJckJ6T@6@]~>
-#$LBV\D!1KJ_G\/_V,$BV"r^S;IYr:YM.!6QBlUGH<@0Gg.p6c>hIca\9LoLg=Ue<Q?omhF-`,2
-`n"slQ=dujYgld&g23.1+e#Ym_SS.7aD@/`1YUK9OHtBq@;X`=D9URMQBl=4=H\tqY1f71T`3XW
-BU45iW7bNnZJ+#l9;POX=P!B'!l>5Kn_+3,s5)Iaddm:h#Kq\dlFuc@6%A~>
-#$LBV\^d1YJ`_OG_WClUXnh)h<bJ"R\`V:]St:5iJ6fM\k"ar)@H?S5_LGXkk2_/cSq4T7HCg^O
-dG]):SnuV0]&6bFk&[,S,GVk0c-82YdrM%*2Wj([R%B&<Aom+_F4]DpSt9rU?(.@7\E9GSWW)#l
-DOu\+Z/oM9]]S@A:Td`r?/b\C!mM"`n`C&As4PqXe+*=c#KMJckJ6T@6@]~>
-#$LBV\^c7gJZOF(_Q3cNJbcALLR<(:ri??eEH.bTG]A?6X9!p1ri?3^EH-O.X<hn,Lod\SEH.&@
-XIX?NQ^DcKVf@!`U2bX?JV\<5QuRq`P&ZIDri?r[EJ1E5FKDR,TWFi,EKdJ[EH-`7XFP;:ri?^'
-EIrt!X)W-9XK6hiQuSL5W;EXt:Gnj9X9Q9(f@>Z*nb^iAa+NjD_!p&EJ,~>
-#$LBV\D!1KJ_G\/_V,$CU\WUGXMBpurn7UeOH@fBR#n0Cg&\%Rrn7I^OH?49g*MlCXP2CUOH?p)
-g;f;:^ql,6e<$*Pc&eU&UTKWn^lY\P\ra6mrn83TOJgfoPM4a$b1b($OLj/IOH?Krg7j[trn7t+
-OJJtVfoV;ug=i-[^lZ?nebe&%A4+T2g'6R:hV*_4o)%,GbCT*H^@9fAJ,~>
-#$LBV\^d1YJ`_OG_WClVXSLu\[EFrEroOI&R$cUiTU;n\joMWproO<sR$arRjs?F_[H?W-R$b\O
-k0fWab0-0\i0^5#fpJ_LXL=M>bF#a#`0e27roP&hR'>_?SEAtOf&kVPR)S3qR$b8Ck,XlEroOgB
-R'!d$jd;FFk2rS/bF$J?iVVa=Bh-eFjp(/Og!tl,nb^iAa+NjD_!p&EJ,~>
-#$LBV\^c7gJZOF(_5mWI\Z>q3Df8^Fb,bSRn#Q`)map!Ee+*=c#KMJckJ6T@6@]~>
-#$LBV\D!1KJ_G\/_:em<\_728NK%hmb1ZiEn(J!*s5)Iaddm:h#Kq\dlFuc@6%A~>
-#$LBV\^d1YJ`_OG_<(`O\`O%PPa$:6b2r\Xn)ai?s4PqXe+*=c#KMJckJ6T@6@]~>
-#$LBV\^c7gJZOF(JZSXJ"/pKjOg_=q]'e2#LXYejeHa-In)qLUg-U;~>
-#$LBV\D!1KJ_G\/J_KnQ"4Wa,\@1)qir@lhL=5Yig'>fPmcqOUfg1,~>
-#$LBV\^d1YJ`_OGJ`cai"5ooJ_m\\3li5YgLXYejeHa-In)qLUg-U;~>
-#$LBV\^c7gJZOF(WiQ5hPPqQ`O)OTj!K<Y=X9Q9(f@>Z*nb^iAa+NjD_!p&EJ,~>
-#$LBV\D!1KJ_G\/WnIKi])C=`[Z0k3!O9e8g'6R:hV*_4o)%,GbCT*H^@9fAJ,~>
-#$LBV\^d1YJ`_OGWoa?+`;Sg!^m+EP!P?mMjp(/Og!tl,nb^iAa+NjD_!p&EJ,~>
-#$LBV\^c7gJZOF(WiQ4pSGfMiRPOH8!Fq2_X9Ef#DNlqYXK2W;map!Ee+*=c#KMJckJ6T@6@]~>
-#$LBV\D!1KJ_G\/WnIJ]`r4Tl_a!_G!IhKLg'*g)MnD;nXP*m<s5)Iaddm:h#Kq\dlFuc@6%A~>
-#$LBV\^d1YJ`_OGWoa=ndJ`2.c9h*a!JS>]joqA@PK$"5XQB`Qs4PqXe+*=c#KMJckJ6T@6@]~>
-#$LBV\^c7gJZOF(WiQ1_ri?3`@"1<<X:8rQUo\*7X*A$=XDqX>ri@61@!6mtXH-b>XK3sRU._&Y
-Q!e!bXE9#4KPcOHXCbk>]rVFLmap!Ee+*=c#KMJckJ6T@6@]~>
-#$LBV\D!1KJ_G\/WnIGHrn7I_H(dq2g'rg_d+WtpfpI'"g5gO#rn8L3H'XuRg9l4$g=eK&c!SKE
-]m4n9g6/4kW/@\1g4=P#^"N\Ms5)Iaddm:h#Kq\dlFuc@6%A~>
-#$LBV\^d1YJ`_OGWoa:XroO<uJ>uHFjpdB%[email protected]*LVIroP?IJ=`Ruk.cGJk2n^GfO`Im
-a+/]\k*rH<Z&uHVk(nQI^#fObs4PqXe+*=c#KMJckJ6T@6@]~>
-#$LBV\^c7gJZOF(X/nLV9!#+_=GUW6XJfc[LfpH^=0%E>U9'GJN3'+Q=GUu4X-d%GB7m9J?\h@G
-XB::78?@OaAfYAbVdb76>,8m6#.j6SeVDWDqpbqlKCA!=nCg3Z~>
-#$LBV\D!1KJ_G\/X4fbY?J=,NE34dCg=:hIX`;X7DV;HacJ#a4ZJ+$SDlo*?fYMR0K;R?rH*(Gn
-g2O0r>hZ/#JL#\bdsS!oEmVPS#3,[>g4n&Hqq;:uJaVg;nC^*X~>
-#$LBV\^d1YJ`_OGX6)UpA*2puG.*>]k2D2q[WgDXFQL;,g#g+Z]B88*FgdYWjNMhVMQl5>J@9%:
-k'"2A@HOm@LaIh$hh/)?Gh]sp#4)<BeVDWDqpbqlKCA!=nCg3Z~>
-#$LBV\^c7gJZOF(X/lGKE3--'ri?MjXH>&9=@-V`=0$Cbri?H3N3'*SS#i]4X#^/](b)OKX?9.H
-XHQag,-7>.PuE]HL,)k54`S3;#.j6SeVDWDqpbqlKCA!=nCg3Z~>
-#$LBV\D!1KJ_G\/X4d]ENS<)[rn7cSg:0+]E)_D"DV1):rn7^$ZJ+#@`S0%/fgu*](c9r?g.Ykn
-g:D6B/)&$N]kOioW]tHA9om$B#3,[>g4n&Hqq;:uJaVg;nC^*X~>
-#$LBV\^d1YJ`_OGX6'PYQ0.4*roOVck/'3'G$0X>FQAj\roOQ7]B86fd,sJZj\5Ys(cUSRk"oX:
-k/;Fd0':SmaDS_;ZU8nZ;4##Z#4)<BeVDWDqpbqlKCA!=nCg3Z~>
-#$LBV\^c7gJZOF(WiQgqXK56cXIh>NQ:QpqLm4u>MamZH.U7q6XBpdcXI-(aI#sG>X?<S2%%XIh
-OG,0cSP,5HN`qE:NKAm]XK%5T_Q3sQmap!Ee+*=c#KMJckJ6T@6@]~>
-#$LBV\D!1KJ_G\/WnJ(Zg=g,Sg;u\8^0InNXLm2#YZ^qY.WhuMg39aSg;)EPT!l)$g.^4j&B<F+
-[\u(;a'ZMoZuWK^ZaQmLg=W^X_V,4Rs5)Iaddm:h#Kq\dlFuc@6%A~>
-#$LBV\^d1YJ`_OGWoapjk2pI&k0ul_a^Mcr[`.BH\R,6s.XSeik'ji&k0)n$VSL!Hk"t39&CKWG
-^p5r^dU^F:^3RD*]tgttk2a20_WD'gs4PqXe+*=c#KMJckJ6T@6@]~>
-#$LBV\^c7gJZOF(WiQgqXK8F':fSTaXFjDI;i@`Y!d4LD.qL4tJ#o_[:f(8pWE2nm@t>VMRjai/
->YnBAFC?DG-[mP<ISip@OK>2WJASAl]'e2#LXYejeHa-In)qLUg-U;~>
-#$LBV\D!1KJ_G\/WnJ(Zg=k1tAo&iag8AUrBsHCG"-rl>.tKTWU"\4HAnGu7eo,/4I\S-^`&#Ee
-FCo;:PC"jV0q^DITP%kO\(]..UVb^hir@lhL=5Yig'>fPmcqOUfg1,~>
-#$LBV\^d1YJ`_OGWoapjk2t]HCiUu#k-/`>Dn>)n".fGR.u62fWoiGpCi"7UicT'RKrcT$cSj25
-HYd[ORt<;q1oNCbWGQHj_<0JPXMX*(li5YgLXYejeHa-In)qLUg-U;~>
-#$LBV\^c7gJZOF(WiQY%SZJogQ_9kBXK7nXSc5\kR&0e`/"DrmU9(GoQ^=PMXJD2LVkTNPXIuSp
-VO*pHTUhFGQ_g%JXI5EHXK4cgVo#M>]'e2#LXYejeHa-In)qLUg-U;~>
-#$LBV\D!1KJ_G\/WnIngaP,@p^rsaAg=jK\`r=Zm^s`59/&oB?c.^n#^qe@Og<dXNeBYkSg<8.&
-d_NuGb/_<F^sTsLg;:YHg=fPAe&'fCir@lhL=5Yig'>fPmcqOUfg1,~>
-#$LBV\^d1YJ`_OGWoab#e)ofJbLY(mk2t"5dJi8/bME0[/()P`g#hGSbKJ]'k1e)&i7Z<,k1A\V
-hTOEte^DXrbM:;#k0;)uk2ofchnnL[li5YgLXYejeHa-In)qLUg-U;~>
-#$LBV\^c7gJZOF(WiQ5fOi4=$IDDog]'e2#LXYejeHa-In)qLUg-U;~>
-#$LBV\D!1KJ_G\/WnIKh\A[)$T"s%air@lhL=5Yig'>fPmcqOUfg1,~>
-#$LBV\^d1YJ`_OGWoa?)_SkR:VnhF!li5YgLXYejeHa-In)qLUg-U;~>
-#$LBV\^c7gJZOF(JZPiP#.j6SeVDWDqpbqlKCA!=nCg3Z~>
-#$LBV\D!1KJ_G\/J_I*W#3,[>g4n&Hqq;:uJaVg;nC^*X~>
-#$LBV\^d1YJ`_OGJ``ro#4)<BeVDWDqpbqlKCA!=nCg3Z~>
-#$LBV\^c7gJZOF(JZR.u!JQNiX9Q9(f@>Z*nb^iAa+NjD_!p&EJ,~>
-#$LBV\D!1KJ_G\/J_JE'!N<?]g'6R:hV*_4o)%,GbCT*H^@9fAJ,~>
-#$LBV\^d1YJ`_OGJ`b8?!OBDqjp(/Og!tl,nb^iAa+NjD_!p&EJ,~>
-#$LBV\^c7gJZOF(PcOpNX?Z*R!IAeVX9)ZSK)VhQ:*5kpX9XGkIVu6gW]o:@#.j6SeVDWDqpbql
-KCA!=nCg3Z~>
-#$LBV\D!1KJ_G\/PhH18g/.1j!Lf,?g&cFOV#K'L@jf(`g'=U/T8VFWfM:;W#3,[>g4n&Hqq;:u
-JaVg;nC^*X~>
-#$LBV\^d1YJ`_OGPi`$Ik#Lg2!Mc%PjoTreXo@GaBdq6sjp/2KW0?B+j&=gs#4)<BeVDWDqpbql
-KCA!=nCg3Z~>
-#$LBV\^c7gJZOF(PcOpKX??K`+HAQh@B67f4DV!A9lW:AXK4'&4Gp574-Oe_X/g"u4Jr+Z!GI#^
-X8u1bri?Tb4CbFn=)FBgRB2'PHu/e`!'K,>#.j6SeVDWDqpbqlKCA!=nCg3Z~>
-#$LBV\D!1KJ_G\/PhH14g._M"+LFgbI+ctB9ShAg@ZO3Og=eVC9X!0q9=g?ug"D0T9[j!p!J@0G
-g&Yg$rn7j_9Rb[KDi2J,_:kf:SV[:!!)28'#3,[>g4n&Hqq;:uJaVg;nC^*X~>
-#$LBV\^d1YJ`_OGPi`$Dk"u'>+ML["K&tic:lj_1B9uGik2nlb:q5Z@:W/c<jlMP":u;36!K4&X
-joK;@roO]u:ke#nFct$HbiZ-aVNCf>!)VP7#4)<BeVDWDqpbqlKCA!=nCg3Z~>
-#$LBV\^c7gJZOF(PcP^4XCSE6M-d9B(6qauXF4lc.<hjdSZI'TrN$K;:ii%LCON:c;4"AcBRp&_
-'2b*tXG(,bKO_*Q0j(MfXHJ$mKDqqQ@>EaA#.j6SeVDWDqpbqlKCA!=nCg3Z~>
-#$LBV\D!1KJ_G\/PhHt(g4.i1Y'A[**5-"=g7F,S1mcp'`nHf?rRqa.AWjotLn<>SB><0SK;8D!
-'5#&6g8TMSW.*I=5&]/)g:Er`VZ,9MHE?#X#3,[>g4n&Hqq;:uJaVg;nC^*X~>
-#$LBV\^d1YJ`_OGPi`g;k(`$\\:3SP*lr0[k,4:&2kT5DdH7*frT4TACRWJ?O/M.&D9:r&Mlcm>
-'5YhRk-B[&Z%_>d6?VFFk/=74YQ!YbJ[OCt#4)<BeVDWDqpbqlKCA!=nCg3Z~>
-#$LBV\^c7gJZOF(O/rOZS#i]MEH_>_#s>:OXK5'cXE\^_X8uaAri?)^ri?9IENH6TJGlPX;4"Ac
-5rq+j,-77mUA(_i=c_IA#.j6SeVDWDqpbqlKCA!=nCg3Z~>
-#$LBV\D!1KJ_G\/O4jeH`S0%NO-]e!#u'&Hg=foRg6dp!g&ZPPrn7?Grn7OBO4r<?U]&mTB#*-S
-;b9YV/)%p1c1fomEOF]X#3,[>g4n&Hqq;:uJaVg;nC^*X~>
-#$LBV\^d1YJ`_OGO6-XYd,sK&Q_+3=#uKb\k2p7&k+J%=joL'jroO2WroOBVQfdFgXSq8iCs(o&
-=A;Ug/`tANf_=M/GJE%t#4)<BeVDWDqpbqlKCA!=nCg3Z~>
-#$LBV\^c7gJZOF(O/s4?Ff_ZoM-m?cN`rMHXK5'cXE\]cI]TVZL]4@]>)o\c?\tkcBRp&_$W37l
-XDN<cXF@7?:%kXg4T)8]EK'"\#.j6SeVDWDqpbqlKCA!=nCg3Z~>
-#$LBV\D!1KJ_G\/O4kJ7PhOibXa&RRZuXkog=foRg6doST\A+HX8^fZEjXQSGcocSK;8D!$YI3.
-g5;ESg7[0<@eSLU9`3TFO0[m$#3,[>g4n&Hqq;:uJaVg;nC^*X~>
-#$LBV\^d1YJ`_OGO6.=KSEAt6[t!Q&^3Jd:k2p7&k+J%&WTN>p[/T1oGeW>&J%+S&Mlcm>$Z*uJ
-k)lM&k,ILhBD1Hf;#KGVQb2AA#4)<BeVDWDqpbqlKCA!=nCg3Z~>
-#$LBV\^c7gJZOF(NiY-\4?R>ZN''4+UN[i(PU'81T2[pjXJ.."Eic@;>!+p+XK5\X0l="n:*hiH
-XK68$4E.B#,u"'7!'L4]!i$]HjfAZtmap!Ee+*=c#KMJckJ6T@6@]~>
-#$LBV\D!1KJ_G\/NnQCT9MC/oZ:mr4cBfuF]In$Sb%j\0g<MQ@OP8F6E_K03g=g^/5)\.K@kU9B
-g=hEX9TIhA/n"G-!)3@F!m`'Ajk9pus5)Iaddm:h#Kq\dlFuc@6%A~>
-#$LBV\^d1YJ`_OGNoi6h:f*,5]MMFLfq0dd`\;GqeT"ELk1M[]R-*PbGYh5Kk2q(Q6B^KnBei8W
-k2qh':mL0^0kU1B!)WXV!nnoUjlQd5s4PqXe+*=c#KMJckJ6T@6@]~>
-#$LBV\^c7gJZOF(JZR.u!K^F^X8u@$jK&Qsmap!Ee+*=c#KMJckJ6T@6@]~>
-#$LBV\D!1KJ_G\/J_JE'!OctGg&Z&+jOsgts5)Iaddm:h#Kq\dlFuc@6%A~>
-#$LBV\^d1YJ`_OGJ`b8?!PimWjoKOBjQ6[4s4PqXe+*=c#KMJckJ6T@6@]~>
-#$LBV\^c7gJZOF(JZR.u!M?+bX9"fgjK&Qsmap!Ee+*=c#KMJckJ6T@6@]~>
-#$LBV\D!1KJ_G\/J_JE'!Qr[cg&].@jOsgts5)Iaddm:h#Kq\dlFuc@6%A~>
-#$LBV\^d1YJ`_OGJ`b8?!S,m%joNfcjQ6[4s4PqXe+*=c#KMJckJ6T@6@]~>
-#$LBV\^c7gJZOF(JZPiP#.j6SeVDWDqpbqlKCA!=nCg3Z~>
-#$LBV\D!1KJ_G\/J_I*W#3,[>g4n&Hqq;:uJaVg;nC^*X~>
-#$LBV\^d1YJ`_OGJ``ro#4)<BeVDWDqpbqlKCA!=nCg3Z~>
-#$LBV\^c7gJZOF(R]HOV:&1k9V2LP=NJjm=Mi4")S;Wo=RZ!f4MjLNHP`(HhXK7J@WL/U;T`'cK
-V8TG>]'e2#LXYejeHa-In)qLUg-U;~>
-#$LBV\D!1KJ_G\/Rb@eX@en_'dBL7:Z`r09Ycu!u`j!J:_m%;.YeSoG]<JNXg=j!>f>4]8bPeXF
-dDX`Cir@lhL=5Yig'>fPmcqOUfg1,~>
-#$LBV\^d1YJ`_OGRcXXnBDL[8h7CSf]Xm7d]"6/KdCR`fc+;HY]#j*s`k&b-k2sIjilepbfDW8\
-h8JF[li5YgLXYejeHa-In)qLUg-U;~>
-#$LBV\^c7gJZOF(S#c[R=?H>[.@_h;X@57PD-^FKQ\HW;XFD@PP[-DQXDp'gK<2.P25PXBOcU\k
->r7AUX9Q9(f@>Z*nb^iAa+NjD_!p&EJ,~>
-#$LBV\D!1KJ_G\/S([qRDbBiZ.E+,&g/q&%MKO&Z^oAi_g7]t$]QHp%g5nX+VV9a;6dhJR\@*i/
-F[E1Jg'6R:hV*_4o)%,GbCT*H^@9fAJ,~>
-#$LBV\^d1YJ`_OGS)sdhF\hhq.F:"7k$:gFOaMOub-W\*k,KrE`dCVFk*SVHYNFtb7bsmk_SIaM
-HptK^jp(/Og!tl,nb^iAa+NjD_!p&EJ,~>
-#$LBV\^c7gJZOF(XK3(Z4?R>YX(a[Y0!%]>7QcF,VPQEMX;O]FDg?8GE3-.:7''1PXHc_cX@[/T
-XK5icri?K^@]ZXnXK4OcP&cZ&X9Q9(f@>Z*nb^iAa+NjD_!p&EJ,~>
-#$LBV\D!1KJ_G\/XP+>S9MC/nfnE*n3ndqK=\PjLe'Ukag)4=PNL>`mNnW45<n_-$g:_4Sg0BE*
-g=gnSrn7a[I+m:Jg=f6S\WF;=g'6R:hV*_4o)%,GbCT*H^@9fAJ,~>
-#$LBV\^d1YJ`_OGXQC1g:f*/5jc!#453?Bf?;RujhVD$'jr%ciPbOD9Q0.5`>NT\Ek/_H&k$a:K
-k2q9&roOTpKBD;mk2oM&_jJ9Yjp(/Og!tl,nb^iAa+NjD_!p&EJ,~>
-#$LBV\^c7gJZOF(XK2q\XK4XbW'IGcIB8PeTr^BUX8kBXX9M@T;flqtG5eQR4KOTHX@o+cN`qWH
-XK5icri?E\@]ZXnXK4?O,/UDc]'e2#LXYejeHa-In)qLUg-U;~>
-#$LBV\D!1KJ_G\/XP+2Wg=fBRePY&STA$e?c.Ykjg&OhAg'1ugBp4L;QN#SK9\Qmog0_kRZuW`n
-g=gnSrn7[YI+m:Jg=f##/Ag*Fir@lhL=5Yig'>fPmcqOUfg1,~>
-#$LBV\^d1YJ`_OGXQC%kk2o\&iDo%&Vrkiaf]H$0joA6Qjp#G-DjuuYT)Rj_;!,N:k%2s&]m7S:
-k2q9&roONnKBD;mk2o6C0#H`Tli5YgLXYejeHa-In)qLUg-U;~>
-#$LBV\^c7gJZOF(XK2qQ4?OCXXF!&lEibC)XK4P`X8kBXX9M@[email protected]]FC2)MB/i"4
-O/ucFXH6hE@]ZXnXK4LV=I5c#X9Q9(f@>Z*nb^iAa+NjD_!p&EJ,~>
-#$LBV\D!1KJ_G\/XP+2H9M?GVg71i1OkR<_g=f7"g&OhAg'2!)HtnV%QN#SZ9\S*5PBkj8K1AU)
-[G#u.g9u:,I+m:Jg=f3CE50Z9g'6R:hV*_4o)%,GbCT*H^@9fAJ,~>
-#$LBV\^d1YJ`_OGXQC%\:f&4lk+kgMRHDA.k2oM>joA6Qjp#GEK5[!AT)Rjn;!-eWRt'P^MG$c;
-^ZL-Tk.lMRKBD;mk2oIjG08LVjp(/Og!tl,nb^iAa+NjD_!p&EJ,~>
-#$LBV\^c7gJZOF(XK2ppXGn'qWG&B74KOZHXK4P`X8kBXX=R&7X9ig2;QQsKC94Lp:QVZZ4KPW\
-6`a^OXH$J=@]ZXnXK4OcXC-jcQp@:bX9Q9(f@>Z*nb^iAa+NjD_!p&EJ,~>
-#$LBV\D!1KJ_G\/XP+1Yg9VjNf7_l39\R!og=f7"g&OhAg+6[Og'`kRB\M14LYCIdA[^=H9\S4J
-<SDf#g9bn#I+m:Jg=f6Sg3TjS_,8=qg'6R:hV*_4o)%,GbCT*H^@9fAJ,~>
-#$LBV\^d1YJ`_OGXQC$ik.Mnrj,<'^;!,W:k2oM>joA6Qjt(,kjp[KrD<BuZNooK8C;Auo;!-oq
->3:FDk.Z,IKBD;mk2oM&k('o&bZ<98jp(/Og!tl,nb^iAa+NjD_!p&EJ,~>
-#$LBV\^c7gJZOF(XK3+r4Bc0$WB!('O/u2>Rr168N''*bqQ('i3`rJ=K<1n34DLqrX<(cNXCsUV
-Kfh@X3]fGcFfT7>4Jf-43BTDbPcSO>T#du;]'e2#LXYejeHa-In)qLUg-U;~>
-#$LBV\D!1KJ_G\/XP+Ar9QPQ,f1AY0[G#4a`Jd?\YtR\bqUu=j8T3=`VV9Ek9S_=#g)bRog4W!j
-WD#lW8kViNPhCgc9[VRm85)]L]@qoaaN3'>ir@lhL=5Yig'>fPmcqOUfg1,~>
-#$LBV\^d1YJ`_OGXQC53:jIYDi_<6G^ZK?,d$.5']221$qW81+9m,U*YNFY;:laZ:jrT*9k)2o0
-Z;=7l:/=\^SE5c-:u(3<9MeP\`TE+,e&^YUli5YgLXYejeHa-In)qLUg-U;~>
-#$LBV\^c7gJZOF(Q)sk^f;o!0OiOO-]'e2#LXYejeHa-In)qLUg-U;~>
-#$LBV\D!1KJ_G\/Q.l/e!8#iV!CF<:g'6R:hV*_4o)%,GbCT*H^@9fAJ,~>
-#$LBV\^d1YJ`_OGQ0/#'!92Vm!CaoHjp(/Og!tl,nb^iAa+NjD_!p&EJ,~>
-#$LBV\^c7gJZOF(QE1(^r'(0^S#ch*map!Ee+*=c#KMJckJ6T@6@]~>
-#$LBV\D!1KJ_G\/QJ)>cr(mB1S(\)+s5)Iaddm:h#Kq\dlFuc@6%A~>
-#$LBV\^d1YJ`_OGQKA2%r)E`<S)sq@s4PqXe+*=c#KMJckJ6T@6@]~>
-#$LBV\^c7gJZOF(RB-CbP,nl!map!Ee+*=c#KMJckJ6T@6@]~>
-#$LBV\D!1KJ_G\/RG%YgP1g-"s5)Iaddm:h#Kq\dlFuc@6%A~>
-#$LBV\^d1YJ`_OGRH=M)P3)u7s4PqXe+*=c#KMJckJ6T@6@]~>
-#$LBV\^c7gJZOF(R]HO>48Gs'SRm#HBk=?EAS$OrMIh[HKOp73AU^_^G\(HAXK6;NVL`<CPPo%m
-S]%T6]'e2#LXYejeHa-In)qLUg-U;~>
-#$LBV\D!1KJ_G\/Rb@e99DR9ea+0N1Kn.k.J:OQOYCNh1W.;@lJ=kQLR"0^fg=hL9e"_H*])@-Z
-a2H[9ir@lhL=5Yig'>fPmcqOUfg1,~>
-#$LBV\^d1YJ`_OGRcXXN:\j,udYFIWN/-NTLPN+r\VI]WZ%p0;LT'@tTSJ<1k2qk_hQ2LP`VkPl
-d_t8Pli5YgLXYejeHa-In)qLUg-U;~>
-#$LBV\^c7gJZOF(XK3)6R@0nQXJM>QS#i0US=-CYN+kBLX=9o*1SnDWV-JY*A;?O)R&lQ*S=k'l
-VQ>eMAs]U#CJ(Ri/tSUdK7caO`2j0Smap!Ee+*=c#KMJckJ6T@6@]~>
-#$LBV\D!1KJ_G\/XP+?;_SX^Sg<mdS`S/AX`kpB^Z%YjHg*t??5gadkdWD@`J#gCH_:lR``QFKF
-e(V-7K"p$nLgJZD3loB'VP[V"`7bFTs5)Iaddm:h#Kq\dlFuc@6%A~>
-#$LBV\^d1YJ`_OGXQC2Sc->),k2";,d,rd1dEU_6]8TP]jsf%[7,362h0Q9.L:#/fbN?i.d++aj
-hWDL]M94oBO(7.e4k%kCYHMED`9%9is4PqXe+*=c#KMJckJ6T@6@]~>
-#$LBV\^c7gJZOF(XK2qB:/4okW`W"k-EL0";,2'/X8kBXX9M@;B6eE8G5eQR4KN"HXFOucX?:HH
-XK5icri?K^@]ZXnXK4OcH%VL&X9Q9(f@>Z*nb^iAa+NjD_!p&EJ,~>
-#$LBV\D!1KJ_G\/XP+25@q0H0fPb800\U;)An-i"g&OhAg'1uGK:.[[QN#SK9\Olog7j8Sg.[Nn
-g=gnSrn7a[I+m:Jg=f6SRARg=g'6R:hV*_4o)%,GbCT*H^@9fAJ,~>
-#$LBV\^d1YJ`_OGXQC%HBk_bOjE>6O1Zi[ACh]16joA6Qjp#F`MP??&T)Rj_;!*D:k,XF&k"qA:
-k2q9&roOTpKBD;mk2oM&U9DeZjp(/Og!tl,nb^iAa+NjD_!p&EJ,~>
-#$LBV\^c7gJZOF(XK2qoP*.`%WCN,7OK=R6VlW#[X8kBXX9M@^9QG&kG5eQ_4KO`KUJIM`JlROj
-XK5icXJ__G@]ZXnXK4<B+2Y)`]'e2#LXYejeHa-In)qLUg-U;~>
-#$LBV\D!1KJ_G\/XP+2n\[b,YeloVp[bA5neCmUqg&OhAg'1us@$$>/QN#SX9\R*tc=G&NV/*).
-g=gnSg=49FI+m:Jg=eth.)O[Bir@lhL=5Yig'>fPmcqOUfg1,~>
-#$LBV\^d1YJ`_OGXQC&/_o#%(iEjF>^uiL>hr[c7joA6Qjp#G9AXJ^LT)Rjl;!,`?g1f(!Y&UdJ
-k2q9&k2=drKBD;mk2o63.`1<Pli5YgLXYejeHa-In)qLUg-U;~>
-#$LBV\^c7gJZOF(XK2q><`U?AXGg1\@'#JlXK4P`X8kBXX9M@fGW]naG5eQK4KPV_E+,iL>5hP8
-GcY>/XH$J=@]ZXnXK4OcFG?7&X9Q9(f@>Z*nb^iAa+NjD_!p&EJ,~>
-#$LBV\D!1KJ_G\/XP+21D/C]Og9PR4H.ocGg=f7"g&OhAg'2!)R8&X%QN#SD9\S37NdKL6ErKng
-R+cnfg9bn#I+m:Jg=f6SPH)O=g'6R:hV*_4o)%,GbCT*H^@9fAJ,~>
-#$LBV\^d1YJ`_OGXQC%DF)rhik.>\UJEF^jk2oM>joA6Qjp#GETi%&AT)RjX;!-nYQ@\2\GlDas
-T]Uj5k.Z,IKBD;mk2oM&S$UDYjp(/Og!tl,nb^iAa+NjD_!p&EJ,~>
-#$LBV\^c7gJZOF(XK3+.MKBVsWC2W$9!!A/VjT61U5CX_qQ)9F4b]sZDkgKnMJ7[DXIhnSXHtVu
-TS,4\:2Gf.>)lmGMG^IJ0T(`^Loc^WR`MQ7]'e2#LXYejeHa-In)qLUg-U;~>
-#$LBV\D!1KJ_G\/XP+@pYEKs:elJuX?J:oOeA=AjcEBC8qV!OK:8uqpN6cOJYD&h,g<!C>g;#kT
-bG[h4@u7CNEjKqmY@cM34g2%uXP10-`5pX:ir@lhL=5Yig'>fPmcqOUfg1,~>
-#$LBV\^d1YJ`_OGXQC4,\XOYYiENk'A*0Unhp"F9fssAZqW9Bc;R5F7PhLAm\W!]Rk1!Vek0$$#
-f!.cVBT]imH+eX:\SUEZ5e4F<[cYFOcH,,Pli5YgLXYejeHa-In)qLUg-U;~>
-#$LBV\^c7gJZOF(XK2Sn??CO<Wr?<4R][email protected]!Rd)qQ($o??*'3OK>Ef?@VpT#'m;OI9p6B
-qHaD^XFOV`WN;3[?3He":bnfeX9Q9(f@>Z*nb^iAa+NjD_!p&EJ,~>
-#$LBV\D!1KJ_G\/XP*ipGE\M_f`$(&_qKulbG9?f]m"[HqUu:qGECOl\(]DWGG4uh#+=3!Sp,Cf
-qKE1Fg7ie8f%RV3G6Gn=AO"J]g'6R:hV*_4o)%,GbCT*H^@9fAJ,~>
-#$LBV\^d1YJ`_OGXQB]2I@I%*jSjQ8c/t.:f<'J5aF/JeqW8.3I@00;_<0a*IB*8.#,:8BVgX!1
-qL&UUk,NiXio\)UI0@pZC.$[qjp(/Og!tl,nb^iAa+NjD_!p&EJ,~>
-#$LBV\^c7gJZOF(QE1(cr.>!-f;o!PUW9G?]'e2#LXYejeHa-In)qLUg-U;~>
-#$LBV\D!1KJ_G\/QJ)>ir1sCtf@g7?cc=`Dir@lhL=5Yig'>fPmcqOUfg1,~>
-#$LBV\^d1YJ`_OGQKA2,r3$+3fB**Qg;i=[li5YgLXYejeHa-In)qLUg-U;~>
-#$LBV\^c7gJZOF(QE1(ar+,kMS#ch*map!Ee+*=c#KMJckJ6T@6@]~>
-#$LBV\D!1KJ_G\/QJ)>fr."d2S(\)+s5)Iaddm:h#Kq\dlFuc@6%A~>
-#$LBV\^d1YJ`_OGQKA2)r.k?BS)sq@s4PqXe+*=c#KMJckJ6T@6@]~>
-#$LBV\^c7gJZOF(RB-CIP,nl!map!Ee+*=c#KMJckJ6T@6@]~>
-#$LBV\D!1KJ_G\/RG%YGP1g-"s5)Iaddm:h#Kq\dlFuc@6%A~>
-#$LBV\^d1YJ`_OGRH=L]P3)u7s4PqXe+*=c#KMJckJ6T@6@]~>
-#$LBV\^c7gJZOF(R]HO&3r,j&Ps8HR76diO5<j%eGX$DRDa/f25@ppt><b>nXK5,\UM2rJLAa=:
-Q,Ka.]'e2#LXYejeHa-In)qLUg-U;~>
-#$LBV\D!1KJ_G\/Rb@do9)70d]hie(=&@T#:f*)(R8B7(N)6=S:k79RFAPesg=g"4c@o)qWVoWn
-]u8V/ir@lhL=5Yig'>fPmcqOUfg1,~>
-#$LBV\^d1YJ`_OGRcXX-:AO#taAdHI>ZBhD<)f(DTi@]IPZ4cr</9VuH;mk4k2p;Ug5T(=Zi*i'
-a2I*Eli5YgLXYejeHa-In)qLUg-U;~>
-#$LBV\^c7gJZOF(XK3),F*!\LXI"!LHE;RWHul0dN.F+eX=:2C6Bub3R8Kr_H>]`EWiW3^X/gnJ
-S#iVsKW;,TKOCm]40,DDWMs3[`2j0Smap!Ee+*=c#KMJckJ6T@6@]~>
-#$LBV\D!1KJ_G\/XP+?0P*3T6g:rf6RbFFCSW_IUZ(t(hg*t]^<5"WU_IqHNRu>okf\4tMf\*03
-`7iggW7]hXVg@(L9%hlif%,&H`7bFTs5)Iaddm:h#Kq\dlFuc@6%A~>
-#$LBV\^d1YJ`_OGXQC2GR[VC]k/s-]UZSPkV4-9']<+p*jsfD&=NI+sb\Z:uUQab7jQ>N!jQ3UY
-cfX8;Z/k'0Z%1us:Z^\6io5Eq`9%9is4PqXe+*=c#KMJckJ6T@6@]~>
-#$LBV\^c7gJZOF(XK2q5F`gHZWD7SY19>=6Cirq\X8kBXX9M@<ApJ<7G5eQR4KNXHXD30bX$(KH
-XK5icri?K^@]ZXnXK4O_?^.5%X9Q9(f@>Z*nb^iAa+NjD_!p&EJ,~>
-#$LBV\D!1KJ_G\/XP+2%Pa#\0f41&05MCuAM3N&[g&OhAg'1uIJshRZQN#SK9\P\og4u<SfM7No
-g=gnSrn7a[I+m:Jg=f6MGe;/;g'6R:hV*_4o)%,GbCT*H^@9fAJ,~>
-#$LBV\^d1YJ`_OGXQC%7S=F9Qib=pQ6KXFZOdp^rjoA6Qjp#FaM5$6%T)Rj_;!+7:k)QD&jAMA:
-k2q9&roOTpKBD;mk2oLuJ&U!Wjp(/Og!tl,nb^iAa+NjD_!p&EJ,~>
-#$LBV\^c7gJZOF(XK2r'ChtMuWDIDISZIrTXK4P`X8kBXX9M@f7<!0bG5eQ_4KOuQQ;aNZGXcKt
-XK5icXJ(W.@]ZXnXK4?G+Mt2a]'e2#LXYejeHa-In)qLUg-U;~>
-#$LBV\D!1KJ_G\/XP+3*Lkmh:f4Khpa4e%@g=f7"g&OhAg'2!)=,r6$QN#SX9\RC%^1tsIQs#5$
-g=gnSg<?n'I+m:Jg=etn.DjdCir@lhL=5Yig'>fPmcqOUfg1,~>
-#$LBV\^d1YJ`_OGXQC&@OH;?Yj(sg=dcSDgk2oM>joA6Qjp#GE>aCVAT)Rjl;!-&FaD]boTO*^<
-k2q9&k1@;QKBD;mk2o69/&LEQli5YgLXYejeHa-In)qLUg-U;~>
-#$LBV\^c7gJZOF(XK2q/I!I0>XHS$Z:ood\XK4P`X8kBXX=R&7O!\dgEic@?6*..jChBcM9mh>6
-@'!dlXH$J=@]ZXnXK4OcNHLDcWh?E6X9Q9(f@>Z*nb^iAa+NjD_!p&EJ,~>
-#$LBV\D!1KJ_G\/XP+1rSXD=bg:EiGA_OY3g=f7"g&OhAg+6[O[P3Z*OkSO<;VKiEM1OC7@@`sW
-HJ3_Hg9bn#I+m:Jg=f6SZBVoRf?;gfg'6R:hV*_4o)%,GbCT*H^@9fAJ,~>
-#$LBV\^d1YJ`_OGXQC%.VP6$.k/=-oCZ`KUk2oM>joA6Qjt(,k^bV.FRHEYh=6AXhObi/^Au;H"
-J`_Qkk.Z,IKBD;mk2oM&]Uct&j4<;4jp(/Og!tl,nb^iAa+NjD_!p&EJ,~>
-#$LBV\^c7gJZOF(XK3+>A6^("W$Ptb>-)0gTnO_PQXh=QqQ('q/8_IJDldV_A6>/sX<'L*XFMO+
-P@,bK3)4!^>*`9$A8&'.,@k=ELocR9QcQ64]'e2#LXYejeHa-In)qLUg-U;~>
-#$LBV\D!1KJ_G\/XP+A/Irus(eLuE%EnYn+c)<2$^jdneqUu=t3/ZE[N7rr7IrN.$g)`rAg7p3K
-\p6&\87R-`EkZIAItZOe/:W.>XP0r[^rY46ir@lhL=5Yig'>fPmcqOUfg1,~>
-#$LBV\^d1YJ`_OGXQC4AL3k/>iA-.BGijWHfWd*Eb(_R+qW8164-AYuPidmYL3CZ;jrR@]k,^4j
-`IKe"9PK6!H-(5aL5Y3408>3S[cY4&b/i]Lli5YgLXYejeHa-In)qLUg-U;~>
-#$LBV\^c7gJZOF(XK2T"KTD=ZX8[b[UTBE-VNun*TS.uPqQ(%"KT<.,SueuGKU)M;#*Q'hP_=^]
-qLf*AXHeHlWiVfjKES*P3_uZpX9Q9(f@>Z*nb^iAa+NjD_!p&EJ,~>
-#$LBV\D!1KJ_G\/XP*j'VmX+Gg&@lWcJ#P$d_;WubGV8;qUu;&VmP1$aP,:EVnN&_#.`IA];MRJ
-qPOS8g:aD^f\4FFVZb?"8n?Gmg'6R:hV*_4o)%,GbCT*H^@9fAJ,~>
-#$LBV\^d1YJ`_OGXQB]>YeS,njo2Ilg#foNhT2qJf!)BaqW8.>YeK8Ne)o_qYfH_)#/fTc`NZSq
-qQL4Kk/X^1jQ=qiYQW_C:28\-jp(/Og!tl,nb^iAa+NjD_!p&EJ,~>
-#$LBV\^c7gJZOF(QE1(`r*05=f;nsk`iKBUmap!Ee+*=c#KMJckJ6T@6@]~>
-#$LBV\D!1KJ_G\/QJ)>fr,i!sf@g4b`nCXVs5)Iaddm:h#Kq\dlFuc@6%A~>
-#$LBV\^d1YJ`_OGQKA2(r-SL-fB*'u`o[Kks4PqXe+*=c#KMJckJ6T@6@]~>
-#$LBV\^c7gJZOF(QE1(dr/1Q<S#ch*map!Ee+*=c#KMJckJ6T@6@]~>
-#$LBV\D!1KJ_G\/QJ)>jr3674S(\)+s5)Iaddm:h#Kq\dlFuc@6%A~>
-#$LBV\^d1YJ`_OGQKA2-r42mGS)sq@s4PqXe+*=c#KMJckJ6T@6@]~>
-#$LBV\^c7gJZOF(RB-C0cE%"er2]m>rN$$pI/U,IR#(^B!fU-)ri?-NTDbhmF]FP&X8m>>X8m>?
-X9,A$>PtQ,]'e2#LXYejeHa-In)qLUg-U;~>
-#$LBV\D!1KJ_G\/RG%Y(cIr8]r7V.6rRq:uSc.7C^o[Lg!jZX1rn7CJao0opP\df-g&R<6g&R<7
-g&flBFSshsir@lhL=5Yig'>fPmcqOUfg1,~>
-#$LBV\^d1YJ`_OGRH=L<cK5+qr8n!JrT4.7VZ#WXbI.<2!kWHGroO6_eG\M2S8l@DjoCkJjoCkK
-joXO^HMln0li5YgLXYejeHa-In)qLUg-U;~>
-#$LBV\^c7gJZOF(S#c[c=??8Z/<qVIX>_f5OZYa3Uj",.XDK86MEFS6XB@,3Eic?0/Ycr)L4gj8
-4=lJnJS4q_!H!2_X9,A+NrH*]VG*``X9,/S8,fRjTLf$_!h<bBri?-Y?2^i*GB!P_!iqMBr2^+6
-map!Ee+*=c#KMJckJ6T@6@]~>
-#$LBV\D!1KJ_G\/S([qgDbBiZ/A3i8g."3X\4fS>d$HDNg57PXY=r?Xg2T,>OP8Df3R371WMhID
-9K9B4UP&O!!K3HHg&flK[/Sb\dpUH"g&fR'>5m4Vb$=o!!lfYQrn7CWG5^+qQ]D(!!nk.Pr7VA7
-s5)Iaddm:h#Kq\dlFuc@6%A~>
-#$LBV\^d1YJ`_OGS)se)F\_bp/B9YIk"7l"_GF'Vgn-?nk)qL#\PQo#k'&pWR-*O64P>TIZ`u8^
-:clAQXGZu=!Ks8XjoXRi^Ad6rhIbF>joX8H?N0'feRAF=!mu[kroO6mI/W1.TU,T>!p.Bkr8n4L
-s4PqXe+*=c#KMJckJ6T@6@]~>
-#$LBV\^c7gJZOF(XK3)#9hgJGXGKYG=KGkX>>:inQB46(X:.d"L3[]r>cb#b?*$0fX9h"jXDV1%
-XK5icri?Ta@]ZXnXK4OcXC-jcNEc@_!HrM^X8u[brN$#jT`(qmTh#'_!'L1\!HWA^X9"\arN$$O
-B)J_14T)8b]'e2#LXYejeHa-In)qLUg-U;~>
-#$LBV\D!1KJ_G\/XP+?$@UcLog9"gnDq]K.FCNPL^:-f2g'hD&WgSgNFkYQRG1oXhg'LI,g5L!Y
-g=gnSrn7j^I+m:Jg=f6Sg3TjSZ?6'!!L8fGg&ZH$rRq9VbPg,qbZau!!)3=E!Kr]Hg&]$$rRq:J
-K)F=&9`3TKir@lhL=5Yig'>fPmcqOUfg1,~>
-#$LBV\^d1YJ`_OGXQC2;B4n^9k-nu9Fln4PH=tpnaMC^JjpYj=Z_E\rHfjJ%I-+9)jp=lHk*1))
-k2q9&roO]sKBD;mk2oM&k('o&]R'P=!M,YWjoKt@rT4,gf)=_3fO"O=!)WUU!LfPXjoN\@rT4-_
-M>ZK9;#KG[li5YgLXYejeHa-In)qLUg-U;~>
-#$LBV\^c7gJZOF(XK2q>S!ugFW'm,E<31fqNLNB9X8kBXX9M@F?[$F.G5eQR4KO9GXAtIcT1ONH
-XK5icri?Wb@]ZXnXK4I64J\pWPZap`X9!rbrN$$?G5\KC@>Ff_!MN$^X8u+brN$$@FT/?CSPu?`
-X9+>eWr9"!4T)8b]'e2#LXYejeHa-In)qLUg-U;~>
-#$LBV\D!1KJ_G\/XP+20`5G^-eQ9]-C>,[7ZG]lEg&OhAg'1uUGaFANQN#SK9\QLng2+@Sb$:Wo
-g=gnSrn7m_I+m:Jg=f,o:!hGE]Pu@!g&\($rRq:6Q2TD;H`R,!!R+aGg&Ya#rRq:8PlBA<a(`p"
-g&eR(fDXD'9`3TKir@lhL=5Yig'>fPmcqOUfg1,~>
-#$LBV\^d1YJ`_OGXQC%Ccd,hTiEOXSE9=JT]['m_joA6Qjp#FnJ"MsmT)Rj_;!,-:k&SE&eR>J:
-k2q9&roO`tKBD;mk2oC?;;C-m`cp>>joMZ@rT4-JT)IdPJ[PI=!SC`WjoK5@rT4-LSGqXPdVmn>
-joW/Dj8J*?;#KG[li5YgLXYejeHa-In)qLUg-U;~>
-#$LBV\^c7gJZOF(XK2qs7Re;pW`hk]PcU!KXK4P`X8kBXX9M@f7<!0bG5eQ_4KP2ULfgOUGV)B*
-XK5icXI=Kj@]ZXnXK4Bn.fQLNR9-3`X9"8brN$$KCAk47E-M8^!MN$^X8uRbrN$$@FT/?CTN.W`
-X9+SgW;Wdt4T)8b]'e2#LXYejeHa-In)qLUg-U;~>
-#$LBV\D!1KJ_G\/XP+2s=BH`sfQ((r]@sc4g=f7"g&OhAg'2!)=,r6$QN#SX9\R[+X`2_BQoS7o
-g=gnSg;BG\I+m:Jg=f)L2?);2_J[^!g&\I$rRq:FLAfg,O-fh!!R+aGg&Z<$rRq:8PlBA<bA56!
-g&ej*ec"2%9`3TKir@lhL=5Yig'>fPmcqOUfg1,~>
-#$LBV\^d1YJ`_OGXQC&4?!SZ5jEY$:`ob-[k2oM>joA6Qjp#GE>aCVAT)Rjl;!->L[W^NiTKQR-
-k2q9&k0Bg0KBD;mk2o<n3<&%Ac#h_>joN)@rT4-[NW%u?QD"3=!SC`WjoKhArT4-LSGqXPeoB4=
-joWJFiVhm=;#KG[li5YgLXYejeHa-In)qLUg-U;~>
-#$LBV\^c7gJZOF(XK2ptU6I+*X,3RF5cg)LXK4P`X8kBXX=Hu6V@RTtAZVu!;66j9@<\fS5GFmB
-8ZZ?UXH$J=@]ZXnXK4OcVIYRcNEc@_!HrM^X8u[brN$#jT`(qmTh#'_!'L1\!HWA^X9"\arN$$O
-B)J_14T)8b]'e2#LXYJa]a(lrn)qLUg-U;~>
-#$LBV\D!1KJ_G\/XP+1^cFc!afr`QF;;/Ntg=f7"g&OhAg+-UNdh@\:JD/_lBA2'sH^<C>:sRA*
-?.sY+g9bn#I+m:Jg=f6SdXSISZ?6'!!L8fGg&ZH$rRq9VbPg,qbZau!!)3=E!Kr]Hg&]$$rRq:J
-K)F=&9`3TKir@lhL=5>`^^%8umcqOUfg1,~>
-#$LBV\^d1YJ`_OGXQC$nfu>u0jL<gq<T_/?k2oM>joA6Qjst&jh@u3XM!!jAD<BuDJtM2f<S?'P
[email protected],IKBD;mk2oM&hM/Q&]R'P=!M,YWjoKt@rT4,gf)=_3fO"O=!)WUU!LfPXjoN\@rT4-_
-M>ZK9;#KG[li5YgLXYJa]a(lrn)qLUg-U;~>
-#$LBV\^c7gJZOF(XK3+M5"mD6W#%W]C90uKS8]6nN'8"CqQ('i*)s":DleIQ5#\'PX;sF)XD&G6
-L-$59,;DA<>+SYV5(BYf(-Xo,LocS?rN$$CErE'??]"`_!D&m^X9#"brN#u]r2]p?FT/?BQr![^
-!J4q]X8kB\X9Q9(f@>Z*U%s<En)qLUg-U;~>
-#$LBV\D!1KJ_G\/XP+AC:LGu*eK%F]L>#o]`Jkh1Z;2E<qUu=j,APqEN7t"%:MIoLg)Wl@g4^JA
-WCn=//3ZiqEli#k:SHLA)c'6\XP0t%rRq:;Oo<u7Gcq#!!F*bGg&]E$rRq6Fr7V17PlBA;_.ET!
-!Mk>Fg&OhEg'6R:hV*_4TD=$AmcqOUfg1,~>
-#$LBV\^d1YJ`_OGXQC4V;e7k<i?(usNTO\"d$5WO]2K_OqW81,-#i!_Pif#F;f:+ajrI:\k)CB[
-ZVM]B00rN)H.6b2;l\uc*E,lh[cY5KrT4-ORJl7KJ%,C=!FXLWjoO+@rT4)Vr8n$KSGqXOb\I+=
-!Nh4VjoA6Ujp(/Og!tl,U%s<En)qLUg-U;~>
-#$LBV\^c7gJZOF(XK2T+WiE,#XT#7"XT,:'XK/A%X8]-pXT,:*XK/D'XK&;$rN$4(XK8J&WiPur
-#HOr,WiE/%X8T'uX9!<arN$$/LAn7UVHK2`X9,"kV#IFsQYT+jX9"AbrN$'U9m$B9!I8S]X9!'b
-ri?1$E\.-i"hO-ReVCX/dKTI0_!p&EJ,~>
-#$LBV\D!1KJ_G\/XP*^.fDaD&gA]\0g"P*1g=b*2g&BV"g'ZNbf\5$3g=k01f_sM.f\5'3f@S^P
-f*C!_f[na/g=cGV"52CiQMoM<IB!5"!n2/&rn7FqB@-Y3!l'Oprn7C\E;eJlXC7@mg&[Y$rRq:-
-TDmOGfTA/kg'-L9hV*^ppsoWFlFuc@6%A~>
-#$LBV\^d1YJ`_OGXQBQFj8S*>k5OBHjlYXak2bRajo4<:jpL51jQ>Rck2t^ajSe3FjQ>Ucj5]7t
-is4].jQ#:_k2lR%"6J[4T)IdPK<tR>!oA.AroO:3D;5'P!m6R1roO6rGQ$Y*[:c$/joM3@rT4-@
-W;bo\jI&+-jot)Ng!tkepsK?AkJ6T@6@]~>
-#$LBV\^c7gJZOF(QE1(^r&asXf;nt/r2]mTrN$$tNr?$[T9]AV!gn.iri?-_V#@@rMKYHfX8n+T
-X8n+UX9,DFHMjiK]'e2#LUR6[rWi>Ko]O$Zg-U;~>
-#$LBV\D!1KJ_G\/QJ)>br(I*)f@g5,r7V.QrRq;$[/J\Zb.[c-!l:/,rn7C_ci)Q!Y*Hs)g&S8Q
-g&S8Rg&folRf(kDir@lhL:@3[rWi>Jo]j0[fg1,~>
-#$LBV\^d1YJ`_OGQKA2%r(mB3fB*(Br8n!grT4.<^A[0pe]@^[email protected]\p79\=LqEjoDmg
-joDmhjoXV7U\s6Yli5YgLUR6[rWi>Ko]O$Zg-U;~>
-#$LBV\^c7gJZOF(JZPiP#J0?TeVC*km/5B=P+hU4_!p&EJ,~>
-#$LBV\D!1KJ_G\/J_I*W#NGd?g4lZsn,1lEOe_[9^@9fAJ,~>
-#$LBV\^d1YJ`_OGJ``ro#ODECeVC*km/5B=P+hU4_!p&EJ,~>
-#$LBV\^c7gJZOF(JZPiP#eKHUeVC*Or7Cqu#e>u'p?06\g-U;~>
-#$LBV\D!1KJ_G\/J_I*W#ibm@g4lZYr7q;*#eQ),pZfK^fg1,~>
-#$LBV\^d1YJ`_OGJ``ro#j_NDeVC*Or7Cqu#e>u'p?06\g-U;~>
-#$LBV\^c7gJZOF(JZPiP'Y<_aeVC*:lgNBSd@?c@p?06\g-U;~>
-#$LBV\D!1KJ_G\/J_I*W']T/Lg4lZFm.&f`eXW5JpZfK^fg1,~>
-#$LBV\^d1YJ`_OGJ``ro'^PePeVC*:lgNBSd@?c@p?06\g-U;~>
-#$LBV\^c7gJZOF(JZPiP'Y<_aeVC*:ansrF`.kY4p?06\g-U;~>
-#$LBV\D!1KJ_G\/J_I*W']T/Lg4lZFc2?STaG%.@pZfK^fg1,~>
-#$LBV\^d1YJ`_OGJ``ro'^PePeVC*:ansrF`.kY4p?06\g-U;~>
-#$LBV\^c7gJZOF(JZPiP'Y<_aeVC*:^?k7;Q(Pb'p?06\g-U;~>
-#$LBV\D!1KJ_G\/J_I*W']T/Lg4lZF_sQpHQ(Z"2pZfK^fg1,~>
-#$LBV\^d1YJ`_OGJ``ro'^PePeVC*:^?k7;Q(Pb'p?06\g-U;~>
-#$LBV\^c7gJZOF(JZPiP'Y<_aeVC*:^!c\[N46L6p?06\g-U;~>
-#$LBV\D!1KJ_G\/J_I*W']T/Lg4lZF_UeLfMnHpDpZfK^fg1,~>
-#$LBV\^d1YJ`_OGJ``ro'^PePeVC*:^!c\[N46L6p?06\g-U;~>
-#$LBV\^c7gJZOF(JZPiP"hO-ReVC+&]`R5HT)QD,p?06\g-U;~>
-#$LBV\D!1KJ_G\/J_I*W"lfR=g4l[-_?/eLTDl\2pZfK^fg1,~>
-#$LBV\^d1YJ`_OGJ``ro"mc3AeVC+&]`R5HT)QD,p?06\g-U;~>
-#$LBV\^c7mJ\$EDJ\%hl"i]o]eVC+&]`Pp(Zi7WAp?06\g-U;~>
-#$LBV\D!1OJ`;7?J`<Zg"mH!Cg4l[,_?#G$rk\j5lFuc@6%A~>
-#$LBV\^d1[Ja7mQJa9<$"n2KEeVC+&]`Pp(Zi7WAp?06\g-U;~>
-#$LBV\^cVbJaS*WJaTH("4u(Y_#E<oi7%Ya"oIJunCg3Z~>
-#$LBV\D!M5JcC<$JcDYJ"5_ad_>`Krimdqf"oIT!nC^*X~>
-#$LBV\^dM:JcC<$JcDYJ"524[_#E<oi7%Ya"oIJunCg3Z~>
-"^19U\^f#Wf7DP)f;@1"eH*#Gp[eUK_!p&EJ,~>
-"^19U\D#JahLXO7hPT00g&\PMp\"aP^@9fAJ,~>
-"^19U\^f)Yfn%h-fr!I&eH*#Gp[eUK_!p&EJ,~>
-"'P'S\Ui:^eUc89eH<VVg-U;~>
-"'P'S\:N@bg4@tCg&o(Yfg1,~>
-"'P'S\Ui:^eUc89eH<VVg-U;~>
-"Bk0T\[-jBJVSf3V2#&Wo@3rYnCg3Z~>
-"Bk0T\@$mAJVAZ/V1eoUo@a;\nC^*X~>
-"Bk0T\[-jBJVSf3V2#&Wo@3rYnCg3Z~>
-"^19U\ZptdVuis:`duTidt,u\dfHr+q5=>0nFP04_!p&EJ,~>
-"^19U\?gtcWr^/ZJ^T+tJ^V3Z!P-VRWr^',o@a;\nC^*X~>
-"^19U\ZptdVuis:`duTidt,u\dfHr+q5=>0nFP04_!p&EJ,~>
-"\,r'Q*H8E]`lU<igB'-Jan<]JapMF#3_c/s8V!!r4N-jo^gT8S@G1AJ,~>
-"\?50Qa;SH_?J9GigK31Jb"B_Jb$SH#3hc2s8V*(r5&Kqp@Hu?T=ppKJ,~>
-"]3XiYHa#_]`lU<igB'-Jan<]JapMF#3_c/s8V!!r4N-jo^gT8[ahZ6J,~>
-"Y=h;>Hs+c]a2?fkP"SDR-X0keUc8%e\BW?]n=c4iqE',_#D"Jiq2im"(#V5&:a~>
-"YbLUA[@9n_?e&tl1anHR-jBog4@t/g:u>I^k()9jnJK3`;[USjS&3!")2jY&qB~>
-"[ff-U9TXU]a2?fkP"SDR-X0keUc8%e\BW?]n=c4iqE',_#D"Jiq2im"/W>h,_,~>
-&MS*3=0[[s]uo74nDDcgR-X0keUc8%e\BWD]n=c4e^`UJs5(l2iq2im"(?4P(Ou~>
-&N"lT@^Cs/_Tq0@o&JGrR-jBog4@t/g:u>N^k()9g=kWYs5;/=jS&3!")NI!)Lq~>
-&Oj7;U9TWi]uo74nDDcgR-X0keUc8%e\BWD]n=c4e^`UJs5(l2iq2im"/`]11k5~>
-&MS*3=0[Xmh!k!pf%&<CR-X0keUc8%e\BW:]n=c4rm_5(i:ZHji:QWk"(?4P(Ou~>
-&N"lT@^Cp)hXU@$gY1ARR-jBog4@t/g:u>D^k()9rn7S2jS%rqiqDut")NI!)Lq~>
-&Oj7;U9TTch!k!pf%&<CR-X0keUc8%e\BW:]n=c4rm_5(i:ZHji:QWk"/`]11k5~>
-#r$7+=0[LMLRbsSeH;G2lgB>SJ^o>%^XWG"[email protected]"feH96#=;QJ~>
-#rI$L@^CcZL7GpTg&mt7mI5\\J_G\/^Y/e*J_'hug'"^4LXc%hg&l/@Af?1~>
-#t;D3U9THCLRbsSeH;G2lgB>SJ^o>%^XWG"[email protected]"feH;\\W\f5~>
-&MS*3=0[[sZCHo>`mN>/R-X0keUc8%e\BWD]n=c4e^`'cQ&M<@iq2im"(?4P(Ou~>
-&N"lT@^Cs/[[iABb1>:=R-jBog4@t/g:u>N^k()9g=k)uQ&D9DjS&3!")NI!)Lq~>
-&Oj7;U9TWiZCHo>`mN>/R-X0keUc8%e\BWD]n=c4e^`'cQ&M<@iq2im"/`]11k5~>
-"Yah'=0[\_]a2'=Kq5fIR-X0keUc8%e\BWD]n=c4e[_3)T=;MIiq2im"(?4P(Ou~>
-"Z1UH@^Csk_?d`GKV#lLR-jBog4@t/g:u>N^k()9g:Nl/TY/.YjS&3!")NI!)Lq~>
-"\#u/U9TXU]a2'=Kq5fIR-X0keUc8%e\BWD]n=c4e[_3)T=;MIiq2im"/`]11k5~>
-"Yah'=0[\]]`tj6Nej(gl%-m+a+;:G`s8r'deo8gS[A@/!TNbCeH96#=;QJ~>
-"Z1UH@^Csi_?RK>NeWqgl@I-0bCRjOb6PG+f)1YiT"+a9!T`tGg&l/@Af?1~>
-"\#u/U9TXS]`tj6Nej(gl%-m+a+;:G`s8r'deo8gS[A@/!TNbCeH;\\W\f5~>
-"Yah'=0[\[]`b^9R-:H!K7SZ+K=up;dK-&Lqn3$io^gT8@<,HdJ,~>
-"Z1UH@^Csg_?@BDR-LN!JUrB'J\?U:f$U8'qn`Bpp@Hu?Ck$%8J,~>
-"\#u/U9TXQ]`b^9R-:H!K7SZ+K=up;dK-&Lqn3$io^gT8VRribJ,~>
-"Yah'=0\Rrp&X^]Ja\0YJa^8?!VuB`p&Y'_o@3qOE`a-.~>
-"Z1UH@^Dg(pAsg^JaS*WJaU2=!VuB`pAt0bo@a:_IqBUL~>
-"\#u/U9UNhp&X^]Ja\0YJa^8?!VuB`p&Y'_o@3r?];d]<~>
-"Yah'=2isGkCMfIkGIDBj7Ce'@<,HdJ,~>
-"Z1UH@`dJXl@J5OlDEhHk4@:/Ck$%8J,~>
-"\#u/U;bo=kCMfIkGIDBj7Ce'VRribJ,~>
-">+@t?X*>7!FD:I^k':P^oP6OVeGj6"*.mG4Fd~>
-">Y.?DJ&]\!GS0W^4F"L^8nsKWcRrO"+P>p5C`~>
-"@fN#Z)%2m!N!5U^k':P^oP6O^9.1-"1bh-;1J~>
-"<q2^@VPXY!GAron:C([n>l$Zc$K/*"(PdnVLS~>
-">"/)EHh5.!Hc#+n:C([n>l$Zd>%FG"*/B?VLS~>
-"@n9T[(#kC!OL=-n:C([n>l$ZiP,*!"1>LLVLS~>
-"#h>U:&%fk;5JitJ_G\/X4dTcAGB7/9eV%oJ,~>
-"%+Iq>52\1?E&M/J_>V-X4[NfEVO,J=uV$0J,~>
-"*$Y@RJ<c_UV_T9J_G\/X4dU%Z1t=$R:q<OJ,~>
-s"sg$)YY$J1P%lD6@hJ(630"`p_O#pVYgCD~>
-"%5L-+86ZR1k@rD6%M>&5liqdp_j6!VYgCD~>
-")i0L3qkH24b5qN6@hJ(630A2pbW(MVYgCD~>
-%%EndData
-showpage
-%%Trailer
-end
-%%EOF
diff --git a/lib/et/doc/src/megaco_filter.gif b/lib/et/doc/src/megaco_filter.gif
deleted file mode 100644
index bd03929b4c..0000000000
--- a/lib/et/doc/src/megaco_filter.gif
+++ /dev/null
Binary files differ
diff --git a/lib/et/doc/src/megaco_filter.png b/lib/et/doc/src/megaco_filter.png
new file mode 100644
index 0000000000..cdea3a147e
--- /dev/null
+++ b/lib/et/doc/src/megaco_filter.png
Binary files differ
diff --git a/lib/et/doc/src/megaco_filter.ps b/lib/et/doc/src/megaco_filter.ps
deleted file mode 100644
index 19a1fc6bd1..0000000000
--- a/lib/et/doc/src/megaco_filter.ps
+++ /dev/null
@@ -1,1733 +0,0 @@
-%!PS-Adobe-3.0 EPSF-3.0
-%%Creator: GIMP PostScript file plugin V 1.12 by Peter Kirchgessner
-%%Title: /home/hakan/picts/megaco_filter.ps
-%%CreationDate: Mon Oct 14 17:46:21 2002
-%%DocumentData: Clean7Bit
-%%LanguageLevel: 2
-%%Pages: 1
-%%BoundingBox: 14 14 469 306
-%%EndComments
-%%BeginProlog
-% Use own dictionary to avoid conflicts
-10 dict begin
-%%EndProlog
-%%Page: 1 1
-% Translate for offset
-14.173228 14.173228 translate
-% Translate to begin of first scanline
-0.000000 290.927657 translate
-453.947466 -290.927657 scale
-% Image geometry
-543 348 8
-% Transformation matrix
-[ 543 0 0 348 0 0 ]
-% Strings to hold RGB-samples per scanline
-/rstr 543 string def
-/gstr 543 string def
-/bstr 543 string def
-{currentfile /ASCII85Decode filter /RunLengthDecode filter rstr readstring pop}
-{currentfile /ASCII85Decode filter /RunLengthDecode filter gstr readstring pop}
-{currentfile /ASCII85Decode filter /RunLengthDecode filter bstr readstring pop}
-true 3
-%%BeginData: 99787 ASCII Bytes
-colorimage
-!AQV60nB=U!.b-$!:0^c3<Coq0n9~>
-r'Z)9JH16$JH5$:r'Z&~>
-"DW"!C3+q+JH16$JH5$:r,[A~>
-r]0uYnc&U&JcC<$JcE7[!56GQrr<*T3B;T~>
-r^?bdnc&U'JcC<$JcE7[!5?MRrrE$dJ,~>
-rcA)>nc&U&JcC<$JcE7[!56GQrr<+8F)uj~>
-s"OQTs8VWG!53s6J^o>%\CCSma56ja!WXr0J,~>
-s$Qngs8VWC!5=$8J_#D'\CLYoa4gR]!WYVVJ,~>
-s)S5As8VWG!53s6J^o>%\CCSma56ja!W[:VJ,~>
-!]^8\n(n&XJ^o>%J^q9\!56A.!lY."J,~>
-!^m%gn(IcUJ_#D'J_%?^!5?G+!l=q*J,~>
-!cnAAn(n&XJ^o>%J^q9\!56A.!lY.\J,~>
-!\j]Tn(n&XJ^sYJ!6(hc!6'N>S(.MP`SL[8!',Q~>
-!^m%gn(IcUJ_'_L!QrigecEqAJ_$@B!5?G+!l=q*J,~>
-!cnAAn(n&XJ^sYJ!6(hc!6'N>S(.MP`SL[8!-<Y~>
-!<E/fh>k6dec1lieHNpfe\-<VrfmH5!J>a&eH3F2HiB90eH(;LnC7Q8]n+_AeH!;GhY3Q5hZ',E
-hZ',Dh>s\XJ,~>
-!<E/fg&Sjaf)LlgedTEhf"Q]`R?<W_eq&CUed9'AI@64[f%,D'nC@W6^4FkCec<GIg@q$.gAdT>
-gAdT=g&\>VJ,~>
-!<E/fh>k6dec1lieHNpfe\-<VrfmH5!J>a&eH3F2HiB90eH(;LnC7Q8]n+_AeH!;GhY3Q5hZ',E
-hZ',Dh>s\XJ,~>
-!<E/thZ',ChZ',Eh>k7]eH*Y&iRItJ^$sPQ`P(Qes-2Bj&]K+(eVedneWc<KeUr5!e]#5.eI@F`
-`RU3;e^];!e^_XPo[O#MHc:Qd[abAkkMGs'p>5b<s5*^ErS@RV!.Y~>
-!<E/tf)M08f)M0:ec<GVdK.4niR.bD[d_]G_RAaXs,l0d&]0+-dZ&[pcB47;dXcttd_`H!dLD1a
-`m0^/daE\tdaH"@o[3fLID19\[aG/ikLTBqp=B21s47.:rRM"P!.Y~>
-!<E/thZ',ChZ',Eh>k7]eH*Y&iRItJ^$sPQ`P(Qes-2Bj&]K+(eVedneWc<KeUr5!e]#5.eI@F`
-`RU3;e^];!e^_XPo[O#MHc:Qd[abAkkMGs'p>5b<s5*^ErS@RV!.Y~>
-!<E/uhYiuChYiuDh>k7]eH(;LiRIs]HgoPdK6tSf"cJVqeUr5GeHLSPe^];!Zdf)/Hi)=sK6u/!
-K7!4?!L/Lne[F!.^$"8HSG(h6SGh:FX8mb~>
-!<E/uf);$8f);$9ec<GVdf4mWdf4mfdf4m;dKPJmdaE\tqpPLqs3gpuZdSl)qpPLqs3gpuo?mZ)
-M1O*`dK%#Ef(YU+f(YU2ecDoRJ,~>
-!<E/uhYiuChYiuDh>k7]eH(;LiRIs]HgoPdK6tSf"cJVqeUr5GeHLSPe^];!Zdf)/Hi)=sK6u/!
-K7!4?!L/Lne[F!.^$"8HSG(h6SGh:FX8mb~>
-!<E/uhY`oDhY`oCh>k7deHX!NH\8]UV#G]@`VS*mXG_FPMp9eRMgLA`rmh%,"hfP8[+1uOHiM%o
-MgL)`e^]S9]n:[=eYN1ks2>,!H[CCYqUHs`HbIt[XFo&UHe$ZcMgL)`eZ=,:eXV!*eXWGc`J](q
-[+3]bMl_j8eHER4^"&YPHO.lKHe$Z!He"qkHiM%nMgL)`e^]S9XGbV]Hi)@nM\<^UHaL/4HaM>R
-`J](q[+3^GPl5qCe]!c"H],kneZ=[UH]-/!XG_F`XSC<GSGmj@c%CAneUr5!V#G`@`=7`PK='1Z
-Mi4Zpe\-=CJ^q6[!57RPpRLp5q4.B>!NZ9O~>
-!<E/uf)1s9f)1s8ec<G]dK[RNI>+uTU&KH?_YV[gY).RTM9=8LM1(5`rmLh+"hKD=ZI5HGIK..n
-OaVqhdaF,7\qP^@d\6Ygs2"o$JUN6\qU-aZICdkTV1m?KJ^Vu`OaVqhd].`4d[>O#d[?fW_NB8#
-ZI70\NMVX5dKI.0]$d#GI0duHJ^VttJ^U7kIK..mOaVqhdaF,7V2`oSJc!mqN=r[RJZcG8J[3_P
-_NB8#ZI71<Oo9\Bd`.E#I>tthd]SFTI>Q+pY).R`Y5$EFRJqU?b(5,ldXcttU&KK?_@;WUKsK.T
-NK'cod^FS8J^V$U!5@XIpR1^*q3h03!NlEQ~>
-!<E/uhY`oDhY`oCh>k7deHX!NH\8]UV#G]@`VS*mXG_FPMp9eRMgLA`rmh%,"hfP8[+1uOHiM%o
-MgL)`e^]S9]n:[=eYN1ks2>,!H[CCYqUHs`HbIt[XFo&UHe$ZcMgL)`eZ=,:eXV!*eXWGc`J](q
-[+3]bMl_j8eHER4^"&YPHO.lKHe$Z!He"qkHiM%nMgL)`e^]S9XGbV]Hi)@nM\<^UHaL/4HaM>R
-`J](q[+3^GPl5qCe]!c"H],kneZ=[UH]-/!XG_F`XSC<GSGmj@c%CAneUr5!V#G`@`=7`PK='1Z
-Mi4Zpe\-=CJ^q6[!57RPpRLp5q4.B>!NZ9O~>
-!<E/teb>U4eH!;\bmMFBK>!Lr`Pm1N^&#u1UjJ$,[%t[BH^)4.H`YK:K6rNHH\9S^H[EHFK7gk%
-Hc=6^H]+D@K?_A^HbI[^HaLJn^&#u$[!S%^c%Dh:K6tk^K7gk%Hc<[FXNcBEXNcC)`IifVP^CBo
-K6rNPrQQOVHc=7KH[EHNK6tkfK6tk^H[EHFK7gk%Hc=6^H]+]EMhCoO/q\M/S9oU@S9on5`IifV
-P^CBoK7h.fK6tkVXM(ufMp8&EMmTje`N4EN]p*lFq9:##H[EHNK6tkfK6tk^H[EHFK7gk%Hc=6^
-H]+]E`I",+c*tpt^$!oGSGC\8SFkA/SGUh;X8mb~>
-!<E/tdeB1.dK%#Zc3h^FKt<Ot`l<RX_YVP7V1"3+[]7?II?hO3IB(T<JUNBKI>,tdJUPDTJVC\#
-IE'Q`I>OYGL!I\hIDX9dIC?ku^A?,&[XFRhcAACCJUu+hJVC\#IE&jHWm6<HWm61(b(58XQ$pZt
-JUNBOrQZU\IE'RPJUPD\JUu+lJUu+dJUPDTJVC\#IE'Q`I>OfGM2D,T/qJG1Tm_?KTm_X?b(58X
-Q$pZpJVCtdKmh7\Y.h>mM9_rGM6aRi`i=HP^6O,Hq9C)%JUPD\JUu+lJUu+dJUPDTJVC\#IE'Q`
-I>OfG`dOP3cF;(!^?<oERJG82RInr)RJYD5XoNt~>
-!<E/teb>U4eH!;\bmMFBK>!Lr`Pm1N^&#u1UjJ$,[%t[BH^)4.H`YK:K6rNHH\9S^H[EHFK7gk%
-Hc=6^H]+D@K?_A^HbI[^HaLJn^&#u$[!S%^c%Dh:K6tk^K7gk%Hc<[FXNcBEXNcC)`IifVP^CBo
-K6rNPrQQOVHc=7KH[EHNK6tkfK6tk^H[EHFK7gk%Hc=6^H]+]EMhCoO/q\M/S9oU@S9on5`IifV
-P^CBoK7h.fK6tkVXM(ufMp8&EMmTje`N4EN]p*lFq9:##H[EHNK6tkfK6tk^H[EHFK7gk%Hc=6^
-H]+]E`I",+c*tpt^$!oGSGC\8SFkA/SGUh;X8mb~>
-!<E/sebPa5eH!;\bmCIuSB\-^XNcBEq98tnHc>s..t`2fc,G$^c-:lf`Q`aVc-:lfc)c8^c)c8n
-c%CA^c$Of^c%CAfc&6q=^%]bsK6tkVHc=6^Hd/X=SB\-^XNc*V`I!6%]mJ#*H^r?^H`YJEHi)%g
-P^EDS(k[1[c%CAfc%CAfc%CAfXF$J^XF%%nK7!=:(k[1Sc$OfVc$Of^XF$J^XF%%MH^r@*K7!UB
-#K=B/K?]$q`Vn$cK6tS^`I!74bnu([c-:lfc-:lfc-:lfc)c8^c)c8nc%CBAblN0UJ^([K!57RG
-!1`l8!1`]3qjdQ6!NZ9O~>
-!<E/sdeT=/dK%#Zc3^Y%TusNdY0MTLq9B%qIDYs..uA\ocGk9hcH^uh`m0-dcH^ulcE;Shb-$/q
-c@LD`c@LPlc@LPlcA?t?_Y;@UJKr=OIDX9\J^1EHTusNdY0MH\`dNQ/_L9S0IA+fdIBLkHIEMK5
-!L8*4cMrIqcMrIqcMrIqcMrG'cE;Shb-$/qc@LDdpWaV,IEKidIEKidJ^1EHTusNdY-NJHcH_,l
-rltbc^4D!`Kmgi:c3B,R`m2SPM>5BrJcF$qJcF$qJcF$qJIBc+IA+fdIBLkHIEMQ7!I^5acF;(!
-^?<oERJG82RInr)RJYD5XoNt~>
-!<E/sebPa5eH!;\bmCIuSB\-^XNcBEq98tnHc>s..t`2fc,G$^c-:lf`Q`aVc-:lfc)c8^c)c8n
-c%CA^c$Of^c%CAfc&6q=^%]bsK6tkVHc=6^Hd/X=SB\-^XNc*V`I!6%]mJ#*H^r?^H`YJEHi)%g
-P^EDS(k[1[c%CAfc%CAfc%CAfXF$J^XF%%nK7!=:(k[1Sc$OfVc$Of^XF$J^XF%%MH^r@*K7!UB
-#K=B/K?]$q`Vn$cK6tS^`I!74bnu([c-:lfc-:lfc-:lfc)c8^c)c8nc%CBAblN0UJ^([K!57RG
-!1`l8!1`]3qjdQ6!NZ9O~>
-!<E/rebbm6eH!;\blFR;HNU(gK7!F=s*O[gs*Oais*Odj$\NfNc%CAfc%CAfV#5QQUs4O=c-:lf
-c-:lfc-=4lH[C[aq998:H`W`qc-:lfc(t8a$`)%*K<1<%K<1!UV#5QAUs4O=qoo/+HiD8#K6tkf
-K6tkfK6tkfK6tk=r-JOAc%CB:bmT/Nc-:lfc-:lfc(t8as.g0PUs7/:Hd06VK8Y)/c$Og8c2W.i
-c2W.cbn#GRc-:lfc-:lfc-:lfc(t8a"/O1oHi;1iH^'*+\'4odr7(e\q4%Gup=0/5q:,J8p!rl.
-r7(hL!.Y~>
-!<E/rdefI0dK%#Zc2a^=I06=kJV!XBs*agj!J,[ucMr=mcMrIqcMrIqcMrFrcDCGe';a!*J^2Pl
-J^2PlJ^2QXQ$n(?^A6%]SUIZ3NR#h#J^1+iI1)msOb'ZtR>%Z#cDCGe"/X:oJc!^nQ$rYWs+13q
-s+13qs+13qs+(3rV>P`DV9XXCp<N\hs3CXqs3CXq!R@P>IK-,SIA+s3Kmh7XKn553L!G*pr6>=o
-IK%OlIJD+fJcF$qJcF$qJcF$qJH=&mr-\[Dc@LQFc2i?YJ^1aM!5ABZ!4quo!4qmP!1EZ2!1EN.
-q3h0/!NlEQ~>
-!<E/rebbm6eH!;\blFR;HNU(gK7!F=s*O[gs*Oais*Odj$\NfNc%CAfc%CAfV#5QQUs4O=c-:lf
-c-:lfc-=4lH[C[aq998:H`W`qc-:lfc(t8a$`)%*K<1<%K<1!UV#5QAUs4O=qoo/+HiD8#K6tkf
-K6tkfK6tkfK6tk=r-JOAc%CB:bmT/Nc-:lfc-:lfc(t8as.g0PUs7/:Hd06VK8Y)/c$Og8c2W.i
-c2W.cbn#GRc-:lfc-:lfc-:lfc(t8a"/O1oHi;1iH^'*+\'4odr7(e\q4%Gup=0/5q:,J8p!rl.
-r7(hL!.Y~>
-!<E/qebu$7eH!;\blXtnSG^V4K7!F=!eYj5rQQ+1Hc=7KH\9SfK6tkfK6tkfK6tkEH^t#Y$%mTL
-c%CAfc%CBAblbq\H\;.=%)%"GK<3>BK6tkEH^t#Y$`&--Uo\p$Us5ufSG^V4K7!L?(8Q;rc-:lf
-c-:lfc-:lfc-:lfc)c8^r657pHhP\nK6tkfK6tkfK6tkEH^t&Z&Zg>Lc-:T^c&6qnc%CYnK6t<1
-bm&fI`QcAKKD<\'K6tkfK6tkfK6tkfK6tkEH^t#Y!J>aublYk2S:SqoblGHTeb>U-eGu-8eGu-5
-eb>U4eH)`OJ,~>
-!<E/qdf#U1dK%#Zc2t.sU&<49JbdRmKmg]6c5)7b`m2SPM9aCtJ^2PlJ^2PlJ^1EHU&<49JcF$q
-JcF$qJc3jr`h@g7q9BD[I>rfXcH^ulcE;Shr6>\DI>t)'I>srGY'm#AcMrImc5*+%`m2k\J^2Pl
-J^2PlJ^2PlJ^1EHU&<49JbIChJcF$qJcF$qJHO3#IA-Vb&[$PMcH:]dcAdCtc@pttKmg]6c3B,R
-`m2SPM>5BrJcF$qJcF$qJcF$qJHO3#IA-Sas+10p!lfY^J^1aM!5ABZpR1a'!1EZ2!1EQ/pR2!.
-!NlEQ~>
-!<E/qebu$7eH!;\blXtnSG^V4K7!F=!eYj5rQQ+1Hc=7KH\9SfK6tkfK6tkfK6tkEH^t#Y$%mTL
-c%CAfc%CBAblbq\H\;.=%)%"GK<3>BK6tkEH^t#Y$`&--Uo\p$Us5ufSG^V4K7!L?(8Q;rc-:lf
-c-:lfc-:lfc-:lfc)c8^r657pHhP\nK6tkfK6tkfK6tkEH^t&Z&Zg>Lc-:T^c&6qnc%CYnK6t<1
-bm&fI`QcAKKD<\'K6tkfK6tkfK6tkfK6tkEH^t#Y!J>aublYk2S:SqoblGHTeb>U-eGu-8eGu-5
-eb>U4eH)`OJ,~>
-!<E/pec208eH!;[bmB#LUpR51c%CAMqTUjuH\8E5XMq8fPeE<.XNf"BHd0ffHd0ffHaLbEH_e$M
-[*=5Mc-:lfc-:lf[*>DR]sN-Eprt%9H[E`Vc%CAfc%CA=[&gXZ[!R/5]mG+5c-:lfUpR51c%CB?
-boOKE[*?jJHd0ffHd0ffHd0ffHaLbEH_e$M[*=5MrlkJ%KDWnGK6tkfK6tkfK6tkfK6sE$XL,rn
-H_cRHHd.IqXK6bq]rZR5XM(^SXF$2FP^BM,bnu([c-:lfc-:lfc-:lf[)IZEUpR51c%CBBblY8!
-]n+G;blGHTeb>U-eGu-8eGu-5ebu$<ebu$:eH)`OJ,~>
-!<E/pcMs1*c2bTVapZ4CIAOBTZHA#P[`83e1obtXY-t@IWdU/DQ$oLOb(5,db(5,db)(PT_M*E7
-[]ZpYJUttdJUttdM1)hPTsDD<I>RaA,DCPo`lcGTJ]budIAOBTZHBV(IC?_8IC@;<Kmff+Y-Q3$
-Jc!S1\p^a(b(5,db(5,db(5,db)(PT_M*E7[]ZpYJV!gCs,$Wqs+13ms+13ms+)H<`eAi;[]ZpQ
-I=7fGI=97pIB';qID2_0Ks%ka_Q&$L\s7]?pr`Vfs2t@ms2t@ms2kb,IC@"HIAOBTZH@`LrlP;F
-IC=^L\&n]br6G&%p<EZ'q9Au*p<NW%s3CS.rQYGH!.Y~>
-!<E/pec208eH!;[bmB#LUpR51c%CAMqTUjuH\8E5XMq8fPeE<.XNf"BHd0ffHd0ffHaLbEH_e$M
-[*=5Mc-:lfc-:lf[*>DR]sN-Eprt%9H[E`Vc%CAfc%CA=[&gXZ[!R/5]mG+5c-:lfUpR51c%CB?
-boOKE[*?jJHd0ffHd0ffHd0ffHaLbEH_e$M[*=5MrlkJ%KDWnGK6tkfK6tkfK6tkfK6sE$XL,rn
-H_cRHHd.IqXK6bq]rZR5XM(^SXF$2FP^BM,bnu([c-:lfc-:lfc-:lf[)IZEUpR51c%CBBblY8!
-]n+G;blGHTeb>U-eGu-8eGu-5ebu$<ebu$:eH)`OJ,~>
-!<E/feH!;[bmMFSH[CCHc*W+M^&#t]XG_FPMoErBK6r6Prll^@Hd0ffHd0gBK6t;NP^@b0XNcBE
-c-:lfc-<VJHbGYrH[D!rprrl9H^+NS&VGGTc,GooH\8EEc$Of^c$Og:bm;:QH[CCHc%CB>c2W_%
-bnu([c-:lfc-:lfc-<VJHbIC_H[CCHc%CBBblNHDqop^FHd0ffHd0ffHd0gSP^@b0XNdi!K=$8X
-c*W+MS>:M%c)chMH],kfXFkkPXS9sVK6tkfK6tkfK6tkf["E_=`KY^rK<3=MHiD:iMh0-]blGHT
-eH!;YS,g7reb>U,ec20<ec20;eH)`OJ,~>
-!<E/fc2bTUapQ"NJUN6Tb-HSL])'PWWel.PM8%-/KmeZTrlY7ls2t@ms2l=eJUtDLQ%=@;Y0)<H
-b0#9db0%#@J\%+tI=[ZtprWZ3I?FNOs+13m)8_YiI>+iH`dN9Xb'e]Xb0%SdJUN6Tb(5-?b5[J$
-b5[%mb5[%mb5[%mapbS,J\&^`JUN6Tb(5-Cb5[%ib5[%mb5[%mb5[%mas"WeJUN6Tb-$;LZA!kP
-[Y9.#Tm`?OWel.PM8%-/KmeZTpWEMes2t@ms2t@ms2kbUJUtDLQ%=@;Y0)<HrlY8#J]bFD!5ABV
-!4M]g!4MUHpQbEss-<Q.s-<N-!NlEQ~>
-!<E/feH!;[bmMFSH[CCHc*W+M^&#t]XG_FPMoErBK6r6Prll^@Hd0ffHd0gBK6t;NP^@b0XNcBE
-c-:lfc-<VJHbGYrH[D!rprrl9H^+NS&VGGTc,GooH\8EEc$Of^c$Og:bm;:QH[CCHc%CB>c2W_%
-bnu([c-:lfc-:lfc-<VJHbIC_H[CCHc%CBBblNHDqop^FHd0ffHd0ffHd0gSP^@b0XNdi!K=$8X
-c*W+MS>:M%c)chMH],kfXFkkPXS9sVK6tkfK6tkfK6tkf["E_=`KY^rK<3=MHiD:iMh0-]blGHT
-eH!;YS,g7reb>U,ec20<ec20;eH)`OJ,~>
-!<E/feH!;Qc2)be^!4guHN:b0blYk:XMrEbH\:V.qKi4Uk03t/K>iDd[`nfc`74mi!.Y~>
-!<E/fc2bTKb5-Md]$8CoI/pk/ao]G2V8gXZ`dNR+b5-Md]&q-:We&$<b-oFm^;S:tXoNt~>
-!<E/feH!;Qc2)be^!4guHN:b0blYk:XMrEbH\:V.qKi4Uk03t/K>iDd[`nfc`74mi!.Y~>
-!<E/fblGG.`<+#lUrpX\[$7AfMgLu7`;udJJ]5%9!56=q!NZ9O~>
-!<E/faoK/,`WF/oTut@Z[ZRSiNI@M@`W;dIJ]>+;!5?Co!NlEQ~>
-!<E/fblGG.`<+#lUrpX\[$7AfMgLu7`;udJJ]5%9!56=q!NZ9O~>
-!<E/fblGG.`Q,q$]p+.rK;=(;J]7E'!56=q!NZ9O~>
-!<E/faoK/,`lH(&^6*tpKqX(;J]@K)!5?Co!NlEQ~>
-!<E/fblGG.`Q,q$]p+.rK;=(;J]7E'!56=q!NZ9O~>
-!<E/fblGG.`IZ!Z`ONke]u8.rX8mb~>
-!<E/faoK/,`du-\`jj"g^;S.pXoNt~>
-!<E/fblGG.`IZ!Z`ONke]u8.rX8mb~>
-!!%S&JV/N+JV3$9!!%N~>
-!!%S$JUrB'JUum5!!%N~>
-!!%S&JV/N+JV3$9!!%N~>
-!<E0!joD3.s+13$s+14<rro4uk2s>WJ,~>
-!<E0!joD*+s+13$s+14<rro+rk2s5TJ,~>
-!<E0!joD3.s+13$s+14<rro4uk2s>WJ,~>
-!<E0!joD3.s+13$s+14=rs"+Os5rIW!.Y~>
-!<E0!joD*+s+13$s+14=rs"%Js5rIT!.Y~>
-!<E0!joD3.s+13$s+14=rs"+Os5rIW!.Y~>
-!<E0!joV@Ys+/^OeUc8%eah8jK*A(Nk2s>WJ,~>
-!<E0!joV7Vs+/mTg4@t/g@EttJH_bIk2s5TJ,~>
-!<E0!joV@Ys+/^OeUc8%eah8jK*A(Nk2s>WJ,~>
-!<E0!joV@Ys+/^OeUc8%eah8jK*A(Nk2s>WJ,~>
-!<E0!joV7Vs+/mTg4@t/g@EttJH_bIk2s5TJ,~>
-!<E0!joV@Ys+/^OeUc8%eah8jK*A(Nk2s>WJ,~>
-!<E0!joV@Ys+/^OeUc8%eah8jK*A(Nk2s>WJ,~>
-!<E0!joV7Vs+/mTg4@t/g@EttJH_bIk2s5TJ,~>
-!<E0!joV@Ys+/^OeUc8%eah8jK*A(Nk2s>WJ,~>
-!<E0!joV@Ys+/^OeUc8%eah8jK*A(Nk2s>WJ,~>
-!<E0!joV7Vs+/mTg4@t/g@EttJH_bIk2s5TJ,~>
-!<E0!joV@Ys+/^OeUc8%eah8jK*A(Nk2s>WJ,~>
-!<E0!joV@Ys+/^OeUc8%eah8jK*A(Nk2s>WJ,~>
-!<E0!joV7Vs+/mTg4@t/g@EttJH_bIk2s5TJ,~>
-!<E0!joV@Ys+/^OeUc8%eah8jK*A(Nk2s>WJ,~>
-!<E0!joV@Ys+/^OeUc8%eah8jK*A(Nk2s>WJ,~>
-!<E0!joV7Vs+/mTg4@t/g@EttJH_bIk2s5TJ,~>
-!<E0!joV@Ys+/^OeUc8%eah8jK*A(Nk2s>WJ,~>
-!<E0!joV@Ys+/^OeUc8%eah8jK*A(Nk2s>WJ,~>
-!<E0!joV7Vs+/mTg4@t/g@EttJH_bIk2s5TJ,~>
-!<E0!joV@Ys+/^OeUc8%eah8jK*A(Nk2s>WJ,~>
-!<E0!joV@Ys8(:A!!:[N!:889!<1OK!!:[N!;tCI!:/25!9Mc2!:SJ6!!^sR!7fU"!.i[OeV)KQ
-K*A(Nk2s>WJ,~>
-!<E0!joV7Vs8(IF!!:jS!:8G>!<1^P!!:jS!;tRN!:/A:!9Mr7!:SY;!!_-W!8?-,!.ijTg4\2[
-JH_bIk2s5TJ,~>
-!<E0!joV@Ys8(:A!!:[N!:889!<1OK!!:[N!;tCI!:/25!9Mc2!:SJ6!!^sR!7fU"!.i[OeV)KQ
-K*A(Nk2s>WJ,~>
-!<E0!joV@Ys8(:G!;b7G!:889!<1OK!;Y1F!:889!<1OK!9Vi3!:SJ<!;b7G!<:UL!.i[OeV)KQ
-K*A(Nk2s>WJ,~>
-!<E0!joV7Vs8(IL!;bFL!:8G>!<1^P!;Y@K!:8G>!<1^P!9W#8!:SYA!;bFL!<:dQ!.ijTg4\2[
-JH_bIk2s5TJ,~>
-!<E0!joV@Ys8(:G!;b7G!:889!<1OK!;Y1F!:889!<1OK!9Vi3!:SJ<!;b7G!<:UL!.i[OeV)KQ
-K*A(Nk2s>WJ,~>
-!<E0!joV@Ys8(:G!<(IJ!!LgP!7fWu!:n\?!<1OK!"7<W!7fU"!7_&Le^aTuo%!a?rmh#Ks4.&J
-rmgrIs4.,L"4[AOeboLJec,UNeGoU?ec,XJec,UOeGoU"r;clJr;clJrr</O!!(RJ!.i[OeX+hd
-K*A(Nk2s>WJ,~>
-!<E0!joV7Vs8(IL!<(XO!!M!U!8?0*!:nkD!<1^P!"7K\!8?-,!87DQg=lK*o%O*Drn@APs4[DO
-rn@;Ns4[JQ"53_TgAM$OgA_-Sg&M-DgA_0OgA_-Tg&M-,r;clOr;clOrr</T!!(aO!.ijTg6^On
-JH_bIk2s5TJ,~>
-!<E0!joV@Ys8(:G!<(IJ!!LgP!7fWu!:n\?!<1OK!"7<W!7fU"!7_&Le^aTuo%!a?rmh#Ks4.&J
-rmgrIs4.,L"4[AOeboLJec,UNeGoU?ec,XJec,UOeGoU"r;clJr;clJrr</O!!(RJ!.i[OeX+hd
-K*A(Nk2s>WJ,~>
-!<E0!joV@Ys8(:G!<(IJ!"%0U!7_&Le^XX"o@<j@rmh#K#1W\ReGoU"rW!/Q!!(R"!!)T?rW)oI
-rrE)Lrr<;S!!(R"!!(RG!<:UL!!(RK!!:[N!;"b@!<(IJ!"[T[!7fU"!7fU"!7fU"!7goGs4.,L
-J^o>%R+;4h"f21\k.LbF~>
-!<E0!joV7Vs8(IL!<(XO!"%?Z!87DQg=cN,o@j3Ern@AP#20%Wg&M-,rW!/V!!(a,!!)TDrW)oN
-rrE)Qrr<;X!!(a,!!(aL!<:dQ!!(aP!!:jS!;"qE!<(XO!"[c`!8?-,!8?-,!8?-,!8@8Ls4[JQ
-J_G\/R+hRk"ektYk.1PC~>
-!<E0!joV@Ys8(:G!<(IJ!"%0U!7_&Le^XX"o@<j@rmh#K#1W\ReGoU"rW!/Q!!(R"!!)T?rW)oI
-rrE)Lrr<;S!!(R"!!(RG!<:UL!!(RK!!:[N!;"b@!<(IJ!"[T[!7fU"!7fU"!7fU"!7goGs4.,L
-J^o>%R+;4h"f21\k.LbF~>
-!<E0!joV@Ys8(:D!"@BX!7_&LeGoU"eGoU@ebT7WeGoU"!!(R"!!(OL!7fU"!:\P<!<:UL!<:UL
-!;tCI!!(RK!<:UL!;tCI!<:UL!;"b=!#!f^!7_&Le^XX"e^XX"e^XX"ec#RKec#Q"eUc89ec17*
-V#TT>]`<Q~>
-!<E0!joV7Vs8(II!"@Q]!87DQg&M-,g&M-EgA1d\g&M-,!!(a,!!(^Q!8?-,!:\_A!<:dQ!<:dQ
-!;tRN!!(aP!<:dQ!;tRN!<:dQ!;"qB!#!uc!87DQg=cN,g=cN,g=cN,gAV*PgAV)'g4@tCgAc^-
-U&X9;\c@6~>
-!<E0!joV@Ys8(:D!"@BX!7_&LeGoU"eGoU@ebT7WeGoU"!!(R"!!(OL!7fU"!:\P<!<:UL!<:UL
-!;tCI!!(RK!<:UL!;tCI!<:UL!;"b=!#!f^!7_&Le^XX"e^XX"e^XX"ec#RKec#Q"eUc89ec17*
-V#TT>]`<Q~>
-!<E0!joV@Ys8(:G!<(IJ!!CaO!7grHo@<j@rmh#K$Io+VeGoU"eGoU"qZ-*8rVurKqZ-ZHqu?fK
-!!*#KrrDuIrrE)LrrDZ@rrE#Jrr<>T!!(R"!!(R"qZ$]J!!)rIrW%N"J^p+;s+:KNs5rIW!.Y~>
-!<E0!joV7Vs8(IL!<(XO!!CpT!8@;Mo@j3Ern@AP$JGI[g&M-,g&M-,qZ-*=rVurPqZ-ZMqu?fP
-!!*#PrrDuNrrE)QrrDZErrE#Orr<>Y!!(a,!!(a,qZ$]O!!)rNrW%N'J_HIEs+(?Is5rIT!.Y~>
-!<E0!joV@Ys8(:G!<(IJ!!CaO!7grHo@<j@rmh#K$Io+VeGoU"eGoU"qZ-*8rVurKqZ-ZHqu?fK
-!!*#KrrDuIrrE)LrrDZ@rrE#Jrr<>T!!(R"!!(R"qZ$]J!!)rIrW%N"J^p+;s+:KNs5rIW!.Y~>
-!<E0!joV@Ys8(:G!<(IJ!!UmQ!7_&Ln(%F<rmh#K%+P=XeGoU"eGoU"!!)K<rrE&Krr<,N!!)rI
-rrE)Lrr<,N!!*#KrrDuIrrE)LrrDZ@rrE#Jrr<DV!!(R"!!(R"!!)rIrrDrHrW%N"J^p.<s+:KN
-s5rIW!.Y~>
-!<E0!joV7Vs8(IL!<(XO!!V'V!87DQn(RdArn@AP%,([]g&M-,g&M-,!!)KArrE&Prr<,S!!)rN
-rrE)Qrr<,S!!*#PrrDuNrrE)QrrDZErrE#Orr<D[!!(a,!!(a,!!)rNrrDrMrW%N'J_HLFs+(?I
-s5rIT!.Y~>
-!<E0!joV@Ys8(:G!<(IJ!!UmQ!7_&Ln(%F<rmh#K%+P=XeGoU"eGoU"!!)K<rrE&Krr<,N!!)rI
-rrE)Lrr<,N!!*#KrrDuIrrE)LrrDZ@rrE#Jrr<DV!!(R"!!(R"!!)rIrrDrHrW%N"J^p.<s+:KN
-s5rIW!.Y~>
-!<E0!joV@Ys8(:G!<(IJ!"%0U!7_&Le^XX"o@<j@rmh#K#1W\ReGoU"rW!/Q!!(R"!!)W@rrE&K
-rr<V\!!(R"!!(OL!7fU"!7_&Lrmh#Ks4.,L#1W\Re^XX"o@<j@rRLoJ#LreSe^XX"ec#RKec,UN
-eGoUKec,XLec,W#eUc8<ec17*V#TT>]`<Q~>
-!<E0!joV7Vs8(IL!<(XO!"%?Z!87DQg=cN,o@j3Ern@AP#20%Wg&M-,rW!/V!!(a,!!)WErrE&P
-rr<Va!!(a,!!(^Q!8?-,!87DQrn@APs4[JQ#20%Wg=cN,o@j3ErS%8O#MK.Xg=cN,gAV*PgA_-S
-g&M-PgA_0QgA_/(g4@tFgAc^-U&X9;\c@6~>
-!<E0!joV@Ys8(:G!<(IJ!"%0U!7_&Le^XX"o@<j@rmh#K#1W\ReGoU"rW!/Q!!(R"!!)W@rrE&K
-rr<V\!!(R"!!(OL!7fU"!7_&Lrmh#Ks4.,L#1W\Re^XX"o@<j@rRLoJ#LreSe^XX"ec#RKec,UN
-eGoUKec,XLec,W#eUc8<ec17*V#TT>]`<Q~>
-!<E0!joV@Ys8(:G!<(IJ!!LgP!7fWu!:n\?!<1OK!"7<W!7fU"!7_&Le^aTun^[O;rmgrIrmguJ
-!7h#JrRLiHs4.,Ls4.,Lo@<j@rRLoJ!n@8Nrmh#Ks4.&Js4.,LrRLiHJ^o>%Qdu+g"f21\k.LbF~>
-!<E0!joV7Vs8(IL!<(XO!!M!U!8?0*!:nkD!<1^P!"7K\!8?-,!87DQg=lK*n_3m@rn@;Nrn@>O
-!8@AOrS%2Ms4[JQs4[JQo@j3ErS%8O!nmVSrn@APs4[DOs4[JQrS%2MJ_G\/QeMIj"ektYk.1PC~>
-!<E0!joV@Ys8(:G!<(IJ!!LgP!7fWu!:n\?!<1OK!"7<W!7fU"!7_&Le^aTun^[O;rmgrIrmguJ
-!7h#JrRLiHs4.,Ls4.,Lo@<j@rRLoJ!n@8Nrmh#Ks4.&Js4.,LrRLiHJ^o>%Qdu+g"f21\k.LbF~>
-!<E0!joV@Ys+/^OeUc8%eah8jK*A(Nk2s>WJ,~>
-!<E0!joV7Vs+/mTg4@t/g@EttJH_bIk2s5TJ,~>
-!<E0!joV@Ys+/^OeUc8%eah8jK*A(Nk2s>WJ,~>
-!<E0!joV@Ys+/^OeUc8%eah8jK*A(Nk2s>WJ,~>
-!<E0!joV7Vs+/mTg4@t/g@EttJH_bIk2s5TJ,~>
-!<E0!joV@Ys+/^OeUc8%eah8jK*A(Nk2s>WJ,~>
-!<E0!joV@Ys+/^OeUc8%eah8jK*A(Nk2s>WJ,~>
-!<E0!joV7Vs+/mTg4@t/g@EttJH_bIk2s5TJ,~>
-!<E0!joV@Ys+/^OeUc8%eah8jK*A(Nk2s>WJ,~>
-!<E0!joV@Ys+/^OeUc8%eah8jK*A(Nk2s>WJ,~>
-!<E0!joV7Vs+/mTg4@t/g@EttJH_bIk2s5TJ,~>
-!<E0!joV@Ys+/^OeUc8%eah8jK*A(Nk2s>WJ,~>
-!<E0!joV@Ys+/^OeUc8%eah8jK*A(Nk2s>WJ,~>
-!<E0!joV7Vs+/mTg4@t/g@EttJH_bIk2s5TJ,~>
-!<E0!joV@Ys+/^OeUc8%eah8jK*A(Nk2s>WJ,~>
-!<E0!joV@Ys+/^OeUc8%eah8jK*A(Nk2s>WJ,~>
-!<E0!joV7Vs+/mTg4@t/g@EttJH_bIk2s5TJ,~>
-!<E0!joV@Ys+/^OeUc8%eah8jK*A(Nk2s>WJ,~>
-!<E0!joV@Ys+/^OeUc8%eah8jK*A(Nk2s>WJ,~>
-!<E0!joV7Vs+/mTg4@t/g@EttJH_bIk2s5TJ,~>
-!<E0!joV@Ys+/^OeUc8%eah8jK*A(Nk2s>WJ,~>
-!<E0!joD3.eUc8%eUc9=eHMcKk2s>WJ,~>
-!<E0!joD*+g4@t/g4@uGg'+2Mk2s5TJ,~>
-!<E0!joD3.eUc8%eUc9=eHMcKk2s>WJ,~>
-!<E0!joD3.eUc8%eUl?>K*Kl%s5rIW!.Y~>
-!<E0!joD*+g4@t/g4J&HJHji%s5rIT!.Y~>
-!<E0!joD3.eUc8%eUl?>K*Kl%s5rIW!.Y~>
-!<E0!joV@/eU_IdC4U,TCAucPK*VG,V#TT>]`<Q~>
-!<E0!joV71g4=g+JUrB-Jc=BlJHu5/U&X9;\c@6~>
-!<E0!joV@/eU`X0Mh-eAMuM8qK*VG,V#TT>]`<Q~>
-!<E0!joV@/eU_IdC4U,UC&m]$ec19u]`<]]^&S*:eYN6-k.LbF~>
-!<E0!joV71g4=g+JUrB.JH5`LgAca#_>o/`_Z0W?g7eQ/k.1PC~>
-!<E0!joV@/eU`X0Mh-eBMZEeVec19u]`<]]^&S*:eYN6-k.LbF~>
-!<E0!johL1eS8iMXF[I(XGa1[mf(c:KDW=_s+C0]s8N;RV#TT>]`<Q~>
-!<E0!johC3g4=g+g4@t/g5F\bs8LaPJc!:bs+1$`s8N;WU&X9;\c@6~>
-!<E0!johL1eVf?:k(2ZGk)8C%s8LRKKDW=_s+C0]s8N;RV#TT>]`<Q~>
-!<E0!johL1eS8iMXF[I(XGa1[mf(c:KDW=`s+>t$^&S*:eYN6-k.LbF~>
-!<E0!johC3g4=g+g4@t/g5F\bs8LaPJc!:cs+,au_Z0W?g7eQ/k.1PC~>
-!<E0!johL1eVf?:k(2ZGk)8C%s8LRKKDW=`s+>t$^&S*:eYN6-k.LbF~>
-!<E0!johL1eS8iMXF[I(XGa1[mf(c:KD`F_s8R`K^&S*:eYN6-k.LbF~>
-!<E0!johC3g4=g+g4@t/g5F\bs8LaPJc*Cbs8RZI_Z0W?g7eQ/k.1PC~>
-!<E0!johL1eVf?:k(2ZGk)8C%s8LRKKD`F_s8R`K^&S*:eYN6-k.LbF~>
-!<E0!johL1eS8iMX8o@#!;rqs!.h5&XI60imf(c:KD`F_rrU`'KD`F_rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g&Tk*!;tRL!.ijTg6p[ps8LaPJc*CbrrUo*Jc*Cbrs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:joFQB!;u!X!.j9`k*bB3s8LRKKD`F_rrU`'KD`F_rs%#Ls5rIW!.Y~>
-!<E0!joqR2eS8j#qZ-Srq>gPsq>gMrrW)hsquHbuquHAjquHYrq>^MsrW)r!rVur"q>^MsquH#`
-!!)u!!!*#"!!)u!!!%SOJZP<As6fm:s+C9`s8W,Ls+C6_s8N;RV#TT>]`<Q~>
-!<E0!joqI4g4=h/qZ-TKq>gQLq>gNKrW)iLquHcNquHBCquHZKq>^NLrW)rOrVurPq>^NLquH$9
-!!)uO!!*#P!!)uO!!%T(J_HRHs8W)Ps+1-cs8W,Qs+1*bs8N;WU&X9;\c@6~>
-!<E0!joqR2eVf@JqZ-TWq>gQXq>gNWrW)iXquHcZquHBOquHZWq>^NXrW)r[rVur\q>^NXquH$E
-!!)u[!!*#\!!)u[!!%T4J``E`s8W)Ks+C9`s8W,Ls+C6_s8N;RV#TT>]`<Q~>
-!<E0!jp.^4eS8j#X8r4#!!)u!!!)u!#lq'.!3E7%XK2F"X8i7rX8i7tX8i7iX8i7rX8i8!X9/I(
-X8r1"!!*#"!!)u!!!*#"!!)5a!!)u!!!*#"!!)u!!!%SOJZP<As6fm:s+C9`s8W)Ks+C9`s8N;R
-V#TT>]`<Q~>
-!<E0!jp.U6g4=h/g&V**!!)uO!!)uO#lr]5!8?-,g=cQ)g&M-Kg&M-Mg&M-Bg&M-Kg&M-Og&h?/
-g&V')!!*#P!!)uO!!*#P!!)6:!!)uO!!*#P!!)uO!!%T(J_HRHs8W)Ps+1-cs8W)Ps+1-cs8N;W
-U&X9;\c@6~>
-!<E0!jp.^4eVf@JjoGAB!!)u[!!)u[#ls,M!9WDDk2l[Ajo>DWjo>DYjo>DNjo>DWjo>D[joYVG
-joG>A!!*#\!!)u[!!*#\!!)6F!!)u[!!*#\!!)u[!!%T4J``E`s8W)Ks+C9`s8W)Ks+C9`s8N;R
-V#TT>]`<Q~>
-!<E0!jp.^4eS8j#X8r1"!!*#"!!)u!#lq'.!3E7%XK2F#X9&C'!;`bs!;iht!:[&i!;W\r!<&u$
-!3E7%r2]kuri?)"rN#u!ri?)"poOJqo;holrN#u!ri?)"rN#u!JZOF(R]QPWrmh%$rk8@3rRLq#
-rOr72#1]OLk2s>WJ,~>
-!<E0!jp.U6g4=h/g&V')!!*#P!!)uO#lr]5!8?-,g=cQ*g&_9.!;bCL!;kIM!:\\B!;Y=K!<(UR
-!8?-,r7V,Nrn7>PrRq5Orn7>PptG`Jo@a0ErRq5Orn7>PrRq5OJ_G\/RbIfArn@C'rke^8rS%:&
-rPJU7#25dNk2s5TJ,~>
-!<E0!jp.^4eVf@JjoG>A!!*#\!!)u[#ls,M!9WDDk2l[BjoPPF!;bgX!;kmY!:]+N!;YaW!<)$^
-!9WDDr8mtZroO1\rT4([roO1\pu_SVoB$#QrT4([roO1\rT4([J`_OGRcaYMrmh%$rk8@3rRLq#
-rOr72#1]OLk2s>WJ,~>
-!<E0!jp.^4eS8j#X8r1"!!*#"!s#F(!;`bs!;`bu!3?1sX8i7tX8i7iX8i7rX9/I(X8r1"!!*#"
-!!)u!!s#F(!;rnu!;NYq!:m5i!<&u!!<&u!!.h5&XI?6jmf(c:KDrRas8:FIKDrRars%#Ls5rIW
-!.Y~>
-!<E0!jp.U6g4=h/g&V')!!*#P!s%'/!;bCL!;bCN!87GLg&M-Mg&M-Bg&M-Kg&h?/g&V')!!*#P
-!!)uO!s%'/!;tON!;P:J!:nkB!<(UO!<(UO!.ijTg7$aqs8LaPJc<Ods8:UNJc<Odrs%2Ns5rIT
-!.Y~>
-!<E0!jp.^4eVf@JjoG>A!!*#\!s%KG!;bgX!;bgZ!9O:Xjo>DYjo>DNjo>DWjoYVGjoG>A!!*#\
-!!)u[!s%KG!;tsZ!;P^V!:o:N!<)$[!<)$[!.j9`k*kH4s8LRKKDrRas8:FIKDrRars%#Ls5rIW
-!.Y~>
-!<E0!jp.^4eS8j#X8r1"!!*#"r;c\q!!)nt!!*#"!!)nt!!)nt!!)Mi!!)hrr;cbs!!*#"!!)u!
-r;cbs!!)5a!!)u!!!*#"!!)u!!!%SOJZP<As6fm:s+C?bs8VuHs+C<as8N;RV#TT>]`<Q~>
-!<E0!jp.U6g4=h/g&V')!!*#Pr;c]J!!)oM!!*#P!!)oM!!)oM!!)NB!!)iKr;ccL!!*#P!!)uO
-r;ccL!!)6:!!)uO!!*#P!!)uO!!%T(J_HRHs8W)Ps+13es8VuMs+10ds8N;WU&X9;\c@6~>
-!<E0!jp.^4eVf@JjoG>A!!*#\r;c]V!!)oY!!*#\!!)oY!!)oY!!)NN!!)iWr;ccX!!*#\!!)u[
-r;ccX!!)6F!!)u[!!*#\!!)u[!!%T4J``E`s8W)Ks+C?bs8VuHs+C<as8N;RV#TT>]`<Q~>
-!<E0!jp.^4eS8j#X8r1"!!*#"!s#F(!;`bs!;ikq!;iht!;iht!<&u!!;3Dn!<&u!!<0&%!3E7%
-qlBi!X8r1"!s#F(!;rnu!<&u!!:?if!<&u!!<0&"!<&u!!.h5&XI?6jmf(c:KE&Xbs8(:GKE&Xb
-rs%#Ls5rIW!.Y~>
-!<E0!jp.U6g4=h/g&V')!!*#P!s%'/!;bCL!;kLJ!;kIM!;kIM!<(UO!;5%G!<(UO!<1[S!8?-,
-qq;)Og&V')!s%'/!;tON!<(UO!:AJ?!<(UO!<1[P!<(UO!.ijTg7$aqs8LaPJcEUes8(ILJcEUe
-rs%2Ns5rIT!.Y~>
-!<E0!jp.^4eVf@JjoG>A!!*#\!s%KG!;bgX!;kpV!;kmY!;kmY!<)$[!;5IS!<)$[!<2*_!9WDD
-qrRq[joG>A!s%KG!;tsZ!<)$[!:AnK!<)$[!<2*\!<)$[!.j9`k*kH4s8LRKKE&Xbs8(:GKE&Xb
-rs%#Ls5rIW!.Y~>
-!<E0!jp.^4eS8j#X8r1"!!*#"!!)u!!!)qu!!)qu!!)qu!!)qu!!)nt!!)u!!!)\n!!)u!!!*#"
-!!)u!!!)u!!W];%r2]kurN#u!ri?)"rN#u!mAp9frN#u!ri?)"rN#u!JZOF(R]QPWrmh%$!knX6
-q:5Lts1SI4#1]OLk2s>WJ,~>
-!<E0!jp.U6g4=h/g&V')!!*#P!!)uO!!)rN!!)rN!!)rN!!)rN!!)oM!!)uO!!)]G!!)uO!!*#P
-!!)uO!!)uO!W^pSr7V,NrRq5Orn7>PrRq5OmFhO?rRq5Orn7>PrRq5OJ_G\/RbIfArn@C'!lG!;
-q:bk"s2+g9#25dNk2s5TJ,~>
-!<E0!jp.^4eVf@JjoG>A!!*#\!!)u[!!)rZ!!)rZ!!)rZ!!)rZ!!)oY!!)u[!!)]S!!)u[!!*#\
-!!)u[!!)u[!W_?_r8mtZrT4([roO1\rT4([mH+BKrT4([roO1\rT4([J`_OGRcaYMrmh%$!knX6
-q:5Lts1SI4#1]OLk2s>WJ,~>
-!<E0!jp.^4eS8j#X8r4#!!)u!!!)u!!!)qu!!)qu!!)qu!!)qu!!)nt!!)u!!!)\n!!)u!!!*#"
-!!)u!!!)qu!!)nt!!)u!!!*#"!!)u!!!)u!rrDYl!!)u!!!*#"!!)u!!!%SOJZP<As6fm:s+:Bd
-s8VlEs+:Wks8UWFs5rIW!.Y~>
-!<E0!jp.U6g4=h/g&V**!!)uO!!)uO!!)rN!!)rN!!)rN!!)rN!!)oM!!)uO!!)]G!!)uO!!*#P
-!!)uO!!)rN!!)oM!!)uO!!*#P!!)uO!!)uOrrDZE!!)uO!!*#P!!)uO!!%T(J_HRHs8W)Ps+(6g
-s8VlJs+(Kns8UfHs5rIT!.Y~>
-!<E0!jp.^4eVf@JjoGAB!!)u[!!)u[!!)rZ!!)rZ!!)rZ!!)rZ!!)oY!!)u[!!)]S!!)u[!!*#\
-!!)u[!!)rZ!!)oY!!)u[!!*#\!!)u[!!)u[rrDZQ!!)u[!!*#\!!)u[!!%T4J``E`s8W)Ks+:Bd
-s8VlEs+:Wks8UWFs5rIW!.Y~>
-!<E0!joqR2eS8j#qZ-Srq>gMrquHbur;Zi!r;cl!quHbuq#L/jq#LGrq>gGp!!)quq>^Msq#LAp
-rrDVkr;cbsr;_DMJZP9@s6fm:s+C@Oon*Ras8UWFs5rIW!.Y~>
-!<E0!joqI4g4=h/qZ-TKq>gNKquHcNr;ZiOr;clOquHcNq#L0Cq#LHKq>gHI!!)rNq>^NLq#LBI
-rrDWDr;ccLr;_E&J_HOGs8W)Ps+14MommFds8UfHs5rIT!.Y~>
-!<E0!joqR2eVf@JqZ-TWq>gNWquHcZr;Zi[r;cl[quHcZq#L0Oq#LHWq>gHU!!)rZq>^NXq#LBU
-rrDWPr;ccXr;_E2J``B_s8W)Ks+C@Oon*Ras8UWFs5rIW!.Y~>
-!<E0!johL1eS8iMXF[I(XGa1[mf(c:K)krCKE(rUeYN6-k.LbF~>
-!<E0!johC3g4=g+g4@t/g5F\bs8LaPJH5`AJcG`Sg7eQ/k.1PC~>
-!<E0!johL1eVf?:k(2ZGk)8C%s8LRKK)krCKE(rUeYN6-k.LbF~>
-!<E0!johL1eS8iMXF[I(XGa1[mf(c:KCZ_Urs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g4@t/g5F\bs8LaPJb$\Xrs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k(2ZGk)8C%s8LRKKCZ_Urs%#Ls5rIW!.Y~>
-!<E0!johL1eS8iMXF[I(XGa1[mf(c:KCJmFeYN6-k.LbF~>
-!<E0!johC3g4=g+g4@t/g5F\bs8LaPJai[Dg7eQ/k.1PC~>
-!<E0!johL1eVf?:k(2ZGk)8C%s8LRKKCJmFeYN6-k.LbF~>
-!<E0!johL1eS8iMXF[I(XGa1[mf(c:KCf*LKE(u%V#TT>]`<Q~>
-!<E0!johC3g4=g+g4@t/g5F\bs8LaPJb/mJJcGc(U&X9;\c@6~>
-!<E0!johL1eVf?:k(2ZGk)8C%s8LRKKCf*LKE(u%V#TT>]`<Q~>
-!<E0!johL1eS8iMXF[I(XGa1[mf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g4@t/g5F\bs8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k(2ZGk)8C%s8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8iMXGX(Z!.h5(XT._fec1:%s7Y"CKE(rUeYN6-k.LbF~>
-!<E0!johC3g4=g+g5=Sa!.ijVgAh3PgAca(s7Y1HJcG`Sg7eQ/k.1PC~>
-!<E0!johL1eVf?:k)/:$!.j9bk5YJ\ec1:%s7Y"CKE(rUeYN6-k.LbF~>
-!<E0!joqR2eS8j#quHVqrW)ktqZ-Vsq>^MsquEau!!':*rW)/`!W];%r2fnuJZOL*s6fm:s+C@O
-p=91qs8N;RV#TT>]`<Q~>
-!<E0!joqI4g4=h/quHWJrW)lMqZ-WLq>^NLquEbN!!':XrW)09!W^pSr7_/NJ_Gb1s8W)Ps+14M
-p=fOts8N;WU&X9;\c@6~>
-!<E0!joqR2eVf@JquHWVrW)lYqZ-WXq>^NXquEbZ!!':drW)0E!W_?_r9""ZJ`_UIs8W)Ks+C@O
-p=91qs8N;RV#TT>]`<Q~>
-!<E0!johL1eS8juX8i7pX8i7tX8i8!X8i8"X8i8!X8i8"X8i7!X8i7(X8i7aX9&C'!<&u#!3?0O
-XFmVSmf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=hSg&M-Ig&M-Mg&M-Og&M-Pg&M-Og&M-Pg&M,Og&M,Vg&M-:g&_9.!<(UQ!87F(
-g4S,Zs8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf@bjo>DUjo>DYjo>D[jo>D\jo>D[jo>D\jo>C[jo>Cbjo>DFjoPPF!<)$]!9O94
-k(Dgrs8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8juX8i7qX9&C'!;rnu!<&u!!<0&"!<&u!!<0&"!;NYq!48j*!<'#!!<9/#!<'"t
-!<0)"!!',"!;rqr!;3Gn!<9/#!;rqt!<0)"!!',"!;`bs!<'"u!<9/"!;*>o!3?1tX8i6OXFmVS
-mf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=hSg&M-Jg&_9.!;tON!<(UO!<1[P!<(UO!<1[P!;P:J!4:JX!<(XO!<:dQ!<(XM
-!<1^P!!(aP!;tRK!;5(G!<:dQ!;tRM!<1^P!!(aP!;bCL!<(XN!<:dP!;+tH!87GMg&M,(g4S,Z
-s8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf@bjo>DVjoPPF!;tsZ!<)$[!<2*\!<)$[!<2*\!;P^V!4:nd!<)'[!<;3]!<)'Y
-!<2-\!!)0\!;u!W!;5LS!<;3]!;u!Y!<2-\!!)0\!;bgX!<)'Z!<;3\!;,CT!9O:Yjo>C4k(Dgr
-s8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8juX8i7qX9&C'!;rnu!<&u!!<0&%!3E7%r2]kupoOJqZ`F-,q5ai%X8o?'!3E7%
-rN#u!riH,"ri?)"ri?)"rN#u!oW/2rX8o?'!<0&"!<0&"!<0)"!<0&"!;iht!;rnu!<&u!!;*Aj
-!;rnu!.h5(XT._fec1:%s7Y"CKE(rUeYN6-k.LbF~>
-!<E0!johC3g4=hSg&M-Jg&_9.!;tON!<(UO!<1[S!8?-,r7V,NptG`JZe>BZq:Z)Sg&Tj\!8?-,
-rRq5Orn@APrn7>Prn7>PrRq5Oo\'HKg&Tj\!<1[P!<1[P!<1^P!<1[P!;kIM!;tON!<(UO!;,"C
-!;tON!.ijVgAh3PgAca(s7Y1HJcG`Sg7eQ/k.1PC~>
-!<E0!johL1eVf@bjo>DVjoPPF!;tsZ!<)$[!<2*_!9WDDr8mtZpu_SVZfV5fq;qq_joFQ+!9WDD
-rT4([roX4\roO1\roO1\rT4([o]?;WjoFQ+!<2*\!<2*\!<2-\!<2*\!;kmY!;tsZ!<)$[!;,FO
-!;tsZ!.j9bk5YJ\ec1:%s7Y"CKE(rUeYN6-k.LbF~>
-!<E0!johL1eS8juX8i7rX8i8"X8i8!XS`(sXSi.sX8i7!X8i7rXT&:oX8i8"X8i8!X8i8"X8i7h
-XT&:tX8i7uX9/I(X8r1"!!)qu!!)qu!!)u!!!)Vl!W];%qlBbtJZOL*s6fm:s+C@Op=91qs8N;R
-V#TT>]`<Q~>
-!<E0!johC3g4=hSg&M-Kg&M-Pg&M-OgACsLgAM$Lg&M,Og&M-KgA_0Hg&M-Pg&M-Og&M-Pg&M-A
-gA_0Mg&M-Ng&h?/g&V')!!)rN!!)rN!!)uO!!)WE!W^pSqq;#MJ_Gb1s8W)Ps+14Mp=fOts8N;W
-U&X9;\c@6~>
-!<E0!johL1eVf@bjo>DWjo>D\jo>D[k555Xk5>;Xjo>C[jo>DWk5PGTjo>D\jo>D[jo>D\jo>DM
-k5PGYjo>DZjoYVGjoG>A!!)rZ!!)rZ!!)u[!!)WQ!W_?_qrRkYJ`_UIs8W)Ks+C@Op=91qs8N;R
-V#TT>]`<Q~>
-!<E0!johL1eS8juX8i8!X8i8"XS`(sX8i8!X8i8"X9/I(X8r1"!!)u!!!'.&!!)hr!!)hrquH_t
-!!)u!!!)u!r;cGj!!)ksq>gPs!!)qu!!)qu!!)nt!s#F(!;!;i!;rnu!.h5(XT._fec1:%s7Y"C
-KE(rUeYN6-k.LbF~>
-!<E0!johC3g4=hSg&M-Og&M-PgACsLg&M-Og&M-Pg&h?/g&V')!!)uO!!'.T!!)iK!!)iKquH`M
-!!)uO!!)uOr;cHC!!)lLq>gQL!!)rN!!)rN!!)oM!s%'/!;"qB!;tON!.ijVgAh3PgAca(s7Y1H
-JcG`Sg7eQ/k.1PC~>
-!<E0!johL1eVf@bjo>D[jo>D\k555Xjo>D[jo>D\joYVGjoG>A!!)u[!!'.`!!)iW!!)iWquH`Y
-!!)u[!!)u[r;cHO!!)lXq>gQX!!)rZ!!)rZ!!)oY!s%KG!;#@N!;tsZ!.j9bk5YJ\ec1:%s7Y"C
-KE(rUeYN6-k.LbF~>
-!<E0!johL1eS8juX8i8!X9/I(X8r1"!!*#"!!)u!!!*#"!!)u!!!*#"!!)u!!!'.&!!)hr!!)ks
-!!)u!!!*#"!!)u!!!)hr!!)Ym!!)ks!!)hr!!)qu!!)qu!!)nt!s#F(!:m2m!3?1tX8i6OXFmVS
-mf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=hSg&M-Og&h?/g&V')!!*#P!!)uO!!*#P!!)uO!!*#P!!)uO!!'.T!!)iK!!)lL
-!!)uO!!*#P!!)uO!!)iK!!)ZF!!)lL!!)iK!!)rN!!)rN!!)oM!s%'/!:nhF!87GMg&M,(g4S,Z
-s8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf@bjo>D[joYVGjoG>A!!*#\!!)u[!!*#\!!)u[!!*#\!!)u[!!'.`!!)iW!!)lX
-!!)u[!!*#\!!)u[!!)iW!!)ZR!!)lX!!)iW!!)rZ!!)rZ!!)oY!s%KG!:o7R!9O:Yjo>C4k(Dgr
-s8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8juX8i8!X9/I(X8r1"!!*#"!!)u!!!*#"!!)u!!!*#"!!)u!!!)u!rrBC,!!*#"
-!!)u!!!)ks!!*#"rrE&"!!)u!!!*#"!!)u!!!)Ym!!)hr!!)u!"9>O)!!*#"!!)nt!!)ksrrDSj
-!W];%qlBbtJZOL*s6fm:s+C@Op=91qs8N;RV#TT>]`<Q~>
-!<E0!johC3g4=hSg&M-Og&h?/g&V')!!*#P!!)uO!!*#P!!)uO!!*#P!!)uO!!)uOrrBCZ!!*#P
-!!)uO!!)lL!!*#PrrE&P!!)uO!!*#P!!)uO!!)ZF!!)iK!!)uO"9@00!!*#P!!)oM!!)lLrrDTC
-!W^pSqq;#MJ_Gb1s8W)Ps+14Mp=fOts8N;WU&X9;\c@6~>
-!<E0!johL1eVf@bjo>D[joYVGjoG>A!!*#\!!)u[!!*#\!!)u[!!*#\!!)u[!!)u[rrBCf!!*#\
-!!)u[!!)lX!!*#\rrE&\!!)u[!!*#\!!)u[!!)ZR!!)iW!!)u["9@TH!!*#\!!)oY!!)lXrrDTO
-!W_?_qrRkYJ`_UIs8W)Ks+C@Op=91qs8N;RV#TT>]`<Q~>
-!<E0!joqR2eS8j#q#CDrr;Zi!r;Zi!qZ-Vsq>^Msq#LAprrB@+rW)nur;c_rrW!&%!!',"!<9/"
-!<9.u!;*Ak!;`eq!<0&#!3H/"r2ferqlBbtnZ2clX8r4#quD;LKrk=Brmh%$s8VfCs+C@O#1]OL
-k2s>WJ,~>
-!<E0!joqI4g4=h/q#CEKr;ZiOr;ZiOqZ-WLq>^NLq#LBIrrB@YrW)oNr;c`KrW!&S!!(aP!<:dP
-!<:dN!;,"D!;bFJ!<1[Q!8@DPr7_&Kqq;#Mn_+$Eg&V**quD<%L"cS,rn@C's8VfHs+14M#25dN
-k2s5TJ,~>
-!<E0!joqR2eVf@Jq#CEWr;Zi[r;Zi[qZ-WXq>^NXq#LBUrrB@erW)oZr;c`WrW!&_!!)0\!<;3\
-!<;3Z!;,FP!;bjV!<2*]!9X7\r9!nWqrRkYn`BlQjoGABquD<1L$&F8rmh%$s8VfCs+C@O#1]OL
-k2s>WJ,~>
-!<E0!johL1eS8iMXLYD4!:Hog!.h5&XQZbcmf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g:>o;!:JP@!.ijTg?@8js8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k.0US!:JtL!.j9`k31t-s8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8iMXLYD4!:Hog!.h5&XQZbcmf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g:>o;!:JP@!.ijTg?@8js8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k.0US!:JtL!.j9`k31t-s8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8iMXLbM3!:m5i!.h5&XQchdmf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g:H#:!:nkB!.ijTg?I>ks8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k.9^R!:o:N!.j9`k3;%.s8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8iMXF[I(XGa1[mf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g4@t/g5F\bs8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k(2ZGk)8C%s8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8iMXF[I(XGa1[mf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g4@t/g5F\bs8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k(2ZGk)8C%s8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8iMXF[I(XGa1[mf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g4@t/g5F\bs8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k(2ZGk)8C%s8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!jp%X3eS8j#XSMnsXSW"qXSi.uXSr5!XSr3`X8i7EX8i7rX8i6OXF[J0XT._fec1:%s7Y"C
-KE(rUeYN6-k.LbF~>
-!<E0!jp%O5g4=h/gA1dLgA:mJgAM$NgAV*OgAV)9g&M,sg&M-Kg&M,(g4@u7gAh3PgAca(s7Y1H
-JcG`Sg7eQ/k.1PC~>
-!<E0!jp%X3eVf@Jk5#&Xk5,/Vk5>;Zk5GA[k5G@Ejo>D*jo>DWjo>C4k(2[Ok5YJ\ec1:%s7Y"C
-KE(rUeYN6-k.LbF~>
-!<E0!johL1eS8juX8i8!X9/I(X8r4#!!*#"!!)u!!!*#"rrE&"rrA4`!!(6E!!)hr!!%SOJZR_0
-s6fm:s+C@Op=91qs8N;RV#TT>]`<Q~>
-!<E0!johC3g4=hSg&M-Og&h?/g&V**!!*#P!!)uO!!*#PrrE&PrrA59!!(6s!!)iK!!%T(J_Ju7
-s8W)Ps+14Mp=fOts8N;WU&X9;\c@6~>
-!<E0!johL1eVf@bjo>D[joYVGjoGAB!!*#\!!)u[!!*#\rrE&\rrA5E!!(7*!!)iW!!%T4J`bhO
-s8W)Ks+C@Op=91qs8N;RV#TT>]`<Q~>
-!<E0!johL1eS8juX8i8!X9/I(X8r4#!s#F(!;ii%!3E7%X8o@$!<'#!!33."!!95%!<0(u!<'"s
-!;iks!<0)!!<0)!!<9/!!<0)!!<9/"!;<Ml!<'"s!.h5&XPp8\mf(c:KE(uFec1:%rs%#Ls5rIW
-!.Y~>
-!<E0!johC3g4=hSg&M-Og&h?/g&V**!s%'/!;kIS!8?-,g&Tk+!<(XO!34cP!!:jS!<1^N!<(XL
-!;kLL!<1^O!<1^O!<:dO!<1^O!<:dP!;>.E!<(XL!.ijTg>Uccs8LaPJcGcDgAca(rs%2Ns5rIT
-!.Y~>
-!<E0!johL1eVf@bjo>D[joYVGjoGAB!s%KG!;km_!9WDDjoFQC!<)'[!352\!!;9_!<2-Z!<)'X
-!;kpX!<2-[!<2-[!<;3[!<2-[!<;3\!;>RQ!<)'X!.j9`k2GJ&s8LRKKE(uFec1:%rs%#Ls5rIW
-!.Y~>
-!<E0!johL1eS8juX9/I(X8r4#!!)u!!s#F(!;ii(!3E7%X8o=%X8r4#rrB+$!!*#"rrE&"!!)u!
-!!)u!!!)hr!!*#"!!*#"!!)qu!s#F(!<&u!!<0&"!<&u!!;*>m!;W\r!.h5&XPU&Ymf(c:KE(uF
-ec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=hSg&h?/g&V**!!)uO!s%'/!;kIV!8?-,g&Th,g&V**rrB+R!!*#PrrE&P!!)uO
-!!)uO!!)iK!!*#P!!*#P!!)rN!s%'/!<(UO!<1[P!<(UO!;+tF!;Y=K!.ijTg>:Q`s8LaPJcGcD
-gAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf@bjoYVGjoGAB!!)u[!s%KG!;kmb!9WDDjoFNDjoGABrrB+^!!*#\rrE&\!!)u[
-!!)u[!!)iW!!*#\!!*#\!!)rZ!s%KG!<)$[!<2*\!<)$[!;,CR!;YaW!.j9`k2,8#s8LRKKE(uF
-ec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8juXSi.tX8i8"X8i8"X8i7tX9em.X8o?'!3E7%VQ9atr2]kuq5aPrrN#u!qQ'Ys
-r2^2)XK2E'X8o?'!;`bs!<0&"!<&u!!;*>m!;W\r!.h5&XPU&Ymf(c:KE(uFec1:%rs%#Ls5rIW
-!.Y~>
-!<E0!johC3g4=hSgAM$Mg&M-Pg&M-Pg&M-Mg'Ic5g&Tj\!8?-,VV2"Mr7V,Nq:YfKrRq5OqUtoL
-r7VGWg=cP\g&Tj\!;bCL!<1[P!<(UO!;+tF!;Y=K!.ijTg>:Q`s8LaPJcGcDgAca(rs%2Ns5rIT
-!.Y~>
-!<E0!johL1eVf@bk5>;Yjo>D\jo>D\jo>DYjp;%MjoFQ+!9WDDVWIjYr8mtZq;qYWrT4([qW7bX
-r8n:ck2l[+joFQ+!;bgX!<2*\!<)$[!;,CR!;YaW!.j9`k2,8#s8LRKKE(uFec1:%rs%#Ls5rIW
-!.Y~>
-!<E0!johL1eS8juX9/I(X8r4#r;cet!!)nt#lq'.!3E7%XK2E!X8i7uX8i8!XS`(sX8i7sXSMqs
-X9J[+X8o?'!<0(t!<&u$!3E7%o;holq5aPrJZOF(hQ6bFrmh%$s8VfCs+C@O#1]OLk2s>WJ,~>
-!<E0!johC3g4=hSg&h?/g&V**r;cfM!!)oM#lr]5!8?-,g=cP(g&M-Ng&M-OgACsLg&M-LgA1gL
-g'.Q2g&Tj\!<1^M!<(UR!8?-,o@a0Eq:YfKJ_G\/hV/#0rn@C's8VfHs+14M#25dNk2s5TJ,~>
-!<E0!johL1eVf@bjoYVGjoGABr;cfY!!)oY#ls,M!9WDDk2lZ@jo>DZjo>D[k555Xjo>DXk5#)X
-jothJjoFQ+!<2-Y!<)$^!9WDDoB$#Qq;qYWJ`_OGhWFk<rmh%$s8VfCs+C@O#1]OLk2s>WJ,~>
-!<E0!johL1eS8juX8i7sX8i8"X8i8"X8i7tX9/I(X8r1"!!&mt!!)qu!!*#"!!)u!!!)u!!!)ks
-!!)eq"9>M'X8r7$!!)u!!!)u!!s#F(!;!8l!;W\r!.h5&XPU&Ymf(c:KE(uFec1:%rs%#Ls5rIW
-!.Y~>
-!<E0!johC3g4=hSg&M-Lg&M-Pg&M-Pg&M-Mg&h?/g&V')!!&nM!!)rN!!*#P!!)uO!!)uO!!)lL
-!!)fJ"9@-Ug&V-+!!)uO!!)uO!s%'/!;"nE!;Y=K!.ijTg>:Q`s8LaPJcGcDgAca(rs%2Ns5rIT
-!.Y~>
-!<E0!johL1eVf@bjo>DXjo>D\jo>D\jo>DYjoYVGjoG>A!!&nY!!)rZ!!*#\!!)u[!!)u[!!)lX
-!!)fV"9@QajoGDC!!)u[!!)u[!s%KG!;#=Q!;YaW!.j9`k2,8#s8LRKKE(uFec1:%rs%#Ls5rIW
-!.Y~>
-!<E0!johL1eS8juX8i7sX8i8!X8i8"X8i8!X8i8"X8i7uX8i8!XT&:$X8i8"XT&;"X8i8"XT&;!
-X8i8"X8i8!X8i8!X8i8"XT&8%X8i8"X8i8"XT&:uXT&:kX8i8"X8i8!X8i8"X8i6OXF[J4XT._f
-ec1:%s7Y"CKE(rUeYN6-k.LbF~>
-!<E0!johC3g4=hSg&M-Lg&M-Og&M-Pg&M-Og&M-Pg&M-Ng&M-OgA_/Rg&M-PgA_0Pg&M-PgA_0O
-g&M-Pg&M-Og&M-Og&M-PgA_-Sg&M-Pg&M-PgA_0NgA_0Dg&M-Pg&M-Og&M-Pg&M,(g4@u;gAh3P
-gAca(s7Y1HJcG`Sg7eQ/k.1PC~>
-!<E0!johL1eVf@bjo>DXjo>D[jo>D\jo>D[jo>D\jo>DZjo>D[k5PF^jo>D\k5PG\jo>D\k5PG[
-jo>D\jo>D[jo>D[jo>D\k5PD_jo>D\jo>D\k5PGZk5PGPjo>D\jo>D[jo>D\jo>C4k(2[Sk5YJ\
-ec1:%s7Y"CKE(rUeYN6-k.LbF~>
-!<E0!jp%X3eS8j#XSi.tXSr4uX8i8"XSi.uXSr5!XSr5!XT&:#XSr2#X8r4#rW!#$!!)u!rW)hs
-r;cetrr<,%!!)u!rW!#$!!)qu!!)PjrW)hsrW%MNJZRh3s6fm:s+C@Op=91qs8N;RV#TT>]`<Q~>
-!<E0!jp%O5g4=h/gAM$MgAV*Ng&M-PgAM$NgAV*OgAV*OgA_/QgAV'Qg&V**rW!#R!!)uOrW)iL
-r;cfMrr<,S!!)uOrW!#R!!)rN!!)QCrW)iLrW%N'J_K):s8W)Ps+14Mp=fOts8N;WU&X9;\c@6~>
-!<E0!jp%X3eVf@Jk5>;Yk5GAZjo>D\k5>;Zk5GA[k5GA[k5PF]k5G>]joGABrW!#^!!)u[rW)iX
-r;cfYrr<,_!!)u[rW!#^!!)rZ!!)QOrW)iXrW%N3J`bqRs8W)Ks+C@Op=91qs8N;RV#TT>]`<Q~>
-!<E0!johL1eS8iMXSf."!7._H!.h5&XMh4?mf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+gAKY)!70@!!.ijTg;M_Fs8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k5=?A!70d-!.j9`k/?E^s8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8iMXSo4#!7%YG!.h5&XMh4?mf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+gAT_*!7'9u!.ijTg;M_Fs8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k5FEB!7'^,!.j9`k/?E^s8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8iMXSi.FXSi.tXS;dHXF[J$XT._fec1:%s7Y"CKE(rUeYN6-k.LbF~>
-!<E0!johC3g4=g+gAM#tgAM$Mg@tZ!g4@u+gAh3PgAca(s7Y1HJcG`Sg7eQ/k.1PC~>
-!<E0!johL1eVf?:k5>;+k5>;Yk4eq-k(2[Ck5YJ\ec1:%s7Y"CKE(rUeYN6-k.LbF~>
-!<E0!johL1eS8iMXF[I(XGa1[mf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g4@t/g5F\bs8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k(2ZGk)8C%s8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8iMXF[I(XGa1[mf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g4@t/g5F\bs8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k(2ZGk)8C%s8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8iMXF[I(XGa1[mf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g4@t/g5F\bs8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k(2ZGk)8C%s8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!jp%X3eS8j#XSMqrXSi-MXS&Xp!9^H_!;iks!.h5&XNmpImf(c:KE(uFec1:%rs%#Ls5rIW
-!.Y~>
-!<E0!jp%O5g4=h/gA1gKgAM#&g@a/"!9`)8!;kLL!.ijTg<SFPs8LaPJcGcDgAca(rs%2Ns5rIT
-!.Y~>
-!<E0!jp%X3eVf@Jk5#)Wk5>:2k4Rj:!9`MD!;kpX!.j9`k0E,hs8LRKKE(uFec1:%rs%#Ls5rIW
-!.Y~>
-!<E0!jq+?=eS8j#X8o?'!3E7%XK2F#X8i6OXS/^q!9L9^!;W\r!.h5&XNmpImf(c:KE(uFec1:%
-rs%#Ls5rIW!.Y~>
-!<E0!jq+6?g4=h/g&Tj\!8?-,g=cQ*g&M,(g@j5#!9Mo7!;Y=K!.ijTg<SFPs8LaPJcGcDgAca(
-rs%2Ns5rIT!.Y~>
-!<E0!jq+?=eVf@JjoFQ+!9WDDk2l[Bjo>C4k4[p;!9N>C!;YaW!.j9`k0E,hs8LRKKE(uFec1:%
-rs%#Ls5rIW!.Y~>
-!<E0!jq"9<eS8j#X8o?'!3E7%X8r.!!!)u!rrACerVuu#!<0(u!<0)"!!',"!<'"s!<'#!!<9/#
-!<'"t!;`bs!;W\r!;`er!<'#!!<9/#!.h5&XQ$>]mf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!jq"0>g4=h/g&Tj\!8?-,g&V$(!!)uOrrAD>rVuuQ!<1^N!<1^P!!(aP!<(XL!<(XO!<:dQ
-!<(XM!;bCL!;Y=K!;bFK!<(XO!<:dQ!.ijTg>^ids8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!jq"9<eVf@JjoFQ+!9WDDjoG;@!!)u[rrADJrVuu]!<2-Z!<2-\!!)0\!<)'X!<)'[!<;3]
-!<)'Y!;bgX!;YaW!;bjW!<)'[!<;3]!.j9`k2PP's8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8jsX8i8!X8i7tX8i8!XT&9fX8i8"XT&;#X8i8!X8i8"XT&;"X8i8!X8i7rX9\g-
-!3E7%XK2F#X8i7tX8i7rX8i7tX8i8"X8i8!X9AU*!3E7%JZOF(j/i:Krmh%$s8VfCs+C@O#1]OL
-k2s>WJ,~>
-!<E0!johC3g4=hQg&M-Og&M-Mg&M-OgA_/?g&M-PgA_0Qg&M-Og&M-PgA_0Pg&M-Og&M-Kg'@]4
-!8?-,g=cQ*g&M-Mg&M-Kg&M-Mg&M-Pg&M-Og'%K1!8?-,J_G\/j4aP5rn@C's8VfHs+14M#25dN
-k2s5TJ,~>
-!<E0!johL1eVf@`jo>D[jo>DYjo>D[k5PFKjo>D\k5PG]jo>D[jo>D\k5PG\jo>D[jo>DWjp1tL
-!9WDDk2l[Bjo>DYjo>DWjo>DYjo>D\jo>D[jokbI!9WDDJ`_OGj6$CArmh%$s8VfCs+C@O#1]OL
-k2s>WJ,~>
-!<E0!johL1eS8jsX8i8!X8i7tX8i6aX8i7uX9&C'!;ii"!3E7%rN#u!rN#u!q5jSrr2]kuqlBbt
-r2]kuq5aPrr2]kur2]kuriH,"JZOF(hlQkGrmh%$s8VfCs+C@O#1]OLk2s>WJ,~>
-!<E0!johC3g4=hQg&M-Og&M-Mg&M,:g&M-Ng&_9.!;kIP!8?-,rRq5OrRq5Oq:biKr7V,Nqq;#M
-r7V,Nq:YfKr7V,Nr7V,Nrn@APJ_G\/hqJ,1rn@C's8VfHs+14M#25dNk2s5TJ,~>
-!<E0!johL1eVf@`jo>D[jo>DYjo>CFjo>DZjoPPF!;km\!9WDDrT4([rT4([q<%\Wr8mtZqrRkY
-r8mtZq;qYWr8mtZr8mtZroX4\J`_OGhrat=rmh%$s8VfCs+C@O#1]OLk2s>WJ,~>
-!<E0!johL1eS8jsX8i8!X8i7tX8i6aX8i7sX8i7tX9/I(X8r4#!!)u!!!)hr!!)nt!!)nt!!)qu
-!!)hr!!)quq>gMr!!%SOJZR_0s6fm:s+C@Op=91qs8N;RV#TT>]`<Q~>
-!<E0!johC3g4=hQg&M-Og&M-Mg&M,:g&M-Lg&M-Mg&h?/g&V**!!)uO!!)iK!!)oM!!)oM!!)rN
-!!)iK!!)rNq>gNK!!%T(J_Ju7s8W)Ps+14Mp=fOts8N;WU&X9;\c@6~>
-!<E0!johL1eVf@`jo>D[jo>DYjo>CFjo>DXjo>DYjoYVGjoGAB!!)u[!!)iW!!)oY!!)oY!!)rZ
-!!)iW!!)rZq>gNW!!%T4J`bhOs8W)Ks+C@Op=91qs8N;RV#TT>]`<Q~>
-!<E0!johL1eS8jsX8i8!X8i7tX8i6aX8i7sX8i7tX9/I(X8r4#!!)u!!!)hr!!)nt!!)nt!!)qu
-!!)hr!!)qu!!)eq!!%SOJZR_0s6fm:s+C@Op=91qs8N;RV#TT>]`<Q~>
-!<E0!johC3g4=hQg&M-Og&M-Mg&M,:g&M-Lg&M-Mg&h?/g&V**!!)uO!!)iK!!)oM!!)oM!!)rN
-!!)iK!!)rN!!)fJ!!%T(J_Ju7s8W)Ps+14Mp=fOts8N;WU&X9;\c@6~>
-!<E0!johL1eVf@`jo>D[jo>DYjo>CFjo>DXjo>DYjoYVGjoGAB!!)u[!!)iW!!)oY!!)oY!!)rZ
-!!)iW!!)rZ!!)fV!!%T4J`bhOs8W)Ks+C@Op=91qs8N;RV#TT>]`<Q~>
-!<E0!johL1eS8jsX8i7uX8i8!X8i7uXT&9fX8i8!X9/I(X8r4#!!*#"!!)u!!!)u!!!*#"!!)u!
-!!)ks!!)u!!!)nt!!)hr!!)nt!!)u!!!*#"!!%SOJZR_0s6fm:s+C@Op=91qs8N;RV#TT>]`<Q~>
-!<E0!johC3g4=hQg&M-Ng&M-Og&M-NgA_/?g&M-Og&h?/g&V**!!*#P!!)uO!!)uO!!*#P!!)uO
-!!)lL!!)uO!!)oM!!)iK!!)oM!!)uO!!*#P!!%T(J_Ju7s8W)Ps+14Mp=fOts8N;WU&X9;\c@6~>
-!<E0!johL1eVf@`jo>DZjo>D[jo>DZk5PFKjo>D[joYVGjoGAB!!*#\!!)u[!!)u[!!*#\!!)u[
-!!)lX!!)u[!!)oY!!)iW!!)oY!!)u[!!*#\!!%T4J`bhOs8W)Ks+C@Op=91qs8N;RV#TT>]`<Q~>
-!<E0!johL1eS8juXS`(sXSi.rXT&9eXSi.tXSi.uXSr5"XSr4uXSr4uXSi.rXSi.sXS`(sXS`(r
-XSi.uXSi-MXF[J2XT._fec1:%s7Y"CKE(rUeYN6-k.LbF~>
-!<E0!johC3g4=hSgACsLgAM$KgA_/>gAM$MgAM$NgAV*PgAV*NgAV*NgAM$KgAM$LgACsLgACsK
-gAM$NgAM#&g4@u9gAh3PgAca(s7Y1HJcG`Sg7eQ/k.1PC~>
-!<E0!johL1eVf@bk555Xk5>;Wk5PFJk5>;Yk5>;Zk5GA\k5GAZk5GAZk5>;Wk5>;Xk555Xk555W
-k5>;Zk5>:2k(2[Qk5YJ\ec1:%s7Y"CKE(rUeYN6-k.LbF~>
-!<E0!johL1eS8iMXF[I(XGa1[mf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g4@t/g5F\bs8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k(2ZGk)8C%s8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8iMXF[I(XGa1[mf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g4@t/g5F\bs8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k(2ZGk)8C%s8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8iMXF[I(XGa1[mf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g4@t/g5F\bs8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k(2ZGk)8C%s8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8iMXF[I(XGa1[mf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g4@t/g5F\bs8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k(2ZGk)8C%s8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8iMXF[I(XGa1[mf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g4@t/g5F\bs8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k(2ZGk)8C%s8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8iMX8o@#!;rqs!;rqs!;rqs!:m2k!;`eq!:m2k!;NYq!:m2k!;`ep!;*Ak!;rqs
-!;!;j!:m2k!;`eq!<'"r!;rqt!;`es!;rqs!.h68XT._fec1:%s7Y"CKE(rUeYN6-k.LbF~>
-!<E0!johC3g4=g+g&Tk*!;tRL!;tRL!;tRL!:nhD!;bFJ!:nhD!;P:J!:nhD!;bFI!;,"D!;tRL
-!;"qC!:nhD!;bFJ!<(XK!;tRM!;bFL!;tRL!.ikfgAh3PgAca(s7Y1HJcG`Sg7eQ/k.1PC~>
-!<E0!johL1eVf?:joFQB!;u!X!;u!X!;u!X!:o7P!;bjV!:o7P!;P^V!:o7P!;bjU!;,FP!;u!X
-!;#@O!:o7P!;bjV!<)'W!;u!Y!;bjX!;u!X!.j:rk5YJ\ec1:%s7Y"CKE(rUeYN6-k.LbF~>
-!<E0!jp%X3eS8j#XSMnsXSr5!XSr2"XSMnsXSr5"XSr5"XSMqjXSMqrXSr2#X8p>C!!)u!!!*#"
-!!)u!!!*#"!!)u!!!*#"!!)u!!!)YmrrDqt!!)u!!!)YmrrDkr!W];%o;qrlqQ'YsnZ2]jrN#u!
-ri?)"rN#u!orJ,nrN#u!oW8&mqlBbtrN#u!ri?)"rN#u!rN#u!poFMsX8r4#!!)u!!!%SOl)apQ
-rmh%$s8VfCs+C@O#1]OLk2s>WJ,~>
-!<E0!jp%O5g4=h/gA1dLgAV*OgAV'PgA1dLgAV*PgAV*PgA1gCgA1gKgAV'Qg&T4J!!)uO!!*#P
-!!)uO!!*#P!!)uO!!*#P!!)uO!!)ZFrrDrM!!)uO!!)ZFrrDlK!W^pSo@j3EqUtoLn_*sCrRq5O
-rn7>PrRq5Op"BBGrRq5Oo\0<Fqq;#MrRq5Orn7>PrRq5OrRq5Opt>cLg&V**!!)uO!!%T(l.Z1;
-rn@C's8VfHs+14M#25dNk2s5TJ,~>
-!<E0!jp%X3eVf@Jk5#&Xk5GA[k5G>\k5#&Xk5GA\k5GA\k5#)Ok5#)Wk5G>]joEKb!!)u[!!*#\
-!!)u[!!*#\!!)u[!!*#\!!)u[!!)ZRrrDrY!!)u[!!)ZRrrDlW!W_?_oB-&QqW7bXn`BfOrT4([
-roO1\rT4([p#Z5SrT4([o]H/RqrRkYrT4([roO1\rT4([rT4([puVVXjoGAB!!)u[!!%T4l/r$G
-rmh%$s8VfCs+C@O#1]OLk2s>WJ,~>
-!<E0!johL1eS8juX8i8!X9/I(X8r1"!!*#"!!)u!"9>O)!!*#"!!*#""ota+!3E7%p8eQ#XK2E'
-X8o?'!<0)"!6D5A!<&u!!<0&"!<&u!!<0&"!<&u!!<0&"!<&u!!;3Dp!3?1tX8i8!X8i7nX9&C'
-!;W\t!3?1mX9&C'!;`bs!:6ce!;W\r!;3Dn!<&u!!;3Dp!3?1tX8i8!X8i7rX8i8"X8i7pX9&C'
-!<&u!!<&u!!.h69XT._fec1:%s7Y"CKE(rUeYN6-k.LbF~>
-!<E0!johC3g4=hSg&M-Og&h?/g&V')!!*#P!!)uO"9@00!!*#P!!*#P"p!B2!8?-,p=]fQg=cP\
-g&Tj\!<1^P!6Ejo!<(UO!<1[P!<(UO!<1[P!<(UO!<1[P!<(UO!;5%I!87GMg&M-Og&M-Gg&_9.
-!;Y=M!87GFg&_9.!;bCL!:8D>!;Y=K!;5%G!<(UO!;5%I!87GMg&M-Og&M-Kg&M-Pg&M-Ig&_9.
-!<(UO!<(UO!.ikggAh3PgAca(s7Y1HJcG`Sg7eQ/k.1PC~>
-!<E0!johL1eVf@bjo>D[joYVGjoG>A!!*#\!!)u["9@TH!!*#\!!*#\"p!fJ!9WDDp>uY]k2l[+
-joFQ+!<2-\!6F:&!<)$[!<2*\!<)$[!<2*\!<)$[!<2*\!<)$[!;5IU!9O:Yjo>D[jo>DSjoPPF
-!;YaY!9O:RjoPPF!;bgX!:8hJ!;YaW!;5IS!<)$[!;5IU!9O:Yjo>D[jo>DWjo>D\jo>DUjoPPF
-!<)$[!<)$[!.j:sk5YJ\ec1:%s7Y"CKE(rUeYN6-k.LbF~>
-!<E0!johL1eS8juX8i8!X9/I(X8r1"!!*#"!!)u!#QUs-!3?1%X8r7$"ota+!3E7%p8eQ#XK2E'
-X8o?'!<&u!!;rqu!6VAC!<0&"!<&u!!<0&"!<&u!!;W\r!;!8l!;iht!<&u!!;!8l!;`c!!3E7%
-nuMfkqQ'Ysm&U0eq5aProrJ,nrN#u!o;holqlBbtrN#u!qQ'YsrN#u!poFPtXK2EsX8i6OXQchd
-mf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=hSg&M-Og&h?/g&V')!!*#P!!)uO#QWT4!87G,g&V-+"p!B2!8?-,p=]fQg=cP\
-g&Tj\!<(UO!;tRN!6X!q!<1[P!<(UO!<1[P!<(UO!;Y=K!;"nE!;kIM!<(UO!;"nE!;bCO!8?-,
-o%F'DqUtoLm+MF>q:YfKp"BBGrRq5Oo@a0Eqq;#MrRq5OqUtoLrRq5Opt>fMg=cQ%g&M,(g?I>k
-s8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf@bjo>D[joYVGjoG>A!!*#\!!)u[#QX#L!9O:DjoGDC"p!fJ!9WDDp>uY]k2l[+
-joFQ+!<)$[!;u!Z!6XF(!<2*\!<)$[!<2*\!<)$[!;YaW!;#=Q!;kmY!<)$[!;#=Q!;bg[!9WDD
-o&]oPqW7bXm,e9Jq;qYWp#Z5SrT4([oB$#QqrRkYrT4([qW7bXrT4([puVYYk2l[=jo>C4k3;%.
-s8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8juX9/I(X8r1"!!*#"!!)u!!s#F(!<&u&!3?1%X8r.!!!)Mi!!)qu!!)bprrC6D
-!!)u!!!)u!!!*#"!!)u!!!)ks!!)Sk!!)nt!!)u!!!)Vl!!)ks!s#F(!:m2k!;`eq!:m5j!;iks
-!;*>m!<&u!!;!8l!;iht!<&u!!;`bs!<&u"!3H/"r2]u#XK2EtX8i6OXQZbcmf(c:KE(uFec1:%
-rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=hSg&h?/g&V')!!*#P!!)uO!s%'/!<(UT!87G,g&V$(!!)NB!!)rN!!)cIrrC6r
-!!)uO!!)uO!!*#P!!)uO!!)lL!!)TD!!)oM!!)uO!!)WE!!)lL!s%'/!:nhD!;bFJ!:nkC!;kLL
-!;+tF!<(UO!;"nE!;kIM!<(UO!;bCL!<(UP!8@DPr7V5Qg=cQ&g&M,(g?@8js8LaPJcGcDgAca(
-rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf@bjoYVGjoG>A!!*#\!!)u[!s%KG!<)$`!9O:DjoG;@!!)NN!!)rZ!!)cUrrC7)
-!!)u[!!)u[!!*#\!!)u[!!)lX!!)TP!!)oY!!)u[!!)WQ!!)lX!s%KG!:o7P!;bjV!:o:O!;kpX
-!;,CR!<)$[!;#=Q!;kmY!<)$[!;bgX!<)$\!9X7\r8n(]k2l[>jo>C4k31t-s8LRKKE(uFec1:%
-rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8juXSi.sX8i8"X8i8!XSi.tX9AU*X8o=%qlBbtn>lTiqlK_r`2iq=r2]kurN#u!
-ri?)"rN#u!qlBbtr2fbqr2]kuqlBbtrN#u!riGtsr2]kuqlBbtri?)"nuMfkp8e5on>lTiq5aPr
-orJ,nrN#u!o;holqlBbtrN#u!qQ'YsrN-#!ri?)"ri?)"ri?)"qQ'YsJZS%9s6fm:s+C@Op=91q
-s8N;RV#TT>]`<Q~>
-!<E0!johC3g4=hSgAM$Lg&M-Pg&M-OgAM$Mg'%K1g&Th,qq;#MnCdjBqqCuK`7b1kr7V,NrRq5O
-rn7>PrRq5Oqq;#Mr7_#Jr7V,Nqq;#MrRq5Orn@5Lr7V,Nqq;#Mrn7>Po%F'Dp=]KHnCdjBq:YfK
-p"BBGrRq5Oo@a0Eqq;#MrRq5OqUtoLrS%8Orn7>Prn7>Prn7>PqUtoLJ_K;@s8W)Ps+14Mp=fOt
-s8N;WU&X9;\c@6~>
-!<E0!johL1eVf@bk5>;Xjo>D\jo>D[k5>;YjokbIjoFNDqrRkYnE']Nqr[hW`9%%"r8mtZrT4([
-roO1\rT4([qrRkYr9!kVr8mtZqrRkYrT4([roX(Xr8mtZqrRkYroO1\o&]oPp>u>TnE']Nq;qYW
-p#Z5SrT4([oB$#QqrRkYrT4([qW7bXrT=+[roO1\roO1\roO1\qW7bXJ`c.Xs8W)Ks+C@Op=91q
-s8N;RV#TT>]`<Q~>
-!<E0!johL1eS8juX9/I(X8r.!!W];%r2]u#XK2F#X9AU*X8o=%qlBbtn>lTipT+>p`iK.?qlBbt
-rN#u!ri?)"rN#u!r2]kun>lTiqlBbtrN#u!o;holqlBbtri?)"nuMfkp8e5on>lTiq5aProrJ,n
-rN#u!o;holqlBbtrN#u!qlBbtr2]kurN#u!ri?)"ri?)"qlBbtJZS"8s6fm:s+C@Op=91qs8N;R
-V#TT>]`<Q~>
-!<E0!johC3g4=hSg&h?/g&V$(!W^pSr7V5Qg=cQ*g'%K1g&Th,qq;#MnCdjBpY#TI`nCCmqq;#M
-rRq5Orn7>PrRq5Or7V,NnCdjBqq;#MrRq5Oo@a0Eqq;#Mrn7>Po%F'Dp=]KHnCdjBq:YfKp"BBG
-rRq5Oo@a0Eqq;#MrRq5Oqq;#Mr7V,NrRq5Orn7>Prn7>Pqq;#MJ_K8?s8W)Ps+14Mp=fOts8N;W
-U&X9;\c@6~>
-!<E0!johL1eVf@bjoYVGjoG;@!W_?_r8n(]k2l[BjokbIjoFNDqrRkYnE']NpZ;GU`o[7$qrRkY
-rT4([roO1\rT4([r8mtZnE']NqrRkYrT4([oB$#QqrRkYroO1\o&]oPp>u>TnE']Nq;qYWp#Z5S
-rT4([oB$#QqrRkYrT4([qrRkYr8mtZrT4([roO1\roO1\qrRkYJ`c+Ws8W)Ks+C@Op=91qs8N;R
-V#TT>]`<Q~>
-!<E0!johL1eS8juX8i8!X8i8!X9&C'!;rnu!<&u$!3E7%riH,"qlBbtn>lTir2]kurN#u!a/f7@
-qQ'YsrN#u!ri?)"rN#u!rN#u!n#QKhqlBbtrN#u!o;holqlKYpo;holp8e5on>lTiq5aProrJ,n
-rN#u!o;holqlBbtrN#u!qlBbtr2]kurN#u!riGtsrN#u!JZRt7s6fm:s+C@Op=91qs8N;RV#TT>
-]`<Q~>
-!<E0!johC3g4=hSg&M-Og&M-Og&_9.!;tON!<(UR!8?-,rn@APqq;#MnCdjBr7V,NrRq5Oa4^Ln
-qUtoLrRq5Orn7>PrRq5OrRq5On(IaAqq;#MrRq5Oo@a0EqqCoIo@a0Ep=]KHnCdjBq:YfKp"BBG
-rRq5Oo@a0Eqq;#MrRq5Oqq;#Mr7V,NrRq5Orn@5LrRq5OJ_K5>s8W)Ps+14Mp=fOts8N;WU&X9;
-\c@6~>
-!<E0!johL1eVf@bjo>D[jo>D[joPPF!;tsZ!<)$^!9WDDroX4\qrRkYnE']Nr8mtZrT4([a6!@%
-qW7bXrT4([roO1\rT4([rT4([n)aTMqrRkYrT4([oB$#Qqr[bUoB$#Qp>u>TnE']Nq;qYWp#Z5S
-rT4([oB$#QqrRkYrT4([qrRkYr8mtZrT4([roX(XrT4([J`c(Vs8W)Ks+C@Op=91qs8N;RV#TT>
-]`<Q~>
-!<E0!johL1eS8juX8i8!X8i7uX8i7tX8i8!X9/I(X8r7$rrDqt!!)Mi!!)qurrE&"!!)qurrCBH
-!!)u!!!*#"!!)u!!!*#"!!)u!!!*#"!!)u!!!)Vl!!)nt!!)u!!!)Vl!!)bp!!)Sk!!)nt!!)u!
-!!)qurrDtu!!)u!!!*#"!!)u!!!)qurrDtu!!)u!!!)qurrDns!!)nt!!)u!!!)nt!!)nt!!*#"
-!!)ks!!)u!!!)u!!!%SOl)apQrmh%$s8VfCs+C@O#1]OLk2s>WJ,~>
-!<E0!johC3g4=hSg&M-Og&M-Ng&M-Mg&M-Og&h?/g&V-+rrDrM!!)NB!!)rNrrE&P!!)rNrrCC!
-!!)uO!!*#P!!)uO!!*#P!!)uO!!*#P!!)uO!!)WE!!)oM!!)uO!!)WE!!)cI!!)TD!!)oM!!)uO
-!!)rNrrDuN!!)uO!!*#P!!)uO!!)rNrrDuN!!)uO!!)rNrrDoL!!)oM!!)uO!!)oM!!)oM!!*#P
-!!)lL!!)uO!!)uO!!%T(l.Z1;rn@C's8VfHs+14M#25dNk2s5TJ,~>
-!<E0!johL1eVf@bjo>D[jo>DZjo>DYjo>D[joYVGjoGDCrrDrY!!)NN!!)rZrrE&\!!)rZrrCC-
-!!)u[!!*#\!!)u[!!*#\!!)u[!!*#\!!)u[!!)WQ!!)oY!!)u[!!)WQ!!)cU!!)TP!!)oY!!)u[
-!!)rZrrDuZ!!)u[!!*#\!!)u[!!)rZrrDuZ!!)u[!!)rZrrDoX!!)oY!!)u[!!)oY!!)oY!!*#\
-!!)lX!!)u[!!)u[!!%T4l/r$Grmh%$s8VfCs+C@O#1]OLk2s>WJ,~>
-!<E0!jp%X3eS8j#XSMqpX8i7uXSMnsXSr5!X8i8!XS`(jXS`(tX8r=&rW)hsrrCBHqZ-Srr;cbs
-r;cetqZ-;jquHYrr;cJkquHSprW)VmquHYrr;c_rrrDqtr;cbsr;c_rrrDqtr;c_rrrDtuquHYr
-r;c\q!!)ksrW)errW)r!qZ)2Kl)apQrmh%$s8VfCs+C@O#1]OLk2s>WJ,~>
-!<E0!jp%O5g4=h/gA1gIg&M-NgA1dLgAV*Og&M-OgACsCgACsMg&V3-rW)iLrrCC!qZ-TKr;ccL
-r;cfMqZ-<CquHZKr;cKDquHTIrW)WFquHZKr;c`KrrDrMr;ccLr;c`KrrDrMr;c`KrrDuNquHZK
-r;c]J!!)lLrW)fKrW)rOqZ)3$l.Z1;rn@C's8VfHs+14M#25dNk2s5TJ,~>
-!<E0!jp%X3eVf@Jk5#)Ujo>DZk5#&Xk5GA[jo>D[k555Ok555YjoGJErW)iXrrCC-qZ-TWr;ccX
-r;cfYqZ-<OquHZWr;cKPquHTUrW)WRquHZWr;c`WrrDrYr;ccXr;c`WrrDrYr;c`WrrDuZquHZW
-r;c]V!!)lXrW)fWrW)r[qZ)30l/r$Grmh%$s8VfCs+C@O#1]OLk2s>WJ,~>
-!<E0!johL1eS8iMXF[I(XGa1[mf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g4@t/g5F\bs8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k(2ZGk)8C%s8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8iMXF[I(XGa1[mf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g4@t/g5F\bs8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k(2ZGk)8C%s8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8jJXS;dHXF[I(XMV(=mf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=h(g@tZ!g4@t/g;;SDs8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf@7k4eq-k(2ZGk/-9\s8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8iMXF[I(XGa1[mf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g4@t/g5F\bs8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k(2ZGk)8C%s8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8iMXF[I(XGa1[mf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g4@t/g5F\bs8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k(2ZGk)8C%s8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8iMX8o@#!;rqs!;rqs!;rqs!:m2k!;`eq!:m2k!;NYq!:m2k!;`ep!;*Ak!;rqs
-!;!;j!:m2k!;`eq!;`es!;rqs!;rqr!;rnu!.h66XT._fec1:%s7Y"CKE(rUeYN6-k.LbF~>
-!<E0!johC3g4=g+g&Tk*!;tRL!;tRL!;tRL!:nhD!;bFJ!:nhD!;P:J!:nhD!;bFI!;,"D!;tRL
-!;"qC!:nhD!;bFJ!;bFL!;tRL!;tRK!;tON!.ikdgAh3PgAca(s7Y1HJcG`Sg7eQ/k.1PC~>
-!<E0!johL1eVf?:joFQB!;u!X!;u!X!;u!X!:o7P!;bjV!:o7P!;P^V!:o7P!;bjU!;,FP!;u!X
-!;#@O!:o7P!;bjV!;bjX!;u!X!;u!W!;tsZ!.j:pk5YJ\ec1:%s7Y"CKE(rUeYN6-k.LbF~>
-!<E0!jp%X3eS8j#XSMnsXSW"qXSr4rXSr2%X8o?'q>g5jq>gMrrVuu#!6D5A!<&u!!<0&"!<&u!
-!<0&"!<&u!!<0&"!<&u!!;*Am!;iht!<&u!!;*Am!;W\t!3?1lXT&:sX8i7jX8i8!X8i8"X8i8!
-X8i7nX8i8!X8i7mXT&:tX8i8!X8i7uX9&C'!<&u!!<&u!!<&u!!;W_r!.h66XT._fec1:%s7Y"C
-KE(rUeYN6-k.LbF~>
-!<E0!jp%O5g4=h/gA1dLgA:mJgAV*KgAV'Sg&Tj\q>g6Cq>gNKrVuuQ!6Ejo!<(UO!<1[P!<(UO
-!<1[P!<(UO!<1[P!<(UO!;,"F!;kIM!<(UO!;,"F!;Y=M!87GEgA_0Lg&M-Cg&M-Og&M-Pg&M-O
-g&M-Gg&M-Og&M-FgA_0Mg&M-Og&M-Ng&_9.!<(UO!<(UO!<(UO!;Y@K!.ikdgAh3PgAca(s7Y1H
-JcG`Sg7eQ/k.1PC~>
-!<E0!jp%X3eVf@Jk5#&Xk5,/Vk5GAWk5G>_joFQ+q>g6Oq>gNWrVuu]!6F:&!<)$[!<2*\!<)$[
-!<2*\!<)$[!<2*\!<)$[!;,FR!;kmY!<)$[!;,FR!;YaY!9O:Qk5PGXjo>DOjo>D[jo>D\jo>D[
-jo>DSjo>D[jo>DRk5PGYjo>D[jo>DZjoPPF!<)$[!<)$[!<)$[!;YdW!.j:pk5YJ\ec1:%s7Y"C
-KE(rUeYN6-k.LbF~>
-!<E0!jq+?=eS8j#X8o?'!3E7%XK2F#X8i7tX8i7tX8i8"XT&;"X8i8!X8i7oX9em.X8o?'!3E7%
-riH,"aK,@ArN#u!ri?)"rN#u!ri?)"rN#u!ri?)"rN#u!orJ2pX8r.!!!)u!!!)\n!W];%q5aVt
-X8qmo!W];%qQ'Ysm&U0eq5aProrJ,nrN#u!orJ2pX8r.!!!)u!!!)qu!W];%rN#u!rN#u!rN#u!
-qQ'_uX8mgQk,eUNrmh%$s8VfCs+C@O#1]OLk2s>WJ,~>
-!<E0!jq+6?g4=h/g&Tj\!8?-,g=cQ*g&M-Mg&M-Mg&M-PgA_0Pg&M-Og&M-Hg'Ic5g&Tj\!8?-,
-rn@APaP$UorRq5Orn7>PrRq5Orn7>PrRq5Orn7>PrRq5Op"BHIg&V$(!!)uO!!)]G!W^pSq:YlM
-g&Ud!!W^pSqUtoLm+MF>q:YfKp"BBGrRq5Op"BHIg&V$(!!)uO!!)rN!W^pSrRq5OrRq5OrRq5O
-qUtuNg&Q]Xk1]k8rn@C's8VfHs+14M#25dNk2s5TJ,~>
-!<E0!jq+?=eVf@JjoFQ+!9WDDk2l[Bjo>DYjo>DYjo>D\k5PG\jo>D[jo>DTjp;%MjoFQ+!9WDD
-roX4\aQ<I&rT4([roO1\rT4([roO1\rT4([roO1\rT4([p#Z;UjoG;@!!)u[!!)]S!W_?_q;q_Y
-joG&9!W_?_qW7bXm,e9Jq;qYWp#Z5SrT4([p#Z;UjoG;@!!)u[!!)rZ!W_?_rT4([rT4([rT4([
-qW7hZjoBtpk2u^Drmh%$s8VfCs+C@O#1]OLk2s>WJ,~>
-!<E0!jq+?=eS8j#X8o?'!3E7%XK2F#X8i7uX9&C'!<&u!!;rnu!<0&"!<&u!!;<K#!3E7%XK2E'
-X8r4#!!)qurrC3C!!*#"!!)u!!!*#"!!)u!!!)hr!!)Vl!!)nt!!)u!!!)Vl!!)ks!s#F(!:m2k
-!;`bs!:6ce!;W\r!;3Dn!<&u!!;!8l!;iht!<&u!!<&u$!3E7%rN#u!rN#u!rN#u!poFGqJZS"8
-s6fm:s+C@Op=91qs8N;RV#TT>]`<Q~>
-!<E0!jq+6?g4=h/g&Tj\!8?-,g=cQ*g&M-Ng&_9.!<(UO!;tON!<1[P!<(UO!;>+Q!8?-,g=cP\
-g&V**!!)rNrrC3q!!*#P!!)uO!!*#P!!)uO!!)iK!!)WE!!)oM!!)uO!!)WE!!)lL!s%'/!:nhD
-!;bCL!:8D>!;Y=K!;5%G!<(UO!;"nE!;kIM!<(UO!<(UR!8?-,rRq5OrRq5OrRq5Opt>]JJ_K8?
-s8W)Ps+14Mp=fOts8N;WU&X9;\c@6~>
-!<E0!jq+?=eVf@JjoFQ+!9WDDk2l[Bjo>DZjoPPF!<)$[!;tsZ!<2*\!<)$[!;>O]!9WDDk2l[+
-joGAB!!)rZrrC4(!!*#\!!)u[!!*#\!!)u[!!)iW!!)WQ!!)oY!!)u[!!)WQ!!)lX!s%KG!:o7P
-!;bgX!:8hJ!;YaW!;5IS!<)$[!;#=Q!;kmY!<)$[!<)$^!9WDDrT4([rT4([rT4([puVPVJ`c+W
-s8W)Ks+C@Op=91qs8N;RV#TT>]`<Q~>
-!<E0!johL1eS8jsX8i7uX8i8!X8i7uX9&C'!<&u!!;NVt!3E7%nZ2]jr2]kupT4ApbH([DrN#u!
-rN#u!ri?)"rN#u!qQ'YsnuMfkqlBbtrN#u!o;holqQ'c!XK2EmX8i7sXSi.iXSr4sXSr4lX8i8!
-X8i7lX8i7tX8i8!X8i8!X9/I(X8r1"r;cbsr;c_r!!%SOk,eUNrmh%$s8VfCs+C@O#1]OLk2s>W
-J,~>
-!<E0!johC3g4=hQg&M-Ng&M-Og&M-Ng&_9.!<(UO!;P7M!8?-,n_*sCr7V,NpY,WIbLuprrRq5O
-rRq5Orn7>PrRq5OqUtoLo%F'Dqq;#MrRq5Oo@a0EqUu#Og=cPtg&M-LgAM$BgAV*LgAV*Eg&M-O
-g&M-Eg&M-Mg&M-Og&M-Og&h?/g&V')r;ccLr;c`K!!%T(k1]k8rn@C's8VfHs+14M#25dNk2s5T
-J,~>
-!<E0!johL1eVf@`jo>DZjo>D[jo>DZjoPPF!<)$[!;P[Y!9WDDn`BfOr8mtZpZDJUbN8d)rT4([
-rT4([roO1\rT4([qW7bXo&]oPqrRkYrT4([oB$#QqW7k[k2l[7jo>DXk5>;Nk5GAXk5GAQjo>D[
-jo>DQjo>DYjo>D[jo>D[joYVGjoG>Ar;ccXr;c`W!!%T4k2u^Drmh%$s8VfCs+C@O#1]OLk2s>W
-J,~>
-!<E0!johL1eS8jsX8i7uX8i8"X8i7uX8i8"X8i8"X8i7qXSi.hX8i7tXSi.;X8i7uX8i8!X8i8"
-X8i8!X8i7tX8i7uXSW"qX8i7tX8i8!X8i8"XSW"qX8i7tX8i8"X8i7kX8i7oX8i7iX8i7rX8i7n
-X8i8!X8i7lX8i7tX8i8!X8i8"X8i8"X8i8!X8i8!X8i7rX8i7uX8i6OXQHVamf(c:KE(uFec1:%
-rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=hQg&M-Ng&M-Pg&M-Ng&M-Pg&M-Pg&M-JgAM$Ag&M-MgAM#ig&M-Ng&M-Og&M-P
-g&M-Og&M-Mg&M-NgA:mJg&M-Mg&M-Og&M-PgA:mJg&M-Mg&M-Pg&M-Dg&M-Hg&M-Bg&M-Kg&M-G
-g&M-Og&M-Eg&M-Mg&M-Og&M-Pg&M-Pg&M-Og&M-Og&M-Kg&M-Ng&M,(g?.,hs8LaPJcGcDgAca(
-rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf@`jo>DZjo>D\jo>DZjo>D\jo>D\jo>DVk5>;Mjo>DYk5>:ujo>DZjo>D[jo>D\
-jo>D[jo>DYjo>DZk5,/Vjo>DYjo>D[jo>D\k5,/Vjo>DYjo>D\jo>DPjo>DTjo>DNjo>DWjo>DS
-jo>D[jo>DQjo>DYjo>D[jo>D\jo>D\jo>D[jo>D[jo>DWjo>DZjo>C4k2th+s8LRKKE(uFec1:%
-rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8jsX8i7uXSi.rXS`(tX8i7qX9/I(X8qdl!!)bp!!($?!!)nt!!)u!!!*#"!!)u!
-!!)qu!!)Mi!!)nt!!)u!!!)Vl!!)nt!!*#"!!)Sk!!)_o!!)Mi!!)hr!!)\n!!)u!!!)Vl!!)nt
-!!)u!!!*#"!!*#"!!)u!!!)u!!!)hr!!)qu!!%SOk,eUNrmh%$s8VfCs+C@O#1]OLk2s>WJ,~>
-!<E0!johC3g4=hQg&M-NgAM$KgACsMg&M-Jg&h?/g&UZs!!)cI!!($m!!)oM!!)uO!!*#P!!)uO
-!!)rN!!)NB!!)oM!!)uO!!)WE!!)oM!!*#P!!)TD!!)`H!!)NB!!)iK!!)]G!!)uO!!)WE!!)oM
-!!)uO!!*#P!!*#P!!)uO!!)uO!!)iK!!)rN!!%T(k1]k8rn@C's8VfHs+14M#25dNk2s5TJ,~>
-!<E0!johL1eVf@`jo>DZk5>;Wk555Yjo>DVjoYVGjoFr6!!)cU!!(%$!!)oY!!)u[!!*#\!!)u[
-!!)rZ!!)NN!!)oY!!)u[!!)WQ!!)oY!!*#\!!)TP!!)`T!!)NN!!)iW!!)]S!!)u[!!)WQ!!)oY
-!!)u[!!*#\!!*#\!!)u[!!)u[!!)iW!!)rZ!!%T4k2u^Drmh%$s8VfCs+C@O#1]OLk2s>WJ,~>
-!<E0!johL1eS8jsX8i7uX8i8"X8i8!X8i7uX9/I(X8r$s!!)u!!!)Vl!!)qu!!)u!!!('@!!)ks
-!!)u!!!*#"!!)u!!!)u!!!)Jh!!)nt!!)u!!!)Vl!!)ntqZ-5h!!)_o!!)Mi!!)hr!!)\n!!)u!
-!!)Vl!!)nt!!)u!!!*#"qZ-Vs!!)u!!!)hr!!)qu!!%SOk,eUNrmh%$s8VfCs+C@O#1]OLk2s>W
-J,~>
-!<E0!johC3g4=hQg&M-Ng&M-Pg&M-Og&M-Ng&h?/g&Up%!!)uO!!)WE!!)rN!!)uO!!('n!!)lL
-!!)uO!!*#P!!)uO!!)uO!!)KA!!)oM!!)uO!!)WE!!)oMqZ-6A!!)`H!!)NB!!)iK!!)]G!!)uO
-!!)WE!!)oM!!)uO!!*#PqZ-WL!!)uO!!)iK!!)rN!!%T(k1]k8rn@C's8VfHs+14M#25dNk2s5T
-J,~>
-!<E0!johL1eVf@`jo>DZjo>D\jo>D[jo>DZjoYVGjoG2=!!)u[!!)WQ!!)rZ!!)u[!!((%!!)lX
-!!)u[!!*#\!!)u[!!)u[!!)KM!!)oY!!)u[!!)WQ!!)oYqZ-6M!!)`T!!)NN!!)iW!!)]S!!)u[
-!!)WQ!!)oY!!)u[!!*#\qZ-WX!!)u[!!)iW!!)rZ!!%T4k2u^Drmh%$s8VfCs+C@O#1]OLk2s>W
-J,~>
-!<E0!johL1eS8jsX8i7uX8i8!X8i8"X8i7uX8i8"X8i8!X8i8"X8i8!X8i7lX8i7uXT&;"X8i7u
-XT&:HX8i8!X8i8"X8i8!X8i8"X8i8!X8i8"X8i8!X8i7lX8i7tX8i8!X8i7lX8i7pX8i7kX8i7t
-X8i8!X8i7uXT&:uX8i8!X8i8"X8i8!X8i7uXT&:uX8i8!X8i7uXT&:sX8i7tX8i8!X8i7sX8i8!
-X8i8!X8i8"X8i8!X8i7uX8i6OXQHVamf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=hQg&M-Ng&M-Og&M-Pg&M-Ng&M-Pg&M-Og&M-Pg&M-Og&M-Eg&M-NgA_0Pg&M-N
-gA_0!g&M-Og&M-Pg&M-Og&M-Pg&M-Og&M-Pg&M-Og&M-Eg&M-Mg&M-Og&M-Eg&M-Ig&M-Dg&M-M
-g&M-Og&M-NgA_0Ng&M-Og&M-Pg&M-Og&M-NgA_0Ng&M-Og&M-NgA_0Lg&M-Mg&M-Og&M-Lg&M-O
-g&M-Og&M-Pg&M-Og&M-Ng&M,(g?.,hs8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf@`jo>DZjo>D[jo>D\jo>DZjo>D\jo>D[jo>D\jo>D[jo>DQjo>DZk5PG\jo>DZ
-k5PG-jo>D[jo>D\jo>D[jo>D\jo>D[jo>D\jo>D[jo>DQjo>DYjo>D[jo>DQjo>DUjo>DPjo>DY
-jo>D[jo>DZk5PGZjo>D[jo>D\jo>D[jo>DZk5PGZjo>D[jo>DZk5PGXjo>DYjo>D[jo>DXjo>D[
-jo>D[jo>D\jo>D[jo>DZjo>C4k2th+s8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8juXS`(uXSr4uX8r=&r;Zi!r;chur;chuq>g2iquH_t!<B5#!;ikt!7.bD!<'"t
-!;rqs!<'"r!;3Gk!;rqs!;*Aj!;`er!;3Gk!;rqs!;ikt!;ikr!;rqs!;ikt!;ikr!;ikt!;rqr
-!;rqs!;`er!<'"t!;rqs!<'"s!.h68XT._fec1:%s7Y"CKE(rUeYN6-k.LbF~>
-!<E0!johC3g4=hSgACsNgAV*Ng&V3-r;ZiOr;ciNr;ciNq>g3BquH`M!<CjQ!;kLM!70Br!<(XM
-!;tRL!<(XK!;5(D!;tRL!;,"C!;bFK!;5(D!;tRL!;kLM!;kLK!;tRL!;kLM!;kLK!;kLM!;tRK
-!;tRL!;bFK!<(XM!;tRL!<(XL!.ikfgAh3PgAca(s7Y1HJcG`Sg7eQ/k.1PC~>
-!<E0!johL1eVf@bk555Zk5GAZjoGJEr;Zi[r;ciZr;ciZq>g3NquH`Y!<D9]!;kpY!70g)!<)'Y
-!;u!X!<)'W!;5LP!;u!X!;,FO!;bjW!;5LP!;u!X!;kpY!;kpW!;u!X!;kpY!;kpW!;kpY!;u!W
-!;u!X!;bjW!<)'Y!;u!X!<)'X!.j:rk5YJ\ec1:%s7Y"CKE(rUeYN6-k.LbF~>
-!<E0!johL1eS8iMXF[I(XGa1[mf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g4@t/g5F\bs8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k(2ZGk)8C%s8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8iMXF[I(XGa1[mf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g4@t/g5F\bs8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k(2ZGk)8C%s8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8jJXS;dHXF[I(XMV(=mf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=h(g@tZ!g4@t/g;;SDs8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf@7k4eq-k(2ZGk/-9\s8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8iMXF[I(XGa1[mf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g4@t/g5F\bs8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k(2ZGk)8C%s8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8iMXF[I(XGa1[mf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g4@t/g5F\bs8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k(2ZGk)8C%s8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8iMXF[I(XGa1[mf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g4@t/g5F\bs8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k(2ZGk)8C%s8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8jtXSr2#X8r7$r;churW)u"rW)u"q>gPsq>^MsrW)u"rW)u"q>gMrrVuu#!.h5&
-XF[J$XT._fec1:%s7Y"CKE(rUeYN6-k.LbF~>
-!<E0!johC3g4=hRgAV'Qg&V-+r;ciNrW)uPrW)uPq>gQLq>^NLrW)uPrW)uPq>gNKrVuuQ!.ijT
-g4@u+gAh3PgAca(s7Y1HJcG`Sg7eQ/k.1PC~>
-!<E0!johL1eVf@ak5G>]joGDCr;ciZrW)u\rW)u\q>gQXq>^NXrW)u\rW)u\q>gNWrVuu]!.j9`
-k(2[Ck5YJ\ec1:%s7Y"CKE(rUeYN6-k.LbF~>
-!<E0!johL1eS8juX8i8"XT&;#X8i8!X8i8"XT&;"X8i8"X9J[+X8o?'!<0&"!<&u%!3E7%!<0&"
-!<0&+!3E7%XK2E'X8r7$rr@VOJZOF(d]EK:rmh%$s8VfCs+C@O#1]OLk2s>WJ,~>
-!<E0!johC3g4=hSg&M-PgA_0Qg&M-Og&M-PgA_0Pg&M-Pg'.Q2g&Tj\!<1[P!<(US!8?-,!<1[P
-!<1[Y!8?-,g=cP\g&V-+rr@W(J_G\/db=a$rn@C's8VfHs+14M#25dNk2s5TJ,~>
-!<E0!johL1eVf@bjo>D\k5PG]jo>D[jo>D\k5PG\jo>D\jothJjoFQ+!<2*\!<)$_!9WDD!<2*\
-!<2*e!9WDDk2l[+joGDCrr@W4J`_OGdcUT0rmh%$s8VfCs+C@O#1]OLk2s>WJ,~>
-!<E0!jp.^4eS8j#X8r1"!W];%qlC&'XK2E'!3E7%ri?;(XK2E'X8r7$!!)u!#QUs-!3?1%X8r7$
-#lq'.!3E7%XK2F#X8i7uXT&9OXF[I(XP']Tmf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!jp.U6g4=h/g&V')!W^pSqq;;Ug=cP\!8?-,rn7PVg=cP\g&V-+!!)uO#QWT4!87G,g&V-+
-#lr]5!8?-,g=cQ*g&M-NgA_/(g4@t/g=b3[s8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!jp.^4eVf@JjoG>A!W_?_qrS.ak2l[+!9WDDroOCbk2l[+joGDC!!)u[#QX#L!9O:DjoGDC
-#ls,M!9WDDk2l[Bjo>DZk5PF4k(2ZGk1Snss8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!jp.^4eS8j#X8r*u!!)nt#QUs-!3?1%X8r.!!!)nt!s#F(!<&u&!3?1%X8r.!!!)qu!!)bp
-rr@VOJZOF(frY5Armh%$s8VfCs+C@O#1]OLk2s>WJ,~>
-!<E0!jp.U6g4=h/g&V!'!!)oM#QWT4!87G,g&V$(!!)oM!s%'/!<(UT!87G,g&V$(!!)rN!!)cI
-rr@W(J_G\/g"QK+rn@C's8VfHs+14M#25dNk2s5TJ,~>
-!<E0!jp.^4eVf@JjoG8?!!)oY#QX#L!9O:DjoG;@!!)oY!s%KG!<)$`!9O:DjoG;@!!)rZ!!)cU
-rr@W4J`_OGg#i>7rmh%$s8VfCs+C@O#1]OLk2s>WJ,~>
-!<E0!jp.^4eS8j#X8r*u!!)nt#QUs-!3E7%X8r.!!!)ntr;cet"TYX*!3?1tX8i7tXSi-MXF[I(
-XO4-Lmf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!jp.U6g4=h/g&V!'!!)oM#QWT4!8?-,g&V$(!!)oMr;cfM"T[91!87GMg&M-MgAM#&g4@t/
-g<nXSs8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!jp.^4eVf@JjoG8?!!)oY#QX#L!9WDDjoG;@!!)oYr;cfY"T[]I!9O:Yjo>DYk5>:2k(2ZG
-k0`>ks8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!jp.^4eS8j#X8r*u!!)nt#QUs-!3E7%X8r.!!!)nt!s#F(!<&u&!3E7%X8r.!!!)bp!!%SO
-JZOF(d]EK:rmh%$s8VfCs+C@O#1]OLk2s>WJ,~>
-!<E0!jp.U6g4=h/g&V!'!!)oM#QWT4!8?-,g&V$(!!)oM!s%'/!<(UT!8?-,g&V$(!!)cI!!%T(
-J_G\/db=a$rn@C's8VfHs+14M#25dNk2s5TJ,~>
-!<E0!jp.^4eVf@JjoG8?!!)oY#QX#L!9WDDjoG;@!!)oY!s%KG!<)$`!9WDDjoG;@!!)cU!!%T4
-J`_OGdcUT0rmh%$s8VfCs+C@O#1]OLk2s>WJ,~>
-!<E0!jp.^4eS8j#X8r*u!!)nt!s#F(!<0)"!;iht!;iht!<&u$!3E7%riH,"qlBbtr2]kurN#u!
-JZOF(JZR;$s6fm:s+C@Op=91qs8N;RV#TT>]`<Q~>
-!<E0!jp.U6g4=h/g&V!'!!)oM!s%'/!<1^P!;kIM!;kIM!<(UR!8?-,rn@APqq;#Mr7V,NrRq5O
-J_G\/J_JQ+s8W)Ps+14Mp=fOts8N;WU&X9;\c@6~>
-!<E0!jp.^4eVf@JjoG8?!!)oY!s%KG!<2-\!;kmY!;kmY!<)$^!9WDDroX4\qrRkYr8mtZrT4([
-J`_OGJ`bDCs8W)Ks+C@Op=91qs8N;RV#TT>]`<Q~>
-!<E0!johL1eS8juX8i8!X9/I(X8r4#!!*#"!!*#"rrDqt!!)nt!!)u!!s#F(!<0)"!;iht!;rqu
-!<0&"!;rqu!.h5&XF[J+XT._fec1:%s7Y"CKE(rUeYN6-k.LbF~>
-!<E0!johC3g4=hSg&M-Og&h?/g&V**!!*#P!!*#PrrDrM!!)oM!!)uO!s%'/!<1^P!;kIM!;tRN
-!<1[P!;tRN!.ijTg4@u2gAh3PgAca(s7Y1HJcG`Sg7eQ/k.1PC~>
-!<E0!johL1eVf@bjo>D[joYVGjoGAB!!*#\!!*#\rrDrY!!)oY!!)u[!s%KG!<2-\!;kmY!;u!Z
-!<2*\!;u!Z!.j9`k(2[Jk5YJ\ec1:%s7Y"CKE(rUeYN6-k.LbF~>
-!<E0!johL1eS8jtXSi.tXSi.uXSr5!X8i8!XS`(tXSMnsXSr5!X8i8!XS`(tX8r=&rW)hsrr@VO
-JZOF(frY5Armh%$s8VfCs+C@O#1]OLk2s>WJ,~>
-!<E0!johC3g4=hRgAM$MgAM$NgAV*Og&M-OgACsMgA1dLgAV*Og&M-OgACsMg&V3-rW)iLrr@W(
-J_G\/g"QK+rn@C's8VfHs+14M#25dNk2s5TJ,~>
-!<E0!johL1eVf@ak5>;Yk5>;Zk5GA[jo>D[k555Yk5#&Xk5GA[jo>D[k555YjoGJErW)iXrr@W4
-J`_OGg#i>7rmh%$s8VfCs+C@O#1]OLk2s>WJ,~>
-!<E0!johL1eS8iMXF[I(XGa1[mf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g4@t/g5F\bs8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k(2ZGk)8C%s8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8iMXF[I(XGa1[mf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g4@t/g5F\bs8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k(2ZGk)8C%s8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8iMXF[I(XGa1[mf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g4@t/g5F\bs8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k(2ZGk)8C%s8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8iMXF[I(XGa1[mf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g4@t/g5F\bs8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k(2ZGk)8C%s8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8iMXF[I(XGa1[mf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g4@t/g5F\bs8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k(2ZGk)8C%s8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8iMXF[I(XGa1[mf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g4@t/g5F\bs8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k(2ZGk)8C%s8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8iMXF[I(XGa1[mf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g4@t/g5F\bs8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k(2ZGk)8C%s8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8iMXF[I(XGa1[mf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g4@t/g5F\bs8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k(2ZGk)8C%s8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8iMXF[I(XGa1[mf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g4@t/g5F\bs8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k(2ZGk)8C%s8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8iMXF[I(XGa1[mf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g4@t/g5F\bs8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k(2ZGk)8C%s8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8iMXF[I(XGa1[mf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g4@t/g5F\bs8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k(2ZGk)8C%s8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8iMXF[I(XGa1[mf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g4@t/g5F\bs8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k(2ZGk)8C%s8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8iMXF[I(XGa1[mf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g4@t/g5F\bs8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k(2ZGk)8C%s8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8iMXF[I(XGa1[mf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g4@t/g5F\bs8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k(2ZGk)8C%s8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8iMXF[I(XGa1[mf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g4@t/g5F\bs8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k(2ZGk)8C%s8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8iMXF[I(XGa1[mf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g4@t/g5F\bs8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k(2ZGk)8C%s8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8iMXF[I(XGa1[mf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g4@t/g5F\bs8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k(2ZGk)8C%s8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8iMXF[I(XGa1[mf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g4@t/g5F\bs8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k(2ZGk)8C%s8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8iMXF[I(XGa1[mf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g4@t/g5F\bs8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k(2ZGk)8C%s8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8iMXF[I(XGa1[mf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g4@t/g5F\bs8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k(2ZGk)8C%s8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8j,X8i7gX8i6OXF[I(XR*%gmf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g_g&M-@g&M,(g4@t/g?dPns8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?njo>DLjo>C4k(2ZGk3V71s8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!joqR2eS8j#qZ,o_rW(QOrrDMh!!%SOJZOF(l`C-Srmh%$s8VfCs+C@O#1]OLk2s>WJ,~>
-!<E0!joqI4g4=h/qZ,p8rW(R(rrDNA!!%T(J_G\/le;C=rn@C's8VfHs+14M#25dNk2s5TJ,~>
-!<E0!joqR2eVf@JqZ,pDrW(R4rrDNM!!%T4J`_OGlfS6Irmh%$s8VfCs+C@O#1]OLk2s>WJ,~>
-!<E0!jp.^4eS8j#X8r4#!!)8b!!(ZQ!W];%n#QKhJZOF(JZS1=s6fm:s+C@Op=91qs8N;RV#TT>
-]`<Q~>
-!<E0!jp.U6g4=h/g&V**!!)9;!!([*!W^pSn(IaAJ_G\/J_KGDs8W)Ps+14Mp=fOts8N;WU&X9;
-\c@6~>
-!<E0!jp.^4eVf@JjoGAB!!)9G!!([6!W_?_n)aTMJ`_OGJ`c:\s8W)Ks+C@Op=91qs8N;RV#TT>
-]`<Q~>
-!<E0!jp.^4eS8j#X8r4#!!)qurW)r!rr<&#rW)er!!)u!rW)u"rW(rZ!!)Jh!!%SOJZOF(l`C-S
-rmh%$s8VfCs+C@O#1]OLk2s>WJ,~>
-!<E0!jp.U6g4=h/g&V**!!)rNrW)rOrr<&QrW)fK!!)uOrW)uPrW(s3!!)KA!!%T(J_G\/le;C=
-rn@C's8VfHs+14M#25dNk2s5TJ,~>
-!<E0!jp.^4eVf@JjoGAB!!)rZrW)r[rr<&]rW)fW!!)u[rW)u\rW(s?!!)KM!!%T4J`_OGlfS6I
-rmh%$s8VfCs+C@O#1]OLk2s>WJ,~>
-!<E0!jp.^4eS8j#X8r4#!!)u!!!*#"!!*#"rrE&"!!)nt!!)qu!!)u!!!)\nq>g/h!!)Jh!!%SO
-JZOF(l`C-Srmh%$s8VfCs+C@O#1]OLk2s>WJ,~>
-!<E0!jp.U6g4=h/g&V**!!)uO!!*#P!!*#PrrE&P!!)oM!!)rN!!)uO!!)]Gq>g0A!!)KA!!%T(
-J_G\/le;C=rn@C's8VfHs+14M#25dNk2s5TJ,~>
-!<E0!jp.^4eVf@JjoGAB!!)u[!!*#\!!*#\rrE&\!!)oY!!)rZ!!)u[!!)]Sq>g0M!!)KM!!%T4
-J`_OGlfS6Irmh%$s8VfCs+C@O#1]OLk2s>WJ,~>
-!<E0!jp.^4eS8j#X8r7$!!)u!!!)qu!s#F(!;rnu!;rnu!;rnu!<&u!!9(!Z!:[&i!.h5&XF[J<
-XT._fec1:%s7Y"CKE(rUeYN6-k.LbF~>
-!<E0!jp.U6g4=h/g&V-+!!)uO!!)rN!s%'/!;tON!;tON!;tON!<(UO!9)W3!:\\B!.ijTg4@uC
-gAh3PgAca(s7Y1HJcG`Sg7eQ/k.1PC~>
-!<E0!jp.^4eVf@JjoGDC!!)u[!!)rZ!s%KG!;tsZ!;tsZ!;tsZ!<)$[!9*&?!:]+N!.j9`k(2[[
-k5YJ\ec1:%s7Y"CKE(rUeYN6-k.LbF~>
-!<E0!jp%X3eS8j#XSi.sXSMqsX8i7uX8i7uX8i7tX9/I(X8qmoq>g/h!!)Jh!!%SOJZOF(l`C-S
-rmh%$s8VfCs+C@O#1]OLk2s>WJ,~>
-!<E0!jp%O5g4=h/gAM$LgA1gLg&M-Ng&M-Ng&M-Mg&h?/g&Ud!q>g0A!!)KA!!%T(J_G\/le;C=
-rn@C's8VfHs+14M#25dNk2s5TJ,~>
-!<E0!jp%X3eVf@Jk5>;Xk5#)Xjo>DZjo>DZjo>DYjoYVGjoG&9q>g0M!!)KM!!%T4J`_OGlfS6I
-rmh%$s8VfCs+C@O#1]OLk2s>WJ,~>
-!<E0!jp.^4eS8j#X8r7$!!)u!!!)hr!!)qu!!)qu!!)nt!s#F(!8spY!:Quh!.h5&XF[J=XT._f
-ec1:%s7Y"CKE(rUeYN6-k.LbF~>
-!<E0!jp.U6g4=h/g&V-+!!)uO!!)iK!!)rN!!)rN!!)oM!s%'/!8uQ2!:SVA!.ijTg4@uDgAh3P
-gAca(s7Y1HJcG`Sg7eQ/k.1PC~>
-!<E0!jp.^4eVf@JjoGDC!!)u[!!)iW!!)rZ!!)rZ!!)oY!s%KG!8uu>!:T%M!.j9`k(2[\k5YJ\
-ec1:%s7Y"CKE(rUeYN6-k.LbF~>
-!<E0!jp.^4eS8j#X8r4#!!)u!!!)u!"9>O)!!*#"!!)nt!!)ksrrCrX!!)Jh!!%SOJZOF(l`C-S
-rmh%$s8VfCs+C@O#1]OLk2s>WJ,~>
-!<E0!jp.U6g4=h/g&V**!!)uO!!)uO"9@00!!*#P!!)oM!!)lLrrCs1!!)KA!!%T(J_G\/le;C=
-rn@C's8VfHs+14M#25dNk2s5TJ,~>
-!<E0!jp.^4eVf@JjoGAB!!)u[!!)u["9@TH!!*#\!!)oY!!)lXrrCs=!!)KM!!%T4J`_OGlfS6I
-rmh%$s8VfCs+C@O#1]OLk2s>WJ,~>
-!<E0!joqR2eS8j#rW)nu!!)u!r;chu!<B5#!;rqr!;iht!9($W!:d,j!.h5&XF[J=XT._fec1:%
-s7Y"CKE(rUeYN6-k.LbF~>
-!<E0!joqI4g4=h/rW)oN!!)uOr;ciN!<CjQ!;tRK!;kIM!9)Z0!:ebC!.ijTg4@uDgAh3PgAca(
-s7Y1HJcG`Sg7eQ/k.1PC~>
-!<E0!joqR2eVf@JrW)oZ!!)u[r;ciZ!<D9]!;u!W!;kmY!9*)<!:f1O!.j9`k(2[\k5YJ\ec1:%
-s7Y"CKE(rUeYN6-k.LbF~>
-!<E0!johL1eS8jdX8i7gX8i7DX8i6OXF[I(XQutfmf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=hBg&M-@g&M,rg&M,(g4@t/g?[Jms8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf@Qjo>DLjo>D)jo>C4k(2ZGk3M10s8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8jdX8i7gX8i7CX8i6OXF[I(XR*%gmf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=hBg&M-@g&M,qg&M,(g4@t/g?dPns8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf@Qjo>DLjo>D(jo>C4k(2ZGk3V71s8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8jeXSi.iXSi-MXF[I(XL5/0mf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=hCgAM$BgAM#&g4@t/g9oZ7s8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf@Rk5>;Nk5>:2k(2ZGk-a@Os8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8iMXF[I(XGa1[mf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g4@t/g5F\bs8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k(2ZGk)8C%s8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8iMXF[I(XGa1[mf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g4@t/g5F\bs8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k(2ZGk)8C%s8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8iMXN.CB!.h5&XN%@Amf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g;hnI!.ijTg;_kHs8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k/ZTa!.j9`k/QQ`s8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8j,XSr2#X8qUg!!)2`!!(0C!!%SOJZQhls6fm:s+C@Op=91qs8N;RV#TT>]`<Q~>
-!<E0!johC3g4=g_gAV'Qg&UKn!!)39!!(0q!!%T(J_J)ss8W)Ps+14Mp=fOts8N;WU&X9;\c@6~>
-!<E0!johL1eVf?nk5G>]joFc1!!)3E!!(1(!!%T4J`ar6s8W)Ks+C@Op=91qs8N;RV#TT>]`<Q~>
-!<E0!johL1eS8j-X8i8"XT&:eX8i7`X8i7CX8i6OXF[IlXT._fec1:%s7Y"CKE(rUeYN6-k.LbF~>
-!<E0!johC3g4=g`g&M-PgA_0>g&M-9g&M,qg&M,(g4@tsgAh3PgAca(s7Y1HJcG`Sg7eQ/k.1PC~>
-!<E0!johL1eVf?ojo>D\k5PGJjo>DEjo>D(jo>C4k(2[6k5YJ\ec1:%s7Y"CKE(rUeYN6-k.LbF~>
-!<E0!johL1eS8j.X8i7uX8i8"XSi.uXT&8#XSr4uXS`(qXSr4uXSr2"XSr5"XS`(CX8i6OXF[Il
-XT._fec1:%s7Y"CKE(rUeYN6-k.LbF~>
-!<E0!johC3g4=gag&M-Ng&M-PgAM$NgA_-QgAV*NgACsJgAV*NgAV'PgAV*PgACrqg&M,(g4@ts
-gAh3PgAca(s7Y1HJcG`Sg7eQ/k.1PC~>
-!<E0!johL1eVf?pjo>DZjo>D\k5>;Zk5PD]k5GAZk555Vk5GAZk5G>\k5GA\k555(jo>C4k(2[6
-k5YJ\ec1:%s7Y"CKE(rUeYN6-k.LbF~>
-!<E0!johL1eS8j.X8i7rX8i8!X8i8"XT&;"X8i8!X8i7rX8i8"X8i8!X8i8"X8i8!X8i7jXSMqU
-X8i6OXF[IlXT._fec1:%s7Y"CKE(rUeYN6-k.LbF~>
-!<E0!johC3g4=gag&M-Kg&M-Og&M-PgA_0Pg&M-Og&M-Kg&M-Pg&M-Og&M-Pg&M-Og&M-CgA1g.
-g&M,(g4@tsgAh3PgAca(s7Y1HJcG`Sg7eQ/k.1PC~>
-!<E0!johL1eVf?pjo>DWjo>D[jo>D\k5PG\jo>D[jo>DWjo>D\jo>D[jo>D\jo>D[jo>DOk5#):
-jo>C4k(2[6k5YJ\ec1:%s7Y"CKE(rUeYN6-k.LbF~>
-!<E0!johL1eS8j.X8i7sX8i7tX9/I(X8r4#!!)u!!!)ks!!)qu!!)u!!W];%r2]kuhlQ\To;hol
-JZOF(`2s",rmh%$s8VfCs+C@O#1]OLk2s>WJ,~>
-!<E0!johC3g4=gag&M-Lg&M-Mg&h?/g&V**!!)uO!!)lL!!)rN!!)uO!W^pSr7V,NhqIr-o@a0E
-J_G\/`7k7krn@C's8VfHs+14M#25dNk2s5TJ,~>
-!<E0!johL1eVf?pjo>DXjo>DYjoYVGjoGAB!!)u[!!)lX!!)rZ!!)u[!W_?_r8mtZhrae9oB$#Q
-J`_OG`9.+"rmh%$s8VfCs+C@O#1]OLk2s>WJ,~>
-!<E0!johL1eS8j.X8i7sX8i7tX9/I(X8r4#!!)u!!!)ksq>gGp!!)nt!!)Pjq>fKU!!%SOJZQhl
-s6fm:s+C@Op=91qs8N;RV#TT>]`<Q~>
-!<E0!johC3g4=gag&M-Lg&M-Mg&h?/g&V**!!)uO!!)lLq>gHI!!)oM!!)QCq>fL.!!%T(J_J)s
-s8W)Ps+14Mp=fOts8N;WU&X9;\c@6~>
-!<E0!johL1eVf?pjo>DXjo>DYjoYVGjoGAB!!)u[!!)lXq>gHU!!)oY!!)QOq>fL:!!%T4J`ar6
-s8W)Ks+C@Op=91qs8N;RV#TT>]`<Q~>
-!<E0!johL1eS8j.X8i7sX8i7tX9/I(X8r4#!!)u!!!)ks!!)bp!W];%r2]kub,bRCJZOF(`N9+-
-rmh%$s8VfCs+C@O#1]OLk2s>WJ,~>
-!<E0!johC3g4=gag&M-Lg&M-Mg&h?/g&V**!!)uO!!)lL!!)cI!W^pSr7V,Nb1ZgqJ_G\/`S1@l
-rn@C's8VfHs+14M#25dNk2s5TJ,~>
-!<E0!johL1eVf?pjo>DXjo>DYjoYVGjoGAB!!)u[!!)lX!!)cU!W_?_r8mtZb2r[(J`_OG`TI4#
-rmh%$s8VfCs+C@O#1]OLk2s>WJ,~>
-!<E0!johL1eS8j-X8i8!X9/I(X8r4#!!*#"!!)u!!!)u!!!*#"!!)u!!!)u!!!*#"!!*#"!!)u!
-!!*#"!!(<G!!%SOJZQhls6fm:s+C@Op=91qs8N;RV#TT>]`<Q~>
-!<E0!johC3g4=g`g&M-Og&h?/g&V**!!*#P!!)uO!!)uO!!*#P!!)uO!!)uO!!*#P!!*#P!!)uO
-!!*#P!!(<u!!%T(J_J)ss8W)Ps+14Mp=fOts8N;WU&X9;\c@6~>
-!<E0!johL1eVf?ojo>D[joYVGjoGAB!!*#\!!)u[!!)u[!!*#\!!)u[!!)u[!!*#\!!*#\!!)u[
-!!*#\!!(=,!!%T4J`ar6s8W)Ks+C@Op=91qs8N;RV#TT>]`<Q~>
-!<E0!johL1eS8j,XSi.tXSi.uXSr5"XSr4uXSr4sXSi.uXSr2"XSr4uXSr4EX8i6OXF[IlXT._f
-ec1:%s7Y"CKE(rUeYN6-k.LbF~>
-!<E0!johC3g4=g_gAM$MgAM$NgAV*PgAV*NgAV*LgAM$NgAV'PgAV*NgAV)sg&M,(g4@tsgAh3P
-gAca(s7Y1HJcG`Sg7eQ/k.1PC~>
-!<E0!johL1eVf?nk5>;Yk5>;Zk5GA\k5GAZk5GAXk5>;Zk5G>\k5GAZk5GA*jo>C4k(2[6k5YJ\
-ec1:%s7Y"CKE(rUeYN6-k.LbF~>
-!<E0!johL1eS8iMXN7IC!.h5&XMq:@mf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g;qtJ!.ijTg;VeGs8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k/cZb!.j9`k/HK_s8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8iMXN.CB!.h5&XN%@Amf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g;hnI!.ijTg;_kHs8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k/ZTa!.j9`k/QQ`s8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8iMXF[I(XGa1[mf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g4@t/g5F\bs8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k(2ZGk)8C%s8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8iMXF[I(XGa1[mf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g4@t/g5F\bs8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k(2ZGk)8C%s8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8iMXF[I(XGa1[mf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g4@t/g5F\bs8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k(2ZGk)8C%s8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8iMXN7IC!91*[!/[cW!.h6/XT._fec1:%s7Y"CKE(rUeYN6-k.LbF~>
-!<E0!johC3g4=g+g;qtJ!92`4!/]D0!.ik]gAh3PgAca(s7Y1HJcG`Sg7eQ/k.1PC~>
-!<E0!johL1eVf?:k/cZb!93/@!/]h<!.j:ik5YJ\ec1:%s7Y"CKE(rUeYN6-k.LbF~>
-!<E0!johL1eS8iMXR<1h!!0/$i2cnYkcFa`"KVU)X8nin!!)Gg!!%SOhQ6bFrmh%$s8VfCs+C@O
-#1]OLk2s>WJ,~>
-!<E0!johC3g4=g+g@!\o!!1dRi7\/2kh?"9"PNk0g&R_u!!)H@!!%T(hV/#0rn@C's8VfHs+14M
-#25dNk2s5TJ,~>
-!<E0!johL1eVf?:k3hC2!!23^i8t">kiVjE"Qf^HjoD"8!!)HL!!%T4hWFk<rmh%$s8VfCs+C@O
-#1]OLk2s>WJ,~>
-!<E0!johL1eS8iMXRE4j!<0)"!6;/@!<0)"!<9,#!1p7l!:Hog!.h6.XT._fec1:%s7Y"CKE(rU
-eYN6-k.LbF~>
-!<E0!johC3g4=g+g@*_q!<1^P!6<dn!<1^P!<:aQ!1qmE!:JP@!.ik\gAh3PgAca(s7Y1HJcG`S
-g7eQ/k.1PC~>
-!<E0!johL1eVf?:k3qF4!<2-\!6=4%!<2-\!<;0]!1r<Q!:JtL!.j:hk5YJ\ec1:%s7Y"CKE(rU
-eYN6-k.LbF~>
-!<E0!johL1eS8iMXRE4j!<&u!!;rqt!<'#!!<9/#!<9/"!<9/"!<0)!!;`er!!0/$rN,turN#u!
-r2^#$XK2E'rW)ktr;churr<&#rW)ktrW!#$!!)u!rW(rZrrE)#rrE#!r;cbsr;cetquH8g!!%SO
-hQ6bFrmh%$s8VfCs+C@O#1]OLk2s>WJ,~>
-!<E0!johC3g4=g+g@*_q!<(UO!;tRM!<(XO!<:dQ!<:dP!<:dP!<1^O!;bFK!!1dRrS%5NrRq5O
-r7V8Rg=cP\rW)lMr;ciNrr<&QrW)lMrW!#R!!)uOrW(s3rrE)QrrE#Or;ccLr;cfMquH9@!!%T(
-hV/#0rn@C's8VfHs+14M#25dNk2s5TJ,~>
-!<E0!johL1eVf?:k3qF4!<)$[!;u!Y!<)'[!<;3]!<;3\!<;3\!<2-[!;bjW!!23^rT=(ZrT4([
-r8n+^k2l[+rW)lYr;ciZrr<&]rW)lYrW!#^!!)u[rW(s?rrE)]rrE#[r;ccXr;cfYquH9L!!%T4
-hWFk<rmh%$s8VfCs+C@O#1]OLk2s>WJ,~>
-!<E0!johL1eS8iMXRE4j!;NVq!<0&"!<&u)!3?1%X8o?'!<&u!!;iht!;iht!<0)"!<0&"!<0&"
-!<0&"!;W_r!<0&"!<0&"!<&u!!<0)"!<0&"!<0&"!<0)"!<&u!!<0&"!;3Gi!;3E!!3?1%X8o?'
-!<&u!!<0&"!<&u!!<&u!!:Hog!.h6.XT._fec1:%s7Y"CKE(rUeYN6-k.LbF~>
-!<E0!johC3g4=g+g@*_q!;P7J!<1[P!<(UW!87G,g&Tj\!<(UO!;kIM!;kIM!<1^P!<1[P!<1[P
-!<1[P!;Y@K!<1[P!<1[P!<(UO!<1^P!<1[P!<1[P!<1^P!<(UO!<1[P!;5(B!;5%O!87G,g&Tj\
-!<(UO!<1[P!<(UO!<(UO!:JP@!.ik\gAh3PgAca(s7Y1HJcG`Sg7eQ/k.1PC~>
-!<E0!johL1eVf?:k3qF4!;P[V!<2*\!<)$c!9O:DjoFQ+!<)$[!;kmY!;kmY!<2-\!<2*\!<2*\
-!<2*\!;YdW!<2*\!<2*\!<)$[!<2-\!<2*\!<2*\!<2-\!<)$[!<2*\!;5LN!;5I[!9O:DjoFQ+
-!<)$[!<2*\!<)$[!<)$[!:JtL!.j:hk5YJ\ec1:%s7Y"CKE(rUeYN6-k.LbF~>
-!<E0!johL1eS8iMXR<1g!<&u!!;rnu!<0)"!;iht!<&u!!;iht!;rnu!;ro#!3E7%r2]u#XK2Et
-X8i8!X8i7rX8i8"X8i8!X9/I(X8r1"!!*#"!!)qu!!)&\rrDtu!!)nt!W];%qlBbtri?)"n#QKh
-JZR\/s6fm:s+C@Op=91qs8N;RV#TT>]`<Q~>
-!<E0!johC3g4=g+g@!\n!<(UO!;tON!<1^P!;kIM!<(UO!;kIM!;tON!;tOQ!8?-,r7V5Qg=cQ&
-g&M-Og&M-Kg&M-Pg&M-Og&h?/g&V')!!*#P!!)rN!!)'5rrDuN!!)oM!W^pSqq;#Mrn7>Pn(IaA
-J_Jr6s8W)Ps+14Mp=fOts8N;WU&X9;\c@6~>
-!<E0!johL1eVf?:k3hC1!<)$[!;tsZ!<2-\!;kmY!<)$[!;kmY!;tsZ!;ts]!9WDDr8n(]k2l[>
-jo>D[jo>DWjo>D\jo>D[joYVGjoG>A!!*#\!!)rZ!!)'ArrDuZ!!)oY!W_?_qrRkYroO1\n)aTM
-J`beNs8W)Ks+C@Op=91qs8N;RV#TT>]`<Q~>
-!<E0!johL1eS8iMXQlke!<0(r!<0&"!;W\u!3E7%qQ'Ysr2]kuq5jDms/Z2#q5aPrrN#u!rN,ns
-ri?)"rN$)$XK2F"X8i8"XSMqjXSMqiX8i7tX8i7tX9&C'!;iht!<0&"!:Hog!.h6.XT._fec1:%
-s7Y"CKE(rUeYN6-k.LbF~>
-!<E0!johC3g4=g+g?RAl!<1^K!<1[P!;Y=N!8?-,qUtoLr7V,Nq:bZFs4RGQq:YfKrRq5OrS%/L
-rn7>PrRq>Rg=cQ)g&M-PgA1gCgA1gBg&M-Mg&M-Mg&_9.!;kIM!<1[P!:JP@!.ik\gAh3PgAca(
-s7Y1HJcG`Sg7eQ/k.1PC~>
-!<E0!johL1eVf?:k3D(/!<2-W!<2*\!;YaZ!9WDDqW7bXr8mtZq<%MRs5j:]q;qYWrT4([rT="X
-roO1\rT41^k2l[Ajo>D\k5#)Ok5#)Njo>DYjo>DYjoPPF!;kmY!<2*\!:JtL!.j:hk5YJ\ec1:%
-s7Y"CKE(rUeYN6-k.LbF~>
-!<E0!johL1eS8iMXRE4j!<&u!!<0&"!;NVq!;W\u!3E7%qQ'Ysr2]kuq5aPrq5aPrq5aPrrN#u!
-ri?)"rN#u!ri?)"rN$)$XK2F"X8i8"X8i7VX8i7tX8i7tX9&C'!;iht!<0&"!:Hog!.h6.XT._f
-ec1:%s7Y"CKE(rUeYN6-k.LbF~>
-!<E0!johC3g4=g+g@*_q!<(UO!<1[P!;P7J!;Y=N!8?-,qUtoLr7V,Nq:YfKq:YfKq:YfKrRq5O
-rn7>PrRq5Orn7>PrRq>Rg=cQ)g&M-Pg&M-/g&M-Mg&M-Mg&_9.!;kIM!<1[P!:JP@!.ik\gAh3P
-gAca(s7Y1HJcG`Sg7eQ/k.1PC~>
-!<E0!johL1eVf?:k3qF4!<)$[!<2*\!;P[V!;YaZ!9WDDqW7bXr8mtZq;qYWq;qYWq;qYWrT4([
-roO1\rT4([roO1\rT41^k2l[Ajo>D\jo>D;jo>DYjo>DYjoPPF!;kmY!<2*\!:JtL!.j:hk5YJ\
-ec1:%s7Y"CKE(rUeYN6-k.LbF~>
-!<E0!johL1eS8iMXRE7j!<0&"!<&u!!<&u!!<0&"!;NYq!;W\r!;iht!<&u!!<0&"!<&u!!<0&"
-!<&u$!3E7%rN#u!ri?)"riH,"ri?)"rN#u!ri?)"riH,"rN#u!rN#u!j/`4\qQ'YsrN#u!ri?)"
-rN#u!rN#u!ri?)"nuMfkJZR_0s6fm:s+C@Op=91qs8N;RV#TT>]`<Q~>
-!<E0!johC3g4=g+g@*bq!<1[P!<(UO!<(UO!<1[P!;P:J!;Y=K!;kIM!<(UO!<1[P!<(UO!<1[P
-!<(UR!8?-,rRq5Orn7>Prn@APrn7>PrRq5Orn7>Prn@APrRq5OrRq5Oj4XJ5qUtoLrRq5Orn7>P
-rRq5OrRq5Orn7>Po%F'DJ_Ju7s8W)Ps+14Mp=fOts8N;WU&X9;\c@6~>
-!<E0!johL1eVf?:k3qI4!<2*\!<)$[!<)$[!<2*\!;P^V!;YaW!;kmY!<)$[!<2*\!<)$[!<2*\
-!<)$^!9WDDrT4([roO1\roX4\roO1\rT4([roO1\roX4\rT4([rT4([j5p=AqW7bXrT4([roO1\
-rT4([rT4([roO1\o&]oPJ`bhOs8W)Ks+C@Op=91qs8N;RV#TT>]`<Q~>
-!<E0!johL1eS8iMXRE4k!3H/"qlK_rriH%uqQ0\sqlK\qr2fhsr2fhsr2fhss/c2"s/c2"riH)!
-"0;J&XSr5"XSr5!XSr2#X8r1"r;blZr;c_rr;cbsr;c_rrW)Ji!!%SOhQ6bFrmh%$s8VfCs+C@O
-#1]OLk2s>WJ,~>
-!<E0!johC3g4=g+g@*_r!8@DPqqCuKrn@;NqV(rLqqCrJr7_)Lr7_)Lr7_)Ls4[GPs4[GPrn@>O
-"53_TgAV*PgAV*OgAV'Qg&V')r;bm3r;c`Kr;ccLr;c`KrW)KB!!%T(hV/#0rn@C's8VfHs+14M
-#25dNk2s5TJ,~>
-!<E0!johL1eVf?:k3qF5!9X7\qr[hWroX.ZqW@eXqr[eVr9!qXr9!qXr9!qXs5s:\s5s:\roX1[
-"6KR`k5GA\k5GA[k5G>]joG>Ar;bm?r;c`Wr;ccXr;c`WrW)KN!!%T4hWFk<rmh%$s8VfCs+C@O
-#1]OLk2s>WJ,~>
-!<E0!johL1eS8iMXG<kW!33+#!.h6.XT._fec1:%s7Y"CKE(rUeYN6-k.LbF~>
-!<E0!johC3g4=g+g5"A^!34`Q!.ik\gAh3PgAca(s7Y1HJcG`Sg7eQ/k.1PC~>
-!<E0!johL1eVf?:k(i(!!35/]!.j:hk5YJ\ec1:%s7Y"CKE(rUeYN6-k.LbF~>
-!<E0!johL1eS8iMXGEqX!2ut!!.h6/XT._fec1:%s7Y"CKE(rUeYN6-k.LbF~>
-!<E0!johC3g4=g+g5+G_!3"TO!.ik]gAh3PgAca(s7Y1HJcG`Sg7eQ/k.1PC~>
-!<E0!johL1eVf?:k(r."!3##[!.j:ik5YJ\ec1:%s7Y"CKE(rUeYN6-k.LbF~>
-!<E0!johL1eS8iMXGj7Z!.h5)XT._fec1:%s7Y"CKE(rUeYN6-k.LbF~>
-!<E0!johC3g4=g+g5Oba!.ijWgAh3PgAca(s7Y1HJcG`Sg7eQ/k.1PC~>
-!<E0!johL1eVf?:k)AI$!.j9ck5YJ\ec1:%s7Y"CKE(rUeYN6-k.LbF~>
-!<E0!johL1eS8iMXF[I(XGa1[mf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g4@t/g5F\bs8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k(2ZGk)8C%s8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8iMXF[I(XGa1[mf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g4@t/g5F\bs8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k(2ZGk)8C%s8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8iMXF[GRX8pbO!!%SO]<)&#rmh%$s8VfCs+C@O#1]OLk2s>WJ,~>
-!<E0!johC3g4=g+g4@rYg&TXV!!%T(]A!;brn@C's8VfHs+14M#25dNk2s5TJ,~>
-!<E0!johL1eVf?:k(2XqjoEon!!%T4]B9.nrmh%$s8VfCs+C@O#1]OLk2s>WJ,~>
-!<E0!johL1eS8iMXJW)u!!0/$i2cnYeZ8`NJZQGas6fm:s+C@Op=91qs8N;RV#TT>]`<Q~>
-!<E0!johC3g4=g+g8<U'!!1dRi7\/2e_1!'J_I]hs8W)Ps+14Mp=fOts8N;WU&X9;\c@6~>
-!<E0!johL1eVf?:k,.;?!!23^i8t">e`Hi3J`aQ+s8W)Ks+C@Op=91qs8N;RV#TT>]`<Q~>
-!<E0!johL1eS8iMXJ`-"!<0)"!4/a,!.h5_XT._fec1:%s7Y"CKE(rUeYN6-k.LbF~>
-!<E0!johC3g4=g+g8EX)!<1^P!41AZ!.ik8gAh3PgAca(s7Y1HJcG`Sg7eQ/k.1PC~>
-!<E0!johL1eVf?:k,7>A!<2-\!41ef!.j:Dk5YJ\ec1:%s7Y"CKE(rUeYN6-k.LbF~>
-!<E0!johL1eS8iMXJ`-"!<&u!!;rqt!<'#!!<9/#!<9/"!<9/"!<0)!!;`er!!0/$rN,tur2fer
-nuMfkJZQGas6fm:s+C@Op=91qs8N;RV#TT>]`<Q~>
-!<E0!johC3g4=g+g8EX)!<(UO!;tRM!<(XO!<:dQ!<:dP!<:dP!<1^O!;bFK!!1dRrS%5Nr7_&K
-o%F'DJ_I]hs8W)Ps+14Mp=fOts8N;WU&X9;\c@6~>
-!<E0!johL1eVf?:k,7>A!<)$[!;u!Y!<)'[!<;3]!<;3\!<;3\!<2-[!;bjW!!23^rT=(Zr9!nW
-o&]oPJ`aQ+s8W)Ks+C@Op=91qs8N;RV#TT>]`<Q~>
-!<E0!johL1eS8iMXJ`-"!;NVq!<0&"!<&u)!3?1%X8o?'!<&u!!;iht!;iht!<0)"!<0&"!<0&"
-!<0&"!<&u!!:m2k!.h5_XT._fec1:%s7Y"CKE(rUeYN6-k.LbF~>
-!<E0!johC3g4=g+g8EX)!;P7J!<1[P!<(UW!87G,g&Tj\!<(UO!;kIM!;kIM!<1^P!<1[P!<1[P
-!<1[P!<(UO!:nhD!.ik8gAh3PgAca(s7Y1HJcG`Sg7eQ/k.1PC~>
-!<E0!johL1eVf?:k,7>A!;P[V!<2*\!<)$c!9O:DjoFQ+!<)$[!;kmY!;kmY!<2-\!<2*\!<2*\
-!<2*\!<)$[!:o7P!.j:Dk5YJ\ec1:%s7Y"CKE(rUeYN6-k.LbF~>
-!<E0!johL1eS8iMXJW)t!<&u!!;rnu!<0)"!;iht!<&u!!;iht!;rnu!;ro#!3E7%r2]u#XK2Ei
-X8i6OXLYG4mf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g8<U&!<(UO!;tON!<1^P!;kIM!<(UO!;kIM!;tON!;tOQ!8?-,r7V5Qg=cPp
-g&M,(g:>r;s8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k,.;>!<)$[!;tsZ!<2-\!;kmY!<)$[!;kmY!;tsZ!;ts]!9WDDr8n(]k2l[3
-jo>C4k.0XSs8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8iMXJ2cr!<0(r!<0&"!;W\u!3E7%qQ'Ysr2]kuq5jDmriH%unZ2]jJZQGas6fm:
-s+C@Op=91qs8N;RV#TT>]`<Q~>
-!<E0!johC3g4=g+g7m:$!<1^K!<1[P!;Y=N!8?-,qUtoLr7V,Nq:bZFrn@;Nn_*sCJ_I]hs8W)P
-s+14Mp=fOts8N;WU&X9;\c@6~>
-!<E0!johL1eVf?:k+^u<!<2-W!<2*\!;YaZ!9WDDqW7bXr8mtZq<%MRroX.Zn`BfOJ`aQ+s8W)K
-s+C@Op=91qs8N;RV#TT>]`<Q~>
-!<E0!johL1eS8iMXJ`-"!<&u!!<0&"!;NVq!;W\u!3E7%qQ'Ysr2]kuq5aProW/#mnuMfkJZQGa
-s6fm:s+C@Op=91qs8N;RV#TT>]`<Q~>
-!<E0!johC3g4=g+g8EX)!<(UO!<1[P!;P7J!;Y=N!8?-,qUtoLr7V,Nq:YfKo\'9Fo%F'DJ_I]h
-s8W)Ps+14Mp=fOts8N;WU&X9;\c@6~>
-!<E0!johL1eVf?:k,7>A!<)$[!<2*\!;P[V!;YaZ!9WDDqW7bXr8mtZq;qYWo]?,Ro&]oPJ`aQ+
-s8W)Ks+C@Op=91qs8N;RV#TT>]`<Q~>
-!<E0!johL1eS8iMXJ`0"!<0&"!<&u!!<&u!!<0&"!;NYq!;W\r!;iht!<&u!!<0&"!<&u$!3E7%
-rN#u!nuMfkJZQGas6fm:s+C@Op=91qs8N;RV#TT>]`<Q~>
-!<E0!johC3g4=g+g8E[)!<1[P!<(UO!<(UO!<1[P!;P:J!;Y=K!;kIM!<(UO!<1[P!<(UR!8?-,
-rRq5Oo%F'DJ_I]hs8W)Ps+14Mp=fOts8N;WU&X9;\c@6~>
-!<E0!johL1eVf?:k,7AA!<2*\!<)$[!<)$[!<2*\!;P^V!;YaW!;kmY!<)$[!<2*\!<)$^!9WDD
-rT4([o&]oPJ`aQ+s8W)Ks+C@Op=91qs8N;RV#TT>]`<Q~>
-!<E0!johL1eS8iMXJ`-#!3H/"qlK_rriH%uqQ0\sqlK\qr2fhsr2fhsriH"tnZ2]jJZQGas6fm:
-s+C@Op=91qs8N;RV#TT>]`<Q~>
-!<E0!johC3g4=g+g8EX*!8@DPqqCuKrn@;NqV(rLqqCrJr7_)Lr7_)Lrn@8Mn_*sCJ_I]hs8W)P
-s+14Mp=fOts8N;WU&X9;\c@6~>
-!<E0!johL1eVf?:k,7>B!9X7\qr[hWroX.ZqW@eXqr[eVr9!qXr9!qXroX+Yn`BfOJ`aQ+s8W)K
-s+C@Op=91qs8N;RV#TT>]`<Q~>
-!<E0!johL1eS8iMXF[J%X8i6OXLbM5mf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g4@u,g&M,(g:H#<s8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k(2[Djo>C4k.9^Ts8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8iMXF[J$X8i6OXLkS6mf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g4@u+g&M,(g:Q)=s8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k(2[Cjo>C4k.BdUs8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8iMXF[I(XGa1[mf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g4@t/g5F\bs8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k(2ZGk)8C%s8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8iMXF[I(XGa1[mf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g4@t/g5F\bs8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k(2ZGk)8C%s8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8iMXF[I(XGa1[mf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g4@t/g5F\bs8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k(2ZGk)8C%s8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8iMXF[I^XT&9OXOjQRmf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g4@tegA_/(g=P'Ys8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k(2[(k5PF4k1Abqs8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8iMXF[J2XSr5!XSr4eXS`(oX8i8"XSMqjXSMq*X8i7`XSr4sXSr4]XT._fec1:%
-s7Y"CKE(rUeYN6-k.LbF~>
-!<E0!johC3g4=g+g4@u9gAV*OgAV*>gACsHg&M-PgA1gCgA1fXg&M-9gAV*LgAV*6gAh3PgAca(
-s7Y1HJcG`Sg7eQ/k.1PC~>
-!<E0!johL1eVf?:k(2[Qk5GA[k5GAJk555Tjo>D\k5#)Ok5#(djo>DEk5GAXk5GABk5YJ\ec1:%
-s7Y"CKE(rUeYN6-k.LbF~>
-!<E0!johL1eS8iMXF[J1XT&;"XT&:cX8i7pX8i8"X9J[+X8o?'!;<Ju!3E7%XK2E1X8i7^X8i7r
-X8i7^XT._fec1:%s7Y"CKE(rUeYN6-k.LbF~>
-!<E0!johC3g4=g+g4@u8gA_0PgA_0<g&M-Ig&M-Pg'.Q2g&Tj\!;>+N!8?-,g=cP8g&M-7g&M-K
-g&M-7gAh3PgAca(s7Y1HJcG`Sg7eQ/k.1PC~>
-!<E0!johL1eVf?:k(2[Pk5PG\k5PGHjo>DUjo>D\jothJjoFQ+!;>OZ!9WDDk2lZPjo>DCjo>DW
-jo>DCk5YJ\ec1:%s7Y"CKE(rUeYN6-k.LbF~>
-!<E0!johL1eS8iMXF[J1X9/I(!3H/"riH)!!iuA%rN,tu!NZ;!X8i7tXSr2#X8r7$"ota+!3E7%
-riH%urN$P1XK2E'X8o?'!!'+%!!'+%rW)u"rW(rZrVuu#!<0(u!<0)"!!',"!<'"s!<'#!!<9/#
-!<'"t!;`bs!;W\r!;`er!<'#!!<9/#!;W_rmf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g4@u8g&h?/!8@DPrn@>O!nmVSrS%5N!SRPOg&M-MgAV'Qg&V-+"p!B2!8?-,
-rn@;NrRqe_g=cP\g&Tj\!!(a,!!(a,rW)uPrW(s3rVuuQ!<1^N!<1^P!!(aP!<(XL!<(XO!<:dQ
-!<(XM!;bCL!;Y=K!;bFK!<(XO!<:dQ!;Y@Ks8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k(2[PjoYVG!9X7\roX1[!p0I_rT=(Z!TjC[jo>DYk5G>]joGDC"p!fJ!9WDD
-roX.ZrT4Xkk2l[+joFQ+!!)0D!!)0DrW)u\rW(s?rVuu]!<2-Z!<2-\!!)0\!<)'X!<)'[!<;3]
-!<)'Y!;bgX!;YaW!;bjW!<)'[!<;3]!;YdWs8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8iMXF[J1X9em.!3?1%!3E7%riH,"rN#u!riH,"r2]kur2]kuriH,"qlBbtr2]ku
-rN#u!qlBbtqlC&'X8o?'!3E7%rN#u!orRuiorJ,nriH,"s/Z2#rN#u!riH,"ri?)"rN#u!q5ai%
-X8o?'!3E7%rN#u!qlBbtq5aPrqlBbtri?)"rN$/&X8o?'!;`esmf(c:KE(uFec1:%rs%#Ls5rIW
-!.Y~>
-!<E0!johC3g4=g+g4@u8g'Ic5!87G,!8?-,rn@APrRq5Orn@APr7V,Nr7V,Nrn@APqq;#Mr7V,N
-rRq5Oqq;#Mqq;;Ug&Tj\!8?-,rRq5Op"K6Bp"BBGrn@APs4RGQrRq5Orn@APrn7>PrRq5Oq:Z)S
-g&Tj\!8?-,rRq5Oqq;#Mq:YfKqq;#Mrn7>PrRqDTg&Tj\!;bFLs8LaPJcGcDgAca(rs%2Ns5rIT
-!.Y~>
-!<E0!johL1eVf?:k(2[Pjp;%M!9O:D!9WDDroX4\rT4([roX4\r8mtZr8mtZroX4\qrRkYr8mtZ
-rT4([qrRkYqrS.ajoFQ+!9WDDrT4([p#c)Np#Z5SroX4\s5j:]rT4([roX4\roO1\rT4([q;qq_
-joFQ+!9WDDrT4([qrRkYq;qYWqrRkYroO1\rT47`joFQ+!;bjXs8LRKKE(uFec1:%rs%#Ls5rIW
-!.Y~>
-!<E0!johL1eS8iMXF[J1X9\g-X8o?'!3?1uX8i8"X8i7uX8i7uX8i8!X8i7uX8i7tX8i8!X8i7t
-X8i7uX8i7tXT&:tX8i8!X8i7\X8i7uX9&C'!;ii"!3E7%rN#u!rN#u!q5jSrr2]kuqlBbtr2]ku
-q5aPrr2]kur2]kuriH,"p8n;^rmh%$s8VfCs+C@O#1]OLk2s>WJ,~>
-!<E0!johC3g4=g+g4@u8g'@]4g&Tj\!87GNg&M-Pg&M-Ng&M-Ng&M-Og&M-Ng&M-Mg&M-Og&M-M
-g&M-Ng&M-MgA_0Mg&M-Og&M-5g&M-Ng&_9.!;kIP!8?-,rRq5OrRq5Oq:biKr7V,Nqq;#Mr7V,N
-q:YfKr7V,Nr7V,Nrn@APp=fQHrn@C's8VfHs+14M#25dNk2s5TJ,~>
-!<E0!johL1eVf?:k(2[Pjp1tLjoFQ+!9O:Zjo>D\jo>DZjo>DZjo>D[jo>DZjo>DYjo>D[jo>DY
-jo>DZjo>DYk5PGYjo>D[jo>DAjo>DZjoPPF!;km\!9WDDrT4([rT4([q<%\Wr8mtZqrRkYr8mtZ
-q;qYWr8mtZr8mtZroX4\p?)DTrmh%$s8VfCs+C@O#1]OLk2s>WJ,~>
-!<E0!johL1eS8iMXF[J1X9\g-X8o?'!3?1uX8i8"X8i7oX8i8!X8i7uX8i7tX8i8!X8i7tX8i7u
-X8i7tX8i7rX9/I(X8qmoq>g5j!!)ks!!)nt!s#F(!<&u!!<&u!!;W\r!;iht!;iht!;rnu!;W\r
-!;rqp!<0&"!;3Gnmf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g4@u8g'@]4g&Tj\!87GNg&M-Pg&M-Hg&M-Og&M-Ng&M-Mg&M-Og&M-Mg&M-N
-g&M-Mg&M-Kg&h?/g&Ud!q>g6C!!)lL!!)oM!s%'/!<(UO!<(UO!;Y=K!;kIM!;kIM!;tON!;Y=K
-!;tRI!<1[P!;5(Gs8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k(2[Pjp1tLjoFQ+!9O:Zjo>D\jo>DTjo>D[jo>DZjo>DYjo>D[jo>DYjo>DZ
-jo>DYjo>DWjoYVGjoG&9q>g6O!!)lX!!)oY!s%KG!<)$[!<)$[!;YaW!;kmY!;kmY!;tsZ!;YaW
-!;u!U!<2*\!;5LSs8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8iMXF[J1X8i7uX9&C'!;rnu!<0&"!;<Jo!<&u!!;rnu!;iht!<&u!!;iht!;rnu
-!;iht!;W\u!3E7%iiE+[qQ'YsqlBl"XK2F#X8i8!X8i7rX8i7tX8i7tX8i7uX8i7rX8i7uX8i7q
-X8i7nXT._fec1:%s7Y"CKE(rUeYN6-k.LbF~>
-!<E0!johC3g4=g+g4@u8g&M-Ng&_9.!;tON!<1[P!;>+H!<(UO!;tON!;kIM!<(UO!;kIM!;tON
-!;kIM!;Y=N!8?-,in=A4qUtoLqq;,Pg=cQ*g&M-Og&M-Kg&M-Mg&M-Mg&M-Ng&M-Kg&M-Ng&M-J
-g&M-GgAh3PgAca(s7Y1HJcG`Sg7eQ/k.1PC~>
-!<E0!johL1eVf?:k(2[Pjo>DZjoPPF!;tsZ!<2*\!;>OT!<)$[!;tsZ!;kmY!<)$[!;kmY!;tsZ
-!;kmY!;YaZ!9WDDioU4@qW7bXqrRt\k2l[Bjo>D[jo>DWjo>DYjo>DYjo>DZjo>DWjo>DZjo>DV
-jo>DSk5YJ\ec1:%s7Y"CKE(rUeYN6-k.LbF~>
-!<E0!johL1eS8iMXF[J1X8i7uX9/I(X8r7$rrE#!!!)u!!!)qu!!)qu!!*#"rrDqt!!)qu!!)u!
-!!)nt!!)nt!!)eqrrCuY!!)u!!s#F(!<&u!!<0&"!<&u!!<&u!!<0&"!<&u!!;`bs!<&u!!;iht
-!;W\r!;iht!<&u!!<0&"!;3Gnmf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g4@u8g&M-Ng&h?/g&V-+rrE#O!!)uO!!)rN!!)rN!!*#PrrDrM!!)rN!!)uO
-!!)oM!!)oM!!)fJrrD!2!!)uO!s%'/!<(UO!<1[P!<(UO!<(UO!<1[P!<(UO!;bCL!<(UO!;kIM
-!;Y=K!;kIM!<(UO!<1[P!;5(Gs8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k(2[Pjo>DZjoYVGjoGDCrrE#[!!)u[!!)rZ!!)rZ!!*#\rrDrY!!)rZ!!)u[
-!!)oY!!)oY!!)fVrrD!>!!)u[!s%KG!<)$[!<2*\!<)$[!<)$[!<2*\!<)$[!;bgX!<)$[!;kmY
-!;YaW!;kmY!<)$[!<2*\!;5LSs8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8iMXF[J2XSr5!XSr5"XSr2#X8r1"r;cetquH\srW!#$!!*#"quH\sr;cbsquH_t
-r;cYp!!(oXr;cetr;churW)u"rW)nurW)nur;c_rr;cbsquH\squHYrr;chur;cSns6fm:s+C@O
-p=91qs8N;RV#TT>]`<Q~>
-!<E0!johC3g4=g+g4@u9gAV*OgAV*PgAV'Qg&V')r;cfMquH]LrW!#R!!*#PquH]Lr;ccLquH`M
-r;cZI!!(p1r;cfMr;ciNrW)uPrW)oNrW)oNr;c`Kr;ccLquH]LquHZKr;ciNr;cTGs8W)Ps+14M
-p=fOts8N;WU&X9;\c@6~>
-!<E0!johL1eVf?:k(2[Qk5GA[k5GA\k5G>]joG>Ar;cfYquH]XrW!#^!!*#\quH]Xr;ccXquH`Y
-r;cZU!!(p=r;cfYr;ciZrW)u\rW)oZrW)oZr;c`Wr;ccXquH]XquHZWr;ciZr;cTSs8W)Ks+C@O
-p=91qs8N;RV#TT>]`<Q~>
-!<E0!johL1eS8iMXF[J#X8i76X8i6OXT._fec1:%s7Y"CKE(rUeYN6-k.LbF~>
-!<E0!johC3g4=g+g4@u*g&M,dg&M,(gAh3PgAca(s7Y1HJcG`Sg7eQ/k.1PC~>
-!<E0!johL1eVf?:k(2[Bjo>Cpjo>C4k5YJ\ec1:%s7Y"CKE(rUeYN6-k.LbF~>
-!<E0!johL1eS8iMXF[J$X8i75X8i6OXT._fec1:%s7Y"CKE(rUeYN6-k.LbF~>
-!<E0!johC3g4=g+g4@u+g&M,cg&M,(gAh3PgAca(s7Y1HJcG`Sg7eQ/k.1PC~>
-!<E0!johL1eVf?:k(2[Cjo>Cojo>C4k5YJ\ec1:%s7Y"CKE(rUeYN6-k.LbF~>
-!<E0!johL1eS8iMXF[J(XSi.4XSi-NXT._fec1:%s7Y"CKE(rUeYN6-k.LbF~>
-!<E0!johC3g4=g+g4@u/gAM#bgAM#'gAh3PgAca(s7Y1HJcG`Sg7eQ/k.1PC~>
-!<E0!johL1eVf?:k(2[Gk5>:nk5>:3k5YJ\ec1:%s7Y"CKE(rUeYN6-k.LbF~>
-!<E0!johL1eS8iMXF[I(XGa1[mf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g4@t/g5F\bs8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k(2ZGk)8C%s8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8iMXF[I(XGa1[mf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g4@t/g5F\bs8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k(2ZGk)8C%s8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8iMXJW'!!.h5&XQQ\bmf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g8<R(!.ijTg?72is8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k,.8@!.j9`k3(n,s8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8iMXJMuu!.h5&XQZbcmf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g83L'!.ijTg?@8js8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k,%2?!.j9`k31t-s8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8iMXJMuu!.h5&XQZbcmf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g83L'!.ijTg?@8js8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k,%2?!.j9`k31t-s8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8iMXJMuu!.h5&XQZbcmf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g83L'!.ijTg?@8js8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k,%2?!.j9`k31t-s8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8iMXJMuu!.h5&XQZbcmf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g83L'!.ijTg?@8js8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k,%2?!.j9`k31t-s8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8iMXJDot!.h5&XQchdmf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g8*F&!.ijTg?I>ks8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k+q,>!.j9`k3;%.s8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8iMXJMuu!.h5&XQZbcmf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g83L'!.ijTg?@8js8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k,%2?!.j9`k31t-s8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8iMXJMuu!.h5&XQZbcmf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g83L'!.ijTg?@8js8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k,%2?!.j9`k31t-s8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8iMXJMuu!.h5&XQZbcmf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g83L'!.ijTg?@8js8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k,%2?!.j9`k31t-s8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8iMXJMuu!.h5&XQZbcmf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g83L'!.ijTg?@8js8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k,%2?!.j9`k31t-s8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8iMXJMuu!.h5&XQZbcmf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g83L'!.ijTg?@8js8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k,%2?!.j9`k31t-s8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8iMXJW'!!.h5&XQQ\bmf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g8<R(!.ijTg?72is8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k,.8@!.j9`k3(n,s8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8iMXF[I(XGa1[mf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g4@t/g5F\bs8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k(2ZGk)8C%s8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8iMXF[I(XGa1[mf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g4@t/g5F\bs8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k(2ZGk)8C%s8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8iMXF[I(XGa1[mf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g4@t/g5F\bs8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k(2ZGk)8C%s8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8iMXJW'!!.h5&XQQ\bmf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g8<R(!.ijTg?72is8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k,.8@!.j9`k3(n,s8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8iMXJMuu!.h5&XQZbcmf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g83L'!.ijTg?@8js8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k,%2?!.j9`k31t-s8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8iMXJMuu!.h5&XQZbcmf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g83L'!.ijTg?@8js8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k,%2?!.j9`k31t-s8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8iMXJMuu!.h5&XQZbcmf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g83L'!.ijTg?@8js8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k,%2?!.j9`k31t-s8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8iMXJMuu!.h5&XQZbcmf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g83L'!.ijTg?@8js8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k,%2?!.j9`k31t-s8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8iMXJDot!.h5&XQchdmf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g8*F&!.ijTg?I>ks8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k+q,>!.j9`k3;%.s8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8iMXJMuu!.h5&XQZbcmf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g83L'!.ijTg?@8js8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k,%2?!.j9`k31t-s8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8iMXJMuu!.h5&XQZbcmf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g83L'!.ijTg?@8js8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k,%2?!.j9`k31t-s8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8iMXJMuu!.h5&XQZbcmf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g83L'!.ijTg?@8js8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k,%2?!.j9`k31t-s8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8iMXJMuu!.h5&XQZbcmf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g83L'!.ijTg?@8js8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k,%2?!.j9`k31t-s8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8iMXJMuu!.h5&XQZbcmf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g83L'!.ijTg?@8js8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k,%2?!.j9`k31t-s8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8iMXJW'!!.h5&XQQ\bmf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g8<R(!.ijTg?72is8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k,.8@!.j9`k3(n,s8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8iMXF[I(XGa1[mf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g4@t/g5F\bs8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k(2ZGk)8C%s8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8iMXF[I(XGa1[mf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g4@t/g5F\bs8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k(2ZGk)8C%s8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8iMXF[I(XGa1[mf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g4@t/g5F\bs8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k(2ZGk)8C%s8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8j-X8i6OXF[I(XOjQRmf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g`g&M,(g4@t/g=P'Ys8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?ojo>C4k(2ZGk1Abqs8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8j,X8i6OXF[I(XOsWSmf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g_g&M,(g4@t/g=Y-Zs8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?njo>C4k(2ZGk1Jhrs8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8j,X8i6OXF[I(XOsWSmf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g_g&M,(g4@t/g=Y-Zs8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?njo>C4k(2ZGk1Jhrs8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8j,X8i6OXF[I(XOsWSmf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g_g&M,(g4@t/g=Y-Zs8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?njo>C4k(2ZGk1Jhrs8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8j,X8i6OXF[I(XOsWSmf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g_g&M,(g4@t/g=Y-Zs8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?njo>C4k(2ZGk1Jhrs8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8j+X8i6OXF[I(XP']Tmf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g^g&M,(g4@t/g=b3[s8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?mjo>C4k(2ZGk1Snss8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8j,X8i6OXF[I(XOsWSmf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g_g&M,(g4@t/g=Y-Zs8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?njo>C4k(2ZGk1Jhrs8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8j,X8i6OXF[I(XOsWSmf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g_g&M,(g4@t/g=Y-Zs8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?njo>C4k(2ZGk1Jhrs8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8j,X8i6OXF[I(XOsWSmf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g_g&M,(g4@t/g=Y-Zs8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?njo>C4k(2ZGk1Jhrs8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8j,X8i6OXF[I(XOsWSmf(c:KE(uDKE(rUeYN6-k.LbF~>
-!<E0!johC3g4=g_g&M,(g4@t/g=Y-Zs8LaPJcGcBJcG`Sg7eQ/k.1PC~>
-!<E0!johL1eVf?njo>C4k(2ZGk1Jhrs8LRKKE(uDKE(rUeYN6-k.LbF~>
-!<E0!johL1eS8j,X8i6OXF[I(XOsWSmf(c:K)krCKE(rUeYN6-k.LbF~>
-!<E0!johC3g4=g_g&M,(g4@t/g=Y-Zs8LaPJH5`AJcG`Sg7eQ/k.1PC~>
-!<E0!johL1eVf?njo>C4k(2ZGk1Jhrs8LRKK)krCKE(rUeYN6-k.LbF~>
-!<E0!johL1eS8j-X8i6OXF[I(XOjQRmf(c:KCZ_Urs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g`g&M,(g4@t/g=P'Ys8LaPJb$\Xrs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?ojo>C4k(2ZGk1Abqs8LRKKCZ_Urs%#Ls5rIW!.Y~>
-!<E0!johL1eS8iMXF[I(XGa1[mf(c:KCZ_Urs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g4@t/g5F\bs8LaPJb$\Xrs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k(2ZGk)8C%s8LRKKCZ_Urs%#Ls5rIW!.Y~>
-!<E0!johL1eS8iMXF[I(XGa1[mf(c:KCZ_Urs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g4@t/g5F\bs8LaPJb$\Xrs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k(2ZGk)8C%s8LRKKCZ_Urs%#Ls5rIW!.Y~>
-!<E0!johL1eS8iMXF[I(XGa1[mf(c:KCZ_Urs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g4@t/g5F\bs8LaPJb$\Xrs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k(2ZGk)8C%s8LRKKCZ_Urs%#Ls5rIW!.Y~>
-!<E0!johL1eS8juX8i6OXF[I(XH0I_mf(c:KCZ_Urs%#Ls5rIW!.Y~>
-!<E0!johC3g4=hSg&M,(g4@t/g5jtfs8LaPJb$\Xrs%2Ns5rIT!.Y~>
-!<E0!johL1eVf@bjo>C4k(2ZGk)\[)s8LRKKCZ_Urs%#Ls5rIW!.Y~>
-!<E0!johL1eS8jtX8i6OXF[I(XH9O`mf(c:KCZ_Urs%#Ls5rIW!.Y~>
-!<E0!johC3g4=hRg&M,(g4@t/g5t%gs8LaPJb$\Xrs%2Ns5rIT!.Y~>
-!<E0!johL1eVf@ajo>C4k(2ZGk)ea*s8LRKKCZ_Urs%#Ls5rIW!.Y~>
-!<E0!johL1eS8jtX8i6OXF[I(XH9O`mf(c:KCZ_Urs%#Ls5rIW!.Y~>
-!<E0!johC3g4=hRg&M,(g4@t/g5t%gs8LaPJb$\Xrs%2Ns5rIT!.Y~>
-!<E0!johL1eVf@ajo>C4k(2ZGk)ea*s8LRKKCZ_Urs%#Ls5rIW!.Y~>
-!<E0!johL1eS8jtX8i6OXF[I(XH9O`mf(c:KCZ_Urs%#Ls5rIW!.Y~>
-!<E0!johC3g4=hRg&M,(g4@t/g5t%gs8LaPJb$\Xrs%2Ns5rIT!.Y~>
-!<E0!johL1eVf@ajo>C4k(2ZGk)ea*s8LRKKCZ_Urs%#Ls5rIW!.Y~>
-!<E0!johL1eS8jtX8i6OXF[I(XH9O`mf(c:KCZ_Urs%#Ls5rIW!.Y~>
-!<E0!johC3g4=hRg&M,(g4@t/g5t%gs8LaPJb$\Xrs%2Ns5rIT!.Y~>
-!<E0!johL1eVf@ajo>C4k(2ZGk)ea*s8LRKKCZ_Urs%#Ls5rIW!.Y~>
-!<E0!johL1eS8jsX8i6OXF[I(XHBUamf(c:KCZ_Urs%#Ls5rIW!.Y~>
-!<E0!johC3g4=hQg&M,(g4@t/g6(+hs8LaPJb$\Xrs%2Ns5rIT!.Y~>
-!<E0!johL1eVf@`jo>C4k(2ZGk)ng+s8LRKKCZ_Urs%#Ls5rIW!.Y~>
-!<E0!johL1eS8jtX8i6OXF[I(XH9O`mf(c:KCZ_Urs%#Ls5rIW!.Y~>
-!<E0!johC3g4=hRg&M,(g4@t/g5t%gs8LaPJb$\Xrs%2Ns5rIT!.Y~>
-!<E0!johL1eVf@ajo>C4k(2ZGk)ea*s8LRKKCZ_Urs%#Ls5rIW!.Y~>
-!<E0!johL1eS8jtX8i6OXF[I(XH9O`mf(c:KCZ_Urs%#Ls5rIW!.Y~>
-!<E0!johC3g4=hRg&M,(g4@t/g5t%gs8LaPJb$\Xrs%2Ns5rIT!.Y~>
-!<E0!johL1eVf@ajo>C4k(2ZGk)ea*s8LRKKCZ_Urs%#Ls5rIW!.Y~>
-!<E0!johL1eS8jtX8i6OXF[I(XH9O`mf(c:KCZ_Urs%#Ls5rIW!.Y~>
-!<E0!johC3g4=hRg&M,(g4@t/g5t%gs8LaPJb$\Xrs%2Ns5rIT!.Y~>
-!<E0!johL1eVf@ajo>C4k(2ZGk)ea*s8LRKKCZ_Urs%#Ls5rIW!.Y~>
-!<E0!johL1eS8jtX8i6OXF[I(XH9O`mf(c:KCZ_Urs%#Ls5rIW!.Y~>
-!<E0!johC3g4=hRg&M,(g4@t/g5t%gs8LaPJb$\Xrs%2Ns5rIT!.Y~>
-!<E0!johL1eVf@ajo>C4k(2ZGk)ea*s8LRKKCZ_Urs%#Ls5rIW!.Y~>
-!<E0!johL1eS8jtX8i6OXF[I(XH9O`mf(c:KCZ_Urs%#Ls5rIW!.Y~>
-!<E0!johC3g4=hRg&M,(g4@t/g5t%gs8LaPJb$\Xrs%2Ns5rIT!.Y~>
-!<E0!johL1eVf@ajo>C4k(2ZGk)ea*s8LRKKCZ_Urs%#Ls5rIW!.Y~>
-!<E0!johL1eS8juX8i6OXF[I(XH0I_mf(c:KCJmFeYN6-k.LbF~>
-!<E0!johC3g4=hSg&M,(g4@t/g5jtfs8LaPJai[Dg7eQ/k.1PC~>
-!<E0!johL1eVf@bjo>C4k(2ZGk)\[)s8LRKKCJmFeYN6-k.LbF~>
-!<E0!johL1eS8iMXF[I(XGa1[mf(c:K)iUWrs=>Xs4*qFk2s>WJ,~>
-!<E0!johC3g4=g+g4@t/g5F\bs8LaPJH3RZrs=8Vs4X1Hk2s5TJ,~>
-!<E0!johL1eVf?:k(2ZGk)8C%s8LRKK)iUWrs=>Xs4*qFk2s>WJ,~>
-!<E0!johL1eS8iMXF[I(XGa1[mf(c:K*&ads7k.EK*f6ks4*qFk2s>WJ,~>
-!<E0!johC3g4=g+g4@t/g5F\bs8LaPJHE^gs7k=JJI03ns4X1Hk2s5TJ,~>
-!<E0!johL1eVf?:k(2ZGk)8C%s8LRKK*&ads7k.EK*f6ks4*qFk2s>WJ,~>
-!<E0!johL1eS8iMXF[I(XGa1[mf(c:KE&Xbs7t4FK*f6ks4*qFk2s>WJ,~>
-!<E0!johC3g4=g+g4@t/g5F\bs8LaPJcEUes7tCKJI03ns4X1Hk2s5TJ,~>
-!<E0!johL1eVf?:k(2ZGk)8C%s8LRKKE&Xbs7t4FK*f6ks4*qFk2s>WJ,~>
-!<E0!johL1eS8iMXF[I(XGa1[mf(c:KE&Xbs8(:GKE&Xbrs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g4@t/g5F\bs8LaPJcEUes8(ILJcEUers%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k(2ZGk)8C%s8LRKKE&Xbs8(:GKE&Xbrs%#Ls5rIW!.Y~>
-!<E0!johL1eS8iMXF[I(XGa1[mf(c:KDrRas81@HKE&Xbrs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g4@t/g5F\bs8LaPJc<Ods81OMJcEUers%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k(2ZGk)8C%s8LRKKDrRas81@HKE&Xbrs%#Ls5rIW!.Y~>
-!<E0!johL1eS8iMXF[I(XGa1[mf(c:KDrRas8:FIKDrRars%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g4@t/g5F\bs8LaPJc<Ods8:UNJc<Odrs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k(2ZGk)8C%s8LRKKDrRas8:FIKDrRars%#Ls5rIW!.Y~>
-!<E0!johL1eS8iMXF[I(XGa1[mf(c:KDiL`s8CLJKDrRars%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g4@t/g5F\bs8LaPJc3Ics8C[OJc<Odrs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k(2ZGk)8C%s8LRKKDiL`s8CLJKDrRars%#Ls5rIW!.Y~>
-!<E0!johL1eS8iMXF[I(XGa1[mf(c:KDiL`s8LRKKDiL`rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g4@t/g5F\bs8LaPJc3Ics8LaPJc3Icrs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k(2ZGk)8C%s8LRKKDiL`s8LRKKDiL`rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8iMXF[I(XGa1[mf(c:KD`F_s8UXLKDiL`rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g4@t/g5F\bs8LaPJc*Cbs8UgQJc3Icrs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k(2ZGk)8C%s8LRKKD`F_s8UXLKDiL`rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8iMXF[I(XGa1[mf(c:KD`F_rrU`'KD`F_rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g4@t/g5F\bs8LaPJc*CbrrUo*Jc*Cbrs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k(2ZGk)8C%s8LRKKD`F_rrU`'KD`F_rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8iMXF[I(XGa1[mf(c:KDW=^s8IZK^&S*:eYN6-k.LbF~>
-!<E0!johC3g4=g+g4@t/g5F\bs8LaPJc!:as8ITI_Z0W?g7eQ/k.1PC~>
-!<E0!johL1eVf?:k(2ZGk)8C%s8LRKKDW=^s8IZK^&S*:eYN6-k.LbF~>
-!<E0!johL1eS8iMXF[I(XGa1[mf(c:KDW=`s+>t$^&S*:eYN6-k.LbF~>
-!<E0!johC3g4=g+g4@t/g5F\bs8LaPJc!:cs+,au_Z0W?g7eQ/k.1PC~>
-!<E0!johL1eVf?:k(2ZGk)8C%s8LRKKDW=`s+>t$^&S*:eYN6-k.LbF~>
-!<E0!johL1eS8iMXF[I(XGa1[mf(c:KDN:]KDW@^rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g4@t/g5F\bs8LaPJbm7`Jc!=ars%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k(2ZGk)8C%s8LRKKDN:]KDW@^rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8iMmXaeWmYUB2ec19u]`<]]^&S*:eYN6-k.LbF~>
-!<E0!johC3g4=g+s+13$s,$dTgAca#_>o/`_Z0W?g7eQ/k.1PC~>
-!<E0!johL1eVf?:s+13$s,$dTec19u]`<]]^&S*:eYN6-k.LbF~>
-!<E0!jo_F0eS9['JaS*WM!k8ms+Bh@#1]OLk2s>WJ,~>
-!<E0!jo_=2g4=hTJcC<$M#[J.s+0\>#25dNk2s5TJ,~>
-!<E0!jo_F0eVf"YJcC<$M#[J)s+Bh@#1]OLk2s>WJ,~>
-!<E0!joD3.eUc8%eUl<OKCAgEeYN6-k.LbF~>
-!<E0!joD*+g4@t/g4J#YJa`UCg7eQ/k.1PC~>
-!<E0!joD3.eUc8%eUl<OKCAgEeYN6-k.LbF~>
-!<E0!joD3.eUc8%eUc9=eHMcKk2s>WJ,~>
-!<E0!joD*+g4@t/g4@uGg'+2Mk2s5TJ,~>
-!<E0!joD3.eUc8%eUc9=eHMcKk2s>WJ,~>
-!<E0!joD3.eUc8%eUc9=eHMcKk2s>WJ,~>
-!<E0!joD*+g4@t/g4@uGg'+2Mk2s5TJ,~>
-!<E0!joD3.eUc8%eUc9=eHMcKk2s>WJ,~>
-!<E0!joM:.JV/N+JV/Z/ldZ07s5rIW!.Y~>
-!<E0!joM10JUrB'JUrN+le2N9s5rIT!.Y~>
-!<E0!joM:.JV/N+JV/Z/ldZ07s5rIW!.Y~>
-!<E0!joM:.JV/N+JV/]0!<;B8"f21\k.LbF~>
-!<E0!joM10JUrB'JUrQ,!<;B="ektYk.1PC~>
-!<E0!joM:.JV/N+JV/]0!<;B8"f21\k.LbF~>
-!<E0!jo_F0K7id/!WTias+13$s/H#"^&S-)^&S,ueHMcKk2s>WJ,~>
-!<E0!jo_=2JV!F0!WU#fs+13$s/H#"_Z0Z._Z0Z%g'+2Mk2s5TJ,~>
-!<E0!jo_F0K7id/!WTias+13$s/H#"^&S-)^&S,ueHMcKk2s>WJ,~>
-!<E0!jo_F0K7ij1s8N+P]n-37s+13MrrIbcrVuT)s8VE8"f21\k.LbF~>
-!<E0!jo_=2JV!L2s8N+N_L_`<s+13MrrI\frVuT.s8VE="ektYk.1PC~>
-!<E0!jo_F0K7ij1s8N+P]n-37s+13MrrIbcrVuT)s8VE8"f21\k.LbF~>
-!<Bh3S-%5nKD3(Ys8R]Q^&S+`eUc8%eZIC%K)iU^s7j;-s6J2=S@tG_!!%N~>
-!<B_0R0))nJbR%\s8RWO_Z0Xeg4@t/g9'*/JH3Ras7jJ2s6JABRC\fS!!%N~>
-!<Bh3S-%5nKD3(Ys8R]Q^&S+`eUc8%eZIC%K)iU^s7j;-s6J2=S@tG_!!%N~>
-!!)uB".[noKDE4Zrrpr*K>%<bJ^o>%J^pmQs+:Hfs8UX"rVu`-s8VE8"e<iN]po(Q~>
-!!)u?".@koJbd1]rrq,-J\qHeJ_G\/J_I6[s+(<is8Ug,rVu`2s8VE="e!NE\sWPK~>
-!!)uB".[noKDE4Zrrpr*K>%<bJ^o>%J^pmQs+:Hfs8UX"rVu`-s8VE8"e<iN]po(Q~>
-!<CCD]`XeTK7j'7rVulIs+:Bds8RZ#J^o>%Xk!H(!knX6rRLlHr4W.1ldZ0/c+Uf\!.Y~>
-!<C:A\c\ASJV!^8rVulNs+(6gs8RZ(J_G\/XkNf+!lG!;rS%5Mr5/L6le2N1b.>0P!.Y~>
-!<CCD]`XeTK7j'7rVulIs+:Bds8RZ#J^o>%Xk!H(!knX6rRLlHr4W.1ldZ0/c+Uf\!.Y~>
-!<CCD]`XeTK7j-9rVufGs+:Bds8RZ#J^o>%Xk!H(!knX6qpkZFrk8@3ldZ0/c+Uf\!.Y~>
-!<C:A\c\ASJV!d:rVufLs+(6gs8RZ(J_G\/XkNf+!lG!;qqD#Krke^8le2N1b.>0P!.Y~>
-!<CCD]`XeTK7j-9rVufGs+:Bds8RZ#J^o>%Xk!H(!knX6qpkZFrk8@3ldZ0/c+Uf\!.Y~>
-!<CCD]`jqVK7gkNrVu`Es+:Bds8RZ#J^o>%Xk!H(!knX6q:5HD!knX6ldZ0/c+Uf\!.Y~>
-!<C:A\cnMUJUt\TrVu`Js+(6gs8RZ(J_G\/XkNf+!lG!;q:bfI!lG!;le2N1b.>0P!.Y~>
-!<CCD]`jqVK7gkNrVu`Es+:Bds8RZ#J^o>%Xk!H(!knX6q:5HD!knX6ldZ0/c+Uf\!.Y~>
-!<CCD]`FYRqh+[os+:Bds8RZ#J^o>%Xk!H(!knX6pso=qs8VE8"e<iN]po(Q~>
-!<C:A\cJ5QqgnOrs+(6gs8RZ(J_G\/XkNf+!lG!;ptG[ts8VE="e!NE\sWPK~>
-!<CCD]`FYRqh+[os+:Bds8RZ#J^o>%Xk!H(!knX6pso=qs8VE8"e<iN]po(Q~>
-!<CCD]`jqVK7gkNrIasss+:Bds8RZ#J^o>%Xk!H(!knX6q:5Fr!knX6ldZ0/c+Uf\!.Y~>
-!<C:A\cnMUJUt\TrIOh!s+(6gs8RZ(J_G\/XkNf+!lG!;q:bdu!lG!;le2N1b.>0P!.Y~>
-!<CCD]`jqVK7gkNrIasss+:Bds8RZ#J^o>%Xk!H(!knX6q:5Fr!knX6ldZ0/c+Uf\!.Y~>
-!<CCD]`XeTK7j-9rIb$us+:Bds8RZ#J^o>%Xk!H(!knX6qpkXtrk8@3ldZ0/c+Uf\!.Y~>
-!<C:A\c\ASJV!d:rIOn#s+(6gs8RZ(J_G\/XkNf+!lG!;qqD""rke^8le2N1b.>0P!.Y~>
-!<CCD]`XeTK7j-9rIb$us+:Bds8RZ#J^o>%Xk!H(!knX6qpkXtrk8@3ldZ0/c+Uf\!.Y~>
-!<CCD]`XeTK7j'7rIb+"s+:Bds8RZ#J^o>%Xk!H(!knX6rRLk!r4W.1ldZ0/c+Uf\!.Y~>
-!<C:A\c\ASJV!^8rIOt%s+(6gs8RZ(J_G\/XkNf+!lG!;rS%4$r5/L6le2N1b.>0P!.Y~>
-!<CCD]`XeTK7j'7rIb+"s+:Bds8RZ#J^o>%Xk!H(!knX6rRLk!r4W.1ldZ0/c+Uf\!.Y~>
-!<CCD]`XeTK7j!5rIY:(K7gl;s+/^OeUc8Qec17)^&S,_ebt-s^&S,ueHMJf]tKp9J,~>
-!<C:A\c\ASJV!X6rIG.+JUt]<s+/mTg4@t[gAc^,_Z0YigAQU!_Z0Z%g'*ne]"4:0J,~>
-!<CCD]`XeTK7j!5rIY:(K7gl;s+/^OeUc8Qec17)^&S,_ebt-s^&S,ueHMJf]tKp9J,~>
-!<CCD]`XeTK7ip3r.>'as8RZ#J^o>%Xk!H(!knX6rIamYs8VE8"e<iN]po(Q~>
-!<C:A\c\ASJV!R4r.+pds8RZ(J_G\/XkNf+!lG!;rIOa\s8VE="e!NE\sWPK~>
-!<CCD]`XeTK7ip3r.>'as8RZ#J^o>%Xk!H(!knX6rIamYs8VE8"e<iN]po(Q~>
-!<CCD]`XeTK7ij1rdt9cs8RY&JV/N+X+LPgs8R_(p:^M+ldZ0/c+Uf\!.Y~>
-!<C:A\c\ASJV!L2rdb-fs8RY$JUrB'X+:Djs8RY$p;6k0le2N1b.>0P!.Y~>
-!<CCD]`XeTK7ij1rdt9cs8RY&JV/N+X+LPgs8R_(p:^M+ldZ0/c+Uf\!.Y~>
-!<CCD]`XeTK7id/!e\2dJV/N+JV0tT!knVdoY(;)ldZ0/c+Uf\!.Y~>
-!<C:A\c\ASJV!F0!eJ5gJUrB'JUshP!lFtgoYUY.le2N1b.>0P!.Y~>
-!<CCD]`XeTK7id/!e\2dJV/N+JV0tT!knVdoY(;)ldZ0/c+Uf\!.Y~>
-!<CCD]`XeTK7eaTJcC<$L]?\j"e<iN]po(Q~>
-!<C:A\c\ASJUrCPJcC<$L]?\o"e!NE\sWPK~>
-!<CCD]`XeTK7eaTJcC<$L]?\j"e<iN]po(Q~>
-!<CCD]`O_SK7X&Rs+13)s6J2=SB\a\S,e'~>
-!<C:A\cS;RJV!iPs+13)s6JABREE+PR/ha~>
-!<CCD]`O_SK7X&Rs+13)s6J2=SB\a\S,e'~>
-!<CCD]`=RReUc8%eUc9=eHMJf]tKp9J,~>
-!<C:A\cA.Lg4@t/g4@uGg'*ne]"4:0J,~>
-!<CCD]`=RReUc8%eUc9=eHMJf]tKp9J,~>
-!<CCC^%%VDUk,=mUlM5N^%.Znc2PBWS,e'~>
-!<C:@]()2>Tn/ngToPfH](26hb5SsQR/ha~>
-!<CCC^%%VDUk,=mUlM5N^%.Znc2PBWS,e'~>
-!\j]"rOqgI!53s`JcC<$NrSXork/B'!&9!~>
-!^m%2rOVUC!4ma]JcC<$NrSXlrji0!!(;>~>
-!bq_[rOqgI!53s`JcC<$NrSXork/B'!-<Y~>
-!\j]"n%A^kJ`_OGJ``!T!6suG!h96NJ,~>
-!^m%2n%&LeJ`_OGJ``!T!6XcA!gs$VJ,~>
-!cn@dn%A^kJ`_OGJ``!T!6suG!h973J,~>
-s#C,\S=K,_!1\W&J`_OGNog>dn\+sm!WY58J,~>
-s$QngR@3TV!1AE#J`_OGNog>an[eag!WYVVJ,~>
-s)S5AS=K,_!1\W&J`_OGNog>dn\+sm!W[:_J,~>
-">Mnk!!)MYJ\?WJJ\@&VnXTUZs"OL6J,~>
-r^?bdn<nj=J\$EDNOnYJrrE$dJ,~>
-rcA)>n=5'CJ\?WJNP4kPrrE%>J,~>
-rAaj4JH16$JH16$li7#?r]'s5J,~>
-r'Z)9JH16$JH5$:r'Z&~>
-r,[DhJH16$JH5$:r,[A~>
-%%EndData
-showpage
-%%Trailer
-end
-%%EOF
diff --git a/lib/et/doc/src/megaco_tracer.gif b/lib/et/doc/src/megaco_tracer.gif
deleted file mode 100644
index cc4f747f03..0000000000
--- a/lib/et/doc/src/megaco_tracer.gif
+++ /dev/null
Binary files differ
diff --git a/lib/et/doc/src/megaco_tracer.png b/lib/et/doc/src/megaco_tracer.png
new file mode 100644
index 0000000000..b4b65a9f47
--- /dev/null
+++ b/lib/et/doc/src/megaco_tracer.png
Binary files differ
diff --git a/lib/et/doc/src/megaco_tracer.ps b/lib/et/doc/src/megaco_tracer.ps
deleted file mode 100644
index da1e1b6ba0..0000000000
--- a/lib/et/doc/src/megaco_tracer.ps
+++ /dev/null
@@ -1,2508 +0,0 @@
-%!PS-Adobe-3.0 EPSF-3.0
-%%Creator: GIMP PostScript file plugin V 1.12 by Peter Kirchgessner
-%%Title: /home/hakan/picts/megaco_tracer.ps
-%%CreationDate: Mon Oct 14 17:35:19 2002
-%%DocumentData: Clean7Bit
-%%LanguageLevel: 2
-%%Pages: 1
-%%BoundingBox: 14 14 443 516
-%%EndComments
-%%BeginProlog
-% Use own dictionary to avoid conflicts
-10 dict begin
-%%EndProlog
-%%Page: 1 1
-% Translate for offset
-14.173228 14.173228 translate
-% Translate to begin of first scanline
-0.000000 501.599409 translate
-428.031496 -501.599409 scale
-% Image geometry
-512 600 8
-% Transformation matrix
-[ 512 0 0 600 0 0 ]
-% Strings to hold RGB-samples per scanline
-/rstr 512 string def
-/gstr 512 string def
-/bstr 512 string def
-{currentfile /ASCII85Decode filter /RunLengthDecode filter rstr readstring pop}
-{currentfile /ASCII85Decode filter /RunLengthDecode filter gstr readstring pop}
-{currentfile /ASCII85Decode filter /RunLengthDecode filter bstr readstring pop}
-true 3
-%%BeginData: 143198 ASCII Bytes
-colorimage
-">Mns0fadbJH16$MZ<c<1&a1`~>
-r'Z)9JH16$MZEZCJ,~>
-rc8*TF+F=B!.b-.!;png~>
-"?A1s!!)Qh!53s`JcC<$fDbiaa8c/>!\l\qJ,~>
-r^?bdnc&U'JcC<$JcF@%!5?MRrrE$dJ,~>
-rcA)>nc&U&JcC<$JcF@%!56GQrrE%>J,~>
-">Mn:s8VWG!53s6J^o>%f@9l7a56ja!WY58J,~>
-s$Qngs8VWC!5=$8J_#D'f@Br9a4gR]!WYVVJ,~>
-s)S5As8VWG!53s6J^o>%f@9l7a56ja!W[:VJ,~>
-!]^8\n(n&XJ^o>%J^rB&!56A.!lY."J,~>
-!^m%gn(IcUJ_#D'J_&H(!5?G+!l=q*J,~>
-!cnAAn(n&XJ^o>%J^rB&!56A.!lY.\J,~>
-!\j]Tn(n&XJ^qcj!6(hc!6'N>n'qEO`SL[8!',Q~>
-!^m%gn(IcUJ_%il!QrigecEqAJ_'>A!5?G+!l=q*J,~>
-!bq`8n(n&XJ^qcj!6(hc!6'N>n'qEO`SL[8!-<Y~>
-!<E/fh>k6HeH(;L`75%1Ut*/*HiB90eH(;LYLN]fH[GaVs4%.&HgoPdUqMW8!57RPpRLp5s.'&E
-s.'#D!NZ9O~>
-!<E/fg&SjEf)L<>edTEhf"Q]`R?<W_eq&CUed9'AI@64[f%,D'nC@W6^5:D@^?=5ERJ#;6RJkk>
-RJbb>XoNt~>
-!<E/fh>k6HeH(;L`75%1Ut*/*HiB90eH(;LYLN]fH[GaVs4%.&HgoPdUqMW8!57RPpRLp5s.'&E
-s.'#D!NZ9O~>
-!<E/thZ',ChZ',Eh>k7dec0srMuM6.UjIaFeH*Y&eCFGC!/(-u!J>a^eI9ELe^_X/K6r6@c./'U
-HNBA]r-JI&^&-=l`I"uBMgNFnPa'_KK6u/!`P&V.%?#SPeWc<KeUr5!e]#5oeH3+)`JW1G^$"8H
-SG(h<SH%IESGh:FX8mb~>
-!<E/tf)M08f)M0:ec<G]df4^qNW.?-Tm_XGdK.4neC">Jr-\R!qU5CpkL'dQL!nDhR>$'CS]]BG
-qgAO.dXh@F!K"PfdLj?I[aL.``m0^/daE\tdaH"@ZdK;BIE'QpOj_[/J^Vu`[e.uL[XGlIdK%#E
-f(YU+f);$:f);$8ecDoRJ,~>
-!<E/thZ',ChZ',Eh>k7dec0srMuM6.UjIaFeH*Y&eCFGC!/(-u!J>a^eI9ELe^_X/K6r6@c./'U
-HNBA]r-JI&^&-=l`I"uBMgNFnPa'_KK6u/!`P&V.%?#SPeWc<KeUr5!e]#5oeH3+)`JW1G^$"8H
-SG(h<SH%IESGh:FX8mb~>
-!<E/uhYiuChYiuDh>k7dec'n!c.1?sH\9o"!J>aKec1!o^&$7[K6ue3)l0"S`IiN=]qg"-c,IB0
-H[EH>`RT<^]tL4gKDX1&Mj2cBK7!LG"bV0PeUr4TeH(;Lqpbk&He$Z!Hh5bgP`(FL!57RPpRLs6
-pRM3=!NZ9O~>
-!<E/uf);$8f);$9ec<G]df+Xub0n^lI>-8#s+/\J!J,[t\cBJ@df4m]dMo$Rd`-idV7NLOL!%9D
-\p]"<]#)mHJ\&FdI>RjL"c8MmdXcuHdf4mudf4m)df4mqdf4mudf4midK,ViMUDL=kLTBqp=Au+
-rRM"P!.Y~>
-!<E/uhYiuChYiuDh>k7dec'n!c.1?sH\9o"!J>aKec1!o^&$7[K6ue3)l0"S`IiN=]qg"-c,IB0
-H[EH>`RT<^]tL4gKDX1&Mj2cBK7!LG"bV0PeUr4TeH(;Lqpbk&He$Z!Hh5bgP`(FL!57RPpRLs6
-pRM3=!NZ9O~>
-!<E/uhY`oDhY`oCh>k7deJ!:^HaM>BH\6t$e]!GnK='1Z`K^=J'\10eH[C[ie^^aZH[C[qeZ=[U
-Mlcg+!2TU@*lX%qXGb&^H[C[ie^^aZH[C[qe]!GnK='1ZMi4Zpo[WtgqUPV((T`PFK6u.fP^@b8
-`RWLsMnOai[+3^GPl5t.eHLlEeWbE^rm_(GH^t)cs*O^ps*Oaqs*O[o"MK/qeXZVc#gJ!Ke^];!
-eYN1ks2>D)H\8]UeVf?eMq*H,qpk_)'"rpE['YI4[+3^GMgL)`e^_X'rHf7/`KY^rMoF5sXG_FP
-Mp9eRMgLA`psfA7rd+pqK6u/!K6u.Erd4[a%?#Rc[+3]bMl_ie]mIGNeH!;GhY3Q5hYE]>h>s\X
-J,~>
-!<E/uf)1s9f)1s8ec<G]dM%%_IBq;<JUrO'd__,pKsK.T_NFeF'[k!`JUNNldaG:TI=6spd]SFT
-M6?a(!29C?*l<nrV2`KWJUNNldaG:TI=6spd__,pKsK.TNK'coo[3bkIJVClN>JFNdXctt`fYh#
-NP<ihNK(N'J[3_P_NFeFrmCt0]$cjlY5ZiNV1"p6dK+oIrR1^srmLgpr6b_ZICdjprd>'pJUu7t
-JUu7CrdFg`%$>slZI70\NMVW_JV!^Hs,@Z"Kn6D8Kn6PXd__,pKsK.T_NFeF'[k!`JUNNldaG:T
-I=6spd]SFTM6?X%!1Eh7#g.^LdaE\td\6Ygs2#5-I>+uTdZ'6_NRG7`\r4u:^?=)ARJ#/,RJbV:
-XoNt~>
-!<E/uhY`oDhY`oCh>k7deJ!:^HaM>BH\6t$e]!GnK='1Z`K^=J'\10eH[C[ie^^aZH[C[qeZ=[U
-Mlcg+!2TU@*lX%qXGb&^H[C[ie^^aZH[C[qe]!GnK='1ZMi4Zpo[WtgqUPV((T`PFK6u.fP^@b8
-`RWLsMnOai[+3^GPl5t.eHLlEeWbE^rm_(GH^t)cs*O^ps*Oaqs*O[o"MK/qeXZVc#gJ!Ke^];!
-eYN1ks2>D)H\8]UeVf?eMq*H,qpk_)'"rpE['YI4[+3^GMgL)`e^_X'rHf7/`KY^rMoF5sXG_FP
-Mp9eRMgLA`psfA7rd+pqK6u/!K6u.Erd4[a%?#Rc[+3]bMl_ie]mIGNeH!;GhY3Q5hYE]>h>s\X
-J,~>
-!<E/teb>U4eH!;[bq4:4H^)dNP_4V5`IifVP^CBoK7h.fK6tkVXM(ufMp8&EMmTje`N4EN]p*lF
-r66G)H[EHNK6rNP]r\oSH]-.EH],8<UrC<*K>!Lr`Qa$^Mkp!is*O^XrlldBH]+]EK6tkVXM(uf
-Mp9M!H]+D@K?_YnK>l)fHd0gSHd0f^Hc?!/!kir5rltIirQY@hs31V@H].gH,+O#!c,G$V^!21V
-c-:lfc,G$V]u>VV]p*l_c%CA$Us4gMqopaGH]+D@H]+D@K?_AfK>!Lr`Qa$f`Qa$^c+U3l[!R_U
-UjJ$,[%t[BH^)4.H`[%f+2rSR^!21Vc-:lfc,G$V]u>VV]p*l_c%CA$Us6l*S;YVl^$!oGSGC\8
-SFkA/SGUh;X8mb~>
-!<E/tdeB1.dK%#Yc7OI8I?i*SR>$@?b(58XQ$pZpJVCtdKmh7\Y.h>mM9_rGM6aRi`i=HP^6O,H
-r6?M+JUPD\JUNBO^952YI>Q7GI>P8<WlE24Kt<Ot`m0-`M5Bji!J,[t\gbeIc@LD#V9XXCcG$Hq
-[XF"Xc@LD#Tm_X?b(58`c@p\lcGkFXc@(,\rltS^I>.[G!J,[tcMrFucH;u3Oo3KKTmar+`drQT
-c@LPlc@LPl`drQT`driTQ$pZtJUNBOcA@DTc7XZrNM1cKNM1cScH:]l\s7]`b(58`c@p\l^952Y
-I>Q7GI>P8<WlD&eQ+iN3Wqjp^`drQTc@LPlc@LPl`drQT`driTQ$pZtJUNBOcGk:+Mp;=:kL'?u
-q9f82o[<W)qpGMJ!.Y~>
-!<E/teb>U4eH!;[bq4:4H^)dNP_4V5`IifVP^CBoK7h.fK6tkVXM(ufMp8&EMmTje`N4EN]p*lF
-r66G)H[EHNK6rNP]r\oSH]-.EH],8<UrC<*K>!Lr`Qa$^Mkp!is*O^XrlldBH]+]EK6tkVXM(uf
-Mp9M!H]+D@K?_YnK>l)fHd0gSHd0f^Hc?!/!kir5rltIirQY@hs31V@H].gH,+O#!c,G$V^!21V
-c-:lfc,G$V]u>VV]p*l_c%CA$Us4gMqopaGH]+D@H]+D@K?_AfK>!Lr`Qa$f`Qa$^c+U3l[!R_U
-UjJ$,[%t[BH^)4.H`[%f+2rSR^!21Vc-:lfc,G$V]u>VV]p*l_c%CA$Us6l*S;YVl^$!oGSGC\8
-SFkA/SGUh;X8mb~>
-!<E/sebPa5eH!;[bnk`&P^CZ5["F"UXF$J^XF%%MH^r@*K7!UB#K=B/K?]$q`Vn$cK6tS^`I!77
-blr`Hc-:lfrQPSd]n:s^K6tT9bmCIuSB\-^XNcBEqoo5=H[CDCc22hj^!4fSHiD7jK7!UB)o]LC
-K?_YnHc=6VHd/X=SB]<2Hd0g:Pg.I"Hi;1j`Hut2c2W.hc2;nhMoGV=!L.s1bnu([c-:lfc-:lf
-c-:lfc)c8^c)c8nc%CB:bnu([`Q`aV`Q`aVc)c8^c)c8nXF$J^c%CBBbm25$K7hF$Hc>s.#(q9A
-c,G$^prsY.Hd0ffHd0ffHd0ffHd/X=SB\-^XNcBErQP@iP`*cd^$!oGSGC\8SFkA/SGUh;X8mb~>
-!<E/sdeT=/dK%#Yc51o*Ob(Z3ZA""XY'm"dY'mIYI@\[/KmisG#K"3+L!GC#_YqaaM1*Ch`dN^@
-cMrIqc2rQFb5TZk_S1STc@p\`rQYbQIA+fdIBLkHIEMK5"/UEoM>YX!Jc'p&^<Y#TIEKj\JV!gG
-)oB=?L!ItpIE'Q`J^1QLS^,N7IEp-@Q-RO#IJqFmb'e^;c2iKErQYCorI"^'_Yh[[Q$rYWs+13q
-s+13qs+13qs+(R'Y'm"dY'mIuJUP]8c5;+\b0GQdb0GQhcE;Shb-$/qZ@/:hc@p]Gc3M5#JVDC'
-IDYs.#)RcJcGk9hps/njs3CXqs3CXqs3CXq$dPo'TusNdY0MTHb5TZeI?f`9!5@XE!1EZ2!1EK-
-qjI?0!NlEQ~>
-!<E/sebPa5eH!;[bnk`&P^CZ5["F"UXF$J^XF%%MH^r@*K7!UB#K=B/K?]$q`Vn$cK6tS^`I!77
-blr`Hc-:lfrQPSd]n:s^K6tT9bmCIuSB\-^XNcBEqoo5=H[CDCc22hj^!4fSHiD7jK7!UB)o]LC
-K?_YnHc=6VHd/X=SB]<2Hd0g:Pg.I"Hi;1j`Hut2c2W.hc2;nhMoGV=!L.s1bnu([c-:lfc-:lf
-c-:lfc)c8^c)c8nc%CB:bnu([`Q`aV`Q`aVc)c8^c)c8nXF$J^c%CBBbm25$K7hF$Hc>s.#(q9A
-c,G$^prsY.Hd0ffHd0ffHd0ffHd/X=SB\-^XNcBErQP@iP`*cd^$!oGSGC\8SFkA/SGUh;X8mb~>
-!<E/rebbm6eH!;[bmJfnXF$aic%CYnV#5T>U^qgJc-:lfc+Sa^MgL*$H[G\8s*Oais*OXf&;,>S
-c%CAfc+Sa^MgL*$H[G\8!2TO>"/O1oHi)%i`P&t(r6>7gqTT%nHiD85K6tkVK7f)/K?_YnHd0ff
-Hd/@5Us7/:Hd0g"XNf":Hc?!/!kir5rltIirQY@hs0MdFqTT&*HiD8#K6tkfK6tkfK6tkfK6tk=
-r-JOAc%CB:bmT/Nc-:lfc-:lfc(t8as.g0PUs7/:Hd06VK8Y)/c$Og8c2W.ic2W.cbn#GRc-:lf
-c-:lfc-:lfc(t8a"/O1oHi;1iH^'H5!58<\!582u!58*V!1`l8!1``4q4.B5!NZ9O~>
-!<E/rdefI0dK%#Yc3eurY'm<ub(YPpV>PcAV%8!JcH_,lcFS^\NI?N+I=;%=!J,[ucMr=icMrIq
-cMrIqc3V"8JW5)3c@(-=c2a^=I06=kJV!^D!6Y;Xr6>=oIJV7hJc<spJKN1KKn553L!ItpJ^2Pl
-J^1*?U!Cr;IEp-#Y0P=@IE)93!lBA>rltOqIJqIkJcE:]_YVOYQ$rYWs+13qs+13qs+13qs+(3r
-V>P`DV9XXCp<N\hs3CXqs3CXq!R@P>IK-,SIA+s3Kmh7XKn553L!G*pr6>=oIK%OlIJD+fJcF$q
-JcF$qJcF$qJH=&mr-\[Dc@LQFc2i?YMp;=:r6bSVq3_5op<ir/q9f82p!WZ(r6bVK!.Y~>
-!<E/rebbm6eH!;[bmJfnXF$aic%CYnV#5T>U^qgJc-:lfc+Sa^MgL*$H[G\8s*Oais*OXf&;,>S
-c%CAfc+Sa^MgL*$H[G\8!2TO>"/O1oHi)%i`P&t(r6>7gqTT%nHiD85K6tkVK7f)/K?_YnHd0ff
-Hd/@5Us7/:Hd0g"XNf":Hc?!/!kir5rltIirQY@hs0MdFqTT&*HiD8#K6tkfK6tkfK6tkfK6tk=
-r-JOAc%CB:bmT/Nc-:lfc-:lfc(t8as.g0PUs7/:Hd06VK8Y)/c$Og8c2W.ic2W.cbn#GRc-:lf
-c-:lfc-:lfc(t8a"/O1oHi;1iH^'H5!58<\!582u!58*V!1`l8!1``4q4.B5!NZ9O~>
-!<E/qebu$7eH!;[bm\rp`Hurrc%CYnXF$K9bn7%(SB]<*Hd.Iqc-:lnc%CAVrQPP!Hc=7KH\;4?
-&VGGTc%CAfc&6qnc%CYnK6t<1blXtnSG^V4K7!16s*OUe!J>auboq^dc&6qnc%CYnc%CAfc%CAf
-XF$J^c$Of^c$RFSc'3RVrlkM?H^t)[s*O^hs*OLb(8Q;rc-:lfc-:lfc-:lfc-:lfc)c8^r657p
-HhP\nK6tkfK6tkfK6tkEH^t&Z&Zg>Lc-:T^c&6qnc%CYnK6t<1bm&fI`QcAKKD<\'K6tkfK6tkf
-K6tkfK6tkEH^t#Y!J>aublYk2S;YVl^&6FTSG(J5SGC\8SG(M-SGgt=X8mb~>
-!<E/qdf#U1dK%#Yc4#,t`dN9#c@pttY'm#Bc4R4-REis+IEmh'b0G]pc@p\\rQYV(IE'RPI>RjH
-s+13qs+13q$&sMYc@pttKmg]6c2t.sU&<49Jb%(eJURC?s+10ps+)9;NIf6tKn[gtJUu+lJUu+L
-I@8C'JUPhdIE'RXQ$o\3c2s\fRJtJ4JURLBs+0pi(86/rcH^ulcH^ulcH^ulcH^ulcE;Shr6G=n
-p<N\hs3CXqs3CXq"4"&tU&E7KY'l_`b(4udNIf6tKn[g+ID5[*#)RcJcGk9hps/njs3CXqs3CXq
-s3CXq"4"&tU&<49Jc<pr`dOP=c2bTVdeB1'dK#^2dK#^/deB1.dK-KNJ,~>
-!<E/qebu$7eH!;[bm\rp`Hurrc%CYnXF$K9bn7%(SB]<*Hd.Iqc-:lnc%CAVrQPP!Hc=7KH\;4?
-&VGGTc%CAfc&6qnc%CYnK6t<1blXtnSG^V4K7!16s*OUe!J>auboq^dc&6qnc%CYnc%CAfc%CAf
-XF$J^c$Of^c$RFSc'3RVrlkM?H^t)[s*O^hs*OLb(8Q;rc-:lfc-:lfc-:lfc-:lfc)c8^r657p
-HhP\nK6tkfK6tkfK6tkEH^t&Z&Zg>Lc-:T^c&6qnc%CYnK6t<1bm&fI`QcAKKD<\'K6tkfK6tkf
-K6tkfK6tkEH^t#Y!J>aublYk2S;YVl^&6FTSG(J5SGC\8SG(M-SGgt=X8mb~>
-!<E/pec208eH!;[bq4:<c&6qMc%CYnc%CA=[&gXRH[DQHH[F"qH`X;qHbHM-K<2bf`N4EN]p*lF
-qop48HaM%MHd0fnH`X;qHbHM-K<2bf`Qa$^UpR51c%CB6c2W.g[/\AOK7!UB)hWL^MgMP,H[EHN
-K6tkfK6tk^H[DQHH[F#EMuLs,]mG+%[%r&$`W"-^Hi;4hHhYc*]mI-2c%CAfc%CAfc%CAfc%CAM
-`IiN5[&gXZK7!UB!K2U-bq=Wqc-:lfc-:lfc-:lfUpR51`Hus-MgKfqMgMP,H[EH-H\8E5XMq8f
-PeE<.XSC$WK6tkfK6tkfK6tkfK6suEK6sE$XL-6)HiD7k[!TKEblGHTeb>U-eGu-8eGu-5ebu$<
-ebu$:eH)`OJ,~>
-!<E/pcMs1*c2bTUat8%8b)(PLb(YPl`eAi;[]ZpQI=7fGI=97pIB';qID2_0Ks%ka_Q&$L\s7]?
-qoU";[email protected]]c,lIB';qID2_0Ks%ka_T%:XV7*P4b(5-7aoR'Ar3?FEb(5-Cb5[#1b)(PHWdT<0
-b(5,db(5,d_L6j+M1'fpZAJS'#ekk<TsCA?J\qE/!J,[tb5[%earS'AY0+n<J]c,dJ]c,dJ]c,l
-IC@"HIAOBTZH@`LrlY7tqo\qis2t@ms2t@m,g+,\IAOBTZGM$<To"2Gb)(PHWdT<0WdTT([]73E
-I?hC/IAQ_]s+13ms+13ms+13m%#KD@_M*E7[]ZpYJV!gC!j6s[Mol%6r6G&%p<EZ'q9Au*p<NW%
-s3CS.rQYGH!.Y~>
-!<E/pec208eH!;[bq4:<c&6qMc%CYnc%CA=[&gXRH[DQHH[F"qH`X;qHbHM-K<2bf`N4EN]p*lF
-qop48HaM%MHd0fnH`X;qHbHM-K<2bf`Qa$^UpR51c%CB6c2W.g[/\AOK7!UB)hWL^MgMP,H[EHN
-K6tkfK6tk^H[DQHH[F#EMuLs,]mG+%[%r&$`W"-^Hi;4hHhYc*]mI-2c%CAfc%CAfc%CAfc%CAM
-`IiN5[&gXZK7!UB!K2U-bq=Wqc-:lfc-:lfc-:lfUpR51`Hus-MgKfqMgMP,H[EH-H\8E5XMq8f
-PeE<.XSC$WK6tkfK6tkfK6tkfK6suEK6sE$XL-6)HiD7k[!TKEblGHTeb>U-eGu-8eGu-5ebu$<
-ebu$:eH)`OJ,~>
-!<E/feH!;[bq+4;c+U4'c%CYnc,GooH\8EEXFl/4K6tkMK6s,aH^r?^MgKf/`QbK:H\8Erboa<F
-HbG&Yc-<VJH^pmYSB\-nH[C[ic,GooH\8EEK7!16qKi=Xc%CBBbo;:^c*W+MS>:M%c%CAfc%CAf
-c)cPM["E_MS>?,.#/ugZH\7j-rQY@hrQY@hp<EVqs32C5Hd0ffHd0ffHd0gBK6t;NP^@b0XNcBE
-rlkIrHi)&>K6tkfK6tkfK6tkf`KY^rK<3>!K7gO`Hd/pMH^pmYSB\-nH[C[ic)cPEK<4gl(k[1[
-c%CAfc%CAfc*W+M]u?4_H\8EEK7!UBs,2cZ!58<\!582u!58*VpRLp,s.'&<s.'#;!NZ9O~>
-!<E/fc2bTUat.t7b.=Umb(YPlb/0EpI>+iHY(;;4Kn7CTKmfMcI@86XM1'f/^<3:+I>+]tardp?
-J\$D`b0%/HI@['[REDOdI=6sdb/0EpI>+iHJV!C7!.k#q"1lX+Jc<glJJlV=KmfMcI@86/J]c,d
-J]c-<JVCC`J]aCSrQ5>YQ%=@;RDSpF!J,[tb5[%db5[J$b5[%mb5[%mb5[%mapbS,J\&^`JUN6T
-b(5-Cb5[%ib5[%mb5[%mb5[%mas"WeJUN6Tb-$;LZA!kP[Y9.#Tm`?OWel.PM8%-/KmeZTpWEMe
-s2t@ms2t@ms2kbUJUtDLQ%=@;Y0)<HrlY8#MTPq5r6>;Nq3:rgp<NDtp!3T&rQbG.r6>>G!.Y~>
-!<E/feH!;[bq+4;c+U4'c%CYnc,GooH\8EEXFl/4K6tkMK6s,aH^r?^MgKf/`QbK:H\8Erboa<F
-HbG&Yc-<VJH^pmYSB\-nH[C[ic,GooH\8EEK7!16qKi=Xc%CBBbo;:^c*W+MS>:M%c%CAfc%CAf
-c)cPM["E_MS>?,.#/ugZH\7j-rQY@hrQY@hp<EVqs32C5Hd0ffHd0ffHd0gBK6t;NP^@b0XNcBE
-rlkIrHi)&>K6tkfK6tkfK6tkf`KY^rK<3>!K7gO`Hd/pMH^pmYSB\-nH[C[ic)cPEK<4gl(k[1[
-c%CAfc%CAfc*W+M]u?4_H\8EEK7!UBs,2cZ!58<\!582u!58*VpRLp,s.'&<s.'#;!NZ9O~>
-!<E/feH!;EblN0DOj+#UK?]%^hou5AK<3&:!IKIac2)be^#mQ@XFnKLblGGqeH)`OJ,~>
-!<E/fc2bT@ao]S2Kp'R^`dNQ`Kt?0a!lBMb`l\A&I>-t/qL&@Tk/mb*J\m;e!5?Cs!NlEQ~>
-!<E/feH!;EblN0DOj+#UK?]%^hou5AK<3&:!IKIac2)be^#mQ@XFnKLblGGqeH)`OJ,~>
-!<E/fblGHB`<N]6Uo]K$S<h,"[$7AfMgLu$KAFKI]qifi#.0VjXG_Fqa2J(T]ns].]u8.rX8mb~>
-!<E/faoK0@`Wil6WiD&,TpE\([ZRSiNI@M/J_e<H^7i]h#.BYoWf;G#a2S.R^59i0^;S.pXoNt~>
-!<E/fblGHB`<N]6Uo]K$S<h,"[$7AfMgLu$KAFKI]qifi#.0VjXG_Fqa2J(T]ns].]u8.rX8mb~>
-!<E/fblGHB`<Er>K6r6HQ,O$BP_4=8UrC$SUr<MNP_4=8Uk-M/`;mTiblOmGJ,~>
-!<E/faoK0@`Wa)=JUN6GQ,X*DOb%q7TuOgXUrESPOb%q7Tn15-`W3`kaoSXFJ,~>
-!<E/fblGHB`<Er>K6r6HQ,O$BP_4=8UrC$SUr<MNP_4=8Uk-M/`;mTiblOmGJ,~>
-!<E/fblGG.`IZ!Z`Ri'/]u8.rX8mb~>
-!<E/faoK/,`du-\`n/31^;S.pXoNt~>
-!<E/fblGG.`IZ!Z`Ri'/]u8.rX8mb~>
-!!%S&JV/N+K7a.(J,~>
-!!%S$JUrB'K7O"&J,~>
-!!%S&JV/N+K7a.(J,~>
-!<E0!joD3.s+13$s,I$^V#TT>]`<Q~>
-!<E0!joD*+s+13$s,I$^U&X9;\c@6~>
-!<E0!joD3.s+13$s,I$^V#TT>]`<Q~>
-!<E0!joD3.s+13$s,R*`K;AP0k.LbF~>
-!<E0!joD*+s+13$s,R*`JYE,+k.1PC~>
-!<E0!joD3.s+13$s,R*`K;AP0k.LbF~>
-!<E0!joV@Ys+/^OeUc85ec17*V#TT>]`<Q~>
-!<E0!joV7Vs+/mTg4@t?gAc^-U&X9;\c@6~>
-!<E0!joV@Ys+/^OeUc85ec17*V#TT>]`<Q~>
-!<E0!joV@Ys+/^OeUc85ec17*V#TT>]`<Q~>
-!<E0!joV7Vs+/mTg4@t?gAc^-U&X9;\c@6~>
-!<E0!joV@Ys+/^OeUc85ec17*V#TT>]`<Q~>
-!<E0!joV@Ys+/^OeUc85ec17*V#TT>]`<Q~>
-!<E0!joV7Vs+/mTg4@t?gAc^-U&X9;\c@6~>
-!<E0!joV@Ys+/^OeUc85ec17*V#TT>]`<Q~>
-!<E0!joV@Ys+/^OeUc85ec17*V#TT>]`<Q~>
-!<E0!joV7Vs+/mTg4@t?gAc^-U&X9;\c@6~>
-!<E0!joV@Ys+/^OeUc85ec17*V#TT>]`<Q~>
-!<E0!joV@Ys+/^OeUc85ec17*V#TT>]`<Q~>
-!<E0!joV7Vs+/mTg4@t?gAc^-U&X9;\c@6~>
-!<E0!joV@Ys+/^OeUc85ec17*V#TT>]`<Q~>
-!<E0!joV@Ys+/^OeUc85ec17*V#TT>]`<Q~>
-!<E0!joV7Vs+/mTg4@t?gAc^-U&X9;\c@6~>
-!<E0!joV@Ys+/^OeUc85ec17*V#TT>]`<Q~>
-!<E0!joV@Ys+/^OeUc85ec17*V#TT>]`<Q~>
-!<E0!joV7Vs+/mTg4@t?gAc^-U&X9;\c@6~>
-!<E0!joV@Ys+/^OeUc85ec17*V#TT>]`<Q~>
-!<E0!joV@Ys8(:A!!:[N!:A>:!<(IH!7TKs!;Y1F!!:[N!:eV>!9Vi-!!^sR!7fU"!9Vi3!<1OK
-!;Y1F!.i[Oe`bQ`K*A(Nk2s>WJ,~>
-!<E0!joV7Vs8(IF!!:jS!:AM?!<(XM!7T[#!;Y@K!!:jS!:eeC!9W#2!!_-W!8?-,!9W#8!<1^P
-!;Y@K!.ijTg?@8jJH_bIk2s5TJ,~>
-!<E0!joV@Ys8(:A!!:[N!:A>:!<(IH!7TKs!;Y1F!!:[N!:eV>!9Vi-!!^sR!7fU"!9Vi3!<1OK
-!;Y1F!.i[Oe`bQ`K*A(Nk2s>WJ,~>
-!<E0!joV@Ys8(:G!;b7G!:A>:!<(IJ!7KEt!<:UL!;b7G!!:[N!:eV>!9Vi3!;b7G!<:UL!9Vi3
-!<1OK!;Y1F!.i[Oe`bQ`K*A(Nk2s>WJ,~>
-!<E0!joV7Vs8(IL!;bFL!:AM?!<(XO!7KU$!<:dQ!;bFL!!:jS!:eeC!9W#8!;bFL!<:dQ!9W#8
-!<1^P!;Y@K!.ijTg?@8jJH_bIk2s5TJ,~>
-!<E0!joV@Ys8(:G!;b7G!:A>:!<(IJ!7KEt!<:UL!;b7G!!:[N!:eV>!9Vi3!;b7G!<:UL!9Vi3
-!<1OK!;Y1F!.i[Oe`bQ`K*A(Nk2s>WJ,~>
-!<E0!joV@Ys8(:G!<(IJ!!LgP!7fWu!:n\?!<:UL!!LgP!7fWu!<:UL!<:UL!<:UL!<:UJ!<:UL
-!!:[N!;+hA!;k=F!<:UL!!LgP!7fWu!<1OI!<:UJ!<:UJ!<:UL!!:[N!;+hA!<(IJ!!CaO!7h#J
-s4.&Js4.,L!n@8No[WsArmh#Ks4.&Js4.,L"k<SQeGoT#eUc9=ec17*V#TT>]`<Q~>
-!<E0!joV7Vs8(IL!<(XO!!M!U!8?0*!:nkD!<:dQ!!M!U!8?0*!<:dQ!<:dQ!<:dQ!<:dO!<:dQ
-!!:jS!;,"F!;kLK!<:dQ!!M!U!8?0*!<1^N!<:dO!<:dO!<:dQ!!:jS!;,"F!<(XO!!CpT!8@AO
-s4[DOs4[JQ!nmVSo\0<Frn@APs4[DOs4[JQ"kiqVg&M,(g4@uGgAc^-U&X9;\c@6~>
-!<E0!joV@Ys8(:G!<(IJ!!LgP!7fWu!:n\?!<:UL!!LgP!7fWu!<:UL!<:UL!<:UL!<:UJ!<:UL
-!!:[N!;+hA!;k=F!<:UL!!LgP!7fWu!<1OI!<:UJ!<:UJ!<:UL!!:[N!;+hA!<(IJ!!CaO!7h#J
-s4.&Js4.,L!n@8No[WsArmh#Ks4.&Js4.,L"k<SQeGoT#eUc9=ec17*V#TT>]`<Q~>
-!<E0!joV@Ys8(:G!<(IJ!"%0U!7_&Le^XX"o@<j@s4.,L*7Y#heGoU"eGoU"!!(R"!!(R"!!(OL
-!7fU"!7guIo[WsAr71fIs4.,L+OpGleGoU"!!(R"!!(OL!7fU"!7fU"!7fU"!7fU"!7guIo[WsA
-rRLoJ&(LX[e^XX"e^XX"e^XX"ebfF>ec,XKec,UVeGoU"eGoU"!!(RK!!:[N!.i[OeaM&gK*A(N
-k2s>WJ,~>
-!<E0!joV7Vs8(IL!<(XO!"%?Z!87DQg=cN,o@j3Es4[JQ*81Amg&M-,g&M-,!!(a,!!(a,!!(^Q
-!8?-,!8@>No\0<Fr7_/Ns4[JQ+PHeqg&M-,!!(a,!!(^Q!8?-,!8?-,!8?-,!8?-,!8@>No\0<F
-rS%8O&)%!`g=cN,g=cN,g=cN,gACsCgA_0PgA_-[g&M-,g&M-,!!(aP!!:jS!.ijTg@*bqJH_bI
-k2s5TJ,~>
-!<E0!joV@Ys8(:G!<(IJ!"%0U!7_&Le^XX"o@<j@s4.,L*7Y#heGoU"eGoU"!!(R"!!(R"!!(OL
-!7fU"!7guIo[WsAr71fIs4.,L+OpGleGoU"!!(R"!!(OL!7fU"!7fU"!7fU"!7fU"!7guIo[WsA
-rRLoJ&(LX[e^XX"e^XX"e^XX"ebfF>ec,XKec,UVeGoU"eGoU"!!(RK!!:[N!.i[OeaM&gK*A(N
-k2s>WJ,~>
-!<E0!joV@Ys8(:D!"@BX!7_&LeGoU"eGoU@ec,XLec,UheGoU"!!(R"!!(R"!!(OL!7_&Le^XX"
-e^XX"ec#R>ec,XIec,XLec,U[eGoU"!!(OL!7fU"!7_&Lqpk]Hs4.,Ls4.,L!7h&Ko%!X<'%Hs^
-eGoU"eGoU"eGoU"eGoU"rW)N>q>_)W!!(R"!!(OL!7_&Le^XX"J^o>%n(%Gj"f21\k.LbF~>
-!<E0!joV7Vs8(II!"@Q]!87DQg&M-,g&M-EgA_0QgA_-mg&M-,!!(a,!!(a,!!(^Q!87DQg=cN,
-g=cN,gAV*CgA_0NgA_0QgA_-`g&M-,!!(^Q!8?-,!87DQqqD&Ms4[JQs4[JQ!8@DPo%O!A'&!<c
-g&M-,g&M-,g&M-,g&M-,rW)NCq>_)\!!(a,!!(^Q!87DQg=cN,J_G\/n(Rem"ektYk.1PC~>
-!<E0!joV@Ys8(:D!"@BX!7_&LeGoU"eGoU@ec,XLec,UheGoU"!!(R"!!(R"!!(OL!7_&Le^XX"
-e^XX"ec#R>ec,XIec,XLec,U[eGoU"!!(OL!7fU"!7_&Lqpk]Hs4.,Ls4.,L!7h&Ko%!X<'%Hs^
-eGoU"eGoU"eGoU"eGoU"rW)N>q>_)W!!(R"!!(OL!7_&Le^XX"J^o>%n(%Gj"f21\k.LbF~>
-!<E0!joV@Ys8(:G!<(IJ!!CaO!7grHo$n!Ge^XZMeGoU"qZ-ZHrr<;S!!(OL!7fWs!!:[N!:eV>
-!;tCI!<:UL!!^sR!7_&Leb]=JeGoUHec,XLec,XLec,UNeGoU>ec,XJec,UTeGoU"eGoU"eb]=J
-eGoU>ec,XKec,ULeb]=QeGoU"!!(R"!!%T#J^s5>s+:KNs5rIW!.Y~>
-!<E0!joV7Vs8(IL!<(XO!!CpT!8@;Mo%F?Lg=cP\g&M-,qZ-ZMrr<;X!!(^Q!8?0(!!:jS!:eeC
-!;tRN!<:dQ!!_-W!87DQgA:jOg&M-MgA_0QgA_0QgA_-Sg&M-CgA_0OgA_-Yg&M-,g&M-,gA:jO
-g&M-CgA_0PgA_-QgA:jVg&M-,!!(a,!!%T(J_KSHs+(?Is5rIT!.Y~>
-!<E0!joV@Ys8(:G!<(IJ!!CaO!7grHo$n!Ge^XZMeGoU"qZ-ZHrr<;S!!(OL!7fWs!!:[N!:eV>
-!;tCI!<:UL!!^sR!7_&Leb]=JeGoUHec,XLec,XLec,UNeGoU>ec,XJec,UTeGoU"eGoU"eb]=J
-eGoU>ec,XKec,ULeb]=QeGoU"!!(R"!!%T#J^s5>s+:KNs5rIW!.Y~>
-!<E0!joV@Ys8(:G!<(IJ!!UmQ!7_&Lma_79s4.,L!n@8Nqpk]H$.T"UeGoU"eGoUIec,X>ec,XI
-ec,XLec,UTeGoU"!!(OL!;tCI!;k=H!<:UL!<:UL!!:[N!:eV>!<(IJ!".6V!7fU"!7fU"!;tCI
-!:eV>!<1OK!!:[N!;tCI!!^sR!7fU"!.i[OeaM&gK*A(Nk2s>WJ,~>
-!<E0!joV7Vs8(IL!<(XO!!V'V!87DQmb7U>s4[JQ!nmVSqqD&M$/,@Zg&M-,g&M-NgA_0CgA_0N
-gA_0QgA_-Yg&M-,!!(^Q!;tRN!;kLM!<:dQ!<:dQ!!:jS!:eeC!<(XO!".E[!8?-,!8?-,!;tRN
-!:eeC!<1^P!!:jS!;tRN!!_-W!8?-,!.ijTg@*bqJH_bIk2s5TJ,~>
-!<E0!joV@Ys8(:G!<(IJ!!UmQ!7_&Lma_79s4.,L!n@8Nqpk]H$.T"UeGoU"eGoUIec,X>ec,XI
-ec,XLec,UTeGoU"!!(OL!;tCI!;k=H!<:UL!<:UL!!:[N!:eV>!<(IJ!".6V!7fU"!7fU"!;tCI
-!:eV>!<1OK!!:[N!;tCI!!^sR!7fU"!.i[OeaM&gK*A(Nk2s>WJ,~>
-!<E0!joV@Ys8(:G!<(IJ!"%0U!7_&Le^XX"n^[X>rmh#K#1W\Re^XX"rmh#Ks4.,Lrmh#Ks4.,L
-!n@8NnC@O=s4.&Js4.,L(tATdeGoU"!!(R"!!(OL!7fU"!7fU"!7h&Ks4.,L!n@8Nn^[X>rRLoJ
-#LreSe^XX"ec#RKec,UNeGoU>ec,XKec,UVeGoU"eGoU"!!(RK!!:[N!.i[OeaM&gK*A(Nk2s>W
-J,~>
-!<E0!joV7Vs8(IL!<(XO!"%?Z!87DQg=cN,n_4!Crn@AP#20%Wg=cN,rn@APs4[JQrn@APs4[JQ
-!nmVSnCmmBs4[DOs4[JQ(tnrig&M-,!!(a,!!(^Q!8?-,!8?-,!8@DPs4[JQ!nmVSn_4!CrS%8O
-#MK.Xg=cN,gAV*PgA_-Sg&M-CgA_0PgA_-[g&M-,g&M-,!!(aP!!:jS!.ijTg@*bqJH_bIk2s5T
-J,~>
-!<E0!joV@Ys8(:G!<(IJ!"%0U!7_&Le^XX"n^[X>rmh#K#1W\Re^XX"rmh#Ks4.,Lrmh#Ks4.,L
-!n@8NnC@O=s4.&Js4.,L(tATdeGoU"!!(R"!!(OL!7fU"!7fU"!7h&Ks4.,L!n@8Nn^[X>rRLoJ
-#LreSe^XX"ec#RKec,UNeGoU>ec,XKec,UVeGoU"eGoU"!!(RK!!:[N!.i[OeaM&gK*A(Nk2s>W
-J,~>
-!<E0!joV@Ys8(:G!<(IJ!!LgP!7fWu!:\P=!<1OK!<:UJ!<(IJ!<:UL!<(IH!<:UL!:SJ:!<:UJ
-!<:UL!!LgP!7fWu!<1OI!<(IJ!<:UJ!<:UL!:eV>!<(IJ!!:[N!<1OK!<:UJ!<:UL!:eV>!<1OK
-!<:UJ!<:UL!!UmQ!7_&LJ^o>%ma_>i"f21\k.LbF~>
-!<E0!joV7Vs8(IL!<(XO!!M!U!8?0*!:\_B!<1^P!<:dO!<(XO!<:dQ!<(XM!<:dQ!:SY?!<:dO
-!<:dQ!!M!U!8?0*!<1^N!<(XO!<:dO!<:dQ!:eeC!<(XO!!:jS!<1^P!<:dO!<:dQ!:eeC!<1^P
-!<:dO!<:dQ!!V'V!87DQJ_G\/mb7\l"ektYk.1PC~>
-!<E0!joV@Ys8(:G!<(IJ!!LgP!7fWu!:\P=!<1OK!<:UJ!<(IJ!<:UL!<(IH!<:UL!:SJ:!<:UJ
-!<:UL!!LgP!7fWu!<1OI!<(IJ!<:UJ!<:UL!:eV>!<(IJ!!:[N!<1OK!<:UJ!<:UL!:eV>!<1OK
-!<:UJ!<:UL!!UmQ!7_&LJ^o>%ma_>i"f21\k.LbF~>
-!<E0!joV@Ys+/_"ec,W#eUc9:ec17*V#TT>]`<Q~>
-!<E0!joV7Vs+/n'gA_/(g4@uDgAc^-U&X9;\c@6~>
-!<E0!joV@Ys+/_"ec,W#eUc9:ec17*V#TT>]`<Q~>
-!<E0!joV@Ys+/_"ec,W#eUc9:ec17*V#TT>]`<Q~>
-!<E0!joV7Vs+/n'gA_/(g4@uDgAc^-U&X9;\c@6~>
-!<E0!joV@Ys+/_"ec,W#eUc9:ec17*V#TT>]`<Q~>
-!<E0!joV@Ys+/_"ec,W#eUc9:ec17*V#TT>]`<Q~>
-!<E0!joV7Vs+/n'gA_/(g4@uDgAc^-U&X9;\c@6~>
-!<E0!joV@Ys+/_"ec,W#eUc9:ec17*V#TT>]`<Q~>
-!<E0!joV@Ys+/^OeUc85ec17*V#TT>]`<Q~>
-!<E0!joV7Vs+/mTg4@t?gAc^-U&X9;\c@6~>
-!<E0!joV@Ys+/^OeUc85ec17*V#TT>]`<Q~>
-!<E0!joV@Ys+/^OeUc85ec17*V#TT>]`<Q~>
-!<E0!joV7Vs+/mTg4@t?gAc^-U&X9;\c@6~>
-!<E0!joV@Ys+/^OeUc85ec17*V#TT>]`<Q~>
-!<E0!joV@Ys+/^OeUc85ec17*V#TT>]`<Q~>
-!<E0!joV7Vs+/mTg4@t?gAc^-U&X9;\c@6~>
-!<E0!joV@Ys+/^OeUc85ec17*V#TT>]`<Q~>
-!<E0!joV@Ys+/^OeUc85ec17*V#TT>]`<Q~>
-!<E0!joV7Vs+/mTg4@t?gAc^-U&X9;\c@6~>
-!<E0!joV@Ys+/^OeUc85ec17*V#TT>]`<Q~>
-!<E0!joV@Ys+/^OeUc85ec17*V#TT>]`<Q~>
-!<E0!joV7Vs+/mTg4@t?gAc^-U&X9;\c@6~>
-!<E0!joV@Ys+/^OeUc85ec17*V#TT>]`<Q~>
-!<E0!joV@Ys+,fRK7SZ9K*A(Nk2s>WJ,~>
-!<E0!joV7Vs+,`PJUrB5JH_bIk2s5TJ,~>
-!<E0!joV@Ys+,fRK7SZ9K*A(Nk2s>WJ,~>
-!<E0!joM:XJV/N+JV/u8"f21\k.LbF~>
-!<E0!joM1UJUrB'JUri4"ektYk.1PC~>
-!<E0!joM:XJV/N+JV/u8"f21\k.LbF~>
-!<E0!joD3.eUc8%eW&)_V#TT>]`<Q~>
-!<E0!joD*+g4@t/g5XeiU&X9;\c@6~>
-!<E0!joD3.eUc8%eW&)_V#TT>]`<Q~>
-!<E0!joD3.eUc8%eW&)_V#TT>]`<Q~>
-!<E0!joD*+g4@t/g5XeiU&X9;\c@6~>
-!<E0!joD3.eUc8%eW&)_V#TT>]`<Q~>
-!<E0!joD3.eUc8%eW&)_V#TT>]`<Q~>
-!<E0!joD*+g4@t/g5XeiU&X9;\c@6~>
-!<E0!joD3.eUc8%eW&)_V#TT>]`<Q~>
-!<E0!joD3.eUc8%eW&)_V#TT>]`<Q~>
-!<E0!joD*+g4@t/g5XeiU&X9;\c@6~>
-!<E0!joD3.eUc8%eW&)_V#TT>]`<Q~>
-!<E0!joD3.eUc8%eW&)_V#TT>]`<Q~>
-!<E0!joD*+g4@t/g5XeiU&X9;\c@6~>
-!<E0!joD3.eUc8%eW&)_V#TT>]`<Q~>
-!<E0!joD3.eUc8%eW&)_V#TT>]`<Q~>
-!<E0!joD*+g4@t/g5XeiU&X9;\c@6~>
-!<E0!joD3.eUc8%eW&)_V#TT>]`<Q~>
-!<E0!joD3.eUc8%eW&)_V#TT>]`<Q~>
-!<E0!joD*+g4@t/g5XeiU&X9;\c@6~>
-!<E0!joD3.eUc8%eW&)_V#TT>]`<Q~>
-!<E0!joD3.eUc8%eW&)_V#TT>]`<Q~>
-!<E0!joD*+g4@t/g5XeiU&X9;\c@6~>
-!<E0!joD3.eUc8%eW&)_V#TT>]`<Q~>
-!<E0!joD3.eUc8%eW&)_V#TT>]`<Q~>
-!<E0!joD*+g4@t/g5XeiU&X9;\c@6~>
-!<E0!joD3.eUc8%eW&)_V#TT>]`<Q~>
-!<E0!joD3.eUc8%eW&)_V#TT>]`<Q~>
-!<E0!joD*+g4@t/g5XeiU&X9;\c@6~>
-!<E0!joD3.eUc8%eW&)_V#TT>]`<Q~>
-!<E0!joD3.e`#'V!;=tC!;P+E!!:[N!;k=H!9_o4!.i[Oea_/nV#TT>]`<Q~>
-!<E0!joD*+g>Uc`!;>.H!;P:J!!:jS!;kLM!9`)9!.ijTg@<l#U&X9;\c@6~>
-!<E0!joD3.e`#'V!;=tC!;P+E!!:[N!;k=H!9_o4!.i[Oea_/nV#TT>]`<Q~>
-!<E0!joD3.e`#'Y!<:UL!;G%D!;4nB!;k=H!9_o4!.i[Oea_/nV#TT>]`<Q~>
-!<E0!joD*+g>Ucc!<:dQ!;G4I!;5(G!;kLM!9`)9!.ijTg@<l#U&X9;\c@6~>
-!<E0!joD3.e`#'Y!<:UL!;G%D!;4nB!;k=H!9_o4!.i[Oea_/nV#TT>]`<Q~>
-!<E0!joD4Keb9%=eb]?&ec,XKec,XLeboLJeboLJeboLJec,UNeGoUHec,XIeboLJec,XKec,XL
-eboLJec,W#eUc9@eHMcKk2s>WJ,~>
-!<E0!joD+Hg@kRBgA:l+gA_0PgA_0QgAM$OgAM$OgAM$OgA_-Sg&M-MgA_0NgAM$OgA_0PgA_0Q
-gAM$OgA_/(g4@uJg'+2Mk2s5TJ,~>
-!<E0!joD4Keb9%=eb]?&ec,XKec,XLeboLJeboLJeboLJec,UNeGoUHec,XIeboLJec,XKec,XL
-eboLJec,W#eUc9@eHMcKk2s>WJ,~>
-!<E0!joD4KebB(DKDF't!//o&!<1OK!#X5d!7fU"!7fU"!7fU"!7fU"!7_&LeGoUHec,XJec,XL
-ec,UNeGoUKec,UUeGoU"eGoU"!!%T#J^s;@"f21\k.LbF~>
-!<E0!joD+Hg@tUIJbe%"!/0)+!<1^P!#XDi!8?-,!8?-,!8?-,!8?-,!87DQg&M-MgA_0OgA_0Q
-gA_-Sg&M-PgA_-Zg&M-,g&M-,!!%T(J_KYJ"ektYk.1PC~>
-!<E0!joD4KebB(DKDF't!//o&!<1OK!#X5d!7fU"!7fU"!7fU"!7fU"!7_&LeGoUHec,XJec,XL
-ec,UNeGoUKec,UUeGoU"eGoU"!!%T#J^s;@"f21\k.LbF~>
-!<E0!joD4Kec5[Gec19tec,XJec,UOeGoU"r;ciIr;clJquHcIr;`_FrrE&Krr<DV!!(R"!!(R"
-!!)oHrr<5Q!!(OL!;k=H!<(IJ!<:UL!<:UL!"IHY!7fU"!7fU"!7_&LJ^o>%n^Rf=s5rIW!.Y~>
-!<E0!joD+HgAh3LgAca"gA_0OgA_-Tg&M-,r;ciNr;clOquHcNr;`_KrrE&Prr<D[!!(a,!!(a,
-!!)oMrr<5V!!(^Q!;kLM!<(XO!<:dQ!<:dQ!"IW^!8?-,!8?-,!87DQJ_G\/n_+/?s5rIT!.Y~>
-!<E0!joD4Kec5[Gec19tec,XJec,UOeGoU"r;ciIr;clJquHcIr;`_FrrE&Krr<DV!!(R"!!(R"
-!!)oHrr<5Q!!(OL!;k=H!<(IJ!<:UL!<:UL!"IHY!7fU"!7fU"!7_&LJ^o>%n^Rf=s5rIW!.Y~>
-!<E0!joD4Kec5[Gec19tec,XJebT:Gec,UReGoU"eGoUJec,UReGoU"eGoTIec,XKec,ULeb]@H
-ec,XKebfCNeGoU"!!)oHrrE#JqZ-ZHrr<2P!!(R"qZ$]J!!%T#J^s;@"f21\k.LbF~>
-!<E0!joD+HgAh3LgAca"gA_0OgA1gLgA_-Wg&M-,g&M-OgA_-Wg&M-,g&M,NgA_0PgA_-QgA:mM
-gA_0PgACpSg&M-,!!)oMrrE#OqZ-ZMrr<2U!!(a,qZ$]O!!%T(J_KYJ"ektYk.1PC~>
-!<E0!joD4Kec5[Gec19tec,XJebT:Gec,UReGoU"eGoUJec,UReGoU"eGoTIec,XKec,ULeb]@H
-ec,XKebfCNeGoU"!!)oHrrE#JqZ-ZHrr<2P!!(R"qZ$]J!!%T#J^s;@"f21\k.LbF~>
-!<E0!joD4Kec5[Gec19tebfCIec#RKec,XLec,UReGoU"eGoUKec,XLec,XLec,WIec,XKec,UN
-eGoUHec,XLec,XLec,UQeGoU"!!)oHrrE#JrrDoGrW)rJrrDuIrr@W#J^s;@"f21\k.LbF~>
-!<E0!joD+HgAh3LgAca"gACpNgAV*PgA_0QgA_-Wg&M-,g&M-PgA_0QgA_0QgA_/NgA_0PgA_-S
-g&M-MgA_0QgA_0QgA_-Vg&M-,!!)oMrrE#OrrDoLrW)rOrrDuNrr@W(J_KYJ"ektYk.1PC~>
-!<E0!joD4Kec5[Gec19tebfCIec#RKec,XLec,UReGoU"eGoUKec,XLec,XLec,WIec,XKec,UN
-eGoUHec,XLec,XLec,UQeGoU"!!)oHrrE#JrrDoGrW)rJrrDuIrr@W#J^s;@"f21\k.LbF~>
-!<E0!joD4Kec5[Gec19tec,XJec,XKeb]=Heb]@GeGoUKeb]?Eec,XLec,XLec,XLec,XLec,UL
-ec#RKec,UQeGoU"!!)oHrrE#JrrE)LrrE&KrW)rJrrE)Lrr<,N!!%T#J^s;@"f21\k.LbF~>
-!<E0!joD+HgAh3LgAca"gA_0OgA_0PgA:jMgA:mLg&M-PgA:lJgA_0QgA_0QgA_0QgA_0QgA_-Q
-gAV*PgA_-Vg&M-,!!)oMrrE#OrrE)QrrE&PrW)rOrrE)Qrr<,S!!%T(J_KYJ"ektYk.1PC~>
-!<E0!joD4Kec5[Gec19tec,XJec,XKeb]=Heb]@GeGoUKeb]?Eec,XLec,XLec,XLec,XLec,UL
-ec#RKec,UQeGoU"!!)oHrrE#JrrE)LrrE&KrW)rJrrE)Lrr<,N!!%T#J^s;@"f21\k.LbF~>
-!<E0!joD4Kec5[Gec19tec,XJec,XKec,XIec,XHec,XKec,WEebfFGeboLHec,XLec#OKeboIL
-eGoUHeb]=HeboLGeGoUIeboLJec,W#eUc9@eHMcKk2s>WJ,~>
-!<E0!joD+HgAh3LgAca"gA_0OgA_0PgA_0NgA_0MgA_0PgA_/JgACsLgAM$MgA_0QgAV'PgAM!Q
-g&M-MgA:jMgAM$Lg&M-NgAM$OgA_/(g4@uJg'+2Mk2s5TJ,~>
-!<E0!joD4Kec5[Gec19tec,XJec,XKec,XIec,XHec,XKec,WEebfFGeboLHec,XLec#OKeboIL
-eGoUHeb]=HeboLGeGoUIeboLJec,W#eUc9@eHMcKk2s>WJ,~>
-!<E0!joD4Kec5[Gec19tec,XJec,XKec,XLec,UUeGoU"eGoU"!!)uJrrE)Lrr@W#J^o>%e("Vt
-s5rIW!.Y~>
-!<E0!joD+HgAh3LgAca"gA_0OgA_0PgA_0QgA_-Zg&M-,g&M-,!!)uOrrE)Qrr@W(J_G\/e(Ou!
-s5rIT!.Y~>
-!<E0!joD4Kec5[Gec19tec,XJec,XKec,XLec,UUeGoU"eGoU"!!)uJrrE)Lrr@W#J^o>%e("Vt
-s5rIW!.Y~>
-!<E0!joD4Kec5[Gec19tec,XJec,XJeboLIeboLJebfFIeboK!eUc8%e^DtOV#TT>]`<Q~>
-!<E0!joD+HgAh3LgAca"gA_0OgA_0OgAM$NgAM$OgACsNgAM#&g4@t/g="[YU&X9;\c@6~>
-!<E0!joD4Kec5[Gec19tec,XJec,XJeboLIeboLJebfFIeboK!eUc8%e^DtOV#TT>]`<Q~>
-!<E0!joD4Kec5[EK7VR(eUc8JeHMcKk2s>WJ,~>
-!<E0!joD+HgAh3JJUuO+g4@tTg'+2Mk2s5TJ,~>
-!<E0!joD4Kec5[EK7VR(eUc8JeHMcKk2s>WJ,~>
-!<E0!joD3.eUc8%eW&)_V#TT>]`<Q~>
-!<E0!joD*+g4@t/g5XeiU&X9;\c@6~>
-!<E0!joD3.eUc8%eW&)_V#TT>]`<Q~>
-!<E0!joD3.eUc8%eW&)_V#TT>]`<Q~>
-!<E0!joD*+g4@t/g5XeiU&X9;\c@6~>
-!<E0!joD3.eUc8%eW&)_V#TT>]`<Q~>
-!<E0!joD3.eUc8%eW&)_V#TT>]`<Q~>
-!<E0!joD*+g4@t/g5XeiU&X9;\c@6~>
-!<E0!joD3.eUc8%eW&)_V#TT>]`<Q~>
-!<E0!joD3.eUc8%eW&)_V#TT>]`<Q~>
-!<E0!joD*+g4@t/g5XeiU&X9;\c@6~>
-!<E0!joD3.eUc8%eW&)_V#TT>]`<Q~>
-!<E0!joD3.eUc8dec,XJeboLIeboK!e_em\V#TT>]`<Q~>
-!<E0!joD*+g4@tngA_0OgAM$NgAM#&g>CTfU&X9;\c@6~>
-!<E0!joD3.eUc8dec,XJeboLIeboK!e_em\V#TT>]`<Q~>
-!<E0!joD3.eUc8feboLIec,XLec,UReGoU"eGoT#e_ns]V#TT>]`<Q~>
-!<E0!joD*+g4@tpgAM$NgA_0QgA_-Wg&M-,g&M,(g>LZgU&X9;\c@6~>
-!<E0!joD3.eUc8feboLIec,XLec,UReGoU"eGoT#e_ns]V#TT>]`<Q~>
-!<E0!joD3.eUc8dec,XKec,XLec,UReGoU"eGoT#e_ns]V#TT>]`<Q~>
-!<E0!joD*+g4@tngA_0PgA_0QgA_-Wg&M-,g&M,(g>LZgU&X9;\c@6~>
-!<E0!joD3.eUc8dec,XKec,XLec,UReGoU"eGoT#e_ns]V#TT>]`<Q~>
-!<E0!joD3.eUc8dec,XKec,XLec,UReGoU"eGoT#e_ns]V#TT>]`<Q~>
-!<E0!joD*+g4@tngA_0PgA_0QgA_-Wg&M-,g&M,(g>LZgU&X9;\c@6~>
-!<E0!joD3.eUc8dec,XKec,XLec,UReGoU"eGoT#e_ns]V#TT>]`<Q~>
-!<E0!joD3.eUc8dec,XKec,XLec,UReGoU"eGoT#e_ns]V#TT>]`<Q~>
-!<E0!joD*+g4@tngA_0PgA_0QgA_-Wg&M-,g&M,(g>LZgU&X9;\c@6~>
-!<E0!joD3.eUc8dec,XKec,XLec,UReGoU"eGoT#e_ns]V#TT>]`<Q~>
-!<E0!joD3.eUc8dec,XKec,XLec,UReGoU"eGoT#e_ns]V#TT>]`<Q~>
-!<E0!joD*+g4@tngA_0PgA_0QgA_-Wg&M-,g&M,(g>LZgU&X9;\c@6~>
-!<E0!joD3.eUc8dec,XKec,XLec,UReGoU"eGoT#e_ns]V#TT>]`<Q~>
-!<E0!joD4Keb4Xkec,XKec,UNeGoUIec,XAeb]@,ebK2reZ77#!<1OK!<:UL!!^sR!7fU"!.i\Y
-eHMcKk2s>WJ,~>
-!<E0!joD+Hg@g*ngA_0PgA_-Sg&M-NgA_0FgA:m1gA(`"g8is-!<1^P!<:dQ!!_-W!8?-,!.ik^
-g'+2Mk2s5TJ,~>
-!<E0!joD4Keb4Xkec,XKec,UNeGoUIec,XAeb]@,ebK2reZ77#!<1OK!<:UL!!^sR!7fU"!.i\Y
-eHMcKk2s>WJ,~>
-!<E0!joD4Keb=[rs7t4F!<1OK!;Y1F!;+hA!8Q-)!.i\!ec,XKec,XLec,UReGoU"eGoT#e_ns]
-V#TT>]`<Q~>
-!<E0!joD+Hg@p-us7tCK!<1^P!;Y@K!;,"F!8Q<.!.ik&gA_0PgA_0QgA_-Wg&M-,g&M,(g>LZg
-U&X9;\c@6~>
-!<E0!joD4Keb=[rs7t4F!<1OK!;Y1F!;+hA!8Q-)!.i\!ec,XKec,XLec,UReGoU"eGoT#e_ns]
-V#TT>]`<Q~>
-!<E0!joD4Kec19uXT/=rec,XKec,UWeGoU"eGoU"!!(R"r;c]ErrE#Jrr</O!!(RJ!<:RM!7h&K
-!7h&Kp!s'BrRLiHJ^q!TrrE#Jr;ciIr;_E!hphn+s5rIW!.Y~>
-!<E0!joD+HgAca#0`V1KgA_0PgA_-\g&M-,g&M-,!!(a,r;c]JrrE#Orr</T!!(aO!<:aR!8@DP
-!8@DPp"KEGrS%2MJ_I?^rrE#Or;ciNr;_E&hqA7-s5rIT!.Y~>
-!<E0!joD4Kec19u@fQK(ec,XKec,UWeGoU"eGoU"!!(R"r;c]ErrE#Jrr</O!!(RJ!<:RM!7h&K
-!7h&Kp!s'BrRLiHJ^q!TrrE#Jr;ciIr;_E!hphn+s5rIW!.Y~>
-!<E0!joD4Kec19uXT/=rec,XKec,UReGoU"!!(RK!!^sR!7fU"!;k=H!<(IE!<:UL!".6V!7fU"
-!7fU"!;=tC!<1OK!<:UL!.i[OeUc9MeHMcKk2s>WJ,~>
-!<E0!joD+HgAca#0`V1KgA_0PgA_-Wg&M-,!!(aP!!_-W!8?-,!;kLM!<(XJ!<:dQ!".E[!8?-,
-!8?-,!;>.H!<1^P!<:dQ!.ijTg4@uWg'+2Mk2s5TJ,~>
-!<E0!joD4Kec19u@fQK(ec,XKec,UReGoU"!!(RK!!^sR!7fU"!;k=H!<(IE!<:UL!".6V!7fU"
-!7fU"!;=tC!<1OK!<:UL!.i[OeUc9MeHMcKk2s>WJ,~>
-!<E0!joD4Kec19uXT/=rebT7WeGoU"!!(R"!!(OL!7fU"!;k=E!!(RK!<:UL!<:UL!"7<W!7fU"
-!7fU"!7grHrRLoJrmh#Ks4.,LJ^o>%J^sbM"f21\k.LbF~>
-!<E0!joD+HgAca#0`V1KgA1d\g&M-,!!(a,!!(^Q!8?-,!;kLJ!!(aP!<:dQ!<:dQ!"7K\!8?-,
-!8?-,!8@;MrS%8Orn@APs4[JQJ_G\/J_L+W"ektYk.1PC~>
-!<E0!joD4Kec19u@fQK(ebT7WeGoU"!!(R"!!(OL!7fU"!;k=E!!(RK!<:UL!<:UL!"7<W!7fU"
-!7fU"!7grHrRLoJrmh#Ks4.,LJ^o>%J^sbM"f21\k.LbF~>
-!<E0!joD4Kec19uXT/=rec,XKec,UVeGoU"!!(R"!!(RH!;k=H!<(IJ!<1OK!<:UL!".6V!7fU"
-!7fU"!;=tC!<1OK!<:UL!.i[OeUc9MeHMcKk2s>WJ,~>
-!<E0!joD+HgAca#0`V1KgA_0PgA_-[g&M-,!!(a,!!(aM!;kLM!<(XO!<1^P!<:dQ!".E[!8?-,
-!8?-,!;>.H!<1^P!<:dQ!.ijTg4@uWg'+2Mk2s5TJ,~>
-!<E0!joD4Kec19u@fQK(ec,XKec,UVeGoU"!!(R"!!(RH!;k=H!<(IJ!<1OK!<:UL!".6V!7fU"
-!7fU"!;=tC!<1OK!<:UL!.i[OeUc9MeHMcKk2s>WJ,~>
-!<E0!joD4Kec19uXT/=rec,XKec,UXeGoU"!!(R"!!(OL!;G%D!<(IJ!<1OK!<:UL!"7<W!7fU"
-!7fU"!7grHrRLoJrmh#Ks4.,LJ^o>%J^sbM"f21\k.LbF~>
-!<E0!joD+HgAca#0`V1KgA_0PgA_-]g&M-,!!(a,!!(^Q!;G4I!<(XO!<1^P!<:dQ!"7K\!8?-,
-!8?-,!8@;MrS%8Orn@APs4[JQJ_G\/J_L+W"ektYk.1PC~>
-!<E0!joD4Kec19u@fQK(ec,XKec,UXeGoU"!!(R"!!(OL!;G%D!<(IJ!<1OK!<:UL!"7<W!7fU"
-!7fU"!7grHrRLoJrmh#Ks4.,LJ^o>%J^sbM"f21\k.LbF~>
-!<E0!joD4Kec19uXT/=rec,XKec,UReGoU"!!(RK!!^sR!7fU"!;k=H!<(IJ!<1OK!<:UL!".6V
-!7fU"!7fU"!;=tC!<1OK!<:UL!.i[OeUc9MeHMcKk2s>WJ,~>
-!<E0!joD+HgAca#0`V1KgA_0PgA_-Wg&M-,!!(aP!!_-W!8?-,!;kLM!<(XO!<1^P!<:dQ!".E[
-!8?-,!8?-,!;>.H!<1^P!<:dQ!.ijTg4@uWg'+2Mk2s5TJ,~>
-!<E0!joD4Kec19u@fQK(ec,XKec,UReGoU"!!(RK!!^sR!7fU"!;k=H!<(IJ!<1OK!<:UL!".6V
-!7fU"!7fU"!;=tC!<1OK!<:UL!.i[OeUc9MeHMcKk2s>WJ,~>
-!<E0!joD4Kec19uXT/=rec,XKec,UWeGoU"eGoU"!!(R"r;c]ErrE#JrrE#Jr;clJrrE)LrrE)L
-rrDcCrrE#Jr;bI"JV1dkJ^rr6"f21\k.LbF~>
-!<E0!joD+HgAca#0`V1KgA_0PgA_-\g&M-,g&M-,!!(a,r;c]JrrE#OrrE#Or;clOrrE)QrrE)Q
-rrDcHrrE#Or;bI'JUtXgJ_K;@"ektYk.1PC~>
-!<E0!joD4Kec19u@fQK(ec,XKec,UWeGoU"eGoU"!!(R"r;c]ErrE#JrrE#Jr;clJrrE)LrrE)L
-rrDcCrrE#Jr;bI"JV1dkJ^rr6"f21\k.LbF~>
-!<E0!joD4Kec19ss+/]#eU`@iK)kq&e`YHdV#TT>]`<Q~>
-!<E0!joD+HgAca!s+/l(g4=glJH5_$g?7/nU&X9;\c@6~>
-!<E0!joD4Kec19ss+/]#eU`@iK)kq&e`YHdV#TT>]`<Q~>
-!<E0!joD3.e`YK_K7U_r^#B!Be`YHdV#TT>]`<Q~>
-!<E0!joD*+g?72iJUt\u_VtNGg?7/nU&X9;\c@6~>
-!<E0!joD3.e`YK_K7U_r^#B!Be`YHdV#TT>]`<Q~>
-!<E0!joD3.e`YK_K7U_r^#]1pKE(t&e`YHdV#TT>]`<Q~>
-!<E0!joD*+g?72iJUt\u_W:^uJcGb$g?7/nU&X9;\c@6~>
-!<E0!joD3.e`YK_K7U_r^#]1pKE(t&e`YHdV#TT>]`<Q~>
-!<E0!joD3.e`YK_K7U_r^&S-*eH(=&p!s(ps8RZ#kLBa3s5rIW!.Y~>
-!<E0!joD*+g?72iJUt\u_Z0Z/g&Zd)p"KFss8RZ(kLp*5s5rIT!.Y~>
-!<E0!joD3.e`YK_K7U_r^&S-*eH(=&p!s(ps8RZ#kLBa3s5rIW!.Y~>
-!<E0!joD3.e`YK_K7U_r^&S-*eH(=&p!s(ps8RZ#kLBa3s5rIW!.Y~>
-!<E0!joD*+g?72iJUt\u_Z0Z/g&Zd)p"KFss8RZ(kLp*5s5rIT!.Y~>
-!<E0!joD3.e`YK_K7U_r^&S-*eH(=&p!s(ps8RZ#kLBa3s5rIW!.Y~>
-!<E0!joD3.e`YK_K7U_r^&S-*eH(=&p!s(ps8RZ#kLBa3s5rIW!.Y~>
-!<E0!joD*+g?72iJUt\u_Z0Z/g&Zd)p"KFss8RZ(kLp*5s5rIT!.Y~>
-!<E0!joD3.e`YK_K7U_r^&S-*eH(=&p!s(ps8RZ#kLBa3s5rIW!.Y~>
-!<E0!joD3.e`YK_K7U_r^&S-*eH(=&p!s(ps8RZ#kLBa3s5rIW!.Y~>
-!<E0!joD*+g?72iJUt\u_Z0Z/g&Zd)p"KFss8RZ(kLp*5s5rIT!.Y~>
-!<E0!joD3.e`YK_K7U_r^&S-*eH(=&p!s(ps8RZ#kLBa3s5rIW!.Y~>
-!<E0!joD3.e`YK_K7U_r^&S-*eH(=&p!s(ps8RZ#kLBa3s5rIW!.Y~>
-!<E0!joD*+g?72iJUt\u_Z0Z/g&Zd)p"KFss8RZ(kLp*5s5rIT!.Y~>
-!<E0!joD3.e`YK_K7U_r^&S-*eH(=&p!s(ps8RZ#kLBa3s5rIW!.Y~>
-!<E0!joD3.e`YK_K7U_r^&S-*eH(=&p!s(ps8RZ#kLBa3s5rIW!.Y~>
-!<E0!joD*+g?72iJUt\u_Z0Z/g&Zd)p"KFss8RZ(kLp*5s5rIT!.Y~>
-!<E0!joD3.e`YK_K7U_r^&S-*eH(=&p!s(ps8RZ#kLBa3s5rIW!.Y~>
-!<E0!joD3.e`YK_K7U_r^&S-*eH(=&p!s(ps8RZ#kLBa3s5rIW!.Y~>
-!<E0!joD*+g?72iJUt\u_Z0Z/g&Zd)p"KFss8RZ(kLp*5s5rIT!.Y~>
-!<E0!joD3.e`YK_K7U_r^&S-*eH(=&p!s(ps8RZ#kLBa3s5rIW!.Y~>
-!<E0!joD3.e`YK_K7U_r^&S-*eH(=&p!s(ps8RZ#kLBa3s5rIW!.Y~>
-!<E0!joD*+g?72iJUt\u_Z0Z/g&Zd)p"KFss8RZ(kLp*5s5rIT!.Y~>
-!<E0!joD3.e`YK_K7U_r^&S-*eH(=&p!s(ps8RZ#kLBa3s5rIW!.Y~>
-!<E0!joD4Keb9%=ec,XKec,UNeGoUIec,XAec,XKec,XFec,WYec18Q^#Qg+s7OnCKE(Vps+C@O
-J^rr6"f21\k.LbF~>
-!<E0!joD+Hg@kRBgA_0PgA_-Sg&M-NgA_0FgA_0PgA_0KgA_/^gAc_T_W/N5s7P(HJcGDss+14M
-J_K;@"ektYk.1PC~>
-!<E0!joD4Keb9%=ec,XKec,UNeGoUIec,XAec,XKec,XFec,WYec18Q^#Qg+s7OnCKE(Vps+C@O
-J^rr6"f21\k.LbF~>
-!<E0!joD4KebB(DKDF't!<1OK!;Y1F!;+hA!<1OK!;Y1F!4UMYK7U_r^&S-*eH(=&p!s(ps8RZ#
-kLBa3s5rIW!.Y~>
-!<E0!joD+Hg@tUIJbe%"!<1^P!;Y@K!;,"F!<1^P!;Y@K!4U\^JUt\u_Z0Z/g&Zd)p"KFss8RZ(
-kLp*5s5rIT!.Y~>
-!<E0!joD4KebB(DKDF't!<1OK!;Y1F!;+hA!<1OK!;Y1F!4UMYK7U_r^&S-*eH(=&p!s(ps8RZ#
-kLBa3s5rIW!.Y~>
-!<E0!joD4Kec5[Gec19tec,XKec,UWeGoU"eGoU"!!(R"r;c]ErrE&Krr<__!!(OL!7fU"!7fU"
-!7_&LeGoUKeboLJec,XLec,XLec,UQeGoU"!!(a's+>m9j1YKmp!j(qs7OqBKE(t&e`YHdV#TT>
-]`<Q~>
-!<E0!joD+HgAh3LgAca"gA_0PgA_-\g&M-,g&M-,!!(a,r;c]JrrE&Prr<_d!!(^Q!8?-,!8?-,
-!87DQg&M-PgAM$OgA_0QgA_0QgA_-Vg&M-,!!(a,s+,a<j21irp"BFts7P+GJcGb$g?7/nU&X9;
-\c@6~>
-!<E0!joD4Kec5[Gec19tec,XKec,UWeGoU"eGoU"!!(R"r;c]ErrE&Krr<__!!(OL!7fU"!7fU"
-!7_&LeGoUKeboLJec,XLec,XLec,UQeGoU"!!(a's+>m9j1YKmp!j(qs7OqBKE(t&e`YHdV#TT>
-]`<Q~>
-!<E0!joD4Kec5[Gec19tec,XKec,UReGoU"!!(RK!!^sR!7fU"!;k=H!<1OK!!(RK!".6V!7_&L
-eGoU"ec#O`eGoU"!!(R"!!(OL!7fU"!7fU"!7h&K!n@8NgXZ=VJ\C*Ws8V_D!<;YCs8RZ#kLBa3
-s5rIW!.Y~>
-!<E0!joD+HgAh3LgAca"gA_0PgA_-Wg&M-,!!(aP!!_-W!8?-,!;kLM!<1^P!!(aP!".E[!87DQ
-g&M-,gAV'eg&M-,!!(a,!!(^Q!8?-,!8?-,!8@DP!nmVSgY2[YJ\pHas8V_B!<;YAs8RZ(kLp*5
-s5rIT!.Y~>
-!<E0!joD4Kec5[Gec19tec,XKec,UReGoU"!!(RK!!^sR!7fU"!;k=H!<1OK!!(RK!".6V!7_&L
-eGoU"ec#O`eGoU"!!(R"!!(OL!7fU"!7fU"!7h&K!n@8NgXZ=VJ\C*Ws8V_D!<;YCs8RZ#kLBa3
-s5rIW!.Y~>
-!<E0!joD4Kec5[Gec19tebT7WeGoU"!!(R"!!(OL!7fU"!;k=H!<1OK!!h$S!7fU"!7h#Jrmh#K
-s4.,L(tATde^XX"e^XX"eGoU"!!(R"!!(R"!!(d(s+>m9j1PHmjFdL4J^rr6"f21\k.LbF~>
-!<E0!joD+HgAh3LgAca"gA1d\g&M-,!!(a,!!(^Q!8?-,!;kLM!<1^P!!h3X!8?-,!8@AOrn@AP
-s4[JQ(tnrig=cN,g=cN,g&M-,!!(a,!!(a,!!(d-s+,a<j2(frjFR@2J_K;@"ektYk.1PC~>
-!<E0!joD4Kec5[Gec19tebT7WeGoU"!!(R"!!(OL!7fU"!;k=H!<1OK!!h$S!7fU"!7h#Jrmh#K
-s4.,L(tATde^XX"e^XX"eGoU"!!(R"!!(R"!!(d(s+>m9j1PHmjFdL4J^rr6"f21\k.LbF~>
-!<E0!joD4Kec5[Gec19tec,XKec,UVeGoU"!!(R"!!(RH!;k=H!<1OK!!h$S!7fU"!7h#Jrmh#K
-s4.,L(tATde^XX"e^XX"eGoU"!!(R"!!(R"!!(d(s+>n&_uG;<kLBa3s5rIW!.Y~>
-!<E0!joD+HgAh3LgAca"gA_0PgA_-[g&M-,!!(a,!!(aM!;kLM!<1^P!!h3X!8?-,!8@AOrn@AP
-s4[JQ(tnrig=cN,g=cN,g&M-,!!(a,!!(a,!!(d-s+,b$_uG;AkLp*5s5rIT!.Y~>
-!<E0!joD4Kec5[Gec19tec,XKec,UVeGoU"!!(R"!!(RH!;k=H!<1OK!!h$S!7fU"!7h#Jrmh#K
-s4.,L(tATde^XX"e^XX"eGoU"!!(R"!!(R"!!(d(s+>n&_uG;<kLBa3s5rIW!.Y~>
-!<E0!joD4Kec5[Gec19tec,XKec,UXeGoU"!!(R"!!(OL!;G%D!<1OK!%l_$!7fU"!7_&LeGoU"
-eGoU"eGoU"!!(R"!!(R"!!(OL!7_&Le^XX"e^XX"gXQ:VJcEUeJ^rr6"f21\k.LbF~>
-!<E0!joD+HgAh3LgAca"gA_0PgA_-]g&M-,!!(a,!!(^Q!;G4I!<1^P!%ln)!8?-,!87DQg&M-,
-g&M-,g&M-,!!(a,!!(a,!!(^Q!87DQg=cN,g=cN,gY)XYJcEUeJ_K;@"ektYk.1PC~>
-!<E0!joD4Kec5[Gec19tec,XKec,UXeGoU"!!(R"!!(OL!;G%D!<1OK!%l_$!7fU"!7_&LeGoU"
-eGoU"eGoU"!!(R"!!(R"!!(OL!7_&Le^XX"e^XX"gXQ:VJcEUeJ^rr6"f21\k.LbF~>
-!<E0!joD4Kec5[Gec19tec,XKec,UReGoU"!!(RK!!^sR!7fU"!;b7G!$B_k!7fU"!7fU"!7_&L
-e^XX"eGoU"eGoU"!!(R"!!*#KrrE)LrrE&KrrE)Lrr@W#J^o>%"f21\k.LbF~>
-!<E0!joD+HgAh3LgAca"gA_0PgA_-Wg&M-,!!(aP!!_-W!8?-,!;bFL!$Bnp!8?-,!8?-,!87DQ
-g=cN,g&M-,g&M-,!!(a,!!*#PrrE)QrrE&PrrE)Qrr@W(J_G\/"ektYk.1PC~>
-!<E0!joD4Kec5[Gec19tec,XKec,UReGoU"!!(RK!!^sR!7fU"!;b7G!$B_k!7fU"!7fU"!7_&L
-e^XX"eGoU"eGoU"!!(R"!!*#KrrE)LrrE&KrrE)Lrr@W#J^o>%"f21\k.LbF~>
-!<E0!joD4Kec5[Gec19tec,XKec,UWeGoU"eGoU"!!(R"r;cZDquHcIrrE)Lrr<,N!!*#Kr;clJ
-rrE)Lr;cfHrrE)LrrE&KrrE)Lrr@W#J^o>%"f21\k.LbF~>
-!<E0!joD+HgAh3LgAca"gA_0PgA_-\g&M-,g&M-,!!(a,r;cZIquHcNrrE)Qrr<,S!!*#Pr;clO
-rrE)Qr;cfMrrE)QrrE&PrrE)Qrr@W(J_G\/"ektYk.1PC~>
-!<E0!joD4Kec5[Gec19tec,XKec,UWeGoU"eGoU"!!(R"r;cZDquHcIrrE)Lrr<,N!!*#Kr;clJ
-rrE)Lr;cfHrrE)LrrE&KrrE)Lrr@W#J^o>%"f21\k.LbF~>
-!<E0!joD4Kec5[EK7VR(eUc8JeHMcKk2s>WJ,~>
-!<E0!joD+HgAh3JJUuO+g4@tTg'+2Mk2s5TJ,~>
-!<E0!joD4Kec5[EK7VR(eUc8JeHMcKk2s>WJ,~>
-!<E0!joD3.eUc8%eW&)_V#TT>]`<Q~>
-!<E0!joD*+g4@t/g5XeiU&X9;\c@6~>
-!<E0!joD3.eUc8%eW&)_V#TT>]`<Q~>
-!<E0!joD3.eUc8%eY^mbKDX1&V#TT>]`<Q~>
-!<E0!joD*+g4@t/g8<TlJc".)U&X9;\c@6~>
-!<E0!joD3.eUc8%eY^mbKDX1&V#TT>]`<Q~>
-!<E0!joD3.eUc8%eY^mcK)krKeHMcKk2s>WJ,~>
-!<E0!joD*+g4@t/g8<TmJH5`Ig'+2Mk2s5TJ,~>
-!<E0!joD3.eUc8%eY^mcK)krKeHMcKk2s>WJ,~>
-!<E0!joD3.eUc8%eY^msKDN7]KDN:]s81=MV#TT>]`<Q~>
-!<E0!joD*+g4@t/g8<U(Jbm4`Jbm7`s81LRU&X9;\c@6~>
-!<E0!joD3.eUc8%eY^msKDN7]KDN:]s81=MV#TT>]`<Q~>
-!<E0!joD3.eUc8%eY^msKDW=_s+C0]s8VuH"f21\k.LbF~>
-!<E0!joD*+g4@t/g8<U(Jc!:bs+1$`s8VuM"ektYk.1PC~>
-!<E0!joD3.eUc8%eY^msKDW=_s+C0]s8VuH"f21\k.LbF~>
-!<E0!joD3.eUc8%eY^msKDW=`s+>t$^&S-0eHMcKk2s>WJ,~>
-!<E0!joD*+g4@t/g8<U(Jc!:cs+,au_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD3.eUc8%eY^msKDW=`s+>t$^&S-0eHMcKk2s>WJ,~>
-!<E0!joD3.eUc8%eY^msKD`F_s8R`K^&S-0eHMcKk2s>WJ,~>
-!<E0!joD*+g4@t/g8<U(Jc*Cbs8RZI_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD3.eUc8%eY^msKD`F_s8R`K^&S-0eHMcKk2s>WJ,~>
-!<E0!joD3.eUc8%eY^msKD`F_rrU`'KD`F_s81=MV#TT>]`<Q~>
-!<E0!joD*+g4@t/g8<U(Jc*CbrrUo*Jc*Cbs81LRU&X9;\c@6~>
-!<E0!joD3.eUc8%eY^msKD`F_rrU`'KD`F_s81=MV#TT>]`<Q~>
-!<E0!joD3.eUc8%eY^msKDiL`s8UXLKD`F_s81=MV#TT>]`<Q~>
-!<E0!joD*+g4@t/g8<U(Jc3Ics8UgQJc*Cbs81LRU&X9;\c@6~>
-!<E0!joD3.eUc8%eY^msKDiL`s8UXLKD`F_s81=MV#TT>]`<Q~>
-!<E0!joD3.eUc8%eY^msKDiL`s8LRKKDiL`s81=MV#TT>]`<Q~>
-!<E0!joD*+g4@t/g8<U(Jc3Ics8LaPJc3Ics81LRU&X9;\c@6~>
-!<E0!joD3.eUc8%eY^msKDiL`s8LRKKDiL`s81=MV#TT>]`<Q~>
-!<E0!joD3.eUc8%eY^msKDrRas8CLJKDiL`s81=MV#TT>]`<Q~>
-!<E0!joD*+g4@t/g8<U(Jc<Ods8C[OJc3Ics81LRU&X9;\c@6~>
-!<E0!joD3.eUc8%eY^msKDrRas8CLJKDiL`s81=MV#TT>]`<Q~>
-!<E0!joD3.eUc8%eY^msKDrRas8:FIKDrRas81=MV#TT>]`<Q~>
-!<E0!joD*+g4@t/g8<U(Jc<Ods8:UNJc<Ods81LRU&X9;\c@6~>
-!<E0!joD3.eUc8%eY^msKDrRas8:FIKDrRas81=MV#TT>]`<Q~>
-!<E0!joD3.eUc8%eY^msKE&Xbs81@HKDrRas81=MV#TT>]`<Q~>
-!<E0!joD*+g4@t/g8<U(JcEUes81OMJc<Ods81LRU&X9;\c@6~>
-!<E0!joD3.eUc8%eY^msKE&Xbs81@HKDrRas81=MV#TT>]`<Q~>
-!<E0!joD3.eUc8%eY^msKE&Xbs8(:GKE&Xbs81=MV#TT>]`<Q~>
-!<E0!joD*+g4@t/g8<U(JcEUes8(ILJcEUes81LRU&X9;\c@6~>
-!<E0!joD3.eUc8%eY^msKE&Xbs8(:GKE&Xbs81=MV#TT>]`<Q~>
-!<E0!joD4>eH#X+eH#XIeH#WVeH#X+eH#XIeH#XIec,TWec5[IeH#XCeH#X%eH#XIec5ZpeH#X=
-ec5[Jec5Zkec17'^&S-.ec1:%^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+;g&M-0g&M-Ng&M,[g&M-0g&M-Ng&M-NgAV)\gA_0Ng&M-Hg&M-*g&M-NgA_/ug&M-B
-gA_0OgA_/pgAc^*_Z0Z3gAca(_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4>eGoU+eGoUIeGoTVeGoU+eGoUIeGoUIec#QWec,XIeGoUCeGoU%eGoUIec,WpeGoU=
-ec,XJec,Wkec17'^&S-.ec1:%^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4>eH#X+eH#XIeH#WVeH#X+eH#XIeH#XJeH#XKeH#WXeH#WaeH#WpeH#X<eH#XIeH#Wk
-ec17'^&S--ec17'^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+;g&M-0g&M-Ng&M,[g&M-0g&M-Ng&M-Og&M-Pg&M,]g&M,fg&M,ug&M-Ag&M-Ng&M,p
-gAc^*_Z0Z2gAc^*_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4>eGoU+eGoUIeGoTVeGoU+eGoUIeGoUJeGoUKeGoTXeGoTaeGoTpeGoU<eGoUIeGoTk
-ec17'^&S--ec17'^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4Jec5XPec42"s8CLHs8LRKs8UUTs4./"s8UXLs8LRKrrUaNs7t4Ds8UXJs2*=drrgmP
-ec5[Jec#OIec5[LeHl3*s4./Lec5[Kec5XNec5[Fec#OJec#LMec41Mr;QiKs8W)Krr;uJs8W)K
-!WU^Ls5VW3s4./Lrm_&Lec,UKec5[IeH#XJec5[Lec5XMec5Tus8W,L"96pOs8LRKs8CIKs4.&I
-!nI>NqUPWG!S.5Kec5[Jec,U,ec5[Jec5[LeH>j%s8W)KrVuoJ!WU^Ls8UXLs8:CIs8:CIs8CLJ
-s8LOLs4.,Kf@BnRs8VbE!knX6qpbkGs5rIW!.Y~>
-!<E0!joD+GgA_-Ug&Th,!<(XM!<1^P!<:aY!87G,!!(^Q!<1^P!!:jS!;Y@I!<:dO!5dIi!!M!U
-g&M-OgAM$NgA_0Qg'@]4!87DQg&M-PgA_-Sg&M-KgAM$OgAM!Rg&Tj\qu?fP!!*#PrW)rOrrE&P
-!<CjQ!9;c8!87DQrn7AQgAV*PgA_0Ng&M-OgA_0QgA_-Rg&V**rrE)Q!s%$T!<1^P!<(UP!8@>N
-!nmVSqV(rL!SRPPgA_0OgAV*1gA_0OgA_0Qg&h?/!!*#Pr;clO!<CjQ!<:dQ!;tON!;tON!<(XO
-!<1[Q!8@DPf@p7Us8VbC!lG!;qq;4Is5rIT!.Y~>
-!<E0!joD4Jec,UPeH","!<(IH!<1OK!<:RT!7_)"!!(OL!<1OK!!:[N!;Y1D!<:UJ!5d:d!!LgP
-eGoUJeboLIec,XLeHc0*!7_&LeGoUKec,UNeGoUFeboLJeboIMeH".Mqu?fK!!*#KrW)rJrrE&K
-!<C[L!9;T3!7_&Lrm_#Lec#RKec,XIeGoUJec,XLec,UMeH#QurrE)L!s$jO!<1OK!<(FK!7guI
-!n@8NqUPTG!S%2Kec,XJec#R,ec,XJec,XLeH5g%!!*#Kr;clJ!<C[L!<:UL!;t@I!;t@I!<(IJ
-!<1LL!7h&Kf@BnRs8VbE!knX6qpbkGs5rIW!.Y~>
-!<E0!joD4KeH>j%ec5Tu!<<#J!<<#J$3/Q+s4./"s4./JeH#XKeH>j%ec5Ep!<;uI!<9mc"96p%
-s8CIJs8CIJs8CISs4,["ec42"ec5Tu!<<&K"96p%s7k+Es8:CIs8LOXs4./"s4,["e^a]Mec5Qt
-"96p%s8LOKs52?/s4,["rm_#KrRD#Me^a]ueH#XIeHc-)ec42"ec5Tu!<<&K"96p%s8CIJs8CIJ
-s8CIMs4,["qUG`Kec42"rRCoJrm_,Ne^a]YeIV]1ec41Ms4,["e^a]Mec5X!!<;uI!<<#J"96p%
-s8CIJs8:CIs8LONs4,["rm_#KeCFSO!<;YCs8VuH"f21\k.LbF~>
-!<E0!joD+Hg&h?/g&V**!!)uO!!)uO#lr]5!87G,!87GOg&M-Pg&h?/g&Up%!!)rN!!'jh!s%'/
-!<(UO!<(UO!<(UX!8?-,g&Th,g&V**!!*#P!s%'/!;P7J!;tON!<1[]!87G,!8?-,g=cP\g&V')
-!s%'/!<1[P!8lK4!8?-,rn7>PrRq>Rg=cQ*g&M-Ng'7W3g&Th,g&V**!!*#P!s%'/!<(UO!<(UO
-!<(UR!8?-,qUu&Pg&Th,rRq5Orn7GSg=cPcg(+2;g&Tj\!8?-,g=cP\g&V-+!!)rN!!)uO!s%'/
-!<(UO!;tON!<1[S!8?-,rn7>PeCsqR!<;YAs8VuM"ektYk.1PC~>
-!<E0!joD4KeH5g%eH#Qu!!)uJ!!)uJ#lrN+!7_)"!7_)JeGoUKeH5g%eH#Bp!!)rI!!'jc!s$m%
-!<(FJ!<(FJ!<(FS!7fU"eH","eH#Qu!!*#K!s$m%!;P(E!;t@I!<1LX!7_)"!7fU"e^XZMeH#Nt
-!s$m%!<1LK!8l</!7fU"rm^uKrRCuMe^XZueGoUIeHZ*)eH","eH#Qu!!*#K!s$m%!<(FJ!<(FJ
-!<(FM!7fU"qUG]KeH","rRClJrm_)Ne^XZYeIMZ1eH".M!7fU"e^XZMeH#U!!!)rI!!)uJ!s$m%
-!<(FJ!;t@I!<1LN!7fU"rm^uKeCFSO!<;YCs8VuH"f21\k.LbF~>
-!<E0!joD4KeHQ!'ec41Mrr;rI!<<#Jrr<#K#636Rec41Mrr;uJ"96p%s7k+Es8:CIs2!4hs4,["
-e^a[!rRCoJrRLoIs4%>Rec42"e^a[!rm_,Ne^a]peH#XIeH#XKeI)?,s4./"ec41Ms8LRKs8LRJ
-s8CIJs52?/s4,["rm_#KrRLoIr7(fIr7)&Pe^a]Ms4./JeH#XKeHQ!'ec41Mrr;rI!<<#J"96p%
-s8(7Ks4./"s8CIJs8LONs4,["iRIr.r7),Re^a]Mec41Ms8LOKs8:CIs8CIMs4,["rRCoJr7(fI
-rmh#JrRCoJeCFSOo"G)'qpbkGs5rIW!.Y~>
-!<E0!joD+Hg'%K1g&Tj\rW)oN!!)uOrW)uP"p!?Wg&Tj\rW)rO!s%'/!;P7J!;tON!5[@m!8?-,
-g=lN+rRq5OrS%5Ns4RYWg&Th,g=lN+rn7GSg=cQ%g&M-Ng&M-Pg'Ri6!87G,g&Tj\!<1^P!<1^O
-!<(UO!8lK4!8?-,rn7>PrS%5Nr7V,Nr7VAUg=cP\!87GOg&M-Pg'%K1g&Tj\rW)oN!!)uO!s%'/
-!;bCP!87G,!<(UO!<1[S!8?-,iS"83r7VGWg=cP\g&Tj\!<1[P!;tON!<(UR!8?-,rRq5Or7V,N
-rn@>OrRq5OeCsqRo"tG,qq;4Is5rIT!.Y~>
-!<E0!joD4KeHGs'eH".MrW)oI!!)uJrW)uK"p!0ReH".MrW)rJ!s$m%!;P(E!;t@I!5[1h!7fU"
-e^aX!rRClJrRLlIs4%;ReH","e^aX!rm_)Ne^XZpeGoUIeGoUKeHu<,!7_)"eH".M!<1OK!<1OJ
-!<(FJ!8l</!7fU"rm^uKrRLlIr7(cIr7)#Pe^XZM!7_)JeGoUKeHGs'eH".MrW)oI!!)uJ!s$m%
-!;b4K!7_)"!<(FJ!<1LN!7fU"iRIo.r7))Re^XZMeH".M!<1LK!;t@I!<(FM!7fU"rRClJr7(cI
-rmguJrRClJeCFSOo"G)'qpbkGs5rIW!.Y~>
-!<E0!joD4KeHl3*ec42"e^a]ueJ%u5ec42"e^a]Mec42"e^a]Mec5X!"96p%s7k+Ns4,["e^a]M
-ec3S<#liH*s4./"ec5Tu'E?V5s4./"ec41Ms4./"ec41Ms8LONs4,["psffQe^a]Mec41Ms8UX"
-rr3,Os4,["r7)#Oe^a]Mec5X!!<:s,"96p%s8LOKs8CIMs4,["rRCoJr7)&Pe^a]Ms4./JeH#XK
-eHl3*ec42"e^a]ueH#XJeH>j%ec5Kr"TR$Pec5Tu!<<&K"96p%s5DK=s4,["e^a]Mec41Ms4,["
-rm_5Qe^a]Mec5Tu"96p%s8CIJs8:CIs8LONs4,["rm_#KeCFSOnGiC9"f21\k.LbF~>
-!<E0!joD+Hg'@]4g&Th,g=cQ*g(OJ?g&Th,g=cP\g&Th,g=cP\g&V-+!s%'/!;P7S!8?-,g=cP\
-g&T(F#QWT4!87G,g&V**'*-b?!87G,g&Tj\!87G,g&Tj\!<1[S!8?-,pt?,Vg=cP\g&Tj\!!(a,
-rW!)T!8?-,r7V>Tg=cP\g&V-+!!(p1!s%'/!<1[P!<(UR!8?-,rRq5Or7VAUg=cP\!87GOg&M-P
-g'@]4g&Th,g=cQ*g&M-Og&h?/g&V!'"9@-Ug&V**!!*#P!s%'/!9)WB!8?-,g=cP\g&Tj\!8?-,
-rn7PVg=cP\g&V**!s%'/!<(UO!;tON!<1[S!8?-,rn7>PeCsqRnGiC>"ektYk.1PC~>
-!<E0!joD4KeHc0*eH","e^XZueIqr5eH","e^XZMeH","e^XZMeH#U!!s$m%!;P(N!7fU"e^XZM
-eH!P<#QWE*!7_)"eH#Qu'*-S5!7_)"eH".M!7_)"eH".M!<1LN!7fU"psfcQe^XZMeH".M!!(R"
-rW!)O!7fU"r7(uOe^XZMeH#U!!!(p,!s$m%!<1LK!<(FM!7fU"rRClJr7)#Pe^XZM!7_)JeGoUK
-eHc0*eH","e^XZueGoUJeH5g%eH#Hr"9?sPeH#Qu!!*#K!s$m%!9)H=!7fU"e^XZMeH".M!7fU"
-rm_2Qe^XZMeH#Qu!s$m%!<(FJ!;t@I!<1LN!7fU"rm^uKeCFSOnGiC9"f21\k.LbF~>
-!<E0!joD4Jec,UKec5XMec5Tus8W)Ks8W)K!rpgNrmh&K!S.5Lec5[Cec5[Jec5Zdec,UKec5XM
-ec5Tus8W)Ks8W)K!rpgNrmh&K!S.5Lec5[Cec5[Jec5[LeH#XHec5XNec42!s8CLJs8LRIs5DN-
-s8LRIs8LRKs8LRHrrCUHrrpsQec5["q>UcOs8UXLs4./"ec#OIec5[FeHZ'(s4./LeboIIec5XM
-ec4UYs8W&Js8W,Lrr3&Ms8W)Ks8W,LrVulIs8W)Kr;QcIr;ZfIs8W)KrVtI!s+BqC!e^OQqpbkG
-s5rIW!.Y~>
-!<E0!joD+GgAV*PgA_-Rg&V**rrE&PrrE&P!W^pSrn@AP!SRPQgA_0HgA_0OgA_/igAV*PgA_-R
-g&V**rrE&PrrE&P!W^pSrn@AP!SRPQgA_0HgA_0OgA_0Qg&M-MgA_-Sg&Tk+!<(XO!<1^N!9)Z2
-!<1^N!<1^P!<1^M!!(aM!!V'Vg&M-,q#C`T!!(^Q!87G,gAM$NgA_0Kg'.Q2!87DQgACsNgA_-R
-g&U*crrE#OrrE)QrW!#R!!*#PrrE)Qr;ciNrrE&Pqu?`NquHcNrrE&Pr;bF&s+0eA!eLCOqq;4I
-s5rIT!.Y~>
-!<E0!joD4Jec#RKec,UMeH#QurrE&KrrE&K!W^aNrmh#K!S%2Lec,XCec,XJec,Wdec#RKec,UM
-eH#QurrE&KrrE&K!W^aNrmh#K!S%2Lec,XCec,XJec,XLeGoUHec,UNeH"/!!<(IJ!<1OI!9)K-
-!<1OI!<1OK!<1OH!!(RH!!UmQeGoU"q#C`O!!(OL!7_)"eboLIec,XFeHQ$(!7_&LebfFIec,UM
-eH"RYrrE#JrrE)LrW!#M!!*#KrrE)Lr;ciIrrE&Kqu?`IquHcIrrE&Kr;bF!s+BqC!e^OQqpbkG
-s5rIW!.Y~>
-!<E0!joD4HeH#X-eH#WNeH#X-eH#X7ec,TjeH#WgeH#W#e`,-ZKE(uFec1:%s81=MV#TT>]`<Q~>
-!<E0!joD+Eg&M-2g&M,Sg&M-2g&M-<gAV)og&M,lg&M,(g>^idJcGcDgAca(s81LRU&X9;\c@6~>
-!<E0!joD4HeGoU-eGoTNeGoU-eGoU7ec#QjeGoTgeGoT#e`,-ZKE(uFec1:%s81=MV#TT>]`<Q~>
-!<E0!joD4Kec,U-ec5[JebfBVec,U-ec5[JebfBWec#Niec5[JebfAtea(ccKE(uFec1:%s81=M
-V#TT>]`<Q~>
-!<E0!joD+HgAV*2gA_0OgA:l[gAV*2gA_0OgA:l\gAM#ngA_0OgA:l$g?[JmJcGcDgAca(s81LR
-U&X9;\c@6~>
-!<E0!joD4Kec#R-ec,XJeb]?Vec#R-ec,XJeb]?WeboKiec,XJeb]>tea(ccKE(uFec1:%s81=M
-V#TT>]`<Q~>
-!<E0!joD3.eUc8%eY^msKE(uFec1:%s81=MV#TT>]`<Q~>
-!<E0!joD*+g4@t/g8<U(JcGcDgAca(s81LRU&X9;\c@6~>
-!<E0!joD3.eUc8%eY^msKE(uFec1:%s81=MV#TT>]`<Q~>
-!<E0!joD3.eUc8%eY^msKE(uFec1:%s81=MV#TT>]`<Q~>
-!<E0!joD*+g4@t/g8<U(JcGcDgAca(s81LRU&X9;\c@6~>
-!<E0!joD3.eUc8%eY^msKE(uFec1:%s81=MV#TT>]`<Q~>
-!<E0!joD3.eUc8%eY^msKE(uFec1:%s81=MV#TT>]`<Q~>
-!<E0!joD*+g4@t/g8<U(JcGcDgAca(s81LRU&X9;\c@6~>
-!<E0!joD3.eUc8%eY^msKE(uFec1:%s81=MV#TT>]`<Q~>
-!<E0!joD3.eUc8%eY^msKE(uFec1:%s81=MV#TT>]`<Q~>
-!<E0!joD*+g4@t/g8<U(JcGcDgAca(s81LRU&X9;\c@6~>
-!<E0!joD3.eUc8%eY^msKE(uFec1:%s81=MV#TT>]`<Q~>
-!<E0!joD3.eUc8%eY^msKE(uFec1:%s81=MV#TT>]`<Q~>
-!<E0!joD*+g4@t/g8<U(JcGcDgAca(s81LRU&X9;\c@6~>
-!<E0!joD3.eUc8%eY^msKE(uFec1:%s81=MV#TT>]`<Q~>
-!<E0!joD3.eUc8%eY^msKE(uFec1:%s81=MV#TT>]`<Q~>
-!<E0!joD*+g4@t/g8<U(JcGcDgAca(s81LRU&X9;\c@6~>
-!<E0!joD3.eUc8%eY^msKE(uFec1:%s81=MV#TT>]`<Q~>
-!<E0!joD3.eUc8%eY^msKE(uFec1:%s81=MV#TT>]`<Q~>
-!<E0!joD*+g4@t/g8<U(JcGcDgAca(s81LRU&X9;\c@6~>
-!<E0!joD3.eUc8%eY^msKE(uFec1:%s81=MV#TT>]`<Q~>
-!<E0!joD3.eUc8%eY^msKE(uFec1:%s81=MV#TT>]`<Q~>
-!<E0!joD*+g4@t/g8<U(JcGcDgAca(s81LRU&X9;\c@6~>
-!<E0!joD3.eUc8%eY^msKE(uFec1:%s81=MV#TT>]`<Q~>
-!<E0!joD3.eUc8%eY^msKE(uFec1:%s81=MV#TT>]`<Q~>
-!<E0!joD*+g4@t/g8<U(JcGcDgAca(s81LRU&X9;\c@6~>
-!<E0!joD3.eUc8%eY^msKE(uFec1:%s81=MV#TT>]`<Q~>
-!<E0!joD3.eUc8%eY^msKE(uFec1:%s81=MV#TT>]`<Q~>
-!<E0!joD*+g4@t/g8<U(JcGcDgAca(s81LRU&X9;\c@6~>
-!<E0!joD3.eUc8%eY^msKE(uFec1:%s81=MV#TT>]`<Q~>
-!<E0!joD3.eUc8%eY^msKE(uFec1:%s81=MV#TT>]`<Q~>
-!<E0!joD*+g4@t/g8<U(JcGcDgAca(s81LRU&X9;\c@6~>
-!<E0!joD3.eUc8%eY^msKE(uFec1:%s81=MV#TT>]`<Q~>
-!<E0!joD3.eUc8%eY^msKE(uFec1:%s81=MV#TT>]`<Q~>
-!<E0!joD*+g4@t/g8<U(JcGcDgAca(s81LRU&X9;\c@6~>
-!<E0!joD3.eUc8%eY^msKE(uFec1:%s81=MV#TT>]`<Q~>
-!<E0!joD3.eUc8%eY^msKE(uFec1:%s81=MV#TT>]`<Q~>
-!<E0!joD*+g4@t/g8<U(JcGcDgAca(s81LRU&X9;\c@6~>
-!<E0!joD3.eUc8%eY^msKE(uFec1:%s81=MV#TT>]`<Q~>
-!<E0!joD3.eUc8%eY^msKE(uFec1:%s81=MV#TT>]`<Q~>
-!<E0!joD*+g4@t/g8<U(JcGcDgAca(s81LRU&X9;\c@6~>
-!<E0!joD3.eUc8%eY^msKE(uFec1:%s81=MV#TT>]`<Q~>
-!<E0!joD3.eUc8%eY^msKE(uFec1:%s81=MV#TT>]`<Q~>
-!<E0!joD*+g4@t/g8<U(JcGcDgAca(s81LRU&X9;\c@6~>
-!<E0!joD3.eUc8%eY^msKE(uFec1:%s81=MV#TT>]`<Q~>
-!<E0!joD3.eUc8%eY^msKE(uFec1:%s81=MV#TT>]`<Q~>
-!<E0!joD*+g4@t/g8<U(JcGcDgAca(s81LRU&X9;\c@6~>
-!<E0!joD3.eUc8%eY^msKE(uFec1:%s81=MV#TT>]`<Q~>
-!<E0!joD3.eUc8%eY^msKE(uFec1:%s81=MV#TT>]`<Q~>
-!<E0!joD*+g4@t/g8<U(JcGcDgAca(s81LRU&X9;\c@6~>
-!<E0!joD3.eUc8%eY^msKE(uFec1:%s81=MV#TT>]`<Q~>
-!<E0!joD3.eUc8%eY^msKE(uFec1:%s81=MV#TT>]`<Q~>
-!<E0!joD*+g4@t/g8<U(JcGcDgAca(s81LRU&X9;\c@6~>
-!<E0!joD3.eUc8%eY^msKE(uFec1:%s81=MV#TT>]`<Q~>
-!<E0!joD3.eUc8%eY^msKE(uFec1:%s81=MV#TT>]`<Q~>
-!<E0!joD*+g4@t/g8<U(JcGcDgAca(s81LRU&X9;\c@6~>
-!<E0!joD3.eUc8%eY^msKE(uFec1:%s81=MV#TT>]`<Q~>
-!<E0!joD3.eUc8%eY^msKE(uFec1:%s81=MV#TT>]`<Q~>
-!<E0!joD*+g4@t/g8<U(JcGcDgAca(s81LRU&X9;\c@6~>
-!<E0!joD3.eUc8%eY^msKE(uFec1:%s81=MV#TT>]`<Q~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec1:%s7Y"CKE(uKeHMcKk2s>WJ,~>
-!<E0!joD+?g&M,1g&M,1g&M,1g&M,MgAca(s7Y1HJcGcIg'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec1:%s7Y"CKE(uKeHMcKk2s>WJ,~>
-!<E0!joD4BeH#X5ec5[Jec5[Lec5[>ec5ZmeH#XEeH#W,eH#W,eH#WHec1:%s7Y"CKE(uKeHMcK
-k2s>WJ,~>
-!<E0!joD+?g&M-:gA_0OgA_0QgA_0CgA_/rg&M-Jg&M,1g&M,1g&M,MgAca(s7Y1HJcGcIg'+2M
-k2s5TJ,~>
-!<E0!joD4BeGoU5ec,XJec,XLec,X>ec,WmeGoUEeGoT,eGoT,eGoTHec1:%s7Y"CKE(uKeHMcK
-k2s>WJ,~>
-!<E0!joD4BeH#X4eH#XIeH#XKeH#X=eH#WmeH#XEeH#W,eH#W,eH#WHec1:%s7Y"CKE(uKeHMcK
-k2s>WJ,~>
-!<E0!joD+?g&M-9g&M-Ng&M-Pg&M-Bg&M,rg&M-Jg&M,1g&M,1g&M,MgAca(s7Y1HJcGcIg'+2M
-k2s5TJ,~>
-!<E0!joD4BeGoU4eGoUIeGoUKeGoU=eGoTmeGoUEeGoT,eGoT,eGoTHec1:%s7Y"CKE(uKeHMcK
-k2s>WJ,~>
-!<E0!joD4BeH#XAec5[Kec5[HeH#XIeH#XKec,UJec5[Iec5[KeH>j%s8W)K!<;cCs8W&Js8W,L
-$3/QUs4,["ec5[Jec5[Jec5[Kec#OEeH#W,eH#W,eH#WHec1:%s7Y"CKE(uKeHMcKk2s>WJ,~>
-!<E0!joD+?g&M-FgA_0PgA_0Mg&M-Ng&M-PgAV*OgA_0NgA_0Pg&h?/!!*#P!!)`HrrE#OrrE)Q
-#lrZZ!8?-,g&M-OgA_0OgA_0PgAM$Jg&M,1g&M,1g&M,MgAca(s7Y1HJcGcIg'+2Mk2s5TJ,~>
-!<E0!joD4BeGoUAec,XKec,XHeGoUIeGoUKec#RJec,XIec,XKeH5g%!!*#K!!)`CrrE#JrrE)L
-#lrKU!7fU"eGoUJec,XJec,XKeboLEeGoT,eGoT,eGoTHec1:%s7Y"CKE(uKeHMcKk2s>WJ,~>
-!<E0!joD4BeH#XBeH>j%ec5Tu!<;uI!<;uI!<<&K"96p%s8CIJs8LOSs4,["e^a]Ms8CIJs7b%e
-s4,["e^a]Mec41Ms4,["e^a]Mec41Ms4,["e^a]Mec5X!!<;iE!<7r,!<7r,!<8qHs+C@Op=91q
-s8VuH"f21\k.LbF~>
-!<E0!joD+?g&M-Gg&h?/g&V**!!)rN!!)rN!!*#P!s%'/!<(UO!<1[X!8?-,g=cP\!<(UO!;G1j
-!8?-,g=cP\g&Tj\!8?-,g=cP\g&Tj\!8?-,g=cP\g&V-+!!)fJ!!%o1!!%o1!!&nMs+14Mp=fOt
-s8VuM"ektYk.1PC~>
-!<E0!joD4BeGoUBeH5g%eH#Qu!!)rI!!)rI!!*#K!s$m%!<(FJ!<1LS!7fU"e^XZM!<(FJ!;G"e
-!7fU"e^XZMeH".M!7fU"e^XZMeH".M!7fU"e^XZMeH#U!!!)fE!!%o,!!%o,!!&nHs+C@Op=91q
-s8VuH"f21\k.LbF~>
-!<E0!joD4BeH#XBeH#XIec,UHeH#XIeH#XKeHQ!'ec41Mrr;uJ!<;uIs8VW>!<;uI&c^D3s4,["
-e^a]Mec41Ms4,[!s8LOKs81=Hs7k+Es,,>,s,,>,s/+?HKE(uFec1:%s81=MV#TT>]`<Q~>
-!<E0!joD+?g&M-Gg&M-NgAV*Mg&M-Ng&M-Pg'%K1g&Tj\rW)rO!!)rNrrDTC!!)rN&HLP=!8?-,
-g=cP\g&Tj\!8?0+!<1[P!;kIM!;P7J!/fJ1!/fJ1!2eKMJcGcDgAca(s81LRU&X9;\c@6~>
-!<E0!joD4BeGoUBeGoUIec#RHeGoUIeGoUKeHGs'eH".MrW)rJ!!)rIrrDT>!!)rI&HLA3!7fU"
-e^XZMeH".M!7fX!!<1LK!;k:H!;P(E!/f;,!/f;,!2e<HKE(uFec1:%s81=MV#TT>]`<Q~>
-!<E0!joD4BeH#XBeHl3*ec42"e^a]teH#XIeH#XKeHl3*ec42"e^a^!eHl3*ec41Ms4./JeH#XD
-eKOtCec41Ms4,["e^a]Mec41Ms4,["e^a]Mec41Ms4,["rm_,Ne^a]seH#W,eH#W,eH#WHec1:%
-s7Y"CKE(uKeHMcKk2s>WJ,~>
-!<E0!joD+?g&M-Gg'@]4g&Th,g=cQ)g&M-Ng&M-Pg'@]4g&Th,g=cQ+g'@]4g&Tj\!87GOg&M-I
-g*$IMg&Tj\!8?-,g=cP\g&Tj\!8?-,g=cP\g&Tj\!8?-,rn7GSg=cQ(g&M,1g&M,1g&M,MgAca(
-s7Y1HJcGcIg'+2Mk2s5TJ,~>
-!<E0!joD4BeGoUBeHc0*eH","e^XZteGoUIeGoUKeHc0*eH","e^X[!eHc0*eH".M!7_)JeGoUD
-eKFqCeH".M!7fU"e^XZMeH".M!7fU"e^XZMeH".M!7fU"rm_)Ne^XZseGoT,eGoT,eGoTHec1:%
-s7Y"CKE(uKeHMcKk2s>WJ,~>
-!<E0!joD4BeH#XAec5[Kec5XOec41Mr;QcIq#C?Ds8N,Ms8LRKs8UXLrrUaNs8LOKs7Y"Cs8CLJ
-s8UXKrrCUIrs%$Rs4,["s8CLJs8:FIs8(7Gs,,>,s,,>,s/+?HKE(uFec1:%s81=MV#TT>]`<Q~>
-!<E0!joD+?g&M-FgA_0PgA_-Tg&Tj\qu?`Np]1<Irr<)R!<1^P!<:dQ!!:jS!<1[P!;>.H!<(XO
-!<:dP!!(aN!!_-W!8?-,!<(XO!;tRN!;bCL!/fJ1!/fJ1!2eKMJcGcDgAca(s81LRU&X9;\c@6~>
-!<E0!joD4BeGoUAec,XKec,UOeH".Mqu?`Ip]1<Drr<)M!<1OK!<:UL!!:[N!<1LK!;=tC!<(IJ
-!<:UK!!(RI!!^sR!7fU"!<(IJ!;tCI!;b4G!/f;,!/f;,!2e<HKE(uFec1:%s81=MV#TT>]`<Q~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec1:%s7Y"CKE(uKeHMcKk2s>WJ,~>
-!<E0!joD+?g&M,1g&M,1g&M,1g&M,MgAca(s7Y1HJcGcIg'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec1:%s7Y"CKE(uKeHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec1:%s7Y"CKE(uKeHMcKk2s>WJ,~>
-!<E0!joD+?g&M,1g&M,1g&M,1g&M,MgAca(s7Y1HJcGcIg'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec1:%s7Y"CKE(uKeHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec1:%s7Y"CKE(uKeHMcKk2s>WJ,~>
-!<E0!joD+?g&M,1g&M,1g&M,1g&M,MgAca(s7Y1HJcGcIg'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec1:%s7Y"CKE(uKeHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec1:%s7Y"CKE(uKeHMcKk2s>WJ,~>
-!<E0!joD+?g&M,1g&M,1g&M,1g&M,MgAca(s7Y1HJcGcIg'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec1:%s7Y"CKE(uKeHMcKk2s>WJ,~>
-!<E0!joD4BeH#W5ec,XGeH#W,eH#W,eH#WHec1:%s7Y"CKE(uKeHMcKk2s>WJ,~>
-!<E0!joD+?g&M,:gA_0Lg&M,1g&M,1g&M,MgAca(s7Y1HJcGcIg'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT5ec,XGeGoT,eGoT,eGoTHec1:%s7Y"CKE(uKeHMcKk2s>WJ,~>
-!<E0!joD4BeH#W5eboLGeH#W,eH#W,eH#WHec1:%s7Y"CKE(uKeHMcKk2s>WJ,~>
-!<E0!joD+?g&M,:gAM$Lg&M,1g&M,1g&M,MgAca(s7Y1HJcGcIg'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT5eboLGeGoT,eGoT,eGoTHec1:%s7Y"CKE(uKeHMcKk2s>WJ,~>
-!<E0!joD4BeH#W4eb]@HeH#W,eH#W,eH#WHec1:%s7Y"CKE(uKeHMcKk2s>WJ,~>
-!<E0!joD+?g&M,9gA:mMg&M,1g&M,1g&M,MgAca(s7Y1HJcGcIg'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT4eb]@HeGoT,eGoT,eGoTHec1:%s7Y"CKE(uKeHMcKk2s>WJ,~>
-!<E0!joD4BeVO8+s,,>,s,,>,s/+?HKE(uFec1:%s81=MV#TT>]`<Q~>
-!<E0!joD+?g5#`dg&M,1g&M,MgAca(s7Y1HJcGcIg'+2Mk2s5TJ,~>
-!<E0!joD4BeVF3_eGoT,eGoTHec1:%s7Y"CKE(uKeHMcKk2s>WJ,~>
-!<E0!joD4BeH#W4eb]@HeH#W,eH#W,eH#WHec1:%s7Y"CKE(uKeHMcKk2s>WJ,~>
-!<E0!joD+?g&M,9gA:mMg&M,1g&M,1g&M,MgAca(s7Y1HJcGcIg'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT4eb]@HeGoT,eGoT,eGoTHec1:%s7Y"CKE(uKeHMcKk2s>WJ,~>
-!<E0!joD4BeH#W4ec#RHeH#W,eH#W,eH#WHec1:%s7Y"CKE(uKeHMcKk2s>WJ,~>
-!<E0!joD+?g&M,9gAV*Mg&M,1g&M,1g&M,MgAca(s7Y1HJcGcIg'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT4ec#RHeGoT,eGoT,eGoTHec1:%s7Y"CKE(uKeHMcKk2s>WJ,~>
-!<E0!joD4BeH#W5ec,XGeH#W,eH#W,eH#WHec1:%s7Y"CKE(uKeHMcKk2s>WJ,~>
-!<E0!joD+?g&M,:gA_0Lg&M,1g&M,1g&M,MgAca(s7Y1HJcGcIg'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT5ec,XGeGoT,eGoT,eGoTHec1:%s7Y"CKE(uKeHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec1:%s7Y"CKE(uKeHMcKk2s>WJ,~>
-!<E0!joD+?g&M,1g&M,1g&M,1g&M,MgAca(s7Y1HJcGcIg'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec1:%s7Y"CKE(uKeHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec1:%s7Y"CKE(uKeHMcKk2s>WJ,~>
-!<E0!joD+?g&M,1g&M,1g&M,1g&M,MgAca(s7Y1HJcGcIg'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec1:%s7Y"CKE(uKeHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec1:%s7Y"CKE(uKeHMcKk2s>WJ,~>
-!<E0!joD+?g&M,1g&M,1g&M,1g&M,MgAca(s7Y1HJcGcIg'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec1:%s7Y"CKE(uKeHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec1:%s7Y"CKE(uKeHMcKk2s>WJ,~>
-!<E0!joD+?g&M,1g&M,1g&M,1g&M,MgAca(s7Y1HJcGcIg'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec1:%s7Y"CKE(uKeHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec1:%s7Y"CKE(uKeHMcKk2s>WJ,~>
-!<E0!joD+?g&M,1g&M,1g&M,1g&M,MgAca(s7Y1HJcGcIg'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec1:%s7Y"CKE(uKeHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec1:%s7Y"CKE(uKeHMcKk2s>WJ,~>
-!<E0!joD+?g&M,1g&M,1g&M,1g&M,MgAca(s7Y1HJcGcIg'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec1:%s7Y"CKE(uKeHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec1:%s7Y"CKE(uKeHMcKk2s>WJ,~>
-!<E0!joD+?g&M,1g&M,1g&M,1g&M,MgAca(s7Y1HJcGcIg'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec1:%s7Y"CKE(uKeHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec1:%s7Y"CKE(uKeHMcKk2s>WJ,~>
-!<E0!joD+?g&M,1g&M,1g&M,1g&M,MgAca(s7Y1HJcGcIg'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec1:%s7Y"CKE(uKeHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec1:%s7Y"CKE(uKeHMcKk2s>WJ,~>
-!<E0!joD+?g&M,1g&M,1g&M,1g&M,MgAca(s7Y1HJcGcIg'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec1:%s7Y"CKE(uKeHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec1:%s7Y"CKE(uKeHMcKk2s>WJ,~>
-!<E0!joD+?g&M,1g&M,1g&M,1g&M,MgAca(s7Y1HJcGcIg'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec1:%s7Y"CKE(uKeHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec1:%s7Y"CKE(uKeHMcKk2s>WJ,~>
-!<E0!joD+?g&M,1g&M,1g&M,1g&M,MgAca(s7Y1HJcGcIg'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec1:%s7Y"CKE(uKeHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec1:%s7Y"CKE(uKeHMcKk2s>WJ,~>
-!<E0!joD+?g&M,1g&M,1g&M,1g&M,MgAca(s7Y1HJcGcIg'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec1:%s7Y"CKE(uKeHMcKk2s>WJ,~>
-!<E0!joD4BeH#X5eH#W\eH#X9eH#W,eH#W,eH#WHec1:%s7Y"CKE(uKeHMcKk2s>WJ,~>
-!<E0!joD+?g&M-:g&M,ag&M->g&M,1g&M,1g&M,MgAca(s7Y1HJcGcIg'+2Mk2s5TJ,~>
-!<E0!joD4BeGoU5eGoT\eGoU9eGoT,eGoT,eGoTHec1:%s7Y"CKE(uKeHMcKk2s>WJ,~>
-!<E0!joD4BeH#X5eH#W\eH#X9eH#W,eH#W,eH#WHec1:%s7Y"CKE(uKeHMcKk2s>WJ,~>
-!<E0!joD+?g&M-:g&M,ag&M->g&M,1g&M,1g&M,MgAca(s7Y1HJcGcIg'+2Mk2s5TJ,~>
-!<E0!joD4BeGoU5eGoT\eGoU9eGoT,eGoT,eGoTHec1:%s7Y"CKE(uKeHMcKk2s>WJ,~>
-!<E0!joD4BeH#XBeH,^#rr<#Ks8W)KrVm2Ss8UXLs4,["ec#LLec5[JeH#XCec5[Jec5[LeHu9+
-s8UX"s4./LrRLrJrRLrJrmguImaV=;MU__,MU__,VUb^!s8VfCs+C@OqpbkGs5rIW!.Y~>
-!<E0!joD+?g&M-Gg&V3-rW)uPrrE&Pr;[/X!!(^Q!8?-,gAM!Qg&M-Og&M-HgA_0OgA_0Qg'Ic5
-!!(a,!87DQrS%8OrS%8Orn@;Nmb.X@MV8%1MV8%1VV;'$s8VfHs+14Mqq;4Is5rIT!.Y~>
-!<E0!joD4BeGoUBeH#[#rW)uKrrE&Kr;[/S!!(OL!7fU"eboILeGoUJeGoUCec,XJec,XLeHl6+
-!!(R"!7_&LrRLoJrRLoJrmgrImaV:;MU_\,MU_\,VUb^!s8VfCs+C@OqpbkGs5rIW!.Y~>
-!<E0!joD4BeH#XAeH#XJeH>j%ec5X!!<<#J"96p%s8LOKs8CIMs4,["rm_#KpXLGee^a]Mec41M
-s4,["e^a]Mec41Ms4,["e^a]Mec41Ms8LOKs6S89s,,>,s,,>,s/+?HKE(uFec1:%s81=MV#TT>
-]`<Q~>
-!<E0!joD+?g&M-Fg&M-Og&h?/g&V-+!!)uO!s%'/!<1[P!<(UR!8?-,rn7>PpY$bjg=cP\g&Tj\
-!8?-,g=cP\g&Tj\!8?-,g=cP\g&Tj\!<1[P!:8D>!/fJ1!/fJ1!2eKMJcGcDgAca(s81LRU&X9;
-\c@6~>
-!<E0!joD4BeGoUAeGoUJeH5g%eH#U!!!)uJ!s$m%!<1LK!<(FM!7fU"rm^uKpXLDee^XZMeH".M
-!7fU"e^XZMeH".M!7fU"e^XZMeH".M!<1LK!:859!/f;,!/f;,!2e<HKE(uFec1:%s81=MV#TT>
-]`<Q~>
-!<E0!joD4BeH#XAeH#XJec,UIeH#XJeH>j%ec5X!!<<#J"96p%s7=b@s8:CZs4,["e^a]Mec41M
-s4,["e^a[!rm_#Kqpb]Hm*u+9MU__,MU__,VUb^!s8VfCs+C@OqpbkGs5rIW!.Y~>
-!<E0!joD+?g&M-Fg&M-OgAV*Ng&M-Og&h?/g&V-+!!)uO!s%'/!;"nE!;tO_!8?-,g=cP\g&Tj\
-!8?-,g=lN+rn7>Pqq;#Mm+MF>MV8%1MV8%1VV;'$s8VfHs+14Mqq;4Is5rIT!.Y~>
-!<E0!joD4BeGoUAeGoUJec#RIeGoUJeH5g%eH#U!!!)uJ!s$m%!;"_@!;t@Z!7fU"e^XZMeH".M
-!7fU"e^aX!rm^uKqpbZHm*u(9MU_\,MU_\,VUb^!s8VfCs+C@OqpbkGs5rIW!.Y~>
-!<E0!joD4BeH#XAeH#XJeH>j%ec5X!#liH*s4./"ec5X!!<<#J"96p%s8LOKs7b%es4,["e^a]M
-ec41Ms4,["e^a]Mec41Ms4,["e^a]Mec5X!"96p%s6nJ<s,,>,s,,>,s/+?HKE(uFec1:%s81=M
-V#TT>]`<Q~>
-!<E0!joD+?g&M-Fg&M-Og&h?/g&V-+#QWT4!87G,g&V-+!!)uO!s%'/!<1[P!;G1j!8?-,g=cP\
-g&Tj\!8?-,g=cP\g&Tj\!8?-,g=cP\g&V-+!s%'/!:SVA!/fJ1!/fJ1!2eKMJcGcDgAca(s81LR
-U&X9;\c@6~>
-!<E0!joD4BeGoUAeGoUJeH5g%eH#U!#QWE*!7_)"eH#U!!!)uJ!s$m%!<1LK!;G"e!7fU"e^XZM
-eH".M!7fU"e^XZMeH".M!7fU"e^XZMeH#U!!s$m%!:SG<!/f;,!/f;,!2e<HKE(uFec1:%s81=M
-V#TT>]`<Q~>
-!<E0!joD4BeH#XBec#OIec5[Iec5[Kec5XNec41urrCUKrrpsQs4,["p=93CrRLrJs4.,K!7h#I
-#1`bRe^a^"rRLrJr71iImaV=;MU__,MU__,VUb^!s8VfCs+C@OqpbkGs5rIW!.Y~>
-!<E0!joD+?g&M-GgAM$NgA_0NgA_0PgA_-Sg&Tk*!!(aP!!V'V!8?-,p=fNHrS%8Os4[GP!8@>N
-#20%Wg=cN,rS%8Or7_/Nmb.X@MV8%1MV8%1VV;'$s8VfHs+14Mqq;4Is5rIT!.Y~>
-!<E0!joD4BeGoUBeboLIec,XIec,XKec,UNeH".u!!(RK!!UmQ!7fU"p=90CrRLoJs4.)K!7guI
-#1W\Re^XX"rRLoJr71fImaV:;MU_\,MU_\,VUb^!s8VfCs+C@OqpbkGs5rIW!.Y~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec1:%s7CsDs81=MV#TT>]`<Q~>
-!<E0!joD+?g&M,1g&M,1g&M,1g&M,MgAca(s7CmBs81LRU&X9;\c@6~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec1:%s7CsDs81=MV#TT>]`<Q~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec17%s7:mCs81=MV#TT>]`<Q~>
-!<E0!joD+?g&M,1g&M,1g&M,1g&M,MgAc^(s7:gAs81LRU&X9;\c@6~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec17%s7:mCs81=MV#TT>]`<Q~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&M,1g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&M,1g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#XGec,W5eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&M-LgA_/:g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoUGec,W5eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#XJeboK2eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&M-OgAM#7g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoUJeboK2eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH5d$eb]?0eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&_9.gA:l5g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeH,a$eb]?0eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeVO8+s,,>,s,,>,s/+?HKCZ_Us81=MV#TT>]`<Q~>
-!<E0!joD+?g5#`dg&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeVF3_eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH5d$ebfE0eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&_9.gACr5g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeH,a$ebfE0eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#XJeboK2eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&M-OgAM#7g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoUJeboK2eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#XGec,W5eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&M-LgA_/:g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoUGec,W5eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&M,1g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&M,1g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&M,1g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&M,1g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&M,1g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&M,1g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&M,1g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&M,1g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&M,1g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&M,1g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&M,1g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&M,1g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#X.ec5[EeH#W\eH#XKeH#XGeH5d$s8CIJs-_C;s,,>,s/+?HKCZ_Us81=MV#TT>
-]`<Q~>
-!<E0!joD+?g&M-3gA_0Jg&M,ag&M-Pg&M-Lg&_9.!<(UO!1DO@!/fJ1!2eKMJb$\Xs81LRU&X9;
-\c@6~>
-!<E0!joD4BeGoU.ec,XEeGoT\eGoUKeGoUGeH,a$!<(FJ!1D@;!/f;,!2e<HKCZ_Us81=MV#TT>
-]`<Q~>
-!<E0!joD4BeH#X-eH#XEeH#W\eH#XKeH#XGeHGp&s4,[!s-_C;s,,>,s/+?HKCZ_Us81=MV#TT>
-]`<Q~>
-!<E0!joD+?g&M-2g&M-Jg&M,ag&M-Pg&M-Lg&qE0!8?0+!1DO@!/fJ1!2eKMJb$\Xs81LRU&X9;
-\c@6~>
-!<E0!joD4BeGoU-eGoUEeGoT\eGoUKeGoUGeH>m&!7fX!!1D@;!/f;,!2e<HKCZ_Us81=MV#TT>
-]`<Q~>
-!<E0!joD4BeH#XAec,UJec5[LeH>j%s8W&Jrr;fErVuoJ!WU^LrrUaNs8LONs4./LrRLoIq:,NG
-ec,UKec5[Jec5XLec,RMec5[Kec5[Jec,UKec#LKec5Nsr;ZcH!<8J;!<7r,!<8qHs+BmUs8VuH
-"f21\k.LbF~>
-!<E0!joD+?g&M-FgAV*OgA_0Qg&h?/!!)uOrW)cJr;clO!<CjQ!!:jS!<1[S!87DQrS%5Nq:YiL
-gAV*PgA_0OgA_-QgAV'Rg&M-PgA_0OgAV*PgAM!Pg&V$(quH`M!!&G@!!%o1!!&nMs+0aXs8VuM
-"ektYk.1PC~>
-!<E0!joD4BeGoUAec#RJec,XLeH5g%!!)uJrW)cEr;clJ!<C[L!!:[N!<1LN!7_&LrRLlIq:,KG
-ec#RKec,XJec,ULec#OMeGoUKec,XJec#RKeboIKeH#KsquH`H!!&G;!!%o,!!&nHs+BmUs8VuH
-"f21\k.LbF~>
-!<E0!joD4BeH#XBeH#XIeIV]1ec41Ms4,["e^a]Mec5Ep!<;uI!<;rH!<<&K#636(s4,["p!j'B
-rRDbbe^a]Mec41Ms4,["e^a]Mec41Ms4,["qpb]Hrm_#KqUGZIec5Tu!<8J;!<7r,!<8qHs+BmU
-s8VuH"f21\k.LbF~>
-!<E0!joD+?g&M-Gg&M-Ng(+2;g&Tj\!8?-,g=cP\g&Up%!!)rN!!)oM!!*#P"p!B2!8?-,p"BBG
-rRr(gg=cP\g&Tj\!8?-,g=cP\g&Tj\!8?-,qq;#Mrn7>PqUtuNg&V**!!&G@!!%o1!!&nMs+0aX
-s8VuM"ektYk.1PC~>
-!<E0!joD4BeGoUBeGoUIeIMZ1eH".M!7fU"e^XZMeH#Bp!!)rI!!)oH!!*#K"p!3(!7fU"p!j$B
-rRD_be^XZMeH".M!7fU"e^XZMeH".M!7fU"qpbZHrm^uKqUGWIeH#Qu!!&G;!!%o,!!&nHs+BmU
-s8VuH"f21\k.LbF~>
-!<E0!joD4BeH#XAec5[Kec,UJeHu9+ec41Ms4,["psfBEr7(fIrRLoIrm_,Ne^a^!ec5[DeH#XJ
-ec,UJeI2E-ec41Ms4,["e^a[!rRLrJrRCoJrm_#KqUGZIec5Tu!<8J;!<7r,!<8qHs+BmUs8VuH
-"f21\k.LbF~>
-!<E0!joD+?g&M-FgA_0PgAV*Og'Ic5g&Tj\!8?-,pt>]Jr7V,NrS%5Nrn7GSg=cQ+gA_0Ig&M-O
-gAV*Og'[o7g&Tj\!8?-,g=lN+rS%8OrRq5Orn7>PqUtuNg&V**!!&G@!!%o1!!&nMs+0aXs8VuM
-"ektYk.1PC~>
-!<E0!joD4BeGoUAec,XKec#RJeHl6+eH".M!7fU"psf?Er7(cIrRLlIrm_)Ne^X[!ec,XDeGoUJ
-ec#RJeI)B-eH".M!7fU"e^aX!rRLoJrRClJrm^uKqUGWIeH#Qu!!&G;!!%o,!!&nHs+BmUs8VuH
-"f21\k.LbF~>
-!<E0!joD4BeH#X?eIqo4ec41Ms4,["e^a]Mec41Ms7k+Ks4,["e^a^!eH>j%ec5X!"96p%s8:CI
-s7k+Es8CI_s4,["e^a]Mec41Ms4,["e^a]Mec5Qt!<<&K"TR$&s8VuHr;ZcH!<8J;!<7r,!<8qH
-s+BmUs8VuH"f21\k.LbF~>
-!<E0!joD+?g&M-Dg(FD>g&Tj\!8?-,g=cP\g&Tj\!;P7P!8?-,g=cQ+g&h?/g&V-+!s%'/!;tON
-!;P7J!<(Ud!8?-,g=cP\g&Tj\!8?-,g=cP\g&V')!!*#P"9@00!!)oMquH`M!!&G@!!%o1!!&nM
-s+0aXs8VuM"ektYk.1PC~>
-!<E0!joD4BeGoU?eIhl4eH".M!7fU"e^XZMeH".M!;P(K!7fU"e^X[!eH5g%eH#U!!s$m%!;t@I
-!;P(E!<(F_!7fU"e^XZMeH".M!7fU"e^XZMeH#Nt!!*#K"9@!&!!)oHquH`H!!&G;!!%o,!!&nH
-s+BmUs8VuH"f21\k.LbF~>
-!<E0!joD4BeH#XBec,UIec5[Lec,RSec5["ec5["s7k.Es8UXJs8UXLrrUaNec,RNec5["rr;cD
-rVulIs8W&Jrr;uJs8N8Qs4,["s8LRJs8:FIrrL[MqUG`Kec41MrVr>:!<7r,!<8qHs+BmUs8VuH
-"f21\k.LbF~>
-!<E0!joD+?g&M-GgAV*NgA_0QgAV'Xg&M-,g&M-,!;P:J!<:dO!<:dQ!!:jSgAV'Sg&M-,rW)`I
-r;ciNrrE#OrW)rOrr<5V!8?-,!<1^O!;tRN!!1dRqUu&Pg&Tj\r;`;?!!%o1!!&nMs+0aXs8VuM
-"ektYk.1PC~>
-!<E0!joD4BeGoUBec#RIec,XLec#OSeGoU"eGoU"!;P+E!<:UJ!<:UL!!:[Nec#ONeGoU"rW)`D
-r;ciIrrE#JrW)rJrr<5Q!7fU"!<1OJ!;tCI!!1UMqUG]KeH".Mr;`;:!!%o,!!&nHs+BmUs8VuH
-"f21\k.LbF~>
-!<E0!joD4BeH#WFeH#X5eH#XGeH5d$s-2%6s,,>,s/+?HKCZ_Us81=MV#TT>]`<Q~>
-!<E0!joD+?g&M,Kg&M-:g&M-Lg&_9.!0l1;!/fJ1!2eKMJb$\Xs81LRU&X9;\c@6~>
-!<E0!joD4BeGoTFeGoU5eGoUGeH,a$!0l"6!/f;,!2e<HKCZ_Us81=MV#TT>]`<Q~>
-!<E0!joD4BeH#WGec,U5eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&M,LgAV*:g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoTGec#R5eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&M,1g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&M,1g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W5ec,XGeH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&M,1g&M,:gA_0Lg&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT5ec,XGeGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W5eboLGeH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&M,1g&M,:gAM$Lg&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT5eboLGeGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W4eb]@HeH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&M,1g&M,9gA:mMg&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT4eb]@HeGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeU[^_!!*%VeH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g496c!/fJ1!2eKMJb$\Xs81LRU&X9;\c@6~>
-!<E0!joD4BeU[^^!/f;,!2e<HKCZ_Us81=MV#TT>]`<Q~>
-!<E0!joD4BeH#W,eH#W4eb]@HeH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&M,1g&M,9gA:mMg&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT4eb]@HeGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W4ec#RHeH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&M,1g&M,9gAV*Mg&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT4ec#RHeGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W5ec,XGeH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&M,1g&M,:gA_0Lg&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT5ec,XGeGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&M,1g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&M,1g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&M,1g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&M,1g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&M,1g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&M,1g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&M,1g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&M,1g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&M,1g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&M,1g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&M,1g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&M,1g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#X.ec5[DeH#XIeH#XIeH#XFec5[BeH#X7eH5d$s8CIJs7t1Fs,,>,s,,>,s/+?H
-KCZ_Us81=MV#TT>]`<Q~>
-!<E0!joD+?g&M-3gA_0Ig&M-Ng&M-Ng&M-KgA_0Gg&M-<g&_9.!<(UO!;Y=K!/fJ1!/fJ1!2eKM
-Jb$\Xs81LRU&X9;\c@6~>
-!<E0!joD4BeGoU.ec,XDeGoUIeGoUIeGoUFec,XBeGoU7eH,a$!<(FJ!;Y.F!/f;,!/f;,!2e<H
-KCZ_Us81=MV#TT>]`<Q~>
-!<E0!joD4BeH#X-eH#XFec,UIec5[Jec5[EeH#XBeH#X7eHGp&s4,[!s7t1Fs,,>,s,,>,s/+?H
-KCZ_Us81=MV#TT>]`<Q~>
-!<E0!joD+?g&M-2g&M-KgAV*NgA_0OgA_0Jg&M-Gg&M-<g&qE0!8?0+!;Y=K!/fJ1!/fJ1!2eKM
-Jb$\Xs81LRU&X9;\c@6~>
-!<E0!joD4BeGoU-eGoUFec#RIec,XJec,XEeGoUBeGoU7eH>m&!7fX!!;Y.F!/f;,!/f;,!2e<H
-KCZ_Us81=MV#TT>]`<Q~>
-!<E0!joD4BeH#XAec,UJec5[LeH>j%s8W&Jrr;`C!<<&K!rpgNrm_)Mec5Eprr<#Ks8N5Ps8UX"
-rVulIs8W&Jrr;fEr;ZcH!<;lF!<7r,!<7r,!<8qHs+BmUs8VuH"f21\k.LbF~>
-!<E0!joD+?g&M-FgAV*OgA_0Qg&h?/!!)uOrW)]H!!*#P!W^pSrn7DRg&Up%rW)uPrr<2U!!(a,
-r;ciNrrE#OrW)cJquH`M!!)iK!!%o1!!%o1!!&nMs+0aXs8VuM"ektYk.1PC~>
-!<E0!joD4BeGoUAec#RJec,XLeH5g%!!)uJrW)]C!!*#K!W^aNrm_&MeH#BprW)uKrr<2P!!(R"
-r;ciIrrE#JrW)cEquH`H!!)iF!!%o,!!%o,!!&nHs+BmUs8VuH"f21\k.LbF~>
-!<E0!joD4BeH#XBeH#XIeIV]1ec41Ms4,["e^a]Mec5Bo%0+l.s4,["e^a]Mec5Ep$3/Q+s4,["
-e^a^!eH#XJeHZ'(ec41Ms7OnDs4./JeH#XFeH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&M-Gg&M-Ng(+2;g&Tj\!8?-,g=cP\g&Um$$io#8!8?-,g=cP\g&Up%#lr]5!8?-,
-g=cQ+g&M-Og'.Q2g&Tj\!;5%I!87GOg&M-Kg&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoUBeGoUIeIMZ1eH".M!7fU"e^XZMeH#?o$ini.!7fU"e^XZMeH#Bp#lrN+!7fU"
-e^X[!eGoUJeHQ$(eH".M!;4kD!7_)JeGoUFeGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#XAec5[Kec,UJeHu9+ec41Ms4,["pXK?Fe^aTt!7h#Iq:,fOe^a]Mec41Ms8LOK
-s8CLIs8CLJs7b%Fs4./JeH#XFeH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&M-FgA_0PgAV*Og'Ic5g&Tj\!8?-,pY#ZKg=lH)!8@>Nq:Z,Tg=cP\g&Tj\!<1[P
-!<(XN!<(XO!;G1K!87GOg&M-Kg&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoUAec,XKec#RJeHl6+eH".M!7fU"pXK<Fe^aQt!7guIq:,cOe^XZMeH".M!<1LK
-!<(II!<(IJ!;G"F!7_)JeGoUFeGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#X?eIqo4ec41Ms4,["e^a]Mec41Ms7b%Ds8:CIs8:CIs7k+Ns4,["e^a]Mec5X!
-#liH*s4./"ec5Qt!<;lFr;ZcH!<;lF!<7r,!<7r,!<8qHs+BmUs8VuH"f21\k.LbF~>
-!<E0!joD+?g&M-Dg(FD>g&Tj\!8?-,g=cP\g&Tj\!;G1I!;tON!;tON!;P7S!8?-,g=cP\g&V-+
-#QWT4!87G,g&V')!!)iKquH`M!!)iK!!%o1!!%o1!!&nMs+0aXs8VuM"ektYk.1PC~>
-!<E0!joD4BeGoU?eIhl4eH".M!7fU"e^XZMeH".M!;G"D!;t@I!;t@I!;P(N!7fU"e^XZMeH#U!
-#QWE*!7_)"eH#Nt!!)iFquH`H!!)iF!!%o,!!%o,!!&nHs+BmUs8VuH"f21\k.LbF~>
-!<E0!joD4BeH#XBec,UIec5[Lec,RSec5["ec5["s8(:Es8CIJs8:CIs7t4Ds8CLJs8:FIs8LRK
-s8LRJs7b%Hs4./"ec#OEeH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&M-GgAV*NgA_0QgAV'Xg&M-,g&M-,!;bFJ!<(UO!;tON!;Y@I!<(XO!;tRN!<1^P
-!<1^O!;G1M!87G,gAM$Jg&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoUBec#RIec,XLec#OSeGoU"eGoU"!;b7E!<(FJ!;t@I!;Y1D!<(IJ!;tCI!<1OK
-!<1OJ!;G"H!7_)"eboLEeGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#WZeH#X1eH5d$s7FhAs,,>,s,,>,s/+?HKCZ_Us81=MV#TT>]`<Q~>
-!<E0!joD+?g&M,_g&M-6g&_9.!;+tF!/fJ1!/fJ1!2eKMJb$\Xs81LRU&X9;\c@6~>
-!<E0!joD4BeGoTZeGoU1eH,a$!;+eA!/f;,!/f;,!2e<HKCZ_Us81=MV#TT>]`<Q~>
-!<E0!joD4BeH#W\ec5ZueH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&M,agA_0%g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT\ec,WueGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&M,1g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&M,1g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W5ec,XGeH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&M,1g&M,:gA_0Lg&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT5ec,XGeGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W5eboLGeH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&M,1g&M,:gAM$Lg&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT5eboLGeGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W4eb]@HeH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&M,1g&M,9gA:mMg&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT4eb]@HeGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeU[^_!!*%VeH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g496c!/fJ1!2eKMJb$\Xs81LRU&X9;\c@6~>
-!<E0!joD4BeU[^^!/f;,!2e<HKCZ_Us81=MV#TT>]`<Q~>
-!<E0!joD4BeH#W,eH#W4eb]@HeH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&M,1g&M,9gA:mMg&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT4eb]@HeGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W4ec#RHeH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&M,1g&M,9gAV*Mg&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT4ec#RHeGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W5ec,XGeH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&M,1g&M,:gA_0Lg&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT5ec,XGeGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&M,1g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&M,1g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&M,1g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&M,1g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&M,1g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&M,1g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&M,1g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&M,1g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&M,1g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&M,1g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&M,1g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&M,1g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#X(eH#X7eH#XIeH#XIeH#XFec5[BeH#X9eH#W,eH#W,eH#WHec19m^&S-0eHMcK
-k2s>WJ,~>
-!<E0!joD+?g&M--g&M-<g&M-Ng&M-Ng&M-KgA_0Gg&M->g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2M
-k2s5TJ,~>
-!<E0!joD4BeGoU(eGoU7eGoUIeGoUIeGoUFec,XBeGoU9eGoT,eGoT,eGoTHec19m^&S-0eHMcK
-k2s>WJ,~>
-!<E0!joD4BeH#Wgec,UIec5[Jec5[EeH#XBeH#X9eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>W
-J,~>
-!<E0!joD+?g&M,lgAV*NgA_0OgA_0Jg&M-Gg&M->g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5T
-J,~>
-!<E0!joD4BeGoTgec#RIec,XJec,XEeGoUBeGoU9eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>W
-J,~>
-!<E0!joD4BeH#XBeH,^#rr<#Ks8W&Js8W&Js8W&Js8W,Ls8W,Ls8W,Ls8VfC!<<&K!rpgNrm_)M
-ec5Eprr<#Ks8N5Ps8UX"rVulIs8W&Jrr;iF!<7r,!<7r,!<8qHs+BmUs8VuH"f21\k.LbF~>
-!<E0!joD+?g&M-Gg&V3-rW)uPrrE#OrrE#OrrE#OrrE)QrrE)QrrE)QrrDcH!!*#P!W^pSrn7DR
-g&Up%rW)uPrr<2U!!(a,r;ciNrrE#OrW)fK!!%o1!!%o1!!&nMs+0aXs8VuM"ektYk.1PC~>
-!<E0!joD4BeGoUBeH#[#rW)uKrrE#JrrE#JrrE#JrrE)LrrE)LrrE)LrrDcC!!*#K!W^aNrm_&M
-eH#BprW)uKrr<2P!!(R"r;ciIrrE#JrW)fF!!%o,!!%o,!!&nHs+BmUs8VuH"f21\k.LbF~>
-!<E0!joD4BeH#XAeH#XJeIV]1ec41Ms4,["e^a]Mec5Tu!<<&K!<<&K"om-Qe^a]oeI;K.ec41M
-s4,["e^a]peHu9+ec41Ms4,["rm_#KrRD,Pe^a]Mec5Bo!<7r,!<7r,!<8qHs+BmUs8VuH"f21\
-k.LbF~>
-!<E0!joD+?g&M-Fg&M-Og(+2;g&Tj\!8?-,g=cP\g&V**!!*#P!!*#P"T[6Vg=cQ$g'du8g&Tj\
-!8?-,g=cQ%g'Ic5g&Tj\!8?-,rn7>PrRqGUg=cP\g&Um$!!%o1!!%o1!!&nMs+0aXs8VuM"ektY
-k.1PC~>
-!<E0!joD4BeGoUAeGoUJeIMZ1eH".M!7fU"e^XZMeH#Qu!!*#K!!*#K"T['Qe^XZoeI2H.eH".M
-!7fU"e^XZpeHl6+eH".M!7fU"rm^uKrRD)Pe^XZMeH#?o!!%o,!!%o,!!&nHs+BmUs8VuH"f21\
-k.LbF~>
-!<E0!joD4BeH#XAeH#XJec,UJeH#XIec,UHeH#XJeHGp&s4,[!s7XtEs4,ZtrrCUIs7t1Os4,["
-e^a]Mec5X!!<<#Jrr;rIs8VoF!<7r,!<7r,!<8qHs+BmUs8VuH"f21\k.LbF~>
-!<E0!joD+?g&M-Fg&M-OgAV*Og&M-NgAV*Mg&M-Og&qE0!8?0+!;>+J!8?0)!!(aN!;Y=T!8?-,
-g=cP\g&V-+!!)uOrW)oNrrDlK!!%o1!!%o1!!&nMs+0aXs8VuM"ektYk.1PC~>
-!<E0!joD4BeGoUAeGoUJec#RJeGoUIec#RHeGoUJeH>m&!7fX!!;=qE!7fWt!!(RI!;Y.O!7fU"
-e^XZMeH#U!!!)uJrW)oIrrDlF!!%o,!!%o,!!&nHs+BmUs8VuH"f21\k.LbF~>
-!<E0!joD4BeH#XAeH#XJeIV]1ec41Ms4,["e^a]Mec5Tu!<<#J#liHTe^a]Mec5Bo!<;uI!<;uI
-!<;iE$3/Q+s4,["e^a^!eHl3*ec42"e^a]teH#XGeH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>W
-J,~>
-!<E0!joD+?g&M-Fg&M-Og(+2;g&Tj\!8?-,g=cP\g&V**!!)uO#QWQYg=cP\g&Um$!!)rN!!)rN
-!!)fJ#lr]5!8?-,g=cQ+g'@]4g&Th,g=cQ)g&M-Lg&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5T
-J,~>
-!<E0!joD4BeGoUAeGoUJeIMZ1eH".M!7fU"e^XZMeH#Qu!!)uJ#QWBTe^XZMeH#?o!!)rI!!)rI
-!!)fE#lrN+!7fU"e^X[!eHc0*eH","e^XZteGoUGeGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>W
-J,~>
-!<E0!joD4BeH#XBec#OIec5[Jec5[Jec5[KeboIHeH#XJec5[Eec#OHeH#XIeH#XFec#OHec5[I
-ec5[Kec5[Kec,UEeH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&M-GgAM$NgA_0OgA_0OgA_0PgACsMg&M-OgA_0JgAM$Mg&M-Ng&M-KgAM$MgA_0N
-gA_0PgA_0PgAV*Jg&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoUBeboLIec,XJec,XJec,XKebfFHeGoUJec,XEeboLHeGoUIeGoUFeboLHec,XI
-ec,XKec,XKec#REeGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#WHeH#X3eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&M,Mg&M-8g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoTHeGoU3eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#WJec5[2eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&M,OgA_07g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoTJec,X2eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&M,1g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&M,1g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W5ec,XGeH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&M,1g&M,1g&M,:gA_0Lg&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT5ec,XGeGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W5eboLGeH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&M,1g&M,1g&M,:gAM$Lg&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT5eboLGeGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W4eb]@HeH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&M,1g&M,1g&M,9gA:mMg&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT4eb]@HeGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeU[^O!1<fes/+?HKCZ_Us81=MV#TT>]`<Q~>
-!<E0!joD+?g496T!13b`gAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeU[^O!13b`ec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W4eb]@HeH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&M,1g&M,1g&M,9gA:mMg&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT4eb]@HeGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W4ec#RHeH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&M,1g&M,1g&M,9gAV*Mg&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT4ec#RHeGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W5ec,XGeH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&M,1g&M,1g&M,:gA_0Lg&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT5ec,XGeGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&M,1g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&M,1g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&M,1g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&M,1g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&M,1g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&M,1g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&M,1g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&M,1g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&M,1g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&M,1g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&M,1g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&M,1g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#X.ec5[EeH#Wnec5[>eHc-)s4./"ec1WZ!<7r,!<8qHs+BmUs8VuH"f21\k.LbF~>
-!<E0!joD+?g&M-3gA_0Jg&M,sgA_0Cg'7W3!87G,g&R,d!!%o1!!&nMs+0aXs8VuM"ektYk.1PC~>
-!<E0!joD4BeGoU.ec,XEeGoTnec,X>eHZ*)!7_)"eGtTZ!!%o,!!&nHs+BmUs8VuH"f21\k.LbF~>
-!<E0!joD4BeH#X-eH#XEeH#WmeH#X>eH>j%s4.)JNR\%/MU__,VUb^!o"G)'qpbkGs5rIW!.Y~>
-!<E0!joD+?g&M-2g&M-Jg&M,rg&M-Cg&h?/!8@AONS4@4MV8%1VV;'$o"tG,qq;4Is5rIT!.Y~>
-!<E0!joD4BeGoU-eGoUEeGoTmeGoU>eH5g%!7h#JNR\"/MU_\,VUb^!o"G)'qpbkGs5rIW!.Y~>
-!<E0!joD4BeH#XAec,UJec5[LeH>j%s8W&Jrr;fErVuoJ!WU^LrrUaNs8LONs4./LrRLoIq:,NG
-ec,UKec5[LeH>j%s8W#I#QN?)s8UXLs7t4Bs8UULs,GP/s,,>,s/+?HKCZ_Us81=MV#TT>]`<Q~>
-!<E0!joD+?g&M-FgAV*OgA_0Qg&h?/!!)uOrW)cJr;clO!<CjQ!!:jS!<1[S!87DQrS%5Nq:YiL
-gAV*PgA_0Qg&h?/!!)rN#6<K3!!(^Q!;Y@G!<:aQ!0,\4!/fJ1!2eKMJb$\Xs81LRU&X9;\c@6~>
-!<E0!joD4BeGoUAec#RJec,XLeH5g%!!)uJrW)cEr;clJ!<C[L!!:[N!<1LN!7_&LrRLlIq:,KG
-ec#RKec,XLeH5g%!!)rI#6<<)!!(OL!;Y1B!<:RL!0,M/!/f;,!2e<HKCZ_Us81=MV#TT>]`<Q~>
-!<E0!joD4BeH#XBeH#XIeIV]1ec41Ms4,["e^a]Mec5Ep!<;uI!<;rH!<<&K#636(s4,["p!j'B
-rRD5Se^a]Mec41Ms8CIJs8LONs4,["psfWLec42"e^a\ZeH#W,eH#WHec19m^&S-0eHMcKk2s>W
-J,~>
-!<E0!joD+?g&M-Gg&M-Ng(+2;g&Tj\!8?-,g=cP\g&Up%!!)rN!!)oM!!*#P"p!B2!8?-,p"BBG
-rRqPXg=cP\g&Tj\!<(UO!<1[S!8?-,pt>rQg&Th,g=cOdg&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5T
-J,~>
-!<E0!joD4BeGoUBeGoUIeIMZ1eH".M!7fU"e^XZMeH#Bp!!)rI!!)oH!!*#K"p!3(!7fU"p!j$B
-rRD2Se^XZMeH".M!<(FJ!<1LN!7fU"psfTLeH","e^XYZeGoT,eGoTHec19m^&S-0eHMcKk2s>W
-J,~>
-!<E0!joD4BeH#XAec5[Kec,UJeHu9+ec41Ms4,["psfBEr7(fIrRLoIrm_,Ne^a^!ec5[DeH#XJ
-ec,UJeH>j%ec5Tu!<<&K"96p%s7k+Ls4./"s4,["NR\%/MU__,VUb^!o"G)'qpbkGs5rIW!.Y~>
-!<E0!joD+?g&M-FgA_0PgAV*Og'Ic5g&Tj\!8?-,pt>]Jr7V,NrS%5Nrn7GSg=cQ+gA_0Ig&M-O
-gAV*Og&h?/g&V**!!*#P!s%'/!;P7Q!87G,!8?-,NS4@4MV8%1VV;'$o"tG,qq;4Is5rIT!.Y~>
-!<E0!joD4BeGoUAec,XKec#RJeHl6+eH".M!7fU"psf?Er7(cIrRLlIrm_)Ne^X[!ec,XDeGoUJ
-ec#RJeH5g%eH#Qu!!*#K!s$m%!;P(L!7_)"!7fU"NR\"/MU_\,VUb^!o"G)'qpbkGs5rIW!.Y~>
-!<E0!joD4BeH#X?eIqo4ec41Ms4,["e^a]Mec41Ms7k+Ks4,["e^a^!eH>j%ec5X!"96p%s8:CI
-s7k+Es8CISs4,["e^a]Mec5Tu!<<&K"96p%s7t4Bs8UULs,GP/s,,>,s/+?HKCZ_Us81=MV#TT>
-]`<Q~>
-!<E0!joD+?g&M-Dg(FD>g&Tj\!8?-,g=cP\g&Tj\!;P7P!8?-,g=cQ+g&h?/g&V-+!s%'/!;tON
-!;P7J!<(UX!8?-,g=cP\g&V**!!*#P!s%'/!;Y@G!<:aQ!0,\4!/fJ1!2eKMJb$\Xs81LRU&X9;
-\c@6~>
-!<E0!joD4BeGoU?eIhl4eH".M!7fU"e^XZMeH".M!;P(K!7fU"e^X[!eH5g%eH#U!!s$m%!;t@I
-!;P(E!<(FS!7fU"e^XZMeH#Qu!!*#K!s$m%!;Y1B!<:RL!0,M/!/f;,!2e<HKCZ_Us81=MV#TT>
-]`<Q~>
-!<E0!joD4BeH#XBec,UIec5[Lec,RSec5["ec5["s7k.Es8UXJs8UXLrrUaNec,RNec5["rr;cD
-rVulIs8W)Krr;uJr;ZfIs8ViD"96pOeboH-eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&M-GgAV*NgA_0QgAV'Xg&M-,g&M-,!;P:J!<:dO!<:dQ!!:jSgAV'Sg&M-,rW)`I
-r;ciNrrE&PrW)rOquHcNrrDfI!s%$TgACr2g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoUBec#RIec,XLec#OSeGoU"eGoU"!;P+E!<:UJ!<:UL!!:[Nec#ONeGoU"rW)`D
-r;ciIrrE&KrW)rJquHcIrrDfD!s$jOebfE-eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#WIeH#XBeH#XCeHGp&s4..,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&M,Ng&M-Gg&M-Hg&qE0!87F1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoTIeGoUBeGoUCeH>m&!7_(,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#WJec#ODec5[>eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&M,OgAM$IgA_0Cg&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoTJeboLDec,X>eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&M,1g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&M,1g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#XGec,W5eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&M-LgA_/:g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoUGec,W5eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#XJeboK2eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&M-OgAM#7g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoUJeboK2eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH5d$eb]?0eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&_9.gA:l5g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeH,a$eb]?0eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeU[^O!1<fes/+?HKCZ_Us81=MV#TT>]`<Q~>
-!<E0!joD+?g496T!13b`gAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeU[^O!13b`ec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH5d$ebfE0eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&_9.gACr5g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeH,a$ebfE0eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#XJeboK2eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&M-OgAM#7g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoUJeboK2eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#XGec,W5eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&M-LgA_/:g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoUGec,W5eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&M,1g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&M,1g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&M,1g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&M,1g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&M,1g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&M,1g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&M,1g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&M,1g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&M,1g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&M,1g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&M,1g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&M,1g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#X.ec5[DeH#XJec5[Jec5[Fec5[BeH#X7eH5d$s8CIJs7t1Fs,,>,s,,>,s/+?H
-KCZ_Us81=MV#TT>]`<Q~>
-!<E0!joD+?g&M-3gA_0Ig&M-OgA_0OgA_0KgA_0Gg&M-<g&_9.!<(UO!;Y=K!/fJ1!/fJ1!2eKM
-Jb$\Xs81LRU&X9;\c@6~>
-!<E0!joD4BeGoU.ec,XDeGoUJec,XJec,XFec,XBeGoU7eH,a$!<(FJ!;Y.F!/f;,!/f;,!2e<H
-KCZ_Us81=MV#TT>]`<Q~>
-!<E0!joD4BeH#X-eH#XFec,UJeHu9+ec41Ms4,["q:,KFp!j'BlI?%;ec41Mrr;fE!<7r,!<7r,
-!<8qHs+BmUs8VuH"f21\k.LbF~>
-!<E0!joD+?g&M-2g&M-KgAV*Og'Ic5g&Tj\!8?-,q:YfKp"BBGlIl@@g&Tj\rW)cJ!!%o1!!%o1
-!!&nMs+0aXs8VuM"ektYk.1PC~>
-!<E0!joD4BeGoU-eGoUFec#RJeHl6+eH".M!7fU"q:,HFp!j$BlI?";eH".MrW)cE!!%o,!!%o,
-!!&nHs+BmUs8VuH"f21\k.LbF~>
-!<E0!joD4BeH#XAec,UJec5[LeH>j%s8W&Jrr;`C!<;rH#636(s4,["q:5KEs4./L"P*PPe^aWu
-rmh&KrRLoIq:5ECrm_#Kq:,KFMU__,MU__,VUb^!o"G)'qpbkGs5rIW!.Y~>
-!<E0!joD+?g&M-FgAV*OgA_0Qg&h?/!!)uOrW)]H!!)oM"p!B2!8?-,q:bfJs4[JQ"PNhUg=lK*
-rn@APrS%5Nq:b`Hrn7>Pq:YfKMV8%1MV8%1VV;'$o"tG,qq;4Is5rIT!.Y~>
-!<E0!joD4BeGoUAec#RJec,XLeH5g%!!)uJrW)]C!!)oH"p!3(!7fU"q:5HEs4.,L"P!JPe^aTu
-rmh#KrRLlIq:5BCrm^uKq:,HFMU_\,MU_\,VUb^!o"G)'qpbkGs5rIW!.Y~>
-!<E0!joD4BeH#XBeH#XIeIV]1ec41Ms4,["e^a]Mec5Bo!<;uI!<<#Js8VlE$3/Q+s4,["e^a^!
-eH#XJeHZ'(ec41Ms7OnDs4./JeH#XFeH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&M-Gg&M-Ng(+2;g&Tj\!8?-,g=cP\g&Um$!!)rN!!)uOrrDiJ#lr]5!8?-,g=cQ+
-g&M-Og'.Q2g&Tj\!;5%I!87GOg&M-Kg&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoUBeGoUIeIMZ1eH".M!7fU"e^XZMeH#?o!!)rI!!)uJrrDiE#lrN+!7fU"e^X[!
-eGoUJeHQ$(eH".M!;4kD!7_)JeGoUFeGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#XAec5[Kec,UJeHu9+ec41Ms4,["pXK9DrRCoJrRD#Me^a]qeHu9+ec41Ms4,["
-rm_#KrRLoIrRLrJpXK?Fec5Tu!<;lF!<7r,!<7r,!<8qHs+BmUs8VuH"f21\k.LbF~>
-!<E0!joD+?g&M-FgA_0PgAV*Og'Ic5g&Tj\!8?-,pY#TIrRq5OrRq>Rg=cQ&g'Ic5g&Tj\!8?-,
-rn7>PrS%5NrS%8OpY#ZKg&V**!!)iK!!%o1!!%o1!!&nMs+0aXs8VuM"ektYk.1PC~>
-!<E0!joD4BeGoUAec,XKec#RJeHl6+eH".M!7fU"pXK6DrRClJrRCuMe^XZqeHl6+eH".M!7fU"
-rm^uKrRLlIrRLoJpXK<FeH#Qu!!)iF!!%o,!!%o,!!&nHs+BmUs8VuH"f21\k.LbF~>
-!<E0!joD4BeH#X?eIqo4ec41Ms4,["e^a]Mec41Ms7b%Ds8LOKs8:CLs4,["q:,fOe^a]Mec41M
-s8LOSs4,["ec41Ms8:CIs7t4Cs8LOKs7t1Fs,,>,s,,>,s/+?HKCZ_Us81=MV#TT>]`<Q~>
-!<E0!joD+?g&M-Dg(FD>g&Tj\!8?-,g=cP\g&Tj\!;G1I!<1[P!;tOQ!8?-,q:Z,Tg=cP\g&Tj\
-!<1[X!8?-,g&Tj\!;tON!;Y@H!<1[P!;Y=K!/fJ1!/fJ1!2eKMJb$\Xs81LRU&X9;\c@6~>
-!<E0!joD4BeGoU?eIhl4eH".M!7fU"e^XZMeH".M!;G"D!<1LK!;t@L!7fU"q:,cOe^XZMeH".M
-!<1LS!7fU"eH".M!;t@I!;Y1C!<1LK!;Y.F!/f;,!/f;,!2e<HKCZ_Us81=MV#TT>]`<Q~>
-!<E0!joD4BeH#XBec,UIec5[Lec,RSec5["ec5["s8(:Es8UXJs8LRKs7t4Ds8CLJs8:FIs8LRK
-s8LRJs7b%Hs4./"ec#OEeH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&M-GgAV*NgA_0QgAV'Xg&M-,g&M-,!;bFJ!<:dO!<1^P!;Y@I!<(XO!;tRN!<1^P
-!<1^O!;G1M!87G,gAM$Jg&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoUBec#RIec,XLec#OSeGoU"eGoU"!;b7E!<:UJ!<1OK!;Y1D!<(IJ!;tCI!<1OK
-!<1OJ!;G"H!7_)"eboLEeGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#WZeH#X1eH5d$s7FhAs,,>,s,,>,s/+?HKCZ_Us81=MV#TT>]`<Q~>
-!<E0!joD+?g&M,_g&M-6g&_9.!;+tF!/fJ1!/fJ1!2eKMJb$\Xs81LRU&X9;\c@6~>
-!<E0!joD4BeGoTZeGoU1eH,a$!;+eA!/f;,!/f;,!2e<HKCZ_Us81=MV#TT>]`<Q~>
-!<E0!joD4BeH#W\ec5ZueH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&M,agA_0%g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT\ec,WueGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&M,1g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&M,1g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#XGec,W5eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&M-LgA_/:g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoUGec,W5eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#XJeboK2eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&M-OgAM#7g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoUJeboK2eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH5d$eb]?0eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&_9.gA:l5g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeH,a$eb]?0eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeU[^O!1<fes/+?HKCZ_Us81=MV#TT>]`<Q~>
-!<E0!joD+?g496T!13b`gAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeU[^O!13b`ec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH5d$ebfE0eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&_9.gACr5g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeH,a$ebfE0eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#XJeboK2eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&M-OgAM#7g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoUJeboK2eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#XGec,W5eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&M-LgA_/:g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoUGec,W5eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&M,1g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&M,1g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&M,1g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&M,1g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&M,1g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&M,1g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&M,1g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&M,1g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&M,1g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&M,1g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&M,1g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&M,1g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#X5ec5[Jec5[Lec5[>ec5ZmeH#XEeH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>W
-J,~>
-!<E0!joD+?g&M-:gA_0OgA_0QgA_0CgA_/rg&M-Jg&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5T
-J,~>
-!<E0!joD4BeGoU5ec,XJec,XLec,X>ec,WmeGoUEeGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>W
-J,~>
-!<E0!joD4BeH#X4eH#XIeH#XKeH#X=eH#WmeH#XEeH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>W
-J,~>
-!<E0!joD+?g&M-9g&M-Ng&M-Pg&M-Bg&M,rg&M-Jg&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5T
-J,~>
-!<E0!joD4BeGoU4eGoUIeGoUKeGoU=eGoTmeGoUEeGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>W
-J,~>
-!<E0!joD4BeH#XAec5[Kec5[HeH#XIeH#XKec,UJec5[Iec5[KeH>j%s8W)K!<;cCs8W&Js8W,L
-$3/QUs4,["ec5[Jec5[Jec5[Kec#OEeH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&M-FgA_0PgA_0Mg&M-Ng&M-PgAV*OgA_0NgA_0Pg&h?/!!*#P!!)`HrrE#OrrE)Q
-#lrZZ!8?-,g&M-OgA_0OgA_0PgAM$Jg&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoUAec,XKec,XHeGoUIeGoUKec#RJec,XIec,XKeH5g%!!*#K!!)`CrrE#JrrE)L
-#lrKU!7fU"eGoUJec,XJec,XKeboLEeGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#XBeH>j%ec5Tu!<;uI!<;uI!<<&K"96p%s8CIJs8LOSs4,["e^a]Ms8CIJs7b%e
-s4,["e^a]Mec41Ms4,["e^a]Mec41Ms4,["e^a]Mec5X!!<;iE!<7r,!<7r,!<8qHs+BmUs8VuH
-"f21\k.LbF~>
-!<E0!joD+?g&M-Gg&h?/g&V**!!)rN!!)rN!!*#P!s%'/!<(UO!<1[X!8?-,g=cP\!<(UO!;G1j
-!8?-,g=cP\g&Tj\!8?-,g=cP\g&Tj\!8?-,g=cP\g&V-+!!)fJ!!%o1!!%o1!!&nMs+0aXs8VuM
-"ektYk.1PC~>
-!<E0!joD4BeGoUBeH5g%eH#Qu!!)rI!!)rI!!*#K!s$m%!<(FJ!<1LS!7fU"e^XZM!<(FJ!;G"e
-!7fU"e^XZMeH".M!7fU"e^XZMeH".M!7fU"e^XZMeH#U!!!)fE!!%o,!!%o,!!&nHs+BmUs8VuH
-"f21\k.LbF~>
-!<E0!joD4BeH#XBeH#XIec,UHeH#XIeH#XKeHQ!'ec41Mrr;uJ!<;uIs8VW>!<;uI&c^D3s4,["
-e^a]Mec41Ms4,[!s8LOKs81=Hs7k+Es,,>,s,,>,s/+?HKCZ_Us81=MV#TT>]`<Q~>
-!<E0!joD+?g&M-Gg&M-NgAV*Mg&M-Ng&M-Pg'%K1g&Tj\rW)rO!!)rNrrDTC!!)rN&HLP=!8?-,
-g=cP\g&Tj\!8?0+!<1[P!;kIM!;P7J!/fJ1!/fJ1!2eKMJb$\Xs81LRU&X9;\c@6~>
-!<E0!joD4BeGoUBeGoUIec#RHeGoUIeGoUKeHGs'eH".MrW)rJ!!)rIrrDT>!!)rI&HLA3!7fU"
-e^XZMeH".M!7fX!!<1LK!;k:H!;P(E!/f;,!/f;,!2e<HKCZ_Us81=MV#TT>]`<Q~>
-!<E0!joD4BeH#XBeHl3*ec42"e^a]teH#XIeH#XKeHl3*ec42"e^a^!eHl3*ec41Ms4./JeH#XD
-eKOtCec41Ms4,["e^a]Mec41Ms4,["e^a]Mec41Ms4,["rm_,Ne^a]seH#W,eH#W,eH#WHec19m
-^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&M-Gg'@]4g&Th,g=cQ)g&M-Ng&M-Pg'@]4g&Th,g=cQ+g'@]4g&Tj\!87GOg&M-I
-g*$IMg&Tj\!8?-,g=cP\g&Tj\!8?-,g=cP\g&Tj\!8?-,rn7GSg=cQ(g&M,1g&M,1g&M,MgAc`p
-_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoUBeHc0*eH","e^XZteGoUIeGoUKeHc0*eH","e^X[!eHc0*eH".M!7_)JeGoUD
-eKFqCeH".M!7fU"e^XZMeH".M!7fU"e^XZMeH".M!7fU"rm_)Ne^XZseGoT,eGoT,eGoTHec19m
-^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#XAec5[Kec5XOec41Mr;QcIq#C?Ds8N,Ms8LRKs8UXLrrUaNs8LOKs7Y"Cs8CLJ
-s8UXKrrCUIrs%$Rs4,["s8CLJs8:FIs8(7Gs,,>,s,,>,s/+?HKCZ_Us81=MV#TT>]`<Q~>
-!<E0!joD+?g&M-FgA_0PgA_-Tg&Tj\qu?`Np]1<Irr<)R!<1^P!<:dQ!!:jS!<1[P!;>.H!<(XO
-!<:dP!!(aN!!_-W!8?-,!<(XO!;tRN!;bCL!/fJ1!/fJ1!2eKMJb$\Xs81LRU&X9;\c@6~>
-!<E0!joD4BeGoUAec,XKec,UOeH".Mqu?`Ip]1<Drr<)M!<1OK!<:UL!!:[N!<1LK!;=tC!<(IJ
-!<:UK!!(RI!!^sR!7fU"!<(IJ!;tCI!;b4G!/f;,!/f;,!2e<HKCZ_Us81=MV#TT>]`<Q~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&M,1g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&M,1g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&M,1g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&M,1g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W5ec,XGeH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&M,:gA_0Lg&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT5ec,XGeGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W5eboLGeH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&M,:gAM$Lg&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT5eboLGeGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W4eb]@HeH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&M,9gA:mMg&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT4eb]@HeGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeVO8+s,,>,s,,>,s/+?HKCZ_Us81=MV#TT>]`<Q~>
-!<E0!joD+?g5#`dg&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeVF3_eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W4eb]@HeH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&M,9gA:mMg&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT4eb]@HeGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W4ec#RHeH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&M,9gAV*Mg&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT4ec#RHeGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W5ec,XGeH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&M,:gA_0Lg&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT5ec,XGeGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&M,1g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&M,1g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&M,1g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&M,1g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&M,1g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&M,1g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&M,1g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&M,1g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&M,1g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&M,1g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&M,1g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&M,1g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#X5eH#W\eH#X9eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&M-:g&M,ag&M->g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoU5eGoT\eGoU9eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#X5eH#W\eH#X9eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&M-:g&M,ag&M->g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoU5eGoT\eGoU9eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#XBeH,^#rr<#Ks8W)KrVm2Ss8UXLs4,["ec#LLec5[JeH#XCec5[Jec5[LeHu9+
-s8UX"s4./LrRLrJrRLrJrmguImaV=;MU__,MU__,VUb^!o"G)'qpbkGs5rIW!.Y~>
-!<E0!joD+?g&M-Gg&V3-rW)uPrrE&Pr;[/X!!(^Q!8?-,gAM!Qg&M-Og&M-HgA_0OgA_0Qg'Ic5
-!!(a,!87DQrS%8OrS%8Orn@;Nmb.X@MV8%1MV8%1VV;'$o"tG,qq;4Is5rIT!.Y~>
-!<E0!joD4BeGoUBeH#[#rW)uKrrE&Kr;[/S!!(OL!7fU"eboILeGoUJeGoUCec,XJec,XLeHl6+
-!!(R"!7_&LrRLoJrRLoJrmgrImaV:;MU_\,MU_\,VUb^!o"G)'qpbkGs5rIW!.Y~>
-!<E0!joD4BeH#XAeH#XJeH>j%ec5X!!<<#J"96p%s8LOKs8CIMs4,["rm_#KpXLGee^a]Mec41M
-s4,["e^a]Mec41Ms4,["e^a]Mec41Ms8LOKs6S89s,,>,s,,>,s/+?HKCZ_Us81=MV#TT>]`<Q~>
-!<E0!joD+?g&M-Fg&M-Og&h?/g&V-+!!)uO!s%'/!<1[P!<(UR!8?-,rn7>PpY$bjg=cP\g&Tj\
-!8?-,g=cP\g&Tj\!8?-,g=cP\g&Tj\!<1[P!:8D>!/fJ1!/fJ1!2eKMJb$\Xs81LRU&X9;\c@6~>
-!<E0!joD4BeGoUAeGoUJeH5g%eH#U!!!)uJ!s$m%!<1LK!<(FM!7fU"rm^uKpXLDee^XZMeH".M
-!7fU"e^XZMeH".M!7fU"e^XZMeH".M!<1LK!:859!/f;,!/f;,!2e<HKCZ_Us81=MV#TT>]`<Q~>
-!<E0!joD4BeH#XAeH#XJec,UIeH#XJeH>j%ec5X!!<<#J"96p%s7=b@s8:CZs4,["e^a]Mec41M
-s4,["e^a[!rm_#Kqpb]Hm*u+9MU__,MU__,VUb^!o"G)'qpbkGs5rIW!.Y~>
-!<E0!joD+?g&M-Fg&M-OgAV*Ng&M-Og&h?/g&V-+!!)uO!s%'/!;"nE!;tO_!8?-,g=cP\g&Tj\
-!8?-,g=lN+rn7>Pqq;#Mm+MF>MV8%1MV8%1VV;'$o"tG,qq;4Is5rIT!.Y~>
-!<E0!joD4BeGoUAeGoUJec#RIeGoUJeH5g%eH#U!!!)uJ!s$m%!;"_@!;t@Z!7fU"e^XZMeH".M
-!7fU"e^aX!rm^uKqpbZHm*u(9MU_\,MU_\,VUb^!o"G)'qpbkGs5rIW!.Y~>
-!<E0!joD4BeH#XAeH#XJeH>j%ec5X!#liH*s4./"ec5X!!<<#J"96p%s8LOKs7b%es4,["e^a]M
-ec41Ms4,["e^a]Mec41Ms4,["e^a]Mec5X!"96p%s6nJ<s,,>,s,,>,s/+?HKCZ_Us81=MV#TT>
-]`<Q~>
-!<E0!joD+?g&M-Fg&M-Og&h?/g&V-+#QWT4!87G,g&V-+!!)uO!s%'/!<1[P!;G1j!8?-,g=cP\
-g&Tj\!8?-,g=cP\g&Tj\!8?-,g=cP\g&V-+!s%'/!:SVA!/fJ1!/fJ1!2eKMJb$\Xs81LRU&X9;
-\c@6~>
-!<E0!joD4BeGoUAeGoUJeH5g%eH#U!#QWE*!7_)"eH#U!!!)uJ!s$m%!<1LK!;G"e!7fU"e^XZM
-eH".M!7fU"e^XZMeH".M!7fU"e^XZMeH#U!!s$m%!:SG<!/f;,!/f;,!2e<HKCZ_Us81=MV#TT>
-]`<Q~>
-!<E0!joD4BeH#XBec#OIec5[Iec5[Kec5XNec41urrCUKrrpsQs4,["p=93CrRLrJs4.,K!7h#I
-#1`bRe^a^"rRLrJr71iImaV=;MU__,MU__,VUb^!o"G)'qpbkGs5rIW!.Y~>
-!<E0!joD+?g&M-GgAM$NgA_0NgA_0PgA_-Sg&Tk*!!(aP!!V'V!8?-,p=fNHrS%8Os4[GP!8@>N
-#20%Wg=cN,rS%8Or7_/Nmb.X@MV8%1MV8%1VV;'$o"tG,qq;4Is5rIT!.Y~>
-!<E0!joD4BeGoUBeboLIec,XIec,XKec,UNeH".u!!(RK!!UmQ!7fU"p=90CrRLoJs4.)K!7guI
-#1W\Re^XX"rRLoJr71fImaV:;MU_\,MU_\,VUb^!o"G)'qpbkGs5rIW!.Y~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&M,1g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&M,1g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&M,1g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&M,1g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#XGec,W5eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&M-LgA_/:g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoUGec,W5eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#XJeboK2eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&M-OgAM#7g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoUJeboK2eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH5d$eb]?0eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&_9.gA:l5g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeH,a$eb]?0eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeVO8+s,,>,s,,>,s/+?HKCZ_Us81=MV#TT>]`<Q~>
-!<E0!joD+?g5#`dg&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeVF3_eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH5d$ebfE0eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&_9.gACr5g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeH,a$ebfE0eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#XJeboK2eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&M-OgAM#7g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoUJeboK2eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#XGec,W5eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&M-LgA_/:g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoUGec,W5eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&M,1g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&M,1g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&M,1g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&M,1g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&M,1g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&M,1g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&M,1g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&M,1g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&M,1g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&M,1g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&M,1g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&M,1g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#X(eH#X7eH#XJec5[Jec5[Fec5[BeH#X9eH#W,eH#W,eH#WHec19m^&S-0eHMcK
-k2s>WJ,~>
-!<E0!joD+?g&M--g&M-<g&M-OgA_0OgA_0KgA_0Gg&M->g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2M
-k2s5TJ,~>
-!<E0!joD4BeGoU(eGoU7eGoUJec,XJec,XFec,XBeGoU9eGoT,eGoT,eGoTHec19m^&S-0eHMcK
-k2s>WJ,~>
-!<E0!joD4BeH#Wgec,UJeHu9+ec41Ms4,["q:,KFp!j'Bm*u+9MU__,MU__,VUb^!o"G)'qpbkG
-s5rIW!.Y~>
-!<E0!joD+?g&M,lgAV*Og'Ic5g&Tj\!8?-,q:YfKp"BBGm+MF>MV8%1MV8%1VV;'$o"tG,qq;4I
-s5rIT!.Y~>
-!<E0!joD4BeGoTgec#RJeHl6+eH".M!7fU"q:,HFp!j$Bm*u(9MU_\,MU_\,VUb^!o"G)'qpbkG
-s5rIW!.Y~>
-!<E0!joD4BeH#XBeH,^#rr<#Ks8W&Js8W&Js8W&Js8W,Ls8W,Ls8W,Ls8VfC!<;rH#636(s4,["
-q:5KEs4./L"P*PPe^aWurmh&KrRLoIqUGTGMU__,MU__,VUb^!o"G)'qpbkGs5rIW!.Y~>
-!<E0!joD+?g&M-Gg&V3-rW)uPrrE#OrrE#OrrE#OrrE)QrrE)QrrE)QrrDcH!!)oM"p!B2!8?-,
-q:bfJs4[JQ"PNhUg=lK*rn@APrS%5NqUtoLMV8%1MV8%1VV;'$o"tG,qq;4Is5rIT!.Y~>
-!<E0!joD4BeGoUBeH#[#rW)uKrrE#JrrE#JrrE#JrrE)LrrE)LrrE)LrrDcC!!)oH"p!3(!7fU"
-q:5HEs4.,L"P!JPe^aTurmh#KrRLlIqUGQGMU_\,MU_\,VUb^!o"G)'qpbkGs5rIW!.Y~>
-!<E0!joD4BeH#XAeH#XJeIV]1ec41Ms4,["e^a]Mec5Tu!<<&K!<<&K"om-Qe^a]oeH#XIeH#XJ
-ec5[EeHu9+ec41Ms4,["rm_#KrRD,Pe^a]Mec5Bo!<7r,!<7r,!<8qHs+BmUs8VuH"f21\k.LbF~>
-!<E0!joD+?g&M-Fg&M-Og(+2;g&Tj\!8?-,g=cP\g&V**!!*#P!!*#P"T[6Vg=cQ$g&M-Ng&M-O
-gA_0Jg'Ic5g&Tj\!8?-,rn7>PrRqGUg=cP\g&Um$!!%o1!!%o1!!&nMs+0aXs8VuM"ektYk.1PC~>
-!<E0!joD4BeGoUAeGoUJeIMZ1eH".M!7fU"e^XZMeH#Qu!!*#K!!*#K"T['Qe^XZoeGoUIeGoUJ
-ec,XEeHl6+eH".M!7fU"rm^uKrRD)Pe^XZMeH#?o!!%o,!!%o,!!&nHs+BmUs8VuH"f21\k.LbF~>
-!<E0!joD4BeH#XAeH#XJec,UJeH#XIec,UHeH#XJeHGp&s4,[!s7XtCs8CIJs8CIMs4,["q:,fO
-e^a]Mec41Ms8LOKs8CLIs8CLJs7t1Fs,,>,s,,>,s/+?HKCZ_Us81=MV#TT>]`<Q~>
-!<E0!joD+?g&M-Fg&M-OgAV*Og&M-NgAV*Mg&M-Og&qE0!8?0+!;>+H!<(UO!<(UR!8?-,q:Z,T
-g=cP\g&Tj\!<1[P!<(XN!<(XO!;Y=K!/fJ1!/fJ1!2eKMJb$\Xs81LRU&X9;\c@6~>
-!<E0!joD4BeGoUAeGoUJec#RJeGoUIec#RHeGoUJeH>m&!7fX!!;=qC!<(FJ!<(FM!7fU"q:,cO
-e^XZMeH".M!<1LK!<(II!<(IJ!;Y.F!/f;,!/f;,!2e<HKCZ_Us81=MV#TT>]`<Q~>
-!<E0!joD4BeH#XAeH#XJeIV]1ec41Ms4,["e^a]Mec5Tu!<<#J#liHTe^a]Mec5Bo!<<&K!<;uI
-"96p%s7t1Os4,["e^a]Mec5X!#liH*s4./"ec5Qt!<;oG!<7r,!<7r,!<8qHs+BmUs8VuH"f21\
-k.LbF~>
-!<E0!joD+?g&M-Fg&M-Og(+2;g&Tj\!8?-,g=cP\g&V**!!)uO#QWQYg=cP\g&Um$!!*#P!!)rN
-!s%'/!;Y=T!8?-,g=cP\g&V-+#QWT4!87G,g&V')!!)lL!!%o1!!%o1!!&nMs+0aXs8VuM"ektY
-k.1PC~>
-!<E0!joD4BeGoUAeGoUJeIMZ1eH".M!7fU"e^XZMeH#Qu!!)uJ#QWBTe^XZMeH#?o!!*#K!!)rI
-!s$m%!;Y.O!7fU"e^XZMeH#U!#QWE*!7_)"eH#Nt!!)lG!!%o,!!%o,!!&nHs+BmUs8VuH"f21\
-k.LbF~>
-!<E0!joD4BeH#XBec#OIec5[Jec5[Jec5[KeboIHeH#XJec5[Eec#OJec#OIec5[Fec#OHec5[I
-ec5[Kec5[Kec,UEeH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&M-GgAM$NgA_0OgA_0OgA_0PgACsMg&M-OgA_0JgAM$OgAM$NgA_0KgAM$MgA_0N
-gA_0PgA_0PgAV*Jg&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoUBeboLIec,XJec,XJec,XKebfFHeGoUJec,XEeboLJeboLIec,XFeboLHec,XI
-ec,XKec,XKec#REeGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#WHeH#X3eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&M,Mg&M-8g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoTHeGoU3eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#WJec5[2eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&M,OgA_07g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoTJec,X2eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&M,1g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&M,1g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#XGec,W5eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&M-LgA_/:g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoUGec,W5eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#XJeboK2eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&M-OgAM#7g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoUJeboK2eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH5d$eb]?0eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&_9.gA:l5g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeH,a$eb]?0eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeU[^O!1<fes/+?HKCZ_Us81=MV#TT>]`<Q~>
-!<E0!joD+?g496T!13b`gAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeU[^O!13b`ec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH5d$ebfE0eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&_9.gACr5g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeH,a$ebfE0eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#XJeboK2eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&M-OgAM#7g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoUJeboK2eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#XGec,W5eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&M-LgA_/:g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoUGec,W5eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&M,1g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&M,1g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&M,1g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&M,1g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&M,1g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&M,1g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&M,1g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&M,1g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&M,1g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&M,1g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&M,1g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&M,1g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#XAeH#Wnec5[>eH5d$s8CIJs6%o4s,,>,s,,>,s/+?HKCZ_Us81=MV#TT>]`<Q~>
-!<E0!joD+?g&M-Fg&M,sgA_0Cg&_9.!<(UO!9`&9!/fJ1!/fJ1!2eKMJb$\Xs81LRU&X9;\c@6~>
-!<E0!joD4BeGoUAeGoTnec,X>eH,a$!<(FJ!9_l4!/f;,!/f;,!2e<HKCZ_Us81=MV#TT>]`<Q~>
-!<E0!joD4BeH#XAeH#WmeH#X>eHGp&s4,[!s6%o4s,,>,s,,>,s/+?HKCZ_Us81=MV#TT>]`<Q~>
-!<E0!joD+?g&M-Fg&M,rg&M-Cg&qE0!8?0+!9`&9!/fJ1!/fJ1!2eKMJb$\Xs81LRU&X9;\c@6~>
-!<E0!joD4BeGoUAeGoTmeGoU>eH>m&!7fX!!9_l4!/f;,!/f;,!2e<HKCZ_Us81=MV#TT>]`<Q~>
-!<E0!joD4BeH#XBec#OJeH,^#rr3&Ms8W)K"96pOs8CLIs7t1Gs4.,Ks4./Ls4%5Oec5[IeHc-)
-ec5["s8VoFr;ZcH!<;64!<7r,!<7r,!<8qHs+BmUs8VuH"f21\k.LbF~>
-!<E0!joD+?g&M-GgAM$Og&V3-rW!#R!!*#P!s%$T!<(XN!;Y=L!8@DPs4[JQs4RPTg&M-Ng'7W3
-g&M-,!!)iKquH`M!!)39!!%o1!!%o1!!&nMs+0aXs8VuM"ektYk.1PC~>
-!<E0!joD4BeGoUBeboLJeH#[#rW!#M!!*#K!s$jO!<(II!;Y.G!7h&Ks4.,Ls4%2OeGoUIeHZ*)
-eGoU"!!)iFquH`H!!)34!!%o,!!%o,!!&nHs+BmUs8VuH"f21\k.LbF~>
-!<E0!joD4BeH#XAeH#XIeH#XHeH#XKeHZ'(ec41Ms7OnBs8CISs4,["e^a]Mec5Tu!<<&K"96p%
-s7k+Gs4./JeH#X4eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&M-Fg&M-Ng&M-Mg&M-Pg'.Q2g&Tj\!;5%G!<(UX!8?-,g=cP\g&V**!!*#P!s%'/
-!;P7L!87GOg&M-9g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoUAeGoUIeGoUHeGoUKeHQ$(eH".M!;4kB!<(FS!7fU"e^XZMeH#Qu!!*#K!s$m%
-!;P(G!7_)JeGoU4eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#XAeH#XIeH#XJec,UJeH>j%ec5X!s8ViD!<<#Jrr;uJ"96p%s8CIJs8LONs4,["
-psfHGec5Tu!<;64!<7r,!<7r,!<8qHs+BmUs8VuH"f21\k.LbF~>
-!<E0!joD+?g&M-Fg&M-Ng&M-OgAV*Og&h?/g&V-+rrDfI!!)uOrW)rO!s%'/!<(UO!<1[S!8?-,
-pt>cLg&V**!!)39!!%o1!!%o1!!&nMs+0aXs8VuM"ektYk.1PC~>
-!<E0!joD4BeGoUAeGoUIeGoUJec#RJeH5g%eH#U!rrDfD!!)uJrW)rJ!s$m%!<(FJ!<1LN!7fU"
-psfEGeH#Qu!!)34!!%o,!!%o,!!&nHs+BmUs8VuH"f21\k.LbF~>
-!<E0!joD4BeH#XAeHZ'(ec41Ms8LONs4,["rm_,Ne^a]teH#XEeH#XJeHu9+ec41Ms4,["rRCoJ
-rm_,Ne^a]qeboIHeH#X4eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&M-Fg'.Q2g&Tj\!<1[S!8?-,rn7GSg=cQ)g&M-Jg&M-Og'Ic5g&Tj\!8?-,rRq5O
-rn7GSg=cQ&gACsMg&M-9g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoUAeHQ$(eH".M!<1LN!7fU"rm_)Ne^XZteGoUEeGoUJeHl6+eH".M!7fU"rRClJ
-rm_)Ne^XZqebfFHeGoU4eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#X@ec5[Lec#OJec5XNec42!rr^gOs4.,Kpso?Crmh&Krmh#JrmgrHs4./LpXKEH
-ec41MrVu*3!<7r,!<7r,!<8qHs+BmUs8VuH"f21\k.LbF~>
-!<E0!joD+?g&M-EgA_0QgAM$OgA_-Sg&Tk+!!CpT!8@DPptGZHrn@APrn@>Orn@8Ms4[JQpY#`M
-g&Tj\r;c'8!!%o1!!%o1!!&nMs+0aXs8VuM"ektYk.1PC~>
-!<E0!joD4BeGoU@ec,XLeboLJec,UNeH"/!!!CaO!7h&Kpso<Crmh#KrmguJrmgoHs4.,LpXKBH
-eH".Mr;c'3!!%o,!!%o,!!&nHs+BmUs8VuH"f21\k.LbF~>
-!<E0!joD4BeH#WgeH#XBeH#XCeH5d$s5MQ/s,,>,s,,>,s/+?HKCZ_Us81=MV#TT>]`<Q~>
-!<E0!joD+?g&M,lg&M-Gg&M-Hg&_9.!92]4!/fJ1!/fJ1!2eKMJb$\Xs81LRU&X9;\c@6~>
-!<E0!joD4BeGoTgeGoUBeGoUCeH,a$!92N/!/f;,!/f;,!2e<HKCZ_Us81=MV#TT>]`<Q~>
-!<E0!joD4BeH#Whec#ODec5ZueH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&M,mgAM$IgA_0%g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoTheboLDec,WueGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&M,1g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&M,1g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W5ec,XGeH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&M,1g&M,1g&M,:gA_0Lg&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT5ec,XGeGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W5eboLGeH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&M,1g&M,1g&M,:gAM$Lg&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT5eboLGeGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W4eb]@HeH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&M,1g&M,1g&M,9gA:mMg&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT4eb]@HeGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeU[^O!1<fes/+?HKCZ_Us81=MV#TT>]`<Q~>
-!<E0!joD+?g496T!13b`gAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeU[^O!13b`ec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W4eb]@HeH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&M,1g&M,1g&M,9gA:mMg&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT4eb]@HeGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W4ec#RHeH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&M,1g&M,1g&M,9gAV*Mg&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT4ec#RHeGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W5ec,XGeH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&M,1g&M,1g&M,:gA_0Lg&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT5ec,XGeGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&M,1g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&M,1g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&M,1g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&M,1g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&M,1g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&M,1g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&M,1g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&M,1g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&M,1g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&M,1g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&M,1g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&M,1g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#X5ec5[Jec5[Lec5[>ec5[<eH#X!eH#XGec5[>eH5d$s8CIJs/XZMs,,>,s/+?H
-KCZ_Us81=MV#TT>]`<Q~>
-!<E0!joD+?g&M-:gA_0OgA_0QgA_0CgA_0Ag&M-&g&M-LgA_0Cg&_9.!<(UO!3=fR!/fJ1!2eKM
-Jb$\Xs81LRU&X9;\c@6~>
-!<E0!joD4BeGoU5ec,XJec,XLec,X>ec,X<eGoU!eGoUGec,X>eH,a$!<(FJ!3=WM!/f;,!2e<H
-KCZ_Us81=MV#TT>]`<Q~>
-!<E0!joD4BeH#X4eH#XIeH#XKeH#X=eH#X<eH#X!eH#XFeH#X>eHGp&s4,[!s/XZMs,,>,s/+?H
-KCZ_Us81=MV#TT>]`<Q~>
-!<E0!joD+?g&M-9g&M-Ng&M-Pg&M-Bg&M-Ag&M-&g&M-Kg&M-Cg&qE0!8?0+!3=fR!/fJ1!2eKM
-Jb$\Xs81LRU&X9;\c@6~>
-!<E0!joD4BeGoU4eGoUIeGoUKeGoU=eGoU<eGoU!eGoUFeGoU>eH>m&!7fX!!3=WM!/f;,!2e<H
-KCZ_Us81=MV#TT>]`<Q~>
-!<E0!joD4BeH#XAec5[Kec5[HeH#XIeH#XKec,UJec5[Iec5[KeH>j%s8W)K!<;fDrVuoJ!WU^L
-rrUaNs8LONs4./LrRLoIq:,NGec,UKec5[LeH>j%s8W#I#QN?)s8UXLs7t4Cs8LOKs/XZMs,,>,
-s/+?HKCZ_Us81=MV#TT>]`<Q~>
-!<E0!joD+?g&M-FgA_0PgA_0Mg&M-Ng&M-PgAV*OgA_0NgA_0Pg&h?/!!*#P!!)cIr;clO!<CjQ
-!!:jS!<1[S!87DQrS%5Nq:YiLgAV*PgA_0Qg&h?/!!)rN#6<K3!!(^Q!;Y@H!<1[P!3=fR!/fJ1
-!2eKMJb$\Xs81LRU&X9;\c@6~>
-!<E0!joD4BeGoUAec,XKec,XHeGoUIeGoUKec#RJec,XIec,XKeH5g%!!*#K!!)cDr;clJ!<C[L
-!!:[N!<1LN!7_&LrRLlIq:,KGec#RKec,XLeH5g%!!)rI#6<<)!!(OL!;Y1C!<1LK!3=WM!/f;,
-!2e<HKCZ_Us81=MV#TT>]`<Q~>
-!<E0!joD4BeH#XBeH>j%ec5Tu!<;uI!<;uI!<<&K"96p%s8CIJs8LOSs4,["e^a]Ms8CIJs7XtC
-s8:CIs81=Hs8LOQs4,["e^a]meH#XJeHu9+ec42"s4,["rRCoJrm_,Ne^a]peH5d$s8CIJs/XZM
-s,,>,s/+?HKCZ_Us81=MV#TT>]`<Q~>
-!<E0!joD+?g&M-Gg&h?/g&V**!!)rN!!)rN!!*#P!s%'/!<(UO!<1[X!8?-,g=cP\!<(UO!;>+H
-!;tON!;kIM!<1[V!8?-,g=cQ"g&M-Og'Ic5g&Th,!8?-,rRq5Orn7GSg=cQ%g&_9.!<(UO!3=fR
-!/fJ1!2eKMJb$\Xs81LRU&X9;\c@6~>
-!<E0!joD4BeGoUBeH5g%eH#Qu!!)rI!!)rI!!*#K!s$m%!<(FJ!<1LS!7fU"e^XZM!<(FJ!;=qC
-!;t@I!;k:H!<1LQ!7fU"e^XZmeGoUJeHl6+eH","!7fU"rRClJrm_)Ne^XZpeH,a$!<(FJ!3=WM
-!/f;,!2e<HKCZ_Us81=MV#TT>]`<Q~>
-!<E0!joD4BeH#XBeH#XIec,UHeH#XIeH#XKeHQ!'ec41Mrr;uJ!<;uIs8VT=!<;uI!<<#Jrr;uJ
-"96p%s8LRKs7b%Ds8CLIs8UXLs8UULs8CIJs8LONs4,["psfHGec5Tu!<9+M!<7r,!<8qHs+BmU
-s8VuH"f21\k.LbF~>
-!<E0!joD+?g&M-Gg&M-NgAV*Mg&M-Ng&M-Pg'%K1g&Tj\rW)rO!!)rNrrDQB!!)rN!!)uOrW)rO
-!s%'/!<1^P!;G1I!<(XN!<:dQ!<:aQ!<(UO!<1[S!8?-,pt>cLg&V**!!'(R!!%o1!!&nMs+0aX
-s8VuM"ektYk.1PC~>
-!<E0!joD4BeGoUBeGoUIec#RHeGoUIeGoUKeHGs'eH".MrW)rJ!!)rIrrDQ=!!)rI!!)uJrW)rJ
-!s$m%!<1OK!;G"D!<(II!<:UL!<:RL!<(FJ!<1LN!7fU"psfEGeH#Qu!!'(M!!%o,!!&nHs+BmU
-s8VuH"f21\k.LbF~>
-!<E0!joD4BeH#XBeHl3*ec42"e^a]teH#XIeH#XKeHl3*ec42"e^a^!eHl3*ec41Ms4./JeH#XC
-eHZ'(ec41Ms8LONs4,["rm_,Ne^a]teH#XEeH#XJeHu9+ec42"s4,["rRCoJrm_,Ne^a]qeboIH
-eH#WMeH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&M-Gg'@]4g&Th,g=cQ)g&M-Ng&M-Pg'@]4g&Th,g=cQ+g'@]4g&Tj\!87GOg&M-H
-g'.Q2g&Tj\!<1[S!8?-,rn7GSg=cQ)g&M-Jg&M-Og'Ic5g&Th,!8?-,rRq5Orn7GSg=cQ&gACsM
-g&M,Rg&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoUBeHc0*eH","e^XZteGoUIeGoUKeHc0*eH","e^X[!eHc0*eH".M!7_)JeGoUC
-eHQ$(eH".M!<1LN!7fU"rm_)Ne^XZteGoUEeGoUJeHl6+eH","!7fU"rRClJrm_)Ne^XZqebfFH
-eGoTMeGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#XAec5[Kec5XOec41Mr;QcIq#C?Ds8N,Ms8LRKs8UXLrrUaNs8LOKs7OqBs8UXJ
-s8UXLrrUaNec,RNec5["rr;cDrVulIs8W,LrVulIr;ZfIs8ViD"TR$Pe^aWuXOR=NMU__,VUb^!
-o"G)'qpbkGs5rIW!.Y~>
-!<E0!joD+?g&M-FgA_0PgA_-Tg&Tj\qu?`Np]1<Irr<)R!<1^P!<:dQ!!:jS!<1[P!;5(G!<:dO
-!<:dQ!!:jSgAV'Sg&M-,rW)`Ir;ciNrrE)Qr;ciNquHcNrrDfI"9@-Ug=lK*XP*XSMV8%1VV;'$
-o"tG,qq;4Is5rIT!.Y~>
-!<E0!joD4BeGoUAec,XKec,UOeH".Mqu?`Ip]1<Drr<)M!<1OK!<:UL!!:[N!<1LK!;4nB!<:UJ
-!<:UL!!:[Nec#ONeGoU"rW)`Dr;ciIrrE)Lr;ciIquHcIrrDfD"9?sPe^aTuXOR:NMU_\,VUb^!
-o"G)'qpbkGs5rIW!.Y~>
-!<E0!joD4BeH#W,ec5[BeH#XCeH5d$s/+<Hs,,>,s/+?HKCZ_Us81=MV#TT>]`<Q~>
-!<E0!joD+?g&M,1gA_0Gg&M-Hg&_9.!2eHM!/fJ1!2eKMJb$\Xs81LRU&X9;\c@6~>
-!<E0!joD4BeGoT,ec,XBeGoUCeH,a$!2e9H!/f;,!2e<HKCZ_Us81=MV#TT>]`<Q~>
-!<E0!joD4BeH#W,ec#ODec5Z9eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&M,1gAM$IgA_/>g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eboLDec,W9eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&M,1g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&M,1g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W5ec,XGeH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&M,:gA_0Lg&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT5ec,XGeGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W5eboLGeH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&M,:gAM$Lg&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT5eboLGeGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W4eb]@HeH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&M,9gA:mMg&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT4eb]@HeGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeVO8+s,,>,s,,>,s/+?HKCZ_Us81=MV#TT>]`<Q~>
-!<E0!joD+?g5#`dg&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeVF3_eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W4eb]@HeH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&M,9gA:mMg&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT4eb]@HeGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W4ec#RHeH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&M,9gAV*Mg&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT4ec#RHeGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W5ec,XGeH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&M,:gA_0Lg&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT5ec,XGeGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&M,1g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&M,1g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&M,1g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&M,1g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&M,1g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&M,1g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&M,1g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&M,1g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&M,1g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&M,1g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&M,1g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&M,1g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#X5ec5[Jec5[Lec5[>ec5[:eH#X?ec5[Jec5[KeH#XBeH#XKeH#Wrec5[>eH5d$
-s8CIJs4,X"s,,>,s/+?HKCZ_Us81=MV#TT>]`<Q~>
-!<E0!joD+?g&M-:gA_0OgA_0QgA_0CgA_0?g&M-DgA_0OgA_0Pg&M-Gg&M-Pg&M-"gA_0Cg&_9.
-!<(UO!7fd'!/fJ1!2eKMJb$\Xs81LRU&X9;\c@6~>
-!<E0!joD4BeGoU5ec,XJec,XLec,X>ec,X:eGoU?ec,XJec,XKeGoUBeGoUKeGoTrec,X>eH,a$
-!<(FJ!7fU"!/f;,!2e<HKCZ_Us81=MV#TT>]`<Q~>
-!<E0!joD4BeH#X4eH#XIeH#XKeH#X=eH#X;eH#X=eH#XIeH#XJeH#XCeH#XKeH#WqeH#X>eHGp&
-s4,[!s4,X"s,,>,s/+?HKCZ_Us81=MV#TT>]`<Q~>
-!<E0!joD+?g&M-9g&M-Ng&M-Pg&M-Bg&M-@g&M-Bg&M-Ng&M-Og&M-Hg&M-Pg&M-!g&M-Cg&qE0
-!8?0+!7fd'!/fJ1!2eKMJb$\Xs81LRU&X9;\c@6~>
-!<E0!joD4BeGoU4eGoUIeGoUKeGoU=eGoU;eGoU=eGoUIeGoUJeGoUCeGoUKeGoTqeGoU>eH>m&
-!7fX!!7fU"!/f;,!2e<HKCZ_Us81=MV#TT>]`<Q~>
-!<E0!joD4BeH#XAec5[Kec5[HeH#XIeH#XKec,UJec5[Iec5[KeH>j%s8W)K!<;`B!<<#Js8W)K
-s8VuH!<;uI!<<#J!<;fDrVluMs8UXKrrUaNs8LONs4./LrRLoIq:,NGec,UKec5[LeH>j%s8W#I
-#QN?)s8UXLs7t4Cs8LOKs4,X"s,,>,s/+?HKCZ_Us81=MV#TT>]`<Q~>
-!<E0!joD+?g&M-FgA_0PgA_0Mg&M-Ng&M-PgAV*OgA_0NgA_0Pg&h?/!!*#P!!)]G!!)uOrrE&P
-rrDrM!!)rN!!)uO!!)cIr;ZrR!!(aP!!:jS!<1[S!87DQrS%5Nq:YiLgAV*PgA_0Qg&h?/!!)rN
-#6<K3!!(^Q!;Y@H!<1[P!7fd'!/fJ1!2eKMJb$\Xs81LRU&X9;\c@6~>
-!<E0!joD4BeGoUAec,XKec,XHeGoUIeGoUKec#RJec,XIec,XKeH5g%!!*#K!!)]B!!)uJrrE&K
-rrDrH!!)rI!!)uJ!!)cDr;ZrM!!(RK!!:[N!<1LN!7_&LrRLlIq:,KGec#RKec,XLeH5g%!!)rI
-#6<<)!!(OL!;Y1C!<1LK!7fU"!/f;,!2e<HKCZ_Us81=MV#TT>]`<Q~>
-!<E0!joD4BeH#XBeH>j%ec5Tu!<;uI!<;uI!<<&K"96p%s8CIJs8LOSs4,["e^a]Ms8CIJs7XtC
-s8CIMs4,["rRCoJr7(fIr7(fIr7(fIpXK9Drm_)Mec5Ns!<<&K#636(s4,["p!j'BrRD5Se^a]M
-ec41Ms8CIJs8LONs4,["psfHGec5Tu!<:U"!<7r,!<8qHs+BmUs8VuH"f21\k.LbF~>
-!<E0!joD+?g&M-Gg&h?/g&V**!!)rN!!)rN!!*#P!s%'/!<(UO!<1[X!8?-,g=cP\!<(UO!;>+H
-!<(UR!8?-,rRq5Or7V,Nr7V,Nr7V,NpY#TIrn7DRg&V$(!!*#P"p!B2!8?-,p"BBGrRqPXg=cP\
-g&Tj\!<(UO!<1[S!8?-,pt>cLg&V**!!(R'!!%o1!!&nMs+0aXs8VuM"ektYk.1PC~>
-!<E0!joD4BeGoUBeH5g%eH#Qu!!)rI!!)rI!!*#K!s$m%!<(FJ!<1LS!7fU"e^XZM!<(FJ!;=qC
-!<(FM!7fU"rRClJr7(cIr7(cIr7(cIpXK6Drm_&MeH#Ks!!*#K"p!3(!7fU"p!j$BrRD2Se^XZM
-eH".M!<(FJ!<1LN!7fU"psfEGeH#Qu!!(R"!!%o,!!&nHs+BmUs8VuH"f21\k.LbF~>
-!<E0!joD4BeH#XBeH#XIec,UHeH#XIeH#XKeHQ!'ec41Mrr;uJ!<;uIs8VT=!<<#J!<;uIrr;oH
-!<;uI!<;uI!<;fD!<<&K!rpgNrRLoIrm_,Ne^a^!ec5[DeH#XJec,UJeH>j%ec5Tu!<<&K"96p%
-s7k+Gs4./JeH#X"eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&M-Gg&M-NgAV*Mg&M-Ng&M-Pg'%K1g&Tj\rW)rO!!)rNrrDQB!!)uO!!)rNrW)lM
-!!)rN!!)rN!!)cI!!*#P!W^pSrS%5Nrn7GSg=cQ+gA_0Ig&M-OgAV*Og&h?/g&V**!!*#P!s%'/
-!;P7L!87GOg&M-'g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoUBeGoUIec#RHeGoUIeGoUKeHGs'eH".MrW)rJ!!)rIrrDQ=!!)uJ!!)rIrW)lH
-!!)rI!!)rI!!)cD!!*#K!W^aNrRLlIrm_)Ne^X[!ec,XDeGoUJec#RJeH5g%eH#Qu!!*#K!s$m%
-!;P(G!7_)JeGoU"eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#XBeHl3*ec42"e^a]teH#XIeH#XKeHl3*ec42"e^a^!eHl3*ec41Ms4./JeH#XC
-eH#XJeHl3*ec42"e^a]teH#XIeH#XIeH#XDeHZ'(ec5["s8LONs4,["rm_,Ne^a]teH#XEeH#XJ
-eHu9+ec41Ms4,["rRCoJrm_,Ne^a]qeboIHeH#X"eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&M-Gg'@]4g&Th,g=cQ)g&M-Ng&M-Pg'@]4g&Th,g=cQ+g'@]4g&Tj\!87GOg&M-H
-g&M-Og'@]4g&Th,g=cQ)g&M-Ng&M-Ng&M-Ig'.Q2g&M-,!<1[S!8?-,rn7GSg=cQ)g&M-Jg&M-O
-g'Ic5g&Tj\!8?-,rRq5Orn7GSg=cQ&gACsMg&M-'g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoUBeHc0*eH","e^XZteGoUIeGoUKeHc0*eH","e^X[!eHc0*eH".M!7_)JeGoUC
-eGoUJeHc0*eH","e^XZteGoUIeGoUIeGoUDeHQ$(eGoU"!<1LN!7fU"rm_)Ne^XZteGoUEeGoUJ
-eHl6+eH".M!7fU"rRClJrm_)Ne^XZqebfFHeGoU"eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#XAec5[Kec5XOec41Mr;QcIq#C?Ds8N,Ms8LRKs8UXLrrUaNs8LOKs7OnBs8CLJ
-s8LRKrr^gOe^aTt!7h#Is4%,Lp!s*B!7h#Is4./L!nI>$rr3)Ns8UXKs7k.Cs8LRKs8LRJs8LRH
-s8UXLs7b%Hs4./"ec#O!eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&M-FgA_0PgA_-Tg&Tj\qu?`Np]1<Irr<)R!<1^P!<:dQ!!:jS!<1[P!;5%G!<(XO
-!<1^P!!CpTg=lH)!8@>Ns4RGQp"KEG!8@>Ns4[JQ!nmY.rW!&S!!(aP!;P:H!<1^P!<1^O!<1^M
-!<:dQ!;G1M!87G,gAM$&g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoUAec,XKec,UOeH".Mqu?`Ip]1<Drr<)M!<1OK!<:UL!!:[N!<1LK!;4kB!<(IJ
-!<1OK!!CaOe^aQt!7guIs4%)Lp!s'B!7guIs4.,L!n@;$rW!&N!!(RK!;P+C!<1OK!<1OJ!<1OH
-!<:UL!;G"H!7_)"eboL!eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#WYeH#X2eH#X?eH#X$eH#XBeH#XCeH5d$s3T9rs,,>,s/+?HKCZ_Us81=MV#TT>
-]`<Q~>
-!<E0!joD+?g&M,^g&M-7g&M-Dg&M-)g&M-Gg&M-Hg&_9.!79F"!/fJ1!2eKMJb$\Xs81LRU&X9;
-\c@6~>
-!<E0!joD4BeGoTYeGoU2eGoU?eGoU$eGoUBeGoUCeH,a$!796r!/f;,!2e<HKCZ_Us81=MV#TT>
-]`<Q~>
-!<E0!joD4BeH#WXeH#X4eH#X>eH#X%ec#ODec5ZceH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&M,]g&M-9g&M-Cg&M-*gAM$IgA_/hg&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoTXeGoU4eGoU>eGoU%eboLDec,WceGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&M,1g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&M,1g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W5ec,XGeH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&M,:gA_0Lg&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT5ec,XGeGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W5eboLGeH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&M,:gAM$Lg&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT5eboLGeGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W4eb]@HeH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&M,9gA:mMg&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT4eb]@HeGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeVO8+s,,>,s,,>,s/+?HKCZ_Us81=MV#TT>]`<Q~>
-!<E0!joD+?g5#`dg&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeVF3_eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W4eb]@HeH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&M,9gA:mMg&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT4eb]@HeGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W4ec#RHeH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&M,9gAV*Mg&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT4ec#RHeGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W5ec,XGeH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&M,:gA_0Lg&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT5ec,XGeGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&M,1g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&M,1g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&M,1g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&M,1g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&M,1g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&M,1g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&M,1g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&M,1g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&M,1g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&M,1g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&M,1g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&M,1g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#XCec5[;ec5[Kec5[4ec5[BeH5d$s8CIJs5DK.s,,>,s,,>,s/+?HKCZ_Us81=M
-V#TT>]`<Q~>
-!<E0!joD+?g&M-HgA_0@gA_0PgA_09gA_0Gg&_9.!<(UO!9)W3!/fJ1!/fJ1!2eKMJb$\Xs81LR
-U&X9;\c@6~>
-!<E0!joD4BeGoUCec,X;ec,XKec,X4ec,XBeH,a$!<(FJ!9)H.!/f;,!/f;,!2e<HKCZ_Us81=M
-V#TT>]`<Q~>
-!<E0!joD4BeH#XBeH#X:eH#XJeH#X3eH#XBeHGp&s4,[!s5DK.s,,>,s,,>,s/+?HKCZ_Us81=M
-V#TT>]`<Q~>
-!<E0!joD+?g&M-Gg&M-?g&M-Og&M-8g&M-Gg&qE0!8?0+!9)W3!/fJ1!/fJ1!2eKMJb$\Xs81LR
-U&X9;\c@6~>
-!<E0!joD4BeGoUBeGoU:eGoUJeGoU3eGoUBeH>m&!7fX!!9)H.!/f;,!/f;,!2e<HKCZ_Us81=M
-V#TT>]`<Q~>
-!<E0!joD4BeH#XBec,UJec5[KeH>j%s8W&Jrr;rI!<<#Js8VlEs8W#Is8W)K"96pOs7t4Cs8LOK
-s5DK.s,,>,s,,>,s/+?HKCZ_Us81=MV#TT>]`<Q~>
-!<E0!joD+?g&M-GgAV*OgA_0Pg&h?/!!)uOrW)oN!!)uOrrDiJrrDuNrrE&P!s%$T!;Y@H!<1[P
-!9)W3!/fJ1!/fJ1!2eKMJb$\Xs81LRU&X9;\c@6~>
-!<E0!joD4BeGoUBec#RJec,XKeH5g%!!)uJrW)oI!!)uJrrDiErrDuIrrE&K!s$jO!;Y1C!<1LK
-!9)H.!/f;,!/f;,!2e<HKCZ_Us81=MV#TT>]`<Q~>
-!<E0!joD4BeH#XBeH>j%ec5Tu!<<&K$3/Q+s4,["e^a]ueH#XKeH>j%ec5Bo!<<&K#liH*s4,["
-ec5Bo!rpgNrRCoJiRIr.MU__,MU__,VUb^!o"G)'qpbkGs5rIW!.Y~>
-!<E0!joD+?g&M-Gg&h?/g&V**!!*#P#lr]5!8?-,g=cQ*g&M-Pg&h?/g&Um$!!*#P#QWT4!8?-,
-g&Um$!W^pSrRq5OiS"83MV8%1MV8%1VV;'$o"tG,qq;4Is5rIT!.Y~>
-!<E0!joD4BeGoUBeH5g%eH#Qu!!*#K#lrN+!7fU"e^XZueGoUKeH5g%eH#?o!!*#K#QWE*!7fU"
-eH#?o!W^aNrRClJiRIo.MU_\,MU_\,VUb^!o"G)'qpbkGs5rIW!.Y~>
-!<E0!joD4BeH#XBeHQ!'ec41Mrr;uJ$3/Q+s4,["e^a]ueH#XKec,UDec,UJeH#XIec5[CeH5d$
-s8CIJs5DK.s,,>,s,,>,s/+?HKCZ_Us81=MV#TT>]`<Q~>
-!<E0!joD+?g&M-Gg'%K1g&Tj\rW)rO#lr]5!8?-,g=cQ*g&M-PgAV*IgAV*Og&M-NgA_0Hg&_9.
-!<(UO!9)W3!/fJ1!/fJ1!2eKMJb$\Xs81LRU&X9;\c@6~>
-!<E0!joD4BeGoUBeHGs'eH".MrW)rJ#lrN+!7fU"e^XZueGoUKec#RDec#RJeGoUIec,XCeH,a$
-!<(FJ!9)H.!/f;,!/f;,!2e<HKCZ_Us81=MV#TT>]`<Q~>
-!<E0!joD4BeH#XBeHl3*ec42"e^a^!eHu9+ec41Ms4,["rRCoJrm_,Ne^a]reH>j%ec5X!#liH*
-s4,["ec5Epr;ZcH!<;$.!<7r,!<7r,!<8qHs+BmUs8VuH"f21\k.LbF~>
-!<E0!joD+?g&M-Gg'@]4g&Th,g=cQ+g'Ic5g&Tj\!8?-,rRq5Orn7GSg=cQ'g&h?/g&V-+#QWT4
-!8?-,g&Up%quH`M!!)!3!!%o1!!%o1!!&nMs+0aXs8VuM"ektYk.1PC~>
-!<E0!joD4BeGoUBeHc0*eH","e^X[!eHl6+eH".M!7fU"rRClJrm_)Ne^XZreH5g%eH#U!#QWE*
-!7fU"eH#BpquH`H!!)!.!!%o,!!%o,!!&nHs+BmUs8VuH"f21\k.LbF~>
-!<E0!joD4BeH#XCec,RSec5["s8UXLec,RTec5["ec5["s4.&Is4./LpsoEE!S.5Lec5[Lec5XN
-ec5[EeHGp&s4,Zus5MQ/s,,>,s,,>,s/+?HKCZ_Us81=MV#TT>]`<Q~>
-!<E0!joD+?g&M-HgAV'Xg&M-,!!(^QgAV'Yg&M-,g&M-,!8@>Ns4[JQptG`J!SRPQgA_0QgA_-S
-g&M-Jg&qE0!8?0*!92]4!/fJ1!/fJ1!2eKMJb$\Xs81LRU&X9;\c@6~>
-!<E0!joD4BeGoUCec#OSeGoU"!!(OLec#OTeGoU"eGoU"!7guIs4.,LpsoBE!S%2Lec,XLec,UN
-eGoUEeH>m&!7fWu!92N/!/f;,!/f;,!2e<HKCZ_Us81=MV#TT>]`<Q~>
-!<E0!joD4BeH#WTeH5d$s4l-)s,,>,s,,>,s/+?HKCZ_Us81=MV#TT>]`<Q~>
-!<E0!joD+?g&M,Yg&_9.!8Q9.!/fJ1!/fJ1!2eKMJb$\Xs81LRU&X9;\c@6~>
-!<E0!joD4BeGoTTeH,a$!8Q*)!/f;,!/f;,!2e<HKCZ_Us81=MV#TT>]`<Q~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&M,1g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&M,1g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&M,1g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#XGec,W5eH#W,eH#W,eH#WHec19ks81=MV#TT>]`<Q~>
-!<E0!joD+?g&M-LgA_/:g&M,1g&M,1g&M,MgAc`ns81LRU&X9;\c@6~>
-!<E0!joD4BeGoUGec,W5eGoT,eGoT,eGoTHec19ks81=MV#TT>]`<Q~>
-!<E0!joD4BeH#XJeboK2eH#W,eH#W,eH#WHec17%^%D=+KE(uKeHMcKk2s>WJ,~>
-!<E0!joD+?g&M-OgAM#7g&M,1g&M,1g&M,MgAc^(_Y!j0JcGcIg'+2Mk2s5TJ,~>
-!<E0!joD4BeGoUJeboK2eGoT,eGoT,eGoTHec17%^%D=+KE(uKeHMcKk2s>WJ,~>
-!<E0!joD4BeH5d$eb]?0eH#W,eH#W,eH#WHec17'^&S--ec17'^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&_9.gA:l5g&M,1g&M,1g&M,MgAc^*_Z0Z2gAc^*_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeH,a$eb]?0eGoT,eGoT,eGoTHec17'^&S--ec17'^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeU[^O!1<fes/+?HKE&Xbs7t4FK*&ads81=MV#TT>]`<Q~>
-!<E0!joD+?g496T!13b`gAca(_Z0Z3gAc^*_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeU[^O!13b`ec1:%^&S-.ec17'^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH5d$ebfE0eH#W,eH#W,eH#WHec1:%^&S-/ec1:%^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&_9.gACr5g&M,1g&M,1g&M,MgAca(_Z0Z4gAca(_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeH,a$ebfE0eGoT,eGoT,eGoTHec1:%^&S-/ec1:%^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#XJeboK2eH#W,eH#W,eH#WHec1:$^&S-0ec1:%^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&M-OgAM#7g&M,1g&M,1g&M,MgAca'_Z0Z5gAca(_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoUJeboK2eGoT,eGoT,eGoTHec1:$^&S-0ec1:%^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#XGec,W5eH#W,eH#W,eH#WHec1:$^&S-1ec1:$^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&M-LgA_/:g&M,1g&M,1g&M,MgAca'_Z0Z6gAca'_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoUGec,W5eGoT,eGoT,eGoTHec1:$^&S-1ec1:$^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec1:#^&S-2ec1:$^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&M,1g&M,1g&M,1g&M,MgAca&_Z0Z7gAca'_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec1:#^&S-2ec1:$^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec1:#^&S-3ec1:#^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&M,1g&M,1g&M,1g&M,MgAca&_Z0Z8gAca&_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec1:#^&S-3ec1:#^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec1:"^&S-4ec1:#^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&M,1g&M,1g&M,1g&M,MgAca%_Z0Z9gAca&_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec1:"^&S-4ec1:#^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec1:"^&S*6eUrMP^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&M,1g&M,1g&M,1g&M,MgAca%_Z0W;g4=hQ_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec1:"^&S*6eUrMP^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec1:!]`A*3KD`F_s81=MV#TT>]`<Q~>
-!<E0!joD+?g&M,1g&M,1g&M,1g&M,MgAca$_>sW8Jc*Cbs81LRU&X9;\c@6~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec1:!]`A*3KD`F_s81=MV#TT>]`<Q~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec1:!]`S4dKDW@^s81=MV#TT>]`<Q~>
-!<E0!joD+?g&M,1g&M,1g&M,1g&M,MgAca$_?0agJc!=as81LRU&X9;\c@6~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec1:!]`S4dKDW@^s81=MV#TT>]`<Q~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19u^&N`^^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&M,1g&M,1g&M,1g&M,MgAca#_Z,2a_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19u^&N`^^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19u]`<]]^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&M,1g&M,1g&M,1g&M,MgAca#_>o/`_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19u]`<]]^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19ks81=MV#TT>]`<Q~>
-!<E0!joD+?g&M,1g&M,1g&M,1g&M,MgAc`ns81LRU&X9;\c@6~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19ks81=MV#TT>]`<Q~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHeGt6js81=MV#TT>]`<Q~>
-!<E0!joD+?g&M,1g&M,1g&M,1g&M,Mg&Q]ms81LRU&X9;\c@6~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHeGt6js81=MV#TT>]`<Q~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#W/eHMcKk2s>WJ,~>
-!<E0!joD+?g&M,1g&M,1g&M,1g&M,4g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoT/eHMcKk2s>WJ,~>
-!<E0!joD3.eUc8%eW&)_V#TT>]`<Q~>
-!<E0!joD*+g4@t/g5XeiU&X9;\c@6~>
-!<E0!joD3.eUc8%eW&)_V#TT>]`<Q~>
-!<E0!joD4SeU`@(K7SZXKBC\fV#TT>]`<Q~>
-!<E0!joD+Pg4=g+JUrBTJ`bYiU&X9;\c@6~>
-!<E0!joD4SeU`@(K7SZXKBC\fV#TT>]`<Q~>
-!<E0!joD4SeU`@(K7SZYK)kr6eHMcKk2s>WJ,~>
-!<E0!joD+Pg4=g+JUrBUJH5`4g'+2Mk2s5TJ,~>
-!<E0!joD4SeU`@(K7SZYK)kr6eHMcKk2s>WJ,~>
-!<E0!joD4Sec19n]`J/H]`3PrJ\@A_s8V`)s8V63"f21\k.LbF~>
-!<E0!joD+PgAc`q_?'\R]`3Q"J\m_is8V`.s8V68"ektYk.1PC~>
-!<E0!joD4Sec19n]`J/H]`3PrJ\@A_s8V`)s8V63"f21\k.LbF~>
-!<E0!joD4Sec19p^&S*5K>"tu!/#j9J\@A_rVuT)s8V63"f21\k.LbF~>
-!<E0!joD+PgAc`s_Z0W:J\o,#!.f^<J\m_irVuT.s8V68"ektYk.1PC~>
-!<E0!joD4Sec19p^&S*5K>"tu!/#j9J\@A_rVuT)s8V63"f21\k.LbF~>
-!<Bh3SGUk:KD3(Ys8R]Q^&S,Jec18Q]n*k_^&.j)^&S,peHMJVS=BQZJ,~>
-!<B_0RJY_<JbR%\s8RWO_Z0YOgAc_T_L]Ri_YaB._Z0Yug'*nUR@+$TJ,~>
-!<Bh3SGUk:KD3(Ys8R]Q^&S,Jec18Q]n*k_^&.j)^&S,peHMJVS=BQZJ,~>
-!!)uB!1`r:s+C-\rVm&OK7gl;s1m1bK7U^e]p?A3s8UXJs8'G/s5qi8SB\a\S,e'~>
-!!)u?!1E`<s+1!_rVm&TJUt]<s1m@gJUt[h_Nr(=s8UgOs8'V4s5r#=REE+PR/ha~>
-!!)uB!1`r:s+C-\rVm&OK7gl;s1m1bK7U^e]p?A3s8UXJs8'G/s5qi8SB\a\S,e'~>
-!<CCD]`=T"ec1:!^&A!1ec17'^&S,Jec18Q]n*k_^&S-2ec#OG^&S,peHMJf]tKp9J,~>
-!<C:A\cA/qgAca$_YsN6gAc^*_Z0YOgAc_T_L]Ri_Z0Z7gAV'L_Z0Yug'*ne]"4:0J,~>
-!<CCD]`=T"ec1:!^&A!1ec17'^&S,Jec18Q]n*k_^&S-2ec#OG^&S,peHMJf]tKp9J,~>
-!<CCD]`=T"ec1:#^&A!/ec17'^&S,Jec18Q]n*k_^&S-0ec#OI^&S,peHMJf]tKp9J,~>
-!<C:A\cA/qgAca&_YsN4gAc^*_Z0YOgAc_T_L]Ri_Z0Z5gAV'N_Z0Yug'*ne]"4:0J,~>
-!<CCD]`=T"ec1:#^&A!/ec17'^&S,Jec18Q]n*k_^&S-0ec#OI^&S,peHMJf]tKp9J,~>
-!<CCD]`=T"ec1:%^&A!-ec17'^&S,Jec18Q]n*k_^&S-.ec#LL^&S,peHMJf]tKp9J,~>
-!<C:A\cA/qgAca(_YsN2gAc^*_Z0YOgAc_T_L]Ri_Z0Z3gAV$Q_Z0Yug'*ne]"4:0J,~>
-!<CCD]`=T"ec1:%^&A!-ec17'^&S,Jec18Q]n*k_^&S-.ec#LL^&S,peHMJf]tKp9J,~>
-!<CCD]`=T"ebb!oec17'^&S,Jec18Q]n*k_^&S--ebt.#s5qi8SB\a\S,e'~>
-!<C:A\cA/qgA?HrgAc^*_Z0YOgAc_T_L]Ri_Z0Z2gAQU&s5r#=REE+PR/ha~>
-!<CCD]`=T"ebb!oec17'^&S,Jec18Q]n*k_^&S--ebt.#s5qi8SB\a\S,e'~>
-!<CCD]`=T"ec1:%^&<T[ec17'^&S,Jec18Q]n*k_^&S-.ebt+%^&S,peHMJf]tKp9J,~>
-!<C:A\cA/qgAca(_Yo&^gAc^*_Z0YOgAc_T_L]Ri_Z0Z3gAQR(_Z0Yug'*ne]"4:0J,~>
-!<CCD]`=T"ec1:%^&<T[ec17'^&S,Jec18Q]n*k_^&S-.ebt+%^&S,peHMJf]tKp9J,~>
-!<CCD]`=T"ec1:#^&<T]ec17'^&S,Jec18Q]n*k_^&S-0ebt."^&S,peHMJf]tKp9J,~>
-!<C:A\cA/qgAca&_Yo&`gAc^*_Z0YOgAc_T_L]Ri_Z0Z5gAQU%_Z0Yug'*ne]"4:0J,~>
-!<CCD]`=T"ec1:#^&<T]ec17'^&S,Jec18Q]n*k_^&S-0ebt."^&S,peHMJf]tKp9J,~>
-!<CCD]`=T"ec1:!^&<T_ec17'^&S,Jec18Q]n*k_^&S-2ebt-u^&S,peHMJf]tKp9J,~>
-!<C:A\cA/qgAca$_Yo&bgAc^*_Z0YOgAc_T_L]Ri_Z0Z7gAQU#_Z0Yug'*ne]"4:0J,~>
-!<CCD]`=T"ec1:!^&<T_ec17'^&S,Jec18Q]n*k_^&S-2ebt-u^&S,peHMJf]tKp9J,~>
-!<CCD]`=T"ec19t^&<QeeUrLfs8Tmbs+>m9J\@A_s8W,LrIas[s8V63"e<iN]po(Q~>
-!<C:A\cA/qgAca"_Yo#hg4=gls8Tmgs+,a<J\m_is8W,QrIOg^s8V68"e!NE\sWPK~>
-!<CCD]`=T"ec19t^&<QeeUrLfs8Tmbs+>m9J\@A_s8W,LrIas[s8V63"e<iN]po(Q~>
-!<CCD]`=T"ec19r^&3Ka^&S,Jec18Q]n*k_^&S-2KD<.[s5qi8SB\a\S,e'~>
-!<C:A\cA/qgAc`u_Yerd_Z0YOgAc_T_L]Ri_Z0Z7Jb[+^s5r#=REE+PR/ha~>
-!<CCD]`=T"ec19r^&3Ka^&S,Jec18Q]n*k_^&S-2KD<.[s5qi8SB\a\S,e'~>
-!<CCD]`=T"ec19p^&EWc^&S,HK7U^e]p?A3s8R`F^&S,peHMJf]tKp9J,~>
-!<C:A\cA/qgAc`s_Z#)f_Z0YMJUt[h_Nr(=s8RZD_Z0Yug'*ne]"4:0J,~>
-!<CCD]`=T"ec19p^&EWc^&S,HK7U^e]p?A3s8R`F^&S,peHMJf]tKp9J,~>
-!<CCD]`=T"ec19n]`Ni"s1O&9]n*k_]`J.coY(;)k1'X*c+Uf\!.Y~>
-!<C:A\cA/qgAc`q_?,;*s1Nu7_L]Ri_?'[foYUY.k1U!,b.>0P!.Y~>
-!<CCD]`=T"ec19n]`Ni"s1O&9]n*k_]`J.coY(;)k1'X*c+Uf\!.Y~>
-!<CCD]`=T"ec18Qs+13$s02OceHMJf]tKp9J,~>
-!<C:A\cA/qgAc_Ts+13$s02Ocg'*ne]"4:0J,~>
-!<CCD]`=T"ec18Qs+13$s02OceHMJf]tKp9J,~>
-!<CCD]`=T"eGt5Qs+13$s0)IbeHMJf]tKp9J,~>
-!<C:A\cA/qg&Q\Ts+13$s0)Ibg'*ne]"4:0J,~>
-!<CCD]`=T"eGt5Qs+13$s0)IbeHMJf]tKp9J,~>
-!<CCD]`=RReUc8%eW&)_SB\a\S,e'~>
-!<C:A\cA.Lg4@t/g5XeiREE+PR/ha~>
-!<CCD]`=RReUc8%eW&)_SB\a\S,e'~>
-!<CCC^%%VDUk,=mUogEm^%.Znc2PBWS,e'~>
-!<C:@]()2>Tn/ngTrk!g](26hb5SsQR/ha~>
-!<CCC^%%VDUk,=mUogEm^%.Znc2PBWS,e'~>
-!]^8*rOqgI!53s`JcC<$XoIq9rk/B'!<7Q~>
-!^m%2rOVUC!4ma]JcC<$XoIq6rji0!!<7Q~>
-!cn@drOqgI!53s`JcC<$XoIq9rk/B'!<7Q~>
-!\j]"n%A^kJ`_OGJ`a)s!6suG!h98jJ,~>
-!^m%2n%&LeJ`_OGJ`a)s!6XcA!gs&gJ,~>
-!cn@dn%A^kJ`_OGJ`a)s!6suG!h98jJ,~>
-s#C,\S=K,_!1\W&J`_OGXl]W.n\+sm!W`9#J,~>
-s$QngR@3TV!1AE#J`_OGXl]W+n[eag!W`9#J,~>
-s)S5AS=K,_!1\W&J`_OGXl]W.n\+sm!W`9#J,~>
-">Mnk!!)MYJ\?WJJ\A.unXTUZrr7K~>
-r^?bdn<nj=J\$EDXLdqirrE&uJ,~>
-"DW"!!!)MYJ\?WJJ\A.unXTUZrr7K~>
-"?A1s0fadbJH16$MZE\TJ,~>
-r'Z)9JH16$MZE\TJ,~>
-rc8*TF+F=B!.b-.!;ukI~>
-%%EndData
-showpage
-%%Trailer
-end
-%%EOF
diff --git a/lib/et/doc/src/note.gif b/lib/et/doc/src/note.gif
deleted file mode 100644
index 6fffe30419..0000000000
--- a/lib/et/doc/src/note.gif
+++ /dev/null
Binary files differ
diff --git a/lib/et/doc/src/notes.gif b/lib/et/doc/src/notes.gif
deleted file mode 100644
index e000cca26a..0000000000
--- a/lib/et/doc/src/notes.gif
+++ /dev/null
Binary files differ
diff --git a/lib/et/doc/src/notes.xml b/lib/et/doc/src/notes.xml
index 5abab9766c..8611955d3d 100644
--- a/lib/et/doc/src/notes.xml
+++ b/lib/et/doc/src/notes.xml
@@ -4,7 +4,7 @@
<chapter>
<header>
<copyright>
- <year>2002</year><year>2009</year>
+ <year>2002</year><year>2010</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
@@ -13,12 +13,12 @@
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>Event Tracer (ET) Release Notes</title>
@@ -28,12 +28,50 @@
<rev>%VSN%</rev>
<file>notes.xml</file>
</header>
- <p>This document describes the changes made to the Event Tracer (ET) system
- from version to version. The intention of this document is to
- list all incompatibilities as well as all enhancements and
- bugfixes for every release of Event Tracer (ET). Each release of Event Tracer (ET)
- thus constitutes one section in this document. The title of each
- section is the version number of Event Tracer (ET).</p>
+ <p>This document describes the changes made to the <c>Event Tracer
+ (ET)</c> system from version to version. The intention of this
+ document is to list all incompatibilities as well as all
+ enhancements and bugfixes for every release of <c>Event Tracer
+ (ET)</c>. Each release of <c>Event Tracer (ET) </c> thus constitutes
+ one section in this document. The title of each section is the
+ version number of <c>Event Tracer (ET)</c>.</p>
+
+<section><title>ET 1.4</title>
+
+ <section><title>Improvements and New Features</title>
+ <list>
+ <item>
+ <p>Thanks to Olle Mattsson the GUI parts are rewritten to
+ use <c>wxWidgets</c>. For the time being it is still
+ possible to use the old <c>GS</c> based version of the tool,
+ but it is deprecated. The <c>wxWidgets</c> based version is
+ started by default.</p>
+
+ <p>A print function has been added, in order to enable
+ printing of sequence charts.</p>
+
+ <p>A new tutorial has been added to the documentation. It is
+ based on <c>Jayson Vantuyl's</c> article
+ <c>http://souja.net/2009/04/making-sense-of-erlangs-event-tracer.html</c>.</p>
+
+ <p>The functions <c>et:trace_me/4</c> and
+ <c>et:trace_me/5</c> has been introduced in order to replace
+ the deprecated functions <c>et:report_event/4</c> and
+ <c>et:report_event/5</c>. Hopefully the new names makes it a
+ little more obvious what the intended usage of the functions
+ are.</p>
+
+ <p>The <c>max_events</c> configuration parameter to
+ <c>et_viewer</c> is not used any more. Now the event cache
+ in the <c>Viewer</c> only contains those events that
+ actually are displayed in the GUI.</p>
+
+ <p>Own Id: OTP-8058</p>
+ </item>
+ </list>
+ </section>
+
+</section>
<section><title>ET 1.3.3</title>
@@ -130,8 +168,8 @@
<section>
<title>Improvements and new features</title>
- <p>This is the first release of the Event Tracer (ET) as
- a stand-alone application.</p>
+ <p>This is the first release of the <c>Event Tracer (ET)</c> as
+ a stand-alone application separated from the Megaco application.</p>
</section>
</section>
</chapter>
diff --git a/lib/et/doc/src/part.xml b/lib/et/doc/src/part.xml
index d0375ffaf9..627aee866d 100644
--- a/lib/et/doc/src/part.xml
+++ b/lib/et/doc/src/part.xml
@@ -4,7 +4,7 @@
<part xmlns:xi="http://www.w3.org/2001/XInclude">
<header>
<copyright>
- <year>2002</year><year>2009</year>
+ <year>2002</year><year>2010</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
@@ -13,12 +13,12 @@
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>Event Tracer (ET) Users Guide</title>
@@ -32,7 +32,8 @@
and provides tools for collection and graphical viewing of trace data.</p>
</description>
<xi:include href="et_intro.xml"/>
- <xi:include href="et_architecture.xml"/>
+ <xi:include href="et_tutorial.xml"/>
+ <xi:include href="et_desc.xml"/>
<xi:include href="et_examples.xml"/>
</part>
diff --git a/lib/et/doc/src/part_notes.xml b/lib/et/doc/src/part_notes.xml
deleted file mode 100644
index 00b3d9df23..0000000000
--- a/lib/et/doc/src/part_notes.xml
+++ /dev/null
@@ -1,36 +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>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.
-
- </legalnotice>
-
- <title>Event Tracer (ET) Release Notes</title>
- <prepared>H&aring;kan Mattsson</prepared>
- <docno></docno>
- <date></date>
- <rev>%VSN%</rev>
- </header>
- <description>
- <p>The Event Tracer (ET) uses the built-in trace mechanism in Erlang
- and provides tools for collection and graphical viewing of trace data.</p>
- </description>
- <xi:include href="notes.xml"/>
-</part>
-
diff --git a/lib/et/doc/src/ref_man.gif b/lib/et/doc/src/ref_man.gif
deleted file mode 100644
index b13c4efd53..0000000000
--- a/lib/et/doc/src/ref_man.gif
+++ /dev/null
Binary files differ
diff --git a/lib/et/doc/src/sim_trans.gif b/lib/et/doc/src/sim_trans.gif
deleted file mode 100644
index e3ab0bd3f1..0000000000
--- a/lib/et/doc/src/sim_trans.gif
+++ /dev/null
Binary files differ
diff --git a/lib/et/doc/src/sim_trans.png b/lib/et/doc/src/sim_trans.png
new file mode 100644
index 0000000000..0a3a8fdcb5
--- /dev/null
+++ b/lib/et/doc/src/sim_trans.png
Binary files differ
diff --git a/lib/et/doc/src/sim_trans.ps b/lib/et/doc/src/sim_trans.ps
deleted file mode 100644
index efc48162b7..0000000000
--- a/lib/et/doc/src/sim_trans.ps
+++ /dev/null
@@ -1,6595 +0,0 @@
-%!PS-Adobe-3.0
-%%Creator: (ImageMagick)
-%%Title: (sim_trans.ps)
-%%CreationDate: (Mon Oct 14 16:45:00 2002)
-%%BoundingBox: 0 0 512 426
-%%DocumentData: Clean7Bit
-%%LanguageLevel: 1
-%%Orientation: Portrait
-%%PageOrder: Ascend
-%%Pages: 1
-%%EndComments
-
-%%BeginDefaults
-%%EndDefaults
-
-%%BeginProlog
-%
-% Display a color image. The image is displayed in color on
-% Postscript viewers or printers that support color, otherwise
-% it is displayed as grayscale.
-%
-/DirectClassPacket
-{
- %
- % Get a DirectClass packet.
- %
- % Parameters:
- % red.
- % green.
- % blue.
- % length: number of pixels minus one of this color (optional).
- %
- currentfile color_packet readhexstring pop pop
- compression 0 eq
- {
- /number_pixels 3 def
- }
- {
- currentfile byte readhexstring pop 0 get
- /number_pixels exch 1 add 3 mul def
- } ifelse
- 0 3 number_pixels 1 sub
- {
- pixels exch color_packet putinterval
- } for
- pixels 0 number_pixels getinterval
-} bind def
-
-/DirectClassImage
-{
- %
- % Display a DirectClass image.
- %
- systemdict /colorimage known
- {
- columns rows 8
- [
- columns 0 0
- rows neg 0 rows
- ]
- { DirectClassPacket } false 3 colorimage
- }
- {
- %
- % No colorimage operator; convert to grayscale.
- %
- columns rows 8
- [
- columns 0 0
- rows neg 0 rows
- ]
- { GrayDirectClassPacket } image
- } ifelse
-} bind def
-
-/GrayDirectClassPacket
-{
- %
- % Get a DirectClass packet; convert to grayscale.
- %
- % Parameters:
- % red
- % green
- % blue
- % length: number of pixels minus one of this color (optional).
- %
- currentfile color_packet readhexstring pop pop
- color_packet 0 get 0.299 mul
- color_packet 1 get 0.587 mul add
- color_packet 2 get 0.114 mul add
- cvi
- /gray_packet exch def
- compression 0 eq
- {
- /number_pixels 1 def
- }
- {
- currentfile byte readhexstring pop 0 get
- /number_pixels exch 1 add def
- } ifelse
- 0 1 number_pixels 1 sub
- {
- pixels exch gray_packet put
- } for
- pixels 0 number_pixels getinterval
-} bind def
-
-/GrayPseudoClassPacket
-{
- %
- % Get a PseudoClass packet; convert to grayscale.
- %
- % Parameters:
- % index: index into the colormap.
- % length: number of pixels minus one of this color (optional).
- %
- currentfile byte readhexstring pop 0 get
- /offset exch 3 mul def
- /color_packet colormap offset 3 getinterval def
- color_packet 0 get 0.299 mul
- color_packet 1 get 0.587 mul add
- color_packet 2 get 0.114 mul add
- cvi
- /gray_packet exch def
- compression 0 eq
- {
- /number_pixels 1 def
- }
- {
- currentfile byte readhexstring pop 0 get
- /number_pixels exch 1 add def
- } ifelse
- 0 1 number_pixels 1 sub
- {
- pixels exch gray_packet put
- } for
- pixels 0 number_pixels getinterval
-} bind def
-
-/PseudoClassPacket
-{
- %
- % Get a PseudoClass packet.
- %
- % Parameters:
- % index: index into the colormap.
- % length: number of pixels minus one of this color (optional).
- %
- currentfile byte readhexstring pop 0 get
- /offset exch 3 mul def
- /color_packet colormap offset 3 getinterval def
- compression 0 eq
- {
- /number_pixels 3 def
- }
- {
- currentfile byte readhexstring pop 0 get
- /number_pixels exch 1 add 3 mul def
- } ifelse
- 0 3 number_pixels 1 sub
- {
- pixels exch color_packet putinterval
- } for
- pixels 0 number_pixels getinterval
-} bind def
-
-/PseudoClassImage
-{
- %
- % Display a PseudoClass image.
- %
- % Parameters:
- % class: 0-PseudoClass or 1-Grayscale.
- %
- currentfile buffer readline pop
- token pop /class exch def pop
- class 0 gt
- {
- currentfile buffer readline pop
- token pop /depth exch def pop
- /grays columns 8 add depth sub depth mul 8 idiv string def
- columns rows depth
- [
- columns 0 0
- rows neg 0 rows
- ]
- { currentfile grays readhexstring pop } image
- }
- {
- %
- % Parameters:
- % colors: number of colors in the colormap.
- % colormap: red, green, blue color packets.
- %
- currentfile buffer readline pop
- token pop /colors exch def pop
- /colors colors 3 mul def
- /colormap colors string def
- currentfile colormap readhexstring pop pop
- systemdict /colorimage known
- {
- columns rows 8
- [
- columns 0 0
- rows neg 0 rows
- ]
- { PseudoClassPacket } false 3 colorimage
- }
- {
- %
- % No colorimage operator; convert to grayscale.
- %
- columns rows 8
- [
- columns 0 0
- rows neg 0 rows
- ]
- { GrayPseudoClassPacket } image
- } ifelse
- } ifelse
-} bind def
-
-/DisplayImage
-{
- %
- % Display a DirectClass or PseudoClass image.
- %
- % Parameters:
- % x & y translation.
- % x & y scale.
- % label pointsize.
- % image label.
- % image columns & rows.
- % class: 0-DirectClass or 1-PseudoClass.
- % compression: 0-none or 1-RunlengthEncoded.
- % hex color packets.
- %
- gsave
- /buffer 512 string def
- /byte 1 string def
- /color_packet 3 string def
- /pixels 768 string def
-
- currentfile buffer readline pop
- token pop /x exch def
- token pop /y exch def pop
- x y translate
- currentfile buffer readline pop
- token pop /x exch def
- token pop /y exch def pop
- currentfile buffer readline pop
- token pop /pointsize exch def pop
- /Times-Roman findfont pointsize scalefont setfont
- x y scale
- currentfile buffer readline pop
- token pop /columns exch def
- token pop /rows exch def pop
- currentfile buffer readline pop
- token pop /class exch def pop
- currentfile buffer readline pop
- token pop /compression exch def pop
- class 0 gt { PseudoClassImage } { DirectClassImage } ifelse
- grestore
- showpage
-} bind def
-%%EndProlog
-%%Page: 1 1
-%%PageBoundingBox: 0 0 512 426
-DisplayImage
-0 0
-512 426
-12.000000
-512 426
-1
-0
-0
-256
-020202
-0a0a0a
-6272a4
-fea602
-fe0202
-bec2be
-fefefe
-c6c6d6
-424242
-7a86ae
-0202fe
-bebece
-717ace
-bebabe
-e6e6e6
-42568a
-6a72c6
-969296
-6272b6
-5a6e9e
-4a464a
-969ade
-9696d6
-5a6a96
-fefafe
-b6baee
-2a3662
-323e72
-f6f6f6
-324272
-9696ce
-5a6696
-7286c6
-6272ae
-969ab6
-e6e2e6
-f6f2f6
-3a4a8a
-969ac6
-728ac6
-526297
-626ea6
-7a8bce
-42569e
-9696be
-d6d6d6
-eeeeee
-555e9e
-828282
-dedade
-727eb6
-5a6aa6
-828eb5
-4a528a
-3a4a82
-5a6eae
-8a92ce
-52669e
-eeeaee
-4a5a9e
-6a7ac6
-9ea6d6
-627abe
-a6aac6
-a6aade
-7982ae
-4a5296
-424e96
-7278a6
-a7acce
-828ec6
-a6a6de
-727ac6
-5266ae
-bec2d6
-dedef6
-5a6eb6
-7282ce
-6a72bd
-8a96b6
-8a9ad1
-5a6aae
-969ad6
-808ad6
-cecece
-4256a6
-9e9ed6
-969bbe
-8a92d6
-d6dad6
-8292c6
-5a5e96
-dedede
-6266a6
-7a82ce
-8a96d6
-525d8a
-757eae
-5262a6
-e6e6f6
-3a4e8a
-969ed6
-626aae
-aeafd6
-9696b6
-6a6e9e
-5a66a6
-32427a
-7a86bd
-f6f6fe
-bebed6
-969ace
-dedfee
-9ea6de
-424a7f
-6276b6
-b6bade
-969ece
-7282c6
-424642
-a3a6c6
-8a8eb6
-8296ce
-6a72ae
-7986ce
-626a9e
-626eb6
-ced2ee
-8286b6
-cfd1e6
-707aae
-828ed6
-626ebe
-4a5ea6
-424e82
-3a427a
-4a5996
-3a4672
-4a569e
-8a96c6
-969ede
-b6bede
-96a2d6
-4a4a4a
-d6daee
-8292ce
-5a6296
-727ab8
-5a669e
-5a72be
-8a92b6
-626aa6
-9ea2de
-6a76a1
-6a6ea6
-7a82b7
-525a9e
-eeeef6
-4a5682
-42528a
-b6beee
-9e9ec6
-d4d6e6
-8a96be
-5a66b6
-a6aed6
-6a7ece
-6a7fc6
-8286ae
-7580a6
-525a96
-5a6ab6
-6a76be
-7a82d6
-a6a2a6
-7a8ac6
-eeeaf6
-c6c6ee
-9ea1ce
-d6d2d6
-7a86c6
-626eae
-525eae
-8a96de
-828ace
-e6e6ee
-8292de
-8a92c6
-c6c2d6
-6276be
-6b76ae
-435282
-acb5de
-828abe
-5262af
-626e9e
-6a7ab6
-727ece
-8a92be
-9ea2d6
-aeaaae
-e6e2f6
-8a92de
-9696c6
-828ebe
-c6cce5
-3a467a
-9e9ebe
-828ac6
-4a5e8a
-6a72a4
-424e8a
-5266b6
-62669e
-7a82c6
-96a2c6
-4a5e96
-5a62a6
-9eaad6
-424a8a
-7a86d6
-525ea6
-7a8aba
-4a56a6
-8a96ce
-6a76c6
-425296
-8a8ebe
-7282bc
-828ece
-6272be
-828ab6
-626696
-6a7abe
-626ab6
-5a66ae
-32466a
-5a6a9e
-5a629e
-a7aec6
-727ec6
-e6eaf6
-828aae
-e6e2ee
-4a5aa6
-d6dae6
-525e96
-727ebe
-324672
-dee2f6
-6a7aa6
-bec2e6
-3a4682
-5a6ebe
-4a578a
-8292d6
-ec89f8ecf800000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-00000089f889f8898787870000060606060606060606060606060606061aa0a0a0a0a0a0
-a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0
-a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0
-a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0
-a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a019191919191919191919191919191919191919
-191919191919191919191919191919191919191919191919191919191919191919191919
-191919191919191919191919191919191919191919191919191919191919191919191919
-191919191919191919191919191919191919191919191919191919191919191919191919
-191919191919191919191919191919191919191919191919191919191919191919191919
-191919191919191919191919191919191919191919191919191919191919191919191919
-191919191919191919191919191919191919191919191919191919191919191919191919
-191919191919191919191919191919191919191919191919191919191919191919191919
-1919191919191919191919191919191919191919191919c01a0606060606060606060606
-060606060606060606ae0606060606060606060606060606060606060606ae0606060606
-06060606060606060606060000878787ecec0006062d2d2d313131315c5c5c2323230e0e
-0e1abacabacabacabacabacabacabacabacabacabacabacabacabacabacabacabacabaca
-bacabacabacabacabacabacabacabacabacabacabacabacabacabacabacabacabacabaca
-bacabacabacabacabacabacabacabacabacabacabacabacabacabacabacabacabacabaca
-bacabacabacabacabaca83ca83ca83ca83ca83ca83ca83ca83ca83ca83ca83ca83ca83ca
-83ca83ca83ca83ca83ca83ca83ca83ca83ca83ca83ca83ca83ca83ca83ca83ca83ca83ca
-83ca83ca83ca83ca83ca83ca83ca83ca83ca83ca83ca83ca83ca83ca83ca83ca83ca83ca
-83ca83ca83ca83ca83ca83ca83ca83ca83ca83ca83ca8383838383838383838383838383
-838383838383838383838383838383838383838383838383838383838383838383838383
-838383838383838383838383838383838383838383838383838383838383838383838383
-838383838383838383838383838383838383838383838383838383838383838383838383
-838383838383838383838383838383838383838383838383838383838383838383838383
-838383838383838383838383838383838383838383838383838383838383ba831a0654b3
-b3b32d2d2d313131315c5c5c2323230e0eae0654b3b3b32d2d2d313131315c5c5c232323
-0e0eae0654b3b3b32d2d2d313131315c5c5c23060600ec891d0006b32d2d2d313131315c
-5c5c2323230e0e0e231ac5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5
-c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5
-c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5
-c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c548c548c50cc548c50cc548c50cc548c50cc548
-c50c4d48c50c4d48c50cad48c50cad48c50cdc48c50cdc48c50cdc48c50cdc48c50cdc48
-c50c5348c50cb8c5c50cb8c5c50cb8c5c54883c5c54883c5c54883c5c54883c5c54858c5
-c548cac5c548cac5c548cac5c5485fadc5485fadc5485fadc548b7adc50cb7adc5c5b7ad
-c5a615adc5a615adc5a615adc5a615adc5a615adc5a615adc5a615adc5a615adc5a615ad
-c5a615adc5a615adc5a68cadc5a68cadc5a68cadc5a68cadc5a68cadc5a68cadc5a68cad
-c5a68cadc5a68cadc5a68cdcc5a68cdcc5a68cdcc5a68cdcc5a68cdcc5a68cdcc5a68cdc
-c5a68cdcc5a68cdcc5a68cdcc5a68cdcc5a68cdcc5a68cdcc5a68cdcc5a68cdcc5a68cdc
-c5a68cdcc5a68cdcc5a68cdcc5a68cdcc5a68cdcc5a68cdcc5a68cdcc5a68cdcc5a68cdc
-c5c58cc51a06b3b3b32d2d2d313131315c5c5c2323230e0e23ae06b3b3b32d2d2d313131
-315c5c5c2323230e0e23ae06b3b3b32d2d2d313131315c5c5c2323230e54001d1d00062d
-2d2d313131315c5c5c2323230e0e0e3a0e1aac3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c
-3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c
-3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3cc5464d3c3c3c3c3c3c3c3c3c3c3c3c3c3c
-3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c0c3c0c3c3c0c3c0c3c0c3c
-0c3c0c3c0c3c0c3c0ca70c3c0ca60c3c0cc50c3c0cc50c3c0c4d0c3c0c4d0c3c0c4d0c3c
-0c7c3c0c3cb4a60c3c7ca63c0c53a70c3c53a70c3c53a60c3c53a63c0ce5c53c0ce5c53c
-0c58c53c0cffc53c0c38c50c3c58c50c3c5fc50c3c580c0c3c580c0c3c580c0c3c5f0c3c
-3c504d3c3c504d3c0c504d3c0c504d3c0c154d3c0c154d3c0c154d3c0c154d3c0c654d3c
-0c654d3c0c654d3c0c654d3c0c654d3c0c654d3c0c654d3c0c654d3c0c654d3c0c8e4d3c
-0c8e4d3c0c8e4d3c0c8e4d3c0c8e4d3c0c8e4d3c0c8e4d3c0c8e4d3c0c8e4d3c0c8e4d3c
-0c8e4d3c0c8e4d3c0c8e4d3c0c8e4d3c0c8e4d3c0c8e4d3c0c8e4d3c0c8e4d3c0c8e4d3c
-0c8e4d3c0c8e4d3c0c8e4d3c0c8e4d3c0c8e4d3c0c8e4d3c0c8e4d3c0c8e4d3c0c8e4d3c
-0c8e4d3c0c8e4d3c3c98c5e11a06b3b32d2d2d313131315c5c5c2323230e0e0e3aae06b3
-b32d2d2d313131315c5c5c2323230e0e0e3aae06b3b32d2d2d313131315c5c5c2323230e
-0e54008900062d2d2d313131315c5c5c2323230e0e0e3a3a231ae1acacacacacacacacac
-acacacacacacacacacacacacacacacacacacacacac4b4bacacacacacacacacacacacacac
-acacacacacacacacacacacacacacacacacacacacacacac5fb1ac6518067f4b4bacac1c18
-acacacacacacacacacacacacacacacacacacacacacacacacacacacacacace1ace110e110
-e110ac10ac6d1810ac6d1810ac10ac103c10ac104810ac104810ac10c510ac10c510ac10
-c510ac105ee1acb171e1e110b4e1ac10dce1ac10b40cac10b848e110b848e110b848e110
-8348e1108348e110910ce1105848e110580ce1105f48e1105f48e11016c5e11052c5e110
-52c5e11052c5e110150ce1e115c5e1e165c5e1e165c5e1e165a6e1e165a6e1e165a6e1e1
-65a6e1e156a6e1e156a6e1e198a6e1e198a6e1e198a6e1e198a6e1e1984de1e1984de1e1
-984de1e1984de1e1714de1e1714de1e1714de1e1714de1e1475ee1e1475ee1e1475ee1e1
-475ee1e1475ee1e1475ee1e1475ee1e1475ee1e1475ee1e1475ee1e1475ee1e1475ee1e1
-475ee1e1475ee1e1475ee1e1475ee1e1475ee1e1475ee1e1475ee1e1475ee1e1475ee1e1
-475ee1e1475ee1e1475ee1e1475ee1e1475ee1e11a18542d2d2d313131315c5c5c232323
-0e0e0e3a3aae18542d2d2d080808080808080808080e0e0e3a3aae18542d2d2d31080831
-5c5c5c0808230e0e0e3a0d0000062d2d31313108085c5c2323230e08083a3a3a231aeaea
-eaeaeaeaeaeaeaeaeaeaeab815eaeaeaeaeaeaeaeaeaeaeaeaeaeaea84907ffceaeaeaea
-eaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeab8181e436306
-aa898181fc846d6d1beab815eaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaea
-eaeaea84847e847e84848484ea6d6d1bea6d6d1b8484841284ea84107e84841084848438
-658484ac8484843c128484481284ea4006d684c5e6847ef04e8484d69aea84d610ea84d6
-10ea845e10ea845e108484b8108484b8108484b810848446e1847e83e1848438e1848438
-e1847ee0e1847ee03c847e5f3c8484163ceaea58e1eaea16e1abea16e1abea16aceaea16
-aceaea1648eaea1648eaea1648eaea1548eaea1548eaea1548eaea1548eaea1548eaab15
-48abea1548abea1548abea56e1eaab56e1eaab56e1eaab56e1eaea5648eaea5648eaea8e
-48eaea8e48eaea8e48eaea8e48eaea8e48eaea8e48eaea8e48eaea8e48eaea8e48eaea8e
-48eaea8e48eaea8e48eaea8e48eaea8e48eaea8e48eaea8e48eaea8e48eaea8e48eaea8e
-48eaea8e48eaea8e48eaea8e48eaea8e48eaea9848eaea98488484ea1a182d2d2d593131
-315c5c5c2323230e0e0e3a3a3aae062d2d2d59080808080808087777080e0e3a3a3aae06
-2d2d2d5908080808315c777708080e0e3a3a0d0000062d31312d080808082323230e0877
-14143a2e231aababababababababababababab6d18f4abababababababababababababab
-a451fcfcabababababababababababababababababababababababababababababababab
-abab63811b3b1c181bc2c2fcfca46d241bab6d18f4ababababababababababababababab
-abababababababababababa451a4aba4aba4aba4ab6d6d1bab6d6d1b51a451a4abab4ca4
-aba484a451a4e66d18dfe6ab51a4bd51aba4ac51aba43c377ff35151aba43ceaaba4c5ea
-ababc5eaa4ab7684a4ab76e6a4ab76e6aba4b484aba4b48451a4af84aba4af84aba446e6
-51a446e6aba45ae6ab51914eab51e04eab51e04eabab8b4eabab5facabab5facabab5fac
-abab5facabab50acabab50e9a4ab6fe9a4ab6f3ca4ab6fe9a4ab6fe9a4ab75e9a4ab75e9
-a4ab75e9a4ab75e9a4ab75e9a4ab75e9a4ab653cabab8e3cabab8e3cabab8e3cabab8e3c
-a4ab8e3ca4abc73ca4abc73ca4abc73ca4abc73ca4abc73ca4abc73ca4abc73ca4abc73c
-a4abc73ca4abc73ca4abc73ca4abc73ca4abc73ca4abc73ca4abc73ca4abc73ca4abc73c
-a4abc73ca4abc73ca4abc73ca4abc73ca4abc73ca4abc73ca4ab8ee9a4ab8ec4a4a456ab
-1a182d2d313131315c5c5c2323230e0e0e3a3a3a2eae182d2d2d311a0808080808770808
-770e3a3a3a2eae182d2d31b3080808080808080877770e3a3a3a0d000006313131310808
-080808230e77080814142e2e231aa4d4a4d4a4d47c4b189d8ea48d0606067cd4a4d4a4d4
-a4cd065fd4a4c09dc26d18a4d47c4b189d8ea4c0067cd4cd06b4a4cdfba4204b189d8ea4
-d4c9f9c0c9d4a4d4a49106a9fccd060606e96d18a4d46d6d1b8d0606067c7c4b189d8ea4
-d4c9f9c0c9d46d18a4d4a4d4a4d4da631806b0e9d4dab006b0dad449d46d6d1bd46d6d1b
-d4204b189d8e49d4da631806b0a78d06060627dab006b0dad412d4f9f974c94938068249
-493e84d449e9fdd4d43c84d4d4a74cd449a784d4d4764ca4497612d4492095d449b412a4
-49afe6d4d4af4ed449e5e649a4e5bdc2c291bdc2c291bdc2c238bdc2c25f73d4d47aacd4
-d4e0bdd4a4e0bdd4a48bbdd4d4e0bdd4d4e0bdd4d4503ed4d4503ed4d4503ea4d4503ea4
-d4503ea4d4503ea4d45093d4d475e9d4d465e9d4d465e9d4d4653ea4d465c4a4d48ec4a4
-d48ec4a4d48ec4d4d48ec4a4d48e3ca4d48e3ca4d48e3ca4d48e3ca4d48e3ca4d48e3ca4
-d48e3ca4d48e3ca4d48e3ca4d48e3ca4d48e3ca4d48e3ca4d48e3ca4d48e3ca4d48e3ca4
-d48e3ca4d48e3ca4d48e3ca4d48e3ca4d48e3ca4d48e3ca4d48e3ca4d48e3ca4d48e3ca4
-d48e3c49d48e3cc21a1c2d313131315c5c5c2323230e0e0e3a3a3a2e2eae1c2d31313108
-08081a0808777708083a3a3a2e2eae1c2d3131313108080808777708080e3a3a3a2e0d00
-0006313131312d080808770808081414142e2e9d311af4b6b6b6b6ea6d9d9abc06337e6d
-18f61bdfb6b6b6b6b6bb066e42b6b0456b6d241bea6d9d9abc0633d60696df9d0696df6d
-413b6d9d9abc0633b66d064b401bb6b6b674068642126d18601d6d6d1b9c6d241b7e6d18
-60866d9d9abc0633b66d064bda1b63c91bb6b6b6b6a506c94199689fd706cd174a0675b6
-b66d241b9c6d241b5d6d9d694a0633a506f94199680feb6d18602206cd174a06b2c2b66d
-06703f6b3206ef424ec2b69c10d9b69ce1d9b6b610d99cb63cd99cb693a4b6b6f7a4b69c
-f05db69c765db69c5e5db69cb466b69cb4eab69cafeab6b6b8eab6b6b8eab6b646eab6b6
-46eab69c467eb6b6e312b6b6bb12b6b6bb12b6b6bb12b6b63812b6b6e37bb6b6e37bb6b6
-384eb685384eb685384eb685384eb685384eb6b61e4eb6b61e4eb6b61eacb6b61eacb685
-6facb6b66facb6b66facb6b66facb6b66facb6b66facb6856facb6856facb6856facb685
-6facb6856facb6856facb6856facb6856facb6856facb6856facb6856facb6856facb685
-6facb6856facb6856facb6856facb6856facb6856facb6856facb6856facb6856facb685
-6facb6856fac85b66facb6b675acf4b61a1c313131315c5c5c2323230e0e0e3a3a3a2e2e
-2eae1c3131313108315c23235c0e0e0e143a3a2e2e2eae1c31313131312d080877080877
-0e3a3a3a2e2e0d000006315c5c5c232308087777140814143a2e24245c1adfdfdfdfdf75
-063f258b06f22b6d6d1be2dfdfdfdfdff485241864f00628256d6d1b6f063f258b06f23b
-064a2818b00b5106ce26063f258b06a82b6d18726bfc55dff481061b55f46d6d1b2b6d6d
-1bf46d6d1bf46d6d1b26063f258b06a82b6d18726b25f41b1b55dfdff49d06606b43e225
-63069ece49060e25f46d6d1bf46d6d1b52063f648b06a82e06601b2be264556d6d1b6306
-9efceb06b964f46d18ce1be249060764c2f4f47ec2f4f47ec2dff412c2f4f44e49f4f44e
-498a8ac449f4f493a4f4f4f0a4f4f4f051f4f47651f4f47651f4f4b4513bf46c33f4f4de
-29f4f4d04cf4f4d037f4f4b8668adfd0eadf8ad066df8ad0eadf8ad066df8ad0668af45a
-eadff45aeadf3b5a668af4bb668af4bb7e8af4bb7e8af48b7e8adfbb7e8a8abb7e8a3b8b
-7e8a3b8b7e8adfbb4cdf8abb4cdf8a8b4cdf8a1e7edf3b6f4cdf3b6f37dff46f37dff46f
-37dff46f37dff46f37dff46f37dff46f37dff46f37dff46f37dff46f37dff46f37dff46f
-37dff46f37dff46f37dff46f37dff46f37dff46f37dff46f37dff46f37dff46f37dff46f
-37dff46f37dff46f37dff46f7edf3b6f7edff42612f4f4551a1c31315c5c5c2323230e0e
-0e3a3a3a2e2e2e2424ae1c31313131082323230e0e0e3a3a082e2e2e2424ae1c31315c5c
-5c230808777708773a3a2e2e2e240d0000065c5c5c2323230e7708081414142e2e242424
-311af4f4f4f43ba50606060606cf436d6d1bf4f4f4f4f4f4f4f48d06f2744b1be26d241b
-a50606060606cf43902479a20b6357f31b670606060606a1256d6d1b55f4f4f4f4cd061b
-df3b6d241bdf6d241bf46d241bf46d6d1ba50606060606a1256d6d1bdfdfdff4f4f4f4f4
-df06061be28af4f418061b2b3b06066b3b6d241bf46d241ba50606060606cf06061df485
-2bf4626d6d1b18061b2b6a06061b516d6d1b49b6850607fc3bdf7eb6f4df12c2f43b7e62
-f4f41262f4f47b493bf4c4c23b55c4d93bdff7d93bdff75df4dff76af4dfe45d3bdf9beb
-3bdf6c33f48a6c37f42bc14c3b8ad07ef4dfd07ef4f4467ef43b467ef43b467ef43b467e
-f43b467ef4f4d07ef4f4467ef43b467ef4f4e312f4f4e3123bf4e3123bf4bb123bf48b12
-3bf48b123bf4bb123bf4bb123bf48b12f43b8b123b3b5012f43b6f12f43b1e12f43b1e12
-f43b1e73f43b1e73f43b1e73f43b1e73f43b1e73f43b1e73f43b1e73f43b1e73f43b1e73
-f43b1e73f43b1e73f43b1e73f43b1e73f43b1e73f43b1e73f43b1e73f43b1e73f43b1e73
-f43b1e73f43b1e73f43b1e73f43b1e73f43b1e73f4f41e73f43b1e12dff41e3b1a24315c
-5c31ae0808080808141408ae2e2e24242eae24315c5c5c0823230e0e0e3a3a3a8f2e2e24
-242eae24315c5c5c2308770808080814142e2e2e24240d0000065c5c2323230e0e0e1414
-08142e2e2424241c311a8a8a8a8a422606ef1b1b1b1bfc6d6d1b8a8a8a8a8a8a8a423206
-b324c66b2b6d6d1b2606ef1b1b1b1bfca50631b29606f5a51b2606ef1b1b1b1b256d6d1b
-428a8a8a8ac0069e2b8a6d6d1b426d6d1b8a6d6d1b8a6d6d1b2606ef1b1b1b1b256d6d1b
-8a8a8a8a8a8a8a8a8ab0061f8a428a8a630635426606631b2b6d6d1b426d6d1b2606ef1b
-1b1b1bf1061f8a8a42dd3b6d6d1bf10635dd9a06631b3b6d6d1b858a66063f878a662f8a
-8ab5dd8a8a29dd8a8a21628a8a7b628a8abe628a8abed98a8a93d98a8a936a8a8a616a8a
-8a326a8a8a9b6a8a8a9b5d8a8a9b5d8a8a9beb8a8a805d8a8ac1668a8ac1668a8ac1668a
-8ac1668a8ac1668a8acc668a8acc298a8acc298a8acc298a8a46298a8ae3b58a8ac6b58a
-8ac6298a8a96b58a8ac6298a8abb298a8a8b298a8a8b298a8a8bb58a8a8b298a8acb212b
-8acb218a8a26218a8a26218a8a267b8a8a267b8a8a267b8a8a267b8a8a267b8a8a267b8a
-8a267b8a8a267b8a8a267b8a8a267b8a8a267b8a8a267b8a8a267b8a8a267b8a8a267b8a
-8a267b8a8a267b8a8a267b8a8a267b8a8a267b8a8a267b8a8a267b8a8a26218a8a26218a
-8a269a421a9d5c5c5c2377777777770814148f8f2e2424241cae245c5c5c2308230e0e0e
-3a3a3a2e8f2e2424241cae245c5c5c23770877777714141414142e2424240d0000065c23
-23230e0e0e3a3a14142e2e2424241c24311a428a8a8a8a629d18269bbb808a6306d2628a
-8a8a8a42428a42b00606d3fc8a6d241b629d18269bbb808ad606060202060699fc629d18
-a19bbbc18a6d241b8a8a8a428a93064143426d241b8a6d241b426d241b426306d2b59d18
-a19bbbc18a6d241b428ab9638a8a8a8a8ab206b9bb9b2666a1064abecd06961b426d241b
-8a6d241b629d18a16cbbc1b206b9969b75668a6306d2a5064ac4cd064f1b8a6d241b8a42
-d7067d87669c8a42b59c8a4229b6424229628a429a628a42be628a42be5b8a42c4d98a42
-93d98a4232d98a4232d98a42e4d98a429b6a8a4280338a426c668a42c1668a42c15d8a8a
-c1978a8ac1668a8ac1668a8ac1668a8acc298a8accb5428accb5428acc7e428accb5428a
-e3b5428ac6b5428ac6b5428ac6b58a8ac6b58a8abbb5428abb7e428a8bb58a8a8b218a8a
-8b218a8a8b218a8acb21428acb21428a267b428a267b428a267b428a267b428a267b428a
-267b428a267b428a267b428a267b428a267b428a267b428a267b428a267b428a267b428a
-267b428a267b428a267b428a267b428a267b428a267b428a267b428a267b428a267b422b
-267b422b267b8a8acb7b8a2b1a245c5c2323080808081414141414142424241c24ae245c
-5c2323770e0e0e3a3a3a2e2e142424241c24ae245c5c235c087708083a3a1414148f2424
-241c0d0000062323230e0e0e3a3a3a2e2e2e2424241c1c1c311a4242424242427d4a1c06
-b079dbe3241869db424242424242426706071bdb426d6d1b42974a1c06b079db9c061889
-d318066bdb425d4a1c06b079db6d6d1b424242354235a2a2db426d6d1b426d6d1b426d6d
-1b42e32418d26a4a1c06b079db6d6d1b4242246d1b42354242424f700618f3e8d3226306
-f1681b87426d6d1b426d6d1b425d4a1c06b0793596700618f3e8dbe32418d2570e06f157
-1b87426d6d1b425b70a21b9c9c42427d9c42425d9c424229f642429add3542699c42427b
-5b4242be5b42424492424282ee424282924242619235429b9442429b6a42429b6a424280
-5d4242805d4242a85d4235805d4235805d423580d54242805d4242a8974242807d424280
-974242c17d4242e35d4242e35d4242795d4242e35d4235e35d424279974242e3294242e3
-7d4242797d4242797d4242797d42429629424296294242969a4242966942429669424296
-694242966942429669424296694242966942429669424296694242966942429669424296
-694242966942429669424296694242966942429669424296694242966942429669424296
-69424296694242966942422c7d42352c294242421a2e5c232323ae7708081408148f8fc8
-24241c1c1cae2e5c23232308777708141414148f1424241c1c1cae2e5c230e0e0e7777f1
-3a0e2e8f142424241c1c0d00000623230e0e0e3a3a3a2e2e2e2424241c1c1c18b31a35db
-35db353535d3871b1b1bdb35fc1b06060606060606443535ce1b1b3535421a1b3535d387
-1b1b1b7235351b1b35351b1b35353525871b1b1bfc351b1a3535db3535357d242c35d31b
-1b35d31b1b35351b1b3535721b1b8625871b1b1bdb351b1bdb35421b1a35db35353535fc
-1b1b1b1b2535871b1b1b6b4235d31b1b35421a1b353564871b1b1bdb35fc6b1b1b1bfefe
-721b1b866b1b1b1b6b355baa1b1b5b7824d187aa3535d5aa3535d5aa35357d9c35357df6
-db359af63535695b35359a5b3535d25b3535d25b3535445b3535445b3535615b35359392
-353541ee353541d53535a8d535dba8d5db35a8d5353580d5353580d5353580d5353580d5
-353580d5353580d53535e7d5353579d5353579d5353579d5353579d5353579d5353579d5
-3535797d353579693535797d3535797d3535797d35352c7d35352c7d35352c7d35352c69
-35352c6935352c6935352c6935352c6935352c6935352c6935352c6935352c6935352c69
-35352c6935352c6935352c6935352c6935352c6935352c6935352c6935352c6935352c69
-35352c6935352c6935352c6935352c6935352c693535c66935db2c351a2e2323230e0e0e
-3a3ab02e2e2e2424241c1c1c1cae2e2323230e0e0e3a3a3a2e2e2e2424241c1c1c1cae2e
-2323230e0e0e3a3a3a2e2e2e2424241c1c1c0d000006230e0e0e3a3a3a2e2e2e2424241c
-1c1c18182d1ad3d335d3d3d3d343d3d3d3d3d335649f0f1b1b1b1b1b1b1bfcd3644243d3
-d39f43d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d364d3d39fd3d3d3d3d3d343d343d3d3d3d3
-d3d39f7dcf25d364d3d3d3644364d3d3d3d3d3d3d3d39fd3d3d3d3d364d3d39fd3d3d3e2
-d342d3d3d3d364d3d3d3d3d3439fd3436443d3d39fd36464d39f43d3d30fd3d3d39fd3d3
-9f8a9f64d38a0f64d3880f9f43aa424343284264d3288878281b9f64d3ee8ad3d3178a64
-d31faa64d3c3d89fd37dd864d302aad36402aad3d3be92d3d39992d3d3999264d34462d3
-d3932fd3d36139d364611fd3d34192d3d34192d3354192d3d34192d3d34117d3d3de17d3
-d3de17d3d3de17d3d3e717d3d3e7edd3d3e717d3d3e717d3d3e717d3d3e717d3d3e71fd3
-d3e71fd3d33417d3d35a1386d39617d3d39613d3d3966964d3c6c364d3966964d3966964
-d39669d3d3967dd3d3c67dd3d3c67dd3d3c67dd3d3c67dd3d3c67dd3d3c67dd3d3c67dd3
-d3c67dd3d3c67dd3d3c67dd3d3c67dd3d3c67dd3d3c67dd3d3c67dd3d3c67dd3d3c67dd3
-d3c67dd3d3c67dd3d3c67dd3d3c67dd3d3c67dd3d3967dd3d3967dd3d34f69d335967dd3
-1a3a23230e0e0e3a3a3a2e2e2e2424241c1c1c1818ae2e23230e0e0e3a3a3a2e2e2e2424
-241c1c1c1818ae2e23230e0e0e3a3a3a2e2e2e2424241c1c1c180d0000060e0e0e3a3a3a
-2e2e2e2424241c1c1c181818b31a7272368672db86868686863672db86dbdb723672db25
-72db648686368686867286dbdb8686d3868672db8686862586648672db86db868686db72
-64728686db8686dbdb727236728786dbdb8686db7272db25db72db86db86db8686867272
-72dbdbdb6472db7286368636db7286866472db868625867286868686db8672db86db8672
-db7286869f86727235bf8686fe9f7286febf257288bf868660358686f6356472726486db
-929e867292fe86861ffe86867dfe72727daa7286c3aa862569aa8672d2aa3686d2603686
-99f67286fa2f368644928672a9287272a9282586415b86db419286724192868641928686
-091fdb86091f8686091f8686091f7286a81f8686f21f8686f21f8686f21fdb86f21fdb86
-f21fdb86f21f8686341f8686341fdb86341786863417648679178686797d8686967d8686
-967d7286967d8686967d86864f7d86864f7d86864f7d86864f7d86864f7d86864f7d8686
-4f7d86864f7d86864f7d86864f7d86864f7d86864f7d86864f7d86864f7d86864f7d8686
-4f7d86864f7d86864f7d86864f7d86864f7d86864f7d86864f7d86864f7d86864f7d7272
-4fd53672967d72361a2e230e0e0e3a3a3a2e2e2e2424241c1c1c18181cae2e230e0e0e3a
-3a3a2e2e2e2424241c1c1c18181cae2e230e0e0e3a3a3a2e2e2e2424241c1c1c18180d00
-00060e3a3a3a2e2e2e2424241c1c1c1818180606b31af4f4dff43bdfdfdfdfdff4f43bdf
-3b3bf4f4f43b3bf43b3bdfdf3bdfdfdff48af43bdff48adfdff43bdfdfdf3bdf8adff43b
-df3bdfdfdf3bf48af4f48a3bf4df3b3bf4f4f4df3bdf3b3bf4df3bf4f43b3b3bf43bdf3b
-f43bdfdfdff4f4f43b3b3b8af43bf4df3bdf3bf4f4f48adff43bdf8a3bdff4dff4dfdf3b
-dff43bdf3bdff43bf4dfdf8adff4f4df3bf4df8af4f4df8af43bf43b3b3bdf3bdff4dfdf
-3bdff4f4f48af4dff4dff43bdf3bdfdff48a8a8a3bf4f43b3bf48a8a8af43b8a8a3b3bf4
-3b3b8a8af43bdff43bf4df3b8af48af43bdff48a8af43bdf8a3b8a8a3bf43b8a3bf4f48a
-3bdfdf3b3bdf8adf8af48a8a8adf8a8a8a8adf8a8af4df8a8adfdfdf8a8adf8a8adfdf8a
-df3bdf3b3b3b8af43b3bdf3bf4f48a8a3bdfdf42df8a42424242424242df42424242df42
-4242424242df4242dfdf4242df42df4242df4242df42df4242df42df4242df4242df42df
-4242df4242df42df4242df4242df42df4242df4242df42df4242df4242df42df4242df42
-42df42df4242df4242df42df4242df4242df42df4242df4242df42df4242df4242df42df
-42df4242dfdfdfdfdfdfdf8adfdf42421a3a0e0e3a3a3a2e2e2e2424241c1c1c18181806
-06ae3a0e0e3a3a3a2e2e2e2424241c1c1c1818180606ae3a0e0e3a3a3a2e2e2e2424241c
-1c1c181818060d000011111111111111111111111111111111111111111a010101010101
-010101010101010101010101010101010101010101010101010100010101010101010101
-010101010101010101010101010101010101010101010101000101010101010101010101
-010101010101010101010101010101010101010100010101010101010001010101010101
-010101010001010101010101010101010101010101010101010101010100010100010001
-010101010101010101010001010101010101010101010101010101010100010101010101
-010101010101010101010101010100010101010101010100010101010101010101010101
-010101010101010101010101010101010101010101010101010101010101010101010101
-010101010101010101010101010101010101010100010101010101010101010101010101
-010101010101010101010101010101010101010101010101010101010101010101010101
-010101010101010101010101010101010101010101010101010101010101010101010101
-010101010101010101010101010101010101010101010101010101010101010101010101
-0101010101010101010101010101010101010101010101011a1111111111111111111111
-111111111111111111ae1111111111111111111111111111111111111111ae1111111111
-111111111111111111111111111111000006230e0eae0606060606060606060606060606
-060606060606060606060606060606060606061818181818060606060606060606060606
-060606060606060606060606060606060606060606060606060606060606060606060606
-060606060606060606060606060606060606060606060606060606060606060606060606
-060606060606060606060606060606060606060606060606060606060606060606060606
-060606060606060606060606060606060606060606060606060606060606060606060606
-060606060606060606060606060606060606060606060606060606060606060606060606
-060606060606060606060606060606060606060606060606060606060606060606060606
-060606060606060606060606060606060606060618060606180606060606060606060606
-060606060606060606060606060606060606060606060606060606060606060606060606
-060606060606060606060606060606060606060606060606060606060606060606060606
-060606060606060606060606060606060606060606060606060606060606060606060606
-060606060606060606060606060606060606060606060606060606060606060606060606
-060606060606060606060606060606060606060606060606060606060606060606060606
-060606060606060606060606060606060606ae18230e0d0000060e0e23ae060606060606
-060606060606060606060606060606060606060606060606060606060606060606060606
-060606060606060606060606060606060606060606060606060606060606060606060606
-060606060606060606060606060606060606060606060606060606060606060606060606
-060606060606060606060606060606060606060606060606060606060606060606060606
-060606060606060606060606060606060606060606060606060606060606060606060606
-060606060606060606060606060606060606060606060606060606060606060606060606
-060606060606060606060606060606060606060606060606060606060606060606060606
-060606060606060606060606060606060606060606060606060606060606060606060606
-060606060606060606060606060606060606060606060606060606060606060606060606
-060606060606060606060606060606060606060606060606060606060606060606060606
-060606060606060606060606060606060606060606060606060606060606060606060606
-060606060606060606060606060606060606060606060606060606060606060606060606
-060606060606060606060606060606060606060606060606060606060606060606060606
-0606060606060606060606060606060606060606060606061830ae060e0e0d0000060e0e
-0eae06065959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-59595959595959595959595959595959595959595959595959595959595959593030ae06
-0e0e0d0000060e0e23ae0606595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959593030ae060e0e0d0000060e0e0eae060659595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-5959595959595959595959593030ae060e0e0d0000060e0e0eae06065959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959592d3030ae060e0e0d0000060e0e0eae0606
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959593030ae060e0e0d00
-00060e0e0eae060659595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-59595959595959595959595959595959595959595959595959595959595959595959592d
-3030ae060e0e0d0000060e0e0eae06065959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-59595959595959593030ae060e0e0d0000060e0e0eae0606595959595959590000000000
-000000590000595959595959595959595959595959595959595900005959595900000000
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959590000000059595959595959590000590000595959595959595959
-595959595959590000595959595959595959595959595959595959595959595959595959
-000000000000000059000059590000595959595959595959595959595959595959595959
-595959595959000059595900005959595959595959000059595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-5959595959595959595959595959592d3030ae060e0e0d0000060e0e0eae060659595959
-595959000059595959595959000059595959595959595959595959595959595959590000
-595959590000595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595900005959000059595959595959000059000059
-595959595959595959595959595959000059595959595959595959595959595959595959
-595959595959595900005959595959595900005959000059595959595959595959595959
-595959595959595959595959595900005959590000595959595959595900005959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-5959595959595959595959595959595959595959595959593030ae060e0e0d0000060e0e
-0eae06065959595959595900005959595900005900005959000000005959595959595959
-595959595959590000595900005900005959000000005959000059590000595900005959
-000000005959000059000059595959595959595959595959000059595959595900000000
-595900005900005959000000005959590000000059590000000059590000000059590000
-590000595959595959595959595959590000595959590000590000590000000059590000
-000059590000590000595959595959595959595959590000595959000059590000000059
-590000590000590000595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959592d3030ae06
-0e0e0d0000060e0e0eae0606595959595959590000595959590000590000590000595900
-005959595959595959595959595959000059590000590000590000595900005900005959
-000059590000590000595900005900000000005959595959595959595959595900005959
-595959000059590000590000590000590000595900005900005959000059590000595900
-005959000059000000000059595959595959595959595959000059595959000059000059
-590000595900005959000059000000000059595959595959595959595959000059595900
-005900005959000059000059000000590000595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959593030ae060e0e0d0000060e0e0eae060659595959595959000000000059000059
-000059000059590000595959595959595959595959595900005959000059000059000059
-590000595900005900005900005959000059590000590000005959595959595959595959
-595959590000595959595900005959000059000059000059000059590000590000595959
-595959000059590000595900005900000059595959595959595959595959595900000000
-005900005900005959000059590000595900005900000059595959595959595959595959
-595900000000000000590000595900005900005900005959000059595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-59595959595959595959592d3030ae060e0e0d0000060e0e0eae06065959595959595900
-005959595900005900005900000000000059595959595959595959595959595900595900
-595900005900000000000059590000590000590000595900000000000059000059595959
-595959595959595959595959000059595959590000595900005900005900005900000000
-000059000059595959595900005959000059590000590000595959595959595959595959
-595959590000595959590000590000595900005959000000000000590000595959595959
-595959595959595959590000595959000059000000000000590000590000595900005959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-59595959595959595959595959595959595959593030ae060e0e0d0000060e0e0eae0606
-595959595959590000595959590000590000590000595959595959595959595959595959
-595959590000000059590000590000595959595959000059000059000059590000595959
-595900005959595959595959595959595959595900005959595959000059590000590000
-590000590000595959595900005959595959590000595900005959000059000059595959
-595959595959595959595959000059595959000059000059590000595900005959595959
-000059595959595959595959595959595959000059595900005900005959595959000059
-000059590000595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-5959595959595959595959595959595959595959595959595959592d3030ae060e0e0d00
-00060e0e0eae060659595959595959000059595959000059000059000059590000595959
-595959595959595959595959590000595959000059000059590000595959000059590000
-595959000059590000590000595959595959595959595959595959595900005959000000
-005959000059000059000059000059590000590000595900005959000059000000595900
-005900005959595959595959595959595959595900005959595900005900005959000059
-000000595900005900005959595959595959595959595959595900005959590000590000
-595900005900005900000059000059595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-3030ae060e0e0d0000060e0e0ed706065959595959595900005959595900005900005959
-000000005959595959595959595959595959595959000059595900005959000000005959
-595900005959000059595959000000005959000059595959595959595959595959595959
-595900000000595900000000595900005900005959000000005959590000000059595959
-000059590000000059590000595959595959595959595959595959590000595959590000
-590000595959000059590000000059590000595959595959595959595959595959590000
-595959000059590000000059590000590000590000595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959592d3030ae060e0e0d0000060e0e0eae0606595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959000059595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959593030ae060e0e0d0000060e0e0eae060659595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595900005959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595459
-59595959595959595959595959595959595959595959592d3030ae060e0e0d0000060e0e
-0eae06065959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959590000595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595954
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-59595959595959595459545954595954595954595959595959595959595959593030ae06
-0e0e0d0000060e0e0eae0606595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595459595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595954595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959545959595959595459595459595459545959595459545959595959595959595959
-595959545959545959545959595959595959595959595959595959595959595959595959
-5959592d3030ae060e0e0d0000060e0e0eae060659595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595954595959545959595459595954595959545959595459595954595959545959
-595959595959595959595959595954595959545959595459595954595959595959595959
-595459595459545959545954595959595954595459545954595954595959545959595459
-595954595959545959595459595954595959545959595459595954595959545959595459
-595954595959545959595459595954595959545959595459595954595959545959595459
-595959595954595959595959595459595959595959595959595959595959595959595959
-545959545959545959595959595959595959595959595959595959595959595959595959
-5954595959595959595959593030ae060e0e0d0000060e0ef9ae06065959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595459
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595954595954595459595959595959595959595959595959595959595959595959595959
-595959595959595959595459545954595459545959595959595959595959595959595959
-595459595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595459595959595459595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959592d3030ae060e0e0d0000060e0e0eae0606
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595954595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595459
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595954595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959593030ae060e0e0d00
-00060e0e0eae061c59595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595459595959595959595959595959595959595959595959595959
-595959595959595959595959595954595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-59595959595959595959595959595959595959595959595959595959595959595959592d
-3030ae060e0e0d0000060e0e0eae0606303030303030303030303030303030303030a930
-3030a930a93030a930a930fa30303030a930303030303030303030303030303030303030
-30303030303030303030303030a93030a93030a9303030a93030a930fa30303030a93030
-303030303030303030303030303030303030303030303030303030303030303030303030
-3030303030a9303030fa3030a93030fa3030a930fa303030a93030303030303030303030
-3030303030303030303030a9303030a9303030a9303030a930fa30303030a93030303030
-303030303030303030303030303030a9303030a9303030a93030a93030a93030a930a930
-30a93030a930a93030a930a93030a930a93030a930a93030a930a93030a93030a93030a9
-303030a93030a930a93030a930a93030a930a93030a930a930a93030a930a930a93030a9
-3030a93030a930a930a930a93030a93030a930a930a930a93030a930a93030fa30a93030
-a930a93030a930a93030fa3030a930a93030fa3030a930a93030fa3030a930a93030fa30
-30a930a93030fa3030a930a93030fa3030a930a93030fa3030a930a93030fa3030a93030
-a930a93030a930a93030a930a93030a93030a93030a93030a93030a93030a930303030a9
-3030a930a930a93030a93030a930a930a93030a93030a930a93030a93030a93030fa30fa
-303030a9303030303030ae180e0e0d0000060e0e0eae0630303030303030303030303030
-303030303030303030303030303030303030303030303030303030303030303030303030
-303030303030303030303030303030303030303030303030303030303030303030303030
-303030303030303030303030303030303030303030303030303030303030303030303030
-303030303030303030303030303030303030303030303030303030303030303030303030
-303030303030303030303030303030303030303030303030303030303030303030303030
-303030303030303030303030303030303030303030303030303030303030303030303030
-303030303030303030303030303030303030303030303030303030303030303030303030
-303030303030303030303030303030303030303030303030303030303030303030303030
-303030303030303030303030303030303030303030303030303030303030303030303030
-303030303030303030303030303030303030303030303030303030303030303030303030
-303030303030303030303030303030303030303030303030303030303030303030303030
-303030303030303030303030303030303030303030303030303030303030303030303030
-303030303030303030303030303030303030303030303030303030303030303030303030
-303030303030303030303030303030303030ae060e0e0d0000060e0e0eae59592d2d2d2d
-2d2d2d54592d2d2d2d2d2d2d2d5459595959595959595959595959592d54592d54592d2d
-2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d54595959595959
-595959595959595959545954592d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d
-2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d54595459595959595959595959595959
-5954592d2d2d2d2d54592d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d545959595959595959
-595959595959545954592d2d2d54592d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d5459595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959592d5459592d2d2d2d2d2dae060e0e0d0000060e0e
-0ed759595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-59595959595959595959595959595959595959595959595959595959595959595959ae06
-0e0e0d0000060e0e0eae2d59595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959545959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959ae060e0e0d0000060e0e0e22595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-5959595959595959595959595959ae060e0e0d0000060e0e0eae59595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-59595959595959595959595959595959595959595959ae060e0e0d0000060e0e0eae5959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595954
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959ae060e0e0d00
-00060e0e0eae595959595959595959595959595959595959595959595954595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595954595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-5959ae060e0e0d0000060e0e0e2259595959595959595959595959595959595959545959
-595959545959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-59595959595959595959ae060e0e0d0000060e0e0eae5959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595459595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595459595959595954595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959545959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959ae060e0e0d0000060e0e0e22595959595959
-595959595959595959595959595959595959595959595459595959595959595959595959
-595959595959595959595959595959595959595959595959595959545959595959595959
-595954595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959545959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-5959595959595959595959595959595959595959595959595959ae060e0e0d0000060e0e
-0eae59595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959545959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595459595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959000000000059595959595959595459590000
-595959595959595959000059000059595959595900005959595959595959595959595959
-595959595959595959595959000059595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-59595959595959595959595959595959595954595959595959595959595959595959ae06
-0e0e0d0000060e0e0e225959595959595959595959595959595959595959595959595959
-595959595959595959595954595959595959545959545959595459595959595959595959
-595959595959595959595959595959595959595959595959595954595959595959595959
-595959595459595959545959545959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595954595959595900005959000059595959
-595959595959000059595959595959595959595900005959595959590000595959595959
-595959545959595959595959595959595959595900005959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959ae060e0e0d0000060e0e0eae59595959545954595954595959591c1c1c1c
-1c1c1c1c1c1c1c5959595959595959000000000000595959595959595959595959595959
-595959595459595459595959595959595959595959595959595959595959595959595959
-545959545959545959595959595959595959595959595959595959595459595459595459
-595959595959595959595959595959595959595959595954595959595959595959590000
-595959000059590000000059590000000059590000000059590000590000595959595959
-000059595959590000000059590000595959000059590000000059590000595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959545959595959595959595959595959595959
-5959595959595959595959595959ae060e0e0d0000060e0e0ed759595959595959595959
-595959591c061c061c061c061c1c30595959595959595900005959595959545959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959000059595900005900005959000059590000595900005959000059000059
-000059595959595900005959595900005959000059000059595900005900005959000059
-000059595959545959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595954595954595959545959545959595459595954595459
-545959595459595459595459595459595954595959595459595959545959595959595959
-59595959595959595959595959595959595959595959ae060e0e0d0000060e0e0eae5959
-5959595959595959595959591c0659595959595959303059595959595959590000595959
-590000590000590000000059595900000000595900000000005959000000005959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595900005959590000590000595900005959000059595959
-595900005900005900005959595959590000595959590000595900005959000059000059
-590000595900005900005959595959595954595954595959545959595459595459595459
-595459545959545959595959595959595959595959595959595959595959595959595959
-595954595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595954595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595954595959595959595959595959595459595959595959595959595959ae060e0e0d00
-00060e0e0ed7595959595959595959595959595906065959595959595930305959595959
-595959000059595959000000000000005959000059000059590000595959590000590000
-595900005959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959590000595959000059000000000000
-595900005959590000000000590000590000595959595959000059595959000000000000
-595900005900005959000000000000590000595959595959595959595959595959595959
-595959595959595959595959595959595459595954595959545959595459595954595459
-595459595954595959595959545959595954595959545959595459595954595959545959
-595459595959595959595459545959595959595959595959595959545959595959595954
-595959595959595459595959595959545959595959595954595959595959595459595959
-595959545959595959595954595959595959595954595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-5959ae060e0e0d0000060e0e0eae59595959595959595959595959590606595959595959
-593030595959595959595900000000005900000059590000595900005900005959000059
-595900005959000059590000595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959000059595900
-005900005959595959590000595900005959000059000059000059595959595900005959
-595900005959595959595900000059595900005959595959000059595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959545954595959595959595459545959545959595459595959
-595459545959595959545954595959595954595459595959595459545959595959545954
-595959595954595459595959595459545959595959545959545959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595954595959595959595959595959595459
-59595959595959595959d7060e0e0d0000060e0e0ed75959595959595959595959595959
-060659595959595959303059595959595959590000595959590000595959000000000000
-590000000000005959590059595900000000000059595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595900005959000059590000595900005959000059000000595900005900005900005959
-595959590000595959590000595900005959590000005959590000595900005900005959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959ae060e0e0d0000060e0e0eae595959595959
-595959595959595906065959595959595930305959595959595959000059595959000059
-595900005959595959000059595959595900005959590000595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959590000000000595959590000000059595959000059590000005900
-000000590000595959595959000000000000590000000059595959590059595959590000
-000059590000595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-5959595959595959595959595959595959595959595959595959ae060e0e0d0000060e0e
-0ed75959595959595959595959595959061c5959595959595930fa595959595959595900
-005959595900005959590000595900005900005959000059000059595959000059590000
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-59595959595959595959545959595959595959595959595959595959595959595959ae06
-0e0e0d0000060e0e0eae59595959595959595959595959591c0659595959595959303059
-595959595959590000595959590000595959590000000059595900000000595900000000
-005959000000005959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595954595959
-595959595959ae060e0e0d00001c0e0e0ed75959595959595959595959595959061c3030
-303030303030305959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959545959595954595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-5959595959595959595959595959ae060e0e0d0000060e0e0eae59595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-59595959595959595959595959545959595959595959ae060e0e0d00001c0e0e5cd75959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959ae060e0e0d00
-00060e0e0eae595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-5959595959595959595459595959595959595959595959595959cd5959595959cd595959
-595959cd5959595959595959595959595959595954595959595959595959595959595954
-595959595959595959595959595959545959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-5959ae060e0e0d0000060e0e5cd759595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-5959595959595959595959595959595959595954595959cd5959595959cd595959595959
-cd5959595959cd595959595959cd595959cd595959595959545959595959595959595959
-595959595959595959595459595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-59595959595959595959ae060e0e0d0000060e0e0eae5959595959595959595959595959
-595959595954595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595459595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959590100595959590100010059595901000100
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959545959595959595959595959595959
-595959595459595959595959595959595959595959595959595959595959595959545959
-595959595959595959545959595959595959ae060e0e0d00001c0e0e0ed7595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595954
-595959595959595959595959595959545959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959590000000159595900005959
-000159000059590001595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595459595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-5959595959595959595959595959595959595959595959595959ae060e0e0d0000060e0e
-0eae59595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595459595959595959595959595959595959
-595959595959595959595959595959595459595959595959595954595959595959595959
-595954595959595959595959595459595959595954595959595959595959595959595900
-005959590000595900005900005959000059595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595459595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-59595959595959595959595959595959595959595959595959595959595959595959ae06
-0e0e0d00001c0e0e59d75959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959545959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959590000595959000059590000590000595900005959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959545959595959595959595959595959595959595959595959595959595959
-595959595959ae060e0e0d0000060e0e2eae595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959545959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595954595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959000059595900005959000059000059590000595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-5959595959595959595959595959ae060e0e0d0000060e5c0e2259595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595459595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959545959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595900005959590000595900005900
-005959000059595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959545959595959595959595959
-59595459595959595959595959595959595959595959ae060e0e0d0000060e0e0eae5959
-5959595959595959595959591c1c1c1c1c1c1c1c1c1c1c59595959595959590000595959
-000059000059595959590000595959595959595959595959590000000000015959595959
-595959595959595959595959595959595959595959595959590100010001000100595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595459595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959590000595959
-000059590000590000595900005959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-59cd59595959595959595959595959595959595959545959595959595959ae060e0e0d00
-001c0e0e0ed759595959595959595959595959591c1c061c1c1c1c1c061c305959595959
-595959000059595900005959595959595959000059595959595959595959595959000059
-595959595959595959595959595959595959595959595959595959595959595959595959
-000059595959595959595959595959595959595959595959595959595959595959595959
-595959595959cd5959595959595959595959595959595959595959595959595959595959
-595959595959595959595459595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959000059595900005959000059000059590000595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-5959ae060e0e0d0000060e0e0eae59595959595959595959595959591c06595959595959
-593030595959595959595900005959590000590000595900005900005959000000005959
-595959595900005959595900005901005901000001595901590100015901000159595959
-5959595959595959000059595959010000015959595959595959cd595959cd5959595959
-595959595959595959595959595959595959595959595959595459595959595959595959
-595959595959595959595959595959595959595954595954595959595959595959595959
-595959595959595959595954595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595900005959595900000000595959000000005959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-59595959595959595959ae060e0e0d00001c0e0e0e4f5959595959595959595959595959
-06065959595959595930a959595959595959590000595959000059000059000059000000
-590000595900005959595959590000595959590000000000000059590000590000595900
-005959000159595959595959595959590000595959000059590001595959595959595959
-5959595959595959cd595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595459595959595959595959595954
-5959595959545959595959595959595959595959595959595959595959cd595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-cd5959595959595959595959595959595959ae060e0e0d0000060e0e0eae595959595959
-595959595959595906065959595959595930305959595959595959000000000000005900
-005900005959000059000059590000595959595959000000000059000000595900005959
-000059000059590000595900005901010000000059595959000059595900005959000059
-59595959595959595959595959595959595959595959cd59595959595959595959595959
-595959595959545954595959595959545954595959545959595954595959595959595959
-595959595959595959545959595959545954595459595459595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959cd5959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-5959595959595959595959595959595959545959595959595959ae060e0e0d00001c0e0e
-0ed759595959595959595959595959590606595959595959593030595959595959595900
-005959590000590000590000595900005900000000000059595959595900005959595900
-005959590000595900005900005959000059590000595959595959595959595900005959
-590000595900005959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959545954595959595959595959595959595959
-595959595959595959595959545959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959cd59595959cd
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595954595959595959595959595959
-595959595959595959595959595959595959545959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-59595959595959595959595959595959595959595959595959595959595959595959ae06
-0e0e0d0000060e0e0eae5959595459595959595959595959060659595959595959303054
-595959595959590000595959000059000059000059590000590000595959595959595959
-590000595959590000595959000059590000590000595900005959000059000000000000
-595959590000595959000059590000595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595954595959595959595959595959595959595959595959595959595959595959595959
-59595959595959595959595959595959595959595959595959cd59595959595959595959
-595959595959595959595959cd5959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595905595959055959
-590559595959595959055959590559595905595959055959595905595959055959595959
-595959595959595959595959595959cd5959595959595959595959595959595959595459
-595959595959ae060e0e0d00001c0e0e0ed75959595959595959595959595959061c5959
-595959595930305959595959595959000059595900005900005900005900000059000059
-590000595959595959000059595959000059595900005959000059000059590000595900
-005959595959595959595959000059595900005959000059595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959545959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959590559595959595959595959595959595959595959595959595959595959595959
-595959595959590559595959595959595959590559595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-5959595959595959595959595959ae060e0e0d0000060e0e0eae59595959595959595959
-595959590606595959595959593030595959595959595900005959590000590000595900
-005900005959000000005959595959595900005959595900005959595900000000595900
-005959000059590000595959595959595959595900005959595900000000595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-a930a93030a93030a93030a930303030a93030a930fa3030fa3030a930a93030a93030a9
-30a93030fa3030fa3030a930a93030a93030a930a930fa30fa30fa30fa30fa30fa30fa30
-fafa3027fa30fa27fafa30273027fafa30fa30fa27fafa30fa30fa3027fafafafafafafa
-fafafafafafafafafafafafafa30273027fafafafafafafafa30273027fafafafafafafa
-fafafafafafa30fa30fa30fa30fa3030303030fa30303030303030303030303030303030
-3030fa3030fa30fafa30fafa595959595959595959595905595959595959590559595959
-595959055959595959595905595959595959590559595959590559595959590559595905
-595959595959595959595959595959595959595959055959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-59595959595959595959595959595959595959595959ae060e0e0d00001c0e0e0ed75959
-595959595959595959595959061c30303030303030303059595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595930303030303030303030303030303030303030303030303030303030
-303030303030303030303030303030303030303030303030303030303030303030303030
-303030303030303030303030303030303030303030303030303030303030303030303030
-303030303030303030303030303030303030303030303030303030303030303030303030
-303030303030303030303030303030303030303030303030303030303030303030303030
-30303030303030303030303030303030303030f159595959595905595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959ae060e0e0d00
-00060e0e5cae595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959593030050505050505050505050505050505050505
-050505050505050505050505050505050505050505050505050505050505050505050505
-050505050505050505050505050505050505050505050505050505050505050505050505
-050505050505050505050505050505050505050505050505050505050505050505050505
-05050505050505050505050505050505050505050505050505050505050505051c1c0606
-060606061c0618181c061c061c06061c1c1c1c1c1c1c1c1c2e1c2e1c5959595959595959
-595959595959055959595959595905595959595959590559595959595959055959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-5959ae060e0e0d00001c0e0e0ed759595954595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959303005050505050505050505
-050505050505050505050505050505050505050505050505050505050505050505050505
-050505050505050505050505050505050505050505050505050505050505050505050505
-050505050505050505050505050505050505050505050505050505050505050505050505
-050505050505050505050505050505050505050505050505050505050505050505050505
-050505050606060606060606060606060606060606060606061c1c1c1c1c1c1c1c301cf1
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-5959595959595959595959595959595959595959595959595959595959cd595959595959
-59595959595959595959ae060e0e0d0000060e0e0eae5959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-5959595959595959595959595959595959cd595959595959595959595959595930300505
-050505050505050505050505050505050505050505050505050505050505050505050505
-050505050505050505050505050505050505050505050505050505050505050505050505
-050505050505050505050505050505050505050505050505050505050505050505050505
-050505050505050505050505050505050505050505050505050505050505050505050505
-050505050505050505050505060659595959595959595959595930065959595959595959
-5959595930301c1c59595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595459595959595959ae060e0e0d00001c0e0e0ed7595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-59595959595959595959595959595959595959595959595959595959595959cd59595959
-595959593030050505050505050505050505050505050505050505050505050505050505
-050505050505050505050505050505050505050505050505050505050505050505050505
-050505050505050505050505050505050505050505050505050505050505050505050505
-050505050505050505050505050505050505050505050505050505050505050505050505
-050505050505050505050505050505050505050506065959595959595959595959593006
-59595959595959595959595930301c2e5959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-5959595959595959595959595959595959595959595959595959ae060e0e0d0000060e0e
-0eae59595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-5959595959595959595959595959cd595959595959595959595959595959595959595959
-595959595959595959595959303005050505050505050505050505050505050505050505
-050505050505050505050505050505050505050505050505050505050505050505050505
-050505050505050505050505050505050505050505050505050505050505050505050505
-050505050505050505050505050505050505050505050505050505050505050505050505
-050505050505050505050505050505050505050505050505050505050606595959595959
-595959595959300659595959595959595959595930301c1c595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-59595959595959595959595959595959595959595959595959595959595959595959ae06
-0e0e0d00001c0e0e0ed75959595959595959595959595959595959595959545959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-59595959595959595959595959595959595959595959595959595959cd59595959595959
-595959595959595959595959595959595959595930300505050505050505050505050505
-050505050505050505050505050505050505050505050505050505050505050505050505
-050505050505050505050505050505050505050505050505050505050505050505050505
-050505050505050505050505050505050505050505050505050505050505050505050505
-050505050505050505050505050505050505050505050505050505050505050505050505
-0606595959595959595959595959300659595959595959595959595930301c2e59595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959590559595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959ae060e0e0d0000060e0e0eae595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959543030050505050505
-050505050505050505050505050505050505050505050505050505050505050505050505
-050505050505050505050505050505050505050505050505050505050505050505050505
-050505050505050505050505050505050505050505050505050505050505050505050505
-050505050505050505050505050505050505050505050505050505050505050505050505
-050505050505050506065959595959595959595959593006595959595959595959595959
-30301c1c5959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959cd5959595959595959
-5959595959595459595959595959ae060e0e0d00001c0e0e0ed759595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595954595959595959595959595959
-59595959595959595959cd59595959595959595959595959595959595959595959595959
-303005050505050505050505050505050505050505050505050505050505050505050505
-050505050505050505050505050505050505050505050505050505050505050505050505
-050505050505050505050505050505050505050505050505050505050505050505050505
-050505050505050505050505050505050505050505050505050505050505050505050505
-050505050505050505050505050505050606595959595959595959595959300659595959
-595959595959595930301c2e595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959cd5959595959595959595959
-59595959595959595959595959595959595959595959ae060e0e0d0000060e0e0eae5959
-595959595959595959595959595959595959595954595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595930300505050505050505050505050505050505050505050505050505
-050505050505050505050505050505050505050505050505050505050505050505050505
-050505050505050505050505050505050505050505050505050505050505050505050505
-050505050505050505050505050505050505050505050505050505050505050505050505
-050505050505050505050505050505050505050505050505060659595959595959595959
-5959300659595959595959595959595930301c1c59595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595905595959595959
-595959595959595959595959595959595959595959595959595959595959ae060e0e0d00
-001c0e0e59d7595959545959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-59595959595959cd59595959595959595959595959595959595959595959595959595959
-5959595959595959595959595959595930fa050505050505050505050505050505050505
-050505050505050505050505050505050505050505050505050505050505050505050505
-050505050505050505050505050505050505050505050505050505050505050505050505
-050505050505050505050505050505050505050505050505050505050505050505050505
-050505050505050505050505050505050505050505050505050505050505050506065959
-59595959595959595959301c59595959595959595959595930301c2e5959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595905595959595959
-59595959595959595959595959595959595959595959cd59595959595959595959595959
-5959ae060e0e0d0000060e0e0eae59595959595959595959595959591c1c1c1c1c1c1c1c
-1c1c1c595959595959595900005959590000590000595959595900005959595959595959
-595959595900005959590000595959595959595900005959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959303005050505050505050505
-050505050505050505050505050505050505050505050505050505050505050505050505
-050505050505050505050505050505050505050505050505050505050505050505050505
-050505050505050505050505050505050505050505050505050505050505050505050505
-050505050505050505050505050505050505050505050505050505050505050505050505
-050505051c06595959595959595959595959300659595959595959595959595930301c1c
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-59595459595959595959ae060e0e0d00001c0e0e0ed75959595959595959595959595959
-1c1c061c06060606061ca959595959595959590000595959000059595959595959590000
-595959595959595959595959590000595959000059595959595959590000595959595959
-595959595959595959595959595954595959595959595959595959055959595959595959
-5959595959595959cd595959595959595959595959595959595959595959595930300505
-050505050505050505050505050505050505050505050505050505050505050505050505
-050505050505050505050505050505050505050505050505050505050505050505050505
-050505050505050505050505050505050505050505050505050505050505050505050505
-050505050505050505050505050505050505050505050505050505050505050505050505
-0505050505050505050505050606595959595959595959595959301c5959595959595959
-5959595930301cf159595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959ae060e0e0d0000060e0e0eae595959595959
-59595959595959591c065959595959595930305959595959595959000059595900005900
-005959000059000059590000000059595959595959000059595900005900005900005959
-000059590000590000590000595959000000005959000059590000595901015901015901
-015959595959595959595959595959595959595959595959595959595959595954595959
-595959593030050505050505050505050505050505050505050505050505050505050505
-050505050505050505050505050505050505050505050505050505050505050505050505
-050505050505050505050505050505050505050505050505050505050505050505050505
-050505050505050505050505050505050505050505050505050505050505050505050505
-050505050505050505050505050505050505050506065959595959595959595959593006
-59595959595959595959595930301c1c5959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-5959595959595959595959595959595959595959595959595959ae060e0e0d00001c0e0e
-0ed759595959595959595959595959590606595959595959593030595959595959595900
-005959590000590000590000590000005900005959000059595959595900005959590000
-590000005900005900005900005959000000590000590000595900005900005959000059
-590000590001015901015959595959595959595959595959595959595959595959cd5959
-595959595959595959595959303005050505050505050505050505050505050505050505
-050505050505050505050505050505050505050505050505050505050505050505050505
-050505050505050505050505050505050505050505050505050505050505050505050505
-050505050505050505050505050505050505050505050505050505050505050505050505
-050505050505050505050505050505050505050505050505050505050606303030303030
-303030303030301c30303030303030303030303030301c2e595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-59595959595959595959595959595959595959595959595959595959595959595959ae06
-0e0e0d0000060e0e0eae59595959595959595959595959591c0659595959595959303059
-595959595959590000000000000059000059000059590000590000595900005959595959
-590000595959000059000059590000590000000059595900005959000059000059590000
-595900005900005900005959000059590000595959595959595959595959595959595959
-595959595959595959595959595959595959595930300505050505050505050505050505
-050505050505050505050505050505050505050505050505050505050505050505050505
-050505050505050505050505050505050505050505050505050505050505050505050505
-050505050505050505050505050505050505050505050505050505050505050505050505
-050505050505050505050505050505050505050505050505050505050505050505050505
-0630303030303030303030303030303030303030303030303030303030301c1c59595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595954
-595959595959ae060e0e0d00001c0e0e59d75959595459595959595959595959061c5959
-595959595930fa5959595959595959000059595900005900005900005959000059000000
-000000595959595959000059595900005900005959000059000000005959590000595900
-005900005959000059590000590000590000595900005959000159595959595959595959
-59595959595959595959595959595959595959595959595959595959fa301c1c1c1c1c1c
-1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c
-1c1c1c1c1c1c2e1c2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e
-2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e
-2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e1c1c1c
-1c1c1c1c1c1c06060606060606060606060606060606061c1c1c1c1c1c1c1c1c1c1c1c1c
-1c1c1cf15959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-59595959595959595959595959595959595959cd59595959595959595959595959595959
-5959595959595959595959595959ae060e0e0d0000060e0e0eae59595959595959595959
-595959590606595959595959593030595959595959595900005959590000590000590000
-595900005900005959595959595959595900005959590000590000595900005900005900
-005959000059590000590000595900005959000059000059000059590000595900005959
-595959595959595959595959595959595959595959595959595959595959595959595959
-301c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c
-1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c
-1c2e1c1c2e1c1c2e1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c
-1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c
-1c1c1c1c1c1c1c1c1c1c0606060606060606060606060606060606060606060606060606
-060606060606060606061c1c595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-59595959595959595959595959595959595959595959ae060e0e0d00001c0e0e0ed75959
-595959595959595959595959061c59595959595959303059595959595959590000595959
-000059000059000059000000590000595900005959595959595900005900005959000059
-590000590000595900005900005959000059000059590000595959000059590000595959
-0000595900015959595959595959595959595959cd595959595959595959595959595959
-545959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959055959590559595959595959595959595959595959595959595959595959
-595905595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959ae060e0e0d00
-00060e0e0eae595959595959595959595959595906065959595959595930305459595959
-595959000059595900005900005959000059000059590000000059595959595959590000
-000000595900005959000059000059595900000000595900005959000000005959595900
-005959000059595900005959000059595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959590559595905595959595959595959595959590559595959595959595959595959
-595959595959595959595959595905595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595459595959
-5959ae060e0e0d00001c0e0e0ed75959595959595959595959595959061c303030303030
-303030595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595905
-595959055959590559595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-59595959595959595959595959595959cd59595959595959595959595959cd5959595959
-59595959595959595959ae060e0e0d0000060e0e0eae5959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595905595959595959595959055959595959
-590559595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959ae060e0e0d00001c0e0e59d7595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959cd5959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595905595959595959595905595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-59fa30fa30fa30fa3030a930fa30fa30a93030a9595959595959ae060e0e0d0000060e0e
-0eae59595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595905595959595959595959595959595959
-5959595959595959593030303030303030303030303030303030301c595959595959ae06
-0e0e0d00001c0e0e0ed75959595459595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595459595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-59595959595959595959595959595959593030050505050505053005050505050505061c
-595959595959ae060e0e0d0000060e0e0eae595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959055959595959595959595959595959595959595959595959
-5959595959595959595959595959595959595959595959595930300505050505051c3005
-0505050505051c06595959595959ae060e0e0d00001c0e2e59d759595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959590559595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959055959590559595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959303005
-05050505051c3030050505050505061c595959595959ae060e0e0d0000060e0e0eae5959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-5959595959303005050505051c1c30300505050505050606595959595959ae060e0e0d00
-001c0e0e0ed7595959595959595959595959595959595959595954595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959055959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595954595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595905595959595959595959595959
-595959595959595959595959055959595959595959595959595905595959595959595959
-59595959595959595959595959303005050505051c1c5930300505050505061c59595959
-5959ae060e0e0d0000060e0e0eae59595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-59595959cd59595959595954595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595954
-595959595959595459595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-5959055959595959595959595959595959595959593030050505051c1c59593030050505
-05050606595959595959ae060e0e0d00001c0e0e0ed75959595959595959595959595959
-595954595959595954595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595459595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959545959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595905595959
-595959595959595959595959595959595959595959595959595959595930300505050506
-1c5959593030050505050606595959595959ae060e0e0d0000060e0e0eae595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-5930300505051c1c595959593030050505050606595959595959ae060e0e0d00001c0e0e
-0ed759595459595959595959595959595959595959595959595459595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-5959595959595959593030050505061c59595959593030050505061c595959595959ae06
-0e0e0d0000060e0e0eae5959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595954595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-5959595959595959595959595959595959303005051c0659595959595930300505050606
-595959595959ae060e0e0d00001c0e0e0ed7595959595959595959595959595959595959
-595959595959595954595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959545959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-5959595959595959595959595959595959595959595959595930300505061c5959595959
-595930300505061c595959595959ae060e0e0d0000060e0e59ae59595959595959595959
-595959595959595959595959595959595959595459595959595959595959595959595954
-595959595959595959545959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959040459595959595959595959595904045959595904045959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959045959595959595959595959595959595904
-595959595959595959595959595959595959595959595959595959595959595959545959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959080559595959
-595959595959595959595908045959595959595959595959595959080459595959595959
-595959595959595959595959595959590559595959595959595959595959595959303005
-1c065959595959595959303005050606595959595959ae060e0e0d00001c0e0e0ed75959
-59595959595959595959590303595903030303590303030303590303590303cd03030359
-cd0303595903035903030303035903030359595959545959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959045959595959595959595959595904595959595904595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959590459595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959b354085959595959595959595959595959cd
-045959595959595959595959595959595959595959595959595959595959595959595959
-5959595959303005061c5959595959595959593030050606595959595959ae060e0e0d00
-00060e0e0eae5959595954595959595959595959035959035959037f59037f59037f0359
-7f59035959037f5903597f037f03597f59037f59037f5903595959595959595459595459
-595959595954595459595959545959595954595959595954595459545959595959595959
-595959595959595959595959595959595959595959595959595905595959590404cd0459
-590404cd0404595959595959595959040404595904040459595959040459595959590459
-595959590459595959595959595959595959595959595959595959595959595959595959
-545959595959595959595959595959595959595959595959595959595959595959595959
-595959595959590404590459590459040459595959040459595959040404595959040459
-595904045959595959595959595904040404590404590459595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959590804cd08545908540408545959590804cd
-595959080404cd59590404595959080459595959595959595959592d04595959590804cd
-5959590804cd595904590804595959080459595908540408045959595959595959595959
-5959595959595959595959595930301c0630303030303030303030303005060659595959
-5959ae060e0e0d00001c0e0e0ed759595959595959595959595959590359590359590303
-5903595903035959595903035903595903595903590359035903595903037f0359595459
-595959595959595954595459595959595959595959595459595959595459595959595959
-59545959595959595959595959595959cd59595959595959055959595959595959595959
-5959cd045904590459590459cd04595959595959595904595959597f0459590459590459
-5904595959cd0459595959cd045959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-59595959595959595959595959595904cd04590459cd04595904595904595904595904cd
-595959595959045959595959045959595959595959597f0459597f04cd04590459595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595954045904590454590454
-5904595904595408595904cd595959595959045959545905085959595959595959595959
-045959590459540859590459590459590454045959590459cd04592d590459cd59595959
-595959595959595959595905595959595959595959303006303030303030303030303030
-3030061c595959595959ae060e0e0d0000060e0e0eae595959595959595959595959597f
-03595903595903590303595903590359595903590303595903595903590359037f035959
-035903035959595959595959595959595959595959595959545959595959595959595959
-59595959595959595959595959595959595959cd59595959595959595959595959595959
-595959595959595959595904590459045959045959045959595959595959590404595959
-04cd59045959040404595959595904595959595904595959595959595959595959595959
-595959595959595959595954595959595959595959595959595959595959595959595959
-5959595959595959595959595959595959595959595959045904590459590459cd045959
-040404cd595959040459595959cd0459595904040459595959595959595959047f595904
-59047f045959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595904
-7f0459045959045959045959040404b35959590404595959595904595959040404595959
-595959595959595904cd5959045959045959045959595959040459595959040404595959
-540459595959595959595959595959595959595959595959595959595930300505050505
-050505050505050505050606595959595959ae060e0e0d00001c0e0e0ed7595959595959
-595959595959595903595903595903595903595903595903595903595903595903595903
-595903590359595903595903595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-5959595959595959595959595959595959595904cd045904595904595904595959595959
-5959cd59590459590459590459cd04595904595959590459595959590459595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-5959595959595959595959595959595959595959595959595959595959597f0459045904
-59590459590459cd045959045959595959045959595904595904cd5904595959595959cd
-595959045959040459047f04595959595959595959595959595959595459595959595959
-595959595905595959595959595959595959595959595959595959595959055959595959
-595959595959590459045904595904595904cd59045959045959595959045959cd590459
-590459590459595959595959595959590459595904595904545904595904597f04590459
-59cd04595904595959045959595959595959595959595959595959595959595959595959
-593030060606061c1c061c061c0606060606061c595959595959ae060e0e0d0000060e0e
-0eae595959595959595459595959595959030359590303595903590303037f5903030359
-5903597f5903035959590359035959030359590359595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959045904590404595904
-045959595959595959590404045959040404590404595904045959590404040404590404
-040404595959595959595959595959595959595959595459595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-5959590459047f0404040404590404595904045959590404047f59590404040404590404
-590459595959595959595959040459045904590404595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959590559
-595959595959595959595959595959047f04590404040404590404595904045959590404
-045959590404040404590404cd04595959595959595904040404047f5904045959595904
-04595904047f040459595904045959590404040459595959595959595959595959595959
-59595959595959595930301c06060606060606060606060606300606595959595959ae06
-0e0e0d00001c0e0e0ed7595959595959595959595959595959597f59597f5959597f5959
-59595959595959595959595959597f595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959cd59597f0459595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959545959595959595959595959595959595959595959590559595959595959590559
-5959595959595959595959595959595959595959595959595959597f597f595959595959
-5959cd595959cd59595959595959597f5959595959595959595959595959595959595959
-597f595959597f595959595959595959595959597f595959595959595959595959595959
-595959595959595959595959595959595930300606595959595959595959595930300606
-595959595959ae060e0e0d0000060e0e59ae595959595959595959595959595959595959
-595959595959595959595959597f59595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959590404595959590404040404045959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-59595959595959595959595959595959595959595959597f595959597f59595959595959
-5959595959595959597f5959595959595959590404040404045959595959595959595959
-595959595954595954595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959055959595959595959595959
-595959595959595959595959595959595959595959595959595959595959590404040404
-0459595959595959595959595959595959595959595959595959595959595959595959cd
-595959595959595959595959595959595959595959595959593030060659595959595959
-5959595930300606595959595959ae060e0e0d00001c0e0e0ed759595959595959595959
-597f59595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-5905595959595959595959595959595959595959595959cd595959597f59595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-5959cd59595959595959cd5959595959595959595959cd59595959595959597f59595959
-597f59595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-59595959cd5959cd59595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959303006
-0659595959595959595959593030061c595959595959ae060e0e0d0000060e0e0eae5959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595459595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-5959595959595959595959597f5959cd5959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595930300606595959595959595959595930300606595959595959ae060e0e0d00
-001c0e0e0ed7595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-59cd59595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-5959595959595959cd595959595959595959595959595959595959595959595959595959
-5959595954595959595959595930300606595959595959595959592d3030060659595959
-5959ae060e0e0d0000060e0e0eae59595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-59595959cd59595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959cd5959595959595959595959595959595959595959
-595959595959595959595959595959595459595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595954595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959545959303006065959595959595959595959
-30300606595959595959ae060e0e0d00001c0e0e59d75959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959cd5959595959595959595959595959595959
-595959595959595959595959595959595959595959055959590559595905595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-5959595959595959595959595959595959595959cd595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959055959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-59595959595959595959055959595959595959595959595959595959593030061c595959
-595959595959592d3030061c595959595959ae060e0e0d0000060e0e0eae595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-5959595959595959595959cd595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959cd595959cd595959cd595959595959595959595959595959595959
-595959595959595959595959595959595959595959595905595959595959595959595959
-595959595905595959055959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-5930300606595959595959595959595930300606595959595959ae060e0e0d00001c0e0e
-0ed759595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595905
-595959595959595959595959595959595959595959595959595959595959595959595959
-59595959595959cd595959cd595959595959595959595959595959cd5959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595905595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-59595959595959592d3030061c595959595959595959592d30300606595959595959ae06
-0e0e0d0000060e0e0eae5959595959595959595959595959595959595959595959595959
-5959595959595959595959595959595959595959595959cd595959595959595959595959
-59595959595959595959595959595959cd5959595959cd59595959595959595959595959
-595959595959595959595959595905595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-5959595959595959595959595959cd595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595930300606595959595959595959595930300606
-595959595959ae060e0e0d00001c0e0e0e4f595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959cd595959cd595959cd595959cd595959cd595959595959cd595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959cd5959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959590559595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959055959595959595959595959595959595959595959595959595959595959
-59595959595959595959595959cd595959595959595959595959595959595959595959cd
-59595959cd59595959595959cd5959595959595959595959595959595959595959595959
-5959595959595959595959595959595959595959595959592d3030061c59595959595959
-5959592d3030061c595959595959ae060e0e0d0000060e0e0eae59595959595959595959
-5959595959cd59595959595959595959595959595959595959595959595959595959cd59
-595959595959595959595959595959595959595959595959595959595959595959595959
-59595959595959595959cd59595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595954595959595959595959595959595959595959
-595959595959595959595959595959595959595905595959055959595959595959595959
-5959595959595959595959595959595959595959595959595959cd595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959303006
-06595959595959595959595930300606595959595959ae060e0e0d00001c0e0e0ed75959
-5959cd595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-5959595959595959595959595959595959595959595959595959cd59595959cd59595959
-59595959595959595959595959595959595959595959595959595959595959cd59595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-5959595959cd595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-5959595959595959cd595959595959595959595959595959595959595959595959595959
-595959592d3030061c595959595959595959592d30300606595959595959ae060e0e0d00
-00060e0e0eae595959595959595959595959595959595959595959595959595959595959
-595959595959cd5959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595905595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959cd59595959cd595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-59595959595959595959595959595959595959595959595959595959cd59595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959055959
-595959595959595959595959593030060659595959595959595959593030060659595959
-5959ae060e0e0d00001c0e0e0e4f59595959595959595959595959595959595959595959
-59595959595959595959595959595959cd59595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-59595959595959595959595959595959595959595959595959595959cd59595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-59595959595959595959595959595959595959595959595959595959595959595959cd59
-5959595959595959595959595959cd5959595959595959595959595959cd595959595959
-595959595959595959595959055959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-59595959595959595959595959595959595959592d3030061c595959595959595959592d
-3030061c595959595959ae060e0e0d0000060e0e0eae5959595959595959595959595959
-59595959cd59595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595905595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959cd5959595959
-595959595959595959595959cd59595959595959595959595959595959cd595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-59595959cd59595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959cd5959595959595959595959
-595959595959595959595959595959595959595959595959595959595930300606595959
-595959595959595930300606595959595959ae060e0e0d00001c0e0e0ed75959595959cd
-5959595959595959595959595959595959cd5959cd5959cd595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959cd5959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-59595959595959595959595959595959595959595959595959595959cd59595959595959
-5959595959595959595959595959595959595959595959595959595959595959cd595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-59595959cd59595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-2d3030061c595959595959595959592d30300606595959595959ae060e0e0d0000060e0e
-0eae59595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-5959595959595959595959595959cd595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959590559595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959cd5959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-59595959595959595930300606595959595959595959595930300606595959595959ae06
-0e0e0d00001c0e0e0ed75959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-59595959595959595959595959595959595959595959595959595959595959cd59595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-5959595959595959595959595959595959595959595959595959595959595959595959cd
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595905595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959055959595959595959595959
-595959595959595459595959595959592d3030061c595959595959595959592d3030061c
-595959595959ae060e0e0d0000060e0e0eae595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959055959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595905595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-5959595959595959595959595959595959595959595959595959cd595959595959595959
-595959cd5959595959595959595959595959595959595959595959cd5959595959595959
-5959595959595959595959595959595959595959595959595930300606303030a9303030
-3030303030300606595959595959ae060e0e0d00001c0e0e0ed759595959595959cd5959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959cd5959595959595959595959595959595959cd5959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959590559
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-59595959595959595959595959595959595959595959595959595959595959592d30301c
-30303030303030303030303030300606595959595959ae060e0e0d0000060e0e0eae5959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959cd59595959595959595959595959cd595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959590559595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-59595959595959595959595959595959595959595959595959595959cd59595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595930300505050505050505050505050505050606595959595959ae060e0e0d00
-001c590e0ed7595959595959595959595959595959595959595959595903595959595959
-59595959595959595959595959595959595959cd59595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959cd5904595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595904595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595904595959595959
-5959595959595959595959595959595959cd595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959593030050505050505050505050505050505061c59595959
-5959ae060e0e0d0000060e0e0eae59595959595959595959595959595959595959595959
-59035959595959595959595959595959595959cd59595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959cd5959595959595959
-595959590559595959595959595959595959595959595959595959595959595959595959
-5959595959595959595959595904cd5959595959595959595959595959595959cd045959
-595959595959595959595959595959045959595959595959595959595959595959595959
-595959045959595959595959595959595959595959595959595959595959595905595959
-595959595959595959595959595959595959595959595959590459595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959055959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-5904cd595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959303005050505050505050505050505
-05050606595959595959ae060e0e0d00001c0e0e0ed75959595959595959595959595959
-595959595959595959035959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959045959cd5959595959595959595959
-595959595904595959595959595959595959595959595904595959595959595959595959
-59595959595959595959cd04595959595959595959595959595959595959595959595959
-595959595959595959cd59595959595959595959595959595959595959595959cd045959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-5959595959595959595959595959595905595959595959595959cd595959595959595959
-595959595959595959045959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595930300505050505
-05050505050505050505061c595959595959ae060e0e0d0000060e0e59ae595959595959
-595959595959cd5959595959595959595903595959595959595959cd5959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595905595959595959595959
-595959595959595959595959595959595959595959595959595959595904595959595959
-595959595959590404045959040404045959040459595959045904040459040404045959
-595959595959590404595904045904045959040404045959590404595959045904040459
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595904595959595959595959595959595959595959595959595959595959595959
-595959595959cd5959595959055959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959cd5959595959595904595959595959595959595959595959595959
-59595959595959595959595959595959595959cd59595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-5930300505050505050505050505050505050606595959595959ae060e0e0d00001c2e0e
-0ed7595959595959595959595959595959595959595959597f0359595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-590459595959cd5959595959595904cd5959595959045959cd5959cd0459595959045959
-59cd5904cd5959595959595959590459590459cd0459cd0459595904cd59595904cd5904
-5959cd0459cd595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959590459595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959055959595959590559595959595959595959595959595959
-5959595959595959cd5959595959595959595959595959cd590459595959595959595959
-59595959595959595959595959595959595959595959595959595959595959595959cd59
-595959595959595959595959595959595959595959595959595959595959595959595459
-59595959595959595930300505050505050505050505050505050606595959595959ae06
-0e0e0d0000060e0e0eae5959595959595959595959595959595959595959595959035959
-59cd59595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959045959595959595959595959595904045959595904595959590404
-04595959cd045959595959045959595959595959595904cd5904595904595904cd595904
-59595959040404cd59595904595959595959595959595959595959595959595959595959
-5959595959595959595959595959595959595959590459595959cd595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959045959
-5959595959595959cd595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959055959590559595959
-595959595959595959595959595959595930300505050505050505050505050505050606
-595959595959ae060e0e0d00001c0e2e59d7595959595959595959595959595959595959
-595959595903595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959cd5959595959595959595959595959
-5959595959595959595959595959595959590559595959595959595959595959cd595959
-595959595959595959595959595959595904595959595959595959595959595959045959
-590459590404595904595959590459595959590459590459595959595959045959045959
-045959045959590459590459045959045959590459595959595959595959595959595959
-59595959595959595959595959595959595959595959595959595959cd04595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-59595959cd045959595959595959595959595959595959595959595959595959cd595959
-595959595959595959595959595959595959cd5959595959595959595959595959595959
-595959595959595959595959595959595959595959595959543030050505050505050505
-050505050505061c595959595959ae060e0e0d0000060e0e0eae59595959595959595959
-5959595959595959595959595903cd595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959590459595959595959595959
-595904040459595959590404595904045904595904040404595959590404595959595959
-595959040459595959040459045959590404cd5959040459595904040404595959590559
-595959595959595959595959595959595959595959595959595959595959595959595959
-5904595959595959595959595959595959595959595959595959595959595959cd595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959590559595959595959595959595959595959595959595959595959
-5959595959595959595959595904595959595959cd595959595959cd5959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595459595959303005
-05050505050505050505050505050606595959595959ae060e0e0d00001c0e0e0ed75959
-595959595959595959595959595959595959595959035959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959045959
-595959595959595959595959595959cd595959cd595959cd595959595959595959595959
-59595959595959595959595959595959595959595959595959595959595959595959cd59
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959045959595959595959595959595959cd5959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959590559595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959045959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595930fa050505050505050505050505050505061c595959595959ae060e0e0d00
-00060e0e0ed7595959595959595959595959595959595959595959595903595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-59cd595959cd595959595959595959595959595959595959590559595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595904595959595959cd5959595959595959595959595959595959595959595959
-5959595959595959cd5959040404040404cd595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595904595959595959595959595959595959595959
-5959595959595959cd595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595904595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959593030050505050505050505050505050505060659595959
-5959ae060e0e0d00001c0e0e0ed759595959595959595959595959595959595959595959
-5903595959595959595959595959595959595959595959595959595959cd5959cd5959cd
-5959cd5959cd595959595959595959595959595959595959595959595959595959595959
-5959595959595959595959595959595959595959595959595959595959cd595959595959
-595959595959595959595959590459595959595959595959595959595959595959595959
-595959595959595959595959595959595959cd5959cd5959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959590459595959595959cd5959
-595959595959595959cd5959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595905595959595959590559595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-590459595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959303005050505050505050505050505
-0505061c595959595959ae060e0e0d0000060e0e0eae5959595959595959595959595959
-595959595959595959c8595959595959595959595959595959595959595959cd59595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-59595959595959595959595959595959595959595904595959595959595959cd59595959
-5959595959595959595959595959595959595959cd595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-5959595959595959595959595959595959595959595959595959595959595959cd045959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-5959595959595959cd0459cd595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595930300505050505
-050505050505050505050606595959595959ae060e0e0d00001c0e0e59d7595959595959
-59595959595959595959595959595959590359595959595959595959595959595959cd59
-5959595959595959595959595959595959595959595959595959595959595959595959cd
-595959595905595959595959595959595959595959595959595959595959595959595959
-59595959595959595959595959595959595959595959595959595959cd04595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595901015959
-595959595904595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595904595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595459595959595959595959
-5930fa050505050505050505050505050505061c595959595959ae060e0e0d0000060e0e
-0eae59595959595959595959595959595959595959595959590359595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959cd5959595959595959595959595959
-5904595959595959595959595959595959595959595959595959595959595959cd595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959590100010159595959590459595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595905595959055959595959
-595959595959595959590559595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959590459595959595959595959
-59595959cd59595959595959595959595959595959595959595959595959595959595959
-595959595959595959590559595959595959595959595959595959595959595959595959
-5959595959595959593030050505050505058d050505050505050606595959595959ae06
-0e0e0d00001c0e0e0e4f59595959595959cd595959595959595959595959595959035959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959055959595959595959595959595959595959595959595959595959
-595959595959595959045959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-5959595959595959595959595959595959595959595959595959595959cd595959595959
-5959cd5959595959595959595900000101010159cd045959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959055959595959595959595959590559595959595959590559
-59595959cd5959595959595959595959cd59595959595959595959595959595959045959
-5959595959595959595959595959595959595959595959595959cd595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-54595959595959595959595959595959593030050505050505050505050505050505061c
-595959595959ae060e0e0d0000060e0e0ec8595959595959595959595959595959595959
-5959595959035959595959595959595959cd595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595901010101010101010101010101010101010101
-010101010101010101010101010101010101010101010101010101010101010101010101
-010101010101010101010101010101010101010101010101010101010101010101010101
-010101010101010101010101010101010101000000000000000001010104595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595904595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959545959593030050505050505050505
-0505050505050606595959595959ae060e0e0d00001c0e0e0e4f59595959595959595959
-59cd5959595959595959595959c859595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595905595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959590459595959595959595959
-5959595959595959595959595959595959595c5959595959595c59595959595c59595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595900000000000059
-590459595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959540859595959595959595959595959595959595959595959
-595959595959595959595959595959cd5959595959595959595959595959595959595959
-59595959595959595959595959595959595959595959595959595959595959595930fa05
-0505050505050505050505050505061c595959595959ae060e0e0d0000060e0e0ed75959
-5959595959595959595959595959595959595959590359595959595959cd595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959045959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-590000005959595959045959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959590559595959595959595959595959595959595959595959595959595959
-595959595959595959595959cd5959595959595959045959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-590559595959595959595959595959595959055959595959595959595959595959595959
-595959595930300505050505050505050505050505050606595959595959ae060e0e0d00
-001c0e0e0ed7595959595959595959595959595959595959595959595903595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-5959595959595959595959595959595959595959595959595959cd595959595959595959
-595959595904595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595900005959595959595904595959595959595959595959595959595959
-595959595959595959595959595959590559595959595959595959595959595959595959
-595959590559595959595959595959595959595959595959595959595959595959595959
-5959cd595959595959595959595959595959595959595959595959595904595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959593030050505050505050505050505050505061c59595959
-5959ae060e0e0d0000060e0e0eae59595959595959595959595959595959595959595959
-590359595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959cd595959cd59595959590459595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-5959595959595959595959595959595959595959595959595904cd595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595905595959595959595959055959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-590459595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959590559595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959303005ef0505050505050505050505
-05050606595959595959ae060e0e0d00001c0e0e0ed75959595959595959595959595959
-595959595959595959c85959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-59595959595959595959595959595959595959595959cd59595959595959595959595959
-595959595959595959595959595959595959595959045959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959045959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-5959595959595959cd045959595959595959595959595959595959595959595959595959
-59595959595959595959595959cd59595959595959595959595959595959595959595959
-595959595959595959595959595959595954595959595959595959595930300505050505
-05050505050505050505061c595959595959ae060e0e0d0000060e0e59ae595959595959
-595959595959595959595959595959595903595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595904595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595904595959595959595959595959595959595959595959595959595959595959
-595959595959595959055959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-5959cd5959595959595959595959595959045959cd595959595959595959595959595959
-59595959595959595959595959cd59595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595459
-5930300505050505050505050505050505050606595959595959ae060e0e0d00001c0e0e
-0ed759595959595959595959cd5959595959595959595959590359595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959055959595959595959595959595959595959
-59595959595959595959cd5959595959595959595959595959595959595959595959597f
-590459595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959590459595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959590559595959
-595959595959595959590559595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959590459595959595959595959
-5959cd5959cd595959595959595959595959595959595959595959595959595959595959
-595959595959595959590559595959595959595959595959595959595959595959595959
-5959595959595959593030050505050505050505050505050505061c595959595959ae06
-0e0e0d0000060e0e0ed75959595959595959595959595959595959595959595959035959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959590559595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959045959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959045959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595905595959595905595959595959595905595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959045959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595930300505050505050505058d05050505050606
-595959595959ae060e0e0d00001c0e0e0ed7595959595959595959595959595959595959
-5959595959c8595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-59595959595959595959595959595959595959cd59595959595959595959595959595959
-595959595959595959595959595959595904595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959cd590459cd59595959
-cd5959595959595959595959595959595959590559595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-59595959055959595959595959595959cd59595959595959595959595959595959595959
-59595959590459595959cd5959595959595959595959595959cd59595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-5959595959595959595959595959595959595959595959595930fa050505050505050505
-0505050505050606595959595959ae060e0e0d0000060e0e59ae59595959595959595959
-595959595959595959595959590359595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959055959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-5959595959595959595959595959595959595959595959597f0459595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-5904595959595959595959cd595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-59595959595959cd59595959590459595959595959595959595959595959595959595959
-59cd59595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959545959303005
-05050505050505050505050505050606595959595959ae060e0e0d00001c0e0e0ed75959
-595959595959595959595959595959595959595959035959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959045959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959045959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595954085959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959545959595959
-59595959593030050505050505050505050505050505061c595959595959ae060e0e0d00
-00060e0e0eae595959595959595959595959595959595959595959595903595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595904595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595904595959595959595959595959595959595959
-055959595959595959595959595959595959595959595959595959595959595959595905
-595959595905595959595959590559595959595905595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595904595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959593030050505050505050505050505050505060659595959
-5959ae060e0e0d00001c0e0e59d7595959595959595959cd595959595959595959595959
-59c859595959595959595959595959595959595959595959595959595959595959595959
-595959595905595959595959595959595959595959595959595959595959595959055959
-595959595959595959595959595959595959595959595959595959cd5959595959595959
-595959595959595959595959590459595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959590459595959595959595959
-595959055959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-590459595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-59595959595959595959595959595959595959595930fa05050505050505050505050505
-0505061c595959595959ae060e0e0d0000060e0e0ed75959595959595959595959595959
-595959595959595959035959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595905595959595959595959595959595959595959595959595959
-59595959595959595959595959595959595959597f045959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-59595959595959595959595959595959595959595959595959595959595959595904cd59
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959045959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959590559595959595959595959595959595959595959595959595930300505050505
-050505050505050505050606595959595959ae060e0e0d00001c0e0e0ed7595959595959
-595959595959595959595959595959595903595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595904595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959cd5959595959595959
-cd5959595904595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595905595959595959595959595959590559595959
-595905595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595904595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959590559595959595959595959595959595459595959595959595959595959595959
-593030050505050505050505050505050505061c595959595959ae060e0e0d0000060e0e
-0ed759595959595959595959595959595959595959595959590359595959595959595959
-595959595959595959595959595959595959595959590559595959595959595959595959
-595959595905595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-590459595959595959595959595959595959595959595959595959595959595959595959
-595959045959595959590459595959590404595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959590459595959595959595959595959595959595959595959
-595959595959595959595959055959595959595959595959595959595959595905595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959cd0459595959595959595959
-5959595959595959595959595959595959cd595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-59595959595959595930300505050505050505050505050505050606595959595959ae06
-0e0e0d00001c0e0e0e4f5959595959595959595959595959595959595959595959c85959
-595959595959595959595959055959595959595959595959590559595959595959595959
-595959595959595959595959595959595959595959595959595959595905595959595959
-5959595959595959595959cd595959595959595959595959595959595959595959595959
-595959595959595959045959595959595959595959595959595959595959595959595959
-595959595959595959595904595959595959595959595959590459595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595954085959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959045959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595905595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595930fa050505050505050505050505050505061c
-595959595959ae060e0e0d0000060e0e0eae595959595959595959595959595959595959
-595959595903595959595959595959595959595959595959055959590559595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959597f04595959595959595959595904590404595959
-590404595904590459040459595959595959040404045959590404595959590404045959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595904595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595905595959595959595959595959595959595959595959595959595959
-5959595959595959595959595959595959595959cd595959595959595959595959595959
-595959595904595959595959595959595959595959595959595959595959595959595959
-595959590559595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959593030050505050505050505
-0505050505050606595959595959ae060e0e0d00001c0e0e0ed759595959595959595959
-59595959595959595959595959c859595959595959595905595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959590459595959595959595959
-59590459cd04595904595904590459045904595959595959595959045959595959590459
-595904595904595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-590459595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959590559595959595905595959595959
-05595959595959595959595905595959595959595959cd59595959595959595959595959
-5959595959595959595959595904595959595959595959cd595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595954595959595959595959303005
-0505050505050505050505050505061c595959595959ae060e0e0d0000060e0e0ed75959
-5959595959595959cd595959595959595959595959035959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959055959595959595959595959
-5959595959595959595959595959595959595959cd595959595959595959595959045959
-595959595959595959590459590459590404047f59045904590459595959595959595904
-595959595959045959590459590459595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959045959595959595959595959595959595959595959595959595959
-595905595959595959595959595959595959590559595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959cd595959595959595959595959595959595904cd59595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-59595959593030050505050505c005050505050505050606595959595959ae060e0e0d00
-001c0e0e2e4f5959595959595959595959595959595959595959595959c8595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595905595959595905595959595959595959
-59595959595959595959595959595959595959cd59595959595959595959595959595959
-595959595904595959595959595959595959045959047f59045959045959047f04595959
-595959595959590459590459597f04595959045959045959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-59595959595959595959595959595959cd04595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959cd5959595959595959595959595908595959595959
-5959595959595959cd595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-5959595959595959595959595930fa050505050505050505050505050505061c59595959
-5959ae060e0e0d0000060e0e0eae59595959595959595959595959595959595959595959
-590359595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959590559595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959cd0459595959595959595959590404045904045959040459
-5959045904595959595959597f59595904047f5904040404047f590404cd045959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959590459595959595959595959
-595959595959595959595959595959595959595959595959595959595959590559595959
-595959595959595959595959590559595959595905595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-590459595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959303005050505050505050505050505
-05050606595959595959ae060e0e0d00001c0e590ed75959595959595959595959595959
-5959595959595959590d59cd595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-5959595959595959595959cd595959595959595959045959cd5959595959595959597f59
-59595959595959597f59595959595959595959595959597f59595959595959cd59595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959045959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959590559595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-5959595959cd595959045959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595954595959595959595959595959595959595930300505050505
-05050505050505050505061c595959595959ae060e0e0d0000060e0e0ed7595959595959
-595959595959595959595959595959595903595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959590559595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595904595959595959
-cd5959595959595959595959597f59595959595959595904040404040459595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-5959595959595959595959595959595959595959595959595959595959cd595959595959
-595959595904cd5959595959595959595959595959595959595959590559595959595959
-595959595959595959595959595959595905595959595959595959595959595959595959
-595959590559595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595904595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595954595959595959
-5930300505050505050505050505050505050606595959595959ae060e0e0d00001c0e0e
-0e4f59595959595959595959595959595959595959595959590359595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595905595959595905595959595959595959595959
-59595959cd59595959595959595959595959595959595959595959595959595959595959
-59045959595959595959595959595959595959595959595959597f5959597f597f597f59
-595959595959595959595959595959595959595959595959595959595959595959595959
-59595959595959595959595959595959595959595959595959595959cd595959cd595959
-595959595959595959595959590459595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959590559595959
-595959595959595959595959595959595959595959595959055959595959595959595959
-595959595959595959595959595959595959595959595959cd0459595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-59595959595959595930fa050505050505050505050505050505061c595959595959ae06
-0e0e0d0000060e0e0ec85959595959595959595959595959595959595959595959035959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959590559595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-59595959cd59595959045959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-5959595959595959cd595959cd595959cd595959cd595959cd5959595959595959595959
-5959595959595959595959595959595959595959590459595959cd595959595959595959
-595959595959595959595959595959595959595959595905595959595959595959595959
-595959595959595959590559595959595959595959595959595959595959595959595959
-5959595959595959595959595959595959595959595959595959595959595959590459cd
-595959595959595959595959595959595959595959055959595959595959595959595959
-595959595959595959595905595959595959595959595959595959595959595959595959
-595959595959595959595959595959595930300505050505050505050505050505050606
-595959595959ae060e0e0d00001c0e0e0e4f595959595959595959595959595959595959
-5959595959c8595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-59595959595959055959595959595959595959595959cd59595959595959595959595959
-595959595959595959595959595959597f04595959595959590000595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-cd5959595959595959595959595959595959595959595959595959595408595959595959
-595959595959595959595959595959595959595959595959595959595959595959590559
-595959595959595959595959595959595959595959055959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595904595959595959595959595959595959595959595959595959595959595959
-595959595959595905595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959593030050505050505050505
-050505050505061c595959595959ae060e0e0d0000060e0e0eef59595959595959595959
-595959595959595959595959590359595959595959595959595959595959595959595959
-595959595959595959595959595959055959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959590459595959010000005959
-595959597f59595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-5959595959595959595959cd595959595959595959595959595959595959595959595959
-590459595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959590559595959595959595959595959
-055959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959590459595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959055959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959303005
-05050505050505050505050505050606595959595959ae060e0e0d00001c2e590e4f5959
-595959595959595959595959595959595959595959c85959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595905595959595905595959595959595959595959595959595959595959
-59595959595959595959cd59595959595959595959595959595959595959595959045959
-000000000000595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959045959595959595959595959595905595959595959595959595959
-595959595959595959595959595959595905595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959cd5959595959595959595959
-595959595959cd5959595959595959595959595954085959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595905595959595959595959595959595959595959595959545959595959595959545959
-595959595930fa050505050505050505050505050505061c595959595959ae060e0e0d00
-00060e0e0ed759595959595959cd59595959595959595959595959595903595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595900000000000000000000000000000000000000000000010000010000010000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000100010000010001000100010001000100010000010000010001010000010001010101
-010101010101010101010101010100000004595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959055959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595904595959595959
-595959595959595959055959595959595959595959595959595959595959595959595959
-595959595959595959595959595959055959595959590559595959595959595959595959
-595959595959595959595959593030050505050505050505050505050505060659595959
-5959ae060e0e0d00001c0e0e0ed759595959595959595959595959595959595959595959
-590d59595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959055959595959595959595959595959595905
-5959595905595959595959595959595959595959595959595959595959cd595959595959
-595959595959595959595959590459590000000000595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959590459595959595959595959
-595959595959595959595959595959595959595959055959595959595959595959595905
-595959590559595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-590459595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959303005050505050505050505050505
-0505061c595959595959ae060e0e0d0000060e0e0eae5959595959595959595959595959
-595959595959595959035959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959590559595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959045959595900000000595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959045959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-59595959595959595904cd59595959595905595959595959595959595959595959595959
-595959595959595959595959055959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595930300505050505
-050505050505050505050606595959595959ae060e0e0d00001c0e0e0e4f595959595959
-5959595959595959595959595959595959c8595959595959595959595959595959595959
-595959595959595959590559595959595959595959595959595959595959595959595959
-0559595959590559595959595959595959595959595959595959595959595959595959cd
-595959595959595959595959595959595959595959595959595959595904595959595959
-590000595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595904595959595959595959595959595959595959595959595959595959595959
-595959595959590559595959595959595959595959595959595959595959055959595959
-5959595959595959595959595959595959595959595959cd595959595959595959595959
-595959595959595959595959595959595904595959595959595959595959595959595959
-595959595959595959595905595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595954595959595959
-5930fa050505050505050505050505050505061c595959595959ae060e0e0d0000060e0e
-0eef59595959595959595959595959595959595959595959590359595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959590559595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-590459595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-5959595959595959595959595904cd595959595959590559595959595959595959595959
-595959595959595959595959055959595959595959595959595959595959055959595905
-595959595959595959055959595905595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959590459595959595959595959
-595959595959595959595959595959595959595959595959055959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-59595959595959595930300505050505050505050505050505050606595959595959ae06
-0e0e0d00001c2e590e4f59595959595959595959595959595959595959595959590d5959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959590559595959595959595959595959595959595959595959595959595959595959
-590559595959595959595959595959595959595959595959595959595959cd5959595959
-595959595959595959045959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-59595959595959595959595959595959595959592d085959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959055959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595954085959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-59595959595959595959595959595959593030050505050505050505050505050505061c
-595959595959ae060e0e0d0000060e0e0eae595959595959595959595959595959595959
-595959595903595959595959595959595959595959595959595959055959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959055959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595904595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595904595959595959
-595959595959595959595959595959595959595905595959595959595959595959595959
-595959595959595959595959595959595959595959055959595959595959595959595959
-595959595959595959595959595959cd5959595959595959595959595959595959595959
-595959595904595959595959595959595959595959595959595959595959595959595959
-595959595959595959595905595959595959595959595959595959595959595959595959
-595959595959595959595459595959595959595954595959593030050505050505050505
-8d05050505050606595959595959ae060e0e0d00001c0e0e0ed759595959595959595959
-59595959595959595959595959c859595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959055959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959590459595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-590459595959595959595959595959595959595959595959595959595959055959595959
-595959590559595959595959055959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959cd5959
-595959595959595959595959590459595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-59595959595959595959595959595959595959595959595959595959595959595930fa05
-0505050505050505050505050505061c595959595959ae060e0e0d0000060e0e0ed75959
-595959595959595959595959595959595959595959035959595959595959595959595959
-055959595959595959595959595959595959595959595959595959595959590559595959
-595959595959595959590559595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959045959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-59595959595959595904cd59595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959590559595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-5959595959595959595959cd59595959595959595904cd59595959595959595959595959
-595959595959595959595959595959055959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595930300505050505050505050505050505050606595959595959ae060e0e0d00
-001c2e592e4f5959595959cd5959595959595959595959595959595959c8595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959590559595959595959595959595959595959595959595905595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595904595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-59595959595959595959595959597f595904595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959590559595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595904595959595959
-595959595959595959595959595959595959595959595959595959595905595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959593030050505050505050505050505050505061c59595959
-5959ae060e0e0d0000060e0e0eae59595959595959595959595959595959595959595959
-590359595959595959590559595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959055959595959
-595959595959055959595959595959595959595959595959595959595959595959595959
-595959595959595959595959590459595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959590459595959595959595959
-595959595959595959595959055959595959595959055959595959595959595959595959
-595959055959595959595959590559595959595959595959595959055959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-590459595959595959595959595959595959595959595959590559595959595959595959
-595959595959595959595959595959595959595959595959595959595959055959595959
-595959595959595959595959595959595959595959303005050505050505050505050505
-05050606595959595959ae060e0e0d00001c0e0e0ed75959595959595959595959595959
-595959595959595959c85959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959cd5959595959595959595959045959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-59595959595959595959595959595959595959595959545959595959595959592d085959
-595959595959595959595959595959595959595959595959595959595959595959595959
-590559595959595959595959595959595959595959595959595959595905595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595954085959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595930fa0505050505
-05050505050505050505061c595959595959ae060e0e0d0000060e0e0ed7595959595959
-595959595959595959595959595959595903595959595959595959595959595959595959
-595959595959595959595959595959595959590559595959595959590559595959590559
-595959595905595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595904595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595904595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-59595959595959595959595959595905595959595959595959595959cd59595959595959
-595959595959595959595959595959595904595959595959595959595959595959595959
-595959595959595959595905595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-5930300505050505050505050505050505050606595959595959ae060e0e0d00001c0e0e
-0ed75959595959595959595959595959595959595959595959c859595959595959595959
-595959595959595959595959055959595959595959595959595959595959055959595959
-595959595959595959595959595959595959595905595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-590459595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595459
-595959595959595959595959590459595959595959595959595959595959055959595959
-595959595959595959595905595959595959595959055959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959590459595959595959595959
-595959595959595905595959595959595959595959595959595959590559595959595959
-595959595959595905595959595959595959595959595959595959595959595959595959
-5959595459595959593030050505050505050505050505050505061c595959595959ae06
-0e0e0d0000060e0e0eae5959595959595959595959595959595959595959595959035959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959055959
-595959055959595959595959595959595959595959595959595959595959595959595959
-595959597f59595959045959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-59595959595959595959595959595959595959595904cd59595959595959595959595959
-595959595959595959590559595959595959595959595959595959595959595959595959
-055959595905595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959045959
-595959595959595959595959595959595959595959055959595959595959590559595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595930300505050505050505050505050505050606
-595959595959ae060e0e0d00001c0e0e0e4f595959595959595959595959595959595959
-5959595959c8595959595959595959595959595959595959595959595959595959595959
-590559595959595959595959595959595959595959595905595959595959595959595959
-595959595959595959595959595959595959595959cd59595959595959cd595959595959
-595959595959595959595959595959595904595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595954
-595959545954595954595959595959595959595959595959595959595904595959595959
-595959595959595959595959595959595959595959055959595959595959595959595959
-595959595959595959595959595959595959595959595959595905595959595959595959
-59595959595959595959595959595959595959595959595959595959595959cd59595959
-59595959cd04595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-5905595959595959595959595959595959595959595959595930fa050505050505050505
-050505050505061c595959595959ae060e0e0d0000060e0e0eae59595959595959595959
-595959595959595959595959590359595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595905595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959590459595959595959595959
-595959045959595959595959595959595959595959595959595959595959595959595959
-595959590459595959045959595959595959595959595959595959040459595959595959
-59595954595959040459595959595959595959595959595959595959cd59595959595959
-590459595959595959595959595905595959595959055959595959595959595959595959
-595905595959595959595959055959595959595959595959590559595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959590459595959595959595959595905595959595959595959
-595959595959595959595959595959595959590559595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959303005
-05050505050505050505050505050606595959595959ae060e0e0d00001c0e0e0ed75959
-595959595959595959595959595959595959595959c85959595959595959595959595959
-595959595959595959595959595959595959595959595959595959590559595959055959
-595959595959595959595959595959595959595959595959595959595959595959595959
-5959595959595959595959595959595959595959595959cd59595959595959597f045959
-595959595959595959595904595959595959595959595959595959595959595959595959
-59595959595959595959595959595959590459595959595959595459595954595459597f
-045954595954595959595959595959590459595959595959595959595959595959595959
-595959595959595954085959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-055959595959595959590559595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595954085959590559595959595959595959
-595959595959595959595959595905595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595954
-59595959593030050505050505050505050505050505061c595959595959ae060e0e0d00
-00060e0e0ed7595959595959595959595959595959595959595959595903595959595959
-595959595959055959595959595959595959595959595959595959590559595959595959
-595959595959595959595959595905595959595959595905595959595959055959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-5459595959047f5959595959595959595959040404045959045904040404045904045959
-595959595904590459040459045904040459590404595959040404045959590404595959
-595959595959595904595959590404595959590404595959045904045959595959595959
-595959595959595959595959595959595904595959595959595959595959595959595959
-595959595959595959595959055959595959595959595905595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595904595959595959
-595959595959595959590559595959595905595959595959595959590559595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-5959595959595959595959595930300505050505050505058d0505050505060659595959
-5959ae060e0e0d00001c2e592e4f59595959595959595959595959595959595959595959
-590559595959595959595959595959595959595959595959595959590559595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959055959595959595959595959595959595959595959595959595959595959
-59595959595959595959595959045959595959595959595959597f04597f59597f04597f
-597f04597f0459595959595959045904590459597f0459597f59597f045959597f04597f
-5959047f5904595959595959595959590459595904595904595904595904595904590459
-595959595959595959595959595959595959595959595959590459595905595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595905595959595959595959595959595959595959595959595959595959595959
-59595959595959595959cd5959595959595959cd59595959595959595959595959595959
-590459595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595905
-59595959595959595959595959595959595959595930fa05050505050505050505050505
-0505061c595959595959ae060e0e0d0000060e0e0eae5959595959595959595959595959
-595959595959595959035959595959595959595959595959595959595959595959595959
-595959595959595959595959055959595959595959595959055959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-59595959cd59595959595959595959595959595959045959595959595959595959595904
-59595959590459595959045959045959595959597f047f047f0459595904595959595959
-0459595959045959595904040459595959595959595959590459595904597f0459590459
-7f59597f0404595959595959595959595959595959595959595959595959595959045959
-595959595959595959595905595959595959055959595959595959595959595959590559
-595959595959595959595959595959595959595959595959595959055959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959045959595959595959595959590559595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595459595959595959595959595930300505050505
-050505050505050505050606595959595959ae060e0e0d00001c0e0e0ed7595959595959
-5959595959595959595959595959595959c8595959595959595959595959595959595959
-595959595959595959590559595959595959595959595959595959595959595959595959
-595959595905595959595959055959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959597f04595959595959
-5959595959597f045959045959045959595904597f045959595959595959045904595959
-5904595959595959045959597f0459590459045959045959595959595959595904595959
-045959045959045959045959047f04595959595959595959595959595959595959595959
-595959cd5904595959595959590559595959595959595959595959595959055959595959
-595959595959595959595959595959595959595959595959595905595959595959595959
-595905595959595959055959595959595959595959595959595959595959595959595959
-595959595959595959595959595959cd5904595959595959055959595959595959595905
-595959595905595959595959595959595905595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-593030050505050505050505050505050505061c595959595959ae060e0e0d0000060e0e
-0eae59595959595959595959595959595959595959595959590359595959595959595959
-595959595959595959595959595959595959595959595959055959595959595905595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-590459595959595959595959595959590404595904040404595959040459595959595959
-5959047f0459595904040404595904040404045959590404597f59040459595959595959
-595904040404045959040459595959040459590404590404595959595959595959595959
-595959595959595959595959590459595959595959595959595959595959595959595959
-595959595959595905595959595959595959595905595959590559595959595959595959
-595959595959595959595959595959595959595959595959595959055959595959595959
-595959595959595959595959595959595959595959595959590459595959595959595959
-595959595959595959595959595959595959055959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-59595959595459595930300505050505050505050505050505050606595959595959ae06
-0e0e0d00001c0e0e59d75905595959595959595959595959595959595959595959c85959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959055959595959595905595959595959595959595959595959595905595959
-595905595959595959595959cd5959595959595959595959595959595959595959595959
-595959595959595959045959595959595959595959595959597f59597f597f5959595904
-7f5959595959595959595959595959597f597f595959597f597f59595959595959595959
-7f595959595959595959597f597f595959597f5959595959595959595959595959595959
-595959595959595959595959595959595959595954085959595959595959595959595959
-055959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959055959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595954085959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959055959595959595959595959595959595959055959
-595959595959595959595959595959595930fa050505050505050505050505050505061c
-595959595959ae060e0e0d0000060e0e0eef595959595959595959595959595959595959
-595959595903595959595959595959595959595959595959595905595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-5959595959595959595959595959595959595959595959595959595959cd595959595959
-595959595959595959595959595959597f04595959595959595959595959595959595959
-595959595904045959595904040404040459595959595959595959595959595959595959
-595959595959595959595904040404040459595959595959595959595959595959595959
-5959595959595959cd595959595959595959595959595959595959595904595959595959
-595959595959595959595959595959595959595959595959595959595959595905595959
-595959595959595959055959595959595959595959595959595959595905595959595959
-055959595959595959595959595959595959595959595959595959595959595959595959
-595959595904595959595959595959595959595959595959595959595959595959595959
-595959595959595905595959595959590559595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959593030050505050505050505
-0505050505050606595959595959ae060e0e0d00001c0e2e59d759595959595959595959
-595959595959595959595959590559595959595959595959595959595959595959595959
-595959595959055959595959595959595959595959595959595959595959595959595959
-595959055959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959590459595959595959595959
-59595959595959595959595959597f5959595959597f59597f5959595959595959595959
-59595959595959595959595959595959595959595959597f595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-590459595959595959590559595959595959595959595959595905595959595959590559
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-59cd59595959595959595959590459595959595959590559595959595959055959595959
-595959595959595905595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959303005
-0505050505050505050505050505061c595959595959ae060e0e0d0000060e0e0eae5959
-595959595959595959595959595959595959595959035959595959595959595959595959
-595959595959595959595959595959595959595959590559595959595959595959055959
-595959595905595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959045959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-59595959595959595904cd59595959595959595959595959595959055959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-055959595959595959595959595959595959595959595959595959595959595959595959
-59595959595959595959595959595959595959595904cd59595959595959595959595959
-595959595959595905595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595930300505050505050505050505050505050606595959595959ae060e0e0d00
-001c0e0e0ed75959595959595959595959595959595959595959595959c8595959595959
-595959595959595905595959595959590559595959595959595959595959595959595959
-595959595959595959595959595959595959595959595905595959595905595959595959
-5959595959595959595959cd595959595959595959595959595959595959595959595959
-595959595904595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-5959595959595959595959595959595959595959595959595959cd595959595959595959
-595959595959595959595959595959595408595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959055959595959595959
-055959595959595959595905595959595959055959595959595959595959595959595959
-59cd59595959595959595959595959595959595901015959595959595408595959595959
-595959590559595959595959595959595959595959595959595905595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-5959595959595959595959595930fa050505050505050505050505050505061c59595959
-5959ae060e0e0d0000060e0e0eae59595959595959595959595959595959595959595959
-590359595959595959595959595959595959595959595959595959595959595959055959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959055959595959595959595959595959595959595959595959595959595959
-595959595959595959595959cd0459595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959cd59595959cd595959595959595959590459595959595959595959
-595905595959595959595959595959595905595959595959595959595959055959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-59595959595959595959595959595959595959cd59595959595959590000000159595959
-590459595959595959595959595959595959595959595959595959590559595959595959
-595959595905595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959303005050505050505050505050505
-05050606595959595959ae060e0e0d00001c0e0e0e4f5959595959595959595959595959
-595959595959595959c85959590559595959595959595959595959595959595959595959
-595959595959595959595959595959055959595959595905595959595959590559595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959cd59595959cd595959595959595959045959cd5959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-5959595959595959595959597f5959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959045959
-595959595959595959595959595959595959055959595959595959595959595905595959
-595959595959595959590559595959595959055959595959595959595959595959595959
-595959595959595959595959595959595959595959cd5959595959595959595959595959
-590000000000005959045959595959595959595959595959595905595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959545959595930300505050505
-05050505050505050505061c595959595959ae060e0e0d0000060e0e0eae595959595959
-595959595959595959595959595959595903595959595959595959055959595959595905
-595959595959595905595959595959595959595905595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595900000001000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000100010001000001000100010101000101010001000100
-000000000001010101010101010101010101010101010101010101010101010101010101
-010101010101010101010101010101010101010101010101010101010101010101010101
-010101010101010101010101010101010101010101010101010101010101010101010101
-010101010100000000000000000000000004595959595959595959595959595959595959
-595959590559595959595959595959595905595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-5930300505050505050505050505050505050606595959595959ae060e0e0d00001c0e0e
-0ed759595959595959595959595959595959595959595959590559595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595905595959595905595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-590459595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-59595959595959595959595959045c59f9595cf95cf95cf95cf95cf95cf95cf9590e0ef9
-5cf95cf95cf95cf959f1590e0ef95cf95cf95cf95cf959f1590e0ef95cf959f1590e0e5c
-f95cf95cf95cf95cf95cf95cf95cf95cf95cf95cf95cf95cf95cf959f959f9595c59f959
-5c595c595959595959595959595959595900000000000059590459595959595959595905
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959590559595959595959595959595959595959595959595959595959595959
-59595959595959595930fa050505050505050505050505050505061c595959595959ae06
-0e0e0d0000060e0e0eae5959595959595959595959595959595959595959595959035959
-595959595959595959595959595959595959590559595959595959595959590559595959
-595959595959055959595959595905595959595959595959595959595959595959055959
-5959595959595959595959595959595959595959595959cd595959595959595959595959
-595959595959595959045959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959045959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-59595959595959595959595959595959595959595959595959000000595959595904cd59
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595930300505050505050505058d05050505050606
-595959595959ae060e0e0d00001c0e590e4f595959595959595959595959595959595959
-5959595959c8595959595959595959595905595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595905595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595904595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595904595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595900005959
-595959595908595959595959595959595959595959590559595959595959595959595905
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595905595959595959595959595959595959595959593030050505050505050505
-050505050505061c595959595959ae060e0e0d0000060e2e0eae59595959595959595959
-595959595959595959595959590359595959595959595959595959595959595959595959
-595959595959055959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959590459595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-590459595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959540459595959595959595959595959055959595959595959
-595959055959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959303005
-05050505050505050505050505050606595959595959ae060e0e0d00001c0e0e0e4f5959
-595959595959595959595959595959595959595959c85959595959595959595959595959
-590559595959595959595959595959595959595959595959595959595959595905595959
-595959595905595959595905595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959cd5959595959595959045959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959045959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959045959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959545959595959595959
-545959595930fa050505050505050505050505050505061c595959595959ae060e0e0d00
-00060e0e0eef595959595959595959595959595959595959595959595903595959595959
-595959595959595959595959595959590559595959595959595959595959590559595959
-595959595959595959595959595959595959595959595959055959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595904595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595904595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595904595959595959
-595905595959595959595959590559595959595959595959595905595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959593030050505050505050505050505050505060659595959
-5959ae060e0e0d00001c0e0e0e4f59595959595959595959595959595959595959595959
-590559595959595905595959595959595959595959595959595959595959595959595959
-595959595959055959595959595959055959595959595959595959595959595959595959
-595959590559595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959590459595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959590459595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-540859595959595959595959595959595959595959595959595959595959595959595959
-595905595959595959595959595959595959595905595959595959595959595959595959
-595959595959595959595959595959595959595959303005050505050505050505050505
-0505061c595959595959ae060e0e0d0000060e0e0eae5959595959595959595959595959
-595959595959595959035959595959595959595959595959595959590559595959595959
-595959055959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959045959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959045959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-59595959595959592d045959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959055959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595930300505050505
-050505050505050505050606595959595959ae060e0e0d00001c0e0e0e4f595959595959
-5959595959595959595959595959595959c8595959595959595959595905595959595959
-595959595959595959595959590559595959595959595959595959595959595959595959
-595905595959595959595959595905595959595959595959595959595905595959595959
-595959595959595959595959595959595959595959595959595959595904595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595904595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959597f04595959595959595959595959595959595959
-595959595959595905595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595954595959
-5930fa050505050505050505050505050505061c595959595959ae060e0e0d0000060e0e
-0eae59595959595959595959595959595959595959595959590359595959595959595959
-595959595959595959595959595905595959595959595959595959595959595959595959
-595959595959590559595959595959055959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-590459595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959590459595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959590459595959595959595959
-595905595959595959055959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-59595959595959595930300505050505050505050505050505050606595959595959ae06
-0e0e0d00001c2e592e4f5959595959595959595959595959595959595959595959c85959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595905595959595959595959595959595959595959595959595959595959595959
-59595959595959595959595959cd59595959595959595959595959595959595959595959
-595959595959595959045959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959045959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595954085959
-055959595959595959595959595959595959595959595959595959595905595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-59595959595959595959595959595959593030050505050505050505050505050505061c
-595959595959ae060e0e0d0000060e0e0eae595959590559595959595959595959595959
-595959595903595959595959595959595959590559595959595959595959595959595959
-595959590559595959055959595959595959055959595959595959595959595959595959
-595959595959590559595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595904595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595904595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595904595959595959595959595959595959055959595959595959595959595959
-595959595959055959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959593030050505050505050505
-0505050505050606595959595959ae060e0e0d00001c0e0e0ed759595959595959595959
-595959595959595959595959590559595959595959055959595959595959595905595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595905595959595959595959595959595959595959595959595959595959595959
-595959cd5959595959595959595959595959595959595959590459595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-590459595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959590459595959595959055959595959595959595959595959
-590559595959595959595959595959595959595959595959595959595959595959595959
-59595905595959595959595959595959595959595459595959595959595959595930fa05
-0505050505050505050505050505061c595959595959ae060e0e0d0000060e0e0eae5959
-595959595959595959595959595959595959595959035959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959055959595959595959595959595959595959
-595959595959595959595959595959595959595959595959cd5959597f59595959045959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-59595959595959597f045959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959045959595959595959595959595959
-595959595959055959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595930300505050505050505050505050505050606595959595959ae060e0e0d00
-001c0e2e59d75959595959595959595959595959595959595959595959c8595959595959
-595959595959595959595959595959590559595959055959595959595959595959595959
-595959595959595959595959595959055959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-5959597f5904595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959545959595959595959
-595959595959595959595959595959595904595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595459595959595959595959595408595959595959
-595959595959595959595959595959595959595959590559595959595959595959595959
-595959595959595959595959055959595959595959595959595959595959055959595959
-595959595959595954595959593030050505050505050505050505050505061c59595959
-5959ae060e0e0d0000060e0e0eae59595959595959595959595959595959595959595959
-590359595959595959595959595959590559595959595959595959595959595959595959
-595905595959595905595959595959595959055959595959595959595959595959595959
-595959055959595959595959595959595959595959595959595959595959595959595959
-59595959595959595959595959047f595959595959595959595959595959595959595959
-595959595959595959595959595959045959595959595959595959590404595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595459595459595959595959595959595959595959595959590459595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-2d0459595959595959595959055959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-59595959595959595959595959595959595959595930300505050505050505058d050505
-05050606595959595959ae060e0e0d00001c592e59d75959595959595959595959595959
-595959595959595959c85959595959590559595959595959595959595959595959595959
-595959590559595959595959595959595959590559595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959045959595959595959595959595959
-595959595959595959595959595959595959595959597f04595959595959595959595959
-7f0459595959595959595959595959595959595959595959595959595959595959545959
-59545959595959595959595959595959595954595959595959595959595959597f045959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959045959595959595959595959590559595959595959595959595959
-595959595959590559595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595930fa0505050505
-05050505050505050505061c595959595959ae060e0e0d0000060e0e0eae595959595959
-595959595959595959595959595959595903595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959055959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959545959595904595959595959
-595959595959590404590459045904040459040459595904590404595959040404045959
-590404595959590404045959595959595959595959595959595959595959595959595459
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595904595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-545959595959595959595959595959595904595959595959595959595959595959595959
-595959595959055959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-5930300505050505050505050505050505050606595959595959ae060e0e0d00001c0e0e
-0ed759595959595959595959595959595959595959595959590559595959595959590559
-595959595959595905595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959590559595959055959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-7f0459595954595959595459597f04597f047f597f04597f597f597f0459597f04597f04
-59597f047f59597f04597f04595904597f04595959595959545959595459595954595959
-545959545959595959595959595959595959595959595959595959595959595959595959
-5959595959595959595959597f0459595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959540859595959595959595959
-595959595905595959595959595959595959595959595959590559595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-5959595959595959593030050505050505050505050505050505061c595959595959ae06
-0e0e0d0000060e0e0eae5959595959595959595959595959595959595959595959035959
-595959595959595959595959595959595959595959055959595959595959595959595959
-595959595959595959590559595959590559595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959045959595959595959595959590459590459595904595959590404
-0459595904595904595959045959595904040459597f0459590459595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959045959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-59595959595959595959595959595959595959595959595959595959595959592d045959
-595959595959595959595959595959595959595959595959595905595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595930300505050505050505050505050505050606
-595959595959ae060e0e0d00001c0e0e0e4f595959055959595959595959595959595959
-5959595959c8595959595959595959595905595959595959595959595959595959595959
-595905595959590559595959595959595959595959595959595959595959595959595959
-59595959595959595959595959595959595905595959cd59595959595959cd5959595959
-595959595959595959595959595959595904595959595959595959595959045959045959
-590459595904597f0459597f04595904595959045959045904597f045959045959045959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595904595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595904595959595959595959595959595959595959055959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-5959595959595959595959595959595959595959545959595930fa050505050505050505
-050505050505061c595959595959ae060e0e0d0000060e0e0eef59595959595959595959
-595959595959595959595959590359595959595959595959595959595959595959595959
-595959595959055959595959595959595959595959595959595959595959595959595959
-595959595959595959595905595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959590459595959595959595959
-595959040404595904040404595904045904590404047f0404597f590404597f59040459
-595959040459045959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-5904cd595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959590459595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959303005
-05050505050505050505050505050606595959595959ae060e0e0d00001c0e0e59d75959
-595959595959595959595959595959595959595959c85959595959595959595959595959
-055959595959595959595959595959595959595959595959595959590559595959595959
-595959595959595959595905595959595959595959055959595959595959595959595959
-595959595959595959595959595959cd5959595959595959595959595959595959045959
-5959595959595959595959597f0459597f597f595959597f595959595959595959595959
-5959595959595959595959597f59cd595959595959595959595959595959595959595959
-5959595959595959595959595959595959595959595959595959595959595959595959cd
-595959595959595959045959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595954085959055959595905595959595959
-595959595959595905595959595905595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-59595959593030050505050505050505050505050505061c595959595959ae060e0e0d00
-00060e0e0eae595959595959595905595959595959595959595959595903595959595959
-595959595959595959595959590559595959595959595959595959595959595959595959
-595959595959055959595959590559595959595959595959595959595959595959595959
-055959595959595959595959595959595959595959595959595959595959595959595959
-595959597f04595959595959595959595959040404595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-5959595959595959595959cd595959595904595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959592d04595959595959
-595959595959590559595959595959595959595959595959595959590559595959595959
-595959055959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959593030050505050505050505050505050505060659595959
-5959ae060e0e0d00001c0e0e0ed759595959595959595959595959595959595959595959
-590559595959595959595959595959595959595959595959055959595959595959595959
-595959595959595959595959595959595959595959595959595959595905595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-5959595959595959595959595904595959595959595959595959597f5959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959cd5959595959595959595959595959590459595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-5959595959cd595959595959595959595959595959595959595959595959595959595959
-590459595959595959595959595959595959595959595959595959595959595959595959
-595905595959595959595959595959595959595959595959595959590559595959595959
-59595959595959595959595959595959545959595930fa05050505050505050505050505
-0505061c595959595959ae060e0e0d0000060e0e0eae5959595959595959595959595959
-595959595959595959035959595959595959595959595959595959595959595959595959
-595959595905595959590559595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959045959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959045959
-5959595959cd595959cd5959595959cd59595959cd595959595959595959cd595959cd59
-5959cd595959cd5959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959045959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595930300505050505
-050505050505050505050606595959595959ae060e0e0d00001c0e0e0ed7595959595959
-5959595959595959595959595959595959c8595959595959595959055959595959595959
-595959595959595959595959595959595959595959595959055959595959590559595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595904595959595959
-590000595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595904cd595959595959595959595959595959595959595959595959595959cd59
-5959595959595959595959595959595959595959cd5959cd5959cd5959cd5959cd595959
-cd59595959595959595959595959595959595959595959cd595959595959595959595959
-595959595959595959595959595959595408595959595959590559595959595959595959
-055959595959595959590559595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959055959595959595959595959595959595959
-593030050505050505050505050505050505061c595959595959ae060e0e0d0000060e0e
-0eae59595959595959595959595959595959595959595959590359595959595959595959
-595959590559595959595959595959055959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-590459595959000000005959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959590459595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-5959595959595959595959cd59595959595959595959595959595959595959595959cd59
-59595959595959cd595959cd5959595959595959595959592d0459595959595959595959
-595959590559595959595959590559595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-59595959595959595930300505050505050505058d05050505050606595959595959ae06
-0e0e0d00001c0e0e0e4f5959595959595959595959595959595959595959595959c85959
-595959595959595959595959595959595959595959595959595959595959595959590559
-595959595959595959595959595959595959055959595959595905595959590559595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959597f59045959000000000000595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-59595959595959595959595959595959595959595959cd595959595959cd595959cd5959
-595959595959595959595959595959595959595959045959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-59595959595959595959cd59595959595959595959595959595959595959595959045959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595905595959595959595959595959595959595959595959595959
-595959595459595959595959595959595930fa050505050505050505050505050505061c
-595959595959ae060e0e0d0000060e0e0eef595959595959595959595959595959595959
-595959595903595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959590559595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595900000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000001010000000000
-010100000101000000000000010000000100000100000100000000010000010001010101
-010101010101000101010100010101010001000100010101010100010101000101010001
-010100010001000101010101010101010101010101010101010101010100010000010000
-010000000100000100010001000100000001010000000100010000010000000000000000
-000000000004cd5959595959595959590559595959595959595959595959595959595959
-595959595959055959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959593030050505050505050505
-0505050505050606595959595959ae060e0e0d00001c2e590e4f59595959595959595959
-595959595959595959595959590559595959590559595959595959595959595959055959
-595959595959595905595959595959595959595959590559595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-59595959595959cd5959595959595959cd59595959595959590459590000000000595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-590459595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959590459595959595959595959595959595959595959595959
-595959595959595905595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595459595959303005
-0505050505050505050505050505061c595959595959ae060e0e0d0000060e0e0eae5959
-595959595959595959595959595959595959595959c85959595959595959595905595959
-590559595959595959595905595959595959595959595959590559595959595959595959
-595959595959595959055959595959595959595959595959595959595959595959590559
-595959595959595959595959595959595959595959595959595959595959595959045959
-595900000000595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959045959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959045959595959595959595959595959
-595959055959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595930300505050505050505050505050505050606595959595959ae060e0e0d00
-001c0e0e0ed75959595959595959595959595959595959595959595959c8595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959590559595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595904595959595959590000595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595904595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595408595959595959
-595959595959595959595959595959595959055959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-5959595959595959595959595930fa050505050505050505050505050505061c59595959
-5959ae060e0e0d0000060e0e0ed759595959595959595959595959595959595959595959
-590359595959595959595959595959595959595959595959595959595959595959595959
-055959595959595959595959595959595959595959595959595959595905595959590559
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959590459595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959590459595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-590459595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959055959595959595959595959595959595959
-595959595959595959595959595959595959595959303005050505050505050505050505
-05050606595959595959ae060e0e0d00001c2e592e4f5959595959595905595959595959
-595959595959595959c85959595959595959595959595959595959595905595959595959
-595959595959595959595959595959595959595959595959595959055959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959045959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959045959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959045959595959595959595959055959595959590559595959595959
-055959595959055959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595930300505050505
-05050505050505050505061c595959595959ae060e0e0d0000060e0e0eae595959595959
-595959595959595959595959595959595903595959595959595959595959595959595959
-595959595959595905595959595959595959595959595959595959595959590559595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-59595959595959595959595959cd59595959595959595959595959595904595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595904595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595904595959595959590559595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-5930300505050505050505050505050505050606595959595959ae060e0e0d00001c0e0e
-0ed759595959595959595959595959595959595959595959590559595959595959595959
-590559595959595959595959595959595959055959595959595959595959055959595959
-595959595959595959595905595959595959595959595959595959595959595959595959
-59595959cd59595959595959595959595959595959595959595959595959595959595959
-590459595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959590459595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959540859595959595959595959
-595959595959595959595959595959595959595959595959590559595959595959595959
-595959595959595959595959595959590559595959595959595959595959595959595959
-59595959545959595930fa050505050505050505050505050505061c595959595959ae06
-0e0e0d0000060e0e0ed75959595959595959595959595959595959595959595959035959
-595959595905595959595959595959595959595905595959595959595959595959055959
-595959595959595959595959595959595959595959595959595959595905595959595959
-595959595959595959595959595959595959cd5959595959595959595959595959595959
-59cd59595959595959045959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959045959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-59595959595959595959595959595959595959595959595959595959595959592d045959
-595959595959595959595959055959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595930300505050505050505050505050505050606
-595959595959ae060e0e0d00001c2e592e4f595959595959595959595959595959595959
-5959595959c8595959595959595959595959595905595959595959595959595959595959
-595959595959595959595959590559595959595959595959595959595959590559595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595904595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595904595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959597f04595905595959595959595959595959595959595959055959595959055959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959593030050505050505050505
-050505050505061c595959595959ae060e0e0d0000060e0e0eae59595959595959595959
-595959595959595959595959590359595959595959595959595959595959595959595959
-595959595959595959055959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959590459595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-590459595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959590459595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595905595959595959595959595959595959595959595959303005
-05050505050505050505050505050606595959595959ae060e0e0d00001c0e0e0ed75959
-595959595959595959595959595959595959595959c85959595959595959595959595959
-595905595959595959595959595959595959595959595959595959595959595905595959
-595959055959595959595959595959595959055959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959045959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959045959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595954085959595959595959595959595959
-595959595959595959595959595959055959595959590559595959595959595959595959
-590559595959595959595959595959595959595959595959595959595959595959595959
-545959595930fa050505050505050505050505050505061c595959595959ae060e0e0d00
-00060e0e0ed7595959595959595959595959595959595959595959595903595959595959
-595959595959595959595959595959595959595959595959595959595959590559595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-545959595904595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595904595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595904595959595959
-595905595959595959055959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-5959595959595959595959595930300505050505050505058d0505050505060659595959
-5959ae060e0e0d00001c0e0e0ed759595959595959595905595959595959595959595959
-590559595959595959595959595959595959595905595959595959595959595959595959
-595959595959595959595959595959595959595959590559595959590559595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959590459595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-59595959595959595959595959595959595959595959597f590459595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-590459595959595959595959595959595959595905595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959303005050505050505050505050505
-0505061c595959595959ae060e0e0d0000060e0e0eae5959595959595959595959595959
-595959595959595959035959595959595905595959595959595959595959595959055959
-595959595959595959595959595959595959595959595905595959595959595959595959
-595959595959595959595959590559595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959045959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959045959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595954595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959045959595959595959595959595959595959595959595959055959
-595959595959055959595959595959595959595959595959595959595959595959595959
-595959595959595959595959590559595959595959595959595959595930300505050505
-050505050505050505050606595959595959ae060e0e0d00001c0e0e0e4f595959595959
-5959595959595959595959595959595959c8595959595959595959055959595959595959
-595959595959595905595959590559595959595959595905595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-5959595959cd595959595959595959595959595959595959595959595904595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959597f04595459595959595959595959595959595959595959595959595959595959
-595959595959595954595959595954595459595459545954595459595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595408595959595959595959055959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-5930fa050505050505050505050505050505061c595959595959ae060e0e0d0000060e0e
-0eef59595959595959595959595959595959595959595959590359595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595905595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-590459595959595959595959595959590a0a595959595959595959595959595959595959
-595959595959595959595959595959595959595959590a595959590a5959595959595959
-595959595959595959595959595959595459595959595959595959595959595959595959
-595959595959595959595959590459595954595459545959545954595954595959595459
-545959545959595459595954595959595959595959595959595959595959595959595959
-595954595959595959545959595959595959595959595959595959595959595959595959
-5959595959595959595459595959595959595959595959592d0459595959595959595959
-595959595959595959595959595959595959595959595959595905595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-59595959595959595930300505050505050505050505050505050606595959595959ae06
-0e0e0d00001c0e2e594f5959595959595959595959595959595959595959595959c85959
-595959595959595959595959595959595959595959595959595959595959595905595959
-595959595905595959595959055959595959590559595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959cd5959595959595959
-595959595959595959045959595959595959595959595959590a59595959595959595959
-59595959595959595959595959595959595959595959595959595959595959595959590a
-595959595959595959595959595459595959595959545959595959595959595959595959
-59595959595959595959595959595959595959597f045959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959545959595959595959595959545959595959595459595959
-59595459595959595959595959595959595959595959595959595959595959597f045959
-595959595959595959595959595959595959595959595959055959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-59595959595959595959595954595959593030050505050505050505050505050505061c
-595959595959ae060e0e0d0000060e592eef595959595959595959595959595959595959
-595959595903595959595959595959595959595959590559595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595905595959
-595959595959595959595959595959595905595959595959595959595959595959595959
-5959595959595959595959597f59595959047f5959595959595959595959590a0a0a5959
-590a0a595959595959595959590a0a595959590a0a59590a0a590a59590a0a590a595959
-590a0a5959590a0a0a0a5959595954595959595959595959595959595959595959595959
-595959595959595959595459595959595959545959545959595959595904595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959545959545959595959595959595959595959595959
-595959595904595959595959595959595959055959595905595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959593030050505050505050505
-0505050505050606595959595959ae060e0e0d00001c0e2e594f59595959595959595959
-595959595959595959595959590559595959595959595959055959595959595959055959
-595959595959595959595959595905595959595959595959595959595959595959595959
-595959595959595959595959595959595959055959595959595959595959595959595959
-59595959595959595959595959595959595959595959597f590459595959595959545959
-59590a59590a59590a59590a59595959545959590a59590a59590a59590a590a590a590a
-590a590a590a595959590a595959590a5959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-590459595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959540859590559595959595959595959595959595959595959
-595959595959590559595959595959595959595959595959595959590559595959595959
-05595959595959595959595959595959595959595959595959595959595959595930fa05
-0505050505050505050505050505061c595959595959ae060e0e0d0000060e0e0eef5959
-595959595959595959595959595959595959595959035959595959595959595959595959
-595959595959595959595905595959595959595959595959595959595959595959595959
-595959055959595959595959595959595959055959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959045959
-595959595959595959590a59590a59590a59590a59595959595959590a59595959590a59
-590a590a590a590a590a590a590a595959590a595959590a595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959045959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-59595959595959595959595959595959595959592d045959595959595959595959595959
-595959595959590559595959595959595959595959590559595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595930300505050505050505050505050505050606595959595959ae060e0e0d00
-001c0e2e59d75959595959595959595959595959595959595959595959c8595959595959
-595959595959595959595959595959595959595959590559595959595959595959595959
-595905595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959597f045954595959595959595959590a59590a59590a59590a5959595959595959
-0a59590a59590a59590a590a590a590a590a590a590a595959590a595959590a59590a59
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595904595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595904595959595959
-055959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959593030050505050505050505050505050505061c59595959
-5959ae060e0e0d0000060e0e0eae59595959595959595959595959595959595959595959
-590359595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595905595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-5959595959595959595959595904595959595959595959595959590a0a590a59590a0a59
-5959595959595959590a0a595959590a0a59590a590a590a0a0a590a590a0a590a0a0a0a
-0a5959590a0a595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959590459595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-59595959595959595959595959595959595959595959595959cd59595959595959595959
-590459595959595959595959595959595959590559595959595959595959595959590559
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959303005050505050505050505050505
-05050606595959595959ae060e0e0d00001c0e2e59d75959595959595959595959595959
-595959595959595959c85959595959595959595959590559595959595905595959595959
-595959595959595959595959055959595959595959055959595959595959595959595959
-055959595959595959595959595959595959595959595905595959595959595959595959
-595959595959595959595959595959595959595959045959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959045959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595954085959595959595959595959055959595959595959595959590559
-595959595959595959595905595959595959595959595959595959595959595959595959
-590559595959595959595959595959595959595959595959545959595930fa0505050505
-05050505050505050505061c595959595959ae060e0e0d0000060e592ed7595959595959
-595959595959595959595959595959595903595959595959595905595959595959595959
-595959595959595959595959595959595905595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-59595959595959595959595959cd59595959595959595959595959595904595959595959
-59595959595959595959595959595959590a0a0a0a0a0a59595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-59595959cd04595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959592d04595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-5930300505050505050505050505050505050606595959595959ae060e0e0d00001c0e2e
-59d759595959595959595959595959595959595959595959590559595959595959595959
-595959595959595959595959595959595959590559595959595959595959595959595959
-595959590559595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959cd5959595959595959595959
-590459595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959590459595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959590459595959595959595959
-595959595959595959595959595959590559595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-5959595959595959593030050505050505050505050505050505061c595959595959ae06
-0e0e0d0000060e0e0eae5959595959595959595959595959595959595959595959c85959
-595959595959595959595959590559595959595905595959595959595959595959595959
-595959055959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-59595959595959597f045959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959045959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959045959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595905595959
-595959595959595959595959595959595930300505050505050505058d05050505050606
-595959595959ae060e0e0d00001c0e2e59d7595959595959595905595959595959595959
-5959595959c8595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595905595959590559595959590559
-5959595959595959595959595959595959595959595959595959595959cd595959595959
-595959595959595959595959595959595904595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595904595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595408595959595959590559595959590559595959055959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-5959595959595959595959595959595959595959545959595930fa050505050505050505
-050505050505061c595959595959ae060e0e0d0000060e592ed759595959595959595959
-595959595959595959595959590359595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959590459595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-590459595959595959595959595959595959595959595959595959595959595959595959
-cd5959595959595959595959595959595959595959595959595959595959595959595959
-59595959595959595959595959595959595959595959595959595959cd5959cd59595959
-5959595959595959595959592d0459595959595959595959595959595959595959595959
-595959595959590559595959595905595959595959595959595959595959595959595959
-595959595959595959595959595959590559595959595959595959595959595959303005
-05050505050505050505050505050606595959595959ae060e0e0d00001c0e2e59d75959
-595959595959595959595959595959595959595959c85959595959595959590559595959
-595959595959595959590559595959590559595959595959595959595959055959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959045959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-59595959595959595959cd5959cd595959cd5959595959595959595959595959cd595959
-59595959595959597f045959595959595959595959595959595959595959595959595959
-5959cd59595959595959595959595959595959595959595959cd59595959595959cd5959
-595959595959cd595959cd59595959595959cd595959595959595959595959cd59595959
-59595959595959595959595959595959595959597f045959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-59595959593030050505050505050505050505050505061c595959595959ae060e0e0d00
-00060e0e0eae595959595959595959595959595959595959595959595903595959595959
-595959595959595959590559595959595959595959595959595959595905595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-59595959cd04595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-5959595959cd595959cd595959cd595959595959595959595959595959cd595959cd5959
-5959595959595959595959595959595959047f5959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-cd5959595959595959cd595959595959595959595959cd59595959595959cd5959595959
-5959595959595959595959595959595959cd595959595959595959595904595959595959
-595959595959595959595959595959055959595959595959595959595959595959055959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959593030050505050505050505050505050505060659595959
-5959ae060e0e0d00001c0e2e59d759595959595959595959595959595959595959595959
-590559595959595959595959595959595959595959595959595959595959595959595959
-595959590559595959595959590559595959595959595959595959055959595959595959
-595959595959595959595959595959055959595959595959595959595959595959595959
-595959595959595959595959590459595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-5959595959595959cd595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959590459595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-540859590559595959595905595959595959595959595959590559595959595959055959
-595959595959595959595959595959595959595959595959595959595959595959595959
-59595959595959595959595959595959595959595930fa05050505050505050505050505
-0505061c595959595959ae060e0e0d0000060e0e0ed75959595959595959595959595959
-595959595959595959035959595959595959595959590559595959595959595959595959
-595959595959595959595959595959595959595959595959595905595959590559595959
-595959590559595959595959595959595959595959595959595959595959595959595959
-59595959595959595959cd59595959595959595959045959595959595459595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-59595959595959595959595959595959cd595959595959cd595959595959595959045959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959045959595959595959595959595959055959595959595959595959
-595959595959595959595959595959595959595959055959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595930300505050505
-050505050505050505050606595959595959ae060e0e0d00001c0e2e59d7595959595959
-5959595959595959595959595959595959c8595959595959595959595959595959595959
-595905595959590559595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595904595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595459595959595959595959595959595959595959595959
-59595959595959595959595959595959595959595959595959595959595959595959cd59
-595959597f04595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595904595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959590559
-595959595959595959595959595959595959595959595959595959595959595954595959
-593030050505050505050505050505050505061c595959595959ae060e0e0d0000060e0e
-0eef59595959595959595959595959595959595959595959590359595959595959595959
-595959595959590559595959595959595959595905595959595959595959590559595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-5959595959595959595959595959595959595959595959595959595959cd595959595959
-590459595959595959595459595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959590459595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959590459595959595959595959
-595959595959595959595959595959590559595959595959055959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-59595959595959595930300505050505050505050505050505050606595959595959ae06
-0e0e0d00001c0e2e594f5959595959595959590559595959595959595959595959c85959
-595959590559595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-055959595959595959595959595959595959595959cd5959595959595959595959595959
-595959595959597f59045959595959595959595959595959545959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959045959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595954085959
-595959595959595959595959590559595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595930fa050505050505050505050505050505061c
-595959595959ae060e0e0d0000060e592eef595959595959595959595959595959595959
-595959595903595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959590559595959595959595959595959055959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595904595959595959595959545959595959595959
-595959595959595959595959595959595959595959595959595959595959595954595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595904cd59595959cd
-595959595959cd595959595959595959595959595959595959595959595959595959cd59
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959592d04595959595959595959055959595959595959595959595959595959595959
-595959595959595905595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959593030050505050505050505
-0505050505050606595959595959ae060e0e0d00001c2e590e4f59595959595959595959
-595959595959595959595959590559595959595959595905595959595959595959595959
-595959595959595959595959590559595959595959595959595959055959595905595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-5959595959595959595959595959595959595959595959597f0459595959595959595959
-595459595959595459595959595959595959595459595959595459595959595959595959
-545959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-590459595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959590459595959595959595959595959595959595959590559
-595959595959055959595959595959595959595959595959595959595959595959595959
-055959595959595959595959595959595959595959595959595959595959595959303005
-0505050505050505050505050505061c595959595959ae060e0e0d0000060e2e0eae5959
-595959595959595959595959595959595959595959035959595959595959595959595959
-055959595959590559595959055959595959055959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959045959
-595959595959595959595959595959595959545959545959545959595959545959595959
-545959545959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-5959595959595959590459595959595959595959595959595959cd595959595959595959
-5959595959595959cd595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959045959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595930300505050505050505058d05050505050606595959595959ae060e0e0d00
-001c0e2e59d75959595959595959595959595959595959595959595959c8595959595959
-595959595959595959595959595959595959595959595959595959595959595959590559
-595959595959595959595959595959595959595959590559595959595959595959595959
-59595959595959595959595959595959595959595959cd59595959595959595959595959
-595959597f04595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595459595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595904595959595959595959595959595959595959
-595959cd5959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-59595959595959595959595959595959cd59595959595959595959595408595959595959
-595959595959595959595959595959595959595959595959595905595959595959595959
-595959595959595959595959595959595959595959595959595959595959055959595959
-5959595959595959545959595930fa050505050505050505050505050505061c59595959
-5959ae060e0e0d0000060e0e2ed759595959595959595959595959595959595959595959
-590359595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959590559595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959590459595959595959595959595959595959595959595959
-595959595959595959595959595459595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959590459595959595959cd5959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-2d0459595959595959595959055959595905595959595959590559595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959303005050505050505050505050505
-05050606595959595959ae060e0e0d00001c0e0e59d75959595959595959595959595959
-595959595959595959c85959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959590559595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959045959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-5959595959595959595959595959595959595959595959595959595959595959cd045959
-595959595959595959595959595959595959595959595959595959595959595959595959
-5959595959cd595959595959595959595959595959595959595959595959595959595959
-59595959cd5959595959cd5959595959595959595959cd59595959595959595959595959
-59595959595959597f045959055959595959595959595959595959595959595959595959
-595959595959595959055959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595930300505050505
-05050505050505050505061c595959595959ae060e0e0d0000060e0e2ed7595959595959
-595959595959595959595959595959595903595959595959595905595959595959595905
-595959595959595959055959595959595959055959595959590559595959055959595905
-595959595959595959595959595959595959595959595959595959595959595905595959
-595959595959595959595959595959595959595959595959595959595904595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-59595959595959595959595959595959595959595959595959595959595959595959cd59
-5959595959cd595959595959595959595959595959595959595959595959595959595959
-59595959590459cd59595959595959595959595959595959595959595959595959595959
-5959595959595959595959595959595959595959595959595959595959cd595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595904595959595959595959595959595959595959
-595959595959595959055959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-5930300505050505050505050505050505050606595959595959ae060e0e0d00001c0e0e
-59d759595959595959595959595959595959595959595959590559595959595959595959
-595959595959595959595905595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-7f0459595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959cd5959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959cd5959595959590459595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-59595959cd59595959595959595959595959595959595959540859595959595959595959
-595959595959590559595959595959595959595959595959595959055959595959595959
-595959595959595959595959595959595959595959595959595959595959595954595959
-59595959595959595930fa050505050505050505050505050505061c595959595959ae06
-0e0e0d0000060e0e2ed75959595959595959595959595959595959595959595959035959
-595959595959595959590559595959595959595959595959595959595905595959595959
-595959595959595959595959595959595959595959590559595959055959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959045959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959545959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959045959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959045959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959590559595959595959595959595959
-595959595959595959595959595959595930300505050505050505050505050505050606
-595959595959ae060e0e0d00001c0e0e59d7595959595959595959595959595959595959
-5959595959c8595959595959595959595959595959595959595959595959595959595959
-595959595959590559595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959cd5959595959595959595959597f04595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-59595959595959595959595959595959cd59595959595959595959595904595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595904595959595959055959595905595959595959595905595959595959595905
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595954595959593030050505050505050505
-050505050505061c595959595959ae060e0e0d0000060e0e0eae59595959595959595959
-595959595959595959595959590359595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595905595959590559595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959590459595959595959595959
-595959595959595959595959595959040459595959595959595959595959595959595959
-5959595959595959595959595959cd045959595959590459595959590404595959595959
-595959595959595959595959595959595959cd5959595959595959595959595959595959
-590459595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959590459595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959303005
-05050505050505050505050505050606595959595959ae060e0e0d00001c0e2e59d75959
-595959595959595959595959595959595959595959c85959595959590559595959595959
-595959595959595959595905595959595959595959595959595959590559595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-59595959595959595959595959595959595959595959595959595959595959597f045959
-595959595959595959595959595959595959595959595959045959595959595959595959
-595959595959595959595959595959595959595959595904595959595959595959595959
-590459595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959045959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-5959595959595959cd595959595959595959595954085959595959595959595959595959
-595959595959595905595959595959595959595959595959055959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595930fa050505050505050505050505050505061c595959595959ae060e0e0d00
-00060e0e0ed7595959595959595959595959595959595959595959595903595959595959
-595959595959590559595959590559595959595959595959595959595959595959595959
-595959595959595959595959595959595959055959595959595959595959595959595959
-5959595959595959595959595959595959595959595959595959595959cd595959595959
-595959595904595959595959595959595959045904040459590404595959595904595959
-59040459595904045959595959040404cd59590404595959595959595959040404045959
-59040459595959040404cd59595959595959595959595959595959595959595959595959
-595959595959595959595959595959595904595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959592d04595959595959
-595959595959595905595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959590559595959595959
-595959595959595959595959593030050505050505050505050505050505060659595959
-5959ae060e0e0d00001c0e2e59d759595959595959595959595959595959595959595959
-590559595959595959595959595959595959595959595959595959595959595959055959
-595959595959595959595959595959595959595905595959595959595959595959595959
-595959595959595959595959595959595959595959595959cd5959595959595959595959
-5959595959595959595959597f04595959595959595959595959590459cd59590459cd04
-5959597f0459595904595904595959cd04595959047f595959cd04595904595959595959
-5959cd045959595959cd045959cd04595904595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959590459595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-7f0459595959595959595959595959595959595959595959595959595959595959590559
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959303005050505050505050505050505
-0505061c595959595959ae060e0e0d0000060e0e0eef5959595959055959595959595959
-595959595959595959c85959595959595959590559595959595959595959595959595959
-595905595959595959590559595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959047f59595959595959595959595904
-595959590404045959595959045959cd0404047f59590404045959595904045959590404
-045959cd5959595959595904595959595959045959590459590459595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959045959
-59cd595959595959595959595959595959cd595959cd5959cd5959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959045959595959595959055959595959595959595959595959595905
-595959595959595959595959595959595959595959590559595959595959595959595959
-595959595959595959595959595959595959595959595959595959595930300505050505
-050505050505050505050606595959595959ae060e0e0d00001c0e2e594f595959595959
-5959590559595959595959595959595959c8595959595959595959595959595959595959
-595959055959595959595959595959595959595959595959590559595959055959595959
-595959595959595905595959595959595959595959055959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595904595959595959
-595959595959590459595959045959045959595904595959045959045904597f04595959
-595959045959047f59045959595959595959590459590459595904595959045959045959
-595959595959595959595959595959595959595959595959595959595959595959595959
-59595959cd04595959595959595959cd5959cd5959cd59595959595959595959595959cd
-5959cd595959cd595959595959cd595959cd5959595959595959595959595959cd595959
-5959595959595959595959595959595959595959cd595959595959595959595959595959
-595959595959595959595959595959595408595959595959595959595959595959590559
-595959595959595959055959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595954595959
-5930fa050505050505050505050505050505061c595959595959ae060e0e0d0000060e0e
-0eef59595959595959595959595959595959595959595959590359595959595959595959
-595959590559595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-590459595959595459595959595904040404595959040459595904040404045959040459
-5959040459047f5904040459595959040459595959595959595959590404cd5904040404
-04595904045904cd59595959cd5959595959595959595959595959595959595959595959
-595959595959595959595959590459595959595959595959595959595959595959595959
-59595959595959595959595959595959595959595959595959595959cd5959595959cd59
-59595959595959cd5959cd5959595959595959cd5959595959cd59595959595959595959
-595959595959595959595959595959595959595959595959590459595959595959595959
-595959595959595959595959595959595959595959595959055959595905595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-59595959595959595930300505050505050505058d05050505050606595959595959ae06
-0e0e0d00001c0e2e59d75959595959595959595959595959595959595959595959c85959
-595959595959595959595959595959595959595959595959595959595959595959595905
-595959595959595959595959595959595959055959595959595959595959595959595959
-595959595959595959590559595959595959595959595959595959595959595959cd5959
-595959595959595959045959595959595959cd595959597f595959595959cd5959595959
-7f5959595959597f59595959595959595959595959595959595959595959595959595959
-59595959595959595959595959595959595959595959595959cd59595959595959595959
-595959595959595959595959595959595959595959045959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-5959cd595959595959595959595959595959595959cd59595959595959595959cd045959
-595959595959595959595959595959595905595959595959595959595959595959595959
-595959595959595959595959595959595959595905595959595959595959595959595959
-59595959545959595959595959595959593030050505050505050505050505050505061c
-595959595959ae060e0e0d0000060e592ed7595959595959595959595959595959595959
-595959595903595959595959595959595959595959595959595959595959595959595959
-595959055959595959595959595959595959595959590559595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595904cd5959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595904
-0404040404595959595959595959595959cd595959595959595959595959595959595959
-cd5959595959595959595959595959595959595959595959595959595904595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595904595959595959595959055959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959593030050505050505050505
-0505050505050606595959595959ae060e0e0d00001c0e0e0ed759595959595959595959
-595959595959595959595959590559595959595959590559595959595959590559595959
-590559595959595959595959595959595959055959595959595959595959595959595959
-595959595905595959595959595959595959595959595959595959595959595959595959
-5959cd5959595959595959595959cd595959595959595959590459595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-59595959595959595959595959cd595959595959cd595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-590459595959595959595959595959595959595959595959595959595959595959595959
-5959595959595959595959595959595959595959595959595959595959595959595959cd
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959540859590559595959595959595959595959595959595959
-595959595959055959595959595959595959595959595959595959595959595959595959
-59595959595959595959595959595905595959595959595959595959595959595930fa05
-0505050505050505050505050505061c595959595959ae060e0e0d0000060e0e0ed75959
-595959595959595959595959595959595959595959035959595959595959595959595959
-595959595959595959595959595905595959595959595959595959595959595905595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959045959
-59595959595959595959595959597f595959595959595959595959595959595959595959
-59595959595959595959cd59595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-59595959cd59595959045959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959045959595959595959595959595959
-595959595959595959595959595959595959595959595959595905595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595930300505050505050505050505050505050606595959595959ae060e0e0d00
-001c0e0e0ed75959595959595959595959595959595959595959595959c8595959595959
-595959595905595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959590559595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-5959595959045959595959595959595959595959595959595959597f5959595959595959
-5959597f5959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-59595959595959595959595959595959cd04595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-5959cd595959595959595959595959595959595900005959595959595904595959595959
-595959595959590559595959595959590559595959595959595959590559595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595954595959593030050505050505050505050505050505061c59595959
-5959ae060e0e0d0000060e0e0ed759595959595959595959595959595959595959595959
-590359595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959590459595959595959595959595959595959595959595959
-5959595959597f59595959595959595959595959595959595959595959595959cd595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-59595959595959595959595959595959cd59595959595959590459595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959590000000059595959
-590459595959595959595905595959595959595905595959595959595959595959055959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959303005050505050505050505050505
-05050606595959595959ae060e0e0d00001c0e0e0ed75959595959595959595959595959
-595959595959595959c85959595959595959595959595959595959595905595959595959
-595959595959595959595959595905595959595905595959595959595959595959055959
-595959595959595959595959055959595959595959595959595959595959595959595959
-595959595959595959595959cd59595959595959590459595959595959595959cd595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959045959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-590000000000005954085959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595930fa0505050505
-05050505050505050505061c595959595959ae060e0e0d0000060e0e0ed7595959595959
-595959595959595959595959595959595903595959595959595959595959595905595959
-595959595959055959595959055959595959590559595959595959595959595959595959
-595959595959595959590559595959595959595959595959595959595959595959595959
-59595959595959595959595959595959595959595959595959cd59595901000001000001
-000000010100000000000000000000000000000000000000000000000000000000000000
-000100010101010101010101010101010101010101010101010101010001010101010101
-010101010101010101010101010101010101010101010101010101010001010101010101
-010101010101010101010101010101010101010101010101010101010101010101010101
-010101010101010101010101010101010101010101010101010101010101010101010101
-010101010101010101010101010101010101010101010101010101010100010001000100
-000100000000000000000000000000000004595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595905595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-5930300505050505050505050505050505050606595959595959ae060e0e0d00001c2e59
-0ed759595959595959595959595959595959595959595959590559595959595905595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959055959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-590459595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959590459595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595900000000000059590459595959595959595959
-595959595959595959595959595959055959595959595959590559595959595959595959
-595959595959595959595959055959595959595959595959595959595959595959595959
-5959595959595959593030050505050505050505050505050505061c595959595959ae06
-0e0e0d0000060e0e0eae5959595959595959595959595959595959595959595959035959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959590559595959595959595959595959595959595959
-595959595959595959595959055959595959595959595959595959595959595959595959
-595959595959595959045959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959045959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-59595959595959595959595959595959595959595959595959000000595959595904cd59
-595959595959595959590559595959595959590559595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595930300505050505050505050505050505050606
-595959595959ae060e0e0d00001c0e2e59d7595959595959595959055959595959595959
-5959595959c8595959595959595905595959595959595959595959595959595959595959
-590559595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595904595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595904595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595900005959
-59595959b308595959595959595959595959595959595959595959595959595959595959
-595959595959595905595959595959595959595959595959595959595959595959595959
-5959595959595959595959595959595959595959545959595930fa050505050505050505
-050505050505061c595959595959ae060e0e0d0000060e0e0ed759595959595959595959
-595959595959595959595959590359595959595959595959595959595905595959590559
-595959595905595959595959595959595959590559595959595959595959595959595959
-055959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959590459595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-590459595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-5959595959595959595959592d0459595959595959595959595959595959055959595959
-595959595959055959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959303005
-05050505050505050505050505050606595959595959ae060e0e0d00001c0e0e0ed75959
-595959595959595959595959595959595959595959c85959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595905595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959045959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959045959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959045959595959595905595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595905595959595459595959595959
-59595959593030050505050505050505050505050505061c595959595959ae060e0e0d00
-00060e0e0ed7595959595959595959595959595959595959595959595903595959595959
-595959595905595959595959595959595959595959595959595959595905595959595959
-595959595959055959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959cd5959595959595959595959595959
-5959597f5904595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595904595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595904595959595959
-595959595959595959595959595959595959595959595959595959055959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-5959595959595959595959595930300505050505050505058d0505050505060659595959
-5959ae060e0e0d00001c0e2e59d759595959595959595959595959595959595959595959
-590559595959595959595959595959595959595959595905595959595959595959595959
-595959595959595959595959595959595959590559595959595959590559595959595959
-595959590559595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959590459595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959590459595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-540859595959595959595959055959595959595959595959055959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-59595959595959595959595959595959545959595930fa05050505050505050505050505
-0505061c595959595959ae060e0e0d0000060e0e0ed75959595959595959595959595959
-595959595959595959035959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595905595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959045959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959045959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-59595959595959592d045959595959595959595959595959595959055959595959595959
-595905595959595959595959055959595959595959595959595959595959595959590559
-595959595959595959595959595959595959595959595959595959595930300505050505
-050505050505050505050606595959595959ae060e0e0d00001c0e2e59d7595959595959
-5959595959595959595959595959595959c8595959595959595959595959055959595959
-595959595959595959595905595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595904595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595904595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959597f04595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-593030050505050505050505050505050505061c595959595959ae060e0e0d0000060e0e
-0eef59595959595959595959595959595959595959595959590359595959595959595959
-595959595959595959595959595905595959595959595959595905595959595959595959
-595959055959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-590459595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959590459595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959590459595959595959595959
-595959055959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-59595959595959595930300505050505050505050505050505050606595959595959ae06
-0e0e0d00001c0e2e594f5959595959595959595959595959595959595959595959c85959
-595959055959595959595959595905595959595959595959595959595959595959595959
-595959595905595959595959595959595959595959595959055959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959045959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959045959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595954085959
-055959595959595959595959595959595959595905595959595959595959055959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595930fa050505050505050505050505050505061c
-595959595959ae060e0e0d0000060e0e0eef595959595959595959595959595959595959
-595959595903595959595959595959595959595959595959595959595959595959595959
-595905595959595959590559595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595905595959595959595959595959595959
-595959595959595959595959595959595904595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959597f04595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959592d04595959595959595959595959595959595959595959595959595959595959
-595959595959595959055959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959593030050505050505050505
-0505050505050606595959595959ae060e0e0d00001c0e2e594f59595959595959595959
-595959595959595959595959590559595959595959595959595959595959595905595959
-595959595959595959595959595959595959595959595959595959595959595905595959
-595959595959595959595959595959590559595959595959595959595959595959595959
-595959595959595959cd5959595959595959595959595959590459595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-590459595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959590459595959595959055959595959595959595959595959
-595959055959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595459595959303005
-0505050505050505050505050505061c595959595959ae060e0e0d0000060e0e0eef5959
-595959595959595959595959595959595959595959035959595959595959595959055959
-595959595959595959595959590559595959595959595959595959595959595959595959
-590559595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959597f59045959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595459
-595959595959595959045959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959545959595959595959595959595959
-595959595959595959595959595959595959595959045959595959595959595959595959
-590559595959595959595959595959595959595959055959595959595959595959055959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595930300505050505050505050505050505050606595959595959ae060e0e0d00
-001c0e0e0e4f5959595959595959595959595959595959595959595959c8595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959055959595959595959595959055959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959597f04595959595959595959595959595959595959595959595959595959595959
-595959595959595959595954595459545959595459595459545959545959545959595959
-545959545959545954595459595954595954595459545954595459545954595954595959
-595959595959595959595959595959597f04595459595954595959545959595459595954
-595959545959595459545954595459595459595459595954595459595459545959595459
-595954595959595954595954595459595459595954595959595459595959595959595959
-595959595959595959595959595959595959595959595959595959595408595959595959
-595959595959595959595959595959595959595959055959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-5959595959595959595959595930fa050505050505050505050505050505061c59595959
-5959ae060e0e0d0000060e0e0eef59595959595959595959595959595959595959595959
-590359595959595959595959595959595959595959595905595959595959595959595959
-055959595959595959595959595959595959595959595959595959590559595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959590459595959595959595959595959590404595959595959
-595959040459595959595959595959045959595959595959595959595959595959045959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959045959595959590459595959595459595959595959590459595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959545959595954595959595959595959595959595959595959595959595959595959
-2d0459595959595959595959055959595959595959055959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959055959595959
-595959595959595959595959595959595959595959303005050505050505050505050505
-05050606595959595959ae060e0e0d00001c0e0e594f5959595959595959595959595959
-595959595959595959c85959595959055959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959cd5959595959595959045959595959595959595959595959
-7f045959595959595959597f045959595959595959595904595959595959595959595959
-595959595904595959595959595959595959595959595959595959595959595959595959
-595959595959595959595904595959595959595959595959595959595959595959045959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959045959595959595959595959595959595959595959595959595959
-595959055959595959595905595959595959595959595959595959595959595959595959
-595959595959595959595905595959595959595959595959595959595930300505050505
-05050505050505050505061c595959595959ae060e0e0d0000060e0e2eef595959595905
-595959595959595959595959595959595903595959595959595959595959055959595959
-595959595959595959595905595959595959595959055959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959597f04595959595959
-595959595959590404045959590404595959595904595959590404595959040404045959
-590404595959595959595959040404045959045904040459040459595904590404595959
-5904040459590404595959595904045959590404040459595904045959595904047f5904
-7f0404595904595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959545959
-595954595959595959595959595959595904595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-5930300505050505050505058d05050505050606595959595959ae060e0e0d00001c0e0e
-594f59595959595959595905595959595959595959595959590559595959595959595959
-595959595905595959595959590559595959595959595959595959595959595959595959
-055959595959595959595959595959595959595959595959595959590559595959595959
-59595959cd59595959595959595959595959595959595959595959595959595959595959
-590459595959595959595959595904597f04595904597f04595959590459595904597f04
-59597f045959595904595904595959595959595959045959595959045959595959590459
-59590459590459590459595959595959045959590459590459597f047f595959597f0459
-595904595904595904597f04590459595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959545959595959595959595959540859595959595959595959
-595959055959595959595959595959595959595959595959595959595959595959595959
-595959595959055959595959595959595959595959595959595959595959595959595959
-59595959545959595930fa050505050505050505050505050505061c595959595959ae06
-0e0e0d0000060e0e2eef5959595959595959595959595959595959595959595959035959
-595959595959595959595959595959595959595959595959595959595959595959055959
-595959595905595959595959590559595959055959595959590559595959595959595959
-5959595959595959595959595959595959595959595959595959595959cd595959595959
-5959595959595959590459595959595959595959595904595904597f040404595959597f
-04595959040404595959590459595959040404595959595959595959590459595959cd04
-595959590404045959590459590459595904045959590404045959590459595959595904
-5959595959590459595904597f045959045959047f045959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-59595959595959595959595959595954595959595959595959595959595959592d045959
-595959595959595959595959595959595959055959595959595959595959055959595959
-595905595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595930300505050505050505050505050505050606
-595959595959ae060e0e0d00001c0e2e594f595959595959595959595959595959595959
-5959595959c8595959595959055959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595904595959595959595959595959045959045959
-04595904595959590459595904597f0459597f0459590459047f59045959595959595959
-590459590459590459595904597f0459595904595904595959597f045904595904595959
-045959045959590459590459595904595959045959045959045959045904595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959597f04595905595959055959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959593030050505050505050505
-050505050505061c595959595959ae060e0e0d0000060e592eef59595959595959595959
-595959595959595959595959590359595959595959595959595959595959595905595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959055959595959
-5959595959595959595959595959595959595959595959597f0459595959595959595959
-597f59040459047f59040459595904040404047f5904045959595959040459595904047f
-5959595959595959cd590404595904040404595904045904590404047f04045904040459
-7f5904045904597f59040459595959590404595904040404045959040459590404045904
-040459595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959590459595959595959595959595959595959055959595959
-595905595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959303005
-05050505050505050505050505050606595959595959ae060e0e0d00001c0e2e59d75959
-595959595959595959595959595959595959595959c85959595959595959595959595959
-595959595959595959590559595959055959595959595959595959595959595959595959
-595959595959590559595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959045959
-5959595959595959595959597f59595959597f59595959597f5959595959595959595959
-597f59595959595959595959595959595959595959595959597f595959595959597f5959
-595959597f5959595959597f5959595959597f595959595959cd59597f597f597f595959
-7f595959597f59597f045959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595954085959595959595959595959595959
-595959595959595959595959055959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595459595959595959
-595959595930fa050505050505050505050505050505061c595959595959ae060e0e0d00
-00060e0e0ed7595959595959595959595959595959595959595959595903595959595959
-595959055959595959595959595959595959595959595959595959595959590559595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595904595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595904040404040459595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595904595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959592d04595959595959
-595959055959595959595959595959595959595959595959595959590559595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959593030050505050505050505050505050505060659595959
-5959ae060e0e0d00001c0e0e0ed759595959595959595959595959595959595959595959
-590559595959595959595959595905595959595959595959595959595959595959595959
-595959595959595959595959055959595905595959595959595959595959595959595959
-595959590559595959595959595959595959595959595959595959595959595959595959
-59595959cd59595959595959590459595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959597f59595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959590459595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-590459595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595459595959303005050505050505050505050505
-0505061c595959595959ae060e0e0d0000060e0e0ed75959595959595959595959595959
-595959595959595959035959595959595959595959595959595959595905595959595959
-595959595959055959595959595959590559595959595959595959595959595959590559
-595959595959595959595959595959595959595959595959595959595959595959595959
-5959595959595959595959595959595959595959cd045959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959045959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959045959595959595959595959595959595959590559595959595959
-595959055959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595930300505050505
-050505050505050505050606595959595959ae060e0e0d00001c0e0e0ed7595959595959
-5959595959595959595959595959595959c8595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-cd5959595959595959595959595959595959595959595959595959595904595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595900005959
-595959597f04595959595959595959595959595959595959595959595959595959595959
-5959595959595959595959595959595959595959595959cd595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595904595959595959595959595959055959595959
-595959595959595959595959595959595959595905595959595959595959595959590559
-595959595959595959595959595959595959595959595959595959595959595959595959
-5930fa050505050505050505050505050505061c595959595959ae060e0e0d0000060e0e
-0ed759595959595959595959595959595959595959595959590359595959595959595959
-595959595905595959595959590559595959595959595959595959590559595959595959
-595959595959595959055959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-590459595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959590000000059595959590459cd5959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-5959595959595959595959595959cd595959595959595959595959595959595959595959
-5959595959595959595959595959595959595959595959595904cd595959595959595959
-595959595959595959595959595959595959595959595959055959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-59595959595959595930300505050505050505050505050505050606595959595959ae06
-0e0e0d00001c0e0e0ed75959595959595959595905595959595959595959595959c85959
-595959595959595959595959595959595959595959595959055959595959595959595959
-595959595959590559595959595959595959595959595905595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-5959595959595959590459cd595959595959595959595959595959595959595959595959
-5959595959595959595959595959595959595959597f5959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959590000000000005959045959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959cd595959cd59595959
-59cd59595959595959595959595959595959595959595959595959595959595959085959
-595959055959595959595959595959595959595959055959595959595959595959595959
-595959595959595959595959595959595959595959595959590559595959595959595959
-59595959595959595959595959595959593030050505050505050505050505050505061c
-595959595959ae060e0e0d0000060e0e0ed7595959595959595959595959595959595959
-595959595903595959595959595959595905595959595959595959595959595959595959
-595959055959595959595959595959595959595905595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595900000100000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000004595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959cd595959595959cd59595959595959595959595959595959595959595959
-595959cd5904595959595959595959595959595959595959590559595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959590559595959595959595959595959595959595959593030050505050505050505
-0505050505050606595959595959ae060e0e0d00001c0e2e59d759595959595959595959
-595959595959595959595959590559595959590559595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959cd59595959595959595959cd595959595959590459595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595900000000000059
-590459595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-5959595959595959595959595959595959595959595959595959595959595959cd595959
-595959595959595959595959590459595959595959590559595959055959595959595959
-595959595959055959595959595959595905595959595959595959595959595959595959
-59595959595959595959595959595959595959595959595959595959545959595930fa05
-0505050505050505050505050505061c595959595959ae060e0e0d0000060e0e0eae5959
-595959595959595959595959595959595959595959035959595959595959595959595959
-595959590559595959595959595959055959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595905595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959045959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-590000005959595959045959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-59595959595959595959595959595959595959595959595959595959595959595959cd59
-5959595959595959cd59595959595959595959595904cd59595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959545959595959
-595959595930300505050505050505058d05050505050606595959595959ae060e0e0d00
-001c0e2e59d75959595959595959595959595959595959595959595959c8595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959590559595959590559595959595959595959595959595959
-59595959595959595959595959cd59595959595959595959595959595959595959595959
-595959595904595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595900005959595959595904595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959592d08595959595959
-595959595959595959595959595959590559595959595959590559595959595959595959
-595959595959595959590559595959595959595959595959595959595959595959595959
-595959595959595959595959593030050505050505050505050505050505061c59595959
-5959ae060e0e0d0000060e592ed759595959595959595959595959595959595959595959
-590359595959595959595959595959595959595959595959595905595959595959595959
-590559595959055959595905595959595959055959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959590459595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-59595959595959595959595959595959595959595959595959047f595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-540459595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959303005050505050505050505050505
-05050606595959595959ae060e0e0d00001c0e2e59d75959595959595959595959595959
-595959595959595959c85959595959595905595959595905595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959045959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959045959
-5959cd595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959045959595959595959595959595959055959595959595959595959
-595959595959595905595959590559595959595959595959595959595959595959595959
-595959595959595959595905595959595959595959595959595959595930fa0505050505
-05050505050505050505061c595959595959ae060e0e0d0000060e0e0ed7595959595959
-595959595959595959595959595959595903595959595959595959595959595959595959
-055959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595904595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595904595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-59595959595959cd59595959595959595904595959595959595959055959595959595959
-595959595959590559595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-5930300505050505050505050505050505050606595959595959ae060e0e0d00001c0e0e
-0ed759595959595959595959595959595959595959595959590559595959595959595959
-595959595959595959595959595959595959595905595959595959595959595959595959
-055959595959595959055959595959055959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-590459595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959590459595959595959cd5959cd5959595959595959595959
-595959595959cd59595959595959595959cd595959cd5959595959595959595959595959
-5959cd595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959540859595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-5959595954595959593030050505050505050505050505050505061c595959595959ae06
-0e0e0d0000060e0e0ed75959595959595959595959595959595959595959595959035959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959045959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-59595959595959595959595959595959595959597f0459595959595959595959595959cd
-595959cd5959cd5959cd59595959595959cd5959cd59595959595959595959595959cd59
-595959cd5959cd595959595959cd59595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959045959
-595959595959595959595959595959055959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595930300505050505050505050505050505050606
-595959595959ae060e0e0d00001c0e2e59d7595959595959595959595959595959595959
-5959595959c8595959595959595959055959595959595959595959595959055959595959
-595959595905595959590559595959595959595959595959595959595959595959595959
-595959595959595959055959595959590559595959595959595959595959595959595959
-595959595959595959595959595959595904595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595904595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959cd5959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595904595959595959595959595959595959595959590559595959595959595905
-595959595959595959595959595959595959595959595959595959595959595959595959
-5959595959595959595959595959595959595959595959595930fa050505050505050505
-050505050505061c595959595959ae060e0e0d0000060e0e0ed759595959595959595959
-595959595959595959595959590359595959595959595959595959595959590559595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959590459595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-590459595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959590459595959595959595959590559595959595959595959
-595959595959595959595959055959595905595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959303005
-05050505050505050505050505050606595959595959ae060e0e0d00001c0e0e0ed75959
-595959595959595959cd5959595959595959595959055959595959595959595959055959
-595959595959595959595959595959595959595959595959595959595959595959590559
-595959595959055959595959055959595959595959595959595959595959595959595959
-595959595959595959595959cd5959595959595959595959595959595959595959045959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-59595959595959597f045959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595954085959055959595959595959595959
-595959595959595905595959595959595959595959595959595959595959595959595959
-595905595959595959595959595959595959595959595959595959595959595959595959
-59595959593030050505050505050505050505050505061c595959595959ae060e0e0d00
-00060e0e0ed75959595959595959595959595959595959595959595959c8595959595959
-595959595959595959595959595959595959595905595959590559595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-59595959595959595959595959595959595959595959595959595959cd59595959595959
-597f59595904595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595904595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959592d04595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959593030050505050505050505050505050505060659595959
-5959ae060e0e0d00001c0e0e0e4f59595959595959595959595959595959595959595959
-59c859595959595959595959595959595959595959590559595959595959595959595959
-055959595959595905595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959cd5959595959595959595959595959595959
-595959cd5959595959595959590459595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-5959595959595959595959595959597f59595959595959597f0459595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-5959595959cd595959595959595959595959595959595959595959595959595959595959
-590459595959590559595959595959595959595959595959595959055959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-59595959595959595959595959595959545959595930fa05050505050505050505050505
-0505061c595959595959ae060e0e0d0000060e0e0eef5959595959595959595959595959
-595959595959595959035959595959595959595959595959595959055959595959595959
-595959595959595959595959595959595959595959595959055959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959045959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959045959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959cd5959595959cd5959595959595959595959
-595959595959595959045959595959595959595959590559595959595959595959595959
-595959590559595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595930300505050505
-050505050505050505050606595959595959ae060e0e0d00001c0e2e594f595959595959
-5959595959595959595959595959595959c8595959595959595959595905595959595959
-595959595959595959595959595959595959055959595959595959595959595959595959
-595959595959595905595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595904595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595904595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595408595959595959595959595959595959595959
-595959595959595959595959595959590559595959055959595959595959595959595959
-595959595905595959595959595959595959595959595959595959595959595959595959
-593030050505050505050505050505050505061c595959595959ae060e0e0d0000060e0e
-0eef59595959595959595959595959595959595959595959590359595959595959590559
-595959595959595959595959595959595959055959595959595959595959595959590559
-595959595959595905595959590559595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-590459595959595959595959595959595959595959595959595959590a0a595959595959
-5959595959595959595959595959590a5959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-5959595959595959595959595904cd595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-5959595959595959595959595959595959595959595959592d0459595959595959595959
-595959595959055959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-59595959595959595930300505050505050505058d05050505050606595959595959ae06
-0e0e0d00001c0e0e0e4f5959595959595959595959595959595959595959595959c85959
-595959595959595959595959595959595959595905595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959cd5959595959595959595959
-59595959595959597f045959595959595959595959595959595959595959595959595959
-590a5959595959595959595959595959595959595959590a595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595459595959595959595959595959045959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959045959
-595959590559595959595959595959595959055959595959595959595959595959595959
-595959595959595959595959595905595959595959595959595959595959595959590559
-595959595959595959595959545959595930fa050505050505050505050505050505061c
-595959595959ae060e0e0d0000060e0e0ed7595959595959595959595959595959595959
-595959595903595959595959595959595959595959595959595959595959595959595959
-595959595959595959055959595959595959595905595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959545959595904595959595959595959595959590a0a59590a
-590a0a595959590a0a0a5959595959595959590a0a59590a0a590a0a59590a0a0a0a5959
-590a0a5959590a590a0a0a59595959595959595959595959595959595959595959595959
-5959595959595959595959595459595959595959cd595959595959595904595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595904595959595959595959595959595959595959595959595959590559595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959593030050505050505050505
-0505050505050606595959595959ae060e0e0d00001c0e2e59d759595959595959595959
-595959595959595959595959590559595959595959595959595905595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-5959595959595959595959595959595959595959595959597f0459595959545959595459
-59590a59590a59590a59590a59590a59590a59595959595959590a59590a59590a59590a
-5959590a595959590a59590a5959590a5959595959595459595954595959595459595959
-545959595959595959595959545959595459595959595959595959595959595959595959
-590459595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-5959595959595959595959595959595959595959595959595959595959595959cd595959
-5959cd595959595959595959540859595959595959595959055959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959303005
-0505050505050505050505050505061c595959595959ae060e0e0d0000060e0e2ed75959
-595959595959055959595959595959595959595959035959595959595959595959595959
-595959055959595959595959595959595959595959595959595959595959595905595959
-595959595959595959595959590559595959595959595905595959595959595959595959
-595959cd5959595959595959595959595959595959595959595959595959595959045959
-595959595959595959590a0a0a5959590a59590a59590a59590a59595959595959590a59
-590a59590a59590a5959590a595959590a0a0a595959590a595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-59595959595959595904595959cd59595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-59595959595959595959595959595959595959592d045959595959595959595959595959
-595959595959595959595959595959055959595905595959590559595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595930300505050505050505050505050505050606595959595959ae060e0e0d00
-001c0e2e59d75959595959595959595959595959595959595959595959c8595959595959
-595959595959595959595959595959055959595959590559595959055959595959595959
-595959595959595959595959055959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959597f045959595959595959595959590a59590a59590a59590a59590a59590a5959
-5459595959590a59590a59590a59590a5959590a59590a590a59590a5959590a59595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595904595959595959595959595959cd5959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959cd595959cd59595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595904595959595959
-595959595959595959055959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-5459595959595959595959595930fa050505050505050505050505050505061c59595959
-5959ae060e0e0d0000060e592ed759595959595959595959595959595959595959595959
-590359595959595959595959595959595959595959595959595959595959595959595959
-595959595959055959595959595959595959595959595959595959595959595959595959
-595959595959595959055959595959595959595959595959595959595959595959595959
-5959595959595959595959595904595959595959595959595959590a0a59590a0a0a590a
-0a59590a0a590a59595959595959590a0a595959590a0a590a5959590a0a5959590a0a59
-59590a0a0a0a595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959590459595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959cd5959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-590459595959595959595959595959595959595959590559595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959303005050505050505050505050505
-05050606595959595959ae060e0e0d00001c0e2e59d75959595959595959595959595959
-595959595959595959055959595959590559595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959590559595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959045959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-5959595959595959595959595959595959595959595959595959595959595959cd045959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959cd5959595959595959595959595959595959595959595959595959595959595959
-595959595959595954085959595959595959595959595959595959595959595959055959
-595959595959595959595959595959595959595959595959595959595959595959595959
-590559595959595959595959595959595959595959595959545959595930300505050505
-05050505050505050505061c595959595959ae060e0e0d0000060e0e0ed7595959595959
-595959595959595959595959595959595903595959595959595959595905595959595959
-595959595959055959595959595959595959055959595959595959595959590559595959
-595959595959595959590559595959595959595959595959595959595959595959595959
-5959595959595959595959595959595959595959cd595959595959595904595959595959
-59595959595959595959595959595959595959595959590a0a0a0a0a0a59595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595904595959595959595959595959595959595959595959595959595959595959
-5959595959595959595959595959595959595959595959595959595959595959cd595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959592d04595959595959595905595959595959595959
-595959595959595959595959595959590559595959595905595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-5930300505050505050505050505050505050606595959595959ae060e0e0d00001c0e2e
-59d75959595959595959595959595959595959595959595959c859595959595959595959
-595959595959595959595959595959595905595959595959595959595959595905595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-590459595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959590459595959595959595959595959595959cd5959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-59595959595959595959595959595959595959595959595959cd59595959595959595959
-595959595959595959595959595959595959595959595959590459595959595959595959
-590559595959595959595959595959595959055959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-59595959595959595930fa050505050505050505050505050505061c595959595959ae06
-0e0e0d0000060e0e0ed75959595959595959595959595959595959595959595959035959
-595959595959595959595959590559595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959590559595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-5959595959595959cd045959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959045959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-5959595959595959cd595959595959595959595959595959595959595959595959595959
-59595959595959595959595959595959595959595959595959595959595959595904cd59
-595959595959595959595959595959055959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595905595959
-595959595959595959595959595959595930300505050505050505050505050505050606
-595959595959ae060e0e0d00001c0e2e59d7595959595959595959595959595959595959
-5959595959c8595959595959595959595959595959595959055959595959595959595959
-055959595959595959595959595959595959595959590559595959595959595959595959
-59595959595959595959595959595959590559595959595959595959595959cd59595959
-cd5959595959595959595959595959595904595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595904595959595959
-595959595959595959595959cd5959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-59595959595959cd5959595959cd59595959595959595959595959595959cd5959595959
-59595959b308595959595959595959595959595959595959595959590559595959595959
-595959595905595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959593030050505050505050505
-050505050505061c595959595959ae060e0e0d0000060e0e0eef59595959595959595959
-595959595959595959595959590359595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595905595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959590459595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959cd5959595959cd5959595959
-5904cd595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959590559595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-5959595959595959595459592d0459595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959303005
-05050505050505058d05050505050606595959595959ae060e0e0d00001c0e2e594f5959
-595959595959590559595959595959595959595959055959595959595959590559595959
-595959595959595959595959595959595959595959590559595959595959595959595959
-595959590559595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959045959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-5959595959595959595959595959595959595959595959cd595959595959595959595959
-595959595959595959045959595959595959595959595959595959595959055959595959
-595959cd5959cd595959cd59595959595959595959595959595959595959595959595959
-59595959595959595959595959595959595959595959595959595959595959cd59595959
-595959595959595959595959595959595959595959045959595959595959595959055959
-595959595959595959595959595959055959595959595959595959595959595959595959
-595905595959595959595959595959595959595959595959595959595959595959595959
-545959595930fa050505050505050505050505050505061c595959595959ae060e0e0d00
-00060e0e0eef595959595959595959595959595959595959595959595903595959595959
-595959595959595959595959595959595959595959595959595959055959595959595959
-595959595959595959595959595959595959595959055959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595904595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-5959595959595959595959595959cd595959cd5959595959595959595959595959595959
-595959595959595959595959595959595904595959595959595959595959595959595959
-595959595959cd5959595959595959595959595959cd5959cd595959cd59595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595904595959595959
-595959595959595959595959595959595959590559595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959593030050505050505050505050505050505060659595959
-5959ae060e0e0d00001c0e2e594f59595959595959595959595959595959595959595959
-59c859595959595959595959595959595959595959055959595905595959595959595959
-595959595905595959595959055959595959595959595959595959595959595959595959
-595959595959595959595959595959595905595959595959595959595959595959595959
-59595959cd59595959595959590459595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-54595959595959595959595959595959cd59595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959cd0459595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-5959595959595959595959595959595959595959cd595959595959595959595959595959
-540859590559595959595959595959595959595959595959595959595959595959595959
-595959590559595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959303005050505050505050505050505
-0505061c595959595959ae060e0e0d0000060e0e0eef5959595959595959595959595959
-595959595959595959035959595959595959595959055959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959590559595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-5959595959595959595959595959595959595959cd045959595959595459595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-59595959595959595959595959595959595959cd59595959595959595959595959595959
-5959cd595959cd5959595959595959595959595959595959595959595959595959045959
-cd5959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-59595959595959592d045959595959595959595959595959055959595959595959595959
-595959595959595905595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595930300505050505
-050505050505050505050606595959595959ae060e0e0d00001c0e2e59d7595959595959
-5959595959595959595959595959595959c8595959595905595959595959595959595959
-595959595959595959055959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595904595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595904595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595904595959595959055959595959595959595959
-590559595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959590559595959545959595959595959595959
-5930301c1c1c1c1c1c1c1c1c1c061c060606061c595959595959ae060e0e0d0000060e59
-2ed759595959595959595959595959595959595959595959590359595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959055959595959595959595959595959055959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-590459595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595954595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959cd5959595959
-595959595959595959595959590459595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959590459595959595959595959
-595959595959595959595959595959595959590559595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-5959595959595959593030051c1c1c1c1c0606060606060606300606595959595959ae06
-0e0e0d00001c0e2e59d75959595959595959595959595959595959595959595959055959
-595959595959595959595959595905595959595959595959595959595959595959595959
-595959055959595959595959590559595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-5959cd59595959597f045959595959595959545959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959045959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959cd5959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595954085959
-595959595959055959595959595959595959595959595959595959595959595959595959
-590559595959595959595959595959595959595959595959595959595959595959595959
-59595959595959595959595959595959593030051c065959595959595959593030050606
-595959595959ae060e0e0d0000060e0e0ed7595959595959595959595959595959595959
-5959595959c8595959595959595959595905595959595959595959055959595959595959
-055959595959595959595959595959595959595959595959595959055959595959595959
-595959595959590559595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595904595959595959595959595959595959595459
-595959595959595959595959595959595959595959595959595959595959595459595959
-5959595959595959cd595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595904595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-5959595959595959595959595959595959595959595959595959595959595959cd595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959592d04595959595959595959595959595905595959595959590559595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959545959593030050506065959595959
-5959593030050606595959595959ae060e0e0d00001c0e2e59d759595959595959595959
-59595959595959595959595959c859595959595959595959595959595959595959595959
-595959595959595959595959590559595959595959055959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-5959595959595959595959595959595959595959595959597f0459595959595959595954
-595954595959595959545959595959595959595959595959595459595954595954595954
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-590459595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959590459595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959055959595959
-595959595959595959595959595959595959595959595959595959595959595959303005
-05061c5959595959595930300505061c595959595959ae060e0e0d0000060e0e0eef5959
-595959595959595959595959595959595959595959035959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959590559595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959045959
-595959595959595959595959595959595959595959595459595954595959545959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-5959595959595959cd045959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959045959595959595959595959595959
-595959595959595959595905595959595905595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595930300505050606595959595959303005050606595959595959ae060e0e0d00
-001c0e2e594f5959595959595959590559595959595959595959595959c8595959595959
-055959595959595959595959595959595959055959595959595959595959595959595959
-595959595959595905595959595959055959595959595959595959595959595959595959
-595959595959595959595959595959595959cd5959595959595959595959595959595959
-595959597f04595959595959595959595959595459595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-5959595959cd595959595959595959595904595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959cd5959595959595959cd59595959cd595959595959595959595408595959595959
-595905595959595959595905595959595959595959595959595959595959055959595959
-595959595959595959595959595959590559595959595959595959595959595959595959
-595959595959595959595959593030050505060659595959593030050505060659595959
-5959ae060e0e0d0000060e0e0eef59595959595959595959595959595959595959595959
-590359595959595959595959595905595959590559595959595959595959595905595959
-595959595905595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959cd5959
-595959595959595959595959590459595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-59595959595959cd59595959595959595959595959595959590459595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-2d0459595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-5959595959595959595959595959595959595959593030050505051c0659595959303005
-05050606595959595959ae060e0e0d00001c0e2e594f5959595959595959595959595959
-595959595959595959c85959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595905595959595959595959595959595959595959595959595959595959595959595959
-59595959595959595959595959595959595959597f045959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-5959595959595959595959595959595959595959595959595959595959595959cd045959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959045959595959595959595959055959595959595959595959595959
-595959595959595959595959590559595959595959595959595959595959595959595959
-595959595959595959595959595959595459595959595959595959595930300505050506
-06595959303005050505061c595959595959ae060e0e0d0000060e0e0eef595959595959
-595959595959595959595959595959595903595959595959595959595959595959595959
-595959595959595959595959595959590559595959595959595905595959595959595959
-595959595959595959595959595959595959590559595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595904595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595904595959cd5959595959595959595959595959595905595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595904595959595959595959595959595959595959
-595905595959595959055959595905595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-5930300505050505060659593030050505050606595959595959ae060e0e0d00001c0e0e
-0e4f59595959595959595959595959595959595959595959590559595959595959595959
-595959595959595905595959595905595959595959595959595959595959595959595959
-595959595959055959595959055959595959595959595959595959595959590559595959
-59595959cd59595959595959595959595959595959595959595959595959595959595959
-7f0459595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595459595959595959595959595959595959
-cd59595959595959cd595959595959595959595959595959595959595959595959595959
-595959595959595959595959cd0459595959595959590559595959595959595959595959
-595959055959590559595959595959595905595959590559595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959540859595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-5959595959595959593030050505050506065430300505050505061c595959595959ae06
-0e0e0d0000060e0e0ed75959595959595959595959595959595959595959595959035959
-595959595959055959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959045959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959045959595959595959595959590559
-595959595959595959595959595959595959590559595959595959595959595959590559
-595905595959055959590559595959595959595959595959595959595959595959595959
-59595959595959595959595959595959595959595959595959595959595959592d045959
-595959595959595959595959055959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959545930300505050505050630303005050505050606
-595959595959ae060e0e0d00001c0e0e0ed7595959595959595959595959595959595959
-5959595959c8595959595959595959595905595959595959595959595959595959590559
-595959595959595959595959595959590559595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959597f04595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959cd5959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595408595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-5959595959595959595959595959595959cd5959595959595959595959cd595959595959
-595959595904595959595959595959595959595959595959595959055959595959595959
-595959595959595959055959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959545959595959593030050505050505063030
-0505050505050606595959595959ae060e0e0d0000060e0e0ed759595959595959595959
-595959595959595959595959590359595959595959595959595959595959595959595959
-595959595959595959595959590559595959055959595959595959595959595959595959
-595959055959595905595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959590459595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959cd5959595959595959
-590459595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-5959595959595959595959595904cd595959595959595905595959595959595959595959
-595959595959595959595905595959595959595959595959595959595959595959595959
-595905595959595959595959595959595959595959595959595959595959595959303005
-05050505050530300505050505050606595959595959ae060e0e0d00001c0e2e59d75959
-595959595959595959595959595959595959595959c85959595959595959595959595959
-595959595905595959595959595959595959595959595959595959595959595959595959
-595959055959595959595959595959595959595959595959595959595959595959595959
-5959595959595959595959595959595959595959cd59595959595959595959597f045959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959045959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-590559595959595959595959590559595959595959595959595959595959595959595959
-595959595959595959595959595959595959595954085959595959595959595959595959
-595959595959595959595959590559595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-5959595959303005050505050505308d050505050505061c595959595959ae060e0e0d00
-00060e0e0ed7595959595959595959595959595959595959595959595903595959595959
-595959595959595905595959595959595959595959595959590559595959595959595959
-595959595959590559595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595904595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959545959595959595959595959595959595959595959
-5959595959595959595959595959595959595959595959595959cd595959595959595959
-595959595959595959595959595959595904595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959055959595959595959590559595959595959595959
-595959595959595959595959595959595959595959595959595959595904595959595959
-595959595959595959055959595959595959055959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-5959595959595959595959595930301c1c061c06060606061c0606060606060659595959
-5959ae060e0e0d00001c0e0e0ed759595959595959595959595959595959595959595959
-590559595959595959595959595959595959595959595959595905595959595959595959
-595959595959595959595959595959595959595959055959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-5959595959595959595959597f0459595959595959595959595959595959595959595959
-595959595959595959595959595959595959545959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959590459595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-590459595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595905595959595959
-595959595959595959595959595959595959595959300606060606060606060606060606
-0606061c595959595959ae060e0e0d0000060e0e0ed75959595959595959595959595959
-595959595959595959035959595959595959595959595959595959595959595959595959
-595959595959595959595959595959055959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959590559595959595959595959
-5959595959595959595959595959595959595959590459cd595959595959595959595959
-595959595959595959595959595959595959595959595959545959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-5959cd595959595959595959595959595959595959595959595959595959595959045959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959045959595959595959595959055959595959595959595959595959
-595959595959590559595959055959595959595959595959595959595959595959595959
-595959595959595905595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959ae060e0e0d00001c0e0e0e4f595959595959
-595959595959595959595959595959595959595959595959595905595959595959595959
-595959595959595959595959595959595905595959595959590559595959595959595959
-595959595959055959595959595959595959595959595959595959595959595959595959
-595959595959cd5959595959595959595959595959595959595959595959595959595459
-595959595954595959545959595959595959595959595954595959545959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959cd5959595959595959595959595959595959595959595959595959595959
-595959cd5959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959cd5959595959
-595959595959595959595959595959595959595905595959595959595959595959595959
-055959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-5959595959595959595959595959595959595959595959595959ae060e0e0d0000060e0e
-0eef5959595959593efafa27fafa30fa3030fa3030fa3027fafa273e27273e2727272727
-27273e2727273e2727273e2727273e2727273e2727273e2727272727273e272727272727
-273e2727273e2727273e27272727272727273e2727273e27273e27273e273e273e3e273e
-273e27272727fa27fafa27fa27fa2730fafa30fa3027fa30fa30fa30fa3027fa302730a9
-30a93030a9303030fa3030fa303030303030fa30fa30fa30fa30fa3030fa303030fa3030
-3030fa303030fa3030fa3030fa30fa30fa30fa30fa30fa30fa30fafa30fafa30fa30fafa
-30fafa30fa30fafa30fafa30fa3027fa3027fa3027fa27fa27fa27fafa27fafa27fa273e
-273e27273e27fa27fa27273027fa27fa273e273e273e273e273e273e273e273e273e273e
-27273e273e273e273e273e273e273e273e273e27273e27273e27273e273e273e273e273e
-2727273e273e27273e2727273e27273e27273e27273e273efa27fafa27fafa27fafa27fa
-27fa2730fa30fa30fa30fa30fa30fa30fa30a93030a9a9faa927fa27272727273e272727
-3e2727273e272727272727273e2727273e2727273e2727273e2727273e27273e27273e27
-273e273e273e273e273e2727273e27272727fa27fa27fa2727fa27fafa30fa30fa3030fa
-30303030303030595959595959595959595959595959595959595959595959595959ae06
-0e0e0d00001c0e2e594f59595959595930303030303030303030303030303030302727fa
-272727273e2727fa27272727fa272727fa272727fa272727fa272727fa27273e2727fa27
-2727273e2727fa27272727fa272727fa272727fa273e2727fa272727fa2727fa2727fa27
-27272727272727272730fa30fa3030273030303030303030303030303030303030303030
-303030303030303030303030303030303030303030303030303030303030303030303030
-303030303030303030303030303030303030303030303030303030303030303030303030
-303030303030303030303030303030303030303030303030303030303030303030303030
-302730303030303030303030303030303030303030303030302730273027302730272730
-27273027273027fa273027273027302730273027302730273027fa273027302727302730
-273027302727302730fa273027fa273030fa2730fa2730273030fa273030303027303030
-303030303030303030303030303030303030303030303030303030303030303030272727
-fa27fa272727fa272727fa2727273e2727fa27272727fa272727fa272727fa272727fa27
-27fa2727fa2727fa27272727272727272727fa3027fa2730fa3030303030303030303030
-30303030303030303030303030301c595959595959595959595959595959595959595959
-595959595959ae060e0e0d0000060e0e0eef595959595959273005050505050505050505
-050505052e052e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e
-2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e
-2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e1c2e2e2e1c2e1c1c1c1c1c1c1c
-1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c
-1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c
-1c1c1c2e1c1c1c1c1c1c2e1c2e1c2e1c1c2e1c2e1c1c2e1c1c2e1c2e1c2e1c2e1c2e1c2e
-1c2e1c2e2e1c2e2e2e2e2e2e2e2e2e2e2e2e2e1c2e1c1c1c1c1c1c1c2e2e2e2e2e2e2e2e
-2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e
-2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e1c2e2e2e1c2e2e1c2e2e2e2e2e0505
-050505050505050505050505050505050505050505050505050505050505050505050505
-050505050505050505050505050505050505050505050505050505050505050505050505
-050505050505050505050505050505050505050505050505050505050505050505050505
-0505050505052e1c050505050505050505050505051c1c59595959595959595959595959
-5959595959595959595959595959ae060e0e0d00001c0e0e0e4f59595959595930300505
-050505050505050505051c2e30051c1c1c1c2e1c1c2e1c1c1c2e1c1c1c2e1c1c1c2e1c1c
-1c2e1c1c1c2e1c1c1c1c1c1c2e1c1c1c2e1c1c1c2e1c1c1c2e1c1c1c2e1c1c1c1c2e1c1c
-1c1c1c1c1c1c2e1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c
-1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c06061c0606060606061c1c1c1c1c061c1c1c1c
-1c1c1c1c1c06060606061c0606061c061c061c1c061c1c1c1c1c1c1c1c1c1c1c1c1c1c1c
-1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c
-1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c
-1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c
-1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c
-1c1c1c1c1c30050505050505050505050505050505050505050505050505050505050505
-050505050505050505050505050505050505050505050505050505050505050505050505
-050505050505050505050505050505050505050505050505050505050505050505050505
-05050505050505050505050505051c1c1c2e0505050505050505050505061c5959595959
-59595959595959595959595959595959595959595959ae060e0e0d000002ec0fec0f5959
-595959593030050505050505050505052e1c1c3030051c1c595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959303005050505050505050505050505050505050505050505
-050505050505050505050505050505050505050505050505050505050505050505050505
-050505050505050505050505050505050505050505050505050505050505050505050505
-050505050505050505050505050505050505050505051c1c1c1c1c1c0505050505050505
-051c06595959595959595959595959595959595959595959595959595959643725db0000
-014f4f4f4fec595959595959303005050505050505051c1c1c1c593030051c1c59595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-5959595c5959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595930300505050505050505050505050505
-050505050505050505050505050505050505050505050505050505050505050505050505
-050505050505050505050505050505050505050505050505050505050505050505050505
-0505050505050505050505050505050505050505050505050505050505051c1c59591c1c
-1c1c05050505050505061c59595959595959595959595959595959595959595959595959
-5959258b4e122500004f13133e0f59595959595930300505050505052e1c1c1c59595930
-30051c1c5959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959593030050505050505
-050505050505050505050505050505050505050505050505050505050505050505050505
-050505050505050505050505050505050505050505050505050505050505050505050505
-050505050505050505050505050505050505050505050505050505050505050505050505
-05051c06595959591c1c1c1c050505050506065959595959595959595959595959595959
-59595959595959595959438b1212db00004f3e1313ec5959595959593030050505051c1c
-1c1c59595959593030051c1c595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-303005050505050505050505050505050505050505050505050505050505050505050505
-050505050505050505050505050505050505050505050505050505050505050505050505
-050505050505050505050505050505050505050505050505050505050505050505050505
-050505050505050505051c1c5959595959591c1c1c1c050505061c595959595959595959
-595959595959595959595959595959595959dbbb7e124300004f133e130f595959595959
-303005052e2e1c1c595959595959593030051c0659595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595930300505050505050505050505050505050505050505050505050505
-050505050505050505050505050505050505050505050505050505050505050505050505
-050505050505050505050505050505050505050505050505050505050505050505050505
-0505050505050505050505050505050505051c0659595959595959591c061c0605060659
-5959595959595959595959595959595959545959595959595959438b7e7e2500007a1313
-3eec5959595959593030303030305959595959595959593030051c1c5959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959593030050505050505050505050505050505050505
-050505050505050505050505050505050505050505050505050505050505050505050505
-050505050505050505050505050505050505050505050505050505050505050505050505
-0505050505050505050505050505050505050505050505050505061c5959595959595959
-5930303030061c595959595959595959595959595459595959595959595959595959258b
-12124300004f3e731364595959595959303005053030303059595959595959303005061c
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959303005050505050505050505
-050505050505050505050505050505050505050505050505050505050505050505050505
-050505050505050505050505050505050505050505050505050505050505050505050505
-050505050505050505050505050505050505050505050505050505050505050505051c06
-595959595959595930303030050606595959595959545959595959595959595959595959
-595959595959db8b127e2500007a13133eec595959595959303005050505303030305959
-5959593030051c1c59595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595930fa0505
-050505050505050505050505050505050505050505050505050505050505050505050505
-050505050505050505050505050505050505050505050505050505050505050505050505
-050505050505050505050505050505050505050505050505050505050505050505050505
-050505050505061c595959595959303030300505051c1c59595959595959595959595959
-5954595959595959595959595959438b12124300004f7395130f59595959595930300505
-0505050530303030595959303005061c5959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959593030050505050505050505050505050505050505050505050505050505050505
-050505050505050505050505050505050505050505050505050505050505050505050505
-050505050505050505050505050505050505050505050505050505050505050505050505
-05050505050505050505050505051c065959595930303030050505050506065959595959
-59595959595959595959595959595959595959595959dbbb127e2500004f133e13ec5959
-595959593030050505050505050530303030593030051c1c595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-59595959595959595959595930fa05050505050505050505050505050505050505050505
-050505050505050505050505050505050505050505050505050505050505050505050505
-050505050505050505050505050505050505050505050505050505050505050505050505
-05050505050505050505050505050505050505050505061c595930303030050505050505
-05061c595959595959595959595959595959595959595959595959595959438b12124300
-008b73957364595959595959303005050505050505050505303030303005061c59595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595930300505050505050505050505050505
-050505050505050505050505050505050505050505050505050505050505050505050505
-050505050505050505050505050505050505050505050505050505050505050505050505
-0505050505050505050505050505050505050505050505050505050505051c0630303030
-0505050505050505051c0659595959595959595959595959595959595459595959595959
-595943bb127e2500004f13133eec59595959595930300505050505050505050505053030
-30051c1c3030303030303030303030303030303030303030303030303030303030303030
-303030303030303030303030303030303030303030303030303030303030303030303030
-303030303030303030303030303030303030303030303030303030303030303030303030
-303030303030303030303030303030303030303030303030303030303030303030303030
-303030303030303030303030303030303030303030303030303030303030303030303030
-303030303030303030303030303030303030303030303030303030303030303030303030
-303030303030303030303030303030303030303030303030303030303030303030303030
-303030303030303030303030303030303030303030303030303030303030303030303030
-3030303030303030303030303030303030303030303030303030303030fa050505050505
-050505050505050505050505050505050505050505050505050505050505050505050505
-050505050505050505050505050505050505050505050505050505050505050505050505
-050505050505050505050505050505050505050505050505050505050505050505050505
-0505061c30300505050505050505050505061c5959595959595959595959595959595959
-59595959595959595959db8b12124300008b217313645959595959593030050505050505
-050505050505050530050630303030303030303030303030303030303030303030303030
-303030303030303030303030303030303030303030303030303030303030303030303030
-303030303030303030303030303030303030303030303030303030303030303030303030
-303030303030303030303030303030303030303030303030303030303030303030303030
-303030303030303030303030303030303030303030303030303030303030303030303030
-303030303030303030303030303030303030303030303030303030303030303030303030
-303030303030303030303030303030303030303030303030303030303030303030303030
-303030303030303030303030303030303030303030303030303030303030303030303030
-303030303030303030303030303030303030303030303030303030303030303030303030
-303005050505050505050505050505050505050505050505050505050505050505050505
-050505050505050505050505050505050505050505050505050505050505050505050505
-050505050505050505050505050505050505050505050505050505050505050505050505
-05050505050505050505063005050505050505050505050505061c595959595959595959
-59595959595959595959595959595959595943bb127e2500007a73133eec595959595959
-30301c1c1c1c1c1c1c1c1c1c1c06060606061c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c
-1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c
-1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c
-1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c
-1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c
-1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c
-1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c
-1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c
-1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c
-1c1c1c1c1c1c1c1c2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e
-1c2e2e2e2e2e2e2e2e2e2e2e2e2e2e0e2ef10ef10ef10ef10ef10ef10ef10ef10ef10ef1
-0ef10ef10ef10ef10ef10ef10ef10ef10ef10ef10ef10ef12e0e2e2e2e2e2e2e2e2e2e2e
-2e2e2e2e2e2e2e2e2e1c1c1c1c1c1c1c060606061c1c061c061c061c061c060606061c59
-5959595959595959595959595959595959595959595959595959db8b1212430000a32173
-1364595959595959301c1c1c1c0606060606060606060606060606061c1c1c1c1c1c1c1c
-1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c
-1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c
-1c1c1c061c061c061c0606061c0606060606060606060606060606060606060606060606
-060606060606060606060606060606060606060606060606060606060606060606060606
-06060606060606060606061c061c061c061c061c1c061c06061c06061c06061c061c061c
-061c061c1c061c061c061c1c061c1c061c1c061c061c1c061c1c061c1c061c061c06061c
-1c061c061c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c061c1c061c1c1c1c061c1c1c1c1c1c
-1c1c1c1c1c1c1c1c1c1c1c061c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c061c061c1c1c06
-1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c2e1c2e1c1c1c1c1c1c1c1c1c1c1c1c
-1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e
-2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e1c2e2e2e1c2e2e1c2e1c2e2e2e2e2e2e
-2e2e2e2e2e1c2e2e1c2e1c1c1c1c1c1c1c1c1c1c1c060606060606060606060606060606
-0606060606060659595959595959595959595959595959595459595959595959595943bb
-217e2500009673133eec5959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959595959595959595959595959595959595959595959595959595959595959
-595959595959db8b1212430000bb21730273ecec64ecec64bf8f0fbf8f368f368f36aeae
-aeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeae
-aeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeae
-aeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeae
-aeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeae
-aeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeae
-aeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeae
-aeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeae
-aeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeae
-aeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeae
-aeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeae
-aeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeae
-aeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeae
-aeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeae22aed7d7aed7d7d7d7d7d7d7d713ec
-6464646464f864646425256443648b7e127e25001d007a1313733e4f504f4f4f7a4f347a
-4f7a4f4f4fc306060606060606060606061c061c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c
-1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c
-1c1c1c1c1c1c1c061c06061c060606060606060606060606060606060606061c06061c06
-061c06061c06061c060606060606061c0606060606060606060606060606060606060606
-06060606060606060606060606060606060606060606060606061c0606061c06061c0606
-06061c0606060606061c060606061c06060606060606060606060606061c060606060606
-0606060606060606060606060606060606061c0606060606060606060606060606060606
-060606060606060606060606060606060606060606060606060606060606060606060606
-0606060606060606060606060606060606060606060606060606061c061c1c1c1c1c1c1c
-1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c
-1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c
-1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c
-1c1c1c1c1c1c061c0606060606060606060606060606060606061c06061c1c1c1c1c1c1c
-1c1c1c1c1c1c7a7a7a7a7a7a7a7a8b5a8b8b8b38bbbb1212124300061d008b7373021313
-73130295027302212121212173860e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e
-0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e
-0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e5c0e0e
-0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e
-0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e
-0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e
-0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e
-0e0e0e5c0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e
-0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e
-0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e
-0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e
-0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e
-0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e
-0e0e0e0e0e0e0e0e0e0e0e0e0e0e4f02137302022121123712121212127e12b512db0006
-898700256473730273737321217e121212122121138f0e0e0e0e0e0e0e0e0e0e0e0e0e0e
-0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e
-0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e
-0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e
-0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e
-0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e
-0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e
-0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e
-0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e
-0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e
-0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e
-0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e
-0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e
-0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0ef10ea37321b51212127e1212127e1212
-21121243db000606f81d890000646425252564d3432543434343434343640d0d0d0d0d0d
-0d050d050d05050505050505050505050505050505050505050505050505050505050505
-050505050505050505050505050505050505050505050505050505050505050d050d050d
-050d0d0d0d0d0d0d0d050d050d050d0d050d050d050d050d050d050d050d050d050d0d0d
-050d050d050d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d
-0d0d0d0d0d0d0d0d0d0d0d050d050d050d050d050d050d050d050d050d0d050d050d050d
-050d050d0d0d0d0d0d0d0d0d0d0d050d050d050d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d
-0d0d0d050d050d050d0d0d0d0d0d0d050d050d050d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d
-0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d
-0d0d0d0d0d0d0d0d0d0d0d050d050d050505050505050505050505050505050505050505
-050505050505050505050505050505050505050505050505050505050505050505050505
-050505050505050505050505050505050505050505050505050505050505050505050505
-0505050505050505050505050505050505050505050505050505050505050d050d0d0d0d
-0d0d0d0d0d0d0d0d0d0d050d050d050d0505050505050505050505050d051343432543db
-43db43db43dbdbdb43dbdb00000000061d891d1d1d000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000060600
-%%PageTrailer
-%%Trailer
-%%EOF
diff --git a/lib/et/doc/src/sim_trans_contents_viewer_collector.gif b/lib/et/doc/src/sim_trans_contents_viewer_collector.gif
deleted file mode 100644
index 77115b71ab..0000000000
--- a/lib/et/doc/src/sim_trans_contents_viewer_collector.gif
+++ /dev/null
Binary files differ
diff --git a/lib/et/doc/src/sim_trans_contents_viewer_collector.png b/lib/et/doc/src/sim_trans_contents_viewer_collector.png
new file mode 100644
index 0000000000..545697bf38
--- /dev/null
+++ b/lib/et/doc/src/sim_trans_contents_viewer_collector.png
Binary files differ
diff --git a/lib/et/doc/src/sim_trans_contents_viewer_collector.ps b/lib/et/doc/src/sim_trans_contents_viewer_collector.ps
deleted file mode 100644
index 3ef1921fa2..0000000000
--- a/lib/et/doc/src/sim_trans_contents_viewer_collector.ps
+++ /dev/null
@@ -1,1407 +0,0 @@
-%!PS-Adobe-3.0 EPSF-3.0
-%%Creator: GIMP PostScript file plugin V 1.12 by Peter Kirchgessner
-%%Title: /home/hakan/picts/sim_trans_contents_viewer_collector.ps
-%%CreationDate: Mon Oct 14 17:27:25 2002
-%%DocumentData: Clean7Bit
-%%LanguageLevel: 2
-%%Pages: 1
-%%BoundingBox: 14 14 406 232
-%%EndComments
-%%BeginProlog
-% Use own dictionary to avoid conflicts
-10 dict begin
-%%EndProlog
-%%Page: 1 1
-% Translate for offset
-14.173228 14.173228 translate
-% Translate to begin of first scanline
-0.000000 217.359744 translate
-391.247539 -217.359744 scale
-% Image geometry
-468 260 8
-% Transformation matrix
-[ 468 0 0 260 0 0 ]
-% Strings to hold RGB-samples per scanline
-/rstr 468 string def
-/gstr 468 string def
-/bstr 468 string def
-{currentfile /ASCII85Decode filter /RunLengthDecode filter rstr readstring pop}
-{currentfile /ASCII85Decode filter /RunLengthDecode filter gstr readstring pop}
-{currentfile /ASCII85Decode filter /RunLengthDecode filter bstr readstring pop}
-true 3
-%%BeginData: 82198 ASCII Bytes
-colorimage
-r;V<JJH16$[f?Ok0f^sKJ,~>
-r;V<JJH16$[fH=oJ,~>
-r;V<JJH16$[fH>IJ,~>
-rr;uunc&S<J[C!8K<tV-mJd0^mJd0^nc/Uhs#C'6J,~>
-rr;uunc&SGMnXbRJ\(Zg!&X*C!28f[!28r_rrE$dJ,~>
-rr;uunc&SuJaS*WKC/_KmJd0^mJd0^nc/Uhrc<S~>
-s8N-#s8W)KqVM,3!%EJWXc%a_f7O,Rs3:GkqVM/4!i5k@qpkQ"r8n'Vs3:GkqVDD<s8N'Z3Ih~>
-s8N-#s8W)LrS%8-ro3q>!&U.0JWYMGlB)-)s3CVlrmq&%rndY6s5jBVs3CVlrmq&%rndY6s5jBV
-s3CVlrmq&%rn[h<s8N'e7">~>
-s8N-#s8W)KqVM,3!+LN9J_l%9!b22SqpkQ"r8n'Vs3:GkqVM/4!i5k@qpkQ""m5jb!-<43~>
-!ri9#rRLc$qW7c,JTJAC!.4]d!.4]d!.4]d!.4]d!/(8l!/(8l!/(8l!/(8l!/(8l!/pht!/pht
-IuAYpF,PBdF,PBdF,PBdF,PBdF-M#mF-M#mF-M#mF-M#mF-M#mF-M#mF-M#mF-M#mF-M#mF-M#m
-F-M#mF-M#mF-M#mF-M#mF-M#mF-M#mF-M#mF-M#mF-M#mF-M#mF-M#mF-M#mF-M#mF-M#mF-M#m
-F-M#mF-M#mEsn4ZF*!RmF*!Re.KB:qqVM,3!Mobmeb\/"joM:XqpkQ"rT41+!&9!~>
-"9/B$df.hrgA]t.ir/!>1kC(kI/nitI/nitI/nitI/o!#I/o!#I/o!#I/o-'I=I*)I=7*+I=7*+
-I=7*+I=76/I=76/I=76/I=7B3I=7B3I=7B3I=7B3I=7N7I=7N7I=7N7I=7N7I=7N7I=7N7I=7N7
-I=7Z;I=7Z;I=7Z;I=7Z;I=7Z;I=7Z?I=7Z?I=7Z?I=7Z?I=7Z?I=7Z?I=7Z?I=7Z?I=7Z?I=3?2
-KmeB?KmeB?KmeB?KmeB?KmeB?KmeB?KmeB?KmeB?I5M!'df.hrgA]t.ir8'@U&Y,?rmq&%rndY6
-roO6Ts8LIGf)=>%hYuL:k0<rpJ,~>
-!ri9#rRLc$qW7ceJ^(aM!7h(n!7h(n!7h(n!7h(n!7h(n!7h(n!7h(n!7h(n!7h(n!7h(ns4..o
-s4..os4..os4..oJ)8`#c/.!qc/.!qc/.!qc/.!qc/.!qc/.!qc/.!qc/.!qc/.!qc/.!qc/.!q
-c/.!qc/.!qc/.!qc/.!qc/.!qc/.!qc/.!qc/.!qc/.!qc/.!qc/.!qc/.!qc/.!qc/.!qc/.!q
-c/.!qc/.!qc/.!qc/.!qc/-]Ss81@ChYZF9V#U>BqVM,3!Mobmeb\/$joWd-F+=~>
-!ri9#rmgl%qrRtJjsbjrr+Z:SK6,%I!-A-S!-A-S!-A-S!-A-S!.4][!.4][!.4][!.4][ItMfW
-C4gSBC4gSBC4gSBC5[.JC5[.JC5[.JC5[.JC5[.JC5[.JC6WdSC6WdSC6WdSC6WdSC6WdSC6WdS
-C6WdSC6WdSC6WdSC6WdSC6WdSC7K?[C7K?[C7K?[C7K?[C7K?[C7K?[C7K?[C7K?[C7K?[C7K?[
-C7K?[C)iabC208[C208[C208[C208[C208[C208[C+92\eb\/"joXtHs8:FDhYZF:m\Km\eb\/#
-joWd-0n9~>
-!ri9#rmq&%rndY6roO:IjtqX7r-8?lNIf5t!.Fil!.Fil!.Fil!.k,p!.k,pIt`;rH%gZlH&6rp
-H&6rpH&[5tH&[5tH'*N#H'*N#H'Nf'H'Nf'H'Nf'H's5/H's5/H's5/H's5/H's5/H's5/H(BM3
-H(BM3H(BM3H(BM3H(BM3H(BM3H(fe7H(fe7H(fe7H(fe7H(fe7H(fe7H(fe7H(fe7H(fe7GqPeA
-H$Q*7H$Q*7H$Q*7H$Q*7H$Q*7H$Q*7H$Q*7H$Q*7H$Q*7H$Q*7Gr5QLdf.hrgA]t.ir8'ClCn7+
-df.hrgA]t.ir8'ClCn7+df.hrgA]t.irA-Bc2^7_~>
-!ri9#rmgl%qrRtJk$in\r5JZ[`l.r&rl"l^rl"l^rl"l^rl"l^rl"l^rl"l^rl+o^s2G#_s2G#_
-s2BK<c,IZPc,IZPc,IZPc,IZPc,IZPc,IZPc,IZPc,IZPc,IZPc,IZPc,IZPc,IZPc,IZPc,IZP
-c,IZPc,IZPc,IZPc,IZPc,IZPc,IZPc,IZPc,IZPc,IZPc,IZPc,IZPc,IZPc,IZPc,IZPc,IZP
-c,IZPc,IZPc,IX9e]l(Pe]l(Pe]l(Pe]l(Pe]l'Bs8:FDhYZF:m\Km\eb\/"joXtHs8:FDhYcL;
-blDg8~>
-!<E0!eb\/"k5XiMjsd0Bs5)RH%#`)>PlLd.hVN!^pA`c["nqt2CA.]*C&i>SC&i>SC&i>SC&i>S
-C&iV[C&iV[C4CSOC;luiC2/BBC2/BBC2/ZJC2/ZJC2/ZJC2/uSC2/uSC2/uSC2/uSC2/uSC2/uS
-C2/uSC2/uSC208[C208[C208[C208[C208[C208[C208[C208[C208[C20PkC20PkC20PkC20Pk
-C20PkC20PkC20PkC20PkC2,&jHYR;kHYR;kHYR;kHYR;kHYR;kHYR;kHYR;kHYR;kHYR:Es8CLE
-hYZI8mK'-`rRLX.roX7K!MoboeH4Sn62f[?62fpIm_&UN~>
-!<E0!f)=>%hYuO6k5X]IjtrrXs5)RS%$ehTSbiB7hVNBtpA3Ea"nqe8FnY\0FT?^dFT?jhFT?jh
-FansfF`i7\F`iC`F`iC`FiLG,F`i[hF`i[hF`iglF`igpF`istF`j+#F`j+#F`j+#F`j+#F`j7'
-F`j7'F`j7'F`j7'F`j7'F`jC+F`jC+F`jC/F`jC/F`jC/F`jO3F`jO3F`jO3F`jO3F`jO3F`jO3
-F`jO3F`jO3F`fI9JTZ+3JTZ+3JTZ+3JTZ+3JTZ+3JTZ+3JTZ+3JTZ+3JTZ+3JTZ+3JTZ+3JTZ)l
-qU5AorS%8-ro3q>s69ZZqU5AoqEY$JroX7G!hoJ=rmh2*5X='&hZ#tDir8'AlFHtG~>
-!<E0!eb\/"k5XiMk$k4,s7Y9f%+Xdbec5[;p@cJEs8U`js8W,<s8W#9!6tM^!6tM^!6tM^!6tM^
-!6tM^s3:S_s36&4mbZ4-`QcZH`RW5P`RW5P`RW5P`RW5P`RW5P`RW5P`RW5P`RW5P`RW5P`RW5P
-`RW5P`RW5P`RW5P`SSkY`SSkY`SSkY`SSkY`SSkY`SSkY`SSkY`SSkY`SSkY`SSkY`SSkY`SSkY
-`SSkY`SSkY`SSkY`SSkY`SSl>`?F*_`Pp]Y`Pp]Y`Pp]Y`Pp]Y`Pp]Y`Pp]Y`Pp]Y`Pl<drRLc$
-qr[qH!Moboeb;B/k5XiMV#UDD!o?4/rSIQ?rT41L]`<Q~>
-!s&AOec+G*63#g?k5RaHmK)H!oO7iRPi6'PK9Yk7!J?X%@KP*)3T"9XKE%0%k5S=Fc-87Xp@^4M
-K9Y/#s7QRM@eTLMraGkBraGkBraGkBraPnls'btLraL@uC1:Y!C1:YRs*J4%C1:Y)C1:Y)C1:Y)
-C1:Y1C1:Y1C1:Y1C1:Y1C1:Y:C1:Y:C1:Y:C1:Y:C1:Y:F(/UCF(/UCF(/UCF(/UKF(/UKF(/UK
-F(/UKF(/UKF(/UKF(/UKF(/UKF(/UKF(/UKF(/UKF(/UKF(/UKF(/T)S9&.KS9&.KS9&.KS9&.K
-S9&.KS9&.KS9&.KS9&.KS9&.KS9+[=!@e'Jeb\/"k5OcLV#UGE!8dH9s5s=K!MobpeH"J)63#g?
-63$*ImK(!$J,~>
-!s&APf)FD'5l]^?iWA717/lHPi\^:E!KEZ/D#oWen8/2cSa(%ng<rOLD%VX$R8E&G=\-id88\(o
-4Dg(Kghm)b"?^Ppp,r=k!-/!T!-S9X!-S9XJ!HRAD1-D@D1-D@D1Q\DD6EniD1utHD2ECPD2ECP
-D2i[TD38sXD38sXD3]B`D3]B`D3]B`D4,ZdD4,ZdD4,ZdD4,ZdD4,ZdD4PrhD4PrhD4PrhD4Prh
-D4PrhD4u5lD4u5lD4u5lD4u5lD5DMpD5DMpD5DMpD5DMpD(VT0D/H+pD/H+pD/H+pD/H+pD/H+p
-D/H+pD/H+pD/H+pD/H+pD/H+pD/H+prbVZmqYo(EgA]t.ir8*>l2dUTrmh)'q`t*Js5s=G!MTAh
-ec=G&5l]^>7/uELl2eHrJ,~>
-!s&AOec+G*63#g?k5RaHmK)HZoXt:Me`"1Bc.2<s!R90[]`RWaKAX?Sc2Z%QpA^%tk2q<0s8R/R
-c.1U_s8N4C^&S+RqRlmJrk/<Nrk8?^s1JEOrk/<Nrk/<Nrk3g<s2D[r`P&t0`P&t0`P&t0`P&t0
-`P&t0`P&t0`P&t8`P&t8`P&t8`P&t8`P&t8`P&t8`P&t8`P&t8`P&t8`P&t8`P&t8`P&t8`P&t8
-`P&t8`P&t8`P&t8`P&t8`P&t8`P&t8`P&t8`P&t8`P&t8`P&t8`P&t8`P&r*e]#58e]#58e]#58
-e]#58e]#58e]#58e]#58e]%O$!Fl*.eb\/"k5OcLV#UGE!8dH9s5s=K!MobpeH"J)63#g?63$*I
-mK(!$J,~>
-!W`8NrndT>rT=,Gs%<=Z!Tkj'=p"Et9&a"UpA[bT=p"Et9'TU[3T"!Qk05VQp@^4=;E6a@p@^4E
-pA[b@>6":!0j=;E1&G,S@fBO2@fBO6CA.["CAqCdC1:@MF(/<VF(3DV@U`MEHX^/^HX^/^HX^/^
-K48"fK48"fMeZF!MeZF!MeZF!MeZF!MeZF!MeZF!MeZF!P\OB*P\OB*P\OB*P\OB*P\OB*P\OB*
-P\OB*P\OB*S8)52S8)52S8)52S8)52S8)52S8)52S8)52S8)52/Y$QZ>+B>2>+B>2>+B>2>+B>2
->+B>2>+B>2>+B>2>+B>2>+B>2>+AbFs4,ZrhYZI6mKKEde^`O5pH\fArU'ibs4,ZVhY0;9k5OcL
-]`<Q~>
-!W`8Orn@<9ro*q?rBpbQmc$(qB`e#)=lO,spA.q^B`e#)=mB]%84;?L''@V)=n_\S@:_ttC%h6_
-C%hC+h.co_#<Z_op,m&'D>n5LD>n7!EG]E(FnYZ7H#780H#780I;N\4JT9,tEH,],KlLg@M/d6D
-M/d6DNHJrLO`bAPO`bAPQ$$eTQ$$eTQ$$eTQ$$eTR<<4XR<`L\R<`L\R<`L\SU"p`SU"p`SU"p`
-SU"p`SU"p`Tm:?dTm:?dTm:?dTm:?dTm:?dTm:?d3MC_4Bq]fdBq]fdBq]fdBq]fdBq]fdBq]fd
-Bq]fdBq]fdBq]fdBq]fdBq]fdBq]fdBq]5tqUX6rgA]t.ir8*>l3?[MqUX6OgAF566icBKl3?[M
-qUX6OgAF566icBKl2eHrJ,~>
-!W`8NrndT>rT=,Gs%<=Z!Tmk`[/^.+UuJc]rrAkb[/^.+V!>>eKAX$Kp?$Fds8R/A["F"<s8R/I
-s8SnN[/^./F0tuIF8N<E^&GA=^&GAA^&S,.^&GD=^&PJ>^&PHh`P(F%[(WiR`P&Xc`P&Xc`P&Xc
-`P&Xcc+UKkc+UKkc+UKkc+UKkc+UKkc+UKkc+UKkc+UKkc+UKkc+UKkc+UKkc+UKkc+UKkc+UKk
-e\/>se\/>se\/>se\/>se\/>se\/>se\/>se\/>se\/>se\/>se\/>se\/>s-.T]9[+2js[+2js
-[+2js[+2js[+2js[+2js[+2js[+2Nms4,ZrhYZI6mKKEde^`O5pH\fArU'ibs4,ZVhY0;9k5OcL
-]`<Q~>
-!<E/uhY]\>k5RaH9)n;[jsg1*#'8Z$mZ^VVrr2t>qGI]kk5YJLC/USis6cEV;ZGSWKC8c0;RHH'
-s)SY+s6c+L;Vp8_mf/eT[/U(0F*ldDs6bgA;CBH`K2PUKmS`cY;GqSms6c+LV#PL6`W(9_`P#/j
-hZ*#.;GuB.XPWnR"G?_q3Q;!t#\s)5;H!5^0spr[s)SV*s6c+L;Vp93hGX(Iqbdflk5YJLC/USi
-s6cEV;ZHG(0iI`=0iE)Ls6cCT;OlnLs6as8rr7FoSF6FFS5O**hVPX%;N(Qi;GqR>;GqR>;GqjN
-;GqjN;GqjN;Gr-V;Gr-V;Gr-V;GrE^;GrE^;GrE^;GrE^;GrE^;GrEf;GrEf;GrEf;Gr`o;Gr`o
-;Gr`o;Gr`o;Gr`o;Gr`o;Gr`o;Gr`o;Gr`o;Gr`o;Gr`o;Go66C/RroC/RroC/RroC/RroC/Rro
-C/RroC/RroC/RroC/RroC/RroC/RroC/QMSeb\/"k5=WKV"W@<hY0>6mK03Xec"A#5lg'GmK(!$
-J,~>
-!<E/ugAXA;6il<0r'^SQ!TGs5AHmkFqX1%g^Ae-4L&,[email protected],h"d/6LTk1t;
-s8Rc^hYQZ6AS'l\Om`(>A\S0Ds+LU4qZ#uKqIM&"s-7/,[dI`#qIO5lhYQZ6A[;>iA]k%,A^8/(
-L#2[oTk.fpijRkFAH\:uI7VZ_rs3oDqIO73p,p(gs8Rc]hYQZ6AS'l\[c1llqYOh3Woj0Xl?Qs@
-lMp.Lral-''0Kk"p,loChYQZ:AS%n(qZ#i3^Ae.]M5ok@m]'iDD;sQhk%0hXH"CQ<EFi^8EFi^<
-EFi^<EFi^@F_,-HF_,-HF_,-LF_,-LF_,-LF_,-LF_,-PF_,-PH"CQTH"CQTH"CQTH"CQXH"CQX
-H"CQXH"CQ\H"CQ\H"CQ\H"CQ\H"CQ\H"CQ\H"CQ\H"CQ\H"CPATm:3\Tm:3\Tm:3\Tm:3\Tm:3\
-Tm:3\Tm:3\Tm:3\Tm:3\Tm:3\Tm:3\Tm:3+p=B2rrndY6roX4Fs6]r^p=B5srBU6Jrp'OO!ho>=
-rS%69r'UPIrosRQ\c@6~>
-!<E/uhY]\>k5RaH9)n;[k$n4p#0$$1p=6P,rr2u;qQpX\pAb0d]sQ>`s7Y"B[/]h'c1_1f[,1f^
-s2>H8s7Y!M[.a4<pA`[MhZ!QT`<>W/s7X_6ZmY#9c*Xk7p9al"['[g?s7Y!MhZ(R%k5WE-k2s%i
-mf3"2[']Q#hY-oT"O6tBKBE15#eg9<[']l5F5Hors2>E7s7Y!M[.a4Mp9al"qm6a]pAb0d]sQ>`
-s7Y"B[/^.>F0tuIF0rpSs7Y!M[+4mMs7XFgrr7Gleb9%:e[3$'p@dYB[*AWH['[fc['[fc['[fc
-['[fc['\)k['\)k['\)k['\)k['\)k['\)k['\)k['\)k['\)k['\)k['\)k['\)k['\As['\As
-['\As['\As['\As['\As['\B&['\B&['\B&['\B&['\B&['VR<`O*#&`O*#&`O*#&`O*#&`O*#&
-`O*#&`O*#&`O*#&`O*#&`O*#&`O*#&`O'+Jeb\/"k5=WKV"W@<hY0>6mK03Xec"A#5lg'GmK(!$
-J,~>
-!<E/thYKP;9)e5ZhC8A#$tAquC;p3V@eTh"3D03I25L9/HYSd2SH$Q3^&O<p;YL.I[/]P[@eTh"
-9(q[f`W'+>pAa!Vs6`0^pA\#Nk5TL+F';35;CIJ']h22jUbVT:0k0kEC;p3VHiK!rmf/2;p3TF*
-mV9`@>#P(ohP;n*;BrRK5tYV[s&(TFp+]J=p+^%Ms&)J_mV9`@>#P(ohP;mgjtZg4I\d##HYSd2
-SH$Q3^&O<p;YKf=;YKf=@eT5)`W',;s5&*;PX/LHs&,*]`EKtTS6Ahas5'P+HiL0>F';I>F(/$F
-HX]lNHX]lNHX]lNK47_VK47_VK47_VMdfR^MdfR^MdfR^MeZ-fMeZ-fMeZ-fMeZ-fMeZ-fP\O)o
-=d3Z!;Ntoo;Ntoo;Ntoo;Ntoo;Ntoo;Ntoo;Ntoo;Ntoo;Ntoo;Ntoo;Ntoo;Ntoo;Ntoo;Ntoo
-;Ntoo;Ntoo;Ntoo;Ntoo;Ntoo;Ntoo;Ntoo;CV>9hYZI4mK'[email protected]!)!1W!MoGdhYTS=
-k5=WJ]`<Q~>
-!<E0!gAg"05kmbHmK)0$r*9_Fp?le7s(Q?DqHZ?dr*;1_s5JTPPuXOXb%\`mSR#Ops5LKel:c'g
-qHZqkmVTi@BjLH4ijSmP9PsM">sRQPH!tu0;#=NHOoN-l?0\FTp@^U_p?le7s(R2eO]CiLO]Ct'
-=n_9#_Z+=UpAa!L5lP%6])PT'EVB675kan6?2!tSD>*g3;"j<o_Z+=UpAa!L5j%&grEXlTs5JTP
-PuXOXb%\`mSR#Opp,lXSp,[email protected][5XC%hC/RK(QH_Z-<@?2"<TW^)F@Y#'CX?!Vkm
-?!W"q?!W/$?!W/$?!W;(?!WG,?!WG,?!WG0?!WS4?!WS4?!WS4?!WS4?!W_8?!W_8?!W_8?!W_8
-?!UU$EEuk<F^8:@F^8:@F^8:DF^8:DF^8:DF^8:DF^8:DF^8:DF^8:DF^8:DF^8:DF^8:DF^8:D
-F^8:DF^8:DF^8:DF^8:DF^8:DF^8:DF^8:DF^890pAN_EhYuO6k5OZFmK'$TrRq<<hVS7kroO8M
-lK\B:!MT5cgAg"05l="Mk5OZGmK'm!J,~>
-!<E/thYKP;9)e5ZhI?Da%(-'.Ut,L@[/^/aH_gS@2:_`pXIQYUc2ZXbec3UiXT/=gec5'%[/^/a
-KE(Y@ec2GHs8VN;s6c,Ys8S"(pA^qHUm.DHX=2'feXW`7c$TKjF0tu@Ut,L@`W*<@pA_Lqs/_Ib
-p8$7=UoaUrm`g+XX<ZU%K:K=Ks,1sus)Y:As)YRIs,2O0p8$7=UoaUrm`g+PmW8?.Ib"JdXIQYU
-c2ZXbec3UiXT/<AXT/<A[/]iqec2Gqs6ctY[#;$cs,48ak*4Erc*XSPs6e-Y`W*oI]sOlB]sOlB
-]sOlB`O)_J`O)_J`O)_J`O)_J`O)_J`O)_J`O)_J`O)_Jc*XRRc*XRRc+U3[c+U3[c+U3[c+U3[
-=j=X]XNeG[XNeG[XNeG[XNeG[XNeG[XNeG[XNeG[XNeG[XNeG[XNeG[XNeG[XNeG[XNeG[XNeG[
-XNeG[XNeG[XNeG[XNeG[XNeG[XNeG[XNeG[XCCo"hYZI4mK'[email protected]!)!1W!MoGdhYTS=
-k5=WJ]`<Q~>
-!<E/uhZ)a:62aFUmf2t]hC8@p$^C[e3K*oi62(",62O80mf-0>5s[Nns%5:Ts5l=6pA[E5p@^45
-p@^5*s.hZ5s+<W2s$8C5p+]25p+\kqs/]]/62F2$pA[F"s&(lNp+_g3UcFA5K1c0W;ZH0u>5pmQ
-s.hZ5s+<W2s$8A"r^nE[s"Qf3p@^4,p@^45p@^45p@^5*s.hZ5s+<W2s$8A"8hi(!8q6:/;DCI'
-3Tg?63ElIF3D0#=0hV050pM^63K*oimf-0>5s[Lsp@^6's%5:Ts5l=6pA[E58lG].8lA8RC0F5%
-F';1.F';1.HWj$6HWj$6HWj$6K3Cl>K47GFK47GFK47GFK47GFK47GFK47GFMdf:NMdf:NMdf:N
-Mdl]Y;2\mU8rI.N8rI.N8sEdW8sEdW8sEdW8sEdW8sEdW8sEdW8sEdW8sEdW8sEdW8sEdW8sEdW
-8sEdW8sEdW8sEdW8sEdW8sEdW8sEdW8sEfa8c^C7r8.>5qsOLX!MoGfh>fk=k5XiL9)e8Yp&Uu_
-r8%G9r':<Tr9aX[]`<Q~>
-!W`8Srnd\7qEtNYmdBZ:hDG.5$_@<t8<s43<VH,K<VooVmf-QX9MeFFs&DHus5m!XpA[fOp@^UO
-p@^V:s/JVTs+sbLs%G]Op,lLOp,l@;s/p?A:f[Bq-scE?:jr@P8G;a>Sc>]\Q2c\Ds2&@DlFq-8
-8=BLX8<s43<VH8[5Y1lW,L6<O<E]%h4B;+K4B_CO4B_CO4IQ5L8<s43<VH8[5Y,$C5lFi8mf-QX
-9MeFFs&DHus5m!Xp@^UOp@^V>s/Jb\s,$1D>sMCd9NCf[4QcZD6tQD\9Nh)c83g0hs2J&M=]p#]
-=]p/a=]p;i=]p;i=]pGm=]pSu=]pSu=]p`$=]p`$=]p`$=]p`$=]pl(=]pl(=]pl,=]pl,=]q#0
-=]q#0s&i3aEEQG0EEQG4EEQG4EEQG4EEQG4EEQG4EEQG4EEQG4EEQG4EEQG4EEQG4EEQG4EEQG4
-EEQG4EEQG4EEQG4EEQG4EEQG4EEQG4EEQG4EW0)C2"oYWrndY6roX4FrpKgW#,1bEg>:[Oro3q>
-s69SPrpKgW"/5GBgA]q/iql.DlMg2Qo""gO~>
-!<E/uhZ)a:62aFUmf2t]hI?DY$dJ^jK>mklSH&V1SGT*>pA^%tPa%+"s+>s*s6bf@s8R^us8RGA
-s8R/Zs2BW0s/_ajs+>[us*LRAs)X_(s2D(0PaqTGs8OC'^&O=Ts8R/bs2BW0s/_ajeXZ[5c)gql
-`W*o0`W*$0s8RFmMuKLsk5TLuV#UI9SH&V1V#UI9V#UI9`W*o0`W*$0s8RFmMkk]HrM4r:s,25g
-P`,88K7g9*mYdn@s)Y"9s)ZHb`Il/0XS2[PH^p=YV#UI9pA]btXT.^HV#UIAH^(W3eVgN)UpR5!
-UqNk*UqNk*UqNk*UqNk*UqO.2UrB^:UrB^:UrB^:UrB^:UrB^:UrB^:UrB^:UrB^:UrB^:UrB^:
-UrB_@Uf#+<Unku:Unku:Unl8BUnl8BUnl8BUnl8BUnl8BUnl8BUnl8BUnl8BUnl8BUnl8BUnl8B
-Unl8BUnl8BUnl8BUnl8BUnl8BUnl8BUnl8BrhKR(pAEeEk54THp&Uu_rS@N?qr[qH!)!7Ys7QJh
-pAEbIk57LF9)S)Yp:UHV~>
-!<E0!hYlU:62aFUmf)n\hC8@p!3H+u"IqdOp+cD9s8N*S62jLVrt7%P9)noG9(qs59(qs59(qs5
-XSi)3S3clB0hV050hV050hPoos8UVjq+;"$s+@]80gYO,0s(<Q$_0N5p5@2/k*4^WXSi)$S3clB
-1&OWX`W%Yb9(qs59(qs59(qs59(qs5XSi)$S3clB1&+B@rrFi?r_!4j%P^7As8OfGp@^45p@^5B
-r;Qkhs8OhP8q1%<p+cUI0gT:Ks"S!Vp+^#S9)ljj8kNi%8kO/.8kO/.8kO/.8kOG68kOG68kO_F
-8kO_F8kO_F8kO_F8kO_F8kO_F8kO_F8kP"N8kP"N8kP"N8kP"N8kP"N8kP"N8kP"N8kP=W8kP=W
-8kP=W8kP=W8kP=W8kP=W8kLn(@S07W@S07W@S07W@S07W@S07W@S07W@S07W@S07W@S07W@S07W
-@S07W@S07W8h'K4h>jAL62jIXV!d[Mp&Uu_rS@N?r9""H!_VnKrq6AgpANhJk57OE9)e8Yp&Vi,
-J,~>
-!<E0!hYuL7k57UK8FGpFnc@H$r)j$&r;Qnj9_S0BqH<ju!C0Za=VU`44B5Pas$0`\p,l@Kp,lLO
-p,oMUrtCqsp@^UKp@^UOp@^UOEQ8%Yg3rd"$GQOs]&#PLp@^VOr;R.q9\T&sf"U:7i]OCArrnre
-p@^UKrE0i[s$0^ip@^UOp@^UOp@^UOp@^VOr;Qqk9_S0B<V]etrrGAbr`Kg/s#a:as8P>ep@^UO
-p@^VOr;V8;s8P>i?!1<Ap@^WFs#a:us8P?(p@^Uc@9roQ86K)@AQ`/aAQ`/aBj"SiBj"SmBj"Sq
-D-:"uD-:#$D-:#$D-:#$D-:#$D-:#(D-:#(D-:#(EEQG,EEQG0EEQG0EEQG0EEQG0EEQG4EEQG4
-EEQG4EEQG4F]hk8F]hj0R<;Y8R<;Y8R<;Y8R<;Y8R<;Y8R<;Y8R<;Y8R<;Y8R<;Y8R<;Y8R<;Y8
-R<;Y8R<;Y8R<;Y8R9;B;gA]q/SbYYTV=*dNncGNUgA]q17,m5*k5OWI8FGpFncGNUgA]q/iqZ"A
-mf2hY\c@6~>
-!<E0!hYlU:62aFUmf)n\hI?DY!7h#I"ML'"s)\%4s8N+@SGo>art9CCV#UIAV#UI9V#UI9V#UI9
-eboF\]p/QsF/8j9F/8j9F/61ns8VN#q4nASs/b)FF.E:1F4L3g$b_emp9`u,m_/%0eboFM]p/Qs
-F8VgJk5TLuV#UI9V#UI9V#UI9V#UI9eboFM]p/QsF82R2rrI22rhTSo%We/9s8RGAs8R/9s8R/j
-r;Ql4s8R0=UjoKGs)\5?F.BW;s*M-Qs)YQKV#SttUnkB!Unk]*Unk]*Unk]*Unk]*Unk]*Unku:
-Unku:Unku:Unku:Unku:Unku:Unku:Unku:Unku:Unku:Unku:Unku:Unku:Unku:Unl8BUnl8B
-Unl8BUnl8BUnl8BUnl8BUnffk[%sMB[%sMB[%sMB[%sMB[%sMB[%sMB[%sMB[%sMB[%sMB[%sMB
-[%sMB[%sMBUgj&rh>jAL62jIXV!d[Mp&Uu_rS@N?r9""H!_VnKrq6AgpANhJk57OE9)e8Yp&Vi,
-J,~>
-!s&AXhYZI69)n>Xp&X#!r(7$Ts.oTJ"$-)K1&=KDmf-Jh8f$Rh8kNRmjtTL%p+]25p+]25p+_g3
-V#<"]3VN/$9(qs59(qs58kMBAV#TjKqFV0;s4-h$0hV050pM^6r@n^@XT..QPlK:00pM^6r@nC7
-p@^6=8cc$nr_!4a%l$]Mp+]25p+]25p+_g3V#<"M3VN/$pdtVUs'#@n''B3d8n.h_0hV050hV05
-0pM^6r@nB9s'#CoIp,bDp+b_08m6!0jtTd-p+]H;@fN5a8nqO%8on0.8on0.8on0.8pa`68pa`6
-8qUSF8qUSF8qUSF8qUSF8qUSF8qUSF8qUSF8rI.N8rI.N8rI.N8rI.N8rI.N8rI.N8rI.N8sEdW
-8sEdW8sF'_8sF'_8sF'_8sF'_8i2cI8kP=_8kP=_8kP=_8kP=_8kP=_8kP=_8kP=_8kP=_8kP=_
-8kP=_8kP=_8kP=_8h'K5h>l^962X=Tmeuh[V"XfE!Tl]Hk5F]K9()ZO!MoGgh>l^962X=Tmf)n\
-]`<Q~>
-!s&AXhYuO6k5IaM8FGpFncJO=2#L>TRK'Gg49J.Jp,r1O!p]esrDaWqs&E'5s5lFDp@^UKp@^UK
-p@^V:s/u;_'1hij4B;+K4B;+K4B5BX=f)/`;#40#IK.adPsA@Cp,ncCY5LHk8?W!HV3V)7Y!AET
-Y5LHb8G;a>r)Ed's8H$up('8cp@^UKp@^UKp@^V:s/u;_"%`.Z4SVnXlMkGo<>+Ho<E3c5jucZ;
-p,l@Kp,ncCY5LJ4lMkEu<E3I1p@^W6s&EcQs5lFLp@^UW<GDK55ZMr8<E4<U<E4HY<E4HY<E4Ta
-<E4`e<E4li<E4li<E4li<E4li<E5#q<E5#q<E5#q<E5#q<E5/u<E5/u<E5/u<E5/u<E5<$<E5<$
-<E5<(<E5H,<E5H,<E5H,<E5H,s&D%HEE-#,EE-#,EE-#,EE-#,EE-#,EE-#,EE-#,EE-#,EE-#,
-EE-#,EE-#,EE-#,EE-#,EE+jdrn[Y7q*b6R!:KjW!qr>Yrn[_97,n4.rosRQ8FHKJ!qr>Yrn[Y7
-q*b6R!:KjW!P/8]~>
-!s&AXhYZI69)n>Xp&X#Zr1!i-s2FqX",$XRF8DC.pA^BUS/1huK:K%CmW4ous)X_1s)X_1s)Z0Z
-`VjikKE(smSH&V1SH&V1S=Gh.`W,XrqO@u$s5s$gH^t-9F2e0urGrC"ec4dN[/]:5Hc?$(rGr'n
-s8R0<S/0ZTK:JJ3s)X_1s)X_1s)X_1s)Z0Z`Vji[KE(smpm_EZs-3JP'))?XS?2bYF.E:1F.E:1
-F2e0urGr&6s-3MQJ#&V7s)[o6K<2H[mW53(s)Y!+XT-7dS?/NVS@#)^S@#)^S@#)^S@#)^S@u"o
-S@u"oS@u"oS@u"oS@u"oS@u"oS@u"oS@u"oS@u"oS@u"oS@u"oSAhS"SAhS"SAhS"SAhS"SAhS"
-SAhS"SAhS"SAhS"SAhS"SAhS"S2A3dS=IR"S=IR"S=IR"S=IR"S=IR"S=IR"S=IR"S=IR"S=IR"
-S=IR"S=IR"S=IR"S7;3kh>l^962X=Tmeuh[V"XfE!Tl]Hk5F]K9()ZO!MoGgh>l^962X=Tmf)n\
-]`<Q~>
-!W`8Wqr[qHs%<=Zr:U0J.JudG;XXRTH^'.Tk5T0oqar`9s5o5dP[^0_]kYOdM_Ritp+]25p+]2%
-s(Z$2s."G#K1bk20hV050hUU.C/V-cC4lQC1&4Eemf3;Q3D0#=0iIH>S9pKQ8pgU<@UfB;C,o2[
-s."G#K1bk21&OWfF8pSQ9(qs59(qs59(qs59'6.g@da8dH^'.Tp@^459'5:68q*<1k)4SN@\!J3
-C;p420hV050hV050iIH>S:d&YSH%`0H^nhCk5T1ls1NKms,/U(p@^458u2Jr3GM_i8nqO%8on0.
-8on0.8pa`68pa`68qUSF8qUSF8qUSF8qUSF8qUSF8qUSF8qUSF8rI.N8rI.N8rI.N8rI.N8mR?a
-8kP"N8kP"N8kP=W8kP=W8kP=_8kP=_8kP=_8kP=_8kP=_8kP=_8kP=_8kP=_8kP=_8kP=_8kP=_
-8kP=_8kP=_8kP=_8kP=_8kP=_8kP=_8kLQ+hVRDWrB^<Qr:U>jp>4Zgk!B"/r9aPWr:U;ip>4Zg
-k5@UGmeocVp&Vi,J,~>
-!W`8Wro3q>s69\S8FGpFo)JCag,/_-$XrK"SV<>c<Ta=(@Ja%^U&X8;JXL5Cs2&p$s-5]Hp@^UK
-p@^[email protected]&/N7p,l@Kp,l@;s)hbUM04[ThE:U6,jPF09Lr1Wp,ldOqON>*M,f90s)E&Y
-s*7"@meWK.Q&/N7p,r7Q,(9KB:f[5_4B;+K4B;+K4B:PDF`$RCSV<>c<VH,K<E82Dr)J3>s5oGp
-R;&5l_KF$$Prr(?p,l@Kp,lpSqONV6M4st3Ob'3C<Ta=(Y5c@eb5[_l<VH,K<E5mqD+&MT<E4<U
-<E4<U<E4HY<E4Ta<E4`e<E4li<E4li<E4li<E4li<E5#q<E5#q<E5#q<E5#q<E5/u<E5/u<E5/u
-<E3=eD,jT$D,jT$EE-#(EE-#(EE-#,EE-#,EE-#,EE-#,EE-#,EE-#,EE-#,EE-#,EE-#,EE-#,
-EE-#,EE-#,EE-#,EE-#,EE-#,EE-#,EE-#,EE-!qo%r6_iqc(B8H/2[p'.5]hVR8O7/l?JlMp8P
-8H/2[p'%/\hVR8OrC$\N!(?fWrpg-a\c@6~>
-!W`8Wqr[qHs%<=Zr:U0J@f2`(V"Xi-]u@[TpA^YYqj]Ogs6dS-`N7&YeZ@p5[!S>Cs)X_1s)X_(
-s.$1as2D[j]q#-&F.E:1F.Dt(S>=]KXM+YrHhj0WpAb/FMk'hIF/8O0`P'7(SA"t&S>?2bUk>K:
-s2D[j]q#-&F8VOP[/ZqdSH&V1SH&V1SH&V1SG)uQXS2\5]u@[Ts8R/1SF6+KS:8`_m_-!HXMt4i
-XQKPiH^t-9F.E:1F/8O0`P'7(c2[4F[*>\BpA^Z-s4+L=s0R-Cs8R/1SB_(uK<1l=S@#)^S@#)^
-S@#)^S@#)^S@u"oS@u"oS@u"oS@u"oS@u"oS@u"oS@u"oS@u"oS@u"oS@u"oS@u"oS@u"oS6a+8
-S=IR"S=IR"S=IR"S=IR"S=IR"S=IR"S=IR"S=IR"S=IR"S=IR"S=IR"S=IR"S=IR"S=IR"S=IR"
-S=IR"S=IR"S=IR"S=IR"S=IR"S=IR"S=F'^hVRDWrB^<Qr:U>jp>4Zgk!B"/r9aPWr:U;ip>4Zg
-k5@UGmeocVp&Vi,J,~>
-!<E/sk54TDp&X#!qaq3)^%VKoMa<9ps(_C&1lL5js5mcVPii#.PVG0jp@^45p@^45Mt[0c>.sY0
-mYaC)p+]25p+]0tpA\mPpAaj*;DIu>,cq$b0gSG*p+]0K^%VKoMa:8@s#ECFs#EA;@_ML8mYaC)
-p+cG:s4&5X9(qs59(qs59(qs58rNECC0J=Es6be2p@^459(qs5r(;ErhZ*W<@R67@s5oP#3D0#=
-0hV050hPogpAaQ=8rMR+s5mcVPkP,lPii#.S2!#rp@^45C>RJq>#IsbC0F5%F';1.F';1.HWj$6
-HWj$6HX]T>K47GFK47GFK47GFK47GFK47GFK47GFK47GFMdf:NMdf:NMdf:NMdl]Y;2\mU8rI.N
-8rI.N8sEdW8sF'_8sF'_8sF'_8sF'_8sF'_8sF'_8sF'_8sF'_8sF'_8sF'_8sF'_8sF'_8sF'_
-8sF'_8sF'_8sF'_8sF)i8cgI0hYuX=Ud7<D8cYsjp&_&XhYu[:62F4Op&_&XhYlU:62g6O9)SA`
-]`<Q~>
-!<E0!ir8*>lMg5No)A=`g,/\'$YdKOs6>S7NUlpc9`%XCQ/;Q;iakfOk5X_34@E$>p,l1Fp,l02
-o(m??_Y4#pNC`d:4AbbF4A_%.qJj[Ks7XT<5l"5%Y5cL(9MkHV4A]b/pAaE;86Puh6qmIW6qC-g
-_Y4#pNC`d:4SqtTef[L[p@^UFp@^UFp@^UFNUlpcBu9TDlA\@.p,l/Jp@^WH:k"\ds8(_d9UY&C
-lBOJ";"jTF;"jTF:hdf?s6>S?Q/;Q;iakfOo(m?sk5X_;4@E$>p,l/ghUXf#>u4@?>u4@?@8KdG
-@8KdK@8KdOAPc3SAPc3WAPc3WBi%W_Bi%W_Bi%W_Bi%W_Bi%WcBi%WcBi%WcBi%WcBi%WgD?!F0
-O_mokO_mokO_mokQ#0>oQ#0>oQ#0>oQ#0>oQ#0>oQ#0>oQ#0>oQ#0>oQ#0>oQ#0>oQ#0>oQ#0>o
-Q#0>oQ#0>oQ#0>oQ#0>oQ#0>oQ#6Ls!]9?%ro*pOr'^NT!ikh^rq6Demb[s&qaCBRs760_!ho&=
-ro+"A6q%%>!q&TMrpp*_!P/8]~>
-!<E/sk54TDp&X#ZqihG`eb9%:[#;Wks.oLU1pl]Ns6c,0^$bpoZu^kas8R/)s8R/)^%VK%Ut,2=
-p9]bXs)XG)s)XF<pA^rNpAb0LMgP8a,gHA>F-Mphs)XF#eb9%:[#:ISs*K\(s*KZgUt,2=p9]bX
-s)\(%s5kG^PlLc)PlLc)PlLc)PeHejUnlQ7s7WgXs8R/)PlLc)r02Z;mf3=TP`*6Cs7Wg@K9ZE9
-F-Q_)F-NKNpAainMmVpPs6c,0^%VK%`U<d"]lSgjs8R/)V!dAdS=Gh.XIPN>XIPN>XIPN>XIPN>
-[%rqN[%rqN[%rqN[%rqN[%rqN[%rqN[%rqN]qgmW]qgmW]qgmW]qgmW]qgmW]qk[m;8&ciPeElW
-PeElWPeElWPeElWPeElWPeElWPeElWPeElWPeElWPeElWPeElWPeElWPeElWPeElWPeElWPeElW
-PeElWPeElWPeElWPeEmlPQG=^hYuX=Ud7<D8cYsjp&_&XhYu[:62F4Op&_&XhYlU:62g6O9)SA`
-]`<Q~>
-!<E/tk54TDp&b9E.JcX;5rnp!"$oOF1&CnOF%SIk0`jX53W:`53W;YN1&jlG1&jiL5qt)[5rnp!%
-RE]A0hP%m0hP&(0eksSr\4C5qYp_?8kM)u3W;YN1&jiH5rnp!#XM'T0el9m0erZ"!C8aF0`s^60
-erPt(1Q]r8kLfm8kLfm8kLfm8kMB(0gS)cr\4L@8hi("9)gXC8cUmM0`jX53W:`53W;YN1&jlG1
-&acF3W:`75tX091&k,S5qt)d3W:a_3D*aY0em.5p.@>C8kNi%8kO/.8kO/.8kO/.8kOG68kOG>8
-kO_F8kO_F8kO_F8kO_F8kO_F8kO_F8kO_F8kP"N8kP"N8kP"N8kP"N8kP"N8kP"N8kP"N8kP=W8
-kP=_8kP=_8kP=_8kP=_8kP=_8kP=_8kP=_8kP=_s%4Z'C._*_C._*_C._*_C._*_C._*_C._*_C
-._*_C._*_C._*_8h'3*k54TDp&b8imec/Dmec\Zs.o)[k54TDp&Vi,J,~>
-!s&A\ir8*>lMg5No)A=aqURM":]X6Tr]C9R:e3_FrrRIB8GtXP9Me.V49.eK;#`ZX;#`ZX:^'BP
-4A8F6r]CZ]:cpj::cpj::e3]29L/S>!'pD\"aNp@6p*a6;#`ZX:]X6Tr]CHW:f'8::f'8:r_NVh
-5lNkJ85ME2qbS&BnsN<N4?QG:4?QG:4?QG:83B".9L/S>"%Z6N4T81W4SqqT8GtXP9Me.V49.eK
-;#`ZX;#`ZW:]Nc[49J,N83m/:Ip#cB4?QG.4?Pks:ha&p4Dgqc>tA6t:iTc;:j$2C:jHJG:jlbK
-:jlnO:k<1S:k`IW:k`IW:k`U[:l/m_:l/m_:l/m_:lT0c:lT0c:lT0c:lT0c:m#Tk:m#Tk:m#Tk
-:m#Tk:mGlo:mGlo:mGlo:mGlo:mGlo:mGlo:c"AR:f*Eo:f*Eo:f*Eo:f*Eo:f*Eo:f*Eo:f*Eo
-:f*Eo:f*Eo:f*Eo:f*Eo:f*ER2"(A&roX4FrpKdVrq6EiU$hp>roX4FrpKdVrq6EiU$hp>roX4F
-rpKdVrq6B(!.Y~>
-!<E/tk54TDp&b9E@eko^HiA'gK8YA'qYpVmMhD"M"+,raKDoolKDpf/F8q0uF8q.%K6)*dMgPGE%
-YK[\F,PrtF,Ps/F)ut\rc8'dqYp_pMi2q'HiAs'F8h'tHiA'lK8YY/F,PrtF8_!sHiA'gK8Xelq
-hl5[p:ZBBF*!7tF*!7tF*!7tK6)*dMgPGE"+uMQF8h*tF8LjqKDoooH]*f7rc8'lrepets,6nur
-egc'rc8O$Mh?@tF*ih0K6)*lKDoqAK8Z7aF*!kjp5=9^Mi4BqMi4BqMi4BqMi4[,Mi4[,Mi4[,M
-i4[,Mi4[,Mi4s4Mi4s4Mi4s4Mi4s4Mi4s4Mi4s4Mi4s4Mi4s4Mi4s4Mi4s4Mi4s4Mi59=Mi59=M
-i59=Mi59=Mi59=Mi59=Mi59=Mi59=Mi59=Mi59=s,/8<S;W<=S;W<=S;W<=S;W<=S;W<=S;W<=S
-;W<=S;W<=S;W<=Mdl,Ok54TDp&b8imec/Dmec\Zs.o)[k54TDp&Vi,J,~>
-!<E/uk54TDpAb-neLBuRqCqt1bsD1\!'/Rq!b.Z[_Ee/or]pNVr]q5r8jPa@8jPaH8jPaH8jPaH
-8t8d6r]u$C;F*T`;F*T`;F*Ti;F*Ti;F*Ti>!YH$>!YH$>!YH$>!YH$>!YH$>!YH,>!YH,>!YH,
->!YH,>!YH,>!YH,>!YH,>!YH4>!YH4@R3;<@R3;<@R3;<@R3;<@R3;<@R3;<@R3;<@R3;<@R3;<
-@R3;<@R3;<@R3;<@R3:"Mdet<Mdet<Mdet<Mdet<Mdet<Mdet<Mdet$mel5Emec_XrrJq`r9!nE
-qtC'i!Mo/]k54TDp&b9-!.Y~>
-!W`8[roX4FrpKdVrq?Bg!S0*t:]OMl49/(#:]OMl49/(*:]b@%8B+I+<W5gE=]J9p>ua]t>ua]t
-@9HE'AQ_i+Bj"8/D-`uH5Zpo[EEuC;F^\*CH!sNGI:5rKI:Z5OJRqYSKk4(WKk4(WKkX@[M.od_
-M.od_M.od_M.od_NG23cNG23cNG23cO_IWgO_mokO_mokO_mokQ#0>oQ#0>oQ#0>oQ#0>o5*]t]
-:mGlo:mGlo:mGlo:mGlo:mGlo:mGlo:mGlo:mGlo:mGlo:mGlo:mGlo:mGlo:mGlo:mGlo2"'A_
-roX4FrpKdVrq?Bg"/5/Bir8*>lMg5No)A@_q?*GZio9t"rp'LNrpp'^!rBJ.J,~>
-!<E/uk54TDpAb-neRJ$+qJuXhc&;F>!/&g[!h?rV_M\DYregc@repf@s,6oAs,.;UP`(HiP`(Hi
-Pf8l.rel9%P`(HqP`(HqP`(I$S;W<,S;W<,S;W<,S;W<,S;W<4S;W<4S;W<4S;W<4S;W<4S;W<4
-S;W<4S;W<4S;W<4S;W<4S;W<4S;W<=S;W<=S;W<=S;W<=S;W<=S;W<=S;W<=S;W<=S;W<=S;W<=
-S;W<=S;W<=S;W<=S;W:F]pt"=]pt"=]pt"=]pt"=]pt"=]pt"=]pt!imel5Emec_XrrJq`r9!nE
-qtC'i!Mo/]k54TDp&b9-!.Y~>
-!<E0!k54TDpAY'meL?&8r]pNE_a+8pr]pNVr]q5r8jPa@8jPa@8jPaH8jPaH8jPa8r]u$C;F*T`
-;F*T`;F*T`;F*Ti;F*Ti>!YH$>!YH$>!YH$>!YH$>!YH$>!YH,>!YH,>!YH,>!YH,>!YH,>!YH,
->!YH,>!YH4>!YH4@R3;<@R3;<@R3;<@R3;<@R3;<@R3;<@R3;<@R3;<@R3;<@R3;<@R3;<@R3;<
-@R3:#Mdet<Mdet<Mdet<Mdet<Mdet<Mdet<Mdet<.IR/sqsO@Trr3"pmeu;Fmec_WrrJq`rT="F
-qtC'i!PJJ`~>
-!<E0!k5OZFmf)eVpAXmhehhqOs%EGa7)qt$;#X.<<DZ@_<DZ@_=\qdc>uaQl@9#upAQ;DtBj",'
-:fU1_D-9P+EEu73F^7[7H!O*;H!sB?I:[email protected]@S
-M.K@SNFbdWNG2'[NG2'[NG2'[O_IK_O_IK_O_IK_Q"`ocQ"`oc5*]hU9U0<c9U0<c9U0<c9U0<c
-9U0<c9U0<c9U0<c9U0<c9U0<c9U0<c9U0<c9U0<c9U0<c9U0<c9Jl1sroX4FrpKdVrq??f!ho&A
-roX4FrpKdVrq??f!ho&AroX4FrpKdVrq?Bg!P/8]~>
-!<E0!k54TDpAY'meRF)^rdt2t_h.rIrdt3/re(6/s+>fcMh?YHMh?YHMh?YHMh?Y?Mh?YPMh?YP
-Mh?YPP_4UaP_4UaP_4UaP_4UiP_4UiP_4UiP_4UiP_4UiP_4UiP_4UiP_4UiP_4UiP_4UiP_4Uq
-P_4UqP_4UqP_4UqP_4UqS:cI$S:cI$S:cI$S:cI$S:cI$S:cI$S:cGK[%)c$[%)c$[%)c$[%)c$
-[%)c$[%)c$[%)c$[%)c$[%)c$[%)c$[%)c$[%)c$@da3WqsO@Trr3"pmeu;Fmec_WrrJq`rT="F
-qtC'i!PJJ`~>
-!W`8_qsO@Tr;QfJ.=k*B8qT_<.IQ?\qsO@Tr;QkpmcN[/mec_Urr](bk2uR/qtC!g!PJJ`~>
-!W`8_rp'LNrpp'^rqcZp!R`fU=b9e.<<G)Ck2u[.rpKdVrq??fs8N1plK77.lMg5No)A@^qZ$Qt
-U$Ce&rp'LNrpp'^rqZ]r\c@6~>
-!W`8_qsO@Tr;QfJ@Y(>+Uk>HF@d`C@qsO@Tr;QkpmcN[/mec_Urr](bk2uR/qtC!g!PJJ`~>
-!!)DN!%EI)JI$l6!%I<"!2T"H!2T"H!!%N~>
-!!)DK!&T64JI$l6!&X)*!28eB!28eB!!%N~>
-!!)DN!+LKbJI$l6!+P>[!2T"H!2T"H!!%N~>
-!<E0!joD3.s+13$s1/.5V#TT>]`<Q~>
-!<E0!joD*+s+13$s1/.5U&X9;\c@6~>
-!<E0!joD3.s+13$s1/.5V#TT>]`<Q~>
-!<E0!joD3.s+13$s1847K;AP0k.LbF~>
-!<E0!joD*+s+13$s1847JYE,+k.1PC~>
-!<E0!joD3.s+13$s1847K;AP0k.LbF~>
-!<E0!joV@Ys+/^OeUc8aec17*V#TT>]`<Q~>
-!<E0!joV7Vs+/mTg4@tkgAc^-U&X9;\c@6~>
-!<E0!joV@Ys+/^OeUc8aec17*V#TT>]`<Q~>
-!<E0!joV@Ys+/^OeUc8aec17*V#TT>]`<Q~>
-!<E0!joV7Vs+/mTg4@tkgAc^-U&X9;\c@6~>
-!<E0!joV@Ys+/^OeUc8aec17*V#TT>]`<Q~>
-!<E0!joV@Ys+/^OeUc8aec17*V#TT>]`<Q~>
-!<E0!joV7Vs+/mTg4@tkgAc^-U&X9;\c@6~>
-!<E0!joV@Ys+/^OeUc8aec17*V#TT>]`<Q~>
-!<E0!joV@Ys+/^OeUc8aec17*V#TT>]`<Q~>
-!<E0!joV7Vs+/mTg4@tkgAc^-U&X9;\c@6~>
-!<E0!joV@Ys+/^OeUc8aec17*V#TT>]`<Q~>
-!<E0!joV@Ys+/^OeUc8aec17*V#TT>]`<Q~>
-!<E0!joV7Vs+/mTg4@tkgAc^-U&X9;\c@6~>
-!<E0!joV@Ys+/^OeUc8aec17*V#TT>]`<Q~>
-!<E0!joV@Ys+/^OeUc8aec17*V#TT>]`<Q~>
-!<E0!joV7Vs+/mTg4@tkgAc^-U&X9;\c@6~>
-!<E0!joV@Ys+/^OeUc8aec17*V#TT>]`<Q~>
-!<E0!joV@Ys+/^OeUc8aec17*V#TT>]`<Q~>
-!<E0!joV7Vs+/mTg4@tkgAc^-U&X9;\c@6~>
-!<E0!joV@Ys+/^OeUc8aec17*V#TT>]`<Q~>
-!<E0!joV@Ys8(:A!!:[N!:889!<1OK!!:[N!;tCI!:/25!9Mc2!:SJ6!!^sR!7fU"!.i[Oe^)eG
-K*A(Nk2s>WJ,~>
-!<E0!joV7Vs8(IF!!:jS!:8G>!<1^P!!:jS!;tRN!:/A:!9Mr7!:SY;!!_-W!8?-,!.ijTg<\LQ
-JH_bIk2s5TJ,~>
-!<E0!joV@Ys8(:A!!:[N!:889!<1OK!!:[N!;tCI!:/25!9Mc2!:SJ6!!^sR!7fU"!.i[Oe^)eG
-K*A(Nk2s>WJ,~>
-!<E0!joV@Ys8(:G!;b7G!:889!<1OK!;Y1F!:889!<1OK!9Vi3!:SJ<!;b7G!<:UL!.i[Oe^)eG
-K*A(Nk2s>WJ,~>
-!<E0!joV7Vs8(IL!;bFL!:8G>!<1^P!;Y@K!:8G>!<1^P!9W#8!:SYA!;bFL!<:dQ!.ijTg<\LQ
-JH_bIk2s5TJ,~>
-!<E0!joV@Ys8(:G!;b7G!:889!<1OK!;Y1F!:889!<1OK!9Vi3!:SJ<!;b7G!<:UL!.i[Oe^)eG
-K*A(Nk2s>WJ,~>
-!<E0!joV@Ys8(:G!<(IJ!!LgP!7fWu!:n\?!<1OK!"7<W!7fU"!7_&Le^aTuo%!a?rmh#Ks4.&J
-rmgrIs4.,L"4[AOeboLJec,UNeGoU?ec,XJec,UOeGoU"r;clJr;clJrr</O!!(RJ!.i[Oe`,-Z
-K*A(Nk2s>WJ,~>
-!<E0!joV7Vs8(IL!<(XO!!M!U!8?0*!:nkD!<1^P!"7K\!8?-,!87DQg=lK*o%O*Drn@APs4[DO
-rn@;Ns4[JQ"53_TgAM$OgA_-Sg&M-DgA_0OgA_-Tg&M-,r;clOr;clOrr</T!!(aO!.ijTg>^id
-JH_bIk2s5TJ,~>
-!<E0!joV@Ys8(:G!<(IJ!!LgP!7fWu!:n\?!<1OK!"7<W!7fU"!7_&Le^aTuo%!a?rmh#Ks4.&J
-rmgrIs4.,L"4[AOeboLJec,UNeGoU?ec,XJec,UOeGoU"r;clJr;clJrr</O!!(RJ!.i[Oe`,-Z
-K*A(Nk2s>WJ,~>
-!<E0!joV@Ys8(:G!<(IJ!"%0U!7_&Le^XX"o@<j@rmh#K#1W\ReGoU"rW!/Q!!(R"!!)T?rW)oI
-rrE)Lrr<;S!!(R"!!(RG!<:UL!!(RK!!:[N!;"b@!<(IJ!"[T[!7fU"!7fU"!7fU"!7goGs4.,L
-J^o>%j440^"f21\k.LbF~>
-!<E0!joV7Vs8(IL!<(XO!"%?Z!87DQg=cN,o@j3Ern@AP#20%Wg&M-,rW!/V!!(a,!!)TDrW)oN
-rrE)Qrr<;X!!(a,!!(aL!<:dQ!!(aP!!:jS!;"qE!<(XO!"[c`!8?-,!8?-,!8?-,!8@8Ls4[JQ
-J_G\/j4aNa"ektYk.1PC~>
-!<E0!joV@Ys8(:G!<(IJ!"%0U!7_&Le^XX"o@<j@rmh#K#1W\ReGoU"rW!/Q!!(R"!!)T?rW)oI
-rrE)Lrr<;S!!(R"!!(RG!<:UL!!(RK!!:[N!;"b@!<(IJ!"[T[!7fU"!7fU"!7fU"!7goGs4.,L
-J^o>%j440^"f21\k.LbF~>
-!<E0!joV@Ys8(:D!"@BX!7_&LeGoU"eGoU@ebT7WeGoU"!!(R"!!(OL!7fU"!:\P<!<:UL!<:UL
-!;tCI!!(RK!<:UL!;tCI!<:UL!;"b=!#!f^!7_&Le^XX"e^XX"e^XX"ec#RKec#Q"eUc9/ec17*
-V#TT>]`<Q~>
-!<E0!joV7Vs8(II!"@Q]!87DQg&M-,g&M-EgA1d\g&M-,!!(a,!!(^Q!8?-,!:\_A!<:dQ!<:dQ
-!;tRN!!(aP!<:dQ!;tRN!<:dQ!;"qB!#!uc!87DQg=cN,g=cN,g=cN,gAV*PgAV)'g4@u9gAc^-
-U&X9;\c@6~>
-!<E0!joV@Ys8(:D!"@BX!7_&LeGoU"eGoU@ebT7WeGoU"!!(R"!!(OL!7fU"!:\P<!<:UL!<:UL
-!;tCI!!(RK!<:UL!;tCI!<:UL!;"b=!#!f^!7_&Le^XX"e^XX"e^XX"ec#RKec#Q"eUc9/ec17*
-V#TT>]`<Q~>
-!<E0!joV@Ys8(:G!<(IJ!!CaO!7grHo@<j@rmh#K$Io+VeGoU"eGoU"qZ-*8rVurKqZ-ZHqu?fK
-!!*#KrrDuIrrE)LrrDZ@rrE#Jrr<>T!!(R"!!(R"qZ$]J!!)rIrW%N"J^rc1s+:KNs5rIW!.Y~>
-!<E0!joV7Vs8(IL!<(XO!!CpT!8@;Mo@j3Ern@AP$JGI[g&M-,g&M-,qZ-*=rVurPqZ-ZMqu?fP
-!!*#PrrDuNrrE)QrrDZErrE#Orr<>Y!!(a,!!(a,qZ$]O!!)rNrW%N'J_K,;s+(?Is5rIT!.Y~>
-!<E0!joV@Ys8(:G!<(IJ!!CaO!7grHo@<j@rmh#K$Io+VeGoU"eGoU"qZ-*8rVurKqZ-ZHqu?fK
-!!*#KrrDuIrrE)LrrDZ@rrE#Jrr<>T!!(R"!!(R"qZ$]J!!)rIrW%N"J^rc1s+:KNs5rIW!.Y~>
-!<E0!joV@Ys8(:G!<(IJ!!UmQ!7_&Ln(%F<rmh#K%+P=XeGoU"eGoU"!!)K<rrE&Krr<,N!!)rI
-rrE)Lrr<,N!!*#KrrDuIrrE)LrrDZ@rrE#Jrr<DV!!(R"!!(R"!!)rIrrDrHrW%N"J^rf2s+:KN
-s5rIW!.Y~>
-!<E0!joV7Vs8(IL!<(XO!!V'V!87DQn(RdArn@AP%,([]g&M-,g&M-,!!)KArrE&Prr<,S!!)rN
-rrE)Qrr<,S!!*#PrrDuNrrE)QrrDZErrE#Orr<D[!!(a,!!(a,!!)rNrrDrMrW%N'J_K/<s+(?I
-s5rIT!.Y~>
-!<E0!joV@Ys8(:G!<(IJ!!UmQ!7_&Ln(%F<rmh#K%+P=XeGoU"eGoU"!!)K<rrE&Krr<,N!!)rI
-rrE)Lrr<,N!!*#KrrDuIrrE)LrrDZ@rrE#Jrr<DV!!(R"!!(R"!!)rIrrDrHrW%N"J^rf2s+:KN
-s5rIW!.Y~>
-!<E0!joV@Ys8(:G!<(IJ!"%0U!7_&Le^XX"o@<j@rmh#K#1W\ReGoU"rW!/Q!!(R"!!)W@rrE&K
-rr<V\!!(R"!!(OL!7fU"!7_&Lrmh#Ks4.,L#1W\Re^XX"o@<j@rRLoJ#LreSe^XX"ec#RKec,UN
-eGoUKec,XLec,W#eUc92ec17*V#TT>]`<Q~>
-!<E0!joV7Vs8(IL!<(XO!"%?Z!87DQg=cN,o@j3Ern@AP#20%Wg&M-,rW!/V!!(a,!!)WErrE&P
-rr<Va!!(a,!!(^Q!8?-,!87DQrn@APs4[JQ#20%Wg=cN,o@j3ErS%8O#MK.Xg=cN,gAV*PgA_-S
-g&M-PgA_0QgA_/(g4@u<gAc^-U&X9;\c@6~>
-!<E0!joV@Ys8(:G!<(IJ!"%0U!7_&Le^XX"o@<j@rmh#K#1W\ReGoU"rW!/Q!!(R"!!)W@rrE&K
-rr<V\!!(R"!!(OL!7fU"!7_&Lrmh#Ks4.,L#1W\Re^XX"o@<j@rRLoJ#LreSe^XX"ec#RKec,UN
-eGoUKec,XLec,W#eUc92ec17*V#TT>]`<Q~>
-!<E0!joV@Ys8(:G!<(IJ!!LgP!7fWu!:n\?!<1OK!"7<W!7fU"!7_&Le^aTun^[O;rmgrIrmguJ
-!7h#JrRLiHs4.,Ls4.,Lo@<j@rRLoJ!n@8Nrmh#Ks4.&Js4.,LrRLiHJ^o>%imn']"f21\k.LbF~>
-!<E0!joV7Vs8(IL!<(XO!!M!U!8?0*!:nkD!<1^P!"7K\!8?-,!87DQg=lK*n_3m@rn@;Nrn@>O
-!8@AOrS%2Ms4[JQs4[JQo@j3ErS%8O!nmVSrn@APs4[DOs4[JQrS%2MJ_G\/inFE`"ektYk.1PC~>
-!<E0!joV@Ys8(:G!<(IJ!!LgP!7fWu!:n\?!<1OK!"7<W!7fU"!7_&Le^aTun^[O;rmgrIrmguJ
-!7h#JrRLiHs4.,Ls4.,Lo@<j@rRLoJ!n@8Nrmh#Ks4.&Js4.,LrRLiHJ^o>%imn']"f21\k.LbF~>
-!<E0!joV@Ys+/^OeUc8aec17*V#TT>]`<Q~>
-!<E0!joV7Vs+/mTg4@tkgAc^-U&X9;\c@6~>
-!<E0!joV@Ys+/^OeUc8aec17*V#TT>]`<Q~>
-!<E0!joV@Ys+/^OeUc8aec17*V#TT>]`<Q~>
-!<E0!joV7Vs+/mTg4@tkgAc^-U&X9;\c@6~>
-!<E0!joV@Ys+/^OeUc8aec17*V#TT>]`<Q~>
-!<E0!joV@Ys+/^OeUc8aec17*V#TT>]`<Q~>
-!<E0!joV7Vs+/mTg4@tkgAc^-U&X9;\c@6~>
-!<E0!joV@Ys+/^OeUc8aec17*V#TT>]`<Q~>
-!<E0!joV@Ys+/^OeUc8aec17*V#TT>]`<Q~>
-!<E0!joV7Vs+/mTg4@tkgAc^-U&X9;\c@6~>
-!<E0!joV@Ys+/^OeUc8aec17*V#TT>]`<Q~>
-!<E0!joV@Ys+/^OeUc8aec17*V#TT>]`<Q~>
-!<E0!joV7Vs+/mTg4@tkgAc^-U&X9;\c@6~>
-!<E0!joV@Ys+/^OeUc8aec17*V#TT>]`<Q~>
-!<E0!joV@Ys+/^OeUc8aec17*V#TT>]`<Q~>
-!<E0!joV7Vs+/mTg4@tkgAc^-U&X9;\c@6~>
-!<E0!joV@Ys+/^OeUc8aec17*V#TT>]`<Q~>
-!<E0!joV@Ys+/^OeUc8aec17*V#TT>]`<Q~>
-!<E0!joV7Vs+/mTg4@tkgAc^-U&X9;\c@6~>
-!<E0!joV@Ys+/^OeUc8aec17*V#TT>]`<Q~>
-!<E0!joD3.eUc8%e[a36V#TT>]`<Q~>
-!<E0!joD*+g4@t/g:>o@U&X9;\c@6~>
-!<E0!joD3.eUc8%e[a36V#TT>]`<Q~>
-!<E0!joD3.eUc8%e]lY4K*Kl%s5rIW!.Y~>
-!<E0!joD*+g4@t/g<J@>JHji%s5rIT!.Y~>
-!<E0!joD3.eUc8%e]lY4K*Kl%s5rIW!.Y~>
-!<E0!joV@/eU_IdC4U-JCAucPK*VG,V#TT>]`<Q~>
-!<E0!joV71g4=g+JUrC#Jc=BlJHu5/U&X9;\c@6~>
-!<E0!joV@/eU`X0Mh-f7MuM8qK*VG,V#TT>]`<Q~>
-!<E0!joV@/eU_IdC4U-KC&m]$ec19u]`<]]^&S*:eYN6-k.LbF~>
-!<E0!joV71g4=g+JUrC$JH5`LgAca#_>o/`_Z0W?g7eQ/k.1PC~>
-!<E0!joV@/eU`X0Mh-f8MZEeVec19u]`<]]^&S*:eYN6-k.LbF~>
-!<E0!johL1eS8iMXF[I(XOaKQmf(c:KDW=_s+C0]s8N;RV#TT>]`<Q~>
-!<E0!johC3g4=g+g4@t/g=G!Xs8LaPJc!:bs+1$`s8N;WU&X9;\c@6~>
-!<E0!johL1eVf?:k(2ZGk18\ps8LRKKDW=_s+C0]s8N;RV#TT>]`<Q~>
-!<E0!johL1eS8iMXF[I(XOaKQmf(c:KDW=`s+>t$^&S*:eYN6-k.LbF~>
-!<E0!johC3g4=g+g4@t/g=G!Xs8LaPJc!:cs+,au_Z0W?g7eQ/k.1PC~>
-!<E0!johL1eVf?:k(2ZGk18\ps8LRKKDW=`s+>t$^&S*:eYN6-k.LbF~>
-!<E0!johL1eS8iMXF[I(XOaKQmf(c:KD`F_s8R`K^&S*:eYN6-k.LbF~>
-!<E0!johC3g4=g+g4@t/g=G!Xs8LaPJc*Cbs8RZI_Z0W?g7eQ/k.1PC~>
-!<E0!johL1eVf?:k(2ZGk18\ps8LRKKD`F_s8R`K^&S*:eYN6-k.LbF~>
-!<E0!johL1eS8iMXT#=$!;rqs!.h5&XQ6J_mf(c:KD`F_rrU`'KD`F_rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+gA]h+!;tRL!.ijTg>pufs8LaPJc*CbrrUo*Jc*Cbrs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k5ONC!;u!X!.j9`k2b\)s8LRKKD`F_rrU`'KD`F_rs%#Ls5rIW!.Y~>
-!<E0!joqR2eS8j#qZ-Srq>gPsq>gMrrW)hsquHbuquHAjquHYrq>^MsrW)r!rVur"q>^MsquGr^
-!W];%rN#u!rN#u!JZOF(jfJLMrmh%$rOr72s4..%r4W.1#1]OLk2s>WJ,~>
-!<E0!joqI4g4=h/qZ-TKq>gQLq>gNKrW)iLquHcNquHBCquHZKq>^NLrW)rOrVurPq>^NLquGs7
-!W^pSrRq5OrRq5OJ_G\/jkBb7rn@C'rPJU7s4[L(r5/L6#25dNk2s5TJ,~>
-!<E0!joqR2eVf@JqZ-TWq>gQXq>gNWrW)iXquHcZquHBOquHZWq>^NXrW)r[rVur\q>^NXquGsC
-!W_?_rT4([rT4([J`_OGjlZUCrmh%$rOr72s4..%r4W.1#1]OLk2s>WJ,~>
-!<E0!jp.^4eS8j#X8r4#!!)u!!!)u!#lq'.!3E7%XK2F"X8i7rX8i7tX8i7iX8i7rX8i8!X9/I(
-X8r1"!!*#"!!)u!!!*#"!!)/_!W];%rN#u!rN#u!JZOF(jfJLMrmh%$rOr72rmh%$rOr72#1]OL
-k2s>WJ,~>
-!<E0!jp.U6g4=h/g&V**!!)uO!!)uO#lr]5!8?-,g=cQ)g&M-Kg&M-Mg&M-Bg&M-Kg&M-Og&h?/
-g&V')!!*#P!!)uO!!*#P!!)08!W^pSrRq5OrRq5OJ_G\/jkBb7rn@C'rPJU7rn@C'rPJU7#25dN
-k2s5TJ,~>
-!<E0!jp.^4eVf@JjoGAB!!)u[!!)u[#ls,M!9WDDk2l[Ajo>DWjo>DYjo>DNjo>DWjo>D[joYVG
-joG>A!!*#\!!)u[!!*#\!!)0D!W_?_rT4([rT4([J`_OGjlZUCrmh%$rOr72rmh%$rOr72#1]OL
-k2s>WJ,~>
-!<E0!jp.^4eS8j#X8r1"!!*#"!!)u!#lq'.!3E7%XK2F#X9&C'!;`bs!;iht!:[&i!;W\r!<&u$
-!3E7%r2]kuri?)"rN#u!ri?)"poOJqnuMonXK2F#X8i8!X8i6OXF[J7XT._fec1:$^&S-2ec1:#
-^&S*:eYN6-k.LbF~>
-!<E0!jp.U6g4=h/g&V')!!*#P!!)uO#lr]5!8?-,g=cQ*g&_9.!;bCL!;kIM!:\\B!;Y=K!<(UR
-!8?-,r7V,Nrn7>PrRq5Orn7>PptG`Jo%F0Gg=cQ*g&M-Og&M,(g4@u>gAh3PgAca'_Z0Z7gAca&
-_Z0W?g7eQ/k.1PC~>
-!<E0!jp.^4eVf@JjoG>A!!*#\!!)u[#ls,M!9WDDk2l[BjoPPF!;bgX!;kmY!:]+N!;YaW!<)$^
-!9WDDr8mtZroO1\rT4([roO1\pu_SVo&^#Sk2l[Bjo>D[jo>C4k(2[Vk5YJ\ec1:$^&S-2ec1:#
-^&S*:eYN6-k.LbF~>
-!<E0!jp.^4eS8j#X8r1"!!*#"!s#F(!;`bs!;`bu!3?1sX8i7tX8i7iX8i7rX9/I(X8r1"!!*#"
-!!)u!!s#F(!;rnu!;NYq!:m2n!3E7%rN#u!rN#u!JZOF(jfJLMrmh%$rk8@3r71h"rk8@3#1]OL
-k2s>WJ,~>
-!<E0!jp.U6g4=h/g&V')!!*#P!s%'/!;bCL!;bCN!87GLg&M-Mg&M-Bg&M-Kg&h?/g&V')!!*#P
-!!)uO!s%'/!;tON!;P:J!:nhG!8?-,rRq5OrRq5OJ_G\/jkBb7rn@C'rke^8r7_1%rke^8#25dN
-k2s5TJ,~>
-!<E0!jp.^4eVf@JjoG>A!!*#\!s%KG!;bgX!;bgZ!9O:Xjo>DYjo>DNjo>DWjoYVGjoG>A!!*#\
-!!)u[!s%KG!;tsZ!;P^V!:o7S!9WDDrT4([rT4([J`_OGjlZUCrmh%$rk8@3r71h"rk8@3#1]OL
-k2s>WJ,~>
-!<E0!jp.^4eS8j#X8r1"!!*#"r;c\q!!)nt!!*#"!!)nt!!)nt!!)Mi!!)hrr;cbs!!*#"!!)u!
-r;cbs!!)5a!!*#"!!)u!!!)u!!!%SOJZRt7s6fm:s+C?bs8VuHs+C<as8N;RV#TT>]`<Q~>
-!<E0!jp.U6g4=h/g&V')!!*#Pr;c]J!!)oM!!*#P!!)oM!!)oM!!)NB!!)iKr;ccL!!*#P!!)uO
-r;ccL!!)6:!!*#P!!)uO!!)uO!!%T(J_K5>s8W)Ps+13es8VuMs+10ds8N;WU&X9;\c@6~>
-!<E0!jp.^4eVf@JjoG>A!!*#\r;c]V!!)oY!!*#\!!)oY!!)oY!!)NN!!)iWr;ccX!!*#\!!)u[
-r;ccX!!)6F!!*#\!!)u[!!)u[!!%T4J`c(Vs8W)Ks+C?bs8VuHs+C<as8N;RV#TT>]`<Q~>
-!<E0!jp.^4eS8j#X8r1"!!*#"!s#F(!;`bs!;ikq!;iht!;iht!<&u!!;3Dn!<&u!!<0&%!3E7%
-qlBi!X8r1"!s#F(!;rnu!<&u!!:?if!<0&"!<&u!!<&u!!.h5&XQ?P`mf(c:KE&Xbs8(:GKE&Xb
-rs%#Ls5rIW!.Y~>
-!<E0!jp.U6g4=h/g&V')!!*#P!s%'/!;bCL!;kLJ!;kIM!;kIM!<(UO!;5%G!<(UO!<1[S!8?-,
-qq;)Og&V')!s%'/!;tON!<(UO!:AJ?!<1[P!<(UO!<(UO!.ijTg?%&gs8LaPJcEUes8(ILJcEUe
-rs%2Ns5rIT!.Y~>
-!<E0!jp.^4eVf@JjoG>A!!*#\!s%KG!;bgX!;kpV!;kmY!;kmY!<)$[!;5IS!<)$[!<2*_!9WDD
-qrRq[joG>A!s%KG!;tsZ!<)$[!:AnK!<2*\!<)$[!<)$[!.j9`k2kb*s8LRKKE&Xbs8(:GKE&Xb
-rs%#Ls5rIW!.Y~>
-!<E0!jp.^4eS8j#X8r1"!!*#"!!)u!!!)qu!!)qu!!)qu!!)qu!!)nt!!)u!!!)\n!!)u!!!*#"
-!!)u!!!)u!!W];%r2]kurN#u!ri?)"rN#u!mB$0bri?)"rN#u!JZOF(jfJLMrmh%$!knX6q:5Lt
-s1SI4#1]OLk2s>WJ,~>
-!<E0!jp.U6g4=h/g&V')!!*#P!!)uO!!)rN!!)rN!!)rN!!)rN!!)oM!!)uO!!)]G!!)uO!!*#P
-!!)uO!!)uO!W^pSr7V,NrRq5Orn7>PrRq5OmFqF;rn7>PrRq5OJ_G\/jkBb7rn@C'!lG!;q:bk"
-s2+g9#25dNk2s5TJ,~>
-!<E0!jp.^4eVf@JjoG>A!!*#\!!)u[!!)rZ!!)rZ!!)rZ!!)rZ!!)oY!!)u[!!)]S!!)u[!!*#\
-!!)u[!!)u[!W_?_r8mtZrT4([roO1\rT4([mH49GroO1\rT4([J`_OGjlZUCrmh%$!knX6q:5Lt
-s1SI4#1]OLk2s>WJ,~>
-!<E0!jp.^4eS8j#X8r4#!!)u!!!)u!!!)qu!!)qu!!)qu!!)qu!!)nt!!)u!!!)\n!!)u!!!*#"
-!!)u!!!)qu!!)nt!!)u!!!*#"!!)u!!!)u!rrDMh!!)u!!!)u!!!%SOJZRt7s6fm:s+:Bds8VlE
-s+:Wks8UWFs5rIW!.Y~>
-!<E0!jp.U6g4=h/g&V**!!)uO!!)uO!!)rN!!)rN!!)rN!!)rN!!)oM!!)uO!!)]G!!)uO!!*#P
-!!)uO!!)rN!!)oM!!)uO!!*#P!!)uO!!)uOrrDNA!!)uO!!)uO!!%T(J_K5>s8W)Ps+(6gs8VlJ
-s+(Kns8UfHs5rIT!.Y~>
-!<E0!jp.^4eVf@JjoGAB!!)u[!!)u[!!)rZ!!)rZ!!)rZ!!)rZ!!)oY!!)u[!!)]S!!)u[!!*#\
-!!)u[!!)rZ!!)oY!!)u[!!*#\!!)u[!!)u[rrDNM!!)u[!!)u[!!%T4J`c(Vs8W)Ks+:Bds8VlE
-s+:Wks8UWFs5rIW!.Y~>
-!<E0!joqR2eS8j#qZ-Srq>gMrquHbur;Zi!r;cl!quHbuq#L/jq#LGrq>gGp!!)quq>^Msq#LAp
-rrDPirW)nur;_DMJZRq6s6fm:s+C@Oon*Ras8UWFs5rIW!.Y~>
-!<E0!joqI4g4=h/qZ-TKq>gNKquHcNr;ZiOr;clOquHcNq#L0Cq#LHKq>gHI!!)rNq>^NLq#LBI
-rrDQBrW)oNr;_E&J_K2=s8W)Ps+14MommFds8UfHs5rIT!.Y~>
-!<E0!joqR2eVf@JqZ-TWq>gNWquHcZr;Zi[r;cl[quHcZq#L0Oq#LHWq>gHU!!)rZq>^NXq#LBU
-rrDQNrW)oZr;_E2J`c%Us8W)Ks+C@Oon*Ras8UWFs5rIW!.Y~>
-!<E0!johL1eS8iMXF[I(XOaKQmf(c:K)krCKE(rUeYN6-k.LbF~>
-!<E0!johC3g4=g+g4@t/g=G!Xs8LaPJH5`AJcG`Sg7eQ/k.1PC~>
-!<E0!johL1eVf?:k(2ZGk18\ps8LRKK)krCKE(rUeYN6-k.LbF~>
-!<E0!johL1eS8iMXF[I(XOaKQmf(c:KCZ_Urs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g4@t/g=G!Xs8LaPJb$\Xrs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k(2ZGk18\ps8LRKKCZ_Urs%#Ls5rIW!.Y~>
-!<E0!johL1eS8iMXF[I(XOaKQmf(c:KCJmFeYN6-k.LbF~>
-!<E0!johC3g4=g+g4@t/g=G!Xs8LaPJai[Dg7eQ/k.1PC~>
-!<E0!johL1eVf?:k(2ZGk18\ps8LRKKCJmFeYN6-k.LbF~>
-!<E0!johL1eS8iMXF[I(XOaKQmf(c:KCf*LKE(u%V#TT>]`<Q~>
-!<E0!johC3g4=g+g4@t/g=G!Xs8LaPJb/mJJcGc(U&X9;\c@6~>
-!<E0!johL1eVf?:k(2ZGk18\ps8LRKKCf*LKE(u%V#TT>]`<Q~>
-!<E0!johL1eS8iMXF[I(XOaKQmf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g4@t/g=G!Xs8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k(2ZGk18\ps8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8iMXO4*L!;NYq!.h57XT._fec1:%s7Y"CKE(rUeYN6-k.LbF~>
-!<E0!johC3g4=g+g<nUS!;P:J!.ijegAh3PgAca(s7Y1HJcG`Sg7eQ/k.1PC~>
-!<E0!johL1eVf?:k0`;k!;P^V!.j9qk5YJ\ec1:%s7Y"CKE(rUeYN6-k.LbF~>
-!<E0!joqR2eS8j#quHVqrW)ktqZ-Vsq>^MsquDJQ!!)bp!!)bp!!%SOP-"]Ormh%$s8VfCs+C@O
-#1]OLk2s>WJ,~>
-!<E0!joqI4g4=h/quHWJrW)lMqZ-WLq>^NLquDK*!!)cI!!)cI!!%T(P1os9rn@C's8VfHs+14M
-#25dNk2s5TJ,~>
-!<E0!joqR2eVf@JquHWVrW)lYqZ-WXq>^NXquDK6!!)cU!!)cU!!%T4P32fErmh%$s8VfCs+C@O
-#1]OLk2s>WJ,~>
-!<E0!johL1eS8juX8i7pX8i7tX8i8!X8i8"X8i8!X8i8"X8i6RX8i7eX8i6OXHK[bmf(c:KE(uF
-ec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=hSg&M-Ig&M-Mg&M-Og&M-Pg&M-Og&M-Pg&M,+g&M->g&M,(g611is8LaPJcGcD
-gAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf@bjo>DUjo>DYjo>D[jo>D\jo>D[jo>D\jo>C7jo>DJjo>C4k*"m,s8LRKKE(uF
-ec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8juX8i7qX9&C'!;rnu!<&u!!<0&"!<&u!!<0&"!;NYq!4Ap.!!',"!;iks!<0)!
-!<0)!!;ESm!;rqt!;iks!!0/$JZP$9s6fm:s+C@Op=91qs8N;RV#TT>]`<Q~>
-!<E0!johC3g4=hSg&M-Jg&_9.!;tON!<(UO!<1[P!<(UO!<1[P!;P:J!4CP\!!(aP!;kLL!<1^O
-!<1^O!;G4F!;tRM!;kLL!!1dRJ_H:@s8W)Ps+14Mp=fOts8N;WU&X9;\c@6~>
-!<E0!johL1eVf@bjo>DVjoPPF!;tsZ!<)$[!<2*\!<)$[!<2*\!;P^V!4Cth!!)0\!;kpX!<2-[
-!<2-[!;GXR!;u!Y!;kpX!!23^J``-Xs8W)Ks+C@Op=91qs8N;RV#TT>]`<Q~>
-!<E0!johL1eS8juX8i7qX9&C'!;rnu!<&u!!<0&%!3E7%r2]kupoOJq[&j9-ri?)"rN#u!ri?)"
-ri?)"r2]kuorJ,npT+>pr2]kuriH,"JZP$9s6fm:s+C@Op=91qs8N;RV#TT>]`<Q~>
-!<E0!johC3g4=hSg&M-Jg&_9.!;tON!<(UO!<1[S!8?-,r7V,NptG`J[+bN[rn7>PrRq5Orn7>P
-rn7>Pr7V,Np"BBGpY#TIr7V,Nrn@APJ_H:@s8W)Ps+14Mp=fOts8N;WU&X9;\c@6~>
-!<E0!johL1eVf@bjo>DVjoPPF!;tsZ!<)$[!<2*_!9WDDr8mtZpu_SV[-%AgroO1\rT4([roO1\
-roO1\r8mtZp#Z5SpZ;GUr8mtZroX4\J``-Xs8W)Ks+C@Op=91qs8N;RV#TT>]`<Q~>
-!<E0!johL1eS8juX8i7rX8i8"X8i8!XS`(sXSi.sX8i7"X8i8!X8i8"X8i7uX9em.X8o?'!3E7%
-orJ,npT+>prN#u!r2]kuJZP$9s6fm:s+C@Op=91qs8N;RV#TT>]`<Q~>
-!<E0!johC3g4=hSg&M-Kg&M-Pg&M-OgACsLgAM$Lg&M,Pg&M-Og&M-Pg&M-Ng'Ic5g&Tj\!8?-,
-p"BBGpY#TIrRq5Or7V,NJ_H:@s8W)Ps+14Mp=fOts8N;WU&X9;\c@6~>
-!<E0!johL1eVf@bjo>DWjo>D\jo>D[k555Xk5>;Xjo>C\jo>D[jo>D\jo>DZjp;%MjoFQ+!9WDD
-p#Z5SpZ;GUrT4([r8mtZJ``-Xs8W)Ks+C@Op=91qs8N;RV#TT>]`<Q~>
-!<E0!johL1eS8juX8i8!X8i8"XS`(sX8i8!X8i8"X9/I(X8r1"!!)u!!!'1'!!)u!!!*#"q>gPs
-"ota+!3E7%orJ,npT+>prN#u!r2]kuJZP$9s6fm:s+C@Op=91qs8N;RV#TT>]`<Q~>
-!<E0!johC3g4=hSg&M-Og&M-PgACsLg&M-Og&M-Pg&h?/g&V')!!)uO!!'1U!!)uO!!*#Pq>gQL
-"p!B2!8?-,p"BBGpY#TIrRq5Or7V,NJ_H:@s8W)Ps+14Mp=fOts8N;WU&X9;\c@6~>
-!<E0!johL1eVf@bjo>D[jo>D\k555Xjo>D[jo>D\joYVGjoG>A!!)u[!!'1a!!)u[!!*#\q>gQX
-"p!fJ!9WDDp#Z5SpZ;GUrT4([r8mtZJ``-Xs8W)Ks+C@Op=91qs8N;RV#TT>]`<Q~>
-!<E0!johL1eS8juX8i8!X9/I(X8r1"!!*#"!!)u!!!*#"!!)u!!!*#"!!)u!!!'1'!!)u!!!*#"
-!!)eq"9>M'X8qmo!!)bp!!)u!!!)qu!!%SOP-"]Ormh%$s8VfCs+C@O#1]OLk2s>WJ,~>
-!<E0!johC3g4=hSg&M-Og&h?/g&V')!!*#P!!)uO!!*#P!!)uO!!*#P!!)uO!!'1U!!)uO!!*#P
-!!)fJ"9@-Ug&Ud!!!)cI!!)uO!!)rN!!%T(P1os9rn@C's8VfHs+14M#25dNk2s5TJ,~>
-!<E0!johL1eVf@bjo>D[joYVGjoG>A!!*#\!!)u[!!*#\!!)u[!!*#\!!)u[!!'1a!!)u[!!*#\
-!!)fV"9@QajoG&9!!)cU!!)u[!!)rZ!!%T4P32fErmh%$s8VfCs+C@O#1]OLk2s>WJ,~>
-!<E0!johL1eS8juX8i8!X9/I(X8r1"!!*#"!!)u!!!*#"!!)u!!!*#"!!)u!!!)u!rrBF-!!)u!
-!!)u!!!)u!!!*#"rr<,%!!)Ym!!*#"!!)nt!!)qu!!*#"rr@VOP-"]Ormh%$s8VfCs+C@O#1]OL
-k2s>WJ,~>
-!<E0!johC3g4=hSg&M-Og&h?/g&V')!!*#P!!)uO!!*#P!!)uO!!*#P!!)uO!!)uOrrBF[!!)uO
-!!)uO!!)uO!!*#Prr<,S!!)ZF!!*#P!!)oM!!)rN!!*#Prr@W(P1os9rn@C's8VfHs+14M#25dN
-k2s5TJ,~>
-!<E0!johL1eVf@bjo>D[joYVGjoG>A!!*#\!!)u[!!*#\!!)u[!!*#\!!)u[!!)u[rrBFg!!)u[
-!!)u[!!)u[!!*#\rr<,_!!)ZR!!*#\!!)oY!!)rZ!!*#\rr@W4P32fErmh%$s8VfCs+C@O#1]OL
-k2s>WJ,~>
-!<E0!joqR2eS8j#q#CDrr;Zi!r;Zi!qZ-Vsq>^Msq#LAprrBI.rW)u"rW)nur;cetrr<,%!!)Vl
-rW)ktquH\srW!#$!!%SOPH=fPrmh%$s8VfCs+C@O#1]OLk2s>WJ,~>
-!<E0!joqI4g4=h/q#CEKr;ZiOr;ZiOqZ-WLq>^NLq#LBIrrBI\rW)uPrW)oNr;cfMrr<,S!!)WE
-rW)lMquH]LrW!#R!!%T(PM6':rn@C's8VfHs+14M#25dNk2s5TJ,~>
-!<E0!joqR2eVf@Jq#CEWr;Zi[r;Zi[qZ-WXq>^NXq#LBUrrBIhrW)u\rW)oZr;cfYrr<,_!!)WQ
-rW)lYquH]XrW!#^!!%T4PNMoFrmh%$s8VfCs+C@O#1]OLk2s>WJ,~>
-!<E0!johL1eS8iMXF[I(XOaKQmf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g4@t/g=G!Xs8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k(2ZGk18\ps8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8iMXF[I(XOaKQmf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g4@t/g=G!Xs8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k(2ZGk18\ps8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8iMXQQ\[!.h5&XSJstmf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g?72b!.ijTgA0J&s8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k3(n%!.j9`k5"0>s8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8iMXF[I(XOaKQmf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g4@t/g=G!Xs8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k(2ZGk18\ps8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8iMXF[I(XOaKQmf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g4@t/g=G!Xs8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k(2ZGk18\ps8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8iMXP0`U!.h5&XT#=$mf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g=k6\!.ijTgA]h+s8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k1\qt!.j9`k5ONCs8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!jp%X3eS8j#XSMnsXSW"qXSi.uXSr5!XSr3NXT,@%!9pQb!.h5<XT._fec1:%s7Y"CKE(rU
-eYN6-k.LbF~>
-!<E0!jp%O5g4=h/gA1dLgA:mJgAM$NgAV*OgAV)'gAfk,!9r2;!.ijjgAh3PgAca(s7Y1HJcG`S
-g7eQ/k.1PC~>
-!<E0!jp%X3eVf@Jk5#&Xk5,/Vk5>;Zk5GA[k5G@3k5XQD!9rVG!.j:!k5YJ\ec1:%s7Y"CKE(rU
-eYN6-k.LbF~>
-!<E0!johL1eS8juX8i8!X9/I(X8r4#!!*#"!!)u!!!*#"rrE&"rr@VOjfAF^JZP3>s6fm:s+C@O
-p=91qs8N;RV#TT>]`<Q~>
-!<E0!johC3g4=hSg&M-Og&h?/g&V**!!*#P!!)uO!!*#PrrE&Prr@W(jk9\7J_HIEs8W)Ps+14M
-p=fOts8N;WU&X9;\c@6~>
-!<E0!johL1eVf@bjo>D[joYVGjoGAB!!*#\!!)u[!!*#\rrE&\rr@W4jlQOCJ``<]s8W)Ks+C@O
-p=91qs8N;RV#TT>]`<Q~>
-!<E0!johL1eS8juX8i8!X9/I(X8r4#!s#F(!;ii%!3E7%X8o@$!<'#!!3E:%!"#_,!3?/#X8i7%
-rW)hsrW)ktquH\srW)hsr;cJkquH_trr<5(!!')#!.h5JXT._fec1:%s7Y"CKE(rUeYN6-k.LbF~>
-!<E0!johC3g4=hSg&M-Og&h?/g&V**!s%'/!;kIS!8?-,g&Tk+!<(XO!3FoS!"%?Z!87DQg&M-,
-rW)iLrW)lMquH]LrW)iLr;cKDquH`Mrr<5V!!(^Q!.ik#gAh3PgAca(s7Y1HJcG`Sg7eQ/k.1PC~>
-!<E0!johL1eVf@bjo>D[joYVGjoGAB!s%KG!;km_!9WDDjoFQC!<)'[!3G>_!"%cf!9O7]jo>DD
-rW)iXrW)lYquH]XrW)iXr;cKPquH`Yrr<5b!!)-]!.j:/k5YJ\ec1:%s7Y"CKE(rUeYN6-k.LbF~>
-!<E0!johL1eS8juX9/I(X8r4#!!)u!!s#F(!;ii(!3E7%X8o=%X8r4#rrB+$rr<>+!!')#XK2C%
-ri?)"rN#u!ri?)"ri?)"rN#u!qlBbtr2]kurN#u!oW/#mqQ0\s"KVS'X8mgQV6'^brmh%$s8VfC
-s+C@O#1]OLk2s>WJ,~>
-!<E0!johC3g4=hSg&h?/g&V**!!)uO!s%'/!;kIV!8?-,g&Th,g&V**rrB+Rrr<>Y!!(^Qg=cN,
-rn7>PrRq5Orn7>Prn7>PrRq5Oqq;#Mr7V,NrRq5Oo\'9FqV(rL"PNhUg&Q]XV:ttLrn@C's8VfH
-s+14M#25dNk2s5TJ,~>
-!<E0!johL1eVf@bjoYVGjoGAB!!)u[!s%KG!;kmb!9WDDjoFNDjoGABrrB+^rr<>e!!)-]k2lXD
-roO1\rT4([roO1\roO1\rT4([qrRkYr8mtZrT4([o]?,RqW@eX"Qf[ajoBtpV<7gXrmh%$s8VfC
-s+C@O#1]OLk2s>WJ,~>
-!<E0!johL1eS8juXSi.tX8i8"X8i8"X8i7tX9em.X8o?'!3E7%V5st'XK2E'X8o?'!<&u!!<0&"
-!;ro#!3E7%p8e5opT+>poW/#mqQ'l$XK2E'X8mgQV6'^brmh%$s8VfCs+C@O#1]OLk2s>WJ,~>
-!<E0!johC3g4=hSgAM$Mg&M-Pg&M-Pg&M-Mg'Ic5g&Tj\!8?-,V:l4Ug=cP\g&Tj\!<(UO!<1[P
-!;tOQ!8?-,p=]KHpY#TIo\'9FqUu,Rg=cP\g&Q]XV:ttLrn@C's8VfHs+14M#25dNk2s5TJ,~>
-!<E0!johL1eVf@bk5>;Yjo>D\jo>D\jo>DYjp;%MjoFQ+!9WDDV</'ak2l[+joFQ+!<)$[!<2*\
-!;ts]!9WDDp>u>TpZ;GUo]?,RqW7t^k2l[+joBtpV<7gXrmh%$s8VfCs+C@O#1]OLk2s>WJ,~>
-!<E0!johL1eS8juX9/I(X8r4#r;cet!!)nt#lq'.!3E7%XK2DuX9em.X8o?'!3E7%rN#u!riGqr
-riH%uqQ'YsqlK\qoW/#mqQ'l$XK2E'X8mgQV6'^brmh%$s8VfCs+C@O#1]OLk2s>WJ,~>
-!<E0!johC3g4=hSg&h?/g&V**r;cfM!!)oM#lr]5!8?-,g=cP'g'Ic5g&Tj\!8?-,rRq5Orn@2K
-rn@;NqUtoLqqCrJo\'9FqUu,Rg=cP\g&Q]XV:ttLrn@C's8VfHs+14M#25dNk2s5TJ,~>
-!<E0!johL1eVf@bjoYVGjoGABr;cfY!!)oY#ls,M!9WDDk2lZ?jp;%MjoFQ+!9WDDrT4([roX%W
-roX.ZqW7bXqr[eVo]?,RqW7t^k2l[+joBtpV<7gXrmh%$s8VfCs+C@O#1]OLk2s>WJ,~>
-!<E0!johL1eS8juX8i7sX8i8"X8i8"X8i7tX9/I(X8r1"!!&js#lq'.!3E7%XK2F#X8i8"X8i7m
-X8i7tX8i7uX8i8!X8i7mX8i7sX9J[+X8o?'!.h5JXT._fec1:%s7Y"CKE(rUeYN6-k.LbF~>
-!<E0!johC3g4=hSg&M-Lg&M-Pg&M-Pg&M-Mg&h?/g&V')!!&kL#lr]5!8?-,g=cQ*g&M-Pg&M-F
-g&M-Mg&M-Ng&M-Og&M-Fg&M-Lg'.Q2g&Tj\!.ik#gAh3PgAca(s7Y1HJcG`Sg7eQ/k.1PC~>
-!<E0!johL1eVf@bjo>DXjo>D\jo>D\jo>DYjoYVGjoG>A!!&kX#ls,M!9WDDk2l[Bjo>D\jo>DR
-jo>DYjo>DZjo>D[jo>DRjo>DXjothJjoFQ+!.j:/k5YJ\ec1:%s7Y"CKE(rUeYN6-k.LbF~>
-!<E0!johL1eS8juX8i7sX8i8!X8i8"X8i8!X8i8"X8i7uX8i8!XT&:$X9em.X8o?'!3E7%rN#u!
-rN#u!rN$)$XK2F#X8i7tX8i7uX8i8"XT&:mX8i8"X8i8"X9J[+X8o?'!.h5JXT._fec1:%s7Y"C
-KE(rUeYN6-k.LbF~>
-!<E0!johC3g4=hSg&M-Lg&M-Og&M-Pg&M-Og&M-Pg&M-Ng&M-OgA_/Rg'Ic5g&Tj\!8?-,rRq5O
-rRq5OrRq>Rg=cQ*g&M-Mg&M-Ng&M-PgA_0Fg&M-Pg&M-Pg'.Q2g&Tj\!.ik#gAh3PgAca(s7Y1H
-JcG`Sg7eQ/k.1PC~>
-!<E0!johL1eVf@bjo>DXjo>D[jo>D\jo>D[jo>D\jo>DZjo>D[k5PF^jp;%MjoFQ+!9WDDrT4([
-rT4([rT41^k2l[Bjo>DYjo>DZjo>D\k5PGRjo>D\jo>D\jothJjoFQ+!.j:/k5YJ\ec1:%s7Y"C
-KE(rUeYN6-k.LbF~>
-!<E0!jp%X3eS8j#XSi.tXSr4uX8i8"XSi.uXSr5!XSr5!XT&:%XSr2%X8i7%quHburW)nur;chu
-quHYrquH\srW!#$!!)YmrW)r!rW!,'!!')#!.h5KXT._fec1:%s7Y"CKE(rUeYN6-k.LbF~>
-!<E0!jp%O5g4=h/gAM$MgAV*Ng&M-PgAM$NgAV*OgAV*OgA_/SgAV'Sg&M-,quHcNrW)oNr;ciN
-quHZKquH]LrW!#R!!)ZFrW)rOrW!,U!!(^Q!.ik$gAh3PgAca(s7Y1HJcG`Sg7eQ/k.1PC~>
-!<E0!jp%X3eVf@Jk5>;Yk5GAZjo>D\k5>;Zk5GA[k5GA[k5PF_k5G>_jo>DDquHcZrW)oZr;ciZ
-quHZWquH]XrW!#^!!)ZRrW)r[rW!,a!!)-]!.j:0k5YJ\ec1:%s7Y"CKE(rUeYN6-k.LbF~>
-!<E0!johL1eS8iMXF[I(XOaKQmf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g4@t/g=G!Xs8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k(2ZGk18\ps8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8iMXF[I(XOaKQmf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g4@t/g=G!Xs8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k(2ZGk18\ps8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8iMXN[d@!.h59XT._fec1:%s7Y"CKE(rUeYN6-k.LbF~>
-!<E0!johC3g4=g+g<A:G!.ijggAh3PgAca(s7Y1HJcG`Sg7eQ/k.1PC~>
-!<E0!johL1eVf?:k02u_!.j9sk5YJ\ec1:%s7Y"CKE(rUeYN6-k.LbF~>
-!<E0!johL1eS8iMXF[I(XOaKQmf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g4@t/g=G!Xs8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k(2ZGk18\ps8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8iMXF[I(XOaKQmf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g4@t/g=G!Xs8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k(2ZGk18\ps8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8iMXPU&Y!.h5&XS]+!mf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g>:Q`!.ijTgABV(s8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k2,8#!.j9`k54<@s8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!jp%X3eS8j#XSMqrXSi-MXR3(h!:R#g!;iks!.h5>XT._fec1:%s7Y"CKE(rUeYN6-k.LbF~>
-!<E0!jp%O5g4=h/gA1gKgAM#&g?mSo!:SY@!;kLL!.ijlgAh3PgAca(s7Y1HJcG`Sg7eQ/k.1PC~>
-!<E0!jp%X3eVf@Jk5#)Wk5>:2k3_:2!:T(L!;kpX!.j:#k5YJ\ec1:%s7Y"CKE(rUeYN6-k.LbF~>
-!<E0!jq+?=eS8j#X8o?'!3E7%XK2F#X8i6OXR<.i!:?if!;W\r!.h5>XT._fec1:%s7Y"CKE(rU
-eYN6-k.LbF~>
-!<E0!jq+6?g4=h/g&Tj\!8?-,g=cQ*g&M,(g@!Yp!:AJ?!;Y=K!.ijlgAh3PgAca(s7Y1HJcG`S
-g7eQ/k.1PC~>
-!<E0!jq+?=eVf@JjoFQ+!9WDDk2l[Bjo>C4k3h@3!:AnK!;YaW!.j:#k5YJ\ec1:%s7Y"CKE(rU
-eYN6-k.LbF~>
-!<E0!jq"9<eS8j#X8o?'!3E7%X8r.!!!)u!rrALhrr<8)!!')#!3H/"s/c2"orS&kri?,#XSr4s
-XSr4rX8i7rX8i6OXI60imf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!jq"0>g4=h/g&Tj\!8?-,g&V$(!!)uOrrAMArr<8W!!(^Q!8@DPs4[GPp"K<Drn7AQgAV*L
-gAV*Kg&M-Kg&M,(g6p[ps8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!jq"9<eVf@JjoFQ+!9WDDjoG;@!!)u[rrAMMrr<8c!!)-]!9X7\s5s:\p#c/ProO4]k5GAX
-k5GAWjo>DWjo>C4k*bB3s8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8jsX8i8!X8i7tX8i8!XT&9gXT&8*X8i7%!3E7%rN#u!orJ,nrN#u!riH,"ri?)"
-rN#u!ri?)"qlBbtq5aPrJZP9@s6fm:s+C@Op=91qs8N;RV#TT>]`<Q~>
-!<E0!johC3g4=hQg&M-Og&M-Mg&M-OgA_/@gA_-Xg&M-,!8?-,rRq5Op"BBGrRq5Orn@APrn7>P
-rRq5Orn7>Pqq;#Mq:YfKJ_HOGs8W)Ps+14Mp=fOts8N;WU&X9;\c@6~>
-!<E0!johL1eVf@`jo>D[jo>DYjo>D[k5PFLk5PDdjo>DD!9WDDrT4([p#Z5SrT4([roX4\roO1\
-rT4([roO1\qrRkYq;qYWJ``B_s8W)Ks+C@Op=91qs8N;RV#TT>]`<Q~>
-!<E0!johL1eS8jsX8i8!X8i7tX8i6aX9em.X8o?'!3E7%rN#u!orJ,nq5aPrrN#u!ri?)"r2]ku
-r2]kuq5aPrJZP9@s6fm:s+C@Op=91qs8N;RV#TT>]`<Q~>
-!<E0!johC3g4=hQg&M-Og&M-Mg&M,:g'Ic5g&Tj\!8?-,rRq5Op"BBGq:YfKrRq5Orn7>Pr7V,N
-r7V,Nq:YfKJ_HOGs8W)Ps+14Mp=fOts8N;WU&X9;\c@6~>
-!<E0!johL1eVf@`jo>D[jo>DYjo>CFjp;%MjoFQ+!9WDDrT4([p#Z5Sq;qYWrT4([roO1\r8mtZ
-r8mtZq;qYWJ``B_s8W)Ks+C@Op=91qs8N;RV#TT>]`<Q~>
-!<E0!johL1eS8jsX8i8!X8i7tX8i6aX9J[+X8o?'!<0&%!3E7%o;qljrN#u!rN#u!riGqrr2]ku
-q5aPrJZP9@s6fm:s+C@Op=91qs8N;RV#TT>]`<Q~>
-!<E0!johC3g4=hQg&M-Og&M-Mg&M,:g'.Q2g&Tj\!<1[S!8?-,o@j-CrRq5OrRq5Orn@2Kr7V,N
-q:YfKJ_HOGs8W)Ps+14Mp=fOts8N;WU&X9;\c@6~>
-!<E0!johL1eVf@`jo>D[jo>DYjo>CFjothJjoFQ+!<2*_!9WDDoB,uOrT4([rT4([roX%Wr8mtZ
-q;qYWJ``B_s8W)Ks+C@Op=91qs8N;RV#TT>]`<Q~>
-!<E0!johL1eS8jsX8i8!X8i7tX8i6aX9J[+X8o?'!<0&%!3E7%n#QKhri?)"rN#u!ri?)"p8e5o
-q5aPrJZP9@s6fm:s+C@Op=91qs8N;RV#TT>]`<Q~>
-!<E0!johC3g4=hQg&M-Og&M-Mg&M,:g'.Q2g&Tj\!<1[S!8?-,n(IaArn7>PrRq5Orn7>Pp=]KH
-q:YfKJ_HOGs8W)Ps+14Mp=fOts8N;WU&X9;\c@6~>
-!<E0!johL1eVf@`jo>D[jo>DYjo>CFjothJjoFQ+!<2*_!9WDDn)aTMroO1\rT4([roO1\p>u>T
-q;qYWJ``B_s8W)Ks+C@Op=91qs8N;RV#TT>]`<Q~>
-!<E0!johL1eS8jsX8i7uX8i8!X8i7uXT&9gX9J[+X8o?'!<'#!!;!8l!<&u!!<0&"!<&u!!<&u!
-!<&u!!;rnu!;W\r!.h5>XT._fec1:%s7Y"CKE(rUeYN6-k.LbF~>
-!<E0!johC3g4=hQg&M-Ng&M-Og&M-NgA_/@g'.Q2g&Tj\!<(XO!;"nE!<(UO!<1[P!<(UO!<(UO
-!<(UO!;tON!;Y=K!.ijlgAh3PgAca(s7Y1HJcG`Sg7eQ/k.1PC~>
-!<E0!johL1eVf@`jo>DZjo>D[jo>DZk5PFLjothJjoFQ+!<)'[!;#=Q!<)$[!<2*\!<)$[!<)$[
-!<)$[!;tsZ!;YaW!.j:#k5YJ\ec1:%s7Y"CKE(rUeYN6-k.LbF~>
-!<E0!johL1eS8juXS`(sXSi.rXT&9hXSr2'X8i7%!!)u!!!)VlquH_trW)u"rW)nur;cetquH\s
-quD;LS#lYXrmh%$s8VfCs+C@O#1]OLk2s>WJ,~>
-!<E0!johC3g4=hSgACsLgAM$KgA_/AgAV'Ug&M-,!!)uO!!)WEquH`MrW)uPrW)oNr;cfMquH]L
-quD<%S(doBrn@C's8VfHs+14M#25dNk2s5TJ,~>
-!<E0!johL1eVf@bk555Xk5>;Wk5PFMk5G>ajo>DD!!)u[!!)WQquH`YrW)u\rW)oZr;cfYquH]X
-quD<1S*'bNrmh%$s8VfCs+C@O#1]OLk2s>WJ,~>
-!<E0!johL1eS8iMXS/^q!.h5&XQ$>]mf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g@j5#!.ijTg>^ids8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k4[p;!.j9`k2PP's8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8iMXS/^q!.h5&XQ$>]mf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g@j5#!.ijTg>^ids8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k4[p;!.j9`k2PP's8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8iMXSAmq!<'"o!.h5&XRN=kmf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+gA'D#!<(XH!.ijTg@3hrs8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k4n*;!<)'T!.j9`k4%O5s8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8iMXF[I(XOaKQmf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g4@t/g=G!Xs8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k(2ZGk18\ps8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8iMXF[I(XOaKQmf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g4@t/g=G!Xs8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k(2ZGk18\ps8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8iMX8o@#!;rqs!;rqs!;rqs!:m2k!;`eq!:m2k!;NYq!:m2k!;NYq!;!;j!<'"r
-!:m5k!;rqt!:m5i!;iks!;iht!;W_q!;rqs!;rqs!5,E5mf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g&Tk*!;tRL!;tRL!;tRL!:nhD!;bFJ!:nhD!;P:J!:nhD!;P:J!;"qC!<(XK
-!:nkD!;tRM!:nkB!;kLL!;kIM!;Y@J!;tRL!;tRL!5.%cs8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:joFQB!;u!X!;u!X!;u!X!:o7P!;bjV!:o7P!;P^V!:o7P!;P^V!;#@O!<)'W
-!:o:P!;u!Y!:o:N!;kpX!;kmY!;YdV!;u!X!;u!X!5.Ios8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!jp%X3eS8j#XSW"rXSr4uXSW"qXSr2#X8r7$q>^MsqZ+%*!!)u!!!*#"!!)u!!!*#"!!)u!
-!!*#"!!)u!!!)YmrrDqt!!)u!!!)YmrrDkr!W];%o;qrlq5aVtX8qmo!!)u!!!*#"!!)u!!!)Vl
-!W];%rN#u!ri?)"oW/#mrN#u!rN#u!q5jSrqQ'YsqQ'YsrN#u!ri?)"rN#u!]r_8%rmh%$s8VfC
-s+C@O#1]OLk2s>WJ,~>
-!<E0!jp%O5g4=h/gA:mKgAV*NgA:mJgAV'Qg&V-+q>^NLqZ+%X!!)uO!!*#P!!)uO!!*#P!!)uO
-!!*#P!!)uO!!)ZFrrDrM!!)uO!!)ZFrrDlK!W^pSo@j3Eq:YlMg&Ud!!!)uO!!*#P!!)uO!!)WE
-!W^pSrRq5Orn7>Po\'9FrRq5OrRq5Oq:biKqUtoLqUtoLrRq5Orn7>PrRq5O^"WMdrn@C's8VfH
-s+14M#25dNk2s5TJ,~>
-!<E0!jp%X3eVf@Jk5,/Wk5GAZk5,/Vk5G>]joGDCq>^NXqZ+%d!!)u[!!*#\!!)u[!!*#\!!)u[
-!!*#\!!)u[!!)ZRrrDrY!!)u[!!)ZRrrDlW!W_?_oB-&Qq;q_YjoG&9!!)u[!!*#\!!)u[!!)WQ
-!W_?_rT4([roO1\o]?,RrT4([rT4([q<%\WqW7bXqW7bXrT4([roO1\rT4([^#o@prmh%$s8VfC
-s+C@O#1]OLk2s>WJ,~>
-!<E0!johL1eS8juX8i8!X8i7uX8i7uX8i8!X8i8"X8i8"XT&;!X8i8!X9/I(X8r4#!!'I/!!)u!
-!!*#"!!)u!!!*#"!!)u!!!*#"!!)u!!!)\n!W];%qlBbtrN#u!orJ2pX8r't!W];%oW/)oX8r't
-!W];%oW/#mrN#u!q5aPro;hunX8r4#!!)u!!!)\n!!)u!!!*#"!!)hr!W];%qlBbtq5aPrrN#u!
-ri?)"rN#u!]r_8%rmh%$s8VfCs+C@O#1]OLk2s>WJ,~>
-!<E0!johC3g4=hSg&M-Og&M-Ng&M-Ng&M-Og&M-Pg&M-PgA_0Og&M-Og&h?/g&V**!!'I]!!)uO
-!!*#P!!)uO!!*#P!!)uO!!*#P!!)uO!!)]G!W^pSqq;#MrRq5Op"BHIg&Us&!W^pSo\'?Hg&Us&
-!W^pSo\'9FrRq5Oq:YfKo@a6Gg&V**!!)uO!!)]G!!)uO!!*#P!!)iK!W^pSqq;#Mq:YfKrRq5O
-rn7>PrRq5O^"WMdrn@C's8VfHs+14M#25dNk2s5TJ,~>
-!<E0!johL1eVf@bjo>D[jo>DZjo>DZjo>D[jo>D\jo>D\k5PG[jo>D[joYVGjoGAB!!'Ii!!)u[
-!!*#\!!)u[!!*#\!!)u[!!*#\!!)u[!!)]S!W_?_qrRkYrT4([p#Z;UjoG5>!W_?_o]?2TjoG5>
-!W_?_o]?,RrT4([q;qYWoB$)SjoGAB!!)u[!!)]S!!)u[!!*#\!!)iW!W_?_qrRkYq;qYWrT4([
-roO1\rT4([^#o@prmh%$s8VfCs+C@O#1]OLk2s>WJ,~>
-!<E0!johL1eS8juX8i8!X8i8!X9&C'!<&u!!<&u!!<0&"!<&u!!<&u!!<&u$!3E7%r2]kurN-#!
-\?#Z1ri?)"rN#u!ri?)"rN#u!q5aPro;holqlBbtrN#u!o;holqQ'c!XK2EmX8i7sX9/I(X8q^j
-!!)ks!!)Vl!s#F(!<&u!!<&u!!:[&i!<0&"!;EPp!;iht!;*>m!;W\r!55K6mf(c:KE(uFec1:%
-rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=hSg&M-Og&M-Og&_9.!<(UO!<(UO!<1[P!<(UO!<(UO!<(UR!8?-,r7V,NrS%8O
-\Cpo_rn7>PrRq5Orn7>PrRq5Oq:YfKo@a0Eqq;#MrRq5Oo@a0EqUu#Og=cPtg&M-Lg&h?/g&UTq
-!!)lL!!)WE!s%'/!<(UO!<(UO!:\\B!<1[P!;G1I!;kIM!;+tF!;Y=K!57+ds8LaPJcGcDgAca(
-rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf@bjo>D[jo>D[joPPF!<)$[!<)$[!<2*\!<)$[!<)$[!<)$^!9WDDr8mtZrT=+[
-\E3bkroO1\rT4([roO1\rT4([q;qYWoB$#QqrRkYrT4([oB$#QqW7k[k2l[7jo>DXjoYVGjoFl4
-!!)lX!!)WQ!s%KG!<)$[!<)$[!:]+N!<2*\!;GUU!;kmY!;,CR!;YaW!57Ops8LRKKE(uFec1:%
-rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8juX8i8!X8i8!X9&C'!<&u!!<&u!!<0&"!;NVt!3E7%rN#u!r2]kurN-#!\Z>c2
-rN#u!rN#u!ri?)"rN#u!qQ'YsnuMfkqlBbtrN#u!o;holqQ'c!XK2EmX8i7sX9/I(X8qak!!)hr
-!!)Vl!s#F(!<&u!!<0)"!:d,j!<&u"!3H/"qlBbtqlBeuXSr4qX8i7rX8i75XT._fec1:%s7Y"C
-KE(rUeYN6-k.LbF~>
-!<E0!johC3g4=hSg&M-Og&M-Og&_9.!<(UO!<(UO!<1[P!;P7M!8?-,rRq5Or7V,NrS%8O\_7#`
-rRq5OrRq5Orn7>PrRq5OqUtoLo%F'Dqq;#MrRq5Oo@a0EqUu#Og=cPtg&M-Lg&h?/g&UWr!!)iK
-!!)WE!s%'/!<(UO!<1^P!:ebC!<(UP!8@DPqq;#Mqq;&NgAV*Jg&M-Kg&M,cgAh3PgAca(s7Y1H
-JcG`Sg7eQ/k.1PC~>
-!<E0!johL1eVf@bjo>D[jo>D[joPPF!<)$[!<)$[!<2*\!;P[Y!9WDDrT4([r8mtZrT=+[\`Nkl
-rT4([rT4([roO1\rT4([qW7bXo&]oPqrRkYrT4([oB$#QqW7k[k2l[7jo>DXjoYVGjoFo5!!)iW
-!!)WQ!s%KG!<)$[!<2-\!:f1O!<)$\!9X7\qrRkYqrRnZk5GAVjo>DWjo>Cok5YJ\ec1:%s7Y"C
-KE(rUeYN6-k.LbF~>
-!<E0!johL1eS8juX8i8!X8i8"X8i8"X8i8"X8i8"X8i7uXSi.sXSi.tX8i7uX8i7-X8i7uX8i8!
-X8i8"X8i8!X8i7tX8i7uXSW"qX8i7tX8i8!X8i8"XSW"qX8i7tX8i8"X8i7kX8i7tX8i8"X8i7j
-X8i7qX8i7mX8i8"X8i7uXSr2#X8qgm!!)qurrE&"!!)qu!!)ntrrE&"!!)nt!!)hr!!'X4s6fm:
-s+C@Op=91qs8N;RV#TT>]`<Q~>
-!<E0!johC3g4=hSg&M-Og&M-Pg&M-Pg&M-Pg&M-Pg&M-NgAM$LgAM$Mg&M-Ng&M,[g&M-Ng&M-O
-g&M-Pg&M-Og&M-Mg&M-NgA:mJg&M-Mg&M-Og&M-PgA:mJg&M-Mg&M-Pg&M-Dg&M-Mg&M-Pg&M-C
-g&M-Jg&M-Fg&M-Pg&M-NgAV'Qg&U]t!!)rNrrE&P!!)rN!!)oMrrE&P!!)oM!!)iK!!'Xbs8W)P
-s+14Mp=fOts8N;WU&X9;\c@6~>
-!<E0!johL1eVf@bjo>D[jo>D\jo>D\jo>D\jo>D\jo>DZk5>;Xk5>;Yjo>DZjo>Cgjo>DZjo>D[
-jo>D\jo>D[jo>DYjo>DZk5,/Vjo>DYjo>D[jo>D\k5,/Vjo>DYjo>D\jo>DPjo>DYjo>D\jo>DO
-jo>DVjo>DRjo>D\jo>DZk5G>]joFu7!!)rZrrE&\!!)rZ!!)oYrrE&\!!)oY!!)iW!!'Xns8W)K
-s+C@Op=91qs8N;RV#TT>]`<Q~>
-!<E0!johL1eS8juXS`(sXS`(tXSi.nX8i8!X9/I(X8r4#!!)qu!!'F.!!)nt!!)u!!!*#"!!)u!
-!!)qu!!)Mi!!)nt!!)u!!!)Vl!!)nt!!*#"!!)Sk!!)nt!!*#"!!)Sk!!)eq!!)Vl!!*#"!!)eq
-!!)Vl!!)nt!!)u!!!)qu!!)nt!!)u!!!)qu!!)hr!!'U3s6fm:s+C@Op=91qs8N;RV#TT>]`<Q~>
-!<E0!johC3g4=hSgACsLgACsMgAM$Gg&M-Og&h?/g&V**!!)rN!!'F\!!)oM!!)uO!!*#P!!)uO
-!!)rN!!)NB!!)oM!!)uO!!)WE!!)oM!!*#P!!)TD!!)oM!!*#P!!)TD!!)fJ!!)WE!!*#P!!)fJ
-!!)WE!!)oM!!)uO!!)rN!!)oM!!)uO!!)rN!!)iK!!'Uas8W)Ps+14Mp=fOts8N;WU&X9;\c@6~>
-!<E0!johL1eVf@bk555Xk555Yk5>;Sjo>D[joYVGjoGAB!!)rZ!!'Fh!!)oY!!)u[!!*#\!!)u[
-!!)rZ!!)NN!!)oY!!)u[!!)WQ!!)oY!!*#\!!)TP!!)oY!!*#\!!)TP!!)fV!!)WQ!!*#\!!)fV
-!!)WQ!!)oY!!)u[!!)rZ!!)oY!!)u[!!)rZ!!)iW!!'Ums8W)Ks+C@Op=91qs8N;RV#TT>]`<Q~>
-!<E0!johL1eS8juX8i7sX8i7uX9/I(X8r7$!!)u!!!)u!!!)u!!!)u!!s#F(!;rnu!4Js/!;`bs
-!<&u!!<0&"!<&u!!<&u!!:Quh!;iht!<&u!!;!8l!;ikp!;!8l!;ikp!;*>m!;EPp!;!;h!;W\r
-!;*>m!;`bs!<&u!!;rnu!;iht!<&u!!<&u!!;W\r!4f32mf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=hSg&M-Lg&M-Ng&h?/g&V-+!!)uO!!)uO!!)uO!!)uO!s%'/!;tON!4LS]!;bCL
-!<(UO!<1[P!<(UO!<(UO!:SVA!;kIM!<(UO!;"nE!;kLI!;"nE!;kLI!;+tF!;G1I!;"qA!;Y=K
-!;+tF!;bCL!<(UO!;tON!;kIM!<(UO!<(UO!;Y=K!4gh`s8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf@bjo>DXjo>DZjoYVGjoGDC!!)u[!!)u[!!)u[!!)u[!s%KG!;tsZ!4M"i!;bgX
-!<)$[!<2*\!<)$[!<)$[!:T%M!;kmY!<)$[!;#=Q!;kpU!;#=Q!;kpU!;,CR!;GUU!;#@M!;YaW
-!;,CR!;bgX!<)$[!;tsZ!;kmY!<)$[!<)$[!;YaW!4h7ls8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8juX8i7sX8i7uX9/I(X8r4#!!*#"rrE&"!!)u!!!)u!!s#F(!<&u!!;rqu!55H6
-!<&u!!<0&"!<&u!!<0&"!<&u!!<0&"!<&u!!;!8l!;iht!<&u!!;!8l!;EPp!:m2k!;EPp!;ikt
-!;rnu!<&u!!;iht!;`es!;NVq!;W\r!;ikt!;rnu!<&u!!<&u!!<0&"!;rnu!;`bs!<0&"!<0&"
-!<&u!!<0&"!<&u!!55K6mf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=hSg&M-Lg&M-Ng&h?/g&V**!!*#PrrE&P!!)uO!!)uO!s%'/!<(UO!;tRN!57(d
-!<(UO!<1[P!<(UO!<1[P!<(UO!<1[P!<(UO!;"nE!;kIM!<(UO!;"nE!;G1I!:nhD!;G1I!;kLM
-!;tON!<(UO!;kIM!;bFL!;P7J!;Y=K!;kLM!;tON!<(UO!<(UO!<1[P!;tON!;bCL!<1[P!<1[P
-!<(UO!<1[P!<(UO!57+ds8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf@bjo>DXjo>DZjoYVGjoGAB!!*#\rrE&\!!)u[!!)u[!s%KG!<)$[!;u!Z!57Lp
-!<)$[!<2*\!<)$[!<2*\!<)$[!<2*\!<)$[!;#=Q!;kmY!<)$[!;#=Q!;GUU!:o7P!;GUU!;kpY
-!;tsZ!<)$[!;kmY!;bjX!;P[V!;YaW!;kpY!;tsZ!<)$[!<)$[!<2*\!;tsZ!;bgX!<2*\!<2*\
-!<)$[!<2*\!<)$[!57Ops8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!jp%X3eS8j#XSi.tXSi,!XSMqqX98O)X8o@$!<'"q!!'+t!;ikt!55K2!<'"t!;rqs!<'"r
-!;3Gk!;rqs!;*Aj!;`er!;3Gk!;`er!;rqu!;rqq!;iht!;`es!;W_q!<'"u!;`es!;rqq!;rqt
-!<'"s!;iks!<'"r!<0(s!55K6mf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!jp%O5g4=h/gAM$MgAM!OgA1gJg&qE0g&Tk+!<(XJ!!(aM!;kLM!57+`!<(XM!;tRL!<(XK
-!;5(D!;tRL!;,"C!;bFK!;5(D!;bFK!;tRN!;tRJ!;kIM!;bFL!;Y@J!<(XN!;bFL!;tRJ!;tRM
-!<(XL!;kLL!<(XK!<1^L!57+ds8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!jp%X3eVf@Jk5>;Yk5>8[k5#)Vjob\HjoFQC!<)'V!!)0Y!;kpY!57Ol!<)'Y!;u!X!<)'W
-!;5LP!;u!X!;,FO!;bjW!;5LP!;bjW!;u!Z!;u!V!;kmY!;bjX!;YdV!<)'Z!;bjX!;u!V!;u!Y
-!<)'X!;kpX!<)'W!<2-X!57Ops8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8iMXF[I(XOaKQmf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g4@t/g=G!Xs8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k(2ZGk18\ps8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8iMXF[I(XOaKQmf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g4@t/g=G!Xs8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k(2ZGk18\ps8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8iMXF[I(XOaKQmf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g4@t/g=G!Xs8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k(2ZGk18\ps8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8iMXF[I(XOaKQmf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g4@t/g=G!Xs8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k(2ZGk18\ps8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8iMXF[I(XOaKQmf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g4@t/g=G!Xs8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k(2ZGk18\ps8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8iMXF[I(XOaKQmf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g4@t/g=G!Xs8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k(2ZGk18\ps8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8jtXSr2#X8r7$r;churW)u"rW)u"q>gPsq>^MsrW)u"rW)u"q>gMrrVuu#!.h5&
-XIZHmmf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=hRgAV'Qg&V-+r;ciNrW)uPrW)uPq>gQLq>^NLrW)uPrW)uPq>gNKrVuuQ!.ijT
-g7?sts8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf@ak5G>]joGDCr;ciZrW)u\rW)u\q>gQXq>^NXrW)u\rW)u\q>gNWrVuu]!.j9`
-k+1Z7s8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8juX8i8"XT&;#X8i8!X8i8"XT&;"X8i8"X9J[+X8o?'!<0&"!<&u%!3E7%!<0&"
-!<0&+!3E7%XK2E'X8r7$rr@VOJZPEDs6fm:s+C@Op=91qs8N;RV#TT>]`<Q~>
-!<E0!johC3g4=hSg&M-PgA_0Qg&M-Og&M-PgA_0Pg&M-Pg'.Q2g&Tj\!<1[P!<(US!8?-,!<1[P
-!<1[Y!8?-,g=cP\g&V-+rr@W(J_H[Ks8W)Ps+14Mp=fOts8N;WU&X9;\c@6~>
-!<E0!johL1eVf@bjo>D\k5PG]jo>D[jo>D\k5PG\jo>D\jothJjoFQ+!<2*\!<)$_!9WDD!<2*\
-!<2*e!9WDDk2l[+joGDCrr@W4J``Ncs8W)Ks+C@Op=91qs8N;RV#TT>]`<Q~>
-!<E0!jp.^4eS8j#X8r1"!W];%qlC&'XK2E'!3E7%ri?;(XK2E'X8r7$!!)u!#QUs-!3?1%X8r7$
-#lq'.!3E7%XK2F#X8i7uXT&9OXF[IKXT._fec1:%s7Y"CKE(rUeYN6-k.LbF~>
-!<E0!jp.U6g4=h/g&V')!W^pSqq;;Ug=cP\!8?-,rn7PVg=cP\g&V-+!!)uO#QWT4!87G,g&V-+
-#lr]5!8?-,g=cQ*g&M-NgA_/(g4@tRgAh3PgAca(s7Y1HJcG`Sg7eQ/k.1PC~>
-!<E0!jp.^4eVf@JjoG>A!W_?_qrS.ak2l[+!9WDDroOCbk2l[+joGDC!!)u[#QX#L!9O:DjoGDC
-#ls,M!9WDDk2l[Bjo>DZk5PF4k(2Zjk5YJ\ec1:%s7Y"CKE(rUeYN6-k.LbF~>
-!<E0!jp.^4eS8j#X8r*u!!)nt#QUs-!3?1%X8r.!!!)nt!s#F(!<&u&!3?1%X8r.!!!)qu!!)bp
-rr@VOJZPZKs6fm:s+C@Op=91qs8N;RV#TT>]`<Q~>
-!<E0!jp.U6g4=h/g&V!'!!)oM#QWT4!87G,g&V$(!!)oM!s%'/!<(UT!87G,g&V$(!!)rN!!)cI
-rr@W(J_HpRs8W)Ps+14Mp=fOts8N;WU&X9;\c@6~>
-!<E0!jp.^4eVf@JjoG8?!!)oY#QX#L!9O:DjoG;@!!)oY!s%KG!<)$`!9O:DjoG;@!!)rZ!!)cU
-rr@W4J``cjs8W)Ks+C@Op=91qs8N;RV#TT>]`<Q~>
-!<E0!jp.^4eS8j#X8r*u!!)nt#QUs-!3E7%X8r.!!!)ntr;cet"TYX*!3?1tX8i7tXSi-MXF[IC
-XT._fec1:%s7Y"CKE(rUeYN6-k.LbF~>
-!<E0!jp.U6g4=h/g&V!'!!)oM#QWT4!8?-,g&V$(!!)oMr;cfM"T[91!87GMg&M-MgAM#&g4@tJ
-gAh3PgAca(s7Y1HJcG`Sg7eQ/k.1PC~>
-!<E0!jp.^4eVf@JjoG8?!!)oY#QX#L!9WDDjoG;@!!)oYr;cfY"T[]I!9O:Yjo>DYk5>:2k(2Zb
-k5YJ\ec1:%s7Y"CKE(rUeYN6-k.LbF~>
-!<E0!jp.^4eS8j#X8r*u!!)nt#QUs-!3E7%X8r.!!!)nt!s#F(!<&u&!3E7%X8r.!!!)bp!!%SO
-JZPEDs6fm:s+C@Op=91qs8N;RV#TT>]`<Q~>
-!<E0!jp.U6g4=h/g&V!'!!)oM#QWT4!8?-,g&V$(!!)oM!s%'/!<(UT!8?-,g&V$(!!)cI!!%T(
-J_H[Ks8W)Ps+14Mp=fOts8N;WU&X9;\c@6~>
-!<E0!jp.^4eVf@JjoG8?!!)oY#QX#L!9WDDjoG;@!!)oY!s%KG!<)$`!9WDDjoG;@!!)cU!!%T4
-J``Ncs8W)Ks+C@Op=91qs8N;RV#TT>]`<Q~>
-!<E0!jp.^4eS8j#X8r*u!!)nt!s#F(!<0)"!;iht!;iht!<&u$!3E7%riH,"qlBbtr2]kurN#u!
-JZOF(SZMkZrmh%$s8VfCs+C@O#1]OLk2s>WJ,~>
-!<E0!jp.U6g4=h/g&V!'!!)oM!s%'/!<1^P!;kIM!;kIM!<(UR!8?-,rn@APqq;#Mr7V,NrRq5O
-J_G\/S_F,Drn@C's8VfHs+14M#25dNk2s5TJ,~>
-!<E0!jp.^4eVf@JjoG8?!!)oY!s%KG!<2-\!;kmY!;kmY!<)$^!9WDDroX4\qrRkYr8mtZrT4([
-J`_OGS`]tPrmh%$s8VfCs+C@O#1]OLk2s>WJ,~>
-!<E0!johL1eS8juX8i8!X9/I(X8r4#!!*#"!!*#"rrDqt!!)nt!!)u!!s#F(!<0)"!;iht!;rqu
-!<0&"!;rqu!.h5&XJDrtmf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=hSg&M-Og&h?/g&V**!!*#P!!*#PrrDrM!!)oM!!)uO!s%'/!<1^P!;kIM!;tRN
-!<1[P!;tRN!.ijTg8*I&s8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf@bjo>D[joYVGjoGAB!!*#\!!*#\rrDrY!!)oY!!)u[!s%KG!<2-\!;kmY!;u!Z
-!<2*\!;u!Z!.j9`k+q/>s8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8jtXSi.tXSi.uXSr5!X8i8!XS`(tXSMnsXSr5!X8i8!XS`(tX8r=&rW)hsrr@VO
-JZPZKs6fm:s+C@Op=91qs8N;RV#TT>]`<Q~>
-!<E0!johC3g4=hRgAM$MgAM$NgAV*Og&M-OgACsMgA1dLgAV*Og&M-OgACsMg&V3-rW)iLrr@W(
-J_HpRs8W)Ps+14Mp=fOts8N;WU&X9;\c@6~>
-!<E0!johL1eVf@ak5>;Yk5>;Zk5GA[jo>D[k555Yk5#&Xk5GA[jo>D[k555YjoGJErW)iXrr@W4
-J``cjs8W)Ks+C@Op=91qs8N;RV#TT>]`<Q~>
-!<E0!johL1eS8iMXF[I(XOaKQmf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g4@t/g=G!Xs8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k(2ZGk18\ps8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8iMXF[I(XOaKQmf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g4@t/g=G!Xs8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k(2ZGk18\ps8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8iMXF[I(XOaKQmf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g4@t/g=G!Xs8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k(2ZGk18\ps8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8iMXF[I(XOaKQmf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g4@t/g=G!Xs8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k(2ZGk18\ps8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8iMXF[I(XOaKQmf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g4@t/g=G!Xs8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k(2ZGk18\ps8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8iMXF[I(XOaKQmf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g4@t/g=G!Xs8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k(2ZGk18\ps8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8iMXF[I(XOaKQmf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g4@t/g=G!Xs8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k(2ZGk18\ps8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8iMXF[I(XOaKQmf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g4@t/g=G!Xs8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k(2ZGk18\ps8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8iMXF[I(XOaKQmf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g4@t/g=G!Xs8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k(2ZGk18\ps8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8iMXF[I(XOaKQmf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g4@t/g=G!Xs8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k(2ZGk18\ps8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8iMXF[I(XOaKQmf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g4@t/g=G!Xs8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k(2ZGk18\ps8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8iMXF[I(XOaKQmf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g4@t/g=G!Xs8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k(2ZGk18\ps8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8iMXF[I(XOaKQmf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g4@t/g=G!Xs8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k(2ZGk18\ps8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8iMXF[I(XOaKQmf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g4@t/g=G!Xs8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k(2ZGk18\ps8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8iMXF[I(XOaKQmf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g4@t/g=G!Xs8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k(2ZGk18\ps8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8iMXF[I(XOaKQmf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g4@t/g=G!Xs8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k(2ZGk18\ps8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8iMXF[I(XOaKQmf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g4@t/g=G!Xs8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k(2ZGk18\ps8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8iMXF[I(XOaKQmf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g4@t/g=G!Xs8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k(2ZGk18\ps8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8iMXF[I(XOaKQmf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g4@t/g=G!Xs8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k(2ZGk18\ps8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8iMXF[I(XOaKQmf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g4@t/g=G!Xs8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k(2ZGk18\ps8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8i\X8i7WX8i7qXT&:kX8i7`XT&;!XSW"qX8i7rX8i6OXLtY7mf(c:KE(uFec1:%
-rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g:g&M-0g&M-JgA_0Dg&M-9gA_0OgA:mJg&M-Kg&M,(g:Z/>s8LaPJcGcDgAca(
-rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?Ijo>D<jo>DVk5PGPjo>DEk5PG[k5,/Vjo>DWjo>C4k.KjVs8LRKKE(uFec1:%
-rs%#Ls5rIW!.Y~>
-!<E0!joqR2eS8j#rW)u"rW(u[!!'p<!!)bp!!(lW!!)bp!!)Sk!!)5a!W];%rN#u!rN#u!rN-#!
-qQ0\sJZQMcs6fm:s+C@Op=91qs8N;RV#TT>]`<Q~>
-!<E0!joqI4g4=h/rW)uPrW)!4!!'pj!!)cI!!(m0!!)cI!!)TD!!)6:!W^pSrRq5OrRq5OrS%8O
-qV(rLJ_Icjs8W)Ps+14Mp=fOts8N;WU&X9;\c@6~>
-!<E0!joqR2eVf@JrW)u\rW)!@!!'q!!!)cU!!(m<!!)cU!!)TP!!)6F!W_?_rT4([rT4([rT=+[
-qW@eXJ`aW-s8W)Ks+C@Op=91qs8N;RV#TT>]`<Q~>
-!<E0!jp7d5eS8j#X8i8"X8i7[X8i7<X8i7AX8i7QX9&C'!;NVq!<0&$!3?1tX9&C'!.h5aXT._f
-ec1:%s7Y"CKE(rUeYN6-k.LbF~>
-!<E0!jp7[7g4=h/g&M-Pg&M-4g&M,jg&M,og&M-*g&_9.!;P7J!<1[R!87GMg&_9.!.ik:gAh3P
-gAca(s7Y1HJcG`Sg7eQ/k.1PC~>
-!<E0!jp7d5eVf@Jjo>D\jo>D@jo>D!jo>D&jo>D6joPPF!;P[V!<2*^!9O:YjoPPF!.j:Fk5YJ\
-ec1:%s7Y"CKE(rUeYN6-k.LbF~>
-!<E0!jp\'9eS8j#X8o=%XK2F"XSr5!XSr5!XSr4oXS`(sXT&;#XT&;!XSi.uXT&8#XSr4tXS`(s
-XSi.rXSr2%X8o?'quHYrrW)hsr;churr<&#rW)PkrW)hsrVuu#!;*Al!;ikq!;*>p!3E7%q5aPr
-qlBbtq5aPrJZQMcs6fm:s+C@Op=91qs8N;RV#TT>]`<Q~>
-!<E0!jp[s;g4=h/g&Th,g=cQ)gAV*OgAV*OgAV*HgACsLgA_0QgA_0OgAM$NgA_-QgAV*MgACsL
-gAM$KgAV'Sg&Tj\quHZKrW)iLr;ciNrr<&QrW)QDrW)iLrVuuQ!;,"E!;kLJ!;+tI!8?-,q:YfK
-qq;#Mq:YfKJ_Icjs8W)Ps+14Mp=fOts8N;WU&X9;\c@6~>
-!<E0!jp\'9eVf@JjoFNDk2l[Ak5GA[k5GA[k5GATk555Xk5PG]k5PG[k5>;Zk5PD]k5GAYk555X
-k5>;Wk5G>_joFQ+quHZWrW)iXr;ciZrr<&]rW)QPrW)iXrVuu]!;,FQ!;kpV!;,CU!9WDDq;qYW
-qrRkYq;qYWJ`aW-s8W)Ks+C@Op=91qs8N;RV#TT>]`<Q~>
-!<E0!jp\'9eS8j#X8o=%XK2F#X8i8"X8i8"X8i7uX8i7nX8i7rX9\g-!3E7%XK2F#X8i8"XT&;"
-X8i8"X8i8!X8i8"X8i8!X8i8!X8i8"XT&;"X8i7pX8i7uX8i8!X8i8"XT&;"X8i7kX8i7uX8i8"
-XT&:kX8i7uX8i8!X8i7mX9/I(X8r't!!)nt!!)hr!!%SO]WD/$rmh%$s8VfCs+C@O#1]OLk2s>W
-J,~>
-!<E0!jp[s;g4=h/g&Th,g=cQ*g&M-Pg&M-Pg&M-Ng&M-Gg&M-Kg'@]4!8?-,g=cQ*g&M-PgA_0P
-g&M-Pg&M-Og&M-Pg&M-Og&M-Og&M-PgA_0Pg&M-Ig&M-Ng&M-Og&M-PgA_0Pg&M-Dg&M-Ng&M-P
-gA_0Dg&M-Ng&M-Og&M-Fg&h?/g&Us&!!)oM!!)iK!!%T(]\<Dcrn@C's8VfHs+14M#25dNk2s5T
-J,~>
-!<E0!jp\'9eVf@JjoFNDk2l[Bjo>D\jo>D\jo>DZjo>DSjo>DWjp1tL!9WDDk2l[Bjo>D\k5PG\
-jo>D\jo>D[jo>D\jo>D[jo>D[jo>D\k5PG\jo>DUjo>DZjo>D[jo>D\k5PG\jo>DPjo>DZjo>D\
-k5PGPjo>DZjo>D[jo>DRjoYVGjoG5>!!)oY!!)iW!!%T4]]T7ormh%$s8VfCs+C@O#1]OLk2s>W
-J,~>
-!<E0!jp\'9eS8j#X8o?'!3?2"X8i7uX9em.X8o?'!3E7%orJ,nq5jSrp8e5ori?)"rN#u!ri?)"
-oW/#mri?)"r2]kuri?)"pT+>prN#u!qlBl"XK2F#X8i7kX8i8!X8i7uX8i7kX8i7uX8i7iX8i8"
-X8i7rX8i7tX8i7rX8i6OXLtY7mf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!jp[s;g4=h/g&Tj\!87GPg&M-Ng'Ic5g&Tj\!8?-,p"BBGq:biKp=]KHrn7>PrRq5Orn7>P
-o\'9Frn7>Pr7V,Nrn7>PpY#TIrRq5Oqq;,Pg=cQ*g&M-Dg&M-Og&M-Ng&M-Dg&M-Ng&M-Bg&M-P
-g&M-Kg&M-Mg&M-Kg&M,(g:Z/>s8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!jp\'9eVf@JjoFQ+!9O:\jo>DZjp;%MjoFQ+!9WDDp#Z5Sq<%\Wp>u>TroO1\rT4([roO1\
-o]?,RroO1\r8mtZroO1\pZ;GUrT4([qrRt\k2l[Bjo>DPjo>D[jo>DZjo>DPjo>DZjo>DNjo>D\
-jo>DWjo>DYjo>DWjo>C4k.KjVs8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!jp\'9eS8j#X8o?'!3?2"XSMqsX9J[+X8o?'!;3Dn!;W\r!;W_o!<0&"!<&u!!<'"t!;rqr
-!<0&"!;NVq!;EPp!<&u!!;ii"!3E7%rN#u!nuMfkrN#u!r2]kunuMfkqlK_roW/#mri?)"qQ'Ys
-qQ'Ysq5aPrJZQMcs6fm:s+C@Op=91qs8N;RV#TT>]`<Q~>
-!<E0!jp[s;g4=h/g&Tj\!87GPgA1gLg'.Q2g&Tj\!;5%G!;Y=K!;Y@H!<1[P!<(UO!<(XM!;tRK
-!<1[P!;P7J!;G1I!<(UO!;kIP!8?-,rRq5Oo%F'DrRq5Or7V,No%F'DqqCuKo\'9Frn7>PqUtoL
-qUtoLq:YfKJ_Icjs8W)Ps+14Mp=fOts8N;WU&X9;\c@6~>
-!<E0!jp\'9eVf@JjoFQ+!9O:\k5#)XjothJjoFQ+!;5IS!;YaW!;YdT!<2*\!<)$[!<)'Y!;u!W
-!<2*\!;P[V!;GUU!<)$[!;km\!9WDDrT4([o&]oPrT4([r8mtZo&]oPqr[hWo]?,RroO1\qW7bX
-qW7bXq;qYWJ`aW-s8W)Ks+C@Op=91qs8N;RV#TT>]`<Q~>
-!<E0!jp.^4eS8j#X8r7$rrE&"!!)eq"9>M'X8qmo!!)hr!!)ks!!)u!!!*#"!!)u!!!)hr!!*#"
-!!)u!!!*#"!!)eq!!)bp!!)u!!!)nt!s#F(!<&u!!:m2k!<&u!!;rnu!:m2k!;EPp!;3Gj!;iht
-!;`bs!;W\r!.h5aXT._fec1:%s7Y"CKE(rUeYN6-k.LbF~>
-!<E0!jp.U6g4=h/g&V-+rrE&P!!)fJ"9@-Ug&Ud!!!)iK!!)lL!!)uO!!*#P!!)uO!!)iK!!*#P
-!!)uO!!*#P!!)fJ!!)cI!!)uO!!)oM!s%'/!<(UO!:nhD!<(UO!;tON!:nhD!;G1I!;5(C!;kIM
-!;bCL!;Y=K!.ik:gAh3PgAca(s7Y1HJcG`Sg7eQ/k.1PC~>
-!<E0!jp.^4eVf@JjoGDCrrE&\!!)fV"9@QajoG&9!!)iW!!)lX!!)u[!!*#\!!)u[!!)iW!!*#\
-!!)u[!!*#\!!)fV!!)cU!!)u[!!)oY!s%KG!<)$[!:o7P!<)$[!;tsZ!:o7P!;GUU!;5LO!;kmY
-!;bgX!;YaW!.j:Fk5YJ\ec1:%s7Y"CKE(rUeYN6-k.LbF~>
-!<E0!jp.^4eS8j#X8r7$rrE#!!!)u!!!*#"rr<,%!!)Ym!!*#"!!)u!!!)ks!!*#"rrE&"!!)u!
-!!*#"!!)u!!!*#"!!*#"rrE#!!!)u!!!*#"!!*#"!!)nt!!)qu!!)u!!!*#"!!)u!!!)Sk!!)qu
-!!*#"rrDVk!!)qu!!)u!!!)Pj!!)ks!!)ks!!)hr!!%SO]WD/$rmh%$s8VfCs+C@O#1]OLk2s>W
-J,~>
-!<E0!jp.U6g4=h/g&V-+rrE#O!!)uO!!*#Prr<,S!!)ZF!!*#P!!)uO!!)lL!!*#PrrE&P!!)uO
-!!*#P!!)uO!!*#P!!*#PrrE#O!!)uO!!*#P!!*#P!!)oM!!)rN!!)uO!!*#P!!)uO!!)TD!!)rN
-!!*#PrrDWD!!)rN!!)uO!!)QC!!)lL!!)lL!!)iK!!%T(]\<Dcrn@C's8VfHs+14M#25dNk2s5T
-J,~>
-!<E0!jp.^4eVf@JjoGDCrrE#[!!)u[!!*#\rr<,_!!)ZR!!*#\!!)u[!!)lX!!*#\rrE&\!!)u[
-!!*#\!!)u[!!*#\!!*#\rrE#[!!)u[!!*#\!!*#\!!)oY!!)rZ!!)u[!!*#\!!)u[!!)TP!!)rZ
-!!*#\rrDWP!!)rZ!!)u[!!)QO!!)lX!!)lX!!)iW!!%T4]]T7ormh%$s8VfCs+C@O#1]OLk2s>W
-J,~>
-!<E0!joqR2eS8j#rW)r!!!)qur;cetrr<,%!!)VlrW)nur;c_rrW!&%!!',"!<9/"!<9.u!;rqt
-!!95%!<'"t!;rqt!;rqr!<'"t!<0)!!<9/"!;3Gk!<'"u!!95%!;3Gk!<0(t!:d/i!;iht!;rqr
-!<'"s!.h5cXT._fec1:%s7Y"CKE(rUeYN6-k.LbF~>
-!<E0!joqI4g4=h/rW)rO!!)rNr;cfMrr<,S!!)WErW)oNr;c`KrW!&S!!(aP!<:dP!<:dN!;tRM
-!!:jS!<(XM!;tRM!;tRK!<(XM!<1^O!<:dP!;5(D!<(XN!!:jS!;5(D!<1^M!:eeB!;kIM!;tRK
-!<(XL!.ik<gAh3PgAca(s7Y1HJcG`Sg7eQ/k.1PC~>
-!<E0!joqR2eVf@JrW)r[!!)rZr;cfYrr<,_!!)WQrW)oZr;c`WrW!&_!!)0\!<;3\!<;3Z!;u!Y
-!!;9_!<)'Y!;u!Y!;u!W!<)'Y!<2-[!<;3\!;5LP!<)'Z!!;9_!;5LP!<2-Y!:f4N!;kmY!;u!W
-!<)'X!.j:Hk5YJ\ec1:%s7Y"CKE(rUeYN6-k.LbF~>
-!<E0!johL1eS8iMXF[I(XOaKQmf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g4@t/g=G!Xs8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k(2ZGk18\ps8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8iMXF[I(XOaKQmf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g4@t/g=G!Xs8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k(2ZGk18\ps8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8iMXF[I(XOaKQmf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g4@t/g=G!Xs8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k(2ZGk18\ps8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8iMXF[I(XOaKQmf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g4@t/g=G!Xs8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k(2ZGk18\ps8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8iMXF[I(XOaKQmf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g4@t/g=G!Xs8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k(2ZGk18\ps8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8iMXF[I(XOaKQmf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g4@t/g=G!Xs8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k(2ZGk18\ps8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8iMXF[I(XOaKQmf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g4@t/g=G!Xs8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k(2ZGk18\ps8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8iMXF[I(XOaKQmf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g4@t/g=G!Xs8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k(2ZGk18\ps8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8iMXF[I(XOaKQmf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g4@t/g=G!Xs8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k(2ZGk18\ps8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8iMXF[I(XOaKQmf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g4@t/g=G!Xs8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k(2ZGk18\ps8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8iMXF[I(XOaKQmf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g4@t/g=G!Xs8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k(2ZGk18\ps8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8iMXF[I(XOaKQmf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g4@t/g=G!Xs8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k(2ZGk18\ps8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8iMXF[I(XOaKQmf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g4@t/g=G!Xs8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k(2ZGk18\ps8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8iMXF[I(XOaKQmf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g4@t/g=G!Xs8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k(2ZGk18\ps8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8iMXF[I(XOaKQmf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g4@t/g=G!Xs8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k(2ZGk18\ps8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8iMXF[I(XOaKQmf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g4@t/g=G!Xs8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k(2ZGk18\ps8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8iMXF[I(XOaKQmf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g4@t/g=G!Xs8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k(2ZGk18\ps8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8iMXF[I(XOaKQmf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g4@t/g=G!Xs8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k(2ZGk18\ps8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8iMXF[I(XOaKQmf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g4@t/g=G!Xs8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k(2ZGk18\ps8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8iMXF[I(XOaKQmf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g4@t/g=G!Xs8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k(2ZGk18\ps8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8iMXF[I(XOaKQmf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g4@t/g=G!Xs8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k(2ZGk18\ps8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8iMXF[I(XOaKQmf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g4@t/g=G!Xs8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k(2ZGk18\ps8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8iMXF[I(XOaKQmf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g4@t/g=G!Xs8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k(2ZGk18\ps8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8iMXF[I(XOaKQmf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g4@t/g=G!Xs8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k(2ZGk18\ps8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8iMXF[I(XOaKQmf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g4@t/g=G!Xs8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k(2ZGk18\ps8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8iMXF[I(XOaKQmf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g4@t/g=G!Xs8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k(2ZGk18\ps8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8iMXF[I(XOaKQmf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g4@t/g=G!Xs8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k(2ZGk18\ps8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8iMXF[I(XOaKQmf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g4@t/g=G!Xs8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k(2ZGk18\ps8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8iMXF[I(XOaKQmf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g4@t/g=G!Xs8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k(2ZGk18\ps8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8iMXF[I(XOaKQmf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g4@t/g=G!Xs8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k(2ZGk18\ps8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8iMXF[I(XOaKQmf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g4@t/g=G!Xs8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k(2ZGk18\ps8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8iMXF[I(XOaKQmf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g4@t/g=G!Xs8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k(2ZGk18\ps8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8iMXF[I(XOaKQmf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g4@t/g=G!Xs8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k(2ZGk18\ps8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8iMXF[I(XOaKQmf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g4@t/g=G!Xs8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k(2ZGk18\ps8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8iMXF[I(XOaKQmf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g4@t/g=G!Xs8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k(2ZGk18\ps8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8iMXF[I(XOaKQmf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g4@t/g=G!Xs8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k(2ZGk18\ps8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8iMXF[I(XOaKQmf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g4@t/g=G!Xs8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k(2ZGk18\ps8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8iMXF[I(XOaKQmf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g4@t/g=G!Xs8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k(2ZGk18\ps8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8iMXF[I(XOaKQmf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g4@t/g=G!Xs8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k(2ZGk18\ps8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8iMXF[I(XOaKQmf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g4@t/g=G!Xs8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k(2ZGk18\ps8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8iMXF[I(XOaKQmf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g4@t/g=G!Xs8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k(2ZGk18\ps8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8iMXF[I(XOaKQmf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g4@t/g=G!Xs8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k(2ZGk18\ps8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8iMXF[I(XOaKQmf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g4@t/g=G!Xs8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k(2ZGk18\ps8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8iMXF[I(XOaKQmf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g4@t/g=G!Xs8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k(2ZGk18\ps8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8iMXF[I(XOaKQmf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g4@t/g=G!Xs8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k(2ZGk18\ps8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8iMXF[I(XOaKQmf(c:KE(uDKE(rUeYN6-k.LbF~>
-!<E0!johC3g4=g+g4@t/g=G!Xs8LaPJcGcBJcG`Sg7eQ/k.1PC~>
-!<E0!johL1eVf?:k(2ZGk18\ps8LRKKE(uDKE(rUeYN6-k.LbF~>
-!<E0!johL1eS8iMXF[I(XOaKQmf(c:K)krCKE(rUeYN6-k.LbF~>
-!<E0!johC3g4=g+g4@t/g=G!Xs8LaPJH5`AJcG`Sg7eQ/k.1PC~>
-!<E0!johL1eVf?:k(2ZGk18\ps8LRKK)krCKE(rUeYN6-k.LbF~>
-!<E0!johL1eS8iMXF[I(XOaKQmf(c:KCZ_Urs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g4@t/g=G!Xs8LaPJb$\Xrs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k(2ZGk18\ps8LRKKCZ_Urs%#Ls5rIW!.Y~>
-!<E0!johL1eS8iMXF[I(XOaKQmf(c:KCJmFeYN6-k.LbF~>
-!<E0!johC3g4=g+g4@t/g=G!Xs8LaPJai[Dg7eQ/k.1PC~>
-!<E0!johL1eVf?:k(2ZGk18\ps8LRKKCJmFeYN6-k.LbF~>
-!<E0!johL1eS8iMXF[I(XOaKQmf(c:K)iUWrs=>Xs4*qFk2s>WJ,~>
-!<E0!johC3g4=g+g4@t/g=G!Xs8LaPJH3RZrs=8Vs4X1Hk2s5TJ,~>
-!<E0!johL1eVf?:k(2ZGk18\ps8LRKK)iUWrs=>Xs4*qFk2s>WJ,~>
-!<E0!johL1eS8iMXF[I(XOaKQmf(c:K*&ads7k.EK*f6ks4*qFk2s>WJ,~>
-!<E0!johC3g4=g+g4@t/g=G!Xs8LaPJHE^gs7k=JJI03ns4X1Hk2s5TJ,~>
-!<E0!johL1eVf?:k(2ZGk18\ps8LRKK*&ads7k.EK*f6ks4*qFk2s>WJ,~>
-!<E0!johL1eS8iMXF[I(XOaKQmf(c:KE&Xbs7t4FK*f6ks4*qFk2s>WJ,~>
-!<E0!johC3g4=g+g4@t/g=G!Xs8LaPJcEUes7tCKJI03ns4X1Hk2s5TJ,~>
-!<E0!johL1eVf?:k(2ZGk18\ps8LRKKE&Xbs7t4FK*f6ks4*qFk2s>WJ,~>
-!<E0!johL1eS8iMXF[I(XOaKQmf(c:KE&Xbs8(:GKE&Xbrs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g4@t/g=G!Xs8LaPJcEUes8(ILJcEUers%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k(2ZGk18\ps8LRKKE&Xbs8(:GKE&Xbrs%#Ls5rIW!.Y~>
-!<E0!johL1eS8iMXF[I(XOaKQmf(c:KDrRas81@HKE&Xbrs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g4@t/g=G!Xs8LaPJc<Ods81OMJcEUers%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k(2ZGk18\ps8LRKKDrRas81@HKE&Xbrs%#Ls5rIW!.Y~>
-!<E0!johL1eS8iMXF[I(XOaKQmf(c:KDrRas8:FIKDrRars%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g4@t/g=G!Xs8LaPJc<Ods8:UNJc<Odrs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k(2ZGk18\ps8LRKKDrRas8:FIKDrRars%#Ls5rIW!.Y~>
-!<E0!johL1eS8iMXF[I(XOaKQmf(c:KDiL`s8CLJKDrRars%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g4@t/g=G!Xs8LaPJc3Ics8C[OJc<Odrs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k(2ZGk18\ps8LRKKDiL`s8CLJKDrRars%#Ls5rIW!.Y~>
-!<E0!johL1eS8iMXF[I(XOaKQmf(c:KDiL`s8LRKKDiL`rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g4@t/g=G!Xs8LaPJc3Ics8LaPJc3Icrs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k(2ZGk18\ps8LRKKDiL`s8LRKKDiL`rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8iMXF[I(XOaKQmf(c:KD`F_s8UXLKDiL`rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g4@t/g=G!Xs8LaPJc*Cbs8UgQJc3Icrs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k(2ZGk18\ps8LRKKD`F_s8UXLKDiL`rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8iMXF[I(XOaKQmf(c:KD`F_rrU`'KD`F_rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g4@t/g=G!Xs8LaPJc*CbrrUo*Jc*Cbrs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k(2ZGk18\ps8LRKKD`F_rrU`'KD`F_rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8iMXF[I(XOaKQmf(c:KDW=^s8IZK^&S*:eYN6-k.LbF~>
-!<E0!johC3g4=g+g4@t/g=G!Xs8LaPJc!:as8ITI_Z0W?g7eQ/k.1PC~>
-!<E0!johL1eVf?:k(2ZGk18\ps8LRKKDW=^s8IZK^&S*:eYN6-k.LbF~>
-!<E0!johL1eS8iMXF[I(XOaKQmf(c:KDW=`s+>t$^&S*:eYN6-k.LbF~>
-!<E0!johC3g4=g+g4@t/g=G!Xs8LaPJc!:cs+,au_Z0W?g7eQ/k.1PC~>
-!<E0!johL1eVf?:k(2ZGk18\ps8LRKKDW=`s+>t$^&S*:eYN6-k.LbF~>
-!<E0!johL1eS8iMXF[I(XOaKQmf(c:KDN:]KDW@^rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g4@t/g=G!Xs8LaPJbm7`Jc!=ars%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k(2ZGk18\ps8LRKKDN:]KDW@^rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8iMmXaeWmaU\(ec19u]`<]]^&S*:eYN6-k.LbF~>
-!<E0!johC3g4=g+s+13$s4%)JgAca#_>o/`_Z0W?g7eQ/k.1PC~>
-!<E0!johL1eVf?:s+13$s4%)Jec19u]`<]]^&S*:eYN6-k.LbF~>
-!<E0!jo_F0eS9['JaS*We*d4cs+Bh@#1]OLk2s>WJ,~>
-!<E0!jo_=2g4=hTJcC<$e,TF$s+0\>#25dNk2s5TJ,~>
-!<E0!jo_F0eVf"YJcC<$e,TEts+Bh@#1]OLk2s>WJ,~>
-!<E0!joD3.eUc8%e]lVEKCAgEeYN6-k.LbF~>
-!<E0!joD*+g4@t/g<J=OJa`UCg7eQ/k.1PC~>
-!<E0!joD3.eUc8%e]lVEKCAgEeYN6-k.LbF~>
-!<E0!joD3.eUc8%e[a36V#TT>]`<Q~>
-!<E0!joD*+g4@t/g:>o@U&X9;\c@6~>
-!<E0!joD3.eUc8%e[a36V#TT>]`<Q~>
-!<E0!joD3.eUc8%e[a36V#TT>]`<Q~>
-!<E0!joD*+g4@t/g:>o@U&X9;\c@6~>
-!<E0!joD3.eUc8%e[a36V#TT>]`<Q~>
-!<E0!joM:.JV/N+JV2=%ldZ07s5rIW!.Y~>
-!<E0!joM10JUrB'JUu1!le2N9s5rIT!.Y~>
-!<E0!joM:.JV/N+JV2=%ldZ07s5rIW!.Y~>
-!<E0!joM:.JV/N+JV2@&!<;B8"f21\k.LbF~>
-!<E0!joM10JUrB'JUu4"!<;B="ektYk.1PC~>
-!<E0!joM:.JV/N+JV2@&!<;B8"f21\k.LbF~>
-!<E0!jo_F0K7id/!WTias+13$s7H<m^&S-)^&S,ueHMcKk2s>WJ,~>
-!<E0!jo_=2JV!F0!WU#fs+13$s7H<m_Z0Z._Z0Z%g'+2Mk2s5TJ,~>
-!<E0!jo_F0K7id/!WTias+13$s7H<m^&S-)^&S,ueHMcKk2s>WJ,~>
-!<E0!jo_F0K7ij1s8N+P]n-37s+14CrrIbcrVuT)s8VE8"f21\k.LbF~>
-!<E0!jo_=2JV!L2s8N+N_L_`<s+14CrrI\frVuT.s8VE="ektYk.1PC~>
-!<E0!jo_F0K7ij1s8N+P]n-37s+14CrrIbcrVuT)s8VE8"f21\k.LbF~>
-!<?U-5m#ShKD3(Ys8R]Q^&S+`eUc8%ebI\pK)iU^s7j;-s6J2=6"3,G!!%N~>
-!<@-<9ENq!JbR%\s8RWO_Z0Xeg4@t/gA'D%JH3Ras7jJ2s6JAB9Q<a"!!%N~>
-!<BM*PQKBfKD3(Ys8R]Q^&S+`eUc8%ebI\pK)iU^s7j;-s6J2=PdH[>!!%N~>
-!!)tU"$tIiKDE4Zrrpr*K>%<bJ^o>%J^sPGs+:Hfs8UX"rVu`-s8VE8"[S&U@R1!E~>
-!!)t_"&.F"Jbd1]rrq,-J\qHeJ_G\/J_KnQs+(<is8Ug,rVu`2s8VE="\b2$ED-@_~>
-!!)u:"-h>gKDE4Zrrpr*K>%<bJ^o>%J^sPGs+:Hfs8UX"rVu`-s8VE8"dI!5[$1Q@~>
-!<A&W@KSpHK7j'7rVulIs+:Bds8RZ#J^o>%psoCs!knX6rRLlHr4W.1ldZ/)Mdg-]!.Y~>
-!<ADaE<AngJV!^8rVulNs+(6gs8RZ(J_G\/ptGb!!lG!;rS%5Mr5/L6le2M9Q#Ue;!.Y~>
-!<C+<ZicQCK7j'7rVulIs+:Bds8RZ#J^o>%psoCs!knX6rRLlHr4W.1ldZ0'`O*":!.Y~>
-!<A&W@KSpHK7j-9rVufGs+:Bds8RZ#J^o>%psoCs!knX6qpkZFrk8@3ldZ/)Mdg-]!.Y~>
-!<ADaE<AngJV!d:rVufLs+(6gs8RZ(J_G\/ptGb!!lG!;qqD#Krke^8le2M9Q#Ue;!.Y~>
-!<C+<ZicQCK7j-9rVufGs+:Bds8RZ#J^o>%psoCs!knX6qpkZFrk8@3ldZ0'`O*":!.Y~>
-!<A&W@Kf'JK7gkNrVu`Es+:Bds8RZ#J^o>%psoCs!knX6q:5HD!knX6ldZ/)Mdg-]!.Y~>
-!<ADaE<T%iJUt\TrVu`Js+(6gs8RZ(J_G\/ptGb!!lG!;q:bfI!lG!;le2M9Q#Ue;!.Y~>
-!<C+<Ziu]EK7gkNrVu`Es+:Bds8RZ#J^o>%psoCs!knX6q:5HD!knX6ldZ0'`O*":!.Y~>
-!<A&W@KAdFqh+[os+:Bds8RZ#J^o>%psoCs!knX6pso=qs8VE8"[S&U@R1!E~>
-!<ADaE</beqgnOrs+(6gs8RZ(J_G\/ptGb!!lG!;ptG[ts8VE="\b2$ED-@_~>
-!<C+<ZiQEAqh+[os+:Bds8RZ#J^o>%psoCs!knX6pso=qs8VE8"dI!5[$1Q@~>
-!<A&W@Kf'JK7gkNrIasss+:Bds8RZ#J^o>%psoCs!knX6q:5Fr!knX6ldZ/)Mdg-]!.Y~>
-!<ADaE<T%iJUt\TrIOh!s+(6gs8RZ(J_G\/ptGb!!lG!;q:bdu!lG!;le2M9Q#Ue;!.Y~>
-!<C+<Ziu]EK7gkNrIasss+:Bds8RZ#J^o>%psoCs!knX6q:5Fr!knX6ldZ0'`O*":!.Y~>
-!<A&W@KSpHK7j-9rIb$us+:Bds8RZ#J^o>%psoCs!knX6qpkXtrk8@3ldZ/)Mdg-]!.Y~>
-!<ADaE<AngJV!d:rIOn#s+(6gs8RZ(J_G\/ptGb!!lG!;qqD""rke^8le2M9Q#Ue;!.Y~>
-!<C+<ZicQCK7j-9rIb$us+:Bds8RZ#J^o>%psoCs!knX6qpkXtrk8@3ldZ0'`O*":!.Y~>
-!<A&W@KSpHK7j'7rIb+"s+:Bds8RZ#J^o>%psoCs!knX6rRLk!r4W.1ldZ/)Mdg-]!.Y~>
-!<ADaE<AngJV!^8rIOt%s+(6gs8RZ(J_G\/ptGb!!lG!;rS%4$r5/L6le2M9Q#Ue;!.Y~>
-!<C+<ZicQCK7j'7rIb+"s+:Bds8RZ#J^o>%psoCs!knX6rRLk!r4W.1ldZ0'`O*":!.Y~>
-!<A&W@KSpHK7j!5rIY:(K7gl;s+/^OeUc9Gec17)^&S,_ebt-s^&S,ueHJ6s@U_V'J,~>
-!<ADaE<AngJV!X6rIG.+JUt]<s+/mTg4@uQgAc^,_Z0YigAQU!_Z0Z%g'(08EH+YPJ,~>
-!<C+<ZicQCK7j!5rIY:(K7gl;s+/^OeUc9Gec17)^&S,_ebt-s^&S,ueHM2V['Z%tJ,~>
-!<A&W@KSpHK7ip3r.>'as8RZ#J^o>%psoCs!knX6rIamYs8VE8"[S&U@R1!E~>
-!<ADaE<AngJV!R4r.+pds8RZ(J_G\/ptGb!!lG!;rIOa\s8VE="\b2$ED-@_~>
-!<C+<ZicQCK7ip3r.>'as8RZ#J^o>%psoCs!knX6rIamYs8VE8"dI!5[$1Q@~>
-!<A&W@KSpHK7ij1rdt9cs8RY&JV/N+p4EL]s8R_(p:^M+ldZ/)Mdg-]!.Y~>
-!<ADaE<AngJV!L2rdb-fs8RY$JUrB'p43@`s8RY$p;6k0le2M9Q#Ue;!.Y~>
-!<C+<ZicQCK7ij1rdt9cs8RY&JV/N+p4EL]s8R_(p:^M+ldZ0'`O*":!.Y~>
-!<A&W@KSpHK7id/!e\2dJV/N+JV3WJ!knVdoY(;)ldZ/)Mdg-]!.Y~>
-!<ADaE<AngJV!F0!eJ5gJUrB'JV!KF!lFtgoYUY.le2M9Q#Ue;!.Y~>
-!<C+<ZicQCK7id/!e\2dJV/N+JV3WJ!knVdoY(;)ldZ0'`O*":!.Y~>
-!<A&W@KSpHK7eaTJcC<$df8X`"[S&U@R1!E~>
-!<ADaE<AngJUrCPJcC<$df8Xe"\b2$ED-@_~>
-!<C+<ZicQCK7eaTJcC<$df8X`"dI!5[$1Q@~>
-!<A&W@KJjGK7X&Rs+13ts6J2=6&T2]5lcE~>
-!<ADaE<8hfJV!iPs+13ts6JAB9U0U;9E9S~>
-!<C+<ZiZKBK7X&Rs+13ts6J2=Pf:#:PQ64~>
-!<A&W@K8]FeUc8%e[a366&T2]5lcE~>
-!<ADaE<&[`g4@t/g:>o@9U0U;9E9S~>
-!<C+<ZiH>AeUc8%e[a36Pf:#:PQ64~>
-!<A&V@dua8Uk,=mUtMOD@e)ebMuI/d5lcE~>
-!<AD`EUc_RTn/ngU"Q+>EUld'Q2Yb(9E9S~>
-!<C+;[.0B3Uk,=mUtMOD[.9F]`W!4FPQ64~>
-!\j\5rF5AV!+LNZJcC<$g&LT#raGpp!7cT~>
-!^m$RrGhFo!-*SiJcC<$g&LT-rc&!5!8;r~>
-!cn@\rNu18!47=WJcC<$g&LT]rj2`k!7cT~>
-!\j\5mpZ8_J`_OGJ`bYJ!/p;T!^Qh:J,~>
-!^m$Rmr8>$J`_OGJ`bYJ!1!"m!_`UJJ,~>
-!cn@\n$E(ZJ`_OGJ`bYJ!6+E6!gE]8J,~>
-"?A1:5sb$M!'u1uJ`_OGg#`9mnRDMa!W^d$J,~>
-s$Qng9MFtr!).t+J`_OGg#`:"nT"S&!W^s.J,~>
-s)S5APa(^F!0i&sJ`_OGg#`:Rn[/=\!W^d$J,~>
-">Mnk!!)LSJ\?WJJ\BaM!+PIarrE&KJ,~>
-r^?bdn4\DEJ\$EDft%0'nP&r_rn;l~>
-rcA)>n<AL;J\?WJft@BmnWa%RrmcN~>
-s#L*6!',T1JH16$[fH?VJ,~>
-r'Z)9JH16$[fH?[J,~>
-rc8*TF+F=B!.b-Z!;tAt~>
-%%EndData
-showpage
-%%Trailer
-end
-%%EOF
diff --git a/lib/et/doc/src/sim_trans_contents_viewer_mgr_actors.gif b/lib/et/doc/src/sim_trans_contents_viewer_mgr_actors.gif
deleted file mode 100644
index d0d6031b22..0000000000
--- a/lib/et/doc/src/sim_trans_contents_viewer_mgr_actors.gif
+++ /dev/null
Binary files differ
diff --git a/lib/et/doc/src/sim_trans_contents_viewer_mgr_actors.png b/lib/et/doc/src/sim_trans_contents_viewer_mgr_actors.png
new file mode 100644
index 0000000000..06ff60280f
--- /dev/null
+++ b/lib/et/doc/src/sim_trans_contents_viewer_mgr_actors.png
Binary files differ
diff --git a/lib/et/doc/src/sim_trans_contents_viewer_mgr_actors.ps b/lib/et/doc/src/sim_trans_contents_viewer_mgr_actors.ps
deleted file mode 100644
index 7ad54e9932..0000000000
--- a/lib/et/doc/src/sim_trans_contents_viewer_mgr_actors.ps
+++ /dev/null
@@ -1,1371 +0,0 @@
-%!PS-Adobe-3.0 EPSF-3.0
-%%Creator: GIMP PostScript file plugin V 1.12 by Peter Kirchgessner
-%%Title: /home/hakan/picts/sim_trans_contents_viewer_mgr_actors.ps
-%%CreationDate: Mon Oct 14 17:26:33 2002
-%%DocumentData: Clean7Bit
-%%LanguageLevel: 2
-%%Pages: 1
-%%BoundingBox: 14 14 406 232
-%%EndComments
-%%BeginProlog
-% Use own dictionary to avoid conflicts
-10 dict begin
-%%EndProlog
-%%Page: 1 1
-% Translate for offset
-14.173228 14.173228 translate
-% Translate to begin of first scanline
-0.000000 217.359744 translate
-391.247539 -217.359744 scale
-% Image geometry
-468 260 8
-% Transformation matrix
-[ 468 0 0 260 0 0 ]
-% Strings to hold RGB-samples per scanline
-/rstr 468 string def
-/gstr 468 string def
-/bstr 468 string def
-{currentfile /ASCII85Decode filter /RunLengthDecode filter rstr readstring pop}
-{currentfile /ASCII85Decode filter /RunLengthDecode filter gstr readstring pop}
-{currentfile /ASCII85Decode filter /RunLengthDecode filter bstr readstring pop}
-true 3
-%%BeginData: 78558 ASCII Bytes
-colorimage
-!AQV60nB=U!.b-Z!!G#:0ek\=~>
-r'Z)9JH16$[fH=oJ,~>
-"DW"!C3+q+JH16$[fH>IJ,~>
-r]0uYnc&U&JcC<$KDtqba8c/>!]_tqJ,~>
-r^?bdnc&U'JcC<$KDtqca8c/>r^;8~>
-rcA)>nc&U&JcC<$KDtqba8c/>!cr*tJ,~>
-s"OQTs8VWG!53s6J^oD'!56G0s6]pg3B;T~>
-s$Qngs8VWC!5=$8J_#J)!5?M-s6]pg6puP~>
-s)S5As8VWG!53s6J^oD'!56G0s6]pgF)uj~>
-!]^8\n(n&XJ^o>%K@Kt8`SL[8!',Q~>
-!^m%gn(IcUJ_#D'K@U%:`S(C1!(;>~>
-!cnAAn(n&XJ^o>%K@Kt8`SL[8!-<Y~>
-!\j]Tn(n&XJ^sYJ!6'N>MU_^?`SL[8!',Q~>
-!^m%gn(IcUJ_'_L!QriAer/)Z^;\e-_>luS~>
-!cnAAn(n&XJ^sYJ!6'N>MU_^?`SL[8!-<Y~>
-!<E/fh>k6dec1lieHNpfe\-<VrfmH5!J>`neH)JZJ^s>A!57RPpRLp5s.'&Es.'#D!NZ9O~>
-!<E/fg&Sjaf)LlgedTEhf"Q]`R?<W_eq&CHecDJYJ_'DC!5@XMpR1^.s-`i>s-`f=!NlEQ~>
-!<E/fh>k6dec1lieHNpfe\-<VrfmH5!J>`neH)JZJ^s>A!57RPpRLp5s.'&Es.'#D!NZ9O~>
-!<E/thZ',ChZ',Eh>k7]eH*Y&iRItJ^$sPQ`P(Qes-2Bj&]K+(eVedneWc<KeUr5!e]#58eH*Y&
-m*u0EHc:Qdo@3iSkMGs'p>5b<s5*^ErS@RV!.Y~>
-!<E/tf)M08f)M0:ec<GVdK.4niR.bD[d_]G_RAaXs,l0d&]0+-dZ&[pcB47;dXcttd_`H+dK.4n
-m*YsDID19\o?mWQkLTBqp=B21s47.:rRM"P!.Y~>
-!<E/thZ',ChZ',Eh>k7]eH*Y&iRItJ^$sPQ`P(Qes-2Bj&]K+(eVedneWc<KeUr5!e]#58eH*Y&
-m*u0EHc:Qdo@3iSkMGs'p>5b<s5*^ErS@RV!.Y~>
-!<E/uhYiuChYiuDh>k7]eH(;LiRIs]HgoPdK6tSf"cJVqeUr5GeHLSPe^];!^"!.9HgB2_P`(+C
-o@3iSkMGs'p>5P6rS@RV!.Y~>
-!<E/uf);$8f);$9ec<GVdf4mWdf4mfdf4m;dKPJmdaE\tqpPLqs3gpu^!cq3ld>g!M1O+HdK%#E
-f(YU+f(YU2ecDoRJ,~>
-!<E/uhYiuChYiuDh>k7]eH(;LiRIs]HgoPdK6tSf"cJVqeUr5GeHLSPe^];!^"!.9HgB2_P`(+C
-o@3iSkMGs'p>5P6rS@RV!.Y~>
-!<E/uhY`oDhY`oCh>k7deHX!NH\8]UV#G]@`VS*mXG_FPMp9eRMgLA`rmh%,"hfP8[+1uOHiM%o
-MgL)`e^]S9]n:[=eYN1ks2>,!H[CCYqUHs`HbIt[XFo&UHe$ZcMgL)`eZ=,:eXV!*eXWGc`J](q
-[+3]bMl_j8eHER4^"&YPHO.lKHe$Z!He"qkHiM%nMgL)`e^]S9XGbV]Hi)@nM[R4NHaL/4HaM>R
-`K^=Js4..-!N_4UeIKQ_H[C[ie^^aZH[C[qV#G]E`N4uEMlcp.s,.;eMq,e)H[CCYe\-=CJ^sDC
-!57RPpRLp5q4.B>!NZ9O~>
-!<E/uf)1s9f)1s8ec<G]dK[RNI>+uTU&KH?_YV[gY).RTM9=8LM1(5`rmLh+"hKD=ZI5HGIK..n
-OaVqhdaF,7\qP^@d\6Ygs2"o$JUN6\qU-aZICdkTV1m?KJ^Vu`OaVqhd].`4d[>O#d[?fW_NB8#
-ZI70\NMVX5dKI.0]$d#GI0duHJ^VttJ^U7kIK..mOaVqhdaF,7V2`oSJc!mqN=31KJZcG8J[3_P
-_NFeFs3gq,!MtePdLO9ZJUNNldaG:TI=6spU&KHD_QJ`DM6?j+s,@G`NRG\+JUN6\d^FS8J^X2=
-!5@XIpR1^*q3h03!NlEQ~>
-!<E/uhY`oDhY`oCh>k7deHX!NH\8]UV#G]@`VS*mXG_FPMp9eRMgLA`rmh%,"hfP8[+1uOHiM%o
-MgL)`e^]S9]n:[=eYN1ks2>,!H[CCYqUHs`HbIt[XFo&UHe$ZcMgL)`eZ=,:eXV!*eXWGc`J](q
-[+3]bMl_j8eHER4^"&YPHO.lKHe$Z!He"qkHiM%nMgL)`e^]S9XGbV]Hi)@nM[R4NHaL/4HaM>R
-`K^=Js4..-!N_4UeIKQ_H[C[ie^^aZH[C[qV#G]E`N4uEMlcp.s,.;eMq,e)H[CCYe\-=CJ^sDC
-!57RPpRLp5q4.B>!NZ9O~>
-!<E/teb>U4eH!;\bmMFBK>!Lr`Pm1N^&#u1UjJ$,[%t[BH^)4.H`YK:K6rNHH\9S^H[EHFK7gk%
-Hc=6^H]+D@K?_A^HbI[^HaLJn^&#u$[!S%^c%Dh:K6tk^K7gk%Hc<[FXNcBEXNcC)`IifVP^CBo
-K6rNPrQQOVHc=7KH[EHNK6tkfK6tk^H[EHFK7gk%Hc=6^H]+]EMhCoO(P@'mS9oU@S9on5c%CYf
-c%CAfc%CA$V#&=b]r\oSH]-.EH],8<UrC<"HbH5%PeE<.XNf"BH]+]EMgMhE[(X`'H^oZ3oZ[BL
-kLBR&q:,J8o[Wi/qpb_K!.Y~>
-!<E/tdeB1.dK%#Zc3h^FKt<Ot`l<RX_YVP7V1"3+[]7?II?hO3IB(T<JUNBKI>,tdJUPDTJVC\#
-IE'Q`I>OYGL!I\hIDX9dIC?ku^A?,&[XFRhcAACCJUu+hJVC\#IE&jHWm6<HWm61(b(58XQ$pZt
-JUNBOrQZU\IE'RPJUPD\JUu+lJUu+dJUPDTJVC\#IE'Q`I>OfGM2D,T(P.!oTm_?KTm_X?b(58`
-c@p\lc@LD#V>AId^952YI>Q7GI>P8<WlE&0IDW"4Q+iN3Wm8n@I>OfGM1)hH[_C&,IA)5;oZdHN
-kL'?uq9f82o[<W)qpGMJ!.Y~>
-!<E/teb>U4eH!;\bmMFBK>!Lr`Pm1N^&#u1UjJ$,[%t[BH^)4.H`YK:K6rNHH\9S^H[EHFK7gk%
-Hc=6^H]+D@K?_A^HbI[^HaLJn^&#u$[!S%^c%Dh:K6tk^K7gk%Hc<[FXNcBEXNcC)`IifVP^CBo
-K6rNPrQQOVHc=7KH[EHNK6tkfK6tk^H[EHFK7gk%Hc=6^H]+]EMhCoO(P@'mS9oU@S9on5c%CYf
-c%CAfc%CA$V#&=b]r\oSH]-.EH],8<UrC<"HbH5%PeE<.XNf"BH]+]EMgMhE[(X`'H^oZ3oZ[BL
-kLBR&q:,J8o[Wi/qpb_K!.Y~>
-!<E/sebPa5eH!;\bmCIuSB\-^XNcBEq98tnHc>s..t`2fc,G$^c-:lf`Q`aVc-:lfc)c8^c)c8n
-c%CA^c$Of^c%CAfc&6q=^%]bsK6tkVHc=6^Hd/X=SB\-^XNc*V`I!6%]mJ#*H^r?^H`YJEHi)%g
-P^EDS(k[1[c%CAfc%CAfc%CAfXF$J^XF%%nK7!=:'n^kPc$OfVc$Of^XF$J^c%CAfc%CB:bm25$
-K7hF$Hc>p-%>0#PK6tS^`I!6^c%CBBbl`lNSA"mG!IL&^c1K6\^$!oGSGC\8SFkA/SGUh;X8mb~>
-!<E/sdeT=/dK%#Zc3^Y%TusNdY0MTLq9B%qIDYs..uA\ocGk9hcH^uh`m0-dcH^ulcE;Shb-$/q
-c@LD`c@LPlc@LPlcA?t?_Y;@UJKr=OIDX9\J^1EHTusNdY0MH\`dNQ/_L9S0IA+fdIBLkHIEMK5
-!L8*4cMrIqcMrIqcMrIqcMrG'cE;Shb-$/qc@LDdpWaP*IEKidIEKidJ^1QLS^,N7IEp,hIEM<0
-#K"3+L!GC#_Yh^ZJJ-7bIE'RPI>Q7pJUP\dcA?t?_Yqa\I?fB/oZdHNkL'?uq9f82o[<W)qpGMJ
-!.Y~>
-!<E/sebPa5eH!;\bmCIuSB\-^XNcBEq98tnHc>s..t`2fc,G$^c-:lf`Q`aVc-:lfc)c8^c)c8n
-c%CA^c$Of^c%CAfc&6q=^%]bsK6tkVHc=6^Hd/X=SB\-^XNc*V`I!6%]mJ#*H^r?^H`YJEHi)%g
-P^EDS(k[1[c%CAfc%CAfc%CAfXF$J^XF%%nK7!=:'n^kPc$OfVc$Of^XF$J^c%CAfc%CB:bm25$
-K7hF$Hc>p-%>0#PK6tS^`I!6^c%CBBbl`lNSA"mG!IL&^c1K6\^$!oGSGC\8SFkA/SGUh;X8mb~>
-!<E/rebbm6eH!;\blFR;HNU(gK7!F=s*O[gs*Oais*Odj$\NfNc%CAfc%CAfV#5QQUs4O=c-:lf
-c-:lfc-=4lH[C[aq998:H`W`qc-:lfc(t8a$`)%*K<1<%K<1!UV#5QAUs4O=qoo/+HiD8#K6tkf
-K6tkfK6tkfK6tk=r-JOAc%CB:bnYkXc-:lfc-:lfc(o]^c-:lfc-:lfprs)XK7f)/K?\aiqoo7r
-Hd-narltIis31RsHiD7r`KY^rMnRB[H^'*+oZ[BLr7(e\q4%Gup=0/5q:,J8p!rl.r7(hL!.Y~>
-!<E/rdefI0dK%#Zc2a^=I06=kJV!XBs*agj!J,[ucMr=mcMrIqcMrIqcMrFrcDCGe';a!*J^2Pl
-J^2PlJ^2QXQ$n(?^A6%]SUIZ3NR#h#J^1+iI1)msOb'ZtR>%Z#cDCGe"/X:oJc!^nQ$rYWs+13q
-s+13qs+13qs+(3rV>P`DV9XXCp<N\hs3CXqs3CXq$dPSsU!Cr;IEp,hJb[Lr\qP]pI>,spIJ_=i
-JHF,JIK%OlIK.UmJc<q$_NfOtNP<]`I?fB/oZdHNr6bSVq3_5op<ir/q9f82p!WZ(r6bVK!.Y~>
-!<E/rebbm6eH!;\blFR;HNU(gK7!F=s*O[gs*Oais*Odj$\NfNc%CAfc%CAfV#5QQUs4O=c-:lf
-c-:lfc-=4lH[C[aq998:H`W`qc-:lfc(t8a$`)%*K<1<%K<1!UV#5QAUs4O=qoo/+HiD8#K6tkf
-K6tkfK6tkfK6tk=r-JOAc%CB:bnYkXc-:lfc-:lfc(o]^c-:lfc-:lfprs)XK7f)/K?\aiqoo7r
-Hd-narltIis31RsHiD7r`KY^rMnRB[H^'*+oZ[BLr7(e\q4%Gup=0/5q:,J8p!rl.r7(hL!.Y~>
-!<E/qebu$7eH!;\blXtnSG^V4K7!F=!eYj5rQQ+1Hc=7KH\9SfK6tkfK6tkfK6tkEH^t#Y$%mTL
-c%CAfc%CBAblbq\H\;.=%)%"GK<3>BK6tkEH^t#Y$`&--Uo\p$Us5ufSG^V4K7!L?(8Q;rc-:lf
-c-:lfc-:lfc-:lfc)c8^r657pHhP]!K6tkfK6tkfK6tkEH^r@*H[F#^K7!C<$&a/Tc%CYnK6t<0
-bmf;Pc%CA^c,G$^c-:lfr65JcUjIa=`I",+c1K6\^&6FTSG(J5SGC\8SG(M-SGgt=X8mb~>
-!<E/qdf#U1dK%#Zc2t.sU&<49JbdRmKmg]6c5)7b`m2SPM9aCtJ^2PlJ^2PlJ^1EHU&<49JcF$q
-JcF$qJc3jr`h@g7q9BD[I>rfXcH^ulcE;Shr6>\DI>t)'I>srGY'm#AcMrImc5*+%`m2k\J^2Pl
-J^2PlJ^2PlJ^1EHU&<49JbIChJcF$qJcF$qJIBc+I@8C'JUPhhJV!UA$&sMYc@pttKmg]5cMrG'
-cA?thcGk9hcH^ulr6>PeTm_X?`dOP3cLfB^^AQFRRJ,&/RJG82RJ,)'RJkP7XoNt~>
-!<E/qebu$7eH!;\blXtnSG^V4K7!F=!eYj5rQQ+1Hc=7KH\9SfK6tkfK6tkfK6tkEH^t#Y$%mTL
-c%CAfc%CBAblbq\H\;.=%)%"GK<3>BK6tkEH^t#Y$`&--Uo\p$Us5ufSG^V4K7!L?(8Q;rc-:lf
-c-:lfc-:lfc-:lfc)c8^r657pHhP]!K6tkfK6tkfK6tkEH^r@*H[F#^K7!C<$&a/Tc%CYnK6t<0
-bmf;Pc%CA^c,G$^c-:lfr65JcUjIa=`I",+c1K6\^&6FTSG(J5SGC\8SG(M-SGgt=X8mb~>
-!<E/pec208eH!;[bmB#LUpR51c%CAMqTUjuH\8E5XMq8fPeE<.XNf"BHd0ffHd0ffHaLbEH_e$M
-[*=5Mc-:lfc-:lf[*>DR]sN-Eprt%9H[E`Vc%CAfc%CA=[&gXZ[!R/5]mG+5c-:lfUpR51c%CB?
-boOKE[*?jJHd0ffHd0ffHd0ffHaLbEH_e$M[*=5MrlkJ%KDWn.K6tkfK6tkfK6tk^H[DQHH[F#^
-K7!C<*/f0FXF#<-XF#T$]r]2tK6su$H^)4.H`YK:K7!UB$)FrA[!R_U[!TK;c1K6\^&6FTSG(J5
-SGC\8SG(M3SH%.<SGgt=X8mb~>
-!<E/pcMs1*c2bTVapZ4CIAOBTZHA#P[`83e1obtXY-t@IWdU/DQ$oLOb(5,db(5,db)(PT_M*E7
-[]ZpYJUttdJUttdM1)hPTsDD<I>RaA,DCPo`lcGTJ]budIAOBTZHBV(IC?_8IC@;<Kmff+Y-Q3$
-Jc!S1\p^a(b(5,db(5,db(5,db)(PT_M*E7[]ZpYJV!gCs,$Wqs+13ms+13ms+(R#_L6j+M1'fp
-b(5-=arH7dWiCJq^8cU8Y-t@Ib)(PTV1"W?Q$oLOb(5-CapFcI^9W0Db-$0$J]dW-!5ABVpQbHt
-!1!B*!1!9'rK[E.rK[?,!NlEQ~>
-!<E/pec208eH!;[bmB#LUpR51c%CAMqTUjuH\8E5XMq8fPeE<.XNf"BHd0ffHd0ffHaLbEH_e$M
-[*=5Mc-:lfc-:lf[*>DR]sN-Eprt%9H[E`Vc%CAfc%CA=[&gXZ[!R/5]mG+5c-:lfUpR51c%CB?
-boOKE[*?jJHd0ffHd0ffHd0ffHaLbEH_e$M[*=5MrlkJ%KDWn.K6tkfK6tkfK6tk^H[DQHH[F#^
-K7!C<*/f0FXF#<-XF#T$]r]2tK6su$H^)4.H`YK:K7!UB$)FrA[!R_U[!TK;c1K6\^&6FTSG(J5
-SGC\8SG(M3SH%.<SGgt=X8mb~>
-!<E/feH!;[bmMFSH[CCHc*W+M^&#t]XG_FPMoErBK6r6Prll^@Hd0ffHd0gBK6t;NP^@b0XNcBE
-c-:lfc-<VJHbGYrH[D!rprrl9H^+NS&VGGTc,GooH\8EEc$Of^c$Og:bm;:QH[CCHc%CB>c2W_%
-bnu([c-:lfc-:lfc-<VJHbIC_H[CCHc%CBBblNHDqook.Hd0ffHd0ffHd0g:K7gO`Hd0ffHhbi%
-["E^qUjJWVXG_FPMoErJK6t;5K6r6PrlkIrHiD7qP_4=0Pf:n*Mh0.EblGHTeH!;YS,g7reb>U,
-ec20<ec20;eH)`OJ,~>
-!<E/fc2bTUapQ"NJUN6Tb-HSL])'PWWel.PM8%-/KmeZTrlY7ls2t@ms2l=eJUtDLQ%=@;Y0)<H
-b0#9db0%#@J\%+tI=[ZtprWZ3I?FNOs+13m)8_YiI>+iH`dN9Xb'e]Xb0%SdJUN6Tb(5-?b5[J$
-b5[%mb5[%mb5[%mapbS,J\&^`JUN6Tb(5-Cb5[%ib5[%mb5[%mb5[%mapG5%KsHD`b0#9dprXD]
-KmfMcI@86XM1'f/^<3a4J\%\3I>+^#b5[%lap=8`I=[Ztb)MC3b4EaU^AQ7V[eZ0g[eA#@Q1`H&
-Q2T#.Q2Jo.XoNt~>
-!<E/feH!;[bmMFSH[CCHc*W+M^&#t]XG_FPMoErBK6r6Prll^@Hd0ffHd0gBK6t;NP^@b0XNcBE
-c-:lfc-<VJHbGYrH[D!rprrl9H^+NS&VGGTc,GooH\8EEc$Of^c$Og:bm;:QH[CCHc%CB>c2W_%
-bnu([c-:lfc-:lfc-<VJHbIC_H[CCHc%CBBblNHDqook.Hd0ffHd0ffHd0g:K7gO`Hd0ffHhbi%
-["E^qUjJWVXG_FPMoErJK6t;5K6r6PrlkIrHiD7qP_4=0Pf:n*Mh0.EblGHTeH!;YS,g7reb>U,
-ec20<ec20;eH)`OJ,~>
-!<E/feH!;Qc2)be^!4guHN:b0blYk:XN\oiH\;4?qKi4Ugs#o%K>iDdo?@9K`74mi!.Y~>
-!<E/fc2bTKb5-Md]$8CoI/pk/ao]G2V9R-a`dNR<b5-Md]%kF0We&$<b4EaU^;S:tXoNt~>
-!<E/feH!;Qc2)be^!4guHN:b0blYk:XN\oiH\;4?qKi4Ugs#o%K>iDdo?@9K`74mi!.Y~>
-!<E/fblGG.`<+#lUs[-c[$7AfMgLu>`;udJJ]73!!56=q!NZ9O~>
-!<E/faoK/,`WF/oU!^ja[ZRSiNI@MG`W;dIJ]@9#!5?Co!NlEQ~>
-!<E/fblGG.`<+#lUs[-c[$7AfMgLu>`;udJJ]73!!56=q!NZ9O~>
-!<E/fblGG.`QlF+]p+.rK;=(;]Ysla`6A=a!.Y~>
-!<E/faoK/,`m2R-^6*tpKqX(;]Z'rc`6&+`!.Y~>
-!<E/fblGG.`QlF+]p+.rK;=(;]Ysla`6A=a!.Y~>
-!<E/fblGG.`IZ!\`;mTiblOmGJ,~>
-!<E/faoK/,`du-^`W3`kaoSXFJ,~>
-!<E/fblGG.`IZ!\`;mTiblOmGJ,~>
-!!%S&JV/N+YCcfTJ,~>
-!!%S$JUrB'YCQZRJ,~>
-!!%S&JV/N+YCcfTJ,~>
-!<E0!joD3.s+13$s1/.5V#TT>]`<Q~>
-!<E0!joD*+s+13$s1/.5U&X9;\c@6~>
-!<E0!joD3.s+13$s1/.5V#TT>]`<Q~>
-!<E0!joD3.s+13$s1847K;AP0k.LbF~>
-!<E0!joD*+s+13$s1847JYE,+k.1PC~>
-!<E0!joD3.s+13$s1847K;AP0k.LbF~>
-!<E0!joV@Ys+/^OeUc8aec17*V#TT>]`<Q~>
-!<E0!joV7Vs+/mTg4@tkgAc^-U&X9;\c@6~>
-!<E0!joV@Ys+/^OeUc8aec17*V#TT>]`<Q~>
-!<E0!joV@Ys+/^OeUc8aec17*V#TT>]`<Q~>
-!<E0!joV7Vs+/mTg4@tkgAc^-U&X9;\c@6~>
-!<E0!joV@Ys+/^OeUc8aec17*V#TT>]`<Q~>
-!<E0!joV@Ys+/^OeUc8aec17*V#TT>]`<Q~>
-!<E0!joV7Vs+/mTg4@tkgAc^-U&X9;\c@6~>
-!<E0!joV@Ys+/^OeUc8aec17*V#TT>]`<Q~>
-!<E0!joV@Ys+/^OeUc8aec17*V#TT>]`<Q~>
-!<E0!joV7Vs+/mTg4@tkgAc^-U&X9;\c@6~>
-!<E0!joV@Ys+/^OeUc8aec17*V#TT>]`<Q~>
-!<E0!joV@Ys+/^OeUc8aec17*V#TT>]`<Q~>
-!<E0!joV7Vs+/mTg4@tkgAc^-U&X9;\c@6~>
-!<E0!joV@Ys+/^OeUc8aec17*V#TT>]`<Q~>
-!<E0!joV@Ys+/^OeUc8aec17*V#TT>]`<Q~>
-!<E0!joV7Vs+/mTg4@tkgAc^-U&X9;\c@6~>
-!<E0!joV@Ys+/^OeUc8aec17*V#TT>]`<Q~>
-!<E0!joV@Ys+/^OeUc8aec17*V#TT>]`<Q~>
-!<E0!joV7Vs+/mTg4@tkgAc^-U&X9;\c@6~>
-!<E0!joV@Ys+/^OeUc8aec17*V#TT>]`<Q~>
-!<E0!joV@Ys8(:A!!:[N!:889!<1OK!!:[N!;tCI!:/25!9Mc2!:SJ6!!^sR!7fU"!.i[Oe^)eG
-K*A(Nk2s>WJ,~>
-!<E0!joV7Vs8(IF!!:jS!:8G>!<1^P!!:jS!;tRN!:/A:!9Mr7!:SY;!!_-W!8?-,!.ijTg<\LQ
-JH_bIk2s5TJ,~>
-!<E0!joV@Ys8(:A!!:[N!:889!<1OK!!:[N!;tCI!:/25!9Mc2!:SJ6!!^sR!7fU"!.i[Oe^)eG
-K*A(Nk2s>WJ,~>
-!<E0!joV@Ys8(:G!;b7G!:889!<1OK!;Y1F!:889!<1OK!9Vi3!:SJ<!;b7G!<:UL!.i[Oe^)eG
-K*A(Nk2s>WJ,~>
-!<E0!joV7Vs8(IL!;bFL!:8G>!<1^P!;Y@K!:8G>!<1^P!9W#8!:SYA!;bFL!<:dQ!.ijTg<\LQ
-JH_bIk2s5TJ,~>
-!<E0!joV@Ys8(:G!;b7G!:889!<1OK!;Y1F!:889!<1OK!9Vi3!:SJ<!;b7G!<:UL!.i[Oe^)eG
-K*A(Nk2s>WJ,~>
-!<E0!joV@Ys8(:G!<(IJ!!LgP!7fWu!:n\?!<1OK!"7<W!7fU"!7_&Le^aTuo%!a?rmh#Ks4.&J
-rmgrIs4.,L"4[AOeboLJec,UNeGoU?ec,XJec,UOeGoU"r;clJr;clJrr</O!!(RJ!.i[Oe`,-Z
-K*A(Nk2s>WJ,~>
-!<E0!joV7Vs8(IL!<(XO!!M!U!8?0*!:nkD!<1^P!"7K\!8?-,!87DQg=lK*o%O*Drn@APs4[DO
-rn@;Ns4[JQ"53_TgAM$OgA_-Sg&M-DgA_0OgA_-Tg&M-,r;clOr;clOrr</T!!(aO!.ijTg>^id
-JH_bIk2s5TJ,~>
-!<E0!joV@Ys8(:G!<(IJ!!LgP!7fWu!:n\?!<1OK!"7<W!7fU"!7_&Le^aTuo%!a?rmh#Ks4.&J
-rmgrIs4.,L"4[AOeboLJec,UNeGoU?ec,XJec,UOeGoU"r;clJr;clJrr</O!!(RJ!.i[Oe`,-Z
-K*A(Nk2s>WJ,~>
-!<E0!joV@Ys8(:G!<(IJ!"%0U!7_&Le^XX"o@<j@rmh#K#1W\ReGoU"rW!/Q!!(R"!!)T?rW)oI
-rrE)Lrr<;S!!(R"!!(RG!<:UL!!(RK!!:[N!;"b@!<(IJ!"[T[!7fU"!7fU"!7fU"!7goGs4.,L
-J^o>%j440^"f21\k.LbF~>
-!<E0!joV7Vs8(IL!<(XO!"%?Z!87DQg=cN,o@j3Ern@AP#20%Wg&M-,rW!/V!!(a,!!)TDrW)oN
-rrE)Qrr<;X!!(a,!!(aL!<:dQ!!(aP!!:jS!;"qE!<(XO!"[c`!8?-,!8?-,!8?-,!8@8Ls4[JQ
-J_G\/j4aNa"ektYk.1PC~>
-!<E0!joV@Ys8(:G!<(IJ!"%0U!7_&Le^XX"o@<j@rmh#K#1W\ReGoU"rW!/Q!!(R"!!)T?rW)oI
-rrE)Lrr<;S!!(R"!!(RG!<:UL!!(RK!!:[N!;"b@!<(IJ!"[T[!7fU"!7fU"!7fU"!7goGs4.,L
-J^o>%j440^"f21\k.LbF~>
-!<E0!joV@Ys8(:D!"@BX!7_&LeGoU"eGoU@ebT7WeGoU"!!(R"!!(OL!7fU"!:\P<!<:UL!<:UL
-!;tCI!!(RK!<:UL!;tCI!<:UL!;"b=!#!f^!7_&Le^XX"e^XX"e^XX"ec#RKec#Q"eUc9/ec17*
-V#TT>]`<Q~>
-!<E0!joV7Vs8(II!"@Q]!87DQg&M-,g&M-EgA1d\g&M-,!!(a,!!(^Q!8?-,!:\_A!<:dQ!<:dQ
-!;tRN!!(aP!<:dQ!;tRN!<:dQ!;"qB!#!uc!87DQg=cN,g=cN,g=cN,gAV*PgAV)'g4@u9gAc^-
-U&X9;\c@6~>
-!<E0!joV@Ys8(:D!"@BX!7_&LeGoU"eGoU@ebT7WeGoU"!!(R"!!(OL!7fU"!:\P<!<:UL!<:UL
-!;tCI!!(RK!<:UL!;tCI!<:UL!;"b=!#!f^!7_&Le^XX"e^XX"e^XX"ec#RKec#Q"eUc9/ec17*
-V#TT>]`<Q~>
-!<E0!joV@Ys8(:G!<(IJ!!CaO!7grHo@<j@rmh#K$Io+VeGoU"eGoU"qZ-*8rVurKqZ-ZHqu?fK
-!!*#KrrDuIrrE)LrrDZ@rrE#Jrr<>T!!(R"!!(R"qZ$]J!!)rIrW%N"J^rc1s+:KNs5rIW!.Y~>
-!<E0!joV7Vs8(IL!<(XO!!CpT!8@;Mo@j3Ern@AP$JGI[g&M-,g&M-,qZ-*=rVurPqZ-ZMqu?fP
-!!*#PrrDuNrrE)QrrDZErrE#Orr<>Y!!(a,!!(a,qZ$]O!!)rNrW%N'J_K,;s+(?Is5rIT!.Y~>
-!<E0!joV@Ys8(:G!<(IJ!!CaO!7grHo@<j@rmh#K$Io+VeGoU"eGoU"qZ-*8rVurKqZ-ZHqu?fK
-!!*#KrrDuIrrE)LrrDZ@rrE#Jrr<>T!!(R"!!(R"qZ$]J!!)rIrW%N"J^rc1s+:KNs5rIW!.Y~>
-!<E0!joV@Ys8(:G!<(IJ!!UmQ!7_&Ln(%F<rmh#K%+P=XeGoU"eGoU"!!)K<rrE&Krr<,N!!)rI
-rrE)Lrr<,N!!*#KrrDuIrrE)LrrDZ@rrE#Jrr<DV!!(R"!!(R"!!)rIrrDrHrW%N"J^rf2s+:KN
-s5rIW!.Y~>
-!<E0!joV7Vs8(IL!<(XO!!V'V!87DQn(RdArn@AP%,([]g&M-,g&M-,!!)KArrE&Prr<,S!!)rN
-rrE)Qrr<,S!!*#PrrDuNrrE)QrrDZErrE#Orr<D[!!(a,!!(a,!!)rNrrDrMrW%N'J_K/<s+(?I
-s5rIT!.Y~>
-!<E0!joV@Ys8(:G!<(IJ!!UmQ!7_&Ln(%F<rmh#K%+P=XeGoU"eGoU"!!)K<rrE&Krr<,N!!)rI
-rrE)Lrr<,N!!*#KrrDuIrrE)LrrDZ@rrE#Jrr<DV!!(R"!!(R"!!)rIrrDrHrW%N"J^rf2s+:KN
-s5rIW!.Y~>
-!<E0!joV@Ys8(:G!<(IJ!"%0U!7_&Le^XX"o@<j@rmh#K#1W\ReGoU"rW!/Q!!(R"!!)W@rrE&K
-rr<V\!!(R"!!(OL!7fU"!7_&Lrmh#Ks4.,L#1W\Re^XX"o@<j@rRLoJ#LreSe^XX"ec#RKec,UN
-eGoUKec,XLec,W#eUc92ec17*V#TT>]`<Q~>
-!<E0!joV7Vs8(IL!<(XO!"%?Z!87DQg=cN,o@j3Ern@AP#20%Wg&M-,rW!/V!!(a,!!)WErrE&P
-rr<Va!!(a,!!(^Q!8?-,!87DQrn@APs4[JQ#20%Wg=cN,o@j3ErS%8O#MK.Xg=cN,gAV*PgA_-S
-g&M-PgA_0QgA_/(g4@u<gAc^-U&X9;\c@6~>
-!<E0!joV@Ys8(:G!<(IJ!"%0U!7_&Le^XX"o@<j@rmh#K#1W\ReGoU"rW!/Q!!(R"!!)W@rrE&K
-rr<V\!!(R"!!(OL!7fU"!7_&Lrmh#Ks4.,L#1W\Re^XX"o@<j@rRLoJ#LreSe^XX"ec#RKec,UN
-eGoUKec,XLec,W#eUc92ec17*V#TT>]`<Q~>
-!<E0!joV@Ys8(:G!<(IJ!!LgP!7fWu!:n\?!<1OK!"7<W!7fU"!7_&Le^aTun^[O;rmgrIrmguJ
-!7h#JrRLiHs4.,Ls4.,Lo@<j@rRLoJ!n@8Nrmh#Ks4.&Js4.,LrRLiHJ^o>%imn']"f21\k.LbF~>
-!<E0!joV7Vs8(IL!<(XO!!M!U!8?0*!:nkD!<1^P!"7K\!8?-,!87DQg=lK*n_3m@rn@;Nrn@>O
-!8@AOrS%2Ms4[JQs4[JQo@j3ErS%8O!nmVSrn@APs4[DOs4[JQrS%2MJ_G\/inFE`"ektYk.1PC~>
-!<E0!joV@Ys8(:G!<(IJ!!LgP!7fWu!:n\?!<1OK!"7<W!7fU"!7_&Le^aTun^[O;rmgrIrmguJ
-!7h#JrRLiHs4.,Ls4.,Lo@<j@rRLoJ!n@8Nrmh#Ks4.&Js4.,LrRLiHJ^o>%imn']"f21\k.LbF~>
-!<E0!joV@Ys+/^OeUc8aec17*V#TT>]`<Q~>
-!<E0!joV7Vs+/mTg4@tkgAc^-U&X9;\c@6~>
-!<E0!joV@Ys+/^OeUc8aec17*V#TT>]`<Q~>
-!<E0!joV@Ys+/^OeUc8aec17*V#TT>]`<Q~>
-!<E0!joV7Vs+/mTg4@tkgAc^-U&X9;\c@6~>
-!<E0!joV@Ys+/^OeUc8aec17*V#TT>]`<Q~>
-!<E0!joV@Ys+/^OeUc8aec17*V#TT>]`<Q~>
-!<E0!joV7Vs+/mTg4@tkgAc^-U&X9;\c@6~>
-!<E0!joV@Ys+/^OeUc8aec17*V#TT>]`<Q~>
-!<E0!joV@Ys+/^OeUc8aec17*V#TT>]`<Q~>
-!<E0!joV7Vs+/mTg4@tkgAc^-U&X9;\c@6~>
-!<E0!joV@Ys+/^OeUc8aec17*V#TT>]`<Q~>
-!<E0!joV@Ys+/^OeUc8aec17*V#TT>]`<Q~>
-!<E0!joV7Vs+/mTg4@tkgAc^-U&X9;\c@6~>
-!<E0!joV@Ys+/^OeUc8aec17*V#TT>]`<Q~>
-!<E0!joV@Ys+/^OeUc8aec17*V#TT>]`<Q~>
-!<E0!joV7Vs+/mTg4@tkgAc^-U&X9;\c@6~>
-!<E0!joV@Ys+/^OeUc8aec17*V#TT>]`<Q~>
-!<E0!joV@Ys+/^OeUc8aec17*V#TT>]`<Q~>
-!<E0!joV7Vs+/mTg4@tkgAc^-U&X9;\c@6~>
-!<E0!joV@Ys+/^OeUc8aec17*V#TT>]`<Q~>
-!<E0!joD3.eUc8%e[a36V#TT>]`<Q~>
-!<E0!joD*+g4@t/g:>o@U&X9;\c@6~>
-!<E0!joD3.eUc8%e[a36V#TT>]`<Q~>
-!<E0!joD3.eUc8%e]lY4K*Kl%s5rIW!.Y~>
-!<E0!joD*+g4@t/g<J@>JHji%s5rIT!.Y~>
-!<E0!joD3.eUc8%e]lY4K*Kl%s5rIW!.Y~>
-!<E0!joV@/eU_IdC4U-JCAucPK*VG,V#TT>]`<Q~>
-!<E0!joV71g4=g+JUrC#Jc=BlJHu5/U&X9;\c@6~>
-!<E0!joV@/eU`X0Mh-f7MuM8qK*VG,V#TT>]`<Q~>
-!<E0!joV@/eU_IdC4U-KC&m]$ec19u]`<]]^&S*:eYN6-k.LbF~>
-!<E0!joV71g4=g+JUrC$JH5`LgAca#_>o/`_Z0W?g7eQ/k.1PC~>
-!<E0!joV@/eU`X0Mh-f8MZEeVec19u]`<]]^&S*:eYN6-k.LbF~>
-!<E0!johL1eS8iMXF[I(XOaKQmf(c:KDW=_s+C0]s8N;RV#TT>]`<Q~>
-!<E0!johC3g4=g+g4@t/g=G!Xs8LaPJc!:bs+1$`s8N;WU&X9;\c@6~>
-!<E0!johL1eVf?:k(2ZGk18\ps8LRKKDW=_s+C0]s8N;RV#TT>]`<Q~>
-!<E0!johL1eS8iMXF[I(XOaKQmf(c:KDW=`s+>t$^&S*:eYN6-k.LbF~>
-!<E0!johC3g4=g+g4@t/g=G!Xs8LaPJc!:cs+,au_Z0W?g7eQ/k.1PC~>
-!<E0!johL1eVf?:k(2ZGk18\ps8LRKKDW=`s+>t$^&S*:eYN6-k.LbF~>
-!<E0!johL1eS8iMXF[I(XOaKQmf(c:KD`F_s8R`K^&S*:eYN6-k.LbF~>
-!<E0!johC3g4=g+g4@t/g=G!Xs8LaPJc*Cbs8RZI_Z0W?g7eQ/k.1PC~>
-!<E0!johL1eVf?:k(2ZGk18\ps8LRKKD`F_s8R`K^&S*:eYN6-k.LbF~>
-!<E0!johL1eS8iMXT#=$!;rqs!.h5&XQ6J_mf(c:KD`F_rrU`'KD`F_rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+gA]h+!;tRL!.ijTg>pufs8LaPJc*CbrrUo*Jc*Cbrs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k5ONC!;u!X!.j9`k2b\)s8LRKKD`F_rrU`'KD`F_rs%#Ls5rIW!.Y~>
-!<E0!joqR2eS8j#qZ-Srq>gPsq>gMrrW)hsquHbuquHAjquHYrq>^MsrW)r!rVur"q>^MsquGr^
-!W];%rN#u!rN#u!JZOF(jfJLMrmh%$rOr72s4..%r4W.1#1]OLk2s>WJ,~>
-!<E0!joqI4g4=h/qZ-TKq>gQLq>gNKrW)iLquHcNquHBCquHZKq>^NLrW)rOrVurPq>^NLquGs7
-!W^pSrRq5OrRq5OJ_G\/jkBb7rn@C'rPJU7s4[L(r5/L6#25dNk2s5TJ,~>
-!<E0!joqR2eVf@JqZ-TWq>gQXq>gNWrW)iXquHcZquHBOquHZWq>^NXrW)r[rVur\q>^NXquGsC
-!W_?_rT4([rT4([J`_OGjlZUCrmh%$rOr72s4..%r4W.1#1]OLk2s>WJ,~>
-!<E0!jp.^4eS8j#X8r4#!!)u!!!)u!#lq'.!3E7%XK2F"X8i7rX8i7tX8i7iX8i7rX8i8!X9/I(
-X8r1"!!*#"!!)u!!!*#"!!)/_!W];%rN#u!rN#u!JZOF(jfJLMrmh%$rOr72rmh%$rOr72#1]OL
-k2s>WJ,~>
-!<E0!jp.U6g4=h/g&V**!!)uO!!)uO#lr]5!8?-,g=cQ)g&M-Kg&M-Mg&M-Bg&M-Kg&M-Og&h?/
-g&V')!!*#P!!)uO!!*#P!!)08!W^pSrRq5OrRq5OJ_G\/jkBb7rn@C'rPJU7rn@C'rPJU7#25dN
-k2s5TJ,~>
-!<E0!jp.^4eVf@JjoGAB!!)u[!!)u[#ls,M!9WDDk2l[Ajo>DWjo>DYjo>DNjo>DWjo>D[joYVG
-joG>A!!*#\!!)u[!!*#\!!)0D!W_?_rT4([rT4([J`_OGjlZUCrmh%$rOr72rmh%$rOr72#1]OL
-k2s>WJ,~>
-!<E0!jp.^4eS8j#X8r1"!!*#"!!)u!#lq'.!3E7%XK2F#X9&C'!;`bs!;iht!:[&i!;W\r!<&u$
-!3E7%r2]kuri?)"rN#u!ri?)"poOJqnuMonXK2F#X8i8!X8i6OXF[J7XT._fec1:$^&S-2ec1:#
-^&S*:eYN6-k.LbF~>
-!<E0!jp.U6g4=h/g&V')!!*#P!!)uO#lr]5!8?-,g=cQ*g&_9.!;bCL!;kIM!:\\B!;Y=K!<(UR
-!8?-,r7V,Nrn7>PrRq5Orn7>PptG`Jo%F0Gg=cQ*g&M-Og&M,(g4@u>gAh3PgAca'_Z0Z7gAca&
-_Z0W?g7eQ/k.1PC~>
-!<E0!jp.^4eVf@JjoG>A!!*#\!!)u[#ls,M!9WDDk2l[BjoPPF!;bgX!;kmY!:]+N!;YaW!<)$^
-!9WDDr8mtZroO1\rT4([roO1\pu_SVo&^#Sk2l[Bjo>D[jo>C4k(2[Vk5YJ\ec1:$^&S-2ec1:#
-^&S*:eYN6-k.LbF~>
-!<E0!jp.^4eS8j#X8r1"!!*#"!s#F(!;`bs!;`bu!3?1sX8i7tX8i7iX8i7rX9/I(X8r1"!!*#"
-!!)u!!s#F(!;rnu!;NYq!:m2n!3E7%rN#u!rN#u!JZOF(jfJLMrmh%$rk8@3r71h"rk8@3#1]OL
-k2s>WJ,~>
-!<E0!jp.U6g4=h/g&V')!!*#P!s%'/!;bCL!;bCN!87GLg&M-Mg&M-Bg&M-Kg&h?/g&V')!!*#P
-!!)uO!s%'/!;tON!;P:J!:nhG!8?-,rRq5OrRq5OJ_G\/jkBb7rn@C'rke^8r7_1%rke^8#25dN
-k2s5TJ,~>
-!<E0!jp.^4eVf@JjoG>A!!*#\!s%KG!;bgX!;bgZ!9O:Xjo>DYjo>DNjo>DWjoYVGjoG>A!!*#\
-!!)u[!s%KG!;tsZ!;P^V!:o7S!9WDDrT4([rT4([J`_OGjlZUCrmh%$rk8@3r71h"rk8@3#1]OL
-k2s>WJ,~>
-!<E0!jp.^4eS8j#X8r1"!!*#"r;c\q!!)nt!!*#"!!)nt!!)nt!!)Mi!!)hrr;cbs!!*#"!!)u!
-r;cbs!!)5a!!*#"!!)u!!!)u!!!%SOJZRt7s6fm:s+C?bs8VuHs+C<as8N;RV#TT>]`<Q~>
-!<E0!jp.U6g4=h/g&V')!!*#Pr;c]J!!)oM!!*#P!!)oM!!)oM!!)NB!!)iKr;ccL!!*#P!!)uO
-r;ccL!!)6:!!*#P!!)uO!!)uO!!%T(J_K5>s8W)Ps+13es8VuMs+10ds8N;WU&X9;\c@6~>
-!<E0!jp.^4eVf@JjoG>A!!*#\r;c]V!!)oY!!*#\!!)oY!!)oY!!)NN!!)iWr;ccX!!*#\!!)u[
-r;ccX!!)6F!!*#\!!)u[!!)u[!!%T4J`c(Vs8W)Ks+C?bs8VuHs+C<as8N;RV#TT>]`<Q~>
-!<E0!jp.^4eS8j#X8r1"!!*#"!s#F(!;`bs!;ikq!;iht!;iht!<&u!!;3Dn!<&u!!<0&%!3E7%
-qlBi!X8r1"!s#F(!;rnu!<&u!!:?if!<0&"!<&u!!<&u!!.h5&XQ?P`mf(c:KE&Xbs8(:GKE&Xb
-rs%#Ls5rIW!.Y~>
-!<E0!jp.U6g4=h/g&V')!!*#P!s%'/!;bCL!;kLJ!;kIM!;kIM!<(UO!;5%G!<(UO!<1[S!8?-,
-qq;)Og&V')!s%'/!;tON!<(UO!:AJ?!<1[P!<(UO!<(UO!.ijTg?%&gs8LaPJcEUes8(ILJcEUe
-rs%2Ns5rIT!.Y~>
-!<E0!jp.^4eVf@JjoG>A!!*#\!s%KG!;bgX!;kpV!;kmY!;kmY!<)$[!;5IS!<)$[!<2*_!9WDD
-qrRq[joG>A!s%KG!;tsZ!<)$[!:AnK!<2*\!<)$[!<)$[!.j9`k2kb*s8LRKKE&Xbs8(:GKE&Xb
-rs%#Ls5rIW!.Y~>
-!<E0!jp.^4eS8j#X8r1"!!*#"!!)u!!!)qu!!)qu!!)qu!!)qu!!)nt!!)u!!!)\n!!)u!!!*#"
-!!)u!!!)u!!W];%r2]kurN#u!ri?)"rN#u!mB$0bri?)"rN#u!JZOF(jfJLMrmh%$!knX6q:5Lt
-s1SI4#1]OLk2s>WJ,~>
-!<E0!jp.U6g4=h/g&V')!!*#P!!)uO!!)rN!!)rN!!)rN!!)rN!!)oM!!)uO!!)]G!!)uO!!*#P
-!!)uO!!)uO!W^pSr7V,NrRq5Orn7>PrRq5OmFqF;rn7>PrRq5OJ_G\/jkBb7rn@C'!lG!;q:bk"
-s2+g9#25dNk2s5TJ,~>
-!<E0!jp.^4eVf@JjoG>A!!*#\!!)u[!!)rZ!!)rZ!!)rZ!!)rZ!!)oY!!)u[!!)]S!!)u[!!*#\
-!!)u[!!)u[!W_?_r8mtZrT4([roO1\rT4([mH49GroO1\rT4([J`_OGjlZUCrmh%$!knX6q:5Lt
-s1SI4#1]OLk2s>WJ,~>
-!<E0!jp.^4eS8j#X8r4#!!)u!!!)u!!!)qu!!)qu!!)qu!!)qu!!)nt!!)u!!!)\n!!)u!!!*#"
-!!)u!!!)qu!!)nt!!)u!!!*#"!!)u!!!)u!rrDMh!!)u!!!)u!!!%SOJZRt7s6fm:s+:Bds8VlE
-s+:Wks8UWFs5rIW!.Y~>
-!<E0!jp.U6g4=h/g&V**!!)uO!!)uO!!)rN!!)rN!!)rN!!)rN!!)oM!!)uO!!)]G!!)uO!!*#P
-!!)uO!!)rN!!)oM!!)uO!!*#P!!)uO!!)uOrrDNA!!)uO!!)uO!!%T(J_K5>s8W)Ps+(6gs8VlJ
-s+(Kns8UfHs5rIT!.Y~>
-!<E0!jp.^4eVf@JjoGAB!!)u[!!)u[!!)rZ!!)rZ!!)rZ!!)rZ!!)oY!!)u[!!)]S!!)u[!!*#\
-!!)u[!!)rZ!!)oY!!)u[!!*#\!!)u[!!)u[rrDNM!!)u[!!)u[!!%T4J`c(Vs8W)Ks+:Bds8VlE
-s+:Wks8UWFs5rIW!.Y~>
-!<E0!joqR2eS8j#qZ-Srq>gMrquHbur;Zi!r;cl!quHbuq#L/jq#LGrq>gGp!!)quq>^Msq#LAp
-rrDPirW)nur;_DMJZRq6s6fm:s+C@Oon*Ras8UWFs5rIW!.Y~>
-!<E0!joqI4g4=h/qZ-TKq>gNKquHcNr;ZiOr;clOquHcNq#L0Cq#LHKq>gHI!!)rNq>^NLq#LBI
-rrDQBrW)oNr;_E&J_K2=s8W)Ps+14MommFds8UfHs5rIT!.Y~>
-!<E0!joqR2eVf@JqZ-TWq>gNWquHcZr;Zi[r;cl[quHcZq#L0Oq#LHWq>gHU!!)rZq>^NXq#LBU
-rrDQNrW)oZr;_E2J`c%Us8W)Ks+C@Oon*Ras8UWFs5rIW!.Y~>
-!<E0!johL1eS8iMXF[I(XOaKQmf(c:K)krCKE(rUeYN6-k.LbF~>
-!<E0!johC3g4=g+g4@t/g=G!Xs8LaPJH5`AJcG`Sg7eQ/k.1PC~>
-!<E0!johL1eVf?:k(2ZGk18\ps8LRKK)krCKE(rUeYN6-k.LbF~>
-!<E0!johL1eS8iMXF[I(XOaKQmf(c:KCZ_Urs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g4@t/g=G!Xs8LaPJb$\Xrs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k(2ZGk18\ps8LRKKCZ_Urs%#Ls5rIW!.Y~>
-!<E0!johL1eS8iMXF[I(XOaKQmf(c:KCJmFeYN6-k.LbF~>
-!<E0!johC3g4=g+g4@t/g=G!Xs8LaPJai[Dg7eQ/k.1PC~>
-!<E0!johL1eVf?:k(2ZGk18\ps8LRKKCJmFeYN6-k.LbF~>
-!<E0!johL1eS8iMXF[I(XOaKQmf(c:KCf*LKE(u%V#TT>]`<Q~>
-!<E0!johC3g4=g+g4@t/g=G!Xs8LaPJb/mJJcGc(U&X9;\c@6~>
-!<E0!johL1eVf?:k(2ZGk18\ps8LRKKCf*LKE(u%V#TT>]`<Q~>
-!<E0!johL1eS8iMXF[I(XOaKQmf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g4@t/g=G!Xs8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k(2ZGk18\ps8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8iMXO4*L!;NYq!.h57XT._fec1:%s7Y"CKE(rUeYN6-k.LbF~>
-!<E0!johC3g4=g+g<nUS!;P:J!.ijegAh3PgAca(s7Y1HJcG`Sg7eQ/k.1PC~>
-!<E0!johL1eVf?:k0`;k!;P^V!.j9qk5YJ\ec1:%s7Y"CKE(rUeYN6-k.LbF~>
-!<E0!joqR2eS8j#quHVqrW)ktqZ-Vsq>^MsquDJQ!!)bp!!)bp!!%SOP-"]Ormh%$s8VfCs+C@O
-#1]OLk2s>WJ,~>
-!<E0!joqI4g4=h/quHWJrW)lMqZ-WLq>^NLquDK*!!)cI!!)cI!!%T(P1os9rn@C's8VfHs+14M
-#25dNk2s5TJ,~>
-!<E0!joqR2eVf@JquHWVrW)lYqZ-WXq>^NXquDK6!!)cU!!)cU!!%T4P32fErmh%$s8VfCs+C@O
-#1]OLk2s>WJ,~>
-!<E0!johL1eS8juX8i7pX8i7tX8i8!X8i8"X8i8!X8i8"X8i6RX8i7eX8i6OXHK[bmf(c:KE(uF
-ec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=hSg&M-Ig&M-Mg&M-Og&M-Pg&M-Og&M-Pg&M,+g&M->g&M,(g611is8LaPJcGcD
-gAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf@bjo>DUjo>DYjo>D[jo>D\jo>D[jo>D\jo>C7jo>DJjo>C4k*"m,s8LRKKE(uF
-ec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8juX8i7qX9&C'!;rnu!<&u!!<0&"!<&u!!<0&"!;NYq!4Ap.!!',"!;iks!<0)!
-!<0)!!;ESm!;rqt!;iks!!0/$JZP$9s6fm:s+C@Op=91qs8N;RV#TT>]`<Q~>
-!<E0!johC3g4=hSg&M-Jg&_9.!;tON!<(UO!<1[P!<(UO!<1[P!;P:J!4CP\!!(aP!;kLL!<1^O
-!<1^O!;G4F!;tRM!;kLL!!1dRJ_H:@s8W)Ps+14Mp=fOts8N;WU&X9;\c@6~>
-!<E0!johL1eVf@bjo>DVjoPPF!;tsZ!<)$[!<2*\!<)$[!<2*\!;P^V!4Cth!!)0\!;kpX!<2-[
-!<2-[!;GXR!;u!Y!;kpX!!23^J``-Xs8W)Ks+C@Op=91qs8N;RV#TT>]`<Q~>
-!<E0!johL1eS8juX8i7qX9&C'!;rnu!<&u!!<0&%!3E7%r2]kupoOJq[&j9-ri?)"rN#u!ri?)"
-ri?)"r2]kuorJ,npT+>pr2]kuriH,"JZP$9s6fm:s+C@Op=91qs8N;RV#TT>]`<Q~>
-!<E0!johC3g4=hSg&M-Jg&_9.!;tON!<(UO!<1[S!8?-,r7V,NptG`J[+bN[rn7>PrRq5Orn7>P
-rn7>Pr7V,Np"BBGpY#TIr7V,Nrn@APJ_H:@s8W)Ps+14Mp=fOts8N;WU&X9;\c@6~>
-!<E0!johL1eVf@bjo>DVjoPPF!;tsZ!<)$[!<2*_!9WDDr8mtZpu_SV[-%AgroO1\rT4([roO1\
-roO1\r8mtZp#Z5SpZ;GUr8mtZroX4\J``-Xs8W)Ks+C@Op=91qs8N;RV#TT>]`<Q~>
-!<E0!johL1eS8juX8i7rX8i8"X8i8!XS`(sXSi.sX8i7"X8i8!X8i8"X8i7uX9em.X8o?'!3E7%
-orJ,npT+>prN#u!r2]kuJZP$9s6fm:s+C@Op=91qs8N;RV#TT>]`<Q~>
-!<E0!johC3g4=hSg&M-Kg&M-Pg&M-OgACsLgAM$Lg&M,Pg&M-Og&M-Pg&M-Ng'Ic5g&Tj\!8?-,
-p"BBGpY#TIrRq5Or7V,NJ_H:@s8W)Ps+14Mp=fOts8N;WU&X9;\c@6~>
-!<E0!johL1eVf@bjo>DWjo>D\jo>D[k555Xk5>;Xjo>C\jo>D[jo>D\jo>DZjp;%MjoFQ+!9WDD
-p#Z5SpZ;GUrT4([r8mtZJ``-Xs8W)Ks+C@Op=91qs8N;RV#TT>]`<Q~>
-!<E0!johL1eS8juX8i8!X8i8"XS`(sX8i8!X8i8"X9/I(X8r1"!!)u!!!'1'!!)u!!!*#"q>gPs
-"ota+!3E7%orJ,npT+>prN#u!r2]kuJZP$9s6fm:s+C@Op=91qs8N;RV#TT>]`<Q~>
-!<E0!johC3g4=hSg&M-Og&M-PgACsLg&M-Og&M-Pg&h?/g&V')!!)uO!!'1U!!)uO!!*#Pq>gQL
-"p!B2!8?-,p"BBGpY#TIrRq5Or7V,NJ_H:@s8W)Ps+14Mp=fOts8N;WU&X9;\c@6~>
-!<E0!johL1eVf@bjo>D[jo>D\k555Xjo>D[jo>D\joYVGjoG>A!!)u[!!'1a!!)u[!!*#\q>gQX
-"p!fJ!9WDDp#Z5SpZ;GUrT4([r8mtZJ``-Xs8W)Ks+C@Op=91qs8N;RV#TT>]`<Q~>
-!<E0!johL1eS8juX8i8!X9/I(X8r1"!!*#"!!)u!!!*#"!!)u!!!*#"!!)u!!!'1'!!)u!!!*#"
-!!)eq"9>M'X8qmo!!)bp!!)u!!!)qu!!%SOP-"]Ormh%$s8VfCs+C@O#1]OLk2s>WJ,~>
-!<E0!johC3g4=hSg&M-Og&h?/g&V')!!*#P!!)uO!!*#P!!)uO!!*#P!!)uO!!'1U!!)uO!!*#P
-!!)fJ"9@-Ug&Ud!!!)cI!!)uO!!)rN!!%T(P1os9rn@C's8VfHs+14M#25dNk2s5TJ,~>
-!<E0!johL1eVf@bjo>D[joYVGjoG>A!!*#\!!)u[!!*#\!!)u[!!*#\!!)u[!!'1a!!)u[!!*#\
-!!)fV"9@QajoG&9!!)cU!!)u[!!)rZ!!%T4P32fErmh%$s8VfCs+C@O#1]OLk2s>WJ,~>
-!<E0!johL1eS8juX8i8!X9/I(X8r1"!!*#"!!)u!!!*#"!!)u!!!*#"!!)u!!!)u!rrBF-!!)u!
-!!)u!!!)u!!!*#"rr<,%!!)Ym!!*#"!!)nt!!)qu!!*#"rr@VOP-"]Ormh%$s8VfCs+C@O#1]OL
-k2s>WJ,~>
-!<E0!johC3g4=hSg&M-Og&h?/g&V')!!*#P!!)uO!!*#P!!)uO!!*#P!!)uO!!)uOrrBF[!!)uO
-!!)uO!!)uO!!*#Prr<,S!!)ZF!!*#P!!)oM!!)rN!!*#Prr@W(P1os9rn@C's8VfHs+14M#25dN
-k2s5TJ,~>
-!<E0!johL1eVf@bjo>D[joYVGjoG>A!!*#\!!)u[!!*#\!!)u[!!*#\!!)u[!!)u[rrBFg!!)u[
-!!)u[!!)u[!!*#\rr<,_!!)ZR!!*#\!!)oY!!)rZ!!*#\rr@W4P32fErmh%$s8VfCs+C@O#1]OL
-k2s>WJ,~>
-!<E0!joqR2eS8j#q#CDrr;Zi!r;Zi!qZ-Vsq>^Msq#LAprrBI.rW)u"rW)nur;cetrr<,%!!)Vl
-rW)ktquH\srW!#$!!%SOPH=fPrmh%$s8VfCs+C@O#1]OLk2s>WJ,~>
-!<E0!joqI4g4=h/q#CEKr;ZiOr;ZiOqZ-WLq>^NLq#LBIrrBI\rW)uPrW)oNr;cfMrr<,S!!)WE
-rW)lMquH]LrW!#R!!%T(PM6':rn@C's8VfHs+14M#25dNk2s5TJ,~>
-!<E0!joqR2eVf@Jq#CEWr;Zi[r;Zi[qZ-WXq>^NXq#LBUrrBIhrW)u\rW)oZr;cfYrr<,_!!)WQ
-rW)lYquH]XrW!#^!!%T4PNMoFrmh%$s8VfCs+C@O#1]OLk2s>WJ,~>
-!<E0!johL1eS8iMXF[I(XOaKQmf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g4@t/g=G!Xs8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k(2ZGk18\ps8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8iMXF[I(XOaKQmf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g4@t/g=G!Xs8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k(2ZGk18\ps8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8iMXQQ\[!.h5&XSJstmf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g?72b!.ijTgA0J&s8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k3(n%!.j9`k5"0>s8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8iMXF[I(XOaKQmf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g4@t/g=G!Xs8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k(2ZGk18\ps8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8iMXF[I(XOaKQmf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g4@t/g=G!Xs8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k(2ZGk18\ps8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8iMXF[I(XOaKQmf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g4@t/g=G!Xs8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k(2ZGk18\ps8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!jp%X3eS8j#XSMnsXSW"qXSi.uXSr5!XSr3rX8i6OXF[J*XT._fec1:%s7Y"CKE(rUeYN6-
-k.LbF~>
-!<E0!jp%O5g4=h/gA1dLgA:mJgAM$NgAV*OgAV)Kg&M,(g4@u1gAh3PgAca(s7Y1HJcG`Sg7eQ/
-k.1PC~>
-!<E0!jp%X3eVf@Jk5#&Xk5,/Vk5>;Zk5GA[k5G@Wjo>C4k(2[Ik5YJ\ec1:%s7Y"CKE(rUeYN6-
-k.LbF~>
-!<E0!johL1eS8juX8i8!X9/I(X8r4#!!*#"!!)u!!!*#"rrE&"rrAjr!!%SOJZRM*s6fm:s+C@O
-p=91qs8N;RV#TT>]`<Q~>
-!<E0!johC3g4=hSg&M-Og&h?/g&V**!!*#P!!)uO!!*#PrrE&PrrAkK!!%T(J_Jc1s8W)Ps+14M
-p=fOts8N;WU&X9;\c@6~>
-!<E0!johL1eVf@bjo>D[joYVGjoGAB!!*#\!!)u[!!*#\rrE&\rrAkW!!%T4J`bVIs8W)Ks+C@O
-p=91qs8N;RV#TT>]`<Q~>
-!<E0!johL1eS8juX8i8!X9/I(X8r4#!s#F(!;ii%!3E7%X8o@$!<'#!!3<4!!<'#!!<9/#!<'"t
-!<0)"!!',"!;rqr!;<Mo!!TG(!3?/#riH)!$EO4-XK2C%XK2C%JZPZKs6fm:s+C@Op=91qs8N;R
-V#TT>]`<Q~>
-!<E0!johC3g4=hSg&M-Og&h?/g&V**!s%'/!;kIS!8?-,g&Tk+!<(XO!3=iO!<(XO!<:dQ!<(XM
-!<1^P!!(aP!;tRK!;>.H!!V'V!87DQrn@>O$JGI[g=cN,g=cN,J_HpRs8W)Ps+14Mp=fOts8N;W
-U&X9;\c@6~>
-!<E0!johL1eVf@bjo>D[joYVGjoGAB!s%KG!;km_!9WDDjoFQC!<)'[!3>8[!<)'[!<;3]!<)'Y
-!<2-\!!)0\!;u!W!;>RT!!VKb!9O7]roX1[$K_<gk2lXDk2lXDJ``cjs8W)Ks+C@Op=91qs8N;R
-V#TT>]`<Q~>
-!<E0!johL1eS8juX9/I(X8r4#!!)u!!s#F(!;ii(!3E7%X8o=%X8r4#rrB(#!!)hr#QUq+XK2E'
-X8r4#!!*#"rrE&"!!*#"!!)u!!!)\nrr<;*!!')#XK2F$XT&;!X9AU*!3E7%JZP]Ls6fm:s+C@O
-p=91qs8N;RV#TT>]`<Q~>
-!<E0!johC3g4=hSg&h?/g&V**!!)uO!s%'/!;kIV!8?-,g&Th,g&V**rrB(Q!!)iK#QWQYg=cP\
-g&V**!!*#PrrE&P!!*#P!!)uO!!)]Grr<;X!!(^Qg=cQ+gA_0Og'%K1!8?-,J_HsSs8W)Ps+14M
-p=fOts8N;WU&X9;\c@6~>
-!<E0!johL1eVf@bjoYVGjoGAB!!)u[!s%KG!;kmb!9WDDjoFNDjoGABrrB(]!!)iW#QWuek2l[+
-joGAB!!*#\rrE&\!!*#\!!)u[!!)]Srr<;d!!)-]k2l[Ck5PG[jokbI!9WDDJ``fks8W)Ks+C@O
-p=91qs8N;RV#TT>]`<Q~>
-!<E0!johL1eS8juXSi.tX8i8"X8i8"X8i7tX9em.X8o?'!3E7%UoXOrq5jSrp8e5ori?)"rN#u!
-ri?)"n>llqXK2E'X8o=%r2]kurN-#!JZPQHs6fm:s+C@Op=91qs8N;RV#TT>]`<Q~>
-!<E0!johC3g4=hSgAM$Mg&M-Pg&M-Pg&M-Mg'Ic5g&Tj\!8?-,UtPeKq:biKp=]KHrn7>PrRq5O
-rn7>PnCe-Jg=cP\g&Th,r7V,NrS%8OJ_HgOs8W)Ps+14Mp=fOts8N;WU&X9;\c@6~>
-!<E0!johL1eVf@bk5>;Yjo>D\jo>D\jo>DYjp;%MjoFQ+!9WDDUuhXWq<%\Wp>u>TroO1\rT4([
-roO1\nE'uVk2l[+joFNDr8mtZrT=+[J``Zgs8W)Ks+C@Op=91qs8N;RV#TT>]`<Q~>
-!<E0!johL1eS8juX9/I(X8r4#r;cet!!)nt#lq'.!3E7%XK2DtX8i7rX8i7rXS`(tX8i8!X8i8!
-XSi.kX9\g-X8o?'!3?1uX8i8!X8i6OXIuZpmf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=hSg&h?/g&V**r;cfM!!)oM#lr]5!8?-,g=cP&g&M-Kg&M-KgACsMg&M-Og&M-O
-gAM$Dg'@]4g&Tj\!87GNg&M-Og&M,(g7[1"s8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf@bjoYVGjoGABr;cfY!!)oY#ls,M!9WDDk2lZ>jo>DWjo>DWk555Yjo>D[jo>D[
-k5>;Pjp1tLjoFQ+!9O:Zjo>D[jo>C4k+Ll:s8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8juX8i7sX8i8"X8i8"X8i7tX9/I(X8r1"!!&gr!!)hr!!)ks!!)u!!!*#"!!)u!
-!!)hr!!)\n#QUs-!3E7%X8r1"!!)u!!!%SOTWJ1]rmh%$s8VfCs+C@O#1]OLk2s>WJ,~>
-!<E0!johC3g4=hSg&M-Lg&M-Pg&M-Pg&M-Mg&h?/g&V')!!&hK!!)iK!!)lL!!)uO!!*#P!!)uO
-!!)iK!!)]G#QWT4!8?-,g&V')!!)uO!!%T(T\BGGrn@C's8VfHs+14M#25dNk2s5TJ,~>
-!<E0!johL1eVf@bjo>DXjo>D\jo>D\jo>DYjoYVGjoG>A!!&hW!!)iW!!)lX!!)u[!!*#\!!)u[
-!!)iW!!)]S#QX#L!9WDDjoG>A!!)u[!!%T4T]Z:Srmh%$s8VfCs+C@O#1]OLk2s>WJ,~>
-!<E0!johL1eS8juX8i7sX8i8!X8i8"X8i8!X8i8"X8i7uX8i8!XT&:#X8i8"X8i8!X8i7sX8i8"
-XT&;"X8i8!X8i8"X8i8!X8i7nX9em.X8o?'!3E7%riH,"rN#u!JZPNGs6fm:s+C@Op=91qs8N;R
-V#TT>]`<Q~>
-!<E0!johC3g4=hSg&M-Lg&M-Og&M-Pg&M-Og&M-Pg&M-Ng&M-OgA_/Qg&M-Pg&M-Og&M-Lg&M-P
-gA_0Pg&M-Og&M-Pg&M-Og&M-Gg'Ic5g&Tj\!8?-,rn@APrRq5OJ_HdNs8W)Ps+14Mp=fOts8N;W
-U&X9;\c@6~>
-!<E0!johL1eVf@bjo>DXjo>D[jo>D\jo>D[jo>D\jo>DZjo>D[k5PF]jo>D\jo>D[jo>DXjo>D\
-k5PG\jo>D[jo>D\jo>D[jo>DSjp;%MjoFQ+!9WDDroX4\rT4([J``Wfs8W)Ks+C@Op=91qs8N;R
-V#TT>]`<Q~>
-!<E0!jp%X3eS8j#XSi.tXSr4uX8i8"XSi.uXSr5!XSr5!XT&:"XSr4uXSi.rXSr2%X8i7%rW)u"
-rW)u"quHDkrW!2)!!')#!3E:$!!0/$riH%uJZPTIs6fm:s+C@Op=91qs8N;RV#TT>]`<Q~>
-!<E0!jp%O5g4=h/gAM$MgAV*Ng&M-PgAM$NgAV*OgAV*OgA_/PgAV*NgAM$KgAV'Sg&M-,rW)uP
-rW)uPquHEDrW!2W!!(^Q!8?0+!!1dRrn@;NJ_HjPs8W)Ps+14Mp=fOts8N;WU&X9;\c@6~>
-!<E0!jp%X3eVf@Jk5>;Yk5GAZjo>D\k5>;Zk5GA[k5GA[k5PF\k5GAZk5>;Wk5G>_jo>DDrW)u\
-rW)u\quHEPrW!2c!!)-]!9WGC!!23^roX.ZJ``]hs8W)Ks+C@Op=91qs8N;RV#TT>]`<Q~>
-!<E0!johL1eS8iMXM(\8!.h5@XT._fec1:%s7Y"CKE(rUeYN6-k.LbF~>
-!<E0!johC3g4=g+g:c2?!.ijngAh3PgAca(s7Y1HJcG`Sg7eQ/k.1PC~>
-!<E0!johL1eVf?:k.TmW!.j:%k5YJ\ec1:%s7Y"CKE(rUeYN6-k.LbF~>
-!<E0!johL1eS8iMXM1b9!.h5?XT._fec1:%s7Y"CKE(rUeYN6-k.LbF~>
-!<E0!johC3g4=g+g:l8@!.ijmgAh3PgAca(s7Y1HJcG`Sg7eQ/k.1PC~>
-!<E0!johL1eVf?:k.]sX!.j:$k5YJ\ec1:%s7Y"CKE(rUeYN6-k.LbF~>
-!<E0!johL1eS8iMXOXEI!;ESn!.h5>XT._fec1:%s7Y"CKE(rUeYN6-k.LbF~>
-!<E0!johC3g4=g+g==pP!;G4G!.ijlgAh3PgAca(s7Y1HJcG`Sg7eQ/k.1PC~>
-!<E0!johL1eVf?:k1/Vh!;GXS!.j:#k5YJ\ec1:%s7Y"CKE(rUeYN6-k.LbF~>
-!<E0!johL1eS8iMXF[I(XOaKQmf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g4@t/g=G!Xs8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k(2ZGk18\ps8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8iMXF[I(XOaKQmf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g4@t/g=G!Xs8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k(2ZGk18\ps8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8iMXPU&Y!.h5&XS]+!mf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g>:Q`!.ijTgABV(s8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k2,8#!.j9`k54<@s8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!jp%X3eS8j#XSMqrXSi-MXR3(h!:R#g!;iks!.h5>XT._fec1:%s7Y"CKE(rUeYN6-k.LbF~>
-!<E0!jp%O5g4=h/gA1gKgAM#&g?mSo!:SY@!;kLL!.ijlgAh3PgAca(s7Y1HJcG`Sg7eQ/k.1PC~>
-!<E0!jp%X3eVf@Jk5#)Wk5>:2k3_:2!:T(L!;kpX!.j:#k5YJ\ec1:%s7Y"CKE(rUeYN6-k.LbF~>
-!<E0!jq+?=eS8j#X8o?'!3E7%XK2F#X8i6OXR<.i!:?if!;W\r!.h5>XT._fec1:%s7Y"CKE(rU
-eYN6-k.LbF~>
-!<E0!jq+6?g4=h/g&Tj\!8?-,g=cQ*g&M,(g@!Yp!:AJ?!;Y=K!.ijlgAh3PgAca(s7Y1HJcG`S
-g7eQ/k.1PC~>
-!<E0!jq+?=eVf@JjoFQ+!9WDDk2l[Bjo>C4k3h@3!:AnK!;YaW!.j:#k5YJ\ec1:%s7Y"CKE(rU
-eYN6-k.LbF~>
-!<E0!jq"9<eS8j#X8o?'!3E7%X8r.!!!)u!rrALhrr<8)!!')#!3H/"s/c2"orS&kri?,#XSr4s
-XSr4rX8i7rX8i6OXI60imf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!jq"0>g4=h/g&Tj\!8?-,g&V$(!!)uOrrAMArr<8W!!(^Q!8@DPs4[GPp"K<Drn7AQgAV*L
-gAV*Kg&M-Kg&M,(g6p[ps8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!jq"9<eVf@JjoFQ+!9WDDjoG;@!!)u[rrAMMrr<8c!!)-]!9X7\s5s:\p#c/ProO4]k5GAX
-k5GAWjo>DWjo>C4k*bB3s8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8jsX8i8!X8i7tX8i8!XT&9gXT&8*X8i7%!3E7%rN#u!orJ,nrN#u!riH,"ri?)"
-rN#u!ri?)"qlBbtq5aPrJZP9@s6fm:s+C@Op=91qs8N;RV#TT>]`<Q~>
-!<E0!johC3g4=hQg&M-Og&M-Mg&M-OgA_/@gA_-Xg&M-,!8?-,rRq5Op"BBGrRq5Orn@APrn7>P
-rRq5Orn7>Pqq;#Mq:YfKJ_HOGs8W)Ps+14Mp=fOts8N;WU&X9;\c@6~>
-!<E0!johL1eVf@`jo>D[jo>DYjo>D[k5PFLk5PDdjo>DD!9WDDrT4([p#Z5SrT4([roX4\roO1\
-rT4([roO1\qrRkYq;qYWJ``B_s8W)Ks+C@Op=91qs8N;RV#TT>]`<Q~>
-!<E0!johL1eS8jsX8i8!X8i7tX8i6aX9em.X8o?'!3E7%rN#u!orJ,nq5aPrrN#u!ri?)"r2]ku
-r2]kuq5aPrJZP9@s6fm:s+C@Op=91qs8N;RV#TT>]`<Q~>
-!<E0!johC3g4=hQg&M-Og&M-Mg&M,:g'Ic5g&Tj\!8?-,rRq5Op"BBGq:YfKrRq5Orn7>Pr7V,N
-r7V,Nq:YfKJ_HOGs8W)Ps+14Mp=fOts8N;WU&X9;\c@6~>
-!<E0!johL1eVf@`jo>D[jo>DYjo>CFjp;%MjoFQ+!9WDDrT4([p#Z5Sq;qYWrT4([roO1\r8mtZ
-r8mtZq;qYWJ``B_s8W)Ks+C@Op=91qs8N;RV#TT>]`<Q~>
-!<E0!johL1eS8jsX8i8!X8i7tX8i6aX9J[+X8o?'!<0&%!3E7%o;qljrN#u!rN#u!riGqrr2]ku
-q5aPrJZP9@s6fm:s+C@Op=91qs8N;RV#TT>]`<Q~>
-!<E0!johC3g4=hQg&M-Og&M-Mg&M,:g'.Q2g&Tj\!<1[S!8?-,o@j-CrRq5OrRq5Orn@2Kr7V,N
-q:YfKJ_HOGs8W)Ps+14Mp=fOts8N;WU&X9;\c@6~>
-!<E0!johL1eVf@`jo>D[jo>DYjo>CFjothJjoFQ+!<2*_!9WDDoB,uOrT4([rT4([roX%Wr8mtZ
-q;qYWJ``B_s8W)Ks+C@Op=91qs8N;RV#TT>]`<Q~>
-!<E0!johL1eS8jsX8i8!X8i7tX8i6aX9J[+X8o?'!<0&%!3E7%n#QKhri?)"rN#u!ri?)"p8e5o
-q5aPrJZP9@s6fm:s+C@Op=91qs8N;RV#TT>]`<Q~>
-!<E0!johC3g4=hQg&M-Og&M-Mg&M,:g'.Q2g&Tj\!<1[S!8?-,n(IaArn7>PrRq5Orn7>Pp=]KH
-q:YfKJ_HOGs8W)Ps+14Mp=fOts8N;WU&X9;\c@6~>
-!<E0!johL1eVf@`jo>D[jo>DYjo>CFjothJjoFQ+!<2*_!9WDDn)aTMroO1\rT4([roO1\p>u>T
-q;qYWJ``B_s8W)Ks+C@Op=91qs8N;RV#TT>]`<Q~>
-!<E0!johL1eS8jsX8i7uX8i8!X8i7uXT&9gX9J[+X8o?'!<'#!!;!8l!<&u!!<0&"!<&u!!<&u!
-!<&u!!;rnu!;W\r!.h5>XT._fec1:%s7Y"CKE(rUeYN6-k.LbF~>
-!<E0!johC3g4=hQg&M-Ng&M-Og&M-NgA_/@g'.Q2g&Tj\!<(XO!;"nE!<(UO!<1[P!<(UO!<(UO
-!<(UO!;tON!;Y=K!.ijlgAh3PgAca(s7Y1HJcG`Sg7eQ/k.1PC~>
-!<E0!johL1eVf@`jo>DZjo>D[jo>DZk5PFLjothJjoFQ+!<)'[!;#=Q!<)$[!<2*\!<)$[!<)$[
-!<)$[!;tsZ!;YaW!.j:#k5YJ\ec1:%s7Y"CKE(rUeYN6-k.LbF~>
-!<E0!johL1eS8juXS`(sXSi.rXT&9hXSr2'X8i7%!!)u!!!)VlquH_trW)u"rW)nur;cetquH\s
-quD;LS#lYXrmh%$s8VfCs+C@O#1]OLk2s>WJ,~>
-!<E0!johC3g4=hSgACsLgAM$KgA_/AgAV'Ug&M-,!!)uO!!)WEquH`MrW)uPrW)oNr;cfMquH]L
-quD<%S(doBrn@C's8VfHs+14M#25dNk2s5TJ,~>
-!<E0!johL1eVf@bk555Xk5>;Wk5PFMk5G>ajo>DD!!)u[!!)WQquH`YrW)u\rW)oZr;cfYquH]X
-quD<1S*'bNrmh%$s8VfCs+C@O#1]OLk2s>WJ,~>
-!<E0!johL1eS8iMXS/^q!.h5&XQ$>]mf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g@j5#!.ijTg>^ids8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k4[p;!.j9`k2PP's8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8iMXS/^q!.h5&XQ$>]mf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g@j5#!.ijTg>^ids8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k4[p;!.j9`k2PP's8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8iMXSAmq!<'"o!.h5&XRN=kmf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+gA'D#!<(XH!.ijTg@3hrs8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k4n*;!<)'T!.j9`k4%O5s8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8iMXF[I(XOaKQmf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g4@t/g=G!Xs8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k(2ZGk18\ps8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8iMXF[I(XOaKQmf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g4@t/g=G!Xs8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k(2ZGk18\ps8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8iMX8o@#!;rqs!;rqs!;rqs!:m2k!;`eq!:m2k!;NYq!:m2k!;NYq!;!;j!<'"r
-!:m5k!;rqt!:m5i!;iks!;iht!;W_q!;rqs!;rqs!5,E5mf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g&Tk*!;tRL!;tRL!;tRL!:nhD!;bFJ!:nhD!;P:J!:nhD!;P:J!;"qC!<(XK
-!:nkD!;tRM!:nkB!;kLL!;kIM!;Y@J!;tRL!;tRL!5.%cs8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:joFQB!;u!X!;u!X!;u!X!:o7P!;bjV!:o7P!;P^V!:o7P!;P^V!;#@O!<)'W
-!:o:P!;u!Y!:o:N!;kpX!;kmY!;YdV!;u!X!;u!X!5.Ios8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!jp%X3eS8j#XSW"rXSr4uXSW"qXSr2#X8r7$q>^MsqZ+%*!!)u!!!*#"!!)u!!!*#"!!)u!
-!!*#"!!)u!!!)YmrrDqt!!)u!!!)YmrrDkr!W];%o;qrlq5aVtX8qmo!!)u!!!*#"!!)u!!!)Vl
-!W];%rN#u!ri?)"oW/#mrN#u!rN#u!q5jSrqQ'YsqQ'YsrN#u!ri?)"rN#u!]r_8%rmh%$s8VfC
-s+C@O#1]OLk2s>WJ,~>
-!<E0!jp%O5g4=h/gA:mKgAV*NgA:mJgAV'Qg&V-+q>^NLqZ+%X!!)uO!!*#P!!)uO!!*#P!!)uO
-!!*#P!!)uO!!)ZFrrDrM!!)uO!!)ZFrrDlK!W^pSo@j3Eq:YlMg&Ud!!!)uO!!*#P!!)uO!!)WE
-!W^pSrRq5Orn7>Po\'9FrRq5OrRq5Oq:biKqUtoLqUtoLrRq5Orn7>PrRq5O^"WMdrn@C's8VfH
-s+14M#25dNk2s5TJ,~>
-!<E0!jp%X3eVf@Jk5,/Wk5GAZk5,/Vk5G>]joGDCq>^NXqZ+%d!!)u[!!*#\!!)u[!!*#\!!)u[
-!!*#\!!)u[!!)ZRrrDrY!!)u[!!)ZRrrDlW!W_?_oB-&Qq;q_YjoG&9!!)u[!!*#\!!)u[!!)WQ
-!W_?_rT4([roO1\o]?,RrT4([rT4([q<%\WqW7bXqW7bXrT4([roO1\rT4([^#o@prmh%$s8VfC
-s+C@O#1]OLk2s>WJ,~>
-!<E0!johL1eS8juX8i8!X8i7uX8i7uX8i8!X8i8"X8i8"XT&;!X8i8!X9/I(X8r4#!!'I/!!)u!
-!!*#"!!)u!!!*#"!!)u!!!*#"!!)u!!!)\n!W];%qlBbtrN#u!orJ2pX8r't!W];%oW/)oX8r't
-!W];%oW/#mrN#u!q5aPro;hunX8r4#!!)u!!!)\n!!)u!!!*#"!!)hr!W];%qlBbtq5aPrrN#u!
-ri?)"rN#u!]r_8%rmh%$s8VfCs+C@O#1]OLk2s>WJ,~>
-!<E0!johC3g4=hSg&M-Og&M-Ng&M-Ng&M-Og&M-Pg&M-PgA_0Og&M-Og&h?/g&V**!!'I]!!)uO
-!!*#P!!)uO!!*#P!!)uO!!*#P!!)uO!!)]G!W^pSqq;#MrRq5Op"BHIg&Us&!W^pSo\'?Hg&Us&
-!W^pSo\'9FrRq5Oq:YfKo@a6Gg&V**!!)uO!!)]G!!)uO!!*#P!!)iK!W^pSqq;#Mq:YfKrRq5O
-rn7>PrRq5O^"WMdrn@C's8VfHs+14M#25dNk2s5TJ,~>
-!<E0!johL1eVf@bjo>D[jo>DZjo>DZjo>D[jo>D\jo>D\k5PG[jo>D[joYVGjoGAB!!'Ii!!)u[
-!!*#\!!)u[!!*#\!!)u[!!*#\!!)u[!!)]S!W_?_qrRkYrT4([p#Z;UjoG5>!W_?_o]?2TjoG5>
-!W_?_o]?,RrT4([q;qYWoB$)SjoGAB!!)u[!!)]S!!)u[!!*#\!!)iW!W_?_qrRkYq;qYWrT4([
-roO1\rT4([^#o@prmh%$s8VfCs+C@O#1]OLk2s>WJ,~>
-!<E0!johL1eS8juX8i8!X8i8!X9&C'!<&u!!<&u!!<0&"!<&u!!<&u!!<&u$!3E7%r2]kurN-#!
-\?#Z1ri?)"rN#u!ri?)"rN#u!q5aPro;holqlBbtrN#u!o;holqQ'c!XK2EmX8i7sX9/I(X8q^j
-!!)ks!!)Vl!s#F(!<&u!!<&u!!:[&i!<0&"!;EPp!;iht!;*>m!;W\r!55K6mf(c:KE(uFec1:%
-rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=hSg&M-Og&M-Og&_9.!<(UO!<(UO!<1[P!<(UO!<(UO!<(UR!8?-,r7V,NrS%8O
-\Cpo_rn7>PrRq5Orn7>PrRq5Oq:YfKo@a0Eqq;#MrRq5Oo@a0EqUu#Og=cPtg&M-Lg&h?/g&UTq
-!!)lL!!)WE!s%'/!<(UO!<(UO!:\\B!<1[P!;G1I!;kIM!;+tF!;Y=K!57+ds8LaPJcGcDgAca(
-rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf@bjo>D[jo>D[joPPF!<)$[!<)$[!<2*\!<)$[!<)$[!<)$^!9WDDr8mtZrT=+[
-\E3bkroO1\rT4([roO1\rT4([q;qYWoB$#QqrRkYrT4([oB$#QqW7k[k2l[7jo>DXjoYVGjoFl4
-!!)lX!!)WQ!s%KG!<)$[!<)$[!:]+N!<2*\!;GUU!;kmY!;,CR!;YaW!57Ops8LRKKE(uFec1:%
-rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8juX8i8!X8i8!X9&C'!<&u!!<&u!!<0&"!;NVt!3E7%rN#u!r2]kurN-#!\Z>c2
-rN#u!rN#u!ri?)"rN#u!qQ'YsnuMfkqlBbtrN#u!o;holqQ'c!XK2EmX8i7sX9/I(X8qak!!)hr
-!!)Vl!s#F(!<&u!!<0)"!:d,j!<&u"!3H/"qlBbtqlBeuXSr4qX8i7rX8i75XT._fec1:%s7Y"C
-KE(rUeYN6-k.LbF~>
-!<E0!johC3g4=hSg&M-Og&M-Og&_9.!<(UO!<(UO!<1[P!;P7M!8?-,rRq5Or7V,NrS%8O\_7#`
-rRq5OrRq5Orn7>PrRq5OqUtoLo%F'Dqq;#MrRq5Oo@a0EqUu#Og=cPtg&M-Lg&h?/g&UWr!!)iK
-!!)WE!s%'/!<(UO!<1^P!:ebC!<(UP!8@DPqq;#Mqq;&NgAV*Jg&M-Kg&M,cgAh3PgAca(s7Y1H
-JcG`Sg7eQ/k.1PC~>
-!<E0!johL1eVf@bjo>D[jo>D[joPPF!<)$[!<)$[!<2*\!;P[Y!9WDDrT4([r8mtZrT=+[\`Nkl
-rT4([rT4([roO1\rT4([qW7bXo&]oPqrRkYrT4([oB$#QqW7k[k2l[7jo>DXjoYVGjoFo5!!)iW
-!!)WQ!s%KG!<)$[!<2-\!:f1O!<)$\!9X7\qrRkYqrRnZk5GAVjo>DWjo>Cok5YJ\ec1:%s7Y"C
-KE(rUeYN6-k.LbF~>
-!<E0!johL1eS8juX8i8!X8i8"X8i8"X8i8"X8i8"X8i7uXSi.sXSi.tX8i7uX8i7-X8i7uX8i8!
-X8i8"X8i8!X8i7tX8i7uXSW"qX8i7tX8i8!X8i8"XSW"qX8i7tX8i8"X8i7kX8i7tX8i8"X8i7j
-X8i7qX8i7mX8i8"X8i7uXSr2#X8qgm!!)qurrE&"!!)qu!!)ntrrE&"!!)nt!!)hr!!'X4s6fm:
-s+C@Op=91qs8N;RV#TT>]`<Q~>
-!<E0!johC3g4=hSg&M-Og&M-Pg&M-Pg&M-Pg&M-Pg&M-NgAM$LgAM$Mg&M-Ng&M,[g&M-Ng&M-O
-g&M-Pg&M-Og&M-Mg&M-NgA:mJg&M-Mg&M-Og&M-PgA:mJg&M-Mg&M-Pg&M-Dg&M-Mg&M-Pg&M-C
-g&M-Jg&M-Fg&M-Pg&M-NgAV'Qg&U]t!!)rNrrE&P!!)rN!!)oMrrE&P!!)oM!!)iK!!'Xbs8W)P
-s+14Mp=fOts8N;WU&X9;\c@6~>
-!<E0!johL1eVf@bjo>D[jo>D\jo>D\jo>D\jo>D\jo>DZk5>;Xk5>;Yjo>DZjo>Cgjo>DZjo>D[
-jo>D\jo>D[jo>DYjo>DZk5,/Vjo>DYjo>D[jo>D\k5,/Vjo>DYjo>D\jo>DPjo>DYjo>D\jo>DO
-jo>DVjo>DRjo>D\jo>DZk5G>]joFu7!!)rZrrE&\!!)rZ!!)oYrrE&\!!)oY!!)iW!!'Xns8W)K
-s+C@Op=91qs8N;RV#TT>]`<Q~>
-!<E0!johL1eS8juXS`(sXS`(tXSi.nX8i8!X9/I(X8r4#!!)qu!!'F.!!)nt!!)u!!!*#"!!)u!
-!!)qu!!)Mi!!)nt!!)u!!!)Vl!!)nt!!*#"!!)Sk!!)nt!!*#"!!)Sk!!)eq!!)Vl!!*#"!!)eq
-!!)Vl!!)nt!!)u!!!)qu!!)nt!!)u!!!)qu!!)hr!!'U3s6fm:s+C@Op=91qs8N;RV#TT>]`<Q~>
-!<E0!johC3g4=hSgACsLgACsMgAM$Gg&M-Og&h?/g&V**!!)rN!!'F\!!)oM!!)uO!!*#P!!)uO
-!!)rN!!)NB!!)oM!!)uO!!)WE!!)oM!!*#P!!)TD!!)oM!!*#P!!)TD!!)fJ!!)WE!!*#P!!)fJ
-!!)WE!!)oM!!)uO!!)rN!!)oM!!)uO!!)rN!!)iK!!'Uas8W)Ps+14Mp=fOts8N;WU&X9;\c@6~>
-!<E0!johL1eVf@bk555Xk555Yk5>;Sjo>D[joYVGjoGAB!!)rZ!!'Fh!!)oY!!)u[!!*#\!!)u[
-!!)rZ!!)NN!!)oY!!)u[!!)WQ!!)oY!!*#\!!)TP!!)oY!!*#\!!)TP!!)fV!!)WQ!!*#\!!)fV
-!!)WQ!!)oY!!)u[!!)rZ!!)oY!!)u[!!)rZ!!)iW!!'Ums8W)Ks+C@Op=91qs8N;RV#TT>]`<Q~>
-!<E0!johL1eS8juX8i7sX8i7uX9/I(X8r7$!!)u!!!)u!!!)u!!!)u!!s#F(!;rnu!4Js/!;`bs
-!<&u!!<0&"!<&u!!<&u!!:Quh!;iht!<&u!!;!8l!;ikp!;!8l!;ikp!;*>m!;EPp!;!;h!;W\r
-!;*>m!;`bs!<&u!!;rnu!;iht!<&u!!<&u!!;W\r!4f32mf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=hSg&M-Lg&M-Ng&h?/g&V-+!!)uO!!)uO!!)uO!!)uO!s%'/!;tON!4LS]!;bCL
-!<(UO!<1[P!<(UO!<(UO!:SVA!;kIM!<(UO!;"nE!;kLI!;"nE!;kLI!;+tF!;G1I!;"qA!;Y=K
-!;+tF!;bCL!<(UO!;tON!;kIM!<(UO!<(UO!;Y=K!4gh`s8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf@bjo>DXjo>DZjoYVGjoGDC!!)u[!!)u[!!)u[!!)u[!s%KG!;tsZ!4M"i!;bgX
-!<)$[!<2*\!<)$[!<)$[!:T%M!;kmY!<)$[!;#=Q!;kpU!;#=Q!;kpU!;,CR!;GUU!;#@M!;YaW
-!;,CR!;bgX!<)$[!;tsZ!;kmY!<)$[!<)$[!;YaW!4h7ls8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8juX8i7sX8i7uX9/I(X8r4#!!*#"rrE&"!!)u!!!)u!!s#F(!<&u!!;rqu!55H6
-!<&u!!<0&"!<&u!!<0&"!<&u!!<0&"!<&u!!;!8l!;iht!<&u!!;!8l!;EPp!:m2k!;EPp!;ikt
-!;rnu!<&u!!;iht!;`es!;NVq!;W\r!;ikt!;rnu!<&u!!<&u!!<0&"!;rnu!;`bs!<0&"!<0&"
-!<&u!!<0&"!<&u!!55K6mf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=hSg&M-Lg&M-Ng&h?/g&V**!!*#PrrE&P!!)uO!!)uO!s%'/!<(UO!;tRN!57(d
-!<(UO!<1[P!<(UO!<1[P!<(UO!<1[P!<(UO!;"nE!;kIM!<(UO!;"nE!;G1I!:nhD!;G1I!;kLM
-!;tON!<(UO!;kIM!;bFL!;P7J!;Y=K!;kLM!;tON!<(UO!<(UO!<1[P!;tON!;bCL!<1[P!<1[P
-!<(UO!<1[P!<(UO!57+ds8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf@bjo>DXjo>DZjoYVGjoGAB!!*#\rrE&\!!)u[!!)u[!s%KG!<)$[!;u!Z!57Lp
-!<)$[!<2*\!<)$[!<2*\!<)$[!<2*\!<)$[!;#=Q!;kmY!<)$[!;#=Q!;GUU!:o7P!;GUU!;kpY
-!;tsZ!<)$[!;kmY!;bjX!;P[V!;YaW!;kpY!;tsZ!<)$[!<)$[!<2*\!;tsZ!;bgX!<2*\!<2*\
-!<)$[!<2*\!<)$[!57Ops8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!jp%X3eS8j#XSi.tXSi,!XSMqqX98O)X8o@$!<'"q!!'+t!;ikt!55K2!<'"t!;rqs!<'"r
-!;3Gk!;rqs!;*Aj!;`er!;3Gk!;`er!;rqu!;rqq!;iht!;`es!;W_q!<'"u!;`es!;rqq!;rqt
-!<'"s!;iks!<'"r!<0(s!55K6mf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!jp%O5g4=h/gAM$MgAM!OgA1gJg&qE0g&Tk+!<(XJ!!(aM!;kLM!57+`!<(XM!;tRL!<(XK
-!;5(D!;tRL!;,"C!;bFK!;5(D!;bFK!;tRN!;tRJ!;kIM!;bFL!;Y@J!<(XN!;bFL!;tRJ!;tRM
-!<(XL!;kLL!<(XK!<1^L!57+ds8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!jp%X3eVf@Jk5>;Yk5>8[k5#)Vjob\HjoFQC!<)'V!!)0Y!;kpY!57Ol!<)'Y!;u!X!<)'W
-!;5LP!;u!X!;,FO!;bjW!;5LP!;bjW!;u!Z!;u!V!;kmY!;bjX!;YdV!<)'Z!;bjX!;u!V!;u!Y
-!<)'X!;kpX!<)'W!<2-X!57Ops8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8iMXF[I(XOaKQmf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g4@t/g=G!Xs8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k(2ZGk18\ps8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8iMXF[I(XOaKQmf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g4@t/g=G!Xs8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k(2ZGk18\ps8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8iMXF[I(XOaKQmf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g4@t/g=G!Xs8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k(2ZGk18\ps8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8iMXF[I(XOaKQmf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g4@t/g=G!Xs8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k(2ZGk18\ps8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8iMXF[I(XOaKQmf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g4@t/g=G!Xs8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k(2ZGk18\ps8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8iMXF[I(XOaKQmf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g4@t/g=G!Xs8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k(2ZGk18\ps8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8jtXSr2#X8r7$r;churW)u"rW)u"q>gPsq>^MsrW)u"rW)u"q>gMrrVuu#!.h5&
-XIZHmmf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=hRgAV'Qg&V-+r;ciNrW)uPrW)uPq>gQLq>^NLrW)uPrW)uPq>gNKrVuuQ!.ijT
-g7?sts8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf@ak5G>]joGDCr;ciZrW)u\rW)u\q>gQXq>^NXrW)u\rW)u\q>gNWrVuu]!.j9`
-k+1Z7s8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8juX8i8"XT&;#X8i8!X8i8"XT&;"X8i8"X9J[+X8o?'!<0&"!<&u%!3E7%!<0&"
-!<0&+!3E7%XK2E'X8r7$rr@VOJZPEDs6fm:s+C@Op=91qs8N;RV#TT>]`<Q~>
-!<E0!johC3g4=hSg&M-PgA_0Qg&M-Og&M-PgA_0Pg&M-Pg'.Q2g&Tj\!<1[P!<(US!8?-,!<1[P
-!<1[Y!8?-,g=cP\g&V-+rr@W(J_H[Ks8W)Ps+14Mp=fOts8N;WU&X9;\c@6~>
-!<E0!johL1eVf@bjo>D\k5PG]jo>D[jo>D\k5PG\jo>D\jothJjoFQ+!<2*\!<)$_!9WDD!<2*\
-!<2*e!9WDDk2l[+joGDCrr@W4J``Ncs8W)Ks+C@Op=91qs8N;RV#TT>]`<Q~>
-!<E0!jp.^4eS8j#X8r1"!W];%qlC&'XK2E'!3E7%ri?;(XK2E'X8r7$!!)u!#QUs-!3?1%X8r7$
-#lq'.!3E7%XK2F#X8i7uXT&9OXF[IKXT._fec1:%s7Y"CKE(rUeYN6-k.LbF~>
-!<E0!jp.U6g4=h/g&V')!W^pSqq;;Ug=cP\!8?-,rn7PVg=cP\g&V-+!!)uO#QWT4!87G,g&V-+
-#lr]5!8?-,g=cQ*g&M-NgA_/(g4@tRgAh3PgAca(s7Y1HJcG`Sg7eQ/k.1PC~>
-!<E0!jp.^4eVf@JjoG>A!W_?_qrS.ak2l[+!9WDDroOCbk2l[+joGDC!!)u[#QX#L!9O:DjoGDC
-#ls,M!9WDDk2l[Bjo>DZk5PF4k(2Zjk5YJ\ec1:%s7Y"CKE(rUeYN6-k.LbF~>
-!<E0!jp.^4eS8j#X8r*u!!)nt#QUs-!3?1%X8r.!!!)nt!s#F(!<&u&!3?1%X8r.!!!)qu!!)bp
-rr@VOJZPZKs6fm:s+C@Op=91qs8N;RV#TT>]`<Q~>
-!<E0!jp.U6g4=h/g&V!'!!)oM#QWT4!87G,g&V$(!!)oM!s%'/!<(UT!87G,g&V$(!!)rN!!)cI
-rr@W(J_HpRs8W)Ps+14Mp=fOts8N;WU&X9;\c@6~>
-!<E0!jp.^4eVf@JjoG8?!!)oY#QX#L!9O:DjoG;@!!)oY!s%KG!<)$`!9O:DjoG;@!!)rZ!!)cU
-rr@W4J``cjs8W)Ks+C@Op=91qs8N;RV#TT>]`<Q~>
-!<E0!jp.^4eS8j#X8r*u!!)nt#QUs-!3E7%X8r.!!!)ntr;cet"TYX*!3?1tX8i7tXSi-MXF[IC
-XT._fec1:%s7Y"CKE(rUeYN6-k.LbF~>
-!<E0!jp.U6g4=h/g&V!'!!)oM#QWT4!8?-,g&V$(!!)oMr;cfM"T[91!87GMg&M-MgAM#&g4@tJ
-gAh3PgAca(s7Y1HJcG`Sg7eQ/k.1PC~>
-!<E0!jp.^4eVf@JjoG8?!!)oY#QX#L!9WDDjoG;@!!)oYr;cfY"T[]I!9O:Yjo>DYk5>:2k(2Zb
-k5YJ\ec1:%s7Y"CKE(rUeYN6-k.LbF~>
-!<E0!jp.^4eS8j#X8r*u!!)nt#QUs-!3E7%X8r.!!!)nt!s#F(!<&u&!3E7%X8r.!!!)bp!!%SO
-JZPEDs6fm:s+C@Op=91qs8N;RV#TT>]`<Q~>
-!<E0!jp.U6g4=h/g&V!'!!)oM#QWT4!8?-,g&V$(!!)oM!s%'/!<(UT!8?-,g&V$(!!)cI!!%T(
-J_H[Ks8W)Ps+14Mp=fOts8N;WU&X9;\c@6~>
-!<E0!jp.^4eVf@JjoG8?!!)oY#QX#L!9WDDjoG;@!!)oY!s%KG!<)$`!9WDDjoG;@!!)cU!!%T4
-J``Ncs8W)Ks+C@Op=91qs8N;RV#TT>]`<Q~>
-!<E0!jp.^4eS8j#X8r*u!!)nt!s#F(!<0)"!;iht!;iht!<&u$!3E7%riH,"qlBbtr2]kurN#u!
-JZOF(SZMkZrmh%$s8VfCs+C@O#1]OLk2s>WJ,~>
-!<E0!jp.U6g4=h/g&V!'!!)oM!s%'/!<1^P!;kIM!;kIM!<(UR!8?-,rn@APqq;#Mr7V,NrRq5O
-J_G\/S_F,Drn@C's8VfHs+14M#25dNk2s5TJ,~>
-!<E0!jp.^4eVf@JjoG8?!!)oY!s%KG!<2-\!;kmY!;kmY!<)$^!9WDDroX4\qrRkYr8mtZrT4([
-J`_OGS`]tPrmh%$s8VfCs+C@O#1]OLk2s>WJ,~>
-!<E0!johL1eS8juX8i8!X9/I(X8r4#!!*#"!!*#"rrDqt!!)nt!!)u!!s#F(!<0)"!;iht!;rqu
-!<0&"!;rqu!.h5&XJDrtmf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=hSg&M-Og&h?/g&V**!!*#P!!*#PrrDrM!!)oM!!)uO!s%'/!<1^P!;kIM!;tRN
-!<1[P!;tRN!.ijTg8*I&s8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf@bjo>D[joYVGjoGAB!!*#\!!*#\rrDrY!!)oY!!)u[!s%KG!<2-\!;kmY!;u!Z
-!<2*\!;u!Z!.j9`k+q/>s8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8jtXSi.tXSi.uXSr5!X8i8!XS`(tXSMnsXSr5!X8i8!XS`(tX8r=&rW)hsrr@VO
-JZPZKs6fm:s+C@Op=91qs8N;RV#TT>]`<Q~>
-!<E0!johC3g4=hRgAM$MgAM$NgAV*Og&M-OgACsMgA1dLgAV*Og&M-OgACsMg&V3-rW)iLrr@W(
-J_HpRs8W)Ps+14Mp=fOts8N;WU&X9;\c@6~>
-!<E0!johL1eVf@ak5>;Yk5>;Zk5GA[jo>D[k555Yk5#&Xk5GA[jo>D[k555YjoGJErW)iXrr@W4
-J``cjs8W)Ks+C@Op=91qs8N;RV#TT>]`<Q~>
-!<E0!johL1eS8iMXF[I(XOaKQmf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g4@t/g=G!Xs8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k(2ZGk18\ps8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8iMXF[I(XOaKQmf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g4@t/g=G!Xs8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k(2ZGk18\ps8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8iMXF[I(XOaKQmf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g4@t/g=G!Xs8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k(2ZGk18\ps8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8iMXF[I(XOaKQmf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g4@t/g=G!Xs8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k(2ZGk18\ps8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8iMXF[I(XOaKQmf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g4@t/g=G!Xs8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k(2ZGk18\ps8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8iMXF[I(XOaKQmf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g4@t/g=G!Xs8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k(2ZGk18\ps8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8iMXF[I(XOaKQmf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g4@t/g=G!Xs8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k(2ZGk18\ps8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8iMXF[I(XOaKQmf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g4@t/g=G!Xs8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k(2ZGk18\ps8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8iMXF[I(XOaKQmf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g4@t/g=G!Xs8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k(2ZGk18\ps8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8iMXF[I(XOaKQmf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g4@t/g=G!Xs8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k(2ZGk18\ps8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8iMXF[I(XOaKQmf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g4@t/g=G!Xs8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k(2ZGk18\ps8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8iMXF[I(XOaKQmf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g4@t/g=G!Xs8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k(2ZGk18\ps8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8iMXF[I(XOaKQmf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g4@t/g=G!Xs8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k(2ZGk18\ps8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8iMXF[I(XOaKQmf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g4@t/g=G!Xs8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k(2ZGk18\ps8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8iMXF[I(XOaKQmf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g4@t/g=G!Xs8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k(2ZGk18\ps8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8iMXF[I(XOaKQmf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g4@t/g=G!Xs8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k(2ZGk18\ps8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8iMXF[I(XOaKQmf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g4@t/g=G!Xs8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k(2ZGk18\ps8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8iMXF[I(XOaKQmf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g4@t/g=G!Xs8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k(2ZGk18\ps8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8iMXF[I(XOaKQmf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g4@t/g=G!Xs8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k(2ZGk18\ps8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8iMXF[I(XOaKQmf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g4@t/g=G!Xs8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k(2ZGk18\ps8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8jtXSr4qX8i7aX8i7`XSi.+X8i7PX8i6OXI$$gmf(c:KE(uFec1:%rs%#Ls5rIW
-!.Y~>
-!<E0!johC3g4=hRgAV*Jg&M-:g&M-9gAM#Yg&M-)g&M,(g6^Ons8LaPJcGcDgAca(rs%2Ns5rIT
-!.Y~>
-!<E0!johL1eVf@ak5GAVjo>DFjo>DEk5>:ejo>D5jo>C4k*P61s8LRKKE(uFec1:%rs%#Ls5rIW
-!.Y~>
-!<E0!johL1eS8jtX8i7qX8i7`X8i7aX8i7)X8i7bX8i7hX8i6OXI-*hmf(c:KE(uFec1:%rs%#L
-s5rIW!.Y~>
-!<E0!johC3g4=hRg&M-Jg&M-9g&M-:g&M,Wg&M-;g&M-Ag&M,(g6gUos8LaPJcGcDgAca(rs%2N
-s5rIT!.Y~>
-!<E0!johL1eVf@ajo>DVjo>DEjo>DFjo>Ccjo>DGjo>DMjo>C4k*Y<2s8LRKKE(uFec1:%rs%#L
-s5rIW!.Y~>
-!<E0!johL1eS8jtX8i7qX8i7FX8i6eX8i7hX8i6OXI-*hmf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=hRg&M-Jg&M,tg&M,>g&M-Ag&M,(g6gUos8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf@ajo>DVjo>D+jo>CJjo>DMjo>C4k*Y<2s8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8jtX8i7qX8i7tXSi.tXT&;#XT&;!XSr4sXSr2$X8i7oXSW"sXT&;#XT&;!XSi.u
-XT&8(X8i7%!!)bprr<A,!!')#!3?/#XSr4sXSr4tXS`(sXSr4sXSi.kXS`(tXT&8(X8i7%!!)u!
-!!%SOR&p>Urmh%$s8VfCs+C@O#1]OLk2s>WJ,~>
-!<E0!johC3g4=hRg&M-Jg&M-MgAM$MgA_0QgA_0OgAV*LgAV'Rg&M-HgA:mLgA_0QgA_0OgAM$N
-gA_-Vg&M-,!!)cIrr<AZ!!(^Q!87DQgAV*LgAV*MgACsLgAV*LgAM$DgACsMgA_-Vg&M-,!!)uO
-!!%T(R+hT?rn@C's8VfHs+14M#25dNk2s5TJ,~>
-!<E0!johL1eVf@ajo>DVjo>DYk5>;Yk5PG]k5PG[k5GAXk5G>^jo>DTk5,/Xk5PG]k5PG[k5>;Z
-k5PDbjo>DD!!)cUrr<Af!!)-]!9O7]k5GAXk5GAYk555Xk5GAXk5>;Pk555Yk5PDbjo>DD!!)u[
-!!%T4R-+GKrmh%$s8VfCs+C@O#1]OLk2s>WJ,~>
-!<E0!johL1eS8jtX8i7qX8i7uX8i8!X8i8!X9AU*!3E7%r2]kur2]kuriH,"o;holqQ'r&X8o?'
-!3E7%rN#u!riH,""KVS'X8qsqrr<>+!!')#XK2C%ri?)"rN#u!ri?)"ri?)"rN#u!qlBbtr2]ku
-rN#u!oW/#mqQ0\s"KVS'X8r4#!!%SOR&p>Urmh%$s8VfCs+C@O#1]OLk2s>WJ,~>
-!<E0!johC3g4=hRg&M-Jg&M-Ng&M-Og&M-Og'%K1!8?-,r7V,Nr7V,Nrn@APo@a0EqUu2Tg&Tj\
-!8?-,rRq5Orn@AP"PNhUg&Uj#rr<>Y!!(^Qg=cN,rn7>PrRq5Orn7>Prn7>PrRq5Oqq;#Mr7V,N
-rRq5Oo\'9FqV(rL"PNhUg&V**!!%T(R+hT?rn@C's8VfHs+14M#25dNk2s5TJ,~>
-!<E0!johL1eVf@ajo>DVjo>DZjo>D[jo>D[jokbI!9WDDr8mtZr8mtZroX4\oB$#QqW8%`joFQ+
-!9WDDrT4([roX4\"Qf[ajoG,;rr<>e!!)-]k2lXDroO1\rT4([roO1\roO1\rT4([qrRkYr8mtZ
-rT4([o]?,RqW@eX"Qf[ajoGAB!!%T4R-+GKrmh%$s8VfCs+C@O#1]OLk2s>WJ,~>
-!<E0!johL1eS8jtX8i7rX8i7uX8i7tX8i8"XT&:qX8i8!X8i7uX8i7lX8i7sXT&:uX8i7tX9em.
-X8o?'!3E7%p8eQ#XK2E'X8o?'!<&u!!<0&"!;ro#!3E7%p8e5opT+>poW/#mqQ'l$XK2E'X8r1"
-!!%SORB6GVrmh%$s8VfCs+C@O#1]OLk2s>WJ,~>
-!<E0!johC3g4=hRg&M-Kg&M-Ng&M-Mg&M-PgA_0Jg&M-Og&M-Ng&M-Eg&M-LgA_0Ng&M-Mg'Ic5
-g&Tj\!8?-,p=]fQg=cP\g&Tj\!<(UO!<1[P!;tOQ!8?-,p=]KHpY#TIo\'9FqUu,Rg=cP\g&V')
-!!%T(RG.]@rn@C's8VfHs+14M#25dNk2s5TJ,~>
-!<E0!johL1eVf@ajo>DWjo>DZjo>DYjo>D\k5PGVjo>D[jo>DZjo>DQjo>DXk5PGZjo>DYjp;%M
-joFQ+!9WDDp>uY]k2l[+joFQ+!<)$[!<2*\!;ts]!9WDDp>u>TpZ;GUo]?,RqW7t^k2l[+joG>A
-!!%T4RHFPLrmh%$s8VfCs+C@O#1]OLk2s>WJ,~>
-!<E0!johL1eS8jtX8i7qX8i8!X8i7tX8i8"X8i7pX8i8!X8i7uX8i7lX8i7sX8i7tX8i7tX9em.
-X8o?'!3E7%p8eQ#XK2E'X8o?'!<&u!!<0(r!<0(u!;`bs!;ikq!;*>m!;`c$!3E7%XK2F#X8i6O
-XI-*hmf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=hRg&M-Jg&M-Og&M-Mg&M-Pg&M-Ig&M-Og&M-Ng&M-Eg&M-Lg&M-Mg&M-Mg'Ic5
-g&Tj\!8?-,p=]fQg=cP\g&Tj\!<(UO!<1^K!<1^N!;bCL!;kLJ!;+tF!;bCR!8?-,g=cQ*g&M,(
-g6gUos8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf@ajo>DVjo>D[jo>DYjo>D\jo>DUjo>D[jo>DZjo>DQjo>DXjo>DYjo>DYjp;%M
-joFQ+!9WDDp>uY]k2l[+joFQ+!<)$[!<2-W!<2-Z!;bgX!;kpV!;,CR!;bg^!9WDDk2l[Bjo>C4
-k*Y<2s8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8jtX8i7qX8i8!X8i7tX8i8"X8i7pX8i8!X8i7uX8i7lX8i7sX8i7tX8i7tX9em.
-X8o?'!3E7%p8eQ#XK2E'X8o?'!<&u!!<0&"!;*>m!;iht!;rnu!<&u!!;*>m!;`c$!3E7%XK2F#
-X8i6OXI-*hmf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=hRg&M-Jg&M-Og&M-Mg&M-Pg&M-Ig&M-Og&M-Ng&M-Eg&M-Lg&M-Mg&M-Mg'Ic5
-g&Tj\!8?-,p=]fQg=cP\g&Tj\!<(UO!<1[P!;+tF!;kIM!;tON!<(UO!;+tF!;bCR!8?-,g=cQ*
-g&M,(g6gUos8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf@ajo>DVjo>D[jo>DYjo>D\jo>DUjo>D[jo>DZjo>DQjo>DXjo>DYjo>DYjp;%M
-joFQ+!9WDDp>uY]k2l[+joFQ+!<)$[!<2*\!;,CR!;kmY!;tsZ!<)$[!;,CR!;bg^!9WDDk2l[B
-jo>C4k*Y<2s8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8jtX8i7qX8i7uX8i8!X8i8!X8i7pX8i7uX8i8"XT&:lX8i7sX8i7sX8i8!X8i8"
-X9J[+X8o?'!<'#!!;ro)!3E7%XK2E'X8r4#!!)u!!!)u!!s#F(!<&u!!;iht!;rnu!<0)"!;*>m
-!<0&"!<0&(!3E7%XK2F#X8i7rXT&9OXJ2frmf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=hRg&M-Jg&M-Ng&M-Og&M-Og&M-Ig&M-Ng&M-PgA_0Eg&M-Lg&M-Lg&M-Og&M-P
-g'.Q2g&Tj\!<(XO!;tOW!8?-,g=cP\g&V**!!)uO!!)uO!s%'/!<(UO!;kIM!;tON!<1^P!;+tF
-!<1[P!<1[V!8?-,g=cQ*g&M-KgA_/(g7m=$s8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf@ajo>DVjo>DZjo>D[jo>D[jo>DUjo>DZjo>D\k5PGQjo>DXjo>DXjo>D[jo>D\
-jothJjoFQ+!<)'[!;tsc!9WDDk2l[+joGAB!!)u[!!)u[!s%KG!<)$[!;kmY!;tsZ!<2-\!;,CR
-!<2*\!<2*b!9WDDk2l[Bjo>DWk5PF4k+_#<s8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8jtX8i7qX8i7tXSi.tXSi.rXS`(sXSr2#X8qppquH\sr;c_rr;churW!,'!!')#
-!<0)"!<'"u!!B;&!3H(us/c2"rN,qtriH"tr2ferrN,tu!iuA%oW8#lriH)!"fq\(X8i8"X8i7r
-XT&9OXJ2frmf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=hRg&M-Jg&M-MgAM$MgAM$KgACsLgAV'Qg&Ug"quH]Lr;c`Kr;ciNrW!,U!!(^Q
-!<1^P!<(XN!!CpT!8@>Ns4[GPrS%2Mrn@8Mr7_&KrS%5N!nmVSo\09Ern@>O"kiqVg&M-Pg&M-K
-gA_/(g7m=$s8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf@ajo>DVjo>DYk5>;Yk5>;Wk555Xk5G>]joG):quH]Xr;c`Wr;ciZrW!,a!!)-]
-!<2-\!<)'Z!!D?`!9X1Zs5s:\rT=%YroX+Yr9!nWrT=(Z!p0I_o]H,QroX1["m,dbjo>D\jo>DW
-k5PF4k+_#<s8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8jtX8i7qX8i7UX8i7IXT&:!X8i7sXT&9OXJ)`qmf(c:KE(uFec1:%rs%#Ls5rIW
-!.Y~>
-!<E0!johC3g4=hRg&M-Jg&M-.g&M-"gA_/Og&M-LgA_/(g7d7#s8LaPJcGcDgAca(rs%2Ns5rIT
-!.Y~>
-!<E0!johL1eVf@ajo>DVjo>D:jo>D.k5PF[jo>DXk5PF4k+Ur;s8LRKKE(uFec1:%rs%#Ls5rIW
-!.Y~>
-!<E0!johL1eS8jtXSr4qX8i7WX8i7HX8i7!X8i7rX8i6OXIuZpmf(c:KE(uFec1:%rs%#Ls5rIW
-!.Y~>
-!<E0!johC3g4=hRgAV*Jg&M-0g&M-!g&M,Og&M-Kg&M,(g7[1"s8LaPJcGcDgAca(rs%2Ns5rIT
-!.Y~>
-!<E0!johL1eVf@ak5GAVjo>D<jo>D-jo>C[jo>DWjo>C4k+Ll:s8LRKKE(uFec1:%rs%#Ls5rIW
-!.Y~>
-!<E0!johL1eS8jIXSi.tXS;deXS;dHXFdPRmf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=h'gAM$Mg@tZ>g@tZ!g4J&Ys8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf@6k5>;Yk4eqJk4eq-k(;aqs8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8iMXF[I(XOaKQmf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g4@t/g=G!Xs8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k(2ZGk18\ps8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8iMXF[I(XOaKQmf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g4@t/g=G!Xs8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k(2ZGk18\ps8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8jiX8i7aX8i7%XT&:VX8i6OXF[JNXT._fec1:%s7Y"CKE(rUeYN6-k.LbF~>
-!<E0!johC3g4=hGg&M-:g&M,SgA_0/g&M,(g4@uUgAh3PgAca(s7Y1HJcG`Sg7eQ/k.1PC~>
-!<E0!johL1eVf@Vjo>DFjo>C_k5PG;jo>C4k(2[mk5YJ\ec1:%s7Y"CKE(rUeYN6-k.LbF~>
-!<E0!johL1eS8jjX8i7`X8i7bX8i7=X8i7hXSr4sXSr4rX8i6OXF[JOXT._fec1:%s7Y"CKE(rU
-eYN6-k.LbF~>
-!<E0!johC3g4=hHg&M-9g&M-;g&M,kg&M-AgAV*LgAV*Kg&M,(g4@uVgAh3PgAca(s7Y1HJcG`S
-g7eQ/k.1PC~>
-!<E0!johL1eVf@Wjo>DEjo>DGjo>D"jo>DMk5GAXk5GAWjo>C4k(2[nk5YJ\ec1:%s7Y"CKE(rU
-eYN6-k.LbF~>
-!<E0!johL1eS8jjX8i7GX8i7=X8i7fX8i7rX8i7sX8i6OXF[JOXT._fec1:%s7Y"CKE(rUeYN6-
-k.LbF~>
-!<E0!johC3g4=hHg&M,ug&M,kg&M-?g&M-Kg&M-Lg&M,(g4@uVgAh3PgAca(s7Y1HJcG`Sg7eQ/
-k.1PC~>
-!<E0!johL1eVf@Wjo>D,jo>D"jo>DKjo>DWjo>DXjo>C4k(2[nk5YJ\ec1:%s7Y"CKE(rUeYN6-
-k.LbF~>
-!<E0!johL1eS8jjX8i7tXSi.tXT&;#XT&;!XSr4sXSr2$X8i7oXS`(rXSi.lXT&8)X8i7%!!',"
-!<9/"!;3Gk!<0&#!3H/"qlKbsqQ'Ysq5aPrqQ'YsJZOF(rN-%ermh%$s8VfCs+C@O#1]OLk2s>W
-J,~>
-!<E0!johC3g4=hHg&M-MgAM$MgA_0QgA_0OgAV*LgAV'Rg&M-HgACsKgAM$EgA_-Wg&M-,!!(aP
-!<:dP!;5(D!<1[Q!8@DPqqD#LqUtoLq:YfKqUtoLJ_G\/rS%;Orn@C's8VfHs+14M#25dNk2s5T
-J,~>
-!<E0!johL1eVf@Wjo>DYk5>;Yk5PG]k5PG[k5GAXk5G>^jo>DTk555Wk5>;Qk5PDcjo>DD!!)0\
-!<;3\!;5LP!<2*]!9X7\qr[kXqW7bXq;qYWqW7bXJ`_OGrT=.[rmh%$s8VfCs+C@O#1]OLk2s>W
-J,~>
-!<E0!johL1eS8jjX8i7uX8i8!X8i8!X9AU*!3E7%r2]kur2]kuriH,"oW/#mqQ'YsrN#u!orS/n
-#HRn*X8o?'!<&u!!;3Dn!<&u!!<0)"!<0&"!<&u!!<0&"!;iht!;W\r!;`bs!.h5&XSo7#mf(c:
-KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=hHg&M-Ng&M-Og&M-Og'%K1!8?-,r7V,Nr7V,Nrn@APo\'9FqUtoLrRq5Op"KEG
-#MK.Xg&Tj\!<(UO!;5%G!<(UO!<1^P!<1[P!<(UO!<1[P!;kIM!;Y=K!;bCL!.ijTgATb*s8LaP
-JcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf@Wjo>DZjo>D[jo>D[jokbI!9WDDr8mtZr8mtZroX4\o]?,RqW7bXrT4([p#c8S
-#Nc!djoFQ+!<)$[!;5IS!<)$[!<2-\!<2*\!<)$[!<2*\!;kmY!;YaW!;bgX!.j9`k5FHBs8LRK
-KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8jkX8i7uX8i7tX8i8"XT&:qX8i8!X8i7uX8i7mX8i7tX8i7tX8i7oX9em.X8o?'
-!3E7%rN#u!orJ,nq5aPrrN#u!ri?)"r2]kur2]kuq5aPrq5aPrJZOF(riH.frmh%$s8VfCs+C@O
-#1]OLk2s>WJ,~>
-!<E0!johC3g4=hIg&M-Ng&M-Mg&M-PgA_0Jg&M-Og&M-Ng&M-Fg&M-Mg&M-Mg&M-Hg'Ic5g&Tj\
-!8?-,rRq5Op"BBGq:YfKrRq5Orn7>Pr7V,Nr7V,Nq:YfKq:YfKJ_G\/rn@DPrn@C's8VfHs+14M
-#25dNk2s5TJ,~>
-!<E0!johL1eVf@Xjo>DZjo>DYjo>D\k5PGVjo>D[jo>DZjo>DRjo>DYjo>DYjo>DTjp;%MjoFQ+
-!9WDDrT4([p#Z5Sq;qYWrT4([roO1\r8mtZr8mtZq;qYWq;qYWJ`_OGroX7\rmh%$s8VfCs+C@O
-#1]OLk2s>WJ,~>
-!<E0!johL1eS8jjX8i8!X8i7tX8i8"X8i7pX8i8!X8i7uX8i7mX8i7tX8i7tX8i7oX9J[+X8o?'
-!<0&%!3E7%o;qljrN#u!rN#u!riGqrr2]kuq5aPrqQ'YsJZOF(rN-%ermh%$s8VfCs+C@O#1]OL
-k2s>WJ,~>
-!<E0!johC3g4=hHg&M-Og&M-Mg&M-Pg&M-Ig&M-Og&M-Ng&M-Fg&M-Mg&M-Mg&M-Hg'.Q2g&Tj\
-!<1[S!8?-,o@j-CrRq5OrRq5Orn@2Kr7V,Nq:YfKqUtoLJ_G\/rS%;Orn@C's8VfHs+14M#25dN
-k2s5TJ,~>
-!<E0!johL1eVf@Wjo>D[jo>DYjo>D\jo>DUjo>D[jo>DZjo>DRjo>DYjo>DYjo>DTjothJjoFQ+
-!<2*_!9WDDoB,uOrT4([rT4([roX%Wr8mtZq;qYWqW7bXJ`_OGrT=.[rmh%$s8VfCs+C@O#1]OL
-k2s>WJ,~>
-!<E0!johL1eS8jjX8i8!X8i7tX8i8"X8i7pX8i8!X8i7uX8i7mX8i7tX8i7tX8i7oX9J[+X8o?'
-!<0&%!3E7%n#QKhri?)"rN#u!ri?)"p8e5oq5aPrqQ'YsJZOF(rN-%ermh%$s8VfCs+C@O#1]OL
-k2s>WJ,~>
-!<E0!johC3g4=hHg&M-Og&M-Mg&M-Pg&M-Ig&M-Og&M-Ng&M-Fg&M-Mg&M-Mg&M-Hg'.Q2g&Tj\
-!<1[S!8?-,n(IaArn7>PrRq5Orn7>Pp=]KHq:YfKqUtoLJ_G\/rS%;Orn@C's8VfHs+14M#25dN
-k2s5TJ,~>
-!<E0!johL1eVf@Wjo>D[jo>DYjo>D\jo>DUjo>D[jo>DZjo>DRjo>DYjo>DYjo>DTjothJjoFQ+
-!<2*_!9WDDn)aTMroO1\rT4([roO1\p>u>Tq;qYWqW7bXJ`_OGrT=.[rmh%$s8VfCs+C@O#1]OL
-k2s>WJ,~>
-!<E0!johL1eS8jjX8i7uX8i8!X8i8!X8i7pX8i7uX8i8"XT&:mX8i8"X8i8"X8i8!X8i7uXT&:u
-X9J[+X8o?'!<'#!!;!8l!<&u!!<0&"!<&u!!<&u!!<&u!!;rnu!;W\r!;`bs!;W_r!.h5,XT._f
-ec1:%s7Y"CKE(rUeYN6-k.LbF~>
-!<E0!johC3g4=hHg&M-Ng&M-Og&M-Og&M-Ig&M-Ng&M-PgA_0Fg&M-Pg&M-Pg&M-Og&M-NgA_0N
-g'.Q2g&Tj\!<(XO!;"nE!<(UO!<1[P!<(UO!<(UO!<(UO!;tON!;Y=K!;bCL!;Y@K!.ijZgAh3P
-gAca(s7Y1HJcG`Sg7eQ/k.1PC~>
-!<E0!johL1eVf@Wjo>DZjo>D[jo>D[jo>DUjo>DZjo>D\k5PGRjo>D\jo>D\jo>D[jo>DZk5PGZ
-jothJjoFQ+!<)'[!;#=Q!<)$[!<2*\!<)$[!<)$[!<)$[!;tsZ!;YaW!;bgX!;YdW!.j9fk5YJ\
-ec1:%s7Y"CKE(rUeYN6-k.LbF~>
-!<E0!johL1eS8jjX8i7tXSi.tXSi.rXS`(sXSr2#X8qjnrW)ktr;c_rrrE#!rW!,'!!')#!<&u!
-!;!;i!<0)!!<9/"!<'"t!<'"s!<'"s!;rnu!;W_r!.h5,XT._fec1:%s7Y"CKE(rUeYN6-k.LbF~>
-!<E0!johC3g4=hHg&M-MgAM$MgAM$KgACsLgAV'Qg&U`urW)lMr;c`KrrE#OrW!,U!!(^Q!<(UO
-!;"qB!<1^O!<:dP!<(XM!<(XL!<(XL!;tON!;Y@K!.ijZgAh3PgAca(s7Y1HJcG`Sg7eQ/k.1PC~>
-!<E0!johL1eVf@Wjo>DYk5>;Yk5>;Wk555Xk5G>]joG#8rW)lYr;c`WrrE#[rW!,a!!)-]!<)$[
-!;#@N!<2-[!<;3\!<)'Y!<)'X!<)'X!;tsZ!;YdW!.j9fk5YJ\ec1:%s7Y"CKE(rUeYN6-k.LbF~>
-!<E0!johL1eS8jjX8i7UX8i7[XT&:iX8i7<X8i7sXT&9OXG3hVmf(c:KE(uFec1:%rs%#Ls5rIW
-!.Y~>
-!<E0!johC3g4=hHg&M-.g&M-4gA_0Bg&M,jg&M-LgA_/(g4n>]s8LaPJcGcDgAca(rs%2Ns5rIT
-!.Y~>
-!<E0!johL1eVf@Wjo>D:jo>D@k5PGNjo>D!jo>DXk5PF4k(`$us8LRKKE(uFec1:%rs%#Ls5rIW
-!.Y~>
-!<E0!johL1eS8jiX8i7WX8i7ZX8i7hX8i7=X8i7rX8i6OXG*bUmf(c:KE(uFec1:%rs%#Ls5rIW
-!.Y~>
-!<E0!johC3g4=hGg&M-0g&M-3g&M-Ag&M,kg&M-Kg&M,(g4e8\s8LaPJcGcDgAca(rs%2Ns5rIT
-!.Y~>
-!<E0!johL1eVf@Vjo>D<jo>D?jo>DMjo>D"jo>DWjo>C4k(Vsts8LRKKE(uFec1:%rs%#Ls5rIW
-!.Y~>
-!<E0!johL1eS8jIXSi.tXS;eNXSi.tXS;dHXF[IsXT._fec1:%s7Y"CKE(rUeYN6-k.LbF~>
-!<E0!johC3g4=h'gAM$Mg@t['gAM$Mg@tZ!g4@u%gAh3PgAca(s7Y1HJcG`Sg7eQ/k.1PC~>
-!<E0!johL1eVf@6k5>;Yk4er3k5>;Yk4eq-k(2[=k5YJ\ec1:%s7Y"CKE(rUeYN6-k.LbF~>
-!<E0!johL1eS8iMXF[I(XOaKQmf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g4@t/g=G!Xs8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k(2ZGk18\ps8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8iMXF[I(XOaKQmf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g4@t/g=G!Xs8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k(2ZGk18\ps8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8jiX8i7aX8i6OXJ)]q!8adW!;NYq!:m2k!9^H`!<'"r!;rnu!;W\r!:d,j!;W_q
-!:d/jmf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=hGg&M-:g&M,(g7d4#!8cE0!;P:J!:nhD!9`)9!<(XK!;tON!;Y=K!:ebC!;Y@J
-!:eeCs8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf@Vjo>DFjo>C4k+Uo;!8ci<!;P^V!:o7P!9`ME!<)'W!;tsZ!;YaW!:f1O!;YdV
-!:f4Os8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8jjX8i7`X8i7GX8i7`X8i7`X9/I(X8r7$rW)u"rW(u[!!'p<!!)bp!!(lW!!)bp
-!!)Sk!!)5a!W];%rN#u!rN#u!rN-#!qQ0\sqQ'c!XK2F!X8i7qX8i7jXT._fec1:%s7Y"CKE(rU
-eYN6-k.LbF~>
-!<E0!johC3g4=hHg&M-9g&M,ug&M-9g&M-9g&h?/g&V-+rW)uPrW)!4!!'pj!!)cI!!(m0!!)cI
-!!)TD!!)6:!W^pSrRq5OrRq5OrS%8OqV(rLqUu#Og=cQ(g&M-Jg&M-CgAh3PgAca(s7Y1HJcG`S
-g7eQ/k.1PC~>
-!<E0!johL1eVf@Wjo>DEjo>D,jo>DEjo>DEjoYVGjoGDCrW)u\rW)!@!!'q!!!)cU!!(m<!!)cU
-!!)TP!!)6F!W_?_rT4([rT4([rT=+[qW@eXqW7k[k2l[@jo>DVjo>DOk5YJ\ec1:%s7Y"CKE(rU
-eYN6-k.LbF~>
-!<E0!johL1eS8jjX8i7,X8i7`X8i7`X9/I(X8r4#rrE&"!!)#[!!'p<!!(*A!!(ZQ!W];%poFGq
-ri?/$X8r.!!W];%qQ'c!XK2F!X8i7qX8i7jXT._fec1:%s7Y"CKE(rUeYN6-k.LbF~>
-!<E0!johC3g4=hHg&M,Zg&M-9g&M-9g&h?/g&V**rrE&P!!)$4!!'pj!!(*o!!([*!W^pSpt>]J
-rn7DRg&V$(!W^pSqUu#Og=cQ(g&M-Jg&M-CgAh3PgAca(s7Y1HJcG`Sg7eQ/k.1PC~>
-!<E0!johL1eVf@Wjo>Cfjo>DEjo>DEjoYVGjoGABrrE&\!!)$@!!'q!!!(+&!!([6!W_?_puVPV
-roO7^joG;@!W_?_qW7k[k2l[@jo>DVjo>DOk5YJ\ec1:%s7Y"CKE(rUeYN6-k.LbF~>
-!<E0!johL1eS8jjX8i7tXSi.tXT&;#XT&;!XSr4sXSr2$X8i7mXSr2#X8r7$r;churr<&#rW)nu
-quHVqrW)r!rr<&#rW)nuquHYrquHAj!s#F(!<&u&!3?1%X8r1"rW)r!rW)r!rW)\oquH\srrE)#
-rrE#!r;churr<&#rW)ktquH\sr;c_rrW!&%!3E:"!;rqt!;ikr!<0)"!!',"!;!;k!;iks!!0/$
-oW8#lqlK\qoW/,pXK2EtX8i7tX8i7rX8i7sX9/I(X8r.!!!)eq!!)Pjs6fm:s+C@Op=91qs8N;R
-V#TT>]`<Q~>
-!<E0!johC3g4=hHg&M-MgAM$MgA_0QgA_0OgAV*LgAV'Rg&M-FgAV'Qg&V-+r;ciNrr<&QrW)oN
-quHWJrW)rOrr<&QrW)oNquHZKquHBC!s%'/!<(UT!87G,g&V')rW)rOrW)rOrW)]HquH]LrrE)Q
-rrE#Or;ciNrr<&QrW)lMquH]Lr;c`KrW!&S!8?0)!;tRM!;kLK!<1^P!!(aP!;"qD!;kLL!!1dR
-o\09EqqCrJo\'BIg=cQ&g&M-Mg&M-Kg&M-Lg&h?/g&V$(!!)fJ!!)QCs8W)Ps+14Mp=fOts8N;W
-U&X9;\c@6~>
-!<E0!johL1eVf@Wjo>DYk5>;Yk5PG]k5PG[k5GAXk5G>^jo>DRk5G>]joGDCr;ciZrr<&]rW)oZ
-quHWVrW)r[rr<&]rW)oZquHZWquHBO!s%KG!<)$`!9O:DjoG>ArW)r[rW)r[rW)]TquH]XrrE)]
-rrE#[r;ciZrr<&]rW)lYquH]Xr;c`WrW!&_!9WGA!;u!Y!;kpW!<2-\!!)0\!;#@P!;kpX!!23^
-o]H,Qqr[eVo]?5Uk2l[>jo>DYjo>DWjo>DXjoYVGjoG;@!!)fV!!)QOs8W)Ks+C@Op=91qs8N;R
-V#TT>]`<Q~>
-!<E0!johL1eS8jjX8i7uX8i8!X8i8!X9AU*!3E7%r2]kur2]kuriH,"oW/#mriH,"s/Z2#rN#u!
-riH,"ri?)"rN#u!q5aPrri?)"riH,"ri?)"rN#u!qQ'YsrN#u!oW/,pXK2F#X9AU*!3E7%rN#u!
-ri?)"ri?)"r2]kuorJ,nq5ai%X8o?'!3E7%rN#u!riH,"ri?)"ri?)"rN#u!ri?)"rN#u!rN#u!
-riH,"ri?)"pT+>pr2]kurN#u!riH,"ri?)"nuMfkr2]kuriH,"nuMfkr2]kurN#u!oW/,pXK2Et
-X8i7tX8i7rX8i7sX9/I(X8r.!!!)eq!!)Pjs6fm:s+C@Op=91qs8N;RV#TT>]`<Q~>
-!<E0!johC3g4=hHg&M-Ng&M-Og&M-Og'%K1!8?-,r7V,Nr7V,Nrn@APo\'9Frn@APs4RGQrRq5O
-rn@APrn7>PrRq5Oq:YfKrn7>Prn@APrn7>PrRq5OqUtoLrRq5Oo\'BIg=cQ*g'%K1!8?-,rRq5O
-rn7>Prn7>Pr7V,Np"BBGq:Z)Sg&Tj\!8?-,rRq5Orn@APrn7>Prn7>PrRq5Orn7>PrRq5OrRq5O
-rn@APrn7>PpY#TIr7V,NrRq5Orn@APrn7>Po%F'Dr7V,Nrn@APo%F'Dr7V,NrRq5Oo\'BIg=cQ&
-g&M-Mg&M-Kg&M-Lg&h?/g&V$(!!)fJ!!)QCs8W)Ps+14Mp=fOts8N;WU&X9;\c@6~>
-!<E0!johL1eVf@Wjo>DZjo>D[jo>D[jokbI!9WDDr8mtZr8mtZroX4\o]?,RroX4\s5j:]rT4([
-roX4\roO1\rT4([q;qYWroO1\roX4\roO1\rT4([qW7bXrT4([o]?5Uk2l[BjokbI!9WDDrT4([
-roO1\roO1\r8mtZp#Z5Sq;qq_joFQ+!9WDDrT4([roX4\roO1\roO1\rT4([roO1\rT4([rT4([
-roX4\roO1\pZ;GUr8mtZrT4([roX4\roO1\o&]oPr8mtZroX4\o&]oPr8mtZrT4([o]?5Uk2l[>
-jo>DYjo>DWjo>DXjoYVGjoG;@!!)fV!!)QOs8W)Ks+C@Op=91qs8N;RV#TT>]`<Q~>
-!<E0!johL1eS8jkX8i7uX8i7tX8i8"XT&:qX8i8!X8i7uX8i7nX8i7uX9&C'!;ii"!3E7%rN#u!
-rN#u!qQ'Ysr2]u#XK2F#X8i8!X8i7sX8i7`X9AU*X8o=%ri?)"r2^2)XK2E'X8o?'!;3Dn!;W_r
-!;<Jo!<0&"!<&u!!<0&"!;*>m!<0&"!;rnu!<0&"!;EPp!<&u!!;ii"!3E7%rN#u!nuMfkrN#u!
-r2]kunuMfkr2]kun>lTiri?)"q5aPrqlBbtq5aPrn#QKhq5aPrnZ;cYrmh%$s8VfCs+C@O#1]OL
-k2s>WJ,~>
-!<E0!johC3g4=hIg&M-Ng&M-Mg&M-PgA_0Jg&M-Og&M-Ng&M-Gg&M-Ng&_9.!;kIP!8?-,rRq5O
-rRq5OqUtoLr7V5Qg=cQ*g&M-Og&M-Lg&M-9g'%K1g&Th,rn7>Pr7VGWg=cP\g&Tj\!;5%G!;Y@K
-!;>+H!<1[P!<(UO!<1[P!;+tF!<1[P!;tON!<1[P!;G1I!<(UO!;kIP!8?-,rRq5Oo%F'DrRq5O
-r7V,No%F'Dr7V,NnCdjBrn7>Pq:YfKqq;#Mq:YfKn(IaAq:YfKn_4$Crn@C's8VfHs+14M#25dN
-k2s5TJ,~>
-!<E0!johL1eVf@Xjo>DZjo>DYjo>D\k5PGVjo>D[jo>DZjo>DSjo>DZjoPPF!;km\!9WDDrT4([
-rT4([qW7bXr8n(]k2l[Bjo>D[jo>DXjo>DEjokbIjoFNDroO1\r8n:ck2l[+joFQ+!;5IS!;YdW
-!;>OT!<2*\!<)$[!<2*\!;,CR!<2*\!;tsZ!<2*\!;GUU!<)$[!;km\!9WDDrT4([o&]oPrT4([
-r8mtZo&]oPr8mtZnE']NroO1\q;qYWqrRkYq;qYWn)aTMq;qYWn`KlOrmh%$s8VfCs+C@O#1]OL
-k2s>WJ,~>
-!<E0!johL1eS8jjX8i8!X8i7tX8i8"X8i7pX8i8!X8i7uX8i7nX8i7sX8i7tX9/I(X8r4#!!)u!
-!!)ksq>gPs!!)u!!!)u!!!)hrr;c/b"TYX*!3?2"XSMqsX9J[+X8o?'!;3Dn!;W\r!;W_o!<0&"
-!<&u!!<'"t!;rqr!<0&"!;NVq!;EPp!<&u!!;ii"!3E7%rN#u!nuMfkrN#u!r2]kunuMfkqlK_r
-oW/#mri?)"qQ'YsqQ'Ysq5aPrn>lTipoFGqnZ;cYrmh%$s8VfCs+C@O#1]OLk2s>WJ,~>
-!<E0!johC3g4=hHg&M-Og&M-Mg&M-Pg&M-Ig&M-Og&M-Ng&M-Gg&M-Lg&M-Mg&h?/g&V**!!)uO
-!!)lLq>gQL!!)uO!!)uO!!)iKr;c0;"T[91!87GPgA1gLg'.Q2g&Tj\!;5%G!;Y=K!;Y@H!<1[P
-!<(UO!<(XM!;tRK!<1[P!;P7J!;G1I!<(UO!;kIP!8?-,rRq5Oo%F'DrRq5Or7V,No%F'DqqCuK
-o\'9Frn7>PqUtoLqUtoLq:YfKnCdjBpt>]Jn_4$Crn@C's8VfHs+14M#25dNk2s5TJ,~>
-!<E0!johL1eVf@Wjo>D[jo>DYjo>D\jo>DUjo>D[jo>DZjo>DSjo>DXjo>DYjoYVGjoGAB!!)u[
-!!)lXq>gQX!!)u[!!)u[!!)iWr;c0G"T[]I!9O:\k5#)XjothJjoFQ+!;5IS!;YaW!;YdT!<2*\
-!<)$[!<)'Y!;u!W!<2*\!;P[V!;GUU!<)$[!;km\!9WDDrT4([o&]oPrT4([r8mtZo&]oPqr[hW
-o]?,RroO1\qW7bXqW7bXq;qYWnE']NpuVPVn`KlOrmh%$s8VfCs+C@O#1]OLk2s>WJ,~>
-!<E0!johL1eS8jjX8i8!X8i7tX8i8"X8i7pX8i8!X8i7uX8i7nX8i7sX8i7tX9/I(X8r4#!!)u!
-!!)ks!!)hr!!)u!!!)u!!!)\n!!)Ae!!*#"rrE&"!!)eq"9>M'X8qmo!!)hr!!)ks!!)u!!!*#"
-!!)u!!!)hr!!*#"!!)u!!!*#"!!)eq!!)bp!!)u!!!)nt!s#F(!<&u!!:m2k!<&u!!;rnu!:m2k
-!;EPp!;3Gj!;iht!;`bs!;W\r!:[&i!;NVq!:d/jmf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=hHg&M-Og&M-Mg&M-Pg&M-Ig&M-Og&M-Ng&M-Gg&M-Lg&M-Mg&h?/g&V**!!)uO
-!!)lL!!)iK!!)uO!!)uO!!)]G!!)B>!!*#PrrE&P!!)fJ"9@-Ug&Ud!!!)iK!!)lL!!)uO!!*#P
-!!)uO!!)iK!!*#P!!)uO!!*#P!!)fJ!!)cI!!)uO!!)oM!s%'/!<(UO!:nhD!<(UO!;tON!:nhD
-!;G1I!;5(C!;kIM!;bCL!;Y=K!:\\B!;P7J!:eeCs8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf@Wjo>D[jo>DYjo>D\jo>DUjo>D[jo>DZjo>DSjo>DXjo>DYjoYVGjoGAB!!)u[
-!!)lX!!)iW!!)u[!!)u[!!)]S!!)BJ!!*#\rrE&\!!)fV"9@QajoG&9!!)iW!!)lX!!)u[!!*#\
-!!)u[!!)iW!!*#\!!)u[!!*#\!!)fV!!)cU!!)u[!!)oY!s%KG!<)$[!:o7P!<)$[!;tsZ!:o7P
-!;GUU!;5LO!;kmY!;bgX!;YaW!:]+N!;P[V!:f4Os8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8jjX8i7uX8i8!X8i8!X8i7pX8i7uX8i8"XT&:mX8i8!X9/I(X8r4#!!*#"!!)u!
-!!)u!!!*#"!!)u!!!)u!!s#F(!<&u!!<&u!!<0&"!<0&"!<&u!!;rqu!;!8l!<0)"!<&u!!<&u!
-!<0)"!!95%!;*>m!<0&"!<&u!!;`bs!<0)"!<0&"!<&u!!<0&"!<&u!!<0&"!<0)"!<&u!!<&u!
-!<0&"!<0&"!;iht!;rnu!<&u!!<0&"!<&u!!:m2k!;rnu!<0)"!:m2k!;rnu!<&u!!:d,j!;`bs
-!;`bs!;W\r!:[&i!;NVq!:d/jmf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=hHg&M-Ng&M-Og&M-Og&M-Ig&M-Ng&M-PgA_0Fg&M-Og&h?/g&V**!!*#P!!)uO
-!!)uO!!*#P!!)uO!!)uO!s%'/!<(UO!<(UO!<1[P!<1[P!<(UO!;tRN!;"nE!<1^P!<(UO!<(UO
-!<1^P!!:jS!;+tF!<1[P!<(UO!;bCL!<1^P!<1[P!<(UO!<1[P!<(UO!<1[P!<1^P!<(UO!<(UO
-!<1[P!<1[P!;kIM!;tON!<(UO!<1[P!<(UO!:nhD!;tON!<1^P!:nhD!;tON!<(UO!:ebC!;bCL
-!;bCL!;Y=K!:\\B!;P7J!:eeCs8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf@Wjo>DZjo>D[jo>D[jo>DUjo>DZjo>D\k5PGRjo>D[joYVGjoGAB!!*#\!!)u[
-!!)u[!!*#\!!)u[!!)u[!s%KG!<)$[!<)$[!<2*\!<2*\!<)$[!;u!Z!;#=Q!<2-\!<)$[!<)$[
-!<2-\!!;9_!;,CR!<2*\!<)$[!;bgX!<2-\!<2*\!<)$[!<2*\!<)$[!<2*\!<2-\!<)$[!<)$[
-!<2*\!<2*\!;kmY!;tsZ!<)$[!<2*\!<)$[!:o7P!;tsZ!<2-\!:o7P!;tsZ!<)$[!:f1O!;bgX
-!;bgX!;YaW!:]+N!;P[V!:f4Os8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8jjX8i7tXSi.tXSi.rXS`(sXSr2#X8qjnr;cetr;churW)u"rW)nurW)hsr;cl!
-rW)u"rW)nurW)nuquHVqrrD\mrW)r!!!)qur;cetrr<,%!!)VlrW)nur;c_rrW!&%!!',"!<9/"
-!<9.u!;rqt!!95%!<'"t!;rqt!;rqr!<'"t!<0)!!<9/"!;3Gk!<'"u!!95%!;3Gk!<0(t!:d/i
-!;iht!;rqr!<'"s!:m2k!;NVq!:d/jmf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=hHg&M-MgAM$MgAM$KgACsLgAV'Qg&U`ur;cfMr;ciNrW)uPrW)oNrW)iLr;clO
-rW)uPrW)oNrW)oNquHWJrrD]FrW)rO!!)rNr;cfMrr<,S!!)WErW)oNr;c`KrW!&S!!(aP!<:dP
-!<:dN!;tRM!!:jS!<(XM!;tRM!;tRK!<(XM!<1^O!<:dP!;5(D!<(XN!!:jS!;5(D!<1^M!:eeB
-!;kIM!;tRK!<(XL!:nhD!;P7J!:eeCs8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf@Wjo>DYk5>;Yk5>;Wk555Xk5G>]joG#8r;cfYr;ciZrW)u\rW)oZrW)iXr;cl[
-rW)u\rW)oZrW)oZquHWVrrD]RrW)r[!!)rZr;cfYrr<,_!!)WQrW)oZr;c`WrW!&_!!)0\!<;3\
-!<;3Z!;u!Y!!;9_!<)'Y!;u!Y!;u!W!<)'Y!<2-[!<;3\!;5LP!<)'Z!!;9_!;5LP!<2-Y!:f4N
-!;kmY!;u!W!<)'X!:o7P!;P[V!:f4Os8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8jjX8i7UX8i7%XT&9OXF[JOX8i7qX8i7jXT._fec1:%s7Y"CKE(rUeYN6-k.LbF~>
-!<E0!johC3g4=hHg&M-.g&M,SgA_/(g4@uVg&M-Jg&M-CgAh3PgAca(s7Y1HJcG`Sg7eQ/k.1PC~>
-!<E0!johL1eVf@Wjo>D:jo>C_k5PF4k(2[njo>DVjo>DOk5YJ\ec1:%s7Y"CKE(rUeYN6-k.LbF~>
-!<E0!johL1eS8jiX8i7WX8i7$X8i6OXF[JOX8i7rXSr4iXT._fec1:%s7Y"CKE(rUeYN6-k.LbF~>
-!<E0!johC3g4=hGg&M-0g&M,Rg&M,(g4@uVg&M-KgAV*BgAh3PgAca(s7Y1HJcG`Sg7eQ/k.1PC~>
-!<E0!johL1eVf@Vjo>D<jo>C^jo>C4k(2[njo>DWk5GANk5YJ\ec1:%s7Y"CKE(rUeYN6-k.LbF~>
-!<E0!johL1eS8jIXSi.tXS;dHXF[I=XT._fec1:%s7Y"CKE(rUeYN6-k.LbF~>
-!<E0!johC3g4=h'gAM$Mg@tZ!g4@tDgAh3PgAca(s7Y1HJcG`Sg7eQ/k.1PC~>
-!<E0!johL1eVf@6k5>;Yk4eq-k(2Z\k5YJ\ec1:%s7Y"CKE(rUeYN6-k.LbF~>
-!<E0!johL1eS8iMXF[I(XOaKQmf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g4@t/g=G!Xs8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k(2ZGk18\ps8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8iMXF[I(XOaKQmf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g4@t/g=G!Xs8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k(2ZGk18\ps8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8iMXF[I(XOaKQmf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g4@t/g=G!Xs8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k(2ZGk18\ps8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8iMXF[I(XOaKQmf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g4@t/g=G!Xs8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k(2ZGk18\ps8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8iMXF[I(XOaKQmf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g4@t/g=G!Xs8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k(2ZGk18\ps8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8iMXF[I(XOaKQmf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g4@t/g=G!Xs8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k(2ZGk18\ps8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8iMXF[I(XOaKQmf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g4@t/g=G!Xs8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k(2ZGk18\ps8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8iMXF[I(XOaKQmf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g4@t/g=G!Xs8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k(2ZGk18\ps8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8iMXF[I(XOaKQmf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g4@t/g=G!Xs8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k(2ZGk18\ps8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8iMXF[I(XOaKQmf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g4@t/g=G!Xs8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k(2ZGk18\ps8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8iMXF[I(XOaKQmf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g4@t/g=G!Xs8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k(2ZGk18\ps8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8iMXF[I(XOaKQmf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g4@t/g=G!Xs8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k(2ZGk18\ps8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8iMXF[I(XOaKQmf(c:KE(uDKE(rUeYN6-k.LbF~>
-!<E0!johC3g4=g+g4@t/g=G!Xs8LaPJcGcBJcG`Sg7eQ/k.1PC~>
-!<E0!johL1eVf?:k(2ZGk18\ps8LRKKE(uDKE(rUeYN6-k.LbF~>
-!<E0!johL1eS8iMXF[I(XOaKQmf(c:K)krCKE(rUeYN6-k.LbF~>
-!<E0!johC3g4=g+g4@t/g=G!Xs8LaPJH5`AJcG`Sg7eQ/k.1PC~>
-!<E0!johL1eVf?:k(2ZGk18\ps8LRKK)krCKE(rUeYN6-k.LbF~>
-!<E0!johL1eS8iMXF[I(XOaKQmf(c:KCZ_Urs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g4@t/g=G!Xs8LaPJb$\Xrs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k(2ZGk18\ps8LRKKCZ_Urs%#Ls5rIW!.Y~>
-!<E0!johL1eS8iMXF[I(XOaKQmf(c:KCJmFeYN6-k.LbF~>
-!<E0!johC3g4=g+g4@t/g=G!Xs8LaPJai[Dg7eQ/k.1PC~>
-!<E0!johL1eVf?:k(2ZGk18\ps8LRKKCJmFeYN6-k.LbF~>
-!<E0!johL1eS8iMXF[I(XOaKQmf(c:K)iUWrs=>Xs4*qFk2s>WJ,~>
-!<E0!johC3g4=g+g4@t/g=G!Xs8LaPJH3RZrs=8Vs4X1Hk2s5TJ,~>
-!<E0!johL1eVf?:k(2ZGk18\ps8LRKK)iUWrs=>Xs4*qFk2s>WJ,~>
-!<E0!johL1eS8iMXF[I(XOaKQmf(c:K*&ads7k.EK*f6ks4*qFk2s>WJ,~>
-!<E0!johC3g4=g+g4@t/g=G!Xs8LaPJHE^gs7k=JJI03ns4X1Hk2s5TJ,~>
-!<E0!johL1eVf?:k(2ZGk18\ps8LRKK*&ads7k.EK*f6ks4*qFk2s>WJ,~>
-!<E0!johL1eS8iMXF[I(XOaKQmf(c:KE&Xbs7t4FK*f6ks4*qFk2s>WJ,~>
-!<E0!johC3g4=g+g4@t/g=G!Xs8LaPJcEUes7tCKJI03ns4X1Hk2s5TJ,~>
-!<E0!johL1eVf?:k(2ZGk18\ps8LRKKE&Xbs7t4FK*f6ks4*qFk2s>WJ,~>
-!<E0!johL1eS8iMXF[I(XOaKQmf(c:KE&Xbs8(:GKE&Xbrs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g4@t/g=G!Xs8LaPJcEUes8(ILJcEUers%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k(2ZGk18\ps8LRKKE&Xbs8(:GKE&Xbrs%#Ls5rIW!.Y~>
-!<E0!johL1eS8iMXF[I(XOaKQmf(c:KDrRas81@HKE&Xbrs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g4@t/g=G!Xs8LaPJc<Ods81OMJcEUers%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k(2ZGk18\ps8LRKKDrRas81@HKE&Xbrs%#Ls5rIW!.Y~>
-!<E0!johL1eS8iMXF[I(XOaKQmf(c:KDrRas8:FIKDrRars%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g4@t/g=G!Xs8LaPJc<Ods8:UNJc<Odrs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k(2ZGk18\ps8LRKKDrRas8:FIKDrRars%#Ls5rIW!.Y~>
-!<E0!johL1eS8iMXF[I(XOaKQmf(c:KDiL`s8CLJKDrRars%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g4@t/g=G!Xs8LaPJc3Ics8C[OJc<Odrs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k(2ZGk18\ps8LRKKDiL`s8CLJKDrRars%#Ls5rIW!.Y~>
-!<E0!johL1eS8iMXF[I(XOaKQmf(c:KDiL`s8LRKKDiL`rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g4@t/g=G!Xs8LaPJc3Ics8LaPJc3Icrs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k(2ZGk18\ps8LRKKDiL`s8LRKKDiL`rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8iMXF[I(XOaKQmf(c:KD`F_s8UXLKDiL`rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g4@t/g=G!Xs8LaPJc*Cbs8UgQJc3Icrs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k(2ZGk18\ps8LRKKD`F_s8UXLKDiL`rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8iMXF[I(XOaKQmf(c:KD`F_rrU`'KD`F_rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g4@t/g=G!Xs8LaPJc*CbrrUo*Jc*Cbrs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k(2ZGk18\ps8LRKKD`F_rrU`'KD`F_rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8iMXF[I(XOaKQmf(c:KDW=^s8IZK^&S*:eYN6-k.LbF~>
-!<E0!johC3g4=g+g4@t/g=G!Xs8LaPJc!:as8ITI_Z0W?g7eQ/k.1PC~>
-!<E0!johL1eVf?:k(2ZGk18\ps8LRKKDW=^s8IZK^&S*:eYN6-k.LbF~>
-!<E0!johL1eS8iMXF[I(XOaKQmf(c:KDW=`s+>t$^&S*:eYN6-k.LbF~>
-!<E0!johC3g4=g+g4@t/g=G!Xs8LaPJc!:cs+,au_Z0W?g7eQ/k.1PC~>
-!<E0!johL1eVf?:k(2ZGk18\ps8LRKKDW=`s+>t$^&S*:eYN6-k.LbF~>
-!<E0!johL1eS8iMXF[I(XOaKQmf(c:KDN:]KDW@^rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g4@t/g=G!Xs8LaPJbm7`Jc!=ars%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k(2ZGk18\ps8LRKKDN:]KDW@^rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8iMmXaeWmaU\(ec19u]`<]]^&S*:eYN6-k.LbF~>
-!<E0!johC3g4=g+s+13$s4%)JgAca#_>o/`_Z0W?g7eQ/k.1PC~>
-!<E0!johL1eVf?:s+13$s4%)Jec19u]`<]]^&S*:eYN6-k.LbF~>
-!<E0!jo_F0eS9['JaS*We*d4cs+Bh@#1]OLk2s>WJ,~>
-!<E0!jo_=2g4=hTJcC<$e,TF$s+0\>#25dNk2s5TJ,~>
-!<E0!jo_F0eVf"YJcC<$e,TEts+Bh@#1]OLk2s>WJ,~>
-!<E0!joD3.eUc8%e]lVEKCAgEeYN6-k.LbF~>
-!<E0!joD*+g4@t/g<J=OJa`UCg7eQ/k.1PC~>
-!<E0!joD3.eUc8%e]lVEKCAgEeYN6-k.LbF~>
-!<E0!joD3.eUc8%e[a36V#TT>]`<Q~>
-!<E0!joD*+g4@t/g:>o@U&X9;\c@6~>
-!<E0!joD3.eUc8%e[a36V#TT>]`<Q~>
-!<E0!joD3.eUc8%e[a36V#TT>]`<Q~>
-!<E0!joD*+g4@t/g:>o@U&X9;\c@6~>
-!<E0!joD3.eUc8%e[a36V#TT>]`<Q~>
-!<E0!joM:.JV/N+JV2=%ldZ07s5rIW!.Y~>
-!<E0!joM10JUrB'JUu1!le2N9s5rIT!.Y~>
-!<E0!joM:.JV/N+JV2=%ldZ07s5rIW!.Y~>
-!<E0!joM:.JV/N+JV2@&!<;B8"f21\k.LbF~>
-!<E0!joM10JUrB'JUu4"!<;B="ektYk.1PC~>
-!<E0!joM:.JV/N+JV2@&!<;B8"f21\k.LbF~>
-!<E0!jo_F0K7id/!WTias+13$s7H<m^&S-)^&S,ueHMcKk2s>WJ,~>
-!<E0!jo_=2JV!F0!WU#fs+13$s7H<m_Z0Z._Z0Z%g'+2Mk2s5TJ,~>
-!<E0!jo_F0K7id/!WTias+13$s7H<m^&S-)^&S,ueHMcKk2s>WJ,~>
-!<E0!jo_F0K7ij1s8N+P]n-37s+14CrrIbcrVuT)s8VE8"f21\k.LbF~>
-!<E0!jo_=2JV!L2s8N+N_L_`<s+14CrrI\frVuT.s8VE="ektYk.1PC~>
-!<E0!jo_F0K7ij1s8N+P]n-37s+14CrrIbcrVuT)s8VE8"f21\k.LbF~>
-!<Bh3S-%5nKD3(Ys8R]Q^&S+`eUc8%ebI\pK)iU^s7j;-s6J2=S@tG_!!%N~>
-!<B_0R0))nJbR%\s8RWO_Z0Xeg4@t/gA'D%JH3Ras7jJ2s6JABRC\fS!!%N~>
-!<Bh3S-%5nKD3(Ys8R]Q^&S+`eUc8%ebI\pK)iU^s7j;-s6J2=S@tG_!!%N~>
-!!)uB".[noKDE4Zrrpr*K>%<bJ^o>%J^sPGs+:Hfs8UX"rVu`-s8VE8"e<iN]po(Q~>
-!!)u?".@koJbd1]rrq,-J\qHeJ_G\/J_KnQs+(<is8Ug,rVu`2s8VE="e!NE\sWPK~>
-!!)uB".[noKDE4Zrrpr*K>%<bJ^o>%J^sPGs+:Hfs8UX"rVu`-s8VE8"e<iN]po(Q~>
-!<CCD]`XeTK7j'7rVulIs+:Bds8RZ#J^o>%psoCs!knX6rRLlHr4W.1ldZ0/c+Uf\!.Y~>
-!<C:A\c\ASJV!^8rVulNs+(6gs8RZ(J_G\/ptGb!!lG!;rS%5Mr5/L6le2N1b.>0P!.Y~>
-!<CCD]`XeTK7j'7rVulIs+:Bds8RZ#J^o>%psoCs!knX6rRLlHr4W.1ldZ0/c+Uf\!.Y~>
-!<CCD]`XeTK7j-9rVufGs+:Bds8RZ#J^o>%psoCs!knX6qpkZFrk8@3ldZ0/c+Uf\!.Y~>
-!<C:A\c\ASJV!d:rVufLs+(6gs8RZ(J_G\/ptGb!!lG!;qqD#Krke^8le2N1b.>0P!.Y~>
-!<CCD]`XeTK7j-9rVufGs+:Bds8RZ#J^o>%psoCs!knX6qpkZFrk8@3ldZ0/c+Uf\!.Y~>
-!<CCD]`jqVK7gkNrVu`Es+:Bds8RZ#J^o>%psoCs!knX6q:5HD!knX6ldZ0/c+Uf\!.Y~>
-!<C:A\cnMUJUt\TrVu`Js+(6gs8RZ(J_G\/ptGb!!lG!;q:bfI!lG!;le2N1b.>0P!.Y~>
-!<CCD]`jqVK7gkNrVu`Es+:Bds8RZ#J^o>%psoCs!knX6q:5HD!knX6ldZ0/c+Uf\!.Y~>
-!<CCD]`FYRqh+[os+:Bds8RZ#J^o>%psoCs!knX6pso=qs8VE8"e<iN]po(Q~>
-!<C:A\cJ5QqgnOrs+(6gs8RZ(J_G\/ptGb!!lG!;ptG[ts8VE="e!NE\sWPK~>
-!<CCD]`FYRqh+[os+:Bds8RZ#J^o>%psoCs!knX6pso=qs8VE8"e<iN]po(Q~>
-!<CCD]`jqVK7gkNrIasss+:Bds8RZ#J^o>%psoCs!knX6q:5Fr!knX6ldZ0/c+Uf\!.Y~>
-!<C:A\cnMUJUt\TrIOh!s+(6gs8RZ(J_G\/ptGb!!lG!;q:bdu!lG!;le2N1b.>0P!.Y~>
-!<CCD]`jqVK7gkNrIasss+:Bds8RZ#J^o>%psoCs!knX6q:5Fr!knX6ldZ0/c+Uf\!.Y~>
-!<CCD]`XeTK7j-9rIb$us+:Bds8RZ#J^o>%psoCs!knX6qpkXtrk8@3ldZ0/c+Uf\!.Y~>
-!<C:A\c\ASJV!d:rIOn#s+(6gs8RZ(J_G\/ptGb!!lG!;qqD""rke^8le2N1b.>0P!.Y~>
-!<CCD]`XeTK7j-9rIb$us+:Bds8RZ#J^o>%psoCs!knX6qpkXtrk8@3ldZ0/c+Uf\!.Y~>
-!<CCD]`XeTK7j'7rIb+"s+:Bds8RZ#J^o>%psoCs!knX6rRLk!r4W.1ldZ0/c+Uf\!.Y~>
-!<C:A\c\ASJV!^8rIOt%s+(6gs8RZ(J_G\/ptGb!!lG!;rS%4$r5/L6le2N1b.>0P!.Y~>
-!<CCD]`XeTK7j'7rIb+"s+:Bds8RZ#J^o>%psoCs!knX6rRLk!r4W.1ldZ0/c+Uf\!.Y~>
-!<CCD]`XeTK7j!5rIY:(K7gl;s+/^OeUc9Gec17)^&S,_ebt-s^&S,ueHMJf]tKp9J,~>
-!<C:A\c\ASJV!X6rIG.+JUt]<s+/mTg4@uQgAc^,_Z0YigAQU!_Z0Z%g'*ne]"4:0J,~>
-!<CCD]`XeTK7j!5rIY:(K7gl;s+/^OeUc9Gec17)^&S,_ebt-s^&S,ueHMJf]tKp9J,~>
-!<CCD]`XeTK7ip3r.>'as8RZ#J^o>%psoCs!knX6rIamYs8VE8"e<iN]po(Q~>
-!<C:A\c\ASJV!R4r.+pds8RZ(J_G\/ptGb!!lG!;rIOa\s8VE="e!NE\sWPK~>
-!<CCD]`XeTK7ip3r.>'as8RZ#J^o>%psoCs!knX6rIamYs8VE8"e<iN]po(Q~>
-!<CCD]`XeTK7ij1rdt9cs8RY&JV/N+p4EL]s8R_(p:^M+ldZ0/c+Uf\!.Y~>
-!<C:A\c\ASJV!L2rdb-fs8RY$JUrB'p43@`s8RY$p;6k0le2N1b.>0P!.Y~>
-!<CCD]`XeTK7ij1rdt9cs8RY&JV/N+p4EL]s8R_(p:^M+ldZ0/c+Uf\!.Y~>
-!<CCD]`XeTK7id/!e\2dJV/N+JV3WJ!knVdoY(;)ldZ0/c+Uf\!.Y~>
-!<C:A\c\ASJV!F0!eJ5gJUrB'JV!KF!lFtgoYUY.le2N1b.>0P!.Y~>
-!<CCD]`XeTK7id/!e\2dJV/N+JV3WJ!knVdoY(;)ldZ0/c+Uf\!.Y~>
-!<CCD]`XeTK7eaTJcC<$df8X`"e<iN]po(Q~>
-!<C:A\c\ASJUrCPJcC<$df8Xe"e!NE\sWPK~>
-!<CCD]`XeTK7eaTJcC<$df8X`"e<iN]po(Q~>
-!<CCD]`O_SK7X&Rs+13ts6J2=SB\a\S,e'~>
-!<C:A\cS;RJV!iPs+13ts6JABREE+PR/ha~>
-!<CCD]`O_SK7X&Rs+13ts6J2=SB\a\S,e'~>
-!<CCD]`=RReUc8%e[a36SB\a\S,e'~>
-!<C:A\cA.Lg4@t/g:>o@REE+PR/ha~>
-!<CCD]`=RReUc8%e[a36SB\a\S,e'~>
-!<CCC^%%VDUk,=mUtMOD^%.Znc2PBWS,e'~>
-!<C:@]()2>Tn/ngU"Q+>](26hb5SsQR/ha~>
-!<CCC^%%VDUk,=mUtMOD^%.Znc2PBWS,e'~>
-!]^8*rOqgI!53s`JcC<$g&LTerk/B'!7cT~>
-!^m%2rOVUC!4ma]JcC<$g&LTbrji0!!8;r~>
-!cn@drOqgI!53s`JcC<$g&LTerk/B'!7cT~>
-!\j]"n%A^kJ`_OGJ`bYJ!6suG!h98@J,~>
-!^m%2n%&LeJ`_OGJ`bYJ!6XcA!gs&BJ,~>
-!bq_[n%A^kJ`_OGJ`bYJ!6suG!h98@J,~>
-s#C,\S=K,_!1\W&J`_OGg#`:Zn\+sm!W^d$J,~>
-s$QngR@3TV!1AE#J`_OGg#`:Wn[eag!W^s.J,~>
-s)S5AS=K,_!1\W&J`_OGg#`:Zn\+sm!W^d$J,~>
-r\=EQn=5'CJ\?WJfY-gFrrE&KJ,~>
-r^?bdn<nj=J\$EDfXgU@rrE&PJ,~>
-rcA)>n=5'CJ\?WJfY-gFrrE&KJ,~>
-r](!63Iq0]!.b-Z!<:RNs4,YM~>
-r'Z)9JH16$[fHH^!W^s.J,~>
-r,[DhJH16$[fHHY!W^d$J,~>
-%%EndData
-showpage
-%%Trailer
-end
-%%EOF
diff --git a/lib/et/doc/src/sim_trans_mgr_actors.gif b/lib/et/doc/src/sim_trans_mgr_actors.gif
deleted file mode 100644
index b954a45bba..0000000000
--- a/lib/et/doc/src/sim_trans_mgr_actors.gif
+++ /dev/null
Binary files differ
diff --git a/lib/et/doc/src/sim_trans_mgr_actors.png b/lib/et/doc/src/sim_trans_mgr_actors.png
new file mode 100644
index 0000000000..e42e82adad
--- /dev/null
+++ b/lib/et/doc/src/sim_trans_mgr_actors.png
Binary files differ
diff --git a/lib/et/doc/src/sim_trans_mgr_actors.ps b/lib/et/doc/src/sim_trans_mgr_actors.ps
deleted file mode 100644
index 9bfa4ab544..0000000000
--- a/lib/et/doc/src/sim_trans_mgr_actors.ps
+++ /dev/null
@@ -1,1705 +0,0 @@
-%!PS-Adobe-3.0 EPSF-3.0
-%%Creator: GIMP PostScript file plugin V 1.12 by Peter Kirchgessner
-%%Title: /home/hakan/picts/sim_trans_mgr_actors.ps
-%%CreationDate: Mon Oct 14 17:07:53 2002
-%%DocumentData: Clean7Bit
-%%LanguageLevel: 2
-%%Pages: 1
-%%BoundingBox: 14 14 443 371
-%%EndComments
-%%BeginProlog
-% Use own dictionary to avoid conflicts
-10 dict begin
-%%EndProlog
-%%Page: 1 1
-% Translate for offset
-14.173228 14.173228 translate
-% Translate to begin of first scanline
-0.000000 356.135581 translate
-428.031496 -356.135581 scale
-% Image geometry
-512 426 8
-% Transformation matrix
-[ 512 0 0 426 0 0 ]
-% Strings to hold RGB-samples per scanline
-/rstr 512 string def
-/gstr 512 string def
-/bstr 512 string def
-{currentfile /ASCII85Decode filter /RunLengthDecode filter rstr readstring pop}
-{currentfile /ASCII85Decode filter /RunLengthDecode filter gstr readstring pop}
-{currentfile /ASCII85Decode filter /RunLengthDecode filter bstr readstring pop}
-true 3
-%%BeginData: 92674 ASCII Bytes
-colorimage
-r.BP#JH16$MZE\TJ,~>
-r.0D!JH16$MZE\TJ,~>
-r.BP#JH16$MZE\TJ,~>
-rk8=3nc&U&JcC<$JcF@%!56GQquD6~>
-rke[8nc&U'JcC<$JcF@%!5?MRquD6~>
-rk8=3nc&U&JcC<$JcF@%!56GQquD6~>
-s1JI6s8VWG!53s6J^o>%f@9l7a56ja!W`9#J,~>
-s2"g;s8VWC!5=$8J_#D'f@Br9a4gR]!W`9#J,~>
-s1JI6s8VWG!53s6J^o>%f@9l7a56ja!W`9#J,~>
-!keU6n(n&XJ^o>%J^rB&!56A.!lY0>J,~>
-!l=s;n(IcUJ_#D'J_&H(!5?G+!l=s;J,~>
-!keU6n(n&XJ^o>%J^rB&!56A.!lY0>J,~>
-!keU6n(n&X\((JtJ^o>%U=B7W`SL[8!<7Q~>
-!l=s;n(IcU\(1T&dXfu#et^dr^;\e-_>sUd~>
-!keU6n(n&X\((JtJ^o>%U=B7W`SL[8!<7Q~>
-!<E/fh>k7Kec1lieHNpfe\-<VrfmH5!J>`neH)JZJ^oY.!57RPpRLp5s.'&Es.'#D!NZ9O~>
-!<E/fg&SkHf)LlgedTEhf"Q]`R?<W_eq&CHecDJYJ_#_0!5@XMpR1^.s-`i>s-`f=!NlEQ~>
-!<E/fh>k7Kec1lieHNpfe\-<VrfmH5!J>`neH)JZJ^oY.!57RPpRLp5s.'&Es.'#D!NZ9O~>
-!<E/thZ',ChZ',Eh>k7]eH*Y&n^[Z(hUN4WHaM=]Hc=O"Ph"<:He$Zc]tMqs`P(Wg!jm<nJ^o\/
-!57RPpRLs6rLEoErLEiC!NZ9O~>
-!<E/tf)M08f)M0:ec<GVdK.4nn^@H"hU3"QJ[X!dIE'QpOj_[/J^Vu`[_:)i_RAgZ!k*NkJ^TJ)
-!5@XIpR1a+rL*]:rL*W8!NlEQ~>
-!<E/thZ',ChZ',Eh>k7]eH*Y&n^[Z(hUN4WHaM=]Hc=O"Ph"<:He$Zc]tMqs`P(Wg!jm<nJ^o\/
-!57RPpRLs6rLEoErLEiC!NZ9O~>
-!<E/uhYiuChYiuDh>k7]eH(;LbgclTPh"<:Hi)=sK6u/!K6t;^!J>abeH(nmJ^o\/!57RPpRLs6
-pRM3=!NZ9O~>
-!<E/uf);$8f);$9ec<GVdf4mBdKPJmdaE\tqpPLqs3gpu^!cq3ld>g!M1O*5dK%#Ef(YU+f(YU2
-ecDoRJ,~>
-!<E/uhYiuChYiuDh>k7]eH(;LbgclTPh"<:Hi)=sK6u/!K6t;^!J>abeH(nmJ^o\/!57RPpRLs6
-pRM3=!NZ9O~>
-!<E/uhY`oDhY`oCh>k7deHX!NH\8]UV#G]@`V\15S9qs"eZ=DRK6u/!`J](q[+27)`RUK*`RUKS
-e]!GnK='1ZMi4ZprRD%aHbIt"rd+pqK6u/!K6u.Erd4[a%#]Ib[+3]bMl_ieK7!LGs,.8uK6su4
-K6suUe]!dOHiMXrMZKo;qUH(pP^@b8`RWM?MgKf/c(t>c"i[R$H],!)ec1O9XGbWJMgKf'^"'fC
-]n+^meH!;GhY3Q5hYE]>h>s\XJ,~>
-!<E/uf)1s9f)1s8ec<G]dK[RNI>+uTU&KH?_Y_b/R=2Zpd\VZGJUu7t_NB8#ZI5b$_U=j#_U=jG
-d__,pKsK.TNK'corR(h[ICdjprd>'pJUu7tJUu7CrdFg`%$>slZI70\NMVW_JV!^Hs,@DpKn6D8
-Kn6PXd__.FIK.aqN<,l8qU,knOb%q?^=(H4M1'f/b+\f_"i@F!I>P-+df5:8V2`p?Ob%q7[aMU4
-\q/:gdK%#Ef(YU*f(ka3ecDoRJ,~>
-!<E/uhY`oDhY`oCh>k7deHX!NH\8]UV#G]@`V\15S9qs"eZ=DRK6u/!`J](q[+27)`RUK*`RUKS
-e]!GnK='1ZMi4ZprRD%aHbIt"rd+pqK6u/!K6u.Erd4[a%#]Ib[+3]bMl_ieK7!LGs,.8uK6su4
-K6suUe]!dOHiMXrMZKo;qUH(pP^@b8`RWM?MgKf/c(t>c"i[R$H],!)ec1O9XGbWJMgKf'^"'fC
-]n+^meH!;GhY3Q5hYE]>h>s\XJ,~>
-!<E/teb>U4eH!;\bmMFBK>!Lr`Pm1N^&#u$[!S%^c%Dh:K6tk^K7gk%Hc<[FXNcBEXNcC)`IifV
-P^CBoK6rNPrQQOVHc=7KH[EHNK6tkfK6tk^H[EHFK7gk%Hc=6^H]+]EMhCoO(P@'mS9oU@S9on5
-c%CYfc%CAfc%CA$V#&=b]r\oSH]-.EH],8<UrC<"HbH5%PeE<.XNf"BH]+]EMgMhE[(X`'H^oZ3
-N6M@9kLBR&q:,J8o[Wi/qpb_K!.Y~>
-!<E/tdeB1.dK%#Zc3h^FKt<Ot`l<RX_YVP*[XFRhcAACCJUu+hJVC\#IE&jHWm6<HWm61(b(58X
-Q$pZtJUNBOrQZU\IE'RPJUPD\JUu+lJUu+dJUPDTJVC\#IE'Q`I>OfGM2D,T(P.!oTm_?KTm_X?
-b(58`c@p\lc@LD#V>AId^952YI>Q7GI>P8<WlE&0IDW"4Q+iN3Wm8n@I>OfGM1)hH[_C&,IA)5;
-N6VF;kL'?uq9f82o[<W)qpGMJ!.Y~>
-!<E/teb>U4eH!;\bmMFBK>!Lr`Pm1N^&#u$[!S%^c%Dh:K6tk^K7gk%Hc<[FXNcBEXNcC)`IifV
-P^CBoK6rNPrQQOVHc=7KH[EHNK6tkfK6tk^H[EHFK7gk%Hc=6^H]+]EMhCoO(P@'mS9oU@S9on5
-c%CYfc%CAfc%CA$V#&=b]r\oSH]-.EH],8<UrC<"HbH5%PeE<.XNf"BH]+]EMgMhE[(X`'H^oZ3
-N6M@9kLBR&q:,J8o[Wi/qpb_K!.Y~>
-!<E/sebPa5eH!;\bmCIuSB\-^XNcBEprt(:Hd06N`Qa$^c)c8^c)c8nc$P\oH\7QrHd/X=SB\-^
-XNcBEqoo/+HiD8,K6tkfK6tkfK6tkfK6tkEH^r?^H`YJEHhP]!K6tS^H[E`VH[F#=H^r@*K6tkf
-K7!=:#K=B/K?]$q`VdsiK6tjqHc=7KH\9SfK7!UB",hMr^&?1VH^'*+N6M@9kLBR&q:,J8o[Wi/
-qpb_K!.Y~>
-!<E/sdeT=/dK%#Zc3^Y%TusNdY0MTLps/nj,Kd`K_Tm^`cE;Shb-$/qc@(ttI>+*+IEJ^@TusNd
-Y0MTHb5BNcQ$rYWs+13qs+13qs+13qs+(R'Y'm"dY'mIuJUP]8c5(tZb0GQdb0GQhcE_khcH_,l
-cH^uhb4j0d_S1STc@p\`r6G=n'$c>^`m2SPM9aCtIEKj\M1(r3rQYFlQ%@5>c2bTAdK#^2dK#^-
-defI0dK-KNJ,~>
-!<E/sebPa5eH!;\bmCIuSB\-^XNcBEprt(:Hd06N`Qa$^c)c8^c)c8nc$P\oH\7QrHd/X=SB\-^
-XNcBEqoo/+HiD8,K6tkfK6tkfK6tkfK6tkEH^r?^H`YJEHhP]!K6tS^H[E`VH[F#=H^r@*K6tkf
-K7!=:#K=B/K?]$q`VdsiK6tjqHc=7KH\9SfK7!UB",hMr^&?1VH^'*+N6M@9kLBR&q:,J8o[Wi/
-qpb_K!.Y~>
-!<E/rebbm6eH!;\blFR;HNU(gK7!C<$ClIES;YY:K6tk=r-JgIc&74UPa$g%Mp8'qHNU(gK7!L?
-!L.s1bn#GRc-:lfc-:lfc-:lfc(t8a"/O1oHhP]!K6tkfK6tkfK6tk=H_ep2K6tkfK7!C<#ebkC
-MgL*$H[GY7"G;'GH[Gb:s*Odj!J>aubmD@RH[C[ac-:U"J^'.u!58<\!582u!58*V!1`l8!1``4
-q4.B5!NZ9O~>
-!<E/rdefI0dK%#Zc2a^=I06=kJV!UA$CuUJSW1q?JUu+Cr-\sLcB3[\OdUp'NR"BuI06=kJV!^D
-!L8*4cMrIqcMrIqcMrIqcMrFrcDCGe"/X:oJbIChJcF$qJcF$qJIBc"IA+s3Kmh7lJV!UA#eG_@
-NI?N+I=;"<s+(6sJUROCs*apms+10p$,VsUI>ttdc@(t/cA^$K^AQCZ](q`o](XPPRJG82RJ##(
-RJbJ6XoNt~>
-!<E/rebbm6eH!;\blFR;HNU(gK7!C<$ClIES;YY:K6tk=r-JgIc&74UPa$g%Mp8'qHNU(gK7!L?
-!L.s1bn#GRc-:lfc-:lfc-:lfc(t8a"/O1oHhP]!K6tkfK6tkfK6tk=H_ep2K6tkfK7!C<#ebkC
-MgL*$H[GY7"G;'GH[Gb:s*Odj!J>aubmD@RH[C[ac-:U"J^'.u!58<\!582u!58*V!1`l8!1``4
-q4.B5!NZ9O~>
-!<E/qebu$7eH!;\blXtnSG^V4K7!C<%)%"GK<3>BK6tkEH^t#Y$`&--Uo\p$Us5ufSG^V4K7!L?
-(8Q;rc-:lfc-:lfc-:lfc-:lfc)c8^r657pHhP]!K6tkfK6tkfK6tkEH^r@*H[F#^K7!C<$&a/T
-c%CYnK6t<0bmf;Pc%CA^c,G$^c-:lfr65JcUjIa=`I",+c&BmI^&6FTSG(J5SGC\8SG(M-SGgt=
-X8mb~>
-!<E/qdf#U1dK%#Zc2t.sU&<49Jb[M!\p]QhWm8n@J^1EHU&<1DTm_osWdTl#cE;Shr6G=nqp#tN
-IE'RXJUu+lJUu+lJUu+lJUu+LIA-Sas+0mhs+13qs+13qs+(R'Y'l_`b(4udc@LQAc3]J]b0G]p
-c@p\\r6G=n$dOTW`m2SPM9aCtJc*du`h@g7cGk:+J^05"!5ABZpR1a'!1EZ2!1EQ/pR2!.!NlEQ~>
-!<E/qebu$7eH!;\blXtnSG^V4K7!C<%)%"GK<3>BK6tkEH^t#Y$`&--Uo\p$Us5ufSG^V4K7!L?
-(8Q;rc-:lfc-:lfc-:lfc-:lfc)c8^r657pHhP]!K6tkfK6tkfK6tkEH^r@*H[F#^K7!C<$&a/T
-c%CYnK6t<0bmf;Pc%CA^c,G$^c-:lfr65JcUjIa=`I",+c&BmI^&6FTSG(J5SGC\8SG(M-SGgt=
-X8mb~>
-!<E/pec208eH!;[bmB#LUpR51c%CAMprt%9H[E`Vc%CAfc%CA=[&gXZ[!R/5]mG+5c-:lfUpR51
-c%CB?boOKE[*?jJHd0ffHd0ffHd0ffHaLbEH_e$M[*=5MrlkJ%KDWn.K6tkfK6tkfK6tk^H[DQH
-H[F#^K7!C<*/f0FXF#<-XF#T$]r]2tK6su$H^)4.H`YK:K7!UB$)FrA[!R_U[!TK;c&BmI^&6FT
-SG(J5SGC\8SG(M3SH%.<SGgt=X8mb~>
-!<E/pcMs1*c2bTVapZ4CIAOBTZHA#P[`8-c,DCPo`lcGTJ]budIAOBTZHBV(IC?_8IC@;<Kmff+
-Y-Q3$Jc!S1\p^a(b(5,db(5,db(5,db)(PT_M*E7[]ZpYJV!gCs,$Wqs+13ms+13ms+(R#_L6j+
-M1'fpb(5-=arH7dWiCJq^8cU8Y-t@Ib)(PTV1"W?Q$oLOb(5-CapFcI^9W0Db-$0$J]`qo!5ABV
-pQbHt!1!B*!1!9'rK[E.rK[?,!NlEQ~>
-!<E/pec208eH!;[bmB#LUpR51c%CAMprt%9H[E`Vc%CAfc%CA=[&gXZ[!R/5]mG+5c-:lfUpR51
-c%CB?boOKE[*?jJHd0ffHd0ffHd0ffHaLbEH_e$M[*=5MrlkJ%KDWn.K6tkfK6tkfK6tk^H[DQH
-H[F#^K7!C<*/f0FXF#<-XF#T$]r]2tK6su$H^)4.H`YK:K7!UB$)FrA[!R_U[!TK;c&BmI^&6FT
-SG(J5SGC\8SG(M3SH%.<SGgt=X8mb~>
-!<E/feH!;[bmMFSH[CCHc*W+M^%onSUjJ@*bn5STc-=4lH[CCHc-:T^c-:T^rlk_fP^@b0XNcBE
-qT]%us32C5Hd0ffHd0ffHd0gBK6t;NP^@b0XNcBErlkIrHi)&&K6tkfK6tkfK6tkfXFl/4K6tkf
-K7!C<(USgAS>:M%c)chMH],kf["E_=XFkkPXT$HFK7!UB#aBsgH^)LoMi3/2Mp278r7(e\q4%Gu
-p=8o-p!s)4rRLq<r7(hL!.Y~>
-!<E/fc2bTUapQ"NJUN6Tb-HSL](sJMTm`(&b5[%mar/']JUN6Tb/SjXb0#-\`lcH@Q%=@;Y0)<H
-qTAhts2t@ms2t@ms2t@ms2kbUJUtDLQ%=@;Y0)<HrlY7lqo\qis2t@ms2t@ms2kYNJVCC`J]c,d
-Jb[A([Y9.#Tm`?OWel.PM8%-<JUtD/KmeZTrlY7lrlPM3JUN*7^<2FpJ]`nn!5ABV!4M]g!4MUH
-pQbEss-<Q.s-<N-!NlEQ~>
-!<E/feH!;[bmMFSH[CCHc*W+M^%onSUjJ@*bn5STc-=4lH[CCHc-:T^c-:T^rlk_fP^@b0XNcBE
-qT]%us32C5Hd0ffHd0ffHd0gBK6t;NP^@b0XNcBErlkIrHi)&&K6tkfK6tkfK6tkfXFl/4K6tkf
-K7!C<(USgAS>:M%c)chMH],kf["E_=XFkkPXT$HFK7!UB#aBsgH^)LoMi3/2Mp278r7(e\q4%Gu
-p=8o-p!s)4rRLq<r7(hL!.Y~>
-!<E/feH!;Qc2)be^"(@/`Ik89blN0Dqp"ta!5714!j%$nJ^'+t!56>$!NZ9O~>
-!<E/fc2bTKb5-Md]%+q)_L\Q.ao]S2L&9$hI/pk6ao\So_L]jfaoK/oc2k'JJ,~>
-!<E/feH!;Qc2)be^"(@/`Ik89blN0Dqp"ta!5714!j%$nJ^'+t!56>$!NZ9O~>
-!<E/fblGGi`<!ZJdDZ<sPbbC=H^rC#!MmD[`JVV7]u8.rX8mb~>
-!<E/faoK/g`W<fIdDcC!OfGF@IA+s+!MR5Y`eqb9^;S.pXoNt~>
-!<E/fblGGi`<!ZJdDZ<sPbbC=H^rC#!MmD[`JVV7]u8.rX8mb~>
-!<E/fblGG7`<Er>K6r6HJ]32ZeAVF$`6A=a!.Y~>
-!<E/faoK/5`Wa)=JUN6GJ]<8\eA_L&`6&+`!.Y~>
-!<E/fblGG7`<Er>K6r6HJ]32ZeAVF$`6A=a!.Y~>
-!<E/fblGG.`IZ!Z`Ri'/]u8.rX8mb~>
-!<E/faoK/,`du-\`n/31^;S.pXoNt~>
-!<E/fblGG.`IZ!Z`Ri'/]u8.rX8mb~>
-!!%S&JV/N+K7a.(J,~>
-!!%S$JUrB'K7O"&J,~>
-!!%S&JV/N+K7a.(J,~>
-!<E0!joD3.s+13$s,I$^V#TT>]`<Q~>
-!<E0!joD*+s+13$s,I$^U&X9;\c@6~>
-!<E0!joD3.s+13$s,I$^V#TT>]`<Q~>
-!<E0!joD3.s+13$s,R*`K;AP0k.LbF~>
-!<E0!joD*+s+13$s,R*`JYE,+k.1PC~>
-!<E0!joD3.s+13$s,R*`K;AP0k.LbF~>
-!<E0!joV@Ys+/^OeUc85ec17*V#TT>]`<Q~>
-!<E0!joV7Vs+/mTg4@t?gAc^-U&X9;\c@6~>
-!<E0!joV@Ys+/^OeUc85ec17*V#TT>]`<Q~>
-!<E0!joV@Ys+/^OeUc85ec17*V#TT>]`<Q~>
-!<E0!joV7Vs+/mTg4@t?gAc^-U&X9;\c@6~>
-!<E0!joV@Ys+/^OeUc85ec17*V#TT>]`<Q~>
-!<E0!joV@Ys+/^OeUc85ec17*V#TT>]`<Q~>
-!<E0!joV7Vs+/mTg4@t?gAc^-U&X9;\c@6~>
-!<E0!joV@Ys+/^OeUc85ec17*V#TT>]`<Q~>
-!<E0!joV@Ys+/^OeUc85ec17*V#TT>]`<Q~>
-!<E0!joV7Vs+/mTg4@t?gAc^-U&X9;\c@6~>
-!<E0!joV@Ys+/^OeUc85ec17*V#TT>]`<Q~>
-!<E0!joV@Ys+/^OeUc85ec17*V#TT>]`<Q~>
-!<E0!joV7Vs+/mTg4@t?gAc^-U&X9;\c@6~>
-!<E0!joV@Ys+/^OeUc85ec17*V#TT>]`<Q~>
-!<E0!joV@Ys+/^OeUc85ec17*V#TT>]`<Q~>
-!<E0!joV7Vs+/mTg4@t?gAc^-U&X9;\c@6~>
-!<E0!joV@Ys+/^OeUc85ec17*V#TT>]`<Q~>
-!<E0!joV@Ys+/^OeUc85ec17*V#TT>]`<Q~>
-!<E0!joV7Vs+/mTg4@t?gAc^-U&X9;\c@6~>
-!<E0!joV@Ys+/^OeUc85ec17*V#TT>]`<Q~>
-!<E0!joV@Ys8(:A!!:[N!:A>:!<(IH!7TKs!;Y1F!!:[N!:eV>!9Vi-!!^sR!7fU"!9Vi3!<1OK
-!;Y1F!.i[Oe`bQ`K*A(Nk2s>WJ,~>
-!<E0!joV7Vs8(IF!!:jS!:AM?!<(XM!7T[#!;Y@K!!:jS!:eeC!9W#2!!_-W!8?-,!9W#8!<1^P
-!;Y@K!.ijTg?@8jJH_bIk2s5TJ,~>
-!<E0!joV@Ys8(:A!!:[N!:A>:!<(IH!7TKs!;Y1F!!:[N!:eV>!9Vi-!!^sR!7fU"!9Vi3!<1OK
-!;Y1F!.i[Oe`bQ`K*A(Nk2s>WJ,~>
-!<E0!joV@Ys8(:G!;b7G!:A>:!<(IJ!7KEt!<:UL!;b7G!!:[N!:eV>!9Vi3!;b7G!<:UL!9Vi3
-!<1OK!;Y1F!.i[Oe`bQ`K*A(Nk2s>WJ,~>
-!<E0!joV7Vs8(IL!;bFL!:AM?!<(XO!7KU$!<:dQ!;bFL!!:jS!:eeC!9W#8!;bFL!<:dQ!9W#8
-!<1^P!;Y@K!.ijTg?@8jJH_bIk2s5TJ,~>
-!<E0!joV@Ys8(:G!;b7G!:A>:!<(IJ!7KEt!<:UL!;b7G!!:[N!:eV>!9Vi3!;b7G!<:UL!9Vi3
-!<1OK!;Y1F!.i[Oe`bQ`K*A(Nk2s>WJ,~>
-!<E0!joV@Ys8(:G!<(IJ!!LgP!7fWu!:n\?!<:UL!!LgP!7fWu!<:UL!<:UL!<:UL!<:UJ!<:UL
-!!:[N!;+hA!;k=F!<:UL!!LgP!7fWu!<1OI!<:UJ!<:UJ!<:UL!!:[N!;+hA!<(IJ!!CaO!7h#J
-s4.&Js4.,L!n@8No[WsArmh#Ks4.&Js4.,L"k<SQeGoT#eUc9=ec17*V#TT>]`<Q~>
-!<E0!joV7Vs8(IL!<(XO!!M!U!8?0*!:nkD!<:dQ!!M!U!8?0*!<:dQ!<:dQ!<:dQ!<:dO!<:dQ
-!!:jS!;,"F!;kLK!<:dQ!!M!U!8?0*!<1^N!<:dO!<:dO!<:dQ!!:jS!;,"F!<(XO!!CpT!8@AO
-s4[DOs4[JQ!nmVSo\0<Frn@APs4[DOs4[JQ"kiqVg&M,(g4@uGgAc^-U&X9;\c@6~>
-!<E0!joV@Ys8(:G!<(IJ!!LgP!7fWu!:n\?!<:UL!!LgP!7fWu!<:UL!<:UL!<:UL!<:UJ!<:UL
-!!:[N!;+hA!;k=F!<:UL!!LgP!7fWu!<1OI!<:UJ!<:UJ!<:UL!!:[N!;+hA!<(IJ!!CaO!7h#J
-s4.&Js4.,L!n@8No[WsArmh#Ks4.&Js4.,L"k<SQeGoT#eUc9=ec17*V#TT>]`<Q~>
-!<E0!joV@Ys8(:G!<(IJ!"%0U!7_&Le^XX"o@<j@s4.,L*7Y#heGoU"eGoU"!!(R"!!(R"!!(OL
-!7fU"!7guIo[WsAr71fIs4.,L+OpGleGoU"!!(R"!!(OL!7fU"!7fU"!7fU"!7fU"!7guIo[WsA
-rRLoJ&(LX[e^XX"e^XX"e^XX"ebfF>ec,XKec,UVeGoU"eGoU"!!(RK!!:[N!.i[OeaM&gK*A(N
-k2s>WJ,~>
-!<E0!joV7Vs8(IL!<(XO!"%?Z!87DQg=cN,o@j3Es4[JQ*81Amg&M-,g&M-,!!(a,!!(a,!!(^Q
-!8?-,!8@>No\0<Fr7_/Ns4[JQ+PHeqg&M-,!!(a,!!(^Q!8?-,!8?-,!8?-,!8?-,!8@>No\0<F
-rS%8O&)%!`g=cN,g=cN,g=cN,gACsCgA_0PgA_-[g&M-,g&M-,!!(aP!!:jS!.ijTg@*bqJH_bI
-k2s5TJ,~>
-!<E0!joV@Ys8(:G!<(IJ!"%0U!7_&Le^XX"o@<j@s4.,L*7Y#heGoU"eGoU"!!(R"!!(R"!!(OL
-!7fU"!7guIo[WsAr71fIs4.,L+OpGleGoU"!!(R"!!(OL!7fU"!7fU"!7fU"!7fU"!7guIo[WsA
-rRLoJ&(LX[e^XX"e^XX"e^XX"ebfF>ec,XKec,UVeGoU"eGoU"!!(RK!!:[N!.i[OeaM&gK*A(N
-k2s>WJ,~>
-!<E0!joV@Ys8(:D!"@BX!7_&LeGoU"eGoU@ec,XLec,UheGoU"!!(R"!!(R"!!(OL!7_&Le^XX"
-e^XX"ec#R>ec,XIec,XLec,U[eGoU"!!(OL!7fU"!7_&Lqpk]Hs4.,Ls4.,L!7h&Ko%!X<'%Hs^
-eGoU"eGoU"eGoU"eGoU"rW)N>q>_)W!!(R"!!(OL!7_&Le^XX"J^o>%n(%Gj"f21\k.LbF~>
-!<E0!joV7Vs8(II!"@Q]!87DQg&M-,g&M-EgA_0QgA_-mg&M-,!!(a,!!(a,!!(^Q!87DQg=cN,
-g=cN,gAV*CgA_0NgA_0QgA_-`g&M-,!!(^Q!8?-,!87DQqqD&Ms4[JQs4[JQ!8@DPo%O!A'&!<c
-g&M-,g&M-,g&M-,g&M-,rW)NCq>_)\!!(a,!!(^Q!87DQg=cN,J_G\/n(Rem"ektYk.1PC~>
-!<E0!joV@Ys8(:D!"@BX!7_&LeGoU"eGoU@ec,XLec,UheGoU"!!(R"!!(R"!!(OL!7_&Le^XX"
-e^XX"ec#R>ec,XIec,XLec,U[eGoU"!!(OL!7fU"!7_&Lqpk]Hs4.,Ls4.,L!7h&Ko%!X<'%Hs^
-eGoU"eGoU"eGoU"eGoU"rW)N>q>_)W!!(R"!!(OL!7_&Le^XX"J^o>%n(%Gj"f21\k.LbF~>
-!<E0!joV@Ys8(:G!<(IJ!!CaO!7grHo$n!Ge^XZMeGoU"qZ-ZHrr<;S!!(OL!7fWs!!:[N!:eV>
-!;tCI!<:UL!!^sR!7_&Leb]=JeGoUHec,XLec,XLec,UNeGoU>ec,XJec,UTeGoU"eGoU"eb]=J
-eGoU>ec,XKec,ULeb]=QeGoU"!!(R"!!%T#J^s5>s+:KNs5rIW!.Y~>
-!<E0!joV7Vs8(IL!<(XO!!CpT!8@;Mo%F?Lg=cP\g&M-,qZ-ZMrr<;X!!(^Q!8?0(!!:jS!:eeC
-!;tRN!<:dQ!!_-W!87DQgA:jOg&M-MgA_0QgA_0QgA_-Sg&M-CgA_0OgA_-Yg&M-,g&M-,gA:jO
-g&M-CgA_0PgA_-QgA:jVg&M-,!!(a,!!%T(J_KSHs+(?Is5rIT!.Y~>
-!<E0!joV@Ys8(:G!<(IJ!!CaO!7grHo$n!Ge^XZMeGoU"qZ-ZHrr<;S!!(OL!7fWs!!:[N!:eV>
-!;tCI!<:UL!!^sR!7_&Leb]=JeGoUHec,XLec,XLec,UNeGoU>ec,XJec,UTeGoU"eGoU"eb]=J
-eGoU>ec,XKec,ULeb]=QeGoU"!!(R"!!%T#J^s5>s+:KNs5rIW!.Y~>
-!<E0!joV@Ys8(:G!<(IJ!!UmQ!7_&Lma_79s4.,L!n@8Nqpk]H$.T"UeGoU"eGoUIec,X>ec,XI
-ec,XLec,UTeGoU"!!(OL!;tCI!;k=H!<:UL!<:UL!!:[N!:eV>!<(IJ!".6V!7fU"!7fU"!;tCI
-!:eV>!<1OK!!:[N!;tCI!!^sR!7fU"!.i[OeaM&gK*A(Nk2s>WJ,~>
-!<E0!joV7Vs8(IL!<(XO!!V'V!87DQmb7U>s4[JQ!nmVSqqD&M$/,@Zg&M-,g&M-NgA_0CgA_0N
-gA_0QgA_-Yg&M-,!!(^Q!;tRN!;kLM!<:dQ!<:dQ!!:jS!:eeC!<(XO!".E[!8?-,!8?-,!;tRN
-!:eeC!<1^P!!:jS!;tRN!!_-W!8?-,!.ijTg@*bqJH_bIk2s5TJ,~>
-!<E0!joV@Ys8(:G!<(IJ!!UmQ!7_&Lma_79s4.,L!n@8Nqpk]H$.T"UeGoU"eGoUIec,X>ec,XI
-ec,XLec,UTeGoU"!!(OL!;tCI!;k=H!<:UL!<:UL!!:[N!:eV>!<(IJ!".6V!7fU"!7fU"!;tCI
-!:eV>!<1OK!!:[N!;tCI!!^sR!7fU"!.i[OeaM&gK*A(Nk2s>WJ,~>
-!<E0!joV@Ys8(:G!<(IJ!"%0U!7_&Le^XX"n^[X>rmh#K#1W\Re^XX"rmh#Ks4.,Lrmh#Ks4.,L
-!n@8NnC@O=s4.&Js4.,L(tATdeGoU"!!(R"!!(OL!7fU"!7fU"!7h&Ks4.,L!n@8Nn^[X>rRLoJ
-#LreSe^XX"ec#RKec,UNeGoU>ec,XKec,UVeGoU"eGoU"!!(RK!!:[N!.i[OeaM&gK*A(Nk2s>W
-J,~>
-!<E0!joV7Vs8(IL!<(XO!"%?Z!87DQg=cN,n_4!Crn@AP#20%Wg=cN,rn@APs4[JQrn@APs4[JQ
-!nmVSnCmmBs4[DOs4[JQ(tnrig&M-,!!(a,!!(^Q!8?-,!8?-,!8@DPs4[JQ!nmVSn_4!CrS%8O
-#MK.Xg=cN,gAV*PgA_-Sg&M-CgA_0PgA_-[g&M-,g&M-,!!(aP!!:jS!.ijTg@*bqJH_bIk2s5T
-J,~>
-!<E0!joV@Ys8(:G!<(IJ!"%0U!7_&Le^XX"n^[X>rmh#K#1W\Re^XX"rmh#Ks4.,Lrmh#Ks4.,L
-!n@8NnC@O=s4.&Js4.,L(tATdeGoU"!!(R"!!(OL!7fU"!7fU"!7h&Ks4.,L!n@8Nn^[X>rRLoJ
-#LreSe^XX"ec#RKec,UNeGoU>ec,XKec,UVeGoU"eGoU"!!(RK!!:[N!.i[OeaM&gK*A(Nk2s>W
-J,~>
-!<E0!joV@Ys8(:G!<(IJ!!LgP!7fWu!:\P=!<1OK!<:UJ!<(IJ!<:UL!<(IH!<:UL!:SJ:!<:UJ
-!<:UL!!LgP!7fWu!<1OI!<(IJ!<:UJ!<:UL!:eV>!<(IJ!!:[N!<1OK!<:UJ!<:UL!:eV>!<1OK
-!<:UJ!<:UL!!UmQ!7_&LJ^o>%ma_>i"f21\k.LbF~>
-!<E0!joV7Vs8(IL!<(XO!!M!U!8?0*!:\_B!<1^P!<:dO!<(XO!<:dQ!<(XM!<:dQ!:SY?!<:dO
-!<:dQ!!M!U!8?0*!<1^N!<(XO!<:dO!<:dQ!:eeC!<(XO!!:jS!<1^P!<:dO!<:dQ!:eeC!<1^P
-!<:dO!<:dQ!!V'V!87DQJ_G\/mb7\l"ektYk.1PC~>
-!<E0!joV@Ys8(:G!<(IJ!!LgP!7fWu!:\P=!<1OK!<:UJ!<(IJ!<:UL!<(IH!<:UL!:SJ:!<:UJ
-!<:UL!!LgP!7fWu!<1OI!<(IJ!<:UJ!<:UL!:eV>!<(IJ!!:[N!<1OK!<:UJ!<:UL!:eV>!<1OK
-!<:UJ!<:UL!!UmQ!7_&LJ^o>%ma_>i"f21\k.LbF~>
-!<E0!joV@Ys+/_"ec,W#eUc9:ec17*V#TT>]`<Q~>
-!<E0!joV7Vs+/n'gA_/(g4@uDgAc^-U&X9;\c@6~>
-!<E0!joV@Ys+/_"ec,W#eUc9:ec17*V#TT>]`<Q~>
-!<E0!joV@Ys+/_"ec,W#eUc9:ec17*V#TT>]`<Q~>
-!<E0!joV7Vs+/n'gA_/(g4@uDgAc^-U&X9;\c@6~>
-!<E0!joV@Ys+/_"ec,W#eUc9:ec17*V#TT>]`<Q~>
-!<E0!joV@Ys+/_"ec,W#eUc9:ec17*V#TT>]`<Q~>
-!<E0!joV7Vs+/n'gA_/(g4@uDgAc^-U&X9;\c@6~>
-!<E0!joV@Ys+/_"ec,W#eUc9:ec17*V#TT>]`<Q~>
-!<E0!joV@Ys+/^OeUc85ec17*V#TT>]`<Q~>
-!<E0!joV7Vs+/mTg4@t?gAc^-U&X9;\c@6~>
-!<E0!joV@Ys+/^OeUc85ec17*V#TT>]`<Q~>
-!<E0!joV@Ys+/^OeUc85ec17*V#TT>]`<Q~>
-!<E0!joV7Vs+/mTg4@t?gAc^-U&X9;\c@6~>
-!<E0!joV@Ys+/^OeUc85ec17*V#TT>]`<Q~>
-!<E0!joV@Ys+/^OeUc85ec17*V#TT>]`<Q~>
-!<E0!joV7Vs+/mTg4@t?gAc^-U&X9;\c@6~>
-!<E0!joV@Ys+/^OeUc85ec17*V#TT>]`<Q~>
-!<E0!joV@Ys+/^OeUc85ec17*V#TT>]`<Q~>
-!<E0!joV7Vs+/mTg4@t?gAc^-U&X9;\c@6~>
-!<E0!joV@Ys+/^OeUc85ec17*V#TT>]`<Q~>
-!<E0!joV@Ys+/^OeUc85ec17*V#TT>]`<Q~>
-!<E0!joV7Vs+/mTg4@t?gAc^-U&X9;\c@6~>
-!<E0!joV@Ys+/^OeUc85ec17*V#TT>]`<Q~>
-!<E0!joV@Ys+,fRK7SZ9K*A(Nk2s>WJ,~>
-!<E0!joV7Vs+,`PJUrB5JH_bIk2s5TJ,~>
-!<E0!joV@Ys+,fRK7SZ9K*A(Nk2s>WJ,~>
-!<E0!joM:XJV/N+JV/u8"f21\k.LbF~>
-!<E0!joM1UJUrB'JUri4"ektYk.1PC~>
-!<E0!joM:XJV/N+JV/u8"f21\k.LbF~>
-!<E0!joD3.eUc8%eW&)_V#TT>]`<Q~>
-!<E0!joD*+g4@t/g5XeiU&X9;\c@6~>
-!<E0!joD3.eUc8%eW&)_V#TT>]`<Q~>
-!<E0!joD3.eUc8%eW&)_V#TT>]`<Q~>
-!<E0!joD*+g4@t/g5XeiU&X9;\c@6~>
-!<E0!joD3.eUc8%eW&)_V#TT>]`<Q~>
-!<E0!joD3.eUc8%eW&)_V#TT>]`<Q~>
-!<E0!joD*+g4@t/g5XeiU&X9;\c@6~>
-!<E0!joD3.eUc8%eW&)_V#TT>]`<Q~>
-!<E0!joD3.eUc8%eW&)_V#TT>]`<Q~>
-!<E0!joD*+g4@t/g5XeiU&X9;\c@6~>
-!<E0!joD3.eUc8%eW&)_V#TT>]`<Q~>
-!<E0!joD3.eUc8%eW&)_V#TT>]`<Q~>
-!<E0!joD*+g4@t/g5XeiU&X9;\c@6~>
-!<E0!joD3.eUc8%eW&)_V#TT>]`<Q~>
-!<E0!joD3.eUc8%eW&)_V#TT>]`<Q~>
-!<E0!joD*+g4@t/g5XeiU&X9;\c@6~>
-!<E0!joD3.eUc8%eW&)_V#TT>]`<Q~>
-!<E0!joD3.eUc8%eW&)_V#TT>]`<Q~>
-!<E0!joD*+g4@t/g5XeiU&X9;\c@6~>
-!<E0!joD3.eUc8%eW&)_V#TT>]`<Q~>
-!<E0!joD3.eUc8%eW&)_V#TT>]`<Q~>
-!<E0!joD*+g4@t/g5XeiU&X9;\c@6~>
-!<E0!joD3.eUc8%eW&)_V#TT>]`<Q~>
-!<E0!joD3.eUc8%eW&)_V#TT>]`<Q~>
-!<E0!joD*+g4@t/g5XeiU&X9;\c@6~>
-!<E0!joD3.eUc8%eW&)_V#TT>]`<Q~>
-!<E0!joD3.eUc8%eW&)_V#TT>]`<Q~>
-!<E0!joD*+g4@t/g5XeiU&X9;\c@6~>
-!<E0!joD3.eUc8%eW&)_V#TT>]`<Q~>
-!<E0!joD3.e`#'V!;=tC!;P+E!!:[N!;k=H!9_o4!.i[Oea_/nV#TT>]`<Q~>
-!<E0!joD*+g>Uc`!;>.H!;P:J!!:jS!;kLM!9`)9!.ijTg@<l#U&X9;\c@6~>
-!<E0!joD3.e`#'V!;=tC!;P+E!!:[N!;k=H!9_o4!.i[Oea_/nV#TT>]`<Q~>
-!<E0!joD3.e`#'Y!<:UL!;G%D!;4nB!;k=H!9_o4!.i[Oea_/nV#TT>]`<Q~>
-!<E0!joD*+g>Ucc!<:dQ!;G4I!;5(G!;kLM!9`)9!.ijTg@<l#U&X9;\c@6~>
-!<E0!joD3.e`#'Y!<:UL!;G%D!;4nB!;k=H!9_o4!.i[Oea_/nV#TT>]`<Q~>
-!<E0!joD4Keb9%=eb]?&ec,XKec,XLeboLJeboLJeboLJec,UNeGoUHec,XIeboLJec,XKec,XL
-eboLJec,W#eUc9@eHMcKk2s>WJ,~>
-!<E0!joD+Hg@kRBgA:l+gA_0PgA_0QgAM$OgAM$OgAM$OgA_-Sg&M-MgA_0NgAM$OgA_0PgA_0Q
-gAM$OgA_/(g4@uJg'+2Mk2s5TJ,~>
-!<E0!joD4Keb9%=eb]?&ec,XKec,XLeboLJeboLJeboLJec,UNeGoUHec,XIeboLJec,XKec,XL
-eboLJec,W#eUc9@eHMcKk2s>WJ,~>
-!<E0!joD4KebB(DKDF't!//o&!<1OK!#X5d!7fU"!7fU"!7fU"!7fU"!7_&LeGoUHec,XJec,XL
-ec,UNeGoUKec,UUeGoU"eGoU"!!%T#J^s;@"f21\k.LbF~>
-!<E0!joD+Hg@tUIJbe%"!/0)+!<1^P!#XDi!8?-,!8?-,!8?-,!8?-,!87DQg&M-MgA_0OgA_0Q
-gA_-Sg&M-PgA_-Zg&M-,g&M-,!!%T(J_KYJ"ektYk.1PC~>
-!<E0!joD4KebB(DKDF't!//o&!<1OK!#X5d!7fU"!7fU"!7fU"!7fU"!7_&LeGoUHec,XJec,XL
-ec,UNeGoUKec,UUeGoU"eGoU"!!%T#J^s;@"f21\k.LbF~>
-!<E0!joD4Kec5[Gec19tec,XJec,UOeGoU"r;ciIr;clJquHcIr;`_FrrE&Krr<DV!!(R"!!(R"
-!!)oHrr<5Q!!(OL!;k=H!<(IJ!<:UL!<:UL!"IHY!7fU"!7fU"!7_&LJ^o>%n^Rf=s5rIW!.Y~>
-!<E0!joD+HgAh3LgAca"gA_0OgA_-Tg&M-,r;ciNr;clOquHcNr;`_KrrE&Prr<D[!!(a,!!(a,
-!!)oMrr<5V!!(^Q!;kLM!<(XO!<:dQ!<:dQ!"IW^!8?-,!8?-,!87DQJ_G\/n_+/?s5rIT!.Y~>
-!<E0!joD4Kec5[Gec19tec,XJec,UOeGoU"r;ciIr;clJquHcIr;`_FrrE&Krr<DV!!(R"!!(R"
-!!)oHrr<5Q!!(OL!;k=H!<(IJ!<:UL!<:UL!"IHY!7fU"!7fU"!7_&LJ^o>%n^Rf=s5rIW!.Y~>
-!<E0!joD4Kec5[Gec19tec,XJebT:Gec,UReGoU"eGoUJec,UReGoU"eGoTIec,XKec,ULeb]@H
-ec,XKebfCNeGoU"!!)oHrrE#JqZ-ZHrr<2P!!(R"qZ$]J!!%T#J^s;@"f21\k.LbF~>
-!<E0!joD+HgAh3LgAca"gA_0OgA1gLgA_-Wg&M-,g&M-OgA_-Wg&M-,g&M,NgA_0PgA_-QgA:mM
-gA_0PgACpSg&M-,!!)oMrrE#OqZ-ZMrr<2U!!(a,qZ$]O!!%T(J_KYJ"ektYk.1PC~>
-!<E0!joD4Kec5[Gec19tec,XJebT:Gec,UReGoU"eGoUJec,UReGoU"eGoTIec,XKec,ULeb]@H
-ec,XKebfCNeGoU"!!)oHrrE#JqZ-ZHrr<2P!!(R"qZ$]J!!%T#J^s;@"f21\k.LbF~>
-!<E0!joD4Kec5[Gec19tebfCIec#RKec,XLec,UReGoU"eGoUKec,XLec,XLec,WIec,XKec,UN
-eGoUHec,XLec,XLec,UQeGoU"!!)oHrrE#JrrDoGrW)rJrrDuIrr@W#J^s;@"f21\k.LbF~>
-!<E0!joD+HgAh3LgAca"gACpNgAV*PgA_0QgA_-Wg&M-,g&M-PgA_0QgA_0QgA_/NgA_0PgA_-S
-g&M-MgA_0QgA_0QgA_-Vg&M-,!!)oMrrE#OrrDoLrW)rOrrDuNrr@W(J_KYJ"ektYk.1PC~>
-!<E0!joD4Kec5[Gec19tebfCIec#RKec,XLec,UReGoU"eGoUKec,XLec,XLec,WIec,XKec,UN
-eGoUHec,XLec,XLec,UQeGoU"!!)oHrrE#JrrDoGrW)rJrrDuIrr@W#J^s;@"f21\k.LbF~>
-!<E0!joD4Kec5[Gec19tec,XJec,XKeb]=Heb]@GeGoUKeb]?Eec,XLec,XLec,XLec,XLec,UL
-ec#RKec,UQeGoU"!!)oHrrE#JrrE)LrrE&KrW)rJrrE)Lrr<,N!!%T#J^s;@"f21\k.LbF~>
-!<E0!joD+HgAh3LgAca"gA_0OgA_0PgA:jMgA:mLg&M-PgA:lJgA_0QgA_0QgA_0QgA_0QgA_-Q
-gAV*PgA_-Vg&M-,!!)oMrrE#OrrE)QrrE&PrW)rOrrE)Qrr<,S!!%T(J_KYJ"ektYk.1PC~>
-!<E0!joD4Kec5[Gec19tec,XJec,XKeb]=Heb]@GeGoUKeb]?Eec,XLec,XLec,XLec,XLec,UL
-ec#RKec,UQeGoU"!!)oHrrE#JrrE)LrrE&KrW)rJrrE)Lrr<,N!!%T#J^s;@"f21\k.LbF~>
-!<E0!joD4Kec5[Gec19tec,XJec,XKec,XIec,XHec,XKec,WEebfFGeboLHec,XLec#OKeboIL
-eGoUHeb]=HeboLGeGoUIeboLJec,W#eUc9@eHMcKk2s>WJ,~>
-!<E0!joD+HgAh3LgAca"gA_0OgA_0PgA_0NgA_0MgA_0PgA_/JgACsLgAM$MgA_0QgAV'PgAM!Q
-g&M-MgA:jMgAM$Lg&M-NgAM$OgA_/(g4@uJg'+2Mk2s5TJ,~>
-!<E0!joD4Kec5[Gec19tec,XJec,XKec,XIec,XHec,XKec,WEebfFGeboLHec,XLec#OKeboIL
-eGoUHeb]=HeboLGeGoUIeboLJec,W#eUc9@eHMcKk2s>WJ,~>
-!<E0!joD4Kec5[Gec19tec,XJec,XKec,XLec,UUeGoU"eGoU"!!)uJrrE)Lrr@W#J^o>%e("Vt
-s5rIW!.Y~>
-!<E0!joD+HgAh3LgAca"gA_0OgA_0PgA_0QgA_-Zg&M-,g&M-,!!)uOrrE)Qrr@W(J_G\/e(Ou!
-s5rIT!.Y~>
-!<E0!joD4Kec5[Gec19tec,XJec,XKec,XLec,UUeGoU"eGoU"!!)uJrrE)Lrr@W#J^o>%e("Vt
-s5rIW!.Y~>
-!<E0!joD4Kec5[Gec19tec,XJec,XJeboLIeboLJebfFIeboK!eUc8%e^DtOV#TT>]`<Q~>
-!<E0!joD+HgAh3LgAca"gA_0OgA_0OgAM$NgAM$OgACsNgAM#&g4@t/g="[YU&X9;\c@6~>
-!<E0!joD4Kec5[Gec19tec,XJec,XJeboLIeboLJebfFIeboK!eUc8%e^DtOV#TT>]`<Q~>
-!<E0!joD4Kec5[EK7VR(eUc8JeHMcKk2s>WJ,~>
-!<E0!joD+HgAh3JJUuO+g4@tTg'+2Mk2s5TJ,~>
-!<E0!joD4Kec5[EK7VR(eUc8JeHMcKk2s>WJ,~>
-!<E0!joD3.eUc8%eW&)_V#TT>]`<Q~>
-!<E0!joD*+g4@t/g5XeiU&X9;\c@6~>
-!<E0!joD3.eUc8%eW&)_V#TT>]`<Q~>
-!<E0!joD3.eUc8%eW&)_V#TT>]`<Q~>
-!<E0!joD*+g4@t/g5XeiU&X9;\c@6~>
-!<E0!joD3.eUc8%eW&)_V#TT>]`<Q~>
-!<E0!joD3.eUc8%eW&)_V#TT>]`<Q~>
-!<E0!joD*+g4@t/g5XeiU&X9;\c@6~>
-!<E0!joD3.eUc8%eW&)_V#TT>]`<Q~>
-!<E0!joD3.eUc8%eW&)_V#TT>]`<Q~>
-!<E0!joD*+g4@t/g5XeiU&X9;\c@6~>
-!<E0!joD3.eUc8%eW&)_V#TT>]`<Q~>
-!<E0!joD3.eUc8dec,XJeboLIeboK!e_em\V#TT>]`<Q~>
-!<E0!joD*+g4@tngA_0OgAM$NgAM#&g>CTfU&X9;\c@6~>
-!<E0!joD3.eUc8dec,XJeboLIeboK!e_em\V#TT>]`<Q~>
-!<E0!joD3.eUc8feboLIec,XLec,UReGoU"eGoT#e_ns]V#TT>]`<Q~>
-!<E0!joD*+g4@tpgAM$NgA_0QgA_-Wg&M-,g&M,(g>LZgU&X9;\c@6~>
-!<E0!joD3.eUc8feboLIec,XLec,UReGoU"eGoT#e_ns]V#TT>]`<Q~>
-!<E0!joD3.eUc8dec,XKec,XLec,UReGoU"eGoT#e_ns]V#TT>]`<Q~>
-!<E0!joD*+g4@tngA_0PgA_0QgA_-Wg&M-,g&M,(g>LZgU&X9;\c@6~>
-!<E0!joD3.eUc8dec,XKec,XLec,UReGoU"eGoT#e_ns]V#TT>]`<Q~>
-!<E0!joD3.eUc8dec,XKec,XLec,UReGoU"eGoT#e_ns]V#TT>]`<Q~>
-!<E0!joD*+g4@tngA_0PgA_0QgA_-Wg&M-,g&M,(g>LZgU&X9;\c@6~>
-!<E0!joD3.eUc8dec,XKec,XLec,UReGoU"eGoT#e_ns]V#TT>]`<Q~>
-!<E0!joD3.eUc8dec,XKec,XLec,UReGoU"eGoT#e_ns]V#TT>]`<Q~>
-!<E0!joD*+g4@tngA_0PgA_0QgA_-Wg&M-,g&M,(g>LZgU&X9;\c@6~>
-!<E0!joD3.eUc8dec,XKec,XLec,UReGoU"eGoT#e_ns]V#TT>]`<Q~>
-!<E0!joD3.eUc8dec,XKec,XLec,UReGoU"eGoT#e_ns]V#TT>]`<Q~>
-!<E0!joD*+g4@tngA_0PgA_0QgA_-Wg&M-,g&M,(g>LZgU&X9;\c@6~>
-!<E0!joD3.eUc8dec,XKec,XLec,UReGoU"eGoT#e_ns]V#TT>]`<Q~>
-!<E0!joD4Keb9%=ec,XKec,UNeGoUIec,XAeb]@,ebK2reZ77#!<1OK!<:UL!!^sR!7fU"!.i\Y
-eHMcKk2s>WJ,~>
-!<E0!joD+Hg@kRBgA_0PgA_-Sg&M-NgA_0FgA:m1gA(`"g8is-!<1^P!<:dQ!!_-W!8?-,!.ik^
-g'+2Mk2s5TJ,~>
-!<E0!joD4Keb9%=ec,XKec,UNeGoUIec,XAeb]@,ebK2reZ77#!<1OK!<:UL!!^sR!7fU"!.i\Y
-eHMcKk2s>WJ,~>
-!<E0!joD4KebB(DKDF't!<1OK!;Y1F!;+hA!8Q-)!.i\!ec,XKec,XLec,UReGoU"eGoT#e_ns]
-V#TT>]`<Q~>
-!<E0!joD+Hg@tUIJbe%"!<1^P!;Y@K!;,"F!8Q<.!.ik&gA_0PgA_0QgA_-Wg&M-,g&M,(g>LZg
-U&X9;\c@6~>
-!<E0!joD4KebB(DKDF't!<1OK!;Y1F!;+hA!8Q-)!.i\!ec,XKec,XLec,UReGoU"eGoT#e_ns]
-V#TT>]`<Q~>
-!<E0!joD4Kec5[Gec19tec,XKec,UWeGoU"eGoU"!!(R"r;c]ErrE#Jrr</O!!(RJ!<:RM!7h&K
-!7h&Kp!s'BrRLiHJ^q!TrrE#Jr;ciIr;_E!hphn+s5rIW!.Y~>
-!<E0!joD+HgAh3LgAca"gA_0PgA_-\g&M-,g&M-,!!(a,r;c]JrrE#Orr</T!!(aO!<:aR!8@DP
-!8@DPp"KEGrS%2MJ_I?^rrE#Or;ciNr;_E&hqA7-s5rIT!.Y~>
-!<E0!joD4Kec5[Gec19tec,XKec,UWeGoU"eGoU"!!(R"r;c]ErrE#Jrr</O!!(RJ!<:RM!7h&K
-!7h&Kp!s'BrRLiHJ^q!TrrE#Jr;ciIr;_E!hphn+s5rIW!.Y~>
-!<E0!joD4Kec5[Gec19tec,XKec,UReGoU"!!(RK!!^sR!7fU"!;k=H!<(IE!<:UL!".6V!7fU"
-!7fU"!;=tC!<1OK!<:UL!.i[OeUc9MeHMcKk2s>WJ,~>
-!<E0!joD+HgAh3LgAca"gA_0PgA_-Wg&M-,!!(aP!!_-W!8?-,!;kLM!<(XJ!<:dQ!".E[!8?-,
-!8?-,!;>.H!<1^P!<:dQ!.ijTg4@uWg'+2Mk2s5TJ,~>
-!<E0!joD4Kec5[Gec19tec,XKec,UReGoU"!!(RK!!^sR!7fU"!;k=H!<(IE!<:UL!".6V!7fU"
-!7fU"!;=tC!<1OK!<:UL!.i[OeUc9MeHMcKk2s>WJ,~>
-!<E0!joD4Kec5[Gec19tebT7WeGoU"!!(R"!!(OL!7fU"!;k=E!!(RK!<:UL!<:UL!"7<W!7fU"
-!7fU"!7grHrRLoJrmh#Ks4.,LJ^o>%J^sbM"f21\k.LbF~>
-!<E0!joD+HgAh3LgAca"gA1d\g&M-,!!(a,!!(^Q!8?-,!;kLJ!!(aP!<:dQ!<:dQ!"7K\!8?-,
-!8?-,!8@;MrS%8Orn@APs4[JQJ_G\/J_L+W"ektYk.1PC~>
-!<E0!joD4Kec5[Gec19tebT7WeGoU"!!(R"!!(OL!7fU"!;k=E!!(RK!<:UL!<:UL!"7<W!7fU"
-!7fU"!7grHrRLoJrmh#Ks4.,LJ^o>%J^sbM"f21\k.LbF~>
-!<E0!joD4Kec5[Gec19tec,XKec,UVeGoU"!!(R"!!(RH!;k=H!<(IJ!<1OK!<:UL!".6V!7fU"
-!7fU"!;=tC!<1OK!<:UL!.i[OeUc9MeHMcKk2s>WJ,~>
-!<E0!joD+HgAh3LgAca"gA_0PgA_-[g&M-,!!(a,!!(aM!;kLM!<(XO!<1^P!<:dQ!".E[!8?-,
-!8?-,!;>.H!<1^P!<:dQ!.ijTg4@uWg'+2Mk2s5TJ,~>
-!<E0!joD4Kec5[Gec19tec,XKec,UVeGoU"!!(R"!!(RH!;k=H!<(IJ!<1OK!<:UL!".6V!7fU"
-!7fU"!;=tC!<1OK!<:UL!.i[OeUc9MeHMcKk2s>WJ,~>
-!<E0!joD4Kec5[Gec19tec,XKec,UXeGoU"!!(R"!!(OL!;G%D!<(IJ!<1OK!<:UL!"7<W!7fU"
-!7fU"!7grHrRLoJrmh#Ks4.,LJ^o>%J^sbM"f21\k.LbF~>
-!<E0!joD+HgAh3LgAca"gA_0PgA_-]g&M-,!!(a,!!(^Q!;G4I!<(XO!<1^P!<:dQ!"7K\!8?-,
-!8?-,!8@;MrS%8Orn@APs4[JQJ_G\/J_L+W"ektYk.1PC~>
-!<E0!joD4Kec5[Gec19tec,XKec,UXeGoU"!!(R"!!(OL!;G%D!<(IJ!<1OK!<:UL!"7<W!7fU"
-!7fU"!7grHrRLoJrmh#Ks4.,LJ^o>%J^sbM"f21\k.LbF~>
-!<E0!joD4Kec5[Gec19tec,XKec,UReGoU"!!(RK!!^sR!7fU"!;k=H!<(IJ!<1OK!<:UL!".6V
-!7fU"!7fU"!;=tC!<1OK!<:UL!.i[OeUc9MeHMcKk2s>WJ,~>
-!<E0!joD+HgAh3LgAca"gA_0PgA_-Wg&M-,!!(aP!!_-W!8?-,!;kLM!<(XO!<1^P!<:dQ!".E[
-!8?-,!8?-,!;>.H!<1^P!<:dQ!.ijTg4@uWg'+2Mk2s5TJ,~>
-!<E0!joD4Kec5[Gec19tec,XKec,UReGoU"!!(RK!!^sR!7fU"!;k=H!<(IJ!<1OK!<:UL!".6V
-!7fU"!7fU"!;=tC!<1OK!<:UL!.i[OeUc9MeHMcKk2s>WJ,~>
-!<E0!joD4Kec5[Gec19tec,XKec,UWeGoU"eGoU"!!(R"r;c]ErrE#JrrE#Jr;clJrrE)LrrE)L
-rrDcCrrE#Jr;bI"JV1dkJ^rr6"f21\k.LbF~>
-!<E0!joD+HgAh3LgAca"gA_0PgA_-\g&M-,g&M-,!!(a,r;c]JrrE#OrrE#Or;clOrrE)QrrE)Q
-rrDcHrrE#Or;bI'JUtXgJ_K;@"ektYk.1PC~>
-!<E0!joD4Kec5[Gec19tec,XKec,UWeGoU"eGoU"!!(R"r;c]ErrE#JrrE#Jr;clJrrE)LrrE)L
-rrDcCrrE#Jr;bI"JV1dkJ^rr6"f21\k.LbF~>
-!<E0!joD4Kec5[EK7VPQeU`@iK)kq&e`YHdV#TT>]`<Q~>
-!<E0!joD+HgAh3JJUuMTg4=glJH5_$g?7/nU&X9;\c@6~>
-!<E0!joD4Kec5[EK7VPQeU`@iK)kq&e`YHdV#TT>]`<Q~>
-!<E0!joD3.e`YK_K7U_r^#B!Be`YHdV#TT>]`<Q~>
-!<E0!joD*+g?72iJUt\u_VtNGg?7/nU&X9;\c@6~>
-!<E0!joD3.e`YK_K7U_r^#B!Be`YHdV#TT>]`<Q~>
-!<E0!joD3.e`YK_K7U_r^#]1pKE(t&e`YHdV#TT>]`<Q~>
-!<E0!joD*+g?72iJUt\u_W:^uJcGb$g?7/nU&X9;\c@6~>
-!<E0!joD3.e`YK_K7U_r^#]1pKE(t&e`YHdV#TT>]`<Q~>
-!<E0!joD3.e`YK_K7U_r^&S-*eH(=&p!s(ps8RZ#kLBa3s5rIW!.Y~>
-!<E0!joD*+g?72iJUt\u_Z0Z/g&Zd)p"KFss8RZ(kLp*5s5rIT!.Y~>
-!<E0!joD3.e`YK_K7U_r^&S-*eH(=&p!s(ps8RZ#kLBa3s5rIW!.Y~>
-!<E0!joD3.e`YK_K7U_r^&S-*eH(=&p!s(ps8RZ#kLBa3s5rIW!.Y~>
-!<E0!joD*+g?72iJUt\u_Z0Z/g&Zd)p"KFss8RZ(kLp*5s5rIT!.Y~>
-!<E0!joD3.e`YK_K7U_r^&S-*eH(=&p!s(ps8RZ#kLBa3s5rIW!.Y~>
-!<E0!joD3.e`YK_K7U_r^&S-*eH(=&p!s(ps8RZ#kLBa3s5rIW!.Y~>
-!<E0!joD*+g?72iJUt\u_Z0Z/g&Zd)p"KFss8RZ(kLp*5s5rIT!.Y~>
-!<E0!joD3.e`YK_K7U_r^&S-*eH(=&p!s(ps8RZ#kLBa3s5rIW!.Y~>
-!<E0!joD3.e`YK_K7U_r^&S-*eH(=&p!s(ps8RZ#kLBa3s5rIW!.Y~>
-!<E0!joD*+g?72iJUt\u_Z0Z/g&Zd)p"KFss8RZ(kLp*5s5rIT!.Y~>
-!<E0!joD3.e`YK_K7U_r^&S-*eH(=&p!s(ps8RZ#kLBa3s5rIW!.Y~>
-!<E0!joD3.e`YK_K7U_r^&S-*eH(=&p!s(ps8RZ#kLBa3s5rIW!.Y~>
-!<E0!joD*+g?72iJUt\u_Z0Z/g&Zd)p"KFss8RZ(kLp*5s5rIT!.Y~>
-!<E0!joD3.e`YK_K7U_r^&S-*eH(=&p!s(ps8RZ#kLBa3s5rIW!.Y~>
-!<E0!joD3.e`YK_K7U_r^&S-*eH(=&p!s(ps8RZ#kLBa3s5rIW!.Y~>
-!<E0!joD*+g?72iJUt\u_Z0Z/g&Zd)p"KFss8RZ(kLp*5s5rIT!.Y~>
-!<E0!joD3.e`YK_K7U_r^&S-*eH(=&p!s(ps8RZ#kLBa3s5rIW!.Y~>
-!<E0!joD3.e`YK_K7U_r^&S-*eH(=&p!s(ps8RZ#kLBa3s5rIW!.Y~>
-!<E0!joD*+g?72iJUt\u_Z0Z/g&Zd)p"KFss8RZ(kLp*5s5rIT!.Y~>
-!<E0!joD3.e`YK_K7U_r^&S-*eH(=&p!s(ps8RZ#kLBa3s5rIW!.Y~>
-!<E0!joD3.e`YK_K7U_r^&S-*eH(=&p!s(ps8RZ#kLBa3s5rIW!.Y~>
-!<E0!joD*+g?72iJUt\u_Z0Z/g&Zd)p"KFss8RZ(kLp*5s5rIT!.Y~>
-!<E0!joD3.e`YK_K7U_r^&S-*eH(=&p!s(ps8RZ#kLBa3s5rIW!.Y~>
-!<E0!joD4Keb9%=ec,XKec,UNeGoUIec,XAec,XKec,XFec,WYec18Q^#Qg+s7OnCKE(Vps+C@O
-J^rr6"f21\k.LbF~>
-!<E0!joD+Hg@kRBgA_0PgA_-Sg&M-NgA_0FgA_0PgA_0KgA_/^gAc_T_W/N5s7P(HJcGDss+14M
-J_K;@"ektYk.1PC~>
-!<E0!joD4Keb9%=ec,XKec,UNeGoUIec,XAec,XKec,XFec,WYec18Q^#Qg+s7OnCKE(Vps+C@O
-J^rr6"f21\k.LbF~>
-!<E0!joD4KebB(DKDF't!<1OK!;Y1F!;+hA!<1OK!;Y1F!4UMYK7U_r^&S-*eH(=&p!s(ps8RZ#
-kLBa3s5rIW!.Y~>
-!<E0!joD+Hg@tUIJbe%"!<1^P!;Y@K!;,"F!<1^P!;Y@K!4U\^JUt\u_Z0Z/g&Zd)p"KFss8RZ(
-kLp*5s5rIT!.Y~>
-!<E0!joD4KebB(DKDF't!<1OK!;Y1F!;+hA!<1OK!;Y1F!4UMYK7U_r^&S-*eH(=&p!s(ps8RZ#
-kLBa3s5rIW!.Y~>
-!<E0!joD4Kec5[Gec19tec,XKec,UWeGoU"eGoU"!!(R"r;c]ErrE&Krr<__!!(OL!7fU"!7fU"
-!7_&LeGoUKeboLJec,XLec,XLec,UQeGoU"!!(a's+>m9j1YKmp!j(qs7OqBKE(t&e`YHdV#TT>
-]`<Q~>
-!<E0!joD+HgAh3LgAca"gA_0PgA_-\g&M-,g&M-,!!(a,r;c]JrrE&Prr<_d!!(^Q!8?-,!8?-,
-!87DQg&M-PgAM$OgA_0QgA_0QgA_-Vg&M-,!!(a,s+,a<j21irp"BFts7P+GJcGb$g?7/nU&X9;
-\c@6~>
-!<E0!joD4Kec5[Gec19tec,XKec,UWeGoU"eGoU"!!(R"r;c]ErrE&Krr<__!!(OL!7fU"!7fU"
-!7_&LeGoUKeboLJec,XLec,XLec,UQeGoU"!!(a's+>m9j1YKmp!j(qs7OqBKE(t&e`YHdV#TT>
-]`<Q~>
-!<E0!joD4Kec5[Gec19tec,XKec,UReGoU"!!(RK!!^sR!7fU"!;k=H!<1OK!!(RK!".6V!7_&L
-eGoU"ec#O`eGoU"!!(R"!!(OL!7fU"!7fU"!7h&K!n@8NgXZ=VJ\C*Ws8V_D!<;YCs8RZ#kLBa3
-s5rIW!.Y~>
-!<E0!joD+HgAh3LgAca"gA_0PgA_-Wg&M-,!!(aP!!_-W!8?-,!;kLM!<1^P!!(aP!".E[!87DQ
-g&M-,gAV'eg&M-,!!(a,!!(^Q!8?-,!8?-,!8@DP!nmVSgY2[YJ\pHas8V_B!<;YAs8RZ(kLp*5
-s5rIT!.Y~>
-!<E0!joD4Kec5[Gec19tec,XKec,UReGoU"!!(RK!!^sR!7fU"!;k=H!<1OK!!(RK!".6V!7_&L
-eGoU"ec#O`eGoU"!!(R"!!(OL!7fU"!7fU"!7h&K!n@8NgXZ=VJ\C*Ws8V_D!<;YCs8RZ#kLBa3
-s5rIW!.Y~>
-!<E0!joD4Kec5[Gec19tebT7WeGoU"!!(R"!!(OL!7fU"!;k=H!<1OK!!h$S!7fU"!7h#Jrmh#K
-s4.,L(tATde^XX"e^XX"eGoU"!!(R"!!(R"!!(d(s+>m9j1PHmjFdL4J^rr6"f21\k.LbF~>
-!<E0!joD+HgAh3LgAca"gA1d\g&M-,!!(a,!!(^Q!8?-,!;kLM!<1^P!!h3X!8?-,!8@AOrn@AP
-s4[JQ(tnrig=cN,g=cN,g&M-,!!(a,!!(a,!!(d-s+,a<j2(frjFR@2J_K;@"ektYk.1PC~>
-!<E0!joD4Kec5[Gec19tebT7WeGoU"!!(R"!!(OL!7fU"!;k=H!<1OK!!h$S!7fU"!7h#Jrmh#K
-s4.,L(tATde^XX"e^XX"eGoU"!!(R"!!(R"!!(d(s+>m9j1PHmjFdL4J^rr6"f21\k.LbF~>
-!<E0!joD4Kec5[Gec19tec,XKec,UVeGoU"!!(R"!!(RH!;k=H!<1OK!!h$S!7fU"!7h#Jrmh#K
-s4.,L(tATde^XX"e^XX"eGoU"!!(R"!!(R"!!(d(s+>n&_uG;<kLBa3s5rIW!.Y~>
-!<E0!joD+HgAh3LgAca"gA_0PgA_-[g&M-,!!(a,!!(aM!;kLM!<1^P!!h3X!8?-,!8@AOrn@AP
-s4[JQ(tnrig=cN,g=cN,g&M-,!!(a,!!(a,!!(d-s+,b$_uG;AkLp*5s5rIT!.Y~>
-!<E0!joD4Kec5[Gec19tec,XKec,UVeGoU"!!(R"!!(RH!;k=H!<1OK!!h$S!7fU"!7h#Jrmh#K
-s4.,L(tATde^XX"e^XX"eGoU"!!(R"!!(R"!!(d(s+>n&_uG;<kLBa3s5rIW!.Y~>
-!<E0!joD4Kec5[Gec19tec,XKec,UXeGoU"!!(R"!!(OL!;G%D!<1OK!%l_$!7fU"!7_&LeGoU"
-eGoU"eGoU"!!(R"!!(R"!!(OL!7_&Le^XX"e^XX"gXQ:VJcEUeJ^rr6"f21\k.LbF~>
-!<E0!joD+HgAh3LgAca"gA_0PgA_-]g&M-,!!(a,!!(^Q!;G4I!<1^P!%ln)!8?-,!87DQg&M-,
-g&M-,g&M-,!!(a,!!(a,!!(^Q!87DQg=cN,g=cN,gY)XYJcEUeJ_K;@"ektYk.1PC~>
-!<E0!joD4Kec5[Gec19tec,XKec,UXeGoU"!!(R"!!(OL!;G%D!<1OK!%l_$!7fU"!7_&LeGoU"
-eGoU"eGoU"!!(R"!!(R"!!(OL!7_&Le^XX"e^XX"gXQ:VJcEUeJ^rr6"f21\k.LbF~>
-!<E0!joD4Kec5[Gec19tec,XKec,UReGoU"!!(RK!!^sR!7fU"!;b7G!$B_k!7fU"!7fU"!7_&L
-e^XX"eGoU"eGoU"!!(R"!!*#KrrE)LrrE&KrrE)Lrr@W#J^o>%"f21\k.LbF~>
-!<E0!joD+HgAh3LgAca"gA_0PgA_-Wg&M-,!!(aP!!_-W!8?-,!;bFL!$Bnp!8?-,!8?-,!87DQ
-g=cN,g&M-,g&M-,!!(a,!!*#PrrE)QrrE&PrrE)Qrr@W(J_G\/"ektYk.1PC~>
-!<E0!joD4Kec5[Gec19tec,XKec,UReGoU"!!(RK!!^sR!7fU"!;b7G!$B_k!7fU"!7fU"!7_&L
-e^XX"eGoU"eGoU"!!(R"!!*#KrrE)LrrE&KrrE)Lrr@W#J^o>%"f21\k.LbF~>
-!<E0!joD4Kec5[Gec19tec,XKec,UWeGoU"eGoU"!!(R"r;cZDquHcIrrE)Lrr<,N!!*#Kr;clJ
-rrE)Lr;cfHrrE)LrrE&KrrE)Lrr@W#J^o>%"f21\k.LbF~>
-!<E0!joD+HgAh3LgAca"gA_0PgA_-\g&M-,g&M-,!!(a,r;cZIquHcNrrE)Qrr<,S!!*#Pr;clO
-rrE)Qr;cfMrrE)QrrE&PrrE)Qrr@W(J_G\/"ektYk.1PC~>
-!<E0!joD4Kec5[Gec19tec,XKec,UWeGoU"eGoU"!!(R"r;cZDquHcIrrE)Lrr<,N!!*#Kr;clJ
-rrE)Lr;cfHrrE)LrrE&KrrE)Lrr@W#J^o>%"f21\k.LbF~>
-!<E0!joD4Kec5[EK7VR(eUc8JeHMcKk2s>WJ,~>
-!<E0!joD+HgAh3JJUuO+g4@tTg'+2Mk2s5TJ,~>
-!<E0!joD4Kec5[EK7VR(eUc8JeHMcKk2s>WJ,~>
-!<E0!joD3.eUc8%eW&)_V#TT>]`<Q~>
-!<E0!joD*+g4@t/g5XeiU&X9;\c@6~>
-!<E0!joD3.eUc8%eW&)_V#TT>]`<Q~>
-!<E0!joD3.eUc8%eY^mbKDX1&V#TT>]`<Q~>
-!<E0!joD*+g4@t/g8<TlJc".)U&X9;\c@6~>
-!<E0!joD3.eUc8%eY^mbKDX1&V#TT>]`<Q~>
-!<E0!joD3.eUc8%eY^mcK)krKeHMcKk2s>WJ,~>
-!<E0!joD*+g4@t/g8<TmJH5`Ig'+2Mk2s5TJ,~>
-!<E0!joD3.eUc8%eY^mcK)krKeHMcKk2s>WJ,~>
-!<E0!joD3.eUc8%eY^msKDN7]KDN:]s81=MV#TT>]`<Q~>
-!<E0!joD*+g4@t/g8<U(Jbm4`Jbm7`s81LRU&X9;\c@6~>
-!<E0!joD3.eUc8%eY^msKDN7]KDN:]s81=MV#TT>]`<Q~>
-!<E0!joD3.eUc8%eY^msKDW=_s+C0]s8VuH"f21\k.LbF~>
-!<E0!joD*+g4@t/g8<U(Jc!:bs+1$`s8VuM"ektYk.1PC~>
-!<E0!joD3.eUc8%eY^msKDW=_s+C0]s8VuH"f21\k.LbF~>
-!<E0!joD3.eUc8%eY^msKDW=`s+>t$^&S-0eHMcKk2s>WJ,~>
-!<E0!joD*+g4@t/g8<U(Jc!:cs+,au_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD3.eUc8%eY^msKDW=`s+>t$^&S-0eHMcKk2s>WJ,~>
-!<E0!joD3.eUc8%eY^msKD`F_s8R`K^&S-0eHMcKk2s>WJ,~>
-!<E0!joD*+g4@t/g8<U(Jc*Cbs8RZI_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD3.eUc8%eY^msKD`F_s8R`K^&S-0eHMcKk2s>WJ,~>
-!<E0!joD3.eUc8%eY^msKD`F_rrU`'KD`F_s81=MV#TT>]`<Q~>
-!<E0!joD*+g4@t/g8<U(Jc*CbrrUo*Jc*Cbs81LRU&X9;\c@6~>
-!<E0!joD3.eUc8%eY^msKD`F_rrU`'KD`F_s81=MV#TT>]`<Q~>
-!<E0!joD3.eUc8%eY^msKDiL`s8UXLKD`F_s81=MV#TT>]`<Q~>
-!<E0!joD*+g4@t/g8<U(Jc3Ics8UgQJc*Cbs81LRU&X9;\c@6~>
-!<E0!joD3.eUc8%eY^msKDiL`s8UXLKD`F_s81=MV#TT>]`<Q~>
-!<E0!joD3.eUc8%eY^msKDiL`s8LRKKDiL`s81=MV#TT>]`<Q~>
-!<E0!joD*+g4@t/g8<U(Jc3Ics8LaPJc3Ics81LRU&X9;\c@6~>
-!<E0!joD3.eUc8%eY^msKDiL`s8LRKKDiL`s81=MV#TT>]`<Q~>
-!<E0!joD3.eUc8%eY^msKDrRas8CLJKDiL`s81=MV#TT>]`<Q~>
-!<E0!joD*+g4@t/g8<U(Jc<Ods8C[OJc3Ics81LRU&X9;\c@6~>
-!<E0!joD3.eUc8%eY^msKDrRas8CLJKDiL`s81=MV#TT>]`<Q~>
-!<E0!joD3.eUc8%eY^msKDrRas8:FIKDrRas81=MV#TT>]`<Q~>
-!<E0!joD*+g4@t/g8<U(Jc<Ods8:UNJc<Ods81LRU&X9;\c@6~>
-!<E0!joD3.eUc8%eY^msKDrRas8:FIKDrRas81=MV#TT>]`<Q~>
-!<E0!joD3.eUc8%eY^msKE&Xbs81@HKDrRas81=MV#TT>]`<Q~>
-!<E0!joD*+g4@t/g8<U(JcEUes81OMJc<Ods81LRU&X9;\c@6~>
-!<E0!joD3.eUc8%eY^msKE&Xbs81@HKDrRas81=MV#TT>]`<Q~>
-!<E0!joD3.eUc8%eY^msKE&Xbs8(:GKE&Xbs81=MV#TT>]`<Q~>
-!<E0!joD*+g4@t/g8<U(JcEUes8(ILJcEUes81LRU&X9;\c@6~>
-!<E0!joD3.eUc8%eY^msKE&Xbs8(:GKE&Xbs81=MV#TT>]`<Q~>
-!<E0!joD3.e`>9\s7OqBs8CLJs0^AWs,,A,s7=e@s0'uQK*&ads7t4FKE&Xbs81=MV#TT>]`<Q~>
-!<E0!joD*+g>puf!;5(G!<(XO!4CM\!/fM1!;"qE!3b,VJHE^gs7tCKJcEUes81LRU&X9;\c@6~>
-!<E0!joD3.e`>9\!;4nB!<(IJ!4C>W!/f>,!;"b@!3arQK*&ads7t4FKE&Xbs81=MV#TT>]`<Q~>
-!<E0!joD4Lec5[Lec#LJeboFOec5["s8UXKs8UXLs8UXLrrCUIrrCUKs-hI<s7FhAs8:CIs0^AW
-s,#8+s74\?s0'uQK*&ads7k.EK*&ads81=MV#TT>]`<Q~>
-!<E0!joD+IgAe#LgARiJgAIcOg81Y"V5;oFV>o9LV>o9LV#]6IV#]6KV4-*<!;+tF!;tON!4CM\
-!/]D0!:nhD!3b,VJHE^gs7k=JJHE^gs81LRU&X9;\c@6~>
-!<E0!joD4Lec,XLeboIJebfCOeGoU"!!(RK!<:UL!<:UL!!(RI!!(RK!1MF<!;+eA!;t@I!4C>W
-!/]5+!:nY?!3arQK*&ads7k.EK*&ads81=MV#TT>]`<Q~>
-!<E0!joD4KeIMW0ec41Ms4,["e^a]Ms8LOVs4,["e^a]Mec42"rm_5Qe^a]Mec2r*s8NATs4,["
-s4./LpsoBDs4.,KrRLrJr7(fIr7(fI[ak?Vs4%/Mec,RMec5[KeH>j%s8W&Jrr;iFs8N,Ms8CLJ
-rrgmPec42!s1Hk^s8CLJs8CLJs8LONs4./LqUPWG!S.5Kec5XPec42"ec,Tlec1:%s7M!G^&S-0
-eHMcKk2s>WJ,~>
-!<E0!joD+Hg('t5g83NWV:sY"g=iCWV>f0VV:sY"g=iCWg83N"rn7RQg=iCWg82+/rr<>Y!8?-,
-!87DQptG]Is4[GPrS%8Or7V,Nr7V,N[bCZ[s4RJRgAV'Rg&M-Pg&h?/!!)uOrW)fKrr<)R!<(XO
-!!M!Ug&Tk+!5."c!<(XO!<(XO!<1[S!87DQqV(rL!SRPPgA_-Ug&Th,gAV)qgAca(s7LpE_Z0Z5
-g'+2Mk2s5TJ,~>
-!<E0!joD4KeIDT0eH".M!7fU"e^XZM!<1LV!7fU"e^XZMeH","rm_2Qe^XZMeGuo*rr<>T!7fU"
-!7_&Lpso?Ds4.)KrRLoJr7(cIr7(cI[ak<Vs4%,Mec#OMeGoUKeH5g%!!)uJrW)fFrr<)M!<(IJ
-!!LgPeH"/!!5-h^!<(IJ!<(IJ!<1LN!7_&LqUPTG!S%2Kec,UPeH","ec#Qlec1:%s7M!G^&S-0
-eHMcKk2s>WJ,~>
-!<E0!joD4KeIDQ/ec41Ms8UXLe^a^"rRLrJ'@m-5ec41Ms4./"s4./"ec5["s0C/^s4./"s4,["
-e^a]qeH#XIeHu9+ec41Ms4,["rRCoJr7(fI[FG9Wr7(fIqpb]Hrm_5Qe^a]Mec5Bo$NJZVec41M
-s4,["rm_#K\^^][rm_MYe^a]Mec41Ms4,["ec5Hq$NJZVec41Ms4,["rm_#KaOU<C!<;YCs8VuH
-"f21\k.LbF~>
-!<E0!joD+Hg'sn4g83NWV5;nBg=iC"rS%:J'AB;:g83NWV:qd"V:qd"g81Y"V6\e^!87G,!8?-,
-g=cQ&g&M-Ng'Ic5g&Tj\!8?-,rRq5Or7V,N[FtT\r7V,Nqq;#Mrn7PVg=cP\g&Um$$38c[g&Tj\
-!8?-,rn7>P\_7#`rn7h^g=cP\g&Tj\!8?-,g&Us&$38c[g&Tj\!8?-,rn7>PaP-ZF!<;YAs8VuM
-"ektYk.1PC~>
-!<E0!joD4KeI;N/eH".M!!(OLe^XX"rRLoJ'@d*5eH".M!7_)"!7_)"eGoU"!4(,^!7_)"!7fU"
-e^XZqeGoUIeHl6+eH".M!7fU"rRClJr7(cI[FG6Wr7(cIqpbZHrm_2Qe^XZMeH#?o$38TVeH".M
-!7fU"rm^uK\^^Z[rm_JYe^XZMeH".M!7fU"eH#Eq$38TVeH".M!7fU"rm^uKaOU<C!<;YCs8VuH
-"f21\k.LbF~>
-!<E0!joD4KeIMW0ec41Ms4./Le^a]Ms8LO`s4./Le^a]Mec42"ec42"e^a]Ms8TCT$NJZVec41M
-s4,["psoEErm_2Pe^a]Mec,UHeH#XIeH#WWeH#XIeH#XJec,UJeH>j%ec5X!s8VoF$NJZVec41M
-s4,["rm_#K\^^][rm_5Qe^a]Mec5Qts8VlE$NJZVec41Ms4,["rm_#KaOU<Co"G)'qpbkGs5rIW
-!.Y~>
-!<E0!joD+Hg('t5g83NWV:qcBg=iCWV>f0`V:qcBg=iCWg83N"g83N"g=iCWV5:KO$38c[g&Tj\
-!8?-,ptG`Jrn7MUg=cP\gAV*Mg&M-Ng&M,\g&M-Ng&M-OgAV*Og&h?/g&V-+rrDlK$38c[g&Tj\
-!8?-,rn7>P\_7#`rn7PVg=cP\g&V')rrDiJ$38c[g&Tj\!8?-,rn7>PaP-ZFo"tG,qq;4Is5rIT
-!.Y~>
-!<E0!joD4KeIDT0eH".M!7_&Le^XZM!<1L`!7_&Le^XZMeH","eH","e^XZM!!'=T$38TVeH".M
-!7fU"psoBErm_/Pe^XZMec#RHeGoUIeGoTWeGoUIeGoUJec#RJeH5g%eH#U!rrDlF$38TVeH".M
-!7fU"rm^uK\^^Z[rm_2Qe^XZMeH#NtrrDiE$38TVeH".M!7fU"rm^uKaOU<Co"G)'qpbkGs5rIW
-!.Y~>
-!<E0!joD4KeKFnBec41Ms4,["e^a]Mec41Ms4,["e^a]Mec41Ms4./KeH>j%ec2r*$NJZVec41M
-s4,["p=0TOe^a]Mec41Ms4,["rRCoJr7(fI[FGK]e^a]Mec5X!"96p%s8LONs4,["r7(fIqUGrQ
-ec42"e^a]Mec5X!!<9U[!<<&K%fb)0s4,["e^a]Mec42"q:,iPec42"e^a]Mec5X!!<:-js+Bh@
-qpbkGs5rIW!.Y~>
-!<E0!joD+Hg*!6Gg83NWV:sY"g=iCWg83NWV:sY"g=iCWg83NWV:qdFg&n2*g82+/$38c[g&Tj\
-!8?-,p=]oTg=cP\g&Tj\!8?-,rRq5Or7V,N[Ftfbg=cP\g&V-+!s%'/!<1[S!8?-,r7V,NqUu8V
-g&Th,g=cP\g&V-+!!'R`!!*#P%KP5:!8?-,g=cP\g&Th,q:Z/Ug&Th,g=cP\g&V-+!!(*os+0\>
-qq;4Is5rIT!.Y~>
-!<E0!joD4KeK=kBeH".M!7fU"e^XZMeH".M!7fU"e^XZMeH".M!7_)KeH5g%eGuo*$38TVeH".M
-!7fU"p=0QOe^XZMeH".M!7fU"rRClJr7(cI[FGH]e^XZMeH#U!!s$m%!<1LN!7fU"r7(cIqUGoQ
-eH","e^XZMeH#U!!!'R[!!*#K%KP&0!7fU"e^XZMeH","q:,fPeH","e^XZMeH#U!!!(*js+Bh@
-qpbkGs5rIW!.Y~>
-!<E0!joD4Jec5[Lec5[LeH,^#rr<#Krr<#K!<<&Ks8W)K$3/QUe^a^"e^a]*eHu9+s4./Le^a^"
-psoBDs4.,K#1`bRe^a^"rmgrH!7h#I[akEXs4.)Js4./L!nI>$rr3)Ns8UXKs7t1Ms4./"s8UX"
-rr<#KrVsR]r;ZfIs8W&Js8W,Ls8N/Ns8VrG#QN?Sec5["ec,UKec#Njec19nrrRiQs81=MV#TT>
-]`<Q~>
-!<E0!joD+GgAe#LgAe#Lg&\&(rh]YKrh]YK!2]\Ks/#_K$)Q@Pg=iC"g=iC/g'Ic5!87DQg=cN,
-ptG]Is4[GP#20%Wg=cN,rn@8M!8@>N[bC`]s4[DOs4[JQ!nmY.rW!&S!!(aP!;Y=R!87G,!!(a,
-rW)uPr;aObquHcNrrE#OrrE)Qrr<,S!!)lL#6<HXg&M-,gAV*PgAM#ogAc`qrrRcOs81LRU&X9;
-\c@6~>
-!<E0!joD4Jec,XLec,XLeH#[#rW)uKrW)uK!!*#KrrE&K#lrKUe^XX"e^XZ*eHl6+!7_&Le^XX"
-pso?Ds4.)K#1W\Re^XX"rmgoH!7guI[akBXs4.&Js4.,L!n@;$rW!&N!!(RK!;Y.M!7_)"!!(R"
-rW)uKr;aO]quHcIrrE#JrrE)Lrr<,N!!)lG#6<9SeGoU"ec#RKeboKjec19nrrRiQs81=MV#TT>
-]`<Q~>
-!<E0!joD3.eb%Als+/_]eH#W2eH#Wfec1:%s7Y"CKE(uKeHMcKk2s>WJ,~>
-!<E0!joD*+g@X)!!.ikbg&M,7g&M,kgAca(s7Y1HJcGcIg'+2Mk2s5TJ,~>
-!<E0!joD3.eb%Al!.i\]eGoT2eGoTfec1:%s7Y"CKE(uKeHMcKk2s>WJ,~>
-!<E0!joD3.eb7Pns8CLFs+/`!ebfCCec,T@ebfCCec,Tdec1:%s7Y"CKE(uKeHMcKk2s>WJ,~>
-!<E0!joD*+g@j8#!<(XK!.il&gA:mHgAV)EgA:mHgAV)igAca(s7Y1HJcGcIg'+2Mk2s5TJ,~>
-!<E0!joD3.eb7Pn!<(IF!.i]!eb]@Cec#Q@eb]@Cec#Qdec1:%s7Y"CKE(uKeHMcKk2s>WJ,~>
-!<E0!joD3.eUc8%eY^msKE(uFec1:%s81=MV#TT>]`<Q~>
-!<E0!joD*+g4@t/g8<U(JcGcDgAca(s81LRU&X9;\c@6~>
-!<E0!joD3.eUc8%eY^msKE(uFec1:%s81=MV#TT>]`<Q~>
-!<E0!joD3.eUc8%eY^msKE(uFec1:%s81=MV#TT>]`<Q~>
-!<E0!joD*+g4@t/g8<U(JcGcDgAca(s81LRU&X9;\c@6~>
-!<E0!joD3.eUc8%eY^msKE(uFec1:%s81=MV#TT>]`<Q~>
-!<E0!joD3.eUc8%eY^msKE(uFec1:%s81=MV#TT>]`<Q~>
-!<E0!joD*+g4@t/g8<U(JcGcDgAca(s81LRU&X9;\c@6~>
-!<E0!joD3.eUc8%eY^msKE(uFec1:%s81=MV#TT>]`<Q~>
-!<E0!joD3.eUc8%eY^msKE(uFec1:%s81=MV#TT>]`<Q~>
-!<E0!joD*+g4@t/g8<U(JcGcDgAca(s81LRU&X9;\c@6~>
-!<E0!joD3.eUc8%eY^msKE(uFec1:%s81=MV#TT>]`<Q~>
-!<E0!joD3.eUc8%eY^msKE(uFec1:%s81=MV#TT>]`<Q~>
-!<E0!joD*+g4@t/g8<U(JcGcDgAca(s81LRU&X9;\c@6~>
-!<E0!joD3.eUc8%eY^msKE(uFec1:%s81=MV#TT>]`<Q~>
-!<E0!joD3.eUc8%eY^msKE(uFec1:%s81=MV#TT>]`<Q~>
-!<E0!joD*+g4@t/g8<U(JcGcDgAca(s81LRU&X9;\c@6~>
-!<E0!joD3.eUc8%eY^msKE(uFec1:%s81=MV#TT>]`<Q~>
-!<E0!joD3.eUc8%eY^msKE(uFec1:%s81=MV#TT>]`<Q~>
-!<E0!joD*+g4@t/g8<U(JcGcDgAca(s81LRU&X9;\c@6~>
-!<E0!joD3.eUc8%eY^msKE(uFec1:%s81=MV#TT>]`<Q~>
-!<E0!joD3.eUc8%eY^msKE(uFec1:%s81=MV#TT>]`<Q~>
-!<E0!joD*+g4@t/g8<U(JcGcDgAca(s81LRU&X9;\c@6~>
-!<E0!joD3.eUc8%eY^msKE(uFec1:%s81=MV#TT>]`<Q~>
-!<E0!joD3.eUc8%eY^msKE(uFec1:%s81=MV#TT>]`<Q~>
-!<E0!joD*+g4@t/g8<U(JcGcDgAca(s81LRU&X9;\c@6~>
-!<E0!joD3.eUc8%eY^msKE(uFec1:%s81=MV#TT>]`<Q~>
-!<E0!joD3.eUc8%eY^msKE(uFec1:%s81=MV#TT>]`<Q~>
-!<E0!joD*+g4@t/g8<U(JcGcDgAca(s81LRU&X9;\c@6~>
-!<E0!joD3.eUc8%eY^msKE(uFec1:%s81=MV#TT>]`<Q~>
-!<E0!joD3.eUc8%eY^msKE(uFec1:%s81=MV#TT>]`<Q~>
-!<E0!joD*+g4@t/g8<U(JcGcDgAca(s81LRU&X9;\c@6~>
-!<E0!joD3.eUc8%eY^msKE(uFec1:%s81=MV#TT>]`<Q~>
-!<E0!joD3.eUc8%eY^msKE(uFec1:%s81=MV#TT>]`<Q~>
-!<E0!joD*+g4@t/g8<U(JcGcDgAca(s81LRU&X9;\c@6~>
-!<E0!joD3.eUc8%eY^msKE(uFec1:%s81=MV#TT>]`<Q~>
-!<E0!joD3.eUc8%eY^msKE(uFec1:%s81=MV#TT>]`<Q~>
-!<E0!joD*+g4@t/g8<U(JcGcDgAca(s81LRU&X9;\c@6~>
-!<E0!joD3.eUc8%eY^msKE(uFec1:%s81=MV#TT>]`<Q~>
-!<E0!joD3.eUc8%eY^msKE(uFec1:%s81=MV#TT>]`<Q~>
-!<E0!joD*+g4@t/g8<U(JcGcDgAca(s81LRU&X9;\c@6~>
-!<E0!joD3.eUc8%eY^msKE(uFec1:%s81=MV#TT>]`<Q~>
-!<E0!joD3.eUc8%eY^msKE(uFec1:%s81=MV#TT>]`<Q~>
-!<E0!joD*+g4@t/g8<U(JcGcDgAca(s81LRU&X9;\c@6~>
-!<E0!joD3.eUc8%eY^msKE(uFec1:%s81=MV#TT>]`<Q~>
-!<E0!joD3.eUc8%eY^msKE(uFec1:%s81=MV#TT>]`<Q~>
-!<E0!joD*+g4@t/g8<U(JcGcDgAca(s81LRU&X9;\c@6~>
-!<E0!joD3.eUc8%eY^msKE(uFec1:%s81=MV#TT>]`<Q~>
-!<E0!joD3.eUc8%eY^msKE(uFec1:%s81=MV#TT>]`<Q~>
-!<E0!joD*+g4@t/g8<U(JcGcDgAca(s81LRU&X9;\c@6~>
-!<E0!joD3.eUc8%eY^msKE(uFec1:%s81=MV#TT>]`<Q~>
-!<E0!joD3.eUc8%eY^msKE(uDKE(uKeHMcKk2s>WJ,~>
-!<E0!joD*+g4@t/g8<U(JcGcBJcGcIg'+2Mk2s5TJ,~>
-!<E0!joD3.eUc8%eY^msKE(uDKE(uKeHMcKk2s>WJ,~>
-!<E0!joD3.eUc8%eY^msK)krCKE(uKeHMcKk2s>WJ,~>
-!<E0!joD*+g4@t/g8<U(JH5`AJcGcIg'+2Mk2s5TJ,~>
-!<E0!joD3.eUc8%eY^msK)krCKE(uKeHMcKk2s>WJ,~>
-!<E0!joD3.eUc8%eY^msKCZ_Us81=MV#TT>]`<Q~>
-!<E0!joD*+g4@t/g8<U(Jb$\Xs81LRU&X9;\c@6~>
-!<E0!joD3.eUc8%eY^msKCZ_Us81=MV#TT>]`<Q~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#X;eH#X=eH#X7eH#WjeH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M-@g&M-Bg&M-<g&M,og&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoU;eGoU=eGoU7eGoTjeGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#X;eH#X=eH#X7eH#WjeH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M-@g&M-Bg&M-<g&M,og&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoU;eGoU=eGoU7eGoTjeGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#XAec,UKec#OJec5[JeH,^#rr2uKrVuZCs8W,Ls8N5Ps8UX"rVulIs8W)K
-!WU^Ls4>d$s,,>,s/+?HKCZ_Us81=MV#TT>]`<Q~>
-!<E0!joD+?g&Rt,g&M-FgAV*PgAM$OgA_0Og&V3-rVurPr;cWHrrE)Qrr<2U!!(a,r;ciNrrE&P
-!<CjQ!8#p)!/fJ1!2eKMJb$\Xs81LRU&X9;\c@6~>
-!<E0!joD4BeGoT,eGoUAec#RKeboLJec,XJeH#[#rVurKr;cWCrrE)Lrr<2P!!(R"r;ciIrrE&K
-!<C[L!8#a$!/f;,!2e<HKCZ_Us81=MV#TT>]`<Q~>
-!<E0!joD4BeH#W,eH#XBeH#XHeH#XHeH#XJeH#XIeH#XDeHu9+ec41Ms4,["rm_#KrRD#Me^a^!
-eH#X!eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M-Gg&M-Mg&M-Mg&M-Og&M-Ng&M-Ig'Ic5g&Tj\!8?-,rn7>PrRq>Rg=cQ+
-g&M-&g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoUBeGoUHeGoUHeGoUJeGoUIeGoUDeHl6+eH".M!7fU"rm^uKrRCuMe^X[!
-eGoU!eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#XAec5[JeH#XJec,UIeH#XIeH#XDeHu9+ec41Ms4,["rm_#KrRLoIrRCoJ
-eC=R!MU__,VUb^!o"G)'qpbkGs5rIW!.Y~>
-!<E0!joD+?g&Rt,g&M-FgA_0Og&M-OgAV*Ng&M-Ng&M-Ig'Ic5g&Tj\!8?-,rn7>PrS%5NrRq5O
-eCjm&MV8%1VV;'$o"tG,qq;4Is5rIT!.Y~>
-!<E0!joD4BeGoT,eGoUAec,XJeGoUJec#RIeGoUIeGoUDeHl6+eH".M!7fU"rm^uKrRLlIrRClJ
-eC=O!MU_\,VUb^!o"G)'qpbkGs5rIW!.Y~>
-!<E0!joD4BeH#W,eH#X?eH#XKeHc-)ec5["ec5Tu!<;uI"96p%s8(7Ps4,["e^a]Mec5X!#liH*
-s4./"ec5X!!<:R!!<7r,!<8qHs+BmUs8VuH"f21\k.LbF~>
-!<E0!joD+?g&Rt,g&M-Dg&M-Pg'7W3g&M-,g&V**!!)rN!s%'/!;bCU!8?-,g=cP\g&V-+#QWT4
-!87G,g&V-+!!(O&!!%o1!!&nMs+0aXs8VuM"ektYk.1PC~>
-!<E0!joD4BeGoT,eGoU?eGoUKeHZ*)eGoU"eH#Qu!!)rI!s$m%!;b4P!7fU"e^XZMeH#U!#QWE*
-!7_)"eH#U!!!(O!!!%o,!!&nHs+BmUs8VuH"f21\k.LbF~>
-!<E0!joD4BeH#W,eH#XBec,UHec5[Lec5XOec41MrVuiHs8VlEs8W&Js8N,Ms8LRKs8LRKs8LRI
-s45^#s,,>,s/+?HKCZ_Us81=MV#TT>]`<Q~>
-!<E0!joD+?g&Rt,g&M-GgAV*MgA_0QgA_-Tg&Tj\r;cfMrrDiJrrE#Orr<)R!<1^P!<1^P!<1^N
-!7oj(!/fJ1!2eKMJb$\Xs81LRU&X9;\c@6~>
-!<E0!joD4BeGoT,eGoUBec#RHec,XLec,UOeH".Mr;cfHrrDiErrE#Jrr<)M!<1OK!<1OK!<1OI
-!7o[#!/f;,!2e<HKCZ_Us81=MV#TT>]`<Q~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#X%ebfBWeH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M-*gA:l\g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoU%eb]?WeGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W5ec,XGeH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M,:gA_0Lg&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT5ec,XGeGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W5eboLGeH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M,:gAM$Lg&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT5eboLGeGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W4eb]@HeH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M,9gA:mMg&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT4eb]@HeGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eVO8+s,,>,s/+?HKCZ_Us81=MV#TT>]`<Q~>
-!<E0!joD+?g&Rt,g5#`dg&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eVF3_eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W4eb]@HeH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M,9gA:mMg&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT4eb]@HeGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W4ec#RHeH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M,9gAV*Mg&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT4ec#RHeGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W5ec,XGeH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M,:gA_0Lg&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT5ec,XGeGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#X)eH#XHeH#XIec5Z`eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M-.g&M-Mg&M-NgA_/eg&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoU)eGoUHeGoUIec,W`eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#X)eH#XAeH#W`eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M-.g&M-Fg&M,eg&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoU)eGoUAeGoT`eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#XCeH>j%s8W&Js8W,L"om-Qec5[Gec#OIec5[Jec,T_eH#W,eH#WHec19m
-^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M-Hg&h?/!!)uOrrE)Q"T[6Vg&M-LgAM$NgA_0OgAV)dg&M,1g&M,MgAc`p
-_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoUCeH5g%!!)uJrrE)L"T['QeGoUGeboLIec,XJec#Q_eGoT,eGoTHec19m
-^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#XBeIV]1ec41Ms4,["ec42"ec5Ep!<;rH!<<&K"96p%s1["`s,,>,s/+?H
-KCZ_Us81=MV#TT>]`<Q~>
-!<E0!joD+?g&Rt,g&M-Gg(+2;g&Tj\!8?-,g&Th,g&Up%!!)oM!!*#P!s%'/[email protected]!/fJ1!2eKM
-Jb$\Xs81LRU&X9;\c@6~>
-!<E0!joD4BeGoT,eGoUBeIMZ1eH".M!7fU"eH","eH#Bp!!)oH!!*#K!s$m%!5?t`!/f;,!2e<H
-KCZ_Us81=MV#TT>]`<Q~>
-!<E0!joD4BeH#W,eH#XBeHQ!'ec41Mrr<#K"TR$Pec5Ep!<;rH!<<&K"96p%s1["`s,,>,s/+?H
-KCZ_Us81=MV#TT>]`<Q~>
-!<E0!joD+?g&Rt,g&M-Gg'%K1g&Tj\rW)uP"9@-Ug&Up%!!)oM!!*#P!s%'/[email protected]!/fJ1!2eKM
-Jb$\Xs81LRU&X9;\c@6~>
-!<E0!joD4BeGoT,eGoUBeHGs'eH".MrW)uK"9?sPeH#Bp!!)oH!!*#K!s$m%!5?t`!/f;,!2e<H
-KCZ_Us81=MV#TT>]`<Q~>
-!<E0!joD4BeH#W,eH#XBeIMW0ec41Ms4,["e^a]Ms7b%Gs4,["rm_#Krm_,Ne^a]6eH#W,eH#WH
-ec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M-Gg(",:g&Tj\!8?-,g=cP\!;G1L!8?-,rn7>Prn7GSg=cP@g&M,1g&M,M
-gAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoUBeIDT0eH".M!7fU"e^XZM!;G"G!7fU"rm^uKrm_)Ne^XZ6eGoT,eGoTH
-ec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#XCec,RQec5["ec5[KeH5d$s7Y"Cs8UXIs8UXLrrL[M^XW>aMU__,VUb^!
-o"G)'qpbkGs5rIW!.Y~>
-!<E0!joD+?g&Rt,g&M-HgAV'Vg&M-,g&M-Pg&_9.!;>.H!<:dN!<:dQ!!1dR^Y/YfMV8%1VV;'$
-o"tG,qq;4Is5rIT!.Y~>
-!<E0!joD4BeGoT,eGoUCec#OQeGoU"eGoUKeH,a$!;=tC!<:UI!<:UL!!1UM^XW;aMU_\,VUb^!
-o"G)'qpbkGs5rIW!.Y~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#X1ebfBKeH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M-6gA:lPg&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoU1eb]?KeGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#XGec,W5eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M-LgA_/:g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoUGec,W5eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#XJeboK2eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M-OgAM#7g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoUJeboK2eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH5d$eb]?0eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&_9.gA:l5g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eH,a$eb]?0eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eVO8+s,,>,s/+?HKCZ_Us81=MV#TT>]`<Q~>
-!<E0!joD+?g&Rt,g5#`dg&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eVF3_eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH5d$ebfE0eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&_9.gACr5g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eH,a$ebfE0eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#XJeboK2eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M-OgAM#7g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoUJeboK2eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#XGec,W5eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M-LgA_/:g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoUGec,W5eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#XAeH#X*eH#XJeH#X=ec5[@ec5[2eH#W,eH#WHec19m^&S-0eHMcKk2s>W
-J,~>
-!<E0!joD+?g&Rt,g&M-Fg&M-/g&M-Og&M-BgA_0EgA_07g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5T
-J,~>
-!<E0!joD4BeGoT,eGoUAeGoU*eGoUJeGoU=ec,X@ec,X2eGoT,eGoTHec19m^&S-0eHMcKk2s>W
-J,~>
-!<E0!joD4BeH#W,eH#XAeH#X%eH#X<eH#X?eH#X2eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M-Fg&M-*g&M-Ag&M-Dg&M-7g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoUAeGoU%eGoU<eGoU?eGoU2eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#XBec#OJeH,^#r;QiKs8VrG#liHTec5["s4.,Ks4./LrmguIrmh&Kp=00C
-rRLrJrRLrJrm_,Nec5[5eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M-GgAM$Og&V3-qu?fP!!)lL#QWQYg&M-,!8@DPs4[JQrn@;Nrn@APp=]KH
-rS%8OrS%8Orn7GSg&M-:g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoUBeboLJeH#[#qu?fK!!)lG#QWBTeGoU"!7h&Ks4.,LrmgrIrmh#Kp=0-C
-rRLoJrRLoJrm_)NeGoU5eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#XAeH#XIeH#XJeH>j%ec5Kr"TR$Pec5X!!<;rH!<<#J!<<#J"96p%s7b%D
-s8LOYs4,["e^a]Mec41Ms4./4eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M-Fg&M-Ng&M-Og&h?/g&V!'"9@-Ug&V-+!!)oM!!)uO!!)uO!s%'/!;G1I
-!<1[^!8?-,g=cP\g&Tj\!87G9g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoUAeGoUIeGoUJeH5g%eH#Hr"9?sPeH#U!!!)oH!!)uJ!!)uJ!s$m%!;G"D
-!<1LY!7fU"e^XZMeH".M!7_)4eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#XAeH#XIeH#XJeH>j%ec5Kr"TR$Pec5X!!<;rH!<<#J!<<#Jrr;]B!<<&K
-#636(s4,["r71iIk1'J3MU__,VUb^!o"G)'qpbkGs5rIW!.Y~>
-!<E0!joD+?g&Rt,g&M-Fg&M-Ng&M-Og&h?/g&V!'"9@-Ug&V-+!!)oM!!)uO!!)uOrW)ZG!!*#P
-"p!B2!8?-,r7_/Nk1Te8MV8%1VV;'$o"tG,qq;4Is5rIT!.Y~>
-!<E0!joD4BeGoT,eGoUAeGoUIeGoUJeH5g%eH#Hr"9?sPeH#U!!!)oH!!)uJ!!)uJrW)ZB!!*#K
-"p!3(!7fU"r71fIk1'G3MU_\,VUb^!o"G)'qpbkGs5rIW!.Y~>
-!<E0!joD4BeH#W,eH#XAeHZ'(ec41Ms8CIMs4,["q:,QHec5Tu!<;rH!<<#J#liH*s4./"ec5Bo
-!<<&K%fb)0s4,["e^a]Mec42"kLBS4MU__,VUb^!o"G)'qpbkGs5rIW!.Y~>
-!<E0!joD+?g&Rt,g&M-Fg'.Q2g&Tj\!<(UR!8?-,q:YlMg&V**!!)oM!!)uO#QWT4!87G,g&Um$
-!!*#P%KP5:!8?-,g=cP\g&Th,kLon9MV8%1VV;'$o"tG,qq;4Is5rIT!.Y~>
-!<E0!joD4BeGoT,eGoUAeHQ$(eH".M!<(FM!7fU"q:,NHeH#Qu!!)oH!!)uJ#QWE*!7_)"eH#?o
-!!*#K%KP&0!7fU"e^XZMeH","kLBP4MU_\,VUb^!o"G)'qpbkGs5rIW!.Y~>
-!<E0!joD4BeH#W,eH#X@ec5[Lec#OIec5[EeH5d$s8LRIs8UXIs8LRKs8LRKs7k.Bs8UXLs8CLJ
-s8UXLrrUaNs6.u5s,,>,s/+?HKCZ_Us81=MV#TT>]`<Q~>
-!<E0!joD+?g&Rt,g&M-EgA_0QgAM$NgA_0Jg&_9.!<1^N!<:dN!<1^P!<1^P!;P:G!<:dQ!<(XO
-!<:dQ!!:jS!9i,:!/fJ1!2eKMJb$\Xs81LRU&X9;\c@6~>
-!<E0!joD4BeGoT,eGoU@ec,XLeboLIec,XEeH,a$!<1OI!<:UI!<1OK!<1OK!;P+B!<:UL!<(IJ
-!<:UL!!:[N!9hr5!/f;,!2e<HKCZ_Us81=MV#TT>]`<Q~>
-!<E0!joD4BeH#W,eH#X5eH#WFeH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M-:g&M,Kg&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoU5eGoTFeGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#X7ec5[JebfC,ebfBoeH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M-<gA_0OgA:m1gA:ltg&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoU7ec,XJeb]@,eb]?oeGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W5ec,XGeH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M,1g&M,:gA_0Lg&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT5ec,XGeGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W5eboLGeH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M,1g&M,:gAM$Lg&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT5eboLGeGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W4eb]@HeH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M,1g&M,9gA:mMg&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT4eb]@HeGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eU[^_!!*%rec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g496c!2eKMJb$\Xs81LRU&X9;\c@6~>
-!<E0!joD4BeGoT,eU[^^!2e<HKCZ_Us81=MV#TT>]`<Q~>
-!<E0!joD4BeH#W,eH#W,eH#W4eb]@HeH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M,1g&M,9gA:mMg&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT4eb]@HeGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W4ec#RHeH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M,1g&M,9gAV*Mg&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT4ec#RHeGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W5ec,XGeH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M,1g&M,:gA_0Lg&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT5ec,XGeGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#X)eH#XBec5Z`eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M-.g&M-GgA_/eg&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoU)eGoUBec,W`eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#X)eH#XAeH#W`eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M-.g&M-Fg&M,eg&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoU)eGoUAeGoT`eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#XAec5XPec42"ec,RMec5[KeH>j%s8W)KrVulIs8W&Jrr9^_!<7r,!<8qH
-s+BmUs8VuH"f21\k.LbF~>
-!<E0!joD+?g&Rt,g&M-FgA_-Ug&Th,gAV'Rg&M-Pg&h?/!!*#Pr;ciNrrE#OrW'[d!!%o1!!&nM
-s+0aXs8VuM"ektYk.1PC~>
-!<E0!joD4BeGoT,eGoUAec,UPeH","ec#OMeGoUKeH5g%!!*#Kr;ciIrrE#JrW'[_!!%o,!!&nH
-s+BmUs8VuH"f21\k.LbF~>
-!<E0!joD4BeH#W,eH#XBeH>j%ec5X!!<;rH!<<&K"96p%s8LOKs8CISs4,["e^a]Mec3A6!<7r,
-!<8qHs+BmUs8VuH"f21\k.LbF~>
-!<E0!joD+?g&Rt,g&M-Gg&h?/g&V-+!!)oM!!*#P!s%'/!<1[P!<(UX!8?-,g=cP\g&Sk@!!%o1
-!!&nMs+0aXs8VuM"ektYk.1PC~>
-!<E0!joD4BeGoT,eGoUBeH5g%eH#U!!!)oH!!*#K!s$m%!<1LK!<(FS!7fU"e^XZMeH!>6!!%o,
-!!&nHs+BmUs8VuH"f21\k.LbF~>
-!<E0!joD4BeH#W,eH#XBeH>j%ec5X!!<<#Jrr;uJ"96p%s8LOKs8CLIs8LONs4,["^=<5`MU__,
-VUb^!o"G)'qpbkGs5rIW!.Y~>
-!<E0!joD+?g&Rt,g&M-Gg&h?/g&V-+!!)uOrW)rO!s%'/!<1[P!<(XN!<1[S!8?-,^=iPeMV8%1
-VV;'$o"tG,qq;4Is5rIT!.Y~>
-!<E0!joD4BeGoT,eGoUBeH5g%eH#U!!!)uJrW)rJ!s$m%!<1LK!<(II!<1LN!7fU"^=<2`MU_\,
-VUb^!o"G)'qpbkGs5rIW!.Y~>
-!<E0!joD4BeH#W,eH#XBeH>j%ec5X!!<<&K"96p%s8LONs4,["rm_MYe^a]Ms4,["e^a]Mec3A6
-!<7r,!<8qHs+BmUs8VuH"f21\k.LbF~>
-!<E0!joD+?g&Rt,g&M-Gg&h?/g&V-+!!*#P!s%'/!<1[S!8?-,rn7h^g=cP\!8?-,g=cP\g&Sk@
-!!%o1!!&nMs+0aXs8VuM"ektYk.1PC~>
-!<E0!joD4BeGoT,eGoUBeH5g%eH#U!!!*#K!s$m%!<1LN!7fU"rm_JYe^XZM!7fU"e^XZMeH!>6
-!!%o,!!&nHs+BmUs8VuH"f21\k.LbF~>
-!<E0!joD4BeH#W,eH#XAec,UKec#OJec5XNec42!rrUaNs8LRKs8LRKs8CLJrrL[M^XW>aMU__,
-VUb^!o"G)'qpbkGs5rIW!.Y~>
-!<E0!joD+?g&Rt,g&M-FgAV*PgAM$OgA_-Sg&Tk+!!:jS!<1^P!<1^P!<(XO!!1dR^Y/YfMV8%1
-VV;'$o"tG,qq;4Is5rIT!.Y~>
-!<E0!joD4BeGoT,eGoUAec#RKeboLJec,UNeH"/!!!:[N!<1OK!<1OK!<(IJ!!1UM^XW;aMU_\,
-VUb^!o"G)'qpbkGs5rIW!.Y~>
-!<E0!joD4BeH#W,eH#X?eH#W<eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M-Dg&M,Ag&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoU?eGoT<eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#XBec,T:eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M-GgAV)?g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoUBec#Q:eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#XGec,W5eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M-LgA_/:g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoUGec,W5eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#XJeboK2eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M-OgAM#7g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoUJeboK2eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH5d$eb]?0eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&_9.gA:l5g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eH,a$eb]?0eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eU[^_!!*%rec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g496c!2eKMJb$\Xs81LRU&X9;\c@6~>
-!<E0!joD4BeGoT,eU[^^!2e<HKCZ_Us81=MV#TT>]`<Q~>
-!<E0!joD4BeH#W,eH5d$ebfE0eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&_9.gACr5g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eH,a$ebfE0eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#XJeboK2eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M-OgAM#7g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoUJeboK2eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#XGec,W5eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M-LgA_/:g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoUGec,W5eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#X@ec,X&eGoUJeGoTjeH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M-EgA_0+g&M-Og&M,og&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoU@ec5[&eH#XJeH#WjeGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#X?eGoU!eGoTjeH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M-Dg&M-&g&M,og&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoU?eH#X!eH#WjeGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#XAec#RJec,XDec,XJec,XLec,USeH".M!!(OLrRLoJrmgrIb1-LlMU__,
-VUb^!o"G)'qpbkGs5rIW!.Y~>
-!<E0!joD+?g&Rt,g&M-FgAV*OgA_0IgA_0OgA_0QgA_-Xg&Tj\!!(^QrS%8Orn@;Nb1ZgqMV8%1
-VV;'$o"tG,qq;4Is5rIT!.Y~>
-!<E0!joD4BeGoT,eGoUAec,UJec5[Dec5[Jec5[Lec5XSec41Ms8UXLrRLrJrmguIb1-IlMU_\,
-VUb^!o"G)'qpbkGs5rIW!.Y~>
-!<E0!joD4BeH#W,eH#XBeHl6+eH".M!7fU"q:-2[e^XZMeH".M!7_)"!7_)"!7_)"!<(FJ!<(FJ
-!6E[js,,>,s/+?HKCZ_Us81=MV#TT>]`<Q~>
-!<E0!joD+?g&Rt,g&M-Gg'Ic5g&Tj\!8?-,q:ZP`g=cP\g&Tj\!87G,!87G,!87G,!<(UO!<(UO
-!6Ejo!/fJ1!2eKMJb$\Xs81LRU&X9;\c@6~>
-!<E0!joD4BeGoT,eGoUBeHu9+ec41Ms4,["q:-5[e^a]Mec41Ms4./"s4./"s4./"s8CIJs8CIJ
-s2`^j!/f;,!2e<HKCZ_Us81=MV#TT>]`<Q~>
-!<E0!joD4BeH#W,eH#XBeHl6+eH".M!7fU"q:,HFr7);Xe^XZM!7_)"!7_)"!7_)JeGoUJeGoTj
-eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M-Gg'Ic5g&Tj\!8?-,q:YfKr7VY]g=cP\!87G,!87G,!87GOg&M-Og&M,o
-g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoUBeHu9+ec41Ms4,["q:,KFr7)>Xe^a]Ms4./"s4./"s4./JeH#XJeH#Wj
-eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#XBeHl6+eH".M!7fU"q:-2[e^XZMeH".M!7_)"!7_)"!7_)"!<(FJ!<(FM
-!7fU"bLHUmMU__,VUb^!o"G)'qpbkGs5rIW!.Y~>
-!<E0!joD+?g&Rt,g&M-Gg'Ic5g&Tj\!8?-,q:ZP`g=cP\g&Tj\!87G,!87G,!87G,!<(UO!<(UR
-!8?-,bLuprMV8%1VV;'$o"tG,qq;4Is5rIT!.Y~>
-!<E0!joD4BeGoT,eGoUBeHu9+ec41Ms4,["q:-5[e^a]Mec41Ms4./"s4./"s4./"s8CIJs8CIM
-s4,["bLHRmMU_\,VUb^!o"G)'qpbkGs5rIW!.Y~>
-!<E0!joD4BeH#W,eH#XAec,UQeH".M!!)cDrrE#JrrE)L!s$jOec#OPeH","!7guIrmh#Kb1-Ll
-MU__,VUb^!o"G)'qpbkGs5rIW!.Y~>
-!<E0!joD+?g&Rt,g&M-FgA_-Vg&Tj\!!)cIrrE#OrrE)Q!s%$TgAV'Ug&Th,!8@>Nrn@APb1Zgq
-MV8%1VV;'$o"tG,qq;4Is5rIT!.Y~>
-!<E0!joD4BeGoT,eGoUAec5XQec41Ms8ViDs8W&Js8W,L"96pOec,RPec42"s4.&Irmh&Kb1-Il
-MU_\,VUb^!o"G)'qpbkGs5rIW!.Y~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#X7eb]?EeH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M-<gA:lJg&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoU7ebfBEeGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#X5ec5[,eH#XHeH#XIec5[#eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M-:gA_01g&M-Mg&M-NgA_0(g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoU5ec,X,eGoUHeGoUIec,X#eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#X4eH#X,eH#XAeH#X#eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M-9g&M-1g&M-Fg&M-(g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoU4eGoU,eGoUAeGoU#eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#XBeH,^#rr<#Ks8W#I!<<#Js8W)Ks8W#Irr;uJs8VlErVulIs8W&Jrr:R"
-!<7r,!<8qHs+BmUs8VuH"f21\k.LbF~>
-!<E0!joD+?g&Rt,g&M-Gg&V3-rW)uPrrDuN!!)uOrrE&PrrDuNrW)rOrrDiJr;ciNrrE#OrW(O'
-!!%o1!!&nMs+0aXs8VuM"ektYk.1PC~>
-!<E0!joD4BeGoT,eGoUBeH#[#rW)uKrrDuI!!)uJrrE&KrrDuIrW)rJrrDiEr;ciIrrE#JrW(O"
-!!%o,!!&nHs+BmUs8VuH"f21\k.LbF~>
-!<E0!joD4BeH#W,eH#XAeH#XJeH>j%ec5Tu!<<&K"96p%s8CIJs8LOKs8:CLs4,["psfBEqpb]H
-rm_,Ne^a]NeH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M-Fg&M-Og&h?/g&V**!!*#P!s%'/!<(UO!<1[P!;tOQ!8?-,pt>]Jqq;#M
-rn7GSg=cPXg&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoUAeGoUJeH5g%eH#Qu!!*#K!s$m%!<(FJ!<1LK!;t@L!7fU"psf?EqpbZH
-rm_)Ne^XZNeGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#XAeH#XJec,UHeH#XKec,UJec,UIec5[Kec,UCeH#XHeH#XKeH>j%ec44N
-!<7r,!<8qHs+BmUs8VuH"f21\k.LbF~>
-!<E0!joD+?g&Rt,g&M-Fg&M-OgAV*Mg&M-PgAV*OgAV*NgA_0PgAV*Hg&M-Mg&M-Pg&h?/g&T^X
-!!%o1!!&nMs+0aXs8VuM"ektYk.1PC~>
-!<E0!joD4BeGoT,eGoUAeGoUJec#RHeGoUKec#RJec#RIec,XKec#RCeGoUHeGoUKeH5g%eH"1N
-!!%o,!!&nHs+BmUs8VuH"f21\k.LbF~>
-!<E0!joD4BeH#W,eH#XAeH#XJeH>j%ec5Tu!<<&K#liH*s4./"ec5Ns#636(s4,["psfKHe^a^!
-eH#XKeH>j%ec44N!<7r,!<8qHs+BmUs8VuH"f21\k.LbF~>
-!<E0!joD+?g&Rt,g&M-Fg&M-Og&h?/g&V**!!*#P#QWT4!87G,g&V$("p!B2!8?-,pt>fMg=cQ+
-g&M-Pg&h?/g&T^X!!%o1!!&nMs+0aXs8VuM"ektYk.1PC~>
-!<E0!joD4BeGoT,eGoUAeGoUJeH5g%eH#Qu!!*#K#QWE*!7_)"eH#Ks"p!3(!7fU"psfHHe^X[!
-eGoUKeH5g%eH"1N!!%o,!!&nHs+BmUs8VuH"f21\k.LbF~>
-!<E0!joD4BeH#W,eH#XBec#OIec5[KeboIIec5[Kec5XOec41Mrr;rIs8VfCs8W,Lr;ZfIs8N,M
-s4>d$s,,>,s/+?HKCZ_Us81=MV#TT>]`<Q~>
-!<E0!joD+?g&Rt,g&M-GgAM$NgA_0PgACsNgA_0PgA_-Tg&Tj\rW)oNrrDcHrrE)QquHcNrr<)R
-!8#p)!/fJ1!2eKMJb$\Xs81LRU&X9;\c@6~>
-!<E0!joD4BeGoT,eGoUBeboLIec,XKebfFIec,XKec,UOeH".MrW)oIrrDcCrrE)LquHcIrr<)M
-!8#a$!/f;,!2e<HKCZ_Us81=MV#TT>]`<Q~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#WnebfBceH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M,sgA:lhg&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoTneb]?ceGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W5ec,XGeH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M,1g&M,:gA_0Lg&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT5ec,XGeGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W5eboLGeH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M,1g&M,:gAM$Lg&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT5eboLGeGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W4eb]@HeH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M,1g&M,9gA:mMg&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT4eb]@HeGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eU[^_!!*%rec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g496c!2eKMJb$\Xs81LRU&X9;\c@6~>
-!<E0!joD4BeGoT,eU[^^!2e<HKCZ_Us81=MV#TT>]`<Q~>
-!<E0!joD4BeH#W,eH#W,eH#W4eb]@HeH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M,1g&M,9gA:mMg&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT4eb]@HeGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W4ec#RHeH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M,1g&M,9gAV*Mg&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT4ec#RHeGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W5ec,XGeH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M,1g&M,:gA_0Lg&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT5ec,XGeGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#X@ec5[Eec5[DeH#X=eH#X%eH#XHeH#X@eH#W,eH#WHec19m^&S-0eHMcK
-k2s>WJ,~>
-!<E0!joD+?g&Rt,g&M-EgA_0JgA_0Ig&M-Bg&M-*g&M-Mg&M-Eg&M,1g&M,MgAc`p_Z0Z5g'+2M
-k2s5TJ,~>
-!<E0!joD4BeGoT,eGoU@ec,XEec,XDeGoU=eGoU%eGoUHeGoU@eGoT,eGoTHec19m^&S-0eHMcK
-k2s>WJ,~>
-!<E0!joD4BeH#W,eH#X?eH#XDeH#XDeH#X=eH#X%eH#X9eH#W,eH#WHec19m^&S-0eHMcKk2s>W
-J,~>
-!<E0!joD+?g&Rt,g&M-Dg&M-Ig&M-Ig&M-Bg&M-*g&M->g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5T
-J,~>
-!<E0!joD4BeGoT,eGoU?eGoUDeGoUDeGoU=eGoU%eGoU9eGoT,eGoTHec19m^&S-0eHMcKk2s>W
-J,~>
-!<E0!joD4BeH#W,eH#XAec,UJec5[IeH#XJec5[Kec#OIec5[Eec#OJeH,^#rr3&Ms8W)K"96pO
-s8CLIs8UXLs8:FIs8LRIs8LRKs8CLJs8UURs4./Le^a\WeH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M-FgAV*OgA_0Ng&M-OgA_0PgAM$NgA_0JgAM$Og&V3-rW!#R!!*#P!s%$T
-!<(XN!<:dQ!;tRN!<1^N!<1^P!<(XO!<:aW!87DQg=cOag&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoUAec#RJec,XIeGoUJec,XKeboLIec,XEeboLJeH#[#rW!#M!!*#K!s$jO
-!<(II!<:UL!;tCI!<1OI!<1OK!<(IJ!<:RR!7_&Le^XYWeGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#XBeHu9+ec41Ms4,["rRCoJrm_,Ne^a^!eH#XJeH>j%ec5Ep!<;uI!<;rH
-!<<&K#636(s4,["qUGTGrm_,Ne^a^!eH#XHeH#XKeI2E-ec41Ms4,["ec1NW!<8qHs+BmUs8VuH
-"f21\k.LbF~>
-!<E0!joD+?g&Rt,g&M-Gg'Ic5g&Tj\!8?-,rRq5Orn7GSg=cQ+g&M-Og&h?/g&Up%!!)rN!!)oM
-!!*#P"p!B2!8?-,qUtoLrn7GSg=cQ+g&M-Mg&M-Pg'[o7g&Tj\!8?-,g&R#a!!&nMs+0aXs8VuM
-"ektYk.1PC~>
-!<E0!joD4BeGoT,eGoUBeHl6+eH".M!7fU"rRClJrm_)Ne^X[!eGoUJeH5g%eH#Bp!!)rI!!)oH
-!!*#K"p!3(!7fU"qUGQGrm_)Ne^X[!eGoUHeGoUKeI)B-eH".M!7fU"eGtKW!!&nHs+BmUs8VuH
-"f21\k.LbF~>
-!<E0!joD4BeH#W,eH#XBeHQ!'ec41Mrr;oH!<<&Krr;rI!<<#Jrr;`C!<;uI!<<#Jrr;uJ"96p%
-s8LRKs8LRJs8LOKs81=Hs81=Hs8LOVs4,["e^a]Mec42"MU__,VUb^!o"G)'qpbkGs5rIW!.Y~>
-!<E0!joD+?g&Rt,g&M-Gg'%K1g&Tj\rW)lM!!*#PrW)oN!!)uOrW)]H!!)rN!!)uOrW)rO!s%'/
-!<1^P!<1^O!<1[P!;kIM!;kIM!<1[[!8?-,g=cP\g&Th,MV8%1VV;'$o"tG,qq;4Is5rIT!.Y~>
-!<E0!joD4BeGoT,eGoUBeHGs'eH".MrW)lH!!*#KrW)oI!!)uJrW)]C!!)rI!!)uJrW)rJ!s$m%
-!<1OK!<1OJ!<1LK!;k:H!;k:H!<1LV!7fU"e^XZMeH","MU_\,VUb^!o"G)'qpbkGs5rIW!.Y~>
-!<E0!joD4BeH#W,eH#XBeHu9+ec41Ms4,["rRCoJrm_,Ne^a^!eHl3*ec42"e^a]peHZ'(ec41M
-s8LONs4,["rm_,Ne^a]teHQ!'s4,["rm_,Ne^a^!eH>j%ec5X!!<<&K$iec-s4,["e^a]Ms,,>,
-s/+?HKCZ_Us81=MV#TT>]`<Q~>
-!<E0!joD+?g&Rt,g&M-Gg'Ic5g&Tj\!8?-,rRq5Orn7GSg=cQ+g'@]4g&Th,g=cQ%g'.Q2g&Tj\
-!<1[S!8?-,rn7GSg=cQ)g'%K1!8?-,rn7GSg=cQ+g&h?/g&V-+!!*#P$NSo7!8?-,g=cP\!/fJ1
-!2eKMJb$\Xs81LRU&X9;\c@6~>
-!<E0!joD4BeGoT,eGoUBeHl6+eH".M!7fU"rRClJrm_)Ne^X[!eHc0*eH","e^XZpeHQ$(eH".M
-!<1LN!7fU"rm_)Ne^XZteHGs'!7fU"rm_)Ne^X[!eH5g%eH#U!!!*#K$NS`-!7fU"e^XZM!/f;,
-!2e<HKCZ_Us81=MV#TT>]`<Q~>
-!<E0!joD4BeH#W,eH#XAec5XQec41Ms8W)Kr;ZfIs8W#Is8W)Ks8VfCs8W,LrVuoJs8N/Ns4.,K
-"4dGOec,UJec5XMec5X!s8W#Is8W,Lr;ZfIs8W,Lrr2uKrr7l+!<8qHs+BmUs8VuH"f21\k.LbF~>
-!<E0!joD+?g&Rt,g&M-FgA_-Vg&Tj\!!*#PquHcNrrDuNrrE&PrrDcHrrE)Qr;clOrr<,S!8@DP
-"53_TgAV*OgA_-Rg&V-+rrDuNrrE)QquHcNrrE)QrVurPrW%i0!!&nMs+0aXs8VuM"ektYk.1PC~>
-!<E0!joD4BeGoT,eGoUAec,UQeH".M!!*#KquHcIrrDuIrrE&KrrDcCrrE)Lr;clJrr<,N!7h&K
-"4[AOec#RJec,UMeH#U!rrDuIrrE)LquHcIrrE)LrVurKrW%i+!!&nHs+BmUs8VuH"f21\k.LbF~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#WtebfB]eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M-$gA:lbg&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoTteb]?]eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W5ec,XGeH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M,:gA_0Lg&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT5ec,XGeGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W5eboLGeH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M,:gAM$Lg&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT5eboLGeGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W4eb]@HeH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M,9gA:mMg&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT4eb]@HeGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eVO8+s,,>,s/+?HKCZ_Us81=MV#TT>]`<Q~>
-!<E0!joD+?g&Rt,g5#`dg&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eVF3_eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W4eb]@HeH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M,9gA:mMg&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT4eb]@HeGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W4ec#RHeH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M,9gAV*Mg&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT4ec#RHeGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W5ec,XGeH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M,:gA_0Lg&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT5ec,XGeGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#X4ec,X9eGoT^eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M-9gA_0>g&M,cg&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoU4ec5[9eH#W^eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#X3eGoU9eGoT^eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M-8g&M->g&M,cg&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoU3eH#X9eH#W^eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#XAec,XLeH5g%!!)uJrW)`DrrE)Lrr<2P!!(R"r;ciIrrE&K!<C[L!6`mm
-s,,>,s/+?HKCZ_Us81=MV#TT>]`<Q~>
-!<E0!joD+?g&Rt,g&M-FgA_0Qg&h?/!!)uOrW)`IrrE)Qrr<2U!!(a,r;ciNrrE&P!<CjQ!6a'r
-!/fJ1!2eKMJb$\Xs81LRU&X9;\c@6~>
-!<E0!joD4BeGoT,eGoUAec5[LeH>j%s8W&Jrr;cDs8W,Ls8N5Ps8UX"rVulIs8W)K!WU^Ls3&pm
-!/f;,!2e<HKCZ_Us81=MV#TT>]`<Q~>
-!<E0!joD4BeH#W,eH#XBeIMZ1eH".M!7fU"e^XZMeH#Eq#lrN+!7fU"e^X[!eGoUJeH5g%eH#U!
-!!(*j!<7r,!<8qHs+BmUs8VuH"f21\k.LbF~>
-!<E0!joD+?g&Rt,g&M-Gg(+2;g&Tj\!8?-,g=cP\g&Us&#lr]5!8?-,g=cQ+g&M-Og&h?/g&V-+
-!!(*o!!%o1!!&nMs+0aXs8VuM"ektYk.1PC~>
-!<E0!joD4BeGoT,eGoUBeIV]1ec41Ms4,["e^a]Mec5Hq$3/Q+s4,["e^a^!eH#XJeH>j%ec5X!
-!<:-j!!%o,!!&nHs+BmUs8VuH"f21\k.LbF~>
-!<E0!joD4BeH#W,eH#XBec#RJeHl6+eH".M!7fU"q:,cOe^XZMeH".M!<1LK!<(II!<(FJ!6E[j
-s,,>,s/+?HKCZ_Us81=MV#TT>]`<Q~>
-!<E0!joD+?g&Rt,g&M-GgAV*Og'Ic5g&Tj\!8?-,q:Z,Tg=cP\g&Tj\!<1[P!<(XN!<(UO!6Ejo
-!/fJ1!2eKMJb$\Xs81LRU&X9;\c@6~>
-!<E0!joD4BeGoT,eGoUBec,UJeHu9+ec41Ms4,["q:,fOe^a]Mec41Ms8LOKs8CLIs8CIJs2`^j
-!/f;,!2e<HKCZ_Us81=MV#TT>]`<Q~>
-!<E0!joD4BeH#W,eH#XBeIMZ1eH".M!7fU"e^XZMeH#Eq#lrN+!7fU"e^X[!eHc0*eH","e^X[!
-eGoTjeH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M-Gg(+2;g&Tj\!8?-,g=cP\g&Us&#lr]5!8?-,g=cQ+g'@]4g&Th,g=cQ+
-g&M,og&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoUBeIV]1ec41Ms4,["e^a]Mec5Hq$3/Q+s4,["e^a^!eHl3*ec42"e^a^!
-eH#WjeGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#XAec,XLec#OSeGoU"eGoU"!;Y1F!<(IJ!!1UMrmh#Krmh#KrmgrIb1-Ll
-MU__,VUb^!o"G)'qpbkGs5rIW!.Y~>
-!<E0!joD+?g&Rt,g&M-FgA_0QgAV'Xg&M-,g&M-,!;Y@K!<(XO!!1dRrn@APrn@APrn@;Nb1Zgq
-MV8%1VV;'$o"tG,qq;4Is5rIT!.Y~>
-!<E0!joD4BeGoT,eGoUAec5[Lec,RSec5["ec5["s7t4Fs8CLJrrL[Mrmh&Krmh&KrmguIb1-Il
-MU_\,VUb^!o"G)'qpbkGs5rIW!.Y~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#X1eb]?KeH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M-6gA:lPg&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoU1ebfBKeGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M,1g&M,1g&M,MgAc`p_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19m^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19ks81=MV#TT>]`<Q~>
-!<E0!joD+?g&Rt,g&M,1g&M,1g&M,MgAc`ns81LRU&X9;\c@6~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19ks81=MV#TT>]`<Q~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec17%^%D=+KE(uKeHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M,1g&M,1g&M,MgAc^(_Y!j0JcGcIg'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec17%^%D=+KE(uKeHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec17'^&S--ec17'^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M,1g&M,1g&M,MgAc^*_Z0Z2gAc^*_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec17'^&S--ec17'^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec1:%^&S-.ec17'^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M,1g&M,1g&M,MgAca(_Z0Z3gAc^*_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec1:%^&S-.ec17'^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec1:%^&S-/ec1:%^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M,1g&M,1g&M,MgAca(_Z0Z4gAca(_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec1:%^&S-/ec1:%^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec1:$^&S-0ec1:%^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M,1g&M,1g&M,MgAca'_Z0Z5gAca(_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec1:$^&S-0ec1:%^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec1:$^&S-1ec1:$^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M,1g&M,1g&M,MgAca'_Z0Z6gAca'_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec1:$^&S-1ec1:$^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec1:#^&S-2ec1:$^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M,1g&M,1g&M,MgAca&_Z0Z7gAca'_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec1:#^&S-2ec1:$^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec1:#^&S-3ec1:#^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M,1g&M,1g&M,MgAca&_Z0Z8gAca&_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec1:#^&S-3ec1:#^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec1:"^&S-4ec1:#^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M,1g&M,1g&M,MgAca%_Z0Z9gAca&_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec1:"^&S-4ec1:#^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec1:"^&S*6eUrMP^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M,1g&M,1g&M,MgAca%_Z0W;g4=hQ_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec1:"^&S*6eUrMP^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec1:!]`A*3KD`F_s81=MV#TT>]`<Q~>
-!<E0!joD+?g&Rt,g&M,1g&M,1g&M,MgAca$_>sW8Jc*Cbs81LRU&X9;\c@6~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec1:!]`A*3KD`F_s81=MV#TT>]`<Q~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec1:!]`S4dKDW@^s81=MV#TT>]`<Q~>
-!<E0!joD+?g&Rt,g&M,1g&M,1g&M,MgAca$_?0agJc!=as81LRU&X9;\c@6~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec1:!]`S4dKDW@^s81=MV#TT>]`<Q~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19u^&N`^^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M,1g&M,1g&M,MgAca#_Z,2a_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19u^&N`^^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19u]`<]]^&S-0eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M,1g&M,1g&M,MgAca#_>o/`_Z0Z5g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19u]`<]]^&S-0eHMcKk2s>WJ,~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHec19ks81=MV#TT>]`<Q~>
-!<E0!joD+?g&Rt,g&M,1g&M,1g&M,MgAc`ns81LRU&X9;\c@6~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHec19ks81=MV#TT>]`<Q~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#WHeGt6js81=MV#TT>]`<Q~>
-!<E0!joD+?g&Rt,g&M,1g&M,1g&M,Mg&Q]ms81LRU&X9;\c@6~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoTHeGt6js81=MV#TT>]`<Q~>
-!<E0!joD4BeH#W,eH#W,eH#W,eH#W/eHMcKk2s>WJ,~>
-!<E0!joD+?g&Rt,g&M,1g&M,1g&M,4g'+2Mk2s5TJ,~>
-!<E0!joD4BeGoT,eGoT,eGoT,eGoT/eHMcKk2s>WJ,~>
-!<E0!joD3.eUc8%eW&)_V#TT>]`<Q~>
-!<E0!joD*+g4@t/g5XeiU&X9;\c@6~>
-!<E0!joD3.eUc8%eW&)_V#TT>]`<Q~>
-!<E0!joD4SeU`@(K7SZXKBC\fV#TT>]`<Q~>
-!<E0!joD+Pg4=g+JUrBTJ`bYiU&X9;\c@6~>
-!<E0!joD4SeU`@(K7SZXKBC\fV#TT>]`<Q~>
-!<E0!joD4SeU`@(K7SZYK)kr6eHMcKk2s>WJ,~>
-!<E0!joD+Pg4=g+JUrBUJH5`4g'+2Mk2s5TJ,~>
-!<E0!joD4SeU`@(K7SZYK)kr6eHMcKk2s>WJ,~>
-!<E0!joD4Sec19n]`J/HJcC<$`W(q2s8V`)s8V63"f21\k.LbF~>
-!<E0!joD+PgAc`q_?'\RJcC<$`W(q7s8V`.s8V68"ektYk.1PC~>
-!<E0!joD4Sec19n]`J/HJcC<$`W(q2s8V`)s8V63"f21\k.LbF~>
-!<E0!joD4Sec19p^&S*5K=uj9JcEai!/$9ErVuT)s8V63"f21\k.LbF~>
-!<E0!joD+PgAc`s_Z0W:J\m!<JcEai!.g-HrVuT.s8V68"ektYk.1PC~>
-!<E0!joD4Sec19p^&S*5K=uj9JcEai!/$9ErVuT)s8V63"f21\k.LbF~>
-!<Bh3SGUk:KD3(Ys8R]Q^&S+`eUc8mec18]^&.j)^&S,peHMJVS=BQZJ,~>
-!<B_0RJY_<JbR%\s8RWO_Z0Xeg4@u"gAc_`_YaB._Z0Yug'*nUR@+$TJ,~>
-!<Bh3SGUk:KD3(Ys8R]Q^&S+`eUc8mec18]^&.j)^&S,peHMJVS=BQZJ,~>
-!!)uB!1`r:s+C-\rVm&OK7gl;s+/^Oe]HAAK8mSEs8UXJs8'G/s5qi8SB\a\S,e'~>
-!!)u?!1E`<s+1!_rVm&TJUt]<s+/mTg<&(KJW7PHs8UgOs8'V4s5r#=REE+PR/ha~>
-!!)uB!1`r:s+C-\rVm&OK7gl;s+/^Oe]HAAK8mSEs8UXJs8'G/s5qi8SB\a\S,e'~>
-!<CCD]`=T"ec1:!^&A!1ec17'^&S+`eUc8mec18]^&S-2ec#OG^&S,peHMJf]tKp9J,~>
-!<C:A\cA/qgAca$_YsN6gAc^*_Z0Xeg4@u"gAc_`_Z0Z7gAV'L_Z0Yug'*ne]"4:0J,~>
-!<CCD]`=T"ec1:!^&A!1ec17'^&S+`eUc8mec18]^&S-2ec#OG^&S,peHMJf]tKp9J,~>
-!<CCD]`=T"ec1:#^&A!/ec17'^&S+`eUc8mec18]^&S-0ec#OI^&S,peHMJf]tKp9J,~>
-!<C:A\cA/qgAca&_YsN4gAc^*_Z0Xeg4@u"gAc_`_Z0Z5gAV'N_Z0Yug'*ne]"4:0J,~>
-!<CCD]`=T"ec1:#^&A!/ec17'^&S+`eUc8mec18]^&S-0ec#OI^&S,peHMJf]tKp9J,~>
-!<CCD]`=T"ec1:%^&A!-ec17'^&S+`eUc8mec18]^&S-.ec#LL^&S,peHMJf]tKp9J,~>
-!<C:A\cA/qgAca(_YsN2gAc^*_Z0Xeg4@u"gAc_`_Z0Z3gAV$Q_Z0Yug'*ne]"4:0J,~>
-!<CCD]`=T"ec1:%^&A!-ec17'^&S+`eUc8mec18]^&S-.ec#LL^&S,peHMJf]tKp9J,~>
-!<CCD]`=T"ebb!oec17'^&S+`eUc8mec18]^&S--ebt.#s5qi8SB\a\S,e'~>
-!<C:A\cA/qgA?HrgAc^*_Z0Xeg4@u"gAc_`_Z0Z2gAQU&s5r#=REE+PR/ha~>
-!<CCD]`=T"ebb!oec17'^&S+`eUc8mec18]^&S--ebt.#s5qi8SB\a\S,e'~>
-!<CCD]`=T"ec1:%^&<T[ec17'^&S+`eUc8mec18]^&S-.ebt+%^&S,peHMJf]tKp9J,~>
-!<C:A\cA/qgAca(_Yo&^gAc^*_Z0Xeg4@u"gAc_`_Z0Z3gAQR(_Z0Yug'*ne]"4:0J,~>
-!<CCD]`=T"ec1:%^&<T[ec17'^&S+`eUc8mec18]^&S-.ebt+%^&S,peHMJf]tKp9J,~>
-!<CCD]`=T"ec1:#^&<T]ec17'^&S+`eUc8mec18]^&S-0ebt."^&S,peHMJf]tKp9J,~>
-!<C:A\cA/qgAca&_Yo&`gAc^*_Z0Xeg4@u"gAc_`_Z0Z5gAQU%_Z0Yug'*ne]"4:0J,~>
-!<CCD]`=T"ec1:#^&<T]ec17'^&S+`eUc8mec18]^&S-0ebt."^&S,peHMJf]tKp9J,~>
-!<CCD]`=T"ec1:!^&<T_ec17'^&S+`eUc8mec18]^&S-2ebt-u^&S,peHMJf]tKp9J,~>
-!<C:A\cA/qgAca$_Yo&bgAc^*_Z0Xeg4@u"gAc_`_Z0Z7gAQU#_Z0Yug'*ne]"4:0J,~>
-!<CCD]`=T"ec1:!^&<T_ec17'^&S+`eUc8mec18]^&S-2ebt-u^&S,peHMJf]tKp9J,~>
-!<CCD]`=T"ec19t^&<QeeUrLfs8RZ#J^qlms+?<Es8W,LrIas[s8V63"e<iN]po(Q~>
-!<C:A\cA/qgAca"_Yo#hg4=gls8RZ(J_J6"s+-0Hs8W,QrIOg^s8V68"e!NE\sWPK~>
-!<CCD]`=T"ec19t^&<QeeUrLfs8RZ#J^qlms+?<Es8W,LrIas[s8V63"e<iN]po(Q~>
-!<CCD]`=T"ec19r^&3Ka^&S+`eUc8mec18]^&S-2KD<.[s5qi8SB\a\S,e'~>
-!<C:A\cA/qgAc`u_Yerd_Z0Xeg4@u"gAc_`_Z0Z7Jb[+^s5r#=REE+PR/ha~>
-!<CCD]`=T"ec19r^&3Ka^&S+`eUc8mec18]^&S-2KD<.[s5qi8SB\a\S,e'~>
-!<CCD]`=T"ec19p^&EWc^&S+`K7SZqK8mSEs8R`F^&S,peHMJf]tKp9J,~>
-!<C:A\cA/qgAc`s_Z#)f_Z0XeJUrBmJW7PHs8RZD_Z0Yug'*ne]"4:0J,~>
-!<CCD]`=T"ec19p^&EWc^&S+`K7SZqK8mSEs8R`F^&S,peHMJf]tKp9J,~>
-!<CCD]`=T"ec19n]`Ni"s+,fRK>rP']`J.coY(;)k1'X*c+Uf\!.Y~>
-!<C:A\cA/qgAc`q_?,;*s+,`PJ]<8#_?'[foYUY.k1U!,b.>0P!.Y~>
-!<CCD]`=T"ec19n]`Ni"s+,fRK>rP']`J.coY(;)k1'X*c+Uf\!.Y~>
-!<CCD]`=T"ec18Qs+13$s02OceHMJf]tKp9J,~>
-!<C:A\cA/qgAc_Ts+13$s02Ocg'*ne]"4:0J,~>
-!<CCD]`=T"ec18Qs+13$s02OceHMJf]tKp9J,~>
-!<CCD]`=T"eGt5Qs+13$s0)IbeHMJf]tKp9J,~>
-!<C:A\cA/qg&Q\Ts+13$s0)Ibg'*ne]"4:0J,~>
-!<CCD]`=T"eGt5Qs+13$s0)IbeHMJf]tKp9J,~>
-!<CCD]`=RReUc8%eW&)_SB\a\S,e'~>
-!<C:A\cA.Lg4@t/g5XeiREE+PR/ha~>
-!<CCD]`=RReUc8%eW&)_SB\a\S,e'~>
-!<CCC^%%VDUk,=mUogEm^%.Znc2PBWS,e'~>
-!<C:@]()2>Tn/ngTrk!g](26hb5SsQR/ha~>
-!<CCC^%%VDUk,=mUogEm^%.Znc2PBWS,e'~>
-rr<&DrOqgI!53s`JcC<$XoIq9rk/B'!<7Q~>
-rr<&ArOVUC!4ma]JcC<$XoIq6rji0!!<7Q~>
-rr<&DrOqgI!53s`JcC<$XoIq9rk/B'!<7Q~>
-rr<&Dn%A^kJ`_OGJ`a)s!6suG!h98jJ,~>
-rr<&An%&LeJ`_OGJ`a)s!6XcA!gs&gJ,~>
-rr<&Dn%A^kJ`_OGJ`a)s!6suG!h98jJ,~>
-"9AH%S=K,_!1\W&J`_OGXl]W.n\+sm!W`9#J,~>
-"9AH%R@3TV!1AE#J`_OGXl]W+n[eag!W`9#J,~>
-"9AH%S=K,_!1\W&J`_OGXl]W.n\+sm!W`9#J,~>
-"9AK%!!)MYJ\?WJJ\A.unXTUZrr7K~>
-"9AK%!!)MVJ\$EDJ\%qonX9CWrr7K~>
-"9AK%!!)MYJ\?WJJ\A.unXTUZrr7K~>
-"TJH%s8RWMJH16$MZE\TJ,~>
-"TJH%s8RWMJH16$MZE\TJ,~>
-"TJH%s8RWMJH16$MZE\TJ,~>
-%%EndData
-showpage
-%%Trailer
-end
-%%EOF
diff --git a/lib/et/doc/src/sim_trans_move_actor.gif b/lib/et/doc/src/sim_trans_move_actor.gif
deleted file mode 100644
index f7185cada2..0000000000
--- a/lib/et/doc/src/sim_trans_move_actor.gif
+++ /dev/null
Binary files differ
diff --git a/lib/et/doc/src/sim_trans_move_actor.png b/lib/et/doc/src/sim_trans_move_actor.png
new file mode 100644
index 0000000000..c642720a8b
--- /dev/null
+++ b/lib/et/doc/src/sim_trans_move_actor.png
Binary files differ
diff --git a/lib/et/doc/src/sim_trans_move_actor.ps b/lib/et/doc/src/sim_trans_move_actor.ps
deleted file mode 100644
index b459735a82..0000000000
--- a/lib/et/doc/src/sim_trans_move_actor.ps
+++ /dev/null
@@ -1,6403 +0,0 @@
-%!PS-Adobe-3.0
-%%Creator: (ImageMagick)
-%%Title: (sim_trans_move_actor.ps)
-%%CreationDate: (Mon Oct 14 16:44:32 2002)
-%%BoundingBox: 0 0 512 426
-%%DocumentData: Clean7Bit
-%%LanguageLevel: 1
-%%Orientation: Portrait
-%%PageOrder: Ascend
-%%Pages: 1
-%%EndComments
-
-%%BeginDefaults
-%%EndDefaults
-
-%%BeginProlog
-%
-% Display a color image. The image is displayed in color on
-% Postscript viewers or printers that support color, otherwise
-% it is displayed as grayscale.
-%
-/DirectClassPacket
-{
- %
- % Get a DirectClass packet.
- %
- % Parameters:
- % red.
- % green.
- % blue.
- % length: number of pixels minus one of this color (optional).
- %
- currentfile color_packet readhexstring pop pop
- compression 0 eq
- {
- /number_pixels 3 def
- }
- {
- currentfile byte readhexstring pop 0 get
- /number_pixels exch 1 add 3 mul def
- } ifelse
- 0 3 number_pixels 1 sub
- {
- pixels exch color_packet putinterval
- } for
- pixels 0 number_pixels getinterval
-} bind def
-
-/DirectClassImage
-{
- %
- % Display a DirectClass image.
- %
- systemdict /colorimage known
- {
- columns rows 8
- [
- columns 0 0
- rows neg 0 rows
- ]
- { DirectClassPacket } false 3 colorimage
- }
- {
- %
- % No colorimage operator; convert to grayscale.
- %
- columns rows 8
- [
- columns 0 0
- rows neg 0 rows
- ]
- { GrayDirectClassPacket } image
- } ifelse
-} bind def
-
-/GrayDirectClassPacket
-{
- %
- % Get a DirectClass packet; convert to grayscale.
- %
- % Parameters:
- % red
- % green
- % blue
- % length: number of pixels minus one of this color (optional).
- %
- currentfile color_packet readhexstring pop pop
- color_packet 0 get 0.299 mul
- color_packet 1 get 0.587 mul add
- color_packet 2 get 0.114 mul add
- cvi
- /gray_packet exch def
- compression 0 eq
- {
- /number_pixels 1 def
- }
- {
- currentfile byte readhexstring pop 0 get
- /number_pixels exch 1 add def
- } ifelse
- 0 1 number_pixels 1 sub
- {
- pixels exch gray_packet put
- } for
- pixels 0 number_pixels getinterval
-} bind def
-
-/GrayPseudoClassPacket
-{
- %
- % Get a PseudoClass packet; convert to grayscale.
- %
- % Parameters:
- % index: index into the colormap.
- % length: number of pixels minus one of this color (optional).
- %
- currentfile byte readhexstring pop 0 get
- /offset exch 3 mul def
- /color_packet colormap offset 3 getinterval def
- color_packet 0 get 0.299 mul
- color_packet 1 get 0.587 mul add
- color_packet 2 get 0.114 mul add
- cvi
- /gray_packet exch def
- compression 0 eq
- {
- /number_pixels 1 def
- }
- {
- currentfile byte readhexstring pop 0 get
- /number_pixels exch 1 add def
- } ifelse
- 0 1 number_pixels 1 sub
- {
- pixels exch gray_packet put
- } for
- pixels 0 number_pixels getinterval
-} bind def
-
-/PseudoClassPacket
-{
- %
- % Get a PseudoClass packet.
- %
- % Parameters:
- % index: index into the colormap.
- % length: number of pixels minus one of this color (optional).
- %
- currentfile byte readhexstring pop 0 get
- /offset exch 3 mul def
- /color_packet colormap offset 3 getinterval def
- compression 0 eq
- {
- /number_pixels 3 def
- }
- {
- currentfile byte readhexstring pop 0 get
- /number_pixels exch 1 add 3 mul def
- } ifelse
- 0 3 number_pixels 1 sub
- {
- pixels exch color_packet putinterval
- } for
- pixels 0 number_pixels getinterval
-} bind def
-
-/PseudoClassImage
-{
- %
- % Display a PseudoClass image.
- %
- % Parameters:
- % class: 0-PseudoClass or 1-Grayscale.
- %
- currentfile buffer readline pop
- token pop /class exch def pop
- class 0 gt
- {
- currentfile buffer readline pop
- token pop /depth exch def pop
- /grays columns 8 add depth sub depth mul 8 idiv string def
- columns rows depth
- [
- columns 0 0
- rows neg 0 rows
- ]
- { currentfile grays readhexstring pop } image
- }
- {
- %
- % Parameters:
- % colors: number of colors in the colormap.
- % colormap: red, green, blue color packets.
- %
- currentfile buffer readline pop
- token pop /colors exch def pop
- /colors colors 3 mul def
- /colormap colors string def
- currentfile colormap readhexstring pop pop
- systemdict /colorimage known
- {
- columns rows 8
- [
- columns 0 0
- rows neg 0 rows
- ]
- { PseudoClassPacket } false 3 colorimage
- }
- {
- %
- % No colorimage operator; convert to grayscale.
- %
- columns rows 8
- [
- columns 0 0
- rows neg 0 rows
- ]
- { GrayPseudoClassPacket } image
- } ifelse
- } ifelse
-} bind def
-
-/DisplayImage
-{
- %
- % Display a DirectClass or PseudoClass image.
- %
- % Parameters:
- % x & y translation.
- % x & y scale.
- % label pointsize.
- % image label.
- % image columns & rows.
- % class: 0-DirectClass or 1-PseudoClass.
- % compression: 0-none or 1-RunlengthEncoded.
- % hex color packets.
- %
- gsave
- /buffer 512 string def
- /byte 1 string def
- /color_packet 3 string def
- /pixels 768 string def
-
- currentfile buffer readline pop
- token pop /x exch def
- token pop /y exch def pop
- x y translate
- currentfile buffer readline pop
- token pop /x exch def
- token pop /y exch def pop
- currentfile buffer readline pop
- token pop /pointsize exch def pop
- /Times-Roman findfont pointsize scalefont setfont
- x y scale
- currentfile buffer readline pop
- token pop /columns exch def
- token pop /rows exch def pop
- currentfile buffer readline pop
- token pop /class exch def pop
- currentfile buffer readline pop
- token pop /compression exch def pop
- class 0 gt { PseudoClassImage } { DirectClassImage } ifelse
- grestore
- showpage
-} bind def
-%%EndProlog
-%%Page: 1 1
-%%PageBoundingBox: 0 0 512 426
-DisplayImage
-0 0
-512 426
-12.000000
-512 426
-1
-0
-0
-64
-31446a
-394473
-314473
-000000
-ffffff
-bdbebd
-dedade
-d5d6d5
-949194
-ded6de
-9c999c
-d5d2d5
-c5c2c5
-bdb6bd
-838183
-7b817b
-8b918b
-7b7d7b
-838583
-b4b2b4
-a4a1a4
-bdbabd
-aca5ac
-acaaac
-cdcecd
-c5cac5
-949594
-c5c6c5
-bdc2bd
-b4b6b4
-949994
-838983
-a4a5a4
-acaeac
-9ca19c
-cdcacd
-9c9d9c
-8b8d8b
-d5ced5
-9c959c
-cdc6cd
-e6e6e6
-d5dad5
-8b898b
-b4aeb4
-c5bec5
-a4aaa4
-eeeeee
-ffa500
-ff0000
-0000ff
-ffffff
-ffffff
-ffffff
-ffffff
-ffffff
-ffffff
-ffffff
-ffffff
-ffffff
-ffffff
-ffffff
-ffffff
-ffffff
-000102000203030303030303030303030303030303030303030303030303030303030303
-030303030303030303030303030303030303030303030303030303030303030303030303
-030303030303030303030303030303030303030303030303030303030303030303030303
-030303030303030303030303030303030303030303030303030303030303030303030303
-030303030303030303030303030303030303030303030303030303030303030303030303
-030303030303030303030303030303030303030303030303030303030303030303030303
-030303030303030303030303030303030303030303030303030303030303030303030303
-030303030303030303030303030303030303030303030303030303030303030303030303
-030303030303030303030303030303030303030303030303030303030303030303030303
-030303030303030303030303030303030303030303030303030303030303030303030303
-030303030303030303030303030303030303030303030303030303030303030303030303
-030303030303030303030303030303030303030303030303030303030303030303030303
-030303030303030303030303030303030303030303030303030303030303030303030303
-030303030303030303030303030303030303030303030303030303030303030303030303
-030303010201020101010103030404040404040404040404040404040405040404040404
-040404040404040404040404040404040404040404040404040404040404040404040404
-040404040404040404040404040404040404040404040404040404040404040404040404
-040404040404040404040404040404040404040404040404040404040404040404040404
-040404040404040404040404040404040404040404040404040404040404040404040404
-040404040404040404040404040404040404040404040404040404040404040404040404
-040404040404040404040404040404040404040404040404040404040404040404040404
-040404040404040404040404040404040404040404040404040404040404040404040404
-040404040404040404040404040404040404040404040404040404040404040404040404
-040404040404040404040404040404040404040404040404040404040404040404040404
-040404040404040404040404040404040404040404040404040404040404040404040404
-040404040404040404040404040404040404040404040404040404040404040404040404
-040404040404040404040404040404040404040404040404050404040404040404040404
-040404040404040404040404040404040404040404040404040404040404040404040404
-040404040404040404040403030101010202030404060606060606060606060606060606
-060507070707070707070707070707070707070707070707070707070707070707070707
-070707070707070707070707070707070707070707070707070707070707070707070707
-070707070707070707070707070707070707070707070707070707070707070707070707
-070707070707070707070707070707070707070707070707070707070707070707070707
-070707070707070707070707070707070707070707070707070707070707070707070707
-070707070707070707070707070707070707070707070707070707070707070707070707
-070707070707070707070707070707070707070707070707070707070707070707070707
-070707070707070707070707070707070707070707070707070707070707070707070707
-070707070707070707070707070707070707070707070707070707070707070707070707
-070707070707070707070707070707070707070707070707070707070707070707070707
-070707070707070707070707070707070707070707070707070707070707070707070707
-070707070707070707070707070707070707070707070707070707070707070705060606
-060606060606060606060606060606060606060606060606060606060606060606060606
-060606060606060606060606060606060606062f2f030001010304060606060606060606
-060606060606060606050707070707070707070707070707070707070707070707070707
-070707070707070707070707070707070707070707070707070707070707070707070707
-070707070707070707070707070707070707070707070707070707070707070707070707
-070707070707070707070707070707070707070707070707070707070707070707070707
-070707070707070707070707070707070707070707070707070707070707070707070707
-070707070707070707070707070707070707070707070707070707070707070707070707
-070707070707070707070707070707070707070707070707070707070707070707070707
-070707070707070707070707070707070707070707070707070707070707070707070707
-070707070707070707070707070707070707070707070707070707070707070707070707
-070707070707070707070707070707070707070707070707070707070707070707070707
-070707070707070707070707070707070707070707070707070707070707070707070707
-070707070707070707070707070707070707070707070707070707070707070707070707
-070707070506060606060606060606060606060606060606060606060606060606060606
-06060606060606060606060606060606060606060606060606060606060c030002030406
-060606060606060606060606060606060605070707070707070707070707070707070707
-070707070707070707070707070707070707070707070707070707070707070707070707
-0707070707070707070707070707070707070707190b0707070707070707070707070707
-070707070707070707070707070707070707070707070707070707070707070707070707
-070707070707070707070707070707070707070707070707070707070707070707070707
-070707070707070707070707070707070707070707070707070707070707070707070707
-070707070707070707070707070707070707070707070707070707070707070707070707
-070707070707070707070707070707070707070707070707070707070707070707070707
-070707070707070707070707070707070707070707070707070707070707070707070707
-070707070707070707070707070707070707070707070707070707070707070707070707
-070707070707070707070707070707070707070707070707070707070707070707070707
-070707070707070707070707070707070707070707070707070707070707070707070707
-070707070707070707070707050606060606060606060606060606060606060606060606
-060606060606060606060606060606060606060606060606060606060606060606060606
-060c03010304060606060606060606060606060606060606060507070707070707070707
-070707070707070707070707070707070707070707080807070707070707070707070707
-07070707070707070707070707070707070707070707070c1407050f111e080807070e0f
-070707070707070707070707070707070707070707070707070707070707070707070707
-07070707070e0f07070e0f07070707070707070707070707070707070707070707070707
-070707070707071405070707070707070707070707070707070707070707070707070707
-070707070707070707070707070707070707070707070707070707070707070707070707
-070707070707070707070707070707070707070707070707070707070707070707070707
-070707070707070707070707070707070707070707070707070707070707070707070707
-070707070707070707070707070707070707070707070707070707070707070707070707
-070707070707070707070707070707070707070707070707070707070707070707070707
-070707070707070707070707070707070707070707070707070707070707070707070707
-070707070707070707070707070707070707070705060606060606060606060606060606
-06060606060606060606060a0a0a0a0a0a0a0a0a0a0606060606060606060606060a0a06
-0606060a0a06060606062103030409090909090a0a0909090909090a0a09090909050b0b
-0b0b0b0b0b0b0b0b0b0b0b0c0d0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b08080b0b0b0b0b
-0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0c0f1d0b2511
-1b2608080b0b0e0f0b0b0c0d0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b
-0b0b0b0b0b0b0b0b0b0b0b0b0b0e0f0b0b0e0f0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0c
-0d0b0b0b0b0b0b0b0b0b0b0b0b0b0b1d112d0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b
-0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b
-0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b
-0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b
-0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b
-0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b
-0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b
-0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0509090909090909
-090909090909090909090909090909090909090a0a0a0a0a0a0a0a0a0a09090909090909
-090909090a0a0a0a09090a0a0a0a0909090921030304090909090a0a0a0a090909090a0a
-0a0a090909050b0b0b0b0b0b0b0b0b0b0b0b0b0e0f0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b
-0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b
-0b0b2b1a0b0b0e0f0b0b0b0b0b0b0e0f0b0b0e0f0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b
-0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0e0f0b0b0e0f0b0b0b0b0b0b0b0b0b
-0b0b0b0b0b0b0b0e0f0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b1a2b0b0b0b0b0b0b0b0b0b0b
-0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b
-0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b
-0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b
-0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b
-0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b
-0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b
-0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b
-0509090909090909090909090909090909090909090909090909090a0a0a0a0a0a0a0a0a
-0a09090909090909090909090a0a0a0a0a0a0a0a0a0a0909090921030304090909090a0a
-0a0a0a09090a0a0a0a0a090909050b0b0b0b0b0b0c101112130b141111110c0b0b0b0b0b
-0b0a11150b0b16120b0e0f0b0b0c101112130b17110c0b0a110c0b0a140b0c101112130b
-0b252516250b0b0b0b1511150b0a111111230e0f0b0b0e0f0b141111110c0c101112130b
-0b252516250b0e0f0b0b0b0b0b0b212b11112b230b212b112b210b0b0b0e0f0b0b0e0f0b
-0b0c101112130b0b212b11112b23141111110c212b112b210b0b0b252516250b0d11150b
-0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b
-0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b
-0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b
-0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b
-0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b
-0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b
-0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b
-0b0b0b0b0b0b0b0b0509090909090909090909090909090909090909090909090909090a
-0a0a0a0a0a0a0a0a0a0909090909090909090909090a0a0a0a0a0a0a0a09090909092103
-03040b0b0b0b0b0a0a0a0a0a0a0a0a0a0a0b0b0b0b051818181818190e12151a111b1b0f
-111c181818181818181d111e18181f20180e0f18190e12151a111b15111718121117180e
-1d190e12151a111b180e112b201818181822111b181b0f111c180e0f18180e0f181b0f11
-1c1b0e12151a111b180e112b20182b1f181818181820112b131d2e1b17111a051a111718
-180e0f18180e0f18190e12151a111b20112b131d2e1b1b0f111c2e111a051a111718180e
-112b20181b11221818181818181818181818181818181818181818181818181818181818
-181818181818181818181818181818181818181818181818181818181818181818181818
-181818181818181818181818181818181818181818181818181818181818181818181818
-181818181818181818181818181818181818181818181818181818181818181818181818
-181818181818181818181818181818181818181818181818181818181818181818181818
-181818181818181818181818181818181818181818181818181818181818181818181818
-181818181818181818181818181818181818181818181818181818181818181818181818
-18181818181818181818181818181818050b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b
-0b0b0b0b0b0b0b0a0b0b0b0b0b0b0b0b0a0b0b0b0b0b0b0b0b0b0b0b0b0b0a0a0a0a0a0a
-0b0b0b0b0b0b210303040b0b0b0b0b0b0a0a0a0a0a0a0a0a0b0b0b0b0b05181818181821
-112223211121180e0f1818181818181818180e0f2305110c180e0f182111222321112118
-111a1b11121e1c112321112223211121180e112318181818181a111818180e0f18180e0f
-18180e0f18180e0f1821112223211121180e112318181818181818181812110c18181818
-1f111b181b111f18180e0f18180e0f182111222321112112110c18181818180e0f181f11
-1b181b111f18180e1123181818111a181818181818181818181818181818181818181818
-181818181818181818181818181818181818181818181818181818181818181818181818
-181818181818181818181818181818181818181818181818181818181818181818181818
-181818181818181818181818181818181818181818181818181818181818181818181818
-181818181818181818181818181818181818181818181818181818181818181818181818
-181818181818181818181818181818181818181818181818181818181818181818181818
-181818181818181818181818181818181818181818181818181818181818181818181818
-181818181818181818181818181818181818181818181818050b0b0b0b0b0b0b0b0b0b0b
-0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0a0b0b0b0b0b0b0b0b0a0b0b0b0b0b0b0b0b0b0b0b
-0b0b0a0a0a0a0a0a0b0b0b0b0b0b210303040b0b0b0b0b0b0b0a0a0a0a0a0a0b0b0b0b0b
-0b05181818181820111111111120180e0f181818181818181818241121242518180e0f18
-2011111111112018100e21081e1217251820111111111120180e0f1818181818181a1118
-18180e0f18180e0f18180e0f18180e0f1820111111111120180e0f181818181818181818
-18111118181818180f11181818111118180e0f18180e0f18201111111111201111181818
-1818180e0f180f11181818111118180e0f18181818111a18181818181818181818181818
-181818181818181818181818181818181818181818181818181818181818181818181818
-181818181818181818181818181818181818181818181818181818181818181818181818
-181818181818181818181818181818181818181818181818181818181818181818181818
-181818181818181818181818181818181818181818181818181818181818181818181818
-181818181818181818181818181818181818181818181818181818181818181818181818
-181818181818181818181818181818181818181818181818181818181818181818181818
-1818181818181818181818181818181818181818181818181818181818181818050b0b0b
-0b0b150a0a0a0a0a0a0a0a150b0b0b0b0b0b0b0b0b0b0b0a0b0b0b0b0b0b0b0b0a0b0b0b
-0b0b0b0b0b0b0b0b0b0a0a0a0a0a0a0a0a0b0b0b0b0b210303040b0b0b0b0b0b0b0b0a0a
-0a0a0b0b0b0b0b0b0b05181818181821112218181818180e0f1818181818181818181511
-250e1718180e0f18211122181818181814112520171125141821112218181818180e0f18
-181818181814111b18180e0f18180e0f18180e0f18180e0f1821112218181818180e0f18
-181818181818181818121105181818181f111b181b111f18180e0f18180e0f1821112218
-18181812110518181818180e0f181f111b181b111f18180e0f1818181b11221818181818
-181818181818181818181818181818181818181818181818181818181818181818181818
-181818181818181818181818181818181818181818181818181818181818181818181818
-181818181818181818181818181818181818181818181818181818181818181818181818
-181818181818181818181818181818181818181818181818181818181818181818181818
-181818181818181818181818181818181818181818181818181818181818181818181818
-181818181818181818181818181818181818181818181818181818181818181818181818
-181818181818181818181818181818181818181818181818181818181818181818181818
-18181818050b0b0b0b0b0a0a0a0a0a0a0a0a0a0a0b0b0b0b0b0b0b0b0b0b0b0a0b0b0b0b
-0b0b0b0b0a0b0b0b0b0b0b0b0b0b0b0b0a0a0a0a0a0a0a0a0a0a0b0b0b0b210303042626
-2626262626262627272626262626262626052323232323281211201d2113231f111d2823
-232323232323231211111b23230e0f23281211201d2113231d11110d1511111d23281211
-201d2113230e0f23232323232315112c23230e0f23230e0f23230e0f23231f111d0c1211
-201d2113230e0f2323232b1f2323232323171112210d170c17111a151a111623230e0f23
-230e0f23281211201d2113171112210d170c231f111d20111a151a111623230e0f232323
-2c110d232323232323232323232323232323232323232323232323232323232323232323
-232323232323232323232323232323232323232323232323232323232323232323232323
-232323232323232323232323232323232323232323232323232323232323232323232323
-232323232323232323232323232323232323232323232323232323232323232323232323
-232323232323232323232323232323232323232323232323232323232323232323232323
-232323232323232323232323232323232323232323232323232323232323232323232323
-232323232323232323232323232323232323232323232323232323232323232323232323
-232323232323232323232323052626262626272727272727272727272626262626262626
-262626272626262626262626272626262626262626262626272727272626272727272626
-26262103030426262626262626262626262626262626262626052323232323230c1a0f11
-122123130e0f1523232323232323231411082323230e0f23230c1a0f1112212328111123
-2311112823230c1a0f111221230e0f23232323232323252523230e0f23230e0f23230e0f
-2323130e0f150c1a0f111221230e0f2323230e0f232323232323172b11112b2d23161211
-12172323230e0f23230e0f23230c1a0f11122123172b11112b2d23130e0f151612111217
-2323230e0f23232325252323232323232323232323232323232323232323232323232323
-232323232323232323232323232323232323232323232323232323232323232323232323
-232323232323232323232323232323232323232323232323232323232323232323232323
-232323232323232323232323232323232323232323232323232323232323232323232323
-232323232323232323232323232323232323232323232323232323232323232323232323
-232323232323232323232323232323232323232323232323232323232323232323232323
-232323232323232323232323232323232323232323232323232323232323232323232323
-23232323232323232323232323232323232323230526262626260d27272727272727270d
-262626262626262626262627272727272727272727262626262626262626262626272726
-262626272726262626262103030426262626262626262626262626262626262626052323
-232323232323232323232323232311111111111111152323232323232323232323232323
-2323232323232323232323232323232323232323232323232323232323230c0e16232323
-232323232323232323232323232323232323232323232323232323232323232323232323
-232323232323232323232323232323232323232323232323232323232323232323232323
-232323232323232323232323232323170e0c232323232323232323232323232323232323
-232323232323232323232323232323232323232323232323232323232323232323232323
-232323232323232323232323232323232323232323232323232323232323232323232323
-232323232323232323232323232323232323232323232323232323232323232323232323
-232323232323232323232323232323232323232323232323232323232323232323232323
-232323232323232323232323232323232323232323232323232323232323232323232323
-232323232323232323232323232323232323232323232323232323232323232323232323
-232323232323232323232323232323232323232323232323232323230526262626262626
-262626262626262626262626262626262626262626262626262626262626262626262626
-262626262626262626262626262626262626210303042323232323232323232323232323
-2323232323051b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b
-1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b
-1b1b1b05141b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b
-1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b
-1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b14051b1b1b1b1b1b1b1b1b1b1b
-1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b
-1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b
-1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b
-1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b
-1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b
-1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b
-1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b
-052323232323232323232323232323232323232323232323232323232323232323232323
-232323232323232323232323232323232323232323232323232321030304232323232323
-23232323232323232323232323051b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b
-1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b
-1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b
-1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b
-1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b
-1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b
-1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b
-1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b
-1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b
-1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b
-1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b
-1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b
-1b1b1b1b1b1b1b1b05232323232323232323232323232323232323232323232323232323
-232323232323232323232323232323232323232323232323232323232323232323232103
-030423232323232323232323232323232323232323051b1b1b1b1b1b1b1b1b1b1b1b1b1b
-1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b
-1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b
-1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b
-1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b
-1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b
-1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b
-1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b
-1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b
-1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b
-1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b
-1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b
-1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b0523232323232323232323232323232323232323
-232323232323232323232323232323232323232323232323232323232323232323232323
-2323232323232103030e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e
-0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e
-0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e
-0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e
-0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e
-0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e
-0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e
-0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e
-0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e
-0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e
-0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e
-0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e
-0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e
-0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e
-0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e030304292929140404040404040404040404040404
-040404040404040404040404040404040404040404040404040404040404040404040404
-040404040404040404040404040404040404040404040404040404040404040404040404
-040404040404040404040404040404040404040404040404040404040404040404040404
-040404040404040404040404040404040404040404040404040404040404040404040404
-040404040404040404040404040404040404040404040404040404040404040404040404
-040404040404040404040404040404040404040404040404040404040404040404040404
-040404040404040404040404040404040404040404040404040404040404040404040404
-040404040404040404040404040404040404040404040404040404040404040404040404
-040404040404040404040404040404040404040404040404040404040404040404040404
-040404040404040404040404040404040404040404040404040404040404040404040404
-040404040404040404040404040404040404040404040404040404040404040404040404
-040404040404040404040404040404040404040404040404040404040404040404040404
-040404040404040404040404040404040404040404040404040404040404040404040404
-040404040404040404040404040404040404140429291503030429292914040404040404
-040404040404040404040404040404040404040404040404040404040404040404040404
-040404040404040404040404040404040404040404040404040404040404040404040404
-040404040404040404040404040404040404040404040404040404040404040404040404
-040404040404040404040404040404040404040404040404040404040404040404040404
-040404040404040404040404040404040404040404040404040404040404040404040404
-040404040404040404040404040404040404040404040404040404040404040404040404
-040404040404040404040404040404040404040404040404040404040404040404040404
-040404040404040404040404040404040404040404040404040404040404040404040404
-040404040404040404040404040404040404040404040404040404040404040404040404
-040404040404040404040404040404040404040404040404040404040404040404040404
-040404040404040404040404040404040404040404040404040404040404040404040404
-040404040404040404040404040404040404040404040404040404040404040404040404
-040404040404040404040404040404040404040404040404040404040404040404040404
-040404040404040404040404040404040404040404040404040e14042929150303042929
-291404042a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a0e0e1404
-2929150303042929291404042a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a0e0e14042929150303042929291404042a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a0e0e14042929150303042929291404042a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a0e0e1404292915030304292929140404
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a0e0e140429291503
-03042929291404042a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-0e0e14042929150303042929291404042a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a0e0e14042929150303042929291404042a2a2a2a2a2a2a0303030303
-0303032a03032a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a03032a2a2a2a03030303
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a030303032a2a2a2a2a2a2a2a03032a03032a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a03032a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-03030303030303032a03032a2a03032a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a03032a2a2a03032a2a2a2a2a2a2a2a03032a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a0e0e14042929150303042929291404042a2a2a2a
-2a2a2a03032a2a2a2a2a2a2a03032a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a0303
-2a2a2a2a03032a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a03032a2a03032a2a2a2a2a2a2a03032a03032a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a03032a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a03032a2a2a2a2a2a2a03032a2a03032a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a03032a2a2a03032a2a2a2a2a2a2a2a03032a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a0e0e14042929150303042929
-291404042a2a2a2a2a2a2a03032a2a2a2a03032a03032a2a030303032a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a03032a2a03032a03032a2a030303032a2a03032a2a03032a2a03032a2a
-030303032a2a03032a03032a2a2a2a2a2a2a2a2a2a2a2a2a03032a2a2a2a2a2a03030303
-2a2a03032a03032a2a030303032a2a2a030303032a2a030303032a2a030303032a2a0303
-2a03032a2a2a2a2a2a2a2a2a2a2a2a2a03032a2a2a2a03032a03032a030303032a2a0303
-03032a2a03032a03032a2a2a2a2a2a2a2a2a2a2a2a2a03032a2a2a03032a2a030303032a
-2a03032a03032a03032a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a0e0e1404
-2929150303042929291404042a2a2a2a2a2a2a03032a2a2a2a03032a03032a03032a2a03
-032a2a2a2a2a2a2a2a2a2a2a2a2a2a03032a2a03032a03032a03032a2a03032a03032a2a
-03032a2a03032a03032a2a03032a03030303032a2a2a2a2a2a2a2a2a2a2a2a2a03032a2a
-2a2a2a03032a2a03032a03032a03032a03032a2a03032a03032a2a03032a2a03032a2a03
-032a2a03032a03030303032a2a2a2a2a2a2a2a2a2a2a2a2a03032a2a2a2a03032a03032a
-2a03032a2a03032a2a03032a03030303032a2a2a2a2a2a2a2a2a2a2a2a2a03032a2a2a03
-032a03032a2a03032a03032a0303032a03032a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a0e0e14042929150303042929291404042a2a2a2a2a2a2a03030303032a03032a
-03032a03032a2a03032a2a2a2a2a2a2a2a2a2a2a2a2a2a03032a2a03032a03032a03032a
-2a03032a2a03032a03032a03032a2a03032a2a03032a0303032a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a03032a2a2a2a2a03032a2a03032a03032a03032a03032a2a03032a03032a2a2a
-2a2a2a03032a2a03032a2a03032a0303032a2a2a2a2a2a2a2a2a2a2a2a2a2a2a03030303
-032a03032a03032a2a03032a2a03032a2a03032a0303032a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a030303030303032a03032a2a03032a03032a03032a2a03032a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a0e0e14042929150303042929291404042a2a2a2a2a2a2a03
-032a2a2a2a03032a03032a0303030303032a2a2a2a2a2a2a2a2a2a2a2a2a2a2a032a2a03
-2a2a03032a0303030303032a2a03032a03032a03032a2a0303030303032a03032a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a03032a2a2a2a2a03032a2a03032a03032a03032a03030303
-03032a03032a2a2a2a2a2a03032a2a03032a2a03032a03032a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a03032a2a2a2a03032a03032a2a03032a2a0303030303032a03032a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a03032a2a2a03032a0303030303032a03032a03032a2a03032a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a0e0e1404292915030304292929140404
-2a2a2a2a2a2a2a03032a2a2a2a03032a03032a03032a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a030303032a2a03032a03032a2a2a2a2a2a03032a03032a03032a2a03032a2a2a
-2a2a03032a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a03032a2a2a2a2a03032a2a03032a0303
-2a03032a03032a2a2a2a2a03032a2a2a2a2a2a03032a2a03032a2a03032a03032a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a03032a2a2a2a03032a03032a2a03032a2a03032a2a2a2a2a
-03032a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a03032a2a2a03032a03032a2a2a2a2a03032a
-03032a2a03032a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a0e0e140429291503
-03042929291404042a2a2a2a2a2a2a03032a2a2a2a03032a03032a03032a2a03032a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a03032a2a2a03032a03032a2a03032a2a2a03032a2a0303
-2a2a2a03032a2a03032a03032a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a03032a2a030303
-032a2a03032a03032a03032a03032a2a03032a03032a2a03032a2a03032a0303032a2a03
-032a03032a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a03032a2a2a2a03032a03032a2a03032a
-0303032a2a03032a03032a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a03032a2a2a03032a0303
-2a2a03032a03032a0303032a03032a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-0e0e14042929150303042929291404042a2a2a2a2a2a2a03032a2a2a2a03032a03032a2a
-030303032a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a03032a2a2a03032a2a030303032a2a
-2a2a03032a2a03032a2a2a2a030303032a2a03032a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a030303032a2a030303032a2a03032a03032a2a030303032a2a2a030303032a2a2a2a
-03032a2a030303032a2a03032a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a03032a2a2a2a0303
-2a03032a2a2a03032a2a030303032a2a03032a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a0303
-2a2a2a03032a2a030303032a2a03032a03032a03032a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a0e0e14042929150303042929291404042a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a03032a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a0e0e14042929150303042929291404042a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a03032a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a0e0e14042929150303042929
-291404042a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a03032a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a0e0e1404
-2929150303042929291404042a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a0e0e14042929150303042929291404042a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a0e0e14042929150303042929291404042a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a0e0e1404292915030304292929140404
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a0e0e140429291503
-03042929291404042a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-0e0e14042929150303042929291404040e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e
-0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e
-0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e
-0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e
-0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e
-0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e
-0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e
-0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e
-0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e
-0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e
-0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e
-0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e
-0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e
-0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e
-0e0e0e0e0e0e0e0e0e0e140429291503030429292914040e0e0e0e0e0e0e0e0e0e0e0e0e
-0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e
-0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e
-0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e
-0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e
-0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e
-0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e
-0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e
-0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e
-0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e
-0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e
-0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e
-0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e
-0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e
-0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e1404292915030304292929142a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a14042929150303042929
-29142a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a1404
-292915030304292929142a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a1404292915030304292929142a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a1404292915030304292929142a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a1404292915030304292929142a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a140429291503
-0304292929142a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a1404292915030304292929142a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a1404292915030304292929142a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a1404292915030304292929142a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a14042929150303042929
-29142a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a03030303032a2a2a2a2a2a2a2a2a2a2a0303
-2a2a2a2a2a2a2a2a2a03032a03032a2a2a2a2a2a03032a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a03032a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a1404
-292915030304292929142a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a03032a2a03032a2a2a2a
-2a2a2a2a2a2a03032a2a2a2a2a2a2a2a2a2a2a2a03032a2a2a2a2a2a03032a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a03032a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a1404292915030304292929142a2a2a2a2a2a2a2a2a2a2a2a2a2a04040404
-040404040404042a2a2a2a2a2a2a2a0303030303032a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a0303
-2a2a2a03032a2a030303032a2a030303032a2a030303032a2a03032a03032a2a2a2a2a2a
-03032a2a2a2a2a030303032a2a03032a2a2a03032a2a030303032a2a03032a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a1404292915030304292929142a2a2a2a2a2a2a2a2a2a
-2a2a2a2a040404040404040404040e2a2a2a2a2a2a2a2a03032a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a03032a2a2a03032a03032a2a03032a2a03032a2a03032a2a03032a03032a
-03032a2a2a2a2a2a03032a2a2a2a03032a2a03032a03032a2a2a03032a03032a2a03032a
-03032a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a1404292915030304292929142a2a
-2a2a2a2a2a2a2a2a2a2a2a2a04042a2a2a2a2a2a2a0e0e2a2a2a2a2a2a2a2a03032a2a2a
-2a03032a03032a030303032a2a2a030303032a2a03030303032a2a030303032a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a03032a2a2a03032a03032a2a03032a2a03032a2a2a2a
-2a2a03032a03032a03032a2a2a2a2a2a03032a2a2a2a03032a2a03032a2a03032a03032a
-2a03032a2a03032a03032a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a140429291503
-0304292929142a2a2a2a2a2a2a2a2a2a2a2a2a2a04042a2a2a2a2a2a2a0e0e2a2a2a2a2a
-2a2a2a03032a2a2a2a030303030303032a2a03032a03032a2a03032a2a2a2a03032a0303
-2a2a03032a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a03032a2a2a03032a030303030303
-2a2a03032a2a2a03030303032a03032a03032a2a2a2a2a2a03032a2a2a2a030303030303
-2a2a03032a03032a2a0303030303032a03032a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a1404292915030304292929142a2a2a2a2a2a2a2a2a2a2a2a2a2a04042a2a2a2a2a2a
-2a0e0e2a2a2a2a2a2a2a2a03030303032a0303032a2a03032a2a03032a03032a2a03032a
-2a2a03032a2a03032a2a03032a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a03032a2a2a03
-032a03032a2a2a2a2a2a03032a2a03032a2a03032a03032a03032a2a2a2a2a2a03032a2a
-2a2a03032a2a2a2a2a2a2a0303032a2a2a03032a2a2a2a2a03032a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a1404292915030304292929142a2a2a2a2a2a2a2a2a2a2a2a2a2a
-04042a2a2a2a2a2a2a0e0e2a2a2a2a2a2a2a2a03032a2a2a2a03032a2a2a030303030303
-2a0303030303032a2a2a032a2a2a0303030303032a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a03032a2a03032a2a03032a2a03032a2a03032a0303032a2a03032a03032a03032a2a
-2a2a2a2a03032a2a2a2a03032a2a03032a2a2a0303032a2a2a03032a2a03032a03032a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a1404292915030304292929142a2a2a2a2a2a
-2a2a2a2a2a2a2a2a04042a2a2a2a2a2a2a0e0e2a2a2a2a2a2a2a2a03032a2a2a2a03032a
-2a2a03032a2a2a2a2a03032a2a2a2a2a2a03032a2a2a03032a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a03030303032a2a2a2a030303032a2a2a2a03032a2a0303032a03
-0303032a03032a2a2a2a2a2a0303030303032a030303032a2a2a2a2a032a2a2a2a2a0303
-03032a2a03032a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a14042929150303042929
-29142a2a2a2a2a2a2a2a2a2a2a2a2a2a04042a2a2a2a2a2a2a0e0e2a2a2a2a2a2a2a2a03
-032a2a2a2a03032a2a2a03032a2a03032a03032a2a03032a03032a2a2a2a03032a2a0303
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a1404
-292915030304292929142a2a2a2a2a2a2a2a2a2a2a2a2a2a04042a2a2a2a2a2a2a0e0e2a
-2a2a2a2a2a2a2a03032a2a2a2a03032a2a2a2a030303032a2a2a030303032a2a03030303
-032a2a030303032a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a1404292915030304292929142a2a2a2a2a2a2a2a2a2a2a2a2a2a04040e0e
-0e0e0e0e0e0e0e2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a1404292915030304292929142a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a1404292915030304292929142a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a140429291503
-0304292929142a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a1404292915030304292929142a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a1404292915030304292929142a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a03032a2a2a2a030303032a2a2a03030303
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a1404292915030304292929142a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a030303032a2a2a03032a2a
-03032a03032a2a03032a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a14042929150303042929
-29142a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a03
-032a2a2a03032a2a03032a03032a2a03032a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a1404
-292915030304292929142a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a03032a2a2a03032a2a03032a03032a2a03032a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a1404292915030304292929142a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a03032a2a2a03032a2a03032a03032a2a03032a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a1404292915030304292929142a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a03032a2a2a03032a2a03032a03
-032a2a03032a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a1404292915030304292929142a2a
-2a2a2a2a2a2a2a2a2a2a2a2a04040404040404040404042a2a2a2a2a2a2a2a03032a2a2a
-03032a03032a2a2a2a2a03032a2a2a2a2a2a2a2a2a2a2a2a2a0303030303032a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a03030303030303032a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a03032a2a2a
-03032a2a03032a03032a2a03032a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a140429291503
-0304292929142a2a2a2a2a2a2a2a2a2a2a2a2a2a040404040404040404040e2a2a2a2a2a
-2a2a2a03032a2a2a03032a2a2a2a2a2a2a2a03032a2a2a2a2a2a2a2a2a2a2a2a2a03032a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-03032a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a03032a2a2a03032a2a03032a03032a2a03032a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a1404292915030304292929142a2a2a2a2a2a2a2a2a2a2a2a2a2a04042a2a2a2a2a2a
-2a0e0e2a2a2a2a2a2a2a2a03032a2a2a03032a03032a2a03032a03032a2a030303032a2a
-2a2a2a2a2a03032a2a2a2a03032a03032a030303032a2a032a0303032a0303032a2a2a2a
-2a2a2a2a2a2a2a2a03032a2a2a2a030303032a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a03032a2a2a2a030303032a2a2a030303032a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a1404292915030304292929142a2a2a2a2a2a2a2a2a2a2a2a2a2a
-04042a2a2a2a2a2a2a0e0e2a2a2a2a2a2a2a2a03032a2a2a03032a03032a03032a030303
-2a03032a2a03032a2a2a2a2a2a03032a2a2a2a030303030303032a2a03032a03032a2a03
-032a2a03032a2a2a2a2a2a2a2a2a2a2a03032a2a2a03032a2a03032a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a1404292915030304292929142a2a2a2a2a2a
-2a2a2a2a2a2a2a2a04042a2a2a2a2a2a2a0e0e2a2a2a2a2a2a2a2a030303030303032a03
-032a03032a2a03032a03032a2a03032a2a2a2a2a2a03030303032a0303032a2a03032a2a
-03032a03032a2a03032a2a03032a0303030303032a2a2a2a03032a2a2a03032a2a03032a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a14042929150303042929
-29142a2a2a2a2a2a2a2a2a2a2a2a2a2a04042a2a2a2a2a2a2a0e0e2a2a2a2a2a2a2a2a03
-032a2a2a03032a03032a03032a2a03032a0303030303032a2a2a2a2a2a03032a2a2a2a03
-032a2a2a03032a2a03032a03032a2a03032a2a03032a2a2a2a2a2a2a2a2a2a2a03032a2a
-2a03032a2a03032a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a1404
-292915030304292929142a2a2a2a2a2a2a2a2a2a2a2a2a2a04042a2a2a2a2a2a2a0e0e2a
-2a2a2a2a2a2a2a03032a2a2a03032a03032a03032a2a03032a03032a2a2a2a2a2a2a2a2a
-2a03032a2a2a2a03032a2a2a03032a2a03032a03032a2a03032a2a03032a030303030303
-2a2a2a2a03032a2a2a03032a2a03032a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a1404292915030304292929142a2a2a2a2a2a2a2a2a2a2a2a2a2a04042a2a
-2a2a2a2a2a0e0e2a2a2a2a2a2a2a2a03032a2a2a03032a03032a03032a0303032a03032a
-2a03032a2a2a2a2a2a03032a2a2a2a03032a2a2a03032a2a03032a03032a2a03032a2a03
-032a2a2a2a2a2a2a2a2a2a2a03032a2a2a03032a2a03032a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a1404292915030304292929142a2a2a2a2a2a2a2a2a2a
-2a2a2a2a04042a2a2a2a2a2a2a0e0e2a2a2a2a2a2a2a2a03032a2a2a03032a03032a2a03
-032a03032a2a030303032a2a2a2a2a2a2a03032a2a2a2a03032a2a2a2a030303032a2a03
-032a2a03032a2a03032a2a2a2a2a2a2a2a2a2a2a03032a2a2a2a030303032a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e
-0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e
-0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e
-0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e
-0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e
-0e0e0e0e0e0e0e0e0e0e0e0e2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a1404292915030304292929142a2a
-2a2a2a2a2a2a2a2a2a2a2a2a04040e0e0e0e0e0e0e0e0e2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e
-0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e
-0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e
-0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e
-0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e
-0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e042a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a140429291503
-0304292929142a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a0e0e1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c
-1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c
-1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c
-1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c
-1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c04040404
-040404040404040404040404040404040404040404040404040404042a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a1404292915030304292929142a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a0e0e1c1c1c1c1c1c1c1c1c1c
-1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c
-1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c
-1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c
-1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c
-1c1c1c1c04040404040404040404040404040404040404040404040404040404040e0404
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a1404292915030304292929142a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a0e0e1c1c
-1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c
-1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c
-1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c
-1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c
-1c1c1c1c1c1c1c1c1c1c1c1c04042a2a2a2a2a2a2a2a2a2a2a2a0e042a2a2a2a2a2a2a2a
-2a2a2a2a0e0e04042a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a1404292915030304292929142a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a0e0e1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c
-1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c
-1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c
-1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c
-1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c04042a2a2a2a2a2a2a2a2a2a2a2a0e04
-2a2a2a2a2a2a2a2a2a2a2a2a0e0e04042a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a14042929150303042929
-29142a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a0e0e1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c
-1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c
-1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c
-1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c
-1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c04042a2a2a2a2a2a
-2a2a2a2a2a2a0e042a2a2a2a2a2a2a2a2a2a2a2a0e0e04042a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a1404
-292915030304292929142a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a0e0e1c1c1c1c1c1c1c1c1c1c1c1c1c1c
-1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c
-1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c
-1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c
-1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c
-04042a2a2a2a2a2a2a2a2a2a2a2a0e042a2a2a2a2a2a2a2a2a2a2a2a0e0e04042a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a1404292915030304292929142a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a0e0e1c1c1c1c1c1c
-1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c
-1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c
-1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c
-1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c
-1c1c1c1c1c1c1c1c04042a2a2a2a2a2a2a2a2a2a2a2a0e042a2a2a2a2a2a2a2a2a2a2a2a
-0e0e04042a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a1404292915030304292929142a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-0e0e1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c
-1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c
-1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c
-1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c
-1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c04042a2a2a2a2a2a2a2a2a2a2a2a0e042a2a2a2a
-2a2a2a2a2a2a2a2a0e0e04042a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a1404292915030304292929142a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a0e0e1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c
-1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c
-1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c
-1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c
-1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c04042a2a2a2a2a2a2a2a2a2a
-2a2a0e042a2a2a2a2a2a2a2a2a2a2a2a0e0e04042a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a140429291503
-0304292929142a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a0e0e1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c
-1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c
-1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c
-1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c
-1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c04042a2a
-2a2a2a2a2a2a2a2a2a2a0e042a2a2a2a2a2a2a2a2a2a2a2a0e0e04042a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a1404292915030304292929142a2a2a2a2a2a2a2a2a2a2a2a2a2a0404040404040404
-0404042a2a2a2a2a2a2a2a03032a2a2a03032a03032a2a2a2a2a03032a2a2a2a2a2a2a2a
-2a2a2a2a2a03032a2a2a03032a2a2a2a2a2a2a2a03032a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a0e0e1c1c1c1c1c1c1c1c1c1c
-1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c
-1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c
-1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c
-1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c
-1c1c1c1c04042a2a2a2a2a2a2a2a2a2a2a2a0e042a2a2a2a2a2a2a2a2a2a2a2a0e0e0404
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a1404292915030304292929142a2a2a2a2a2a2a2a2a2a2a2a2a2a
-040404040404040404040e2a2a2a2a2a2a2a2a03032a2a2a03032a2a2a2a2a2a2a2a0303
-2a2a2a2a2a2a2a2a2a2a2a2a2a03032a2a2a03032a2a2a2a2a2a2a2a03032a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a0e0e1c1c
-1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c
-1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c
-1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c
-1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c
-1c1c1c1c1c1c1c1c1c1c1c1c04042a2a2a2a2a2a2a2a2a2a2a2a0e042a2a2a2a2a2a2a2a
-2a2a2a2a0e0e04042a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a1404292915030304292929142a2a2a2a2a2a
-2a2a2a2a2a2a2a2a04042a2a2a2a2a2a2a0e0e2a2a2a2a2a2a2a2a03032a2a2a03032a03
-032a2a03032a03032a2a030303032a2a2a2a2a2a2a03032a2a2a03032a03032a03032a2a
-03032a2a03032a03032a03032a2a2a030303032a2a03032a2a03032a2a03032a03032a03
-032a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a0e0e1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c
-1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c
-1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c
-1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c
-1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c04042a2a2a2a2a2a2a2a2a2a2a2a0e04
-2a2a2a2a2a2a2a2a2a2a2a2a0e0e04042a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a14042929150303042929
-29142a2a2a2a2a2a2a2a2a2a2a2a2a2a04042a2a2a2a2a2a2a0e0e2a2a2a2a2a2a2a2a03
-032a2a2a03032a03032a03032a0303032a03032a2a03032a2a2a2a2a2a03032a2a2a0303
-2a0303032a03032a03032a03032a2a0303032a03032a03032a2a03032a03032a2a03032a
-2a03032a0303032a03032a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a0e0e1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c
-1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c
-1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c
-1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c
-1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c04040e0e0e0e0e0e
-0e0e0e0e0e0e0e040e0e0e0e0e0e0e0e0e0e0e0e0e0e04042a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a1404
-292915030304292929142a2a2a2a2a2a2a2a2a2a2a2a2a2a04042a2a2a2a2a2a2a0e0e2a
-2a2a2a2a2a2a2a030303030303032a03032a03032a2a03032a03032a2a03032a2a2a2a2a
-2a03032a2a2a03032a03032a2a03032a030303032a2a2a03032a2a03032a03032a2a0303
-2a2a03032a03032a03032a2a03032a2a03032a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a0e0e1c1c1c1c1c1c1c1c1c1c1c1c1c1c
-1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c
-1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c
-1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c
-1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c
-040e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e04042a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a1404292915030304292929142a2a2a2a2a2a2a2a2a2a2a2a2a2a04042a2a
-2a2a2a2a2a0e0e2a2a2a2a2a2a2a2a03032a2a2a03032a03032a03032a2a03032a030303
-0303032a2a2a2a2a2a03032a2a2a03032a03032a2a03032a030303032a2a2a03032a2a03
-032a03032a2a03032a2a03032a03032a03032a2a03032a2a03032a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a0e0e040404040404
-040404040404040404040404040404040404040404040404040404040404040404040404
-040404040404040404040404040404040404040404040404040404040404040404040404
-040404040404040404040404040404040404040404040404040404040404040404040404
-040404040404040404040404040404040404040404040404040404040404040404040404
-040404040404040404040404040404040404040404040404040404040404040404040404
-040404042a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a1404292915030304292929142a2a2a2a2a2a2a2a2a2a
-2a2a2a2a04042a2a2a2a2a2a2a0e0e2a2a2a2a2a2a2a2a03032a2a2a03032a03032a0303
-2a2a03032a03032a2a2a2a2a2a2a2a2a2a03032a2a2a03032a03032a2a03032a03032a03
-032a2a03032a2a03032a03032a2a03032a2a03032a03032a03032a2a03032a2a03032a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-0e0404040404040404040404040404040404040404040404040404040404040404040404
-040404040404040404040404040404040404040404040404040404040404040404040404
-040404040404040404040404040404040404040404040404040404040404040404040404
-040404040404040404040404040404040404040404040404040404040404040404040404
-040404040404040404040404040404040404040404040404040404040404040404040404
-0404040404040404040404042a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a1404292915030304292929142a2a
-2a2a2a2a2a2a2a2a2a2a2a2a04042a2a2a2a2a2a2a0e0e2a2a2a2a2a2a2a2a03032a2a2a
-03032a03032a03032a0303032a03032a2a03032a2a2a2a2a2a2a03032a03032a2a03032a
-2a03032a03032a2a03032a03032a2a03032a03032a2a03032a2a2a03032a2a03032a2a2a
-03032a2a03032a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a140429291503
-0304292929142a2a2a2a2a2a2a2a2a2a2a2a2a2a04042a2a2a2a2a2a2a0e0e2a2a2a2a2a
-2a2a2a03032a2a2a03032a03032a2a03032a03032a2a030303032a2a2a2a2a2a2a2a0303
-0303032a2a03032a2a03032a03032a2a2a030303032a2a03032a2a030303032a2a2a2a03
-032a2a03032a2a2a03032a2a03032a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a1404292915030304292929142a2a2a2a2a2a2a2a2a2a2a2a2a2a04040e0e0e0e0e0e
-0e0e0e2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a1404292915030304292929142a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a1404292915030304292929142a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e2a2a2a2a2a2a14042929150303042929
-29142a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e042a2a2a2a2a2a1404
-292915030304292929142a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a0e0e1c1c1c1c1c1c1c0e1c1c1c1c1c1c1c0404
-2a2a2a2a2a2a1404292915030304292929142a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a0e0e1c1c1c1c1c1c040e1c
-1c1c1c1c1c1c04042a2a2a2a2a2a1404292915030304292929142a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a0e0e1c
-1c1c1c1c1c040e0e1c1c1c1c1c1c04042a2a2a2a2a2a1404292915030304292929142a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a0e0e1c1c1c1c1c04040e0e1c1c1c1c1c1c04042a2a2a2a2a2a140429291503
-0304292929142a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a0e0e1c1c1c1c1c04042a0e0e1c1c1c1c1c04042a2a2a2a
-2a2a1404292915030304292929142a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a0e0e1c1c1c1c04042a2a0e0e1c1c1c
-1c1c04042a2a2a2a2a2a1404292915030304292929142a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a0e0e1c1c1c1c04
-042a2a2a0e0e1c1c1c1c04042a2a2a2a2a2a1404292915030304292929142a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a0e0e1c1c1c04042a2a2a2a0e0e1c1c1c1c04042a2a2a2a2a2a14042929150303042929
-29142a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a0e0e1c1c1c04042a2a2a2a2a0e0e1c1c1c04042a2a2a2a2a2a1404
-292915030304292929142a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a0e0e1c1c04042a2a2a2a2a2a0e0e1c1c1c0404
-2a2a2a2a2a2a1404292915030304292929142a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a0e0e1c1c04042a2a2a2a2a
-2a2a0e0e1c1c04042a2a2a2a2a2a1404292915030304292929142a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a31312a2a2a2a2a2a2a2a2a2a2a2a31312a2a2a2a31312a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a31
-312a2a2a2a2a2a2a2a2a2a2a2a2a2a31312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a0e0e1c
-04042a2a2a2a2a2a2a2a0e0e1c1c04042a2a2a2a2a2a1404292915030304292929142a2a
-2a2a2a2a2a2a2a2a2a2a2a30302a2a303030302a30303030302a30302a30302a3030302a
-2a30302a2a30302a30303030302a3030302a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a312a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a0e0e1c04042a2a2a2a2a2a2a2a2a0e0e1c04042a2a2a2a2a2a140429291503
-0304292929142a2a2a2a2a2a2a2a2a2a2a2a2a2a302a2a302a2a302a2a302a2a302a302a
-2a2a302a2a302a2a302a2a302a302a2a2a302a2a302a2a302a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a31312a312a
-2a31312a31312a2a2a2a2a2a2a2a2a3131312a2a3131312a2a2a2a31312a2a2a2a2a312a
-2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a31312a312a2a312a31312a2a2a2a31312a2a2a2a3131312a2a2a31312a
-2a2a31312a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a31312a2a2a2a31312a2a2a312a3131
-2a2a2a31312a2a2a312a3131312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a31312a312a2a312a31312a2a2a2a31312a
-2a2a2a3131312a2a2a31312a2a2a31312a2a2a2a2a2a2a2a2a2a313131312a31312a312a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a0e0e04040e0e0e0e0e0e0e0e0e0e0e0e1c04042a2a2a2a
-2a2a1404292915030304292929142a2a2a2a2a2a2a2a2a2a2a2a2a2a302a2a302a2a3030
-2a302a2a30302a2a2a2a30302a302a2a302a2a302a302a302a302a2a30302a302a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a312a312a312a2a312a2a312a2a2a2a2a2a2a2a312a2a2a2a2a312a2a312a2a312a
-2a312a2a2a2a312a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a312a312a2a312a2a312a2a312a2a312a2a312a
-2a2a2a2a2a2a312a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a312a2a2a312a2a312a2a312a
-2a312a2a312a312a2a2a312a2a312a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a312a312a2a312a
-2a312a2a312a2a312a2a312a2a2a2a2a2a2a312a2a2a2a2a312a2a2a2a2a2a2a2a2a2a31
-2a2a2a312a312a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a0e0e040e0e0e0e0e0e0e0e0e0e0e0e
-0e0e04042a2a2a2a2a2a1404292915030304292929142a2a2a2a2a2a2a2a2a2a2a2a2a2a
-302a2a302a2a302a30302a2a302a302a2a2a302a30302a2a302a2a302a302a302a302a2a
-302a30302a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a312a312a312a2a312a2a312a2a2a2a2a2a2a2a2a31312a2a2a
-312a2a312a2a3131312a2a2a2a2a312a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a312a312a2a312a2a312a2a
-3131312a2a2a2a31312a2a2a2a2a312a2a2a3131312a2a2a2a2a2a2a2a2a2a2a312a2a2a
-312a2a312a2a312a2a2a2a2a31312a2a2a2a3131312a2a2a2a312a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a31
-2a312a312a2a312a2a312a2a3131312a2a2a2a31312a2a2a2a2a312a2a2a3131312a2a2a
-2a2a2a2a2a2a2a312a2a2a312a312a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a0e0e1c1c1c1c1c
-1c1c1c1c1c1c1c1c1c1c04042a2a2a2a2a2a1404292915030304292929142a2a2a2a2a2a
-2a2a2a2a2a2a2a2a302a2a302a2a302a2a302a2a302a2a302a2a302a2a302a2a302a2a30
-2a2a302a302a2a2a302a2a302a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a312a312a2a312a2a312a2a2a2a2a2a
-2a2a2a2a2a312a2a312a2a312a2a312a2a312a2a2a2a312a2a2a2a2a312a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a312a31
-2a2a312a2a312a2a312a2a312a2a2a2a2a312a2a2a2a312a2a312a2a312a2a2a2a2a2a2a
-2a2a2a2a312a2a2a312a2a312a2a312a2a312a2a312a312a2a2a312a2a312a2a2a312a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a312a312a312a2a312a2a312a2a312a2a312a2a2a2a2a312a2a2a2a312a
-2a312a2a312a2a2a2a2a2a2a2a2a2a312a2a31312a312a312a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a0e0e04040404040404040404040404040404042a2a2a2a2a2a14042929150303042929
-29142a2a2a2a2a2a2a2a2a2a2a2a2a2a2a30302a2a30302a2a302a3030302a2a3030302a
-2a302a2a2a30302a2a2a302a302a2a30302a2a302a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a312a31312a2a31
-312a2a2a2a2a2a2a2a2a3131312a2a3131312a31312a2a31312a2a2a31313131312a3131
-3131312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a312a312a31313131312a31312a2a31312a2a2a3131312a2a2a31313131312a3131
-2a312a2a2a2a2a2a2a2a31313131312a2a31312a2a2a2a31312a2a31312a31312a2a2a31
-312a2a2a313131312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a312a31313131312a31312a2a31312a2a2a3131
-312a2a2a31313131312a31312a312a2a2a2a2a2a2a2a2a2a31312a312a312a31312a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a0e0e04040404040404040404040404040e04042a2a2a2a2a2a1404
-292915030304292929142a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a0e0e04042a2a2a2a2a2a2a2a2a2a2a0e0e0404
-2a2a2a2a2a2a1404292915030304292929142a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a31312a2a2a2a3131313131312a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a3131313131312a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a3131313131
-312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a0e0e04042a2a2a2a2a2a2a
-2a2a2a2a0e0e04042a2a2a2a2a2a1404292915030304292929142a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a0e0e04
-042a2a2a2a2a2a2a2a2a2a2a0e0e04042a2a2a2a2a2a1404292915030304292929142a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a0e0e04042a2a2a2a2a2a2a2a2a2a2a0e0e04042a2a2a2a2a2a140429291503
-0304292929142a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a0e0e04042a2a2a2a2a2a2a2a2a2a2a0e0e04042a2a2a2a
-2a2a1404292915030304292929142a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a0e0e04042a2a2a2a2a2a2a2a2a2a2a
-0e0e04042a2a2a2a2a2a1404292915030304292929142a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a0e0e04042a2a2a
-2a2a2a2a2a2a2a2a0e0e04042a2a2a2a2a2a1404292915030304292929142a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a0e0e04042a2a2a2a2a2a2a2a2a2a2a0e0e04042a2a2a2a2a2a14042929150303042929
-29142a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a0e0e04042a2a2a2a2a2a2a2a2a2a2a0e0e04042a2a2a2a2a2a1404
-292915030304292929142a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a0e0e04042a2a2a2a2a2a2a2a2a2a2a0e0e0404
-2a2a2a2a2a2a1404292915030304292929142a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a0e0e04042a2a2a2a2a2a2a
-2a2a2a2a0e0e04042a2a2a2a2a2a1404292915030304292929142a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a0e0e04
-042a2a2a2a2a2a2a2a2a2a2a0e0e04042a2a2a2a2a2a1404292915030304292929142a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a0e0e04042a2a2a2a2a2a2a2a2a2a2a0e0e04042a2a2a2a2a2a140429291503
-0304292929142a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a0e0e04042a2a2a2a2a2a2a2a2a2a2a0e0e04042a2a2a2a
-2a2a1404292915030304292929142a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a0e0e04042a2a2a2a2a2a2a2a2a2a2a
-0e0e04042a2a2a2a2a2a1404292915030304292929142a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a0e0e04042a2a2a
-2a2a2a2a2a2a2a2a0e0e04042a2a2a2a2a2a1404292915030304292929142a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a0e0e04042a2a2a2a2a2a2a2a2a2a2a0e0e04042a2a2a2a2a2a14042929150303042929
-29142a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a0e0e04042a2a2a2a2a2a2a2a2a2a2a0e0e04042a2a2a2a2a2a1404
-292915030304292929142a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a0e0e04042a2a2a2a2a2a2a2a2a2a2a0e0e0404
-2a2a2a2a2a2a1404292915030304292929142a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a0e0e04040e0e0e0e0e0e0e
-0e0e0e0e0e0e04042a2a2a2a2a2a1404292915030304292929142a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a0e0e04
-0e0e0e0e0e0e0e0e0e0e0e0e0e0e04042a2a2a2a2a2a1404292915030304292929142a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a0e0e1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c04042a2a2a2a2a2a140429291503
-0304292929142a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a302a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a0e0e1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c04042a2a2a2a
-2a2a1404292915030304292929142a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a302a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a312a2a2a2a2a31312a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a0e0e1c1c1c1c1c1c1c1c1c1c1c1c1c
-1c1c04042a2a2a2a2a2a1404292915030304292929142a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a302a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a
-2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a0e0e1c1c1c1c1c
-1c1c1c1c1c1c1c1c1c1c04042a2a2a2a2a2a1404292915030304292929142a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a302a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a
-2a2a2a2a2a312a31312a2a2a2a31312a2a312a312a31312a2a2a2a2a2a2a313131312a2a
-2a31312a2a2a2a3131312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a0e0e1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c04042a2a2a2a2a2a14042929150303042929
-29142a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a302a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a312a2a2a2a2a2a2a2a2a2a2a2a312a2a312a2a312a2a312a312a312a312a2a2a2a2a2a
-2a2a2a312a2a2a2a2a2a312a2a2a312a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a0e0e1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c04042a2a2a2a2a2a1404
-292915030304292929142a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a302a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a312a2a312a2a3131312a2a312a31
-2a312a2a2a2a2a2a2a2a2a312a2a2a2a2a2a312a2a2a312a2a312a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a0e0e1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c0404
-2a2a2a2a2a2a1404292915030304292929142a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a302a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a312a2a312a2a
-312a2a312a2a312a312a2a2a2a2a2a2a2a2a2a312a2a312a2a2a312a2a2a312a2a312a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a0e0e1c1c1c1c1c1c1c1c1c
-1c1c1c1c1c1c04042a2a2a2a2a2a1404292915030304292929142a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a302a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a
-2a3131312a31312a2a31312a2a2a312a312a2a2a2a2a2a2a2a2a2a2a31312a2a31313131
-312a2a31312a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a0e0e1c
-1c1c1c1c1c1c1c1c1c1c1c1c1c1c04042a2a2a2a2a2a1404292915030304292929142a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a302a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a0e0e1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c04042a2a2a2a2a2a140429291503
-0304292929142a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a302a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a31
-31313131312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a0e0e1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c04042a2a2a2a
-2a2a1404292915030304292929142a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a302a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a0e0e1c1c1c1c1c1c1c1c1c1c1c1c1c
-1c1c04042a2a2a2a2a2a1404292915030304292929142a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a302a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a0e0e1c1c1c1c1c
-1c1c1c1c1c1c1c1c1c1c04042a2a2a2a2a2a1404292915030304292929142a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a302a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a
-2a03032a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a0e0e1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c04042a2a2a2a2a2a14042929150303042929
-29142a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a302a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a312a2a2a2a030303032a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a0e0e1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c04042a2a2a2a2a2a1404
-292915030304292929142a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a302a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a312a2a0303030303032a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a0e0e1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c0404
-2a2a2a2a2a2a1404292915030304292929142a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a302a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a03030303030303030303030303030303030303
-030303030303030303030303030303030303030303030303030303030303030303030303
-030303030303030303030303030303030303030303030303030303030303030303030303
-030303030303030303030303030303030303030303030303030303030303030303030303
-030303030303030303030303030303030303030303030303030303030303030303030303
-030303030303030303030303030303030303030303030303030303030303030303030303
-030303030303030303030303030303030303030303030303030303030303030303030303
-0303030303312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a0e0e1c1c1c1c1c1c1c1c1c
-1c1c1c1c1c1c04042a2a2a2a2a2a1404292915030304292929142a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a302a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a03030303032a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a0e0e1c
-1c1c1c1c1c1c1c1c1c1c1c1c1c1c04042a2a2a2a2a2a1404292915030304292929142a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a302a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a
-2a2a030303032a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a0e0e1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c04042a2a2a2a2a2a140429291503
-0304292929142a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a302a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a312a2a2a2a2a2a2a03032a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a0e0e1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c04042a2a2a2a
-2a2a1404292915030304292929142a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a302a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a0e0e1c1c1c1c1c1c1c1c1c1c1c1c1c
-1c1c04042a2a2a2a2a2a1404292915030304292929142a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a302a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a0e0e1c1c1c1c1c
-1c1c1c1c1c1c1c1c1c1c04042a2a2a2a2a2a1404292915030304292929142a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a302a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a0e0e1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c04042a2a2a2a2a2a14042929150303042929
-29142a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a302a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a0e0e1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c04042a2a2a2a2a2a1404
-292915030304292929142a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a302a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a0e0e1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c0404
-2a2a2a2a2a2a1404292915030304292929142a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a302a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a0e0e1c1c1c1c1c1c1c1c1c
-1c1c1c1c1c1c04042a2a2a2a2a2a1404292915030304292929142a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a302a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a0e0e1c
-1c1c1c1c1c1c1c1c1c1c1c1c1c1c04042a2a2a2a2a2a1404292915030304292929142a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a302a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a0e0e1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c04042a2a2a2a2a2a140429291503
-0304292929142a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a302a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a0e0e1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c04042a2a2a2a
-2a2a1404292915030304292929142a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a302a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a0e0e1c1c1c1c1c1c1c1c1c1c1c1c1c
-1c1c04042a2a2a2a2a2a1404292915030304292929142a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a302a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a0e0e1c1c1c1c1c
-1c1c1c1c1c1c1c1c1c1c04042a2a2a2a2a2a1404292915030304292929142a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a302a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a0e0e1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c04042a2a2a2a2a2a14042929150303042929
-29142a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a302a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a312a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a31312a2a2a2a2a2a2a2a2a2a2a2a2a2a31312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a0e0e1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c04042a2a2a2a2a2a1404
-292915030304292929142a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a302a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a0e0e1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c0404
-2a2a2a2a2a2a1404292915030304292929142a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a302a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a313131312a2a
-312a31313131312a31312a2a2a2a2a2a2a312a312a31312a312a3131312a2a31312a2a2a
-313131312a2a2a31312a2a2a2a2a2a2a2a2a2a2a312a2a2a2a31312a2a2a2a31312a2a2a
-312a31312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a0e0e1c1c1c1c1c1c1c1c1c
-1c1c1c1c1c1c04042a2a2a2a2a2a1404292915030304292929142a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a302a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a
-2a2a2a312a2a2a2a2a312a2a2a2a312a2a312a2a2a2a2a2a2a312a312a312a2a2a312a2a
-2a2a2a2a312a2a2a2a312a2a2a2a312a2a312a2a2a2a2a2a2a2a2a2a312a2a2a312a2a31
-2a2a312a2a312a2a312a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a0e0e1c
-1c1c1c1c1c1c1c1c1c1c1c1c1c1c04042a2a2a2a2a2a1404292915030304292929142a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a302a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a
-2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a312a2a2a2a312a2a312a2a2a2a2a2a2a312a31
-2a312a2a2a312a2a2a2a2a2a312a2a2a2a312a2a2a2a3131312a2a2a2a2a2a2a2a2a2a2a
-312a2a2a312a2a312a2a312a2a2a2a2a31312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a0e0e1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c04042a2a2a2a2a2a140429291503
-0304292929142a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a302a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a312a2a312a2a312a2a2a2a312a2a312a2a
-2a2a2a2a2a2a312a312a2a2a2a312a2a2a2a2a2a312a2a2a2a312a2a312a312a2a312a2a
-2a2a2a2a2a2a2a2a312a2a2a312a2a312a2a312a2a312a2a312a312a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a0e0e1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c04042a2a2a2a
-2a2a1404292915030304292929142a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a302a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a31312a2a31313131
-2a2a2a31312a2a2a2a2a2a2a2a2a312a312a2a2a313131312a2a31313131312a2a2a3131
-2a2a2a31312a2a2a2a2a2a2a2a2a31313131312a2a31312a2a2a2a31312a2a31312a3131
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a0e0e1c1c1c1c1c1c1c1c1c1c1c1c1c
-1c1c04042a2a2a2a2a2a1404292915030304292929142a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a302a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a0e0e1c1c1c1c1c
-1c1c1c1c1c1c1c1c1c1c04042a2a2a2a2a2a1404292915030304292929142a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a302a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a31312a2a2a2a3131313131312a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a3131313131312a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a0e0e1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c04042a2a2a2a2a2a14042929150303042929
-29142a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a302a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a0e0e1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c04042a2a2a2a2a2a1404
-292915030304292929142a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a302a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a0e0e1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c0404
-2a2a2a2a2a2a1404292915030304292929142a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a302a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a03032a2a2a2a2a2a2a312a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a0e0e1c1c1c1c1c1c1c1c1c
-1c1c1c1c1c1c04042a2a2a2a2a2a1404292915030304292929142a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a302a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a030303032a2a2a2a
-2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a0e0e1c
-1c1c1c1c1c1c1c1c1c1c1c1c1c1c04042a2a2a2a2a2a1404292915030304292929142a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a302a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a0303030303032a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a0e0e1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c04042a2a2a2a2a2a140429291503
-0304292929142a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a302a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a03030303030303030303030303030303030303030303030303030303030303
-030303030303030303030303030303030303030303030303030303030303030303030303
-030303030303030303030303030303030303030303030303030303030303030303030303
-0303030303030303030303030303030303312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a0e0e1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c04042a2a2a2a
-2a2a1404292915030304292929142a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a302a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a0303030303032a2a312a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a0e0e1c1c1c1c1c1c1c1c1c1c1c1c1c
-1c1c04042a2a2a2a2a2a1404292915030304292929142a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a302a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a0303032a2a2a2a2a312a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a0e0e1c1c1c1c1c
-1c1c1c1c1c1c1c1c1c1c04042a2a2a2a2a2a1404292915030304292929142a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a302a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a03032a2a
-2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a0e0e1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c04042a2a2a2a2a2a14042929150303042929
-29142a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a302a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a0e0e1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c04042a2a2a2a2a2a1404
-292915030304292929142a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a302a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a0e0e1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c0404
-2a2a2a2a2a2a1404292915030304292929142a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a302a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a0e0e1c1c1c1c1c1c1c1c1c
-1c1c1c1c1c1c04042a2a2a2a2a2a1404292915030304292929142a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a302a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a0e0e1c
-1c1c1c1c1c1c1c1c1c1c1c1c1c1c04042a2a2a2a2a2a1404292915030304292929142a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a302a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a0e0e1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c04042a2a2a2a2a2a140429291503
-0304292929142a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a302a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a0e0e1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c04042a2a2a2a
-2a2a1404292915030304292929142a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a302a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a0e0e1c1c1c1c1c1c1c1c1c1c1c1c1c
-1c1c04042a2a2a2a2a2a1404292915030304292929142a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a302a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a0e0e1c1c1c1c1c
-1c1c1c1c1c1c1c1c1c1c04042a2a2a2a2a2a1404292915030304292929142a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a302a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a0e0e1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c04042a2a2a2a2a2a14042929150303042929
-29142a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a302a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a0e0e1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c04042a2a2a2a2a2a1404
-292915030304292929142a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a302a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a0e0e1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c0404
-2a2a2a2a2a2a1404292915030304292929142a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a302a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a0e0e1c1c1c1c1c1c1c1c1c
-1c1c1c1c1c1c04042a2a2a2a2a2a1404292915030304292929142a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a302a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a
-2a2a2a2a31312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a0e0e1c
-1c1c1c1c1c1c1c1c1c1c1c1c1c1c04042a2a2a2a2a2a1404292915030304292929142a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a302a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a31
-2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a0e0e1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c04042a2a2a2a2a2a140429291503
-0304292929142a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a302a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a31312a312a312a3131312a31312a2a2a31
-2a31312a2a2a313131312a2a2a31312a2a2a2a3131312a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a0e0e1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c04042a2a2a2a
-2a2a1404292915030304292929142a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a302a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a312a2a312a2a2a312a2a
-2a2a2a2a312a2a2a312a2a312a2a2a312a2a2a2a312a2a312a2a312a2a312a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a0e0e1c1c1c1c1c1c1c1c1c1c1c1c1c
-1c1c04042a2a2a2a2a2a1404292915030304292929142a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a302a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a312a
-2a312a2a2a312a2a2a2a3131312a2a2a312a2a312a2a2a312a2a2a2a3131312a2a2a312a
-2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a0e0e1c1c1c1c1c
-1c1c1c1c1c1c1c1c1c1c04042a2a2a2a2a2a1404292915030304292929142a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a302a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a
-2a2a2a2a2a2a312a2a312a2a2a312a2a2a312a2a312a2a2a312a2a312a2a2a312a2a312a
-312a2a312a2a312a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a0e0e1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c04042a2a2a2a2a2a14042929150303042929
-29142a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a302a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a312a2a2a2a2a2a2a2a2a2a2a2a2a3131312a2a313131312a2a31312a312a3131312a31
-312a2a2a31312a2a2a31312a2a2a2a31312a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a0e0e1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c04042a2a2a2a2a2a1404
-292915030304292929142a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a302a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a0e0e1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c0404
-2a2a2a2a2a2a1404292915030304292929142a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a302a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a3131312a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a0e0e1c1c1c1c1c1c1c1c1c
-1c1c1c1c1c1c04042a2a2a2a2a2a1404292915030304292929142a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a302a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a0e0e1c
-1c1c1c1c1c1c1c1c1c1c1c1c1c1c04042a2a2a2a2a2a1404292915030304292929142a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a302a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a0e0e1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c04042a2a2a2a2a2a140429291503
-0304292929142a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a302a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a312a2a2a2a2a2a2a03032a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a0e0e1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c04042a2a2a2a
-2a2a1404292915030304292929142a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a302a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a030303032a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a0e0e1c1c1c1c1c1c1c1c1c1c1c1c1c
-1c1c04042a2a2a2a2a2a1404292915030304292929142a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a302a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a0303030303032a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a0e0e1c1c1c1c1c
-1c1c1c1c1c1c1c1c1c1c04042a2a2a2a2a2a1404292915030304292929142a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a302a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a03030303030303
-030303030303030303030303030303030303030303030303030303030303030303030303
-030303030303030303030303030303030303030303030303030303030303030303030303
-030303030303030303030303030303030303030303030303030303030303030303030303
-0303030303312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a0e0e1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c04042a2a2a2a2a2a14042929150303042929
-29142a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a302a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a312a2a03030303032a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a0e0e1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c04042a2a2a2a2a2a1404
-292915030304292929142a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a302a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a312a2a2a2a030303032a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a0e0e1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c0404
-2a2a2a2a2a2a1404292915030304292929142a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a302a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a03032a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a0e0e1c1c1c1c1c1c1c1c1c
-1c1c1c1c1c1c04042a2a2a2a2a2a1404292915030304292929142a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a302a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a0e0e1c
-1c1c1c1c1c1c1c1c1c1c1c1c1c1c04042a2a2a2a2a2a1404292915030304292929142a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a302a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a0e0e1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c04042a2a2a2a2a2a140429291503
-0304292929142a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a302a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a0e0e1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c04042a2a2a2a
-2a2a1404292915030304292929142a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a302a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a0e0e1c1c1c1c1c1c1c1c1c1c1c1c1c
-1c1c04042a2a2a2a2a2a1404292915030304292929142a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a302a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a0e0e1c1c1c1c1c
-1c1c1c1c1c1c1c1c1c1c04042a2a2a2a2a2a1404292915030304292929142a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a302a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a0e0e1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c04042a2a2a2a2a2a14042929150303042929
-29142a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a302a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a0e0e1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c04042a2a2a2a2a2a1404
-292915030304292929142a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a302a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a0e0e1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c0404
-2a2a2a2a2a2a1404292915030304292929142a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a302a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a0e0e1c1c1c1c1c1c1c1c1c
-1c1c1c1c1c1c04042a2a2a2a2a2a1404292915030304292929142a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a302a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a0e0e1c
-1c1c1c1c1c1c1c1c1c1c1c1c1c1c04042a2a2a2a2a2a1404292915030304292929142a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a302a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a0e0e1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c04042a2a2a2a2a2a140429291503
-0304292929142a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a302a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a0e0e1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c04042a2a2a2a
-2a2a1404292915030304292929142a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a302a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a32322a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a322a
-2a2a2a322a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a0e0e1c1c1c1c1c1c1c1c1c1c1c1c1c
-1c1c04042a2a2a2a2a2a1404292915030304292929142a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a302a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a322a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a322a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a0e0e1c1c1c1c1c
-1c1c1c1c1c1c1c1c1c1c04042a2a2a2a2a2a1404292915030304292929142a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a302a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a
-2a2a2a2a2a2a2a3232322a2a2a32322a2a2a2a2a2a2a2a2a2a32322a2a2a2a32322a2a32
-322a322a2a32322a322a2a2a2a32322a2a2a323232322a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a0e0e1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c04042a2a2a2a2a2a14042929150303042929
-29142a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a302a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a312a2a2a2a2a2a2a2a2a2a2a2a322a2a322a2a322a2a322a2a2a2a2a2a2a2a322a2a32
-2a2a322a2a322a322a322a322a322a322a322a2a2a2a322a2a2a2a322a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a0e0e1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c04042a2a2a2a2a2a1404
-292915030304292929142a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a302a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a322a2a322a2a322a2a322a2a2a2a
-2a2a2a2a322a2a2a2a2a322a2a322a322a322a322a322a322a322a2a2a2a322a2a2a2a32
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a0e0e1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c0404
-2a2a2a2a2a2a1404292915030304292929142a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a302a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a322a2a322a2a
-322a2a322a2a2a2a2a2a2a2a322a2a322a2a322a2a322a322a322a322a322a322a322a2a
-2a2a322a2a2a2a322a2a322a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a0e0e1c1c1c1c1c1c1c1c1c
-1c1c1c1c1c1c04042a2a2a2a2a2a1404292915030304292929142a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a302a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a
-2a2a2a32322a322a2a32322a2a2a2a2a2a2a2a2a2a32322a2a2a2a32322a2a322a322a32
-32322a322a32322a32323232322a2a2a32322a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a0e0e1c
-1c1c1c1c1c1c1c1c1c1c1c1c1c1c04042a2a2a2a2a2a1404292915030304292929142a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a302a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a0e0e1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c04042a2a2a2a2a2a140429291503
-0304292929142a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a302a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a3232323232322a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a0e0e1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c04042a2a2a2a
-2a2a1404292915030304292929142a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a302a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a0e0e1c1c1c1c1c1c1c1c1c1c1c1c1c
-1c1c04042a2a2a2a2a2a1404292915030304292929142a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a302a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a0e0e1c1c1c1c1c
-1c1c1c1c1c1c1c1c1c1c04042a2a2a2a2a2a1404292915030304292929142a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a302a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a0e0e1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c04042a2a2a2a2a2a14042929150303042929
-29142a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a302a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a0e0e1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c04042a2a2a2a2a2a1404
-292915030304292929142a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a302a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a0e0e1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c0404
-2a2a2a2a2a2a1404292915030304292929142a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a302a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a0e0e1c1c1c1c1c1c1c1c1c
-1c1c1c1c1c1c04042a2a2a2a2a2a1404292915030304292929142a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a302a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a0e0e1c
-1c1c1c1c1c1c1c1c1c1c1c1c1c1c04042a2a2a2a2a2a1404292915030304292929142a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a302a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a0e0e1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c04042a2a2a2a2a2a140429291503
-0304292929142a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a302a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a0e0e1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c04042a2a2a2a
-2a2a1404292915030304292929142a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a302a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a0e0e1c1c1c1c1c1c1c1c1c1c1c1c1c
-1c1c04042a2a2a2a2a2a1404292915030304292929142a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a302a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a0e0e1c1c1c1c1c
-1c1c1c1c1c1c1c1c1c1c04042a2a2a2a2a2a1404292915030304292929142a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a302a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a0e0e1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c04042a2a2a2a2a2a14042929150303042929
-29142a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a302a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a0e0e1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c04042a2a2a2a2a2a1404
-292915030304292929142a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a302a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a0e0e1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c0404
-2a2a2a2a2a2a1404292915030304292929142a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a302a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a0e0e1c1c1c1c1c1c1c1c1c
-1c1c1c1c1c1c04042a2a2a2a2a2a1404292915030304292929142a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a302a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a0e0e1c
-1c1c1c1c1c1c1c1c1c1c1c1c1c1c04042a2a2a2a2a2a1404292915030304292929142a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a302a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a0e0e1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c04042a2a2a2a2a2a140429291503
-0304292929142a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a302a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a0e0e1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c04042a2a2a2a
-2a2a1404292915030304292929142a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a302a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a0e0e1c1c1c1c1c1c1c1c1c1c1c1c1c
-1c1c04042a2a2a2a2a2a1404292915030304292929142a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a302a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a0e0e1c1c1c1c1c
-1c1c1c1c1c1c1c1c1c1c04042a2a2a2a2a2a1404292915030304292929142a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a302a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a0e0e1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c04042a2a2a2a2a2a14042929150303042929
-29142a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a302a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a31312a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a312a
-2a2a2a2a31312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a0e0e1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c04042a2a2a2a2a2a1404
-292915030304292929142a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a302a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a31
-2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a0e0e1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c0404
-2a2a2a2a2a2a1404292915030304292929142a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a302a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a312a3131312a
-2a31312a2a2a2a2a312a2a2a2a31312a2a2a31312a2a2a2a2a3131312a2a2a31312a2a2a
-2a2a2a2a2a2a313131312a2a2a31312a2a2a2a3131312a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a0e0e1c1c1c1c1c1c1c1c1c
-1c1c1c1c1c1c04042a2a2a2a2a2a1404292915030304292929142a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a302a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a
-2a2a2a312a2a2a2a312a2a312a2a2a2a312a2a2a312a2a312a2a2a2a312a2a2a312a2a2a
-2a2a312a2a312a2a2a2a2a2a2a2a2a312a2a2a2a2a2a312a2a2a312a2a312a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a0e0e1c
-1c1c1c1c1c1c1c1c1c1c1c1c1c1c04042a2a2a2a2a2a1404292915030304292929142a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a302a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a
-2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a3131312a2a2a2a2a312a2a2a3131312a2a2a3131
-312a2a2a2a31312a2a2a3131312a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a312a2a2a312a
-2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a0e0e1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c04042a2a2a2a2a2a140429291503
-0304292929142a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a302a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a312a2a312a2a2a2a312a2a2a
-312a2a312a312a2a312a2a2a2a2a2a312a2a312a2a312a2a2a2a2a2a2a2a2a312a2a312a
-2a2a312a2a2a312a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a0e0e1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c04042a2a2a2a
-2a2a1404292915030304292929142a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a302a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a313131312a2a2a31312a
-2a2a31313131312a2a31312a2a2a31312a312a2a3131312a2a2a2a31312a2a2a2a2a2a2a
-2a2a2a2a31312a2a31313131312a2a31312a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a0e0e1c1c1c1c1c1c1c1c1c1c1c1c1c
-1c1c04042a2a2a2a2a2a1404292915030304292929142a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a302a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a0e0e1c1c1c1c1c
-1c1c1c1c1c1c1c1c1c1c04042a2a2a2a2a2a1404292915030304292929142a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a302a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a3131313131312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a0e0e1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c04042a2a2a2a2a2a14042929150303042929
-29142a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a302a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a0e0e1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c04042a2a2a2a2a2a1404
-292915030304292929142a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a302a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a0e0e1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c0404
-2a2a2a2a2a2a1404292915030304292929142a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a302a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a03032a2a2a2a2a2a2a312a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a0e0e1c1c1c1c1c1c1c1c1c
-1c1c1c1c1c1c04042a2a2a2a2a2a1404292915030304292929142a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a302a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a030303032a2a2a2a
-2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a0e0e1c
-1c1c1c1c1c1c1c1c1c1c1c1c1c1c04042a2a2a2a2a2a1404292915030304292929142a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a302a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a0303030303032a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a0e0e1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c04042a2a2a2a2a2a140429291503
-0304292929142a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a302a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a03030303030303030303030303030303030303030303030303030303030303
-030303030303030303030303030303030303030303030303030303030303030303030303
-030303030303030303030303030303030303030303030303030303030303030303030303
-0303030303030303030303030303030303312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a0e0e1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c04042a2a2a2a
-2a2a1404292915030304292929142a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a302a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a0303030303032a2a312a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a0e0e1c1c1c1c1c1c1c1c1c1c1c1c1c
-1c1c04042a2a2a2a2a2a1404292915030304292929142a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a302a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a0303032a2a2a2a2a312a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a0e0e1c1c1c1c1c
-1c1c1c1c1c1c1c1c1c1c04042a2a2a2a2a2a1404292915030304292929142a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a302a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a03032a2a
-2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a0e0e1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c04042a2a2a2a2a2a14042929150303042929
-29142a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a302a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a0e0e1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c04042a2a2a2a2a2a1404
-292915030304292929142a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a302a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a0e0e1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c0404
-2a2a2a2a2a2a1404292915030304292929142a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a302a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a0e0e1c1c1c1c1c1c1c1c1c
-1c1c1c1c1c1c04042a2a2a2a2a2a1404292915030304292929142a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a302a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a0e0e1c
-1c1c1c1c1c1c1c1c1c1c1c1c1c1c04042a2a2a2a2a2a1404292915030304292929142a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a302a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a0e0e1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c04042a2a2a2a2a2a140429291503
-0304292929142a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a302a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a0e0e1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c04042a2a2a2a
-2a2a1404292915030304292929142a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a302a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a0e0e1c1c1c1c1c1c1c1c1c1c1c1c1c
-1c1c04042a2a2a2a2a2a1404292915030304292929142a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a302a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a0e0e1c1c1c1c1c
-1c1c1c1c1c1c1c1c1c1c04042a2a2a2a2a2a1404292915030304292929142a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a302a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a0e0e1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c04042a2a2a2a2a2a14042929150303042929
-29142a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a302a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a0e0e1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c04042a2a2a2a2a2a1404
-292915030304292929142a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a302a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a0e0e1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c0404
-2a2a2a2a2a2a1404292915030304292929142a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a302a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a0e0e1c1c1c1c1c1c1c1c1c
-1c1c1c1c1c1c04042a2a2a2a2a2a1404292915030304292929142a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a302a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a
-2a2a2a2a31312a2a2a2a2a2a2a2a2a31312a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a
-2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a0e0e1c
-1c1c1c1c1c1c1c1c1c1c1c1c1c1c04042a2a2a2a2a2a1404292915030304292929142a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a302a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a31
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a0e0e1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c04042a2a2a2a2a2a140429291503
-0304292929142a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a302a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a3131312a2a2a31312a2a2a2a2a312a2a2a
-2a31312a2a2a313131312a2a2a31312a2a2a2a2a2a2a2a2a313131312a2a312a3131312a
-31312a2a2a312a31312a2a2a2a3131312a2a31312a2a2a2a2a31312a2a2a313131312a2a
-2a31312a2a2a2a31312a2a312a31312a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a0e0e1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c04042a2a2a2a
-2a2a1404292915030304292929142a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a302a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a312a2a312a2a312a2a31
-2a2a2a2a312a2a2a312a2a312a2a2a312a2a2a2a312a2a312a2a2a2a2a2a2a2a2a312a2a
-2a2a2a312a2a2a2a2a2a312a2a2a312a2a312a2a312a2a2a2a2a2a2a312a2a2a312a2a31
-2a2a2a312a2a2a2a2a2a312a2a2a312a2a312a2a312a2a312a312a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a0e0e1c1c1c1c1c1c1c1c1c1c1c1c1c
-1c1c04042a2a2a2a2a2a1404292915030304292929142a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a302a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a312a
-2a312a2a3131312a2a2a2a2a312a2a2a3131312a2a2a2a312a2a2a2a3131312a2a2a2a2a
-2a2a2a2a2a312a2a2a2a2a312a2a2a2a3131312a2a2a312a2a312a2a2a31312a2a2a3131
-312a2a2a312a2a2a2a2a2a312a2a2a2a2a2a312a2a2a312a2a312a2a312a2a312a312a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a0e0e1c1c1c1c1c
-1c1c1c1c1c1c1c1c1c1c04042a2a2a2a2a2a1404292915030304292929142a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a302a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a
-2a2a2a2a2a2a312a2a312a2a312a2a312a2a2a2a312a2a2a312a2a312a2a2a312a2a312a
-312a2a312a2a2a2a2a2a2a2a2a312a2a312a2a312a2a2a312a2a312a2a2a312a2a312a2a
-2a2a2a312a312a2a312a2a2a312a2a312a2a2a312a2a312a2a2a312a2a2a312a2a312a2a
-312a2a312a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a0e0e1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c04042a2a2a2a2a2a14042929150303042929
-29142a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a302a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a312a2a2a2a2a2a2a2a2a2a2a2a2a31312a312a2a31312a2a2a31313131312a2a31312a
-2a2a2a2a31312a2a2a31312a2a2a2a2a2a2a2a2a2a2a31312a2a313131312a2a31312a31
-2a3131312a31312a3131312a2a2a31312a312a2a2a31312a2a2a2a2a31312a2a31313131
-312a2a31312a2a3131312a3131312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a0e0e1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c04042a2a2a2a2a2a1404
-292915030304292929142a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a302a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a0e0e1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c0404
-2a2a2a2a2a2a1404292915030304292929142a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a302a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a3131313131312a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a0e0e1c1c1c1c1c1c1c1c1c
-1c1c1c1c1c1c04042a2a2a2a2a2a1404292915030304292929142a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a302a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a0e0e1c
-1c1c1c1c1c1c1c1c1c1c1c1c1c1c04042a2a2a2a2a2a1404292915030304292929142a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a302a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a0e0e1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c04042a2a2a2a2a2a140429291503
-0304292929142a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a302a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a03032a2a2a2a2a2a2a312a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a0e0e1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c04042a2a2a2a
-2a2a1404292915030304292929142a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a302a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a030303032a2a2a2a
-2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a0e0e1c1c1c1c1c1c1c1c1c1c1c1c1c
-1c1c04042a2a2a2a2a2a1404292915030304292929142a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a302a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a0303030303032a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a0e0e1c1c1c1c1c
-1c1c1c1c1c1c1c1c1c1c04042a2a2a2a2a2a1404292915030304292929142a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a302a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a03030303030303
-030303030303030303030303030303030303030303030303030303030303030303030303
-030303030303030303030303030303030303030303030303030303030303030303030303
-030303030303030303030303030303030303030303030303030303030303030303030303
-030303030303030303030303030303030303030303030303030303030303030303030303
-030303030303030303030303030303030303030303030303030303030303030303030303
-030303030303030303030303030303030303030303030303030303030303030303030303
-0303030303030303030303030303030303312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a0e0e1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c04042a2a2a2a2a2a14042929150303042929
-29142a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a302a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a0303030303032a2a312a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a0e0e1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c04042a2a2a2a2a2a1404
-292915030304292929142a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a302a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a0303032a2a2a2a2a312a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a0e0e1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c0404
-2a2a2a2a2a2a1404292915030304292929142a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a302a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a03032a2a
-2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a0e0e1c1c1c1c1c1c1c1c1c
-1c1c1c1c1c1c04042a2a2a2a2a2a1404292915030304292929142a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a302a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a0e0e1c
-1c1c1c1c1c1c1c1c1c1c1c1c1c1c04042a2a2a2a2a2a1404292915030304292929142a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a302a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a0e0e1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c04042a2a2a2a2a2a140429291503
-0304292929142a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a302a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a0e0e1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c04042a2a2a2a
-2a2a1404292915030304292929142a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a302a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a0e0e1c1c1c1c1c1c1c1c1c1c1c1c1c
-1c1c04042a2a2a2a2a2a1404292915030304292929142a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a302a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a0e0e1c1c1c1c1c
-1c1c1c1c1c1c1c1c1c1c04042a2a2a2a2a2a1404292915030304292929142a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a302a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a0e0e1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c04042a2a2a2a2a2a14042929150303042929
-29142a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a302a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a0e0e1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c04042a2a2a2a2a2a1404
-292915030304292929142a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a302a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a0e0e1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c0404
-2a2a2a2a2a2a1404292915030304292929142a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a302a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a0e0e1c1c1c1c1c1c1c1c1c
-1c1c1c1c1c1c04042a2a2a2a2a2a1404292915030304292929142a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a302a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a0e0e1c
-1c1c1c1c1c1c1c1c1c1c1c1c1c1c04042a2a2a2a2a2a1404292915030304292929142a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a302a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a0e0e1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c04042a2a2a2a2a2a140429291503
-0304292929142a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a302a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a0e0e1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c04042a2a2a2a
-2a2a1404292915030304292929142a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a302a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a32322a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a322a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a0e0e1c1c1c1c1c1c1c1c1c1c1c1c1c
-1c1c04042a2a2a2a2a2a1404292915030304292929142a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a302a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a322a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a32
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a0e0e1c1c1c1c1c
-1c1c1c1c1c1c1c1c1c1c04042a2a2a2a2a2a1404292915030304292929142a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a302a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a
-2a2a2a2a2a2a2a32322a2a322a32322a2a2a2a3232322a2a2a2a2a2a2a2a2a32322a2a32
-322a32322a2a323232322a2a2a32322a2a2a322a3232322a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a0e0e1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c04042a2a2a2a2a2a14042929150303042929
-29142a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a302a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a312a2a2a2a2a2a2a2a2a2a2a2a322a2a322a2a322a2a322a2a322a2a322a2a2a2a2a2a
-2a2a322a2a322a2a322a2a322a2a2a322a2a2a2a322a2a322a2a2a322a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a0e0e1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c04042a2a2a2a2a2a1404
-292915030304292929142a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a302a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a3232322a2a2a322a2a322a2a322a
-2a322a2a2a2a2a2a2a2a322a2a322a2a322a2a322a2a2a322a2a2a2a3232322a2a2a2a32
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a0e0e1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c0404
-2a2a2a2a2a2a1404292915030304292929142a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a302a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a322a2a322a2a
-322a2a322a2a322a2a322a2a2a2a2a2a2a2a322a2a322a2a322a2a322a2a2a322a2a322a
-322a2a322a2a2a322a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a0e0e1c1c1c1c1c1c1c1c1c
-1c1c1c1c1c1c04042a2a2a2a2a2a1404292915030304292929142a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a302a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a
-2a2a2a32322a2a3232322a32322a2a32322a322a2a2a2a2a2a2a2a32322a2a2a2a32322a
-322a2a2a32322a2a2a32322a2a2a323232322a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a0e0e1c
-1c1c1c1c1c1c1c1c1c1c1c1c1c1c04042a2a2a2a2a2a1404292915030304292929142a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a302a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a0e0e1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c04042a2a2a2a2a2a140429291503
-0304292929142a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a302a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a32
-32323232322a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a0e0e1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c04042a2a2a2a
-2a2a1404292915030304292929142a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a302a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a0e0e1c1c1c1c1c1c1c1c1c1c1c1c1c
-1c1c04042a2a2a2a2a2a1404292915030304292929142a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a302a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a0e0e1c1c1c1c1c
-1c1c1c1c1c1c1c1c1c1c04042a2a2a2a2a2a1404292915030304292929142a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a302a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a0e0e1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c04042a2a2a2a2a2a14042929150303042929
-29142a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a302a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a0e0e1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c04042a2a2a2a2a2a1404
-292915030304292929142a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a302a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a0e0e1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c0404
-2a2a2a2a2a2a1404292915030304292929142a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a302a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a0e0e1c1c1c1c1c1c1c1c1c
-1c1c1c1c1c1c04042a2a2a2a2a2a1404292915030304292929142a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a302a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a0e0e1c
-1c1c1c1c1c1c1c1c1c1c1c1c1c1c04042a2a2a2a2a2a1404292915030304292929142a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a302a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a0e0e1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c04042a2a2a2a2a2a140429291503
-0304292929142a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a302a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a0e0e1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c04042a2a2a2a
-2a2a1404292915030304292929142a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a302a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a0e0e1c1c1c1c1c1c1c1c1c1c1c1c1c
-1c1c04042a2a2a2a2a2a1404292915030304292929142a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a302a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a0e0e1c1c1c1c1c
-1c1c1c1c1c1c1c1c1c1c04042a2a2a2a2a2a1404292915030304292929142a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a302a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a0e0e1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c04042a2a2a2a2a2a14042929150303042929
-29142a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a302a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a0e0e1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c04042a2a2a2a2a2a1404
-292915030304292929142a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a302a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a0e0e1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c0404
-2a2a2a2a2a2a1404292915030304292929142a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a302a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a0e0e1c1c1c1c1c1c1c1c1c
-1c1c1c1c1c1c04042a2a2a2a2a2a1404292915030304292929142a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a302a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a0e0e1c
-1c1c1c1c1c1c1c1c1c1c1c1c1c1c04042a2a2a2a2a2a1404292915030304292929142a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a302a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a0e0e1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c04042a2a2a2a2a2a140429291503
-0304292929142a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a302a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a0e0e1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c04042a2a2a2a
-2a2a1404292915030304292929142a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a302a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a0e0e1c1c1c1c1c1c1c1c1c1c1c1c1c
-1c1c04042a2a2a2a2a2a1404292915030304292929142a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a302a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a0e0e1c1c1c1c1c
-1c1c1c1c1c1c1c1c1c1c04042a2a2a2a2a2a1404292915030304292929142a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a302a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a0e0e1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c04042a2a2a2a2a2a14042929150303042929
-29142a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a302a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a0e0e1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c04042a2a2a2a2a2a1404
-292915030304292929142a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a302a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a0e0e1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c0404
-2a2a2a2a2a2a1404292915030304292929142a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a302a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a0e0e1c1c1c1c1c1c1c1c1c
-1c1c1c1c1c1c04042a2a2a2a2a2a1404292915030304292929142a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a302a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a0e0e1c
-1c1c1c1c1c1c1c1c1c1c1c1c1c1c04042a2a2a2a2a2a1404292915030304292929142a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a302a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a0e0e1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c04042a2a2a2a2a2a140429291503
-0304292929142a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a302a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a0e0e1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c04042a2a2a2a
-2a2a1404292915030304292929142a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a302a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a0e0e1c1c1c1c1c1c1c1c1c1c1c1c1c
-1c1c04042a2a2a2a2a2a1404292915030304292929142a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a302a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a0e0e1c1c1c1c1c
-1c1c1c1c1c1c1c1c1c1c04042a2a2a2a2a2a1404292915030304292929142a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a302a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a0e0e1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c04042a2a2a2a2a2a14042929150303042929
-29142a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a302a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a0e0e1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c04042a2a2a2a2a2a1404
-292915030304292929142a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a302a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a0e0e1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c0404
-2a2a2a2a2a2a1404292915030304292929142a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a302a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a0e0e1c1c1c1c1c1c1c1c1c
-1c1c1c1c1c1c04042a2a2a2a2a2a1404292915030304292929142a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a302a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a0e0e1c
-1c1c1c1c1c1c1c1c1c1c1c1c1c1c04042a2a2a2a2a2a1404292915030304292929142a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a302a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a0e0e1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c04042a2a2a2a2a2a140429291503
-0304292929142a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a302a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a0e0e1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c04042a2a2a2a
-2a2a1404292915030304292929142a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a302a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a0e0e1c1c1c1c1c1c1c1c1c1c1c1c1c
-1c1c04042a2a2a2a2a2a1404292915030304292929142a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a302a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a0e0e1c1c1c1c1c
-1c1c1c1c1c1c1c1c1c1c04042a2a2a2a2a2a1404292915030304292929142a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a302a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a0e0e04040404040404040404040404040404042a2a2a2a2a2a14042929150303042929
-29142a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a302a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a0e0e1c040404040404040404040404040e04042a2a2a2a2a2a1404
-292915030304292929142a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a302a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a0e0e1c04042a2a2a2a2a2a2a2a2a0e0e1c0404
-2a2a2a2a2a2a1404292915030304292929142a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a302a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a0e0e1c1c04042a2a2a2a2a
-2a2a2a0e0e1c04042a2a2a2a2a2a1404292915030304292929142a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a302a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a0e0e1c
-1c04042a2a2a2a2a2a2a0e0e1c1c04042a2a2a2a2a2a1404292915030304292929142a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a302a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a0e0e1c1c1c04042a2a2a2a2a2a0e0e1c1c04042a2a2a2a2a2a140429291503
-0304292929142a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a302a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a0e0e1c1c1c04042a2a2a2a2a0e0e1c1c1c04042a2a2a2a
-2a2a1404292915030304292929142a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a302a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a0e0e1c1c1c1c04042a2a2a2a0e0e1c
-1c1c04042a2a2a2a2a2a1404292915030304292929142a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a302a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a0e0e1c1c1c1c04
-042a2a2a0e0e1c1c1c1c04042a2a2a2a2a2a1404292915030304292929142a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a302a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a0e0e1c1c1c1c1c04042a2a0e0e1c1c1c1c04042a2a2a2a2a2a14042929150303042929
-29142a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a302a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a0e0e1c1c1c1c1c04042a0e0e1c1c1c1c1c04042a2a2a2a2a2a1404
-292915030304292929142a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a302a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a0e0e1c1c1c1c1c1c040e0e0e1c1c1c1c1c0404
-2a2a2a2a2a2a1404292915030304292929142a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a302a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a0e0e1c1c1c1c1c1c040e0e
-1c1c1c1c1c1c04042a2a2a2a2a2a1404292915030304292929142a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a302a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a0e0e1c
-1c1c1c1c1c1c0e0e1c1c1c1c1c1c04042a2a2a2a2a2a1404292915030304292929142a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a302a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a0e0e1c1c1c1c1c1c1c0e1c1c1c1c1c1c1c04042a2a2a2a2a2a140429291503
-0304292929142a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a302a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a0e0e04040404040404040404040404040404042a2a2a2a
-2a2a1404292915030304292929142a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a302a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a0e0404040404040404040404040404
-040404042a2a2a2a2a2a1404292915030304292929142a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a302a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a312a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a312a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a1404292915030304292929142a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a14042929150303042929
-29142a2a2a2a2a2a0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e
-0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e
-0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e
-0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e
-0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e
-0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e
-0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e
-0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e
-0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e
-0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e
-0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e
-0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e
-0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e
-0e0e0e0e0e0e0e2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a1404
-292915030304292929142a2a2a2a2a2a0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e
-0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e
-0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e
-0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e
-0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e
-0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e
-0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e
-0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e
-0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e
-0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e
-0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e
-0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e
-0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e
-0e0e0e0e0e0e0e0e0e0e0e0e0e0e042a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a1404292915030304292929142a2a2a2a2a2a0e0e1c1c1c1c1c1c1c1c1c1c
-1c1c1c1c041c040404040404040404040404040404040404040404040404040404040404
-040404040404040404040404040404040404040404040404040404040404040404040404
-040404040404040404040404040404040404040404040404040404040404040404040404
-040404040404040404040404040404040404040404040404040404040404040404040404
-040404040404040404040404040404040404040404040404040404040404040404040404
-040404040404040404040404040404040404040404040404040404040404040404040404
-040404040404040404040404040404040404040404040404040404040404040404040404
-040404040404040404040404040404040404040404040404040404040404040404040404
-040404040404040404040404040404040404040404040404040404040404040404041c1c
-1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c
-1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c
-1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c
-1c1c1c1c1c1c04041c1c1c1c1c1c1c1c1c1c1c1c1c04042a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a1404292915030304292929142a2a2a2a2a2a0e0e1c1c
-1c1c1c1c1c1c1c1c1c1c04040e1c04040404040404040404040404040404040404040404
-040404040404040404040404040404040404040404040404040404040404040404040404
-040404040404040404040404040404040404040404040404040404040404040404040404
-040404040404040404040404040404040404040404040404040404040404040404040404
-040404040404040404040404040404040404040404040404040404040404040404040404
-040404040404040404040404040404040404040404040404040404040404040404040404
-040404040404040404040404040404040404040404040404040404040404040404040404
-040404040404040404040404040404040404040404040404040404040404040404040404
-040404040404040404040404040404040404040404040404040404040404040404040404
-04040404040e1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c
-1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c
-1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c
-1c1c1c1c1c1c1c1c1c1c1c1c1c1c040404041c1c1c1c1c1c1c1c1c1c1c04042a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a14042929150303150a0a0a0a2a2a
-2a2a2a2a0e0e1c1c1c1c1c1c1c1c1c1c0404040e0e1c04042a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a0e0e1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c
-1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c
-1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c
-1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c0404040404041c1c1c1c1c1c1c1c
-1c04042a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a0a150a0a0303
-03232323230a2a2a2a2a2a2a0e0e1c1c1c1c1c1c1c1c040404042a0e0e1c04042a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a0e0e1c1c1c1c1c1c1c1c1c1c1c1c1c1c
-1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c
-1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c
-1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c04042a2a0404
-04041c1c1c1c1c1c1c04042a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a0a2315150a0303231515150a2a2a2a2a2a2a0e0e1c1c1c1c1c1c040404042a2a2a0e
-0e1c04042a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a0e0e1c1c1c1c1c1c
-1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c
-1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c
-1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c
-1c1c04042a2a2a2a040404041c1c1c1c1c04042a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a0a2315150a0303231515150a2a2a2a2a2a2a0e0e1c1c1c1c0404
-04042a2a2a2a2a0e0e1c04042a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-0e0e1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c
-1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c
-1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c
-1c1c1c1c1c1c1c1c1c1c04042a2a2a2a2a2a040404041c1c1c04042a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a0a2315150a0303231515150a2a2a2a2a2a2a
-0e0e1c1c040404042a2a2a2a2a2a2a0e0e1c04042a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a0e0e1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c
-1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c
-1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c
-1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c04042a2a2a2a2a2a2a2a040404041c04042a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a0a2315150a0303231515
-150a2a2a2a2a2a2a0e0e0e0e0e0e2a2a2a2a2a2a2a2a2a0e0e1c04042a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a0e0e1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c
-1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c
-1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c
-1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c04042a2a2a2a2a2a2a2a
-2a0e0e0e0e04042a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a0a23
-15150a0303231515150a2a2a2a2a2a2a0e0e1c1c0e0e0e0e2a2a2a2a2a2a2a0e0e1c0404
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a0e0e1c1c1c1c1c1c1c1c1c1c
-1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c
-1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c
-1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c0404
-2a2a2a2a2a2a2a2a0e0e0e0e1c04042a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a0a2315150a0303231515150a2a2a2a2a2a2a0e0e1c1c1c1c0e0e0e0e2a2a
-2a2a2a0e0e1c04042a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a0e0e1c1c
-1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c
-1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c
-1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c
-1c1c1c1c1c1c04042a2a2a2a2a2a0e0e0e0e1c1c1c04042a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a0a2315150a0303231515150a2a2a2a2a2a2a0e0e1c1c
-1c1c1c1c0e0e0e0e2a2a2a0e0e1c04042a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a0e0e1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c
-1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c
-1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c
-1c1c1c1c1c1c1c1c1c1c1c1c1c1c04042a2a2a2a0e0e0e0e1c1c1c1c1c04042a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a0a2315150a0303231515150a2a2a
-2a2a2a2a0e0e1c1c1c1c1c1c1c1c0e0e0e0e2a0e0e1c04042a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a0e0e1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c
-1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c
-1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c
-1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c04042a2a0e0e0e0e1c1c1c1c1c1c
-1c04042a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a0a2315150a03
-03231515150a2a2a2a2a2a2a0e0e1c1c1c1c1c1c1c1c1c1c0e0e0e0e0e1c04042a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a0e0e1c1c1c1c1c1c1c1c1c1c1c1c1c1c
-1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c
-1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c
-1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c04040e0e0e0e
-1c1c1c1c1c1c1c1c1c04042a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a0a2315150a0303231515150a2a2a2a2a2a2a0e0e1c1c1c1c1c1c1c1c1c1c1c1c0e0e
-0e1c04040e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e
-0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e
-0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e
-0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e
-0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e
-0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e
-0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e
-0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e
-0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e1c1c1c1c1c1c
-1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c
-1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c
-1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c
-1c1c04040e0e1c1c1c1c1c1c1c1c1c1c1c04042a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a0a2315150a0303231515150a2a2a2a2a2a2a0e0e1c1c1c1c1c1c
-1c1c1c1c1c1c1c1c0e1c040e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e
-0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e
-0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e
-0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e
-0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e
-0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e
-0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e
-0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e
-0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e
-0e0e1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c
-1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c
-1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c
-1c1c1c1c1c1c1c1c1c1c040e1c1c1c1c1c1c1c1c1c1c1c1c1c04042a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a0a2315150a0303231515150a2a2a2a2a2a2a
-0e0e04040404040404040404040404040404040404040404040404040404040404040404
-040404040404040404040404040404040404040404040404040404040404040404040404
-040404040404040404040404040404040404040404040404040404040404040404040404
-040404040404040404040404040404040404040404040404040404040404040404040404
-040404040404040404040404040404040404040404040404040404040404040404040404
-040404040404040404040404040404040404040404040404040404040404040404040404
-040404040404040404040404040404040404040404040404040404040404040404040404
-040404040404040404040404040404040404040404040404040404040404040404040404
-040404040404040404040404040404040404040404040404040404040404040404040404
-040404040404040404040404040404040404040404040404040404040404040404040404
-040404040404040404040404040404040404040404040404040404040404040404040404
-040404040404040404040404040404040404040404040404040404040404040404040404
-04040404040404040404040404040404040404040404040404040404040404040404042a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a0a2315150a0303231515
-150a2a2a2a2a2a2a0e040404040404040404040404040404040404040404040404040404
-040404040404040404040404040404040404040404040404040404040404040404040404
-040404040404040404040404040404040404040404040404040404040404040404040404
-040404040404040404040404040404040404040404040404040404040404040404040404
-040404040404040404040404040404040404040404040404040404040404040404040404
-040404040404040404040404040404040404040404040404040404040404040404040404
-040404040404040404040404040404040404040404040404040404040404040404040404
-040404040404040404040404040404040404040404040404040404040404040404040404
-040404040404040404040404040404040404040404040404040404040404040404040404
-040404040404040404040404040404040404040404040404040404040404040404040404
-040404040404040404040404040404040404040404040404040404040404040404040404
-040404040404040404040404040404040404040404040404040404040404040404040404
-040404040404040404040404040404040404040404040404040404040404040404040404
-040404040404042a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a0a23
-15150a0303231515150a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
-2a2a2a2a2a2a0a2315150a030323151515150a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a1414
-141414141414141414141414141414141414141414141414141414141414141414141414
-141414141414141414141414141414141414141414141414141414141414141414141414
-141414141414141414141414141414141414141414141414141414141414141414141414
-141414141414141414141414141414141414141414141414141414141414141414141414
-141414141414141414141414141414141414141414141414141414141414141414141414
-141414141414141414141414141414141414141414141414141414141414141414141414
-141414141414141414141414141414141414141414141414141414141414141414141414
-141414141414141414141414141414141414141414141414141414141414141414141414
-141414141414141414141414141414141414141414141414141414141414141414141414
-141414141414141414141414141414141414141414141414141414141414141414141414
-141414141414141414141414141414141414141414141414141414141414141414141414
-141414141414141414141414141414141414141414141414141414141414141414141414
-14141414141414141414141414141414141414141414141414141414141414141414150a
-0a0a0a0a0a0a0a0a0a0a0a0a0a0a231515150a0302032315151515232323232323232323
-232323232315040404040404040404040404040404040404040404040404040404040404
-040404040404040404040404040404040404040404040404040404040404040404040404
-040404040404040404040404040404040404040404040404040404040404040404040404
-040404040404040404040404040404040404040404040404040404040404040404040404
-040404040404040404040404040404040404040404040404040404040404040404040404
-040404040404040404040404040404040404040404040404040404040404040404040404
-040404040404040404040404040404040404040404040404040404040404040404040404
-040404040404040404040404040404040404040404040404040404040404040404040404
-040404040404040404040404040404040404040404040404040404040404040404040404
-040404040404040404040404040404040404040404040404040404040404040404040404
-040404040404040404040404040404040404040404040404040404040404040404040404
-040404040404040404040404040404040404040404040404040404040404040404040404
-040404040404040404040404040404040404040404040404040404040404040404040404
-040404040404232323232323232323232323232323231515150a03040103231515151515
-151515151515151515151515150a29292929292929292929292929292929292929292929
-292929292929292929292929292929292929292929292929292929292929292929292929
-292929292929292929292929292929292929292929292929292929292929292929292929
-292929292929292929292929292929292929292929292929292929292929292929292929
-292929292929292929292929292929292929292929292929292929292929292929292929
-292929292929292929292929292929292929292929292929292929292929292929292929
-292929292929292929292929292929292929292929292929292929292929292929292929
-292929292929292929292929292929292929292929292929292929292929292929292929
-292929292929292929292929292929292929292929292929292929292929292929292929
-292929292929292929292929292929292929292929292929292929292929292929292929
-292929292929292929292929292929292929292929292929292929292929292929292929
-292929292929292929292929292929292929292929292929292929292929292929292929
-292929292929292929292929292929292929292929292929292929292929292929292929
-2929292929292929292929292929231515151515151515151515151515151515150a0304
-0101030a0a151515151515151515151515151515150a2929292929292929292929292929
-292929292929292929292929292929292929292929292929292929292929292929292929
-292929292929292929292929292929292929292929292929292929292929292929292929
-292929292929292929292929292929292929292929292929292929292929292929292929
-292929292929292929292929292929292929292929292929292929292929292929292929
-292929292929292929292929292929292929292929292929292929292929292929292929
-292929292929292929292929292929292929292929292929292929292929292929292929
-292929292929292929292929292929292929292929292929292929292929292929292929
-292929292929292929292929292929292929292929292929292929292929292929292929
-292929292929292929292929292929292929292929292929292929292929292929292929
-292929292929292929292929292929292929292929292929292929292929292929292929
-292929292929292929292929292929292929292929292929292929292929292929292929
-292929292929292929292929292929292929292929292929292929292929292929292929
-292929292929292929292929292929292929292929292315151515151515151515151515
-1515150a0a03040402010103030a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a151515151515
-151515151515151515151515151515151515151515151515151515151515151515151515
-151515151515151515151515151515151515151515151515151515151515151515151515
-151515151515151515151515151515151515151515151515151515151515151515151515
-151515151515151515151515151515151515151515151515151515151515151515151515
-151515151515151515151515151515151515151515151515151515151515151515151515
-151515151515151515151515151515151515151515151515151515151515151515151515
-151515151515151515151515151515151515151515151515151515151515151515151515
-151515151515151515151515151515151515151515151515151515151515151515151515
-151515151515151515151515151515151515151515151515151515151515151515151515
-151515151515151515151515151515151515151515151515151515151515151515151515
-151515151515151515151515151515151515151515151515151515151515151515151515
-151515151515151515151515151515151515151515151515151515151515151515151515
-151515151515151515151515151515151515151515151515151515151515150a0a0a0a0a
-0a0a0a0a0a0a0a0a0a0a0a03030303040001020001030303030303030303030303030303
-030303030303030303030303030303030303030303030303030303030303030303030303
-030303030303030303030303030303030303030303030303030303030303030303030303
-030303030303030303030303030303030303030303030303030303030303030303030303
-030303030303030303030303030303030303030303030303030303030303030303030303
-030303030303030303030303030303030303030303030303030303030303030303030303
-030303030303030303030303030303030303030303030303030303030303030303030303
-030303030303030303030303030303030303030303030303030303030303030303030303
-030303030303030303030303030303030303030303030303030303030303030303030303
-030303030303030303030303030303030303030303030303030303030303030303030303
-030303030303030303030303030303030303030303030303030303030303030303030303
-030303030303030303030303030303030303030303030303030303030303030303030303
-030303030303030303030303030303030303030303030303030303030303030303030303
-030303030303030303030303030303030303030303030303030303030303030303030303
-030303030303030303030303030303030303030303040403
-%%PageTrailer
-%%Trailer
-%%EOF
diff --git a/lib/et/doc/src/sim_trans_write_lock.gif b/lib/et/doc/src/sim_trans_write_lock.gif
deleted file mode 100644
index d62505fe35..0000000000
--- a/lib/et/doc/src/sim_trans_write_lock.gif
+++ /dev/null
Binary files differ
diff --git a/lib/et/doc/src/sim_trans_write_lock.png b/lib/et/doc/src/sim_trans_write_lock.png
new file mode 100644
index 0000000000..1ce15a33c5
--- /dev/null
+++ b/lib/et/doc/src/sim_trans_write_lock.png
Binary files differ
diff --git a/lib/et/doc/src/sim_trans_write_lock.ps b/lib/et/doc/src/sim_trans_write_lock.ps
deleted file mode 100644
index 80e03852dc..0000000000
--- a/lib/et/doc/src/sim_trans_write_lock.ps
+++ /dev/null
@@ -1,1287 +0,0 @@
-%!PS-Adobe-3.0 EPSF-3.0
-%%Creator: GIMP PostScript file plugin V 1.12 by Peter Kirchgessner
-%%Title: /home/hakan/picts/sim_trans_write_lock.ps
-%%CreationDate: Mon Oct 14 17:06:30 2002
-%%DocumentData: Clean7Bit
-%%LanguageLevel: 2
-%%Pages: 1
-%%BoundingBox: 14 14 359 199
-%%EndComments
-%%BeginProlog
-% Use own dictionary to avoid conflicts
-10 dict begin
-%%EndProlog
-%%Page: 1 1
-% Translate for offset
-14.173228 14.173228 translate
-% Translate to begin of first scanline
-0.000000 184.755782 translate
-344.431594 -184.755782 scale
-% Image geometry
-412 221 8
-% Transformation matrix
-[ 412 0 0 221 0 0 ]
-% Strings to hold RGB-samples per scanline
-/rstr 412 string def
-/gstr 412 string def
-/bstr 412 string def
-{currentfile /ASCII85Decode filter /RunLengthDecode filter rstr readstring pop}
-{currentfile /ASCII85Decode filter /RunLengthDecode filter gstr readstring pop}
-{currentfile /ASCII85Decode filter /RunLengthDecode filter bstr readstring pop}
-true 3
-%%BeginData: 74154 ASCII Bytes
-colorimage
-!AQV60nB=U!.b.=!<5%\0f_7E~>
-r'Z)9JH16$mf<8RJ,~>
-"DW"!C3+q+JH16$mf<B/!budtJ,~>
-r]0uYnc&S<J[C!8]<hPemJd0^mJd0^nc/Uh!]_tqJ,~>
-r^?bdnc&SGS\BZdT=P"ZmJd0[mJd0[nc/Uhr^;8~>
-rcA)>nc&SuJaS*W]C#Z.mJd0^mJd0^nc/Uhrc<S~>
-s"OQTs8W)KqVM,3!%EJWb_q%)n:Lcks3:GkqVM/4!i5k@qpkQ"r8n'Vs3:GkqVDD<s8N'Z3Ih~>
-s$Qngs8W)LrS%8-ro3q>!&U[?JWZ.Y!]9r&rmLesrS%8-ro3t?!hoY>rmLesrS%8-ro3t?!hoY>
-rmLesrS%8-"lfR^!(95*~>
-s)S5As8W)KqVM,3!+LN9J_n#q!b22SqpkQ"r8n'Vs3:GkqVM/4!i5k@qpkQ""m5jb!-<43~>
-!]^8\rRLc$qW7c,JTJMG!.4]d!.4]d!.4]d!/(8l!/(8l!/(8l!/(8l!/pht@uG\TF,PBdF,PBd
-F-M#mF-M#mF-M#mF-M#mF-M#mF-M#mF-M#mF-M#mF-M#mF-M#mF-M#mF-M#mF-M#mF-M#mF-M#m
-F-M#mF-M#mF-M#mF-M#mF-M#mF-M#mF-L_ps81@ChYZF9V#U>BqVM,3!Mobmeb\/$joWd-3Ih~>
-"%3.hdf.hrgA]t.ir/!>1kC(kI/nitI/nitI/o!#I/o!#I<UO!I=6s'I=7*+I=76/I=76/I=7B3
-I=7B3I=7B3I=7N7I=7N7I=7N7I=7N7I=7N7I=7Z;I=7Z;I=7Z;I=7Z;I=7Z?I=7Z?I=7Z?I=7Z?
-I=7Z?I=7Z?I=7Z?I=7Z?I=7Z?I=7Z?I=7Z?I=7Z?I=7Z72#mR'rmq&%rndY6roO6Ts8LIGf)=>%
-hYuO6joM1UrmLesrS%8-ro+%Bc2^7_~>
-!cnAArRLc$qW7ceJ^(mQ!7h(n!7h(n!7h(n!7h(n!7h(n!7h(n!7h(ns4..os4..os4..o>MdoT
-c/.!qc/.!qc/.!qc/.!qc/.!qc/.!qc/.!qc/.!qc/.!qc/.!qc/.!qc/.!qc/.!qc/.!qc/.!q
-c/.!qc/.!qc/.!qc/.!qc/.!qc/.!qc/-]Ss81@ChYZF9V#U>BqVM,3!Mobmeb\/$joWd-F+=~>
-!\j]Trmgl%qrRtJjsbjrr+Z:SK6,%I!-A-S!-A-S!.4][!.4][!.4][E.`4HC4gSBC4gSBC5[.J
-C5[.JC5[.JC5[.JC6WdSC6WdSC6WdSC6WdSC6WdSC6WdSC6WdSC6WdSC7K?[C7K?[C7K?[C7K?[
-C7K?[C7K?[C7K?[C7K?[C7K?[C7K?[C7K?[C7K?[C7K?[.KB=rqVM,3!q)lar71Z#qrRtJV#UAC
-qVM/4!mL^"J,~>
-!^m%grmq&%rndY6roO:IjtqX7r-8?lNIf5t!.Fil!.Fil!.k,pIYE2qH%gZlH&6rpH&[5tH'*N#
-H'*N#H'Nf'H'Nf'H's5/H's5/H's5/H's5/H(BM3H(BM3H(BM3H(BM3H(fe7H(fe7H(fe7H(fe7
-H(fe7H(fe7H(fe7H(fe7H(fe7H(fe7H(fe7H(fe7H(fe7H(fe7H(fe72#l"Prmq&%rndY6roO@K
-U&WQhrmq&%rndY6roO@KU&WQhrmq&%rndY6s5jC.!(;>~>
-!cnAArmgl%qrRtJk$in\r5JZ[`l.r&rl"l^rl"l^rl"l^rl+o^s2G#_s2Ag)c,IZPc,IZPc,IZP
-c,IZPc,IZPc,IZPc,IZPc,IZPc,IZPc,IZPc,IZPc,IZPc,IZPc,IZPc,IZPc,IZPc,IZPc,IZP
-c,IZPc,IZPc,IZPc,IZPc,IZPc,IZPc,IZPc,IZPc,F/lr71Z#qrRtJV#UACqVM,3!q)lar71Z#
-r8n(*!-<Y~>
-!<E0!eb\/"k5XiMjsd0Bs5)RH%#`)>PlLd.hVN!^pA`c["nqt2CA.]*C&i>SC&i>SC&iV[C&iV[
-C3>/MC2/BBC2/BBC;m8qC2/ZJC2/uSC2/uSC2/uSC2/uSC2/uSC208[C208[C208[C208[C208[
-C208[C208[C20PkC20PkC20PkC20PkC20PkC20PkC20PkC20PkC20PkC20PkC20PkC20PkC2,3t
-rRLc$qr[qH!Moboeb;B/k5XiMV#UDD!o?4/rSIQ?rT41L]`<Q~>
-!<E0!f)=>%hYuO6k5X]IjtrrXs5)RS%$ehTSbiB7hVNBtpA3Ea#PS":FnYZSH2_pdH2_r9I<fsX
-JU)B\Km@f`M0X5dNHoYhNHoZdZ@-k<Q$mdtR=04#R=04#R=04#SUGX'SUGX'SUGX'Tm_'+Tm_'+
-Tn.?/Tn.?/V1Ec3V1Ec3V1Ec3V1Ec3V1Ec3V1Ec3V1Ec3V1Ec3V1Ec3V1Ec3V1Ec3V1Ec3V1Ec3
-V1Ec3!]9c%rmq&%rndY6roX7G!hoJ=rmpp2r^?bJs69ZZqU5Ao"56"*gA]t/6ic6GjoXhZ!.Y~>
-!<E0!eb\/"k5XiMk$k4,s7Y9f%+Xdbec5[;p@cJEs8U`js8W,<s8N,=c2PZ^c2PZ^c2PZ^c2P]^
-c2Yc_c2Yc_c2Yb"e]l)$k0:lae]l(Pe]l(Pe]l(Pe]l(Pe]l(Pe]l(Pe]l(PhTa$YhTa$YhTa$Y
-hTa$YhTa$YhTa$YhTa$YhTa$YhTa$YhTa$YhTa$YhTa$YhTa$YhTa$YhTa$YhTa$YhTa$YhTa$Y
-@fQDWqVM,3s6]o`s8CLB62p$HmK'-`rRCu+5sbJ+s$?VG!q*`%J,~>
-!s&AOec+G*63#g?k5RaHmK)H!oO7iRPi6'PK9Yk7!J?X%@KP*)3T"9XKE%0%k5S=Fc-87Xp@^4M
-K9Y/#s7QRM@eTLMraGkBraGkBraGkKraL#7S75rSC1:Y!C1:Y)C1:YZs*J45C1:Y1C1:Y1C1:Y:
-C1:Y:C1:Y:F(/UCF(/UCF(/UCF(/UKF(/UKF(/UKF(/UKF(/UKF(/UKF(/UKF(/UKF(/UKF(/UK
-F(/UKF(/UKF(/UKF(/UKF(/UKF(/UKF8fVL.KBCtqVM,3rpBf_s8LOKhY0>9k5OcLV#UGE!8dZ?
-s5*]?s5s@L!PJJ`~>
-!s&APf)FD'5l]^?iWA717/lHPi\^:E!KEZ/D#oWen8/2cSa(%ng<rOLD%VX$R8E&G=\-id88\(o
-4Dg(Kghm)b"?^Ppp,r=k!-S9XI<BOHD0^,<D4-r3D1Q\DD1utHD2ECPD79IqD38sXD3]6\D3]B`
-D3]B`D4,ZdD4,ZdD4,ZdD4PrhD4PrhD4PrhD4u5lD4u5lD4u5lD5DMpD5DMpD5DMpD5DMpD5DMp
-D5DMpD5DMpD5DMpD5DMpD5DMpD5DMpD5DOWD#lKirmq&%rndY6roX4F!MTAhec=G$5lF+Nk5OWH
-U&+c>!8@B:s5*]Bs5s@H!P/8]~>
-!s&AOec+G*63#g?k5RaHmK)HZoXt:Me`"1Bc.2<s!R90[]`RWaKAX?Sc2Z%QpA^%tk2q<0s8R/R
-c.1U_s8N4C^&S+Rrk/<Nrk/<Nrk/<Nrk8?^s1SHOs1N9o`P&t0`P&tIs2D[r`P&t0`P&t8`P&t8
-`P&t8`P&t8`P&t8`P&t8`P&t8`P&t8`P&t8`P&t8`P&t8`P&t8`P&t8`P&t8`P&t8`P&t8`P&t8
-`P&t8`P&t8`P&t8`P&t8`P&t8`P&t8`W!OO@fQGXqVM,3rpBf_s8LOKhY0>9k5OcLV#UGE!8dZ?
-s5*]?s5s@L!PJJ`~>
-!W`8NrndT>rT=,Gs%<=Z!Tkj'=p"Et9&a"UpA[bT=p"Et9'TU[3T"!Qk05VQp@^4=;E6a@p@^4E
-pA[b@>6":$0j=;E0j7air`T;2r`T;:r`X_bpA[a+@TlrV@Tlr^@Tlr^@a4%V@TlrfC0Ff!C0Ff!
-C0Ff!C0Ff!C0Ff*C0Ff*C0Ff*C0Ff*C0Ff*C0Ff*C0Ff2C0Ff2C0Ff2C0Ff2C0Ff2C0Ff2C0Ff2
-C0Ff2C0Ff2C0Ff2C0Ff2C0Ff2C0Ff2C0Ff2=t0L%eb\/"k5F]OV#SuqhVRum!9X7J"f21Ke_]0W
-5lg'HmK(!$J,~>
-!W`8Orn@<9ro*q?rBpbQmc$(qB`e#)=lO,spA.q^B`e#)=mB]%84;?L''@V)=n_\S@:_ttC%h6_
-C%hC+h.co_#<Z_op,m&'D>n7!EG]E(F_ti,H1q);I;N\4JT5C<KlLg@M/gu'H$*h8O`bAPQ$$eT
-Q$$eTQ$$eTR<<4XR<`L\R<`L\SU"p`SU"p`SU"p`Tm:?dTm:?dTm:?dTm:?dTm:?dTm:?dTm:?d
-Tm:?dTm:?dTm:?dTm:?dTm:?dTm:?dTm:?d"efWeqUX6rgA]t.ir8*>l3?[MqUX6OgAF566icBK
-l3?[MqUX6OgAF566icBKl2eHrJ,~>
-!W`8NrndT>rT=,Gs%<=Z!Tmk`[/^.+UuJc]rrAkb[/^.+V!>>eKAX$Kp?$Fds8R/A["F"<s8R/I
-s8SnN[/^.2F0tuIF0r<frj2[=rj2[=rj7*es8Sn.]sP/c]sP/c]sP/c^#nai]sP/k]sP/k]sP/k
-]sP/k]sP/k]sP/k]sP/k]sP/k]sP/k]sP/k]sP/s]sP/s]sP/s]sP/s]sP/s]sP/s]sP/s]sP/s
-]sP/s]sP/s]sP/s]sP/s]sP/s]sP/s]sP/sZss'ceb\/"k5F]OV#SuqhVRum!9X7J"f21Ke_]0W
-5lg'HmK(!$J,~>
-!<E/uhY]\>k5RaH9)n;[jsg1*#'8Z$mZ^VVrr2t>qGI]kk5YJLC/USis6cEV;ZGSWKC8c0;RHH'
-s)SY+s6c+L;Vp8_mf/eT[/U(0F*ldDs6bgA;CBH`K2PUKmS`cY;GqSms6c+LV#PL6`W(9_`P#/j
-hZ*#.;GuB.XPWnR"G?_q3Q;!t#\s)5;H!5^0spr[s)SV*s6c+L;Vp93hGX(Iqbdflk5YJLC/USi
-s6cEV;ZHG(0iI`=0iEATs6cCT;OlnLs6as8rr74iSF6FFS5OE3hVPs.;N(Qr;Gr-V;Gr-V;Gr-V
-;GrE^;GrE^;GrE^;GrEf;GrEf;Gr`o;Gr`o;Gr`o;Gr`o;Gr`o;Gr`o;Gr`o;Gr`o;Gr`o;Gr`o
-;Gr`o;Gr`o;Gr`o;Gr`o;Gr`o;Gr`o;Gr`o;CV=iqVM,3r9aW^p=90!pHe`F!i5P?rSI?9!9X7J
-!PJJ`~>
-!<E/ugAXA;6il<0r'^SQ!TGs5AHmkFqX1%g^Ae-4L&,[email protected],h"d/6LTk1t;
-s8Rc^hYQZ6AS'l\Om`(>A\S0Ds+LU4qZ#uKqIM&"s-7/,[dI`#qIO5lhYQZ6A[;>iA]k%,A^8/(
-L#2[oTk.fpijRkFAH\:uI7VZ_rs3oDqIO73p,p(gs8Rc]hYQZ6AS'l\[c1llqYOh3Woj0Xl?Qs@
-lMp.Lral-''0Kk"p,loChYQZ:Bk==,qZ#i7^Ae.WM5ok@m]'iLET5utk%0hXI:ZuLF_,-HF_,-L
-F_,-LF_,-LF_,-PH"CQTH"CQTH"CQXH"CQXH"CQXH"CQ\H"CQ\H"CQ\H"CQ\H"CQ\H"CQ\H"CQ\
-H"CQ\H"CQ\H"CQ\H"CQ\H"CQ\H"CQ\H"CQ\H"Ai+f)=>%hYuO6k5OZGmK0*Uf)FD%5l3tKlMp8R
-U%[(9gAXA86icBKl2pCb!.Y~>
-!<E/uhY]\>k5RaH9)n;[k$n4p#0$$1p=6P,rr2u;qQpX\pAb0d]sQ>`s7Y"B[/]h'c1_1f[,1f^
-s2>H8s7Y!M[.a4<pA`[MhZ!QT`<>W/s7X_6ZmY#9c*Xk7p9al"['[g?s7Y!MhZ(R%k5WE-k2s%i
-mf3"2[']Q#hY-oT"O6tBKBE15#eg9<[']l5F5Hors2>E7s7Y!M[.a4Mp9al"qm6a]pAb0d]sQ>`
-s7Y"B[/^.>F0tuIF0s3[s7Y!M[+4mMs7XForr75feb9%:e[3</p@dYB[*AWH['\)k['\)k['\)k
-['\)k['\)k['\)k['\)k['\)k['\)k['\As['\As['\As['\B&['\B&['\B&['\B&['\B&['\B&
-['\B&['\B&['\B&['\B&['\B&['\B&['\B&ZsraZqVM,3r9aW^p=90!pHe`F!i5P?rSI?9!9X7J
-!PJJ`~>
-!<E/thYKP;9)e5ZhC8A#$tAquC;p3V@eTh"3D03I25L9/HYSd2SH$Q3^&O<p;YL.I[/]P[@eTh"
-9(q[f`W'+>pAa!Vs6`0^pA\#Nk5TL+F';35;CIJ']h22jUbVT:0k0kEC;p3VHiK!rmf/2;p3TF*
-mV9`@>#P(ohP;n*;BrRK5tYV[s&(TFp+]J=p+^%Ms&)J_mV9`@>#P(ohP;mgjtZg4I\d##HYSd2
-SH$Q3^&O<p;YKf=;YKf=@eT5)`W',;s5&*;PX/LHs&,*]c!%g\S6Ahas5'P+MuTkNHX]lNK47_V
-K47_VMdfR^MdfR^MeZ-fMeZ-fMeZ-fP\O)oP\O)oP\O)oP\O)oP\O)oP\O)oP\O)oP\O)oP\O)o
-+d?_>;Ntoo;Ntoo;Ntoo;Ntoo;Ntoo;Ntoo;Ntoo;CV>9hYZI4mK'[email protected]!)!1W!MoGd
-hYTS=k5=WJ]`<Q~>
-!<E0!gAg"05kmbHmK)0$r*9_Fp?le7s(Q?DqHZ?dr*;1_s5JTPPuXOXb%\`mSR#Ops5LKel:c'g
-qHZqkmVTi@BjLH4ijSmP9PsM">sRQPH!tu0;#=NHOoN-l?0\FTp@^U_p?le7s(R2eO]CiLO]Ct'
-=n_9#_Z+=UpAa!L5lP%6])PT'EVB675kan6?2!tSD>*g3;"j<o_Z+=UpAa!L5j%&grEXlTs5JTP
-PuXOXb%\`mSR#Opp,lXSp,[email protected][5XC%hC/RK(QH_Z-HH?2"<XW^)^HY#'sl?!WG,
-?!WG,?!WG0?!WS4?!WS4?!W_8?!W_8?!W_8?!Wk@?!Wk@?!Wk@?!X"D?!X"D?!X"D?!X"D?!X"D
-?!SVEF^8:DF^8:DF^8:DF^8:DF^8:DF^8:DF^8:DF^890pAN_EhYuO6k5OZFmK'$TrRq<<hVS7k
-roO8MlK\B:!MT5cgAg"05l="Mk5OZGmK'm!J,~>
-!<E/thYKP;9)e5ZhI?Da%(-'.Ut,L@[/^/aH_gS@2:_`pXIQYUc2ZXbec3UiXT/=gec5'%[/^/a
-KE(Y@ec2GHs8VN;s6c,Ys8S"(pA^qHUm.DHX=2'feXW`7c$TKjF0tu@Ut,L@`W*<@pA_Lqs/_Ib
-p8$7=UoaUrm`g+XX<ZU%K:K=Ks,1sus)Y:As)YRIs,2O0p8$7=UoaUrm`g+PmW8?.Ib"JdXIQYU
-c2ZXbec3UiXT/<AXT/<A^&Rf%ec2Gqs6ctY[#;$cs,48ak*4Erc*XSPs6e-Yc2YbQ`O)_J`O)_J
-`O)_J`O)_J`O)_Jc*XRRc+U3[c+U3[c+U3[c+U3[c+U3[c+U3[c+U3[c+U3[c+U3[c+U3[c+U3[
-+jI^%XNeG[XNeG[XNeG[XNeG[XNeG[XNeG[XNeG[XCCo"hYZI4mK'[email protected]!)!1W!MoGd
-hYTS=k5=WJ]`<Q~>
-!<E/uhZ)a:62aFUmf2t]hC8@p$^C[e3K*oi62(",62O80mf-0>5s[Nns%5:Ts5l=6pA[E5p@^45
-p@^5*s.hZ5s+<W2s$8C5p+]25p+\kqs/]]/62F2$pA[F"s&(lNp+_g3UcFA5K1c0W;ZH0u>5pmQ
-s.hZ5s+<W2s$8A"r^nE[s"Qf3p@^4,p@^45p@^45p@^5*s.hZ5s+<W2s$8A"8hi(!8q6:/;DCI'
-3Tg?63ElIF3D0#=0hV050pM^63K*oimf-0>8kM*0p@^6's%5:Ts5l=6pA[E5;Hj+>;Hc[bHWj$6
-K3Cl>K47GFK47GFK47GFK47GFMdf:NMdf:NMdf:NMdf:NMdf:NP[[6WP[[6WP[[6WP[[6WP[[6W
-P[aYb)3eT&8sEdW8sEdW8sEdW8sEdW8sEdW8sEfa8c^C7r8.>5qsOLX!MoGfh>fk=k5XiL9)e8Y
-p&Uu_r8%G9r':<Tr9aX[]`<Q~>
-!W`8Srnd\7qEtNYmdBZ:hDG.5$_@<t8<s43<VH,K<VooVmf-QX9MeFFs&DHus5m!XpA[fOp@^UO
-p@^V:s/JVTs+sbLs%G]Op,lLOp,l@;s/p?A:f[Bq-scE?:jr@P8G;a>Sc>]\Q2c\Ds2&@DlFq-8
-8=BLX8<s43<VH8[5Y1lW,L6<O<E]%h4B;+K4B_CO4B_CO4IQ5L8<s43<VH8[5Y,$C5lFi8mf-QX
-9MeFFs&DHus5m!Xp@^UOp@^V>s/Jb\s,$1D>sMOm9NCf[4QcZD6tQD\9Nh)c83g<ps2J2U=]pSu
-=]pSu=]p`$=]p`$=]p`$=]pl(=]pl,=]q#0=]q#0=]q#0=]q/4=]q/4=]q/4=]q/4=]q/4=]q/4
-=]q/4s&g5-EEQG4EEQG4EEQG4EEQG4EEQG4EEQG4EW0)C2"oYWrndY6roX4FrpKgW#,1bEg>:[O
-ro3q>s69SPrpKgW"/5GBgA]q/iql.DlMg2Qo""gO~>
-!<E/uhZ)a:62aFUmf2t]hI?DY$dJ^jK>mklSH&V1SGT*>pA^%tPa%+"s+>s*s6bf@s8R^us8RGA
-s8R/Zs2BW0s/_ajs+>[us*LRAs)X_(s2D(0PaqTGs8OC'^&O=Ts8R/bs2BW0s/_ajeXZ[5c)gql
-`W*o0`W*$0s8RFmMuKLsk5TLuV#UI9SH&V1V#UI9V#UI9`W*o0`W*$0s8RFmMkk]HrM4r:s,25g
-P`,88K7g9*mYdn@s)Y"9s)ZHb`Il/0XS2[PH^pUaV#UI9pA]btXT.^HV#UIAH^(W3eWd/2UqNk*
-UrB^:UrB^:UrB^:UrB^:UrB^:UrB^:UrB^:UrB^:UrB^:UrB^:Us69BUs69BUs69BUs69BUs69B
-Us6:HU`%FaUnl8BUnl8BUnl8BUnl8BUnl8BUnl8BrhKR(pAEeEk54THp&Uu_rS@N?qr[qH!)!7Y
-s7QJhpAEbIk57LF9)S)Yp:UHV~>
-!<E0!hYlU:62aFUmf)n\hC8@p!3H+u"IqdOp+cD9s8N*S62jLVrt7%P9)noG9(qs59(qs59(qs5
-XSi)3S3clB0hV050hV050hPoos8UVjq+;"$s+@]80gYO,0s(<Q$_0N5p5@2/k*4^WXSi)$S3clB
-1&OWX`W%Yb9(qs59(qs59(qs59(qs5XSi)$S3clB1&+B@rrFi?r_!4j%P^7As8OfGp@^45p@^5B
-r;V8:s8OfO;G'Pjp@^6@s"QfSs8Ofgp@^4U>"\h63D)nj>"VD>@S07F@S07F@S07F@S07F@S07N
-@S07N@S07N@S07N@S07N@S07W@S07W@S07W@S07W@S07W@S07W@S07W@S07W@S07W@S07W@S07W
-@S07W@S07W@S05pPY*CurS@OMr'C<S!i58Prq6AgpANhJ62]mEmK-#Kmf)n\V"XcD!9X2Fr_!1X
-s7QK,!.Y~>
-!<E0!hYuL7k57UK8FGpFnc@H$r)j$&r;Qnj9_S0BqH<ju!C0Za=VU`44B5Pas$0`\p,l@Kp,lLO
-p,oMUrtCqsp@^UKp@^UOp@^UOEQ8%Yg3rd"$GQOs]&#PLp@^VOr;R.q9\T&sf"U:7i]OCArrnre
-p@^UKrE0i[s$0^ip@^UOp@^UOp@^UOp@^VOr;Qqk9_S0B<V]etrrGAbr`Kg/s#a:as8P>ep@^UO
-p@^VOr;V8;s8P>m@9H`Mp@^WFs#a;(s8P?0p@^UoBjLbY86K)LD-:"uD-:#$D-:#$D-:#$D-:#(
-D-:#(EEQG0EEQG0EEQG0EEQG0EEQG4EEQG4F]hk8F]hk8F]hk8F]hk8F]hk8F]hk8F]hk8F]hk8
-F]hk8F]hk8F]hk8F]hiMR9;B;gA]q/SbYYTV=*dNncGNUgA]q17,m5*k5OWI8FGpFncGNUgA]q/
-iqZ"Amf2hY\c@6~>
-!<E0!hYlU:62aFUmf)n\hI?DY!7h#I"ML'"s)\%4s8N+@SGo>art9CCV#UIAV#UI9V#UI9V#UI9
-eboF\]p/QsF/8j9F/8j9F/61ns8VN#q4nASs/b)FF.E:1F4L3g$b_emp9`u,m_/%0eboFM]p/Qs
-F8VgJk5TLuV#UI9V#UI9V#UI9V#UI9eboFM]p/QsF82R2rrI22rhTSo%We/9s8RGAs8R/9s8R/j
-r;V8[s8R/9XJDZ!s8R0?s)X^;s8RGQs8R/RXJGmHK;><VXJDZ2[%sM:[%sM:[%sM:[%sM:[%sM:
-[%sM:[%sM:[%sM:[%sM:[%sMB[%sMB[%sMB[%sMB[%sMB[%sMB[%sMB[%sMB[%sMB[%sMB[%sMB
-[%sMB[%sMB[%sK"c(nhBrS@OMr'C<S!i58Prq6AgpANhJ62]mEmK-#Kmf)n\V"XcD!9X2Fr_!1X
-s7QK,!.Y~>
-!s&AXhYZI69)n>Xp&X#!r(7$Ts.oTJ"$-)K1&=KDmf-Jh8f$Rh8kNRmjtTL%p+]25p+]25p+_g3
-V#<"]3VN/$9(qs59(qs58kMBAV#TjKqFV0;s4-h$0hV050pM^6r@n^@XT..QPlK:00pM^6r@nC7
-p@^6=8cc$nr_!4a%l$]Mp+]25p+]25p+_g3V#<"M3VN/$pdtVUs'#@n''B3d8n.h_0hV050hV05
-0pM^6r@r`_s&r;m8m5-dp+b_08nr,@jtU'5p+]`C@fN5a8pa`68qUSF8qUSF8qUSF8qUSF8qUSF
-8rI.N8rI.N8rI.N8rI.N8rI.N8sEdW8sEdW8sF'_8sF'_8sF'_8sF'_8sF'_8sF'_8sF'_8sF'_
-8sF'_8sF'_8sF'_8d(An8h'K5h>l^962X=Tmeuh[V"XfE!Tl]Hk5F]K9()ZO!MoGgh>l^962X=T
-mf)n\]`<Q~>
-!s&AXhYuO6k5IaM8FGpFncJO=2#L>TRK'Gg49J.Jp,r1O!p]esrDaWqs&E'5s5lFDp@^UKp@^UK
-p@^V:s/u;_'1hij4B;+K4B;+K4B5BX=f)/`;#40#IK.adPsA@Cp,ncCY5LHk8?W!HV3V)7Y!AET
-Y5LHb8G;a>r)Ed's8H$up('8cp@^UKp@^UKp@^V:s/u;_"%`.Z4SVnXlMkGo<>+Ho<E3c5jucZ;
-p,l@Kp,ncCY5LJ2lMkEu<E3a=p@^W6s&F&]s5lFPp@^U[<GDK55ZNAL<E4li<E4li<E4li<E5#q
-<E5#q<E5#q<E5/u<E5/u<E5<$<E5<$<E5<(<E5H,<E5H,<E5H,<E5H,<E5H,<E5H,<E5H,<E5H,
-<E5H,<E5H,<E5H,<E5H,<E00iEE+jdrn[Y7q*b6R!:KjW!qr>Yrn[_97,n4.rosRQ8FHKJ!qr>Y
-rn[Y7q*b6R!:KjW!P/8]~>
-!s&AXhYZI69)n>Xp&X#Zr1!i-s2FqX",$XRF8DC.pA^BUS/1huK:K%CmW4ous)X_1s)X_1s)Z0Z
-`VjikKE(smSH&V1SH&V1S=Gh.`W,XrqO@u$s5s$gH^t-9F2e0urGrC"ec4dN[/]:5Hc?$(rGr'n
-s8R0<S/0ZTK:JJ3s)X_1s)X_1s)X_1s)Z0Z`Vji[KE(smpm_EZs-3JP'))?XS?2bYF.E:1F.E:1
-F2e0urGr&6s-3MQs.o\pG]WTYK<2H[mW53(s)Y!+XT-7dS@#)^S@u"oS@u"oS@u"oS@u"oS@u"o
-S@u"oS@u"oS@u"oSAhS"SAhS"SAhS"SAhS"SAhS"SAhS"SAhS"SAhS"SAhS"SAhS"SAhS"SAhS"
-SAhS"SAhS"SAhS"SAhS"@eTfX!9X2Fr(6tWrUp8fpAWnLk!At.rU'\Ymeuh[V"XfE!9X2Fr(6tW
-rq6B+!.Y~>
-!W`8Wqr[qHs%<=Zr:U0J.JudG;XXRTH^'.Tk5T0oqar`9s5o5dP[^0_]kYOdM_Ritp+]25p+]2%
-s(Z$2s."G#K1bk20hV050hUU.C/V-cC4lQC1&4Eemf3;Q3D0#=0iIH>S9pKQ8pgU<@UfB;C,o2[
-s."G#K1bk21&OWfF8pSQ9(qs59(qs59(qs59'6.g@da8dH^'.Tp@^459'5:68q*<1k)4SN@\!J3
-C;p420hV050hV050j=#FS:d&YSH%`0H^nhCk5T1ls1NKms,/U(p@^458u2Jr3I=q%8pb#>8qUSF
-8qUSF8qUSF8qUSF8qUSF8rI.N8rI.N8rI.N8rI.N8rI.N8sEdW8sF'_8sF'_8sF'_8sF'_8gT^:
-8kP=_8kP=_8kP=_8kP=_8kP=_8kP=_8kP=_8kLQ+hVRDWrB^<Qr:U>jp>4Zgk!B"/r9aPWr:U;i
-p>4Zgk5@UGmeocVp&Vi,J,~>
-!W`8Wro3q>s69\S8FGpFo)JCag,/_-$XrK"SV<>c<Ta=(@Ja%^U&X8;JXL5Cs2&p$s-5]Hp@^UK
-p@^[email protected]&/N7p,l@Kp,l@;s)hbUM04[ThE:U6,jPF09Lr1Wp,ldOqON>*M,f90s)E&Y
-s*7"@meWK.Q&/N7p,r7Q,(9KB:f[5_4B;+K4B;+K4B:PDF`$RCSV<>c<VH,K<E82Dr)J3>s5oGp
-R;&5l_KF$$Prr(?p,l@Kp,lpSqONV6M4st3Ob'?K<Ta=(Y5c@eb5[_l<VH,K<E64%D+&qh<E4`e
-<E4li<E4li<E5#q<E5#q<E5#q<E5/u<E5/u<E5/u<E5<(<E5<(<E5H,<E5H,<E5H,<E5H,<E5H,
-<E1?5EE-#,EE-#,EE-#,EE-#,EE-#,EE-#,EE-#,EE-!qo%r6_iqc(B8H/2[p'.5]hVR8O7/l?J
-lMp8P8H/2[p'%/\hVR8OrC$\N!(?fWrpg-a\c@6~>
-!W`8Wqr[qHs%<=Zr:U0J@f2`(V"Xi-]u@[TpA^YYqj]Ogs6dS-`N7&YeZ@p5[!S>Cs)X_1s)X_(
-s.$1as2D[j]q#-&F.E:1F.Dt(S>=]KXM+YrHhj0WpAb/FMk'hIF/8O0`P'7(SA"t&S>?2bUk>K:
-s2D[j]q#-&F8VOP[/ZqdSH&V1SH&V1SH&V1SG)uQXS2\5]u@[Ts8R/1SF6+KS:8`_m_-!HXMt4i
-XQKPiH^t-9F.E:1F/8O0`P'7(c2[4F[*>tJpA^Z-s4+L=s0R-Cs8R/1SCRY(K=%GES@u"oS@u"o
-S@u"oS@u"oS@u"oS@u"oS@u"oS@u"oSAhS"SAhS"SAhS"SAhS"SAhS"SAhS"SAhS"SAhS"S0c.U
-S=IR"S=IR"S=IR"S=IR"S=IR"S=IR"S=IR"S=F'^hVRDWrB^<Qr:U>jp>4Zgk!B"/r9aPWr:U;i
-p>4Zgk5@UGmeocVp&Vi,J,~>
-!<E/sk54TDp&X#!qaq3)^%VKoMa<9ps(_C&1lL5js5mcVPii#.PVG0jp@^45p@^45Mt[0c>.sY0
-mYaC)p+]25p+]0tpA\mPpAaj*;DIu>,cq$b0gSG*p+]0K^%VKoMa:8@s#ECFs#EA;@_ML8mYaC)
-p+cG:s4&5X9(qs59(qs59(qs58rNECC0J=Es6be2p@^459(qs5r(;ErhZ*W<@R67@s5oP#3D0#=
-0hV050hPogpAaQ=8sJ34s5mcVSG)ttSEBk6S2!#rp@^45F5GG%C0F5%HX]T>K47GFK47GFK47GF
-K47GFK47GFMdf:NMdf:NMdf:NMdf:NMdf:NP[[6WP\Nf_P\Nf_P\Nf_P\Nf_P\U4j)3el.8sF'_
-8sF'_8sF'_8sF'_8sF'_8sF)i8cgI0hYuX=Ud7<D8cYsjp&_&XhYu[:62F4Op&_&XhYlU:62g6O
-9)SA`]`<Q~>
-!<E0!ir8*>lMg5No)A=`g,/\'$YdKOs6>S7NUlpc9`%XCQ/;Q;iakfOk5X_34@E$>p,l1Fp,l02
-o(m??_Y4#pNC`d:4AbbF4A_%.qJj[Ks7XT<5l"5%Y5cL(9MkHV4A]b/pAaE;86Puh6qmIW6qC-g
-_Y4#pNC`d:4SqtTef[L[p@^UFp@^UFp@^UFNUlpcBu9TDlA\@.p,l/Jp@^WH:k"\ds8(_d9UY&C
-lBOJ";"jTF;"jTF:hdf?s6>S?Q/;Q;iakfOo(m@"k5X_;4@E$>p,l/shUXf+APc3SAPc3WAPc3W
-Bi%W_Bi%W_Bi%WcBi%WcBi%WcBi%WgD,=&kD,=&kD,=&oD,=&oD,=&oD,=&oD,=&oD,=&oD?!EM
-Q#0>oQ#0>oQ#0>oQ#0>oQ#0>oQ#0>oQ#6Ls!]9?%ro*pOr'^NT!ikh^rq6Demb[s&qaCBRs760_
-!ho&=ro+"A6q%%>!q&TMrpp*_!P/8]~>
-!<E/sk54TDp&X#ZqihG`eb9%:[#;Wks.oLU1pl]Ns6c,0^$bpoZu^kas8R/)s8R/)^%VK%Ut,2=
-p9]bXs)XG)s)XF<pA^rNpAb0LMgP8a,gHA>F-Mphs)XF#eb9%:[#:ISs*K\(s*KZgUt,2=p9]bX
-s)\(%s5kG^PlLc)PlLc)PlLc)PeHejUnlQ7s7WgXs8R/)PlLc)r02Z;mf3=TP`*6Cs7Wg@K9ZE9
-F-Q_)F-NKNpAainMmVpPs6c,0`V0>-`U<d"]lSgjs8R/)XR>4lS>;C6[%rqN[%rqN[%rqN[%rqN
-[%rqN]qgmW]qgmW]qgmW]qgmW]qgmW]qgmW]qgmW]qgmW]qgmW]qgmW]qgmW]qk[m)82i1PeElW
-PeElWPeElWPeElWPeElWPeEmlPQG=^hYuX=Ud7<D8cYsjp&_&XhYu[:62F4Op&_&XhYlU:62g6O
-9)SA`]`<Q~>
-!<E/tk54TDp&b9E.JcX;5rnp!"$oOF1&CnOF%SIk0`jX53W:`53W;YN1&jlG1&jiL5qt)[5rnp!%
-RE]A0hP%m0hP&(0eksSr\4C5qYp_?8kM)u3W;YN1&jiH5rnp!#XM'T0el9m0erZ"!C8aF0`s^60
-erPt(1Q]r8kLfm8kLfm8kLfm8kMB(0gS)cr\4L@8hi("9)gXC8cUmM0`jX53W:`53W;YN1&jlG1
-&acF3W:`85tX-tr\4U\;F*#l8icl*EB-X+=tqaQV"RDH>"VD6>"VD>@S07F@S07F@S07F@S07F@
-S07N@S07N@S07N@S07N@S07N@S07W@S07WC._*_C._*_C._*_C._*_C._*_C._*_C._*_C._*_C
-._*_C._*_C._*_C._*_8h'3*k54TDp&b8imec/Dmec\Zs.o)[k54TDp&Vi,J,~>
-!s&A\ir8*>lMg5No)A=aqURM":]X6Tr]C9R:e3_FrrRIB8GtXP9Me.V49.eK;#`ZX;#`ZX:^'BP
-4A8F6r]CZ]:cpj::cpj::e3]29L/S>!'pD\"aNp@6p*a6;#`ZX:]X6Tr]CHW:f'8::f'8:r_NVh
-5lNkJ85ME2qbS&BnsN<N4?QG:4?QG:4?QG:83B".9L/S>"%Z6N4T81W4SqqT8GtXP9Me.V49.eK
-;#`ZX;#`ZX:^C&h4?Pl":e3kN4F:@:83B"76p*Rs6r8#34?Rnhnm+dp:f)^S:f)jW:f)j[:f*!_
-:f*!_:f*!_:f*-c:f*-c:f*9g:f*9k:f*9k:f*Eo:f*Eo:f*Eo:f*Eo:f*Eo:f*Eo:f*Eo:f*Eo
-:f*Eo:f*Eo:f*Eo:f*Eo:f*Eo:f*ER2"(A&roX4FrpKdVrq6EiU$hp>roX4FrpKdVrq6EiU$hp>
-roX4FrpKdVrq6B(!.Y~>
-!<E/tk54TDp&b9E@eko^HiA'gK8YA'qYpVmMhD"M"+,raKDoolKDpf/F8q0uF8q.%K6)*dMgPGE%
-YK[\F,PrtF,Ps/F)ut\rc8'dqYp_pMi2q'HiAs'F8h'tHiA'lK8YY/F,PrtF8_!sHiA'gK8Xelq
-hl5[p:ZBBF*!7tF*!7tF*!7tK6)*dMgPGE"+uMQF8h*tF8LjqKDoooH]*f7rc8'lrepets,6nur
-egc'rc8O$Mh?@tF*j.9K6)*lKDoq3K8ZOiF*".rp5=QnMi4[,Mi4[,Mi4[,Mi4s4Mi4s4Mi4s4M
-i4s4Mi4s4Mi4s4Mi4s4Mi4s4Mi59=Mi59=Mi59=Mi59=Mi59=Mi59=Mi59=Mi59=Mi59=Mi59=M
-i59=Mi59=Mi59=Mi59,@da-UqsO@T!ro(aqr[eDqt:*kV!e-BqsO@T!PJJ`~>
-!<E/uk54TDpAb-neLBuRqCqt1bsD1\!'/Rq!b.Z[`^'Ssr]pNVr]tm/8jPa@8jPaH8jPaP8jPaP
-;F*T`;OgW>8jPaa;F*Tq>!YH$>!YH$>!YH$>!YH,>!YH,>!YH,>!YH,>!YH4>!YH4@R3;<@R3;<
-@R3;<@R3;<@R3;<@R3;<@R3;<@R3;<@R3;<@R3;<@R3;<@R3;<@R3;<@R39_Mdet$mel5Emec_X
-rrJq`r9!nEqtC'i!Mo/]k54TDp&b9-!.Y~>
-!W`8[roX4FrpKdVrq?Bg!S0*t:]OMl49/(#:]OMl49/(*:]b@%8B+L+<W>mF>ua]t@9HE'AQ_i+
-Bj"8/D-]t7EEuC;F^_+T5Zpo[JRqYSKk4(WKk4(WM.od_M.od_M.od_NG23cNG23cNG23cO_mok
-O_mokQ#0>oQ#0>oQ#0>oQ#0>oQ#0>oQ#0>oQ#0>oQ#0>oQ#0>oQ#0>oQ#0>oQ#0>oQ#0>o#*j%%
-2"'A_roX4FrpKdVrq?Bg"/5/Bir8*>lMg5No)A@_q?*GZio9t"rp'LNrpp'^!rBJ.J,~>
-!<E/uk54TDpAb-neRJ$+qJuXhc&;F>!/&g[!h?rV`esh]regc@repf@s,28pP`(HiP`(HiP`(Hq
-P`(HqPf8l6P`(I$S;W<,S;W<,S;W<4S;W<4S;W<4S;W<4S;W<4S;W<4S;W<4S;W<4S;W<=S;W<=
-S;W<=S;W<=S;W<=S;W<=S;W<=S;W<=S;W<=S;W<=S;W<=S;W<=S;W<=S;W<=S;UkEr9!nEqtC'i
-!Mo/]k54TDpAb-nV!e0CqsO@T!roq6J,~>
-!<E0!k54TDpAY'meL?&8r]pNEa$B\tr]pNVr]u$38jPa@8jPaH8jPaP8jPaP;F*T`;F*T@8jPaa
-;F*Tq>!YH$>!YH$>!YH$>!YH,>!YH,>!YH,>!YH,>!YH,>!YH4@R3;<@R3;<@R3;<@R3;<@R3;<
-@R3;<@R3;<@R3;<@R3;<@R3;<@R3;<@R3;<@R3;<@R3;<@R39\.IR/sqsO@Trr3"pmeu;Fmec_W
-rrJq`rT="FqtC'i!PJJ`~>
-!<E0!k5OZFmf)eVpAXmhehhqOs%EGa7)qt$;#X.<<DZ@_>u43g@9#upAQ;DtBj",'D-9P+EEu73
-=]nElI:[email protected]@SM.K@SNG2'[NG2'[NG2'[O_IK_O_IK_Q"`oc
-Q"`ocQ"`ocQ"`ocQ"`ocQ"`ocQ"`ocQ"`ocQ"`ocQ"`ocQ"`oc#*imr9Jl1sroX4FrpKdVrq??f
-!ho&AroX4FrpKdVrq??f!ho&AroX4FrpKdVrq?Bg!P/8]~>
-!<E0!k54TDpAY'meRF)^rdt2ta+FAMrdt3/re(6/s+>`aMh?YHMh?YPMh?YPMh?YPMh?Y?Mh?YX
-P_4UiP_4UiP_4UiP_4UiP_4UiP_4UiP_4UiP_4UqP_4UqP_4UqP_4UqS:cI$S:cI$S:cI$S:cI$
-S:cI$S:cI$S:cI$S:cI$S:cI$S:cI$S:cI$S:cI$S:cI$S:cH'meu;Fmec_WrrJq`rT="FqtC$h
-!Mo/^k54TDpAb-n]`<Q~>
-!W`8_qsO@Tr;QfJ.=k*B9"R[t.IQ?\qsO@Tr;QkpmcN[/mec_Urr](bk2uR/qtC!g!PJJ`~>
-!W`8_rp'LNrpp'^rqcZp!R`fU=f5Df<<G)Ck2u[.rpKdVrq??fs8N1plK77.lMg5No)A@^qZ$Qt
-U$Ce&rp'LNrpp'^rqZ]r\c@6~>
-!W`8_qsO@Tr;QfJ@Y(>+Uq<E)@d`C@qsO@Tr;QkpmcN[/mec_Urr](bk2uR/qtC!g!PJJ`~>
-!!)DN!%EI)JI&jn!%I<"!2T"H!2T"H!!%N~>
-!!)DK!&T64JI&jn!&X)*!28eB!28eB!!%N~>
-!!)DN!+LKbJI&jn!+P>[!2T"H!2T"H!!%N~>
-!<E0!joD3.s+13$s7-*mV#TT>]`<Q~>
-!<E0!joD*+s+13$s7-*mU&X9;\c@6~>
-!<E0!joD3.s+13$s7-*mV#TT>]`<Q~>
-!<E0!joD3.s+13$s760oK;AP0k.LbF~>
-!<E0!joD*+s+13$s760oJYE,+k.1PC~>
-!<E0!joD3.s+13$s760oK;AP0k.LbF~>
-!<E0!joV@Ys+/^OeUc9Dec17*V#TT>]`<Q~>
-!<E0!joV7Vs+/mTg4@uNgAc^-U&X9;\c@6~>
-!<E0!joV@Ys+/^OeUc9Dec17*V#TT>]`<Q~>
-!<E0!joV@Ys+/^OeUc9Dec17*V#TT>]`<Q~>
-!<E0!joV7Vs+/mTg4@uNgAc^-U&X9;\c@6~>
-!<E0!joV@Ys+/^OeUc9Dec17*V#TT>]`<Q~>
-!<E0!joV@Ys+/^OeUc9Dec17*V#TT>]`<Q~>
-!<E0!joV7Vs+/mTg4@uNgAc^-U&X9;\c@6~>
-!<E0!joV@Ys+/^OeUc9Dec17*V#TT>]`<Q~>
-!<E0!joV@Ys+/^OeUc9Dec17*V#TT>]`<Q~>
-!<E0!joV7Vs+/mTg4@uNgAc^-U&X9;\c@6~>
-!<E0!joV@Ys+/^OeUc9Dec17*V#TT>]`<Q~>
-!<E0!joV@Ys+/^OeUc9Dec17*V#TT>]`<Q~>
-!<E0!joV7Vs+/mTg4@uNgAc^-U&X9;\c@6~>
-!<E0!joV@Ys+/^OeUc9Dec17*V#TT>]`<Q~>
-!<E0!joV@Ys+/^OeUc9Dec17*V#TT>]`<Q~>
-!<E0!joV7Vs+/mTg4@uNgAc^-U&X9;\c@6~>
-!<E0!joV@Ys+/^OeUc9Dec17*V#TT>]`<Q~>
-!<E0!joV@Ys+/^OeUc9Dec17*V#TT>]`<Q~>
-!<E0!joV7Vs+/mTg4@uNgAc^-U&X9;\c@6~>
-!<E0!joV@Ys+/^OeUc9Dec17*V#TT>]`<Q~>
-!<E0!joV@Ys8(:A!!:[N!:889!<1OK!!:[N!;tCI!:/25!9Mc2!:SJ6!!^sR!7fU"!.i[Uec17*
-V#TT>]`<Q~>
-!<E0!joV7Vs8(IF!!:jS!:8G>!<1^P!!:jS!;tRN!:/A:!9Mr7!:SY;!!_-W!8?-,!.ijZgAc^-
-U&X9;\c@6~>
-!<E0!joV@Ys8(:A!!:[N!:889!<1OK!!:[N!;tCI!:/25!9Mc2!:SJ6!!^sR!7fU"!.i[Uec17*
-V#TT>]`<Q~>
-!<E0!joV@Ys8(:G!;b7G!:889!<1OK!;Y1F!:889!<1OK!9Vi3!:SJ<!;b7G!<:UL!.i[Uec17*
-V#TT>]`<Q~>
-!<E0!joV7Vs8(IL!;bFL!:8G>!<1^P!;Y@K!:8G>!<1^P!9W#8!:SYA!;bFL!<:dQ!.ijZgAc^-
-U&X9;\c@6~>
-!<E0!joV@Ys8(:G!;b7G!:889!<1OK!;Y1F!:889!<1OK!9Vi3!:SJ<!;b7G!<:UL!.i[Uec17*
-V#TT>]`<Q~>
-!<E0!joV@Ys8(:G!<(IJ!!LgP!7fWu!:n\?!<1OK!"7<W!7fU"!7_&Le^aTuo%!a?rmh#Ks4.&J
-rmgrIs4.,L"4[AOeboLJec,UNeGoU?ec,XJec,UOeGoU"r;clJr;clJrr</O!!(RJ!.i[hec17*
-V#TT>]`<Q~>
-!<E0!joV7Vs8(IL!<(XO!!M!U!8?0*!:nkD!<1^P!"7K\!8?-,!87DQg=lK*o%O*Drn@APs4[DO
-rn@;Ns4[JQ"53_TgAM$OgA_-Sg&M-DgA_0OgA_-Tg&M-,r;clOr;clOrr</T!!(aO!.ijmgAc^-
-U&X9;\c@6~>
-!<E0!joV@Ys8(:G!<(IJ!!LgP!7fWu!:n\?!<1OK!"7<W!7fU"!7_&Le^aTuo%!a?rmh#Ks4.&J
-rmgrIs4.,L"4[AOeboLJec,UNeGoU?ec,XJec,UOeGoU"r;clJr;clJrr</O!!(RJ!.i[hec17*
-V#TT>]`<Q~>
-!<E0!joV@Ys8(:G!<(IJ!"%0U!7_&Le^XX"o@<j@rmh#K#1W\ReGoU"rW!/Q!!(R"!!)T?rW)oI
-rrE)Lrr<;S!!(R"!!(RG!<:UL!!(RK!!:[N!;"b@!<(IJ!"[T[!7fU"!7fU"!7fU"!7goGs4.,L
-J^p7?s+:KNs5rIW!.Y~>
-!<E0!joV7Vs8(IL!<(XO!"%?Z!87DQg=cN,o@j3Ern@AP#20%Wg&M-,rW!/V!!(a,!!)TDrW)oN
-rrE)Qrr<;X!!(a,!!(aL!<:dQ!!(aP!!:jS!;"qE!<(XO!"[c`!8?-,!8?-,!8?-,!8@8Ls4[JQ
-J_HUIs+(?Is5rIT!.Y~>
-!<E0!joV@Ys8(:G!<(IJ!"%0U!7_&Le^XX"o@<j@rmh#K#1W\ReGoU"rW!/Q!!(R"!!)T?rW)oI
-rrE)Lrr<;S!!(R"!!(RG!<:UL!!(RK!!:[N!;"b@!<(IJ!"[T[!7fU"!7fU"!7fU"!7goGs4.,L
-J^p7?s+:KNs5rIW!.Y~>
-!<E0!joV@Ys8(:D!"@BX!7_&LeGoU"eGoU@ebT7WeGoU"!!(R"!!(OL!7fU"!:\P<!<:UL!<:UL
-!;tCI!!(RK!<:UL!;tCI!<:UL!;"b=!#!f^!7_&Le^XX"e^XX"e^XX"ec#RKec#Q"eX4neK*A(N
-k2s>WJ,~>
-!<E0!joV7Vs8(II!"@Q]!87DQg&M-,g&M-EgA1d\g&M-,!!(a,!!(^Q!8?-,!:\_A!<:dQ!<:dQ
-!;tRN!!(aP!<:dQ!;tRN!<:dQ!;"qB!#!uc!87DQg=cN,g=cN,g=cN,gAV*PgAV)'g6gUoJH_bI
-k2s5TJ,~>
-!<E0!joV@Ys8(:D!"@BX!7_&LeGoU"eGoU@ebT7WeGoU"!!(R"!!(OL!7fU"!:\P<!<:UL!<:UL
-!;tCI!!(RK!<:UL!;tCI!<:UL!;"b=!#!f^!7_&Le^XX"e^XX"e^XX"ec#RKec#Q"eX4neK*A(N
-k2s>WJ,~>
-!<E0!joV@Ys8(:G!<(IJ!!CaO!7grHo@<j@rmh#K$Io+VeGoU"eGoU"qZ-*8rVurKqZ-ZHqu?fK
-!!*#KrrDuIrrE)LrrDZ@rrE#Jrr<>T!!(R"!!(R"qZ$]J!!)rIrW%N"RaqFj"f21\k.LbF~>
-!<E0!joV7Vs8(IL!<(XO!!CpT!8@;Mo@j3Ern@AP$JGI[g&M-,g&M-,qZ-*=rVurPqZ-ZMqu?fP
-!!*#PrrDuNrrE)QrrDZErrE#Orr<>Y!!(a,!!(a,qZ$]O!!)rNrW%N'RbIdm"ektYk.1PC~>
-!<E0!joV@Ys8(:G!<(IJ!!CaO!7grHo@<j@rmh#K$Io+VeGoU"eGoU"qZ-*8rVurKqZ-ZHqu?fK
-!!*#KrrDuIrrE)LrrDZ@rrE#Jrr<>T!!(R"!!(R"qZ$]J!!)rIrW%N"RaqFj"f21\k.LbF~>
-!<E0!joV@Ys8(:G!<(IJ!!UmQ!7_&Ln(%F<rmh#K%+P=XeGoU"eGoU"!!)K<rrE&Krr<,N!!)rI
-rrE)Lrr<,N!!*#KrrDuIrrE)LrrDZ@rrE#Jrr<DV!!(R"!!(R"!!)rIrrDrHrW%N"S(7Ok"f21\
-k.LbF~>
-!<E0!joV7Vs8(IL!<(XO!!V'V!87DQn(RdArn@AP%,([]g&M-,g&M-,!!)KArrE&Prr<,S!!)rN
-rrE)Qrr<,S!!*#PrrDuNrrE)QrrDZErrE#Orr<D[!!(a,!!(a,!!)rNrrDrMrW%N'S(dmn"ektY
-k.1PC~>
-!<E0!joV@Ys8(:G!<(IJ!!UmQ!7_&Ln(%F<rmh#K%+P=XeGoU"eGoU"!!)K<rrE&Krr<,N!!)rI
-rrE)Lrr<,N!!*#KrrDuIrrE)LrrDZ@rrE#Jrr<DV!!(R"!!(R"!!)rIrrDrHrW%N"S(7Ok"f21\
-k.LbF~>
-!<E0!joV@Ys8(:G!<(IJ!"%0U!7_&Le^XX"o@<j@rmh#K#1W\ReGoU"rW!/Q!!(R"!!)W@rrE&K
-rr<V\!!(R"!!(OL!7fU"!7_&Lrmh#Ks4.,L#1W\Re^XX"o@<j@rRLoJ#LreSe^XX"ec#RKec,UN
-eGoUKec,XLec,W#eXP+hK*A(Nk2s>WJ,~>
-!<E0!joV7Vs8(IL!<(XO!"%?Z!87DQg=cN,o@j3Ern@AP#20%Wg&M-,rW!/V!!(a,!!)WErrE&P
-rr<Va!!(a,!!(^Q!8?-,!87DQrn@APs4[JQ#20%Wg=cN,o@j3ErS%8O#MK.Xg=cN,gAV*PgA_-S
-g&M-PgA_0QgA_/(g7-grJH_bIk2s5TJ,~>
-!<E0!joV@Ys8(:G!<(IJ!"%0U!7_&Le^XX"o@<j@rmh#K#1W\ReGoU"rW!/Q!!(R"!!)W@rrE&K
-rr<V\!!(R"!!(OL!7fU"!7_&Lrmh#Ks4.,L#1W\Re^XX"o@<j@rRLoJ#LreSe^XX"ec#RKec,UN
-eGoUKec,XLec,W#eXP+hK*A(Nk2s>WJ,~>
-!<E0!joV@Ys8(:G!<(IJ!!LgP!7fWu!:n\?!<1OK!"7<W!7fU"!7_&Le^aTun^[O;rmgrIrmguJ
-!7h#JrRLiHs4.,Ls4.,Lo@<j@rRLoJ!n@8Nrmh#Ks4.&Js4.,LrRLiHJ^p4>s+:KNs5rIW!.Y~>
-!<E0!joV7Vs8(IL!<(XO!!M!U!8?0*!:nkD!<1^P!"7K\!8?-,!87DQg=lK*n_3m@rn@;Nrn@>O
-!8@AOrS%2Ms4[JQs4[JQo@j3ErS%8O!nmVSrn@APs4[DOs4[JQrS%2MJ_HRHs+(?Is5rIT!.Y~>
-!<E0!joV@Ys8(:G!<(IJ!!LgP!7fWu!:n\?!<1OK!"7<W!7fU"!7_&Le^aTun^[O;rmgrIrmguJ
-!7h#JrRLiHs4.,Ls4.,Lo@<j@rRLoJ!n@8Nrmh#Ks4.&Js4.,LrRLiHJ^p4>s+:KNs5rIW!.Y~>
-!<E0!joV@Ys+/^OeUc9Dec17*V#TT>]`<Q~>
-!<E0!joV7Vs+/mTg4@uNgAc^-U&X9;\c@6~>
-!<E0!joV@Ys+/^OeUc9Dec17*V#TT>]`<Q~>
-!<E0!joV@Ys+/^OeUc9Dec17*V#TT>]`<Q~>
-!<E0!joV7Vs+/mTg4@uNgAc^-U&X9;\c@6~>
-!<E0!joV@Ys+/^OeUc9Dec17*V#TT>]`<Q~>
-!<E0!joV@Ys+/^OeUc9Dec17*V#TT>]`<Q~>
-!<E0!joV7Vs+/mTg4@uNgAc^-U&X9;\c@6~>
-!<E0!joV@Ys+/^OeUc9Dec17*V#TT>]`<Q~>
-!<E0!joV@Ys+/^OeUc9Dec17*V#TT>]`<Q~>
-!<E0!joV7Vs+/mTg4@uNgAc^-U&X9;\c@6~>
-!<E0!joV@Ys+/^OeUc9Dec17*V#TT>]`<Q~>
-!<E0!joV@Ys+/^OeUc9Dec17*V#TT>]`<Q~>
-!<E0!joV7Vs+/mTg4@uNgAc^-U&X9;\c@6~>
-!<E0!joV@Ys+/^OeUc9Dec17*V#TT>]`<Q~>
-!<E0!joV@Ys+/^OeUc9Dec17*V#TT>]`<Q~>
-!<E0!joV7Vs+/mTg4@uNgAc^-U&X9;\c@6~>
-!<E0!joV@Ys+/^OeUc9Dec17*V#TT>]`<Q~>
-!<E0!joV@Ys+/^OeUc9Dec17*V#TT>]`<Q~>
-!<E0!joV7Vs+/mTg4@uNgAc^-U&X9;\c@6~>
-!<E0!joV@Ys+/^OeUc9Dec17*V#TT>]`<Q~>
-!<E0!joD3.eUc8%ea_/nV#TT>]`<Q~>
-!<E0!joD*+g4@t/g@<l#U&X9;\c@6~>
-!<E0!joD3.eUc8%ea_/nV#TT>]`<Q~>
-!<E0!joD3.eUc8)eaA%oeYN6-k.LbF~>
-!<E0!joD*+g4@t3g?sLrg7eQ/k.1PC~>
-!<E0!joD3.eUc8)eaA%oeYN6-k.LbF~>
-!<E0!joV@/eU_IdC5Qd*eaJ+qs4*qFk2s>WJ,~>
-!<E0!joV71g4=g+JVo$Xg@'Rts4X1Hk2s5TJ,~>
-!<E0!joV@/eU`X0Mi*GleaJ+qs4*qFk2s>WJ,~>
-!<E0!joV@/eU_IdC5Zg,mf(c:KDN7]KDN:]rs%#Ls5rIW!.Y~>
-!<E0!joV71g4=g+JW#'Zs8LaPJbm4`Jbm7`rs%2Ns5rIT!.Y~>
-!<E0!joV@/eU`X0Mi3Jns8LRKKDN7]KDN:]rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8iMXF[I5XT._fec1:!]`J.cqRuq/#1]OLk2s>WJ,~>
-!<E0!johC3g4=g+g4@t<gAh3PgAca$_?'[fqSN:4#25dNk2s5TJ,~>
-!<E0!johL1eVf?:k(2ZTk5YJ\ec1:!]`J.cqRuq/#1]OLk2s>WJ,~>
-!<E0!johL1eS8iMXF[I5XT._fec1:!]`S4dKDW@^rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g4@t<gAh3PgAca$_?0agJc!=ars%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k(2ZTk5YJ\ec1:!]`S4dKDW@^rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8iMXF[I5XT._fec1:"^&S-4KDW@^rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g4@t<gAh3PgAca%_Z0Z9Jc!=ars%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k(2ZTk5YJ\ec1:"^&S-4KDW@^rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8iMX8o@#!;rqs!.h5AXT._fec1:"^&S*6eUrMP^&S*:eYN6-k.LbF~>
-!<E0!johC3g4=g+g&Tk*!;tRL!.ijogAh3PgAca%_Z0W;g4=hQ_Z0W?g7eQ/k.1PC~>
-!<E0!johL1eVf?:joFQB!;u!X!.j:&k5YJ\ec1:"^&S*6eUrMP^&S*:eYN6-k.LbF~>
-!<E0!joqR2eS8j#qZ-Srq>gPsq>gMrrW)hsquHbuquHAjquHYrq>^MsrW)r!rVur"q>^MsquH#`
-!!)u!!!*#"!!)u!!!%SOSZMkZrmh%$rOr72s4..%r4W.1#1]OLk2s>WJ,~>
-!<E0!joqI4g4=h/qZ-TKq>gQLq>gNKrW)iLquHcNquHBCquHZKq>^NLrW)rOrVurPq>^NLquH$9
-!!)uO!!*#P!!)uO!!%T(S_F,Drn@C'rPJU7s4[L(r5/L6#25dNk2s5TJ,~>
-!<E0!joqR2eVf@JqZ-TWq>gQXq>gNWrW)iXquHcZquHBOquHZWq>^NXrW)r[rVur\q>^NXquH$E
-!!)u[!!*#\!!)u[!!%T4S`]tPrmh%$rOr72s4..%r4W.1#1]OLk2s>WJ,~>
-!<E0!jp.^4eS8j#X8r4#!!)u!!!)u!#lq'.!3E7%XK2F"X8i7rX8i7tX8i7iX8i7rX8i8!X9/I(
-X8r1"!!*#"!!)u!!!*#"!!)5a!!)u!!!*#"!!)u!!!%SOSZMkZrmh%$rOr72rmh%$rOr72#1]OL
-k2s>WJ,~>
-!<E0!jp.U6g4=h/g&V**!!)uO!!)uO#lr]5!8?-,g=cQ)g&M-Kg&M-Mg&M-Bg&M-Kg&M-Og&h?/
-g&V')!!*#P!!)uO!!*#P!!)6:!!)uO!!*#P!!)uO!!%T(S_F,Drn@C'rPJU7rn@C'rPJU7#25dN
-k2s5TJ,~>
-!<E0!jp.^4eVf@JjoGAB!!)u[!!)u[#ls,M!9WDDk2l[Ajo>DWjo>DYjo>DNjo>DWjo>D[joYVG
-joG>A!!*#\!!)u[!!*#\!!)6F!!)u[!!*#\!!)u[!!%T4S`]tPrmh%$rOr72rmh%$rOr72#1]OL
-k2s>WJ,~>
-!<E0!jp.^4eS8j#X8r1"!!*#"!!)u!#lq'.!3E7%XK2F#X9&C'!;`bs!;iht!:[&i!;W\r!<&u$
-!3E7%r2]kuri?)"rN#u!ri?)"poOJqm]6Bgri?)"rN#u!JZPEDs6fm:s+C<as8W&Js+C9`s8N;R
-V#TT>]`<Q~>
-!<E0!jp.U6g4=h/g&V')!!*#P!!)uO#lr]5!8?-,g=cQ*g&_9.!;bCL!;kIM!:\\B!;Y=K!<(UR
-!8?-,r7V,Nrn7>PrRq5Orn7>PptG`Jmb.X@rn7>PrRq5OJ_H[Ks8W)Ps+10ds8W&Os+1-cs8N;W
-U&X9;\c@6~>
-!<E0!jp.^4eVf@JjoG>A!!*#\!!)u[#ls,M!9WDDk2l[BjoPPF!;bgX!;kmY!:]+N!;YaW!<)$^
-!9WDDr8mtZroO1\rT4([roO1\pu_SVmcFKLroO1\rT4([J``Ncs8W)Ks+C<as8W&Js+C9`s8N;R
-V#TT>]`<Q~>
-!<E0!jp.^4eS8j#X8r1"!!*#"!s#F(!;`bs!;`bu!3?1sX8i7tX8i7iX8i7rX9/I(X8r1"!!*#"
-!!)u!!s#F(!;rnu!;NYq!:Quh!<&u!!<&u!!.h5BXT._fec1:$^&S-1ec1:$^&S*:eYN6-k.LbF~>
-!<E0!jp.U6g4=h/g&V')!!*#P!s%'/!;bCL!;bCN!87GLg&M-Mg&M-Bg&M-Kg&h?/g&V')!!*#P
-!!)uO!s%'/!;tON!;P:J!:SVA!<(UO!<(UO!.ijpgAh3PgAca'_Z0Z6gAca'_Z0W?g7eQ/k.1PC~>
-!<E0!jp.^4eVf@JjoG>A!!*#\!s%KG!;bgX!;bgZ!9O:Xjo>DYjo>DNjo>DWjoYVGjoG>A!!*#\
-!!)u[!s%KG!;tsZ!;P^V!:T%M!<)$[!<)$[!.j:'k5YJ\ec1:$^&S-1ec1:$^&S*:eYN6-k.LbF~>
-!<E0!jp.^4eS8j#X8r1"!!*#"r;c\q!!)nt!!*#"!!)nt!!)nt!!)Mi!!)hrr;cbs!!*#"!!)u!
-r;cbs!!),^!!)qu!!)u!!!%SOSZMkZrmh%$s1SI4qpk_!rk8@3#1]OLk2s>WJ,~>
-!<E0!jp.U6g4=h/g&V')!!*#Pr;c]J!!)oM!!*#P!!)oM!!)oM!!)NB!!)iKr;ccL!!*#P!!)uO
-r;ccL!!)-7!!)rN!!)uO!!%T(S_F,Drn@C's2+g9qqD($rke^8#25dNk2s5TJ,~>
-!<E0!jp.^4eVf@JjoG>A!!*#\r;c]V!!)oY!!*#\!!)oY!!)oY!!)NN!!)iWr;ccX!!*#\!!)u[
-r;ccX!!)-C!!)rZ!!)u[!!%T4S`]tPrmh%$s1SI4qpk_!rk8@3#1]OLk2s>WJ,~>
-!<E0!jp.^4eS8j#X8r1"!!*#"!s#F(!;`bs!;ikq!;iht!;iht!<&u!!;3Dn!<&u!!<0&%!3E7%
-qlBi!X8r1"!s#F(!;rnu!<&u!!:-]d!;iht!<&u!!.h5BXT._fec1:%^&S-/ec1:%^&S*:eYN6-
-k.LbF~>
-!<E0!jp.U6g4=h/g&V')!!*#P!s%'/!;bCL!;kLJ!;kIM!;kIM!<(UO!;5%G!<(UO!<1[S!8?-,
-qq;)Og&V')!s%'/!;tON!<(UO!:/>=!;kIM!<(UO!.ijpgAh3PgAca(_Z0Z4gAca(_Z0W?g7eQ/
-k.1PC~>
-!<E0!jp.^4eVf@JjoG>A!!*#\!s%KG!;bgX!;kpV!;kmY!;kmY!<)$[!;5IS!<)$[!<2*_!9WDD
-qrRq[joG>A!s%KG!;tsZ!<)$[!:/bI!;kmY!<)$[!.j:'k5YJ\ec1:%^&S-/ec1:%^&S*:eYN6-
-k.LbF~>
-!<E0!jp.^4eS8j#X8r1"!!*#"!!)u!!!)qu!!)qu!!)qu!!)qu!!)nt!!)u!!!)\n!!)u!!!*#"
-!!)u!!!)u!!W];%r2]kurN#u!ri?)"rN#u!m&U0eqQ'YsrN#u!JZPEDs6fm:s+:Bds8VoFs+C?b
-s8N;RV#TT>]`<Q~>
-!<E0!jp.U6g4=h/g&V')!!*#P!!)uO!!)rN!!)rN!!)rN!!)rN!!)oM!!)uO!!)]G!!)uO!!*#P
-!!)uO!!)uO!W^pSr7V,NrRq5Orn7>PrRq5Om+MF>qUtoLrRq5OJ_H[Ks8W)Ps+(6gs8VoKs+13e
-s8N;WU&X9;\c@6~>
-!<E0!jp.^4eVf@JjoG>A!!*#\!!)u[!!)rZ!!)rZ!!)rZ!!)rZ!!)oY!!)u[!!)]S!!)u[!!*#\
-!!)u[!!)u[!W_?_r8mtZrT4([roO1\rT4([m,e9JqW7bXrT4([J``Ncs8W)Ks+:Bds8VoFs+C?b
-s8N;RV#TT>]`<Q~>
-!<E0!jp.^4eS8j#X8r4#!!)u!!!)u!!!)qu!!)qu!!)qu!!)qu!!)nt!!)u!!!)\n!!)u!!!*#"
-!!)u!!!)qu!!)nt!!)u!!!*#"!!)u!!!)u!rrDYl!!)u!!!*#"!!)u!!!%SOSZMkZrmh%$!knX6
-psoCs$,-B=eYN6-k.LbF~>
-!<E0!jp.U6g4=h/g&V**!!)uO!!)uO!!)rN!!)rN!!)rN!!)rN!!)oM!!)uO!!)]G!!)uO!!*#P
-!!)uO!!)rN!!)oM!!)uO!!*#P!!)uO!!)uOrrDZE!!)uO!!*#P!!)uO!!%T(S_F,Drn@C'!lG!;
-ptGb!$,Z`Bg7eQ/k.1PC~>
-!<E0!jp.^4eVf@JjoGAB!!)u[!!)u[!!)rZ!!)rZ!!)rZ!!)rZ!!)oY!!)u[!!)]S!!)u[!!*#\
-!!)u[!!)rZ!!)oY!!)u[!!*#\!!)u[!!)u[rrDZQ!!)u[!!*#\!!)u[!!%T4S`]tPrmh%$!knX6
-psoCs$,-B=eYN6-k.LbF~>
-!<E0!joqR2eS8j#qZ-Srq>gMrquHbur;Zi!r;cl!quHbuq#L/jq#LGrq>gGp!!)quq>^Msq#LAp
-rrDYlqZ-Srr;_DMS?2bYrmh%$s8VbE$,-B=eYN6-k.LbF~>
-!<E0!joqI4g4=h/qZ-TKq>gNKquHcNr;ZiOr;clOquHcNq#L0Cq#LHKq>gHI!!)rNq>^NLq#LBI
-rrDZEqZ-TKr;_E&SD+#Crn@C's8VbC$,Z`Bg7eQ/k.1PC~>
-!<E0!joqR2eVf@JqZ-TWq>gNWquHcZr;Zi[r;cl[quHcZq#L0Oq#LHWq>gHU!!)rZq>^NXq#LBU
-rrDZQqZ-TWr;_E2SEBkOrmh%$s8VbE$,-B=eYN6-k.LbF~>
-!<E0!johL1eS8iMXF[I5XT._fec17%s7:mCrs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g4@t<gAh3PgAc^(s7:gArs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k(2ZTk5YJ\ec17%s7:mCrs%#Ls5rIW!.Y~>
-!<E0!johL1eS8iMXF[I5XT._fec19m^&S*:eYN6-k.LbF~>
-!<E0!johC3g4=g+g4@t<gAh3PgAc`p_Z0W?g7eQ/k.1PC~>
-!<E0!johL1eVf?:k(2ZTk5YJ\ec19m^&S*:eYN6-k.LbF~>
-!<E0!johL1eS8iMXF[I5XT._fec19krs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g4@t<gAh3PgAc`nrs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k(2ZTk5YJ\ec19krs%#Ls5rIW!.Y~>
-!<E0!johL1eS8iMXF[I5XT._fec19nrs=>Xs4*qFk2s>WJ,~>
-!<E0!johC3g4=g+g4@t<gAh3PgAc`qrs=8Vs4X1Hk2s5TJ,~>
-!<E0!johL1eVf?:k(2ZTk5YJ\ec19nrs=>Xs4*qFk2s>WJ,~>
-!<E0!johL1eS8iMXF[I5XT._fec1:%s7Y"CKE(rUeYN6-k.LbF~>
-!<E0!johC3g4=g+g4@t<gAh3PgAca(s7Y1HJcG`Sg7eQ/k.1PC~>
-!<E0!johL1eVf?:k(2ZTk5YJ\ec1:%s7Y"CKE(rUeYN6-k.LbF~>
-!<E0!johL1eS8iMXN7IC!.h5mXT._fec1:%s7Y"CKE(rUeYN6-k.LbF~>
-!<E0!johC3g4=g+g;qtJ!.ikFgAh3PgAca(s7Y1HJcG`Sg7eQ/k.1PC~>
-!<E0!johL1eVf?:k/cZb!.j:Rk5YJ\ec1:%s7Y"CKE(rUeYN6-k.LbF~>
-!<E0!joqR2eS8j#quHVqrW)ktqZ-Vsq>^MsquEau!!(0C!!)nt!!)2`rW)5brr@bSs6fm:s+C@O
-p=91qs8N;RV#TT>]`<Q~>
-!<E0!joqI4g4=h/quHWJrW)lMqZ-WLq>^NLquEbN!!(0q!!)oM!!)39rW)6;rr@c,s8W)Ps+14M
-p=fOts8N;WU&X9;\c@6~>
-!<E0!joqR2eVf@JquHWVrW)lYqZ-WXq>^NXquEbZ!!(1(!!)oY!!)3ErW)6Grr@c8s8W)Ks+C@O
-p=91qs8N;RV#TT>]`<Q~>
-!<E0!johL1eS8juX8i7pX8i7tX8i8!X8i8"X8i8!X8i8"X8i7!X8i7<X8i7^X8i7bX8i6SXT._f
-ec1:%s7Y"CKE(rUeYN6-k.LbF~>
-!<E0!johC3g4=hSg&M-Ig&M-Mg&M-Og&M-Pg&M-Og&M-Pg&M,Og&M,jg&M-7g&M-;g&M,,gAh3P
-gAca(s7Y1HJcG`Sg7eQ/k.1PC~>
-!<E0!johL1eVf@bjo>DUjo>DYjo>D[jo>D\jo>D[jo>D\jo>C[jo>D!jo>DCjo>DGjo>C8k5YJ\
-ec1:%s7Y"CKE(rUeYN6-k.LbF~>
-!<E0!johL1eS8juX8i7qX9&C'!;rnu!<&u!!<0&"!<&u!!<0&"!;NYq!48j*!<'#!!<9/#!<9/"
-!<9/"!;ESo!<0)!!!]M)!3E7%!<'"u!;rqr!;iks!:d,j!;ikr!;iks!!0/$ri?/$XK;C$MQHjG
-rmh%$s8VfCs+C@O#1]OLk2s>WJ,~>
-!<E0!johC3g4=hSg&M-Jg&_9.!;tON!<(UO!<1[P!<(UO!<1[P!;P:J!4:JX!<(XO!<:dQ!<:dP
-!<:dP!;G4H!<1^O!!_-W!8?-,!<(XN!;tRK!;kLL!:ebC!;kLK!;kLL!!1dRrn7DRg=lN+MVA+1
-rn@C's8VfHs+14M#25dNk2s5TJ,~>
-!<E0!johL1eVf@bjo>DVjoPPF!;tsZ!<)$[!<2*\!<)$[!<2*\!;P^V!4:nd!<)'[!<;3]!<;3\
-!<;3\!;GXT!<2-[!!_Qc!9WDD!<)'Z!;u!W!;kpX!:f1O!;kpW!;kpX!!23^roO7^k2uXCMWXs=
-rmh%$s8VfCs+C@O#1]OLk2s>WJ,~>
-!<E0!johL1eS8juX8i7qX9&C'!;rnu!<&u!!<0&%!3E7%r2]kupoOJqZ`F-,q5ai%X8o?'!3E7%
-rN#u!orJ,nr2]kuri?8'X8o?'!;rnu!;iht!;W\r!<0&"!:m2k!;rnu!<&u!!<&u!!<0)"!<0&%
-!3E7%LogXErmh%$s8VfCs+C@O#1]OLk2s>WJ,~>
-!<E0!johC3g4=hSg&M-Jg&_9.!;tON!<(UO!<1[S!8?-,r7V,NptG`JZe>BZq:Z)Sg&Tj\!8?-,
-rRq5Op"BBGr7V,Nrn7MUg&Tj\!;tON!;kIM!;Y=K!<1[P!:nhD!;tON!<(UO!<(UO!<1^P!<1[S
-!8?-,Lt_n/rn@C's8VfHs+14M#25dNk2s5TJ,~>
-!<E0!johL1eVf@bjo>DVjoPPF!;tsZ!<)$[!<2*_!9WDDr8mtZpu_SVZfV5fq;qq_joFQ+!9WDD
-rT4([p#Z5Sr8mtZroO@ajoFQ+!;tsZ!;kmY!;YaW!<2*\!:o7P!;tsZ!<)$[!<)$[!<2-\!<2*_
-!9WDDM!"a;rmh%$s8VfCs+C@O#1]OLk2s>WJ,~>
-!<E0!johL1eS8juX8i7rX8i8"X8i8!XS`(sXSi.sX8i7!X8i7rXT&:tX8i8!X8i7nX9J[+X8o?'
-!<0)"!;NVq!;iht!;`bs!;rnu!;!8l!<&u!!;ii"!3E7%r2]kuri?/$X8n$Ws6fm:s+C@Op=91q
-s8N;RV#TT>]`<Q~>
-!<E0!johC3g4=hSg&M-Kg&M-Pg&M-OgACsLgAM$Lg&M,Og&M-KgA_0Mg&M-Og&M-Gg'.Q2g&Tj\
-!<1^P!;P7J!;kIM!;bCL!;tON!;"nE!<(UO!;kIP!8?-,r7V,Nrn7DRg&Qo^s8W)Ps+14Mp=fOt
-s8N;WU&X9;\c@6~>
-!<E0!johL1eVf@bjo>DWjo>D\jo>D[k555Xk5>;Xjo>C[jo>DWk5PGYjo>D[jo>DSjothJjoFQ+
-!<2-\!;P[V!;kmY!;bgX!;tsZ!;#=Q!<)$[!;km\!9WDDr8mtZroO7^joC2!s8W)Ks+C@Op=91q
-s8N;RV#TT>]`<Q~>
-!<E0!johL1eS8juX8i8!X8i8"XS`(sX8i8!X8i8"X9/I(X8r1"!!)u!!!'.&!!)hr!!)hr!s#F(
-!;*>s!3E7%XK2F$X8i7pX8i7tX8i7sXSMqgX8i8!X8i7tX9/I(X8r$srr@eTs6fm:s+C@Op=91q
-s8N;RV#TT>]`<Q~>
-!<E0!johC3g4=hSg&M-Og&M-PgACsLg&M-Og&M-Pg&h?/g&V')!!)uO!!'.T!!)iK!!)iK!s%'/
-!;+tL!8?-,g=cQ+g&M-Ig&M-Mg&M-LgA1g@g&M-Og&M-Mg&h?/g&Up%rr@f-s8W)Ps+14Mp=fOt
-s8N;WU&X9;\c@6~>
-!<E0!johL1eVf@bjo>D[jo>D\k555Xjo>D[jo>D\joYVGjoG>A!!)u[!!'.`!!)iW!!)iW!s%KG
-!;,CX!9WDDk2l[Cjo>DUjo>DYjo>DXk5#)Ljo>D[jo>DYjoYVGjoG2=rr@f9s8W)Ks+C@Op=91q
-s8N;RV#TT>]`<Q~>
-!<E0!johL1eS8juX8i8!X9/I(X8r1"!!*#"!!)u!!!*#"!!)u!!!*#"!!)u!!!'.&!!)hr!!)hr
-!s#F(!;!8p!3?1%!<&u!!;EPp!;iht!;`bs!:?if!<&u!!;ii"!3E7%poFMsX8n$Ws6fm:s+C@O
-p=91qs8N;RV#TT>]`<Q~>
-!<E0!johC3g4=hSg&M-Og&h?/g&V')!!*#P!!)uO!!*#P!!)uO!!*#P!!)uO!!'.T!!)iK!!)iK
-!s%'/!;"nI!87G,!<(UO!;G1I!;kIM!;bCL!:AJ?!<(UO!;kIP!8?-,pt>cLg&Qo^s8W)Ps+14M
-p=fOts8N;WU&X9;\c@6~>
-!<E0!johL1eVf@bjo>D[joYVGjoG>A!!*#\!!)u[!!*#\!!)u[!!*#\!!)u[!!'.`!!)iW!!)iW
-!s%KG!;#=U!9O:D!<)$[!;GUU!;kmY!;bgX!:AnK!<)$[!;km\!9WDDpuVVXjoC2!s8W)Ks+C@O
-p=91qs8N;RV#TT>]`<Q~>
-!<E0!johL1eS8juX8i8!X9/I(X8r1"!!*#"!!)u!!!*#"!!)u!!!*#"!!)u!!!)u!rrBC,!!*#"
-!!)u!!!)eqrrDVkrr<,%!!)u!!!)bp!!)nt!!*#"!!)u!!!)u!!!)Vl!!)qu!!)u!!!)u!!!)u!
-!!*#"!s#F(!/R`Vmf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=hSg&M-Og&h?/g&V')!!*#P!!)uO!!*#P!!)uO!!*#P!!)uO!!)uOrrBCZ!!*#P
-!!)uO!!)fJrrDWDrr<,S!!)uO!!)cI!!)oM!!*#P!!)uO!!)uO!!)WE!!)rN!!)uO!!)uO!!)uO
-!!*#P!s%'/!/TA/s8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf@bjo>D[joYVGjoG>A!!*#\!!)u[!!*#\!!)u[!!*#\!!)u[!!)u[rrBCf!!*#\
-!!)u[!!)fVrrDWPrr<,_!!)u[!!)cU!!)oY!!*#\!!)u[!!)u[!!)WQ!!)rZ!!)u[!!)u[!!)u[
-!!*#\!s%KG!/Te;s8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!joqR2eS8j#q#CDrr;Zi!r;Zi!qZ-Vsq>^Msq#LAprrB@+rW)nur;cYp!!)Skrr<,%!!*#"
-r;c_rquHYrrW)hsr;cJkquH\sr;c_rr;churrE)#rW%hWs6fm:s+C@Op=91qs8N;RV#TT>]`<Q~>
-!<E0!joqI4g4=h/q#CEKr;ZiOr;ZiOqZ-WLq>^NLq#LBIrrB@YrW)oNr;cZI!!)TDrr<,S!!*#P
-r;c`KquHZKrW)iLr;cKDquH]Lr;c`Kr;ciNrrE)QrW%i0s8W)Ps+14Mp=fOts8N;WU&X9;\c@6~>
-!<E0!joqR2eVf@Jq#CEWr;Zi[r;Zi[qZ-WXq>^NXq#LBUrrB@erW)oZr;cZU!!)TPrr<,_!!*#\
-r;c`WquHZWrW)iXr;cKPquH]Xr;c`Wr;ciZrrE)]rW%i<s8W)Ks+C@Op=91qs8N;RV#TT>]`<Q~>
-!<E0!johL1eS8iMXR3(h!.h5HXT._fec1:%s7Y"CKE(rUeYN6-k.LbF~>
-!<E0!johC3g4=g+g?mSo!.ik!gAh3PgAca(s7Y1HJcG`Sg7eQ/k.1PC~>
-!<E0!johL1eVf?:k3_:2!.j:-k5YJ\ec1:%s7Y"CKE(rUeYN6-k.LbF~>
-!<E0!johL1eS8iMXR3(h!.h5HXT._fec1:%s7Y"CKE(rUeYN6-k.LbF~>
-!<E0!johC3g4=g+g?mSo!.ik!gAh3PgAca(s7Y1HJcG`Sg7eQ/k.1PC~>
-!<E0!johL1eVf?:k3_:2!.j:-k5YJ\ec1:%s7Y"CKE(rUeYN6-k.LbF~>
-!<E0!johL1eS8iMXRE7h!<'"o!7\+F!.h67XT._fec1:%s7Y"CKE(rUeYN6-k.LbF~>
-!<E0!johC3g4=g+g@*bo!<(XH!7]`t!.ikegAh3PgAca(s7Y1HJcG`Sg7eQ/k.1PC~>
-!<E0!johL1eVf?:k3qI2!<)'T!7^0+!.j:qk5YJ\ec1:%s7Y"CKE(rUeYN6-k.LbF~>
-!<E0!johL1eS8iMXF[I5XT._fec1:%s7Y"CKE(rUeYN6-k.LbF~>
-!<E0!johC3g4=g+g4@t<gAh3PgAca(s7Y1HJcG`Sg7eQ/k.1PC~>
-!<E0!johL1eVf?:k(2ZTk5YJ\ec1:%s7Y"CKE(rUeYN6-k.LbF~>
-!<E0!johL1eS8iMXF[I5XT._fec1:%s7Y"CKE(rUeYN6-k.LbF~>
-!<E0!johC3g4=g+g4@t<gAh3PgAca(s7Y1HJcG`Sg7eQ/k.1PC~>
-!<E0!johL1eVf?:k(2ZTk5YJ\ec1:%s7Y"CKE(rUeYN6-k.LbF~>
-!<E0!johL1eS8iMXPU&Y!.h5XXT._fec1:%s7Y"CKE(rUeYN6-k.LbF~>
-!<E0!johC3g4=g+g>:Q`!.ik1gAh3PgAca(s7Y1HJcG`Sg7eQ/k.1PC~>
-!<E0!johL1eVf?:k2,8#!.j:=k5YJ\ec1:%s7Y"CKE(rUeYN6-k.LbF~>
-!<E0!jp%X3eS8j#XSMnsXSW"qXSi.uXSr5!XSr3OX8i7hXSr4sXSr3NXO4-Lmf(c:KE(uFec1:%
-rs%#Ls5rIW!.Y~>
-!<E0!jp%O5g4=h/gA1dLgA:mJgAM$NgAV*OgAV)(g&M-AgAV*LgAV)'g<nXSs8LaPJcGcDgAca(
-rs%2Ns5rIT!.Y~>
-!<E0!jp%X3eVf@Jk5#&Xk5,/Vk5>;Zk5GA[k5G@4jo>DMk5GAXk5G@3k0`>ks8LRKKE(uFec1:%
-rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8juX8i8!X9/I(X8r4#!!*#"!!)u!!!*#"rrE&"rr@VO!!)Df!!)hr!!%SOdB*B9
-rmh%$s8VfCs+C@O#1]OLk2s>WJ,~>
-!<E0!johC3g4=hSg&M-Og&h?/g&V**!!*#P!!)uO!!*#PrrE&Prr@W(!!)E?!!)iK!!%T(dG"X#
-rn@C's8VfHs+14M#25dNk2s5TJ,~>
-!<E0!johL1eVf@bjo>D[joYVGjoGAB!!*#\!!)u[!!*#\rrE&\rr@W4!!)EK!!)iW!!%T4dH:K/
-rmh%$s8VfCs+C@O#1]OLk2s>WJ,~>
-!<E0!johL1eS8juX8i8!X9/I(X8r4#!s#F(!;ii%!3E7%X8o@$!<'#!!3E:%!!]M)!3?/#XSr5"
-XSr4mXS`(tX8r=&rW)hsrW)er!!)hr!!%SOdB*B9rmh%$s8VfCs+C@O#1]OLk2s>WJ,~>
-!<E0!johC3g4=hSg&M-Og&h?/g&V**!s%'/!;kIS!8?-,g&Tk+!<(XO!3FoS!!_-W!87DQgAV*P
-gAV*FgACsMg&V3-rW)iLrW)fK!!)iK!!%T(dG"X#rn@C's8VfHs+14M#25dNk2s5TJ,~>
-!<E0!johL1eVf@bjo>D[joYVGjoGAB!s%KG!;km_!9WDDjoFQC!<)'[!3G>_!!_Qc!9O7]k5GA\
-k5GARk555YjoGJErW)iXrW)fW!!)iW!!%T4dH:K/rmh%$s8VfCs+C@O#1]OLk2s>WJ,~>
-!<E0!johL1eS8juX9/I(X8r4#!!)u!!s#F(!;ii(!3E7%X8o=%X8r4#rrB+$rr<;*!!')#XK2F#
-X8i7nX8i8!X8i8"XT&;"X8i8!X8i8"X8i7tX8i7rX8i6OXO4-Lmf(c:KE(uFec1:%rs%#Ls5rIW
-!.Y~>
-!<E0!johC3g4=hSg&h?/g&V**!!)uO!s%'/!;kIV!8?-,g&Th,g&V**rrB+Rrr<;X!!(^Qg=cQ*
-g&M-Gg&M-Og&M-PgA_0Pg&M-Og&M-Pg&M-Mg&M-Kg&M,(g<nXSs8LaPJcGcDgAca(rs%2Ns5rIT
-!.Y~>
-!<E0!johL1eVf@bjoYVGjoGAB!!)u[!s%KG!;kmb!9WDDjoFNDjoGABrrB+^rr<;d!!)-]k2l[B
-jo>DSjo>D[jo>D\k5PG\jo>D[jo>D\jo>DYjo>DWjo>C4k0`>ks8LRKKE(uFec1:%rs%#Ls5rIW
-!.Y~>
-!<E0!johL1eS8juXSi.tX8i8"X8i8"X8i7tX9em.X8o?'!3E7%V5st'XK2E'X8o?'!<&u!!;3Dn
-!;W\r!<&u!!<0&"!;rnu!;rnu!;W\r!.h6!XT._fec1:%s7Y"CKE(rUeYN6-k.LbF~>
-!<E0!johC3g4=hSgAM$Mg&M-Pg&M-Pg&M-Mg'Ic5g&Tj\!8?-,V:l4Ug=cP\g&Tj\!<(UO!;5%G
-!;Y=K!<(UO!<1[P!;tON!;tON!;Y=K!.ikOgAh3PgAca(s7Y1HJcG`Sg7eQ/k.1PC~>
-!<E0!johL1eVf@bk5>;Yjo>D\jo>D\jo>DYjp;%MjoFQ+!9WDDV</'ak2l[+joFQ+!<)$[!;5IS
-!;YaW!<)$[!<2*\!;tsZ!;tsZ!;YaW!.j:[k5YJ\ec1:%s7Y"CKE(rUeYN6-k.LbF~>
-!<E0!johL1eS8juX9/I(X8r4#r;cet!!)nt#lq'.!3E7%XK2DuX9J[+X8o?'!<0&%!3E7%o;qlj
-rN#u!rN#u!riGqrr2]kuq5aPrJZR8#s6fm:s+C@Op=91qs8N;RV#TT>]`<Q~>
-!<E0!johC3g4=hSg&h?/g&V**r;cfM!!)oM#lr]5!8?-,g=cP'g'.Q2g&Tj\!<1[S!8?-,o@j-C
-rRq5OrRq5Orn@2Kr7V,Nq:YfKJ_JN*s8W)Ps+14Mp=fOts8N;WU&X9;\c@6~>
-!<E0!johL1eVf@bjoYVGjoGABr;cfY!!)oY#ls,M!9WDDk2lZ?jothJjoFQ+!<2*_!9WDDoB,uO
-rT4([rT4([roX%Wr8mtZq;qYWJ`bABs8W)Ks+C@Op=91qs8N;RV#TT>]`<Q~>
-!<E0!johL1eS8juX8i7sX8i8"X8i8"X8i7tX9/I(X8r1"!!&js"ota+!3E7%ri?2%XK2EjX8i8"
-X8i8!X8i8"X8i7oX8i7rX8i6OXO4-Lmf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=hSg&M-Lg&M-Pg&M-Pg&M-Mg&h?/g&V')!!&kL"p!B2!8?-,rn7GSg=cPqg&M-P
-g&M-Og&M-Pg&M-Hg&M-Kg&M,(g<nXSs8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf@bjo>DXjo>D\jo>D\jo>DYjoYVGjoG>A!!&kX"p!fJ!9WDDroO:_k2l[4jo>D\
-jo>D[jo>D\jo>DTjo>DWjo>C4k0`>ks8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8juX8i7sX8i8!X8i8"X8i8!X8i8"X8i7uX8i8!XT&:$X9J[+X8o?'!<'#!!;!8l
-!<&u!!<0&"!<&u!!<&u!!<&u!!;rnu!;W\r!.h6!XT._fec1:%s7Y"CKE(rUeYN6-k.LbF~>
-!<E0!johC3g4=hSg&M-Lg&M-Og&M-Pg&M-Og&M-Pg&M-Ng&M-OgA_/Rg'.Q2g&Tj\!<(XO!;"nE
-!<(UO!<1[P!<(UO!<(UO!<(UO!;tON!;Y=K!.ikOgAh3PgAca(s7Y1HJcG`Sg7eQ/k.1PC~>
-!<E0!johL1eVf@bjo>DXjo>D[jo>D\jo>D[jo>D\jo>DZjo>D[k5PF^jothJjoFQ+!<)'[!;#=Q
-!<)$[!<2*\!<)$[!<)$[!<)$[!;tsZ!;YaW!.j:[k5YJ\ec1:%s7Y"CKE(rUeYN6-k.LbF~>
-!<E0!jp%X3eS8j#XSi.tXSr4uX8i8"XSi.uXSr5!XSr5!XT&:%XSr2'X8i7%!!)u!!!)VlquH_t
-rW)u"rW)nur;cetquH\squD;Le#`T;rmh%$s8VfCs+C@O#1]OLk2s>WJ,~>
-!<E0!jp%O5g4=h/gAM$MgAV*Ng&M-PgAM$NgAV*OgAV*OgA_/SgAV'Ug&M-,!!)uO!!)WEquH`M
-rW)uPrW)oNr;cfMquH]LquD<%e(Xj%rn@C's8VfHs+14M#25dNk2s5TJ,~>
-!<E0!jp%X3eVf@Jk5>;Yk5GAZjo>D\k5>;Zk5GA[k5GA[k5PF_k5G>ajo>DD!!)u[!!)WQquH`Y
-rW)u\rW)oZr;cfYquH]XquD<1e)p]1rmh%$s8VfCs+C@O#1]OLk2s>WJ,~>
-!<E0!johL1eS8iMXS/^q!.h5?XT._fec1:%s7Y"CKE(rUeYN6-k.LbF~>
-!<E0!johC3g4=g+g@j5#!.ijmgAh3PgAca(s7Y1HJcG`Sg7eQ/k.1PC~>
-!<E0!johL1eVf?:k4[p;!.j:$k5YJ\ec1:%s7Y"CKE(rUeYN6-k.LbF~>
-!<E0!johL1eS8iMXS/^q!.h5?XT._fec1:%s7Y"CKE(rUeYN6-k.LbF~>
-!<E0!johC3g4=g+g@j5#!.ijmgAh3PgAca(s7Y1HJcG`Sg7eQ/k.1PC~>
-!<E0!johL1eVf?:k4[p;!.j:$k5YJ\ec1:%s7Y"CKE(rUeYN6-k.LbF~>
-!<E0!johL1eS8iMXSAmq!<'"o!.h5MXT._fec1:%s7Y"CKE(rUeYN6-k.LbF~>
-!<E0!johC3g4=g+gA'D#!<(XH!.ik&gAh3PgAca(s7Y1HJcG`Sg7eQ/k.1PC~>
-!<E0!johL1eVf?:k4n*;!<)'T!.j:2k5YJ\ec1:%s7Y"CKE(rUeYN6-k.LbF~>
-!<E0!johL1eS8iMXF[I5XT._fec1:%s7Y"CKE(rUeYN6-k.LbF~>
-!<E0!johC3g4=g+g4@t<gAh3PgAca(s7Y1HJcG`Sg7eQ/k.1PC~>
-!<E0!johL1eVf?:k(2ZTk5YJ\ec1:%s7Y"CKE(rUeYN6-k.LbF~>
-!<E0!johL1eS8iMXF[I5XT._fec1:%s7Y"CKE(rUeYN6-k.LbF~>
-!<E0!johC3g4=g+g4@t<gAh3PgAca(s7Y1HJcG`Sg7eQ/k.1PC~>
-!<E0!johL1eVf?:k(2ZTk5YJ\ec1:%s7Y"CKE(rUeYN6-k.LbF~>
-!<E0!johL1eS8iMXP0`U!.h5[XT._fec1:%s7Y"CKE(rUeYN6-k.LbF~>
-!<E0!johC3g4=g+g=k6\!.ik4gAh3PgAca(s7Y1HJcG`Sg7eQ/k.1PC~>
-!<E0!johL1eVf?:k1\qt!.j:@k5YJ\ec1:%s7Y"CKE(rUeYN6-k.LbF~>
-!<E0!jp%X3eS8j#XSMqrXSi-MXQlke!9pTa!:$Zc!.h6:XT._fec1:%s7Y"CKE(rUeYN6-k.LbF~>
-!<E0!jp%O5g4=h/gA1gKgAM#&g?RAl!9r5:!:&;<!.ikhgAh3PgAca(s7Y1HJcG`Sg7eQ/k.1PC~>
-!<E0!jp%X3eVf@Jk5#)Wk5>:2k3D(/!9rYF!:&_H!.j:tk5YJ\ec1:%s7Y"CKE(rUeYN6-k.LbF~>
-!<E0!jq+?=eS8j#X8o?'!3E7%XK2F#X8i6OXO+$K!9pQb!.h6:XT._fec1:%s7Y"CKE(rUeYN6-
-k.LbF~>
-!<E0!jq+6?g4=h/g&Tj\!8?-,g=cQ*g&M,(g<eOR!9r2;!.ikhgAh3PgAca(s7Y1HJcG`Sg7eQ/
-k.1PC~>
-!<E0!jq+?=eVf@JjoFQ+!9WDDk2l[Bjo>C4k0W5j!9rVG!.j:tk5YJ\ec1:%s7Y"CKE(rUeYN6-
-k.LbF~>
-!<E0!jq"9<eS8j#X8o?'!3E7%X8r.!!!)u!rrALhrr<A,!!')#!3?/#XSr4sXSr4tXS`(sXSr4s
-XSi.hX8i7tXSi.rXSr2#X8r7$!W]='rW)nurW)nurrE)#rr@VO!j(hXrmh%$s8VfCs+C@O#1]OL
-k2s>WJ,~>
-!<E0!jq"0>g4=h/g&Tj\!8?-,g&V$(!!)uOrrAMArr<AZ!!(^Q!87DQgAV*LgAV*MgACsLgAV*L
-gAM$Ag&M-MgAM$KgAV'Qg&V-+!W^s.rW)oNrW)oNrrE)Qrr@W(!o!\Srn@C's8VfHs+14M#25dN
-k2s5TJ,~>
-!<E0!jq"9<eVf@JjoFQ+!9WDDjoG;@!!)u[rrAMMrr<Af!!)-]!9O7]k5GAXk5GAYk555Xk5GAX
-k5>;Mjo>DYk5>;Wk5G>]joGDC!W_BFrW)oZrW)oZrrE)]rr@W4!p9O_rmh%$s8VfCs+C@O#1]OL
-k2s>WJ,~>
-!<E0!johL1eS8jsX8i8!X8i7tX8i8!XT&9gXT&8+X8i7%!3E7%!<0&"!<&u!!<0&"!<0&"!<&u!
-!;iht!;rnu!<&u!!:m2k!;rnu!<&u!!<&u!!<0)"!<0&%!3E7%r2]kuri?)"rN$/&X8o?'!.h6O
-mf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=hQg&M-Og&M-Mg&M-OgA_/@gA_-Yg&M-,!8?-,!<1[P!<(UO!<1[P!<1[P!<(UO
-!;kIM!;tON!<(UO!:nhD!;tON!<(UO!<(UO!<1^P!<1[S!8?-,r7V,Nrn7>PrRqDTg&Tj\!.il(
-s8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf@`jo>D[jo>DYjo>D[k5PFLk5PDejo>DD!9WDD!<2*\!<)$[!<2*\!<2*\!<)$[
-!;kmY!;tsZ!<)$[!:o7P!;tsZ!<)$[!<)$[!<2-\!<2*_!9WDDr8mtZroO1\rT47`joFQ+!.j;4
-s8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8jsX8i8!X8i7tX8i6aX9em.X8o?'!3E7%rN#u!ri?)"r2]u#XK2EqX8i7pX8i7k
-X8i8!X8i7tX9/I(X8r1"!!*#"!W];%r2]kur2]kuriH,"JZSgOs6fm:s+C@Op=91qs8N;RV#TT>
-]`<Q~>
-!<E0!johC3g4=hQg&M-Og&M-Mg&M,:g'Ic5g&Tj\!8?-,rRq5Orn7>Pr7V5Qg=cQ#g&M-Ig&M-D
-g&M-Og&M-Mg&h?/g&V')!!*#P!W^pSr7V,Nr7V,Nrn@APJ_L(Vs8W)Ps+14Mp=fOts8N;WU&X9;
-\c@6~>
-!<E0!johL1eVf@`jo>D[jo>DYjo>CFjp;%MjoFQ+!9WDDrT4([roO1\r8n(]k2l[;jo>DUjo>DP
-jo>D[jo>DYjoYVGjoG>A!!*#\!W_?_r8mtZr8mtZroX4\J`cpns8W)Ks+C@Op=91qs8N;RV#TT>
-]`<Q~>
-!<E0!johL1eS8jsX8i8!X8i7tX8i6aX9em.X8o?'!3E7%rN#u!riGqrriH%uqQ'YsqlK\qnuMfk
-rN#u!qlBl"XK2EsXT&:tXSMqrX8i6OXSf1"mf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=hQg&M-Og&M-Mg&M,:g'Ic5g&Tj\!8?-,rRq5Orn@2Krn@;NqUtoLqqCrJo%F'D
-rRq5Oqq;,Pg=cQ%gA_0MgA1gKg&M,(gAK\)s8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf@`jo>D[jo>DYjo>CFjp;%MjoFQ+!9WDDrT4([roX%WroX.ZqW7bXqr[eVo&]oP
-rT4([qrRt\k2l[=k5PGYk5#)Wjo>C4k5=BAs8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8jsX8i8!X8i7tX8i6aX9em.X8o?'!3E7%rN#u!ri?)"oW/#mqlBbtr2]kurN#u!
-nuMfkrN#u!qlBl"XK2EsX9&C'!;rnu!;NVq!.h6LXT._fec1:%s7Y"CKE(rUeYN6-k.LbF~>
-!<E0!johC3g4=hQg&M-Og&M-Mg&M,:g'Ic5g&Tj\!8?-,rRq5Orn7>Po\'9Fqq;#Mr7V,NrRq5O
-o%F'DrRq5Oqq;,Pg=cQ%g&_9.!;tON!;P7J!.il%gAh3PgAca(s7Y1HJcG`Sg7eQ/k.1PC~>
-!<E0!johL1eVf@`jo>D[jo>DYjo>CFjp;%MjoFQ+!9WDDrT4([roO1\o]?,RqrRkYr8mtZrT4([
-o&]oPrT4([qrRt\k2l[=joPPF!;tsZ!;P[V!.j;1k5YJ\ec1:%s7Y"CKE(rUeYN6-k.LbF~>
-!<E0!johL1eS8jsX8i7uX8i8!X8i7uXT&9gX9em.X8o?'!3E7%rN#u!rN#u!rN$)$XK2F#X8i7t
-X8i7uX8i8"XT&:kX8i7uX8i8!X8i8!X8i8!X8i8"X9/I(X8r1"!!)u!!!*#"!!%SOr2fqdrmh%$
-s8VfCs+C@O#1]OLk2s>WJ,~>
-!<E0!johC3g4=hQg&M-Ng&M-Og&M-NgA_/@g'Ic5g&Tj\!8?-,rRq5OrRq5OrRq>Rg=cQ*g&M-M
-g&M-Ng&M-PgA_0Dg&M-Ng&M-Og&M-Og&M-Og&M-Pg&h?/g&V')!!)uO!!*#P!!%T(r7_2Nrn@C'
-s8VfHs+14M#25dNk2s5TJ,~>
-!<E0!johL1eVf@`jo>DZjo>D[jo>DZk5PFLjp;%MjoFQ+!9WDDrT4([rT4([rT41^k2l[Bjo>DY
-jo>DZjo>D\k5PGPjo>DZjo>D[jo>D[jo>D[jo>D\joYVGjoG>A!!)u[!!*#\!!%T4r9"%Zrmh%$
-s8VfCs+C@O#1]OLk2s>WJ,~>
-!<E0!johL1eS8juXS`(sXSi.rXT&9hXSr2%X8i7%quHburW)nur;chuquHYrquH\srW!#$!!)\n
-quH\sr;c_rr;churrE)#rW)nur;chur;_DMriH.frmh%$s8VfCs+C@O#1]OLk2s>WJ,~>
-!<E0!johC3g4=hSgACsLgAM$KgA_/AgAV'Sg&M-,quHcNrW)oNr;ciNquHZKquH]LrW!#R!!)]G
-quH]Lr;c`Kr;ciNrrE)QrW)oNr;ciNr;_E&rn@DPrn@C's8VfHs+14M#25dNk2s5TJ,~>
-!<E0!johL1eVf@bk555Xk5>;Wk5PFMk5G>_jo>DDquHcZrW)oZr;ciZquHZWquH]XrW!#^!!)]S
-quH]Xr;c`Wr;ciZrrE)]rW)oZr;ciZr;_E2roX7\rmh%$s8VfCs+C@O#1]OLk2s>WJ,~>
-!<E0!johL1eS8iMXF[I5XT._fec1:%s7Y"CKE(rUeYN6-k.LbF~>
-!<E0!johC3g4=g+g4@t<gAh3PgAca(s7Y1HJcG`Sg7eQ/k.1PC~>
-!<E0!johL1eVf?:k(2ZTk5YJ\ec1:%s7Y"CKE(rUeYN6-k.LbF~>
-!<E0!johL1eS8iMXF[I5XT._fec1:%s7Y"CKE(rUeYN6-k.LbF~>
-!<E0!johC3g4=g+g4@t<gAh3PgAca(s7Y1HJcG`Sg7eQ/k.1PC~>
-!<E0!johL1eVf?:k(2ZTk5YJ\ec1:%s7Y"CKE(rUeYN6-k.LbF~>
-!<E0!johL1eS8iMXN[d@!.h5qXT._fec1:%s7Y"CKE(rUeYN6-k.LbF~>
-!<E0!johC3g4=g+g<A:G!.ikJgAh3PgAca(s7Y1HJcG`Sg7eQ/k.1PC~>
-!<E0!johL1eVf?:k02u_!.j:Vk5YJ\ec1:%s7Y"CKE(rUeYN6-k.LbF~>
-!<E0!johL1eS8iMXF[I5XT._fec1:%s7Y"CKE(rUeYN6-k.LbF~>
-!<E0!johC3g4=g+g4@t<gAh3PgAca(s7Y1HJcG`Sg7eQ/k.1PC~>
-!<E0!johL1eVf?:k(2ZTk5YJ\ec1:%s7Y"CKE(rUeYN6-k.LbF~>
-!<E0!johL1eS8iMXF[I5XT._fec1:%s7Y"CKE(rUeYN6-k.LbF~>
-!<E0!johC3g4=g+g4@t<gAh3PgAca(s7Y1HJcG`Sg7eQ/k.1PC~>
-!<E0!johL1eVf?:k(2ZTk5YJ\ec1:%s7Y"CKE(rUeYN6-k.LbF~>
-!<E0!johL1eS8iMX8o@#!;rqs!;rqs!;rqs!:m2k!;`eq!:m2k!;NYq!:m2k!;NYq!;!;j!<'"r
-!:m5k!;rqt!:m5i!;iks!;iht!;W_q!;`es!;iht!:m5kmf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g&Tk*!;tRL!;tRL!;tRL!:nhD!;bFJ!:nhD!;P:J!:nhD!;P:J!;"qC!<(XK
-!:nkD!;tRM!:nkB!;kLL!;kIM!;Y@J!;bFL!;kIM!:nkDs8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:joFQB!;u!X!;u!X!;u!X!:o7P!;bjV!:o7P!;P^V!:o7P!;P^V!;#@O!<)'W
-!:o:P!;u!Y!:o:N!;kpX!;kmY!;YdV!;bjX!;kmY!:o:Ps8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!jp%X3eS8j#XSW"rXSr4uXSW"qXSr2#X8r7$q>^MsqZ+%*!!)u!!!*#"!!)u!!!*#"!!)u!
-!!*#"!!)u!!!)YmrrDqt!!)u!!!)YmrrDkr!W];%o;qrlq5aVtX8qmo!!)u!!!*#"!!)u!!!)Vl
-!W];%rN#u!ri?)"oW/#mrN#u!rN#u!q5jSrqQ'YspoFMsX8r1"rrDVks6fm:s+C@Op=91qs8N;R
-V#TT>]`<Q~>
-!<E0!jp%O5g4=h/gA:mKgAV*NgA:mJgAV'Qg&V-+q>^NLqZ+%X!!)uO!!*#P!!)uO!!*#P!!)uO
-!!*#P!!)uO!!)ZFrrDrM!!)uO!!)ZFrrDlK!W^pSo@j3Eq:YlMg&Ud!!!)uO!!*#P!!)uO!!)WE
-!W^pSrRq5Orn7>Po\'9FrRq5OrRq5Oq:biKqUtoLpt>cLg&V')rrDWDs8W)Ps+14Mp=fOts8N;W
-U&X9;\c@6~>
-!<E0!jp%X3eVf@Jk5,/Wk5GAZk5,/Vk5G>]joGDCq>^NXqZ+%d!!)u[!!*#\!!)u[!!*#\!!)u[
-!!*#\!!)u[!!)ZRrrDrY!!)u[!!)ZRrrDlW!W_?_oB-&Qq;q_YjoG&9!!)u[!!*#\!!)u[!!)WQ
-!W_?_rT4([roO1\o]?,RrT4([rT4([q<%\WqW7bXpuVVXjoG>ArrDWPs8W)Ks+C@Op=91qs8N;R
-V#TT>]`<Q~>
-!<E0!johL1eS8juX8i8!X8i7uX8i7uX8i8!X8i8"X8i8"XT&;!X8i8!X9/I(X8r4#!!'I/!!)u!
-!!*#"!!)u!!!*#"!!)u!!!*#"!!)u!!!)\n!W];%qlBbtrN#u!orJ2pX8r't!W];%oW/)oX8r't
-!W];%oW/#mrN#u!q5aPro;hunX8r4#!!)u!!!)\n!!)u!!!*#"!!)hr!W];%qlBbtpT+DrX8r4#
-!W];%nuVlZrmh%$s8VfCs+C@O#1]OLk2s>WJ,~>
-!<E0!johC3g4=hSg&M-Og&M-Ng&M-Ng&M-Og&M-Pg&M-PgA_0Og&M-Og&h?/g&V**!!'I]!!)uO
-!!*#P!!)uO!!*#P!!)uO!!*#P!!)uO!!)]G!W^pSqq;#MrRq5Op"BHIg&Us&!W^pSo\'?Hg&Us&
-!W^pSo\'9FrRq5Oq:YfKo@a6Gg&V**!!)uO!!)]G!!)uO!!*#P!!)iK!W^pSqq;#MpY#ZKg&V**
-!W^pSo%O-Drn@C's8VfHs+14M#25dNk2s5TJ,~>
-!<E0!johL1eVf@bjo>D[jo>DZjo>DZjo>D[jo>D\jo>D\k5PG[jo>D[joYVGjoGAB!!'Ii!!)u[
-!!*#\!!)u[!!*#\!!)u[!!*#\!!)u[!!)]S!W_?_qrRkYrT4([p#Z;UjoG5>!W_?_o]?2TjoG5>
-!W_?_o]?,RrT4([q;qYWoB$)SjoGAB!!)u[!!)]S!!)u[!!*#\!!)iW!W_?_qrRkYpZ;MWjoGAB
-!W_?_o&fuPrmh%$s8VfCs+C@O#1]OLk2s>WJ,~>
-!<E0!johL1eS8juX8i8!X8i8!X9&C'!<&u!!<&u!!<0&"!<&u!!<&u!!<&u$!3E7%r2]kurN-#!
-\?#Z1ri?)"rN#u!ri?)"rN#u!q5aPro;holqlBbtrN#u!o;holqQ'c!XK2EmX8i7sX9/I(X8q^j
-!!)ks!!)Vl!s#F(!<&u!!<&u!!:[&i!<0&"!;EPp!;iht!;NVt!3E7%qlBbtnuVlZrmh%$s8VfC
-s+C@O#1]OLk2s>WJ,~>
-!<E0!johC3g4=hSg&M-Og&M-Og&_9.!<(UO!<(UO!<1[P!<(UO!<(UO!<(UR!8?-,r7V,NrS%8O
-\Cpo_rn7>PrRq5Orn7>PrRq5Oq:YfKo@a0Eqq;#MrRq5Oo@a0EqUu#Og=cPtg&M-Lg&h?/g&UTq
-!!)lL!!)WE!s%'/!<(UO!<(UO!:\\B!<1[P!;G1I!;kIM!;P7M!8?-,qq;#Mo%O-Drn@C's8VfH
-s+14M#25dNk2s5TJ,~>
-!<E0!johL1eVf@bjo>D[jo>D[joPPF!<)$[!<)$[!<2*\!<)$[!<)$[!<)$^!9WDDr8mtZrT=+[
-\E3bkroO1\rT4([roO1\rT4([q;qYWoB$#QqrRkYrT4([oB$#QqW7k[k2l[7jo>DXjoYVGjoFl4
-!!)lX!!)WQ!s%KG!<)$[!<)$[!:]+N!<2*\!;GUU!;kmY!;P[Y!9WDDqrRkYo&fuPrmh%$s8VfC
-s+C@O#1]OLk2s>WJ,~>
-!<E0!johL1eS8juX8i8!X8i8!X9&C'!<&u!!<&u!!<0&"!;NVt!3E7%rN#u!r2]kurN-#!\Z>c2
-rN#u!rN#u!ri?)"rN#u!qQ'YsnuMfkqlBbtrN#u!o;holqQ'c!XK2EmX8i7sX9/I(X8qak!!)hr
-!!)Vl!s#F(!<&u!!<0)"!:d,j!<&u"!3H/"qlBbtqlBeuXSr4tX9/I(X8r.!!!)Sks6fm:s+C@O
-p=91qs8N;RV#TT>]`<Q~>
-!<E0!johC3g4=hSg&M-Og&M-Og&_9.!<(UO!<(UO!<1[P!;P7M!8?-,rRq5Or7V,NrS%8O\_7#`
-rRq5OrRq5Orn7>PrRq5OqUtoLo%F'Dqq;#MrRq5Oo@a0EqUu#Og=cPtg&M-Lg&h?/g&UWr!!)iK
-!!)WE!s%'/!<(UO!<1^P!:ebC!<(UP!8@DPqq;#Mqq;&NgAV*Mg&h?/g&V$(!!)TDs8W)Ps+14M
-p=fOts8N;WU&X9;\c@6~>
-!<E0!johL1eVf@bjo>D[jo>D[joPPF!<)$[!<)$[!<2*\!;P[Y!9WDDrT4([r8mtZrT=+[\`Nkl
-rT4([rT4([roO1\rT4([qW7bXo&]oPqrRkYrT4([oB$#QqW7k[k2l[7jo>DXjoYVGjoFo5!!)iW
-!!)WQ!s%KG!<)$[!<2-\!:f1O!<)$\!9X7\qrRkYqrRnZk5GAYjoYVGjoG;@!!)TPs8W)Ks+C@O
-p=91qs8N;RV#TT>]`<Q~>
-!<E0!johL1eS8juX8i8!X8i8"X8i8"X8i8"X8i8"X8i7uXSi.sXSi.tX8i7uX8i7-X8i7uX8i8!
-X8i8"X8i8!X8i7tX8i7uXSW"qX8i7tX8i8!X8i8"XSW"qX8i7tX8i8"X8i7kX8i7tX8i8"X8i7j
-X8i7qX8i7mX8i8"X8i7uXSr2#X8qgm!!)qurrE&"!!)qu!!)ntrrE&"!!*#"!!*#"!!)nt!!)Sk
-s6fm:s+C@Op=91qs8N;RV#TT>]`<Q~>
-!<E0!johC3g4=hSg&M-Og&M-Pg&M-Pg&M-Pg&M-Pg&M-NgAM$LgAM$Mg&M-Ng&M,[g&M-Ng&M-O
-g&M-Pg&M-Og&M-Mg&M-NgA:mJg&M-Mg&M-Og&M-PgA:mJg&M-Mg&M-Pg&M-Dg&M-Mg&M-Pg&M-C
-g&M-Jg&M-Fg&M-Pg&M-NgAV'Qg&U]t!!)rNrrE&P!!)rN!!)oMrrE&P!!*#P!!*#P!!)oM!!)TD
-s8W)Ps+14Mp=fOts8N;WU&X9;\c@6~>
-!<E0!johL1eVf@bjo>D[jo>D\jo>D\jo>D\jo>D\jo>DZk5>;Xk5>;Yjo>DZjo>Cgjo>DZjo>D[
-jo>D\jo>D[jo>DYjo>DZk5,/Vjo>DYjo>D[jo>D\k5,/Vjo>DYjo>D\jo>DPjo>DYjo>D\jo>DO
-jo>DVjo>DRjo>D\jo>DZk5G>]joFu7!!)rZrrE&\!!)rZ!!)oYrrE&\!!*#\!!*#\!!)oY!!)TP
-s8W)Ks+C@Op=91qs8N;RV#TT>]`<Q~>
-!<E0!johL1eS8juXS`(sXS`(tXSi.nX8i8!X9/I(X8r4#!!)qu!!'F.!!)nt!!)u!!!*#"!!)u!
-!!)qu!!)Mi!!)nt!!)u!!!)Vl!!)nt!!*#"!!)Sk!!)nt!!*#"!!)Sk!!)eq!!)Vl!!*#"!!)eq
-!!)Vl!!)nt!!)u!!!)qu!!)nt!!)u!!!*#"!!*#"!!)nt!!)Sks6fm:s+C@Op=91qs8N;RV#TT>
-]`<Q~>
-!<E0!johC3g4=hSgACsLgACsMgAM$Gg&M-Og&h?/g&V**!!)rN!!'F\!!)oM!!)uO!!*#P!!)uO
-!!)rN!!)NB!!)oM!!)uO!!)WE!!)oM!!*#P!!)TD!!)oM!!*#P!!)TD!!)fJ!!)WE!!*#P!!)fJ
-!!)WE!!)oM!!)uO!!)rN!!)oM!!)uO!!*#P!!*#P!!)oM!!)TDs8W)Ps+14Mp=fOts8N;WU&X9;
-\c@6~>
-!<E0!johL1eVf@bk555Xk555Yk5>;Sjo>D[joYVGjoGAB!!)rZ!!'Fh!!)oY!!)u[!!*#\!!)u[
-!!)rZ!!)NN!!)oY!!)u[!!)WQ!!)oY!!*#\!!)TP!!)oY!!*#\!!)TP!!)fV!!)WQ!!*#\!!)fV
-!!)WQ!!)oY!!)u[!!)rZ!!)oY!!)u[!!*#\!!*#\!!)oY!!)TPs8W)Ks+C@Op=91qs8N;RV#TT>
-]`<Q~>
-!<E0!johL1eS8juX8i7sX8i7uX9/I(X8r7$!!)u!!!)u!!!)u!!!)u!!s#F(!;rnu!4Js/!;`bs
-!<&u!!<0&"!<&u!!<&u!!:Quh!;iht!<&u!!;!8l!;ikp!;!8l!;ikp!;*>m!;EPp!;!;h!;W\r
-!;*>m!;`bs!<&u!!;rnu!;iht!<&u!!<0(s!;rnu!:m5kmf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=hSg&M-Lg&M-Ng&h?/g&V-+!!)uO!!)uO!!)uO!!)uO!s%'/!;tON!4LS]!;bCL
-!<(UO!<1[P!<(UO!<(UO!:SVA!;kIM!<(UO!;"nE!;kLI!;"nE!;kLI!;+tF!;G1I!;"qA!;Y=K
-!;+tF!;bCL!<(UO!;tON!;kIM!<(UO!<1^L!;tON!:nkDs8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf@bjo>DXjo>DZjoYVGjoGDC!!)u[!!)u[!!)u[!!)u[!s%KG!;tsZ!4M"i!;bgX
-!<)$[!<2*\!<)$[!<)$[!:T%M!;kmY!<)$[!;#=Q!;kpU!;#=Q!;kpU!;,CR!;GUU!;#@M!;YaW
-!;,CR!;bgX!<)$[!;tsZ!;kmY!<)$[!<2-X!;tsZ!:o:Ps8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8juX8i7sX8i7uX9/I(X8r4#!!*#"rrE&"!!)u!!!)u!!s#F(!<&u!!;rqu!55H6
-!<&u!!<0&"!<&u!!<0&"!<&u!!<0&"!<&u!!;!8l!;iht!<&u!!;!8l!;EPp!:m2k!;EPp!;ikt
-!;rnu!<&u!!;iht!;`es!;NVq!;W\r!;ikt!;rnu!<&u!!<&u!!<0&"!;rnu!;`bs!<0&"!;`bs
-!;iht!:m5kmf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=hSg&M-Lg&M-Ng&h?/g&V**!!*#PrrE&P!!)uO!!)uO!s%'/!<(UO!;tRN!57(d
-!<(UO!<1[P!<(UO!<1[P!<(UO!<1[P!<(UO!;"nE!;kIM!<(UO!;"nE!;G1I!:nhD!;G1I!;kLM
-!;tON!<(UO!;kIM!;bFL!;P7J!;Y=K!;kLM!;tON!<(UO!<(UO!<1[P!;tON!;bCL!<1[P!;bCL
-!;kIM!:nkDs8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf@bjo>DXjo>DZjoYVGjoGAB!!*#\rrE&\!!)u[!!)u[!s%KG!<)$[!;u!Z!57Lp
-!<)$[!<2*\!<)$[!<2*\!<)$[!<2*\!<)$[!;#=Q!;kmY!<)$[!;#=Q!;GUU!:o7P!;GUU!;kpY
-!;tsZ!<)$[!;kmY!;bjX!;P[V!;YaW!;kpY!;tsZ!<)$[!<)$[!<2*\!;tsZ!;bgX!<2*\!;bgX
-!;kmY!:o:Ps8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!jp%X3eS8j#XSi.tXSi,!XSMqqX98O)X8o@$!<'"q!!'+t!;ikt!55K2!<'"t!;rqs!<'"r
-!;3Gk!;rqs!;*Aj!;`er!;3Gk!;`er!;rqu!;rqq!;iht!;`es!;W_q!<'"u!;`es!;rqq!;rqt
-!<'"s!;iks!;`er!<0(t!;*Ammf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!jp%O5g4=h/gAM$MgAM!OgA1gJg&qE0g&Tk+!<(XJ!!(aM!;kLM!57+`!<(XM!;tRL!<(XK
-!;5(D!;tRL!;,"C!;bFK!;5(D!;bFK!;tRN!;tRJ!;kIM!;bFL!;Y@J!<(XN!;bFL!;tRJ!;tRM
-!<(XL!;kLL!;bFK!<1^M!;,"Fs8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!jp%X3eVf@Jk5>;Yk5>8[k5#)Vjob\HjoFQC!<)'V!!)0Y!;kpY!57Ol!<)'Y!;u!X!<)'W
-!;5LP!;u!X!;,FO!;bjW!;5LP!;bjW!;u!Z!;u!V!;kmY!;bjX!;YdV!<)'Z!;bjX!;u!V!;u!Y
-!<)'X!;kpX!;bjW!<2-Y!;,FRs8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8iMXF[I5XT._fec1:%s7Y"CKE(rUeYN6-k.LbF~>
-!<E0!johC3g4=g+g4@t<gAh3PgAca(s7Y1HJcG`Sg7eQ/k.1PC~>
-!<E0!johL1eVf?:k(2ZTk5YJ\ec1:%s7Y"CKE(rUeYN6-k.LbF~>
-!<E0!johL1eS8iMXF[I5XT._fec1:%s7Y"CKE(rUeYN6-k.LbF~>
-!<E0!johC3g4=g+g4@t<gAh3PgAca(s7Y1HJcG`Sg7eQ/k.1PC~>
-!<E0!johL1eVf?:k(2ZTk5YJ\ec1:%s7Y"CKE(rUeYN6-k.LbF~>
-!<E0!johL1eS8iMXF[I5XT._fec1:%s7Y"CKE(rUeYN6-k.LbF~>
-!<E0!johC3g4=g+g4@t<gAh3PgAca(s7Y1HJcG`Sg7eQ/k.1PC~>
-!<E0!johL1eVf?:k(2ZTk5YJ\ec1:%s7Y"CKE(rUeYN6-k.LbF~>
-!<E0!johL1eS8iMXF[I5XT._fec1:%s7Y"CKE(rUeYN6-k.LbF~>
-!<E0!johC3g4=g+g4@t<gAh3PgAca(s7Y1HJcG`Sg7eQ/k.1PC~>
-!<E0!johL1eVf?:k(2ZTk5YJ\ec1:%s7Y"CKE(rUeYN6-k.LbF~>
-!<E0!johL1eS8iMXF[I5XT._fec1:%s7Y"CKE(rUeYN6-k.LbF~>
-!<E0!johC3g4=g+g4@t<gAh3PgAca(s7Y1HJcG`Sg7eQ/k.1PC~>
-!<E0!johL1eVf?:k(2ZTk5YJ\ec1:%s7Y"CKE(rUeYN6-k.LbF~>
-!<E0!johL1eS8iMXF[I5XT._fec1:%s7Y"CKE(rUeYN6-k.LbF~>
-!<E0!johC3g4=g+g4@t<gAh3PgAca(s7Y1HJcG`Sg7eQ/k.1PC~>
-!<E0!johL1eVf?:k(2ZTk5YJ\ec1:%s7Y"CKE(rUeYN6-k.LbF~>
-!<E0!johL1eS8jtXSr2#X8r7$r;churW)u"rW)u"q>gPsq>^MsrW)u"rW)u"q>gMrrVuu#!.h5&
-XOXEPmf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=hRgAV'Qg&V-+r;ciNrW)uPrW)uPq>gQLq>^NLrW)uPrW)uPq>gNKrVuuQ!.ijT
-g==pWs8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf@ak5G>]joGDCr;ciZrW)u\rW)u\q>gQXq>^NXrW)u\rW)u\q>gNWrVuu]!.j9`
-k1/Vos8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8juX8i8"XT&;#X8i8!X8i8"XT&;"X8i8"X9J[+X8o?'!<0&"!<&u%!3E7%!<0&"
-!<0&+!3E7%XK2E'X8r7$rr@VOJZRD's6fm:s+C@Op=91qs8N;RV#TT>]`<Q~>
-!<E0!johC3g4=hSg&M-PgA_0Qg&M-Og&M-PgA_0Pg&M-Pg'.Q2g&Tj\!<1[P!<(US!8?-,!<1[P
-!<1[Y!8?-,g=cP\g&V-+rr@W(J_JZ.s8W)Ps+14Mp=fOts8N;WU&X9;\c@6~>
-!<E0!johL1eVf@bjo>D\k5PG]jo>D[jo>D\k5PG\jo>D\jothJjoFQ+!<2*\!<)$_!9WDD!<2*\
-!<2*e!9WDDk2l[+joGDCrr@W4J`bMFs8W)Ks+C@Op=91qs8N;RV#TT>]`<Q~>
-!<E0!jp.^4eS8j#X8r1"!W];%qlC&'XK2E'!3E7%ri?;(XK2E'X8r7$!!)u!#QUs-!3?1%X8r7$
-#lq'.!3E7%XK2F#X8i7uXT&9OXF[J.XT._fec1:%s7Y"CKE(rUeYN6-k.LbF~>
-!<E0!jp.U6g4=h/g&V')!W^pSqq;;Ug=cP\!8?-,rn7PVg=cP\g&V-+!!)uO#QWT4!87G,g&V-+
-#lr]5!8?-,g=cQ*g&M-NgA_/(g4@u5gAh3PgAca(s7Y1HJcG`Sg7eQ/k.1PC~>
-!<E0!jp.^4eVf@JjoG>A!W_?_qrS.ak2l[+!9WDDroOCbk2l[+joGDC!!)u[#QX#L!9O:DjoGDC
-#ls,M!9WDDk2l[Bjo>DZk5PF4k(2[Mk5YJ\ec1:%s7Y"CKE(rUeYN6-k.LbF~>
-!<E0!jp.^4eS8j#X8r*u!!)nt#QUs-!3?1%X8r.!!!)nt!s#F(!<&u&!3?1%X8r.!!!)qu!!)bp
[email protected]:s+C@Op=91qs8N;RV#TT>]`<Q~>
-!<E0!jp.U6g4=h/g&V!'!!)oM#QWT4!87G,g&V$(!!)oM!s%'/!<(UT!87G,g&V$(!!)rN!!)cI
-rr@W(J_Jo5s8W)Ps+14Mp=fOts8N;WU&X9;\c@6~>
-!<E0!jp.^4eVf@JjoG8?!!)oY#QX#L!9O:DjoG;@!!)oY!s%KG!<)$`!9O:DjoG;@!!)rZ!!)cU
-rr@W4J`bbMs8W)Ks+C@Op=91qs8N;RV#TT>]`<Q~>
-!<E0!jp.^4eS8j#X8r*u!!)nt#QUs-!3E7%X8r.!!!)ntr;cet"TYX*!3?1tX8i7tXSi-MXF[J&
-XT._fec1:%s7Y"CKE(rUeYN6-k.LbF~>
-!<E0!jp.U6g4=h/g&V!'!!)oM#QWT4!8?-,g&V$(!!)oMr;cfM"T[91!87GMg&M-MgAM#&g4@u-
-gAh3PgAca(s7Y1HJcG`Sg7eQ/k.1PC~>
-!<E0!jp.^4eVf@JjoG8?!!)oY#QX#L!9WDDjoG;@!!)oYr;cfY"T[]I!9O:Yjo>DYk5>:2k(2[E
-k5YJ\ec1:%s7Y"CKE(rUeYN6-k.LbF~>
-!<E0!jp.^4eS8j#X8r*u!!)nt#QUs-!3E7%X8r.!!!)nt!s#F(!<&u&!3E7%X8r.!!!)bp!!%SO
-JZRD's6fm:s+C@Op=91qs8N;RV#TT>]`<Q~>
-!<E0!jp.U6g4=h/g&V!'!!)oM#QWT4!8?-,g&V$(!!)oM!s%'/!<(UT!8?-,g&V$(!!)cI!!%T(
-J_JZ.s8W)Ps+14Mp=fOts8N;WU&X9;\c@6~>
-!<E0!jp.^4eVf@JjoG8?!!)oY#QX#L!9WDDjoG;@!!)oY!s%KG!<)$`!9WDDjoG;@!!)cU!!%T4
-J`bMFs8W)Ks+C@Op=91qs8N;RV#TT>]`<Q~>
-!<E0!jp.^4eS8j#X8r*u!!)nt!s#F(!<0)"!;iht!;iht!<&u$!3E7%riH,"qlBbtr2]kurN#u!
-JZOF(eZAf=rmh%$s8VfCs+C@O#1]OLk2s>WJ,~>
-!<E0!jp.U6g4=h/g&V!'!!)oM!s%'/!<1^P!;kIM!;kIM!<(UR!8?-,rn@APqq;#Mr7V,NrRq5O
-J_G\/e_:''rn@C's8VfHs+14M#25dNk2s5TJ,~>
-!<E0!jp.^4eVf@JjoG8?!!)oY!s%KG!<2-\!;kmY!;kmY!<)$^!9WDDroX4\qrRkYr8mtZrT4([
-J`_OGe`Qo3rmh%$s8VfCs+C@O#1]OLk2s>WJ,~>
-!<E0!johL1eS8juX8i8!X9/I(X8r4#!!*#"!!*#"rrDqt!!)nt!!)u!!s#F(!<0)"!;iht!;rqu
-!<0&"!;rqu!.h5&XPBoWmf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=hSg&M-Og&h?/g&V**!!*#P!!*#PrrDrM!!)oM!!)uO!s%'/!<1^P!;kIM!;tRN
-!<1[P!;tRN!.ijTg>(E^s8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf@bjo>D[joYVGjoGAB!!*#\!!*#\rrDrY!!)oY!!)u[!s%KG!<2-\!;kmY!;u!Z
-!<2*\!;u!Z!.j9`k1o,!s8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8jtXSi.tXSi.uXSr5!X8i8!XS`(tXSMnsXSr5!X8i8!XS`(tX8r=&rW)hsrr@VO
-JZRY.s6fm:s+C@Op=91qs8N;RV#TT>]`<Q~>
-!<E0!johC3g4=hRgAM$MgAM$NgAV*Og&M-OgACsMgA1dLgAV*Og&M-OgACsMg&V3-rW)iLrr@W(
-J_Jo5s8W)Ps+14Mp=fOts8N;WU&X9;\c@6~>
-!<E0!johL1eVf@ak5>;Yk5>;Zk5GA[jo>D[k555Yk5#&Xk5GA[jo>D[k555YjoGJErW)iXrr@W4
-J`bbMs8W)Ks+C@Op=91qs8N;RV#TT>]`<Q~>
-!<E0!johL1eS8iMXF[I5XT._fec1:%s7Y"CKE(rUeYN6-k.LbF~>
-!<E0!johC3g4=g+g4@t<gAh3PgAca(s7Y1HJcG`Sg7eQ/k.1PC~>
-!<E0!johL1eVf?:k(2ZTk5YJ\ec1:%s7Y"CKE(rUeYN6-k.LbF~>
-!<E0!johL1eS8iMXF[I5XT._fec1:%s7Y"CKE(rUeYN6-k.LbF~>
-!<E0!johC3g4=g+g4@t<gAh3PgAca(s7Y1HJcG`Sg7eQ/k.1PC~>
-!<E0!johL1eVf?:k(2ZTk5YJ\ec1:%s7Y"CKE(rUeYN6-k.LbF~>
-!<E0!johL1eS8iMXF[I5XT._fec1:%s7Y"CKE(rUeYN6-k.LbF~>
-!<E0!johC3g4=g+g4@t<gAh3PgAca(s7Y1HJcG`Sg7eQ/k.1PC~>
-!<E0!johL1eVf?:k(2ZTk5YJ\ec1:%s7Y"CKE(rUeYN6-k.LbF~>
-!<E0!johL1eS8iMXF[I5XT._fec1:%s7Y"CKE(rUeYN6-k.LbF~>
-!<E0!johC3g4=g+g4@t<gAh3PgAca(s7Y1HJcG`Sg7eQ/k.1PC~>
-!<E0!johL1eVf?:k(2ZTk5YJ\ec1:%s7Y"CKE(rUeYN6-k.LbF~>
-!<E0!johL1eS8iMXF[I5XT._fec1:%s7Y"CKE(rUeYN6-k.LbF~>
-!<E0!johC3g4=g+g4@t<gAh3PgAca(s7Y1HJcG`Sg7eQ/k.1PC~>
-!<E0!johL1eVf?:k(2ZTk5YJ\ec1:%s7Y"CKE(rUeYN6-k.LbF~>
-!<E0!johL1eS8iMXF[I5XT._fec1:%s7Y"CKE(rUeYN6-k.LbF~>
-!<E0!johC3g4=g+g4@t<gAh3PgAca(s7Y1HJcG`Sg7eQ/k.1PC~>
-!<E0!johL1eVf?:k(2ZTk5YJ\ec1:%s7Y"CKE(rUeYN6-k.LbF~>
-!<E0!johL1eS8iMXF[I5XT._fec1:%s7Y"CKE(rUeYN6-k.LbF~>
-!<E0!johC3g4=g+g4@t<gAh3PgAca(s7Y1HJcG`Sg7eQ/k.1PC~>
-!<E0!johL1eVf?:k(2ZTk5YJ\ec1:%s7Y"CKE(rUeYN6-k.LbF~>
-!<E0!johL1eS8iMXF[I5XT._fec1:%s7Y"CKE(rUeYN6-k.LbF~>
-!<E0!johC3g4=g+g4@t<gAh3PgAca(s7Y1HJcG`Sg7eQ/k.1PC~>
-!<E0!johL1eVf?:k(2ZTk5YJ\ec1:%s7Y"CKE(rUeYN6-k.LbF~>
-!<E0!johL1eS8iMXF[I5XT._fec1:%s7Y"CKE(rUeYN6-k.LbF~>
-!<E0!johC3g4=g+g4@t<gAh3PgAca(s7Y1HJcG`Sg7eQ/k.1PC~>
-!<E0!johL1eVf?:k(2ZTk5YJ\ec1:%s7Y"CKE(rUeYN6-k.LbF~>
-!<E0!johL1eS8iMXF[I5XT._fec1:%s7Y"CKE(rUeYN6-k.LbF~>
-!<E0!johC3g4=g+g4@t<gAh3PgAca(s7Y1HJcG`Sg7eQ/k.1PC~>
-!<E0!johL1eVf?:k(2ZTk5YJ\ec1:%s7Y"CKE(rUeYN6-k.LbF~>
-!<E0!johL1eS8iMXF[I5XT._fec1:%s7Y"CKE(rUeYN6-k.LbF~>
-!<E0!johC3g4=g+g4@t<gAh3PgAca(s7Y1HJcG`Sg7eQ/k.1PC~>
-!<E0!johL1eVf?:k(2ZTk5YJ\ec1:%s7Y"CKE(rUeYN6-k.LbF~>
-!<E0!johL1eS8iMXF[I5XT._fec1:%s7Y"CKE(rUeYN6-k.LbF~>
-!<E0!johC3g4=g+g4@t<gAh3PgAca(s7Y1HJcG`Sg7eQ/k.1PC~>
-!<E0!johL1eVf?:k(2ZTk5YJ\ec1:%s7Y"CKE(rUeYN6-k.LbF~>
-!<E0!johL1eS8iMXF[I5XT._fec1:%s7Y"CKE(rUeYN6-k.LbF~>
-!<E0!johC3g4=g+g4@t<gAh3PgAca(s7Y1HJcG`Sg7eQ/k.1PC~>
-!<E0!johL1eVf?:k(2ZTk5YJ\ec1:%s7Y"CKE(rUeYN6-k.LbF~>
-!<E0!johL1eS8iMXF[I5XT._fec1:%s7Y"CKE(rUeYN6-k.LbF~>
-!<E0!johC3g4=g+g4@t<gAh3PgAca(s7Y1HJcG`Sg7eQ/k.1PC~>
-!<E0!johL1eVf?:k(2ZTk5YJ\ec1:%s7Y"CKE(rUeYN6-k.LbF~>
-!<E0!johL1eS8iMXF[I5XT._fec1:%s7Y"CKE(rUeYN6-k.LbF~>
-!<E0!johC3g4=g+g4@t<gAh3PgAca(s7Y1HJcG`Sg7eQ/k.1PC~>
-!<E0!johL1eVf?:k(2ZTk5YJ\ec1:%s7Y"CKE(rUeYN6-k.LbF~>
-!<E0!johL1eS8iMXF[I5XT._fec1:%s7Y"CKE(rUeYN6-k.LbF~>
-!<E0!johC3g4=g+g4@t<gAh3PgAca(s7Y1HJcG`Sg7eQ/k.1PC~>
-!<E0!johL1eVf?:k(2ZTk5YJ\ec1:%s7Y"CKE(rUeYN6-k.LbF~>
-!<E0!johL1eS8iMXF[I5XT._fec1:%s7Y"CKE(rUeYN6-k.LbF~>
-!<E0!johC3g4=g+g4@t<gAh3PgAca(s7Y1HJcG`Sg7eQ/k.1PC~>
-!<E0!johL1eVf?:k(2ZTk5YJ\ec1:%s7Y"CKE(rUeYN6-k.LbF~>
-!<E0!johL1eS8iMXF[I5XT._fec1:%s7Y"CKE(rUeYN6-k.LbF~>
-!<E0!johC3g4=g+g4@t<gAh3PgAca(s7Y1HJcG`Sg7eQ/k.1PC~>
-!<E0!johL1eVf?:k(2ZTk5YJ\ec1:%s7Y"CKE(rUeYN6-k.LbF~>
-!<E0!johL1eS8iMXF[I5XT._fec1:%s7Y"CKE(rUeYN6-k.LbF~>
-!<E0!johC3g4=g+g4@t<gAh3PgAca(s7Y1HJcG`Sg7eQ/k.1PC~>
-!<E0!johL1eVf?:k(2ZTk5YJ\ec1:%s7Y"CKE(rUeYN6-k.LbF~>
-!<E0!johL1eS8iMXF[I5XT._fec1:%s7Y"CKE(rUeYN6-k.LbF~>
-!<E0!johC3g4=g+g4@t<gAh3PgAca(s7Y1HJcG`Sg7eQ/k.1PC~>
-!<E0!johL1eVf?:k(2ZTk5YJ\ec1:%s7Y"CKE(rUeYN6-k.LbF~>
-!<E0!johL1eS8jOX8i7EX8i7*XSi.WX8i7JXT&:DX8i7FXT._fec1:%s7Y"CKE(rUeYN6-k.LbF~>
-!<E0!johC3g4=h-g&M,sg&M,XgAM$0g&M-#gA_/rg&M,tgAh3PgAca(s7Y1HJcG`Sg7eQ/k.1PC~>
-!<E0!johL1eVf@<jo>D*jo>Cdk5>;<jo>D/k5PG)jo>D+k5YJ\ec1:%s7Y"CKE(rUeYN6-k.LbF~>
-!<E0!johL1eS8juXSr4VX8i7EX8i7tX8i7`XSr4bXT&:hX8i7VX8i7YX8i7jX8i7`XT&:_X8i7G
-XT._fec1:%s7Y"CKE(rUeYN6-k.LbF~>
-!<E0!johC3g4=hSgAV*/g&M,sg&M-Mg&M-9gAV*;gA_0Ag&M-/g&M-2g&M-Cg&M-9gA_08g&M,u
-gAh3PgAca(s7Y1HJcG`Sg7eQ/k.1PC~>
-!<E0!johL1eVf@bk5GA;jo>D*jo>DYjo>DEk5GAGk5PGMjo>D;jo>D>jo>DOjo>DEk5PGDjo>D,
-k5YJ\ec1:%s7Y"CKE(rUeYN6-k.LbF~>
-!<E0!johL1eS8jsX8i6oX8i7^X8i7bX8i7hX8i7VX8i7YX8i7jX8i7_X8i7_X8i7GXT._fec1:%
-s7Y"CKE(rUeYN6-k.LbF~>
-!<E0!johC3g4=hQg&M,Hg&M-7g&M-;g&M-Ag&M-/g&M-2g&M-Cg&M-8g&M-8g&M,ugAh3PgAca(
-s7Y1HJcG`Sg7eQ/k.1PC~>
-!<E0!johL1eVf@`jo>CTjo>DCjo>DGjo>DMjo>D;jo>D>jo>DOjo>DDjo>DDjo>D,k5YJ\ec1:%
-s7Y"CKE(rUeYN6-k.LbF~>
-!<E0!johL1eS8jtX9&C'!;iks!!0/$riH)!"fq\(X8i8"XT&;!XSr4tXT&;#XT&:uXSr4mXSr5!
-XSr2(X8i7%X8i8!XSr4tXS`(qXSr4iX8i7tXSi.rXSr2#X8r7$!W]='rW)YnqZ-Srr;cetrrE)#
-rrDVk!!)u!rr<8)!!')#!3H/"s/c2"p8n/lr2fhsrN$#"XSr4bX9&C'XSr4uXSr5!XSr5"XSr4u
-X8i7GXT._fec1:%s7Y"CKE(rUeYN6-k.LbF~>
-!<E0!johC3g4=hRg&_9.!;kLL!!1dRrn@>O"kiqVg&M-PgA_0OgAV*MgA_0QgA_0NgAV*FgAV*O
-gAV'Vg&M-,g&M-OgAV*MgACsJgAV*Bg&M-MgAM$KgAV'Qg&V-+!W^s.rW)ZGqZ-TKr;cfMrrE)Q
-rrDWD!!)uOrr<8W!!(^Q!8@DPs4[GPp=fEEr7_)LrRq8PgAV*;g&_9.gAV*NgAV*OgAV*PgAV*N
-g&M,ugAh3PgAca(s7Y1HJcG`Sg7eQ/k.1PC~>
-!<E0!johL1eVf@ajoPPF!;kpX!!23^roX1["m,dbjo>D\k5PG[k5GAYk5PG]k5PGZk5GARk5GA[
-k5G>bjo>DDjo>D[k5GAYk555Vk5GANjo>DYk5>;Wk5G>]joGDC!W_BFrW)ZSqZ-TWr;cfYrrE)]
-rrDWP!!)u[rr<8c!!)-]!9X7\s5s:\p?)8Qr9!qXrT4+\k5GAGjoPPFk5GAZk5GA[k5GA\k5GAZ
-jo>D,k5YJ\ec1:%s7Y"CKE(rUeYN6-k.LbF~>
-!<E0!johL1eS8jtX9&C'!;rnu!<0)"!<9,#!<0)"!<0&"!<&u!!;iht!;ii$!3?1%X8r7$!!*#"
-!!)\n!!)qu!!*#""TYV(XK2F"X8i7tX8i7rX8i8"X8i7kX8i7uX8i8!X8i8!X8i8"XT&;"X9/I(
-X8qgm!!)nt!!)u!!!)u!"TYV(XK2EnX8i7uXT&8*X8i7%!3E7%rN#u!oW/#mqQ'YsrN#u!riH,"
-ri?)"l`:0gXK2F"X8i8"X8i8"X8i8!X8i7uX8i7GXT._fec1:%s7Y"CKE(rUeYN6-k.LbF~>
-!<E0!johC3g4=hRg&_9.!;tON!<1^P!<:aQ!<1^P!<1[P!<(UO!;kIM!;kIR!87G,g&V-+!!*#P
-!!)]G!!)rN!!*#P"T[6Vg=cQ)g&M-Mg&M-Kg&M-Pg&M-Dg&M-Ng&M-Og&M-Og&M-PgA_0Pg&h?/
-g&U]t!!)oM!!)uO!!)uO"T[6Vg=cPug&M-NgA_-Xg&M-,!8?-,rRq5Oo\'9FqUtoLrRq5Orn@AP
-rn7>Ple2F@g=cQ)g&M-Pg&M-Pg&M-Og&M-Ng&M,ugAh3PgAca(s7Y1HJcG`Sg7eQ/k.1PC~>
-!<E0!johL1eVf@ajoPPF!;tsZ!<2-\!<;0]!<2-\!<2*\!<)$[!;kmY!;km^!9O:DjoGDC!!*#\
-!!)]S!!)rZ!!*#\"T[Zbk2l[Ajo>DYjo>DWjo>D\jo>DPjo>DZjo>D[jo>D[jo>D\k5PG\joYVG
-joFu7!!)oY!!)u[!!)u["T[Zbk2l[8jo>DZk5PDdjo>DD!9WDDrT4([o]?,RqW7bXrT4([roX4\
-roO1\lfJ9Lk2l[Ajo>D\jo>D\jo>D[jo>DZjo>D,k5YJ\ec1:%s7Y"CKE(rUeYN6-k.LbF~>
-!<E0!johL1eS8juX8i8"X8i8"X8i7uX9&C'!;rnu!<0&"!<&u!!;iht!;ikt!;iht!;rnu!;<Ju
-!3E7%XK2F$XT&:qX8i7tX8i7sX8i7uX8i7lX8i8!X8i7tX9/I(X8r1"!!*#"!W];%nZ2]jr2]ku
-qlBbtriH,"n>lTiqlC)(XK2E'X8o?'!<&u!!;*>m!;3Dn!<0&"!;rnu!:6cg!3?1uX8i7uX9/I(
-X8r4#!!)nt!!(?Hs6fm:s+C@Op=91qs8N;RV#TT>]`<Q~>
-!<E0!johC3g4=hSg&M-Pg&M-Pg&M-Ng&_9.!;tON!<1[P!<(UO!;kIM!;kLM!;kIM!;tON!;>+N
-!8?-,g=cQ+gA_0Jg&M-Mg&M-Lg&M-Ng&M-Eg&M-Og&M-Mg&h?/g&V')!!*#P!W^pSn_*sCr7V,N
-qq;#Mrn@APnCdjBqq;>Vg=cP\g&Tj\!<(UO!;+tF!;5%G!<1[P!;tON!:8D@!87GNg&M-Ng&h?/
-g&V**!!)oM!!(@!s8W)Ps+14Mp=fOts8N;WU&X9;\c@6~>
-!<E0!johL1eVf@bjo>D\jo>D\jo>DZjoPPF!;tsZ!<2*\!<)$[!;kmY!;kpY!;kmY!;tsZ!;>OZ
-!9WDDk2l[Ck5PGVjo>DYjo>DXjo>DZjo>DQjo>D[jo>DYjoYVGjoG>A!!*#\!W_?_n`BfOr8mtZ
-qrRkYroX4\nE']NqrS1bk2l[+joFQ+!<)$[!;,CR!;5IS!<2*\!;tsZ!:8hL!9O:Zjo>DZjoYVG
-joGAB!!)oY!!(@-s8W)Ks+C@Op=91qs8N;RV#TT>]`<Q~>
-!<E0!johL1eS8juXS`(tX8i7sX8i7uX8i8"X8i8!X8i7tX8i7tX8i7sXSMqjX9J[+X8o?'!<0&"
-!;EPp!;iht!;`en!;!8l!<&u!!;ii"!3E7%poOJqn>lTir2]kuqlBbtri?)"m]6Bgr2^)&XK2E'
-X8r7$!s#F(!;!8l!;W_o!<0&"!;rnu!:6fe!;iko!<0&%!3E7%qlBbtcE.'6rmh%$s8VfCs+C@O
-#1]OLk2s>WJ,~>
-!<E0!johC3g4=hSgACsMg&M-Lg&M-Ng&M-Pg&M-Og&M-Mg&M-Mg&M-LgA1gCg'.Q2g&Tj\!<1[P
-!;G1I!;kIM!;bFG!;"nE!<(UO!;kIP!8?-,ptG`JnCdjBr7V,Nqq;#Mrn7>Pmb.X@r7V>Tg=cP\
-g&V-+!s%'/!;"nE!;Y@H!<1[P!;tON!:8G>!;kLH!<1[S!8?-,qq;#McJ&<urn@C's8VfHs+14M
-#25dNk2s5TJ,~>
-!<E0!johL1eVf@bk555Yjo>DXjo>DZjo>D\jo>D[jo>DYjo>DYjo>DXk5#)OjothJjoFQ+!<2*\
-!;GUU!;kmY!;bjS!;#=Q!<)$[!;km\!9WDDpu_SVnE']Nr8mtZqrRkYroO1\mcFKLr8n1`k2l[+
-joGDC!s%KG!;#=Q!;YdT!<2*\!;tsZ!:8kJ!;kpT!<2*_!9WDDqrRkYcK>0,rmh%$s8VfCs+C@O
-#1]OLk2s>WJ,~>
-!<E0!jp.^4eS8j#X8r1"!s#F(!;`bs!;rnu!<0&"!<&u!!;iht!;iht!;`bs!:Qul!3?1%!<&u!
-!;EPp!;iht!;`bs!:?if!<&u!!;ii"!3E7%poFMsX8qdl!!)qu!!)nt!!*#"!!)Gg!!)qu"ota+
-!3E7%ri?2%XK2EnX8i7sX8i8!X8i8"X8i7uX8i7eX9&C'!;rnu!;NVt!3E7%qlBbtcE.'6rmh%$
-s8VfCs+C@O#1]OLk2s>WJ,~>
-!<E0!jp.U6g4=h/g&V')!s%'/!;bCL!;tON!<1[P!<(UO!;kIM!;kIM!;bCL!:SVE!87G,!<(UO
-!;G1I!;kIM!;bCL!:AJ?!<(UO!;kIP!8?-,pt>cLg&UZs!!)rN!!)oM!!*#P!!)H@!!)rN"p!B2
-!8?-,rn7GSg=cPug&M-Lg&M-Og&M-Pg&M-Ng&M->g&_9.!;tON!;P7M!8?-,qq;#McJ&<urn@C'
-s8VfHs+14M#25dNk2s5TJ,~>
-!<E0!jp.^4eVf@JjoG>A!s%KG!;bgX!;tsZ!<2*\!<)$[!;kmY!;kmY!;bgX!:T%Q!9O:D!<)$[
-!;GUU!;kmY!;bgX!:AnK!<)$[!;km\!9WDDpuVVXjoFr6!!)rZ!!)oY!!*#\!!)HL!!)rZ"p!fJ
-!9WDDroO:_k2l[8jo>DXjo>D[jo>D\jo>DZjo>DJjoPPF!;tsZ!;P[Y!9WDDqrRkYcK>0,rmh%$
-s8VfCs+C@O#1]OLk2s>WJ,~>
-!<E0!jp.^4eS8j#X8r1"!!*#"!!)u!!s#F(!<0)"!<0&"!<0)"!;iht!;iht!;W\r!<&u!!;3Gn
-!!95%!<&u!!;EPp!;iht!<0&"!<&u!!<&u!!;!8l!;rnu!<&u!!<&u!!<&u!!<0&%!3E7%nuMfk
-qlBbtrN#u!rN#u!m]6Bgr2^)&XK2E'X8r4#rrDVk!!*#"!!*#"!!*#"rrE&"rrE&"!!)qurrDVk
-!s#F(!;rnu!<&u!!<'#!!;`bs!7%\Gmf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!jp.U6g4=h/g&V')!!*#P!!)uO!s%'/!<1^P!<1[P!<1^P!;kIM!;kIM!;Y=K!<(UO!;5(G
-!!:jS!<(UO!;G1I!;kIM!<1[P!<(UO!<(UO!;"nE!;tON!<(UO!<(UO!<(UO!<1[S!8?-,o%F'D
-qq;#MrRq5OrRq5Omb.X@r7V>Tg=cP\g&V**rrDWD!!*#P!!*#P!!*#PrrE&PrrE&P!!)rNrrDWD
-!s%'/!;tON!<(UO!<(XO!;bCL!7'<us8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!jp.^4eVf@JjoG>A!!*#\!!)u[!s%KG!<2-\!<2*\!<2-\!;kmY!;kmY!;YaW!<)$[!;5LS
-!!;9_!<)$[!;GUU!;kmY!<2*\!<)$[!<)$[!;#=Q!;tsZ!<)$[!<)$[!<)$[!<2*_!9WDDo&]oP
-qrRkYrT4([rT4([mcFKLr8n1`k2l[+joGABrrDWP!!*#\!!*#\!!*#\rrE&\rrE&\!!)rZrrDWP
-!s%KG!;tsZ!<)$[!<)'[!;bgX!7'a,s8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!joqR2eS8j#r;Zi!r;chur;cetrVuu#!<'"u!!95%!<0(t!<0(u!;`eq!;*Am!!95%!<0(u
-!;ikq!;rqt!;ikr!;*Aj!<'"t!;ikr!<0)"!<9/"!;<Ml!;rqs!<'"t!:[&i!<'"u!!TG(!3?/#
-rN#u!nZ;]ir2fkt#-7e)X8i7%rW)hsrrDYlrrE)#rW)nur;c_r!!)ks!!(<Gs6fm:s+C@Op=91q
-s8N;RV#TT>]`<Q~>
-!<E0!joqI4g4=h/r;ZiOr;ciNr;cfMrVuuQ!<(XN!!:jS!<1^M!<1^N!;bFJ!;,"F!!:jS!<1^N
-!;kLJ!;tRM!;kLK!;,"C!<(XM!;kLK!<1^P!<:dP!;>.E!;tRL!<(XM!:\\B!<(XN!!V'V!87DQ
-rRq5On_3sBr7_,M#20%Wg&M-,rW)iLrrDZErrE)QrW)oNr;c`K!!)lL!!(<us8W)Ps+14Mp=fOt
-s8N;WU&X9;\c@6~>
-!<E0!joqR2eVf@Jr;Zi[r;ciZr;cfYrVuu]!<)'Z!!;9_!<2-Y!<2-Z!;bjV!;,FR!!;9_!<2-Z
-!;kpV!;u!Y!;kpW!;,FO!<)'Y!;kpW!<2-\!<;3\!;>RQ!;u!X!<)'Y!:]+N!<)'Z!!VKb!9O7]
-rT4([n`KfNr9!tY#3Gmcjo>DDrW)iXrrDZQrrE)]rW)oZr;c`W!!)lX!!(=,s8W)Ks+C@Op=91q
-s8N;RV#TT>]`<Q~>
-!<E0!johL1eS8j_X8i6OXN.CB!:d,j!7n7O!8adW!;W\r!7%\Gmf(c:KE(uFec1:%rs%#Ls5rIW
-!.Y~>
-!<E0!johC3g4=h=g&M,(g;hnI!:ebC!7om(!8cE0!;Y=K!7'<us8LaPJcGcDgAca(rs%2Ns5rIT
-!.Y~>
-!<E0!johL1eVf@Ljo>C4k/ZTa!:f1O!7p<4!8ci<!;YaW!7'a,s8LRKKE(uFec1:%rs%#Ls5rIW
-!.Y~>
-!<E0!johL1eS8j_X8i6OXN%=A!:m2k!7n4O!8X^V!;`bs!6qVFmf(c:KE(uFec1:%rs%#Ls5rIW
-!.Y~>
-!<E0!johC3g4=h=g&M,(g;_hH!:nhD!7oj(!8Z?/!;bCL!6s6ts8LaPJcGcDgAca(rs%2Ns5rIT
-!.Y~>
-!<E0!johL1eVf@Ljo>C4k/QN`!:o7P!7p94!8Zc;!;bgX!6s[+s8LRKKE(uFec1:%rs%#Ls5rIW
-!.Y~>
-!<E0!johL1eS8jaXSi-MXLYG2!<'"o!5Yc8!62,?mf(c:KE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=h?gAM#&g:>r9!<(XH!5[Cf!63ams8LaPJcGcDgAca(rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf@Nk5>:2k.0XQ!<)'T!5[gr!641$s8LRKKE(uFec1:%rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8iMXF[I5XT._fec1:%s7Y"CKE(rUeYN6-k.LbF~>
-!<E0!johC3g4=g+g4@t<gAh3PgAca(s7Y1HJcG`Sg7eQ/k.1PC~>
-!<E0!johL1eVf?:k(2ZTk5YJ\ec1:%s7Y"CKE(rUeYN6-k.LbF~>
-!<E0!johL1eS8iMXF[I5XT._fec1:%s7Y"CKE(rUeYN6-k.LbF~>
-!<E0!johC3g4=g+g4@t<gAh3PgAca(s7Y1HJcG`Sg7eQ/k.1PC~>
-!<E0!johL1eVf?:k(2ZTk5YJ\ec1:%s7Y"CKE(rUeYN6-k.LbF~>
-!<E0!johL1eS8iMXF[I5XT._fec1:%s7Y"CKE(rUeYN6-k.LbF~>
-!<E0!johC3g4=g+g4@t<gAh3PgAca(s7Y1HJcG`Sg7eQ/k.1PC~>
-!<E0!johL1eVf?:k(2ZTk5YJ\ec1:%s7Y"CKE(rUeYN6-k.LbF~>
-!<E0!johL1eS8iMXF[I5XT._fec1:%s7CsDrs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g4@t<gAh3PgAca(s7CmBrs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k(2ZTk5YJ\ec1:%s7CsDrs%#Ls5rIW!.Y~>
-!<E0!johL1eS8iMXF[I5XT._fec17%s7:mCrs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g4@t<gAh3PgAc^(s7:gArs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k(2ZTk5YJ\ec17%s7:mCrs%#Ls5rIW!.Y~>
-!<E0!johL1eS8iMXF[I5XT._fec19m^&S*:eYN6-k.LbF~>
-!<E0!johC3g4=g+g4@t<gAh3PgAc`p_Z0W?g7eQ/k.1PC~>
-!<E0!johL1eVf?:k(2ZTk5YJ\ec19m^&S*:eYN6-k.LbF~>
-!<E0!johL1eS8iMXF[I5XT._fec19krs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g4@t<gAh3PgAc`nrs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k(2ZTk5YJ\ec19krs%#Ls5rIW!.Y~>
-!<E0!johL1eS8iMXF[I5XT._fec17%^%D=2KE(u%V#TT>]`<Q~>
-!<E0!johC3g4=g+g4@t<gAh3PgAc^(_Y!j7JcGc(U&X9;\c@6~>
-!<E0!johL1eVf?:k(2ZTk5YJ\ec17%^%D=2KE(u%V#TT>]`<Q~>
-!<E0!johL1eS8iMXF[I5XT._fec17'^&S--ec17.^&S,_V#TT>]`<Q~>
-!<E0!johC3g4=g+g4@t<gAh3PgAc^*_Z0Z2gAc^1_Z0YiU&X9;\c@6~>
-!<E0!johL1eVf?:k(2ZTk5YJ\ec17'^&S--ec17.^&S,_V#TT>]`<Q~>
-!<E0!johL1eS8iMXF[I5XT._fec1:%^&S-.ec17.^&S,_V#TT>]`<Q~>
-!<E0!johC3g4=g+g4@t<gAh3PgAca(_Z0Z3gAc^1_Z0YiU&X9;\c@6~>
-!<E0!johL1eVf?:k(2ZTk5YJ\ec1:%^&S-.ec17.^&S,_V#TT>]`<Q~>
-!<E0!johL1eS8iMXF[I5XT._fec1:%^&S-/ec1:%^&S*:eYN6-k.LbF~>
-!<E0!johC3g4=g+g4@t<gAh3PgAca(_Z0Z4gAca(_Z0W?g7eQ/k.1PC~>
-!<E0!johL1eVf?:k(2ZTk5YJ\ec1:%^&S-/ec1:%^&S*:eYN6-k.LbF~>
-!<E0!johL1eS8iMXF[I5XT._fec1:$^&S-0ec1:%^&S*:eYN6-k.LbF~>
-!<E0!johC3g4=g+g4@t<gAh3PgAca'_Z0Z5gAca(_Z0W?g7eQ/k.1PC~>
-!<E0!johL1eVf?:k(2ZTk5YJ\ec1:$^&S-0ec1:%^&S*:eYN6-k.LbF~>
-!<E0!johL1eS8iMXF[I5XT._fec1:$^&S-1ec1:$^&S*:eYN6-k.LbF~>
-!<E0!johC3g4=g+g4@t<gAh3PgAca'_Z0Z6gAca'_Z0W?g7eQ/k.1PC~>
-!<E0!johL1eVf?:k(2ZTk5YJ\ec1:$^&S-1ec1:$^&S*:eYN6-k.LbF~>
-!<E0!johL1eS8iMXF[I5XT._fec1:#^&S-2ec1:$^&S*:eYN6-k.LbF~>
-!<E0!johC3g4=g+g4@t<gAh3PgAca&_Z0Z7gAca'_Z0W?g7eQ/k.1PC~>
-!<E0!johL1eVf?:k(2ZTk5YJ\ec1:#^&S-2ec1:$^&S*:eYN6-k.LbF~>
-!<E0!johL1eS8iMXF[I5XT._fec1:#^&S-3ec1:#^&S*:eYN6-k.LbF~>
-!<E0!johC3g4=g+g4@t<gAh3PgAca&_Z0Z8gAca&_Z0W?g7eQ/k.1PC~>
-!<E0!johL1eVf?:k(2ZTk5YJ\ec1:#^&S-3ec1:#^&S*:eYN6-k.LbF~>
-!<E0!johL1eS8iMXF[I5XT._fec1:"^&S-4ec1:#^&S*:eYN6-k.LbF~>
-!<E0!johC3g4=g+g4@t<gAh3PgAca%_Z0Z9gAca&_Z0W?g7eQ/k.1PC~>
-!<E0!johL1eVf?:k(2ZTk5YJ\ec1:"^&S-4ec1:#^&S*:eYN6-k.LbF~>
-!<E0!johL1eS8iMXF[I5XT._fec1:"^&S*6eUrMP^&S*:eYN6-k.LbF~>
-!<E0!johC3g4=g+g4@t<gAh3PgAca%_Z0W;g4=hQ_Z0W?g7eQ/k.1PC~>
-!<E0!johL1eVf?:k(2ZTk5YJ\ec1:"^&S*6eUrMP^&S*:eYN6-k.LbF~>
-!<E0!johL1eS8iMXF[I5XT._fec1:!]`A*3KD`F_rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g4@t<gAh3PgAca$_>sW8Jc*Cbrs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k(2ZTk5YJ\ec1:!]`A*3KD`F_rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8iMXF[I5XT._fec1:!]`S4dKDW@^rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+g4@t<gAh3PgAca$_?0agJc!=ars%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:k(2ZTk5YJ\ec1:!]`S4dKDW@^rs%#Ls5rIW!.Y~>
-!<E0!johL1eS8iMXF[I5XT._fec19u^&N`^^&S*:eYN6-k.LbF~>
-!<E0!johC3g4=g+g4@t<gAh3PgAca#_Z,2a_Z0W?g7eQ/k.1PC~>
-!<E0!johL1eVf?:k(2ZTk5YJ\ec19u^&N`^^&S*:eYN6-k.LbF~>
-!<E0!johL1eS8iMmXaebmf(c:KDN7]KDN:]rs%#Ls5rIW!.Y~>
-!<E0!johC3g4=g+s+13/s8LaPJbm4`Jbm7`rs%2Ns5rIT!.Y~>
-!<E0!johL1eVf?:s+13/s8LRKKDN7]KDN:]rs%#Ls5rIW!.Y~>
-!<E0!jo_F0eS9['JaSHarmh%$nG`^CV#TT>]`<Q~>
-!<E0!jo_=2g4=hTJcCZ.rn@C'nG`^HU&X9;\c@6~>
-!<E0!jo_F0eVf"YJcCZ.rmh%$nG`^CV#TT>]`<Q~>
-!<E0!joD3.eUc8)eGt6jrs%#Ls5rIW!.Y~>
-!<E0!joD*+g4@t3g&Q]mrs%2Ns5rIT!.Y~>
-!<E0!joD3.eUc8)eGt6jrs%#Ls5rIW!.Y~>
-!<E0!joD3.eUc8%ea_/nV#TT>]`<Q~>
-!<E0!joD*+g4@t/g@<l#U&X9;\c@6~>
-!<E0!joD3.eUc8%ea_/nV#TT>]`<Q~>
-!<E0!joD3.eUc8%ea_/nV#TT>]`<Q~>
-!<E0!joD*+g4@t/g@<l#U&X9;\c@6~>
-!<E0!joD3.eUc8%ea_/nV#TT>]`<Q~>
-!<E0!joM:.JV/N+LkG$D"f21\k.LbF~>
-!<E0!joM10JUrB'Lk4mG"ektYk.1PC~>
-!<E0!joM:.JV/N+LkG$D"f21\k.LbF~>
-!<E0!joM:.JV/N+M1Yg.ldZ07s5rIW!.Y~>
-!<E0!joM10JUrB'M1G[,le2N9s5rIT!.Y~>
-!<E0!joM:.JV/N+M1Yg.ldZ07s5rIW!.Y~>
-!<E0!jo_F0K7id/!WTias+13OrrTn6s7F#)s6J2=V#TT>]`<Q~>
-!<E0!jo_=2JV!F0!WU#fs+13OrrU(;s7F2.s6JABU&X9;\c@6~>
-!<E0!jo_F0K7id/!WTias+13OrrTn6s7F#)s6J2=V#TT>]`<Q~>
-!<E0!jo_F0K7ij1s8N+P]n-37s/l;%K>%6`p:^M+ldZ07s5rIW!.Y~>
-!<E0!jo_=2JV!L2s8N+N_L_`<s/l;%J\qBcp;6k0le2N9s5rIT!.Y~>
-!<E0!jo_F0K7ij1s8N+P]n-37s/l;%K>%6`p:^M+ldZ07s5rIW!.Y~>
-!<?U-5m#ShKD3(Ys8R]Q^&S+`eUc8Tec17%^&.j)^&S,ueHJ6J5sYJNJ,~>
-!<@-<9ENq!JbR%\s8RWO_Z0Xeg4@t^gAc^(_YaB._Z0Z%g'(/i9M>EdJ,~>
-!<BM*PQKBfKD3(Ys8R]Q^&S+`eUc8Tec17%^&.j)^&S,ueHM2EP`u.JJ,~>
-!!)tU"$tIiKDE4Zrrpr*K>%<bJ^o>%Ygrc+"MOj8e^aWuqRuq/ldZ/)Mdg-]!.Y~>
-!!)t_"&.F"Jbd1]rrq,-J\qHeJ_G\/YhK,."N(3=g=lN*qSN:4le2M9Q#Ue;!.Y~>
-!!)u:"-h>gKDE4Zrrpr*K>%<bJ^o>%Ygrc+"MOj8e^aWuqRuq/ldZ0'`O*":!.Y~>
-!<A&W@KSpHK7j'7rVulIs+:Bds8RZ#J^q!Ts+:Bds8W&JrVuf/s8VE8"[S&U@R1!E~>
-!<ADaE<AngJV!^8rVulNs+(6gs8RZ(J_I?^s+(6gs8W&OrVuf4s8VE="\b2$ED-@_~>
-!<C+<ZicQCK7j'7rVulIs+:Bds8RZ#J^q!Ts+:Bds8W&JrVuf/s8VE8"dI!5[$1Q@~>
-!<A&W@KSpHK7j-9rVufGs+:Bds8RZ#J^q!Ts+:Bds8VuHrVul1s8VE8"[S&U@R1!E~>
-!<ADaE<AngJV!d:rVufLs+(6gs8RZ(J_I?^s+(6gs8VuMrVul6s8VE="\b2$ED-@_~>
-!<C+<ZicQCK7j-9rVufGs+:Bds8RZ#J^q!Ts+:Bds8VuHrVul1s8VE8"dI!5[$1Q@~>
-!<A&W@Kf'JK7gkNrVu`Es+:Bds8RZ#J^q!Ts+:Bds8VoFrVlr4s8VE8"[S&U@R1!E~>
-!<ADaE<T%iJUt\TrVu`Js+(6gs8RZ(J_I?^s+(6gs8VoKrVlr9s8VE="\b2$ED-@_~>
-!<C+<Ziu]EK7gkNrVu`Es+:Bds8RZ#J^q!Ts+:Bds8VoFrVlr4s8VE8"dI!5[$1Q@~>
-!<A&W@KAdFqh+[os+:Bds8RZ#J^q!Ts+:Bds8VlErIb.MldZ/)Mdg-]!.Y~>
-!<ADaE</beqgnOrs+(6gs8RZ(J_I?^s+(6gs8VlJrIP"Kle2M9Q#Ue;!.Y~>
-!<C+<ZiQEAqh+[os+:Bds8RZ#J^q!Ts+:Bds8VlErIb.MldZ0'`O*":!.Y~>
-!<A&W@Kf'JK7gkNrIasss+:Bds8RZ#J^q!Ts+:Bds8VoFrIY0bs8VE8"[S&U@R1!E~>
-!<ADaE<T%iJUt\TrIOh!s+(6gs8RZ(J_I?^s+(6gs8VoKrIG$es8VE="\b2$ED-@_~>
-!<C+<Ziu]EK7gkNrIasss+:Bds8RZ#J^q!Ts+:Bds8VoFrIY0bs8VE8"dI!5[$1Q@~>
-!<A&W@KSpHK7j-9rIb$us+:Bds8RZ#J^q!Ts+:Bds8VuHrIb*_s8VE8"[S&U@R1!E~>
-!<ADaE<AngJV!d:rIOn#s+(6gs8RZ(J_I?^s+(6gs8VuMrIOsbs8VE="\b2$ED-@_~>
-!<C+<ZicQCK7j-9rIb$us+:Bds8RZ#J^q!Ts+:Bds8VuHrIb*_s8VE8"dI!5[$1Q@~>
-!<A&W@KSpHK7j'7rIb+"s+:Bds8RZ#J^q!Ts+:Bds8W&JrIb$]s8VE8"[S&U@R1!E~>
-!<ADaE<AngJV!^8rIOt%s+(6gs8RZ(J_I?^s+(6gs8W&OrIOm`s8VE="\b2$ED-@_~>
-!<C+<ZicQCK7j'7rIb+"s+:Bds8RZ#J^q!Ts+:Bds8W&JrIb$]s8VE8"dI!5[$1Q@~>
-!<A&W@KSpHK7j!5rIY:(K7gl;s+/^OeZdU(K*8mfs4,ZuKDN:]s6J2=6&T2]5lcE~>
-!<ADaE<AngJV!X6rIG.+JUt]<s+/mTg9B<2JHWjis4Z3*Jbm7`s6JAB9U0U;9E9S~>
-!<C+<ZicQCK7j!5rIY:(K7gl;s+/^OeZdU(K*8mfs4,ZuKDN:]s6J2=Pf:#:PQ64~>
-!<A&W@KSpHK7ip3r.>'as8RZ#J^q!Ts+:Bds8W%Mpq?_-ldZ/)Mdg-]!.Y~>
-!<ADaE<AngJV!R4r.+pds8RZ(J_I?^s+(6gs8W%Kpqm(2le2M9Q#Ue;!.Y~>
-!<C+<ZicQCK7ip3r.>'as8RZ#J^q!Ts+:Bds8W%Mpq?_-ldZ0'`O*":!.Y~>
-!<A&W@KSpHK7ij1rdt9cs8RY&JV1+X"MOj8K7im2s8VE8"[S&U@R1!E~>
-!<ADaE<AngJV!L2rdb-fs8RY$JUstT"N(3=JV!O3s8VE="\b2$ED-@_~>
-!<C+<ZicQCK7ij1rdt9cs8RY&JV1+X"MOj8K7im2s8VE8"dI!5[$1Q@~>
-!<A&W@KSpHK7id/!e\2dJV/N+Xb-\gs+BsWs8VE8"[S&U@R1!E~>
-!<ADaE<AngJV!F0!eJ5gJUrB'XapPjs+0gZs8VE="\b2$ED-@_~>
-!<C+<ZicQCK7id/!e\2dJV/N+Xb-\gs+BsWs8VE8"dI!5[$1Q@~>
-!<A&W@KSpHK7eaTJcCW-ldZ/)Mdg-]!.Y~>
-!<ADaE<AngJUrCPJcCW-le2M9Q#Ue;!.Y~>
-!<C+<ZicQCK7eaTJcCW-ldZ0'`O*":!.Y~>
-!<A&W@KJjGK7X&Rs,$dAeHJ6s@U_V'J,~>
-!<ADaE<8hfJV!iPs,$dAg'(08EH+YPJ,~>
-!<C+<ZiZKBK7X&Rs,$dAeHM2V['Z%tJ,~>
-!<A&W@K8]FeUc8%ea_/n6&T2]5lcE~>
-!<ADaE<&[`g4@t/g@<l#9U0U;9E9S~>
-!<C+<ZiH>AeUc8%ea_/nPf:#:PQ64~>
-!<A&V@dua8Uk,>(U]=lp5lciB@KAapJ,~>
-!<AD`EUc_RTn/o"T`B*'9E:@WE</`5J,~>
-!<C+;[.0B3Uk,>(U]@dmPQ8]%ZiQBkJ,~>
-!\j\5rF5AV!+LNZJcCl4nVdBU!^Qh:J,~>
-!^m$RrGhFo!-*SiJcCl4nWj)n!_`UJJ,~>
-!cn@\rNu18!47=WJcCl4n\tL7!gE]8J,~>
-!]^7=mpZ8_J`_OGOlcY%mpZ>a!7cT~>
-!^m$Rmr8>$J`_OGOlcY/mr8D&!8;r~>
-!cn@\n$E(ZJ`_OGOlcY_n$E.\!7cT~>
-">Mn:5sb$M!'u1uJ``*W!/pAVs$6\de^]0~>
-s$Qng9MFtr!).t+J``*W!1!(os%EIog=h&~>
-s)S5APa(^F!0i&sJ``*W!6+K8s-*Qbe^]0~>
-r]0uYn3MW=J\@2Z!+PIarrE&KJ,~>
-r^?bdn4\DEJ\$uT!-.O&rrE&PJ,~>
-rcA)>n<AL;J\@2Z!4;9\rrE&KJ,~>
-">Mnk3B;WjJH16$mf3C=s8LQ!~>
-r'Z)9JH16$mf3CB!<1]&~>
-"DW!mF)um4JH16$mf3C=!<1N!~>
-%%EndData
-showpage
-%%Trailer
-end
-%%EOF
diff --git a/lib/et/doc/src/user_guide.gif b/lib/et/doc/src/user_guide.gif
deleted file mode 100644
index e6275a803d..0000000000
--- a/lib/et/doc/src/user_guide.gif
+++ /dev/null
Binary files differ
diff --git a/lib/et/doc/src/warning.gif b/lib/et/doc/src/warning.gif
deleted file mode 100644
index 96af52360e..0000000000
--- a/lib/et/doc/src/warning.gif
+++ /dev/null
Binary files differ
diff --git a/lib/et/examples/Makefile b/lib/et/examples/Makefile
index 553fe55f3b..67a6536fdf 100644
--- a/lib/et/examples/Makefile
+++ b/lib/et/examples/Makefile
@@ -1,19 +1,19 @@
#
# %CopyrightBegin%
-#
-# Copyright Ericsson AB 2002-2009. All Rights Reserved.
-#
+#
+# Copyright Ericsson AB 2002-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%
#
@@ -38,7 +38,9 @@ RELSYSDIR = $(RELEASE_PATH)/lib/et-$(VSN)
MODULES = \
- et_demo
+ et_demo \
+ et_display_demo \
+ et_trace_demo
ERL_FILES= $(MODULES:=.erl)
diff --git a/lib/et/examples/et_demo.erl b/lib/et/examples/et_demo.erl
index 57e7e77246..e439e6882c 100644
--- a/lib/et/examples/et_demo.erl
+++ b/lib/et/examples/et_demo.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2002-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 2002-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%
%%
%%----------------------------------------------------------------------
@@ -23,24 +23,29 @@
-module(et_demo).
-export([
- sim_trans/0,
+ sim_trans/0, sim_trans/1,
+ live_trans/0, live_trans/1,
mgr_actors/1,
- live_trans/0,
- start/0,
- start/1,
+ start/0, start/1,
filters/0,
trace_mnesia/0
]).
+%% Test
+-export([s/0, t/0, t/1, init/0, gen/3]).
+
-include_lib("et/include/et.hrl").
%%----------------------------------------------------------------------
%sim_trans
sim_trans() ->
+ sim_trans([]).
+
+sim_trans(ExtraOptions) ->
Options = [{dict_insert, {filter, mgr_actors}, fun mgr_actors/1}],
- {ok, Viewer} = et_viewer:start_link(Options),
- Collector = et_viewer:get_collector_pid(Viewer),
+ {ok, Viewer} = et_viewer:start_link(Options ++ ExtraOptions),
+ Collector = et_viewer:get_collector_pid(Viewer),
et_collector:report_event(Collector, 60, my_shell, mnesia_tm, start_outer,
"Start outer transaction"),
et_collector:report_event(Collector, 40, mnesia_tm, my_shell, new_tid,
@@ -56,11 +61,13 @@ sim_trans() ->
et_collector:report_event(Collector, 60, my_shell, mnesia_tm, delete_transaction,
"End of outer transaction"),
et_collector:report_event(Collector, 20, my_shell, end_outer,
- "Transaction returned {atomic, ok}").
+ "Transaction returned {atomic, ok}"),
+ {collector, Collector}.
+
%sim_trans
%mgr_actors
-mgr_actors(E) when record(E, event) ->
+mgr_actors(E) when is_record(E, event) ->
Actor = fun(A) ->
case A of
mnesia_tm -> trans_mgr;
@@ -94,9 +101,13 @@ start(ExtraOptions) ->
%live_trans
live_trans() ->
- et_demo:start([{title, "Mnesia tracer"},
- {hide_actions, true},
- {active_filter, named_process_info_nolink}]),
+ live_trans([]).
+
+live_trans(ExtraOptions) ->
+ Options = [{title, "Mnesia tracer"},
+ {hide_actions, true},
+ {active_filter, named_process_info_nolink}],
+ et_demo:start(Options ++ ExtraOptions),
mnesia:start(),
mnesia:create_table(my_tab, [{ram_copies, [node()]}]),
et_demo:trace_mnesia(),
@@ -146,7 +157,7 @@ filters() ->
%filters
%module_as_actor
-module_as_actor(E) when record(E, event) ->
+module_as_actor(E) when is_record(E, event) ->
case lists:keysearch(mfa, 1, E#event.contents) of
{value, {mfa, {M, F, _A}}} ->
case lists:keysearch(pam_result, 1, E#event.contents) of
@@ -163,7 +174,7 @@ module_as_actor(E) when record(E, event) ->
%%----------------------------------------------------------------------
%plain_process_info
-plain_process_info(E) when record(E, event) ->
+plain_process_info(E) when is_record(E, event) ->
case E#event.label of
send -> true;
send_to_non_existing_process -> true;
@@ -182,7 +193,7 @@ plain_process_info(E) when record(E, event) ->
%plain_process_info
%plain_process_info_nolink
-plain_process_info_nolink(E) when record(E, event) ->
+plain_process_info_nolink(E) when is_record(E, event) ->
(E#event.label /= link) and
(E#event.label /= unlink) and
(E#event.label /= getting_linked) and
@@ -191,7 +202,7 @@ plain_process_info_nolink(E) when record(E, event) ->
%%----------------------------------------------------------------------
-named_process_info(E) when record(E, event) ->
+named_process_info(E) when is_record(E, event) ->
case plain_process_info(E) of
true ->
{true, E#event{to = pid_to_name(E#event.to),
@@ -201,7 +212,7 @@ named_process_info(E) when record(E, event) ->
false
end.
-named_process_info_nolink(E) when record(E, event) ->
+named_process_info_nolink(E) when is_record(E, event) ->
case plain_process_info_nolink(E) of
true ->
{true, E#event{to = pid_to_name(E#event.to),
@@ -211,7 +222,7 @@ named_process_info_nolink(E) when record(E, event) ->
false
end.
-pid_to_name(Pid) when pid(Pid) ->
+pid_to_name(Pid) when is_pid(Pid) ->
case process_info(Pid, registered_name) of
{registered_name, Name} ->
Name;
@@ -225,7 +236,7 @@ pid_to_name(Other) ->
%%----------------------------------------------------------------------
-node_process_info(E) when record(E, event) ->
+node_process_info(E) when is_record(E, event) ->
case plain_process_info(E) of
true ->
{true, E#event{to = pid_to_node(E#event.to),
@@ -234,7 +245,7 @@ node_process_info(E) when record(E, event) ->
false ->
false
end.
-node_process_info_nolink(E) when record(E, event) ->
+node_process_info_nolink(E) when is_record(E, event) ->
case plain_process_info_nolink(E) of
true ->
{true, E#event{to = pid_to_node(E#event.to),
@@ -244,21 +255,21 @@ node_process_info_nolink(E) when record(E, event) ->
false
end.
-pid_to_node(Pid) when pid(Pid) ->
+pid_to_node(Pid) when is_pid(Pid) ->
node(Pid);
-pid_to_node(Name) when atom(Name) ->
+pid_to_node(Name) when is_atom(Name) ->
node();
-pid_to_node({_Name, Node}) when atom(Node) ->
+pid_to_node({_Name, Node}) when is_atom(Node) ->
Node.
%%----------------------------------------------------------------------
-application_as_actor(E) when record(E, event) ->
+application_as_actor(E) when is_record(E, event) ->
{true, E#event{to = pid_to_application(E#event.to),
from = pid_to_application(E#event.from),
label = msg_to_label(E)}}.
-pid_to_application(Pid) when pid(Pid) ->
+pid_to_application(Pid) when is_pid(Pid) ->
case application:get_application(Pid) of
{ok, Name} ->
Name;
@@ -268,7 +279,7 @@ pid_to_application(Pid) when pid(Pid) ->
%%----------------------------------------------------------------------
-msg_to_label(E) when record(E, event) ->
+msg_to_label(E) when is_record(E, event) ->
case lists:keysearch(msg, 1, E#event.contents) of
{value, {msg, Msg}} ->
mnesia_msg_to_label(Msg, E#event.label);
@@ -349,3 +360,35 @@ mnesia_msg_to_label(Msg, Label) ->
_ -> Label
end.
+%%----------------------------------------------------------------------
+
+s() ->
+ spawn(fun() -> t(), timer:sleep(infinity) end).
+
+t() ->
+ t(500).
+
+t(N) ->
+ Collector = init(),
+ gen(Collector, 1, N),
+ Collector.
+
+init() ->
+ EvenFilter =
+ fun(#event{label = Label}) ->
+ case catch (list_to_integer(Label) div 10) rem 2 of
+ 0 ->
+ false;
+ _ ->
+ true
+ end
+ end,
+ OddFilter = fun(E) -> not EvenFilter(E) end,
+ {ok, Viewer} = et_viewer:start_link([{dict_insert, {filter, odd_tens}, EvenFilter},
+ {dict_insert, {filter, even_tens}, OddFilter},
+ {active_filter, odd_tens}]),
+ et_viewer:get_collector_pid(Viewer).
+
+gen(Collector, From, To) ->
+ [et_collector:report_event(Collector, 20, from, to, integer_to_list(I), [I]) || I <- lists:seq(From, To)],
+ ok.
diff --git a/lib/et/examples/et_display_demo.erl b/lib/et/examples/et_display_demo.erl
new file mode 100644
index 0000000000..ebcbc2e816
--- /dev/null
+++ b/lib/et/examples/et_display_demo.erl
@@ -0,0 +1,32 @@
+%%
+%% %CopyrightBegin%
+%% %CopyrightEnd%
+%%
+
+%module
+-module(et_display_demo).
+
+-export([test/0]).
+
+test() ->
+ {ok, Viewer} = et_viewer:start([{title,"Coffee Order"}, {max_actors,10}]),
+ Drink = {drink,iced_chai_latte},
+ Size = {size,grande},
+ Milk = {milk,whole},
+ Flavor = {flavor,vanilla},
+ C = et_viewer:get_collector_pid(Viewer),
+ et_collector:report_event(C,99,customer,barrista1,place_order,[Drink,Size,Milk,Flavor]),
+ et_collector:report_event(C,80,barrista1,register,enter_order,[Drink,Size,Flavor]),
+ et_collector:report_event(C,80,register,barrista1,give_total,"$5"),
+ et_collector:report_event(C,80,barrista1,barrista1,get_cup,[Drink,Size]),
+ et_collector:report_event(C,80,barrista1,barrista2,give_cup,[]),
+ et_collector:report_event(C,90,barrista1,customer,request_money,"$5"),
+ et_collector:report_event(C,90,customer,barrista1,pay_money,"$5"),
+ et_collector:report_event(C,80,barrista2,barrista2,get_chai_mix,[]),
+ et_collector:report_event(C,80,barrista2,barrista2,add_flavor,[Flavor]),
+ et_collector:report_event(C,80,barrista2,barrista2,add_milk,[Milk]),
+ et_collector:report_event(C,80,barrista2,barrista2,add_ice,[]),
+ et_collector:report_event(C,80,barrista2,barrista2,swirl,[]),
+ et_collector:report_event(C,80,barrista2,customer,give_tasty_beverage,[Drink,Size]),
+ ok.
+%module
diff --git a/lib/et/examples/et_trace_demo.erl b/lib/et/examples/et_trace_demo.erl
new file mode 100644
index 0000000000..5c16d4b77c
--- /dev/null
+++ b/lib/et/examples/et_trace_demo.erl
@@ -0,0 +1,38 @@
+%%
+%% %CopyrightBegin%
+%% %CopyrightEnd%
+%%
+
+%module
+-module(et_trace_demo).
+
+-export([test/0]).
+
+test() ->
+ et_viewer:start([
+ {title,"Coffee Order"},
+ {trace_global,true},
+ {trace_pattern,{et,max}},
+ {max_actors,10}
+ ]),
+ %% dbg:p(all,call),
+ %% dbg:tpl(et, trace_me, 5, []),
+ Drink = {drink,iced_chai_latte},
+ Size = {size,grande},
+ Milk = {milk,whole},
+ Flavor = {flavor,vanilla},
+ et:trace_me(99,customer,barrista1,place_order,[Drink,Size,Milk,Flavor]),
+ et:trace_me(80,barrista1,register,enter_order,[Drink,Size,Flavor]),
+ et:trace_me(80,register,barrista1,give_total,"$5"),
+ et:trace_me(80,barrista1,barrista1,get_cup,[Drink,Size]),
+ et:trace_me(80,barrista1,barrista2,give_cup,[]),
+ et:trace_me(90,barrista1,customer,request_money,"$5"),
+ et:trace_me(90,customer,barrista1,pay_money,"$5"),
+ et:trace_me(80,barrista2,barrista2,get_chai_mix,[]),
+ et:trace_me(80,barrista2,barrista2,add_flavor,[Flavor]),
+ et:trace_me(80,barrista2,barrista2,add_milk,[Milk]),
+ et:trace_me(80,barrista2,barrista2,add_ice,[]),
+ et:trace_me(80,barrista2,barrista2,swirl,[]),
+ et:trace_me(80,barrista2,customer,give_tasty_beverage,[Drink,Size]),
+ ok.
+%module
diff --git a/lib/et/src/Makefile b/lib/et/src/Makefile
index c590852625..bb6632ee91 100644
--- a/lib/et/src/Makefile
+++ b/lib/et/src/Makefile
@@ -1,19 +1,19 @@
#
# %CopyrightBegin%
-#
-# Copyright Ericsson AB 2000-2009. All Rights Reserved.
-#
+#
+# Copyright Ericsson AB 2000-2010. All Rights Reserved.
+#
# The contents of this file are subject to the Erlang Public License,
# Version 1.1, (the "License"); you may not use this file except in
# compliance with the License. You should have received a copy of the
# Erlang Public License along with this software. If not, it can be
# retrieved online at http://www.erlang.org/.
-#
+#
# Software distributed under the License is distributed on an "AS IS"
# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
# the License for the specific language governing rights and limitations
# under the License.
-#
+#
# %CopyrightEnd%
#
@@ -127,9 +127,16 @@ $(EBIN)/et_selector.$(EMULATOR): et_selector.erl ../include/et.hrl
$(EBIN)/et_contents_viewer.$(EMULATOR): et_contents_viewer.erl ../include/et.hrl et_internal.hrl
+$(EBIN)/et_gs_contents_viewer.$(EMULATOR): et_gs_contents_viewer.erl ../include/et.hrl et_internal.hrl
+$(EBIN)/et_wx_contents_viewer.$(EMULATOR): et_wx_contents_viewer.erl ../include/et.hrl et_internal.hrl
+
$(EBIN)/et_collector.$(EMULATOR): et_collector.erl ../include/et.hrl et_internal.hrl
$(EBIN)/et_viewer.$(EMULATOR): et_viewer.erl ../include/et.hrl et_internal.hrl
+$(EBIN)/et_gs_viewer.$(EMULATOR): et_gs_viewer.erl ../include/et.hrl et_internal.hrl
+
+$(EBIN)/et_wx_viewer.$(EMULATOR): et_wx_viewer.erl ../include/et.hrl et_internal.hrl
+
diff --git a/lib/et/src/et.app.src b/lib/et/src/et.app.src
index 0c7bef7c3d..fd203e3e44 100644
--- a/lib/et/src/et.app.src
+++ b/lib/et/src/et.app.src
@@ -1,20 +1,20 @@
%% This is an -*- erlang -*- file.
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2002-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 2002-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%
{application, et,
@@ -24,9 +24,12 @@
[
et,
et_collector,
- et_contents_viewer,
+ et_gs_contents_viewer,
+ et_gs_viewer,
et_selector,
- et_viewer
+ et_viewer,
+ et_wx_contents_viewer,
+ et_wx_viewer
]},
{registered, [et_collector]},
{applications, [stdlib, kernel]},
diff --git a/lib/et/src/et.erl b/lib/et/src/et.erl
index 9c0a7f8f49..e2cd8564c3 100644
--- a/lib/et/src/et.erl
+++ b/lib/et/src/et.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2000-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 2000-2010. All Rights Reserved.
+%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
-%%
+%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
-%%
+%%
%% %CopyrightEnd%
%%
%%----------------------------------------------------------------------
@@ -84,13 +84,15 @@
-module(et).
-export([
- phone_home/4, report_event/4,
- phone_home/5, report_event/5
+ trace_me/4, phone_home/4, report_event/4,
+ trace_me/5, phone_home/5, report_event/5
]).
%%----------------------------------------------------------------------
%% Reports an event, such as a message
%%
+%% trace_me(DetailLevel, FromTo, Label, Contents) -> hopefully_traced
+%% trace_me(DetailLevel, From, To, Label, Contents) -> hopefully_traced
%% report_event(DetailLevel, FromTo, Label, Contents) -> hopefully_traced
%% report_event(DetailLevel, From, To, Label, Contents) -> hopefully_traced
%% phone_home(DetailLevel, FromTo, Label, Contents) -> hopefully_traced
@@ -123,18 +125,28 @@
%% Other events (termed actions) may be undirected and only have one actor.
%%----------------------------------------------------------------------
+trace_me(DetailLevel, FromTo, Label, Contents)
+ when is_integer(DetailLevel) ->
+ ?MODULE:trace_me(DetailLevel, FromTo, FromTo, Label, Contents).
+
+trace_me(DetailLevel, _From, _To, _Label, _Contents)
+ when is_integer(DetailLevel) ->
+ hopefully_traced.
+
phone_home(DetailLevel, FromTo, Label, Contents) ->
%% N.B External call
- ?MODULE:report_event(DetailLevel, FromTo, FromTo, Label, Contents).
+ ?MODULE:trace_me(DetailLevel, FromTo, FromTo, Label, Contents).
phone_home(DetailLevel, From, To, Label, Contents) ->
%% N.B External call
- ?MODULE:report_event(DetailLevel, From, To, Label, Contents).
+ ?MODULE:trace_me(DetailLevel, From, To, Label, Contents).
report_event(DetailLevel, FromTo, Label, Contents) ->
%% N.B External call
- ?MODULE:report_event(DetailLevel, FromTo, FromTo, Label, Contents).
+ ?MODULE:trace_me(DetailLevel, FromTo, FromTo, Label, Contents).
+
+report_event(DetailLevel, From, To, Label, Contents)
+ when is_integer(DetailLevel) ->
+ %% N.B External call
+ ?MODULE:trace_me(DetailLevel, From, To, Label, Contents).
-report_event(DetailLevel, _From, _To, _Label, _Contents)
- when integer(DetailLevel) ->
- hopefully_traced.
diff --git a/lib/et/src/et_collector.erl b/lib/et/src/et_collector.erl
index ea23c188f7..a63d15fb4c 100644
--- a/lib/et/src/et_collector.erl
+++ b/lib/et/src/et_collector.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2000-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 2000-2010. All Rights Reserved.
+%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
-%%
+%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
-%%
+%%
%% %CopyrightEnd%
%%
%%----------------------------------------------------------------------
@@ -36,6 +36,7 @@
iterate/3,
iterate/5,
+ lookup/2,
start_trace_client/3,
start_trace_port/1,
@@ -45,6 +46,7 @@
get_global_pid/0,
%% get_table_handle/1,
+ get_table_size/1,
change_pattern/2,
make_key/2,
@@ -55,13 +57,19 @@
multicast/2
]).
+%% Internal export
+-export([monitor_trace_port/2]).
+
%% gen_server callbacks
-export([init/1,terminate/2, code_change/3,
handle_call/3, handle_cast/2, handle_info/2]).
+-include("et_internal.hrl").
-include("../include/et.hrl").
-record(state, {parent_pid,
+ auto_shutdown, % Optionally shutdown when the last subscriber dies
+ event_tab_size,
event_tab,
dict_tab,
event_order,
@@ -102,7 +110,7 @@
%% stored by the collector. By replacing the default collector filter
%% with a customized dito it is possible to allow any trace data as
%% input. The collector filter is a dictionary entry with the
-%% predefined key {filter, collector} and the value is a fun of
+%% predefined key {filter, all} and the value is a fun of
%% arity 1. See et_selector:parse_event/2 for interface details,
%% such as which erlang:trace/1 tuples that are accepted.
%%
@@ -126,7 +134,7 @@
%% option() =
%% {parent_pid, pid()} |
%% {event_order, event_order()} |
-%% {dict_insert, {filter, collector}, collector_fun()} |
+%% {dict_insert, {filter, all}, collector_fun()} |
%% {dict_insert, {filter, event_filter_name()}, event_filter_fun()} |
%% {dict_insert, {subscriber, pid()}, dict_val()} |
%% {dict_insert, dict_key(), dict_val()} |
@@ -139,7 +147,7 @@
%%
%% event_order() = trace_ts | event_ts
%% trace_pattern() = detail_level() | dbg_match_spec()
-%% detail_level() = min | max | integer(X) when X =< 0, X >= 100
+%% detail_level() = min | max | integer(X) when X >= 0, X =< 100
%% trace_client() =
%% {event_file, file_name()} |
%% {dbg_trace_type(), dbg_trace_parameters()}
@@ -159,19 +167,16 @@
start_link(Options) ->
case parse_opt(Options, default_state(), [], []) of
- {ok, S, Dict2, Clients} when S#state.trace_global == false ->
- case gen_server:start_link(?MODULE, [S, Dict2], []) of
- {ok, Pid} when S#state.parent_pid /= self() ->
- unlink(Pid),
- start_clients(Pid, Clients);
- {ok,Pid} ->
- start_clients(Pid, Clients);
- {error, Reason} ->
- {error, Reason}
- end;
- {ok, S, Dict2, Clients} when S#state.trace_global == true ->
- case gen_server:start_link({global, ?MODULE}, ?MODULE, [S, Dict2], []) of
- {ok, Pid} when S#state.parent_pid /= self() ->
+ {ok, S, Dict2, Clients} ->
+ Res =
+ case S#state.trace_global of
+ false ->
+ gen_server:start_link(?MODULE, [S, Dict2], []);
+ true ->
+ gen_server:start_link({global, ?MODULE}, ?MODULE, [S, Dict2], [])
+ end,
+ case Res of
+ {ok, Pid} when S#state.parent_pid =/= self() ->
unlink(Pid),
start_clients(Pid, Clients);
{ok,Pid} ->
@@ -185,6 +190,7 @@ start_link(Options) ->
default_state() ->
#state{parent_pid = self(),
+ auto_shutdown = false,
event_order = trace_ts,
subscribers = [],
trace_global = false,
@@ -196,28 +202,30 @@ default_state() ->
parse_opt([], S, Dict, Clients) ->
{Mod, Pattern} = et_selector:make_pattern(S#state.trace_pattern),
Fun = fun(E) -> et_selector:parse_event(Mod, E) end,
- Default = {dict_insert, {filter, collector}, Fun},
+ Default = {dict_insert, {filter, ?DEFAULT_FILTER_NAME}, Fun},
{ok, S#state{trace_pattern = {Mod, Pattern}}, [Default | Dict], Clients};
parse_opt([H | T], S, Dict, Clients) ->
case H of
- {parent_pid, Parent} when Parent == undefined ->
+ {parent_pid, Parent} when Parent =:= undefined ->
parse_opt(T, S#state{parent_pid = Parent}, Dict, Clients);
- {parent_pid, Parent} when pid(Parent) ->
+ {parent_pid, Parent} when is_pid(Parent) ->
parse_opt(T, S#state{parent_pid = Parent}, Dict, Clients);
- {event_order, Order} when Order == trace_ts ->
+ {auto_shutdown, Bool} when Bool =:= true; Bool =:= false ->
+ parse_opt(T, S#state{auto_shutdown = Bool}, Dict, Clients);
+ {event_order, Order} when Order =:= trace_ts ->
parse_opt(T, S#state{event_order = Order}, Dict, Clients);
- {event_order, Order} when Order == event_ts ->
+ {event_order, Order} when Order =:= event_ts ->
parse_opt(T, S#state{event_order = Order}, Dict, Clients);
{dict_insert, {filter, Name}, Fun} ->
if
- atom(Name), function(Fun) ->
+ is_atom(Name), is_function(Fun) ->
parse_opt(T, S, Dict ++ [H], Clients);
true ->
{error, {bad_option, H}}
end;
{dict_insert, {subscriber, Pid}, _Val} ->
if
- pid(Pid) ->
+ is_pid(Pid) ->
parse_opt(T, S, Dict ++ [H], Clients);
true ->
{error, {bad_option, H}}
@@ -228,17 +236,17 @@ parse_opt([H | T], S, Dict, Clients) ->
parse_opt(T, S, Dict ++ [H], Clients);
{trace_client, Client = {_, _}} ->
parse_opt(T, S, Dict, Clients ++ [Client]);
- {trace_global, Bool} when Bool == false ->
+ {trace_global, Bool} when Bool =:= false ->
parse_opt(T, S#state{trace_global = Bool}, Dict, Clients);
- {trace_global, Bool} when Bool == true ->
+ {trace_global, Bool} when Bool =:= true ->
parse_opt(T, S#state{trace_global = Bool}, Dict, Clients);
- {trace_pattern, {Mod, _} = Pattern} when atom(Mod) ->
+ {trace_pattern, {Mod, _} = Pattern} when is_atom(Mod) ->
parse_opt(T, S#state{trace_pattern = Pattern}, Dict, Clients);
{trace_pattern, undefined = Pattern} ->
parse_opt(T, S#state{trace_pattern = Pattern}, Dict, Clients);
- {trace_port, Port} when integer(Port) ->
+ {trace_port, Port} when is_integer(Port) ->
parse_opt(T, S#state{trace_port = Port}, Dict, Clients);
- {trace_max_queue, MaxQueue} when integer(MaxQueue) ->
+ {trace_max_queue, MaxQueue} when is_integer(MaxQueue) ->
parse_opt(T, S#state{trace_port = MaxQueue}, Dict, Clients);
Bad ->
{error, {bad_option, Bad}}
@@ -352,19 +360,19 @@ do_load_event_file(Fun, Fd, Cont, Acc, FileName, BadBytes) ->
%% Returns: {ok, Continuation} | exit(Reason)
%%----------------------------------------------------------------------
-report(CollectorPid, TraceOrEvent) when pid(CollectorPid) ->
+report(CollectorPid, TraceOrEvent) when is_pid(CollectorPid) ->
case get_table_handle(CollectorPid) of
- {ok, TH} when record(TH, table_handle) ->
+ {ok, TH} when is_record(TH, table_handle) ->
report(TH, TraceOrEvent);
{error, Reason} ->
exit(Reason)
end;
-report(TH, TraceOrEvent) when record(TH, table_handle) ->
+report(TH, TraceOrEvent) when is_record(TH, table_handle) ->
Fun = TH#table_handle.filter,
case Fun(TraceOrEvent) of
false ->
{ok, TH};
- true when record(TraceOrEvent, event) ->
+ true when is_record(TraceOrEvent, event) ->
Key = make_key(TH, TraceOrEvent),
case catch ets:insert(TH#table_handle.event_tab, {Key, TraceOrEvent}) of
true ->
@@ -373,7 +381,7 @@ report(TH, TraceOrEvent) when record(TH, table_handle) ->
%% Refresh the report handle and try again
report(TH#table_handle.collector_pid, TraceOrEvent)
end;
- {true, Event} when record(Event, event) ->
+ {true, Event} when is_record(Event, event) ->
Key = make_key(TH, Event),
case catch ets:insert(TH#table_handle.event_tab, {Key, Event}) of
true ->
@@ -401,7 +409,7 @@ report(TH, TraceOrEvent) when record(TH, table_handle) ->
report(TH#table_handle.collector_pid, TraceOrEvent)
end
end;
-report(TH, end_of_trace) when record(TH, table_handle) ->
+report(TH, end_of_trace) when is_record(TH, table_handle) ->
{ok, TH};
report(_, Bad) ->
exit({bad_event, Bad}).
@@ -410,7 +418,9 @@ report_event(CollectorPid, DetailLevel, FromTo, Label, Contents) ->
report_event(CollectorPid, DetailLevel, FromTo, FromTo, Label, Contents).
report_event(CollectorPid, DetailLevel, From, To, Label, Contents)
- when integer(DetailLevel), DetailLevel >= 0, DetailLevel =< 100, list(Contents) ->
+ when is_integer(DetailLevel),
+ DetailLevel >= ?detail_level_min,
+ DetailLevel =< ?detail_level_max ->
TS= erlang:now(),
E = #event{detail_level = DetailLevel,
trace_ts = TS,
@@ -431,32 +441,38 @@ report_event(CollectorPid, DetailLevel, From, To, Label, Contents)
%% Key = record(event_ts) | record(trace_ts)
%%----------------------------------------------------------------------
-make_key(TH, Stuff) when record(TH, table_handle) ->
+make_key(TH, Stuff) when is_record(TH, table_handle) ->
make_key(TH#table_handle.event_order, Stuff);
make_key(trace_ts, Stuff) ->
if
- record(Stuff, event) ->
+ is_record(Stuff, event) ->
#event{trace_ts = R, event_ts = P} = Stuff,
#trace_ts{trace_ts = R, event_ts = P};
- record(Stuff, trace_ts) ->
+ is_record(Stuff, trace_ts) ->
Stuff;
- record(Stuff, event_ts) ->
+ is_record(Stuff, event_ts) ->
#event_ts{trace_ts = R, event_ts = P} = Stuff,
#trace_ts{trace_ts = R, event_ts = P}
end;
make_key(event_ts, Stuff) ->
if
- record(Stuff, event) ->
+ is_record(Stuff, event) ->
#event{trace_ts = R, event_ts = P} = Stuff,
#event_ts{trace_ts = R, event_ts = P};
- record(Stuff, event_ts) ->
+ is_record(Stuff, event_ts) ->
Stuff;
- record(Stuff, trace_ts) ->
+ is_record(Stuff, trace_ts) ->
#trace_ts{trace_ts = R, event_ts = P} = Stuff,
#event_ts{trace_ts = R, event_ts = P}
end.
%%----------------------------------------------------------------------
+%%----------------------------------------------------------------------
+
+get_table_size(CollectorPid) when is_pid(CollectorPid) ->
+ call(CollectorPid, get_table_size).
+
+%%----------------------------------------------------------------------
%% get_table_handle(CollectorPid) -> Handle
%%
%% Return a table handle
@@ -465,7 +481,7 @@ make_key(event_ts, Stuff) ->
%% Handle = record(table_handle)
%%----------------------------------------------------------------------
-get_table_handle(CollectorPid) when pid(CollectorPid) ->
+get_table_handle(CollectorPid) when is_pid(CollectorPid) ->
call(CollectorPid, get_table_handle).
%%----------------------------------------------------------------------
@@ -480,7 +496,7 @@ get_table_handle(CollectorPid) when pid(CollectorPid) ->
get_global_pid() ->
case global:whereis_name(?MODULE) of
- CollectorPid when pid(CollectorPid) ->
+ CollectorPid when is_pid(CollectorPid) ->
CollectorPid;
undefined ->
exit(global_collector_not_started)
@@ -505,7 +521,7 @@ change_pattern(CollectorPid, RawPattern) ->
call(CollectorPid, {change_pattern, Pattern}).
%%----------------------------------------------------------------------
-%% dict_insert(CollectorPid, {filter, collector}, FilterFun) -> ok
+%% dict_insert(CollectorPid, {filter, all}, FilterFun) -> ok
%% dict_insert(CollectorPid, {subscriber, SubscriberPid}, Void) -> ok
%% dict_insert(CollectorPid, Key, Val) -> ok
%%
@@ -532,14 +548,14 @@ change_pattern(CollectorPid, RawPattern) ->
dict_insert(CollectorPid, Key = {filter, Name}, Fun) ->
if
- atom(Name), function(Fun) ->
+ is_atom(Name), is_function(Fun) ->
call(CollectorPid, {dict_insert, Key, Fun});
true ->
exit({badarg, Key})
end;
dict_insert(CollectorPid, Key = {subscriber, Pid}, Val) ->
if
- pid(Pid) ->
+ is_pid(Pid) ->
call(CollectorPid, {dict_insert, Key, Val});
true ->
exit({badarg, Key})
@@ -626,9 +642,9 @@ multicast(CollectorPid, Msg) ->
%% Pid = dbg_trace_client_pid()
%%----------------------------------------------------------------------
-start_trace_client(CollectorPid, Type, FileName) when Type == event_file ->
+start_trace_client(CollectorPid, Type, FileName) when Type =:= event_file ->
load_event_file(CollectorPid, FileName);
-start_trace_client(CollectorPid, Type, FileName) when Type == file ->
+start_trace_client(CollectorPid, Type, FileName) when Type =:= file ->
WaitFor = {make_ref(), end_of_trace},
EventFun = fun(E, {ReplyTo, {ok, TH}}) -> {ReplyTo, report(TH, E)} end,
EndFun = fun({ReplyTo, {ok, _TH}}) -> ReplyTo ! WaitFor, ReplyTo end,
@@ -658,9 +674,9 @@ start_trace_client(CollectorPid, Type, Parameters) ->
{trace_client_pid, Pid}.
trace_spec_wrapper(EventFun, EndFun, EventInitialAcc)
- when function(EventFun), function(EndFun) ->
+ when is_function(EventFun), is_function(EndFun) ->
{fun(Trace, Acc) ->
- case Trace == end_of_trace of
+ case Trace =:= end_of_trace of
true -> EndFun(Acc);
false -> EventFun(Trace, Acc)
end
@@ -670,6 +686,17 @@ trace_spec_wrapper(EventFun, EndFun, EventInitialAcc)
start_trace_port(Parameters) ->
dbg:tracer(port, dbg:trace_port(ip, Parameters)).
+monitor_trace_port(CollectorPid, Parameters) ->
+ Res = start_trace_port(Parameters),
+ spawn(fun() ->
+ MonitorRef = erlang:monitor(process, CollectorPid),
+ receive
+ {'DOWN', MonitorRef, _, _, _} ->
+ dbg:stop_clear()
+ end
+ end),
+ Res.
+
%%----------------------------------------------------------------------
%% iterate(Handle, Prev, Limit) ->
%% iterate(Handle, Prev, Limit, undefined, Prev)
@@ -702,24 +729,24 @@ iterate(Handle, Prev, Limit) ->
%% Acc = NewAcc = term()
%%----------------------------------------------------------------------
-iterate(_, _, Limit, _, Acc) when Limit == 0 ->
+iterate(_, _, Limit, _, Acc) when Limit =:= 0 ->
Acc;
-iterate(CollectorPid, Prev, Limit, Fun, Acc) when pid(CollectorPid) ->
+iterate(CollectorPid, Prev, Limit, Fun, Acc) when is_pid(CollectorPid) ->
case get_table_handle(CollectorPid) of
- {ok, TH} when record(TH, table_handle) ->
+ {ok, TH} when is_record(TH, table_handle) ->
iterate(TH, Prev, Limit, Fun, Acc);
{error, Reason} ->
exit(Reason)
end;
-iterate(TH, Prev, Limit, Fun, Acc) when record(TH, table_handle) ->
+iterate(TH, Prev, Limit, Fun, Acc) when is_record(TH, table_handle) ->
if
- Limit == infinity ->
+ Limit =:= infinity ->
next_iterate(TH, Prev, Limit, Fun, Acc);
- integer(Limit), Limit > 0 ->
+ is_integer(Limit), Limit > 0 ->
next_iterate(TH, Prev, Limit, Fun, Acc);
- Limit == '-infinity' ->
+ Limit =:= '-infinity' ->
prev_iterate(TH, Prev, Limit, Fun, Acc);
- integer(Limit), Limit < 0 ->
+ is_integer(Limit), Limit < 0 ->
prev_iterate(TH, Prev, Limit, Fun, Acc)
end.
@@ -793,7 +820,7 @@ prev_iterate(TH, Prev, Limit, Fun, Acc) ->
lookup_and_apply(TH, Prev, Next, Limit, 1, Fun, Acc)
end.
-lookup_and_apply(TH, _Prev, Next, Limit, Incr, Fun, _Acc) when Fun == undefined ->
+lookup_and_apply(TH, _Prev, Next, Limit, Incr, Fun, _Acc) when Fun =:= undefined ->
Limit2 = incr(Limit, Incr),
iterate(TH, Next, Limit2, Fun, Next);
lookup_and_apply(TH, Prev, Next, Limit, Incr, Fun, Acc) ->
@@ -801,17 +828,33 @@ lookup_and_apply(TH, Prev, Next, Limit, Incr, Fun, Acc) ->
case catch ets:lookup_element(Tab, Next, 2) of
{'EXIT', _} ->
iterate(TH#table_handle.collector_pid, Prev, Limit, Fun, Acc);
- E when record(E, event) ->
+ E when is_record(E, event) ->
Acc2 = Fun(E, Acc),
Limit2 = incr(Limit, Incr),
iterate(TH, Next, Limit2, Fun, Acc2)
end.
+lookup(CollectorPid, Key) when is_pid(CollectorPid) ->
+ case get_table_handle(CollectorPid) of
+ {ok, TH} when is_record(TH, table_handle) ->
+ lookup(TH, Key);
+ {error, Reason} ->
+ {error, Reason}
+ end;
+lookup(TH, Key) when is_record(TH, table_handle) ->
+ Tab = TH#table_handle.event_tab,
+ case catch ets:lookup_element(Tab, Key, 2) of
+ {'EXIT', _} ->
+ {error, enoent};
+ E when is_record(E, event) ->
+ {ok, E}
+ end.
+
incr(Val, Incr) ->
if
- Val == infinity -> Val;
- Val == '-infinity' -> Val;
- integer(Val) -> Val + Incr
+ Val =:= infinity -> Val;
+ Val =:= '-infinity' -> Val;
+ is_integer(Val) -> Val + Incr
end.
%%----------------------------------------------------------------------
@@ -824,13 +867,18 @@ incr(Val, Incr) ->
%% table_handle() = record(table_handle)
%%----------------------------------------------------------------------
-clear_table(CollectorPid) when pid(CollectorPid) ->
+clear_table(CollectorPid) when is_pid(CollectorPid) ->
call(CollectorPid, clear_table);
-clear_table(TH) when record(TH, table_handle) ->
+clear_table(TH) when is_record(TH, table_handle) ->
clear_table(TH#table_handle.collector_pid).
call(CollectorPid, Request) ->
- gen_server:call(CollectorPid, Request, infinity).
+ try
+ gen_server:call(CollectorPid, Request, infinity)
+ catch
+ exit:{noproc,_} ->
+ {error, no_collector}
+ end.
%%%----------------------------------------------------------------------
%%% Callback functions from gen_server
@@ -849,7 +897,7 @@ init([InitialS, Dict]) ->
case InitialS#state.parent_pid of
undefined ->
ignore;
- Pid when pid(Pid) ->
+ Pid when is_pid(Pid) ->
link(Pid)
end,
Funs = [fun init_tables/1,
@@ -860,7 +908,7 @@ init([InitialS, Dict]) ->
init_tables(S) ->
EventTab = ets:new(et_events, [ordered_set, {keypos, 1}, public]),
DictTab = ets:new(et_dict, [ordered_set, {keypos, 1}, public]),
- S#state{event_tab = EventTab, dict_tab = DictTab}.
+ S#state{event_tab = EventTab, dict_tab = DictTab, event_tab_size = 0}.
init_global(S) ->
case S#state.trace_global of
@@ -889,44 +937,53 @@ init_global(S) ->
handle_call({multicast, Msg}, _From, S) ->
do_multicast(S#state.subscribers, Msg),
- {reply, ok, S};
+ reply(ok, S);
handle_call(Msg = {dict_insert, _Key, _Val}, _From, S) ->
S2 = do_dict_insert(Msg, S),
- {reply, ok, S2};
+ reply(ok, S2);
handle_call(Msg = {dict_delete, _Key}, _From, S) ->
- S2 = do_dict_delete(Msg, S),
- {reply, ok, S2};
-
+ try
+ S2 = do_dict_delete(Msg, S),
+ reply(ok, S2)
+ catch
+ throw:{stop, R} ->
+ opt_unlink(S#state.parent_pid),
+ {stop, R, S}
+ end;
handle_call({dict_lookup, Key}, _From, S) ->
Reply = ets:lookup(S#state.dict_tab, Key),
- {reply, Reply, S};
+ reply(Reply, S);
handle_call({dict_match, Pattern}, _From, S) ->
case catch ets:match_object(S#state.dict_tab, Pattern) of
{'EXIT', _Reason} ->
- {reply, [], S};
+ reply([], S);
Matching ->
- {reply, Matching, S}
+ reply(Matching, S)
end;
handle_call(get_table_handle, _From, S) ->
- [{_, TableFilter}] = ets:lookup(S#state.dict_tab, {filter, collector}),
+ [{_, TableFilter}] = ets:lookup(S#state.dict_tab, {filter, ?DEFAULT_FILTER_NAME}),
TH = #table_handle{collector_pid = self(),
event_tab = S#state.event_tab,
event_order = S#state.event_order,
filter = TableFilter},
- {reply, {ok, TH}, S};
+ reply({ok, TH}, S);
+
+handle_call(get_table_size, _From, S) ->
+ Size = ets:info(S#state.event_tab, size),
+ reply({ok, Size}, S);
handle_call(close, _From, S) ->
case S#state.file of
undefined ->
- {reply, {error, file_not_open}, S};
+ reply({error, file_not_open}, S);
F ->
Reply = disk_log:close(F#file.desc),
S2 = S#state{file = undefined},
- {reply, Reply, S2}
+ reply(Reply, S2)
end;
handle_call({save_event_file, FileName, Options}, _From, S) ->
Default = #file{name = FileName,
@@ -934,7 +991,7 @@ handle_call({save_event_file, FileName, Options}, _From, S) ->
file_opt = write,
table_opt = keep},
case parse_file_options(Default, Options) of
- {ok, F} when record(F, file) ->
+ {ok, F} when is_record(F, file) ->
case file_open(F) of
{ok, Fd} ->
F2 = F#file{desc = Fd},
@@ -966,16 +1023,16 @@ handle_call({save_event_file, FileName, Options}, _From, S) ->
end,
case F2#file.table_opt of
keep ->
- {reply, Reply2, S3};
+ reply(Reply2, S3);
clear ->
S4 = do_clear_table(S3),
- {reply, Reply2, S4}
+ reply(Reply2, S4)
end;
{error, Reason} ->
- {reply, {error, {file_open, Reason}}, S}
+ reply({error, {file_open, Reason}}, S)
end;
{error, Reason} ->
- {reply, {error, Reason}, S}
+ reply({error, Reason}, S)
end;
handle_call({change_pattern, Pattern}, _From, S) ->
@@ -983,23 +1040,23 @@ handle_call({change_pattern, Pattern}, _From, S) ->
rpc:multicall(Ns, et_selector, change_pattern, [Pattern]),
Reply = {old_pattern, S#state.trace_pattern},
S2 = S#state{trace_pattern = Pattern},
- {reply, Reply, S2};
+ reply(Reply, S2);
handle_call(clear_table, _From, S) ->
S2 = do_clear_table(S),
- {reply, ok, S2};
+ reply(ok, S2);
handle_call(stop, _From, S) ->
do_multicast(S#state.subscribers, close),
case S#state.trace_global of
- true -> rpc:multicall(S#state.trace_nodes, dbg, stop, []);
+ true -> rpc:multicall(S#state.trace_nodes, dbg, stop_clear, []);
false -> ignore
end,
{stop, shutdown, ok, S};
handle_call(Request, From, S) ->
ok = error_logger:format("~p(~p): handle_call(~p, ~p, ~p)~n",
[?MODULE, self(), Request, From, S]),
- {reply, {error, {bad_request, Request}}, S}.
+ reply({error, {bad_request, Request}}, S).
%%----------------------------------------------------------------------
%% Func: handle_cast/2
@@ -1011,7 +1068,7 @@ handle_call(Request, From, S) ->
handle_cast(Msg, S) ->
ok = error_logger:format("~p(~p): handle_cast(~p, ~p)~n",
[?MODULE, self(), Msg, S]),
- {noreply, S}.
+ noreply(S).
%%----------------------------------------------------------------------
%% Func: handle_info/2
@@ -1020,54 +1077,67 @@ handle_cast(Msg, S) ->
%% {stop, Reason, State} (terminate/2 is called)
%%----------------------------------------------------------------------
+handle_info(timeout, S) ->
+ S2 = check_size(S),
+ noreply(S2);
handle_info({nodeup, Node}, S) ->
Port = S#state.trace_port,
MaxQueue = S#state.trace_max_queue,
- case rpc:call(Node, ?MODULE, start_trace_port, [{Port, MaxQueue}]) of
+ case rpc:call(Node, ?MODULE, monitor_trace_port, [self(), {Port, MaxQueue}]) of
{ok, _} ->
- listen_on_trace_port(Node, Port, S);
- {error, Reason} when Reason == already_started->
+ S2 = listen_on_trace_port(Node, Port, S),
+ noreply(S2);
+ {error, Reason} when Reason =:= already_started->
ok = error_logger:format("~p(~p): producer ignored(~p:~p):~n ~p~n",
[?MODULE, self(), Node, Port, Reason]),
S2 = S#state{trace_port = Port + 1},
- {noreply, S2};
+ noreply(S2);
{badrpc, Reason} ->
ok = error_logger:format("~p(~p): producer ignored(~p:~p):~n ~p~n",
[?MODULE, self(), Node, Port, Reason]),
S2 = S#state{trace_port = Port + 1},
- {noreply, S2};
+ noreply(S2);
{error, Reason} ->
self() ! {nodeup, Node},
ok = error_logger:format("~p(~p): producer retry(~p:~p):~n ~p~n",
[?MODULE, self(), Node, Port, Reason]),
S2 = S#state{trace_port = Port + 1},
- {noreply, S2}
+ noreply(S2)
end;
handle_info({nodedown, Node}, S) ->
- {noreply, S#state{trace_nodes = S#state.trace_nodes -- [Node]}};
+ noreply(S#state{trace_nodes = S#state.trace_nodes -- [Node]});
handle_info({register_trace_client, Pid}, S) ->
link(Pid),
- {noreply, S};
+ noreply(S);
-handle_info({'EXIT', Pid, Reason}, S) when Pid == S#state.parent_pid ->
+handle_info({'EXIT', Pid, Reason}, S) when Pid =:= S#state.parent_pid ->
{stop, Reason, S};
-handle_info(Info = {'EXIT', Pid, _Reason}, S) ->
- OldSubscribers = S#state.subscribers,
+handle_info(Info = {'EXIT', Pid, Reason}, S) ->
+ OldSubscribers = S#state.subscribers,
case lists:member(Pid, OldSubscribers) of
- true ->
- S2 = do_dict_delete({dict_delete, {subscriber, Pid}}, S),
- {noreply, S2};
+ true when Reason =:= shutdown ->
+ try
+ S2 = do_dict_delete({dict_delete, {subscriber, Pid}}, S),
+ noreply(S2)
+ catch
+ throw:{stop, R} ->
+ opt_unlink(S#state.parent_pid),
+ {stop, R, S}
+ end;
+ true ->
+ opt_unlink(S#state.parent_pid),
+ {stop, Reason, S};
false ->
ok = error_logger:format("~p(~p): handle_info(~p, ~p)~n",
[?MODULE, self(), Info, S]),
- {noreply, S}
+ noreply(S)
end;
handle_info(Info, S) ->
ok = error_logger:format("~p(~p): handle_info(~p, ~p)~n",
[?MODULE, self(), Info, S]),
- {noreply, S}.
+ noreply(S).
listen_on_trace_port(Node, Port, S) ->
[_Name, Host] = string:tokens(atom_to_list(Node), [$@]),
@@ -1075,20 +1145,17 @@ listen_on_trace_port(Node, Port, S) ->
{trace_client_pid, RemotePid} ->
rpc:call(Node, et_selector, change_pattern, [S#state.trace_pattern]),
link(RemotePid),
- S2 = S#state{trace_nodes = [Node | S#state.trace_nodes],
- trace_port = Port + 1},
- {noreply, S2};
- {'EXIT', Reason} when Reason == already_started->
+ S#state{trace_nodes = [Node | S#state.trace_nodes],
+ trace_port = Port + 1};
+ {'EXIT', Reason} when Reason =:= already_started->
ok = error_logger:format("~p(~p): consumer ignored(~p:~p): ~p~n",
[?MODULE, self(), Node, Port, Reason]),
- S2 = S#state{trace_port = Port + 1},
- {noreply, S2};
+ S#state{trace_port = Port + 1};
{'EXIT', Reason} ->
self() ! {nodeup, Node},
ok = error_logger:format("~p(~p): consumer retry(~p:~p):~n ~p~n",
[?MODULE, self(), Node, Port, Reason]),
- S2 = S#state{trace_port = Port + 1},
- {noreply, S2}
+ S#state{trace_port = Port + 1}
end.
%%----------------------------------------------------------------------
@@ -1120,7 +1187,7 @@ do_clear_table(S) ->
NewTab = ets:new(et_events, [ordered_set, {keypos, 1}, public]),
S#state{event_tab = NewTab}.
-do_dict_insert(Msg = {dict_insert, Key = {subscriber, Pid}, Val}, S) when pid(Pid) ->
+do_dict_insert(Msg = {dict_insert, Key = {subscriber, Pid}, Val}, S) when is_pid(Pid) ->
OldSubscribers = S#state.subscribers,
NewSubscribers =
case lists:member(Pid, OldSubscribers) of
@@ -1133,6 +1200,8 @@ do_dict_insert(Msg = {dict_insert, Key = {subscriber, Pid}, Val}, S) when pid(Pi
[Pid | OldSubscribers]
end,
do_multicast(NewSubscribers, Msg),
+ Size = ets:info(S#state.event_tab, size),
+ do_multicast(NewSubscribers, {more_events, Size}),
ets:insert(S#state.dict_tab, {Key, Val}),
S#state{subscribers = NewSubscribers};
do_dict_insert(Msg = {dict_insert, Key, Val}, S) ->
@@ -1147,11 +1216,18 @@ do_dict_delete(Msg = {dict_delete, Key = {subscriber, Pid}}, S) ->
case lists:member(Pid, OldSubscribers) of
true ->
unlink(Pid),
- S#state{subscribers = OldSubscribers -- [Pid]};
+ S2 = S#state{subscribers = OldSubscribers -- [Pid]},
+ if
+ S2#state.auto_shutdown,
+ S2#state.subscribers =:= [] ->
+ throw({stop, shutdown});
+ true ->
+ S2
+ end;
false ->
S
end;
-do_dict_delete({dict_delete, {filter, collector}}, S) ->
+do_dict_delete({dict_delete, {filter, ?DEFAULT_FILTER_NAME}}, S) ->
S;
do_dict_delete(Msg = {dict_delete, Key}, S) ->
do_multicast(S#state.subscribers, Msg),
@@ -1202,3 +1278,33 @@ do_multicast([Pid | Pids], Msg) ->
do_multicast(Pids, Msg);
do_multicast([], _Msg) ->
ok.
+
+opt_unlink(Pid) ->
+ if
+ Pid =:= undefined ->
+ ignore;
+ true ->
+ unlink(Pid)
+ end.
+
+reply(Reply, #state{subscribers = []} = S) ->
+ {reply, Reply, S};
+reply(Reply, S) ->
+ {reply, Reply, S, 500}.
+
+noreply(#state{subscribers = []} = S) ->
+ {noreply, S};
+noreply(S) ->
+ {noreply, S, 500}.
+
+check_size(S) ->
+ Size = ets:info(S#state.event_tab, size),
+ if
+ Size =:= S#state.event_tab_size ->
+ S;
+ true ->
+ %% Tell the subscribers that more events are available
+ Msg = {more_events, Size},
+ do_multicast(S#state.subscribers, Msg),
+ S#state{event_tab_size = Size}
+ end.
diff --git a/lib/et/src/et_contents_viewer.erl b/lib/et/src/et_contents_viewer.erl
deleted file mode 100644
index 29ca93ca64..0000000000
--- a/lib/et/src/et_contents_viewer.erl
+++ /dev/null
@@ -1,591 +0,0 @@
-%%
-%% %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: Displays details of a trace event
-%%----------------------------------------------------------------------
-
--module(et_contents_viewer).
-
--behaviour(gen_server).
-
-%% External exports
--export([start_link/1,
- stop/1]).
-
-%% gen_server callbacks
--export([init/1, terminate/2, code_change/3,
- handle_call/3, handle_cast/2, handle_info/2]).
-
--include("../include/et.hrl").
--include("et_internal.hrl").
-
--record(state, {parent_pid, % Pid of parent process
- viewer_pid, % Pid of viewer process
- event_order, % Field to be used as primary key
- event, % The original event
- filtered_event, % Event processed by active filter
- active_filter, % Name of the active filter
- filters, % List of possible filters
- win, % GUI: Window object
- packer, % GUI: Packer object
- width, % GUI: Window width
- height}). % GUI: Window height
-
-%%%----------------------------------------------------------------------
-%%% Client side
-%%%----------------------------------------------------------------------
-
-%%----------------------------------------------------------------------
-%% start_link(Options) -> {ok, ContentsPid} | {error, Reason}
-%%
-%% Start an viewer for the event contents as window in GS
-%%
-%% Options = [option()]
-%%
-%% option() =
-%%
-%% {parent_pid, pid()} | % Pid of parent process
-%% {viewer_pid, pid()} | % Pid of viewer process
-%% {event_order, event_order()} | % Field to be used as primary key
-%% {active_filter, atom()} | % Name of the active filter
-%% {filter, atom(), fun()} % A named filter fun
-%%
-%% event_order() = 'trace_ts' | 'event_ts'
-%% ContentsPid = pid()
-%% Reason = term()
-%%----------------------------------------------------------------------
-
-start_link(Options) ->
- case parse_opt(Options, default_state()) of
- {ok, S} ->
- case gen_server:start_link(?MODULE, [S], []) of
- {ok, ContentsPid} when S#state.parent_pid /= self() ->
- unlink(ContentsPid),
- {ok, ContentsPid};
- Other ->
- Other
- end;
- {error, Reason} ->
- {error, Reason}
- end.
-
-default_state() ->
- #state{parent_pid = self(),
- viewer_pid = undefined,
- active_filter = collector,
- filters = [#filter{name = collector, function = fun(E) -> E end}],
- width = 600,
- height = 300}.
-
-parse_opt([], S) ->
- Name = S#state.active_filter,
- Filters = S#state.filters,
- if
- S#state.event == undefined ->
- {error, {badarg, no_event}};
- atom(Name) ->
- case lists:keysearch(Name, #filter.name, Filters) of
- {value, F} when record(F, filter) ->
- {ok, S#state{active_filter = Name}};
- false ->
- {error, {badarg, {no_such_filter, Name, Filters}}}
- end
- end;
-parse_opt([H | T], S) ->
- case H of
- {parent_pid, ParentPid} when pid(ParentPid) ->
- parse_opt(T, S#state{parent_pid = ParentPid});
- {viewer_pid, ViewerPid} when pid(ViewerPid) ->
- parse_opt(T, S#state{viewer_pid = ViewerPid});
- {event_order, trace_ts} ->
- parse_opt(T, S#state{event_order = trace_ts});
- {event_order, event_ts} ->
- parse_opt(T, S#state{event_order = event_ts});
- {event, Event} when record(Event, event) ->
- parse_opt(T, S#state{event = Event});
- {active_filter, Name} when atom(Name) ->
- parse_opt(T, S#state{active_filter = Name});
- F when record(F, filter),
- atom(F#filter.name),
- function(F#filter.function) ->
- Filters = lists:keydelete(F#filter.name, #filter.name, S#state.filters),
- Filters2 = lists:keysort(#filter.name, [F | Filters]),
- parse_opt(T, S#state{filters = Filters2});
- {width, Width} when integer(Width), Width > 0 ->
- parse_opt(T, S#state{width = Width});
- {height, Height} when integer(Height), Height > 0 ->
- parse_opt(T, S#state{height = Height});
- Bad ->
- {error, {bad_option, Bad}}
- end;
-parse_opt(BadList, _S) ->
- {error, {bad_option_list, BadList}}.
-
-%%----------------------------------------------------------------------
-%% stop(ContentsPid) -> ok
-%%
-%% Stops a contents viewer process
-%%
-%% ContentsPid = pid()
-%%----------------------------------------------------------------------
-
-stop(ContentsPid) ->
- unlink(ContentsPid),
- call(ContentsPid, stop).
-
-call(ContentsPid, Request) ->
- gen_server:call(ContentsPid, Request, infinity).
-
-%%%----------------------------------------------------------------------
-%%% Callback functions from gen_server
-%%%----------------------------------------------------------------------
-
-%%----------------------------------------------------------------------
-%% Func: init/1
-%% Returns: {ok, State} |
-%% {ok, State, Timeout} |
-%% ignore |
-%% {stop, Reason}
-%%----------------------------------------------------------------------
-
-init([S]) when record(S, state) ->
- process_flag(trap_exit, true),
- S2 = create_window(S),
- {ok, S2}.
-
-%%----------------------------------------------------------------------
-%% Func: handle_call/3
-%% Returns: {reply, Reply, State} |
-%% {reply, Reply, State, Timeout} |
-%% {noreply, State} |
-%% {noreply, State, Timeout} |
-%% {stop, Reason, Reply, State} | (terminate/2 is called)
-%% {stop, Reason, State} (terminate/2 is called)
-%%----------------------------------------------------------------------
-
-handle_call(stop, _From, S) ->
- unlink(S#state.parent_pid),
- {stop, shutdown, ok, S};
-handle_call(Request, From, S) ->
- ok = error_logger:format("~p(~p): handle_call(~p, ~p, ~p)~n",
- [?MODULE, self(), Request, From, S]),
- Reply = {error, {bad_request, Request}},
- {reply, Reply, S}.
-
-%%----------------------------------------------------------------------
-%% Func: handle_cast/2
-%% Returns: {noreply, State} |
-%% {noreply, State, Timeout} |
-%% {stop, Reason, State} (terminate/2 is called)
-%%----------------------------------------------------------------------
-
-handle_cast(Msg, S) ->
- ok = error_logger:format("~p(~p): handle_cast(~p, ~p)~n",
- [?MODULE, self(), Msg, S]),
- {noreply, S}.
-
-%%----------------------------------------------------------------------
-%% Func: handle_info/2
-%% Returns: {noreply, State} |
-%% {noreply, State, Timeout} |
-%% {stop, Reason, State} (terminate/2 is called)
-%%----------------------------------------------------------------------
-
-handle_info({gs, Button, click, Data, _Other}, S) ->
- case Button of
- close ->
- gs:destroy(S#state.win),
- {stop, normal, S};
- save ->
- Event = S#state.event,
- Bin = list_to_binary(event_to_string(Event, S#state.event_order)),
- TimeStamp =
- case S#state.event_order of
- trace_ts -> Event#event.trace_ts;
- event_ts -> Event#event.event_ts
- end,
- FileName = ["et_contents_viewer_", now_to_string(TimeStamp), ".save"],
- file:write_file(lists:flatten(FileName), Bin),
- {noreply, S};
- _PopupMenuItem when record(Data, filter) ->
- F = Data,
- ChildState= S#state{active_filter = F#filter.name},
- case gen_server:start_link(?MODULE, [ChildState], []) of
- {ok, Pid} when S#state.parent_pid /= self() ->
- unlink(Pid),
- {noreply, S};
- _ ->
- {noreply, S}
- end;
- {hide, Actors} ->
- send_viewer_event(S, {delete_actors, Actors}),
- {noreply, S};
- {show, Actors} ->
- send_viewer_event(S, {insert_actors, Actors}),
- {noreply, S};
- {mode, Mode} ->
- send_viewer_event(S, {mode, Mode}),
- {noreply, S};
- Nyi ->
- ok = error_logger:format("~p: click ~p ignored (nyi)~n",
- [?MODULE, Nyi]),
- {noreply, S}
- end;
-handle_info({gs, _Obj, destroy,_, _}, S) ->
- unlink(S#state.parent_pid),
- gs:destroy(S#state.win),
- {stop, normal, S};
-handle_info({gs, _Obj, keypress, _, [KeySym, _Keycode, _Shift, _Control | _]}, S) ->
- case KeySym of
- 'c' ->
- gs:destroy(S#state.win),
- {stop, normal, S};
-
- 'f' ->
- E = S#state.filtered_event,
- From = E#event.from,
- send_viewer_event(S, {delete_actors, [From]}),
- {noreply, S};
- 't' ->
- E = S#state.filtered_event,
- To = E#event.to,
- send_viewer_event(S, {delete_actors, [To]}),
- {noreply, S};
- 'b' ->
- E = S#state.filtered_event,
- From = E#event.from,
- To = E#event.to,
- send_viewer_event(S, {delete_actors, [From, To]}),
- {noreply, S};
-
- 'F' ->
- E = S#state.filtered_event,
- From = E#event.from,
- send_viewer_event(S, {insert_actors, [From]}),
- {noreply, S};
- 'T' ->
- E = S#state.filtered_event,
- To = E#event.to,
- send_viewer_event(S, {insert_actors, [To]}),
- {noreply, S};
- 'B' ->
- E = S#state.filtered_event,
- From = E#event.from,
- To = E#event.to,
- send_viewer_event(S, {insert_actors, [From, To]}),
- {noreply, S};
-
- 's' ->
- E = S#state.filtered_event,
- From = E#event.from,
- To = E#event.to,
- First = et_collector:make_key(S#state.event_order, E),
- Mode = {search_actors, forward, First, [From, To]},
- send_viewer_event(S, {mode, Mode}),
- {noreply, S};
- 'r' ->
- E = S#state.filtered_event,
- From = E#event.from,
- To = E#event.to,
- First = et_collector:make_key(S#state.event_order, E),
- Mode = {search_actors, reverse, First, [From, To]},
- send_viewer_event(S, {mode, Mode}),
- {noreply, S};
- 'a' ->
- send_viewer_event(S, {mode, all}),
- {noreply, S};
-
- 0 ->
- case lists:keysearch(collector, #filter.name, S#state.filters) of
- {value, F} when record(F, filter) ->
- ChildState= S#state{active_filter = F#filter.name},
- case gen_server:start_link(?MODULE, [ChildState], []) of
- {ok, Pid} when S#state.parent_pid /= self() ->
- unlink(Pid);
- _ ->
- ignore
- end;
- false ->
- ignore
- end,
- {noreply, S};
- Int when integer(Int), Int > 0, Int =< 9 ->
- case catch lists:nth(Int, S#state.filters) of
- F when record(F, filter) ->
- ChildState= S#state{active_filter = F#filter.name},
- case gen_server:start_link(?MODULE, [ChildState], []) of
- {ok, Pid} when S#state.parent_pid /= self() ->
- unlink(Pid);
- _ ->
- ignore
- end;
- {'EXIT', _} ->
- ignore
- end,
- {noreply, S};
-
- 'Shift_L' ->
- {noreply, S};
- 'Shift_R' ->
- {noreply, S};
- 'Caps_Lock' ->
- {noreply, S};
- _ ->
- io:format("~p: ignored: ~p~n", [?MODULE, KeySym]),
- {noreply, S}
- end;
-handle_info({gs, _Obj, configure, [], [W, H | _]}, S) ->
- gs:config(S#state.packer, [{width, W},{height, H}]),
- S2 = S#state{width = W, height = H},
- {noreply, S2};
-handle_info({'EXIT', Pid, Reason}, S) ->
- if
- Pid == S#state.parent_pid ->
- unlink(Pid),
- {stop, Reason, S};
- true ->
- {noreply, S}
- end;
-handle_info(Info, S) ->
- ok = error_logger:format("~p(~p): handle_info(~p, ~p)~n",
- [?MODULE, self(), Info, S]),
- {noreply, S}.
-
-%%----------------------------------------------------------------------
-%% Func: terminate/2
-%% Purpose: Shutdown the server
-%% Returns: any (ignored by gen_server)
-%%----------------------------------------------------------------------
-
-terminate(_Reason, _S) ->
- ignore.
-
-%%----------------------------------------------------------------------
-%% Func: code_change/3
-%% Purpose: Convert process state when code is changed
-%% Returns: {ok, NewState}
-%%----------------------------------------------------------------------
-
-code_change(_OldVsn, S, _Extra) ->
- {ok, S}.
-
-%%%----------------------------------------------------------------------
-%%% Handle graphics
-%%%----------------------------------------------------------------------
-
-create_window(S) ->
- H = S#state.height,
- W = S#state.width,
- Name = S#state.active_filter,
- Title = lists:concat([?MODULE, " (filter: ", Name, ")"]),
- WinOpt = [{title, Title}, {configure, true},
- {width, W}, {height, H}],
- GS = gs:start(),
- Win = gs:window(GS, WinOpt),
- Bar = gs:menubar(Win, []),
- create_file_menu(Bar),
- PackerOpt = [{packer_x, [{stretch, 1}]},
- {packer_y, [{stretch, 1}, {fixed, 25}]},
- {x, 0}, {y, 25}],
- Packer = gs:frame(Win, PackerOpt),
- EditorOpt = [{pack_xy, {1, 1}}, {vscroll, right}, {hscroll, bottom},
- {wrap, none},
- {bg, lightblue}, {font, {courier, 12}}],
- Editor = gs:editor(Packer, EditorOpt),
- FilteredEvent = config_editor(Editor, S),
- S2 = S#state{win = Win, packer = Packer, filtered_event = FilteredEvent},
- create_hide_menu(Bar, S2),
- create_search_menu(Bar, S2),
- create_filter_menu(Bar, S#state.filters),
- gs:config(Packer, [{width, W}, {height, H}]),
- gs:config(Win, [{map,true}, {keypress, true}]),
- S2.
-
-create_file_menu(Bar) ->
- Button = gs:menubutton(Bar, [{label, {text, "File"}}]),
- Menu = gs:menu(Button, []),
- gs:menuitem(close, Menu, [{label, {text,"Close (c)"}}]),
- gs:menuitem(save, Menu, [{label, {text,"Save"}}]).
-
-create_filter_menu(Bar, Filters) ->
- Button = gs:menubutton(Bar, [{label, {text, "Filters"}}]),
- Menu = gs:menu(Button, []),
- gs:menuitem(Menu, [{label, {text, "Select Filter"}}, {bg, lightblue}, {enable, false}]),
- gs:menuitem(Menu, [{itemtype, separator}]),
- Item = fun(F, N) when F#filter.name == collector->
- Label = lists:concat([pad_string(F#filter.name, 20), "(0)"]),
- gs:menuitem(Menu, [{label, {text, Label}}, {data, F}]),
- N + 1;
- (F, N) ->
- Name = F#filter.name,
- Label = lists:concat([pad_string(Name, 20), "(", N, ")"]),
- gs:menuitem(Menu, [{label, {text, Label}}, {data, F}]),
- N + 1
- end,
- Filters2 = lists:keysort(#filter.name, Filters),
- lists:foldl(Item, 1, Filters2),
- Menu.
-
-create_hide_menu(Bar, S) ->
- Button = gs:menubutton(Bar, [{label, {text, "Hide"}}]),
- Menu = gs:menu(Button, []),
- E = S#state.filtered_event,
- From = E#event.from,
- To = E#event.to,
- if
- S#state.viewer_pid == undefined ->
- ignore;
- From == To ->
- gs:menuitem(Menu, [{label, {text, "Hide actor in Viewer "}}, {bg, lightblue}, {enable, false}]),
- gs:menuitem(Menu, [{itemtype, separator}]),
- gs:menuitem({hide, [From]}, Menu, [{label, {text,"From=To (f|t|b)"}}]),
- gs:menuitem(Menu, [{itemtype, separator}]),
- gs:menuitem(Menu, [{label, {text, "Show actor in Viewer "}}, {bg, lightblue}, {enable, false}]),
- gs:menuitem(Menu, [{itemtype, separator}]),
- gs:menuitem({show, [From]}, Menu, [{label, {text,"From=To (F|T|B)"}}]);
- true ->
- gs:menuitem(Menu, [{label, {text, "Hide actor in Viewer "}}, {bg, lightblue}, {enable, false}]),
- gs:menuitem(Menu, [{itemtype, separator}]),
- gs:menuitem({hide, [From]}, Menu, [{label, {text,"From (f)"}}]),
- gs:menuitem({hide, [To]}, Menu, [{label, {text,"To (t)"}}]),
- gs:menuitem({hide, [From, To]}, Menu, [{label, {text,"Both (b)"}}]),
- gs:menuitem(Menu, [{itemtype, separator}]),
- gs:menuitem(Menu, [{label, {text, "Show actor in Viewer "}}, {bg, lightblue}, {enable, false}]),
- gs:menuitem(Menu, [{itemtype, separator}]),
- gs:menuitem({show, [From]}, Menu, [{label, {text,"From (F)"}}]),
- gs:menuitem({show, [To]}, Menu, [{label, {text,"To (T)"}}]),
- gs:menuitem({show, [From, To]}, Menu, [{label, {text,"Both (B)"}}])
- end.
-
-create_search_menu(Bar, S) ->
- Button = gs:menubutton(Bar, [{label, {text, "Search"}}]),
- Menu = gs:menu(Button, []),
- E = S#state.filtered_event,
- From = E#event.from,
- To = E#event.to,
- gs:menuitem(Menu, [{label, {text, "Search in Viewer "}},
- {bg, lightblue}, {enable, false}]),
- gs:menuitem(Menu, [{itemtype, separator}]),
- if
- S#state.viewer_pid == undefined ->
- S;
- From == To ->
- Key = et_collector:make_key(S#state.event_order, E),
- ModeS = {search_actors, forward, Key, [From]},
- ModeR = {search_actors, reverse, Key, [From]},
- gs:menuitem({mode, ModeS}, Menu, [{label, {text,"Forward from this event (s)"}}]),
- gs:menuitem({mode, ModeR}, Menu, [{label, {text,"Reverse from this event (r)"}}]);
- true ->
- Key = et_collector:make_key(S#state.event_order, E),
- ModeS = {search_actors, forward, Key, [From, To]},
- ModeR = {search_actors, reverse, Key, [From, To]},
- gs:menuitem({mode, ModeS}, Menu, [{label, {text,"Forward from this event (s)"}}]),
- gs:menuitem({mode, ModeR}, Menu, [{label, {text,"Reverse from this event (r)"}}])
- end,
- gs:menuitem({mode, all}, Menu, [{label, {text,"Abort search. Display all (a)"}}]).
-
-config_editor(Editor, S) ->
- Event = S#state.event,
- Name = S#state.active_filter,
- {value, F} = lists:keysearch(Name, #filter.name, S#state.filters),
- FilterFun = F#filter.function,
- case catch FilterFun(Event) of
- true ->
- do_config_editor(Editor, Event, lightblue, S#state.event_order);
- {true, Event2} when record(Event2, event) ->
- do_config_editor(Editor, Event2, lightblue, S#state.event_order);
- false ->
- do_config_editor(Editor, Event, red, S#state.event_order);
- Bad ->
- Contents = {bad_filter, Name, Bad},
- BadEvent = Event#event{contents = Contents},
- do_config_editor(Editor, BadEvent, red, S#state.event_order)
- end.
-
-do_config_editor(Editor, Event, Colour, TsKey) ->
- String = event_to_string(Event, TsKey),
- gs:config(Editor, {insert, {'end', String}}),
- gs:config(Editor, {enable, false}),
- gs:config(Editor, {bg, Colour}),
- Event.
-
-%%%----------------------------------------------------------------------
-%%% String handling
-%%%----------------------------------------------------------------------
-
-term_to_string(Term) ->
- case catch io_lib:format("~s", [Term]) of
- {'EXIT', _} -> io_lib:format("~p", [Term]);
- GoodString -> GoodString
- end.
-
-now_to_string({Mega, Sec, Micro} = Now)
- when integer(Mega), integer(Sec), integer(Micro) ->
- {{Y, Mo, D}, {H, Mi, S}} = calendar:now_to_universal_time(Now),
- lists:concat([Y, "-", Mo, "-", D, " ", H, ".", Mi, ".", S, ".", Micro]);
-now_to_string(Other) ->
- term_to_string(Other).
-
-event_to_string(Event, TsKey) ->
- ReportedTs = Event#event.trace_ts,
- ParsedTs = Event#event.event_ts,
- Deep =
- ["DETAIL LEVEL: ", term_to_string(Event#event.detail_level),
- "\nLABEL: ", term_to_string(Event#event.label),
- case Event#event.from == Event#event.to of
- true ->
- ["\nACTOR: ", term_to_string(Event#event.from)];
- false ->
- ["\nFROM: ", term_to_string(Event#event.from),
- "\nTO: ", term_to_string(Event#event.to)]
- end,
- case ReportedTs == ParsedTs of
- true ->
- ["\nPARSED: ", now_to_string(ParsedTs)];
- false ->
- case TsKey of
- trace_ts ->
- ["\nTRACE_TS: ", now_to_string(ReportedTs),
- "\nEVENT_TS: ", now_to_string(ParsedTs)];
- event_ts ->
- ["\nEVENT_TS: ", now_to_string(ParsedTs),
- "\nTRACE_TS: ", now_to_string(ReportedTs)]
- end
- end,
- "\nCONTENTS:\n\n", term_to_string(Event#event.contents)],
- lists:flatten(Deep).
-
-pad_string(Atom, MinLen) when atom(Atom) ->
- pad_string(atom_to_list(Atom), MinLen);
-pad_string(String, MinLen) when integer(MinLen), MinLen >= 0 ->
- Len = length(String),
- case Len >= MinLen of
- true ->
- String;
- false ->
- String ++ lists:duplicate(MinLen - Len, $ )
- end.
-
-send_viewer_event(S, Event) ->
- case S#state.viewer_pid of
- ViewerPid when pid(ViewerPid) ->
- ViewerPid ! {et, Event};
- undefined ->
- ignore
- end.
diff --git a/lib/et/src/et_gs_contents_viewer.erl b/lib/et/src/et_gs_contents_viewer.erl
new file mode 100644
index 0000000000..f6a87bd608
--- /dev/null
+++ b/lib/et/src/et_gs_contents_viewer.erl
@@ -0,0 +1,591 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 2000-2010. All Rights Reserved.
+%%
+%% The contents of this file are subject to the Erlang Public License,
+%% Version 1.1, (the "License"); you may not use this file except in
+%% compliance with the License. You should have received a copy of the
+%% Erlang Public License along with this software. If not, it can be
+%% retrieved online at http://www.erlang.org/.
+%%
+%% Software distributed under the License is distributed on an "AS IS"
+%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+%% the License for the specific language governing rights and limitations
+%% under the License.
+%%
+%% %CopyrightEnd%
+%%
+%%----------------------------------------------------------------------
+%% Purpose: Displays details of a trace event
+%%----------------------------------------------------------------------
+
+-module(et_gs_contents_viewer).
+
+-behaviour(gen_server).
+
+%% External exports
+-export([start_link/1,
+ stop/1]).
+
+%% gen_server callbacks
+-export([init/1, terminate/2, code_change/3,
+ handle_call/3, handle_cast/2, handle_info/2]).
+
+-include("../include/et.hrl").
+-include("et_internal.hrl").
+
+-record(state, {parent_pid, % Pid of parent process
+ viewer_pid, % Pid of viewer process
+ event_order, % Field to be used as primary key
+ event, % The original event
+ filtered_event, % Event processed by active filter
+ active_filter, % Name of the active filter
+ filters, % List of possible filters
+ win, % GUI: Window object
+ packer, % GUI: Packer object
+ width, % GUI: Window width
+ height}). % GUI: Window height
+
+%%%----------------------------------------------------------------------
+%%% Client side
+%%%----------------------------------------------------------------------
+
+%%----------------------------------------------------------------------
+%% start_link(Options) -> {ok, ContentsPid} | {error, Reason}
+%%
+%% Start an viewer for the event contents as window in GS
+%%
+%% Options = [option()]
+%%
+%% option() =
+%%
+%% {parent_pid, pid()} | % Pid of parent process
+%% {viewer_pid, pid()} | % Pid of viewer process
+%% {event_order, event_order()} | % Field to be used as primary key
+%% {active_filter, atom()} | % Name of the active filter
+%% {filter, atom(), fun()} % A named filter fun
+%%
+%% event_order() = 'trace_ts' | 'event_ts'
+%% ContentsPid = pid()
+%% Reason = term()
+%%----------------------------------------------------------------------
+
+start_link(Options) ->
+ case parse_opt(Options, default_state()) of
+ {ok, S} ->
+ case gen_server:start_link(?MODULE, [S], []) of
+ {ok, ContentsPid} when S#state.parent_pid =/= self() ->
+ unlink(ContentsPid),
+ {ok, ContentsPid};
+ Other ->
+ Other
+ end;
+ {error, Reason} ->
+ {error, Reason}
+ end.
+
+default_state() ->
+ #state{parent_pid = self(),
+ viewer_pid = undefined,
+ active_filter = ?DEFAULT_FILTER_NAME,
+ filters = [?DEFAULT_FILTER],
+ width = 600,
+ height = 300}.
+
+parse_opt([], S) ->
+ Name = S#state.active_filter,
+ Filters = S#state.filters,
+ if
+ S#state.event =:= undefined ->
+ {error, {badarg, no_event}};
+ is_atom(Name) ->
+ case lists:keysearch(Name, #filter.name, Filters) of
+ {value, F} when is_record(F, filter) ->
+ {ok, S#state{active_filter = Name}};
+ false ->
+ {error, {badarg, {no_such_filter, Name, Filters}}}
+ end
+ end;
+parse_opt([H | T], S) ->
+ case H of
+ {parent_pid, ParentPid} when is_pid(ParentPid) ->
+ parse_opt(T, S#state{parent_pid = ParentPid});
+ {viewer_pid, ViewerPid} when is_pid(ViewerPid) ->
+ parse_opt(T, S#state{viewer_pid = ViewerPid});
+ {event_order, trace_ts} ->
+ parse_opt(T, S#state{event_order = trace_ts});
+ {event_order, event_ts} ->
+ parse_opt(T, S#state{event_order = event_ts});
+ {event, Event} when is_record(Event, event) ->
+ parse_opt(T, S#state{event = Event});
+ {active_filter, Name} when is_atom(Name) ->
+ parse_opt(T, S#state{active_filter = Name});
+ F when is_record(F, filter),
+ is_atom(F#filter.name),
+ is_function(F#filter.function) ->
+ Filters = lists:keydelete(F#filter.name, #filter.name, S#state.filters),
+ Filters2 = lists:keysort(#filter.name, [F | Filters]),
+ parse_opt(T, S#state{filters = Filters2});
+ {width, Width} when is_integer(Width), Width > 0 ->
+ parse_opt(T, S#state{width = Width});
+ {height, Height} when is_integer(Height), Height > 0 ->
+ parse_opt(T, S#state{height = Height});
+ Bad ->
+ {error, {bad_option, Bad}}
+ end;
+parse_opt(BadList, _S) ->
+ {error, {bad_option_list, BadList}}.
+
+%%----------------------------------------------------------------------
+%% stop(ContentsPid) -> ok
+%%
+%% Stops a contents viewer process
+%%
+%% ContentsPid = pid()
+%%----------------------------------------------------------------------
+
+stop(ContentsPid) ->
+ unlink(ContentsPid),
+ call(ContentsPid, stop).
+
+call(ContentsPid, Request) ->
+ gen_server:call(ContentsPid, Request, infinity).
+
+%%%----------------------------------------------------------------------
+%%% Callback functions from gen_server
+%%%----------------------------------------------------------------------
+
+%%----------------------------------------------------------------------
+%% Func: init/1
+%% Returns: {ok, State} |
+%% {ok, State, Timeout} |
+%% ignore |
+%% {stop, Reason}
+%%----------------------------------------------------------------------
+
+init([S]) when is_record(S, state) ->
+ process_flag(trap_exit, true),
+ S2 = create_window(S),
+ {ok, S2}.
+
+%%----------------------------------------------------------------------
+%% Func: handle_call/3
+%% Returns: {reply, Reply, State} |
+%% {reply, Reply, State, Timeout} |
+%% {noreply, State} |
+%% {noreply, State, Timeout} |
+%% {stop, Reason, Reply, State} | (terminate/2 is called)
+%% {stop, Reason, State} (terminate/2 is called)
+%%----------------------------------------------------------------------
+
+handle_call(stop, _From, S) ->
+ unlink(S#state.parent_pid),
+ {stop, shutdown, ok, S};
+handle_call(Request, From, S) ->
+ ok = error_logger:format("~p(~p): handle_call(~p, ~p, ~p)~n",
+ [?MODULE, self(), Request, From, S]),
+ Reply = {error, {bad_request, Request}},
+ {reply, Reply, S}.
+
+%%----------------------------------------------------------------------
+%% Func: handle_cast/2
+%% Returns: {noreply, State} |
+%% {noreply, State, Timeout} |
+%% {stop, Reason, State} (terminate/2 is called)
+%%----------------------------------------------------------------------
+
+handle_cast(Msg, S) ->
+ ok = error_logger:format("~p(~p): handle_cast(~p, ~p)~n",
+ [?MODULE, self(), Msg, S]),
+ {noreply, S}.
+
+%%----------------------------------------------------------------------
+%% Func: handle_info/2
+%% Returns: {noreply, State} |
+%% {noreply, State, Timeout} |
+%% {stop, Reason, State} (terminate/2 is called)
+%%----------------------------------------------------------------------
+
+handle_info({gs, Button, click, Data, _Other}, S) ->
+ case Button of
+ close ->
+ gs:destroy(S#state.win),
+ {stop, normal, S};
+ save ->
+ Event = S#state.event,
+ Bin = list_to_binary(event_to_string(Event, S#state.event_order)),
+ TimeStamp =
+ case S#state.event_order of
+ trace_ts -> Event#event.trace_ts;
+ event_ts -> Event#event.event_ts
+ end,
+ FileName = ["et_contents_viewer_", now_to_string(TimeStamp), ".save"],
+ file:write_file(lists:flatten(FileName), Bin),
+ {noreply, S};
+ _PopupMenuItem when is_record(Data, filter) ->
+ F = Data,
+ ChildState= S#state{active_filter = F#filter.name},
+ case gen_server:start_link(?MODULE, [ChildState], []) of
+ {ok, Pid} when S#state.parent_pid =/= self() ->
+ unlink(Pid),
+ {noreply, S};
+ _ ->
+ {noreply, S}
+ end;
+ {hide, Actors} ->
+ send_viewer_event(S, {delete_actors, Actors}),
+ {noreply, S};
+ {show, Actors} ->
+ send_viewer_event(S, {insert_actors, Actors}),
+ {noreply, S};
+ {mode, Mode} ->
+ send_viewer_event(S, {mode, Mode}),
+ {noreply, S};
+ Nyi ->
+ ok = error_logger:format("~p: click ~p ignored (nyi)~n",
+ [?MODULE, Nyi]),
+ {noreply, S}
+ end;
+handle_info({gs, _Obj, destroy,_, _}, S) ->
+ unlink(S#state.parent_pid),
+ gs:destroy(S#state.win),
+ {stop, normal, S};
+handle_info({gs, _Obj, keypress, _, [KeySym, _Keycode, _Shift, _Control | _]}, S) ->
+ case KeySym of
+ 'c' ->
+ gs:destroy(S#state.win),
+ {stop, normal, S};
+
+ 'f' ->
+ E = S#state.filtered_event,
+ From = E#event.from,
+ send_viewer_event(S, {delete_actors, [From]}),
+ {noreply, S};
+ 't' ->
+ E = S#state.filtered_event,
+ To = E#event.to,
+ send_viewer_event(S, {delete_actors, [To]}),
+ {noreply, S};
+ 'b' ->
+ E = S#state.filtered_event,
+ From = E#event.from,
+ To = E#event.to,
+ send_viewer_event(S, {delete_actors, [From, To]}),
+ {noreply, S};
+
+ 'F' ->
+ E = S#state.filtered_event,
+ From = E#event.from,
+ send_viewer_event(S, {insert_actors, [From]}),
+ {noreply, S};
+ 'T' ->
+ E = S#state.filtered_event,
+ To = E#event.to,
+ send_viewer_event(S, {insert_actors, [To]}),
+ {noreply, S};
+ 'B' ->
+ E = S#state.filtered_event,
+ From = E#event.from,
+ To = E#event.to,
+ send_viewer_event(S, {insert_actors, [From, To]}),
+ {noreply, S};
+
+ 's' ->
+ E = S#state.filtered_event,
+ From = E#event.from,
+ To = E#event.to,
+ First = et_collector:make_key(S#state.event_order, E),
+ Mode = {search_actors, forward, First, [From, To]},
+ send_viewer_event(S, {mode, Mode}),
+ {noreply, S};
+ 'r' ->
+ E = S#state.filtered_event,
+ From = E#event.from,
+ To = E#event.to,
+ First = et_collector:make_key(S#state.event_order, E),
+ Mode = {search_actors, reverse, First, [From, To]},
+ send_viewer_event(S, {mode, Mode}),
+ {noreply, S};
+ 'a' ->
+ send_viewer_event(S, {mode, all}),
+ {noreply, S};
+
+ 0 ->
+ case lists:keysearch(?DEFAULT_FILTER_NAME, #filter.name, S#state.filters) of
+ {value, F} when is_record(F, filter) ->
+ ChildState= S#state{active_filter = F#filter.name},
+ case gen_server:start_link(?MODULE, [ChildState], []) of
+ {ok, Pid} when S#state.parent_pid =/= self() ->
+ unlink(Pid);
+ _ ->
+ ignore
+ end;
+ false ->
+ ignore
+ end,
+ {noreply, S};
+ Int when is_integer(Int), Int > 0, Int =< 9 ->
+ case catch lists:nth(Int, S#state.filters) of
+ F when is_record(F, filter) ->
+ ChildState= S#state{active_filter = F#filter.name},
+ case gen_server:start_link(?MODULE, [ChildState], []) of
+ {ok, Pid} when S#state.parent_pid =/= self() ->
+ unlink(Pid);
+ _ ->
+ ignore
+ end;
+ {'EXIT', _} ->
+ ignore
+ end,
+ {noreply, S};
+
+ 'Shift_L' ->
+ {noreply, S};
+ 'Shift_R' ->
+ {noreply, S};
+ 'Caps_Lock' ->
+ {noreply, S};
+ _ ->
+ io:format("~p: ignored: ~p~n", [?MODULE, KeySym]),
+ {noreply, S}
+ end;
+handle_info({gs, _Obj, configure, [], [W, H | _]}, S) ->
+ gs:config(S#state.packer, [{width, W},{height, H}]),
+ S2 = S#state{width = W, height = H},
+ {noreply, S2};
+handle_info({'EXIT', Pid, Reason}, S) ->
+ if
+ Pid =:= S#state.parent_pid ->
+ unlink(Pid),
+ {stop, Reason, S};
+ true ->
+ {noreply, S}
+ end;
+handle_info(Info, S) ->
+ ok = error_logger:format("~p(~p): handle_info(~p, ~p)~n",
+ [?MODULE, self(), Info, S]),
+ {noreply, S}.
+
+%%----------------------------------------------------------------------
+%% Func: terminate/2
+%% Purpose: Shutdown the server
+%% Returns: any (ignored by gen_server)
+%%----------------------------------------------------------------------
+
+terminate(_Reason, _S) ->
+ ignore.
+
+%%----------------------------------------------------------------------
+%% Func: code_change/3
+%% Purpose: Convert process state when code is changed
+%% Returns: {ok, NewState}
+%%----------------------------------------------------------------------
+
+code_change(_OldVsn, S, _Extra) ->
+ {ok, S}.
+
+%%%----------------------------------------------------------------------
+%%% Handle graphics
+%%%----------------------------------------------------------------------
+
+create_window(S) ->
+ H = S#state.height,
+ W = S#state.width,
+ Name = S#state.active_filter,
+ Title = lists:concat([?MODULE, " (filter: ", Name, ")"]),
+ WinOpt = [{title, Title}, {configure, true},
+ {width, W}, {height, H}],
+ GS = gs:start(),
+ Win = gs:window(GS, WinOpt),
+ Bar = gs:menubar(Win, []),
+ create_file_menu(Bar),
+ PackerOpt = [{packer_x, [{stretch, 1}]},
+ {packer_y, [{stretch, 1}, {fixed, 25}]},
+ {x, 0}, {y, 25}],
+ Packer = gs:frame(Win, PackerOpt),
+ EditorOpt = [{pack_xy, {1, 1}}, {vscroll, right}, {hscroll, bottom},
+ {wrap, none},
+ {bg, lightblue}, {font, {courier, 12}}],
+ Editor = gs:editor(Packer, EditorOpt),
+ FilteredEvent = config_editor(Editor, S),
+ S2 = S#state{win = Win, packer = Packer, filtered_event = FilteredEvent},
+ create_hide_menu(Bar, S2),
+ create_search_menu(Bar, S2),
+ create_filter_menu(Bar, S#state.filters),
+ gs:config(Packer, [{width, W}, {height, H}]),
+ gs:config(Win, [{map,true}, {keypress, true}]),
+ S2.
+
+create_file_menu(Bar) ->
+ Button = gs:menubutton(Bar, [{label, {text, "File"}}]),
+ Menu = gs:menu(Button, []),
+ gs:menuitem(close, Menu, [{label, {text,"Close (c)"}}]),
+ gs:menuitem(save, Menu, [{label, {text,"Save"}}]).
+
+create_filter_menu(Bar, Filters) ->
+ Button = gs:menubutton(Bar, [{label, {text, "Filters"}}]),
+ Menu = gs:menu(Button, []),
+ gs:menuitem(Menu, [{label, {text, "Select Filter"}}, {bg, lightblue}, {enable, false}]),
+ gs:menuitem(Menu, [{itemtype, separator}]),
+ Item = fun(F, N) when F#filter.name =:= ?DEFAULT_FILTER_NAME->
+ Label = lists:concat([pad_string(F#filter.name, 20), "(0)"]),
+ gs:menuitem(Menu, [{label, {text, Label}}, {data, F}]),
+ N + 1;
+ (F, N) ->
+ Name = F#filter.name,
+ Label = lists:concat([pad_string(Name, 20), "(", N, ")"]),
+ gs:menuitem(Menu, [{label, {text, Label}}, {data, F}]),
+ N + 1
+ end,
+ Filters2 = lists:keysort(#filter.name, Filters),
+ lists:foldl(Item, 1, Filters2),
+ Menu.
+
+create_hide_menu(Bar, S) ->
+ Button = gs:menubutton(Bar, [{label, {text, "Hide"}}]),
+ Menu = gs:menu(Button, []),
+ E = S#state.filtered_event,
+ From = E#event.from,
+ To = E#event.to,
+ if
+ S#state.viewer_pid =:= undefined ->
+ ignore;
+ From =:= To ->
+ gs:menuitem(Menu, [{label, {text, "Hide actor in Viewer "}}, {bg, lightblue}, {enable, false}]),
+ gs:menuitem(Menu, [{itemtype, separator}]),
+ gs:menuitem({hide, [From]}, Menu, [{label, {text,"From=To (f|t|b)"}}]),
+ gs:menuitem(Menu, [{itemtype, separator}]),
+ gs:menuitem(Menu, [{label, {text, "Show actor in Viewer "}}, {bg, lightblue}, {enable, false}]),
+ gs:menuitem(Menu, [{itemtype, separator}]),
+ gs:menuitem({show, [From]}, Menu, [{label, {text,"From=To (F|T|B)"}}]);
+ true ->
+ gs:menuitem(Menu, [{label, {text, "Hide actor in Viewer "}}, {bg, lightblue}, {enable, false}]),
+ gs:menuitem(Menu, [{itemtype, separator}]),
+ gs:menuitem({hide, [From]}, Menu, [{label, {text,"From (f)"}}]),
+ gs:menuitem({hide, [To]}, Menu, [{label, {text,"To (t)"}}]),
+ gs:menuitem({hide, [From, To]}, Menu, [{label, {text,"Both (b)"}}]),
+ gs:menuitem(Menu, [{itemtype, separator}]),
+ gs:menuitem(Menu, [{label, {text, "Show actor in Viewer "}}, {bg, lightblue}, {enable, false}]),
+ gs:menuitem(Menu, [{itemtype, separator}]),
+ gs:menuitem({show, [From]}, Menu, [{label, {text,"From (F)"}}]),
+ gs:menuitem({show, [To]}, Menu, [{label, {text,"To (T)"}}]),
+ gs:menuitem({show, [From, To]}, Menu, [{label, {text,"Both (B)"}}])
+ end.
+
+create_search_menu(Bar, S) ->
+ Button = gs:menubutton(Bar, [{label, {text, "Search"}}]),
+ Menu = gs:menu(Button, []),
+ E = S#state.filtered_event,
+ From = E#event.from,
+ To = E#event.to,
+ gs:menuitem(Menu, [{label, {text, "Search in Viewer "}},
+ {bg, lightblue}, {enable, false}]),
+ gs:menuitem(Menu, [{itemtype, separator}]),
+ if
+ S#state.viewer_pid =:= undefined ->
+ S;
+ From =:= To ->
+ Key = et_collector:make_key(S#state.event_order, E),
+ ModeS = {search_actors, forward, Key, [From]},
+ ModeR = {search_actors, reverse, Key, [From]},
+ gs:menuitem({mode, ModeS}, Menu, [{label, {text,"Forward from this event (s)"}}]),
+ gs:menuitem({mode, ModeR}, Menu, [{label, {text,"Reverse from this event (r)"}}]);
+ true ->
+ Key = et_collector:make_key(S#state.event_order, E),
+ ModeS = {search_actors, forward, Key, [From, To]},
+ ModeR = {search_actors, reverse, Key, [From, To]},
+ gs:menuitem({mode, ModeS}, Menu, [{label, {text,"Forward from this event (s)"}}]),
+ gs:menuitem({mode, ModeR}, Menu, [{label, {text,"Reverse from this event (r)"}}])
+ end,
+ gs:menuitem({mode, all}, Menu, [{label, {text,"Abort search. Display all (a)"}}]).
+
+config_editor(Editor, S) ->
+ Event = S#state.event,
+ Name = S#state.active_filter,
+ {value, F} = lists:keysearch(Name, #filter.name, S#state.filters),
+ FilterFun = F#filter.function,
+ case catch FilterFun(Event) of
+ true ->
+ do_config_editor(Editor, Event, lightblue, S#state.event_order);
+ {true, Event2} when is_record(Event2, event) ->
+ do_config_editor(Editor, Event2, lightblue, S#state.event_order);
+ false ->
+ do_config_editor(Editor, Event, red, S#state.event_order);
+ Bad ->
+ Contents = {bad_filter, Name, Bad},
+ BadEvent = Event#event{contents = Contents},
+ do_config_editor(Editor, BadEvent, red, S#state.event_order)
+ end.
+
+do_config_editor(Editor, Event, Colour, TsKey) ->
+ String = event_to_string(Event, TsKey),
+ gs:config(Editor, {insert, {'end', String}}),
+ gs:config(Editor, {enable, false}),
+ gs:config(Editor, {bg, Colour}),
+ Event.
+
+%%%----------------------------------------------------------------------
+%%% String handling
+%%%----------------------------------------------------------------------
+
+term_to_string(Term) ->
+ case catch io_lib:format("~s", [Term]) of
+ {'EXIT', _} -> io_lib:format("~p", [Term]);
+ GoodString -> GoodString
+ end.
+
+now_to_string({Mega, Sec, Micro} = Now)
+ when is_integer(Mega), is_integer(Sec), is_integer(Micro) ->
+ {{Y, Mo, D}, {H, Mi, S}} = calendar:now_to_universal_time(Now),
+ lists:concat([Y, "-", Mo, "-", D, " ", H, ".", Mi, ".", S, ".", Micro]);
+now_to_string(Other) ->
+ term_to_string(Other).
+
+event_to_string(Event, TsKey) ->
+ ReportedTs = Event#event.trace_ts,
+ ParsedTs = Event#event.event_ts,
+ Deep =
+ ["DETAIL LEVEL: ", term_to_string(Event#event.detail_level),
+ "\nLABEL: ", term_to_string(Event#event.label),
+ case Event#event.from =:= Event#event.to of
+ true ->
+ ["\nACTOR: ", term_to_string(Event#event.from)];
+ false ->
+ ["\nFROM: ", term_to_string(Event#event.from),
+ "\nTO: ", term_to_string(Event#event.to)]
+ end,
+ case ReportedTs =:= ParsedTs of
+ true ->
+ ["\nPARSED: ", now_to_string(ParsedTs)];
+ false ->
+ case TsKey of
+ trace_ts ->
+ ["\nTRACE_TS: ", now_to_string(ReportedTs),
+ "\nEVENT_TS: ", now_to_string(ParsedTs)];
+ event_ts ->
+ ["\nEVENT_TS: ", now_to_string(ParsedTs),
+ "\nTRACE_TS: ", now_to_string(ReportedTs)]
+ end
+ end,
+ "\nCONTENTS:\n\n", term_to_string(Event#event.contents)],
+ lists:flatten(Deep).
+
+pad_string(Atom, MinLen) when is_atom(Atom) ->
+ pad_string(atom_to_list(Atom), MinLen);
+pad_string(String, MinLen) when is_integer(MinLen), MinLen >= 0 ->
+ Len = length(String),
+ case Len >= MinLen of
+ true ->
+ String;
+ false ->
+ String ++ lists:duplicate(MinLen - Len, $ )
+ end.
+
+send_viewer_event(S, Event) ->
+ case S#state.viewer_pid of
+ ViewerPid when is_pid(ViewerPid) ->
+ ViewerPid ! {et, Event};
+ undefined ->
+ ignore
+ end.
diff --git a/lib/et/src/et_gs_viewer.erl b/lib/et/src/et_gs_viewer.erl
new file mode 100644
index 0000000000..0af7814d15
--- /dev/null
+++ b/lib/et/src/et_gs_viewer.erl
@@ -0,0 +1,1481 @@
+%%
+%% %CopyrightBegin%
+%%
+%% 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%
+%%
+%%----------------------------------------------------------------------
+%% Purpose: Displays a sequence chart for trace events (messages/actions)
+%%----------------------------------------------------------------------
+
+-module(et_gs_viewer).
+
+-behaviour(gen_server).
+
+%% External exports
+-export([start_link/1]).
+
+%% gen_server callbacks
+-export([init/1, terminate/2, code_change/3,
+ handle_call/3, handle_cast/2, handle_info/2]).
+
+-include("../include/et.hrl").
+-include("et_internal.hrl").
+
+-define(unknown, "UNKNOWN").
+
+-record(state,
+ {parent_pid, % Pid of parent process
+ collector_pid, % Pid of collector process
+ event_order, % Field to be used as primary key
+ trace_pattern, % Collector trace pattern
+ active_filter, % Name of the active filter
+ filters, % List of possible filters
+ selected_actor, % Actor selected by user
+ first_event, % Key of first event (regardless of visibility)
+ last_event, % Key of last event (regardless of visibility)
+ max_events, % Maximum number of shown events
+ events, % Queue containg all event keys (regardless of visibility)
+ max_actors, % Maximum number of shown actors
+ actors, % List of known actors
+ refresh_needed, % Refresh is needed in order to show all actors
+ display_mode, % Display all or only matching actors
+ detail_level, % Show only events with lesser detail level
+ hide_actions, % Hide/show events where to == from actor (bool)
+ hide_unknown, % Hide/show events with unknown actor (bool)
+ is_suspended, % Suspend viewer updates (bool)
+ title, % GUI: Window title
+ win, % GUI: Window object
+ menubar, % GUI: Menu bar object
+ packer, % GUI: Packer object
+ width, % GUI: Window width
+ height, % GUI: Window height
+ scale, % GUI: Scaling factor on canvas
+ font, % GUI: Font to be used on text labels
+ canvas_width, % GUI: Canvas width
+ canvas_height, % GUI: Canvas height
+ canvas, % GUI: Canvas object
+ y_pos}). % GUI: Current y position on canvas
+
+-record(actor, {name, string}).
+
+-define(initial_x, 10).
+-define(incr_x, 60).
+-define(initial_y, 15).
+-define(incr_y, 15).
+
+%%%----------------------------------------------------------------------
+%%% Client side
+%%%----------------------------------------------------------------------
+
+start_link(Options) ->
+ case parse_opt(Options, default_state(), []) of
+ {ok, S, CollectorOpt} ->
+ case S#state.collector_pid of
+ CollectorPid when is_pid(CollectorPid) ->
+ case gen_server:start_link(?MODULE, [S], []) of
+ {ok, Pid} when S#state.parent_pid =/= self() ->
+ unlink(Pid),
+ {ok, Pid};
+ Other ->
+ Other
+ end;
+ undefined ->
+ case et_collector:start_link(CollectorOpt) of
+ {ok, CollectorPid} ->
+ S2 = S#state{collector_pid = CollectorPid},
+ case gen_server:start_link(?MODULE, [S2], []) of
+ {ok, Pid} when S#state.parent_pid =/= self() ->
+ unlink(Pid),
+ {ok, Pid};
+ Other ->
+ Other
+ end;
+ {error, Reason} ->
+ {error, {et_collector, Reason}}
+ end
+ end;
+ {error, Reason} ->
+ {error, Reason}
+ end.
+
+default_state() ->
+ #state{parent_pid = self(),
+ collector_pid = undefined,
+ detail_level = ?detail_level_max,
+ active_filter = ?DEFAULT_FILTER_NAME,
+ filters = [?DEFAULT_FILTER],
+ event_order = trace_ts,
+ is_suspended = false,
+ max_events = 100,
+ first_event = first,
+ last_event = first,
+ events = queue_new(),
+ max_actors = 5,
+ actors = [create_actor(?unknown)],
+ selected_actor = ?unknown,
+ hide_actions = false,
+ hide_unknown = false,
+ refresh_needed = false,
+ display_mode = all,
+ scale = 2,
+ canvas_height = 0,
+ canvas_width = 0,
+ width = 800,
+ height = 600}.
+
+parse_opt([], S, CollectorOpt) ->
+ {ok, S, [{parent_pid, S#state.parent_pid} | CollectorOpt]};
+parse_opt([H | T], S, CollectorOpt) ->
+ case H of
+ {parent_pid, Parent} when Parent =:= undefined ->
+ CollectorOpt2 = [H | CollectorOpt],
+ parse_opt(T, S#state{parent_pid = Parent}, CollectorOpt2);
+ {parent_pid, Parent} when is_pid(Parent) ->
+ CollectorOpt2 = [H | CollectorOpt],
+ parse_opt(T, S#state{parent_pid = Parent}, CollectorOpt2);
+ {title, Title} ->
+ parse_opt(T, S#state{title = name_to_string(Title)}, CollectorOpt);
+ {detail_level, Level} when is_integer(Level),
+ Level >= ?detail_level_min,
+ Level =< ?detail_level_max ->
+ parse_opt(T, S#state{detail_level = Level}, CollectorOpt);
+ {detail_level, max} ->
+ parse_opt(T, S#state{detail_level = ?detail_level_max}, CollectorOpt);
+ {detail_level, min} ->
+ parse_opt(T, S#state{detail_level = ?detail_level_min}, CollectorOpt);
+ {is_suspended, true} ->
+ parse_opt(T, S#state{is_suspended = true}, CollectorOpt);
+ {is_suspended, false} ->
+ parse_opt(T, S#state{is_suspended = false}, CollectorOpt);
+ {scale, Scale} when is_integer(Scale), Scale > 0 ->
+ parse_opt(T, S#state{scale = Scale}, CollectorOpt);
+ {width, W} when is_integer(W), W > 0 ->
+ parse_opt(T, S#state{width = W, canvas_width = W}, CollectorOpt);
+ {height, WH} when is_integer(WH), WH > 0 ->
+ parse_opt(T, S#state{height = WH, canvas_height = WH}, CollectorOpt);
+ {collector_pid, Pid} when is_pid(Pid) ->
+ parse_opt(T, S#state{collector_pid = Pid}, CollectorOpt);
+ {collector_pid, undefined} ->
+ parse_opt(T, S#state{collector_pid = undefined}, CollectorOpt);
+ {active_filter, Name} when is_atom(Name) ->
+ parse_opt(T, S#state{active_filter = Name}, CollectorOpt);
+ {event_order, trace_ts} -> %% BUGBUG: Verify event_order with collector
+ CollectorOpt2 = [H | CollectorOpt],
+ parse_opt(T, S#state{event_order = trace_ts}, CollectorOpt2);
+ {event_order, event_ts} -> %% BUGBUG: Verify event_order with collector
+ CollectorOpt2 = [H | CollectorOpt],
+ parse_opt(T, S#state{event_order = event_ts}, CollectorOpt2);
+ {trace_port, _Port} ->
+ CollectorOpt2 = [H | CollectorOpt],
+ parse_opt(T, S, CollectorOpt2);
+ {trace_max_queue, _Queue} ->
+ CollectorOpt2 = [H | CollectorOpt],
+ parse_opt(T, S, CollectorOpt2);
+ {trace_pattern, _Pattern} ->
+ CollectorOpt2 = [H | CollectorOpt],
+ parse_opt(T, S, CollectorOpt2);
+ {trace_global, _Boolean} ->
+ CollectorOpt2 = [H | CollectorOpt],
+ parse_opt(T, S, CollectorOpt2);
+ {trace_client, _Client} ->
+ CollectorOpt2 = [H | CollectorOpt],
+ parse_opt(T, S, CollectorOpt2);
+ {dict_insert, {filter, Name}, Fun} ->
+ if
+ is_atom(Name), is_function(Fun) ->
+ F = #filter{name = Name, function = Fun},
+ Filters = lists:keydelete(Name, #filter.name, S#state.filters),
+ CollectorOpt2 = [H | CollectorOpt],
+ parse_opt(T, S#state{filters = Filters ++ [F]}, CollectorOpt2);
+ true ->
+ {error, {bad_option, H}}
+ end;
+ {dict_insert, {subscriber, Pid}, _Val} ->
+ if
+ is_pid(Pid) ->
+ CollectorOpt2 = [H | CollectorOpt],
+ parse_opt(T, S, CollectorOpt2);
+ true ->
+ {error, {bad_option, H}}
+ end;
+ {dict_insert, _Key, _Val} ->
+ CollectorOpt2 = [H | CollectorOpt],
+ parse_opt(T, S, CollectorOpt2);
+ {dict_delete, {filter, Name}} ->
+ Filters = lists:keydelete(Name, #filter.name, S#state.filters),
+ CollectorOpt2 = [H | CollectorOpt],
+ parse_opt(T, S#state{filters = Filters}, CollectorOpt2);
+ {dict_delete, _Key} ->
+ CollectorOpt2 = [H | CollectorOpt],
+ parse_opt(T, S, CollectorOpt2);
+ {max_events, Max} when is_integer(Max), Max > 0->
+ parse_opt(T, S#state{max_events = Max}, CollectorOpt);
+ {max_events, Max} when Max =:= infinity ->
+ parse_opt(T, S#state{max_events = Max}, CollectorOpt);
+ {max_actors, Max} when is_integer(Max), Max >= 0->
+ parse_opt(T, S#state{max_actors = Max}, CollectorOpt);
+ {max_actors, Max} when Max =:= infinity ->
+ parse_opt(T, S#state{max_actors = Max}, CollectorOpt);
+ {actors, ActorNames} when is_list(ActorNames) ->
+ ActorNames2 =
+ case lists:member(?unknown, ActorNames) of
+ false -> [?unknown | ActorNames];
+ true -> ActorNames
+ end,
+ Actors = [create_actor(Name) || Name <- ActorNames2],
+ parse_opt(T, S#state{actors = Actors}, CollectorOpt);
+ {first_event, First} ->
+ parse_opt(T, S#state{first_event = First}, CollectorOpt);
+ {hide_unknown, Bool} when Bool =:= false ->
+ parse_opt(T, S#state{hide_unknown = Bool}, CollectorOpt);
+ {hide_unknown, Bool} when Bool =:= true ->
+ parse_opt(T, S#state{hide_unknown = Bool}, CollectorOpt);
+ {hide_actions, Bool} when Bool =:= false ->
+ parse_opt(T, S#state{hide_actions = Bool}, CollectorOpt);
+ {hide_actions, Bool} when Bool =:= true ->
+ parse_opt(T, S#state{hide_actions = Bool}, CollectorOpt);
+ {display_mode, Mode = all} ->
+ parse_opt(T, S#state{display_mode = Mode}, CollectorOpt);
+ {display_mode, Mode = {search_actors, Dir, _Key, Actors}} when is_list(Actors), Dir =:= forward ->
+ parse_opt(T, S#state{display_mode = Mode}, CollectorOpt);
+ {display_mode, Mode = {search_actors, Dir, _Key, Actors}} when is_list(Actors), Dir =:= reverse ->
+ parse_opt(T, S#state{display_mode = Mode}, CollectorOpt);
+
+ Bad ->
+ {error, {bad_option, Bad}}
+ end;
+parse_opt(BadList, _S, _CollectorOpt) ->
+ {error, {bad_option_list, BadList}}.
+
+do_dict_insert({filter, Name}, Fun, S) when is_atom(Name), is_function(Fun) ->
+ F = #filter{name = Name, function = Fun},
+ Filters = lists:keydelete(Name, #filter.name, S#state.filters),
+ Filters2 = lists:keysort(#filter.name, [F | Filters]),
+ gs:destroy(filter_menu),
+ create_filter_menu(S#state.active_filter, Filters2),
+ S#state{filters = Filters2};
+do_dict_insert(_Key, _Val, S) ->
+ %% ok = error_logger:format("~p(~p): handle_info({et, {dict_insert, ~p, ~p}})~n",
+ %% [?MODULE, self(), Key, Val]),
+ S.
+
+do_dict_delete({filter, Name}, S) when is_atom(Name), Name =/= S#state.active_filter ->
+ Filters = lists:keydelete(Name, #filter.name, S#state.filters),
+ gs:destroy(filter_menu),
+ create_filter_menu(S#state.active_filter, Filters),
+ S#state{filters = Filters};
+do_dict_delete(_Key, S) ->
+ %% ok = error_logger:format("~p(~p): handle_info({et, {dict_delete, ~p}})~n",
+ %% [?MODULE, self(), Key]),
+ S.
+
+%%%----------------------------------------------------------------------
+%%% Callback functions from gen_server
+%%%----------------------------------------------------------------------
+
+%%----------------------------------------------------------------------
+%% Func: init/1
+%% Returns: {ok, State} |
+%% {ok, State, Timeout} |
+%% ignore |
+%% {stop, Reason}
+%%----------------------------------------------------------------------
+
+init([S]) when is_record(S, state) ->
+ process_flag(trap_exit, true),
+ InitialTimeout = 0,
+ case S#state.parent_pid of
+ undefined ->
+ ignore;
+ Pid when is_pid(Pid) ->
+ link(Pid)
+ end,
+ et_collector:dict_insert(S#state.collector_pid,
+ {subscriber, self()},
+ ?MODULE),
+ {ok, create_main_window(S), InitialTimeout}.
+
+%%----------------------------------------------------------------------
+%% Func: handle_call/3
+%% Returns: {reply, Reply, State} |
+%% {reply, Reply, State, Timeout} |
+%% {noreply, State} |
+%% {noreply, State, Timeout} |
+%% {stop, Reason, Reply, State} | (terminate/2 is called)
+%% {stop, Reason, State} (terminate/2 is called)
+%%----------------------------------------------------------------------
+
+handle_call(get_collector_pid, _From, S) ->
+ Reply = S#state.collector_pid,
+ reply(Reply, S);
+handle_call(stop, _From, S) ->
+ gs:destroy(S#state.win),
+ {stop, shutdown, ok, S};
+handle_call(Request, From, S) ->
+ ok = error_logger:format("~p(~p): handle_call(~p, ~p, ~p)~n",
+ [?MODULE, self(), Request, From, S]),
+ Reply = {error, {bad_request, Request}},
+ reply(Reply, S).
+
+%%----------------------------------------------------------------------
+%% Func: handle_cast/2
+%% Returns: {noreply, State} |
+%% {noreply, State, Timeout} |
+%% {stop, Reason, State} (terminate/2 is called)
+%%----------------------------------------------------------------------
+
+handle_cast(Msg, S) ->
+ ok = error_logger:format("~p(~p): handle_cast(~p, ~p)~n",
+ [?MODULE, self(), Msg, S]),
+ noreply(S).
+
+%%----------------------------------------------------------------------
+%% Func: handle_info/2
+%% Returns: {noreply, State} |
+%% {noreply, State, Timeout} |
+%% {stop, Reason, State} (terminate/2 is called)
+%%----------------------------------------------------------------------
+
+handle_info({et, {more_events, _Size}}, S) ->
+ noreply(S);
+handle_info({et, {insert_actors, ActorNames}}, S) when is_list(ActorNames) ->
+ Fun = fun(N, Actors) ->
+ case lists:keymember(N, #actor.name, Actors) of
+ true -> Actors;
+ false -> Actors ++ [create_actor(N)]
+ end
+ end,
+ Actors = lists:foldl(Fun, S#state.actors, ActorNames),
+ S2 = refresh_main_window(S#state{actors = Actors}),
+ noreply(S2);
+handle_info({et, {delete_actors, ActorNames}}, S) when is_list(ActorNames)->
+ Fun = fun(N, Actors) when N =:= ?unknown ->
+ Actors;
+ (N, Actors) ->
+ lists:keydelete(N, #actor.name, Actors)
+ end,
+ New = lists:foldl(Fun, S#state.actors, ActorNames),
+ S2 = refresh_main_window(S#state{actors = New}),
+ noreply(S2);
+handle_info({et, {dict_insert, Key, Val}}, S) ->
+ S2 = do_dict_insert(Key, Val, S),
+ noreply(S2);
+handle_info({et, {dict_delete, Key}}, S) ->
+ S2 = do_dict_delete(Key, S),
+ noreply(S2);
+handle_info({et, first}, S) ->
+ S2 = scroll_first(S),
+ noreply(S2);
+handle_info({et, prev}, S) ->
+ S2 = scroll_prev(S),
+ noreply(S2);
+handle_info({et, next}, S) ->
+ S2 = scroll_next(S),
+ noreply(S2);
+handle_info({et, last}, S) ->
+ S2 = scroll_last(S),
+ noreply(S2);
+handle_info({et, refresh}, S) ->
+ S2 = refresh_main_window(S),
+ noreply(S2);
+handle_info({et, {display_mode, Mode}}, S) ->
+ S2 = change_display_mode(Mode, S),
+ noreply(S2);
+handle_info({et, close}, S) ->
+ gs:destroy(S#state.win),
+ {stop, shutdown, S};
+handle_info({gs, Button, click, Data, Other} = Click, S) ->
+ CollectorPid = S#state.collector_pid,
+ case Button of
+ close ->
+ gs:destroy(S#state.win),
+ {stop, shutdown, S};
+ suspended ->
+ case Other of
+ [_Text, _Group, Bool | _] when Bool =:= true ->
+ S2 = do_suspend(S),
+ noreply(S2);
+ [_Text, _Group, Bool | _] when Bool =:= false ->
+ S2 = do_resume(S),
+ noreply(S2);
+ _ ->
+ click_error(Click, S),
+ noreply(S)
+ end;
+ hide_actions ->
+ case Other of
+ [_Text, _Group, Bool | _] when Bool =:= true ->
+ S2 = refresh_main_window(S#state{hide_actions = Bool}),
+ noreply(S2);
+ [_Text, _Group, Bool | _] when Bool =:= false ->
+ S2 = refresh_main_window(S#state{hide_actions = Bool}),
+ noreply(S2);
+ _ ->
+ click_error(Click, S),
+ noreply(S)
+ end;
+ hide_unknown ->
+ case Other of
+ [_Text, _Group, Bool | _] when Bool =:= true ->
+ S2 = refresh_main_window(S#state{hide_unknown = Bool}),
+ noreply(S2);
+ [_Text, _Group, Bool | _] when Bool =:= false ->
+ S2 = refresh_main_window(S#state{hide_unknown = Bool}),
+ noreply(S2);
+ _ ->
+ click_error(Click, S),
+ noreply(S)
+ end;
+ up ->
+ S2 = scroll_up(S),
+ noreply(S2);
+ down ->
+ S2 = scroll_down(S),
+ noreply(S2);
+ first ->
+ S2 = scroll_first(S),
+ noreply(S2);
+ prev ->
+ S2 = scroll_prev(S),
+ noreply(S2);
+ next ->
+ S2 = scroll_next(S),
+ noreply(S2);
+ last ->
+ S2 = scroll_last(S),
+ noreply(S2);
+ refresh ->
+ S2 = refresh_main_window(S),
+ noreply(S2);
+ {display_mode, Mode} ->
+ S2 = change_display_mode(Mode, S),
+ noreply(S2);
+ close_all ->
+ close_all(S);
+ close_all_others ->
+ close_all_others(S);
+ first_all ->
+ et_collector:multicast(CollectorPid, first),
+ noreply(S);
+ prev_all ->
+ et_collector:multicast(CollectorPid, prev),
+ noreply(S);
+ next_all ->
+ et_collector:multicast(CollectorPid, next),
+ noreply(S);
+ last_all ->
+ et_collector:multicast(CollectorPid, last),
+ noreply(S);
+ refresh_all ->
+ et_collector:multicast(CollectorPid, refresh),
+ noreply(S);
+ clear_all ->
+ et_collector:clear_table(CollectorPid),
+ et_collector:multicast(CollectorPid, refresh),
+ noreply(S);
+ load_all ->
+ et_collector:start_trace_client(CollectorPid, event_file, "et_viewer.log"),
+ noreply(S);
+ save_all ->
+ et_collector:save_event_file(CollectorPid,
+ "et_viewer.log",
+ [existing, write, keep]),
+ noreply(S);
+ {open_viewer, Scale} ->
+ Actors = [A#actor.name || A <- S#state.actors],
+ open_viewer(Scale, S#state.active_filter, Actors, S),
+ noreply(S);
+ _Level when Data =:= detail_level, is_integer(hd(Other)),
+ hd(Other) >= ?detail_level_min,
+ hd(Other) =< ?detail_level_max ->
+ S2 = S#state{detail_level = hd(Other)},
+ noreply(S2);
+ _PopupMenuItem when is_record(Data, filter) ->
+ open_viewer(S#state.scale, Data#filter.name, [?unknown], S),
+ noreply(S);
+ _ ->
+ click_error(Click, S),
+ noreply(S)
+ end;
+handle_info({gs, _Obj, destroy,_, _}, S) ->
+ gs:destroy(S#state.win),
+ {stop, shutdown, S};
+handle_info({gs, _Obj, buttonpress, _, [_Button, X, Y | _]}, S) ->
+ S3 =
+ case y_to_n(Y, S) of
+ actor ->
+ %% Actor click
+ case S#state.actors of
+ [] ->
+ S;
+ _ ->
+ N = x_to_n(X, S),
+ A = lists:nth(N, S#state.actors),
+ S#state{selected_actor = A}
+ end;
+ {event, N} ->
+ %% Event click
+ List = queue_to_list(S#state.events),
+ S2 = S#state{events = list_to_queue(List)},
+
+ Key = lists:nth(N, List),
+ Pid = S#state.collector_pid,
+ Fun = fun create_contents_window/2,
+ case et_collector:iterate(Pid, Key, -1) of
+ Prev when Prev =:= Key ->
+ et_collector:iterate(Pid, first, 1, Fun, S2);
+ Prev ->
+ et_collector:iterate(Pid, Prev, 1, Fun, S2)
+ end
+ end,
+ noreply(S3);
+handle_info({gs, _Obj, buttonrelease, _, [_Button, X, Y | _]}, S) ->
+ S2 =
+ case y_to_n(Y, S) of
+ actor ->
+ %% Actor click
+ case S#state.actors of
+ [] ->
+ S;
+ Actors ->
+ N = x_to_n(X, S),
+ New = lists:nth(N, S#state.actors),
+ Old = S#state.selected_actor,
+ case New#actor.name =:= Old#actor.name of
+ true ->
+ A = S#state.selected_actor,
+ toggle_search_for_actor(A#actor.name, S);
+ false ->
+ move_actor(Old, New, Actors, S)
+ end
+ end;
+ {event, _N} ->
+ %% Event click ignored
+ S
+ end,
+ noreply(S2);
+handle_info({gs, _Obj, keypress, _, [KeySym, _Keycode, _Shift, _Control | _]} = Key, S) ->
+ case KeySym of
+ 'c' ->
+ close_all_others(S);
+ 'C' ->
+ close_all(S);
+ 'Up' ->
+ S2 = scroll_up(S),
+ noreply(S2);
+ 'Down' ->
+ S2 = scroll_down(S),
+ noreply(S2);
+ 'f' ->
+ S2 = scroll_first(S),
+ noreply(S2);
+ 'p' ->
+ S2 = scroll_prev(S),
+ noreply(S2);
+ 'Prior' ->
+ S2 = scroll_prev(S),
+ noreply(S2);
+ 'n' ->
+ S2 = scroll_next(S),
+ noreply(S2);
+ 'Next' ->
+ S2 = scroll_next(S),
+ noreply(S2);
+ 'l' ->
+ S2 = scroll_last(S),
+ noreply(S2);
+ 'r' ->
+ S2 = refresh_main_window(S),
+ noreply(S2);
+ 'F' ->
+ et_collector:multicast(S#state.collector_pid, first),
+ noreply(S);
+ 'P' ->
+ et_collector:multicast(S#state.collector_pid, prev),
+ noreply(S);
+ 'N' ->
+ et_collector:multicast(S#state.collector_pid, next),
+ noreply(S);
+ 'L' ->
+ et_collector:multicast(S#state.collector_pid, last),
+ noreply(S);
+ 'R' ->
+ et_collector:multicast(S#state.collector_pid, refresh),
+ noreply(S);
+
+ 'a' ->
+ S2 = S#state{display_mode = all},
+ S3 = refresh_main_window(S2),
+ noreply(S3);
+
+ 'equal' ->
+ Scale = S#state.scale,
+ Actors = [A#actor.name || A <- S#state.actors],
+ open_viewer(Scale, S#state.active_filter, Actors, S),
+ noreply(S);
+ 'plus' ->
+ Scale = S#state.scale + 1,
+ Actors = [A#actor.name || A <- S#state.actors],
+ open_viewer(Scale, S#state.active_filter, Actors, S),
+ noreply(S);
+ 'minus' ->
+ case S#state.scale of
+ 1 ->
+ gs:config(S#state.canvas, beep);
+ Scale ->
+ Actors = [A#actor.name || A <- S#state.actors],
+ open_viewer(Scale - 1, S#state.active_filter, Actors, S)
+ end,
+ noreply(S);
+ 0 ->
+ case lists:keysearch(?DEFAULT_FILTER_NAME, #filter.name, S#state.filters) of
+ {value, F} when is_record(F, filter) ->
+ open_viewer(S#state.scale, F#filter.name, [?unknown], S);
+ false ->
+ gs:config(S#state.canvas, beep)
+ end,
+ noreply(S);
+ Int when is_integer(Int), Int > 0, Int =< 9 ->
+ case catch lists:nth(Int, S#state.filters) of
+ F when is_record(F, filter) ->
+ open_viewer(S#state.scale, F#filter.name, [?unknown], S);
+ {'EXIT', _} ->
+ gs:config(S#state.canvas, beep)
+ end,
+ noreply(S);
+
+ 'Shift_L' ->
+ noreply(S);
+ 'Shift_R' ->
+ noreply(S);
+ 'Caps_Lock' ->
+ noreply(S);
+
+ _ ->
+ click_error(Key, S),
+ noreply(S)
+ end;
+handle_info({gs, _Obj,configure, [], [W, H | _]}, S) ->
+ gs:config(S#state.packer, [{width, W}, {height, H}]),
+ S2 = S#state{width = W, height = H},
+ noreply(S2);
+handle_info(timeout, S) ->
+ Try =
+ case S#state.display_mode of
+ {search_actors, reverse, _, _} ->
+ -10;
+ _ ->
+ 10
+ end,
+ if
+ S#state.is_suspended =:= true ->
+ {noreply, S, infinity};
+ S#state.max_events =:= infinity ->
+ display_more_events(Try, S);
+ true ->
+ Needed = S#state.max_events - queue_length(S#state.events),
+ if
+ Needed =< 0 -> {noreply, S, infinity};
+ Needed > 10 -> display_more_events(Try, S);
+ Needed =< 10 -> display_more_events(Needed, S)
+ end
+ end;
+
+handle_info({'EXIT', Pid, Reason}, S) ->
+ if
+ Pid =:= S#state.collector_pid ->
+ unlink(Pid),
+ gs:destroy(S#state.win),
+ {stop, Reason, S};
+ Pid =:= S#state.parent_pid ->
+ unlink(Pid),
+ gs:destroy(S#state.win),
+ {stop, Reason, S};
+ true ->
+ noreply(S)
+ end;
+handle_info(Info, S) ->
+ ok = error_logger:format("~p(~p): handle_info(~p, ~p)~n",
+ [?MODULE, self(), Info, S]),
+ noreply(S).
+
+%%----------------------------------------------------------------------
+%% Func: terminate/2
+%% Purpose: Shutdown the server
+%% Returns: any (ignored by gen_server)
+%%----------------------------------------------------------------------
+
+terminate(_Reason, _S) ->
+ ignore.
+
+%%----------------------------------------------------------------------
+%% Func: code_change/3
+%% Purpose: Convert process state when code is changed
+%% Returns: {ok, NewState}
+%%----------------------------------------------------------------------
+
+code_change(_OldVsn, S, _Extra) ->
+ {ok, S}.
+
+%%%----------------------------------------------------------------------
+%%% Handle suspend/resume
+%%%----------------------------------------------------------------------
+
+reply(Reply, S) ->
+ case queue_length(S#state.events) of
+ _ when S#state.is_suspended =:= true ->
+ {reply, Reply, S, infinity};
+ _ when S#state.max_events =:= infinity ->
+ {reply, Reply, S, 500};
+ N when N >= S#state.max_events ->
+ {reply, Reply, S, infinity};
+ _ ->
+ {reply, Reply, S, 0}
+ end.
+
+noreply(S) ->
+ case queue_length(S#state.events) of
+ _ when S#state.is_suspended =:= true ->
+ {noreply, S, infinity};
+ _ when S#state.max_events =:= infinity ->
+ {noreply, S, 500};
+ N when N >= S#state.max_events ->
+ {noreply, S, infinity};
+ _ ->
+ {noreply, S, 0}
+ end.
+
+do_suspend(S) ->
+ config_suspend(S#state{is_suspended = true}).
+
+do_resume(S) ->
+ config_suspend(S#state{is_suspended = false}).
+
+config_suspend(S) ->
+ Suspended = S#state.is_suspended,
+ gs:config(refresh, [{enable, not Suspended}]),
+ gs:config(refresh_all, [{enable, not Suspended}]),
+ gs:config(clear_all, [{enable, not Suspended}]),
+ S.
+
+refresh_main_window(S) ->
+ Pid = S#state.collector_pid,
+ Key = S#state.first_event,
+ case et_collector:iterate(Pid, Key, -1) of
+ Prev when Prev =:= Key ->
+ scroll_first(S);
+ _Prev ->
+ S2 = S#state{last_event = S#state.first_event},
+ clear_canvas(S2)
+ end.
+
+scroll_first(S) ->
+ S2 = S#state{first_event = first, last_event = first},
+ clear_canvas(S2).
+
+scroll_prev(S) ->
+ Try =
+ case S#state.max_events of
+ infinity -> -10;
+ Max -> -Max
+ end,
+ Key = et_collector:iterate(S#state.collector_pid, S#state.first_event, Try),
+ S2 = S#state{first_event = Key, last_event = Key},
+ clear_canvas(S2).
+
+scroll_next(S) ->
+ S2 = S#state{first_event = S#state.last_event},
+ clear_canvas(S2).
+
+scroll_up(S) ->
+ Key = et_collector:iterate(S#state.collector_pid, S#state.first_event, -5),
+ S2 = S#state{first_event = Key, last_event = Key},
+ clear_canvas(S2).
+
+scroll_down(S) ->
+ Key = et_collector:iterate(S#state.collector_pid, S#state.first_event, 5),
+ S2 = S#state{first_event = Key, last_event = Key},
+ clear_canvas(S2).
+
+scroll_last(S) ->
+ S2 = S#state{first_event = last, last_event = last},
+ clear_canvas(S2).
+
+change_display_mode(Mode, S) ->
+ case Mode of
+ all ->
+ S2 = S#state{display_mode = Mode},
+ refresh_main_window(S2);
+ {search_actors, _Dir, _Key, []} ->
+ S2 = S#state{display_mode = all},
+ refresh_main_window(S2);
+ {search_actors, _Dir, Key, Actors} when is_list(Actors) ->
+ Pid = S#state.collector_pid,
+ Prev = et_collector:iterate(Pid, Key, -1),
+ S2 = S#state{first_event = Prev,
+ last_event = Prev,
+ display_mode = Mode},
+ clear_canvas(S2)
+ end.
+
+close_all(S) ->
+ et_collector:multicast(S#state.collector_pid, close),
+ timer:sleep(timer:seconds(1)),
+ spawn(et_collector, stop, [S#state.collector_pid]),
+ gs:destroy(S#state.win),
+ {stop, shutdown, S}.
+
+close_all_others(S) ->
+ Fun =
+ fun({{subscriber, Pid}, _}) ->
+ if
+ Pid =:= self() ->
+ ignore;
+ true ->
+ unlink(Pid),
+ Pid ! {et, close}
+ end
+ end,
+ All = et_collector:dict_match(S#state.collector_pid,
+ {{subscriber, '_'}, '_'}),
+ lists:foreach(Fun, All),
+ noreply(S).
+
+click_error(Click, S) ->
+ gs:config(S#state.canvas, beep),
+ io:format("~p: ignored: ~p~n", [?MODULE, Click]).
+
+%%%----------------------------------------------------------------------
+%%% Clone viewer
+%%%----------------------------------------------------------------------
+
+open_viewer(Scale, FilterName, Actors, S) ->
+ Filters = [{dict_insert, {filter, F#filter.name}, F#filter.function}
+ || F <- S#state.filters],
+ Options =
+ [{parent_pid, S#state.parent_pid},
+ {title, S#state.title},
+ {collector_pid, S#state.collector_pid},
+ {is_suspended, S#state.is_suspended},
+ {detail_level, S#state.detail_level},
+ {active_filter, FilterName},
+ {event_order, S#state.event_order},
+ {first_event, S#state.first_event},
+ {max_events, S#state.max_events},
+ {max_actors, S#state.max_actors},
+ {hide_actions, S#state.hide_actions},
+ {hide_unknown, S#state.hide_unknown},
+ {is_suspended, S#state.is_suspended},
+ {actors, Actors},
+ {scale, Scale},
+ {width, S#state.width},
+ {height, S#state.height} | Filters],
+ case start_link(Options) of
+ {ok, ViewerPid} ->
+ unlink(ViewerPid),
+ ok;
+ {error, Reason} ->
+ ok = error_logger:format("~p: Failed to start a new window: ~p~n",
+ [?MODULE, Reason])
+ end.
+
+%%%----------------------------------------------------------------------
+%%% Handle graphics
+%%%----------------------------------------------------------------------
+
+create_main_window(S) ->
+ Font = select_font(S#state.scale),
+ GS = gs:start(),
+ Name = name_to_string(S#state.active_filter),
+ Title = case S#state.title of
+ undefined -> atom_to_list(?MODULE);
+ Explicit -> name_to_string(Explicit)
+ end,
+ WinOpt = [{title, Title ++ " (filter: " ++ Name ++ ")"},
+ {configure, true},
+ {width, S#state.width},
+ {height, S#state.height}],
+ Win = gs:window(GS, WinOpt),
+ Bar = gs:menubar(Win, []),
+
+ create_file_menu(Bar),
+ create_viewer_menu(Bar),
+ create_collector_menu(Bar),
+ gs:menubutton(filter_button, Bar, [{label, {text, "Filter"}}]),
+ create_filter_menu(S#state.active_filter, S#state.filters),
+ create_help_menu(Bar),
+
+ config_suspend(S),
+
+ PackerOpt = [{packer_x, [{fixed, 5}, {fixed, 40}, {fixed, 40},
+ {stretch, 1}, {fixed, 5}]},
+ {packer_y, [{fixed, 30}, {fixed, 30},
+ {stretch, 1}, {fixed, 30}]},
+ {x, 0}, {y, 30}],
+ Packer = gs:frame(Win, PackerOpt),
+ gs:checkbutton(suspended, Packer, [{label,{text,"Freeze"}},
+ {x, 10}, {y, 0},
+ {width, 120}, {align, w},
+ {select, S#state.is_suspended}]),
+ gs:checkbutton(hide_actions, Packer, [{label,{text,"Hide From=To"}},
+ {x, 10}, {y, 20},
+ {width, 120}, {align, w},
+ {select, S#state.hide_actions}]),
+ gs:checkbutton(hide_unknown, Packer, [{label,{text,"Hide Unknown"}},
+ {x, 10}, {y, 40},
+ {width, 120}, {align, w},
+ {select, S#state.hide_unknown}]),
+ gs:scale(Packer, [{text,"Detail Level"},
+ {range, {?detail_level_min, ?detail_level_max}},
+ {orient, horizontal},
+ {x, 150}, {y, 0}, {height, 65}, {width, 200},
+ {pos, S#state.detail_level}, {data, detail_level}]),
+ CanvasW = calc_canvas_width(S),
+ CanvasH = calc_canvas_height(S),
+ CanOpt = [{pack_xy, {{2, 4}, 3}}, {vscroll, right}, {hscroll, bottom},
+ {scrollregion, {2, 2, CanvasW, CanvasH}}],
+ Canvas = gs:canvas(Packer, CanOpt),
+ gs:config(Canvas, [{buttonpress, true}, {buttonrelease, true}]),
+ gs:config(Packer, [{width, S#state.width}, {height, S#state.height}]),
+ gs:config(Win, [{map, true}, {keypress, true}]),
+ S2 = S#state{title = Title,
+ win = Win, font = Font, packer = Packer,
+ canvas_width = CanvasW, canvas_height = CanvasH,
+ canvas = Canvas,
+ y_pos = ?initial_y * S#state.scale},
+ draw_all_actors(S2).
+
+select_font(Scale) when is_integer(Scale) ->
+ case Scale of
+ 1 -> {courier, 7};
+ 2 -> {courier, 10};
+ 3 -> {courier, 12};
+ 4 -> {courier, 14};
+ S -> {courier, S * 4}
+ end.
+
+create_file_menu(Bar) ->
+ Button = gs:menubutton(Bar, [{label, {text, "File"}}]),
+ Menu = gs:menu(Button, []),
+ gs:menuitem(close_all, Menu, [{label, {text, "Close Collector and all Viewers (C) "}}]),
+ gs:menuitem(close_all_others, Menu, [{label, {text, "Close other Viewers, but keep Collector (c)"}}]),
+ gs:menuitem(close, Menu, [{label, {text, "Close this Viewer, but keep Collector"}}]),
+ gs:menuitem(Menu, [{itemtype, separator}]),
+
+ gs:menuitem(clear_all, Menu, [{label, {text, "Clear Collector"}}]),
+ gs:menuitem(load_all, Menu, [{label, {text, "Load Collector from the file \"et_viewer.log\""}}]),
+ gs:menuitem(save_all, Menu, [{label, {text, "Save Collector to the file \"et_viewer.log\""}}]).
+
+create_viewer_menu(Bar) ->
+ Button = gs:menubutton(Bar, [{label, {text, "Viewer"}}]),
+ Menu = gs:menu(Button, []),
+ gs:menuitem(Menu, [{label, {text, "Scroll this Viewer"}}, {bg, lightblue}, {enable,false}]),
+ gs:menuitem(Menu, [{itemtype, separator}]),
+ gs:menuitem(first, Menu, [{label, {text, "First (f)"}}]),
+ gs:menuitem(prev, Menu, [{label, {text, "Prev (p)"}}]),
+ gs:menuitem(next, Menu, [{label, {text, "Next (n)"}}]),
+ gs:menuitem(last, Menu, [{label, {text, "Last (l)"}}]),
+ gs:menuitem(refresh, Menu, [{label, {text, "Refresh (r)"}}]),
+ gs:menuitem(Menu, [{itemtype, separator}]),
+ gs:menuitem(up, Menu, [{label, {text, "Up 5 (Up)"}}]),
+ gs:menuitem(down, Menu, [{label, {text, "Down 5 (Down)"}}]),
+ gs:menuitem(Menu, [{itemtype, separator}]),
+ gs:menuitem(Menu, [{label, {text, "Search in this Viewer"}}, {bg, lightblue}, {enable,false}]),
+ gs:menuitem(Menu, [{itemtype, separator}]),
+ gs:menuitem({mode, all}, Menu, [{label, {text, "Abort search. Display all (a)"}}]).
+
+create_collector_menu(Bar) ->
+ Button = gs:menubutton(Bar, [{label, {text, "Collector"}}]),
+ Menu = gs:menu(Button, []),
+ gs:menuitem(Menu, [{label, {text, "Scroll all Viewers"}}, {bg, lightblue}, {enable,false}]),
+ gs:menuitem(Menu, [{itemtype, separator}]),
+ gs:menuitem(first_all, Menu, [{label, {text, "First (F)"}}]),
+ gs:menuitem(prev_all, Menu, [{label, {text, "Prev (P)"}}]),
+ gs:menuitem(next_all, Menu, [{label, {text, "Next (N)"}}]),
+ gs:menuitem(last_all, Menu, [{label, {text, "Last (L)"}}]),
+ gs:menuitem(refresh_all, Menu, [{label, {text, "Refresh (R)"}}]).
+
+create_filter_menu(ActiveFilterName, Filters) ->
+ Menu = gs:menu(filter_menu, filter_button, []),
+ Item = fun(F, N) when F#filter.name =:= collector ->
+ Label = lists:concat([pad_string(F#filter.name, 20), "(0)"]),
+ gs:menuitem(Menu, [{label, {text, Label}}, {data, F}]),
+ N + 1;
+ (F, N) ->
+ Label = lists:concat([pad_string(F#filter.name, 20), "(", N, ")"]),
+ gs:menuitem(Menu, [{label, {text, Label}}, {data, F}]),
+ N + 1
+ end,
+ gs:menuitem(Menu, [{label, {text, "Same Filter New Scale"}}, {bg, lightblue}, {enable,false}]),
+ gs:menuitem(Menu, [{itemtype, separator}]),
+ {value, Filter} = lists:keysearch(ActiveFilterName, #filter.name, Filters),
+ Same = lists:concat([pad_string(ActiveFilterName, 20), "(=)"]),
+ Larger = lists:concat([pad_string(ActiveFilterName, 20), "(+)"]),
+ Smaller = lists:concat([pad_string(ActiveFilterName, 20), "(-)"]),
+ gs:menuitem(Menu, [{label, {text, Same}}, {data, Filter}]),
+ gs:menuitem(Menu, [{label, {text, Smaller}}, {data, Filter}]),
+ gs:menuitem(Menu, [{label, {text, Larger}}, {data, Filter}]),
+ gs:menuitem(Menu, [{itemtype, separator}]),
+ gs:menuitem(Menu, [{label, {text, "New Filter Same Scale"}}, {bg, lightblue}, {enable,false}]),
+ gs:menuitem(Menu, [{itemtype, separator}]),
+ lists:foldl(Item, 1, Filters).
+
+create_help_menu(Bar) ->
+ Button = gs:menubutton(Bar, [{label, {text, "Help"}}]),
+ Menu = gs:menu(Button, []),
+ gs:menuitem(Menu, [{label, {text, "Display details of an event"}},
+ {bg, lightblue}, {enable,false}]),
+ gs:menuitem(Menu, [{label, {text, " Single click on the name tag or the arrow (Mouse-1)"}},
+ {enable,false}]),
+ gs:menuitem(Menu, [{itemtype, separator}]),
+ gs:menuitem(Menu, [{label, {text, "Toggle actor search"}},
+ {bg, lightblue}, {enable,false}]),
+ gs:menuitem(Menu, [{label, {text, " Single click on the name tag (Mouse-1)"}},
+ {enable,false}]),
+ gs:menuitem(Menu, [{itemtype, separator}]),
+ gs:menuitem(Menu, [{label, {text, "Move actor"}},
+ {bg, lightblue}, {enable,false}]),
+ gs:menuitem(Menu, [{label, {text, " se drag and drop on name tag (Mouse-1)"}},
+ {enable,false}]).
+
+clear_canvas(S) ->
+ gs:destroy(S#state.canvas),
+ CanvasW = calc_canvas_width(S),
+ CanvasH = calc_canvas_height(S),
+ CanOpt = [{pack_xy, {{2, 4}, 3}}, {vscroll, right}, {hscroll, bottom},
+ {scrollregion, {2, 2, CanvasW, CanvasH}}],
+ Canvas = gs:canvas(S#state.packer, CanOpt),
+ gs:config(S#state.packer, [{width, S#state.width}, {height, S#state.height}]),
+ gs:config(Canvas, [{buttonpress, true}, {buttonrelease, true}]),
+ S2 = S#state{refresh_needed = false,
+ y_pos = ?initial_y * S#state.scale,
+ canvas = Canvas,
+ canvas_width = CanvasW,
+ canvas_height = CanvasH,
+ events = queue_new()},
+ draw_all_actors(S2).
+
+calc_canvas_width(S) ->
+ Min = calc_min_actors(S),
+ CanvasW = ((2 * ?initial_x) + (Min * ?incr_x)) * S#state.scale,
+ lists:max([CanvasW, S#state.width - (15 * S#state.scale), S#state.canvas_width]).
+
+calc_canvas_height(S) ->
+ Min = calc_min_events(S),
+ CanvasH = ((2 * ?initial_y) + (Min * ?incr_y)) * S#state.scale,
+ lists:max([CanvasH, S#state.height - (4 * 30), S#state.canvas_height]).
+
+calc_min_actors(S) ->
+ Max = S#state.max_actors,
+ N = length(S#state.actors),
+ if
+ Max =:= infinity ->
+ N * 2;
+ Max < N ->
+ N;
+ true ->
+ Max
+ end.
+
+calc_min_events(S) ->
+ Max = S#state.max_events,
+ N = queue_length(S#state.events),
+ if
+ Max =:= infinity ->
+ N * 2;
+ Max < N ->
+ N;
+ true ->
+ Max
+ end.
+
+display_more_events(Try, S) ->
+ Name = S#state.active_filter,
+ {value, F} = lists:keysearch(Name, #filter.name, S#state.filters),
+ FilterFun = F#filter.function,
+ Fun = fun(Event, State) ->
+ case catch FilterFun(Event) of
+ true ->
+ State2 = ensure_key(Event, State),
+ opt_display_event(Event, State2);
+ {true, Event2} ->
+ State2 = ensure_key(Event2, State),
+ opt_display_event(Event2, State2);
+ false ->
+ ensure_key(Event, State);
+ Bad ->
+ Contents = {bad_filter, Name, Bad, Event},
+ Event2 = Event#event{contents = Contents,
+ from = bad_filter,
+ to = bad_filter},
+ State2 = ensure_key(Event2, State),
+ opt_display_event(Event2, State2)
+ end
+ end,
+ Pid = S#state.collector_pid,
+ S2 = et_collector:iterate(Pid, S#state.last_event, Try, Fun, S),
+ case queue_length(S2#state.events) - queue_length(S#state.events) of
+ Diff when Diff =:= Try ->
+ %% Got as much as requested, look for more
+ %% io:format("Done: ~p~n", [{Try, Diff}]),
+ {noreply, S2, 0};
+ _Diff when S2#state.first_event =:= S#state.first_event,
+ S2#state.last_event =:= S#state.last_event ->
+ %% Got lesser than requested, wait a while before looking for more
+ %% io:format("More: ~p~n", [{Try, Diff}]),
+ {noreply, S2, 500};
+ _Diff ->
+ %% Got lesser than requested, look for more
+ %% io:format("More2: ~p~n", [{Try, Diff}]),
+ {noreply, S2, 0}
+ end.
+
+ensure_key(E, S) when is_record(E, event), is_record(S, state) ->
+ Key = et_collector:make_key(S#state.event_order, E),
+ case S#state.first_event of
+ first ->
+ S#state{first_event = Key, last_event = Key};
+ last ->
+ S#state{first_event = Key, last_event = Key};
+ _ ->
+ S#state{last_event = Key}
+ end.
+
+opt_display_event(E, S) ->
+ case S#state.display_mode of
+ all ->
+ display_event(E, S);
+ {search_actors, _Dir, _FirstKey, Actors} ->
+ %% Key = S#state.last_event,
+ From = select_actor_name(E#event.from, S),
+ case lists:member(From, Actors) of
+ true ->
+ display_event(E, S);
+ false ->
+ To = select_actor_name(E#event.to, S),
+ case lists:member(To, Actors) of
+ true ->
+ display_event(E, S);
+ false ->
+ S
+ end
+ end
+ end.
+
+select_actor_name(Name, S) ->
+ case lists:keymember(Name, #actor.name, S#state.actors) of
+ true -> Name;
+ false -> ?unknown
+ end.
+
+display_event(E, S) when E#event.detail_level < S#state.detail_level ->
+ {FromRefresh, From} = ensure_actor(E#event.from, S),
+ {FromName, FromPos, S2} = From,
+ {ToRefresh, To} = ensure_actor(E#event.to, S2),
+ {ToName, ToPos, S3} = To,
+ if
+ FromRefresh =/= false, ToRefresh =/= false ->
+ Key = S#state.last_event,
+ refresh_beep(S),
+ S3#state{refresh_needed = true,
+ events = queue_in(Key, S3#state.events)};
+ FromName =:= ToName ->
+ case S#state.hide_actions of
+ true ->
+ S3;
+ false ->
+ Label = name_to_string(E#event.label),
+ draw_named_arrow(Label, FromName, FromPos, ToName, ToPos, S3)
+ end;
+ true ->
+ Label = name_to_string(E#event.label),
+ draw_named_arrow(Label, FromName, FromPos, ToName, ToPos, S3)
+ end;
+display_event(_, S) ->
+ S.
+
+draw_named_arrow(Label, FromName, FromPos, ToName, ToPos, S) ->
+ Key = S#state.last_event,
+ case S#state.y_pos + (?incr_y * S#state.scale) of
+ _ when S#state.hide_unknown =:= true, FromName =:= ?unknown ->
+ S;
+ _ when S#state.hide_unknown =:= true, ToName =:= ?unknown ->
+ S;
+ Y when Y > S#state.canvas_height ->
+ refresh_beep(S),
+ S#state{refresh_needed = true,
+ events = queue_in(Key, S#state.events)};
+ Y ->
+ S2 = S#state{y_pos = Y, events = queue_in(Key, S#state.events)},
+ S3 = draw_arrow(FromPos, ToPos, S2),
+ draw_label(Label, FromName, ToName, FromPos, ToPos, S3)
+ end.
+
+refresh_beep(S) ->
+ case S#state.refresh_needed of
+ false ->
+ gs:config(S#state.canvas, beep),
+ gs:config(S#state.canvas, beep),
+ gs:config(S#state.canvas, beep);
+ true ->
+ ignore
+ end.
+
+draw_arrow(Pos, Pos, S) ->
+ S;
+draw_arrow(FromPos, ToPos, S) ->
+ Y = S#state.y_pos,
+ CanOpts = [{coords, [{FromPos , Y}, {ToPos, Y}]},
+ {arrow, last},{width, 1}, {fg, black}],
+ gs:line(S#state.canvas, CanOpts),
+ S.
+
+draw_label(Label, FromName, ToName, FromPos, ToPos, S) ->
+ Colour =
+ if
+ FromName =:= ?unknown,
+ ToName =:= ?unknown -> blue; %turquoise;
+ FromName =:= ?unknown -> orange;
+ ToName =:= ?unknown -> orange;
+ FromPos =:= ToPos -> blue;
+ true -> red
+ end,
+ Scale = S#state.scale,
+ X = lists:min([FromPos, ToPos]) + (6 * Scale),
+ Y = S#state.y_pos,
+ write_text(Label, X, Y, Colour, S),
+ S.
+
+draw_all_actors(State) ->
+ Scale = State#state.scale,
+ Fun = fun(A, X) ->
+ draw_actor(A, X, State),
+ X + (?incr_x * Scale)
+ end,
+ lists:foldl(Fun, ?initial_x * Scale, State#state.actors),
+ State.
+
+%% Returns: {NeedsRefreshBool, {ActorPos, NewsS, NewActors}}
+ensure_actor(Name, S) ->
+ do_ensure_actor(Name, S, S#state.actors, 0).
+
+do_ensure_actor(Name, S, [H | _], N) when H#actor.name =:= Name ->
+ Pos = (?initial_x + (N * ?incr_x)) * S#state.scale,
+ {false, {Name, Pos, S}};
+do_ensure_actor(Name, S, [_ | T], N) ->
+ do_ensure_actor(Name, S, T, N + 1);
+do_ensure_actor(Name, S, [], N) ->
+ %% A brand new actor, let's see if it does fit
+ Pos = (?initial_x + (N * ?incr_x)) * S#state.scale,
+ MaxActors = S#state.max_actors,
+ if
+ is_integer(MaxActors), N > MaxActors ->
+ %% Failed on max_actors limit, put into unknown
+ %% Assume that unknown always is in actor list
+ ensure_actor(?unknown, S);
+ Pos > (S#state.canvas_width - ((?initial_x - 15) * S#state.scale)) ->
+ %% New actor does not fit in canvas, refresh needed
+ A = create_actor(Name),
+ draw_actor(A, Pos, S),
+ {true, {Name, Pos, S#state{actors = S#state.actors ++ [A]}}};
+ true ->
+ %% New actor fits in canvas. Draw the new actor.
+ A = create_actor(Name),
+ draw_actor(A, Pos, S),
+ {false, {Name, Pos, S#state{actors = S#state.actors ++ [A]}}}
+ end.
+
+draw_actor(A, LineX, S) ->
+ Scale = S#state.scale,
+ TextX = LineX - (5 * Scale),
+ TextY = ?initial_y * Scale,
+ LineTopY = TextY + ((?incr_y / 2) * Scale),
+ LineBotY = S#state.canvas_height - ((?incr_y / 2) * Scale),
+ Colour = case A#actor.name of
+ ?unknown -> orange;
+ _ -> red
+ end,
+ write_text(A#actor.string, TextX, TextY, Colour, S),
+ LineOpt = [{coords, [{LineX, LineTopY}, {LineX, LineBotY}]},
+ {width, 1}, {fg, Colour}],
+ gs:line(S#state.canvas, LineOpt).
+
+toggle_search_for_actor(ActorName,S) ->
+ case S#state.display_mode of
+ all ->
+ io:format("~p: search for: ~p ++ ~p~n", [?MODULE, [], [ActorName]]),
+ %% Search for this actor
+ Key = S#state.first_event,
+ Actors = [ActorName],
+ Mode = {search_actors, forward, Key, Actors},
+ change_display_mode(Mode, S);
+ {search_actors, Dir, Key, Actors}->
+ Actors2 =
+ case lists:member(ActorName, Actors) of
+ true ->
+ io:format("~p: search for: ~p -- ~p~n", [?MODULE, Actors, [ActorName]]),
+ %% Remove actor from search list
+ Actors -- [ActorName];
+ false ->
+ io:format("~p: search for: ~p ++ ~p~n", [?MODULE, Actors, [ActorName]]),
+ %% Add actor from search list
+ [ActorName | Actors]
+ end,
+ Mode2 = {search_actors, Dir, Key, Actors2},
+ change_display_mode(Mode2, S)
+ end.
+
+move_actor(From, To, Actors, S) ->
+ Pos = #actor.name,
+ ToName = To#actor.name,
+ FromName = From#actor.name,
+ ToIx = actor_index(ToName, Pos, Actors),
+ FromIx = actor_index(FromName, Pos, Actors),
+ if
+ FromIx =/= 0, ToIx =/= 0, ToIx > FromIx ->
+ Actors2 = lists:keydelete(FromName, Pos, Actors),
+ Actors3 = insert_actor_after(From, To, Actors2),
+ S2 = S#state{actors = Actors3},
+ refresh_main_window(S2);
+ FromIx =/= 0, ToIx =/= 0 ->
+ Actors2 = lists:keydelete(FromName, Pos, Actors),
+ Actors3 = insert_actor_before(From, To, Actors2),
+ S2 = S#state{actors = Actors3},
+ refresh_main_window(S2);
+ true ->
+ %% Ignore
+ S
+ end.
+
+insert_actor_after(From, To, [H | T]) ->
+ case To#actor.name =:= H#actor.name of
+ true -> [H, From | T];
+ false -> [H | insert_actor_after(From, To, T)]
+ end;
+insert_actor_after(_From, _To, []) ->
+ [].
+
+insert_actor_before(From, To, [H | T]) ->
+ case To#actor.name =:= H#actor.name of
+ true -> [From, H | T];
+ false -> [H | insert_actor_before(From, To, T)]
+ end;
+insert_actor_before(_From, _To, []) ->
+ [].
+
+actor_index(_Key, _Pos, []) ->
+ 0;
+actor_index(Key, Pos, [H | T]) ->
+ case Key =:= element(Pos, H) of
+ false -> actor_index(Key, Pos, T) + 1;
+ true -> 1
+ end.
+
+y_to_n(Y, S) ->
+ Y2 = ((Y / S#state.scale) - ?initial_y + (?incr_y / 2)),
+ N = round(Y2 / ?incr_y - 0.2),
+ MaxN = queue_length(S#state.events),
+ if
+ N =< 0 -> actor;
+ N > MaxN -> actor;
+ true -> {event, N}
+ end.
+
+x_to_n(X, S) ->
+ Scale = S#state.scale,
+ Len = length(S#state.actors),
+ X2 = X - (?initial_x * Scale),
+ N = X2 / (?incr_x * Scale),
+ N2 = trunc(N + 1.5),
+ if
+ N2 > Len -> Len;
+ N2 < 1 -> 1;
+ true -> N2
+ end.
+
+write_text(Text, X, Y, Colour, S) ->
+ Opt = [{coords, [{X, Y - (?incr_y * S#state.scale / 2)}]},
+ {font, S#state.font}, {fg, Colour}, {text, Text}],
+ gs:text(S#state.canvas, Opt).
+
+create_contents_window(Event, S) ->
+ Options = [{viewer_pid, self()},
+ {event, Event},
+ {event_order, S#state.event_order},
+ {active_filter, S#state.active_filter}
+ | S#state.filters],
+ case et_gs_contents_viewer:start_link(Options) of
+ {ok, _Pid} ->
+ S;
+ {error, Reason} ->
+ ok = error_logger:format("~p(~p): create_contents_window(~p) ->~n ~p~n",
+ [?MODULE, self(), Options, Reason]),
+ S
+ end.
+
+%%%----------------------------------------------------------------------
+%%% String padding of actors
+%%%----------------------------------------------------------------------
+
+create_actor(Name) ->
+ String = name_to_string(Name),
+ PaddedString = pad_string(String, 8),
+ #actor{name = Name, string = PaddedString}.
+
+name_to_string(Name) ->
+ case catch io_lib:format("~s", [Name]) of
+ {'EXIT', _} -> lists:flatten(io_lib:format("~w", [Name]));
+ GoodString -> lists:flatten(GoodString)
+ end.
+
+pad_string(Atom, MinLen) when is_atom(Atom) ->
+ pad_string(atom_to_list(Atom), MinLen);
+pad_string(String, MinLen) when is_integer(MinLen), MinLen >= 0 ->
+ Len = length(String),
+ case Len >= MinLen of
+ true ->
+ String;
+ false ->
+ String ++ lists:duplicate(MinLen - Len, $ )
+ end.
+
+%%%----------------------------------------------------------------------
+%%% Queue management
+%%%----------------------------------------------------------------------
+
+queue_new() ->
+ {0, [], []}.
+
+queue_in(X, {Size, In, Out}) ->
+ {Size + 1, [X | In], Out}.
+
+%% queue_out(Q) ->
+%% case Q of
+%% {Size, In, [H | Out]} -> {{value, H}, {Size - 1, In, Out}};
+%% {Size, [], []} -> {empty, {Size, [], []}};
+%% {Size, In, _} -> queue_out({Size, [], lists:reverse(In)})
+%% end.
+
+queue_to_list({_Size, [], Out}) ->
+ Out;
+queue_to_list({_Size, In, Out}) ->
+ Out ++ lists:reverse(In).
+
+queue_length({Size, _In, _Out}) ->
+ Size.
+
+list_to_queue(List) when is_list(List) ->
+ {length(List), [], List}.
diff --git a/lib/et/src/et_internal.hrl b/lib/et/src/et_internal.hrl
index b6f84f5b4b..419d35afcd 100644
--- a/lib/et/src/et_internal.hrl
+++ b/lib/et/src/et_internal.hrl
@@ -1,23 +1,29 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2002-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 2002-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%
%%
%%----------------------------------------------------------------------
%% Purpose: Definition of internal data structures
%%----------------------------------------------------------------------
+-define(detail_level_min, 0).
+-define(detail_level_max, 100).
+
-record(filter, {name, function}).
+
+-define(DEFAULT_FILTER_NAME, all).
+-define(DEFAULT_FILTER, #filter{name = ?DEFAULT_FILTER_NAME, function = fun(E) -> E end}).
diff --git a/lib/et/src/et_selector.erl b/lib/et/src/et_selector.erl
index 845359622d..f39f21aa70 100644
--- a/lib/et/src/et_selector.erl
+++ b/lib/et/src/et_selector.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2001-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 2001-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%
%%
%%----------------------------------------------------------------------
@@ -39,16 +39,16 @@
%% RawPattern = detail_level()
%% TracePattern = erlang_trace_pattern_match_spec()
%%
-%% detail_level() = min | max | integer(X) when X =< 0, X >= 100
+%% detail_level() = min | max | integer(X) when X >= 0, X =< 100
%%
-%% min - minimum level of tracing (ignore calls to report_event/4,5)
-%% max - maximum level of tracing (all calls to report_event/4,5)
+%% min - minimum level of tracing (ignore calls to trace_me/4,5)
+%% max - maximum level of tracing (all calls to trace_me/4,5)
%% integer() - explicit detail level of tracing
%%----------------------------------------------------------------------
make_pattern(undefined) ->
{undefined, undefined};
-make_pattern({Mod, Pattern}) when atom(Mod) ->
+make_pattern({Mod, Pattern}) when is_atom(Mod) ->
case Pattern of
min ->
{Mod, []};
@@ -57,7 +57,7 @@ make_pattern({Mod, Pattern}) when atom(Mod) ->
Body = [],
Cond = [],
{Mod, [{Head, Cond, Body}]};
- DetailLevel when integer(DetailLevel) ->
+ DetailLevel when is_integer(DetailLevel) ->
Head = ['$1', '_', '_', '_', '_'],
Body = [],
Cond = [{ '<', '$1', DetailLevel}],
@@ -80,28 +80,31 @@ make_pattern({Mod, Pattern}) when atom(Mod) ->
%% detail_level() = min | max | integer(X) when X =<0, X >= 100
%% empty_match_spec() = []
%%
-%% Min detail level deactivates tracing of calls to report_event/4,5
+%% Min detail level deactivates tracing of calls to trace_me/4,5
%%
-%% Max detail level activates tracing of all calls to report_event/4,5
+%% Max detail level activates tracing of all calls to trace_me/4,5
%%
%% integer(X) detail level activates tracing of all calls to
-%% report_event/4,5 whose detail level argument is lesser than X.
+%% trace_me/4,5 whose detail level argument is lesser than X.
%%
-%% An empty match spec deactivates tracing of calls to report_event/4,5
+%% An empty match spec deactivates tracing of calls to trace_me/4,5
%%
-%% Other match specs activates tracing of calls to report_event/4,5
+%% Other match specs activates tracing of calls to trace_me/4,5
%% accordlingly with erlang:trace_pattern/2.
%%----------------------------------------------------------------------
-change_pattern({Mod, Pattern}) when atom(Mod) ->
- MFA = {Mod, report_event, 5},
+change_pattern({Mod, Pattern}) when is_atom(Mod) ->
+ MFA = {Mod, trace_me, 5},
case Pattern of
undefined ->
ignore;
[] ->
+ error_to_exit(old_ctp(MFA)),
error_to_exit(dbg:ctp(MFA)),
error_to_exit(dbg:p(all, clear));
- List when list(List) ->
+ List when is_list(List) ->
+ error_to_exit(old_ctp(MFA)),
+ error_to_exit(old_tp(MFA, Pattern)),
error_to_exit(dbg:ctp(MFA)),
error_to_exit(dbg:tp(MFA, Pattern)),
error_to_exit(dbg:p(all, [call, timestamp]));
@@ -110,6 +113,18 @@ change_pattern({Mod, Pattern}) when atom(Mod) ->
end,
ok.
+old_ctp({Mod, _Fun, Args}) ->
+ case Mod of
+ et -> ignore;
+ _ -> dbg:ctp({Mod, report_event, Args})
+ end.
+
+old_tp({Mod, _Fun, Args}, Pattern) ->
+ case Mod of
+ et -> ignore;
+ _ -> dbg:tp({Mod, report_event, Args}, Pattern)
+ end.
+
error_to_exit({error, Reason}) ->
exit(Reason);
error_to_exit({ok, Res}) ->
@@ -148,7 +163,7 @@ error_to_exit({ok, Res}) ->
%% label - Label intended to provide a brief event summary.
%% contents - All nitty gritty details of the event.
%%
-%% See et:report_event/4 and et:report_event/5 for details.
+%% See et:trace_me/4 and et:trace_me/5 for details.
%%
%% Returns:
%%
@@ -161,7 +176,7 @@ error_to_exit({ok, Res}) ->
%% should be dropped
%%----------------------------------------------------------------------
-parse_event(_Mod, E) when record(E, event) ->
+parse_event(_Mod, E) when is_record(E, event) ->
true;
parse_event(Mod, Trace) ->
ParsedTS = erlang:now(),
@@ -293,6 +308,14 @@ parse_event(Mod, Trace, ParsedTS, ReportedTS, From, Label, Contents) ->
{msg, Msg}]}};
call ->
case Contents of
+ [{M, trace_me, [UserDetailLevel, UserFrom, UserTo, UserLabel, UserContents]}] when M == Mod, Mod /= undefined ->
+ {true, #event{detail_level = UserDetailLevel,
+ trace_ts = ReportedTS,
+ event_ts = ParsedTS,
+ from = UserFrom,
+ to = UserTo,
+ label = UserLabel,
+ contents = UserContents}}; % Term
[{M, report_event, [UserDetailLevel, UserFrom, UserTo, UserLabel, UserContents]}] when M == Mod, Mod /= undefined ->
{true, #event{detail_level = UserDetailLevel,
trace_ts = ReportedTS,
@@ -358,6 +381,21 @@ parse_event(Mod, Trace, ParsedTS, ReportedTS, From, Label, Contents) ->
{to, From},
{mfa, MFA},
{return, ReturnValue}]}};
+ exception_from ->
+ DetailLevel = 54,
+ [MFA, Exception] = Contents,
+ {true, #event{detail_level = DetailLevel,
+ trace_ts = ReportedTS,
+ event_ts = ParsedTS,
+ from = From,
+ to = From,
+ label = Label,
+ contents = [{label, Label},
+ {detail_level, DetailLevel},
+ {from, From},
+ {to, From},
+ {mfa, MFA},
+ {exception, Exception}]}};
spawn ->
DetailLevel = 25,
[NewPid, MFA] = Contents,
diff --git a/lib/et/src/et_viewer.erl b/lib/et/src/et_viewer.erl
index ede2c401eb..d9bd01f8d0 100644
--- a/lib/et/src/et_viewer.erl
+++ b/lib/et/src/et_viewer.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2000-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 2000-2010. All Rights Reserved.
+%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
-%%
+%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
-%%
+%%
%% %CopyrightEnd%
%%
%%----------------------------------------------------------------------
@@ -22,66 +22,23 @@
-module(et_viewer).
--behaviour(gen_server).
%% External exports
-export([file/1,
start/0,
start/1,
+ start/2,
start_link/1,
+ start_link/2,
+ open_event/2,
stop/1,
get_collector_pid/1]).
-%% gen_server callbacks
--export([init/1, terminate/2, code_change/3,
- handle_call/3, handle_cast/2, handle_info/2]).
-
-include("../include/et.hrl").
-include("et_internal.hrl").
-define(unknown, "UNKNOWN").
--record(state,
- {parent_pid, % Pid of parent process
- collector_pid, % Pid of collector process
- event_order, % Field to be used as primary key
- trace_pattern, % Collector trace pattern
- active_filter, % Name of the active filter
- filters, % List of possible filters
- selected_actor, % Actor selected by user
- first_event, % Key of first event (regardless of visibility)
- last_event, % Key of last event (regardless of visibility)
- max_events, % Maximum number of shown events
- events, % Queue containg all event keys (regardless of visibility)
- max_actors, % Maximum number of shown actors
- actors, % List of known actors
- refresh_needed, % Refresh is needed in order to show all actors
- display_mode, % Display all or only matching actors
- detail_level, % Show only events with lesser detail level
- hide_actions, % Hide/show events where to == from actor (bool)
- hide_unknown, % Hide/show events with unknown actor (bool)
- is_suspended, % Suspend viewer updates (bool)
- title, % GUI: Window title
- win, % GUI: Window object
- menubar, % GUI: Menu bar object
- packer, % GUI: Packer object
- width, % GUI: Window width
- height, % GUI: Window height
- scale, % GUI: Scaling factor on canvas
- font, % GUI: Font to be used on text labels
- canvas_width, % GUI: Canvas width
- canvas_height, % GUI: Canvas height
- canvas, % GUI: Canvas object
- y_pos}). % GUI: Current y position on canvas
-
--record(actor, {name, string}).
-
--define(initial_x, 10).
--define(incr_x, 60).
--define(initial_y, 15).
--define(incr_y, 15).
--define(detail_level_min, 0).
--define(detail_level_max, 100).
%%%----------------------------------------------------------------------
%%% Client side
@@ -99,7 +56,7 @@
%%----------------------------------------------------------------------
file(FileName) ->
- start_link([{trace_client, {file, FileName}}]).
+ start_link([{trace_client, {file, FileName}}], default).
%%----------------------------------------------------------------------
%% start() -> ok
@@ -113,14 +70,19 @@ file(FileName) ->
%%----------------------------------------------------------------------
start() ->
- start([{trace_global, true}]).
+ start([{trace_global, true}], default).
%%----------------------------------------------------------------------
%% start(Options) -> {ok, ViewerPid} | {error, Reason}
%%----------------------------------------------------------------------
+start(GUI) when GUI =:= wx; GUI =:= gs; GUI =:= default ->
+ start_link([{trace_global, true}], GUI);
start(Options) ->
- start_link([{parent_pid, undefined} | Options]).
+ start_link([{parent_pid, undefined} | Options], default).
+
+start(Options, GUI) ->
+ start_link([{parent_pid, undefined} | Options], GUI).
%%----------------------------------------------------------------------
%% start_link(Options) -> {ok, ViewerPid} | {error, Reason}
@@ -177,216 +139,31 @@ start(Options) ->
%% and returns false | true | {true, NewEvent}.
%%----------------------------------------------------------------------
-start_link(Options) ->
- case parse_opt(Options, default_state(), []) of
- {ok, S, CollectorOpt} ->
- case S#state.collector_pid of
- CollectorPid when pid(CollectorPid) ->
- case gen_server:start_link(?MODULE, [S], []) of
- {ok, Pid} when S#state.parent_pid /= self() ->
- unlink(Pid),
- {ok, Pid};
- Other ->
- Other
- end;
- undefined ->
- case et_collector:start_link(CollectorOpt) of
- {ok, CollectorPid} ->
- S2 = S#state{collector_pid = CollectorPid},
- case gen_server:start_link(?MODULE, [S2], []) of
- {ok, Pid} when S#state.parent_pid /= self() ->
- unlink(Pid),
- {ok, Pid};
- Other ->
- Other
- end;
- {error, Reason} ->
- {error, {et_collector, Reason}}
- end
- end;
- {error, Reason} ->
- {error, Reason}
- end.
-
-default_state() ->
- #state{parent_pid = self(),
- collector_pid = undefined,
- detail_level = ?detail_level_max,
- active_filter = collector,
- filters = [#filter{name = collector, function = fun(E) -> E end}],
- event_order = trace_ts,
- is_suspended = false,
- max_events = 100,
- first_event = first,
- last_event = first,
- events = queue_new(),
- max_actors = 5,
- actors = [create_actor(?unknown)],
- selected_actor = ?unknown,
- hide_actions = false,
- hide_unknown = false,
- refresh_needed = false,
- display_mode = all,
- scale = 2,
- canvas_height = 0,
- canvas_width = 0,
- width = 800,
- height = 600}.
-
-parse_opt([], S, CollectorOpt) ->
- {ok, S, [{parent_pid, S#state.parent_pid} | CollectorOpt]};
-parse_opt([H | T], S, CollectorOpt) ->
- case H of
- {parent_pid, Parent} when Parent == undefined ->
- CollectorOpt2 = [H | CollectorOpt],
- parse_opt(T, S#state{parent_pid = Parent}, CollectorOpt2);
- {parent_pid, Parent} when pid(Parent) ->
- CollectorOpt2 = [H | CollectorOpt],
- parse_opt(T, S#state{parent_pid = Parent}, CollectorOpt2);
- {title, Title} ->
- parse_opt(T, S#state{title = name_to_string(Title)}, CollectorOpt);
- {detail_level, Level} when integer(Level),
- Level >= ?detail_level_min,
- Level =< ?detail_level_max ->
- parse_opt(T, S#state{detail_level = Level}, CollectorOpt);
- {detail_level, max} ->
- parse_opt(T, S#state{detail_level = ?detail_level_max}, CollectorOpt);
- {detail_level, min} ->
- parse_opt(T, S#state{detail_level = ?detail_level_min}, CollectorOpt);
- {is_suspended, true} ->
- parse_opt(T, S#state{is_suspended = true}, CollectorOpt);
- {is_suspended, false} ->
- parse_opt(T, S#state{is_suspended = false}, CollectorOpt);
- {scale, Scale} when integer(Scale), Scale > 0 ->
- parse_opt(T, S#state{scale = Scale}, CollectorOpt);
- {width, W} when integer(W), W > 0 ->
- parse_opt(T, S#state{width = W, canvas_width = W}, CollectorOpt);
- {height, WH} when integer(WH), WH > 0 ->
- parse_opt(T, S#state{height = WH, canvas_height = WH}, CollectorOpt);
- {collector_pid, Pid} when pid(Pid) ->
- parse_opt(T, S#state{collector_pid = Pid}, CollectorOpt);
- {collector_pid, undefined} ->
- parse_opt(T, S#state{collector_pid = undefined}, CollectorOpt);
- {active_filter, Name} when atom(Name) ->
- parse_opt(T, S#state{active_filter = Name}, CollectorOpt);
- {event_order, trace_ts} -> %% BUGBUG: Verify event_order with collector
- CollectorOpt2 = [H | CollectorOpt],
- parse_opt(T, S#state{event_order = trace_ts}, CollectorOpt2);
- {event_order, event_ts} -> %% BUGBUG: Verify event_order with collector
- CollectorOpt2 = [H | CollectorOpt],
- parse_opt(T, S#state{event_order = event_ts}, CollectorOpt2);
- {trace_port, _Port} ->
- CollectorOpt2 = [H | CollectorOpt],
- parse_opt(T, S, CollectorOpt2);
- {trace_max_queue, _Queue} ->
- CollectorOpt2 = [H | CollectorOpt],
- parse_opt(T, S, CollectorOpt2);
- {trace_pattern, _Pattern} ->
- CollectorOpt2 = [H | CollectorOpt],
- parse_opt(T, S, CollectorOpt2);
- {trace_global, _Boolean} ->
- CollectorOpt2 = [H | CollectorOpt],
- parse_opt(T, S, CollectorOpt2);
- {trace_client, _Client} ->
- CollectorOpt2 = [H | CollectorOpt],
- parse_opt(T, S, CollectorOpt2);
- {dict_insert, {filter, Name}, Fun} ->
- if
- atom(Name), function(Fun) ->
- F = #filter{name = Name, function = Fun},
- Filters = lists:keydelete(Name, #filter.name, S#state.filters),
- CollectorOpt2 = [H | CollectorOpt],
- parse_opt(T, S#state{filters = Filters ++ [F]}, CollectorOpt2);
- true ->
- {error, {bad_option, H}}
- end;
- {dict_insert, {subscriber, Pid}, _Val} ->
- if
- pid(Pid) ->
- CollectorOpt2 = [H | CollectorOpt],
- parse_opt(T, S, CollectorOpt2);
- true ->
- {error, {bad_option, H}}
- end;
- {dict_insert, _Key, _Val} ->
- CollectorOpt2 = [H | CollectorOpt],
- parse_opt(T, S, CollectorOpt2);
- {dict_delete, {filter, Name}} ->
- Filters = lists:keydelete(Name, #filter.name, S#state.filters),
- CollectorOpt2 = [H | CollectorOpt],
- parse_opt(T, S#state{filters = Filters}, CollectorOpt2);
- {dict_delete, _Key} ->
- CollectorOpt2 = [H | CollectorOpt],
- parse_opt(T, S, CollectorOpt2);
- {max_events, Max} when integer(Max), Max > 0->
- parse_opt(T, S#state{max_events = Max}, CollectorOpt);
- {max_events, Max} when Max == infinity ->
- parse_opt(T, S#state{max_events = Max}, CollectorOpt);
- {max_actors, Max} when integer(Max), Max >= 0->
- parse_opt(T, S#state{max_actors = Max}, CollectorOpt);
- {max_actors, Max} when Max == infinity ->
- parse_opt(T, S#state{max_actors = Max}, CollectorOpt);
- {actors, ActorNames} when list(ActorNames) ->
- ActorNames2 =
- case lists:member(?unknown, ActorNames) of
- false -> [?unknown | ActorNames];
- true -> ActorNames
- end,
- Actors = [create_actor(Name) || Name <- ActorNames2],
- parse_opt(T, S#state{actors = Actors}, CollectorOpt);
- {first_event, First} ->
- parse_opt(T, S#state{first_event = First}, CollectorOpt);
- {hide_unknown, Bool} when Bool == false ->
- parse_opt(T, S#state{hide_unknown = Bool}, CollectorOpt);
- {hide_unknown, Bool} when Bool == true ->
- parse_opt(T, S#state{hide_unknown = Bool}, CollectorOpt);
- {hide_actions, Bool} when Bool == false ->
- parse_opt(T, S#state{hide_actions = Bool}, CollectorOpt);
- {hide_actions, Bool} when Bool == true ->
- parse_opt(T, S#state{hide_actions = Bool}, CollectorOpt);
- {display_mode, Mode = all} ->
- parse_opt(T, S#state{display_mode = Mode}, CollectorOpt);
- {display_mode, Mode = {search_actors, Dir, _Key, Actors}} when list(Actors), Dir == forward ->
- parse_opt(T, S#state{display_mode = Mode}, CollectorOpt);
- {display_mode, Mode = {search_actors, Dir, _Key, Actors}} when list(Actors), Dir == reverse ->
- parse_opt(T, S#state{display_mode = Mode}, CollectorOpt);
+start_link(GUI) when GUI =:= wx; GUI =:= gs; GUI =:= default ->
+ start_link([{trace_global, true}], GUI);
+start_link(Options) ->
+ start_link(Options, default).
- Bad ->
- {error, {bad_option, Bad}}
- end;
-parse_opt(BadList, _S, _CollectorOpt) ->
- {error, {bad_option_list, BadList}}.
+start_link(Options, GUI) ->
+ case GUI of
+ wx ->
+ et_wx_viewer:start_link(Options);
+ gs ->
+ et_gs_viewer:start_link(Options);
+ default ->
+ start_link(Options, which_gui())
+ end.
-do_dict_insert({filter, Name}, Fun, S) when atom(Name), function(Fun) ->
- F = #filter{name = Name, function = Fun},
- Filters = lists:keydelete(Name, #filter.name, S#state.filters),
- Filters2 = lists:keysort(#filter.name, [F | Filters]),
- gs:destroy(filter_menu),
- create_filter_menu(S#state.active_filter, Filters2),
- S#state{filters = Filters2};
-do_dict_insert(_Key, _Val, S) ->
- %% ok = error_logger:format("~p(~p): handle_info({et, {dict_insert, ~p, ~p}})~n",
- %% [?MODULE, self(), Key, Val]),
- S.
-do_dict_delete({filter, Name}, S) when atom(Name), Name /= S#state.active_filter ->
- Filters = lists:keydelete(Name, #filter.name, S#state.filters),
- gs:destroy(filter_menu),
- create_filter_menu(S#state.active_filter, Filters),
- S#state{filters = Filters};
-do_dict_delete(_Key, S) ->
- %% ok = error_logger:format("~p(~p): handle_info({et, {dict_delete, ~p}})~n",
- %% [?MODULE, self(), Key]),
- S.
+which_gui() ->
+ try
+ wx:new(),
+ wx:destroy(),
+ wx
+ catch _:_ ->
+ gs
+ end.
-%%----------------------------------------------------------------------
-%% get_collector_pid(ViewerPid) -> CollectorPid
-%%
-%% Returns the identifier of the collector process
-%%
-%% ViewerPid = pid()
-%% CollectorPid = pid()
-%%----------------------------------------------------------------------
get_collector_pid(ViewerPid) ->
call(ViewerPid, get_collector_pid).
@@ -402,1201 +179,14 @@ get_collector_pid(ViewerPid) ->
stop(ViewerPid) ->
call(ViewerPid, stop).
-call(ViewerPid, Request) ->
- gen_server:call(ViewerPid, Request, infinity).
-
-%%%----------------------------------------------------------------------
-%%% Callback functions from gen_server
-%%%----------------------------------------------------------------------
%%----------------------------------------------------------------------
-%% Func: init/1
-%% Returns: {ok, State} |
-%% {ok, State, Timeout} |
-%% ignore |
-%% {stop, Reason}
-%%----------------------------------------------------------------------
-init([S]) when record(S, state) ->
- process_flag(trap_exit, true),
- InitialTimeout = 0,
- case S#state.parent_pid of
- undefined ->
- ignore;
- Pid when pid(Pid) ->
- link(Pid)
- end,
- et_collector:dict_insert(S#state.collector_pid,
- {subscriber, self()},
- ?MODULE),
- {ok, create_main_window(S), InitialTimeout}.
+open_event(ViewerPid, N) ->
+ call(ViewerPid, {open_event, N}).
%%----------------------------------------------------------------------
-%% Func: handle_call/3
-%% Returns: {reply, Reply, State} |
-%% {reply, Reply, State, Timeout} |
-%% {noreply, State} |
-%% {noreply, State, Timeout} |
-%% {stop, Reason, Reply, State} | (terminate/2 is called)
-%% {stop, Reason, State} (terminate/2 is called)
-%%----------------------------------------------------------------------
-
-handle_call(get_collector_pid, _From, S) ->
- Reply = S#state.collector_pid,
- reply(Reply, S);
-handle_call(stop, _From, S) ->
- gs:destroy(S#state.win),
- {stop, shutdown, ok, S};
-handle_call(Request, From, S) ->
- ok = error_logger:format("~p(~p): handle_call(~p, ~p, ~p)~n",
- [?MODULE, self(), Request, From, S]),
- Reply = {error, {bad_request, Request}},
- reply(Reply, S).
-
-%%----------------------------------------------------------------------
-%% Func: handle_cast/2
-%% Returns: {noreply, State} |
-%% {noreply, State, Timeout} |
-%% {stop, Reason, State} (terminate/2 is called)
-%%----------------------------------------------------------------------
-
-handle_cast(Msg, S) ->
- ok = error_logger:format("~p(~p): handle_cast(~p, ~p)~n",
- [?MODULE, self(), Msg, S]),
- noreply(S).
-
-%%----------------------------------------------------------------------
-%% Func: handle_info/2
-%% Returns: {noreply, State} |
-%% {noreply, State, Timeout} |
-%% {stop, Reason, State} (terminate/2 is called)
-%%----------------------------------------------------------------------
-
-handle_info({et, {insert_actors, ActorNames}}, S) when list(ActorNames) ->
- Fun = fun(N, Actors) ->
- case lists:keymember(N, #actor.name, Actors) of
- true -> Actors;
- false -> Actors ++ [create_actor(N)]
- end
- end,
- Actors = lists:foldl(Fun, S#state.actors, ActorNames),
- S2 = refresh_main_window(S#state{actors = Actors}),
- noreply(S2);
-handle_info({et, {delete_actors, ActorNames}}, S) when list(ActorNames)->
- Fun = fun(N, Actors) when N == ?unknown ->
- Actors;
- (N, Actors) ->
- lists:keydelete(N, #actor.name, Actors)
- end,
- New = lists:foldl(Fun, S#state.actors, ActorNames),
- S2 = refresh_main_window(S#state{actors = New}),
- noreply(S2);
-handle_info({et, {dict_insert, Key, Val}}, S) ->
- S2 = do_dict_insert(Key, Val, S),
- noreply(S2);
-handle_info({et, {dict_delete, Key}}, S) ->
- S2 = do_dict_delete(Key, S),
- noreply(S2);
-handle_info({et, first}, S) ->
- S2 = scroll_first(S),
- noreply(S2);
-handle_info({et, prev}, S) ->
- S2 = scroll_prev(S),
- noreply(S2);
-handle_info({et, next}, S) ->
- S2 = scroll_next(S),
- noreply(S2);
-handle_info({et, last}, S) ->
- S2 = scroll_last(S),
- noreply(S2);
-handle_info({et, refresh}, S) ->
- S2 = refresh_main_window(S),
- noreply(S2);
-handle_info({et, {display_mode, Mode}}, S) ->
- S2 = change_display_mode(Mode, S),
- noreply(S2);
-handle_info({et, close}, S) ->
- gs:destroy(S#state.win),
- {stop, shutdown, S};
-handle_info({gs, Button, click, Data, Other} = Click, S) ->
- CollectorPid = S#state.collector_pid,
- case Button of
- close ->
- gs:destroy(S#state.win),
- {stop, shutdown, S};
- suspended ->
- case Other of
- [_Text, _Group, Bool | _] when Bool == true ->
- S2 = do_suspend(S),
- noreply(S2);
- [_Text, _Group, Bool | _] when Bool == false ->
- S2 = do_resume(S),
- noreply(S2);
- _ ->
- click_error(Click, S),
- noreply(S)
- end;
- hide_actions ->
- case Other of
- [_Text, _Group, Bool | _] when Bool == true ->
- S2 = refresh_main_window(S#state{hide_actions = Bool}),
- noreply(S2);
- [_Text, _Group, Bool | _] when Bool == false ->
- S2 = refresh_main_window(S#state{hide_actions = Bool}),
- noreply(S2);
- _ ->
- click_error(Click, S),
- noreply(S)
- end;
- hide_unknown ->
- case Other of
- [_Text, _Group, Bool | _] when Bool == true ->
- S2 = refresh_main_window(S#state{hide_unknown = Bool}),
- noreply(S2);
- [_Text, _Group, Bool | _] when Bool == false ->
- S2 = refresh_main_window(S#state{hide_unknown = Bool}),
- noreply(S2);
- _ ->
- click_error(Click, S),
- noreply(S)
- end;
- up ->
- S2 = scroll_up(S),
- noreply(S2);
- down ->
- S2 = scroll_down(S),
- noreply(S2);
- first ->
- S2 = scroll_first(S),
- noreply(S2);
- prev ->
- S2 = scroll_prev(S),
- noreply(S2);
- next ->
- S2 = scroll_next(S),
- noreply(S2);
- last ->
- S2 = scroll_last(S),
- noreply(S2);
- refresh ->
- S2 = refresh_main_window(S),
- noreply(S2);
- {display_mode, Mode} ->
- S2 = change_display_mode(Mode, S),
- noreply(S2);
- close_all ->
- close_all(S);
- close_all_others ->
- close_all_others(S);
- first_all ->
- et_collector:multicast(CollectorPid, first),
- noreply(S);
- prev_all ->
- et_collector:multicast(CollectorPid, prev),
- noreply(S);
- next_all ->
- et_collector:multicast(CollectorPid, next),
- noreply(S);
- last_all ->
- et_collector:multicast(CollectorPid, last),
- noreply(S);
- refresh_all ->
- et_collector:multicast(CollectorPid, refresh),
- noreply(S);
- clear_all ->
- et_collector:clear_table(CollectorPid),
- et_collector:multicast(CollectorPid, refresh),
- noreply(S);
- load_all ->
- et_collector:start_trace_client(CollectorPid, event_file, "et_viewer.log"),
- noreply(S);
- save_all ->
- et_collector:save_event_file(CollectorPid,
- "et_viewer.log",
- [existing, write, keep]),
- noreply(S);
- {open_viewer, Scale} ->
- Actors = [A#actor.name || A <- S#state.actors],
- open_viewer(Scale, S#state.active_filter, Actors, S),
- noreply(S);
- _Level when Data == detail_level, integer(hd(Other)),
- hd(Other) >= ?detail_level_min,
- hd(Other) =< ?detail_level_max ->
- S2 = S#state{detail_level = hd(Other)},
- noreply(S2);
- _PopupMenuItem when record(Data, filter) ->
- open_viewer(S#state.scale, Data#filter.name, [?unknown], S),
- noreply(S);
- _ ->
- click_error(Click, S),
- noreply(S)
- end;
-handle_info({gs, _Obj, destroy,_, _}, S) ->
- gs:destroy(S#state.win),
- {stop, shutdown, S};
-handle_info({gs, _Obj, buttonpress, _, [_Button, X, Y | _]}, S) ->
- S3 =
- case y_to_n(Y, S) of
- actor ->
- %% Actor click
- case S#state.actors of
- [] ->
- S;
- _ ->
- N = x_to_n(X, S),
- A = lists:nth(N, S#state.actors),
- S#state{selected_actor = A}
- end;
- {event, N} ->
- %% Event click
- List = queue_to_list(S#state.events),
- S2 = S#state{events = list_to_queue(List)},
-
- Key = lists:nth(N, List),
- Pid = S#state.collector_pid,
- Fun = fun create_contents_window/2,
- case et_collector:iterate(Pid, Key, -1) of
- Prev when Prev == Key ->
- et_collector:iterate(Pid, first, 1, Fun, S2);
- Prev ->
- et_collector:iterate(Pid, Prev, 1, Fun, S2)
- end
- end,
- noreply(S3);
-handle_info({gs, _Obj, buttonrelease, _, [_Button, X, Y | _]}, S) ->
- S2 =
- case y_to_n(Y, S) of
- actor ->
- %% Actor click
- case S#state.actors of
- [] ->
- S;
- Actors ->
- N = x_to_n(X, S),
- New = lists:nth(N, S#state.actors),
- Old = S#state.selected_actor,
- case New#actor.name == Old#actor.name of
- true ->
- A = S#state.selected_actor,
- toggle_search_for_actor(A#actor.name, S);
- false ->
- move_actor(Old, New, Actors, S)
- end
- end;
- {event, _N} ->
- %% Event click ignored
- S
- end,
- noreply(S2);
-handle_info({gs, _Obj, keypress, _, [KeySym, _Keycode, _Shift, _Control | _]} = Key, S) ->
- case KeySym of
- 'c' ->
- close_all_others(S);
- 'C' ->
- close_all(S);
- 'Up' ->
- S2 = scroll_up(S),
- noreply(S2);
- 'Down' ->
- S2 = scroll_down(S),
- noreply(S2);
- 'f' ->
- S2 = scroll_first(S),
- noreply(S2);
- 'p' ->
- S2 = scroll_prev(S),
- noreply(S2);
- 'Prior' ->
- S2 = scroll_prev(S),
- noreply(S2);
- 'n' ->
- S2 = scroll_next(S),
- noreply(S2);
- 'Next' ->
- S2 = scroll_next(S),
- noreply(S2);
- 'l' ->
- S2 = scroll_last(S),
- noreply(S2);
- 'r' ->
- S2 = refresh_main_window(S),
- noreply(S2);
- 'F' ->
- et_collector:multicast(S#state.collector_pid, first),
- noreply(S);
- 'P' ->
- et_collector:multicast(S#state.collector_pid, prev),
- noreply(S);
- 'N' ->
- et_collector:multicast(S#state.collector_pid, next),
- noreply(S);
- 'L' ->
- et_collector:multicast(S#state.collector_pid, last),
- noreply(S);
- 'R' ->
- et_collector:multicast(S#state.collector_pid, refresh),
- noreply(S);
-
- 'a' ->
- S2 = S#state{display_mode = all},
- S3 = refresh_main_window(S2),
- noreply(S3);
-
- 'equal' ->
- Scale = S#state.scale,
- Actors = [A#actor.name || A <- S#state.actors],
- open_viewer(Scale, S#state.active_filter, Actors, S),
- noreply(S);
- 'plus' ->
- Scale = S#state.scale + 1,
- Actors = [A#actor.name || A <- S#state.actors],
- open_viewer(Scale, S#state.active_filter, Actors, S),
- noreply(S);
- 'minus' ->
- case S#state.scale of
- 1 ->
- gs:config(S#state.canvas, beep);
- Scale ->
- Actors = [A#actor.name || A <- S#state.actors],
- open_viewer(Scale - 1, S#state.active_filter, Actors, S)
- end,
- noreply(S);
- 0 ->
- case lists:keysearch(collector, #filter.name, S#state.filters) of
- {value, F} when record(F, filter) ->
- open_viewer(S#state.scale, F#filter.name, [?unknown], S);
- false ->
- gs:config(S#state.canvas, beep)
- end,
- noreply(S);
- Int when integer(Int), Int > 0, Int =< 9 ->
- case catch lists:nth(Int, S#state.filters) of
- F when record(F, filter) ->
- open_viewer(S#state.scale, F#filter.name, [?unknown], S);
- {'EXIT', _} ->
- gs:config(S#state.canvas, beep)
- end,
- noreply(S);
-
- 'Shift_L' ->
- noreply(S);
- 'Shift_R' ->
- noreply(S);
- 'Caps_Lock' ->
- noreply(S);
-
- _ ->
- click_error(Key, S),
- noreply(S)
- end;
-handle_info({gs, _Obj,configure, [], [W, H | _]}, S) ->
- gs:config(S#state.packer, [{width, W}, {height, H}]),
- S2 = S#state{width = W, height = H},
- noreply(S2);
-handle_info(timeout, S) ->
- Try =
- case S#state.display_mode of
- {search_actors, reverse, _, _} ->
- -10;
- _ ->
- 10
- end,
- if
- S#state.is_suspended == true ->
- {noreply, S, infinity};
- S#state.max_events == infinity ->
- display_more_events(Try, S);
- true ->
- Needed = S#state.max_events - queue_length(S#state.events),
- if
- Needed =< 0 -> {noreply, S, infinity};
- Needed > 10 -> display_more_events(Try, S);
- Needed =< 10 -> display_more_events(Needed, S)
- end
- end;
-
-handle_info({'EXIT', Pid, Reason}, S) ->
- if
- Pid == S#state.collector_pid ->
- unlink(Pid),
- gs:destroy(S#state.win),
- {stop, Reason, S};
- Pid == S#state.parent_pid ->
- unlink(Pid),
- gs:destroy(S#state.win),
- {stop, Reason, S};
- true ->
- noreply(S)
- end;
-handle_info(Info, S) ->
- ok = error_logger:format("~p(~p): handle_info(~p, ~p)~n",
- [?MODULE, self(), Info, S]),
- noreply(S).
-
-%%----------------------------------------------------------------------
-%% Func: terminate/2
-%% Purpose: Shutdown the server
-%% Returns: any (ignored by gen_server)
-%%----------------------------------------------------------------------
-
-terminate(_Reason, _S) ->
- ignore.
-
-%%----------------------------------------------------------------------
-%% Func: code_change/3
-%% Purpose: Convert process state when code is changed
-%% Returns: {ok, NewState}
-%%----------------------------------------------------------------------
-
-code_change(_OldVsn, S, _Extra) ->
- {ok, S}.
-
-%%%----------------------------------------------------------------------
-%%% Handle suspend/resume
-%%%----------------------------------------------------------------------
-
-reply(Reply, S) ->
- case queue_length(S#state.events) of
- _ when S#state.is_suspended == true ->
- {reply, Reply, S, infinity};
- _ when S#state.max_events == infinity ->
- {reply, Reply, S, 500};
- N when N >= S#state.max_events ->
- {reply, Reply, S, infinity};
- _ ->
- {reply, Reply, S, 0}
- end.
-
-noreply(S) ->
- case queue_length(S#state.events) of
- _ when S#state.is_suspended == true ->
- {noreply, S, infinity};
- _ when S#state.max_events == infinity ->
- {noreply, S, 500};
- N when N >= S#state.max_events ->
- {noreply, S, infinity};
- _ ->
- {noreply, S, 0}
- end.
-
-do_suspend(S) ->
- config_suspend(S#state{is_suspended = true}).
-
-do_resume(S) ->
- config_suspend(S#state{is_suspended = false}).
-
-config_suspend(S) ->
- Suspended = S#state.is_suspended,
- gs:config(refresh, [{enable, not Suspended}]),
- gs:config(refresh_all, [{enable, not Suspended}]),
- gs:config(clear_all, [{enable, not Suspended}]),
- S.
-
-refresh_main_window(S) ->
- Pid = S#state.collector_pid,
- Key = S#state.first_event,
- case et_collector:iterate(Pid, Key, -1) of
- Prev when Prev == Key ->
- scroll_first(S);
- _Prev ->
- S2 = S#state{last_event = S#state.first_event},
- clear_canvas(S2)
- end.
-
-scroll_first(S) ->
- S2 = S#state{first_event = first, last_event = first},
- clear_canvas(S2).
-
-scroll_prev(S) ->
- Try =
- case S#state.max_events of
- infinity -> -10;
- Max -> -Max
- end,
- Key = et_collector:iterate(S#state.collector_pid, S#state.first_event, Try),
- S2 = S#state{first_event = Key, last_event = Key},
- clear_canvas(S2).
-
-scroll_next(S) ->
- S2 = S#state{first_event = S#state.last_event},
- clear_canvas(S2).
-
-scroll_up(S) ->
- Key = et_collector:iterate(S#state.collector_pid, S#state.first_event, -5),
- S2 = S#state{first_event = Key, last_event = Key},
- clear_canvas(S2).
-
-scroll_down(S) ->
- Key = et_collector:iterate(S#state.collector_pid, S#state.first_event, 5),
- S2 = S#state{first_event = Key, last_event = Key},
- clear_canvas(S2).
-
-scroll_last(S) ->
- S2 = S#state{first_event = last, last_event = last},
- clear_canvas(S2).
-
-change_display_mode(Mode, S) ->
- case Mode of
- all ->
- S2 = S#state{display_mode = Mode},
- refresh_main_window(S2);
- {search_actors, _Dir, _Key, []} ->
- S2 = S#state{display_mode = all},
- refresh_main_window(S2);
- {search_actors, _Dir, Key, Actors} when list(Actors) ->
- Pid = S#state.collector_pid,
- Prev = et_collector:iterate(Pid, Key, -1),
- S2 = S#state{first_event = Prev,
- last_event = Prev,
- display_mode = Mode},
- clear_canvas(S2)
- end.
-
-close_all(S) ->
- et_collector:multicast(S#state.collector_pid, close),
- timer:sleep(timer:seconds(1)),
- spawn(et_collector, stop, [S#state.collector_pid]),
- gs:destroy(S#state.win),
- {stop, shutdown, S}.
-
-close_all_others(S) ->
- Fun =
- fun({{subscriber, Pid}, _}) ->
- if
- Pid == self() ->
- ignore;
- true ->
- unlink(Pid),
- Pid ! {et, close}
- end
- end,
- All = et_collector:dict_match(S#state.collector_pid,
- {{subscriber, '_'}, '_'}),
- lists:foreach(Fun, All),
- noreply(S).
-
-click_error(Click, S) ->
- gs:config(S#state.canvas, beep),
- io:format("~p: ignored: ~p~n", [?MODULE, Click]).
-
-%%%----------------------------------------------------------------------
-%%% Clone viewer
-%%%----------------------------------------------------------------------
-open_viewer(Scale, FilterName, Actors, S) ->
- Filters = [{dict_insert, {filter, F#filter.name}, F#filter.function}
- || F <- S#state.filters],
- Options =
- [{parent_pid, S#state.parent_pid},
- {title, S#state.title},
- {collector_pid, S#state.collector_pid},
- {is_suspended, S#state.is_suspended},
- {detail_level, S#state.detail_level},
- {active_filter, FilterName},
- {event_order, S#state.event_order},
- {first_event, S#state.first_event},
- {max_events, S#state.max_events},
- {max_actors, S#state.max_actors},
- {hide_actions, S#state.hide_actions},
- {hide_unknown, S#state.hide_unknown},
- {is_suspended, S#state.is_suspended},
- {actors, Actors},
- {scale, Scale},
- {width, S#state.width},
- {height, S#state.height} | Filters],
- case start_link(Options) of
- {ok, ViewerPid} ->
- unlink(ViewerPid),
- ok;
- {error, Reason} ->
- ok = error_logger:format("~p: Failed to start a new window: ~p~n",
- [?MODULE, Reason])
- end.
-
-%%%----------------------------------------------------------------------
-%%% Handle graphics
-%%%----------------------------------------------------------------------
-
-create_main_window(S) ->
- Font = select_font(S#state.scale),
- GS = gs:start(),
- Name = name_to_string(S#state.active_filter),
- Title = case S#state.title of
- undefined -> atom_to_list(?MODULE);
- Explicit -> name_to_string(Explicit)
- end,
- WinOpt = [{title, Title ++ " (filter: " ++ Name ++ ")"},
- {configure, true},
- {width, S#state.width},
- {height, S#state.height}],
- Win = gs:window(GS, WinOpt),
- Bar = gs:menubar(Win, []),
-
- create_file_menu(Bar),
- create_viewer_menu(Bar),
- create_collector_menu(Bar),
- gs:menubutton(filter_button, Bar, [{label, {text, "Filter"}}]),
- create_filter_menu(S#state.active_filter, S#state.filters),
- create_help_menu(Bar),
-
- config_suspend(S),
-
- PackerOpt = [{packer_x, [{fixed, 5}, {fixed, 40}, {fixed, 40},
- {stretch, 1}, {fixed, 5}]},
- {packer_y, [{fixed, 30}, {fixed, 30},
- {stretch, 1}, {fixed, 30}]},
- {x, 0}, {y, 30}],
- Packer = gs:frame(Win, PackerOpt),
- gs:checkbutton(suspended, Packer, [{label,{text,"Freeze"}},
- {x, 10}, {y, 0},
- {width, 120}, {align, w},
- {select, S#state.is_suspended}]),
- gs:checkbutton(hide_actions, Packer, [{label,{text,"Hide From=To"}},
- {x, 10}, {y, 20},
- {width, 120}, {align, w},
- {select, S#state.hide_actions}]),
- gs:checkbutton(hide_unknown, Packer, [{label,{text,"Hide Unknown"}},
- {x, 10}, {y, 40},
- {width, 120}, {align, w},
- {select, S#state.hide_unknown}]),
- gs:scale(Packer, [{text,"Detail Level"},
- {range, {?detail_level_min, ?detail_level_max}},
- {orient, horizontal},
- {x, 150}, {y, 0}, {height, 65}, {width, 200},
- {pos, S#state.detail_level}, {data, detail_level}]),
- CanvasW = calc_canvas_width(S),
- CanvasH = calc_canvas_height(S),
- CanOpt = [{pack_xy, {{2, 4}, 3}}, {vscroll, right}, {hscroll, bottom},
- {scrollregion, {2, 2, CanvasW, CanvasH}}],
- Canvas = gs:canvas(Packer, CanOpt),
- gs:config(Canvas, [{buttonpress, true}, {buttonrelease, true}]),
- gs:config(Packer, [{width, S#state.width}, {height, S#state.height}]),
- gs:config(Win, [{map, true}, {keypress, true}]),
- S2 = S#state{title = Title,
- win = Win, font = Font, packer = Packer,
- canvas_width = CanvasW, canvas_height = CanvasH,
- canvas = Canvas,
- y_pos = ?initial_y * S#state.scale},
- draw_all_actors(S2).
-
-select_font(Scale) when integer(Scale) ->
- case Scale of
- 1 -> {courier, 7};
- 2 -> {courier, 10};
- 3 -> {courier, 12};
- 4 -> {courier, 14};
- S -> {courier, S * 4}
- end.
-
-create_file_menu(Bar) ->
- Button = gs:menubutton(Bar, [{label, {text, "File"}}]),
- Menu = gs:menu(Button, []),
- gs:menuitem(close_all, Menu, [{label, {text, "Close Collector and all Viewers (C) "}}]),
- gs:menuitem(close_all_others, Menu, [{label, {text, "Close other Viewers, but keep Collector (c)"}}]),
- gs:menuitem(close, Menu, [{label, {text, "Close this Viewer, but keep Collector"}}]),
- gs:menuitem(Menu, [{itemtype, separator}]),
-
- gs:menuitem(clear_all, Menu, [{label, {text, "Clear Collector"}}]),
- gs:menuitem(load_all, Menu, [{label, {text, "Load Collector from the file \"et_viewer.log\""}}]),
- gs:menuitem(save_all, Menu, [{label, {text, "Save Collector to the file \"et_viewer.log\""}}]).
-
-create_viewer_menu(Bar) ->
- Button = gs:menubutton(Bar, [{label, {text, "Viewer"}}]),
- Menu = gs:menu(Button, []),
- gs:menuitem(Menu, [{label, {text, "Scroll this Viewer"}}, {bg, lightblue}, {enable,false}]),
- gs:menuitem(Menu, [{itemtype, separator}]),
- gs:menuitem(first, Menu, [{label, {text, "First (f)"}}]),
- gs:menuitem(prev, Menu, [{label, {text, "Prev (p)"}}]),
- gs:menuitem(next, Menu, [{label, {text, "Next (n)"}}]),
- gs:menuitem(last, Menu, [{label, {text, "Last (l)"}}]),
- gs:menuitem(refresh, Menu, [{label, {text, "Refresh (r)"}}]),
- gs:menuitem(Menu, [{itemtype, separator}]),
- gs:menuitem(up, Menu, [{label, {text, "Up 5 (Up)"}}]),
- gs:menuitem(down, Menu, [{label, {text, "Down 5 (Down)"}}]),
- gs:menuitem(Menu, [{itemtype, separator}]),
- gs:menuitem(Menu, [{label, {text, "Search in this Viewer"}}, {bg, lightblue}, {enable,false}]),
- gs:menuitem(Menu, [{itemtype, separator}]),
- gs:menuitem({mode, all}, Menu, [{label, {text, "Abort search. Display all (a)"}}]).
-
-create_collector_menu(Bar) ->
- Button = gs:menubutton(Bar, [{label, {text, "Collector"}}]),
- Menu = gs:menu(Button, []),
- gs:menuitem(Menu, [{label, {text, "Scroll all Viewers"}}, {bg, lightblue}, {enable,false}]),
- gs:menuitem(Menu, [{itemtype, separator}]),
- gs:menuitem(first_all, Menu, [{label, {text, "First (F)"}}]),
- gs:menuitem(prev_all, Menu, [{label, {text, "Prev (P)"}}]),
- gs:menuitem(next_all, Menu, [{label, {text, "Next (N)"}}]),
- gs:menuitem(last_all, Menu, [{label, {text, "Last (L)"}}]),
- gs:menuitem(refresh_all, Menu, [{label, {text, "Refresh (R)"}}]).
-
-create_filter_menu(ActiveFilterName, Filters) ->
- Menu = gs:menu(filter_menu, filter_button, []),
- Item = fun(F, N) when F#filter.name == collector ->
- Label = lists:concat([pad_string(F#filter.name, 20), "(0)"]),
- gs:menuitem(Menu, [{label, {text, Label}}, {data, F}]),
- N + 1;
- (F, N) ->
- Label = lists:concat([pad_string(F#filter.name, 20), "(", N, ")"]),
- gs:menuitem(Menu, [{label, {text, Label}}, {data, F}]),
- N + 1
- end,
- gs:menuitem(Menu, [{label, {text, "Same Filter New Scale"}}, {bg, lightblue}, {enable,false}]),
- gs:menuitem(Menu, [{itemtype, separator}]),
- {value, Filter} = lists:keysearch(ActiveFilterName, #filter.name, Filters),
- Same = lists:concat([pad_string(ActiveFilterName, 20), "(=)"]),
- Larger = lists:concat([pad_string(ActiveFilterName, 20), "(+)"]),
- Smaller = lists:concat([pad_string(ActiveFilterName, 20), "(-)"]),
- gs:menuitem(Menu, [{label, {text, Same}}, {data, Filter}]),
- gs:menuitem(Menu, [{label, {text, Smaller}}, {data, Filter}]),
- gs:menuitem(Menu, [{label, {text, Larger}}, {data, Filter}]),
- gs:menuitem(Menu, [{itemtype, separator}]),
- gs:menuitem(Menu, [{label, {text, "New Filter Same Scale"}}, {bg, lightblue}, {enable,false}]),
- gs:menuitem(Menu, [{itemtype, separator}]),
- lists:foldl(Item, 1, Filters).
-
-create_help_menu(Bar) ->
- Button = gs:menubutton(Bar, [{label, {text, "Help"}}]),
- Menu = gs:menu(Button, []),
- gs:menuitem(Menu, [{label, {text, "Display details of an event"}},
- {bg, lightblue}, {enable,false}]),
- gs:menuitem(Menu, [{label, {text, " Single click on the name tag or the arrow (Mouse-1)"}},
- {enable,false}]),
- gs:menuitem(Menu, [{itemtype, separator}]),
- gs:menuitem(Menu, [{label, {text, "Toggle actor search"}},
- {bg, lightblue}, {enable,false}]),
- gs:menuitem(Menu, [{label, {text, " Single click on the name tag (Mouse-1)"}},
- {enable,false}]),
- gs:menuitem(Menu, [{itemtype, separator}]),
- gs:menuitem(Menu, [{label, {text, "Move actor"}},
- {bg, lightblue}, {enable,false}]),
- gs:menuitem(Menu, [{label, {text, " se drag and drop on name tag (Mouse-1)"}},
- {enable,false}]).
-
-clear_canvas(S) ->
- gs:destroy(S#state.canvas),
- CanvasW = calc_canvas_width(S),
- CanvasH = calc_canvas_height(S),
- CanOpt = [{pack_xy, {{2, 4}, 3}}, {vscroll, right}, {hscroll, bottom},
- {scrollregion, {2, 2, CanvasW, CanvasH}}],
- Canvas = gs:canvas(S#state.packer, CanOpt),
- gs:config(S#state.packer, [{width, S#state.width}, {height, S#state.height}]),
- gs:config(Canvas, [{buttonpress, true}, {buttonrelease, true}]),
- S2 = S#state{refresh_needed = false,
- y_pos = ?initial_y * S#state.scale,
- canvas = Canvas,
- canvas_width = CanvasW,
- canvas_height = CanvasH,
- events = queue_new()},
- draw_all_actors(S2).
-
-calc_canvas_width(S) ->
- Min = calc_min_actors(S),
- CanvasW = ((2 * ?initial_x) + (Min * ?incr_x)) * S#state.scale,
- lists:max([CanvasW, S#state.width - (15 * S#state.scale), S#state.canvas_width]).
-
-calc_canvas_height(S) ->
- Min = calc_min_events(S),
- CanvasH = ((2 * ?initial_y) + (Min * ?incr_y)) * S#state.scale,
- lists:max([CanvasH, S#state.height - (4 * 30), S#state.canvas_height]).
-
-calc_min_actors(S) ->
- Max = S#state.max_actors,
- N = length(S#state.actors),
- if
- Max == infinity ->
- N * 2;
- Max < N ->
- N;
- true ->
- Max
- end.
-
-calc_min_events(S) ->
- Max = S#state.max_events,
- N = queue_length(S#state.events),
- if
- Max == infinity ->
- N * 2;
- Max < N ->
- N;
- true ->
- Max
- end.
-
-display_more_events(Try, S) ->
- Name = S#state.active_filter,
- {value, F} = lists:keysearch(Name, #filter.name, S#state.filters),
- FilterFun = F#filter.function,
- Fun = fun(Event, State) ->
- case catch FilterFun(Event) of
- true ->
- State2 = ensure_key(Event, State),
- opt_display_event(Event, State2);
- {true, Event2} ->
- State2 = ensure_key(Event2, State),
- opt_display_event(Event2, State2);
- false ->
- ensure_key(Event, State);
- Bad ->
- Contents = {bad_filter, Name, Bad, Event},
- Event2 = Event#event{contents = Contents,
- from = bad_filter,
- to = bad_filter},
- State2 = ensure_key(Event2, State),
- opt_display_event(Event2, State2)
- end
- end,
- Pid = S#state.collector_pid,
- S2 = et_collector:iterate(Pid, S#state.last_event, Try, Fun, S),
- case queue_length(S2#state.events) - queue_length(S#state.events) of
- Diff when Diff == Try ->
- %% Got as much as requested, look for more
- %% io:format("Done: ~p~n", [{Try, Diff}]),
- {noreply, S2, 0};
- _Diff when S2#state.first_event == S#state.first_event,
- S2#state.last_event == S#state.last_event ->
- %% Got lesser than requested, wait a while before looking for more
- %% io:format("More: ~p~n", [{Try, Diff}]),
- {noreply, S2, 500};
- _Diff ->
- %% Got lesser than requested, look for more
- %% io:format("More2: ~p~n", [{Try, Diff}]),
- {noreply, S2, 0}
- end.
-
-ensure_key(E, S) when record(E, event), record(S, state) ->
- Key = et_collector:make_key(S#state.event_order, E),
- case S#state.first_event of
- first ->
- S#state{first_event = Key, last_event = Key};
- last ->
- S#state{first_event = Key, last_event = Key};
- _ ->
- S#state{last_event = Key}
- end.
-
-opt_display_event(E, S) ->
- case S#state.display_mode of
- all ->
- display_event(E, S);
- {search_actors, _Dir, _FirstKey, Actors} ->
- %% Key = S#state.last_event,
- From = select_actor_name(E#event.from, S),
- case lists:member(From, Actors) of
- true ->
- display_event(E, S);
- false ->
- To = select_actor_name(E#event.to, S),
- case lists:member(To, Actors) of
- true ->
- display_event(E, S);
- false ->
- S
- end
- end
- end.
-
-select_actor_name(Name, S) ->
- case lists:keymember(Name, #actor.name, S#state.actors) of
- true -> Name;
- false -> ?unknown
- end.
-
-display_event(E, S) when E#event.detail_level < S#state.detail_level ->
- {FromRefresh, From} = ensure_actor(E#event.from, S),
- {FromName, FromPos, S2} = From,
- {ToRefresh, To} = ensure_actor(E#event.to, S2),
- {ToName, ToPos, S3} = To,
- if
- FromRefresh /= false, ToRefresh /= false ->
- Key = S#state.last_event,
- refresh_beep(S),
- S3#state{refresh_needed = true,
- events = queue_in(Key, S3#state.events)};
- FromName == ToName ->
- case S#state.hide_actions of
- true ->
- S3;
- false ->
- Label = name_to_string(E#event.label),
- draw_named_arrow(Label, FromName, FromPos, ToName, ToPos, S3)
- end;
- true ->
- Label = name_to_string(E#event.label),
- draw_named_arrow(Label, FromName, FromPos, ToName, ToPos, S3)
- end;
-display_event(_, S) ->
- S.
-
-draw_named_arrow(Label, FromName, FromPos, ToName, ToPos, S) ->
- Key = S#state.last_event,
- case S#state.y_pos + (?incr_y * S#state.scale) of
- _ when S#state.hide_unknown == true, FromName == ?unknown ->
- S;
- _ when S#state.hide_unknown == true, ToName == ?unknown ->
- S;
- Y when Y > S#state.canvas_height ->
- refresh_beep(S),
- S#state{refresh_needed = true,
- events = queue_in(Key, S#state.events)};
- Y ->
- S2 = S#state{y_pos = Y, events = queue_in(Key, S#state.events)},
- S3 = draw_arrow(FromPos, ToPos, S2),
- draw_label(Label, FromName, ToName, FromPos, ToPos, S3)
- end.
-
-refresh_beep(S) ->
- case S#state.refresh_needed of
- false ->
- gs:config(S#state.canvas, beep),
- gs:config(S#state.canvas, beep),
- gs:config(S#state.canvas, beep);
- true ->
- ignore
- end.
-
-draw_arrow(Pos, Pos, S) ->
- S;
-draw_arrow(FromPos, ToPos, S) ->
- Y = S#state.y_pos,
- CanOpts = [{coords, [{FromPos , Y}, {ToPos, Y}]},
- {arrow, last},{width, 1}, {fg, black}],
- gs:line(S#state.canvas, CanOpts),
- S.
-
-draw_label(Label, FromName, ToName, FromPos, ToPos, S) ->
- Colour =
- if
- FromName == ?unknown,
- ToName == ?unknown -> blue; %turquoise;
- FromName == ?unknown -> orange;
- ToName == ?unknown -> orange;
- FromPos == ToPos -> blue;
- true -> red
- end,
- Scale = S#state.scale,
- X = lists:min([FromPos, ToPos]) + (6 * Scale),
- Y = S#state.y_pos,
- write_text(Label, X, Y, Colour, S),
- S.
-
-draw_all_actors(State) ->
- Scale = State#state.scale,
- Fun = fun(A, X) ->
- draw_actor(A, X, State),
- X + (?incr_x * Scale)
- end,
- lists:foldl(Fun, ?initial_x * Scale, State#state.actors),
- State.
-
-%% Returns: {NeedsRefreshBool, {ActorPos, NewsS, NewActors}}
-ensure_actor(Name, S) ->
- do_ensure_actor(Name, S, S#state.actors, 0).
-
-do_ensure_actor(Name, S, [H | _], N) when H#actor.name == Name ->
- Pos = (?initial_x + (N * ?incr_x)) * S#state.scale,
- {false, {Name, Pos, S}};
-do_ensure_actor(Name, S, [_ | T], N) ->
- do_ensure_actor(Name, S, T, N + 1);
-do_ensure_actor(Name, S, [], N) ->
- %% A brand new actor, let's see if it does fit
- Pos = (?initial_x + (N * ?incr_x)) * S#state.scale,
- MaxActors = S#state.max_actors,
- if
- integer(MaxActors), N > MaxActors ->
- %% Failed on max_actors limit, put into unknown
- %% Assume that unknown always is in actor list
- ensure_actor(?unknown, S);
- Pos > (S#state.canvas_width - ((?initial_x - 15) * S#state.scale)) ->
- %% New actor does not fit in canvas, refresh needed
- A = create_actor(Name),
- draw_actor(A, Pos, S),
- {true, {Name, Pos, S#state{actors = S#state.actors ++ [A]}}};
- true ->
- %% New actor fits in canvas. Draw the new actor.
- A = create_actor(Name),
- draw_actor(A, Pos, S),
- {false, {Name, Pos, S#state{actors = S#state.actors ++ [A]}}}
- end.
-
-draw_actor(A, LineX, S) ->
- Scale = S#state.scale,
- TextX = LineX - (5 * Scale),
- TextY = ?initial_y * Scale,
- LineTopY = TextY + ((?incr_y / 2) * Scale),
- LineBotY = S#state.canvas_height - ((?incr_y / 2) * Scale),
- Colour = case A#actor.name of
- ?unknown -> orange;
- _ -> red
- end,
- write_text(A#actor.string, TextX, TextY, Colour, S),
- LineOpt = [{coords, [{LineX, LineTopY}, {LineX, LineBotY}]},
- {width, 1}, {fg, Colour}],
- gs:line(S#state.canvas, LineOpt).
-
-toggle_search_for_actor(ActorName,S) ->
- case S#state.display_mode of
- all ->
- io:format("~p: search for: ~p ++ ~p~n", [?MODULE, [], [ActorName]]),
- %% Search for this actor
- Key = S#state.first_event,
- Actors = [ActorName],
- Mode = {search_actors, forward, Key, Actors},
- change_display_mode(Mode, S);
- {search_actors, Dir, Key, Actors}->
- Actors2 =
- case lists:member(ActorName, Actors) of
- true ->
- io:format("~p: search for: ~p -- ~p~n", [?MODULE, Actors, [ActorName]]),
- %% Remove actor from search list
- Actors -- [ActorName];
- false ->
- io:format("~p: search for: ~p ++ ~p~n", [?MODULE, Actors, [ActorName]]),
- %% Add actor from search list
- [ActorName | Actors]
- end,
- Mode2 = {search_actors, Dir, Key, Actors2},
- change_display_mode(Mode2, S)
- end.
-
-move_actor(From, To, Actors, S) ->
- Pos = #actor.name,
- ToName = To#actor.name,
- FromName = From#actor.name,
- ToIx = actor_index(ToName, Pos, Actors),
- FromIx = actor_index(FromName, Pos, Actors),
- if
- FromIx /= 0, ToIx /= 0, ToIx > FromIx ->
- Actors2 = lists:keydelete(FromName, Pos, Actors),
- Actors3 = insert_actor_after(From, To, Actors2),
- S2 = S#state{actors = Actors3},
- refresh_main_window(S2);
- FromIx /= 0, ToIx /= 0 ->
- Actors2 = lists:keydelete(FromName, Pos, Actors),
- Actors3 = insert_actor_before(From, To, Actors2),
- S2 = S#state{actors = Actors3},
- refresh_main_window(S2);
- true ->
- %% Ignore
- S
- end.
-
-insert_actor_after(From, To, [H | T]) ->
- case To#actor.name == H#actor.name of
- true -> [H, From | T];
- false -> [H | insert_actor_after(From, To, T)]
- end;
-insert_actor_after(_From, _To, []) ->
- [].
-
-insert_actor_before(From, To, [H | T]) ->
- case To#actor.name == H#actor.name of
- true -> [From, H | T];
- false -> [H | insert_actor_before(From, To, T)]
- end;
-insert_actor_before(_From, _To, []) ->
- [].
-
-actor_index(_Key, _Pos, []) ->
- 0;
-actor_index(Key, Pos, [H | T]) ->
- case Key == element(Pos, H) of
- false -> actor_index(Key, Pos, T) + 1;
- true -> 1
- end.
-
-y_to_n(Y, S) ->
- Y2 = ((Y / S#state.scale) - ?initial_y + (?incr_y / 2)),
- N = round(Y2 / ?incr_y - 0.2),
- MaxN = queue_length(S#state.events),
- if
- N =< 0 -> actor;
- N > MaxN -> actor;
- true -> {event, N}
- end.
-
-x_to_n(X, S) ->
- Scale = S#state.scale,
- Len = length(S#state.actors),
- X2 = X - (?initial_x * Scale),
- N = X2 / (?incr_x * Scale),
- N2 = trunc(N + 1.5),
- if
- N2 > Len -> Len;
- N2 < 1 -> 1;
- true -> N2
- end.
-
-write_text(Text, X, Y, Colour, S) ->
- Opt = [{coords, [{X, Y - (?incr_y * S#state.scale / 2)}]},
- {font, S#state.font}, {fg, Colour}, {text, Text}],
- gs:text(S#state.canvas, Opt).
-
-create_contents_window(Event, S) ->
- Options = [{viewer_pid, self()},
- {event, Event},
- {event_order, S#state.event_order},
- {active_filter, S#state.active_filter}
- | S#state.filters],
- case et_contents_viewer:start_link(Options) of
- {ok, _Pid} ->
- S;
- {error, Reason} ->
- ok = error_logger:format("~p(~p): create_contents_window(~p) ->~n ~p~n",
- [?MODULE, self(), Options, Reason]),
- S
- end.
-
-%%%----------------------------------------------------------------------
-%%% String padding of actors
-%%%----------------------------------------------------------------------
-
-create_actor(Name) ->
- String = name_to_string(Name),
- PaddedString = pad_string(String, 8),
- #actor{name = Name, string = PaddedString}.
-
-name_to_string(Name) ->
- case catch io_lib:format("~s", [Name]) of
- {'EXIT', _} -> lists:flatten(io_lib:format("~w", [Name]));
- GoodString -> lists:flatten(GoodString)
- end.
-
-pad_string(Atom, MinLen) when atom(Atom) ->
- pad_string(atom_to_list(Atom), MinLen);
-pad_string(String, MinLen) when integer(MinLen), MinLen >= 0 ->
- Len = length(String),
- case Len >= MinLen of
- true ->
- String;
- false ->
- String ++ lists:duplicate(MinLen - Len, $ )
- end.
-
-%%%----------------------------------------------------------------------
-%%% Queue management
-%%%----------------------------------------------------------------------
-
-queue_new() ->
- {0, [], []}.
-
-queue_in(X, {Size, In, Out}) ->
- {Size + 1, [X | In], Out}.
-
-%% queue_out(Q) ->
-%% case Q of
-%% {Size, In, [H | Out]} -> {{value, H}, {Size - 1, In, Out}};
-%% {Size, [], []} -> {empty, {Size, [], []}};
-%% {Size, In, _} -> queue_out({Size, [], lists:reverse(In)})
-%% end.
-
-queue_to_list({_Size, [], Out}) ->
- Out;
-queue_to_list({_Size, In, Out}) ->
- Out ++ lists:reverse(In).
-
-queue_length({Size, _In, _Out}) ->
- Size.
+call(ViewerPid, Request) ->
+ gen_server:call(ViewerPid, Request, infinity).
-list_to_queue(List) when list(List) ->
- {length(List), [], List}.
diff --git a/lib/et/src/et_wx_contents_viewer.erl b/lib/et/src/et_wx_contents_viewer.erl
new file mode 100644
index 0000000000..8a8d9ef1ee
--- /dev/null
+++ b/lib/et/src/et_wx_contents_viewer.erl
@@ -0,0 +1,700 @@
+%%
+%% %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: Displays details of a trace event
+%%----------------------------------------------------------------------
+
+-module(et_wx_contents_viewer).
+
+-behaviour(wx_object).
+
+%% External exports
+-export([start_link/1,
+ stop/1]).
+
+%% gen_server callbacks
+-export([init/1, terminate/2, code_change/3,
+ handle_call/3, handle_cast/2, handle_info/2,
+ handle_event/2]).
+
+-include("../include/et.hrl").
+-include("et_internal.hrl").
+-include_lib("wx/include/wx.hrl").
+
+-record(state, {parent_pid, % Pid of parent process
+ viewer_pid, % Pid of viewer process
+ event_order, % Field to be used as primary key
+ event, % The original event
+ filtered_event, % Event processed by active filter
+ active_filter, % Name of the active filter
+ filters, % List of possible filters
+ win, % GUI: Frame object
+ frame, % GUI: Frame object
+ panel, % GUI: Panel object
+ width, % GUI: Window width
+ height,
+ editor,
+ menu_data, % GUI: Window height
+ wx_debug, % GUI: WX debug level
+ trap_exit}). % trap_exit process flag
+
+%%%----------------------------------------------------------------------
+%%% Client side
+%%%----------------------------------------------------------------------
+
+%%----------------------------------------------------------------------
+%% start_link(Options) -> {ok, ContentsPid} | {error, Reason}
+%%
+%% Start a viewer for the event contents as window in GS
+%%
+%% Options = [option()]
+%%
+%% option() =
+%%
+%% {parent_pid, pid()} | % Pid of parent process
+%% {viewer_pid, pid()} | % Pid of viewer process
+%% {event_order, event_order()} | % Field to be used as primary key
+%% {active_filter, atom()} | % Name of the active filter
+%% {filter, atom(), fun()} % A named filter fun
+%%
+%% event_order() = 'trace_ts' | 'event_ts'
+%% ContentsPid = pid()
+%% Reason = term()
+%%----------------------------------------------------------------------
+
+start_link(Options) ->
+ case parse_opt(Options, default_state()) of
+ {ok, S} ->
+ try
+ WxRef = wx_object:start_link(?MODULE, [S], []),
+ Pid = wx_object:get_pid(WxRef),
+ if
+ S#state.parent_pid =/= self() ->
+ unlink(Pid);
+ true ->
+ ignore
+ end,
+ {ok, Pid}
+ catch
+ error:Reason ->
+ {error, {'EXIT', Reason, erlang:get_stacktrace()}}
+ end;
+ {error, Reason} ->
+ {error, Reason}
+ end.
+
+default_state() ->
+ #state{parent_pid = self(),
+ viewer_pid = undefined,
+ active_filter = ?DEFAULT_FILTER_NAME,
+ filters = [?DEFAULT_FILTER],
+ width = 600,
+ height = 300,
+ wx_debug = 0,
+ trap_exit = true}.
+
+parse_opt([], S) ->
+ Name = S#state.active_filter,
+ Filters = S#state.filters,
+ if
+ S#state.event =:= undefined ->
+ {error, {badarg, no_event}};
+ is_atom(Name) ->
+ case lists:keysearch(Name, #filter.name, Filters) of
+ {value, F} when is_record(F, filter) ->
+ {ok, S#state{active_filter = Name}};
+ false ->
+ {error, {badarg, {no_such_filter, Name, Filters}}}
+ end
+ end;
+parse_opt([H | T], S) ->
+ case H of
+ {parent_pid, ParentPid} when is_pid(ParentPid); ParentPid =:= undefined ->
+ parse_opt(T, S#state{parent_pid = ParentPid});
+ {viewer_pid, ViewerPid} when is_pid(ViewerPid) ->
+ parse_opt(T, S#state{viewer_pid = ViewerPid});
+ {wx_debug, Level} ->
+ parse_opt(T, S#state{wx_debug = Level});
+ {trap_exit, Bool} when Bool =:= true; Bool =:= false->
+ parse_opt(T, S#state{trap_exit = Bool});
+ {event_order, trace_ts} ->
+ parse_opt(T, S#state{event_order = trace_ts});
+ {event_order, event_ts} ->
+ parse_opt(T, S#state{event_order = event_ts});
+ {event, Event} when is_record(Event, event) ->
+ parse_opt(T, S#state{event = Event});
+ {active_filter, Name} when is_atom(Name) ->
+ parse_opt(T, S#state{active_filter = Name});
+ F when is_record(F, filter),
+ is_atom(F#filter.name),
+ is_function(F#filter.function) ->
+ Filters = lists:keydelete(F#filter.name, #filter.name, S#state.filters),
+ Filters2 = lists:keysort(#filter.name, [F | Filters]),
+ parse_opt(T, S#state{filters = Filters2});
+ {width, Width} when is_integer(Width), Width > 0 ->
+ parse_opt(T, S#state{width = Width});
+ {height, Height} when is_integer(Height), Height > 0 ->
+ parse_opt(T, S#state{height = Height});
+ Bad ->
+ {error, {bad_option, Bad}}
+ end;
+parse_opt(BadList, _S) ->
+ {error, {bad_option_list, BadList}}.
+
+%%----------------------------------------------------------------------
+%% stop(ContentsPid) -> ok
+%%
+%% Stops a contents viewer process
+%%
+%% ContentsPid = pid()
+%%----------------------------------------------------------------------
+
+stop(ContentsPid) when is_pid(ContentsPid) ->
+ Type = process,
+ MonitorRef = erlang:monitor(Type, ContentsPid),
+ ContentsPid ! {stop, self()},
+ receive
+ {'DOWN', MonitorRef, Type, ContentsPid, shutdown} ->
+ ok;
+ {'DOWN', MonitorRef, Type, ContentsPid, Reason} ->
+ {error, Reason}
+ end.
+
+%% call(Frame, Request) ->
+%% wx_object:call(Frame, Request, infinity).
+
+%%%----------------------------------------------------------------------
+%%% Callback functions from gen_server
+%%%----------------------------------------------------------------------
+
+%%----------------------------------------------------------------------
+%% Func: init/1
+%% Returns: {ok, State} |
+%% {ok, State, Timeout} |
+%% ignore |
+%% {stop, Reason}
+%%----------------------------------------------------------------------
+
+init([S]) when is_record(S, state) ->
+ process_flag(trap_exit, S#state.trap_exit),
+ case S#state.parent_pid of
+ undefined -> ok;
+ ParentPid -> link(ParentPid)
+ end,
+ wx:debug(S#state.wx_debug),
+ S2 = create_window(S),
+ {S2#state.frame, S2}.
+
+%%----------------------------------------------------------------------
+%% Func: handle_call/3
+%% Returns: {reply, Reply, State} |
+%% {reply, Reply, State, Timeout} |
+%% {noreply, State} |
+%% {noreply, State, Timeout} |
+%% {stop, Reason, Reply, State} | (terminate/2 is called)
+%% {stop, Reason, State} (terminate/2 is called)
+%%----------------------------------------------------------------------
+
+handle_call(Request, From, S) ->
+ ok = error_logger:format("~p(~p): handle_call(~p, ~p, ~p)~n",
+ [?MODULE, self(), Request, From, S]),
+ Reply = {error, {bad_request, Request}},
+ {reply, Reply, S}.
+
+%%----------------------------------------------------------------------
+%% Func: handle_cast/2
+%% Returns: {noreply, State} |
+%% {noreply, State, Timeout} |
+%% {stop, Reason, State} (terminate/2 is called)
+%%----------------------------------------------------------------------
+
+handle_cast(Msg, S) ->
+ ok = error_logger:format("~p(~p): handle_cast(~p, ~p)~n",
+ [?MODULE, self(), Msg, S]),
+ {noreply, S}.
+
+%%----------------------------------------------------------------------
+%% Func: handle_event/2
+%% Returns: {noreply, State} |
+%% {noreply, State, Timeout} |
+%% {stop, Reason, State} (terminate/2 is called)
+%%----------------------------------------------------------------------
+
+handle_event(#wx{id = Id,
+ event = #wxCommand{type = command_menu_selected}},
+ S) ->
+ case proplists:get_value(Id, S#state.menu_data) of
+ undefined ->
+ ignore;
+ Data when is_record(Data, filter) ->
+ F = Data,
+ ChildState= S#state{active_filter = F#filter.name},
+ case wx_object:start_link(?MODULE, [ChildState], []) of
+ {ok, Pid} when S#state.parent_pid =/= self() ->
+ unlink(Pid);
+ _ ->
+ ignore
+ end;
+ {hide, Actors} ->
+ send_viewer_event(S, {delete_actors, Actors});
+ {show, Actors} ->
+ send_viewer_event(S, {insert_actors, Actors});
+ {mode, Mode} ->
+ send_viewer_event(S, {mode, Mode});
+ Nyi ->
+ ok = error_logger:format("~p: click ~p ignored (nyi)~n",
+ [?MODULE, Nyi])
+ end,
+ case Id of
+ ?wxID_EXIT ->
+ wxFrame:destroy(S#state.frame),
+ opt_unlink(S#state.parent_pid),
+ {stop, shutdown, S};
+ ?wxID_SAVE ->
+ Event = S#state.event,
+ TimeStamp =
+ case S#state.event_order of
+ trace_ts -> Event#event.trace_ts;
+ event_ts -> Event#event.event_ts
+ end,
+ FileName = lists:flatten(["et_contents_viewer_", now_to_string(TimeStamp), ".txt"]),
+ Style = ?wxFD_SAVE bor ?wxFD_OVERWRITE_PROMPT,
+ Msg = "Select a file to the events to",
+ case select_file(S#state.frame, Msg, filename:absname(FileName), Style) of
+ {ok, FileName2} ->
+ Bin = list_to_binary(event_to_string(Event, S#state.event_order)),
+ file:write_file(FileName2, Bin);
+ cancel ->
+ ok
+ end,
+ {noreply, S};
+ ?wxID_PRINT ->
+ Html = wxHtmlEasyPrinting:new([{parentWindow, S#state.win}]),
+ Text = "<pre>" ++ wxTextCtrl:getValue(S#state.editor) ++ "</pre>",
+ wxHtmlEasyPrinting:previewText(Html, Text),
+ {noreply, S};
+ _ ->
+ {noreply, S}
+ end;
+handle_event(#wx{event = #wxKey{rawCode = KeyCode}}, S) ->
+ case KeyCode of
+ $c ->
+ wxFrame:destroy(S#state.frame),
+ opt_unlink(S#state.parent_pid),
+ {stop, normal, S};
+ $f ->
+ E = S#state.filtered_event,
+ From = E#event.from,
+ send_viewer_event(S, {delete_actors, [From]}),
+ {noreply, S};
+ $t ->
+ E = S#state.filtered_event,
+ To = E#event.to,
+ send_viewer_event(S, {delete_actors, [To]}),
+ {noreply, S};
+ $b ->
+ E = S#state.filtered_event,
+ From = E#event.from,
+ To = E#event.to,
+ send_viewer_event(S, {delete_actors, [From, To]}),
+ {noreply, S};
+
+ $F ->
+ E = S#state.filtered_event,
+ From = E#event.from,
+ send_viewer_event(S, {insert_actors, [From]}),
+ {noreply, S};
+ $T ->
+ E = S#state.filtered_event,
+ To = E#event.to,
+ send_viewer_event(S, {insert_actors, [To]}),
+ {noreply, S};
+ $B ->
+ E = S#state.filtered_event,
+ From = E#event.from,
+ To = E#event.to,
+ send_viewer_event(S, {insert_actors, [From, To]}),
+ {noreply, S};
+
+ $s ->
+ E = S#state.filtered_event,
+ From = E#event.from,
+ To = E#event.to,
+ First = et_collector:make_key(S#state.event_order, E),
+ Mode = {search_actors, forward, First, [From, To]},
+ send_viewer_event(S, {mode, Mode}),
+ {noreply, S};
+ $r ->
+ E = S#state.filtered_event,
+ From = E#event.from,
+ To = E#event.to,
+ First = et_collector:make_key(S#state.event_order, E),
+ Mode = {search_actors, reverse, First, [From, To]},
+ send_viewer_event(S, {mode, Mode}),
+ {noreply, S};
+ $a ->
+ send_viewer_event(S, {mode, all}),
+ {noreply, S};
+
+ $0 ->
+ case lists:keysearch(?DEFAULT_FILTER_NAME, #filter.name, S#state.filters) of
+ {value, F} when is_record(F, filter) ->
+ ChildState= S#state{active_filter = F#filter.name},
+ case wx_object:start_link(?MODULE, [ChildState], []) of
+ {ok, Pid} when S#state.parent_pid =/= self() ->
+ unlink(Pid);
+ _ ->
+ ignore
+ end;
+ false ->
+ ignore
+ end,
+ {noreply, S};
+ Int when is_integer(Int), Int > $0, Int =< $9 ->
+ case catch lists:nth(Int-$0, S#state.filters) of
+ F when is_record(F, filter) ->
+ ChildState= S#state{active_filter = F#filter.name},
+ case wx_object:start_link(?MODULE, [ChildState], []) of
+ {ok, Pid} when S#state.parent_pid =/= self() ->
+ unlink(Pid);
+ _ ->
+ ignore
+ end;
+ {'EXIT', _} ->
+ ignore
+ end,
+ {noreply, S};
+
+ _ ->
+ io:format("~p: ignored: ~p~n", [?MODULE, KeyCode]),
+ {noreply, S}
+ end;
+handle_event(#wx{event = #wxClose{}}, S) ->
+ opt_unlink(S#state.parent_pid),
+ {stop, shutdown, S};
+handle_event(#wx{event = #wxSize{size = {W, H}}}, S) ->
+ S2 = S#state{width = W, height = H},
+ {noreply, S2};
+handle_event(Wx = #wx{}, S) ->
+ io:format("~p got an unexpected event: ~p\n", [self(), Wx]),
+ {noreply, S}.
+
+%%----------------------------------------------------------------------
+%% Func: handle_info/2
+%% Returns: {noreply, State} |
+%% {noreply, State, Timeout} |
+%% {stop, Reason, State} (terminate/2 is called)
+%%----------------------------------------------------------------------
+
+handle_info({stop, _From}, S) ->
+ wxFrame:destroy(S#state.frame),
+ opt_unlink(S#state.parent_pid),
+ {stop, shutdown, S};
+handle_info({'EXIT', Pid, Reason}, S) ->
+ if
+ Pid =:= S#state.parent_pid ->
+ wxFrame:destroy(S#state.frame),
+ opt_unlink(S#state.parent_pid),
+ {stop, Reason, S};
+ true ->
+ {noreply, S}
+ end;
+handle_info(Info, S) ->
+ ok = error_logger:format("~p(~p): handle_info(~p, ~p)~n",
+ [?MODULE, self(), Info, S]),
+ {noreply, S}.
+
+%%----------------------------------------------------------------------
+%% Func: terminate/2
+%% Purpose: Shutdown the server
+%% Returns: any (ignored by gen_server)
+%%----------------------------------------------------------------------
+
+terminate(_Reason, _S) ->
+ ignore.
+
+%%----------------------------------------------------------------------
+%% Func: code_change/3
+%% Purpose: Convert process state when code is changed
+%% Returns: {ok, NewState}
+%%----------------------------------------------------------------------
+
+code_change(_OldVsn, S, _Extra) ->
+ {ok, S}.
+
+%%%----------------------------------------------------------------------
+%%% Handle graphics
+%%%----------------------------------------------------------------------
+
+opt_unlink(Pid) ->
+ if
+ Pid =:= undefined ->
+ ignore;
+ true ->
+ unlink(Pid)
+ end.
+
+create_window(S) ->
+ H = S#state.height,
+ W = S#state.width,
+ Name = S#state.active_filter,
+ Title = lists:concat([?MODULE, " (filter: ", Name, ")"]),
+ WinOpt = [{size, {W,H}}],
+ Frame = wxFrame:new(wx:null(), ?wxID_ANY, Title, WinOpt),
+ wxFrame:createStatusBar(Frame),
+
+ Panel = wxPanel:new(Frame, []),
+ Bar = wxMenuBar:new(),
+ wxFrame:setMenuBar(Frame,Bar),
+ create_file_menu(Bar),
+ Editor = wxTextCtrl:new(Panel, ?wxID_ANY, [{style, 0
+ bor ?wxDEFAULT
+ bor ?wxTE_MULTILINE
+ bor ?wxTE_READONLY
+ bor ?wxTE_DONTWRAP}]),
+ Font = wxFont:new(10, ?wxFONTFAMILY_TELETYPE, ?wxNORMAL, ?wxNORMAL,[]),
+ TextAttr = wxTextAttr:new(?wxBLACK, [{font, Font}]),
+ wxTextCtrl:setDefaultStyle(Editor, TextAttr),
+ Sizer = wxBoxSizer:new(?wxHORIZONTAL),
+ wxSizer:add(Sizer, Editor, [{flag, ?wxEXPAND}, {proportion, 1}]),
+ FilteredEvent = config_editor(Editor, S),
+ S2 = S#state{win = Frame, panel = Panel, filtered_event = FilteredEvent},
+ HideData = create_hide_menu(Bar, S2),
+ SearchData = create_search_menu(Bar, S2),
+ FilterData = create_filter_menu(Bar, S#state.filters),
+ wxFrame:connect(Frame, command_menu_selected, []),
+ wxFrame:connect(Frame, key_up),
+ wxFrame:connect(Frame, close_window, [{skip,true}]),
+ wxFrame:setFocus(Frame),
+ wxPanel:setSizer(Panel, Sizer),
+ wxFrame:show(Frame),
+ S2#state{menu_data = HideData++SearchData++FilterData, editor = Editor, frame = Frame}.
+
+menuitem(Menu, Id, Text, UserData) ->
+ Item = wxMenu:append(Menu, Id, Text),
+ {wxMenuItem:getId(Item), UserData}.
+
+create_file_menu(Bar) ->
+ Menu = wxMenu:new([]),
+ wxMenu:append(Menu, ?wxID_SAVE, "Save"),
+ wxMenu:append(Menu, ?wxID_PRINT,"Print"),
+ wxMenu:appendSeparator(Menu),
+ wxMenu:append(Menu, ?wxID_EXIT, "Close"),
+ wxMenuBar:append(Bar, Menu, "File").
+
+create_filter_menu(Bar, Filters) ->
+ Menu = wxMenu:new([]),
+ wxMenuItem:enable(wxMenu:append(Menu, ?wxID_ANY, "Select Filter"), [{enable, false}]),
+ wxMenu:appendSeparator(Menu),
+ Item = fun(F, {N,Acc}) when F#filter.name =:= ?DEFAULT_FILTER_NAME->
+ Label = lists:concat([pad_string(F#filter.name, 20, $\ , right), "(0)"]),
+ MenuItem = menuitem(Menu, ?wxID_ANY, Label, F),
+ {N + 1, [MenuItem|Acc]};
+ (F, {N, Acc}) ->
+ Name = F#filter.name,
+ Label = lists:concat([pad_string(Name, 20, $\ , right), "(", N, ")"]),
+ MenuItem = menuitem(Menu, ?wxID_ANY, Label, F),
+ {N + 1, [MenuItem|Acc]}
+ end,
+ Filters2 = lists:keysort(#filter.name, Filters),
+ {_,MenuData} = lists:foldl(Item, {1, []}, Filters2),
+ wxMenuBar:append(Bar, Menu, "Filters"),
+ MenuData.
+
+create_hide_menu(Bar, S) ->
+ Menu = wxMenu:new([]),
+ E = S#state.filtered_event,
+ From = E#event.from,
+ To = E#event.to,
+ MenuData =
+ if
+ S#state.viewer_pid =:= undefined ->
+ ignore;
+ From =:= To ->
+ wxMenuItem:enable(wxMenu:append(Menu, ?wxID_ANY, "Hide actor in Viewer "),
+ [{enable, false}]),
+ wxMenu:appendSeparator(Menu),
+ Hide = menuitem(Menu, ?wxID_ANY, "From=To (f|t|b)", {hide, [From]}),
+ wxMenu:appendSeparator(Menu),
+ wxMenuItem:enable(wxMenu:append(Menu, ?wxID_ANY, "Show actor in Viewer "),
+ [{enable, false}]),
+ wxMenu:appendSeparator(Menu),
+ Show = menuitem(Menu, ?wxID_ANY, "From=To (F|T|B)", {show, [From]}),
+ [Show,Hide];
+ true ->
+ wxMenuItem:enable(wxMenu:append(Menu, ?wxID_ANY, "Hide actor in Viewer "),
+ [{enable, false}]),
+ wxMenu:appendSeparator(Menu),
+ Hide = [menuitem(Menu, ?wxID_ANY, "From (f)", {hide, [From]}),
+ menuitem(Menu, ?wxID_ANY, "To (t)", {hide, [To]}),
+ menuitem(Menu, ?wxID_ANY, "Both (b)", {hide, [From, To]})],
+ wxMenu:appendSeparator(Menu),
+ wxMenuItem:enable(wxMenu:append(Menu, ?wxID_ANY, "Show actor in Viewer "),
+ [{enable, false}]),
+ wxMenu:appendSeparator(Menu),
+ Show = [menuitem(Menu, ?wxID_ANY, "From (F)", {show, [From]}),
+ menuitem(Menu, ?wxID_ANY, "To (T)", {show, [To]}),
+ menuitem(Menu, ?wxID_ANY, "Both (B)", {show, [From, To]})],
+ Show++Hide
+ end,
+ wxMenuBar:append(Bar, Menu, "Hide"),
+ MenuData.
+
+create_search_menu(Bar, S) ->
+ Menu = wxMenu:new([]),
+ E = S#state.filtered_event,
+ From = E#event.from,
+ To = E#event.to,
+ wxMenuItem:enable(wxMenu:append(Menu, ?wxID_ANY, "Search in Viewer "),
+ [{enable, false}]),
+ wxMenu:appendSeparator(Menu),
+ MenuData =
+ if
+ S#state.viewer_pid =:= undefined ->
+ [menuitem(Menu, ?wxID_ANY, "Abort search. Display all (a)", {mode, all})];
+ From =:= To ->
+ Key = et_collector:make_key(S#state.event_order, E),
+ ModeS = {search_actors, forward, Key, [From]},
+ ModeR = {search_actors, reverse, Key, [From]},
+ [menuitem(Menu, ?wxID_ANY, "Forward from this event (s)", {mode, ModeS}),
+ menuitem(Menu, ?wxID_ANY, "Reverse from this event (r)", {mode, ModeR}),
+ menuitem(Menu, ?wxID_ANY, "Abort search. Display all (a)", {mode, all})];
+ true ->
+ Key = et_collector:make_key(S#state.event_order, E),
+ ModeS = {search_actors, forward, Key, [From, To]},
+ ModeR = {search_actors, reverse, Key, [From, To]},
+ [menuitem(Menu, ?wxID_ANY, "Forward from this event (s)", {mode, ModeS}),
+ menuitem(Menu, ?wxID_ANY, "Reverse from this event (r)", {mode, ModeR}),
+ menuitem(Menu, ?wxID_ANY, "Abort search. Display all (a)", {mode, all})]
+ end,
+ wxMenuBar:append(Bar, Menu, "Search"),
+ MenuData.
+
+config_editor(Editor, S) ->
+ Event = S#state.event,
+ Name = S#state.active_filter,
+ {value, F} = lists:keysearch(Name, #filter.name, S#state.filters),
+ FilterFun = F#filter.function,
+ case catch FilterFun(Event) of
+ true ->
+ do_config_editor(Editor, Event, lightblue, S#state.event_order);
+ {true, Event2} when is_record(Event2, event) ->
+ do_config_editor(Editor, Event2, lightblue, S#state.event_order);
+ false ->
+ do_config_editor(Editor, Event, red, S#state.event_order);
+ Bad ->
+ Contents = {bad_filter, Name, Bad},
+ BadEvent = Event#event{contents = Contents},
+ do_config_editor(Editor, BadEvent, red, S#state.event_order)
+ end.
+
+do_config_editor(Editor, Event, _Colour, TsKey) ->
+ String = event_to_string(Event, TsKey),
+ wxTextCtrl:appendText(Editor, String),
+ Event.
+
+%%%----------------------------------------------------------------------
+%%% String handling
+%%%----------------------------------------------------------------------
+
+term_to_string(Term) ->
+ case catch io_lib:format("~s", [Term]) of
+ {'EXIT', _} -> io_lib:format("~p", [Term]);
+ GoodString -> GoodString
+ end.
+
+now_to_string({Mega, Sec, Micro} = Now)
+ when is_integer(Mega), is_integer(Sec), is_integer(Micro) ->
+ {{Y, Mo, D}, {H, Mi, S}} = calendar:now_to_universal_time(Now),
+ lists:concat([Y, "-",
+ pad_string(Mo, 2, $0, left), "-",
+ pad_string(D, 2, $0, left),
+ "T",
+ pad_string(H, 2, $0, left), ":",
+ pad_string(Mi, 2, $0, left), ":",
+ pad_string(S, 2, $0, left), ".",
+ Micro]);
+now_to_string(Other) ->
+ term_to_string(Other).
+
+event_to_string(Event, TsKey) ->
+ ReportedTs = Event#event.trace_ts,
+ ParsedTs = Event#event.event_ts,
+ Deep =
+ ["DETAIL LEVEL: ", term_to_string(Event#event.detail_level),
+ "\nLABEL: ", term_to_string(Event#event.label),
+ case Event#event.from =:= Event#event.to of
+ true ->
+ ["\nACTOR: ", term_to_string(Event#event.from)];
+ false ->
+ ["\nFROM: ", term_to_string(Event#event.from),
+ "\nTO: ", term_to_string(Event#event.to)]
+ end,
+ case ReportedTs =:= ParsedTs of
+ true ->
+ ["\nPARSED: ", now_to_string(ParsedTs)];
+ false ->
+ case TsKey of
+ trace_ts ->
+ ["\nTRACE_TS: ", now_to_string(ReportedTs),
+ "\nEVENT_TS: ", now_to_string(ParsedTs)];
+ event_ts ->
+ ["\nEVENT_TS: ", now_to_string(ParsedTs),
+ "\nTRACE_TS: ", now_to_string(ReportedTs)]
+ end
+ end,
+ "\nCONTENTS:\n\n", term_to_string(Event#event.contents)],
+ lists:flatten(Deep).
+
+pad_string(Int, MinLen, Char, Dir) when is_integer(Int) ->
+ pad_string(integer_to_list(Int), MinLen, Char, Dir);
+pad_string(Atom, MinLen, Char, Dir) when is_atom(Atom) ->
+ pad_string(atom_to_list(Atom), MinLen, Char, Dir);
+pad_string(String, MinLen, Char, Dir) when is_integer(MinLen), MinLen >= 0 ->
+ Len = length(String),
+ case {Len >= MinLen, Dir} of
+ {true, _} ->
+ String;
+ {false, right} ->
+ String ++ lists:duplicate(MinLen - Len, Char);
+ {false, left} ->
+ lists:duplicate(MinLen - Len, Char) ++ String
+ end.
+
+send_viewer_event(S, Event) ->
+ case S#state.viewer_pid of
+ ViewerPid when is_pid(ViewerPid) ->
+ ViewerPid ! {et, Event};
+ undefined ->
+ ignore
+ end.
+
+select_file(Frame, Message, DefaultFile, Style) ->
+ Dialog = wxFileDialog:new(Frame,
+ [{message, Message},
+ {defaultDir, filename:dirname(DefaultFile)},
+ {defaultFile, filename:basename(DefaultFile)},
+ {style, Style}]),
+ Choice =
+ case wxMessageDialog:showModal(Dialog) of
+ ?wxID_CANCEL -> cancel;
+ ?wxID_OK -> {ok, wxFileDialog:getPath(Dialog)}
+ end,
+ wxFileDialog:destroy(Dialog),
+ Choice.
diff --git a/lib/et/src/et_wx_viewer.erl b/lib/et/src/et_wx_viewer.erl
new file mode 100644
index 0000000000..5cd3563aed
--- /dev/null
+++ b/lib/et/src/et_wx_viewer.erl
@@ -0,0 +1,2122 @@
+%%
+%% %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: Displays a sequence chart for trace events (messages/actions)
+%%----------------------------------------------------------------------
+
+-module(et_wx_viewer).
+
+-behaviour(gen_server).
+
+%% External exports
+-export([start_link/1]).
+
+%% gen_server callbacks
+-export([init/1, terminate/2, code_change/3,
+ handle_call/3, handle_cast/2, handle_info/2]).
+
+-include("../include/et.hrl").
+-include("et_internal.hrl").
+-include_lib("wx/include/wx.hrl").
+
+-define(unknown, "UNKNOWN").
+-define(initial_x, 10).
+-define(incr_x, 60).
+-define(initial_y, 15).
+-define(incr_y, 15).
+
+-record(state,
+ {parent_pid, % Pid of parent process
+ auto_shutdown, % Shutdown collector when last subscriber dies
+ collector_pid, % Pid of collector process
+ event_order, % Field to be used as primary key
+ trace_pattern, % Collector trace pattern
+ active_filter, % Name of the active filter
+ filters, % List of possible filters
+ filter_menu,
+ pending_actor, % Pending actor - move or toggle
+ first_event, % Key of first event (regardless of visibility)
+ last_event, % Key of last event (regardless of visibility)
+ events_per_page, % Maximum number of shown events
+ events, % Queue containg all event keys (regardless of visibility)
+ n_events, % Number of events available in the collector
+ max_actors, % Maximum number of shown actors
+ actors, % List of known actors
+ refresh_needed, % Refresh is needed in order to show all actors
+ detail_level, % Show only events with lesser detail level
+ hide_actions, % Hide/show events where to == from actor (bool)
+ hide_actors, % Hide/show events with unknown actor (bool)
+ display_all,
+ context, % display | print
+ title, % GUI: Window title
+ frame, % GUI: Window object
+ menubar, % GUI: Menu bar object
+ packer, % GUI: Packer object
+ width, % GUI: Window width
+ height, % GUI: Window height
+ scale, % GUI: Scaling factor on canvas
+ normal_font, % GUI: Font to be used on text labels
+ bold_font, % GUI: Font to be used on text labels
+ pen,
+ brush,
+ print_psdd,
+ print_d,
+ canvas_width, % GUI: Canvas width
+ canvas_height, % GUI: Canvas height
+ canvas, % GUI: Canvas object
+ canvas_sizer,
+ scroll_bar, % GUI: Canvas scroll bar
+ y_pos, % GUI: Current y position on canvas
+ menu_data,
+ checkbox_data,
+ hide_actions_box,
+ hide_actors_box,
+ status_bar,
+ event_file,
+ wx_debug, % GUI: WX debug level
+ trap_exit}). % trap_exit process flag
+
+
+-record(actor, {name, string, include, exclude}).
+-record(e, {pos, key, event}).
+
+%%%----------------------------------------------------------------------
+%%% Client side
+%%%----------------------------------------------------------------------
+
+start_link(Options) ->
+ case parse_opt(Options, default_state(), []) of
+ {ok, S, CollectorOpt} ->
+ case S#state.collector_pid of
+ CollectorPid when is_pid(CollectorPid) ->
+ case gen_server:start_link(?MODULE, [S], []) of
+ {ok, Pid} when S#state.parent_pid =/= self() ->
+ unlink(Pid),
+ {ok, Pid};
+ Other ->
+ Other
+ end;
+ undefined ->
+ case et_collector:start_link([{auto_shutdown, true} | CollectorOpt]) of
+ {ok, CollectorPid} ->
+ S2 = S#state{collector_pid = CollectorPid},
+ case gen_server:start_link(?MODULE, [S2], []) of
+ {ok, Pid} when S#state.parent_pid =/= self() ->
+ unlink(Pid),
+ {ok, Pid};
+ Other ->
+ Other
+ end;
+ {error, Reason} ->
+ {error, {et_collector, Reason}}
+ end
+ end;
+ {error, Reason} ->
+ {error, Reason}
+ end.
+
+default_state() ->
+ #state{parent_pid = self(),
+ collector_pid = undefined,
+ n_events = 0,
+ detail_level = ?detail_level_max,
+ active_filter = ?DEFAULT_FILTER_NAME,
+ filters = [?DEFAULT_FILTER],
+ event_order = trace_ts,
+ events_per_page = 100,
+ first_event = first,
+ last_event = first,
+ events = queue_new(),
+ max_actors = 5,
+ actors = [create_actor(?unknown)],
+ pending_actor = ?unknown,
+ hide_actions = false,
+ hide_actors = false,
+ display_all = true,
+ context = display,
+ refresh_needed = false,
+ scale = 2,
+ canvas_height = 0,
+ canvas_width = 0,
+ width = 800,
+ height = 600,
+ event_file = filename:absname("et_viewer.etrace"),
+ wx_debug = 0,
+ trap_exit = true}.
+
+parse_opt([], S, CollectorOpt) ->
+ {ok, S, [{parent_pid, S#state.parent_pid} | CollectorOpt]};
+parse_opt([H | T], S, CollectorOpt) ->
+ case H of
+ {parent_pid, Parent} when is_pid(Parent); Parent =:= undefined ->
+ parse_opt(T, S#state{parent_pid = Parent}, CollectorOpt);
+ {wx_debug, Level} ->
+ parse_opt(T, S#state{wx_debug = Level}, CollectorOpt);
+ {trap_exit, Bool} when Bool =:= true; Bool =:= false->
+ parse_opt(T, S#state{trap_exit = Bool}, CollectorOpt);
+ {title, Title} ->
+ parse_opt(T, S#state{title = name_to_string(Title)}, CollectorOpt);
+ {detail_level, Level} when is_integer(Level),
+ Level >= ?detail_level_min,
+ Level =< ?detail_level_max ->
+ parse_opt(T, S#state{detail_level = Level}, CollectorOpt);
+ {detail_level, max} ->
+ parse_opt(T, S#state{detail_level = ?detail_level_max}, CollectorOpt);
+ {detail_level, min} ->
+ parse_opt(T, S#state{detail_level = ?detail_level_min}, CollectorOpt);
+ {scale, Scale} when is_integer(Scale), Scale > 0 ->
+ parse_opt(T, S#state{scale = Scale}, CollectorOpt);
+ {width, W} when is_integer(W), W > 0 ->
+ parse_opt(T, S#state{width = W, canvas_width = W}, CollectorOpt);
+ {height, WH} when is_integer(WH), WH > 0 ->
+ parse_opt(T, S#state{height = WH, canvas_height = WH}, CollectorOpt);
+ {collector_pid, Pid} when is_pid(Pid) ->
+ parse_opt(T, S#state{collector_pid = Pid}, CollectorOpt);
+ {collector_pid, undefined} ->
+ parse_opt(T, S#state{collector_pid = undefined}, CollectorOpt);
+ {active_filter, Name} when is_atom(Name) ->
+ parse_opt(T, S#state{active_filter = Name}, CollectorOpt);
+ {event_order, trace_ts} -> %% BUGBUG: Verify event_order with collector
+ CollectorOpt2 = [H | CollectorOpt],
+ parse_opt(T, S#state{event_order = trace_ts}, CollectorOpt2);
+ {event_order, event_ts} -> %% BUGBUG: Verify event_order with collector
+ CollectorOpt2 = [H | CollectorOpt],
+ parse_opt(T, S#state{event_order = event_ts}, CollectorOpt2);
+ {trace_port, _Port} ->
+ CollectorOpt2 = [H | CollectorOpt],
+ parse_opt(T, S, CollectorOpt2);
+ {trace_max_queue, _Queue} ->
+ CollectorOpt2 = [H | CollectorOpt],
+ parse_opt(T, S, CollectorOpt2);
+ {trace_pattern, _Pattern} ->
+ CollectorOpt2 = [H | CollectorOpt],
+ parse_opt(T, S, CollectorOpt2);
+ {trace_global, _Boolean} ->
+ CollectorOpt2 = [H | CollectorOpt],
+ parse_opt(T, S, CollectorOpt2);
+ {trace_client, _Client} ->
+ CollectorOpt2 = [H | CollectorOpt],
+ parse_opt(T, S, CollectorOpt2);
+ {dict_insert, {filter, Name}, Fun} ->
+ if
+ is_atom(Name), is_function(Fun) ->
+ F = #filter{name = Name, function = Fun},
+ Filters = lists:keydelete(Name, #filter.name, S#state.filters),
+ CollectorOpt2 = [H | CollectorOpt],
+ parse_opt(T, S#state{filters = Filters ++ [F]}, CollectorOpt2);
+ true ->
+ {error, {bad_option, H}}
+ end;
+ {dict_insert, {subscriber, Pid}, _Val} ->
+ if
+ is_pid(Pid) ->
+ CollectorOpt2 = [H | CollectorOpt],
+ parse_opt(T, S, CollectorOpt2);
+ true ->
+ {error, {bad_option, H}}
+ end;
+ {dict_insert, _Key, _Val} ->
+ CollectorOpt2 = [H | CollectorOpt],
+ parse_opt(T, S, CollectorOpt2);
+ {dict_delete, {filter, Name}} ->
+ Filters = lists:keydelete(Name, #filter.name, S#state.filters),
+ CollectorOpt2 = [H | CollectorOpt],
+ parse_opt(T, S#state{filters = Filters}, CollectorOpt2);
+ {dict_delete, _Key} ->
+ CollectorOpt2 = [H | CollectorOpt],
+ parse_opt(T, S, CollectorOpt2);
+ {max_events, _Max} ->
+ %% Kept for backward compatibility
+ parse_opt(T, S, CollectorOpt);
+ {max_actors, Max} when is_integer(Max), Max >= 0 ->
+ parse_opt(T, S#state{max_actors = Max}, CollectorOpt);
+ {max_actors, Max} when Max =:= infinity ->
+ parse_opt(T, S#state{max_actors = Max}, CollectorOpt);
+ {actors, ActorNames} when is_list(ActorNames) ->
+ ActorNames2 =
+ case lists:member(?unknown, ActorNames) of
+ false -> [?unknown | ActorNames];
+ true -> ActorNames
+ end,
+ Actors = [create_actor(Name) || Name <- ActorNames2],
+ parse_opt(T, S#state{actors = Actors}, CollectorOpt);
+ {include, ActorNames} when is_list(ActorNames) ->
+ Actors = [opt_create_actor(Name, include, S#state.actors) || Name <- ActorNames],
+ parse_opt(T, S#state{actors = Actors}, CollectorOpt);
+ {exclude, ActorNames} when is_list(ActorNames) ->
+ Actors = [opt_create_actor(Name, exclude, S#state.actors) || Name <- ActorNames],
+ parse_opt(T, S#state{actors = Actors}, CollectorOpt);
+ {first_event, _FirstKey} ->
+ %% NYI
+ parse_opt(T, S, CollectorOpt);
+ {hide_actors, Bool} when Bool =:= true; Bool =:= false ->
+ parse_opt(T, S#state{hide_actors = Bool}, CollectorOpt);
+ {hide_actions, Bool} when Bool =:= true; Bool =:= false ->
+ parse_opt(T, S#state{hide_actions = Bool}, CollectorOpt);
+ {hide_unknown, Bool} when Bool =:= true; Bool =:= false ->
+ %% Kept for backward compatibility
+ parse_opt(T, S, CollectorOpt);
+ {display_mode, _Mode} ->
+ %% Kept for backward compatibility
+ parse_opt(T, S, CollectorOpt);
+ Bad ->
+ {error, {bad_option, Bad}}
+ end;
+parse_opt(BadList, _S, _CollectorOpt) ->
+ {error, {bad_option_list, BadList}}.
+
+do_dict_insert({filter, Name}, Fun, S) when is_atom(Name), is_function(Fun) ->
+ F = #filter{name = Name, function = Fun},
+ Filters = lists:keydelete(Name, #filter.name, S#state.filters),
+ Filters2 = lists:keysort(#filter.name, [F | Filters]),
+ S2 = create_filter_menu(S, S#state.active_filter, Filters2),
+ S2#state{filters = Filters2};
+do_dict_insert(_Key, _Val, S) ->
+ %%ok = error_logger:format("~p(~p): handle_info({et, {dict_insert, ~p, ~p}})~n",
+ %% [?MODULE, self(), Key, Val]),
+ S.
+
+do_dict_delete({filter, Name}, S) when is_atom(Name), Name =/= S#state.active_filter ->
+ Filters = lists:keydelete(Name, #filter.name, S#state.filters),
+ S2 = create_filter_menu(S, S#state.active_filter, Filters),
+ S2#state{filters = Filters};
+do_dict_delete(_Key, S) ->
+ %% ok = error_logger:format("~p(~p): handle_info({et, {dict_delete, ~p}})~n",
+ %% [?MODULE, self(), Key]),
+ S.
+
+%%%----------------------------------------------------------------------
+%%% Callback functions from gen_server
+%%%----------------------------------------------------------------------
+
+%%----------------------------------------------------------------------
+%% Func: init/1
+%% Returns: {ok, State} |
+%% {ok, State, Timeout} |
+%% ignore |
+%% {stop, Reason}
+%%----------------------------------------------------------------------
+
+init([S]) when is_record(S, state) ->
+ process_flag(trap_exit, S#state.trap_exit),
+ case S#state.parent_pid of
+ undefined -> ok;
+ ParentPid -> link(ParentPid)
+ end,
+ wx:new(),
+ wx:debug(S#state.wx_debug),
+ et_collector:dict_insert(S#state.collector_pid,
+ {subscriber, self()},
+ ?MODULE),
+ S2 = create_main_window(S),
+ EventsPerPage = events_per_page(S2, S2#state.height),
+ S3 = revert_main_window(S2#state{events_per_page = EventsPerPage}),
+ Timeout = timeout(S3),
+ {ok, S3, Timeout}.
+
+%%----------------------------------------------------------------------
+%% Func: handle_call/3
+%% Returns: {reply, Reply, State} |
+%% {reply, Reply, State, Timeout} |
+%% {noreply, State} |
+%% {noreply, State, Timeout} |
+%% {stop, Reason, Reply, State} | (terminate/2 is called)
+%% {stop, Reason, State} (terminate/2 is called)
+%%----------------------------------------------------------------------
+
+handle_call(get_collector_pid, _From, S) ->
+ Reply = S#state.collector_pid,
+ reply(Reply, S);
+handle_call(stop, _From, S) ->
+ wxFrame:destroy(S#state.frame),
+ opt_unlink(S#state.parent_pid),
+ {stop, shutdown, ok, S};
+handle_call({open_event, N}, _From, S) when is_integer(N), N > 0->
+ Reply = do_open_event(S, N),
+ reply(Reply, S);
+handle_call(Request, From, S) ->
+ ok = error_logger:format("~p(~p): handle_call(~p, ~p, ~p)~n",
+ [?MODULE, self(), Request, From, S]),
+ Reply = {error, {bad_request, Request}},
+ reply(Reply, S).
+
+%%----------------------------------------------------------------------
+%% Func: handle_cast/2
+%% Returns: {noreply, State} |
+%% {noreply, State, Timeout} |
+%% {stop, Reason, State} (terminate/2 is called)
+%%----------------------------------------------------------------------
+
+handle_cast(Msg, S) ->
+ ok = error_logger:format("~p(~p): handle_cast(~p, ~p)~n",
+ [?MODULE, self(), Msg, S]),
+ noreply(S).
+
+
+%%----------------------------------------------------------------------
+%% Func: handle_info/2
+%% Returns: {noreply, State} |
+%% {noreply, State, Timeout} |
+%% {stop, Reason, State} (terminate/2 is called)
+%%----------------------------------------------------------------------
+
+handle_info({et, {more_events, N}}, S) ->
+ %% io:format("more events: ~p \n", [N]),
+ S4 =
+ if
+ N =:= S#state.n_events ->
+ S;
+ true ->
+ Missing = S#state.events_per_page - queue_length(S#state.events),
+ if
+ Missing =:= 0 ->
+ update_scroll_bar(S#state{n_events = N});
+ Missing > 0 ->
+ OldEvents = queue_to_list(S#state.events),
+ {S2, NewEvents} =
+ collect_more_events(S#state{n_events = N},
+ S#state.last_event,
+ Missing),
+ S3 = replace_events(S2, OldEvents ++ NewEvents),
+ refresh_main_window(S3)
+ end
+ end,
+ noreply(S4);
+handle_info({et, {insert_actors, ActorNames}}, S) when is_list(ActorNames) ->
+ Fun = fun(N, Actors) ->
+ case lists:keymember(N, #actor.name, Actors) of
+ true -> Actors;
+ false -> Actors ++ [create_actor(N)]
+ end
+ end,
+ Actors = lists:foldl(Fun, S#state.actors, ActorNames),
+ S2 = refresh_main_window(S#state{actors = Actors}),
+ noreply(S2);
+handle_info({et, {delete_actors, ActorNames}}, S) when is_list(ActorNames)->
+ Fun = fun(N, Actors) when N =:= ?unknown ->
+ Actors;
+ (N, Actors) ->
+ lists:keydelete(N, #actor.name, Actors)
+ end,
+ Actors = lists:foldl(Fun, S#state.actors, ActorNames),
+ S2 = refresh_main_window(S#state{actors = Actors}),
+ noreply(S2);
+handle_info({et, {dict_insert, Key, Val}}, S) ->
+ S2 = do_dict_insert(Key, Val, S),
+ noreply(S2);
+handle_info({et, {dict_delete, Key}}, S) ->
+ S2 = do_dict_delete(Key, S),
+ noreply(S2);
+handle_info({et, first}, S) ->
+ S2 = scroll_first(S),
+ noreply(S2);
+handle_info({et, prev}, S) ->
+ S2 = scroll_prev(S),
+ noreply(S2);
+handle_info({et, next}, S) ->
+ S2 = scroll_next(S),
+ noreply(S2);
+handle_info({et, last}, S) ->
+ S2 = scroll_last(S),
+ noreply(S2);
+handle_info({et, refresh}, S) ->
+ S2 = revert_main_window(S),
+ noreply(S2);
+handle_info({et, {display_mode, _Mode}}, S) ->
+ %% Kept for backward compatibility
+ noreply(S);
+handle_info({et, close}, S) ->
+ wxFrame:destroy(S#state.frame),
+ opt_unlink(S#state.parent_pid),
+ {stop, shutdown, S};
+handle_info(#wx{id=?wxID_HELP}, S) ->
+ HelpString =
+ "Vertical scroll:\n"
+ "\tUse mouse wheel and up/down arrows to scroll little.\n"
+ "\tUse page up/down and home/end buttons to scroll more.\n\n"
+ "Display details of an event:\n"
+ "\tLeft mouse click on the event label or the arrow.\n\n"
+ "Highlight actor (toggle):\n"
+ "\tLeft mouse click on the actor name tag.\n"
+ "\tThe actor name will be enclosed in square brackets [].\n\n"
+ "Exclude actor (toggle):\n"
+ "\tRight mouse click on the actor name tag.\n"
+ "\tThe actor name will be enclosed in round brackets ().\n\n"
+ "Move actor:\n"
+ "\tLeft mouse button drag and drop on actor name tag.\n\n"
+ "Display all (reset settings for hidden and/or highlighted actors):\n"
+ "\tPress the 'a' button.",
+ Dialog =
+ wxMessageDialog:new(S#state.frame, HelpString,
+ [{style, 0
+ bor ?wxOK
+ bor ?wxICON_INFORMATION
+ bor ?wxSTAY_ON_TOP},
+ {caption, "Help"}]),
+ wxMessageDialog:showModal(Dialog),
+ noreply(S);
+handle_info(#wx{id=Id, event = #wxCommand{type = command_menu_selected}}, S=#state{filter_menu = {_,Data}}) ->
+ CollectorPid = S#state.collector_pid,
+ case get_value(Id, 3, S#state.menu_data) of
+ close ->
+ wxFrame:destroy(S#state.frame),
+ opt_unlink(S#state.parent_pid),
+ {stop, shutdown, S};
+ up ->
+ S2 = scroll_up(S),
+ noreply(S2);
+ down ->
+ S2 = scroll_down(S),
+ noreply(S2);
+ first ->
+ S2 = scroll_first(S),
+ noreply(S2);
+ prev ->
+ S2 = scroll_prev(S),
+ noreply(S2);
+ next ->
+ S2 = scroll_next(S),
+ noreply(S2);
+ last ->
+ S2 = scroll_last(S),
+ noreply(S2);
+ refresh ->
+ S2 = revert_main_window(S),
+ noreply(S2);
+ {display_mode, _Mode} ->
+ %% Kept for backward compatibility
+ noreply(S);
+ display_all ->
+ S2 = display_all(S),
+ noreply(S2);
+ close_all ->
+ close_all(S);
+ close_all_others ->
+ close_all_others(S);
+ first_all ->
+ et_collector:multicast(CollectorPid, first),
+ noreply(S);
+ prev_all ->
+ et_collector:multicast(CollectorPid, prev),
+ noreply(S);
+ next_all ->
+ et_collector:multicast(CollectorPid, next),
+ noreply(S);
+ last_all ->
+ et_collector:multicast(CollectorPid, last),
+ noreply(S);
+ refresh_all ->
+ et_collector:multicast(CollectorPid, refresh),
+ noreply(S);
+ clear_all ->
+ et_collector:clear_table(CollectorPid),
+ et_collector:multicast(CollectorPid, refresh),
+ noreply(S);
+ load_all ->
+ Style = ?wxFD_OPEN bor ?wxFD_OVERWRITE_PROMPT,
+ Msg = "Select a file to load events from",
+ S2 =
+ case select_file(S#state.frame, Msg, S#state.event_file, Style) of
+ {ok, NewFile} ->
+ et_collector:start_trace_client(CollectorPid, event_file, NewFile),
+ S#state{event_file = NewFile};
+ cancel ->
+ S
+ end,
+ noreply(S2);
+ save_all ->
+ Style = ?wxFD_SAVE bor ?wxFD_OVERWRITE_PROMPT,
+ Msg = "Select a file to save events to",
+ S2 =
+ case select_file(S#state.frame, Msg, S#state.event_file, Style) of
+ {ok, NewFile} ->
+ et_collector:save_event_file(CollectorPid, NewFile, [existing, write, keep]),
+ S#state{event_file = NewFile};
+ cancel ->
+ S
+ end,
+ noreply(S2);
+ print_setup ->
+ S2 = print_setup(S),
+ noreply(S2);
+ print_one_page = Scope ->
+ S2 = print(S, Scope),
+ noreply(S2);
+ print_all_pages = Scope ->
+ S2 = print(S, Scope),
+ noreply(S2);
+ {open_viewer, Scale} ->
+ Actors = [A#actor.name || A <- S#state.actors],
+ open_viewer(Scale, S#state.active_filter, Actors, S),
+ noreply(S);
+
+ _ ->
+ case get_value(Id, 3, Data) of
+ {data, F=#filter{}, Scale} ->
+ open_viewer(S#state.scale+Scale, F#filter.name, [?unknown], S);
+ {data, F=#filter{}} ->
+ open_viewer(S#state.scale, F#filter.name, [?unknown], S);
+ false ->
+ ok
+ end,
+ noreply(S)
+ end;
+handle_info(#wx{event = #wxCommand{type = command_slider_updated, commandInt = Level}}, S) ->
+ if
+ Level >= ?detail_level_min,
+ Level =< ?detail_level_max ->
+ S2 = S#state{detail_level = Level},
+ S3 = revert_main_window(S2),
+ noreply(S3);
+
+ true ->
+ noreply(S)
+ end;
+handle_info(#wx{id = Id, event = #wxCommand{type = command_checkbox_clicked, commandInt = Int}}, S) ->
+ case get_value(Id, 2, S#state.checkbox_data) of
+ hide_actions ->
+ case Int of
+ 1 ->
+ S2 = S#state{hide_actions = true},
+ S3 = revert_main_window(S2),
+ noreply(S3);
+ 0 ->
+ S2 = S#state{hide_actions = false},
+ S3 = revert_main_window(S2),
+ noreply(S3)
+ end;
+ hide_actors ->
+ case Int of
+ 1 ->
+ S2 = S#state{hide_actors = true},
+ S3 = revert_main_window(S2),
+ noreply(S3);
+ 0 ->
+ S2 = S#state{hide_actors = false},
+ S3 = revert_main_window(S2),
+ noreply(S3)
+ end;
+ false ->
+ noreply(S)
+ end;
+handle_info(#wx{event = #wxMouse{type = left_down, x = X, y = Y}}, S) ->
+ S3 =
+ case y_to_n(Y, S) of
+ actor ->
+ %% Actor click
+ case S#state.actors of
+ [] ->
+ S;
+ Actors ->
+ N = x_to_n(X, S),
+ A = lists:nth(N, Actors),
+ S#state{pending_actor = A}
+ end;
+ {event, N} ->
+ %% Event click
+ do_open_event(S, N),
+ S
+ end,
+ noreply(S3);
+handle_info(#wx{event = #wxMouse{type = left_up}}, S) when S#state.pending_actor =:= undefined ->
+ noreply(S);
+handle_info(#wx{event = #wxMouse{type = left_up, x = X, y = Y}}, S) ->
+ S3 =
+ case y_to_n(Y, S) of
+ actor ->
+ %% Actor click
+ case S#state.actors of
+ [] ->
+ S;
+ Actors ->
+ N = x_to_n(X, S),
+ A = lists:nth(N, Actors),
+ Pending = S#state.pending_actor,
+ if
+ A#actor.name =:= Pending#actor.name ->
+ %% Toggle include actor
+ A2 = A#actor{include = not A#actor.include},
+ %% io:format("include ~p: ~p -> ~p\n",
+ %% [A#actor.name, A#actor.include, A2#actor.include]),
+ Actors2 = lists:keyreplace(A#actor.name, #actor.name, Actors, A2),
+ DisplayAll = not lists:keymember(true, #actor.include, Actors2),
+ S2 = S#state{actors = Actors2, display_all = DisplayAll},
+ revert_main_window(S2);
+ true ->
+ move_actor(Pending, A, Actors, S)
+ end
+ end;
+ {event, _N} ->
+ %% Event click ignored
+ S
+ end,
+ noreply(S3#state{pending_actor = undefined});
+handle_info(#wx{event = #wxMouse{type = right_up, x = X, y = Y}}, S) ->
+ S3 =
+ case y_to_n(Y, S) of
+ actor ->
+ %% Actor click
+ case S#state.actors of
+ [] ->
+ S;
+ Actors ->
+ %% Toggle exclude actor
+ N = x_to_n(X, S),
+ A = lists:nth(N, Actors),
+ A2 = A#actor{exclude = not A#actor.exclude},
+ Actors2 = lists:keyreplace(A#actor.name, #actor.name, Actors, A2),
+ S2 = S#state{actors = Actors2},
+ revert_main_window(S2)
+ end;
+ {event, _N} ->
+ %% Event click ignored
+ S
+ end,
+ noreply(S3#state{pending_actor = undefined});
+handle_info(#wx{event = #wxKey{keyCode = KeyCode, shiftDown = SD}}, S) ->
+ case KeyCode of
+ $C when SD =:= true ->
+ close_all(S);
+ $c ->
+ close_all_others(S);
+ ?WXK_HOME ->
+ S2 = scroll_first(S),
+ noreply(S2);
+ ?WXK_END ->
+ S2 = scroll_last(S),
+ noreply(S2);
+ ?WXK_UP ->
+ S2 = scroll_up(S),
+ noreply(S2);
+ ?WXK_DOWN ->
+ S2 = scroll_down(S),
+ noreply(S2);
+ ?WXK_PAGEUP ->
+ S2 = scroll_prev(S),
+ noreply(S2);
+ ?WXK_PAGEDOWN ->
+ S2 = scroll_next(S),
+ noreply(S2);
+ $F when SD =:= true ->
+ et_collector:multicast(S#state.collector_pid, first),
+ noreply(S);
+ $F ->
+ S2 = scroll_first(S),
+ noreply(S2);
+ $P when SD =:= true ->
+ et_collector:multicast(S#state.collector_pid, prev),
+ noreply(S);
+ $P ->
+ S2 = scroll_prev(S),
+ noreply(S2);
+ $N when SD =:= true ->
+ et_collector:multicast(S#state.collector_pid, next),
+ noreply(S);
+ $N ->
+ S2 = scroll_next(S),
+ noreply(S2);
+ $L when SD =:= true ->
+ et_collector:multicast(S#state.collector_pid, last),
+ noreply(S);
+ $L ->
+ S2 = scroll_last(S),
+ noreply(S2);
+ $R when SD =:= true ->
+ et_collector:multicast(S#state.collector_pid, refresh),
+ noreply(S);
+ $R ->
+ S2 = revert_main_window(S),
+ noreply(S2);
+ $A ->
+ S2 = display_all(S),
+ noreply(S2);
+ $= ->
+ Scale = S#state.scale,
+ Actors = [A#actor.name || A <- S#state.actors],
+ open_viewer(Scale, S#state.active_filter, Actors, S),
+ noreply(S);
+ Int when Int =:= $+; Int =:= ?WXK_NUMPAD_ADD ->
+ Scale = S#state.scale + 1,
+ Actors = [A#actor.name || A <- S#state.actors],
+ open_viewer(Scale, S#state.active_filter, Actors, S),
+ noreply(S);
+ Int when Int =:= $-; Int =:= ?WXK_NUMPAD_SUBTRACT ->
+ case S#state.scale of
+ 1 ->
+ ignore;
+ Scale ->
+ Actors = [A#actor.name || A <- S#state.actors],
+ open_viewer(Scale - 1, S#state.active_filter, Actors, S)
+ end,
+ noreply(S);
+ $0 ->
+ case lists:keysearch(?DEFAULT_FILTER_NAME, #filter.name, S#state.filters) of
+ {value, F} when is_record(F, filter) ->
+ open_viewer(S#state.scale, F#filter.name, [?unknown], S);
+ false ->
+ ok
+ end,
+ noreply(S);
+ Int when is_integer(Int), Int > $0, Int =< $9 ->
+ case catch lists:nth(Int-$0, S#state.filters) of
+ F when is_record(F, filter) ->
+ open_viewer(S#state.scale, F#filter.name, [?unknown], S);
+ {'EXIT', _} ->
+ ok
+ end,
+ noreply(S);
+
+ _ ->
+ noreply(S)
+ end;
+handle_info(#wx{event = #wxScroll{type = scroll_changed}} = Wx, S) ->
+ get_latest_scroll(Wx),
+ Pos = wxScrollBar:getThumbPosition(S#state.scroll_bar),
+ {_, LineTopY, LineBotY} = calc_y(S),
+ Range = LineBotY - LineTopY,
+ N = round(S#state.n_events * Pos / Range),
+ Diff =
+ case N - event_pos(S) of
+ D when D < 0 -> D - 1;
+ D -> D + 1
+ end,
+ S2 = scroll_changed(S, Diff),
+ noreply(S2);
+handle_info(timeout, S) ->
+ noreply(S);
+handle_info({'EXIT', Pid, Reason}, S) ->
+ if
+ Pid =:= S#state.collector_pid ->
+ io:format("collector died: ~p\n\n", [Reason]),
+ wxFrame:destroy(S#state.frame),
+ {stop, Reason, S};
+ Pid =:= S#state.parent_pid ->
+ wxFrame:destroy(S#state.frame),
+ {stop, Reason, S};
+ true ->
+ noreply(S)
+ end;
+handle_info(#wx{event = #wxClose{}}, S) ->
+ opt_unlink(S#state.parent_pid),
+ {stop, shutdown, S};
+handle_info(#wx{event = #wxMouse{type = mousewheel, wheelRotation = Rot}}, S) when Rot > 0 ->
+ S2 = scroll_up(S),
+ noreply(S2);
+handle_info(#wx{event = #wxMouse{type = mousewheel, wheelRotation = Rot}}, S) when Rot < 0 ->
+ S2 = scroll_down(S),
+ noreply(S2);
+handle_info(#wx{event = #wxSize{size = {OldW, OldH}}} = Wx, S) ->
+ #wx{event = #wxSize{type = size, size = {W, H}}} = get_latest_resize(Wx),
+ S2 = S#state{width = W, height = H, canvas_width = W, canvas_height = H},
+ EventsPerPage = events_per_page(S, H),
+ Diff = EventsPerPage - S#state.events_per_page,
+ S6 =
+ if
+ OldW =:= W, OldH =:= H, S2#state.events_per_page =:= EventsPerPage ->
+ S2;
+ Diff =:= 0 ->
+ refresh_main_window(S2);
+ Diff > 0 ->
+ OldEvents = queue_to_list(S2#state.events),
+ {S3, NewEvents} = collect_more_events(S2, S2#state.last_event, Diff),
+ S4 = S3#state{events_per_page = EventsPerPage},
+ S5 = replace_events(S4, OldEvents ++ NewEvents),
+ refresh_main_window(S5);
+ Diff < 0 ->
+ OldEvents = queue_to_list(S2#state.events),
+ RevEvents = delete_n(lists:reverse(OldEvents), abs(Diff)),
+ S3 = S2#state{events_per_page = EventsPerPage},
+ S4 = replace_events(S3, lists:reverse(RevEvents)),
+ refresh_main_window(S4)
+ end,
+ noreply(S6);
+handle_info(#wx{event = #wxFocus{}}, S) ->
+ wxWindow:setFocus(S#state.canvas), % Get keyboard focus
+ noreply(S);
+handle_info(#wx{event = #wxMouse{type = enter_window}}, S) ->
+ wxWindow:setFocus(S#state.canvas), % Get keyboard focus
+ noreply(S);
+handle_info(#wx{event = #wxPaint{}}, S) ->
+ S2 = refresh_main_window(S),
+ noreply(S2);
+handle_info(#wx{event = #wxMouse{type = T, x=X,y=Y}}, S) ->
+ io:format("~p ~p\n", [T, {X,Y}]),
+ noreply(S);
+handle_info(Info, S) ->
+ ok = error_logger:format("~p(~p): handle_info(~p, ~p)~n",
+ [?MODULE, self(), Info, S]),
+ noreply(S).
+
+%%----------------------------------------------------------------------
+%% Func: terminate/2
+%% Purpose: Shutdown the server
+%% Returns: any (ignored by gen_server)
+%%----------------------------------------------------------------------
+
+terminate(_Reason, _S) ->
+ ignore.
+
+%%----------------------------------------------------------------------
+%% Func: code_change/3
+%% Purpose: Convert process state when code is changed
+%% Returns: {ok, NewState}
+%%----------------------------------------------------------------------
+
+code_change(_OldVsn, S, _Extra) ->
+ {ok, S}.
+
+%%%----------------------------------------------------------------------
+%%% Handle stuff
+%%%----------------------------------------------------------------------
+
+reply(Reply, S) ->
+ Timeout = timeout(S),
+ {reply, Reply, S, Timeout}.
+
+noreply(S) ->
+ Timeout = timeout(S),
+ {noreply, S, Timeout}.
+
+timeout(_S) ->
+ infinity.
+
+scroll_first(S) ->
+ EventsPerPage = S#state.events_per_page,
+ {S2, NewEvents} =
+ collect_more_events(S, first, EventsPerPage),
+ S3 =
+ case NewEvents of
+ [] ->
+ S2;
+ [FirstE | _] ->
+ S2#state{first_event = FirstE}
+ end,
+ S4 = replace_events(S3, NewEvents),
+ refresh_main_window(S4).
+
+scroll_last(S) ->
+ case collect_more_events(S, last, -1) of
+ {_, []} ->
+ scroll_first(S);
+ {S2, NewEvents} ->
+ [FirstE | _] = NewEvents,
+ S3 = replace_events(S2#state{first_event = FirstE}, NewEvents),
+ refresh_main_window(S3)
+ end.
+
+scroll_prev(S) ->
+ scroll_up(S, S#state.events_per_page).
+
+scroll_next(S) ->
+ scroll_down(S, S#state.events_per_page).
+
+scroll_up(S) ->
+ scroll_up(S, calc_scroll(S)).
+
+scroll_up(S, Expected) ->
+ N = queue_length(S#state.events),
+ EventsPerPage = S#state.events_per_page,
+ Expected2 = adjust_expected(Expected, N, EventsPerPage),
+ OldEvents = queue_to_list(S#state.events),
+ case collect_more_events(S, S#state.first_event, -Expected2) of
+ {_, []} ->
+ S;
+ {S2, NewEvents} ->
+ NewN = length(NewEvents),
+ if
+ N + NewN > EventsPerPage ->
+ RevAllEvents = lists:reverse(OldEvents, lists:reverse(NewEvents)),
+ TooMany = N + NewN - EventsPerPage,
+ case delete_n(RevAllEvents, TooMany) of
+ [] ->
+ S;
+ [LastE | _] = RevEvents ->
+ Events = lists:reverse(RevEvents),
+ S3 = replace_events(S2#state{last_event = LastE}, Events),
+ refresh_main_window(S3)
+ end;
+ true ->
+ Events = NewEvents ++ OldEvents,
+ LastE = lists:last(Events),
+ S3 = replace_events(S2#state{last_event = LastE}, Events),
+ refresh_main_window(S3)
+ end
+ end.
+
+scroll_down(S) ->
+ scroll_down(S, calc_scroll(S)).
+
+scroll_down(S, Expected) ->
+ N = queue_length(S#state.events),
+ EventsPerPage = S#state.events_per_page,
+ Expected2 = adjust_expected(Expected, N, EventsPerPage),
+ OldEvents = queue_to_list(S#state.events),
+ case collect_more_events(S, S#state.last_event, Expected2) of
+ {_, []} ->
+ case collect_more_events(S, S#state.first_event, N - EventsPerPage) of
+ {_, []} ->
+ S;
+ {S2, NewEvents} ->
+ Events = NewEvents ++ OldEvents,
+ [FirstE | _] = Events,
+ S3 = replace_events(S2#state{first_event = FirstE}, Events),
+ refresh_main_window(S3)
+ end;
+ {S2, NewEvents} ->
+ AllEvents = OldEvents ++ NewEvents,
+ case delete_n(AllEvents, length(NewEvents)) of
+ [] ->
+ scroll_first(S);
+ Events ->
+ [FirstE | _] = Events,
+ S3 = replace_events(S2#state{first_event = FirstE}, Events),
+ refresh_main_window(S3)
+ end
+ end.
+
+scroll_changed(S, Expected) ->
+ if
+ Expected =:= 0 ->
+ refresh_main_window(S);
+ Expected < 0 ->
+ %% Up
+ OldPos = event_pos(S),
+ NewPos = lists:max([OldPos + Expected, 0]),
+ case S#state.first_event of
+ #e{key = Key, pos = OldPos} ->
+ jump_up(S, Key, OldPos, NewPos);
+ first ->
+ scroll_first(S);
+ last ->
+ scroll_last(S)
+ end;
+ true ->
+ %% Down
+ OldPos = event_pos(S),
+ NewPos = lists:min([OldPos + Expected, S#state.n_events]),
+ case S#state.first_event of
+ #e{key = Key, pos = OldPos} ->
+ jump_down(S, Key, OldPos, NewPos);
+ first = Key ->
+ jump_down(S, Key, 0, NewPos);
+ last ->
+ scroll_last(S)
+ end
+ end.
+
+jump_up(S, OldKey, OldPos, NewPos) ->
+ Try = NewPos - OldPos,
+ Order = S#state.event_order,
+ Fun = fun(Event, #e{pos = P}) when P >= NewPos ->
+ Key = et_collector:make_key(Order, Event),
+ #e{event = Event, key = Key, pos = P - 1};
+ (_, Acc) ->
+ Acc
+ end,
+ PrevE = et_collector:iterate(S#state.collector_pid,
+ OldKey,
+ Try,
+ Fun,
+ #e{key = OldKey, pos = OldPos}),
+ case collect_more_events(S, PrevE, S#state.events_per_page) of
+ {_, []} ->
+ S;
+ {S2, Events} ->
+ [FirstE | _] = Events,
+ S3 = replace_events(S2#state{first_event = FirstE}, Events),
+ refresh_main_window(S3)
+ end.
+
+jump_down(S, OldKey, OldPos, NewPos) ->
+ Try = NewPos - OldPos,
+ Order = S#state.event_order,
+ Fun = fun(Event, #e{pos = P}) when P < NewPos ->
+ Key = et_collector:make_key(Order, Event),
+ #e{event = Event, key = Key, pos = P + 1};
+ (_, Acc) ->
+ Acc
+ end,
+ PrevE = et_collector:iterate(S#state.collector_pid,
+ OldKey,
+ Try,
+ Fun,
+ #e{key = OldKey, pos = OldPos}),
+ case collect_more_events(S, PrevE, S#state.events_per_page) of
+ {_, []} ->
+ S;
+ {S2, Events} ->
+ [FirstE | _] = Events,
+ S3 = replace_events(S2#state{first_event = FirstE}, Events),
+ refresh_main_window(S3)
+ end.
+
+adjust_expected(Expected, N, EventsPerPage) ->
+ if
+ N < EventsPerPage ->
+ EventsPerPage - N;
+ Expected < EventsPerPage ->
+ Expected;
+ true ->
+ EventsPerPage
+ end.
+
+calc_scroll(S) ->
+ lists:max([S#state.events_per_page div 3, 1]).
+
+revert_main_window(S) ->
+ {S2, Events} = revert(S),
+ S3 = replace_events(S2, Events),
+ refresh_main_window(S3).
+
+revert(S) ->
+ EventsPerPage = S#state.events_per_page,
+ %% Find previous event
+ case collect_more_events(S, S#state.first_event, -1) of
+ {_, []} ->
+ collect_more_events(S, first, EventsPerPage);
+ {S2, [_PrevEvent]} ->
+ collect_more_events(S, S2#state.first_event, EventsPerPage)
+ end.
+
+delete_n(List, 0) ->
+ List;
+delete_n([], _) ->
+ [];
+delete_n([_ | Tail], N) when N > 0 ->
+ delete_n(Tail, N - 1).
+
+pick_n(Rest, 0, Acc) ->
+ {lists:reverse(Acc), Rest};
+pick_n([], _N, Acc) ->
+ {lists:reverse(Acc), []};
+pick_n([Head | Tail], N, Acc) when N > 0 ->
+ pick_n(Tail, N - 1, [Head | Acc]).
+
+close_all(S) ->
+ close_all_others(S),
+ wxFrame:destroy(S#state.frame),
+ opt_unlink(S#state.parent_pid),
+ {stop, shutdown, S}.
+
+close_all_others(S) ->
+ Fun =
+ fun({{subscriber, Pid}, _}) ->
+ if
+ Pid =:= self() ->
+ ignore;
+ true ->
+ unlink(Pid),
+ Pid ! {et, close}
+ end
+ end,
+ All = et_collector:dict_match(S#state.collector_pid,
+ {{subscriber, '_'}, '_'}),
+ lists:foreach(Fun, All),
+ noreply(S).
+
+opt_unlink(Pid) ->
+ if
+ Pid =:= undefined ->
+ ignore;
+ true ->
+ unlink(Pid)
+ end.
+
+%%%----------------------------------------------------------------------
+%%% Clone viewer
+%%%----------------------------------------------------------------------
+
+open_viewer(Scale, FilterName, Actors, S) ->
+ Filters = [{dict_insert, {filter, F#filter.name}, F#filter.function}
+ || F <- S#state.filters],
+ Options =
+ [{parent_pid, S#state.parent_pid},
+ {title, S#state.title},
+ {collector_pid, S#state.collector_pid},
+ {detail_level, S#state.detail_level},
+ {active_filter, FilterName},
+ {event_order, S#state.event_order},
+ {first_event, S#state.first_event},
+ {max_actors, S#state.max_actors},
+ {hide_actions, S#state.hide_actions},
+ {hide_actors, S#state.hide_actors},
+ {actors, Actors},
+ {scale, Scale},
+ {width, S#state.width},
+ {height, S#state.height} | Filters],
+ case start_link(Options) of
+ {ok, _ViewerPid} ->
+ %% unlink(ViewerPid),
+ ok;
+ {error, Reason} ->
+ ok = error_logger:format("~p: Failed to start a new window: ~p~n",
+ [?MODULE, Reason])
+ end.
+
+%%%----------------------------------------------------------------------
+%%% Handle graphics
+%%%----------------------------------------------------------------------
+
+create_main_window(S) ->
+ {NormalFont, BoldFont} = select_fonts(S#state.scale),
+ Name = name_to_string(S#state.active_filter),
+ Title = case S#state.title of
+ undefined -> atom_to_list(?MODULE);
+ Explicit -> name_to_string(Explicit)
+ end,
+ Frame = wxFrame:new(wx:null(),
+ ?wxID_ANY,
+ Title ++ " (filter: " ++ Name ++ ")",
+ [{size, {S#state.width, S#state.height}}]),
+ StatusBar = wxFrame:createStatusBar(Frame),
+
+ Panel = wxPanel:new(Frame, []),
+ Bar = wxMenuBar:new(),
+ wxFrame:setMenuBar(Frame,Bar),
+ MainSizer = wxBoxSizer:new(?wxVERTICAL),
+
+ MenuData = lists:flatten([create_file_menu(Bar),
+ create_viewer_menu(Bar),
+ create_collector_menu(Bar)]),
+ FilterMenu = wxMenu:new([]),
+ S2 = create_filter_menu(S#state{filter_menu = {FilterMenu,[]}},
+ S#state.active_filter,
+ S#state.filters),
+ wxMenuBar:append(Bar, FilterMenu, "Filters and scaling"),
+ create_help_menu(Bar),
+
+ OptSizer = wxBoxSizer:new(?wxHORIZONTAL),
+ CheckSizer = wxBoxSizer:new(?wxVERTICAL),
+ HideActions = wxCheckBox:new(Panel, ?wxID_ANY, "Hide From=To"),
+ wxCheckBox:setValue(HideActions, S#state.hide_actions),
+ HideActors = wxCheckBox:new(Panel, ?wxID_ANY, "Hide (excluded actors)"),
+ wxCheckBox:setValue(HideActors, S#state.hide_actors),
+ CheckBoxData = [{wxCheckBox:getId(HideActions), hide_actions},
+ {wxCheckBox:getId(HideActors), hide_actors}],
+ wxPanel:connect(Panel, command_checkbox_clicked),
+ wxSizer:add(CheckSizer, HideActions),
+ wxSizer:add(CheckSizer,HideActors),
+ wxSizer:add(OptSizer, CheckSizer, [{border, 10}, {flag, ?wxALL}]),
+ DetailLevelBox = wxStaticBoxSizer:new(?wxHORIZONTAL,
+ Panel,
+ [{label, "Detail level"}]),
+ DetailLevel = wxSlider:new(Panel, ?wxID_ANY,
+ S#state.detail_level,
+ ?detail_level_min,
+ ?detail_level_max,
+ [{style, ?wxSL_LABELS},
+ {size, {200,-1}}]),
+ wxStatusBar:setStatusText(StatusBar, where_text(S)),
+ wxFrame:connect(Frame, command_slider_updated),
+ wxSizer:add(DetailLevelBox, DetailLevel),
+ wxSizer:add(OptSizer, DetailLevelBox, [{border, 10}, {flag, ?wxALL}]),
+ wxSizer:addStretchSpacer(OptSizer),
+ wxSizer:add(MainSizer, OptSizer),
+ wxSizer:add(MainSizer,
+ wxStaticLine:new(Panel, [{style, ?wxLI_HORIZONTAL}]),
+ [{flag, ?wxEXPAND}]),
+
+ CanvasSizer = wxBoxSizer:new(?wxHORIZONTAL),
+ Canvas = wxPanel:new(Panel, []),
+ {CanvasW,CanvasH} = wxPanel:getSize(Canvas),
+ ScrollBar = wxScrollBar:new(Panel, ?wxID_ANY, [{style, ?wxSB_VERTICAL}]),
+
+ wxSizer:add(CanvasSizer, Canvas, [{flag, ?wxEXPAND}, {proportion, 1}]),
+ wxSizer:add(CanvasSizer, ScrollBar, [{flag, ?wxEXPAND}]),
+ wxSizer:add(MainSizer, CanvasSizer, [{flag, ?wxEXPAND}, {proportion, 1}]),
+ wxPanel:connect(Canvas, left_down),
+ wxPanel:connect(Canvas, left_up),
+ wxPanel:connect(Canvas, right_up),
+ wxPanel:connect(Canvas, size),
+ wxPanel:connect(Canvas, paint),
+ wxPanel:connect(Canvas, key_down),
+ wxPanel:connect(Canvas, kill_focus),
+ wxPanel:connect(Canvas, enter_window, [{skip, true}]),
+ wxFrame:connect(Frame, command_menu_selected),
+ wxFrame:connect(Frame, close_window),
+ wxFrame:connect(ScrollBar, scroll_changed),
+ wxPanel:setSize(Panel, {S#state.width, S#state.height}),
+ wxPanel:setSizer(Panel, MainSizer),
+ wxFrame:show(Frame),
+ wxPanel:setFocus(Canvas),
+ wxPanel:connect(Canvas, mousewheel),
+
+ S3 = S2#state{title = Title,
+ frame = Frame, packer = Panel,
+ normal_font = NormalFont, bold_font = BoldFont,
+ canvas_width = CanvasW, canvas_height = CanvasH,
+ canvas = Canvas,
+ canvas_sizer = CanvasSizer,
+ scroll_bar = ScrollBar,
+ y_pos = ?initial_y * S#state.scale,
+ pen = wxPen:new(),
+ brush = wxBrush:new(),
+ print_d = undefined,
+ print_psdd = undefined,
+ menu_data = MenuData,
+ checkbox_data = CheckBoxData,
+ hide_actions_box = HideActions,
+ hide_actors_box = HideActors,
+ status_bar = StatusBar},
+ DC = wxClientDC:new(Canvas),
+ S4 = draw_all_actors(S3, DC),
+ wxClientDC:destroy(DC),
+ S4.
+
+where_text(#state{n_events = N} = S) ->
+ Pos = event_pos(S),
+ lists:concat([Pos, " (", N, ")"]).
+
+event_pos(#state{first_event = E, events = Events, n_events = Last}) ->
+ case E of
+ #e{pos = Pos} ->
+ Pos;
+ first ->
+ case queue_length(Events) of
+ 0 ->
+ 0;
+ _ ->
+ 1
+ end;
+ last ->
+ Last
+ end.
+
+init_printers(#state{print_d = undefined, print_psdd = undefined} = S) ->
+ PD = wxPrintData:new(),
+ PSDD = wxPageSetupDialogData:new(PD),
+ wxPrintData:setPaperId(PD, ?wxPAPER_A4),
+ wxPageSetupDialogData:setMarginTopLeft(PSDD, {15,15}),
+ wxPageSetupDialogData:setMarginBottomRight(PSDD, {15,15}),
+ S#state{print_d = PD, print_psdd = PSDD};
+init_printers(#state{} = S) ->
+ S.
+
+select_fonts(Scale) when is_integer(Scale) ->
+ Size =
+ case Scale of
+ 1 -> 5;
+ 2 -> 10;
+ 3 -> 14;
+ 4 -> 20;
+ S -> S*6
+ end,
+ {wxFont:new(Size, ?wxFONTFAMILY_TELETYPE, ?wxNORMAL, ?wxNORMAL,[]),
+ wxFont:new(Size, ?wxFONTFAMILY_TELETYPE, ?wxNORMAL, ?wxBOLD,[])}.
+
+get_value(Key, Pos, TupleList) when is_list(TupleList)->
+ case lists:keysearch(Key, 1, TupleList) of
+ {value, Tuple} when is_tuple(Tuple)->
+ element(Pos, Tuple);
+ false ->
+ false
+ end.
+
+menuitem(Menu, Id, Text, UserData) ->
+ Item = wxMenu:append(Menu, Id, Text),
+ {wxMenuItem:getId(Item), Item, UserData}.
+
+create_file_menu(Bar) ->
+ Menu = wxMenu:new([]),
+ Data = [
+ menuitem(Menu, ?wxID_ANY, "Clear all events in the Collector", clear_all),
+ menuitem(Menu, ?wxID_ANY, "Load events to the Collector from file", load_all),
+ menuitem(Menu, ?wxID_ANY, "Save all events in the Collector to file", save_all),
+
+ menuitem(Menu, ?wxID_PRINT_SETUP, "Print setup", print_setup),
+ menuitem(Menu, ?wxID_ANY, "Print current page", print_one_page),
+ menuitem(Menu, ?wxID_PRINT, "Print all pages", print_all_pages),
+
+ menuitem(Menu, ?wxID_ANY, "Close this Viewer", close),
+ menuitem(Menu, ?wxID_ANY, "Close all other Viewers, but this (c)", close_all_others),
+ menuitem(Menu, ?wxID_ANY, "Close all Viewers and the Collector) (C) ", close_all)
+ ],
+ wxMenu:insertSeparator(Menu, 3),
+ wxMenu:insertSeparator(Menu, 7),
+ wxMenuBar:append(Bar, Menu, "File"),
+ Data.
+
+create_viewer_menu(Bar) ->
+ Menu = wxMenu:new([]),
+ wxMenuItem:enable(wxMenu:append(Menu, ?wxID_ANY, "Scroll this Viewer"),
+ [{enable, false}]),
+ wxMenu:appendSeparator(Menu),
+ D1 = [
+ menuitem(Menu, ?wxID_ANY, "First (f)", first),
+ menuitem(Menu, ?wxID_ANY, "Last (l)", last),
+ menuitem(Menu, ?wxID_ANY, "Prev (p)", prev),
+ menuitem(Menu, ?wxID_ANY, "Next (n)", next),
+ menuitem(Menu, ?wxID_ANY, "Refresh (r)", refresh)
+ ],
+ wxMenu:appendSeparator(Menu),
+ D2 = [
+ menuitem(Menu, ?wxID_ANY, "Up 5 (Up)", up),
+ menuitem(Menu, ?wxID_ANY, "Down 5 (Down)", down)
+ ],
+ wxMenu:appendSeparator(Menu),
+ wxMenuItem:enable(wxMenu:append(Menu, ?wxID_ANY, "Actor visibility in this Viewer"),
+ [{enable, false}]),
+ wxMenu:appendSeparator(Menu),
+ D3 = [menuitem(Menu, ?wxID_ANY, "Display all actors (a)", display_all)],
+ wxMenuBar:append(Bar, Menu, "Viewer"),
+ [D1,D2,D3].
+
+create_collector_menu(Bar) ->
+ Menu = wxMenu:new([]),
+ wxMenuItem:enable(wxMenu:append(Menu, ?wxID_ANY, "Scroll all Viewers"),
+ [{enable, false}]),
+ wxMenu:appendSeparator(Menu),
+ Data = [
+ menuitem(Menu, ?wxID_ANY, "First (F)", first_all),
+ menuitem(Menu, ?wxID_ANY, "Last (L)", last_all),
+ menuitem(Menu, ?wxID_ANY, "Prev (P)", prev_all),
+ menuitem(Menu, ?wxID_ANY, "Next (N)", next_all),
+ menuitem(Menu, ?wxID_ANY, "Refresh (R)", refresh_all)
+ ],
+ wxMenuBar:append(Bar, Menu, "Collector"),
+ Data.
+
+create_filter_menu(S=#state{filter_menu = {Menu,Data}}, ActiveFilterName, Filters) ->
+ wx:foreach(fun({_,I,_}) ->
+ wxMenu:delete(Menu,I);
+ (I) ->
+ try
+ wxMenu:delete(Menu,I)
+ catch
+ _:Reason ->
+ io:format("Could not delete item: ~p, because ~p.\n", [I, Reason])
+ end
+ end,
+ Data),
+ Item = fun(F, {N, Acc}) when F#filter.name =:= all ->
+ Label = lists:concat([pad_string(F#filter.name, 20), "(0)"]),
+ {N+1, [menuitem(Menu, ?wxID_ANY, Label, {data, F})|Acc]};
+ (F, {N, Acc}) ->
+ Label = lists:concat([pad_string(F#filter.name, 20), "(", N, ")"]),
+ {N+1, [menuitem(Menu, ?wxID_ANY, Label, {data, F})|Acc]}
+ end,
+ D1 = [I1 = wxMenu:append(Menu, ?wxID_ANY, "Same Filter New Scale"),
+ wxMenu:appendSeparator(Menu)],
+ wxMenuItem:enable(I1, [{enable,false}]),
+ {value, Filter} = lists:keysearch(ActiveFilterName, #filter.name, Filters),
+ Same = lists:concat([pad_string(ActiveFilterName, 20), "(=) same scale"]),
+ Larger = lists:concat([pad_string(ActiveFilterName, 20), "(+) bigger scale"]),
+ Smaller = lists:concat([pad_string(ActiveFilterName, 20), "(-) smaller scale"]),
+ D2 = [
+ menuitem(Menu, ?wxID_ANY, Same, {data, Filter, 0}),
+ menuitem(Menu, ?wxID_ANY, Smaller, {data, Filter, -1}),
+ menuitem(Menu, ?wxID_ANY, Larger, {data, Filter, 1}),
+ wxMenu:appendSeparator(Menu),
+ I2 = wxMenu:append(Menu, ?wxID_ANY, "New Filter Same Scale"),
+ wxMenu:appendSeparator(Menu)
+ ],
+ wxMenuItem:enable(I2, [{enable,false}]),
+ {_,D3} = lists:foldl(Item, {1,[]}, Filters),
+ S#state{filter_menu = {Menu, lists:flatten([D1,D2,D3])}}.
+
+create_help_menu(Bar) ->
+ Menu = wxMenu:new([]),
+ menuitem(Menu, ?wxID_HELP, "Info", help),
+ wxMenuBar:append(Bar, Menu, "Help").
+
+clear_canvas(S) ->
+ DC = wxClientDC:new(S#state.canvas),
+ wxDC:clear(DC),
+ {CanvasW, CanvasH} = wxPanel:getSize(S#state.canvas),
+ wxSizer:recalcSizes(S#state.canvas_sizer),
+ S2 = S#state{refresh_needed = false,
+ y_pos = ?initial_y * S#state.scale,
+ canvas_width = CanvasW,
+ canvas_height = CanvasH,
+ events = queue_new()},
+ S3 = draw_all_actors(S2, DC),
+ wxClientDC:destroy(DC),
+ S3.
+
+replace_events(S, []) ->
+ S#state{first_event = first,
+ last_event = first,
+ events = queue_new()};
+replace_events(S, Events) ->
+ Queue = lists:foldl(fun(E, Q) -> queue_in(E, Q) end, queue_new(), Events),
+ S#state{events = Queue}.
+
+refresh_main_window(S) ->
+ wx:batch(fun() ->
+ S2 = clear_canvas(S),
+ S3 = update_scroll_bar(S2),
+ display_events(S3, queue_to_list(S#state.events))
+ end).
+
+display_events(S, []) ->
+ S;
+display_events(S, Events) ->
+ DC = wxClientDC:new(S#state.canvas),
+ S2 = lists:foldl(fun(E, State) -> display_event(E, State, DC) end, S, Events),
+ wxClientDC:destroy(DC),
+ S2.
+
+collect_more_events(S, PrevKey = first, Try) ->
+ PrevE = #e{event = undefined, key = PrevKey, pos = 0},
+ S2 = S#state{first_event = PrevE, last_event = PrevE},
+ do_collect_more_events(S2, Try, PrevE, []);
+collect_more_events(S, PrevKey = last, Try) ->
+ PrevE = #e{event = undefined, key = PrevKey, pos = S#state.n_events},
+ S2 = S#state{first_event = PrevE, last_event = PrevE},
+ do_collect_more_events(S2, Try, PrevE, []);
+collect_more_events(S, #e{} = PrevE, Try) ->
+ do_collect_more_events(S, Try, PrevE, []).
+
+do_collect_more_events(#state{collector_pid = Collector,
+ event_order = Order,
+ active_filter = Active,
+ filters = Filters} = S,
+ Try,
+ PrevE,
+ Acc) ->
+ Incr =
+ if
+ Try < 0 -> -1;
+ true -> 1
+ end,
+ PrevKey = PrevE#e.key,
+ {value, #filter{function = FilterFun}} =
+ lists:keysearch(Active, #filter.name, Filters),
+ {_S, _Incr, _Order, _Active, _FilterFun, LastE, NewEvents} =
+ et_collector:iterate(Collector,
+ PrevKey,
+ Try,
+ fun collect_event/2,
+ {S, Incr, Order, Active, FilterFun, PrevE, []}),
+ Expected = abs(Try),
+ Actual = length(NewEvents),
+ Missing = Expected - Actual,
+ {S2, Acc2, Try2} =
+ if
+ Try < 0 ->
+ {S#state{first_event = LastE}, NewEvents ++ Acc, -Missing};
+ true ->
+ TmpEvents = lists:reverse(NewEvents),
+ {S#state{last_event = LastE}, Acc ++ TmpEvents, Missing}
+ end,
+ if
+ Missing =/= 0, PrevKey =/= LastE#e.key ->
+ do_collect_more_events(S2, Try2, LastE, Acc2);
+ true ->
+ {S2, Acc2}
+ end.
+
+collect_event(Event, {S, Incr, Order, Active, FilterFun, #e{pos = PrevPos}, Events}) ->
+ Key = et_collector:make_key(Order, Event),
+ E = #e{event = Event, key = Key, pos = PrevPos + Incr},
+ {LastE, Events2} =
+ case catch FilterFun(Event) of
+ true ->
+ case is_hidden(Event#event.from, Event#event.to, S) of
+ true ->
+ {E, Events};
+ false ->
+ {E, [E | Events]}
+ end;
+ {true, Event2} ->
+ Key2 = et_collector:make_key(Order, Event2),
+ E2 = E#e{event = Event2, key = Key2},
+ case is_hidden(Event2#event.from, Event2#event.to, S) of
+ true ->
+ {E2, Events};
+ false ->
+ {E2, [E2 | Events]}
+ end;
+ false ->
+ {E, Events};
+ Bad ->
+ Contents = {bad_filter, S#state.active_filter, Bad, Event},
+ Event2 = Event#event{contents = Contents,
+ from = bad_filter,
+ to = bad_filter},
+ E2 = E#e{event = Event2},
+ {E2, [E2 | Events]}
+ end,
+ {S, Incr, Order, Active, FilterFun, LastE, Events2}.
+
+display_event(#e{event = Event} = E, S, DC)
+ when Event#event.detail_level =< S#state.detail_level ->
+ {FromRefresh, From} = ensure_actor(Event#event.from, S, DC),
+ {FromName, FromPos, S2} = From,
+ {ToRefresh, To} = ensure_actor(Event#event.to, S2, DC),
+ {ToName, ToPos, S3} = To,
+ S4 =
+ if
+ FromRefresh =/= false, ToRefresh =/= false ->
+ S3#state{refresh_needed = true,
+ events = queue_in(E, S3#state.events)};
+ FromName =:= ToName ->
+ case S#state.hide_actions of
+ true ->
+ S3;
+ false ->
+ Label = name_to_string(Event#event.label),
+ draw_named_arrow(Label, FromName, ToName, FromPos, ToPos, E, S3, DC)
+ end;
+ true ->
+ Label = name_to_string(Event#event.label),
+ draw_named_arrow(Label, FromName, ToName, FromPos, ToPos, E, S3, DC)
+ end,
+ S4;
+display_event(#e{}, S, _DC) ->
+ S.
+
+draw_named_arrow(Label, FromName, ToName, FromPos, ToPos, E, S, DC) ->
+ case S#state.y_pos + (?incr_y * S#state.scale) of
+ _ when S#state.hide_actors =:= true, FromName =:= ?unknown ->
+ S;
+ _ when S#state.hide_actors =:= true, ToName =:= ?unknown ->
+ S;
+ Y when Y > S#state.canvas_height ->
+ S#state{refresh_needed = true,
+ events = queue_in(E, S#state.events)};
+ Y ->
+ S2 = S#state{y_pos = Y, events = queue_in(E, S#state.events)},
+ S3 = draw_arrow(FromPos, ToPos, S2, DC),
+ draw_label(Label, FromName, ToName, FromPos, ToPos, S3, DC)
+ end.
+
+draw_arrow(Pos, Pos, S, _DC) ->
+ S;
+draw_arrow(FromPos, ToPos, S, DC) ->
+ Y = S#state.y_pos,
+ wxPen:setColour(S#state.pen, ?wxBLACK),
+ wxDC:setPen(DC, S#state.pen),
+ wxDC:drawLine(DC, {FromPos , Y}, {ToPos, Y}),
+
+ %% Draw arrow head
+ Radians = calc_angle({FromPos, Y}, {ToPos, Y}),
+ Len = 5,
+ Radians2 = Radians + 3.665191429188092,
+ Radians3 = Radians + 2.617993877991494,
+ {X3, Y3} = calc_point({ToPos, Y}, Len, Radians2),
+ {X4, Y4} = calc_point({ToPos, Y}, Len, Radians3),
+ Points = [{round(ToPos), round(Y)},
+ {round(X3), round(Y3)},
+ {round(X4), round(Y4)}],
+ wxBrush:setColour(S#state.brush, ?wxBLACK),
+ wxDC:setBrush(DC, S#state.brush),
+ wxDC:drawPolygon(DC, Points, []),
+ S.
+
+ %% Calclulate angle in radians for a line between two points
+calc_angle({X1, Y1}, {X2, Y2}) ->
+ math:atan2((Y2 - Y1), (X2 - X1)).
+
+ %% Calc new point at a given distance and angle from another point
+calc_point({X, Y}, Length, Radians) ->
+ X2 = round(X + Length * math:cos(Radians)),
+ Y2 = round(Y + Length * math:sin(Radians)),
+ {X2, Y2}.
+
+draw_label(Label, FromName, ToName, FromPos, ToPos, S, DC) ->
+ Color =
+ if
+ FromName =:= ?unknown,
+ ToName =:= ?unknown -> {2, 71, 254};% blue
+ FromName =:= ?unknown -> {255,126,0}; % orange
+ ToName =:= ?unknown -> {255,126,0}; % orange
+ FromPos =:= ToPos -> {2, 71, 254};% blue
+ true -> {227,38, 54} % red
+ end,
+ Scale = S#state.scale,
+ X = lists:min([FromPos, ToPos]) + (6 * Scale),
+ Y = S#state.y_pos,
+ write_text(Label, X, Y, Color, S#state.normal_font, S, DC),
+ S.
+
+draw_all_actors(S, DC) ->
+ Scale = S#state.scale,
+ Fun = fun(A, X) ->
+ case draw_actor(A, X, S, DC) of
+ true ->
+ X + (?incr_x * Scale);
+ false ->
+ X
+ end
+ end,
+ lists:foldl(Fun, ?initial_x * Scale, S#state.actors),
+ S.
+
+%% Returns: {NeedsRefreshBool, {ActorPos, NewsS, NewActors}}
+ensure_actor(Name, S, DC) ->
+ do_ensure_actor(Name, S, S#state.actors, 0, DC).
+
+do_ensure_actor(Name, S, [H | _], N, _DC) when H#actor.name =:= Name ->
+ Pos = (?initial_x + (N * ?incr_x)) * S#state.scale,
+ {false, {Name, Pos, S}};
+do_ensure_actor(Name, S, [H | T], N, DC) ->
+ if
+ S#state.hide_actors, H#actor.exclude ->
+ do_ensure_actor(Name, S, T, N, DC);
+ true ->
+ do_ensure_actor(Name, S, T, N + 1, DC)
+ end;
+do_ensure_actor(Name, S, [], N, DC) ->
+ %% A brand new actor, let's see if it does fit
+ Pos = (?initial_x + (N * ?incr_x)) * S#state.scale,
+ MaxActors = S#state.max_actors,
+ if
+ is_integer(MaxActors), N > MaxActors ->
+ %% Failed on max_actors limit, put into unknown
+ %% Assume that unknown always is in actor list
+ ensure_actor(?unknown, S, DC);
+ Pos > (S#state.canvas_width - ((?initial_x - 15) * S#state.scale)) ->
+ %% New actor does not fit in canvas, refresh needed
+ A = create_actor(Name),
+ draw_actor(A, Pos, S, DC),
+ {true, {Name, Pos, S#state{actors = S#state.actors ++ [A]}}};
+ true ->
+ %% New actor fits in canvas. Draw the new actor.
+ A = create_actor(Name),
+ draw_actor(A, Pos, S, DC),
+ {false, {Name, Pos, S#state{actors = S#state.actors ++ [A]}}}
+ end.
+
+draw_actor(A, LineX, S, DC) ->
+ if
+ S#state.hide_actors, A#actor.exclude ->
+ false;
+ true ->
+ Scale = S#state.scale,
+ TextX = LineX - (5 * Scale),
+ {TextY, LineTopY, LineBotY} = calc_y(S),
+ Color =
+ case A#actor.name of
+ ?unknown -> {255,126,0};% orange
+ _ -> {227,38,54} % red
+ end,
+ {String, Font} =
+ if
+ S#state.context =:= display, A#actor.exclude ->
+ {"(" ++ A#actor.string ++ ")", S#state.normal_font};
+ S#state.context =:= display, A#actor.include ->
+ {"[" ++ A#actor.string ++ "]", S#state.bold_font};
+ true ->
+ {A#actor.string, S#state.normal_font}
+ end,
+ write_text(String, TextX, TextY, Color, Font, S, DC),
+ wxPen:setColour(S#state.pen, Color),
+ wxDC:setPen(DC, S#state.pen),
+ wxDC:drawLines(DC, [{LineX, LineTopY}, {LineX, LineBotY}]),
+ true
+ end.
+
+calc_y(#state{canvas_height = Height, scale = Scale}) ->
+ TextY = ?initial_y * Scale,
+ LineTopY = round(TextY + ((?incr_y / 2) * Scale)),
+ LineBotY = Height,
+ %% LineBotY = round(Height - ((?incr_y / 2) * Scale)),
+ {TextY, LineTopY, LineBotY}.
+
+display_all(S) ->
+ Actors = S#state.actors,
+ Actors2 = [A#actor{include = false, exclude = false} || A <- Actors],
+ S2 = S#state{actors = Actors2,
+ display_all = true,
+ hide_actions = false,
+ hide_actors = false},
+ wxCheckBox:setValue(S2#state.hide_actions_box, S2#state.hide_actions),
+ wxCheckBox:setValue(S2#state.hide_actors_box, S2#state.hide_actors),
+ revert_main_window(S2).
+
+is_hidden(A, S) ->
+ case S#state.display_all of
+ true ->
+ A#actor.exclude;
+ false ->
+ A#actor.exclude orelse not A#actor.include
+ end.
+
+is_hidden(From, To, S) ->
+ Actors = S#state.actors,
+ DisplayAll = S#state.display_all,
+ FromMatch = lists:keysearch(From, #actor.name, Actors),
+ ToMatch = lists:keysearch(To, #actor.name, Actors),
+ case {FromMatch, ToMatch} of
+ {false, false} ->
+ not DisplayAll;
+ {false, {value, T}} ->
+ is_hidden(T, S);
+ {{value, F}, false} ->
+ is_hidden(F, S);
+ {{value, F}, {value, T}} when DisplayAll ->
+ is_hidden(F, S) orelse is_hidden(T, S);
+ {{value, F}, {value, T}} when F#actor.include; T#actor.include ->
+ F#actor.exclude orelse T#actor.exclude;
+ {{value, _F}, {value, _T}}->
+ true
+ end.
+
+move_actor(From, To, Actors, S) ->
+ Pos = #actor.name,
+ ToName = To#actor.name,
+ FromName = From#actor.name,
+ ToIx = actor_index(ToName, Pos, Actors),
+ FromIx = actor_index(FromName, Pos, Actors),
+ if
+ FromIx =/= 0, ToIx =/= 0, ToIx > FromIx ->
+ Actors2 = lists:keydelete(FromName, Pos, Actors),
+ Actors3 = insert_actor_after(From, To, Actors2),
+ S2 = S#state{actors = Actors3},
+ refresh_main_window(S2);
+ FromIx =/= 0, ToIx =/= 0 ->
+ Actors2 = lists:keydelete(FromName, Pos, Actors),
+ Actors3 = insert_actor_before(From, To, Actors2),
+ S2 = S#state{actors = Actors3},
+ refresh_main_window(S2);
+ true ->
+ %% Ignore
+ S
+ end.
+
+insert_actor_after(From, To, [H | T]) ->
+ case To#actor.name =:= H#actor.name of
+ true -> [H, From | T];
+ false -> [H | insert_actor_after(From, To, T)]
+ end;
+insert_actor_after(_From, _To, []) ->
+ [].
+
+insert_actor_before(From, To, [H | T]) ->
+ case To#actor.name =:= H#actor.name of
+ true -> [From, H | T];
+ false -> [H | insert_actor_before(From, To, T)]
+ end;
+insert_actor_before(_From, _To, []) ->
+ [].
+
+actor_index(_Key, _Pos, []) ->
+ 0;
+actor_index(Key, Pos, [H | T]) ->
+ case Key =:= element(Pos, H) of
+ false -> actor_index(Key, Pos, T) + 1;
+ true -> 1
+ end.
+
+y_to_n(Y, S) ->
+ Y2 = ((Y / S#state.scale) - ?initial_y + (?incr_y / 2)),
+ N = round(Y2 / ?incr_y - 0.2),
+ MaxN = queue_length(S#state.events),
+ if
+ N =< 0 -> actor;
+ N > MaxN -> actor;
+ true -> {event, N}
+ end.
+
+x_to_n(X, S) ->
+ Scale = S#state.scale,
+ Len = length(S#state.actors),
+ X2 = X - (?initial_x * Scale),
+ N = X2 / (?incr_x * Scale),
+ N2 = trunc(N + 1.5),
+ if
+ N2 > Len -> Len;
+ N2 < 1 -> 1;
+ true -> N2
+ end.
+
+write_text(Text, X, Y, Color, Font, S, DC) ->
+ wxDC:setFont(DC, Font),
+ wxDC:setTextForeground(DC, Color),
+ wxDC:drawText(DC, Text, {X, round(Y - (?incr_y * S#state.scale / 2))-3}).
+
+do_open_event(S, N) ->
+ Events = queue_to_list(S#state.events),
+ S2 = S#state{events = list_to_queue(Events)},
+ case catch lists:nth(N, Events) of
+ {'EXIT', _} ->
+ {error, {no_such_event, N}};
+ #e{key = Key} ->
+ Pid = S#state.collector_pid,
+ Fun = fun create_contents_window/2,
+ Prev = et_collector:iterate(Pid, Key, -1),
+ {S2, Res} =
+ if
+ Prev =:= Key ->
+ et_collector:iterate(Pid, first, 1, Fun, {S2, []});
+ true ->
+ et_collector:iterate(Pid, Prev, 1, Fun, {S2, []})
+ end,
+ case Res of
+ [] ->
+ {error, no_contents_viewer_started};
+ [Single] ->
+ Single;
+ Multi ->
+ {error, {too_many, Multi}}
+ end
+ end.
+
+create_contents_window(Event, {S, Res}) ->
+ Options = [{viewer_pid, self()},
+ {event, Event},
+ {event_order, S#state.event_order},
+ {active_filter, S#state.active_filter},
+ {wx_debug, S#state.wx_debug}
+ | S#state.filters],
+ case catch et_wx_contents_viewer:start_link(Options) of
+ {ok, Pid} ->
+ {S, [{ok, Pid} | Res]};
+ {error, Reason} ->
+ ok = error_logger:format("~p(~p): create_contents_window(~p) ->~n ~p~n",
+ [?MODULE, self(), Options, Reason]),
+ {S, [{error, Reason} | Res]};
+ Stuff ->
+ {S, [{error, {stuff, Stuff}} | Res]}
+ end.
+
+print_setup(S) ->
+ S2 = #state{print_psdd = PSDD0, print_d = PD0} = init_printers(S),
+
+ wxPageSetupDialogData:setPrintData(PSDD0, PD0),
+ PSD = wxPageSetupDialog:new(S#state.frame, [{data,PSDD0}]),
+ wxPageSetupDialog:showModal(PSD),
+
+ PSDD1 = wxPageSetupDialog:getPageSetupData(PSD),
+ PD1 = wxPageSetupDialogData:getPrintData(PSDD1),
+
+ %% Create new objects using copy constructor
+ PD = wxPrintData:new(PD1),
+ PsDD = wxPageSetupDialogData:new(PSDD1),
+ wxPageSetupDialog:destroy(PSD),
+ wxPageSetupDialogData:destroy(PSDD0),
+ wxPrintData:destroy(PD0),
+ S2#state{print_psdd=PsDD, print_d=PD}.
+
+print(#state{print_d = undefined, print_psdd = undefined} = S, Scope) ->
+ S2 = print_setup(S),
+ print(S2, Scope);
+print(#state{print_psdd = PSDD, print_d = PD} = S, Scope) ->
+ PDD = wxPrintDialogData:new(PD),
+ wxPrintDialogData:enablePrintToFile(PDD, true),
+ wxPrintDialogData:enablePageNumbers(PDD, true),
+ wxPrintDialogData:enableSelection(PDD, true),
+ Tab = ets:new(?MODULE, [public]),
+ GetPageInfo =
+ fun(This) ->
+ {_, _, PW, PH} = wxPrintout:getPaperRectPixels(This),
+ PrinterS = S#state{context = printer,
+ canvas_width = PW,
+ canvas_height = PH},
+ EventsPerPage = events_per_page(PrinterS, PH),
+ PagedEvents = paged_events(PrinterS, Scope, EventsPerPage),
+ [ets:insert(Tab, PE) || PE <- PagedEvents],
+ ets:insert(Tab, PrinterS),
+ NumPages = length(PagedEvents),
+ {1, NumPages, 1, NumPages}
+ end,
+ HasPage =
+ fun(_This, Page) ->
+ Size = ets:info(Tab, size),
+ NumPages = Size - 1,
+ (Page >= 1) andalso (Page =< NumPages)
+ end,
+ OnPrintPage =
+ fun(This, Page) ->
+ wxPrintout:mapScreenSizeToPageMargins(This, PSDD),
+ [PrinterS] = ets:lookup(Tab, state),
+ Events = ets:lookup_element(Tab, Page, 2),
+ DC = wxPrintout:getDC(This),
+ PrinterS2 = draw_all_actors(PrinterS, DC),
+ PrinterS3 = PrinterS2#state{y_pos = ?initial_y * PrinterS2#state.scale},
+ lists:foldl(fun(E, State) -> display_event(E, State, DC) end,
+ PrinterS3,
+ Events),
+ true
+ end,
+ Printout1 = wxPrintout:new("Print", OnPrintPage,
+ [{getPageInfo, GetPageInfo}, {hasPage, HasPage}]),
+ Printout2 = wxPrintout:new("Print", OnPrintPage,
+ [{getPageInfo, GetPageInfo}, {hasPage, HasPage}]),
+ Preview = wxPrintPreview:new(Printout1, [{printoutForPrinting, Printout2}, {data,PDD}]),
+ case wxPrintPreview:isOk(Preview) of
+ true ->
+ PF = wxPreviewFrame:new(Preview, S#state.frame, []),
+ wxPreviewFrame:centre(PF, [{dir, ?wxBOTH}]),
+ wxPreviewFrame:initialize(PF),
+ wxPreviewFrame:centre(PF),
+ wxPreviewFrame:show(PF),
+ OnClose = fun(_Wx, EventRef) -> ets:delete(Tab), wxEvent:skip(EventRef) end,
+ wxPreviewFrame:connect(PF, close_window, [{callback, OnClose}]);
+ false ->
+ io:format("Could not create preview window.\n"
+ "Perhaps your current printer is not set correctly?~n", []),
+ wxPrintPreview:destroy(Preview),
+ ets:delete(Tab)
+ end,
+ S.
+
+paged_events(S, Scope, EventsPerPage) ->
+ {_, Events} =
+ case Scope of
+ print_one_page ->
+ revert(S#state{events_per_page = EventsPerPage});
+ print_all_pages ->
+ collect_more_events(S, first, S#state.n_events)
+ end,
+ split_list(Events, EventsPerPage).
+
+split_list(List, N) when is_integer(N), N > 0 ->
+ do_split_list(List, N, 1, []).
+
+do_split_list([], _N, _Page, Acc) ->
+ lists:reverse(Acc);
+do_split_list(List, N, Page, Acc) ->
+ {Items, Rest} = pick_n(List, N, []),
+ do_split_list(Rest, N, Page + 1, [{Page, Items} | Acc]).
+
+get_latest_resize(#wx{obj = ObjRef, event = #wxSize{}} = Wx) ->
+ receive
+ #wx{obj = ObjRef, event = #wxSize{}} = Wx2 ->
+ get_latest_resize(Wx2)
+ after 100 ->
+ Wx
+ end.
+
+get_latest_scroll(#wx{obj = ObjRef, event = #wxScroll{type = scroll_changed}} = Wx) ->
+ receive
+ #wx{obj = ObjRef, event = #wxScroll{type = scroll_changed}} = Wx2 ->
+ get_latest_scroll(Wx2)
+ after 100 ->
+ Wx
+ end.
+
+update_scroll_bar(#state{scroll_bar = ScrollBar,
+ status_bar = StatusBar,
+ events_per_page = EventsPerPage,
+ n_events = N} = S) ->
+ Opts = [{refresh, true}],
+ {_, LineTopY, LineBotY} = calc_y(S),
+ Range = LineBotY - LineTopY,
+ EventPos =
+ case event_pos(S) of
+ 1 -> 0;
+ P -> P
+ end,
+ if
+ N =/= 0,
+ EventsPerPage =/= 0 ->
+ PixelsPerEvent = Range / EventsPerPage,
+ Share = EventsPerPage / N,
+ wxScrollBar:setScrollbar(ScrollBar,
+ trunc(EventPos * Share * PixelsPerEvent),
+ round(Share * Range),
+ Range,
+ round(Share * Range),
+ Opts);
+ true ->
+ wxScrollBar:setScrollbar(ScrollBar,
+ 0,
+ Range,
+ Range,
+ Range,
+ Opts)
+ end,
+ wxStatusBar:setStatusText(StatusBar, where_text(S)),
+ S.
+
+events_per_page(S, PageHeight) ->
+ EventsPerPage = ((PageHeight - (?initial_y * S#state.scale)) div (?incr_y * S#state.scale)),
+ lists:max([1, EventsPerPage]).
+
+select_file(Frame, Message, DefaultFile, Style) ->
+ Dialog = wxFileDialog:new(Frame,
+ [{message, Message},
+ {defaultDir, filename:dirname(DefaultFile)},
+ {defaultFile, filename:basename(DefaultFile)},
+ {style, Style}]),
+ Choice =
+ case wxMessageDialog:showModal(Dialog) of
+ ?wxID_CANCEL -> cancel;
+ ?wxID_OK -> {ok, wxFileDialog:getPath(Dialog)}
+ end,
+ wxFileDialog:destroy(Dialog),
+ Choice.
+
+%%%----------------------------------------------------------------------
+%%% String padding of actors
+%%%----------------------------------------------------------------------
+
+opt_create_actor(Name, Tag, S) ->
+ Actors = S#state.actors,
+ New =
+ case lists:keysearch(Name, #actor.name, Actors) of
+ {value, Old} -> Old;
+ false -> create_actor(Name)
+ end,
+ case Tag of
+ include -> New#actor{include = true};
+ exclude -> New#actor{exclude = true}
+ end.
+
+create_actor(Name) ->
+ String = name_to_string(Name),
+ %% PaddedString = pad_string(String, 8),
+ #actor{name = Name, string = String, include = false, exclude = false}.
+
+name_to_string(Name) ->
+ case catch io_lib:format("~s", [Name]) of
+ {'EXIT', _} -> lists:flatten(io_lib:format("~w", [Name]));
+ GoodString -> lists:flatten(GoodString)
+ end.
+
+pad_string(Atom, MinLen) when is_atom(Atom) ->
+ pad_string(atom_to_list(Atom), MinLen);
+pad_string(String, MinLen) when is_integer(MinLen), MinLen >= 0 ->
+ Len = length(String),
+ case Len >= MinLen of
+ true ->
+ String;
+ false ->
+ String ++ lists:duplicate(MinLen - Len, $ )
+ end.
+
+%%%----------------------------------------------------------------------
+%%% Queue management
+%%%----------------------------------------------------------------------
+
+queue_new() ->
+ {0, [], []}.
+
+queue_in(X, {Size, In, Out}) ->
+ {Size + 1, [X | In], Out}.
+
+%% queue_out(Q) ->
+%% case Q of
+%% {Size, In, [H | Out]} -> {{value, H}, {Size - 1, In, Out}};
+%% {Size, [], []} -> {empty, {Size, [], []}};
+%% {Size, In, _} -> queue_out({Size, [], lists:reverse(In)})
+%% end.
+
+queue_to_list({_Size, [], Out}) ->
+ Out;
+queue_to_list({_Size, In, Out}) ->
+ Out ++ lists:reverse(In).
+
+queue_length({Size, _In, _Out}) ->
+ Size.
+
+list_to_queue(List) when is_list(List) ->
+ {length(List), [], List}.
diff --git a/lib/et/src/modules.mk b/lib/et/src/modules.mk
index 8e9dd1a386..8d6c0902fb 100644
--- a/lib/et/src/modules.mk
+++ b/lib/et/src/modules.mk
@@ -1,27 +1,30 @@
#-*-makefile-*- ; force emacs to enter makefile-mode
# %CopyrightBegin%
-#
-# Copyright Ericsson AB 2001-2009. All Rights Reserved.
-#
+#
+# Copyright Ericsson AB 2001-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%
MODULES = \
et \
et_collector \
- et_contents_viewer \
+ et_gs_contents_viewer \
+ et_gs_viewer \
et_selector \
- et_viewer
+ et_viewer \
+ et_wx_contents_viewer \
+ et_wx_viewer
HRL_FILES = \
../include/et.hrl
diff --git a/lib/et/test/Makefile b/lib/et/test/Makefile
new file mode 100644
index 0000000000..9aedf96ce9
--- /dev/null
+++ b/lib/et/test/Makefile
@@ -0,0 +1,81 @@
+#
+# %CopyrightBegin%
+#
+# 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%
+
+include $(ERL_TOP)/make/target.mk
+include $(ERL_TOP)/make/$(TARGET)/otp.mk
+
+# ----------------------------------------------------
+# Target Specs
+# ----------------------------------------------------
+
+MODULES= \
+ ett \
+ et_wx_SUITE \
+ et_test_lib
+
+
+ERL_FILES= $(MODULES:%=%.erl)
+
+HRL_FILES= et_test_lib.hrl
+
+TARGET_FILES= \
+ $(MODULES:%=$(EBIN)/%.$(EMULATOR))
+
+INSTALL_PROGS= $(TARGET_FILES)
+
+# ----------------------------------------------------
+# Release directory specification
+# ----------------------------------------------------
+RELSYSDIR = $(RELEASE_PATH)/et_test
+
+# ----------------------------------------------------
+# FLAGS
+# ----------------------------------------------------
+#ERL_COMPILE_FLAGS +=
+
+EBIN = .
+
+# ----------------------------------------------------
+# Targets
+# ----------------------------------------------------
+
+tests debug opt: $(TARGET_FILES)
+
+clean:
+ rm -f $(TARGET_FILES)
+ rm -f core
+
+docs:
+
+# ----------------------------------------------------
+# Release Target
+# ----------------------------------------------------
+include $(ERL_TOP)/make/otp_release_targets.mk
+
+release_spec: opt
+
+release_tests_spec: opt
+ $(INSTALL_DIR) $(RELSYSDIR)
+ $(INSTALL_DATA) et.spec $(ERL_FILES) $(HRL_FILES) $(RELSYSDIR)
+ $(INSTALL_PROGRAM) ett $(INSTALL_PROGS) $(RELSYSDIR)
+# chmod -f -R u+w $(RELSYSDIR)
+# @tar cf - *_SUITE_data | (cd $(RELSYSDIR); tar xf -)
+
+release_docs_spec:
+
+
diff --git a/lib/et/test/README b/lib/et/test/README
new file mode 100644
index 0000000000..4269186c93
--- /dev/null
+++ b/lib/et/test/README
@@ -0,0 +1,30 @@
+
+Testing and running et tests.
+
+Testing gui api/applications can be hard, but we can at least
+test that wxerlang behaves as we expected, i.e. that the api
+is consistent and that it don't crash.
+
+The tests are structured as they are because we want you to
+be able to run them in three different ways.
+ - direct via an erlang shell
+ - via common_test application
+ - via erlang/OTP inhouse ts tool.
+
+To run all the tests compile them and on unix
+run ./ett to create an erlang terminal.
+
+Invoke ett:t(). in the erlang shell to run all regression tests.
+If you want to specific tests invoke ett:t(Module)
+or ett:t(Module, TestCase).
+
+To run all tests including the ones that require manual intervention run.
+ett:t(all, [{user,true}]).
+
+To see every test_case window use
+ett:t(all, [{user,step}]).
+This requires that you manually close each window to step to the
+next test_case.
+
+If you want to run specific test_cases use:
+ett:t({Module,TestCase}, [{user,step}]).
diff --git a/lib/et/test/et.spec b/lib/et/test/et.spec
new file mode 100644
index 0000000000..69cd8d7582
--- /dev/null
+++ b/lib/et/test/et.spec
@@ -0,0 +1,2 @@
+{topcase, {dir, "../et_test"}}.
+
diff --git a/lib/et/test/et_test_lib.erl b/lib/et/test/et_test_lib.erl
new file mode 100644
index 0000000000..b91b63786c
--- /dev/null
+++ b/lib/et/test/et_test_lib.erl
@@ -0,0 +1,329 @@
+%%
+%% %CopyrightBegin%
+%%
+%% 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(et_test_lib).
+-compile(export_all).
+
+-include("et_test_lib.hrl").
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+init_per_suite(Config) when is_list(Config)->
+ incr_timetrap(Config, 5).
+
+end_per_suite(Config) when is_list(Config)->
+ ok.
+
+incr_timetrap(Config, Times) ->
+ Key = tc_timeout,
+ KeyPos = 1,
+ NewTime =
+ case lists:keysearch(Key, KeyPos, Config) of
+ {value, {Key, OldTime}} ->
+ (timer:minutes(1) + OldTime) * Times;
+ false ->
+ timer:minutes(1) * Times
+ end,
+ lists:keystore(Key, KeyPos, Config, {Key, NewTime}).
+
+set_kill_timer(Config) ->
+ case init:get_argument(et_test_timeout) of
+ {ok, _} ->
+ Config;
+ _ ->
+ Time =
+ case lookup_config(tc_timeout, Config) of
+ [] ->
+ timer:minutes(5);
+ ConfigTime when is_integer(ConfigTime) ->
+ ConfigTime
+ end,
+ WatchDog = test_server:timetrap(Time),
+ [{kill_timer, WatchDog} | Config]
+ end.
+
+reset_kill_timer(Config) ->
+ DogKiller =
+ case get(et_test_server) of
+ true ->
+ fun(P) when is_pid(P) -> P ! stop;
+ (_) -> ok
+ end;
+ _ ->
+ fun(Ref) -> test_server:timetrap_cancel(Ref) end
+ end,
+ case lists:keysearch(kill_timer, 1, Config) of
+ {value, {kill_timer, WatchDog}} ->
+ DogKiller(WatchDog),
+ lists:keydelete(kill_timer, 1, Config);
+ _ ->
+ Config
+ end.
+
+lookup_config(Key,Config) ->
+ case lists:keysearch(Key, 1, Config) of
+ {value,{Key,Val}} ->
+ Val;
+ _ ->
+ []
+ end.
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+wx_init_per_suite(Config) ->
+ {_Pid, Ref} =
+ spawn_monitor(fun() ->
+ %% Avoid test case crash if wx master process dies
+ process_flag(trap_exit, true),
+ try
+ case os:type() of
+ {unix,darwin} ->
+ exit({skipped, "Can not test on MacOSX"});
+ {unix, _} ->
+ io:format("DISPLAY ~s~n", [os:getenv("DISPLAY")]),
+ case proplists:get_value(xserver, Config, none) of
+ none -> ignore;
+ Server -> os:putenv("DISPLAY", Server)
+ end;
+ _ ->
+ ignore
+ end,
+ wx:new(),
+ wx:destroy()
+ catch
+ error:undef ->
+ exit({skipped, "No wx compiled for this platform"});
+ _:Reason ->
+ exit({skipped, lists:flatten(io_lib:format("Start wx failed: ~p", [Reason]))})
+ end,
+ exit(normal)
+ end),
+ receive
+ {'DOWN', Ref, _, _, normal} ->
+ init_per_suite(Config);
+ {'DOWN', Ref, _, _, {skipped, _} = Skipped} ->
+ Skipped;
+ {'DOWN', Ref, _, _, Reason} ->
+ exit({wx_init_per_suite, Reason})
+ after timer:minutes(1) ->
+ exit({wx_init_per_suite, timeout})
+ end.
+
+wx_end_per_suite(Config) ->
+ end_per_suite(Config).
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+init_per_testcase(_Func, Config) when is_list(Config) ->
+ set_kill_timer(Config),
+ global:register_name(et_global_logger, group_leader()),
+ Config.
+
+end_per_testcase(_Func, Config) when is_list(Config) ->
+ global:unregister_name(et_global_logger),
+ reset_kill_timer(Config),
+ Config.
+
+%% Backwards compatible with test_server
+tc_info(suite) -> [];
+tc_info(doc) -> "".
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+%% Use ?log(Format, Args) as wrapper
+log(Format, Args, LongFile, Line) ->
+ File = filename:basename(LongFile),
+ Format2 = lists:concat([File, "(", Line, ")", ": ", Format]),
+ log(Format2, Args).
+
+log(Format, Args) ->
+ case global:whereis_name(et_global_logger) of
+ undefined ->
+ io:format(user, Format, Args);
+ Pid ->
+ io:format(Pid, Format, Args)
+ end.
+
+verbose(Format, Args, File, Line) ->
+ Arg = et_test_verbose,
+ case get(Arg) of
+ false ->
+ ok;
+ true ->
+ log(Format, Args, File, Line);
+ undefined ->
+ case init:get_argument(Arg) of
+ {ok, List} when is_list(List) ->
+ case lists:last(List) of
+ ["true"] ->
+ put(Arg, true),
+ log(Format, Args, File, Line);
+ _ ->
+ put(Arg, false),
+ ok
+ end;
+ _ ->
+ put(Arg, false),
+ ok
+ end
+ end.
+
+error(Format, Args, File, Line) ->
+ global:send(et_global_logger, {failed, File, Line}),
+ Fail = {filename:basename(File),Line,Args},
+ case global:whereis_name(et_test_case_sup) of
+ undefined -> ignore;
+ Pid -> Pid ! Fail
+ %% global:send(et_test_case_sup, Fail),
+ end,
+ log("<ERROR>~n" ++ Format, Args, File, Line).
+
+
+pick_msg() ->
+ receive
+ Message -> Message
+ after 4000 -> timeout
+ end.
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%% Utility functions
+
+user_available(Config) ->
+ false /= proplists:get_value(user, Config, false).
+
+
+wx_destroy(Frame, Config) ->
+ case proplists:get_value(user, Config, false) of
+ false ->
+ timer:sleep(100),
+ ?m(ok, wxFrame:destroy(Frame)),
+ ?m(ok, wx:destroy());
+ true ->
+ timer:sleep(500),
+ ?m(ok, wxFrame:destroy(Frame)),
+ ?m(ok, wx:destroy());
+ step -> %% Wait for user to close window
+ ?m(ok, wxEvtHandler:connect(Frame, close_window, [{skip,true}])),
+ wait_for_close()
+ end.
+
+wait_for_close() ->
+ receive
+ #wx{event=#wxClose{}} ->
+ ?log("Got close~n",[]),
+ ?m(ok, wx:destroy());
+ #wx{obj=Obj, event=Event} ->
+ try
+ Name = wxTopLevelWindow:getTitle(Obj),
+ ?log("~p Event: ~p~n", [Name, Event])
+ catch _:_ ->
+ ?log("Event: ~p~n", [Event])
+ end,
+ wait_for_close();
+ Other ->
+ ?log("Unexpected: ~p~n", [Other]),
+ wait_for_close()
+ end.
+
+
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%% A small test server, which can be run standalone in a shell
+
+run_test(Test = {_,_},Config) ->
+ run_test([Test],Config);
+run_test([{Module, TC} | Rest], Config) ->
+ log("\n\n=== Eval test suite: ~w ===~n", [Module]),
+ case catch Module:init_per_suite(Config) of
+ {skipped, Reason} ->
+ log("Test suite skipped: ~s~n", [Reason]),
+ [{skipped, Reason}];
+ NewConfig when is_list(NewConfig) ->
+ Res =
+ if
+ TC =:= all ->
+ [do_run_test(Module, Test, NewConfig) || Test <- Module:all()];
+ is_list(TC) ->
+ [do_run_test(Module, Test, NewConfig) || Test <- TC];
+ true ->
+ [do_run_test(Module, TC, NewConfig)]
+ end,
+ Module:end_per_suite(NewConfig),
+ Res ++ run_test(Rest, NewConfig);
+ Error ->
+ ?error("Test suite skipped: ~w~n", [Error]),
+ [{skipped, Error}]
+ end;
+run_test([], _Config) ->
+ [].
+
+do_run_test(Module, all, Config) ->
+ All = [{Module, Test} || Test <- Module:all()],
+ run_test(All, Config);
+do_run_test(Module, TestCase, Config) ->
+ log("Eval test case: ~w~n", [{Module, TestCase}]),
+ Sec = timer:seconds(1) * 1000,
+ {T, Res} =
+ timer:tc(?MODULE, eval_test_case, [Module, TestCase, Config]),
+ log("Tested ~w in ~w sec~n", [TestCase, T div Sec]),
+ {T div Sec, Res}.
+
+eval_test_case(Mod, Fun, Config) ->
+ flush(),
+ global:register_name(et_test_case_sup, self()),
+ Flag = process_flag(trap_exit, true),
+ Pid = spawn_link(?MODULE, test_case_evaluator, [Mod, Fun, [Config]]),
+ R = wait_for_evaluator(Pid, Mod, Fun, Config),
+ global:unregister_name(et_test_case_sup),
+ process_flag(trap_exit, Flag),
+ R.
+
+test_case_evaluator(Mod, Fun, [Config]) ->
+ NewConfig = Mod:init_per_testcase(Fun, Config),
+ R = apply(Mod, Fun, [NewConfig]),
+ Mod:fin_per_testcase(Fun, NewConfig),
+ exit({test_case_ok, R}).
+
+wait_for_evaluator(Pid, Mod, Fun, Config) ->
+ receive
+ {'EXIT', Pid, {test_case_ok, _PidRes}} ->
+ Errors = flush(),
+ Res =
+ case Errors of
+ [] -> ok;
+ Errors -> failed
+ end,
+ {Res, {Mod, Fun}, Errors};
+ {'EXIT', Pid, {skipped, Reason}} ->
+ log("<WARNING> Test case ~w skipped, because ~p~n",
+ [{Mod, Fun}, Reason]),
+ Mod:fin_per_testcase(Fun, Config),
+ {skip, {Mod, Fun}, Reason};
+ {'EXIT', Pid, Reason} ->
+ log("<ERROR> Eval process ~w exited, because\n\t~p~n",
+ [{Mod, Fun}, Reason]),
+ Mod:fin_per_testcase(Fun, Config),
+ {crash, {Mod, Fun}, Reason}
+ end.
+
+flush() ->
+ receive Msg -> [Msg | flush()]
+ after 0 -> []
+ end.
+
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
diff --git a/lib/et/test/et_test_lib.hrl b/lib/et/test/et_test_lib.hrl
new file mode 100644
index 0000000000..0d75318d99
--- /dev/null
+++ b/lib/et/test/et_test_lib.hrl
@@ -0,0 +1,90 @@
+%%
+%% %CopyrightBegin%
+%%
+%% 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%
+
+-include_lib("wx/include/wx.hrl").
+
+-define(log(Format,Args), et_test_lib:log(Format,Args,?FILE,?LINE)).
+-define(warning(Format,Args), ?log("<WARNING>\n " ++ Format,Args)).
+-define(error(Format,Args), et_test_lib:error(Format,Args,?FILE,?LINE)).
+-define(verbose(Format,Args), et_test_lib:verbose(Format,Args,?FILE,?LINE)).
+
+-define(fatal(Format,Args),
+ ?error(Format, Args),
+ exit({test_case_fatal, Format, Args, ?FILE, ?LINE})).
+
+-define(skip(Format,Args),
+ ?warning(Format, Args),
+ exit({skipped, ?flat_format(Format, Args)})).
+
+-define(ignore(Expr),
+ fun() ->
+ AcTuAlReS = (catch (Expr)),
+ ?verbose("ok: ~p\n",[AcTuAlReS])
+ end()).
+
+-define(msym(ExpectedRes, Expr),
+ fun() ->
+ AcTuAlReS = (catch (Expr)),
+ case AcTuAlReS of
+ ExpectedRes ->
+ ?verbose("ok: ~p\n",[AcTuAlReS]),
+ AcTuAlReS;
+ _ ->
+ et_test_lib:error("Not matching actual result was:\n ~p \nExpected ~s\n",
+ [AcTuAlReS, ??ExpectedRes],
+ ?FILE, ?LINE),
+ AcTuAlReS
+ end
+ end()).
+
+-define(m(ExpectedRes, Expr),
+ fun() ->
+ AcTuAlReS = (catch (Expr)),
+ case AcTuAlReS of
+ ExpectedRes ->
+ ?verbose("ok: ~p\n",[AcTuAlReS]),
+ AcTuAlReS;
+ _ ->
+ et_test_lib:error("Not matching actual result was:\n\t~p \nExpected:\n\t~p\n",
+ [AcTuAlReS, ExpectedRes],
+ ?FILE, ?LINE),
+ AcTuAlReS
+ end
+ end()).
+
+-define(m_receive(ExpectedMsg),
+ ?m(ExpectedMsg,et_test_lib:pick_msg())).
+
+-define(m_multi_receive(ExpectedMsgs),
+ fun() ->
+ TmPeXpCtEdMsGs = lists:sort(ExpectedMsgs),
+ AcTuAlReS =
+ lists:sort(lists:map(fun(_) ->
+ et_test_lib:pick_msg()
+ end, TmPeXpCtEdMsGs)),
+ case AcTuAlReS of
+ TmPeXpCtEdMsGs ->
+ ?verbose("ok: ~p\n",[AcTuAlReS]),
+ AcTuAlReS;
+ _ ->
+ et_test_lib:error("Not matching actual result was:\n ~p \nExpected ~p\n",
+ [AcTuAlReS, ExpectedMsgs],
+ ?FILE, ?LINE),
+ AcTuAlReS
+ end
+ end()).
diff --git a/lib/et/test/et_wx_SUITE.erl b/lib/et/test/et_wx_SUITE.erl
new file mode 100644
index 0000000000..1a16ca69a3
--- /dev/null
+++ b/lib/et/test/et_wx_SUITE.erl
@@ -0,0 +1,100 @@
+%%
+%% %CopyrightBegin%
+%%
+%% 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(et_wx_SUITE).
+
+-export([all/0, init_per_suite/1, end_per_suite/1,
+ init_per_testcase/2, fin_per_testcase/2, end_per_testcase/2]).
+
+-compile(export_all).
+
+-include("et_test_lib.hrl").
+
+%% Initialization functions.
+init_per_suite(Config) ->
+ et_test_lib:wx_init_per_suite(Config).
+
+end_per_suite(Config) ->
+ et_test_lib:wx_end_per_suite(Config).
+
+init_per_testcase(Func,Config) ->
+ et_test_lib:init_per_testcase(Func,Config).
+end_per_testcase(Func,Config) ->
+ et_test_lib:end_per_testcase(Func,Config).
+fin_per_testcase(Func,Config) -> %% For test_server
+ et_test_lib:end_per_testcase(Func,Config).
+
+%% SUITE specification
+all() ->
+ all(suite).
+all(suite) ->
+ [
+ start_all_windows
+ ].
+
+%% The test cases
+
+%% Display all windows and see if something crashes
+start_all_windows(TestInfo) when is_atom(TestInfo) ->
+ et_test_lib:tc_info(TestInfo);
+start_all_windows(_Config) ->
+ process_flag(trap_exit, true),
+ {ok, ViewerPid} = ?msym({ok, _}, et_viewer:start_link([])),
+ CollectorPid = et_viewer:get_collector_pid(ViewerPid),
+ ?msym({ok, _}, et_collector:report_event(CollectorPid,
+ 60,
+ some_from_actor,
+ some_to_actor,
+ some_label,
+ "Some details")),
+ timer:sleep(timer:seconds(1)),
+
+ {ok, EventPid1} = ?msym({ok, _}, et_viewer:open_event(ViewerPid, 1)),
+ {ok, EventPid2} = ?msym({ok, _}, et_viewer:open_event(ViewerPid, 1)),
+ timer:sleep(timer:seconds(10)),
+
+ ?msym(alive, process_state(ViewerPid)),
+ ?msym(alive, process_state(CollectorPid)),
+ ?msym(alive, process_state(EventPid1)),
+ ?msym(alive, process_state(EventPid2)),
+
+ ?m(ok, et_wx_contents_viewer:stop(EventPid1)),
+ timer:sleep(timer:seconds(1)),
+
+ ?msym(alive, process_state(ViewerPid)),
+ ?msym(alive, process_state(CollectorPid)),
+ ?msym(dead, process_state(EventPid1)),
+ ?msym(alive, process_state(EventPid2)),
+
+ ?m(ok, et_viewer:stop(ViewerPid)),
+ timer:sleep(timer:seconds(1)),
+
+ ?msym(dead, process_state(ViewerPid)),
+ ?msym(dead, process_state(CollectorPid)),
+ ?msym(dead, process_state(EventPid1)),
+ ?msym(dead, process_state(EventPid2)),
+
+ ?m([], et_test_lib:flush()),
+
+ ok.
+
+process_state(Pid) ->
+ case process_info(Pid, group_leader) of
+ {group_leader, _} -> alive;
+ undefined -> dead
+ end.
diff --git a/lib/et/test/ett b/lib/et/test/ett
new file mode 100755
index 0000000000..da2443df61
--- /dev/null
+++ b/lib/et/test/ett
@@ -0,0 +1,55 @@
+#! /bin/sh -f
+# %CopyrightBegin%
+#
+# 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%
+
+# Usage: ett [-cerl] <args to erlang startup script>
+
+emu=erl
+while [ $# -gt 0 ]; do
+ case "$1" in
+ "-cerl")
+ shift
+ emu=cerl
+ ;;
+ *)
+ break
+ ;;
+ esac
+done
+
+log=test_log_$$
+latest=test_log_latest
+args=${1+"$@"}
+
+erlcmd="$emu -sname test_server -smp -pa ../../et/ebin $p $args -et_test_verbose true -et_test_timeout"
+
+echo "Give the following command in order to see the outcome:"
+echo ""
+echo " less $log"
+
+rm "$latest" 2>/dev/null
+ln -s "$log" "$latest"
+touch "$log"
+
+ostype=`uname -s`
+if [ "$ostype" = "SunOS" ] ; then
+ /usr/openwin/bin/xterm -T "Testing et" -l -lf "$log" -e $erlcmd &
+else
+ xterm -T "Testing et" -e script -f -c "$erlcmd" "$log" &
+fi
+
+tail -f "$log" | egrep 'Eval|<ERROR>|NYI'
diff --git a/lib/et/test/ett.erl b/lib/et/test/ett.erl
new file mode 100644
index 0000000000..1896e65842
--- /dev/null
+++ b/lib/et/test/ett.erl
@@ -0,0 +1,154 @@
+%%
+%% %CopyrightBegin%
+%%
+%% 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(ett).
+-compile(export_all).
+
+%% Modules or suites can be shortcuts, for example wx expands to et_wx_SUITE.
+%%
+%% t(Tests) run et testcases.
+%% Tests can be module, {module, test_case} or [module|{module,test_case}]
+
+t() ->
+ t(read_test_case()).
+t(Test) ->
+ t(Test, []).
+
+t(Mod, TC) when is_atom(Mod), is_atom(TC) ->
+ t({Mod,TC}, []);
+t(all, Config) when is_list(Config) ->
+ Fs = filelib:wildcard("et_*_SUITE.erl"),
+ t([list_to_atom(filename:rootname(File)) || File <- Fs], Config);
+t(Test,Config) when is_list(Config) ->
+ Tests = resolve(Test),
+ write_test_case(Test),
+ Res = et_test_lib:run_test(Tests, Config),
+ append_test_case_info(Test, Res).
+
+user() ->
+ user(read_test_case()).
+user(Mod) ->
+ t(Mod, [{user,step}]).
+user(Mod,Tc) when is_atom(Tc) ->
+ t({Mod,Tc}, [{user,step}]).
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%% Resolves the name of test suites and test cases
+%% according to the alias definitions. Single atoms
+%% are assumed to be the name of a test suite.
+
+resolve(Suite0) when is_atom(Suite0) ->
+ case alias(Suite0) of
+ Suite when is_atom(Suite) ->
+ {Suite, all};
+ {Suite, Case} ->
+ {Suite, Case}
+ end;
+resolve({Suite0, Case}) when is_atom(Suite0), is_atom(Case) ->
+ case alias(Suite0) of
+ Suite when is_atom(Suite) ->
+ {Suite, Case};
+ {Suite, Case2} ->
+ {Suite, Case2}
+ end;
+resolve(List) when is_list(List) ->
+ [resolve(Case) || Case <- List].
+
+alias(Suite) when is_atom(Suite) ->
+ Str = atom_to_list(Suite),
+ case {Str, lists:reverse(Str)} of
+ {"et" ++ _, "ETIUS" ++ _} ->
+ Suite;
+ _ ->
+ list_to_atom("et_" ++ Str ++ "_SUITE")
+ end.
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+config_fname() ->
+ "et_test_case_config".
+
+%% Read default config file
+read_config() ->
+ Fname = config_fname(),
+ et_test_lib:log("Consulting file ~s...~n", [Fname]),
+ case file:consult(Fname) of
+ {ok, Config} ->
+ et_test_lib:log("Read config ~w~n", [Config]),
+ Config;
+ _Error ->
+ Config = et_test_lib:default_config(),
+ et_test_lib:log("<>WARNING<> Using default config: ~w~n", [Config]),
+ Config
+ end.
+
+%% Write new default config file
+write_config(Config) when is_list(Config) ->
+ Fname = config_fname(),
+ {ok, Fd} = file:open(Fname, write),
+ write_list(Fd, Config),
+ file:close(Fd).
+
+write_list(Fd, [H | T]) ->
+ ok = io:format(Fd, "~p.~n",[H]),
+ write_list(Fd, T);
+write_list(_, []) ->
+ ok.
+
+test_case_fname() ->
+ "et_test_case_info".
+
+%% Read name of test case
+read_test_case() ->
+ Fname = test_case_fname(),
+ case file:open(Fname, [read]) of
+ {ok, Fd} ->
+ Res = io:read(Fd, []),
+ file:close(Fd),
+ case Res of
+ {ok, TestCase} ->
+ et_test_lib:log("Using test case ~w from file ~s~n",
+ [TestCase, Fname]),
+ TestCase;
+ {error, _} ->
+ default_test_case(Fname)
+ end;
+ {error, _} ->
+ default_test_case(Fname)
+ end.
+
+default_test_case(Fname) ->
+ TestCase = all,
+ et_test_lib:log("<>WARNING<> Cannot read file ~s, "
+ "using default test case: ~w~n",
+ [Fname, TestCase]),
+ TestCase.
+
+write_test_case(TestCase) ->
+ Fname = test_case_fname(),
+ {ok, Fd} = file:open(Fname, write),
+ ok = io:format(Fd, "~p.~n",[TestCase]),
+ file:close(Fd).
+
+append_test_case_info(TestCase, TestCaseInfo) ->
+ Fname = test_case_fname(),
+ {ok, Fd} = file:open(Fname, [read, write]),
+ ok = io:format(Fd, "~p.~n",[TestCase]),
+ ok = io:format(Fd, "~p.~n",[TestCaseInfo]),
+ file:close(Fd),
+ TestCaseInfo.
diff --git a/lib/et/vsn.mk b/lib/et/vsn.mk
index c6d58e2055..64140ac4ce 100644
--- a/lib/et/vsn.mk
+++ b/lib/et/vsn.mk
@@ -1,23 +1,6 @@
-# This is an -*-makefile-*- file.
-# %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%
+ET_VSN = 1.4
+TICKETS = OTP-8058
-ET_VSN = 1.3.3
-
-TICKETS = OTP-8201
+TICKETS_1_3_3 = OTP-8201
TICKETS_1_3_2 = OTP-8078
TICKETS_1_3_1 = OTP-7830
diff --git a/lib/eunit/doc/src/Makefile b/lib/eunit/doc/src/Makefile
index faf2f9a847..19be96d763 100644
--- a/lib/eunit/doc/src/Makefile
+++ b/lib/eunit/doc/src/Makefile
@@ -123,11 +123,10 @@ man: $(MAN3_FILES)
gifs: $(GIF_FILES:%=$(HTMLDIR)/%)
$(XML_REF3_FILES):
- docb_gen -def vsn $(EUNIT_VSN) -includes $(EUNIT_INC_DIR) $(EUNIT_DIR)/$(@:%.xml=%.erl)
+ escript $(DOCGEN)/priv/bin/xml_from_edoc.escript -def vsn $(EUNIT_VSN) -i $(EUNIT_INC_DIR) $(EUNIT_DIR)/$(@:%.xml=%.erl)
$(XML_CHAPTER_FILES):
- docb_gen -chapter -def vsn $(EUNIT_VSN) ../overview.edoc
-
+ escript $(DOCGEN)/priv/bin/xml_from_edoc.escript -def vsn $(EUNIT_VSN) -chapter ../overview.edoc
info:
@echo "XML_PART_FILES: $(XML_PART_FILES)"
diff --git a/lib/eunit/doc/src/notes.xml b/lib/eunit/doc/src/notes.xml
index ac86448fab..974ba1db4e 100644
--- a/lib/eunit/doc/src/notes.xml
+++ b/lib/eunit/doc/src/notes.xml
@@ -32,6 +32,37 @@
</header>
<p>This document describes the changes made to the EUnit application.</p>
+<section><title>Eunit 2.1.5</title>
+
+ <section><title>Improvements and New Features</title>
+ <list>
+ <item>
+ <p>The documentation is now possible to build in an open
+ source environment after a number of bugs are fixed and
+ some features are added in the documentation build
+ process. </p>
+ <p>- The arity calculation is updated.</p>
+ <p>- The module prefix used in the function names for
+ bif's are removed in the generated links so the links
+ will look like
+ "http://www.erlang.org/doc/man/erlang.html#append_element-2"
+ instead of
+ "http://www.erlang.org/doc/man/erlang.html#erlang:append_element-2".</p>
+ <p>- Enhanced the menu positioning in the html
+ documentation when a new page is loaded.</p>
+ <p>- A number of corrections in the generation of man
+ pages (thanks to Sergei Golovan)</p>
+ <p>- The legal notice is taken from the xml book file so
+ OTP's build process can be used for non OTP
+ applications.</p>
+ <p>
+ Own Id: OTP-8343</p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
<section><title>Eunit 2.1.4</title>
<section><title>Improvements and New Features</title>
diff --git a/lib/eunit/info b/lib/eunit/info
index 138f4dc040..e7e6265940 100644
--- a/lib/eunit/info
+++ b/lib/eunit/info
@@ -1,2 +1,2 @@
-group: tools
+group: test
short: Support for unit testing.
diff --git a/lib/eunit/test/Makefile b/lib/eunit/test/Makefile
index 83fca0ade4..74d485d1cc 100644
--- a/lib/eunit/test/Makefile
+++ b/lib/eunit/test/Makefile
@@ -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%
#
include $(ERL_TOP)/make/target.mk
@@ -50,7 +50,7 @@ EBIN = .
make_emakefile:
$(ERL_TOP)/make/make_emakefile $(ERL_COMPILE_FLAGS) -o$(EBIN) \
- $(MODULES) >> $(EMAKEFILE)
+ $(MODULES) > $(EMAKEFILE)
tests debug opt: make_emakefile
erl $(ERL_MAKE_FLAGS) -make
diff --git a/lib/eunit/vsn.mk b/lib/eunit/vsn.mk
index 002703b1b3..3bfa9c8000 100644
--- a/lib/eunit/vsn.mk
+++ b/lib/eunit/vsn.mk
@@ -1 +1 @@
-EUNIT_VSN = 2.1.4
+EUNIT_VSN = 2.1.5
diff --git a/lib/hipe/Makefile b/lib/hipe/Makefile
index be3a618e34..6682c9aac0 100644
--- a/lib/hipe/Makefile
+++ b/lib/hipe/Makefile
@@ -1,19 +1,19 @@
#
# %CopyrightBegin%
-#
-# Copyright Ericsson AB 2001-2009. All Rights Reserved.
-#
+#
+# Copyright Ericsson AB 2001-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%
#
SHELL=/bin/sh
@@ -27,7 +27,7 @@ else
HIPE_SUBDIRS =
endif
-ALWAYS_SUBDIRS = misc main cerl icode flow util
+ALWAYS_SUBDIRS = misc main cerl icode flow util doc/src
ifdef HIPE_ENABLED
# "rtl" below must be the first directory so that file rtl/hipe_literals.hrl
@@ -37,20 +37,20 @@ else
SUB_DIRECTORIES = $(ALWAYS_SUBDIRS)
endif
+include native.mk
+
#
# Default Subdir Targets
#
include $(ERL_TOP)/make/otp_subdir.mk
-# This overrides the default recursive-make edocs target in otp_subdir.mk
-# It is not pretty, but it will have to do for now.
-docs:
+# The overriding docs target have been removed so the default make rules work properly.
+
+edocs:
@if [ -d $(ERL_TOP)/lib/edoc/ebin ]; then \
erl -noshell -pa $(ERL_TOP)/lib/edoc/ebin $(ERL_TOP)/lib/syntax_tools/ebin $(ERL_TOP)/lib/xmerl/ebin -run edoc_run application 'hipe' '"."' '[new,no_packages]' -s init stop ; \
fi
-edocs: docs
-
all-subdirs:
-for dir in $(SUB_DIRECTORIES); do \
(cd $$dir; $(MAKE) $(MAKETARGET) EBIN=../ebin; cd ..); \
diff --git a/lib/hipe/amd64/Makefile b/lib/hipe/amd64/Makefile
index 93e5f086d9..58377e5349 100644
--- a/lib/hipe/amd64/Makefile
+++ b/lib/hipe/amd64/Makefile
@@ -1,19 +1,19 @@
#
# %CopyrightBegin%
-#
-# Copyright Ericsson AB 2004-2009. All Rights Reserved.
-#
+#
+# Copyright Ericsson AB 2004-2010. All Rights Reserved.
+#
# The contents of this file are subject to the Erlang Public License,
# Version 1.1, (the "License"); you may not use this file except in
# compliance with the License. You should have received a copy of the
# Erlang Public License along with this software. If not, it can be
# retrieved online at http://www.erlang.org/.
-#
+#
# Software distributed under the License is distributed on an "AS IS"
# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
# the License for the specific language governing rights and limitations
# under the License.
-#
+#
# %CopyrightEnd%
#
@@ -80,7 +80,10 @@ ERL_COMPILE_FLAGS += -DHIPE_AMD64 +warn_exported_vars
debug opt: $(TARGET_FILES)
-docs: $(DOC_FILES)
+docs:
+
+# Moved docs target to edocs so the standard docs rule work properly.
+edocs: $(DOC_FILES)
clean:
rm -f $(TARGET_FILES)
diff --git a/lib/hipe/arm/Makefile b/lib/hipe/arm/Makefile
index 571a1da0fc..3f60cd77cc 100644
--- a/lib/hipe/arm/Makefile
+++ b/lib/hipe/arm/Makefile
@@ -1,19 +1,19 @@
#
# %CopyrightBegin%
-#
-# Copyright Ericsson AB 2005-2009. All Rights Reserved.
-#
+#
+# Copyright Ericsson AB 2005-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%
#
@@ -81,7 +81,10 @@ ERL_COMPILE_FLAGS += +warn_exported_vars
debug opt: $(TARGET_FILES)
-docs: $(DOC_FILES)
+docs:
+
+# Moved docs target to edocs so the standard docs rule work properly.
+edocs: $(DOC_FILES)
clean:
rm -f $(TARGET_FILES)
diff --git a/lib/hipe/cerl/Makefile b/lib/hipe/cerl/Makefile
index fb7ca1153b..7fcc44d27d 100644
--- a/lib/hipe/cerl/Makefile
+++ b/lib/hipe/cerl/Makefile
@@ -1,19 +1,19 @@
#
# %CopyrightBegin%
-#
-# Copyright Ericsson AB 2003-2009. All Rights Reserved.
-#
+#
+# Copyright Ericsson AB 2003-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%
#
@@ -73,7 +73,10 @@ ERL_COMPILE_FLAGS += +inline +warn_exported_vars +warn_unused_import +warn_missi
debug opt: $(TARGET_FILES)
-docs: $(DOC_FILES)
+docs:
+
+# Moved docs target to edocs so the standard docs rule work properly.
+edocs: $(DOC_FILES)
clean:
rm -f $(TARGET_FILES)
diff --git a/lib/hipe/cerl/erl_bif_types.erl b/lib/hipe/cerl/erl_bif_types.erl
index 0f57a93a7c..38342870e5 100644
--- a/lib/hipe/cerl/erl_bif_types.erl
+++ b/lib/hipe/cerl/erl_bif_types.erl
@@ -1,20 +1,20 @@
%% -*- erlang-indent-level: 2 -*-
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2003-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 2003-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%
%%
%% =====================================================================
@@ -102,6 +102,7 @@
t_list_elements/1,
t_list_termination/1,
t_mfa/0,
+ t_module/0,
t_nil/0,
t_node/0,
t_none/0,
@@ -694,6 +695,8 @@ type(erlang, binary_to_list, 3, Xs) ->
fun (_) -> t_list(t_byte()) end);
type(erlang, binary_to_term, 1, Xs) ->
strict(arg_types(erlang, binary_to_term, 1), Xs, fun (_) -> t_any() end);
+type(erlang, binary_to_term, 2, Xs) ->
+ strict(arg_types(erlang, binary_to_term, 2), Xs, fun (_) -> t_any() end);
type(erlang, bitsize, 1, Xs) -> % XXX: TAKE OUT
type(erlang, bit_size, 1, Xs);
type(erlang, bit_size, 1, Xs) ->
@@ -710,6 +713,10 @@ type(erlang, bump_reductions, 1, Xs) ->
type(erlang, byte_size, 1, Xs) ->
strict(arg_types(erlang, byte_size, 1), Xs,
fun (_) -> t_non_neg_integer() end);
+type(erlang, call_on_load_function, 1, Xs) ->
+ %% Internal BIF used by on_load.
+ strict(arg_types(erlang, call_on_load_function, 1), Xs,
+ fun (_) -> t_any() end);
type(erlang, cancel_timer, 1, Xs) ->
strict(arg_types(erlang, cancel_timer, 1), Xs,
fun (_) -> t_sup(t_integer(), t_atom('false')) end);
@@ -773,6 +780,10 @@ type(erlang, element, 2, Xs) ->
type(erlang, erase, 0, _) -> t_any();
type(erlang, erase, 1, _) -> t_any();
type(erlang, external_size, 1, _) -> t_integer();
+type(erlang, finish_after_on_load, 2, Xs) ->
+ %% Internal BIF used by on_load.
+ strict(arg_types(erlang, finish_after_on_load, 2), Xs,
+ fun (_) -> t_atom('true') end);
type(erlang, float, 1, Xs) ->
strict(arg_types(erlang, float, 1), Xs, fun (_) -> t_float() end);
type(erlang, float_to_list, 1, Xs) ->
@@ -1760,8 +1771,29 @@ type(erts_debug, disassemble, 1, Xs) ->
fun (_) -> t_sup([t_atom('false'),
t_atom('undef'),
t_tuple([t_integer(), t_binary(), t_mfa()])]) end);
+type(erts_debug, dist_ext_to_term, 2, Xs) ->
+ strict(arg_types(erts_debug, dist_ext_to_term, 2), Xs,
+ fun (_) -> t_any() end);
type(erts_debug, flat_size, 1, Xs) ->
strict(arg_types(erts_debug, flat_size, 1), Xs, fun (_) -> t_integer() end);
+type(erts_debug, lock_counters, 1, Xs) ->
+ strict(arg_types(erts_debug, lock_counters, 1), Xs,
+ fun ([Arg]) ->
+ case t_is_atom(Arg) of
+ true ->
+ case t_atom_vals(Arg) of
+ ['enabled'] -> t_boolean();
+ ['info'] -> t_any();
+ ['clear'] -> t_atom(ok);
+ _ -> t_sup([t_boolean(), t_any(), t_atom('ok')])
+ end;
+ false ->
+ case t_is_tuple(Arg) of
+ true -> t_boolean();
+ false -> t_sup([t_boolean(), t_any(), t_atom('ok')])
+ end
+ end
+ end);
type(erts_debug, same, 2, Xs) ->
strict(arg_types(erts_debug, same, 2), Xs, fun (_) -> t_boolean() end);
%%-- ets ----------------------------------------------------------------------
@@ -2661,6 +2693,8 @@ type(os, getenv, 1, Xs) ->
type(os, getpid, 0, _) -> t_string();
type(os, putenv, 2, Xs) ->
strict(arg_types(os, putenv, 2), Xs, fun (_) -> t_atom('true') end);
+type(os, timestamp, 0, _) ->
+ t_time();
%%-- re -----------------------------------------------------------------------
type(re, compile, 1, Xs) ->
strict(arg_types(re, compile, 1), Xs,
@@ -3119,21 +3153,26 @@ arith(Op, X1, X2) ->
end,
%% io:format("done arith ~p = ~p~n", [Op, {NewMin, NewMax}]),
{ok, t_from_range(NewMin, NewMax)};
- false ->
- AllVals =
- case Op of
- '+' -> [X + Y || X <- L1, Y <- L2];
- '-' -> [X - Y || X <- L1, Y <- L2];
- '*' -> [X * Y || X <- L1, Y <- L2];
- 'div' -> [X div Y || X <- L1, Y <- L2,Y =/= 0];
- 'rem' -> [X rem Y || X <- L1, Y <- L2,Y =/= 0];
- 'bsl' -> [X bsl Y || X <- L1, Y <- L2];
- 'bsr' -> [X bsr Y || X <- L1, Y <- L2];
- 'band' -> [X band Y || X <- L1, Y <- L2];
- 'bor' -> [X bor Y || X <- L1, Y <- L2];
- 'bxor' -> [X bxor Y || X <- L1, Y <- L2]
- end,
- {ok, t_integers(ordsets:from_list(AllVals))}
+ false ->
+ %% Some of these arithmetic operations might throw a system_limit
+ %% exception; for example, when trying to evaluate 1 bsl 100000000.
+ try case Op of
+ '+' -> [X + Y || X <- L1, Y <- L2];
+ '-' -> [X - Y || X <- L1, Y <- L2];
+ '*' -> [X * Y || X <- L1, Y <- L2];
+ 'div' -> [X div Y || X <- L1, Y <- L2, Y =/= 0];
+ 'rem' -> [X rem Y || X <- L1, Y <- L2, Y =/= 0];
+ 'bsl' -> [X bsl Y || X <- L1, Y <- L2];
+ 'bsr' -> [X bsr Y || X <- L1, Y <- L2];
+ 'band' -> [X band Y || X <- L1, Y <- L2];
+ 'bor' -> [X bor Y || X <- L1, Y <- L2];
+ 'bxor' -> [X bxor Y || X <- L1, Y <- L2]
+ end of
+ AllVals ->
+ {ok, t_integers(ordsets:from_list(AllVals))}
+ catch
+ error:system_limit -> error
+ end
end
end.
@@ -3325,8 +3364,7 @@ arg_types(erlang, abs, 1) ->
arg_types(erlang, append_element, 2) ->
[t_tuple(), t_any()];
arg_types(erlang, apply, 2) ->
- [t_sup(t_tuple([t_sup(t_atom(), % module name
- t_tuple()), % parameterized module
+ [t_sup(t_tuple([t_module(),
t_atom()]),
t_fun()),
t_list()];
@@ -3346,6 +3384,8 @@ arg_types(erlang, binary_to_list, 3) ->
[t_binary(), t_pos_integer(), t_pos_integer()]; % I want fixnum, but cannot
arg_types(erlang, binary_to_term, 1) ->
[t_binary()];
+arg_types(erlang, binary_to_term, 2) ->
+ [t_binary(), t_list(t_atom('safe'))];
arg_types(erlang, bitsize, 1) -> % XXX: TAKE OUT
arg_types(erlang, bit_size, 1);
arg_types(erlang, bit_size, 1) ->
@@ -3358,6 +3398,8 @@ arg_types(erlang, bump_reductions, 1) ->
[t_pos_fixnum()];
arg_types(erlang, byte_size, 1) ->
[t_binary()];
+arg_types(erlang, call_on_load_function, 1) ->
+ [t_atom()];
arg_types(erlang, cancel_timer, 1) ->
[t_reference()];
arg_types(erlang, check_process_code, 2) ->
@@ -3402,6 +3444,8 @@ arg_types(erlang, exit, 2) ->
[t_sup(t_pid(), t_port()), t_any()];
arg_types(erlang, external_size, 1) ->
[t_any()]; % takes any term as input
+arg_types(erlang, finish_after_on_load, 2) ->
+ [t_atom(), t_boolean()];
arg_types(erlang, float, 1) ->
[t_number()];
arg_types(erlang, float_to_list, 1) ->
@@ -3853,8 +3897,16 @@ arg_types(erts_debug, breakpoint, 2) ->
[t_tuple([t_atom(), t_atom(), t_sup(t_integer(), t_atom('_'))]), t_boolean()];
arg_types(erts_debug, disassemble, 1) ->
[t_sup(t_mfa(), t_integer())];
+arg_types(erts_debug, dist_ext_to_term, 2) ->
+ [t_tuple(), t_binary()];
arg_types(erts_debug, flat_size, 1) ->
[t_any()];
+arg_types(erts_debug, lock_counters, 1) ->
+ [t_sup([t_atom(enabled),
+ t_atom(info),
+ t_atom(clear),
+ t_tuple([t_atom(copy_save), t_boolean()]),
+ t_tuple([t_atom(process_locks), t_boolean()])])];
arg_types(erts_debug, same, 2) ->
[t_any(), t_any()];
%%------- ets -----------------------------------------------------------------
@@ -4277,6 +4329,8 @@ arg_types(os, getpid, 0) ->
[];
arg_types(os, putenv, 2) ->
[t_string(), t_string()];
+arg_types(os, timestamp, 0) ->
+ [];
%%-- re -----------------------------------------------------------------------
arg_types(re, compile, 1) ->
[t_iodata()];
@@ -4334,6 +4388,7 @@ structure_inspecting_args(erlang, is_pid, 1) -> [1];
structure_inspecting_args(erlang, is_port, 1) -> [1];
structure_inspecting_args(erlang, is_reference, 1) -> [1];
structure_inspecting_args(erlang, is_tuple, 1) -> [1];
+structure_inspecting_args(erlang, length, 1) -> [1];
%%structure_inspecting_args(erlang, setelement, 3) -> [2].
structure_inspecting_args(_, _, _) -> []. % XXX: assume no arg needs inspection
@@ -4462,6 +4517,7 @@ t_code_load_error_rsn() -> % also used in erlang:load_module/2
t_atom('nofile'),
t_atom('not_purged'),
t_atom('native_code'),
+ t_atom('on_load'),
t_atom('sticky_directory')]). % only for the 'code' functions
t_code_loaded_fname_or_status() ->
@@ -4893,7 +4949,8 @@ t_inet_setoption_packettype() ->
t_integers([0,1,2,4]),
t_atom('asn1'), t_atom('cdr'), t_atom('sunrm'),
t_atom('fcgi'), t_atom('tpkt'), t_atom('line'),
- t_atom('http')]). %% but t_atom('httph') is not needed
+ t_atom('http'),
+ t_atom('http_bin')]). %% but t_atom('httph') is not needed
t_inet_posix_error() ->
t_atom(). %% XXX: Very underspecified
diff --git a/lib/hipe/cerl/erl_types.erl b/lib/hipe/cerl/erl_types.erl
index fac308d0c6..b4d80d359a 100644
--- a/lib/hipe/cerl/erl_types.erl
+++ b/lib/hipe/cerl/erl_types.erl
@@ -1,20 +1,20 @@
%% -*- erlang-indent-level: 2 -*-
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2003-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 2003-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%
%%
%% ======================================================================
@@ -97,6 +97,7 @@
t_inf/3,
t_inf_lists/2,
t_inf_lists/3,
+ t_inf_lists_masked/3,
t_integer/0,
t_integer/1,
t_non_neg_integer/0,
@@ -167,6 +168,7 @@
t_opaque_match_record/2,
t_opaque_matching_structure/2,
t_opaque_structure/1,
+ %% t_parameterized_module/0,
t_pid/0,
t_port/0,
t_maybe_improper_list/0,
@@ -194,9 +196,11 @@
t_tuple_sizes/1,
t_tuple_subtypes/1,
t_unify/2,
+ t_unify/3,
t_unit/0,
t_unopaque/1,
t_unopaque/2,
+ t_unopaque_on_mismatch/3,
t_var/1,
t_var_name/1,
%% t_assign_variables_to_subtype/2,
@@ -227,6 +231,8 @@
%% Limits
%%
+-define(REC_TYPE_LIMIT, 2).
+
-define(TUPLE_TAG_LIMIT, 5).
-define(TUPLE_ARITY_LIMIT, 10).
-define(SET_LIMIT, 13).
@@ -590,33 +596,48 @@ t_opaque_tuple_tags(OpaqueStruct) ->
end.
%% Decompose opaque instances of type arg2 to structured types, in arg1
--spec t_struct_from_opaque(erl_type(), erl_type()) -> erl_type().
-
-t_struct_from_opaque(?function(Domain, Range), Opaque) ->
- ?function(t_struct_from_opaque(Domain, Opaque),
- t_struct_from_opaque(Range, Opaque));
-t_struct_from_opaque(?list(Types, Term, Size), Opaque) ->
- ?list(t_struct_from_opaque(Types, Opaque), Term, Size);
-t_struct_from_opaque(?opaque(_) = T, Opaque) ->
- case T =:= Opaque of
+%% XXX: Same as t_unopaque
+-spec t_struct_from_opaque(erl_type(), [erl_type()]) -> erl_type().
+
+t_struct_from_opaque(?function(Domain, Range), Opaques) ->
+ ?function(t_struct_from_opaque(Domain, Opaques),
+ t_struct_from_opaque(Range, Opaques));
+t_struct_from_opaque(?list(Types, Term, Size), Opaques) ->
+ ?list(t_struct_from_opaque(Types, Opaques), Term, Size);
+t_struct_from_opaque(?opaque(_) = T, Opaques) ->
+ case lists:member(T, Opaques) of
true -> t_opaque_structure(T);
false -> T
end;
-t_struct_from_opaque(?product(Types), Opaque) ->
- ?product(list_struct_from_opaque(Types, Opaque));
-t_struct_from_opaque(?tuple(?any, _, _) = T, _Opaque) -> T;
-t_struct_from_opaque(?tuple(Types, Arity, Tag), Opaque) ->
- ?tuple(list_struct_from_opaque(Types, Opaque), Arity, Tag);
-t_struct_from_opaque(?tuple_set(Set), Opaque) ->
- NewSet = [{Sz, [t_struct_from_opaque(T, Opaque) || T <- Tuples]}
+t_struct_from_opaque(?product(Types), Opaques) ->
+ ?product(list_struct_from_opaque(Types, Opaques));
+t_struct_from_opaque(?tuple(?any, _, _) = T, _Opaques) -> T;
+t_struct_from_opaque(?tuple(Types, Arity, Tag), Opaques) ->
+ ?tuple(list_struct_from_opaque(Types, Opaques), Arity, Tag);
+t_struct_from_opaque(?tuple_set(Set), Opaques) ->
+ NewSet = [{Sz, [t_struct_from_opaque(T, Opaques) || T <- Tuples]}
|| {Sz, Tuples} <- Set],
?tuple_set(NewSet);
-t_struct_from_opaque(?union(List), Opaque) ->
- t_sup(list_struct_from_opaque(List, Opaque));
-t_struct_from_opaque(Type, _Opaque) -> Type.
-
-list_struct_from_opaque(Types, Opaque) ->
- [t_struct_from_opaque(Type, Opaque) || Type <- Types].
+t_struct_from_opaque(?union(List), Opaques) ->
+ t_sup(list_struct_from_opaque(List, Opaques));
+t_struct_from_opaque(Type, _Opaques) -> Type.
+
+list_struct_from_opaque(Types, Opaques) ->
+ [t_struct_from_opaque(Type, Opaques) || Type <- Types].
+
+-spec t_unopaque_on_mismatch(erl_type(), erl_type(), [erl_type()]) -> erl_type().
+
+t_unopaque_on_mismatch(GenType, Type, Opaques) ->
+ case t_inf(GenType, Type) of
+ ?none ->
+ Unopaqued = t_unopaque(Type, Opaques),
+ %% Unions might be a problem, must investigate.
+ case t_inf(GenType, Unopaqued) of
+ ?none -> Type;
+ _ -> Unopaqued
+ end;
+ _ -> Type
+ end.
-spec module_builtin_opaques(module()) -> [erl_type()].
@@ -630,7 +651,7 @@ module_builtin_opaques(Module) ->
-spec t_remote(module(), atom(), [_]) -> erl_type().
t_remote(Mod, Name, Args) ->
- ?remote(set_singleton(#remote{mod=Mod, name=Name, args=Args})).
+ ?remote(set_singleton(#remote{mod = Mod, name = Name, args = Args})).
-spec t_is_remote(erl_type()) -> boolean().
@@ -640,78 +661,124 @@ t_is_remote(_) -> false.
-spec t_solve_remote(erl_type(), dict()) -> erl_type().
t_solve_remote(Type , Records) ->
- t_solve_remote(Type, Records, ordsets:new()).
+ {RT, _RR} = t_solve_remote(Type, Records, []),
+ RT.
t_solve_remote(?function(Domain, Range), R, C) ->
- ?function(t_solve_remote(Domain, R, C), t_solve_remote(Range, R, C));
+ {RT1, RR1} = t_solve_remote(Domain, R, C),
+ {RT2, RR2} = t_solve_remote(Range, R, C),
+ {?function(RT1, RT2), RR1 ++ RR2};
t_solve_remote(?list(Types, Term, Size), R, C) ->
- ?list(t_solve_remote(Types, R, C), Term, Size);
+ {RT, RR} = t_solve_remote(Types, R, C),
+ {?list(RT, Term, Size), RR};
t_solve_remote(?product(Types), R, C) ->
- ?product(list_solve_remote(Types, R, C));
+ {RL, RR} = list_solve_remote(Types, R, C),
+ {?product(RL), RR};
t_solve_remote(?opaque(Set), R, C) ->
List = ordsets:to_list(Set),
- NewList = [Remote#opaque{struct = t_solve_remote(Struct, R, C)}
- || Remote = #opaque{struct = Struct} <- List],
- ?opaque(ordsets:from_list(NewList));
-t_solve_remote(?tuple(?any, _, _) = T, _R, _C) -> T;
+ {NewList, RR} = opaques_solve_remote(List, R, C),
+ {?opaque(ordsets:from_list(NewList)), RR};
+t_solve_remote(?tuple(?any, _, _) = T, _R, _C) -> {T, []};
t_solve_remote(?tuple(Types, Arity, Tag), R, C) ->
- ?tuple(list_solve_remote(Types, R, C), Arity, Tag);
-t_solve_remote(?tuple_set(Set), R, C) ->
- NewSet = [{Sz, [t_solve_remote(T, R, C) || T <- Tuples]} || {Sz, Tuples} <- Set],
- ?tuple_set(NewSet);
+ {RL, RR} = list_solve_remote(Types, R, C),
+ {?tuple(RL, Arity, Tag), RR};
+t_solve_remote(?tuple_set(Set), R, C) ->
+ {NewSet, RR} = tuples_solve_remote(Set, R, C),
+ {?tuple_set(NewSet), RR};
t_solve_remote(?remote(Set), R, C) ->
- Cycle = ordsets:intersection(Set, C),
- case ordsets:size(Cycle) of
- 0 -> ok;
- _ ->
- CycleMsg = "Cycle detected while processing remote types: " ++
- t_to_string(?remote(C), dict:new()),
- throw({error, CycleMsg})
- end,
- NewCycle = ordsets:union(C, Set),
- TypeFun =
- fun(#remote{mod = RemoteModule, name = Name, args = Args}) ->
- case dict:find(RemoteModule, R) of
- error ->
- Msg = io_lib:format("Cannot locate module ~w to "
- "resolve the remote type: ~w:~w()~n",
- [RemoteModule, RemoteModule, Name]),
- throw({error, Msg});
- {ok, RemoteDict} ->
- case lookup_type(Name, RemoteDict) of
- {type, {_TypeMod, Type, ArgNames}} when length(Args) =:= length(ArgNames) ->
- List = lists:zip(ArgNames, Args),
- TmpVardict = dict:from_list(List),
- NewType = t_from_form(Type, RemoteDict, TmpVardict),
- t_solve_remote(NewType, R, NewCycle);
- {opaque, {OpModule, Type, ArgNames}} when length(Args) =:= length(ArgNames) ->
- List = lists:zip(ArgNames, Args),
- TmpVardict = dict:from_list(List),
- Rep = t_from_form(Type, RemoteDict, TmpVardict),
- NewRep = t_solve_remote(Rep, R, NewCycle),
- t_from_form({opaque, -1, Name, {OpModule, Args, NewRep}},
- RemoteDict, TmpVardict);
- {type, _} ->
- Msg = io_lib:format("Unknown remote type ~w\n", [Name]),
- throw({error, Msg});
- {opaque, _} ->
- Msg = io_lib:format("Unknown remote opaque type ~w\n", [Name]),
- throw({error, Msg});
- error ->
- Msg = io_lib:format("Unable to find remote type ~w:~w()\n",
- [RemoteModule, Name]),
- throw({error, Msg})
- end
- end
- end,
RemoteList = ordsets:to_list(Set),
- t_sup([TypeFun(RemoteType) || RemoteType <- RemoteList]);
-t_solve_remote(?union(List), R, C) ->
- t_sup(list_solve_remote(List, R, C));
-t_solve_remote(T, _R, _C) -> T.
+ {RL, RR} = list_solve_remote_type(RemoteList, R, C),
+ {t_sup(RL), RR};
+t_solve_remote(?union(List), R, C) ->
+ {RL, RR} = list_solve_remote(List, R, C),
+ {t_sup(RL), RR};
+t_solve_remote(T, _R, _C) -> {T, []}.
+
+t_solve_remote_type(#remote{mod = RemMod, name = Name, args = Args} = RemType,
+ R, C) ->
+ case dict:find(RemMod, R) of
+ error ->
+ Msg = io_lib:format("Cannot locate module ~w to "
+ "resolve the remote type: ~w:~w()~n",
+ [RemMod, RemMod, Name]),
+ throw({error, Msg});
+ {ok, RemDict} ->
+ case lookup_type(Name, RemDict) of
+ {type, {_Mod, Type, ArgNames}} when length(Args) =:= length(ArgNames) ->
+ {NewType, NewCycle, NewRR} =
+ case unfold(RemType, C) of
+ true ->
+ List = lists:zip(ArgNames, Args),
+ TmpVarDict = dict:from_list(List),
+ {t_from_form(Type, RemDict, TmpVarDict), [RemType|C], []};
+ false -> {t_any(), C, [RemType]}
+ end,
+ {RT, RR} = t_solve_remote(NewType, R, NewCycle),
+ RetRR = NewRR ++ RR,
+ RT1 =
+ case lists:member(RemType, RetRR) of
+ true -> t_limit(RT, ?REC_TYPE_LIMIT);
+ false -> RT
+ end,
+ {RT1, RetRR};
+ {opaque, {Mod, Type, ArgNames}} when length(Args) =:= length(ArgNames) ->
+ List = lists:zip(ArgNames, Args),
+ TmpVarDict = dict:from_list(List),
+ {Rep, NewCycle, NewRR} =
+ case unfold(RemType, C) of
+ true -> {t_from_form(Type, RemDict, TmpVarDict), [RemType|C], []};
+ false -> {t_any(), C, [RemType]}
+ end,
+ {NewRep, RR} = t_solve_remote(Rep, R, NewCycle),
+ RetRR = NewRR ++ RR,
+ RT1 =
+ case lists:member(RemType, RetRR) of
+ true -> t_limit(NewRep, ?REC_TYPE_LIMIT);
+ false -> NewRep
+ end,
+ {t_from_form({opaque, -1, Name, {Mod, Args, RT1}},
+ RemDict, TmpVarDict),
+ RetRR};
+ {type, _} ->
+ Msg = io_lib:format("Unknown remote type ~w\n", [Name]),
+ throw({error, Msg});
+ {opaque, _} ->
+ Msg = io_lib:format("Unknown remote opaque type ~w\n", [Name]),
+ throw({error, Msg});
+ error ->
+ Msg = io_lib:format("Unable to find remote type ~w:~w()\n",
+ [RemMod, Name]),
+ throw({error, Msg})
+ end
+ end.
-list_solve_remote(Types, R, C) ->
- [t_solve_remote(Type, R, C) || Type <- Types].
+list_solve_remote([], _R, _C) ->
+ {[], []};
+list_solve_remote([Type|Types], R, C) ->
+ {RT, RR1} = t_solve_remote(Type, R, C),
+ {RL, RR2} = list_solve_remote(Types, R, C),
+ {[RT|RL], RR1 ++ RR2}.
+
+list_solve_remote_type([], _R, _C) ->
+ {[], []};
+list_solve_remote_type([Type|Types], R, C) ->
+ {RT, RR1} = t_solve_remote_type(Type, R, C),
+ {RL, RR2} = list_solve_remote_type(Types, R, C),
+ {[RT|RL], RR1 ++ RR2}.
+
+opaques_solve_remote([], _R, _C) ->
+ {[], []};
+opaques_solve_remote([#opaque{struct = Struct} = Remote|Tail], R, C) ->
+ {RT, RR1} = t_solve_remote(Struct, R, C),
+ {LOp, RR2} = opaques_solve_remote(Tail, R, C),
+ {[Remote#opaque{struct = RT}|LOp], RR1 ++ RR2}.
+
+tuples_solve_remote([], _R, _C) ->
+ {[], []};
+tuples_solve_remote([{Sz, Tuples}|Tail], R, C) ->
+ {RL, RR1} = list_solve_remote(Tuples, R, C),
+ {LSzTpls, RR2} = tuples_solve_remote(Tail, R, C),
+ {[{Sz, RL}|LSzTpls], RR1 ++ RR2}.
%%-----------------------------------------------------------------------------
%% Unit type. Signals non termination.
@@ -1432,7 +1499,7 @@ t_mfa() ->
-spec t_module() -> erl_type().
t_module() ->
- t_atom().
+ t_sup(t_atom(), t_parameterized_module()).
-spec t_node() -> erl_type().
@@ -1457,6 +1524,11 @@ t_iolist(N) when N > 0 ->
t_iolist(0) ->
t_maybe_improper_list(t_any(), t_sup(t_binary(), t_nil())).
+-spec t_parameterized_module() -> erl_type().
+
+t_parameterized_module() ->
+ t_tuple().
+
-spec t_timeout() -> erl_type().
t_timeout() ->
@@ -2219,9 +2291,23 @@ t_inf(T, ?union(U2), Mode) ->
?union(U1) = force_union(T),
inf_union(U1, U2, Mode);
%% and as a result, the cases for ?opaque should appear *after* ?union
-t_inf(?opaque(Set1), ?opaque(Set2), _Mode) ->
+t_inf(?opaque(Set1) = T1, ?opaque(Set2) = T2, Mode) ->
case set_intersection(Set1, Set2) of
- ?none -> ?none;
+ ?none ->
+ case Mode =:= opaque of
+ true ->
+ Struct1 = t_opaque_structure(T1),
+ case t_inf(Struct1, T2) of
+ ?none ->
+ Struct2 = t_opaque_structure(T2),
+ case t_inf(Struct2, T1) of
+ ?none -> ?none;
+ _ -> T2
+ end;
+ _ -> T1
+ end;
+ false -> ?none
+ end;
NewSet -> ?opaque(NewSet)
end;
t_inf(?opaque(_) = T1, T2, opaque) ->
@@ -2272,6 +2358,12 @@ t_inf_lists_strict([T1|Left1], [T2|Left2], Acc, Mode) ->
t_inf_lists_strict([], [], Acc, _Mode) ->
lists:reverse(Acc).
+-spec t_inf_lists_masked([erl_type()], [erl_type()], [t_inf_mode()]) -> [erl_type()].
+
+t_inf_lists_masked(List1, List2, Mask) ->
+ List = lists:zip3(List1, List2, Mask),
+ [t_inf(T1, T2, Mode) || {T1, T2, Mode} <- List].
+
inf_tuple_sets(L1, L2, Mode) ->
case inf_tuple_sets(L1, L2, [], Mode) of
[] -> ?none;
@@ -2434,82 +2526,112 @@ t_subst(T, _Dict, _Fun) ->
-spec t_unify(erl_type(), erl_type()) -> {erl_type(), [{_, erl_type()}]}.
t_unify(T1, T2) ->
- {T, Dict} = t_unify(T1, T2, dict:new()),
+ t_unify(T1, T2, []).
+
+-spec t_unify(erl_type(), erl_type(), [erl_type()]) -> {erl_type(), [{_, erl_type()}]}.
+
+t_unify(T1, T2, Opaques) ->
+ {T, Dict} = t_unify(T1, T2, dict:new(), Opaques),
{t_subst(T, Dict), lists:keysort(1, dict:to_list(Dict))}.
-t_unify(?var(Id) = T, ?var(Id), Dict) ->
+t_unify(?var(Id) = T, ?var(Id), Dict, _Opaques) ->
{T, Dict};
-t_unify(?var(Id1) = T, ?var(Id2), Dict) ->
+t_unify(?var(Id1) = T, ?var(Id2), Dict, Opaques) ->
case dict:find(Id1, Dict) of
error ->
case dict:find(Id2, Dict) of
error -> {T, dict:store(Id2, T, Dict)};
- {ok, Type} -> {Type, t_unify(T, Type, Dict)}
+ {ok, Type} -> {Type, t_unify(T, Type, Dict, Opaques)}
end;
{ok, Type1} ->
case dict:find(Id2, Dict) of
error -> {Type1, dict:store(Id2, T, Dict)};
- {ok, Type2} -> t_unify(Type1, Type2, Dict)
+ {ok, Type2} -> t_unify(Type1, Type2, Dict, Opaques)
end
end;
-t_unify(?var(Id), Type, Dict) ->
+t_unify(?var(Id), Type, Dict, Opaques) ->
case dict:find(Id, Dict) of
error -> {Type, dict:store(Id, Type, Dict)};
- {ok, VarType} -> t_unify(VarType, Type, Dict)
+ {ok, VarType} -> t_unify(VarType, Type, Dict, Opaques)
end;
-t_unify(Type, ?var(Id), Dict) ->
+t_unify(Type, ?var(Id), Dict, Opaques) ->
case dict:find(Id, Dict) of
error -> {Type, dict:store(Id, Type, Dict)};
- {ok, VarType} -> t_unify(VarType, Type, Dict)
+ {ok, VarType} -> t_unify(VarType, Type, Dict, Opaques)
end;
-t_unify(?function(Domain1, Range1), ?function(Domain2, Range2), Dict) ->
- {Domain, Dict1} = t_unify(Domain1, Domain2, Dict),
- {Range, Dict2} = t_unify(Range1, Range2, Dict1),
+t_unify(?function(Domain1, Range1), ?function(Domain2, Range2), Dict, Opaques) ->
+ {Domain, Dict1} = t_unify(Domain1, Domain2, Dict, Opaques),
+ {Range, Dict2} = t_unify(Range1, Range2, Dict1, Opaques),
{?function(Domain, Range), Dict2};
t_unify(?list(Contents1, Termination1, Size),
- ?list(Contents2, Termination2, Size), Dict) ->
- {Contents, Dict1} = t_unify(Contents1, Contents2, Dict),
- {Termination, Dict2} = t_unify(Termination1, Termination2, Dict1),
+ ?list(Contents2, Termination2, Size), Dict, Opaques) ->
+ {Contents, Dict1} = t_unify(Contents1, Contents2, Dict, Opaques),
+ {Termination, Dict2} = t_unify(Termination1, Termination2, Dict1, Opaques),
{?list(Contents, Termination, Size), Dict2};
-t_unify(?product(Types1), ?product(Types2), Dict) ->
- {Types, Dict1} = unify_lists(Types1, Types2, Dict),
+t_unify(?product(Types1), ?product(Types2), Dict, Opaques) ->
+ {Types, Dict1} = unify_lists(Types1, Types2, Dict, Opaques),
{?product(Types), Dict1};
-t_unify(?tuple(?any, ?any, ?any) = T, ?tuple(?any, ?any, ?any), Dict) ->
+t_unify(?tuple(?any, ?any, ?any) = T, ?tuple(?any, ?any, ?any), Dict, _Opaques) ->
{T, Dict};
t_unify(?tuple(Elements1, Arity, _),
- ?tuple(Elements2, Arity, _), Dict) when Arity =/= ?any ->
- {NewElements, Dict1} = unify_lists(Elements1, Elements2, Dict),
+ ?tuple(Elements2, Arity, _), Dict, Opaques) when Arity =/= ?any ->
+ {NewElements, Dict1} = unify_lists(Elements1, Elements2, Dict, Opaques),
{t_tuple(NewElements), Dict1};
t_unify(?tuple_set([{Arity, _}]) = T1,
- ?tuple(_, Arity, _) = T2, Dict) when Arity =/= ?any ->
- unify_tuple_set_and_tuple(T1, T2, Dict);
+ ?tuple(_, Arity, _) = T2, Dict, Opaques) when Arity =/= ?any ->
+ unify_tuple_set_and_tuple(T1, T2, Dict, Opaques);
t_unify(?tuple(_, Arity, _) = T1,
- ?tuple_set([{Arity, _}]) = T2, Dict) when Arity =/= ?any ->
- unify_tuple_set_and_tuple(T2, T1, Dict);
-t_unify(?tuple_set(List1), ?tuple_set(List2), Dict) ->
+ ?tuple_set([{Arity, _}]) = T2, Dict, Opaques) when Arity =/= ?any ->
+ unify_tuple_set_and_tuple(T2, T1, Dict, Opaques);
+t_unify(?tuple_set(List1), ?tuple_set(List2), Dict, Opaques) ->
{Tuples, NewDict} =
unify_lists(lists:append([T || {_Arity, T} <- List1]),
- lists:append([T || {_Arity, T} <- List2]), Dict),
+ lists:append([T || {_Arity, T} <- List2]), Dict, Opaques),
{t_sup(Tuples), NewDict};
-t_unify(T, T, Dict) ->
+t_unify(?opaque(Elements) = T, ?opaque(Elements), Dict, _Opaques) ->
+ {T, Dict};
+t_unify(?opaque(_) = T1, ?opaque(_) = T2, _Dict, _Opaques) ->
+ throw({mismatch, T1, T2});
+t_unify(Type, ?opaque(_) = OpType, Dict, Opaques) ->
+ t_unify_with_opaque(Type, OpType, Dict, Opaques);
+t_unify(?opaque(_) = OpType, Type, Dict, Opaques) ->
+ t_unify_with_opaque(Type, OpType, Dict, Opaques);
+t_unify(T, T, Dict, _Opaques) ->
{T, Dict};
-t_unify(T1, T2, _) ->
+t_unify(T1, T2, _, _) ->
throw({mismatch, T1, T2}).
+t_unify_with_opaque(Type, OpType, Dict, Opaques) ->
+ case lists:member(OpType, Opaques) of
+ true ->
+ Struct = t_opaque_structure(OpType),
+ try t_unify(Type, Struct, Dict, Opaques) of
+ {_T, Dict1} -> {OpType, Dict1}
+ catch
+ throw:{mismatch, _T1, _T2} ->
+ case t_inf(OpType, Type, opaque) of
+ ?none -> throw({mismatch, Type, OpType});
+ _ -> {OpType, Dict}
+ end
+ end;
+ false ->
+ throw({mismatch, Type, OpType})
+ end.
+
unify_tuple_set_and_tuple(?tuple_set([{Arity, List}]),
- ?tuple(Elements2, Arity, _), Dict) ->
+ ?tuple(Elements2, Arity, _), Dict, Opaques) ->
%% Can only work if the single tuple has variables at correct places.
%% Collapse the tuple set.
- {NewElements, Dict1} = unify_lists(sup_tuple_elements(List), Elements2, Dict),
+ {NewElements, Dict1} = unify_lists(sup_tuple_elements(List), Elements2, Dict, Opaques),
{t_tuple(NewElements), Dict1}.
-unify_lists(L1, L2, Dict) ->
- unify_lists(L1, L2, Dict, []).
+unify_lists(L1, L2, Dict, Opaques) ->
+ unify_lists(L1, L2, Dict, [], Opaques).
-unify_lists([T1|Left1], [T2|Left2], Dict, Acc) ->
- {NewT, NewDict} = t_unify(T1, T2, Dict),
- unify_lists(Left1, Left2, NewDict, [NewT|Acc]);
-unify_lists([], [], Dict, Acc) ->
+unify_lists([T1|Left1], [T2|Left2], Dict, Acc, Opaques) ->
+ {NewT, NewDict} = t_unify(T1, T2, Dict, Opaques),
+ unify_lists(Left1, Left2, NewDict, [NewT|Acc], Opaques);
+unify_lists([], [], Dict, Acc, _Opaques) ->
{lists:reverse(Acc), Dict}.
%%t_assign_variables_to_subtype(T1, T2) ->
@@ -3237,123 +3359,218 @@ t_from_form(Form, RecDict) ->
-spec t_from_form(parse_form(), dict(), dict()) -> erl_type().
-t_from_form({var, _L, '_'}, _RecDict, _VarDict) -> t_any();
-t_from_form({var, _L, Name}, _RecDict, VarDict) ->
+t_from_form(Form, RecDict, VarDict) ->
+ {T, _R} = t_from_form(Form, [], RecDict, VarDict),
+ T.
+
+-type type_names() :: [{'type' | 'opaque' | 'record', atom()}].
+-spec t_from_form(parse_form(), type_names(), dict(), dict()) ->
+ {erl_type(), type_names()}.
+
+t_from_form({var, _L, '_'}, _TypeNames, _RecDict, _VarDict) ->
+ {t_any(), []};
+t_from_form({var, _L, Name}, _TypeNames, _RecDict, VarDict) ->
case dict:find(Name, VarDict) of
- error -> t_var(Name);
- {ok, Val} -> Val
+ error -> {t_var(Name), []};
+ {ok, Val} -> {Val, []}
end;
-t_from_form({ann_type, _L, [_Var, Type]}, RecDict, VarDict) ->
- t_from_form(Type, RecDict, VarDict);
-t_from_form({paren_type, _L, [Type]}, RecDict, VarDict) ->
- t_from_form(Type, RecDict, VarDict);
+t_from_form({ann_type, _L, [_Var, Type]}, TypeNames, RecDict, VarDict) ->
+ t_from_form(Type, TypeNames, RecDict, VarDict);
+t_from_form({paren_type, _L, [Type]}, TypeNames, RecDict, VarDict) ->
+ t_from_form(Type, TypeNames, RecDict, VarDict);
t_from_form({remote_type, _L, [{atom, _, Module}, {atom, _, Type}, Args]},
- RecDict, VarDict) ->
- t_remote(Module, Type, [t_from_form(A, RecDict, VarDict) || A <- Args]);
-t_from_form({atom, _L, Atom}, _RecDict, _VarDict) -> t_atom(Atom);
-t_from_form({integer, _L, Int}, _RecDict, _VarDict) -> t_integer(Int);
-t_from_form({type, _L, any, []}, _RecDict, _VarDict) -> t_any();
-t_from_form({type, _L, arity, []}, _RecDict, _VarDict) -> t_arity();
-t_from_form({type, _L, array, []}, _RecDict, _VarDict) -> t_array();
-t_from_form({type, _L, atom, []}, _RecDict, _VarDict) -> t_atom();
-t_from_form({type, _L, binary, []}, _RecDict, _VarDict) -> t_binary();
+ TypeNames, RecDict, VarDict) ->
+ {L, R} = list_from_form(Args, TypeNames, RecDict, VarDict),
+ {t_remote(Module, Type, L), R};
+t_from_form({atom, _L, Atom}, _TypeNames, _RecDict, _VarDict) ->
+ {t_atom(Atom), []};
+t_from_form({integer, _L, Int}, _TypeNames, _RecDict, _VarDict) ->
+ {t_integer(Int), []};
+t_from_form({type, _L, any, []}, _TypeNames, _RecDict, _VarDict) ->
+ {t_any(), []};
+t_from_form({type, _L, arity, []}, _TypeNames, _RecDict, _VarDict) ->
+ {t_arity(), []};
+t_from_form({type, _L, array, []}, _TypeNames, _RecDict, _VarDict) ->
+ {t_array(), []};
+t_from_form({type, _L, atom, []}, _TypeNames, _RecDict, _VarDict) ->
+ {t_atom(), []};
+t_from_form({type, _L, binary, []}, _TypeNames, _RecDict, _VarDict) ->
+ {t_binary(), []};
t_from_form({type, _L, binary, [{integer, _, Base}, {integer, _, Unit}]},
- _RecDict, _VarDict) ->
- t_bitstr(Unit, Base);
-t_from_form({type, _L, bitstring, []}, _RecDict, _VarDict) -> t_bitstr();
-t_from_form({type, _L, bool, []}, _RecDict, _VarDict) -> t_boolean(); % XXX: Temporarily
-t_from_form({type, _L, boolean, []}, _RecDict, _VarDict) -> t_boolean();
-t_from_form({type, _L, byte, []}, _RecDict, _VarDict) -> t_byte();
-t_from_form({type, _L, char, []}, _RecDict, _VarDict) -> t_char();
-t_from_form({type, _L, dict, []}, _RecDict, _VarDict) -> t_dict();
-t_from_form({type, _L, digraph, []}, _RecDict, _VarDict) -> t_digraph();
-t_from_form({type, _L, float, []}, _RecDict, _VarDict) -> t_float();
-t_from_form({type, _L, function, []}, _RecDict, _VarDict) -> t_fun();
-t_from_form({type, _L, 'fun', []}, _RecDict, _VarDict) -> t_fun();
-t_from_form({type, _L, 'fun', [{type, _, any, []}, Range]}, RecDict, VarDict) ->
- t_fun(t_from_form(Range, RecDict, VarDict));
-t_from_form({type, _L, 'fun', [{type, _, product, Domain}, Range]},
- RecDict, VarDict) ->
- t_fun([t_from_form(D, RecDict, VarDict) || D <- Domain],
- t_from_form(Range, RecDict, VarDict));
-t_from_form({type, _L, gb_set, []}, _RecDict, _VarDict) -> t_gb_set();
-t_from_form({type, _L, gb_tree, []}, _RecDict, _VarDict) -> t_gb_tree();
-t_from_form({type, _L, identifier, []}, _RecDict, _VarDict) -> t_identifier();
-t_from_form({type, _L, integer, []}, _RecDict, _VarDict) -> t_integer();
-t_from_form({type, _L, iodata, []}, _RecDict, _VarDict) -> t_iodata();
-t_from_form({type, _L, iolist, []}, _RecDict, _VarDict) -> t_iolist();
-t_from_form({type, _L, list, []}, _RecDict, _VarDict) -> t_list();
-t_from_form({type, _L, list, [Type]}, RecDict, VarDict) ->
- t_list(t_from_form(Type, RecDict, VarDict));
-t_from_form({type, _L, mfa, []}, _RecDict, _VarDict) -> t_mfa();
-t_from_form({type, _L, module, []}, _RecDict, _VarDict) -> t_module();
-t_from_form({type, _L, nil, []}, _RecDict, _VarDict) -> t_nil();
-t_from_form({type, _L, neg_integer, []}, _RecDict, _VarDict) -> t_neg_integer();
-t_from_form({type, _L, non_neg_integer, []}, _RecDict, _VarDict) ->
- t_non_neg_integer();
-t_from_form({type, _L, no_return, []}, _RecDict, _VarDict) -> t_unit();
-t_from_form({type, _L, node, []}, _RecDict, _VarDict) -> t_node();
-t_from_form({type, _L, none, []}, _RecDict, _VarDict) -> t_none();
-t_from_form({type, _L, nonempty_list, []}, _RecDict, _VarDict) ->
- t_nonempty_list();
-t_from_form({type, _L, nonempty_list, [Type]}, RecDict, VarDict) ->
- t_nonempty_list(t_from_form(Type, RecDict, VarDict));
-t_from_form({type, _L, nonempty_improper_list, [Cont, Term]},
- RecDict, VarDict) ->
- t_cons(t_from_form(Cont, RecDict, VarDict),
- t_from_form(Term, RecDict, VarDict));
-t_from_form({type, _L, nonempty_maybe_improper_list, []}, _RecDict, _VarDict) ->
- t_cons(?any, ?any);
-t_from_form({type, _L, nonempty_maybe_improper_list, [Cont, Term]},
- RecDict, VarDict) ->
- t_cons(t_from_form(Cont, RecDict, VarDict),
- t_from_form(Term, RecDict, VarDict));
-t_from_form({type, _L, nonempty_string, []}, _RecDict, _VarDict) ->
- t_nonempty_string();
-t_from_form({type, _L, number, []}, _RecDict, _VarDict) -> t_number();
-t_from_form({type, _L, pid, []}, _RecDict, _VarDict) -> t_pid();
-t_from_form({type, _L, port, []}, _RecDict, _VarDict) -> t_port();
-t_from_form({type, _L, pos_integer, []}, _RecDict, _VarDict) -> t_pos_integer();
-t_from_form({type, _L, maybe_improper_list, []}, _RecDict, _VarDict) ->
- t_maybe_improper_list();
-t_from_form({type, _L, maybe_improper_list, [Content, Termination]},
- RecDict, VarDict) ->
- t_maybe_improper_list(t_from_form(Content, RecDict, VarDict),
- t_from_form(Termination, RecDict, VarDict));
-t_from_form({type, _L, product, Elements}, RecDict, VarDict) ->
- t_product([t_from_form(E, RecDict, VarDict) || E <- Elements]);
-t_from_form({type, _L, queue, []}, _RecDict, _VarDict) -> t_queue();
+ _TypeNames, _RecDict, _VarDict) ->
+ {t_bitstr(Unit, Base), []};
+t_from_form({type, _L, bitstring, []}, _TypeNames, _RecDict, _VarDict) ->
+ {t_bitstr(), []};
+t_from_form({type, _L, bool, []}, _TypeNames, _RecDict, _VarDict) ->
+ {t_boolean(), []}; % XXX: Temporarily
+t_from_form({type, _L, boolean, []}, _TypeNames, _RecDict, _VarDict) ->
+ {t_boolean(), []};
+t_from_form({type, _L, byte, []}, _TypeNames, _RecDict, _VarDict) ->
+ {t_byte(), []};
+t_from_form({type, _L, char, []}, _TypeNames, _RecDict, _VarDict) ->
+ {t_char(), []};
+t_from_form({type, _L, dict, []}, _TypeNames, _RecDict, _VarDict) ->
+ {t_dict(), []};
+t_from_form({type, _L, digraph, []}, _TypeNames, _RecDict, _VarDict) ->
+ {t_digraph(), []};
+t_from_form({type, _L, float, []}, _TypeNames, _RecDict, _VarDict) ->
+ {t_float(), []};
+t_from_form({type, _L, function, []}, _TypeNames, _RecDict, _VarDict) ->
+ {t_fun(), []};
+t_from_form({type, _L, 'fun', []}, _TypeNames, _RecDict, _VarDict) ->
+ {t_fun(), []};
+t_from_form({type, _L, 'fun', [{type, _, any, []}, Range]}, TypeNames,
+ RecDict, VarDict) ->
+ {T, R} = t_from_form(Range, TypeNames, RecDict, VarDict),
+ {t_fun(T), R};
+t_from_form({type, _L, 'fun', [{type, _, product, Domain}, Range]},
+ TypeNames, RecDict, VarDict) ->
+ {L, R1} = list_from_form(Domain, TypeNames, RecDict, VarDict),
+ {T, R2} = t_from_form(Range, TypeNames, RecDict, VarDict),
+ {t_fun(L, T), R1 ++ R2};
+t_from_form({type, _L, gb_set, []}, _TypeNames, _RecDict, _VarDict) ->
+ {t_gb_set(), []};
+t_from_form({type, _L, gb_tree, []}, _TypeNames, _RecDict, _VarDict) ->
+ {t_gb_tree(), []};
+t_from_form({type, _L, identifier, []}, _TypeNames, _RecDict, _VarDict) ->
+ {t_identifier(), []};
+t_from_form({type, _L, integer, []}, _TypeNames, _RecDict, _VarDict) ->
+ {t_integer(), []};
+t_from_form({type, _L, iodata, []}, _TypeNames, _RecDict, _VarDict) ->
+ {t_iodata(), []};
+t_from_form({type, _L, iolist, []}, _TypeNames, _RecDict, _VarDict) ->
+ {t_iolist(), []};
+t_from_form({type, _L, list, []}, _TypeNames, _RecDict, _VarDict) ->
+ {t_list(), []};
+t_from_form({type, _L, list, [Type]}, TypeNames, RecDict, VarDict) ->
+ {T, R} = t_from_form(Type, TypeNames, RecDict, VarDict),
+ {t_list(T), R};
+t_from_form({type, _L, mfa, []}, _TypeNames, _RecDict, _VarDict) ->
+ {t_mfa(), []};
+t_from_form({type, _L, module, []}, _TypeNames, _RecDict, _VarDict) ->
+ {t_module(), []};
+t_from_form({type, _L, nil, []}, _TypeNames, _RecDict, _VarDict) ->
+ {t_nil(), []};
+t_from_form({type, _L, neg_integer, []}, _TypeNames, _RecDict, _VarDict) ->
+ {t_neg_integer(), []};
+t_from_form({type, _L, non_neg_integer, []}, _TypeNames, _RecDict, _VarDict) ->
+ {t_non_neg_integer(), []};
+t_from_form({type, _L, no_return, []}, _TypeNames, _RecDict, _VarDict) ->
+ {t_unit(), []};
+t_from_form({type, _L, node, []}, _TypeNames, _RecDict, _VarDict) ->
+ {t_node(), []};
+t_from_form({type, _L, none, []}, _TypeNames, _RecDict, _VarDict) ->
+ {t_none(), []};
+t_from_form({type, _L, nonempty_list, []}, _TypeNames, _RecDict, _VarDict) ->
+ {t_nonempty_list(), []};
+t_from_form({type, _L, nonempty_list, [Type]}, TypeNames, RecDict, VarDict) ->
+ {T, R} = t_from_form(Type, TypeNames, RecDict, VarDict),
+ {t_nonempty_list(T), R};
+t_from_form({type, _L, nonempty_improper_list, [Cont, Term]}, TypeNames,
+ RecDict, VarDict) ->
+ {T1, R1} = t_from_form(Cont, TypeNames, RecDict, VarDict),
+ {T2, R2} = t_from_form(Term, TypeNames, RecDict, VarDict),
+ {t_cons(T1, T2), R1 ++ R2};
+t_from_form({type, _L, nonempty_maybe_improper_list, []}, _TypeNames,
+ _RecDict, _VarDict) ->
+ {t_cons(?any, ?any), []};
+t_from_form({type, _L, nonempty_maybe_improper_list, [Cont, Term]}, TypeNames,
+ RecDict, VarDict) ->
+ {T1, R1} = t_from_form(Cont, TypeNames, RecDict, VarDict),
+ {T2, R2} = t_from_form(Term, TypeNames, RecDict, VarDict),
+ {t_cons(T1, T2), R1 ++ R2};
+t_from_form({type, _L, nonempty_string, []}, _TypeNames, _RecDict, _VarDict) ->
+ {t_nonempty_string(), []};
+t_from_form({type, _L, number, []}, _TypeNames, _RecDict, _VarDict) ->
+ {t_number(), []};
+t_from_form({type, _L, pid, []}, _TypeNames, _RecDict, _VarDict) ->
+ {t_pid(), []};
+t_from_form({type, _L, port, []}, _TypeNames, _RecDict, _VarDict) ->
+ {t_port(), []};
+t_from_form({type, _L, pos_integer, []}, _TypeNames, _RecDict, _VarDict) ->
+ {t_pos_integer(), []};
+t_from_form({type, _L, maybe_improper_list, []}, _TypeNames, _RecDict,
+ _VarDict) ->
+ {t_maybe_improper_list(), []};
+t_from_form({type, _L, maybe_improper_list, [Content, Termination]}, TypeNames,
+ RecDict, VarDict) ->
+ {T1, R1} = t_from_form(Content, TypeNames, RecDict, VarDict),
+ {T2, R2} = t_from_form(Termination, TypeNames, RecDict, VarDict),
+ {t_maybe_improper_list(T1, T2), R1 ++ R2};
+t_from_form({type, _L, product, Elements}, TypeNames, RecDict, VarDict) ->
+ {L, R} = list_from_form(Elements, TypeNames, RecDict, VarDict),
+ {t_product(L), R};
+t_from_form({type, _L, queue, []}, _TypeNames, _RecDict, _VarDict) ->
+ {t_queue(), []};
t_from_form({type, _L, range, [{integer, _, From}, {integer, _, To}]},
- _RecDict, _VarDict) ->
- t_from_range(From, To);
-t_from_form({type, _L, record, [Name|Fields]}, RecDict, VarDict) ->
- record_from_form(Name, Fields, RecDict, VarDict);
-t_from_form({type, _L, reference, []}, _RecDict, _VarDict) -> t_reference();
-t_from_form({type, _L, set, []}, _RecDict, _VarDict) -> t_set();
-t_from_form({type, _L, string, []}, _RecDict, _VarDict) -> t_string();
-t_from_form({type, _L, term, []}, _RecDict, _VarDict) -> t_any();
-t_from_form({type, _L, tid, []}, _RecDict, _VarDict) -> t_tid();
-t_from_form({type, _L, timeout, []}, _RecDict, _VarDict) -> t_timeout();
-t_from_form({type, _L, tuple, any}, _RecDict, _VarDict) -> t_tuple();
-t_from_form({type, _L, tuple, Args}, RecDict, VarDict) ->
- t_tuple([t_from_form(A, RecDict, VarDict) || A <- Args]);
-t_from_form({type, _L, union, Args}, RecDict, VarDict) ->
- t_sup([t_from_form(A, RecDict, VarDict) || A <- Args]);
-t_from_form({type, _L, Name, Args}, RecDict, VarDict) ->
+ _TypeNames, _RecDict, _VarDict) ->
+ {t_from_range(From, To), []};
+t_from_form({type, _L, record, [Name|Fields]}, TypeNames, RecDict, VarDict) ->
+ record_from_form(Name, Fields, TypeNames, RecDict, VarDict);
+t_from_form({type, _L, reference, []}, _TypeNames, _RecDict, _VarDict) ->
+ {t_reference(), []};
+t_from_form({type, _L, set, []}, _TypeNames, _RecDict, _VarDict) ->
+ {t_set(), []};
+t_from_form({type, _L, string, []}, _TypeNames, _RecDict, _VarDict) ->
+ {t_string(), []};
+t_from_form({type, _L, term, []}, _TypeNames, _RecDict, _VarDict) ->
+ {t_any(), []};
+t_from_form({type, _L, tid, []}, _TypeNames, _RecDict, _VarDict) ->
+ {t_tid(), []};
+t_from_form({type, _L, timeout, []}, _TypeNames, _RecDict, _VarDict) ->
+ {t_timeout(), []};
+t_from_form({type, _L, tuple, any}, _TypeNames, _RecDict, _VarDict) ->
+ {t_tuple(), []};
+t_from_form({type, _L, tuple, Args}, TypeNames, RecDict, VarDict) ->
+ {L, R} = list_from_form(Args, TypeNames, RecDict, VarDict),
+ {t_tuple(L), R};
+t_from_form({type, _L, union, Args}, TypeNames, RecDict, VarDict) ->
+ {L, R} = list_from_form(Args, TypeNames, RecDict, VarDict),
+ {t_sup(L), R};
+t_from_form({type, _L, Name, Args}, TypeNames, RecDict, VarDict) ->
case lookup_type(Name, RecDict) of
{type, {_Module, Type, ArgNames}} when length(Args) =:= length(ArgNames) ->
- List = lists:zipwith(fun(ArgName, ArgType) ->
- {ArgName, t_from_form(ArgType, RecDict, VarDict)}
- end, ArgNames, Args),
- TmpVardict = dict:from_list(List),
- t_from_form(Type, RecDict, TmpVardict);
+ case unfold({type, Name}, TypeNames) of
+ true ->
+ List = lists:zipwith(
+ fun(ArgName, ArgType) ->
+ {Ttemp, _R} = t_from_form(ArgType, TypeNames,
+ RecDict, VarDict),
+ {ArgName, Ttemp}
+ end,
+ ArgNames, Args),
+ TmpVarDict = dict:from_list(List),
+ {T, R} = t_from_form(Type, [{type, Name}|TypeNames], RecDict,
+ TmpVarDict),
+ case lists:member({type, Name}, R) of
+ true -> {t_limit(T, ?REC_TYPE_LIMIT), R};
+ false -> {T, R}
+ end;
+ false -> {t_any(), [{type, Name}]}
+ end;
{opaque, {Module, Type, ArgNames}} when length(Args) =:= length(ArgNames) ->
- List = lists:zipwith(fun(ArgName, ArgType) ->
- {ArgName, t_from_form(ArgType, RecDict, VarDict)}
- end, ArgNames, Args),
- TmpVardict = dict:from_list(List),
- Rep = t_from_form(Type, RecDict, TmpVardict),
- t_from_form({opaque, -1, Name, {Module, Args, Rep}}, RecDict, VarDict);
+ {Rep, Rret} =
+ case unfold({opaque, Name}, TypeNames) of
+ true ->
+ List = lists:zipwith(
+ fun(ArgName, ArgType) ->
+ {Ttemp, _R} = t_from_form(ArgType, TypeNames,
+ RecDict, VarDict),
+ {ArgName, Ttemp}
+ end,
+ ArgNames, Args),
+ TmpVarDict = dict:from_list(List),
+ {T, R} = t_from_form(Type, [{opaque, Name}|TypeNames], RecDict,
+ TmpVarDict),
+ case lists:member({opaque, Name}, R) of
+ true -> {t_limit(T, ?REC_TYPE_LIMIT), R};
+ false -> {T, R}
+ end;
+ false -> {t_any(), [{opaque, Name}]}
+ end,
+ Tret = t_from_form({opaque, -1, Name, {Module, Args, Rep}},
+ RecDict, VarDict),
+ {Tret, Rret};
{type, _} ->
throw({error, io_lib:format("Unknown type ~w\n", [Name])});
{opaque, _} ->
@@ -3361,48 +3578,70 @@ t_from_form({type, _L, Name, Args}, RecDict, VarDict) ->
error ->
throw({error, io_lib:format("Unable to find type ~w\n", [Name])})
end;
-t_from_form({opaque, _L, Name, {Mod, Args, Rep}}, _RecDict, _VarDict) ->
+t_from_form({opaque, _L, Name, {Mod, Args, Rep}}, _TypeNames, _RecDict,
+ _VarDict) ->
case Args of
- [] -> t_opaque(Mod, Name, Args, Rep);
+ [] -> {t_opaque(Mod, Name, Args, Rep), []};
_ -> throw({error, "Polymorphic opaque types not supported yet"})
end.
-record_from_form({atom, _, Name}, ModFields, RecDict, VarDict) ->
- case lookup_record(Name, RecDict) of
- {ok, DeclFields} ->
- case get_mod_record(ModFields, DeclFields, RecDict, VarDict) of
- {error, FieldName} ->
- throw({error, io_lib:format("Illegal declaration of ~w#{~w}\n",
- [Name, FieldName])});
- {ok, NewFields} ->
- t_tuple([t_atom(Name)|[Type || {_FieldName, Type} <- NewFields]])
+record_from_form({atom, _, Name}, ModFields, TypeNames, RecDict, VarDict) ->
+ case unfold({record, Name}, TypeNames) of
+ true ->
+ case lookup_record(Name, RecDict) of
+ {ok, DeclFields} ->
+ TypeNames1 = [{record, Name}|TypeNames],
+ AreTyped = [is_erl_type(FieldType)
+ || {_FieldName, FieldType} <- DeclFields],
+ {DeclFields1, R1} =
+ case lists:all(fun(Elem) -> Elem end, AreTyped) of
+ true -> {DeclFields, []};
+ false -> fields_from_form(DeclFields, TypeNames1,
+ RecDict, dict:new())
+ end,
+ {GetModRec, R2} = get_mod_record(ModFields, DeclFields1,
+ TypeNames1, RecDict, VarDict),
+ case GetModRec of
+ {error, FieldName} ->
+ throw({error, io_lib:format("Illegal declaration of ~w#{~w}\n",
+ [Name, FieldName])});
+ {ok, NewFields} ->
+ {t_tuple(
+ [t_atom(Name)|[Type || {_FieldName, Type} <- NewFields]]),
+ R1 ++ R2}
+ end;
+ error ->
+ throw({error, erlang:error(io_lib:format("Unknown record #~w{}\n",
+ [Name]))})
end;
- error ->
- throw({error,
- erlang:error(io_lib:format("Unknown record #~w{}\n", [Name]))})
+ false -> {t_any(), []}
end.
-get_mod_record([], DeclFields, _RecDict, _VarDict) ->
- {ok, DeclFields};
-get_mod_record(ModFields, DeclFields, RecDict, VarDict) ->
+get_mod_record([], DeclFields, _TypeNames, _RecDict, _VarDict) ->
+ {{ok, DeclFields}, []};
+get_mod_record(ModFields, DeclFields, TypeNames, RecDict, VarDict) ->
DeclFieldsDict = orddict:from_list(DeclFields),
- ModFieldsDict = build_field_dict(ModFields, RecDict, VarDict),
+ {ModFieldsDict, R} = build_field_dict(ModFields, TypeNames,
+ RecDict, VarDict),
case get_mod_record(DeclFieldsDict, ModFieldsDict, []) of
- {error, _FieldName} = Error -> Error;
+ {error, _FieldName} = Error -> {Error, R};
{ok, FinalOrdDict} ->
- {ok, [{FieldName, orddict:fetch(FieldName, FinalOrdDict)}
- || {FieldName, _} <- DeclFields]}
+ {{ok, [{FieldName, orddict:fetch(FieldName, FinalOrdDict)}
+ || {FieldName, _} <- DeclFields]},
+ R}
end.
-build_field_dict(FieldTypes, RecDict, VarDict) ->
- build_field_dict(FieldTypes, RecDict, VarDict, []).
+build_field_dict(FieldTypes, TypeNames, RecDict, VarDict) ->
+ build_field_dict(FieldTypes, TypeNames, RecDict, VarDict, []).
build_field_dict([{type, _, field_type, [{atom, _, Name}, Type]}|Left],
- RecDict, VarDict, Acc) ->
- NewAcc = [{Name, t_from_form(Type, RecDict, VarDict)}|Acc],
- build_field_dict(Left, RecDict, VarDict, NewAcc);
-build_field_dict([], _RecDict, _VarDict, Acc) ->
- orddict:from_list(Acc).
+ TypeNames, RecDict, VarDict, Acc) ->
+ {T, R1} = t_from_form(Type, TypeNames, RecDict, VarDict),
+ NewAcc = [{Name, T}|Acc],
+ {D, R2} = build_field_dict(Left, TypeNames, RecDict, VarDict, NewAcc),
+ {D, R1 ++ R2};
+build_field_dict([], _TypeNames, _RecDict, _VarDict, Acc) ->
+ {orddict:from_list(Acc), []}.
get_mod_record([{FieldName, DeclType}|Left1],
[{FieldName, ModType}|Left2], Acc) ->
@@ -3419,6 +3658,20 @@ get_mod_record(DeclFields, [], Acc) ->
get_mod_record(_, [{FieldName2, _ModType}|_], _Acc) ->
{error, FieldName2}.
+fields_from_form([], _TypeNames, _RecDict, _VarDict) ->
+ {[], []};
+fields_from_form([{Name, Type}|Tail], TypeNames, RecDict, VarDict) ->
+ {T, R1} = t_from_form(Type, TypeNames, RecDict, VarDict),
+ {F, R2} = fields_from_form(Tail, TypeNames, RecDict, VarDict),
+ {[{Name, T}|F], R1 ++ R2}.
+
+list_from_form([], _TypeNames, _RecDict, _VarDict) ->
+ {[], []};
+list_from_form([H|Tail], TypeNames, RecDict, VarDict) ->
+ {T, R1} = t_from_form(H, TypeNames, RecDict, VarDict),
+ {L, R2} = list_from_form(Tail, TypeNames, RecDict, VarDict),
+ {[T|L], R1 ++ R2}.
+
-spec t_form_to_string(parse_form()) -> string().
t_form_to_string({var, _L, '_'}) -> "_";
@@ -3510,11 +3763,19 @@ any_none_or_unit([?unit|_]) -> true;
any_none_or_unit([_|Left]) -> any_none_or_unit(Left);
any_none_or_unit([]) -> false.
--spec lookup_record(atom(), dict()) -> 'error' | {'ok', [{atom(), erl_type()}]}.
+is_erl_type(?any) -> true;
+is_erl_type(?none) -> true;
+is_erl_type(?unit) -> true;
+is_erl_type(#c{}) -> true;
+is_erl_type(_) -> false.
+
+-spec lookup_record(atom(), dict()) ->
+ 'error' | {'ok', [{atom(), parse_form() | erl_type()}]}.
lookup_record(Tag, RecDict) when is_atom(Tag) ->
case dict:find({record, Tag}, RecDict) of
- {ok, [{_Arity, Fields}]} -> {ok, Fields};
+ {ok, [{_Arity, Fields}]} ->
+ {ok, Fields};
{ok, List} when is_list(List) ->
%% This will have to do, since we do not know which record we
%% are looking for.
@@ -3547,6 +3808,9 @@ lookup_type(Name, RecDict) ->
type_is_defined(TypeOrOpaque, Name, RecDict) ->
dict:is_key({TypeOrOpaque, Name}, RecDict).
+unfold(TypeName, TypeNames) ->
+ not lists:member(TypeName, TypeNames).
+
%% -----------------------------------
%% Set
%%
diff --git a/lib/hipe/doc/Makefile b/lib/hipe/doc/Makefile
index 340f909aa6..cdf9c9c798 100644
--- a/lib/hipe/doc/Makefile
+++ b/lib/hipe/doc/Makefile
@@ -1,21 +1,28 @@
-# ``The contents of this file are subject to the Erlang Public License,
+#
+# %CopyrightBegin%
+#
+# Copyright Ericsson AB 2006-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 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.
-#
+#
+# %CopyrightEnd%
+#
SHELL=/bin/sh
include $(ERL_TOP)/make/target.mk
include $(ERL_TOP)/make/$(TARGET)/otp.mk
clean:
- -rm -f *.html edoc-info stylesheet.css
+ -rm -f *.html edoc-info stylesheet.css erlang.png
# ----------------------------------------------------
# Special Build Targets
diff --git a/lib/hipe/doc/src/Makefile b/lib/hipe/doc/src/Makefile
index 3b63e57549..d440178e4c 100644
--- a/lib/hipe/doc/src/Makefile
+++ b/lib/hipe/doc/src/Makefile
@@ -1,19 +1,20 @@
-# ``The contents of this file are subject to the Erlang Public License,
+#
+# %CopyrightBegin%
+#
+# Copyright Ericsson AB 2006-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 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%
#
include $(ERL_TOP)/make/target.mk
include $(ERL_TOP)/make/$(TARGET)/otp.mk
@@ -33,7 +34,7 @@ RELSYSDIR = $(RELEASE_PATH)/lib/$(APPLICATION)-$(VSN)
# ----------------------------------------------------
# Target Specs
# ----------------------------------------------------
-XML_APPLICATION_FILES =
+XML_APPLICATION_FILES = ref_man.xml
XML_REF3_FILES =
XML_PART_FILES = part_notes.xml
diff --git a/lib/hipe/doc/src/book.xml b/lib/hipe/doc/src/book.xml
index 236dfc69a1..9c95e3a827 100644
--- a/lib/hipe/doc/src/book.xml
+++ b/lib/hipe/doc/src/book.xml
@@ -4,7 +4,7 @@
<book xmlns:xi="http://www.w3.org/2001/XInclude">
<header titlestyle="normal">
<copyright>
- <year>2006</year><year>2009</year>
+ <year>2006</year><year>2010</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
@@ -13,12 +13,12 @@
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>HiPE</title>
@@ -31,6 +31,9 @@
<preamble>
</preamble>
<pagetext>HiPE</pagetext>
+ <applications>
+ <xi:include href="ref_man.xml"/>
+ </applications>
<releasenotes>
<xi:include href="notes.xml"/>
</releasenotes>
diff --git a/lib/hipe/doc/src/hipe_app.xml b/lib/hipe/doc/src/hipe_app.xml
new file mode 100644
index 0000000000..56729d4cc4
--- /dev/null
+++ b/lib/hipe/doc/src/hipe_app.xml
@@ -0,0 +1,58 @@
+<?xml version="1.0" encoding="latin1" ?>
+<!DOCTYPE appref SYSTEM "appref.dtd">
+
+<appref>
+ <header>
+ <copyright>
+ <year>1997</year><year>2010</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>snmp</title>
+ <prepared></prepared>
+ <responsible></responsible>
+ <docno></docno>
+ <approved></approved>
+ <checked></checked>
+ <date></date>
+ <rev></rev>
+ <file>hipe.xml</file>
+ </header>
+ <app>HiPE</app>
+ <appsummary>The HiPE Application</appsummary>
+ <description>
+ <p>
+ The normal way to native-compile an Erlang module using HiPE is to include the atom native
+ in the Erlang compiler options, as in:
+ <code>
+ 1> <input>c(my_module, [native]).</input></code>
+ Options to the HiPE compiler are then passed as follows:
+ <code>
+ 1> <input>c(my_module, [native,{hipe,Options}]).</input></code>
+ For on-line help in the Erlang shell, call <c>hipe:help()</c>.
+ Details on HiPE compiler options are given by <c>hipe:help_options()</c>.
+ </p>
+ </description>
+ <section>
+ <title>SEE ALSO</title>
+ <p>
+ <seealso marker="stdlib:c">c(3)</seealso>,
+ <seealso marker="compiler:compile">compile(3)</seealso>
+ </p>
+ </section>
+
+</appref>
+
diff --git a/lib/hipe/doc/src/notes.xml b/lib/hipe/doc/src/notes.xml
index 8bb9320756..2c78558190 100644
--- a/lib/hipe/doc/src/notes.xml
+++ b/lib/hipe/doc/src/notes.xml
@@ -4,7 +4,7 @@
<chapter>
<header>
<copyright>
- <year>2006</year><year>2009</year>
+ <year>2006</year><year>2010</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
@@ -13,12 +13,12 @@
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>HiPE Release Notes</title>
@@ -30,6 +30,37 @@
</header>
<p>This document describes the changes made to HiPE.</p>
+<section><title>Hipe 3.7.5</title>
+
+ <section><title>Improvements and New Features</title>
+ <list>
+ <item>
+ <p>The documentation is now possible to build in an open
+ source environment after a number of bugs are fixed and
+ some features are added in the documentation build
+ process. </p>
+ <p>- The arity calculation is updated.</p>
+ <p>- The module prefix used in the function names for
+ bif's are removed in the generated links so the links
+ will look like
+ "http://www.erlang.org/doc/man/erlang.html#append_element-2"
+ instead of
+ "http://www.erlang.org/doc/man/erlang.html#erlang:append_element-2".</p>
+ <p>- Enhanced the menu positioning in the html
+ documentation when a new page is loaded.</p>
+ <p>- A number of corrections in the generation of man
+ pages (thanks to Sergei Golovan)</p>
+ <p>- The legal notice is taken from the xml book file so
+ OTP's build process can be used for non OTP
+ applications.</p>
+ <p>
+ Own Id: OTP-8343</p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
<section><title>Hipe 3.7.4</title>
<section><title>Improvements and New Features</title>
diff --git a/lib/hipe/doc/src/ref_man.xml b/lib/hipe/doc/src/ref_man.xml
new file mode 100644
index 0000000000..09d10147ee
--- /dev/null
+++ b/lib/hipe/doc/src/ref_man.xml
@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="latin1" ?>
+<!DOCTYPE application SYSTEM "application.dtd">
+
+<application xmlns:xi="http://www.w3.org/2001/XInclude">
+ <header>
+ <copyright>
+ <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.
+
+ </legalnotice>
+
+ <title>HiPE</title>
+ <prepared></prepared>
+ <docno></docno>
+ <date>1997-06-04</date>
+ <rev>1.3.1</rev>
+ <file>ref_man.xml</file>
+ </header>
+ <description>
+ </description>
+ <xi:include href="hipe_app.xml"/>
+</application>
+
diff --git a/lib/hipe/flow/Makefile b/lib/hipe/flow/Makefile
index 5b9d0b7582..02f610587b 100644
--- a/lib/hipe/flow/Makefile
+++ b/lib/hipe/flow/Makefile
@@ -1,19 +1,19 @@
#
# %CopyrightBegin%
-#
-# Copyright Ericsson AB 2001-2009. All Rights Reserved.
-#
+#
+# Copyright Ericsson AB 2001-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%
#
@@ -73,7 +73,10 @@ ERL_COMPILE_FLAGS += +warn_exported_vars +warn_missing_spec +warn_untyped_record
debug opt: $(TARGET_FILES)
-docs: $(DOC_FILES)
+docs:
+
+# Moved docs target to edocs so the standard docs rule work properly.
+edocs: $(DOC_FILES)
clean:
rm -f $(TARGET_FILES)
@@ -102,4 +105,5 @@ release_spec: opt
release_docs_spec:
$(EBIN)/hipe_bb.beam: hipe_bb.hrl
+$(EBIN)/hipe_dominators.beam: cfg.hrl
$(EBIN)/hipe_gen_cfg.beam: cfg.hrl cfg.inc ../main/hipe.hrl
diff --git a/lib/hipe/icode/Makefile b/lib/hipe/icode/Makefile
index de37c4e4c4..eced90b0ec 100644
--- a/lib/hipe/icode/Makefile
+++ b/lib/hipe/icode/Makefile
@@ -1,19 +1,19 @@
#
# %CopyrightBegin%
-#
-# Copyright Ericsson AB 2001-2009. All Rights Reserved.
-#
+#
+# Copyright Ericsson AB 2001-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%
#
@@ -91,7 +91,10 @@ ERL_COMPILE_FLAGS += +warn_unused_import +warn_missing_spec +warn_untyped_record
debug opt: $(TARGET_FILES)
-docs: $(DOC_FILES)
+docs:
+
+# Moved docs target to edocs so the standard docs rule work properly.
+edocs: $(DOC_FILES)
clean:
rm -f $(TARGET_FILES)
diff --git a/lib/hipe/info b/lib/hipe/info
index 51b5dfb979..fe08fc8990 100644
--- a/lib/hipe/info
+++ b/lib/hipe/info
@@ -1,2 +1,2 @@
-group: basic
+group: misc Miscellaneous Applications
short: High Performance Erlang \ No newline at end of file
diff --git a/lib/hipe/main/Makefile b/lib/hipe/main/Makefile
index 0ac522b1b2..a14c9c3ca4 100644
--- a/lib/hipe/main/Makefile
+++ b/lib/hipe/main/Makefile
@@ -1,19 +1,19 @@
#
# %CopyrightBegin%
-#
-# Copyright Ericsson AB 2001-2009. All Rights Reserved.
-#
+#
+# Copyright Ericsson AB 2001-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%
#
@@ -83,7 +83,11 @@ $(EBIN)/hipe_main.beam: hipe.hrl ../icode/hipe_icode.hrl #../rtl/hipe_rtl.hrl
debug opt: $(TARGET_FILES)
-docs: $(DOC_FILES)
+docs:
+
+# Moved docs target to edocs so the standard docs rule work properly.
+
+edocs: $(DOC_FILES)
clean:
rm -f $(TARGET_FILES) $(DOC_FILES) $(HRL_FILES)
diff --git a/lib/hipe/misc/Makefile b/lib/hipe/misc/Makefile
index d5c395855a..98a69d62c7 100644
--- a/lib/hipe/misc/Makefile
+++ b/lib/hipe/misc/Makefile
@@ -1,19 +1,19 @@
#
# %CopyrightBegin%
-#
-# Copyright Ericsson AB 2001-2009. All Rights Reserved.
-#
+#
+# Copyright Ericsson AB 2001-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%
#
@@ -76,7 +76,10 @@ ERL_COMPILE_FLAGS += +warn_exported_vars +warn_missing_spec +warn_untyped_record
debug opt: $(TARGET_FILES)
-docs: $(DOC_FILES)
+docs:
+
+# Moved docs target to edocs so the standard docs rule work properly.
+edocs: $(DOC_FILES)
clean:
rm -f $(TARGET_FILES)
diff --git a/lib/hipe/opt/Makefile b/lib/hipe/opt/Makefile
index 972cf63944..74fde26c0b 100644
--- a/lib/hipe/opt/Makefile
+++ b/lib/hipe/opt/Makefile
@@ -1,19 +1,19 @@
#
# %CopyrightBegin%
-#
-# Copyright Ericsson AB 2001-2009. All Rights Reserved.
-#
+#
+# Copyright Ericsson AB 2001-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%
#
@@ -71,7 +71,10 @@ ERL_COMPILE_FLAGS += +warn_exported_vars +warn_missing_spec +warn_untyped_record
debug opt: $(TARGET_FILES)
-docs: $(DOC_FILES)
+docs:
+
+# Moved docs target to edocs so the standard docs rule work properly.
+edocs: $(DOC_FILES)
clean:
rm -f $(TARGET_FILES)
diff --git a/lib/hipe/ppc/Makefile b/lib/hipe/ppc/Makefile
index 0857043527..f24139e34b 100644
--- a/lib/hipe/ppc/Makefile
+++ b/lib/hipe/ppc/Makefile
@@ -1,19 +1,19 @@
#
# %CopyrightBegin%
-#
-# Copyright Ericsson AB 2004-2009. All Rights Reserved.
-#
+#
+# Copyright Ericsson AB 2004-2010. All Rights Reserved.
+#
# The contents of this file are subject to the Erlang Public License,
# Version 1.1, (the "License"); you may not use this file except in
# compliance with the License. You should have received a copy of the
# Erlang Public License along with this software. If not, it can be
# retrieved online at http://www.erlang.org/.
-#
+#
# Software distributed under the License is distributed on an "AS IS"
# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
# the License for the specific language governing rights and limitations
# under the License.
-#
+#
# %CopyrightEnd%
#
@@ -83,7 +83,10 @@ ERL_COMPILE_FLAGS += +warn_exported_vars
debug opt: $(TARGET_FILES)
-docs: $(DOC_FILES)
+docs:
+
+# Moved docs target to edocs so the standard docs rule work properly.
+edocs: $(DOC_FILES)
clean:
rm -f $(TARGET_FILES)
diff --git a/lib/hipe/regalloc/Makefile b/lib/hipe/regalloc/Makefile
index 5ab70d1837..386f3589c6 100644
--- a/lib/hipe/regalloc/Makefile
+++ b/lib/hipe/regalloc/Makefile
@@ -1,19 +1,19 @@
#
# %CopyrightBegin%
-#
-# Copyright Ericsson AB 2001-2009. All Rights Reserved.
-#
+#
+# Copyright Ericsson AB 2001-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%
#
@@ -84,7 +84,11 @@ ERL_COMPILE_FLAGS += +warn_exported_vars# +warn_missing_spec +warn_untyped_recor
debug opt: $(TARGET_FILES)
-docs: $(DOC_FILES)
+docs:
+
+# Moved docs target to edocs so the standard docs rule work properly.
+
+edocs: $(DOC_FILES)
clean:
rm -f $(TARGET_FILES)
diff --git a/lib/hipe/rtl/Makefile b/lib/hipe/rtl/Makefile
index beab8da547..55d20af8af 100644
--- a/lib/hipe/rtl/Makefile
+++ b/lib/hipe/rtl/Makefile
@@ -1,19 +1,19 @@
#
# %CopyrightBegin%
-#
-# Copyright Ericsson AB 2001-2009. All Rights Reserved.
-#
+#
+# Copyright Ericsson AB 2001-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%
#
@@ -113,8 +113,11 @@ HIPE_MKLITERALS=$(ERL_TOP)/bin/$(TARGET)/hipe_mkliterals
hipe_literals.hrl: $(HIPE_MKLITERALS)
$(HIPE_MKLITERALS) -e > hipe_literals.hrl
+# Need to generate hipe.hrl from one and only one target in one and only
+# one makefile; otherwise, clearmake will force rebuilds of hipe over and
+# over again.
../main/hipe.hrl: ../vsn.mk ../main/hipe.hrl.src
- sed -e "s;%VSN%;$(HIPE_VSN);" ../main/hipe.hrl.src > ../main/hipe.hrl
+ (cd ../main && $(MAKE) hipe.hrl)
$(EBIN)/hipe_rtl.beam: hipe_rtl.hrl ../main/hipe.hrl
$(EBIN)/hipe_rtl_arch.beam: hipe_rtl.hrl hipe_literals.hrl
diff --git a/lib/hipe/sparc/Makefile b/lib/hipe/sparc/Makefile
index efd4996046..f25212a89b 100644
--- a/lib/hipe/sparc/Makefile
+++ b/lib/hipe/sparc/Makefile
@@ -1,19 +1,19 @@
#
# %CopyrightBegin%
-#
-# Copyright Ericsson AB 2001-2009. All Rights Reserved.
-#
+#
+# Copyright Ericsson AB 2001-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%
#
@@ -83,7 +83,10 @@ ERL_COMPILE_FLAGS += +warn_exported_vars
debug opt: $(TARGET_FILES)
-docs: $(DOC_FILES)
+docs:
+
+# Moved docs target to edocs so the standard docs rule work properly.
+edocs: $(DOC_FILES)
clean:
rm -f $(TARGET_FILES)
diff --git a/lib/hipe/tools/Makefile b/lib/hipe/tools/Makefile
index 6ce5cb1b8b..0eaa3a7b05 100644
--- a/lib/hipe/tools/Makefile
+++ b/lib/hipe/tools/Makefile
@@ -1,19 +1,19 @@
#
# %CopyrightBegin%
-#
-# Copyright Ericsson AB 2002-2009. All Rights Reserved.
-#
+#
+# Copyright Ericsson AB 2002-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%
#
@@ -72,7 +72,10 @@ ERL_COMPILE_FLAGS += +warn_exported_vars +warn_missing_spec +warn_untyped_record
debug opt: $(TARGET_FILES)
-docs: $(DOC_FILES)
+docs:
+
+# Moved docs target to edocs so the standard docs rule work properly.
+edocs: $(DOC_FILES)
clean:
rm -f $(TARGET_FILES)
diff --git a/lib/hipe/tools/hipe_tool.erl b/lib/hipe/tools/hipe_tool.erl
index ae1cad06cc..a1bd79895d 100644
--- a/lib/hipe/tools/hipe_tool.erl
+++ b/lib/hipe/tools/hipe_tool.erl
@@ -1,20 +1,20 @@
%% -*- erlang-indent-level: 2 -*-
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2002-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 2002-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%
%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
@@ -506,8 +506,8 @@ get_edoc(Mod) ->
ok.
edoc(Name, Opts) ->
- Doc = edoc:get_doc([Name, Opts]),
+ Doc = edoc:get_doc(Name, Opts),
%% Comments = edoc:read_comments(Name, Opts),
%% Text = edoc:forms(Forms, Comments, Name, Opts),
- edoc:layout([Doc, Opts]),
+ edoc:layout(Doc, Opts),
ok.
diff --git a/lib/hipe/util/Makefile b/lib/hipe/util/Makefile
index 27cacedf11..85719ec3d6 100644
--- a/lib/hipe/util/Makefile
+++ b/lib/hipe/util/Makefile
@@ -1,19 +1,19 @@
#
# %CopyrightBegin%
-#
-# Copyright Ericsson AB 2001-2009. All Rights Reserved.
-#
+#
+# Copyright Ericsson AB 2001-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%
#
@@ -76,7 +76,10 @@ ERL_COMPILE_FLAGS += +warn_exported_vars +warn_missing_spec +warn_untyped_record
debug opt: $(TARGET_FILES)
-docs: $(DOC_FILES)
+docs:
+
+# Moved docs target to edocs so the standard docs rule work properly.
+edocs: $(DOC_FILES)
clean:
rm -f $(TARGET_FILES)
diff --git a/lib/hipe/vsn.mk b/lib/hipe/vsn.mk
index c75ac5efe7..129718a305 100644
--- a/lib/hipe/vsn.mk
+++ b/lib/hipe/vsn.mk
@@ -1 +1 @@
-HIPE_VSN = 3.7.4
+HIPE_VSN = 3.7.5
diff --git a/lib/hipe/x86/Makefile b/lib/hipe/x86/Makefile
index 065b56fce3..d7d0c7bf5a 100644
--- a/lib/hipe/x86/Makefile
+++ b/lib/hipe/x86/Makefile
@@ -1,19 +1,19 @@
#
# %CopyrightBegin%
-#
-# Copyright Ericsson AB 2001-2009. All Rights Reserved.
-#
+#
+# Copyright Ericsson AB 2001-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%
#
@@ -91,7 +91,10 @@ ERL_COMPILE_FLAGS += +warn_exported_vars
debug opt: $(TARGET_FILES)
-docs: $(DOC_FILES)
+docs:
+
+# Moved docs target to edocs so the standard docs rule work properly.
+edocs: $(DOC_FILES)
clean:
rm -f $(TARGET_FILES)
diff --git a/lib/ic/doc/src/Makefile b/lib/ic/doc/src/Makefile
index fff930d745..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 \
@@ -169,6 +172,7 @@ JD_GIF_FILES = \
PACK_DIR = com/ericsson/otp/ic
JAVA_SOURCE_DIR = ../../java_src/$(PACK_DIR)
+JAVA_OUT_DIR = ../html/java
JD_PACK_HTML_FILES = \
package-frame.html \
@@ -176,10 +180,10 @@ JD_PACK_HTML_FILES = \
package-tree.html
JAVADOC_PACK_HTML_FILES = \
- $(JAVA_SOURCE_FILES:%.java=../html/java/$(PACK_DIR)/%.html) \
- $(JD_PACK_HTML_FILES:%=../html/java/$(PACK_DIR)/%)
+ $(JAVA_SOURCE_FILES:%.java=$(JAVA_OUT_DIR)/$(PACK_DIR)/%.html) \
+ $(JD_PACK_HTML_FILES:%=$(JAVA_OUT_DIR)/$(PACK_DIR)/%)
-JAVADOC_INDEX_HTML_FILES = $(JD_INDEX_HTML_FILES:%=../html/java/%)
+JAVADOC_INDEX_HTML_FILES = $(JD_INDEX_HTML_FILES:%=$(JAVA_OUT_DIR)/%)
JAVADOC_GENERATED_FILES = $(JAVADOC_PACK_HTML_FILES) $(JAVADOC_INDEX_HTML_FILES)
@@ -244,11 +248,14 @@ clean clean_docs clean_tex:
rm -f $(HTML_FILES) $(MAN3_FILES)
rm -f $(TOP_PDF_FILE) $(TOP_PS_FILE)
rm -f errs core *~ *xmls_output *xmls_errs $(LATEX_CLEAN)
- rm -rf ../html/java/*
+ rm -rf $(JAVA_OUT_DIR)
endif
-$(JAVADOC_GENERATED_FILES):
+$(JAVA_OUT_DIR):
+ mkdir $(JAVA_OUT_DIR)
+
+$(JAVADOC_GENERATED_FILES): $(JAVA_OUT_DIR)
@(cd ../../java_src; $(JAVADOC) $(JAVADOCFLAGS) com.ericsson.otp.ic)
man: $(MAN3_FILES)
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.xml b/lib/ic/doc/src/ic.xml
index 9f48229425..b743736a66 100644
--- a/lib/ic/doc/src/ic.xml
+++ b/lib/ic/doc/src/ic.xml
@@ -4,23 +4,21 @@
<erlref>
<header>
<copyright>
- <year>1997</year>
- <year>2007</year>
- <holder>Ericsson AB, All Rights Reserved</holder>
+ <year>1997</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</title>
@@ -64,7 +62,7 @@
<v>timeout | {timeout, String()} | {{timeout, String()}, bool()} |</v>
<v>{scoped_op_calls, bool()} | {scl, bool()} |</v>
<v>{user_protocol, Prefix} |</v>
- <v>{c_timeout, SendTimeout, RecvTimeout} |</v>
+ <v>{c_timeout, {SendTimeout, RecvTimeout}} |</v>
<v>{c_report, bool()} |</v>
<v>{precond, {atom(), atom()}} | {{precond, String()} {atom(), atom()}} |</v>
<v>{postcond, {atom(), atom()}} | {{postcond, String()} {atom(), atom()}}</v>
@@ -264,7 +262,7 @@ The option
<p>Makes sends and receives to have timeouts (C back-ends only). These
timeouts are specified in milliseconds. </p>
<p>Example options:
- <c>[{be,c_client},{c_timeout, 10000, 20000}])</c> produces
+ <c>[{be,c_client},{c_timeout, {10000, 20000}}])</c> produces
client stubs which use a 10 seconds send timeout, and a
20 seconds receive timeout.</p>
</item>
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 c4314d8cc1..45ba233051 100644
--- a/lib/ic/doc/src/notes.xml
+++ b/lib/ic/doc/src/notes.xml
@@ -4,7 +4,7 @@
<chapter>
<header>
<copyright>
- <year>1998</year><year>2009</year>
+ <year>1998</year><year>2010</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
@@ -31,6 +31,68 @@
</header>
<section>
+ <title>IC 4.2.26</title>
+
+ <section>
+ <title>Improvements and New Features</title>
+ <list type="bulleted">
+ <item>
+ <p>
+ Partial support for recursive structs and unions. Only available
+ for the erl_corba backend and requires that Light IFR is used.
+ I.e. the IC option {light_ifr, true} and that Orber is configured
+ in such a way that Light IFR is activated. Recursive TypeCode is
+ currently not supported.</p>
+ <p>
+ Own Id: OTP-8868 Aux Id: seq11633</p>
+ </item>
+ </list>
+ </section>
+ </section>
+
+ <section>
+ <title>IC 4.2.25</title>
+
+ <section>
+ <title>Improvements and New Features</title>
+ <list type="bulleted">
+ <item>
+ <p>
+ The documentation can now be built and installed without Java.</p>
+ <p>
+ Own Id: OTP-8639 Aux Id:</p>
+ </item>
+ </list>
+ </section>
+ </section>
+
+ <section>
+ <title>IC 4.2.24</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 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>
+
+ <section>
<title>IC 4.2.23</title>
<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/src/ic_forms.erl b/lib/ic/src/ic_forms.erl
index 7409ddeb7b..fc46a2ed40 100644
--- a/lib/ic/src/ic_forms.erl
+++ b/lib/ic/src/ic_forms.erl
@@ -1,7 +1,7 @@
%%
%% %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
@@ -65,6 +65,7 @@ get_line(X) when is_record(X, scoped_id) -> X#scoped_id.line;
get_line(X) when is_record(X, module) -> get_line(X#module.id);
get_line(X) when is_record(X, interface) -> get_line(X#interface.id);
get_line(X) when is_record(X, forward) -> get_line(X#forward.id);
+get_line(X) when is_record(X, constr_forward) -> get_line(X#constr_forward.id);
get_line(X) when is_record(X, const) -> get_line(X#const.id);
get_line(X) when is_record(X, typedef) -> get_line(X#typedef.id);
get_line(X) when is_record(X, struct) -> get_line(X#struct.id);
@@ -114,6 +115,7 @@ get_line(_) -> -1.
get_id2(X) when is_record(X, module) -> get_id(X#module.id);
get_id2(X) when is_record(X, interface) -> get_id(X#interface.id);
get_id2(X) when is_record(X, forward) -> get_id(X#forward.id);
+get_id2(X) when is_record(X, constr_forward) -> get_id(X#constr_forward.id);
get_id2(X) when is_record(X, const) -> get_id(X#const.id);
get_id2(X) when is_record(X, typedef) -> get_id(hd(X#typedef.id));
get_id2(X) when is_record(X, struct) -> get_id(X#struct.id);
@@ -156,6 +158,7 @@ get_type(X) when is_record(X, param) -> X#param.type.
%% Temporary place
get_tk(X) when is_record(X, interface) -> X#interface.tk;
get_tk(X) when is_record(X, forward) -> X#forward.tk;
+get_tk(X) when is_record(X, constr_forward) -> X#constr_forward.tk;
get_tk(X) when is_record(X, const) -> X#const.tk;
get_tk(X) when is_record(X, type_dcl) -> X#type_dcl.tk;
get_tk(X) when is_record(X, typedef) -> X#typedef.tk;
@@ -228,6 +231,7 @@ clean_up_scope([N|Ns],Found) ->
get_type_code2(_, _, X) when is_record(X, interface) -> X#interface.tk;
get_type_code2(_, _, X) when is_record(X, forward) -> X#forward.tk;
+get_type_code2(_, _, X) when is_record(X, constr_forward) -> X#constr_forward.tk;
get_type_code2(_, _, X) when is_record(X, const) -> X#const.tk;
get_type_code2(_, _, X) when is_record(X, type_dcl) -> X#type_dcl.tk;
get_type_code2(_, _, X) when is_record(X, typedef) ->
diff --git a/lib/ic/src/ic_pragma.erl b/lib/ic/src/ic_pragma.erl
index 9165e3b03b..45cb64c9c8 100644
--- a/lib/ic/src/ic_pragma.erl
+++ b/lib/ic/src/ic_pragma.erl
@@ -1,7 +1,7 @@
%%
%% %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
@@ -60,7 +60,7 @@ pragma_reg(G,X) ->
init_pragma_status(S),
registerOptions(G,S),
pragma_reg_all(G, S, [], X),
- denote_specific_code_opts(G), %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+ denote_specific_code_opts(G),
case get_pragma_compilation_status(S) of
true ->
%% Remove ugly pragmas from form
@@ -132,6 +132,7 @@ applyCodeOpt(G) ->
%% This removes all pragma records from the form.
%% When debugged, it can be enbodied in pragma_reg_all.
+cleanup(undefined,C) -> C;
cleanup([],C) -> C;
cleanup([X|Xs],CSF) ->
cleanup(Xs, CSF++cleanup(X)).
@@ -279,7 +280,12 @@ pragma_reg(G, S, N, X) when is_record(X, union) ->
pragma_reg(G, S, N, X) when is_record(X, struct) ->
mk_ref(G,[get_id2(X) | N],struct_ref),
mk_file_data(G,X,N,struct),
- pragma_reg_all(G, S, N, X#struct.body);
+ case X#struct.body of
+ undefined ->
+ ok;
+ _ ->
+ pragma_reg_all(G, S, N, X#struct.body)
+ end;
pragma_reg(G, _S, N, X) when is_record(X, attr) ->
XX = #id_of{type=X},
diff --git a/lib/ic/src/ic_symtab.erl b/lib/ic/src/ic_symtab.erl
index 889c75e3a2..d710154a5d 100644
--- a/lib/ic/src/ic_symtab.erl
+++ b/lib/ic/src/ic_symtab.erl
@@ -1,7 +1,7 @@
%%
%% %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
@@ -69,6 +69,8 @@ store(G, N, X) ->
ets:insert(G#genobj.symtab, {Name, X});
{ok, Y} when is_record(Y, forward) ->
ets:insert(G#genobj.symtab, {Name, X});
+ {ok, Y} when is_record(Y, constr_forward) ->
+ ets:insert(G#genobj.symtab, {Name, X});
{ok, _Y} ->
ic_error:error(G, {multiply_defined, X})
end.
diff --git a/lib/ic/src/icforms.hrl b/lib/ic/src/icforms.hrl
index d1869e6330..1b394a11b4 100644
--- a/lib/ic/src/icforms.hrl
+++ b/lib/ic/src/icforms.hrl
@@ -1,7 +1,7 @@
%%
%% %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
@@ -34,6 +34,7 @@
-record(module, {id, body}).
-record(interface, {id, inherit, body, inherit_body, tk}).
-record(forward, {id, tk}).
+-record(constr_forward, {id, tk}).
-record(const, {type, id, val, tk}).
-record(type_dcl, {type, tk}).
-record(typedef, {type, id, tk}).
diff --git a/lib/ic/src/icparse.yrl b/lib/ic/src/icparse.yrl
index 25b0f452e7..d0dd6cde4c 100644
--- a/lib/ic/src/icparse.yrl
+++ b/lib/ic/src/icparse.yrl
@@ -1,21 +1,20 @@
-%%<copyright>
-%% <year>1997-2007</year>
-%% <holder>Ericsson AB, All Rights Reserved</holder>
-%%</copyright>
-%%<legalnotice>
+%%
+%% %CopyrightBegin%
+%%
+%% 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.
-%%
-%% The Initial Developer of the Original Code is Ericsson AB.
-%%</legalnotice>
+%%
+%% %CopyrightEnd%
%%
%%------------------------------------------------------------
%% Yecc spec for IDL
@@ -150,6 +149,7 @@ Nonterminals
'ZorM_<integer_literal>'
'<fixed_pt_type>'
'<fixed_pt_const_type>'
+ '<constr_forward_decl>'
.
@@ -473,6 +473,7 @@ OE_preproc -> '#' '<integer_literal>' '<string_literal>'
'<type_dcl>' -> '<struct_type>' : '$1' .
'<type_dcl>' -> '<union_type>' : '$1' .
'<type_dcl>' -> '<enum_type>' : '$1' .
+'<type_dcl>' -> '<constr_forward_decl>' : '$1' .
%% (28) NIY multiple declarators (FIXED)
'<type_declarator>' -> '<type_spec>' '<declarators>'
@@ -832,6 +833,9 @@ OE_preproc -> '#' '<integer_literal>' '<string_literal>'
'<fixed_pt_type>' -> 'fixed' '<' '<positive_int_const>' ',' '<positive_int_const>' '>'
: #fixed{digits='$3',scale='$5'} .
+%% (99)
+'<constr_forward_decl>' -> 'struct' '<identifier>' : #constr_forward{id='$2', tk=tk_struct} .
+'<constr_forward_decl>' -> 'union' '<identifier>' : #constr_forward{id='$2', tk=tk_union} .
%% Added clause
'ZorM_<string_literal>' -> '$empty' : [] .
diff --git a/lib/ic/src/ictype.erl b/lib/ic/src/ictype.erl
index 4704191bee..9e20801464 100644
--- a/lib/ic/src/ictype.erl
+++ b/lib/ic/src/ictype.erl
@@ -1,7 +1,7 @@
%%
%% %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
@@ -407,6 +407,18 @@ check(G, S, N, X) when is_record(X, forward) ->
tktab_add(G, S, N, X, {tk_objref, ictk:get_IR_ID(G, N, X), ic_forms:get_id2(X)}),
X;
+check(G, S, N, #constr_forward{tk = tk_struct} = X) ->
+ ?STDDBG,
+ ID = ic_forms:get_id2(X),
+ Module = list_to_atom(string:join(lists:reverse([ID|N]), "_")),
+ tktab_add(G, S, N, X, {tk_struct, ictk:get_IR_ID(G, N, X), ID, Module}),
+ X;
+check(G, S, N, #constr_forward{tk = tk_union} = X) ->
+ ?STDDBG,
+ ID = ic_forms:get_id2(X),
+ Module = list_to_atom(string:join(lists:reverse([ID|N]), "_")),
+ tktab_add(G, S, N, X, {tk_union, ictk:get_IR_ID(G, N, X), ID, [], [], Module}),
+ X;
check(G, S, N, X) when is_record(X, const) ->
?STDDBG,
@@ -427,21 +439,6 @@ check(G, S, N, X) when is_record(X, const) ->
end
end;
-check(G, S, N, X) when is_record(X, const) ->
- ?STDDBG,
- case tk_base(G, S, N, ic_forms:get_type(X)) of
- Err when element(1, Err) == error -> X;
- TK ->
- check_const_tk(G, S, N, X, TK),
- case iceval:eval_const(G, S, N, TK, X#const.val) of
- Err when element(1, Err) == error -> X;
- Val ->
- V = iceval:get_val(Val),
- tktab_add(G, S, N, X, TK, V),
- X#const{val=V, tk=TK}
- end
- end;
-
check(G, S, N, X) when is_record(X, except) ->
?STDDBG,
TK = tk(G, S, N, X),
@@ -795,9 +792,15 @@ tktab_add_id(G, S, N, X, Id, TK, Aux) ->
Name = [Id | N],
UName = mk_uppercase(Name),
case ets:lookup(S, Name) of
- [{_, forward, _, _}] when is_record(X, interface) -> ok;
- [XX] when is_record(X, forward) andalso element(2, XX)==interface -> ok;
- [_] -> ic_error:error(G, {multiply_defined, X});
+ [{_, forward, _, _}] when is_record(X, interface) ->
+ ok;
+ [{_, constr_forward, _, _}] when is_record(X, union) orelse
+ is_record(X, struct) ->
+ ok;
+ [XX] when is_record(X, forward) andalso element(2, XX)==interface ->
+ ok;
+ [_] ->
+ ic_error:error(G, {multiply_defined, X});
[] ->
case ets:lookup(S, UName) of
[] -> ok;
diff --git a/lib/ic/test/Makefile b/lib/ic/test/Makefile
new file mode 100644
index 0000000000..1142159d19
--- /dev/null
+++ b/lib/ic/test/Makefile
@@ -0,0 +1,277 @@
+#
+# %CopyrightBegin%
+#
+# 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%
+#
+#
+include $(ERL_TOP)/make/target.mk
+include $(ERL_TOP)/make/$(TARGET)/otp.mk
+
+# ----------------------------------------------------
+# Application version
+# ----------------------------------------------------
+include ../vsn.mk
+VSN=$(IC_VSN)
+# ----------------------------------------------------
+# Release directory specification
+# ----------------------------------------------------
+RELSYSDIR = $(RELEASE_PATH)/ic_test
+
+# ----------------------------------------------------
+# Target Specs
+# ----------------------------------------------------
+TEST_SPEC_FILE = ic.spec ic.spec.vxworks
+
+
+IDL_FILES =
+
+COMPILER_TEST_FILES = \
+ ic_SUITE_data/Corba.idl \
+ ic_SUITE_data/Coss.idl \
+ ic_SUITE_data/attr.idl \
+ ic_SUITE_data/c_err1.idl \
+ ic_SUITE_data/c_err2.idl \
+ ic_SUITE_data/c_err3.idl \
+ ic_SUITE_data/c_norm.idl \
+ ic_SUITE_data/enum.idl \
+ ic_SUITE_data/forward.idl \
+ ic_SUITE_data/include.idl \
+ ic_SUITE_data/include2.idl \
+ ic_SUITE_data/include3.idl \
+ ic_SUITE_data/inherit.idl \
+ ic_SUITE_data/inherit_err.idl \
+ ic_SUITE_data/inherit_warn.idl \
+ ic_SUITE_data/mult_ids.idl \
+ ic_SUITE_data/nasty.idl \
+ ic_SUITE_data/one.idl \
+ ic_SUITE_data/one_out.idl \
+ ic_SUITE_data/one_raises.idl \
+ ic_SUITE_data/one_followed.idl \
+ ic_SUITE_data/one_void.idl \
+ ic_SUITE_data/raises_reg.idl \
+ ic_SUITE_data/struct.idl \
+ ic_SUITE_data/syntax1.idl \
+ ic_SUITE_data/syntax2.idl \
+ ic_SUITE_data/syntax3.idl \
+ ic_SUITE_data/syntax4.idl \
+ ic_SUITE_data/syntax5.idl \
+ ic_SUITE_data/syntax6.idl \
+ ic_SUITE_data/type.idl \
+ ic_SUITE_data/typeid.idl \
+ ic_SUITE_data/u_case_mult.idl \
+ ic_SUITE_data/u_mult.idl \
+ ic_SUITE_data/u_norm.idl \
+ ic_SUITE_data/u_type.idl \
+ ic_SUITE_data/u_default.idl \
+ ic_SUITE_data/undef_id.idl
+
+
+COMPILER_TEST_FILES2 = \
+ ic_register_SUITE_data/reg_m8.idl \
+ ic_register_SUITE_data/reg_m9.idl \
+ ic_register_SUITE_data/reg_m10.idl \
+ ic_register_SUITE_data/reg_m11.idl \
+ ic_register_SUITE_data/reg_m12.idl
+
+
+COMPILER_TEST_FILES3 = \
+ ic_pragma_SUITE_data/reg_m0.idl \
+ ic_pragma_SUITE_data/reg_m1.idl \
+ ic_pragma_SUITE_data/reg_m2.idl \
+ ic_pragma_SUITE_data/reg_m3.idl \
+ ic_pragma_SUITE_data/reg_m4.idl \
+ ic_pragma_SUITE_data/reg_m5.idl \
+ ic_pragma_SUITE_data/reg_m6.idl \
+ ic_pragma_SUITE_data/reg_m7.idl \
+ ic_pragma_SUITE_data/uggly.idl
+
+
+COMPILER_TEST_FILES4 = \
+ ic_be_SUITE_data/plain.idl
+
+
+PREPROCESSOR_TEST_FILES = \
+ ic_pp_SUITE_data/arg.idl \
+ ic_pp_SUITE_data/cascade.idl \
+ ic_pp_SUITE_data/comment.idl \
+ ic_pp_SUITE_data/concat.idl \
+ ic_pp_SUITE_data/define.idl \
+ ic_pp_SUITE_data/if.idl \
+ ic_pp_SUITE_data/if_zero.idl \
+ ic_pp_SUITE_data/improp_nest_constr.idl \
+ ic_pp_SUITE_data/inc.idl \
+ ic_pp_SUITE_data/line.idl \
+ ic_pp_SUITE_data/misc.idl \
+ ic_pp_SUITE_data/nopara.idl \
+ ic_pp_SUITE_data/predef.idl \
+ ic_pp_SUITE_data/predef_time.idl \
+ ic_pp_SUITE_data/self_ref.idl \
+ ic_pp_SUITE_data/separate.idl \
+ ic_pp_SUITE_data/swallow_sc.idl \
+ ic_pp_SUITE_data/unintended_grp.idl
+
+C_CLIENT_ERL_SERVER_TEST_FILES = \
+ c_client_erl_server_SUITE_data/Makefile.src \
+ c_client_erl_server_SUITE_data/c_erl_test.idl \
+ c_client_erl_server_SUITE_data/c_client.c \
+ c_client_erl_server_SUITE_data/m_i_impl.erl
+
+C_CLIENT_ERL_SERVER_PROTO_TEST_FILES = \
+ c_client_erl_server_proto_SUITE_data/Makefile.src \
+ c_client_erl_server_proto_SUITE_data/c_erl_test.idl \
+ c_client_erl_server_proto_SUITE_data/c_client.c \
+ c_client_erl_server_proto_SUITE_data/my.c \
+ c_client_erl_server_proto_SUITE_data/m_i_impl.erl
+
+C_CLIENT_ERL_SERVER_PROTO_TMO_TEST_FILES = \
+ c_client_erl_server_proto_tmo_SUITE_data/Makefile.src \
+ c_client_erl_server_proto_tmo_SUITE_data/c_erl_test.idl \
+ c_client_erl_server_proto_tmo_SUITE_data/c_client.c \
+ c_client_erl_server_proto_tmo_SUITE_data/my.c \
+ c_client_erl_server_proto_tmo_SUITE_data/m_i_impl.erl
+
+ERL_CLIENT_C_SERVER_TEST_FILES = \
+ erl_client_c_server_SUITE_data/Makefile.src \
+ erl_client_c_server_SUITE_data/erl_c_test.idl \
+ erl_client_c_server_SUITE_data/erl_client.erl \
+ erl_client_c_server_SUITE_data/c_server.c \
+ erl_client_c_server_SUITE_data/callbacks.c
+
+ERL_CLIENT_C_SERVER_PROTO_TEST_FILES = \
+ erl_client_c_server_proto_SUITE_data/Makefile.src \
+ erl_client_c_server_proto_SUITE_data/erl_c_test.idl \
+ erl_client_c_server_proto_SUITE_data/erl_client.erl \
+ erl_client_c_server_proto_SUITE_data/c_server.c \
+ erl_client_c_server_proto_SUITE_data/callbacks.c
+
+JAVA_CLIENT_ERL_SERVER_TEST_FILES = \
+ java_client_erl_server_SUITE_data/Makefile.src \
+ java_client_erl_server_SUITE_data/java_erl_test.idl \
+ java_client_erl_server_SUITE_data/JavaClient.java \
+ java_client_erl_server_SUITE_data/m_i_impl.erl
+
+MODULES = \
+ ic_SUITE \
+ ic_register_SUITE \
+ ic_pragma_SUITE \
+ ic_pp_SUITE \
+ ic_be_SUITE \
+ c_client_erl_server_SUITE \
+ c_client_erl_server_proto_SUITE \
+ c_client_erl_server_proto_tmo_SUITE \
+ erl_client_c_server_SUITE \
+ erl_client_c_server_proto_SUITE \
+ java_client_erl_server_SUITE
+
+GEN_MODULES =
+
+ERL_FILES = $(MODULES:%=%.erl)
+
+HRL_FILES =
+
+GEN_HRL_FILES =
+
+
+GEN_FILES = \
+ $(GEN_HRL_FILES:%=$(IDLOUTDIR)/%) \
+ $(GEN_MODULES=:%=$(IDLOUTDIR)/%.erl)
+
+GEN_TARGET_FILES = $(GEN_MODULES:%=$(IDLOUTDIR)/%.$(EMULATOR))
+
+SUITE_TARGET_FILES = $(MODULES:%=%.$(EMULATOR))
+
+TARGET_FILES = \
+ $(GEN_TARGET_FILES) \
+ $(SUITE_TARGET_FILES)
+
+# ----------------------------------------------------
+# PROGRAMS
+# ----------------------------------------------------
+
+# ----------------------------------------------------
+# FLAGS
+# ----------------------------------------------------
+ERL_LOCAL_FLAGS += -pa $(ERL_TOP)/lib/orber/ebin -pa $(ERL_TOP)/lib/ic/ebin
+
+ERL_COMPILE_FLAGS += \
+ $(ERL_LOCAL_FLAGS) \
+ -pa $(ERL_TOP)/lib/test_server/ebin \
+ -pa $(ERL_TOP)/lib/orber/ebin \
+ -I$(ERL_TOP)/lib/orber \
+ -I$(ERL_TOP)/lib/test_server/include
+
+# ----------------------------------------------------
+# Targets
+# ----------------------------------------------------
+tests debug opt: $(TARGET_FILES)
+
+clean:
+ rm -f $(TARGET_FILES)
+ rm -f errs core *~
+
+docs:
+
+# ----------------------------------------------------
+# Special Targets
+# ----------------------------------------------------
+
+
+# ----------------------------------------------------
+# Release Targets
+# ----------------------------------------------------
+include $(ERL_TOP)/make/otp_release_targets.mk
+
+release_spec:
+
+release_docs_spec:
+
+release_tests_spec: tests
+ $(INSTALL_DIR) $(RELSYSDIR)
+ $(INSTALL_DIR) $(RELSYSDIR)/ic_SUITE_data
+ $(INSTALL_DIR) $(RELSYSDIR)/ic_register_SUITE_data
+ $(INSTALL_DIR) $(RELSYSDIR)/ic_pragma_SUITE_data
+ $(INSTALL_DIR) $(RELSYSDIR)/ic_pp_SUITE_data
+ $(INSTALL_DIR) $(RELSYSDIR)/ic_be_SUITE_data
+ $(INSTALL_DIR) $(RELSYSDIR)/c_client_erl_server_SUITE_data
+ $(INSTALL_DIR) $(RELSYSDIR)/c_client_erl_server_proto_SUITE_data
+ $(INSTALL_DIR) $(RELSYSDIR)/c_client_erl_server_proto_tmo_SUITE_data
+ $(INSTALL_DIR) $(RELSYSDIR)/erl_client_c_server_SUITE_data
+ $(INSTALL_DIR) $(RELSYSDIR)/erl_client_c_server_proto_SUITE_data
+ $(INSTALL_DIR) $(RELSYSDIR)/java_client_erl_server_SUITE_data
+ $(INSTALL_DATA) $(IDL_FILES) $(TEST_SPEC_FILE) $(ERL_FILES) \
+ $(RELSYSDIR)
+ $(INSTALL_DATA) $(COMPILER_TEST_FILES) $(RELSYSDIR)/ic_SUITE_data
+ $(INSTALL_DATA) $(COMPILER_TEST_FILES2) \
+ $(RELSYSDIR)/ic_register_SUITE_data
+ $(INSTALL_DATA) $(COMPILER_TEST_FILES3) \
+ $(RELSYSDIR)/ic_pragma_SUITE_data
+ $(INSTALL_DATA) $(COMPILER_TEST_FILES4) \
+ $(RELSYSDIR)/ic_be_SUITE_data
+ $(INSTALL_DATA) $(PREPROCESSOR_TEST_FILES) \
+ $(RELSYSDIR)/ic_pp_SUITE_data
+ $(INSTALL_DATA) $(C_CLIENT_ERL_SERVER_TEST_FILES) \
+ $(RELSYSDIR)/c_client_erl_server_SUITE_data
+ $(INSTALL_DATA) $(C_CLIENT_ERL_SERVER_PROTO_TEST_FILES) \
+ $(RELSYSDIR)/c_client_erl_server_proto_SUITE_data
+ $(INSTALL_DATA) $(C_CLIENT_ERL_SERVER_PROTO_TMO_TEST_FILES) \
+ $(RELSYSDIR)/c_client_erl_server_proto_tmo_SUITE_data
+ $(INSTALL_DATA) $(ERL_CLIENT_C_SERVER_TEST_FILES) \
+ $(RELSYSDIR)/erl_client_c_server_SUITE_data
+ $(INSTALL_DATA) $(ERL_CLIENT_C_SERVER_PROTO_TEST_FILES) \
+ $(RELSYSDIR)/erl_client_c_server_proto_SUITE_data
+ $(INSTALL_DATA) $(SUITE_TARGET_FILES) $(RELSYSDIR)
+ $(INSTALL_DATA) $(JAVA_CLIENT_ERL_SERVER_TEST_FILES) \
+ $(RELSYSDIR)/java_client_erl_server_SUITE_data
diff --git a/lib/ic/test/c_client_erl_server_SUITE.erl b/lib/ic/test/c_client_erl_server_SUITE.erl
new file mode 100644
index 0000000000..40c1395d10
--- /dev/null
+++ b/lib/ic/test/c_client_erl_server_SUITE.erl
@@ -0,0 +1,315 @@
+%%
+%% %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 : Test suite for c-client/erl-server
+%%----------------------------------------------------------------------
+
+
+-module(c_client_erl_server_SUITE).
+-include("test_server.hrl").
+
+-export([init_per_testcase/2, fin_per_testcase/2,
+ all/1, void_test/1, long_test/1, long_long_test/1,
+ unsigned_short_test/1, unsigned_long_test/1,
+ unsigned_long_long_test/1, double_test/1, char_test/1,
+ wchar_test/1, octet_test/1, bool_test/1, struct_test/1,
+ struct2_test/1, seq1_test/1, seq2_test/1, seq3_test/1,
+ seq4_test/1, seq5_test/1, array1_test/1, array2_test/1,
+ enum_test/1, string1_test/1, string2_test/1, string3_test/1,
+ string4_test/1, pid_test/1, port_test/1, ref_test/1, term_test/1,
+ typedef_test/1, inline_sequence_test/1, term_sequence_test/1,
+ term_struct_test/1, wstring1_test/1]).
+
+-define(DEFAULT_TIMEOUT, 20000).
+-define(PORT_TIMEOUT, 15000).
+-define(ERLANG_SERVER_NAME, idl_erlang_server).
+-define(C_CLIENT_NODE_NAME, c_client_idl_test).
+
+%% Add/remove code path and watchdog before/after each test case.
+%%
+init_per_testcase(_Case, Config) ->
+ DataDir = ?config(data_dir, Config),
+ code:add_patha(DataDir),
+
+ %% Since other test suites use the module m_i, we have
+ %% to make sure we are using the right m_i module.
+ code:purge(m_i),
+ code:load_file(m_i),
+
+ WatchDog = test_server:timetrap(?DEFAULT_TIMEOUT),
+ [{watchdog, WatchDog}| Config].
+
+fin_per_testcase(_Case, Config) ->
+ DataDir = ?config(data_dir, Config),
+ code:del_path(DataDir),
+ WatchDog = ?config(watchdog, Config),
+ test_server:timetrap_cancel(WatchDog).
+
+all(doc) ->
+ "Test of IC with a C-client and an Erlang generic server. "
+ "The communication is via Erlang distribution.";
+all(suite) ->
+ [void_test, long_test, long_long_test, unsigned_short_test,
+ unsigned_long_test, unsigned_long_long_test, double_test,
+ char_test, wchar_test, octet_test, bool_test, struct_test,
+ struct2_test, seq1_test, seq2_test, seq3_test, seq4_test,
+ seq5_test, array1_test, array2_test, enum_test, string1_test,
+ string2_test, string3_test, string4_test, pid_test, port_test,
+ ref_test, term_test, typedef_test, inline_sequence_test,
+ term_sequence_test, term_struct_test, wstring1_test].
+
+
+array1_test(doc) -> "";
+array1_test(suite) -> [];
+array1_test(Config) ->
+ do_test(array1_test, Config).
+
+array2_test(doc) -> "";
+array2_test(suite) -> [];
+array2_test(Config) ->
+ do_test(array2_test, Config).
+
+bool_test(doc) -> "";
+bool_test(suite) -> [];
+bool_test(Config) ->
+ do_test(bool_test, Config).
+
+char_test(doc) -> "";
+char_test(suite) -> [];
+char_test(Config) ->
+ do_test(char_test, Config).
+
+double_test(doc) -> "";
+double_test(suite) -> [];
+double_test(Config) ->
+ do_test(double_test, Config).
+
+enum_test(doc) -> "";
+enum_test(suite) -> [];
+enum_test(Config) ->
+ do_test(enum_test, Config).
+
+inline_sequence_test(doc) -> "";
+inline_sequence_test(suite) -> [];
+inline_sequence_test(Config) ->
+ do_test(inline_sequence_test, Config).
+
+long_long_test(doc) -> "";
+long_long_test(suite) -> [];
+long_long_test(Config) ->
+ do_test(long_long_test, Config).
+
+long_test(doc) -> "";
+long_test(suite) -> [];
+long_test(Config) ->
+ do_test(long_test, Config).
+
+octet_test(doc) -> "";
+octet_test(suite) -> [];
+octet_test(Config) ->
+ do_test(octet_test, Config).
+
+pid_test(doc) -> "";
+pid_test(suite) -> [];
+pid_test(Config) ->
+ do_test(pid_test, Config).
+
+port_test(doc) -> "";
+port_test(suite) -> [];
+port_test(Config) ->
+ do_test(port_test, Config).
+
+ref_test(doc) -> "";
+ref_test(suite) -> [];
+ref_test(Config) ->
+ do_test(ref_test, Config).
+
+seq1_test(doc) -> "";
+seq1_test(suite) -> [];
+seq1_test(Config) ->
+ do_test(seq1_test, Config).
+
+seq2_test(doc) -> "";
+seq2_test(suite) -> [];
+seq2_test(Config) ->
+ do_test(seq2_test, Config).
+
+seq3_test(doc) -> "";
+seq3_test(suite) -> [];
+seq3_test(Config) ->
+ do_test(seq3_test, Config).
+
+seq4_test(doc) -> "";
+seq4_test(suite) -> [];
+seq4_test(Config) ->
+ do_test(seq4_test, Config).
+
+seq5_test(doc) -> "";
+seq5_test(suite) -> [];
+seq5_test(Config) ->
+ do_test(seq5_test, Config).
+
+string1_test(doc) -> "";
+string1_test(suite) -> [];
+string1_test(Config) ->
+ do_test(string1_test, Config).
+
+string2_test(doc) -> "";
+string2_test(suite) -> [];
+string2_test(Config) ->
+ do_test(string2_test, Config).
+
+string3_test(doc) -> "";
+string3_test(suite) -> [];
+string3_test(Config) ->
+ do_test(string3_test, Config).
+
+string4_test(doc) -> "";
+string4_test(suite) -> [];
+string4_test(Config) ->
+ do_test(string4_test, Config).
+
+struct2_test(doc) -> "";
+struct2_test(suite) -> [];
+struct2_test(Config) ->
+ do_test(struct2_test, Config).
+
+struct_test(doc) -> "";
+struct_test(suite) -> [];
+struct_test(Config) ->
+ do_test(struct_test, Config).
+
+term_sequence_test(doc) -> "";
+term_sequence_test(suite) -> [];
+term_sequence_test(Config) ->
+ do_test(term_sequence_test, Config).
+
+term_struct_test(doc) -> "";
+term_struct_test(suite) -> [];
+term_struct_test(Config) ->
+ do_test(term_struct_test, Config).
+
+term_test(doc) -> "";
+term_test(suite) -> [];
+term_test(Config) ->
+ do_test(term_test, Config).
+
+typedef_test(doc) -> "";
+typedef_test(suite) -> [];
+typedef_test(Config) ->
+ do_test(typedef_test, Config).
+
+unsigned_long_long_test(doc) -> "";
+unsigned_long_long_test(suite) -> [];
+unsigned_long_long_test(Config) ->
+ do_test(unsigned_long_long_test, Config).
+
+unsigned_long_test(doc) -> "";
+unsigned_long_test(suite) -> [];
+unsigned_long_test(Config) ->
+ do_test(unsigned_long_test, Config).
+
+unsigned_short_test(doc) -> "";
+unsigned_short_test(suite) -> [];
+unsigned_short_test(Config) ->
+ do_test(unsigned_short_test, Config).
+
+void_test(doc) -> "";
+void_test(suite) -> [];
+void_test(Config) ->
+ do_test(void_test, Config).
+
+wchar_test(doc) -> "";
+wchar_test(suite) -> [];
+wchar_test(Config) ->
+ do_test(wchar_test, Config).
+
+wstring1_test(doc) -> "";
+wstring1_test(suite) -> [];
+wstring1_test(Config) ->
+ do_test(wstring1_test, Config).
+
+
+%% It is here that all tests really are done.
+%%
+
+do_test(Case, Config) ->
+ %% Trap exits
+ process_flag(trap_exit, true),
+ %% Start the server
+ {ok, _Pid} = m_i:oe_create_link([], {local, ?ERLANG_SERVER_NAME}),
+ Node = atom_to_list(node()),
+ DataDir = ?config(data_dir, Config),
+ %% io:format("~p: data directory: ~p~n", [?MODULE, DataDir]),
+ Cookie = atom_to_list(erlang:get_cookie()),
+ %% Start C-client node as a port program.
+ Cmd = filename:join([DataDir, "c_client"]) ++
+ " -this-node-name " ++ atom_to_list(?C_CLIENT_NODE_NAME) ++
+ " -peer-node " ++ Node ++
+ " -peer-process-name " ++ atom_to_list(?ERLANG_SERVER_NAME) ++
+ " -cookie " ++ Cookie ++
+ " -test-case " ++ atom_to_list(Case),
+ Port = open_port({spawn, Cmd}, [exit_status, eof, stderr_to_stdout]),
+ Res = wait_for_completion(Port),
+ %% Kill off node if there was timeout
+ case Res of
+ {error, timeout} ->
+ catch rpc:cast(?C_CLIENT_NODE_NAME, erlang, halt, [1]);
+ _ ->
+ ok
+ end,
+ process_flag(trap_exit, false),
+ catch m_i:stop(?ERLANG_SERVER_NAME),
+ ok = Res.
+
+
+%% Wait for eof *and* exit status, but return if exit status indicates
+%% an error, or we have been waiting more than PORT_TIMEOUT seconds.
+%%
+wait_for_completion(Port) ->
+ wait_for_completion(Port, 0).
+
+wait_for_completion(Port, N) when N < 2 ->
+ receive
+ {Port, {data, Bytes}} ->
+ %% Relay output
+ io:format("~s", [Bytes]),
+ wait_for_completion(Port, N);
+ {Port, {exit_status, 0}} ->
+ wait_for_completion(Port, N + 1);
+ {Port, {exit_status, Status}} ->
+ {error, Status};
+ {Port, eof} ->
+ wait_for_completion(Port, N + 1);
+ {'EXIT', Port, Reason} ->
+ io:format("Port exited with reason: ~w~n", [Reason]),
+ wait_for_completion(Port, N);
+ {'EXIT', From, Reason} ->
+ io:format("Got unexpected exit: ~p~n", [{'EXIT', From, Reason}]),
+ wait_for_completion(Port, N)
+ after ?PORT_TIMEOUT ->
+ {error, timeout}
+ end;
+wait_for_completion(_, _) ->
+ ok.
+
+
+
diff --git a/lib/ic/test/c_client_erl_server_SUITE_data/Makefile.src b/lib/ic/test/c_client_erl_server_SUITE_data/Makefile.src
new file mode 100644
index 0000000000..6516e699bd
--- /dev/null
+++ b/lib/ic/test/c_client_erl_server_SUITE_data/Makefile.src
@@ -0,0 +1,145 @@
+#
+# %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%
+#
+#
+# Makefile.src for c_client_erl_server test
+# Note: This file *must* work for both Unix and Windows
+#
+# We use both `rm' (Unix) and `del' (Windows) for removing files, but
+# with a `-' in front so that the error in not finding `rm' (`del') on
+# Windows (Unix) is ignored.
+#
+# VxWorks? XXX
+#
+
+.SUFFIXES:
+.SUFFIXES: .c .h .erl .idl @obj@ .@EMULATOR@
+
+
+# Variables from ts:
+#
+
+ERL_INCLUDE = @erl_include@
+
+IC_INCLUDE_PATH = @ic_include_path@
+IC_LIB = @ic_libpath@@DS@@ic_lib@
+
+ERL_INTERFACE_INCLUDE = @erl_interface_include@
+ERL_INTERFACE_LIB = @erl_interface_libpath@@DS@@erl_interface_lib@
+ERL_INTERFACE_EILIB = @erl_interface_libpath@@DS@@erl_interface_eilib@
+ERL_INTERFACE_THREADLIB = @erl_interface_threadlib@
+ERL_INTERFACE_SOCK_LIBS = @erl_interface_sock_libs@
+
+CC = @CC@
+## XXX Should set warning flag with a DEBUG_FLAG
+CFLAGS = @CFLAGS@ @DEFS@ -I@erl_include@ \
+ -I@ic_include_path@ -I@erl_interface_include@
+
+LD = @LD@
+LDFLAGS = @CROSSLDFLAGS@
+LIBS = $(IC_LIB) $(ERL_INTERFACE_LIB) $(ERL_INTERFACE_EILIB) \
+ $(ERL_INTERFACE_THREADLIB) @LIBS@ $(ERL_INTERFACE_SOCK_LIBS)
+ERLC = erlc
+
+# Generated C header files
+GEN_H_FILES = \
+ m.h \
+ m_i.h \
+ oe_c_erl_test.h
+
+# Generated C files
+GEN_C_FILES = \
+ m.c \
+ m_i.c \
+ oe_c_erl_test.c \
+ oe_code_m_a.c \
+ oe_code_m_arr1.c \
+ oe_code_m_arr2.c \
+ oe_code_m_arr3.c \
+ oe_code_m_aseq.c \
+ oe_code_m_b.c \
+ oe_code_m_bseq.c \
+ oe_code_m_dd.c \
+ oe_code_m_dyn.c \
+ oe_code_m_dyn_sl.c \
+ oe_code_m_es.c \
+ oe_code_m_et.c \
+ oe_code_m_etseq.c \
+ oe_code_m_fruit.c \
+ oe_code_m_lseq.c \
+ oe_code_m_s.c \
+ oe_code_m_s_sl.c \
+ oe_code_m_sarr3.c \
+ oe_code_m_simple.c \
+ oe_code_m_ssarr3.c \
+ oe_code_m_sseq.c \
+ oe_code_m_ssstr3.c \
+ oe_code_m_sstr3.c \
+ oe_code_m_str1.c \
+ oe_code_m_str3.c \
+ oe_code_m_strRec.c \
+ oe_code_m_strRec_str5.c \
+ oe_code_m_strRec_str7.c
+
+GEN_HRL_FILES = \
+ m.hrl \
+ m_i.hrl \
+ oe_c_erl_test.hrl
+
+GEN_ERL_FILES = \
+ m.erl \
+ m_arr2.erl \
+ m_arr3.erl \
+ m_i.erl \
+ m_str3.erl \
+ oe_c_erl_test.erl
+
+C_FILES = $(GEN_C_FILES) c_client.c
+
+OBJS = $(C_FILES:.c=@obj@)
+
+PGMS = c_client@exe@
+
+ERL_FILES = $(GEN_ERL_FILES) m_i_impl.erl
+
+EBINS = $(ERL_FILES:.erl=.@EMULATOR@)
+
+
+all: $(PGMS) $(EBINS)
+
+clean:
+ -rm -f $(OBJS) $(GEN_C_FILES) $(GEN_H_FILES) $(PGMS) \
+ $(EBINS) $(GEN_ERL_FILES) $(GEN_HRL_FILES)
+ -del /F /Q $(OBJS) $(GEN_C_FILES) $(GEN_H_FILES) $(PGMS) \
+ $(EBINS) $(GEN_ERL_FILES) $(GEN_HRL_FILES)
+
+$(PGMS): $(OBJS)
+ $(LD) $(LDFLAGS) -o $@ $(OBJS) $(LIBS)
+
+$(GEN_C_FILES) $(GEN_H_FILES): c_erl_test.idl
+ $(ERLC) -I $(IC_INCLUDE_PATH) "+{be,c_client}" c_erl_test.idl
+
+$(GEN_ERL_FILES) $(GEN_HRL_FILES): c_erl_test.idl
+ $(ERLC) -I $(IC_INCLUDE_PATH) "+{be,erl_genserv}" c_erl_test.idl
+
+.c@obj@:
+ $(CC) -c -o $*@obj@ $(CFLAGS) $<
+
+.erl.@EMULATOR@:
+ $(ERLC) -I $(IC_INCLUDE_PATH) $<
+
diff --git a/lib/ic/test/c_client_erl_server_SUITE_data/c_client.c b/lib/ic/test/c_client_erl_server_SUITE_data/c_client.c
new file mode 100644
index 0000000000..e4f9cfdece
--- /dev/null
+++ b/lib/ic/test/c_client_erl_server_SUITE_data/c_client.c
@@ -0,0 +1,1760 @@
+/*
+ * %CopyrightBegin%
+ *
+ * Copyright Ericsson AB 2001-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%
+ *
+ */
+/* C-client for test of IC.
+ *
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#ifndef __WIN32__
+# include <unistd.h>
+#endif
+
+#include <string.h>
+
+#ifdef __WIN32__
+# include <time.h>
+# include <sys/timeb.h>
+#elif defined VXWORKS
+#include <time.h>
+#include <sys/times.h>
+#else
+#include <sys/time.h>
+#endif
+
+#include <ctype.h>
+
+#ifdef __WIN32__
+# include <winsock2.h>
+# include <windows.h>
+#else
+# include <sys/types.h>
+# include <sys/socket.h>
+# include <netinet/in.h>
+# include <arpa/inet.h>
+# include <netdb.h>
+#endif
+
+#include "ei.h"
+#include "erl_interface.h"
+#include "m_i.h"
+
+#define HOSTNAMESZ 256
+#define NODENAMESZ 512
+
+#define INBUFSZ 10
+#define OUTBUFSZ 0
+
+#define MAXTRIES 5
+
+#define CHECK_EXCEPTION(x) \
+ if ((x)->_major != CORBA_NO_EXCEPTION) { \
+ fprintf(stderr,"\n\nException: %s\n\n", \
+ (char *)CORBA_exception_value((x))); \
+ CORBA_exception_free((x)); \
+ return -1; \
+ } \
+
+/* XXX Should free things here too! */
+#define RETURN_IF_OK(x) \
+ if ((x)) {\
+ fprintf(stdout, "ok\n");\
+ return 0;\
+ }\
+
+#define cmp_str(x,y) (!strcmp((x),(y)))
+#define cmp_wstr(x,y) (!ic_wstrcmp((x),(y)))
+
+typedef CORBA_Environment IC_Env;
+
+typedef int (*TestFunc)(IC_Env *);
+typedef struct {
+ char *name;
+ TestFunc func;
+} TestCase;
+
+static char longtext[] =
+"Introduction The IC application is an IDL compiler implemented in Erlang."
+" The IDL compiler generates client stubs and server skeletons."
+" Several back-ends are supported, and they fall into three main groups."
+" For more details on IC compiler options consult the ic(3) manual page."
+" Argument passing cases 1 Caller allocates all necessary storage,"
+" except that which may be encapsulated and managed within the parameter itself."
+" 2 The caller allocates a pointer and passes it by reference to the callee."
+" The callee sets the pointer to point to a valid instance of the parameter's type."
+" The caller is responsible for releasing the returned storage."
+" Following completion of a request, the caller is not allowed to modify any values"
+" in the returned storage. To do so the caller must first copy the returned instance"
+" into a new instance, then modify the new instance. 3 The caller allocates a"
+" pointer to an array slice which has all the same dimensions of the original"
+" array except the first, and passes it by reference to the callee. The callee sets"
+" the pointer to point to a valid instance of the array. The caller is responsible for"
+" releasing the returned storage. Following completion of a request, the caller is not"
+" allowed to modify any values in the returned storage. To do so the caller must first"
+" copy the returned instance into a new instance, then modify the new instance."
+" Generated Files Two files will be generated for each scope. One set of files will be"
+" generated for each module and each interface scope. An extra set is generated for"
+" those definitions at top level scope. One of the files is a header file(.h), and the"
+" other file is a C source code file (.c). In addition to these files a number of C"
+" source files will be generated for type encodings, they are named according to the "
+"following template: oe_code_<type>.c.";
+static char this_node[NODENAMESZ + 1];
+static char *progname;
+
+/* Test function prototypes */
+
+static int void_test(IC_Env *env);
+static int long_test(IC_Env *env);
+static int long_long_test(IC_Env *env);
+static int unsigned_short_test(IC_Env *env);
+static int unsigned_long_test(IC_Env *env);
+static int unsigned_long_long_test(IC_Env *env);
+static int double_test(IC_Env *env);
+static int char_test(IC_Env *env);
+static int wchar_test(IC_Env *env);
+static int octet_test(IC_Env *env);
+static int bool_test(IC_Env *env);
+static int struct_test(IC_Env *env);
+static int struct2_test(IC_Env *env);
+static int seq1_test(IC_Env *env);
+static int seq2_test(IC_Env *env);
+static int seq3_test(IC_Env *env);
+static int seq4_test(IC_Env *env);
+static int seq5_test(IC_Env *env);
+static int array1_test(IC_Env *env);
+static int array2_test(IC_Env *env);
+static int enum_test(IC_Env *env);
+static int string1_test(IC_Env *env);
+static int string2_test(IC_Env *env);
+static int string3_test(IC_Env *env);
+static int string4_test(IC_Env *env);
+static int pid_test(IC_Env *env);
+static int port_test(IC_Env *env);
+static int ref_test(IC_Env *env);
+static int term_test(IC_Env *env);
+static int typedef_test(IC_Env *env);
+static int inline_sequence_test(IC_Env *env);
+static int term_sequence_test(IC_Env *env);
+static int term_struct_test(IC_Env *env);
+static int wstring1_test(IC_Env *env);
+
+static TestCase test_cases[] = {
+ {"void_test", void_test},
+ {"long_test", long_test},
+ {"long_long_test", long_long_test},
+ {"unsigned_short_test", unsigned_short_test},
+ {"unsigned_long_test", unsigned_long_test},
+ {"unsigned_long_long_test", unsigned_long_long_test},
+ {"double_test", double_test},
+ {"char_test", char_test},
+ {"wchar_test", wchar_test},
+ {"octet_test", octet_test},
+ {"bool_test", bool_test},
+ {"struct_test", struct_test},
+ {"struct2_test", struct2_test},
+ {"seq1_test", seq1_test},
+ {"seq2_test", seq2_test},
+ {"seq3_test", seq3_test},
+ {"seq4_test", seq4_test},
+ {"seq5_test", seq5_test},
+ {"array1_test", array1_test},
+ {"array2_test", array2_test},
+ {"enum_test", enum_test},
+ {"string1_test", string1_test},
+ {"string2_test", string2_test},
+ {"string3_test", string3_test},
+ {"string4_test", string4_test},
+ {"pid_test", pid_test},
+ {"port_test", port_test},
+ {"ref_test", ref_test},
+ {"term_test", term_test},
+ {"typedef_test", typedef_test},
+ {"inline_sequence_test", inline_sequence_test},
+ {"term_sequence_test", term_sequence_test},
+ {"term_struct_test", term_struct_test},
+ {"wstring1_test", wstring1_test},
+ {"", NULL}
+};
+
+/* Other prototypes */
+static int cmp_aseq(m_aseq *a1, m_aseq *a2);
+static int cmp_a(m_a *a1, m_a *a2);
+static int cmp_bseq(m_bseq *b1, m_bseq *b2);
+static int cmp_b(m_b *b1, m_b *b2);
+static int cmp_lseq(m_lseq *b1, m_lseq *b2);
+static int cmp_etseq(m_etseq *b1, m_etseq *b2);
+static int cmp_et(m_et* b1, m_et *b2);
+static int cmp_es(m_es *b1, m_es *b2);
+static int cmp_arr1(m_arr1 b1, m_arr1 b2);
+static int cmp_dd(m_dd b1, m_dd b2);
+static int cmp_strRec(m_strRec *b1, m_strRec *b2);
+static int cmp_sseq(m_sseq *b1, m_sseq *b2);
+static int cmp_pid(erlang_pid *p1, erlang_pid *p2);
+static int cmp_port(erlang_port *p1, erlang_port *p2);
+static int cmp_ref(erlang_ref *p1, erlang_ref *p2);
+static int cmp_s(m_s *b1, m_s *b2);
+static int cmp_ssstr3(m_ssstr3 *b1, m_ssstr3 *b2);
+static int cmp_ssarr3(m_ssarr3 *b1, m_ssarr3 *b2);
+static int cmp_sarr3(m_sarr3 *b1, m_sarr3 *b2);
+static int cmp_arr3(m_arr3 b1, m_arr3 b2);
+
+static void print_aseq(m_aseq *a);
+static void print_a(m_a *a);
+static void print_bseq(m_bseq *b);
+static void print_lseq(m_lseq *b);
+static void print_b(m_b *b);
+static void print_etseq(m_etseq *b);
+static void print_et(m_et* b);
+static void print_es(m_es *b);
+static void print_arr1(long a[500]);
+static void print_dd(long a[2][3]);
+static void print_strRec(m_strRec* sr);
+static void print_sseq(m_sseq *b);
+static void print_pid(erlang_pid *p);
+static void print_port(erlang_port *p);
+static void print_ref(erlang_ref *p);
+static void print_term(ETERM *t);
+static void print_s(m_s *p);
+static void print_ssstr3(m_ssstr3 *b1);
+static void print_ssarr3(m_ssarr3 *b1);
+static void print_sarr3(m_sarr3 *b1);
+static void print_arr3(m_arr3 b1);
+static void print_wstr(CORBA_wchar *ws);
+
+static void free_etseq_buf(m_etseq *b);
+static void free_et(m_et* b);
+
+#ifdef __WIN32__
+typedef struct {
+ long tv_sec;
+ long tv_usec;
+} MyTimeval;
+#else
+typedef struct timeval MyTimeval;
+#endif
+static void my_gettimeofday(MyTimeval *tv);
+static void showtime(MyTimeval *start, MyTimeval *stop);
+static void usage(void);
+static void done(int r);
+
+
+
+/* main */
+
+#ifdef VXWORKS
+int client(int argc, char **argv)
+#else
+int main(int argc, char **argv)
+#endif
+{
+ struct hostent *hp;
+ erlang_pid pid;
+ MyTimeval start, stop;
+ int i, fd, ires, tres;
+ IC_Env *env;
+ int tries = 0;
+ char *this_node_name = NULL;
+ char *peer_node = NULL;
+ char *peer_process_name = NULL;
+ char *cookie = NULL;
+ char host[HOSTNAMESZ + 1];
+ TestFunc test_func = NULL;
+ TestCase *test_case;
+ char *test_case_name = NULL;
+
+#ifdef __WIN32__
+ WORD wVersionRequested;
+ WSADATA wsaData;
+
+ wVersionRequested = MAKEWORD(2, 0);
+
+ if (WSAStartup(wVersionRequested, &wsaData) != 0) {
+ fprintf(stderr, "Could not load winsock2 v2.0 compatible DLL");
+ exit(1);
+ }
+#endif
+
+ progname = argv[0];
+ host[HOSTNAMESZ] = '\0';
+ if (gethostname(host, HOSTNAMESZ) < 0) {
+ fprintf(stderr, "Can't find own hostname\n");
+ done(1);
+ }
+ if ((hp = gethostbyname(host)) == 0) {
+ fprintf(stderr, "Can't get ip address for host %s\n", host);
+ done(1);
+ }
+ for (i = 1; i < argc; i++) {
+ if (cmp_str(argv[i], "-help")) {
+ usage();
+ done(0);
+ } else if (cmp_str(argv[i], "-this-node-name")) {
+ i++;
+ this_node_name = argv[i];
+ } else if (cmp_str(argv[i], "-peer-node")) {
+ i++;
+ peer_node = argv[i];
+ } else if (cmp_str(argv[i], "-peer-process-name")) {
+ i++;
+ peer_process_name = argv[i];
+ } else if (cmp_str(argv[i], "-cookie")) {
+ i++;
+ cookie = argv[i];
+ } else if (cmp_str(argv[i], "-test-case")) {
+ i++;
+ test_case_name = argv[i];
+ } else {
+ fprintf(stderr, "Error : invalid argument \"%s\"\n", argv[i]);
+ usage();
+ done(1);
+ }
+ }
+
+ if (this_node_name == NULL || peer_node == NULL || test_case_name == NULL
+ || peer_process_name == NULL || cookie == NULL) {
+ fprintf(stderr, "Error: missing option\n");
+ usage();
+ done(1);
+ }
+
+ test_case = test_cases;
+ while (test_case->func) {
+ if (cmp_str(test_case->name, test_case_name)) {
+ test_func = test_case->func;
+ break;
+ }
+ test_case++;
+ }
+ if (test_func == NULL) {
+ fprintf(stderr, "Error: illegal test case: \"%s\"\n", test_case_name);
+ done(1);
+ }
+
+ /* Behead hostname at first dot */
+ for (i=0; host[i] != '\0'; i++) {
+ if (host[i] == '.') { host[i] = '\0'; break; }
+ }
+ sprintf(this_node, "%s@%s", this_node_name, host);
+ fprintf(stderr, "c_client: this node: \"%s\"\n", this_node);
+ fprintf(stderr, "c_client: peer node: \"%s\"\n", peer_node);
+ fprintf(stderr, "c_client: test case: \"%s\"\n", test_case_name);
+
+ fprintf(stderr, "c_client: starting\n");
+
+ /* initialize erl_interface */
+ erl_init(NULL, 0);
+
+ for (tries = 0; tries < MAXTRIES; tries++) {
+
+ /* connect to erlang node */
+
+ ires = erl_connect_xinit(host, this_node_name, this_node,
+ (struct in_addr *)*hp->h_addr_list,
+ cookie, 0);
+
+ fprintf(stderr, "c_client: erl_connect_xinit(): %d\n", ires);
+
+ fd = erl_connect(peer_node);
+ fprintf(stderr, "c_client: erl_connect(): %d\n", fd);
+
+ if (fd >= 0)
+ break;
+ fprintf(stderr, "c_client: cannot connect, retrying\n");
+ }
+ if (fd < 0) {
+ fprintf(stderr, "c_client: cannot connect, exiting\n");
+ done(1);
+ }
+ env = CORBA_Environment_alloc(INBUFSZ, OUTBUFSZ);
+ env->_fd = fd;
+ strcpy(env->_regname, peer_process_name);
+ env->_to_pid = NULL;
+ env->_from_pid = &pid;
+
+ strcpy(pid.node, this_node);
+ pid.num = fd;
+ pid.serial = 0;
+ pid.creation = 0;
+
+ my_gettimeofday(&start);
+ tres = test_func(env); /* Call test case */
+ my_gettimeofday(&stop);
+ showtime(&start, &stop);
+ erl_close_connection(fd);
+
+ printf("c_client: env->_inbuf before : %d\n", INBUFSZ);
+ printf("c_client: env->_outbuf before : %d\n", OUTBUFSZ);
+ printf("c_client: env->_inbuf after : %d\n", env->_inbufsz);
+ printf("c_client: env->_outbuf after : %d\n", env->_outbufsz);
+
+ CORBA_free(env->_inbuf);
+ CORBA_free(env->_outbuf);
+ CORBA_free(env);
+ done(tres);
+}
+
+static void usage()
+{
+ fprintf(stderr, "Usage: %s [-help] -this-node-name <name> "
+ "-peer-node <nodename> -peer-process-name <name> "
+ "-cookie <cookie> -test-case <test case name>\n", progname);
+ fprintf(stderr, "Example:\n %s -this-node-name kalle "
+ "-peer-node olle@home -peer-process-name idltest "
+ "-cookie oa678er -test-case octet_test\n", progname);
+}
+
+static void done(int r)
+{
+#ifdef __WIN32__
+ WSACleanup();
+#endif
+ exit(r);
+}
+
+
+/* TESTS */
+
+static int void_test(IC_Env *env)
+{
+ fprintf(stdout, "\n======== m_i_void test ======\n\n");
+ m_i_void_test(NULL,env);
+ CHECK_EXCEPTION(env);
+ RETURN_IF_OK(1);
+}
+
+static int long_test(IC_Env *env)
+{
+ long l = 4711, lo, lr;
+
+ fprintf(stdout, "\n======== m_i_long test ======\n\n");
+ lr = m_i_long_test(NULL, l, &lo, env);
+ CHECK_EXCEPTION(env);
+ RETURN_IF_OK(l == lo && l == lr);
+ if (l != lo)
+ fprintf(stdout, " out parameter error, sent: %ld, got: %ld\n", l, lo);
+ if (l != lr)
+ fprintf(stdout, " result error, sent: %ld, got: %ld\n", l, lr);
+ return -1;
+}
+
+static int long_long_test(IC_Env *env)
+{
+ CORBA_long_long ll = 4711, llo, llr;
+
+ fprintf(stdout, "\n======== m_i_longlong test ======\n\n");
+ llr = m_i_longlong_test(NULL, ll, &llo, env);
+ CHECK_EXCEPTION(env);
+ RETURN_IF_OK(ll == llo && ll == llr);
+ if (ll != llo)
+ fprintf(stdout, " out parameter error, sent: %ld, got: %ld\n",
+ ll, llo);
+ if (ll != llr)
+ fprintf(stdout, " result error, sent: %ld, got: %ld\n", ll, llr);
+ return -1;
+}
+
+static int unsigned_short_test(IC_Env *env)
+{
+ unsigned short x, y = 2, z;
+
+ fprintf(stdout, "\n======== m_i_ushort test ======\n\n");
+ x = m_i_ushort_test(NULL, y, &z, env);
+ CHECK_EXCEPTION(env);
+ RETURN_IF_OK(y == z && y == x);
+ if (y != z)
+ fprintf(stdout, " out parameter error, sent: %d, got: %d\n", y, z);
+ if (y != x)
+ fprintf(stdout, " result error, sent: %d, got: %d\n", y, x);
+ return -1;
+}
+
+
+static int unsigned_long_test(IC_Env *env)
+{
+ unsigned long ul = 5050, ulo, ulr;
+
+ fprintf(stdout, "\n======== m_i_ulong test ======\n\n");
+ ulr = m_i_ulong_test(NULL, ul, &ulo, env);
+ CHECK_EXCEPTION(env);
+ RETURN_IF_OK(ul == ulo && ul == ulr);
+ if (ul != ulo)
+ fprintf(stdout, " out parameter error, sent: %lu, got: %lu\n",
+ ul, ulo);
+ if (ul != ulr)
+ fprintf(stdout, " result error, sent: %lu, got: %lu\n", ul, ulr);
+ return -1;
+}
+
+/*
+ * Note: CORBA_unsigned_long_long is in fact a plain long.
+ */
+static int unsigned_long_long_test(IC_Env *env)
+{
+ CORBA_unsigned_long_long ull = 5050, ullo, ullr;
+
+ fprintf(stdout, "\n======== m_i_ulonglong test ======\n\n");
+ ullr = m_i_ulonglong_test(NULL, ull, &ullo, env);
+ CHECK_EXCEPTION(env);
+ RETURN_IF_OK(ull == ullo && ull == ullr);
+ if (ull != ullo)
+ fprintf(stdout, " out parameter error, sent: %lu, got: %lu\n",
+ ull, ullo);
+ if (ull != ullr)
+ fprintf(stdout, " result error, sent: %lu, got: %lu\n",
+ ull, ullr);
+ return -1;
+}
+
+static int double_test(IC_Env *env)
+{
+ double d = 12.1212, db, dr;
+
+ fprintf(stdout, "\n======== m_i_double test ======\n\n");
+ dr = m_i_double_test(NULL, d, &db, env);
+ CHECK_EXCEPTION(env);
+ RETURN_IF_OK(d == db && d == dr);
+ if (d != db)
+ fprintf(stdout, " out parameter error, sent: %f, got: %f\n", d, db);
+ if (d != dr)
+ fprintf(stdout, " result error, sent: %f, got: %f\n", d, dr);
+ return -1;
+}
+
+static int char_test(IC_Env *env)
+{
+ char c = 'g', co, cr;
+
+ /* char test */
+ fprintf(stdout, "\n======== m_i_char test ======\n\n");
+ cr = m_i_char_test(NULL, c, &co, env);
+ CHECK_EXCEPTION(env);
+ RETURN_IF_OK(c == co && c == cr);
+ if (c !=co)
+ fprintf(stdout, " out parameter error, sent: %c, got: %c\n", c, co);
+ if (c != cr)
+ fprintf(stdout, " result error, sent: %c, got: %c\n", c, cr);
+ return -1;
+}
+
+static int wchar_test(IC_Env *env)
+{
+ CORBA_wchar wc = 103, wco, wcr;
+
+ fprintf(stdout, "\n======== m_i_wchar test ======\n\n");
+ wcr = m_i_wchar_test(NULL, wc, &wco, env);
+ CHECK_EXCEPTION(env);
+ RETURN_IF_OK(wc == wco && wc == wcr);
+ if (wc != wco)
+ fprintf(stdout, " out parameter error, sent: %lu, got: %lu\n",
+ wc, wco);
+ if (wc != wcr)
+ fprintf(stdout, " result error, sent: %lu, got: %lu\n",
+ wc, wcr);
+ return -1;
+}
+
+static int octet_test(IC_Env *env)
+{
+ char o ='r', oo, or;
+
+ fprintf(stdout, "\n======== m_i_octet test ======\n\n");
+ or = m_i_octet_test(NULL, o, &oo, env);
+ CHECK_EXCEPTION(env);
+ RETURN_IF_OK(o == oo && o == or);
+ if (o != oo)
+ fprintf(stdout, " out parameter error, sent: %c, got: %c\n", o, oo);
+ if (o != or)
+ fprintf(stdout, " result error, sent: %c, got: %c\n", o, or);
+ return -1;
+}
+
+static int bool_test(IC_Env *env)
+{
+ unsigned char i = 0, io, ir;
+
+ fprintf(stdout, "\n======== m_i_bool test ======\n\n");
+ ir = m_i_bool_test(NULL, i, &io, env);
+ CHECK_EXCEPTION(env);
+ RETURN_IF_OK(i == io && i == ir);
+ if (i != io)
+ fprintf(stdout, " out parameter error, sent: %d, got: %d\n", i, io);
+ if (i != ir)
+ fprintf(stdout, " result error, sent: %d, got: %d\n", i, ir);
+ return -1;
+}
+
+static int struct_test(IC_Env *env)
+{
+ m_b b = {4711, 'a'}, bo, br;
+
+ fprintf(stdout, "\n======== m_i_struct test ======\n\n");
+ br = m_i_struct_test(NULL, &b, &bo, env);
+ CHECK_EXCEPTION(env);
+ RETURN_IF_OK(cmp_b(&b, &bo) && cmp_b(&b, &br));
+ if (!cmp_b(&b, &bo)) {
+ fprintf(stdout, " out parameter error, sent:\n");
+ print_b(&b);
+ fprintf(stdout, " got:\n");
+ print_b(&bo);
+ fprintf(stdout, "\n");
+ }
+ if (!cmp_b(&b, &br)) {
+ fprintf(stdout, " result error, sent:\n");
+ print_b(&b);
+ fprintf(stdout, " got:\n");
+ print_b(&br);
+ fprintf(stdout, "\n");
+ }
+ return -1;
+}
+
+static int struct2_test(IC_Env *env)
+{
+ m_es esi = {m_peach, 5050}, eso, esr;
+
+ fprintf(stdout, "\n======== m_i_struct2 test ======\n\n");
+ esr = m_i_struct2_test(NULL, &esi, &eso, env);
+ CHECK_EXCEPTION(env);
+ RETURN_IF_OK(cmp_es(&esi, &eso) && cmp_es(&esi, &esr));
+ if (!cmp_es(&esi, &eso)) {
+ fprintf(stdout, " out parameter error, sent:\n");
+ print_es(&esi);
+ fprintf(stdout, " got:\n");
+ print_es(&eso);
+ fprintf(stdout, "\n");
+ }
+ if (!cmp_es(&esi, &esr)) {
+ fprintf(stdout, " result error, sent:\n");
+ print_es(&esi);
+ fprintf(stdout, " got:\n");
+ print_es(&esr);
+ fprintf(stdout, "\n");
+ }
+ return -1;
+}
+
+
+static int seq1_test(IC_Env *env)
+{
+ m_bseq bs, *bso, *bsr;
+
+ m_b ba[3] = {{4711, 'a'}, {4712, 'b'}, {4713, 'c'}};
+ bs._length = 3;
+ bs._buffer = ba;
+
+ fprintf(stdout, "\n======== m_i_seq1 test ======\n\n");
+ bsr = m_i_seq1_test(NULL, &bs, &bso, env);
+ CHECK_EXCEPTION(env);
+ RETURN_IF_OK(cmp_bseq(&bs, bso) && cmp_bseq(&bs, bsr));
+ if (!cmp_bseq(&bs, bso)) {
+ fprintf(stdout, " out parameter error, sent:\n");
+ print_bseq(&bs);
+ fprintf(stdout, " got:\n");
+ print_bseq(bso);
+ fprintf(stdout, "\n");
+ }
+ if (!cmp_bseq(&bs, bsr)) {
+ fprintf(stdout, " result error, sent:\n");
+ print_bseq(&bs);
+ fprintf(stdout, " got:\n");
+ print_bseq(bsr);
+ fprintf(stdout, "\n");
+ }
+ CORBA_free(bso);
+ CORBA_free(bsr);
+ return -1;
+}
+
+static int seq2_test(IC_Env *env)
+{
+ m_b ba[3] = {{4711, 'a'}, {4712, 'b'}, {4713, 'c'}};
+ m_a a;
+ m_a aa[2];
+ m_aseq as, *aso, *asr;
+
+ a.l = 9999;
+ a.y._length = 3;
+ a.y._buffer = ba;
+ a.d = 66.89898989;
+
+ aa[0] = a;
+ aa[1] = a;
+ as._length = 2;
+ as._buffer = aa;
+
+ fprintf(stdout, "\n======== m_i_seq2 test ======\n\n");
+ asr = m_i_seq2_test(NULL, &as, &aso, env);
+ CHECK_EXCEPTION(env);
+ RETURN_IF_OK(cmp_aseq(&as, aso) && cmp_aseq(&as, asr));
+ if (!cmp_aseq(&as, aso)) {
+ fprintf(stdout, " out parameter error, sent:\n");
+ print_aseq(&as);
+ fprintf(stdout, " got:\n");
+ print_aseq(aso);
+ fprintf(stdout, "\n");
+ }
+ if (!cmp_aseq(&as, asr)) {
+ fprintf(stdout, " result error, sent:\n");
+ print_aseq(&as);
+ fprintf(stdout, " got:\n");
+ print_aseq(asr);
+ fprintf(stdout, "\n");
+ }
+ CORBA_free(aso);
+ CORBA_free(asr);
+ return -1;
+}
+
+static int seq3_test(IC_Env *env)
+{
+ m_lseq lsi, *lso, *lsr;
+ long al[500];
+ int i=0;
+
+ for (i = 0; i < 500; i++)
+ al[i]=i;
+ lsi._length = 500;
+ lsi._buffer = al;
+
+ fprintf(stdout, "\n======== m_i_seq3 test ======\n\n");
+ lsr = m_i_seq3_test(NULL, &lsi, &lso, env);
+ CHECK_EXCEPTION(env);
+ RETURN_IF_OK(cmp_lseq(&lsi, lso) && cmp_lseq(&lsi, lsr));
+ if (!cmp_lseq(&lsi, lso)) {
+ fprintf(stdout, " out parameter error, sent:\n");
+ print_lseq(&lsi);
+ fprintf(stdout, " got:\n");
+ print_lseq(lso);
+ fprintf(stdout, "\n");
+ }
+ if (!cmp_lseq(&lsi, lsr)) {
+ fprintf(stdout, " result error, sent:\n");
+ print_lseq(&lsi);
+ fprintf(stdout, " got:\n");
+ print_lseq(lsr);
+ fprintf(stdout, "\n");
+ }
+ CORBA_free(lso);
+ CORBA_free(lsr);
+ return -1;
+}
+
+static int seq4_test(IC_Env *env)
+{
+ char *stra0[3] = {"a", "long", "time"};
+ char *stra1[3] = {"ago", "there", "was"};
+ char *stra2[3] = {"a", "buggy", "compiler"};
+ m_sstr3 str3s[3] = {{3, 3, stra0}, {3, 3, stra1}, {3, 3, stra2}};
+ m_ssstr3 str3ssi = {3, 3, str3s};
+ m_ssstr3 *str3sso, *str3ssr;
+
+ fprintf(stdout, "\n======== m_i_seq4 test ======\n\n");
+ str3ssr = m_i_seq4_test(NULL, &str3ssi, &str3sso, env);
+ CHECK_EXCEPTION(env);
+ RETURN_IF_OK(cmp_ssstr3(&str3ssi, str3sso) &&
+ cmp_ssstr3(&str3ssi, str3ssr));
+ if (!cmp_ssstr3(&str3ssi, str3sso)){
+ fprintf(stdout, " out parameter error, sent:\n");
+ print_ssstr3(&str3ssi);
+ fprintf(stdout, " got:\n");
+ print_ssstr3(str3sso);
+ fprintf(stdout, "\n");
+ }
+ if (!cmp_ssstr3(&str3ssi, str3ssr)) {
+ fprintf(stdout, " result error, sent:\n");
+ print_ssstr3(&str3ssi);
+ fprintf(stdout, " got:\n");
+ print_ssstr3(str3ssr);
+ fprintf(stdout, "\n");
+ }
+ CORBA_free(str3sso);
+ CORBA_free(str3ssr);
+ return -1;
+}
+
+static int seq5_test(IC_Env *env)
+{
+ m_arr3 arr3a[3] = {
+ {4711, 18931947, 3},
+ {4711, 18931947, 3},
+ {4711, 18931947, 3}};
+ m_sarr3 arr3sa[3] = {{3, 3, arr3a}, {3, 3, arr3a}, {3, 3, arr3a}};
+ m_ssarr3 arr3ssi = {3, 3, arr3sa};
+ m_ssarr3 *arr3sso;
+ m_ssarr3 *arr3ssr;
+
+ fprintf(stdout, "\n======== m_i_seq5 test ======\n\n");
+ arr3ssr = m_i_seq5_test(NULL, &arr3ssi, &arr3sso, env);
+ CHECK_EXCEPTION(env);
+ RETURN_IF_OK(cmp_ssarr3(&arr3ssi, arr3sso) &&
+ cmp_ssarr3(&arr3ssi, arr3ssr));
+ if (!cmp_ssarr3(&arr3ssi, arr3sso)) {
+ fprintf(stdout, " out parameter error, sent:\n");
+ print_ssarr3(&arr3ssi);
+ fprintf(stdout, " got:\n");
+ print_ssarr3(arr3sso);
+ fprintf(stdout, "\n");
+ }
+ if (!cmp_ssarr3(&arr3ssi, arr3ssr)) {
+ fprintf(stdout, " result error, sent:\n");
+ print_ssarr3(&arr3ssi);
+ fprintf(stdout, " got:\n");
+ print_ssarr3(arr3ssr);
+ fprintf(stdout, "\n");
+ }
+ CORBA_free(arr3sso);
+ CORBA_free(arr3ssr);
+ return -1;
+}
+
+static int array1_test(IC_Env *env)
+{
+ int i;
+ long al[500];
+ m_arr1 alo;
+ m_arr1_slice* alr;
+
+ for (i = 0; i < 500; i++)
+ al[i]=i;
+
+ fprintf(stdout, "\n======== m_i_array1 test ======\n\n");
+ alr = m_i_array1_test(NULL, al, alo, env);
+ CHECK_EXCEPTION(env);
+ RETURN_IF_OK(cmp_arr1(al, alo) && cmp_arr1(al, alr));
+ if (!cmp_arr1(al, alo)) {
+ fprintf(stdout, " out parameter error, sent:\n");
+ print_arr1(al);
+ fprintf(stdout, " got:\n");
+ print_arr1(alo);
+ fprintf(stdout, "\n");
+ }
+ if (!cmp_arr1(al,alr)) {
+ fprintf(stdout, " result error, sent:\n");
+ print_arr1(al);
+ fprintf(stdout, " got:\n");
+ print_arr1(alr);
+ fprintf(stdout, "\n");
+ }
+ free(alo);
+ free(alr);
+ return -1;
+}
+
+static int array2_test(IC_Env *env)
+{
+ long dl[2][3] = {{11, 2, 7}, {22, 8 ,13}};
+ m_dd dlo;
+ m_dd_slice* dlr;
+
+ fprintf(stdout, "\n======== m_i_array2 test ======\n\n");
+ dlr = m_i_array2_test(NULL, dl, dlo, env);
+ CHECK_EXCEPTION(env);
+ RETURN_IF_OK(cmp_dd(dl,dlo) && cmp_dd(dl,dlr));
+ if (!cmp_dd(dl,dlo)) {
+ fprintf(stdout, " out parameter error, sent:\n");
+ print_dd(dl);
+ fprintf(stdout, " got:\n");
+ print_dd(dlo);
+ fprintf(stdout, "\n");
+ }
+ if (!cmp_dd(dl,dlr)) {
+ fprintf(stdout, " result error, sent:\n");
+ print_dd(dl);
+ fprintf(stdout, " got:\n");
+ print_dd(dlr);
+ fprintf(stdout, "\n");
+ }
+ free(*dlr);
+ return -1;
+}
+
+static int enum_test(IC_Env *env)
+{
+ m_fruit ei = m_banana, eo, er;
+
+ fprintf(stdout, "\n======== m_i_enum test ======\n\n");
+ er = m_i_enum_test(NULL, ei, &eo, env);
+ CHECK_EXCEPTION(env);
+ RETURN_IF_OK(ei == eo && ei == er);
+ if (ei != eo)
+ fprintf(stdout, " out parameter error, sent: %d, got: %d\n", ei, eo);
+ if (ei != er)
+ fprintf(stdout, " result error, sent: %d, got: %d\n", ei, er);
+ return -1;
+}
+
+static int string1_test(IC_Env *env)
+{
+ char* si = longtext;
+ char* so;
+ char* sr;
+
+ fprintf(stdout, "\n======== m_i_string1 test ======\n\n");
+ sr = m_i_string1_test(NULL, si, &so, env);
+ CHECK_EXCEPTION(env);
+ RETURN_IF_OK(cmp_str(si, so) && cmp_str(si, sr));
+ if (!cmp_str(si, so))
+ fprintf(stdout, " out parameter error, sent: %s, got: %s\n", si, so);
+ if (!cmp_str(si, sr))
+ fprintf(stdout, " result error, sent: %s, got: %s\n", si, sr);
+ CORBA_free(so);
+ CORBA_free(sr);
+ return -1;
+}
+
+static int string2_test(IC_Env *env)
+{
+ char* sa[3] = {"hello", "foo", "bar"};
+ m_sseq ssi = {3, 3, sa};
+ m_sseq *sso, *ssr;
+
+ fprintf(stdout, "\n======== m_i_string2 test ======\n\n");
+ ssr = m_i_string2_test(NULL, &ssi, &sso, env);
+ CHECK_EXCEPTION(env);
+ RETURN_IF_OK(cmp_sseq(&ssi, sso) && cmp_sseq(&ssi, sso));
+ if (!cmp_sseq(&ssi, sso)) {
+ fprintf(stdout, " out parameter error, sent:\n");
+ print_sseq(&ssi);
+ fprintf(stdout, "got:\n");
+ print_sseq(sso);
+ }
+ if (!cmp_sseq(&ssi, ssr)) {
+ fprintf(stdout, " result error, sent:\n");
+ print_sseq(&ssi);
+ fprintf(stdout, "got:\n");
+ print_sseq(ssr);
+ }
+ CORBA_free(sso);
+ CORBA_free(ssr);
+ return -1;
+}
+
+static int string3_test(IC_Env *env)
+{
+ char* si = longtext;
+ char* so;
+ char* sr;
+
+ fprintf(stdout, "\n======== m_i_string3 test ======\n\n");
+ sr = m_i_string3_test(NULL, si, &so, env);
+ CHECK_EXCEPTION(env);
+ RETURN_IF_OK(cmp_str(si, so) && cmp_str(si, so));
+ if (!cmp_str(si, so))
+ fprintf(stdout, " out parameter error, sent: %s, got: %s\n", si, so);
+ if (!cmp_str(si, sr))
+ fprintf(stdout, " result error, sent: %s, got: %s\n", si, sr);
+ CORBA_free(so);
+ CORBA_free(sr);
+ return -1;
+}
+
+static int string4_test(IC_Env *env)
+{
+ char as1[100] = "a string", as2[200] = "help", as3[200] = "hello there";
+ m_strRec stri = { 1, /* dd */
+ as1, /* str4 */
+ {{'a', 'k'}, {'z', 'g'}, {'n', 'q'}}, /* str7 */
+ {3, 3, "buf"}, /* str5 */
+ as2, /* str6 */
+ {'m', 'f', 'o'}, /* str8 */
+ as3, /* str9 */
+ {3, 3, "stu"} /* str10 */
+ };
+ m_strRec *stro, *strr;
+
+ fprintf(stdout, "\n======== m_i_string4 test ======\n\n");
+ strr = m_i_string4_test(NULL, &stri, &stro, env);
+ CHECK_EXCEPTION(env);
+ RETURN_IF_OK(cmp_strRec(&stri,stro) && cmp_strRec(&stri,strr));
+ if (!cmp_strRec(&stri,stro)) {
+ fprintf(stdout, " out parameter error, sent:\n");
+ print_strRec(&stri);
+ fprintf(stdout, " got:\n");
+ print_strRec(stro);
+ fprintf(stdout, "\n");
+ }
+ if (!cmp_strRec(&stri,strr)) {
+ fprintf(stdout, " result error, sent:\n");
+ print_strRec(&stri);
+ fprintf(stdout, " got:\n");
+ print_strRec(strr);
+ fprintf(stdout, "\n");
+ }
+ CORBA_free(stro);
+ CORBA_free(strr);
+ return -1;
+}
+
+
+static int pid_test(IC_Env *env)
+{
+ erlang_pid pid = {"", 7, 0, 0}, pido, pidr;
+
+ strcpy(pid.node, this_node), /* this currently running node */
+ fprintf(stdout, "\n======== m_i_pid test ======\n\n");
+ pidr = m_i_pid_test(NULL, &pid, &pido, env);
+ CHECK_EXCEPTION(env);
+ RETURN_IF_OK(cmp_pid(&pid, &pido) && cmp_pid(&pid, &pidr));
+ if (!cmp_pid(&pid, &pido)) {
+ fprintf(stdout, " out parameter error, sent:\n");
+ print_pid(&pid);
+ fprintf(stdout, "got:\n");
+ print_pid(&pido);
+ }
+ if (!cmp_pid(&pid, &pidr)) {
+ fprintf(stdout, " result error, sent:\n");
+ print_pid(&pid);
+ fprintf(stdout, "got:\n");
+ print_pid(&pidr);
+ }
+ return -1;
+}
+
+static int port_test(IC_Env *env)
+{
+ erlang_port porti = {"node", 5, 1}, porto, portr;
+
+ fprintf(stdout, "\n======== m_i_port test ======\n\n");
+ portr = m_i_port_test(NULL, &porti, &porto, env);
+ CHECK_EXCEPTION(env);
+ RETURN_IF_OK(cmp_port(&porti, &porto) && cmp_port(&porti, &portr));
+ if (!cmp_port(&porti, &porto)) {
+ fprintf(stdout, " out parameter error, sent:\n");
+ print_port(&porti);
+ fprintf(stdout, "got:\n");
+ print_port(&porto);
+ }
+ if (!cmp_port(&porti, &portr)) {
+ fprintf(stdout, " result error, sent:\n");
+ print_port(&porti);
+ fprintf(stdout, "got:\n");
+ print_port(&portr);
+ }
+ return -1;
+}
+
+static int ref_test(IC_Env *env)
+{
+ erlang_ref refi = { "node1", 3, {1, 2, 3}, 1},
+ refo, refr;
+
+ fprintf(stdout, "\n======== m_i_ref test ======\n\n");
+ refr = m_i_ref_test(NULL, &refi, &refo, env);
+ CHECK_EXCEPTION(env);
+ RETURN_IF_OK(cmp_ref(&refi, &refo) && cmp_ref(&refi, &refr));
+ if (!cmp_ref(&refi, &refo)) {
+ fprintf(stdout, " out parameter error, sent:\n");
+ print_ref(&refi);
+ fprintf(stdout, "got:\n");
+ print_ref(&refo);
+ }
+ if (!cmp_ref(&refi, &refr)) {
+ fprintf(stdout, " result error, sent:\n");
+ print_ref(&refi);
+ fprintf(stdout, "got:\n");
+ print_ref(&refr);
+ }
+ return -1;
+}
+
+static int term_test(IC_Env *env)
+{
+ ETERM *ti, *to, *tr;
+
+ ti = erl_format("[{hej, 1, 23}, \"string\", {1.23, 45}]");
+
+ fprintf(stdout, "\n======== m_i_term test ======\n\n");
+ tr = m_i_term_test(NULL, ti, &to, env);
+ CHECK_EXCEPTION(env);
+ RETURN_IF_OK(erl_match(ti, to) && erl_match(ti, tr));
+ if (!erl_match(ti, to)) {
+ fprintf(stdout, " out parameter error, sent:\n");
+ print_term(ti);
+ fprintf(stdout, "got:\n");
+ print_term(to);
+ }
+ if (!erl_match(ti, tr)) {
+ fprintf(stdout, " result error, sent:\n");
+ print_term(ti);
+ fprintf(stdout, "got:\n");
+ print_term(tr);
+ }
+ erl_free_term(ti);
+ erl_free_term(to);
+ erl_free_term(tr);
+ return -1;
+}
+
+static int typedef_test(IC_Env *env)
+{
+ m_banan mbi, mbo; /* erlang_port */
+ m_apa mai; /* ETERM* */
+ m_apa mao = NULL;
+ long tl;
+
+ strcpy(mbi.node,"node");
+ mbi.id = 15;
+ mbi.creation = 1;
+
+ fprintf(stdout, "\n======== m_i_typedef test ======\n\n");
+ mai = erl_format("[{hej, 1, 23}, \"string\", {1.23, 45}]");
+ tl = m_i_typedef_test(NULL, mai, &mbi, &mao, &mbo, env);
+ CHECK_EXCEPTION(env);
+ RETURN_IF_OK(erl_match(mai, mao) && cmp_port(&mbi, &mbo) && tl == 4711);
+ if (!erl_match(mai, mao)) {
+ fprintf(stdout, " out parameter error (term), sent:\n");
+ print_term(mai);
+ fprintf(stdout, "got:\n");
+ print_term(mao);
+ }
+ if (!cmp_port(&mbi, &mbo)) {
+ fprintf(stdout, " out parameter error (port), sent:\n");
+ print_port(&mbi);
+ fprintf(stdout, "got:\n");
+ print_port(&mbo);
+ }
+ if (tl != 4711) {
+ fprintf(stdout, " result error, sent: 4711, got %ld\n", tl);
+ }
+ erl_free_term(mai);
+ erl_free_term(mao);
+ return -1;
+}
+
+static int inline_sequence_test(IC_Env *env)
+{
+ int i;
+ long al[500];
+ m_s isi = {4711, {500, 10, al}},
+ *iso, *isr;
+
+ for (i = 0; i < 500; i++)
+ al[i]=i;
+ fprintf(stdout, "\n======== m_i_inline_sequence test ======\n\n");
+ isr = m_i_inline_sequence_test(NULL, &isi, &iso, env);
+ CHECK_EXCEPTION(env);
+ RETURN_IF_OK(cmp_s(&isi, iso) && cmp_s(&isi, isr));
+ if (!cmp_s(&isi, iso)) {
+ fprintf(stdout, " out parameter error, sent:\n");
+ print_s(&isi);
+ fprintf(stdout, "got:\n");
+ print_s(iso);
+ }
+ if (!cmp_s(&isi, isr)) {
+ fprintf(stdout, " result error, sent:\n");
+ print_s(&isi);
+ fprintf(stdout, "got:\n");
+ print_s(isr);
+ }
+ CORBA_free(iso);
+ CORBA_free(isr);
+ return -1;
+}
+
+static int term_sequence_test(IC_Env *env)
+{
+ ETERM* et_array[4] = {
+ erl_format("[{apa, 1, 23}, \"string\", {1.23, 45}]"),
+ erl_format("[{banan, 1, 23}, \"string\", {1.23, 45}]"),
+ erl_format("[{apelsin, 1, 23}, \"string\", {1.23, 45}]"),
+ erl_format("[{mango, 1, 23}, \"string\", {1.23, 45}]")};
+ m_etseq etsi = {4, 4, et_array}, *etso, *etsr;
+
+ fprintf(stdout, "\n======== m_i_term_sequence test ======\n\n");
+ etsr = m_i_term_sequence_test(NULL, &etsi, &etso, env);
+ CHECK_EXCEPTION(env);
+ RETURN_IF_OK(cmp_etseq(&etsi, etso) && cmp_etseq(&etsi, etsr));
+ if (!cmp_etseq(&etsi, etso)) {
+ fprintf(stdout, " out parameter error, sent:\n");
+ print_etseq(&etsi);
+ fprintf(stdout, "got:\n");
+ print_etseq(etso);
+ }
+ if (!cmp_etseq(&etsi, etsr)) {
+ fprintf(stdout, " result error, sent:\n");
+ print_etseq(&etsi);
+ fprintf(stdout, "got:\n");
+ print_etseq(etsr);
+ }
+ free_etseq_buf(&etsi);
+ free_etseq_buf(etso);
+ free_etseq_buf(etsr);
+ CORBA_free(etso);
+ CORBA_free(etsr);
+ return -1;
+}
+
+static int term_struct_test(IC_Env *env)
+{
+ m_et eti = { erl_format("[{hej, 1, 23}, \"string\", {1.23, 45}]"),
+ 121212 };
+ m_et eto, etr;
+
+ fprintf(stdout, "\n======== m_i_term_struct test ======\n\n");
+ etr = m_i_term_struct_test(NULL, &eti, &eto, env);
+ CHECK_EXCEPTION(env);
+ RETURN_IF_OK(cmp_et(&eti, &eto) && cmp_et(&eti, &etr));
+ if (!cmp_et(&eti, &eto)) {
+ fprintf(stdout, " out parameter error, sent:\n");
+ print_et(&eti);
+ fprintf(stdout, "got:\n");
+ print_et(&eto);
+ }
+ if (!cmp_et(&eti, &etr)) {
+ fprintf(stdout, " result error, sent:\n");
+ print_et(&eti);
+ fprintf(stdout, "got:\n");
+ print_et(&etr);
+ }
+ free_et(&eti);
+ free_et(&eto);
+ free_et(&etr);
+ return -1;
+}
+
+static int wstring1_test(IC_Env *env)
+{
+ CORBA_wchar wsi[] = {100, 101, 102, 103, 104, 0}, *wso, *wsr;
+
+ fprintf(stdout, "\n======== m_i_wstring1 test ======\n\n");
+ wsr = m_i_wstring1_test(NULL, wsi, &wso, env);
+ CHECK_EXCEPTION(env);
+ RETURN_IF_OK(cmp_wstr(wsi, wso) && cmp_wstr(wsi, wsr));
+ if (!cmp_wstr(wsi, wso)) {
+ fprintf(stdout, " out parameter error, sent: \n");
+ print_wstr(wsi);
+ fprintf(stdout, "got:\n");
+ print_wstr(wso);
+ }
+ if (!cmp_wstr(wsi, wsr)) {
+ fprintf(stdout, " result error, sent: \n");
+ print_wstr(wsi);
+ fprintf(stdout, "got:\n");
+ print_wstr(wsr);
+ }
+ CORBA_free(wso);
+ CORBA_free(wsr);
+ return -1;
+}
+
+/* Compare functions */
+static int cmp_aseq(m_aseq *a1, m_aseq *a2)
+{
+ int i;
+
+ if (a1->_length != a2->_length)
+ return 0;
+ for (i = 0; i < a1->_length; i++)
+ if (cmp_a(&(a1->_buffer[i]), &(a2->_buffer[i])) == 0)
+ return 0;
+ return 1;
+}
+
+static int cmp_a(m_a *a1, m_a *a2)
+{
+ return a1->l == a2->l &&
+ a1->d == a2->d &&
+ cmp_bseq(&a1->y, &a2->y);
+}
+
+static int cmp_bseq(m_bseq *b1, m_bseq *b2)
+{
+ int i;
+
+ if (b1->_length != b2->_length)
+ return 0;
+ for (i = 0; i < b1->_length; i++)
+ if (cmp_b(&(b1->_buffer[i]), &(b2->_buffer[i])) == 0)
+ return 0;
+ return 1;
+}
+
+static int cmp_b(m_b *b1, m_b *b2)
+{
+ return b1->l == b2->l && b1->c == b2->c;
+}
+
+static int cmp_lseq(m_lseq *b1, m_lseq *b2)
+{
+ int i;
+
+ if (b1->_length != b2->_length)
+ return 0;
+ for (i = 0; i < b1->_length; i++)
+ if (b1->_buffer[i] != b2->_buffer[i])
+ return 0;
+ return 1;
+}
+
+static int cmp_etseq(m_etseq *b1, m_etseq *b2)
+{
+ int i;
+
+ if (b1->_length != b2->_length)
+ return 0;
+ for (i = 0; i < b1->_length; i++)
+ if (!erl_match(b1->_buffer[i], b2->_buffer[i]))
+ return 0;
+ return 1;
+}
+
+static int cmp_et(m_et* b1, m_et *b2)
+{
+ return erl_match(b1->e, b2->e) && b1->l == b2->l;
+}
+
+static int cmp_es(m_es *b1, m_es *b2)
+{
+ return b1->f == b2->f && b1->l == b2->l;
+}
+
+static int cmp_arr1(m_arr1 b1, m_arr1 b2)
+{
+ int i;
+
+ for (i = 0; i < 500; i++)
+ if (b1[i] != b2[i])
+ return 0;
+ return 1;
+}
+
+static int cmp_dd(m_dd b1, m_dd b2)
+{
+
+ int i, j;
+
+ for (i = 0; i < 2; i++)
+ for (j = 0; j < 3; j++)
+ if (b1[i][j] != b2[i][j])
+ return 0;
+ return 1;
+}
+
+
+
+static int cmp_strRec(m_strRec *b1, m_strRec *b2)
+{
+ int i, j;
+
+ if (b1->bb != b2->bb)
+ return 0;
+ if (!cmp_str(b1->str4,b2->str4))
+ return 0;
+ if (b1->str5._length != b2->str5._length)
+ return 0;
+ for (j = 0; j < b1->str5._length; j++)
+ if (b1->str5._buffer[j] != b2->str5._buffer[j])
+ return 0;
+ if (!cmp_str(b1->str6,b2->str6))
+ return 0;
+ for (i = 0; i < 2; i++)
+ for (j = 0; j < 3; j++)
+ if (b1->str7[i][j] != b2->str7[i][j])
+ return 0;
+ for (j = 0; j < 3; j++)
+ if (b1->str8[j] != b2->str8[j])
+ return 0;
+ if (!cmp_str(b1->str9,b2->str9))
+ return 0;
+ if (b1->str10._length != b2->str10._length)
+ return 0;
+ for (j = 0; j < b1->str10._length; j++)
+ if (b1->str10._buffer[j] != b2->str10._buffer[j])
+ return 0;
+ return 1;
+}
+
+
+static int cmp_sseq(m_sseq *b1, m_sseq *b2)
+{
+ int i;
+
+ if (b1->_length != b2->_length)
+ return 0;
+ for (i = 0; i < b1->_length; i++)
+ if (!cmp_str(b1->_buffer[i], b2->_buffer[i]))
+ return 0;
+ return 1;
+}
+
+
+static int cmp_pid(erlang_pid *p1, erlang_pid *p2)
+{
+ return cmp_str(p1->node,p2-> node) &&
+ p1->num == p2->num &&
+ p1->serial == p2->serial &&
+ p1->creation == p2->creation;
+}
+
+static int cmp_port(erlang_port *p1, erlang_port *p2)
+{
+ return cmp_str(p1->node,p2-> node) && p1->id == p2->id;
+}
+
+static int cmp_ref(erlang_ref *p1, erlang_ref *p2)
+{
+ return cmp_str(p1->node, p2->node) &&
+ p1->len == p2->len &&
+ (p1->len < 1 || p1->n[0] == p2->n[0]) &&
+ (p1->len < 2 || p1->n[1] == p2->n[1]) &&
+ (p1->len < 3 || p1->n[2] == p2->n[2]);
+}
+
+static int cmp_s(m_s *b1, m_s *b2)
+{
+ int i;
+
+ if (b1->l != b2->l)
+ return 0;
+ if (b1->sl._length != b2->sl._length)
+ return 0;
+ for (i = 0; i < b1->sl._length; i++)
+ if (b1->sl._buffer[i] != b2->sl._buffer[i])
+ return 0;
+ return 1;
+}
+
+
+static int cmp_ssstr3(m_ssstr3 *b1, m_ssstr3 *b2)
+{
+ int i,j;
+
+ if (b1->_length != b2->_length)
+ return 0;
+ for (i = 0; i < b1->_length; i++) {
+ if (b1->_buffer[i]._length != b2->_buffer[i]._length)
+ return 0;
+ for (j = 0; j < b1->_buffer[i]._length; j++)
+ if (!cmp_str(b1->_buffer[i]._buffer[j],
+ b2->_buffer[i]._buffer[j]))
+ return 0;
+ }
+ return 1;
+}
+
+
+
+static int cmp_ssarr3(m_ssarr3 *b1, m_ssarr3 *b2)
+{
+ int i;
+
+ if (b1->_length != b2->_length)
+ return 0;
+ for (i = 0; i < b1->_length; i++) {
+ if (!cmp_sarr3(&b1->_buffer[i], &b2->_buffer[i]))
+ return 0;
+ }
+ return 1;
+}
+
+static int cmp_sarr3(m_sarr3 *b1, m_sarr3 *b2)
+{
+ int i;
+
+ if (b1->_length != b2->_length)
+ return 0;
+ for (i = 0; i < b1->_length; i++) {
+ if (!cmp_arr3(b1->_buffer[i], b2->_buffer[i]))
+ return 0;
+ }
+ return 1;
+}
+
+static int cmp_arr3(m_arr3 b1, m_arr3 b2)
+{
+ int i;
+
+ for (i = 0; i < sizeof(m_arr3)/sizeof(CORBA_long); i++) {
+ if (b1[i] != b2[i])
+ return 0;
+ }
+ return 1;
+}
+
+/* Print functions */
+static void print_aseq(m_aseq *a)
+{
+ int i;
+ fprintf(stdout, "\nm_aseq size: %ld --------\n", a->_length);
+ for (i = 0; i < a->_length; i++)
+ print_a(&(a->_buffer[i]));
+}
+
+static void print_a(m_a *a)
+{
+ fprintf(stdout, "\nm_a --------\n l: %ld\n d:%f\n", a->l, a->d);
+ print_bseq(&a->y);
+}
+
+static void print_bseq(m_bseq *b)
+{
+ int i;
+
+ fprintf(stdout, "\nm_bseq size: %ld --------\n",b->_length);
+ for (i = 0; i < b->_length; i++)
+ print_b(&(b->_buffer[i]));
+}
+
+static void print_lseq(m_lseq *b)
+{
+ int i;
+
+ fprintf(stdout, "\nm_lseq size: %ld --------\n",b->_length);
+ for (i = 0; i < b->_length; i++)
+ fprintf(stdout, "[%d]: %ld\n", i, b->_buffer[i]);
+}
+
+static void print_b(m_b *b)
+{
+ fprintf(stdout, "\nm_b --------\n l: %ld\n c: %c\n", b->l, b->c);
+}
+
+
+static void print_etseq(m_etseq *b)
+{
+ int i;
+
+ for (i = 0; i < b->_length; i++) {
+ fprintf(stdout, "[%d]:\n", i);
+ erl_print_term(stdout, b->_buffer[i]);
+ }
+}
+
+
+static void print_et(m_et* b)
+{
+ fprintf(stdout, "\net struct --------\n");
+ erl_print_term(stdout, b->e);
+ fprintf(stdout, "long: %ld\n", b->l);
+ fprintf(stdout, "\n--------\n");
+}
+
+static void print_es(m_es *b)
+{
+ fprintf(stdout, "\nm_es --------\n f: %d\n l: %ld\n", b->f, b->l);
+}
+
+
+static void print_arr1(long a[10])
+{
+ int i;
+
+ for (i = 0; i < 10; i++)
+ fprintf(stdout, "\n[%d]: %ld\n", i, a[i]);
+}
+
+static void print_dd(long a[2][3])
+{
+ int i, j;
+
+ fprintf(stdout, "\nlong dd[2][3] --------\n");
+ for (i = 0; i < 2; i++)
+ for (j = 0; j < 3; j++)
+ fprintf(stdout, "\n[%d][%d]: %ld\n", i, j, a[i][j]);
+}
+
+
+static void print_strRec(m_strRec* sr)
+{
+ int i, j;
+
+ fprintf(stdout, "\nboolean bb : %d\n",sr->bb);
+ fprintf(stdout, "string str4 : %s\n",sr->str4);
+ fprintf(stdout, "str7[2][3] :\n");
+ for (i = 0; i < 2; i++)
+ for (j = 0; j < 3; j++)
+ fprintf(stdout, "str7[%d][%d]: %ld\n", i, j, sr->str7[i][j]);
+ fprintf(stdout, "str5._length : %ld\n",sr->str5._length);
+ for (j = 0; j < sr->str5._length; j++)
+ fprintf(stdout, "str5._buffer[%d]: %c\n", j, sr->str5._buffer[j]);
+ fprintf(stdout, "string str6 : %s\n",sr->str6);
+ fprintf(stdout, "str8 :\n");
+ for (j = 0; j < 3; j++)
+ fprintf(stdout, "str8[%d]: %c\n", j, sr->str8[j]);
+ fprintf(stdout, "string str9 : %s\n",sr->str9);
+ fprintf(stdout, "str10._length : %ld\n",sr->str10._length);
+ for (j = 0; j < sr->str10._length; j++)
+ fprintf(stdout, "str10._buffer[%d]: %c\n", j, sr->str10._buffer[j]);
+}
+
+static void print_sseq(m_sseq *b)
+{
+ int i;
+
+ fprintf(stdout, "\nm_sseq size: %ld --------\n",b->_length);
+ for (i = 0; i < b->_length; i++)
+ fprintf(stdout, "%s\n", b->_buffer[i]);
+
+}
+
+
+static void print_pid(erlang_pid *p)
+{
+ fprintf(stdout, "\nerlang_pid --------\n node: %s\n num: %d\n "
+ "serial: %d\n creation: %d\n",
+ p->node, p->num, p->serial, p->creation);
+}
+
+static void print_port(erlang_port *p)
+{
+ fprintf(stdout, "\nerlang_port --------\n node: %s\n id: %d\n "
+ "creation: %d\n", p->node, p->id, p->creation);
+}
+
+static void print_ref(erlang_ref *p)
+{
+ fprintf(stdout, "\nerlang_ref --------\n node: %s\n len: %d\n "
+ "n[0]: %d\n n[1]: %d\n n[2]: %d\n creation: %d\n",
+ p->node, p->len, p->n[0], p->n[1], p->n[2], p->creation);
+}
+
+static void print_term(ETERM *t)
+{
+ fprintf(stdout, "\nETERM --------\n");
+ erl_print_term(stdout, t);
+ fprintf(stdout, "\n--------\n");
+}
+
+static void print_s(m_s *p)
+{
+ int i;
+
+ fprintf(stdout, "\n%ld\n", p->l);
+ for (i = 0; i < p->sl._length; i++)
+ fprintf(stdout, "\n[%d]: %ld\n", i, p->sl._buffer[i]);
+}
+
+
+static void print_ssstr3(m_ssstr3 *b1)
+{
+ int i,j;
+
+ fprintf(stdout, "\nSSSTR3 --------\n");
+ fprintf(stdout,"b1->_length = %ld\n",b1->_length);
+ for (i = 0; i < b1->_length; i++) {
+ fprintf(stdout,"\nb1->_buffer[%d]._length %ld\n",
+ i, b1->_buffer[i]._length);
+ for (j = 0; j < b1->_buffer[i]._length; j++)
+ fprintf(stdout,"b1->_buffer[%d]._buffer[%d] = %s\n",
+ i, j, b1->_buffer[i]._buffer[j]);
+ }
+ fprintf(stdout, "\n--------\n");
+}
+
+static void print_wstr(CORBA_wchar *ws)
+{
+ int i = 0;
+
+ fprintf(stdout, "\nwstr --------\n");
+ while (ws[i]) {
+ fprintf(stdout, "[%d]: %ld\n", i, ws[i]);
+ i++;
+ }
+ fprintf(stdout, "\n--------\n");
+}
+
+
+static void print_ssarr3(m_ssarr3 *b1)
+{
+ int i;
+
+ fprintf(stdout, "\nssarr3 --------\n");
+ fprintf(stdout,"length: %ld\n",b1->_length);
+ fprintf(stdout, "buffer:\n");
+ for (i = 0; i < b1->_length; i++)
+ print_sarr3(&b1->_buffer[i]);
+ fprintf(stdout, "\n--------\n");
+}
+
+static void print_sarr3(m_sarr3 *b1)
+{
+ int i;
+
+ fprintf(stdout, "\nsarr3 --------\n");
+ fprintf(stdout,"length: %ld\n",b1->_length);
+ fprintf(stdout, "buffer:\n");
+ for (i = 0; i < b1->_length; i++)
+ print_arr3(b1->_buffer[i]);
+ fprintf(stdout, "\n--------\n");
+}
+
+static void print_arr3(m_arr3 b1)
+{
+ int i;
+
+ fprintf(stdout, "\narr3 --------\n");
+ for (i = 0; i < sizeof(m_arr3)/sizeof(CORBA_long); i++)
+ fprintf(stdout, "%ld ", b1[i]);
+ fprintf(stdout, "\n--------\n");
+}
+
+static void free_etseq_buf(m_etseq *b)
+{
+ int i;
+
+ for (i = 0; i < b->_length; i++)
+ erl_free_term(b->_buffer[i]);
+}
+
+static void free_et(m_et* b)
+{
+ erl_free_term(b->e);
+}
+
+static void showtime(MyTimeval *start, MyTimeval *stop)
+{
+ MyTimeval elapsed;
+
+ elapsed.tv_sec = stop->tv_sec - start->tv_sec;
+ elapsed.tv_usec = stop->tv_usec - start->tv_usec;
+ while (elapsed.tv_usec < 0) {
+ elapsed.tv_sec -= 1;
+ elapsed.tv_usec += 1000000;
+ }
+ fprintf(stderr,"%ld.%06ld seconds\n",elapsed.tv_sec, elapsed.tv_usec);
+}
+
+static void my_gettimeofday(MyTimeval *tv)
+#ifdef __WIN32__
+#define EPOCH_JULIAN_DIFF 11644473600i64
+{
+ SYSTEMTIME t;
+ FILETIME ft;
+ LONGLONG lft;
+
+ GetSystemTime(&t);
+ SystemTimeToFileTime(&t, &ft);
+ memcpy(&lft, &ft, sizeof(lft));
+ tv->tv_usec = (long) ((lft / 10i64) % 1000000i64);
+ tv->tv_sec = (long) ((lft / 10000000i64) - EPOCH_JULIAN_DIFF);
+}
+#elif defined VXWORKS
+{
+ int rate = sysClkRateGet(); /* Ticks per second */
+ unsigned long ctick = tickGet();
+ tv->tv_sec = ctick / rate; /* secs since reboot */
+ tv->tv_usec = ((ctick - (tv->tv_sec * rate))*1000000)/rate;
+}
+#else
+{
+ gettimeofday(tv, NULL);
+}
+#endif
diff --git a/lib/ic/test/c_client_erl_server_SUITE_data/c_erl_test.idl b/lib/ic/test/c_client_erl_server_SUITE_data/c_erl_test.idl
new file mode 100644
index 0000000000..ccb8f54508
--- /dev/null
+++ b/lib/ic/test/c_client_erl_server_SUITE_data/c_erl_test.idl
@@ -0,0 +1,174 @@
+
+
+// %CopyrightBegin%
+//
+// Copyright Ericsson AB 2001-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%
+
+#include "erlang.idl"
+
+
+const short TestConst = 1;
+
+module m {
+
+ const short TestConst = 2;
+
+ struct b {
+ long l;
+ char c;
+ };
+
+ struct simple {
+ long l;
+ b b_t;
+ };
+
+ enum fruit {orange, banana, apple, peach, pear};
+
+ typedef sequence<long> lseq;
+
+ typedef sequence<b> bseq;
+
+ struct a {
+ long l;
+ bseq y;
+ double d;
+ };
+
+ typedef sequence<a> aseq;
+
+ typedef sequence<string> sseq;
+ typedef string str;
+ typedef long myLong;
+
+ typedef long arr1[500], dd[2][3];
+
+ typedef erlang::term apa;
+ typedef erlang::port banan;
+
+ typedef sequence<erlang::term> etseq;
+
+ struct s {
+ long l;
+ sequence<long> sl;
+ };
+
+ struct es {
+ fruit f;
+ myLong l;
+ };
+
+ struct et {
+ erlang::term e;
+ long l;
+ };
+
+
+ typedef sequence<char> str1;
+ typedef string<12> str2;
+ typedef char str3[3];
+
+ typedef sequence<string> sstr3; // sequence of string
+ typedef sequence<sstr3> ssstr3; // sequence of sequences of strings
+
+ typedef long arr3[3]; // array of long
+ typedef sequence<arr3> sarr3; // sequence of array
+ typedef sequence<sarr3> ssarr3; // sequence of sequnces of arrays of strings
+
+ struct strRec{
+ boolean bb;
+ string str4;
+ long str7[3][2];
+ sequence<char> str5;
+ string<12> str6;
+ str3 str8;
+ str2 str9;
+ str1 str10;
+ };
+
+
+ struct dyn {
+ long l;
+ sequence<long> sl;
+ };
+ typedef dyn arr2[1][2];
+
+
+ interface i {
+
+ const short TestConst = 3;
+
+ //arr2 suck(in arr2 x, out arr2 y );
+
+ ///////////////////////////////// attribute long l;
+
+ // simple types
+ void void_test();
+ long long_test(in long a, out long a1);
+ long long longlong_test(in long long a, out long long a1);
+ unsigned short ushort_test(in unsigned short a, out unsigned short a1);
+ unsigned long ulong_test(in unsigned long a, out unsigned long a1);
+ unsigned long long ulonglong_test(in unsigned long long a, out unsigned long long a1);
+ double double_test(in double a, out double a1);
+ char char_test(in char a, out char a1);
+ wchar wchar_test(in wchar a, out wchar a1);
+ octet octet_test(in octet a, out octet a1);
+ boolean bool_test(in boolean a, out boolean a1);
+
+ // Seq. and struct tests
+ b struct_test(in b a, out b a1);
+ es struct2_test(in es a, out es a1);
+ //simple struct3_test(in simple x, out simple y);
+ bseq seq1_test(in bseq a, out bseq a1);
+ aseq seq2_test(in aseq a, out aseq a1);
+ lseq seq3_test(in lseq a, out lseq a1);
+ ssstr3 seq4_test(in ssstr3 a, out ssstr3 a1);
+ ssarr3 seq5_test(in ssarr3 a, out ssarr3 a1);
+
+ // Array tests
+ arr1 array1_test(in arr1 a, out arr1 a1);
+ dd array2_test(in dd a, out dd a1);
+
+ // enum test
+ fruit enum_test(in fruit a, out fruit a1);
+
+ // string tests
+ string string1_test(in string a, out string a1);
+ wstring wstring1_test(in wstring a, out wstring a1);
+ sseq string2_test(in sseq a, out sseq a1);
+ str string3_test(in str a, out str a1);
+ strRec string4_test(in strRec a, out strRec a1);
+
+ // Special erlang types
+ erlang::pid pid_test(in erlang::pid a, out erlang::pid a1);
+ erlang::port port_test(in erlang::port a, out erlang::port a1);
+ erlang::ref ref_test(in erlang::ref a, out erlang::ref a1);
+ erlang::term term_test(in erlang::term a, out erlang::term a1);
+
+ // typedef test
+ long typedef_test(in apa a, in banan b, out apa a1, out banan b1);
+
+ // inlined seq. test
+ s inline_sequence_test(in s a, out s a1);
+
+ // term seq. test
+ etseq term_sequence_test(in etseq a, out etseq a1);
+ // term struct test
+ et term_struct_test(in et a, out et a1);
+
+ };
+
+};
diff --git a/lib/ic/test/c_client_erl_server_SUITE_data/erl_server.erl b/lib/ic/test/c_client_erl_server_SUITE_data/erl_server.erl
new file mode 100644
index 0000000000..dffbbb059c
--- /dev/null
+++ b/lib/ic/test/c_client_erl_server_SUITE_data/erl_server.erl
@@ -0,0 +1,28 @@
+%%
+%% %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(erl_server).
+
+-export([run/0, stop/0]).
+
+run() ->
+ m_i:oe_create().
+
+stop() ->
+ gen_server:cast(cidl_test, stop).
diff --git a/lib/ic/test/c_client_erl_server_SUITE_data/m_i_impl.erl b/lib/ic/test/c_client_erl_server_SUITE_data/m_i_impl.erl
new file mode 100644
index 0000000000..cfcaa793a5
--- /dev/null
+++ b/lib/ic/test/c_client_erl_server_SUITE_data/m_i_impl.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(m_i_impl).
+-include("m.hrl").
+
+-export([init/1, terminate/2, void_test/1, long_test/2, ushort_test/2,
+ longlong_test/2, ulong_test/2, ulonglong_test/2,
+ double_test/2, char_test/2, wchar_test/2, octet_test/2,
+ bool_test/2, struct_test/2, struct2_test/2, seq1_test/2,
+ seq2_test/2, seq3_test/2, seq4_test/2, seq5_test/2,
+ array1_test/2, array2_test/2, enum_test/2, string1_test/2,
+ string2_test/2, string3_test/2, string4_test/2, pid_test/2,
+ port_test/2, ref_test/2, term_test/2, typedef_test/3,
+ inline_sequence_test/2, '_set_l'/2, '_get_l'/1,
+ term_struct_test/2, term_sequence_test/2, wstring1_test/2]).
+
+-define(PRINTDEBUG(Case),
+ io:format("erl_server: case: ~p~n"
+ "erl_server: location: ~p~n", [Case, [?FILE, ?LINE]])).
+-define(PRINTDEBUG2(Case, Msg),
+ io:format("erl_server: case: ~p~n"
+ "erl_server: Msg: ~p~n"
+ "erl_server: location: ~p~n", [Case, Msg, [?FILE, ?LINE]])).
+
+init(Env) ->
+ {ok, []}.
+
+terminate(F, R) ->
+ ok.
+
+'_get_l'(State) ->
+ ?PRINTDEBUG("_get_l"),
+ {reply, State, State}.
+void_test(State) ->
+ ?PRINTDEBUG("void_test"),
+ {reply, ok, State}.
+
+'_set_l'(State, V) ->
+ ?PRINTDEBUG2("_set_l", V),
+ {reply, ok, V}.
+ushort_test(State, V) ->
+ ?PRINTDEBUG2("ushort_test", V),
+ {reply, {V, V}, State}.
+long_test(State, V) ->
+ ?PRINTDEBUG2("long_test", V),
+ {reply, {V, V}, State}.
+longlong_test(State, V) ->
+ ?PRINTDEBUG2("longlong_test", V),
+ {reply, {V, V}, State}.
+ulong_test(State, V) ->
+ ?PRINTDEBUG2("ulong_test", V),
+ {reply, {V, V}, State}.
+ulonglong_test(State, V) ->
+ ?PRINTDEBUG2("ulonglong_test", V),
+ {reply, {V, V}, State}.
+double_test(State, V) ->
+ ?PRINTDEBUG2("double_test", V),
+ {reply, {V, V}, State}.
+char_test(State, V) ->
+ ?PRINTDEBUG2("char_test", V),
+ {reply, {V, V}, State}.
+wchar_test(State, V) ->
+ ?PRINTDEBUG2("wchar_test", V),
+ {reply, {V, V}, State}.
+octet_test(State, V) ->
+ ?PRINTDEBUG2("octet_test", V),
+ {reply, {V, V}, State}.
+bool_test(State, V) ->
+ ?PRINTDEBUG2("bool_test", V),
+ {reply, {V, V}, State}.
+
+struct_test(State, V) ->
+ ?PRINTDEBUG2("struct_test", V),
+ {reply, {V, V}, State}.
+struct2_test(State, V) ->
+ ?PRINTDEBUG2("struct2_test", V),
+ {reply, {V, V}, State}.
+seq1_test(State, V) ->
+ ?PRINTDEBUG2("seq1_test", V),
+ {reply, {V, V}, State}.
+seq2_test(State, V) ->
+ ?PRINTDEBUG2("seq2_test", V),
+ {reply, {V, V}, State}.
+seq3_test(State, V) ->
+ ?PRINTDEBUG2("seq3_test", V),
+ {reply, {V, V}, State}.
+seq4_test(State, V) ->
+ ?PRINTDEBUG2("seq4_test", V),
+ {reply, {V, V}, State}.
+seq5_test(State, V) ->
+ ?PRINTDEBUG2("seq5_test", V),
+ {reply, {V, V}, State}.
+array1_test(State, V) ->
+ ?PRINTDEBUG2("array1_test", V),
+ {reply, {V, V}, State}.
+array2_test(State, V) ->
+ ?PRINTDEBUG2("array2_test", V),
+ {reply, {V, V}, State}.
+enum_test(State, V) ->
+ ?PRINTDEBUG2("enum_test", V),
+ {reply, {V, V}, State}.
+string1_test(State, V) ->
+ ?PRINTDEBUG2("string1_test", V),
+ {reply, {V, V}, State}.
+string2_test(State, V) ->
+ ?PRINTDEBUG2("string2_test", V),
+ {reply, {V, V}, State}.
+string3_test(State, V) ->
+ ?PRINTDEBUG2("string3_test", V),
+ {reply, {V, V}, State}.
+string4_test(State, V) ->
+ ?PRINTDEBUG2("string4_test", V),
+ {reply, {V, V}, State}.
+pid_test(State, V) ->
+ ?PRINTDEBUG2("pid_test", V),
+ {reply, {V, V}, State}.
+port_test(State, V) ->
+ ?PRINTDEBUG2("port_test", binary_to_list(term_to_binary(V))),
+ {reply, {V, V}, State}.
+ref_test(State, V) ->
+ ?PRINTDEBUG2("ref_test", binary_to_list(term_to_binary(V))),
+ {reply, {V, V}, State}.
+term_test(State, V) ->
+ ?PRINTDEBUG2("term_test", V),
+ {reply, {V, V}, State}.
+typedef_test(State, A, B) ->
+ ?PRINTDEBUG2("typedef_test", [A,B]),
+ {reply, {4711, A, B}, State}.
+inline_sequence_test(State, V) ->
+ ?PRINTDEBUG2("inline_sequence_test", V),
+ {reply, {V, V}, State}.
+term_sequence_test(State, V) ->
+ ?PRINTDEBUG2("term_sequence_test", V),
+ {reply, {V, V}, State}.
+term_struct_test(State, V) ->
+ ?PRINTDEBUG2("term_struct_test", V),
+ {reply, {V, V}, State}.
+wstring1_test(State, V) ->
+ ?PRINTDEBUG2("wstring1_test", V),
+ {reply, {V, V}, State}.
+
+
+
+
diff --git a/lib/ic/test/c_client_erl_server_proto_SUITE.erl b/lib/ic/test/c_client_erl_server_proto_SUITE.erl
new file mode 100644
index 0000000000..58309a2221
--- /dev/null
+++ b/lib/ic/test/c_client_erl_server_proto_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%
+%%
+%%
+
+%%----------------------------------------------------------------------
+%% Purpose : Test suite for c-client/erl-server
+%%----------------------------------------------------------------------
+
+-module(c_client_erl_server_proto_SUITE).
+-include("test_server.hrl").
+
+-export([init_per_testcase/2, fin_per_testcase/2,
+ all/1, void_test/1, long_test/1, long_long_test/1,
+ unsigned_short_test/1, unsigned_long_test/1,
+ unsigned_long_long_test/1, double_test/1, char_test/1,
+ wchar_test/1, octet_test/1, bool_test/1, struct_test/1,
+ struct2_test/1, seq1_test/1, seq2_test/1, seq3_test/1,
+ seq4_test/1, seq5_test/1, array1_test/1, array2_test/1,
+ enum_test/1, string1_test/1, string2_test/1, string3_test/1,
+ string4_test/1, pid_test/1, port_test/1, ref_test/1, term_test/1,
+ typedef_test/1, inline_sequence_test/1, term_sequence_test/1,
+ term_struct_test/1, wstring1_test/1]).
+
+-define(DEFAULT_TIMEOUT, 20000).
+-define(PORT_TIMEOUT, 15000).
+-define(ERLANG_SERVER_NAME, idl_erlang_server).
+-define(C_CLIENT_NODE_NAME, c_client_idl_test).
+
+%% Add/remove code path and watchdog before/after each test case.
+%%
+init_per_testcase(_Case, Config) ->
+ DataDir = ?config(data_dir, Config),
+ code:add_patha(DataDir),
+
+ %% Since other test suites use the module m_i, we have
+ %% to make sure we are using the right m_i module.
+ code:purge(m_i),
+ code:load_file(m_i),
+
+ WatchDog = test_server:timetrap(?DEFAULT_TIMEOUT),
+ [{watchdog, WatchDog}| Config].
+
+fin_per_testcase(_Case, Config) ->
+ DataDir = ?config(data_dir, Config),
+ code:del_path(DataDir),
+ WatchDog = ?config(watchdog, Config),
+ test_server:timetrap_cancel(WatchDog).
+
+all(doc) ->
+ "Test of IC with a C-client and an Erlang generic server. "
+ "The communication is via Erlang distribution.";
+all(suite) ->
+ [void_test, long_test, long_long_test, unsigned_short_test,
+ unsigned_long_test, unsigned_long_long_test, double_test,
+ char_test, wchar_test, octet_test, bool_test, struct_test,
+ struct2_test, seq1_test, seq2_test, seq3_test, seq4_test,
+ seq5_test, array1_test, array2_test, enum_test, string1_test,
+ string2_test, string3_test, string4_test, pid_test, port_test,
+ ref_test, term_test, typedef_test, inline_sequence_test,
+ term_sequence_test, term_struct_test, wstring1_test].
+
+
+array1_test(doc) -> "";
+array1_test(suite) -> [];
+array1_test(Config) ->
+ do_test(array1_test, Config).
+
+array2_test(doc) -> "";
+array2_test(suite) -> [];
+array2_test(Config) ->
+ do_test(array2_test, Config).
+
+bool_test(doc) -> "";
+bool_test(suite) -> [];
+bool_test(Config) ->
+ do_test(bool_test, Config).
+
+char_test(doc) -> "";
+char_test(suite) -> [];
+char_test(Config) ->
+ do_test(char_test, Config).
+
+double_test(doc) -> "";
+double_test(suite) -> [];
+double_test(Config) ->
+ do_test(double_test, Config).
+
+enum_test(doc) -> "";
+enum_test(suite) -> [];
+enum_test(Config) ->
+ do_test(enum_test, Config).
+
+inline_sequence_test(doc) -> "";
+inline_sequence_test(suite) -> [];
+inline_sequence_test(Config) ->
+ do_test(inline_sequence_test, Config).
+
+long_long_test(doc) -> "";
+long_long_test(suite) -> [];
+long_long_test(Config) ->
+ do_test(long_long_test, Config).
+
+long_test(doc) -> "";
+long_test(suite) -> [];
+long_test(Config) ->
+ do_test(long_test, Config).
+
+octet_test(doc) -> "";
+octet_test(suite) -> [];
+octet_test(Config) ->
+ do_test(octet_test, Config).
+
+pid_test(doc) -> "";
+pid_test(suite) -> [];
+pid_test(Config) ->
+ do_test(pid_test, Config).
+
+port_test(doc) -> "";
+port_test(suite) -> [];
+port_test(Config) ->
+ do_test(port_test, Config).
+
+ref_test(doc) -> "";
+ref_test(suite) -> [];
+ref_test(Config) ->
+ do_test(ref_test, Config).
+
+seq1_test(doc) -> "";
+seq1_test(suite) -> [];
+seq1_test(Config) ->
+ do_test(seq1_test, Config).
+
+seq2_test(doc) -> "";
+seq2_test(suite) -> [];
+seq2_test(Config) ->
+ do_test(seq2_test, Config).
+
+seq3_test(doc) -> "";
+seq3_test(suite) -> [];
+seq3_test(Config) ->
+ do_test(seq3_test, Config).
+
+seq4_test(doc) -> "";
+seq4_test(suite) -> [];
+seq4_test(Config) ->
+ do_test(seq4_test, Config).
+
+seq5_test(doc) -> "";
+seq5_test(suite) -> [];
+seq5_test(Config) ->
+ do_test(seq5_test, Config).
+
+string1_test(doc) -> "";
+string1_test(suite) -> [];
+string1_test(Config) ->
+ do_test(string1_test, Config).
+
+string2_test(doc) -> "";
+string2_test(suite) -> [];
+string2_test(Config) ->
+ do_test(string2_test, Config).
+
+string3_test(doc) -> "";
+string3_test(suite) -> [];
+string3_test(Config) ->
+ do_test(string3_test, Config).
+
+string4_test(doc) -> "";
+string4_test(suite) -> [];
+string4_test(Config) ->
+ do_test(string4_test, Config).
+
+struct2_test(doc) -> "";
+struct2_test(suite) -> [];
+struct2_test(Config) ->
+ do_test(struct2_test, Config).
+
+struct_test(doc) -> "";
+struct_test(suite) -> [];
+struct_test(Config) ->
+ do_test(struct_test, Config).
+
+term_sequence_test(doc) -> "";
+term_sequence_test(suite) -> [];
+term_sequence_test(Config) ->
+ do_test(term_sequence_test, Config).
+
+term_struct_test(doc) -> "";
+term_struct_test(suite) -> [];
+term_struct_test(Config) ->
+ do_test(term_struct_test, Config).
+
+term_test(doc) -> "";
+term_test(suite) -> [];
+term_test(Config) ->
+ do_test(term_test, Config).
+
+typedef_test(doc) -> "";
+typedef_test(suite) -> [];
+typedef_test(Config) ->
+ do_test(typedef_test, Config).
+
+unsigned_long_long_test(doc) -> "";
+unsigned_long_long_test(suite) -> [];
+unsigned_long_long_test(Config) ->
+ do_test(unsigned_long_long_test, Config).
+
+unsigned_long_test(doc) -> "";
+unsigned_long_test(suite) -> [];
+unsigned_long_test(Config) ->
+ do_test(unsigned_long_test, Config).
+
+unsigned_short_test(doc) -> "";
+unsigned_short_test(suite) -> [];
+unsigned_short_test(Config) ->
+ do_test(unsigned_short_test, Config).
+
+void_test(doc) -> "";
+void_test(suite) -> [];
+void_test(Config) ->
+ do_test(void_test, Config).
+
+wchar_test(doc) -> "";
+wchar_test(suite) -> [];
+wchar_test(Config) ->
+ do_test(wchar_test, Config).
+
+wstring1_test(doc) -> "";
+wstring1_test(suite) -> [];
+wstring1_test(Config) ->
+ do_test(wstring1_test, Config).
+
+
+%% It is here that all tests really are done.
+%%
+
+do_test(Case, Config) ->
+ %% Trap exits
+ process_flag(trap_exit, true),
+ %% Start the server
+ {ok, _Pid} = m_i:oe_create_link([], {local, ?ERLANG_SERVER_NAME}),
+ Node = atom_to_list(node()),
+ %% [NodeName, HostName] = string:tokens(Node, "@"),
+ DataDir = ?config(data_dir, Config),
+ %% io:format("~p: data directory: ~p~n", [?MODULE, DataDir]),
+ Cookie = atom_to_list(erlang:get_cookie()),
+ %% Start C-client node as a port program.
+ Cmd = filename:join([DataDir, "c_client"]) ++
+ " -this-node-name " ++ atom_to_list(?C_CLIENT_NODE_NAME) ++
+ " -peer-node " ++ Node ++
+ " -peer-process-name " ++ atom_to_list(?ERLANG_SERVER_NAME) ++
+ " -cookie " ++ Cookie ++
+ " -test-case " ++ atom_to_list(Case),
+ Port = open_port({spawn, Cmd}, [exit_status, eof, stderr_to_stdout]),
+ Res = wait_for_completion(Port),
+ %% Kill off node if there was timeout
+ case Res of
+ {error, timeout} ->
+ catch rpc:cast(?C_CLIENT_NODE_NAME, erlang, halt, [1]);
+ _ ->
+ ok
+ end,
+ process_flag(trap_exit, false),
+ catch m_i:stop(?ERLANG_SERVER_NAME),
+ ok = Res.
+
+
+%% Wait for eof *and* exit status, but return if exit status indicates
+%% an error, or we have been waiting more than PORT_TIMEOUT seconds.
+%%
+wait_for_completion(Port) ->
+ wait_for_completion(Port, 0).
+
+wait_for_completion(Port, N) when N < 2 ->
+ receive
+ {Port, {data, Bytes}} ->
+ %% Relay output
+ io:format("~s", [Bytes]),
+ wait_for_completion(Port, N);
+ {Port, {exit_status, 0}} ->
+ wait_for_completion(Port, N + 1);
+ {Port, {exit_status, Status}} ->
+ {error, Status};
+ {Port, eof} ->
+ wait_for_completion(Port, N + 1);
+ {'EXIT', Port, Reason} ->
+ io:format("Port exited with reason: ~w~n", [Reason]),
+ wait_for_completion(Port, N);
+ {'EXIT', From, Reason} ->
+ io:format("Got unexpected exit: ~p~n", [{'EXIT', From, Reason}]),
+ wait_for_completion(Port, N)
+ after ?PORT_TIMEOUT ->
+ {error, timeout}
+ end;
+wait_for_completion(_, _) ->
+ ok.
+
+
+
diff --git a/lib/ic/test/c_client_erl_server_proto_SUITE_data/Makefile.src b/lib/ic/test/c_client_erl_server_proto_SUITE_data/Makefile.src
new file mode 100644
index 0000000000..3dcd1d9387
--- /dev/null
+++ b/lib/ic/test/c_client_erl_server_proto_SUITE_data/Makefile.src
@@ -0,0 +1,146 @@
+#
+# %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%
+#
+#
+# Makefile.src for c_client_erl_server test
+# Note: This file *must* work for both Unix and Windows
+#
+# We use both `rm' (Unix) and `del' (Windows) for removing files, but
+# with a `-' in front so that the error in not finding `rm' (`del') on
+# Windows (Unix) is ignored.
+#
+# VxWorks? XXX
+#
+
+.SUFFIXES:
+.SUFFIXES: .c .h .erl .idl @obj@ .@EMULATOR@
+
+
+# Variables from ts:
+#
+
+ERL_INCLUDE = @erl_include@
+
+IC_INCLUDE_PATH = @ic_include_path@
+IC_LIB = @ic_libpath@@DS@@ic_lib@
+
+ERL_INTERFACE_INCLUDE = @erl_interface_include@
+ERL_INTERFACE_LIB = @erl_interface_libpath@@DS@@erl_interface_lib@
+ERL_INTERFACE_EILIB = @erl_interface_libpath@@DS@@erl_interface_eilib@
+ERL_INTERFACE_THREADLIB = @erl_interface_threadlib@
+ERL_INTERFACE_SOCK_LIBS = @erl_interface_sock_libs@
+
+CC = @CC@
+## XXX Should set warning flag with a DEBUG_FLAG
+CFLAGS = @CFLAGS@ @DEFS@ -I@erl_include@ \
+ -I@ic_include_path@ -I@erl_interface_include@
+
+LD = @LD@
+LDFLAGS = @CROSSLDFLAGS@
+LIBS = $(IC_LIB) $(ERL_INTERFACE_LIB) $(ERL_INTERFACE_EILIB) \
+ $(ERL_INTERFACE_THREADLIB) @LIBS@ $(ERL_INTERFACE_SOCK_LIBS)
+ERLC = erlc
+
+# Generated C header files
+GEN_H_FILES = \
+ m.h \
+ m_i.h \
+ oe_c_erl_test.h
+
+# Generated C files
+GEN_C_FILES = \
+ m.c \
+ m_i.c \
+ oe_c_erl_test.c \
+ oe_code_m_a.c \
+ oe_code_m_arr1.c \
+ oe_code_m_arr2.c \
+ oe_code_m_arr3.c \
+ oe_code_m_aseq.c \
+ oe_code_m_b.c \
+ oe_code_m_bseq.c \
+ oe_code_m_dd.c \
+ oe_code_m_dyn.c \
+ oe_code_m_dyn_sl.c \
+ oe_code_m_es.c \
+ oe_code_m_et.c \
+ oe_code_m_etseq.c \
+ oe_code_m_fruit.c \
+ oe_code_m_lseq.c \
+ oe_code_m_s.c \
+ oe_code_m_s_sl.c \
+ oe_code_m_sarr3.c \
+ oe_code_m_simple.c \
+ oe_code_m_ssarr3.c \
+ oe_code_m_sseq.c \
+ oe_code_m_ssstr3.c \
+ oe_code_m_sstr3.c \
+ oe_code_m_str1.c \
+ oe_code_m_str3.c \
+ oe_code_m_strRec.c \
+ oe_code_m_strRec_str5.c \
+ oe_code_m_strRec_str7.c
+
+GEN_HRL_FILES = \
+ m.hrl \
+ m_i.hrl \
+ oe_c_erl_test.hrl
+
+GEN_ERL_FILES = \
+ m.erl \
+ m_arr2.erl \
+ m_arr3.erl \
+ m_i.erl \
+ m_str3.erl \
+ oe_c_erl_test.erl
+
+C_FILES = $(GEN_C_FILES) c_client.c my.c
+
+OBJS = $(C_FILES:.c=@obj@)
+
+PGMS = c_client@exe@
+
+ERL_FILES = $(GEN_ERL_FILES) m_i_impl.erl
+
+EBINS = $(ERL_FILES:.erl=.@EMULATOR@)
+
+
+all: $(PGMS) $(EBINS)
+
+clean:
+ -rm -f $(OBJS) $(GEN_C_FILES) $(GEN_H_FILES) $(PGMS) \
+ $(EBINS) $(GEN_ERL_FILES) $(GEN_HRL_FILES)
+ -del /F /Q $(OBJS) $(GEN_C_FILES) $(GEN_H_FILES) $(PGMS) \
+ $(EBINS) $(GEN_ERL_FILES) $(GEN_HRL_FILES)
+
+$(PGMS): $(OBJS)
+ $(LD) $(LDFLAGS) -o $@ $(OBJS) $(LIBS)
+
+$(GEN_C_FILES) $(GEN_H_FILES): c_erl_test.idl
+ $(ERLC) -I $(IC_INCLUDE_PATH) "+{be,c_client}" \
+ "+{user_protocol,my}" c_erl_test.idl
+
+$(GEN_ERL_FILES) $(GEN_HRL_FILES): c_erl_test.idl
+ $(ERLC) -I $(IC_INCLUDE_PATH) "+{be,erl_genserv}" c_erl_test.idl
+
+.c@obj@:
+ $(CC) -c -o $*@obj@ $(CFLAGS) $<
+
+.erl.@EMULATOR@:
+ $(ERLC) -I $(IC_INCLUDE_PATH) $<
+
diff --git a/lib/ic/test/c_client_erl_server_proto_SUITE_data/c_client.c b/lib/ic/test/c_client_erl_server_proto_SUITE_data/c_client.c
new file mode 100644
index 0000000000..f352b91fd5
--- /dev/null
+++ b/lib/ic/test/c_client_erl_server_proto_SUITE_data/c_client.c
@@ -0,0 +1,1763 @@
+/*
+ * %CopyrightBegin%
+ *
+ * Copyright Ericsson AB 2003-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%
+ *
+ */
+/* C-client for test of IC.
+ *
+ * TODO:
+ *
+ * 1. XXX #includes for VxWorks, Windows
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#ifndef __WIN32__
+# include <unistd.h>
+#endif
+
+#include <string.h>
+
+#ifdef __WIN32__
+# include <time.h>
+# include <sys/timeb.h>
+#elif defined VXWORKS
+#include <time.h>
+#include <sys/times.h>
+#else
+#include <sys/time.h>
+#endif
+
+#include <ctype.h>
+
+#ifdef __WIN32__
+# include <winsock2.h>
+# include <windows.h>
+#else
+# include <sys/types.h>
+# include <sys/socket.h>
+# include <netinet/in.h>
+# include <arpa/inet.h>
+# include <netdb.h>
+#endif
+
+#include "ei.h"
+#include "erl_interface.h"
+#include "m_i.h"
+
+#define HOSTNAMESZ 256
+#define NODENAMESZ 512
+
+#define INBUFSZ 10
+#define OUTBUFSZ 0
+
+#define MAXTRIES 5
+
+#define CHECK_EXCEPTION(x) \
+ if ((x)->_major != CORBA_NO_EXCEPTION) { \
+ fprintf(stderr,"\n\nException: %s\n\n", \
+ (char *)CORBA_exception_value((x))); \
+ CORBA_exception_free((x)); \
+ return -1; \
+ } \
+
+/* XXX Should free things here too! */
+#define RETURN_IF_OK(x) \
+ if ((x)) {\
+ fprintf(stdout, "ok\n");\
+ return 0;\
+ }\
+
+#define cmp_str(x,y) (!strcmp((x),(y)))
+#define cmp_wstr(x,y) (!ic_wstrcmp((x),(y)))
+
+typedef CORBA_Environment IC_Env;
+
+typedef int (*TestFunc)(IC_Env *);
+typedef struct {
+ char *name;
+ TestFunc func;
+} TestCase;
+
+static char longtext[] =
+"Introduction The IC application is an IDL compiler implemented in Erlang."
+" The IDL compiler generates client stubs and server skeletons."
+" Several back-ends are supported, and they fall into three main groups."
+" For more details on IC compiler options consult the ic(3) manual page."
+" Argument passing cases 1 Caller allocates all necessary storage,"
+" except that which may be encapsulated and managed within the parameter itself."
+" 2 The caller allocates a pointer and passes it by reference to the callee."
+" The callee sets the pointer to point to a valid instance of the parameter's type."
+" The caller is responsible for releasing the returned storage."
+" Following completion of a request, the caller is not allowed to modify any values"
+" in the returned storage. To do so the caller must first copy the returned instance"
+" into a new instance, then modify the new instance. 3 The caller allocates a"
+" pointer to an array slice which has all the same dimensions of the original"
+" array except the first, and passes it by reference to the callee. The callee sets"
+" the pointer to point to a valid instance of the array. The caller is responsible for"
+" releasing the returned storage. Following completion of a request, the caller is not"
+" allowed to modify any values in the returned storage. To do so the caller must first"
+" copy the returned instance into a new instance, then modify the new instance."
+" Generated Files Two files will be generated for each scope. One set of files will be"
+" generated for each module and each interface scope. An extra set is generated for"
+" those definitions at top level scope. One of the files is a header file(.h), and the"
+" other file is a C source code file (.c). In addition to these files a number of C"
+" source files will be generated for type encodings, they are named according to the "
+"following template: oe_code_<type>.c.";
+static char this_node[NODENAMESZ + 1];
+static char *progname;
+
+/* Test function prototypes */
+
+static int void_test(IC_Env *env);
+static int long_test(IC_Env *env);
+static int long_long_test(IC_Env *env);
+static int unsigned_short_test(IC_Env *env);
+static int unsigned_long_test(IC_Env *env);
+static int unsigned_long_long_test(IC_Env *env);
+static int double_test(IC_Env *env);
+static int char_test(IC_Env *env);
+static int wchar_test(IC_Env *env);
+static int octet_test(IC_Env *env);
+static int bool_test(IC_Env *env);
+static int struct_test(IC_Env *env);
+static int struct2_test(IC_Env *env);
+static int seq1_test(IC_Env *env);
+static int seq2_test(IC_Env *env);
+static int seq3_test(IC_Env *env);
+static int seq4_test(IC_Env *env);
+static int seq5_test(IC_Env *env);
+static int array1_test(IC_Env *env);
+static int array2_test(IC_Env *env);
+static int enum_test(IC_Env *env);
+static int string1_test(IC_Env *env);
+static int string2_test(IC_Env *env);
+static int string3_test(IC_Env *env);
+static int string4_test(IC_Env *env);
+static int pid_test(IC_Env *env);
+static int port_test(IC_Env *env);
+static int ref_test(IC_Env *env);
+static int term_test(IC_Env *env);
+static int typedef_test(IC_Env *env);
+static int inline_sequence_test(IC_Env *env);
+static int term_sequence_test(IC_Env *env);
+static int term_struct_test(IC_Env *env);
+static int wstring1_test(IC_Env *env);
+
+static TestCase test_cases[] = {
+ {"void_test", void_test},
+ {"long_test", long_test},
+ {"long_long_test", long_long_test},
+ {"unsigned_short_test", unsigned_short_test},
+ {"unsigned_long_test", unsigned_long_test},
+ {"unsigned_long_long_test", unsigned_long_long_test},
+ {"double_test", double_test},
+ {"char_test", char_test},
+ {"wchar_test", wchar_test},
+ {"octet_test", octet_test},
+ {"bool_test", bool_test},
+ {"struct_test", struct_test},
+ {"struct2_test", struct2_test},
+ {"seq1_test", seq1_test},
+ {"seq2_test", seq2_test},
+ {"seq3_test", seq3_test},
+ {"seq4_test", seq4_test},
+ {"seq5_test", seq5_test},
+ {"array1_test", array1_test},
+ {"array2_test", array2_test},
+ {"enum_test", enum_test},
+ {"string1_test", string1_test},
+ {"string2_test", string2_test},
+ {"string3_test", string3_test},
+ {"string4_test", string4_test},
+ {"pid_test", pid_test},
+ {"port_test", port_test},
+ {"ref_test", ref_test},
+ {"term_test", term_test},
+ {"typedef_test", typedef_test},
+ {"inline_sequence_test", inline_sequence_test},
+ {"term_sequence_test", term_sequence_test},
+ {"term_struct_test", term_struct_test},
+ {"wstring1_test", wstring1_test},
+ {"", NULL}
+};
+
+/* Other prototypes */
+static int cmp_aseq(m_aseq *a1, m_aseq *a2);
+static int cmp_a(m_a *a1, m_a *a2);
+static int cmp_bseq(m_bseq *b1, m_bseq *b2);
+static int cmp_b(m_b *b1, m_b *b2);
+static int cmp_lseq(m_lseq *b1, m_lseq *b2);
+static int cmp_etseq(m_etseq *b1, m_etseq *b2);
+static int cmp_et(m_et* b1, m_et *b2);
+static int cmp_es(m_es *b1, m_es *b2);
+static int cmp_arr1(m_arr1 b1, m_arr1 b2);
+static int cmp_dd(m_dd b1, m_dd b2);
+static int cmp_strRec(m_strRec *b1, m_strRec *b2);
+static int cmp_sseq(m_sseq *b1, m_sseq *b2);
+static int cmp_pid(erlang_pid *p1, erlang_pid *p2);
+static int cmp_port(erlang_port *p1, erlang_port *p2);
+static int cmp_ref(erlang_ref *p1, erlang_ref *p2);
+static int cmp_s(m_s *b1, m_s *b2);
+static int cmp_ssstr3(m_ssstr3 *b1, m_ssstr3 *b2);
+static int cmp_ssarr3(m_ssarr3 *b1, m_ssarr3 *b2);
+static int cmp_sarr3(m_sarr3 *b1, m_sarr3 *b2);
+static int cmp_arr3(m_arr3 b1, m_arr3 b2);
+
+static void print_aseq(m_aseq *a);
+static void print_a(m_a *a);
+static void print_bseq(m_bseq *b);
+static void print_lseq(m_lseq *b);
+static void print_b(m_b *b);
+static void print_etseq(m_etseq *b);
+static void print_et(m_et* b);
+static void print_es(m_es *b);
+static void print_arr1(long a[500]);
+static void print_dd(long a[2][3]);
+static void print_strRec(m_strRec* sr);
+static void print_sseq(m_sseq *b);
+static void print_pid(erlang_pid *p);
+static void print_port(erlang_port *p);
+static void print_ref(erlang_ref *p);
+static void print_term(ETERM *t);
+static void print_s(m_s *p);
+static void print_ssstr3(m_ssstr3 *b1);
+static void print_ssarr3(m_ssarr3 *b1);
+static void print_sarr3(m_sarr3 *b1);
+static void print_arr3(m_arr3 b1);
+static void print_wstr(CORBA_wchar *ws);
+
+static void free_etseq_buf(m_etseq *b);
+static void free_et(m_et* b);
+
+#ifdef __WIN32__
+typedef struct {
+ long tv_sec;
+ long tv_usec;
+} MyTimeval;
+#else
+typedef struct timeval MyTimeval;
+#endif
+static void my_gettimeofday(MyTimeval *tv);
+static void showtime(MyTimeval *start, MyTimeval *stop);
+static void usage(void);
+static void done(int r);
+
+
+
+/* main */
+
+#ifdef VXWORKS
+int client(int argc, char **argv)
+#else
+int main(int argc, char **argv)
+#endif
+{
+ struct hostent *hp;
+ erlang_pid pid;
+ MyTimeval start, stop;
+ int i, fd, ires, tres;
+ IC_Env *env;
+ int tries = 0;
+ char *this_node_name = NULL;
+ char *peer_node = NULL;
+ char *peer_process_name = NULL;
+ char *cookie = NULL;
+ char host[HOSTNAMESZ + 1];
+ TestFunc test_func = NULL;
+ TestCase *test_case;
+ char *test_case_name = NULL;
+
+#ifdef __WIN32__
+ WORD wVersionRequested;
+ WSADATA wsaData;
+
+ wVersionRequested = MAKEWORD(2, 0);
+
+ if (WSAStartup(wVersionRequested, &wsaData) != 0) {
+ fprintf(stderr, "Could not load winsock2 v2.0 compatible DLL");
+ exit(1);
+ }
+#endif
+
+ progname = argv[0];
+ host[HOSTNAMESZ] = '\0';
+ if (gethostname(host, HOSTNAMESZ) < 0) {
+ fprintf(stderr, "Can't find own hostname\n");
+ done(1);
+ }
+ if ((hp = gethostbyname(host)) == 0) {
+ fprintf(stderr, "Can't get ip address for host %s\n", host);
+ done(1);
+ }
+ for (i = 1; i < argc; i++) {
+ if (cmp_str(argv[i], "-help")) {
+ usage();
+ done(0);
+ } else if (cmp_str(argv[i], "-this-node-name")) {
+ i++;
+ this_node_name = argv[i];
+ } else if (cmp_str(argv[i], "-peer-node")) {
+ i++;
+ peer_node = argv[i];
+ } else if (cmp_str(argv[i], "-peer-process-name")) {
+ i++;
+ peer_process_name = argv[i];
+ } else if (cmp_str(argv[i], "-cookie")) {
+ i++;
+ cookie = argv[i];
+ } else if (cmp_str(argv[i], "-test-case")) {
+ i++;
+ test_case_name = argv[i];
+ } else {
+ fprintf(stderr, "Error : invalid argument \"%s\"\n", argv[i]);
+ usage();
+ done(1);
+ }
+ }
+
+ if (this_node_name == NULL || peer_node == NULL || test_case_name == NULL
+ || peer_process_name == NULL || cookie == NULL) {
+ fprintf(stderr, "Error: missing option\n");
+ usage();
+ done(1);
+ }
+
+ test_case = test_cases;
+ while (test_case->func) {
+ if (cmp_str(test_case->name, test_case_name)) {
+ test_func = test_case->func;
+ break;
+ }
+ test_case++;
+ }
+ if (test_func == NULL) {
+ fprintf(stderr, "Error: illegal test case: \"%s\"\n", test_case_name);
+ done(1);
+ }
+
+ /* Behead hostname at first dot */
+ for (i=0; host[i] != '\0'; i++) {
+ if (host[i] == '.') { host[i] = '\0'; break; }
+ }
+ sprintf(this_node, "%s@%s", this_node_name, host);
+ fprintf(stderr, "c_client: this node: \"%s\"\n", this_node);
+ fprintf(stderr, "c_client: peer node: \"%s\"\n", peer_node);
+ fprintf(stderr, "c_client: test case: \"%s\"\n", test_case_name);
+
+ fprintf(stderr, "c_client: starting\n");
+
+ /* initialize erl_interface */
+ erl_init(NULL, 0);
+
+ for (tries = 0; tries < MAXTRIES; tries++) {
+
+ /* connect to erlang node */
+
+ ires = erl_connect_xinit(host, this_node_name, this_node,
+ (struct in_addr *)*hp->h_addr_list,
+ cookie, 0);
+
+ fprintf(stderr, "c_client: erl_connect_xinit(): %d\n", ires);
+
+ fd = erl_connect(peer_node);
+ fprintf(stderr, "c_client: erl_connect(): %d\n", fd);
+
+ if (fd >= 0)
+ break;
+ fprintf(stderr, "c_client: cannot connect, retrying\n");
+ }
+ if (fd < 0) {
+ fprintf(stderr, "c_client: cannot connect, exiting\n");
+ done(1);
+ }
+ env = CORBA_Environment_alloc(INBUFSZ, OUTBUFSZ);
+ env->_fd = fd;
+ strcpy(env->_regname, peer_process_name);
+ env->_to_pid = NULL;
+ env->_from_pid = &pid;
+
+ strcpy(pid.node, this_node);
+ pid.num = fd;
+ pid.serial = 0;
+ pid.creation = 0;
+
+ my_gettimeofday(&start);
+ tres = test_func(env); /* Call test case */
+ my_gettimeofday(&stop);
+ showtime(&start, &stop);
+ erl_close_connection(fd);
+
+ printf("c_client: env->_inbuf before : %d\n", INBUFSZ);
+ printf("c_client: env->_outbuf before : %d\n", OUTBUFSZ);
+ printf("c_client: env->_inbuf after : %d\n", env->_inbufsz);
+ printf("c_client: env->_outbuf after : %d\n", env->_outbufsz);
+
+ CORBA_free(env->_inbuf);
+ CORBA_free(env->_outbuf);
+ CORBA_free(env);
+ done(tres);
+}
+
+static void usage()
+{
+ fprintf(stderr, "Usage: %s [-help] -this-node-name <name> "
+ "-peer-node <nodename> -peer-process-name <name> "
+ "-cookie <cookie> -test-case <test case name>\n", progname);
+ fprintf(stderr, "Example:\n %s -this-node-name kalle "
+ "-peer-node olle@home -peer-process-name idltest "
+ "-cookie oa678er -test-case octet_test\n", progname);
+}
+
+static void done(int r)
+{
+#ifdef __WIN32__
+ WSACleanup();
+#endif
+ exit(r);
+}
+
+
+/* TESTS */
+
+static int void_test(IC_Env *env)
+{
+ fprintf(stdout, "\n======== m_i_void test ======\n\n");
+ m_i_void_test(NULL,env);
+ CHECK_EXCEPTION(env);
+ RETURN_IF_OK(1);
+}
+
+static int long_test(IC_Env *env)
+{
+ long l = 4711, lo, lr;
+
+ fprintf(stdout, "\n======== m_i_long test ======\n\n");
+ lr = m_i_long_test(NULL, l, &lo, env);
+ CHECK_EXCEPTION(env);
+ RETURN_IF_OK(l == lo && l == lr);
+ if (l != lo)
+ fprintf(stdout, " out parameter error, sent: %ld, got: %ld\n", l, lo);
+ if (l != lr)
+ fprintf(stdout, " result error, sent: %ld, got: %ld\n", l, lr);
+ return -1;
+}
+
+static int long_long_test(IC_Env *env)
+{
+ CORBA_long_long ll = 4711, llo, llr;
+
+ fprintf(stdout, "\n======== m_i_longlong test ======\n\n");
+ llr = m_i_longlong_test(NULL, ll, &llo, env);
+ CHECK_EXCEPTION(env);
+ RETURN_IF_OK(ll == llo && ll == llr);
+ if (ll != llo)
+ fprintf(stdout, " out parameter error, sent: %ld, got: %ld\n",
+ ll, llo);
+ if (ll != llr)
+ fprintf(stdout, " result error, sent: %ld, got: %ld\n", ll, llr);
+ return -1;
+}
+
+static int unsigned_short_test(IC_Env *env)
+{
+ unsigned short x, y = 2, z;
+
+ fprintf(stdout, "\n======== m_i_ushort test ======\n\n");
+ x = m_i_ushort_test(NULL, y, &z, env);
+ CHECK_EXCEPTION(env);
+ RETURN_IF_OK(y == z && y == x);
+ if (y != z)
+ fprintf(stdout, " out parameter error, sent: %d, got: %d\n", y, z);
+ if (y != x)
+ fprintf(stdout, " result error, sent: %d, got: %d\n", y, x);
+ return -1;
+}
+
+
+static int unsigned_long_test(IC_Env *env)
+{
+ unsigned long ul = 5050, ulo, ulr;
+
+ fprintf(stdout, "\n======== m_i_ulong test ======\n\n");
+ ulr = m_i_ulong_test(NULL, ul, &ulo, env);
+ CHECK_EXCEPTION(env);
+ RETURN_IF_OK(ul == ulo && ul == ulr);
+ if (ul != ulo)
+ fprintf(stdout, " out parameter error, sent: %lu, got: %lu\n",
+ ul, ulo);
+ if (ul != ulr)
+ fprintf(stdout, " result error, sent: %lu, got: %lu\n", ul, ulr);
+ return -1;
+}
+
+/*
+ * Note: CORBA_unsigned_long_long is in fact a plain long.
+ */
+static int unsigned_long_long_test(IC_Env *env)
+{
+ CORBA_unsigned_long_long ull = 5050, ullo, ullr;
+
+ fprintf(stdout, "\n======== m_i_ulonglong test ======\n\n");
+ ullr = m_i_ulonglong_test(NULL, ull, &ullo, env);
+ CHECK_EXCEPTION(env);
+ RETURN_IF_OK(ull == ullo && ull == ullr);
+ if (ull != ullo)
+ fprintf(stdout, " out parameter error, sent: %lu, got: %lu\n",
+ ull, ullo);
+ if (ull != ullr)
+ fprintf(stdout, " result error, sent: %lu, got: %lu\n",
+ ull, ullr);
+ return -1;
+}
+
+static int double_test(IC_Env *env)
+{
+ double d = 12.1212, db, dr;
+
+ fprintf(stdout, "\n======== m_i_double test ======\n\n");
+ dr = m_i_double_test(NULL, d, &db, env);
+ CHECK_EXCEPTION(env);
+ RETURN_IF_OK(d == db && d == dr);
+ if (d != db)
+ fprintf(stdout, " out parameter error, sent: %f, got: %f\n", d, db);
+ if (d != dr)
+ fprintf(stdout, " result error, sent: %f, got: %f\n", d, dr);
+ return -1;
+}
+
+static int char_test(IC_Env *env)
+{
+ char c = 'g', co, cr;
+
+ /* char test */
+ fprintf(stdout, "\n======== m_i_char test ======\n\n");
+ cr = m_i_char_test(NULL, c, &co, env);
+ CHECK_EXCEPTION(env);
+ RETURN_IF_OK(c == co && c == cr);
+ if (c !=co)
+ fprintf(stdout, " out parameter error, sent: %c, got: %c\n", c, co);
+ if (c != cr)
+ fprintf(stdout, " result error, sent: %c, got: %c\n", c, cr);
+ return -1;
+}
+
+static int wchar_test(IC_Env *env)
+{
+ CORBA_wchar wc = 103, wco, wcr;
+
+ fprintf(stdout, "\n======== m_i_wchar test ======\n\n");
+ wcr = m_i_wchar_test(NULL, wc, &wco, env);
+ CHECK_EXCEPTION(env);
+ RETURN_IF_OK(wc == wco && wc == wcr);
+ if (wc != wco)
+ fprintf(stdout, " out parameter error, sent: %lu, got: %lu\n",
+ wc, wco);
+ if (wc != wcr)
+ fprintf(stdout, " result error, sent: %lu, got: %lu\n",
+ wc, wcr);
+ return -1;
+}
+
+static int octet_test(IC_Env *env)
+{
+ char o ='r', oo, or;
+
+ fprintf(stdout, "\n======== m_i_octet test ======\n\n");
+ or = m_i_octet_test(NULL, o, &oo, env);
+ CHECK_EXCEPTION(env);
+ RETURN_IF_OK(o == oo && o == or);
+ if (o != oo)
+ fprintf(stdout, " out parameter error, sent: %c, got: %c\n", o, oo);
+ if (o != or)
+ fprintf(stdout, " result error, sent: %c, got: %c\n", o, or);
+ return -1;
+}
+
+static int bool_test(IC_Env *env)
+{
+ unsigned char i = 0, io, ir;
+
+ fprintf(stdout, "\n======== m_i_bool test ======\n\n");
+ ir = m_i_bool_test(NULL, i, &io, env);
+ CHECK_EXCEPTION(env);
+ RETURN_IF_OK(i == io && i == ir);
+ if (i != io)
+ fprintf(stdout, " out parameter error, sent: %d, got: %d\n", i, io);
+ if (i != ir)
+ fprintf(stdout, " result error, sent: %d, got: %d\n", i, ir);
+ return -1;
+}
+
+static int struct_test(IC_Env *env)
+{
+ m_b b = {4711, 'a'}, bo, br;
+
+ fprintf(stdout, "\n======== m_i_struct test ======\n\n");
+ br = m_i_struct_test(NULL, &b, &bo, env);
+ CHECK_EXCEPTION(env);
+ RETURN_IF_OK(cmp_b(&b, &bo) && cmp_b(&b, &br));
+ if (!cmp_b(&b, &bo)) {
+ fprintf(stdout, " out parameter error, sent:\n");
+ print_b(&b);
+ fprintf(stdout, " got:\n");
+ print_b(&bo);
+ fprintf(stdout, "\n");
+ }
+ if (!cmp_b(&b, &br)) {
+ fprintf(stdout, " result error, sent:\n");
+ print_b(&b);
+ fprintf(stdout, " got:\n");
+ print_b(&br);
+ fprintf(stdout, "\n");
+ }
+ return -1;
+}
+
+static int struct2_test(IC_Env *env)
+{
+ m_es esi = {m_peach, 5050}, eso, esr;
+
+ fprintf(stdout, "\n======== m_i_struct2 test ======\n\n");
+ esr = m_i_struct2_test(NULL, &esi, &eso, env);
+ CHECK_EXCEPTION(env);
+ RETURN_IF_OK(cmp_es(&esi, &eso) && cmp_es(&esi, &esr));
+ if (!cmp_es(&esi, &eso)) {
+ fprintf(stdout, " out parameter error, sent:\n");
+ print_es(&esi);
+ fprintf(stdout, " got:\n");
+ print_es(&eso);
+ fprintf(stdout, "\n");
+ }
+ if (!cmp_es(&esi, &esr)) {
+ fprintf(stdout, " result error, sent:\n");
+ print_es(&esi);
+ fprintf(stdout, " got:\n");
+ print_es(&esr);
+ fprintf(stdout, "\n");
+ }
+ return -1;
+}
+
+
+static int seq1_test(IC_Env *env)
+{
+ m_bseq bs, *bso, *bsr;
+
+ m_b ba[3] = {{4711, 'a'}, {4712, 'b'}, {4713, 'c'}};
+ bs._length = 3;
+ bs._buffer = ba;
+
+ fprintf(stdout, "\n======== m_i_seq1 test ======\n\n");
+ bsr = m_i_seq1_test(NULL, &bs, &bso, env);
+ CHECK_EXCEPTION(env);
+ RETURN_IF_OK(cmp_bseq(&bs, bso) && cmp_bseq(&bs, bsr));
+ if (!cmp_bseq(&bs, bso)) {
+ fprintf(stdout, " out parameter error, sent:\n");
+ print_bseq(&bs);
+ fprintf(stdout, " got:\n");
+ print_bseq(bso);
+ fprintf(stdout, "\n");
+ }
+ if (!cmp_bseq(&bs, bsr)) {
+ fprintf(stdout, " result error, sent:\n");
+ print_bseq(&bs);
+ fprintf(stdout, " got:\n");
+ print_bseq(bsr);
+ fprintf(stdout, "\n");
+ }
+ CORBA_free(bso);
+ CORBA_free(bsr);
+ return -1;
+}
+
+static int seq2_test(IC_Env *env)
+{
+ m_b ba[3] = {{4711, 'a'}, {4712, 'b'}, {4713, 'c'}};
+ m_a a;
+ m_a aa[2];
+ m_aseq as, *aso, *asr;
+
+ a.l = 9999;
+ a.y._length = 3;
+ a.y._buffer = ba;
+ a.d = 66.89898989;
+
+ aa[0] = a;
+ aa[1] = a;
+ as._length = 2;
+ as._buffer = aa;
+
+ fprintf(stdout, "\n======== m_i_seq2 test ======\n\n");
+ asr = m_i_seq2_test(NULL, &as, &aso, env);
+ CHECK_EXCEPTION(env);
+ RETURN_IF_OK(cmp_aseq(&as, aso) && cmp_aseq(&as, asr));
+ if (!cmp_aseq(&as, aso)) {
+ fprintf(stdout, " out parameter error, sent:\n");
+ print_aseq(&as);
+ fprintf(stdout, " got:\n");
+ print_aseq(aso);
+ fprintf(stdout, "\n");
+ }
+ if (!cmp_aseq(&as, asr)) {
+ fprintf(stdout, " result error, sent:\n");
+ print_aseq(&as);
+ fprintf(stdout, " got:\n");
+ print_aseq(asr);
+ fprintf(stdout, "\n");
+ }
+ CORBA_free(aso);
+ CORBA_free(asr);
+ return -1;
+}
+
+static int seq3_test(IC_Env *env)
+{
+ m_lseq lsi, *lso, *lsr;
+ long al[500];
+ int i=0;
+
+ for (i = 0; i < 500; i++)
+ al[i]=i;
+ lsi._length = 500;
+ lsi._buffer = al;
+
+ fprintf(stdout, "\n======== m_i_seq3 test ======\n\n");
+ lsr = m_i_seq3_test(NULL, &lsi, &lso, env);
+ CHECK_EXCEPTION(env);
+ RETURN_IF_OK(cmp_lseq(&lsi, lso) && cmp_lseq(&lsi, lsr));
+ if (!cmp_lseq(&lsi, lso)) {
+ fprintf(stdout, " out parameter error, sent:\n");
+ print_lseq(&lsi);
+ fprintf(stdout, " got:\n");
+ print_lseq(lso);
+ fprintf(stdout, "\n");
+ }
+ if (!cmp_lseq(&lsi, lsr)) {
+ fprintf(stdout, " result error, sent:\n");
+ print_lseq(&lsi);
+ fprintf(stdout, " got:\n");
+ print_lseq(lsr);
+ fprintf(stdout, "\n");
+ }
+ CORBA_free(lso);
+ CORBA_free(lsr);
+ return -1;
+}
+
+static int seq4_test(IC_Env *env)
+{
+ char *stra0[3] = {"a", "long", "time"};
+ char *stra1[3] = {"ago", "there", "was"};
+ char *stra2[3] = {"a", "buggy", "compiler"};
+ m_sstr3 str3s[3] = {{3, 3, stra0}, {3, 3, stra1}, {3, 3, stra2}};
+ m_ssstr3 str3ssi = {3, 3, str3s};
+ m_ssstr3 *str3sso, *str3ssr;
+
+ fprintf(stdout, "\n======== m_i_seq4 test ======\n\n");
+ str3ssr = m_i_seq4_test(NULL, &str3ssi, &str3sso, env);
+ CHECK_EXCEPTION(env);
+ RETURN_IF_OK(cmp_ssstr3(&str3ssi, str3sso) &&
+ cmp_ssstr3(&str3ssi, str3ssr));
+ if (!cmp_ssstr3(&str3ssi, str3sso)){
+ fprintf(stdout, " out parameter error, sent:\n");
+ print_ssstr3(&str3ssi);
+ fprintf(stdout, " got:\n");
+ print_ssstr3(str3sso);
+ fprintf(stdout, "\n");
+ }
+ if (!cmp_ssstr3(&str3ssi, str3ssr)) {
+ fprintf(stdout, " result error, sent:\n");
+ print_ssstr3(&str3ssi);
+ fprintf(stdout, " got:\n");
+ print_ssstr3(str3ssr);
+ fprintf(stdout, "\n");
+ }
+ CORBA_free(str3sso);
+ CORBA_free(str3ssr);
+ return -1;
+}
+
+static int seq5_test(IC_Env *env)
+{
+ m_arr3 arr3a[3] = {
+ {4711, 18931947, 3},
+ {4711, 18931947, 3},
+ {4711, 18931947, 3}};
+ m_sarr3 arr3sa[3] = {{3, 3, arr3a}, {3, 3, arr3a}, {3, 3, arr3a}};
+ m_ssarr3 arr3ssi = {3, 3, arr3sa};
+ m_ssarr3 *arr3sso;
+ m_ssarr3 *arr3ssr;
+
+ fprintf(stdout, "\n======== m_i_seq5 test ======\n\n");
+ arr3ssr = m_i_seq5_test(NULL, &arr3ssi, &arr3sso, env);
+ CHECK_EXCEPTION(env);
+ RETURN_IF_OK(cmp_ssarr3(&arr3ssi, arr3sso) &&
+ cmp_ssarr3(&arr3ssi, arr3ssr));
+ if (!cmp_ssarr3(&arr3ssi, arr3sso)) {
+ fprintf(stdout, " out parameter error, sent:\n");
+ print_ssarr3(&arr3ssi);
+ fprintf(stdout, " got:\n");
+ print_ssarr3(arr3sso);
+ fprintf(stdout, "\n");
+ }
+ if (!cmp_ssarr3(&arr3ssi, arr3ssr)) {
+ fprintf(stdout, " result error, sent:\n");
+ print_ssarr3(&arr3ssi);
+ fprintf(stdout, " got:\n");
+ print_ssarr3(arr3ssr);
+ fprintf(stdout, "\n");
+ }
+ CORBA_free(arr3sso);
+ CORBA_free(arr3ssr);
+ return -1;
+}
+
+static int array1_test(IC_Env *env)
+{
+ int i;
+ long al[500];
+ m_arr1 alo;
+ m_arr1_slice* alr;
+
+ for (i = 0; i < 500; i++)
+ al[i]=i;
+
+ fprintf(stdout, "\n======== m_i_array1 test ======\n\n");
+ alr = m_i_array1_test(NULL, al, alo, env);
+ CHECK_EXCEPTION(env);
+ RETURN_IF_OK(cmp_arr1(al, alo) && cmp_arr1(al, alr));
+ if (!cmp_arr1(al, alo)) {
+ fprintf(stdout, " out parameter error, sent:\n");
+ print_arr1(al);
+ fprintf(stdout, " got:\n");
+ print_arr1(alo);
+ fprintf(stdout, "\n");
+ }
+ if (!cmp_arr1(al,alr)) {
+ fprintf(stdout, " result error, sent:\n");
+ print_arr1(al);
+ fprintf(stdout, " got:\n");
+ print_arr1(alr);
+ fprintf(stdout, "\n");
+ }
+ free(alo);
+ free(alr);
+ return -1;
+}
+
+static int array2_test(IC_Env *env)
+{
+ long dl[2][3] = {{11, 2, 7}, {22, 8 ,13}};
+ m_dd dlo;
+ m_dd_slice* dlr;
+
+ fprintf(stdout, "\n======== m_i_array2 test ======\n\n");
+ dlr = m_i_array2_test(NULL, dl, dlo, env);
+ CHECK_EXCEPTION(env);
+ RETURN_IF_OK(cmp_dd(dl,dlo) && cmp_dd(dl,dlr));
+ if (!cmp_dd(dl,dlo)) {
+ fprintf(stdout, " out parameter error, sent:\n");
+ print_dd(dl);
+ fprintf(stdout, " got:\n");
+ print_dd(dlo);
+ fprintf(stdout, "\n");
+ }
+ if (!cmp_dd(dl,dlr)) {
+ fprintf(stdout, " result error, sent:\n");
+ print_dd(dl);
+ fprintf(stdout, " got:\n");
+ print_dd(dlr);
+ fprintf(stdout, "\n");
+ }
+ free(*dlr);
+ return -1;
+}
+
+static int enum_test(IC_Env *env)
+{
+ m_fruit ei = m_banana, eo, er;
+
+ fprintf(stdout, "\n======== m_i_enum test ======\n\n");
+ er = m_i_enum_test(NULL, ei, &eo, env);
+ CHECK_EXCEPTION(env);
+ RETURN_IF_OK(ei == eo && ei == er);
+ if (ei != eo)
+ fprintf(stdout, " out parameter error, sent: %d, got: %d\n", ei, eo);
+ if (ei != er)
+ fprintf(stdout, " result error, sent: %d, got: %d\n", ei, er);
+ return -1;
+}
+
+static int string1_test(IC_Env *env)
+{
+ char* si = longtext;
+ char* so;
+ char* sr;
+
+ fprintf(stdout, "\n======== m_i_string1 test ======\n\n");
+ sr = m_i_string1_test(NULL, si, &so, env);
+ CHECK_EXCEPTION(env);
+ RETURN_IF_OK(cmp_str(si, so) && cmp_str(si, sr));
+ if (!cmp_str(si, so))
+ fprintf(stdout, " out parameter error, sent: %s, got: %s\n", si, so);
+ if (!cmp_str(si, sr))
+ fprintf(stdout, " result error, sent: %s, got: %s\n", si, sr);
+ CORBA_free(so);
+ CORBA_free(sr);
+ return -1;
+}
+
+static int string2_test(IC_Env *env)
+{
+ char* sa[3] = {"hello", "foo", "bar"};
+ m_sseq ssi = {3, 3, sa};
+ m_sseq *sso, *ssr;
+
+ fprintf(stdout, "\n======== m_i_string2 test ======\n\n");
+ ssr = m_i_string2_test(NULL, &ssi, &sso, env);
+ CHECK_EXCEPTION(env);
+ RETURN_IF_OK(cmp_sseq(&ssi, sso) && cmp_sseq(&ssi, sso));
+ if (!cmp_sseq(&ssi, sso)) {
+ fprintf(stdout, " out parameter error, sent:\n");
+ print_sseq(&ssi);
+ fprintf(stdout, "got:\n");
+ print_sseq(sso);
+ }
+ if (!cmp_sseq(&ssi, ssr)) {
+ fprintf(stdout, " result error, sent:\n");
+ print_sseq(&ssi);
+ fprintf(stdout, "got:\n");
+ print_sseq(ssr);
+ }
+ CORBA_free(sso);
+ CORBA_free(ssr);
+ return -1;
+}
+
+static int string3_test(IC_Env *env)
+{
+ char* si = longtext;
+ char* so;
+ char* sr;
+
+ fprintf(stdout, "\n======== m_i_string3 test ======\n\n");
+ sr = m_i_string3_test(NULL, si, &so, env);
+ CHECK_EXCEPTION(env);
+ RETURN_IF_OK(cmp_str(si, so) && cmp_str(si, so));
+ if (!cmp_str(si, so))
+ fprintf(stdout, " out parameter error, sent: %s, got: %s\n", si, so);
+ if (!cmp_str(si, sr))
+ fprintf(stdout, " result error, sent: %s, got: %s\n", si, sr);
+ CORBA_free(so);
+ CORBA_free(sr);
+ return -1;
+}
+
+static int string4_test(IC_Env *env)
+{
+ char as1[100] = "a string", as2[200] = "help", as3[200] = "hello there";
+ m_strRec stri = { 1, /* dd */
+ as1, /* str4 */
+ {{'a', 'k'}, {'z', 'g'}, {'n', 'q'}}, /* str7 */
+ {3, 3, "buf"}, /* str5 */
+ as2, /* str6 */
+ {'m', 'f', 'o'}, /* str8 */
+ as3, /* str9 */
+ {3, 3, "stu"} /* str10 */
+ };
+ m_strRec *stro, *strr;
+
+ fprintf(stdout, "\n======== m_i_string4 test ======\n\n");
+ strr = m_i_string4_test(NULL, &stri, &stro, env);
+ CHECK_EXCEPTION(env);
+ RETURN_IF_OK(cmp_strRec(&stri,stro) && cmp_strRec(&stri,strr));
+ if (!cmp_strRec(&stri,stro)) {
+ fprintf(stdout, " out parameter error, sent:\n");
+ print_strRec(&stri);
+ fprintf(stdout, " got:\n");
+ print_strRec(stro);
+ fprintf(stdout, "\n");
+ }
+ if (!cmp_strRec(&stri,strr)) {
+ fprintf(stdout, " result error, sent:\n");
+ print_strRec(&stri);
+ fprintf(stdout, " got:\n");
+ print_strRec(strr);
+ fprintf(stdout, "\n");
+ }
+ CORBA_free(stro);
+ CORBA_free(strr);
+ return -1;
+}
+
+
+static int pid_test(IC_Env *env)
+{
+ erlang_pid pid = {"", 7, 0, 0}, pido, pidr;
+
+ strcpy(pid.node, this_node), /* this currently running node */
+ fprintf(stdout, "\n======== m_i_pid test ======\n\n");
+ pidr = m_i_pid_test(NULL, &pid, &pido, env);
+ CHECK_EXCEPTION(env);
+ RETURN_IF_OK(cmp_pid(&pid, &pido) && cmp_pid(&pid, &pidr));
+ if (!cmp_pid(&pid, &pido)) {
+ fprintf(stdout, " out parameter error, sent:\n");
+ print_pid(&pid);
+ fprintf(stdout, "got:\n");
+ print_pid(&pido);
+ }
+ if (!cmp_pid(&pid, &pidr)) {
+ fprintf(stdout, " result error, sent:\n");
+ print_pid(&pid);
+ fprintf(stdout, "got:\n");
+ print_pid(&pidr);
+ }
+ return -1;
+}
+
+static int port_test(IC_Env *env)
+{
+ erlang_port porti = {"node", 5, 1}, porto, portr;
+
+ fprintf(stdout, "\n======== m_i_port test ======\n\n");
+ portr = m_i_port_test(NULL, &porti, &porto, env);
+ CHECK_EXCEPTION(env);
+ RETURN_IF_OK(cmp_port(&porti, &porto) && cmp_port(&porti, &portr));
+ if (!cmp_port(&porti, &porto)) {
+ fprintf(stdout, " out parameter error, sent:\n");
+ print_port(&porti);
+ fprintf(stdout, "got:\n");
+ print_port(&porto);
+ }
+ if (!cmp_port(&porti, &portr)) {
+ fprintf(stdout, " result error, sent:\n");
+ print_port(&porti);
+ fprintf(stdout, "got:\n");
+ print_port(&portr);
+ }
+ return -1;
+}
+
+static int ref_test(IC_Env *env)
+{
+ erlang_ref refi = { "node1", 3, {1, 2, 3}, 1},
+ refo, refr;
+
+ fprintf(stdout, "\n======== m_i_ref test ======\n\n");
+ refr = m_i_ref_test(NULL, &refi, &refo, env);
+ CHECK_EXCEPTION(env);
+ RETURN_IF_OK(cmp_ref(&refi, &refo) && cmp_ref(&refi, &refr));
+ if (!cmp_ref(&refi, &refo)) {
+ fprintf(stdout, " out parameter error, sent:\n");
+ print_ref(&refi);
+ fprintf(stdout, "got:\n");
+ print_ref(&refo);
+ }
+ if (!cmp_ref(&refi, &refr)) {
+ fprintf(stdout, " result error, sent:\n");
+ print_ref(&refi);
+ fprintf(stdout, "got:\n");
+ print_ref(&refr);
+ }
+ return -1;
+}
+
+static int term_test(IC_Env *env)
+{
+ ETERM *ti, *to, *tr;
+
+ ti = erl_format("[{hej, 1, 23}, \"string\", {1.23, 45}]");
+
+ fprintf(stdout, "\n======== m_i_term test ======\n\n");
+ tr = m_i_term_test(NULL, ti, &to, env);
+ CHECK_EXCEPTION(env);
+ RETURN_IF_OK(erl_match(ti, to) && erl_match(ti, tr));
+ if (!erl_match(ti, to)) {
+ fprintf(stdout, " out parameter error, sent:\n");
+ print_term(ti);
+ fprintf(stdout, "got:\n");
+ print_term(to);
+ }
+ if (!erl_match(ti, tr)) {
+ fprintf(stdout, " result error, sent:\n");
+ print_term(ti);
+ fprintf(stdout, "got:\n");
+ print_term(tr);
+ }
+ erl_free_term(ti);
+ erl_free_term(to);
+ erl_free_term(tr);
+ return -1;
+}
+
+static int typedef_test(IC_Env *env)
+{
+ m_banan mbi, mbo; /* erlang_port */
+ m_apa mai; /* ETERM* */
+ m_apa mao = NULL;
+ long tl;
+
+ strcpy(mbi.node,"node");
+ mbi.id = 15;
+ mbi.creation = 1;
+
+ fprintf(stdout, "\n======== m_i_typedef test ======\n\n");
+ mai = erl_format("[{hej, 1, 23}, \"string\", {1.23, 45}]");
+ tl = m_i_typedef_test(NULL, mai, &mbi, &mao, &mbo, env);
+ CHECK_EXCEPTION(env);
+ RETURN_IF_OK(erl_match(mai, mao) && cmp_port(&mbi, &mbo) && tl == 4711);
+ if (!erl_match(mai, mao)) {
+ fprintf(stdout, " out parameter error (term), sent:\n");
+ print_term(mai);
+ fprintf(stdout, "got:\n");
+ print_term(mao);
+ }
+ if (!cmp_port(&mbi, &mbo)) {
+ fprintf(stdout, " out parameter error (port), sent:\n");
+ print_port(&mbi);
+ fprintf(stdout, "got:\n");
+ print_port(&mbo);
+ }
+ if (tl != 4711) {
+ fprintf(stdout, " result error, sent: 4711, got %ld\n", tl);
+ }
+ erl_free_term(mai);
+ erl_free_term(mao);
+ return -1;
+}
+
+static int inline_sequence_test(IC_Env *env)
+{
+ int i;
+ long al[500];
+ m_s isi = {4711, {500, 10, al}},
+ *iso, *isr;
+
+ for (i = 0; i < 500; i++)
+ al[i]=i;
+ fprintf(stdout, "\n======== m_i_inline_sequence test ======\n\n");
+ isr = m_i_inline_sequence_test(NULL, &isi, &iso, env);
+ CHECK_EXCEPTION(env);
+ RETURN_IF_OK(cmp_s(&isi, iso) && cmp_s(&isi, isr));
+ if (!cmp_s(&isi, iso)) {
+ fprintf(stdout, " out parameter error, sent:\n");
+ print_s(&isi);
+ fprintf(stdout, "got:\n");
+ print_s(iso);
+ }
+ if (!cmp_s(&isi, isr)) {
+ fprintf(stdout, " result error, sent:\n");
+ print_s(&isi);
+ fprintf(stdout, "got:\n");
+ print_s(isr);
+ }
+ CORBA_free(iso);
+ CORBA_free(isr);
+ return -1;
+}
+
+static int term_sequence_test(IC_Env *env)
+{
+ ETERM* et_array[4] = {
+ erl_format("[{apa, 1, 23}, \"string\", {1.23, 45}]"),
+ erl_format("[{banan, 1, 23}, \"string\", {1.23, 45}]"),
+ erl_format("[{apelsin, 1, 23}, \"string\", {1.23, 45}]"),
+ erl_format("[{mango, 1, 23}, \"string\", {1.23, 45}]")};
+ m_etseq etsi = {4, 4, et_array}, *etso, *etsr;
+
+ fprintf(stdout, "\n======== m_i_term_sequence test ======\n\n");
+ etsr = m_i_term_sequence_test(NULL, &etsi, &etso, env);
+ CHECK_EXCEPTION(env);
+ RETURN_IF_OK(cmp_etseq(&etsi, etso) && cmp_etseq(&etsi, etsr));
+ if (!cmp_etseq(&etsi, etso)) {
+ fprintf(stdout, " out parameter error, sent:\n");
+ print_etseq(&etsi);
+ fprintf(stdout, "got:\n");
+ print_etseq(etso);
+ }
+ if (!cmp_etseq(&etsi, etsr)) {
+ fprintf(stdout, " result error, sent:\n");
+ print_etseq(&etsi);
+ fprintf(stdout, "got:\n");
+ print_etseq(etsr);
+ }
+ free_etseq_buf(&etsi);
+ free_etseq_buf(etso);
+ free_etseq_buf(etsr);
+ CORBA_free(etso);
+ CORBA_free(etsr);
+ return -1;
+}
+
+static int term_struct_test(IC_Env *env)
+{
+ m_et eti = { erl_format("[{hej, 1, 23}, \"string\", {1.23, 45}]"),
+ 121212 };
+ m_et eto, etr;
+
+ fprintf(stdout, "\n======== m_i_term_struct test ======\n\n");
+ etr = m_i_term_struct_test(NULL, &eti, &eto, env);
+ CHECK_EXCEPTION(env);
+ RETURN_IF_OK(cmp_et(&eti, &eto) && cmp_et(&eti, &etr));
+ if (!cmp_et(&eti, &eto)) {
+ fprintf(stdout, " out parameter error, sent:\n");
+ print_et(&eti);
+ fprintf(stdout, "got:\n");
+ print_et(&eto);
+ }
+ if (!cmp_et(&eti, &etr)) {
+ fprintf(stdout, " result error, sent:\n");
+ print_et(&eti);
+ fprintf(stdout, "got:\n");
+ print_et(&etr);
+ }
+ free_et(&eti);
+ free_et(&eto);
+ free_et(&etr);
+ return -1;
+}
+
+static int wstring1_test(IC_Env *env)
+{
+ CORBA_wchar wsi[] = {100, 101, 102, 103, 104, 0}, *wso, *wsr;
+
+ fprintf(stdout, "\n======== m_i_wstring1 test ======\n\n");
+ wsr = m_i_wstring1_test(NULL, wsi, &wso, env);
+ CHECK_EXCEPTION(env);
+ RETURN_IF_OK(cmp_wstr(wsi, wso) && cmp_wstr(wsi, wsr));
+ if (!cmp_wstr(wsi, wso)) {
+ fprintf(stdout, " out parameter error, sent: \n");
+ print_wstr(wsi);
+ fprintf(stdout, "got:\n");
+ print_wstr(wso);
+ }
+ if (!cmp_wstr(wsi, wsr)) {
+ fprintf(stdout, " result error, sent: \n");
+ print_wstr(wsi);
+ fprintf(stdout, "got:\n");
+ print_wstr(wsr);
+ }
+ CORBA_free(wso);
+ CORBA_free(wsr);
+ return -1;
+}
+
+/* Compare functions */
+static int cmp_aseq(m_aseq *a1, m_aseq *a2)
+{
+ int i;
+
+ if (a1->_length != a2->_length)
+ return 0;
+ for (i = 0; i < a1->_length; i++)
+ if (cmp_a(&(a1->_buffer[i]), &(a2->_buffer[i])) == 0)
+ return 0;
+ return 1;
+}
+
+static int cmp_a(m_a *a1, m_a *a2)
+{
+ return a1->l == a2->l &&
+ a1->d == a2->d &&
+ cmp_bseq(&a1->y, &a2->y);
+}
+
+static int cmp_bseq(m_bseq *b1, m_bseq *b2)
+{
+ int i;
+
+ if (b1->_length != b2->_length)
+ return 0;
+ for (i = 0; i < b1->_length; i++)
+ if (cmp_b(&(b1->_buffer[i]), &(b2->_buffer[i])) == 0)
+ return 0;
+ return 1;
+}
+
+static int cmp_b(m_b *b1, m_b *b2)
+{
+ return b1->l == b2->l && b1->c == b2->c;
+}
+
+static int cmp_lseq(m_lseq *b1, m_lseq *b2)
+{
+ int i;
+
+ if (b1->_length != b2->_length)
+ return 0;
+ for (i = 0; i < b1->_length; i++)
+ if (b1->_buffer[i] != b2->_buffer[i])
+ return 0;
+ return 1;
+}
+
+static int cmp_etseq(m_etseq *b1, m_etseq *b2)
+{
+ int i;
+
+ if (b1->_length != b2->_length)
+ return 0;
+ for (i = 0; i < b1->_length; i++)
+ if (!erl_match(b1->_buffer[i], b2->_buffer[i]))
+ return 0;
+ return 1;
+}
+
+static int cmp_et(m_et* b1, m_et *b2)
+{
+ return erl_match(b1->e, b2->e) && b1->l == b2->l;
+}
+
+static int cmp_es(m_es *b1, m_es *b2)
+{
+ return b1->f == b2->f && b1->l == b2->l;
+}
+
+static int cmp_arr1(m_arr1 b1, m_arr1 b2)
+{
+ int i;
+
+ for (i = 0; i < 500; i++)
+ if (b1[i] != b2[i])
+ return 0;
+ return 1;
+}
+
+static int cmp_dd(m_dd b1, m_dd b2)
+{
+
+ int i, j;
+
+ for (i = 0; i < 2; i++)
+ for (j = 0; j < 3; j++)
+ if (b1[i][j] != b2[i][j])
+ return 0;
+ return 1;
+}
+
+
+
+static int cmp_strRec(m_strRec *b1, m_strRec *b2)
+{
+ int i, j;
+
+ if (b1->bb != b2->bb)
+ return 0;
+ if (!cmp_str(b1->str4,b2->str4))
+ return 0;
+ if (b1->str5._length != b2->str5._length)
+ return 0;
+ for (j = 0; j < b1->str5._length; j++)
+ if (b1->str5._buffer[j] != b2->str5._buffer[j])
+ return 0;
+ if (!cmp_str(b1->str6,b2->str6))
+ return 0;
+ for (i = 0; i < 2; i++)
+ for (j = 0; j < 3; j++)
+ if (b1->str7[i][j] != b2->str7[i][j])
+ return 0;
+ for (j = 0; j < 3; j++)
+ if (b1->str8[j] != b2->str8[j])
+ return 0;
+ if (!cmp_str(b1->str9,b2->str9))
+ return 0;
+ if (b1->str10._length != b2->str10._length)
+ return 0;
+ for (j = 0; j < b1->str10._length; j++)
+ if (b1->str10._buffer[j] != b2->str10._buffer[j])
+ return 0;
+ return 1;
+}
+
+
+static int cmp_sseq(m_sseq *b1, m_sseq *b2)
+{
+ int i;
+
+ if (b1->_length != b2->_length)
+ return 0;
+ for (i = 0; i < b1->_length; i++)
+ if (!cmp_str(b1->_buffer[i], b2->_buffer[i]))
+ return 0;
+ return 1;
+}
+
+
+static int cmp_pid(erlang_pid *p1, erlang_pid *p2)
+{
+ return cmp_str(p1->node,p2-> node) &&
+ p1->num == p2->num &&
+ p1->serial == p2->serial &&
+ p1->creation == p2->creation;
+}
+
+static int cmp_port(erlang_port *p1, erlang_port *p2)
+{
+ return cmp_str(p1->node,p2-> node) && p1->id == p2->id;
+}
+
+static int cmp_ref(erlang_ref *p1, erlang_ref *p2)
+{
+ return cmp_str(p1->node, p2->node) &&
+ p1->len == p2->len &&
+ (p1->len < 1 || p1->n[0] == p2->n[0]) &&
+ (p1->len < 2 || p1->n[1] == p2->n[1]) &&
+ (p1->len < 3 || p1->n[2] == p2->n[2]);
+}
+
+static int cmp_s(m_s *b1, m_s *b2)
+{
+ int i;
+
+ if (b1->l != b2->l)
+ return 0;
+ if (b1->sl._length != b2->sl._length)
+ return 0;
+ for (i = 0; i < b1->sl._length; i++)
+ if (b1->sl._buffer[i] != b2->sl._buffer[i])
+ return 0;
+ return 1;
+}
+
+
+static int cmp_ssstr3(m_ssstr3 *b1, m_ssstr3 *b2)
+{
+ int i,j;
+
+ if (b1->_length != b2->_length)
+ return 0;
+ for (i = 0; i < b1->_length; i++) {
+ if (b1->_buffer[i]._length != b2->_buffer[i]._length)
+ return 0;
+ for (j = 0; j < b1->_buffer[i]._length; j++)
+ if (!cmp_str(b1->_buffer[i]._buffer[j],
+ b2->_buffer[i]._buffer[j]))
+ return 0;
+ }
+ return 1;
+}
+
+
+
+static int cmp_ssarr3(m_ssarr3 *b1, m_ssarr3 *b2)
+{
+ int i;
+
+ if (b1->_length != b2->_length)
+ return 0;
+ for (i = 0; i < b1->_length; i++) {
+ if (!cmp_sarr3(&b1->_buffer[i], &b2->_buffer[i]))
+ return 0;
+ }
+ return 1;
+}
+
+static int cmp_sarr3(m_sarr3 *b1, m_sarr3 *b2)
+{
+ int i;
+
+ if (b1->_length != b2->_length)
+ return 0;
+ for (i = 0; i < b1->_length; i++) {
+ if (!cmp_arr3(b1->_buffer[i], b2->_buffer[i]))
+ return 0;
+ }
+ return 1;
+}
+
+static int cmp_arr3(m_arr3 b1, m_arr3 b2)
+{
+ int i;
+
+ for (i = 0; i < sizeof(m_arr3)/sizeof(CORBA_long); i++) {
+ if (b1[i] != b2[i])
+ return 0;
+ }
+ return 1;
+}
+
+/* Print functions */
+static void print_aseq(m_aseq *a)
+{
+ int i;
+ fprintf(stdout, "\nm_aseq size: %ld --------\n", a->_length);
+ for (i = 0; i < a->_length; i++)
+ print_a(&(a->_buffer[i]));
+}
+
+static void print_a(m_a *a)
+{
+ fprintf(stdout, "\nm_a --------\n l: %ld\n d:%f\n", a->l, a->d);
+ print_bseq(&a->y);
+}
+
+static void print_bseq(m_bseq *b)
+{
+ int i;
+
+ fprintf(stdout, "\nm_bseq size: %ld --------\n",b->_length);
+ for (i = 0; i < b->_length; i++)
+ print_b(&(b->_buffer[i]));
+}
+
+static void print_lseq(m_lseq *b)
+{
+ int i;
+
+ fprintf(stdout, "\nm_lseq size: %ld --------\n",b->_length);
+ for (i = 0; i < b->_length; i++)
+ fprintf(stdout, "[%d]: %ld\n", i, b->_buffer[i]);
+}
+
+static void print_b(m_b *b)
+{
+ fprintf(stdout, "\nm_b --------\n l: %ld\n c: %c\n", b->l, b->c);
+}
+
+
+static void print_etseq(m_etseq *b)
+{
+ int i;
+
+ for (i = 0; i < b->_length; i++) {
+ fprintf(stdout, "[%d]:\n", i);
+ erl_print_term(stdout, b->_buffer[i]);
+ }
+}
+
+
+static void print_et(m_et* b)
+{
+ fprintf(stdout, "\net struct --------\n");
+ erl_print_term(stdout, b->e);
+ fprintf(stdout, "long: %ld\n", b->l);
+ fprintf(stdout, "\n--------\n");
+}
+
+static void print_es(m_es *b)
+{
+ fprintf(stdout, "\nm_es --------\n f: %d\n l: %ld\n", b->f, b->l);
+}
+
+
+static void print_arr1(long a[10])
+{
+ int i;
+
+ for (i = 0; i < 10; i++)
+ fprintf(stdout, "\n[%d]: %ld\n", i, a[i]);
+}
+
+static void print_dd(long a[2][3])
+{
+ int i, j;
+
+ fprintf(stdout, "\nlong dd[2][3] --------\n");
+ for (i = 0; i < 2; i++)
+ for (j = 0; j < 3; j++)
+ fprintf(stdout, "\n[%d][%d]: %ld\n", i, j, a[i][j]);
+}
+
+
+static void print_strRec(m_strRec* sr)
+{
+ int i, j;
+
+ fprintf(stdout, "\nboolean bb : %d\n",sr->bb);
+ fprintf(stdout, "string str4 : %s\n",sr->str4);
+ fprintf(stdout, "str7[2][3] :\n");
+ for (i = 0; i < 2; i++)
+ for (j = 0; j < 3; j++)
+ fprintf(stdout, "str7[%d][%d]: %ld\n", i, j, sr->str7[i][j]);
+ fprintf(stdout, "str5._length : %ld\n",sr->str5._length);
+ for (j = 0; j < sr->str5._length; j++)
+ fprintf(stdout, "str5._buffer[%d]: %c\n", j, sr->str5._buffer[j]);
+ fprintf(stdout, "string str6 : %s\n",sr->str6);
+ fprintf(stdout, "str8 :\n");
+ for (j = 0; j < 3; j++)
+ fprintf(stdout, "str8[%d]: %c\n", j, sr->str8[j]);
+ fprintf(stdout, "string str9 : %s\n",sr->str9);
+ fprintf(stdout, "str10._length : %ld\n",sr->str10._length);
+ for (j = 0; j < sr->str10._length; j++)
+ fprintf(stdout, "str10._buffer[%d]: %c\n", j, sr->str10._buffer[j]);
+}
+
+static void print_sseq(m_sseq *b)
+{
+ int i;
+
+ fprintf(stdout, "\nm_sseq size: %ld --------\n",b->_length);
+ for (i = 0; i < b->_length; i++)
+ fprintf(stdout, "%s\n", b->_buffer[i]);
+
+}
+
+
+static void print_pid(erlang_pid *p)
+{
+ fprintf(stdout, "\nerlang_pid --------\n node: %s\n num: %d\n "
+ "serial: %d\n creation: %d\n",
+ p->node, p->num, p->serial, p->creation);
+}
+
+static void print_port(erlang_port *p)
+{
+ fprintf(stdout, "\nerlang_port --------\n node: %s\n id: %d\n "
+ "creation: %d\n", p->node, p->id, p->creation);
+}
+
+static void print_ref(erlang_ref *p)
+{
+ fprintf(stdout, "\nerlang_ref --------\n node: %s\n len: %d\n "
+ "n[0]: %d\n n[1]: %d\n n[2]: %d\n creation: %d\n",
+ p->node, p->len, p->n[0], p->n[1], p->n[2], p->creation);
+}
+
+static void print_term(ETERM *t)
+{
+ fprintf(stdout, "\nETERM --------\n");
+ erl_print_term(stdout, t);
+ fprintf(stdout, "\n--------\n");
+}
+
+static void print_s(m_s *p)
+{
+ int i;
+
+ fprintf(stdout, "\n%ld\n", p->l);
+ for (i = 0; i < p->sl._length; i++)
+ fprintf(stdout, "\n[%d]: %ld\n", i, p->sl._buffer[i]);
+}
+
+
+static void print_ssstr3(m_ssstr3 *b1)
+{
+ int i,j;
+
+ fprintf(stdout, "\nSSSTR3 --------\n");
+ fprintf(stdout,"b1->_length = %ld\n",b1->_length);
+ for (i = 0; i < b1->_length; i++) {
+ fprintf(stdout,"\nb1->_buffer[%d]._length %ld\n",
+ i, b1->_buffer[i]._length);
+ for (j = 0; j < b1->_buffer[i]._length; j++)
+ fprintf(stdout,"b1->_buffer[%d]._buffer[%d] = %s\n",
+ i, j, b1->_buffer[i]._buffer[j]);
+ }
+ fprintf(stdout, "\n--------\n");
+}
+
+static void print_wstr(CORBA_wchar *ws)
+{
+ int i = 0;
+
+ fprintf(stdout, "\nwstr --------\n");
+ while (ws[i]) {
+ fprintf(stdout, "[%d]: %ld\n", i, ws[i]);
+ i++;
+ }
+ fprintf(stdout, "\n--------\n");
+}
+
+
+static void print_ssarr3(m_ssarr3 *b1)
+{
+ int i;
+
+ fprintf(stdout, "\nssarr3 --------\n");
+ fprintf(stdout,"length: %ld\n",b1->_length);
+ fprintf(stdout, "buffer:\n");
+ for (i = 0; i < b1->_length; i++)
+ print_sarr3(&b1->_buffer[i]);
+ fprintf(stdout, "\n--------\n");
+}
+
+static void print_sarr3(m_sarr3 *b1)
+{
+ int i;
+
+ fprintf(stdout, "\nsarr3 --------\n");
+ fprintf(stdout,"length: %ld\n",b1->_length);
+ fprintf(stdout, "buffer:\n");
+ for (i = 0; i < b1->_length; i++)
+ print_arr3(b1->_buffer[i]);
+ fprintf(stdout, "\n--------\n");
+}
+
+static void print_arr3(m_arr3 b1)
+{
+ int i;
+
+ fprintf(stdout, "\narr3 --------\n");
+ for (i = 0; i < sizeof(m_arr3)/sizeof(CORBA_long); i++)
+ fprintf(stdout, "%ld ", b1[i]);
+ fprintf(stdout, "\n--------\n");
+}
+
+static void free_etseq_buf(m_etseq *b)
+{
+ int i;
+
+ for (i = 0; i < b->_length; i++)
+ erl_free_term(b->_buffer[i]);
+}
+
+static void free_et(m_et* b)
+{
+ erl_free_term(b->e);
+}
+
+static void showtime(MyTimeval *start, MyTimeval *stop)
+{
+ MyTimeval elapsed;
+
+ elapsed.tv_sec = stop->tv_sec - start->tv_sec;
+ elapsed.tv_usec = stop->tv_usec - start->tv_usec;
+ while (elapsed.tv_usec < 0) {
+ elapsed.tv_sec -= 1;
+ elapsed.tv_usec += 1000000;
+ }
+ fprintf(stderr,"%ld.%06ld seconds\n",elapsed.tv_sec, elapsed.tv_usec);
+}
+
+static void my_gettimeofday(MyTimeval *tv)
+#ifdef __WIN32__
+#define EPOCH_JULIAN_DIFF 11644473600i64
+{
+ SYSTEMTIME t;
+ FILETIME ft;
+ LONGLONG lft;
+
+ GetSystemTime(&t);
+ SystemTimeToFileTime(&t, &ft);
+ memcpy(&lft, &ft, sizeof(lft));
+ tv->tv_usec = (long) ((lft / 10i64) % 1000000i64);
+ tv->tv_sec = (long) ((lft / 10000000i64) - EPOCH_JULIAN_DIFF);
+}
+#elif defined VXWORKS
+{
+ int rate = sysClkRateGet(); /* Ticks per second */
+ unsigned long ctick = tickGet();
+ tv->tv_sec = ctick / rate; /* secs since reboot */
+ tv->tv_usec = ((ctick - (tv->tv_sec * rate))*1000000)/rate;
+}
+#else
+{
+ gettimeofday(tv, NULL);
+}
+#endif
diff --git a/lib/ic/test/c_client_erl_server_proto_SUITE_data/c_erl_test.idl b/lib/ic/test/c_client_erl_server_proto_SUITE_data/c_erl_test.idl
new file mode 100644
index 0000000000..6d229c3ac1
--- /dev/null
+++ b/lib/ic/test/c_client_erl_server_proto_SUITE_data/c_erl_test.idl
@@ -0,0 +1,173 @@
+
+// %CopyrightBegin%
+//
+// Copyright Ericsson AB 2003-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%
+
+#include "erlang.idl"
+
+
+const short TestConst = 1;
+
+module m {
+
+ const short TestConst = 2;
+
+ struct b {
+ long l;
+ char c;
+ };
+
+ struct simple {
+ long l;
+ b b_t;
+ };
+
+ enum fruit {orange, banana, apple, peach, pear};
+
+ typedef sequence<long> lseq;
+
+ typedef sequence<b> bseq;
+
+ struct a {
+ long l;
+ bseq y;
+ double d;
+ };
+
+ typedef sequence<a> aseq;
+
+ typedef sequence<string> sseq;
+ typedef string str;
+ typedef long myLong;
+
+ typedef long arr1[500], dd[2][3];
+
+ typedef erlang::term apa;
+ typedef erlang::port banan;
+
+ typedef sequence<erlang::term> etseq;
+
+ struct s {
+ long l;
+ sequence<long> sl;
+ };
+
+ struct es {
+ fruit f;
+ myLong l;
+ };
+
+ struct et {
+ erlang::term e;
+ long l;
+ };
+
+
+ typedef sequence<char> str1;
+ typedef string<12> str2;
+ typedef char str3[3];
+
+ typedef sequence<string> sstr3; // sequence of string
+ typedef sequence<sstr3> ssstr3; // sequence of sequences of strings
+
+ typedef long arr3[3]; // array of long
+ typedef sequence<arr3> sarr3; // sequence of array
+ typedef sequence<sarr3> ssarr3; // sequence of sequnces of arrays of strings
+
+ struct strRec{
+ boolean bb;
+ string str4;
+ long str7[3][2];
+ sequence<char> str5;
+ string<12> str6;
+ str3 str8;
+ str2 str9;
+ str1 str10;
+ };
+
+
+ struct dyn {
+ long l;
+ sequence<long> sl;
+ };
+ typedef dyn arr2[1][2];
+
+
+ interface i {
+
+ const short TestConst = 3;
+
+ //arr2 suck(in arr2 x, out arr2 y );
+
+ ///////////////////////////////// attribute long l;
+
+ // simple types
+ void void_test();
+ long long_test(in long a, out long a1);
+ long long longlong_test(in long long a, out long long a1);
+ unsigned short ushort_test(in unsigned short a, out unsigned short a1);
+ unsigned long ulong_test(in unsigned long a, out unsigned long a1);
+ unsigned long long ulonglong_test(in unsigned long long a, out unsigned long long a1);
+ double double_test(in double a, out double a1);
+ char char_test(in char a, out char a1);
+ wchar wchar_test(in wchar a, out wchar a1);
+ octet octet_test(in octet a, out octet a1);
+ boolean bool_test(in boolean a, out boolean a1);
+
+ // Seq. and struct tests
+ b struct_test(in b a, out b a1);
+ es struct2_test(in es a, out es a1);
+ //simple struct3_test(in simple x, out simple y);
+ bseq seq1_test(in bseq a, out bseq a1);
+ aseq seq2_test(in aseq a, out aseq a1);
+ lseq seq3_test(in lseq a, out lseq a1);
+ ssstr3 seq4_test(in ssstr3 a, out ssstr3 a1);
+ ssarr3 seq5_test(in ssarr3 a, out ssarr3 a1);
+
+ // Array tests
+ arr1 array1_test(in arr1 a, out arr1 a1);
+ dd array2_test(in dd a, out dd a1);
+
+ // enum test
+ fruit enum_test(in fruit a, out fruit a1);
+
+ // string tests
+ string string1_test(in string a, out string a1);
+ wstring wstring1_test(in wstring a, out wstring a1);
+ sseq string2_test(in sseq a, out sseq a1);
+ str string3_test(in str a, out str a1);
+ strRec string4_test(in strRec a, out strRec a1);
+
+ // Special erlang types
+ erlang::pid pid_test(in erlang::pid a, out erlang::pid a1);
+ erlang::port port_test(in erlang::port a, out erlang::port a1);
+ erlang::ref ref_test(in erlang::ref a, out erlang::ref a1);
+ erlang::term term_test(in erlang::term a, out erlang::term a1);
+
+ // typedef test
+ long typedef_test(in apa a, in banan b, out apa a1, out banan b1);
+
+ // inlined seq. test
+ s inline_sequence_test(in s a, out s a1);
+
+ // term seq. test
+ etseq term_sequence_test(in etseq a, out etseq a1);
+ // term struct test
+ et term_struct_test(in et a, out et a1);
+
+ };
+
+};
diff --git a/lib/ic/test/c_client_erl_server_proto_SUITE_data/erl_server.erl b/lib/ic/test/c_client_erl_server_proto_SUITE_data/erl_server.erl
new file mode 100644
index 0000000000..09358b7cf9
--- /dev/null
+++ b/lib/ic/test/c_client_erl_server_proto_SUITE_data/erl_server.erl
@@ -0,0 +1,28 @@
+%%
+%% %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(erl_server).
+
+-export([run/0, stop/0]).
+
+run() ->
+ m_i:oe_create().
+
+stop() ->
+ gen_server:cast(cidl_test, stop).
diff --git a/lib/ic/test/c_client_erl_server_proto_SUITE_data/m_i_impl.erl b/lib/ic/test/c_client_erl_server_proto_SUITE_data/m_i_impl.erl
new file mode 100644
index 0000000000..9f231de856
--- /dev/null
+++ b/lib/ic/test/c_client_erl_server_proto_SUITE_data/m_i_impl.erl
@@ -0,0 +1,161 @@
+%%
+%% %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(m_i_impl).
+-include("m.hrl").
+
+-export([init/1, terminate/2, void_test/1, long_test/2, ushort_test/2,
+ longlong_test/2, ulong_test/2, ulonglong_test/2,
+ double_test/2, char_test/2, wchar_test/2, octet_test/2,
+ bool_test/2, struct_test/2, struct2_test/2, seq1_test/2,
+ seq2_test/2, seq3_test/2, seq4_test/2, seq5_test/2,
+ array1_test/2, array2_test/2, enum_test/2, string1_test/2,
+ string2_test/2, string3_test/2, string4_test/2, pid_test/2,
+ port_test/2, ref_test/2, term_test/2, typedef_test/3,
+ inline_sequence_test/2, '_set_l'/2, '_get_l'/1,
+ term_struct_test/2, term_sequence_test/2, wstring1_test/2]).
+
+-define(PRINTDEBUG(Case),
+ io:format("erl_server: case: ~p~n"
+ "erl_server: location: ~p~n", [Case, [?FILE, ?LINE]])).
+-define(PRINTDEBUG2(Case, Msg),
+ io:format("erl_server: case: ~p~n"
+ "erl_server: Msg: ~p~n"
+ "erl_server: location: ~p~n", [Case, Msg, [?FILE, ?LINE]])).
+
+init(Env) ->
+ {ok, []}.
+
+terminate(F, R) ->
+ ok.
+
+'_get_l'(State) ->
+ ?PRINTDEBUG("_get_l"),
+ {reply, State, State}.
+void_test(State) ->
+ ?PRINTDEBUG("void_test"),
+ {reply, ok, State}.
+
+'_set_l'(State, V) ->
+ ?PRINTDEBUG2("_set_l", V),
+ {reply, ok, V}.
+ushort_test(State, V) ->
+ ?PRINTDEBUG2("ushort_test", V),
+ {reply, {V, V}, State}.
+long_test(State, V) ->
+ ?PRINTDEBUG2("long_test", V),
+ {reply, {V, V}, State}.
+longlong_test(State, V) ->
+ ?PRINTDEBUG2("longlong_test", V),
+ {reply, {V, V}, State}.
+ulong_test(State, V) ->
+ ?PRINTDEBUG2("ulong_test", V),
+ {reply, {V, V}, State}.
+ulonglong_test(State, V) ->
+ ?PRINTDEBUG2("ulonglong_test", V),
+ {reply, {V, V}, State}.
+double_test(State, V) ->
+ ?PRINTDEBUG2("double_test", V),
+ {reply, {V, V}, State}.
+char_test(State, V) ->
+ ?PRINTDEBUG2("char_test", V),
+ {reply, {V, V}, State}.
+wchar_test(State, V) ->
+ ?PRINTDEBUG2("wchar_test", V),
+ {reply, {V, V}, State}.
+octet_test(State, V) ->
+ ?PRINTDEBUG2("octet_test", V),
+ {reply, {V, V}, State}.
+bool_test(State, V) ->
+ ?PRINTDEBUG2("bool_test", V),
+ {reply, {V, V}, State}.
+
+struct_test(State, V) ->
+ ?PRINTDEBUG2("struct_test", V),
+ {reply, {V, V}, State}.
+struct2_test(State, V) ->
+ ?PRINTDEBUG2("struct2_test", V),
+ {reply, {V, V}, State}.
+seq1_test(State, V) ->
+ ?PRINTDEBUG2("seq1_test", V),
+ {reply, {V, V}, State}.
+seq2_test(State, V) ->
+ ?PRINTDEBUG2("seq2_test", V),
+ {reply, {V, V}, State}.
+seq3_test(State, V) ->
+ ?PRINTDEBUG2("seq3_test", V),
+ {reply, {V, V}, State}.
+seq4_test(State, V) ->
+ ?PRINTDEBUG2("seq4_test", V),
+ {reply, {V, V}, State}.
+seq5_test(State, V) ->
+ ?PRINTDEBUG2("seq5_test", V),
+ {reply, {V, V}, State}.
+array1_test(State, V) ->
+ ?PRINTDEBUG2("array1_test", V),
+ {reply, {V, V}, State}.
+array2_test(State, V) ->
+ ?PRINTDEBUG2("array2_test", V),
+ {reply, {V, V}, State}.
+enum_test(State, V) ->
+ ?PRINTDEBUG2("enum_test", V),
+ {reply, {V, V}, State}.
+string1_test(State, V) ->
+ ?PRINTDEBUG2("string1_test", V),
+ {reply, {V, V}, State}.
+string2_test(State, V) ->
+ ?PRINTDEBUG2("string2_test", V),
+ {reply, {V, V}, State}.
+string3_test(State, V) ->
+ ?PRINTDEBUG2("string3_test", V),
+ {reply, {V, V}, State}.
+string4_test(State, V) ->
+ ?PRINTDEBUG2("string4_test", V),
+ {reply, {V, V}, State}.
+pid_test(State, V) ->
+ ?PRINTDEBUG2("pid_test", V),
+ {reply, {V, V}, State}.
+port_test(State, V) ->
+ ?PRINTDEBUG2("port_test", binary_to_list(term_to_binary(V))),
+ {reply, {V, V}, State}.
+ref_test(State, V) ->
+ ?PRINTDEBUG2("ref_test", binary_to_list(term_to_binary(V))),
+ {reply, {V, V}, State}.
+term_test(State, V) ->
+ ?PRINTDEBUG2("term_test", V),
+ {reply, {V, V}, State}.
+typedef_test(State, A, B) ->
+ ?PRINTDEBUG2("typedef_test", [A,B]),
+ {reply, {4711, A, B}, State}.
+inline_sequence_test(State, V) ->
+ ?PRINTDEBUG2("inline_sequence_test", V),
+ {reply, {V, V}, State}.
+term_sequence_test(State, V) ->
+ ?PRINTDEBUG2("term_sequence_test", V),
+ {reply, {V, V}, State}.
+term_struct_test(State, V) ->
+ ?PRINTDEBUG2("term_struct_test", V),
+ {reply, {V, V}, State}.
+wstring1_test(State, V) ->
+ ?PRINTDEBUG2("wstring1_test", V),
+ {reply, {V, V}, State}.
+
+
+
+
diff --git a/lib/ic/test/c_client_erl_server_proto_SUITE_data/my.c b/lib/ic/test/c_client_erl_server_proto_SUITE_data/my.c
new file mode 100644
index 0000000000..f8a3b28cc2
--- /dev/null
+++ b/lib/ic/test/c_client_erl_server_proto_SUITE_data/my.c
@@ -0,0 +1,50 @@
+/*
+ * %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 "ic.h"
+#include "m_i.h"
+
+int my_prepare_notification_encoding(CORBA_Environment *env)
+{
+ return oe_prepare_notification_encoding(env);
+}
+
+int my_send_notification(CORBA_Environment *env)
+{
+ return oe_send_notification(env);
+}
+
+int my_prepare_request_encoding(CORBA_Environment *env)
+{
+ return oe_prepare_request_encoding(env);
+}
+
+int my_send_request_and_receive_reply(CORBA_Environment *env)
+{
+ return oe_send_request_and_receive_reply(env);
+}
+
+int my_prepare_reply_decoding(CORBA_Environment *env)
+{
+ return oe_prepare_reply_decoding(env);
+}
+
+
+
diff --git a/lib/ic/test/c_client_erl_server_proto_tmo_SUITE.erl b/lib/ic/test/c_client_erl_server_proto_tmo_SUITE.erl
new file mode 100644
index 0000000000..595c5bf483
--- /dev/null
+++ b/lib/ic/test/c_client_erl_server_proto_tmo_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%
+%%
+%%
+
+%%----------------------------------------------------------------------
+%% Purpose : Test suite for c-client/erl-server
+%%----------------------------------------------------------------------
+
+-module(c_client_erl_server_proto_tmo_SUITE).
+-include("test_server.hrl").
+
+-export([init_per_testcase/2, fin_per_testcase/2,
+ all/1, void_test/1, long_test/1, long_long_test/1,
+ unsigned_short_test/1, unsigned_long_test/1,
+ unsigned_long_long_test/1, double_test/1, char_test/1,
+ wchar_test/1, octet_test/1, bool_test/1, struct_test/1,
+ struct2_test/1, seq1_test/1, seq2_test/1, seq3_test/1,
+ seq4_test/1, seq5_test/1, array1_test/1, array2_test/1,
+ enum_test/1, string1_test/1, string2_test/1, string3_test/1,
+ string4_test/1, pid_test/1, port_test/1, ref_test/1, term_test/1,
+ typedef_test/1, inline_sequence_test/1, term_sequence_test/1,
+ term_struct_test/1, wstring1_test/1]).
+
+-define(DEFAULT_TIMEOUT, 20000).
+-define(PORT_TIMEOUT, 15000).
+-define(ERLANG_SERVER_NAME, idl_erlang_server).
+-define(C_CLIENT_NODE_NAME, c_client_idl_test).
+
+%% Add/remove code path and watchdog before/after each test case.
+%%
+init_per_testcase(_Case, Config) ->
+ DataDir = ?config(data_dir, Config),
+ code:add_patha(DataDir),
+
+ %% Since other test suites use the module m_i, we have
+ %% to make sure we are using the right m_i module.
+ code:purge(m_i),
+ code:load_file(m_i),
+
+ WatchDog = test_server:timetrap(?DEFAULT_TIMEOUT),
+ [{watchdog, WatchDog}| Config].
+
+fin_per_testcase(_Case, Config) ->
+ DataDir = ?config(data_dir, Config),
+ code:del_path(DataDir),
+ WatchDog = ?config(watchdog, Config),
+ test_server:timetrap_cancel(WatchDog).
+
+all(doc) ->
+ "Test of IC with a C-client and an Erlang generic server. "
+ "The communication is via Erlang distribution.";
+all(suite) ->
+ [void_test, long_test, long_long_test, unsigned_short_test,
+ unsigned_long_test, unsigned_long_long_test, double_test,
+ char_test, wchar_test, octet_test, bool_test, struct_test,
+ struct2_test, seq1_test, seq2_test, seq3_test, seq4_test,
+ seq5_test, array1_test, array2_test, enum_test, string1_test,
+ string2_test, string3_test, string4_test, pid_test, port_test,
+ ref_test, term_test, typedef_test, inline_sequence_test,
+ term_sequence_test, term_struct_test, wstring1_test].
+
+
+array1_test(doc) -> "";
+array1_test(suite) -> [];
+array1_test(Config) ->
+ do_test(array1_test, Config).
+
+array2_test(doc) -> "";
+array2_test(suite) -> [];
+array2_test(Config) ->
+ do_test(array2_test, Config).
+
+bool_test(doc) -> "";
+bool_test(suite) -> [];
+bool_test(Config) ->
+ do_test(bool_test, Config).
+
+char_test(doc) -> "";
+char_test(suite) -> [];
+char_test(Config) ->
+ do_test(char_test, Config).
+
+double_test(doc) -> "";
+double_test(suite) -> [];
+double_test(Config) ->
+ do_test(double_test, Config).
+
+enum_test(doc) -> "";
+enum_test(suite) -> [];
+enum_test(Config) ->
+ do_test(enum_test, Config).
+
+inline_sequence_test(doc) -> "";
+inline_sequence_test(suite) -> [];
+inline_sequence_test(Config) ->
+ do_test(inline_sequence_test, Config).
+
+long_long_test(doc) -> "";
+long_long_test(suite) -> [];
+long_long_test(Config) ->
+ do_test(long_long_test, Config).
+
+long_test(doc) -> "";
+long_test(suite) -> [];
+long_test(Config) ->
+ do_test(long_test, Config).
+
+octet_test(doc) -> "";
+octet_test(suite) -> [];
+octet_test(Config) ->
+ do_test(octet_test, Config).
+
+pid_test(doc) -> "";
+pid_test(suite) -> [];
+pid_test(Config) ->
+ do_test(pid_test, Config).
+
+port_test(doc) -> "";
+port_test(suite) -> [];
+port_test(Config) ->
+ do_test(port_test, Config).
+
+ref_test(doc) -> "";
+ref_test(suite) -> [];
+ref_test(Config) ->
+ do_test(ref_test, Config).
+
+seq1_test(doc) -> "";
+seq1_test(suite) -> [];
+seq1_test(Config) ->
+ do_test(seq1_test, Config).
+
+seq2_test(doc) -> "";
+seq2_test(suite) -> [];
+seq2_test(Config) ->
+ do_test(seq2_test, Config).
+
+seq3_test(doc) -> "";
+seq3_test(suite) -> [];
+seq3_test(Config) ->
+ do_test(seq3_test, Config).
+
+seq4_test(doc) -> "";
+seq4_test(suite) -> [];
+seq4_test(Config) ->
+ do_test(seq4_test, Config).
+
+seq5_test(doc) -> "";
+seq5_test(suite) -> [];
+seq5_test(Config) ->
+ do_test(seq5_test, Config).
+
+string1_test(doc) -> "";
+string1_test(suite) -> [];
+string1_test(Config) ->
+ do_test(string1_test, Config).
+
+string2_test(doc) -> "";
+string2_test(suite) -> [];
+string2_test(Config) ->
+ do_test(string2_test, Config).
+
+string3_test(doc) -> "";
+string3_test(suite) -> [];
+string3_test(Config) ->
+ do_test(string3_test, Config).
+
+string4_test(doc) -> "";
+string4_test(suite) -> [];
+string4_test(Config) ->
+ do_test(string4_test, Config).
+
+struct2_test(doc) -> "";
+struct2_test(suite) -> [];
+struct2_test(Config) ->
+ do_test(struct2_test, Config).
+
+struct_test(doc) -> "";
+struct_test(suite) -> [];
+struct_test(Config) ->
+ do_test(struct_test, Config).
+
+term_sequence_test(doc) -> "";
+term_sequence_test(suite) -> [];
+term_sequence_test(Config) ->
+ do_test(term_sequence_test, Config).
+
+term_struct_test(doc) -> "";
+term_struct_test(suite) -> [];
+term_struct_test(Config) ->
+ do_test(term_struct_test, Config).
+
+term_test(doc) -> "";
+term_test(suite) -> [];
+term_test(Config) ->
+ do_test(term_test, Config).
+
+typedef_test(doc) -> "";
+typedef_test(suite) -> [];
+typedef_test(Config) ->
+ do_test(typedef_test, Config).
+
+unsigned_long_long_test(doc) -> "";
+unsigned_long_long_test(suite) -> [];
+unsigned_long_long_test(Config) ->
+ do_test(unsigned_long_long_test, Config).
+
+unsigned_long_test(doc) -> "";
+unsigned_long_test(suite) -> [];
+unsigned_long_test(Config) ->
+ do_test(unsigned_long_test, Config).
+
+unsigned_short_test(doc) -> "";
+unsigned_short_test(suite) -> [];
+unsigned_short_test(Config) ->
+ do_test(unsigned_short_test, Config).
+
+void_test(doc) -> "";
+void_test(suite) -> [];
+void_test(Config) ->
+ do_test(void_test, Config).
+
+wchar_test(doc) -> "";
+wchar_test(suite) -> [];
+wchar_test(Config) ->
+ do_test(wchar_test, Config).
+
+wstring1_test(doc) -> "";
+wstring1_test(suite) -> [];
+wstring1_test(Config) ->
+ do_test(wstring1_test, Config).
+
+
+%% It is here that all tests really are done.
+%%
+
+do_test(Case, Config) ->
+ %% Trap exits
+ process_flag(trap_exit, true),
+ %% Start the server
+ {ok, _Pid} = m_i:oe_create_link([], {local, ?ERLANG_SERVER_NAME}),
+ Node = atom_to_list(node()),
+ %% [NodeName, HostName] = string:tokens(Node, "@"),
+ DataDir = ?config(data_dir, Config),
+ %% io:format("~p: data directory: ~p~n", [?MODULE, DataDir]),
+ Cookie = atom_to_list(erlang:get_cookie()),
+ %% Start C-client node as a port program.
+ Cmd = filename:join([DataDir, "c_client"]) ++
+ " -this-node-name " ++ atom_to_list(?C_CLIENT_NODE_NAME) ++
+ " -peer-node " ++ Node ++
+ " -peer-process-name " ++ atom_to_list(?ERLANG_SERVER_NAME) ++
+ " -cookie " ++ Cookie ++
+ " -test-case " ++ atom_to_list(Case),
+ Port = open_port({spawn, Cmd}, [exit_status, eof, stderr_to_stdout]),
+ Res = wait_for_completion(Port),
+ %% Kill off node if there was timeout
+ case Res of
+ {error, timeout} ->
+ catch rpc:cast(?C_CLIENT_NODE_NAME, erlang, halt, [1]);
+ _ ->
+ ok
+ end,
+ process_flag(trap_exit, false),
+ catch m_i:stop(?ERLANG_SERVER_NAME),
+ ok = Res.
+
+
+%% Wait for eof *and* exit status, but return if exit status indicates
+%% an error, or we have been waiting more than PORT_TIMEOUT seconds.
+%%
+wait_for_completion(Port) ->
+ wait_for_completion(Port, 0).
+
+wait_for_completion(Port, N) when N < 2 ->
+ receive
+ {Port, {data, Bytes}} ->
+ %% Relay output
+ io:format("~s", [Bytes]),
+ wait_for_completion(Port, N);
+ {Port, {exit_status, 0}} ->
+ wait_for_completion(Port, N + 1);
+ {Port, {exit_status, Status}} ->
+ {error, Status};
+ {Port, eof} ->
+ wait_for_completion(Port, N + 1);
+ {'EXIT', Port, Reason} ->
+ io:format("Port exited with reason: ~w~n", [Reason]),
+ wait_for_completion(Port, N);
+ {'EXIT', From, Reason} ->
+ io:format("Got unexpected exit: ~p~n", [{'EXIT', From, Reason}]),
+ wait_for_completion(Port, N)
+ after ?PORT_TIMEOUT ->
+ {error, timeout}
+ end;
+wait_for_completion(_, _) ->
+ ok.
+
+
+
diff --git a/lib/ic/test/c_client_erl_server_proto_tmo_SUITE_data/Makefile.src b/lib/ic/test/c_client_erl_server_proto_tmo_SUITE_data/Makefile.src
new file mode 100644
index 0000000000..62672e0b95
--- /dev/null
+++ b/lib/ic/test/c_client_erl_server_proto_tmo_SUITE_data/Makefile.src
@@ -0,0 +1,146 @@
+#
+# %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%
+#
+#
+# Makefile.src for c_client_erl_server test
+# Note: This file *must* work for both Unix and Windows
+#
+# We use both `rm' (Unix) and `del' (Windows) for removing files, but
+# with a `-' in front so that the error in not finding `rm' (`del') on
+# Windows (Unix) is ignored.
+#
+# VxWorks? XXX
+#
+
+.SUFFIXES:
+.SUFFIXES: .c .h .erl .idl @obj@ .@EMULATOR@
+
+
+# Variables from ts:
+#
+
+ERL_INCLUDE = @erl_include@
+
+IC_INCLUDE_PATH = @ic_include_path@
+IC_LIB = @ic_libpath@@DS@@ic_lib@
+
+ERL_INTERFACE_INCLUDE = @erl_interface_include@
+ERL_INTERFACE_LIB = @erl_interface_libpath@@DS@@erl_interface_lib@
+ERL_INTERFACE_EILIB = @erl_interface_libpath@@DS@@erl_interface_eilib@
+ERL_INTERFACE_THREADLIB = @erl_interface_threadlib@
+ERL_INTERFACE_SOCK_LIBS = @erl_interface_sock_libs@
+
+CC = @CC@
+## XXX Should set warning flag with a DEBUG_FLAG
+CFLAGS = @CFLAGS@ @DEFS@ -I@erl_include@ \
+ -I@ic_include_path@ -I@erl_interface_include@
+
+LD = @LD@
+LDFLAGS = @CROSSLDFLAGS@
+LIBS = $(IC_LIB) $(ERL_INTERFACE_LIB) $(ERL_INTERFACE_EILIB) \
+ $(ERL_INTERFACE_THREADLIB) @LIBS@ $(ERL_INTERFACE_SOCK_LIBS)
+ERLC = erlc
+
+# Generated C header files
+GEN_H_FILES = \
+ m.h \
+ m_i.h \
+ oe_c_erl_test.h
+
+# Generated C files
+GEN_C_FILES = \
+ m.c \
+ m_i.c \
+ oe_c_erl_test.c \
+ oe_code_m_a.c \
+ oe_code_m_arr1.c \
+ oe_code_m_arr2.c \
+ oe_code_m_arr3.c \
+ oe_code_m_aseq.c \
+ oe_code_m_b.c \
+ oe_code_m_bseq.c \
+ oe_code_m_dd.c \
+ oe_code_m_dyn.c \
+ oe_code_m_dyn_sl.c \
+ oe_code_m_es.c \
+ oe_code_m_et.c \
+ oe_code_m_etseq.c \
+ oe_code_m_fruit.c \
+ oe_code_m_lseq.c \
+ oe_code_m_s.c \
+ oe_code_m_s_sl.c \
+ oe_code_m_sarr3.c \
+ oe_code_m_simple.c \
+ oe_code_m_ssarr3.c \
+ oe_code_m_sseq.c \
+ oe_code_m_ssstr3.c \
+ oe_code_m_sstr3.c \
+ oe_code_m_str1.c \
+ oe_code_m_str3.c \
+ oe_code_m_strRec.c \
+ oe_code_m_strRec_str5.c \
+ oe_code_m_strRec_str7.c
+
+GEN_HRL_FILES = \
+ m.hrl \
+ m_i.hrl \
+ oe_c_erl_test.hrl
+
+GEN_ERL_FILES = \
+ m.erl \
+ m_arr2.erl \
+ m_arr3.erl \
+ m_i.erl \
+ m_str3.erl \
+ oe_c_erl_test.erl
+
+C_FILES = $(GEN_C_FILES) c_client.c my.c
+
+OBJS = $(C_FILES:.c=@obj@)
+
+PGMS = c_client@exe@
+
+ERL_FILES = $(GEN_ERL_FILES) m_i_impl.erl
+
+EBINS = $(ERL_FILES:.erl=.@EMULATOR@)
+
+
+all: $(PGMS) $(EBINS)
+
+clean:
+ -rm -f $(OBJS) $(GEN_C_FILES) $(GEN_H_FILES) $(PGMS) \
+ $(EBINS) $(GEN_ERL_FILES) $(GEN_HRL_FILES)
+ -del /F /Q $(OBJS) $(GEN_C_FILES) $(GEN_H_FILES) $(PGMS) \
+ $(EBINS) $(GEN_ERL_FILES) $(GEN_HRL_FILES)
+
+$(PGMS): $(OBJS)
+ $(LD) $(LDFLAGS) -o $@ $(OBJS) $(LIBS)
+
+$(GEN_C_FILES) $(GEN_H_FILES): c_erl_test.idl
+ $(ERLC) -I $(IC_INCLUDE_PATH) "+{be,c_client}" \
+ "+{user_protocol,my}" "+{c_timeout,{5000,5000}}" c_erl_test.idl
+
+$(GEN_ERL_FILES) $(GEN_HRL_FILES): c_erl_test.idl
+ $(ERLC) -I $(IC_INCLUDE_PATH) "+{be,erl_genserv}" c_erl_test.idl
+
+.c@obj@:
+ $(CC) -c -o $*@obj@ $(CFLAGS) $<
+
+.erl.@EMULATOR@:
+ $(ERLC) -I $(IC_INCLUDE_PATH) $<
+
diff --git a/lib/ic/test/c_client_erl_server_proto_tmo_SUITE_data/c_client.c b/lib/ic/test/c_client_erl_server_proto_tmo_SUITE_data/c_client.c
new file mode 100644
index 0000000000..b2c5b0c836
--- /dev/null
+++ b/lib/ic/test/c_client_erl_server_proto_tmo_SUITE_data/c_client.c
@@ -0,0 +1,1763 @@
+/*
+ * %CopyrightBegin%
+ *
+ * Copyright Ericsson AB 2004-2010. All Rights Reserved.
+ *
+ * The contents of this file are subject to the Erlang Public License,
+ * Version 1.1, (the "License"); you may not use this file except in
+ * compliance with the License. You should have received a copy of the
+ * Erlang Public License along with this software. If not, it can be
+ * retrieved online at http://www.erlang.org/.
+ *
+ * Software distributed under the License is distributed on an "AS IS"
+ * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+ * the License for the specific language governing rights and limitations
+ * under the License.
+ *
+ * %CopyrightEnd%
+ *
+ */
+/* C-client for test of IC.
+ *
+ * TODO:
+ *
+ * 1. XXX #includes for VxWorks, Windows
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#ifndef __WIN32__
+# include <unistd.h>
+#endif
+
+#include <string.h>
+
+#ifdef __WIN32__
+# include <time.h>
+# include <sys/timeb.h>
+#elif defined VXWORKS
+#include <time.h>
+#include <sys/times.h>
+#else
+#include <sys/time.h>
+#endif
+
+#include <ctype.h>
+
+#ifdef __WIN32__
+# include <winsock2.h>
+# include <windows.h>
+#else
+# include <sys/types.h>
+# include <sys/socket.h>
+# include <netinet/in.h>
+# include <arpa/inet.h>
+# include <netdb.h>
+#endif
+
+#include "ei.h"
+#include "erl_interface.h"
+#include "m_i.h"
+
+#define HOSTNAMESZ 256
+#define NODENAMESZ 512
+
+#define INBUFSZ 10
+#define OUTBUFSZ 0
+
+#define MAXTRIES 5
+
+#define CHECK_EXCEPTION(x) \
+ if ((x)->_major != CORBA_NO_EXCEPTION) { \
+ fprintf(stderr,"\n\nException: %s\n\n", \
+ (char *)CORBA_exception_value((x))); \
+ CORBA_exception_free((x)); \
+ return -1; \
+ } \
+
+/* XXX Should free things here too! */
+#define RETURN_IF_OK(x) \
+ if ((x)) {\
+ fprintf(stdout, "ok\n");\
+ return 0;\
+ }\
+
+#define cmp_str(x,y) (!strcmp((x),(y)))
+#define cmp_wstr(x,y) (!ic_wstrcmp((x),(y)))
+
+typedef CORBA_Environment IC_Env;
+
+typedef int (*TestFunc)(IC_Env *);
+typedef struct {
+ char *name;
+ TestFunc func;
+} TestCase;
+
+static char longtext[] =
+"Introduction The IC application is an IDL compiler implemented in Erlang."
+" The IDL compiler generates client stubs and server skeletons."
+" Several back-ends are supported, and they fall into three main groups."
+" For more details on IC compiler options consult the ic(3) manual page."
+" Argument passing cases 1 Caller allocates all necessary storage,"
+" except that which may be encapsulated and managed within the parameter itself."
+" 2 The caller allocates a pointer and passes it by reference to the callee."
+" The callee sets the pointer to point to a valid instance of the parameter's type."
+" The caller is responsible for releasing the returned storage."
+" Following completion of a request, the caller is not allowed to modify any values"
+" in the returned storage. To do so the caller must first copy the returned instance"
+" into a new instance, then modify the new instance. 3 The caller allocates a"
+" pointer to an array slice which has all the same dimensions of the original"
+" array except the first, and passes it by reference to the callee. The callee sets"
+" the pointer to point to a valid instance of the array. The caller is responsible for"
+" releasing the returned storage. Following completion of a request, the caller is not"
+" allowed to modify any values in the returned storage. To do so the caller must first"
+" copy the returned instance into a new instance, then modify the new instance."
+" Generated Files Two files will be generated for each scope. One set of files will be"
+" generated for each module and each interface scope. An extra set is generated for"
+" those definitions at top level scope. One of the files is a header file(.h), and the"
+" other file is a C source code file (.c). In addition to these files a number of C"
+" source files will be generated for type encodings, they are named according to the "
+"following template: oe_code_<type>.c.";
+static char this_node[NODENAMESZ + 1];
+static char *progname;
+
+/* Test function prototypes */
+
+static int void_test(IC_Env *env);
+static int long_test(IC_Env *env);
+static int long_long_test(IC_Env *env);
+static int unsigned_short_test(IC_Env *env);
+static int unsigned_long_test(IC_Env *env);
+static int unsigned_long_long_test(IC_Env *env);
+static int double_test(IC_Env *env);
+static int char_test(IC_Env *env);
+static int wchar_test(IC_Env *env);
+static int octet_test(IC_Env *env);
+static int bool_test(IC_Env *env);
+static int struct_test(IC_Env *env);
+static int struct2_test(IC_Env *env);
+static int seq1_test(IC_Env *env);
+static int seq2_test(IC_Env *env);
+static int seq3_test(IC_Env *env);
+static int seq4_test(IC_Env *env);
+static int seq5_test(IC_Env *env);
+static int array1_test(IC_Env *env);
+static int array2_test(IC_Env *env);
+static int enum_test(IC_Env *env);
+static int string1_test(IC_Env *env);
+static int string2_test(IC_Env *env);
+static int string3_test(IC_Env *env);
+static int string4_test(IC_Env *env);
+static int pid_test(IC_Env *env);
+static int port_test(IC_Env *env);
+static int ref_test(IC_Env *env);
+static int term_test(IC_Env *env);
+static int typedef_test(IC_Env *env);
+static int inline_sequence_test(IC_Env *env);
+static int term_sequence_test(IC_Env *env);
+static int term_struct_test(IC_Env *env);
+static int wstring1_test(IC_Env *env);
+
+static TestCase test_cases[] = {
+ {"void_test", void_test},
+ {"long_test", long_test},
+ {"long_long_test", long_long_test},
+ {"unsigned_short_test", unsigned_short_test},
+ {"unsigned_long_test", unsigned_long_test},
+ {"unsigned_long_long_test", unsigned_long_long_test},
+ {"double_test", double_test},
+ {"char_test", char_test},
+ {"wchar_test", wchar_test},
+ {"octet_test", octet_test},
+ {"bool_test", bool_test},
+ {"struct_test", struct_test},
+ {"struct2_test", struct2_test},
+ {"seq1_test", seq1_test},
+ {"seq2_test", seq2_test},
+ {"seq3_test", seq3_test},
+ {"seq4_test", seq4_test},
+ {"seq5_test", seq5_test},
+ {"array1_test", array1_test},
+ {"array2_test", array2_test},
+ {"enum_test", enum_test},
+ {"string1_test", string1_test},
+ {"string2_test", string2_test},
+ {"string3_test", string3_test},
+ {"string4_test", string4_test},
+ {"pid_test", pid_test},
+ {"port_test", port_test},
+ {"ref_test", ref_test},
+ {"term_test", term_test},
+ {"typedef_test", typedef_test},
+ {"inline_sequence_test", inline_sequence_test},
+ {"term_sequence_test", term_sequence_test},
+ {"term_struct_test", term_struct_test},
+ {"wstring1_test", wstring1_test},
+ {"", NULL}
+};
+
+/* Other prototypes */
+static int cmp_aseq(m_aseq *a1, m_aseq *a2);
+static int cmp_a(m_a *a1, m_a *a2);
+static int cmp_bseq(m_bseq *b1, m_bseq *b2);
+static int cmp_b(m_b *b1, m_b *b2);
+static int cmp_lseq(m_lseq *b1, m_lseq *b2);
+static int cmp_etseq(m_etseq *b1, m_etseq *b2);
+static int cmp_et(m_et* b1, m_et *b2);
+static int cmp_es(m_es *b1, m_es *b2);
+static int cmp_arr1(m_arr1 b1, m_arr1 b2);
+static int cmp_dd(m_dd b1, m_dd b2);
+static int cmp_strRec(m_strRec *b1, m_strRec *b2);
+static int cmp_sseq(m_sseq *b1, m_sseq *b2);
+static int cmp_pid(erlang_pid *p1, erlang_pid *p2);
+static int cmp_port(erlang_port *p1, erlang_port *p2);
+static int cmp_ref(erlang_ref *p1, erlang_ref *p2);
+static int cmp_s(m_s *b1, m_s *b2);
+static int cmp_ssstr3(m_ssstr3 *b1, m_ssstr3 *b2);
+static int cmp_ssarr3(m_ssarr3 *b1, m_ssarr3 *b2);
+static int cmp_sarr3(m_sarr3 *b1, m_sarr3 *b2);
+static int cmp_arr3(m_arr3 b1, m_arr3 b2);
+
+static void print_aseq(m_aseq *a);
+static void print_a(m_a *a);
+static void print_bseq(m_bseq *b);
+static void print_lseq(m_lseq *b);
+static void print_b(m_b *b);
+static void print_etseq(m_etseq *b);
+static void print_et(m_et* b);
+static void print_es(m_es *b);
+static void print_arr1(long a[500]);
+static void print_dd(long a[2][3]);
+static void print_strRec(m_strRec* sr);
+static void print_sseq(m_sseq *b);
+static void print_pid(erlang_pid *p);
+static void print_port(erlang_port *p);
+static void print_ref(erlang_ref *p);
+static void print_term(ETERM *t);
+static void print_s(m_s *p);
+static void print_ssstr3(m_ssstr3 *b1);
+static void print_ssarr3(m_ssarr3 *b1);
+static void print_sarr3(m_sarr3 *b1);
+static void print_arr3(m_arr3 b1);
+static void print_wstr(CORBA_wchar *ws);
+
+static void free_etseq_buf(m_etseq *b);
+static void free_et(m_et* b);
+
+#ifdef __WIN32__
+typedef struct {
+ long tv_sec;
+ long tv_usec;
+} MyTimeval;
+#else
+typedef struct timeval MyTimeval;
+#endif
+static void my_gettimeofday(MyTimeval *tv);
+static void showtime(MyTimeval *start, MyTimeval *stop);
+static void usage(void);
+static void done(int r);
+
+
+
+/* main */
+
+#ifdef VXWORKS
+int client(int argc, char **argv)
+#else
+int main(int argc, char **argv)
+#endif
+{
+ struct hostent *hp;
+ erlang_pid pid;
+ MyTimeval start, stop;
+ int i, fd, ires, tres;
+ IC_Env *env;
+ int tries = 0;
+ char *this_node_name = NULL;
+ char *peer_node = NULL;
+ char *peer_process_name = NULL;
+ char *cookie = NULL;
+ char host[HOSTNAMESZ + 1];
+ TestFunc test_func = NULL;
+ TestCase *test_case;
+ char *test_case_name = NULL;
+
+#ifdef __WIN32__
+ WORD wVersionRequested;
+ WSADATA wsaData;
+
+ wVersionRequested = MAKEWORD(2, 0);
+
+ if (WSAStartup(wVersionRequested, &wsaData) != 0) {
+ fprintf(stderr, "Could not load winsock2 v2.0 compatible DLL");
+ exit(1);
+ }
+#endif
+
+ progname = argv[0];
+ host[HOSTNAMESZ] = '\0';
+ if (gethostname(host, HOSTNAMESZ) < 0) {
+ fprintf(stderr, "Can't find own hostname\n");
+ done(1);
+ }
+ if ((hp = gethostbyname(host)) == 0) {
+ fprintf(stderr, "Can't get ip address for host %s\n", host);
+ done(1);
+ }
+ for (i = 1; i < argc; i++) {
+ if (cmp_str(argv[i], "-help")) {
+ usage();
+ done(0);
+ } else if (cmp_str(argv[i], "-this-node-name")) {
+ i++;
+ this_node_name = argv[i];
+ } else if (cmp_str(argv[i], "-peer-node")) {
+ i++;
+ peer_node = argv[i];
+ } else if (cmp_str(argv[i], "-peer-process-name")) {
+ i++;
+ peer_process_name = argv[i];
+ } else if (cmp_str(argv[i], "-cookie")) {
+ i++;
+ cookie = argv[i];
+ } else if (cmp_str(argv[i], "-test-case")) {
+ i++;
+ test_case_name = argv[i];
+ } else {
+ fprintf(stderr, "Error : invalid argument \"%s\"\n", argv[i]);
+ usage();
+ done(1);
+ }
+ }
+
+ if (this_node_name == NULL || peer_node == NULL || test_case_name == NULL
+ || peer_process_name == NULL || cookie == NULL) {
+ fprintf(stderr, "Error: missing option\n");
+ usage();
+ done(1);
+ }
+
+ test_case = test_cases;
+ while (test_case->func) {
+ if (cmp_str(test_case->name, test_case_name)) {
+ test_func = test_case->func;
+ break;
+ }
+ test_case++;
+ }
+ if (test_func == NULL) {
+ fprintf(stderr, "Error: illegal test case: \"%s\"\n", test_case_name);
+ done(1);
+ }
+
+ /* Behead hostname at first dot */
+ for (i=0; host[i] != '\0'; i++) {
+ if (host[i] == '.') { host[i] = '\0'; break; }
+ }
+ sprintf(this_node, "%s@%s", this_node_name, host);
+ fprintf(stderr, "c_client: this node: \"%s\"\n", this_node);
+ fprintf(stderr, "c_client: peer node: \"%s\"\n", peer_node);
+ fprintf(stderr, "c_client: test case: \"%s\"\n", test_case_name);
+
+ fprintf(stderr, "c_client: starting\n");
+
+ /* initialize erl_interface */
+ erl_init(NULL, 0);
+
+ for (tries = 0; tries < MAXTRIES; tries++) {
+
+ /* connect to erlang node */
+
+ ires = erl_connect_xinit(host, this_node_name, this_node,
+ (struct in_addr *)*hp->h_addr_list,
+ cookie, 0);
+
+ fprintf(stderr, "c_client: erl_connect_xinit(): %d\n", ires);
+
+ fd = erl_connect(peer_node);
+ fprintf(stderr, "c_client: erl_connect(): %d\n", fd);
+
+ if (fd >= 0)
+ break;
+ fprintf(stderr, "c_client: cannot connect, retrying\n");
+ }
+ if (fd < 0) {
+ fprintf(stderr, "c_client: cannot connect, exiting\n");
+ done(1);
+ }
+ env = CORBA_Environment_alloc(INBUFSZ, OUTBUFSZ);
+ env->_fd = fd;
+ strcpy(env->_regname, peer_process_name);
+ env->_to_pid = NULL;
+ env->_from_pid = &pid;
+
+ strcpy(pid.node, this_node);
+ pid.num = fd;
+ pid.serial = 0;
+ pid.creation = 0;
+
+ my_gettimeofday(&start);
+ tres = test_func(env); /* Call test case */
+ my_gettimeofday(&stop);
+ showtime(&start, &stop);
+ erl_close_connection(fd);
+
+ printf("c_client: env->_inbuf before : %d\n", INBUFSZ);
+ printf("c_client: env->_outbuf before : %d\n", OUTBUFSZ);
+ printf("c_client: env->_inbuf after : %d\n", env->_inbufsz);
+ printf("c_client: env->_outbuf after : %d\n", env->_outbufsz);
+
+ CORBA_free(env->_inbuf);
+ CORBA_free(env->_outbuf);
+ CORBA_free(env);
+ done(tres);
+}
+
+static void usage()
+{
+ fprintf(stderr, "Usage: %s [-help] -this-node-name <name> "
+ "-peer-node <nodename> -peer-process-name <name> "
+ "-cookie <cookie> -test-case <test case name>\n", progname);
+ fprintf(stderr, "Example:\n %s -this-node-name kalle "
+ "-peer-node olle@home -peer-process-name idltest "
+ "-cookie oa678er -test-case octet_test\n", progname);
+}
+
+static void done(int r)
+{
+#ifdef __WIN32__
+ WSACleanup();
+#endif
+ exit(r);
+}
+
+
+/* TESTS */
+
+static int void_test(IC_Env *env)
+{
+ fprintf(stdout, "\n======== m_i_void test ======\n\n");
+ m_i_void_test(NULL,env);
+ CHECK_EXCEPTION(env);
+ RETURN_IF_OK(1);
+}
+
+static int long_test(IC_Env *env)
+{
+ long l = 4711, lo, lr;
+
+ fprintf(stdout, "\n======== m_i_long test ======\n\n");
+ lr = m_i_long_test(NULL, l, &lo, env);
+ CHECK_EXCEPTION(env);
+ RETURN_IF_OK(l == lo && l == lr);
+ if (l != lo)
+ fprintf(stdout, " out parameter error, sent: %ld, got: %ld\n", l, lo);
+ if (l != lr)
+ fprintf(stdout, " result error, sent: %ld, got: %ld\n", l, lr);
+ return -1;
+}
+
+static int long_long_test(IC_Env *env)
+{
+ CORBA_long_long ll = 4711, llo, llr;
+
+ fprintf(stdout, "\n======== m_i_longlong test ======\n\n");
+ llr = m_i_longlong_test(NULL, ll, &llo, env);
+ CHECK_EXCEPTION(env);
+ RETURN_IF_OK(ll == llo && ll == llr);
+ if (ll != llo)
+ fprintf(stdout, " out parameter error, sent: %ld, got: %ld\n",
+ ll, llo);
+ if (ll != llr)
+ fprintf(stdout, " result error, sent: %ld, got: %ld\n", ll, llr);
+ return -1;
+}
+
+static int unsigned_short_test(IC_Env *env)
+{
+ unsigned short x, y = 2, z;
+
+ fprintf(stdout, "\n======== m_i_ushort test ======\n\n");
+ x = m_i_ushort_test(NULL, y, &z, env);
+ CHECK_EXCEPTION(env);
+ RETURN_IF_OK(y == z && y == x);
+ if (y != z)
+ fprintf(stdout, " out parameter error, sent: %d, got: %d\n", y, z);
+ if (y != x)
+ fprintf(stdout, " result error, sent: %d, got: %d\n", y, x);
+ return -1;
+}
+
+
+static int unsigned_long_test(IC_Env *env)
+{
+ unsigned long ul = 5050, ulo, ulr;
+
+ fprintf(stdout, "\n======== m_i_ulong test ======\n\n");
+ ulr = m_i_ulong_test(NULL, ul, &ulo, env);
+ CHECK_EXCEPTION(env);
+ RETURN_IF_OK(ul == ulo && ul == ulr);
+ if (ul != ulo)
+ fprintf(stdout, " out parameter error, sent: %lu, got: %lu\n",
+ ul, ulo);
+ if (ul != ulr)
+ fprintf(stdout, " result error, sent: %lu, got: %lu\n", ul, ulr);
+ return -1;
+}
+
+/*
+ * Note: CORBA_unsigned_long_long is in fact a plain long.
+ */
+static int unsigned_long_long_test(IC_Env *env)
+{
+ CORBA_unsigned_long_long ull = 5050, ullo, ullr;
+
+ fprintf(stdout, "\n======== m_i_ulonglong test ======\n\n");
+ ullr = m_i_ulonglong_test(NULL, ull, &ullo, env);
+ CHECK_EXCEPTION(env);
+ RETURN_IF_OK(ull == ullo && ull == ullr);
+ if (ull != ullo)
+ fprintf(stdout, " out parameter error, sent: %lu, got: %lu\n",
+ ull, ullo);
+ if (ull != ullr)
+ fprintf(stdout, " result error, sent: %lu, got: %lu\n",
+ ull, ullr);
+ return -1;
+}
+
+static int double_test(IC_Env *env)
+{
+ double d = 12.1212, db, dr;
+
+ fprintf(stdout, "\n======== m_i_double test ======\n\n");
+ dr = m_i_double_test(NULL, d, &db, env);
+ CHECK_EXCEPTION(env);
+ RETURN_IF_OK(d == db && d == dr);
+ if (d != db)
+ fprintf(stdout, " out parameter error, sent: %f, got: %f\n", d, db);
+ if (d != dr)
+ fprintf(stdout, " result error, sent: %f, got: %f\n", d, dr);
+ return -1;
+}
+
+static int char_test(IC_Env *env)
+{
+ char c = 'g', co, cr;
+
+ /* char test */
+ fprintf(stdout, "\n======== m_i_char test ======\n\n");
+ cr = m_i_char_test(NULL, c, &co, env);
+ CHECK_EXCEPTION(env);
+ RETURN_IF_OK(c == co && c == cr);
+ if (c !=co)
+ fprintf(stdout, " out parameter error, sent: %c, got: %c\n", c, co);
+ if (c != cr)
+ fprintf(stdout, " result error, sent: %c, got: %c\n", c, cr);
+ return -1;
+}
+
+static int wchar_test(IC_Env *env)
+{
+ CORBA_wchar wc = 103, wco, wcr;
+
+ fprintf(stdout, "\n======== m_i_wchar test ======\n\n");
+ wcr = m_i_wchar_test(NULL, wc, &wco, env);
+ CHECK_EXCEPTION(env);
+ RETURN_IF_OK(wc == wco && wc == wcr);
+ if (wc != wco)
+ fprintf(stdout, " out parameter error, sent: %lu, got: %lu\n",
+ wc, wco);
+ if (wc != wcr)
+ fprintf(stdout, " result error, sent: %lu, got: %lu\n",
+ wc, wcr);
+ return -1;
+}
+
+static int octet_test(IC_Env *env)
+{
+ char o ='r', oo, or;
+
+ fprintf(stdout, "\n======== m_i_octet test ======\n\n");
+ or = m_i_octet_test(NULL, o, &oo, env);
+ CHECK_EXCEPTION(env);
+ RETURN_IF_OK(o == oo && o == or);
+ if (o != oo)
+ fprintf(stdout, " out parameter error, sent: %c, got: %c\n", o, oo);
+ if (o != or)
+ fprintf(stdout, " result error, sent: %c, got: %c\n", o, or);
+ return -1;
+}
+
+static int bool_test(IC_Env *env)
+{
+ unsigned char i = 0, io, ir;
+
+ fprintf(stdout, "\n======== m_i_bool test ======\n\n");
+ ir = m_i_bool_test(NULL, i, &io, env);
+ CHECK_EXCEPTION(env);
+ RETURN_IF_OK(i == io && i == ir);
+ if (i != io)
+ fprintf(stdout, " out parameter error, sent: %d, got: %d\n", i, io);
+ if (i != ir)
+ fprintf(stdout, " result error, sent: %d, got: %d\n", i, ir);
+ return -1;
+}
+
+static int struct_test(IC_Env *env)
+{
+ m_b b = {4711, 'a'}, bo, br;
+
+ fprintf(stdout, "\n======== m_i_struct test ======\n\n");
+ br = m_i_struct_test(NULL, &b, &bo, env);
+ CHECK_EXCEPTION(env);
+ RETURN_IF_OK(cmp_b(&b, &bo) && cmp_b(&b, &br));
+ if (!cmp_b(&b, &bo)) {
+ fprintf(stdout, " out parameter error, sent:\n");
+ print_b(&b);
+ fprintf(stdout, " got:\n");
+ print_b(&bo);
+ fprintf(stdout, "\n");
+ }
+ if (!cmp_b(&b, &br)) {
+ fprintf(stdout, " result error, sent:\n");
+ print_b(&b);
+ fprintf(stdout, " got:\n");
+ print_b(&br);
+ fprintf(stdout, "\n");
+ }
+ return -1;
+}
+
+static int struct2_test(IC_Env *env)
+{
+ m_es esi = {m_peach, 5050}, eso, esr;
+
+ fprintf(stdout, "\n======== m_i_struct2 test ======\n\n");
+ esr = m_i_struct2_test(NULL, &esi, &eso, env);
+ CHECK_EXCEPTION(env);
+ RETURN_IF_OK(cmp_es(&esi, &eso) && cmp_es(&esi, &esr));
+ if (!cmp_es(&esi, &eso)) {
+ fprintf(stdout, " out parameter error, sent:\n");
+ print_es(&esi);
+ fprintf(stdout, " got:\n");
+ print_es(&eso);
+ fprintf(stdout, "\n");
+ }
+ if (!cmp_es(&esi, &esr)) {
+ fprintf(stdout, " result error, sent:\n");
+ print_es(&esi);
+ fprintf(stdout, " got:\n");
+ print_es(&esr);
+ fprintf(stdout, "\n");
+ }
+ return -1;
+}
+
+
+static int seq1_test(IC_Env *env)
+{
+ m_bseq bs, *bso, *bsr;
+
+ m_b ba[3] = {{4711, 'a'}, {4712, 'b'}, {4713, 'c'}};
+ bs._length = 3;
+ bs._buffer = ba;
+
+ fprintf(stdout, "\n======== m_i_seq1 test ======\n\n");
+ bsr = m_i_seq1_test(NULL, &bs, &bso, env);
+ CHECK_EXCEPTION(env);
+ RETURN_IF_OK(cmp_bseq(&bs, bso) && cmp_bseq(&bs, bsr));
+ if (!cmp_bseq(&bs, bso)) {
+ fprintf(stdout, " out parameter error, sent:\n");
+ print_bseq(&bs);
+ fprintf(stdout, " got:\n");
+ print_bseq(bso);
+ fprintf(stdout, "\n");
+ }
+ if (!cmp_bseq(&bs, bsr)) {
+ fprintf(stdout, " result error, sent:\n");
+ print_bseq(&bs);
+ fprintf(stdout, " got:\n");
+ print_bseq(bsr);
+ fprintf(stdout, "\n");
+ }
+ CORBA_free(bso);
+ CORBA_free(bsr);
+ return -1;
+}
+
+static int seq2_test(IC_Env *env)
+{
+ m_b ba[3] = {{4711, 'a'}, {4712, 'b'}, {4713, 'c'}};
+ m_a a;
+ m_a aa[2];
+ m_aseq as, *aso, *asr;
+
+ a.l = 9999;
+ a.y._length = 3;
+ a.y._buffer = ba;
+ a.d = 66.89898989;
+
+ aa[0] = a;
+ aa[1] = a;
+ as._length = 2;
+ as._buffer = aa;
+
+ fprintf(stdout, "\n======== m_i_seq2 test ======\n\n");
+ asr = m_i_seq2_test(NULL, &as, &aso, env);
+ CHECK_EXCEPTION(env);
+ RETURN_IF_OK(cmp_aseq(&as, aso) && cmp_aseq(&as, asr));
+ if (!cmp_aseq(&as, aso)) {
+ fprintf(stdout, " out parameter error, sent:\n");
+ print_aseq(&as);
+ fprintf(stdout, " got:\n");
+ print_aseq(aso);
+ fprintf(stdout, "\n");
+ }
+ if (!cmp_aseq(&as, asr)) {
+ fprintf(stdout, " result error, sent:\n");
+ print_aseq(&as);
+ fprintf(stdout, " got:\n");
+ print_aseq(asr);
+ fprintf(stdout, "\n");
+ }
+ CORBA_free(aso);
+ CORBA_free(asr);
+ return -1;
+}
+
+static int seq3_test(IC_Env *env)
+{
+ m_lseq lsi, *lso, *lsr;
+ long al[500];
+ int i=0;
+
+ for (i = 0; i < 500; i++)
+ al[i]=i;
+ lsi._length = 500;
+ lsi._buffer = al;
+
+ fprintf(stdout, "\n======== m_i_seq3 test ======\n\n");
+ lsr = m_i_seq3_test(NULL, &lsi, &lso, env);
+ CHECK_EXCEPTION(env);
+ RETURN_IF_OK(cmp_lseq(&lsi, lso) && cmp_lseq(&lsi, lsr));
+ if (!cmp_lseq(&lsi, lso)) {
+ fprintf(stdout, " out parameter error, sent:\n");
+ print_lseq(&lsi);
+ fprintf(stdout, " got:\n");
+ print_lseq(lso);
+ fprintf(stdout, "\n");
+ }
+ if (!cmp_lseq(&lsi, lsr)) {
+ fprintf(stdout, " result error, sent:\n");
+ print_lseq(&lsi);
+ fprintf(stdout, " got:\n");
+ print_lseq(lsr);
+ fprintf(stdout, "\n");
+ }
+ CORBA_free(lso);
+ CORBA_free(lsr);
+ return -1;
+}
+
+static int seq4_test(IC_Env *env)
+{
+ char *stra0[3] = {"a", "long", "time"};
+ char *stra1[3] = {"ago", "there", "was"};
+ char *stra2[3] = {"a", "buggy", "compiler"};
+ m_sstr3 str3s[3] = {{3, 3, stra0}, {3, 3, stra1}, {3, 3, stra2}};
+ m_ssstr3 str3ssi = {3, 3, str3s};
+ m_ssstr3 *str3sso, *str3ssr;
+
+ fprintf(stdout, "\n======== m_i_seq4 test ======\n\n");
+ str3ssr = m_i_seq4_test(NULL, &str3ssi, &str3sso, env);
+ CHECK_EXCEPTION(env);
+ RETURN_IF_OK(cmp_ssstr3(&str3ssi, str3sso) &&
+ cmp_ssstr3(&str3ssi, str3ssr));
+ if (!cmp_ssstr3(&str3ssi, str3sso)){
+ fprintf(stdout, " out parameter error, sent:\n");
+ print_ssstr3(&str3ssi);
+ fprintf(stdout, " got:\n");
+ print_ssstr3(str3sso);
+ fprintf(stdout, "\n");
+ }
+ if (!cmp_ssstr3(&str3ssi, str3ssr)) {
+ fprintf(stdout, " result error, sent:\n");
+ print_ssstr3(&str3ssi);
+ fprintf(stdout, " got:\n");
+ print_ssstr3(str3ssr);
+ fprintf(stdout, "\n");
+ }
+ CORBA_free(str3sso);
+ CORBA_free(str3ssr);
+ return -1;
+}
+
+static int seq5_test(IC_Env *env)
+{
+ m_arr3 arr3a[3] = {
+ {4711, 18931947, 3},
+ {4711, 18931947, 3},
+ {4711, 18931947, 3}};
+ m_sarr3 arr3sa[3] = {{3, 3, arr3a}, {3, 3, arr3a}, {3, 3, arr3a}};
+ m_ssarr3 arr3ssi = {3, 3, arr3sa};
+ m_ssarr3 *arr3sso;
+ m_ssarr3 *arr3ssr;
+
+ fprintf(stdout, "\n======== m_i_seq5 test ======\n\n");
+ arr3ssr = m_i_seq5_test(NULL, &arr3ssi, &arr3sso, env);
+ CHECK_EXCEPTION(env);
+ RETURN_IF_OK(cmp_ssarr3(&arr3ssi, arr3sso) &&
+ cmp_ssarr3(&arr3ssi, arr3ssr));
+ if (!cmp_ssarr3(&arr3ssi, arr3sso)) {
+ fprintf(stdout, " out parameter error, sent:\n");
+ print_ssarr3(&arr3ssi);
+ fprintf(stdout, " got:\n");
+ print_ssarr3(arr3sso);
+ fprintf(stdout, "\n");
+ }
+ if (!cmp_ssarr3(&arr3ssi, arr3ssr)) {
+ fprintf(stdout, " result error, sent:\n");
+ print_ssarr3(&arr3ssi);
+ fprintf(stdout, " got:\n");
+ print_ssarr3(arr3ssr);
+ fprintf(stdout, "\n");
+ }
+ CORBA_free(arr3sso);
+ CORBA_free(arr3ssr);
+ return -1;
+}
+
+static int array1_test(IC_Env *env)
+{
+ int i;
+ long al[500];
+ m_arr1 alo;
+ m_arr1_slice* alr;
+
+ for (i = 0; i < 500; i++)
+ al[i]=i;
+
+ fprintf(stdout, "\n======== m_i_array1 test ======\n\n");
+ alr = m_i_array1_test(NULL, al, alo, env);
+ CHECK_EXCEPTION(env);
+ RETURN_IF_OK(cmp_arr1(al, alo) && cmp_arr1(al, alr));
+ if (!cmp_arr1(al, alo)) {
+ fprintf(stdout, " out parameter error, sent:\n");
+ print_arr1(al);
+ fprintf(stdout, " got:\n");
+ print_arr1(alo);
+ fprintf(stdout, "\n");
+ }
+ if (!cmp_arr1(al,alr)) {
+ fprintf(stdout, " result error, sent:\n");
+ print_arr1(al);
+ fprintf(stdout, " got:\n");
+ print_arr1(alr);
+ fprintf(stdout, "\n");
+ }
+ free(alo);
+ free(alr);
+ return -1;
+}
+
+static int array2_test(IC_Env *env)
+{
+ long dl[2][3] = {{11, 2, 7}, {22, 8 ,13}};
+ m_dd dlo;
+ m_dd_slice* dlr;
+
+ fprintf(stdout, "\n======== m_i_array2 test ======\n\n");
+ dlr = m_i_array2_test(NULL, dl, dlo, env);
+ CHECK_EXCEPTION(env);
+ RETURN_IF_OK(cmp_dd(dl,dlo) && cmp_dd(dl,dlr));
+ if (!cmp_dd(dl,dlo)) {
+ fprintf(stdout, " out parameter error, sent:\n");
+ print_dd(dl);
+ fprintf(stdout, " got:\n");
+ print_dd(dlo);
+ fprintf(stdout, "\n");
+ }
+ if (!cmp_dd(dl,dlr)) {
+ fprintf(stdout, " result error, sent:\n");
+ print_dd(dl);
+ fprintf(stdout, " got:\n");
+ print_dd(dlr);
+ fprintf(stdout, "\n");
+ }
+ free(*dlr);
+ return -1;
+}
+
+static int enum_test(IC_Env *env)
+{
+ m_fruit ei = m_banana, eo, er;
+
+ fprintf(stdout, "\n======== m_i_enum test ======\n\n");
+ er = m_i_enum_test(NULL, ei, &eo, env);
+ CHECK_EXCEPTION(env);
+ RETURN_IF_OK(ei == eo && ei == er);
+ if (ei != eo)
+ fprintf(stdout, " out parameter error, sent: %d, got: %d\n", ei, eo);
+ if (ei != er)
+ fprintf(stdout, " result error, sent: %d, got: %d\n", ei, er);
+ return -1;
+}
+
+static int string1_test(IC_Env *env)
+{
+ char* si = longtext;
+ char* so;
+ char* sr;
+
+ fprintf(stdout, "\n======== m_i_string1 test ======\n\n");
+ sr = m_i_string1_test(NULL, si, &so, env);
+ CHECK_EXCEPTION(env);
+ RETURN_IF_OK(cmp_str(si, so) && cmp_str(si, sr));
+ if (!cmp_str(si, so))
+ fprintf(stdout, " out parameter error, sent: %s, got: %s\n", si, so);
+ if (!cmp_str(si, sr))
+ fprintf(stdout, " result error, sent: %s, got: %s\n", si, sr);
+ CORBA_free(so);
+ CORBA_free(sr);
+ return -1;
+}
+
+static int string2_test(IC_Env *env)
+{
+ char* sa[3] = {"hello", "foo", "bar"};
+ m_sseq ssi = {3, 3, sa};
+ m_sseq *sso, *ssr;
+
+ fprintf(stdout, "\n======== m_i_string2 test ======\n\n");
+ ssr = m_i_string2_test(NULL, &ssi, &sso, env);
+ CHECK_EXCEPTION(env);
+ RETURN_IF_OK(cmp_sseq(&ssi, sso) && cmp_sseq(&ssi, sso));
+ if (!cmp_sseq(&ssi, sso)) {
+ fprintf(stdout, " out parameter error, sent:\n");
+ print_sseq(&ssi);
+ fprintf(stdout, "got:\n");
+ print_sseq(sso);
+ }
+ if (!cmp_sseq(&ssi, ssr)) {
+ fprintf(stdout, " result error, sent:\n");
+ print_sseq(&ssi);
+ fprintf(stdout, "got:\n");
+ print_sseq(ssr);
+ }
+ CORBA_free(sso);
+ CORBA_free(ssr);
+ return -1;
+}
+
+static int string3_test(IC_Env *env)
+{
+ char* si = longtext;
+ char* so;
+ char* sr;
+
+ fprintf(stdout, "\n======== m_i_string3 test ======\n\n");
+ sr = m_i_string3_test(NULL, si, &so, env);
+ CHECK_EXCEPTION(env);
+ RETURN_IF_OK(cmp_str(si, so) && cmp_str(si, so));
+ if (!cmp_str(si, so))
+ fprintf(stdout, " out parameter error, sent: %s, got: %s\n", si, so);
+ if (!cmp_str(si, sr))
+ fprintf(stdout, " result error, sent: %s, got: %s\n", si, sr);
+ CORBA_free(so);
+ CORBA_free(sr);
+ return -1;
+}
+
+static int string4_test(IC_Env *env)
+{
+ char as1[100] = "a string", as2[200] = "help", as3[200] = "hello there";
+ m_strRec stri = { 1, /* dd */
+ as1, /* str4 */
+ {{'a', 'k'}, {'z', 'g'}, {'n', 'q'}}, /* str7 */
+ {3, 3, "buf"}, /* str5 */
+ as2, /* str6 */
+ {'m', 'f', 'o'}, /* str8 */
+ as3, /* str9 */
+ {3, 3, "stu"} /* str10 */
+ };
+ m_strRec *stro, *strr;
+
+ fprintf(stdout, "\n======== m_i_string4 test ======\n\n");
+ strr = m_i_string4_test(NULL, &stri, &stro, env);
+ CHECK_EXCEPTION(env);
+ RETURN_IF_OK(cmp_strRec(&stri,stro) && cmp_strRec(&stri,strr));
+ if (!cmp_strRec(&stri,stro)) {
+ fprintf(stdout, " out parameter error, sent:\n");
+ print_strRec(&stri);
+ fprintf(stdout, " got:\n");
+ print_strRec(stro);
+ fprintf(stdout, "\n");
+ }
+ if (!cmp_strRec(&stri,strr)) {
+ fprintf(stdout, " result error, sent:\n");
+ print_strRec(&stri);
+ fprintf(stdout, " got:\n");
+ print_strRec(strr);
+ fprintf(stdout, "\n");
+ }
+ CORBA_free(stro);
+ CORBA_free(strr);
+ return -1;
+}
+
+
+static int pid_test(IC_Env *env)
+{
+ erlang_pid pid = {"", 7, 0, 0}, pido, pidr;
+
+ strcpy(pid.node, this_node), /* this currently running node */
+ fprintf(stdout, "\n======== m_i_pid test ======\n\n");
+ pidr = m_i_pid_test(NULL, &pid, &pido, env);
+ CHECK_EXCEPTION(env);
+ RETURN_IF_OK(cmp_pid(&pid, &pido) && cmp_pid(&pid, &pidr));
+ if (!cmp_pid(&pid, &pido)) {
+ fprintf(stdout, " out parameter error, sent:\n");
+ print_pid(&pid);
+ fprintf(stdout, "got:\n");
+ print_pid(&pido);
+ }
+ if (!cmp_pid(&pid, &pidr)) {
+ fprintf(stdout, " result error, sent:\n");
+ print_pid(&pid);
+ fprintf(stdout, "got:\n");
+ print_pid(&pidr);
+ }
+ return -1;
+}
+
+static int port_test(IC_Env *env)
+{
+ erlang_port porti = {"node", 5, 1}, porto, portr;
+
+ fprintf(stdout, "\n======== m_i_port test ======\n\n");
+ portr = m_i_port_test(NULL, &porti, &porto, env);
+ CHECK_EXCEPTION(env);
+ RETURN_IF_OK(cmp_port(&porti, &porto) && cmp_port(&porti, &portr));
+ if (!cmp_port(&porti, &porto)) {
+ fprintf(stdout, " out parameter error, sent:\n");
+ print_port(&porti);
+ fprintf(stdout, "got:\n");
+ print_port(&porto);
+ }
+ if (!cmp_port(&porti, &portr)) {
+ fprintf(stdout, " result error, sent:\n");
+ print_port(&porti);
+ fprintf(stdout, "got:\n");
+ print_port(&portr);
+ }
+ return -1;
+}
+
+static int ref_test(IC_Env *env)
+{
+ erlang_ref refi = { "node1", 3, {1, 2, 3}, 1},
+ refo, refr;
+
+ fprintf(stdout, "\n======== m_i_ref test ======\n\n");
+ refr = m_i_ref_test(NULL, &refi, &refo, env);
+ CHECK_EXCEPTION(env);
+ RETURN_IF_OK(cmp_ref(&refi, &refo) && cmp_ref(&refi, &refr));
+ if (!cmp_ref(&refi, &refo)) {
+ fprintf(stdout, " out parameter error, sent:\n");
+ print_ref(&refi);
+ fprintf(stdout, "got:\n");
+ print_ref(&refo);
+ }
+ if (!cmp_ref(&refi, &refr)) {
+ fprintf(stdout, " result error, sent:\n");
+ print_ref(&refi);
+ fprintf(stdout, "got:\n");
+ print_ref(&refr);
+ }
+ return -1;
+}
+
+static int term_test(IC_Env *env)
+{
+ ETERM *ti, *to, *tr;
+
+ ti = erl_format("[{hej, 1, 23}, \"string\", {1.23, 45}]");
+
+ fprintf(stdout, "\n======== m_i_term test ======\n\n");
+ tr = m_i_term_test(NULL, ti, &to, env);
+ CHECK_EXCEPTION(env);
+ RETURN_IF_OK(erl_match(ti, to) && erl_match(ti, tr));
+ if (!erl_match(ti, to)) {
+ fprintf(stdout, " out parameter error, sent:\n");
+ print_term(ti);
+ fprintf(stdout, "got:\n");
+ print_term(to);
+ }
+ if (!erl_match(ti, tr)) {
+ fprintf(stdout, " result error, sent:\n");
+ print_term(ti);
+ fprintf(stdout, "got:\n");
+ print_term(tr);
+ }
+ erl_free_term(ti);
+ erl_free_term(to);
+ erl_free_term(tr);
+ return -1;
+}
+
+static int typedef_test(IC_Env *env)
+{
+ m_banan mbi, mbo; /* erlang_port */
+ m_apa mai; /* ETERM* */
+ m_apa mao = NULL;
+ long tl;
+
+ strcpy(mbi.node,"node");
+ mbi.id = 15;
+ mbi.creation = 1;
+
+ fprintf(stdout, "\n======== m_i_typedef test ======\n\n");
+ mai = erl_format("[{hej, 1, 23}, \"string\", {1.23, 45}]");
+ tl = m_i_typedef_test(NULL, mai, &mbi, &mao, &mbo, env);
+ CHECK_EXCEPTION(env);
+ RETURN_IF_OK(erl_match(mai, mao) && cmp_port(&mbi, &mbo) && tl == 4711);
+ if (!erl_match(mai, mao)) {
+ fprintf(stdout, " out parameter error (term), sent:\n");
+ print_term(mai);
+ fprintf(stdout, "got:\n");
+ print_term(mao);
+ }
+ if (!cmp_port(&mbi, &mbo)) {
+ fprintf(stdout, " out parameter error (port), sent:\n");
+ print_port(&mbi);
+ fprintf(stdout, "got:\n");
+ print_port(&mbo);
+ }
+ if (tl != 4711) {
+ fprintf(stdout, " result error, sent: 4711, got %ld\n", tl);
+ }
+ erl_free_term(mai);
+ erl_free_term(mao);
+ return -1;
+}
+
+static int inline_sequence_test(IC_Env *env)
+{
+ int i;
+ long al[500];
+ m_s isi = {4711, {500, 10, al}},
+ *iso, *isr;
+
+ for (i = 0; i < 500; i++)
+ al[i]=i;
+ fprintf(stdout, "\n======== m_i_inline_sequence test ======\n\n");
+ isr = m_i_inline_sequence_test(NULL, &isi, &iso, env);
+ CHECK_EXCEPTION(env);
+ RETURN_IF_OK(cmp_s(&isi, iso) && cmp_s(&isi, isr));
+ if (!cmp_s(&isi, iso)) {
+ fprintf(stdout, " out parameter error, sent:\n");
+ print_s(&isi);
+ fprintf(stdout, "got:\n");
+ print_s(iso);
+ }
+ if (!cmp_s(&isi, isr)) {
+ fprintf(stdout, " result error, sent:\n");
+ print_s(&isi);
+ fprintf(stdout, "got:\n");
+ print_s(isr);
+ }
+ CORBA_free(iso);
+ CORBA_free(isr);
+ return -1;
+}
+
+static int term_sequence_test(IC_Env *env)
+{
+ ETERM* et_array[4] = {
+ erl_format("[{apa, 1, 23}, \"string\", {1.23, 45}]"),
+ erl_format("[{banan, 1, 23}, \"string\", {1.23, 45}]"),
+ erl_format("[{apelsin, 1, 23}, \"string\", {1.23, 45}]"),
+ erl_format("[{mango, 1, 23}, \"string\", {1.23, 45}]")};
+ m_etseq etsi = {4, 4, et_array}, *etso, *etsr;
+
+ fprintf(stdout, "\n======== m_i_term_sequence test ======\n\n");
+ etsr = m_i_term_sequence_test(NULL, &etsi, &etso, env);
+ CHECK_EXCEPTION(env);
+ RETURN_IF_OK(cmp_etseq(&etsi, etso) && cmp_etseq(&etsi, etsr));
+ if (!cmp_etseq(&etsi, etso)) {
+ fprintf(stdout, " out parameter error, sent:\n");
+ print_etseq(&etsi);
+ fprintf(stdout, "got:\n");
+ print_etseq(etso);
+ }
+ if (!cmp_etseq(&etsi, etsr)) {
+ fprintf(stdout, " result error, sent:\n");
+ print_etseq(&etsi);
+ fprintf(stdout, "got:\n");
+ print_etseq(etsr);
+ }
+ free_etseq_buf(&etsi);
+ free_etseq_buf(etso);
+ free_etseq_buf(etsr);
+ CORBA_free(etso);
+ CORBA_free(etsr);
+ return -1;
+}
+
+static int term_struct_test(IC_Env *env)
+{
+ m_et eti = { erl_format("[{hej, 1, 23}, \"string\", {1.23, 45}]"),
+ 121212 };
+ m_et eto, etr;
+
+ fprintf(stdout, "\n======== m_i_term_struct test ======\n\n");
+ etr = m_i_term_struct_test(NULL, &eti, &eto, env);
+ CHECK_EXCEPTION(env);
+ RETURN_IF_OK(cmp_et(&eti, &eto) && cmp_et(&eti, &etr));
+ if (!cmp_et(&eti, &eto)) {
+ fprintf(stdout, " out parameter error, sent:\n");
+ print_et(&eti);
+ fprintf(stdout, "got:\n");
+ print_et(&eto);
+ }
+ if (!cmp_et(&eti, &etr)) {
+ fprintf(stdout, " result error, sent:\n");
+ print_et(&eti);
+ fprintf(stdout, "got:\n");
+ print_et(&etr);
+ }
+ free_et(&eti);
+ free_et(&eto);
+ free_et(&etr);
+ return -1;
+}
+
+static int wstring1_test(IC_Env *env)
+{
+ CORBA_wchar wsi[] = {100, 101, 102, 103, 104, 0}, *wso, *wsr;
+
+ fprintf(stdout, "\n======== m_i_wstring1 test ======\n\n");
+ wsr = m_i_wstring1_test(NULL, wsi, &wso, env);
+ CHECK_EXCEPTION(env);
+ RETURN_IF_OK(cmp_wstr(wsi, wso) && cmp_wstr(wsi, wsr));
+ if (!cmp_wstr(wsi, wso)) {
+ fprintf(stdout, " out parameter error, sent: \n");
+ print_wstr(wsi);
+ fprintf(stdout, "got:\n");
+ print_wstr(wso);
+ }
+ if (!cmp_wstr(wsi, wsr)) {
+ fprintf(stdout, " result error, sent: \n");
+ print_wstr(wsi);
+ fprintf(stdout, "got:\n");
+ print_wstr(wsr);
+ }
+ CORBA_free(wso);
+ CORBA_free(wsr);
+ return -1;
+}
+
+/* Compare functions */
+static int cmp_aseq(m_aseq *a1, m_aseq *a2)
+{
+ int i;
+
+ if (a1->_length != a2->_length)
+ return 0;
+ for (i = 0; i < a1->_length; i++)
+ if (cmp_a(&(a1->_buffer[i]), &(a2->_buffer[i])) == 0)
+ return 0;
+ return 1;
+}
+
+static int cmp_a(m_a *a1, m_a *a2)
+{
+ return a1->l == a2->l &&
+ a1->d == a2->d &&
+ cmp_bseq(&a1->y, &a2->y);
+}
+
+static int cmp_bseq(m_bseq *b1, m_bseq *b2)
+{
+ int i;
+
+ if (b1->_length != b2->_length)
+ return 0;
+ for (i = 0; i < b1->_length; i++)
+ if (cmp_b(&(b1->_buffer[i]), &(b2->_buffer[i])) == 0)
+ return 0;
+ return 1;
+}
+
+static int cmp_b(m_b *b1, m_b *b2)
+{
+ return b1->l == b2->l && b1->c == b2->c;
+}
+
+static int cmp_lseq(m_lseq *b1, m_lseq *b2)
+{
+ int i;
+
+ if (b1->_length != b2->_length)
+ return 0;
+ for (i = 0; i < b1->_length; i++)
+ if (b1->_buffer[i] != b2->_buffer[i])
+ return 0;
+ return 1;
+}
+
+static int cmp_etseq(m_etseq *b1, m_etseq *b2)
+{
+ int i;
+
+ if (b1->_length != b2->_length)
+ return 0;
+ for (i = 0; i < b1->_length; i++)
+ if (!erl_match(b1->_buffer[i], b2->_buffer[i]))
+ return 0;
+ return 1;
+}
+
+static int cmp_et(m_et* b1, m_et *b2)
+{
+ return erl_match(b1->e, b2->e) && b1->l == b2->l;
+}
+
+static int cmp_es(m_es *b1, m_es *b2)
+{
+ return b1->f == b2->f && b1->l == b2->l;
+}
+
+static int cmp_arr1(m_arr1 b1, m_arr1 b2)
+{
+ int i;
+
+ for (i = 0; i < 500; i++)
+ if (b1[i] != b2[i])
+ return 0;
+ return 1;
+}
+
+static int cmp_dd(m_dd b1, m_dd b2)
+{
+
+ int i, j;
+
+ for (i = 0; i < 2; i++)
+ for (j = 0; j < 3; j++)
+ if (b1[i][j] != b2[i][j])
+ return 0;
+ return 1;
+}
+
+
+
+static int cmp_strRec(m_strRec *b1, m_strRec *b2)
+{
+ int i, j;
+
+ if (b1->bb != b2->bb)
+ return 0;
+ if (!cmp_str(b1->str4,b2->str4))
+ return 0;
+ if (b1->str5._length != b2->str5._length)
+ return 0;
+ for (j = 0; j < b1->str5._length; j++)
+ if (b1->str5._buffer[j] != b2->str5._buffer[j])
+ return 0;
+ if (!cmp_str(b1->str6,b2->str6))
+ return 0;
+ for (i = 0; i < 2; i++)
+ for (j = 0; j < 3; j++)
+ if (b1->str7[i][j] != b2->str7[i][j])
+ return 0;
+ for (j = 0; j < 3; j++)
+ if (b1->str8[j] != b2->str8[j])
+ return 0;
+ if (!cmp_str(b1->str9,b2->str9))
+ return 0;
+ if (b1->str10._length != b2->str10._length)
+ return 0;
+ for (j = 0; j < b1->str10._length; j++)
+ if (b1->str10._buffer[j] != b2->str10._buffer[j])
+ return 0;
+ return 1;
+}
+
+
+static int cmp_sseq(m_sseq *b1, m_sseq *b2)
+{
+ int i;
+
+ if (b1->_length != b2->_length)
+ return 0;
+ for (i = 0; i < b1->_length; i++)
+ if (!cmp_str(b1->_buffer[i], b2->_buffer[i]))
+ return 0;
+ return 1;
+}
+
+
+static int cmp_pid(erlang_pid *p1, erlang_pid *p2)
+{
+ return cmp_str(p1->node,p2-> node) &&
+ p1->num == p2->num &&
+ p1->serial == p2->serial &&
+ p1->creation == p2->creation;
+}
+
+static int cmp_port(erlang_port *p1, erlang_port *p2)
+{
+ return cmp_str(p1->node,p2-> node) && p1->id == p2->id;
+}
+
+static int cmp_ref(erlang_ref *p1, erlang_ref *p2)
+{
+ return cmp_str(p1->node, p2->node) &&
+ p1->len == p2->len &&
+ (p1->len < 1 || p1->n[0] == p2->n[0]) &&
+ (p1->len < 2 || p1->n[1] == p2->n[1]) &&
+ (p1->len < 3 || p1->n[2] == p2->n[2]);
+}
+
+static int cmp_s(m_s *b1, m_s *b2)
+{
+ int i;
+
+ if (b1->l != b2->l)
+ return 0;
+ if (b1->sl._length != b2->sl._length)
+ return 0;
+ for (i = 0; i < b1->sl._length; i++)
+ if (b1->sl._buffer[i] != b2->sl._buffer[i])
+ return 0;
+ return 1;
+}
+
+
+static int cmp_ssstr3(m_ssstr3 *b1, m_ssstr3 *b2)
+{
+ int i,j;
+
+ if (b1->_length != b2->_length)
+ return 0;
+ for (i = 0; i < b1->_length; i++) {
+ if (b1->_buffer[i]._length != b2->_buffer[i]._length)
+ return 0;
+ for (j = 0; j < b1->_buffer[i]._length; j++)
+ if (!cmp_str(b1->_buffer[i]._buffer[j],
+ b2->_buffer[i]._buffer[j]))
+ return 0;
+ }
+ return 1;
+}
+
+
+
+static int cmp_ssarr3(m_ssarr3 *b1, m_ssarr3 *b2)
+{
+ int i;
+
+ if (b1->_length != b2->_length)
+ return 0;
+ for (i = 0; i < b1->_length; i++) {
+ if (!cmp_sarr3(&b1->_buffer[i], &b2->_buffer[i]))
+ return 0;
+ }
+ return 1;
+}
+
+static int cmp_sarr3(m_sarr3 *b1, m_sarr3 *b2)
+{
+ int i;
+
+ if (b1->_length != b2->_length)
+ return 0;
+ for (i = 0; i < b1->_length; i++) {
+ if (!cmp_arr3(b1->_buffer[i], b2->_buffer[i]))
+ return 0;
+ }
+ return 1;
+}
+
+static int cmp_arr3(m_arr3 b1, m_arr3 b2)
+{
+ int i;
+
+ for (i = 0; i < sizeof(m_arr3)/sizeof(CORBA_long); i++) {
+ if (b1[i] != b2[i])
+ return 0;
+ }
+ return 1;
+}
+
+/* Print functions */
+static void print_aseq(m_aseq *a)
+{
+ int i;
+ fprintf(stdout, "\nm_aseq size: %ld --------\n", a->_length);
+ for (i = 0; i < a->_length; i++)
+ print_a(&(a->_buffer[i]));
+}
+
+static void print_a(m_a *a)
+{
+ fprintf(stdout, "\nm_a --------\n l: %ld\n d:%f\n", a->l, a->d);
+ print_bseq(&a->y);
+}
+
+static void print_bseq(m_bseq *b)
+{
+ int i;
+
+ fprintf(stdout, "\nm_bseq size: %ld --------\n",b->_length);
+ for (i = 0; i < b->_length; i++)
+ print_b(&(b->_buffer[i]));
+}
+
+static void print_lseq(m_lseq *b)
+{
+ int i;
+
+ fprintf(stdout, "\nm_lseq size: %ld --------\n",b->_length);
+ for (i = 0; i < b->_length; i++)
+ fprintf(stdout, "[%d]: %ld\n", i, b->_buffer[i]);
+}
+
+static void print_b(m_b *b)
+{
+ fprintf(stdout, "\nm_b --------\n l: %ld\n c: %c\n", b->l, b->c);
+}
+
+
+static void print_etseq(m_etseq *b)
+{
+ int i;
+
+ for (i = 0; i < b->_length; i++) {
+ fprintf(stdout, "[%d]:\n", i);
+ erl_print_term(stdout, b->_buffer[i]);
+ }
+}
+
+
+static void print_et(m_et* b)
+{
+ fprintf(stdout, "\net struct --------\n");
+ erl_print_term(stdout, b->e);
+ fprintf(stdout, "long: %ld\n", b->l);
+ fprintf(stdout, "\n--------\n");
+}
+
+static void print_es(m_es *b)
+{
+ fprintf(stdout, "\nm_es --------\n f: %d\n l: %ld\n", b->f, b->l);
+}
+
+
+static void print_arr1(long a[10])
+{
+ int i;
+
+ for (i = 0; i < 10; i++)
+ fprintf(stdout, "\n[%d]: %ld\n", i, a[i]);
+}
+
+static void print_dd(long a[2][3])
+{
+ int i, j;
+
+ fprintf(stdout, "\nlong dd[2][3] --------\n");
+ for (i = 0; i < 2; i++)
+ for (j = 0; j < 3; j++)
+ fprintf(stdout, "\n[%d][%d]: %ld\n", i, j, a[i][j]);
+}
+
+
+static void print_strRec(m_strRec* sr)
+{
+ int i, j;
+
+ fprintf(stdout, "\nboolean bb : %d\n",sr->bb);
+ fprintf(stdout, "string str4 : %s\n",sr->str4);
+ fprintf(stdout, "str7[2][3] :\n");
+ for (i = 0; i < 2; i++)
+ for (j = 0; j < 3; j++)
+ fprintf(stdout, "str7[%d][%d]: %ld\n", i, j, sr->str7[i][j]);
+ fprintf(stdout, "str5._length : %ld\n",sr->str5._length);
+ for (j = 0; j < sr->str5._length; j++)
+ fprintf(stdout, "str5._buffer[%d]: %c\n", j, sr->str5._buffer[j]);
+ fprintf(stdout, "string str6 : %s\n",sr->str6);
+ fprintf(stdout, "str8 :\n");
+ for (j = 0; j < 3; j++)
+ fprintf(stdout, "str8[%d]: %c\n", j, sr->str8[j]);
+ fprintf(stdout, "string str9 : %s\n",sr->str9);
+ fprintf(stdout, "str10._length : %ld\n",sr->str10._length);
+ for (j = 0; j < sr->str10._length; j++)
+ fprintf(stdout, "str10._buffer[%d]: %c\n", j, sr->str10._buffer[j]);
+}
+
+static void print_sseq(m_sseq *b)
+{
+ int i;
+
+ fprintf(stdout, "\nm_sseq size: %ld --------\n",b->_length);
+ for (i = 0; i < b->_length; i++)
+ fprintf(stdout, "%s\n", b->_buffer[i]);
+
+}
+
+
+static void print_pid(erlang_pid *p)
+{
+ fprintf(stdout, "\nerlang_pid --------\n node: %s\n num: %d\n "
+ "serial: %d\n creation: %d\n",
+ p->node, p->num, p->serial, p->creation);
+}
+
+static void print_port(erlang_port *p)
+{
+ fprintf(stdout, "\nerlang_port --------\n node: %s\n id: %d\n "
+ "creation: %d\n", p->node, p->id, p->creation);
+}
+
+static void print_ref(erlang_ref *p)
+{
+ fprintf(stdout, "\nerlang_ref --------\n node: %s\n len: %d\n "
+ "n[0]: %d\n n[1]: %d\n n[2]: %d\n creation: %d\n",
+ p->node, p->len, p->n[0], p->n[1], p->n[2], p->creation);
+}
+
+static void print_term(ETERM *t)
+{
+ fprintf(stdout, "\nETERM --------\n");
+ erl_print_term(stdout, t);
+ fprintf(stdout, "\n--------\n");
+}
+
+static void print_s(m_s *p)
+{
+ int i;
+
+ fprintf(stdout, "\n%ld\n", p->l);
+ for (i = 0; i < p->sl._length; i++)
+ fprintf(stdout, "\n[%d]: %ld\n", i, p->sl._buffer[i]);
+}
+
+
+static void print_ssstr3(m_ssstr3 *b1)
+{
+ int i,j;
+
+ fprintf(stdout, "\nSSSTR3 --------\n");
+ fprintf(stdout,"b1->_length = %ld\n",b1->_length);
+ for (i = 0; i < b1->_length; i++) {
+ fprintf(stdout,"\nb1->_buffer[%d]._length %ld\n",
+ i, b1->_buffer[i]._length);
+ for (j = 0; j < b1->_buffer[i]._length; j++)
+ fprintf(stdout,"b1->_buffer[%d]._buffer[%d] = %s\n",
+ i, j, b1->_buffer[i]._buffer[j]);
+ }
+ fprintf(stdout, "\n--------\n");
+}
+
+static void print_wstr(CORBA_wchar *ws)
+{
+ int i = 0;
+
+ fprintf(stdout, "\nwstr --------\n");
+ while (ws[i]) {
+ fprintf(stdout, "[%d]: %ld\n", i, ws[i]);
+ i++;
+ }
+ fprintf(stdout, "\n--------\n");
+}
+
+
+static void print_ssarr3(m_ssarr3 *b1)
+{
+ int i;
+
+ fprintf(stdout, "\nssarr3 --------\n");
+ fprintf(stdout,"length: %ld\n",b1->_length);
+ fprintf(stdout, "buffer:\n");
+ for (i = 0; i < b1->_length; i++)
+ print_sarr3(&b1->_buffer[i]);
+ fprintf(stdout, "\n--------\n");
+}
+
+static void print_sarr3(m_sarr3 *b1)
+{
+ int i;
+
+ fprintf(stdout, "\nsarr3 --------\n");
+ fprintf(stdout,"length: %ld\n",b1->_length);
+ fprintf(stdout, "buffer:\n");
+ for (i = 0; i < b1->_length; i++)
+ print_arr3(b1->_buffer[i]);
+ fprintf(stdout, "\n--------\n");
+}
+
+static void print_arr3(m_arr3 b1)
+{
+ int i;
+
+ fprintf(stdout, "\narr3 --------\n");
+ for (i = 0; i < sizeof(m_arr3)/sizeof(CORBA_long); i++)
+ fprintf(stdout, "%ld ", b1[i]);
+ fprintf(stdout, "\n--------\n");
+}
+
+static void free_etseq_buf(m_etseq *b)
+{
+ int i;
+
+ for (i = 0; i < b->_length; i++)
+ erl_free_term(b->_buffer[i]);
+}
+
+static void free_et(m_et* b)
+{
+ erl_free_term(b->e);
+}
+
+static void showtime(MyTimeval *start, MyTimeval *stop)
+{
+ MyTimeval elapsed;
+
+ elapsed.tv_sec = stop->tv_sec - start->tv_sec;
+ elapsed.tv_usec = stop->tv_usec - start->tv_usec;
+ while (elapsed.tv_usec < 0) {
+ elapsed.tv_sec -= 1;
+ elapsed.tv_usec += 1000000;
+ }
+ fprintf(stderr,"%ld.%06ld seconds\n",elapsed.tv_sec, elapsed.tv_usec);
+}
+
+static void my_gettimeofday(MyTimeval *tv)
+#ifdef __WIN32__
+#define EPOCH_JULIAN_DIFF 11644473600i64
+{
+ SYSTEMTIME t;
+ FILETIME ft;
+ LONGLONG lft;
+
+ GetSystemTime(&t);
+ SystemTimeToFileTime(&t, &ft);
+ memcpy(&lft, &ft, sizeof(lft));
+ tv->tv_usec = (long) ((lft / 10i64) % 1000000i64);
+ tv->tv_sec = (long) ((lft / 10000000i64) - EPOCH_JULIAN_DIFF);
+}
+#elif defined VXWORKS
+{
+ int rate = sysClkRateGet(); /* Ticks per second */
+ unsigned long ctick = tickGet();
+ tv->tv_sec = ctick / rate; /* secs since reboot */
+ tv->tv_usec = ((ctick - (tv->tv_sec * rate))*1000000)/rate;
+}
+#else
+{
+ gettimeofday(tv, NULL);
+}
+#endif
diff --git a/lib/ic/test/c_client_erl_server_proto_tmo_SUITE_data/c_erl_test.idl b/lib/ic/test/c_client_erl_server_proto_tmo_SUITE_data/c_erl_test.idl
new file mode 100644
index 0000000000..e687cec114
--- /dev/null
+++ b/lib/ic/test/c_client_erl_server_proto_tmo_SUITE_data/c_erl_test.idl
@@ -0,0 +1,173 @@
+
+// %CopyrightBegin%
+//
+// Copyright Ericsson AB 2004-2010. All Rights Reserved.
+//
+// The contents of this file are subject to the Erlang Public License,
+// Version 1.1, (the "License"); you may not use this file except in
+// compliance with the License. You should have received a copy of the
+// Erlang Public License along with this software. If not, it can be
+// retrieved online at http://www.erlang.org/.
+//
+// Software distributed under the License is distributed on an "AS IS"
+// basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+// the License for the specific language governing rights and limitations
+// under the License.
+//
+// %CopyrightEnd%
+
+#include "erlang.idl"
+
+
+const short TestConst = 1;
+
+module m {
+
+ const short TestConst = 2;
+
+ struct b {
+ long l;
+ char c;
+ };
+
+ struct simple {
+ long l;
+ b b_t;
+ };
+
+ enum fruit {orange, banana, apple, peach, pear};
+
+ typedef sequence<long> lseq;
+
+ typedef sequence<b> bseq;
+
+ struct a {
+ long l;
+ bseq y;
+ double d;
+ };
+
+ typedef sequence<a> aseq;
+
+ typedef sequence<string> sseq;
+ typedef string str;
+ typedef long myLong;
+
+ typedef long arr1[500], dd[2][3];
+
+ typedef erlang::term apa;
+ typedef erlang::port banan;
+
+ typedef sequence<erlang::term> etseq;
+
+ struct s {
+ long l;
+ sequence<long> sl;
+ };
+
+ struct es {
+ fruit f;
+ myLong l;
+ };
+
+ struct et {
+ erlang::term e;
+ long l;
+ };
+
+
+ typedef sequence<char> str1;
+ typedef string<12> str2;
+ typedef char str3[3];
+
+ typedef sequence<string> sstr3; // sequence of string
+ typedef sequence<sstr3> ssstr3; // sequence of sequences of strings
+
+ typedef long arr3[3]; // array of long
+ typedef sequence<arr3> sarr3; // sequence of array
+ typedef sequence<sarr3> ssarr3; // sequence of sequnces of arrays of strings
+
+ struct strRec{
+ boolean bb;
+ string str4;
+ long str7[3][2];
+ sequence<char> str5;
+ string<12> str6;
+ str3 str8;
+ str2 str9;
+ str1 str10;
+ };
+
+
+ struct dyn {
+ long l;
+ sequence<long> sl;
+ };
+ typedef dyn arr2[1][2];
+
+
+ interface i {
+
+ const short TestConst = 3;
+
+ //arr2 suck(in arr2 x, out arr2 y );
+
+ ///////////////////////////////// attribute long l;
+
+ // simple types
+ void void_test();
+ long long_test(in long a, out long a1);
+ long long longlong_test(in long long a, out long long a1);
+ unsigned short ushort_test(in unsigned short a, out unsigned short a1);
+ unsigned long ulong_test(in unsigned long a, out unsigned long a1);
+ unsigned long long ulonglong_test(in unsigned long long a, out unsigned long long a1);
+ double double_test(in double a, out double a1);
+ char char_test(in char a, out char a1);
+ wchar wchar_test(in wchar a, out wchar a1);
+ octet octet_test(in octet a, out octet a1);
+ boolean bool_test(in boolean a, out boolean a1);
+
+ // Seq. and struct tests
+ b struct_test(in b a, out b a1);
+ es struct2_test(in es a, out es a1);
+ //simple struct3_test(in simple x, out simple y);
+ bseq seq1_test(in bseq a, out bseq a1);
+ aseq seq2_test(in aseq a, out aseq a1);
+ lseq seq3_test(in lseq a, out lseq a1);
+ ssstr3 seq4_test(in ssstr3 a, out ssstr3 a1);
+ ssarr3 seq5_test(in ssarr3 a, out ssarr3 a1);
+
+ // Array tests
+ arr1 array1_test(in arr1 a, out arr1 a1);
+ dd array2_test(in dd a, out dd a1);
+
+ // enum test
+ fruit enum_test(in fruit a, out fruit a1);
+
+ // string tests
+ string string1_test(in string a, out string a1);
+ wstring wstring1_test(in wstring a, out wstring a1);
+ sseq string2_test(in sseq a, out sseq a1);
+ str string3_test(in str a, out str a1);
+ strRec string4_test(in strRec a, out strRec a1);
+
+ // Special erlang types
+ erlang::pid pid_test(in erlang::pid a, out erlang::pid a1);
+ erlang::port port_test(in erlang::port a, out erlang::port a1);
+ erlang::ref ref_test(in erlang::ref a, out erlang::ref a1);
+ erlang::term term_test(in erlang::term a, out erlang::term a1);
+
+ // typedef test
+ long typedef_test(in apa a, in banan b, out apa a1, out banan b1);
+
+ // inlined seq. test
+ s inline_sequence_test(in s a, out s a1);
+
+ // term seq. test
+ etseq term_sequence_test(in etseq a, out etseq a1);
+ // term struct test
+ et term_struct_test(in et a, out et a1);
+
+ };
+
+};
diff --git a/lib/ic/test/c_client_erl_server_proto_tmo_SUITE_data/erl_server.erl b/lib/ic/test/c_client_erl_server_proto_tmo_SUITE_data/erl_server.erl
new file mode 100644
index 0000000000..2e624ec5c0
--- /dev/null
+++ b/lib/ic/test/c_client_erl_server_proto_tmo_SUITE_data/erl_server.erl
@@ -0,0 +1,28 @@
+%%
+%% %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(erl_server).
+
+-export([run/0, stop/0]).
+
+run() ->
+ m_i:oe_create().
+
+stop() ->
+ gen_server:cast(cidl_test, stop).
diff --git a/lib/ic/test/c_client_erl_server_proto_tmo_SUITE_data/m_i_impl.erl b/lib/ic/test/c_client_erl_server_proto_tmo_SUITE_data/m_i_impl.erl
new file mode 100644
index 0000000000..0c96fb9edf
--- /dev/null
+++ b/lib/ic/test/c_client_erl_server_proto_tmo_SUITE_data/m_i_impl.erl
@@ -0,0 +1,161 @@
+%%
+%% %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(m_i_impl).
+-include("m.hrl").
+
+-export([init/1, terminate/2, void_test/1, long_test/2, ushort_test/2,
+ longlong_test/2, ulong_test/2, ulonglong_test/2,
+ double_test/2, char_test/2, wchar_test/2, octet_test/2,
+ bool_test/2, struct_test/2, struct2_test/2, seq1_test/2,
+ seq2_test/2, seq3_test/2, seq4_test/2, seq5_test/2,
+ array1_test/2, array2_test/2, enum_test/2, string1_test/2,
+ string2_test/2, string3_test/2, string4_test/2, pid_test/2,
+ port_test/2, ref_test/2, term_test/2, typedef_test/3,
+ inline_sequence_test/2, '_set_l'/2, '_get_l'/1,
+ term_struct_test/2, term_sequence_test/2, wstring1_test/2]).
+
+-define(PRINTDEBUG(Case),
+ io:format("erl_server: case: ~p~n"
+ "erl_server: location: ~p~n", [Case, [?FILE, ?LINE]])).
+-define(PRINTDEBUG2(Case, Msg),
+ io:format("erl_server: case: ~p~n"
+ "erl_server: Msg: ~p~n"
+ "erl_server: location: ~p~n", [Case, Msg, [?FILE, ?LINE]])).
+
+init(Env) ->
+ {ok, []}.
+
+terminate(F, R) ->
+ ok.
+
+'_get_l'(State) ->
+ ?PRINTDEBUG("_get_l"),
+ {reply, State, State}.
+void_test(State) ->
+ ?PRINTDEBUG("void_test"),
+ {reply, ok, State}.
+
+'_set_l'(State, V) ->
+ ?PRINTDEBUG2("_set_l", V),
+ {reply, ok, V}.
+ushort_test(State, V) ->
+ ?PRINTDEBUG2("ushort_test", V),
+ {reply, {V, V}, State}.
+long_test(State, V) ->
+ ?PRINTDEBUG2("long_test", V),
+ {reply, {V, V}, State}.
+longlong_test(State, V) ->
+ ?PRINTDEBUG2("longlong_test", V),
+ {reply, {V, V}, State}.
+ulong_test(State, V) ->
+ ?PRINTDEBUG2("ulong_test", V),
+ {reply, {V, V}, State}.
+ulonglong_test(State, V) ->
+ ?PRINTDEBUG2("ulonglong_test", V),
+ {reply, {V, V}, State}.
+double_test(State, V) ->
+ ?PRINTDEBUG2("double_test", V),
+ {reply, {V, V}, State}.
+char_test(State, V) ->
+ ?PRINTDEBUG2("char_test", V),
+ {reply, {V, V}, State}.
+wchar_test(State, V) ->
+ ?PRINTDEBUG2("wchar_test", V),
+ {reply, {V, V}, State}.
+octet_test(State, V) ->
+ ?PRINTDEBUG2("octet_test", V),
+ {reply, {V, V}, State}.
+bool_test(State, V) ->
+ ?PRINTDEBUG2("bool_test", V),
+ {reply, {V, V}, State}.
+
+struct_test(State, V) ->
+ ?PRINTDEBUG2("struct_test", V),
+ {reply, {V, V}, State}.
+struct2_test(State, V) ->
+ ?PRINTDEBUG2("struct2_test", V),
+ {reply, {V, V}, State}.
+seq1_test(State, V) ->
+ ?PRINTDEBUG2("seq1_test", V),
+ {reply, {V, V}, State}.
+seq2_test(State, V) ->
+ ?PRINTDEBUG2("seq2_test", V),
+ {reply, {V, V}, State}.
+seq3_test(State, V) ->
+ ?PRINTDEBUG2("seq3_test", V),
+ {reply, {V, V}, State}.
+seq4_test(State, V) ->
+ ?PRINTDEBUG2("seq4_test", V),
+ {reply, {V, V}, State}.
+seq5_test(State, V) ->
+ ?PRINTDEBUG2("seq5_test", V),
+ {reply, {V, V}, State}.
+array1_test(State, V) ->
+ ?PRINTDEBUG2("array1_test", V),
+ {reply, {V, V}, State}.
+array2_test(State, V) ->
+ ?PRINTDEBUG2("array2_test", V),
+ {reply, {V, V}, State}.
+enum_test(State, V) ->
+ ?PRINTDEBUG2("enum_test", V),
+ {reply, {V, V}, State}.
+string1_test(State, V) ->
+ ?PRINTDEBUG2("string1_test", V),
+ {reply, {V, V}, State}.
+string2_test(State, V) ->
+ ?PRINTDEBUG2("string2_test", V),
+ {reply, {V, V}, State}.
+string3_test(State, V) ->
+ ?PRINTDEBUG2("string3_test", V),
+ {reply, {V, V}, State}.
+string4_test(State, V) ->
+ ?PRINTDEBUG2("string4_test", V),
+ {reply, {V, V}, State}.
+pid_test(State, V) ->
+ ?PRINTDEBUG2("pid_test", V),
+ {reply, {V, V}, State}.
+port_test(State, V) ->
+ ?PRINTDEBUG2("port_test", binary_to_list(term_to_binary(V))),
+ {reply, {V, V}, State}.
+ref_test(State, V) ->
+ ?PRINTDEBUG2("ref_test", binary_to_list(term_to_binary(V))),
+ {reply, {V, V}, State}.
+term_test(State, V) ->
+ ?PRINTDEBUG2("term_test", V),
+ {reply, {V, V}, State}.
+typedef_test(State, A, B) ->
+ ?PRINTDEBUG2("typedef_test", [A,B]),
+ {reply, {4711, A, B}, State}.
+inline_sequence_test(State, V) ->
+ ?PRINTDEBUG2("inline_sequence_test", V),
+ {reply, {V, V}, State}.
+term_sequence_test(State, V) ->
+ ?PRINTDEBUG2("term_sequence_test", V),
+ {reply, {V, V}, State}.
+term_struct_test(State, V) ->
+ ?PRINTDEBUG2("term_struct_test", V),
+ {reply, {V, V}, State}.
+wstring1_test(State, V) ->
+ ?PRINTDEBUG2("wstring1_test", V),
+ {reply, {V, V}, State}.
+
+
+
+
diff --git a/lib/ic/test/c_client_erl_server_proto_tmo_SUITE_data/my.c b/lib/ic/test/c_client_erl_server_proto_tmo_SUITE_data/my.c
new file mode 100644
index 0000000000..4e0be3fec1
--- /dev/null
+++ b/lib/ic/test/c_client_erl_server_proto_tmo_SUITE_data/my.c
@@ -0,0 +1,51 @@
+/*
+ * %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 "ic.h"
+#include "m_i.h"
+
+int my_prepare_notification_encoding(CORBA_Environment *env)
+{
+ return oe_prepare_notification_encoding(env);
+}
+
+int my_send_notification_tmo(CORBA_Environment *env, unsigned int send_ms)
+{
+ return oe_send_notification_tmo(env, send_ms);
+}
+
+int my_prepare_request_encoding(CORBA_Environment *env)
+{
+ return oe_prepare_request_encoding(env);
+}
+
+int my_send_request_and_receive_reply_tmo(CORBA_Environment *env,
+ unsigned int send_ms,
+ unsigned int recv_ms)
+{
+ return oe_send_request_and_receive_reply_tmo(env, send_ms, recv_ms);
+}
+
+int my_prepare_reply_decoding(CORBA_Environment *env)
+{
+ return oe_prepare_reply_decoding(env);
+}
+
+
+
diff --git a/lib/ic/test/erl_client_c_server_SUITE.erl b/lib/ic/test/erl_client_c_server_SUITE.erl
new file mode 100644
index 0000000000..c5f5b6a218
--- /dev/null
+++ b/lib/ic/test/erl_client_c_server_SUITE.erl
@@ -0,0 +1,350 @@
+%%
+%% %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%
+%%
+%%
+
+%%----------------------------------------------------------------------
+%% Purpose : Test suite for erl-client/c-server
+%%----------------------------------------------------------------------
+
+
+-module(erl_client_c_server_SUITE).
+-include("test_server.hrl").
+
+-export([init_per_testcase/2, fin_per_testcase/2, all/1, void_test/1,
+ long_test/1, longlong_test/1, ushort_test/1, ulong_test/1,
+ ulonglong_test/1, double_test/1, char_test/1, wchar_test/1,
+ octet_test/1, bool_test/1, struct_test/1, struct2_test/1,
+ seq1_test/1, seq2_test/1, seq3_test/1, seq4_test/1,
+ seq5_test/1, array1_test/1, array2_test/1, enum_test/1,
+ string1_test/1, string2_test/1, string3_test/1,
+ string4_test/1, pid_test/1, port_test/1, ref_test/1,
+ term_test/1, typedef_test/1, inline_sequence_test/1,
+ term_sequence_test/1, term_struct_test/1, wstring1_test/1]).
+
+-define(DEFAULT_TIMEOUT, 20000).
+-define(PORT_TIMEOUT, 15000).
+-define(CALL_TIMEOUT, 5000).
+
+-define(C_SERVER_NODE_NAME, idl_c_server_test).
+
+%% Add/remove code path and watchdog before/after each test case.
+%%
+init_per_testcase(_Case, Config) ->
+ DataDir = ?config(data_dir, Config),
+ code:add_patha(DataDir),
+
+ %% Since other test suites use the module m_i, we have
+ %% to make sure we are using the right m_i module.
+ code:purge(m_i),
+ code:load_file(m_i),
+
+ WatchDog = test_server:timetrap(?DEFAULT_TIMEOUT),
+ [{watchdog, WatchDog}| Config].
+
+fin_per_testcase(_Case, Config) ->
+ DataDir = ?config(data_dir, Config),
+ code:del_path(DataDir),
+ WatchDog = ?config(watchdog, Config),
+ test_server:timetrap_cancel(WatchDog).
+
+all(doc) ->
+ "Test of IC with an Erlang client and a C server. "
+ "The communication is via Erlang distribution.";
+all(suite) ->
+ [void_test, long_test, longlong_test, ushort_test,
+ ulong_test, ulonglong_test, double_test,
+ char_test, wchar_test, octet_test, bool_test, struct_test,
+ struct2_test, seq1_test, seq2_test, seq3_test, seq4_test,
+ seq5_test, array1_test, array2_test, enum_test, string1_test,
+ string2_test, string3_test, string4_test, pid_test, port_test,
+ ref_test, term_test, typedef_test, inline_sequence_test,
+ term_sequence_test, term_struct_test, wstring1_test].
+
+
+array1_test(doc) -> "";
+array1_test(suite) -> [];
+array1_test(Config) ->
+ do_test(array1_test, Config).
+
+array2_test(doc) -> "";
+array2_test(suite) -> [];
+array2_test(Config) ->
+ do_test(array2_test, Config).
+
+bool_test(doc) -> "";
+bool_test(suite) -> [];
+bool_test(Config) ->
+ do_test(bool_test, Config).
+
+char_test(doc) -> "";
+char_test(suite) -> [];
+char_test(Config) ->
+ do_test(char_test, Config).
+
+double_test(doc) -> "";
+double_test(suite) -> [];
+double_test(Config) ->
+ do_test(double_test, Config).
+
+enum_test(doc) -> "";
+enum_test(suite) -> [];
+enum_test(Config) ->
+ do_test(enum_test, Config).
+
+inline_sequence_test(doc) -> "";
+inline_sequence_test(suite) -> [];
+inline_sequence_test(Config) ->
+ do_test(inline_sequence_test, Config).
+
+longlong_test(doc) -> "";
+longlong_test(suite) -> [];
+longlong_test(Config) ->
+ do_test(longlong_test, Config).
+
+long_test(doc) -> "";
+long_test(suite) -> [];
+long_test(Config) ->
+ do_test(long_test, Config).
+
+octet_test(doc) -> "";
+octet_test(suite) -> [];
+octet_test(Config) ->
+ do_test(octet_test, Config).
+
+pid_test(doc) -> "";
+pid_test(suite) -> [];
+pid_test(Config) ->
+ do_test(pid_test, Config).
+
+port_test(doc) -> "";
+port_test(suite) -> [];
+port_test(Config) ->
+ do_test(port_test, Config).
+
+ref_test(doc) -> "";
+ref_test(suite) -> [];
+ref_test(Config) ->
+ do_test(ref_test, Config).
+
+seq1_test(doc) -> "";
+seq1_test(suite) -> [];
+seq1_test(Config) ->
+ do_test(seq1_test, Config).
+
+seq2_test(doc) -> "";
+seq2_test(suite) -> [];
+seq2_test(Config) ->
+ do_test(seq2_test, Config).
+
+seq3_test(doc) -> "";
+seq3_test(suite) -> [];
+seq3_test(Config) ->
+ do_test(seq3_test, Config).
+
+seq4_test(doc) -> "";
+seq4_test(suite) -> [];
+seq4_test(Config) ->
+ do_test(seq4_test, Config).
+
+seq5_test(doc) -> "";
+seq5_test(suite) -> [];
+seq5_test(Config) ->
+ do_test(seq5_test, Config).
+
+string1_test(doc) -> "";
+string1_test(suite) -> [];
+string1_test(Config) ->
+ do_test(string1_test, Config).
+
+string2_test(doc) -> "";
+string2_test(suite) -> [];
+string2_test(Config) ->
+ do_test(string2_test, Config).
+
+string3_test(doc) -> "";
+string3_test(suite) -> [];
+string3_test(Config) ->
+ do_test(string3_test, Config).
+
+string4_test(doc) -> "";
+string4_test(suite) -> [];
+string4_test(Config) ->
+ do_test(string4_test, Config).
+
+struct2_test(doc) -> "";
+struct2_test(suite) -> [];
+struct2_test(Config) ->
+ do_test(struct2_test, Config).
+
+struct_test(doc) -> "";
+struct_test(suite) -> [];
+struct_test(Config) ->
+ do_test(struct_test, Config).
+
+term_sequence_test(doc) -> "";
+term_sequence_test(suite) -> [];
+term_sequence_test(Config) ->
+ do_test(term_sequence_test, Config).
+
+term_struct_test(doc) -> "";
+term_struct_test(suite) -> [];
+term_struct_test(Config) ->
+ do_test(term_struct_test, Config).
+
+term_test(doc) -> "";
+term_test(suite) -> [];
+term_test(Config) ->
+ do_test(term_test, Config).
+
+typedef_test(doc) -> "";
+typedef_test(suite) -> [];
+typedef_test(Config) ->
+ do_test(typedef_test, Config).
+
+ulonglong_test(doc) -> "";
+ulonglong_test(suite) -> [];
+ulonglong_test(Config) ->
+ do_test(ulonglong_test, Config).
+
+ulong_test(doc) -> "";
+ulong_test(suite) -> [];
+ulong_test(Config) ->
+ do_test(ulong_test, Config).
+
+ushort_test(doc) -> "";
+ushort_test(suite) -> [];
+ushort_test(Config) ->
+ do_test(ushort_test, Config).
+
+void_test(doc) -> "";
+void_test(suite) -> [];
+void_test(Config) ->
+ do_test(void_test, Config).
+
+wchar_test(doc) -> "";
+wchar_test(suite) -> [];
+wchar_test(Config) ->
+ do_test(wchar_test, Config).
+
+wstring1_test(doc) -> "";
+wstring1_test(suite) -> [];
+wstring1_test(Config) ->
+ do_test(wstring1_test, Config).
+
+
+do_test(Case, Config) ->
+ %% Trap exits
+ process_flag(trap_exit, true),
+ Node = atom_to_list(node()),
+ [_NodeName, HostName] = string:tokens(Node, "@"),
+ DataDir = ?config(data_dir, Config),
+ %% io:format("~p: data directory: ~p~n", [?MODULE, DataDir]),
+ Cookie = atom_to_list(erlang:get_cookie()),
+ ServerNodeName = atom_to_list(?C_SERVER_NODE_NAME),
+ %% Start C-server node as a port program. We wait for the node
+ %% to connect to us.
+ Cmd = filename:join([DataDir, "c_server"]) ++
+ " -this-node-name " ++ ServerNodeName ++
+ " -peer-node " ++ Node ++
+ " -cookie " ++ Cookie,
+ Port = open_port({spawn, Cmd}, [exit_status, eof, stderr_to_stdout]),
+ ServerNode = list_to_atom(ServerNodeName ++ "@" ++ HostName),
+ Res = case wait_for_hidden_node(ServerNode) of
+ ok ->
+ %% Need a port for port_test and typedef_test
+ put(port_test_port, Port),
+ R = (catch erl_client:Case(ServerNode, ?CALL_TIMEOUT)),
+ case wait_for_completion(Port) of
+ {error, timeout} ->
+ kill_off_node(ServerNode);
+ _ ->
+ ok
+ end,
+ R;
+ {error, timeout} ->
+ case wait_for_completion(Port) of
+ {error, timeout} ->
+ kill_off_node(ServerNode);
+ _ ->
+ ok
+ end,
+ {error, timeout}
+ end,
+ process_flag(trap_exit, false),
+ true = Res.
+
+
+%% Wait for eof *and* exit status, but return if exit status indicates
+%% an error, or we have been waiting more than PORT_TIMEOUT seconds.
+%%
+wait_for_completion(Port) ->
+ wait_for_completion(Port, 0).
+
+wait_for_completion(Port, N) when N < 2 ->
+ receive
+ {Port, {data, Bytes}} ->
+ %% Relay output
+ io:format("~s", [Bytes]),
+ wait_for_completion(Port, N);
+ {Port, {exit_status, 0}} ->
+ wait_for_completion(Port, N + 1);
+ {Port, {exit_status, Status}} ->
+ {error, Status};
+ {Port, eof} ->
+ wait_for_completion(Port, N + 1);
+ {'EXIT', Port, Reason} ->
+ io:format("Port exited with reason: ~w~n", [Reason]),
+ wait_for_completion(Port, N);
+ {'EXIT', From, Reason} ->
+ io:format("Got unexpected exit: ~p~n", [{'EXIT', From, Reason}]),
+ wait_for_completion(Port, N)
+ after ?PORT_TIMEOUT ->
+ {error, timeout}
+ end;
+wait_for_completion(_, _) ->
+ ok.
+
+wait_for_hidden_node(Node) ->
+ Times = ?DEFAULT_TIMEOUT div 100,
+ wait_for_hidden_node(Node, Times, 100).
+
+wait_for_hidden_node(Node, Times, WaitTime) when Times > 0 ->
+ io:format("Waiting for hidden node: ~p~n", [Node]),
+ case lists:member(Node, erlang:nodes(hidden)) of
+ true ->
+ ok;
+ false ->
+ delay(WaitTime),
+ wait_for_hidden_node(Node, Times - 1, WaitTime)
+ end;
+wait_for_hidden_node(_Node, _, _WaitTime) ->
+ {error, timeout}.
+
+kill_off_node(Node) ->
+ catch rpc:cast(Node, erlang, halt, [1]).
+
+delay(Time) ->
+ receive
+ after Time ->
+ ok
+ end.
+
+
+
+
diff --git a/lib/ic/test/erl_client_c_server_SUITE_data/Makefile.src b/lib/ic/test/erl_client_c_server_SUITE_data/Makefile.src
new file mode 100644
index 0000000000..cd34d2b247
--- /dev/null
+++ b/lib/ic/test/erl_client_c_server_SUITE_data/Makefile.src
@@ -0,0 +1,150 @@
+#
+# %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%
+#
+#
+# Makefile.src for erl_client_c_server test
+# Note: This file *must* work for both Unix and Windows
+#
+# We use both `rm' (Unix) and `del' (Windows) for removing files, but
+# with a `-' in front so that the error in not finding `rm' (`del') on
+# Windows (Unix) is ignored.
+#
+# VxWorks? XXX
+#
+
+.SUFFIXES:
+.SUFFIXES: .c .h .erl .idl @obj@ .@EMULATOR@
+
+
+# Variables from ts:
+#
+
+ERL_INCLUDE = @erl_include@
+
+IC_INCLUDE_PATH = @ic_include_path@
+IC_LIB = @ic_libpath@@DS@@ic_lib@
+
+ERL_INTERFACE_INCLUDE = @erl_interface_include@
+ERL_INTERFACE_LIB = @erl_interface_libpath@@DS@@erl_interface_lib@
+ERL_INTERFACE_EILIB = @erl_interface_libpath@@DS@@erl_interface_eilib@
+ERL_INTERFACE_THREADLIB = @erl_interface_threadlib@
+ERL_INTERFACE_SOCK_LIBS = @erl_interface_sock_libs@
+
+CC = @CC@
+## XXX Should set warning flag with a DEBUG_FLAG
+CFLAGS = @CFLAGS@ @DEFS@ -I$(ERL_INCLUDE) \
+ -I$(IC_INCLUDE_PATH) -I$(ERL_INTERFACE_INCLUDE)
+
+LD = @LD@
+LDFLAGS = @CROSSLDFLAGS@
+LIBS = $(IC_LIB) $(ERL_INTERFACE_LIB) $(ERL_INTERFACE_EILIB) \
+ $(ERL_INTERFACE_THREADLIB) @LIBS@ $(ERL_INTERFACE_SOCK_LIBS)
+ERLC = erlc
+
+# Generated C header files
+GEN_H_FILES = \
+ m__s.h \
+ m_i__s.h \
+ oe_erl_c_test__s.h
+
+# Generated C files
+GEN_C_FILES = \
+ m__s.c \
+ m_i__s.c \
+ oe_code_m_a.c \
+ oe_code_m_arr1.c \
+ oe_code_m_arr2.c \
+ oe_code_m_arr3.c \
+ oe_code_m_aseq.c \
+ oe_code_m_b.c \
+ oe_code_m_bseq.c \
+ oe_code_m_dd.c \
+ oe_code_m_dyn.c \
+ oe_code_m_dyn_sl.c \
+ oe_code_m_es.c \
+ oe_code_m_et.c \
+ oe_code_m_etseq.c \
+ oe_code_m_fruit.c \
+ oe_code_m_lseq.c \
+ oe_code_m_s.c \
+ oe_code_m_s_sl.c \
+ oe_code_m_sarr3.c \
+ oe_code_m_simple.c \
+ oe_code_m_ssarr3.c \
+ oe_code_m_sseq.c \
+ oe_code_m_ssstr3.c \
+ oe_code_m_sstr3.c \
+ oe_code_m_str1.c \
+ oe_code_m_str3.c \
+ oe_code_m_strRec.c \
+ oe_code_m_strRec_str5.c \
+ oe_code_m_strRec_str7.c \
+ oe_erl_c_test__s.c
+
+GEN_HRL_FILES = \
+ m.hrl \
+ m_i.hrl \
+ oe_erl_c_test.hrl
+
+GEN_ERL_FILES = \
+ m.erl \
+ m_arr2.erl \
+ m_arr3.erl \
+ m_i.erl \
+ m_str3.erl \
+ oe_erl_c_test.erl
+
+C_FILES = $(GEN_C_FILES) c_server.c callbacks.c
+
+OBJS = $(C_FILES:.c=@obj@)
+
+PGMS = c_server@exe@
+
+ERL_FILES = $(GEN_ERL_FILES) erl_client.erl
+
+EBINS = $(ERL_FILES:.erl=.@EMULATOR@)
+
+
+all: $(PGMS) $(EBINS)
+
+clean:
+ -rm -f $(OBJS) $(GEN_C_FILES) $(GEN_H_FILES) $(PGMS) \
+ $(EBINS) $(GEN_ERL_FILES) $(GEN_HRL_FILES)
+ -del /F /Q $(OBJS) $(GEN_C_FILES) $(GEN_H_FILES) $(PGMS) \
+ $(EBINS) $(GEN_ERL_FILES) $(GEN_HRL_FILES)
+
+$(PGMS): $(OBJS)
+ $(LD) $(LDFLAGS) -o $@ $(OBJS) $(LIBS)
+
+$(GEN_C_FILES) $(GEN_H_FILES): erl_c_test.idl
+ $(ERLC) -I $(IC_INCLUDE_PATH) "+{be,c_server}" \
+ "+{scoped_op_calls,true}" erl_c_test.idl
+
+# If we have scoped operation calls for C, we must have that for
+# Erlang as well, if we use the m_i.erl file for calling the server.
+
+$(GEN_ERL_FILES) $(GEN_HRL_FILES): erl_c_test.idl
+ $(ERLC) -I $(IC_INCLUDE_PATH) "+{be,erl_genserv}" \
+ "+{scoped_op_calls,true}" "+{timeout,true}" erl_c_test.idl
+
+.c@obj@:
+ $(CC) -c -o $*@obj@ $(CFLAGS) $<
+
+.erl.@EMULATOR@:
+ $(ERLC) -W -I $(IC_INCLUDE_PATH) $<
+
diff --git a/lib/ic/test/erl_client_c_server_SUITE_data/c_server.c b/lib/ic/test/erl_client_c_server_SUITE_data/c_server.c
new file mode 100644
index 0000000000..acdeff80fe
--- /dev/null
+++ b/lib/ic/test/erl_client_c_server_SUITE_data/c_server.c
@@ -0,0 +1,299 @@
+/*
+ * %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%
+ *
+ */
+/* C-server for test of IC.
+ *
+ * The C-node implemented here connects to its peer node, waits for
+ * one message, evaluates the message, returns an result message, and
+ * terminates.
+ *
+ * TODO:
+ *
+ * 1. XXX #includes for VxWorks, Windows
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#ifndef __WIN32__
+# include <unistd.h>
+#endif
+
+#include <string.h>
+
+#ifdef __WIN32__
+# include <time.h>
+# include <sys/timeb.h>
+#elif defined VXWORKS
+# include <time.h>
+# include <sys/times.h>
+#else
+# include <sys/time.h>
+#endif
+
+#include <ctype.h>
+
+#ifdef __WIN32__
+# include <winsock2.h>
+# include <windows.h>
+#else
+# include <sys/types.h>
+# include <sys/socket.h>
+# include <netinet/in.h>
+# include <arpa/inet.h>
+# include <netdb.h>
+#endif
+
+#include "ic.h"
+#include "ei.h"
+#include "erl_interface.h"
+#include "eicode.h"
+#include "m_i__s.h"
+#include "m__s.h"
+
+#ifdef __WIN32__
+typedef struct {
+ long tv_sec;
+ long tv_usec;
+} MyTimeval;
+#else
+typedef struct timeval MyTimeval;
+#endif
+static void my_gettimeofday(MyTimeval *tv);
+static void showtime(MyTimeval *start, MyTimeval *stop);
+static void usage(void);
+static void done(int r);
+
+#define HOSTNAMESZ 256
+#define NODENAMESZ 512
+#define INBUFSZ 10
+#define OUTBUFSZ 0
+#define MAXTRIES 5
+
+static char *progname;
+
+/* main */
+#ifdef VXWORKS
+int c_server(int argc, char **argv)
+#else
+int main(int argc, char **argv)
+#endif
+{
+ struct hostent *hp;
+ MyTimeval start, stop;
+ int i, fd, ires, tries;
+ CORBA_Environment *env;
+ char *this_node_name = NULL;
+ char *peer_node = NULL;
+ char *cookie = NULL;
+ char host[HOSTNAMESZ + 1];
+ char this_node[NODENAMESZ + 1];
+ erlang_msg msg;
+ int status, loop;
+
+#ifdef __WIN32__
+ WORD wVersionRequested;
+ WSADATA wsaData;
+
+ wVersionRequested = MAKEWORD(2, 0);
+
+ if (WSAStartup(wVersionRequested, &wsaData) != 0) {
+ fprintf(stderr, "Could not load winsock2 v2.0 compatible DLL");
+ exit(1);
+ }
+#endif
+
+ progname = argv[0];
+ host[HOSTNAMESZ] = '\0';
+ if (gethostname(host, HOSTNAMESZ) < 0) {
+ fprintf(stderr, "Can't find own hostname\n");
+ done(1);
+ }
+ if ((hp = gethostbyname(host)) == 0) {
+ fprintf(stderr, "Can't get ip address for host %s\n", host);
+ done(1);
+ }
+ for (i = 1; i < argc; i++) {
+ if (strcmp(argv[i], "-help") == 0) {
+ usage();
+ done(0);
+ } else if (strcmp(argv[i], "-this-node-name") == 0) {
+ i++;
+ this_node_name = argv[i];
+ } else if (strcmp(argv[i], "-peer-node") == 0) {
+ i++;
+ peer_node = argv[i];
+ } else if (strcmp(argv[i], "-cookie") == 0) {
+ i++;
+ cookie = argv[i];
+ } else {
+ fprintf(stderr, "Error : invalid argument \"%s\"\n", argv[i]);
+ usage();
+ done(1);
+ }
+ }
+
+ if (this_node_name == NULL || peer_node == NULL || cookie == NULL) {
+ fprintf(stderr, "Error: missing option\n");
+ usage();
+ done(1);
+ }
+
+ /* Behead hostname at first dot */
+ for (i=0; host[i] != '\0'; i++) {
+ if (host[i] == '.') { host[i] = '\0'; break; }
+ }
+ sprintf(this_node, "%s@%s", this_node_name, host);
+
+ fprintf(stderr, "c_server: this node: \"%s\"\n", this_node);
+ fprintf(stderr, "c_server: peer node: \"%s\"\n", peer_node);
+
+ /* initialize erl_interface */
+ erl_init(NULL, 0);
+
+ for (tries = 0; tries < MAXTRIES; tries++) {
+ /* connect to peer node */
+ ires = erl_connect_xinit(host, this_node_name, this_node,
+ (struct in_addr *)*hp->h_addr_list,
+ cookie, 0);
+ fprintf(stderr, "c_server: erl_connect_xinit(): %d\n", ires);
+
+ fd = erl_connect(peer_node);
+ fprintf(stderr, "c_server: erl_connect(): %d\n", fd);
+ if (fd >= 0)
+ break;
+ fprintf(stderr, "c_server: cannot connect, retrying\n");
+ }
+ if (fd < 0) {
+ fprintf(stderr, "c_server: cannot connect, exiting\n");
+ done(1);
+ }
+ env = CORBA_Environment_alloc(INBUFSZ, OUTBUFSZ);
+ env->_fd = fd;
+
+ status = 1;
+ loop = 1;
+ my_gettimeofday(&start);
+ while (status >= 0 && loop > 0) {
+ status = ei_receive_encoded(env->_fd, &env->_inbuf, &env->_inbufsz,
+ &msg, &env->_iin);
+ switch(status) {
+ case ERL_SEND:
+ case ERL_REG_SEND:
+ /* get result */
+ m_i__switch(NULL, env);
+ switch(env->_major) {
+ case CORBA_NO_EXCEPTION:
+ break;
+ case CORBA_SYSTEM_EXCEPTION:
+ fprintf(stderr, "Request failure, reason : %s\n",
+ (char *) CORBA_exception_value(env));
+ CORBA_exception_free(env);
+ break;
+ default: /* Should not happen */
+ CORBA_exception_free(env);
+ break;
+ }
+ /* send back result data */
+ if (env->_iout > 0)
+ ei_send_encoded(env->_fd, &env->_caller, env->_outbuf,
+ env->_iout);
+ loop = 0;
+ break;
+ case ERL_TICK:
+ break;
+ default:
+ if (status < 0) {
+ fprintf(stderr, "Status negative: %d\n", status);
+ loop = 0;
+ }
+ break;
+ }
+ }
+ my_gettimeofday(&stop);
+ showtime(&start, &stop);
+
+ erl_close_connection(fd);
+
+ CORBA_free(env->_inbuf);
+ CORBA_free(env->_outbuf);
+ CORBA_free(env);
+ if (status < 0)
+ done(-status);
+ else
+ done(0);
+}
+
+static void usage()
+{
+ fprintf(stderr, "Usage: %s [-help] -this-node-name <name> "
+ "-peer-node <nodename> -cookie <cookie>\n", progname);
+ fprintf(stderr, "Example:\n %s -this-node-name kalle "
+ "-peer-node olle@home -cookie oa678er\n", progname);
+}
+
+static void done(int r)
+{
+#ifdef __WIN32__
+ WSACleanup();
+#endif
+ exit(r);
+}
+
+static void showtime(MyTimeval *start, MyTimeval *stop)
+{
+ MyTimeval elapsed;
+
+ elapsed.tv_sec = stop->tv_sec - start->tv_sec;
+ elapsed.tv_usec = stop->tv_usec - start->tv_usec;
+ while (elapsed.tv_usec < 0) {
+ elapsed.tv_sec -= 1;
+ elapsed.tv_usec += 1000000;
+ }
+ fprintf(stderr,"%ld.%06ld seconds\n",elapsed.tv_sec, elapsed.tv_usec);
+}
+
+
+
+static void my_gettimeofday(MyTimeval *tv)
+#ifdef __WIN32__
+#define EPOCH_JULIAN_DIFF 11644473600i64
+{
+ SYSTEMTIME t;
+ FILETIME ft;
+ LONGLONG lft;
+
+ GetSystemTime(&t);
+ SystemTimeToFileTime(&t, &ft);
+ memcpy(&lft, &ft, sizeof(lft));
+ tv->tv_usec = (long) ((lft / 10i64) % 1000000i64);
+ tv->tv_sec = (long) ((lft / 10000000i64) - EPOCH_JULIAN_DIFF);
+}
+#elif defined VXWORKS
+{
+ int rate = sysClkRateGet(); /* Ticks per second */
+ unsigned long ctick = tickGet();
+ tv->tv_sec = ctick / rate; /* secs since reboot */
+ tv->tv_usec = ((ctick - (tv->tv_sec * rate))*1000000)/rate;
+}
+#else
+{
+ gettimeofday(tv, NULL);
+}
+#endif
diff --git a/lib/ic/test/erl_client_c_server_SUITE_data/callbacks.c b/lib/ic/test/erl_client_c_server_SUITE_data/callbacks.c
new file mode 100644
index 0000000000..d6b28b619d
--- /dev/null
+++ b/lib/ic/test/erl_client_c_server_SUITE_data/callbacks.c
@@ -0,0 +1,610 @@
+/*
+ * %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 <stdio.h>
+#include <stdlib.h>
+#ifndef __WIN32__
+# include <unistd.h>
+#endif
+#include <string.h>
+#include <ctype.h>
+#include <ic.h>
+#include <erl_interface.h>
+#include <ei.h>
+#include "m_i__s.h"
+
+
+
+/* OK */
+
+void my_void_test(CORBA_Object oe_obj,
+ CORBA_Environment *oe_env)
+{
+ /* printf("void test !\n"); */
+}
+
+m_i_void_test__rs* m_i_void_test__cb(CORBA_Object oe_obj,
+ CORBA_Environment *oe_env)
+{
+ return (m_i_void_test__rs*) (my_void_test);
+}
+
+
+
+/* OK */
+
+void my_long_test(CORBA_Object oe_obj,
+ long* a,
+ long* b,
+ long* c,
+ CORBA_Environment *oe_env)
+{
+ /* printf("long test !\n"); */
+}
+
+
+m_i_long_test__rs* m_i_long_test__cb(CORBA_Object oe_obj,
+ long* a,
+ long* b,
+ long* c,
+ CORBA_Environment *oe_env)
+{
+ *a = *b;
+ *c = *b;
+ return (m_i_long_test__rs*) (my_long_test);
+}
+
+/* OK */
+
+void my_longlong_test(CORBA_Object oe_obj,
+ CORBA_long_long* a,
+ CORBA_long_long* b,
+ CORBA_long_long* c,
+ CORBA_Environment *oe_env)
+{
+ /* printf("long test !\n"); */
+}
+
+m_i_longlong_test__rs* m_i_longlong_test__cb(CORBA_Object oe_obj,
+ CORBA_long_long* a,
+ CORBA_long_long* b,
+ CORBA_long_long* c,
+ CORBA_Environment *oe_env)
+{
+ *a = *b;
+ *c = *b;
+ return (m_i_longlong_test__rs*) (my_longlong_test);
+}
+
+/* OK */
+void my_ulong_test(CORBA_Object oe_obj,
+ unsigned long* a,
+ unsigned long* b,
+ unsigned long* c,
+ CORBA_Environment *oe_env)
+{
+ /* printf("ulong test !\n"); */
+}
+
+m_i_ulong_test__rs* m_i_ulong_test__cb(CORBA_Object oe_obj,
+ unsigned long* a,
+ unsigned long* b,
+ unsigned long* c,
+ CORBA_Environment *oe_env)
+{
+ *a = *b;
+ *c = *b;
+ return (m_i_ulong_test__rs*) (my_ulong_test);
+}
+
+/* OK */
+void my_ulonglong_test(CORBA_Object oe_obj,
+ CORBA_unsigned_long_long* a,
+ CORBA_unsigned_long_long* b,
+ CORBA_unsigned_long_long* c,
+ CORBA_Environment *oe_env)
+{
+ /* printf("ulong test !\n"); */
+}
+
+m_i_ulonglong_test__rs* m_i_ulonglong_test__cb(CORBA_Object oe_obj,
+ CORBA_unsigned_long_long* a,
+ CORBA_unsigned_long_long* b,
+ CORBA_unsigned_long_long* c,
+ CORBA_Environment *oe_env)
+{
+ *a = *b;
+ *c = *b;
+ return (m_i_ulonglong_test__rs*) (my_ulonglong_test);
+}
+
+m_i_ushort_test__rs* m_i_ushort_test__cb(CORBA_Object oe_obj,
+ unsigned short* a,
+ unsigned short* b,
+ unsigned short* c,
+ CORBA_Environment *oe_env)
+{
+ *a = *b;
+ *c = *b;
+ return (m_i_ushort_test__rs*) NULL;
+}
+
+
+/* OK */
+void my_double_test(CORBA_Object oe_obj,
+ double* a,
+ double* b,
+ double* c,
+ CORBA_Environment *oe_env)
+{
+ /* printf("double test !\n"); */
+}
+
+m_i_double_test__rs* m_i_double_test__cb(CORBA_Object oe_obj,
+ double* a,
+ double* b,
+ double* c,
+ CORBA_Environment *oe_env)
+{
+ *a = *b;
+ *c = *b;
+ return (m_i_double_test__rs*) (my_double_test);
+}
+
+/* OK */
+m_i_char_test__rs* m_i_char_test__cb(CORBA_Object oe_obj,
+ char* a,
+ char* b,
+ char* c,
+ CORBA_Environment *oe_env)
+{
+ m_i_char_test__rs* rs = NULL;
+
+ *a = *b;
+ *c = *b;
+ return rs;
+}
+
+
+/* OK */
+m_i_wchar_test__rs* m_i_wchar_test__cb(CORBA_Object oe_obj,
+ CORBA_wchar* a,
+ CORBA_wchar* b,
+ CORBA_wchar* c,
+ CORBA_Environment *oe_env)
+{
+ m_i_wchar_test__rs* rs = NULL;
+
+ *a = *b;
+ *c = *b;
+ return rs;
+}
+
+/* OK */
+m_i_octet_test__rs* m_i_octet_test__cb(CORBA_Object oe_obj,
+ char* a,
+ char* b,
+ char* c,
+ CORBA_Environment *oe_env)
+{
+ m_i_octet_test__rs* rs = NULL;
+
+ *a = *b;
+ *c = *b;
+ return rs;
+}
+
+/* OK */
+m_i_bool_test__rs* m_i_bool_test__cb(CORBA_Object oe_obj,
+ CORBA_boolean* a,
+ CORBA_boolean* b,
+ CORBA_boolean* c,
+ CORBA_Environment *oe_env)
+{
+ m_i_bool_test__rs* rs = NULL;
+
+ *a = *b;
+ *c = *b;
+ return rs;
+}
+
+/* OK */
+void my_struct_test(CORBA_Object oe_obj,
+ m_b* a,
+ m_b* b,
+ m_b* c,
+ CORBA_Environment *oe_env)
+{
+ /* printf("struct test !\n"); */
+}
+
+m_i_struct_test__rs* m_i_struct_test__cb(CORBA_Object oe_obj,
+ m_b* a,
+ m_b* b,
+ m_b* c,
+ CORBA_Environment *oe_env)
+{
+ *a = *b;
+ *c = *b;
+ return (m_i_struct_test__rs*) (my_struct_test);
+}
+
+/* OK */
+m_i_struct2_test__rs* m_i_struct2_test__cb(CORBA_Object oe_obj,
+ m_es* a,
+ m_es* b,
+ m_es* c,
+ CORBA_Environment *oe_env)
+{
+ m_i_struct2_test__rs* rs = NULL;
+
+ *a = *b;
+ *c = *b;
+ return rs;
+}
+
+/* OK */
+/* XXX Commented out
+m_i_struct3_test__rs* m_i_struct3_test__cb(CORBA_Object oe_obj,
+ m_simple* a,
+ m_simple* b,
+ m_simple* c,
+ CORBA_Environment *oe_env)
+{
+ m_i_struct3_test__rs* rs = NULL;
+ *a = *b;
+ *c = *b;
+ return rs;
+}
+*/
+
+/* OK */
+m_i_seq1_test__rs* m_i_seq1_test__cb(CORBA_Object oe_obj,
+ m_bseq** a,
+ m_bseq* b,
+ m_bseq** c,
+ CORBA_Environment *oe_env)
+{
+ m_i_seq1_test__rs* rs = NULL;
+
+ *a = b;
+ *c = b;
+ return rs;
+}
+
+
+/* OK */
+m_i_seq2_test__rs* m_i_seq2_test__cb(CORBA_Object oe_obj,
+ m_aseq** a,
+ m_aseq* b,
+ m_aseq** c,
+ CORBA_Environment *oe_env)
+{
+ m_i_seq2_test__rs* rs = NULL;
+
+ *a = b;
+ *c = b;
+ return rs;
+}
+
+/* OK */
+m_i_seq3_test__rs* m_i_seq3_test__cb(CORBA_Object oe_obj,
+ m_lseq** a,
+ m_lseq* b,
+ m_lseq** c,
+ CORBA_Environment *oe_env)
+{
+ m_i_seq3_test__rs* rs = NULL;
+
+ *a = b;
+ *c = b;
+ return rs;
+}
+
+/* OK */
+m_i_seq4_test__rs* m_i_seq4_test__cb(CORBA_Object oe_obj,
+ m_ssstr3** a,
+ m_ssstr3* b,
+ m_ssstr3** c,
+ CORBA_Environment *oe_env)
+{
+ m_i_seq4_test__rs* rs = NULL;
+
+ *a = b;
+ *c = b;
+ return rs;
+}
+
+/* OK */
+m_i_seq5_test__rs* m_i_seq5_test__cb(CORBA_Object oe_obj,
+ m_ssarr3** a,
+ m_ssarr3* b,
+ m_ssarr3** c,
+ CORBA_Environment *oe_env)
+{
+ m_i_seq5_test__rs* rs = NULL;
+
+ *a = b;
+ *c = b;
+ return rs;
+}
+
+/* OK */
+m_i_array1_test__rs* m_i_array1_test__cb(CORBA_Object oe_obj,
+ m_arr1 a,
+ m_arr1 b,
+ m_arr1 c,
+ CORBA_Environment *oe_env)
+{
+ int i;
+ m_i_array1_test__rs* rs = NULL;
+
+ for (i = 0; i < 500; i++) {
+ a[i] = b[i];
+ c[i] = b[i];
+ }
+ return rs;
+}
+
+/* OK */
+m_i_array2_test__rs* m_i_array2_test__cb(CORBA_Object oe_obj,
+ m_dd a,
+ m_dd b,
+ m_dd c,
+ CORBA_Environment *oe_env)
+{
+ int i,j;
+ m_i_array2_test__rs* rs = NULL;
+
+ for (i = 0; i < 2; i++)
+ for (j = 0; j < 3; j++) {
+ a[i][j] = b[i][j];
+ c[i][j] = b[i][j];
+ }
+ return rs;
+}
+
+
+/* OK */
+m_i_enum_test__rs* m_i_enum_test__cb(CORBA_Object oe_obj,
+ m_fruit* a,
+ m_fruit* b,
+ m_fruit* c,
+ CORBA_Environment *oe_env)
+{
+ m_i_enum_test__rs* rs = NULL;
+
+ *a = *b;
+ *c = *b;
+ return rs;
+}
+
+/* OK */
+m_i_string1_test__rs* m_i_string1_test__cb(CORBA_Object oe_obj,
+ char ** a,
+ char * b,
+ char ** c,
+ CORBA_Environment *oe_env)
+{
+ m_i_string1_test__rs* rs = NULL;
+
+ /*printf("\nString in ------> %s\n\n",b);*/
+ *a = b;
+ *c = b;
+ return rs;
+}
+
+/* OK */
+m_i_string2_test__rs* m_i_string2_test__cb(CORBA_Object oe_obj,
+ m_sseq** a,
+ m_sseq* b,
+ m_sseq** c,
+ CORBA_Environment *oe_env)
+{
+ m_i_string2_test__rs* rs = NULL;
+
+ *a = b;
+ *c = b;
+ return rs;
+}
+
+/* OK */
+m_i_string3_test__rs* m_i_string3_test__cb(CORBA_Object oe_obj,
+ char ** a,
+ char * b,
+ char ** c,
+ CORBA_Environment *oe_env)
+{
+ m_i_string3_test__rs* rs = NULL;
+
+ *a = b;
+ *c = b;
+ return rs;
+}
+
+m_i_string4_test__rs* m_i_string4_test__cb(CORBA_Object oe_obj,
+ m_strRec** a,
+ m_strRec* b,
+ m_strRec** c,
+ CORBA_Environment *oe_env)
+{
+ *a = b;
+ *c = b;
+
+ return (m_i_string4_test__rs*) NULL;
+}
+
+/* OK */
+m_i_wstring1_test__rs* m_i_wstring1_test__cb(CORBA_Object oe_obj,
+ CORBA_wchar ** a,
+ CORBA_wchar * b,
+ CORBA_wchar ** c,
+ CORBA_Environment *oe_env)
+{
+ int tmp;
+ m_i_wstring1_test__rs* rs = NULL;
+
+ /*printf("\nString in ------> %s\n\n",b);*/
+
+ for(tmp = 0; tmp < 5; tmp++)
+ fprintf(stderr,"\np[%d] = %ld\n", tmp, b[tmp]);
+ *a = b;
+ *c = b;
+ return rs;
+}
+
+
+/* OK */
+m_i_pid_test__rs* m_i_pid_test__cb(CORBA_Object oe_obj,
+ erlang_pid* a,
+ erlang_pid* b,
+ erlang_pid* c,
+ CORBA_Environment *oe_env)
+{
+ m_i_pid_test__rs* rs = NULL;
+
+ *a = *b;
+ *c = *b;
+ return rs;
+}
+
+/* OK */
+m_i_port_test__rs* m_i_port_test__cb(CORBA_Object oe_obj,
+ erlang_port* a,
+ erlang_port* b,
+ erlang_port* c,
+ CORBA_Environment *oe_env)
+{
+ m_i_port_test__rs* rs = NULL;
+
+ strcpy((*a).node,(*b).node);
+ (*a).id = (*b).id;
+ (*a).creation = 0;
+
+ strcpy((*c).node,(*b).node);
+ (*c).id = (*b).id;
+ (*c).creation = 0;
+ return rs;
+}
+
+/* OK */
+m_i_ref_test__rs* m_i_ref_test__cb(CORBA_Object oe_obj,
+ erlang_ref* a,
+ erlang_ref* b,
+ erlang_ref* c,
+ CORBA_Environment *oe_env)
+{
+
+ m_i_ref_test__rs* rs = NULL;
+
+ strcpy((*a).node,(*b).node);
+ /*(*a).id = (*b).id;*/
+ (*a).len = (*b).len;
+ (*a).n[0] = (*b).n[0];
+ (*a).n[1] = (*b).n[1];
+ (*a).n[2] = (*b).n[2];
+ (*a).creation = 0;
+
+ strcpy((*c).node,(*b).node);
+ /*(*c).id = (*b).id;*/
+ (*c).len = (*b).len;
+ (*c).n[0] = (*b).n[0];
+ (*c).n[1] = (*b).n[1];
+ (*c).n[2] = (*b).n[2];
+ (*c).creation = 0;
+ return rs;
+}
+
+/* OK */
+m_i_term_test__rs* m_i_term_test__cb(CORBA_Object oe_obj,
+ ETERM** a,
+ ETERM** b,
+ ETERM** c,
+ CORBA_Environment *oe_env)
+{
+ m_i_term_test__rs* rs = NULL;
+
+ *a = *b;
+ *c = *b;
+ return rs;
+}
+
+m_i_typedef_test__rs* m_i_typedef_test__cb(CORBA_Object oe_obj,
+ long* a,
+ ETERM** b,
+ erlang_port* c,
+ ETERM** d ,
+ erlang_port* e,
+ CORBA_Environment *oe_env)
+{
+ m_i_typedef_test__rs* rs = NULL;
+
+ *d = *b;
+ strcpy((*e).node,(*c).node);
+ (*e).id = (*c).id;
+ (*e).creation = 0;
+ *a = 4711;
+ return rs;
+}
+
+/* OK */
+m_i_inline_sequence_test__rs* m_i_inline_sequence_test__cb(
+ CORBA_Object oe_obj,
+ m_s** a,
+ m_s* b,
+ m_s** c,
+ CORBA_Environment *oe_env)
+{
+ m_i_inline_sequence_test__rs* rs = NULL;
+
+ *a = b;
+ *c = b;
+ return rs;
+}
+
+/* OK */
+m_i_term_sequence_test__rs* m_i_term_sequence_test__cb(
+ CORBA_Object oe_obj,
+ m_etseq** a,
+ m_etseq* b,
+ m_etseq** c,
+ CORBA_Environment *oe_env)
+{
+ m_i_term_sequence_test__rs* rs = NULL;
+
+ *a = b;
+ *c = b;
+ return rs;
+}
+
+
+/* OK */
+m_i_term_struct_test__rs* m_i_term_struct_test__cb(CORBA_Object oe_obj,
+ m_et* a,
+ m_et* b,
+ m_et* c,
+ CORBA_Environment *oe_env)
+{
+ m_i_term_struct_test__rs* rs = NULL;
+
+ *a = *b;
+ *c = *b;
+ return rs;
+}
+
diff --git a/lib/ic/test/erl_client_c_server_SUITE_data/erl_c_test.idl b/lib/ic/test/erl_client_c_server_SUITE_data/erl_c_test.idl
new file mode 100644
index 0000000000..963bc69017
--- /dev/null
+++ b/lib/ic/test/erl_client_c_server_SUITE_data/erl_c_test.idl
@@ -0,0 +1,174 @@
+
+
+// %CopyrightBegin%
+//
+// Copyright Ericsson AB 2002-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%
+
+#include "erlang.idl"
+
+
+const short TestConst = 1;
+
+module m {
+
+ const short TestConst = 2;
+
+ struct b {
+ long l;
+ char c;
+ };
+
+ struct simple {
+ long l;
+ b b_t;
+ };
+
+ enum fruit {orange, banana, apple, peach, pear};
+
+ typedef sequence<long> lseq;
+
+ typedef sequence<b> bseq;
+
+ struct a {
+ long l;
+ bseq y;
+ double d;
+ };
+
+ typedef sequence<a> aseq;
+
+ typedef sequence<string> sseq;
+ typedef string str;
+ typedef long myLong;
+
+ typedef long arr1[500], dd[2][3];
+
+ typedef erlang::term apa;
+ typedef erlang::port banan;
+
+ typedef sequence<erlang::term> etseq;
+
+ struct s {
+ long l;
+ sequence<long> sl;
+ };
+
+ struct es {
+ fruit f;
+ myLong l;
+ };
+
+ struct et {
+ erlang::term e;
+ long l;
+ };
+
+
+ typedef sequence<char> str1;
+ typedef string<12> str2;
+ typedef char str3[3];
+
+ typedef sequence<string> sstr3; // sequence of string
+ typedef sequence<sstr3> ssstr3; // sequence of sequences of strings
+
+ typedef long arr3[3]; // array of long
+ typedef sequence<arr3> sarr3; // sequence of array
+ typedef sequence<sarr3> ssarr3; // sequence of sequnces of arrays of strings
+
+ struct strRec{
+ boolean bb;
+ string str4;
+ long str7[3][2];
+ sequence<char> str5;
+ string<12> str6;
+ str3 str8;
+ str2 str9;
+ str1 str10;
+ };
+
+
+ struct dyn {
+ long l;
+ sequence<long> sl;
+ };
+ typedef dyn arr2[1][2];
+
+
+ interface i {
+
+ const short TestConst = 3;
+
+ //arr2 suck(in arr2 x, out arr2 y );
+
+ ///////////////////////////////// attribute long l;
+
+ // simple types
+ void void_test();
+ long long_test(in long a, out long a1);
+ long long longlong_test(in long long a, out long long a1);
+ unsigned short ushort_test(in unsigned short a, out unsigned short a1);
+ unsigned long ulong_test(in unsigned long a, out unsigned long a1);
+ unsigned long long ulonglong_test(in unsigned long long a, out unsigned long long a1);
+ double double_test(in double a, out double a1);
+ char char_test(in char a, out char a1);
+ wchar wchar_test(in wchar a, out wchar a1);
+ octet octet_test(in octet a, out octet a1);
+ boolean bool_test(in boolean a, out boolean a1);
+
+ // Seq. and struct tests
+ b struct_test(in b a, out b a1);
+ es struct2_test(in es a, out es a1);
+ //simple struct3_test(in simple x, out simple y);
+ bseq seq1_test(in bseq a, out bseq a1);
+ aseq seq2_test(in aseq a, out aseq a1);
+ lseq seq3_test(in lseq a, out lseq a1);
+ ssstr3 seq4_test(in ssstr3 a, out ssstr3 a1);
+ ssarr3 seq5_test(in ssarr3 a, out ssarr3 a1);
+
+ // Array tests
+ arr1 array1_test(in arr1 a, out arr1 a1);
+ dd array2_test(in dd a, out dd a1);
+
+ // enum test
+ fruit enum_test(in fruit a, out fruit a1);
+
+ // string tests
+ string string1_test(in string a, out string a1);
+ wstring wstring1_test(in wstring a, out wstring a1);
+ sseq string2_test(in sseq a, out sseq a1);
+ str string3_test(in str a, out str a1);
+ strRec string4_test(in strRec a, out strRec a1);
+
+ // Special erlang types
+ erlang::pid pid_test(in erlang::pid a, out erlang::pid a1);
+ erlang::port port_test(in erlang::port a, out erlang::port a1);
+ erlang::ref ref_test(in erlang::ref a, out erlang::ref a1);
+ erlang::term term_test(in erlang::term a, out erlang::term a1);
+
+ // typedef test
+ long typedef_test(in apa a, in banan b, out apa a1, out banan b1);
+
+ // inlined seq. test
+ s inline_sequence_test(in s a, out s a1);
+
+ // term seq. test
+ etseq term_sequence_test(in etseq a, out etseq a1);
+ // term struct test
+ et term_struct_test(in et a, out et a1);
+
+ };
+
+};
diff --git a/lib/ic/test/erl_client_c_server_SUITE_data/erl_client.erl b/lib/ic/test/erl_client_c_server_SUITE_data/erl_client.erl
new file mode 100644
index 0000000000..79ec28a921
--- /dev/null
+++ b/lib/ic/test/erl_client_c_server_SUITE_data/erl_client.erl
@@ -0,0 +1,331 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 2002-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(erl_client).
+
+-export([void_test/2, long_test/2, longlong_test/2, ushort_test/2,
+ ulong_test/2, ulonglong_test/2, double_test/2, char_test/2,
+ wchar_test/2, octet_test/2, bool_test/2, struct_test/2,
+ struct2_test/2, seq1_test/2, seq2_test/2, seq3_test/2,
+ seq4_test/2, seq5_test/2, array1_test/2, array2_test/2,
+ enum_test/2, string1_test/2, wstring1_test/2, string2_test/2,
+ string3_test/2, string4_test/2, pid_test/2, port_test/2,
+ ref_test/2, term_test/2, typedef_test/2,
+ inline_sequence_test/2, term_sequence_test/2,
+ term_struct_test/2
+
+]).
+
+-include("m.hrl").
+-include("m_i.hrl").
+-include("oe_erl_c_test.hrl").
+
+%%b
+void_test(Node, Timeout) ->
+ Ret = m_i:void_test({olsson, Node}, Timeout),
+ Ret == void. % XXX Not documented
+%%e
+
+%%b
+long_test(Node, Timeout) ->
+ In = max_long(),
+ {Ret, Out} = m_i:long_test({olsson, Node}, Timeout, In),
+ (Ret == In) and (Out == In).
+%%e
+
+%%b
+longlong_test(Node, Timeout) ->
+ In = 65537,
+ {Ret, Out} = m_i:longlong_test({olsson, Node}, Timeout, In),
+ (Ret == In) and (Out == In).
+%%e
+
+%%b
+ushort_test(Node, Timeout) ->
+ In = max_ushort(),
+ {Ret, Out} = m_i:ushort_test({olsson, Node}, Timeout, In),
+ (Ret == In) and (Out == In).
+%%e
+
+%%b
+ulong_test(Node, Timeout) ->
+ In = max_ulong(),
+ {Ret, Out} = m_i:ulong_test({olsson, Node}, Timeout, In),
+ (Ret == In) and (Out == In).
+%%e
+
+%%b
+ulonglong_test(Node, Timeout) ->
+ In = 65537,
+ {Ret, Out} = m_i:ulonglong_test({olsson, Node}, Timeout, In),
+ (Ret == In) and (Out == In).
+%%e
+
+%%b
+double_test(Node, Timeout) ->
+ In = 37768.93,
+ {Ret, Out} = m_i:double_test({olsson, Node}, Timeout, In),
+ (Ret == In) and (Out == In).
+%%e
+
+%%b
+char_test(Node, Timeout) ->
+ In = 80,
+ {Ret, Out} = m_i:char_test({olsson, Node}, Timeout, In),
+ (Ret == In) and (Out == In).
+%%e
+
+%%b
+wchar_test(Node, Timeout) ->
+ In = 4097,
+ {Ret, Out} = m_i:wchar_test({olsson, Node}, Timeout, In),
+ (Ret == In) and (Out == In).
+%%e
+
+%%b
+octet_test(Node, Timeout) ->
+ In = 255,
+ {Ret, Out} = m_i:octet_test({olsson, Node}, Timeout, In),
+ (Ret == In) and (Out == In).
+%%e
+
+%%b
+bool_test(Node, Timeout) ->
+ In = false,
+ {Ret, Out} = m_i:bool_test({olsson, Node}, Timeout, In),
+ (Ret == In) and (Out == In).
+%%e
+
+%%b
+struct_test(Node, Timeout) ->
+ In = #m_b{l = max_long(), c = $a},
+ {Ret, Out} = m_i:struct_test({olsson, Node}, Timeout, In),
+ (Ret == In) and (Out == In).
+%%e
+
+%%b
+struct2_test(Node, Timeout) ->
+ In = #m_es{ f = banana, l = max_long()},
+ {Ret, Out} = m_i:struct2_test({olsson, Node}, Timeout, In),
+ (Ret == In) and (Out == In).
+%%e
+
+%%b
+seq1_test(Node, Timeout) ->
+ B1 = #m_b{l = max_long(), c = $a},
+ B2 = #m_b{l = min_long(), c = $b},
+ In = [B1, B2],
+ {Ret, Out} = m_i:seq1_test({olsson, Node}, Timeout, In),
+ (Ret == In) and (Out == In).
+%%e
+
+%%b
+seq2_test(Node, Timeout) ->
+ B = #m_b{l = max_long(), c = $a},
+ A = #m_a{l = min_long(), y = [B, B], d = 4711.31},
+ In = [A, A, A],
+ {Ret, Out} = m_i:seq2_test({olsson, Node}, Timeout, In),
+ (Ret == In) and (Out == In).
+%%e
+
+%%b
+seq3_test(Node, Timeout) ->
+ In = [max_long(), min_long(), max_long()],
+ {Ret, Out} = m_i:seq3_test({olsson, Node}, Timeout, In),
+ (Ret == In) and (Out == In).
+%%e
+
+%%b
+seq4_test(Node, Timeout) ->
+ In = [["hello", "all"], ["Erlang", "users", "!"]],
+ {Ret, Out} = m_i:seq4_test({olsson, Node}, Timeout, In),
+ (Ret == In) and (Out == In).
+%%e
+
+%%b
+seq5_test(Node, Timeout) ->
+ Arr3 = mk_array(3, max_long()),
+ In = [[Arr3, Arr3], [Arr3, Arr3, Arr3]],
+ {Ret, Out} = m_i:seq5_test({olsson, Node}, Timeout, In),
+ (Ret == In) and (Out == In).
+%%e
+
+%%b
+array1_test(Node, Timeout) ->
+ In = mk_array(500, min_long()),
+ {Ret, Out} = m_i:array1_test({olsson, Node}, Timeout, In),
+ (Ret == In) and (Out == In).
+%%e
+
+%%b
+array2_test(Node, Timeout) ->
+ In = mk_array(2, mk_array(3, min_long())),
+ {Ret, Out} = m_i:array2_test({olsson, Node}, Timeout, In),
+ (Ret == In) and (Out == In).
+%%e
+
+%%b
+enum_test(Node, Timeout) ->
+ In = banana,
+ {Ret, Out} = m_i:enum_test({olsson, Node}, Timeout, In),
+ (Ret == In) and (Out == In).
+%%e
+
+%%b
+string1_test(Node, Timeout) ->
+ In = "Developing Erlang applications is fun!",
+ {Ret, Out} = m_i:string1_test({olsson, Node}, Timeout, In),
+ (Ret == In) and (Out == In).
+%%e
+
+%%b
+wstring1_test(Node, Timeout) ->
+ In = [1047| "eveloping Erlang applications is fun!"],
+ {Ret, Out} = m_i:wstring1_test({olsson, Node}, Timeout, In),
+ (Ret == In) and (Out == In).
+%%e
+
+%%b
+string2_test(Node, Timeout) ->
+ In = ["Developing Erlang applications ", "is fun!"],
+ {Ret, Out} = m_i:string2_test({olsson, Node}, Timeout, In),
+ (Ret == In) and (Out == In).
+%%e
+
+%%b
+string3_test(Node, Timeout) ->
+ In = "Developing Erlang applications is fun!",
+ {Ret, Out} = m_i:string3_test({olsson, Node}, Timeout, In),
+ (Ret == In) and (Out == In).
+%%e
+
+%%b
+string4_test(Node, Timeout) ->
+
+ In = #m_strRec{
+ bb = true,
+ str4 = "Developing Erlang applications "
+ "is fun!",
+ str7 = mk_array(3, mk_array(2, max_long())),
+ str5 = [$a, $b, $c, $d, $e, $f],
+ str6 = "123456789012",
+ str8 = {$x, $y, $x},
+ str9 = "123456789012",
+ str10 = [$a, $b, $c, $d, $e, $f]
+ },
+ {Ret, Out} = m_i:string4_test({olsson, Node}, Timeout, In),
+ (Ret == In) and (Out == In).
+%%e
+
+%%b
+pid_test(Node, Timeout) ->
+ In = self(),
+ {Ret, Out} = m_i:pid_test({olsson, Node}, Timeout, In),
+ (Ret == In) and (Out == In).
+%%e
+
+%%b
+port_test(Node, Timeout) ->
+ In = get(port_test_port),
+ {Ret, Out} = m_i:port_test({olsson, Node}, Timeout, In),
+ (Ret == In) and (Out == In).
+%%e
+
+%%b
+ref_test(Node, Timeout) ->
+ In = make_ref(),
+ {Ret, Out} = m_i:ref_test({olsson, Node}, Timeout, In),
+ (Ret == In) and (Out == In).
+%%e
+
+%%b
+term_test(Node, Timeout) ->
+ In = {[a, b], 17, kalle},
+ {Ret, Out} = m_i:term_test({olsson, Node}, Timeout, In),
+ (Ret == In) and (Out == In).
+%%e
+
+%%b
+typedef_test(Node, Timeout) ->
+ In1 = {nisse, [1, 2], olsson},
+ In2 = get(port_test_port),
+ {Ret, Out1, Out2} = m_i:typedef_test({olsson, Node}, Timeout, In1, In2),
+ %% XXX Should check that Ret is an integer.
+ (Out1 == In1) and (Out2 == In2).
+%%e
+
+%%b
+inline_sequence_test(Node, Timeout) ->
+ In = #m_s{l = min_long(), sl = [max_long(), min_long()]},
+ {Ret, Out} = m_i:inline_sequence_test({olsson, Node}, Timeout, In),
+ (Ret == In) and (Out == In).
+%%e
+
+%%b
+term_sequence_test(Node, Timeout) ->
+ In = lists:duplicate(17, {nisse, [1, 2], {kalle, olsson}}),
+ {Ret, Out} = m_i:term_sequence_test({olsson, Node}, Timeout, In),
+ (Ret == In) and (Out == In).
+%%e
+
+%%b
+term_struct_test(Node, Timeout) ->
+ In = #m_et{e = {nisse, ["abcde"], {kalle, olsson}}, l = 4711},
+ {Ret, Out} = m_i:term_struct_test({olsson, Node}, Timeout, In),
+ (Ret == In) and (Out == In).
+%%e
+
+
+%% Locals
+
+mk_array(Es) ->
+ list_to_tuple(Es).
+
+mk_array(N, E) ->
+ mk_array(lists:duplicate(N, E)).
+
+%% max_short() ->
+%% power_of_two(15) - 1.
+max_long() ->
+ power_of_two(31) - 1.
+max_longlong() ->
+ power_of_two(63) - 1.
+max_ushort() ->
+ power_of_two(16) - 1.
+max_ulong() ->
+ power_of_two(32) - 1.
+max_ulonglong() ->
+ power_of_two(64) - 1.
+
+%% min_short() ->
+%% -power_of_two(15).
+min_long() ->
+ -power_of_two(31).
+%% min_longlong() ->
+%% -power_of_two(63).
+%% min_ushort() ->
+%% 0.
+%% min_ulong() ->
+%% 0.
+%% min_ulonglong() ->
+%% 0.
+
+power_of_two(N) ->
+ round(math:pow(2, N)).
+
diff --git a/lib/ic/test/erl_client_c_server_proto_SUITE.erl b/lib/ic/test/erl_client_c_server_proto_SUITE.erl
new file mode 100644
index 0000000000..d75feb621a
--- /dev/null
+++ b/lib/ic/test/erl_client_c_server_proto_SUITE.erl
@@ -0,0 +1,350 @@
+%%
+%% %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%
+%%
+%%
+
+%%----------------------------------------------------------------------
+%% Purpose : Test suite for erl-client/c-server
+%%----------------------------------------------------------------------
+
+
+-module(erl_client_c_server_proto_SUITE).
+-include("test_server.hrl").
+
+-export([init_per_testcase/2, fin_per_testcase/2, all/1, void_test/1,
+ long_test/1, longlong_test/1, ushort_test/1, ulong_test/1,
+ ulonglong_test/1, double_test/1, char_test/1, wchar_test/1,
+ octet_test/1, bool_test/1, struct_test/1, struct2_test/1,
+ seq1_test/1, seq2_test/1, seq3_test/1, seq4_test/1,
+ seq5_test/1, array1_test/1, array2_test/1, enum_test/1,
+ string1_test/1, string2_test/1, string3_test/1,
+ string4_test/1, pid_test/1, port_test/1, ref_test/1,
+ term_test/1, typedef_test/1, inline_sequence_test/1,
+ term_sequence_test/1, term_struct_test/1, wstring1_test/1]).
+
+-define(DEFAULT_TIMEOUT, 20000).
+-define(PORT_TIMEOUT, 15000).
+-define(CALL_TIMEOUT, 5000).
+
+-define(C_SERVER_NODE_NAME, idl_c_server_test).
+
+%% Add/remove code path and watchdog before/after each test case.
+%%
+init_per_testcase(_Case, Config) ->
+ DataDir = ?config(data_dir, Config),
+ code:add_patha(DataDir),
+
+ %% Since other test suites use the module m_i, we have
+ %% to make sure we are using the right m_i module.
+ code:purge(m_i),
+ code:load_file(m_i),
+
+ WatchDog = test_server:timetrap(?DEFAULT_TIMEOUT),
+ [{watchdog, WatchDog}| Config].
+
+fin_per_testcase(_Case, Config) ->
+ DataDir = ?config(data_dir, Config),
+ code:del_path(DataDir),
+ WatchDog = ?config(watchdog, Config),
+ test_server:timetrap_cancel(WatchDog).
+
+all(doc) ->
+ "Test of IC with an Erlang client and a C server. "
+ "The communication is via Erlang distribution.";
+all(suite) ->
+ [void_test, long_test, longlong_test, ushort_test,
+ ulong_test, ulonglong_test, double_test,
+ char_test, wchar_test, octet_test, bool_test, struct_test,
+ struct2_test, seq1_test, seq2_test, seq3_test, seq4_test,
+ seq5_test, array1_test, array2_test, enum_test, string1_test,
+ string2_test, string3_test, string4_test, pid_test, port_test,
+ ref_test, term_test, typedef_test, inline_sequence_test,
+ term_sequence_test, term_struct_test, wstring1_test].
+
+
+array1_test(doc) -> "";
+array1_test(suite) -> [];
+array1_test(Config) ->
+ do_test(array1_test, Config).
+
+array2_test(doc) -> "";
+array2_test(suite) -> [];
+array2_test(Config) ->
+ do_test(array2_test, Config).
+
+bool_test(doc) -> "";
+bool_test(suite) -> [];
+bool_test(Config) ->
+ do_test(bool_test, Config).
+
+char_test(doc) -> "";
+char_test(suite) -> [];
+char_test(Config) ->
+ do_test(char_test, Config).
+
+double_test(doc) -> "";
+double_test(suite) -> [];
+double_test(Config) ->
+ do_test(double_test, Config).
+
+enum_test(doc) -> "";
+enum_test(suite) -> [];
+enum_test(Config) ->
+ do_test(enum_test, Config).
+
+inline_sequence_test(doc) -> "";
+inline_sequence_test(suite) -> [];
+inline_sequence_test(Config) ->
+ do_test(inline_sequence_test, Config).
+
+longlong_test(doc) -> "";
+longlong_test(suite) -> [];
+longlong_test(Config) ->
+ do_test(longlong_test, Config).
+
+long_test(doc) -> "";
+long_test(suite) -> [];
+long_test(Config) ->
+ do_test(long_test, Config).
+
+octet_test(doc) -> "";
+octet_test(suite) -> [];
+octet_test(Config) ->
+ do_test(octet_test, Config).
+
+pid_test(doc) -> "";
+pid_test(suite) -> [];
+pid_test(Config) ->
+ do_test(pid_test, Config).
+
+port_test(doc) -> "";
+port_test(suite) -> [];
+port_test(Config) ->
+ do_test(port_test, Config).
+
+ref_test(doc) -> "";
+ref_test(suite) -> [];
+ref_test(Config) ->
+ do_test(ref_test, Config).
+
+seq1_test(doc) -> "";
+seq1_test(suite) -> [];
+seq1_test(Config) ->
+ do_test(seq1_test, Config).
+
+seq2_test(doc) -> "";
+seq2_test(suite) -> [];
+seq2_test(Config) ->
+ do_test(seq2_test, Config).
+
+seq3_test(doc) -> "";
+seq3_test(suite) -> [];
+seq3_test(Config) ->
+ do_test(seq3_test, Config).
+
+seq4_test(doc) -> "";
+seq4_test(suite) -> [];
+seq4_test(Config) ->
+ do_test(seq4_test, Config).
+
+seq5_test(doc) -> "";
+seq5_test(suite) -> [];
+seq5_test(Config) ->
+ do_test(seq5_test, Config).
+
+string1_test(doc) -> "";
+string1_test(suite) -> [];
+string1_test(Config) ->
+ do_test(string1_test, Config).
+
+string2_test(doc) -> "";
+string2_test(suite) -> [];
+string2_test(Config) ->
+ do_test(string2_test, Config).
+
+string3_test(doc) -> "";
+string3_test(suite) -> [];
+string3_test(Config) ->
+ do_test(string3_test, Config).
+
+string4_test(doc) -> "";
+string4_test(suite) -> [];
+string4_test(Config) ->
+ do_test(string4_test, Config).
+
+struct2_test(doc) -> "";
+struct2_test(suite) -> [];
+struct2_test(Config) ->
+ do_test(struct2_test, Config).
+
+struct_test(doc) -> "";
+struct_test(suite) -> [];
+struct_test(Config) ->
+ do_test(struct_test, Config).
+
+term_sequence_test(doc) -> "";
+term_sequence_test(suite) -> [];
+term_sequence_test(Config) ->
+ do_test(term_sequence_test, Config).
+
+term_struct_test(doc) -> "";
+term_struct_test(suite) -> [];
+term_struct_test(Config) ->
+ do_test(term_struct_test, Config).
+
+term_test(doc) -> "";
+term_test(suite) -> [];
+term_test(Config) ->
+ do_test(term_test, Config).
+
+typedef_test(doc) -> "";
+typedef_test(suite) -> [];
+typedef_test(Config) ->
+ do_test(typedef_test, Config).
+
+ulonglong_test(doc) -> "";
+ulonglong_test(suite) -> [];
+ulonglong_test(Config) ->
+ do_test(ulonglong_test, Config).
+
+ulong_test(doc) -> "";
+ulong_test(suite) -> [];
+ulong_test(Config) ->
+ do_test(ulong_test, Config).
+
+ushort_test(doc) -> "";
+ushort_test(suite) -> [];
+ushort_test(Config) ->
+ do_test(ushort_test, Config).
+
+void_test(doc) -> "";
+void_test(suite) -> [];
+void_test(Config) ->
+ do_test(void_test, Config).
+
+wchar_test(doc) -> "";
+wchar_test(suite) -> [];
+wchar_test(Config) ->
+ do_test(wchar_test, Config).
+
+wstring1_test(doc) -> "";
+wstring1_test(suite) -> [];
+wstring1_test(Config) ->
+ do_test(wstring1_test, Config).
+
+
+do_test(Case, Config) ->
+ %% Trap exits
+ process_flag(trap_exit, true),
+ Node = atom_to_list(node()),
+ [_NodeName, HostName] = string:tokens(Node, "@"),
+ DataDir = ?config(data_dir, Config),
+ %% io:format("~p: data directory: ~p~n", [?MODULE, DataDir]),
+ Cookie = atom_to_list(erlang:get_cookie()),
+ ServerNodeName = atom_to_list(?C_SERVER_NODE_NAME),
+ %% Start C-server node as a port program. We wait for the node
+ %% to connect to us.
+ Cmd = filename:join([DataDir, "c_server"]) ++
+ " -this-node-name " ++ ServerNodeName ++
+ " -peer-node " ++ Node ++
+ " -cookie " ++ Cookie,
+ Port = open_port({spawn, Cmd}, [exit_status, eof, stderr_to_stdout]),
+ ServerNode = list_to_atom(ServerNodeName ++ "@" ++ HostName),
+ Res = case wait_for_hidden_node(ServerNode) of
+ ok ->
+ %% Need a port for port_test and typedef_test
+ put(port_test_port, Port),
+ R = (catch erl_client:Case(ServerNode, ?CALL_TIMEOUT)),
+ case wait_for_completion(Port) of
+ {error, timeout} ->
+ kill_off_node(ServerNode);
+ _ ->
+ ok
+ end,
+ R;
+ {error, timeout} ->
+ case wait_for_completion(Port) of
+ {error, timeout} ->
+ kill_off_node(ServerNode);
+ _ ->
+ ok
+ end,
+ {error, timeout}
+ end,
+ process_flag(trap_exit, false),
+ true = Res.
+
+
+%% Wait for eof *and* exit status, but return if exit status indicates
+%% an error, or we have been waiting more than PORT_TIMEOUT seconds.
+%%
+wait_for_completion(Port) ->
+ wait_for_completion(Port, 0).
+
+wait_for_completion(Port, N) when N < 2 ->
+ receive
+ {Port, {data, Bytes}} ->
+ %% Relay output
+ io:format("~s", [Bytes]),
+ wait_for_completion(Port, N);
+ {Port, {exit_status, 0}} ->
+ wait_for_completion(Port, N + 1);
+ {Port, {exit_status, Status}} ->
+ {error, Status};
+ {Port, eof} ->
+ wait_for_completion(Port, N + 1);
+ {'EXIT', Port, Reason} ->
+ io:format("Port exited with reason: ~w~n", [Reason]),
+ wait_for_completion(Port, N);
+ {'EXIT', From, Reason} ->
+ io:format("Got unexpected exit: ~p~n", [{'EXIT', From, Reason}]),
+ wait_for_completion(Port, N)
+ after ?PORT_TIMEOUT ->
+ {error, timeout}
+ end;
+wait_for_completion(_, _) ->
+ ok.
+
+wait_for_hidden_node(Node) ->
+ Times = ?DEFAULT_TIMEOUT div 100,
+ wait_for_hidden_node(Node, Times, 100).
+
+wait_for_hidden_node(Node, Times, WaitTime) when Times > 0 ->
+ io:format("Waiting for hidden node: ~p~n", [Node]),
+ case lists:member(Node, erlang:nodes(hidden)) of
+ true ->
+ ok;
+ false ->
+ delay(WaitTime),
+ wait_for_hidden_node(Node, Times - 1, WaitTime)
+ end;
+wait_for_hidden_node(_Node, _, _WaitTime) ->
+ {error, timeout}.
+
+kill_off_node(Node) ->
+ catch rpc:cast(Node, erlang, halt, [1]).
+
+delay(Time) ->
+ receive
+ after Time ->
+ ok
+ end.
+
+
+
+
diff --git a/lib/ic/test/erl_client_c_server_proto_SUITE_data/Makefile.src b/lib/ic/test/erl_client_c_server_proto_SUITE_data/Makefile.src
new file mode 100644
index 0000000000..b7e7ee77d0
--- /dev/null
+++ b/lib/ic/test/erl_client_c_server_proto_SUITE_data/Makefile.src
@@ -0,0 +1,150 @@
+#
+# %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%
+#
+#
+# Makefile.src for erl_client_c_server test
+# Note: This file *must* work for both Unix and Windows
+#
+# We use both `rm' (Unix) and `del' (Windows) for removing files, but
+# with a `-' in front so that the error in not finding `rm' (`del') on
+# Windows (Unix) is ignored.
+#
+# VxWorks? XXX
+#
+
+.SUFFIXES:
+.SUFFIXES: .c .h .erl .idl @obj@ .@EMULATOR@
+
+
+# Variables from ts:
+#
+
+ERL_INCLUDE = @erl_include@
+
+IC_INCLUDE_PATH = @ic_include_path@
+IC_LIB = @ic_libpath@@DS@@ic_lib@
+
+ERL_INTERFACE_INCLUDE = @erl_interface_include@
+ERL_INTERFACE_LIB = @erl_interface_libpath@@DS@@erl_interface_lib@
+ERL_INTERFACE_EILIB = @erl_interface_libpath@@DS@@erl_interface_eilib@
+ERL_INTERFACE_THREADLIB = @erl_interface_threadlib@
+ERL_INTERFACE_SOCK_LIBS = @erl_interface_sock_libs@
+
+CC = @CC@
+## XXX Should set warning flag with a DEBUG_FLAG
+CFLAGS = @CFLAGS@ @DEFS@ -I$(ERL_INCLUDE) \
+ -I$(IC_INCLUDE_PATH) -I$(ERL_INTERFACE_INCLUDE)
+
+LD = @LD@
+LDFLAGS = @CROSSLDFLAGS@
+LIBS = $(IC_LIB) $(ERL_INTERFACE_LIB) $(ERL_INTERFACE_EILIB) \
+ $(ERL_INTERFACE_THREADLIB) @LIBS@ $(ERL_INTERFACE_SOCK_LIBS)
+ERLC = erlc
+
+# Generated C header files
+GEN_H_FILES = \
+ m__s.h \
+ m_i__s.h \
+ oe_erl_c_test__s.h
+
+# Generated C files
+GEN_C_FILES = \
+ m__s.c \
+ m_i__s.c \
+ oe_code_m_a.c \
+ oe_code_m_arr1.c \
+ oe_code_m_arr2.c \
+ oe_code_m_arr3.c \
+ oe_code_m_aseq.c \
+ oe_code_m_b.c \
+ oe_code_m_bseq.c \
+ oe_code_m_dd.c \
+ oe_code_m_dyn.c \
+ oe_code_m_dyn_sl.c \
+ oe_code_m_es.c \
+ oe_code_m_et.c \
+ oe_code_m_etseq.c \
+ oe_code_m_fruit.c \
+ oe_code_m_lseq.c \
+ oe_code_m_s.c \
+ oe_code_m_s_sl.c \
+ oe_code_m_sarr3.c \
+ oe_code_m_simple.c \
+ oe_code_m_ssarr3.c \
+ oe_code_m_sseq.c \
+ oe_code_m_ssstr3.c \
+ oe_code_m_sstr3.c \
+ oe_code_m_str1.c \
+ oe_code_m_str3.c \
+ oe_code_m_strRec.c \
+ oe_code_m_strRec_str5.c \
+ oe_code_m_strRec_str7.c \
+ oe_erl_c_test__s.c
+
+GEN_HRL_FILES = \
+ m.hrl \
+ m_i.hrl \
+ oe_erl_c_test.hrl
+
+GEN_ERL_FILES = \
+ m.erl \
+ m_arr2.erl \
+ m_arr3.erl \
+ m_i.erl \
+ m_str3.erl \
+ oe_erl_c_test.erl
+
+C_FILES = $(GEN_C_FILES) c_server.c callbacks.c
+
+OBJS = $(C_FILES:.c=@obj@)
+
+PGMS = c_server@exe@
+
+ERL_FILES = $(GEN_ERL_FILES) erl_client.erl
+
+EBINS = $(ERL_FILES:.erl=.@EMULATOR@)
+
+
+all: $(PGMS) $(EBINS)
+
+clean:
+ -rm -f $(OBJS) $(GEN_C_FILES) $(GEN_H_FILES) $(PGMS) \
+ $(EBINS) $(GEN_ERL_FILES) $(GEN_HRL_FILES)
+ -del /F /Q $(OBJS) $(GEN_C_FILES) $(GEN_H_FILES) $(PGMS) \
+ $(EBINS) $(GEN_ERL_FILES) $(GEN_HRL_FILES)
+
+$(PGMS): $(OBJS)
+ $(LD) $(LDFLAGS) -o $@ $(OBJS) $(LIBS)
+
+$(GEN_C_FILES) $(GEN_H_FILES): erl_c_test.idl
+ $(ERLC) -I $(IC_INCLUDE_PATH) "+{be,c_server}" \
+ "+{scoped_op_calls,true}" erl_c_test.idl
+
+# If we have scoped operation calls for C, we must have that for
+# Erlang as well, if we use the m_i.erl file for calling the server.
+
+$(GEN_ERL_FILES) $(GEN_HRL_FILES): erl_c_test.idl
+ $(ERLC) -I $(IC_INCLUDE_PATH) "+{be,erl_genserv}" \
+ "+{scoped_op_calls,true}" "+{timeout,true}" erl_c_test.idl
+
+.c@obj@:
+ $(CC) -c -o $*@obj@ $(CFLAGS) $<
+
+.erl.@EMULATOR@:
+ $(ERLC) -W -I $(IC_INCLUDE_PATH) $<
+
diff --git a/lib/ic/test/erl_client_c_server_proto_SUITE_data/c_server.c b/lib/ic/test/erl_client_c_server_proto_SUITE_data/c_server.c
new file mode 100644
index 0000000000..329f444112
--- /dev/null
+++ b/lib/ic/test/erl_client_c_server_proto_SUITE_data/c_server.c
@@ -0,0 +1,299 @@
+/*
+ * %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%
+ *
+ */
+/* C-server for test of IC.
+ *
+ * The C-node implemented here connects to its peer node, waits for
+ * one message, evaluates the message, returns an result message, and
+ * terminates.
+ *
+ * TODO:
+ *
+ * 1. XXX #includes for VxWorks, Windows
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#ifndef __WIN32__
+# include <unistd.h>
+#endif
+
+#include <string.h>
+
+#ifdef __WIN32__
+# include <time.h>
+# include <sys/timeb.h>
+#elif defined VXWORKS
+# include <time.h>
+# include <sys/times.h>
+#else
+# include <sys/time.h>
+#endif
+
+#include <ctype.h>
+
+#ifdef __WIN32__
+# include <winsock2.h>
+# include <windows.h>
+#else
+# include <sys/types.h>
+# include <sys/socket.h>
+# include <netinet/in.h>
+# include <arpa/inet.h>
+# include <netdb.h>
+#endif
+
+#include "ic.h"
+#include "ei.h"
+#include "erl_interface.h"
+#include "eicode.h"
+#include "m_i__s.h"
+#include "m__s.h"
+
+#ifdef __WIN32__
+typedef struct {
+ long tv_sec;
+ long tv_usec;
+} MyTimeval;
+#else
+typedef struct timeval MyTimeval;
+#endif
+static void my_gettimeofday(MyTimeval *tv);
+static void showtime(MyTimeval *start, MyTimeval *stop);
+static void usage(void);
+static void done(int r);
+
+#define HOSTNAMESZ 256
+#define NODENAMESZ 512
+#define INBUFSZ 10
+#define OUTBUFSZ 0
+#define MAXTRIES 5
+
+static char *progname;
+
+/* main */
+#ifdef VXWORKS
+int c_server(int argc, char **argv)
+#else
+int main(int argc, char **argv)
+#endif
+{
+ struct hostent *hp;
+ MyTimeval start, stop;
+ int i, fd, ires, tries;
+ CORBA_Environment *env;
+ char *this_node_name = NULL;
+ char *peer_node = NULL;
+ char *cookie = NULL;
+ char host[HOSTNAMESZ + 1];
+ char this_node[NODENAMESZ + 1];
+ erlang_msg msg;
+ int status, loop;
+
+#ifdef __WIN32__
+ WORD wVersionRequested;
+ WSADATA wsaData;
+
+ wVersionRequested = MAKEWORD(2, 0);
+
+ if (WSAStartup(wVersionRequested, &wsaData) != 0) {
+ fprintf(stderr, "Could not load winsock2 v2.0 compatible DLL");
+ exit(1);
+ }
+#endif
+
+ progname = argv[0];
+ host[HOSTNAMESZ] = '\0';
+ if (gethostname(host, HOSTNAMESZ) < 0) {
+ fprintf(stderr, "Can't find own hostname\n");
+ done(1);
+ }
+ if ((hp = gethostbyname(host)) == 0) {
+ fprintf(stderr, "Can't get ip address for host %s\n", host);
+ done(1);
+ }
+ for (i = 1; i < argc; i++) {
+ if (strcmp(argv[i], "-help") == 0) {
+ usage();
+ done(0);
+ } else if (strcmp(argv[i], "-this-node-name") == 0) {
+ i++;
+ this_node_name = argv[i];
+ } else if (strcmp(argv[i], "-peer-node") == 0) {
+ i++;
+ peer_node = argv[i];
+ } else if (strcmp(argv[i], "-cookie") == 0) {
+ i++;
+ cookie = argv[i];
+ } else {
+ fprintf(stderr, "Error : invalid argument \"%s\"\n", argv[i]);
+ usage();
+ done(1);
+ }
+ }
+
+ if (this_node_name == NULL || peer_node == NULL || cookie == NULL) {
+ fprintf(stderr, "Error: missing option\n");
+ usage();
+ done(1);
+ }
+
+ /* Behead hostname at first dot */
+ for (i=0; host[i] != '\0'; i++) {
+ if (host[i] == '.') { host[i] = '\0'; break; }
+ }
+ sprintf(this_node, "%s@%s", this_node_name, host);
+
+ fprintf(stderr, "c_server: this node: \"%s\"\n", this_node);
+ fprintf(stderr, "c_server: peer node: \"%s\"\n", peer_node);
+
+ /* initialize erl_interface */
+ erl_init(NULL, 0);
+
+ for (tries = 0; tries < MAXTRIES; tries++) {
+ /* connect to peer node */
+ ires = erl_connect_xinit(host, this_node_name, this_node,
+ (struct in_addr *)*hp->h_addr_list,
+ cookie, 0);
+ fprintf(stderr, "c_server: erl_connect_xinit(): %d\n", ires);
+
+ fd = erl_connect(peer_node);
+ fprintf(stderr, "c_server: erl_connect(): %d\n", fd);
+ if (fd >= 0)
+ break;
+ fprintf(stderr, "c_server: cannot connect, retrying\n");
+ }
+ if (fd < 0) {
+ fprintf(stderr, "c_server: cannot connect, exiting\n");
+ done(1);
+ }
+ env = CORBA_Environment_alloc(INBUFSZ, OUTBUFSZ);
+ env->_fd = fd;
+
+ status = 1;
+ loop = 1;
+ my_gettimeofday(&start);
+ while (status >= 0 && loop > 0) {
+ status = ei_receive_encoded(env->_fd, &env->_inbuf, &env->_inbufsz,
+ &msg, &env->_iin);
+ switch(status) {
+ case ERL_SEND:
+ case ERL_REG_SEND:
+ /* get result */
+ m_i__switch(NULL, env);
+ switch(env->_major) {
+ case CORBA_NO_EXCEPTION:
+ break;
+ case CORBA_SYSTEM_EXCEPTION:
+ fprintf(stderr, "Request failure, reason : %s\n",
+ (char *) CORBA_exception_value(env));
+ CORBA_exception_free(env);
+ break;
+ default: /* Should not happen */
+ CORBA_exception_free(env);
+ break;
+ }
+ /* send back result data */
+ if (env->_iout > 0)
+ ei_send_encoded(env->_fd, &env->_caller, env->_outbuf,
+ env->_iout);
+ loop = 0;
+ break;
+ case ERL_TICK:
+ break;
+ default:
+ if (status < 0) {
+ fprintf(stderr, "Status negative: %d\n", status);
+ loop = 0;
+ }
+ break;
+ }
+ }
+ my_gettimeofday(&stop);
+ showtime(&start, &stop);
+
+ erl_close_connection(fd);
+
+ CORBA_free(env->_inbuf);
+ CORBA_free(env->_outbuf);
+ CORBA_free(env);
+ if (status < 0)
+ done(-status);
+ else
+ done(0);
+}
+
+static void usage()
+{
+ fprintf(stderr, "Usage: %s [-help] -this-node-name <name> "
+ "-peer-node <nodename> -cookie <cookie>\n", progname);
+ fprintf(stderr, "Example:\n %s -this-node-name kalle "
+ "-peer-node olle@home -cookie oa678er\n", progname);
+}
+
+static void done(int r)
+{
+#ifdef __WIN32__
+ WSACleanup();
+#endif
+ exit(r);
+}
+
+static void showtime(MyTimeval *start, MyTimeval *stop)
+{
+ MyTimeval elapsed;
+
+ elapsed.tv_sec = stop->tv_sec - start->tv_sec;
+ elapsed.tv_usec = stop->tv_usec - start->tv_usec;
+ while (elapsed.tv_usec < 0) {
+ elapsed.tv_sec -= 1;
+ elapsed.tv_usec += 1000000;
+ }
+ fprintf(stderr,"%ld.%06ld seconds\n",elapsed.tv_sec, elapsed.tv_usec);
+}
+
+
+
+static void my_gettimeofday(MyTimeval *tv)
+#ifdef __WIN32__
+#define EPOCH_JULIAN_DIFF 11644473600i64
+{
+ SYSTEMTIME t;
+ FILETIME ft;
+ LONGLONG lft;
+
+ GetSystemTime(&t);
+ SystemTimeToFileTime(&t, &ft);
+ memcpy(&lft, &ft, sizeof(lft));
+ tv->tv_usec = (long) ((lft / 10i64) % 1000000i64);
+ tv->tv_sec = (long) ((lft / 10000000i64) - EPOCH_JULIAN_DIFF);
+}
+#elif defined VXWORKS
+{
+ int rate = sysClkRateGet(); /* Ticks per second */
+ unsigned long ctick = tickGet();
+ tv->tv_sec = ctick / rate; /* secs since reboot */
+ tv->tv_usec = ((ctick - (tv->tv_sec * rate))*1000000)/rate;
+}
+#else
+{
+ gettimeofday(tv, NULL);
+}
+#endif
diff --git a/lib/ic/test/erl_client_c_server_proto_SUITE_data/callbacks.c b/lib/ic/test/erl_client_c_server_proto_SUITE_data/callbacks.c
new file mode 100644
index 0000000000..b029bcc63c
--- /dev/null
+++ b/lib/ic/test/erl_client_c_server_proto_SUITE_data/callbacks.c
@@ -0,0 +1,610 @@
+/*
+ * %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 <stdio.h>
+#include <stdlib.h>
+#ifndef __WIN32__
+# include <unistd.h>
+#endif
+#include <string.h>
+#include <ctype.h>
+#include <ic.h>
+#include <erl_interface.h>
+#include <ei.h>
+#include "m_i__s.h"
+
+
+
+/* OK */
+
+void my_void_test(CORBA_Object oe_obj,
+ CORBA_Environment *oe_env)
+{
+ /* printf("void test !\n"); */
+}
+
+m_i_void_test__rs* m_i_void_test__cb(CORBA_Object oe_obj,
+ CORBA_Environment *oe_env)
+{
+ return (m_i_void_test__rs*) (my_void_test);
+}
+
+
+
+/* OK */
+
+void my_long_test(CORBA_Object oe_obj,
+ long* a,
+ long* b,
+ long* c,
+ CORBA_Environment *oe_env)
+{
+ /* printf("long test !\n"); */
+}
+
+
+m_i_long_test__rs* m_i_long_test__cb(CORBA_Object oe_obj,
+ long* a,
+ long* b,
+ long* c,
+ CORBA_Environment *oe_env)
+{
+ *a = *b;
+ *c = *b;
+ return (m_i_long_test__rs*) (my_long_test);
+}
+
+/* OK */
+
+void my_longlong_test(CORBA_Object oe_obj,
+ CORBA_long_long* a,
+ CORBA_long_long* b,
+ CORBA_long_long* c,
+ CORBA_Environment *oe_env)
+{
+ /* printf("long test !\n"); */
+}
+
+m_i_longlong_test__rs* m_i_longlong_test__cb(CORBA_Object oe_obj,
+ CORBA_long_long* a,
+ CORBA_long_long* b,
+ CORBA_long_long* c,
+ CORBA_Environment *oe_env)
+{
+ *a = *b;
+ *c = *b;
+ return (m_i_longlong_test__rs*) (my_longlong_test);
+}
+
+/* OK */
+void my_ulong_test(CORBA_Object oe_obj,
+ unsigned long* a,
+ unsigned long* b,
+ unsigned long* c,
+ CORBA_Environment *oe_env)
+{
+ /* printf("ulong test !\n"); */
+}
+
+m_i_ulong_test__rs* m_i_ulong_test__cb(CORBA_Object oe_obj,
+ unsigned long* a,
+ unsigned long* b,
+ unsigned long* c,
+ CORBA_Environment *oe_env)
+{
+ *a = *b;
+ *c = *b;
+ return (m_i_ulong_test__rs*) (my_ulong_test);
+}
+
+/* OK */
+void my_ulonglong_test(CORBA_Object oe_obj,
+ CORBA_unsigned_long_long* a,
+ CORBA_unsigned_long_long* b,
+ CORBA_unsigned_long_long* c,
+ CORBA_Environment *oe_env)
+{
+ /* printf("ulong test !\n"); */
+}
+
+m_i_ulonglong_test__rs* m_i_ulonglong_test__cb(CORBA_Object oe_obj,
+ CORBA_unsigned_long_long* a,
+ CORBA_unsigned_long_long* b,
+ CORBA_unsigned_long_long* c,
+ CORBA_Environment *oe_env)
+{
+ *a = *b;
+ *c = *b;
+ return (m_i_ulonglong_test__rs*) (my_ulonglong_test);
+}
+
+m_i_ushort_test__rs* m_i_ushort_test__cb(CORBA_Object oe_obj,
+ unsigned short* a,
+ unsigned short* b,
+ unsigned short* c,
+ CORBA_Environment *oe_env)
+{
+ *a = *b;
+ *c = *b;
+ return (m_i_ushort_test__rs*) NULL;
+}
+
+
+/* OK */
+void my_double_test(CORBA_Object oe_obj,
+ double* a,
+ double* b,
+ double* c,
+ CORBA_Environment *oe_env)
+{
+ /* printf("double test !\n"); */
+}
+
+m_i_double_test__rs* m_i_double_test__cb(CORBA_Object oe_obj,
+ double* a,
+ double* b,
+ double* c,
+ CORBA_Environment *oe_env)
+{
+ *a = *b;
+ *c = *b;
+ return (m_i_double_test__rs*) (my_double_test);
+}
+
+/* OK */
+m_i_char_test__rs* m_i_char_test__cb(CORBA_Object oe_obj,
+ char* a,
+ char* b,
+ char* c,
+ CORBA_Environment *oe_env)
+{
+ m_i_char_test__rs* rs = NULL;
+
+ *a = *b;
+ *c = *b;
+ return rs;
+}
+
+
+/* OK */
+m_i_wchar_test__rs* m_i_wchar_test__cb(CORBA_Object oe_obj,
+ CORBA_wchar* a,
+ CORBA_wchar* b,
+ CORBA_wchar* c,
+ CORBA_Environment *oe_env)
+{
+ m_i_wchar_test__rs* rs = NULL;
+
+ *a = *b;
+ *c = *b;
+ return rs;
+}
+
+/* OK */
+m_i_octet_test__rs* m_i_octet_test__cb(CORBA_Object oe_obj,
+ char* a,
+ char* b,
+ char* c,
+ CORBA_Environment *oe_env)
+{
+ m_i_octet_test__rs* rs = NULL;
+
+ *a = *b;
+ *c = *b;
+ return rs;
+}
+
+/* OK */
+m_i_bool_test__rs* m_i_bool_test__cb(CORBA_Object oe_obj,
+ CORBA_boolean* a,
+ CORBA_boolean* b,
+ CORBA_boolean* c,
+ CORBA_Environment *oe_env)
+{
+ m_i_bool_test__rs* rs = NULL;
+
+ *a = *b;
+ *c = *b;
+ return rs;
+}
+
+/* OK */
+void my_struct_test(CORBA_Object oe_obj,
+ m_b* a,
+ m_b* b,
+ m_b* c,
+ CORBA_Environment *oe_env)
+{
+ /* printf("struct test !\n"); */
+}
+
+m_i_struct_test__rs* m_i_struct_test__cb(CORBA_Object oe_obj,
+ m_b* a,
+ m_b* b,
+ m_b* c,
+ CORBA_Environment *oe_env)
+{
+ *a = *b;
+ *c = *b;
+ return (m_i_struct_test__rs*) (my_struct_test);
+}
+
+/* OK */
+m_i_struct2_test__rs* m_i_struct2_test__cb(CORBA_Object oe_obj,
+ m_es* a,
+ m_es* b,
+ m_es* c,
+ CORBA_Environment *oe_env)
+{
+ m_i_struct2_test__rs* rs = NULL;
+
+ *a = *b;
+ *c = *b;
+ return rs;
+}
+
+/* OK */
+/* XXX Commented out
+m_i_struct3_test__rs* m_i_struct3_test__cb(CORBA_Object oe_obj,
+ m_simple* a,
+ m_simple* b,
+ m_simple* c,
+ CORBA_Environment *oe_env)
+{
+ m_i_struct3_test__rs* rs = NULL;
+ *a = *b;
+ *c = *b;
+ return rs;
+}
+*/
+
+/* OK */
+m_i_seq1_test__rs* m_i_seq1_test__cb(CORBA_Object oe_obj,
+ m_bseq** a,
+ m_bseq* b,
+ m_bseq** c,
+ CORBA_Environment *oe_env)
+{
+ m_i_seq1_test__rs* rs = NULL;
+
+ *a = b;
+ *c = b;
+ return rs;
+}
+
+
+/* OK */
+m_i_seq2_test__rs* m_i_seq2_test__cb(CORBA_Object oe_obj,
+ m_aseq** a,
+ m_aseq* b,
+ m_aseq** c,
+ CORBA_Environment *oe_env)
+{
+ m_i_seq2_test__rs* rs = NULL;
+
+ *a = b;
+ *c = b;
+ return rs;
+}
+
+/* OK */
+m_i_seq3_test__rs* m_i_seq3_test__cb(CORBA_Object oe_obj,
+ m_lseq** a,
+ m_lseq* b,
+ m_lseq** c,
+ CORBA_Environment *oe_env)
+{
+ m_i_seq3_test__rs* rs = NULL;
+
+ *a = b;
+ *c = b;
+ return rs;
+}
+
+/* OK */
+m_i_seq4_test__rs* m_i_seq4_test__cb(CORBA_Object oe_obj,
+ m_ssstr3** a,
+ m_ssstr3* b,
+ m_ssstr3** c,
+ CORBA_Environment *oe_env)
+{
+ m_i_seq4_test__rs* rs = NULL;
+
+ *a = b;
+ *c = b;
+ return rs;
+}
+
+/* OK */
+m_i_seq5_test__rs* m_i_seq5_test__cb(CORBA_Object oe_obj,
+ m_ssarr3** a,
+ m_ssarr3* b,
+ m_ssarr3** c,
+ CORBA_Environment *oe_env)
+{
+ m_i_seq5_test__rs* rs = NULL;
+
+ *a = b;
+ *c = b;
+ return rs;
+}
+
+/* OK */
+m_i_array1_test__rs* m_i_array1_test__cb(CORBA_Object oe_obj,
+ m_arr1 a,
+ m_arr1 b,
+ m_arr1 c,
+ CORBA_Environment *oe_env)
+{
+ int i;
+ m_i_array1_test__rs* rs = NULL;
+
+ for (i = 0; i < 500; i++) {
+ a[i] = b[i];
+ c[i] = b[i];
+ }
+ return rs;
+}
+
+/* OK */
+m_i_array2_test__rs* m_i_array2_test__cb(CORBA_Object oe_obj,
+ m_dd a,
+ m_dd b,
+ m_dd c,
+ CORBA_Environment *oe_env)
+{
+ int i,j;
+ m_i_array2_test__rs* rs = NULL;
+
+ for (i = 0; i < 2; i++)
+ for (j = 0; j < 3; j++) {
+ a[i][j] = b[i][j];
+ c[i][j] = b[i][j];
+ }
+ return rs;
+}
+
+
+/* OK */
+m_i_enum_test__rs* m_i_enum_test__cb(CORBA_Object oe_obj,
+ m_fruit* a,
+ m_fruit* b,
+ m_fruit* c,
+ CORBA_Environment *oe_env)
+{
+ m_i_enum_test__rs* rs = NULL;
+
+ *a = *b;
+ *c = *b;
+ return rs;
+}
+
+/* OK */
+m_i_string1_test__rs* m_i_string1_test__cb(CORBA_Object oe_obj,
+ char ** a,
+ char * b,
+ char ** c,
+ CORBA_Environment *oe_env)
+{
+ m_i_string1_test__rs* rs = NULL;
+
+ /*printf("\nString in ------> %s\n\n",b);*/
+ *a = b;
+ *c = b;
+ return rs;
+}
+
+/* OK */
+m_i_string2_test__rs* m_i_string2_test__cb(CORBA_Object oe_obj,
+ m_sseq** a,
+ m_sseq* b,
+ m_sseq** c,
+ CORBA_Environment *oe_env)
+{
+ m_i_string2_test__rs* rs = NULL;
+
+ *a = b;
+ *c = b;
+ return rs;
+}
+
+/* OK */
+m_i_string3_test__rs* m_i_string3_test__cb(CORBA_Object oe_obj,
+ char ** a,
+ char * b,
+ char ** c,
+ CORBA_Environment *oe_env)
+{
+ m_i_string3_test__rs* rs = NULL;
+
+ *a = b;
+ *c = b;
+ return rs;
+}
+
+m_i_string4_test__rs* m_i_string4_test__cb(CORBA_Object oe_obj,
+ m_strRec** a,
+ m_strRec* b,
+ m_strRec** c,
+ CORBA_Environment *oe_env)
+{
+ *a = b;
+ *c = b;
+
+ return (m_i_string4_test__rs*) NULL;
+}
+
+/* OK */
+m_i_wstring1_test__rs* m_i_wstring1_test__cb(CORBA_Object oe_obj,
+ CORBA_wchar ** a,
+ CORBA_wchar * b,
+ CORBA_wchar ** c,
+ CORBA_Environment *oe_env)
+{
+ int tmp;
+ m_i_wstring1_test__rs* rs = NULL;
+
+ /*printf("\nString in ------> %s\n\n",b);*/
+
+ for(tmp = 0; tmp < 5; tmp++)
+ fprintf(stderr,"\np[%d] = %ld\n", tmp, b[tmp]);
+ *a = b;
+ *c = b;
+ return rs;
+}
+
+
+/* OK */
+m_i_pid_test__rs* m_i_pid_test__cb(CORBA_Object oe_obj,
+ erlang_pid* a,
+ erlang_pid* b,
+ erlang_pid* c,
+ CORBA_Environment *oe_env)
+{
+ m_i_pid_test__rs* rs = NULL;
+
+ *a = *b;
+ *c = *b;
+ return rs;
+}
+
+/* OK */
+m_i_port_test__rs* m_i_port_test__cb(CORBA_Object oe_obj,
+ erlang_port* a,
+ erlang_port* b,
+ erlang_port* c,
+ CORBA_Environment *oe_env)
+{
+ m_i_port_test__rs* rs = NULL;
+
+ strcpy((*a).node,(*b).node);
+ (*a).id = (*b).id;
+ (*a).creation = 0;
+
+ strcpy((*c).node,(*b).node);
+ (*c).id = (*b).id;
+ (*c).creation = 0;
+ return rs;
+}
+
+/* OK */
+m_i_ref_test__rs* m_i_ref_test__cb(CORBA_Object oe_obj,
+ erlang_ref* a,
+ erlang_ref* b,
+ erlang_ref* c,
+ CORBA_Environment *oe_env)
+{
+
+ m_i_ref_test__rs* rs = NULL;
+
+ strcpy((*a).node,(*b).node);
+ /*(*a).id = (*b).id;*/
+ (*a).len = (*b).len;
+ (*a).n[0] = (*b).n[0];
+ (*a).n[1] = (*b).n[1];
+ (*a).n[2] = (*b).n[2];
+ (*a).creation = 0;
+
+ strcpy((*c).node,(*b).node);
+ /*(*c).id = (*b).id;*/
+ (*c).len = (*b).len;
+ (*c).n[0] = (*b).n[0];
+ (*c).n[1] = (*b).n[1];
+ (*c).n[2] = (*b).n[2];
+ (*c).creation = 0;
+ return rs;
+}
+
+/* OK */
+m_i_term_test__rs* m_i_term_test__cb(CORBA_Object oe_obj,
+ ETERM** a,
+ ETERM** b,
+ ETERM** c,
+ CORBA_Environment *oe_env)
+{
+ m_i_term_test__rs* rs = NULL;
+
+ *a = *b;
+ *c = *b;
+ return rs;
+}
+
+m_i_typedef_test__rs* m_i_typedef_test__cb(CORBA_Object oe_obj,
+ long* a,
+ ETERM** b,
+ erlang_port* c,
+ ETERM** d ,
+ erlang_port* e,
+ CORBA_Environment *oe_env)
+{
+ m_i_typedef_test__rs* rs = NULL;
+
+ *d = *b;
+ strcpy((*e).node,(*c).node);
+ (*e).id = (*c).id;
+ (*e).creation = 0;
+ *a = 4711;
+ return rs;
+}
+
+/* OK */
+m_i_inline_sequence_test__rs* m_i_inline_sequence_test__cb(
+ CORBA_Object oe_obj,
+ m_s** a,
+ m_s* b,
+ m_s** c,
+ CORBA_Environment *oe_env)
+{
+ m_i_inline_sequence_test__rs* rs = NULL;
+
+ *a = b;
+ *c = b;
+ return rs;
+}
+
+/* OK */
+m_i_term_sequence_test__rs* m_i_term_sequence_test__cb(
+ CORBA_Object oe_obj,
+ m_etseq** a,
+ m_etseq* b,
+ m_etseq** c,
+ CORBA_Environment *oe_env)
+{
+ m_i_term_sequence_test__rs* rs = NULL;
+
+ *a = b;
+ *c = b;
+ return rs;
+}
+
+
+/* OK */
+m_i_term_struct_test__rs* m_i_term_struct_test__cb(CORBA_Object oe_obj,
+ m_et* a,
+ m_et* b,
+ m_et* c,
+ CORBA_Environment *oe_env)
+{
+ m_i_term_struct_test__rs* rs = NULL;
+
+ *a = *b;
+ *c = *b;
+ return rs;
+}
+
diff --git a/lib/ic/test/erl_client_c_server_proto_SUITE_data/erl_c_test.idl b/lib/ic/test/erl_client_c_server_proto_SUITE_data/erl_c_test.idl
new file mode 100644
index 0000000000..e90d0dd5f0
--- /dev/null
+++ b/lib/ic/test/erl_client_c_server_proto_SUITE_data/erl_c_test.idl
@@ -0,0 +1,174 @@
+
+
+// %CopyrightBegin%
+//
+// Copyright Ericsson AB 2004-2010. All Rights Reserved.
+//
+// The contents of this file are subject to the Erlang Public License,
+// Version 1.1, (the "License"); you may not use this file except in
+// compliance with the License. You should have received a copy of the
+// Erlang Public License along with this software. If not, it can be
+// retrieved online at http://www.erlang.org/.
+//
+// Software distributed under the License is distributed on an "AS IS"
+// basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+// the License for the specific language governing rights and limitations
+// under the License.
+//
+// %CopyrightEnd%
+
+#include "erlang.idl"
+
+
+const short TestConst = 1;
+
+module m {
+
+ const short TestConst = 2;
+
+ struct b {
+ long l;
+ char c;
+ };
+
+ struct simple {
+ long l;
+ b b_t;
+ };
+
+ enum fruit {orange, banana, apple, peach, pear};
+
+ typedef sequence<long> lseq;
+
+ typedef sequence<b> bseq;
+
+ struct a {
+ long l;
+ bseq y;
+ double d;
+ };
+
+ typedef sequence<a> aseq;
+
+ typedef sequence<string> sseq;
+ typedef string str;
+ typedef long myLong;
+
+ typedef long arr1[500], dd[2][3];
+
+ typedef erlang::term apa;
+ typedef erlang::port banan;
+
+ typedef sequence<erlang::term> etseq;
+
+ struct s {
+ long l;
+ sequence<long> sl;
+ };
+
+ struct es {
+ fruit f;
+ myLong l;
+ };
+
+ struct et {
+ erlang::term e;
+ long l;
+ };
+
+
+ typedef sequence<char> str1;
+ typedef string<12> str2;
+ typedef char str3[3];
+
+ typedef sequence<string> sstr3; // sequence of string
+ typedef sequence<sstr3> ssstr3; // sequence of sequences of strings
+
+ typedef long arr3[3]; // array of long
+ typedef sequence<arr3> sarr3; // sequence of array
+ typedef sequence<sarr3> ssarr3; // sequence of sequnces of arrays of strings
+
+ struct strRec{
+ boolean bb;
+ string str4;
+ long str7[3][2];
+ sequence<char> str5;
+ string<12> str6;
+ str3 str8;
+ str2 str9;
+ str1 str10;
+ };
+
+
+ struct dyn {
+ long l;
+ sequence<long> sl;
+ };
+ typedef dyn arr2[1][2];
+
+
+ interface i {
+
+ const short TestConst = 3;
+
+ //arr2 suck(in arr2 x, out arr2 y );
+
+ ///////////////////////////////// attribute long l;
+
+ // simple types
+ void void_test();
+ long long_test(in long a, out long a1);
+ long long longlong_test(in long long a, out long long a1);
+ unsigned short ushort_test(in unsigned short a, out unsigned short a1);
+ unsigned long ulong_test(in unsigned long a, out unsigned long a1);
+ unsigned long long ulonglong_test(in unsigned long long a, out unsigned long long a1);
+ double double_test(in double a, out double a1);
+ char char_test(in char a, out char a1);
+ wchar wchar_test(in wchar a, out wchar a1);
+ octet octet_test(in octet a, out octet a1);
+ boolean bool_test(in boolean a, out boolean a1);
+
+ // Seq. and struct tests
+ b struct_test(in b a, out b a1);
+ es struct2_test(in es a, out es a1);
+ //simple struct3_test(in simple x, out simple y);
+ bseq seq1_test(in bseq a, out bseq a1);
+ aseq seq2_test(in aseq a, out aseq a1);
+ lseq seq3_test(in lseq a, out lseq a1);
+ ssstr3 seq4_test(in ssstr3 a, out ssstr3 a1);
+ ssarr3 seq5_test(in ssarr3 a, out ssarr3 a1);
+
+ // Array tests
+ arr1 array1_test(in arr1 a, out arr1 a1);
+ dd array2_test(in dd a, out dd a1);
+
+ // enum test
+ fruit enum_test(in fruit a, out fruit a1);
+
+ // string tests
+ string string1_test(in string a, out string a1);
+ wstring wstring1_test(in wstring a, out wstring a1);
+ sseq string2_test(in sseq a, out sseq a1);
+ str string3_test(in str a, out str a1);
+ strRec string4_test(in strRec a, out strRec a1);
+
+ // Special erlang types
+ erlang::pid pid_test(in erlang::pid a, out erlang::pid a1);
+ erlang::port port_test(in erlang::port a, out erlang::port a1);
+ erlang::ref ref_test(in erlang::ref a, out erlang::ref a1);
+ erlang::term term_test(in erlang::term a, out erlang::term a1);
+
+ // typedef test
+ long typedef_test(in apa a, in banan b, out apa a1, out banan b1);
+
+ // inlined seq. test
+ s inline_sequence_test(in s a, out s a1);
+
+ // term seq. test
+ etseq term_sequence_test(in etseq a, out etseq a1);
+ // term struct test
+ et term_struct_test(in et a, out et a1);
+
+ };
+
+};
diff --git a/lib/ic/test/erl_client_c_server_proto_SUITE_data/erl_client.erl b/lib/ic/test/erl_client_c_server_proto_SUITE_data/erl_client.erl
new file mode 100644
index 0000000000..b5ee7af199
--- /dev/null
+++ b/lib/ic/test/erl_client_c_server_proto_SUITE_data/erl_client.erl
@@ -0,0 +1,331 @@
+%%
+%% %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(erl_client).
+
+-export([void_test/2, long_test/2, longlong_test/2, ushort_test/2,
+ ulong_test/2, ulonglong_test/2, double_test/2, char_test/2,
+ wchar_test/2, octet_test/2, bool_test/2, struct_test/2,
+ struct2_test/2, seq1_test/2, seq2_test/2, seq3_test/2,
+ seq4_test/2, seq5_test/2, array1_test/2, array2_test/2,
+ enum_test/2, string1_test/2, wstring1_test/2, string2_test/2,
+ string3_test/2, string4_test/2, pid_test/2, port_test/2,
+ ref_test/2, term_test/2, typedef_test/2,
+ inline_sequence_test/2, term_sequence_test/2,
+ term_struct_test/2
+
+]).
+
+-include("m.hrl").
+-include("m_i.hrl").
+-include("oe_erl_c_test.hrl").
+
+%%b
+void_test(Node, Timeout) ->
+ Ret = m_i:void_test({olsson, Node}, Timeout),
+ Ret == void. % XXX Not documented
+%%e
+
+%%b
+long_test(Node, Timeout) ->
+ In = max_long(),
+ {Ret, Out} = m_i:long_test({olsson, Node}, Timeout, In),
+ (Ret == In) and (Out == In).
+%%e
+
+%%b
+longlong_test(Node, Timeout) ->
+ In = 65537,
+ {Ret, Out} = m_i:longlong_test({olsson, Node}, Timeout, In),
+ (Ret == In) and (Out == In).
+%%e
+
+%%b
+ushort_test(Node, Timeout) ->
+ In = max_ushort(),
+ {Ret, Out} = m_i:ushort_test({olsson, Node}, Timeout, In),
+ (Ret == In) and (Out == In).
+%%e
+
+%%b
+ulong_test(Node, Timeout) ->
+ In = max_ulong(),
+ {Ret, Out} = m_i:ulong_test({olsson, Node}, Timeout, In),
+ (Ret == In) and (Out == In).
+%%e
+
+%%b
+ulonglong_test(Node, Timeout) ->
+ In = 65537,
+ {Ret, Out} = m_i:ulonglong_test({olsson, Node}, Timeout, In),
+ (Ret == In) and (Out == In).
+%%e
+
+%%b
+double_test(Node, Timeout) ->
+ In = 37768.93,
+ {Ret, Out} = m_i:double_test({olsson, Node}, Timeout, In),
+ (Ret == In) and (Out == In).
+%%e
+
+%%b
+char_test(Node, Timeout) ->
+ In = 80,
+ {Ret, Out} = m_i:char_test({olsson, Node}, Timeout, In),
+ (Ret == In) and (Out == In).
+%%e
+
+%%b
+wchar_test(Node, Timeout) ->
+ In = 4097,
+ {Ret, Out} = m_i:wchar_test({olsson, Node}, Timeout, In),
+ (Ret == In) and (Out == In).
+%%e
+
+%%b
+octet_test(Node, Timeout) ->
+ In = 255,
+ {Ret, Out} = m_i:octet_test({olsson, Node}, Timeout, In),
+ (Ret == In) and (Out == In).
+%%e
+
+%%b
+bool_test(Node, Timeout) ->
+ In = false,
+ {Ret, Out} = m_i:bool_test({olsson, Node}, Timeout, In),
+ (Ret == In) and (Out == In).
+%%e
+
+%%b
+struct_test(Node, Timeout) ->
+ In = #m_b{l = max_long(), c = $a},
+ {Ret, Out} = m_i:struct_test({olsson, Node}, Timeout, In),
+ (Ret == In) and (Out == In).
+%%e
+
+%%b
+struct2_test(Node, Timeout) ->
+ In = #m_es{ f = banana, l = max_long()},
+ {Ret, Out} = m_i:struct2_test({olsson, Node}, Timeout, In),
+ (Ret == In) and (Out == In).
+%%e
+
+%%b
+seq1_test(Node, Timeout) ->
+ B1 = #m_b{l = max_long(), c = $a},
+ B2 = #m_b{l = min_long(), c = $b},
+ In = [B1, B2],
+ {Ret, Out} = m_i:seq1_test({olsson, Node}, Timeout, In),
+ (Ret == In) and (Out == In).
+%%e
+
+%%b
+seq2_test(Node, Timeout) ->
+ B = #m_b{l = max_long(), c = $a},
+ A = #m_a{l = min_long(), y = [B, B], d = 4711.31},
+ In = [A, A, A],
+ {Ret, Out} = m_i:seq2_test({olsson, Node}, Timeout, In),
+ (Ret == In) and (Out == In).
+%%e
+
+%%b
+seq3_test(Node, Timeout) ->
+ In = [max_long(), min_long(), max_long()],
+ {Ret, Out} = m_i:seq3_test({olsson, Node}, Timeout, In),
+ (Ret == In) and (Out == In).
+%%e
+
+%%b
+seq4_test(Node, Timeout) ->
+ In = [["hej", "hopp"], ["ditt", "feta", "nylle"]],
+ {Ret, Out} = m_i:seq4_test({olsson, Node}, Timeout, In),
+ (Ret == In) and (Out == In).
+%%e
+
+%%b
+seq5_test(Node, Timeout) ->
+ Arr3 = mk_array(3, max_long()),
+ In = [[Arr3, Arr3], [Arr3, Arr3, Arr3]],
+ {Ret, Out} = m_i:seq5_test({olsson, Node}, Timeout, In),
+ (Ret == In) and (Out == In).
+%%e
+
+%%b
+array1_test(Node, Timeout) ->
+ In = mk_array(500, min_long()),
+ {Ret, Out} = m_i:array1_test({olsson, Node}, Timeout, In),
+ (Ret == In) and (Out == In).
+%%e
+
+%%b
+array2_test(Node, Timeout) ->
+ In = mk_array(2, mk_array(3, min_long())),
+ {Ret, Out} = m_i:array2_test({olsson, Node}, Timeout, In),
+ (Ret == In) and (Out == In).
+%%e
+
+%%b
+enum_test(Node, Timeout) ->
+ In = banana,
+ {Ret, Out} = m_i:enum_test({olsson, Node}, Timeout, In),
+ (Ret == In) and (Out == In).
+%%e
+
+%%b
+string1_test(Node, Timeout) ->
+ In = "Die Paula muss beim Tango immer weinen",
+ {Ret, Out} = m_i:string1_test({olsson, Node}, Timeout, In),
+ (Ret == In) and (Out == In).
+%%e
+
+%%b
+wstring1_test(Node, Timeout) ->
+ In = [1047| "ie Paula muss beim Tango immer weinen"],
+ {Ret, Out} = m_i:wstring1_test({olsson, Node}, Timeout, In),
+ (Ret == In) and (Out == In).
+%%e
+
+%%b
+string2_test(Node, Timeout) ->
+ In = ["Lass doch die Blumen,", "Konrad!"],
+ {Ret, Out} = m_i:string2_test({olsson, Node}, Timeout, In),
+ (Ret == In) and (Out == In).
+%%e
+
+%%b
+string3_test(Node, Timeout) ->
+ In = "Seeman, lass uns freuden!",
+ {Ret, Out} = m_i:string3_test({olsson, Node}, Timeout, In),
+ (Ret == In) and (Out == In).
+%%e
+
+%%b
+string4_test(Node, Timeout) ->
+
+ In = #m_strRec{
+ bb = true,
+ str4 = "Paula war zu Hause in ihrem Stadtchen als die beste Tanzerin"
+ "bekannt",
+ str7 = mk_array(3, mk_array(2, max_long())),
+ str5 = [$a, $b, $c, $d, $e, $f],
+ str6 = "123456789012",
+ str8 = {$x, $y, $x},
+ str9 = "123456789012",
+ str10 = [$a, $b, $c, $d, $e, $f]
+ },
+ {Ret, Out} = m_i:string4_test({olsson, Node}, Timeout, In),
+ (Ret == In) and (Out == In).
+%%e
+
+%%b
+pid_test(Node, Timeout) ->
+ In = self(),
+ {Ret, Out} = m_i:pid_test({olsson, Node}, Timeout, In),
+ (Ret == In) and (Out == In).
+%%e
+
+%%b
+port_test(Node, Timeout) ->
+ In = get(port_test_port),
+ {Ret, Out} = m_i:port_test({olsson, Node}, Timeout, In),
+ (Ret == In) and (Out == In).
+%%e
+
+%%b
+ref_test(Node, Timeout) ->
+ In = make_ref(),
+ {Ret, Out} = m_i:ref_test({olsson, Node}, Timeout, In),
+ (Ret == In) and (Out == In).
+%%e
+
+%%b
+term_test(Node, Timeout) ->
+ In = {[a, b], 17, kalle},
+ {Ret, Out} = m_i:term_test({olsson, Node}, Timeout, In),
+ (Ret == In) and (Out == In).
+%%e
+
+%%b
+typedef_test(Node, Timeout) ->
+ In1 = {nisse, [1, 2], olsson},
+ In2 = get(port_test_port),
+ {Ret, Out1, Out2} = m_i:typedef_test({olsson, Node}, Timeout, In1, In2),
+ %% XXX Should check that Ret is an integer.
+ (Out1 == In1) and (Out2 == In2).
+%%e
+
+%%b
+inline_sequence_test(Node, Timeout) ->
+ In = #m_s{l = min_long(), sl = [max_long(), min_long()]},
+ {Ret, Out} = m_i:inline_sequence_test({olsson, Node}, Timeout, In),
+ (Ret == In) and (Out == In).
+%%e
+
+%%b
+term_sequence_test(Node, Timeout) ->
+ In = lists:duplicate(17, {nisse, [1, 2], {kalle, olsson}}),
+ {Ret, Out} = m_i:term_sequence_test({olsson, Node}, Timeout, In),
+ (Ret == In) and (Out == In).
+%%e
+
+%%b
+term_struct_test(Node, Timeout) ->
+ In = #m_et{e = {nisse, ["abcde"], {kalle, olsson}}, l = 4711},
+ {Ret, Out} = m_i:term_struct_test({olsson, Node}, Timeout, In),
+ (Ret == In) and (Out == In).
+%%e
+
+
+%% Locals
+
+mk_array(Es) ->
+ list_to_tuple(Es).
+
+mk_array(N, E) ->
+ mk_array(lists:duplicate(N, E)).
+
+%% max_short() ->
+%% power_of_two(15) - 1.
+max_long() ->
+ power_of_two(31) - 1.
+max_longlong() ->
+ power_of_two(63) - 1.
+max_ushort() ->
+ power_of_two(16) - 1.
+max_ulong() ->
+ power_of_two(32) - 1.
+max_ulonglong() ->
+ power_of_two(64) - 1.
+
+%% min_short() ->
+%% -power_of_two(15).
+min_long() ->
+ -power_of_two(31).
+%% min_longlong() ->
+%% -power_of_two(63).
+%% min_ushort() ->
+%% 0.
+%% min_ulong() ->
+%% 0.
+%% min_ulonglong() ->
+%% 0.
+
+power_of_two(N) ->
+ round(math:pow(2, N)).
+
diff --git a/lib/ic/test/erl_client_c_server_proto_SUITE_data/my.c b/lib/ic/test/erl_client_c_server_proto_SUITE_data/my.c
new file mode 100644
index 0000000000..c0401b2621
--- /dev/null
+++ b/lib/ic/test/erl_client_c_server_proto_SUITE_data/my.c
@@ -0,0 +1,34 @@
+/*
+ * %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 "ic.h"
+#include "m_i.h"
+
+int my_prepare_request_decoding(CORBA_Environment *env)
+{
+ return oe_prepare_request_decoding(env);
+}
+
+int my_prepare_reply_encoding(CORBA_Environment *env)
+{
+ return oe_prepare_reply_encoding(env);
+}
+
+
+
diff --git a/lib/ic/test/ic.spec b/lib/ic/test/ic.spec
new file mode 100644
index 0000000000..280c2aba47
--- /dev/null
+++ b/lib/ic/test/ic.spec
@@ -0,0 +1 @@
+{topcase, {dir, "../ic_test"}}.
diff --git a/lib/ic/test/ic.spec.vxworks b/lib/ic/test/ic.spec.vxworks
new file mode 100644
index 0000000000..b15260ab70
--- /dev/null
+++ b/lib/ic/test/ic.spec.vxworks
@@ -0,0 +1,2 @@
+{topcase, {dir, "../ic_test"}}.
+{skip,{ic_pp_SUITE,"Uses gcc"}}.
diff --git a/lib/ic/test/ic_SUITE.erl b/lib/ic/test/ic_SUITE.erl
new file mode 100644
index 0000000000..6682c82f01
--- /dev/null
+++ b/lib/ic/test/ic_SUITE.erl
@@ -0,0 +1,973 @@
+%%
+%% %CopyrightBegin%
+%%
+%% 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%
+%%
+%%
+%%%----------------------------------------------------------------------
+%%% Purpose : Test suite for the IDL compiler
+%%%----------------------------------------------------------------------
+
+-module(ic_SUITE).
+-include("test_server.hrl").
+
+-export([all/1]).
+
+
+-include_lib("orber/src/orber_ifr.hrl").
+-include_lib("orber/src/ifr_objects.hrl").
+-include_lib("orber/include/ifr_types.hrl").
+
+
+%% The type cases
+-export([type/1, type_norm/1]).
+
+%% The syntax case
+-export([syntax/1]).
+-export([syntax1/1, syntax2/1, syntax3/1, syntax4/1, syntax5/1, syntax6/1]).
+
+%% The constant cases
+-export([const/1]).
+-export([const_norm/1, const_bad_tk/1, const_bad_type/1]).
+-export([const_bad_comb/1]).
+
+%% The union cases
+-export([union/1]).
+-export([union_norm/1, union_type/1, union_mult_err/1, union_case_mult/1]).
+-export([union_default/1]).
+
+%% The enum cases
+-export([enum/1]).
+-export([enum_norm/1]).
+
+%% The struct cases
+-export([struct/1]).
+-export([struct_norm/1]).
+
+%% The oneway cases
+-export([oneway/1]).
+-export([oneway_norm/1, oneway_raises/1, oneway_out/1, oneway_void/1, oneway_followed/1]).
+
+%% The attributes cases
+-export([attr/1]).
+-export([attr_norm/1]).
+
+%% The raises registration case
+-export([raises_reg/1]).
+
+
+%% The typeID case
+
+%% general stuff
+-export([general/1]).
+-export([typeid/1, undef_id/1, dir/1, nasty_names/1, coss/1, mult_ids/1]).
+-export([forward/1, include/1, app_test/1]).
+
+%% inheritance stuff
+-export([inherit/1, inherit_norm/1, inherit_warn/1, inherit_err/1]).
+
+%% Standard options to the ic compiler, NOTE unholy use of OutDir
+
+-define(OUT(X), filename:join([?config(priv_dir, Config), gen, to_list(X)])).
+
+
+%% Top of cases
+
+all(doc) ->
+ [];
+all(suite) -> [app_test, const, union, enum, attr, type, struct, general, inherit,
+ oneway, syntax, raises_reg].
+
+
+app_test(doc) -> [];
+app_test(suite) -> [];
+app_test(_Config) ->
+ ok=test_server:app_test(ic),
+ ok.
+
+%%---------------------------------------------------------------------
+%%
+%% Test of constant expressions.
+%%
+
+const(suite) -> [const_norm, const_bad_tk, const_bad_type, const_bad_comb].
+
+
+const_norm(doc) ->
+ ["Checks normal constant types and values"];
+const_norm(suite) -> [];
+const_norm(Config) when is_list(Config) ->
+ DataDir = ?config(data_dir, Config),
+ OutDir = ?OUT(const_norm),
+ File = filename:join(DataDir, c_norm),
+ ?line ok = ic:gen(File, stdopts(OutDir)),
+ ?line {ok, []} = ic:gen(File, stdopts(OutDir)++[silent2]),
+ ?line ok = compile(OutDir, const_norm_files()),
+ ok.
+
+const_bad_tk(doc) ->
+ ["Checks when the constant value doesn't match the declared type"];
+const_bad_tk(suite) -> [];
+const_bad_tk(Config) when is_list(Config) ->
+ DataDir = ?config(data_dir, Config),
+ OutDir = ?OUT(slask),
+ File = filename:join(DataDir, c_err1),
+ ?line error = ic:gen(File, stdopts(OutDir)),
+ ?line {error, [], R} =
+ ic:gen(File, stdopts(OutDir)++[silent2]),
+ check_errors(18, bad_tk_match, R),
+ ok.
+
+const_bad_type(doc) ->
+ ["Checks operands of ops are of correct type"];
+const_bad_type(suite) -> [];
+const_bad_type(Config) when is_list(Config) ->
+ DataDir = ?config(data_dir, Config),
+ OutDir = ?OUT(slask),
+ File = filename:join(DataDir, c_err2),
+ ?line error = ic:gen(File, stdopts(OutDir)),
+ ?line {error, [], R} =
+ ic:gen(File, stdopts(OutDir)++[silent2]),
+ check_errors(4, bad_type, R),
+ ok.
+
+const_bad_comb(doc) ->
+ ["Checks operands of ops are of conflicting types"];
+const_bad_comb(suite) -> [];
+const_bad_comb(Config) when is_list(Config) ->
+ DataDir = ?config(data_dir, Config),
+ OutDir = ?OUT(slask),
+ File = filename:join(DataDir, c_err3),
+ ?line error = ic:gen(File, stdopts(OutDir)),
+ ?line {error, [], R} =
+ ic:gen(File, stdopts(OutDir)++[silent2]),
+ check_errors(3, bad_type_combination, R),
+ ok.
+
+
+
+union(suite) -> [union_norm, union_type, union_mult_err, union_case_mult,
+ union_default];
+union(doc) ->
+ ["Checks allowed usage of the union as well as the illegal cases"].
+
+
+union_norm(doc) ->
+ ["Checks that normal union declarations works."];
+union_norm(suite) -> [];
+union_norm(Config) when is_list(Config) ->
+ DataDir = ?config(data_dir, Config),
+ OutDir = ?OUT(union_norm),
+ File = filename:join(DataDir, u_norm),
+
+ ?line ok = ic:gen(File, stdopts(OutDir)),
+ ?line {ok, []} = ic:gen(File, stdopts(OutDir)++[silent2]),
+ ?line ok = compile(OutDir, union_norm_files()),
+ ok.
+
+
+%% Checks OTP-2007
+union_default(doc) ->
+ ["Checks that default cases are correct in type code."];
+union_default(suite) -> [];
+union_default(Config) when is_list(Config) ->
+ DataDir = ?config(data_dir, Config),
+ OutDir = ?OUT(union_default),
+ File = filename:join(DataDir, u_default),
+
+ ?line ok = ic:gen(File, stdopts(OutDir)),
+ ?line {ok, []} = ic:gen(File, stdopts(OutDir)++[silent2]),
+ ?line ok = compile(OutDir, union_default_files(), [load]),
+ TkList = i1:oe_get_interface(),
+ check_label("op0", 0, TkList),
+ check_label("op1", 1, TkList),
+ check_label("op2", 2, TkList),
+ check_label("op3", -1, TkList),
+ ok.
+
+check_label(Id, N, List) ->
+ case lists:keysearch(Id, 1, List) of
+ {value, {_, {{_, _, _, _, D, L}, _, _}}} ->
+ if D /= N ->
+ test_server:fail({bad_default_num, D, N});
+ D /= -1 ->
+ case lists:nth(D+1, L) of
+ T when element(1, T) == default ->
+ ok;
+ _Que ->
+ test_server:fail({bad_default_list, D, L})
+ end;
+ true ->
+ %% D = N = -1, just check that there is no default label
+ case lists:keysearch(default, 1, L) of
+ false ->
+ ok;
+ _ ->
+ test_server:fail({bad_default_label, D, L})
+ end
+ end;
+ _ ->
+ test_server:fail({'no_such_op!', Id, List})
+ end.
+
+union_type(doc) ->
+ ["Checks that errors are detected. Check that mismatch between case ",
+ "value and declared discriminator type is detected."];
+union_type(suite) -> [];
+union_type(Config) when is_list(Config) ->
+ DataDir = ?config(data_dir, Config),
+ OutDir = ?OUT(slask),
+ File = filename:join(DataDir, u_type),
+ ?line error = ic:gen(File, stdopts(OutDir)),
+ ?line {error, [], R} =
+ ic:gen(File, stdopts(OutDir)++[silent2]),
+ check_errors(28, bad_case_type, R),
+ ok.
+
+
+union_mult_err(doc) ->
+ ["Check that multiple declared declarators are caught.",
+ "Also check that if the discriminator is an enum, then the enum name",
+ "must not be used as a declarator in the union switch (declarator",
+ "as opposed to label)."];
+union_mult_err(suite) -> [];
+union_mult_err(Config) when is_list(Config) ->
+ DataDir = ?config(data_dir, Config),
+ OutDir = ?OUT(slask),
+ File = filename:join(DataDir, u_mult),
+ ?line error = ic:gen(File, stdopts(OutDir)),
+ ?line {error, [], R} =
+ ic:gen(File, stdopts(OutDir)++[silent2]),
+ check_errors(8, multiply_defined, R),
+ ok.
+
+%% Checking mult cases. Now check that other errors are found in the
+%% correct order XXXX
+
+
+union_case_mult(doc) ->
+ ["Check that multiply defined case labels are found and reported."];
+union_case_mult(suite) -> [];
+union_case_mult(Config) when is_list(Config) ->
+ DataDir = ?config(data_dir, Config),
+ OutDir = ?OUT(slask),
+ File = filename:join(DataDir, u_case_mult),
+ ?line error = ic:gen(File, stdopts(OutDir)),
+ ?line {error, [], R} =
+ ic:gen(File, stdopts(OutDir)++[silent2]),
+ check_errors(7, multiple_cases, R),
+ ok.
+
+
+%%--------------------------------------------------------------------
+%%
+%% Enum cases
+%%
+
+enum(suite) -> [enum_norm];
+enum(doc) ->
+ ["Checks allowed usage of the enum as well as the illegal cases"].
+
+enum_norm(doc) ->
+ ["Checks that normal enum declarations works."];
+enum_norm(suite) -> [];
+enum_norm(Config) when is_list(Config) ->
+ DataDir = ?config(data_dir, Config),
+ OutDir = ?OUT(enum_norm),
+ File = filename:join(DataDir, enum),
+
+ ?line ok = ic:gen(File, stdopts(OutDir)),
+ ?line {ok, []} = ic:gen(File, stdopts(OutDir)++[silent2]),
+ ?line ok = compile(OutDir, enum_norm_files()),
+ ok.
+
+
+%%--------------------------------------------------------------------
+%%
+%% Struct cases
+%%
+
+struct(suite) -> [struct_norm];
+struct(doc) ->
+ ["Checks allowed usage of the struct as well as the illegal cases"].
+
+struct_norm(doc) ->
+ ["Checks that normal struct declarations works."];
+struct_norm(suite) -> [];
+struct_norm(Config) when is_list(Config) ->
+ DataDir = ?config(data_dir, Config),
+ OutDir = ?OUT(struct_norm),
+ File = filename:join(DataDir, struct),
+
+ ?line ok = ic:gen(File, stdopts(OutDir)),
+ ?line {ok, []} = ic:gen(File, stdopts(OutDir)++[silent2]),
+ ?line ok = compile(OutDir, struct_norm_files()),
+ Mod = ridiculous_name_to_avoid_clash_svenne,
+ TestFile = filename:join(OutDir, Mod),
+ ?line ok = gen_struct_file(TestFile, Mod),
+ ?line ok = compile(OutDir, [Mod], [load]),
+%% ?line {ok, Mod, []} = compile:file(TestFile,
+%% [{i, OutDir}, {outdir, OutDir},
+%% return, load]),
+ ?line ok = Mod:test(),
+ ok.
+
+
+%%--------------------------------------------------------------------
+%%
+%% General cases
+%%
+
+general(doc) ->
+ ["Check general things like directories and type identifier",
+ "detection."];
+general(suite) -> [typeid, undef_id, mult_ids, forward, include, nasty_names].
+%% coss (add sometimes, takes 440 seconds!)
+
+typeid(doc) ->
+ ["Check that type id's are generated correctly"];
+typeid(suite) -> [];
+typeid(Config) when is_list(Config) ->
+ DataDir = ?config(data_dir, Config),
+ OutDir = ?OUT(typeid),
+ File = filename:join(DataDir, typeid),
+
+ ?line ok = ic:gen(File, stdopts(OutDir)),
+ ?line {ok, []} = ic:gen(File, stdopts(OutDir)++[silent2]),
+ ?line ok = compile(OutDir, typeid_files(), [load]),
+ ?line "IDL:I1:1.0" = 'I1':'typeID'(),
+ ?line "IDL:M1/I1:1.0" = 'M1_I1':'typeID'(),
+ ?line "IDL:M2/M1/I1:1.0" = 'M2_M1_I1':'typeID'(),
+ ?line "IDL:M3/M2/M1/I1:1.0" = 'M3_M2_M1_I1':'typeID'(),
+ ok.
+
+
+%%% This test case is removed because there's no way to test this from
+%%% an automated test suite.
+dir(doc) ->
+ ["Check that relative directories work, absolute is used in",
+ "all other cases in the suite."];
+%%% xxxxxx
+dir(suite) -> [];
+dir(Config) when is_list(Config) ->
+ok;
+dir(Config) ->
+ DataDir = ?config(data_dir, Config),
+
+ %% Needs a unique directory (any better way?)
+ OutDir = mk_unique("oe_the_dir"),
+
+ %% More unique names
+ File = filename:join(DataDir, mk_unique("oe_the_file")),
+ Const = mk_unique("oe_the_constant"),
+ Mod = list_to_atom(File),
+ Func = list_to_atom(Const),
+
+ %% Generate a unique IDL file with a single constant
+ gen_file(File, Const),
+
+ ?line ok = ic:gen(File, stdopts(OutDir)),
+ ?line ok = compile(OutDir, [load]),
+ ?line 19955 = Mod:Func(),
+ ?line {ok, []} = ic:gen(File, stdopts(OutDir)++[silent2]),
+ ?line ok = compile(OutDir, [load]),
+ ?line 19955 = Mod:Func(),
+
+ ?line ok = ic:gen(File),
+%%% ?line ok = compile(".", [load]),
+ ok.
+
+undef_id(doc) ->
+ ["Check that various undefied id's are detected correctly"];
+undef_id(suite) -> [];
+undef_id(Config) when is_list(Config) ->
+ DataDir = ?config(data_dir, Config),
+ OutDir = ?OUT(slask),
+ File = filename:join(DataDir, undef_id),
+ ?line error = ic:gen(File, stdopts(OutDir)),
+ ?line {error, [], R} =
+ ic:gen(File, stdopts(OutDir)++[silent2]),
+ check_errors(16, tk_not_found, R),
+ ok.
+
+mult_ids(doc) ->
+ ["Check that multiply defined ids are caught."];
+mult_ids(suite) -> [];
+mult_ids(Config) when is_list(Config) ->
+ DataDir = ?config(data_dir, Config),
+ OutDir = ?OUT(slask),
+ File = filename:join(DataDir, mult_ids),
+ ?line error = ic:gen(File, stdopts(OutDir)),
+ ?line {error, [], R} =
+ ic:gen(File, stdopts(OutDir)++[silent2]),
+ check_errors(22, multiply_defined, R),
+ ok.
+
+
+nasty_names(doc) ->
+ ["Check that various nasty names can be generated.",
+ "Try to provoke name clashes and name conflicts with",
+ "Erlang and IDL"];
+nasty_names(suite) -> [];
+nasty_names(Config) when is_list(Config) ->
+ DataDir = ?config(data_dir, Config),
+ OutDir = ?OUT(nasty_names),
+ File = filename:join(DataDir, nasty),
+
+ ?line ok = ic:gen(File, stdopts(OutDir)),
+ ?line {ok, []} = ic:gen(File, stdopts(OutDir)++[silent2]),
+ ?line ok = compile(OutDir, nasty_names_files(), [load]),
+ ok.
+
+coss(doc) ->
+ ["Check that the Coss standard specification works."];
+coss(suite) -> [];
+coss(Config) when is_list(Config) ->
+ DataDir = ?config(data_dir, Config),
+ OutDir = ?OUT(coss),
+ File = filename:join(DataDir, 'Coss'),
+
+ ?line ok = ic:gen(File, stdopts(OutDir)),
+ ?line {ok, [_W1]} = ic:gen(File, stdopts(OutDir)++[silent2]),
+ ?line ok = compile(OutDir, []),
+ ok.
+
+forward(doc) ->
+ ["Check that forward declaratios work."];
+forward(suite) -> [];
+forward(Config) when is_list(Config) ->
+ DataDir = ?config(data_dir, Config),
+ OutDir = ?OUT(forward),
+ File = filename:join(DataDir, forward),
+
+ ?line ok = ic:gen(File, stdopts(OutDir)),
+ ?line {ok, []} = ic:gen(File, stdopts(OutDir)++[silent2]),
+ ?line ok = compile(OutDir, forward_files(), [load]),
+ ok.
+
+include(doc) ->
+ ["Check that various undefied id's are detected correctly"];
+include(suite) -> [];
+include(Config) when is_list(Config) ->
+ DataDir = ?config(data_dir, Config),
+ OutDir = ?OUT(slask),
+ File = filename:join(DataDir, include),
+ ?line error = ic:gen(File, stdopts(OutDir)++[{preproc_flags,"-I" ++ DataDir}]),
+ ?line {error, [], R} =
+ ic:gen(File, stdopts(OutDir)++[{preproc_flags,"-I" ++ DataDir},silent2]),
+ case lists:map(fun(D) ->
+ filename:rootname(filename:basename(element(3, D)))
+ end,
+ lists:sort(R)) of
+ ["include",
+ "include2",
+ "include2",
+ "include3"] ->
+ ok;
+ RRR ->
+ test_server:fail({bad_include_file, RRR})
+ end,
+ ok.
+
+
+
+
+%%--------------------------------------------------------------------
+%%
+%% Inhertit cases
+%%
+
+inherit(doc) ->
+ ["Check the inheritance mechanism."];
+inherit(suite) -> [inherit_norm, inherit_warn, inherit_err].
+
+inherit_norm(doc) ->
+ ["Checks that normal inheritance works."];
+inherit_norm(suite) -> [];
+inherit_norm(Config) when is_list(Config) ->
+ DataDir = ?config(data_dir, Config),
+ OutDir = ?OUT(inherit_norm),
+ File = filename:join(DataDir, inherit),
+
+ ?line ok = ic:gen(File, stdopts(OutDir)),
+ ?line {ok, _Ws} = ic:gen(File, stdopts(OutDir)++[silent2]),
+ ?line ok = compile(OutDir, inherit_norm_files(), [load]),
+
+ %% Now check constant values:
+ ?line 9 = m1_I1:c1(),
+
+ ?line 9 = m1_I2:c1(),
+ ?line 14 = m1_I2:c2(),
+ ?line 27 = m1_I2:c3(),
+
+ ?line 50 = m1_I3:c1(),
+ ?line 14 = m1_I3:c2(),
+ ?line 27 = m1_I3:c3(),
+ ?line 91 = m1_I3:c4(),
+ ?line 100 = m1_I3:c5(),
+ ok.
+
+inherit_warn(doc) ->
+ ["Check that various inheritance shadowing is detected"];
+inherit_warn(suite) -> [];
+inherit_warn(Config) when is_list(Config) ->
+ DataDir = ?config(data_dir, Config),
+ OutDir = ?OUT(slask),
+ File = filename:join(DataDir, inherit_warn),
+ ?line ok = ic:gen(File, stdopts(OutDir)),
+ ?line {ok, R} =
+ ic:gen(File, stdopts(OutDir)++[silent2]),
+ check_errors(7, inherit_name_shadow, R),
+ ok.
+
+inherit_err(doc) ->
+ ["Check that various inheritance errors is detected"];
+inherit_err(suite) -> [];
+inherit_err(Config) when is_list(Config) ->
+ DataDir = ?config(data_dir, Config),
+ OutDir = ?OUT(slask),
+ File = filename:join(DataDir, inherit_err),
+ ?line error = ic:gen(File, stdopts(OutDir)),
+ ?line {error, _Ws, R} =
+ ic:gen(File, stdopts(OutDir)++[silent2]),
+ check_errors(21, inherit_name_collision, R),
+ ok.
+
+
+oneway(doc) ->
+ ["Check the oneway operation mechanism."];
+oneway(suite) -> [oneway_norm, oneway_out, oneway_raises, oneway_void, oneway_followed ].
+
+oneway_norm(doc) ->
+ ["Checks that normal oneway operations works."];
+oneway_norm(suite) -> [];
+oneway_norm(Config) when is_list(Config) ->
+ DataDir = ?config(data_dir, Config),
+ OutDir = ?OUT(oneway_norm),
+ File = filename:join(DataDir, one),
+
+ ?line ok = ic:gen(File, stdopts(OutDir)),
+ ?line ok = compile(OutDir, oneway_norm_files(), [load]),
+ ?line {ok, []} = ic:gen(File, stdopts(OutDir)++[silent2]),
+ ?line ok = compile(OutDir, oneway_norm_files(), [load]),
+ ok.
+
+oneway_void(doc) ->
+ ["Check that non-void oneways are detected."];
+oneway_void(suite) -> [];
+oneway_void(Config) when is_list(Config) ->
+ DataDir = ?config(data_dir, Config),
+ OutDir = ?OUT(slask),
+ File = filename:join(DataDir, one_void),
+ ?line error = ic:gen(File, stdopts(OutDir)),
+ ?line {error, [], R} =
+ ic:gen(File, stdopts(OutDir)++[silent2]),
+ check_errors(2, bad_oneway_type, R),
+ ok.
+
+oneway_raises(doc) ->
+ ["Check that oneways cannot raise exceptions."];
+oneway_raises(suite) -> [];
+oneway_raises(Config) when is_list(Config) ->
+ DataDir = ?config(data_dir, Config),
+ OutDir = ?OUT(slask),
+ File = filename:join(DataDir, one_raises),
+ ?line error = ic:gen(File, stdopts(OutDir)),
+ ?line {error, [], R} =
+ ic:gen(File, stdopts(OutDir)++[silent2]),
+ check_errors(3, oneway_raises, R),
+ ok.
+
+oneway_out(doc) ->
+ ["Check that illegal out parameters are detected"];
+oneway_out(suite) -> [];
+oneway_out(Config) when is_list(Config) ->
+ DataDir = ?config(data_dir, Config),
+ OutDir = ?OUT(slask),
+ File = filename:join(DataDir, one_out),
+ ?line error = ic:gen(File, stdopts(OutDir)),
+ ?line {error, [], R} =
+ ic:gen(File, stdopts(OutDir)++[silent2]),
+ check_errors(2, oneway_outparams, R),
+ ok.
+
+oneway_followed(doc) ->
+ ["Checks that normal oneways, followed by other operations."];
+oneway_followed(suite) -> [];
+oneway_followed(Config) when is_list(Config) ->
+ DataDir = ?config(data_dir, Config),
+ OutDir = ?OUT(oneway_followed),
+ File = filename:join(DataDir, one_followed),
+
+ ?line ok = ic:gen(File, stdopts(OutDir)),
+ ?line ok = compile(OutDir, oneway_followed_files(), [load]),
+ ?line {ok, []} = ic:gen(File, stdopts(OutDir)++[silent2]),
+ ?line ok = compile(OutDir, oneway_followed_files(), [load]),
+ ok.
+
+attr(doc) ->
+ ["Check that attributes work."];
+attr(suite) -> [attr_norm].
+
+attr_norm(doc) ->
+ ["Checks that normal attr operations works."];
+attr_norm(suite) -> [];
+attr_norm(Config) when is_list(Config) ->
+ DataDir = ?config(data_dir, Config),
+ OutDir = ?OUT(attr_norm),
+ File = filename:join(DataDir, attr),
+
+ ?line ok = ic:gen(File, stdopts(OutDir)),
+ ?line ok = compile(OutDir, attr_norm_files(), [load]),
+ ?line {ok, []} = ic:gen(File, stdopts(OutDir)++[silent2]),
+ ?line ok = compile(OutDir, attr_norm_files(), [load]),
+ ok.
+
+type(doc) ->
+ ["Check that typeibutes work."];
+type(suite) -> [type_norm].
+
+type_norm(doc) ->
+ ["Checks all types are handled."];
+type_norm(suite) -> [];
+type_norm(Config) when is_list(Config) ->
+ DataDir = ?config(data_dir, Config),
+ OutDir = ?OUT(type_norm),
+ File = filename:join(DataDir, type),
+
+ ?line ok = ic:gen(File, stdopts(OutDir)),
+ ?line ok = compile(OutDir, type_norm_files(), [load]),
+ ?line {ok, []} = ic:gen(File, stdopts(OutDir)++[silent2]),
+ ?line ok = compile(OutDir, type_norm_files(), [load]),
+ ok.
+
+
+syntax(doc) ->
+ ["Check that syntax errors are discovered."];
+syntax(suite) -> [syntax1, syntax2, syntax3, syntax4, syntax5, syntax6].
+
+syntax1(suite) -> [];
+syntax1(Config) when is_list(Config) ->
+ DataDir = ?config(data_dir, Config),
+ OutDir = ?OUT(slask),
+ File = filename:join(DataDir, syntax1),
+
+ ?line error = ic:gen(File, stdopts(OutDir)),
+ ?line {error, [], R} =
+ ic:gen(File, stdopts(OutDir)++[silent2]),
+ check_errors(1, parse_error, R),
+ ok.
+
+syntax2(suite) -> [];
+syntax2(Config) when is_list(Config) ->
+ DataDir = ?config(data_dir, Config),
+ OutDir = ?OUT(slask),
+ File = filename:join(DataDir, syntax2),
+
+ ?line error = ic:gen(File, stdopts(OutDir)),
+ ?line {error, [], R} =
+ ic:gen(File, stdopts(OutDir)++[silent2]),
+ check_errors(1, parse_error, R),
+ ok.
+
+syntax3(suite) -> [];
+syntax3(Config) when is_list(Config) ->
+ DataDir = ?config(data_dir, Config),
+ OutDir = ?OUT(slask),
+ File = filename:join(DataDir, syntax3),
+
+ ?line error = ic:gen(File, stdopts(OutDir)),
+ ?line {error, [], R} =
+ ic:gen(File, stdopts(OutDir)++[silent2]),
+ check_errors(1, parse_error, R),
+ ok.
+
+syntax4(suite) -> [];
+syntax4(Config) when is_list(Config) ->
+ DataDir = ?config(data_dir, Config),
+ OutDir = ?OUT(slask),
+ File = filename:join(DataDir, syntax4),
+
+ ?line error = ic:gen(File, stdopts(OutDir)),
+ ?line {error, [], R} =
+ ic:gen(File, stdopts(OutDir)++[silent2]),
+ check_errors(1, parse_error, R),
+ ok.
+
+syntax5(suite) -> [];
+syntax5(Config) when is_list(Config) ->
+ DataDir = ?config(data_dir, Config),
+ OutDir = ?OUT(slask),
+ File = filename:join(DataDir, syntax5),
+
+ ?line error = ic:gen(File, stdopts(OutDir)),
+ ?line {error, [], R} =
+ ic:gen(File, stdopts(OutDir)++[silent2]),
+ check_errors(1, parse_error, R),
+ ok.
+
+syntax6(suite) -> [];
+syntax6(Config) when is_list(Config) ->
+ DataDir = ?config(data_dir, Config),
+ OutDir = ?OUT(slask),
+ File = filename:join(DataDir, syntax6),
+
+ ?line error = ic:gen(File, stdopts(OutDir)),
+ ?line {error, [], R} =
+ ic:gen(File, stdopts(OutDir)++[silent2]),
+ check_errors(1, parse_error, R),
+ ok.
+
+
+
+%%--------------------------------------------------------------------
+%%
+%% Checks RAISES to be registered under IFR operation registration
+%% ( OTP-2102 )
+%%
+
+raises_reg(doc) ->
+ ["Check that exceptions are really registered to operations."];
+raises_reg(suite) -> [];
+raises_reg(Config) when is_list(Config) ->
+ DataDir = ?config(data_dir, Config),
+ OutDir = ?OUT(raises_reg_check),
+ File = filename:join(DataDir, raises_reg),
+
+ ?line ok = ic:gen(File, stdopts(OutDir)),
+ ?line {ok, []} = ic:gen(File, stdopts(OutDir)++[silent2]),
+ ?line ok = compile(OutDir, raises_reg_files(), [load]),
+
+ set_up('oe_raises_reg'),
+
+ io:format("~n##### Starting the test case #####~n"),
+ io:format("Checking for existance of exception : ~s~n",["IDL:Raises_RegModule/Exception_1:1.0"]),
+ raises_register_check("IDL:Raises_RegModule/R_R/op:1.0","IDL:Raises_RegModule/Exception_1:1.0"),
+
+ io:format("Checking for existance of exception : ~s~n",["IDL:Raises_RegModule/Exception_2:1.0"]),
+ raises_register_check("IDL:Raises_RegModule/R_R/op:1.0","IDL:Raises_RegModule/Exception_2:1.0"),
+
+ io:format("Checking for existance of exception : ~s~n",["IDL:Raises_RegModule/XXXXXXXX:1.0"]),
+ raises_register_check("IDL:Raises_RegModule/R_R/op:1.0","IDL:RaisesModule/XXXXXXXX:1.0"),
+
+ set_down('oe_raises_reg'),
+
+ ok.
+
+set_up(Register) ->
+ io:format("Setting up.....~n"),
+ mnesia:stop(),
+ mnesia:delete_schema([node()]),
+ mnesia:create_schema([node()]),
+ mnesia:start(),
+ orber:install([node()]),
+ orber:start(),
+ io:format("Running OE_register()~n"),
+ Register:'oe_register'().
+
+set_down(Register) ->
+ io:format("Running OE_unregister()~n"),
+ Register:'oe_unregister'(),
+ io:format("Setting down.....~n"),
+ orber:stop(),
+ orber:uninstall(),
+ mnesia:stop(),
+ mnesia:delete_schema([node()]).
+
+
+raises_register_check(OpId,ExcId) ->
+ case is_valid_exc(OpId,ExcId) of
+ true ->
+ ok; % Because right exception where found,
+ % the test succeeds for normal cases.
+ false ->
+ ok; % Because the exception tested, is not
+ % registered for that operation.
+ FailReason ->
+ test_server:fail({FailReason, OpId, ExcId})
+ % Because the test descovered errors in a previous
+ % stage, or no exceptions where registered att all.
+ % ( This testcase assumes that operations to be
+ % checked allways raise excption(s) )
+ end.
+
+is_valid_exc(OpId,ExcId) ->
+ OE_IFR = orber_ifr:find_repository(),
+ OpDef = orber_ifr:'Repository_lookup_id'(OE_IFR,OpId),
+ ExcDefList = orber_ifr:get_exceptions(OpDef),
+ case ExcDefList of
+ [] ->
+ no_exceptions_registered;
+ _ ->
+ ExcDef=orber_ifr:lookup_id(OE_IFR,ExcId),
+ lists:member(ExcDef,ExcDefList)
+ end.
+
+%%--------------------------------------------------------------------
+%%
+%% Utilities
+
+
+stdopts(OutDir) ->
+ [{outdir, OutDir},{maxerrs, infinity}].
+
+mk_unique(Prefix) ->
+ {A,B,C} = now(),
+ Prefix++"_"++integer_to_list(A)++"_"++integer_to_list(B)++"_"++
+ integer_to_list(C).
+
+gen_file(File, Const) ->
+ {ok, Fd} = file:open(File++".idl", [write]),
+ io:format(Fd, "interface ~s {~n", [File]),
+ io:format(Fd, " const long ~s = 19955;~n", [Const]),
+ io:format(Fd, "};~n", []),
+ file:close(Fd).
+
+
+%% Compile all files in Dir. Used for checking that valid Erlang has
+%% been generated.
+%%compile(Dir) ->
+%% compile(Dir, []).
+%%compile(Dir, Opts) ->
+%% {ok, Cwd} = file:get_cwd(),
+%% catch do_compile(Dir, Opts),
+%% file:set_cwd(Cwd).
+
+%%do_compile(Dir, Opts) ->
+%% ok = file:set_cwd(Dir),
+%% up_to_date = ts_make_erl:all(Opts),
+%% ok.
+
+compile(Dir, Files) ->
+ compile(Dir, Files, []).
+
+compile(Dir, Files, Opts) ->
+ {ok, Cwd} = file:get_cwd(),
+ file:set_cwd(Dir),
+ io:format("Changing to ~p~n", [Dir]),
+ case catch do_compile(Files, Opts) of
+ ok ->
+ file:set_cwd(Cwd);
+ Err ->
+ file:set_cwd(Cwd),
+ test_server:fail(Err)
+ end.
+
+do_compile([], _Opts) -> ok;
+do_compile([F | Fs], Opts) ->
+ io:format("Compiling ~p", [F]),
+ case compile:file(F, Opts) of
+ ok ->
+ io:format(" ok~n", []),
+ do_load(F, Opts),
+ do_compile(Fs, Opts);
+ {ok, _} ->
+ io:format(" ok~n", []),
+ do_load(F, Opts),
+ do_compile(Fs, Opts);
+ {ok, _, _} ->
+ io:format(" ok~n", []),
+ do_load(F, Opts),
+ do_compile(Fs, Opts);
+ Err ->
+ io:format(" error: ~p~n", [Err]),
+ Err
+ end.
+
+do_load(File, Opts) ->
+ case lists:member(load, Opts) of
+ true ->
+ io:format("Loading file ~p", [File]),
+ code:purge(File),
+ R = code:load_abs(File),
+ io:format("Loaded: ~p", [R]);
+ false ->
+ ok
+ end.
+
+
+%% Check that ErrList consists of exactly Num errors of type ErrType
+check_errors(Num, ErrType, ErrList) ->
+ Num = length(ErrList),
+ lists:foreach(fun(T) ->
+ case catch element(1, element(4, T)) of
+ ErrType -> ok;
+ Else ->
+ test_server:fail({bad, ErrType, Else})
+ end end, ErrList).
+
+to_list(X) when is_atom(X) -> atom_to_list(X);
+to_list(X) -> X.
+
+
+%% File must be an atom
+gen_struct_file(File, Mod) ->
+
+ ?line {ok, Fd} = file:open(to_list(File)++".erl", [write]),
+ io:format(Fd, "~n", []),
+ io:format(Fd, "-module(~p).~n", [Mod]),
+ io:format(Fd, "-export([test/0]).~n", []),
+ io:format(Fd, "-include(\"oe_struct.hrl\").~n", []),
+ io:format(Fd, "test() ->~n", []),
+ io:format(Fd, " A = #'S1'{a=99, b=$a, s=\"123456789\"},~n", []),
+ io:format(Fd, " B = #'S2'{a=9, b=#'S2_S3'{a=1, b=9, b1=5, c=$2},~n", []),
+ io:format(Fd, " c=[#'S1'{a=1}, #'S1'{a=2}],~n", []),
+ io:format(Fd,
+" c2=[#'S1'{a=2}, #'S1'{a=3}, #'S1'{a=2}, #'S1'{a=3}]},~n", []),
+ io:format(Fd, " C = #'S2_S3'{a=11, b=999, b1=19},~n", []),
+ io:format(Fd, " D = #s4{a=7},~n", []),
+ io:format(Fd, " E = {1, #'U1_S5'{a=3}},~n", []),
+ io:format(Fd, " F = {2, {$b, #'U1_U2_s6'{a=6, b=false}}},~n", []),
+ io:format(Fd, " ok.~n", []),
+ file:close(Fd).
+
+
+union_norm_files() -> ['oe_u_norm'].
+union_default_files() -> ['oe_u_default', i1].
+
+typeid_files() -> ['oe_typeid', 'M3_M2_M1_I1', 'M2_M1_I1', 'M1_I1', 'I1'].
+
+struct_norm_files() -> ['oe_struct'].
+oneway_norm_files() -> ['oe_one', 'I1'].
+oneway_followed_files() -> ['oe_one_followed', 'I1'].
+nasty_names_files() -> ['oe_nasty', 'I2', 'I1'].
+
+inherit_norm_files() -> [m1_I3, m1_I2, m1_I1, 'oe_inherit', 'I4', 'I3',
+ 'I2', 'I1'].
+
+forward_files() -> [i1, 'oe_forward'].
+enum_norm_files() -> ['oe_enum'].
+const_norm_files() -> ['oe_c_norm'].
+attr_norm_files() -> ['oe_attr', 'I1', 'I2'].
+type_norm_files() -> ['oe_type'].
+
+raises_reg_files() -> ['oe_raises_reg'].
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/lib/ic/test/ic_SUITE_data/Corba.idl b/lib/ic/test/ic_SUITE_data/Corba.idl
new file mode 100644
index 0000000000..6b81132500
--- /dev/null
+++ b/lib/ic/test/ic_SUITE_data/Corba.idl
@@ -0,0 +1,1013 @@
+// This file contains OMG IDL from CORBA V2.0, July 1995.
+// Includes IDL for CORBA Core
+// (Interface Repository, ORB Interface, Basic Object Adapter Interface)
+// and CORBA Interoperability (IOP, GIOP, IIOP, and DCE CIOP modules)
+
+// Complete OMG IDL for Interface Repository starts on pg 6-42, CORBA V2.0 July 1995
+// IRObject interface described on pg 6-9 CORBA V2.0, July 1995
+// Contained interface: pg 6-11 CORBA V2, 7-95
+// Container interface: pg 6-12 thru 6-15 CORBA V2, 7-95
+// IDLType interface: pg 6-15 CORBA V2, 7-95
+// Repository interface: pg 6-16 CORBA V2, 7-95
+// ModuleDef interface: pg 6-17 CORBA V2, 7-95
+// ConstantDef interface: pg 6-18 CORBA V2, 7-95
+// TypeDef interface: pg 6-19 CORBA V2, 7-95
+// StructDef interface: pg 6-19 CORBA V2, 7-95
+// UnionDef interface: pg 6-19 CORBA V2, 7-95
+// EnumDef interface: pg 6-20 CORBA V2, 7-95
+// AliasDef interface: pg 6-21 CORBA V2, 7-95
+// PrimitiveDef interface: pg 6-21 CORBA V2, 7-95
+// StringDef interface: pg 6-22 CORBA V2, 7-95
+// SequenceDef interface: pg 6-22 CORBA V2, 7-95
+// ArrayDef interface: pg 6-23 CORBA V2, 7-95
+// ExceptionDef interface: pg 6-24 CORBA V2, 7-95
+// AttributeDef interface: pg 6-25 CORBA V2, 7-95
+// OperationDef interface: pg 6-26 CORBA V2, 7-95
+// InterfaceDef interface: pg 6-28 CORBA V2, 7-95
+// TypeCode interface (PIDL): pg 6-34 CORBA V2, 7-95
+// ORB interface: pg 6-40 CORBA V2, 7-95
+
+#ifndef __CORBA_IDL
+#define __CORBA_IDL
+
+// #pragma prefix "omg.org"
+module CORBA {
+
+ interface TypeCode;
+ typedef string Identifier;
+ typedef string ScopedName;
+ typedef string RepositoryId;
+
+ /*
+ * start of section added by Christian Blum
+ */
+
+ typedef enum new_type {NO,USER,SYSTEM_EXCEPTION} exception_type;
+
+ /**
+ * no definition for this type
+ */
+ interface ImplementationDef
+ {
+ };
+
+ /**
+ * no definition for this type
+ */
+ //interface Principal
+ struct Principal
+ {
+ string str;
+ };
+
+ /**
+ * no definition for this type
+ */
+ interface Environment
+ {
+
+ };
+
+ typedef unsigned long Flags;
+ typedef unsigned long Status;
+
+ struct NamedValue // PIDL
+ {
+ Identifier name; // argument name
+ any argument; // argument
+ long len; // length/count of argument value
+ Flags arg_modes; // argument mode flags
+
+ };
+
+ typedef sequence<NamedValue> NVList; /* C */
+
+ interface Request // PIDL
+ {
+
+ Status add_arg (
+ in Identifier name, // argument name
+ in TypeCode arg_type, // argument datatype
+ // in void * value, // argument value to be added
+ in any value_LOOK_AT_SOURCE, // changed by blum
+ in long len, // length/count of argument value
+ in Flags arg_flags // argument flags
+ );
+
+ Status invoke (
+ in Flags invoke_flags // invocation flags
+ );
+
+ Status delete ();
+ Status send (
+ in Flags invoke_flags // invocation flags
+ );
+
+ Status get_response (
+ in Flags response_flags // response flags
+ );
+
+ };
+
+
+ interface Context // PIDL
+ {
+
+ Status set_one_value (
+ in Identifier prop_name, // property name to add
+ in string value // property value to add
+ );
+
+ Status set_values (
+ in NVList values // property values to be changed
+ );
+
+ Status get_values (
+ in Identifier start_scope, // search scope
+ in Flags op_flags, // operation flags
+ in Identifier prop_name, // name of property(s) to retrieve
+ out NVList values // requested property(s)
+ );
+
+ Status delete_values (
+ in Identifier prop_name // name of property(s) to delete
+ );
+
+ Status create_child (
+ in Identifier ctx_name, // name of context object
+ out Context child_ctx // newly created context object
+ );
+
+ Status delete (
+ in Flags del_flags // flags controlling deletion
+ );
+
+ };
+
+ /*
+ * end of section added by Christian Blum
+ */
+
+
+ enum DefinitionKind {
+ dk_none, dk_all,
+ dk_Attribute, dk_Constant, dk_Exception, dk_Interface,
+ dk_Module, dk_Operation, dk_Typedef,
+ dk_Alias, dk_Struct, dk_Union, dk_Enum,
+ dk_Primitive, dk_String, dk_Sequence, dk_Array,
+ dk_Repository
+ };
+
+
+ interface IRObject {
+ // read interface
+ readonly attribute DefinitionKind def_kind;
+
+ // write interface
+ void destroy ();
+ };
+
+
+
+ typedef string VersionSpec;
+
+ interface Contained;
+ interface Repository;
+ interface Container;
+
+ interface Contained : IRObject {
+ // read/write interface
+
+ attribute RepositoryId id;
+ attribute Identifier name;
+ attribute VersionSpec version;
+
+ // read interface
+
+ readonly attribute Container defined_in;
+ readonly attribute ScopedName absolute_name;
+ readonly attribute Repository containing_repository;
+
+ struct Description {
+ DefinitionKind kind;
+ any value;
+ };
+
+ Description describe ();
+
+ // write interface
+
+ void move (
+ in Container new_container,
+ in Identifier new_name,
+ in VersionSpec new_version
+ );
+ };
+
+
+ interface ModuleDef;
+ interface ConstantDef;
+ interface IDLType;
+ interface StructDef;
+ interface UnionDef;
+ interface EnumDef;
+ interface AliasDef;
+ interface InterfaceDef;
+ typedef sequence <InterfaceDef> InterfaceDefSeq;
+
+ typedef sequence <Contained> ContainedSeq;
+
+ struct StructMember {
+ Identifier name;
+ TypeCode type;
+ IDLType type_def;
+ };
+ typedef sequence <StructMember> StructMemberSeq;
+
+ struct UnionMember {
+ Identifier name;
+ any label;
+ TypeCode type;
+ IDLType type_def;
+ };
+ typedef sequence <UnionMember> UnionMemberSeq;
+
+ typedef sequence <Identifier> EnumMemberSeq;
+
+ interface Container : IRObject {
+ // read interface
+
+ Contained lookup ( in ScopedName search_name);
+
+ ContainedSeq contents (
+ in DefinitionKind limit_type,
+ in boolean exclude_inherited
+ );
+
+ ContainedSeq lookup_name (
+ in Identifier search_name,
+ in long levels_to_search,
+ in DefinitionKind limit_type,
+ in boolean exclude_inherited
+ );
+
+ struct Description {
+ Contained contained_object;
+ DefinitionKind kind;
+ any value;
+ };
+
+ typedef sequence<Description> DescriptionSeq;
+
+ DescriptionSeq describe_contents (
+ in DefinitionKind limit_type,
+ in boolean exclude_inherited,
+ in long max_returned_objs
+ );
+
+ // write interface
+
+ ModuleDef create_module (
+ in RepositoryId id,
+ in Identifier name,
+ in VersionSpec version
+ );
+
+ ConstantDef create_constant (
+ in RepositoryId id,
+ in Identifier name,
+ in VersionSpec version,
+ in IDLType type,
+ in any value
+ );
+
+ StructDef create_struct (
+ in RepositoryId id,
+ in Identifier name,
+ in VersionSpec version,
+ in StructMemberSeq members
+ );
+
+ UnionDef create_union (
+ in RepositoryId id,
+ in Identifier name,
+ in VersionSpec version,
+ in IDLType discriminator_type,
+ in UnionMemberSeq members
+ );
+
+ EnumDef create_enum (
+ in RepositoryId id,
+ in Identifier name,
+ in VersionSpec version,
+ in EnumMemberSeq members
+ );
+
+ AliasDef create_alias (
+ in RepositoryId id,
+ in Identifier name,
+ in VersionSpec version,
+ in IDLType original_type
+ );
+
+ InterfaceDef create_interface (
+ in RepositoryId id,
+ in Identifier name,
+ in VersionSpec version,
+ in InterfaceDefSeq base_interfaces
+ );
+ };
+
+
+
+ interface IDLType : IRObject {
+ readonly attribute TypeCode type;
+ };
+
+
+
+ interface PrimitiveDef;
+ interface StringDef;
+ interface SequenceDef;
+ interface ArrayDef;
+
+ enum PrimitiveKind {
+ pk_null, pk_void, pk_short, pk_long, pk_ushort, pk_ulong,
+ pk_float, pk_double, pk_boolean, pk_char, pk_octet,
+ pk_any, pk_TypeCode, pk_Principal, pk_string, pk_objref
+ };
+
+ interface Repository : Container {
+ // read interface
+
+ Contained lookup_id (in RepositoryId search_id);
+
+ PrimitiveDef get_primitive (in PrimitiveKind kind);
+
+ // write interface
+
+ StringDef create_string (in unsigned long bound);
+
+ SequenceDef create_sequence (
+ in unsigned long bound,
+ in IDLType element_type
+ );
+
+ ArrayDef create_array (
+ in unsigned long length,
+ in IDLType element_type
+ );
+ };
+
+
+ interface ModuleDef : Container, Contained {
+ };
+
+ struct ModuleDescription {
+ Identifier name;
+ RepositoryId id;
+ RepositoryId defined_in;
+ VersionSpec version;
+ };
+
+
+ interface ConstantDef : Contained {
+ readonly attribute TypeCode type;
+ attribute IDLType type_def;
+ attribute any value;
+ };
+
+ struct ConstantDescription {
+ Identifier name;
+ RepositoryId id;
+ RepositoryId defined_in;
+ VersionSpec version;
+ TypeCode type;
+ any value;
+ };
+
+
+ interface TypedefDef : Contained, IDLType {
+ };
+
+ struct TypeDescription {
+ Identifier name;
+ RepositoryId id;
+ RepositoryId defined_in;
+ VersionSpec version;
+ TypeCode type;
+ };
+
+
+ interface StructDef : TypedefDef {
+ attribute StructMemberSeq members;
+ };
+
+
+ interface UnionDef : TypedefDef {
+ readonly attribute TypeCode discriminator_type;
+ attribute IDLType discriminator_type_def;
+ attribute UnionMemberSeq members;
+ };
+
+
+ interface EnumDef : TypedefDef {
+ attribute EnumMemberSeq members;
+ };
+
+
+ interface AliasDef : TypedefDef {
+ attribute IDLType original_type_def;
+ };
+
+
+ interface PrimitiveDef: IDLType {
+ readonly attribute PrimitiveKind kind;
+ };
+
+
+ interface StringDef : IDLType {
+ attribute unsigned long bound;
+ };
+
+
+ interface SequenceDef : IDLType {
+ attribute unsigned long bound;
+ readonly attribute TypeCode element_type;
+ attribute IDLType element_type_def;
+ };
+
+ interface ArrayDef : IDLType {
+ attribute unsigned long length;
+ readonly attribute TypeCode element_type;
+ attribute IDLType element_type_def;
+ };
+
+
+ interface ExceptionDef : Contained {
+ readonly attribute TypeCode type;
+ attribute StructMemberSeq members;
+ };
+ struct ExceptionDescription {
+ Identifier name;
+ RepositoryId id;
+ RepositoryId defined_in;
+ VersionSpec version;
+ TypeCode type;
+ };
+
+
+
+ enum AttributeMode {ATTR_NORMAL, ATTR_READONLY};
+
+ interface AttributeDef : Contained {
+ readonly attribute TypeCode type;
+ attribute IDLType type_def;
+ attribute AttributeMode mode;
+ };
+
+ struct AttributeDescription {
+ Identifier name;
+ RepositoryId id;
+ RepositoryId defined_in;
+ VersionSpec version;
+ TypeCode type;
+ AttributeMode mode;
+ };
+
+
+
+ enum OperationMode {OP_NORMAL, OP_ONEWAY};
+
+ enum ParameterMode {PARAM_IN, PARAM_OUT, PARAM_INOUT};
+ struct ParameterDescription {
+ Identifier name;
+ TypeCode type;
+ IDLType type_def;
+ ParameterMode mode;
+ };
+ typedef sequence <ParameterDescription> ParDescriptionSeq;
+
+ typedef Identifier ContextIdentifier;
+ typedef sequence <ContextIdentifier> ContextIdSeq;
+
+ typedef sequence <ExceptionDef> ExceptionDefSeq;
+ typedef sequence <ExceptionDescription> ExcDescriptionSeq;
+
+ interface OperationDef : Contained {
+ readonly attribute TypeCode result;
+ attribute IDLType result_def;
+ attribute ParDescriptionSeq params;
+ attribute OperationMode mode;
+ attribute ContextIdSeq contexts;
+ attribute ExceptionDefSeq exceptions;
+ };
+
+ struct OperationDescription {
+ Identifier name;
+ RepositoryId id;
+ RepositoryId defined_in;
+ VersionSpec version;
+ TypeCode result;
+ OperationMode mode;
+ ContextIdSeq contexts;
+ ParDescriptionSeq parameters;
+ ExcDescriptionSeq exceptions;
+ };
+
+
+
+ typedef sequence <RepositoryId> RepositoryIdSeq;
+ typedef sequence <OperationDescription> OpDescriptionSeq;
+ typedef sequence <AttributeDescription> AttrDescriptionSeq;
+
+ interface InterfaceDef : Container, Contained, IDLType {
+ // read/write interface
+
+ attribute InterfaceDefSeq base_interfaces;
+
+ // read interface
+
+ boolean is_a (in RepositoryId interface_id);
+
+ struct FullInterfaceDescription {
+ Identifier name;
+ RepositoryId id;
+ RepositoryId defined_in;
+ VersionSpec version;
+ OpDescriptionSeq operations;
+ AttrDescriptionSeq attributes;
+ RepositoryIdSeq base_interfaces;
+ TypeCode type;
+ };
+
+ FullInterfaceDescription describe_interface();
+
+ // write interface
+
+ AttributeDef create_attribute (
+ in RepositoryId id,
+ in Identifier name,
+ in VersionSpec version,
+ in IDLType type,
+ in AttributeMode mode
+ );
+
+ OperationDef create_operation (
+ in RepositoryId id,
+ in Identifier name,
+ in VersionSpec version,
+ in IDLType result,
+ in OperationMode mode,
+ in ParDescriptionSeq params,
+ in ExceptionDefSeq exceptions,
+ in ContextIdSeq contexts
+ );
+ };
+
+ struct InterfaceDescription {
+ Identifier name;
+ RepositoryId id;
+ RepositoryId defined_in;
+ VersionSpec version;
+ RepositoryIdSeq base_interfaces;
+ };
+
+
+
+ enum TCKind {
+ tk_null, tk_void,
+ tk_short, tk_long, tk_ushort, tk_ulong,
+ tk_float, tk_double, tk_boolean, tk_char,
+ tk_octet, tk_any, tk_TypeCode, tk_Principal, tk_objref,
+ tk_struct, tk_union, tk_enum, tk_string,
+ tk_sequence, tk_array, tk_alias, tk_except
+ };
+
+ interface TypeCode { // PIDL
+ exception Bounds {};
+ exception BadKind {};
+
+ // for all TypeCode kinds
+ boolean equal (in TypeCode tc);
+ TCKind kind ();
+
+ // for tk_objref, tk_struct, tk_union, tk_enum, tk_alias, and tk_except
+ RepositoryId id () raises (BadKind);
+
+ // for tk_objref, tk_struct, tk_union, tk_enum, tk_alias, and tk_except
+ Identifier name () raises (BadKind);
+
+ // for tk_struct, tk_union, tk_enum, and tk_except
+ unsigned long member_count () raises (BadKind);
+ Identifier member_name (in unsigned long index) raises (BadKind, Bounds);
+
+ // for tk_struct, tk_union, and tk_except
+ TypeCode member_type (in unsigned long index) raises (BadKind, Bounds);
+
+ // for tk_union
+ any member_label (in unsigned long index) raises (BadKind, Bounds);
+ TypeCode discriminator_type () raises (BadKind);
+ long default_index () raises (BadKind);
+
+ // for tk_string, tk_sequence, and tk_array
+ unsigned long length () raises (BadKind);
+
+ // for tk_sequence, tk_array, and tk_alias
+ TypeCode content_type () raises (BadKind);
+
+ // deprecated interface
+ long param_count ();
+ any parameter (in long index) raises (Bounds);
+ };
+
+
+ /*
+ * following line added by Christian Blum
+ */
+ interface BOA;
+
+ interface ORB {
+ // other operations ...
+
+ TypeCode create_struct_tc (
+ in RepositoryId id,
+ in Identifier name,
+ in StructMemberSeq members
+ );
+
+ TypeCode create_union_tc (
+ in RepositoryId id,
+ in Identifier name,
+ in TypeCode discriminator_type,
+ in UnionMemberSeq members
+ );
+
+ TypeCode create_enum_tc (
+ in RepositoryId id,
+ in Identifier name,
+ in EnumMemberSeq members
+ );
+
+ TypeCode create_alias_tc (
+ in RepositoryId id,
+ in Identifier name,
+ in TypeCode original_type
+ );
+
+ TypeCode create_exception_tc (
+ in RepositoryId id,
+ in Identifier name,
+ in StructMemberSeq members
+ );
+
+ TypeCode create_interface_tc (
+ in RepositoryId id,
+ in Identifier name
+ );
+
+ TypeCode create_string_tc (
+ in unsigned long bound
+ );
+
+ TypeCode create_sequence_tc (
+ in unsigned long bound,
+ in TypeCode element_type
+ );
+
+ TypeCode create_recursive_sequence_tc (
+ in unsigned long bound,
+ in unsigned long offset
+ );
+
+ TypeCode create_array_tc (
+ in unsigned long length,
+ in TypeCode element_type
+ );
+
+ /*
+ * following line commented out by Christian Blum
+ */
+ // };
+
+ // The ORB interface (PIDL) is described in Chapter 7, CORBA V2.0 July 1995
+ // Object interface (object reference operations): pg 7-3 CORBA V2, 7-95
+ // ORB initialization: pg 7-7 CORBA V2, 7-95
+ // Object Adapter and Basic Object Adapter initialization: pg 7-8 CORBA V2 7-95
+ // Getting initial references: pg 7-10 CORBA V2 7-95
+ //PIDL
+
+ /*
+ * following line commented out by Christian Blum
+ */
+ //interface ORB {
+
+
+ string object_to_string (in Object obj);
+ Object string_to_object (in string str);
+
+ Status create_list (
+ in long count,
+ out NVList new_list
+ );
+ Status create_operation_list (
+ in OperationDef oper,
+ out NVList new_list
+ );
+ Status get_default_context (out Context ctx);
+
+ // Initializing the ORB
+ typedef string ORBid;
+ typedef sequence <string> arg_list;
+ ORB ORB_init (inout arg_list argv, in ORBid orb_identifier);
+
+ // Initializing an object adapter and the Basic Object Adapter
+ typedef string OAid;
+
+ // Template for OA initialization operations
+ // <OA> <OA>_init (inout arg_list argv,
+ // in OAid oa_identifier);
+
+
+
+ BOA BOA_init (inout arg_list argv,
+ in OAid boa_identifier);
+
+
+
+ // Getting initial object references
+ typedef string ObjectId;
+ typedef sequence <ObjectId> ObjectIdList;
+
+ exception InvalidName {};
+
+ ObjectIdList list_initial_services ();
+
+ Object resolve_initial_references (in ObjectId identifier)
+ raises (InvalidName);
+ };
+
+ // had to be changed..., Gerald Brose 1996
+ interface ORBject {
+
+ ImplementationDef get_implementation ();
+ InterfaceDef get_interface ();
+ boolean is_nil();
+ Object duplicate ();
+ void release ();
+ boolean is_a (in string logical_type_id);
+ boolean non_existent();
+ boolean is_equivalent (in Object other_object);
+ unsigned long hash(in unsigned long maximum);
+
+
+ Status create_request (
+ in Context ctx,
+ in Identifier operation,
+ in NVList arg_list,
+ inout NamedValue result,
+ out Request request,
+ in Flags req_flags
+ );
+ };
+
+
+ // Basic Object Adapter interface described in Chapter 8, CORBA V2.0, July 1995
+ // interface InterfaceDef; // from Interface Repository // PIDL
+ // interface ImplementationDef; // from Implementation Repository
+ // interface Object; // an object reference
+ // interface Principal; // for the authentication service
+ typedef sequence <octet, 1024> ReferenceData;
+
+ interface BOA {
+ Object create (
+ in ReferenceData id,
+ in InterfaceDef intf,
+ in ImplementationDef impl
+ );
+ void dispose (in Object obj);
+ ReferenceData get_id (in Object obj);
+
+ void change_implementation (in Object obj,
+ in ImplementationDef impl
+ );
+
+ Principal get_principal (in Object obj,
+ in Environment ev
+ );
+
+ void set_exception (in exception_type major, // NO, USER,
+ //or SYSTEM_EXCEPTION
+ in string userid, // exception type id
+ in any param_LOOK_AT_SOURCE
+ // in void *param // pointer to associated data
+ );
+
+ void impl_is_ready (in ImplementationDef impl);
+ void deactivate_impl (in ImplementationDef impl);
+ void obj_is_ready (in Object obj, in ImplementationDef impl);
+ void deactivate_obj (in Object obj);
+ };
+};
+
+// IOP module described in chap 10 CORBA V2, 7-95
+module IOP{ // IDL
+ //
+ // Standard Protocol Profile tag values
+ //
+ typedef unsigned long ProfileId;
+ const ProfileId TAG_INTERNET_IOP = 0;
+ const ProfileId TAG_MULTIPLE_COMPONENTS = 1;
+
+ struct TaggedProfile {
+ ProfileId tag;
+ sequence <octet> profile_data;
+ };
+
+ //
+ // an Interoperable Object Reference is a sequence of
+ // object-specific protocol profiles, plus a type ID.
+ //
+ struct IOR {
+ string type_id;
+ sequence <TaggedProfile> profiles;
+ };
+
+ //
+ // Standard way of representing multicomponent profiles.
+ // This would be encapsulated in a TaggedProfile.
+ //
+ typedef unsigned long ComponentId;
+ struct TaggedComponent {
+ ComponentId tag;
+ sequence <octet> component_data;
+ };
+ typedef sequence <TaggedComponent> MultipleComponentProfile;
+
+
+ typedef unsigned long ServiceID;
+
+ struct ServiceContext {
+ ServiceID context_id;
+ sequence <octet> context_data;
+ };
+ typedef sequence <ServiceContext> ServiceContextList;
+
+ const ServiceID TransactionService = 0;
+
+
+
+};
+// GIOP module described in CORBA V2, 7-95 chap 12
+// Complete IDL for GIOP module in CORBA
+// V2.0, 7-95 p 10-29
+// GIOP message header: CORBA V2, 7-95 p 12-16
+// GIOP request header: CORBA V2, 7-95 p 12-17
+// GIOP reply header: CORBA V2, 7-95 p 12-19
+// GIOP cancel request and locate request: CORBA V2, 7-95 pp 12-20 -- 12-21
+// GIOP locate reply: CORBA V2, 7-95 p 12-22
+module GIOP { // IDL
+ enum MsgType {
+ Request, Reply, CancelRequest,
+ LocateRequest, LocateReply,
+ CloseConnection, MessageError
+ };
+
+ struct Version {
+ char major;
+ char minor;
+ };
+
+ struct MessageHeader {
+ char magic [4];
+ Version GIOP_version;
+ boolean byte_order;
+ octet message_type;
+ unsigned long message_size;
+ };
+
+ struct RequestHeader {
+ ::IOP::ServiceContextList service_context;
+ unsigned long request_id;
+ boolean response_expected;
+ sequence <octet> object_key;
+ string operation;
+
+ /*
+ * ::CORBA:: added for correct scope
+ */
+ ::CORBA::Principal requesting_principal;
+ };
+
+ enum ReplyStatusType {
+ NO_EXCEPTION,
+ USER_EXCEPTION,
+ SYSTEM_EXCEPTION,
+ LOCATION_FORWARD
+ };
+
+ struct ReplyHeader {
+ ::IOP::ServiceContextList service_context;
+ unsigned long request_id;
+ ReplyStatusType reply_status;
+ };
+
+ struct CancelRequestHeader {
+ unsigned long request_id;
+ };
+
+ struct LocateRequestHeader {
+ unsigned long request_id;
+ sequence <octet> object_key;
+ };
+
+ enum LocateStatusType {
+ UNKNOWN_OBJECT,
+ OBJECT_HERE,
+ OBJECT_FORWARD
+ };
+
+ struct LocateReplyHeader {
+ unsigned long request_id;
+ LocateStatusType locate_status;
+ };
+};
+// IIOP module described in CORBA V2, 7-95 chap 12
+// Complete IDL for IIOP module: CORBA V2, 7-95 p 12-31
+module IIOP { // IDL
+ struct Version {
+ char major;
+ char minor;
+ };
+
+ struct ProfileBody {
+ Version iiop_version;
+ string host;
+ unsigned short port;
+ sequence <octet> object_key;
+ };
+};
+// DCE CIOP module described in CORBA V2, 7-95 chap 13
+// IDL for DCE CIOP module: CORBA V2, 7-95 p 13-2
+module DCE_CIOP {
+ struct InvokeRequestHeader {
+ boolean byte_order;
+ ::IOP::ServiceContextList service_context;
+ sequence <octet> object_key;
+ string endpoint_id;
+ string operation;
+ ::CORBA::Principal principal;
+ sequence <string> client_context;
+
+ // in and inout parameters follow
+ };
+ enum InvokeResponseStatus {
+ INVOKE_NO_EXCEPTION,
+ INVOKE_USER_EXCEPTION,
+ INVOKE_SYSTEM_EXCEPTION,
+ INVOKE_LOCATION_FORWARD,
+ INVOKE_TRY_AGAIN
+ };
+
+ struct InvokeResponseHeader {
+ boolean byte_order;
+ ::IOP::ServiceContextList service_context;
+ InvokeResponseStatus status;
+
+ // if status = INVOKE_NO_EXCEPTION,
+ // result then inouts and outs follow
+
+ // if status = INVOKE_USER_EXCEPTION or
+ // INVOKE_SYSTEM_EXCEPTION, an exception follows
+
+ // if status = INVOKE_LOCATION_FORWARD, an
+ // ::IOP::MultipleComponentsProfile follows
+ };
+
+ struct LocateRequestHeader {
+ boolean byte_order;
+ sequence <octet> object_key;
+ string endpoint_id;
+ string operation;
+
+ // no body follows
+ };
+
+ module IOP {
+
+ /*
+ * ::IOP:: added to get the right scope
+ */
+ const ::IOP::ComponentId TAG_OBJECT_KEY = 10;
+ const ::IOP::ComponentId TAG_ENDPOINT_ID = 11;
+ const ::IOP::ComponentId TAG_LOCATION_POLICY = 12;
+ // illegal IDL
+ /* const octet LOCATE_NEVER = 0;
+ const octet LOCATE_OBJECT = 1;
+ const octet LOCATE_OPERATION = 2;
+ const octet LOCATE_ALWAYS = 3;
+ */
+ };
+};
+
+#endif
diff --git a/lib/ic/test/ic_SUITE_data/Coss.idl b/lib/ic/test/ic_SUITE_data/Coss.idl
new file mode 100644
index 0000000000..c84d4a8247
--- /dev/null
+++ b/lib/ic/test/ic_SUITE_data/Coss.idl
@@ -0,0 +1,1537 @@
+// This file contains OMG IDL and PIDL for the Common Object Services.
+// CosNaming Module, p 3-6 CORBAservices, Naming Service V1.0, 3/94
+
+// A few minor changes for the JacORB distribution:
+//
+// added am enclosing COSS module and changed scoped names accordingly
+//
+// corrected a few syntax errors
+//
+// commented out:
+// #includes
+// forward declaration of Object
+
+#include "Corba.idl"
+
+module COSS {
+
+module CosNaming {
+
+ typedef string Istring;
+ struct NameComponent {
+ Istring id;
+ Istring kind;
+ };
+
+ typedef sequence <NameComponent> Name;
+
+ enum BindingType {nobject, ncontext};
+
+ struct Binding {
+ Name binding_name;
+ BindingType binding_type;
+ };
+
+ typedef sequence <Binding> BindingList;
+ interface BindingIterator;
+
+ interface NamingContext {
+
+ enum NotFoundReason { missing_node, not_context, not_object};
+
+ exception NotFound {
+ NotFoundReason why;
+ Name rest_of_name;
+ };
+
+ exception CannotProceed {
+ NamingContext cxt;
+ Name rest_of_name;
+ };
+
+ exception InvalidName{};
+ exception AlreadyBound {};
+ exception NotEmpty{};
+
+ void bind(in Name n, in Object obj)
+ raises(NotFound, CannotProceed, InvalidName, AlreadyBound);
+ void rebind(in Name n, in Object obj)
+ raises(NotFound, CannotProceed, InvalidName);
+ void bind_context(in Name n, in NamingContext nc)
+ raises(NotFound, CannotProceed, InvalidName, AlreadyBound);
+ void rebind_context(in Name n, in NamingContext nc)
+ raises(NotFound, CannotProceed, InvalidName);
+ Object resolve (in Name n)
+ raises(NotFound, CannotProceed, InvalidName);
+ void unbind(in Name n)
+ raises(NotFound, CannotProceed, InvalidName);
+ NamingContext new_context();
+ NamingContext bind_new_context(in Name n)
+ raises(NotFound, AlreadyBound, CannotProceed, InvalidName);
+ void destroy( )
+ raises(NotEmpty);
+ void list (in unsigned long how_many,
+ out BindingList bl, out BindingIterator bi);
+ };
+
+ interface BindingIterator {
+ boolean next_one(out Binding b);
+ boolean next_n(in unsigned long how_many,
+ out BindingList bl);
+ void destroy();
+ };
+};
+
+// Names Library interface in PIDL, CORBAservices p 3- 14, Naming Service V1.0 3/94
+/*
+interface LNameComponent { // PIDL
+ exception NotSet{};
+ string get_id()
+ raises(NotSet);
+ void set_id(in string i);
+ string get_kind()
+ raises(NotSet);
+ void set_kind(in string k);
+ void destroy();
+};
+
+interface LName { // PIDL
+ exception NoComponent{};
+ exception OverFlow{};
+ exception InvalidName{};
+ LName insert_component(in unsigned long i,
+ in LNameComponent n)
+ raises(NoComponent, OverFlow);
+ LNameComponent get_component(in unsigned long i)
+ raises(NoComponent);
+ LNameComponent delete_component(in unsigned long i)
+ raises(NoComponent);
+ unsigned long num_components();
+ boolean equal(in LName ln);
+ boolean less_than(in LName ln);
+ Name to_idl_form()
+ raises(InvalidName);
+ void from_idl_form(in Name n);
+ void destroy();
+};
+
+LName create_lname(); // C/C++
+LNameComponent create_lname_component(); // C/C++
+*/
+
+// CosEventComm Module, CORBAservices p 4-8, Event Service V1.0 3/94
+
+module CosEventComm {
+
+ exception Disconnected{};
+
+ interface PushConsumer {
+ void push (in any data) raises(Disconnected);
+ void disconnect_push_consumer();
+ };
+
+ interface PushSupplier {
+ void disconnect_push_supplier();
+ };
+
+ interface PullSupplier {
+ any pull () raises(Disconnected);
+ any try_pull (out boolean has_event)
+ raises(Disconnected);
+ void disconnect_pull_supplier();
+ };
+
+ interface PullConsumer {
+ void disconnect_pull_consumer();
+ };
+
+};
+
+// CosEventChannelAdmin Module, p 4-15 CORBAservices, Event
+// Service V1.0, 3/94
+
+// #include "CosEventComm.idl"
+
+module CosEventChannelAdmin {
+
+ exception AlreadyConnected {};
+ exception TypeError {};
+
+ interface ProxyPushConsumer: ::COSS::CosEventComm::PushConsumer {
+ void connect_push_supplier(
+ in ::COSS::CosEventComm::PushSupplier push_supplier)
+ raises(AlreadyConnected);
+ };
+
+ interface ProxyPullSupplier: ::COSS::CosEventComm::PullSupplier {
+ void connect_pull_consumer(
+ in ::COSS::CosEventComm::PullConsumer pull_consumer)
+ raises(AlreadyConnected);
+ };
+
+ interface ProxyPullConsumer: ::COSS::CosEventComm::PullConsumer {
+ void connect_pull_supplier(
+ in ::COSS::CosEventComm::PullSupplier pull_supplier)
+ raises(AlreadyConnected,TypeError);
+ };
+
+ interface ProxyPushSupplier: ::COSS::CosEventComm::PushSupplier {
+ void connect_push_consumer(
+ in ::COSS::CosEventComm::PushConsumer
+ push_consumer)
+ raises(AlreadyConnected, TypeError);
+ };
+
+
+ interface ConsumerAdmin {
+ ProxyPushSupplier obtain_push_supplier();
+ ProxyPullSupplier obtain_pull_supplier();
+ };
+
+ interface SupplierAdmin {
+ ProxyPushConsumer obtain_push_consumer();
+ ProxyPullConsumer obtain_pull_consumer();
+ };
+
+ interface EventChannel {
+ ConsumerAdmin for_consumers();
+ SupplierAdmin for_suppliers();
+ void destroy();
+ };
+
+};
+
+
+// CosTyped Event Module, p 4-22 CORBAservices, Event Service
+// V1.0, 3/94
+
+// // #include "CosEventComm.idl"
+
+module CosTypedEventComm {
+
+ interface TypedPushConsumer : ::COSS::CosEventComm::PushConsumer {
+ Object get_typed_consumer();
+ };
+
+ interface TypedPullSupplier : ::COSS::CosEventComm::PullSupplier {
+ Object get_typed_supplier();
+ };
+
+};
+
+// CosTypedEventChannelAdmin Module, p 4- 25 CORBAservices,
+// Event Service V1.0, 3/94
+
+// // #include "CosEventChannel.idl"
+// // #include "CosTypedEventComm.idl"
+module CosTypedEventChannelAdmin {
+ exception InterfaceNotSupported {};
+ exception NoSuchImplementation {};
+ typedef string Key;
+
+ interface TypedProxyPushConsumer :
+ ::COSS::CosEventChannelAdmin::ProxyPushConsumer,
+ ::COSS::CosTypedEventComm::TypedPushConsumer { };
+
+ interface TypedProxyPullSupplier :
+ ::COSS::CosEventChannelAdmin::ProxyPullSupplier,
+ ::COSS::CosTypedEventComm::TypedPullSupplier { };
+
+ interface TypedSupplierAdmin :
+ ::COSS::CosEventChannelAdmin::SupplierAdmin {
+ TypedProxyPushConsumer obtain_typed_push_consumer(
+ in Key supported_interface)
+ raises(InterfaceNotSupported);
+ ::COSS::CosEventChannelAdmin::ProxyPullConsumer obtain_typed_pull_consumer (
+ in Key uses_interface)
+ raises(NoSuchImplementation);
+ };
+
+ interface TypedConsumerAdmin :
+ ::COSS::CosEventChannelAdmin::ConsumerAdmin {
+ TypedProxyPullSupplier obtain_typed_pull_supplier(
+ in Key supported_interface)
+ raises (InterfaceNotSupported);
+ ::COSS::CosEventChannelAdmin::ProxyPushSupplier obtain_typed_push_supplier(
+ in Key uses_interface)
+ raises(NoSuchImplementation);
+ };
+
+ interface TypedEventChannel {
+ TypedConsumerAdmin for_consumers();
+ TypedSupplierAdmin for_suppliers();
+ void destroy ();
+ };
+};
+
+
+// CosPersistencePID Module, p 5-20 CORBAservices,
+// Persistent Object Service V1.0, 3/94
+
+//#ifndef __COSPERSISTENCE
+//#define __COSPERSISTENCE
+
+module CosPersistencePID {
+
+ interface PID {
+ attribute string datastore_type;
+ string get_PIDString();
+ };
+};
+
+
+// CosPersistencePDS Module, p 5-20 CORBAservices,
+// Persistent Object Service V1.0, 3/94
+
+// #include "CosPersistencePID.idl"
+
+module CosPersistencePDS {
+
+// interface Object;
+ interface PDS {
+ PDS connect (in Object obj,
+ in ::COSS::CosPersistencePID::PID p);
+ void disconnect (in Object obj,
+ in ::COSS::CosPersistencePID::PID p);
+ void store (in Object obj,
+ in ::COSS::CosPersistencePID::PID p);
+ void restore (in Object obj,
+ in ::COSS::CosPersistencePID::PID p);
+ void delete (in Object obj,
+ in ::COSS::CosPersistencePID::PID p);
+ };
+};
+
+
+// CosPersistencePO Module, p 5-12 CORBAservices,
+// Persistent Object Service V1.0, 3/94
+
+// // #include "CosPersistencePDS.idl"
+// CosPersistencePDS.idl
+// // #includes CosPersistencePID.idl
+
+module CosPersistencePO {
+
+ interface PO {
+ attribute ::COSS::CosPersistencePID::PID p;
+ ::COSS::CosPersistencePDS::PDS connect (
+ in ::COSS::CosPersistencePID::PID p);
+ void disconnect (in ::COSS::CosPersistencePID::PID p);
+ void store (in ::COSS::CosPersistencePID::PID p);
+ void restore (in ::COSS::CosPersistencePID::PID p);
+ void delete (in ::COSS::CosPersistencePID::PID p);
+ };
+
+ interface SD {
+ void pre_store();
+ void post_restore();
+ };
+};
+
+
+// CosPersistencePOM Module, p 5-15 CORBAservices,
+// Persistent Object Service V1.0, 3/94
+
+// #include "CosPersistencePDS.idl"
+
+// CosPersistencePDS.idl // #includes CosPersistencePID.idl
+
+module CosPersistencePOM {
+
+// interface Object;
+
+ interface POM {
+ ::COSS::CosPersistencePDS::PDS connect (
+ in Object obj,
+ in ::COSS::CosPersistencePID::PID p);
+ void disconnect (
+ in Object obj,
+ in ::COSS::CosPersistencePID::PID p);
+ void store (
+ in Object obj,
+ in ::COSS::CosPersistencePID::PID p);
+ void restore (
+ in Object obj,
+ in ::COSS::CosPersistencePID::PID p);
+ void delete (
+ in Object obj,
+ in ::COSS::CosPersistencePID::PID p);
+ };
+ };
+
+// CosPersistencePDS_DA Module, p 5-22 CORBAservices,
+// Persistent Object Service, V1.0, 3/94
+
+// #include "CosPersistencePDS.idl"
+// CosPersistencePDS.idl // #includes CosPersistencePID.idl
+
+module CosPersistencePDS_DA {
+
+ typedef string DAObjectID;
+
+ interface PID_DA : ::COSS::CosPersistencePID::PID {
+ attribute DAObjectID oid;
+ };
+
+ interface DAObject {
+ boolean dado_same(in DAObject d);
+ DAObjectID dado_oid();
+ PID_DA dado_pid();
+ void dado_remove();
+ void dado_free();
+ };
+
+ interface DAObjectFactory {
+ DAObject create();
+ };
+
+ interface DAObjectFactoryFinder {
+ DAObjectFactory find_factory(in string key);
+ };
+
+ interface PDS_DA : ::COSS::CosPersistencePDS::PDS {
+ DAObject get_data();
+ void set_data(in DAObject new_data);
+ DAObject lookup(in DAObjectID id);
+ PID_DA get_pid();
+ PID_DA get_object_pid(in DAObject dao);
+ DAObjectFactoryFinder data_factories();
+ };
+
+ typedef sequence<string> AttributeNames;
+ interface DynamicAttributeAccess {
+ AttributeNames attribute_names();
+ any attribute_get(in string name);
+ void attribute_set(in string name, in any value);
+ };
+
+ typedef string ClusterID;
+ typedef sequence<ClusterID> ClusterIDs;
+ interface PDS_ClusteredDA : PDS_DA{
+ ClusterID cluster_id();
+ string cluster_kind();
+ ClusterIDs clusters_of();
+ PDS_ClusteredDA create_cluster(in string kind);
+ PDS_ClusteredDA open_cluster(in ClusterID cluster);
+ PDS_ClusteredDA copy_cluster(
+ in PDS_DA source);
+ };
+};
+
+// CosPersistenceDDO Module, p 5-32 CORBAservices, Persistent Object Service V1.0, 3/94
+
+// #include "CosPersistencePID.idl"
+module CosPersistenceDDO {
+
+ interface DDO {
+ attribute string object_type;
+ attribute ::COSS::CosPersistencePID::PID p;
+ short add_data();
+ short add_data_property (in short data_id);
+ short get_data_count();
+ short get_data_property_count (in short data_id);
+ void get_data_property (in short data_id,
+ in short property_id,
+ out string property_name,
+ out any property_value);
+ void set_data_property (in short data_id,
+ in short property_id,
+ in string property_name,
+ in any property_value);
+ void get_data (in short data_id,
+ out string data_name,
+ out any data_value);
+ void set_data (in short data_id,
+ in string data_name,
+ in any data_value);
+ };
+};
+
+// CosPersistenceDS_CLI module, p 5-34 CORBAservices,
+// Persistent Object Service V1.0, 3/94
+
+// #include "CosPersistenceDDO.idl"
+// CosPersistenceDDO.idl // #includes CosPersistencePID.idl
+
+module CosPersistenceDS_CLI {
+ interface UserEnvironment {
+ void set_option (in long option,in any value);
+ void get_option (in long option,out any value);
+ void release();
+ };
+
+ interface Connection {
+ void set_option (in long option,in any value);
+ void get_option (in long option,out any value);
+ };
+
+ interface ConnectionFactory {
+ Connection create_object (
+ in UserEnvironment user_envir);
+ };
+
+ interface Cursor {
+ void set_position (in long position,in any value);
+ ::COSS::CosPersistenceDDO::DDO fetch_object();
+ };
+
+ interface CursorFactory {
+ Cursor create_object (
+ in Connection connection);
+ };
+
+ interface PID_CLI : ::COSS::CosPersistencePID::PID {
+ attribute string datastore_id;
+ attribute string id;
+ };
+
+
+
+ interface Datastore_CLI {
+ void connect (in Connection connection,
+ in string datastore_id,
+ in string user_name,
+ in string authentication);
+ void disconnect (in Connection connection);
+ Connection get_connection (
+ in string datastore_id,
+ in string user_name);
+ void add_object (in Connection connection,
+ in ::COSS::CosPersistenceDDO::DDO data_obj);
+ void delete_object (
+ in Connection connection,
+ in ::COSS::CosPersistenceDDO::DDO data_obj);
+ void update_object (
+ in Connection connection,
+ in ::COSS::CosPersistenceDDO::DDO data_obj);
+ void retrieve_object(
+ in Connection connection,
+ in ::COSS::CosPersistenceDDO::DDO data_obj);
+ Cursor select_object(
+ in Connection connection,
+ in string key);
+ void transact (in UserEnvironment user_envir,
+ in short completion_type);
+ void assign_PID (in PID_CLI p);
+ void assign_PID_relative (
+ in PID_CLI source_pid,
+ in PID_CLI target_pid);
+ boolean is_identical_PID (
+ in PID_CLI pid_1,
+ in PID_CLI pid_2);
+ string get_object_type (in PID_CLI p);
+ void register_mapping_schema (in string schema_file);
+ Cursor execute (in Connection connection,
+ in string command);
+ };
+
+};
+
+
+// CosLifeCycle Module, p 6-10 CORBAservices, LifeCycle Service V1.0, 3/94
+
+// #include "Naming.idl"
+
+module CosLifeCycle
+{
+ typedef ::COSS::CosNaming::Name Key;
+ typedef Object Factory;
+ typedef sequence <Factory> Factories;
+ typedef struct NVP {
+ ::COSS::CosNaming::Istring name;
+ any value;
+ } NameValuePair;
+ typedef sequence <NameValuePair> Criteria;
+
+ exception NoFactory {
+ Key search_key;
+ };
+ exception NotCopyable { string reason; };
+ exception NotMovable { string reason; };
+ exception NotRemovable { string reason; };
+ exception InvalidCriteria{
+ Criteria invalid_criteria;
+ };
+ exception CannotMeetCriteria {
+ Criteria unmet_criteria;
+ };
+
+
+ interface FactoryFinder {
+ Factories find_factories(in Key factory_key)
+ raises(NoFactory);
+ };
+
+ interface LifeCycleObject {
+ LifeCycleObject copy(in FactoryFinder there,
+ in Criteria the_criteria)
+ raises(NoFactory, NotCopyable, InvalidCriteria,
+ CannotMeetCriteria);
+ void move(in FactoryFinder there,
+ in Criteria the_criteria)
+ raises(NoFactory, NotMovable, InvalidCriteria,
+ CannotMeetCriteria);
+ void remove()
+ raises(NotRemovable);
+ };
+
+ interface GenericFactory {
+ boolean supports(in Key k);
+ Object create_object(
+ in Key k,
+ in Criteria the_criteria)
+ raises (NoFactory, InvalidCriteria,
+ CannotMeetCriteria);
+ };
+};
+
+
+
+// LifeCycleService Module, p 6- 55 CORBAservices, Life Cycle
+// Service V1.0, 3/94
+
+// #include "LifeCycle.idl"
+
+module LifeCycleService {
+
+ typedef sequence <::COSS::CosLifeCycle::NameValuePair> PolicyList;
+ typedef sequence <::COSS::CosLifeCycle::Key> Keys;
+ typedef sequence <::COSS::CosLifeCycle::NameValuePair> PropertyList;
+ typedef sequence <::COSS::CosNaming::NameComponent> NameComponents;
+
+ interface LifeCycleServiceAdmin {
+
+ attribute PolicyList policies;
+
+ void bind_generic_factory(
+ in ::COSS::CosLifeCycle::GenericFactory gf,
+ in ::COSS::CosNaming::NameComponent name,
+ in Keys key_set,
+ in PropertyList other_properties)
+ raises (::COSS::CosNaming::NamingContext::AlreadyBound, ::COSS::CosNaming::NamingContext::InvalidName);
+
+ void unbind_generic_factory(
+ in ::COSS::CosNaming::NameComponent name)
+ raises (::COSS::CosNaming::NamingContext::NotFound, ::COSS::CosNaming::NamingContext::InvalidName);
+
+ ::COSS::CosLifeCycle::GenericFactory resolve_generic_factory(
+ in ::COSS::CosNaming::NameComponent name)
+ raises (::COSS::CosNaming::NamingContext::NotFound, ::COSS::CosNaming::NamingContext::InvalidName);
+
+ NameComponents list_generic_factories();
+
+ boolean match_service (in ::COSS::CosLifeCycle::GenericFactory f);
+
+ string get_hint();
+
+ void get_link_properties(
+ in ::COSS::CosNaming::NameComponent name,
+ out Keys key_set,
+ out PropertyList other_properties)
+ raises (::COSS::CosNaming::NamingContext::NotFound, ::COSS::CosNaming::NamingContext::InvalidName);
+ };
+};
+
+// CosTransactions Module, p 10-66
+// CORBAservices, Transaction Service V1.0, 3/94
+
+module CosTransactions {
+// DATATYPES
+enum Status {
+ StatusActive,
+ StatusMarkedRollback,
+ StatusPrepared,
+ StatusCommitted,
+ StatusRolledBack,
+ StatusUnknown,
+ StatusNoTransaction
+};
+
+enum Vote {
+ VoteCommit,
+ VoteRollback,
+ VoteReadOnly
+};
+
+// Standard exceptions
+exception TransactionRequired {};
+exception TransactionRolledBack {};
+exception InvalidTransaction {};
+
+// Heuristic exceptions
+exception HeuristicRollback {};
+exception HeuristicCommit {};
+exception HeuristicMixed {};
+exception HeuristicHazard {};
+
+// Exception from Orb operations
+exception WrongTransaction {};
+
+// Other transaction-specific exceptions
+exception SubtransactionsUnavailable {};
+exception NotSubtransaction {};
+exception Inactive {};
+exception NotPrepared {};
+exception NoTransaction {};
+exception InvalidControl {};
+exception Unavailable {};
+
+// Forward references for interfaces defined later in module
+interface Control;
+interface Terminator;
+interface Coordinator;
+interface Resource;
+interface RecoveryCoordinator;
+interface SubtransactionAwareResource;
+interface TransactionFactory;
+interface TransactionalObject;
+interface Current;
+
+// Current transaction pseudo object (PIDL)
+ interface Current {
+ void begin()
+ raises(SubtransactionsUnavailable);
+ void commit(in boolean report_heuristics)
+ raises(
+ NoTransaction,
+ HeuristicMixed,
+ HeuristicHazard
+ );
+ void rollback()
+ raises(NoTransaction);
+ void rollback_only()
+ raises(NoTransaction);
+
+ Status get_status();
+ string get_transaction_name();
+ void set_timeout(in unsigned long seconds);
+
+ Control get_control();
+ Control suspend();
+ void resume(in Control which)
+ raises(InvalidControl);
+ };
+
+ interface TransactionFactory {
+ Control create(in unsigned long time_out);
+ };
+
+ interface Control {
+ Terminator get_terminator()
+ raises(Unavailable);
+ Coordinator get_coordinator()
+ raises(Unavailable);
+ };
+
+ interface Terminator {
+ void commit(in boolean report_heuristics)
+ raises(
+ HeuristicMixed,
+ HeuristicHazard
+ );
+ void rollback();
+ };
+
+
+ interface Coordinator {
+
+ Status get_status();
+ Status get_parent_status();
+ Status get_top_level_status();
+
+ boolean is_same_transaction(in Coordinator tc);
+ boolean is_related_transaction(in Coordinator tc);
+ boolean is_ancestor_transaction(in Coordinator tc);
+ boolean is_descendant_transaction(in Coordinator tc);
+ boolean is_top_level_transaction();
+
+ unsigned long hash_transaction();
+ unsigned long hash_top_level_tran();
+
+ RecoveryCoordinator register_resource(in Resource r)
+ raises(Inactive);
+
+ void register_subtran_aware(in SubtransactionAwareResource r)
+ raises(Inactive, NotSubtransaction);
+
+ void rollback_only()
+ raises(Inactive);
+
+ string get_transaction_name();
+
+ Control create_subtransaction()
+ raises(SubtransactionsUnavailable, Inactive);
+ };
+
+ interface RecoveryCoordinator {
+ Status replay_completion(in Resource r)
+ raises(NotPrepared);
+ };
+
+}; // end module CosTransactions
+
+
+// CosConcurrency Control Module, p 7-8 CORBAservices,
+// Concurrency Control Service V1.0, 3/94
+
+// #include <CosTransactions.idl>
+module CosConcurrencyControl {
+
+ enum lock_mode {
+ read,
+ write,
+ upgrade,
+ intention_read,
+ intention_write
+ };
+
+ exception LockNotHeld{};
+
+ interface LockCoordinator
+ {
+ void drop_locks();
+ };
+
+ interface LockSet
+ {
+ void lock(in lock_mode mode);
+ boolean try_lock(in lock_mode mode);
+
+ void unlock(in lock_mode mode)
+ raises(LockNotHeld);
+ void change_mode(in lock_mode held_mode,
+ in lock_mode new_mode)
+ raises(LockNotHeld);
+ LockCoordinator get_coordinator(
+ in ::COSS::CosTransactions::Coordinator which);
+ };
+
+ interface TransactionalLockSet
+ {
+ void lock(in ::COSS::CosTransactions::Coordinator current,
+ in lock_mode mode);
+ boolean try_lock(in ::COSS::CosTransactions::Coordinator current,
+ in lock_mode mode);
+ void unlock(in ::COSS::CosTransactions::Coordinator current,
+ in lock_mode mode)
+ raises(LockNotHeld);
+ void change_mode(in ::COSS::CosTransactions::Coordinator current,
+ in lock_mode held_mode,
+ in lock_mode new_mode)
+ raises(LockNotHeld);
+ LockCoordinator get_coordinator(
+ in ::COSS::CosTransactions::Coordinator which);
+ };
+
+ interface LockSetFactory
+ {
+ LockSet create();
+ LockSet create_related(in LockSet which);
+ TransactionalLockSet create_transactional();
+ TransactionalLockSet create_transactional_related(in
+ TransactionalLockSet which);
+ };
+};
+
+// CosObjectIdentity Module, p 9-19 CORBAservices, Relationship
+// Service V1.0, 3/94
+
+
+module CosObjectIdentity {
+
+ typedef unsigned long ObjectIdentifier;
+
+ interface IdentifiableObject {
+ readonly attribute ObjectIdentifier constant_random_id;
+ boolean is_identical (
+ in IdentifiableObject other_object);
+ };
+
+};
+
+
+// CosRelationships Module, p 9-21 CORBAservices, Relationship
+// Service V1.0, 3/94
+
+// #include <ObjectIdentity.idl>
+
+module CosRelationships {
+
+ interface RoleFactory;
+ interface RelationshipFactory;
+ interface Relationship;
+ interface Role;
+ interface RelationshipIterator;
+
+ typedef Object RelatedObject;
+ typedef sequence<Role> Roles;
+ typedef string RoleName;
+ typedef sequence<RoleName> RoleNames;
+
+ struct NamedRole {RoleName name; Role aRole;};
+ typedef sequence<NamedRole> NamedRoles;
+
+ struct RelationshipHandle {
+ Relationship the_relationship;
+ ::COSS::CosObjectIdentity::ObjectIdentifier constant_random_id;
+ };
+ typedef sequence<RelationshipHandle> RelationshipHandles;
+
+ interface RelationshipFactory {
+ struct NamedRoleType {
+ RoleName name;
+ ::CORBA::InterfaceDef named_role_type;
+ };
+ typedef sequence<NamedRoleType> NamedRoleTypes;
+ readonly attribute ::CORBA::InterfaceDef relationship_type;
+ readonly attribute unsigned short degree;
+ readonly attribute NamedRoleTypes named_role_types;
+ exception RoleTypeError {NamedRoles culprits;};
+ exception MaxCardinalityExceeded {
+ NamedRoles culprits;};
+ exception DegreeError {unsigned short required_degree;};
+ exception DuplicateRoleName {NamedRoles culprits;};
+ exception UnknownRoleName {NamedRoles culprits;};
+
+ Relationship create (in NamedRoles named_roles)
+ raises (RoleTypeError,
+ MaxCardinalityExceeded,
+ DegreeError,
+ DuplicateRoleName,
+ UnknownRoleName);
+ };
+
+ interface Relationship :
+ ::COSS::CosObjectIdentity::IdentifiableObject {
+ exception CannotUnlink {
+ Roles offending_roles;
+ };
+ readonly attribute NamedRoles named_roles;
+ void destroy () raises(CannotUnlink);
+ };
+
+ interface Role {
+ exception UnknownRoleName {};
+ exception UnknownRelationship {};
+ exception RelationshipTypeError {};
+ exception CannotDestroyRelationship {
+ RelationshipHandles offenders;
+ };
+ exception ParticipatingInRelationship {
+ RelationshipHandles the_relationships;
+ };
+ readonly attribute RelatedObject related_object;
+ RelatedObject get_other_related_object (
+ in RelationshipHandle rel,
+ in RoleName target_name)
+ raises (UnknownRoleName,
+ UnknownRelationship);
+ Role get_other_role (in RelationshipHandle rel,
+ in RoleName target_name)
+ raises (UnknownRoleName, UnknownRelationship);
+ void get_relationships (
+ in unsigned long how_many,
+ out RelationshipHandles rels,
+ out RelationshipIterator iterator);
+ void destroy_relationships()
+ raises(CannotDestroyRelationship);
+ void destroy() raises(ParticipatingInRelationship);
+ boolean check_minimum_cardinality ();
+ void link (in RelationshipHandle rel,
+ in NamedRoles named_roles)
+ raises(RelationshipFactory::MaxCardinalityExceeded,
+ RelationshipTypeError);
+ void unlink (in RelationshipHandle rel)
+ raises (UnknownRelationship);
+ };
+
+ interface RoleFactory {
+ exception NilRelatedObject {};
+ exception RelatedObjectTypeError {};
+ readonly attribute ::CORBA::InterfaceDef role_type;
+ readonly attribute unsigned long max_cardinality;
+ readonly attribute unsigned long min_cardinality;
+// the following isn't allowed in IDL,
+// readonly attribute sequence <::CORBA::InterfaceDef> related_object_types;
+ typedef sequence <::CORBA::InterfaceDef> InterfaceDefSeq;
+ readonly attribute InterfaceDefSeq related_object_types;
+ Role create_role (in RelatedObject related_object)
+ raises (NilRelatedObject, RelatedObjectTypeError);
+ };
+
+ interface RelationshipIterator {
+ boolean next_one (out RelationshipHandle rel);
+ boolean next_n (in unsigned long how_many,
+ out RelationshipHandles rels);
+ void destroy ();
+ };
+
+};
+
+// CosCompoundExternalization Module, p 8-20 CORBAservices,
+// Externalization Service V1.0, 3/94
+
+// #include <Graphs.idl>
+// #include <Stream.idl>
+
+// CosGraphs Module, p 9-39 CORBAservices, Relationship Service
+// V1.0, 3/94
+
+// #include <Relationships.idl>
+// #include <ObjectIdentity.idl>
+
+module CosGraphs {
+
+ interface TraversalFactory;
+ interface Traversal;
+ interface TraversalCriteria;
+ interface Node;
+ interface NodeFactory;
+ interface Role;
+ interface EdgeIterator;
+
+ struct NodeHandle {
+ Node the_node;
+ ::COSS::CosObjectIdentity::ObjectIdentifier constant_random_id;
+ };
+ typedef sequence<NodeHandle> NodeHandles;
+
+ struct NamedRole {
+ Role the_role;
+ ::COSS::CosRelationships::RoleName the_name;
+ };
+ typedef sequence<NamedRole> NamedRoles;
+
+ struct EndPoint {
+ NodeHandle the_node;
+ NamedRole the_role;
+ };
+ typedef sequence<EndPoint> EndPoints;
+
+ struct Edge {
+ EndPoint from;
+ ::COSS::CosRelationships::RelationshipHandle the_relationship;
+ EndPoints relatives;
+ };
+ typedef sequence<Edge> Edges;
+
+ enum PropagationValue {deep, shallow, none, inhibit};
+ enum Mode {depthFirst, breadthFirst, bestFirst};
+
+ interface TraversalFactory {
+ Traversal create_traversal_on (
+ in NodeHandle root_node,
+ in TraversalCriteria the_criteria,
+ in Mode how);
+ };
+
+ interface Traversal {
+ typedef unsigned long TraversalScopedId;
+ struct ScopedEndPoint {
+ EndPoint point;
+ TraversalScopedId id;
+ };
+ typedef sequence<ScopedEndPoint> ScopedEndPoints;
+ struct ScopedRelationship {
+ ::COSS::CosRelationships::RelationshipHandle
+ scoped_relationship;
+ TraversalScopedId id;
+ };
+ struct ScopedEdge {
+ ScopedEndPoint from;
+ ScopedRelationship the_relationship;
+ ScopedEndPoints relatives;
+ };
+ typedef sequence<ScopedEdge> ScopedEdges;
+ boolean next_one (out ScopedEdge the_edge);
+ boolean next_n (in short how_many,
+ out ScopedEdges the_edges);
+ void destroy ();
+ };
+
+ interface TraversalCriteria {
+ struct WeightedEdge {
+ Edge the_edge;
+ unsigned long weight;
+ sequence<NodeHandle> next_nodes;
+ };
+ typedef sequence<WeightedEdge> WeightedEdges;
+ void visit_node(in NodeHandle a_node,
+ in Mode search_mode);
+ boolean next_one (out WeightedEdge the_edge);
+ boolean next_n (in short how_many,
+ out WeightedEdges the_edges);
+ void destroy();
+ };
+
+ interface Node: ::COSS::CosObjectIdentity::IdentifiableObject {
+ typedef sequence<Role> Roles;
+ exception NoSuchRole {};
+ exception DuplicateRoleType {};
+
+ readonly attribute ::COSS::CosRelationships::RelatedObject
+ related_object;
+ readonly attribute Roles roles_of_node;
+ Roles roles_of_type (
+ in ::CORBA::InterfaceDef role_type);
+ void add_role (in Role a_role)
+ raises (DuplicateRoleType);
+ void remove_role (in ::CORBA::InterfaceDef of_type)
+ raises (NoSuchRole);
+ };
+
+ interface NodeFactory {
+ Node create_node (in Object related_object);
+ };
+
+ interface Role : ::COSS::CosRelationships::Role {
+ void get_edges ( in long how_many,
+ out Edges the_edges,
+ out EdgeIterator the_rest);
+ };
+
+ interface EdgeIterator {
+ boolean next_one (out Edge the_edge);
+ boolean next_n ( in unsigned long how_many,
+ out Edges the_edges);
+ void destroy ();
+ };
+
+};
+
+
+
+// CosStream Module, 8-15 CORBAservices,
+// Externalization Service V1.0, 3/94
+
+// #include <LifeCycle.idl>
+// #include <ObjectIdentity.idl>
+// #include <CompoundExternalization.idl>
+module CosStream {
+ exception ObjectCreationError{};
+ exception StreamDataFormatError{};
+ interface StreamIO;
+
+ interface Streamable: ::COSS::CosObjectIdentity::IdentifiableObject
+ {
+ readonly attribute ::COSS::CosLifeCycle::Key external_form_id;
+ void externalize_to_stream(
+ in StreamIO targetStreamIO);
+ void internalize_from_stream(
+ in StreamIO sourceStreamIO,
+ in ::COSS::CosLifeCycle::FactoryFinder there)
+ raises( ::COSS::CosLifeCycle::NoFactory,
+ ObjectCreationError,
+ StreamDataFormatError );
+ };
+
+ interface StreamableFactory {
+ Streamable create_uninitialized();
+ };
+
+
+ interface StreamIO {
+ void write_string(in string aString);
+ void write_char(in char aChar);
+ void write_octet(in octet anOctet);
+ void write_unsigned_long(
+ in unsigned long anUnsignedLong);
+ void write_unsigned_short(
+ in unsigned short anUnsignedShort);
+ void write_long(in long aLong);
+ void write_short(in short aShort);
+ void write_float(in float aFloat);
+ void write_double(in double aDouble);
+ void write_boolean(in boolean aBoolean);
+ void write_object(in Streamable aStreamable);
+ // void write_graph(in ::COSS::CosCompoundExternalization::Node aNode);
+ string read_string()
+ raises(StreamDataFormatError);
+ char read_char()
+ raises(StreamDataFormatError );
+ octet read_octet()
+ raises(StreamDataFormatError );
+ unsigned long read_unsigned_long()
+ raises(StreamDataFormatError );
+ unsigned short read_unsigned_short()
+ raises( StreamDataFormatError );
+ long read_long()
+ raises(StreamDataFormatError );
+ short read_short()
+ raises(StreamDataFormatError );
+ float read_float()
+ raises(StreamDataFormatError );
+ double read_double()
+ raises(StreamDataFormatError );
+ boolean read_boolean()
+ raises(StreamDataFormatError );
+ Streamable read_object(
+ in ::COSS::CosLifeCycle::FactoryFinder there,
+ in Streamable aStreamable)
+ raises(StreamDataFormatError );
+// void read_graph(
+// in ::COSS::CosCompoundExternalization::Node starting_node,
+// in ::COSS::CosLifeCycle::FactoryFinder there)
+// raises(StreamDataFormatError );
+ };
+};
+
+module CosCompoundExternalization {
+ interface Node;
+ interface Role;
+ interface Relationship;
+ interface PropagationCriteriaFactory;
+
+ struct RelationshipHandle {
+ Relationship theRelationship;
+ ::COSS::CosObjectIdentity::ObjectIdentifier constantRandomId;
+ };
+
+ interface Node : ::COSS::CosGraphs::Node, ::COSS::CosStream::Streamable{
+ void externalize_node (in ::COSS::CosStream::StreamIO sio);
+ void internalize_node (in ::COSS::CosStream::StreamIO sio,
+ in ::COSS::CosLifeCycle::FactoryFinder there,
+ out ::COSS::CosGraphs::Node::Roles rolesOfNode)
+ raises (::COSS::CosLifeCycle::NoFactory);
+ };
+
+ interface Role : ::COSS::CosGraphs::Role {
+ void externalize_role (in ::COSS::CosStream::StreamIO sio);
+ void internalize_role (in ::COSS::CosStream::StreamIO sio);
+ ::COSS::CosGraphs::PropagationValue externalize_propagation (
+ in RelationshipHandle rel,
+ in ::COSS::CosRelationships::RoleName toRoleName,
+ out boolean sameForAll);
+ };
+
+ interface Relationship :
+ ::COSS::CosRelationships::Relationship {
+ void externalize_relationship (
+ in ::COSS::CosStream::StreamIO sio);
+ void internalize_relationship(
+ in ::COSS::CosStream::StreamIO sio,
+ in ::COSS::CosGraphs::NamedRoles newRoles);
+ ::COSS::CosGraphs::PropagationValue externalize_propagation (
+ in ::COSS::CosRelationships::RoleName fromRoleName,
+ in ::COSS::CosRelationships::RoleName toRoleName,
+ out boolean sameForAll);
+ };
+
+ interface PropagationCriteriaFactory {
+ ::COSS::CosGraphs::TraversalCriteria create_for_externalize( );
+ };
+
+};
+
+// CosExternalization Module, 8-12 CORBAservices,
+// Externalization Service V1.0, 3/94
+
+
+// #include <LifeCycle.idl>
+// #include <Stream.idl>
+module CosExternalization {
+ exception InvalidFileNameError{};
+ exception ContextAlreadyRegistered{};
+ interface Stream: ::COSS::CosLifeCycle::LifeCycleObject{
+ void externalize(
+ in ::COSS::CosStream::Streamable theObject);
+ ::COSS::CosStream::Streamable internalize(
+ in ::COSS::CosLifeCycle::FactoryFinder there)
+ raises( ::COSS::CosLifeCycle::NoFactory,
+ ::COSS::CosStream::StreamDataFormatError );
+ void begin_context()
+ raises( ContextAlreadyRegistered);
+ void end_context();
+ void flush();
+ };
+ interface StreamFactory {
+ Stream create();
+ };
+ interface FileStreamFactory {
+ Stream create(
+ in string theFileName)
+ raises( InvalidFileNameError );
+ };
+};
+
+// CosContainment Module, p 9- 48 CORBAservices, Relationship
+// Service V1.0, 3/94
+
+// #include <Graphs.idl>
+
+module CosContainment {
+
+ interface Relationship :
+ ::COSS::CosRelationships::Relationship {};
+
+ interface ContainsRole : ::COSS::CosGraphs::Role {};
+
+ interface ContainedInRole : ::COSS::CosGraphs::Role {};
+
+};
+
+// CosExternalizationContainment Module, p 8-26 CORBAservices,
+// Externalization Service V1.0, 3/94
+
+// #include <Containment.idl>
+// #include <CompoundExternalization.idl>
+
+module CosExternalizationContainment {
+
+ interface Relationship :
+ ::COSS::CosCompoundExternalization::Relationship,
+ ::COSS::CosContainment::Relationship {};
+
+ interface ContainsRole :
+ ::COSS::CosCompoundExternalization::Role,
+ ::COSS::CosContainment::ContainsRole {};
+
+ interface ContainedInRole :
+ ::COSS::CosCompoundExternalization::Role,
+ ::COSS::CosContainment::ContainedInRole {};
+};
+
+// CosReference Module, p 9-50 CORBAservices,
+// Relationship Service V1.0, 3/94
+
+// #include <Graphs.idl>
+
+module CosReference {
+
+ interface Relationship :
+ ::COSS::CosRelationships::Relationship {};
+
+ interface ReferencesRole : ::COSS::CosGraphs::Role {};
+
+ interface ReferencedByRole : ::COSS::CosGraphs::Role {};
+
+};
+
+// CosExternalizationReference Module, p 8-28 CORBAservices,
+// Externalization Service V1.0, 3/94
+
+// #include <Reference.idl>
+// #include <CompoundExternalization.idl>
+
+module CosExternalizationReference {
+
+ interface Relationship :
+ ::COSS::CosCompoundExternalization::Relationship,
+ ::COSS::CosReference::Relationship {};
+
+ interface ReferencesRole :
+ ::COSS::CosCompoundExternalization::Role,
+ ::COSS::CosReference::ReferencesRole {};
+
+ interface ReferencedByRole :
+ ::COSS::CosCompoundExternalization::Role,
+ ::COSS::CosReference::ReferencedByRole {};
+};
+
+// PIDL for CosTSInteroperation Module, p 10-59
+// CORBAservices, Transaction Service V1.0, 3/94
+module CosTSInteroperation { // PIDL
+ struct otid_t {
+ long formatID; /*format identifier. 0 is OSI TP */
+ long bequal_length;
+ sequence <octet> tid;
+ };
+ struct TransIdentity {
+ ::COSS::CosTransactions::Coordinator coordinator;
+ ::COSS::CosTransactions::Terminator terminator;
+ otid_t otid;
+ };
+ struct PropagationContext {
+ unsigned long timeout;
+ TransIdentity current;
+ sequence <TransIdentity> parents;
+ any implementation_specific_data;
+ };
+};
+
+// PIDL for CosTSPortability Module, p 10-63
+// CORBAservices, Transaction Service V1.0, 3/94
+
+module CosTSPortability { // PIDL
+ typedef long ReqId;
+
+ interface Sender {
+ void sending_request(in ReqId id,
+ out ::COSS::CosTSInteroperation::PropagationContext ctx);
+ void received_reply(in ReqId id,
+ in ::COSS::CosTSInteroperation::PropagationContext ctx,
+ in ::CORBA::Environment env);
+ };
+
+ interface Receiver {
+ void received_request(in ReqId id,
+ in ::COSS::CosTSInteroperation::PropagationContext ctx);
+ void sending_reply(in ReqId id,
+ out::COSS::CosTSInteroperation::PropagationContext ctx);
+ };
+};
+
+// CosCompoundLifeCycle Module, p 6-30 CORBAservices,
+// Life Cycle Service V1.0, 3/94
+
+// #include <LifeCycle.idl>
+// #include <Relationships.idl>
+// #include <Graphs.idl>
+
+module CosCompoundLifeCycle {
+ interface OperationsFactory;
+ interface Operations;
+ interface Node;
+ interface Role;
+ interface Relationship;
+ interface PropagationCriteriaFactory;
+
+ enum Operation {copy, move, remove};
+
+ struct RelationshipHandle {
+ Relationship the_relationship;
+ ::COSS::CosObjectIdentity::ObjectIdentifier constant_random_id;
+ };
+
+ interface OperationsFactory {
+ Operations create_compound_operations();
+ };
+
+ interface Operations {
+ Node copy (
+ in Node starting_node,
+ in ::COSS::CosLifeCycle::FactoryFinder there,
+ in ::COSS::CosLifeCycle::Criteria the_criteria)
+ raises (::COSS::CosLifeCycle::NoFactory,
+ ::COSS::CosLifeCycle::NotCopyable,
+ ::COSS::CosLifeCycle::InvalidCriteria,
+ ::COSS::CosLifeCycle::CannotMeetCriteria);
+ void move (
+ in Node starting_node,
+ in ::COSS::CosLifeCycle::FactoryFinder there,
+ in ::COSS::CosLifeCycle::Criteria the_criteria)
+ raises (::COSS::CosLifeCycle::NoFactory,
+ ::COSS::CosLifeCycle::NotMovable,
+ ::COSS::CosLifeCycle::InvalidCriteria,
+ ::COSS::CosLifeCycle::CannotMeetCriteria);
+ void remove (in Node starting_node)
+ raises (::COSS::CosLifeCycle::NotRemovable);
+ void destroy();
+ };
+
+ interface Node : ::COSS::CosGraphs::Node {
+ exception NotLifeCycleObject {};
+ void copy_node ( in ::COSS::CosLifeCycle::FactoryFinder there,
+ in ::COSS::CosLifeCycle::Criteria the_criteria,
+ out Node new_node,
+ out ::COSS::CosGraphs::Node::Roles roles_of_new_node)
+ raises (::COSS::CosLifeCycle::NoFactory,
+ ::COSS::CosLifeCycle::NotCopyable,
+ ::COSS::CosLifeCycle::InvalidCriteria,
+ ::COSS::CosLifeCycle::CannotMeetCriteria);
+ void move_node (in ::COSS::CosLifeCycle::FactoryFinder there,
+ in ::COSS::CosLifeCycle::Criteria the_criteria)
+ raises (::COSS::CosLifeCycle::NoFactory,
+ ::COSS::CosLifeCycle::NotMovable,
+ ::COSS::CosLifeCycle::InvalidCriteria,
+ ::COSS::CosLifeCycle::CannotMeetCriteria);
+ void remove_node ()
+ raises (::COSS::CosLifeCycle::NotRemovable);
+ ::COSS::CosLifeCycle::LifeCycleObject get_life_cycle_object()
+ raises (NotLifeCycleObject);
+ };
+
+ interface Role : ::COSS::CosGraphs::Role {
+ Role copy_role (in ::COSS::CosLifeCycle::FactoryFinder there,
+ in ::COSS::CosLifeCycle::Criteria the_criteria)
+ raises (::COSS::CosLifeCycle::NoFactory,
+ ::COSS::CosLifeCycle::NotCopyable,
+ ::COSS::CosLifeCycle::InvalidCriteria,
+ ::COSS::CosLifeCycle::CannotMeetCriteria);
+ void move_role (in ::COSS::CosLifeCycle::FactoryFinder there,
+ in ::COSS::CosLifeCycle::Criteria the_criteria)
+ raises (::COSS::CosLifeCycle::NoFactory,
+ ::COSS::CosLifeCycle::NotMovable,
+ ::COSS::CosLifeCycle::InvalidCriteria,
+ ::COSS::CosLifeCycle::CannotMeetCriteria);
+ ::COSS::CosGraphs::PropagationValue life_cycle_propagation (
+ in Operation op,
+ in RelationshipHandle rel,
+ in ::COSS::CosRelationships::RoleName to_role_name,
+ out boolean same_for_all);
+ };
+
+ interface Relationship :
+ ::COSS::CosRelationships::Relationship {
+ Relationship copy_relationship (
+ in ::COSS::CosLifeCycle::FactoryFinder there,
+ in ::COSS::CosLifeCycle::Criteria the_criteria,
+ in ::COSS::CosGraphs::NamedRoles new_roles)
+ raises (::COSS::CosLifeCycle::NoFactory,
+ ::COSS::CosLifeCycle::NotCopyable,
+ ::COSS::CosLifeCycle::InvalidCriteria,
+ ::COSS::CosLifeCycle::CannotMeetCriteria);
+ void move_relationship (
+ in ::COSS::CosLifeCycle::FactoryFinder there,
+ in ::COSS::CosLifeCycle::Criteria the_criteria)
+ raises (::COSS::CosLifeCycle::NoFactory,
+ ::COSS::CosLifeCycle::NotMovable,
+ ::COSS::CosLifeCycle::InvalidCriteria,
+ ::COSS::CosLifeCycle::CannotMeetCriteria);
+ ::COSS::CosGraphs::PropagationValue life_cycle_propagation (
+ in Operation op,
+ in ::COSS::CosRelationships::RoleName from_role_name,
+ in ::COSS::CosRelationships::RoleName to_role_name,
+ out boolean same_for_all);
+ };
+
+ interface PropagationCriteriaFactory {
+ ::COSS::CosGraphs::TraversalCriteria create(in Operation op);
+ };
+
+};
+
+// CosLifeCycleContainment Module, p 6-42 CORBAservices,
+// Life Cycle Service V1.0, 3/94
+
+// #include <Containment.idl>
+// #include <CompoundLifeCycle.idl>
+
+module CosLifeCycleContainment {
+
+ interface Relationship :
+ ::COSS::CosCompoundLifeCycle::Relationship,
+ ::COSS::CosContainment::Relationship {};
+
+ interface ContainsRole :
+ ::COSS::CosCompoundLifeCycle::Role,
+ ::COSS::CosContainment::ContainsRole {};
+
+ interface ContainedInRole :
+ ::COSS::CosCompoundLifeCycle::Role,
+ ::COSS::CosContainment::ContainedInRole {};
+};
+
+// CosLifeCycleReference Module, p 6-44 CORBAservices,
+// Life Cycle Service V1.0, 3/94
+
+// #include <Reference.idl>
+// #include <CompoundLifeCycle.idl>
+
+module CosLifeCycleReference {
+
+ interface Relationship :
+ ::COSS::CosCompoundLifeCycle::Relationship,
+ ::COSS::CosReference::Relationship {};
+
+ interface ReferencesRole :
+ ::COSS::CosCompoundLifeCycle::Role,
+ ::COSS::CosReference::ReferencesRole {};
+
+ interface ReferencedByRole :
+ ::COSS::CosCompoundLifeCycle::Role,
+ ::COSS::CosReference::ReferencedByRole {};
+};
+
+
+}; // end module COSS
diff --git a/lib/ic/test/ic_SUITE_data/attr.idl b/lib/ic/test/ic_SUITE_data/attr.idl
new file mode 100644
index 0000000000..c74223eca6
--- /dev/null
+++ b/lib/ic/test/ic_SUITE_data/attr.idl
@@ -0,0 +1,29 @@
+
+
+// %CopyrightBegin%
+//
+// 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%
+
+interface I1 {
+ attribute long a1, a2;
+ attribute char a3;
+};
+
+interface I2 : I1 {
+ attribute short a4;
+ readonly attribute char a5;
+};
+
diff --git a/lib/ic/test/ic_SUITE_data/c_err1.idl b/lib/ic/test/ic_SUITE_data/c_err1.idl
new file mode 100644
index 0000000000..e1bc93dae8
--- /dev/null
+++ b/lib/ic/test/ic_SUITE_data/c_err1.idl
@@ -0,0 +1,63 @@
+
+
+// %CopyrightBegin%
+//
+// 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%
+
+//
+// This file forces the bad_tk_match. This triggers when the type of
+// the expression does not match the declared type of the constant
+//
+
+const long c1 = TRUE;
+const unsigned short c1b= TRUE;
+const boolean c2 = +5;
+const long c3 = 'c';
+const float c5 = 3;
+const unsigned long c6 = -2; // Maybe not checked in compiler or suite
+
+const boolean c4 = 1 | 2;
+
+
+// Now define some correct constants for use in reference checking
+
+const long longC = -9;
+const short shortC = -9;
+const unsigned long ulongC = 1;
+const unsigned short ushortC = 0;
+
+const float floatC = 5.1;
+const double doubleC = -2.111;
+
+const boolean boolC = TRUE;
+
+const char charC = 'f';
+const string stringC = "hej";
+const string<9> stringCb = "hejdu";
+
+// Check the reference errors
+
+const long c19 = floatC;
+const short c20 = doubleC;
+const unsigned long c21 = charC;
+const unsigned short c22 = stringC;
+const float c23 = stringCb;
+const double c24 = boolC;
+const boolean c25 = longC;
+const char c26 = shortC;
+const string c27 = ushortC;
+const string<9> c28 = ulongC;
+const long c29 = 3+floatC;
diff --git a/lib/ic/test/ic_SUITE_data/c_err2.idl b/lib/ic/test/ic_SUITE_data/c_err2.idl
new file mode 100644
index 0000000000..8dac241c7f
--- /dev/null
+++ b/lib/ic/test/ic_SUITE_data/c_err2.idl
@@ -0,0 +1,30 @@
+
+
+// %CopyrightBegin%
+//
+// 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%
+
+//
+// Checks bad type of operands
+//
+
+
+const long c1 = 1 + TRUE;
+const boolean c3 = TRUE | FALSE | 19.8;
+const long c4 = 1 << TRUE;
+const long c5 = TRUE >> TRUE;
+
+
diff --git a/lib/ic/test/ic_SUITE_data/c_err3.idl b/lib/ic/test/ic_SUITE_data/c_err3.idl
new file mode 100644
index 0000000000..dde9539f6f
--- /dev/null
+++ b/lib/ic/test/ic_SUITE_data/c_err3.idl
@@ -0,0 +1,28 @@
+
+
+// %CopyrightBegin%
+//
+// 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%
+
+//
+// Checks ill-formed expressions (type conflict in operands)
+//
+
+
+const long c1 = 5|TRUE;
+const long c2 = 5&TRUE;
+const long c3 = 5^TRUE;
+
diff --git a/lib/ic/test/ic_SUITE_data/c_norm.idl b/lib/ic/test/ic_SUITE_data/c_norm.idl
new file mode 100644
index 0000000000..6f6ef8ff79
--- /dev/null
+++ b/lib/ic/test/ic_SUITE_data/c_norm.idl
@@ -0,0 +1,163 @@
+
+
+// %CopyrightBegin%
+//
+// 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%
+
+//
+// Check normal values and expressions for constants
+//
+
+// Integer types
+const long co1 = 077;
+const long ch1 = 0xf1;
+const long ch2 = 0XAB;
+const long c1 = 1;
+const short c2 = 3;
+const unsigned long c3 = 1;
+const unsigned short c4 = 3;
+
+// Unary ops
+const long c1hb = -0x1;
+const long c1b = -1;
+const short c2b = -3;
+const long c1c = +1;
+const short c2c = +3;
+// ~ not supported
+
+// Check binary ops
+const long c1d = 9+1-3;
+const long c1hd = 9+1-0xf3;
+const short c2d = 7+3;
+const short c2e = 7*3;
+const long c1e = 1 | 7;
+const long c1f = 7 & 9;
+const long c1g = (1 | 7) & 9;
+const long c1h = 1^7;
+
+//floats
+const float c5 = 1.9;
+const double c6 = 1.9;
+const float c5b = -1.9;
+const double c6b = -1.9;
+
+// Check type operand casting
+const float c5c = 1/(9+2) * 2;
+const double c6c = 1.9-1;
+//const double c6d = 1; // Does not work yet
+
+// Booleans and expressions
+const boolean c7 = TRUE;
+const boolean c7b = FALSE;
+const boolean c7c = TRUE | FALSE;
+const boolean c7d = TRUE & FALSE;
+const boolean c7e = TRUE&TRUE | FALSE&TRUE;
+const boolean c7f = TRUE&TRUE ^ FALSE&TRUE;
+
+// Character and string
+const char c8 = 'c';
+const char c8b = '\n';
+const string c9 = "hej";
+const string<9> c9b = "hejdu";
+
+
+//
+// Check that value references work
+//
+
+const long rc1 = c1g;
+const long rc1h = c1h + 9;
+const short rc2 = c2;
+const unsigned long rc3 = c3;
+const unsigned short rc4 = c4;
+
+
+const float rc5c = c5c;
+const double rc6c = c6c;
+const double rc6d = c6c+1.3;
+
+const boolean rc7 = c7;
+const boolean rc7c = c7c | TRUE;
+
+const char rc8 = c8;
+const char rc8b = c8b;
+const string rc9 = c9;
+const string<9> rc9b = c9b;
+
+
+
+
+//
+// Now check that all typerefs work
+//
+
+typedef long longT;
+typedef short shortT;
+typedef unsigned long ulongT;
+typedef unsigned short ushortT;
+
+typedef float floatT;
+typedef double doubleT;
+
+typedef char charT;
+typedef string stringT;
+
+typedef boolean booleanT;
+
+const longT cc1 = 1;
+const shortT cc2 = 3;
+const ::longT cc1b = -1;
+const ::shortT cc2b = -3;
+
+const floatT cc5 = 1.9;
+const doubleT cc6 = 1.9;
+const floatT cc5b = -1.9;
+const doubleT cc6b = -1.9;
+const floatT cc5c = 1/(9+2) * 2;
+const doubleT cc6c = 1.9-1;
+
+const booleanT cc7 = TRUE;
+const booleanT cc7b = TRUE;
+const booleanT cc7c = TRUE | FALSE;
+const booleanT cc7d = TRUE & FALSE;
+const booleanT cc7e = TRUE&TRUE | FALSE&TRUE;
+
+
+const charT cc8 = 'c';
+const charT cc8b = '\n';
+const stringT cc9 = "hej";
+const stringT cc9b = "hejdu";
+
+
+//
+// Check value casting
+//
+const long longC = -9;
+const short shortC = -9;
+const unsigned long ulongC = 1;
+const unsigned short ushortC = 0;
+
+const float floatC = 5.1;
+const double doubleC = -2.111;
+
+const long c20 = shortC;
+const long c21 = ulongC;
+const long c22 = ushortC;
+const short c23 = ushortC;
+const double c34 = floatC;
+
+
+
diff --git a/lib/ic/test/ic_SUITE_data/enum.idl b/lib/ic/test/ic_SUITE_data/enum.idl
new file mode 100644
index 0000000000..c164e4bf74
--- /dev/null
+++ b/lib/ic/test/ic_SUITE_data/enum.idl
@@ -0,0 +1,32 @@
+
+
+// %CopyrightBegin%
+//
+// 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%
+
+
+enum E1 {kalle, sune};
+
+enum E2 { el0, el1, el2, el3, el4, el5, el6, el7, el8, el9, el10, el11, el12, el13,
+el14, el15, el16, el17, el18, el19, el20, el21, el22, el23, el24, el25, el26, el27,
+el28, el29, el30, el31, el32, el33, el34, el35, el36, el37, el38, el39, el40, el41,
+el42, el43, el44, el45, el46, el47, el48, el49, el50, el51, el52, el53, el54, el55,
+el56, el57, el58, el59};
+
+
+
+
+
diff --git a/lib/ic/test/ic_SUITE_data/forward.idl b/lib/ic/test/ic_SUITE_data/forward.idl
new file mode 100644
index 0000000000..1e16265af5
--- /dev/null
+++ b/lib/ic/test/ic_SUITE_data/forward.idl
@@ -0,0 +1,34 @@
+
+
+// %CopyrightBegin%
+//
+// 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%
+
+//
+// Check that forward declarations are handled correctly
+//
+
+
+interface i1;
+
+
+interface i1 {
+ typedef long T;
+};
+
+
+interface i1;
+
diff --git a/lib/ic/test/ic_SUITE_data/include.idl b/lib/ic/test/ic_SUITE_data/include.idl
new file mode 100644
index 0000000000..24022bfa1e
--- /dev/null
+++ b/lib/ic/test/ic_SUITE_data/include.idl
@@ -0,0 +1,30 @@
+
+
+// %CopyrightBegin%
+//
+// 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%
+
+// Check that errors are given with the correct file name reference
+
+#include "include2.idl"
+
+
+typedef T1 T7;
+typedef long T7;
+typedef long T111;
+
+
+
diff --git a/lib/ic/test/ic_SUITE_data/include2.idl b/lib/ic/test/ic_SUITE_data/include2.idl
new file mode 100644
index 0000000000..2f8f7fd62c
--- /dev/null
+++ b/lib/ic/test/ic_SUITE_data/include2.idl
@@ -0,0 +1,26 @@
+
+
+// %CopyrightBegin%
+//
+// 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%
+
+// Check that errors are given with the correct file name reference
+
+#include "include3.idl"
+
+
+typedef T7 T1;
+
diff --git a/lib/ic/test/ic_SUITE_data/include3.idl b/lib/ic/test/ic_SUITE_data/include3.idl
new file mode 100644
index 0000000000..c5f89c6c63
--- /dev/null
+++ b/lib/ic/test/ic_SUITE_data/include3.idl
@@ -0,0 +1,25 @@
+
+
+// %CopyrightBegin%
+//
+// 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%
+
+// Check that errors are given with the correct file name reference
+
+typedef T7 T1;
+
+
+
diff --git a/lib/ic/test/ic_SUITE_data/inherit.idl b/lib/ic/test/ic_SUITE_data/inherit.idl
new file mode 100644
index 0000000000..71b79c8748
--- /dev/null
+++ b/lib/ic/test/ic_SUITE_data/inherit.idl
@@ -0,0 +1,68 @@
+
+
+// %CopyrightBegin%
+//
+// 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%
+
+
+interface I1 {
+ typedef long T1;
+ typedef struct S1 {long a; boolean b;} T2;
+ typedef string StringT, StringT_arr[10];
+
+ T1 op1( in StringT a, inout char b, out StringT_arr c );
+ T2 op2( in char a, inout char b, out StringT_arr c );
+
+ const T1 LongC = 10;
+ const StringT StringC = "Hola bambino";
+
+};
+
+
+interface I2 : I1 {
+ T1 op3( in long a);
+
+ const long c1 = LongC;
+ const string c2 = StringC;
+};
+
+interface I3 : I1 {};
+
+interface I4 : I3, I2 {}; // Check that branced inherit works
+
+
+
+// Now use cnstants to check that inheritance works as expected
+
+module m1 {
+ interface I1 {
+ typedef long T1;
+
+ const T1 c1 = 9;
+ };
+
+ interface I2 : I1 {
+ const T1 c2 = c1+5; // c2 = 14
+ const long c3 = c2+c1+4; // c3 = 27
+ };
+
+ interface I3 : I2, I1 {
+ const long c1 = 50; // Overrides I1::c1
+ const T1 c4 = c1+c2+c3; // c4=91
+ const T1 c5 = I1::c1+c1+c2+c3; // 100
+ };
+};
+
diff --git a/lib/ic/test/ic_SUITE_data/inherit_err.idl b/lib/ic/test/ic_SUITE_data/inherit_err.idl
new file mode 100644
index 0000000000..4cfc3ffbff
--- /dev/null
+++ b/lib/ic/test/ic_SUITE_data/inherit_err.idl
@@ -0,0 +1,71 @@
+
+
+// %CopyrightBegin%
+//
+// 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%
+
+//
+// Ops and attributes must not be redefined (shadowed)
+
+interface I1 {
+ long op1( in long a, inout char b, out boolean c );
+ long op2( in char a, inout char b, out boolean c );
+ attribute long a1, a2;
+ readonly attribute char a3;
+};
+
+interface I2 : I1 {
+ long op1( in float a, inout char b, out boolean c );
+ long op2( in char a, inout char b, out boolean c );
+ attribute long a1, a2;
+ readonly attribute char a3;
+};
+
+interface I3 : I1 {
+ long op3 (in string<19> b);
+};
+
+
+interface I4 : I3 {
+ long op1( in float a, inout char b, out boolean c );
+ long op2( in char a, inout char b, out boolean c );
+ attribute long a1, a2;
+ readonly attribute char a3;
+
+ long op3 (in string<19> b);
+};
+
+
+interface I11 {
+ long op1( in float a, inout char b, out boolean c );
+ long op2( in char a, inout char b, out boolean c );
+ attribute long a1, a2;
+ readonly attribute char a3;
+};
+
+
+
+interface I5 : I1, I11 {};
+
+interface I6 : I1 {
+ const long op1=0;
+ const long op2=0;
+ const long a1=0;
+ const long a2=0;
+ const long a3=0;
+};
+
+
diff --git a/lib/ic/test/ic_SUITE_data/inherit_warn.idl b/lib/ic/test/ic_SUITE_data/inherit_warn.idl
new file mode 100644
index 0000000000..502bfac8d4
--- /dev/null
+++ b/lib/ic/test/ic_SUITE_data/inherit_warn.idl
@@ -0,0 +1,64 @@
+
+
+// %CopyrightBegin%
+//
+// 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%
+
+//
+// Checks that shadow warnings comes out as expected
+//
+
+
+interface I1 {
+ typedef long T1;
+ typedef struct S1 {long a; boolean b;} T2;
+ typedef string StringT, StringT_arr[10];
+
+ T1 op1( in StringT a, inout char b, out StringT_arr c );
+ T2 op2( in char a, inout char b, out StringT_arr c );
+
+ const T1 LongC = 10;
+ const StringT StringC = "Hola bambino";
+
+};
+
+
+interface I2 : I1 {
+ typedef char T1; // Shadows I1::T1
+ const boolean StringC = FALSE; // shadows I1::StringC
+
+ T1 op3( in long a);
+
+ const long c1 = LongC;
+ const boolean c2 = StringC;
+};
+
+interface I3 : I2 {}; // More shadows
+
+interface I4 : I1 {
+ T1 op4();
+ const T1 c2 = 66;
+};
+
+interface I5 : I4 {
+ typedef string T1; // Shadows I1::T1
+ const char LongC = 'a'; // Shadows I1::LongC
+};
+
+
+interface I6 : I4, I3 {
+};
+
diff --git a/lib/ic/test/ic_SUITE_data/mult_ids.idl b/lib/ic/test/ic_SUITE_data/mult_ids.idl
new file mode 100644
index 0000000000..46deaa9f55
--- /dev/null
+++ b/lib/ic/test/ic_SUITE_data/mult_ids.idl
@@ -0,0 +1,92 @@
+
+// %CopyrightBegin%
+//
+// 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%
+//
+// Check that multiply defined identifiers are detected
+//
+
+typedef long T1;
+typedef long T1;
+typedef long T2;
+exception T2 {};
+
+
+//Exceptions
+exception Exc1 {};
+exception Exc1 {};
+
+
+// Enums
+enum E1 {kalle};
+enum E1 {kalle};
+enum E2 {kalle, sune, kalle};
+
+
+// Structs
+struct S1 {long a;};
+struct S1 {long a;};
+struct S2 {long a; short a;};
+struct S3 {long a,b; short a;};
+struct S4 {long a,a; short a;};
+
+
+// Constants
+const long c1 = 0;
+const long c1 = 0;
+
+
+// Interfaces
+
+interface i1 {};
+interface i1 {};
+
+interface i2 {
+ attribute long a1;
+ attribute long a1;
+};
+
+interface i3 {
+ attribute long a1, a2;
+ attribute long a2;
+};
+
+interface i4 {
+ attribute long a1, a1;
+};
+
+interface i5 {
+ long op1();
+ long op1();
+
+ long op2(in long a, inout char a);
+};
+
+
+// Unions
+
+union U1 switch (long) {case 1: long a;};
+union U1 switch (long) {case 1: long a;};
+
+union U2 switch (long) {
+case 1: long a;
+default: char a;
+};
+
+
+
+
+
diff --git a/lib/ic/test/ic_SUITE_data/nasty.idl b/lib/ic/test/ic_SUITE_data/nasty.idl
new file mode 100644
index 0000000000..15fd523c0f
--- /dev/null
+++ b/lib/ic/test/ic_SUITE_data/nasty.idl
@@ -0,0 +1,60 @@
+
+
+// %CopyrightBegin%
+//
+// 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%
+
+//
+// Checks nasty name collisions
+//
+
+typedef string T;
+
+
+#define nasty01 version
+#define nasty02 preproc
+#define nasty03 pragma
+#define nasty04 compile
+#define nasty05 if
+#define nasty06 receive
+#define nasty07 foldr
+#define nasty08 length
+#define nasty09 ID
+
+interface I1 {
+ attribute T nasty01;
+ attribute T nasty02;
+ attribute T nasty03;
+ attribute T nasty04;
+ attribute T nasty05;
+ attribute T nasty06;
+ attribute T nasty07;
+ attribute T nasty08;
+ attribute T nasty09;
+};
+
+interface I2 {
+ T nasty01();
+ T nasty02();
+ T nasty03();
+ T nasty04();
+ T nasty05();
+ T nasty06();
+ T nasty07();
+ T nasty08();
+ T nasty09();
+};
+
diff --git a/lib/ic/test/ic_SUITE_data/one.idl b/lib/ic/test/ic_SUITE_data/one.idl
new file mode 100644
index 0000000000..99281d6079
--- /dev/null
+++ b/lib/ic/test/ic_SUITE_data/one.idl
@@ -0,0 +1,29 @@
+
+
+// %CopyrightBegin%
+//
+// 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%
+
+// Test oneway operations
+
+interface I1 {
+ long op1(in char a, inout boolean b, out string c);
+ oneway void op2(in char a, in boolean b, in string c);
+ oneway void op3();
+};
+
+
+
diff --git a/lib/ic/test/ic_SUITE_data/one_followed.idl b/lib/ic/test/ic_SUITE_data/one_followed.idl
new file mode 100644
index 0000000000..da8ee74e25
--- /dev/null
+++ b/lib/ic/test/ic_SUITE_data/one_followed.idl
@@ -0,0 +1,54 @@
+
+
+// %CopyrightBegin%
+//
+// 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%
+
+// Test oneway operations followed by other operations
+
+interface I1 {
+ oneway void op1();
+ oneway void op2(in char a, in boolean b, in string c);
+ long op3(in char a, inout boolean b, out string c);
+};
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/lib/ic/test/ic_SUITE_data/one_out.idl b/lib/ic/test/ic_SUITE_data/one_out.idl
new file mode 100644
index 0000000000..65f177ff22
--- /dev/null
+++ b/lib/ic/test/ic_SUITE_data/one_out.idl
@@ -0,0 +1,28 @@
+
+
+// %CopyrightBegin%
+//
+// 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%
+
+// Test oneway operations not using in out params
+
+interface I1 {
+ oneway void op1(in char a, inout boolean b, in string c);
+ oneway void op2(in char a, out boolean b, in string c);
+};
+
+
+
diff --git a/lib/ic/test/ic_SUITE_data/one_raises.idl b/lib/ic/test/ic_SUITE_data/one_raises.idl
new file mode 100644
index 0000000000..8290877363
--- /dev/null
+++ b/lib/ic/test/ic_SUITE_data/one_raises.idl
@@ -0,0 +1,32 @@
+
+
+// %CopyrightBegin%
+//
+// 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%
+
+// Test oneway operations not using in out params
+
+exception hell {boolean burn; unsigned long for_how_long;};
+exception high_water {long mark;};
+
+interface I1 {
+ oneway void op1(in char a) raises (hell);
+ oneway void op2(in char a) raises (hell);
+ oneway void op3() raises (hell, high_water);
+};
+
+
+
diff --git a/lib/ic/test/ic_SUITE_data/one_void.idl b/lib/ic/test/ic_SUITE_data/one_void.idl
new file mode 100644
index 0000000000..e1d51c7abb
--- /dev/null
+++ b/lib/ic/test/ic_SUITE_data/one_void.idl
@@ -0,0 +1,30 @@
+
+
+// %CopyrightBegin%
+//
+// 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%
+
+// Test oneway operations not using in out params
+
+typedef long T;
+
+interface I1 {
+ oneway char op1(in char a);
+ oneway T op2(in char a);
+};
+
+
+
diff --git a/lib/ic/test/ic_SUITE_data/raises_reg.idl b/lib/ic/test/ic_SUITE_data/raises_reg.idl
new file mode 100644
index 0000000000..d4458811dc
--- /dev/null
+++ b/lib/ic/test/ic_SUITE_data/raises_reg.idl
@@ -0,0 +1,52 @@
+
+
+// %CopyrightBegin%
+//
+// 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%
+#ifndef _RAISES_REG_IDL
+#define _RAISES_REG_IDL
+
+module Raises_RegModule {
+
+ exception Exception_1 {};
+
+ exception Exception_2 {};
+
+ interface R_R {
+
+ void op()
+ raises(Raises_RegModule::Exception_1,Raises_RegModule::Exception_2);
+
+ };
+
+};
+
+#endif
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/lib/ic/test/ic_SUITE_data/struct.idl b/lib/ic/test/ic_SUITE_data/struct.idl
new file mode 100644
index 0000000000..337ee170e3
--- /dev/null
+++ b/lib/ic/test/ic_SUITE_data/struct.idl
@@ -0,0 +1,53 @@
+
+
+// %CopyrightBegin%
+//
+// 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%
+
+
+struct S1 {
+ long a;
+ char b;
+ string<9> s;
+};
+
+struct S2 {
+ long a;
+ struct S3 {
+ long a;
+ short b, b1;
+ char c;
+ } b;
+ sequence <S1> c, c2, c3, c4, c5, c6, c7;
+};
+
+
+// Check that structs are detected down in other types
+
+
+typedef struct s4 {long a;} T1;
+union U1 switch (long) {
+case 1:
+ struct S5 {unsigned short a;} a;
+case 2:
+ union U2 switch (char) {
+ case 'a':
+ boolean a;
+ case 'b':
+ struct s6 {long a; boolean b;} c;
+ } b;
+};
+
diff --git a/lib/ic/test/ic_SUITE_data/syntax1.idl b/lib/ic/test/ic_SUITE_data/syntax1.idl
new file mode 100644
index 0000000000..83c7de7943
--- /dev/null
+++ b/lib/ic/test/ic_SUITE_data/syntax1.idl
@@ -0,0 +1,28 @@
+
+
+// %CopyrightBegin%
+//
+// 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%
+
+//
+// Check syntax errors
+//
+
+
+typedef long T1 _;
+
+
+
diff --git a/lib/ic/test/ic_SUITE_data/syntax2.idl b/lib/ic/test/ic_SUITE_data/syntax2.idl
new file mode 100644
index 0000000000..10498206c1
--- /dev/null
+++ b/lib/ic/test/ic_SUITE_data/syntax2.idl
@@ -0,0 +1,27 @@
+
+
+// %CopyrightBegin%
+//
+// 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%
+struct S2 {
+ long a_arr[99];
+ struct S3 {
+ long a;_arr[99]
+ boolean b_arr[99];
+ } b;
+};
+
+
diff --git a/lib/ic/test/ic_SUITE_data/syntax3.idl b/lib/ic/test/ic_SUITE_data/syntax3.idl
new file mode 100644
index 0000000000..69ab6b9783
--- /dev/null
+++ b/lib/ic/test/ic_SUITE_data/syntax3.idl
@@ -0,0 +1,20 @@
+
+
+// %CopyrightBegin%
+//
+// 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%
+typdef long T1;
+
diff --git a/lib/ic/test/ic_SUITE_data/syntax4.idl b/lib/ic/test/ic_SUITE_data/syntax4.idl
new file mode 100644
index 0000000000..077a251729
--- /dev/null
+++ b/lib/ic/test/ic_SUITE_data/syntax4.idl
@@ -0,0 +1,23 @@
+
+
+// %CopyrightBegin%
+//
+// 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%
+union U1 switch (long) {
+case 1: long a;
+2: short b;
+};
+
diff --git a/lib/ic/test/ic_SUITE_data/syntax5.idl b/lib/ic/test/ic_SUITE_data/syntax5.idl
new file mode 100644
index 0000000000..10af9fc18c
--- /dev/null
+++ b/lib/ic/test/ic_SUITE_data/syntax5.idl
@@ -0,0 +1,22 @@
+
+
+// %CopyrightBegin%
+//
+// 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%
+union U1 switch (enum E1 {kalle, sune}) {
+case kalle: long a;
+sune: short b;
+};
diff --git a/lib/ic/test/ic_SUITE_data/syntax6.idl b/lib/ic/test/ic_SUITE_data/syntax6.idl
new file mode 100644
index 0000000000..dc15704d94
--- /dev/null
+++ b/lib/ic/test/ic_SUITE_data/syntax6.idl
@@ -0,0 +1,20 @@
+
+
+// %CopyrightBegin%
+//
+// 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%
+
+constant long c1 = 0;
diff --git a/lib/ic/test/ic_SUITE_data/type.idl b/lib/ic/test/ic_SUITE_data/type.idl
new file mode 100644
index 0000000000..67e1d502bd
--- /dev/null
+++ b/lib/ic/test/ic_SUITE_data/type.idl
@@ -0,0 +1,190 @@
+
+
+// %CopyrightBegin%
+//
+// 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%
+
+//
+// Check all types in IDL
+//
+
+typedef long T01;
+typedef unsigned long T02;
+typedef short T03;
+typedef unsigned short T04;
+typedef float T05;
+typedef double T06;
+typedef char T07;
+typedef boolean T08;
+typedef octet T09;
+typedef any T10;
+typedef Object T11;
+typedef T01 T12;
+
+// Template types
+typedef sequence <long> T21;
+typedef sequence <unsigned long> T22;
+typedef sequence <short, 2> T23;
+typedef sequence <unsigned short, 6> T24;
+typedef sequence <float, 12> T25;
+typedef sequence <double> T26;
+typedef sequence <char, 1> T27;
+typedef sequence <boolean> T28;
+typedef sequence <octet, 9> T29;
+typedef sequence <any> T30;
+typedef sequence <Object,2 > T31;
+typedef sequence <T01> T32;
+typedef sequence <sequence <sequence <T32> > > T33;
+
+struct S1 {
+ long a;
+ boolean b;
+};
+
+struct S2 {
+ long a;
+ struct S3 {
+ long a;
+ boolean b;
+ } b;
+};
+
+union U1 switch (enum E1 {kalle1, sune1}) {
+case kalle1: long a;
+default: boolean b;
+case sune1: octet c;
+};
+
+union U2 switch (enum E2 {kalle2, sune2}) {
+case kalle2: long a;
+default: struct S4 { long a; short b;} b;
+case sune2: octet c;
+};
+
+// Typedefs of above types
+
+typedef struct S11 {
+ long a;
+ boolean b;
+} T41;
+
+typedef struct S21 {
+ long a;
+ struct S3 {
+ long a;
+ boolean b;
+ } b;
+} T42;
+
+typedef union U11 switch (enum E3 {kalle3, sune3}) {
+case kalle3: long a;
+default: boolean b;
+case sune3: octet c;
+} T43;
+
+typedef union U21 switch (enum E4 {kalle4, sune4}) {
+case kalle4: long a;
+default: struct S4 { long a; short b;} b;
+case sune4: octet c;
+} T44;
+
+
+
+
+// Array versions
+
+typedef long T01_arr[99];
+typedef unsigned long T02_arr[99];
+typedef short T03_arr[99];
+typedef unsigned short T04_arr[99];
+typedef float T05_arr[99];
+typedef double T06_arr[99];
+typedef char T07_arr[99];
+typedef boolean T08_arr[99];
+typedef octet T09_arr[99];
+typedef any T10_arr[99];
+typedef Object T11_arr[99];
+typedef T01 T12_arr[99];
+
+typedef sequence <long> T21_arr[99];
+typedef sequence <unsigned long> T22_arr[99];
+typedef sequence <short, 2> T23_arr[99];
+typedef sequence <unsigned short, 6> T24_arr[99];
+typedef sequence <float, 12> T25_arr[99];
+typedef sequence <double> T26_arr[99];
+typedef sequence <char, 1> T27_arr[99];
+typedef sequence <boolean> T28_arr[99];
+typedef sequence <octet, 9> T29_arr[99];
+typedef sequence <any> T30_arr[99];
+typedef sequence <Object,2 > T31_arr[99];
+typedef sequence <T01> T32_arr[99];
+typedef sequence <sequence <sequence <T32> > > T33_arr[99];
+
+struct S12 {
+ long a;
+ boolean b_arr[99];
+};
+
+struct S22 {
+ long a_arr[99];
+ struct S3 {
+ long a_arr[99];
+ boolean b_arr[99];
+ } b;
+};
+
+union U12 switch (enum E12 {kalle12, sune12}) {
+case kalle12: long a_arr[99];
+default: boolean b;
+case sune12: octet c;
+};
+
+union U22 switch (enum E22 {kalle22, sune22}) {
+case kalle22: long a;
+default: struct S4 { long a; short b;} b_arr[99];
+case sune22: octet c;
+};
+
+// Typedefs of above types
+
+typedef struct S13 {
+ long a_arr[99];
+ boolean b;
+} T41_arr[99];
+
+typedef struct S23 {
+ long a;
+ struct S3 {
+ long a;
+ boolean b_arr[99];
+ char c;
+ } b;
+} T42_arr[99];
+
+typedef union U13 switch (enum E13 {kalle13, sune13}) {
+case kalle13: long a;
+default: boolean b_arr[99];
+case sune13: octet c;
+} T43_arr[99];
+
+typedef union U23 switch (enum E23 {kalle23, sune23}) {
+case kalle23: long a_arr[99];
+default: struct S4 { long a; short b;} b_arr[99];
+case sune23: octet c_arr[99];
+} T44_arr[99];
+
+
+
diff --git a/lib/ic/test/ic_SUITE_data/typeid.idl b/lib/ic/test/ic_SUITE_data/typeid.idl
new file mode 100644
index 0000000000..6e99f4a50d
--- /dev/null
+++ b/lib/ic/test/ic_SUITE_data/typeid.idl
@@ -0,0 +1,28 @@
+
+
+// %CopyrightBegin%
+//
+// 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%
+
+interface I1 {};
+
+module M1 { interface I1 {};};
+
+module M2 { module M1 { interface I1 {};};};
+
+module M3 { module M2 { module M1 { interface I1 {};};};};
+
+
diff --git a/lib/ic/test/ic_SUITE_data/u_case_mult.idl b/lib/ic/test/ic_SUITE_data/u_case_mult.idl
new file mode 100644
index 0000000000..3c30e144d8
--- /dev/null
+++ b/lib/ic/test/ic_SUITE_data/u_case_mult.idl
@@ -0,0 +1,54 @@
+
+
+// %CopyrightBegin%
+//
+// 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%
+
+// Check that case labels are not duplicated
+
+union U1 switch (long) {
+case 1 : long a;
+case 1 : short b;
+};
+
+union U2 switch (char) {
+case 'c' : long a;
+case 'c' : short b;
+};
+
+union U2b switch (char) {
+case 'c' :
+case 'c' : long a;
+case 'e': long b;
+case 'c': long c;
+};
+
+union U3 switch (enum E1 {kalle, kula}) {
+case kula : long a;
+case kula : short b;
+};
+
+union U4 switch (boolean) {
+case TRUE : long a;
+case TRUE : short b;
+};
+
+union U5 switch (boolean) {
+case TRUE : long a;
+default: short p;
+default: short pp;
+};
+
diff --git a/lib/ic/test/ic_SUITE_data/u_default.idl b/lib/ic/test/ic_SUITE_data/u_default.idl
new file mode 100644
index 0000000000..e5d94a5e54
--- /dev/null
+++ b/lib/ic/test/ic_SUITE_data/u_default.idl
@@ -0,0 +1,51 @@
+
+
+// %CopyrightBegin%
+//
+// 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%
+
+//
+// Checking that default labels are correct in TK
+//
+
+interface i1 {
+ union U1 switch (long) {
+ default: long a;
+ case 1: case 2: long b;
+ };
+
+ union U2 switch (long) {
+ case 0: default: long a;
+ case 1: case 2: long b;
+ };
+
+ union U3 switch (long) {
+ case -1: long aa;
+ case 0: default: long a;
+ case 1: case 2: long b;
+ };
+
+ union U4 switch (long) {
+ case -1: long aa;
+ case 0: long a;
+ case 1: case 2: long b;
+ };
+
+ U1 op0();
+ U2 op1();
+ U3 op2();
+ U4 op3();
+};
diff --git a/lib/ic/test/ic_SUITE_data/u_mult.idl b/lib/ic/test/ic_SUITE_data/u_mult.idl
new file mode 100644
index 0000000000..b916861eec
--- /dev/null
+++ b/lib/ic/test/ic_SUITE_data/u_mult.idl
@@ -0,0 +1,61 @@
+
+
+// %CopyrightBegin%
+//
+// 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%
+
+
+// Check multiply defined declarators
+
+enum E2 {kal, kula, E1}; // legal, but used below
+
+// Now check that declarator a is multiply defined in all unions below
+union U0 switch (long) {
+case 0: long a;
+case 1: short a;
+};
+union U00 switch (char) {
+case 'c' : long a;
+case 'f' : char c;
+case 'b' : short a;
+};
+union U000 switch (boolean) {
+case TRUE: long a;
+case FALSE: short a;
+};
+union U0000 switch (E2) {
+case kal: long a;
+case kula: short a;
+};
+
+
+
+
+// Check that enum name duplication is found.
+
+union U1 switch (enum E1 {kalle, kula, E1}) {
+case E1 : long a; // legal
+case kalle : short E1; // illegal
+};
+
+
+// This is legal, but ended up here anyway
+
+union U2 switch(::E2) {
+case kal : long a;
+case kula : short b;
+default : boolean E1;
+};
diff --git a/lib/ic/test/ic_SUITE_data/u_norm.idl b/lib/ic/test/ic_SUITE_data/u_norm.idl
new file mode 100644
index 0000000000..e23796b8ca
--- /dev/null
+++ b/lib/ic/test/ic_SUITE_data/u_norm.idl
@@ -0,0 +1,63 @@
+
+
+// %CopyrightBegin%
+//
+// 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%
+
+
+union U1 switch (long) {
+case 1: long a;
+case 2: case 3: short b;
+};
+
+
+union U2 switch (unsigned short) {
+case 10: boolean a;
+case 188: char b;
+default: string c;
+};
+
+
+union U3 switch (enum E1 {kalle, kula, boll}) {
+case kalle: long a;
+case kula: U2 b;
+};
+
+enum E2 {Cissi, Anders};
+
+union U4 switch (::E2) {
+case Cissi: U1 a;
+default: case Anders: unsigned long b;
+};
+
+union U5 switch(char) {
+case 'e': long a;
+case 'b': case 'f': char b;
+default: struct S {long a; boolean b;} c;
+};
+
+
+// Now check that references can be used as case values
+
+const long c1 = 9;
+const long c2 = 10;
+
+union U6 switch (long) {
+case c1: boolean a;
+case ::c2: boolean b;
+};
+
+
diff --git a/lib/ic/test/ic_SUITE_data/u_type.idl b/lib/ic/test/ic_SUITE_data/u_type.idl
new file mode 100644
index 0000000000..44e3326305
--- /dev/null
+++ b/lib/ic/test/ic_SUITE_data/u_type.idl
@@ -0,0 +1,82 @@
+
+
+// %CopyrightBegin%
+//
+// 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%
+
+
+//
+// Check that case values match declared discriminator type
+//
+
+
+const long longC = 0;
+const short shortC = 0;
+const char charC = 'c';
+const string stringC = "Yacht";
+
+enum E1 {kalle, kula};
+
+union U1 switch (long) {
+case 'c' : long a;
+case TRUE : long b;
+case stringC : long d;
+case kalle : long f;
+};
+
+union U2 switch (unsigned long) {
+case 'c' : long a;
+case TRUE : long b;
+case stringC : long d;
+case kalle : long f;
+};
+
+union U3 switch (short) {
+case 'c' : long a;
+case TRUE : long b;
+case stringC : long d;
+case kalle : long f;
+};
+
+union U4 switch (unsigned short) {
+case 'c' : long a;
+case TRUE : long b;
+case stringC : long d;
+case kalle : long f;
+};
+
+union U5 switch (char) {
+case TRUE : long b;
+case stringC : long d;
+case shortC : long e;
+case kalle : long f;
+};
+
+
+union U6 switch (E1) {
+case 'c' : long a;
+case TRUE : long b;
+case stringC : long d;
+case shortC : long e;
+};
+
+union U7 switch (enum E2 {ja, nej, kanske}) {
+case 'c' : long a;
+case TRUE : long b;
+case stringC : long d;
+case shortC : long e;
+};
+
diff --git a/lib/ic/test/ic_SUITE_data/undef_id.idl b/lib/ic/test/ic_SUITE_data/undef_id.idl
new file mode 100644
index 0000000000..01a35c4ef8
--- /dev/null
+++ b/lib/ic/test/ic_SUITE_data/undef_id.idl
@@ -0,0 +1,63 @@
+
+
+// %CopyrightBegin%
+//
+// 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%
+
+//
+// Check that undefined ids are detected
+//
+
+typedef T7 T1;
+
+const char c1 = ::c0;
+const T01 c2 = 'h';
+const T7 c3 = 9;
+
+interface i1 {
+ T17 op();
+ long op2( in T7 a);
+ attribute T7 a1, a2;
+ readonly attribute T17 a3;
+};
+
+union U1 switch (long) {
+case 1: long a;
+case ::g : short b;
+};
+
+union U2 switch (enum E1 {kalle, kula}) {
+case kula1: long a;
+case kalle : short b;
+};
+
+union U3 switch (long) {
+case kula2: long a;
+case ::E3::kalle : short b;
+case ::E4::kalle : short c;
+};
+
+enum E2 {kalle2, kula2};
+
+union U4 switch (E2) {
+case kula1: long a;
+case kula1: long b;
+case c3: short c;
+};
+
+
+
+
diff --git a/lib/ic/test/ic_be_SUITE.erl b/lib/ic/test/ic_be_SUITE.erl
new file mode 100644
index 0000000000..e3caf7bdff
--- /dev/null
+++ b/lib/ic/test/ic_be_SUITE.erl
@@ -0,0 +1,69 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 1998-2009. All Rights Reserved.
+%%
+%% The contents of this file are subject to the Erlang Public License,
+%% Version 1.1, (the "License"); you may not use this file except in
+%% compliance with the License. You should have received a copy of the
+%% Erlang Public License along with this software. If not, it can be
+%% retrieved online at http://www.erlang.org/.
+%%
+%% Software distributed under the License is distributed on an "AS IS"
+%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+%% the License for the specific language governing rights and limitations
+%% under the License.
+%%
+%% %CopyrightEnd%
+%%
+%%
+%%%----------------------------------------------------------------------
+%%% Purpose : Test suite for the backends of the IDL compiler
+%%%----------------------------------------------------------------------
+
+-module(ic_be_SUITE).
+-include("test_server.hrl").
+
+
+-export([all/1,plain/1]).
+
+
+-define(OUT(X), filename:join([?config(priv_dir, Config), gen, to_list(X)])).
+
+
+%% Top of cases
+
+all(suite) -> [plain].
+
+
+
+plain(doc) ->
+ ["Checking code for the plain backend."];
+plain(suite) -> [];
+plain(Config) when is_list(Config) ->
+ DataDir = ?config(data_dir, Config),
+ OutDir = ?OUT(slask),
+ File = filename:join(DataDir, plain),
+
+ ?line ok = ic:gen(File,stdopts(OutDir)++[{be,erl_plain}]),
+
+ ok.
+
+
+
+
+%%--------------------------------------------------------------------
+%%
+%% Utilities
+
+
+stdopts(OutDir) ->
+ [{outdir, OutDir}, {maxerrs, infinity}].
+
+
+
+
+
+to_list(X) when is_atom(X) -> atom_to_list(X);
+to_list(X) -> X.
+
diff --git a/lib/ic/test/ic_be_SUITE_data/plain.idl b/lib/ic/test/ic_be_SUITE_data/plain.idl
new file mode 100644
index 0000000000..ee0a995807
--- /dev/null
+++ b/lib/ic/test/ic_be_SUITE_data/plain.idl
@@ -0,0 +1,33 @@
+
+// %CopyrightBegin%
+//
+// 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%
+
+module m {
+
+ struct s {
+ long x;
+ long y;
+ };
+
+ interface i {
+
+ void foo( in s a, out short b );
+
+ };
+
+};
+
diff --git a/lib/ic/test/ic_pp_SUITE.erl b/lib/ic/test/ic_pp_SUITE.erl
new file mode 100644
index 0000000000..d68242bf3a
--- /dev/null
+++ b/lib/ic/test/ic_pp_SUITE.erl
@@ -0,0 +1,647 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 1998-2009. All Rights Reserved.
+%%
+%% The contents of this file are subject to the Erlang Public License,
+%% Version 1.1, (the "License"); you may not use this file except in
+%% compliance with the License. You should have received a copy of the
+%% Erlang Public License along with this software. If not, it can be
+%% retrieved online at http://www.erlang.org/.
+%%
+%% Software distributed under the License is distributed on an "AS IS"
+%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+%% the License for the specific language governing rights and limitations
+%% under the License.
+%%
+%% %CopyrightEnd%
+%%
+%%
+%%----------------------------------------------------------------------
+%% Purpose : Test suite for the IDL preprocessor
+%%----------------------------------------------------------------------
+
+-module(ic_pp_SUITE).
+-include("test_server.hrl").
+
+
+
+%% Standard options to the ic compiler, NOTE unholy use of OutDir
+
+-define(OUT(X), filename:join([?config(priv_dir, Config), gen, to_list(X)])).
+-define(GCC, "g++").
+-define(GCC_VER, "2.95.3").
+
+-export([all/1]).
+-export([arg/1]).
+-export([arg_norm/1]).
+-export([cascade/1]).
+-export([cascade_norm/1]).
+-export([comment/1]).
+-export([comment_norm/1]).
+-export([concat/1]).
+-export([concat_norm/1]).
+-export([define/1]).
+-export([define_norm/1]).
+-export(['if'/1]).
+-export([if_norm/1]).
+-export([if_zero/1]).
+-export([misc/1]).
+-export([misc_norm/1]).
+-export([improp_nest_constr/1]).
+-export([improp_nest_constr_norm/1]).
+-export([inc/1]).
+-export([inc_norm/1]).
+-export([line/1]).
+-export([line_norm/1]).
+-export([nopara/1]).
+-export([nopara_norm/1]).
+-export([predef/1]).
+-export([predef_norm/1]).
+-export([predef_time/1]).
+-export([predef_time_norm/1]).
+-export([self_ref/1]).
+-export([self_ref_norm/1]).
+-export([separate/1]).
+-export([separate_norm/1]).
+-export([swallow_sc/1]).
+-export([swallow_sc_norm/1]).
+-export([unintended_grp/1]).
+-export([unintended_grp_norm/1]).
+-export([cases/0, init_all/1, finish_all/1]).
+
+
+all(doc) -> ["Preprocessing tests for IC"];
+all(suite) ->
+ {req, [], {conf, init_all, cases(), finish_all}}.
+
+init_all(Config) ->
+ if
+ is_list(Config) ->
+ case os:type() of
+ {win32, _} ->
+ {skipped, "Very unplesent to run on windows"};
+ _ ->
+ check_gcc(Config)
+ end;
+ true ->
+ exit("Config not a list")
+ end.
+
+check_gcc(Config) ->
+ case os:find_executable(?GCC) of
+ false ->
+ {skipped,
+ lists:flatten(io_lib:format("Can not run without ~s in path",
+ [?GCC]))};
+ _ ->
+ case trim(os:cmd(?GCC++" --version")) of
+ ?GCC_VER++[] ->
+ Config;
+ ?GCC_VER++[D|_] when is_integer(D), D>=$0, D=<$9 ->
+ fail_gcc(?GCC_VER++[D]);
+ ?GCC_VER++_ ->
+ Config;
+ Ver ->
+ fail_gcc(Ver)
+ end
+ end.
+
+fail_gcc(Ver) ->
+ {skipped, lists:flatten(io_lib:format("Need ~s v~s, not ~s",
+ [?GCC, ?GCC_VER, Ver]))}.
+
+trim(S) -> lists:reverse(skip_white(lists:reverse(skip_white(S)))).
+
+skip_white([$\s|T]) -> skip_white(T);
+skip_white([$\n|T]) -> skip_white(T);
+skip_white([$\r|T]) -> skip_white(T);
+skip_white([$\t|T]) -> skip_white(T);
+skip_white(L) -> L.
+
+
+finish_all(Config) ->
+ Config.
+
+
+cases() ->
+ [arg, cascade, comment, concat, define, misc, 'if', improp_nest_constr, inc,
+ line, nopara, predef, predef_time, self_ref, separate, swallow_sc,
+ unintended_grp].
+
+
+
+%%--------------------------------------------------------------------
+%% arg
+%%--------------------------------------------------------------------
+
+arg(suite) -> [arg_norm];
+arg(doc) -> ["Check #define with some arguments"].
+
+arg_norm(doc) -> ["Checks arguments for #define."];
+arg_norm(suite) -> [];
+arg_norm(Config) when is_list(Config) ->
+ DataDir = ?config(data_dir, Config),
+ _OutDir = ?OUT(arg_norm),
+ File = filename:join(DataDir, arg),
+
+ ?line ok = test_file(File, DataDir),
+ ok.
+
+
+%%--------------------------------------------------------------------
+%% cascade
+%%--------------------------------------------------------------------
+
+cascade(suite) -> [cascade_norm];
+cascade(doc) -> ["Check cascade #define"].
+
+cascade_norm(doc) -> ["Check cascade #define."];
+cascade_norm(suite) -> [];
+cascade_norm(Config) when is_list(Config) ->
+ DataDir = ?config(data_dir, Config),
+ _OutDir = ?OUT(cascade_norm),
+ File = filename:join(DataDir, cascade),
+
+ ?line ok = test_file(File, DataDir),
+ ok.
+
+
+%%--------------------------------------------------------------------
+%% comment
+%%--------------------------------------------------------------------
+
+comment(suite) -> [comment_norm];
+comment(doc) -> ["Check comments"].
+
+comment_norm(doc) -> ["Check comments."];
+comment_norm(suite) -> [];
+comment_norm(Config) when is_list(Config) ->
+ DataDir = ?config(data_dir, Config),
+ _OutDir = ?OUT(comment_norm),
+ File = filename:join(DataDir, comment),
+
+ ?line ok = test_file(File, DataDir),
+ ok.
+
+
+%%--------------------------------------------------------------------
+%% concat
+%%--------------------------------------------------------------------
+
+concat(suite) -> [concat_norm];
+concat(doc) -> ["Check concatinations, i.e ## "].
+
+concat_norm(doc) -> ["Check concatinations, i.e ## ."];
+concat_norm(suite) -> [];
+concat_norm(Config) when is_list(Config) ->
+ DataDir = ?config(data_dir, Config),
+ _OutDir = ?OUT(concat_norm),
+ File = filename:join(DataDir, concat),
+
+ ?line ok = test_file(File, DataDir),
+ ok.
+
+
+%%--------------------------------------------------------------------
+%% define
+%%--------------------------------------------------------------------
+
+define(suite) -> [define_norm];
+define(doc) -> ["Check misceleaneous #define"].
+
+define_norm(doc) -> ["Check misceleaneous #define."];
+define_norm(suite) -> [];
+define_norm(Config) when is_list(Config) ->
+ DataDir = ?config(data_dir, Config),
+ _OutDir = ?OUT(define_norm),
+ File = filename:join(DataDir, define),
+
+ ?line ok = test_file(File, DataDir),
+ ok.
+
+
+%%--------------------------------------------------------------------
+%% if
+%%--------------------------------------------------------------------
+
+'if'(suite) -> [if_norm, if_zero];
+'if'(doc) -> ["Check #if, #elif, and #endif. Note these are not implementen and will ~n
+ result in an error message from internal_pp"].
+
+if_norm(doc) -> ["Check #if, #elif, and #endif. ."];
+if_norm(suite) -> [];
+if_norm(Config) when is_list(Config) ->
+ DataDir = ?config(data_dir, Config),
+ _OutDir = ?OUT(if_norm),
+ File = filename:join(DataDir, 'if'),
+
+ ?line ok = test_file(File, DataDir),
+ ok.
+
+if_zero(doc) -> ["Check #if 0"];
+if_zero(suite) -> [];
+if_zero(Config) when is_list(Config) ->
+ DataDir = ?config(data_dir, Config),
+ _OutDir = ?OUT(if_zero),
+ File = filename:join(DataDir, if_zero),
+
+ ?line ok = test_file(File, DataDir),
+ ok.
+
+
+%%--------------------------------------------------------------------
+%% inc
+%%--------------------------------------------------------------------
+
+inc(suite) -> [inc_norm];
+inc(doc) -> ["Check #include"].
+
+inc_norm(doc) -> ["Check #include."];
+inc_norm(suite) -> [];
+inc_norm(Config) when is_list(Config) ->
+ DataDir = ?config(data_dir, Config),
+ _OutDir = ?OUT(inc_norm),
+ File = filename:join(DataDir, inc),
+
+ ?line ok = test_file(File, DataDir),
+ ok.
+
+
+
+%%--------------------------------------------------------------------
+%% improp_nest_constr
+%%--------------------------------------------------------------------
+
+improp_nest_constr(suite) -> [improp_nest_constr_norm];
+improp_nest_constr(doc) -> ["Check improperly nested constructs"].
+
+improp_nest_constr_norm(doc) -> ["Check improperly nested constructs."];
+improp_nest_constr_norm(suite) -> [];
+improp_nest_constr_norm(Config) when is_list(Config) ->
+ DataDir = ?config(data_dir, Config),
+ _OutDir = ?OUT(improp_nest_constr_norm),
+ File = filename:join(DataDir, improp_nest_constr),
+
+ ?line ok = test_file(File, DataDir),
+ ok.
+
+
+%%--------------------------------------------------------------------
+%% misc
+%%--------------------------------------------------------------------
+
+misc(suite) -> [misc_norm];
+misc(doc) -> ["Misceleaneous checks"].
+
+misc_norm(doc) -> ["Misceleaneous checks."];
+misc_norm(suite) -> [];
+misc_norm(Config) when is_list(Config) ->
+ DataDir = ?config(data_dir, Config),
+ _OutDir = ?OUT(misc_norm),
+ File = filename:join(DataDir, misc),
+
+ ?line ok = test_file(File, DataDir),
+ ok.
+
+
+%%--------------------------------------------------------------------
+%% line
+%%--------------------------------------------------------------------
+
+line(suite) -> [line_norm];
+line(doc) -> ["Checks #line"].
+
+line_norm(doc) -> ["Checks #line."];
+line_norm(suite) -> [];
+line_norm(Config) when is_list(Config) ->
+ DataDir = ?config(data_dir, Config),
+ _OutDir = ?OUT(line_norm),
+ File = filename:join(DataDir, line),
+
+ ?line ok = test_file(File, DataDir),
+ ok.
+
+
+%%--------------------------------------------------------------------
+%% nopara
+%%--------------------------------------------------------------------
+
+nopara(suite) -> [nopara_norm];
+nopara(doc) -> ["Checks #define with no parameters"].
+
+nopara_norm(doc) -> ["Checks #define with no parameters."];
+nopara_norm(suite) -> [];
+nopara_norm(Config) when is_list(Config) ->
+ DataDir = ?config(data_dir, Config),
+ _OutDir = ?OUT(nopara_norm),
+ File = filename:join(DataDir, nopara),
+
+ ?line ok = test_file(File, DataDir),
+ ok.
+
+
+%%--------------------------------------------------------------------
+%% predef
+%%--------------------------------------------------------------------
+
+predef(suite) -> [predef_norm];
+predef(doc) -> ["Checks predefined macros. Note: not __TIME__ and __DATE__"].
+
+predef_norm(doc) -> ["Checks predefined macros. Note: not __TIME__ and __DATE__."];
+predef_norm(suite) -> [];
+predef_norm(Config) when is_list(Config) ->
+ DataDir = ?config(data_dir, Config),
+ _OutDir = ?OUT(predef_norm),
+ File = filename:join(DataDir, predef),
+
+ ?line ok = test_file(File, DataDir),
+ ok.
+
+
+%%--------------------------------------------------------------------
+%% predef_time
+%%--------------------------------------------------------------------
+
+predef_time(suite) -> [predef_time_norm];
+predef_time(doc) -> ["Checks the predefined macros __TIME__ and __DATE__"].
+
+predef_time_norm(doc) -> ["Checks the predefined macros __TIME__ and __DATE__."];
+predef_time_norm(suite) -> [];
+predef_time_norm(Config) when is_list(Config) ->
+ DataDir = ?config(data_dir, Config),
+ _OutDir = ?OUT(predef_time_norm),
+ File = filename:join(DataDir, predef_time),
+
+ ?line ok = test_file(File, DataDir),
+ ok.
+
+
+%%--------------------------------------------------------------------
+%% self_ref
+%%--------------------------------------------------------------------
+
+self_ref(suite) -> [self_ref_norm];
+self_ref(doc) -> ["Checks self referring macros"].
+
+self_ref_norm(doc) -> ["Checks self referring macros."];
+self_ref_norm(suite) -> [];
+self_ref_norm(Config) when is_list(Config) ->
+ DataDir = ?config(data_dir, Config),
+ _OutDir = ?OUT(self_ref_norm),
+ File = filename:join(DataDir, self_ref),
+
+ ?line ok = test_file(File, DataDir),
+ ok.
+
+
+%%--------------------------------------------------------------------
+%% separate
+%%--------------------------------------------------------------------
+
+separate(suite) -> [separate_norm];
+separate(doc) -> ["Checks separete expansion of macro arguments"].
+
+separate_norm(doc) -> ["Checks separete expansion of macro arguments."];
+separate_norm(suite) -> [];
+separate_norm(Config) when is_list(Config) ->
+ DataDir = ?config(data_dir, Config),
+ _OutDir = ?OUT(separate_norm),
+ File = filename:join(DataDir, separate),
+
+ ?line ok = test_file(File, DataDir),
+ ok.
+
+
+%%--------------------------------------------------------------------
+%% swallow_sc
+%%--------------------------------------------------------------------
+
+swallow_sc(suite) -> [swallow_sc_norm];
+swallow_sc(doc) -> ["Checks swallowing an undesirable semicolon"].
+
+swallow_sc_norm(doc) -> ["Checks swallowing an undesirable semicolon."];
+swallow_sc_norm(suite) -> [];
+swallow_sc_norm(Config) when is_list(Config) ->
+ DataDir = ?config(data_dir, Config),
+ _OutDir = ?OUT(swallow_sc_norm),
+ File = filename:join(DataDir, swallow_sc),
+
+ ?line ok = test_file(File, DataDir),
+ ok.
+
+
+%%--------------------------------------------------------------------
+%% unintended_grp
+%%--------------------------------------------------------------------
+
+unintended_grp(suite) -> [unintended_grp_norm];
+unintended_grp(doc) -> ["Checks unintended grouping of arithmetic"].
+
+unintended_grp_norm(doc) -> ["Checks unintended grouping of arithmetic."];
+unintended_grp_norm(suite) -> [];
+unintended_grp_norm(Config) when is_list(Config) ->
+ DataDir = ?config(data_dir, Config),
+ _OutDir = ?OUT(unintended_grp_norm),
+ File = filename:join(DataDir, unintended_grp),
+
+ ?line ok = test_file(File, DataDir),
+ ok.
+
+
+
+
+
+test_file(FileT, DataDir) ->
+ case test_file_1(FileT, DataDir) of
+ ok -> ok;
+ Chars ->
+ io:put_chars(Chars),
+ {error,{FileT,DataDir}}
+ end.
+
+test_file_1(FileT, DataDir) ->
+ Tok = string:tokens(FileT, "/"),
+ FileName = lists:last(Tok),
+ File = FileT++".idl",
+
+ ?line test_server:format("File ~p~n",[File]),
+ ?line test_server:format("FileName ~p~n",[FileName]),
+
+ Flags = "-I"++DataDir,
+
+ ?line test_server:format("Flags ~p~n",[Flags]),
+
+ ?line Erl = pp_erl(File, Flags),
+ ?line Gcc = pp_gcc(File, Flags),
+
+ ?line case Erl of
+ {error,_ErlError} ->
+ ?line test_server:format("Internal_pp Result ~n==================~n~p~n~n",[Erl]);
+ {warning, _ErlWar} ->
+ ?line test_server:format("Internal_pp Result ~n==================~n~p~n~n",[Erl]);
+ _ ->
+ ?line test_server:format("Internal_pp Result ~n==================~n~s~n~n",[Erl])
+ end,
+
+ ?line case Gcc of
+ {error,GccError} ->
+ Error = string:tokens(GccError, "\n"),
+ ?line test_server:format(?GCC" Result ~n==========~n~p~n~n",
+ [Error]);
+ _ ->
+ ?line test_server:format(?GCC" Result ~n==========~n~s~n~n",[Gcc])
+ end,
+
+
+
+ ?line case {Erl,Gcc} of
+ {{warning,W}, {error,X}} ->
+ ?line case is_ok(W,X) of
+ yes ->
+ ok;
+ no ->
+ io_lib:format("Internal_pp found Warning = ~p ~n"
+ ?GCC" found Error = ~p~n",[W,X])
+ end;
+
+
+ {{warning,W}, _} ->
+ io_lib:format(?GCC" did not find warnings while ~n"
+ "Internal_pp found the following Warning = ~p~n",[W]);
+
+ {{error,E}, {error,X}} ->
+ ?line case is_ok(E,X) of
+ yes ->
+ ok;
+ no ->
+ io_lib:format("Internal_pp found Error = ~p ~n"
+ ?GCC" found Error = ~p~n",[E,X])
+ end;
+
+ {{error,E}, _} ->
+ ?line case FileName of
+ "if" ->
+ ?line case if_res(E) of
+ ok ->
+ ok;
+ _ ->
+ io_lib:format(?GCC" did not find errors while ~n"
+ "Internal_pp found the following Error = ~p~n",[E])
+ end;
+ _ ->
+ io_lib:format(?GCC" did not find errors while ~n"
+ "Internal_pp found the following Error = ~p~n",[lists:flatten(E)])
+ end;
+
+ {_, {error,X}} ->
+ io_lib:format("Internal_pp did not find errors while ~n"
+ ?GCC" found the following Error = ~p~n",[X]);
+
+ _ ->
+
+ ?line file:write_file("/tmp/Erl.pp",list_to_binary(Erl)),
+ ?line file:write_file("/tmp/Gcc.pp",list_to_binary(Gcc)),
+
+ ?line Res = os:cmd("diff -b -w /tmp/Erl.pp /tmp/Gcc.pp"),
+ ?line test_server:format("///////////{error,E} E ~p FileName~p~n",[Res,FileName]),
+ ?line case {Res, FileName} of
+ {[], _} ->
+ ?line test_server:format("Diff = [] OK!!!!!!~n"),
+ ok;
+ {_, "predef_time"} ->
+ Tokens = string:tokens(Res,"\n"),
+ ?line test_server:format("///////////{error,E} Tokens~p~n",[Tokens]),
+ case Tokens of
+ ["3c3",_,"---",_,"5c5",_,"---",_,"9c9",_,"---",_] ->
+ ok;
+ _ ->
+ io_lib:format("Diff Result = ~p~n",[Res])
+ end;
+ _ ->
+ io_lib:format("Diff Result = ~p~n",[Res])
+ end
+ end.
+
+
+
+
+
+pp_erl(File, Flags) ->
+ case ic_pp:run(File,Flags) of
+ {ok, [$#, $ , $1 | Rest], []} ->
+ [$#, $ , $1 | Rest];
+ {ok, [$#, $ , $1 | _Rest], Warning} ->
+ {warning,Warning};
+ {error,Error} ->
+ {error,Error}
+ end.
+
+pp_gcc(File, Flags) ->
+ Cmd = ?GCC" -x c++ -E",
+ Line = Cmd++" "++Flags++" "++File,
+
+ case os:cmd(Line) of
+ [$#, $ , $1 | Rest] ->
+ [$#, $ , $1 | Rest];
+ Res ->
+
+ case string:str(Res,"# 1 \"") of
+ 0 ->
+ {error,Res};
+ X ->
+ {error, string:sub_string(Res, 1, X-1)}
+ end
+ end.
+
+
+is_ok([],_Gcc) ->
+ yes;
+is_ok([{FileName,Line,Text}|T],Gcc) ->
+ Str = FileName++":"++integer_to_list(Line)++": "++Text,
+ case string:str(Gcc,Str) of
+ 0 ->
+ io:format("~n is_ok Internal_pp missed Error = ~s~n",[Str]),
+ no;
+ _X ->
+ is_ok(T,Gcc)
+ end;
+is_ok([Str|T],Gcc) ->
+ case string:str(Gcc,Str) of
+ 0 ->
+ io:format("~n is_ok Internal_pp missed Error = ~s~n",[Str]),
+ no;
+ _X ->
+ is_ok(T,Gcc)
+ end.
+
+
+to_list(X) when is_atom(X) -> atom_to_list(X);
+to_list(X) -> X.
+
+
+
+if_res(E) ->
+ if_res(E,1).
+
+if_res([H|T],Nr) ->
+ %% Dir = "/clearcase/otp/libraries/ic/test/ic_pp_SUITE_data/if.idl",
+ case {Nr, H} of
+ {1, {_Dir, 2, "only '#if 0' is implemented at present"}} ->
+ if_res(T,Nr+1);
+ {2, {_Dir, 3, "only '#if 0' is implemented at present"}} ->
+ if_res(T,Nr+1);
+ {3, {_Dir, 5, "`else' command is not implemented at present"}} ->
+ if_res(T,Nr+1);
+ {4, {_Dir, 9, "`elif' command is not implemented at present"}} ->
+ if_res(T,Nr+1);
+ {5, {_Dir, 11, "`else' command is not implemented at present"}} ->
+ ok;
+ _ ->
+ error
+ end;
+if_res(_, _) ->
+ error.
+
+
+
diff --git a/lib/ic/test/ic_pp_SUITE_data/arg.idl b/lib/ic/test/ic_pp_SUITE_data/arg.idl
new file mode 100644
index 0000000000..b4d266121d
--- /dev/null
+++ b/lib/ic/test/ic_pp_SUITE_data/arg.idl
@@ -0,0 +1,38 @@
+
+
+// %CopyrightBegin%
+//
+// 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%
+#define xstr (s) str(s)
+#define str(s) #s
+#define foo 4
+
+xstr(foo);
+
+#define x(kalle)stina
+x(kurt)
+x
+
+#define y(kalle) stina
+y(kurt)
+y
+
+#define a(kalle) stina
+a(kurt)
+a
+
+#define b (kalle) stina
+b(kurt)
diff --git a/lib/ic/test/ic_pp_SUITE_data/cascade.idl b/lib/ic/test/ic_pp_SUITE_data/cascade.idl
new file mode 100644
index 0000000000..8dff1ee99f
--- /dev/null
+++ b/lib/ic/test/ic_pp_SUITE_data/cascade.idl
@@ -0,0 +1,29 @@
+
+
+// %CopyrightBegin%
+//
+// 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%
+#define BUFS 1020
+#define TABS BUFS
+#undef BUFS
+#define BUFS 37
+
+
+main()
+{
+ TABS;
+
+}
diff --git a/lib/ic/test/ic_pp_SUITE_data/comment.idl b/lib/ic/test/ic_pp_SUITE_data/comment.idl
new file mode 100644
index 0000000000..d2ca3e7872
--- /dev/null
+++ b/lib/ic/test/ic_pp_SUITE_data/comment.idl
@@ -0,0 +1,72 @@
+
+
+// %CopyrightBegin%
+//
+// 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%
+#define T 12
+#define F T
+
+//comment
+/*exception except {};*/
+
+// comment
+ // comment
+/* another */
+ /* another */
+/* still
+another */
+ /* still
+ another */
+__LINE__
+/* yet \
+ another */
+// yet \
+ another
+__LINE__
+
+#include "all.c"
+#include <all.c>
+#include /* comment */ "all.c"
+#include /* comment */ <all.c>
+#include "all.c" /* comment */
+#include <all.c> /* comment */
+#include // "all.c"
+#include // <all.c>
+#include "all.c" // comment
+#include <all.c> // comment
+#include "all/*cc*/.c"
+#include <all/*cc*/.c>
+
+main()
+{
+ printf(" %d \n",F);
+ a();
+
+}
+//comment
+/*exception hell {};*/
+#undef T
+#define T "3/*com\
+ment*/4"
+a()
+{
+ printf(" %d \n",F);
+ printf(" %d \n",T);
+}
+
+b()
+{}
+
diff --git a/lib/ic/test/ic_pp_SUITE_data/concat.idl b/lib/ic/test/ic_pp_SUITE_data/concat.idl
new file mode 100644
index 0000000000..b8527fadfc
--- /dev/null
+++ b/lib/ic/test/ic_pp_SUITE_data/concat.idl
@@ -0,0 +1,60 @@
+
+
+// %CopyrightBegin%
+//
+// 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%
+#define sune kurt
+#define a(name) a #name name##_command
+#define b(name) b #name name## _command
+#define c(name) c #name name ##_command
+#define d(name) d #name name ## _command
+#define e(name) e #name command ## _command
+#define f(name) f #name command ## %_command
+#define g(name) g #name name ## %_command
+#define h(name) h #name %_command ## name
+#define i(name) i #name name ## _ ## name
+#define j(name) j #name name ## name
+#define k(name) k #name name ## name
+#define l(name) l #name !name ## name
+#define m(name) m #name name ## !name
+#define n(name) n #name !name ## !name
+#define o(name) stina
+#define p(name) name
+#define q1(name) q1 #name j(name) ## j(name)
+#define q2(name) q2 #name j(name)
+#define q3(name) q3 #name !! ## j(name)
+#define q4(name) q4 #name ## j(name)
+
+a(quit)
+b(quit)
+c(quit)
+d(quit)
+e(quit)
+f(quit)
+g(sune)
+h(sune)
+i(sune)
+j(sune)
+l(sune)
+m(sune)
+n(sune)
+k(j(sune))
+k(o(sune))
+k(p(sune))
+q1(sune)
+q2(sune)
+q3(sune)
+q4(sune)
diff --git a/lib/ic/test/ic_pp_SUITE_data/define.idl b/lib/ic/test/ic_pp_SUITE_data/define.idl
new file mode 100644
index 0000000000..6aac63dd1e
--- /dev/null
+++ b/lib/ic/test/ic_pp_SUITE_data/define.idl
@@ -0,0 +1,41 @@
+
+
+// %CopyrightBegin%
+//
+// 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%
+#define 8
+#define
+#define a
+#define _a
+#define b dfs
+#define 9 fdas
+#define a8
+#define A
+#define (c) fadfas
+#define )c) fadfas
+#define % c) fadfas
+#define d(p) kfdsa
+#define e(p) sinus(p)
+#warning warning line
+#define w%er percent
+#define q() no_para
+#warning warning line
+#undef
+#undef 8
+#undef a
+#undef b
+#undef _a d(kk)
+
diff --git a/lib/ic/test/ic_pp_SUITE_data/if.idl b/lib/ic/test/ic_pp_SUITE_data/if.idl
new file mode 100644
index 0000000000..c381fa73ee
--- /dev/null
+++ b/lib/ic/test/ic_pp_SUITE_data/if.idl
@@ -0,0 +1,32 @@
+
+
+// %CopyrightBegin%
+//
+// 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%
+#define kurt 12
+#if !true
+#if X == 1
+ett
+#else
+else
+#endif
+true
+#elif kurt
+trueelif
+#else
+trueelse
+#endif
+end
diff --git a/lib/ic/test/ic_pp_SUITE_data/if_zero.idl b/lib/ic/test/ic_pp_SUITE_data/if_zero.idl
new file mode 100644
index 0000000000..d715f9d61e
--- /dev/null
+++ b/lib/ic/test/ic_pp_SUITE_data/if_zero.idl
@@ -0,0 +1,31 @@
+
+
+// %CopyrightBegin%
+//
+// 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%
+#if 0
+pelle = mallan
+#endif
+pelle = stina
+#if 0
+kalle = stina
+#endif
+kalle = mallan
+#if 0
+kurt = fia
+#endif
+fia = kurt
+
diff --git a/lib/ic/test/ic_pp_SUITE_data/improp_nest_constr.idl b/lib/ic/test/ic_pp_SUITE_data/improp_nest_constr.idl
new file mode 100644
index 0000000000..463ee3c695
--- /dev/null
+++ b/lib/ic/test/ic_pp_SUITE_data/improp_nest_constr.idl
@@ -0,0 +1,30 @@
+
+
+// %CopyrightBegin%
+//
+// 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%
+#define double(x) (2*(x))
+#define call_with_1(x) x(1)
+
+#define strange(file) fprintf (file, "%s %d",
+
+main()
+{
+ call_with_1(double);
+ strange(stderr) p, 35)
+
+}
+
diff --git a/lib/ic/test/ic_pp_SUITE_data/inc.idl b/lib/ic/test/ic_pp_SUITE_data/inc.idl
new file mode 100644
index 0000000000..0dcd637082
--- /dev/null
+++ b/lib/ic/test/ic_pp_SUITE_data/inc.idl
@@ -0,0 +1,68 @@
+
+
+// %CopyrightBegin%
+//
+// 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%
+
+int x;
+
+#include "head.h"
+#warning line nr
+main()
+{
+ printf(test());
+}
+
+
+
+
+
+
+
+
+#define C false
+#define Z on
+#include "inc2.h"
+#undef Z
+"Ca" C
+"Za" Z
+#include "inc2.h"
+"Cb" C
+"Zb" Z
+
+main()
+{
+#define Q(a,b) sinus(a,b kurt ## b)
+ if (Q(34,56)=='NULL') printf(" T AAA%sEEEE \n",Q);
+ printf(" %d \n",F);
+ a();
+}
+//comment
+/*exception
+hell {};*/
+#undef T
+#define T "3/*com\ment*/4"
+#define T 33
+#define F again
+a ()
+{
+ printf(" %d \n",F);
+ printf(" %d \n",T);
+}
+
+b()
+{}
+
diff --git a/lib/ic/test/ic_pp_SUITE_data/included1.idl b/lib/ic/test/ic_pp_SUITE_data/included1.idl
new file mode 100644
index 0000000000..4cd26c4543
--- /dev/null
+++ b/lib/ic/test/ic_pp_SUITE_data/included1.idl
@@ -0,0 +1,35 @@
+
+
+// %CopyrightBegin%
+//
+// Copyright Ericsson AB 2000-2010. All Rights Reserved.
+//
+// The contents of this file are subject to the Erlang Public License,
+// Version 1.1, (the "License"); you may not use this file except in
+// compliance with the License. You should have received a copy of the
+// Erlang Public License along with this software. If not, it can be
+// retrieved online at http://www.erlang.org/.
+//
+// Software distributed under the License is distributed on an "AS IS"
+// basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+// the License for the specific language governing rights and limitations
+// under the License.
+//
+// %CopyrightEnd%
+#ifndef INCLUDED1_IDL
+#define INCLUDED1_IDL
+
+
+#ifndef SOMETHING
+#endif
+
+
+struct s {
+
+ long l;
+
+};
+
+
+
+#endif
diff --git a/lib/ic/test/ic_pp_SUITE_data/included2.idl b/lib/ic/test/ic_pp_SUITE_data/included2.idl
new file mode 100644
index 0000000000..7cc44eef3e
--- /dev/null
+++ b/lib/ic/test/ic_pp_SUITE_data/included2.idl
@@ -0,0 +1,41 @@
+
+
+// %CopyrightBegin%
+//
+// Copyright Ericsson AB 2000-2010. All Rights Reserved.
+//
+// The contents of this file are subject to the Erlang Public License,
+// Version 1.1, (the "License"); you may not use this file except in
+// compliance with the License. You should have received a copy of the
+// Erlang Public License along with this software. If not, it can be
+// retrieved online at http://www.erlang.org/.
+//
+// Software distributed under the License is distributed on an "AS IS"
+// basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+// the License for the specific language governing rights and limitations
+// under the License.
+//
+// %CopyrightEnd%
+#ifndef INCLUDED2_IDL
+#define INCLUDED2_IDL
+
+#include "included1.idl"
+
+
+#ifdef SOMETHING
+#endif
+
+
+module m {
+
+ struct t {
+
+ s st;
+
+ };
+
+
+};
+
+
+#endif
diff --git a/lib/ic/test/ic_pp_SUITE_data/includer.idl b/lib/ic/test/ic_pp_SUITE_data/includer.idl
new file mode 100644
index 0000000000..c6ebc234e8
--- /dev/null
+++ b/lib/ic/test/ic_pp_SUITE_data/includer.idl
@@ -0,0 +1,45 @@
+
+
+// %CopyrightBegin%
+//
+// Copyright Ericsson AB 2000-2010. All Rights Reserved.
+//
+// The contents of this file are subject to the Erlang Public License,
+// Version 1.1, (the "License"); you may not use this file except in
+// compliance with the License. You should have received a copy of the
+// Erlang Public License along with this software. If not, it can be
+// retrieved online at http://www.erlang.org/.
+//
+// Software distributed under the License is distributed on an "AS IS"
+// basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+// the License for the specific language governing rights and limitations
+// under the License.
+//
+// %CopyrightEnd%
+#ifndef INCLUDER_IDL
+#define INCLUDER_IDL
+
+#include "included1.idl"
+#include "included2.idl"
+
+#ifdef SOMETHING
+#endif
+
+
+
+module n {
+
+ interface j {
+
+ s op(in m::t inpar);
+
+ };
+
+};
+
+
+
+
+#endif
+
+
diff --git a/lib/ic/test/ic_pp_SUITE_data/line.idl b/lib/ic/test/ic_pp_SUITE_data/line.idl
new file mode 100644
index 0000000000..5bd9c9446d
--- /dev/null
+++ b/lib/ic/test/ic_pp_SUITE_data/line.idl
@@ -0,0 +1,45 @@
+
+
+// %CopyrightBegin%
+//
+// 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%
+#line
+#line 8
+#line 8a
+#line 12 abc.c
+#line 12 "kurt.c"
+#warning fdafdsaf
+
+
+#define T 12
+#define F T
+#define Q(a) sinus(a)
+#undef Q
+#
+#line 12
+#warning test of warning
+#warning second of warning
+#warning third of warning
+#pragma kurt
+#ident kurt
+#kurt fdsafd
+#line 20
+main()
+{
+ if (Q(34,56)=='NULL') printf(" T AAA%sEEEE \n",Q);
+ printf(" %d \n",F);
+}
+sune
diff --git a/lib/ic/test/ic_pp_SUITE_data/misc.idl b/lib/ic/test/ic_pp_SUITE_data/misc.idl
new file mode 100644
index 0000000000..9c18610fcf
--- /dev/null
+++ b/lib/ic/test/ic_pp_SUITE_data/misc.idl
@@ -0,0 +1,44 @@
+
+
+// %CopyrightBegin%
+//
+// 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%
+#define str(s) #s
+str(fool);
+str(foo);
+str(kurt);
+#define xstr(s) str(s)
+#define foo 4
+#define kurt sune
+#define sune 17
+
+xstr(fool);
+xstr(foo);
+xstr(kurt);
+
+#define a(b) b #8b
+#define r(b) b #
+#define t(b) b ## a
+a(sinus)
+
+#define ww #www
+ww
+
+#define x 14 + y
+#define y 12 + #x
+x
+
+#define e(a) cosinus(a)
diff --git a/lib/ic/test/ic_pp_SUITE_data/nopara.idl b/lib/ic/test/ic_pp_SUITE_data/nopara.idl
new file mode 100644
index 0000000000..1bb137da11
--- /dev/null
+++ b/lib/ic/test/ic_pp_SUITE_data/nopara.idl
@@ -0,0 +1,35 @@
+
+
+// %CopyrightBegin%
+//
+// 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%
+#11a
+#define xstr str(s) + kurt*2;
+#define asdf pragma
+#asdf
+#define asd #pragma asd
+
+#10
+#12 8kurt
+
+#define sss "stringing in the rain"
+#define ddd "string
+ing in the rain" asd
+#line 20
+#include "head.h" qqqq
+#include %!#
+#include <sys.h>
+
diff --git a/lib/ic/test/ic_pp_SUITE_data/predef.idl b/lib/ic/test/ic_pp_SUITE_data/predef.idl
new file mode 100644
index 0000000000..d8abcb25d5
--- /dev/null
+++ b/lib/ic/test/ic_pp_SUITE_data/predef.idl
@@ -0,0 +1,33 @@
+
+
+// %CopyrightBegin%
+//
+// 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%
+#define b(q,w) kurt q w
+
+
+b(__LINE__, __FILE__)
+__LINE__
+__FILE__
+
+
+
+b(__INCLUDE_LEVEL__, __BASE_FILE__)
+__INCLUDE_LEVEL__
+__BASE_FILE__
+
+Line __LINE__
+#include "predef.h"
diff --git a/lib/ic/test/ic_pp_SUITE_data/predef_time.idl b/lib/ic/test/ic_pp_SUITE_data/predef_time.idl
new file mode 100644
index 0000000000..05e3ba9175
--- /dev/null
+++ b/lib/ic/test/ic_pp_SUITE_data/predef_time.idl
@@ -0,0 +1,24 @@
+
+
+// %CopyrightBegin%
+//
+// 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%
+#define b(q,w) kurt q w
+b(__DATE__, __TIME__)
+__DATE__
+__TIME__
+
+#include "predef_time.h"
diff --git a/lib/ic/test/ic_pp_SUITE_data/self_ref.idl b/lib/ic/test/ic_pp_SUITE_data/self_ref.idl
new file mode 100644
index 0000000000..a44666272e
--- /dev/null
+++ b/lib/ic/test/ic_pp_SUITE_data/self_ref.idl
@@ -0,0 +1,26 @@
+
+
+// %CopyrightBegin%
+//
+// 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%
+#define foo (4 + foo)
+
+
+main()
+{
+ foo;
+
+}
diff --git a/lib/ic/test/ic_pp_SUITE_data/separate.idl b/lib/ic/test/ic_pp_SUITE_data/separate.idl
new file mode 100644
index 0000000000..a3faf9b986
--- /dev/null
+++ b/lib/ic/test/ic_pp_SUITE_data/separate.idl
@@ -0,0 +1,37 @@
+
+
+// %CopyrightBegin%
+//
+// 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%
+#define xstr(s) str(s)
+#define str(s) #s
+#define foo 4
+#define str1(s) #s lose(s)
+#define foo1 4
+
+main()
+{
+ str(foo);
+ str1(foo1);
+ xstr(foo);
+
+#define qxstr(s) qstr(s)
+ qxstr(qfoo);
+#define qstr(s) #s
+ qstr( 4 ) ;
+#define qfoo 4
+ qstr(qfoo);
+}
diff --git a/lib/ic/test/ic_pp_SUITE_data/swallow_sc.idl b/lib/ic/test/ic_pp_SUITE_data/swallow_sc.idl
new file mode 100644
index 0000000000..71ed329ca6
--- /dev/null
+++ b/lib/ic/test/ic_pp_SUITE_data/swallow_sc.idl
@@ -0,0 +1,37 @@
+
+
+// %CopyrightBegin%
+//
+// 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%
+/* comment \
+ ends */
+// comment\
+ends
+Line __LINE__
+#define SKIP_SPACES(p, limit) \
+{register char *lim = (limit); \
+ while (p != lim) { \
+ if (*p++ != ' ') { \
+ p--; break; }}}
+
+
+main()
+{
+ if (*p != 0)
+ SKIP_SPACES (ppp, lim);
+ else
+ a = 17;
+}
diff --git a/lib/ic/test/ic_pp_SUITE_data/unintended_grp.idl b/lib/ic/test/ic_pp_SUITE_data/unintended_grp.idl
new file mode 100644
index 0000000000..3618bab1bc
--- /dev/null
+++ b/lib/ic/test/ic_pp_SUITE_data/unintended_grp.idl
@@ -0,0 +1,29 @@
+
+
+// %CopyrightBegin%
+//
+// 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%
+#define ceil_div( xz, yz) (xz + yz - 1) / yz
+#define ceil_div2(xz, yz) ((xz) + (yz) - 1) / (yz)
+
+#define b kurt
+
+main()
+{
+ ceil_div(b & c, sizeof(int));
+ ceil_div2(b & c, sizeof(int));
+
+}
diff --git a/lib/ic/test/ic_pragma_SUITE.erl b/lib/ic/test/ic_pragma_SUITE.erl
new file mode 100644
index 0000000000..0edb5d4717
--- /dev/null
+++ b/lib/ic/test/ic_pragma_SUITE.erl
@@ -0,0 +1,295 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 1998-2009. All Rights Reserved.
+%%
+%% The contents of this file are subject to the Erlang Public License,
+%% Version 1.1, (the "License"); you may not use this file except in
+%% compliance with the License. You should have received a copy of the
+%% Erlang Public License along with this software. If not, it can be
+%% retrieved online at http://www.erlang.org/.
+%%
+%% Software distributed under the License is distributed on an "AS IS"
+%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+%% the License for the specific language governing rights and limitations
+%% under the License.
+%%
+%% %CopyrightEnd%
+%%
+%%
+%%-----------------------------------------------------------------
+%% File: ic_pragma_SUITE.erl
+%%
+%% Description:
+%% Test suite for the IFR object registration when
+%% pragmas are engaged
+%%
+%%-----------------------------------------------------------------
+-module(ic_pragma_SUITE).
+
+-include("test_server.hrl").
+-include_lib("orber/include/corba.hrl").
+%%-----------------------------------------------------------------
+%% External exports
+%%-----------------------------------------------------------------
+-export([all/1, init_all/1, finish_all/1]).
+-export([ifr_pragma_reg/1, pragma_error/1, uggly_pragmas/1]).
+
+
+%%-----------------------------------------------------------------
+%% Macros
+%%-----------------------------------------------------------------
+-define(REMAP_EXCEPT(F), case catch F of
+ {'EXCEPTION', E} -> exit(E);
+ R -> R
+ end).
+%% Standard options to the ic compiler, NOTE unholy use of OutDir
+
+-define(OUT(X), filename:join([?config(priv_dir, Config), gen, to_list(X)])).
+
+
+%%-----------------------------------------------------------------
+%% Func: all/1
+%% Args:
+%% Returns:
+%%-----------------------------------------------------------------
+all(doc) -> ["Description", "more description"];
+all(suite) -> {req,
+ [mnesia],
+ {conf, init_all, cases(), finish_all}}.
+
+cases() ->
+ [ifr_pragma_reg,pragma_error,uggly_pragmas].
+
+%%-----------------------------------------------------------------
+%% Init and cleanup functions.
+%%-----------------------------------------------------------------
+init_all(Config) ->
+ io:format("Setting up.....~n"),
+ mnesia:stop(),
+ mnesia:delete_schema([node()]),
+ mnesia:create_schema([node()]),
+ mnesia:start(),
+ orber:install([node()]),
+ orber:start(),
+ if
+ is_list(Config) ->
+ Config;
+ true ->
+ exit("Config not a list")
+ end.
+
+finish_all(Config) ->
+ io:format("Setting down.....~n"),
+ orber:stop(),
+ orber:uninstall(),
+ mnesia:stop(),
+ mnesia:delete_schema([node()]),
+ Config.
+
+
+
+
+%%-----------------------------------------------------------------
+%% Test Case: IFR registration with pragmas
+%%-----------------------------------------------------------------
+ifr_pragma_reg(doc) ->
+ ["Checks that IFR object is correctly registered under pragma engagement."];
+ifr_pragma_reg(suite) -> [];
+ifr_pragma_reg(Config) when is_list(Config) ->
+ ?REMAP_EXCEPT(ifr_pragma_reg_run(Config)).
+
+ifr_pragma_reg_run(Config) ->
+ DataDir = ?config(data_dir, Config),
+ OutDir = ?OUT(ifr_pragma_reg),
+ File0 = filename:join(DataDir, reg_m0),
+ ?line ok = ic:gen(File0, stdopts(OutDir)++[{preproc_flags,
+ "-I" ++ DataDir}]),
+ ?line ok = compile(OutDir, ifr_pragma_files()),
+ code:add_pathz(OutDir),
+
+ %% OE_register for all files
+ ?line ok = 'oe_reg_m0':'oe_register'(),
+
+ %% Pragma registration test
+ OE_IFR = orber_ifr:find_repository(),
+ io:format("~n##### Starting the test case #####~n"),
+ check_pragma_effect(OE_IFR,"IDL:M1/T1:1.0"),
+ check_pragma_effect(OE_IFR,"DCE:d62207a2-011e-11ce-88b4-0800090b5d3e:3"),
+ check_pragma_effect(OE_IFR,"IDL:P2/T3:1.0"),
+ check_pragma_effect(OE_IFR,"IDL:P1/M2/T4:2.4"),
+
+ %% OE_unregister for all files
+ ?line ok = 'oe_reg_m0':'oe_unregister'(),
+ code:del_path(OutDir),
+ ok.
+
+
+ifr_pragma_files() -> ['oe_reg_m0'].
+
+
+check_pragma_effect(OE_IFR,ID) ->
+ io:format("Checking for existance of : ~s~n",[ID]),
+ case orber_ifr:lookup_id(OE_IFR,ID) of
+ [] ->
+ test_server:fail(ID ++ " does not exist"),
+ false;
+ {Def,_} ->
+ io:format("Id refers to = {~p,#Bin}~n",[Def]),
+ true
+ end.
+
+
+
+
+%%-----------------------------------------------------------------
+%% Test Case: Syntactical / Semantical error pragma definitions
+%%-----------------------------------------------------------------
+pragma_error(doc) ->
+ ["Finds errornous pragma definitions under compilation."];
+pragma_error(suite) -> [];
+pragma_error(Config) when is_list(Config) ->
+ ?REMAP_EXCEPT(pragma_error_run(Config)).
+
+pragma_error_run(Config) ->
+ DataDir = ?config(data_dir, Config),
+ OutDir = ?OUT(pragma_error),
+ File1 = filename:join(DataDir, reg_m1),
+ File2 = filename:join(DataDir, reg_m2),
+ File3 = filename:join(DataDir, reg_m3),
+ File4 = filename:join(DataDir, reg_m4),
+ File5 = filename:join(DataDir, reg_m5),
+ File6 = filename:join(DataDir, reg_m6),
+
+ ?line error = ic:gen(File1, stdopts(OutDir)++[{preproc_flags,
+ "-I" ++ DataDir}] ),
+
+ ?line error = ic:gen(File2, stdopts(OutDir)++[{preproc_flags,
+ "-I" ++ DataDir}] ),
+
+ ?line error = ic:gen(File3, stdopts(OutDir)++[{preproc_flags,
+ "-I" ++ DataDir}] ),
+
+ ?line ok = ic:gen(File4, stdopts(OutDir)++[{preproc_flags,
+ "-I" ++ DataDir}] ),
+
+ ?line error = ic:gen(File5, stdopts(OutDir)++[{preproc_flags,
+ "-I" ++ DataDir}] ),
+
+ ?line error = ic:gen(File6, stdopts(OutDir)++[{preproc_flags,
+ "-I" ++ DataDir}] ),
+ ok.
+
+
+
+
+%%-----------------------------------------------------------------
+%% Test Case: IFR registration with realy uggly placed pragmas
+%%-----------------------------------------------------------------
+uggly_pragmas(doc) ->
+ ["Checks that IFR object is correctly registered under really uggly pragma engagement."];
+uggly_pragmas(suite) -> [];
+uggly_pragmas(Config) when is_list(Config) ->
+ ?REMAP_EXCEPT(uggly_pragmas_run(Config)).
+
+uggly_pragmas_run(Config) ->
+ DataDir = ?config(data_dir, Config),
+ OutDir = ?OUT(ifr_pragma_reg),
+ File0 = filename:join(DataDir, uggly),
+
+ ?line ok = ic:gen(File0, stdopts(OutDir)++[{preproc_flags,
+ "-I" ++ DataDir}]),
+
+ ?line ok = compile(OutDir, uggly_pragma_files()),
+ code:add_pathz(OutDir),
+
+ %% OE_register for all files
+ ?line ok = 'oe_uggly':'oe_register'(),
+
+ %% Pragma registration test
+ OE_IFR = orber_ifr:find_repository(),
+ io:format("~n##### Starting the test case #####~n"),
+
+ check_pragma_effect(OE_IFR, "IDL:M:1.0"),
+ check_pragma_effect(OE_IFR, "LOCAL:SomeLocalId:10"),
+ check_pragma_effect(OE_IFR, "LOCAL:SomeLocalId:11"),
+ check_pragma_effect(OE_IFR, "LOCAL:SomeLocalId:17"),
+ check_pragma_effect(OE_IFR, "LOCAL:SomeLocalId:34"),
+ check_pragma_effect(OE_IFR, "IDL:Exc1:2.2"),
+ check_pragma_effect(OE_IFR, "IDL:Exc2:2.2"),
+ check_pragma_effect(OE_IFR, "IDL:S:1.0"),
+ check_pragma_effect(OE_IFR, "IDL:U:1.0"),
+ check_pragma_effect(OE_IFR, "LOCAL:SomeLocalId:23"),
+
+ %% OE_unregister for all files
+ ?line ok = 'oe_uggly':'oe_unregister'(),
+
+ code:del_path(OutDir),
+ ok.
+
+
+uggly_pragma_files() -> ['oe_uggly'].
+
+
+
+
+%%----------------------------
+
+
+stdopts(OutDir) ->
+ [{outdir, OutDir}, {maxerrs, infinity}].
+
+
+compile(Dir, Files) ->
+ compile(Dir, Files, []).
+
+compile(Dir, Files, Opts) ->
+ {ok, Cwd} = file:get_cwd(),
+ file:set_cwd(Dir),
+ io:format("Changing to ~p~n", [Dir]),
+ case catch do_compile(Files, Opts) of
+ ok ->
+ file:set_cwd(Cwd);
+ Err ->
+ file:set_cwd(Cwd),
+ test_server:fail(Err)
+ end.
+
+do_compile([], _Opts) -> ok;
+do_compile([F | Fs], Opts) ->
+ io:format("Compiling ~p", [F]),
+ case compile:file(F, Opts) of
+ ok ->
+ io:format(" ok~n", []),
+ do_load(F, Opts),
+ do_compile(Fs, Opts);
+ {ok, _} ->
+ io:format(" ok~n", []),
+ do_load(F, Opts),
+ do_compile(Fs, Opts);
+ {ok, _, _} ->
+ io:format(" ok~n", []),
+ do_load(F, Opts),
+ do_compile(Fs, Opts);
+ Err ->
+ io:format(" error: ~p~n", [Err]),
+ Err
+ end.
+
+do_load(File, Opts) ->
+ case lists:member(load, Opts) of
+ true ->
+ io:format("Loading file ~p", [File]),
+ code:purge(File),
+ R = code:load_abs(File),
+ io:format("Loaded: ~p", [R]);
+ false ->
+ ok
+ end.
+
+
+to_list(X) when is_atom(X) -> atom_to_list(X);
+to_list(X) -> X.
+
+
+
diff --git a/lib/ic/test/ic_pragma_SUITE_data/reg_m0.idl b/lib/ic/test/ic_pragma_SUITE_data/reg_m0.idl
new file mode 100644
index 0000000000..80f0f2cdd1
--- /dev/null
+++ b/lib/ic/test/ic_pragma_SUITE_data/reg_m0.idl
@@ -0,0 +1,77 @@
+
+// %CopyrightBegin%
+//
+// 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%
+
+// Normal pragmas
+
+module M1 {
+
+ typedef long T1;
+
+ typedef long T2;
+
+#pragma ID T2 "DCE:d62207a2-011e-11ce-88b4-0800090b5d3e:3"
+
+};
+
+
+#pragma prefix "P1"
+
+module M2 {
+
+ module M3 {
+
+#pragma prefix "P2"
+
+ interface I1 {
+ void Op( in short b,
+ out short c);
+ };
+ typedef long T3;
+ };
+
+
+ typedef long T4;
+
+#pragma version T4 2.4
+
+};
+
+
+
+/*
+
+ Specified types with the following scoped names
+ and RepositoryIds
+
+ ::M1::T1 IDL:M1/T1:1.0
+
+ ::M1::T2 DCE:d62207a2-011e-11ce-88b4-0800090b5d3e:3
+
+ ::M2::M3::T3 IDL:P2/T3:1.0
+
+ ::M2::T4 IDL:P1/M2/T4:2.4
+
+*/
+
+
+
+
+
+
+
+
diff --git a/lib/ic/test/ic_pragma_SUITE_data/reg_m1.idl b/lib/ic/test/ic_pragma_SUITE_data/reg_m1.idl
new file mode 100644
index 0000000000..6c22788290
--- /dev/null
+++ b/lib/ic/test/ic_pragma_SUITE_data/reg_m1.idl
@@ -0,0 +1,75 @@
+
+
+// %CopyrightBegin%
+//
+// 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%
+// Bad pragma IDs
+
+// Completelly bad id
+module M1 {
+
+ typedef long T1;
+
+ typedef long T2;
+
+#pragma ID T2 "CompletelyBadId"
+
+};
+
+
+// Bad id, should start with DCE
+module M2 {
+
+ typedef long T1;
+
+ typedef long T2;
+
+#pragma ID T2 "BAD:d62207a2-011e-11ce-88b4-0800090b5d3e:3"
+
+};
+
+
+// Bad version in ID : not a short number
+module M3 {
+
+ typedef long T1;
+
+ typedef long T2;
+
+#pragma ID T2 "DCE:d62207a2-011e-11ce-88b4-0800090b5d3e:ABCD"
+
+};
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/lib/ic/test/ic_pragma_SUITE_data/reg_m2.idl b/lib/ic/test/ic_pragma_SUITE_data/reg_m2.idl
new file mode 100644
index 0000000000..1751751295
--- /dev/null
+++ b/lib/ic/test/ic_pragma_SUITE_data/reg_m2.idl
@@ -0,0 +1,40 @@
+
+
+// %CopyrightBegin%
+//
+// 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%
+// Bad pragma versions
+
+
+// Bad major version : not a short number
+module M1 {
+
+ typedef long T4;
+
+#pragma version T4 2000000000.4
+
+};
+
+// Bad minor version : not a short number
+module M2 {
+
+ typedef long T4;
+
+#pragma version T4 2.4000000000000
+
+};
+
+
diff --git a/lib/ic/test/ic_pragma_SUITE_data/reg_m3.idl b/lib/ic/test/ic_pragma_SUITE_data/reg_m3.idl
new file mode 100644
index 0000000000..b7c9da249f
--- /dev/null
+++ b/lib/ic/test/ic_pragma_SUITE_data/reg_m3.idl
@@ -0,0 +1,38 @@
+
+
+// %CopyrightBegin%
+//
+// 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%
+// Bad pragma prefixs
+
+module M2 {
+
+ module M3 {
+
+#pragma prefix P2 // Should be "P2"
+
+ interface I1 {
+ void foo( in short b,
+ out short c);
+ };
+ typedef long T3;
+ };
+
+
+ typedef long T4;
+};
+
+
diff --git a/lib/ic/test/ic_pragma_SUITE_data/reg_m4.idl b/lib/ic/test/ic_pragma_SUITE_data/reg_m4.idl
new file mode 100644
index 0000000000..0c7079e3dd
--- /dev/null
+++ b/lib/ic/test/ic_pragma_SUITE_data/reg_m4.idl
@@ -0,0 +1,64 @@
+
+
+// %CopyrightBegin%
+//
+// 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%
+// Unrecognmizable pragmas
+
+module M1 {
+
+ typedef long T1;
+
+ typedef long T2;
+
+
+ // Should be ID directive
+
+#pragma ShouldBeId T2 "DCE:d62207a2-011e-11ce-88b4-0800090b5d3e:3"
+
+};
+
+ // Should be prefix directive
+
+#pragma ShouldBePrefix "P1"
+
+module M2 {
+
+ module M3 {
+
+ // Should be prefix directive
+
+#pragma ShouldBePrefix "P2"
+
+ interface I1 {
+ void foo( in short b,
+ out short c);
+ };
+ typedef long T3;
+ };
+
+
+ typedef long T4;
+
+
+ // Should be version
+
+#pragma ShouldBeVersion T4 2.4
+
+};
+
+
+
diff --git a/lib/ic/test/ic_pragma_SUITE_data/reg_m5.idl b/lib/ic/test/ic_pragma_SUITE_data/reg_m5.idl
new file mode 100644
index 0000000000..cbf053fac4
--- /dev/null
+++ b/lib/ic/test/ic_pragma_SUITE_data/reg_m5.idl
@@ -0,0 +1,28 @@
+
+
+// %CopyrightBegin%
+//
+// 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%
+
+// Version not in valid form : major.ninor
+
+module M1 {
+
+ typedef long T4;
+
+ #pragma version T4 2
+
+};
diff --git a/lib/ic/test/ic_pragma_SUITE_data/reg_m6.idl b/lib/ic/test/ic_pragma_SUITE_data/reg_m6.idl
new file mode 100644
index 0000000000..b7c9da249f
--- /dev/null
+++ b/lib/ic/test/ic_pragma_SUITE_data/reg_m6.idl
@@ -0,0 +1,38 @@
+
+
+// %CopyrightBegin%
+//
+// 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%
+// Bad pragma prefixs
+
+module M2 {
+
+ module M3 {
+
+#pragma prefix P2 // Should be "P2"
+
+ interface I1 {
+ void foo( in short b,
+ out short c);
+ };
+ typedef long T3;
+ };
+
+
+ typedef long T4;
+};
+
+
diff --git a/lib/ic/test/ic_pragma_SUITE_data/reg_m7.idl b/lib/ic/test/ic_pragma_SUITE_data/reg_m7.idl
new file mode 100644
index 0000000000..349c13b244
--- /dev/null
+++ b/lib/ic/test/ic_pragma_SUITE_data/reg_m7.idl
@@ -0,0 +1,62 @@
+
+
+// %CopyrightBegin%
+//
+// 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%
+
+// Very uggly pragmas
+
+
+#pragma prefix "P1" // Normal pragma
+
+module M4 {
+
+ module M5 {
+
+#pragma prefix "P2" // Inside a parameter list
+
+ interface I1 {
+ void Op(
+ #pragma prefix "P2" // Inside a parameter list
+ in short b,
+ #pragma prefix "P2" // Inside a parameter list
+ out short c
+ #pragma prefix "P2" // Inside a parameter list
+ );
+ };
+ typedef long T3;
+ };
+
+};
+
+
+
+/*
+
+ Specified types with the following scoped names
+ and RepositoryIds
+
+ ::M4::M5::T3 IDL:P2/T3:1.0
+
+*/
+
+
+
+
+
+
+
+
diff --git a/lib/ic/test/ic_pragma_SUITE_data/uggly.idl b/lib/ic/test/ic_pragma_SUITE_data/uggly.idl
new file mode 100644
index 0000000000..8ed3ac57ec
--- /dev/null
+++ b/lib/ic/test/ic_pragma_SUITE_data/uggly.idl
@@ -0,0 +1,204 @@
+
+
+// %CopyrightBegin%
+//
+// 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%
+// Really uggly pragmas
+
+
+struct S {
+
+#pragma ID TDL1 "LOCAL:SomeLocalId:1"
+#pragma ID TDL1 "LOCAL:SomeLocalId:2"
+
+long a
+
+#pragma ID TDL1 "LOCAL:SomeLocalId:3"
+#pragma ID TDL1 "LOCAL:SomeLocalId:4"
+
+;
+
+#pragma ID TDL1 "LOCAL:SomeLocalId:5"
+#pragma ID TDL1 "LOCAL:SomeLocalId:6"
+
+long b
+
+#pragma ID TDL1 "LOCAL:SomeLocalId:7"
+#pragma ID TDL1 "LOCAL:SomeLocalId:8"
+
+;
+
+
+#pragma ID TDL1 "LOCAL:SomeLocalId:9"
+#pragma ID TDL1 "LOCAL:SomeLocalId:10"
+
+};
+
+
+typedef long TDL1;
+
+
+exception Exc1{
+
+#pragma version Exc1 2.2
+#pragma ID TDL2 "LOCAL:SomeLocalId:11"
+
+};
+
+
+typedef long TDL2;
+
+
+exception Exc2 {
+
+#pragma version Exc2 2.2
+#pragma ID TDL3 "LOCAL:SomeLocalId:11"
+
+ long a
+
+#pragma ID TDL3 "LOCAL:SomeLocalId:12"
+#pragma ID TDL3 "LOCAL:SomeLocalId:13"
+
+ ;
+
+#pragma ID TDL3 "LOCAL:SomeLocalId:14"
+#pragma ID TDL3 "LOCAL:SomeLocalId:15"
+
+ long b
+
+#pragma ID TDL3 "LOCAL:SomeLocalId:16"
+
+ ;
+
+#pragma ID TDL3 "LOCAL:SomeLocalId:17"
+
+
+};
+
+typedef long TDL3;
+
+enum E {
+#pragma ID E "LOCAL:SomeLocalId:18"
+ a
+#pragma ID E "LOCAL:SomeLocalId:19"
+ ,
+#pragma ID E "LOCAL:SomeLocalId:20"
+ b
+#pragma ID E "LOCAL:SomeLocalId:21"
+,
+#pragma ID E "LOCAL:SomeLocalId:22"
+ c
+#pragma ID E "LOCAL:SomeLocalId:23"
+};
+
+
+
+union U switch (long) {
+
+#pragma ID TDL4 "LOCAL:SomeLocalId:24"
+
+ case 1:
+
+#pragma ID TDL4 "LOCAL:SomeLocalId:25"
+
+ long a
+
+#pragma ID TDL4 "LOCAL:SomeLocalId:26"
+
+;
+
+#pragma ID TDL4 "LOCAL:SomeLocalId:27"
+
+ case 2:
+
+#pragma ID TDL4 "LOCAL:SomeLocalId:28"
+
+ case 3:
+
+#pragma ID TDL4 "LOCAL:SomeLocalId:29"
+
+long b
+
+#pragma ID TDL4 "LOCAL:SomeLocalId:30"
+
+;
+
+#pragma ID TDL4 "LOCAL:SomeLocalId:31"
+
+ default :
+
+#pragma ID TDL4 "LOCAL:SomeLocalId:32"
+
+long c
+
+#pragma ID TDL4 "LOCAL:SomeLocalId:33"
+
+;
+
+#pragma ID TDL4 "LOCAL:SomeLocalId:34"
+
+};
+
+
+typedef long TDL4;
+
+
+
+module M {
+
+ interface I {
+
+ void fun1(
+
+#pragma version fun1 3.0
+#pragma ID TDL5 "LOCAL:SomeLocalId:35"
+
+ in short b
+
+#pragma ID TDL5 "LOCAL:SomeLocalId:36"
+#pragma ID TDL5 "LOCAL:SomeLocalId:37"
+
+ ,
+
+#pragma ID TDL5 "LOCAL:SomeLocalId:38"
+#pragma ID TDL5 "LOCAL:SomeLocalId:39"
+
+ out short c
+
+#pragma ID TDL5 "LOCAL:SomeLocalId:40"
+#pragma ID TDL5 "LOCAL:SomeLocalId:41"
+
+ );
+
+
+ typedef long TDL5;
+
+
+ void fun2(
+
+#pragma ID TDL6 "LOCAL:SomeLocalId:42"
+#pragma ID TDL6 "LOCAL:SomeLocalId:43"
+
+ );
+
+ typedef long TDL6;
+
+ };
+
+
+
+};
+
diff --git a/lib/ic/test/ic_register_SUITE.erl b/lib/ic/test/ic_register_SUITE.erl
new file mode 100644
index 0000000000..ae7578199a
--- /dev/null
+++ b/lib/ic/test/ic_register_SUITE.erl
@@ -0,0 +1,425 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 1998-2009. All Rights Reserved.
+%%
+%% The contents of this file are subject to the Erlang Public License,
+%% Version 1.1, (the "License"); you may not use this file except in
+%% compliance with the License. You should have received a copy of the
+%% Erlang Public License along with this software. If not, it can be
+%% retrieved online at http://www.erlang.org/.
+%%
+%% Software distributed under the License is distributed on an "AS IS"
+%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+%% the License for the specific language governing rights and limitations
+%% under the License.
+%%
+%% %CopyrightEnd%
+%%
+%%
+%%-----------------------------------------------------------------
+%% File: ic_register_SUITE.erl
+%%
+%% Description:
+%% Test suite for the IFR object registration
+%%
+%%-----------------------------------------------------------------
+-module(ic_register_SUITE).
+
+-include("test_server.hrl").
+-include_lib("orber/include/corba.hrl").
+%%-----------------------------------------------------------------
+%% External exports
+%%-----------------------------------------------------------------
+-export([all/1, init_all/1, finish_all/1, ifr_reg_unreg/1]).
+-export([ifr_inheritence_reg/1,ifr_reg_unreg_with_inheritence/1]).
+-export([ifr_reg_unreg_with_inheritence_bad_order/1]).
+
+%%-----------------------------------------------------------------
+%% Internal exports
+%%-----------------------------------------------------------------
+-export([]).
+
+%%-----------------------------------------------------------------
+%% Macros
+%%-----------------------------------------------------------------
+-define(REMAP_EXCEPT(F), case catch F of
+ {'EXCEPTION', E} -> exit(E);
+ R -> R
+ end).
+%% Standard options to the ic compiler, NOTE unholy use of OutDir
+
+-define(OUT(X), filename:join([?config(priv_dir, Config), gen, to_list(X)])).
+
+
+%%-----------------------------------------------------------------
+%% Func: all/1
+%% Args:
+%% Returns:
+%%-----------------------------------------------------------------
+all(doc) -> ["Description", "more description"];
+all(suite) -> {req,
+ [mnesia],
+ {conf, init_all, cases(), finish_all}}.
+
+cases() ->
+ [ifr_reg_unreg,ifr_reg_unreg_with_inheritence,
+ ifr_reg_unreg_with_inheritence_bad_order,ifr_inheritence_reg].
+
+%%-----------------------------------------------------------------
+%% Init and cleanup functions.
+%%-----------------------------------------------------------------
+
+init_all(Config) ->
+ io:format("Setting up.....~n"),
+ mnesia:stop(),
+ mnesia:delete_schema([node()]),
+ mnesia:create_schema([node()]),
+ mnesia:start(),
+ orber:install([node()]),
+ orber:start(),
+ if
+ is_list(Config) ->
+ Config;
+ true ->
+ exit("Config not a list")
+ end.
+
+finish_all(Config) ->
+ io:format("Setting down.....~n"),
+ orber:stop(),
+ orber:uninstall(),
+ mnesia:stop(),
+ mnesia:delete_schema([node()]),
+ Config.
+
+
+
+%%-----------------------------------------------------------------
+%% Test Case: IFR type registration
+%%-----------------------------------------------------------------
+ifr_reg_unreg(doc) ->
+ ["Checks that the generated register/unregister "
+ "code for the IFR is correct."];
+ifr_reg_unreg(suite) -> [];
+ifr_reg_unreg(Config) when is_list(Config) ->
+ ?REMAP_EXCEPT(ifr_reg_unregt_run(Config)).
+
+ifr_reg_unregt_run(Config) ->
+ DataDir = ?config(data_dir, Config),
+ OutDir = ?OUT(ifr_reg_unreg),
+ File0 = filename:join(DataDir, reg_m8),
+ File1 = filename:join(DataDir, reg_m9),
+ File2 = filename:join(DataDir, reg_m10),
+ ?line ok = ic:gen(File0, stdopts(OutDir)++[{preproc_flags,
+ "-I" ++ DataDir}] ),
+ ?line {ok, []} = ic:gen(File0, stdopts(OutDir)++[silent2, {preproc_flags,
+ "-I" ++ DataDir}]),
+ ?line ok = ic:gen(File1, stdopts(OutDir)++[{preproc_flags,
+ "-I" ++ DataDir}] ),
+ ?line {ok, []} = ic:gen(File1, stdopts(OutDir)++[silent2, {preproc_flags,
+ "-I" ++ DataDir}]),
+ ?line ok = ic:gen(File2, stdopts(OutDir)++[{preproc_flags,
+ "-I" ++ DataDir}] ),
+ ?line {ok, []} = ic:gen(File2, stdopts(OutDir)++[silent2, {preproc_flags,
+ "-I" ++ DataDir}]),
+ ?line ok = compile(OutDir, ifr_reg_unreg_files()),
+ code:add_pathz(OutDir),
+ ?line ok = 'oe_reg_m8':'oe_register'(),
+ ?line ok = 'oe_reg_m9':'oe_register'(),
+ ?line ok = 'oe_reg_m10':'oe_register'(),
+ ?line ok = 'oe_reg_m10':'oe_unregister'(),
+ ?line ok = 'oe_reg_m9':'oe_unregister'(),
+ ?line ok = 'oe_reg_m8':'oe_unregister'(),
+ code:del_path(OutDir),
+ ok.
+
+ifr_reg_unreg_files() -> ['oe_reg_m8', 'oe_reg_m9', 'oe_reg_m10'].
+
+
+
+%%-----------------------------------------------------------------
+%% Test Case: IFR registration when object inheritence
+%% is applied and registered.
+%%-----------------------------------------------------------------
+ifr_reg_unreg_with_inheritence(doc) ->
+ ["Checks that the generated register/unregister "
+ "code for the IFR is correct, and works even when"
+ "the object inheritence is registered. This fixes"
+ "two bugs in ifr that caused crash when trying to"
+ "use OE_register/OE_unregister in a sequence of"
+ "compiled files that contained interfaces who"
+ "inherited others in sequence."];
+ifr_reg_unreg_with_inheritence(suite) -> [];
+ifr_reg_unreg_with_inheritence(Config) when is_list(Config) ->
+ ?REMAP_EXCEPT(ifr_reg_unreg_with_inheritence_run(Config)).
+
+ifr_reg_unreg_with_inheritence_run(Config) ->
+ DataDir = ?config(data_dir, Config),
+ OutDir = ?OUT(ifr_reg_unreg),
+ File0 = filename:join(DataDir, reg_m8),
+ File1 = filename:join(DataDir, reg_m9),
+ File2 = filename:join(DataDir, reg_m10),
+ File3 = filename:join(DataDir, reg_m11),
+ File4 = filename:join(DataDir, reg_m12),
+ ?line ok = ic:gen(File0, stdopts(OutDir)++[{preproc_flags,
+ "-I" ++ DataDir}] ),
+ ?line {ok, []} = ic:gen(File0, stdopts(OutDir)++[silent2, {preproc_flags,
+ "-I" ++ DataDir}]),
+ ?line ok = ic:gen(File1, stdopts(OutDir)++[{preproc_flags,
+ "-I" ++ DataDir}] ),
+ ?line {ok, []} = ic:gen(File1, stdopts(OutDir)++[silent2, {preproc_flags,
+ "-I" ++ DataDir}]),
+ ?line ok = ic:gen(File2, stdopts(OutDir)++[{preproc_flags,
+ "-I" ++ DataDir}] ),
+ ?line {ok, []} = ic:gen(File2, stdopts(OutDir)++[silent2, {preproc_flags,
+ "-I" ++ DataDir}]),
+ ?line ok = ic:gen(File3, stdopts(OutDir)++[{preproc_flags,
+ "-I" ++ DataDir}] ),
+ ?line {ok, []} = ic:gen(File3, stdopts(OutDir)++[silent2, {preproc_flags,
+ "-I" ++ DataDir}]),
+ ?line ok = ic:gen(File4, stdopts(OutDir)++[{preproc_flags,
+ "-I" ++ DataDir}] ),
+ ?line {ok, []} = ic:gen(File4, stdopts(OutDir)++[silent2, {preproc_flags,
+ "-I" ++ DataDir}]),
+ ?line ok = compile(OutDir, ifr_reg_unreg_with_inheritence_files()),
+ code:add_pathz(OutDir),
+ ?line ok = 'oe_reg_m8':'oe_register'(),
+ ?line ok = 'oe_reg_m9':'oe_register'(),
+ ?line ok = 'oe_reg_m10':'oe_register'(),
+ ?line ok = 'oe_reg_m11':'oe_register'(),
+ ?line ok = 'oe_reg_m12':'oe_register'(),
+ ?line ok = 'oe_reg_m8':'oe_unregister'(),
+ ?line ok = 'oe_reg_m9':'oe_unregister'(),
+ ?line ok = 'oe_reg_m10':'oe_unregister'(),
+ ?line ok = 'oe_reg_m11':'oe_unregister'(),
+ ?line ok = 'oe_reg_m12':'oe_unregister'(),
+ code:del_path(OutDir),
+ ok.
+
+ifr_reg_unreg_with_inheritence_files() ->
+ ['oe_reg_m8', 'oe_reg_m9', 'oe_reg_m10', 'oe_reg_m11', 'oe_reg_m12'].
+
+
+
+
+
+%%-----------------------------------------------------------------
+%% Test Case: IFR registration when object inheritence
+%% is applied and registered in a bad order.
+%% Modules included and used from an ifr object
+%% are not allready registered when the current
+%% object is getting registered.
+%%-----------------------------------------------------------------
+ifr_reg_unreg_with_inheritence_bad_order(doc) ->
+ ["This tests that ifr registration is done with
+ the right write order."
+ "Modules included and used from an ifr object"
+ "are tested if allready registered when the "
+ "current object is getting registered."];
+ifr_reg_unreg_with_inheritence_bad_order(suite) -> [];
+ifr_reg_unreg_with_inheritence_bad_order(Config) when is_list(Config) ->
+ ?REMAP_EXCEPT(ifr_reg_unreg_with_inheritence_bad_order_run(Config)).
+
+ifr_reg_unreg_with_inheritence_bad_order_run(Config) ->
+ DataDir = ?config(data_dir, Config),
+ OutDir = ?OUT(ifr_reg_unreg),
+ File1 = filename:join(DataDir, reg_m9),
+ File2 = filename:join(DataDir, reg_m10),
+ File4 = filename:join(DataDir, reg_m12),
+ ?line ok = ic:gen(File1, stdopts(OutDir)++[{preproc_flags,
+ "-I" ++ DataDir}] ),
+ ?line {ok, []} = ic:gen(File1, stdopts(OutDir)++[silent2, {preproc_flags,
+ "-I" ++ DataDir}]),
+ ?line ok = ic:gen(File2, stdopts(OutDir)++[{preproc_flags,
+ "-I" ++ DataDir}] ),
+ ?line {ok, []} = ic:gen(File2, stdopts(OutDir)++[silent2, {preproc_flags,
+ "-I" ++ DataDir}]),
+ ?line ok = ic:gen(File4, stdopts(OutDir)++[{preproc_flags,
+ "-I" ++ DataDir}] ),
+ ?line {ok, []} = ic:gen(File4, stdopts(OutDir)++[silent2, {preproc_flags,
+ "-I" ++ DataDir}]),
+ ?line ok = compile(OutDir, ifr_reg_unreg_with_inheritence_files()),
+ code:add_pathz(OutDir),
+ case catch 'oe_reg_m12':'oe_register'() of
+ {'EXIT',Reason1} ->
+ io:format("IFR object missing detected : ~p~n",[Reason1]),
+ true;
+ _ ->
+ test_server:fail("Failed to detect object missing : IDL:M1:1.0~n")
+ end,
+ ?line ok = 'oe_reg_m9':'oe_register'(),
+ case catch 'oe_reg_m10':'oe_register'() of
+ {'EXIT',Reason2} ->
+ io:format("IFR object missing detected : ~p~n",[Reason2]),
+ true;
+ _ ->
+ test_server:fail("Failed to detect object missing : IDL:M0:1.0~n")
+ end,
+ ?line ok = 'oe_reg_m9':'oe_unregister'(),
+ code:del_path(OutDir),
+ ok.
+
+
+
+%%-----------------------------------------------------------------
+%% Test Case: IFR registration with inheritence
+%%-----------------------------------------------------------------
+ifr_inheritence_reg(doc) ->
+ ["Checks that IFR object inheritence is correctly registered."];
+ifr_inheritence_reg(suite) -> [];
+ifr_inheritence_reg(Config) when is_list(Config) ->
+ ?REMAP_EXCEPT(ifr_inh_reg_run(Config)).
+
+ifr_inh_reg_run(Config) ->
+ DataDir = ?config(data_dir, Config),
+ OutDir = ?OUT(ifr_reg_unreg),
+ File0 = filename:join(DataDir, reg_m8),
+ File1 = filename:join(DataDir, reg_m9),
+ File2 = filename:join(DataDir, reg_m10),
+ File3 = filename:join(DataDir, reg_m11),
+ File4 = filename:join(DataDir, reg_m12),
+ ?line ok = ic:gen(File0, stdopts(OutDir)++[{preproc_flags,
+ "-I" ++ DataDir}] ),
+ ?line {ok, []} = ic:gen(File0, stdopts(OutDir)++[silent2, {preproc_flags,
+ "-I" ++ DataDir}]),
+ ?line ok = ic:gen(File1, stdopts(OutDir)++[{preproc_flags,
+ "-I" ++ DataDir}] ),
+ ?line {ok, []} = ic:gen(File1, stdopts(OutDir)++[silent2, {preproc_flags,
+ "-I" ++ DataDir}]),
+ ?line ok = ic:gen(File2, stdopts(OutDir)++[{preproc_flags,
+ "-I" ++ DataDir}] ),
+ ?line {ok, []} = ic:gen(File2, stdopts(OutDir)++[silent2, {preproc_flags,
+ "-I" ++ DataDir}]),
+ ?line ok = ic:gen(File3, stdopts(OutDir)++[{preproc_flags,
+ "-I" ++ DataDir}] ),
+ ?line {ok, []} = ic:gen(File3, stdopts(OutDir)++[silent2, {preproc_flags,
+ "-I" ++ DataDir}]),
+ ?line ok = ic:gen(File4, stdopts(OutDir)++[{preproc_flags,
+ "-I" ++ DataDir}] ),
+ ?line {ok, []} = ic:gen(File4, stdopts(OutDir)++[silent2, {preproc_flags,
+ "-I" ++ DataDir}]),
+ ?line ok = compile(OutDir, ifr_reg_unreg_with_inheritence_files()),
+ code:add_pathz(OutDir),
+ %% OE_register for all files
+ ?line ok = 'oe_reg_m8':'oe_register'(),
+ ?line ok = 'oe_reg_m9':'oe_register'(),
+ ?line ok = 'oe_reg_m10':'oe_register'(),
+ ?line ok = 'oe_reg_m11':'oe_register'(),
+ ?line ok = 'oe_reg_m12':'oe_register'(),
+
+ %% Inheritence registration test
+ OE_IFR = orber_ifr:find_repository(),
+ %% Interfaces that not inherit from other interfaces
+ ?line [] = get_inh(OE_IFR, "IDL:m0/i0:1.0"),
+ ?line [] = get_inh(OE_IFR, "IDL:m1/i1:1.0"),
+ ?line [] = get_inh(OE_IFR, "IDL:m3/i3:1.0"),
+ %% Interfaces that inherit from other interfaces
+ ?line ["IDL:m1/i1:1.0"] = get_inh(OE_IFR, "IDL:m2/i2:1.0"),
+ ?line ["IDL:m1/i1:1.0","IDL:m2/i2:1.0"] = get_inh(OE_IFR, "IDL:m4/i4:1.0"),
+ ?line ["IDL:m3/i3:1.0"] = get_inh(OE_IFR, "IDL:m4/i5:1.0"),
+
+ %% OE_unregister for all files
+ ?line ok = 'oe_reg_m8':'oe_unregister'(),
+ ?line ok = 'oe_reg_m9':'oe_unregister'(),
+ ?line ok = 'oe_reg_m10':'oe_unregister'(),
+ ?line ok = 'oe_reg_m11':'oe_unregister'(),
+ ?line ok = 'oe_reg_m12':'oe_unregister'(),
+ code:del_path(OutDir),
+ ok.
+
+
+get_inh(OE_IFR,ID) ->
+ OE_CURRENT = orber_ifr:lookup_id(OE_IFR,ID),
+ INH_LIST = orber_ifr:get_base_interfaces(OE_CURRENT),
+ case INH_LIST of
+ [] ->
+ io:format("~nInterface ~p inherits from nobody.~n",[ID]),
+ [];
+ _ ->
+ print_inh_list_ids(ID, INH_LIST, [])
+ end.
+
+print_inh_list_ids(_ID, [], Acc) ->
+ lists:reverse(Acc);
+print_inh_list_ids(ID, [H|T], Acc) ->
+ io:format("~n"),
+ Parent = orber_ifr:get_id(H),
+ io:format("Interface ~p inherits from ~p.~n", [ID, Parent]),
+ print_inh_list_ids(ID, T, [Parent|Acc]).
+
+
+
+
+stdopts(OutDir) ->
+ [{outdir, OutDir}, {maxerrs, infinity}].
+
+
+compile(Dir, Files) ->
+ compile(Dir, Files, []).
+
+compile(Dir, Files, Opts) ->
+ {ok, Cwd} = file:get_cwd(),
+ file:set_cwd(Dir),
+ io:format("Changing to ~p~n", [Dir]),
+ case catch do_compile(Files, Opts) of
+ ok ->
+ file:set_cwd(Cwd);
+ Err ->
+ file:set_cwd(Cwd),
+ test_server:fail(Err)
+ end.
+
+do_compile([], _Opts) -> ok;
+do_compile([F | Fs], Opts) ->
+ io:format("Compiling ~p", [F]),
+ case compile:file(F, Opts) of
+ ok ->
+ io:format(" ok~n", []),
+ do_load(F, Opts),
+ do_compile(Fs, Opts);
+ {ok, _} ->
+ io:format(" ok~n", []),
+ do_load(F, Opts),
+ do_compile(Fs, Opts);
+ {ok, _, _} ->
+ io:format(" ok~n", []),
+ do_load(F, Opts),
+ do_compile(Fs, Opts);
+ Err ->
+ io:format(" error: ~p~n", [Err]),
+ Err
+ end.
+
+do_load(File, Opts) ->
+ case lists:member(load, Opts) of
+ true ->
+ io:format("Loading file ~p", [File]),
+ code:purge(File),
+ R = code:load_abs(File),
+ io:format("Loaded: ~p", [R]);
+ false ->
+ ok
+ end.
+
+
+to_list(X) when is_atom(X) -> atom_to_list(X);
+to_list(X) -> X.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/lib/ic/test/ic_register_SUITE_data/reg_m10.idl b/lib/ic/test/ic_register_SUITE_data/reg_m10.idl
new file mode 100644
index 0000000000..9c1f126b64
--- /dev/null
+++ b/lib/ic/test/ic_register_SUITE_data/reg_m10.idl
@@ -0,0 +1,37 @@
+
+
+// %CopyrightBegin%
+//
+// 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%
+//
+// IDL for testing register/unregister in the IFR when using included specs
+//
+#include "reg_m9.idl"
+
+typedef sequence<long> Sequence1;
+
+#include "reg_m8.idl"
+
+module m2 {
+
+ interface i2 : m1::i1
+ {
+ short op3( in long a, inout char b, out long c );
+ };
+
+
+};
+
diff --git a/lib/ic/test/ic_register_SUITE_data/reg_m11.idl b/lib/ic/test/ic_register_SUITE_data/reg_m11.idl
new file mode 100644
index 0000000000..607d695357
--- /dev/null
+++ b/lib/ic/test/ic_register_SUITE_data/reg_m11.idl
@@ -0,0 +1,32 @@
+
+
+// %CopyrightBegin%
+//
+// 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%
+//
+// IDL for testing register/unregister in the IFR when using included specs
+//
+
+module m3 {
+
+ interface i3
+ {
+ short op4( in long a, inout char b, out long c );
+ };
+
+
+};
+
diff --git a/lib/ic/test/ic_register_SUITE_data/reg_m12.idl b/lib/ic/test/ic_register_SUITE_data/reg_m12.idl
new file mode 100644
index 0000000000..3dd9267655
--- /dev/null
+++ b/lib/ic/test/ic_register_SUITE_data/reg_m12.idl
@@ -0,0 +1,40 @@
+
+
+// %CopyrightBegin%
+//
+// 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%
+//
+// IDL for testing register/unregister in the IFR when using included specs
+// Special case with multiple inheritence.
+//
+#include "reg_m10.idl"
+#include "reg_m11.idl"
+
+module m4 {
+
+ interface i4 : m2::i2
+ {
+ short op5( in long a, inout char b, out long c );
+ };
+
+ interface i5 : m3::i3
+ {
+ short op6( in long a, inout char b, out long c );
+ };
+
+
+};
+
diff --git a/lib/ic/test/ic_register_SUITE_data/reg_m8.idl b/lib/ic/test/ic_register_SUITE_data/reg_m8.idl
new file mode 100644
index 0000000000..dc7432c05d
--- /dev/null
+++ b/lib/ic/test/ic_register_SUITE_data/reg_m8.idl
@@ -0,0 +1,32 @@
+
+
+// %CopyrightBegin%
+//
+// 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%
+//
+// IDL for testing register/unregister in the IFR when using included specs
+//
+module m0 {
+
+ interface i0 {
+ void op1( in short c );
+ float op2( in char a);
+
+ };
+
+
+};
+
diff --git a/lib/ic/test/ic_register_SUITE_data/reg_m9.idl b/lib/ic/test/ic_register_SUITE_data/reg_m9.idl
new file mode 100644
index 0000000000..e937c41608
--- /dev/null
+++ b/lib/ic/test/ic_register_SUITE_data/reg_m9.idl
@@ -0,0 +1,32 @@
+
+
+// %CopyrightBegin%
+//
+// 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%
+//
+// IDL for testing register/unregister in the IFR when using included specs
+//
+module m1 {
+
+ interface i1 {
+ void op1( in short c );
+ float op2( in char a);
+
+ };
+
+
+};
+
diff --git a/lib/ic/test/java_client_erl_server_SUITE.erl b/lib/ic/test/java_client_erl_server_SUITE.erl
new file mode 100644
index 0000000000..ee77ef0c4e
--- /dev/null
+++ b/lib/ic/test/java_client_erl_server_SUITE.erl
@@ -0,0 +1,330 @@
+%%
+%% %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%
+%%
+%%
+%%%----------------------------------------------------------------------
+%%% Purpose : Test suite for the backends of the IDL compiler
+%%%----------------------------------------------------------------------
+
+-module(java_client_erl_server_SUITE).
+-include("test_server.hrl").
+
+
+-export([all/1,init_all/1,finish_all/1,init_per_testcase/2,fin_per_testcase/2]).
+-export([marshal_ll/1,marshal_ull/1,
+ marshal_l/1,marshal_ul/1,
+ marshal_s/1,marshal_us/1,
+ marshal_c/1,marshal_wc/1,
+ marshal_str/1,
+ marshal_any_3/1,marshal_any_2/1]).
+
+
+%% Top of cases
+
+all(doc) ->
+ "Test of IC with a Java-client and an Erlang generic server. "
+ "The communication is via Erlang distribution.";
+all(suite) -> {conf,init_all,cases(),finish_all}.
+
+cases() -> [marshal_ll,marshal_ull,
+ marshal_l,marshal_ul,
+ marshal_s,marshal_us,
+ marshal_c,marshal_wc,
+ marshal_str,
+ marshal_any_3,marshal_any_2].
+
+init_all(Config) when is_list(Config) ->
+ case case code:priv_dir(jinterface) of
+ {error,bad_name} ->
+ false;
+ P ->
+ filelib:is_dir(P)
+ end
+ of
+ true ->
+ case find_executable(["java"]) of
+ false ->
+ {skip,"Found no Java VM"};
+ Path ->
+ [{java,Path}|Config]
+ end;
+ false ->
+ {skip,"No jinterface application"}
+ end.
+
+
+find_executable([]) ->
+ false;
+find_executable([E|T]) ->
+ case os:find_executable(E) of
+ false -> find_executable(T);
+ Path -> Path
+ end.
+
+finish_all(Config) -> Config.
+
+
+
+%% Add/remove code path and watchdog before/after each test case.
+%%
+init_per_testcase(_Case, Config) ->
+ DataDir = ?config(data_dir, Config),
+ code:add_patha(DataDir),
+
+ %% Since other test suites use the module m_i et,al, we have
+ %% to make sure we are using the right modules.
+ code:purge(m_i),
+ code:purge(m_i_impl),
+ code:purge(oe_java_erl_test),
+ code:load_file(m_i),
+ code:load_file(m_i_impl),
+ code:load_file(oe_java_erl_test),
+
+ WatchDog = test_server:timetrap(test_server:seconds(20)),
+ [{watchdog, WatchDog}| Config].
+
+fin_per_testcase(_Case, Config) ->
+ DataDir = ?config(data_dir, Config),
+ code:del_path(DataDir),
+ WatchDog = ?config(watchdog, Config),
+ test_server:timetrap_cancel(WatchDog).
+
+
+
+%%--------------------------------------------------------------------
+%%
+%% Test cases
+
+marshal_ll(doc) ->
+ ["Testing marshalling of IDL long long"];
+marshal_ll(suite) -> [];
+marshal_ll(Config) when is_list(Config) ->
+ ?line DataDir = ?config(data_dir, Config),
+ ?line {ok,Server} = m_i:oe_create_link([], {local,marshal_ll}),
+ ?line ok = java(?config(java, Config), DataDir, "JavaClient",
+ ["JavaClient",node(),erlang:get_cookie(),marshal_ll]),
+ ?line ok = m_i:stop(Server),
+ ok.
+
+marshal_ull(doc) ->
+ ["Testing marshalling of IDL unsigned long long"];
+marshal_ull(suite) -> [];
+marshal_ull(Config) when is_list(Config) ->
+ ?line DataDir = ?config(data_dir, Config),
+ ?line {ok,Server} = m_i:oe_create_link([], {local,marshal_ull}),
+ ?line ok = java(?config(java, Config), DataDir, "JavaClient",
+ ["JavaClient",node(),erlang:get_cookie(),marshal_ull]),
+ ?line ok = m_i:stop(Server),
+ ok.
+
+marshal_l(doc) ->
+ ["Testing marshalling of IDL long"];
+marshal_l(suite) -> [];
+marshal_l(Config) when is_list(Config) ->
+ ?line DataDir = ?config(data_dir, Config),
+ ?line {ok,Server} = m_i:oe_create_link([], {local,marshal_l}),
+ ?line ok = java(?config(java, Config), DataDir, "JavaClient",
+ ["JavaClient",node(),erlang:get_cookie(),marshal_l]),
+ ?line ok = m_i:stop(Server),
+ ok.
+
+marshal_ul(doc) ->
+ ["Testing marshalling of IDL unsigned long"];
+marshal_ul(suite) -> [];
+marshal_ul(Config) when is_list(Config) ->
+ ?line DataDir = ?config(data_dir, Config),
+ ?line {ok,Server} = m_i:oe_create_link([], {local,marshal_ul}),
+ ?line ok = java(?config(java, Config), DataDir, "JavaClient",
+ ["JavaClient",node(),erlang:get_cookie(),marshal_ul]),
+ ?line ok = m_i:stop(Server),
+ ok.
+
+marshal_s(doc) ->
+ ["Testing marshalling of IDL short"];
+marshal_s(suite) -> [];
+marshal_s(Config) when is_list(Config) ->
+ ?line DataDir = ?config(data_dir, Config),
+ ?line {ok,Server} = m_i:oe_create_link([], {local,marshal_s}),
+ ?line ok = java(?config(java, Config), DataDir, "JavaClient",
+ ["JavaClient",node(),erlang:get_cookie(),marshal_s]),
+ ?line ok = m_i:stop(Server),
+ ok.
+
+marshal_us(doc) ->
+ ["Testing marshalling of IDL unsigned short"];
+marshal_us(suite) -> [];
+marshal_us(Config) when is_list(Config) ->
+ ?line DataDir = ?config(data_dir, Config),
+ ?line {ok,Server} = m_i:oe_create_link([], {local,marshal_us}),
+ ?line ok = java(?config(java, Config), DataDir, "JavaClient",
+ ["JavaClient",node(),erlang:get_cookie(),marshal_us]),
+ ?line ok = m_i:stop(Server),
+ ok.
+
+marshal_c(doc) ->
+ ["Testing marshalling of IDL char"];
+marshal_c(suite) -> [];
+marshal_c(Config) when is_list(Config) ->
+ ?line DataDir = ?config(data_dir, Config),
+ ?line {ok,Server} = m_i:oe_create_link([], {local,marshal_c}),
+ ?line ok = java(?config(java, Config), DataDir, "JavaClient",
+ ["JavaClient",node(),erlang:get_cookie(),marshal_c]),
+ ?line ok = m_i:stop(Server),
+ ok.
+
+marshal_wc(doc) ->
+ ["Testing marshalling of IDL char"];
+marshal_wc(suite) -> [];
+marshal_wc(Config) when is_list(Config) ->
+ ?line DataDir = ?config(data_dir, Config),
+ ?line {ok,Server} = m_i:oe_create_link([], {local,marshal_wc}),
+ ?line ok = java(?config(java, Config), DataDir, "JavaClient",
+ ["JavaClient",node(),erlang:get_cookie(),marshal_wc]),
+ ?line ok = m_i:stop(Server),
+ ok.
+
+marshal_str(doc) ->
+ ["Testing marshalling of IDL string"];
+marshal_str(suite) -> [];
+marshal_str(Config) when is_list(Config) ->
+ ?line DataDir = ?config(data_dir, Config),
+ ?line {ok,Server} = m_i:oe_create_link([], {local,marshal_str}),
+ ?line ok = java(?config(java, Config), DataDir,
+%%% "-DOtpConnection.trace=4 "
+ "JavaClient",
+ ["JavaClient",node(),erlang:get_cookie(),marshal_str]),
+ ?line ok = m_i:stop(Server),
+ ok.
+
+marshal_any_3(doc) ->
+ ["Testing marshalling of IDL any"];
+marshal_any_3(suite) -> [];
+marshal_any_3(Config) when is_list(Config) ->
+ ?line DataDir = ?config(data_dir, Config),
+ ?line {ok,Server} = m_i:oe_create_link([], {local,marshal_any_3}),
+ ?line ok = java(?config(java, Config), DataDir, "JavaClient",
+ ["JavaClient",node(),erlang:get_cookie(),marshal_any_3]),
+ ?line ok = m_i:stop(Server),
+ ok.
+
+marshal_any_2(doc) ->
+ ["Testing marshalling of IDL any"];
+marshal_any_2(suite) -> [];
+marshal_any_2(Config) when is_list(Config) ->
+ ?line DataDir = ?config(data_dir, Config),
+ ?line {ok,Server} = m_i:oe_create_link([], {local,marshal_any_2}),
+ ?line ok = java(?config(java, Config), DataDir, "JavaClient",
+ ["JavaClient",node(),erlang:get_cookie(),marshal_any_2]),
+ ?line ok = m_i:stop(Server),
+ ok.
+
+%%--------------------------------------------------------------------
+%%
+%% Utilities
+
+
+java(Java, Dir, ClassAndArgs) ->
+ cmd(Java++" -classpath "++classpath(Dir)++" "++ClassAndArgs).
+
+java(Java, Dir, Class, Args) ->
+ java(Java, Dir, Class++" "++to_string(Args)).
+
+to_string([H|T]) when is_integer(H) ->
+ integer_to_list(H)++" "++to_string(T);
+to_string([H|T]) when is_atom(H) ->
+ atom_to_list(H)++" "++to_string(T);
+to_string([H|T]) when is_list(H) ->
+ lists:flatten(H)++" "++to_string(T);
+to_string([]) -> [].
+
+% javac(Dir, File) ->
+% cmd("javac -d "++Dir++" -classpath "++classpath(Dir)++" "++
+% filename:join(Dir, File)).
+
+classpath(Dir) ->
+ PS =
+ case os:type() of
+ {win32, _} -> ";";
+ _ -> ":"
+ end,
+ Dir++PS++
+ filename:join([code:lib_dir(ic),"priv","ic.jar"])++PS++
+ filename:join([code:lib_dir(jinterface),"priv","OtpErlang.jar"])++PS++
+ case os:getenv("CLASSPATH") of
+ false -> "";
+ Classpath -> Classpath
+ end.
+
+
+cmd(Cmd) ->
+ PortOpts = [{line,80},eof,exit_status,stderr_to_stdout],
+ io:format("<cmd> ~s~n", [Cmd]),
+ case catch open_port({spawn,Cmd}, PortOpts) of
+ Port when is_port(Port) ->
+ Result = cmd_loop(Port, []),
+ io:format("<cmd=~w>~n", [Result]),
+ case Result of
+ 0 -> ok;
+ ExitCode when is_integer(ExitCode) -> {error,ExitCode};
+ Error -> Error
+ end;
+ {'EXIT',Reason} ->
+ {error,Reason}
+ end.
+
+cmd_loop(Port, Line) ->
+ receive
+ {Port,eof} ->
+ receive
+ {Port,{exit_status,ExitStatus}} ->
+ ExitStatus
+ after 1 ->
+ undefined
+ end;
+ {Port,{exit_status,ExitStatus}} ->
+ receive
+ {Port,eof} ->
+ ok after 1 -> ok end,
+ ExitStatus;
+ {Port,{data,{Tag,Data}}} ->
+ case Tag of
+ eol ->
+ io:put_chars([Line|cr_to_nl(Data)]),
+ io:nl(),
+ cmd_loop(Port, []);
+ noeol ->
+ cmd_loop(Port, [Line|cr_to_nl(Data)])
+ end;
+ {'EXIT',Port,Reason} ->
+ {error,Reason};
+ Other ->
+ io:format("WARNING: Unexpected at ~s:~p: ~p~n",
+ [?MODULE_STRING,?LINE,Other]),
+ cmd_loop(Port, Line)
+ end.
+
+%% Convert lonely CR to NL, and CRLF to NL
+%%
+cr_to_nl([$\r,$\n|T]) ->
+ [$\n|cr_to_nl(T)];
+cr_to_nl([$\r|T]) ->
+ [$\n|cr_to_nl(T)];
+cr_to_nl([C|T]) ->
+ [C|cr_to_nl(T)];
+cr_to_nl([]) ->
+ [].
diff --git a/lib/ic/test/java_client_erl_server_SUITE_data/JavaClient.java b/lib/ic/test/java_client_erl_server_SUITE_data/JavaClient.java
new file mode 100644
index 0000000000..1881279ac8
--- /dev/null
+++ b/lib/ic/test/java_client_erl_server_SUITE_data/JavaClient.java
@@ -0,0 +1,759 @@
+/*
+ * %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%
+ *
+ */
+public class JavaClient {
+
+ public static void main(String[] argv)
+ {
+ System.out.println("Hello World!");
+ if (argv.length < 4) {
+ System.out.println("Too few arguments!");
+ System.exit(1);
+ }
+ // for (int j = 0; j < argv.length; j++)
+ // System.out.println(argv[j]);
+ try {
+ if (argv[3].equals("marshal_ll")) {
+ System.out.println("marshal_ll");
+ marshal_ll(argv[0], argv[1], argv[2], argv[3]);
+ }
+ else if (argv[3].equals("marshal_ull")) {
+ marshal_ull(argv[0], argv[1], argv[2], argv[3]);
+ }
+ else if (argv[3].equals("marshal_l")) {
+ marshal_l(argv[0], argv[1], argv[2], argv[3]);
+ }
+ else if (argv[3].equals("marshal_ul")) {
+ marshal_ul(argv[0], argv[1], argv[2], argv[3]);
+ }
+ else if (argv[3].equals("marshal_s")) {
+ marshal_s(argv[0], argv[1], argv[2], argv[3]);
+ }
+ else if (argv[3].equals("marshal_us")) {
+ marshal_us(argv[0], argv[1], argv[2], argv[3]);
+ }
+ else if (argv[3].equals("marshal_c")) {
+ marshal_c(argv[0], argv[1], argv[2], argv[3]);
+ }
+ else if (argv[3].equals("marshal_wc")) {
+ marshal_wc(argv[0], argv[1], argv[2], argv[3]);
+ }
+ else if (argv[3].equals("marshal_str")) {
+ marshal_str(argv[0], argv[1], argv[2], argv[3]);
+ }
+ else if (argv[3].equals("marshal_any_3")) {
+ marshal_any_3(argv[0], argv[1], argv[2], argv[3]);
+ }
+ else if (argv[3].equals("marshal_any_2")) {
+ marshal_any_2(argv[0], argv[1], argv[2], argv[3]);
+ }
+ else {
+ System.out.println("Unknown test: "+argv[3]);
+ System.exit(2);
+ }
+ } catch (java.lang.Exception e) {
+ System.out.println("Exception!: "+e);
+ System.exit(3);
+ }
+ System.exit(0);
+ }
+
+
+
+ static void marshal_ll(String selfNode, String peerNode,
+ String cookie, String serverName)
+ throws java.lang.Exception
+ {
+ m._iStub i = new m._iStub(selfNode, peerNode, cookie, serverName);
+ // Just warming up..
+ System.out.println("Just warming up.."+i);
+ verify_ll(i, 3, 2, 1);
+ verify_ll(i, 5, 4, 3);
+ verify_ll(i, -128, 0, 1);
+ // The small integer border
+ verify_ll(i, 255, 0, 1);
+ verify_ll(i, 256, 0, 1);
+ // The integer border
+ verify_ll(i, (1L<<26)-1L, 0L, 1);
+ verify_ll(i, 1L<<26, 0L, 1);
+ verify_ll(i, -(1L<<26), 0L, 1);
+ verify_ll(i, (1L<<27)-1L, 0L, 1);
+ verify_ll(i, 1L<<27, 0L, 1);
+ verify_ll(i, -(1L<<27), 0L, 1);
+ // Bignum byte borders
+ verify_ll(i, (1L<<32)-1L, 0L, 1);
+ verify_ll(i, 1L<<32, 0L, 1);
+ verify_ll(i, -(1L<<32)+1L, 0L, 1);
+ verify_ll(i, -(1L<<32), 0L, 1);
+ verify_ll(i, (1L<<40)-1L, 0L, 1);
+ verify_ll(i, 1L<<40, 0L, 1);
+ verify_ll(i, -(1L<<40)+1L, 0L, 1);
+ verify_ll(i, -(1L<<40), 0L, 1);
+ verify_ll(i, (1L<<48)-1L, 0L, 1);
+ verify_ll(i, 1L<<48, 0L, 1);
+ verify_ll(i, -(1L<<48)+1L, 0L, 1);
+ verify_ll(i, -(1L<<48), 0L, 1);
+ // Java long border
+ verify_ll(i, java.lang.Long.MAX_VALUE, 0L, 1);
+ verify_ll(i, java.lang.Long.MIN_VALUE, 0L, 1);
+ verify_ll(i, -1L, 0L, 1);
+ // Impossible decodes
+ verify_ll_bad(i, java.lang.Long.MAX_VALUE, -1L, 1);
+ verify_ll_bad(i, java.lang.Long.MIN_VALUE, 1L, 1);
+ verify_ll_bad(i, java.lang.Long.MIN_VALUE, 0L, -1);
+ verify_ll_bad(i, java.lang.Long.MAX_VALUE, -1L, 2);
+ verify_ll_bad(i, java.lang.Long.MIN_VALUE, 0L, 2);
+ }
+
+ static void marshal_ull(String selfNode, String peerNode,
+ String cookie, String serverName)
+ throws java.lang.Exception
+ {
+ m._iStub i = new m._iStub(selfNode, peerNode, cookie, serverName);
+ // Just warming up..
+ verify_ull(i, 3, 2, 1);
+ verify_ull(i, 5, 4, 3);
+ // The small integer border
+ verify_ull(i, 255, 0, 1);
+ verify_ull(i, 256, 0, 1);
+ // The integer border
+ verify_ull(i, (1L<<26)-1L, 0L, 1);
+ verify_ull(i, 1L<<26, 0L, 1);
+ verify_ull(i, (1L<<27)-1L, 0L, 1);
+ verify_ull(i, 1L<<27, 0L, 1);
+ // Bignum byte borders
+ verify_ull(i, (1L<<32)-1L, 0L, 1);
+ verify_ull(i, 1L<<32, 0L, 1);
+ verify_ull(i, (1L<<40)-1L, 0L, 1);
+ verify_ull(i, 1L<<40, 0L, 1);
+ verify_ull(i, (1L<<48)-1L, 0L, 1);
+ verify_ull(i, 1L<<48, 0L, 1);
+ // Java long border
+ verify_ull(i, java.lang.Long.MAX_VALUE, 0L, 1);
+ verify_ull(i, java.lang.Long.MIN_VALUE, 0L, 1);
+ verify_ull(i, -1L, 0L, 1);
+ verify_ull(i, java.lang.Long.MAX_VALUE,
+ java.lang.Long.MIN_VALUE, 1);
+ // Impossible decodes
+ verify_ull_bad(i, -1L, -1L, 1);
+ verify_ull_bad(i, java.lang.Long.MAX_VALUE, -1L, 2);
+ }
+
+ static void marshal_l(String selfNode, String peerNode,
+ String cookie, String serverName)
+ throws java.lang.Exception
+ {
+ m._iStub i = new m._iStub(selfNode, peerNode, cookie, serverName);
+ // Just warming up..
+ verify_l(i, 3, 2, 1);
+ verify_l(i, 5, 4, 3);
+ verify_l(i, -128, 0, 1);
+ // The small integer border
+ verify_l(i, 255, 0, 1);
+ verify_l(i, 256, 0, 1);
+ // The integer border
+ verify_l(i, (1<<26)-1, 0, 1);
+ verify_l(i, 1<<26, 0, 1);
+ verify_l(i, -(1<<26), 0, 1);
+ verify_l(i, (1<<27)-1, 0, 1);
+ verify_l(i, 1<<27, 0, 1);
+ verify_l(i, -(1<<27), 0, 1);
+ // Java int border
+ verify_l(i, java.lang.Integer.MAX_VALUE, 0, 1);
+ verify_l(i, java.lang.Integer.MIN_VALUE, 0, 1);
+ // Impossible decodes
+ verify_l_bad(i, java.lang.Integer.MAX_VALUE, -1, 1);
+ verify_l_bad(i, java.lang.Integer.MIN_VALUE, 1, 1);
+ verify_l_bad(i, java.lang.Integer.MIN_VALUE, 0, -1);
+ }
+
+ static void marshal_ul(String selfNode, String peerNode,
+ String cookie, String serverName)
+ throws java.lang.Exception
+ {
+ m._iStub i = new m._iStub(selfNode, peerNode, cookie, serverName);
+ // Just warming up..
+ verify_ul(i, 3, 2, 1);
+ verify_ul(i, 5, 4, 3);
+ // The small integer border
+ verify_ul(i, 255, 0, 1);
+ verify_ul(i, 256, 0, 1);
+ // The integer border
+ verify_ul(i, (1<<26)-1, 0, 1);
+ verify_ul(i, 1<<26, 0, 1);
+ verify_ul(i, (1<<27)-1, 0, 1);
+ verify_ul(i, 1<<27, 0, 1);
+ // Java int border
+ verify_ul(i, java.lang.Integer.MAX_VALUE, 0, 1);
+ verify_ul(i, java.lang.Integer.MIN_VALUE, 0, 1);
+ verify_ul(i, -1, 0, 1);
+ verify_ul(i, java.lang.Integer.MAX_VALUE,
+ java.lang.Integer.MIN_VALUE, 1);
+ // Impossible decodes
+ verify_ul_bad(i, -1, -1, 1);
+ }
+
+ static void marshal_s(String selfNode, String peerNode,
+ String cookie, String serverName)
+ throws java.lang.Exception
+ {
+ m._iStub i = new m._iStub(selfNode, peerNode, cookie, serverName);
+ // Just warming up..
+ verify_s(i, 3, 2, 1);
+ verify_s(i, 5, 4, 3);
+ verify_s(i, -128, 0, 1);
+ // The small integer border
+ verify_s(i, 255, 0, 1);
+ verify_s(i, 256, 0, 1);
+ // Java short border
+ verify_s(i, java.lang.Short.MAX_VALUE, 0, 1);
+ verify_s(i, java.lang.Short.MIN_VALUE, 0, 1);
+ // Impossible decodes
+ verify_s_bad(i, java.lang.Short.MAX_VALUE, -1, 1);
+ verify_s_bad(i, java.lang.Short.MIN_VALUE, 1, 1);
+ verify_s_bad(i, java.lang.Short.MIN_VALUE, 0, -1);
+ }
+
+ static void marshal_us(String selfNode, String peerNode,
+ String cookie, String serverName)
+ throws java.lang.Exception
+ {
+ m._iStub i = new m._iStub(selfNode, peerNode, cookie, serverName);
+ // Just warming up..
+ verify_us(i, 3, 2, 1);
+ verify_us(i, 5, 4, 3);
+ // The small integer border
+ verify_us(i, 255, 0, 1);
+ verify_us(i, 256, 0, 1);
+ // Java short border
+ verify_us(i, java.lang.Short.MAX_VALUE, 0, 1);
+ verify_us(i, java.lang.Short.MIN_VALUE, 0, 1);
+ verify_us(i, -1, 0, 1);
+ verify_us(i, java.lang.Short.MAX_VALUE,
+ java.lang.Short.MIN_VALUE, 1);
+ // Impossible decodes
+ verify_us_bad(i, -1, -1, 1);
+ }
+
+ static void marshal_c(String selfNode, String peerNode,
+ String cookie, String serverName)
+ throws java.lang.Exception
+ {
+ m._iStub i = new m._iStub(selfNode, peerNode, cookie, serverName);
+ // Just warming up..
+ verify_c(i, '\3', '\2', 1);
+ verify_c(i, '\5', '\4', 3);
+ // The small integer border
+ verify_c(i, '\u00FF', '\0', 1);
+ verify_c(i, '\u0100', '\0', 1);
+ // Java char border
+ verify_c(i, java.lang.Character.MAX_VALUE, '\0', 1);
+ verify_c(i, java.lang.Character.MIN_VALUE, '\0', 1);
+ verify_c(i, java.lang.Character.MAX_VALUE,
+ java.lang.Character.MIN_VALUE, 1);
+ // Impossible decodes
+ verify_c_bad(i, '\u8000', '\0', 2);
+ }
+
+ static void marshal_wc(String selfNode, String peerNode,
+ String cookie, String serverName)
+ throws java.lang.Exception
+ {
+ m._iStub i = new m._iStub(selfNode, peerNode, cookie, serverName);
+ // Just warming up..
+ verify_wc(i, '\3', '\2', 1);
+ verify_wc(i, '\5', '\4', 3);
+ // The small integer border
+ verify_wc(i, '\u00FF', '\0', 1);
+ verify_wc(i, '\u0100', '\0', 1);
+ // Java char border
+ verify_wc(i, java.lang.Character.MAX_VALUE, '\0', 1);
+ verify_wc(i, java.lang.Character.MIN_VALUE, '\0', 1);
+ verify_wc(i, java.lang.Character.MAX_VALUE,
+ java.lang.Character.MIN_VALUE, 1);
+ // Impossible decodes
+ verify_c_bad(i, '\u8000', '\0', 2);
+ }
+
+ static void marshal_str(String selfNode, String peerNode,
+ String cookie, String serverName)
+ throws java.lang.Exception
+ {
+ m._iStub i = new m._iStub(selfNode, peerNode, cookie, serverName);
+ // Just warming up..
+ verify_str(i, 100, 100);
+ verify_str(i, 100, 1);
+ // Erlang string border
+ verify_str(i, 65535, 1);
+ verify_str(i, 2, 65535);
+ // Erlang string border out
+ verify_str(i, 65536, 1);
+ verify_str(i, 65536, 65536);
+ }
+
+ static void marshal_any_3(String selfNode, String peerNode,
+ String cookie, String serverName)
+ throws java.lang.Exception
+ {
+ m._iStub i = new m._iStub(selfNode, peerNode, cookie, serverName);
+ com.ericsson.otp.ic.Any x = new com.ericsson.otp.ic.Any();
+ com.ericsson.otp.ic.Any y = new com.ericsson.otp.ic.Any();
+ com.ericsson.otp.ic.Any z = new com.ericsson.otp.ic.Any();
+
+ x.insert_longlong(java.lang.Long.MAX_VALUE);
+ y.insert_longlong(1L);
+ z.insert_longlong(java.lang.Long.MAX_VALUE-1L);
+ System.out.println("verify_any_3 longlong max");
+ verify_any_3(i, x, y, 1, z);
+
+ x.insert_longlong(java.lang.Long.MIN_VALUE);
+ y.insert_longlong(-1L);
+ z.insert_longlong(java.lang.Long.MIN_VALUE+1L);
+ System.out.println("verify_any_3 longlong min");
+ verify_any_3(i, x, y, 1, z);
+
+ x.insert_ulonglong(-1L);
+ y.insert_longlong(1L);
+ z.insert_ulonglong(-2L);
+ System.out.println("verify_any_3 ulonglong max");
+ verify_any_3(i, x, y, 1, z);
+
+ x.insert_ulonglong(0L);
+ y.insert_longlong(-1L);
+ z.insert_ulonglong(1L);
+ System.out.println("verify_any_3 ulonglong min");
+ verify_any_3(i, x, y, 1, z);
+
+ x.insert_long(java.lang.Integer.MAX_VALUE);
+ y.insert_long(1);
+ z.insert_long(java.lang.Integer.MAX_VALUE-1);
+ System.out.println("verify_any_3 long max");
+ verify_any_3(i, x, y, 1, z);
+
+ x.insert_long(java.lang.Integer.MIN_VALUE);
+ y.insert_long(-1);
+ z.insert_long(java.lang.Integer.MIN_VALUE+1);
+ System.out.println("verify_any_3 long min");
+ verify_any_3(i, x, y, 1, z);
+
+ x.insert_ulong(-1);
+ y.insert_long(1);
+ z.insert_ulong(-2);
+ System.out.println("verify_any_3 ulong max");
+ verify_any_3(i, x, y, 1, z);
+
+ x.insert_ulong(0);
+ y.insert_long(-1);
+ z.insert_ulong(1);
+ System.out.println("verify_any_3 ulong min");
+ verify_any_3(i, x, y, 1, z);
+
+ x.insert_short(java.lang.Short.MAX_VALUE);
+ y.insert_short((short)1);
+ z.insert_short((short)(java.lang.Short.MAX_VALUE-1));
+ System.out.println("verify_any_3 short max");
+ verify_any_3(i, x, y, 1, z);
+
+ x.insert_short(java.lang.Short.MIN_VALUE);
+ y.insert_short((short)-1);
+ z.insert_short((short)(java.lang.Short.MIN_VALUE+1));
+ System.out.println("verify_any_3 short min");
+ verify_any_3(i, x, y, 1, z);
+
+ x.insert_ushort((short)-1);
+ y.insert_short((short)1);
+ z.insert_ushort((short)-2);
+ System.out.println("verify_any_3 ushort max");
+ verify_any_3(i, x, y, 1, z);
+
+ x.insert_ushort((short)0);
+ y.insert_short((short)-1);
+ z.insert_ushort((short)1);
+ System.out.println("verify_any_3 ushort min");
+ verify_any_3(i, x, y, 1, z);
+
+ x.insert_char('\377');
+ y.insert_char('\1');
+ z.insert_char('\376');
+ System.out.println("verify_any_3 char max");
+ verify_any_3(i, x, y, 1, z);
+
+ x.insert_wchar('\uFFFF');
+ y.insert_wchar('\u0001');
+ z.insert_wchar('\uFFFE');
+ System.out.println("verify_any_3 char max");
+ verify_any_3(i, x, y, 1, z);
+ }
+
+ static void marshal_any_2(String selfNode, String peerNode,
+ String cookie, String serverName)
+ throws java.lang.Exception
+ {
+ m._iStub i = new m._iStub(selfNode, peerNode, cookie, serverName);
+ m.s s = new m.s();
+ com.ericsson.otp.ic.Any a = new com.ericsson.otp.ic.Any();
+ //
+ s.ull_x = -1L;
+ s.ll_x = java.lang.Long.MAX_VALUE;
+ s.ll_y = 1L;
+ s.ull_z = -2L;
+ s.ll_z = java.lang.Long.MAX_VALUE-1L;
+ //
+ s.ul_x = -1;
+ s.l_x = java.lang.Integer.MAX_VALUE;
+ s.l_y = 1;
+ s.ul_z = -2;
+ s.l_z = java.lang.Integer.MAX_VALUE-1;
+ //
+ s.us_x = (short)-1;
+ s.s_x = java.lang.Short.MAX_VALUE;
+ s.s_y = (short)1;
+ s.us_z = (short)-2;
+ s.s_z = (short)(java.lang.Short.MAX_VALUE-1);
+ //
+ s.c_x = '\377';
+ s.c_y = '\1';
+ s.c_z = '\376';
+ s.wc_x = '\uFFFF';
+ s.wc_y = '\u0001';
+ s.wc_z = '\uFFFE';
+ m.sHelper.insert(a, s);
+ verify_any_2(i, a, 1);
+
+ s.ull_x = 0L;
+ s.ll_x = java.lang.Long.MIN_VALUE;
+ s.ll_y = -1L;
+ s.ull_z = 1L;
+ s.ll_z = java.lang.Long.MIN_VALUE+1L;
+ //
+ s.ul_x = 0;
+ s.l_x = java.lang.Integer.MIN_VALUE;
+ s.l_y = -1;
+ s.ul_z = 1;
+ s.l_z = java.lang.Integer.MIN_VALUE+1;
+ //
+ s.us_x = (short)0;
+ s.s_x = java.lang.Short.MIN_VALUE;
+ s.s_y = (short)-1;
+ s.us_z = (short)1;
+ s.s_z = (short)(java.lang.Short.MIN_VALUE+1);
+ //
+ s.c_x = '\0';
+ s.c_y = '\0';
+ s.c_z = '\0';
+ s.wc_x = '\u0000';
+ s.wc_y = '\u0000';
+ s.wc_z = '\u0000';
+ m.sHelper.insert(a, s);
+ verify_any_2(i, a, 1);
+ }
+
+
+ static void verify_ll(m._iStub i, long x, long y, int b)
+ throws java.lang.Exception
+ {
+ m.s a = new m.s();
+ System.out.println("verify_ll "+a);
+ a.ll_x = x;
+ a.ll_y = y;
+ long expected = (x - y)*(short)b;
+ long result = i.marshal_ll(a, (short)b);
+ if (result == expected) {
+ System.out.println("verify_ll("+x+", "+y+", "+b+") => "
+ +result);
+ } else {
+ System.out.println("verify_ll("+x+", "+y+", "+b+") => "
+ +result+" != "+expected);
+ System.exit(4);
+ }
+ }
+
+ static void verify_ull(m._iStub i, long x, long y, int b)
+ throws java.lang.Exception
+ {
+ m.s a = new m.s();
+ a.ull_x = x;
+ a.ll_y = y;
+ long expected = (x - y)*(short)b;
+ long result = i.marshal_ull(a, (short)b);
+ if (result == expected) {
+ System.out.println("verify_ull("+x+", "+y+", "+b+") => "
+ +result);
+ } else {
+ System.out.println("verify_ull("+x+", "+y+", "+b+") => "
+ +result+" != "+expected);
+ System.exit(4);
+ }
+ }
+
+ static void verify_l(m._iStub i, int x, int y, int b)
+ throws java.lang.Exception
+ {
+ m.s a = new m.s();
+ a.l_x = x;
+ a.l_y = y;
+ int expected = (x - y)*(short)b;
+ int result = i.marshal_l(a, (short)b);
+ if (result == expected) {
+ System.out.println("verify_l("+x+", "+y+", "+b+") => "
+ +result);
+ } else {
+ System.out.println("verify_l("+x+", "+y+", "+b+") => "
+ +result+" != "+expected);
+ System.exit(4);
+ }
+ }
+
+ static void verify_ul(m._iStub i, int x, int y, int b)
+ throws java.lang.Exception
+ {
+ m.s a = new m.s();
+ a.ul_x = x;
+ a.l_y = y;
+ int expected = (x - y)*(short)b;
+ int result = i.marshal_ul(a, (short)b);
+ if (result == expected) {
+ System.out.println("verify_ul("+x+", "+y+", "+b+") => "
+ +result);
+ } else {
+ System.out.println("verify_ul("+x+", "+y+", "+b+") => "
+ +result+" != "+expected);
+ System.exit(4);
+ }
+ }
+
+ static void verify_s(m._iStub i, int x, int y, int b)
+ throws java.lang.Exception
+ {
+ m.s a = new m.s();
+ a.s_x = (short)x;
+ a.s_y = (short)y;
+ short expected = (short)((x - y)*(short)b);
+ short result = i.marshal_s(a, (short)b);
+ if (result == expected) {
+ System.out.println("verify_s("+x+", "+y+", "+b+") => "
+ +result);
+ } else {
+ System.out.println("verify_s("+x+", "+y+", "+b+") => "
+ +result+" != "+expected);
+ System.exit(4);
+ }
+ }
+
+ static void verify_us(m._iStub i, int x, int y, int b)
+ throws java.lang.Exception
+ {
+ m.s a = new m.s();
+ a.us_x = (short)x;
+ a.s_y = (short)y;
+ short expected = (short)((x - y)*(short)b);
+ short result = i.marshal_us(a, (short)b);
+ if (result == expected) {
+ System.out.println("verify_us("+x+", "+y+", "+b+") => "
+ +result);
+ } else {
+ System.out.println("verify_us("+x+", "+y+", "+b+") => "
+ +result+" != "+expected);
+ System.exit(4);
+ }
+ }
+
+ static void verify_c(m._iStub i, char x, char y, int b)
+ throws java.lang.Exception
+ {
+ m.s a = new m.s();
+ a.c_x = x;
+ a.c_y = y;
+ char expected = (char)(((int)x - (int)y)*(short)b);
+ char result = i.marshal_c(a, (short)b);
+ if (result == expected) {
+ System.out.println("verify_c("+x+", "+y+", "+b+") => "
+ +result);
+ } else {
+ System.out.println("verify_c("+x+", "+y+", "+b+") => "
+ +result+" != "+expected);
+ System.exit(4);
+ }
+ }
+
+ static void verify_wc(m._iStub i, char x, char y, int b)
+ throws java.lang.Exception
+ {
+ m.s a = new m.s();
+ a.wc_x = x;
+ a.wc_y = y;
+ char expected = (char)(((int)x - (int)y)*(short)b);
+ char result = i.marshal_wc(a, (short)b);
+ if (result == expected) {
+ System.out.println("verify_wc("+x+", "+y+", "+b+") => "
+ +result);
+ } else {
+ System.out.println("verify_wc("+x+", "+y+", "+b+") => "
+ +result+" != "+expected);
+ System.exit(4);
+ }
+ }
+
+ static void verify_str(m._iStub i, int a_len, int b_len)
+ throws java.lang.Exception
+ {
+ String a = mk_str(a_len);
+ String b = mk_str(b_len);
+ String expected = a + b;
+ String result = i.strcat(a, b);
+ if (result.equals(expected)) {
+ System.out.println("verify_str(\""+a+"\", \""+b+"\") => \""
+ +result+"\"");
+ } else {
+ System.out.println("verify_str(\""+a+"\", \""+b+"\") => \""
+ +result+"\" != \""+expected.length()+"\"");
+ System.exit(4);
+ }
+ }
+
+ static String mk_str(int len)
+ throws StringIndexOutOfBoundsException
+ {
+ StringBuffer s = new StringBuffer();
+ // 17 characters is prime relative all bases of two - on purpose
+ do s.append("qwertyuiopasdfghj"); while (s.length() < len);
+ return s.substring(0, len);
+ }
+
+ static void verify_any_3(m._iStub i,
+ com.ericsson.otp.ic.Any x,
+ com.ericsson.otp.ic.Any y,
+ int b,
+ com.ericsson.otp.ic.Any expected)
+ throws java.lang.Exception
+ {
+ com.ericsson.otp.ic.Any result = i.marshal_any_3(x, y, (short)b);
+ if (! expected.equal(result)) {
+ System.exit(4);
+ }
+ }
+
+ static void verify_any_2(m._iStub i, com.ericsson.otp.ic.Any a, int b)
+ throws java.lang.Exception
+ {
+ com.ericsson.otp.ic.Any result = i.marshal_any_2(a, (short)b);
+ if (! a.equal(result)) {
+ System.exit(4);
+ }
+ }
+
+
+
+ static void verify_ll_bad(m._iStub i, long x, long y, int b)
+ throws java.lang.Exception
+ {
+ try {
+ verify_ll(i, x, y, b);
+ System.out.println("Expected exception missing!");
+ System.exit(5);
+ } catch (com.ericsson.otp.erlang.OtpErlangDecodeException e) {
+ System.out.println("Expected exception: "+e);
+ }
+ }
+
+ static void verify_ull_bad(m._iStub i, long x, long y, int b)
+ throws java.lang.Exception
+ {
+ try {
+ verify_ull(i, x, y, b);
+ System.out.println("Expected exception missing!");
+ System.exit(5);
+ } catch (com.ericsson.otp.erlang.OtpErlangDecodeException e) {
+ System.out.println("Expected exception: "+e);
+ }
+ }
+
+ static void verify_l_bad(m._iStub i, int x, int y, int b)
+ throws java.lang.Exception
+ {
+ try {
+ verify_l(i, x, y, b);
+ System.out.println("Expected exception missing!");
+ System.exit(5);
+ } catch (com.ericsson.otp.erlang.OtpErlangDecodeException e) {
+ System.out.println("Expected exception: "+e);
+ }
+ }
+
+ static void verify_ul_bad(m._iStub i, int x, int y, int b)
+ throws java.lang.Exception
+ {
+ try {
+ verify_ul(i, x, y, b);
+ System.out.println("Expected exception missing!");
+ System.exit(5);
+ } catch (com.ericsson.otp.erlang.OtpErlangDecodeException e) {
+ System.out.println("Expected exception: "+e);
+ }
+ }
+
+ static void verify_s_bad(m._iStub i, int x, int y, int b)
+ throws java.lang.Exception
+ {
+ try {
+ verify_s(i, x, y, b);
+ System.out.println("Expected exception missing!");
+ System.exit(5);
+ } catch (com.ericsson.otp.erlang.OtpErlangDecodeException e) {
+ System.out.println("Expected exception: "+e);
+ }
+ }
+
+ static void verify_us_bad(m._iStub i, int x, int y, int b)
+ throws java.lang.Exception
+ {
+ try {
+ verify_us(i, x, y, b);
+ System.out.println("Expected exception missing!");
+ System.exit(5);
+ } catch (com.ericsson.otp.erlang.OtpErlangDecodeException e) {
+ System.out.println("Expected exception: "+e);
+ }
+ }
+
+ static void verify_c_bad(m._iStub i, char x, char y, int b)
+ throws java.lang.Exception
+ {
+ try {
+ verify_c(i, x, y, b);
+ System.out.println("Expected exception missing!");
+ System.exit(5);
+ } catch (com.ericsson.otp.erlang.OtpErlangDecodeException e) {
+ System.out.println("Expected exception: "+e);
+ }
+ }
+
+ static void verify_wc_bad(m._iStub i, char x, char y, int b)
+ throws java.lang.Exception
+ {
+ try {
+ verify_wc(i, x, y, b);
+ System.out.println("Expected exception missing!");
+ System.exit(5);
+ } catch (com.ericsson.otp.erlang.OtpErlangDecodeException e) {
+ System.out.println("Expected exception: "+e);
+ }
+ }
+
+}
diff --git a/lib/ic/test/java_client_erl_server_SUITE_data/Makefile.src b/lib/ic/test/java_client_erl_server_SUITE_data/Makefile.src
new file mode 100644
index 0000000000..de1503401c
--- /dev/null
+++ b/lib/ic/test/java_client_erl_server_SUITE_data/Makefile.src
@@ -0,0 +1,88 @@
+#
+# %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%
+#
+#
+# Makefile.src for java_client_erl_server test
+# Note: This file *must* work for both Unix and Windows
+#
+# We use both `rm' (Unix) and `del' (Windows) for removing files, but
+# with a `-' in front so that the error in not finding `rm' (`del') on
+# Windows (Unix) is ignored.
+#
+# VxWorks? XXX
+#
+
+.SUFFIXES:
+.SUFFIXES: .erl .idl .@EMULATOR@ .java
+
+
+JAVAC = @JAVAC@
+ERLC = erlc
+
+# ic variables available from ts:
+#
+# ic_libpath: @ic_libpath@
+# ic_include_path: @ic_include_path@
+
+IC_INCLUDE_PATH = @ic_include_path@
+IC_CLASSPATH = @ic_classpath@
+
+JINTERFACE_CLASSPATH = @jinterface_classpath@
+
+CLASSPATH = .@PS@$(IC_CLASSPATH)@PS@$(JINTERFACE_CLASSPATH)@PS@
+
+GEN_JAVA_FILES = \
+ m@DS@_iImplBase.java \
+ m@DS@_iStub.java \
+
+GEN_HRL_FILES = \
+ m.hrl \
+ m_i.hrl \
+ oe_java_erl_test.hrl
+
+GEN_ERL_FILES = \
+ m_i.erl \
+ oe_java_erl_test.erl
+
+JAVA_FILES = $(GEN_JAVA_FILES) JavaClient.java
+CLASS_FILES = $(JAVA_FILES:.java=.class)
+ERL_FILES = $(GEN_ERL_FILES) m_i_impl.erl
+EBINS = $(ERL_FILES:.erl=.@EMULATOR@)
+
+
+all: $(CLASS_FILES) $(EBINS)
+
+clean:
+ -rm -f $(GEN_JAVA_FILES) $(CLASS_FILES) \
+ $(GEN_ERL_FILES) $(GEN_HRL_FILES) $(EBINS)
+ -del /F /Q $(GEN_JAVA_FILES) $(CLASS_FILES) \
+ $(GEN_ERL_FILES) $(GEN_HRL_FILES) $(EBINS)
+
+$(GEN_JAVA_FILES) : java_erl_test.idl
+ $(ERLC) -I $(IC_INCLUDE_PATH) "+{be,java}" java_erl_test.idl
+
+$(CLASS_FILES) : $(JAVA_FILES)
+ $(JAVAC) -classpath $(CLASSPATH) $(JAVA_FILES)
+
+$(GEN_ERL_FILES) $(GEN_HRL_FILES): java_erl_test.idl
+ $(ERLC) -I $(IC_INCLUDE_PATH) "+{be,erl_genserv}" java_erl_test.idl
+
+.erl.@EMULATOR@:
+ $(ERLC) -I $(IC_INCLUDE_PATH) $<
diff --git a/lib/ic/test/java_client_erl_server_SUITE_data/java_erl_test.idl b/lib/ic/test/java_client_erl_server_SUITE_data/java_erl_test.idl
new file mode 100644
index 0000000000..b72c972d3b
--- /dev/null
+++ b/lib/ic/test/java_client_erl_server_SUITE_data/java_erl_test.idl
@@ -0,0 +1,68 @@
+
+
+// %CopyrightBegin%
+//
+// Copyright Ericsson AB 2003-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 m {
+
+ struct s {
+ long long ll_x;
+ unsigned long long ull_x;
+ long long ll_y;
+ long long ll_z;
+ unsigned long long ull_z;
+
+ long l_x;
+ unsigned long ul_x;
+ long l_y;
+ long l_z;
+ unsigned long ul_z;
+
+ short s_x;
+ unsigned short us_x;
+ short s_y;
+ short s_z;
+ unsigned short us_z;
+
+ char c_x;
+ char c_y;
+ char c_z;
+
+ wchar wc_x;
+ wchar wc_y;
+ wchar wc_z;
+ };
+
+ interface i {
+ long long marshal_ll( in s a, in short b );
+ unsigned long long marshal_ull( in s a, in short b );
+
+ long marshal_l( in s a, in short b );
+ unsigned long marshal_ul( in s a, in short b );
+
+ short marshal_s( in s a, in short b );
+ unsigned short marshal_us( in s a, in short b );
+
+ char marshal_c( in s a, in short b );
+ wchar marshal_wc( in s a, in short b );
+
+ string strcat( in string a, in string b );
+
+ any marshal_any_3( in any x, in any y, in short b );
+ any marshal_any_2( in any a, in short b );
+ };
+
+};
diff --git a/lib/ic/test/java_client_erl_server_SUITE_data/m_i_impl.erl b/lib/ic/test/java_client_erl_server_SUITE_data/m_i_impl.erl
new file mode 100644
index 0000000000..77e532288f
--- /dev/null
+++ b/lib/ic/test/java_client_erl_server_SUITE_data/m_i_impl.erl
@@ -0,0 +1,169 @@
+%%--------------------------------------------------------------------
+%%
+%% %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(m_i_impl).
+
+-export([marshal_ll/3,marshal_ull/3,
+ marshal_l/3,marshal_ul/3,
+ marshal_s/3,marshal_us/3,
+ marshal_c/3,marshal_wc/3,
+ strcat/3,
+ marshal_any_3/4,marshal_any_2/3]).
+-export([init/1,terminate/2,code_change/3]).
+
+-include("m.hrl").
+
+-define(TK_M_S, {tk_struct,
+ "IDL:m/s:1.0",
+ "s",
+ [{"ll_x",tk_longlong},
+ {"ull_x",tk_ulonglong},
+ {"ll_y",tk_longlong},
+ {"ll_z",tk_longlong},
+ {"ull_z",tk_ulonglong},
+ {"l_x",tk_long},
+ {"ul_x",tk_ulong},
+ {"l_y",tk_long},
+ {"l_z",tk_long},
+ {"ul_z",tk_ulong},
+ {"s_x",tk_short},
+ {"us_x",tk_ushort},
+ {"s_y",tk_short},
+ {"s_z",tk_short},
+ {"us_z",tk_ushort},
+ {"c_x",tk_char},
+ {"c_y",tk_char},
+ {"c_z",tk_char},
+ {"wc_x",tk_wchar},
+ {"wc_y",tk_wchar},
+ {"wc_z",tk_wchar}|_]}).
+
+
+
+marshal_ll(State, #m_s{ll_x = X, ll_y = Y}=_A, B) when integer(B) ->
+ R = (X - Y)*B,
+ io:format("~p", [{?MODULE,?LINE,[X,Y,B,R]}]),
+ {reply, R, State}.
+
+marshal_ull(State, #m_s{ull_x = X, ll_y = Y}=_A, B) when integer(B) ->
+ R = (X - Y)*B,
+ io:format("~p", [{?MODULE,?LINE,[X,Y,B,R]}]),
+ {reply, R, State}.
+
+
+marshal_l(State, #m_s{l_x = X, l_y = Y}=_A, B) when integer(B) ->
+ R = (X - Y)*B,
+ io:format("~p", [{?MODULE,?LINE,[X,Y,B,R]}]),
+ {reply, R, State}.
+
+marshal_ul(State, #m_s{ul_x = X, l_y = Y}=_A, B) when integer(B) ->
+ R = (X - Y)*B,
+ io:format("~p", [{?MODULE,?LINE,[X,Y,B,R]}]),
+ {reply, R, State}.
+
+
+marshal_s(State, #m_s{s_x = X, s_y = Y}=_A, B) when integer(B) ->
+ R = (X - Y)*B,
+ io:format("~p", [{?MODULE,?LINE,[X,Y,B,R]}]),
+ {reply, R, State}.
+
+marshal_us(State, #m_s{us_x = X, s_y = Y}=_A, B) when integer(B) ->
+ R = (X - Y)*B,
+ io:format("~p", [{?MODULE,?LINE,[X,Y,B,R]}]),
+ {reply, R, State}.
+
+
+marshal_c(State, #m_s{c_x = X, c_y = Y}=_A, B) when integer(B) ->
+ R = (X - Y)*B,
+ io:format("~p", [{?MODULE,?LINE,[X,Y,B,R]}]),
+ {reply, R, State}.
+
+marshal_wc(State, #m_s{wc_x = X, wc_y = Y}=_A, B) when integer(B) ->
+ R = (X - Y)*B,
+ io:format("~p", [{?MODULE,?LINE,[X,Y,B,R]}]),
+ {reply, R, State}.
+
+strcat(State, A, B) when list(A), list(B) ->
+ R = A++B,
+ io:format("~p", [{?MODULE,?LINE,[length(A),length(B),A,B,R]}]),
+ {reply, R, State};
+strcat(State, A, B) ->
+ io:format("~p", [{?MODULE,?LINE,[A,B]}]),
+ {reply, [], State}.
+
+marshal_any_3(State, {any,TkX,_}=X, {any,_,_}=Y, B) when integer(B) ->
+ R = any(mul(sub(any(X), any(Y)), B), TkX),
+ io:format("~p", [{?MODULE,?LINE,[X,Y,B,R]}]),
+ {reply, R, State}.
+
+marshal_any_2(State,
+ {any,TkA,#m_s{ll_x=LL_X, ull_x=ULL_X, ll_y=LL_Y,
+ l_x=L_X, ul_x=UL_X, l_y=L_Y,
+ s_x=S_X, us_x=US_X, s_y=S_Y,
+ c_x=C_X, c_y=C_Y,
+ wc_x=WC_X, wc_y=WC_Y} = A},
+ B) when integer(B) ->
+ {check_type_code,?TK_M_S} = {check_type_code,TkA},
+ ULL_Z = (ULL_X - LL_Y) * B,
+ LL_Z = (LL_X - LL_Y) * B,
+ UL_Z = (UL_X - L_Y) * B,
+ L_Z = (L_X - L_Y) * B,
+ US_Z = (US_X - S_Y) * B,
+ S_Z = (S_X - S_Y) * B,
+ C_Z = (C_X - C_Y) * B,
+ WC_Z = (WC_X - WC_Y) * B,
+ R = A#m_s{ll_z=LL_Z, ull_z=ULL_Z,
+ l_z=L_Z, ul_z=UL_Z,
+ s_z=S_Z, us_z=US_Z,
+ c_z=C_Z, wc_z=WC_Z},
+ io:format("~p", [{?MODULE,?LINE,[A,B,R]}]),
+ {reply, {any,TkA,R}, State}.
+
+
+
+init(_Env) ->
+ {ok, []}.
+
+terminate(_Reason, _State) ->
+ ok.
+
+code_change(_OldVsn, State, _Extra) ->
+ {ok, State}.
+
+
+any({any,tk_longlong,X}) -> X;
+any({any,tk_long,X}) -> X;
+any({any,tk_short,X}) -> X;
+any({any,tk_ulonglong,X}) -> X;
+any({any,tk_ulong,X}) -> X;
+any({any,tk_ushort,X}) -> X;
+any({any,tk_char,X}) -> X;
+any({any,tk_wchar,X}) -> X.
+
+any(X, Tk) when integer(X) -> {any,Tk,X}.
+
+sub(X, Y) when integer(X), integer(Y) ->
+ X - Y.
+
+mul(X, Y) when integer(X), integer(Y) ->
+ X * Y.
+
+napp(0, L) -> L;
+napp(N, L) when integer(N), N >= 1 -> napp(N-1, L)++L.
diff --git a/lib/ic/vsn.mk b/lib/ic/vsn.mk
index 6f973e3db4..6d6c7fa625 100644
--- a/lib/ic/vsn.mk
+++ b/lib/ic/vsn.mk
@@ -1,13 +1 @@
-IC_VSN = 4.2.23
-
-TICKETS = OTP-8201
-
-TICKETS_4.2.22 = OTP-8088
-
-TICKETS_4.2.21 = OTP-7982
-
-TICKETS_4.2.20 = OTP-7837
-
-TICKETS_4.2.19 = OTP-7595
-
-TICKETS_4.2.18 = OTP-7313
+IC_VSN = 4.2.26
diff --git a/lib/inets/Makefile b/lib/inets/Makefile
index 9a54bfb8e2..ec05efa461 100644
--- a/lib/inets/Makefile
+++ b/lib/inets/Makefile
@@ -1,19 +1,19 @@
#
# %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
# 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%
#
#
@@ -24,7 +24,7 @@ include $(ERL_TOP)/make/$(TARGET)/otp.mk
# Macros
# ----------------------------------------------------
-SUB_DIRECTORIES = src examples priv doc/src
+SUB_DIRECTORIES = src examples priv doc/src
include vsn.mk
VSN = $(INETS_VSN)
@@ -36,3 +36,11 @@ SPECIAL_TARGETS =
# ----------------------------------------------------
include $(ERL_TOP)/make/otp_subdir.mk
+info:
+ @echo "OS: $(OS)"
+ @echo "DOCB: $(DOCB)"
+ @echo ""
+ @echo "INETS_VSN: $(INETS_VSN)"
+ @echo "APP_VSN: $(APP_VSN)"
+ @echo ""
+
diff --git a/lib/inets/doc/src/Makefile b/lib/inets/doc/src/Makefile
index 5b5a818db8..e4cb0c4e48 100644
--- a/lib/inets/doc/src/Makefile
+++ b/lib/inets/doc/src/Makefile
@@ -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%
#
#
@@ -25,7 +25,7 @@ include $(ERL_TOP)/make/$(TARGET)/otp.mk
# ----------------------------------------------------
include ../../vsn.mk
VSN=$(INETS_VSN)
-APPLICATION=inets
+
# ----------------------------------------------------
# Include dependency
@@ -35,11 +35,13 @@ ifndef DOCSUPPORT
include make.dep
endif
+
# ----------------------------------------------------
# Release directory specification
# ----------------------------------------------------
RELSYSDIR = $(RELEASE_PATH)/lib/$(APPLICATION)-$(VSN)
+
# ----------------------------------------------------
# Target Specs
# ----------------------------------------------------
@@ -56,7 +58,7 @@ XML_REF3_FILES = \
inets.xml \
ftp.xml \
tftp.xml \
- http.xml\
+ httpc.xml\
httpd.xml \
httpd_conf.xml \
httpd_socket.xml \
@@ -67,41 +69,29 @@ XML_REF3_FILES = \
mod_security.xml
XML_PART_FILES = \
- part.xml \
- part_notes.xml \
- part_notes_history.xml
-XML_HTML_FILES = \
- notes_history.xml
+ part.xml
BOOK_FILES = book.xml
-XML_FILES = $(BOOK_FILES) \
- $(XML_CHAPTER_FILES) \
- $(XML_PART_FILES) \
- $(XML_REF6_FILES) \
- $(XML_REF3_FILES) \
- $(XML_APPLICATION_FILES)
+XML_FILES = \
+ $(BOOK_FILES) \
+ $(XML_CHAPTER_FILES) \
+ $(XML_PART_FILES) \
+ $(XML_REF6_FILES) \
+ $(XML_REF3_FILES) \
+ $(XML_APPLICATION_FILES)
-GIF_FILES = \
- inets.gif \
- notes.gif \
- ref_man.gif \
- book.gif \
- warning.gif \
- note.gif
+# GIF_FILES = inets.gif
# ----------------------------------------------------
HTML_FILES = \
$(XML_APPLICATION_FILES:%.xml=$(HTMLDIR)/%.html) \
- $(XML_HTML_FILES:%.xml=$(HTMLDIR)/%.html) \
$(XML_PART_FILES:%.xml=$(HTMLDIR)/%.html)
INFO_FILE = ../../info
EXTRA_FILES = summary.html.src \
- $(DEFAULT_GIF_FILES) \
- $(DEFAULT_HTML_FILES) \
$(XML_REF3_FILES:%.xml=$(HTMLDIR)/%.html) \
$(XML_REF6_FILES:%.xml=$(HTMLDIR)/%.html) \
$(XML_CHAPTER_FILES:%.xml=$(HTMLDIR)/%.html)
@@ -208,6 +198,7 @@ clean_html:
clean_man:
rm -f $(MAN3_FILES)
+
# ----------------------------------------------------
# Release Target
# ----------------------------------------------------
@@ -216,11 +207,11 @@ include $(ERL_TOP)/make/otp_release_targets.mk
ifdef DOCSUPPORT
release_docs_spec: docs
+ @echo "release_docs_spec(docs) when DOCSUPPORT=$DOCSUPPORT"
$(INSTALL_DIR) $(RELSYSDIR)/doc/pdf
$(INSTALL_DATA) $(TOP_PDF_FILE) $(RELSYSDIR)/doc/pdf
$(INSTALL_DIR) $(RELSYSDIR)/doc/html
- $(INSTALL_DATA) $(HTMLDIR)/* \
- $(RELSYSDIR)/doc/html
+ $(INSTALL_DATA) $(HTMLDIR)/* $(RELSYSDIR)/doc/html
$(INSTALL_DATA) $(INFO_FILE) $(RELSYSDIR)
$(INSTALL_DIR) $(RELEASE_PATH)/man/man3
$(INSTALL_DATA) $(MAN3DIR)/* $(RELEASE_PATH)/man/man3
@@ -228,15 +219,18 @@ else
ifeq ($(DOCTYPE),pdf)
release_docs_spec: pdf
+ @echo "release_docs_spec(pdf)"
$(INSTALL_DIR) $(RELEASE_PATH)/pdf
$(INSTALL_DATA) $(TOP_PDF_FILE) $(RELEASE_PATH)/pdf
else
ifeq ($(DOCTYPE),ps)
release_docs_spec: ps
+ @echo "release_docs_spec(ps)"
$(INSTALL_DIR) $(RELEASE_PATH)/ps
$(INSTALL_DATA) $(TOP_PS_FILE) $(RELEASE_PATH)/ps
else
release_docs_spec: docs
+ @echo "release_docs_spec(docs)"
$(INSTALL_DIR) $(RELSYSDIR)/doc/html
$(INSTALL_DATA) $(GIF_FILES) $(EXTRA_FILES) $(HTML_FILES) \
$(RELSYSDIR)/doc/html
@@ -260,10 +254,6 @@ info:
@echo ""
@echo "TOP_HTML_FILES:\n$(TOP_HTML_FILES)"
@echo ""
- @echo "DEFAULT_GIF_FILES:\n$(DEFAULT_GIF_FILES)"
- @echo ""
- @echo "DEFAULT_HTML_FILES:\n$(DEFAULT_HTML_FILES)"
- @echo ""
@echo "XML_REF3_FILES:\n$(XML_REF3_FILES)"
@echo ""
@echo "XML_REF6_FILES:\n$(XML_REF6_FILES)"
diff --git a/lib/inets/doc/src/ftp.xml b/lib/inets/doc/src/ftp.xml
index 9ecca3dde1..25dfe716fc 100644
--- a/lib/inets/doc/src/ftp.xml
+++ b/lib/inets/doc/src/ftp.xml
@@ -4,7 +4,7 @@
<erlref>
<header>
<copyright>
- <year>1997</year><year>2009</year>
+ <year>1997</year><year>2010</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
@@ -13,12 +13,12 @@
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>ftp</title>
@@ -534,12 +534,14 @@
<fsummary>Start an standalone ftp client.</fsummary>
<type>
<v>Host = string() | ip_address()</v>
- <v>Opts = start_options() | open_options()</v>
- <v>start_options() = [start_option()]</v>
+ <v>Opts = options()</v>
+ <v>options() = [option()]</v>
+ <v>option() = start_option() | open_option()</v>
+ <!-- <v>start_options() = [start_option()]</v> -->
<v>start_option() = {verbose, verbose()} | {debug, debug()}</v>
<v>verbose() = boolean() (defaults to false)</v>
<v>debug() = disable | debug | trace (defaults to disable)</v>
- <v>open_options() = [open_option()]</v>
+ <!-- <v>open_options() = [open_option()]</v> -->
<v>open_option() = {ipfamily, ipfamily()} | {port, port()} | {mode, mode()} | {timeout, timeout()} | {progress, progress()}</v>
<v>ipfamily() = inet | inet6 | inet6fb4 (defaults to inet)</v>
<v>port() = integer() > 0 (defaults to 21)</v>
@@ -845,7 +847,7 @@
<type>
<v>Pid = pid()</v>
<v>Command = string()</v>
- <v>FTPLine = string() - Note the telnet end of line characters, from the ftp protocol definition, CRLF e.g. "\\r\ " has been removed.</v>
+ <v>FTPLine = string() - Note the telnet end of line characters, from the ftp protocol definition, CRLF e.g. "\\r\\n" has been removed.</v>
</type>
<desc>
<p>Sends an arbitrary FTP command and returns verbatimly a list
diff --git a/lib/inets/doc/src/http.xml b/lib/inets/doc/src/http.xml
deleted file mode 100644
index f6f8338113..0000000000
--- a/lib/inets/doc/src/http.xml
+++ /dev/null
@@ -1,491 +0,0 @@
-<?xml version="1.0" encoding="latin1" ?>
-<!DOCTYPE erlref SYSTEM "erlref.dtd">
-
-<erlref>
- <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>http</title>
- <prepared>Ingela Anderton Andin</prepared>
- <responsible></responsible>
- <docno></docno>
- <date></date>
- <rev></rev>
- </header>
- <module>http</module>
- <modulesummary>An HTTP/1.1 client </modulesummary>
- <description>
- <p>This module provides the API to a HTTP/1.1 client according to
- RFC 2616, caching is currently not supported.</p>
- <note>
- <p>When starting the Inets application a manager process for the
- default profile will be started. The functions in this API
- that does not explicitly use a profile will accesses the
- default profile. A profile keeps track of proxy options,
- cookies and other options that can be applied to more than one
- request. </p>
-
- <p>If the scheme
- https is used the ssl application needs to be started.</p>
-
- <p>Also note that pipelining will only be used if the pipeline
- timeout is set, otherwise persistent connections without
- pipelining will be used e.i. the client always waits for
- the previous response before sending the next request.</p>
- </note>
- <p>There are some usage examples in the <seealso
- marker="http_client">Inets User's Guide.</seealso></p>
- </description>
-
- <section>
- <title>COMMON DATA TYPES </title>
- <p>Type definitions that are used more than once in
- this module:</p>
- <code type="none"><![CDATA[
-boolean() = true | false
-string() = list of ASCII characters
-request_id() = ref()
-profile() = atom()
-path() = string() representing a file path or directory path
-ip_address() = See inet(3)
- ]]></code>
-
- </section>
-
- <section>
- <title>HTTP DATA TYPES </title>
- <p>Type definitions that are related to HTTP:</p>
- <p>For more information about HTTP see rfc 2616</p>
-
- <code type="none"><![CDATA[
-method() = head | get | put | post | trace | options | delete
-request() = {url(), headers()} |
- {url(), headers(), content_type(), body()}
-url() = string() - Syntax according to the URI definition in rfc 2396, ex: "http://www.erlang.org"
-status_line() = {http_version(), status_code(), reason_phrase()}
-http_version() = string() ex: "HTTP/1.1"
-status_code() = integer()
-reason_phrase() = string()
-content_type() = string()
-headers() = [header()]
-header() = {field(), value()}
-field() = string()
-value() = string()
-body() = string() | binary()
-filename() = string()
- ]]></code>
-
- </section>
-
- <section>
- <title>SSL DATA TYPES </title>
- <p>Some type definitions relevant when using https,
- for details <seealso marker="ssl:ssl">ssl(3)</seealso>: </p>
- <code type="none"><![CDATA[
-ssl_options() = {verify, code()} |
- {depth, depth()} |
- {certfile, path()} |
- {keyfile, path()} |
- {password, string()} |
- {cacertfile, path()} |
- {ciphers, string()}
- ]]></code>
- </section>
-
- <section>
- <title>HTTP CLIENT SERVICE START/STOP </title>
-
- <p>A HTTP client can be configured to start when starting the inets
- application or started dynamically in runtime by calling the
- inets application API <c>inets:start(httpc, ServiceConfig)</c>, or
- <c>inets:start(httpc, ServiceConfig, How)</c>
- see <seealso marker="inets">inets(3)</seealso> Below follows a
- description of the available configuration options.</p>
- <taglist>
- <tag>{profile, profile()}</tag>
- <item>Name of the profile, see
- common data types below, this option is mandatory.</item>
- <tag>{data_dir, path()}</tag>
- <item>Directory where the profile
- may save persistent data, if omitted all cookies will be treated
- as session cookies.</item>
- </taglist>
-
- <p>The client can be stopped using inets:stop(httpc, Pid) or
- inets:stop(httpc, Profile).</p>
-
- <marker id="cancel_request"></marker>
- </section>
-
- <funcs>
- <func>
- <name>cancel_request(RequestId) -> </name>
- <name>cancel_request(RequestId, Profile) -> ok</name>
- <fsummary>Cancels an asynchronous HTTP-request.</fsummary>
- <type>
- <v>RequestId = request_id() - A unique identifier as returned
- by request/4</v>
- <v>Profile = profile()</v>
- </type>
- <desc>
- <p>Cancels an asynchronous HTTP-request. </p>
-
- <marker id="request1"></marker>
- </desc>
- </func>
-
- <func>
- <name>request(Url) -> </name>
- <name>request(Url, Profile) -> {ok, Result} | {error, Reason}</name>
- <fsummary>Sends a get HTTP-request</fsummary>
- <type>
- <v>Url = url() </v> <v>Result = {status_line(), headers(),
- body()} | {status_code(), body()} | request_id() </v>
- <v>Profile = profile()</v>
- <v>Reason = term() </v>
- </type>
- <desc>
- <p>Equivalent to http:request(get, {Url, []}, [], []).</p>
-
- <marker id="request2"></marker>
- </desc>
- </func>
-
- <func>
- <name>request(Method, Request, HTTPOptions, Options) -> </name>
- <name>request(Method, Request, HTTPOptions, Options, Profile) -> {ok, Result} | {ok, saved_to_file} | {error, Reason}</name>
-
- <fsummary>Sends a HTTP-request</fsummary>
- <type>
- <v>Method = method() </v>
- <v>Request = request()</v>
- <v>HTTPOptions = http_options()</v>
- <v>http_options() = [http_option()]</v>
- <v>http_option() = {timeout, timeout()} |
- {connect_timeout, timeout()} |
- {ssl, ssl_options()} |
- {autoredirect, boolean()} |
- {proxy_auth, {userstring(), passwordstring()}} |
- {version, http_version()} |
- {relaxed, boolean()}</v>
- <v>timeout() = integer() >= 0 | infinity</v>
- <v>Options = options()</v>
- <v>options() = [option()]</v>
- <v>option() = {sync, boolean()} |
- {stream, stream_to()} |
- {body_format, body_format()} |
- {full_result, boolean()} |
- {headers_as_is, boolean()}</v>
- <v>stream_to() = self | {self, once} | filename() </v>
- <v>body_format() = string() | binary() </v>
- <v>Result = {status_line(), headers(), body()} |
- {status_code(), body()} | request_id() </v>
- <v>Profile = profile() </v>
- <v>Reason = term() </v>
- </type>
-
- <desc>
- <p>Sends a HTTP-request. The function can be both synchronous
- and asynchronous. In the later case the function will return
- {ok, RequestId} and later on message(s) will be sent to the
- calling process on the format: </p>
-<pre>
- {http, {RequestId, Result}}
- {http, {RequestId, {error, Reason}}}
- {http, {RequestId, stream_start, Headers}
- {http, {RequestId, stream, BinBodyPart}
- {http, {RequestId, stream_end, Headers}
- {http, {RequestId, saved_to_file}}.
-</pre>
-
- <p>Http option (<c>http_option()</c>) details: </p>
- <taglist>
- <tag><c><![CDATA[timeout]]></c></tag>
- <item>
- <p>Timeout time for the request. </p>
- <p>Defaults to <c>infinity</c>. </p>
- </item>
-
- <tag><c><![CDATA[connect_timeout]]></c></tag>
- <item>
- <p>Connection timeout time, used during the initial request,
- when the client is connecting to the server. </p>
- <p>Defaults to the value of the <c>timeout</c> option. </p>
- </item>
-
- <tag><c><![CDATA[ssl]]></c></tag>
- <item>
- <p>If using SSL, these SSL-specific options are used. </p>
- <p>Defaults to <c>[]</c>. </p>
- </item>
-
- <tag><c><![CDATA[autoredirect]]></c></tag>
- <item>
- <p>Should the client automatically retreive the information
- from the new URI and return that as the result instead
- of a 30X-result code. </p>
- <p>Note that for some 30X-result codes automatic redirect
- is not allowed in these cases the 30X-result will always
- be returned. </p>
- <p>Defaults to <c>true</c>. </p>
- </item>
-
- <tag><c><![CDATA[proxy_auth]]></c></tag>
- <item>
- <p>A proxy-authorization header using the provided user name and
- password will be added to the request. </p>
- </item>
-
- <tag><c><![CDATA[version]]></c></tag>
- <item>
- <p>Can be used to make the client act as an <c>HTTP/1.0</c> or
- <c>HTTP/0.9</c> client. By default this is an <c>HTTP/1.1</c>
- client. When using <c>HTTP/1.0</c> persistent connections will
- not be used. </p>
- <p>Defaults to the trsing <c>"HTTP/1.1"</c>. </p>
- </item>
-
- <tag><c><![CDATA[relaxed]]></c></tag>
- <item>
- <p>If set to true workarounds for known server deviations from
- the HTTP-standard are enabled. </p>
- <p>Defaults to <c>false</c>. </p>
- </item>
-
- </taglist>
-
- <p>Option (<c>option()</c>) details: </p>
- <taglist>
- <tag><c><![CDATA[sync]]></c></tag>
- <item>
- <p>Shall the request be synchronous or asynchronous. </p>
- <p>Defaults to <c>true</c>. </p>
- </item>
-
- <tag><c><![CDATA[stream]]></c></tag>
- <item>
- <p>Streams the body of a 200 or 206 response to the calling
- process or to a file. When streaming to the calling process
- using the option <c>self</c> the the following stream messages
- will be sent to that process: {http, {RequestId,
- stream_start, Headers}, {http, {RequestId, stream,
- BinBodyPart}, {http, {RequestId, stream_end, Headers}. When
- streaming to to the calling processes using the option
- <c>{self once}</c> the first message will have an additional
- element e.i. {http, {RequestId, stream_start, Headers, Pid},
- this is the process id that should be used as an argument to
- http:stream_next/1 to trigger the next message to be sent to
- the calling process. </p>
- <p>Note that it is possible that chunked encoding will add
- headers so that there are more headers in the stream_end
- message than in the stream_start.
- When streaming to a file and the request is asynchronous the
- message {http, {RequestId, saved_to_file}} will be sent. </p>
- <p>Defaults to <c>none</c>. </p>
- </item>
-
- <tag><c><![CDATA[body_format]]></c></tag>
- <item>
- <p>Defines if the body shall be delivered as a string or as a
- binary. This option is only valid for the synchronous
- request. </p>
- <p>Defaults to <c>string</c>. </p>
- </item>
-
- <tag><c><![CDATA[full_result]]></c></tag>
- <item>
- <p>Should a "full result" be returned to the caller (that is,
- the body, the headers and the entire status-line) or not
- (the body and the status code). </p>
- <p>Defaults to <c>true</c>. </p>
- </item>
-
- <tag><c><![CDATA[header_as_is]]></c></tag>
- <item>
- <p>Shall the headers provided by the user be made
- lower case or be regarded as case sensitive. </p>
- <p>Note that the http standard requires them to be
- case insenstive. This feature should only be used if there is
- no other way to communicate with the server or for testing
- purpose. Also note that when this option is used no headers
- will be automatically added, all necessary headers has to be
- provided by the user. </p>
- <p>Defaults to <c>false</c>. </p>
- </item>
-
- </taglist>
-
- <marker id="set_options"></marker>
- </desc>
- </func>
-
- <func>
- <name>set_options(Options) -> </name>
- <name>set_options(Options, Profile) -> ok | {error, Reason}</name>
- <fsummary>Sets options to be used for subsequent requests.</fsummary>
- <type>
- <v>Options = [Option]</v>
- <v>Option = {proxy, {Proxy, NoProxy}} | {max_sessions, MaxSessions} |
- {max_keep_alive_length, MaxKeepAlive} | {keep_alive_timeout, KeepAliveTimeout} |
- {max_pipeline_length, MaxPipeline} | {pipeline_timeout, PipelineTimeout} |
- {cookies | CookieMode} |
- {ipfamily, IpFamily} | {ip, IpAddress} | {port, Port} |
- {verbose, VerboseMode} </v>
- <v>Proxy = {Hostname, Port}</v>
- <v>Hostname = string() </v>
- <d>ex: "localhost" or "foo.bar.se"</d>
- <v>Port = integer()</v>
- <d>ex: 8080 </d>
- <v>NoProxy = [NoProxyDesc]</v>
- <v>NoProxyDesc = DomainDesc | HostName | IPDesc</v>
- <v>DomainDesc = "*.Domain"</v>
- <d>ex: "*.ericsson.se"</d>
- <v>IpDesc = string()</v>
- <d>ex: "134.138" or "[FEDC:BA98" (all IP-addresses starting with 134.138 or FEDC:BA98), "66.35.250.150" or "[2010:836B:4179::836B:4179]" (a complete IP-address).</d>
- <v>MaxSessions = integer() </v>
- <d>Default is <em>2</em>.
- Maximum number of persistent connections to a host.</d>
- <v>MaxKeepAlive = integer() </v>
- <d>Default is <em>5</em>.
- Maximum number of outstanding requests on the same connection to
- a host.</d>
- <v>KeepAliveTimeout = integer() </v>
- <d>Default is <em>120000</em> (= 2 min).
- If a persistent connection is idle longer than the
- keep_alive_timeout the client will close the connection.
- The server may also have a such a time out but you should
- not count on it!</d>
- <v>MaxPipeline = integer() </v>
- <d>Default is <em>2</em>.
- Maximum number of outstanding requests on a pipelined connection to a host.</d>
- <v>PipelineTimeout = integer() </v>
- <d>Default is <em>0</em>,
- which will result in pipelining not being used.
- If a persistent connection is idle longer than the
- pipeline_timeout the client will close the connection. </d>
- <v>CookieMode = enabled | disabled | verify </v>
- <d>Default is <em>disabled</em>.
- If Cookies are enabled all valid cookies will automatically be
- saved in the client manager's cookie database.
- If the option verify is used the function http:verify_cookie/2
- has to be called for the cookie to be saved.</d>
- <v>IpFamily = inet | inet6 | inet6fb4 </v>
- <d>By default <em>inet</em>.
- When it is set to <c>inet6fb4</c> you can use both ipv4 and ipv6.
- It first tries <c>inet6</c> and if that does not works falls back to <c>inet</c>.
- The option is here to provide a workaround for buggy ipv6 stacks to ensure that
- ipv4 will always work.</d>
- <v>IpAddress = ip_address() </v>
- <d>If the host has several network interfaces, this option specifies which one to use.
- See gen_tcp:connect/3,4 for more info. </d>
- <v>Port = integer() </v>
- <d>Specify which local port number to use.
- See gen_tcp:connect/3,4 for more info. </d>
- <v>VerboseMode = false | verbose | debug | trace </v>
- <d>Default is <em>false</em>.
- This option is used to switch on (or off)
- different levels of erlang trace on the client.
- It is a debug feature.</d>
- <v>Profile = profile()</v>
- </type>
- <desc>
- <p>Sets options to be used for subsequent
- requests.</p>
- <note>
- <p>If possible the client will keep its connections
- alive and use persistent connections
- with or without pipeline depending on configuration
- and current circumstances. The HTTP/1.1 specification does not
- provide a guideline for how many requests that would be
- ideal to be sent on a persistent connection,
- this very much depends on the
- application. Note that a very long queue of requests may cause a
- user perceived delays as earlier request may take a long time
- to complete. The HTTP/1.1 specification does suggest a
- limit of 2 persistent connections per server, which is the
- default value of the max_sessions option. </p>
- </note>
-
- <marker id="stream_next"></marker>
- </desc>
- </func>
-
- <func>
- <name>stream_next(Pid) -> ok</name>
- <fsummary> Triggers the next message to be streamed, e.i.
- same behavior as active once for sockets.
- </fsummary>
- <type>
- <v>Pid = pid() - as received in the stream_start message</v>
- </type>
- <desc>
- <p>Triggers the next message to be streamed, e.i.
- same behavior as active once for sockets.</p>
-
- <marker id="verify_cookie"></marker>
- </desc>
- </func>
-
- <func>
- <name>verify_cookie(SetCookieHeaders, Url) -> </name>
- <name>verify_cookie(SetCookieHeaders, Url, Profile) -> ok | {error, Reason}</name>
- <fsummary>Saves the cookies defined in SetCookieHeaders in the client profile's cookie database.</fsummary>
- <type>
- <v>SetCookieHeaders = headers() - where field = "set-cookie"</v>
- <v>Url = url()</v>
- <v>Profile = profile()</v>
- </type>
- <desc>
- <p>Saves the cookies defined in SetCookieHeaders
- in the client profile's cookie database. You need to
- call this function if you set the option cookies to verify.
- If no profile is specified the default profile will be used.
- </p>
-
- <marker id="cookie_header"></marker>
- </desc>
- </func>
-
- <func>
- <name>cookie_header(Url) -> </name>
- <name>cookie_header(Url, Profile) -> header() | {error, Rason}</name>
- <fsummary>Returns the cookie header that would be sent when
- making a request to Url using the profile Profile.</fsummary>
- <type>
- <v>Url = url()</v>
- <v>Profile = profile()</v>
- </type>
- <desc>
- <p>Returns the cookie header that would be sent
- when making a request to Url using the profile Profile.
- If no profile is specified the default profile will be used.
- </p>
- </desc>
- </func>
- </funcs>
-
- <section>
- <title>SEE ALSO</title>
- <p>RFC 2616, <seealso marker="inets">inets(3)</seealso>,
- <seealso marker="ssl:ssl">ssl(3)</seealso>
- </p>
- </section>
-
-</erlref>
-
diff --git a/lib/inets/doc/src/http_client.xml b/lib/inets/doc/src/http_client.xml
index 510c30eb35..49327ca80f 100644
--- a/lib/inets/doc/src/http_client.xml
+++ b/lib/inets/doc/src/http_client.xml
@@ -1,10 +1,10 @@
-<?xml version="1.0" encoding="latin1" ?>
+<?xml version="1.0" encoding="iso-8859-1" ?>
<!DOCTYPE chapter SYSTEM "chapter.dtd">
<chapter>
<header>
<copyright>
- <year>2004</year><year>2009</year>
+ <year>2004</year><year>2011</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
@@ -56,8 +56,8 @@
<pre>
[{inets, [{services, [{httpc, PropertyList}]}]}]
</pre>
- <p>For valid properties see <seealso
- marker="http">http(3)</seealso></p>
+ <p>For valid properties see
+ <seealso marker="httpc">httpc(3)</seealso>. </p>
</section>
<section>
@@ -71,67 +71,66 @@
but not for requests to localhost. This will apply to all subsequent
requests</p>
<code type="erl">
- 2 > http:set_options([{proxy, {{"www-proxy.mycompany.com", 8000},
+ 2 > httpc:set_options([{proxy, {{"www-proxy.mycompany.com", 8000},
["localhost"]}}]).
ok
</code>
<p>An ordinary synchronous request. </p>
<code type="erl">
3 > {ok, {{Version, 200, ReasonPhrase}, Headers, Body}} =
- http:request(get, {"http://www.erlang.org", []}, [], []).
+ httpc:request(get, {"http://www.erlang.org", []}, [], []).
</code>
<p>With all default values, as above, a get request can also be written
like this.</p>
<code type="erl">
4 > {ok, {{Version, 200, ReasonPhrase}, Headers, Body}} =
- http:request("http://www.erlang.org").
+ httpc:request("http://www.erlang.org").
</code>
<p>An ordinary asynchronous request. The result will be sent
to the calling process on the form {http, {ReqestId, Result}}</p>
<code type="erl">
5 > {ok, RequestId} =
- http:request(get, {"http://www.erlang.org", []}, [], [{sync, false}]).
+ httpc:request(get, {"http://www.erlang.org", []}, [], [{sync, false}]).
</code>
<p>In this case the calling process is the shell, so we receive the
result.</p>
<code type="erl">
- 6 > receive {http, {RequestId, Result}} -> ok after 500 -> error end.
+ 6 > receive {http, {RequestId, Result}} -> ok after 500 -> error end.
ok
</code>
<p>Send a request with a specified connection header. </p>
<code type="erl">
7 > {ok, {{NewVersion, 200, NewReasonPhrase}, NewHeaders, NewBody}} =
- http:request(get, {"http://www.erlang.org", [{"connection", "close"}]},
+ httpc:request(get, {"http://www.erlang.org", [{"connection", "close"}]},
[], []).
</code>
<p>Start a HTTP client profile. </p>
<code><![CDATA[
- 8 > {ok, Pid} = inets:start(httpc, [{profile, foo}]).
+ 8 > {ok, Pid} = inets:start(httpc, [{profile, foo}]).
{ok, <0.45.0>}
]]></code>
<p>The new profile has no proxy settings so the connection will
be refused</p>
<code type="erl">
- 9 > http:request("http://www.erlang.org", foo).
- {error,econnrefused}
+ 9 > httpc:request("http://www.erlang.org", foo).
+ {error, econnrefused}
</code>
<p>Stop a HTTP client profile. </p>
<code type="erl">
- 10 > inets:stop(httpc, foo).
+ 10 > inets:stop(httpc, foo).
ok
</code>
<p>Alternatively:</p>
<code type="erl">
- 10 > inets:stop(httpc, Pid).
+ 10 > inets:stop(httpc, Pid).
ok
</code>
-
</section>
</chapter>
diff --git a/lib/inets/doc/src/http_server.xml b/lib/inets/doc/src/http_server.xml
index 56317d647c..68dfd1add0 100644
--- a/lib/inets/doc/src/http_server.xml
+++ b/lib/inets/doc/src/http_server.xml
@@ -4,7 +4,7 @@
<chapter>
<header>
<copyright>
- <year>2004</year><year>2009</year>
+ <year>2004</year><year>2010</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
@@ -13,12 +13,12 @@
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>HTTP server </title>
@@ -30,6 +30,8 @@
<date></date>
<rev></rev>
<file>http_server.xml</file>
+
+ <marker id="intro"></marker>
</header>
<section>
@@ -65,6 +67,8 @@
Server API. This API can be used to advantage by all who wants
to enhance the server core functionality, for example custom
logging and authentication.</p>
+
+ <marker id="config"></marker>
</section>
<section>
@@ -82,7 +86,7 @@
<p>The server is configured using an erlang property list.
For the available properties see
- <seealso marker="inets:inets">httpd(3)</seealso>
+ <seealso marker="httpd">httpd(3)</seealso>
For backwards compatibility also apache-like config files
are supported.
</p>
@@ -109,6 +113,8 @@
functions or only exported functions on chosen modules.</p>
<p>{accept_timeout, integer()} sets the wanted timeout value for
the server to set up a request connection.</p>
+
+ <marker id="using_http_server_api"></marker>
</section>
<section>
@@ -173,6 +179,7 @@
the ip address reported by the info function and can
not be the hostname that is allowed when inputting bind_address.</p>
+ <marker id="htaccess"></marker>
</section>
<section>
@@ -246,7 +253,7 @@
every row contains the name of the group and the members
of the group separated by a space, for example:</p>
<pre>
-\011 GroupName: Member1 Member2 .... MemberN
+GroupName: Member1 Member2 .... MemberN
</pre>
</item>
<item>
@@ -278,8 +285,8 @@
and every row contains User Name and Password separated by a
colon, for example:</p>
<pre>
-\011 UserName:Password
-\011 UserName:Password
+UserName:Password
+UserName:Password
</pre>
</item>
<item>
@@ -299,11 +306,11 @@
the specified methods. If no request method is specified
all request methods are verified against the restrictions.</p>
<pre>
-\011 &lt;Limit POST GET HEAD&gt;
-\011 order allow deny
-\011 require group group1
-\011 allow from 123.145.244.5
-\011 &lt;/Limit&gt;
+&lt;Limit POST GET HEAD&gt;
+ order allow deny
+ require group group1
+ allow from 123.145.244.5
+&lt;/Limit&gt;
</pre>
</item>
<item>
@@ -337,6 +344,8 @@
</item>
</list>
</section>
+
+ <marker id="dynamic_we_pages"></marker>
</section>
<section>
@@ -357,18 +366,16 @@
<p>The mod_cgi module makes it possible to execute CGI scripts
in the server. A file that matches the definition of a
ScriptAlias config directive is treated as a CGI script. A CGI
- script is executed by the server and it's output is returned to
+ script is executed by the server and its output is returned to
the client. </p>
<p>The CGI Script response comprises a message-header and a
message-body, separated by a blank line. The message-header
contains one or more header fields. The body may be
empty. Example: </p>
- <code type="none">
-"Content-Type:text/plain\
-Accept-Ranges:none\
-\
-some very
-\011plain text" </code>
+
+ <code>"Content-Type:text/plain\nAccept-Ranges:none\n\nsome very
+ plain text" </code>
+
<p>The server will interpret the cgi-headers and most of them
will be transformed into HTTP headers and sent back to the
client together with the body.</p>
@@ -387,7 +394,7 @@ some very
the extra overhead. An URL which calls an Erlang erl function
has the following syntax (regular expression): </p>
<code type="none">
-\011 http://your.server.org/***/Module[:/]Function(?QueryString|/PathInfo)
+http://your.server.org/***/Module[:/]Function(?QueryString|/PathInfo)
</code>
<p>*** above depends on how the ErlScriptAlias config
directive has been used</p>
@@ -428,7 +435,7 @@ http://your.server.org/***/Mod:Func(Arg1,...,ArgN)
http://your.server.org/eval?httpd_example:print(atom_to_list(apply(erlang,halt,[])))
</code>
<p>which effectively will close down the Erlang node,
- that is use the erl scheme instead, until this
+ therefor, use the erl scheme instead, until this
security breach has been fixed.</p>
<p>Today there are no good way of solving this problem
and therefore Eval Scheme may be removed in future
@@ -436,6 +443,8 @@ http://your.server.org/eval?httpd_example:print(atom_to_list(apply(erlang,halt,[
</note>
</section>
</section>
+
+ <marker id="logging"></marker>
</section>
<section>
@@ -469,6 +478,8 @@ http://your.server.org/eval?httpd_example:print(atom_to_list(apply(erlang,halt,[
</p>
<p><em>[date]</em> access to <em>path</em> failed for
<em>remotehost</em>, reason: <em>reason</em></p>
+
+ <marker id="ssi"></marker>
</section>
<section>
@@ -498,14 +509,14 @@ http://your.server.org/eval?httpd_example:print(atom_to_list(apply(erlang,halt,[
for parsed files, for example:
</p>
<pre>
-\011text/x-server-parsed-html shtml shtm
+ text/x-server-parsed-html shtml shtm
</pre>
<p>This makes files ending with <c>.shtml</c> and <c>.shtm</c>
into parsed files. Alternatively, if the performance hit is not a
problem, <em>all</em> HTML pages can be marked as parsed:
</p>
<pre>
-\011text/x-server-parsed-html html htm
+ text/x-server-parsed-html html htm
</pre>
</section>
@@ -518,7 +529,7 @@ http://your.server.org/eval?httpd_example:print(atom_to_list(apply(erlang,halt,[
unparsed. Each directive has the following format:
</p>
<pre>
-\011&lt;!--#command tag1="value1" tag2="value2" --&gt;
+ &lt;!--#command tag1="value1" tag2="value2" --&gt;
</pre>
<p>Each command takes different arguments, most only accept one
tag at a time. Here is a breakdown of the commands and their
@@ -612,7 +623,7 @@ http://your.server.org/eval?httpd_example:print(atom_to_list(apply(erlang,halt,[
<item>
<p>The unescaped version of any search query the client
sent, with all shell-special characters escaped with
- <c>\\</c>.</p>
+ <c>\</c>.</p>
</item>
<tag><c>DATE_LOCAL</c></tag>
<item>
@@ -753,24 +764,28 @@ http://your.server.org/eval?httpd_example:print(atom_to_list(apply(erlang,halt,[
schema and the tables already is created. </p>
<code>
- -module(mnesia_test).
- -export([start/0,load_data/0]).
- -include("mod_auth.hrl").
-
- first_start()->
- mnesia:create_schema([node()]),
- mnesia:start(),
- mnesia:create_table(httpd_user,
- [{type,bag},{disc_copies,[node()]},
- {attributes,record_info(fields,httpd_user)}]),
- mnesia:create_table(httpd_group,
- [{type,bag},{disc_copies,[node()]},
- {attributes,record_info(fields,httpd_group)}]),
- mnesia:wait_for_tables([httpd_user,httpd_group],60000).
-
- start()->
- mnesia:start(),
- mnesia:wait_for_tables([httpd_user,httpd_group],60000).
+-module(mnesia_test).
+-export([start/0,load_data/0]).
+-include("mod_auth.hrl").
+
+first_start() ->
+ mnesia:create_schema([node()]),
+ mnesia:start(),
+ mnesia:create_table(httpd_user,
+ [{type, bag},
+ {disc_copies, [node()]},
+ {attributes, record_info(fields,
+ httpd_user)}]),
+ mnesia:create_table(httpd_group,
+ [{type, bag},
+ {disc_copies, [node()]},
+ {attributes, record_info(fields,
+ httpd_group)}]),
+ mnesia:wait_for_tables([httpd_user, httpd_group], 60000).
+
+start() ->
+ mnesia:start(),
+ mnesia:wait_for_tables([httpd_user, httpd_group], 60000).
</code>
<p>To create the Mnesia tables we use two records defined in
diff --git a/lib/inets/doc/src/httpc.xml b/lib/inets/doc/src/httpc.xml
new file mode 100644
index 0000000000..7430a62b1b
--- /dev/null
+++ b/lib/inets/doc/src/httpc.xml
@@ -0,0 +1,618 @@
+<?xml version="1.0" encoding="latin1" ?>
+<!DOCTYPE erlref SYSTEM "erlref.dtd">
+
+<erlref>
+ <header>
+ <copyright>
+ <year>2004</year><year>2010</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>httpc</title>
+ <prepared>Ingela Anderton Andin</prepared>
+ <responsible></responsible>
+ <docno></docno>
+ <date></date>
+ <rev></rev>
+ </header>
+ <module>httpc</module>
+ <modulesummary>An HTTP/1.1 client </modulesummary>
+ <description>
+ <p>This module provides the API to a HTTP/1.1 compatible client according
+ to RFC 2616, caching is currently not supported.</p>
+ <note>
+ <p>When starting the Inets application a manager process for the
+ default profile will be started. The functions in this API
+ that does not explicitly use a profile will accesses the
+ default profile. A profile keeps track of proxy options,
+ cookies and other options that can be applied to more than one
+ request. </p>
+
+ <p>If the scheme
+ https is used the ssl application needs to be started.</p>
+
+ <p>Also note that pipelining will only be used if the pipeline
+ timeout is set, otherwise persistent connections without
+ pipelining will be used e.i. the client always waits for
+ the previous response before sending the next request.</p>
+ </note>
+ <p>There are some usage examples in the <seealso
+ marker="http_client">Inets User's Guide.</seealso></p>
+ </description>
+
+ <section>
+ <title>COMMON DATA TYPES </title>
+ <p>Type definitions that are used more than once in
+ this module:</p>
+ <code type="none"><![CDATA[
+boolean() = true | false
+string() = list of ASCII characters
+request_id() = ref()
+profile() = atom()
+path() = string() representing a file path or directory path
+ip_address() = See inet(3)
+socket_opt() = See the Options used by gen_tcp(3) and
+ ssl(3) connect(s)
+ ]]></code>
+
+ </section>
+
+ <section>
+ <title>HTTP DATA TYPES </title>
+ <p>Type definitions that are related to HTTP:</p>
+ <p>For more information about HTTP see rfc 2616</p>
+
+ <code type="none"><![CDATA[
+method() = head | get | put | post | trace | options | delete
+request() = {url(), headers()} |
+ {url(), headers(), content_type(), body()}
+url() = string() - Syntax according to the URI definition in rfc 2396, ex: "http://www.erlang.org"
+status_line() = {http_version(), status_code(), reason_phrase()}
+http_version() = string() ex: "HTTP/1.1"
+status_code() = integer()
+reason_phrase() = string()
+content_type() = string()
+headers() = [header()]
+header() = {field(), value()}
+field() = string()
+value() = string()
+body() = string() | binary()
+filename() = string()
+ ]]></code>
+
+ </section>
+
+ <section>
+ <title>SSL DATA TYPES </title>
+ <p>Some type definitions relevant when using https,
+ for details <seealso marker="ssl:ssl">ssl(3)</seealso>: </p>
+ <code type="none"><![CDATA[
+ssl_options() = {verify, code()} |
+ {depth, depth()} |
+ {certfile, path()} |
+ {keyfile, path()} |
+ {password, string()} |
+ {cacertfile, path()} |
+ {ciphers, string()}
+ ]]></code>
+ </section>
+
+ <section>
+ <title>HTTP CLIENT SERVICE START/STOP </title>
+
+ <p>A HTTP client can be configured to start when starting the inets
+ application or started dynamically in runtime by calling the
+ inets application API <c>inets:start(httpc, ServiceConfig)</c>, or
+ <c>inets:start(httpc, ServiceConfig, How)</c>
+ see <seealso marker="inets">inets(3)</seealso> Below follows a
+ description of the available configuration options.</p>
+ <taglist>
+ <tag>{profile, profile()}</tag>
+ <item>Name of the profile, see
+ common data types below, this option is mandatory.</item>
+ <tag>{data_dir, path()}</tag>
+ <item>Directory where the profile
+ may save persistent data, if omitted all cookies will be treated
+ as session cookies.</item>
+ </taglist>
+
+ <p>The client can be stopped using inets:stop(httpc, Pid) or
+ inets:stop(httpc, Profile).</p>
+
+ <marker id="request1"></marker>
+ </section>
+
+ <funcs>
+ <func>
+ <name>request(Url) -> </name>
+ <name>request(Url, Profile) -> {ok, Result} | {error, Reason}</name>
+ <fsummary>Sends a get HTTP-request</fsummary>
+ <type>
+ <v>Url = url() </v>
+ <v>Result = {status_line(), headers(), body()} |
+ {status_code(), body()} | request_id() </v>
+ <v>Profile = profile()</v>
+ <v>Reason = term() </v>
+ </type>
+ <desc>
+ <p>Equivalent to httpc:request(get, {Url, []}, [], []).</p>
+
+ <marker id="request2"></marker>
+ </desc>
+ </func>
+
+ <func>
+ <name>request(Method, Request, HTTPOptions, Options) -> </name>
+ <name>request(Method, Request, HTTPOptions, Options, Profile) -> {ok, Result} | {ok, saved_to_file} | {error, Reason}</name>
+
+ <fsummary>Sends a HTTP-request</fsummary>
+ <type>
+ <v>Method = method() </v>
+ <v>Request = request()</v>
+ <v>HTTPOptions = http_options()</v>
+ <v>http_options() = [http_option()]</v>
+ <v>http_option() = {timeout, timeout()} |
+ {connect_timeout, timeout()} |
+ {ssl, ssl_options()} |
+ {autoredirect, boolean()} |
+ {proxy_auth, {userstring(), passwordstring()}} |
+ {version, http_version()} |
+ {relaxed, boolean()}</v>
+ <v>timeout() = integer() >= 0 | infinity</v>
+ <v>Options = options()</v>
+ <v>options() = [option()]</v>
+ <v>option() = {sync, boolean()} |
+ {stream, stream_to()} |
+ {body_format, body_format()} |
+ {full_result, boolean()} |
+ {headers_as_is, boolean() |
+ {socket_opts, socket_opts()} |
+ {receiver, receiver()}}</v>
+ <v>stream_to() = none | self | {self, once} | filename() </v>
+ <v>socket_opts() = [socket_opt()]</v>
+ <v>receiver() = pid() | function()/1 | {Module, Function, Args} </v>
+ <v>Module = atom() </v>
+ <v>Function = atom() </v>
+ <v>Args = list() </v>
+ <v>body_format() = string | binary </v>
+ <v>Result = {status_line(), headers(), body()} |
+ {status_code(), body()} | request_id() </v>
+ <v>Profile = profile() </v>
+ <v>Reason = {connect_failed, term()} |
+ {send_failed, term()} | term() </v>
+ </type>
+
+ <desc>
+ <p>Sends a HTTP-request. The function can be both synchronous
+ and asynchronous. In the later case the function will return
+ {ok, RequestId} and later on the information will be delivered
+ to the <c>receiver</c> depending on that value. </p>
+
+ <p>Http option (<c>http_option()</c>) details: </p>
+ <taglist>
+ <tag><c><![CDATA[timeout]]></c></tag>
+ <item>
+ <p>Timeout time for the request. </p>
+ <p>The clock start ticking as soon as the request has been
+ sent. </p>
+ <p>Time is in milliseconds. </p>
+ <p>Defaults to <c>infinity</c>. </p>
+ </item>
+
+ <tag><c><![CDATA[connect_timeout]]></c></tag>
+ <item>
+ <p>Connection timeout time, used during the initial request,
+ when the client is <em>connecting</em> to the server. </p>
+ <p>Time is in milliseconds. </p>
+ <p>Defaults to the value of the <c>timeout</c> option. </p>
+ </item>
+
+ <tag><c><![CDATA[ssl]]></c></tag>
+ <item>
+ <p>If using SSL, these SSL-specific options are used. </p>
+ <p>Defaults to <c>[]</c>. </p>
+ </item>
+
+ <tag><c><![CDATA[autoredirect]]></c></tag>
+ <item>
+ <p>Should the client automatically retreive the information
+ from the new URI and return that as the result instead
+ of a 30X-result code. </p>
+ <p>Note that for some 30X-result codes automatic redirect
+ is not allowed in these cases the 30X-result will always
+ be returned. </p>
+ <p>Defaults to <c>true</c>. </p>
+ </item>
+
+ <tag><c><![CDATA[proxy_auth]]></c></tag>
+ <item>
+ <p>A proxy-authorization header using the provided user name and
+ password will be added to the request. </p>
+ </item>
+
+ <tag><c><![CDATA[version]]></c></tag>
+ <item>
+ <p>Can be used to make the client act as an <c>HTTP/1.0</c> or
+ <c>HTTP/0.9</c> client. By default this is an <c>HTTP/1.1</c>
+ client. When using <c>HTTP/1.0</c> persistent connections will
+ not be used. </p>
+ <p>Defaults to the trsing <c>"HTTP/1.1"</c>. </p>
+ </item>
+
+ <tag><c><![CDATA[relaxed]]></c></tag>
+ <item>
+ <p>If set to true workarounds for known server deviations from
+ the HTTP-standard are enabled. </p>
+ <p>Defaults to <c>false</c>. </p>
+ </item>
+
+ </taglist>
+
+ <p>Option (<c>option()</c>) details: </p>
+ <taglist>
+ <tag><c><![CDATA[sync]]></c></tag>
+ <item>
+ <p>Shall the request be synchronous or asynchronous. </p>
+ <p>Defaults to <c>true</c>. </p>
+ </item>
+
+ <tag><c><![CDATA[stream]]></c></tag>
+ <item>
+ <p>Streams the body of a 200 or 206 response to the calling
+ process or to a file. When streaming to the calling process
+ using the option <c>self</c> the the following stream messages
+ will be sent to that process: {http, {RequestId,
+ stream_start, Headers}, {http, {RequestId, stream,
+ BinBodyPart}, {http, {RequestId, stream_end, Headers}. When
+ streaming to to the calling processes using the option
+ <c>{self, once}</c> the first message will have an additional
+ element e.i. {http, {RequestId, stream_start, Headers, Pid},
+ this is the process id that should be used as an argument to
+ http:stream_next/1 to trigger the next message to be sent to
+ the calling process. </p>
+ <p>Note that it is possible that chunked encoding will add
+ headers so that there are more headers in the stream_end
+ message than in the stream_start.
+ When streaming to a file and the request is asynchronous the
+ message {http, {RequestId, saved_to_file}} will be sent. </p>
+ <p>Defaults to <c>none</c>. </p>
+ </item>
+
+ <tag><c><![CDATA[body_format]]></c></tag>
+ <item>
+ <p>Defines if the body shall be delivered as a string or as a
+ binary. This option is only valid for the synchronous
+ request. </p>
+ <p>Defaults to <c>string</c>. </p>
+ </item>
+
+ <tag><c><![CDATA[full_result]]></c></tag>
+ <item>
+ <p>Should a "full result" be returned to the caller (that is,
+ the body, the headers and the entire status-line) or not
+ (the body and the status code). </p>
+ <p>Defaults to <c>true</c>. </p>
+ </item>
+
+ <tag><c><![CDATA[header_as_is]]></c></tag>
+ <item>
+ <p>Shall the headers provided by the user be made
+ lower case or be regarded as case sensitive. </p>
+ <p>Note that the http standard requires them to be
+ case insenstive. This feature should only be used if there is
+ no other way to communicate with the server or for testing
+ purpose. Also note that when this option is used no headers
+ will be automatically added, all necessary headers has to be
+ provided by the user. </p>
+ <p>Defaults to <c>false</c>. </p>
+ </item>
+
+ <tag><c><![CDATA[socket_opts]]></c></tag>
+ <item>
+ <p>Socket options to be used for this and subsequent
+ request(s). </p>
+ <p>Overrides any value set by the
+ <seealso marker="set_options">set_options</seealso>
+ function. </p>
+ <p>Note that the validity of the options are <em>not</em>
+ checked in any way. </p>
+ <p>Note that this may change the socket behaviour
+ (see <seealso marker="kernel:inet#setopts">inet:setopts/2</seealso>)
+ for an already existing, and therefor already connected
+ request handler. </p>
+ <p>By defaults the socket options set by the
+ <seealso marker="#set_options">set_options/1,2</seealso>
+ function is used when establishing connection. </p>
+ </item>
+
+ <tag><c><![CDATA[receiver]]></c></tag>
+ <item>
+ <p>Defines how the client will deliver the result for a
+ asynchroneous request (<c>sync</c> has the value
+ <c>false</c>). </p>
+
+ <taglist>
+ <tag><c><![CDATA[pid()]]></c></tag>
+ <item>
+ <p>Message(s) will be sent to this process in the format: </p>
+<pre>
+{http, ReplyInfo}
+</pre>
+ </item>
+
+ <tag><c><![CDATA[function/1]]></c></tag>
+ <item>
+ <p>Information will be delivered to the receiver via calls
+ to the provided fun: </p>
+<pre>
+Receiver(ReplyInfo)
+</pre>
+ </item>
+
+ <tag><c><![CDATA[{Module, Funcion, Args}]]></c></tag>
+ <item>
+ <p>Information will be delivered to the receiver via calls
+ to the callback function: </p>
+<pre>
+apply(Module, Function, [ReplyInfo | Args])
+</pre>
+ </item>
+
+ </taglist>
+ <p>In all cases above, <c>ReplyInfo</c> has the following
+ structure: </p>
+
+<pre>
+{RequestId, saved_to_file}
+{RequestId, {error, Reason}}
+{RequestId, Result}
+{RequestId, stream_start, Headers}
+{RequestId, stream_start, Headers, HandlerPid}
+{RequestId, stream, BinBodyPart}
+{RequestId, stream_end, Headers}
+</pre>
+
+ <p>Defaults to the <c>pid()</c> of the process calling the request
+ function (<c>self()</c>). </p>
+ </item>
+ </taglist>
+
+ <marker id="cancel_request"></marker>
+ </desc>
+ </func>
+
+ <func>
+ <name>cancel_request(RequestId) -> </name>
+ <name>cancel_request(RequestId, Profile) -> ok</name>
+ <fsummary>Cancels an asynchronous HTTP-request.</fsummary>
+ <type>
+ <v>RequestId = request_id() - A unique identifier as returned
+ by request/4</v>
+ <v>Profile = profile()</v>
+ </type>
+ <desc>
+ <p>Cancels an asynchronous HTTP-request. </p>
+
+ <marker id="set_options"></marker>
+ </desc>
+ </func>
+
+ <func>
+ <name>set_options(Options) -> </name>
+ <name>set_options(Options, Profile) -> ok | {error, Reason}</name>
+ <fsummary>Sets options to be used for subsequent requests.</fsummary>
+ <type>
+ <v>Options = [Option]</v>
+ <v>Option = {proxy, {Proxy, NoProxy}} |
+ {max_sessions, MaxSessions} |
+ {max_keep_alive_length, MaxKeepAlive} |
+ {keep_alive_timeout, KeepAliveTimeout} |
+ {max_pipeline_length, MaxPipeline} |
+ {pipeline_timeout, PipelineTimeout} |
+ {cookies, CookieMode} |
+ {ipfamily, IpFamily} |
+ {ip, IpAddress} |
+ {port, Port} |
+ {socket_opts, socket_opts()} |
+ {verbose, VerboseMode} </v>
+ <v>Proxy = {Hostname, Port}</v>
+ <v>Hostname = string() </v>
+ <d>ex: "localhost" or "foo.bar.se"</d>
+ <v>Port = integer()</v>
+ <d>ex: 8080 </d>
+ <v>socket_opts() = [socket_opt()]</v>
+ <d>The options are appended to the socket options used by the
+ client. </d>
+ <d>These are the default values when a new request handler
+ is started (for the initial connect). They are passed directly
+ to the underlying transport (gen_tcp or ssl) <em>without</em>
+ verification! </d>
+ <v>NoProxy = [NoProxyDesc]</v>
+ <v>NoProxyDesc = DomainDesc | HostName | IPDesc</v>
+ <v>DomainDesc = "*.Domain"</v>
+ <d>ex: "*.ericsson.se"</d>
+ <v>IpDesc = string()</v>
+ <d>ex: "134.138" or "[FEDC:BA98" (all IP-addresses starting with 134.138 or FEDC:BA98), "66.35.250.150" or "[2010:836B:4179::836B:4179]" (a complete IP-address).</d>
+ <v>MaxSessions = integer() </v>
+ <d>Default is <em>2</em>.
+ Maximum number of persistent connections to a host.</d>
+ <v>MaxKeepAlive = integer() </v>
+ <d>Default is <em>5</em>.
+ Maximum number of outstanding requests on the same connection to
+ a host.</d>
+ <v>KeepAliveTimeout = integer() </v>
+ <d>Default is <em>120000</em> (= 2 min).
+ If a persistent connection is idle longer than the
+ keep_alive_timeout the client will close the connection.
+ The server may also have a such a time out but you should
+ not count on it!</d>
+ <v>MaxPipeline = integer() </v>
+ <d>Default is <em>2</em>.
+ Maximum number of outstanding requests on a pipelined connection to a host.</d>
+ <v>PipelineTimeout = integer() </v>
+ <d>Default is <em>0</em>,
+ which will result in pipelining not being used.
+ If a persistent connection is idle longer than the
+ pipeline_timeout the client will close the connection. </d>
+ <v>CookieMode = enabled | disabled | verify </v>
+ <d>Default is <em>disabled</em>.
+ If Cookies are enabled all valid cookies will automatically be
+ saved in the client manager's cookie database.
+ If the option verify is used the function http:verify_cookie/2
+ has to be called for the cookie to be saved.</d>
+ <v>IpFamily = inet | inet6 | inet6fb4 </v>
+ <d>By default <em>inet</em>.
+ When it is set to <c>inet6fb4</c> you can use both ipv4 and ipv6.
+ It first tries <c>inet6</c> and if that does not works falls back to <c>inet</c>.
+ The option is here to provide a workaround for buggy ipv6 stacks to ensure that
+ ipv4 will always work.</d>
+ <v>IpAddress = ip_address() </v>
+ <d>If the host has several network interfaces, this option specifies which one to use.
+ See gen_tcp:connect/3,4 for more info. </d>
+ <v>Port = integer() </v>
+ <d>Specify which local port number to use.
+ See gen_tcp:connect/3,4 for more info. </d>
+ <v>VerboseMode = false | verbose | debug | trace </v>
+ <d>Default is <em>false</em>.
+ This option is used to switch on (or off)
+ different levels of erlang trace on the client.
+ It is a debug feature.</d>
+ <v>Profile = profile()</v>
+ </type>
+ <desc>
+ <p>Sets options to be used for subsequent
+ requests.</p>
+ <note>
+ <p>If possible the client will keep its connections
+ alive and use persistent connections
+ with or without pipeline depending on configuration
+ and current circumstances. The HTTP/1.1 specification does not
+ provide a guideline for how many requests that would be
+ ideal to be sent on a persistent connection,
+ this very much depends on the
+ application. Note that a very long queue of requests may cause a
+ user perceived delays as earlier request may take a long time
+ to complete. The HTTP/1.1 specification does suggest a
+ limit of 2 persistent connections per server, which is the
+ default value of the max_sessions option. </p>
+ </note>
+
+ <marker id="stream_next"></marker>
+ </desc>
+ </func>
+
+ <func>
+ <name>stream_next(Pid) -> ok</name>
+ <fsummary> Triggers the next message to be streamed, e.i.
+ same behavior as active once for sockets.
+ </fsummary>
+ <type>
+ <v>Pid = pid() - as received in the stream_start message</v>
+ </type>
+ <desc>
+ <p>Triggers the next message to be streamed, e.i.
+ same behavior as active once for sockets.</p>
+
+ <marker id="verify_cookie"></marker>
+ <marker id="store_cookie"></marker>
+ </desc>
+ </func>
+
+ <func>
+ <name>store_cookie(SetCookieHeaders, Url) -> </name>
+ <name>store_cookie(SetCookieHeaders, Url, Profile) -> ok | {error, Reason}</name>
+ <fsummary>Saves the cookies defined in SetCookieHeaders in the client profile's cookie database.</fsummary>
+ <type>
+ <v>SetCookieHeaders = headers() - where field = "set-cookie"</v>
+ <v>Url = url()</v>
+ <v>Profile = profile()</v>
+ </type>
+ <desc>
+ <p>Saves the cookies defined in SetCookieHeaders
+ in the client profile's cookie database. You need to
+ call this function if you set the option cookies to <c>verify</c>.
+ If no profile is specified the default profile will be used.
+ </p>
+
+ <marker id="cookie_header"></marker>
+ </desc>
+ </func>
+
+ <func>
+ <name>cookie_header(Url) -> </name>
+ <name>cookie_header(Url, Profile) -> header() | {error, Rason}</name>
+ <fsummary>Returns the cookie header that would be sent when
+ making a request to Url using the profile Profile.</fsummary>
+ <type>
+ <v>Url = url()</v>
+ <v>Profile = profile()</v>
+ </type>
+ <desc>
+ <p>Returns the cookie header that would be sent
+ when making a request to Url using the profile Profile.
+ If no profile is specified the default profile will be used.
+ </p>
+
+ <marker id="reset_cookies"></marker>
+ </desc>
+ </func>
+
+
+ <func>
+ <name>reset_cookies() -> void()</name>
+ <name>reset_cookies(Profile) -> void()</name>
+ <fsummary>Reset the cookie database.</fsummary>
+ <type>
+ <v>Profile = profile()</v>
+ </type>
+ <desc>
+ <p>Resets (clears) the cookie database for the specified Profile.
+ If no profile is specified the default profile will be used.
+ </p>
+ </desc>
+ </func>
+
+
+ <func>
+ <name>which_cookies() -> cookies()</name>
+ <name>which_cookies(Profile) -> cookies()</name>
+ <fsummary>Dumps out the entire cookie database.</fsummary>
+ <type>
+ <v>Profile = profile()</v>
+ <v>cookies() = [cooie_stores()]</v>
+ <v>cookie_stores() = {cookies, icookies()} | {session_cookies, icookies()}</v>
+ <v>icookies() = [icookie()]</v>
+ <v>cookie() = term()</v>
+ </type>
+ <desc>
+ <p>This function produces a list of the entire cookie database.
+ It is intended for debugging/testing purposes.
+ If no profile is specified the default profile will be used.
+ </p>
+ </desc>
+ </func>
+ </funcs>
+
+ <section>
+ <title>SEE ALSO</title>
+ <p>RFC 2616, <seealso marker="inets">inets(3)</seealso>,
+ <seealso marker="kernel:gen_tcp">gen_tcp(3)</seealso>,
+ <seealso marker="ssl:ssl">ssl(3)</seealso>
+ </p>
+ </section>
+
+</erlref>
+
diff --git a/lib/inets/doc/src/httpd.xml b/lib/inets/doc/src/httpd.xml
index 60afcc6cfe..f061488ac3 100644
--- a/lib/inets/doc/src/httpd.xml
+++ b/lib/inets/doc/src/httpd.xml
@@ -1,10 +1,10 @@
-<?xml version="1.0" encoding="latin1" ?>
+<?xml version="1.0" encoding="iso-8859-1" ?>
<!DOCTYPE erlref SYSTEM "erlref.dtd">
<erlref>
<header>
<copyright>
- <year>1997</year><year>2009</year>
+ <year>1997</year><year>2011</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
@@ -13,12 +13,12 @@
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>httpd</title>
@@ -93,7 +93,7 @@
followed by the value followed by a new line. Ex:
<code>
- {server_root, "/urs/local/www"} -> ServerRoot /usr/local/www
+{server_root, "/urs/local/www"} -> ServerRoot /usr/local/www
</code>
<p>With a few exceptions, that are documented
@@ -103,9 +103,9 @@
as:</p>
<pre>
<![CDATA[
- <Directory Dir>
- <Properties handled as described above>
- </Directory>
+<Directory Dir>
+ <Properties handled as described above>
+</Directory>
]]>
</pre>
</item>
@@ -239,9 +239,9 @@
as an Apache like file as well as directly in the property list. Such
a file may look like:</p>
<pre>
- \011 # MIME type\011\011\011Extension
- \011 text/html\011\011\011html htm
- \011 text/plain\011\011\011asc txt
+# MIME type Extension
+text/html html htm
+text/plain asc txt
</pre>
<p>Defaults to [{"html","text/html"},{"htm","text/html"}]</p>
@@ -869,19 +869,19 @@ bytes
ModData = #mod{}
-record(mod, {
-\011\011data = [],
-\011\011socket_type = ip_comm,
-\011\011socket,
-\011\011config_db,
-\011\011method,
-\011\011absolute_uri,
-\011\011request_uri,
-\011\011http_version,
-\011\011request_line,
-\011\011parsed_header = [],
-\011\011entity_body,
-\011\011connection
-\011 }).
+ data = [],
+ socket_type = ip_comm,
+ socket,
+ config_db,
+ method,
+ absolute_uri,
+ request_uri,
+ http_version,
+ request_line,
+ parsed_header = [],
+ entity_body,
+ connection
+ }).
</code>
<p>The fields of the <c>mod</c> record has the following meaning:
</p>
diff --git a/lib/inets/doc/src/httpd_util.xml b/lib/inets/doc/src/httpd_util.xml
index 1566ee29d1..6ac2b13c72 100644
--- a/lib/inets/doc/src/httpd_util.xml
+++ b/lib/inets/doc/src/httpd_util.xml
@@ -4,7 +4,7 @@
<erlref>
<header>
<copyright>
- <year>1997</year><year>2009</year>
+ <year>1997</year><year>2010</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
@@ -13,12 +13,12 @@
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>httpd_util</title>
@@ -63,7 +63,7 @@
<v>Etag = string()</v>
</type>
<desc>
- <p><c>create_etag/1</c> calculates the Etag for a file, from it's
+ <p><c>create_etag/1</c> calculates the Etag for a file, from its
size and time for last modification. fileinfo is a record defined
in <c>kernel/include/file.hrl</c></p>
@@ -78,7 +78,7 @@
<v>HexValue = DecValue = string()</v>
</type>
<desc>
- <p>Converts the hexadecimal value <c>HexValue</c> into it's
+ <p>Converts the hexadecimal value <c>HexValue</c> into its
decimal equivalent (<c>DecValue</c>).</p>
<marker id="day"></marker>
@@ -218,7 +218,8 @@
<marker id="lookup_mime"></marker>
<p><c>lookup_mime</c> returns the mime type associated with a
specific file suffix as specified in the <c>mime.types</c>
- file (located in the <path unix="$SERVER_ROOT/conf/mime.types" windows="%SERVER_ROOT%\\\\conf\\\\mime.types">config directory</path>).</p>
+ file (located in the
+ <path unix="$SERVER_ROOT/conf/mime.types" windows="%SERVER_ROOT%\conf\mime.types">config directory</path>).</p>
<marker id="lookup_mime_default"></marker>
</desc>
@@ -239,7 +240,7 @@
<p><c>lookup_mime_default</c> returns the mime type associated
with a specific file suffix as specified in the
<c>mime.types</c> file (located in the
- <path unix="$SERVER_ROOT/conf/mime.types" windows="%SERVER_ROOT%\\\\conf\\\\mime.types">config directory</path>).
+ <path unix="$SERVER_ROOT/conf/mime.types" windows="%SERVER_ROOT%\conf\mime.types">config directory</path>).
If no appropriate association can be found
the value of DefaultType is
returned.</p>
diff --git a/lib/inets/doc/src/inets.xml b/lib/inets/doc/src/inets.xml
index e5fe32f32f..c367d7fa77 100644
--- a/lib/inets/doc/src/inets.xml
+++ b/lib/inets/doc/src/inets.xml
@@ -4,7 +4,7 @@
<erlref>
<header>
<copyright>
- <year>2007</year><year>2009</year>
+ <year>2007</year><year>2010</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
@@ -40,13 +40,13 @@
<title>COMMON DATA TYPES </title>
<p>Type definitions that are used more than once in
this module: </p>
- <p><c> service() = ftpc | tfptd | httpc | httpd</c></p>
+ <p><c> service() = ftpc | tftp | httpc | httpd</c></p>
<p><c> property() = atom() </c></p>
</section>
<funcs>
<func>
<name>services() -> [{Service, Pid}]</name>
- <fsummary>Returns a list of currently running services. </fsummary>
+ <fsummary>Returns a list of currently running services. </fsummary>
<type>
<v>Service = service()</v>
<v>Pid = pid()</v>
@@ -97,7 +97,7 @@
<name>start(Type) -> ok | {error, Reason}</name>
<fsummary>Starts the Inets application. </fsummary>
<type>
- <v>Type = permanent | transient | temporary</v>
+ <v>Type = permanent | transient | temporary</v>
</type>
<desc>
<p>Starts the Inets application. Default type
@@ -115,11 +115,9 @@
</func>
<func>
<name>start(Service, ServiceConfig) -> {ok, Pid} | {error, Reason}</name>
- <name>start(Service, ServiceConfig, How) -> {ok, Pid} |
- {error, Reason}</name>
+ <name>start(Service, ServiceConfig, How) -> {ok, Pid} | {error, Reason}</name>
<fsummary>Dynamically starts an inets
- service after the inets application has been
- started. </fsummary>
+ service after the inets application has been started. </fsummary>
<type>
<v>Service = service()</v>
<v>ServiceConfig = [{Option, Value}]</v>
@@ -129,7 +127,7 @@
</type>
<desc>
<p>Dynamically starts an inets service after the inets
- application has been started.\011</p>
+ application has been started. </p>
<note>
<p>Dynamically started services will not be handled by
application takeover and failover behavior when inets is
@@ -153,9 +151,9 @@
<fsummary>Stops a started service of the inets application or takes
down a "stand_alone-service" gracefully.</fsummary>
<type>
- <v>Service = service() | stand_alone</v>
+ <v>Service = service() | stand_alone</v>
<v>Reference = pid() | term() - service specified reference</v>
- <v>Reason = term()</v>
+ <v>Reason = term()</v>
</type>
<desc>
<p>Stops a started service of the inets application or takes
@@ -169,7 +167,7 @@
<section>
<title>SEE ALSO</title>
<p><seealso marker="ftp">ftp(3)</seealso>,
- <seealso marker="http">http(3)</seealso>,
+ <seealso marker="httpc">httpc(3)</seealso>,
<seealso marker="httpd">httpd(3)</seealso>,
<seealso marker="tftp">tftp(3)</seealso></p>
</section>
diff --git a/lib/inets/doc/src/make.dep b/lib/inets/doc/src/make.dep
index d96c6dc5b8..8deb7e7a5a 100644
--- a/lib/inets/doc/src/make.dep
+++ b/lib/inets/doc/src/make.dep
@@ -1,3 +1,23 @@
+#
+# %CopyrightBegin%
+#
+# Copyright Ericsson AB 1999-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%
+#
+#
+
# ----------------------------------------------------
# >>>> Do not edit this file <<<<
# This file was automaticly generated by
@@ -9,7 +29,7 @@
# TeX files that the DVI file depend on
# ----------------------------------------------------
-book.dvi: book.tex ftp.tex ftp_client.tex http.tex http_client.tex \
+book.dvi: book.tex ftp.tex ftp_client.tex httpc.tex http_client.tex \
http_server.tex httpd.tex httpd_conf.tex httpd_socket.tex \
httpd_util.tex inets.tex inets_services.tex \
mod_alias.tex mod_auth.tex mod_esi.tex mod_security.tex \
diff --git a/lib/inets/doc/src/mod_esi.xml b/lib/inets/doc/src/mod_esi.xml
index d4541a1d15..6bad77dc0a 100644
--- a/lib/inets/doc/src/mod_esi.xml
+++ b/lib/inets/doc/src/mod_esi.xml
@@ -4,7 +4,7 @@
<erlref>
<header>
<copyright>
- <year>1997</year><year>2009</year>
+ <year>1997</year><year>2010</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
@@ -13,12 +13,12 @@
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>mod_esi</title>
@@ -94,7 +94,7 @@
that the first chunk of data sent to the client must at
least contain all HTTP header fields that the response
will generate. If the first chunk not contains
- <em>End of HTTP header</em> that is <c>"\\r\ \\r\ "</c>
+ <em>End of HTTP header</em> that is <c>"\r\n\r\n"</c>
the server will
assume that no HTTP header fields will be generated.</p>
</desc>
diff --git a/lib/inets/doc/src/mod_security.xml b/lib/inets/doc/src/mod_security.xml
index 5f9f88071e..2a871d29d8 100644
--- a/lib/inets/doc/src/mod_security.xml
+++ b/lib/inets/doc/src/mod_security.xml
@@ -4,7 +4,7 @@
<erlref>
<header>
<copyright>
- <year>1998</year><year>2009</year>
+ <year>1998</year><year>2010</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
@@ -13,12 +13,12 @@
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>mod_security</title>
@@ -117,11 +117,14 @@
<section>
<marker id="callback_module"></marker>
<title>The SecurityCallbackModule</title>
- <p>The SecurityCallbackModule is a user written module that can receive events from
- the mod_security Erlang Webserver API module. This module only exports one function,
- <seealso marker="#callback_module_event">event/4</seealso>, which is described below.
+ <p>The SecurityCallbackModule is a user written module that can receive
+ events from the mod_security Erlang Webserver API module.
+ This module only exports the function(s),
+ <seealso marker="#callback_module_event">event/4,5</seealso>,
+ which are described below.
</p>
</section>
+
<funcs>
<func>
<name>event(What, Port, Dir, Data) -> ignored</name>
@@ -131,7 +134,7 @@
<v>What = atom()</v>
<v>Port = integer()</v>
<v>Address = {A,B,C,D} | string() &lt;v>Dir = string()</v>
- <v>What = [Info]</v>
+ <v>Data = [Info]</v>
<v>Info = {Name, Value}</v>
</type>
<desc>
diff --git a/lib/inets/doc/src/notes.xml b/lib/inets/doc/src/notes.xml
index 489e88cbe5..c954d4b7eb 100644
--- a/lib/inets/doc/src/notes.xml
+++ b/lib/inets/doc/src/notes.xml
@@ -1,10 +1,10 @@
-<?xml version="1.0" encoding="latin1" ?>
+<?xml version="1.0" encoding="iso-8859-1" ?>
<!DOCTYPE chapter SYSTEM "chapter.dtd">
<chapter>
<header>
<copyright>
- <year>2002</year><year>2009</year>
+ <year>2002</year><year>2011</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
@@ -32,6 +32,426 @@
<file>notes.xml</file>
</header>
+ <section><title>Inets 5.3.6</title>
+
+ <section><title>Fixed Bugs and Malfunctions</title>
+ <list>
+ <item>
+ <p>[httpd] XSS prevention did not work for hex-encoded URL's. </p>
+ <p>Own Id: OTP-9655</p>
+ </item>
+
+ <item>
+ <p>[httpd] GET request with malformed header date caused
+ server crash (non-fatal) with no reply to client. Will
+ now result in a reply with status code 400. </p>
+ <p>Own Id: OTP-9674</p>
+ <p>Aux Id: seq11936</p>
+ </item>
+
+ </list>
+ </section>
+
+ </section> <!-- 5.3.6 -->
+
+
+ <section><title>Inets 5.3.5</title>
+
+ <section><title>Fixed Bugs and Malfunctions</title>
+ <list>
+ <item>
+ <p>Updated http-server to make sure URLs in error-messages
+ are URL-encoded. Added support in http-client to use
+ URL-encoding. Also added the missing include directory
+ for the inets application.</p>
+ <p>Own Id: OTP-8940</p>
+ <p>Aux Id: seq11735</p>
+ </item>
+
+ <item>
+ <p>[httpd] Prevent XSS in error pages.
+ Prevent user controlled input from being interpreted
+ as HTML in error pages by encoding the reserved HTML
+ characters. </p>
+ <p>Michael Santos</p>
+ <p>Own Id: OTP-9124</p>
+ </item>
+ </list>
+ </section>
+
+ </section> <!-- 5.3.5 -->
+
+
+ <section><title>Inets 5.3.4</title>
+
+ <section><title>Improvements and New Features</title>
+ <p>-</p>
+
+<!--
+ <list>
+ <item>
+ <p>[httpc] - Allow users to pass socket options to the transport
+ module when making requests. </p>
+ <p>See the <c>socket_opts</c> option in the
+ <seealso marker="httpc#request2">request/4</seealso> or
+ <seealso marker="httpc#set_options">set_options/1,2</seealso>
+ for more info, </p>
+ <p>Own Id: OTP-8352</p>
+ </item>
+
+ </list>
+-->
+ </section>
+
+ <section><title>Fixed Bugs and Malfunctions</title>
+
+<!--
+ <p>-</p>
+-->
+
+ <list>
+ <item>
+ <p>[httpc] - If a request times out (not during connect), the
+ handler process exited (normal) but neglected to inform
+ the manager process. For this reason, the manager
+ did not clean up the request table, resulting in a
+ memory leak. Also the manager did not create a monitor
+ for the handler, so in an unforseen handler crash, this
+ could also create a memory leak. </p>
+ <p>Own Id: OTP-8739</p>
+ </item>
+
+ <item>
+ <p>[tftp] - Was spelled wrong in documentation and in some
+ parts of the code. It should be tftp. </p>
+ <p>Own Id: OTP-8741</p>
+ </item>
+
+ <item>
+ <p>[htpc] - Replaced the old http client api module (http)
+ with the new, http client in the
+ <seealso marker="http_client">Users Guide</seealso>. </p>
+ <p>Own Id: OTP-8742</p>
+ <p>Ryan Zezeski</p>
+ </item>
+
+ </list>
+ </section>
+
+ </section> <!-- 5.3.4 -->
+
+
+ <section><title>Inets 5.3.3</title>
+
+ <section><title>Improvements and New Features</title>
+ <p>-</p>
+
+<!--
+ <list>
+ <item>
+ <p>[httpc] - Allow users to pass socket options to the transport
+ module when making requests. </p>
+ <p>See the <c>socket_opts</c> option in the
+ <seealso marker="httpc#request2">request/4</seealso> or
+ <seealso marker="httpc#set_options">set_options/1,2</seealso>
+ for more info, </p>
+ <p>Own Id: OTP-8352</p>
+ </item>
+
+ </list>
+-->
+ </section>
+
+ <section><title>Fixed Bugs and Malfunctions</title>
+
+<!--
+ <p>-</p>
+-->
+
+ <list>
+ <item>
+ <p>[httpc] - Made cookie handling more case insensitive.</p>
+ <p>Own Id: OTP-8609</p>
+ <p>Nicolas Thauvin</p>
+ </item>
+
+ <item>
+ <p>[httpc|httpd] - Netscape cookie dates can also be given with a
+ 2-digit year (e.g. 06 = 2006). </p>
+ <p>Own Id: OTP-8610</p>
+ <p>Nicolas Thauvin</p>
+ </item>
+
+ <item>
+ <p>[httpd] - Added support (again) for the documented debugging
+ features. See the User's Guide
+ <seealso marker="http_server#config">Configuration</seealso>
+ chapter for more info. </p>
+ <p>Own Id: OTP-8624</p>
+ </item>
+
+ </list>
+ </section>
+
+ </section> <!-- 5.3.3 -->
+
+
+ <section><title>Inets 5.3.2</title>
+
+ <section><title>Improvements and New Features</title>
+ <p>-</p>
+
+<!--
+ <list>
+ <item>
+ <p>[httpc] - Allow users to pass socket options to the transport
+ module when making requests. </p>
+ <p>See the <c>socket_opts</c> option in the
+ <seealso marker="httpc#request2">request/4</seealso> or
+ <seealso marker="httpc#set_options">set_options/1,2</seealso>
+ for more info, </p>
+ <p>Own Id: OTP-8352</p>
+ </item>
+
+ </list>
+-->
+ </section>
+
+ <section><title>Fixed Bugs and Malfunctions</title>
+
+<!--
+ <p>-</p>
+-->
+
+ <list>
+ <item>
+ <p>[httpc] - Memory leak plugged.
+ The profile manager never cleaned up in its handler database.
+ This meant that with each new request handler, another entry
+ was created that was never deleted. Eventually the request
+ id counter (used as a key) would wrap, but the machine would
+ most likely run out of memory before that happened.</p>
+ <p>Own Id: OTP-8542</p>
+ <p>Lev Walkin</p>
+ </item>
+
+ <item>
+ <p>[httpc] - https requests with default port (443) not handled
+ properly. </p>
+ <p>Own Id: OTP-8607</p>
+ <p>jebu ittiachen</p>
+ </item>
+
+ </list>
+ </section>
+
+ </section> <!-- 5.3.2 -->
+
+
+ <section><title>Inets 5.3.1</title>
+
+ <section><title>Improvements and New Features</title>
+ <p>-</p>
+
+<!--
+ <list>
+ <item>
+ <p>[httpc] - Allow users to pass socket options to the transport
+ module when making requests. </p>
+ <p>See the <c>socket_opts</c> option in the
+ <seealso marker="httpc#request2">request/4</seealso> or
+ <seealso marker="httpc#set_options">set_options/1,2</seealso>
+ for more info, </p>
+ <p>Own Id: OTP-8352</p>
+ </item>
+
+ </list>
+-->
+ </section>
+
+ <section><title>Fixed Bugs and Malfunctions</title>
+
+<!--
+ <p>-</p>
+-->
+
+ <list>
+ <item>
+ <p>[httpc] - Badly formated error reason for errors occuring
+ during initial connect to a server.
+ Also, the possible error reasons was
+ not properly documented.</p>
+ <p>Own Id: OTP-8508</p>
+ <p>Aux Id: seq11407</p>
+ </item>
+
+ <item>
+ <p>[httpd] - Issues with ESI erl_script_timeout. </p>
+ <p>
+ <list type="bulleted">
+ <item>
+ <p>The <c>erl_script_timeout</c> config option is ducumented
+ as a number of seconds. But when parsing the config, in the
+ new format (not a config file), it was handled as if in
+ number of milliseconds. </p>
+ </item>
+ <item>
+ <p>When the erl-script-timeout time was exceeded, the server
+ incorrectly marked the answer as sent, thereby leaving
+ client hanging (with an incomplete answer).
+ This has been changed, so that now the socket will be
+ closed. </p>
+ </item>
+ </list>
+ </p>
+ <p>Own Id: OTP-8509</p>
+ </item>
+ </list>
+ </section>
+
+ </section> <!-- 5.3.1 -->
+
+
+ <section><title>Inets 5.3</title>
+
+ <section><title>Improvements and New Features</title>
+<!--
+ <p>-</p>
+-->
+
+ <list>
+ <item>
+ <p>[httpc] - Allow users to pass socket options to the transport
+ module when making requests. </p>
+ <p>See the <c>socket_opts</c> option in the
+ <seealso marker="httpc#request2">request/4</seealso> or
+ <seealso marker="httpc#set_options">set_options/1,2</seealso>
+ for more info, </p>
+ <p>Own Id: OTP-8352</p>
+ </item>
+
+ <item>
+ <p>[httpc] Fix bug crafting Host header when port is not 80. </p>
+ <p>The host header should include the port number as well as the
+ host name when making a request to a server listening on a port
+ other than the HTTP default of 80. Currently, only the host
+ name is included. This is important to make the http client
+ more compliant with the HTTP specification. </p>
+ <p>Own Id: OTP-8371</p>
+ <p>Kelly McLaughlin</p>
+ </item>
+
+ <item>
+ <p>[httpc|httpd] http_chunk data handling/passing improvement. </p>
+ <p>This is a modification to the http_chunk module to forward any
+ full chunk received, regardless of whether the size field for the
+ following chunk has been received yet. This allows http_chunk to
+ be used in situations where a long term HTTP connection is used to
+ send periodic status updates as individual chunks. Previously a
+ given chunk would not be forwarded to the client process until the
+ size for the next chunk had been read which rendered the module
+ difficult to use for the scenario described. </p>
+ <p>Bernard Duggan</p>
+ <p>Own Id: OTP-8351</p>
+ </item>
+
+ <item>
+ <p>Include the inets test suite in the release of the
+ application. </p>
+ <p>Own Id: OTP-8349</p>
+ </item>
+
+ <item>
+ <p>[httpc] - It is now possible to configure the client to
+ deliver an async reply to more receivers then the calling
+ process. </p>
+ <p>See the
+ <seealso marker="httpc#request2">receiver</seealso>
+ option for more info, </p>
+ <p>Own Id: OTP-8106</p>
+ </item>
+
+ <item>
+ <p>[httpd] - Methods "PUT" and "DELETE" now allowed. </p>
+ <p>Own Id: OTP-8103</p>
+ </item>
+
+ <item>
+ <p>[httpc] Several more or less critical fixes:</p>
+ <p>
+ <list type="bulleted">
+ <item>
+ <p>Initial call between the httpc manager and request
+ handler was synchronous. </p>
+ <p>When the manager starts a new request handler,
+ this is no longer a synchronous operation. Previously,
+ the new request handler made the connection to the
+ server and issuing of the first request (the reason
+ for starting it) in the gen_server init function.
+ If the connection for some reason "took some time",
+ the manager hanged, leaving all other activities by
+ that manager also hanging. </p>
+ </item>
+<!--
+ <item>
+ <p>Copying of data between processes</p>
+ <p>TBD</p>
+ </item>
+ <item>
+ <p>Reading of requests</p>
+ <p>TBD</p>
+ </item>
+-->
+ </list>
+ </p>
+ <p>As a side-effect of these changes, some modules was also
+ renamed, and a new api module,
+ <seealso marker="httpc">httpc</seealso>, has been introduced
+ (the old module <c>http</c> is <em>not</em> removed, but is
+ now just wrapper for <c>httpc</c>). </p>
+ <p>Own Id: OTP-8016</p>
+ <p>*** POTENTIAL INCOMPATIBILITY ***</p>
+ </item>
+ </list>
+ </section>
+
+ <section><title>Fixed Bugs and Malfunctions</title>
+
+<!--
+ <p>-</p>
+-->
+
+ <list>
+ <item>
+ <p>[httpd] The server did not fully support the documented module
+ callback api. Specifically, the load function should be able to
+ return the atom <c>ok</c>, but this was not accepted. </p>
+ <p>Own Id: OTP-8359</p>
+ </item>
+
+ <item>
+ <p>Fixing various documentation-related bugs (bad quotes).</p>
+ <p>Own Id: OTP-8327</p>
+ </item>
+
+ <item>
+ <p>Fixing minor Dialyzer and copyright problem(s). </p>
+ <p>Own Id: OTP-8315</p>
+ </item>
+
+ <item>
+ <p>[httpc] - Added basic sanity check of option value
+ combinations.</p>
+ <p>Own Id: OTP-8056</p>
+ </item>
+ </list>
+ </section>
+
+ </section> <!-- 5.3 -->
+
+
<section><title>Inets 5.2</title>
<section><title>Improvements and New Features</title>
@@ -139,7 +559,7 @@
<p>Timeout out requests are retried. </p>
</item>
</list>
- <p>Jean-S�bastien P�dron</p>
+ <p>Jean-S&#233;bastien P&#233;dron</p>
<p>Own Id: OTP-8248</p>
</item>
@@ -214,7 +634,7 @@
request, when the client connects to the server. Default
value is that of the <c>timeout</c> option. </p>
<p>See the
- <seealso marker="http#request2">request/4,5</seealso>
+ <seealso marker="httpc#request2">request/4,5</seealso>
function for more info. </p>
<p>Own Id: OTP-7298</p>
<!-- <p>Aux Id: seq11086</p> -->
@@ -321,7 +741,7 @@
the client connects to the server. </p>
<p>As a side-effect of this, the option <c>ipv6</c> has been
removed and replaced by the <c>ipfamily</c> option. </p>
- <p>See <seealso marker="http#set_options">http:set_options/1,2</seealso>
+ <p>See <seealso marker="httpc#set_options">http:set_options/1,2</seealso>
for more info. </p>
<p>*** POTENTIAL INCOMPATIBILITY ***</p>
<p>Own Id: OTP-8004</p>
diff --git a/lib/inets/doc/src/notes_history.xml b/lib/inets/doc/src/notes_history.xml
index 53375c9aa7..6480bad758 100644
--- a/lib/inets/doc/src/notes_history.xml
+++ b/lib/inets/doc/src/notes_history.xml
@@ -4,7 +4,7 @@
<chapter>
<header>
<copyright>
- <year>2004</year><year>2009</year>
+ <year>2004</year><year>2010</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
@@ -13,12 +13,12 @@
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>Inets Release Notes History</title>
@@ -385,8 +385,7 @@
</item>
<item>
<p>[httpc, httpd] - In some cases if a body contained the
- sequence "\\r\
- 0" and was chunked encoded this sequence
+ sequence "\r\n0" and was chunked encoded this sequence
was incorrectly interpreted as the last chunk.</p>
<p>Own Id: OTP-6264 Aux Id: OTP-6005 </p>
</item>
@@ -968,8 +967,7 @@
design was changed to use gen_tcp active once semantics.
The API is not effected except for the function
ftp:quote/2 which now returns a list of strings (ftp
- result lines) where the line endings "\\r\
- " has been
+ result lines) where the line endings "\r\n" has been
removed. This was the original intention for the return
value of ftp:quote/2 but it was non trivial to make a
good such solution with the old design and a compromise
@@ -1055,13 +1053,11 @@
<p>Own Id: OTP-5551 Aux Id: seq9854 </p>
</item>
<item>
- <p>The HTTP server now handles "GET /\\r\
- \\r\
- " as well as
- "GET / \\r\
- \\r\
- ". According to the RFC the whitespace is
- not needed.</p>
+ <p>The HTTP server now handles
+ "GET /\r\n\r\n"
+ as well as
+ "GET / \r\n\r\n".
+ According to the RFC the whitespace is not needed.</p>
<p>Own Id: OTP-5552 Aux Id: seq8426 </p>
</item>
</list>
diff --git a/lib/inets/doc/src/ref_man.xml b/lib/inets/doc/src/ref_man.xml
index 7ec2c041c8..45d5dfcd0e 100644
--- a/lib/inets/doc/src/ref_man.xml
+++ b/lib/inets/doc/src/ref_man.xml
@@ -4,7 +4,7 @@
<application xmlns:xi="http://www.w3.org/2001/XInclude">
<header>
<copyright>
- <year>1997</year><year>2009</year>
+ <year>1997</year><year>2010</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
@@ -13,12 +13,12 @@
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>Inets Reference Manual</title>
@@ -36,7 +36,7 @@
<xi:include href="inets.xml"/>
<xi:include href="ftp.xml"/>
<xi:include href="tftp.xml"/>
- <xi:include href="http.xml"/>
+ <xi:include href="httpc.xml"/>
<xi:include href="httpd.xml"/>
<xi:include href="httpd_conf.xml"/>
<xi:include href="httpd_socket.xml"/>
diff --git a/lib/inets/src/ftp/Makefile b/lib/inets/src/ftp/Makefile
index 70d51115e6..0c15277a18 100644
--- a/lib/inets/src/ftp/Makefile
+++ b/lib/inets/src/ftp/Makefile
@@ -1,19 +1,19 @@
#
# %CopyrightBegin%
-#
-# Copyright Ericsson AB 2005-2009. All Rights Reserved.
-#
+#
+# Copyright Ericsson AB 2005-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%
#
#
@@ -32,7 +32,8 @@ VSN = $(INETS_VSN)
# ----------------------------------------------------
# Release directory specification
# ----------------------------------------------------
-RELSYSDIR = $(RELEASE_PATH)/lib/inets-$(VSN)
+RELSYSDIR = $(RELEASE_PATH)/lib/$(APPLICATION)-$(VSN)
+
# ----------------------------------------------------
# Target Specs
@@ -49,15 +50,17 @@ ERL_FILES = $(MODULES:%=%.erl)
TARGET_FILES= $(MODULES:%=$(EBIN)/%.$(EMULATOR))
+
# ----------------------------------------------------
# INETS FLAGS
# ----------------------------------------------------
-INETS_FLAGS = -D'SERVER_SOFTWARE="inets/$(VSN)"'
+INETS_FLAGS = -D'SERVER_SOFTWARE="$(APPLICATION)/$(VSN)"'
ifeq ($(FTP_DEBUG),true)
INETS_FLAGS += -Dftp_debug
endif
+
# ----------------------------------------------------
# FLAGS
# ----------------------------------------------------
@@ -94,6 +97,7 @@ release_spec: opt
release_docs_spec:
info:
+ @echo "APPLICATION = $(APPLICATION)"
@echo "INETS_DEBUG = $(INETS_DEBUG)"
@echo "INETS_FLAGS = $(INETS_FLAGS)"
@echo "ERL_COMPILE_FLAGS = $(ERL_COMPILE_FLAGS)"
diff --git a/lib/inets/src/http_client/Makefile b/lib/inets/src/http_client/Makefile
index 23170f439f..184f45f589 100644
--- a/lib/inets/src/http_client/Makefile
+++ b/lib/inets/src/http_client/Makefile
@@ -1,19 +1,19 @@
#
# %CopyrightBegin%
-#
-# Copyright Ericsson AB 2005-2009. All Rights Reserved.
-#
+#
+# Copyright Ericsson AB 2005-2011. All Rights Reserved.
+#
# The contents of this file are subject to the Erlang Public License,
# Version 1.1, (the "License"); you may not use this file except in
# compliance with the License. You should have received a copy of the
# Erlang Public License along with this software. If not, it can be
# retrieved online at http://www.erlang.org/.
-#
+#
# Software distributed under the License is distributed on an "AS IS"
# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
# the License for the specific language governing rights and limitations
# under the License.
-#
+#
# %CopyrightEnd%
#
#
@@ -22,6 +22,7 @@ include $(ERL_TOP)/make/target.mk
EBIN = ../../ebin
include $(ERL_TOP)/make/$(TARGET)/otp.mk
+
# ----------------------------------------------------
# Application version
# ----------------------------------------------------
@@ -29,25 +30,27 @@ include ../../vsn.mk
VSN = $(INETS_VSN)
+
# ----------------------------------------------------
# Release directory specification
# ----------------------------------------------------
-RELSYSDIR = $(RELEASE_PATH)/lib/inets-$(VSN)
+RELSYSDIR = $(RELEASE_PATH)/lib/$(APPLICATION)-$(VSN)
+
# ----------------------------------------------------
# Target Specs
# ----------------------------------------------------
MODULES = \
http \
- http_cookie \
+ httpc \
+ httpc_cookie \
httpc_handler \
httpc_manager \
httpc_sup \
httpc_handler_sup \
httpc_profile_sup \
httpc_response \
- httpc_request \
- http_uri \
+ httpc_request
HRL_FILES = httpc_internal.hrl
@@ -55,20 +58,24 @@ ERL_FILES = $(MODULES:%=%.erl)
TARGET_FILES= $(MODULES:%=$(EBIN)/%.$(EMULATOR))
+
# ----------------------------------------------------
# INETS FLAGS
# ----------------------------------------------------
-INETS_FLAGS = -D'SERVER_SOFTWARE="inets/$(VSN)"' \
+INETS_FLAGS = -D'SERVER_SOFTWARE="$(APPLICATION)/$(VSN)"'
+
# ----------------------------------------------------
# FLAGS
# ----------------------------------------------------
INETS_ERL_FLAGS += -I ../http_lib -I ../inets_app -pa ../../ebin
-ERL_COMPILE_FLAGS += $(INETS_ERL_FLAGS)\
+ERL_COMPILE_FLAGS += $(INETS_ERL_FLAGS) \
$(INETS_FLAGS) \
+'{parse_transform,sys_pre_attributes}' \
+'{attribute,insert,app_vsn,$(APP_VSN)}'
+
+
# ----------------------------------------------------
# Targets
# ----------------------------------------------------
@@ -94,6 +101,7 @@ release_spec: opt
release_docs_spec:
info:
+ @echo "APPLICATION = $(APPLICATION)"
@echo "INETS_DEBUG = $(INETS_DEBUG)"
@echo "INETS_FLAGS = $(INETS_FLAGS)"
@echo "ERL_COMPILE_FLAGS = $(ERL_COMPILE_FLAGS)"
diff --git a/lib/inets/src/http_client/http.erl b/lib/inets/src/http_client/http.erl
index ce5d7723f0..7e1e90b50e 100644
--- a/lib/inets/src/http_client/http.erl
+++ b/lib/inets/src/http_client/http.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2002-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 2002-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%
%%
%%
@@ -24,7 +24,6 @@
%%% - RFC 2818 HTTP Over TLS
-module(http).
--behaviour(inets_service).
%% API
-export([request/1, request/2, request/4, request/5,
@@ -35,15 +34,6 @@
cookie_header/2, stream_next/1,
default_profile/0]).
-%% Behavior callbacks
--export([start_standalone/1, start_service/1,
- stop_service/1, services/0, service_info/1]).
-
--include("http_internal.hrl").
--include("httpc_internal.hrl").
-
--define(DEFAULT_PROFILE, default).
-
%%%=========================================================================
%%% API
@@ -51,751 +41,75 @@
%%--------------------------------------------------------------------------
%% request(Url [, Profile]) ->
-%% {ok, {StatusLine, Headers, Body}} | {error,Reason}
-%%
-%% Url - string()
-%% Description: Calls request/4 with default values.
+%% request(Method, Request, HTTPOptions, Options [, Profile])
%%--------------------------------------------------------------------------
-request(Url) ->
- request(Url, default_profile()).
-
-request(Url, Profile) ->
- request(get, {Url, []}, [], [], Profile).
-
-
-%%--------------------------------------------------------------------------
-%% request(Method, Request, HTTPOptions, Options [, Profile]) ->
-%% {ok, {StatusLine, Headers, Body}} | {ok, {Status, Body}} |
-%% {ok, RequestId} | {error,Reason} | {ok, {saved_as, FilePath}
-%%
-%% Method - atom() = head | get | put | post | trace | options| delete
-%% Request - {Url, Headers} | {Url, Headers, ContentType, Body}
-%% Url - string()
-%% HTTPOptions - [HttpOption]
-%% HTTPOption - {timeout, Time} | {connect_timeout, Time} |
-%% {ssl, SSLOptions} | {proxy_auth, {User, Password}}
-%% Ssloptions = [SSLOption]
-%% SSLOption = {verify, code()} | {depth, depth()} | {certfile, path()} |
-%% {keyfile, path()} | {password, string()} | {cacertfile, path()} |
-%% {ciphers, string()}
-%% Options - [Option]
-%% Option - {sync, Boolean} | {body_format, BodyFormat} |
-%% {full_result, Boolean} | {stream, To} |
-%% {headers_as_is, Boolean}
-%% StatusLine = {HTTPVersion, StatusCode, ReasonPhrase}</v>
-%% HTTPVersion = string()
-%% StatusCode = integer()
-%% ReasonPhrase = string()
-%% Headers = [Header]
-%% Header = {Field, Value}
-%% Field = string()
-%% Value = string()
-%% Body = string() | binary() - HTLM-code
-%%
-%% Description: Sends a HTTP-request. The function can be both
-%% syncronus and asynchronous in the later case the function will
-%% return {ok, RequestId} and later on a message will be sent to the
-%% calling process on the format {http, {RequestId, {StatusLine,
-%% Headers, Body}}} or {http, {RequestId, {error, Reason}}}
-%%--------------------------------------------------------------------------
+request(Url) -> httpc:request(Url).
+request(Url, Profile) -> httpc:request(Url, Profile).
request(Method, Request, HttpOptions, Options) ->
- request(Method, Request, HttpOptions, Options, default_profile()).
+ httpc:request(Method, Request, HttpOptions, Options).
+request(Method, Request, HttpOptions, Options, Profile) ->
+ httpc:request(Method, Request, HttpOptions, Options, Profile).
-request(Method, {Url, Headers}, HTTPOptions, Options, Profile)
- when (Method =:= options) orelse
- (Method =:= get) orelse
- (Method =:= head) orelse
- (Method =:= delete) orelse
- (Method =:= trace) ->
- case http_uri:parse(Url) of
- {error, Reason} ->
- {error, Reason};
- ParsedUrl ->
- handle_request(Method, Url, ParsedUrl, Headers, [], [],
- HTTPOptions, Options, Profile)
- end;
-
-request(Method, {Url,Headers,ContentType,Body}, HTTPOptions, Options, Profile)
- when (Method =:= post) orelse (Method =:= put) ->
- case http_uri:parse(Url) of
- {error, Reason} ->
- {error, Reason};
- ParsedUrl ->
- handle_request(Method, Url,
- ParsedUrl, Headers, ContentType, Body,
- HTTPOptions, Options, Profile)
- end.
%%--------------------------------------------------------------------------
-%% request(RequestId) -> ok
-%% RequestId - As returned by request/4
-%%
-%% Description: Cancels a HTTP-request.
+%% cancel_request(RequestId [, Profile])
%%-------------------------------------------------------------------------
-cancel_request(RequestId) ->
- cancel_request(RequestId, default_profile()).
+cancel_request(RequestId) ->
+ httpc:cancel_request(RequestId).
cancel_request(RequestId, Profile) ->
- ok = httpc_manager:cancel_request(RequestId, profile_name(Profile)),
- receive
- %% If the request was allready fullfilled throw away the
- %% answer as the request has been canceled.
- {http, {RequestId, _}} ->
- ok
- after 0 ->
- ok
- end.
-
-
-set_option(Key, Value) ->
- set_option(Key, Value, default_profile()).
-
-set_option(Key, Value, Profile) ->
- set_options([{Key, Value}], Profile).
+ httpc:cancel_request(RequestId, Profile).
%%--------------------------------------------------------------------------
-%% set_options(Options [, Profile]) -> ok | {error, Reason}
-%% Options - [Option]
-%% Profile - atom()
-%% Option - {proxy, {Proxy, NoProxy}} | {max_sessions, MaxSessions} |
-%% {max_pipeline_length, MaxPipeline} |
-%% {pipeline_timeout, PipelineTimeout} | {cookies, CookieMode} |
-%% {ipfamily, IpFamily}
-%% Proxy - {Host, Port}
-%% NoProxy - [Domain | HostName | IPAddress]
-%% MaxSessions, MaxPipeline, PipelineTimeout = integer()
-%% CookieMode - enabled | disabled | verify
-%% IpFamily - inet | inet6 | inet6fb4
-%% Description: Informs the httpc_manager of the new settings.
+%% set_options(Options [, Profile])
+%% set_option(Key, Value [, Profile])
%%-------------------------------------------------------------------------
+
set_options(Options) ->
- set_options(Options, default_profile()).
+ httpc:set_options(Options).
set_options(Options, Profile) ->
- case validate_options(Options) of
- {ok, Opts} ->
- try httpc_manager:set_options(Opts, profile_name(Profile)) of
- Result ->
- Result
- catch
- exit:{noproc, _} ->
- {error, inets_not_started}
- end;
- {error, Reason} ->
- {error, Reason}
- end.
+ httpc:set_options(Options, Profile).
+
+set_option(Key, Value) ->
+ httpc:set_option(Key, Value).
+set_option(Key, Value, Profile) ->
+ httpc:set_option(Key, Value, Profile).
%%--------------------------------------------------------------------------
-%% verify_cookies(SetCookieHeaders, Url [, Profile]) -> ok | {error, reason}
-%%
-%%
-%% Description: Store the cookies from <SetCookieHeaders>
-%% in the cookie database
-%% for the profile <Profile>. This function shall be used when the option
-%% cookie is set to verify.
+%% verify_cookies(SetCookieHeaders, Url [, Profile])
%%-------------------------------------------------------------------------
-verify_cookies(SetCookieHeaders, Url) ->
- verify_cookies(SetCookieHeaders, Url, default_profile()).
+verify_cookies(SetCookieHeaders, Url) ->
+ httpc:store_cookies(SetCookieHeaders, Url).
verify_cookies(SetCookieHeaders, Url, Profile) ->
- {_, _, Host, Port, Path, _} = http_uri:parse(Url),
- ProfileName = profile_name(Profile),
- Cookies = http_cookie:cookies(SetCookieHeaders, Path, Host),
- try httpc_manager:store_cookies(Cookies, {Host, Port}, ProfileName) of
- _ ->
- ok
- catch
- exit:{noproc, _} ->
- {error, {not_started, Profile}}
- end.
+ httpc:store_cookies(SetCookieHeaders, Url, Profile).
+
%%--------------------------------------------------------------------------
-%% cookie_header(Url [, Profile]) -> Header | {error, Reason}
-%%
-%% Description: Returns the cookie header that would be sent when making
-%% a request to <Url>.
+%% cookie_header(Url [, Profile])
%%-------------------------------------------------------------------------
-cookie_header(Url) ->
- cookie_header(Url, default_profile()).
+cookie_header(Url) ->
+ httpc:cookie_header(Url).
cookie_header(Url, Profile) ->
- try httpc_manager:cookies(Url, profile_name(Profile)) of
- Header ->
- Header
- catch
- exit:{noproc, _} ->
- {error, {not_started, Profile}}
- end.
-
-
-stream_next(Pid) ->
- httpc_handler:stream_next(Pid).
-
-%%%========================================================================
-%%% Behavior callbacks
-%%%========================================================================
-start_standalone(PropList) ->
- case proplists:get_value(profile, PropList) of
- undefined ->
- {error, no_profile};
- Profile ->
- Dir =
- proplists:get_value(data_dir, PropList, only_session_cookies),
- httpc_manager:start_link({Profile, Dir}, stand_alone)
- end.
-
-start_service(Config) ->
- httpc_profile_sup:start_child(Config).
-
-stop_service(Profile) when is_atom(Profile) ->
- httpc_profile_sup:stop_child(Profile);
-stop_service(Pid) when is_pid(Pid) ->
- case service_info(Pid) of
- {ok, [{profile, Profile}]} ->
- stop_service(Profile);
- Error ->
- Error
- end.
-
-services() ->
- [{httpc, Pid} || {_, Pid, _, _} <-
- supervisor:which_children(httpc_profile_sup)].
-service_info(Pid) ->
- try [{ChildName, ChildPid} ||
- {ChildName, ChildPid, _, _} <-
- supervisor:which_children(httpc_profile_sup)] of
- Children ->
- child_name2info(child_name(Pid, Children))
- catch
- exit:{noproc, _} ->
- {error, service_not_available}
- end.
-
-
-%%%========================================================================
-%%% Internal functions
-%%%========================================================================
-handle_request(Method, Url,
- {Scheme, UserInfo, Host, Port, Path, Query},
- Headers, ContentType, Body,
- HTTPOptions0, Options, Profile) ->
-
- HTTPOptions = http_options(HTTPOptions0),
- Sync = proplists:get_value(sync, Options, true),
- NewHeaders = lists:map(fun({Key, Val}) ->
- {http_util:to_lower(Key), Val} end,
- Headers),
- Stream = proplists:get_value(stream, Options, none),
- case {Sync, Stream} of
- {true, self} ->
- {error, streaming_error};
- _ ->
- RecordHeaders = header_record(NewHeaders,
- #http_request_h{},
- Host,
- HTTPOptions#http_options.version),
- Request = #request{from = self(),
- scheme = Scheme,
- address = {Host,Port},
- path = Path,
- pquery = Query,
- method = Method,
- headers = RecordHeaders,
- content = {ContentType,Body},
- settings = HTTPOptions,
- abs_uri = Url,
- userinfo = UserInfo,
- stream = Stream,
- headers_as_is = headers_as_is(Headers, Options)},
- try httpc_manager:request(Request, profile_name(Profile)) of
- {ok, RequestId} ->
- handle_answer(RequestId, Sync, Options);
- {error, Reason} ->
- {error, Reason}
- catch
- error:{noproc, _} ->
- {error, {not_started, Profile}}
- end
- end.
-
-
-handle_answer(RequestId, false, _) ->
- {ok, RequestId};
-handle_answer(RequestId, true, Options) ->
- receive
- {http, {RequestId, saved_to_file}} ->
- {ok, saved_to_file};
- {http, {RequestId, Result = {_,_,_}}} ->
- return_answer(Options, Result);
- {http, {RequestId, {error, Reason}}} ->
- {error, Reason}
- end.
-
-return_answer(Options, {{"HTTP/0.9",_,_}, _, BinBody}) ->
- Body = format_body(BinBody, Options),
- {ok, Body};
-
-return_answer(Options, {StatusLine, Headers, BinBody}) ->
-
- Body = format_body(BinBody, Options),
-
- case proplists:get_value(full_result, Options, true) of
- true ->
- {ok, {StatusLine, Headers, Body}};
- false ->
- {_, Status, _} = StatusLine,
- {ok, {Status, Body}}
- end.
-
-format_body(BinBody, Options) ->
- case proplists:get_value(body_format, Options, string) of
- string ->
- binary_to_list(BinBody);
- _ ->
- BinBody
- end.
+ httpc:cookie_header(Url, Profile).
-%% This options is a workaround for http servers that do not follow the
-%% http standard and have case sensative header parsing. Should only be
-%% used if there is no other way to communicate with the server or for
-%% testing purpose.
-headers_as_is(Headers, Options) ->
- case proplists:get_value(headers_as_is, Options, false) of
- false ->
- [];
- true ->
- Headers
- end.
+%%--------------------------------------------------------------------------
+%% stream_next(Pid)
+%%-------------------------------------------------------------------------
-http_options(HttpOptions) ->
- HttpOptionsDefault = http_options_default(),
- http_options(HttpOptionsDefault, HttpOptions, #http_options{}).
-
-http_options([], [], Acc) ->
- Acc;
-http_options([], HttpOptions, Acc) ->
- Fun = fun(BadOption) ->
- Report = io_lib:format("Invalid option ~p ignored ~n",
- [BadOption]),
- error_logger:info_report(Report)
- end,
- lists:foreach(Fun, HttpOptions),
- Acc;
-http_options([{Tag, Default, Idx, Post} | Defaults], HttpOptions, Acc) ->
- case lists:keysearch(Tag, 1, HttpOptions) of
- {value, {Tag, Val0}} ->
- case Post(Val0) of
- {ok, Val} ->
- Acc2 = setelement(Idx, Acc, Val),
- HttpOptions2 = lists:keydelete(Tag, 1, HttpOptions),
- http_options(Defaults, HttpOptions2, Acc2);
- error ->
- Report = io_lib:format("Invalid option ~p:~p ignored ~n",
- [Tag, Val0]),
- error_logger:info_report(Report),
- HttpOptions2 = lists:keydelete(Tag, 1, HttpOptions),
- http_options(Defaults, HttpOptions2, Acc)
- end;
- false ->
- DefaultVal =
- case Default of
- {value, Val} ->
- Val;
- {field, DefaultIdx} ->
- element(DefaultIdx, Acc)
- end,
- Acc2 = setelement(Idx, Acc, DefaultVal),
- http_options(Defaults, HttpOptions, Acc2)
- end.
-
-http_options_default() ->
- VersionPost =
- fun(Value) when is_atom(Value) ->
- {ok, http_util:to_upper(atom_to_list(Value))};
- (Value) when is_list(Value) ->
- {ok, http_util:to_upper(Value)};
- (_) ->
- error
- end,
- TimeoutPost = fun(Value) when is_integer(Value) andalso (Value >= 0) ->
- {ok, Value};
- (infinity = Value) ->
- {ok, Value};
- (_) ->
- error
- end,
- AutoRedirectPost = fun(Value) when (Value =:= true) orelse
- (Value =:= false) ->
- {ok, Value};
- (_) ->
- error
- end,
- SslPost = fun(Value) when is_list(Value) ->
- {ok, Value};
- (_) ->
- error
- end,
- ProxyAuthPost = fun({User, Passwd} = Value) when is_list(User) andalso
- is_list(Passwd) ->
- {ok, Value};
- (_) ->
- error
- end,
- RelaxedPost = fun(Value) when (Value =:= true) orelse
- (Value =:= false) ->
- {ok, Value};
- (_) ->
- error
- end,
- ConnTimeoutPost =
- fun(Value) when is_integer(Value) andalso (Value >= 0) ->
- {ok, Value};
- (infinity = Value) ->
- {ok, Value};
- (_) ->
- error
- end,
- [
- {version, {value, "HTTP/1.1"}, #http_options.version, VersionPost},
- {timeout, {value, ?HTTP_REQUEST_TIMEOUT}, #http_options.timeout, TimeoutPost},
- {autoredirect, {value, true}, #http_options.autoredirect, AutoRedirectPost},
- {ssl, {value, []}, #http_options.ssl, SslPost},
- {proxy_auth, {value, undefined}, #http_options.proxy_auth, ProxyAuthPost},
- {relaxed, {value, false}, #http_options.relaxed, RelaxedPost},
- %% this field has to be *after* the timeout field (as that field is used for the default value)
- {connect_timeout, {field, #http_options.timeout}, #http_options.connect_timeout, ConnTimeoutPost}
- ].
-
-validate_options(Options) ->
- (catch validate_options(Options, [])).
-
-validate_options([], ValidateOptions) ->
- {ok, lists:reverse(ValidateOptions)};
-
-validate_options([{proxy, Proxy} = Opt| Tail], Acc) ->
- validate_proxy(Proxy),
- validate_options(Tail, [Opt | Acc]);
-
-validate_options([{max_sessions, Value} = Opt| Tail], Acc) ->
- validate_max_sessions(Value),
- validate_options(Tail, [Opt | Acc]);
-
-validate_options([{keep_alive_timeout, Value} = Opt| Tail], Acc) ->
- validate_keep_alive_timeout(Value),
- validate_options(Tail, [Opt | Acc]);
-
-validate_options([{max_keep_alive_length, Value} = Opt| Tail], Acc) ->
- validate_max_keep_alive_length(Value),
- validate_options(Tail, [Opt | Acc]);
-
-validate_options([{pipeline_timeout, Value} = Opt| Tail], Acc) ->
- validate_pipeline_timeout(Value),
- validate_options(Tail, [Opt | Acc]);
-
-validate_options([{max_pipeline_length, Value} = Opt| Tail], Acc) ->
- validate_max_pipeline_length(Value),
- validate_options(Tail, [Opt | Acc]);
-
-validate_options([{cookies, Value} = Opt| Tail], Acc) ->
- validate_cookies(Value),
- validate_options(Tail, [Opt | Acc]);
-
-validate_options([{ipfamily, Value} = Opt| Tail], Acc) ->
- validate_ipfamily(Value),
- validate_options(Tail, [Opt | Acc]);
-
-%% For backward compatibillity
-validate_options([{ipv6, Value}| Tail], Acc) ->
- NewValue = validate_ipv6(Value),
- Opt = {ipfamily, NewValue},
- validate_options(Tail, [Opt | Acc]);
-
-validate_options([{ip, Value} = Opt| Tail], Acc) ->
- validate_ip(Value),
- validate_options(Tail, [Opt | Acc]);
-
-validate_options([{port, Value} = Opt| Tail], Acc) ->
- validate_port(Value),
- validate_options(Tail, [Opt | Acc]);
-
-validate_options([{verbose, Value} = Opt| Tail], Acc) ->
- validate_verbose(Value),
- validate_options(Tail, [Opt | Acc]);
-
-validate_options([{_, _} = Opt| _], _Acc) ->
- {error, {not_an_option, Opt}}.
-
-
-validate_proxy({{ProxyHost, ProxyPort}, NoProxy} = Proxy)
- when is_list(ProxyHost) andalso
- is_integer(ProxyPort) andalso
- is_list(NoProxy) ->
- Proxy;
-validate_proxy(BadProxy) ->
- bad_option(proxy, BadProxy).
-
-validate_max_sessions(Value) when is_integer(Value) andalso (Value >= 0) ->
- Value;
-validate_max_sessions(BadValue) ->
- bad_option(max_sessions, BadValue).
-
-validate_keep_alive_timeout(Value) when is_integer(Value) andalso (Value >= 0) ->
- Value;
-validate_keep_alive_timeout(infinity = Value) ->
- Value;
-validate_keep_alive_timeout(BadValue) ->
- bad_option(keep_alive_timeout, BadValue).
-
-validate_max_keep_alive_length(Value) when is_integer(Value) andalso (Value >= 0) ->
- Value;
-validate_max_keep_alive_length(BadValue) ->
- bad_option(max_keep_alive_length, BadValue).
-
-validate_pipeline_timeout(Value) when is_integer(Value) ->
- Value;
-validate_pipeline_timeout(infinity = Value) ->
- Value;
-validate_pipeline_timeout(BadValue) ->
- bad_option(pipeline_timeout, BadValue).
-
-validate_max_pipeline_length(Value) when is_integer(Value) ->
- Value;
-validate_max_pipeline_length(BadValue) ->
- bad_option(max_pipeline_length, BadValue).
-
-validate_cookies(Value)
- when ((Value =:= enabled) orelse
- (Value =:= disabled) orelse
- (Value =:= verify)) ->
- Value;
-validate_cookies(BadValue) ->
- bad_option(cookies, BadValue).
-
-validate_ipv6(Value) when (Value =:= enabled) orelse (Value =:= disabled) ->
- case Value of
- enabled ->
- inet6fb4;
- disabled ->
- inet
- end;
-validate_ipv6(BadValue) ->
- bad_option(ipv6, BadValue).
-
-validate_ipfamily(Value)
- when (Value =:= inet) orelse (Value =:= inet6) orelse (Value =:= inet6fb4) ->
- Value;
-validate_ipfamily(BadValue) ->
- bad_option(ipfamily, BadValue).
-
-validate_ip(Value)
- when is_tuple(Value) andalso ((size(Value) =:= 4) orelse (size(Value) =:= 8)) ->
- Value;
-validate_ip(BadValue) ->
- bad_option(ip, BadValue).
-
-validate_port(Value) when is_integer(Value) ->
- Value;
-validate_port(BadValue) ->
- bad_option(port, BadValue).
-
-validate_verbose(Value)
- when ((Value =:= false) orelse
- (Value =:= verbose) orelse
- (Value =:= debug) orelse
- (Value =:= trace)) ->
- ok;
-validate_verbose(BadValue) ->
- bad_option(verbose, BadValue).
-
-bad_option(Option, BadValue) ->
- throw({error, {bad_option, Option, BadValue}}).
-
-
-
-header_record([], RequestHeaders, Host, Version) ->
- validate_headers(RequestHeaders, Host, Version);
-header_record([{"cache-control", Val} | Rest], RequestHeaders, Host, Version) ->
- header_record(Rest, RequestHeaders#http_request_h{'cache-control' = Val},
- Host, Version);
-header_record([{"connection", Val} | Rest], RequestHeaders, Host, Version) ->
- header_record(Rest, RequestHeaders#http_request_h{connection = Val}, Host,
- Version);
-header_record([{"date", Val} | Rest], RequestHeaders, Host, Version) ->
- header_record(Rest, RequestHeaders#http_request_h{date = Val}, Host,
- Version);
-header_record([{"pragma", Val} | Rest], RequestHeaders, Host, Version) ->
- header_record(Rest, RequestHeaders#http_request_h{pragma = Val}, Host,
- Version);
-header_record([{"trailer", Val} | Rest], RequestHeaders, Host, Version) ->
- header_record(Rest, RequestHeaders#http_request_h{trailer = Val}, Host,
- Version);
-header_record([{"transfer-encoding", Val} | Rest], RequestHeaders, Host,
- Version) ->
- header_record(Rest,
- RequestHeaders#http_request_h{'transfer-encoding' = Val},
- Host, Version);
-header_record([{"upgrade", Val} | Rest], RequestHeaders, Host, Version) ->
- header_record(Rest, RequestHeaders#http_request_h{upgrade = Val}, Host,
- Version);
-header_record([{"via", Val} | Rest], RequestHeaders, Host, Version) ->
- header_record(Rest, RequestHeaders#http_request_h{via = Val}, Host,
- Version);
-header_record([{"warning", Val} | Rest], RequestHeaders, Host, Version) ->
- header_record(Rest, RequestHeaders#http_request_h{warning = Val}, Host,
- Version);
-header_record([{"accept", Val} | Rest], RequestHeaders, Host, Version) ->
- header_record(Rest, RequestHeaders#http_request_h{accept = Val}, Host,
- Version);
-header_record([{"accept-charset", Val} | Rest], RequestHeaders, Host, Version) ->
- header_record(Rest, RequestHeaders#http_request_h{'accept-charset' = Val},
- Host, Version);
-header_record([{"accept-encoding", Val} | Rest], RequestHeaders, Host,
- Version) ->
- header_record(Rest, RequestHeaders#http_request_h{'accept-encoding' = Val},
- Host, Version);
-header_record([{"accept-language", Val} | Rest], RequestHeaders, Host,
- Version) ->
- header_record(Rest, RequestHeaders#http_request_h{'accept-language' = Val},
- Host, Version);
-header_record([{"authorization", Val} | Rest], RequestHeaders, Host, Version) ->
- header_record(Rest, RequestHeaders#http_request_h{authorization = Val},
- Host, Version);
-header_record([{"expect", Val} | Rest], RequestHeaders, Host, Version) ->
- header_record(Rest, RequestHeaders#http_request_h{expect = Val}, Host,
- Version);
-header_record([{"from", Val} | Rest], RequestHeaders, Host, Version) ->
- header_record(Rest, RequestHeaders#http_request_h{from = Val}, Host,
- Version);
-header_record([{"host", Val} | Rest], RequestHeaders, Host, Version) ->
- header_record(Rest, RequestHeaders#http_request_h{host = Val}, Host,
- Version);
-header_record([{"if-match", Val} | Rest], RequestHeaders, Host, Version) ->
- header_record(Rest, RequestHeaders#http_request_h{'if-match' = Val},
- Host, Version);
-header_record([{"if-modified-since", Val} | Rest], RequestHeaders, Host,
- Version) ->
- header_record(Rest,
- RequestHeaders#http_request_h{'if-modified-since' = Val},
- Host, Version);
-header_record([{"if-none-match", Val} | Rest], RequestHeaders, Host, Version) ->
- header_record(Rest, RequestHeaders#http_request_h{'if-none-match' = Val},
- Host, Version);
-header_record([{"if-range", Val} | Rest], RequestHeaders, Host, Version) ->
- header_record(Rest, RequestHeaders#http_request_h{'if-range' = Val},
- Host, Version);
-
-header_record([{"if-unmodified-since", Val} | Rest], RequestHeaders, Host,
- Version) ->
- header_record(Rest, RequestHeaders#http_request_h{'if-unmodified-since'
- = Val}, Host, Version);
-header_record([{"max-forwards", Val} | Rest], RequestHeaders, Host, Version) ->
- header_record(Rest, RequestHeaders#http_request_h{'max-forwards' = Val},
- Host, Version);
-header_record([{"proxy-authorization", Val} | Rest], RequestHeaders, Host,
- Version) ->
- header_record(Rest, RequestHeaders#http_request_h{'proxy-authorization'
- = Val}, Host, Version);
-header_record([{"range", Val} | Rest], RequestHeaders, Host, Version) ->
- header_record(Rest, RequestHeaders#http_request_h{range = Val}, Host,
- Version);
-header_record([{"referer", Val} | Rest], RequestHeaders, Host, Version) ->
- header_record(Rest, RequestHeaders#http_request_h{referer = Val}, Host,
- Version);
-header_record([{"te", Val} | Rest], RequestHeaders, Host, Version) ->
- header_record(Rest, RequestHeaders#http_request_h{te = Val}, Host,
- Version);
-header_record([{"user-agent", Val} | Rest], RequestHeaders, Host, Version) ->
- header_record(Rest, RequestHeaders#http_request_h{'user-agent' = Val},
- Host, Version);
-header_record([{"allow", Val} | Rest], RequestHeaders, Host, Version) ->
- header_record(Rest, RequestHeaders#http_request_h{allow = Val}, Host,
- Version);
-header_record([{"content-encoding", Val} | Rest], RequestHeaders, Host,
- Version) ->
- header_record(Rest,
- RequestHeaders#http_request_h{'content-encoding' = Val},
- Host, Version);
-header_record([{"content-language", Val} | Rest], RequestHeaders,
- Host, Version) ->
- header_record(Rest,
- RequestHeaders#http_request_h{'content-language' = Val},
- Host, Version);
-header_record([{"content-length", Val} | Rest], RequestHeaders, Host, Version) ->
- header_record(Rest, RequestHeaders#http_request_h{'content-length' = Val},
- Host, Version);
-header_record([{"content-location", Val} | Rest], RequestHeaders,
- Host, Version) ->
- header_record(Rest,
- RequestHeaders#http_request_h{'content-location' = Val},
- Host, Version);
-header_record([{"content-md5", Val} | Rest], RequestHeaders, Host, Version) ->
- header_record(Rest, RequestHeaders#http_request_h{'content-md5' = Val},
- Host, Version);
-header_record([{"content-range", Val} | Rest], RequestHeaders, Host, Version) ->
- header_record(Rest, RequestHeaders#http_request_h{'content-range' = Val},
- Host, Version);
-header_record([{"content-type", Val} | Rest], RequestHeaders, Host, Version) ->
- header_record(Rest, RequestHeaders#http_request_h{'content-type' = Val},
- Host, Version);
-header_record([{"expires", Val} | Rest], RequestHeaders, Host, Version) ->
- header_record(Rest, RequestHeaders#http_request_h{expires = Val}, Host,
- Version);
-header_record([{"last-modified", Val} | Rest], RequestHeaders, Host, Version) ->
- header_record(Rest, RequestHeaders#http_request_h{'last-modified' = Val},
- Host, Version);
-header_record([{Key, Val} | Rest], RequestHeaders, Host, Version) ->
- header_record(Rest, RequestHeaders#http_request_h{
- other = [{Key, Val} |
- RequestHeaders#http_request_h.other]},
- Host, Version).
+stream_next(Pid) ->
+ httpc:stream_next(Pid).
-validate_headers(RequestHeaders = #http_request_h{te = undefined}, Host,
- "HTTP/1.1" = Version) ->
- validate_headers(RequestHeaders#http_request_h{te = ""}, Host,
- "HTTP/1.1" = Version);
-validate_headers(RequestHeaders = #http_request_h{host = undefined},
- Host, "HTTP/1.1" = Version) ->
- validate_headers(RequestHeaders#http_request_h{host = Host}, Host, Version);
-validate_headers(RequestHeaders, _, _) ->
- RequestHeaders.
+%%--------------------------------------------------------------------------
+%% default_profile()
+%%-------------------------------------------------------------------------
default_profile() ->
- ?DEFAULT_PROFILE.
-
-profile_name(?DEFAULT_PROFILE) ->
- httpc_manager;
-profile_name(Pid) when is_pid(Pid) ->
- Pid;
-profile_name(Profile) ->
- list_to_atom("httpc_manager_" ++ atom_to_list(Profile)).
-
-child_name2info(undefined) ->
- {error, no_such_service};
-child_name2info(httpc_manager) ->
- {ok, [{profile, default}]};
-child_name2info({http, Profile}) ->
- {ok, [{profile, Profile}]}.
-
-child_name(_, []) ->
- undefined;
-child_name(Pid, [{Name, Pid} | _]) ->
- Name;
-child_name(Pid, [_ | Children]) ->
- child_name(Pid, Children).
-
-%% d(F) ->
-%% d(F, []).
-
-%% d(F, A) ->
-%% d(get(dbg), F, A).
-
-%% d(true, F, A) ->
-%% io:format(user, "~w:~w:" ++ F ++ "~n", [self(), ?MODULE | A]);
-%% d(_, _, _) ->
-%% ok.
-
+ httpc:default_profile().
diff --git a/lib/inets/src/http_client/http_cookie.erl b/lib/inets/src/http_client/http_cookie.erl
deleted file mode 100644
index e091070f72..0000000000
--- a/lib/inets/src/http_client/http_cookie.erl
+++ /dev/null
@@ -1,391 +0,0 @@
-%%
-%% %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%
-%%
-%% Description: Cookie handling according to RFC 2109
-
--module(http_cookie).
-
--include("httpc_internal.hrl").
-
--export([header/4, cookies/3, open_cookie_db/1, close_cookie_db/1, insert/2]).
-
-%%%=========================================================================
-%%% API
-%%%=========================================================================
-header(Scheme, {Host, _}, Path, CookieDb) ->
- case lookup_cookies(Host, Path, CookieDb) of
- [] ->
- {"cookie", ""};
- Cookies ->
- {"cookie", cookies_to_string(Scheme, Cookies)}
- end.
-
-cookies(Headers, RequestPath, RequestHost) ->
- Cookies = parse_set_cookies(Headers, {RequestPath, RequestHost}),
- accept_cookies(Cookies, RequestPath, RequestHost).
-
-open_cookie_db({{_, only_session_cookies}, SessionDbName}) ->
- EtsDb = ets:new(SessionDbName, [protected, bag,
- {keypos, #http_cookie.domain}]),
- {undefined, EtsDb};
-
-open_cookie_db({{DbName, Dbdir}, SessionDbName}) ->
- File = filename:join(Dbdir, atom_to_list(DbName)),
- {ok, DetsDb} = dets:open_file(DbName, [{keypos, #http_cookie.domain},
- {type, bag},
- {file, File},
- {ram_file, true}]),
- EtsDb = ets:new(SessionDbName, [protected, bag,
- {keypos, #http_cookie.domain}]),
- {DetsDb, EtsDb}.
-
-close_cookie_db({undefined, EtsDb}) ->
- ets:delete(EtsDb);
-
-close_cookie_db({DetsDb, EtsDb}) ->
- dets:close(DetsDb),
- ets:delete(EtsDb).
-
-%% If no persistent cookie database is defined we
-%% treat all cookies as if they where session cookies.
-insert(Cookie = #http_cookie{max_age = Int},
- Dbs = {undefined, _}) when is_integer(Int) ->
- insert(Cookie#http_cookie{max_age = session}, Dbs);
-
-insert(Cookie = #http_cookie{domain = Key, name = Name,
- path = Path, max_age = session},
- Db = {_, CookieDb}) ->
- case ets:match_object(CookieDb, #http_cookie{domain = Key,
- name = Name,
- path = Path,
- _ = '_'}) of
- [] ->
- ets:insert(CookieDb, Cookie);
- [NewCookie] ->
- delete(NewCookie, Db),
- ets:insert(CookieDb, Cookie)
- end,
- ok;
-insert(#http_cookie{domain = Key, name = Name,
- path = Path, max_age = 0},
- Db = {CookieDb, _}) ->
- case dets:match_object(CookieDb, #http_cookie{domain = Key,
- name = Name,
- path = Path,
- _ = '_'}) of
- [] ->
- ok;
- [NewCookie] ->
- delete(NewCookie, Db)
- end,
- ok;
-insert(Cookie = #http_cookie{domain = Key, name = Name, path = Path},
- Db = {CookieDb, _}) ->
- case dets:match_object(CookieDb, #http_cookie{domain = Key,
- name = Name,
- path = Path,
- _ = '_'}) of
- [] ->
- dets:insert(CookieDb, Cookie);
- [NewCookie] ->
- delete(NewCookie, Db),
- dets:insert(CookieDb, Cookie)
- end,
- ok.
-
-%%%========================================================================
-%%% Internal functions
-%%%========================================================================
-lookup_cookies(Key, {undefined, Ets}) ->
- ets:match_object(Ets, #http_cookie{domain = Key,
- _ = '_'});
-lookup_cookies(Key, {Dets,Ets}) ->
- SessionCookies = ets:match_object(Ets, #http_cookie{domain = Key,
- _ = '_'}),
- Cookies = dets:match_object(Dets, #http_cookie{domain = Key,
- _ = '_'}),
- Cookies ++ SessionCookies.
-
-delete(Cookie = #http_cookie{max_age = session}, {_, CookieDb}) ->
- ets:delete_object(CookieDb, Cookie);
-delete(Cookie, {CookieDb, _}) ->
- dets:delete_object(CookieDb, Cookie).
-
-lookup_cookies(Host, Path, Db) ->
- Cookies =
- case http_util:is_hostname(Host) of
- true ->
- HostCookies = lookup_cookies(Host, Db),
- [_| DomainParts] = string:tokens(Host, "."),
- lookup_domain_cookies(DomainParts, Db, HostCookies);
- false -> % IP-adress
- lookup_cookies(Host, Db)
- end,
- ValidCookies = valid_cookies(Cookies, [], Db),
- lists:filter(fun(Cookie) ->
- lists:prefix(Cookie#http_cookie.path, Path)
- end, ValidCookies).
-
-%% For instance if Host=localhost
-lookup_domain_cookies([], _, AccCookies) ->
- lists:flatten(AccCookies);
-%% Top domains can not have cookies
-lookup_domain_cookies([_], _, AccCookies) ->
- lists:flatten(AccCookies);
-lookup_domain_cookies([Next | DomainParts], CookieDb, AccCookies) ->
- Domain = merge_domain_parts(DomainParts, [Next ++ "."]),
- lookup_domain_cookies(DomainParts, CookieDb,
- [lookup_cookies(Domain, CookieDb)
- | AccCookies]).
-
-merge_domain_parts([Part], Merged) ->
- lists:flatten(["." | lists:reverse([Part | Merged])]);
-merge_domain_parts([Part| Rest], Merged) ->
- merge_domain_parts(Rest, [".", Part | Merged]).
-
-cookies_to_string(Scheme, Cookies = [Cookie | _]) ->
- Version = "$Version=" ++ Cookie#http_cookie.version ++ "; ",
- cookies_to_string(Scheme, path_sort(Cookies), [Version]).
-
-cookies_to_string(_, [], CookieStrs) ->
- case length(CookieStrs) of
- 1 ->
- "";
- _ ->
- lists:flatten(lists:reverse(CookieStrs))
- end;
-
-cookies_to_string(https, [Cookie = #http_cookie{secure = true}| Cookies],
- CookieStrs) ->
- Str = case Cookies of
- [] ->
- cookie_to_string(Cookie);
- _ ->
- cookie_to_string(Cookie) ++ "; "
- end,
- cookies_to_string(https, Cookies, [Str | CookieStrs]);
-
-cookies_to_string(Scheme, [#http_cookie{secure = true}| Cookies],
- CookieStrs) ->
- cookies_to_string(Scheme, Cookies, CookieStrs);
-
-cookies_to_string(Scheme, [Cookie | Cookies], CookieStrs) ->
- Str = case Cookies of
- [] ->
- cookie_to_string(Cookie);
- _ ->
- cookie_to_string(Cookie) ++ "; "
- end,
- cookies_to_string(Scheme, Cookies, [Str | CookieStrs]).
-
-cookie_to_string(Cookie = #http_cookie{name = Name, value = Value}) ->
- Str = Name ++ "=" ++ Value,
- add_domain(add_path(Str, Cookie), Cookie).
-
-add_path(Str, #http_cookie{path_default = true}) ->
- Str;
-add_path(Str, #http_cookie{path = Path}) ->
- Str ++ "; $Path=" ++ Path.
-
-add_domain(Str, #http_cookie{domain_default = true}) ->
- Str;
-add_domain(Str, #http_cookie{domain = Domain}) ->
- Str ++ "; $Domain=" ++ Domain.
-
-parse_set_cookies(OtherHeaders, DefaultPathDomain) ->
- SetCookieHeaders = lists:foldl(fun({"set-cookie", Value}, Acc) ->
- [string:tokens(Value, ",")| Acc];
- (_, Acc) ->
- Acc
- end, [], OtherHeaders),
-
- lists:flatten(lists:map(fun(CookieHeader) ->
- NewHeader =
- fix_netscape_cookie(CookieHeader,
- []),
- parse_set_cookie(NewHeader, [],
- DefaultPathDomain) end,
- SetCookieHeaders)).
-
-parse_set_cookie([], AccCookies, _) ->
- AccCookies;
-parse_set_cookie([CookieHeader | CookieHeaders], AccCookies,
- Defaults = {DefaultPath, DefaultDomain}) ->
- [CookieStr | Attributes] = case string:tokens(CookieHeader, ";") of
- [CStr] ->
- [CStr, ""];
- [CStr | Attr] ->
- [CStr, Attr]
- end,
- Pos = string:chr(CookieStr, $=),
- Name = string:substr(CookieStr, 1, Pos - 1),
- Value = string:substr(CookieStr, Pos + 1),
- Cookie = #http_cookie{name = string:strip(Name),
- value = string:strip(Value)},
- NewAttributes = parse_set_cookie_attributes(Attributes),
- TmpCookie = cookie_attributes(NewAttributes, Cookie),
- %% Add runtime defult values if necessary
- NewCookie = domain_default(path_default(TmpCookie, DefaultPath),
- DefaultDomain),
- parse_set_cookie(CookieHeaders, [NewCookie | AccCookies], Defaults).
-
-parse_set_cookie_attributes([]) ->
- [];
-parse_set_cookie_attributes([Attributes]) ->
- lists:map(fun(Attr) ->
- [AttrName, AttrValue] =
- case string:tokens(Attr, "=") of
- %% All attributes have the form
- %% Name=Value except "secure"!
- [Name] ->
- [Name, ""];
- [Name, Value] ->
- [Name, Value];
- %% Anything not expected will be
- %% disregarded
- _ ->
- ["Dummy",""]
- end,
- {http_util:to_lower(string:strip(AttrName)),
- string:strip(AttrValue)}
- end, Attributes).
-
-cookie_attributes([], Cookie) ->
- Cookie;
-cookie_attributes([{"comment", Value}| Attributes], Cookie) ->
- cookie_attributes(Attributes,
- Cookie#http_cookie{comment = Value});
-cookie_attributes([{"domain", Value}| Attributes], Cookie) ->
- cookie_attributes(Attributes,
- Cookie#http_cookie{domain = Value});
-cookie_attributes([{"max-age", Value}| Attributes], Cookie) ->
- ExpireTime = cookie_expires(list_to_integer(Value)),
- cookie_attributes(Attributes,
- Cookie#http_cookie{max_age = ExpireTime});
-%% Backwards compatibility with netscape cookies
-cookie_attributes([{"expires", Value}| Attributes], Cookie) ->
- Time = http_util:convert_netscapecookie_date(Value),
- ExpireTime = calendar:datetime_to_gregorian_seconds(Time),
- cookie_attributes(Attributes,
- Cookie#http_cookie{max_age = ExpireTime});
-cookie_attributes([{"path", Value}| Attributes], Cookie) ->
- cookie_attributes(Attributes,
- Cookie#http_cookie{path = Value});
-cookie_attributes([{"secure", _}| Attributes], Cookie) ->
- cookie_attributes(Attributes,
- Cookie#http_cookie{secure = true});
-cookie_attributes([{"version", Value}| Attributes], Cookie) ->
- cookie_attributes(Attributes,
- Cookie#http_cookie{version = Value});
-%% Disregard unknown attributes.
-cookie_attributes([_| Attributes], Cookie) ->
- cookie_attributes(Attributes, Cookie).
-
-domain_default(Cookie = #http_cookie{domain = undefined},
- DefaultDomain) ->
- Cookie#http_cookie{domain = DefaultDomain, domain_default = true};
-domain_default(Cookie, _) ->
- Cookie.
-
-path_default(Cookie = #http_cookie{path = undefined},
- DefaultPath) ->
- Cookie#http_cookie{path = skip_right_most_slash(DefaultPath),
- path_default = true};
-path_default(Cookie, _) ->
- Cookie.
-
-%% Note: if the path is only / that / will be keept
-skip_right_most_slash("/") ->
- "/";
-skip_right_most_slash(Str) ->
- string:strip(Str, right, $/).
-
-accept_cookies(Cookies, RequestPath, RequestHost) ->
- lists:filter(fun(Cookie) ->
- accept_cookie(Cookie, RequestPath, RequestHost)
- end, Cookies).
-
-accept_cookie(Cookie, RequestPath, RequestHost) ->
- accept_path(Cookie, RequestPath) and accept_domain(Cookie, RequestHost).
-
-accept_path(#http_cookie{path = Path}, RequestPath) ->
- lists:prefix(Path, RequestPath).
-
-accept_domain(#http_cookie{domain = RequestHost}, RequestHost) ->
- true;
-
-accept_domain(#http_cookie{domain = Domain}, RequestHost) ->
- HostCheck = case http_util:is_hostname(RequestHost) of
- true ->
- (lists:suffix(Domain, RequestHost) andalso
- (not
- lists:member($.,
- string:substr(RequestHost, 1,
- (length(RequestHost) -
- length(Domain))))));
- false ->
- false
- end,
- HostCheck andalso (hd(Domain) == $.)
- andalso (length(string:tokens(Domain, ".")) > 1).
-
-cookie_expires(0) ->
- 0;
-cookie_expires(DeltaSec) ->
- NowSec = calendar:datetime_to_gregorian_seconds({date(), time()}),
- NowSec + DeltaSec.
-
-is_cookie_expired(#http_cookie{max_age = session}) ->
- false;
-is_cookie_expired(#http_cookie{max_age = ExpireTime}) ->
- NowSec = calendar:datetime_to_gregorian_seconds({date(), time()}),
- ExpireTime - NowSec =< 0.
-
-valid_cookies([], Valid, _) ->
- Valid;
-
-valid_cookies([Cookie | Cookies], Valid, Db) ->
- case is_cookie_expired(Cookie) of
- true ->
- delete(Cookie, Db),
- valid_cookies(Cookies, Valid, Db);
- false ->
- valid_cookies(Cookies, [Cookie | Valid], Db)
- end.
-
-path_sort(Cookies)->
- lists:reverse(lists:keysort(#http_cookie.path, Cookies)).
-
-
-%% Informally, the Set-Cookie response header comprises the token
-%% Set-Cookie:, followed by a comma-separated list of one or more
-%% cookies. Netscape cookies expires attribute may also have a
-%% , in this case the header list will have been incorrectly split
-%% in parse_set_cookies/2 this functions fixs that problem.
-fix_netscape_cookie([Cookie1, Cookie2 | Rest], Acc) ->
- case inets_regexp:match(Cookie1, "expires=") of
- {_, _, _} ->
- fix_netscape_cookie(Rest, [Cookie1 ++ Cookie2 | Acc]);
- nomatch ->
- fix_netscape_cookie([Cookie2 |Rest], [Cookie1| Acc])
- end;
-fix_netscape_cookie([Cookie | Rest], Acc) ->
- fix_netscape_cookie(Rest, [Cookie | Acc]);
-
-fix_netscape_cookie([], Acc) ->
- Acc.
diff --git a/lib/inets/src/http_client/http_uri.erl b/lib/inets/src/http_client/http_uri.erl
deleted file mode 100644
index 615a0d8ec4..0000000000
--- a/lib/inets/src/http_client/http_uri.erl
+++ /dev/null
@@ -1,116 +0,0 @@
-%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2006-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(http_uri).
-
--export([parse/1]).
-
-%%%=========================================================================
-%%% API
-%%%=========================================================================
-parse(AbsURI) ->
- case parse_scheme(AbsURI) of
- {error, Reason} ->
- {error, Reason};
- {Scheme, Rest} ->
- case (catch parse_uri_rest(Scheme, Rest)) of
- {UserInfo, Host, Port, Path, Query} ->
- {Scheme, UserInfo, Host, Port, Path, Query};
- _ ->
- {error, {malformed_url, AbsURI}}
- end
- end.
-
-%%%========================================================================
-%%% Internal functions
-%%%========================================================================
-parse_scheme(AbsURI) ->
- case split_uri(AbsURI, ":", {error, no_scheme}, 1, 1) of
- {error, no_scheme} ->
- {error, no_scheme};
- {StrScheme, Rest} ->
- case list_to_atom(http_util:to_lower(StrScheme)) of
- Scheme when Scheme == http; Scheme == https ->
- {Scheme, Rest};
- Scheme ->
- {error, {not_supported_scheme, Scheme}}
- end
- end.
-
-parse_uri_rest(Scheme, "//" ++ URIPart) ->
-
- {Authority, PathQuery} =
- case split_uri(URIPart, "/", URIPart, 1, 0) of
- Split = {_, _} ->
- Split;
- URIPart ->
- case split_uri(URIPart, "\\?", URIPart, 1, 0) of
- Split = {_, _} ->
- Split;
- URIPart ->
- {URIPart,""}
- end
- end,
-
- {UserInfo, HostPort} = split_uri(Authority, "@", {"", Authority}, 1, 1),
- {Host, Port} = parse_host_port(Scheme, HostPort),
- {Path, Query} = parse_path_query(PathQuery),
- {UserInfo, Host, Port, Path, Query}.
-
-
-parse_path_query(PathQuery) ->
- {Path, Query} = split_uri(PathQuery, "\\?", {PathQuery, ""}, 1, 0),
- {path(Path), Query}.
-
-
-parse_host_port(Scheme,"[" ++ HostPort) -> %ipv6
- DefaultPort = default_port(Scheme),
- {Host, ColonPort} = split_uri(HostPort, "\\]", {HostPort, ""}, 1, 1),
- {_, Port} = split_uri(ColonPort, ":", {"", DefaultPort}, 0, 1),
- {Host, int_port(Port)};
-
-parse_host_port(Scheme, HostPort) ->
- DefaultPort = default_port(Scheme),
- {Host, Port} = split_uri(HostPort, ":", {HostPort, DefaultPort}, 1, 1),
- {Host, int_port(Port)}.
-
-split_uri(UriPart, SplitChar, NoMatchResult, SkipLeft, SkipRight) ->
- case inets_regexp:first_match(UriPart, SplitChar) of
- {match, Match, _} ->
- {string:substr(UriPart, 1, Match - SkipLeft),
- string:substr(UriPart, Match + SkipRight, length(UriPart))};
- nomatch ->
- NoMatchResult
- end.
-
-default_port(http) ->
- 80;
-default_port(https) ->
- 443.
-
-int_port(Port) when is_integer(Port) ->
- Port;
-int_port(Port) when is_list(Port) ->
- list_to_integer(Port).
-
-path("") ->
- "/";
-path(Path) ->
- Path.
diff --git a/lib/inets/src/http_client/httpc.erl b/lib/inets/src/http_client/httpc.erl
new file mode 100644
index 0000000000..ca186f46a7
--- /dev/null
+++ b/lib/inets/src/http_client/httpc.erl
@@ -0,0 +1,1096 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 2009-2011. All Rights Reserved.
+%%
+%% The contents of this file are subject to the Erlang Public License,
+%% Version 1.1, (the "License"); you may not use this file except in
+%% compliance with the License. You should have received a copy of the
+%% Erlang Public License along with this software. If not, it can be
+%% retrieved online at http://www.erlang.org/.
+%%
+%% Software distributed under the License is distributed on an "AS IS"
+%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+%% the License for the specific language governing rights and limitations
+%% under the License.
+%%
+%% %CopyrightEnd%
+%%
+%%
+
+%% Description:
+%%% This version of the HTTP/1.1 client supports:
+%%% - RFC 2616 HTTP 1.1 client part
+%%% - RFC 2818 HTTP Over TLS
+
+-module(httpc).
+
+-behaviour(inets_service).
+
+%% API
+-export([
+ request/1, request/2, request/4, request/5,
+ cancel_request/1, cancel_request/2,
+ set_option/2, set_option/3,
+ set_options/1, set_options/2,
+ store_cookies/2, store_cookies/3,
+ cookie_header/1, cookie_header/2,
+ which_cookies/0, which_cookies/1,
+ reset_cookies/0, reset_cookies/1,
+ stream_next/1,
+ default_profile/0,
+ profile_name/1, profile_name/2,
+ info/0, info/1
+ ]).
+
+%% Behavior callbacks
+-export([start_standalone/1, start_service/1,
+ stop_service/1,
+ services/0, service_info/1]).
+
+-include("http_internal.hrl").
+-include("httpc_internal.hrl").
+
+-define(DEFAULT_PROFILE, default).
+
+
+%%%=========================================================================
+%%% API
+%%%=========================================================================
+
+default_profile() ->
+ ?DEFAULT_PROFILE.
+
+
+profile_name(?DEFAULT_PROFILE) ->
+ httpc_manager;
+profile_name(Profile) ->
+ profile_name("httpc_manager_", Profile).
+
+profile_name(Prefix, Profile) when is_atom(Profile) ->
+ list_to_atom(Prefix ++ atom_to_list(Profile));
+profile_name(Prefix, Profile) when is_pid(Profile) ->
+ ProfileStr0 =
+ string:strip(string:strip(erlang:pid_to_list(Profile), left, $<), right, $>),
+ F = fun($.) -> $_; (X) -> X end,
+ ProfileStr = [F(C) || C <- ProfileStr0],
+ list_to_atom(Prefix ++ "pid_" ++ ProfileStr).
+
+
+%%--------------------------------------------------------------------------
+%% request(Url) -> {ok, {StatusLine, Headers, Body}} | {error,Reason}
+%% request(Url Profile) ->
+%% {ok, {StatusLine, Headers, Body}} | {error,Reason}
+%%
+%% Url - string()
+%% Description: Calls request/4 with default values.
+%%--------------------------------------------------------------------------
+
+request(Url) ->
+ request(Url, default_profile()).
+
+request(Url, Profile) ->
+ request(get, {Url, []}, [], [], Profile).
+
+
+%%--------------------------------------------------------------------------
+%% request(Method, Request, HTTPOptions, Options [, Profile]) ->
+%% {ok, {StatusLine, Headers, Body}} | {ok, {Status, Body}} |
+%% {ok, RequestId} | {error,Reason} | {ok, {saved_as, FilePath}
+%%
+%% Method - atom() = head | get | put | post | trace | options| delete
+%% Request - {Url, Headers} | {Url, Headers, ContentType, Body}
+%% Url - string()
+%% HTTPOptions - [HttpOption]
+%% HTTPOption - {timeout, Time} | {connect_timeout, Time} |
+%% {ssl, SSLOptions} | {proxy_auth, {User, Password}}
+%% Ssloptions = [SSLOption]
+%% SSLOption = {verify, code()} | {depth, depth()} | {certfile, path()} |
+%% {keyfile, path()} | {password, string()} | {cacertfile, path()} |
+%% {ciphers, string()}
+%% Options - [Option]
+%% Option - {sync, Boolean} | {body_format, BodyFormat} |
+%% {full_result, Boolean} | {stream, To} |
+%% {headers_as_is, Boolean}
+%% StatusLine = {HTTPVersion, StatusCode, ReasonPhrase}</v>
+%% HTTPVersion = string()
+%% StatusCode = integer()
+%% ReasonPhrase = string()
+%% Headers = [Header]
+%% Header = {Field, Value}
+%% Field = string()
+%% Value = string()
+%% Body = string() | binary() - HTLM-code
+%%
+%% Description: Sends a HTTP-request. The function can be both
+%% syncronus and asynchronous in the later case the function will
+%% return {ok, RequestId} and later on a message will be sent to the
+%% calling process on the format {http, {RequestId, {StatusLine,
+%% Headers, Body}}} or {http, {RequestId, {error, Reason}}}
+%%--------------------------------------------------------------------------
+
+request(Method, Request, HttpOptions, Options) ->
+ request(Method, Request, HttpOptions, Options, default_profile()).
+
+request(Method, {Url, Headers}, HTTPOptions, Options, Profile)
+ when (Method =:= options) orelse
+ (Method =:= get) orelse
+ (Method =:= head) orelse
+ (Method =:= delete) orelse
+ (Method =:= trace) andalso
+ (is_atom(Profile) orelse is_pid(Profile)) ->
+ ?hcrt("request", [{method, Method},
+ {url, Url},
+ {headers, Headers},
+ {http_options, HTTPOptions},
+ {options, Options},
+ {profile, Profile}]),
+ case http_uri:parse(Url) of
+ {error, Reason} ->
+ {error, Reason};
+ ParsedUrl ->
+ handle_request(Method, Url, ParsedUrl, Headers, [], [],
+ HTTPOptions, Options, Profile)
+ end;
+
+request(Method, {Url,Headers,ContentType,Body}, HTTPOptions, Options, Profile)
+ when ((Method =:= post) orelse (Method =:= put)) andalso
+ (is_atom(Profile) orelse is_pid(Profile)) ->
+ ?hcrt("request", [{method, Method},
+ {url, Url},
+ {headers, Headers},
+ {content_type, ContentType},
+ {body, Body},
+ {http_options, HTTPOptions},
+ {options, Options},
+ {profile, Profile}]),
+ case http_uri:parse(Url) of
+ {error, Reason} ->
+ {error, Reason};
+ ParsedUrl ->
+ handle_request(Method, Url,
+ ParsedUrl, Headers, ContentType, Body,
+ HTTPOptions, Options, Profile)
+ end.
+
+
+%%--------------------------------------------------------------------------
+%% cancel_request(RequestId) -> ok
+%% cancel_request(RequestId, Profile) -> ok
+%% RequestId - As returned by request/4
+%%
+%% Description: Cancels a HTTP-request.
+%%-------------------------------------------------------------------------
+cancel_request(RequestId) ->
+ cancel_request(RequestId, default_profile()).
+
+cancel_request(RequestId, Profile)
+ when is_atom(Profile) orelse is_pid(Profile) ->
+ ?hcrt("cancel request", [{request_id, RequestId}, {profile, Profile}]),
+ ok = httpc_manager:cancel_request(RequestId, profile_name(Profile)),
+ receive
+ %% If the request was already fulfilled throw away the
+ %% answer as the request has been canceled.
+ {http, {RequestId, _}} ->
+ ok
+ after 0 ->
+ ok
+ end.
+
+
+%%--------------------------------------------------------------------------
+%% set_options(Options) -> ok | {error, Reason}
+%% set_options(Options, Profile) -> ok | {error, Reason}
+%% Options - [Option]
+%% Profile - atom()
+%% Option - {proxy, {Proxy, NoProxy}} | {max_sessions, MaxSessions} |
+%% {max_pipeline_length, MaxPipeline} |
+%% {pipeline_timeout, PipelineTimeout} | {cookies, CookieMode} |
+%% {ipfamily, IpFamily}
+%% Proxy - {Host, Port}
+%% NoProxy - [Domain | HostName | IPAddress]
+%% MaxSessions, MaxPipeline, PipelineTimeout = integer()
+%% CookieMode - enabled | disabled | verify
+%% IpFamily - inet | inet6 | inet6fb4
+%% Description: Informs the httpc_manager of the new settings.
+%%-------------------------------------------------------------------------
+set_options(Options) ->
+ set_options(Options, default_profile()).
+set_options(Options, Profile) when is_atom(Profile) orelse is_pid(Profile) ->
+ ?hcrt("set cookies", [{options, Options}, {profile, Profile}]),
+ case validate_options(Options) of
+ {ok, Opts} ->
+ try
+ begin
+ httpc_manager:set_options(Opts, profile_name(Profile))
+ end
+ catch
+ exit:{noproc, _} ->
+ {error, inets_not_started}
+ end;
+ {error, Reason} ->
+ {error, Reason}
+ end.
+
+set_option(Key, Value) ->
+ set_option(Key, Value, default_profile()).
+
+set_option(Key, Value, Profile) ->
+ set_options([{Key, Value}], Profile).
+
+
+%%--------------------------------------------------------------------------
+%% store_cookies(SetCookieHeaders, Url [, Profile]) -> ok | {error, reason}
+%%
+%%
+%% Description: Store the cookies from <SetCookieHeaders>
+%% in the cookie database
+%% for the profile <Profile>. This function shall be used when the option
+%% cookie is set to verify.
+%%-------------------------------------------------------------------------
+store_cookies(SetCookieHeaders, Url) ->
+ store_cookies(SetCookieHeaders, Url, default_profile()).
+
+store_cookies(SetCookieHeaders, Url, Profile)
+ when is_atom(Profile) orelse is_pid(Profile) ->
+ ?hcrt("store cookies", [{set_cookie_headers, SetCookieHeaders},
+ {url, Url},
+ {profile, Profile}]),
+ try
+ begin
+ {_, _, Host, Port, Path, _} = http_uri:parse(Url),
+ Address = {Host, Port},
+ ProfileName = profile_name(Profile),
+ Cookies = httpc_cookie:cookies(SetCookieHeaders, Path, Host),
+ httpc_manager:store_cookies(Cookies, Address, ProfileName),
+ ok
+ end
+ catch
+ exit:{noproc, _} ->
+ {error, {not_started, Profile}};
+ error:{badmatch, Bad} ->
+ {error, {parse_failed, Bad}}
+ end.
+
+
+%%--------------------------------------------------------------------------
+%% cookie_header(Url [, Profile]) -> Header | {error, Reason}
+%%
+%% Description: Returns the cookie header that would be sent when making
+%% a request to <Url>.
+%%-------------------------------------------------------------------------
+cookie_header(Url) ->
+ cookie_header(Url, default_profile()).
+
+cookie_header(Url, Profile) ->
+ ?hcrt("cookie header", [{url, Url},
+ {profile, Profile}]),
+ try
+ begin
+ httpc_manager:which_cookies(Url, profile_name(Profile))
+ end
+ catch
+ exit:{noproc, _} ->
+ {error, {not_started, Profile}}
+ end.
+
+
+%%--------------------------------------------------------------------------
+%% which_cookies() -> [cookie()]
+%% which_cookies(Profile) -> [cookie()]
+%%
+%% Description: Debug function, dumping the cookie database
+%%-------------------------------------------------------------------------
+which_cookies() ->
+ which_cookies(default_profile()).
+
+which_cookies(Profile) ->
+ ?hcrt("which cookies", [{profile, Profile}]),
+ try
+ begin
+ httpc_manager:which_cookies(profile_name(Profile))
+ end
+ catch
+ exit:{noproc, _} ->
+ {error, {not_started, Profile}}
+ end.
+
+
+%%--------------------------------------------------------------------------
+%% info() -> list()
+%% info(Profile) -> list()
+%%
+%% Description: Debug function, retreive info about the profile
+%%-------------------------------------------------------------------------
+info() ->
+ info(default_profile()).
+
+info(Profile) ->
+ ?hcrt("info", [{profile, Profile}]),
+ try
+ begin
+ httpc_manager:info(profile_name(Profile))
+ end
+ catch
+ exit:{noproc, _} ->
+ {error, {not_started, Profile}}
+ end.
+
+
+%%--------------------------------------------------------------------------
+%% reset_cookies() -> void()
+%% reset_cookies(Profile) -> void()
+%%
+%% Description: Debug function, reset the cookie database
+%%-------------------------------------------------------------------------
+reset_cookies() ->
+ reset_cookies(default_profile()).
+
+reset_cookies(Profile) ->
+ ?hcrt("reset cookies", [{profile, Profile}]),
+ try
+ begin
+ httpc_manager:reset_cookies(profile_name(Profile))
+ end
+ catch
+ exit:{noproc, _} ->
+ {error, {not_started, Profile}}
+ end.
+
+
+%%--------------------------------------------------------------------------
+%% stream_next(Pid) -> Header | {error, Reason}
+%%
+%% Description: Triggers the next message to be streamed, e.i.
+%% same behavior as active once for sockets.
+%%-------------------------------------------------------------------------
+stream_next(Pid) ->
+ ?hcrt("stream next", [{handler, Pid}]),
+ httpc_handler:stream_next(Pid).
+
+
+%%%========================================================================
+%%% Behaviour callbacks
+%%%========================================================================
+start_standalone(PropList) ->
+ ?hcrt("start standalone", [{proplist, PropList}]),
+ case proplists:get_value(profile, PropList) of
+ undefined ->
+ {error, no_profile};
+ Profile ->
+ Dir =
+ proplists:get_value(data_dir, PropList, only_session_cookies),
+ httpc_manager:start_link(Profile, Dir, stand_alone)
+ end.
+
+start_service(Config) ->
+ ?hcrt("start service", [{config, Config}]),
+ httpc_profile_sup:start_child(Config).
+
+stop_service(Profile) when is_atom(Profile) ->
+ ?hcrt("stop service", [{profile, Profile}]),
+ httpc_profile_sup:stop_child(Profile);
+stop_service(Pid) when is_pid(Pid) ->
+ ?hcrt("stop service", [{pid, Pid}]),
+ case service_info(Pid) of
+ {ok, [{profile, Profile}]} ->
+ stop_service(Profile);
+ Error ->
+ Error
+ end.
+
+services() ->
+ [{httpc, Pid} || {_, Pid, _, _} <-
+ supervisor:which_children(httpc_profile_sup)].
+service_info(Pid) ->
+ try [{ChildName, ChildPid} ||
+ {ChildName, ChildPid, _, _} <-
+ supervisor:which_children(httpc_profile_sup)] of
+ Children ->
+ child_name2info(child_name(Pid, Children))
+ catch
+ exit:{noproc, _} ->
+ {error, service_not_available}
+ end.
+
+
+%%%========================================================================
+%%% Internal functions
+%%%========================================================================
+
+handle_request(Method, Url,
+ {Scheme, UserInfo, Host, Port, Path, Query},
+ Headers, ContentType, Body,
+ HTTPOptions0, Options0, Profile) ->
+
+ Started = http_util:timestamp(),
+ NewHeaders = [{http_util:to_lower(Key), Val} || {Key, Val} <- Headers],
+
+ try
+ begin
+ HTTPOptions = http_options(HTTPOptions0),
+ Options = request_options(Options0),
+ Sync = proplists:get_value(sync, Options),
+ Stream = proplists:get_value(stream, Options),
+ Host2 = header_host(Scheme, Host, Port),
+ HeadersRecord = header_record(NewHeaders, Host2, HTTPOptions),
+ Receiver = proplists:get_value(receiver, Options),
+ SocketOpts = proplists:get_value(socket_opts, Options),
+ MaybeEscPath = maybe_url_encode(HTTPOptions, Path),
+ MaybeEscQuery = maybe_url_encode(HTTPOptions, Query),
+ AbsUri = maybe_url_encode(HTTPOptions, Url),
+ Request = #request{from = Receiver,
+ scheme = Scheme,
+ address = {Host, Port},
+ path = MaybeEscPath,
+ pquery = MaybeEscQuery,
+ method = Method,
+ headers = HeadersRecord,
+ content = {ContentType, Body},
+ settings = HTTPOptions,
+ abs_uri = AbsUri,
+ userinfo = UserInfo,
+ stream = Stream,
+ headers_as_is = headers_as_is(Headers, Options),
+ socket_opts = SocketOpts,
+ started = Started},
+ case httpc_manager:request(Request, profile_name(Profile)) of
+ {ok, RequestId} ->
+ handle_answer(RequestId, Sync, Options);
+ {error, Reason} ->
+ {error, Reason}
+ end
+ end
+ catch
+ error:{noproc, _} ->
+ {error, {not_started, Profile}};
+ throw:Error ->
+ Error
+ end.
+
+maybe_url_encode(#http_options{url_encode = true}, URI) ->
+ http_uri:encode(URI);
+maybe_url_encode(_, URI) ->
+ URI.
+
+handle_answer(RequestId, false, _) ->
+ {ok, RequestId};
+handle_answer(RequestId, true, Options) ->
+ receive
+ {http, {RequestId, saved_to_file}} ->
+ {ok, saved_to_file};
+ {http, {RequestId, {_,_,_} = Result}} ->
+ return_answer(Options, Result);
+ {http, {RequestId, {error, Reason}}} ->
+ {error, Reason}
+ end.
+
+return_answer(Options, {{"HTTP/0.9",_,_}, _, BinBody}) ->
+ Body = maybe_format_body(BinBody, Options),
+ {ok, Body};
+
+return_answer(Options, {StatusLine, Headers, BinBody}) ->
+
+ Body = maybe_format_body(BinBody, Options),
+
+ case proplists:get_value(full_result, Options, true) of
+ true ->
+ {ok, {StatusLine, Headers, Body}};
+ false ->
+ {_, Status, _} = StatusLine,
+ {ok, {Status, Body}}
+ end.
+
+maybe_format_body(BinBody, Options) ->
+ case proplists:get_value(body_format, Options, string) of
+ string ->
+ binary_to_list(BinBody);
+ _ ->
+ BinBody
+ end.
+
+%% This options is a workaround for http servers that do not follow the
+%% http standard and have case sensative header parsing. Should only be
+%% used if there is no other way to communicate with the server or for
+%% testing purpose.
+headers_as_is(Headers, Options) ->
+ case proplists:get_value(headers_as_is, Options, false) of
+ false ->
+ [];
+ true ->
+ Headers
+ end.
+
+
+http_options(HttpOptions) ->
+ HttpOptionsDefault = http_options_default(),
+ http_options(HttpOptionsDefault, HttpOptions, #http_options{}).
+
+http_options([], [], Acc) ->
+ Acc;
+http_options([], HttpOptions, Acc) ->
+ Fun = fun(BadOption) ->
+ Report = io_lib:format("Invalid option ~p ignored ~n",
+ [BadOption]),
+ error_logger:info_report(Report)
+ end,
+ lists:foreach(Fun, HttpOptions),
+ Acc;
+http_options([{Tag, Default, Idx, Post} | Defaults], HttpOptions, Acc) ->
+ case lists:keysearch(Tag, 1, HttpOptions) of
+ {value, {Tag, Val0}} ->
+ case Post(Val0) of
+ {ok, Val} ->
+ Acc2 = setelement(Idx, Acc, Val),
+ HttpOptions2 = lists:keydelete(Tag, 1, HttpOptions),
+ http_options(Defaults, HttpOptions2, Acc2);
+ error ->
+ Report = io_lib:format("Invalid option ~p:~p ignored ~n",
+ [Tag, Val0]),
+ error_logger:info_report(Report),
+ HttpOptions2 = lists:keydelete(Tag, 1, HttpOptions),
+ http_options(Defaults, HttpOptions2, Acc)
+ end;
+ false ->
+ DefaultVal =
+ case Default of
+ {value, Val} ->
+ Val;
+ {field, DefaultIdx} ->
+ element(DefaultIdx, Acc)
+ end,
+ Acc2 = setelement(Idx, Acc, DefaultVal),
+ http_options(Defaults, HttpOptions, Acc2)
+ end.
+
+http_options_default() ->
+ VersionPost =
+ fun(Value) when is_atom(Value) ->
+ {ok, http_util:to_upper(atom_to_list(Value))};
+ (Value) when is_list(Value) ->
+ {ok, http_util:to_upper(Value)};
+ (_) ->
+ error
+ end,
+ TimeoutPost = fun(Value) when is_integer(Value) andalso (Value >= 0) ->
+ {ok, Value};
+ (infinity = Value) ->
+ {ok, Value};
+ (_) ->
+ error
+ end,
+ AutoRedirectPost = fun(Value) when (Value =:= true) orelse
+ (Value =:= false) ->
+ {ok, Value};
+ (_) ->
+ error
+ end,
+ SslPost = fun(Value) when is_list(Value) ->
+ {ok, Value};
+ (_) ->
+ error
+ end,
+ ProxyAuthPost = fun({User, Passwd} = Value) when is_list(User) andalso
+ is_list(Passwd) ->
+ {ok, Value};
+ (_) ->
+ error
+ end,
+ RelaxedPost = fun(Value) when (Value =:= true) orelse
+ (Value =:= false) ->
+ {ok, Value};
+ (_) ->
+ error
+ end,
+ ConnTimeoutPost =
+ fun(Value) when is_integer(Value) andalso (Value >= 0) ->
+ {ok, Value};
+ (infinity = Value) ->
+ {ok, Value};
+ (_) ->
+ error
+ end,
+
+ UrlDecodePost = fun(Value) when (Value =:= true) orelse
+ (Value =:= false) ->
+ {ok, Value};
+ (_) ->
+ error
+ end,
+ [
+ {version, {value, "HTTP/1.1"}, #http_options.version, VersionPost},
+ {timeout, {value, ?HTTP_REQUEST_TIMEOUT}, #http_options.timeout, TimeoutPost},
+ {autoredirect, {value, true}, #http_options.autoredirect, AutoRedirectPost},
+ {ssl, {value, []}, #http_options.ssl, SslPost},
+ {proxy_auth, {value, undefined}, #http_options.proxy_auth, ProxyAuthPost},
+ {relaxed, {value, false}, #http_options.relaxed, RelaxedPost},
+ %% this field has to be *after* the timeout field (as that field is used for the default value)
+ {connect_timeout, {field, #http_options.timeout}, #http_options.connect_timeout, ConnTimeoutPost},
+ {url_encode, {value, false}, #http_options.url_encode, UrlDecodePost}
+ ].
+
+
+request_options_defaults() ->
+ VerifyBoolean =
+ fun(Value) when ((Value =:= true) orelse (Value =:= false)) ->
+ ok;
+ (_) ->
+ error
+ end,
+
+ VerifySync = VerifyBoolean,
+
+ VerifyStream =
+ fun(none = _Value) ->
+ ok;
+ (self = _Value) ->
+ ok;
+ ({self, once} = _Value) ->
+ ok;
+ (Value) when is_list(Value) ->
+ ok;
+ (_) ->
+ error
+ end,
+
+ VerifyBodyFormat =
+ fun(string = _Value) ->
+ ok;
+ (binary = _Value) ->
+ ok;
+ (_) ->
+ error
+ end,
+
+ VerifyFullResult = VerifyBoolean,
+
+ VerifyHeaderAsIs = VerifyBoolean,
+
+ VerifyReceiver =
+ fun(Value) when is_pid(Value) ->
+ ok;
+ ({M, F, A}) when (is_atom(M) andalso
+ is_atom(F) andalso
+ is_list(A)) ->
+ ok;
+ (Value) when is_function(Value, 1) ->
+ ok;
+ (_) ->
+ error
+ end,
+
+ VerifySocketOpts =
+ fun([]) ->
+ {ok, undefined};
+ (Value) when is_list(Value) ->
+ ok;
+ (_) ->
+ error
+ end,
+
+ [
+ {sync, true, VerifySync},
+ {stream, none, VerifyStream},
+ {body_format, string, VerifyBodyFormat},
+ {full_result, true, VerifyFullResult},
+ {headers_as_is, false, VerifyHeaderAsIs},
+ {receiver, self(), VerifyReceiver},
+ {socket_opts, undefined, VerifySocketOpts}
+ ].
+
+request_options(Options) ->
+ Defaults = request_options_defaults(),
+ request_options(Defaults, Options, []).
+
+request_options([], [], Acc) ->
+ request_options_sanity_check(Acc),
+ lists:reverse(Acc);
+request_options([], Options, Acc) ->
+ Fun = fun(BadOption) ->
+ Report = io_lib:format("Invalid option ~p ignored ~n",
+ [BadOption]),
+ error_logger:info_report(Report)
+ end,
+ lists:foreach(Fun, Options),
+ Acc;
+request_options([{Key, DefaultVal, Verify} | Defaults], Options, Acc) ->
+ case lists:keysearch(Key, 1, Options) of
+ {value, {Key, Value}} ->
+ case Verify(Value) of
+ ok ->
+ Options2 = lists:keydelete(Key, 1, Options),
+ request_options(Defaults, Options2, [{Key, Value} | Acc]);
+ {ok, Value2} ->
+ Options2 = lists:keydelete(Key, 1, Options),
+ request_options(Defaults, Options2, [{Key, Value2} | Acc]);
+ error ->
+ Report = io_lib:format("Invalid option ~p:~p ignored ~n",
+ [Key, Value]),
+ error_logger:info_report(Report),
+ Options2 = lists:keydelete(Key, 1, Options),
+ request_options(Defaults, Options2, Acc)
+ end;
+ false ->
+ request_options(Defaults, Options, [{Key, DefaultVal} | Acc])
+ end.
+
+request_options_sanity_check(Opts) ->
+ case proplists:get_value(sync, Opts) of
+ Sync when (Sync =:= true) ->
+ case proplists:get_value(receiver, Opts) of
+ Pid when is_pid(Pid) andalso (Pid =:= self()) ->
+ ok;
+ BadReceiver ->
+ throw({error, {bad_options_combo,
+ [{sync, true}, {receiver, BadReceiver}]}})
+ end,
+ case proplists:get_value(stream, Opts) of
+ Stream when (Stream =:= self) orelse
+ (Stream =:= {self, once}) ->
+ throw({error, streaming_error});
+ _ ->
+ ok
+ end;
+ _ ->
+ ok
+ end,
+ ok.
+
+validate_options(Options) ->
+ (catch validate_options(Options, [])).
+
+validate_options([], ValidateOptions) ->
+ {ok, lists:reverse(ValidateOptions)};
+
+validate_options([{proxy, Proxy} = Opt| Tail], Acc) ->
+ validate_proxy(Proxy),
+ validate_options(Tail, [Opt | Acc]);
+
+validate_options([{max_sessions, Value} = Opt| Tail], Acc) ->
+ validate_max_sessions(Value),
+ validate_options(Tail, [Opt | Acc]);
+
+validate_options([{keep_alive_timeout, Value} = Opt| Tail], Acc) ->
+ validate_keep_alive_timeout(Value),
+ validate_options(Tail, [Opt | Acc]);
+
+validate_options([{max_keep_alive_length, Value} = Opt| Tail], Acc) ->
+ validate_max_keep_alive_length(Value),
+ validate_options(Tail, [Opt | Acc]);
+
+validate_options([{pipeline_timeout, Value} = Opt| Tail], Acc) ->
+ validate_pipeline_timeout(Value),
+ validate_options(Tail, [Opt | Acc]);
+
+validate_options([{max_pipeline_length, Value} = Opt| Tail], Acc) ->
+ validate_max_pipeline_length(Value),
+ validate_options(Tail, [Opt | Acc]);
+
+validate_options([{cookies, Value} = Opt| Tail], Acc) ->
+ validate_cookies(Value),
+ validate_options(Tail, [Opt | Acc]);
+
+validate_options([{ipfamily, Value} = Opt| Tail], Acc) ->
+ validate_ipfamily(Value),
+ validate_options(Tail, [Opt | Acc]);
+
+%% For backward compatibillity
+validate_options([{ipv6, Value}| Tail], Acc) ->
+ NewValue = validate_ipv6(Value),
+ Opt = {ipfamily, NewValue},
+ validate_options(Tail, [Opt | Acc]);
+
+validate_options([{ip, Value} = Opt| Tail], Acc) ->
+ validate_ip(Value),
+ validate_options(Tail, [Opt | Acc]);
+
+validate_options([{port, Value} = Opt| Tail], Acc) ->
+ validate_port(Value),
+ validate_options(Tail, [Opt | Acc]);
+
+validate_options([{socket_opts, Value} = Opt| Tail], Acc) ->
+ validate_socket_opts(Value),
+ validate_options(Tail, [Opt | Acc]);
+
+validate_options([{verbose, Value} = Opt| Tail], Acc) ->
+ validate_verbose(Value),
+ validate_options(Tail, [Opt | Acc]);
+
+validate_options([{_, _} = Opt| _], _Acc) ->
+ {error, {not_an_option, Opt}}.
+
+
+validate_proxy({{ProxyHost, ProxyPort}, NoProxy} = Proxy)
+ when is_list(ProxyHost) andalso
+ is_integer(ProxyPort) andalso
+ is_list(NoProxy) ->
+ Proxy;
+validate_proxy(BadProxy) ->
+ bad_option(proxy, BadProxy).
+
+validate_max_sessions(Value) when is_integer(Value) andalso (Value >= 0) ->
+ Value;
+validate_max_sessions(BadValue) ->
+ bad_option(max_sessions, BadValue).
+
+validate_keep_alive_timeout(Value) when is_integer(Value) andalso (Value >= 0) ->
+ Value;
+validate_keep_alive_timeout(infinity = Value) ->
+ Value;
+validate_keep_alive_timeout(BadValue) ->
+ bad_option(keep_alive_timeout, BadValue).
+
+validate_max_keep_alive_length(Value) when is_integer(Value) andalso (Value >= 0) ->
+ Value;
+validate_max_keep_alive_length(BadValue) ->
+ bad_option(max_keep_alive_length, BadValue).
+
+validate_pipeline_timeout(Value) when is_integer(Value) ->
+ Value;
+validate_pipeline_timeout(infinity = Value) ->
+ Value;
+validate_pipeline_timeout(BadValue) ->
+ bad_option(pipeline_timeout, BadValue).
+
+validate_max_pipeline_length(Value) when is_integer(Value) ->
+ Value;
+validate_max_pipeline_length(BadValue) ->
+ bad_option(max_pipeline_length, BadValue).
+
+validate_cookies(Value)
+ when ((Value =:= enabled) orelse
+ (Value =:= disabled) orelse
+ (Value =:= verify)) ->
+ Value;
+validate_cookies(BadValue) ->
+ bad_option(cookies, BadValue).
+
+validate_ipv6(Value) when (Value =:= enabled) orelse (Value =:= disabled) ->
+ case Value of
+ enabled ->
+ inet6fb4;
+ disabled ->
+ inet
+ end;
+validate_ipv6(BadValue) ->
+ bad_option(ipv6, BadValue).
+
+validate_ipfamily(Value)
+ when (Value =:= inet) orelse (Value =:= inet6) orelse (Value =:= inet6fb4) ->
+ Value;
+validate_ipfamily(BadValue) ->
+ bad_option(ipfamily, BadValue).
+
+validate_ip(Value)
+ when is_tuple(Value) andalso ((size(Value) =:= 4) orelse (size(Value) =:= 8)) ->
+ Value;
+validate_ip(BadValue) ->
+ bad_option(ip, BadValue).
+
+validate_port(Value) when is_integer(Value) ->
+ Value;
+validate_port(BadValue) ->
+ bad_option(port, BadValue).
+
+validate_socket_opts(Value) when is_list(Value) ->
+ Value;
+validate_socket_opts(BadValue) ->
+ bad_option(socket_opts, BadValue).
+
+validate_verbose(Value)
+ when ((Value =:= false) orelse
+ (Value =:= verbose) orelse
+ (Value =:= debug) orelse
+ (Value =:= trace)) ->
+ ok;
+validate_verbose(BadValue) ->
+ bad_option(verbose, BadValue).
+
+bad_option(Option, BadValue) ->
+ throw({error, {bad_option, Option, BadValue}}).
+
+
+header_host(https, Host, 443 = _Port) ->
+ Host;
+header_host(http, Host, 80 = _Port) ->
+ Host;
+header_host(_Scheme, Host, Port) ->
+ Host ++ ":" ++ integer_to_list(Port).
+
+
+header_record(NewHeaders, Host, #http_options{version = Version}) ->
+ header_record(NewHeaders, #http_request_h{}, Host, Version).
+
+header_record([], RequestHeaders, Host, Version) ->
+ validate_headers(RequestHeaders, Host, Version);
+header_record([{"cache-control", Val} | Rest], RequestHeaders, Host, Version) ->
+ header_record(Rest, RequestHeaders#http_request_h{'cache-control' = Val},
+ Host, Version);
+header_record([{"connection", Val} | Rest], RequestHeaders, Host, Version) ->
+ header_record(Rest, RequestHeaders#http_request_h{connection = Val}, Host,
+ Version);
+header_record([{"date", Val} | Rest], RequestHeaders, Host, Version) ->
+ header_record(Rest, RequestHeaders#http_request_h{date = Val}, Host,
+ Version);
+header_record([{"pragma", Val} | Rest], RequestHeaders, Host, Version) ->
+ header_record(Rest, RequestHeaders#http_request_h{pragma = Val}, Host,
+ Version);
+header_record([{"trailer", Val} | Rest], RequestHeaders, Host, Version) ->
+ header_record(Rest, RequestHeaders#http_request_h{trailer = Val}, Host,
+ Version);
+header_record([{"transfer-encoding", Val} | Rest], RequestHeaders, Host,
+ Version) ->
+ header_record(Rest,
+ RequestHeaders#http_request_h{'transfer-encoding' = Val},
+ Host, Version);
+header_record([{"upgrade", Val} | Rest], RequestHeaders, Host, Version) ->
+ header_record(Rest, RequestHeaders#http_request_h{upgrade = Val}, Host,
+ Version);
+header_record([{"via", Val} | Rest], RequestHeaders, Host, Version) ->
+ header_record(Rest, RequestHeaders#http_request_h{via = Val}, Host,
+ Version);
+header_record([{"warning", Val} | Rest], RequestHeaders, Host, Version) ->
+ header_record(Rest, RequestHeaders#http_request_h{warning = Val}, Host,
+ Version);
+header_record([{"accept", Val} | Rest], RequestHeaders, Host, Version) ->
+ header_record(Rest, RequestHeaders#http_request_h{accept = Val}, Host,
+ Version);
+header_record([{"accept-charset", Val} | Rest], RequestHeaders, Host, Version) ->
+ header_record(Rest, RequestHeaders#http_request_h{'accept-charset' = Val},
+ Host, Version);
+header_record([{"accept-encoding", Val} | Rest], RequestHeaders, Host,
+ Version) ->
+ header_record(Rest, RequestHeaders#http_request_h{'accept-encoding' = Val},
+ Host, Version);
+header_record([{"accept-language", Val} | Rest], RequestHeaders, Host,
+ Version) ->
+ header_record(Rest, RequestHeaders#http_request_h{'accept-language' = Val},
+ Host, Version);
+header_record([{"authorization", Val} | Rest], RequestHeaders, Host, Version) ->
+ header_record(Rest, RequestHeaders#http_request_h{authorization = Val},
+ Host, Version);
+header_record([{"expect", Val} | Rest], RequestHeaders, Host, Version) ->
+ header_record(Rest, RequestHeaders#http_request_h{expect = Val}, Host,
+ Version);
+header_record([{"from", Val} | Rest], RequestHeaders, Host, Version) ->
+ header_record(Rest, RequestHeaders#http_request_h{from = Val}, Host,
+ Version);
+header_record([{"host", Val} | Rest], RequestHeaders, Host, Version) ->
+ header_record(Rest, RequestHeaders#http_request_h{host = Val}, Host,
+ Version);
+header_record([{"if-match", Val} | Rest], RequestHeaders, Host, Version) ->
+ header_record(Rest, RequestHeaders#http_request_h{'if-match' = Val},
+ Host, Version);
+header_record([{"if-modified-since", Val} | Rest], RequestHeaders, Host,
+ Version) ->
+ header_record(Rest,
+ RequestHeaders#http_request_h{'if-modified-since' = Val},
+ Host, Version);
+header_record([{"if-none-match", Val} | Rest], RequestHeaders, Host, Version) ->
+ header_record(Rest, RequestHeaders#http_request_h{'if-none-match' = Val},
+ Host, Version);
+header_record([{"if-range", Val} | Rest], RequestHeaders, Host, Version) ->
+ header_record(Rest, RequestHeaders#http_request_h{'if-range' = Val},
+ Host, Version);
+
+header_record([{"if-unmodified-since", Val} | Rest], RequestHeaders, Host,
+ Version) ->
+ header_record(Rest, RequestHeaders#http_request_h{'if-unmodified-since'
+ = Val}, Host, Version);
+header_record([{"max-forwards", Val} | Rest], RequestHeaders, Host, Version) ->
+ header_record(Rest, RequestHeaders#http_request_h{'max-forwards' = Val},
+ Host, Version);
+header_record([{"proxy-authorization", Val} | Rest], RequestHeaders, Host,
+ Version) ->
+ header_record(Rest, RequestHeaders#http_request_h{'proxy-authorization'
+ = Val}, Host, Version);
+header_record([{"range", Val} | Rest], RequestHeaders, Host, Version) ->
+ header_record(Rest, RequestHeaders#http_request_h{range = Val}, Host,
+ Version);
+header_record([{"referer", Val} | Rest], RequestHeaders, Host, Version) ->
+ header_record(Rest, RequestHeaders#http_request_h{referer = Val}, Host,
+ Version);
+header_record([{"te", Val} | Rest], RequestHeaders, Host, Version) ->
+ header_record(Rest, RequestHeaders#http_request_h{te = Val}, Host,
+ Version);
+header_record([{"user-agent", Val} | Rest], RequestHeaders, Host, Version) ->
+ header_record(Rest, RequestHeaders#http_request_h{'user-agent' = Val},
+ Host, Version);
+header_record([{"allow", Val} | Rest], RequestHeaders, Host, Version) ->
+ header_record(Rest, RequestHeaders#http_request_h{allow = Val}, Host,
+ Version);
+header_record([{"content-encoding", Val} | Rest], RequestHeaders, Host,
+ Version) ->
+ header_record(Rest,
+ RequestHeaders#http_request_h{'content-encoding' = Val},
+ Host, Version);
+header_record([{"content-language", Val} | Rest], RequestHeaders,
+ Host, Version) ->
+ header_record(Rest,
+ RequestHeaders#http_request_h{'content-language' = Val},
+ Host, Version);
+header_record([{"content-length", Val} | Rest], RequestHeaders, Host, Version) ->
+ header_record(Rest, RequestHeaders#http_request_h{'content-length' = Val},
+ Host, Version);
+header_record([{"content-location", Val} | Rest], RequestHeaders,
+ Host, Version) ->
+ header_record(Rest,
+ RequestHeaders#http_request_h{'content-location' = Val},
+ Host, Version);
+header_record([{"content-md5", Val} | Rest], RequestHeaders, Host, Version) ->
+ header_record(Rest, RequestHeaders#http_request_h{'content-md5' = Val},
+ Host, Version);
+header_record([{"content-range", Val} | Rest], RequestHeaders, Host, Version) ->
+ header_record(Rest, RequestHeaders#http_request_h{'content-range' = Val},
+ Host, Version);
+header_record([{"content-type", Val} | Rest], RequestHeaders, Host, Version) ->
+ header_record(Rest, RequestHeaders#http_request_h{'content-type' = Val},
+ Host, Version);
+header_record([{"expires", Val} | Rest], RequestHeaders, Host, Version) ->
+ header_record(Rest, RequestHeaders#http_request_h{expires = Val}, Host,
+ Version);
+header_record([{"last-modified", Val} | Rest], RequestHeaders, Host, Version) ->
+ header_record(Rest, RequestHeaders#http_request_h{'last-modified' = Val},
+ Host, Version);
+header_record([{Key, Val} | Rest], RequestHeaders, Host, Version) ->
+ header_record(Rest, RequestHeaders#http_request_h{
+ other = [{Key, Val} |
+ RequestHeaders#http_request_h.other]},
+ Host, Version).
+
+validate_headers(RequestHeaders = #http_request_h{te = undefined}, Host,
+ "HTTP/1.1" = Version) ->
+ validate_headers(RequestHeaders#http_request_h{te = ""}, Host,
+ "HTTP/1.1" = Version);
+validate_headers(RequestHeaders = #http_request_h{host = undefined},
+ Host, "HTTP/1.1" = Version) ->
+ validate_headers(RequestHeaders#http_request_h{host = Host}, Host, Version);
+validate_headers(RequestHeaders, _, _) ->
+ RequestHeaders.
+
+
+child_name2info(undefined) ->
+ {error, no_such_service};
+child_name2info(httpc_manager) ->
+ {ok, [{profile, default}]};
+child_name2info({httpc, Profile}) ->
+ {ok, [{profile, Profile}]}.
+
+child_name(_, []) ->
+ undefined;
+child_name(Pid, [{Name, Pid} | _]) ->
+ Name;
+child_name(Pid, [_ | Children]) ->
+ child_name(Pid, Children).
+
+%% d(F) ->
+%% d(F, []).
+
+%% d(F, A) ->
+%% d(get(dbg), F, A).
+
+%% d(true, F, A) ->
+%% io:format(user, "~w:~w:" ++ F ++ "~n", [self(), ?MODULE | A]);
+%% d(_, _, _) ->
+%% ok.
+
diff --git a/lib/inets/src/http_client/httpc_cookie.erl b/lib/inets/src/http_client/httpc_cookie.erl
new file mode 100644
index 0000000000..4d61f82b5a
--- /dev/null
+++ b/lib/inets/src/http_client/httpc_cookie.erl
@@ -0,0 +1,495 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 2004-2010. All Rights Reserved.
+%%
+%% The contents of this file are subject to the Erlang Public License,
+%% Version 1.1, (the "License"); you may not use this file except in
+%% compliance with the License. You should have received a copy of the
+%% Erlang Public License along with this software. If not, it can be
+%% retrieved online at http://www.erlang.org/.
+%%
+%% Software distributed under the License is distributed on an "AS IS"
+%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+%% the License for the specific language governing rights and limitations
+%% under the License.
+%%
+%% %CopyrightEnd%
+%%
+%% Description: Cookie handling according to RFC 2109
+
+-module(httpc_cookie).
+
+-include("httpc_internal.hrl").
+
+-export([open_db/3, close_db/1, insert/2, header/4, cookies/3]).
+-export([reset_db/1, which_cookies/1]).
+
+-record(cookie_db, {db, session_db}).
+
+
+%%%=========================================================================
+%%% API
+%%%=========================================================================
+
+%%--------------------------------------------------------------------
+%% Func: open_db(DbName, DbDir, SessionDbName) -> #cookie_db{}
+%% Purpose: Create the cookie db
+%%--------------------------------------------------------------------
+
+open_db(_, only_session_cookies, SessionDbName) ->
+ ?hcrt("open (session cookies only) db",
+ [{session_db_name, SessionDbName}]),
+ SessionDb = ets:new(SessionDbName,
+ [protected, bag, {keypos, #http_cookie.domain}]),
+ #cookie_db{session_db = SessionDb};
+
+open_db(Name, Dir, SessionDbName) ->
+ ?hcrt("open db",
+ [{name, Name}, {dir, Dir}, {session_db_name, SessionDbName}]),
+ File = filename:join(Dir, atom_to_list(Name)),
+ case dets:open_file(Name, [{keypos, #http_cookie.domain},
+ {type, bag},
+ {file, File},
+ {ram_file, true}]) of
+ {ok, Db} ->
+ SessionDb = ets:new(SessionDbName,
+ [protected, bag,
+ {keypos, #http_cookie.domain}]),
+ #cookie_db{db = Db, session_db = SessionDb};
+ {error, Reason} ->
+ throw({error, {failed_open_file, Name, File, Reason}})
+ end.
+
+
+%%--------------------------------------------------------------------
+%% Func: reset_db(CookieDb) -> void()
+%% Purpose: Reset (empty) the cookie database
+%%
+%%--------------------------------------------------------------------
+
+reset_db(#cookie_db{db = undefined, session_db = SessionDb}) ->
+ ets:delete_all_objects(SessionDb),
+ ok;
+reset_db(#cookie_db{db = Db, session_db = SessionDb}) ->
+ dets:delete_all_objects(Db),
+ ets:delete_all_objects(SessionDb),
+ ok.
+
+
+%%--------------------------------------------------------------------
+%% Func: close_db(CookieDb) -> ok
+%% Purpose: Close the cookie db
+%%--------------------------------------------------------------------
+
+close_db(#cookie_db{db = Db, session_db = SessionDb}) ->
+ ?hcrt("close db", []),
+ maybe_dets_close(Db),
+ ets:delete(SessionDb),
+ ok.
+
+maybe_dets_close(undefined) ->
+ ok;
+maybe_dets_close(Db) ->
+ dets:close(Db).
+
+
+%%--------------------------------------------------------------------
+%% Func: insert(CookieDb) -> ok
+%% Purpose: Close the cookie db
+%%--------------------------------------------------------------------
+
+%% If no persistent cookie database is defined we
+%% treat all cookies as if they where session cookies.
+insert(#cookie_db{db = undefined} = CookieDb,
+ #http_cookie{max_age = Int} = Cookie) when is_integer(Int) ->
+ insert(CookieDb, Cookie#http_cookie{max_age = session});
+
+insert(#cookie_db{session_db = SessionDb} = CookieDb,
+ #http_cookie{domain = Key,
+ name = Name,
+ path = Path,
+ max_age = session} = Cookie) ->
+ ?hcrt("insert session cookie", [{cookie, Cookie}]),
+ Pattern = #http_cookie{domain = Key, name = Name, path = Path, _ = '_'},
+ case ets:match_object(SessionDb, Pattern) of
+ [] ->
+ ets:insert(SessionDb, Cookie);
+ [NewCookie] ->
+ delete(CookieDb, NewCookie),
+ ets:insert(SessionDb, Cookie)
+ end,
+ ok;
+insert(#cookie_db{db = Db} = CookieDb,
+ #http_cookie{domain = Key,
+ name = Name,
+ path = Path,
+ max_age = 0}) ->
+ ?hcrt("insert", [{domain, Key}, {name, Name}, {path, Path}]),
+ Pattern = #http_cookie{domain = Key, name = Name, path = Path, _ = '_'},
+ case dets:match_object(Db, Pattern) of
+ [] ->
+ ok;
+ [NewCookie] ->
+ delete(CookieDb, NewCookie)
+ end,
+ ok;
+insert(#cookie_db{db = Db} = CookieDb,
+ #http_cookie{domain = Key, name = Name, path = Path} = Cookie) ->
+ ?hcrt("insert", [{cookie, Cookie}]),
+ Pattern = #http_cookie{domain = Key,
+ name = Name,
+ path = Path,
+ _ = '_'},
+ case dets:match_object(Db, Pattern) of
+ [] ->
+ dets:insert(Db, Cookie);
+ [OldCookie] ->
+ delete(CookieDb, OldCookie),
+ dets:insert(Db, Cookie)
+ end,
+ ok.
+
+
+
+%%--------------------------------------------------------------------
+%% Func: header(CookieDb) -> ok
+%% Purpose: Cookies
+%%--------------------------------------------------------------------
+
+header(CookieDb, Scheme, {Host, _}, Path) ->
+ ?hcrd("header", [{scheme, Scheme}, {host, Host}, {path, Path}]),
+ case lookup_cookies(CookieDb, Host, Path) of
+ [] ->
+ {"cookie", ""};
+ Cookies ->
+ {"cookie", cookies_to_string(Scheme, Cookies)}
+ end.
+
+
+%%--------------------------------------------------------------------
+%% Func: cookies(Headers, RequestPath, RequestHost) -> [cookie()]
+%% Purpose: Which cookies are stored
+%%--------------------------------------------------------------------
+
+cookies(Headers, RequestPath, RequestHost) ->
+ ?hcrt("cookies", [{headers, Headers},
+ {request_path, RequestPath},
+ {request_host, RequestHost}]),
+ Cookies = parse_set_cookies(Headers, {RequestPath, RequestHost}),
+ accept_cookies(Cookies, RequestPath, RequestHost).
+
+
+%%--------------------------------------------------------------------
+%% Func: which_cookies(CookieDb) -> [cookie()]
+%% Purpose: For test and debug purpose,
+%% dump the entire cookie database
+%%--------------------------------------------------------------------
+
+which_cookies(#cookie_db{db = undefined, session_db = SessionDb}) ->
+ SessionCookies = ets:tab2list(SessionDb),
+ [{session_cookies, SessionCookies}];
+which_cookies(#cookie_db{db = Db, session_db = SessionDb}) ->
+ Cookies = dets:match_object(Db, '_'),
+ SessionCookies = ets:tab2list(SessionDb),
+ [{cookies, Cookies}, {session_cookies, SessionCookies}].
+
+
+%%%========================================================================
+%%% Internal functions
+%%%========================================================================
+
+delete(#cookie_db{session_db = SessionDb},
+ #http_cookie{max_age = session} = Cookie) ->
+ ets:delete_object(SessionDb, Cookie);
+delete(#cookie_db{db = Db}, Cookie) ->
+ dets:delete_object(Db, Cookie).
+
+
+lookup_cookies(#cookie_db{db = undefined, session_db = SessionDb}, Key) ->
+ Pattern = #http_cookie{domain = Key, _ = '_'},
+ Cookies = ets:match_object(SessionDb, Pattern),
+ ?hcrt("lookup cookies", [{cookies, Cookies}]),
+ Cookies;
+
+lookup_cookies(#cookie_db{db = Db, session_db = SessionDb}, Key) ->
+ Pattern = #http_cookie{domain = Key, _ = '_'},
+ SessionCookies = ets:match_object(SessionDb, Pattern),
+ ?hcrt("lookup cookies", [{session_cookies, SessionCookies}]),
+ Cookies = dets:match_object(Db, Pattern),
+ ?hcrt("lookup cookies", [{cookies, Cookies}]),
+ Cookies ++ SessionCookies.
+
+
+lookup_cookies(CookieDb, Host, Path) ->
+ Cookies =
+ case http_util:is_hostname(Host) of
+ true ->
+ HostCookies = lookup_cookies(CookieDb, Host),
+ [_| DomainParts] = string:tokens(Host, "."),
+ lookup_domain_cookies(CookieDb, DomainParts, HostCookies);
+ false -> % IP-adress
+ lookup_cookies(CookieDb, Host)
+ end,
+ ValidCookies = valid_cookies(CookieDb, Cookies),
+ lists:filter(fun(Cookie) ->
+ lists:prefix(Cookie#http_cookie.path, Path)
+ end, ValidCookies).
+
+%% For instance if Host=localhost
+lookup_domain_cookies(_CookieDb, [], AccCookies) ->
+ lists:flatten(AccCookies);
+
+%% Top domains can not have cookies
+lookup_domain_cookies(_CookieDb, [_], AccCookies) ->
+ lists:flatten(AccCookies);
+
+lookup_domain_cookies(CookieDb, [Next | DomainParts], AccCookies) ->
+ Domain = merge_domain_parts(DomainParts, [Next ++ "."]),
+ lookup_domain_cookies(CookieDb, DomainParts,
+ [lookup_cookies(CookieDb, Domain) | AccCookies]).
+
+merge_domain_parts([Part], Merged) ->
+ lists:flatten(["." | lists:reverse([Part | Merged])]);
+merge_domain_parts([Part| Rest], Merged) ->
+ merge_domain_parts(Rest, [".", Part | Merged]).
+
+cookies_to_string(Scheme, [Cookie | _] = Cookies) ->
+ Version = "$Version=" ++ Cookie#http_cookie.version ++ "; ",
+ cookies_to_string(Scheme, path_sort(Cookies), [Version]).
+
+cookies_to_string(_, [], CookieStrs) ->
+ case length(CookieStrs) of
+ 1 ->
+ "";
+ _ ->
+ lists:flatten(lists:reverse(CookieStrs))
+ end;
+
+cookies_to_string(https, [#http_cookie{secure = true} = Cookie| Cookies],
+ CookieStrs) ->
+ Str = case Cookies of
+ [] ->
+ cookie_to_string(Cookie);
+ _ ->
+ cookie_to_string(Cookie) ++ "; "
+ end,
+ cookies_to_string(https, Cookies, [Str | CookieStrs]);
+
+cookies_to_string(Scheme, [#http_cookie{secure = true}| Cookies],
+ CookieStrs) ->
+ cookies_to_string(Scheme, Cookies, CookieStrs);
+
+cookies_to_string(Scheme, [Cookie | Cookies], CookieStrs) ->
+ Str = case Cookies of
+ [] ->
+ cookie_to_string(Cookie);
+ _ ->
+ cookie_to_string(Cookie) ++ "; "
+ end,
+ cookies_to_string(Scheme, Cookies, [Str | CookieStrs]).
+
+cookie_to_string(#http_cookie{name = Name, value = Value} = Cookie) ->
+ Str = Name ++ "=" ++ Value,
+ add_domain(add_path(Str, Cookie), Cookie).
+
+add_path(Str, #http_cookie{path_default = true}) ->
+ Str;
+add_path(Str, #http_cookie{path = Path}) ->
+ Str ++ "; $Path=" ++ Path.
+
+add_domain(Str, #http_cookie{domain_default = true}) ->
+ Str;
+add_domain(Str, #http_cookie{domain = Domain}) ->
+ Str ++ "; $Domain=" ++ Domain.
+
+parse_set_cookies(OtherHeaders, DefaultPathDomain) ->
+ SetCookieHeaders =
+ lists:foldl(fun({"set-cookie", Value}, Acc) ->
+ [string:tokens(Value, ",")| Acc];
+ (_, Acc) ->
+ Acc
+ end, [], OtherHeaders),
+
+ lists:flatten(
+ lists:map(fun(CookieHeader) ->
+ NewHeader = fix_netscape_cookie(CookieHeader, []),
+ parse_set_cookie(NewHeader, [], DefaultPathDomain)
+ end,
+ SetCookieHeaders)).
+
+parse_set_cookie([], AccCookies, _) ->
+ AccCookies;
+parse_set_cookie([CookieHeader | CookieHeaders], AccCookies,
+ Defaults = {DefaultPath, DefaultDomain}) ->
+ [CookieStr | Attributes] = case string:tokens(CookieHeader, ";") of
+ [CStr] ->
+ [CStr, ""];
+ [CStr | Attr] ->
+ [CStr, Attr]
+ end,
+ Pos = string:chr(CookieStr, $=),
+ Name = string:substr(CookieStr, 1, Pos - 1),
+ Value = string:substr(CookieStr, Pos + 1),
+ Cookie = #http_cookie{name = string:strip(Name),
+ value = string:strip(Value)},
+ NewAttributes = parse_set_cookie_attributes(Attributes),
+ TmpCookie = cookie_attributes(NewAttributes, Cookie),
+ %% Add runtime defult values if necessary
+ NewCookie = domain_default(path_default(TmpCookie, DefaultPath),
+ DefaultDomain),
+ parse_set_cookie(CookieHeaders, [NewCookie | AccCookies], Defaults).
+
+parse_set_cookie_attributes([]) ->
+ [];
+parse_set_cookie_attributes([Attributes]) ->
+ lists:map(fun(Attr) ->
+ [AttrName, AttrValue] =
+ case string:tokens(Attr, "=") of
+ %% All attributes have the form
+ %% Name=Value except "secure"!
+ [Name] ->
+ [Name, ""];
+ [Name, Value] ->
+ [Name, Value];
+ %% Anything not expected will be
+ %% disregarded
+ _ ->
+ ["Dummy",""]
+ end,
+ {http_util:to_lower(string:strip(AttrName)),
+ string:strip(AttrValue)}
+ end, Attributes).
+
+cookie_attributes([], Cookie) ->
+ Cookie;
+cookie_attributes([{"comment", Value}| Attributes], Cookie) ->
+ cookie_attributes(Attributes,
+ Cookie#http_cookie{comment = Value});
+cookie_attributes([{"domain", Value}| Attributes], Cookie) ->
+ cookie_attributes(Attributes,
+ Cookie#http_cookie{domain = Value});
+cookie_attributes([{"max-age", Value}| Attributes], Cookie) ->
+ ExpireTime = cookie_expires(list_to_integer(Value)),
+ cookie_attributes(Attributes,
+ Cookie#http_cookie{max_age = ExpireTime});
+%% Backwards compatibility with netscape cookies
+cookie_attributes([{"expires", Value}| Attributes], Cookie) ->
+ Time = http_util:convert_netscapecookie_date(Value),
+ ExpireTime = calendar:datetime_to_gregorian_seconds(Time),
+ cookie_attributes(Attributes,
+ Cookie#http_cookie{max_age = ExpireTime});
+cookie_attributes([{"path", Value}| Attributes], Cookie) ->
+ cookie_attributes(Attributes,
+ Cookie#http_cookie{path = Value});
+cookie_attributes([{"secure", _}| Attributes], Cookie) ->
+ cookie_attributes(Attributes,
+ Cookie#http_cookie{secure = true});
+cookie_attributes([{"version", Value}| Attributes], Cookie) ->
+ cookie_attributes(Attributes,
+ Cookie#http_cookie{version = Value});
+%% Disregard unknown attributes.
+cookie_attributes([_| Attributes], Cookie) ->
+ cookie_attributes(Attributes, Cookie).
+
+domain_default(Cookie = #http_cookie{domain = undefined},
+ DefaultDomain) ->
+ Cookie#http_cookie{domain = DefaultDomain, domain_default = true};
+domain_default(Cookie, _) ->
+ Cookie.
+
+path_default(#http_cookie{path = undefined} = Cookie, DefaultPath) ->
+ Cookie#http_cookie{path = skip_right_most_slash(DefaultPath),
+ path_default = true};
+path_default(Cookie, _) ->
+ Cookie.
+
+%% Note: if the path is only / that / will be keept
+skip_right_most_slash("/") ->
+ "/";
+skip_right_most_slash(Str) ->
+ string:strip(Str, right, $/).
+
+accept_cookies(Cookies, RequestPath, RequestHost) ->
+ lists:filter(fun(Cookie) ->
+ accept_cookie(Cookie, RequestPath, RequestHost)
+ end, Cookies).
+
+accept_cookie(Cookie, RequestPath, RequestHost) ->
+ Accepted =
+ accept_path(Cookie, RequestPath) andalso
+ accept_domain(Cookie, RequestHost),
+ Accepted.
+
+accept_path(#http_cookie{path = Path}, RequestPath) ->
+ lists:prefix(Path, RequestPath).
+
+accept_domain(#http_cookie{domain = RequestHost}, RequestHost) ->
+ true;
+
+accept_domain(#http_cookie{domain = Domain}, RequestHost) ->
+ HostCheck =
+ case http_util:is_hostname(RequestHost) of
+ true ->
+ (lists:suffix(Domain, RequestHost) andalso
+ (not
+ lists:member($.,
+ string:substr(RequestHost, 1,
+ (length(RequestHost) -
+ length(Domain))))));
+ false ->
+ false
+ end,
+ HostCheck
+ andalso (hd(Domain) =:= $.)
+ andalso (length(string:tokens(Domain, ".")) > 1).
+
+cookie_expires(0) ->
+ 0;
+cookie_expires(DeltaSec) ->
+ NowSec = calendar:datetime_to_gregorian_seconds({date(), time()}),
+ NowSec + DeltaSec.
+
+is_cookie_expired(#http_cookie{max_age = session}) ->
+ false;
+is_cookie_expired(#http_cookie{max_age = ExpireTime}) ->
+ NowSec = calendar:datetime_to_gregorian_seconds({date(), time()}),
+ ExpireTime - NowSec =< 0.
+
+
+valid_cookies(Db, Cookies) ->
+ valid_cookies(Db, Cookies, []).
+
+valid_cookies(_Db, [], Valid) ->
+ Valid;
+
+valid_cookies(Db, [Cookie | Cookies], Valid) ->
+ case is_cookie_expired(Cookie) of
+ true ->
+ delete(Db, Cookie),
+ valid_cookies(Db, Cookies, Valid);
+ false ->
+ valid_cookies(Db, Cookies, [Cookie | Valid])
+ end.
+
+path_sort(Cookies)->
+ lists:reverse(lists:keysort(#http_cookie.path, Cookies)).
+
+
+%% Informally, the Set-Cookie response header comprises the token
+%% Set-Cookie:, followed by a comma-separated list of one or more
+%% cookies. Netscape cookies expires attribute may also have a,
+%% in this case the header list will have been incorrectly split
+%% in parse_set_cookies/2 this functions fix that problem.
+fix_netscape_cookie([Cookie1, Cookie2 | Rest], Acc) ->
+ case inets_regexp:match(string:to_lower(Cookie1), "expires=") of
+ {_, _, _} ->
+ fix_netscape_cookie(Rest, [Cookie1 ++ Cookie2 | Acc]);
+ nomatch ->
+ fix_netscape_cookie([Cookie2 |Rest], [Cookie1| Acc])
+ end;
+fix_netscape_cookie([Cookie | Rest], Acc) ->
+ fix_netscape_cookie(Rest, [Cookie | Acc]);
+
+fix_netscape_cookie([], Acc) ->
+ Acc.
diff --git a/lib/inets/src/http_client/httpc_handler.erl b/lib/inets/src/http_client/httpc_handler.erl
index 7b737c2f86..5e5a9ce32e 100644
--- a/lib/inets/src/http_client/httpc_handler.erl
+++ b/lib/inets/src/http_client/httpc_handler.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2002-2009. All Rights Reserved.
+%% Copyright Ericsson AB 2002-2011. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
@@ -28,7 +28,15 @@
%%--------------------------------------------------------------------
%% Internal Application API
--export([start_link/3, send/2, cancel/2, stream/3, stream_next/1]).
+-export([
+ start_link/2,
+ connect_and_send/2,
+ send/2,
+ cancel/2,
+ stream/3,
+ stream_next/1,
+ info/1
+ ]).
%% gen_server callbacks
-export([init/1, handle_call/3, handle_cast/2, handle_info/2,
@@ -50,7 +58,7 @@
mfa, % {Moduel, Function, Args}
pipeline = queue:new(), % queue()
keep_alive = queue:new(), % queue()
- status = new, % new | pipeline | keep_alive | close | ssl_tunnel
+ status, % undefined | new | pipeline | keep_alive | close | ssl_tunnel
canceled = [], % [RequestId]
max_header_size = nolimit, % nolimit | integer()
max_body_size = nolimit, % nolimit | integer()
@@ -85,9 +93,13 @@
%% the reply or part of it has arrived.)
%%--------------------------------------------------------------------
%%--------------------------------------------------------------------
-start_link(Request, Options, ProfileName) ->
- {ok, proc_lib:spawn_link(?MODULE, init, [[Request, Options,
- ProfileName]])}.
+
+start_link(Options, ProfileName) ->
+ Args = [Options, ProfileName],
+ gen_server:start_link(?MODULE, Args, []).
+
+connect_and_send(Request, HandlerPid) ->
+ call({connect_and_send, Request}, HandlerPid).
%%--------------------------------------------------------------------
@@ -126,6 +138,18 @@ stream_next(Pid) ->
%%--------------------------------------------------------------------
+%% Function: info(Pid) -> [{Key, Val}]
+%% Pid = pid() - the pid of the http-request handler process.
+%%
+%% Description:
+%% Returns various information related to this handler
+%% Used for debugging and testing
+%%--------------------------------------------------------------------
+info(Pid) ->
+ call(info, Pid).
+
+
+%%--------------------------------------------------------------------
%% Function: stream(BodyPart, Request, Code) -> _
%% BodyPart = binary()
%% Request = #request{}
@@ -138,21 +162,21 @@ stream_next(Pid) ->
%%--------------------------------------------------------------------
%% Request should not be streamed
stream(BodyPart, Request = #request{stream = none}, _) ->
- ?hcrt("stream - none", [{body_part, BodyPart}]),
+ ?hcrt("stream - none", []),
{BodyPart, Request};
%% Stream to caller
stream(BodyPart, Request = #request{stream = Self}, Code)
when ((Code =:= 200) orelse (Code =:= 206)) andalso
((Self =:= self) orelse (Self =:= {self, once})) ->
- ?hcrt("stream - self", [{stream, Self}, {code, Code}, {body_part, BodyPart}]),
+ ?hcrt("stream - self", [{stream, Self}, {code, Code}]),
httpc_response:send(Request#request.from,
{Request#request.id, stream, BodyPart}),
{<<>>, Request};
stream(BodyPart, Request = #request{stream = Self}, 404)
when (Self =:= self) orelse (Self =:= {self, once}) ->
- ?hcrt("stream - self with 404", [{stream, Self}, {body_part, BodyPart}]),
+ ?hcrt("stream - self with 404", [{stream, Self}]),
httpc_response:send(Request#request.from,
{Request#request.id, stream, BodyPart}),
{<<>>, Request};
@@ -162,7 +186,7 @@ stream(BodyPart, Request = #request{stream = Self}, 404)
%% We keep this for backward compatibillity...
stream(BodyPart, Request = #request{stream = Filename}, Code)
when ((Code =:= 200) orelse (Code =:= 206)) andalso is_list(Filename) ->
- ?hcrt("stream - filename", [{stream, Filename}, {code, Code}, {body_part, BodyPart}]),
+ ?hcrt("stream - filename", [{stream, Filename}, {code, Code}]),
case file:open(Filename, [write, raw, append, delayed_write]) of
{ok, Fd} ->
?hcrt("stream - file open ok", [{fd, Fd}]),
@@ -174,7 +198,7 @@ stream(BodyPart, Request = #request{stream = Filename}, Code)
%% Stream to file
stream(BodyPart, Request = #request{stream = Fd}, Code)
when ((Code =:= 200) orelse (Code =:= 206)) ->
- ?hcrt("stream to file", [{stream, Fd}, {code, Code}, {body_part, BodyPart}]),
+ ?hcrt("stream to file", [{stream, Fd}, {code, Code}]),
case file:write(Fd, BodyPart) of
ok ->
{<<>>, Request};
@@ -183,7 +207,7 @@ stream(BodyPart, Request = #request{stream = Fd}, Code)
end;
stream(BodyPart, Request,_) -> % only 200 and 206 responses can be streamed
- ?hcrt("stream - ignore", [{request, Request}, {body_part, BodyPart}]),
+ ?hcrt("stream - ignore", [{request, Request}]),
{BodyPart, Request}.
@@ -192,10 +216,9 @@ stream(BodyPart, Request,_) -> % only 200 and 206 responses can be streamed
%%====================================================================
%%--------------------------------------------------------------------
-%% Function: init([Request, Options, ProfileName]) -> {ok, State} |
-%% {ok, State, Timeout} | ignore |{stop, Reason}
+%% Function: init([Options, ProfileName]) -> {ok, State} |
+%% {ok, State, Timeout} | ignore | {stop, Reason}
%%
-%% Request = #request{}
%% Options = #options{}
%% ProfileName = atom() - id of httpc manager process
%%
@@ -206,30 +229,16 @@ stream(BodyPart, Request,_) -> % only 200 and 206 responses can be streamed
%% but we do not want that so errors will be handled by the process
%% sending an init_error message to itself.
%%--------------------------------------------------------------------
-init([Request, Options, ProfileName]) ->
+init([Options, ProfileName]) ->
+ ?hcrv("init - starting", [{options, Options}, {profile, ProfileName}]),
process_flag(trap_exit, true),
-
handle_verbose(Options#options.verbose),
- Address = handle_proxy(Request#request.address, Options#options.proxy),
- {ok, State} =
- case {Address /= Request#request.address, Request#request.scheme} of
- {true, https} ->
- Error = https_through_proxy_is_not_currently_supported,
- self() ! {init_error,
- Error, httpc_response:error(Request, Error)},
- {ok, #state{request = Request, options = Options,
- status = ssl_tunnel}};
- %% This is what we should do if and when ssl supports
- %% "socket upgrading"
- %%send_ssl_tunnel_request(Address, Request,
- %% #state{options = Options,
- %% status = ssl_tunnel});
- {_, _} ->
- send_first_request(Address, Request,
- #state{options = Options,
- profile_name = ProfileName})
- end,
- gen_server:enter_loop(?MODULE, [], State).
+ State = #state{status = undefined,
+ options = Options,
+ profile_name = ProfileName},
+ ?hcrd("init - started", []),
+ {ok, State}.
+
%%--------------------------------------------------------------------
%% Function: handle_call(Request, From, State) -> {reply, Reply, State} |
@@ -240,39 +249,90 @@ init([Request, Options, ProfileName]) ->
%% {stop, Reason, State} (terminate/2 is called)
%% Description: Handling call messages
%%--------------------------------------------------------------------
-handle_call(Request, _, State = #state{session = Session =
- #tcp_session{socket = Socket,
- type = pipeline},
- timers = Timers,
- options = Options,
- profile_name = ProfileName}) ->
- Address = handle_proxy(Request#request.address, Options#options.proxy),
+
+
+%% This is the first request, the reason the proc was started
+handle_call({connect_and_send, #request{address = Address0,
+ scheme = Scheme} = Request},
+ _From,
+ #state{options = #options{proxy = Proxy},
+ status = undefined,
+ session = undefined} = State) ->
+ ?hcrv("connect and send", [{address0, Address0}, {proxy, Proxy}]),
+ Address = handle_proxy(Address0, Proxy),
+ if
+ ((Address =/= Address0) andalso (Scheme =:= https)) ->
+ %% This is what we should do if and when ssl supports
+ %% "socket upgrading"
+ %%send_ssl_tunnel_request(Address, Request,
+ %% #state{options = Options,
+ %% status = ssl_tunnel});
+ Reason = {failed_connecting,
+ https_through_proxy_is_not_currently_supported},
+ %% Send a reply to the original caller
+ ErrorResponse = httpc_response:error(Request, Reason),
+ httpc_response:send(Request#request.from, ErrorResponse),
+ %% Reply to the manager
+ ErrorReply = {error, Reason},
+ {stop, normal, ErrorReply, State};
+ true ->
+ case connect_and_send_first_request(Address, Request, State) of
+ {ok, NewState} ->
+ {reply, ok, NewState};
+ {stop, Error, NewState} ->
+ {stop, normal, Error, NewState}
+ end
+ end;
+
+handle_call(#request{address = Addr} = Request, _,
+ #state{status = Status,
+ session = #tcp_session{socket = Socket,
+ type = pipeline} = Session,
+ timers = Timers,
+ options = #options{proxy = Proxy} = _Options,
+ profile_name = ProfileName} = State)
+ when Status =/= undefined ->
+
+ ?hcrv("new request on a pipeline session",
+ [{request, Request},
+ {profile, ProfileName},
+ {status, Status},
+ {timers, Timers}]),
+
+ Address = handle_proxy(Addr, Proxy),
case httpc_request:send(Address, Request, Socket) of
ok ->
+
+ ?hcrd("request sent", []),
+
%% Activate the request time out for the new request
- NewState = activate_request_timeout(State#state{request =
- Request}),
+ NewState =
+ activate_request_timeout(State#state{request = Request}),
+
+ ClientClose =
+ httpc_request:is_client_closing(Request#request.headers),
- ClientClose = httpc_request:is_client_closing(
- Request#request.headers),
case State#state.request of
- #request{} -> %% Old request no yet finished
+ #request{} -> %% Old request not yet finished
+ ?hcrd("old request still not finished", []),
%% Make sure to use the new value of timers in state
- NewTimers = NewState#state.timers,
+ NewTimers = NewState#state.timers,
NewPipeline = queue:in(Request, State#state.pipeline),
- NewSession =
+ NewSession =
Session#tcp_session{queue_length =
%% Queue + current
queue:len(NewPipeline) + 1,
client_close = ClientClose},
httpc_manager:insert_session(NewSession, ProfileName),
+ ?hcrd("session updated", []),
{reply, ok, State#state{pipeline = NewPipeline,
- session = NewSession,
- timers = NewTimers}};
+ session = NewSession,
+ timers = NewTimers}};
undefined ->
- %% Note: tcp-message reciving has already been
+ %% Note: tcp-message receiving has already been
%% activated by handle_pipeline/2.
+ ?hcrd("no current request", []),
cancel_timer(Timers#timers.queue_timer,
timeout_queue),
NewSession =
@@ -281,54 +341,67 @@ handle_call(Request, _, State = #state{session = Session =
httpc_manager:insert_session(NewSession, ProfileName),
Relaxed =
(Request#request.settings)#http_options.relaxed,
- {reply, ok,
- NewState#state{request = Request,
- session = NewSession,
- mfa = {httpc_response, parse,
- [State#state.max_header_size,
- Relaxed]},
- timers =
- Timers#timers{queue_timer =
- undefined}}}
+ MFA = {httpc_response, parse,
+ [State#state.max_header_size, Relaxed]},
+ NewTimers = Timers#timers{queue_timer = undefined},
+ ?hcrd("session created", []),
+ {reply, ok, NewState#state{request = Request,
+ session = NewSession,
+ mfa = MFA,
+ timers = NewTimers}}
end;
{error, Reason} ->
+ ?hcri("failed sending request", [{reason, Reason}]),
{reply, {pipeline_failed, Reason}, State}
end;
-handle_call(Request, _, #state{session = Session =
- #tcp_session{type = keep_alive,
- socket = Socket},
- timers = Timers,
- options = Options,
- profile_name = ProfileName} = State) ->
-
- ClientClose = httpc_request:is_client_closing(Request#request.headers),
+handle_call(#request{address = Addr} = Request, _,
+ #state{status = Status,
+ session = #tcp_session{socket = Socket,
+ type = keep_alive} = Session,
+ timers = Timers,
+ options = #options{proxy = Proxy} = _Options,
+ profile_name = ProfileName} = State)
+ when Status =/= undefined ->
- Address = handle_proxy(Request#request.address,
- Options#options.proxy),
+ ?hcrv("new request on a keep-alive session",
+ [{request, Request},
+ {profile, ProfileName},
+ {status, Status}]),
+
+ Address = handle_proxy(Addr, Proxy),
case httpc_request:send(Address, Request, Socket) of
ok ->
+
+ ?hcrd("request sent", []),
+
+ %% Activate the request time out for the new request
NewState =
- activate_request_timeout(State#state{request =
- Request}),
+ activate_request_timeout(State#state{request = Request}),
+
+ ClientClose =
+ httpc_request:is_client_closing(Request#request.headers),
case State#state.request of
#request{} -> %% Old request not yet finished
%% Make sure to use the new value of timers in state
- NewTimers = NewState#state.timers,
+ ?hcrd("old request still not finished", []),
+ NewTimers = NewState#state.timers,
NewKeepAlive = queue:in(Request, State#state.keep_alive),
- NewSession =
+ NewSession =
Session#tcp_session{queue_length =
%% Queue + current
queue:len(NewKeepAlive) + 1,
client_close = ClientClose},
httpc_manager:insert_session(NewSession, ProfileName),
+ ?hcrd("session updated", []),
{reply, ok, State#state{keep_alive = NewKeepAlive,
- session = NewSession,
- timers = NewTimers}};
+ session = NewSession,
+ timers = NewTimers}};
undefined ->
%% Note: tcp-message reciving has already been
%% activated by handle_pipeline/2.
+ ?hcrd("no current request", []),
cancel_timer(Timers#timers.queue_timer,
timeout_queue),
NewSession =
@@ -337,16 +410,23 @@ handle_call(Request, _, #state{session = Session =
httpc_manager:insert_session(NewSession, ProfileName),
Relaxed =
(Request#request.settings)#http_options.relaxed,
- {reply, ok,
- NewState#state{request = Request,
- session = NewSession,
- mfa = {httpc_response, parse,
- [State#state.max_header_size,
- Relaxed]}}}
+ MFA = {httpc_response, parse,
+ [State#state.max_header_size, Relaxed]},
+ {reply, ok, NewState#state{request = Request,
+ session = NewSession,
+ mfa = MFA}}
end;
- {error, Reason} ->
+
+ {error, Reason} ->
+ ?hcri("failed sending request", [{reason, Reason}]),
{reply, {request_failed, Reason}, State}
- end.
+ end;
+
+
+handle_call(info, _, State) ->
+ Info = handler_info(State),
+ {reply, Info, State}.
+
%%--------------------------------------------------------------------
%% Function: handle_cast(Msg, State) -> {noreply, State} |
@@ -367,19 +447,30 @@ handle_call(Request, _, #state{session = Session =
%% handle_keep_alive_queue/2 on the other hand will just skip the
%% request as if it was never issued as in this case the request will
%% not have been sent.
-handle_cast({cancel, RequestId}, State = #state{request = Request =
- #request{id = RequestId},
- profile_name = ProfileName}) ->
+handle_cast({cancel, RequestId},
+ #state{request = #request{id = RequestId} = Request,
+ profile_name = ProfileName,
+ canceled = Canceled} = State) ->
+ ?hcrv("cancel current request", [{request_id, RequestId},
+ {profile, ProfileName},
+ {canceled, Canceled}]),
httpc_manager:request_canceled(RequestId, ProfileName),
+ ?hcrv("canceled", []),
{stop, normal,
- State#state{canceled = [RequestId | State#state.canceled],
- request = Request#request{from = answer_sent}}};
-handle_cast({cancel, RequestId}, State = #state{profile_name = ProfileName}) ->
+ State#state{canceled = [RequestId | Canceled],
+ request = Request#request{from = answer_sent}}};
+handle_cast({cancel, RequestId},
+ #state{profile_name = ProfileName,
+ canceled = Canceled} = State) ->
+ ?hcrv("cancel", [{request_id, RequestId},
+ {profile, ProfileName},
+ {canceled, Canceled}]),
httpc_manager:request_canceled(RequestId, ProfileName),
- {noreply, State#state{canceled = [RequestId | State#state.canceled]}};
+ ?hcrv("canceled", []),
+ {noreply, State#state{canceled = [RequestId | Canceled]}};
+
handle_cast(stream_next, #state{session = Session} = State) ->
- http_transport:setopts(socket_type(Session#tcp_session.scheme),
- Session#tcp_session.socket, [{active, once}]),
+ activate_once(Session),
{noreply, State#state{once = once}}.
@@ -390,7 +481,7 @@ handle_cast(stream_next, #state{session = Session} = State) ->
%% Description: Handling all non call/cast messages
%%--------------------------------------------------------------------
handle_info({Proto, _Socket, Data},
- #state{mfa = {Module, Function, Args} = MFA,
+ #state{mfa = {Module, Function, Args},
request = #request{method = Method,
stream = Stream} = Request,
session = Session,
@@ -399,64 +490,68 @@ handle_info({Proto, _Socket, Data},
(Proto =:= ssl) orelse
(Proto =:= httpc_handler) ->
- ?hcri("received data", [{proto, Proto}, {data, Data}, {mfa, MFA}, {method, Method}, {stream, Stream}, {session, Session}, {status_line, StatusLine}]),
+ ?hcri("received data", [{proto, Proto},
+ {module, Module},
+ {function, Function},
+ {method, Method},
+ {stream, Stream},
+ {session, Session},
+ {status_line, StatusLine}]),
FinalResult =
try Module:Function([Data | Args]) of
{ok, Result} ->
- ?hcrd("data processed - ok", [{result, Result}]),
+ ?hcrd("data processed - ok", []),
handle_http_msg(Result, State);
{_, whole_body, _} when Method =:= head ->
?hcrd("data processed - whole body", []),
handle_response(State#state{body = <<>>});
{Module, whole_body, [Body, Length]} ->
- ?hcrd("data processed - whole body", [{module, Module}, {body, Body}, {length, Length}]),
+ ?hcrd("data processed - whole body", [{length, Length}]),
{_, Code, _} = StatusLine,
{NewBody, NewRequest} = stream(Body, Request, Code),
%% When we stream we will not keep the already
%% streamed data, that would be a waste of memory.
- NewLength = case Stream of
- none ->
- Length;
- _ ->
- Length - size(Body)
- end,
+ NewLength =
+ case Stream of
+ none ->
+ Length;
+ _ ->
+ Length - size(Body)
+ end,
NewState = next_body_chunk(State),
-
- {noreply, NewState#state{mfa = {Module, whole_body,
- [NewBody, NewLength]},
+ NewMFA = {Module, whole_body, [NewBody, NewLength]},
+ {noreply, NewState#state{mfa = NewMFA,
request = NewRequest}};
NewMFA ->
- ?hcrd("data processed", [{new_mfa, NewMFA}]),
- http_transport:setopts(socket_type(Session#tcp_session.scheme),
- Session#tcp_session.socket,
- [{active, once}]),
+ ?hcrd("data processed - new mfa", []),
+ activate_once(Session),
{noreply, State#state{mfa = NewMFA}}
catch
- exit:_ ->
- ClientErrMsg = httpc_response:error(Request,
- {could_not_parse_as_http,
- Data}),
- NewState = answer_request(Request, ClientErrMsg, State),
+ exit:_Exit ->
+ ?hcrd("data processing exit", [{exit, _Exit}]),
+ ClientReason = {could_not_parse_as_http, Data},
+ ClientErrMsg = httpc_response:error(Request, ClientReason),
+ NewState = answer_request(Request, ClientErrMsg, State),
{stop, normal, NewState};
- error:_ ->
- ClientErrMsg = httpc_response:error(Request,
- {could_not_parse_as_http,
- Data}),
- NewState = answer_request(Request, ClientErrMsg, State),
+ error:_Error ->
+ ?hcrd("data processing error", [{error, _Error}]),
+ ClientReason = {could_not_parse_as_http, Data},
+ ClientErrMsg = httpc_response:error(Request, ClientReason),
+ NewState = answer_request(Request, ClientErrMsg, State),
{stop, normal, NewState}
end,
- ?hcri("data processed", [{result, FinalResult}]),
+ ?hcri("data processed", []),
FinalResult;
handle_info({Proto, Socket, Data},
- #state{mfa = MFA,
- request = Request,
- session = Session,
- status = Status,
+ #state{mfa = MFA,
+ request = Request,
+ session = Session,
+ status = Status,
status_line = StatusLine,
profile_name = Profile} = State)
when (Proto =:= tcp) orelse
@@ -474,6 +569,7 @@ handle_info({Proto, Socket, Data},
"~n",
[Proto, Socket, Data, MFA,
Request, Session, Status, StatusLine, Profile]),
+
{noreply, State};
@@ -511,30 +607,42 @@ handle_info({ssl_error, _, _} = Reason, State) ->
%% Internally, to a request handling process, a request timeout is
%% seen as a canceled request.
handle_info({timeout, RequestId},
- #state{request = #request{id = RequestId} = Request,
- canceled = Canceled} = State) ->
+ #state{request = #request{id = RequestId} = Request,
+ canceled = Canceled,
+ profile_name = ProfileName} = State) ->
+ ?hcri("timeout of current request", [{id, RequestId}]),
httpc_response:send(Request#request.from,
- httpc_response:error(Request,timeout)),
+ httpc_response:error(Request, timeout)),
+ httpc_manager:request_done(RequestId, ProfileName),
+ ?hcrv("response (timeout) sent - now terminate", []),
{stop, normal,
State#state{request = Request#request{from = answer_sent},
canceled = [RequestId | Canceled]}};
-handle_info({timeout, RequestId}, #state{canceled = Canceled} = State) ->
+handle_info({timeout, RequestId},
+ #state{canceled = Canceled,
+ profile_name = ProfileName} = State) ->
+ ?hcri("timeout", [{id, RequestId}]),
Filter =
fun(#request{id = Id, from = From} = Request) when Id =:= RequestId ->
+ ?hcrv("found request", [{id, Id}, {from, From}]),
%% Notify the owner
- Response = httpc_response:error(Request, timeout),
- httpc_response:send(From, Response),
+ httpc_response:send(From,
+ httpc_response:error(Request, timeout)),
+ httpc_manager:request_done(RequestId, ProfileName),
+ ?hcrv("response (timeout) sent", []),
[Request#request{from = answer_sent}];
(_) ->
true
end,
case State#state.status of
pipeline ->
+ ?hcrd("pipeline", []),
Pipeline = queue:filter(Filter, State#state.pipeline),
{noreply, State#state{canceled = [RequestId | Canceled],
pipeline = Pipeline}};
keep_alive ->
+ ?hcrd("keep_alive", []),
KeepAlive = queue:filter(Filter, State#state.keep_alive),
{noreply, State#state{canceled = [RequestId | Canceled],
keep_alive = KeepAlive}}
@@ -572,14 +680,33 @@ handle_info({'EXIT', _, _}, State) ->
%%--------------------------------------------------------------------
%% Init error there is no socket to be closed.
+terminate(normal,
+ #state{request = Request,
+ session = {send_failed, AReason} = Reason} = State) ->
+ ?hcrd("terminate", [{send_reason, AReason}, {request, Request}]),
+ maybe_send_answer(Request,
+ httpc_response:error(Request, Reason),
+ State),
+ ok;
+
+terminate(normal,
+ #state{request = Request,
+ session = {connect_failed, AReason} = Reason} = State) ->
+ ?hcrd("terminate", [{connect_reason, AReason}, {request, Request}]),
+ maybe_send_answer(Request,
+ httpc_response:error(Request, Reason),
+ State),
+ ok;
+
terminate(normal, #state{session = undefined}) ->
ok;
%% Init error sending, no session information has been setup but
%% there is a socket that needs closing.
-terminate(normal, #state{request = Request,
- session = #tcp_session{id = undefined,
- socket = Socket}}) ->
+terminate(normal,
+ #state{request = Request,
+ session = #tcp_session{id = undefined,
+ socket = Socket}}) ->
http_transport:close(socket_type(Request), Socket);
%% Socket closed remotely
@@ -590,6 +717,9 @@ terminate(normal,
request = Request,
timers = Timers,
pipeline = Pipeline}) ->
+ ?hcrt("terminate(normal) - remote close",
+ [{id, Id}, {profile, ProfileName}]),
+
%% Clobber session
(catch httpc_manager:delete_session(Id, ProfileName)),
@@ -605,23 +735,28 @@ terminate(normal,
%% And, just in case, close our side (**really** overkill)
http_transport:close(socket_type(Request), Socket);
-terminate(_, State = #state{session = Session,
- request = undefined,
- profile_name = ProfileName,
- timers = Timers,
- pipeline = Pipeline,
- keep_alive = KeepAlive}) ->
- catch httpc_manager:delete_session(Session#tcp_session.id,
- ProfileName),
+terminate(_, #state{session = #tcp_session{id = Id,
+ socket = Socket,
+ scheme = Scheme},
+ request = undefined,
+ profile_name = ProfileName,
+ timers = Timers,
+ pipeline = Pipeline,
+ keep_alive = KeepAlive} = State) ->
+ (catch httpc_manager:delete_session(Id, ProfileName)),
maybe_retry_queue(Pipeline, State),
maybe_retry_queue(KeepAlive, State),
cancel_timer(Timers#timers.queue_timer, timeout_queue),
- Socket = Session#tcp_session.socket,
- http_transport:close(socket_type(Session#tcp_session.scheme), Socket);
+ http_transport:close(socket_type(Scheme), Socket);
+
+terminate(Reason, #state{request = undefined}) ->
+ ?hcrt("terminate", [{reason, Reason}]),
+ ok;
-terminate(Reason, State = #state{request = Request}) ->
+terminate(Reason, #state{request = Request} = State) ->
+ ?hcrd("terminate", [{reason, Reason}, {request, Request}]),
NewState = maybe_send_answer(Request,
httpc_response:error(Request, Reason),
State),
@@ -641,13 +776,16 @@ maybe_send_answer(Request, Answer, State) ->
answer_request(Request, Answer, State).
deliver_answers([]) ->
+ ?hcrd("deliver answer done", []),
ok;
-deliver_answers([#request{from = From} = Request | Requests])
+deliver_answers([#request{id = Id, from = From} = Request | Requests])
when is_pid(From) ->
Response = httpc_response:error(Request, socket_closed_remotely),
+ ?hcrd("deliver answer", [{id, Id}, {from, From}, {response, Response}]),
httpc_response:send(From, Response),
deliver_answers(Requests);
-deliver_answers([_|Requests]) ->
+deliver_answers([Request|Requests]) ->
+ ?hcrd("skip deliver answer", [{request, Request}]),
deliver_answers(Requests).
@@ -656,54 +794,63 @@ deliver_answers([_|Requests]) ->
%% Purpose: Convert process state when code is changed
%%--------------------------------------------------------------------
code_change(_, #state{request = Request, pipeline = Queue} = State,
- [{from, '5.0.1'}, {to, '5.0.2'}]) ->
- Settings = new_http_options(Request#request.settings),
+ from_pre_5_3_5) ->
+ Settings = new_http_options(Request#request.settings),
NewRequest = Request#request{settings = Settings},
- NewQueue = new_queue(Queue, fun new_http_options/1),
+ NewQueue = new_queue(Queue, fun new_http_options/1),
{ok, State#state{request = NewRequest, pipeline = NewQueue}};
code_change(_, #state{request = Request, pipeline = Queue} = State,
- [{from, '5.0.2'}, {to, '5.0.1'}]) ->
- Settings = old_http_options(Request#request.settings),
+ to_pre_5_3_5) ->
+ Settings = old_http_options(Request#request.settings),
NewRequest = Request#request{settings = Settings},
- NewQueue = new_queue(Queue, fun old_http_options/1),
+ NewQueue = new_queue(Queue, fun old_http_options/1),
{ok, State#state{request = NewRequest, pipeline = NewQueue}};
code_change(_, State, _) ->
{ok, State}.
-new_http_options({http_options, TimeOut, AutoRedirect, SslOpts,
- Auth, Relaxed}) ->
- {http_options, "HTTP/1.1", TimeOut, AutoRedirect, SslOpts,
- Auth, Relaxed}.
-
-old_http_options({http_options, _, TimeOut, AutoRedirect,
- SslOpts, Auth, Relaxed}) ->
- {http_options, TimeOut, AutoRedirect, SslOpts, Auth, Relaxed}.
-
-new_queue(Queue, Fun) ->
+new_http_options({http_options,
+ Version, Timeout, AutoRedirect, SslOpts,
+ ProxyAuth, Relaxed, ConnTimeout}) ->
+ UrlEncoding = false,
+ {http_options,
+ Version, Timeout, AutoRedirect, SslOpts,
+ ProxyAuth, Relaxed, ConnTimeout, UrlEncoding}.
+
+old_http_options({http_options,
+ Version, TimeOut, AutoRedirect, SslOpts,
+ ProxyAuth, Relaxed, ConnTimeout, _UrlEncode}) ->
+ {http_options,
+ Version, TimeOut, AutoRedirect, SslOpts,
+ ProxyAuth, Relaxed, ConnTimeout}.
+
+new_queue(Queue, TransformSettings) ->
List = queue:to_list(Queue),
NewList =
lists:map(fun(Request) ->
Settings =
- Fun(Request#request.settings),
+ TransformSettings(Request#request.settings),
Request#request{settings = Settings}
end, List),
queue:from_list(NewList).
-%%--------------------------------------------------------------------
+
+%%%--------------------------------------------------------------------
%%% Internal functions
-%%--------------------------------------------------------------------
+%%%--------------------------------------------------------------------
-connect(SocketType, ToAddress, #options{ipfamily = IpFamily,
- ip = FromAddress,
- port = FromPort}, Timeout) ->
+connect(SocketType, ToAddress,
+ #options{ipfamily = IpFamily,
+ ip = FromAddress,
+ port = FromPort,
+ socket_opts = Opts0}, Timeout) ->
Opts1 =
case FromPort of
default ->
- [];
+ Opts0;
_ ->
- [{port, FromPort}]
+ [{port, FromPort} | Opts0]
end,
Opts2 =
case FromAddress of
@@ -728,101 +875,156 @@ connect(SocketType, ToAddress, #options{ipfamily = IpFamily,
http_transport:connect(SocketType, ToAddress, Opts3, Timeout)
end.
-
-send_first_request(Address, Request, #state{options = Options} = State) ->
- SocketType = socket_type(Request),
- ConnTimeout = (Request#request.settings)#http_options.connect_timeout,
- ?hcri("connect",
+connect_and_send_first_request(Address,
+ #request{settings = Settings,
+ headers = Headers,
+ address = OrigAddress,
+ scheme = Scheme} = Request,
+ #state{options = Options} = State) ->
+
+ ?hcrd("connect",
[{address, Address}, {request, Request}, {options, Options}]),
+
+ SocketType = socket_type(Request),
+ ConnTimeout = Settings#http_options.connect_timeout,
case connect(SocketType, Address, Options, ConnTimeout) of
{ok, Socket} ->
- ?hcri("connected - now send first request", [{socket, Socket}]),
+ ?hcrd("connected - now send first request", [{socket, Socket}]),
case httpc_request:send(Address, Request, Socket) of
ok ->
- ?hcri("first request sent", []),
+ ?hcrd("first request sent", []),
ClientClose =
- httpc_request:is_client_closing(
- Request#request.headers),
+ httpc_request:is_client_closing(Headers),
SessionType = httpc_manager:session_type(Options),
Session =
- #tcp_session{id = {Request#request.address, self()},
- scheme = Request#request.scheme,
- socket = Socket,
+ #tcp_session{id = {OrigAddress, self()},
+ scheme = Scheme,
+ socket = Socket,
client_close = ClientClose,
- type = SessionType},
- TmpState = State#state{request = Request,
- session = Session,
- mfa = init_mfa(Request, State),
- status_line =
- init_status_line(Request),
- headers = undefined,
- body = undefined,
- status = new},
- http_transport:setopts(SocketType,
- Socket, [{active, once}]),
+ type = SessionType},
+ TmpState =
+ State#state{request = Request,
+ session = Session,
+ mfa = init_mfa(Request, State),
+ status_line = init_status_line(Request),
+ headers = undefined,
+ body = undefined,
+ status = new},
+ ?hcrt("activate socket", []),
+ activate_once(Session),
NewState = activate_request_timeout(TmpState),
{ok, NewState};
- {error, Reason} ->
- %% Commented out in wait of ssl support to avoid
- %% dialyzer warning
- %%case State#state.status of
- %% new -> % Called from init/1
- self() ! {init_error, error_sending,
- httpc_response:error(Request, Reason)},
- {ok, State#state{request = Request,
- session =
- #tcp_session{socket = Socket}}}
- %%ssl_tunnel -> % Not called from init/1
- %% NewState =
- %% answer_request(Request,
- %%httpc_response:error(Request,
- %%Reason),
- %% State),
- %% {stop, normal, NewState}
- %% end
+ {error, Reason} = Error ->
+ ?hcrv("failed sending request", [{reason, Reason}]),
+ {stop, Error,
+ State#state{session = {send_failed, Reason},
+ request = Request}}
end;
- {error, Reason} ->
- %% Commented out in wait of ssl support to avoid
- %% dialyzer warning
- %% case State#state.status of
- %% new -> % Called from init/1
- self() ! {init_error, error_connecting,
- httpc_response:error(Request, Reason)},
- {ok, State#state{request = Request}}
- %% ssl_tunnel -> % Not called from init/1
- %% NewState =
- %% answer_request(Request,
- %% httpc_response:error(Request,
- %% Reason),
- %% State),
- %% {stop, normal, NewState}
- %%end
+ {error, Reason} = Error ->
+ ?hcri("connect failed", [{reason, Reason}]),
+ {stop, Error, State#state{session = {connect_failed, Reason},
+ request = Request}}
end.
+
+handler_info(#state{request = Request,
+ session = Session,
+ status_line = _StatusLine,
+ pipeline = Pipeline,
+ keep_alive = KeepAlive,
+ status = Status,
+ canceled = _Canceled,
+ options = _Options,
+ timers = _Timers} = _State) ->
+
+ ?hcrt("handler info", [{request, Request},
+ {session, Session},
+ {pipeline, Pipeline},
+ {keep_alive, KeepAlive},
+ {status, Status}]),
+
+ %% Info about the current request
+ RequestInfo =
+ case Request of
+ undefined ->
+ [];
+ #request{id = Id,
+ started = ReqStarted} ->
+ [{id, Id}, {started, ReqStarted}]
+ end,
+
+ ?hcrt("handler info", [{request_info, RequestInfo}]),
+
+ %% Info about the current session/socket
+ SessionType = Session#tcp_session.type,
+ QueueLen = case Session#tcp_session.type of
+ pipeline ->
+ queue:len(Pipeline);
+ keep_alive ->
+ queue:len(KeepAlive)
+ end,
+ Socket = Session#tcp_session.socket,
+ Scheme = Session#tcp_session.scheme,
+ SocketType = socket_type(Scheme),
+
+ ?hcrt("handler info", [{session_type, SessionType},
+ {queue_length, QueueLen},
+ {scheme, Scheme},
+ {socket_type, SocketType},
+ {socket, Socket}]),
+
+ SocketOpts = http_transport:getopts(SocketType, Socket),
+ SocketStats = http_transport:getstat(SocketType, Socket),
+
+ Remote = http_transport:peername(SocketType, Socket),
+ Local = http_transport:sockname(SocketType, Socket),
+
+ ?hcrt("handler info", [{remote, Remote},
+ {local, Local},
+ {socket_opts, SocketOpts},
+ {socket_stats, SocketStats}]),
+
+ SocketInfo = [{remote, Remote},
+ {local, Local},
+ {socket_opts, SocketOpts},
+ {socket_stats, SocketStats}],
+
+ SessionInfo =
+ [{type, SessionType},
+ {queue_length, QueueLen},
+ {scheme, Scheme},
+ {socket_info, SocketInfo}],
+
+ [{status, Status},
+ {current_request, RequestInfo},
+ {session, SessionInfo}].
+
+
+
handle_http_msg({Version, StatusCode, ReasonPharse, Headers, Body},
State = #state{request = Request}) ->
- ?hcrt("handle_http_msg", [{body, Body}]),
+ ?hcrt("handle_http_msg", [{headers, Headers}]),
case Headers#http_response_h.'content-type' of
"multipart/byteranges" ++ _Param ->
- exit(not_yet_implemented);
+ exit({not_yet_implemented, multypart_byteranges});
_ ->
- StatusLine = {Version, StatusCode, ReasonPharse},
+ StatusLine = {Version, StatusCode, ReasonPharse},
{ok, NewRequest} = start_stream(StatusLine, Headers, Request),
handle_http_body(Body,
State#state{request = NewRequest,
status_line = StatusLine,
headers = Headers})
end;
-handle_http_msg({ChunkedHeaders, Body},
- State = #state{headers = Headers}) ->
- ?hcrt("handle_http_msg", [{chunked_headers, ChunkedHeaders}, {body, Body}]),
+handle_http_msg({ChunkedHeaders, Body}, #state{headers = Headers} = State) ->
+ ?hcrt("handle_http_msg",
+ [{chunked_headers, ChunkedHeaders}, {headers, Headers}]),
NewHeaders = http_chunk:handle_headers(Headers, ChunkedHeaders),
handle_response(State#state{headers = NewHeaders, body = Body});
-handle_http_msg(Body, State = #state{status_line = {_,Code, _}}) ->
- ?hcrt("handle_http_msg", [{body, Body}, {code, Code}]),
- {NewBody, NewRequest}= stream(Body, State#state.request, Code),
+handle_http_msg(Body, #state{status_line = {_,Code, _}} = State) ->
+ ?hcrt("handle_http_msg", [{code, Code}]),
+ {NewBody, NewRequest} = stream(Body, State#state.request, Code),
handle_response(State#state{body = NewBody, request = NewRequest}).
handle_http_body(<<>>, State = #state{status_line = {_,304, _}}) ->
@@ -837,11 +1039,12 @@ handle_http_body(<<>>, State = #state{request = #request{method = head}}) ->
?hcrt("handle_http_body - head", []),
handle_response(State#state{body = <<>>});
-handle_http_body(Body, State = #state{headers = Headers,
- max_body_size = MaxBodySize,
- status_line = {_,Code, _},
- request = Request}) ->
- ?hcrt("handle_http_body", [{body, Body}, {max_body_size, MaxBodySize}, {code, Code}]),
+handle_http_body(Body, #state{headers = Headers,
+ max_body_size = MaxBodySize,
+ status_line = {_,Code, _},
+ request = Request} = State) ->
+ ?hcrt("handle_http_body",
+ [{max_body_size, MaxBodySize}, {headers, Headers}, {code, Code}]),
TransferEnc = Headers#http_response_h.'transfer-encoding',
case case_insensitive_header(TransferEnc) of
"chunked" ->
@@ -850,12 +1053,17 @@ handle_http_body(Body, State = #state{headers = Headers,
State#state.max_header_size,
{Code, Request}) of
{Module, Function, Args} ->
- ?hcrt("handle_http_body - new mfa", [{module, Module}, {function, Function}, {args, Args}]),
+ ?hcrt("handle_http_body - new mfa",
+ [{module, Module},
+ {function, Function},
+ {args, Args}]),
NewState = next_body_chunk(State),
{noreply, NewState#state{mfa =
{Module, Function, Args}}};
{ok, {ChunkedHeaders, NewBody}} ->
- ?hcrt("handle_http_body - nyew body", [{chunked_headers, ChunkedHeaders}, {new_body, NewBody}]),
+ ?hcrt("handle_http_body - new body",
+ [{chunked_headers, ChunkedHeaders},
+ {new_body, NewBody}]),
NewHeaders = http_chunk:handle_headers(Headers,
ChunkedHeaders),
handle_response(State#state{headers = NewHeaders,
@@ -872,12 +1080,13 @@ handle_http_body(Body, State = #state{headers = Headers,
?hcrt("handle_http_body - other", []),
Length =
list_to_integer(Headers#http_response_h.'content-length'),
- case ((Length =< MaxBodySize) or (MaxBodySize == nolimit)) of
+ case ((Length =< MaxBodySize) orelse (MaxBodySize =:= nolimit)) of
true ->
case httpc_response:whole_body(Body, Length) of
{ok, Body} ->
- {NewBody, NewRequest}= stream(Body, Request, Code),
- handle_response(State#state{body = NewBody,
+ {NewBody, NewRequest} =
+ stream(Body, Request, Code),
+ handle_response(State#state{body = NewBody,
request = NewRequest});
MFA ->
NewState = next_body_chunk(State),
@@ -893,90 +1102,79 @@ handle_http_body(Body, State = #state{headers = Headers,
end
end.
-%%% Normaly I do not comment out code, I throw it away. But this might
-%%% actually be used on day if ssl is improved.
-%% handle_response(State = #state{status = ssl_tunnel,
-%% request = Request,
-%% options = Options,
-%% session = #tcp_session{socket = Socket,
-%% scheme = Scheme},
-%% status_line = {_, 200, _}}) ->
-%% %%% Insert code for upgrading the socket if and when ssl supports this.
-%% Address = handle_proxy(Request#request.address, Options#options.proxy),
-%% send_first_request(Address, Request, State);
-%% handle_response(State = #state{status = ssl_tunnel,
-%% request = Request}) ->
-%% NewState = answer_request(Request,
-%% httpc_response:error(Request,
-%% ssl_proxy_tunnel_failed),
-%% State),
-%% {stop, normal, NewState};
-
-handle_response(State = #state{status = new}) ->
- handle_response(try_to_enable_pipeline_or_keep_alive(State));
-
-handle_response(State =
- #state{request = Request,
+handle_response(#state{status = new} = State) ->
+ ?hcrd("handle response - status = new", []),
+ handle_response(try_to_enable_pipeline_or_keep_alive(State));
+
+handle_response(#state{request = Request,
status = Status,
session = Session,
status_line = StatusLine,
headers = Headers,
body = Body,
options = Options,
- profile_name = ProfileName}) when Status =/= new ->
- ?hcrt("handle response", [{status, Status}, {session, Session}, {status_line, StatusLine}, {profile_name, ProfileName}]),
+ profile_name = ProfileName} = State)
+ when Status =/= new ->
+
+ ?hcrd("handle response", [{profile, ProfileName},
+ {status, Status},
+ {request, Request},
+ {session, Session},
+ {status_line, StatusLine}]),
+
handle_cookies(Headers, Request, Options, ProfileName),
case httpc_response:result({StatusLine, Headers, Body}, Request) of
%% 100-continue
continue ->
+ ?hcrd("handle response - continue", []),
%% Send request body
{_, RequestBody} = Request#request.content,
http_transport:send(socket_type(Session#tcp_session.scheme),
Session#tcp_session.socket,
RequestBody),
%% Wait for next response
- http_transport:setopts(socket_type(Session#tcp_session.scheme),
- Session#tcp_session.socket,
- [{active, once}]),
+ activate_once(Session),
Relaxed = (Request#request.settings)#http_options.relaxed,
- {noreply,
- State#state{mfa = {httpc_response, parse,
- [State#state.max_header_size,
- Relaxed]},
- status_line = undefined,
- headers = undefined,
- body = undefined
- }};
+ MFA = {httpc_response, parse,
+ [State#state.max_header_size, Relaxed]},
+ {noreply, State#state{mfa = MFA,
+ status_line = undefined,
+ headers = undefined,
+ body = undefined}};
+
%% Ignore unexpected 100-continue response and receive the
%% actual response that the server will send right away.
{ignore, Data} ->
+ ?hcrd("handle response - ignore", [{data, Data}]),
Relaxed = (Request#request.settings)#http_options.relaxed,
- NewState = State#state{mfa =
- {httpc_response, parse,
- [State#state.max_header_size,
- Relaxed]},
+ MFA = {httpc_response, parse,
+ [State#state.max_header_size, Relaxed]},
+ NewState = State#state{mfa = MFA,
status_line = undefined,
- headers = undefined,
- body = undefined},
+ headers = undefined,
+ body = undefined},
handle_info({httpc_handler, dummy, Data}, NewState);
+
%% On a redirect or retry the current request becomes
%% obsolete and the manager will create a new request
%% with the same id as the current.
{redirect, NewRequest, Data} ->
- ?hcrt("handle response - redirect", [{new_request, NewRequest}, {data, Data}]),
+ ?hcrt("handle response - redirect",
+ [{new_request, NewRequest}, {data, Data}]),
ok = httpc_manager:redirect_request(NewRequest, ProfileName),
handle_queue(State#state{request = undefined}, Data);
{retry, TimeNewRequest, Data} ->
- ?hcrt("handle response - retry", [{time_new_request, TimeNewRequest}, {data, Data}]),
+ ?hcrt("handle response - retry",
+ [{time_new_request, TimeNewRequest}, {data, Data}]),
ok = httpc_manager:retry_request(TimeNewRequest, ProfileName),
handle_queue(State#state{request = undefined}, Data);
{ok, Msg, Data} ->
- ?hcrt("handle response - result ok", [{msg, Msg}, {data, Data}]),
+ ?hcrd("handle response - ok", []),
end_stream(StatusLine, Request),
NewState = answer_request(Request, Msg, State),
handle_queue(NewState, Data);
{stop, Msg} ->
- ?hcrt("handle response - result stop", [{msg, Msg}]),
+ ?hcrd("handle response - stop", [{msg, Msg}]),
end_stream(StatusLine, Request),
NewState = answer_request(Request, Msg, State),
{stop, normal, NewState}
@@ -990,60 +1188,67 @@ handle_cookies(_,_, #options{cookies = verify}, _) ->
ok;
handle_cookies(Headers, Request, #options{cookies = enabled}, ProfileName) ->
{Host, _ } = Request#request.address,
- Cookies = http_cookie:cookies(Headers#http_response_h.other,
+ Cookies = httpc_cookie:cookies(Headers#http_response_h.other,
Request#request.path, Host),
httpc_manager:store_cookies(Cookies, Request#request.address,
ProfileName).
%% This request could not be pipelined or used as sequential keept alive
%% queue
-handle_queue(State = #state{status = close}, _) ->
+handle_queue(#state{status = close} = State, _) ->
{stop, normal, State};
-handle_queue(State = #state{status = keep_alive}, Data) ->
+handle_queue(#state{status = keep_alive} = State, Data) ->
handle_keep_alive_queue(State, Data);
-handle_queue(State = #state{status = pipeline}, Data) ->
+handle_queue(#state{status = pipeline} = State, Data) ->
handle_pipeline(State, Data).
-handle_pipeline(State =
- #state{status = pipeline, session = Session,
+handle_pipeline(#state{status = pipeline,
+ session = Session,
profile_name = ProfileName,
- options = #options{pipeline_timeout = TimeOut}},
- Data) ->
+ options = #options{pipeline_timeout = TimeOut}} =
+ State,
+ Data) ->
+
+ ?hcrd("handle pipeline", [{profile, ProfileName},
+ {session, Session},
+ {timeout, TimeOut}]),
+
case queue:out(State#state.pipeline) of
{empty, _} ->
+ ?hcrd("epmty pipeline queue", []),
+
%% The server may choose too teminate an idle pipeline
%% in this case we want to receive the close message
%% at once and not when trying to pipeline the next
%% request.
- http_transport:setopts(socket_type(Session#tcp_session.scheme),
- Session#tcp_session.socket,
- [{active, once}]),
+ activate_once(Session),
+
%% If a pipeline that has been idle for some time is not
%% closed by the server, the client may want to close it.
- NewState = activate_queue_timeout(TimeOut, State),
+ NewState = activate_queue_timeout(TimeOut, State),
NewSession = Session#tcp_session{queue_length = 0},
httpc_manager:insert_session(NewSession, ProfileName),
%% Note mfa will be initilized when a new request
%% arrives.
{noreply,
- NewState#state{request = undefined,
- mfa = undefined,
+ NewState#state{request = undefined,
+ mfa = undefined,
status_line = undefined,
- headers = undefined,
- body = undefined
- }
- };
+ headers = undefined,
+ body = undefined}};
{{value, NextRequest}, Pipeline} ->
case lists:member(NextRequest#request.id,
State#state.canceled) of
true ->
+ ?hcrv("next request had been cancelled", []),
%% See comment for handle_cast({cancel, RequestId})
{stop, normal,
State#state{request =
NextRequest#request{from = answer_sent}}};
false ->
+ ?hcrv("next request", [{request, NextRequest}]),
NewSession =
Session#tcp_session{queue_length =
%% Queue + current
@@ -1051,21 +1256,19 @@ handle_pipeline(State =
httpc_manager:insert_session(NewSession, ProfileName),
Relaxed =
(NextRequest#request.settings)#http_options.relaxed,
+ MFA = {httpc_response,
+ parse,
+ [State#state.max_header_size, Relaxed]},
NewState =
- State#state{pipeline = Pipeline,
- request = NextRequest,
- mfa = {httpc_response, parse,
- [State#state.max_header_size,
- Relaxed]},
+ State#state{pipeline = Pipeline,
+ request = NextRequest,
+ mfa = MFA,
status_line = undefined,
- headers = undefined,
- body = undefined},
+ headers = undefined,
+ body = undefined},
case Data of
<<>> ->
- http_transport:setopts(
- socket_type(Session#tcp_session.scheme),
- Session#tcp_session.socket,
- [{active, once}]),
+ activate_once(Session),
{noreply, NewState};
_ ->
%% If we already received some bytes of
@@ -1076,22 +1279,25 @@ handle_pipeline(State =
end
end.
-handle_keep_alive_queue(State = #state{status = keep_alive,
- session = Session,
- profile_name = ProfileName,
- options = #options{keep_alive_timeout
- = TimeOut}
- },
- Data) ->
+handle_keep_alive_queue(
+ #state{status = keep_alive,
+ session = Session,
+ profile_name = ProfileName,
+ options = #options{keep_alive_timeout = TimeOut}} = State,
+ Data) ->
+
+ ?hcrd("handle keep_alive", [{profile, ProfileName},
+ {session, Session},
+ {timeout, TimeOut}]),
+
case queue:out(State#state.keep_alive) of
{empty, _} ->
+ ?hcrd("empty keep_alive queue", []),
%% The server may choose too terminate an idle keep_alive session
%% in this case we want to receive the close message
%% at once and not when trying to send the next
%% request.
- http_transport:setopts(socket_type(Session#tcp_session.scheme),
- Session#tcp_session.socket,
- [{active, once}]),
+ activate_once(Session),
%% If a keep_alive session has been idle for some time is not
%% closed by the server, the client may want to close it.
NewState = activate_queue_timeout(TimeOut, State),
@@ -1111,25 +1317,25 @@ handle_keep_alive_queue(State = #state{status = keep_alive,
case lists:member(NextRequest#request.id,
State#state.canceled) of
true ->
- handle_keep_alive_queue(State#state{keep_alive =
- KeepAlive}, Data);
+ ?hcrv("next request has already been canceled", []),
+ handle_keep_alive_queue(
+ State#state{keep_alive = KeepAlive}, Data);
false ->
+ ?hcrv("next request", [{request, NextRequest}]),
Relaxed =
(NextRequest#request.settings)#http_options.relaxed,
+ MFA = {httpc_response, parse,
+ [State#state.max_header_size, Relaxed]},
NewState =
- State#state{request = NextRequest,
- keep_alive = KeepAlive,
- mfa = {httpc_response, parse,
- [State#state.max_header_size,
- Relaxed]},
+ State#state{request = NextRequest,
+ keep_alive = KeepAlive,
+ mfa = MFA,
status_line = undefined,
- headers = undefined,
- body = undefined},
+ headers = undefined,
+ body = undefined},
case Data of
<<>> ->
- http_transport:setopts(
- socket_type(Session#tcp_session.scheme),
- Session#tcp_session.socket, [{active, once}]),
+ activate_once(Session),
{noreply, NewState};
_ ->
%% If we already received some bytes of
@@ -1140,11 +1346,6 @@ handle_keep_alive_queue(State = #state{status = keep_alive,
end
end.
-call(Msg, Pid, Timeout) ->
- gen_server:call(Pid, Msg, Timeout).
-
-cast(Msg, Pid) ->
- gen_server:cast(Pid, Msg).
case_insensitive_header(Str) when is_list(Str) ->
http_util:to_lower(Str);
@@ -1152,20 +1353,34 @@ case_insensitive_header(Str) when is_list(Str) ->
case_insensitive_header(Str) ->
Str.
-activate_request_timeout(State = #state{request = Request}) ->
- Time = (Request#request.settings)#http_options.timeout,
- case Time of
+activate_once(#tcp_session{scheme = Scheme, socket = Socket}) ->
+ SocketType = socket_type(Scheme),
+ http_transport:setopts(SocketType, Socket, [{active, once}]).
+
+activate_request_timeout(
+ #state{request = #request{timer = undefined} = Request} = State) ->
+ Timeout = (Request#request.settings)#http_options.timeout,
+ case Timeout of
infinity ->
State;
_ ->
- Ref = erlang:send_after(Time, self(),
- {timeout, Request#request.id}),
- State#state
- {timers =
- #timers{request_timers =
- [{Request#request.id, Ref}|
- (State#state.timers)#timers.request_timers]}}
- end.
+ ReqId = Request#request.id,
+ ?hcrt("activate request timer",
+ [{request_id, ReqId},
+ {time_consumed, t() - Request#request.started},
+ {timeout, Timeout}]),
+ Msg = {timeout, ReqId},
+ Ref = erlang:send_after(Timeout, self(), Msg),
+ Request2 = Request#request{timer = Ref},
+ ReqTimers = [{Request#request.id, Ref} |
+ (State#state.timers)#timers.request_timers],
+ Timers = #timers{request_timers = ReqTimers},
+ State#state{request = Request2, timers = Timers}
+ end;
+
+%% Timer is already running! This is the case for a redirect or retry
+activate_request_timeout(State) ->
+ State.
activate_queue_timeout(infinity, State) ->
State;
@@ -1187,18 +1402,21 @@ is_keep_alive_enabled_server("HTTP/1.0",
is_keep_alive_enabled_server(_,_) ->
false.
-is_keep_alive_connection(Headers, Session) ->
- (not ((Session#tcp_session.client_close) or
- httpc_response:is_server_closing(Headers))).
-
-try_to_enable_pipeline_or_keep_alive(State =
- #state{session = Session,
- request = #request{method = Method},
- status_line = {Version, _, _},
- headers = Headers,
- profile_name = ProfileName}) ->
- case (is_keep_alive_enabled_server(Version, Headers) andalso
- is_keep_alive_connection(Headers, Session)) of
+is_keep_alive_connection(Headers, #tcp_session{client_close = ClientClose}) ->
+ (not ((ClientClose) orelse httpc_response:is_server_closing(Headers))).
+
+try_to_enable_pipeline_or_keep_alive(
+ #state{session = Session,
+ request = #request{method = Method},
+ status_line = {Version, _, _},
+ headers = Headers,
+ profile_name = ProfileName} = State) ->
+ ?hcrd("try to enable pipeline or keep-alive",
+ [{version, Version},
+ {headers, Headers},
+ {session, Session}]),
+ case is_keep_alive_enabled_server(Version, Headers) andalso
+ is_keep_alive_connection(Headers, Session) of
true ->
case (is_pipeline_enabled_client(Session) andalso
httpc_request:is_idempotent(Method)) of
@@ -1209,21 +1427,24 @@ try_to_enable_pipeline_or_keep_alive(State =
httpc_manager:insert_session(Session, ProfileName),
%% Make sure type is keep_alive in session
%% as it in this case might be pipeline
- State#state{status = keep_alive,
- session =
- Session#tcp_session{type = keep_alive}}
+ NewSession = Session#tcp_session{type = keep_alive},
+ State#state{status = keep_alive,
+ session = NewSession}
end;
false ->
State#state{status = close}
end.
-answer_request(Request, Msg, #state{timers = Timers} = State) ->
- httpc_response:send(Request#request.from, Msg),
+answer_request(#request{id = RequestId, from = From} = Request, Msg,
+ #state{timers = Timers, profile_name = ProfileName} = State) ->
+ ?hcrt("answer request", [{request, Request}]),
+ httpc_response:send(From, Msg),
RequestTimers = Timers#timers.request_timers,
TimerRef =
- proplists:get_value(Request#request.id, RequestTimers, undefined),
- Timer = {Request#request.id, TimerRef},
+ proplists:get_value(RequestId, RequestTimers, undefined),
+ Timer = {RequestId, TimerRef},
cancel_timer(TimerRef, {timeout, Request#request.id}),
+ httpc_manager:request_done(RequestId, ProfileName),
State#state{request = Request#request{from = answer_sent},
timers =
Timers#timers{request_timers =
@@ -1253,14 +1474,14 @@ retry_pipeline([Request | PipeLine],
case (catch httpc_manager:retry_request(Request, ProfileName)) of
ok ->
RequestTimers = Timers#timers.request_timers,
+ ReqId = Request#request.id,
TimerRef =
- proplists:get_value(Request#request.id, RequestTimers,
- undefined),
- cancel_timer(TimerRef, {timeout, Request#request.id}),
- State#state{timers = Timers#timers{request_timers =
- lists:delete({Request#request.id,
- TimerRef},
- RequestTimers)}};
+ proplists:get_value(ReqId, RequestTimers, undefined),
+ cancel_timer(TimerRef, {timeout, ReqId}),
+ NewReqsTimers = lists:delete({ReqId, TimerRef}, RequestTimers),
+ NewTimers = Timers#timers{request_timers = NewReqsTimers},
+ State#state{timers = NewTimers};
+
Error ->
answer_request(Request#request.from,
httpc_response:error(Request, Error), State)
@@ -1345,12 +1566,14 @@ socket_type(#request{scheme = https, settings = Settings}) ->
socket_type(http) ->
ip_comm;
socket_type(https) ->
- {ssl, []}. %% Dummy value ok for ex setops that does not use this value
+ {ssl, []}. %% Dummy value ok for ex setopts that does not use this value
-start_stream({_Version, _Code, _ReasonPhrase}, _Headers, #request{stream = none} = Request) ->
+start_stream({_Version, _Code, _ReasonPhrase}, _Headers,
+ #request{stream = none} = Request) ->
?hcrt("start stream - none", []),
{ok, Request};
-start_stream({_Version, Code, _ReasonPhrase}, Headers, #request{stream = self} = Request)
+start_stream({_Version, Code, _ReasonPhrase}, Headers,
+ #request{stream = self} = Request)
when (Code =:= 200) orelse (Code =:= 206) ->
?hcrt("start stream - self", [{code, Code}]),
Msg = httpc_response:stream_start(Headers, Request, ignore),
@@ -1363,7 +1586,8 @@ start_stream({_Version, Code, _ReasonPhrase}, Headers,
Msg = httpc_response:stream_start(Headers, Request, self()),
httpc_response:send(Request#request.from, Msg),
{ok, Request};
-start_stream({_Version, Code, _ReasonPhrase}, _Headers, #request{stream = Filename} = Request)
+start_stream({_Version, Code, _ReasonPhrase}, _Headers,
+ #request{stream = Filename} = Request)
when ((Code =:= 200) orelse (Code =:= 206)) andalso is_list(Filename) ->
?hcrt("start stream", [{code, Code}, {filename, Filename}]),
case file:open(Filename, [write, raw, append, delayed_write]) of
@@ -1436,6 +1660,7 @@ handle_verbose(trace) ->
handle_verbose(_) ->
ok.
+
%%% Normaly I do not comment out code, I throw it away. But this might
%%% actually be used one day if ssl is improved.
%% send_ssl_tunnel_request(Address, Request = #request{address = {Host, Port}},
@@ -1497,3 +1722,21 @@ handle_verbose(_) ->
%% d(_, _, _) ->
%% ok.
+
+call(Msg, Pid) ->
+ Timeout = infinity,
+ call(Msg, Pid, Timeout).
+call(Msg, Pid, Timeout) ->
+ gen_server:call(Pid, Msg, Timeout).
+
+cast(Msg, Pid) ->
+ gen_server:cast(Pid, Msg).
+
+
+%% to(To, Start) when is_integer(Start) andalso (Start >= 0) ->
+%% http_util:timeout(To, Start);
+%% to(To, _Start) ->
+%% http_util:timeout(To, t()).
+
+t() ->
+ http_util:timestamp().
diff --git a/lib/inets/src/http_client/httpc_handler_sup.erl b/lib/inets/src/http_client/httpc_handler_sup.erl
index d9edaa0599..2a69fd15d0 100644
--- a/lib/inets/src/http_client/httpc_handler_sup.erl
+++ b/lib/inets/src/http_client/httpc_handler_sup.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2007-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 2007-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%
%%
%%
@@ -23,7 +23,7 @@
%% API
-export([start_link/0]).
--export([start_child/1]).
+-export([start_child/2]).
%% Supervisor callback
-export([init/1]).
@@ -34,25 +34,28 @@
start_link() ->
supervisor:start_link({local, ?MODULE}, ?MODULE, []).
-start_child(Args) ->
+start_child(Options, Profile) ->
+ Args = [Options, Profile],
supervisor:start_child(?MODULE, Args).
-
+
+
%%%=========================================================================
%%% Supervisor callback
%%%=========================================================================
init(Args) ->
+
RestartStrategy = simple_one_for_one,
MaxR = 0,
MaxT = 3600,
- Name = undefined, % As simple_one_for_one is used.
+ Name = undefined, % As simple_one_for_one is used.
StartFunc = {httpc_handler, start_link, Args},
- Restart = temporary, % E.g. should not be restarted
- Shutdown = 4000,
- Modules = [httpc_handler],
- Type = worker,
-
+ Restart = temporary, % E.g. should not be restarted
+ Shutdown = 4000,
+ Modules = [httpc_handler],
+ Type = worker,
ChildSpec = {Name, StartFunc, Restart, Shutdown, Type, Modules},
+
{ok, {{RestartStrategy, MaxR, MaxT}, [ChildSpec]}}.
diff --git a/lib/inets/src/http_client/httpc_internal.hrl b/lib/inets/src/http_client/httpc_internal.hrl
index ec709b9860..7513aa2838 100644
--- a/lib/inets/src/http_client/httpc_internal.hrl
+++ b/lib/inets/src/http_client/httpc_internal.hrl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2005-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 2005-2011. All Rights Reserved.
+%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
-%%
+%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
-%%
+%%
%% %CopyrightEnd%
%%
%%
@@ -46,7 +46,7 @@
%% bool() - true if auto redirect on 30x response
autoredirect = true,
- %% Ssl socket options
+ %% ssl socket options
ssl = [],
%% {User, Password} = {string(), string()}
@@ -56,48 +56,56 @@
relaxed = false,
%% integer() - ms before a connect times out
- connect_timeout = ?HTTP_REQUEST_CTIMEOUT
+ connect_timeout = ?HTTP_REQUEST_CTIMEOUT,
+
+ %% bool() - Use %-encoding rfc 2396
+ url_encode
+
}
).
%%% HTTP Client per profile setting.
-record(options,
{
- proxy = {undefined, []}, % {{ProxyHost, ProxyPort}, [NoProxy]},
- %% 0 means persistent connections are used without pipelining
- pipeline_timeout = ?HTTP_PIPELINE_TIMEOUT,
- max_pipeline_length = ?HTTP_PIPELINE_LENGTH,
- max_keep_alive_length = ?HTTP_KEEP_ALIVE_LENGTH,
- keep_alive_timeout = ?HTTP_KEEP_ALIVE_TIMEOUT, % Used when pipeline_timeout = 0
- max_sessions = ?HTTP_MAX_TCP_SESSIONS,
- cookies = disabled, % enabled | disabled | verify
- verbose = false,
- ipfamily = inet, % inet | inet6 | inet6fb4
- ip = default, % specify local interface
- port = default % specify local port
- }
+ proxy = {undefined, []}, % {{ProxyHost, ProxyPort}, [NoProxy]},
+ %% 0 means persistent connections are used without pipelining
+ pipeline_timeout = ?HTTP_PIPELINE_TIMEOUT,
+ max_pipeline_length = ?HTTP_PIPELINE_LENGTH,
+ max_keep_alive_length = ?HTTP_KEEP_ALIVE_LENGTH,
+ keep_alive_timeout = ?HTTP_KEEP_ALIVE_TIMEOUT, % Used when pipeline_timeout = 0
+ max_sessions = ?HTTP_MAX_TCP_SESSIONS,
+ cookies = disabled, % enabled | disabled | verify
+ verbose = false,
+ ipfamily = inet, % inet | inet6 | inet6fb4
+ ip = default, % specify local interface
+ port = default, % specify local port
+ socket_opts = [] % other socket options
+ }
).
%%% All data associated to a specific HTTP request
-record(request,
{
- id, % ref() - Request Id
- from, % pid() - Caller
- redircount = 0,% Number of redirects made for this request
- scheme, % http | https
- address, % ({Host,Port}) Destination Host and Port
- path, % string() - Path of parsed URL
- pquery, % string() - Rest of parsed URL
- method, % atom() - HTTP request Method
- headers, % #http_request_h{}
- content, % {ContentType, Body} - Current HTTP request
- settings, % #http_options{} - User defined settings
- abs_uri, % string() ex: "http://www.erlang.org"
- userinfo, % string() - optinal "<userinfo>@<host>:<port>"
- stream, % Boolean() - stream async reply?
- headers_as_is % Boolean() - workaround for servers that does
- %% not honor the http standard, can also be used for testing purposes.
- }
+ id, % ref() - Request Id
+ from, % pid() - Caller
+ redircount = 0,% Number of redirects made for this request
+ scheme, % http | https
+ address, % ({Host,Port}) Destination Host and Port
+ path, % string() - Path of parsed URL
+ pquery, % string() - Rest of parsed URL
+ method, % atom() - HTTP request Method
+ headers, % #http_request_h{}
+ content, % {ContentType, Body} - Current HTTP request
+ settings, % #http_options{} - User defined settings
+ abs_uri, % string() ex: "http://www.erlang.org"
+ userinfo, % string() - optinal "<userinfo>@<host>:<port>"
+ stream, % Boolean() - stream async reply?
+ headers_as_is, % Boolean() - workaround for servers that does
+ % not honor the http standard, can also be used for testing purposes.
+ started, % integer() > 0 - When we started processing the request
+ timer, % undefined | ref()
+ socket_opts % undefined | [socket_option()]
+ }
).
-record(tcp_session,
@@ -107,7 +115,7 @@
scheme, % http (HTTP/TCP) | https (HTTP/SSL/TCP)
socket, % Open socket, used by connection
queue_length = 1, % Current length of pipeline or keep alive queue
- type % pipeline | keep_alive (wait for response before sending new request)
+ type % pipeline | keep_alive (wait for response before sending new request)
}).
-record(http_cookie,
diff --git a/lib/inets/src/http_client/httpc_manager.erl b/lib/inets/src/http_client/httpc_manager.erl
index 63b00c7dce..4738517210 100644
--- a/lib/inets/src/http_client/httpc_manager.erl
+++ b/lib/inets/src/http_client/httpc_manager.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2002-2009. All Rights Reserved.
+%% Copyright Ericsson AB 2002-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
@@ -25,51 +25,77 @@
-include("http_internal.hrl").
%% Internal Application API
--export([start_link/1, start_link/2, request/2, cancel_request/2,
- request_canceled/2, retry_request/2, redirect_request/2,
- insert_session/2, delete_session/2, set_options/2, store_cookies/3,
- cookies/2, session_type/1]).
+-export([
+ start_link/3,
+ request/2,
+ cancel_request/2,
+ request_canceled/2,
+ request_done/2,
+ retry_request/2,
+ redirect_request/2,
+ insert_session/2,
+ delete_session/2,
+ set_options/2,
+ store_cookies/3,
+ which_cookies/1, which_cookies/2,
+ reset_cookies/1,
+ session_type/1,
+ info/1
+ ]).
%% gen_server callbacks
-export([init/1, handle_call/3, handle_cast/2, handle_info/2, terminate/2,
code_change/3]).
--record(state, {
+-record(state,
+ {
cancel = [], % [{RequestId, HandlerPid, ClientPid}]
- handler_db, % ets() - Entry: {Requestid, HandlerPid, ClientPid}
- cookie_db, % {ets(), dets()} - {session_cookie_db, cookie_db}
+ handler_db, % ets() - Entry: #handler_info{}
+ cookie_db, % cookie_db()
session_db, % ets() - Entry: #tcp_session{}
profile_name, % atom()
options = #options{}
}).
+-record(handler_info,
+ {
+ id, % Id of the request: request_id()
+ starter, % Pid of the handler starter process (temp): pid()
+ handler, % Pid of the handler process: pid()
+ from, % From for the request: from()
+ state % State of the handler: initiating | started | operational | canceled
+ }).
+
%%====================================================================
%% Internal Application API
%%====================================================================
%%--------------------------------------------------------------------
-%% Function: start_link({ProfileName, CookieDir}) -> {ok, Pid}
+%% Function: start_link(ProfileName, CookieDir, ManagedHow) -> {ok, Pid}
%%
%% ProfileName - httpc_manager_<Profile>
%% CookieDir - directory()
+%% ManagedHow - stand_alone | inets
%%
-%% Description: Starts the http request manger process. (Started by
-%% the intes supervisor.)
-%%--------------------------------------------------------------------
-start_link({default, CookieDir}) ->
- gen_server:start_link({local, ?MODULE}, ?MODULE,
- [?MODULE, {http_default_cookie_db, CookieDir}],
- []);
-start_link({Profile, CookieDir}) ->
- ProfileName = list_to_atom("httpc_manager_" ++ atom_to_list(Profile)),
- gen_server:start_link({local, ProfileName}, ?MODULE,
- [ProfileName,
- {http_default_cookie_db, CookieDir}], []).
-start_link({Profile, CookieDir}, stand_alone) ->
- ProfileName = list_to_atom("stand_alone_" ++ atom_to_list(Profile)),
- gen_server:start_link(?MODULE, [ProfileName,
- {http_default_cookie_db, CookieDir}],
- []).
+%% Description: Starts the http request manager process.
+%% (If ManagedHow = inets then started by the inets supervisor.)
+%%--------------------------------------------------------------------
+
+start_link(Profile, CookieDir, stand_alone) ->
+ ProfileName = httpc:profile_name("stand_alone_", Profile),
+ Args = [ProfileName, CookieDir],
+ Opts = [],
+ %% Opts = [{debug, [log, statistics]}],
+ gen_server:start_link(?MODULE, Args, Opts);
+start_link(Profile, CookieDir, _) ->
+ ProfileName = httpc:profile_name(Profile),
+ Server = {local, ProfileName},
+ Args = [ProfileName, CookieDir],
+ Opts = [],
+ %% Opts = [{debug, [log, statistics]}],
+ gen_server:start_link(Server, ?MODULE, Args, Opts).
+
+
%%--------------------------------------------------------------------
%% Function: request(Request, ProfileName) ->
%% {ok, Requestid} | {error, Reason}
@@ -78,8 +104,10 @@ start_link({Profile, CookieDir}, stand_alone) ->
%%
%% Description: Sends a request to the httpc manager process.
%%--------------------------------------------------------------------
+
request(Request, ProfileName) ->
- call(ProfileName, {request, Request}, infinity).
+ call(ProfileName, {request, Request}).
+
%%--------------------------------------------------------------------
%% Function: retry_request(Request, ProfileName) -> _
@@ -90,9 +118,11 @@ request(Request, ProfileName) ->
%% to be called by the httpc handler process if it has to terminate with
%% a non empty pipeline.
%%--------------------------------------------------------------------
+
retry_request(Request, ProfileName) ->
cast(ProfileName, {retry_or_redirect_request, Request}).
+
%%--------------------------------------------------------------------
%% Function: redirect_request(Request, ProfileName) -> _
%% Request = #request{}
@@ -102,9 +132,11 @@ retry_request(Request, ProfileName) ->
%% manager process, intended to be called by the httpc handler process
%% when the automatic redirect option is set.
%%--------------------------------------------------------------------
+
redirect_request(Request, ProfileName) ->
cast(ProfileName, {retry_or_redirect_request, Request}).
+
%%--------------------------------------------------------------------
%% Function: cancel_request(RequestId, ProfileName) -> ok
%% RequestId - ref()
@@ -112,8 +144,10 @@ redirect_request(Request, ProfileName) ->
%%
%% Description: Cancels the request with <RequestId>.
%%--------------------------------------------------------------------
+
cancel_request(RequestId, ProfileName) ->
- call(ProfileName, {cancel_request, RequestId}, infinity).
+ call(ProfileName, {cancel_request, RequestId}).
+
%%--------------------------------------------------------------------
%% Function: request_canceled(RequestId, ProfileName) -> ok
@@ -123,9 +157,23 @@ cancel_request(RequestId, ProfileName) ->
%% Description: Confirms that a request has been canceld. Intended to
%% be called by the httpc handler process.
%%--------------------------------------------------------------------
+
request_canceled(RequestId, ProfileName) ->
cast(ProfileName, {request_canceled, RequestId}).
+
+%%--------------------------------------------------------------------
+%% Function: request_done(RequestId, ProfileName) -> ok
+%% RequestId - ref()
+%% ProfileName = atom()
+%%
+%% Description: Inform tha manager that a request has been completed.
+%%--------------------------------------------------------------------
+
+request_done(RequestId, ProfileName) ->
+ cast(ProfileName, {request_done, RequestId}).
+
+
%%--------------------------------------------------------------------
%% Function: insert_session(Session, ProfileName) -> _
%% Session - #tcp_session{}
@@ -135,9 +183,12 @@ request_canceled(RequestId, ProfileName) ->
%% table <ProfileName>_session_db. Intended to be called by
%% the httpc request handler process.
%%--------------------------------------------------------------------
+
insert_session(Session, ProfileName) ->
- Db = list_to_atom(atom_to_list(ProfileName) ++ "_session_db"),
- ets:insert(Db, Session).
+ SessionDbName = session_db_name(ProfileName),
+ ?hcrt("insert session", [{session, Session}, {profile, ProfileName}]),
+ ets:insert(SessionDbName, Session).
+
%%--------------------------------------------------------------------
%% Function: delete_session(SessionId, ProfileName) -> _
@@ -148,9 +199,12 @@ insert_session(Session, ProfileName) ->
%% table httpc_manager_session_db_<Profile>. Intended to be called by
%% the httpc request handler process.
%%--------------------------------------------------------------------
+
delete_session(SessionId, ProfileName) ->
- Db = list_to_atom(atom_to_list(ProfileName) ++ "_session_db"),
- ets:delete(Db, SessionId).
+ SessionDbName = session_db_name(ProfileName),
+ ?hcrt("delete session", [{session_is, SessionId}, {profile, ProfileName}]),
+ ets:delete(SessionDbName, SessionId).
+
%%--------------------------------------------------------------------
%% Function: set_options(Options, ProfileName) -> ok
@@ -166,9 +220,11 @@ delete_session(SessionId, ProfileName) ->
%%
%% Description: Sets the options to be used by the client.
%%--------------------------------------------------------------------
+
set_options(Options, ProfileName) ->
cast(ProfileName, {set_options, Options}).
+
%%--------------------------------------------------------------------
%% Function: store_cookies(Cookies, Address, ProfileName) -> ok
%%
@@ -183,8 +239,22 @@ store_cookies([], _, _) ->
store_cookies(Cookies, Address, ProfileName) ->
cast(ProfileName, {store_cookies, {Cookies, Address}}).
+
+%%--------------------------------------------------------------------
+%% Function: reset_cookies(ProfileName) -> void()
+%%
+%% Url = string()
+%% ProfileName = atom()
+%%
+%% Description: Resets the cookie database
+%%--------------------------------------------------------------------
+
+reset_cookies(ProfileName) ->
+ call(ProfileName, reset_cookies).
+
+
%%--------------------------------------------------------------------
-%% Function: cookies(Url, ProfileName) -> ok
+%% Function: which_cookies(Url, ProfileName) -> [cookie()]
%%
%% Url = string()
%% ProfileName = atom()
@@ -192,8 +262,25 @@ store_cookies(Cookies, Address, ProfileName) ->
%% Description: Retrieves the cookies that would be sent when
%% requesting <Url>.
%%--------------------------------------------------------------------
-cookies(Url, ProfileName) ->
- call(ProfileName, {cookies, Url}, infinity).
+
+which_cookies(ProfileName) ->
+ call(ProfileName, which_cookies).
+which_cookies(Url, ProfileName) ->
+ call(ProfileName, {which_cookies, Url}).
+
+
+%%--------------------------------------------------------------------
+%% Function: info(ProfileName) -> list()
+%%
+%% ProfileName = atom()
+%%
+%% Description: Retrieves various info about the manager and the
+%% handlers it manages
+%%--------------------------------------------------------------------
+
+info(ProfileName) ->
+ call(ProfileName, info).
+
%%--------------------------------------------------------------------
%% Function: session_type(Options) -> ok
@@ -202,11 +289,13 @@ cookies(Url, ProfileName) ->
%%
%% Description: Determines if to use pipelined sessions or not.
%%--------------------------------------------------------------------
+
session_type(#options{pipeline_timeout = 0}) ->
keep_alive;
session_type(_) ->
pipeline.
+
%%====================================================================
%% gen_server callback functions
%%====================================================================
@@ -216,19 +305,46 @@ session_type(_) ->
%% {ok, State, Timeout} | ignore |{stop, Reason}
%% Description: Initiates the httpc_manger process
%%--------------------------------------------------------------------
-init([ProfileName, CookiesConf | _]) ->
+init([ProfileName, CookiesDir]) ->
process_flag(trap_exit, true),
- SessionDb = list_to_atom(atom_to_list(ProfileName) ++ "_session_db"),
- ets:new(SessionDb,
+ ?hcrv("starting", [{profile, ProfileName}]),
+ case (catch do_init(ProfileName, CookiesDir)) of
+ {ok, _} = OK ->
+ ?hcrd("started", [OK]),
+ OK;
+ {error, Reason} ->
+ {stop, Reason};
+ Crap ->
+ {stop, Crap}
+ end.
+
+
+do_init(ProfileName, CookiesDir) ->
+ %% Create session db
+ ?hcrt("create session db", []),
+ SessionDbName = session_db_name(ProfileName),
+ ets:new(SessionDbName,
[public, set, named_table, {keypos, #tcp_session.id}]),
- ?hcri("starting", [{profile, ProfileName}]),
- {ok, #state{handler_db = ets:new(handler_db, [protected, set]),
- cookie_db =
- http_cookie:open_cookie_db({CookiesConf,
- http_session_cookie_db}),
- session_db = SessionDb,
- profile_name = ProfileName
- }}.
+
+ %% Create handler db
+ ?hcrt("create handler/request db", []),
+ HandlerDbName = handler_db_name(ProfileName),
+ ets:new(HandlerDbName,
+ [protected, set, named_table, {keypos, #handler_info.id}]),
+
+ %% Cookie DB
+ ?hcrt("create cookie db", []),
+ SessionCookieDbName = session_cookie_db_name(ProfileName),
+ CookieDbName = cookie_db_name(ProfileName),
+ CookieDb = httpc_cookie:open_db(CookieDbName, CookiesDir,
+ SessionCookieDbName),
+
+ State = #state{handler_db = HandlerDbName,
+ cookie_db = CookieDb,
+ session_db = SessionDbName,
+ profile_name = ProfileName},
+ {ok, State}.
+
%%--------------------------------------------------------------------
%% Function: handle_call(Request, From, State) -> {reply, Reply, State} |
@@ -239,45 +355,80 @@ init([ProfileName, CookiesConf | _]) ->
%% {stop, Reason, State} (terminate/2 is called)
%% Description: Handling call messages
%%--------------------------------------------------------------------
-handle_call({request, Request}, _, State) ->
- ?hcri("request", [{request, Request}]),
+handle_call({request, Request}, _From, State) ->
+ ?hcrv("request", [{request, Request}]),
case (catch handle_request(Request, State)) of
- {reply, Msg, NewState} ->
- {reply, Msg, NewState};
+ {ok, ReqId, NewState} ->
+ {reply, {ok, ReqId}, NewState};
+
Error ->
- {stop, Error, httpc_response:error(Request, Error), State}
+ NewError = {error, {failed_process_request, Error}},
+ {reply, NewError, State}
end;
-handle_call({cancel_request, RequestId}, From, State) ->
- ?hcri("cancel_request", [{request_id, RequestId}]),
+handle_call({cancel_request, RequestId}, From,
+ #state{handler_db = HandlerDb} = State) ->
+ ?hcrv("cancel_request", [{request_id, RequestId}]),
case ets:lookup(State#state.handler_db, RequestId) of
[] ->
- ok, %% Nothing to cancel
- {reply, ok, State};
- [{_, Pid, _}] ->
+ ?hcrd("nothing to cancel", []),
+ Reply = ok, %% Nothing to cancel
+ {reply, Reply, State};
+
+ [#handler_info{handler = Pid}] when is_pid(Pid) ->
+ ?hcrd("found operational handler for this request",
+ [{handler, Pid}]),
httpc_handler:cancel(RequestId, Pid),
{noreply, State#state{cancel =
- [{RequestId, Pid, From} |
+ [{RequestId, Pid, From} |
+ State#state.cancel]}};
+
+ [#handler_info{starter = Pid, state = HandlerState}]
+ when is_pid(Pid) ->
+ ?hcri("found *initiating* handler for this request",
+ [{starter, Pid}, {state, HandlerState}]),
+ ets:update_element(HandlerDb, RequestId,
+ {#handler_info.state, canceled}),
+ {noreply, State#state{cancel =
+ [{RequestId, Pid, From} |
State#state.cancel]}}
+
end;
-handle_call({cookies, Url}, _, State) ->
+handle_call(reset_cookies, _, #state{cookie_db = CookieDb} = State) ->
+ ?hcrv("reset cookies", []),
+ httpc_cookie:reset_db(CookieDb),
+ {reply, ok, State};
+
+handle_call(which_cookies, _, #state{cookie_db = CookieDb} = State) ->
+ ?hcrv("which cookies", []),
+ CookieHeaders = httpc_cookie:which_cookies(CookieDb),
+ {reply, CookieHeaders, State};
+
+handle_call({which_cookies, Url}, _, #state{cookie_db = CookieDb} = State) ->
+ ?hcrv("which cookies", [{url, Url}]),
case http_uri:parse(Url) of
{Scheme, _, Host, Port, Path, _} ->
CookieHeaders =
- http_cookie:header(Scheme, {Host, Port},
- Path, State#state.cookie_db),
+ httpc_cookie:header(CookieDb, Scheme, {Host, Port}, Path),
{reply, CookieHeaders, State};
Msg ->
{reply, Msg, State}
end;
-handle_call(Msg, From, State) ->
- Report = io_lib:format("HTTPC_MANAGER recived unkown call: ~p"
- "from: ~p~n", [Msg, From]),
- error_logger:error_report(Report),
+handle_call(info, _, State) ->
+ ?hcrv("info", []),
+ Info = get_manager_info(State),
+ {reply, Info, State};
+
+handle_call(Req, From, #state{profile_name = ProfileName} = State) ->
+ error_report(ProfileName,
+ "received unkown request"
+ "~n Req: ~p"
+ "~n From: ~p", [Req, From]),
{reply, {error, 'API_violation'}, State}.
+
%%--------------------------------------------------------------------
%% Function: handle_cast(Msg, State) -> {noreply, State} |
%% {noreply, State, Timeout} |
@@ -286,29 +437,66 @@ handle_call(Msg, From, State) ->
%%--------------------------------------------------------------------
handle_cast({retry_or_redirect_request, {Time, Request}},
#state{profile_name = ProfileName} = State) ->
- {ok, _} = timer:apply_after(Time, ?MODULE, retry_request, [Request, ProfileName]),
- {noreply, State};
+ ?hcrv("retry or redirect request", [{time, Time}, {request, Request}]),
+ case timer:apply_after(Time, ?MODULE, retry_request,
+ [Request, ProfileName]) of
+ {ok, _} ->
+ {noreply, State};
+ {error, Reason} ->
+ error_report(ProfileName,
+ "failed scheduling retry/redirect request"
+ "~n Time: ~p"
+ "~n Request: ~p"
+ "~n Reason: ~p", [Time, Request, Reason]),
+ {noreply, State}
+ end;
-handle_cast({retry_or_redirect_request, Request}, State) ->
+handle_cast({retry_or_redirect_request, Request},
+ #state{profile_name = Profile,
+ handler_db = HandlerDb} = State) ->
+ ?hcrv("retry or redirect request", [{request, Request}]),
case (catch handle_request(Request, State)) of
- {reply, {ok, _}, NewState} ->
+ {ok, _, NewState} ->
{noreply, NewState};
+
Error ->
- httpc_response:error(Request, Error),
- {stop, Error, State}
+ ReqId = Request#request.id,
+ error_report(Profile,
+ "failed to retry or redirect request ~p"
+ "~n Error: ~p", [ReqId, Error]),
+ case ets:lookup(HandlerDb, ReqId) of
+ [#handler_info{from = From}] ->
+ Error2 = httpc_response:error(Request, Error),
+ httpc_response:send(From, Error2),
+ ok;
+
+ _ ->
+ ok
+ end,
+ {noreply, State}
end;
handle_cast({request_canceled, RequestId}, State) ->
+ ?hcrv("request canceled", [{request_id, RequestId}]),
ets:delete(State#state.handler_db, RequestId),
case lists:keysearch(RequestId, 1, State#state.cancel) of
{value, Entry = {RequestId, _, From}} ->
+ ?hcrt("found in cancel", [{from, From}]),
gen_server:reply(From, ok),
{noreply,
State#state{cancel = lists:delete(Entry, State#state.cancel)}};
- _ ->
+ Else ->
+ ?hcrt("not found in cancel", [{else, Else}]),
{noreply, State}
end;
+
+handle_cast({request_done, RequestId}, State) ->
+ ?hcrv("request done", [{request_id, RequestId}]),
+ ets:delete(State#state.handler_db, RequestId),
+ {noreply, State};
+
handle_cast({set_options, Options}, State = #state{options = OldOptions}) ->
+ ?hcrv("set options", [{options, Options}, {old_options, OldOptions}]),
NewOptions =
#options{proxy = get_proxy(Options, OldOptions),
pipeline_timeout = get_pipeline_timeout(Options, OldOptions),
@@ -320,7 +508,8 @@ handle_cast({set_options, Options}, State = #state{options = OldOptions}) ->
ipfamily = get_ipfamily(Options, OldOptions),
ip = get_ip(Options, OldOptions),
port = get_port(Options, OldOptions),
- verbose = get_verbose(Options, OldOptions)
+ verbose = get_verbose(Options, OldOptions),
+ socket_opts = get_socket_opts(Options, OldOptions)
},
case {OldOptions#options.verbose, NewOptions#options.verbose} of
{Same, Same} ->
@@ -345,10 +534,10 @@ handle_cast({store_cookies, {Cookies, _}}, State) ->
ok = do_store_cookies(Cookies, State),
{noreply, State};
-handle_cast(Msg, State) ->
- Report = io_lib:format("HTTPC_MANAGER recived unkown cast: ~p",
- [Msg]),
- error_logger:error_report(Report),
+handle_cast(Msg, #state{profile_name = ProfileName} = State) ->
+ error_report(ProfileName,
+ "recived unknown message"
+ "~n Msg: ~p", [Msg]),
{noreply, State}.
@@ -359,17 +548,39 @@ handle_cast(Msg, State) ->
%% {stop, Reason, State} (terminate/2 is called)
%% Description: Handling all non call/cast messages
%%---------------------------------------------------------
-handle_info({'EXIT', _, _}, State) ->
- %% Handled in DOWN
+
+handle_info({started, StarterPid, ReqId, HandlerPid}, State) ->
+ handle_started(StarterPid, ReqId, HandlerPid, State),
+ {noreply, State};
+
+handle_info({connect_and_send, StarterPid, ReqId, HandlerPid, Res}, State) ->
+ handle_connect_and_send(StarterPid, ReqId, HandlerPid, Res, State),
{noreply, State};
+
+handle_info({failed_starting_handler, StarterPid, ReqId, Res}, State) ->
+ handle_failed_starting_handler(StarterPid, ReqId, Res, State),
+ {noreply, State};
+
+handle_info({'EXIT', Pid, Reason}, #state{handler_db = HandlerDb} = State) ->
+ maybe_handle_terminating_starter(Pid, Reason, HandlerDb),
+ {noreply, State};
+
handle_info({'DOWN', _, _, Pid, _}, State) ->
- ets:match_delete(State#state.handler_db, {'_', Pid, '_'}),
+
+ %%
+ %% Normally this should have been cleaned up already
+ %% (when receiving {request_done, PequestId}), but
+ %% just in case there is a glitch, cleanup anyway.
+ %%
+
+ Pattern = #handler_info{handler = Pid, _ = '_'},
+ ets:match_delete(State#state.handler_db, Pattern),
%% If there where any canceled request, handled by the
%% the process that now has terminated, the
%% cancelation can be viewed as sucessfull!
- NewCanceldList =
- lists:foldl(fun(Entry = {_, HandlerPid, From}, Acc) ->
+ NewCanceledList =
+ lists:foldl(fun({_, HandlerPid, From} = Entry, Acc) ->
case HandlerPid of
Pid ->
gen_server:reply(From, ok),
@@ -378,21 +589,25 @@ handle_info({'DOWN', _, _, Pid, _}, State) ->
Acc
end
end, State#state.cancel, State#state.cancel),
- {noreply, State#state{cancel = NewCanceldList}};
-handle_info(Info, State) ->
- Report = io_lib:format("Unknown message in "
- "httpc_manager:handle_info ~p~n", [Info]),
- error_logger:error_report(Report),
+ {noreply, State#state{cancel = NewCanceledList}};
+
+handle_info(Info, #state{profile_name = ProfileName} = State) ->
+ error_report(ProfileName,
+ "received unknown info"
+ "~n Info: ~p", [Info]),
{noreply, State}.
+
+
%%--------------------------------------------------------------------
%% Function: terminate(Reason, State) -> _ (ignored by gen_server)
%% Description: Shutdown the httpc_handler
%%--------------------------------------------------------------------
terminate(_, State) ->
- http_cookie:close_cookie_db(State#state.cookie_db),
+ httpc_cookie:close_db(State#state.cookie_db),
ets:delete(State#state.session_db),
ets:delete(State#state.handler_db).
+
%%--------------------------------------------------------------------
%% Func: code_change(_OldVsn, State, Extra) -> {ok, NewState}
%% Purpose: Convert process state when code is changed
@@ -400,70 +615,286 @@ terminate(_, State) ->
code_change(_OldVsn, State, _Extra) ->
{ok, State}.
+
%%--------------------------------------------------------------------
%% Internal functions
%%--------------------------------------------------------------------
-handle_request(#request{settings =
- #http_options{version = "HTTP/0.9"}} = Request,
- State) ->
- %% Act as an HTTP/0.9 client that does not know anything
- %% about persistent connections
- NewRequest = handle_cookies(generate_request_id(Request), State),
- NewHeaders =
- (NewRequest#request.headers)#http_request_h{connection
- = undefined},
- start_handler(NewRequest#request{headers = NewHeaders}, State),
- {reply, {ok, NewRequest#request.id}, State};
+get_manager_info(#state{handler_db = HDB,
+ cookie_db = CDB} = _State) ->
+ HandlerInfo = get_handler_info(HDB),
+ CookieInfo = httpc_cookie:which_cookies(CDB),
+ [{handlers, HandlerInfo}, {cookies, CookieInfo}].
+
+get_handler_info(Tab) ->
+ Pattern = #handler_info{handler = '$1',
+ state = '$2',
+ _ = '_'},
+ Handlers1 = [{Pid, State} || [Pid, State] <- ets:match(Tab, Pattern)],
+ F = fun({Pid, State} = Elem, Acc) when State =/= canceled ->
+ case lists:keymember(Pid, 1, Acc) of
+ true ->
+ Acc;
+ false ->
+ [Elem | Acc]
+ end;
+ (_, Acc) ->
+ Acc
+ end,
+ Handlers2 = lists:foldl(F, [], Handlers1),
+ Handlers3 = [{Pid, State,
+ case (catch httpc_handler:info(Pid)) of
+ {'EXIT', _} ->
+ %% Why would this crash?
+ %% Only if the process has died, but we don't
+ %% know about it?
+ [];
+ Else ->
+ Else
+ end} ||
+ {Pid, State} <- Handlers2],
+ Handlers3.
+
+
+%%
+%% The request handler process is started asynchronously by a
+%% "starter process". When the handler has sucessfully been started,
+%% this message (started) is sent.
+%%
+
+handle_started(StarterPid, ReqId, HandlerPid,
+ #state{profile_name = Profile,
+ handler_db = HandlerDb}) ->
+ case ets:lookup(HandlerDb, ReqId) of
+ [#handler_info{state = initiating} = HandlerInfo] ->
+ ?hcri("received started ack for initiating handler", []),
+ %% As a last resort, make sure we know when it exits,
+ %% in case it forgets to notify us.
+ %% We dont need to know the ref id?
+ erlang:monitor(process, HandlerPid),
+ HandlerInfo2 = HandlerInfo#handler_info{handler = HandlerPid,
+ state = started},
+ ets:insert(HandlerDb, HandlerInfo2),
+ ok;
+
+ [#handler_info{state = State}] ->
+ error_report(Profile,
+ "unexpected (started) message for handler (~p) in state "
+ "~p regarding request ~p - ignoring", [HandlerPid, State, ReqId]),
+ ?hcri("received unexpected started message", [{state, State}]),
+ ok;
+
+ [] ->
+ error_report(Profile,
+ "unknown handler ~p (~p) started for request ~w - canceling",
+ [HandlerPid, StarterPid, ReqId]),
+ httpc_handler:cancel(ReqId, HandlerPid)
+ end.
+
+
+%%
+%% The request handler process is started asynchronously by a
+%% "starter process". When that process terminates it sends
+%% one of two messages. These ara handled by the two functions
+%% below.
+%%
+
+handle_connect_and_send(_StarterPid, ReqId, HandlerPid, Result,
+ #state{profile_name = Profile,
+ handler_db = HandlerDb}) ->
+ case ets:lookup(HandlerDb, ReqId) of
+ [#handler_info{state = started} = HandlerInfo] when Result =:= ok ->
+ ?hcri("received connect-and-send ack for started handler", []),
+ HandlerInfo2 = HandlerInfo#handler_info{starter = undefined,
+ handler = HandlerPid,
+ state = operational},
+ ets:insert(HandlerDb, HandlerInfo2),
+ ok;
+
+ [#handler_info{state = canceled} = HandlerInfo] when Result =:= ok ->
+ ?hcri("received connect-and-send ack for canceled handler", []),
+ httpc_handler:cancel(ReqId, HandlerPid),
+ HandlerInfo2 = HandlerInfo#handler_info{starter = undefined,
+ handler = HandlerPid},
+ ets:insert(HandlerDb, HandlerInfo2),
+ ok;
+
+ [#handler_info{state = State}] when Result =/= ok ->
+ error_report(Profile,
+ "handler (~p, ~w) failed to connect and/or "
+ "send request ~p"
+ "~n Result: ~p",
+ [HandlerPid, State, ReqId, Result]),
+ ?hcri("received connect-and-send error",
+ [{result, Result}, {state, State}]),
+ %% We don't need to send a response to the original caller
+ %% because the handler already sent one in its terminate
+ %% function.
+ ets:delete(HandlerDb, ReqId),
+ ok;
+
+ [] ->
+ error_report(Profile,
+ "handler (~p) successfully started "
+ "for unknown request ~p => canceling",
+ [HandlerPid, ReqId]),
+ httpc_handler:cancel(ReqId, HandlerPid)
+ end.
+
+handle_failed_starting_handler(_StarterPid, ReqId, Error,
+ #state{profile_name = Profile,
+ handler_db = HandlerDb}) ->
+ case ets:lookup(HandlerDb, ReqId) of
+ [#handler_info{state = canceled}] ->
+ error_report(Profile,
+ "failed starting handler for request ~p"
+ "~n Error: ~p", [ReqId, Error]),
+ request_canceled(Profile, ReqId), % Fake signal from handler
+ ets:delete(HandlerDb, ReqId),
+ ok;
+
+ [#handler_info{from = From}] ->
+ error_report(Profile,
+ "failed starting handler for request ~p"
+ "~n Error: ~p", [ReqId, Error]),
+ Reason2 =
+ case Error of
+ {error, Reason} ->
+ {failed_connecting, Reason};
+ _ ->
+ {failed_connecting, Error}
+ end,
+ DummyReq = #request{id = ReqId},
+ httpc_response:send(From, httpc_response:error(DummyReq, Reason2)),
+ ets:delete(HandlerDb, ReqId),
+ ok;
+
+ [] ->
+ error_report(Profile,
+ "failed starting handler for unknown request ~p"
+ "~n Error: ~p", [ReqId, Error]),
+ ok
+ end.
+
+
+maybe_handle_terminating_starter(MeybeStarterPid, Reason, HandlerDb) ->
+ Pattern = #handler_info{starter = MeybeStarterPid, _ = '_'},
+ case ets:match_object(HandlerDb, Pattern) of
+ [#handler_info{id = ReqId, from = From, state = initiating}] ->
+ %% The starter process crashed before it could start the
+ %% the handler process, therefor we need to answer the
+ %% original caller.
+ ?hcri("starter process crashed bfore starting handler",
+ [{starter, MeybeStarterPid}, {reason, Reason}]),
+ Reason2 =
+ case Reason of
+ {error, Error} ->
+ {failed_connecting, Error};
+ _ ->
+ {failed_connecting, Reason}
+ end,
+ DummyReq = #request{id = ReqId},
+ httpc_response:send(From, httpc_response:error(DummyReq, Reason2)),
+ ets:delete(HandlerDb, ReqId),
+ ok;
+
+ [#handler_info{state = State} = HandlerInfo] ->
+ %% The starter process crashed after the handler was started.
+ %% The handler will answer to the original caller.
+ ?hcri("starter process crashed after starting handler",
+ [{starter, MeybeStarterPid}, {reason, Reason}, {state, State}]),
+ HandlerInfo2 = HandlerInfo#handler_info{starter = undefined},
+ ets:insert(HandlerDb, HandlerInfo2),
+ ok;
+
+ _ ->
+ ok
+ end.
+
+
+%% -----
+%% Act as an HTTP/0.9 client that does not know anything
+%% about persistent connections
+handle_request(#request{settings =
+ #http_options{version = "HTTP/0.9"}} = Request0,
+ State) ->
+ Request1 = handle_cookies(generate_request_id(Request0), State),
+ Hdrs0 = Request1#request.headers,
+ Hdrs1 = Hdrs0#http_request_h{connection = undefined},
+ Request2 = Request1#request{headers = Hdrs1},
+ create_handler_starter(Request2, State),
+ {ok, Request2#request.id, State};
+
+%% -----
+%% Act as an HTTP/1.0 client that does not
+%% use persistent connections
handle_request(#request{settings =
- #http_options{version = "HTTP/1.0"}} = Request,
+ #http_options{version = "HTTP/1.0"}} = Request0,
State) ->
- %% Act as an HTTP/1.0 client that does not
- %% use persistent connections
-
- NewRequest = handle_cookies(generate_request_id(Request), State),
- NewHeaders =
- (NewRequest#request.headers)#http_request_h{connection
- = "close"},
- start_handler(NewRequest#request{headers = NewHeaders}, State),
- {reply, {ok, NewRequest#request.id}, State};
-
-handle_request(Request, State = #state{options = Options}) ->
-
- NewRequest = handle_cookies(generate_request_id(Request), State),
- SessionType = session_type(Options),
- case select_session(Request#request.method,
- Request#request.address,
- Request#request.scheme, SessionType, State) of
+ Request1 = handle_cookies(generate_request_id(Request0), State),
+ Hdrs0 = Request1#request.headers,
+ Hdrs1 = Hdrs0#http_request_h{connection = "close"},
+ Request2 = Request1#request{headers = Hdrs1},
+ create_handler_starter(Request2, State),
+ {ok, Request2#request.id, State};
+
+
+%% -----
+handle_request(#request{method = Method,
+ address = Address,
+ scheme = Scheme} = Request0,
+ #state{options = Opts} = State) ->
+ Request1 = handle_cookies(generate_request_id(Request0), State),
+ SessionType = session_type(Opts),
+ case select_session(Method, Address, Scheme, SessionType, State) of
{ok, HandlerPid} ->
- pipeline_or_keep_alive(NewRequest, HandlerPid, State);
+ pipeline_or_keep_alive(Request1, HandlerPid, State);
no_connection ->
- start_handler(NewRequest, State);
- {no_session, OpenSessions} when OpenSessions
- < Options#options.max_sessions ->
- start_handler(NewRequest, State);
+ create_handler_starter(Request1, State);
+ {no_session, OpenSessions}
+ when OpenSessions < Opts#options.max_sessions ->
+ create_handler_starter(Request1, State);
{no_session, _} ->
%% Do not start any more persistent connections
%% towards this server.
- NewHeaders =
- (NewRequest#request.headers)#http_request_h{connection
- = "close"},
- start_handler(NewRequest#request{headers = NewHeaders}, State)
+ Hdrs0 = Request1#request.headers,
+ Hdrs1 = Hdrs0#http_request_h{connection = "close"},
+ Request2 = Request1#request{headers = Hdrs1},
+ create_handler_starter(Request2, State)
end,
- {reply, {ok, NewRequest#request.id}, State}.
+ {ok, Request1#request.id, State}.
-select_session(Method, HostPort, Scheme, SessionTyp,
- #state{options = #options{max_pipeline_length =
- MaxPipe,
+
+select_session(Method, HostPort, Scheme, SessionType,
+ #state{options = #options{max_pipeline_length = MaxPipe,
max_keep_alive_length = MaxKeepAlive},
session_db = SessionDb}) ->
- case httpc_request:is_idempotent(Method) or (SessionTyp == keep_alive) of
+ ?hcrd("select session", [{session_type, SessionType},
+ {max_pipeline_length, MaxPipe},
+ {max_keep_alive_length, MaxKeepAlive}]),
+ case httpc_request:is_idempotent(Method) orelse
+ (SessionType =:= keep_alive) of
true ->
- Candidates = ets:match(SessionDb,
- {'_', {HostPort, '$1'},
- false, Scheme, '_', '$2', SessionTyp}),
- select_session(Candidates, MaxKeepAlive, MaxPipe, SessionTyp);
+ %% Look for handlers connecting to this host (HostPort)
+ %% tcp_session with record name field (tcp_session) and
+ %% socket fields ignored. The fields id (part of: HostPort),
+ %% client_close, scheme and type specified.
+ %% The fields id (part of: HandlerPid) and queue_length
+ %% specified.
+ Pattern = #tcp_session{id = {HostPort, '$1'},
+ client_close = false,
+ scheme = Scheme,
+ socket = '_',
+ queue_length = '$2',
+ type = SessionType},
+ %% {'_', {HostPort, '$1'}, false, Scheme, '_', '$2', SessionTyp},
+ Candidates = ets:match(SessionDb, Pattern),
+ ?hcrd("select session", [{host_port, HostPort},
+ {scheme, Scheme},
+ {type, SessionType},
+ {candidates, Candidates}]),
+ select_session(Candidates, MaxKeepAlive, MaxPipe, SessionType);
false ->
no_connection
end.
@@ -473,51 +904,105 @@ select_session(Candidates, Max, _, keep_alive) ->
select_session(Candidates, _, Max, pipeline) ->
select_session(Candidates, Max).
+select_session([] = _Candidates, _Max) ->
+ ?hcrd("select session - no candicate", []),
+ no_connection;
select_session(Candidates, Max) ->
- case Candidates of
+ NewCandidates =
+ [{Pid, Length} || [Pid, Length] <- Candidates, Length =< Max],
+ case lists:keysort(2, NewCandidates) of
[] ->
- no_connection;
- _ ->
- NewCandidates =
- lists:foldl(
- fun([Pid, Length], Acc) when Length =< Max ->
- [{Pid, Length} | Acc];
- (_, Acc) ->
- Acc
- end, [], Candidates),
-
- case lists:keysort(2, NewCandidates) of
- [] ->
- {no_session, length(Candidates)};
- [{HandlerPid, _} | _] ->
- {ok, HandlerPid}
- end
+ {no_session, length(Candidates)};
+ [{HandlerPid, _} | _] ->
+ ?hcrd("select session - found one", [{handler, HandlerPid}]),
+ {ok, HandlerPid}
end.
-pipeline_or_keep_alive(Request, HandlerPid, State) ->
+pipeline_or_keep_alive(#request{id = Id} = Request, HandlerPid, State) ->
+ ?hcrd("pipeline of keep-alive", [{id, Id}, {handler, HandlerPid}]),
case (catch httpc_handler:send(Request, HandlerPid)) of
ok ->
- ets:insert(State#state.handler_db, {Request#request.id,
- HandlerPid,
- Request#request.from});
- _ -> %timeout pipelining failed
- start_handler(Request, State)
+ ?hcrd("pipeline or keep-alive - successfully sent", []),
+ Entry = #handler_info{id = Id,
+ handler = HandlerPid,
+ state = operational},
+ ets:insert(State#state.handler_db, Entry);
+
+ _ -> %% timeout pipelining failed
+ ?hcrd("pipeline or keep-alive - failed sending -> "
+ "start a new handler", []),
+ create_handler_starter(Request, State)
end.
-start_handler(Request, State) ->
- {ok, Pid} =
- case is_inets_manager() of
- true ->
- httpc_handler_sup:start_child([Request, State#state.options,
- State#state.profile_name]);
- false ->
- httpc_handler:start_link(Request, State#state.options,
- State#state.profile_name)
- end,
- ets:insert(State#state.handler_db, {Request#request.id,
- Pid, Request#request.from}),
- erlang:monitor(process, Pid).
+create_handler_starter(#request{socket_opts = SocketOpts} = Request,
+ #state{options = Options} = State)
+ when is_list(SocketOpts) ->
+ %% The user provided us with (override) socket options
+ ?hcrt("create handler starter", [{socket_opts, SocketOpts}, {options, Options}]),
+ Options2 = Options#options{socket_opts = SocketOpts},
+ create_handler_starter(Request#request{socket_opts = undefined},
+ State#state{options = Options2});
+
+create_handler_starter(#request{id = Id,
+ from = From} = Request,
+ #state{profile_name = ProfileName,
+ options = Options,
+ handler_db = HandlerDb} = _State) ->
+ ?hcrv("create handler starter", [{id, Id}, {profile, ProfileName}]),
+ IsInetsManager = is_inets_manager(),
+ ManagerPid = self(),
+ StarterFun =
+ fun() ->
+ ?hcrd("handler starter - start",
+ [{id, Id},
+ {profile, ProfileName},
+ {inets_manager, IsInetsManager}]),
+ Result1 =
+ case IsInetsManager of
+ true ->
+ httpc_handler_sup:start_child(Options,
+ ProfileName);
+ false ->
+ httpc_handler:start_link(Options,
+ ProfileName)
+ end,
+ ?hcrd("handler starter - maybe connect and send",
+ [{id, Id}, {profile, ProfileName}, {result, Result1}]),
+ case Result1 of
+ {ok, HandlerPid} ->
+ StartedMessage =
+ {started, self(), Id, HandlerPid},
+ ManagerPid ! StartedMessage,
+ Result2 = httpc_handler:connect_and_send(Request,
+ HandlerPid),
+ ?hcrd("handler starter - connected and sent",
+ [{id, Id}, {profile, ProfileName},
+ {handler, HandlerPid}, {result, Result2}]),
+ ConnAndSendMessage =
+ {connect_and_send,
+ self(), Id, HandlerPid, Result2},
+ ManagerPid ! ConnAndSendMessage;
+ {error, Reason} ->
+ StartFailureMessage =
+ {failed_starting_handler, self(), Id, Reason},
+ ManagerPid ! StartFailureMessage;
+ _ ->
+ StartFailureMessage =
+ {failed_starting_handler, self(), Id, Result1},
+ ManagerPid ! StartFailureMessage
+ end
+ end,
+ Starter = erlang:spawn_link(StarterFun),
+ ?hcrd("create handler starter - started", [{id, Id}, {starter, Starter}]),
+ Entry = #handler_info{id = Id,
+ starter = Starter,
+ from = From,
+ state = initiating},
+ ets:insert(HandlerDb, Entry),
+ ok.
+
+
is_inets_manager() ->
case get('$ancestors') of
[httpc_profile_sup | _] ->
@@ -532,32 +1017,55 @@ generate_request_id(Request) ->
RequestId = make_ref(),
Request#request{id = RequestId};
_ ->
- %% This is an automatic redirect or a retryed pipelined
- %% request keep the old id.
+ %% This is an automatic redirect or a retryed pipelined request
+ %% => keep the old id.
Request
end.
handle_cookies(Request, #state{options = #options{cookies = disabled}}) ->
Request;
-handle_cookies(Request = #request{scheme = Scheme, address = Address,
- path = Path, headers =
- Headers = #http_request_h{other = Other}},
- #state{cookie_db = Db}) ->
- case http_cookie:header(Scheme, Address, Path, Db) of
+handle_cookies(
+ #request{scheme = Scheme,
+ address = Address,
+ path = Path,
+ headers = #http_request_h{other = Other} = Hdrs} = Request,
+ #state{cookie_db = CookieDb}) ->
+ case httpc_cookie:header(CookieDb, Scheme, Address, Path) of
{"cookie", ""} ->
Request;
CookieHeader ->
- NewHeaders =
- Headers#http_request_h{other = [CookieHeader | Other]},
+ NewHeaders = Hdrs#http_request_h{other = [CookieHeader | Other]},
Request#request{headers = NewHeaders}
end.
do_store_cookies([], _) ->
ok;
-do_store_cookies([Cookie | Cookies], State) ->
- ok = http_cookie:insert(Cookie, State#state.cookie_db),
+do_store_cookies([Cookie | Cookies], #state{cookie_db = CookieDb} = State) ->
+ ok = httpc_cookie:insert(CookieDb, Cookie),
do_store_cookies(Cookies, State).
+
+
+session_db_name(ProfileName) ->
+ make_db_name(ProfileName, "__session_db").
+
+cookie_db_name(ProfileName) ->
+ make_db_name(ProfileName, "__cookie_db").
+
+session_cookie_db_name(ProfileName) ->
+ make_db_name(ProfileName, "__session_cookie_db").
+
+handler_db_name(ProfileName) ->
+ make_db_name(ProfileName, "__handler_db").
+
+make_db_name(ProfileName, Post) ->
+ list_to_atom(atom_to_list(ProfileName) ++ Post).
+
+
+
+call(ProfileName, Msg) ->
+ Timeout = infinity,
+ call(ProfileName, Msg, Timeout).
call(ProfileName, Msg, Timeout) ->
gen_server:call(ProfileName, Msg, Timeout).
@@ -611,6 +1119,9 @@ get_port(Opts, #options{port = Default}) ->
get_verbose(Opts, #options{verbose = Default}) ->
proplists:get_value(verbose, Opts, Default).
+get_socket_opts(Opts, #options{socket_opts = Default}) ->
+ proplists:get_value(socket_opts, Opts, Default).
+
handle_verbose(debug) ->
dbg:p(self(), [call]),
@@ -621,6 +1132,12 @@ handle_verbose(trace) ->
handle_verbose(_) ->
ok.
+
+error_report(Profile, F, A) ->
+ Report = io_lib:format("HTTPC-MANAGER<~p> " ++ F ++ "~n", [Profile | A]),
+ error_logger:error_report(Report).
+
+
%% d(F) ->
%% d(F, []).
diff --git a/lib/inets/src/http_client/httpc_profile_sup.erl b/lib/inets/src/http_client/httpc_profile_sup.erl
index 2351083435..29f86aa373 100644
--- a/lib/inets/src/http_client/httpc_profile_sup.erl
+++ b/lib/inets/src/http_client/httpc_profile_sup.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2007-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 2007-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%
%%
%%
@@ -28,6 +28,7 @@
%% Supervisor callback
-export([init/1]).
+
%%%=========================================================================
%%% API
%%%=========================================================================
@@ -39,7 +40,8 @@ start_child(PropList) ->
undefined ->
{error, no_profile};
Profile ->
- Dir = proplists:get_value(data_dir, PropList, only_session_cookies),
+ Dir =
+ proplists:get_value(data_dir, PropList, only_session_cookies),
Spec = httpc_child_spec(Profile, Dir),
supervisor:start_child(?MODULE, Spec)
end.
@@ -63,12 +65,12 @@ stop_child(Profile) ->
end.
id(Profile) ->
- DefaultProfile = http:default_profile(),
+ DefaultProfile = httpc:default_profile(),
case Profile of
DefaultProfile ->
httpc_manager;
_ ->
- {http, Profile}
+ {httpc, Profile}
end.
@@ -98,7 +100,7 @@ child_spec([{httpc, PropList} | Rest], Acc) when is_list(PropList) ->
httpc_child_spec(Profile, Dir) ->
Name = id(Profile),
- StartFunc = {httpc_manager, start_link, [{Profile, Dir}]},
+ StartFunc = {httpc_manager, start_link, [Profile, Dir, inets]},
Restart = permanent,
Shutdown = 4000,
Modules = [httpc_manager],
diff --git a/lib/inets/src/http_client/httpc_request.erl b/lib/inets/src/http_client/httpc_request.erl
index 3d66638d66..55e0af4b42 100644
--- a/lib/inets/src/http_client/httpc_request.erl
+++ b/lib/inets/src/http_client/httpc_request.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2004-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 2004-2010. All Rights Reserved.
+%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
-%%
+%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
-%%
+%%
%% %CopyrightEnd%
%%
@@ -39,14 +39,47 @@
%%
%% Description: Composes and sends a HTTP-request.
%%-------------------------------------------------------------------------
-send(SendAddr, #request{method = Method, scheme = Scheme,
- path = Path, pquery = Query, headers = Headers,
- content = Content, address = Address,
- abs_uri = AbsUri, headers_as_is = HeadersAsIs,
- settings = HttpOptions,
- userinfo = UserInfo},
- Socket) ->
+send(SendAddr, #request{scheme = Scheme, socket_opts = SocketOpts} = Request,
+ Socket)
+ when is_list(SocketOpts) ->
+ SocketType = socket_type(Scheme),
+ case http_transport:setopts(SocketType, Socket, SocketOpts) of
+ ok ->
+ send(SendAddr, Socket, SocketType,
+ Request#request{socket_opts = undefined});
+ {error, Reason} ->
+ {error, {setopts_failed, Reason}}
+ end;
+send(SendAddr, #request{scheme = Scheme} = Request, Socket) ->
+ SocketType = socket_type(Scheme),
+ send(SendAddr, Socket, SocketType, Request).
+
+send(SendAddr, Socket, SocketType,
+ #request{method = Method,
+ path = Path,
+ pquery = Query,
+ headers = Headers,
+ content = Content,
+ address = Address,
+ abs_uri = AbsUri,
+ headers_as_is = HeadersAsIs,
+ settings = HttpOptions,
+ userinfo = UserInfo}) ->
+ ?hcrt("send",
+ [{send_addr, SendAddr},
+ {socket, Socket},
+ {method, Method},
+ {path, Path},
+ {pquery, Query},
+ {headers, Headers},
+ {content, Content},
+ {address, Address},
+ {abs_uri, AbsUri},
+ {headers_as_is, HeadersAsIs},
+ {settings, HttpOptions},
+ {userinfo, UserInfo}]),
+
TmpHeaders = handle_user_info(UserInfo, Headers),
{TmpHeaders2, Body} =
@@ -70,9 +103,14 @@ send(SendAddr, #request{method = Method, scheme = Scheme,
Version = HttpOptions#http_options.version,
Message = [method(Method), " ", Uri, " ",
- version(Version), ?CRLF, headers(FinalHeaders, Version), ?CRLF, Body],
+ version(Version), ?CRLF,
+ headers(FinalHeaders, Version), ?CRLF, Body],
+
+ ?hcrd("send", [{message, Message}]),
- http_transport:send(socket_type(Scheme), Socket, lists:append(Message)).
+ http_transport:send(SocketType, Socket, lists:append(Message)).
+
+
%%-------------------------------------------------------------------------
%% is_idempotent(Method) ->
@@ -123,7 +161,7 @@ is_client_closing(Headers) ->
%%% Internal functions
%%%========================================================================
post_data(Method, Headers, {ContentType, Body}, HeadersAsIs)
- when Method == post; Method == put ->
+ when (Method =:= post) orelse (Method =:= put) ->
ContentLength = body_length(Body),
NewBody = case Headers#http_request_h.expect of
"100-continue" ->
diff --git a/lib/inets/src/http_client/httpc_response.erl b/lib/inets/src/http_client/httpc_response.erl
index e2ba66f730..df7d40a33e 100644
--- a/lib/inets/src/http_client/httpc_response.erl
+++ b/lib/inets/src/http_client/httpc_response.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2004-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 2004-2010. All Rights Reserved.
+%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
-%%
+%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
-%%
+%%
%% %CopyrightEnd%
%%
@@ -132,8 +132,13 @@ result(Response = {{_,Code,_}, _, _}, Request) when (Code div 100) =:= 5 ->
result(Response, Request) ->
transparent(Response, Request).
-send(To, Msg) ->
- To ! {http, Msg}.
+send(Receiver, Msg) when is_pid(Receiver) ->
+ Receiver ! {http, Msg};
+send(Receiver, Msg) when is_function(Receiver) ->
+ (catch Receiver(Msg));
+send({Module, Function, Args}, Msg) ->
+ (catch apply(Module, Function, [Msg | Args])).
+
%%%========================================================================
%%% Internal functions
diff --git a/lib/inets/src/http_lib/Makefile b/lib/inets/src/http_lib/Makefile
index 27e7ee65c5..a715e3c9af 100644
--- a/lib/inets/src/http_lib/Makefile
+++ b/lib/inets/src/http_lib/Makefile
@@ -1,19 +1,19 @@
#
# %CopyrightBegin%
-#
-# Copyright Ericsson AB 2005-2009. All Rights Reserved.
-#
+#
+# Copyright Ericsson AB 2005-2011. All Rights Reserved.
+#
# The contents of this file are subject to the Erlang Public License,
# Version 1.1, (the "License"); you may not use this file except in
# compliance with the License. You should have received a copy of the
# Erlang Public License along with this software. If not, it can be
# retrieved online at http://www.erlang.org/.
-#
+#
# Software distributed under the License is distributed on an "AS IS"
# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
# the License for the specific language governing rights and limitations
# under the License.
-#
+#
# %CopyrightEnd%
#
#
@@ -22,6 +22,7 @@ include $(ERL_TOP)/make/target.mk
EBIN = ../../ebin
include $(ERL_TOP)/make/$(TARGET)/otp.mk
+
# ----------------------------------------------------
# Application version
# ----------------------------------------------------
@@ -29,10 +30,12 @@ include ../../vsn.mk
VSN = $(INETS_VSN)
+
# ----------------------------------------------------
# Release directory specification
# ----------------------------------------------------
-RELSYSDIR = $(RELEASE_PATH)/lib/inets-$(VSN)
+RELSYSDIR = $(RELEASE_PATH)/lib/$(APPLICATION)-$(VSN)
+
# ----------------------------------------------------
# Target Specs
@@ -42,7 +45,8 @@ MODULES = \
http_transport\
http_util \
http_request \
- http_response
+ http_response \
+ http_uri
HRL_FILES = http_internal.hrl
@@ -50,10 +54,12 @@ ERL_FILES = $(MODULES:%=%.erl)
TARGET_FILES= $(MODULES:%=$(EBIN)/%.$(EMULATOR))
+
# ----------------------------------------------------
# INETS FLAGS
# ----------------------------------------------------
-INETS_FLAGS = -D'SERVER_SOFTWARE="inets/$(VSN)"' \
+INETS_FLAGS = -D'SERVER_SOFTWARE="$(APPLICATION)/$(VSN)"'
+
# ----------------------------------------------------
# FLAGS
@@ -82,6 +88,7 @@ clean:
docs:
+
# ----------------------------------------------------
# Release Target
# ----------------------------------------------------
@@ -96,6 +103,8 @@ release_spec: opt
release_docs_spec:
info:
+ @echo "APPLICATION = $(APPLICATION)"
@echo "INETS_DEBUG = $(INETS_DEBUG)"
@echo "INETS_FLAGS = $(INETS_FLAGS)"
@echo "ERL_COMPILE_FLAGS = $(ERL_COMPILE_FLAGS)"
+
diff --git a/lib/inets/src/http_lib/http_chunk.erl b/lib/inets/src/http_lib/http_chunk.erl
index cd20dce9d5..621bc68eae 100644
--- a/lib/inets/src/http_lib/http_chunk.erl
+++ b/lib/inets/src/http_lib/http_chunk.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2004-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 2004-2010. All Rights Reserved.
+%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
-%%
+%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
-%%
+%%
%% %CopyrightEnd%
%%
%% Description: Implements chunked transfer encoding see RFC2616 section
@@ -186,13 +186,6 @@ decode_data(ChunkSize, TotalChunk,
Info = {MaxBodySize, BodySoFar, AccLength, MaxHeaderSize, Stream})
when ChunkSize =< size(TotalChunk) ->
case TotalChunk of
- %% Potential last chunk
- <<_:ChunkSize/binary, ?CR, ?LF, "0">> ->
- {?MODULE, decode_data, [ChunkSize, TotalChunk, Info]};
- <<_:ChunkSize/binary, ?CR, ?LF, "0", ?CR>> ->
- {?MODULE, decode_data, [ChunkSize, TotalChunk, Info]};
- <<_:ChunkSize/binary, ?CR, ?LF>> ->
- {?MODULE, decode_data, [ChunkSize, TotalChunk, Info]};
%% Last chunk
<<Data:ChunkSize/binary, ?CR, ?LF, "0", ";">> ->
%% Note ignore_extensions will call decode_trailer/1
@@ -223,6 +216,10 @@ decode_data(ChunkSize, TotalChunk,
NewBody,
integer_to_list(AccLength));
%% There are more chunks, so here we go agin...
+ <<Data:ChunkSize/binary, ?CR, ?LF>> ->
+ {NewBody, NewStream} =
+ stream(<<BodySoFar/binary, Data/binary>>, Stream),
+ {?MODULE, decode_size, [<<>>, [], {MaxBodySize, NewBody, AccLength, MaxHeaderSize, NewStream}]};
<<Data:ChunkSize/binary, ?CR, ?LF, Rest/binary>>
when (AccLength < MaxBodySize) or (MaxBodySize == nolimit) ->
{NewBody, NewStream} =
diff --git a/lib/inets/src/http_lib/http_transport.erl b/lib/inets/src/http_lib/http_transport.erl
index 8100d7183a..587d215051 100644
--- a/lib/inets/src/http_lib/http_transport.erl
+++ b/lib/inets/src/http_lib/http_transport.erl
@@ -1,32 +1,48 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2004-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 2004-2011. All Rights Reserved.
+%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
-%%
+%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
-%%
+%%
%% %CopyrightEnd%
%%
-%
+
-module(http_transport).
% Internal application API
--export([start/1, connect/3, connect/4, listen/2, listen/3,
- accept/2, accept/3, close/2,
- send/3, controlling_process/3, setopts/3,
- peername/2, resolve/0]).
+-export([
+ start/1,
+ connect/3, connect/4,
+ listen/2, listen/3,
+ accept/2, accept/3,
+ close/2,
+ send/3,
+ controlling_process/3,
+ setopts/3, getopts/2, getopts/3,
+ getstat/2,
+ peername/2, sockname/2,
+ resolve/0
+ ]).
-export([negotiate/3]).
+-include("inets_internal.hrl").
+-define(SERVICE, httpl).
+-define(hlri(Label, Content), ?report_important(Label, ?SERVICE, Content)).
+-define(hlrv(Label, Content), ?report_verbose(Label, ?SERVICE, Content)).
+-define(hlrd(Label, Content), ?report_debug(Label, ?SERVICE, Content)).
+-define(hlrt(Label, Content), ?report_trace(Label, ?SERVICE, Content)).
+
%%%=========================================================================
%%% Internal application API
@@ -77,14 +93,22 @@ connect(SocketType, Address, Opts) ->
connect(ip_comm = _SocketType, {Host, Port}, Opts0, Timeout)
when is_list(Opts0) ->
Opts = [binary, {packet, 0}, {active, false}, {reuseaddr, true} | Opts0],
+ ?hlrt("connect using gen_tcp",
+ [{host, Host}, {port, Port}, {opts, Opts}, {timeout, Timeout}]),
gen_tcp:connect(Host, Port, Opts, Timeout);
connect({ssl, SslConfig}, {Host, Port}, _, Timeout) ->
Opts = [binary, {active, false}] ++ SslConfig,
+ ?hlrt("connect using ssl",
+ [{host, Host}, {port, Port}, {ssl_config, SslConfig},
+ {timeout, Timeout}]),
ssl:connect(Host, Port, Opts, Timeout);
connect({erl_ssl, SslConfig}, {Host, Port}, _, Timeout) ->
Opts = [binary, {active, false}, {ssl_imp, new}] ++ SslConfig,
+ ?hlrt("connect using erl_ssl",
+ [{host, Host}, {port, Port}, {ssl_config, SslConfig},
+ {timeout, Timeout}]),
ssl:connect(Host, Port, Opts, Timeout).
@@ -126,17 +150,22 @@ listen_ip_comm(Addr, Port) ->
case IpFamily of
inet6fb4 ->
Opts2 = [inet6 | Opts],
+ ?hlrt("try ipv6 listen", [{port, NewPort}, {opts, Opts2}]),
case (catch gen_tcp:listen(NewPort, Opts2)) of
{error, Reason} when ((Reason =:= nxdomain) orelse
(Reason =:= eafnosupport)) ->
Opts3 = [inet | Opts],
+ ?hlrt("ipv6 listen failed - try ipv4 instead",
+ [{reason, Reason}, {port, NewPort}, {opts, Opts3}]),
gen_tcp:listen(NewPort, Opts3);
%% This is when a given hostname has resolved to a
%% IPv4-address. The inet6-option together with a
%% {ip, IPv4} option results in badarg
- {'EXIT', _} ->
+ {'EXIT', Reason} ->
Opts3 = [inet | Opts],
+ ?hlrt("ipv6 listen exit - try ipv4 instead",
+ [{reason, Reason}, {port, NewPort}, {opts, Opts3}]),
gen_tcp:listen(NewPort, Opts3);
Other ->
@@ -144,6 +173,7 @@ listen_ip_comm(Addr, Port) ->
end;
_ ->
Opts2 = [IpFamily | Opts],
+ ?hlrt("listen", [{port, NewPort}, {opts, Opts2}]),
gen_tcp:listen(NewPort, Opts2)
end.
@@ -209,6 +239,7 @@ accept(ip_comm, ListenSocket, Timeout) ->
accept({ssl,_SSLConfig}, ListenSocket, Timeout) ->
ssl:transport_accept(ListenSocket, Timeout).
+
%%-------------------------------------------------------------------------
%% controlling_process(SocketType, Socket, NewOwner) -> ok | {error, Reason}
%% SocketType = ip_comm | {ssl, _}
@@ -222,6 +253,7 @@ controlling_process(ip_comm, Socket, NewOwner) ->
controlling_process({ssl, _}, Socket, NewOwner) ->
ssl:controlling_process(Socket, NewOwner).
+
%%-------------------------------------------------------------------------
%% setopts(SocketType, Socket, Options) -> ok | {error, Reason}
%% SocketType = ip_comm | {ssl, _}
@@ -231,10 +263,62 @@ controlling_process({ssl, _}, Socket, NewOwner) ->
%% gen_tcp or ssl.
%%-------------------------------------------------------------------------
setopts(ip_comm, Socket, Options) ->
- inet:setopts(Socket,Options);
+ ?hlrt("ip_comm setopts", [{socket, Socket}, {options, Options}]),
+ inet:setopts(Socket, Options);
setopts({ssl, _}, Socket, Options) ->
+ ?hlrt("ssl setopts", [{socket, Socket}, {options, Options}]),
ssl:setopts(Socket, Options).
+
+%%-------------------------------------------------------------------------
+%% getopts(SocketType, Socket [, Opts]) -> ok | {error, Reason}
+%% SocketType = ip_comm | {ssl, _}
+%% Socket = socket()
+%% Opts = socket_options()
+%% Description: Gets the values for some options.
+%%-------------------------------------------------------------------------
+getopts(SocketType, Socket) ->
+ Opts = [packet, packet_size, recbuf, sndbuf, priority, tos, send_timeout],
+ getopts(SocketType, Socket, Opts).
+
+getopts(ip_comm, Socket, Options) ->
+ ?hlrt("ip_comm getopts", [{socket, Socket}, {options, Options}]),
+ case inet:getopts(Socket, Options) of
+ {ok, SocketOpts} ->
+ SocketOpts;
+ {error, _} ->
+ []
+ end;
+getopts({ssl, _}, Socket, Options) ->
+ ?hlrt("ssl getopts", [{socket, Socket}, {options, Options}]),
+ case ssl:getopts(Socket, Options) of
+ {ok, SocketOpts} ->
+ SocketOpts;
+ {error, _} ->
+ []
+ end.
+
+
+%%-------------------------------------------------------------------------
+%% getstat(SocketType, Socket) -> socket_stats()
+%% SocketType = ip_comm | {ssl, _}
+%% Socket = socket()
+%% socket_stats() = list()
+%% Description: Gets the socket stats values for the socket
+%%-------------------------------------------------------------------------
+getstat(ip_comm = _SocketType, Socket) ->
+ ?hlrt("ip_comm getstat", [{socket, Socket}]),
+ case inet:getstat(Socket) of
+ {ok, Stats} ->
+ Stats;
+ {error, _} ->
+ []
+ end;
+getstat({ssl, _} = _SocketType, _Socket) ->
+ %% ?hlrt("ssl getstat", [{socket, Socket}]),
+ [].
+
+
%%-------------------------------------------------------------------------
%% send(RequestOrSocketType, Socket, Message) -> ok | {error, Reason}
%% SocketType = ip_comm | {ssl, _}
@@ -247,6 +331,7 @@ send(ip_comm, Socket, Message) ->
send({ssl, _}, Socket, Message) ->
ssl:send(Socket, Message).
+
%%-------------------------------------------------------------------------
%% close(SocketType, Socket) -> ok | {error, Reason}
%% SocketType = ip_comm | {ssl, _}
@@ -260,9 +345,11 @@ close({ssl, _}, Socket) ->
ssl:close(Socket).
%%-------------------------------------------------------------------------
-%% peername(SocketType, Socket) -> ok | {error, Reason}
+%% peername(SocketType, Socket) -> {Port, SockName}
%% SocketType = ip_comm | {ssl, _}
%% Socket = socket()
+%% Port = integer() (-1 if error occured)
+%% PeerName = string()
%%
%% Description: Returns the address and port for the other end of a
%% connection, usning either gen_tcp or ssl.
@@ -283,7 +370,21 @@ peername(ip_comm, Socket) ->
http_util:integer_to_hexlist(G) ++":"++
http_util:integer_to_hexlist(H),
{Port, PeerName};
- {error, _} ->
+ {error, Reason} ->
+ Report = io_lib:format("~p Failed getting PeerName for socket ~p: "
+ "~n Reason: ~p"
+ "~n Socket stat: ~p"
+ "~n IfList: ~p"
+ "~n Fd: ~p"
+ "~n",
+ [self(),
+ Socket,
+ Reason,
+ (catch inet:getstat(Socket)),
+ (catch inet:getiflist(Socket)),
+ (catch inet:getfd(Socket))
+ ]),
+ (catch error_logger:error_report(Report)),
{-1, "unknown"}
end;
@@ -297,6 +398,48 @@ peername({ssl, _}, Socket) ->
{-1, "unknown"}
end.
+
+%%-------------------------------------------------------------------------
+%% sockname(SocketType, Socket) -> {Port, SockName}
+%% SocketType = ip_comm | {ssl, _}
+%% Socket = socket()
+%% Port = integer() (-1 if error occured)
+%% SockName = string()
+%%
+%% Description: Returns the address and port for the local (our) end
+%% other end of connection, using either gen_tcp or ssl.
+%%-------------------------------------------------------------------------
+sockname(ip_comm, Socket) ->
+ case inet:sockname(Socket) of
+ {ok,{{A, B, C, D}, Port}} ->
+ SockName = integer_to_list(A)++"."++integer_to_list(B)++"."++
+ integer_to_list(C)++"."++integer_to_list(D),
+ {Port, SockName};
+ {ok,{{A, B, C, D, E, F, G, H}, Port}} ->
+ SockName = http_util:integer_to_hexlist(A) ++ ":"++
+ http_util:integer_to_hexlist(B) ++ ":" ++
+ http_util:integer_to_hexlist(C) ++ ":" ++
+ http_util:integer_to_hexlist(D) ++ ":" ++
+ http_util:integer_to_hexlist(E) ++ ":" ++
+ http_util:integer_to_hexlist(F) ++ ":" ++
+ http_util:integer_to_hexlist(G) ++":"++
+ http_util:integer_to_hexlist(H),
+ {Port, SockName};
+ {error, _} ->
+ {-1, "unknown"}
+ end;
+
+sockname({ssl, _}, Socket) ->
+ case ssl:sockname(Socket) of
+ {ok,{{A, B, C, D}, Port}} ->
+ SockName = integer_to_list(A)++"."++integer_to_list(B)++"."++
+ integer_to_list(C)++"."++integer_to_list(D),
+ {Port, SockName};
+ {error, _} ->
+ {-1, "unknown"}
+ end.
+
+
%%-------------------------------------------------------------------------
%% resolve() -> HostName
%% HostName = string()
diff --git a/lib/inets/src/http_lib/http_uri.erl b/lib/inets/src/http_lib/http_uri.erl
new file mode 100644
index 0000000000..d03acff3a9
--- /dev/null
+++ b/lib/inets/src/http_lib/http_uri.erl
@@ -0,0 +1,147 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 2006-2011. All Rights Reserved.
+%%
+%% The contents of this file are subject to the Erlang Public License,
+%% Version 1.1, (the "License"); you may not use this file except in
+%% compliance with the License. You should have received a copy of the
+%% Erlang Public License along with this software. If not, it can be
+%% retrieved online at http://www.erlang.org/.
+%%
+%% Software distributed under the License is distributed on an "AS IS"
+%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+%% the License for the specific language governing rights and limitations
+%% under the License.
+%%
+%% %CopyrightEnd%
+%%
+%%
+
+-module(http_uri).
+
+-export([parse/1]).
+-export([encode/1, decode/1]).
+
+
+%%%=========================================================================
+%%% API
+%%%=========================================================================
+parse(AbsURI) ->
+ case parse_scheme(AbsURI) of
+ {error, Reason} ->
+ {error, Reason};
+ {Scheme, Rest} ->
+ case (catch parse_uri_rest(Scheme, Rest)) of
+ {UserInfo, Host, Port, Path, Query} ->
+ {Scheme, UserInfo, Host, Port, Path, Query};
+ _ ->
+ {error, {malformed_url, AbsURI}}
+ end
+ end.
+
+encode(URI) ->
+ Reserved = sets:from_list([$;, $:, $@, $&, $=, $+, $,, $/, $?,
+ $#, $[, $], $<, $>, $\", ${, $}, $|,
+ $\\, $', $^, $%, $ ]),
+ lists:append(lists:map(fun(Char) -> uri_encode(Char, Reserved) end, URI)).
+
+decode(String) ->
+ do_decode(String).
+
+do_decode([$%,Hex1,Hex2|Rest]) ->
+ [hex2dec(Hex1)*16+hex2dec(Hex2)|do_decode(Rest)];
+do_decode([First|Rest]) ->
+ [First|do_decode(Rest)];
+do_decode([]) ->
+ [].
+
+
+%%%========================================================================
+%%% Internal functions
+%%%========================================================================
+
+parse_scheme(AbsURI) ->
+ case split_uri(AbsURI, ":", {error, no_scheme}, 1, 1) of
+ {error, no_scheme} ->
+ {error, no_scheme};
+ {StrScheme, Rest} ->
+ case list_to_atom(http_util:to_lower(StrScheme)) of
+ Scheme when Scheme == http; Scheme == https ->
+ {Scheme, Rest};
+ Scheme ->
+ {error, {not_supported_scheme, Scheme}}
+ end
+ end.
+
+parse_uri_rest(Scheme, "//" ++ URIPart) ->
+ {Authority, PathQuery} =
+ case split_uri(URIPart, "/", URIPart, 1, 0) of
+ Split = {_, _} ->
+ Split;
+ URIPart ->
+ case split_uri(URIPart, "\\?", URIPart, 1, 0) of
+ Split = {_, _} ->
+ Split;
+ URIPart ->
+ {URIPart,""}
+ end
+ end,
+
+ {UserInfo, HostPort} = split_uri(Authority, "@", {"", Authority}, 1, 1),
+ {Host, Port} = parse_host_port(Scheme, HostPort),
+ {Path, Query} = parse_path_query(PathQuery),
+ {UserInfo, Host, Port, Path, Query}.
+
+
+parse_path_query(PathQuery) ->
+ {Path, Query} = split_uri(PathQuery, "\\?", {PathQuery, ""}, 1, 0),
+ {path(Path), Query}.
+
+
+parse_host_port(Scheme,"[" ++ HostPort) -> %ipv6
+ DefaultPort = default_port(Scheme),
+ {Host, ColonPort} = split_uri(HostPort, "\\]", {HostPort, ""}, 1, 1),
+ {_, Port} = split_uri(ColonPort, ":", {"", DefaultPort}, 0, 1),
+ {Host, int_port(Port)};
+
+parse_host_port(Scheme, HostPort) ->
+ DefaultPort = default_port(Scheme),
+ {Host, Port} = split_uri(HostPort, ":", {HostPort, DefaultPort}, 1, 1),
+ {Host, int_port(Port)}.
+
+split_uri(UriPart, SplitChar, NoMatchResult, SkipLeft, SkipRight) ->
+ case inets_regexp:first_match(UriPart, SplitChar) of
+ {match, Match, _} ->
+ {string:substr(UriPart, 1, Match - SkipLeft),
+ string:substr(UriPart, Match + SkipRight, length(UriPart))};
+ nomatch ->
+ NoMatchResult
+ end.
+
+default_port(http) ->
+ 80;
+default_port(https) ->
+ 443.
+
+int_port(Port) when is_integer(Port) ->
+ Port;
+int_port(Port) when is_list(Port) ->
+ list_to_integer(Port).
+
+path("") ->
+ "/";
+path(Path) ->
+ Path.
+
+uri_encode(Char, Reserved) ->
+ case sets:is_element(Char, Reserved) of
+ true ->
+ [ $% | http_util:integer_to_hexlist(Char)];
+ false ->
+ [Char]
+ end.
+
+hex2dec(X) when (X>=$0) andalso (X=<$9) -> X-$0;
+hex2dec(X) when (X>=$A) andalso (X=<$F) -> X-$A+10;
+hex2dec(X) when (X>=$a) andalso (X=<$f) -> X-$a+10.
diff --git a/lib/inets/src/http_lib/http_util.erl b/lib/inets/src/http_lib/http_util.erl
index b03b780cf8..5d8cb9365d 100644
--- a/lib/inets/src/http_lib/http_util.erl
+++ b/lib/inets/src/http_lib/http_util.erl
@@ -1,27 +1,34 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2005-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 2005-2011. All Rights Reserved.
+%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
-%%
+%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
-%%
+%%
%% %CopyrightEnd%
%%
%%
-module(http_util).
--export([to_upper/1, to_lower/1, convert_netscapecookie_date/1,
+-export([
+ to_upper/1, to_lower/1,
+ convert_netscapecookie_date/1,
hexlist_to_integer/1, integer_to_hexlist/1,
- convert_month/1, is_hostname/1]).
+ convert_month/1,
+ is_hostname/1,
+ html_encode/1,
+ timestamp/0, timeout/2
+ ]).
+
%%%=========================================================================
%%% Internal application API
@@ -32,13 +39,79 @@ to_upper(Str) ->
to_lower(Str) ->
string:to_lower(Str).
-convert_netscapecookie_date([_D,_A,_Y, $,, _SP,
- D1,D2,_DA,
- M,O,N,_DA,
- Y1,Y2,Y3,Y4,_SP,
- H1,H2,_Col,
- M1,M2,_Col,
+%% Example: Mon, 09-Dec-2002 13:46:00 GMT
+convert_netscapecookie_date([_D,_A,_Y, $,, $ ,
+ D1,D2, $-,
+ M,O,N, $-,
+ Y1,Y2,Y3,Y4, $ ,
+ H1,H2, $:,
+ M1,M2, $:,
+ S1,S2|_Rest]) ->
+ Year = list_to_integer([Y1,Y2,Y3,Y4]),
+ Day = list_to_integer([D1,D2]),
+ Month = convert_month([M,O,N]),
+ Hour = list_to_integer([H1,H2]),
+ Min = list_to_integer([M1,M2]),
+ Sec = list_to_integer([S1,S2]),
+ {{Year,Month,Day},{Hour,Min,Sec}};
+
+convert_netscapecookie_date([_D,_A,_Y, $,, $ ,
+ D1,D2, $-,
+ M,O,N, $-,
+ Y3,Y4, $ ,
+ H1,H2, $:,
+ M1,M2, $:,
+ S1,S2|_Rest]) ->
+ {CurrentYear, _, _} = date(),
+ [Y1,Y2|_] = integer_to_list(CurrentYear),
+ Year = list_to_integer([Y1,Y2,Y3,Y4]),
+ Day = list_to_integer([D1,D2]),
+ Month = convert_month([M,O,N]),
+ Hour = list_to_integer([H1,H2]),
+ Min = list_to_integer([M1,M2]),
+ Sec = list_to_integer([S1,S2]),
+ {{Year,Month,Day},{Hour,Min,Sec}};
+
+convert_netscapecookie_date([_D,_A,_Y, $ ,
+ D1,D2, $-,
+ M,O,N, $-,
+ Y1,Y2,Y3,Y4, $ ,
+ H1,H2, $:,
+ M1,M2, $:,
+ S1,S2|_Rest]) ->
+ Year = list_to_integer([Y1,Y2,Y3,Y4]),
+ Day = list_to_integer([D1,D2]),
+ Month = convert_month([M,O,N]),
+ Hour = list_to_integer([H1,H2]),
+ Min = list_to_integer([M1,M2]),
+ Sec = list_to_integer([S1,S2]),
+ {{Year,Month,Day},{Hour,Min,Sec}};
+
+convert_netscapecookie_date([_D,_A,_Y, $ ,
+ D1,D2, $-,
+ M,O,N, $-,
+ Y3,Y4, $ ,
+ H1,H2, $:,
+ M1,M2, $:,
S1,S2|_Rest]) ->
+ {CurrentYear, _, _} = date(),
+ [Y1,Y2|_] = integer_to_list(CurrentYear),
+ Year = list_to_integer([Y1,Y2,Y3,Y4]),
+ Day = list_to_integer([D1,D2]),
+ Month = convert_month([M,O,N]),
+ Hour = list_to_integer([H1,H2]),
+ Min = list_to_integer([M1,M2]),
+ Sec = list_to_integer([S1,S2]),
+ {{Year,Month,Day},{Hour,Min,Sec}};
+
+%% Sloppy...
+convert_netscapecookie_date([_D,_A,_Y, $,, _SP,
+ D1,D2,_DA,
+ M,O,N,_DA,
+ Y1,Y2,Y3,Y4,_SP,
+ H1,H2,_Col,
+ M1,M2,_Col,
+ S1,S2|_Rest]) ->
Year=list_to_integer([Y1,Y2,Y3,Y4]),
Day=list_to_integer([D1,D2]),
Month=convert_month([M,O,N]),
@@ -48,12 +121,12 @@ convert_netscapecookie_date([_D,_A,_Y, $,, _SP,
{{Year,Month,Day},{Hour,Min,Sec}};
convert_netscapecookie_date([_D,_A,_Y, _SP,
- D1,D2,_DA,
- M,O,N,_DA,
- Y1,Y2,Y3,Y4,_SP,
- H1,H2,_Col,
- M1,M2,_Col,
- S1,S2|_Rest]) ->
+ D1,D2,_DA,
+ M,O,N,_DA,
+ Y1,Y2,Y3,Y4,_SP,
+ H1,H2,_Col,
+ M1,M2,_Col,
+ S1,S2|_Rest]) ->
Year=list_to_integer([Y1,Y2,Y3,Y4]),
Day=list_to_integer([D1,D2]),
Month=convert_month([M,O,N]),
@@ -62,17 +135,17 @@ convert_netscapecookie_date([_D,_A,_Y, _SP,
Sec=list_to_integer([S1,S2]),
{{Year,Month,Day},{Hour,Min,Sec}}.
-hexlist_to_integer([])->
+hexlist_to_integer([]) ->
empty;
%%When the string only contains one value its eaasy done.
%% 0-9
-hexlist_to_integer([Size]) when Size >= 48 , Size =< 57 ->
+hexlist_to_integer([Size]) when (Size >= 48) andalso (Size =< 57) ->
Size - 48;
%% A-F
-hexlist_to_integer([Size]) when Size >= 65 , Size =< 70 ->
+hexlist_to_integer([Size]) when (Size >= 65) andalso (Size =< 70) ->
Size - 55;
%% a-f
-hexlist_to_integer([Size]) when Size >= 97 , Size =< 102 ->
+hexlist_to_integer([Size]) when (Size >= 97) andalso (Size =< 102) ->
Size - 87;
hexlist_to_integer([_Size]) ->
not_a_num;
@@ -100,6 +173,27 @@ convert_month("Dec") -> 12.
is_hostname(Dest) ->
inet_parse:domain(Dest).
+
+timestamp() ->
+ {A,B,C} = os:timestamp(),
+ A*1000000000+B*1000+(C div 1000).
+
+timeout(Timeout, Started) ->
+ %% NewTimeout = Timeout - (timestamp() - Started),
+ case Timeout - (timestamp() - Started) of
+ NewTimeout when Timeout > 0 ->
+ NewTimeout;
+ _ ->
+ 0
+ end.
+
+
+html_encode(Chars) ->
+ Reserved = sets:from_list([$&, $<, $>, $\", $', $/]),
+ lists:append([char_to_html_entity(Char, Reserved) || Char <- Chars]).
+
+
+
%%%========================================================================
%%% Internal functions
%%%========================================================================
@@ -120,7 +214,7 @@ hexlist_to_integer2([HexVal | HexString], Pos, Sum)
hexlist_to_integer2(_AfterHexString, _Pos, Sum)->
Sum.
-integer_to_hexlist(Num, Pot, Res) when Pot<0 ->
+integer_to_hexlist(Num, Pot, Res) when Pot < 0 ->
convert_to_ascii([Num | Res]);
integer_to_hexlist(Num,Pot,Res) ->
@@ -142,7 +236,17 @@ convert_to_ascii(RevesedNum) ->
convert_to_ascii([], Num)->
Num;
-convert_to_ascii([Num | Reversed], Number) when Num > -1, Num < 10 ->
+convert_to_ascii([Num | Reversed], Number)
+ when (Num > -1) andalso (Num < 10) ->
convert_to_ascii(Reversed, [Num + 48 | Number]);
-convert_to_ascii([Num | Reversed], Number) when Num > 9, Num < 16 ->
+convert_to_ascii([Num | Reversed], Number)
+ when (Num > 9) andalso (Num < 16) ->
convert_to_ascii(Reversed, [Num + 55 | Number]).
+
+char_to_html_entity(Char, Reserved) ->
+ case sets:is_element(Char, Reserved) of
+ true ->
+ "&#" ++ integer_to_list(Char) ++ ";";
+ false ->
+ [Char]
+ end.
diff --git a/lib/inets/src/http_server/Makefile b/lib/inets/src/http_server/Makefile
index 4bbd23df3f..3c36b384b8 100644
--- a/lib/inets/src/http_server/Makefile
+++ b/lib/inets/src/http_server/Makefile
@@ -1,19 +1,19 @@
#
# %CopyrightBegin%
-#
-# Copyright Ericsson AB 2005-2009. All Rights Reserved.
-#
+#
+# Copyright Ericsson AB 2005-2011. All Rights Reserved.
+#
# The contents of this file are subject to the Erlang Public License,
# Version 1.1, (the "License"); you may not use this file except in
# compliance with the License. You should have received a copy of the
# Erlang Public License along with this software. If not, it can be
# retrieved online at http://www.erlang.org/.
-#
+#
# Software distributed under the License is distributed on an "AS IS"
# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
# the License for the specific language governing rights and limitations
# under the License.
-#
+#
# %CopyrightEnd%
#
#
@@ -33,7 +33,7 @@ VSN = $(INETS_VSN)
# ----------------------------------------------------
# Release directory specification
# ----------------------------------------------------
-RELSYSDIR = $(RELEASE_PATH)/lib/inets-$(VSN)
+RELSYSDIR = $(RELEASE_PATH)/lib/$(APPLICATION)-$(VSN)
# ----------------------------------------------------
@@ -92,18 +92,22 @@ TARGET_FILES= $(MODULES:%=$(EBIN)/%.$(EMULATOR))
# ----------------------------------------------------
# INETS FLAGS
# ----------------------------------------------------
-INETS_FLAGS = -D'SERVER_SOFTWARE="inets/$(VSN)"'
+INETS_FLAGS = -D'SERVER_SOFTWARE="$(APPLICATION)/$(VSN)"'
# ----------------------------------------------------
# FLAGS
# ----------------------------------------------------
-INETS_ERL_FLAGS += -I ../http_lib -I ../inets_app -pa ../../ebin
+INETS_ERL_FLAGS += \
+ -I ../http_lib \
+ -I ../inets_app \
+ -pa $(ERL_TOP)/lib/inets/ebin
-ERL_COMPILE_FLAGS += $(INETS_ERL_FLAGS) \
- $(INETS_FLAGS) \
- +'{parse_transform,sys_pre_attributes}' \
- +'{attribute,insert,app_vsn,$(APP_VSN)}'
+ERL_COMPILE_FLAGS += \
+ $(INETS_ERL_FLAGS) \
+ $(INETS_FLAGS) \
+ +'{parse_transform,sys_pre_attributes}' \
+ +'{attribute,insert,app_vsn,$(APP_VSN)}'
# ----------------------------------------------------
@@ -133,6 +137,7 @@ release_spec: opt
release_docs_spec:
info:
+ @echo "APPLICATION = $(APPLICATION)"
@echo "INETS_DEBUG = $(INETS_DEBUG)"
@echo "INETS_FLAGS = $(INETS_FLAGS)"
@echo "ERL_COMPILE_FLAGS = $(ERL_COMPILE_FLAGS)"
diff --git a/lib/inets/src/http_server/httpd.erl b/lib/inets/src/http_server/httpd.erl
index 554f162fc5..a88d002b03 100644
--- a/lib/inets/src/http_server/httpd.erl
+++ b/lib/inets/src/http_server/httpd.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 1997-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 1997-2011. All Rights Reserved.
+%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
-%%
+%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
-%%
+%%
%% %CopyrightEnd%
%%
%%
@@ -349,8 +349,8 @@ foreach([KeyValue|Rest]) ->
{ok, Plus2Space, _} = inets_regexp:gsub(KeyValue,"[\+]"," "),
case inets_regexp:split(Plus2Space,"=") of
{ok,[Key|Value]} ->
- [{httpd_util:decode_hex(Key),
- httpd_util:decode_hex(lists:flatten(Value))}|foreach(Rest)];
+ [{http_uri:decode(Key), http_uri:decode(lists:flatten(Value))}|
+ foreach(Rest)];
{ok,_} ->
foreach(Rest)
end.
@@ -358,7 +358,7 @@ foreach([KeyValue|Rest]) ->
get_addr_and_port(ConfigFile) ->
case httpd_conf:load(ConfigFile) of
{ok, ConfigList} ->
- case httpd_conf:validate_properties(ConfigList) of
+ case (catch httpd_conf:validate_properties(ConfigList)) of
{ok, Config} ->
Address = proplists:get_value(bind_address, Config, any),
Port = proplists:get_value(port, Config, 80),
@@ -506,7 +506,7 @@ get_status(Addr,Port,Timeout) when is_integer(Port) ->
end.
do_reload_config(ConfigList, Mode) ->
- case httpd_conf:validate_properties(ConfigList) of
+ case (catch httpd_conf:validate_properties(ConfigList)) of
{ok, Config} ->
Address = proplists:get_value(bind_address, Config, any),
Port = proplists:get_value(port, Config, 80),
diff --git a/lib/inets/src/http_server/httpd_acceptor.erl b/lib/inets/src/http_server/httpd_acceptor.erl
index 568fd3c610..fef3fe58c6 100644
--- a/lib/inets/src/http_server/httpd_acceptor.erl
+++ b/lib/inets/src/http_server/httpd_acceptor.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2001-2009. All Rights Reserved.
+%% Copyright Ericsson AB 2001-2011. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
@@ -21,6 +21,7 @@
-include("httpd.hrl").
-include("httpd_internal.hrl").
+-include("inets_internal.hrl").
%% Internal application API
-export([start_link/5, start_link/6]).
diff --git a/lib/inets/src/http_server/httpd_conf.erl b/lib/inets/src/http_server/httpd_conf.erl
index 9c93e2c5fe..2faf13e9b3 100644
--- a/lib/inets/src/http_server/httpd_conf.erl
+++ b/lib/inets/src/http_server/httpd_conf.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 1997-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 1997-2011. All Rights Reserved.
+%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
-%%
+%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
-%%
+%%
%% %CopyrightEnd%
%%
%%
@@ -30,8 +30,9 @@
validate_properties/1]).
-define(VMODULE,"CONF").
--include("httpd.hrl").
-include("httpd_internal.hrl").
+-include("httpd.hrl").
+-include_lib("inets/src/http_lib/http_internal.hrl").
%%%=========================================================================
@@ -354,7 +355,7 @@ load("DocumentRoot " ++ DocumentRoot,[]) ->
{ok, Directory} ->
{ok, [], {document_root,string:strip(Directory,right,$/)}};
{error, _} ->
- {error, ?NICE(clean(DocumentRoot)++"is an invalid DocumentRoot")}
+ {error, ?NICE(clean(DocumentRoot)++" is an invalid DocumentRoot")}
end;
load("DefaultType " ++ DefaultType, []) ->
{ok, [], {default_type,clean(DefaultType)}};
@@ -864,17 +865,22 @@ load_traverse(Line, [Context|Contexts], [Module|Modules], NewContexts,
{'EXIT', {undef, _}} ->
?hdrt("does not implement load", []),
load_traverse(Line, Contexts, Modules,
- [Context|NewContexts], ConfigList,yes);
+ [Context|NewContexts], ConfigList, yes);
{'EXIT', Reason} ->
error_logger:error_report({'EXIT', Reason}),
load_traverse(Line, Contexts, Modules,
[Context|NewContexts], ConfigList, State);
+ ok ->
+ ?hdrt("line processed", []),
+ load_traverse(Line, Contexts, Modules,
+ [Context|NewContexts], ConfigList, yes);
+
{ok, NewContext} ->
?hdrt("line processed", [{new_context, NewContext}]),
load_traverse(Line, Contexts, Modules,
- [NewContext|NewContexts], ConfigList,yes);
+ [NewContext|NewContexts], ConfigList, yes);
{ok, NewContext, ConfigEntry} when is_tuple(ConfigEntry) ->
?hdrt("line processed",
diff --git a/lib/inets/src/http_server/httpd_file.erl b/lib/inets/src/http_server/httpd_file.erl
index 5fd529100e..4490a6356a 100644
--- a/lib/inets/src/http_server/httpd_file.erl
+++ b/lib/inets/src/http_server/httpd_file.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2006-2009. All Rights Reserved.
+%% Copyright Ericsson AB 2006-2011. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
@@ -22,6 +22,7 @@
-export([handle_error/4]).
-include("httpd.hrl").
+-include("httpd_internal.hrl").
handle_error(eacces, Op, ModData, Path) ->
handle_error(403, Op, ModData, Path,"");
@@ -38,8 +39,8 @@ handle_error(_Reason, Op, _ModData, Path) ->
handle_error(500, Op, none, Path, "").
handle_error(StatusCode, Op, none, Path, Reason) ->
- {StatusCode, none, ?NICE("Can't " ++ Op ++ Path ++ Reason)};
+ {StatusCode, none, ?NICE("Can't " ++ Op ++ " " ++ Path ++ Reason)};
handle_error(StatusCode, Op, ModData, Path, Reason) ->
{StatusCode, ModData#mod.request_uri,
- ?NICE("Can't " ++ Op ++ Path ++ Reason)}.
+ ?NICE("Can't " ++ Op ++ " " ++ Path ++ Reason)}.
diff --git a/lib/inets/src/http_server/httpd_instance_sup.erl b/lib/inets/src/http_server/httpd_instance_sup.erl
index 3b5464132c..baa60d318c 100644
--- a/lib/inets/src/http_server/httpd_instance_sup.erl
+++ b/lib/inets/src/http_server/httpd_instance_sup.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2001-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 2001-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%
%%
%%
@@ -37,7 +37,7 @@
%%% Internal Application API
%%%=========================================================================
start_link([{_, _}| _] = Config, AcceptTimeout, Debug) ->
- case httpd_conf:validate_properties(Config) of
+ case (catch httpd_conf:validate_properties(Config)) of
{ok, Config2} ->
Address = proplists:get_value(bind_address, Config2),
Port = proplists:get_value(port, Config2),
@@ -66,7 +66,7 @@ start_link(ConfigFile, AcceptTimeout, Debug) ->
start_link([{_, _}| _] = Config, AcceptTimeout, ListenInfo, Debug) ->
- case httpd_conf:validate_properties(Config) of
+ case (catch httpd_conf:validate_properties(Config)) of
{ok, Config2} ->
Address = proplists:get_value(bind_address, Config2),
Port = proplists:get_value(port, Config2),
@@ -97,14 +97,16 @@ start_link(ConfigFile, AcceptTimeout, ListenInfo, Debug) ->
%%%=========================================================================
%%% Supervisor callback
%%%=========================================================================
-init([ConfigFile, ConfigList, AcceptTimeout, _Debug, Address, Port]) ->
+init([ConfigFile, ConfigList, AcceptTimeout, Debug, Address, Port]) ->
+ httpd_util:enable_debug(Debug),
Flags = {one_for_one, 0, 1},
Children = [sup_spec(httpd_acceptor_sup, Address, Port),
sup_spec(httpd_misc_sup, Address, Port),
worker_spec(httpd_manager, Address, Port,
ConfigFile, ConfigList,AcceptTimeout)],
{ok, {Flags, Children}};
-init([ConfigFile, ConfigList, AcceptTimeout, _Debug, Address, Port, ListenInfo]) ->
+init([ConfigFile, ConfigList, AcceptTimeout, Debug, Address, Port, ListenInfo]) ->
+ httpd_util:enable_debug(Debug),
Flags = {one_for_one, 0, 1},
Children = [sup_spec(httpd_acceptor_sup, Address, Port),
sup_spec(httpd_misc_sup, Address, Port),
@@ -154,7 +156,7 @@ make_name(Address,Port) ->
file_2_config(ConfigFile) ->
case httpd_conf:load(ConfigFile) of
{ok, ConfigList} ->
- case httpd_conf:validate_properties(ConfigList) of
+ case (catch httpd_conf:validate_properties(ConfigList)) of
{ok, Config} ->
Address = proplists:get_value(bind_address, ConfigList),
Port = proplists:get_value(port, ConfigList),
diff --git a/lib/inets/src/http_server/httpd_request.erl b/lib/inets/src/http_server/httpd_request.erl
index ad2cc4bda3..1c23316ecb 100644
--- a/lib/inets/src/http_server/httpd_request.erl
+++ b/lib/inets/src/http_server/httpd_request.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2005-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 2005-2011. All Rights Reserved.
+%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
-%%
+%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
-%%
+%%
%% %CopyrightEnd%
%%
@@ -68,10 +68,11 @@ body_data(Headers, Body) ->
{binary_to_list(BodyThisReq), Next}
end.
+
%%-------------------------------------------------------------------------
%% validate(Method, Uri, Version) -> ok | {error, {bad_request, Reason} |
%% {error, {not_supported, {Method, Uri, Version}}
-%% Method = "HEAD" | "GET" | "POST" | "TRACE"
+%% Method = "HEAD" | "GET" | "POST" | "TRACE" | "PUT" | "DELETE"
%% Uri = uri()
%% Version = "HTTP/N.M"
%% Description: Checks that HTTP-request-line is valid.
@@ -84,6 +85,10 @@ validate("GET", Uri, "HTTP/0.9") ->
validate_uri(Uri);
validate("GET", Uri, "HTTP/1." ++ _N) ->
validate_uri(Uri);
+validate("PUT", Uri, "HTTP/1." ++ _N) ->
+ validate_uri(Uri);
+validate("DELETE", Uri, "HTTP/1." ++ _N) ->
+ validate_uri(Uri);
validate("POST", Uri, "HTTP/1." ++ _N) ->
validate_uri(Uri);
validate("TRACE", Uri, "HTTP/1." ++ N) when hd(N) >= $1 ->
@@ -251,17 +256,17 @@ validate_uri(RequestURI) ->
UriNoQueryNoHex =
case string:str(RequestURI, "?") of
0 ->
- (catch httpd_util:decode_hex(RequestURI));
+ (catch http_uri:decode(RequestURI));
Ndx ->
- (catch httpd_util:decode_hex(string:left(RequestURI, Ndx)))
+ (catch http_uri:decode(string:left(RequestURI, Ndx)))
end,
case UriNoQueryNoHex of
- {'EXIT',_Reason} ->
+ {'EXIT', _Reason} ->
{error, {bad_request, {malformed_syntax, RequestURI}}};
_ ->
- Path = format_request_uri(UriNoQueryNoHex),
- Path2=[X||X<-string:tokens(Path, "/"),X=/="."], %% OTP-5938
- validate_path( Path2,0, RequestURI)
+ Path = format_request_uri(UriNoQueryNoHex),
+ Path2 = [X||X<-string:tokens(Path, "/"),X=/="."], %% OTP-5938
+ validate_path(Path2, 0, RequestURI)
end.
validate_path([], _, _) ->
diff --git a/lib/inets/src/http_server/httpd_request_handler.erl b/lib/inets/src/http_server/httpd_request_handler.erl
index fa832cba3f..1bf1b20b5b 100644
--- a/lib/inets/src/http_server/httpd_request_handler.erl
+++ b/lib/inets/src/http_server/httpd_request_handler.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1997-2009. All Rights Reserved.
+%% Copyright Ericsson AB 1997-2011. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
@@ -343,7 +343,7 @@ handle_http_msg({Method, Uri, Version, {RecordHeaders, Headers}, Body},
Reason = io_lib:format("Forbidden URI: ~p~n", [URI]),
error_log(Reason, ModData),
{stop, normal, State#state{response_sent = true}};
- {error,{bad_request, {malformed_syntax, URI}}} ->
+ {error, {bad_request, {malformed_syntax, URI}}} ->
?hdrd("validation failed: bad request - malformed syntax",
[{uri, URI}]),
httpd_response:send_status(ModData#mod{http_version = Version},
diff --git a/lib/inets/src/http_server/httpd_response.erl b/lib/inets/src/http_server/httpd_response.erl
index ea9cfbf4f2..dd7223876e 100644
--- a/lib/inets/src/http_server/httpd_response.erl
+++ b/lib/inets/src/http_server/httpd_response.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1997-2009. All Rights Reserved.
+%% Copyright Ericsson AB 1997-2011. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
@@ -78,6 +78,7 @@ traverse_modules(ModData,[Module|Rest]) ->
[Module, Reason])),
report_error(mod_log, ModData#mod.config_db, String),
report_error(mod_disk_log, ModData#mod.config_db, String),
+ send_status(ModData, 500, none),
done;
done ->
?hdrt("traverse modules - done", []),
@@ -100,12 +101,19 @@ send_status(#mod{socket_type = SocketType,
socket = Socket,
config_db = ConfigDB} = ModData, StatusCode, PhraseArgs) ->
+ ?hdrd("send status", [{status_code, StatusCode},
+ {phrase_args, PhraseArgs}]),
+
ReasonPhrase = httpd_util:reason_phrase(StatusCode),
Message = httpd_util:message(StatusCode, PhraseArgs, ConfigDB),
Body = get_body(ReasonPhrase, Message),
- send_header(ModData, StatusCode, [{content_type, "text/html"},
- {content_length, integer_to_list(length(Body))}]),
+ ?hdrt("send status - header", [{reason_phrase, ReasonPhrase},
+ {message, Message}]),
+ send_header(ModData, StatusCode,
+ [{content_type, "text/html"},
+ {content_length, integer_to_list(length(Body))}]),
+
httpd_socket:deliver(SocketType, Socket, Body).
@@ -345,8 +353,9 @@ transform({Field, Value}) when is_list(Field) ->
%% Leave this method and go on to the newer form of response
%% OTP-4408
%%----------------------------------------------------------------------
-send_response_old(#mod{method = "HEAD"} = ModData,
+send_response_old(#mod{method = "HEAD"} = ModData,
StatusCode, Response) ->
+
NewResponse = lists:flatten(Response),
case httpd_util:split(NewResponse, [?CR, ?LF, ?CR, ?LF],2) of
diff --git a/lib/inets/src/http_server/httpd_sup.erl b/lib/inets/src/http_server/httpd_sup.erl
index fc41994727..90d74e3a14 100644
--- a/lib/inets/src/http_server/httpd_sup.erl
+++ b/lib/inets/src/http_server/httpd_sup.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2004-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 2004-2011. All Rights Reserved.
+%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
-%%
+%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
-%%
+%%
%% %CopyrightEnd%
%%
%%
@@ -37,6 +37,7 @@
-define(TIMEOUT, 15000).
-include("httpd_internal.hrl").
+-include("inets_internal.hrl").
%%%=========================================================================
@@ -169,7 +170,7 @@ httpd_child_spec([Value| _] = Config, AcceptTimeout, Debug)
httpd_child_spec(ConfigFile, AcceptTimeout, Debug) ->
case httpd_conf:load(ConfigFile) of
{ok, ConfigList} ->
- case httpd_conf:validate_properties(ConfigList) of
+ case (catch httpd_conf:validate_properties(ConfigList)) of
{ok, Config} ->
Address = proplists:get_value(bind_address, Config, any),
Port = proplists:get_value(port, Config, 80),
@@ -185,14 +186,14 @@ httpd_child_spec(ConfigFile, AcceptTimeout, Debug) ->
httpd_child_spec(Config, AcceptTimeout, Debug, Addr, 0) ->
case start_listen(Addr, 0, Config) of
{Pid, {NewPort, NewConfig, ListenSocket}} ->
- Name = {httpd_instance_sup, Addr, NewPort},
+ Name = {httpd_instance_sup, Addr, NewPort},
StartFunc = {httpd_instance_sup, start_link,
[NewConfig, AcceptTimeout,
{Pid, ListenSocket}, Debug]},
- Restart = permanent,
- Shutdown = infinity,
- Modules = [httpd_instance_sup],
- Type = supervisor,
+ Restart = permanent,
+ Shutdown = infinity,
+ Modules = [httpd_instance_sup],
+ Type = supervisor,
{Name, StartFunc, Restart, Shutdown, Type, Modules};
{Pid, {error, Reason}} ->
exit(Pid, normal),
diff --git a/lib/inets/src/http_server/httpd_util.erl b/lib/inets/src/http_server/httpd_util.erl
index b59fd861dc..15bfe9c621 100644
--- a/lib/inets/src/http_server/httpd_util.erl
+++ b/lib/inets/src/http_server/httpd_util.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 1997-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 1997-2011. All Rights Reserved.
+%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
-%%
+%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
-%%
+%%
%% %CopyrightEnd%
%%
%%
@@ -21,7 +21,7 @@
-export([ip_address/2, lookup/2, lookup/3, multi_lookup/2,
lookup_mime/2, lookup_mime/3, lookup_mime_default/2,
lookup_mime_default/3, reason_phrase/1, message/3, rfc1123_date/0,
- rfc1123_date/1, day/1, month/1, decode_hex/1,
+ rfc1123_date/1, day/1, month/1,
flatlength/1, split_path/1, split_script_path/1,
suffix/1, split/3, uniq/1,
make_name/2,make_name/3,make_name/4,strip/1,
@@ -32,7 +32,8 @@
dir_validate/2, file_validate/2, mime_type_validate/1,
mime_types_validate/1, custom_date/0]).
--export([encode_hex/1]).
+-export([encode_hex/1, decode_hex/1]).
+
-include_lib("kernel/include/file.hrl").
ip_address({_,_,_,_} = Address, _IpFamily) ->
@@ -175,14 +176,15 @@ reason_phrase(_) -> "Internal Server Error".
%% message
message(301,URL,_) ->
- "The document has moved <A HREF=\""++URL++"\">here</A>.";
+ "The document has moved <A HREF=\"" ++ maybe_encode(URL) ++"\">here</A>.";
message(304, _URL,_) ->
"The document has not been changed.";
-message(400,none,_) ->
- "Your browser sent a query that this server could not understand.";
-message(400,Msg,_) ->
- "Your browser sent a query that this server could not understand. "++Msg;
-message(401,none,_) ->
+message(400, none, _) ->
+ "Your browser sent a query that this server could not understand. ";
+message(400, Msg, _) ->
+ "Your browser sent a query that this server could not understand. " ++
+ html_encode(Msg);
+message(401, none, _) ->
"This server could not verify that you
are authorized to access the document you
requested. Either you supplied the wrong
@@ -190,40 +192,66 @@ credentials (e.g., bad password), or your
browser doesn't understand how to supply
the credentials required.";
message(403,RequestURI,_) ->
- "You don't have permission to access "++RequestURI++" on this server.";
+ "You don't have permission to access " ++
+ html_encode(RequestURI) ++
+ " on this server.";
message(404,RequestURI,_) ->
- "The requested URL "++RequestURI++" was not found on this server.";
+ "The requested URL " ++
+ html_encode(RequestURI) ++
+ " was not found on this server.";
message(408, Timeout, _) ->
Timeout;
message(412,none,_) ->
"The requested preconditions where false";
message(413, Reason,_) ->
- "Entity: " ++ Reason;
+ "Entity: " ++ html_encode(Reason);
message(414,ReasonPhrase,_) ->
- "Message "++ReasonPhrase++".";
+ "Message " ++ html_encode(ReasonPhrase) ++ ".";
message(416,ReasonPhrase,_) ->
- ReasonPhrase;
+ html_encode(ReasonPhrase);
message(500,_,ConfigDB) ->
- ServerAdmin=lookup(ConfigDB,server_admin,"unknown@unknown"),
+ ServerAdmin = lookup(ConfigDB, server_admin, "unknown@unknown"),
"The server encountered an internal error or "
"misconfiguration and was unable to complete "
"your request.<P>Please contact the server administrator "
- ++ ServerAdmin ++ ", and inform them of the time the error occurred "
+ ++ html_encode(ServerAdmin) ++
+ ", and inform them of the time the error occurred "
"and anything you might have done that may have caused the error.";
message(501,{Method, RequestURI, HTTPVersion}, _ConfigDB) ->
if
is_atom(Method) ->
atom_to_list(Method)++
- " to "++RequestURI++" ("++HTTPVersion++") not supported.";
+ " to " ++
+ html_encode(RequestURI) ++
+ " (" ++ HTTPVersion ++ ") not supported.";
is_list(Method) ->
Method++
- " to "++RequestURI++" ("++HTTPVersion++") not supported."
+ " to " ++
+ html_encode(RequestURI) ++
+ " (" ++ HTTPVersion ++ ") not supported."
end;
message(503, String, _ConfigDB) ->
- "This service in unavailable due to: "++String.
+ "This service in unavailable due to: " ++ html_encode(String).
+
+maybe_encode(URI) ->
+ case lists:member($%, URI) of
+ true ->
+ URI;
+ false ->
+ http_uri:encode(URI)
+ end.
+
+html_encode(String) ->
+ try http_uri:decode(String) of
+ Decoded when is_list(Decoded) ->
+ http_util:html_encode(Decoded)
+ catch
+ _:_ ->
+ http_util:html_encode(String)
+ end.
%%convert_rfc_date(Date)->{{YYYY,MM,DD},{HH,MIN,SEC}}
@@ -237,7 +265,7 @@ convert_request_date([D,A,Y,DateType| Rest])->
fun convert_rfc850_date/1
end,
case catch Func([D,A,Y,DateType| Rest]) of
- {ok,Date} ->
+ {ok, Date} ->
Date;
_Error->
bad_date
@@ -381,16 +409,11 @@ month(12) -> "Dec".
%% decode_hex
-decode_hex([$%,Hex1,Hex2|Rest]) ->
- [hex2dec(Hex1)*16+hex2dec(Hex2)|decode_hex(Rest)];
-decode_hex([First|Rest]) ->
- [First|decode_hex(Rest)];
-decode_hex([]) ->
- [].
+decode_hex(URI) ->
+ http_uri:decode(URI).
-hex2dec(X) when (X>=$0) andalso (X=<$9) -> X-$0;
-hex2dec(X) when (X>=$A) andalso (X=<$F) -> X-$A+10;
-hex2dec(X) when (X>=$a) andalso (X=<$f) -> X-$a+10.
+encode_hex(URI) ->
+ http_uri:encode(URI).
%% flatlength
flatlength(List) ->
@@ -411,7 +434,7 @@ split_path(Path) ->
case inets_regexp:match(Path,"[\?].*\$") of
%% A QUERY_STRING exists!
{match,Start,Length} ->
- {httpd_util:decode_hex(string:substr(Path,1,Start-1)),
+ {http_uri:decode(string:substr(Path,1,Start-1)),
string:substr(Path,Start,Length)};
%% A possible PATH_INFO exists!
nomatch ->
@@ -419,9 +442,9 @@ split_path(Path) ->
end.
split_path([],SoFar) ->
- {httpd_util:decode_hex(lists:reverse(SoFar)),[]};
+ {http_uri:decode(lists:reverse(SoFar)),[]};
split_path([$/|Rest],SoFar) ->
- Path=httpd_util:decode_hex(lists:reverse(SoFar)),
+ Path = http_uri:decode(lists:reverse(SoFar)),
case file:read_file_info(Path) of
{ok,FileInfo} when FileInfo#file_info.type =:= regular ->
{Path,[$/|Rest]};
@@ -454,7 +477,7 @@ pathinfo_querystring([C|Rest], SoFar) ->
pathinfo_querystring(Rest, [C|SoFar]).
split_script_path([$?|QueryString], SoFar) ->
- Path = httpd_util:decode_hex(lists:reverse(SoFar)),
+ Path = http_uri:decode(lists:reverse(SoFar)),
case file:read_file_info(Path) of
{ok,FileInfo} when FileInfo#file_info.type =:= regular ->
{Path, [$?|QueryString]};
@@ -464,7 +487,7 @@ split_script_path([$?|QueryString], SoFar) ->
not_a_script
end;
split_script_path([], SoFar) ->
- Path = httpd_util:decode_hex(lists:reverse(SoFar)),
+ Path = http_uri:decode(lists:reverse(SoFar)),
case file:read_file_info(Path) of
{ok,FileInfo} when FileInfo#file_info.type =:= regular ->
{Path, []};
@@ -474,7 +497,7 @@ split_script_path([], SoFar) ->
not_a_script
end;
split_script_path([$/|Rest], SoFar) ->
- Path = httpd_util:decode_hex(lists:reverse(SoFar)),
+ Path = http_uri:decode(lists:reverse(SoFar)),
case file:read_file_info(Path) of
{ok, FileInfo} when FileInfo#file_info.type =:= regular ->
{Path, [$/|Rest]};
@@ -608,8 +631,6 @@ hexlist_to_integer(List)->
%%----------------------------------------------------------------------
%%Converts an integer to an hexlist
%%----------------------------------------------------------------------
-encode_hex(Num)->
- integer_to_hexlist(Num).
integer_to_hexlist(Num) when is_integer(Num) ->
http_util:integer_to_hexlist(Num).
@@ -755,23 +776,18 @@ do_enable_debug([{Level,Modules}|Rest])
when is_atom(Level) andalso is_list(Modules) ->
case Level of
all_functions ->
- io:format("Tracing on all functions set on modules: ~p~n",
- [Modules]),
lists:foreach(
- fun(X)->
+ fun(X) ->
dbg:tpl(X, [{'_', [], [{return_trace}]}])
end, Modules);
exported_functions ->
- io:format("Tracing on exported functions set on "
- "modules: ~p~n",[Modules]),
lists:foreach(
- fun(X)->
+ fun(X) ->
dbg:tp(X, [{'_', [], [{return_trace}]}])
end, Modules);
disable ->
- io:format("Tracing disabled on modules: ~p~n", [Modules]),
lists:foreach(
- fun(X)->
+ fun(X) ->
dbg:ctp(X)
end, Modules);
_ ->
diff --git a/lib/inets/src/http_server/mod_alias.erl b/lib/inets/src/http_server/mod_alias.erl
index 7073f5405d..41fcdb5e3a 100644
--- a/lib/inets/src/http_server/mod_alias.erl
+++ b/lib/inets/src/http_server/mod_alias.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 1997-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 1997-2011. All Rights Reserved.
+%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
-%%
+%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
-%%
+%%
%% %CopyrightEnd%
%%
%%
@@ -28,44 +28,52 @@
path/3]).
-include("httpd.hrl").
+-include("httpd_internal.hrl").
+-include("inets_internal.hrl").
-define(VMODULE,"ALIAS").
%% do
-do(Info) ->
- case proplists:get_value(status, Info#mod.data) of
+do(#mod{data = Data} = Info) ->
+ ?hdrt("do", []),
+ case proplists:get_value(status, Data) of
%% A status code has been generated!
{_StatusCode, _PhraseArgs, _Reason} ->
- {proceed,Info#mod.data};
+ {proceed, Data};
%% No status code has been generated!
undefined ->
- case proplists:get_value(response, Info#mod.data) of
+ case proplists:get_value(response, Data) of
%% No response has been generated!
undefined ->
do_alias(Info);
%% A response has been generated or sent!
_Response ->
- {proceed, Info#mod.data}
+ {proceed, Data}
end
end.
-do_alias(Info) ->
- {ShortPath, Path, AfterPath} =
- real_name(Info#mod.config_db,
- Info#mod.request_uri,
- httpd_util:multi_lookup(Info#mod.config_db,alias)),
+do_alias(#mod{config_db = ConfigDB,
+ request_uri = ReqURI,
+ data = Data}) ->
+ {ShortPath, Path, AfterPath} =
+ real_name(ConfigDB, ReqURI, which_alias(ConfigDB)),
+ ?hdrt("real name",
+ [{request_uri, ReqURI},
+ {short_path, ShortPath},
+ {path, Path},
+ {after_path, AfterPath}]),
%% Relocate if a trailing slash is missing else proceed!
LastChar = lists:last(ShortPath),
case file:read_file_info(ShortPath) of
- {ok, FileInfo} when FileInfo#file_info.type == directory,
- LastChar /= $/ ->
- ServerName = httpd_util:lookup(Info#mod.config_db, server_name),
- Port = port_string(httpd_util:lookup(Info#mod.config_db,port, 80)),
- URL = "http://" ++ ServerName ++ Port ++
- Info#mod.request_uri ++ "/",
+ {ok, FileInfo} when ((FileInfo#file_info.type =:= directory) andalso
+ (LastChar =/= $/)) ->
+ ?hdrt("directory and last-char is a /", []),
+ ServerName = which_server_name(ConfigDB),
+ Port = port_string( which_port(ConfigDB) ),
+ URL = "http://" ++ ServerName ++ Port ++ ReqURI ++ "/",
ReasonPhrase = httpd_util:reason_phrase(301),
- Message = httpd_util:message(301, URL, Info#mod.config_db),
+ Message = httpd_util:message(301, URL, ConfigDB),
{proceed,
[{response,
{301, ["Location: ", URL, "\r\n"
@@ -76,25 +84,26 @@ do_alias(Info) ->
"<BODY>\n<H1>",ReasonPhrase,
"</H1>\n", Message,
"\n</BODY>\n</HTML>\n"]}}|
- [{real_name, {Path, AfterPath}} | Info#mod.data]]};
+ [{real_name, {Path, AfterPath}} | Data]]};
_NoFile ->
- {proceed,[{real_name, {Path, AfterPath}} | Info#mod.data]}
+ {proceed, [{real_name, {Path, AfterPath}} | Data]}
end.
port_string(80) ->
"";
port_string(Port) ->
- ":"++integer_to_list(Port).
+ ":" ++ integer_to_list(Port).
%% real_name
real_name(ConfigDB, RequestURI, []) ->
- DocumentRoot = httpd_util:lookup(ConfigDB, document_root, ""),
+ DocumentRoot = which_document_root(ConfigDB),
RealName = DocumentRoot ++ RequestURI,
{ShortPath, _AfterPath} = httpd_util:split_path(RealName),
- {Path, AfterPath} = httpd_util:split_path(default_index(ConfigDB,
- RealName)),
+ {Path, AfterPath} =
+ httpd_util:split_path(default_index(ConfigDB, RealName)),
{ShortPath, Path, AfterPath};
+
real_name(ConfigDB, RequestURI, [{FakeName,RealName}|Rest]) ->
case inets_regexp:match(RequestURI, "^" ++ FakeName) of
{match, _, _} ->
@@ -105,7 +114,7 @@ real_name(ConfigDB, RequestURI, [{FakeName,RealName}|Rest]) ->
httpd_util:split_path(default_index(ConfigDB, ActualName)),
{ShortPath, Path, AfterPath};
nomatch ->
- real_name(ConfigDB,RequestURI,Rest)
+ real_name(ConfigDB, RequestURI, Rest)
end.
%% real_script_name
@@ -113,20 +122,21 @@ real_name(ConfigDB, RequestURI, [{FakeName,RealName}|Rest]) ->
real_script_name(_ConfigDB, _RequestURI, []) ->
not_a_script;
real_script_name(ConfigDB, RequestURI, [{FakeName,RealName} | Rest]) ->
- case inets_regexp:match(RequestURI,"^"++FakeName) of
+ case inets_regexp:match(RequestURI, "^" ++ FakeName) of
{match,_,_} ->
- {ok,ActualName,_}=inets_regexp:sub(RequestURI,"^"++FakeName,RealName),
- httpd_util:split_script_path(default_index(ConfigDB,ActualName));
+ {ok, ActualName, _} =
+ inets_regexp:sub(RequestURI, "^" ++ FakeName, RealName),
+ httpd_util:split_script_path(default_index(ConfigDB, ActualName));
nomatch ->
- real_script_name(ConfigDB,RequestURI,Rest)
+ real_script_name(ConfigDB, RequestURI, Rest)
end.
%% default_index
default_index(ConfigDB, Path) ->
case file:read_file_info(Path) of
- {ok, FileInfo} when FileInfo#file_info.type == directory ->
- DirectoryIndex = httpd_util:lookup(ConfigDB, directory_index, []),
+ {ok, FileInfo} when FileInfo#file_info.type =:= directory ->
+ DirectoryIndex = which_directory_index(ConfigDB),
append_index(Path, DirectoryIndex);
_ ->
Path
@@ -147,9 +157,9 @@ append_index(RealName, [Index | Rest]) ->
path(Data, ConfigDB, RequestURI) ->
case proplists:get_value(real_name, Data) of
undefined ->
- DocumentRoot = httpd_util:lookup(ConfigDB, document_root, ""),
+ DocumentRoot = which_document_root(ConfigDB),
{Path, _AfterPath} =
- httpd_util:split_path(DocumentRoot++RequestURI),
+ httpd_util:split_path(DocumentRoot ++ RequestURI),
Path;
{Path, _AfterPath} ->
Path
@@ -164,7 +174,7 @@ path(Data, ConfigDB, RequestURI) ->
load("DirectoryIndex " ++ DirectoryIndex, []) ->
{ok, DirectoryIndexes} = inets_regexp:split(DirectoryIndex," "),
{ok,[], {directory_index, DirectoryIndexes}};
-load("Alias " ++ Alias,[]) ->
+load("Alias " ++ Alias, []) ->
case inets_regexp:split(Alias," ") of
{ok, [FakeName, RealName]} ->
{ok,[],{alias,{FakeName,RealName}}};
@@ -191,13 +201,13 @@ store({directory_index, Value} = Conf, _) when is_list(Value) ->
end;
store({directory_index, Value}, _) ->
{error, {wrong_type, {directory_index, Value}}};
-store({alias, {Fake, Real}} = Conf, _) when is_list(Fake),
- is_list(Real) ->
+store({alias, {Fake, Real}} = Conf, _)
+ when is_list(Fake) andalso is_list(Real) ->
{ok, Conf};
store({alias, Value}, _) ->
{error, {wrong_type, {alias, Value}}};
-store({script_alias, {Fake, Real}} = Conf, _) when is_list(Fake),
- is_list(Real) ->
+store({script_alias, {Fake, Real}} = Conf, _)
+ when is_list(Fake) andalso is_list(Real) ->
{ok, Conf};
store({script_alias, Value}, _) ->
{error, {wrong_type, {script_alias, Value}}}.
@@ -208,3 +218,21 @@ is_directory_index_list([Head | Tail]) when is_list(Head) ->
is_directory_index_list(Tail);
is_directory_index_list(_) ->
false.
+
+
+%% ---------------------------------------------------------------------
+
+which_alias(ConfigDB) ->
+ httpd_util:multi_lookup(ConfigDB, alias).
+
+which_server_name(ConfigDB) ->
+ httpd_util:lookup(ConfigDB, server_name).
+
+which_port(ConfigDB) ->
+ httpd_util:lookup(ConfigDB, port, 80).
+
+which_document_root(ConfigDB) ->
+ httpd_util:lookup(ConfigDB, document_root, "").
+
+which_directory_index(ConfigDB) ->
+ httpd_util:lookup(ConfigDB, directory_index, []).
diff --git a/lib/inets/src/http_server/mod_auth.erl b/lib/inets/src/http_server/mod_auth.erl
index 07cafb4726..b1d8b03fe4 100644
--- a/lib/inets/src/http_server/mod_auth.erl
+++ b/lib/inets/src/http_server/mod_auth.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1997-2009. All Rights Reserved.
+%% Copyright Ericsson AB 1997-2011. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
@@ -38,6 +38,7 @@
-include("httpd.hrl").
-include("mod_auth.hrl").
-include("httpd_internal.hrl").
+-include("inets_internal.hrl").
-define(VMODULE,"AUTH").
diff --git a/lib/inets/src/http_server/mod_auth_dets.erl b/lib/inets/src/http_server/mod_auth_dets.erl
index bc6c2b70a0..2abf5c517a 100644
--- a/lib/inets/src/http_server/mod_auth_dets.erl
+++ b/lib/inets/src/http_server/mod_auth_dets.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1998-2009. All Rights Reserved.
+%% Copyright Ericsson AB 1998-2011. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
@@ -35,6 +35,7 @@
-export([store_directory_data/3]).
-include("httpd.hrl").
+-include("inets_internal.hrl").
-include("mod_auth.hrl").
store_directory_data(_Directory, DirData, Server_root) ->
diff --git a/lib/inets/src/http_server/mod_auth_plain.erl b/lib/inets/src/http_server/mod_auth_plain.erl
index d88859d28a..12342ba8da 100644
--- a/lib/inets/src/http_server/mod_auth_plain.erl
+++ b/lib/inets/src/http_server/mod_auth_plain.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1998-2009. All Rights Reserved.
+%% Copyright Ericsson AB 1998-2011. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
@@ -22,6 +22,7 @@
-include("httpd.hrl").
-include("mod_auth.hrl").
-include("httpd_internal.hrl").
+-include("inets_internal.hrl").
-define(VMODULE,"AUTH_PLAIN").
diff --git a/lib/inets/src/http_server/mod_auth_server.erl b/lib/inets/src/http_server/mod_auth_server.erl
index 5f9e59be9d..fc50356838 100644
--- a/lib/inets/src/http_server/mod_auth_server.erl
+++ b/lib/inets/src/http_server/mod_auth_server.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2001-2009. All Rights Reserved.
+%% Copyright Ericsson AB 2001-2011. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
@@ -22,6 +22,7 @@
-include("httpd.hrl").
-include("httpd_internal.hrl").
+-include("inets_internal.hrl").
-behaviour(gen_server).
diff --git a/lib/inets/src/http_server/mod_cgi.erl b/lib/inets/src/http_server/mod_cgi.erl
index ab12a3b57b..33605b9698 100644
--- a/lib/inets/src/http_server/mod_cgi.erl
+++ b/lib/inets/src/http_server/mod_cgi.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%
%%
%%
@@ -335,6 +335,8 @@ script_elements(#mod{method = "GET"}, {PathInfo, QueryString}) ->
[{query_string, QueryString}, {path_info, PathInfo}];
script_elements(#mod{method = "POST", entity_body = Body}, _) ->
[{entity_body, Body}];
+script_elements(#mod{method = "PUT", entity_body = Body}, _) ->
+ [{entity_body, Body}];
script_elements(_, _) ->
[].
diff --git a/lib/inets/src/http_server/mod_dir.erl b/lib/inets/src/http_server/mod_dir.erl
index cdc7cc01e4..35e9de24e2 100644
--- a/lib/inets/src/http_server/mod_dir.erl
+++ b/lib/inets/src/http_server/mod_dir.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1997-2009. All Rights Reserved.
+%% Copyright Ericsson AB 1997-2011. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
@@ -18,9 +18,11 @@
%%
%%
-module(mod_dir).
+
-export([do/1]).
-include("httpd.hrl").
+-include("httpd_internal.hrl").
%% do
@@ -57,7 +59,7 @@ do_dir(Info) ->
case file:read_file_info(DefaultPath) of
{ok,FileInfo} when FileInfo#file_info.type == directory ->
DecodedRequestURI =
- httpd_util:decode_hex(Info#mod.request_uri),
+ http_uri:decode(Info#mod.request_uri),
?DEBUG("do_dir -> ~n"
" Path: ~p~n"
" DefaultPath: ~p~n"
diff --git a/lib/inets/src/http_server/mod_esi.erl b/lib/inets/src/http_server/mod_esi.erl
index dd6f62ae2d..bbdb67bb0e 100644
--- a/lib/inets/src/http_server/mod_esi.erl
+++ b/lib/inets/src/http_server/mod_esi.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 1997-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 1997-2011. All Rights Reserved.
+%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
-%%
+%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
-%%
+%%
%% %CopyrightEnd%
%%
%%
@@ -29,10 +29,12 @@
-export([do/1, load/2, store/2]).
-include("httpd.hrl").
+-include("inets_internal.hrl").
-define(VMODULE,"ESI").
-define(DEFAULT_ERL_TIMEOUT,15000).
+
%%%=========================================================================
%%% API
%%%=========================================================================
@@ -52,6 +54,7 @@ deliver(SessionID, Data) when is_pid(SessionID) ->
deliver(_SessionID, _Data) ->
{error, bad_sessionID}.
+
%%%=========================================================================
%%% CALLBACK API
%%%=========================================================================
@@ -74,6 +77,8 @@ do(ModData) ->
{proceed, ModData#mod.data}
end
end.
+
+
%%--------------------------------------------------------------------------
%% load(Line, Context) -> eof | ok | {ok, NewContext} |
%% {ok, NewContext, Directive} |
@@ -127,6 +132,7 @@ load("ErlScriptNoCache " ++ CacheArg, [])->
" is an invalid ErlScriptNoCache directive")}
end.
+
%%--------------------------------------------------------------------------
%% store(Directive, DirectiveList) -> {ok, NewDirective} |
%% {ok, [NewDirective]} |
@@ -163,16 +169,18 @@ store({eval_script_alias, {Name, Modules}} = Conf, _)
store({erl_script_alias, Value}, _) ->
{error, {wrong_type, {erl_script_alias, Value}}};
-store({erl_script_timeout, Value} = Conf, _)
- when is_integer(Value), Value >= 0 ->
- {ok, Conf};
+store({erl_script_timeout, TimeoutSec}, _)
+ when is_integer(TimeoutSec) andalso (TimeoutSec >= 0) ->
+ {ok, {erl_script_timeout, TimeoutSec * 1000}};
store({erl_script_timeout, Value}, _) ->
{error, {wrong_type, {erl_script_timeout, Value}}};
-store({erl_script_nocache, Value} = Conf, _) when Value == true;
- Value == false ->
+store({erl_script_nocache, Value} = Conf, _)
+ when (Value =:= true) orelse (Value =:= false) ->
{ok, Conf};
store({erl_script_nocache, Value}, _) ->
{error, {wrong_type, {erl_script_nocache, Value}}}.
+
+
%%%========================================================================
%%% Internal functions
%%%========================================================================
@@ -227,7 +235,7 @@ alias_match_str(Alias, eval_script_alias) ->
%%------------------------ Erl mechanism --------------------------------
erl(#mod{method = Method} = ModData, ESIBody, Modules)
- when Method == "GET"; Method == "HEAD"->
+ when (Method =:= "GET") orelse (Method =:= "HEAD") ->
case httpd_util:split(ESIBody,":|%3A|/",2) of
{ok, [ModuleName, FuncAndInput]} ->
case httpd_util:split(FuncAndInput,"[\?/]",2) of
@@ -249,7 +257,24 @@ erl(#mod{method = Method} = ModData, ESIBody, Modules)
{proceed, [{status,{400, none, BadRequest}} | ModData#mod.data]}
end;
-erl(#mod{method = "POST", entity_body = Body} = ModData, ESIBody, Modules) ->
+erl(#mod{request_uri = ReqUri,
+ method = "PUT",
+ http_version = Version,
+ data = Data}, _ESIBody, _Modules) ->
+ {proceed, [{status,{501,{"PUT", ReqUri, Version},
+ ?NICE("Erl mechanism doesn't support method PUT")}}|
+ Data]};
+
+erl(#mod{request_uri = ReqUri,
+ method = "DELETE",
+ http_version = Version,
+ data = Data}, _ESIBody, _Modules) ->
+ {proceed,[{status,{501,{"DELETE", ReqUri, Version},
+ ?NICE("Erl mechanism doesn't support method DELETE")}}|
+ Data]};
+
+erl(#mod{method = "POST",
+ entity_body = Body} = ModData, ESIBody, Modules) ->
case httpd_util:split(ESIBody,":|%3A|/",2) of
{ok,[ModuleName, Function]} ->
generate_webpage(ModData, ESIBody, Modules,
@@ -330,7 +355,7 @@ erl_scheme_webpage_chunk(Mod, Func, Env, Input, ModData) ->
Pid = spawn_link(
fun() ->
case catch Mod:Func(Self, Env, Input) of
- {'EXIT',{undef,_}} ->
+ {'EXIT', {undef,_}} ->
%% Will force fallback on the old API
exit(erl_scheme_webpage_chunk_undefined);
_ ->
@@ -413,11 +438,12 @@ handle_body(Pid, ModData, Body, Timeout, Size, IsDisableChunkedSend) ->
{proceed, [{response, {already_sent, 200, Size}} |
ModData#mod.data]};
{'EXIT', Pid, Reason} when is_pid(Pid) ->
+ httpd_response:send_final_chunk(ModData, IsDisableChunkedSend),
exit({mod_esi_linked_process_died, Pid, Reason})
after Timeout ->
process_flag(trap_exit,false),
- {proceed,[{response, {already_sent, 200, Size}} |
- ModData#mod.data]}
+ httpd_response:send_final_chunk(ModData, IsDisableChunkedSend),
+ exit({mod_esi_linked_process_timeout, Pid})
end.
erl_script_timeout(Db) ->
@@ -444,8 +470,26 @@ input_type([_First|Rest]) ->
%%------------------------ Eval mechanism --------------------------------
-eval(#mod{request_uri = ReqUri, method = "POST",
- http_version = Version, data = Data}, _ESIBody, _Modules) ->
+eval(#mod{request_uri = ReqUri,
+ method = "PUT",
+ http_version = Version,
+ data = Data}, _ESIBody, _Modules) ->
+ {proceed,[{status,{501,{"PUT", ReqUri, Version},
+ ?NICE("Eval mechanism doesn't support method PUT")}}|
+ Data]};
+
+eval(#mod{request_uri = ReqUri,
+ method = "DELETE",
+ http_version = Version,
+ data = Data}, _ESIBody, _Modules) ->
+ {proceed,[{status,{501,{"DELETE", ReqUri, Version},
+ ?NICE("Eval mechanism doesn't support method DELETE")}}|
+ Data]};
+
+eval(#mod{request_uri = ReqUri,
+ method = "POST",
+ http_version = Version,
+ data = Data}, _ESIBody, _Modules) ->
{proceed,[{status,{501,{"POST", ReqUri, Version},
?NICE("Eval mechanism doesn't support method POST")}}|
Data]};
diff --git a/lib/inets/src/http_server/mod_include.erl b/lib/inets/src/http_server/mod_include.erl
index 534eba8a36..790bf8f937 100644
--- a/lib/inets/src/http_server/mod_include.erl
+++ b/lib/inets/src/http_server/mod_include.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1997-2009. All Rights Reserved.
+%% Copyright Ericsson AB 1997-2011. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
@@ -186,9 +186,9 @@ document_uri(ConfigDB, RequestURI) ->
FileName = string:substr(Path,Start,Length),
case inets_regexp:match(VirtualPath, FileName++"\$") of
{match, _, _} ->
- httpd_util:decode_hex(VirtualPath)++AfterPath;
+ http_uri:decode(VirtualPath)++AfterPath;
nomatch ->
- string:strip(httpd_util:decode_hex(VirtualPath),right,$/)++
+ string:strip(http_uri:decode(VirtualPath),right,$/)++
"/"++FileName++AfterPath
end.
diff --git a/lib/inets/src/http_server/mod_responsecontrol.erl b/lib/inets/src/http_server/mod_responsecontrol.erl
index 79e2e1bdba..05b5ba1609 100644
--- a/lib/inets/src/http_server/mod_responsecontrol.erl
+++ b/lib/inets/src/http_server/mod_responsecontrol.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2001-2009. All Rights Reserved.
+%% Copyright Ericsson AB 2001-2011. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
@@ -208,14 +208,14 @@ compare_etags(Tag,Etags) ->
nomatch
end.
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-%% %%
-%%Control if the file is modificated %%
-%% %%
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%% %%
+%% Control if the file is modificated %%
+%% %%
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%----------------------------------------------------------------------
-%%Control the If-Modified-Since and If-Not-Modified-Since header fields
+%% Control the If-Modified-Since and If-Not-Modified-Since header fields
%%----------------------------------------------------------------------
control_modification(Path,Info,FileInfo)->
?DEBUG("control_modification() -> entry",[]),
@@ -226,6 +226,8 @@ control_modification(Path,Info,FileInfo)->
continue;
unmodified->
{304, Info, Path};
+ {bad_date, _} = BadDate->
+ {400, Info, BadDate};
undefined ->
case control_modification_data(Info,
FileInfo#file_info.mtime,
@@ -252,21 +254,27 @@ control_modification_data(Info, ModificationTime, HeaderField)->
undefined->
undefined;
LastModified0 ->
- LastModified = calendar:universal_time_to_local_time(
- httpd_util:convert_request_date(LastModified0)),
- ?DEBUG("control_modification_data() -> "
- "~n Request-Field: ~s"
- "~n FileLastModified: ~p"
- "~n FieldValue: ~p",
- [HeaderField, ModificationTime, LastModified]),
- FileTime =
- calendar:datetime_to_gregorian_seconds(ModificationTime),
- FieldTime = calendar:datetime_to_gregorian_seconds(LastModified),
- if
- FileTime =< FieldTime ->
- ?DEBUG("File unmodified~n", []), unmodified;
- FileTime >= FieldTime ->
- ?DEBUG("File modified~n", []), modified
+ case httpd_util:convert_request_date(LastModified0) of
+ bad_date ->
+ {bad_date, LastModified0};
+ ConvertedReqDate ->
+ LastModified =
+ calendar:universal_time_to_local_time(ConvertedReqDate),
+ ?DEBUG("control_modification_data() -> "
+ "~n Request-Field: ~s"
+ "~n FileLastModified: ~p"
+ "~n FieldValue: ~p",
+ [HeaderField, ModificationTime, LastModified]),
+ FileTime =
+ calendar:datetime_to_gregorian_seconds(ModificationTime),
+ FieldTime =
+ calendar:datetime_to_gregorian_seconds(LastModified),
+ if
+ FileTime =< FieldTime ->
+ ?DEBUG("File unmodified~n", []), unmodified;
+ FileTime >= FieldTime ->
+ ?DEBUG("File modified~n", []), modified
+ end
end
end.
@@ -284,6 +292,9 @@ strip_date([C | Rest]) ->
send_return_value({412,_,_}, _FileInfo)->
{status,{412,none,"Precondition Failed"}};
+send_return_value({400,_, {bad_date, BadDate}}, _FileInfo)->
+ {status, {400, none, "Bad date: " ++ BadDate}};
+
send_return_value({304,Info,Path}, FileInfo)->
Suffix = httpd_util:suffix(Path),
MimeType = httpd_util:lookup_mime_default(Info#mod.config_db,Suffix,
diff --git a/lib/inets/src/http_server/mod_security.erl b/lib/inets/src/http_server/mod_security.erl
index 95793e1cfb..5cdbeb9792 100644
--- a/lib/inets/src/http_server/mod_security.erl
+++ b/lib/inets/src/http_server/mod_security.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1998-2009. All Rights Reserved.
+%% Copyright Ericsson AB 1998-2011. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
@@ -32,6 +32,7 @@
-include("httpd.hrl").
-include("httpd_internal.hrl").
+-include("inets_internal.hrl").
-define(VMODULE,"SEC").
diff --git a/lib/inets/src/http_server/mod_security_server.erl b/lib/inets/src/http_server/mod_security_server.erl
index 58060686b3..ca8bee0c8e 100644
--- a/lib/inets/src/http_server/mod_security_server.erl
+++ b/lib/inets/src/http_server/mod_security_server.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2001-2009. All Rights Reserved.
+%% Copyright Ericsson AB 2001-2011. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
@@ -45,6 +45,7 @@
-include("httpd.hrl").
-include("httpd_internal.hrl").
+-include("inets_internal.hrl").
-behaviour(gen_server).
diff --git a/lib/inets/src/inets_app/Makefile b/lib/inets/src/inets_app/Makefile
index 2dab99386a..33c9e34a3a 100644
--- a/lib/inets/src/inets_app/Makefile
+++ b/lib/inets/src/inets_app/Makefile
@@ -1,19 +1,19 @@
#
# %CopyrightBegin%
-#
-# Copyright Ericsson AB 2005-2009. All Rights Reserved.
-#
+#
+# Copyright Ericsson AB 2005-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%
#
#
@@ -22,6 +22,7 @@ include $(ERL_TOP)/make/target.mk
EBIN = ../../ebin
include $(ERL_TOP)/make/$(TARGET)/otp.mk
+
# ----------------------------------------------------
# Application version
# ----------------------------------------------------
@@ -32,12 +33,13 @@ VSN = $(INETS_VSN)
# ----------------------------------------------------
# Release directory specification
# ----------------------------------------------------
-RELSYSDIR = $(RELEASE_PATH)/lib/inets-$(VSN)
+RELSYSDIR = $(RELEASE_PATH)/lib/$(APPLICATION)-$(VSN)
# ----------------------------------------------------
# Target Specs
# ----------------------------------------------------
+
MODULES = \
inets_service \
inets \
@@ -49,7 +51,8 @@ HRL_FILES = inets_internal.hrl
ERL_FILES = $(MODULES:%=%.erl)
-TARGET_FILES= $(MODULES:%=$(EBIN)/%.$(EMULATOR)) \
+TARGET_FILES= \
+ $(MODULES:%=$(EBIN)/%.$(EMULATOR)) \
$(APP_TARGET) \
$(APPUP_TARGET)
@@ -66,7 +69,7 @@ APPUP_TARGET = $(EBIN)/$(APPUP_FILE)
# ----------------------------------------------------
# INETS FLAGS
# ----------------------------------------------------
-INETS_FLAGS = -D'SERVER_SOFTWARE="inets/$(VSN)"' \
+INETS_FLAGS = -D'SERVER_SOFTWARE="$(APPLICATION)/$(VSN)"'
# ----------------------------------------------------
@@ -108,14 +111,15 @@ $(APPUP_TARGET): $(APPUP_SRC) ../../vsn.mk
include $(ERL_TOP)/make/otp_release_targets.mk
release_spec: opt
- $(INSTALL_DIR) $(RELSYSDIR)/src
+ $(INSTALL_DIR) $(RELSYSDIR)/src
$(INSTALL_DATA) $(HRL_FILES) $(ERL_FILES) $(RELSYSDIR)/src
- $(INSTALL_DIR) $(RELSYSDIR)/ebin
+ $(INSTALL_DIR) $(RELSYSDIR)/ebin
$(INSTALL_DATA) $(TARGET_FILES) $(RELSYSDIR)/ebin
release_docs_spec:
info:
+ @echo "APPLICATION = $(APPLICATION)"
@echo "INETS_DEBUG = $(INETS_DEBUG)"
@echo "INETS_FLAGS = $(INETS_FLAGS)"
@echo "ERL_COMPILE_FLAGS = $(ERL_COMPILE_FLAGS)"
diff --git a/lib/inets/src/inets_app/inets.app.src b/lib/inets/src/inets_app/inets.app.src
index 6524c3b19b..04f6365b98 100644
--- a/lib/inets/src/inets_app/inets.app.src
+++ b/lib/inets/src/inets_app/inets.app.src
@@ -1,19 +1,19 @@
%% This is an -*- erlang -*- file.
%% %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%
%%
@@ -34,7 +34,8 @@
ftp_sup,
%% HTTP client:
- http,
+ http, %% Old client API module
+ httpc, %% New client API module
httpc_handler,
httpc_handler_sup,
httpc_manager,
@@ -42,7 +43,7 @@
httpc_request,
httpc_response,
httpc_sup,
- http_cookie,
+ httpc_cookie,
http_uri, %% Proably will by used by server also in the future
diff --git a/lib/inets/src/inets_app/inets.appup.src b/lib/inets/src/inets_app/inets.appup.src
index 59ee1ba03d..2bf36cb47d 100644
--- a/lib/inets/src/inets_app/inets.appup.src
+++ b/lib/inets/src/inets_app/inets.appup.src
@@ -1,7 +1,7 @@
%% This is an -*- erlang -*- file.
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1999-2009. All Rights Reserved.
+%% Copyright Ericsson AB 1999-2011. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
@@ -18,27 +18,99 @@
{"%VSN%",
[
+ {"5.3.5",
+ [
+ {load_module, http_util, soft_purge, soft_purge, []},
+ {load_module, httpd_util, soft_purge, soft_purge, [http_util]},
+ {load_module, httpd_file, soft_purge, soft_purge, []},
+ {load_module, mod_responsecontrol, soft_purge, soft_purge, []},
+ {load_module, httpd_response, soft_purge, soft_purge, [mod_responsecontrol]}
+ ]
+ },
+ {"5.3.4",
+ [
+ {restart_application, inets}
+ ]
+ },
+ {"5.3.3",
+ [
+ {restart_application, inets}
+ ]
+ },
+ {"5.3.2",
+ [
+ {restart_application, inets}
+ ]
+ },
+ {"5.3.1",
+ [
+ {restart_application, inets}
+ ]
+ },
+ {"5.3",
+ [
+ {restart_application, inets}
+ ]
+ },
+ {"5.2",
+ [
+ {restart_application, inets}
+ ]
+ },
{"5.1.3",
[
- {load_module, httpd_response, soft_purge, soft_purge, []},
- {update, ftp, {advanced, upgrade_from_pre_5_12},
- soft_purge, soft_purge, []},
- {update, httpc_handler, soft, soft_purge, soft_purge, []}
+ {restart_application, inets}
]
},
{"5.1.2",
[
{restart_application, inets}
]
- }
+ }
],
[
+ {"5.3.5",
+ [
+ {load_module, http_util, soft_purge, soft_purge, []},
+ {load_module, httpd_util, soft_purge, soft_purge, [http_util]},
+ {load_module, httpd_file, soft_purge, soft_purge, []},
+ {load_module, mod_responsecontrol, soft_purge, soft_purge, []},
+ {load_module, httpd_response, soft_purge, soft_purge, [mod_responsecontrol]}
+ ]
+ },
+ {"5.3.4",
+ [
+ {restart_application, inets}
+ ]
+ },
+ {"5.3.3",
+ [
+ {restart_application, inets}
+ ]
+ },
+ {"5.3.2",
+ [
+ {restart_application, inets}
+ ]
+ },
+ {"5.3.1",
+ [
+ {restart_application, inets}
+ ]
+ },
+ {"5.3",
+ [
+ {restart_application, inets}
+ ]
+ },
+ {"5.2",
+ [
+ {restart_application, inets}
+ ]
+ },
{"5.1.3",
[
- {load_module, httpd_response, soft_purge, soft_purge, []},
- {update, ftp, {advanced, downgrade_to_pre_5_12},
- soft_purge, soft_purge, []},
- {update, httpc_handler, soft, soft_purge, soft_purge, []}
+ {restart_application, inets}
]
},
{"5.1.2",
diff --git a/lib/inets/src/inets_app/inets.erl b/lib/inets/src/inets_app/inets.erl
index 7977a3dc2a..054468e445 100644
--- a/lib/inets/src/inets_app/inets.erl
+++ b/lib/inets/src/inets_app/inets.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2006-2009. All Rights Reserved.
+%% Copyright Ericsson AB 2006-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
@@ -57,7 +57,7 @@ start(Type) ->
%% Function: start(Service, ServiceConfig [, How]) -> {ok, Pid} |
%% {error, Reason}
%%
-%% Service = - ftpc | tftpd | httpc | httpd
+%% Service = - ftpc | tftpd | tftpc | tftp | httpc | httpd
%% ServiceConfig = ConfPropList | ConfFile
%% ConfPropList = [{Property, Value}] according to service
%% ConfFile = Path - when service is httpd
@@ -87,6 +87,7 @@ start(Service, ServiceConfig, How) ->
Module = service_module(Service),
start_service(Module, ServiceConfig, How).
+
%%--------------------------------------------------------------------
%% Function: stop() -> ok
%%
@@ -99,7 +100,7 @@ stop() ->
%%--------------------------------------------------------------------
%% Function: stop(Service, Pid) -> ok
%%
-%% Service - ftp | tftpd | http | httpd | stand_alone
+%% Service - ftpc | ftp | tftpd | tftpc | tftp | httpc | httpd | stand_alone
%%
%% Description: Stops a started service of the inets application or takes
%% down a stand alone "service" gracefully.
@@ -381,7 +382,7 @@ key1search(Key, Vals, Def) ->
%% Description: Returns a list of supported services
%%-------------------------------------------------------------------
service_names() ->
- [ftpc, tftpd, httpc, httpd].
+ [ftpc, tftp, httpc, httpd].
%%-----------------------------------------------------------------
@@ -521,9 +522,7 @@ change_pattern({Mod, Service, Pattern})
catch
exit:{Where, Reason} ->
{error, {Where, Reason}}
- end;
- _ ->
- exit({bad_pattern, Pattern})
+ end
end,
ok.
@@ -534,7 +533,7 @@ error_to_exit(Where, {error, Reason}) ->
%%-----------------------------------------------------------------
-%% report_event(Serverity, Label, Service, Content)
+%% report_event(Severity, Label, Service, Content)
%%
%% Parameters:
%% Severity -> 0 =< integer() =< 100
@@ -579,8 +578,8 @@ handle_trace({trace_ts, _Who, call,
{?MODULE, report_event,
[_Sev, "stop trace", stop_trace, [stop_trace]]},
Timestamp},
- {standard_io, _} = Fd) ->
- (catch io:format(Fd, "stop trace at ~s~n", [format_timestamp(Timestamp)])),
+ {_, standard_io} = Fd) ->
+ (catch io:format(standard_io, "stop trace at ~s~n", [format_timestamp(Timestamp)])),
Fd;
handle_trace({trace_ts, _Who, call,
{?MODULE, report_event,
@@ -726,8 +725,8 @@ call_service(Service, Call, Args) ->
service_module(tftpd) ->
tftp;
-service_module(httpc) ->
- http;
+service_module(tftpc) ->
+ tftp;
service_module(ftpc) ->
ftp;
service_module(Service) ->
diff --git a/lib/inets/src/tftp/Makefile b/lib/inets/src/tftp/Makefile
index 63f70f7943..b4339da1e2 100644
--- a/lib/inets/src/tftp/Makefile
+++ b/lib/inets/src/tftp/Makefile
@@ -1,19 +1,19 @@
#
# %CopyrightBegin%
-#
-# Copyright Ericsson AB 2005-2009. All Rights Reserved.
-#
+#
+# Copyright Ericsson AB 2005-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%
#
#
@@ -33,7 +33,8 @@ VSN = $(INETS_VSN)
# ----------------------------------------------------
# Release directory specification
# ----------------------------------------------------
-RELSYSDIR = $(RELEASE_PATH)/lib/inets-$(VSN)
+RELSYSDIR = $(RELEASE_PATH)/lib/$(APPLICATION)-$(VSN)
+
# ----------------------------------------------------
# Target Specs
@@ -53,10 +54,12 @@ ERL_FILES = $(MODULES:%=%.erl)
TARGET_FILES= $(MODULES:%=$(EBIN)/%.$(EMULATOR))
+
# ----------------------------------------------------
# INETS FLAGS
# ----------------------------------------------------
-INETS_FLAGS = -D'SERVER_SOFTWARE="inets/$(VSN)"' \
+INETS_FLAGS = -D'SERVER_SOFTWARE="$(APPLICATION)/$(VSN)"'
+
# ----------------------------------------------------
# FLAGS
@@ -64,6 +67,8 @@ INETS_FLAGS = -D'SERVER_SOFTWARE="inets/$(VSN)"' \
ERL_COMPILE_FLAGS += $(INETS_FLAGS) \
+'{parse_transform,sys_pre_attributes}' \
+'{attribute,insert,app_vsn,$(APP_VSN)}'
+
+
# ----------------------------------------------------
# Targets
# ----------------------------------------------------
@@ -90,6 +95,7 @@ release_spec: opt
release_docs_spec:
info:
+ @echo "APPLICATION = $(APPLICATION)"
@echo "INETS_DEBUG = $(INETS_DEBUG)"
@echo "INETS_FLAGS = $(INETS_FLAGS)"
@echo "ERL_COMPILE_FLAGS = $(ERL_COMPILE_FLAGS)"
diff --git a/lib/inets/test/Makefile b/lib/inets/test/Makefile
new file mode 100644
index 0000000000..668752da9e
--- /dev/null
+++ b/lib/inets/test/Makefile
@@ -0,0 +1,343 @@
+#
+# %CopyrightBegin%
+#
+# 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%
+#
+#
+# For an outline of how this all_SUITE_data stuff works, see the
+# make file ../../ssl/test/Makefile.
+#
+include $(ERL_TOP)/make/target.mk
+
+include $(ERL_TOP)/make/$(TARGET)/otp.mk
+
+# ----------------------------------------------------
+# Application version
+# ----------------------------------------------------
+include ../vsn.mk
+VSN = $(INETS_VSN)
+
+
+# ----------------------------------------------------
+# Release directory specification
+# ----------------------------------------------------
+RELSYSDIR = $(RELEASE_PATH)/lib/$(APPLICATION)-$(VSN)
+
+
+# ----------------------------------------------------
+# Target Specs
+# ----------------------------------------------------
+INCLUDES = -I. \
+ -I$(ERL_TOP)/lib/test_server/include/ \
+ -I$(ERL_TOP)/lib/inets/src/inets_app \
+ -I$(ERL_TOP)/lib/inets/src/http_lib \
+ -I$(ERL_TOP)/lib/inets/src/http_client \
+ -I$(ERL_TOP)/lib/inets/src/ftp
+
+CP = cp
+
+ifeq ($(TESTROOT_DIR),)
+TESTROOT_DIR = /ldisk/tests/$(USER)/inets
+endif
+
+ifeq ($(INETS_DATA_DIR),)
+INETS_DATA_DIR = $(TESTROOT_DIR)/data_dir
+endif
+
+ifeq ($(INETS_PRIV_DIR),)
+INETS_PRIV_DIR = $(TESTROOT_DIR)/priv_dir
+endif
+
+INETS_FLAGS = -Dinets_data_dir='"$(INETS_DATA_DIR)"' \
+ -Dinets_priv_dir='"$(INETS_PRIV_DIR)"'
+
+
+###
+### test suite debug flags
+###
+ifeq ($(FTP_DEBUG_CLIENT),)
+ FTP_DEBUG_CLIENT = y
+endif
+
+ifeq ($(FTP_DEBUG_CLIENT),)
+ FTP_FLAGS += -Dftp_debug_client
+endif
+
+ifeq ($(FTP_TRACE_CLIENT),)
+ FTP_DEBUG_CLIENT = y
+endif
+
+ifeq ($(FTP_TRACE_CLIENT),y)
+ FTP_FLAGS += -Dftp_trace_client
+endif
+
+ifneq ($(FTP_DEBUG),)
+ FTP_DEBUG = s
+endif
+
+ifeq ($(FTP_DEBUG),l)
+ FTP_FLAGS += -Dftp_log
+endif
+
+ifeq ($(FTP_DEBUG),d)
+ FTP_FLAGS += -Dftp_debug -Dftp_log
+endif
+
+ifeq ($(INETS_DEBUG),)
+ INETS_DEBUG = d
+endif
+
+ifeq ($(INETS_DEBUG),l)
+ INETS_FLAGS += -Dinets_log
+endif
+
+ifeq ($(INETS_DEBUG),d)
+ INETS_FLAGS += -Dinets_debug -Dinets_log
+endif
+
+
+###
+### HTTPD verbosity flags
+###
+
+ifneq ($(MANV),)
+ INETS_FLAGS += -Dhttpd_manager_verbosity=$(MANV)
+else
+ INETS_FLAGS += -Dhttpd_manager_verbosity=trace
+endif
+
+ifneq ($(REQV),)
+ INETS_FLAGS += -Dhttpd_request_handler_verbosity=$(REQV)
+else
+ INETS_FLAGS += -Dhttpd_request_handler_verbosity=trace
+endif
+
+ifneq ($(ACCV),)
+ INETS_FLAGS += -Dhttpd_acceptor_verbosity=$(ACCV)
+else
+ INETS_FLAGS += -Dhttpd_acceptor_verbosity=trace
+endif
+
+ifneq ($(AUTHV),)
+ INETS_FLAGS += -Dhttpd_auth_verbosity=$(AUTHV)
+else
+ INETS_FLAGS += -Dhttpd_auth_verbosity=log
+endif
+
+ifneq ($(SECV),)
+ INETS_FLAGS += -Dhttpd_security_verbosity=$(SECV)
+else
+ INETS_FLAGS += -Dhttpd_security_verbosity=log
+endif
+
+INETS_ROOT = ../../inets
+
+MODULES = \
+ inets_test_lib \
+ ftp_SUITE \
+ ftp_format_SUITE \
+ ftp_solaris8_sparc_test \
+ ftp_solaris9_sparc_test \
+ ftp_solaris10_sparc_test \
+ ftp_solaris10_x86_test \
+ ftp_linux_x86_test \
+ ftp_linux_ppc_test \
+ ftp_macosx_x86_test \
+ ftp_macosx_ppc_test \
+ ftp_openbsd_x86_test \
+ ftp_freebsd_x86_test \
+ ftp_netbsd_x86_test \
+ ftp_windows_xp_test \
+ ftp_windows_2003_server_test \
+ ftp_suite_lib \
+ ftp_ticket_test \
+ http_format_SUITE \
+ httpc_SUITE \
+ httpc_cookie_SUITE \
+ httpd_SUITE \
+ httpd_basic_SUITE \
+ httpd_mod \
+ httpd_block \
+ httpd_load \
+ httpd_time_test \
+ httpd_1_1 \
+ httpd_test_lib \
+ inets_sup_SUITE \
+ inets_SUITE \
+ inets_app_test \
+ inets_appup_test \
+ tftp_test_lib \
+ tftp_SUITE
+
+
+EBIN = .
+
+HRL_FILES = inets_test_lib.hrl \
+ inets_internal.hrl \
+ ftp_internal.hrl \
+ httpc_internal.hrl \
+ http_internal.hrl \
+ tftp_test_lib.hrl
+
+ERL_FILES = $(MODULES:%=%.erl)
+
+SOURCE = $(ERL_FILES) $(HRL_FILES)
+
+TARGET_FILES = $(MODULES:%=$(EBIN)/%.$(EMULATOR))
+
+INETS_SPECS = inets.spec inets.spec.vxworks
+INETS_FILES = inets.config $(INETS_SPECS)
+
+# SUB_SUITES = \
+# inets_sup_suite \
+# inets_httpd_suite \
+# inets_httpc_suite \
+# inets_ftp_suite \
+# inets_tftp_suite
+
+INETS_DATADIRS = inets_SUITE_data inets_sup_SUITE_data
+HTTPD_DATADIRS = httpd_test_data httpd_SUITE_data
+HTTPC_DATADIRS = httpc_SUITE_data
+FTP_DATADIRS = ftp_SUITE_data
+
+DATADIRS = $(INETS_DATADIRS) $(HTTPD_DATADIRS) $(HTTPC_DATADIRS) $(FTP_DATADIRS)
+
+EMAKEFILE = Emakefile
+MAKE_EMAKE = $(wildcard $(ERL_TOP)/make/make_emakefile)
+
+ifeq ($(MAKE_EMAKE),)
+BUILDTARGET = $(TARGET_FILES)
+RELTEST_FILES = $(INETS_SPECS) $(SOURCE)
+else
+BUILDTARGET = emakebuild
+RELTEST_FILES = $(EMAKEFILE) $(INETS_SPECS) $(SOURCE)
+endif
+
+
+# ----------------------------------------------------
+# Release directory specification
+# ----------------------------------------------------
+
+RELTESTSYSDIR = $(RELEASE_PATH)/inets_test
+RELTESTSYSALLDATADIR = $(RELTESTSYSDIR)/all_SUITE_data
+RELTESTSYSBINDIR = $(RELTESTSYSALLDATADIR)/bin
+
+
+# ----------------------------------------------------
+# FLAGS
+# The path to the test_server ebin dir is needed when
+# running the target "targets".
+# ----------------------------------------------------
+ERL_COMPILE_FLAGS += -pa ../../../internal_tools/test_server/ebin \
+ $(INCLUDES) $(FTP_FLAGS) $(INETS_FLAGS)
+
+# ----------------------------------------------------
+# Targets
+# erl -sname kalle -pa ../ebin
+# If you intend to run the test suite locally (private), then
+# there is some requirements:
+# 1) INETS_PRIV_DIR must be created
+# ----------------------------------------------------
+
+tests debug opt: $(BUILDTARGET)
+
+targets: $(TARGET_FILES)
+
+.PHONY: emakebuild
+
+emakebuild: $(EMAKEFILE)
+
+$(EMAKEFILE):
+ $(MAKE_EMAKE) $(ERL_COMPILE_FLAGS) -o$(EBIN) '*_SUITE_make' | grep -v Warning > $(EMAKEFILE)
+ $(MAKE_EMAKE) $(ERL_COMPILE_FLAGS) -o$(EBIN) $(MODULES) | grep -v Warning >> $(EMAKEFILE)
+
+clean:
+ rm -f $(EMAKEFILE)
+ rm -f $(TARGET_FILES)
+ rm -f core *~
+
+docs:
+
+
+# ----------------------------------------------------
+# Release Target
+# ----------------------------------------------------
+include $(ERL_TOP)/make/otp_release_targets.mk
+
+release_spec: opt
+ $(INSTALL_DIR) $(RELSYSDIR)/test
+ $(INSTALL_DATA) $(HRL_FILES) $(ERL_FILES) $(RELSYSDIR)/test
+ $(INSTALL_DATA) $(INETS_FILES) $(RELSYSDIR)/test
+ @for d in $(DATADIRS); do \
+ echo "installing data dir $$d"; \
+ echo $$d/TAR.exclude2 > $$d/TAR.exclude2; \
+ cat $$d/TAR.exclude >> $$d/TAR.exclude2; \
+ find $$d -name '*.contrib*' >> $$d/TAR.exclude2; \
+ find $$d -name '*.keep*' >> $$d/TAR.exclude2; \
+ find $$d -name '*.mkelem*' >> $$d/TAR.exclude2; \
+ find $$d -name '*~' >> $$d/TAR.exclude2; \
+ find $$d -name 'erl_crash.dump' >> $$d/TAR.exclude2; \
+ find $$d -name 'core' >> $$d/TAR.exclude2; \
+ find $$d -name '.cmake.state' >> $$d/TAR.exclude2; \
+ tar cfX - $$d/TAR.exclude2 $$d | (cd $(RELSYSDIR)/test; tar xf -); \
+ done
+
+release_tests_spec: opt
+ $(INSTALL_DIR) $(RELTESTSYSDIR)
+ $(INSTALL_DATA) $(RELTEST_FILES) $(RELTESTSYSDIR)
+ chmod -f -R u+w $(RELTESTSYSDIR)
+ tar chf - $(DATADIRS) | (cd $(RELTESTSYSDIR); tar xf -)
+ $(INSTALL_DIR) $(RELTESTSYSALLDATADIR)
+ $(INSTALL_DIR) $(RELTESTSYSBINDIR)
+ chmod -f -R +x $(RELTESTSYSBINDIR)
+ $(INSTALL_DIR) $(RELTESTSYSALLDATADIR)/win32/lib
+
+release_docs_spec:
+
+info:
+ @echo "MAKE_EMAKE = $(MAKE_EMAKE)"
+ @echo "EMAKEFILE = $(EMAKEFILE)"
+ @echo "BUILDTARGET = $(BUILDTARGET)"
+ @echo ""
+ @echo "MODULES = $(MODULES)"
+ @echo "ERL_FILES = $(ERL_FILES)"
+ @echo "SOURCE = $(SOURCE)"
+ @echo "TARGET_FILES = $(TARGET_FILES)"
+ @echo ""
+ @echo "INETS_SPECS = $(INETS_SPECS)"
+ @echo "INETS_FILES = $(INETS_FILES)"
+ @echo ""
+ @echo "RELEASE_PATH = $(RELEASE_PATH)"
+ @echo "RELSYSDIR = $(RELSYSDIR)"
+ @echo "RELTESTSYSDIR = $(RELTESTSYSDIR)"
+ @echo "RELTESTSYSALLDATADIR = $(RELTESTSYSALLDATADIR)"
+ @echo "RELTESTSYSBINDIR = $(RELTESTSYSBINDIR)"
+ @echo ""
+ @echo "DATADIRS = $(DATADIRS)"
+ @echo "REL_DATADIRS = $(REL_DATADIRS)"
+ @echo ""
+ @echo "INETS_DATA_DIR = $(INETS_DATA_DIR)"
+ @echo "INETS_PRIV_DIR = $(INETS_PRIV_DIR)"
+ @echo "INETS_ROOT = $(INETS_ROOT)"
+ @echo "INETS_FLAGS = $(INETS_FLAGS)"
+ @echo "FTP_FLAGS = $(FTP_FLAGS)"
+
+tftp:
+ erlc $(ERL_COMPILE_FLAGS) tftp_test_lib.erl tftp_SUITE.erl && erl -pa ../../inets/ebin -s tftp_SUITE t -s erlang halt
+
+tftp_work:
+ echo "tftp_test_lib:t([{tftp_SUITE, all}])."
+ erlc $(ERL_COMPILE_FLAGS) tftp_test_lib.erl tftp_SUITE.erl && erl -pa ../../inets/ebin
diff --git a/lib/inets/test/ftp_SUITE.erl b/lib/inets/test/ftp_SUITE.erl
new file mode 100644
index 0000000000..e7404f945b
--- /dev/null
+++ b/lib/inets/test/ftp_SUITE.erl
@@ -0,0 +1,143 @@
+%%
+%% %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%
+%%
+%%
+
+-module(ftp_SUITE).
+
+-include("test_server.hrl").
+-include("test_server_line.hrl").
+
+%% Test server specific exports
+-export([all/1]).
+% -export([init_per_testcase/2, end_per_testcase/2]).
+-export([init_per_suite/1, end_per_suite/1]).
+
+%% Test cases must be exported.
+-export([solaris8_test/1,
+ solaris9_test/1,
+ solaris10_test/1,
+ linux_x86_test/1,
+ linux_ppc_test/1,
+ macosx_x86_test/1,
+ macosx_ppc_test/1,
+ openbsd_test/1,
+ freebsd_test/1,
+ netbsd_test/1,
+ windows_xp_test/1,
+ windows_2003_server_test/1,
+ ticket_tests/1]).
+
+-define(FTP_USER, "anonymous").
+-define(FTP_PASS, passwd()).
+-define(FTP_PORT, 21).
+
+-define(BAD_HOST, "badhostname").
+-define(BAD_USER, "baduser").
+-define(BAD_DIR, "baddirectory").
+
+-ifdef(ftp_debug_client).
+-define(ftp_open(Host, Flags), do_ftp_open(Host, [debug] ++ Flags)).
+-else.
+-ifdef(ftp_trace_client).
+-define(ftp_open(Host, Flags), do_ftp_open(Host, [trace] ++ Flags)).
+-else.
+-define(ftp_open(Host, Flags), do_ftp_open(Host, [verbose] ++ Flags)).
+-endif.
+-endif.
+
+
+%%--------------------------------------------------------------------
+%% all(Arg) -> [Doc] | [Case] | {skip, Comment}
+%% Arg - doc | suite
+%% Doc - string()
+%% Case - atom()
+%% Name of a test case function.
+%% Comment - string()
+%% Description: Returns documentation/test cases in this test suite
+%% or a skip tuple if the platform is not supported.
+%%--------------------------------------------------------------------
+all(doc) ->
+ ["Test the ftp client in the inets application."];
+all(suite) ->
+ [
+ solaris8_test,
+ solaris9_test,
+ solaris10_test,
+ linux_x86_test,
+ linux_ppc_test,
+ macosx_x86_test,
+ macosx_ppc_test,
+ openbsd_test,
+ freebsd_test,
+ netbsd_test,
+ windows_xp_test,
+ windows_2003_server_test,
+ ticket_tests
+ ].
+
+solaris8_test(suite) ->
+ [{ftp_solaris8_sparc_test,all}].
+solaris9_test(suite) ->
+ [{ftp_solaris9_sparc_test,all}].
+solaris10_test(suite) ->
+ [{ftp_solaris10_sparc_test,all}, {ftp_solaris10_x86_test,all}].
+linux_x86_test(suite) ->
+ [{ftp_linux_x86_test,all}].
+linux_ppc_test(suite) ->
+ [{ftp_linux_ppc_test,all}].
+macosx_x86_test(suite) ->
+ [{ftp_macosx_x86_test,all}].
+macosx_ppc_test(suite) ->
+ [{ftp_macosx_ppc_test,all}].
+openbsd_test(suite) ->
+ [{ftp_openbsd_x86_test,all}].
+freebsd_test(suite) ->
+ [{ftp_freebsd_x86_test,all}].
+netbsd_test(suite) ->
+ [{ftp_netbsd_x86_test,all}].
+windows_xp_test(suite) ->
+ [{ftp_windows_xp_test,all}].
+windows_2003_server_test(suite) ->
+ [{ftp_windows_2003_server_test,all}].
+
+ticket_tests(suite) ->
+ [{ftp_ticket_test, all}].
+
+%%--------------------------------------------------------------------
+%% Function: init_per_suite(Config) -> Config
+%% Config - [tuple()]
+%% A list of key/value pairs, holding the test case configuration.
+%% Description: Initiation 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) ->
+ inets: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) ->
+ inets:stop(),
+ ok.
diff --git a/lib/inets/test/ftp_SUITE_data/ftpd_hosts.skel b/lib/inets/test/ftp_SUITE_data/ftpd_hosts.skel
new file mode 100644
index 0000000000..75096ce687
--- /dev/null
+++ b/lib/inets/test/ftp_SUITE_data/ftpd_hosts.skel
@@ -0,0 +1,18 @@
+%% Add a host name in the appropriate list
+%% Each "platform" contains a list of hostnames (a string) that can
+%% be used for testing the ftp client.
+%% The definition below are an example!!
+[{solaris8_sparc, ["solaris8_sparc_dummy1", "solaris8_sparc_dummy2"]},
+ {solaris9_sparc, ["solaris9_sparc_dummy1"]},
+ {solaris10_sparc, ["solaris10_sparc_dummy1"]},
+ {solaris10_x86, ["solaris10_x86_dummy1", "solaris10_x86_dummy2"]},
+ {linux_x86, ["linux_x86_dummy1", "linux_x86_dummy2"]},
+ {linux_ppc, ["linux_ppc_dummy1"]},
+ {macosx_ppc, ["macosx_ppc_dummy1"]},
+ {macosx_x86, ["macosx_x86_dummy1", "macosx_x86_dummy2"]},
+ {openbsd_x86, []},
+ {freebsd_x86, ["freebsd_x86_dummy1"]},
+ {netbsd_x86, []},
+ {windows_xp, []},
+ {windows_2003_server, ["win2003_dummy1"]},
+ {ticket_test, ["solaris8_x86_dummy1", "linux_x86_dummy1"]}].
diff --git a/lib/inets/test/ftp_format_SUITE.erl b/lib/inets/test/ftp_format_SUITE.erl
new file mode 100644
index 0000000000..9ca6575b2d
--- /dev/null
+++ b/lib/inets/test/ftp_format_SUITE.erl
@@ -0,0 +1,341 @@
+%%
+%% %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%
+%%
+%%
+-module(ftp_format_SUITE).
+-author('[email protected]').
+
+-include("test_server.hrl").
+-include("test_server_line.hrl").
+-include("ftp_internal.hrl").
+
+%% Test server specific exports
+-export([all/1, init_per_testcase/2, end_per_testcase/2]).
+
+%% Test cases must be exported.
+-export([ftp_response/1, ftp_150/1,
+ ftp_200/1, ftp_220/1, ftp_226/1, ftp_257/1, ftp_331/1, ftp_425/1,
+ ftp_other_status_codes/1, ftp_multiple_lines/1,
+ ftp_multipel_ctrl_messages/1, format_error/1]).
+
+all(doc) ->
+ ["Test library functions for the ftp client."];
+all(suite) ->
+ [ftp_response, format_error].
+
+init_per_testcase(_, Config) ->
+ Dog = test_server:timetrap(?t:minutes(1)),
+ NewConfig = lists:keydelete(watchdog, 1, Config),
+ [{watchdog, Dog} | NewConfig].
+
+end_per_testcase(_, Config) ->
+ Dog = ?config(watchdog, Config),
+ test_server:timetrap_cancel(Dog),
+ ok.
+
+%%-------------------------------------------------------------------------
+%% Test cases starts here.
+%%-------------------------------------------------------------------------
+ftp_response(doc) ->
+ ["Test ftp_response:parse_lines/3 and ftp_response:interpret/1."
+ " This test case will simulate that the "
+ "message will be recived a little at the time on a socket and the "
+ "package may be broken up into smaller parts at arbitrary point."];
+ftp_response(suite) ->
+ [ftp_150, ftp_200, ftp_220, ftp_226, ftp_257, ftp_331, ftp_425,
+ ftp_other_status_codes, ftp_multiple_lines, ftp_multipel_ctrl_messages].
+
+ftp_150(doc) ->
+ ["Especially check that respons can be devided in a random place."];
+ftp_150(suite) ->
+ [];
+ftp_150(Config) when is_list(Config) ->
+ FtpResponse = ["150 ASCII data conn", "ection for /bin/ls ",
+ "(134.138.177", ".89,50434) (0 bytes).\r\n"],
+
+ "150 ASCII data connection for /bin/ls "
+ "(134.138.177.89,50434) (0 bytes).\r\n" = Msg =
+ parse(ftp_response, parse_lines, [[], start], FtpResponse),
+ {pos_prel, _} = ftp_response:interpret(Msg),
+ ok.
+
+ftp_200(doc) ->
+ ["Especially check that respons can be devided after the first status "
+ "code character and in the end delimiter."];
+ftp_200(suite) ->
+ [];
+ftp_200(Config) when is_list(Config) ->
+ FtpResponse = ["2", "00 PORT command successful.", [?CR], [?LF]],
+
+ "200 PORT command successful.\r\n" = Msg =
+ parse(ftp_response, parse_lines, [[], start], FtpResponse),
+ {pos_compl, _} = ftp_response:interpret(Msg),
+ ok.
+
+ftp_220(doc) ->
+ ["Especially check that respons can be devided after the "
+ "first with space "];
+ftp_220(suite) ->
+ [];
+ftp_220(Config) when is_list(Config) ->
+ FtpResponse = ["220 ","fingon FTP server (SunOS 5.8) ready.\r\n"],
+
+ "220 fingon FTP server (SunOS 5.8) ready.\r\n" = Msg =
+ parse(ftp_response, parse_lines, [[], start], FtpResponse),
+ {pos_compl, _} = ftp_response:interpret(Msg),
+ ok.
+
+ftp_226(doc) ->
+ ["Especially check that respons can be devided after second status code"
+ " character and in the end delimiter."];
+ftp_226(suite) ->
+ [];
+ftp_226(Config) when is_list(Config) ->
+ FtpResponse = ["22" "6 Transfer complete.\r", [?LF]],
+
+ "226 Transfer complete.\r\n" = Msg =
+ parse(ftp_response, parse_lines, [[], start], FtpResponse),
+ {pos_compl, _} = ftp_response:interpret(Msg),
+ ok.
+
+ftp_257(doc) ->
+ ["Especially check that quoted chars do not cause a problem."];
+ftp_257(suite) ->
+ [];
+ftp_257(Config) when is_list(Config) ->
+ FtpResponse = ["257 \"/\" is current directory.\r\n"],
+
+ "257 \"/\" is current directory.\r\n" = Msg =
+ parse(ftp_response, parse_lines, [[], start], FtpResponse),
+ {pos_compl, _} = ftp_response:interpret(Msg),
+ ok.
+
+ftp_331(doc) ->
+ ["Especially check that respons can be devided after the third status "
+ " status code character."];
+ftp_331(suite) ->
+ [];
+ftp_331(Config) when is_list(Config) ->
+ %% Brake before white space after code
+ FtpResponse =
+ ["331"," Guest login ok, send ient as password.\r\n"],
+
+ "331 Guest login ok, send ient as password.\r\n" = Msg =
+ parse(ftp_response, parse_lines, [[], start], FtpResponse),
+ {pos_interm, _} = ftp_response:interpret(Msg),
+ ok.
+
+ftp_425(doc) ->
+ ["Especially check a message that was received in only one part."];
+ftp_425(suite) ->
+ [];
+ftp_425(Config) when is_list(Config) ->
+ FtpResponse =
+ ["425 Can't build data connection: Connection refused.\r\n"],
+
+ "425 Can't build data connection: Connection refused.\r\n"
+ = Msg = parse(ftp_response, parse_lines, [[], start], FtpResponse),
+ {trans_neg_compl, _} = ftp_response:interpret(Msg),
+ ok.
+
+ftp_multiple_lines(doc) ->
+ ["Especially check multiple lines devided in significant places"];
+ftp_multiple_lines(suite) ->
+ [];
+ftp_multiple_lines(Config) when is_list(Config) ->
+ FtpResponse = ["21", "4","-The",
+ " following commands are recognized:\r\n"
+ " USER EPRT STRU MAIL* ALLO CWD",
+ " STAT* XRMD \r\n"
+ " PASS LPRT MODE MSND* "
+ " REST* XCWD HELP PWD ", [?CRLF],
+ " ACCT* EPSV RETR MSOM* RNFR LIST "
+ " NOOP XPWD \r\n",
+ " REIN* LPSV STOR MSAM* RNTO NLST "
+ " MKD CDUP \r\n"
+ " QUIT PASV APPE MRSQ* ABOR SITE* "
+ " XMKD XCUP \r\n"
+ " PORT TYPE MLFL* MRCP* DELE SYST "
+ " RMD STOU \r\n"
+ "214 (*'s => unimplemented)", [?CR], [?LF]],
+
+
+ FtpResponse1 = ["214-", "The",
+ " following commands are recognized:\r\n"
+ " USER EPRT STRU MAIL* ALLO CWD",
+ " STAT* XRMD \r\n"
+ " PASS LPRT MODE MSND* "
+ " REST* XCWD HELP PWD ", [?CRLF],
+ " ACCT* EPSV RETR MSOM* RNFR LIST "
+ " NOOP XPWD \r\n",
+ " REIN* LPSV STOR MSAM* RNTO NLST "
+ " MKD CDUP \r\n"
+ " QUIT PASV APPE MRSQ* ABOR SITE* "
+ " XMKD XCUP \r\n"
+ " PORT TYPE MLFL* MRCP* DELE SYST "
+ " RMD STOU \r\n"
+ "2", "14 (*'s => unimplemented)", [?CR], [?LF]],
+
+ FtpResponse2 = ["214-", "The",
+ " following commands are recognized:\r\n"
+ " USER EPRT STRU MAIL* ALLO CWD",
+ " STAT* XRMD \r\n"
+ " PASS LPRT MODE MSND* "
+ " REST* XCWD HELP PWD ", [?CRLF],
+ " ACCT* EPSV RETR MSOM* RNFR LIST "
+ " NOOP XPWD \r\n",
+ " REIN* LPSV STOR MSAM* RNTO NLST "
+ " MKD CDUP \r\n"
+ " QUIT PASV APPE MRSQ* ABOR SITE* "
+ " XMKD XCUP \r\n"
+ " PORT TYPE MLFL* MRCP* DELE SYST "
+ " RMD STOU \r\n"
+ "21", "4"," (*'s => unimplemented)", [?CR], [?LF]],
+
+ MultiLineResultStr =
+ "214-The following commands are recognized:\r\n"
+ " USER EPRT STRU MAIL* ALLO CWD STAT* "
+ "XRMD \r\n"
+ " PASS LPRT MODE MSND* REST* XCWD HELP "
+ "PWD \r\n"
+ " ACCT* EPSV RETR MSOM* RNFR LIST NOOP "
+ "XPWD \r\n"
+ " REIN* LPSV STOR MSAM* RNTO NLST MKD "
+ "CDUP \r\n"
+ " QUIT PASV APPE MRSQ* ABOR SITE* XMKD "
+ "XCUP \r\n"
+ " PORT TYPE MLFL* MRCP* DELE SYST RMD "
+ "STOU \r\n"
+ "214 (*'s => unimplemented)\r\n",
+
+ MultiLineResultStr =
+ parse(ftp_response, parse_lines, [[], start], FtpResponse),
+ {pos_compl, _} = ftp_response:interpret(MultiLineResultStr),
+
+ MultiLineResultStr = parse(ftp_response, parse_lines, [[], start],
+ FtpResponse1),
+
+ MultiLineResultStr = parse(ftp_response, parse_lines, [[], start],
+ FtpResponse2),
+ ok.
+
+ftp_other_status_codes(doc) ->
+ ["Check that other valid status codes, than the ones above, are handled"
+ "by ftp_response:interpret/1. Note there are som ftp status codes"
+ "that will not be received with the current ftp instruction support,"
+ "they are not included here."];
+ftp_other_status_codes(suite) ->
+ [];
+ftp_other_status_codes(Config) when is_list(Config) ->
+
+ %% 1XX
+ {pos_prel, _ } = ftp_response:interpret("120 Foobar\r\n"),
+
+ %% 2XX
+ {pos_compl, _ } = ftp_response:interpret("202 Foobar\r\n"),
+ {pos_compl, _ } = ftp_response:interpret("221 Foobar\r\n"),
+ {pos_compl, _ } = ftp_response:interpret("227 Foobar\r\n"),
+ {pos_compl, _ } = ftp_response:interpret("230 Foobar\r\n"),
+ {pos_compl, _ } = ftp_response:interpret("250 Foobar\r\n"),
+
+ %% 3XX
+ {pos_interm_acct, _ } = ftp_response:interpret("332 Foobar\r\n"),
+ {pos_interm, _ } = ftp_response:interpret("350 Foobar\r\n"),
+
+ %% 4XX
+ {trans_neg_compl, _ } = ftp_response:interpret("421 Foobar\r\n"),
+ {trans_neg_compl, _ } = ftp_response:interpret("426 Foobar\r\n"),
+ {trans_neg_compl, _ } = ftp_response:interpret("450 Foobar\r\n"),
+ {trans_neg_compl, _ } = ftp_response:interpret("451 Foobar\r\n"),
+ {etnospc, _ } = ftp_response:interpret("452 Foobar\r\n"),
+
+ %% 5XX
+ {perm_neg_compl, _ } = ftp_response:interpret("500 Foobar\r\n"),
+ {perm_neg_compl, _ } = ftp_response:interpret("501 Foobar\r\n"),
+ {perm_neg_compl, _ } = ftp_response:interpret("503 Foobar\r\n"),
+ {perm_neg_compl, _ } = ftp_response:interpret("504 Foobar\r\n"),
+ {perm_neg_compl, _ } = ftp_response:interpret("530 Foobar\r\n"),
+ {perm_neg_compl, _ } = ftp_response:interpret("532 Foobar\r\n"),
+ {epath, _ } = ftp_response:interpret("550 Foobar\r\n"),
+ {epnospc, _ } = ftp_response:interpret("552 Foobar\r\n"),
+ {efnamena, _ } = ftp_response:interpret("553 Foobar\r\n"),
+ ok.
+
+ftp_multipel_ctrl_messages(doc) ->
+ ["The ftp server may send more than one control message as a reply,"
+ "check that they are handled one at the time."];
+ftp_multipel_ctrl_messages(suite) ->
+ [];
+ftp_multipel_ctrl_messages(Config) when is_list(Config) ->
+ FtpResponse = ["200 PORT command successful.\r\n200 Foobar\r\n"],
+
+ {"200 PORT command successful.\r\n" = Msg, NextMsg} =
+ parse(ftp_response, parse_lines, [[], start], FtpResponse),
+ {pos_compl, _} = ftp_response:interpret(Msg),
+ NewMsg = parse(ftp_response, parse_lines, [[], start], NextMsg),
+ {pos_compl, _} = ftp_response:interpret(NewMsg),
+ ok.
+
+
+%%-------------------------------------------------------------------------
+format_error(doc) ->
+ [""];
+format_error(suite) ->
+ [];
+format_error(Config) when is_list(Config) ->
+ "Synchronisation error during chunk sending." =
+ ftp:formaterror(echunk),
+ "Session has been closed." = ftp:formaterror(eclosed),
+ "Connection to remote server prematurely closed." =
+ ftp:formaterror(econn),
+ "File or directory already exists." = ftp:formaterror(eexists),
+ "Host not found, FTP server not found, or connection rejected." =
+ ftp:formaterror(ehost),
+ "User not logged in." = ftp:formaterror(elogin),
+ "Term is not a binary." = ftp:formaterror(enotbinary),
+ "No such file or directory, already exists, or permission denied."
+ = ftp:formaterror(epath),
+ "No such type." = ftp:formaterror(etype),
+ "User name or password not valid." = ftp:formaterror(euser),
+ "Insufficient storage space in system." = ftp:formaterror(etnospc),
+ "Exceeded storage allocation (for current directory or dataset)."
+ = ftp:formaterror(epnospc),
+ "File name not allowed." = ftp:formaterror(efnamena),
+ "Unknown error: foobar" = ftp:formaterror({error, foobar}).
+
+%%--------------------------------------------------------------------
+%%% Internal functions
+%%--------------------------------------------------------------------
+parse(Module, Function, Args, Bin) when is_binary(Bin) ->
+ parse(Module, Function, Args, [binary_to_list(Bin)]);
+
+parse(Module, Function, [AccLines, StatusCode], [Data | Rest]) ->
+ case Module:Function(list_to_binary(Data), AccLines, StatusCode) of
+ {ok, Result, <<>>} ->
+ Result;
+ {ok, Result, Next} ->
+ {Result, Next};
+ {continue, {NewData, NewAccLines, NewStatusCode}} ->
+ case Rest of
+ [] ->
+ test_server:fail({wrong_input, Data, Rest});
+ [_ | _] ->
+ parse(Module, Function, [NewAccLines, NewStatusCode],
+ [binary_to_list(NewData) ++ hd(Rest) | tl(Rest)])
+ end
+ end.
diff --git a/lib/inets/test/ftp_freebsd_x86_test.erl b/lib/inets/test/ftp_freebsd_x86_test.erl
new file mode 100644
index 0000000000..457e18ffbe
--- /dev/null
+++ b/lib/inets/test/ftp_freebsd_x86_test.erl
@@ -0,0 +1,153 @@
+%%
+%% %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%
+%%
+%%
+
+-module(ftp_freebsd_x86_test).
+
+-compile(export_all).
+
+-include("test_server.hrl").
+
+-define(LIB_MOD,ftp_suite_lib).
+-define(CASE_WRAPPER(_A_,_B_,_C_),?LIB_MOD:wrapper(_A_,_B_,_C_)).
+-define(PLATFORM,"Freebsd x86 ").
+
+%% Test server callback functions
+%%--------------------------------------------------------------------
+%% Function: init_per_suite(Config) -> Config
+%% Config - [tuple()]
+%% A list of key/value pairs, holding the test case configuration.
+%% Description: Initiation 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) ->
+ {File, NewFile} = ?LIB_MOD:test_filenames(),
+ NewConfig = [{file, File}, {new_file, NewFile} | Config],
+ ?LIB_MOD:ftpd_init(freebsd_x86, NewConfig).
+
+%%--------------------------------------------------------------------
+%% 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) ->
+ ?LIB_MOD:ftpd_fin(Config).
+
+%%--------------------------------------------------------------------
+%% 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: Initiation 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: Initiation before each test case
+%%--------------------------------------------------------------------
+init_per_testcase(Case, Config) ->
+ ftp_suite_lib:init_per_testcase(Case, 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(Case, Config) ->
+ ftp_suite_lib:end_per_testcase(Case, Config).
+
+%%--------------------------------------------------------------------
+%% 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 ftp client"];
+
+all(suite) ->
+ [open, open_port, passive, active, api_missuse,
+ not_owner, progress_report].
+
+%% Test cases starts here.
+%%--------------------------------------------------------------------
+
+open(X) -> ?CASE_WRAPPER(?PLATFORM,X,fun ?LIB_MOD:open/1).
+open_port(X) -> ?CASE_WRAPPER(?PLATFORM,X,fun ?LIB_MOD:open_port/1).
+passive(X) -> ?CASE_WRAPPER(?PLATFORM,X,fun ?LIB_MOD:passive/1).
+active(X) -> ?CASE_WRAPPER(?PLATFORM,X,fun ?LIB_MOD:active/1).
+api_missuse(X) -> ?CASE_WRAPPER(?PLATFORM,X,fun ?LIB_MOD:api_missuse/1).
+not_owner(X) -> ?CASE_WRAPPER(?PLATFORM,X,fun ?LIB_MOD:not_owner/1).
+progress_report(X) -> ?CASE_WRAPPER(?PLATFORM,X,fun ?LIB_MOD:progress_report/1).
+
+passive_user(X) -> ?LIB_MOD:passive_user(X).
+passive_pwd(X) -> ?LIB_MOD:passive_pwd(X).
+passive_cd(X) -> ?LIB_MOD:passive_cd(X).
+passive_lcd(X) -> ?LIB_MOD:passive_lcd(X).
+passive_ls(X) -> ?LIB_MOD:passive_ls(X).
+passive_nlist(X) -> ?LIB_MOD:passive_nlist(X).
+passive_rename(X) -> ?LIB_MOD:passive_rename(X).
+passive_delete(X) -> ?LIB_MOD:passive_delete(X).
+passive_mkdir(X) -> ?LIB_MOD:passive_mkdir(X).
+passive_send(X) -> ?LIB_MOD:passive_send(X).
+passive_send_bin(X) -> ?LIB_MOD:passive_send_bin(X).
+passive_send_chunk(X) -> ?LIB_MOD:passive_send_chunk(X).
+passive_append(X) -> ?LIB_MOD:passive_append(X).
+passive_append_bin(X) -> ?LIB_MOD:passive_append_bin(X).
+passive_append_chunk(X) -> ?LIB_MOD:passive_append_chunk(X).
+passive_recv(X) -> ?LIB_MOD:passive_recv(X).
+passive_recv_bin(X) -> ?LIB_MOD:passive_recv_bin(X).
+passive_recv_chunk(X) -> ?LIB_MOD:passive_recv_chunk(X).
+passive_type(X) -> ?LIB_MOD:passive_type(X).
+passive_quote(X) -> ?LIB_MOD:passive_quote(X).
+passive_ip_v6_disabled(X) -> ?LIB_MOD:passive_ip_v6_disabled(X).
+active_user(X) -> ?LIB_MOD:active_user(X).
+active_pwd(X) -> ?LIB_MOD:active_pwd(X).
+active_cd(X) -> ?LIB_MOD:active_cd(X).
+active_lcd(X) -> ?LIB_MOD:active_lcd(X).
+active_ls(X) -> ?LIB_MOD:active_ls(X).
+active_nlist(X) -> ?LIB_MOD:active_nlist(X).
+active_rename(X) -> ?LIB_MOD:active_rename(X).
+active_delete(X) -> ?LIB_MOD:active_delete(X).
+active_mkdir(X) -> ?LIB_MOD:active_mkdir(X).
+active_send(X) -> ?LIB_MOD:active_send(X).
+active_send_bin(X) -> ?LIB_MOD:active_send_bin(X).
+active_send_chunk(X) -> ?LIB_MOD:active_send_chunk(X).
+active_append(X) -> ?LIB_MOD:active_append(X).
+active_append_bin(X) -> ?LIB_MOD:active_append_bin(X).
+active_append_chunk(X) -> ?LIB_MOD:active_append_chunk(X).
+active_recv(X) -> ?LIB_MOD:active_recv(X).
+active_recv_bin(X) -> ?LIB_MOD:active_recv_bin(X).
+active_recv_chunk(X) -> ?LIB_MOD:active_recv_chunk(X).
+active_type(X) -> ?LIB_MOD:active_type(X).
+active_quote(X) -> ?LIB_MOD:active_quote(X).
+active_ip_v6_disabled(X) -> ?LIB_MOD:active_ip_v6_disabled(X).
+progress_report_send(X) -> ?LIB_MOD:progress_report_send(X).
+progress_report_recv(X) -> ?LIB_MOD:progress_report_recv(X).
+
+fin(Config) ->
+ ?LIB_MOD:ftpd_fin(Config).
diff --git a/lib/inets/test/ftp_internal.hrl b/lib/inets/test/ftp_internal.hrl
new file mode 120000
index 0000000000..af57081f14
--- /dev/null
+++ b/lib/inets/test/ftp_internal.hrl
@@ -0,0 +1 @@
+../src/ftp/ftp_internal.hrl \ No newline at end of file
diff --git a/lib/inets/test/ftp_linux_ppc_test.erl b/lib/inets/test/ftp_linux_ppc_test.erl
new file mode 100644
index 0000000000..ad38137678
--- /dev/null
+++ b/lib/inets/test/ftp_linux_ppc_test.erl
@@ -0,0 +1,151 @@
+%%
+%% %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%
+%%
+%%
+
+-module(ftp_linux_ppc_test).
+
+%% Note: This directive should only be used in test suites.
+-compile(export_all).
+
+-include("test_server.hrl").
+
+-define(LIB_MOD,ftp_suite_lib).
+-define(CASE_WRAPPER(_A_,_B_,_C_),?LIB_MOD:wrapper(_A_,_B_,_C_)).
+-define(PLATFORM,"Linux ppc ").
+
+%% Test server callback functions
+%%--------------------------------------------------------------------
+%% Function: init_per_suite(Config) -> Config
+%% Config - [tuple()]
+%% A list of key/value pairs, holding the test case configuration.
+%% Description: Initiation 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) ->
+ {File, NewFile} = ?LIB_MOD:test_filenames(),
+ NewConfig = [{file, File}, {new_file, NewFile} | Config],
+ ?LIB_MOD:ftpd_init(linux_ppc, NewConfig).
+
+%%--------------------------------------------------------------------
+%% 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) ->
+ ?LIB_MOD:ftpd_fin(Config).
+
+%%--------------------------------------------------------------------
+%% 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: Initiation 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: Initiation before each test case
+%%--------------------------------------------------------------------
+init_per_testcase(Case, Config) ->
+ ftp_suite_lib:init_per_testcase(Case, 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(Case, Config) ->
+ ftp_suite_lib:end_per_testcase(Case, Config).
+
+%%--------------------------------------------------------------------
+%% 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 ftp client"];
+
+all(suite) ->
+ [open, open_port, passive, active, api_missuse,
+ not_owner, progress_report].
+
+%% Test cases starts here.
+%%--------------------------------------------------------------------
+
+open(X) -> ?CASE_WRAPPER(?PLATFORM,X,fun ?LIB_MOD:open/1).
+open_port(X) -> ?CASE_WRAPPER(?PLATFORM,X,fun ?LIB_MOD:open_port/1).
+passive(X) -> ?CASE_WRAPPER(?PLATFORM,X,fun ?LIB_MOD:passive/1).
+active(X) -> ?CASE_WRAPPER(?PLATFORM,X,fun ?LIB_MOD:active/1).
+api_missuse(X) -> ?CASE_WRAPPER(?PLATFORM,X,fun ?LIB_MOD:api_missuse/1).
+not_owner(X) -> ?CASE_WRAPPER(?PLATFORM,X,fun ?LIB_MOD:not_owner/1).
+progress_report(X) -> ?CASE_WRAPPER(?PLATFORM,X,fun ?LIB_MOD:progress_report/1).
+
+passive_user(X) -> ?LIB_MOD:passive_user(X).
+passive_pwd(X) -> ?LIB_MOD:passive_pwd(X).
+passive_cd(X) -> ?LIB_MOD:passive_cd(X).
+passive_lcd(X) -> ?LIB_MOD:passive_lcd(X).
+passive_ls(X) -> ?LIB_MOD:passive_ls(X).
+passive_nlist(X) -> ?LIB_MOD:passive_nlist(X).
+passive_rename(X) -> ?LIB_MOD:passive_rename(X).
+passive_delete(X) -> ?LIB_MOD:passive_delete(X).
+passive_mkdir(X) -> ?LIB_MOD:passive_mkdir(X).
+passive_send(X) -> ?LIB_MOD:passive_send(X).
+passive_send_bin(X) -> ?LIB_MOD:passive_send_bin(X).
+passive_send_chunk(X) -> ?LIB_MOD:passive_send_chunk(X).
+passive_append(X) -> ?LIB_MOD:passive_append(X).
+passive_append_bin(X) -> ?LIB_MOD:passive_append_bin(X).
+passive_append_chunk(X) -> ?LIB_MOD:passive_append_chunk(X).
+passive_recv(X) -> ?LIB_MOD:passive_recv(X).
+passive_recv_bin(X) -> ?LIB_MOD:passive_recv_bin(X).
+passive_recv_chunk(X) -> ?LIB_MOD:passive_recv_chunk(X).
+passive_type(X) -> ?LIB_MOD:passive_type(X).
+passive_quote(X) -> ?LIB_MOD:passive_quote(X).
+passive_ip_v6_disabled(X) -> ?LIB_MOD:passive_ip_v6_disabled(X).
+active_user(X) -> ?LIB_MOD:active_user(X).
+active_pwd(X) -> ?LIB_MOD:active_pwd(X).
+active_cd(X) -> ?LIB_MOD:active_cd(X).
+active_lcd(X) -> ?LIB_MOD:active_lcd(X).
+active_ls(X) -> ?LIB_MOD:active_ls(X).
+active_nlist(X) -> ?LIB_MOD:active_nlist(X).
+active_rename(X) -> ?LIB_MOD:active_rename(X).
+active_delete(X) -> ?LIB_MOD:active_delete(X).
+active_mkdir(X) -> ?LIB_MOD:active_mkdir(X).
+active_send(X) -> ?LIB_MOD:active_send(X).
+active_send_bin(X) -> ?LIB_MOD:active_send_bin(X).
+active_send_chunk(X) -> ?LIB_MOD:active_send_chunk(X).
+active_append(X) -> ?LIB_MOD:active_append(X).
+active_append_bin(X) -> ?LIB_MOD:active_append_bin(X).
+active_append_chunk(X) -> ?LIB_MOD:active_append_chunk(X).
+active_recv(X) -> ?LIB_MOD:active_recv(X).
+active_recv_bin(X) -> ?LIB_MOD:active_recv_bin(X).
+active_recv_chunk(X) -> ?LIB_MOD:active_recv_chunk(X).
+active_type(X) -> ?LIB_MOD:active_type(X).
+active_quote(X) -> ?LIB_MOD:active_quote(X).
+active_ip_v6_disabled(X) -> ?LIB_MOD:active_ip_v6_disabled(X).
+progress_report_send(X) -> ?LIB_MOD:progress_report_send(X).
+progress_report_recv(X) -> ?LIB_MOD:progress_report_recv(X).
diff --git a/lib/inets/test/ftp_linux_x86_test.erl b/lib/inets/test/ftp_linux_x86_test.erl
new file mode 100644
index 0000000000..b9c88d121a
--- /dev/null
+++ b/lib/inets/test/ftp_linux_x86_test.erl
@@ -0,0 +1,160 @@
+%%
+%% %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%
+%%
+%%
+
+-module(ftp_linux_x86_test).
+
+-compile(export_all).
+
+-include("test_server.hrl").
+
+-define(LIB_MOD,ftp_suite_lib).
+-define(CASE_WRAPPER(_A_,_B_,_C_),?LIB_MOD:wrapper(_A_,_B_,_C_)).
+-define(PLATFORM,"Linux x86 ").
+
+%% Test server callback functions
+%%--------------------------------------------------------------------
+%% Function: init_per_suite(Config) -> Config
+%% Config - [tuple()]
+%% A list of key/value pairs, holding the test case configuration.
+%% Description: Initiation 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) ->
+ {File, NewFile} = ?LIB_MOD:test_filenames(),
+ NewConfig = [{file, File}, {new_file, NewFile} | Config],
+ ?LIB_MOD:ftpd_init(linux_x86, NewConfig).
+
+%%--------------------------------------------------------------------
+%% 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) ->
+ ?LIB_MOD:ftpd_fin(Config).
+
+%%--------------------------------------------------------------------
+%% 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: Initiation 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: Initiation before each test case
+%%--------------------------------------------------------------------
+init_per_testcase(Case, Config) ->
+ ftp_suite_lib:init_per_testcase(Case, 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(Case, Config) ->
+ ftp_suite_lib:end_per_testcase(Case, Config).
+
+%%--------------------------------------------------------------------
+%% 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 ftp client"];
+
+all(suite) ->
+ [
+ open,
+ open_port,
+ passive,
+ active,
+ api_missuse,
+ not_owner,
+ progress_report
+ ].
+
+%% Test cases starts here.
+%%--------------------------------------------------------------------
+
+open(X) -> ?CASE_WRAPPER(?PLATFORM,X,fun ?LIB_MOD:open/1).
+open_port(X) -> ?CASE_WRAPPER(?PLATFORM,X,fun ?LIB_MOD:open_port/1).
+passive(X) -> ?CASE_WRAPPER(?PLATFORM,X,fun ?LIB_MOD:passive/1).
+active(X) -> ?CASE_WRAPPER(?PLATFORM,X,fun ?LIB_MOD:active/1).
+api_missuse(X) -> ?CASE_WRAPPER(?PLATFORM,X,fun ?LIB_MOD:api_missuse/1).
+not_owner(X) -> ?CASE_WRAPPER(?PLATFORM,X,fun ?LIB_MOD:not_owner/1).
+progress_report(X) -> ?CASE_WRAPPER(?PLATFORM,X,fun ?LIB_MOD:progress_report/1).
+
+passive_user(X) -> ?LIB_MOD:passive_user(X).
+passive_pwd(X) -> ?LIB_MOD:passive_pwd(X).
+passive_cd(X) -> ?LIB_MOD:passive_cd(X).
+passive_lcd(X) -> ?LIB_MOD:passive_lcd(X).
+passive_ls(X) -> ?LIB_MOD:passive_ls(X).
+passive_nlist(X) -> ?LIB_MOD:passive_nlist(X).
+passive_rename(X) -> ?LIB_MOD:passive_rename(X).
+passive_delete(X) -> ?LIB_MOD:passive_delete(X).
+passive_mkdir(X) -> ?LIB_MOD:passive_mkdir(X).
+passive_send(X) -> ?LIB_MOD:passive_send(X).
+passive_send_bin(X) -> ?LIB_MOD:passive_send_bin(X).
+passive_send_chunk(X) -> ?LIB_MOD:passive_send_chunk(X).
+passive_append(X) -> ?LIB_MOD:passive_append(X).
+passive_append_bin(X) -> ?LIB_MOD:passive_append_bin(X).
+passive_append_chunk(X) -> ?LIB_MOD:passive_append_chunk(X).
+passive_recv(X) -> ?LIB_MOD:passive_recv(X).
+passive_recv_bin(X) -> ?LIB_MOD:passive_recv_bin(X).
+passive_recv_chunk(X) -> ?LIB_MOD:passive_recv_chunk(X).
+passive_type(X) -> ?LIB_MOD:passive_type(X).
+passive_quote(X) -> ?LIB_MOD:passive_quote(X).
+passive_ip_v6_disabled(X) -> ?LIB_MOD:passive_ip_v6_disabled(X).
+active_user(X) -> ?LIB_MOD:active_user(X).
+active_pwd(X) -> ?LIB_MOD:active_pwd(X).
+active_cd(X) -> ?LIB_MOD:active_cd(X).
+active_lcd(X) -> ?LIB_MOD:active_lcd(X).
+active_ls(X) -> ?LIB_MOD:active_ls(X).
+active_nlist(X) -> ?LIB_MOD:active_nlist(X).
+active_rename(X) -> ?LIB_MOD:active_rename(X).
+active_delete(X) -> ?LIB_MOD:active_delete(X).
+active_mkdir(X) -> ?LIB_MOD:active_mkdir(X).
+active_send(X) -> ?LIB_MOD:active_send(X).
+active_send_bin(X) -> ?LIB_MOD:active_send_bin(X).
+active_send_chunk(X) -> ?LIB_MOD:active_send_chunk(X).
+active_append(X) -> ?LIB_MOD:active_append(X).
+active_append_bin(X) -> ?LIB_MOD:active_append_bin(X).
+active_append_chunk(X) -> ?LIB_MOD:active_append_chunk(X).
+active_recv(X) -> ?LIB_MOD:active_recv(X).
+active_recv_bin(X) -> ?LIB_MOD:active_recv_bin(X).
+active_recv_chunk(X) -> ?LIB_MOD:active_recv_chunk(X).
+active_type(X) -> ?LIB_MOD:active_type(X).
+active_quote(X) -> ?LIB_MOD:active_quote(X).
+active_ip_v6_disabled(X) -> ?LIB_MOD:active_ip_v6_disabled(X).
+progress_report_send(X) -> ?LIB_MOD:progress_report_send(X).
+progress_report_recv(X) -> ?LIB_MOD:progress_report_recv(X).
+
+fin(Config) ->
+ ?LIB_MOD:ftpd_fin(Config).
diff --git a/lib/inets/test/ftp_macosx_ppc_test.erl b/lib/inets/test/ftp_macosx_ppc_test.erl
new file mode 100644
index 0000000000..cf548a73c0
--- /dev/null
+++ b/lib/inets/test/ftp_macosx_ppc_test.erl
@@ -0,0 +1,152 @@
+%%
+%% %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%
+%%
+%%
+
+-module(ftp_macosx_ppc_test).
+
+-compile(export_all).
+
+-include("test_server.hrl").
+
+-define(LIB_MOD,ftp_suite_lib).
+-define(CASE_WRAPPER(_A_,_B_,_C_),?LIB_MOD:wrapper(_A_,_B_,_C_)).
+-define(PLATFORM,"Macosx ppc ").
+
+
+%% Test server callback functions
+%%--------------------------------------------------------------------
+%% Function: init_per_suite(Config) -> Config
+%% Config - [tuple()]
+%% A list of key/value pairs, holding the test case configuration.
+%% Description: Initiation 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) ->
+ {File, NewFile} = ?LIB_MOD:test_filenames(),
+ NewConfig = [{file, File}, {new_file, NewFile} | Config],
+ ?LIB_MOD:ftpd_init(macosx_ppc, NewConfig).
+
+%%--------------------------------------------------------------------
+%% 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) ->
+ ?LIB_MOD:ftpd_fin(Config).
+
+%%--------------------------------------------------------------------
+%% 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: Initiation 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: Initiation before each test case
+%%--------------------------------------------------------------------
+init_per_testcase(Case, Config) ->
+ ftp_suite_lib:init_per_testcase(Case, 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(Case, Config) ->
+ ftp_suite_lib:end_per_testcase(Case, Config).
+
+%%--------------------------------------------------------------------
+%% 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 ftp client"];
+
+all(suite) ->
+ [open, open_port, passive, active, api_missuse,
+ not_owner, progress_report].
+
+
+open(X) -> ?CASE_WRAPPER(?PLATFORM,X,fun ?LIB_MOD:open/1).
+open_port(X) -> ?CASE_WRAPPER(?PLATFORM,X,fun ?LIB_MOD:open_port/1).
+passive(X) -> ?CASE_WRAPPER(?PLATFORM,X,fun ?LIB_MOD:passive/1).
+active(X) -> ?CASE_WRAPPER(?PLATFORM,X,fun ?LIB_MOD:active/1).
+api_missuse(X) -> ?CASE_WRAPPER(?PLATFORM,X,fun ?LIB_MOD:api_missuse/1).
+not_owner(X) -> ?CASE_WRAPPER(?PLATFORM,X,fun ?LIB_MOD:not_owner/1).
+progress_report(X) -> ?CASE_WRAPPER(?PLATFORM,X,fun ?LIB_MOD:progress_report/1).
+
+passive_user(X) -> ?LIB_MOD:passive_user(X).
+passive_pwd(X) -> ?LIB_MOD:passive_pwd(X).
+passive_cd(X) -> ?LIB_MOD:passive_cd(X).
+passive_lcd(X) -> ?LIB_MOD:passive_lcd(X).
+passive_ls(X) -> ?LIB_MOD:passive_ls(X).
+passive_nlist(X) -> ?LIB_MOD:passive_nlist(X).
+passive_rename(X) -> ?LIB_MOD:passive_rename(X).
+passive_delete(X) -> ?LIB_MOD:passive_delete(X).
+passive_mkdir(X) -> ?LIB_MOD:passive_mkdir(X).
+passive_send(X) -> ?LIB_MOD:passive_send(X).
+passive_send_bin(X) -> ?LIB_MOD:passive_send_bin(X).
+passive_send_chunk(X) -> ?LIB_MOD:passive_send_chunk(X).
+passive_append(X) -> ?LIB_MOD:passive_append(X).
+passive_append_bin(X) -> ?LIB_MOD:passive_append_bin(X).
+passive_append_chunk(X) -> ?LIB_MOD:passive_append_chunk(X).
+passive_recv(X) -> ?LIB_MOD:passive_recv(X).
+passive_recv_bin(X) -> ?LIB_MOD:passive_recv_bin(X).
+passive_recv_chunk(X) -> ?LIB_MOD:passive_recv_chunk(X).
+passive_type(X) -> ?LIB_MOD:passive_type(X).
+passive_quote(X) -> ?LIB_MOD:passive_quote(X).
+passive_ip_v6_disabled(_X) -> {skipped,"unknown error"}.%?LIB_MOD:passive_ip_v6_disabled(X).
+active_user(X) -> ?LIB_MOD:active_user(X).
+active_pwd(X) -> ?LIB_MOD:active_pwd(X).
+active_cd(X) -> ?LIB_MOD:active_cd(X).
+active_lcd(X) -> ?LIB_MOD:active_lcd(X).
+active_ls(X) -> ?LIB_MOD:active_ls(X).
+active_nlist(X) -> ?LIB_MOD:active_nlist(X).
+active_rename(X) -> ?LIB_MOD:active_rename(X).
+active_delete(X) -> ?LIB_MOD:active_delete(X).
+active_mkdir(X) -> ?LIB_MOD:active_mkdir(X).
+active_send(X) -> ?LIB_MOD:active_send(X).
+active_send_bin(X) -> ?LIB_MOD:active_send_bin(X).
+active_send_chunk(X) -> ?LIB_MOD:active_send_chunk(X).
+active_append(X) -> ?LIB_MOD:active_append(X).
+active_append_bin(X) -> ?LIB_MOD:active_append_bin(X).
+active_append_chunk(X) -> ?LIB_MOD:active_append_chunk(X).
+active_recv(X) -> ?LIB_MOD:active_recv(X).
+active_recv_bin(X) -> ?LIB_MOD:active_recv_bin(X).
+active_recv_chunk(X) -> ?LIB_MOD:active_recv_chunk(X).
+active_type(X) -> ?LIB_MOD:active_type(X).
+active_quote(X) -> ?LIB_MOD:active_quote(X).
+active_ip_v6_disabled(_X) -> {skipped,"unknown error"}.%%?LIB_MOD:active_ip_v6_disabled(X).
+progress_report_send(X) -> ?LIB_MOD:progress_report_send(X).
+progress_report_recv(X) -> ?LIB_MOD:progress_report_recv(X).
+
+fin(Config) ->
+ ?LIB_MOD:ftpd_fin(Config).
diff --git a/lib/inets/test/ftp_macosx_x86_test.erl b/lib/inets/test/ftp_macosx_x86_test.erl
new file mode 100644
index 0000000000..5566d4feaa
--- /dev/null
+++ b/lib/inets/test/ftp_macosx_x86_test.erl
@@ -0,0 +1,152 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 2005-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(ftp_macosx_x86_test).
+
+-compile(export_all).
+
+-include("test_server.hrl").
+
+-define(LIB_MOD,ftp_suite_lib).
+-define(CASE_WRAPPER(_A_,_B_,_C_),?LIB_MOD:wrapper(_A_,_B_,_C_)).
+-define(PLATFORM,"Macosx x86 ").
+
+%% Test server callback functions
+%%--------------------------------------------------------------------
+%% Function: init_per_suite(Config) -> Config
+%% Config - [tuple()]
+%% A list of key/value pairs, holding the test case configuration.
+%% Description: Initiation 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) ->
+ {File, NewFile} = ?LIB_MOD:test_filenames(),
+ NewConfig = [{file, File}, {new_file, NewFile} | Config],
+ ?LIB_MOD:ftpd_init(macosx_x86, NewConfig).
+
+%%--------------------------------------------------------------------
+%% 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) ->
+ ?LIB_MOD:ftpd_fin(Config).
+
+%%--------------------------------------------------------------------
+%% 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: Initiation 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: Initiation before each test case
+%%--------------------------------------------------------------------
+init_per_testcase(Case, Config) ->
+ ftp_suite_lib:init_per_testcase(Case, 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(Case, Config) ->
+ ftp_suite_lib:end_per_testcase(Case, Config).
+
+%%--------------------------------------------------------------------
+%% 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 ftp client"];
+
+all(suite) ->
+ [open, open_port, passive, active, api_missuse,
+ not_owner, progress_report].
+
+%% Test cases starts here.
+%%--------------------------------------------------------------------
+open(X) -> ?CASE_WRAPPER(?PLATFORM,X,fun ?LIB_MOD:open/1).
+open_port(X) -> ?CASE_WRAPPER(?PLATFORM,X,fun ?LIB_MOD:open_port/1).
+passive(X) -> ?CASE_WRAPPER(?PLATFORM,X,fun ?LIB_MOD:passive/1).
+active(X) -> ?CASE_WRAPPER(?PLATFORM,X,fun ?LIB_MOD:active/1).
+api_missuse(X) -> ?CASE_WRAPPER(?PLATFORM,X,fun ?LIB_MOD:api_missuse/1).
+not_owner(X) -> ?CASE_WRAPPER(?PLATFORM,X,fun ?LIB_MOD:not_owner/1).
+progress_report(X) -> ?CASE_WRAPPER(?PLATFORM,X,fun ?LIB_MOD:progress_report/1).
+
+passive_user(X) -> ?LIB_MOD:passive_user(X).
+passive_pwd(X) -> ?LIB_MOD:passive_pwd(X).
+passive_cd(X) -> ?LIB_MOD:passive_cd(X).
+passive_lcd(X) -> ?LIB_MOD:passive_lcd(X).
+passive_ls(X) -> ?LIB_MOD:passive_ls(X).
+passive_nlist(X) -> ?LIB_MOD:passive_nlist([{wildcard_support, false} | X]).
+passive_rename(X) -> ?LIB_MOD:passive_rename(X).
+passive_delete(X) -> ?LIB_MOD:passive_delete(X).
+passive_mkdir(X) -> ?LIB_MOD:passive_mkdir(X).
+passive_send(X) -> ?LIB_MOD:passive_send(X).
+passive_send_bin(X) -> ?LIB_MOD:passive_send_bin(X).
+passive_send_chunk(X) -> ?LIB_MOD:passive_send_chunk(X).
+passive_append(X) -> ?LIB_MOD:passive_append(X).
+passive_append_bin(X) -> ?LIB_MOD:passive_append_bin(X).
+passive_append_chunk(X) -> ?LIB_MOD:passive_append_chunk(X).
+passive_recv(X) -> ?LIB_MOD:passive_recv(X).
+passive_recv_bin(X) -> ?LIB_MOD:passive_recv_bin(X).
+passive_recv_chunk(X) -> ?LIB_MOD:passive_recv_chunk(X).
+passive_type(X) -> ?LIB_MOD:passive_type(X).
+passive_quote(X) -> ?LIB_MOD:passive_quote(X).
+passive_ip_v6_disabled(X) -> ?LIB_MOD:passive_ip_v6_disabled(X).
+active_user(X) -> ?LIB_MOD:active_user(X).
+active_pwd(X) -> ?LIB_MOD:active_pwd(X).
+active_cd(X) -> ?LIB_MOD:active_cd(X).
+active_lcd(X) -> ?LIB_MOD:active_lcd(X).
+active_ls(X) -> ?LIB_MOD:active_ls(X).
+active_nlist(X) -> ?LIB_MOD:active_nlist([{wildcard_support, false} | X]).
+active_rename(X) -> ?LIB_MOD:active_rename(X).
+active_delete(X) -> ?LIB_MOD:active_delete(X).
+active_mkdir(X) -> ?LIB_MOD:active_mkdir(X).
+active_send(X) -> ?LIB_MOD:active_send(X).
+active_send_bin(X) -> ?LIB_MOD:active_send_bin(X).
+active_send_chunk(X) -> ?LIB_MOD:active_send_chunk(X).
+active_append(X) -> ?LIB_MOD:active_append(X).
+active_append_bin(X) -> ?LIB_MOD:active_append_bin(X).
+active_append_chunk(X) -> ?LIB_MOD:active_append_chunk(X).
+active_recv(X) -> ?LIB_MOD:active_recv(X).
+active_recv_bin(X) -> ?LIB_MOD:active_recv_bin(X).
+active_recv_chunk(X) -> ?LIB_MOD:active_recv_chunk(X).
+active_type(X) -> ?LIB_MOD:active_type(X).
+active_quote(X) -> ?LIB_MOD:active_quote(X).
+active_ip_v6_disabled(X) -> ?LIB_MOD:active_ip_v6_disabled(X).
+progress_report_send(X) -> ?LIB_MOD:progress_report_send(X).
+progress_report_recv(X) -> ?LIB_MOD:progress_report_recv(X).
+
+fin(Config) ->
+ ?LIB_MOD:ftpd_fin(Config).
diff --git a/lib/inets/test/ftp_netbsd_x86_test.erl b/lib/inets/test/ftp_netbsd_x86_test.erl
new file mode 100644
index 0000000000..a5711b7bde
--- /dev/null
+++ b/lib/inets/test/ftp_netbsd_x86_test.erl
@@ -0,0 +1,152 @@
+%%
+%% %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%
+%%
+%%
+
+-module(ftp_netbsd_x86_test).
+
+-compile(export_all).
+
+-include("test_server.hrl").
+
+-define(LIB_MOD,ftp_suite_lib).
+-define(CASE_WRAPPER(_A_,_B_,_C_),?LIB_MOD:wrapper(_A_,_B_,_C_)).
+-define(PLATFORM,"Netbsd x86 ").
+
+%% Test server callback functions
+%%--------------------------------------------------------------------
+%% Function: init_per_suite(Config) -> Config
+%% Config - [tuple()]
+%% A list of key/value pairs, holding the test case configuration.
+%% Description: Initiation 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) ->
+ {File, NewFile} = ?LIB_MOD:test_filenames(),
+ NewConfig = [{file, File}, {new_file, NewFile} | Config],
+ ?LIB_MOD:ftpd_init(netbsd_x86, NewConfig).
+
+%%--------------------------------------------------------------------
+%% 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) ->
+ ?LIB_MOD:ftpd_fin(Config).
+
+%%--------------------------------------------------------------------
+%% 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: Initiation 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: Initiation before each test case
+%%--------------------------------------------------------------------
+init_per_testcase(Case, Config) ->
+ ftp_suite_lib:init_per_testcase(Case, 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(Case, Config) ->
+ ftp_suite_lib:end_per_testcase(Case, Config).
+
+%%--------------------------------------------------------------------
+%% 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 ftp client"];
+
+all(suite) ->
+ [open, open_port, passive, active, api_missuse,
+ not_owner, progress_report].
+
+%% Test cases starts here.
+%%--------------------------------------------------------------------
+open(X) -> ?CASE_WRAPPER(?PLATFORM,X,fun ?LIB_MOD:open/1).
+open_port(X) -> ?CASE_WRAPPER(?PLATFORM,X,fun ?LIB_MOD:open_port/1).
+passive(X) -> ?CASE_WRAPPER(?PLATFORM,X,fun ?LIB_MOD:passive/1).
+active(X) -> ?CASE_WRAPPER(?PLATFORM,X,fun ?LIB_MOD:active/1).
+api_missuse(X) -> ?CASE_WRAPPER(?PLATFORM,X,fun ?LIB_MOD:api_missuse/1).
+not_owner(X) -> ?CASE_WRAPPER(?PLATFORM,X,fun ?LIB_MOD:not_owner/1).
+progress_report(X) -> ?CASE_WRAPPER(?PLATFORM,X,fun ?LIB_MOD:progress_report/1).
+
+passive_user(X) -> ?LIB_MOD:passive_user(X).
+passive_pwd(X) -> ?LIB_MOD:passive_pwd(X).
+passive_cd(X) -> ?LIB_MOD:passive_cd(X).
+passive_lcd(X) -> ?LIB_MOD:passive_lcd(X).
+passive_ls(X) -> ?LIB_MOD:passive_ls(X).
+passive_nlist(X) -> ?LIB_MOD:passive_nlist(X).
+passive_rename(X) -> ?LIB_MOD:passive_rename(X).
+passive_delete(X) -> ?LIB_MOD:passive_delete(X).
+passive_mkdir(X) -> ?LIB_MOD:passive_mkdir(X).
+passive_send(X) -> ?LIB_MOD:passive_send(X).
+passive_send_bin(X) -> ?LIB_MOD:passive_send_bin(X).
+passive_send_chunk(X) -> ?LIB_MOD:passive_send_chunk(X).
+passive_append(X) -> ?LIB_MOD:passive_append(X).
+passive_append_bin(X) -> ?LIB_MOD:passive_append_bin(X).
+passive_append_chunk(X) -> ?LIB_MOD:passive_append_chunk(X).
+passive_recv(X) -> ?LIB_MOD:passive_recv(X).
+passive_recv_bin(X) -> ?LIB_MOD:passive_recv_bin(X).
+passive_recv_chunk(X) -> ?LIB_MOD:passive_recv_chunk(X).
+passive_type(X) -> ?LIB_MOD:passive_type(X).
+passive_quote(X) -> ?LIB_MOD:passive_quote(X).
+passive_ip_v6_disabled(X) -> ?LIB_MOD:passive_ip_v6_disabled(X).
+active_user(X) -> ?LIB_MOD:active_user(X).
+active_pwd(X) -> ?LIB_MOD:active_pwd(X).
+active_cd(X) -> ?LIB_MOD:active_cd(X).
+active_lcd(X) -> ?LIB_MOD:active_lcd(X).
+active_ls(X) -> ?LIB_MOD:active_ls(X).
+active_nlist(X) -> ?LIB_MOD:active_nlist(X).
+active_rename(X) -> ?LIB_MOD:active_rename(X).
+active_delete(X) -> ?LIB_MOD:active_delete(X).
+active_mkdir(X) -> ?LIB_MOD:active_mkdir(X).
+active_send(X) -> ?LIB_MOD:active_send(X).
+active_send_bin(X) -> ?LIB_MOD:active_send_bin(X).
+active_send_chunk(X) -> ?LIB_MOD:active_send_chunk(X).
+active_append(X) -> ?LIB_MOD:active_append(X).
+active_append_bin(X) -> ?LIB_MOD:active_append_bin(X).
+active_append_chunk(X) -> ?LIB_MOD:active_append_chunk(X).
+active_recv(X) -> ?LIB_MOD:active_recv(X).
+active_recv_bin(X) -> ?LIB_MOD:active_recv_bin(X).
+active_recv_chunk(X) -> ?LIB_MOD:active_recv_chunk(X).
+active_type(X) -> ?LIB_MOD:active_type(X).
+active_quote(X) -> ?LIB_MOD:active_quote(X).
+active_ip_v6_disabled(X) -> ?LIB_MOD:active_ip_v6_disabled(X).
+progress_report_send(X) -> ?LIB_MOD:progress_report_send(X).
+progress_report_recv(X) -> ?LIB_MOD:progress_report_recv(X).
+
+fin(Config) ->
+ ?LIB_MOD:ftpd_fin(Config).
diff --git a/lib/inets/test/ftp_openbsd_x86_test.erl b/lib/inets/test/ftp_openbsd_x86_test.erl
new file mode 100644
index 0000000000..4833b6332b
--- /dev/null
+++ b/lib/inets/test/ftp_openbsd_x86_test.erl
@@ -0,0 +1,151 @@
+%%
+%% %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%
+%%
+%%
+
+-module(ftp_openbsd_x86_test).
+
+%% Note: This directive should only be used in test suites.
+-compile(export_all).
+
+-include("test_server.hrl").
+
+-define(LIB_MOD,ftp_suite_lib).
+-define(CASE_WRAPPER(_A_,_B_,_C_),?LIB_MOD:wrapper(_A_,_B_,_C_)).
+-define(PLATFORM,"Openbsd x86 ").
+
+%% Test server callback functions
+%%--------------------------------------------------------------------
+%% Function: init_per_suite(Config) -> Config
+%% Config - [tuple()]
+%% A list of key/value pairs, holding the test case configuration.
+%% Description: Initiation 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) ->
+ {File, NewFile} = ?LIB_MOD:test_filenames(),
+ NewConfig = [{file, File}, {new_file, NewFile} | Config],
+ ?LIB_MOD:ftpd_init(openbsd_x86, NewConfig).
+
+%%--------------------------------------------------------------------
+%% 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) ->
+ ?LIB_MOD:ftpd_fin(Config).
+
+%%--------------------------------------------------------------------
+%% 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: Initiation 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: Initiation before each test case
+%%--------------------------------------------------------------------
+init_per_testcase(Case, Config) ->
+ ftp_suite_lib:init_per_testcase(Case, 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(Case, Config) ->
+ ftp_suite_lib:end_per_testcase(Case, Config).
+
+%%--------------------------------------------------------------------
+%% 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 ftp client"];
+
+all(suite) ->
+ [open, open_port, passive, active, api_missuse,
+ not_owner, progress_report].
+
+%% Test cases starts here.
+%%--------------------------------------------------------------------
+
+open(X) -> ?CASE_WRAPPER(?PLATFORM,X,fun ?LIB_MOD:open/1).
+open_port(X) -> ?CASE_WRAPPER(?PLATFORM,X,fun ?LIB_MOD:open_port/1).
+passive(X) -> ?CASE_WRAPPER(?PLATFORM,X,fun ?LIB_MOD:passive/1).
+active(X) -> ?CASE_WRAPPER(?PLATFORM,X,fun ?LIB_MOD:active/1).
+api_missuse(X) -> ?CASE_WRAPPER(?PLATFORM,X,fun ?LIB_MOD:api_missuse/1).
+not_owner(X) -> ?CASE_WRAPPER(?PLATFORM,X,fun ?LIB_MOD:not_owner/1).
+progress_report(X) -> ?CASE_WRAPPER(?PLATFORM,X,fun ?LIB_MOD:progress_report/1).
+
+passive_user(X) -> ?LIB_MOD:passive_user(X).
+passive_pwd(X) -> ?LIB_MOD:passive_pwd(X).
+passive_cd(X) -> ?LIB_MOD:passive_cd(X).
+passive_lcd(X) -> ?LIB_MOD:passive_lcd(X).
+passive_ls(X) -> ?LIB_MOD:passive_ls(X).
+passive_nlist(X) -> ?LIB_MOD:passive_nlist(X).
+passive_rename(X) -> ?LIB_MOD:passive_rename(X).
+passive_delete(X) -> ?LIB_MOD:passive_delete(X).
+passive_mkdir(X) -> ?LIB_MOD:passive_mkdir(X).
+passive_send(X) -> ?LIB_MOD:passive_send(X).
+passive_send_bin(X) -> ?LIB_MOD:passive_send_bin(X).
+passive_send_chunk(X) -> ?LIB_MOD:passive_send_chunk(X).
+passive_append(X) -> ?LIB_MOD:passive_append(X).
+passive_append_bin(X) -> ?LIB_MOD:passive_append_bin(X).
+passive_append_chunk(X) -> ?LIB_MOD:passive_append_chunk(X).
+passive_recv(X) -> ?LIB_MOD:passive_recv(X).
+passive_recv_bin(X) -> ?LIB_MOD:passive_recv_bin(X).
+passive_recv_chunk(X) -> ?LIB_MOD:passive_recv_chunk(X).
+passive_type(X) -> ?LIB_MOD:passive_type(X).
+passive_quote(X) -> ?LIB_MOD:passive_quote(X).
+passive_ip_v6_disabled(X) -> ?LIB_MOD:passive_ip_v6_disabled(X).
+active_user(X) -> ?LIB_MOD:active_user(X).
+active_pwd(X) -> ?LIB_MOD:active_pwd(X).
+active_cd(X) -> ?LIB_MOD:active_cd(X).
+active_lcd(X) -> ?LIB_MOD:active_lcd(X).
+active_ls(X) -> ?LIB_MOD:active_ls(X).
+active_nlist(X) -> ?LIB_MOD:active_nlist(X).
+active_rename(X) -> ?LIB_MOD:active_rename(X).
+active_delete(X) -> ?LIB_MOD:active_delete(X).
+active_mkdir(X) -> ?LIB_MOD:active_mkdir(X).
+active_send(X) -> ?LIB_MOD:active_send(X).
+active_send_bin(X) -> ?LIB_MOD:active_send_bin(X).
+active_send_chunk(X) -> ?LIB_MOD:active_send_chunk(X).
+active_append(X) -> ?LIB_MOD:active_append(X).
+active_append_bin(X) -> ?LIB_MOD:active_append_bin(X).
+active_append_chunk(X) -> ?LIB_MOD:active_append_chunk(X).
+active_recv(X) -> ?LIB_MOD:active_recv(X).
+active_recv_bin(X) -> ?LIB_MOD:active_recv_bin(X).
+active_recv_chunk(X) -> ?LIB_MOD:active_recv_chunk(X).
+active_type(X) -> ?LIB_MOD:active_type(X).
+active_quote(X) -> ?LIB_MOD:active_quote(X).
+active_ip_v6_disabled(X) -> ?LIB_MOD:active_ip_v6_disabled(X).
+progress_report_send(X) -> ?LIB_MOD:progress_report_send(X).
+progress_report_recv(X) -> ?LIB_MOD:progress_report_recv(X).
diff --git a/lib/inets/test/ftp_solaris10_sparc_test.erl b/lib/inets/test/ftp_solaris10_sparc_test.erl
new file mode 100644
index 0000000000..6066195f9b
--- /dev/null
+++ b/lib/inets/test/ftp_solaris10_sparc_test.erl
@@ -0,0 +1,154 @@
+%%
+%% %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%
+%%
+%%
+
+-module(ftp_solaris10_sparc_test).
+
+-compile(export_all).
+
+-include("test_server.hrl").
+
+-define(LIB_MOD,ftp_suite_lib).
+-define(CASE_WRAPPER(_A_,_B_,_C_),?LIB_MOD:wrapper(_A_,_B_,_C_)).
+-define(PLATFORM,"Solaris 10 sparc ").
+
+
+%% Test server callback functions
+%%--------------------------------------------------------------------
+%% Function: init_per_suite(Config) -> Config
+%% Config - [tuple()]
+%% A list of key/value pairs, holding the test case configuration.
+%% Description: Initiation 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) ->
+ {File, NewFile} = ?LIB_MOD:test_filenames(),
+ NewConfig = [{file, File}, {new_file, NewFile} | Config],
+ ?LIB_MOD:ftpd_init(solaris10_sparc, NewConfig).
+
+%%--------------------------------------------------------------------
+%% 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) ->
+ ?LIB_MOD:ftpd_fin(Config).
+
+%%--------------------------------------------------------------------
+%% 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: Initiation 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: Initiation before each test case
+%%--------------------------------------------------------------------
+init_per_testcase(Case, Config) ->
+ ftp_suite_lib:init_per_testcase(Case, 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(Case, Config) ->
+ ftp_suite_lib:end_per_testcase(Case, Config).
+
+%%--------------------------------------------------------------------
+%% 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 ftp client"];
+
+all(suite) ->
+ [open, open_port, passive, active, api_missuse,
+ not_owner, progress_report].
+
+%% Test cases starts here.
+%%--------------------------------------------------------------------
+
+open(X) -> ?CASE_WRAPPER(?PLATFORM,X,fun ?LIB_MOD:open/1).
+open_port(X) -> ?CASE_WRAPPER(?PLATFORM,X,fun ?LIB_MOD:open_port/1).
+passive(X) -> ?CASE_WRAPPER(?PLATFORM,X,fun ?LIB_MOD:passive/1).
+active(X) -> ?CASE_WRAPPER(?PLATFORM,X,fun ?LIB_MOD:active/1).
+api_missuse(X) -> ?CASE_WRAPPER(?PLATFORM,X,fun ?LIB_MOD:api_missuse/1).
+not_owner(X) -> ?CASE_WRAPPER(?PLATFORM,X,fun ?LIB_MOD:not_owner/1).
+progress_report(X) -> ?CASE_WRAPPER(?PLATFORM,X,fun ?LIB_MOD:progress_report/1).
+
+passive_user(X) -> ?LIB_MOD:passive_user(X).
+passive_pwd(X) -> ?LIB_MOD:passive_pwd(X).
+passive_cd(X) -> ?LIB_MOD:passive_cd(X).
+passive_lcd(X) -> ?LIB_MOD:passive_lcd(X).
+passive_ls(X) -> ?LIB_MOD:passive_ls(X).
+passive_nlist(X) -> ?LIB_MOD:passive_nlist(X).
+passive_rename(X) -> ?LIB_MOD:passive_rename(X).
+passive_delete(X) -> ?LIB_MOD:passive_delete(X).
+passive_mkdir(X) -> ?LIB_MOD:passive_mkdir(X).
+passive_send(X) -> ?LIB_MOD:passive_send(X).
+passive_send_bin(X) -> ?LIB_MOD:passive_send_bin(X).
+passive_send_chunk(X) -> ?LIB_MOD:passive_send_chunk(X).
+passive_append(X) -> ?LIB_MOD:passive_append(X).
+passive_append_bin(X) -> ?LIB_MOD:passive_append_bin(X).
+passive_append_chunk(X) -> ?LIB_MOD:passive_append_chunk(X).
+passive_recv(X) -> ?LIB_MOD:passive_recv(X).
+passive_recv_bin(X) -> ?LIB_MOD:passive_recv_bin(X).
+passive_recv_chunk(X) -> ?LIB_MOD:passive_recv_chunk(X).
+passive_type(X) -> ?LIB_MOD:passive_type(X).
+passive_quote(X) -> ?LIB_MOD:passive_quote(X).
+passive_ip_v6_disabled(X) -> ?LIB_MOD:passive_ip_v6_disabled(X).
+active_user(X) -> ?LIB_MOD:active_user(X).
+active_pwd(X) -> ?LIB_MOD:active_pwd(X).
+active_cd(X) -> ?LIB_MOD:active_cd(X).
+active_lcd(X) -> ?LIB_MOD:active_lcd(X).
+active_ls(X) -> ?LIB_MOD:active_ls(X).
+active_nlist(X) -> ?LIB_MOD:active_nlist(X).
+active_rename(X) -> ?LIB_MOD:active_rename(X).
+active_delete(X) -> ?LIB_MOD:active_delete(X).
+active_mkdir(X) -> ?LIB_MOD:active_mkdir(X).
+active_send(X) -> ?LIB_MOD:active_send(X).
+active_send_bin(X) -> ?LIB_MOD:active_send_bin(X).
+active_send_chunk(X) -> ?LIB_MOD:active_send_chunk(X).
+active_append(X) -> ?LIB_MOD:active_append(X).
+active_append_bin(X) -> ?LIB_MOD:active_append_bin(X).
+active_append_chunk(X) -> ?LIB_MOD:active_append_chunk(X).
+active_recv(X) -> ?LIB_MOD:active_recv(X).
+active_recv_bin(X) -> ?LIB_MOD:active_recv_bin(X).
+active_recv_chunk(X) -> ?LIB_MOD:active_recv_chunk(X).
+active_type(X) -> ?LIB_MOD:active_type(X).
+active_quote(X) -> ?LIB_MOD:active_quote(X).
+active_ip_v6_disabled(X) -> ?LIB_MOD:active_ip_v6_disabled(X).
+progress_report_send(X) -> ?LIB_MOD:progress_report_send(X).
+progress_report_recv(X) -> ?LIB_MOD:progress_report_recv(X).
+
+fin(Config) ->
+ ?LIB_MOD:ftpd_fin(Config).
diff --git a/lib/inets/test/ftp_solaris10_x86_test.erl b/lib/inets/test/ftp_solaris10_x86_test.erl
new file mode 100644
index 0000000000..3bd99fc3f2
--- /dev/null
+++ b/lib/inets/test/ftp_solaris10_x86_test.erl
@@ -0,0 +1,155 @@
+%%
+%% %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(ftp_solaris10_x86_test).
+
+-compile(export_all).
+
+-include("test_server.hrl").
+
+-define(LIB_MOD, ftp_suite_lib).
+-define(CASE_WRAPPER(_A_,_B_,_C_), ?LIB_MOD:wrapper(_A_,_B_,_C_)).
+-define(PLATFORM, "Solaris 10 x86 ").
+
+
+%% Test server callback functions
+%%--------------------------------------------------------------------
+%% Function: init_per_suite(Config) -> Config
+%% Config - [tuple()]
+%% A list of key/value pairs, holding the test case configuration.
+%% Description: Initiation 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) ->
+ {File, NewFile} = ?LIB_MOD:test_filenames(),
+ NewConfig = [{file, File}, {new_file, NewFile} | Config],
+ ?LIB_MOD:ftpd_init(solaris10_x86, NewConfig).
+
+%%--------------------------------------------------------------------
+%% 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) ->
+ ?LIB_MOD:ftpd_fin(Config).
+
+%%--------------------------------------------------------------------
+%% 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: Initiation 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: Initiation before each test case
+%%--------------------------------------------------------------------
+init_per_testcase(Case, Config) ->
+ ftp_suite_lib:init_per_testcase(Case, 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(Case, Config) ->
+ ftp_suite_lib:end_per_testcase(Case, Config).
+
+%%--------------------------------------------------------------------
+%% 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 ftp client"];
+
+all(suite) ->
+ [open, open_port, passive, active, api_missuse,
+ not_owner, progress_report].
+
+%% Test cases starts here.
+%%--------------------------------------------------------------------
+
+open(X) -> ?CASE_WRAPPER(?PLATFORM,X,fun ?LIB_MOD:open/1).
+open_port(X) -> ?CASE_WRAPPER(?PLATFORM,X,fun ?LIB_MOD:open_port/1).
+passive(X) -> ?CASE_WRAPPER(?PLATFORM,X,fun ?LIB_MOD:passive/1).
+active(X) -> ?CASE_WRAPPER(?PLATFORM,X,fun ?LIB_MOD:active/1).
+api_missuse(X) -> ?CASE_WRAPPER(?PLATFORM,X,fun ?LIB_MOD:api_missuse/1).
+not_owner(X) -> ?CASE_WRAPPER(?PLATFORM,X,fun ?LIB_MOD:not_owner/1).
+progress_report(X) -> ?CASE_WRAPPER(?PLATFORM,X,fun ?LIB_MOD:progress_report/1).
+
+passive_user(X) -> ?LIB_MOD:passive_user(X).
+passive_pwd(X) -> ?LIB_MOD:passive_pwd(X).
+passive_cd(X) -> ?LIB_MOD:passive_cd(X).
+passive_lcd(X) -> ?LIB_MOD:passive_lcd(X).
+passive_ls(X) -> ?LIB_MOD:passive_ls(X).
+passive_nlist(X) -> ?LIB_MOD:passive_nlist(X).
+passive_rename(X) -> ?LIB_MOD:passive_rename(X).
+passive_delete(X) -> ?LIB_MOD:passive_delete(X).
+passive_mkdir(X) -> ?LIB_MOD:passive_mkdir(X).
+passive_send(X) -> ?LIB_MOD:passive_send(X).
+passive_send_bin(X) -> ?LIB_MOD:passive_send_bin(X).
+passive_send_chunk(X) -> ?LIB_MOD:passive_send_chunk(X).
+passive_append(X) -> ?LIB_MOD:passive_append(X).
+passive_append_bin(X) -> ?LIB_MOD:passive_append_bin(X).
+passive_append_chunk(X) -> ?LIB_MOD:passive_append_chunk(X).
+passive_recv(X) -> ?LIB_MOD:passive_recv(X).
+passive_recv_bin(X) -> ?LIB_MOD:passive_recv_bin(X).
+passive_recv_chunk(X) -> ?LIB_MOD:passive_recv_chunk(X).
+passive_type(X) -> ?LIB_MOD:passive_type(X).
+passive_quote(X) -> ?LIB_MOD:passive_quote(X).
+passive_ip_v6_disabled(X) -> ?LIB_MOD:passive_ip_v6_disabled(X).
+active_user(X) -> ?LIB_MOD:active_user(X).
+active_pwd(X) -> ?LIB_MOD:active_pwd(X).
+active_cd(X) -> ?LIB_MOD:active_cd(X).
+active_lcd(X) -> ?LIB_MOD:active_lcd(X).
+active_ls(X) -> ?LIB_MOD:active_ls(X).
+active_nlist(X) -> ?LIB_MOD:active_nlist(X).
+active_rename(X) -> ?LIB_MOD:active_rename(X).
+active_delete(X) -> ?LIB_MOD:active_delete(X).
+active_mkdir(X) -> ?LIB_MOD:active_mkdir(X).
+active_send(X) -> ?LIB_MOD:active_send(X).
+active_send_bin(X) -> ?LIB_MOD:active_send_bin(X).
+active_send_chunk(X) -> ?LIB_MOD:active_send_chunk(X).
+active_append(X) -> ?LIB_MOD:active_append(X).
+active_append_bin(X) -> ?LIB_MOD:active_append_bin(X).
+active_append_chunk(X) -> ?LIB_MOD:active_append_chunk(X).
+active_recv(X) -> ?LIB_MOD:active_recv(X).
+active_recv_bin(X) -> ?LIB_MOD:active_recv_bin(X).
+active_recv_chunk(X) -> ?LIB_MOD:active_recv_chunk(X).
+active_type(X) -> ?LIB_MOD:active_type(X).
+active_quote(X) -> ?LIB_MOD:active_quote(X).
+active_ip_v6_disabled(X) -> ?LIB_MOD:active_ip_v6_disabled(X).
+progress_report_send(X) -> ?LIB_MOD:progress_report_send(X).
+progress_report_recv(X) -> ?LIB_MOD:progress_report_recv(X).
+
+fin(Config) ->
+ ?LIB_MOD:ftpd_fin(Config).
diff --git a/lib/inets/test/ftp_solaris8_sparc_test.erl b/lib/inets/test/ftp_solaris8_sparc_test.erl
new file mode 100644
index 0000000000..9764071cd9
--- /dev/null
+++ b/lib/inets/test/ftp_solaris8_sparc_test.erl
@@ -0,0 +1,152 @@
+%%
+%% %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%
+%%
+%%
+
+-module(ftp_solaris8_sparc_test).
+
+-compile(export_all).
+
+-include("test_server.hrl").
+
+-define(LIB_MOD,ftp_suite_lib).
+-define(CASE_WRAPPER(_A_,_B_,_C_),?LIB_MOD:wrapper(_A_,_B_,_C_)).
+-define(PLATFORM,"Solaris 8 sparc ").
+
+%% Test server callback functions
+%%--------------------------------------------------------------------
+%% Function: init_per_suite(Config) -> Config
+%% Config - [tuple()]
+%% A list of key/value pairs, holding the test case configuration.
+%% Description: Initiation 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) ->
+ {File, NewFile} = ?LIB_MOD:test_filenames(),
+ NewConfig = [{file, File}, {new_file, NewFile} | Config],
+ ?LIB_MOD:ftpd_init(solaris8_sparc, NewConfig).
+
+%%--------------------------------------------------------------------
+%% 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) ->
+ ?LIB_MOD:ftpd_fin(Config).
+
+%%--------------------------------------------------------------------
+%% 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: Initiation 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: Initiation before each test case
+%%--------------------------------------------------------------------
+init_per_testcase(Case, Config) ->
+ ftp_suite_lib:init_per_testcase(Case, 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(Case, Config) ->
+ ftp_suite_lib:end_per_testcase(Case, Config).
+
+%%--------------------------------------------------------------------
+%% 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 ftp client"];
+
+all(suite) ->
+ [open, open_port, passive, active, api_missuse,
+ not_owner, progress_report].
+
+%% Test cases starts here.
+
+open(X) -> ?CASE_WRAPPER(?PLATFORM,X,fun ?LIB_MOD:open/1).
+open_port(X) -> ?CASE_WRAPPER(?PLATFORM,X,fun ?LIB_MOD:open_port/1).
+passive(X) -> ?CASE_WRAPPER(?PLATFORM,X,fun ?LIB_MOD:passive/1).
+active(X) -> ?CASE_WRAPPER(?PLATFORM,X,fun ?LIB_MOD:active/1).
+api_missuse(X) -> ?CASE_WRAPPER(?PLATFORM,X,fun ?LIB_MOD:api_missuse/1).
+not_owner(X) -> ?CASE_WRAPPER(?PLATFORM,X,fun ?LIB_MOD:not_owner/1).
+progress_report(X) -> ?CASE_WRAPPER(?PLATFORM,X,fun ?LIB_MOD:progress_report/1).
+
+passive_user(X) -> ?LIB_MOD:passive_user(X).
+passive_pwd(X) -> ?LIB_MOD:passive_pwd(X).
+passive_cd(X) -> ?LIB_MOD:passive_cd(X).
+passive_lcd(X) -> ?LIB_MOD:passive_lcd(X).
+passive_ls(X) -> ?LIB_MOD:passive_ls(X).
+passive_nlist(X) -> ?LIB_MOD:passive_nlist(X).
+passive_rename(X) -> ?LIB_MOD:passive_rename(X).
+passive_delete(X) -> ?LIB_MOD:passive_delete(X).
+passive_mkdir(X) -> ?LIB_MOD:passive_mkdir(X).
+passive_send(X) -> ?LIB_MOD:passive_send(X).
+passive_send_bin(X) -> ?LIB_MOD:passive_send_bin(X).
+passive_send_chunk(X) -> ?LIB_MOD:passive_send_chunk(X).
+passive_append(X) -> ?LIB_MOD:passive_append(X).
+passive_append_bin(X) -> ?LIB_MOD:passive_append_bin(X).
+passive_append_chunk(X) -> ?LIB_MOD:passive_append_chunk(X).
+passive_recv(X) -> ?LIB_MOD:passive_recv(X).
+passive_recv_bin(X) -> ?LIB_MOD:passive_recv_bin(X).
+passive_recv_chunk(X) -> ?LIB_MOD:passive_recv_chunk(X).
+passive_type(X) -> ?LIB_MOD:passive_type(X).
+passive_quote(X) -> ?LIB_MOD:passive_quote(X).
+passive_ip_v6_disabled(X) -> ?LIB_MOD:passive_ip_v6_disabled(X).
+active_user(X) -> ?LIB_MOD:active_user(X).
+active_pwd(X) -> ?LIB_MOD:active_pwd(X).
+active_cd(X) -> ?LIB_MOD:active_cd(X).
+active_lcd(X) -> ?LIB_MOD:active_lcd(X).
+active_ls(X) -> ?LIB_MOD:active_ls(X).
+active_nlist(X) -> ?LIB_MOD:active_nlist(X).
+active_rename(X) -> ?LIB_MOD:active_rename(X).
+active_delete(X) -> ?LIB_MOD:active_delete(X).
+active_mkdir(X) -> ?LIB_MOD:active_mkdir(X).
+active_send(X) -> ?LIB_MOD:active_send(X).
+active_send_bin(X) -> ?LIB_MOD:active_send_bin(X).
+active_send_chunk(X) -> ?LIB_MOD:active_send_chunk(X).
+active_append(X) -> ?LIB_MOD:active_append(X).
+active_append_bin(X) -> ?LIB_MOD:active_append_bin(X).
+active_append_chunk(X) -> ?LIB_MOD:active_append_chunk(X).
+active_recv(X) -> ?LIB_MOD:active_recv(X).
+active_recv_bin(X) -> ?LIB_MOD:active_recv_bin(X).
+active_recv_chunk(X) -> ?LIB_MOD:active_recv_chunk(X).
+active_type(X) -> ?LIB_MOD:active_type(X).
+active_quote(X) -> ?LIB_MOD:active_quote(X).
+active_ip_v6_disabled(X) -> ?LIB_MOD:active_ip_v6_disabled(X).
+progress_report_send(X) -> ?LIB_MOD:progress_report_send(X).
+progress_report_recv(X) -> ?LIB_MOD:progress_report_recv(X).
+
+fin(Config) ->
+ ?LIB_MOD:ftpd_fin(Config).
diff --git a/lib/inets/test/ftp_solaris9_sparc_test.erl b/lib/inets/test/ftp_solaris9_sparc_test.erl
new file mode 100644
index 0000000000..a9f77bbdac
--- /dev/null
+++ b/lib/inets/test/ftp_solaris9_sparc_test.erl
@@ -0,0 +1,151 @@
+%%
+%% %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%
+%%
+%%
+
+-module(ftp_solaris9_sparc_test).
+
+-compile(export_all).
+
+-include("test_server.hrl").
+
+-define(LIB_MOD,ftp_suite_lib).
+-define(CASE_WRAPPER(_A_,_B_,_C_),?LIB_MOD:wrapper(_A_,_B_,_C_)).
+-define(PLATFORM,"Solaris 9 sparc ").
+%% Test server callback functions
+%%--------------------------------------------------------------------
+%% Function: init_per_suite(Config) -> Config
+%% Config - [tuple()]
+%% A list of key/value pairs, holding the test case configuration.
+%% Description: Initiation 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) ->
+ {File, NewFile} = ?LIB_MOD:test_filenames(),
+ NewConfig = [{file, File}, {new_file, NewFile} | Config],
+ ?LIB_MOD:ftpd_init(solaris9_sparc, NewConfig).
+
+%%--------------------------------------------------------------------
+%% 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) ->
+ ?LIB_MOD:ftpd_fin(Config).
+
+%%--------------------------------------------------------------------
+%% 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: Initiation 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: Initiation before each test case
+%%--------------------------------------------------------------------
+init_per_testcase(Case, Config) ->
+ ftp_suite_lib:init_per_testcase(Case, 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(Case, Config) ->
+ ftp_suite_lib:end_per_testcase(Case, Config).
+
+%%--------------------------------------------------------------------
+%% 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 ftp client"];
+
+all(suite) ->
+ [open, open_port, passive, active, api_missuse,
+ not_owner, progress_report].
+
+%% Test cases starts here.
+
+open(X) -> ?CASE_WRAPPER(?PLATFORM,X,fun ?LIB_MOD:open/1).
+open_port(X) -> ?CASE_WRAPPER(?PLATFORM,X,fun ?LIB_MOD:open_port/1).
+passive(X) -> ?CASE_WRAPPER(?PLATFORM,X,fun ?LIB_MOD:passive/1).
+active(X) -> ?CASE_WRAPPER(?PLATFORM,X,fun ?LIB_MOD:active/1).
+api_missuse(X) -> ?CASE_WRAPPER(?PLATFORM,X,fun ?LIB_MOD:api_missuse/1).
+not_owner(X) -> ?CASE_WRAPPER(?PLATFORM,X,fun ?LIB_MOD:not_owner/1).
+progress_report(X) -> ?CASE_WRAPPER(?PLATFORM,X,fun ?LIB_MOD:progress_report/1).
+
+passive_user(X) -> ?LIB_MOD:passive_user(X).
+passive_pwd(X) -> ?LIB_MOD:passive_pwd(X).
+passive_cd(X) -> ?LIB_MOD:passive_cd(X).
+passive_lcd(X) -> ?LIB_MOD:passive_lcd(X).
+passive_ls(X) -> ?LIB_MOD:passive_ls(X).
+passive_nlist(X) -> ?LIB_MOD:passive_nlist(X).
+passive_rename(X) -> ?LIB_MOD:passive_rename(X).
+passive_delete(X) -> ?LIB_MOD:passive_delete(X).
+passive_mkdir(X) -> ?LIB_MOD:passive_mkdir(X).
+passive_send(X) -> ?LIB_MOD:passive_send(X).
+passive_send_bin(X) -> ?LIB_MOD:passive_send_bin(X).
+passive_send_chunk(X) -> ?LIB_MOD:passive_send_chunk(X).
+passive_append(X) -> ?LIB_MOD:passive_append(X).
+passive_append_bin(X) -> ?LIB_MOD:passive_append_bin(X).
+passive_append_chunk(X) -> ?LIB_MOD:passive_append_chunk(X).
+passive_recv(X) -> ?LIB_MOD:passive_recv(X).
+passive_recv_bin(X) -> ?LIB_MOD:passive_recv_bin(X).
+passive_recv_chunk(X) -> ?LIB_MOD:passive_recv_chunk(X).
+passive_type(X) -> ?LIB_MOD:passive_type(X).
+passive_quote(X) -> ?LIB_MOD:passive_quote(X).
+passive_ip_v6_disabled(X) -> ?LIB_MOD:passive_ip_v6_disabled(X).
+active_user(X) -> ?LIB_MOD:active_user(X).
+active_pwd(X) -> ?LIB_MOD:active_pwd(X).
+active_cd(X) -> ?LIB_MOD:active_cd(X).
+active_lcd(X) -> ?LIB_MOD:active_lcd(X).
+active_ls(X) -> ?LIB_MOD:active_ls(X).
+active_nlist(X) -> ?LIB_MOD:active_nlist(X).
+active_rename(X) -> ?LIB_MOD:active_rename(X).
+active_delete(X) -> ?LIB_MOD:active_delete(X).
+active_mkdir(X) -> ?LIB_MOD:active_mkdir(X).
+active_send(X) -> ?LIB_MOD:active_send(X).
+active_send_bin(X) -> ?LIB_MOD:active_send_bin(X).
+active_send_chunk(X) -> ?LIB_MOD:active_send_chunk(X).
+active_append(X) -> ?LIB_MOD:active_append(X).
+active_append_bin(X) -> ?LIB_MOD:active_append_bin(X).
+active_append_chunk(X) -> ?LIB_MOD:active_append_chunk(X).
+active_recv(X) -> ?LIB_MOD:active_recv(X).
+active_recv_bin(X) -> ?LIB_MOD:active_recv_bin(X).
+active_recv_chunk(X) -> ?LIB_MOD:active_recv_chunk(X).
+active_type(X) -> ?LIB_MOD:active_type(X).
+active_quote(X) -> ?LIB_MOD:active_quote(X).
+active_ip_v6_disabled(X) -> ?LIB_MOD:active_ip_v6_disabled(X).
+progress_report_send(X) -> ?LIB_MOD:progress_report_send(X).
+progress_report_recv(X) -> ?LIB_MOD:progress_report_recv(X).
+
+fin(Config) ->
+ ?LIB_MOD:ftpd_fin(Config).
diff --git a/lib/inets/test/ftp_suite_lib.erl b/lib/inets/test/ftp_suite_lib.erl
new file mode 100644
index 0000000000..b3c4ff2657
--- /dev/null
+++ b/lib/inets/test/ftp_suite_lib.erl
@@ -0,0 +1,1599 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 2005-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(ftp_suite_lib).
+
+
+-include("test_server.hrl").
+-include("test_server_line.hrl").
+-include("inets_test_lib.hrl").
+
+%% Test server specific exports
+% -export([init_per_testcase/2, end_per_testcase/2]).
+
+-compile(export_all).
+
+
+-record(progress, {
+ current = 0,
+ total
+ }).
+
+
+
+-define(FTP_USER, "anonymous").
+-define(FTP_PASS, passwd()).
+-define(FTP_PORT, 21).
+
+-define(BAD_HOST, "badhostname").
+-define(BAD_USER, "baduser").
+-define(BAD_DIR, "baddirectory").
+
+-ifdef(ftp_debug_client).
+-define(ftp_open(Host, Flags),
+ do_ftp_open(Host, [debug, {timeout, timer:seconds(15)}] ++ Flags)).
+-else.
+-ifdef(ftp_trace_client).
+-define(ftp_open(Host, Flags),
+ do_ftp_open(Host, [trace, {timeout, timer:seconds(15)}] ++ Flags)).
+-else.
+-define(ftp_open(Host, Flags),
+ do_ftp_open(Host, [verbose, {timeout, timer:seconds(15)}] ++ Flags)).
+-endif.
+-endif.
+
+%% -- Tickets --
+
+tickets(doc) ->
+ "Test cases for reported bugs";
+tickets(suite) ->
+ [ticket_6035].
+
+%% --
+
+ftpd_init(FtpdTag, Config) ->
+ %% Get the host name(s) of FTP server
+ Hosts =
+ case ?config(ftpd_hosts, Config) of
+ undefined ->
+ ftpd_hosts(data_dir(Config));
+ H ->
+ H
+ end,
+ p("ftpd_init -> "
+ "~n Hosts: ~p"
+ "~n Config: ~p"
+ "~n FtpdTag: ~p", [Hosts, Config, FtpdTag]),
+ %% Get the first host that actually have a running FTP server
+ case lists:keysearch(FtpdTag, 1, Hosts) of
+ {value, {_, TagHosts}} when is_list(TagHosts) ->
+ inets:start(),
+ case (catch get_ftpd_host(TagHosts)) of
+ {ok, Host} ->
+ inets:stop(),
+ [{ftp_remote_host, Host}|Config];
+ _ ->
+ inets:stop(),
+ Reason = lists:flatten(
+ io_lib:format("Could not find a valid "
+ "FTP server for ~p (~p)",
+ [FtpdTag, TagHosts])),
+ {skip, Reason}
+ end;
+ _ ->
+ Reason = lists:flatten(
+ io_lib:format("No host(s) running FTPD server "
+ "for ~p", [FtpdTag])),
+ {skip, Reason}
+ end.
+
+ftpd_fin(Config) ->
+ lists:keydelete(ftp_remote_host, 1, Config).
+
+get_ftpd_host([]) ->
+ {error, no_host};
+get_ftpd_host([Host|Hosts]) ->
+ p("get_ftpd_host -> entry with"
+ "~n Host: ~p"
+ "~n", [Host]),
+ case (catch ftp:open({option_list,
+ [{host, Host}, {port, ?FTP_PORT},
+ {timeout, 20000}]})) of
+ {ok, Pid} ->
+ (catch ftp:close(Pid)),
+ {ok, Host};
+ _ ->
+ get_ftpd_host(Hosts)
+ end.
+
+
+%%--------------------------------------------------------------------
+
+dirty_select_ftpd_host(Config) ->
+ Hosts =
+ case ?config(ftpd_hosts, Config) of
+ undefined ->
+ ftpd_hosts(data_dir(Config));
+ H ->
+ H
+ end,
+ dirty_select_ftpd_host2(Hosts).
+
+dirty_select_ftpd_host2([]) ->
+ throw({error, not_found});
+dirty_select_ftpd_host2([{PlatformTag, Hosts} | PlatformHosts]) ->
+ case dirty_select_ftpd_host3(Hosts) of
+ none ->
+ dirty_select_ftpd_host2(PlatformHosts);
+ {ok, Host} ->
+ {PlatformTag, Host}
+ end.
+
+dirty_select_ftpd_host3([]) ->
+ none;
+dirty_select_ftpd_host3([Host|Hosts]) when is_list(Host) ->
+ case dirty_select_ftpd_host4(Host) of
+ true ->
+ {ok, Host};
+ false ->
+ dirty_select_ftpd_host3(Hosts)
+ end;
+dirty_select_ftpd_host3([_|Hosts]) ->
+ dirty_select_ftpd_host3(Hosts).
+
+%% This is a very simple and dirty test that there is a
+%% (FTP) deamon on the other end.
+dirty_select_ftpd_host4(Host) ->
+ Port = 21,
+ IpFam = inet,
+ Opts = [IpFam, binary, {packet, 0}, {active, false}],
+ Timeout = ?SECS(5),
+ case gen_tcp:connect(Host, Port, Opts, Timeout) of
+ {ok, Sock} ->
+ gen_tcp:close(Sock),
+ true;
+ _Error ->
+ false
+ end.
+
+
+%%--------------------------------------------------------------------
+
+test_filenames() ->
+ {ok, Host} = inet:gethostname(),
+ File = Host ++ "_ftp_test.txt",
+ NewFile = "new_" ++ File,
+ {File, NewFile}.
+
+%%--------------------------------------------------------------------
+%% Function: init_per_testcase(Case, 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: Initiation 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.
+%%--------------------------------------------------------------------
+init_per_testcase(Case, Config)
+ when (Case =:= open) orelse (Case =:= open_port) ->
+ io:format(user, "~n~n*** INIT ~w:~w ***~n~n", [?MODULE, Case]),
+ inets:start(),
+ NewConfig = data_dir(Config),
+ watch_dog(NewConfig);
+
+init_per_testcase(Case, Config) ->
+ put(ftp_testcase, Case),
+ inets:enable_trace(max, io, ftpc),
+ do_init_per_testcase(Case, Config).
+
+do_init_per_testcase(Case, Config)
+ when (Case =:= passive_user) ->
+ io:format(user, "~n~n*** INIT ~w:~w ***~n~n", [?MODULE,Case]),
+ inets:start(),
+ NewConfig = close_connection(watch_dog(Config)),
+ Host = ftp_host(Config),
+ case (catch ?ftp_open(Host, [])) of
+ {ok, Pid} ->
+ [{ftp, Pid} | data_dir(NewConfig)];
+ {skip, _} = SKIP ->
+ SKIP
+ end;
+
+do_init_per_testcase(Case, Config)
+ when (Case =:= active_user) ->
+ io:format(user, "~n~n*** INIT ~w:~w ***~n~n", [?MODULE, Case]),
+ inets:start(),
+ NewConfig = close_connection(watch_dog(Config)),
+ Host = ftp_host(Config),
+ case (catch ?ftp_open(Host, [])) of
+ {ok, Pid} ->
+ ok = ftp:force_active(Pid),
+ [{ftp, Pid} | data_dir(NewConfig)];
+ {skip, _} = SKIP ->
+ SKIP
+ end;
+
+do_init_per_testcase(Case, Config)
+ when (Case =:= progress_report_send) orelse
+ (Case =:= progress_report_recv) ->
+ inets:start(),
+ io:format(user, "~n~n*** INIT ~w:~w ***~n~n", [?MODULE, Case]),
+ NewConfig = close_connection(watch_dog(Config)),
+ Host = ftp_host(Config),
+ Opts = [{host, Host},
+ {port, ?FTP_PORT},
+ {flags, [verbose]},
+ {progress, {?MODULE, progress, #progress{}}}],
+ case ftp:open({option_list, Opts}) of
+ {ok, Pid} ->
+ ok = ftp:user(Pid, ?FTP_USER, ?FTP_PASS),
+ [{ftp, Pid} | data_dir(NewConfig)];
+ {skip, _} = SKIP ->
+ SKIP
+ end;
+
+do_init_per_testcase(Case, Config) ->
+ io:format(user,"~n~n*** INIT ~w:~w ***~n~n", [?MODULE, Case]),
+ inets:start(),
+ NewConfig = close_connection(watch_dog(Config)),
+ Host = ftp_host(Config),
+ Flags =
+ if
+ ((Case =:= passive_ip_v6_disabled) orelse
+ (Case =:= active_ip_v6_disabled)) ->
+ [ip_v6_disabled];
+ true ->
+ []
+ end,
+ case (catch ?ftp_open(Host, Flags)) of
+ {ok, Pid} ->
+ case string:tokens(atom_to_list(Case), [$_]) of
+ [_, "active"|_] ->
+ ok = ftp:force_active(Pid);
+ _ ->
+ ok
+ end,
+ ok = ftp:user(Pid, ?FTP_USER, ?FTP_PASS),
+ [{ftp, Pid} | data_dir(NewConfig)];
+ {skip, _} = SKIP ->
+ SKIP
+ end.
+
+
+%%--------------------------------------------------------------------
+%% Function: end_per_testcase(Case, 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(_, Config) ->
+ NewConfig = close_connection(Config),
+ Dog = ?config(watchdog, NewConfig),
+ inets:stop(),
+ test_server:timetrap_cancel(Dog),
+ ok.
+
+
+%%-------------------------------------------------------------------------
+%% Suites similar for all hosts.
+%%-------------------------------------------------------------------------
+
+passive(suite) ->
+ [
+ passive_user,
+ passive_pwd,
+ passive_cd,
+ passive_lcd,
+ passive_ls,
+ passive_nlist,
+ passive_rename,
+ passive_delete,
+ passive_mkdir,
+ passive_send,
+ passive_send_bin,
+ passive_send_chunk,
+ passive_append,
+ passive_append_bin,
+ passive_append_chunk,
+ passive_recv,
+ passive_recv_bin,
+ passive_recv_chunk,
+ passive_type,
+ passive_quote,
+ passive_ip_v6_disabled
+ ].
+
+active(suite) ->
+ [
+ active_user,
+ active_pwd,
+ active_cd,
+ active_lcd,
+ active_ls,
+ active_nlist,
+ active_rename,
+ active_delete,
+ active_mkdir,
+ active_send,
+ active_send_bin,
+ active_send_chunk,
+ active_append,
+ active_append_bin,
+ active_append_chunk,
+ active_recv,
+ active_recv_bin,
+ active_recv_chunk,
+ active_type,
+ active_quote,
+ active_ip_v6_disabled
+ ].
+
+
+
+%%-------------------------------------------------------------------------
+%% Test cases starts here.
+%%-------------------------------------------------------------------------
+
+open(doc) ->
+ ["Open an ftp connection to a host and close the connection."
+ "Also check that !-messages does not disturbe the connection"];
+open(suite) ->
+ [];
+open(Config) when is_list(Config) ->
+ Host = ftp_host(Config),
+ (catch tc_open(Host)).
+
+tc_open(Host) ->
+ {ok, Pid} = ?ftp_open(Host, []),
+ ok = ftp:close(Pid),
+ {ok, Pid1} =
+ ftp:open({option_list, [{host,Host},
+ {port, ?FTP_PORT},
+ {flags, [verbose]},
+ {timeout, 30000}]}),
+ ok = ftp:close(Pid1),
+ {error, ehost} = ftp:open({option_list, [{port, ?FTP_PORT},
+ {flags, [verbose]}]}),
+ {ok, Pid2} = ftp:open(Host),
+ ok = ftp:close(Pid2),
+
+ {ok, NewHost} = inet:getaddr(Host, inet),
+ {ok, Pid3} = ftp:open(NewHost),
+ ftp:user(Pid3, ?FTP_USER, ?FTP_PASS),
+ Pid3 ! foobar,
+ test_server:sleep(5000),
+ {message_queue_len, 0} = process_info(self(), message_queue_len),
+ ["200" ++ _] = ftp:quote(Pid3, "NOOP"),
+ ok = ftp:close(Pid3),
+
+ %% Bad input that has default values are ignored and the defult
+ %% is used.
+ {ok, Pid4} =
+ ftp:open({option_list, [{host, Host}, {port, badarg},
+ {flags, [verbose]},
+ {timeout, 30000}]}),
+ test_server:sleep(100),
+ ok = ftp:close(Pid4),
+ {ok, Pid5} =
+ ftp:open({option_list, [{host, Host}, {port, ?FTP_PORT},
+ {flags, [verbose]},
+ {timeout, -42}]}),
+ test_server:sleep(100),
+ ok = ftp:close(Pid5),
+ {ok, Pid6} =
+ ftp:open({option_list, [{host, Host}, {port, ?FTP_PORT},
+ {flags, [verbose]},
+ {mode, cool}]}),
+ test_server:sleep(100),
+ ok = ftp:close(Pid6),
+ ok.
+
+
+%%-------------------------------------------------------------------------
+
+open_port(doc) ->
+ ["Open an ftp connection to a host with given port number "
+ "and close the connection."]; % See also OTP-3892
+open_port(suite) ->
+ [];
+open_port(Config) when is_list(Config) ->
+ Host = ftp_host(Config),
+ {ok, Pid} = ftp:open(Host, ?FTP_PORT),
+ ok = ftp:close(Pid),
+ {error, ehost} = ftp:open(?BAD_HOST, []),
+ ok.
+
+
+%%-------------------------------------------------------------------------
+
+passive_user(doc) ->
+ ["Open an ftp connection to a host, and logon as anonymous ftp."];
+passive_user(suite) ->
+ [];
+passive_user(Config) when is_list(Config) ->
+ Pid = ?config(ftp, Config),
+ io:format("Pid: ~p~n",[Pid]),
+ do_user(Pid).
+
+
+%%-------------------------------------------------------------------------
+
+passive_pwd(doc) ->
+ ["Test ftp:pwd/1 & ftp:lpwd/1"];
+passive_pwd(suite) ->
+ [];
+passive_pwd(Config) when is_list(Config) ->
+ Pid = ?config(ftp, Config),
+ do_pwd(Pid).
+
+
+%%-------------------------------------------------------------------------
+
+passive_cd(doc) ->
+ ["Open an ftp connection, log on as anonymous ftp, and cd to the"
+ "directory \"/pub\" and the to the non-existent directory."];
+passive_cd(suite) ->
+ [];
+passive_cd(Config) when is_list(Config) ->
+ Pid = ?config(ftp, Config),
+ do_cd(Pid).
+
+
+%%-------------------------------------------------------------------------
+
+passive_lcd(doc) ->
+ ["Test api function ftp:lcd/2"];
+passive_lcd(suite) ->
+ [];
+passive_lcd(Config) when is_list(Config) ->
+ Pid = ?config(ftp, Config),
+ PrivDir = ?config(priv_dir, Config),
+ do_lcd(Pid, PrivDir).
+
+
+%%-------------------------------------------------------------------------
+
+passive_ls(doc) ->
+ ["Open an ftp connection; ls the current directory, and the "
+ "\"incoming\" directory. We assume that ls never fails, since "
+ "it's output is meant to be read by humans. "];
+passive_ls(suite) ->
+ [];
+passive_ls(Config) when is_list(Config) ->
+ Pid = ?config(ftp, Config),
+ do_ls(Pid).
+
+
+%%-------------------------------------------------------------------------
+
+passive_nlist(doc) ->
+ ["Open an ftp connection; nlist the current directory, and the "
+ "\"incoming\" directory. Nlist does not behave consistenly over "
+ "operating systems. On some it is an error to have an empty "
+ "directory."];
+passive_nlist(suite) ->
+ [];
+passive_nlist(Config) when is_list(Config) ->
+ Pid = ?config(ftp, Config),
+ WildcardSupport = ?config(wildcard_support, Config),
+ do_nlist(Pid, WildcardSupport).
+
+
+%%-------------------------------------------------------------------------
+
+passive_rename(doc) ->
+ ["Transfer a file to the server, and rename it; then remove it."];
+passive_rename(suite) ->
+ [];
+passive_rename(Config) when is_list(Config) ->
+ Pid = ?config(ftp, Config),
+ do_rename(Pid, Config).
+
+
+%%-------------------------------------------------------------------------
+
+passive_delete(doc) ->
+ ["Transfer a file to the server, and then delete it"];
+passive_delete(suite) ->
+ [];
+passive_delete(Config) when is_list(Config) ->
+ Pid = ?config(ftp, Config),
+ do_delete(Pid, Config).
+
+
+%%-------------------------------------------------------------------------
+
+passive_mkdir(doc) ->
+ ["Make a remote directory, cd to it, go to parent directory, and "
+ "remove the directory."];
+passive_mkdir(suite) ->
+ [];
+passive_mkdir(Config) when is_list(Config) ->
+ Pid = ?config(ftp, Config),
+ do_mkdir(Pid).
+
+
+%%-------------------------------------------------------------------------
+
+passive_send(doc) ->
+ ["Create a local file in priv_dir; open an ftp connection to a host; "
+ "logon as anonymous ftp; cd to the directory \"incoming\"; lcd to "
+ "priv_dir; send the file; get a directory listing and check that "
+ "the file is on the list;, delete the remote file; get another listing "
+ "and check that the file is not on the list; close the session; "
+ "delete the local file."];
+passive_send(suite) ->
+ [];
+passive_send(Config) when is_list(Config) ->
+ Pid = ?config(ftp, Config),
+ do_send(Pid, Config).
+
+
+%%-------------------------------------------------------------------------
+
+passive_append(doc) ->
+ ["Create a local file in priv_dir; open an ftp connection to a host; "
+ "logon as anonymous ftp; cd to the directory \"incoming\"; lcd to "
+ "priv_dir; append the file to a file at the remote side that not exits"
+ "this will create the file at the remote side. Then it append the file "
+ "again. When this is done it recive the remote file and control that"
+ "the content is doubled in it.After that it will remove the files"];
+passive_append(suite) ->
+ [];
+passive_append(Config) when is_list(Config) ->
+ Pid = ?config(ftp, Config),
+ do_append(Pid, Config).
+
+
+%%-------------------------------------------------------------------------
+
+passive_send_bin(doc) ->
+ ["Open a connection to a host; cd to the directory \"incoming\"; "
+ "send a binary; remove file; close the connection."];
+passive_send_bin(suite) ->
+ [];
+passive_send_bin(Config) when is_list(Config) ->
+ Pid = ?config(ftp, Config),
+ do_send_bin(Pid, Config).
+
+%%-------------------------------------------------------------------------
+
+passive_append_bin(doc) ->
+ ["Open a connection to a host; cd to the directory \"incoming\"; "
+ "append a binary twice; get the file and compare the content"
+ "remove file; close the connection."];
+passive_append_bin(suite) ->
+ [];
+passive_append_bin(Config) when is_list(Config) ->
+ Pid = ?config(ftp, Config),
+ do_append_bin(Pid, Config).
+
+
+%%-------------------------------------------------------------------------
+
+passive_send_chunk(doc) ->
+ ["Open a connection to a host; cd to the directory \"incoming\"; "
+ "send chunks; remove file; close the connection."];
+passive_send_chunk(suite) ->
+ [];
+passive_send_chunk(Config) when is_list(Config) ->
+ Pid = ?config(ftp, Config),
+ do_send_chunk(Pid, Config).
+
+
+%%-------------------------------------------------------------------------
+
+passive_append_chunk(doc) ->
+ ["Open a connection to a host; cd to the directory \"incoming\"; "
+ "append chunks;control content remove file; close the connection."];
+passive_append_chunk(suite) ->
+ [];
+passive_append_chunk(Config) when is_list(Config) ->
+ Pid = ?config(ftp, Config),
+ do_append_chunk(Pid, Config).
+
+
+%%-------------------------------------------------------------------------
+
+passive_recv(doc) ->
+ ["Create a local file and transfer it to the remote host into the "
+ "the \"incoming\" directory, remove "
+ "the local file. Then open a new connection; cd to \"incoming\", "
+ "lcd to the private directory; receive the file; delete the "
+ "remote file; close connection; check that received file is in "
+ "the correct directory; cleanup." ];
+passive_recv(suite) ->
+ [];
+passive_recv(Config) when is_list(Config) ->
+ Pid = ?config(ftp, Config),
+ do_recv(Pid, Config).
+
+
+%%-------------------------------------------------------------------------
+
+passive_recv_bin(doc) ->
+ ["Send a binary to the remote host; and retreive "
+ "the file; then remove the file."];
+passive_recv_bin(suite) ->
+ [];
+passive_recv_bin(Config) when is_list(Config) ->
+ Pid = ?config(ftp, Config),
+ do_recv_bin(Pid, Config).
+
+
+%%-------------------------------------------------------------------------
+
+passive_recv_chunk(doc) ->
+ ["Send a binary to the remote host; Connect again, and retreive "
+ "the file; then remove the file."];
+passive_recv_chunk(suite) ->
+ [];
+passive_recv_chunk(Config) when is_list(Config) ->
+ Pid = ?config(ftp, Config),
+ do_recv_chunk(Pid, Config).
+
+
+%%-------------------------------------------------------------------------
+
+passive_type(doc) ->
+ ["Test that we can change btween ASCCI and binary transfer mode"];
+passive_type(suite) ->
+ [];
+passive_type(Config) when is_list(Config) ->
+ Pid = ?config(ftp, Config),
+ do_type(Pid).
+
+
+%%-------------------------------------------------------------------------
+
+passive_quote(doc) ->
+ [""];
+passive_quote(suite) ->
+ [];
+passive_quote(Config) when is_list(Config) ->
+ Pid = ?config(ftp, Config),
+ do_quote(Pid).
+
+
+%%-------------------------------------------------------------------------
+
+passive_ip_v6_disabled(doc) ->
+ ["Test ipv4 command PASV"];
+passive_ip_v6_disabled(suite) ->
+ [];
+passive_ip_v6_disabled(Config) when is_list(Config) ->
+ Pid = ?config(ftp, Config),
+ do_send(Pid, Config).
+
+
+%%-------------------------------------------------------------------------
+
+active_user(doc) ->
+ ["Open an ftp connection to a host, and logon as anonymous ftp."];
+active_user(suite) ->
+ [];
+active_user(Config) when is_list(Config) ->
+ Pid = ?config(ftp, Config),
+ do_user(Pid).
+
+
+%%-------------------------------------------------------------------------
+
+active_pwd(doc) ->
+ ["Test ftp:pwd/1 & ftp:lpwd/1"];
+active_pwd(suite) ->
+ [];
+active_pwd(Config) when is_list(Config) ->
+ Pid = ?config(ftp, Config),
+ do_pwd(Pid).
+
+
+%%-------------------------------------------------------------------------
+
+active_cd(doc) ->
+ ["Open an ftp connection, log on as anonymous ftp, and cd to the"
+ "directory \"/pub\" and to a non-existent directory."];
+active_cd(suite) ->
+ [];
+active_cd(Config) when is_list(Config) ->
+ Pid = ?config(ftp, Config),
+ do_cd(Pid).
+
+
+%%-------------------------------------------------------------------------
+
+active_lcd(doc) ->
+ ["Test api function ftp:lcd/2"];
+active_lcd(suite) ->
+ [];
+active_lcd(Config) when is_list(Config) ->
+ Pid = ?config(ftp, Config),
+ PrivDir = ?config(priv_dir, Config),
+ do_lcd(Pid, PrivDir).
+
+
+%%-------------------------------------------------------------------------
+
+active_ls(doc) ->
+ ["Open an ftp connection; ls the current directory, and the "
+ "\"incoming\" directory. We assume that ls never fails, since "
+ "it's output is meant to be read by humans. "];
+active_ls(suite) ->
+ [];
+active_ls(Config) when is_list(Config) ->
+ Pid = ?config(ftp, Config),
+ do_ls(Pid).
+
+
+%%-------------------------------------------------------------------------
+
+active_nlist(doc) ->
+ ["Open an ftp connection; nlist the current directory, and the "
+ "\"incoming\" directory. Nlist does not behave consistenly over "
+ "operating systems. On some it is an error to have an empty "
+ "directory."];
+active_nlist(suite) ->
+ [];
+active_nlist(Config) when is_list(Config) ->
+ Pid = ?config(ftp, Config),
+ WildcardSupport = ?config(wildcard_support, Config),
+ do_nlist(Pid, WildcardSupport).
+
+
+%%-------------------------------------------------------------------------
+
+active_rename(doc) ->
+ ["Transfer a file to the server, and rename it; then remove it."];
+active_rename(suite) ->
+ [];
+active_rename(Config) when is_list(Config) ->
+ Pid = ?config(ftp, Config),
+ do_rename(Pid, Config).
+
+
+%%-------------------------------------------------------------------------
+
+active_delete(doc) ->
+ ["Transfer a file to the server, and then delete it"];
+active_delete(suite) ->
+ [];
+active_delete(Config) when is_list(Config) ->
+ Pid = ?config(ftp, Config),
+ do_delete(Pid, Config).
+
+
+%%-------------------------------------------------------------------------
+
+active_mkdir(doc) ->
+ ["Make a remote directory, cd to it, go to parent directory, and "
+ "remove the directory."];
+active_mkdir(suite) ->
+ [];
+active_mkdir(Config) when is_list(Config) ->
+ Pid = ?config(ftp, Config),
+ do_mkdir(Pid).
+
+
+%%-------------------------------------------------------------------------
+
+active_send(doc) ->
+ ["Create a local file in priv_dir; open an ftp connection to a host; "
+ "logon as anonymous ftp; cd to the directory \"incoming\"; lcd to "
+ "priv_dir; send the file; get a directory listing and check that "
+ "the file is on the list;, delete the remote file; get another listing "
+ "and check that the file is not on the list; close the session; "
+ "delete the local file."];
+active_send(suite) ->
+ [];
+active_send(Config) when is_list(Config) ->
+ Pid = ?config(ftp, Config),
+ do_send(Pid, Config).
+
+
+%%-------------------------------------------------------------------------
+
+active_append(doc) ->
+ ["Create a local file in priv_dir; open an ftp connection to a host; "
+ "logon as anonymous ftp; cd to the directory \"incoming\"; lcd to "
+ "priv_dir; append the file to a file at the remote side that not exits"
+ "this will create the file at the remote side. Then it append the file "
+ "again. When this is done it recive the remote file and control that"
+ "the content is doubled in it.After that it will remove the files"];
+active_append(suite) ->
+ [];
+active_append(Config) when is_list(Config) ->
+ Pid = ?config(ftp, Config),
+ do_append(Pid, Config).
+
+
+%%-------------------------------------------------------------------------
+
+active_send_bin(doc) ->
+ ["Open a connection to a host; cd to the directory \"incoming\"; "
+ "send a binary; remove file; close the connection."];
+active_send_bin(suite) ->
+ [];
+active_send_bin(Config) when is_list(Config) ->
+ Pid = ?config(ftp, Config),
+ do_send_bin(Pid, Config).
+
+
+%%-------------------------------------------------------------------------
+
+active_append_bin(doc) ->
+ ["Open a connection to a host; cd to the directory \"incoming\"; "
+ "append a binary twice; get the file and compare the content"
+ "remove file; close the connection."];
+active_append_bin(suite) ->
+ [];
+active_append_bin(Config) when is_list(Config) ->
+ Pid = ?config(ftp, Config),
+ do_append_bin(Pid, Config).
+
+
+%%-------------------------------------------------------------------------
+
+active_send_chunk(doc) ->
+ ["Open a connection to a host; cd to the directory \"incoming\"; "
+ "send chunks; remove file; close the connection."];
+active_send_chunk(suite) ->
+ [];
+active_send_chunk(Config) when is_list(Config) ->
+ Pid = ?config(ftp, Config),
+ do_send_chunk(Pid, Config).
+
+
+%%-------------------------------------------------------------------------
+
+active_append_chunk(doc) ->
+ ["Open a connection to a host; cd to the directory \"incoming\"; "
+ "append chunks;control content remove file; close the connection."];
+active_append_chunk(suite) ->
+ [];
+active_append_chunk(Config) when is_list(Config) ->
+ Pid = ?config(ftp, Config),
+ do_append_chunk(Pid, Config).
+
+
+%%-------------------------------------------------------------------------
+
+active_recv(doc) ->
+ ["Create a local file and transfer it to the remote host into the "
+ "the \"incoming\" directory, remove "
+ "the local file. Then open a new connection; cd to \"incoming\", "
+ "lcd to the private directory; receive the file; delete the "
+ "remote file; close connection; check that received file is in "
+ "the correct directory; cleanup." ];
+active_recv(suite) ->
+ [];
+active_recv(Config) when is_list(Config) ->
+ Pid = ?config(ftp, Config),
+ do_recv(Pid, Config).
+
+
+%%-------------------------------------------------------------------------
+
+active_recv_bin(doc) ->
+ ["Send a binary to the remote host; and retreive "
+ "the file; then remove the file."];
+active_recv_bin(suite) ->
+ [];
+active_recv_bin(Config) when is_list(Config) ->
+ Pid = ?config(ftp, Config),
+ do_recv_bin(Pid, Config).
+
+
+%%-------------------------------------------------------------------------
+
+active_recv_chunk(doc) ->
+ ["Send a binary to the remote host; Connect again, and retreive "
+ "the file; then remove the file."];
+active_recv_chunk(suite) ->
+ [];
+active_recv_chunk(Config) when is_list(Config) ->
+ Pid = ?config(ftp, Config),
+ do_recv_chunk(Pid, Config).
+
+
+%%-------------------------------------------------------------------------
+
+active_type(doc) ->
+ ["Test that we can change btween ASCCI and binary transfer mode"];
+active_type(suite) ->
+ [];
+active_type(Config) when is_list(Config) ->
+ Pid = ?config(ftp, Config),
+ do_type(Pid).
+
+
+%%-------------------------------------------------------------------------
+
+active_quote(doc) ->
+ [""];
+active_quote(suite) ->
+ [];
+active_quote(Config) when is_list(Config) ->
+ Pid = ?config(ftp, Config),
+ do_quote(Pid).
+
+
+%%-------------------------------------------------------------------------
+
+active_ip_v6_disabled(doc) ->
+ ["Test ipv4 command PORT"];
+active_ip_v6_disabled(suite) ->
+ [];
+active_ip_v6_disabled(Config) when is_list(Config) ->
+ Pid = ?config(ftp, Config),
+ do_send(Pid, Config).
+
+
+%%-------------------------------------------------------------------------
+
+api_missuse(doc)->
+ ["Test that behaviour of the ftp process if the api is abused"];
+api_missuse(suite) -> [];
+api_missuse(Config) when is_list(Config) ->
+ Pid = ?config(ftp, Config),
+ Host = ftp_host(Config),
+
+ %% Serious programming fault, connetion will be shut down
+ {error, {connection_terminated, 'API_violation'}} =
+ gen_server:call(Pid, {self(), foobar, 10}, infinity),
+ test_server:sleep(500),
+ undefined = process_info(Pid, status),
+
+ {ok, Pid2} = ?ftp_open(Host, []),
+ %% Serious programming fault, connetion will be shut down
+ gen_server:cast(Pid2, {self(), foobar, 10}),
+ test_server:sleep(500),
+ undefined = process_info(Pid2, status),
+
+ {ok, Pid3} = ?ftp_open(Host, []),
+ %% Could be an innocent misstake the connection lives.
+ Pid3 ! foobar,
+ test_server:sleep(500),
+ {status, _} = process_info(Pid3, status),
+ ok.
+
+
+%%-------------------------------------------------------------------------
+
+not_owner(doc) ->
+ ["Test what happens if a process that not owns the connection tries "
+ "to use it"];
+not_owner(suite) ->
+ [];
+not_owner(Config) when is_list(Config) ->
+ Pid = ?config(ftp, Config),
+ OtherPid = spawn_link(?MODULE, not_owner, [Pid, self()]),
+
+ receive
+ {OtherPid, ok} ->
+ {ok, _} = ftp:pwd(Pid)
+ end,
+ ok.
+
+not_owner(FtpPid, Pid) ->
+ {error, not_connection_owner} = ftp:pwd(FtpPid),
+ ftp:close(FtpPid),
+ test_server:sleep(100),
+ Pid ! {self(), ok}.
+
+
+%%-------------------------------------------------------------------------
+
+
+progress_report(doc) ->
+ ["Solaris 8 sparc test the option progress."];
+progress_report(suite) ->
+ [progress_report_send, progress_report_recv].
+
+
+%% --
+
+progress_report_send(doc) ->
+ ["Test the option progress for ftp:send/[2,3]"];
+progress_report_send(suite) ->
+ [];
+progress_report_send(Config) when is_list(Config) ->
+ Pid = ?config(ftp, Config),
+ ReportPid =
+ spawn_link(?MODULE, progress_report_receiver_init, [self(), 1]),
+ do_send(Pid, Config),
+ receive
+ {ReportPid, ok} ->
+ ok
+ end.
+
+
+%% --
+
+progress_report_recv(doc) ->
+ ["Test the option progress for ftp:recv/[2,3]"];
+progress_report_recv(suite) ->
+ [];
+progress_report_recv(Config) when is_list(Config) ->
+ Pid = ?config(ftp, Config),
+ ReportPid =
+ spawn_link(?MODULE, progress_report_receiver_init, [self(), 3]),
+ do_recv(Pid, Config),
+ receive
+ {ReportPid, ok} ->
+ ok
+ end,
+ ok.
+
+progress(#progress{} = Progress , _File, {file_size, Total}) ->
+ progress_report_receiver ! start,
+ Progress#progress{total = Total};
+progress(#progress{total = Total, current = Current}
+ = Progress, _File, {transfer_size, 0}) ->
+ progress_report_receiver ! finish,
+ case Total of
+ unknown ->
+ ok;
+ Current ->
+ ok;
+ _ ->
+ test_server:fail({error, {progress, {total, Total},
+ {current, Current}}})
+ end,
+ Progress;
+progress(#progress{current = Current} = Progress, _File,
+ {transfer_size, Size}) ->
+ progress_report_receiver ! update,
+ Progress#progress{current = Current + Size}.
+
+progress_report_receiver_init(Pid, N) ->
+ register(progress_report_receiver, self()),
+ receive
+ start ->
+ ok
+ end,
+ progress_report_receiver_loop(Pid, N-1).
+
+progress_report_receiver_loop(Pid, N) ->
+ receive
+ update ->
+ progress_report_receiver_loop(Pid, N);
+ finish when N =:= 0 ->
+ Pid ! {self(), ok};
+ finish ->
+ Pid ! {self(), ok},
+ receive
+ start ->
+ ok
+ end,
+ progress_report_receiver_loop(Pid, N-1)
+ end.
+
+
+%%-------------------------------------------------------------------------
+%% Ticket test cases
+%%-------------------------------------------------------------------------
+
+ticket_6035(doc) -> ["Test that owning process that exits with reason "
+ "'shutdown' does not cause an error message."];
+ticket_6035(suite) -> [];
+ticket_6035(Config) ->
+ p("ticket_6035 -> entry with"
+ "~n Config: ~p", [Config]),
+ PrivDir = ?config(priv_dir, Config),
+ LogFile = filename:join([PrivDir,"ticket_6035.log"]),
+ try
+ begin
+ Host = dirty_select_ftpd_host(Config),
+ Pid = spawn(?MODULE, open_wait_6035, [Host, self()]),
+ error_logger:logfile({open, LogFile}),
+ ok = kill_ftp_proc_6035(Pid,LogFile),
+ error_logger:logfile(close),
+ p("ticket_6035 -> done", []),
+ ok
+ end
+ catch
+ throw:{error, not_found} ->
+ {skip, "No available FTP servers"}
+ end.
+
+kill_ftp_proc_6035(Pid, LogFile) ->
+ p("kill_ftp_proc_6035 -> entry"),
+ receive
+ open ->
+ p("kill_ftp_proc_6035 -> received open: send shutdown"),
+ exit(Pid, shutdown),
+ kill_ftp_proc_6035(Pid, LogFile);
+ {open_failed, Reason} ->
+ p("kill_ftp_proc_6035 -> received open_failed"
+ "~n Reason: ~p", [Reason]),
+ exit({skip, {failed_openening_server_connection, Reason}})
+ after
+ 5000 ->
+ p("kill_ftp_proc_6035 -> timeout"),
+ is_error_report_6035(LogFile)
+ end.
+
+open_wait_6035(FtpServer, From) ->
+ p("open_wait_6035 -> try connect to ~s", [FtpServer]),
+ case ftp:open(FtpServer, [{timeout, timer:seconds(15)}]) of
+ {ok, Pid} ->
+ p("open_wait_6035 -> connected, now login"),
+ LoginResult = ftp:user(Pid,"anonymous","kldjf"),
+ p("open_wait_6035 -> login result: ~p", [LoginResult]),
+ From ! open,
+ receive
+ dummy ->
+ p("open_wait_6035 -> received dummy"),
+ ok
+ after
+ 10000 ->
+ p("open_wait_6035 -> timeout"),
+ ok
+ end,
+ p("open_wait_6035 -> done(ok)"),
+ ok;
+ {error, Reason} ->
+ p("open_wait_6035 -> open failed"
+ "~n Reason: ~p", [Reason]),
+ From ! {open_failed, {Reason, FtpServer}},
+ p("open_wait_6035 -> done(error)"),
+ ok
+ end.
+
+is_error_report_6035(LogFile) ->
+ p("is_error_report_6035 -> entry"),
+ Res =
+ case file:read_file(LogFile) of
+ {ok, Bin} ->
+ p("is_error_report_6035 -> logfile read"),
+ read_log_6035(binary_to_list(Bin));
+ _ ->
+ ok
+ end,
+ p("is_error_report_6035 -> logfile read result: "
+ "~n ~p", [Res]),
+ file:delete(LogFile),
+ Res.
+
+read_log_6035("=ERROR REPORT===="++_Rest) ->
+ error_report;
+read_log_6035([_H|T]) ->
+ read_log_6035(T);
+read_log_6035([]) ->
+ ok.
+
+
+%%--------------------------------------------------------------------
+%% Internal functions
+%%--------------------------------------------------------------------
+do_user(Pid) ->
+ {error, euser} = ftp:user(Pid, ?BAD_USER, ?FTP_PASS),
+ ok = ftp:user(Pid, ?FTP_USER, ?FTP_PASS),
+ ok.
+
+do_pwd(Pid) ->
+ {ok, "/"} = ftp:pwd(Pid),
+ {ok, Path} = ftp:lpwd(Pid),
+ {ok, Path} = file:get_cwd(),
+ ok.
+
+do_cd(Pid) ->
+ ok = ftp:cd(Pid, "/pub"),
+ {error, epath} = ftp:cd(Pid, ?BAD_DIR),
+ ok.
+
+do_lcd(Pid, Dir) ->
+ ok = ftp:lcd(Pid, Dir),
+ {error, epath} = ftp:lcd(Pid, ?BAD_DIR),
+ ok.
+
+
+do_ls(Pid) ->
+ {ok, _} = ftp:ls(Pid),
+ {ok, _} = ftp:ls(Pid, "incoming"),
+ %% neither nlist nor ls operates on a directory
+ %% they operate on a pathname, which *can* be a
+ %% directory, but can also be a filename or a group
+ %% of files (including wildcards).
+ {ok, _} = ftp:ls(Pid, "incom*"),
+ ok.
+
+do_nlist(Pid, WildcardSupport) ->
+ {ok, _} = ftp:nlist(Pid),
+ {ok, _} = ftp:nlist(Pid, "incoming"),
+ %% neither nlist nor ls operates on a directory
+ %% they operate on a pathname, which *can* be a
+ %% directory, but can also be a filename or a group
+ %% of files (including wildcards).
+ case WildcardSupport of
+ true ->
+ {ok, _} = ftp:nlist(Pid, "incom*"),
+ ok;
+ _ ->
+ ok
+ end.
+
+do_rename(Pid, Config) ->
+ PrivDir = ?config(priv_dir, Config),
+ LFile = ?config(file, Config),
+ NewLFile = ?config(new_file, Config),
+ AbsLFile = filename:absname(LFile, PrivDir),
+ Contents = "ftp_SUITE test ...",
+ ok = file:write_file(AbsLFile, list_to_binary(Contents)),
+ ok = ftp:cd(Pid, "incoming"),
+ ok = ftp:lcd(Pid, PrivDir),
+ ftp:delete(Pid, LFile), % reset
+ ftp:delete(Pid, NewLFile), % reset
+ ok = ftp:send(Pid, LFile),
+ {error, epath} = ftp:rename(Pid, NewLFile, LFile),
+ ok = ftp:rename(Pid, LFile, NewLFile),
+ ftp:delete(Pid, LFile), % cleanup
+ ftp:delete(Pid, NewLFile), % cleanup
+ ok.
+
+do_delete(Pid, Config) ->
+ PrivDir = ?config(priv_dir, Config),
+ LFile = ?config(file, Config),
+ AbsLFile = filename:absname(LFile, PrivDir),
+ Contents = "ftp_SUITE test ...",
+ ok = file:write_file(AbsLFile, list_to_binary(Contents)),
+ ok = ftp:cd(Pid, "incoming"),
+ ok = ftp:lcd(Pid, PrivDir),
+ ftp:delete(Pid,LFile), % reset
+ ok = ftp:send(Pid, LFile),
+ ok = ftp:delete(Pid,LFile),
+ ok.
+
+do_mkdir(Pid) ->
+ {A, B, C} = erlang:now(),
+ NewDir = "nisse_" ++ integer_to_list(A) ++ "_" ++
+ integer_to_list(B) ++ "_" ++ integer_to_list(C),
+ ok = ftp:cd(Pid, "incoming"),
+ {ok, CurrDir} = ftp:pwd(Pid),
+ ok = ftp:mkdir(Pid, NewDir),
+ ok = ftp:cd(Pid, NewDir),
+ ok = ftp:cd(Pid, CurrDir),
+ ok = ftp:rmdir(Pid, NewDir),
+ ok.
+
+do_send(Pid, Config) ->
+ PrivDir = ?config(priv_dir, Config),
+ LFile = ?config(file, Config),
+ RFile = LFile ++ ".remote",
+ AbsLFile = filename:absname(LFile, PrivDir),
+ Contents = "ftp_SUITE test ...",
+ ok = file:write_file(AbsLFile, list_to_binary(Contents)),
+ ok = ftp:cd(Pid, "incoming"),
+ ok = ftp:lcd(Pid, PrivDir),
+ ok = ftp:send(Pid, LFile, RFile),
+ {ok, RFilesString} = ftp:nlist(Pid),
+ RFiles = split(RFilesString),
+ true = lists:member(RFile, RFiles),
+ ok = ftp:delete(Pid, RFile),
+ case ftp:nlist(Pid) of
+ {error, epath} ->
+ ok; % No files
+ {ok, RFilesString1} ->
+ RFiles1 = split(RFilesString1),
+ false = lists:member(RFile, RFiles1)
+ end,
+ ok = file:delete(AbsLFile).
+
+do_append(Pid, Config) ->
+ PrivDir = ?config(priv_dir, Config),
+ LFile = ?config(file, Config),
+ RFile = ?config(new_file, Config),
+ AbsLFile = filename:absname(LFile, PrivDir),
+ Contents = "ftp_SUITE test:appending\r\n",
+
+ ok = file:write_file(AbsLFile, list_to_binary(Contents)),
+ ok = ftp:cd(Pid, "incoming"),
+ ok = ftp:lcd(Pid, PrivDir),
+
+ %% remove files from earlier failed test case
+ ftp:delete(Pid, RFile),
+ ftp:delete(Pid, LFile),
+
+ ok = ftp:append(Pid, LFile, RFile),
+ ok = ftp:append(Pid, LFile, RFile),
+ ok = ftp:append(Pid, LFile),
+
+ %% Control the contents of the file
+ {ok, Bin1} = ftp:recv_bin(Pid, RFile),
+ ok = ftp:delete(Pid, RFile),
+ ok = file:delete(AbsLFile),
+ ok = check_content(binary_to_list(Bin1), Contents, double),
+
+ {ok, Bin2} = ftp:recv_bin(Pid, LFile),
+ ok = ftp:delete(Pid, LFile),
+ ok = check_content(binary_to_list(Bin2), Contents, singel),
+ ok.
+
+do_send_bin(Pid, Config) ->
+ File = ?config(file, Config),
+ Contents = "ftp_SUITE test ...",
+ Bin = list_to_binary(Contents),
+ ok = ftp:cd(Pid, "incoming"),
+ {error, enotbinary} = ftp:send_bin(Pid, Contents, File),
+ ok = ftp:send_bin(Pid, Bin, File),
+ {ok, RFilesString} = ftp:nlist(Pid),
+ RFiles = split(RFilesString),
+ true = lists:member(File, RFiles),
+ ok = ftp:delete(Pid, File),
+ ok.
+
+do_append_bin(Pid, Config) ->
+ File = ?config(file, Config),
+ Contents = "ftp_SUITE test ...",
+ Bin = list_to_binary(Contents),
+ ok = ftp:cd(Pid, "incoming"),
+ {error, enotbinary} = ftp:append_bin(Pid, Contents, File),
+ ok = ftp:append_bin(Pid, Bin, File),
+ ok = ftp:append_bin(Pid, Bin, File),
+ %% Control the contents of the file
+ {ok, Bin2} = ftp:recv_bin(Pid, File),
+ ok = ftp:delete(Pid,File),
+ ok = check_content(binary_to_list(Bin2),binary_to_list(Bin), double).
+
+do_send_chunk(Pid, Config) ->
+ File = ?config(file, Config),
+ Contents = "ftp_SUITE test ...",
+ Bin = list_to_binary(Contents),
+ ok = ftp:cd(Pid, "incoming"),
+ ok = ftp:send_chunk_start(Pid, File),
+ {error, echunk} = ftp:cd(Pid, "incoming"),
+ {error, enotbinary} = ftp:send_chunk(Pid, Contents),
+ ok = ftp:send_chunk(Pid, Bin),
+ ok = ftp:send_chunk(Pid, Bin),
+ ok = ftp:send_chunk_end(Pid),
+ {ok, RFilesString} = ftp:nlist(Pid),
+ RFiles = split(RFilesString),
+ true = lists:member(File, RFiles),
+ ok = ftp:delete(Pid, File),
+ ok.
+
+do_append_chunk(Pid, Config) ->
+ File = ?config(file, Config),
+ Contents = ["ER","LE","RL"],
+ ok = ftp:cd(Pid, "incoming"),
+ ok = ftp:append_chunk_start(Pid, File),
+ {error, enotbinary} = ftp:append_chunk(Pid, lists:nth(1,Contents)),
+ ok = ftp:append_chunk(Pid,list_to_binary(lists:nth(1,Contents))),
+ ok = ftp:append_chunk(Pid,list_to_binary(lists:nth(2,Contents))),
+ ok = ftp:append_chunk(Pid,list_to_binary(lists:nth(3,Contents))),
+ ok = ftp:append_chunk_end(Pid),
+ %%Control the contents of the file
+ {ok, Bin2} = ftp:recv_bin(Pid, File),
+ ok = check_content(binary_to_list(Bin2),"ERL", double),
+ ok = ftp:delete(Pid, File),
+ ok.
+
+do_recv(Pid, Config) ->
+ PrivDir = ?config(priv_dir, Config),
+ File = ?config(file, Config),
+ Newfile = ?config(new_file, Config),
+ AbsFile = filename:absname(File, PrivDir),
+ Contents = "ftp_SUITE:recv test ...",
+ ok = file:write_file(AbsFile, list_to_binary(Contents)),
+ ok = ftp:cd(Pid, "incoming"),
+ ftp:delete(Pid, File), % reset
+ ftp:lcd(Pid, PrivDir),
+ ok = ftp:send(Pid, File),
+ ok = file:delete(AbsFile), % cleanup
+ test_server:sleep(100),
+ ok = ftp:lcd(Pid, PrivDir),
+ ok = ftp:recv(Pid, File),
+ {ok, Files} = file:list_dir(PrivDir),
+ true = lists:member(File, Files),
+ ok = file:delete(AbsFile), % cleanup
+ ok = ftp:recv(Pid, File, Newfile),
+ ok = ftp:delete(Pid, File), % cleanup
+ ok.
+
+do_recv_bin(Pid, Config) ->
+ File = ?config(file, Config),
+ Contents1 = "ftp_SUITE test ...",
+ Bin1 = list_to_binary(Contents1),
+ ok = ftp:cd(Pid, "incoming"),
+ ok = ftp:send_bin(Pid, Bin1, File),
+ test_server:sleep(100),
+ {ok, Bin2} = ftp:recv_bin(Pid, File),
+ ok = ftp:delete(Pid, File), % cleanup
+ Contents2 = binary_to_list(Bin2),
+ Contents1 = Contents2,
+ ok.
+
+do_recv_chunk(Pid, Config) ->
+ File = ?config(file, Config),
+ Data = "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"
+ "BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB"
+ "CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC"
+ "DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD"
+ "EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE"
+ "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
+ "GGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGG"
+ "HHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH"
+ "IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII",
+
+ Contents1 = lists:flatten(lists:duplicate(10, Data)),
+ Bin1 = list_to_binary(Contents1),
+ ok = ftp:cd(Pid, "incoming"),
+ ok = ftp:type(Pid, binary),
+ ok = ftp:send_bin(Pid, Bin1, File),
+ test_server:sleep(100),
+ {error, "ftp:recv_chunk_start/2 not called"} = recv_chunk(Pid, <<>>),
+ ok = ftp:recv_chunk_start(Pid, File),
+ {ok, Contents2} = recv_chunk(Pid, <<>>),
+ ok = ftp:delete(Pid, File), % cleanup
+ ok = find_diff(Contents2, Contents1, 1),
+ ok.
+
+do_type(Pid) ->
+ ok = ftp:type(Pid, ascii),
+ ok = ftp:type(Pid, binary),
+ ok = ftp:type(Pid, ascii),
+ {error, etype} = ftp:type(Pid, foobar),
+ ok.
+
+do_quote(Pid) ->
+ ["257 \"/\""++_Rest] = ftp:quote(Pid, "pwd"), %% 257
+ [_| _] = ftp:quote(Pid, "help"),
+ %% This negativ test causes some ftp servers to hang. This test
+ %% is not important for the client, so we skip it for now.
+ %%["425 Can't build data connection: Connection refused."]
+ %% = ftp:quote(Pid, "list"),
+ ok.
+
+ watch_dog(Config) ->
+ Dog = test_server:timetrap(inets_test_lib:minutes(1)),
+ NewConfig = lists:keydelete(watchdog, 1, Config),
+ [{watchdog, Dog} | NewConfig].
+
+ close_connection(Config) ->
+ case ?config(ftp, Config) of
+ Pid when is_pid(Pid) ->
+ ok = ftp:close(Pid),
+ lists:delete({ftp, Pid}, Config);
+ _ ->
+ Config
+ end.
+
+ftp_host(Config) ->
+ case ?config(ftp_remote_host, Config) of
+ undefined ->
+ exit({skip, "No host specified"});
+ Host ->
+ Host
+ end.
+
+check_content(RContent, LContent, Amount) ->
+ LContent2 = case Amount of
+ double ->
+ LContent ++ LContent;
+ singel ->
+ LContent
+ end,
+ case string:equal(RContent, LContent2) of
+ true ->
+ ok;
+ false ->
+ %% Find where the diff is
+ Where = find_diff(RContent, LContent2, 1),
+ Where
+ end.
+
+find_diff(A, A, _) ->
+ ok;
+find_diff([H|T1], [H|T2], Pos) ->
+ find_diff(T1, T2, Pos+1);
+find_diff(RC, LC, Pos) ->
+ {error, {diff, Pos, RC, LC}}.
+
+recv_chunk(Pid, Acc) ->
+ case ftp:recv_chunk(Pid) of
+ ok ->
+ {ok, binary_to_list(Acc)};
+ {ok, Bin} ->
+ recv_chunk(Pid, <<Acc/binary, Bin/binary>>);
+ Error ->
+ Error
+ end.
+
+split(Cs) ->
+ split(Cs, [], []).
+
+split([$\r, $\n| Cs], I, Is) ->
+ split(Cs, [], [lists:reverse(I)| Is]);
+split([C| Cs], I, Is) ->
+ split(Cs, [C| I], Is);
+split([], I, Is) ->
+ lists:reverse([lists:reverse(I)| Is]).
+
+do_ftp_open(Host, Flags) ->
+ io:format("do_ftp_open -> entry with"
+ "~n Host: ~p"
+ "~n Flags: ~p", [Host, Flags]),
+ case ftp:open(Host, Flags) of
+ {ok, _} = OK ->
+ OK;
+ {error, Reason} ->
+ Str =
+ lists:flatten(
+ io_lib:format("Unable to reach test FTP server ~p (~p)",
+ [Host, Reason])),
+ throw({skip, Str})
+ end.
+
+
+passwd() ->
+ Host =
+ case inet:gethostname() of
+ {ok, H} ->
+ H;
+ _ ->
+ "localhost"
+ end,
+ "ftp_SUITE@" ++ Host.
+
+ftpd_hosts(Config) ->
+ DataDir = ?config(data_dir, Config),
+ FileName = filename:join([DataDir, "../ftp_SUITE_data/", ftpd_hosts]),
+ io:format("FileName: ~p~n", [FileName]),
+ case file:consult(FileName) of
+ {ok, [Hosts]} when is_list(Hosts) ->
+ Hosts;
+ _ ->
+ []
+ end.
+
+wrapper(Prefix,doc,Func) ->
+ Prefix++Func(doc);
+wrapper(_,X,Func) ->
+ Func(X).
+
+data_dir(Config) ->
+ case ?config(data_dir, Config) of
+ List when (length(List) > 0) ->
+ PathList = filename:split(List),
+ {NewPathList,_} = lists:split((length(PathList)-1), PathList),
+ DataDir = filename:join(NewPathList ++ [ftp_SUITE_data]),
+ NewConfig =
+ lists:keyreplace(data_dir,1,Config, {data_dir,DataDir}),
+ NewConfig;
+ _ -> Config
+ end.
+
+
+
+p(F) ->
+ p(F, []).
+
+p(F, A) ->
+ case get(ftp_testcase) of
+ undefined ->
+ io:format("~w [~w] " ++ F ++ "~n", [?MODULE, self() | A]);
+ TC when is_atom(TC) ->
+ io:format("~w [~w] ~w:" ++ F ++ "~n", [?MODULE, self(), TC | A])
+ end.
diff --git a/lib/inets/test/ftp_ticket_test.erl b/lib/inets/test/ftp_ticket_test.erl
new file mode 100644
index 0000000000..6748df03bb
--- /dev/null
+++ b/lib/inets/test/ftp_ticket_test.erl
@@ -0,0 +1,51 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 2006-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(ftp_ticket_test).
+
+-compile(export_all).
+
+-define(LIB_MOD,ftp_suite_lib).
+-define(CASE_WRAPPER(_A_,_B_,_C_),?LIB_MOD:wrapper(_A_,_B_,_C_)).
+-define(PLATFORM,"Solaris 8 sparc ").
+
+
+%% Test server callbacks
+init_per_testcase(Case, Config) ->
+ ftp_suite_lib:init_per_testcase(Case, Config).
+
+end_per_testcase(Case, Config) ->
+ ftp_suite_lib:end_per_testcase(Case, Config).
+
+
+all(suite) ->
+ {conf,init,tickets(),fin}.
+
+init(Config) ->
+ ?LIB_MOD:ftpd_init(ticket_test, Config).
+
+tickets() ->
+ [ticket_6035].
+
+
+fin(Config) ->
+ ?LIB_MOD:ftpd_fin(Config).
+
+ticket_6035(X) -> ?LIB_MOD:ticket_6035(X).
diff --git a/lib/inets/test/ftp_windows_2003_server_test.erl b/lib/inets/test/ftp_windows_2003_server_test.erl
new file mode 100644
index 0000000000..d24318d04f
--- /dev/null
+++ b/lib/inets/test/ftp_windows_2003_server_test.erl
@@ -0,0 +1,152 @@
+%%
+%% %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%
+%%
+%%
+
+-module(ftp_windows_2003_server_test).
+
+-compile(export_all).
+
+-include("test_server.hrl").
+
+-define(LIB_MOD,ftp_suite_lib).
+-define(CASE_WRAPPER(_A_,_B_,_C_),?LIB_MOD:wrapper(_A_,_B_,_C_)).
+-define(PLATFORM,"Windows 2003 server ").
+
+%% Test server callback functions
+%%--------------------------------------------------------------------
+%% Function: init_per_suite(Config) -> Config
+%% Config - [tuple()]
+%% A list of key/value pairs, holding the test case configuration.
+%% Description: Initiation 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) ->
+ {File, NewFile} = ?LIB_MOD:test_filenames(),
+ NewConfig = [{file, File}, {new_file, NewFile} | Config],
+ ?LIB_MOD:ftpd_init(windows_2003_server, NewConfig).
+
+%%--------------------------------------------------------------------
+%% 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) ->
+ ?LIB_MOD:ftpd_fin(Config).
+
+%%--------------------------------------------------------------------
+%% 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: Initiation 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: Initiation before each test case
+%%--------------------------------------------------------------------
+init_per_testcase(Case, Config) ->
+ ftp_suite_lib:init_per_testcase(Case, 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(Case, Config) ->
+ ftp_suite_lib:end_per_testcase(Case, Config).
+
+%%--------------------------------------------------------------------
+%% 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 ftp client"];
+
+all(suite) ->
+ [open, open_port, passive, active, api_missuse,
+ not_owner, progress_report].
+
+%% Test cases starts here.
+
+open(X) -> ?CASE_WRAPPER(?PLATFORM,X,fun ?LIB_MOD:open/1).
+open_port(X) -> ?CASE_WRAPPER(?PLATFORM,X,fun ?LIB_MOD:open_port/1).
+passive(X) -> ?CASE_WRAPPER(?PLATFORM,X,fun ?LIB_MOD:passive/1).
+active(X) -> ?CASE_WRAPPER(?PLATFORM,X,fun ?LIB_MOD:active/1).
+api_missuse(X) -> ?CASE_WRAPPER(?PLATFORM,X,fun ?LIB_MOD:api_missuse/1).
+not_owner(X) -> ?CASE_WRAPPER(?PLATFORM,X,fun ?LIB_MOD:not_owner/1).
+progress_report(X) -> ?CASE_WRAPPER(?PLATFORM,X,fun ?LIB_MOD:progress_report/1).
+
+passive_user(X) -> ?LIB_MOD:passive_user(X).
+passive_pwd(X) -> ?LIB_MOD:passive_pwd(X).
+passive_cd(X) -> ?LIB_MOD:passive_cd(X).
+passive_lcd(X) -> ?LIB_MOD:passive_lcd(X).
+passive_ls(X) -> ?LIB_MOD:passive_ls(X).
+passive_nlist(X) -> ?LIB_MOD:passive_nlist(X).
+passive_rename(X) -> ?LIB_MOD:passive_rename(X).
+passive_delete(X) -> ?LIB_MOD:passive_delete(X).
+passive_mkdir(X) -> ?LIB_MOD:passive_mkdir(X).
+passive_send(X) -> ?LIB_MOD:passive_send(X).
+passive_send_bin(X) -> ?LIB_MOD:passive_send_bin(X).
+passive_send_chunk(X) -> ?LIB_MOD:passive_send_chunk(X).
+passive_append(X) -> ?LIB_MOD:passive_append(X).
+passive_append_bin(X) -> ?LIB_MOD:passive_append_bin(X).
+passive_append_chunk(X) -> ?LIB_MOD:passive_append_chunk(X).
+passive_recv(X) -> ?LIB_MOD:passive_recv(X).
+passive_recv_bin(X) -> ?LIB_MOD:passive_recv_bin(X).
+passive_recv_chunk(X) -> ?LIB_MOD:passive_recv_chunk(X).
+passive_type(X) -> ?LIB_MOD:passive_type(X).
+passive_quote(X) -> ?LIB_MOD:passive_quote(X).
+passive_ip_v6_disabled(X) -> ?LIB_MOD:passive_ip_v6_disabled(X).
+active_user(X) -> ?LIB_MOD:active_user(X).
+active_pwd(X) -> ?LIB_MOD:active_pwd(X).
+active_cd(X) -> ?LIB_MOD:active_cd(X).
+active_lcd(X) -> ?LIB_MOD:active_lcd(X).
+active_ls(X) -> ?LIB_MOD:active_ls(X).
+active_nlist(X) -> ?LIB_MOD:active_nlist(X).
+active_rename(X) -> ?LIB_MOD:active_rename(X).
+active_delete(X) -> ?LIB_MOD:active_delete(X).
+active_mkdir(X) -> ?LIB_MOD:active_mkdir(X).
+active_send(X) -> ?LIB_MOD:active_send(X).
+active_send_bin(X) -> ?LIB_MOD:active_send_bin(X).
+active_send_chunk(X) -> ?LIB_MOD:active_send_chunk(X).
+active_append(X) -> ?LIB_MOD:active_append(X).
+active_append_bin(X) -> ?LIB_MOD:active_append_bin(X).
+active_append_chunk(X) -> ?LIB_MOD:active_append_chunk(X).
+active_recv(X) -> ?LIB_MOD:active_recv(X).
+active_recv_bin(X) -> ?LIB_MOD:active_recv_bin(X).
+active_recv_chunk(X) -> ?LIB_MOD:active_recv_chunk(X).
+active_type(X) -> ?LIB_MOD:active_type(X).
+active_quote(X) -> ?LIB_MOD:active_quote(X).
+active_ip_v6_disabled(X) -> ?LIB_MOD:active_ip_v6_disabled(X).
+progress_report_send(X) -> ?LIB_MOD:progress_report_send(X).
+progress_report_recv(X) -> ?LIB_MOD:progress_report_recv(X).
+
+fin(Config) ->
+ ?LIB_MOD:ftpd_fin(Config).
diff --git a/lib/inets/test/ftp_windows_xp_test.erl b/lib/inets/test/ftp_windows_xp_test.erl
new file mode 100644
index 0000000000..bc161e4f6a
--- /dev/null
+++ b/lib/inets/test/ftp_windows_xp_test.erl
@@ -0,0 +1,150 @@
+%%
+%% %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%
+%%
+%%
+
+-module(ftp_windows_xp_test).
+
+-compile(export_all).
+
+-include("test_server.hrl").
+
+-define(LIB_MOD,ftp_suite_lib).
+-define(CASE_WRAPPER(_A_,_B_,_C_),?LIB_MOD:wrapper(_A_,_B_,_C_)).
+-define(PLATFORM,"Windows xp ").
+
+%% Test server callback functions
+%%--------------------------------------------------------------------
+%% Function: init_per_suite(Config) -> Config
+%% Config - [tuple()]
+%% A list of key/value pairs, holding the test case configuration.
+%% Description: Initiation 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) ->
+ {File, NewFile} = ?LIB_MOD:test_filenames(),
+ NewConfig = [{file, File}, {new_file, NewFile} | Config],
+ ?LIB_MOD:ftpd_init(windows_xp, NewConfig).
+
+%%--------------------------------------------------------------------
+%% 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) ->
+ ?LIB_MOD:ftpd_fin(Config).
+
+%%--------------------------------------------------------------------
+%% 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: Initiation 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: Initiation before each test case
+%%--------------------------------------------------------------------
+init_per_testcase(Case, Config) ->
+ ftp_suite_lib:init_per_testcase(Case, 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(Case, Config) ->
+ ftp_suite_lib:end_per_testcase(Case, Config).
+
+%%--------------------------------------------------------------------
+%% 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 ftp client"];
+
+all(suite) ->
+ [open, open_port, passive, active, api_missuse,
+ not_owner, progress_report].
+
+open(X) -> ?CASE_WRAPPER(?PLATFORM,X,fun ?LIB_MOD:open/1).
+open_port(X) -> ?CASE_WRAPPER(?PLATFORM,X,fun ?LIB_MOD:open_port/1).
+passive(X) -> ?CASE_WRAPPER(?PLATFORM,X,fun ?LIB_MOD:passive/1).
+active(X) -> ?CASE_WRAPPER(?PLATFORM,X,fun ?LIB_MOD:active/1).
+api_missuse(X) -> ?CASE_WRAPPER(?PLATFORM,X,fun ?LIB_MOD:api_missuse/1).
+not_owner(X) -> ?CASE_WRAPPER(?PLATFORM,X,fun ?LIB_MOD:not_owner/1).
+progress_report(X) -> ?CASE_WRAPPER(?PLATFORM,X,fun ?LIB_MOD:progress_report/1).
+
+passive_user(X) -> ?LIB_MOD:passive_user(X).
+passive_pwd(X) -> ?LIB_MOD:passive_pwd(X).
+passive_cd(X) -> ?LIB_MOD:passive_cd(X).
+passive_lcd(X) -> ?LIB_MOD:passive_lcd(X).
+passive_ls(X) -> ?LIB_MOD:passive_ls(X).
+passive_nlist(X) -> ?LIB_MOD:passive_nlist(X).
+passive_rename(X) -> ?LIB_MOD:passive_rename(X).
+passive_delete(X) -> ?LIB_MOD:passive_delete(X).
+passive_mkdir(X) -> ?LIB_MOD:passive_mkdir(X).
+passive_send(X) -> ?LIB_MOD:passive_send(X).
+passive_send_bin(X) -> ?LIB_MOD:passive_send_bin(X).
+passive_send_chunk(X) -> ?LIB_MOD:passive_send_chunk(X).
+passive_append(X) -> ?LIB_MOD:passive_append(X).
+passive_append_bin(X) -> ?LIB_MOD:passive_append_bin(X).
+passive_append_chunk(X) -> ?LIB_MOD:passive_append_chunk(X).
+passive_recv(X) -> ?LIB_MOD:passive_recv(X).
+passive_recv_bin(X) -> ?LIB_MOD:passive_recv_bin(X).
+passive_recv_chunk(X) -> ?LIB_MOD:passive_recv_chunk(X).
+passive_type(X) -> ?LIB_MOD:passive_type(X).
+passive_quote(X) -> ?LIB_MOD:passive_quote(X).
+passive_ip_v6_disabled(X) -> ?LIB_MOD:passive_ip_v6_disabled(X).
+active_user(X) -> ?LIB_MOD:active_user(X).
+active_pwd(X) -> ?LIB_MOD:active_pwd(X).
+active_cd(X) -> ?LIB_MOD:active_cd(X).
+active_lcd(X) -> ?LIB_MOD:active_lcd(X).
+active_ls(X) -> ?LIB_MOD:active_ls(X).
+active_nlist(X) -> ?LIB_MOD:active_nlist(X).
+active_rename(X) -> ?LIB_MOD:active_rename(X).
+active_delete(X) -> ?LIB_MOD:active_delete(X).
+active_mkdir(X) -> ?LIB_MOD:active_mkdir(X).
+active_send(X) -> ?LIB_MOD:active_send(X).
+active_send_bin(X) -> ?LIB_MOD:active_send_bin(X).
+active_send_chunk(X) -> ?LIB_MOD:active_send_chunk(X).
+active_append(X) -> ?LIB_MOD:active_append(X).
+active_append_bin(X) -> ?LIB_MOD:active_append_bin(X).
+active_append_chunk(X) -> ?LIB_MOD:active_append_chunk(X).
+active_recv(X) -> ?LIB_MOD:active_recv(X).
+active_recv_bin(X) -> ?LIB_MOD:active_recv_bin(X).
+active_recv_chunk(X) -> ?LIB_MOD:active_recv_chunk(X).
+active_type(X) -> ?LIB_MOD:active_type(X).
+active_quote(X) -> ?LIB_MOD:active_quote(X).
+active_ip_v6_disabled(X) -> ?LIB_MOD:active_ip_v6_disabled(X).
+progress_report_send(X) -> ?LIB_MOD:progress_report_send(X).
+progress_report_recv(X) -> ?LIB_MOD:progress_report_recv(X).
+
+fin(Config) ->
+ ?LIB_MOD:ftpd_fin(Config).
diff --git a/lib/inets/test/http_format_SUITE.erl b/lib/inets/test/http_format_SUITE.erl
new file mode 100644
index 0000000000..79945f0f4d
--- /dev/null
+++ b/lib/inets/test/http_format_SUITE.erl
@@ -0,0 +1,591 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 2004-2010. All Rights Reserved.
+%%
+%% The contents of this file are subject to the Erlang Public License,
+%% Version 1.1, (the "License"); you may not use this file except in
+%% compliance with the License. You should have received a copy of the
+%% Erlang Public License along with this software. If not, it can be
+%% retrieved online at http://www.erlang.org/.
+%%
+%% Software distributed under the License is distributed on an "AS IS"
+%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+%% the License for the specific language governing rights and limitations
+%% under the License.
+%%
+%% %CopyrightEnd%
+%%
+%%
+
+-module(http_format_SUITE).
+-author('[email protected]').
+
+-include("test_server.hrl").
+-include("test_server_line.hrl").
+-include("http_internal.hrl").
+
+%% Test server specific exports
+-export([all/1, init_per_testcase/2, end_per_testcase/2]).
+
+%% Test cases must be exported.
+-export([chunk/1, chunk_decode/1, chunk_encode/1,
+ chunk_extensions_otp_6005/1, chunk_decode_otp_6264/1,
+ chunk_decode_empty_chunk_otp_6511/1,
+ chunk_decode_trailer/1,
+ http_response/1, http_request/1, validate_request_line/1, script/1,
+ esi_parse_headers/1, cgi_parse_headers/1,
+ is_absolut_uri/1, convert_netscapecookie_date/1]).
+
+all(doc) ->
+ ["Test library functions to the http client and server."];
+all(suite) ->
+ [chunk,
+ http_response, http_request, validate_request_line,
+ script, is_absolut_uri, convert_netscapecookie_date].
+
+init_per_testcase(_, Config) ->
+ Dog = test_server:timetrap(?t:minutes(1)),
+ NewConfig = lists:keydelete(watchdog, 1, Config),
+ [{watchdog, Dog} | NewConfig].
+
+end_per_testcase(_, Config) ->
+ Dog = ?config(watchdog, Config),
+ test_server:timetrap_cancel(Dog),
+ ok.
+
+%%-------------------------------------------------------------------------
+%% Test cases starts here.
+%%-------------------------------------------------------------------------
+script(doc) ->
+ ["Test header parsing in esi/cgi functionality."];
+script(suite) ->
+ [esi_parse_headers, cgi_parse_headers].
+
+chunk(doc) ->
+ ["Test chunk encoding"];
+chunk(suite) ->
+ [chunk_decode, chunk_encode, chunk_extensions_otp_6005,
+ chunk_decode_otp_6264, chunk_decode_empty_chunk_otp_6511,
+ chunk_decode_trailer].
+
+%%-------------------------------------------------------------------------
+chunk_decode(doc) ->
+ ["Test http_chunk:decode/3"];
+chunk_decode(suite) ->
+ [];
+chunk_decode(Config) when is_list(Config) ->
+ ReqHeaders = #http_request_h{'transfer-encoding' = "chunked"},
+ ChunkedBody = "A" ++ ?CRLF ++ "1234567890" ++ ?CRLF ++ "4" ++
+ ?CRLF ++ "HEJ!" ++ ?CRLF ++ "0" ++ ?CRLF ++ ?CRLF,
+ {ok, {Headers, Body}} =
+ http_chunk:decode(list_to_binary(ChunkedBody),
+ ?HTTP_MAX_BODY_SIZE, ?HTTP_MAX_HEADER_SIZE),
+ "1234567890HEJ!" = binary_to_list(Body),
+ %% When the "chunked" is removed by the decoding the header
+ %% will become empty in this case i.e. undefined!
+ NewReqHeaders = http_chunk:handle_headers(ReqHeaders, Headers),
+ undefined = NewReqHeaders#http_request_h.'transfer-encoding',
+
+ NewChunkedBody = ["A" ++ [?CR], [?LF] ++ "12345", "67890" ++ ?CRLF ++ "4"
+ ++ ?CRLF ++ "HEJ!" ++ ?CRLF ++ "0" ++ [?CR],
+ [?LF, ?CR, ?LF]],
+
+ {Module, Function, Args} =
+ http_chunk:decode(list_to_binary(hd(NewChunkedBody)),
+ ?HTTP_MAX_BODY_SIZE, ?HTTP_MAX_HEADER_SIZE),
+
+ {_, Body} = parse(Module, Function, Args, tl(NewChunkedBody)),
+ "1234567890HEJ!" = binary_to_list(Body),
+
+ ok.
+
+%%-------------------------------------------------------------------------
+chunk_extensions_otp_6005(doc) ->
+ ["Make sure so called extensions are ignored"];
+chunk_extensions_otp_6005(suite) ->
+ [];
+chunk_extensions_otp_6005(Config) when is_list(Config)->
+ ChunkedBody = "A;ignore this" ++ ?CRLF ++ "1234567890" ++
+ ?CRLF ++ "4" ++ ?CRLF ++ "HEJ!"++ ?CRLF ++ "0" ++
+ ";extensionname=extensionvalue;foo=bar" ++ ?CRLF ++ ?CRLF,
+ {ok, {["content-length:14"], Body}} =
+ http_chunk:decode(list_to_binary(ChunkedBody),
+ ?HTTP_MAX_BODY_SIZE, ?HTTP_MAX_HEADER_SIZE),
+ "1234567890HEJ!" = binary_to_list(Body),
+
+ ChunkedBody1 = ["A;", "ignore this" ++ [?CR], [?LF] ++ "1234567890" ++
+ ?CRLF ++ "4" ++ ?CRLF ++ "HEJ!"++ ?CRLF ++ "0" ++
+ ";extensionname=extensionvalue;foo=bar" ++ ?CRLF ++ ?CRLF],
+
+ {Module1, Function1, Args1} =
+ http_chunk:decode(list_to_binary(hd(ChunkedBody1)),
+ ?HTTP_MAX_BODY_SIZE, ?HTTP_MAX_HEADER_SIZE),
+
+ {_, NewBody} = parse(Module1, Function1, Args1, tl(ChunkedBody1)),
+ "1234567890HEJ!" = binary_to_list(NewBody),
+ ok.
+
+%%-------------------------------------------------------------------------
+chunk_decode_otp_6264(doc) ->
+ ["Check that 0 in the body does not count as the last chunk"];
+chunk_decode_otp_6264(suite) ->
+ [];
+chunk_decode_otp_6264(Config) when is_list(Config)->
+ ChunkedBody = "A;ignore this" ++ ?CRLF ++ "1234567890" ++
+ ?CRLF ++ "4" ++ ?CRLF ++ "0123"++ ?CRLF ++ "0" ++
+ ";extensionname=extensionvalue;foo=bar" ++ ?CRLF ++ ?CRLF,
+ {ok, {["content-length:14"], Body}} =
+ http_chunk:decode(list_to_binary(ChunkedBody),
+ ?HTTP_MAX_BODY_SIZE, ?HTTP_MAX_HEADER_SIZE),
+ "12345678900123" = binary_to_list(Body),
+
+ NewChunkedBody = ["A" ++ [?CR], [?LF] ++ "12345", "67890" ++ ?CRLF ++ "1"
+ ++ ?CRLF ++ "0" ++ ?CRLF ++ "0" ++ [?CR],
+ [?LF, ?CR, ?LF]],
+
+ {Module, Function, Args} =
+ http_chunk:decode(list_to_binary(hd(NewChunkedBody)),
+ ?HTTP_MAX_BODY_SIZE, ?HTTP_MAX_HEADER_SIZE),
+
+ {_, NewBody} = parse(Module, Function, Args, tl(NewChunkedBody)),
+ "12345678900" = binary_to_list(NewBody),
+
+ NewChunkedBody1 = ["A" ++ [?CR], [?LF] ++ "12345", "67890" ++ ?CRLF ++ "1"
+ ++ ?CRLF ++ "0", ?CRLF ++ "0", [?CR], [?LF],
+ [?CR], [?LF]],
+
+ {Module1, Function1, Args1} =
+ http_chunk:decode(list_to_binary(hd(NewChunkedBody1)),
+ ?HTTP_MAX_BODY_SIZE, ?HTTP_MAX_HEADER_SIZE),
+
+ {_, NewBody} = parse(Module1, Function1, Args1, tl(NewChunkedBody1)),
+ "12345678900" = binary_to_list(NewBody),
+
+ ok.
+%%-------------------------------------------------------------------------
+chunk_decode_empty_chunk_otp_6511(doc) ->
+ [""];
+chunk_decode_empty_chunk_otp_6511(suite) ->
+ [];
+chunk_decode_empty_chunk_otp_6511(Config) when is_list(Config) ->
+ ChunkedBody = "0" ++ ?CRLF ++ ?CRLF,
+ {ok,{["content-length:0"],<<>>}} =
+ http_chunk:decode(list_to_binary(ChunkedBody),
+ ?HTTP_MAX_BODY_SIZE, ?HTTP_MAX_HEADER_SIZE),
+ ok.
+
+%%-------------------------------------------------------------------------
+chunk_decode_trailer(doc) ->
+ ["Make sure trailers are handled correctly. Trailers should"
+ "become new headers"];
+chunk_decode_trailer(suite) ->
+ [];
+chunk_decode_trailer(Config) when is_list(Config)->
+ ChunkedBody = "1a; ignore-stuff-here" ++ ?CRLF ++
+ "abcdefghijklmnopqrstuvwxyz" ++ ?CRLF ++ "10" ++ ?CRLF
+ ++ "1234567890abcdef" ++ ?CRLF ++ "0" ++ ?CRLF
+ ++ "some-footer:some-value" ++ ?CRLF
+ ++ "another-footer:another-value" ++ ?CRLF ++ ?CRLF,
+
+ {ok, {Headers, Body}} =
+ http_chunk:decode(list_to_binary(ChunkedBody),
+ ?HTTP_MAX_BODY_SIZE, ?HTTP_MAX_HEADER_SIZE),
+
+ %% There is no guaranteed order of headers.
+ true = lists:member("content-length:42", Headers),
+ true = lists:member("some-footer:some-value", Headers),
+ true = lists:member("another-footer:another-value", Headers),
+ "abcdefghijklmnopqrstuvwxyz1234567890abcdef" = binary_to_list(Body),
+
+ ChunkedBody1 = "1a" ++ ?CRLF ++
+ "abcdefghijklmnopqrstuvwxyz" ++ ?CRLF ++ "10" ++ ?CRLF
+ ++ "1234567890abcdef" ++ ?CRLF ++ "0" ++ ?CRLF
+ ++ "some-footer:some-value" ++ ?CRLF ++ ?CRLF,
+
+ {ok, {Headers1, Body1}} =
+ http_chunk:decode(list_to_binary(ChunkedBody1),
+ ?HTTP_MAX_BODY_SIZE, ?HTTP_MAX_HEADER_SIZE),
+
+ true = lists:member("content-length:42", Headers1),
+ true = lists:member("some-footer:some-value", Headers1),
+ false = lists:member("another-footer:another-value", Headers1),
+ "abcdefghijklmnopqrstuvwxyz1234567890abcdef" = binary_to_list(Body1),
+
+
+ ChunkedBody2 = ["1a", ?CRLF ++
+ "abcdefghijklmnopqrstuvwxyz" ++ ?CRLF ++ "10" ++ ?CRLF
+ ++ "1234567890abcdef" ++ ?CRLF ++ "0", ";",
+ "ignore stuff here=foobar", ?CRLF ++
+ "some-footer:some-value", ?CRLF, ?CRLF],
+
+ {Module, Function, Args} =
+ http_chunk:decode(list_to_binary(hd(ChunkedBody2)),
+ ?HTTP_MAX_BODY_SIZE, ?HTTP_MAX_HEADER_SIZE),
+
+ {_, NewBody} = parse(Module, Function, Args, tl(ChunkedBody2)),
+ "abcdefghijklmnopqrstuvwxyz1234567890abcdef" = binary_to_list(NewBody),
+
+ ChunkedBody3 = ["1a", ?CRLF ++
+ "abcdefghijklmnopqrstuvwxyz", ?CRLF ++ "10" ++ ?CRLF
+ ++ "1234567890abcdef" ++ ?CRLF ++ "0" ++ ?CRLF
+ ++ "some-footer:some-value", [?CR], [?LF] , ?CRLF],
+
+ {Module1, Function1, Args1} =
+ http_chunk:decode(list_to_binary(hd(ChunkedBody3)),
+ ?HTTP_MAX_BODY_SIZE, ?HTTP_MAX_HEADER_SIZE),
+
+ {_, NewBody} = parse(Module1, Function1, Args1, tl(ChunkedBody3)),
+ "abcdefghijklmnopqrstuvwxyz1234567890abcdef" = binary_to_list(NewBody),
+
+ ok.
+
+%%-------------------------------------------------------------------------
+chunk_encode(doc) ->
+ ["Test http_chunk:encode/1 & http_chunk:encode_last/0"];
+chunk_encode(suite) ->
+ [];
+chunk_encode(Config) when is_list(Config) ->
+ <<54, ?CR, ?LF, 102,111,111,98,97,114, ?CR, ?LF>> =
+ http_chunk:encode(list_to_binary("foobar")),
+ ["6", ?CR, ?LF,"foobar", ?CR, ?LF] = http_chunk:encode("foobar"),
+ <<$0, ?CR, ?LF, ?CR, ?LF >> = http_chunk:encode_last(),
+ ok.
+
+
+%%-------------------------------------------------------------------------
+http_response(doc) ->
+ ["Test httpc_response:parse*. This test case will simulate that the "
+ "message will be recived a little at the time on a socket and the "
+ "package may be broken up into smaller parts at arbitrary point."];
+http_response(suite) ->
+ [];
+http_response(Config) when is_list(Config) ->
+
+ HttpHead1 = ["HTTP", "/1.1 ", "20", "0 ", "ok", [?CR, ?LF],
+ "content-length:83" ++ ?CRLF ++ "content", "-type:",
+ "text/html" ++ ?CRLF ++
+ "date:Thu, 28 Oct 2004 07:57:43 GMT" ++
+ [?CR], [?LF, ?CR, ?LF]],
+ {"HTTP/1.1",
+ 200,
+ "ok",
+ #http_response_h{'content-length' = "83",
+ 'content-type' = "text/html",
+ date = "Thu, 28 Oct 2004 07:57:43 GMT"},
+ <<>>} =
+ parse(httpc_response, parse, [?HTTP_MAX_HEADER_SIZE, false],
+ HttpHead1),
+
+ HttpHead2 = ["HTTP/1.1 200", " ok", [?CR], [?LF] ++
+ "content-length:83" ++ ?CRLF ++ "content-type:",
+ "text/html" ++ ?CRLF ++
+ "date:" ++ "Thu, 28 Oct 2004 07:57:43 GMT" ++
+ ?CRLF, ?CRLF],
+ {"HTTP/1.1",
+ 200,
+ "ok",
+ #http_response_h{'content-length' = "83",
+ 'content-type' = "text/html",
+ date = "Thu, 28 Oct 2004 07:57:43 GMT"},
+ <<>>} =
+ parse(httpc_response, parse, [?HTTP_MAX_HEADER_SIZE, false],
+ HttpHead2),
+
+ HttpHead3 = ["HTTP/1.1 200 ", "ok", ?CRLF ++
+ "content-length:83" ++ ?CRLF ++ "content-type:",
+ "text/html" ++ ?CRLF ++
+ "date:" ++ "Thu, 28 Oct 2004 07:57:43 GMT" ++
+ [?CR, ?LF,?CR], [?LF]],
+ {"HTTP/1.1",
+ 200,
+ "ok",
+ #http_response_h{'content-length' = "83",
+ 'content-type' = "text/html",
+ date = "Thu, 28 Oct 2004 07:57:43 GMT"},
+ <<>>} =
+ parse(httpc_response, parse, [?HTTP_MAX_HEADER_SIZE, false],
+ HttpHead3),
+
+ HttpBody = ["<HTML>\n<HEAD>\n<TITLE> dummy </TITLE>\n</HEAD>\n<BODY>\n",
+ "<H1>dummy</H1>\n</BODY>\n</HTML>\n"],
+
+ NewBody = lists:flatten(HttpBody),
+ Length = length(NewBody),
+ NewBody =
+ binary_to_list(parse
+ (httpc_response, whole_body, [<<>>,Length],
+ HttpBody)),
+
+ HttpBody1 = ["<HTML", ">\n<HEAD>", "\n<TITLE> dummy </TITLE>\n</HEAD>\n",
+ "<BODY>\n", "<H1>du", "mmy</H1>\n</BODY>\n</HTML>\n"],
+
+ NewBody1 = lists:flatten(HttpBody1),
+ Length1 = length(NewBody1),
+ NewBody1 = binary_to_list(parse
+ (httpc_response, whole_body,
+ [<<>>,Length1], HttpBody1)),
+ ok.
+%%-------------------------------------------------------------------------
+http_request(doc) ->
+ ["Test httpd_request:parse* This test case will simulate that the "
+ "message will be recived a little at the time on a socket and the "
+ "package may be broken up into smaller parts at arbitrary point."];
+http_request(suite) ->
+ [];
+http_request(Config) when is_list(Config) ->
+
+ HttpHead = ["GE", "T ", "http://www.erlang", ".org ", "HTTP",
+ "/1.1" ++ ?CRLF ++ "host:",
+ "www.erlang.org" ++ [?CR],
+ [?LF] ++ "te: " ++ ?CRLF, ?CRLF],
+ {"GET",
+ "http://www.erlang.org",
+ "HTTP/1.1",
+ {#http_request_h{host = "www.erlang.org", te = []},
+ ["te: ","host:www.erlang.org"]}, <<>>} =
+ parse(httpd_request, parse, [?HTTP_MAX_HEADER_SIZE], HttpHead),
+
+ HttpHead1 = ["GET http://www.erlang.org HTTP/1.1" ++
+ [?CR], [?LF, ?CR, ?LF]],
+ {"GET",
+ "http://www.erlang.org",
+ "HTTP/1.1",
+ {#http_request_h{}, []}, <<>>} =
+ parse(httpd_request, parse, [?HTTP_MAX_HEADER_SIZE], HttpHead1),
+
+
+ HttpHead2 = ["GET http://www.erlang.org HTTP/1.1" ++
+ [?CR, ?LF, ?CR], [?LF]],
+ {"GET",
+ "http://www.erlang.org",
+ "HTTP/1.1",
+ {#http_request_h{}, []}, <<>>} =
+ parse(httpd_request, parse, [?HTTP_MAX_HEADER_SIZE], HttpHead2),
+
+ %% Note the following body is not related to the headers above
+ HttpBody = ["<HTML>\n<HEAD>\n<TITLE> dummy </TITLE>\n</HEAD>\n<BODY>\n",
+ "<H1>dummy</H1>\n</BODY>\n</HTML>\n"],
+
+ NewBody = lists:flatten(HttpBody),
+ Length = length(NewBody),
+ NewBody =
+ binary_to_list(parse
+ (httpd_request, whole_body, [<<>>,Length], HttpBody)),
+
+ HttpBody1 = ["<HTML", ">\n<HEAD>", "\n<TITLE> dummy </TITLE>\n</HEAD>\n",
+ "<BODY>\n", "<H1>du", "mmy</H1>\n</BODY>\n</HTML>\n"],
+
+ NewBody1 = lists:flatten(HttpBody1),
+ Length1 = length(NewBody1),
+ NewBody1 =
+ binary_to_list(parse
+ (httpd_request, whole_body,
+ [<<>>, Length1], HttpBody1)),
+ ok.
+%%-------------------------------------------------------------------------
+validate_request_line(doc) ->
+ ["Test httpd_request:validate/3. Makes sure you can not get past"
+ " the server_root and that the request is recognized by the server"
+ " and protcol version." ];
+validate_request_line(suite) ->
+ [];
+validate_request_line(Config) when is_list(Config) ->
+
+ %% HTTP/0.9 only has GET requests
+ ok =
+ httpd_request:validate("GET", "http://www.erlang/org", "HTTP/0.9"),
+ {error, {not_supported,
+ {"HEAD", "http://www.erlang/org", "HTTP/0.9"}}} =
+ httpd_request:validate("HEAD", "http://www.erlang/org", "HTTP/0.9"),
+ {error, {not_supported,
+ {"TRACE", "http://www.erlang/org", "HTTP/0.9"}}} =
+ httpd_request:validate("TRACE", "http://www.erlang/org", "HTTP/0.9"),
+ {error, {not_supported,
+ {"POST", "http://www.erlang/org", "HTTP/0.9"}}} =
+ httpd_request:validate("POST", "http://www.erlang/org", "HTTP/0.9"),
+
+ %% HTTP/1.*
+ ok = httpd_request:validate("HEAD", "http://www.erlang/org",
+ "HTTP/1.1"),
+ ok = httpd_request:validate("GET", "http://www.erlang/org",
+ "HTTP/1.1"),
+ ok = httpd_request:validate("POST","http://www.erlang/org",
+ "HTTP/1.1"),
+ ok = httpd_request:validate("TRACE","http://www.erlang/org",
+ "HTTP/1.1"),
+ {error, {not_supported,
+ {"FOOBAR", "http://www.erlang/org", "HTTP/1.1"}}} =
+ httpd_request:validate("FOOBAR", "http://www.erlang/org",
+ "HTTP/1.1"),
+
+ %% Attempts to get outside of server_root directory by relative links
+ ForbiddenUri = "http://127.0.0.1:8888/../../../../../etc/passwd",
+ {error, {bad_request, {forbidden, ForbiddenUri}}} =
+ httpd_request:validate("GET", ForbiddenUri, "HTTP/1.1"),
+
+ ForbiddenUri2 =
+ "http://127.0.0.1:8888/././././././../../../../../etc/passwd",
+ {error, {bad_request, {forbidden, ForbiddenUri2}}} =
+ httpd_request:validate("GET", ForbiddenUri2, "HTTP/1.1"),
+
+ HexForbiddenUri = "http://127.0.0.1:8888/%2e%2e/%2e%2e/%2e%2e/"
+ "home/ingela/test.html",
+ {error, {bad_request, {forbidden, HexForbiddenUri}}} =
+ httpd_request:validate("GET", HexForbiddenUri, "HTTP/1.1"),
+
+ NewForbiddenUri =
+ "http://127.0.0.1:8888/foobar/../../../home/ingela/test.html",
+ {error, {bad_request, {forbidden, NewForbiddenUri}}} =
+ httpd_request:validate("GET", NewForbiddenUri, "HTTP/1.1"),
+
+ NewForbiddenUri1 =
+ "http://127.0.0.1:8888/../home/ingela/test.html",
+ {error, {bad_request, {forbidden, NewForbiddenUri1}}} =
+ httpd_request:validate("GET", NewForbiddenUri1, "HTTP/1.1"),
+
+ ok.
+%%-------------------------------------------------------------------------
+esi_parse_headers(doc) ->
+ ["Test httpd_esi:*. All header values are received in the same"
+ " erlang message."];
+esi_parse_headers(suite) ->
+ [];
+esi_parse_headers(Config) when is_list(Config) ->
+
+ ESIResult = "content-type:text/html\r\ndate:Thu, 28 Oct 2004 07:57:43 "
+ "GMT\r\nstatus:200 OK\r\n\r\nFoobar",
+
+ {"content-type:text/html\r\ndate:Thu, 28 Oct 2004 07:57:43 GMT\r\nst"
+ "atus:200 OK\r\n" = Headers,
+ "Foobar"} = httpd_esi:parse_headers(ESIResult),
+
+ {ok,[{"date","Thu, 28 Oct 2004 07:57:43 GMT"},
+ {"content-type","text/html"}], 200} =
+ httpd_esi:handle_headers(Headers),
+
+ ESIResult2 =
+ "location:http://foo.bar.se\r\ndate:Thu, 28 Oct 2004 07:57:43 "
+ "GMT\r\n\r\n",
+
+ {"location:http://foo.bar.se\r\ndate:Thu, 28 Oct 2004 07:57:43 GMT\r\n" =
+ Headers2,[]}
+ = httpd_esi:parse_headers(ESIResult2),
+
+ {ok,[{"date","Thu, 28 Oct 2004 07:57:43 GMT"},
+ {"location","http://foo.bar.se"}], 302} =
+ httpd_esi:handle_headers(Headers2),
+
+ {proceed,"/foo/bar.html"} =
+ httpd_esi:handle_headers("location:/foo/bar.html\r\n"),
+ ok.
+
+%%--------------------------------------------------------------------
+cgi_parse_headers(doc) ->
+ ["Test httpd_cgi:*. This test case will simulate that the "
+ "message will be recived a little at the time on a socket and the "
+ "package may be broken up into smaller parts at arbitrary point."];
+cgi_parse_headers(suite) ->
+ [];
+cgi_parse_headers(Config) when is_list(Config) ->
+
+ CGIResult = ["content-type:text", "/html\ndate:Thu, 28 Oct 2004 07:57:43 "
+ "GMT\nst", "atus:200 OK\n", "\nFoobar"],
+
+ {Headers, Body} =
+ parse(httpd_cgi, parse_headers, [<<>>, [], []], CGIResult),
+
+ "Foobar" = binary_to_list(Body),
+
+ {ok,[{"content-type","text/html"},
+ {"date","Thu, 28 Oct 2004 07:57:43 GMT"}], {200,"OK"}} =
+ httpd_cgi:handle_headers(Headers),
+
+ CGIResult2 = ["location:http://foo.bar.se\ndate:Thu, 28 Oct 2004"
+ " 07:57:43 GMT\n\n"],
+ {Headers2, _} = parse(httpd_cgi, parse_headers,
+ [<<>>, [], []], CGIResult2),
+
+ {ok,[{"location","http://foo.bar.se"},
+ {"date","Thu, 28 Oct 2004 07:57:43 GMT"}], {302,"Redirect"}} =
+ httpd_cgi:handle_headers(Headers2),
+
+ {proceed,"/foo/bar.html"} =
+ httpd_cgi:handle_headers(["location:/foo/bar.html\n"]),
+
+ CGIHTTPResult = ["Content-Type:text", "/html\n", "Connection:close\r\n",
+ "Content-Language:en\r\nAge:", "4711\r\n\r\n\nfoobar"],
+
+ {Headers3, _} = parse(httpd_cgi, parse_headers,
+ [<<>>, [], []], CGIHTTPResult),
+
+ {ok,[{"content-type","text/html"},
+ {"connection","close"},
+ {"content-language","en"},
+ {"age","4711"}], {200,"ok"}} = httpd_cgi:handle_headers(Headers3),
+
+ ok.
+
+%%-------------------------------------------------------------------------
+is_absolut_uri(doc) ->
+ ["Test http_request:is_absolut_uri/1."];
+is_absolut_uri(suite) ->
+ [];
+is_absolut_uri(Config) when is_list(Config) ->
+ true = http_request:is_absolut_uri("http://www.erlang.org"),
+ true = http_request:is_absolut_uri("https://www.erlang.org"),
+ false = http_request:is_absolut_uri("index.html").
+
+
+%%-------------------------------------------------------------------------
+convert_netscapecookie_date(doc) ->
+ ["Test http_util:convert_netscapecookie_date/1."];
+convert_netscapecookie_date(suite) ->
+ [];
+convert_netscapecookie_date(Config) when is_list(Config) ->
+ {{2006,1,6},{8,59,38}} =
+ http_util:convert_netscapecookie_date("Mon, 06-Jan-2006 08:59:38 GMT"),
+ {{2006,2, 7},{8,59,38}} =
+ http_util:convert_netscapecookie_date("Tue, 07-Feb-2006 08:59:38 GMT"),
+ {{2006,3,8},{8,59,38}} =
+ http_util:convert_netscapecookie_date("Wdy, 08-Mar-2006 08:59:38 GMT"),
+ {{2006,4,9},{8,59,38}} =
+ http_util:convert_netscapecookie_date("Thu, 09-Apr-2006 08:59:38 GMT"),
+ {{2006,5,10},{8,59,38}} =
+ http_util:convert_netscapecookie_date("Fri, 10-May-2006 08:59:38 GMT"),
+ {{2006,6,11},{8,59,38}} =
+ http_util:convert_netscapecookie_date("Sat, 11-Jun-2006 08:59:38 GMT"),
+ {{2006,7,12},{8,59,38}} =
+ http_util:convert_netscapecookie_date("Sun, 12-Jul-2006 08:59:38 GMT"),
+ {{2006,8,12},{8,59,38}} =
+ http_util:convert_netscapecookie_date("Sun, 12-Aug-2006 08:59:38 GMT"),
+ {{2006,9,12},{8,59,38}} =
+ http_util:convert_netscapecookie_date("Sun, 12-Sep-2006 08:59:38 GMT"),
+ {{2006,10,12},{8,59,38}} =
+ http_util:convert_netscapecookie_date("Sun, 12-Oct-2006 08:59:38 GMT"),
+ {{2006,11,12},{8,59,38}} =
+ http_util:convert_netscapecookie_date("Sun, 12-Nov-2006 08:59:38 GMT"),
+ {{2006,12,12},{8,59,38}} =
+ http_util:convert_netscapecookie_date("Sun, 12-Dec-2006 08:59:38 GMT"),
+ {{2006,12,12},{8,59,38}} =
+ http_util:convert_netscapecookie_date("Sun 12-Dec-2006 08:59:38 GMT"),
+ {{2006,12,12},{8,59,38}} =
+ http_util:convert_netscapecookie_date("Sun, 12-Dec-06 08:59:38 GMT"),
+ {{2006,12,12},{8,59,38}} =
+ http_util:convert_netscapecookie_date("Sun 12-Dec-06 08:59:38 GMT"),
+ ok.
+
+%%--------------------------------------------------------------------
+%%% Internal functions
+%%--------------------------------------------------------------------
+
+parse(Module, Function, Args, [Data | Rest]) ->
+ case Module:Function([list_to_binary(Data) | Args]) of
+ {ok, Result} ->
+ Result;
+ {NewModule, NewFunction, NewArgs} ->
+ parse(NewModule, NewFunction, NewArgs, Rest)
+ end.
+
+
+
diff --git a/lib/inets/test/http_internal.hrl b/lib/inets/test/http_internal.hrl
new file mode 120000
index 0000000000..a4600a09f7
--- /dev/null
+++ b/lib/inets/test/http_internal.hrl
@@ -0,0 +1 @@
+../src/http_lib/http_internal.hrl \ No newline at end of file
diff --git a/lib/inets/test/httpc_SUITE.erl b/lib/inets/test/httpc_SUITE.erl
new file mode 100644
index 0000000000..3a1f4cc83d
--- /dev/null
+++ b/lib/inets/test/httpc_SUITE.erl
@@ -0,0 +1,3163 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 2004-2011. All Rights Reserved.
+%%
+%% The contents of this file are subject to the Erlang Public License,
+%% Version 1.1, (the "License"); you may not use this file except in
+%% compliance with the License. You should have received a copy of the
+%% Erlang Public License along with this software. If not, it can be
+%% retrieved online at http://www.erlang.org/.
+%%
+%% Software distributed under the License is distributed on an "AS IS"
+%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+%% the License for the specific language governing rights and limitations
+%% under the License.
+%%
+%% %CopyrightEnd%
+%%
+%%
+
+%%
+%% ts:run(inets, httpc_SUITE, [batch]).
+%%
+
+-module(httpc_SUITE).
+
+-include("test_server.hrl").
+-include("test_server_line.hrl").
+
+-include_lib("kernel/include/file.hrl").
+
+%% Note: This directive should only be used in test suites.
+-compile(export_all).
+
+%% Test server specific exports
+-define(PROXY_URL, "http://www.erlang.org").
+-define(PROXY, "www-proxy.ericsson.se").
+-define(PROXY_PORT, 8080).
+-define(IP_PORT, 8998).
+-define(SSL_PORT, 8999).
+-define(NOT_IN_USE_PORT, 8997).
+-define(LOCAL_HOST, {127,0,0,1}).
+-define(IPV6_LOCAL_HOST, "0:0:0:0:0:0:0:1").
+-define(URL_START, "http://localhost:").
+-define(SSL_URL_START, "https://localhost:").
+-define(CR, $\r).
+-define(LF, $\n).
+-define(HTTP_MAX_HEADER_SIZE, 10240).
+
+
+%%--------------------------------------------------------------------
+%% all(Arg) -> [Doc] | [Case] | {skip, Comment}
+%% Arg - doc | suite
+%% Doc - string()
+%% Case - atom()
+%% Name of a test case function.
+%% Comment - string()
+%% Description: Returns documentation/test cases in this test suite
+%% or a skip tuple if the platform is not supported.
+%%--------------------------------------------------------------------
+
+all(doc) ->
+ ["Test the http client in the intes application."];
+all(suite) ->
+ [
+ proxy_options,
+ proxy_head,
+ proxy_get,
+ proxy_trace,
+ proxy_post,
+ proxy_put,
+ proxy_delete,
+ proxy_auth,
+ proxy_headers,
+ proxy_emulate_lower_versions,
+ http_options,
+ http_head,
+ http_get,
+ http_post,
+ http_dummy_pipe,
+ http_inets_pipe,
+ http_trace,
+ http_async,
+ http_save_to_file,
+ http_save_to_file_async,
+ http_headers,
+ http_headers_dummy,
+ http_bad_response,
+ ssl_head,
+ ssl_get,
+ ssl_trace,
+ http_redirect,
+ http_redirect_loop,
+ http_internal_server_error,
+ http_userinfo,
+ http_cookie,
+ http_server_does_not_exist,
+ http_invalid_http,
+ http_emulate_lower_versions,
+ http_relaxed,
+ page_does_not_exist,
+ proxy_page_does_not_exist,
+ proxy_https_not_supported,
+ http_stream,
+ http_stream_once,
+ proxy_stream,
+ parse_url,
+ options,
+ ipv6,
+ headers_as_is,
+ tickets
+ ].
+
+%%--------------------------------------------------------------------
+%% Function: init_per_suite(Config) -> Config
+%% Config - [tuple()]
+%% A list of key/value pairs, holding the test case configuration.
+%% Description: Initiation 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) ->
+ PrivDir = ?config(priv_dir, Config),
+ DataDir = ?config(data_dir, Config),
+ ServerRoot = filename:join(PrivDir, "server_root"),
+ DocRoot = filename:join(ServerRoot, "htdocs"),
+ IpConfFile = integer_to_list(?IP_PORT) ++ ".conf",
+ SslConfFile = integer_to_list(?SSL_PORT) ++ ".conf",
+
+ setup_server_dirs(ServerRoot, DocRoot, DataDir),
+ create_config(IpConfFile, ip_comm, ?IP_PORT, PrivDir, ServerRoot,
+ DocRoot, DataDir),
+ create_config(SslConfFile, ssl, ?SSL_PORT, PrivDir, ServerRoot,
+ DocRoot, DataDir),
+
+ Cgi = case test_server:os_type() of
+ {win32, _} ->
+ filename:join([ServerRoot, "cgi-bin", "cgi_echo.exe"]);
+ _ ->
+ filename:join([ServerRoot, "cgi-bin", "cgi_echo"])
+ end,
+
+ {ok, FileInfo} = file:read_file_info(Cgi),
+ ok = file:write_file_info(Cgi, FileInfo#file_info{mode = 8#00755}),
+
+ [{server_root, ServerRoot},
+ {doc_root, DocRoot},
+ {local_port, ?IP_PORT},
+ {local_ssl_port, ?SSL_PORT} | 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) ->
+ PrivDir = ?config(priv_dir, Config),
+ inets_test_lib:del_dirs(PrivDir),
+ application:stop(inets),
+ application:stop(ssl),
+ ok.
+
+%%--------------------------------------------------------------------
+%% Function: init_per_testcase(Case, 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: Initiation 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.
+%%--------------------------------------------------------------------
+init_per_testcase(otp_8154_1 = Case, Config) ->
+ init_per_testcase(Case, 5, Config);
+init_per_testcase(Case, Config) ->
+ init_per_testcase(Case, 2, Config).
+
+init_per_testcase(Case, Timeout, Config) ->
+ io:format(user,
+ "~n~n*** INIT ~w:~w[~w] ***"
+ "~n~n", [?MODULE, Case, Timeout]),
+ PrivDir = ?config(priv_dir, Config),
+ application:stop(inets),
+ Dog = test_server:timetrap(inets_test_lib:minutes(Timeout)),
+ TmpConfig = lists:keydelete(watchdog, 1, Config),
+ IpConfFile = integer_to_list(?IP_PORT) ++ ".conf",
+ SslConfFile = integer_to_list(?SSL_PORT) ++ ".conf",
+
+ NewConfig =
+ case atom_to_list(Case) of
+ "ssl" ++ _ ->
+ application:stop(ssl),
+ TmpConfig2 =
+ lists:keydelete(local_ssl_server, 1, TmpConfig),
+ %% Will start inets
+ Server = start_http_server(PrivDir, SslConfFile),
+ [{watchdog, Dog}, {local_ssl_server, Server} | TmpConfig2];
+ "proxy_" ++ Rest ->
+ case Rest of
+ "https_not_supported" ->
+ inets:start(),
+ case (catch application:start(ssl)) of
+ ok ->
+ [{watchdog, Dog} | TmpConfig];
+ _ ->
+ [skip("SSL does not seem to be supported") |
+ TmpConfig]
+ end;
+ _ ->
+ %% We use erlang.org for the proxy tests
+ %% and after the switch to erlang-web, many
+ %% of the test cases no longer work (erlang.org
+ %% previously run on Apache).
+ %% Until we have had time to update inets
+ %% (and updated erlang.org to use that inets)
+ %% and the test cases, we simply skip the
+ %% problematic test cases.
+ %% This is not ideal, but I am busy....
+ case is_proxy_available(?PROXY, ?PROXY_PORT) of
+ true ->
+ BadCases =
+ [
+ "delete",
+ "get",
+ "head",
+ "not_modified_otp_6821",
+ "options",
+ "page_does_not_exist",
+ "post",
+ "put",
+ "stream"
+ ],
+ case lists:member(Rest, BadCases) of
+ true ->
+ [skip("TC and server not compatible") |
+ TmpConfig];
+ false ->
+ inets:start(),
+ [{watchdog, Dog} | TmpConfig]
+ end;
+ false ->
+ [skip("proxy not responding") | TmpConfig]
+ end
+ end;
+ _ ->
+ TmpConfig2 = lists:keydelete(local_server, 1, TmpConfig),
+ %% Will start inets
+ Server = start_http_server(PrivDir, IpConfFile),
+ [{watchdog, Dog}, {local_server, Server} | TmpConfig2]
+ end,
+
+ ProxyExceptions = ["localhost", ?IPV6_LOCAL_HOST],
+ http:set_options([{proxy, {{?PROXY, ?PROXY_PORT}, ProxyExceptions}}]),
+ inets:enable_trace(max, io, httpc),
+ %% inets:enable_trace(max, io, all),
+ %% snmp:set_trace([gen_tcp, inet_tcp, prim_inet]),
+ NewConfig.
+
+start_http_server(ConfDir, ConfFile) ->
+ inets_test_lib:start_http_server( filename:join(ConfDir, ConfFile) ).
+
+
+%%--------------------------------------------------------------------
+%% Function: end_per_testcase(Case, 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(http_save_to_file, Config) ->
+ PrivDir = ?config(priv_dir, Config),
+ FullPath = filename:join(PrivDir, "dummy.html"),
+ file:delete(FullPath),
+ finish(Config);
+
+end_per_testcase(_, Config) ->
+ finish(Config).
+
+finish(Config) ->
+ Dog = ?config(watchdog, Config),
+ case Dog of
+ undefined ->
+ ok;
+ _ ->
+ test_server:timetrap_cancel(Dog)
+ end,
+ (catch application:stop(inets)).
+
+
+%%-------------------------------------------------------------------------
+%% Test cases starts here.
+%%-------------------------------------------------------------------------
+
+tickets(doc) ->
+ ["."];
+tickets(suite) ->
+ [
+ hexed_query_otp_6191,
+ empty_body_otp_6243,
+ empty_response_header_otp_6830,
+ transfer_encoding_otp_6807,
+ proxy_not_modified_otp_6821,
+ no_content_204_otp_6982,
+ missing_CR_otp_7304,
+ otp_7883,
+ otp_8154,
+ otp_8106,
+ otp_8056,
+ otp_8352,
+ otp_8371,
+ otp_8739
+ ].
+
+
+%%-------------------------------------------------------------------------
+
+http_options(doc) ->
+ ["Test http options request against local server."];
+http_options(suite) ->
+ [];
+http_options(Config) when is_list(Config) ->
+ {skip, "Not supported by httpd"}.
+
+http_head(doc) ->
+ ["Test http head request against local server."];
+http_head(suite) ->
+ [];
+http_head(Config) when is_list(Config) ->
+ case ?config(local_server, Config) of
+ ok ->
+ Port = ?config(local_port, Config),
+ URL = ?URL_START ++ integer_to_list(Port) ++ "/dummy.html",
+ case http:request(head, {URL, []}, [], []) of
+ {ok, {{_,200,_}, [_ | _], []}} ->
+ ok;
+ {ok, WrongReply} ->
+ tsf({wrong_reply, WrongReply});
+ Error ->
+ tsf({failed, Error})
+ end;
+ _ ->
+ {skip, "Failed to start local http-server"}
+ end.
+%%-------------------------------------------------------------------------
+http_get(doc) ->
+ ["Test http get request against local server"];
+http_get(suite) ->
+ [];
+http_get(Config) when is_list(Config) ->
+ tsp("http_get -> entry with"
+ "~n Config: ~p", [Config]),
+ case ?config(local_server, Config) of
+ ok ->
+ tsp("local-server running"),
+ Method = get,
+ Port = ?config(local_port, Config),
+ URL = ?URL_START ++ integer_to_list(Port) ++ "/dummy.html",
+ Request = {URL, []},
+ Timeout = timer:seconds(1),
+ ConnTimeout = Timeout + timer:seconds(1),
+ HttpOptions1 = [{timeout, Timeout}, {connect_timeout, ConnTimeout}],
+ Options1 = [],
+ Body =
+ case http:request(Method, Request, HttpOptions1, Options1) of
+ {ok, {{_,200,_}, [_ | _], ReplyBody = [_ | _]}} ->
+ ReplyBody;
+ {ok, UnexpectedReply1} ->
+ tsf({unexpected_reply, UnexpectedReply1});
+ {error, _} = Error1 ->
+ tsf({bad_reply, Error1})
+ end,
+
+ %% eqvivivalent to http:request(get, {URL, []}, [], []),
+ inets_test_lib:check_body(Body),
+
+ HttpOptions2 = [],
+ Options2 = [{body_format, binary}],
+ case http:request(Method, Request, HttpOptions2, Options2) of
+ {ok, {{_,200,_}, [_ | _], Bin}} when is_binary(Bin) ->
+ ok;
+ {ok, {{_,200,_}, [_ | _], BadBin}} ->
+ tsf({body_format_not_binary, BadBin});
+ {ok, UnexpectedReply2} ->
+ tsf({unexpected_reply, UnexpectedReply2});
+ {error, _} = Error2 ->
+ tsf({bad_reply, Error2})
+ end;
+ _ ->
+ {skip, "Failed to start local http-server"}
+ end.
+
+%%-------------------------------------------------------------------------
+http_post(doc) ->
+ ["Test http post request against local server. We do in this case"
+ " only care about the client side of the the post. The server"
+ " script will not actually use the post data."];
+http_post(suite) ->
+ [];
+http_post(Config) when is_list(Config) ->
+ case ?config(local_server, Config) of
+ ok ->
+ Port = ?config(local_port, Config),
+
+ URL = case test_server:os_type() of
+ {win32, _} ->
+ ?URL_START ++ integer_to_list(Port) ++
+ "/cgi-bin/cgi_echo.exe";
+ _ ->
+ ?URL_START ++ integer_to_list(Port) ++
+ "/cgi-bin/cgi_echo"
+
+ end,
+ %% Cgi-script expects the body length to be 100
+ Body = lists:duplicate(100, "1"),
+
+ {ok, {{_,200,_}, [_ | _], [_ | _]}} =
+ http:request(post, {URL, [{"expect","100-continue"}],
+ "text/plain", Body}, [], []),
+
+ {ok, {{_,504,_}, [_ | _], []}} =
+ http:request(post, {URL, [{"expect","100-continue"}],
+ "text/plain", "foobar"}, [], []);
+ _ ->
+ {skip, "Failed to start local http-server"}
+ end.
+
+%%-------------------------------------------------------------------------
+http_emulate_lower_versions(doc) ->
+ ["Perform request as 0.9 and 1.0 clients."];
+http_emulate_lower_versions(suite) ->
+ [];
+http_emulate_lower_versions(Config) when is_list(Config) ->
+ case ?config(local_server, Config) of
+ ok ->
+ Port = ?config(local_port, Config),
+ URL = ?URL_START ++ integer_to_list(Port) ++ "/dummy.html",
+ {ok, Body0} =
+ http:request(get, {URL, []}, [{version, "HTTP/0.9"}], []),
+ inets_test_lib:check_body(Body0),
+ {ok, {{"HTTP/1.0", 200, _}, [_ | _], Body1 = [_ | _]}} =
+ http:request(get, {URL, []}, [{version, "HTTP/1.0"}], []),
+ inets_test_lib:check_body(Body1),
+ {ok, {{"HTTP/1.1", 200, _}, [_ | _], Body2 = [_ | _]}} =
+ http:request(get, {URL, []}, [{version, "HTTP/1.1"}], []),
+ inets_test_lib:check_body(Body2);
+ _->
+ {skip, "Failed to start local http-server"}
+ end.
+
+
+%%-------------------------------------------------------------------------
+
+http_relaxed(doc) ->
+ ["Test relaxed mode"];
+http_relaxed(suite) ->
+ [];
+http_relaxed(Config) when is_list(Config) ->
+ ok = http:set_options([{ipv6, disabled}]), % also test the old option
+ %% ok = http:set_options([{ipfamily, inet}]),
+ {DummyServerPid, Port} = dummy_server(self(), ipv4),
+
+ URL = ?URL_START ++ integer_to_list(Port) ++
+ "/missing_reason_phrase.html",
+
+ {error, Reason} =
+ http:request(get, {URL, []}, [{relaxed, false}], []),
+
+ test_server:format("Not relaxed: ~p~n", [Reason]),
+
+ {ok, {{_, 200, _}, [_ | _], [_ | _]}} =
+ http:request(get, {URL, []}, [{relaxed, true}], []),
+
+ DummyServerPid ! stop,
+ ok = http:set_options([{ipv6, enabled}]),
+ %% ok = http:set_options([{ipfamily, inet6fb4}]), % ********** ipfamily = inet6 *************
+ ok.
+
+
+%%-------------------------------------------------------------------------
+http_dummy_pipe(doc) ->
+ ["Test pipelining code."];
+http_dummy_pipe(suite) ->
+ [];
+http_dummy_pipe(Config) when is_list(Config) ->
+ ok = http:set_options([{ipfamily, inet}]),
+ {DummyServerPid, Port} = dummy_server(self(), ipv4),
+
+ URL = ?URL_START ++ integer_to_list(Port) ++ "/foobar.html",
+
+ test_pipeline(URL),
+
+ DummyServerPid ! stop,
+ ok = http:set_options([{ipfamily, inet6fb4}]), % ********** ipfamily = inet6 *************
+ ok.
+
+http_inets_pipe(doc) ->
+ ["Test pipelining code."];
+http_inets_pipe(suite) ->
+ [];
+http_inets_pipe(Config) when is_list(Config) ->
+
+ case ?config(local_server, Config) of
+ ok ->
+ Port = ?config(local_port, Config),
+ URL = ?URL_START ++ integer_to_list(Port) ++ "/dummy.html",
+ test_pipeline(URL);
+ _ ->
+ {skip, "Failed to start local http-server"}
+ end.
+
+test_pipeline(URL) ->
+ p("test_pipeline -> entry with"
+ "~n URL: ~p", [URL]),
+
+ http:set_options([{pipeline_timeout, 50000}]),
+
+ p("test_pipeline -> issue (async) request 1"),
+ {ok, RequestId1} =
+ http:request(get, {URL, []}, [], [{sync, false}]),
+ test_server:format("RequestId1: ~p~n", [RequestId1]),
+ p("test_pipeline -> RequestId1: ~p", [RequestId1]),
+
+ %% Make sure pipeline is initiated
+ p("test_pipeline -> sleep some", []),
+ test_server:sleep(4000),
+
+ p("test_pipeline -> issue (async) request 2"),
+ {ok, RequestId2} =
+ http:request(get, {URL, []}, [], [{sync, false}]),
+ tsp("RequestId2: ~p", [RequestId2]),
+ p("test_pipeline -> RequestId2: ~p", [RequestId2]),
+
+ p("test_pipeline -> issue (sync) request 3"),
+ {ok, {{_,200,_}, [_ | _], [_ | _]}} =
+ http:request(get, {URL, []}, [], []),
+
+ p("test_pipeline -> expect reply for (async) request 1 or 2"),
+ receive
+ {http, {RequestId1, {{_, 200, _}, _, _}}} ->
+ p("test_pipeline -> received reply for (async) request 1 - now wait for 2"),
+ receive
+ {http, {RequestId2, {{_, 200, _}, _, _}}} ->
+ p("test_pipeline -> received reply for (async) request 2"),
+ ok;
+ {http, Msg1} ->
+ test_server:fail(Msg1)
+ end;
+ {http, {RequestId2, {{_, 200, _}, _, _}}} ->
+ io:format("test_pipeline -> received reply for (async) request 2 - now wait for 1"),
+ receive
+ {http, {RequestId1, {{_, 200, _}, _, _}}} ->
+ io:format("test_pipeline -> received reply for (async) request 1"),
+ ok;
+ {http, Msg2} ->
+ test_server:fail(Msg2)
+ end;
+ {http, Msg3} ->
+ test_server:fail(Msg3)
+ after 60000 ->
+ receive Any1 ->
+ tsp("received crap after timeout: ~n ~p", [Any1]),
+ test_server:fail({error, {timeout, Any1}})
+ end
+ end,
+
+ p("test_pipeline -> sleep some"),
+ test_server:sleep(4000),
+
+ p("test_pipeline -> issue (async) request 4"),
+ {ok, RequestId3} =
+ http:request(get, {URL, []}, [], [{sync, false}]),
+ tsp("RequestId3: ~p", [RequestId3]),
+ p("test_pipeline -> RequestId3: ~p", [RequestId3]),
+
+ p("test_pipeline -> issue (async) request 5"),
+ {ok, RequestId4} =
+ http:request(get, {URL, []}, [], [{sync, false}]),
+ tsp("RequestId4: ~p~n", [RequestId4]),
+ p("test_pipeline -> RequestId4: ~p", [RequestId4]),
+
+ p("test_pipeline -> cancel (async) request 4"),
+ ok = http:cancel_request(RequestId3),
+
+ p("test_pipeline -> expect *no* reply for cancelled (async) request 4 (for 3 secs)"),
+ receive
+ {http, {RequestId3, _}} ->
+ test_server:fail(http_cancel_request_failed)
+ after 3000 ->
+ ok
+ end,
+
+ p("test_pipeline -> expect reply for (async) request 4"),
+ Body =
+ receive
+ {http, {RequestId4, {{_, 200, _}, _, BinBody4}}} = Res ->
+ p("test_pipeline -> received reply for (async) request 5"),
+ tsp("Receive : ~p", [Res]),
+ BinBody4;
+ {http, Msg4} ->
+ test_server:fail(Msg4)
+ after 60000 ->
+ receive Any2 ->
+ tsp("received crap after timeout: ~n ~p", [Any2]),
+ test_server:fail({error, {timeout, Any2}})
+ end
+ end,
+
+ p("test_pipeline -> check reply for (async) request 5"),
+ inets_test_lib:check_body(binary_to_list(Body)),
+
+ p("test_pipeline -> ensure no unexpected incomming"),
+ receive
+ {http, Any} ->
+ test_server:fail({unexpected_message, Any})
+ after 500 ->
+ ok
+ end,
+
+ p("test_pipeline -> done"),
+ ok.
+
+
+
+%%-------------------------------------------------------------------------
+http_trace(doc) ->
+ ["Perform a TRACE request that goes through a proxy."];
+http_trace(suite) ->
+ [];
+http_trace(Config) when is_list(Config) ->
+ case ?config(local_server, Config) of
+ ok ->
+ Port = ?config(local_port, Config),
+ URL = ?URL_START ++ integer_to_list(Port) ++ "/dummy.html",
+ case http:request(trace, {URL, []}, [], []) of
+ {ok, {{_,200,_}, [_ | _], "TRACE /dummy.html" ++ _}} ->
+ ok;
+ {ok, {{_,200,_}, [_ | _], WrongBody}} ->
+ test_server:fail({wrong_body, WrongBody});
+ {ok, WrongReply} ->
+ test_server:fail({wrong_reply, WrongReply});
+ Error ->
+ test_server:fail({failed, Error})
+ end;
+ _ ->
+ {skip, "Failed to start local http-server"}
+ end.
+%%-------------------------------------------------------------------------
+http_async(doc) ->
+ ["Test an asynchrony http request."];
+http_async(suite) ->
+ [];
+http_async(Config) when is_list(Config) ->
+ case ?config(local_server, Config) of
+ ok ->
+ Port = ?config(local_port, Config),
+ URL = ?URL_START ++ integer_to_list(Port) ++ "/dummy.html",
+ {ok, RequestId} =
+ http:request(get, {URL, []}, [], [{sync, false}]),
+
+ Body =
+ receive
+ {http, {RequestId, {{_, 200, _}, _, BinBody}}} ->
+ BinBody;
+ {http, Msg} ->
+ test_server:fail(Msg)
+ end,
+
+ inets_test_lib:check_body(binary_to_list(Body)),
+
+ {ok, NewRequestId} =
+ http:request(get, {URL, []}, [], [{sync, false}]),
+ ok = http:cancel_request(NewRequestId),
+ receive
+ {http, {NewRequestId, _NewResult}} ->
+ test_server:fail(http_cancel_request_failed)
+ after 3000 ->
+ ok
+ end;
+ _ ->
+ {skip, "Failed to start local http-server"}
+ end.
+
+%%-------------------------------------------------------------------------
+http_save_to_file(doc) ->
+ ["Test to save the http body to a file"];
+http_save_to_file(suite) ->
+ [];
+http_save_to_file(Config) when is_list(Config) ->
+ case ?config(local_server, Config) of
+ ok ->
+ PrivDir = ?config(priv_dir, Config),
+ FilePath = filename:join(PrivDir, "dummy.html"),
+ Port = ?config(local_port, Config),
+ URL = ?URL_START ++ integer_to_list(Port) ++ "/dummy.html",
+ {ok, saved_to_file}
+ = http:request(get, {URL, []}, [], [{stream, FilePath}]),
+ {ok, Bin} = file:read_file(FilePath),
+ {ok, {{_,200,_}, [_ | _], Body}} = http:request(URL),
+ Bin == Body;
+ _ ->
+ {skip, "Failed to start local http-server"}
+ end.
+
+
+%%-------------------------------------------------------------------------
+http_save_to_file_async(doc) ->
+ ["Test to save the http body to a file"];
+http_save_to_file_async(suite) ->
+ [];
+http_save_to_file_async(Config) when is_list(Config) ->
+ case ?config(local_server, Config) of
+ ok ->
+ PrivDir = ?config(priv_dir, Config),
+ FilePath = filename:join(PrivDir, "dummy.html"),
+ Port = ?config(local_port, Config),
+ URL = ?URL_START ++ integer_to_list(Port) ++ "/dummy.html",
+ {ok, RequestId} = http:request(get, {URL, []}, [],
+ [{stream, FilePath},
+ {sync, false}]),
+ receive
+ {http, {RequestId, saved_to_file}} ->
+ ok;
+ {http, Msg} ->
+ test_server:fail(Msg)
+ end,
+
+ {ok, Bin} = file:read_file(FilePath),
+ {ok, {{_,200,_}, [_ | _], Body}} = http:request(URL),
+ Bin == Body;
+ _ ->
+ {skip, "Failed to start local http-server"}
+ end.
+%%-------------------------------------------------------------------------
+http_headers(doc) ->
+ ["Use as many request headers as possible not used in proxy_headers"];
+http_headers(suite) ->
+ [];
+http_headers(Config) when is_list(Config) ->
+
+ case ?config(local_server, Config) of
+ ok ->
+ Port = ?config(local_port, Config),
+ URL = ?URL_START ++ integer_to_list(Port) ++ "/dummy.html",
+ DocRoot = ?config(doc_root, Config),
+ {ok, FileInfo} =
+ file:read_file_info(filename:join([DocRoot,"dummy.html"])),
+ CreatedSec =
+ calendar:datetime_to_gregorian_seconds(
+ FileInfo#file_info.mtime),
+
+ Mod = httpd_util:rfc1123_date(
+ calendar:gregorian_seconds_to_datetime(
+ CreatedSec-1)),
+
+ Date = httpd_util:rfc1123_date({date(), time()}),
+
+ {ok, {{_,200,_}, [_ | _], [_ | _]}} =
+ http:request(get, {URL, [{"If-Modified-Since",
+ Mod},
+ {"From","[email protected]"},
+ {"Date", Date}
+ ]}, [], []),
+
+ Mod1 = httpd_util:rfc1123_date(
+ calendar:gregorian_seconds_to_datetime(
+ CreatedSec+1)),
+
+ {ok, {{_,200,_}, [_ | _], [_ | _]}} =
+ http:request(get, {URL, [{"If-UnModified-Since",
+ Mod1}
+ ]}, [], []),
+
+ Tag = httpd_util:create_etag(FileInfo),
+
+
+ {ok, {{_,200,_}, [_ | _], [_ | _]}} =
+ http:request(get, {URL, [{"If-Match",
+ Tag}
+ ]}, [], []),
+
+ {ok, {{_,200,_}, [_ | _], _}} =
+ http:request(get, {URL, [{"If-None-Match",
+ "NotEtag,NeihterEtag"},
+ {"Connection", "Close"}
+ ]}, [], []),
+ ok;
+ _ ->
+ {skip, "Failed to start local http-server"}
+ end.
+
+%%-------------------------------------------------------------------------
+http_headers_dummy(doc) ->
+ ["Test the code for handling headers we do not want/can send "
+ "to a real server. Note it is not logical to send"
+ "all of these headers together, we only want to test that"
+ "the code for handling headers will not crash."];
+http_headers_dummy(suite) ->
+ [];
+http_headers_dummy(Config) when is_list(Config) ->
+ ok = http:set_options([{ipfamily, inet}]),
+ {DummyServerPid, Port} = dummy_server(self(), ipv4),
+
+ URL = ?URL_START ++ integer_to_list(Port) ++ "/dummy_headers.html",
+
+ Foo = http_chunk:encode("foobar") ++
+ binary_to_list(http_chunk:encode_last()),
+ FooBar = Foo ++ "\r\n\r\nOther:inets_test\r\n\r\n",
+
+ UserPasswd = base64:encode_to_string("Alladin:Sesame"),
+ Auth = "Basic " ++ UserPasswd,
+
+ %% The dummy server will ignore the headers, we only want to test
+ %% that the client header-handling code. This would not
+ %% be a vaild http-request!
+ {ok, {{_,200,_}, [_ | _], [_|_]}} =
+ http:request(post,
+ {URL,
+ [{"Via",
+ "1.0 fred, 1.1 nowhere.com (Apache/1.1)"},
+ {"Warning","1#pseudonym foobar"},
+ {"Vary","*"},
+ {"Upgrade","HTTP/2.0"},
+ {"Pragma", "1#no-cache"},
+ {"Cache-Control", "no-cache"},
+ {"Connection", "close"},
+ {"Date", "Sat, 29 Oct 1994 19:43:31 GMT"},
+ {"Accept", " text/plain; q=0.5, text/html"},
+ {"Accept-Language", "en"},
+ {"Accept-Encoding","chunked"},
+ {"Accept-Charset", "ISO8859-1"},
+ {"Authorization", Auth},
+ {"Expect", "1#100-continue"},
+ {"User-Agent","inets"},
+ {"Transfer-Encoding","chunked"},
+ {"Range", " bytes=0-499"},
+ {"If-Range", "Sat, 29 Oct 1994 19:43:31 GMT"},
+ {"If-Match", "*"},
+ {"Content-Type", "text/plain"},
+ {"Content-Encoding", "chunked"},
+ {"Content-Length", "6"},
+ {"Content-Language", "en"},
+ {"Content-Location", "http://www.foobar.se"},
+ {"Content-MD5",
+ "104528739076276072743283077410617235478"},
+ {"Content-Range", "bytes 0-499/1234"},
+ {"Allow", "GET"},
+ {"Proxy-Authorization", Auth},
+ {"Expires", "Sat, 29 Oct 1994 19:43:31 GMT"},
+ {"Upgrade", "HTTP/2.0"},
+ {"Last-Modified", "Sat, 29 Oct 1994 19:43:31 GMT"},
+ {"Trailer","1#User-Agent"}
+ ], "text/plain", FooBar},
+ [], []),
+ DummyServerPid ! stop,
+ ok = http:set_options([{ipfamily, inet6fb4}]), % ********** ipfamily = inet6 *************
+ ok.
+
+
+%%-------------------------------------------------------------------------
+http_bad_response(doc) ->
+ ["Test what happens when the server does not follow the protocol"];
+http_bad_response(suite) ->
+ [];
+http_bad_response(Config) when is_list(Config) ->
+ ok = http:set_options([{ipfamily, inet}]),
+ {DummyServerPid, Port} = dummy_server(self(), ipv4),
+
+ URL = ?URL_START ++ integer_to_list(Port) ++ "/missing_crlf.html",
+
+ URL1 = ?URL_START ++ integer_to_list(Port) ++ "/wrong_statusline.html",
+
+ {error, timeout} = http:request(get, {URL, []}, [{timeout, 400}], []),
+
+ {error, Reason} = http:request(URL1),
+
+ test_server:format("Wrong Statusline: ~p~n", [Reason]),
+
+ DummyServerPid ! stop,
+ ok = http:set_options([{ipfamily, inet6fb4}]), % ********** ipfamily = inet6 *************
+ ok.
+
+
+%%-------------------------------------------------------------------------
+ssl_head(doc) ->
+ ["Same as http_head/1 but over ssl sockets."];
+ssl_head(suite) ->
+ [];
+ssl_head(Config) when is_list(Config) ->
+ case ?config(local_ssl_server, Config) of
+ ok ->
+ DataDir = ?config(data_dir, Config),
+ Port = ?config(local_ssl_port, Config),
+ URL = ?SSL_URL_START ++ integer_to_list(Port) ++ "/dummy.html",
+ CertFile = filename:join(DataDir, "ssl_client_cert.pem"),
+ SSLOptions = [{certfile, CertFile}, {keyfile, CertFile}],
+ {ok, {{_,200, _}, [_ | _], []}} =
+ http:request(head, {URL, []}, [{ssl, SSLOptions}], []);
+ {ok, _} ->
+ {skip, "Failed to start local http-server"};
+ _ ->
+ {skip, "Failed to start SSL"}
+ end.
+%%-------------------------------------------------------------------------
+ssl_get(doc) ->
+ ["Same as http_get/1 but over ssl sockets."];
+ssl_get(suite) ->
+ [];
+ssl_get(Config) when is_list(Config) ->
+ case ?config(local_ssl_server, Config) of
+ ok ->
+ DataDir = ?config(data_dir, Config),
+ Port = ?config(local_ssl_port, Config),
+ URL = ?SSL_URL_START ++ integer_to_list(Port) ++ "/dummy.html",
+ CertFile = filename:join(DataDir, "ssl_client_cert.pem"),
+ SSLOptions = [{certfile, CertFile}, {keyfile, CertFile}],
+ {ok, {{_,200, _}, [_ | _], Body = [_ | _]}} =
+ http:request(get, {URL, []}, [{ssl, SSLOptions}], []),
+ inets_test_lib:check_body(Body);
+ {ok, _} ->
+ {skip, "Failed to start local http-server"};
+ _ ->
+ {skip, "Failed to start SSL"}
+ end.
+%%-------------------------------------------------------------------------
+ssl_trace(doc) ->
+ ["Same as http_trace/1 but over ssl sockets."];
+ssl_trace(suite) ->
+ [];
+ssl_trace(Config) when is_list(Config) ->
+ case ?config(local_ssl_server, Config) of
+ ok ->
+ DataDir = ?config(data_dir, Config),
+ Port = ?config(local_ssl_port, Config),
+ URL = ?SSL_URL_START ++ integer_to_list(Port) ++ "/dummy.html",
+ CertFile = filename:join(DataDir, "ssl_client_cert.pem"),
+ SSLOptions = [{certfile, CertFile}, {keyfile, CertFile}],
+ case http:request(trace, {URL, []}, [{ssl, SSLOptions}], []) of
+ {ok, {{_,200, _}, [_ | _], "TRACE /dummy.html" ++ _}} ->
+ ok;
+ {ok, {{_,200,_}, [_ | _], WrongBody}} ->
+ test_server:fail({wrong_body, WrongBody});
+ {ok, WrongReply} ->
+ test_server:fail({wrong_reply, WrongReply});
+ Error ->
+ test_server:fail({failed, Error})
+ end;
+ {ok, _} ->
+ {skip, "Failed to start local http-server"};
+ _ ->
+ {skip, "Failed to start SSL"}
+ end.
+%%-------------------------------------------------------------------------
+http_redirect(doc) ->
+ ["Test redirect with dummy server as httpd does not implement"
+ " server redirect"];
+http_redirect(suite) ->
+ [];
+http_redirect(Config) when is_list(Config) ->
+ tsp("http_redirect -> entry with"
+ "~n Config: ~p", [Config]),
+ case ?config(local_server, Config) of
+ ok ->
+ tsp("http_redirect -> set ipfamily option to inet"),
+ ok = http:set_options([{ipfamily, inet}]),
+
+ tsp("http_redirect -> start dummy server inet"),
+ {DummyServerPid, Port} = dummy_server(self(), ipv4),
+ tsp("http_redirect -> server port = ~p", [Port]),
+
+ URL300 = ?URL_START ++ integer_to_list(Port) ++ "/300.html",
+
+ tsp("http_redirect -> issue request 1: "
+ "~n ~p", [URL300]),
+ {ok, {{_,200,_}, [_ | _], [_|_]}}
+ = http:request(get, {URL300, []}, [], []),
+
+ tsp("http_redirect -> issue request 2: "
+ "~n ~p", [URL300]),
+ {ok, {{_,300,_}, [_ | _], _}} =
+ http:request(get, {URL300, []}, [{autoredirect, false}], []),
+
+ URL301 = ?URL_START ++ integer_to_list(Port) ++ "/301.html",
+
+ tsp("http_redirect -> issue request 3: "
+ "~n ~p", [URL301]),
+ {ok, {{_,200,_}, [_ | _], [_|_]}}
+ = http:request(get, {URL301, []}, [], []),
+
+ tsp("http_redirect -> issue request 4: "
+ "~n ~p", [URL301]),
+ {ok, {{_,200,_}, [_ | _], []}}
+ = http:request(head, {URL301, []}, [], []),
+
+ tsp("http_redirect -> issue request 5: "
+ "~n ~p", [URL301]),
+ {ok, {{_,301,_}, [_ | _], [_|_]}}
+ = http:request(post, {URL301, [],"text/plain", "foobar"},
+ [], []),
+
+ URL302 = ?URL_START ++ integer_to_list(Port) ++ "/302.html",
+
+ tsp("http_redirect -> issue request 6: "
+ "~n ~p", [URL302]),
+ {ok, {{_,200,_}, [_ | _], [_|_]}}
+ = http:request(get, {URL302, []}, [], []),
+ case http:request(get, {URL302, []}, [], []) of
+ {ok, Reply7} ->
+ case Reply7 of
+ {{_,200,_}, [_ | _], [_|_]} ->
+ tsp("http_redirect -> "
+ "expected reply for request 7"),
+ ok;
+ {StatusLine, Headers, Body} ->
+ tsp("http_redirect -> "
+ "unexpected reply for request 7: "
+ "~n StatusLine: ~p"
+ "~n Headers: ~p"
+ "~n Body: ~p",
+ [StatusLine, Headers, Body]),
+ tsf({unexpected_reply, Reply7})
+ end;
+ Error7 ->
+ tsp("http_redirect -> "
+ "unexpected result for request 7: "
+ "~n Error7: ~p",
+ [Error7]),
+ tsf({unexpected_result, Error7})
+ end,
+
+ tsp("http_redirect -> issue request 7: "
+ "~n ~p", [URL302]),
+ {ok, {{_,200,_}, [_ | _], []}}
+ = http:request(head, {URL302, []}, [], []),
+
+ tsp("http_redirect -> issue request 8: "
+ "~n ~p", [URL302]),
+ {ok, {{_,302,_}, [_ | _], [_|_]}}
+ = http:request(post, {URL302, [],"text/plain", "foobar"},
+ [], []),
+
+ URL307 = ?URL_START ++ integer_to_list(Port) ++ "/307.html",
+
+ tsp("http_redirect -> issue request 9: "
+ "~n ~p", [URL307]),
+ {ok, {{_,200,_}, [_ | _], [_|_]}}
+ = http:request(get, {URL307, []}, [], []),
+
+ tsp("http_redirect -> issue request 10: "
+ "~n ~p", [URL307]),
+ {ok, {{_,200,_}, [_ | _], []}}
+ = http:request(head, {URL307, []}, [], []),
+
+ tsp("http_redirect -> issue request 11: "
+ "~n ~p", [URL307]),
+ {ok, {{_,307,_}, [_ | _], [_|_]}}
+ = http:request(post, {URL307, [],"text/plain", "foobar"},
+ [], []),
+
+ tsp("http_redirect -> stop dummy server"),
+ DummyServerPid ! stop,
+ tsp("http_redirect -> reset ipfamily option (to inet6fb4)"),
+ ok = http:set_options([{ipfamily, inet6fb4}]), % ********** ipfamily = inet6 *************
+ tsp("http_redirect -> done"),
+ ok;
+
+ _ ->
+ {skip, "Failed to start local http-server"}
+ end.
+
+
+
+%%-------------------------------------------------------------------------
+http_redirect_loop(doc) ->
+ ["Test redirect loop detection"];
+http_redirect_loop(suite) ->
+ [];
+http_redirect_loop(Config) when is_list(Config) ->
+ ok = http:set_options([{ipfamily, inet}]),
+ {DummyServerPid, Port} = dummy_server(self(), ipv4),
+
+ URL = ?URL_START ++ integer_to_list(Port) ++ "/redirectloop.html",
+
+ {ok, {{_,300,_}, [_ | _], _}}
+ = http:request(get, {URL, []}, [], []),
+ DummyServerPid ! stop,
+ ok = http:set_options([{ipfamily, inet6fb4}]), % ********** ipfamily = inet6 *************
+ ok.
+
+%%-------------------------------------------------------------------------
+http_internal_server_error(doc) ->
+ ["Test 50X codes"];
+http_internal_server_error(suite) ->
+ [];
+http_internal_server_error(Config) when is_list(Config) ->
+ ok = http:set_options([{ipfamily, inet}]),
+ {DummyServerPid, Port} = dummy_server(self(), ipv4),
+
+ URL500 = ?URL_START ++ integer_to_list(Port) ++ "/500.html",
+
+ {ok, {{_,500,_}, [_ | _], _}}
+ = http:request(get, {URL500, []}, [], []),
+
+
+ URL503 = ?URL_START ++ integer_to_list(Port) ++ "/503.html",
+
+ %% Used to be able to make the service available after retry.
+ ets:new(unavailable, [named_table, public, set]),
+ ets:insert(unavailable, {503, unavailable}),
+
+ {ok, {{_,200, _}, [_ | _], [_|_]}} =
+ http:request(get, {URL503, []}, [], []),
+
+ ets:insert(unavailable, {503, long_unavailable}),
+
+ {ok, {{_,503, _}, [_ | _], [_|_]}} =
+ http:request(get, {URL503, []}, [], []),
+
+ ets:delete(unavailable),
+ DummyServerPid ! stop,
+ ok = http:set_options([{ipfamily, inet6fb4}]), % ********** ipfamily = inet6 *************
+ ok.
+
+
+%%-------------------------------------------------------------------------
+http_userinfo(doc) ->
+ ["Test user info e.i. http://user:passwd@host:port/"];
+http_userinfo(suite) ->
+ [];
+http_userinfo(Config) when is_list(Config) ->
+ ok = http:set_options([{ipfamily, inet}]),
+
+ {DummyServerPid, Port} = dummy_server(self(), ipv4),
+
+ URLAuth = "http://alladin:sesame@localhost:"
+ ++ integer_to_list(Port) ++ "/userinfo.html",
+
+ {ok, {{_,200,_}, [_ | _], _}}
+ = http:request(get, {URLAuth, []}, [], []),
+
+ URLUnAuth = "http://alladin:foobar@localhost:"
+ ++ integer_to_list(Port) ++ "/userinfo.html",
+
+ {ok, {{_,401, _}, [_ | _], _}} =
+ http:request(get, {URLUnAuth, []}, [], []),
+
+ DummyServerPid ! stop,
+ ok = http:set_options([{ipfamily, inet6fb4}]), % ********** ipfamily = inet6 *************
+ ok.
+
+
+%%-------------------------------------------------------------------------
+http_cookie(doc) ->
+ ["Test cookies."];
+http_cookie(suite) ->
+ [];
+http_cookie(Config) when is_list(Config) ->
+ ok = http:set_options([{cookies, enabled}, {ipfamily, inet}]),
+ {DummyServerPid, Port} = dummy_server(self(), ipv4),
+
+ URLStart = ?URL_START
+ ++ integer_to_list(Port),
+
+ URLCookie = URLStart ++ "/cookie.html",
+
+ {ok, {{_,200,_}, [_ | _], [_|_]}}
+ = http:request(get, {URLCookie, []}, [], []),
+
+ ets:new(cookie, [named_table, public, set]),
+ ets:insert(cookie, {cookies, true}),
+
+ {ok, {{_,200,_}, [_ | _], [_|_]}}
+ = http:request(get, {URLStart ++ "/", []}, [], []),
+
+ ets:delete(cookie),
+
+ ok = http:set_options([{cookies, disabled}, {ipfamily, inet6fb4}]), % ********** ipfamily = inet6 *************
+ DummyServerPid ! stop,
+ ok = http:set_options([{ipfamily, inet6fb4}]), % ********** ipfamily = inet6************
+ ok.
+
+%%-------------------------------------------------------------------------
+proxy_options(doc) ->
+ ["Perform a OPTIONS request that goes through a proxy."];
+proxy_options(suite) ->
+ [];
+proxy_options(Config) when is_list(Config) ->
+ case ?config(skip, Config) of
+ undefined ->
+ Command =
+ fun() -> http:request(options, {?PROXY_URL, []}, [], []) end,
+ Verify =
+ fun({ok, {{_,200,_}, Headers, _}}) ->
+ case lists:keysearch("allow", 1, Headers) of
+ {value, {"allow", _}} ->
+ ok;
+ _ ->
+ tsf(http_options_request_failed)
+ end;
+ ({ok, {{_, 501, "Not Implemented"}, _Hdrs, _}}) ->
+ skip(options_not_implemented_in_server_501_ni);
+ ({ok, Unexpected}) ->
+ tsf({unexpected_success, Unexpected});
+ (Unexpected) ->
+ tsf({unexpected_result, Unexpected})
+ end,
+ expect(Command, Verify);
+ Reason ->
+ skip(Reason)
+ end.
+
+
+%%-------------------------------------------------------------------------
+proxy_head(doc) ->
+ ["Perform a HEAD request that goes through a proxy."];
+proxy_head(suite) ->
+ [];
+proxy_head(Config) when is_list(Config) ->
+ tsp("proxy_head -> entry with"
+ "~n Config: ~p", [Config]),
+ case ?config(skip, Config) of
+ undefined ->
+ Command =
+ fun() -> http:request(head, {?PROXY_URL, []}, [], []) end,
+ Verify =
+ fun({ok, {{_,200, _}, [_ | _], []}}) ->
+ ok;
+ ({ok, {{_,503,"Service Unavailable"}, [_ | _], []}}) ->
+ skip(head_not_implemented_in_server_503_su);
+ ({ok, Result}) ->
+ tsf({unexpected_success, Result});
+ (Unexpected) ->
+ tsf({unexpected_result, Unexpected})
+ end,
+ expect(Command, Verify);
+ Reason ->
+ skip(Reason)
+ end.
+
+
+%%-------------------------------------------------------------------------
+
+proxy_get(doc) ->
+ ["Perform a GET request that goes through a proxy."];
+proxy_get(suite) ->
+ [];
+proxy_get(Config) when is_list(Config) ->
+ case ?config(skip, Config) of
+ undefined ->
+ case http:request(get, {?PROXY_URL, []}, [], []) of
+ {ok, {{_,200,_}, [_ | _], Body = [_ | _]}} ->
+ inets_test_lib:check_body(Body);
+ Unexpected ->
+ test_server:fail({unexpected_result, Unexpected})
+ end;
+ Reason ->
+ {skip, Reason}
+ end.
+
+
+%%-------------------------------------------------------------------------
+
+proxy_emulate_lower_versions(doc) ->
+ ["Perform requests as 0.9 and 1.0 clients."];
+proxy_emulate_lower_versions(suite) ->
+ [];
+proxy_emulate_lower_versions(Config) when is_list(Config) ->
+ case ?config(skip, Config) of
+ undefined ->
+ Result09 = pelv_get("HTTP/0.9"),
+ case Result09 of
+ {ok, [_| _] = Body0} ->
+ inets_test_lib:check_body(Body0),
+ ok;
+ _ ->
+ tsf({unexpected_result, "HTTP/0.9", Result09})
+ end,
+
+ %% We do not check the version here as many servers
+ %% do not behave according to the rfc and send
+ %% 1.1 in its response.
+ Result10 = pelv_get("HTTP/1.0"),
+ case Result10 of
+ {ok,{{_, 200, _}, [_ | _], Body1 = [_ | _]}} ->
+ inets_test_lib:check_body(Body1),
+ ok;
+ _ ->
+ tsf({unexpected_result, "HTTP/1.0", Result10})
+ end,
+
+ Result11 = pelv_get("HTTP/1.1"),
+ case Result11 of
+ {ok, {{"HTTP/1.1", 200, _}, [_ | _], Body2 = [_ | _]}} ->
+ inets_test_lib:check_body(Body2);
+ _ ->
+ tsf({unexpected_result, "HTTP/1.1", Result11})
+ end;
+
+ Reason ->
+ {skip, Reason}
+ end.
+
+pelv_get(Version) ->
+ http:request(get, {?PROXY_URL, []}, [{version, Version}], []).
+
+
+%%-------------------------------------------------------------------------
+
+proxy_trace(doc) ->
+ ["Perform a TRACE request that goes through a proxy."];
+proxy_trace(suite) ->
+ [];
+proxy_trace(Config) when is_list(Config) ->
+ %%{ok, {{_,200,_}, [_ | _], "TRACE " ++ _}} =
+ %% http:request(trace, {?PROXY_URL, []}, [], []),
+ skip("HTTP TRACE is no longer allowed on the ?PROXY_URL server due "
+ "to security reasons").
+
+
+%%-------------------------------------------------------------------------
+
+proxy_post(doc) ->
+ ["Perform a POST request that goes through a proxy. Note the server"
+ " will reject the request this is a test of the sending of the"
+ " request."];
+proxy_post(suite) ->
+ [];
+proxy_post(Config) when is_list(Config) ->
+ %% After the switch to the erlang.org app,
+ %% the post will succeed, so we skip this
+ %% until we can find a new way of testing
+ %% this.
+ %% case ?config(skip, Config) of
+ %% undefined ->
+ %% Command =
+ %% fun() ->
+ %% http:request(post, {?PROXY_URL, [],
+ %% "text/plain", "foobar"}, [],[])
+ %% end,
+ %% Verify =
+ %% fun({ok, {{_,405,_}, [_ | _], [_ | _]}}) ->
+ %% ok;
+ %% ({ok, Result}) ->
+ %% tsf({unexpected_success, Result});
+ %% (Unexpected) ->
+ %% tsf({unexpected_result, Unexpected})
+ %% end,
+ %% expect(Command, Verify);
+ %% Reason ->
+ %% skip(Reason)
+ %% end.
+ skip("temporary skip").
+
+
+%%-------------------------------------------------------------------------
+
+proxy_put(doc) ->
+ ["Perform a PUT request that goes through a proxy. Note the server"
+ " will reject the request this is a test of the sending of the"
+ " request."];
+proxy_put(suite) ->
+ [];
+proxy_put(Config) when is_list(Config) ->
+ %% After the switch to the erlang.org app,
+ %% the post will succeed, so we skip this
+ %% until we can find a new way of testing
+ %% this.
+ %% case ?config(skip, Config) of
+ %% undefined ->
+ %% case http:request(put, {"http://www.erlang.org/foobar.html", [],
+ %% "html", "<html> <body><h1> foo </h1>"
+ %% "<p>bar</p> </body></html>"}, [], []) of
+ %% {ok, {{_,405,_}, [_ | _], [_ | _]}} ->
+ %% ok;
+ %% Unexpected ->
+ %% test_server:fail({unexpected_result, Unexpected})
+ %% end;
+ %% Reason ->
+ %% {skip, Reason}
+ %% end.
+ skip("temporary skip").
+
+
+%%-------------------------------------------------------------------------
+
+proxy_delete(doc) ->
+ ["Perform a DELETE request that goes through a proxy. Note the server"
+ " will reject the request this is a test of the sending of the"
+ " request. But as the file does not exist the return code will"
+ " be 404 not found."];
+proxy_delete(suite) ->
+ [];
+proxy_delete(Config) when is_list(Config) ->
+ %% After the switch to the erlang.org app,
+ %% the post will succeed, so we skip this
+ %% until we can find a new way of testing
+ %% this.
+ %% case ?config(skip, Config) of
+ %% undefined ->
+ %% URL = ?PROXY_URL ++ "/foobar.html",
+ %% Command = fun() -> http:request(delete, {URL, []}, [], []) end,
+ %% Verify =
+ %% fun({ok, {{_,404,_}, [_ | _], [_ | _]}}) ->
+ %% ok;
+ %% ({ok, Result}) ->
+ %% tsf({unexpected_success, Result});
+ %% (Unexpected) ->
+ %% tsf({unexpected_result, Unexpected})
+ %% end,
+ %% expect(Command, Verify);
+
+ %% Reason ->
+ %% skip(Reason)
+ %% end.
+ skip("temporary skip").
+
+
+%%-------------------------------------------------------------------------
+
+proxy_headers(doc) ->
+ ["Use as many request headers as possible"];
+proxy_headers(suite) ->
+ [];
+proxy_headers(Config) when is_list(Config) ->
+ case ?config(skip, Config) of
+ undefined ->
+ {ok, {{_,200,_}, [_ | _], [_ | _]}}
+ = http:request(get, {?PROXY_URL,
+ [
+ {"Accept",
+ "text/*, text/html,"
+ " text/html;level=1,"
+ " */*"},
+ {"Accept-Charset",
+ "iso-8859-5, unicode-1-1;"
+ "q=0.8"},
+ {"Accept-Encoding", "*"},
+ {"Accept-Language",
+ "sv, en-gb;q=0.8,"
+ " en;q=0.7"},
+ {"User-Agent", "inets"},
+ {"Max-Forwards","5"},
+ {"Referer",
+ "http://otp.ericsson.se:8000"
+ "/product/internal"}
+ ]}, [], []),
+ ok;
+ Reason ->
+ {skip, Reason}
+ end.
+
+%%-------------------------------------------------------------------------
+proxy_auth(doc) ->
+ ["Test the code for sending of proxy authorization."];
+proxy_auth(suite) ->
+ [];
+proxy_auth(Config) when is_list(Config) ->
+ %% Our proxy seems to ignore the header, however our proxy
+ %% does not requirer an auth header, but we want to know
+ %% atleast the code for sending the header does not crash!
+ case ?config(skip, Config) of
+ undefined ->
+ case http:request(get, {?PROXY_URL, []},
+ [{proxy_auth, {"foo", "bar"}}], []) of
+ {ok, {{_,200, _}, [_ | _], [_|_]}} ->
+ ok;
+ Unexpected ->
+ test_server:fail({unexpected_result, Unexpected})
+ end;
+ Reason ->
+ {skip, Reason}
+ end.
+
+
+%%-------------------------------------------------------------------------
+http_server_does_not_exist(doc) ->
+ ["Test that we get an error message back when the server "
+ "does note exist."];
+http_server_does_not_exist(suite) ->
+ [];
+http_server_does_not_exist(Config) when is_list(Config) ->
+ {error, _} =
+ http:request(get, {"http://localhost:" ++
+ integer_to_list(?NOT_IN_USE_PORT)
+ ++ "/", []},[], []),
+ ok.
+
+
+%%-------------------------------------------------------------------------
+page_does_not_exist(doc) ->
+ ["Test that we get a 404 when the page is not found."];
+page_does_not_exist(suite) ->
+ [];
+page_does_not_exist(Config) when is_list(Config) ->
+ Port = ?config(local_port, Config),
+ URL = ?URL_START ++ integer_to_list(Port) ++ "/doesnotexist.html",
+ {ok, {{_,404,_}, [_ | _], [_ | _]}}
+ = http:request(get, {URL, []}, [], []),
+ ok.
+
+
+%%-------------------------------------------------------------------------
+proxy_page_does_not_exist(doc) ->
+ ["Test that we get a 404 when the page is not found."];
+proxy_page_does_not_exist(suite) ->
+ [];
+proxy_page_does_not_exist(Config) when is_list(Config) ->
+ case ?config(skip, Config) of
+ undefined ->
+ URL = ?PROXY_URL ++ "/doesnotexist.html",
+ {ok, {{_,404,_}, [_ | _], [_ | _]}} =
+ http:request(get, {URL, []}, [], []),
+ ok;
+ Reason ->
+ {skip, Reason}
+ end.
+
+
+%%-------------------------------------------------------------------------
+
+proxy_https_not_supported(doc) ->
+ [];
+proxy_https_not_supported(suite) ->
+ [];
+proxy_https_not_supported(Config) when is_list(Config) ->
+ Result = http:request(get, {"https://login.yahoo.com", []}, [], []),
+ case Result of
+ {error, Reason} ->
+ %% ok so far
+ case Reason of
+ {failed_connecting, Why} ->
+ %% ok, now check why
+ case Why of
+ https_through_proxy_is_not_currently_supported ->
+ ok;
+ _ ->
+ tsf({unexpected_why, Why})
+ end;
+ _ ->
+ tsf({unexpected_reason, Reason})
+ end;
+ _ ->
+ tsf({unexpected_result, Result})
+ end,
+ ok.
+
+
+%%-------------------------------------------------------------------------
+
+http_stream(doc) ->
+ ["Test the option stream for asynchrony requests"];
+http_stream(suite) ->
+ [];
+http_stream(Config) when is_list(Config) ->
+ Port = ?config(local_port, Config),
+ URL = ?URL_START ++ integer_to_list(Port) ++ "/dummy.html",
+ {ok, {{_,200,_}, [_ | _], Body}} =
+ http:request(get, {URL, []}, [], []),
+
+ {ok, RequestId} =
+ http:request(get, {URL, []}, [], [{sync, false},
+ {stream, self}]),
+
+ receive
+ {http, {RequestId, stream_start, _Headers}} ->
+ ok;
+ {http, Msg} ->
+ test_server:fail(Msg)
+ end,
+
+ StreamedBody = receive_streamed_body(RequestId, <<>>),
+
+ Body == binary_to_list(StreamedBody).
+
+
+%%-------------------------------------------------------------------------
+http_stream_once(doc) ->
+ ["Test the option stream for asynchrony requests"];
+http_stream_once(suite) ->
+ [];
+http_stream_once(Config) when is_list(Config) ->
+ p("http_stream_once -> entry with"
+ "~n Config: ~p", [Config]),
+
+ p("http_stream_once -> set ipfamily to inet", []),
+ ok = http:set_options([{ipfamily, inet}]),
+ p("http_stream_once -> start dummy server", []),
+ {DummyServerPid, Port} = dummy_server(self(), ipv4),
+
+ PortStr = integer_to_list(Port),
+ p("http_stream_once -> once", []),
+ once(?URL_START ++ PortStr ++ "/once.html"),
+ p("http_stream_once -> once_chunked", []),
+ once(?URL_START ++ PortStr ++ "/once_chunked.html"),
+ p("http_stream_once -> dummy", []),
+ once(?URL_START ++ PortStr ++ "/dummy.html"),
+
+ p("http_stream_once -> stop dummy server", []),
+ DummyServerPid ! stop,
+ p("http_stream_once -> set ipfamily to inet6fb4", []),
+ ok = http:set_options([{ipfamily, inet6fb4}]), % ********** ipfamily = inet6 *************
+ p("http_stream_once -> done", []),
+ ok.
+
+once(URL) ->
+ p("once -> issue sync request for ~p", [URL]),
+ {ok, {{_,200,_}, [_ | _], Body}} =
+ http:request(get, {URL, []}, [], []),
+
+ p("once -> issue async (self stream) request for ~p", [URL]),
+ {ok, RequestId} =
+ http:request(get, {URL, []}, [], [{sync, false},
+ {stream, {self, once}}]),
+
+ p("once -> await stream_start reply for (async) request ~p", [RequestId]),
+ NewPid =
+ receive
+ {http, {RequestId, stream_start, _Headers, Pid}} ->
+ p("once -> received stream_start reply for (async) request ~p: ~p",
+ [RequestId, Pid]),
+ Pid;
+ {http, Msg} ->
+ test_server:fail(Msg)
+ end,
+
+ tsp("once -> request handler: ~p", [NewPid]),
+
+ p("once -> await stream reply for (async) request ~p", [RequestId]),
+ BodyPart =
+ receive
+ {http, {RequestId, stream, BinBodyPart}} ->
+ p("once -> received stream reply for (async) request ~p: "
+ "~n~p", [RequestId, binary_to_list(BinBodyPart)]),
+ BinBodyPart
+ end,
+
+ tsp("once -> first body part '~p' received", [binary_to_list(BodyPart)]),
+
+ StreamedBody = receive_streamed_body(RequestId, BinBodyPart, NewPid),
+
+ Body = binary_to_list(StreamedBody),
+
+ p("once -> done when Bode: ~p", [Body]),
+ ok.
+
+
+%%-------------------------------------------------------------------------
+proxy_stream(doc) ->
+ ["Test the option stream for asynchrony requests"];
+proxy_stream(suite) ->
+ [];
+proxy_stream(Config) when is_list(Config) ->
+ case ?config(skip, Config) of
+ undefined ->
+ {ok, {{_,200,_}, [_ | _], Body}} =
+ http:request(get, {?PROXY_URL, []}, [], []),
+
+ {ok, RequestId} =
+ http:request(get, {?PROXY_URL, []}, [],
+ [{sync, false}, {stream, self}]),
+
+ receive
+ {http, {RequestId, stream_start, _Headers}} ->
+ ok;
+ {http, Msg} ->
+ test_server:fail(Msg)
+ end,
+
+ StreamedBody = receive_streamed_body(RequestId, <<>>),
+
+ Body == binary_to_list(StreamedBody);
+ Reason ->
+ {skip, Reason}
+ end.
+
+
+%%-------------------------------------------------------------------------
+parse_url(doc) ->
+ ["Test that an url is parsed correctly"];
+parse_url(suite) ->
+ [];
+parse_url(Config) when is_list(Config) ->
+ %% ipv6
+ {http,[],"2010:836B:4179::836B:4179",80,"/foobar.html",[]}
+ = http_uri:parse("http://[2010:836B:4179::836B:4179]/foobar.html"),
+ {error,
+ {malformed_url,"http://2010:836B:4179::836B:4179/foobar.html"}} =
+ http_uri:parse("http://2010:836B:4179::836B:4179/foobar.html"),
+
+ %% ipv4
+ {http,[],"127.0.0.1",80,"/foobar.html",[]} =
+ http_uri:parse("http://127.0.0.1/foobar.html"),
+
+ %% host
+ {http,[],"localhost",8888,"/foobar.html",[]} =
+ http_uri:parse("http://localhost:8888/foobar.html"),
+
+ %% Userinfo
+ {http,"nisse:foobar","localhost",8888,"/foobar.html",[]} =
+ http_uri:parse("http://nisse:foobar@localhost:8888/foobar.html"),
+
+ %% Scheme error
+ {error,no_scheme} = http_uri:parse("localhost/foobar.html"),
+ {error,{not_supported_scheme,localhost}} =
+ http_uri:parse("localhost:8888/foobar.html"),
+
+ %% Query
+ {http,[],"localhost",8888,"/foobar.html","?foo=bar&foobar=42"} =
+ http_uri:parse("http://localhost:8888/foobar.html?foo=bar&foobar=42"),
+
+ %% Esc chars
+ {http,[],"www.somedomain.com",80,"/%2Eabc",[]} =
+ http_uri:parse("http://www.somedomain.com/%2Eabc"),
+ {http,[],"www.somedomain.com",80,"/%252Eabc",[]} =
+ http_uri:parse("http://www.somedomain.com/%252Eabc"),
+ {http,[],"www.somedomain.com",80,"/%25abc",[]} =
+ http_uri:parse("http://www.somedomain.com/%25abc"),
+ {http,[],"www.somedomain.com",80,"/%25abc", "?foo=bar"} =
+ http_uri:parse("http://www.somedomain.com/%25abc?foo=bar"),
+ ok.
+
+
+%%-------------------------------------------------------------------------
+ipv6(doc) ->
+ ["Test ipv6."];
+ipv6(suite) ->
+ [];
+ipv6(Config) when is_list(Config) ->
+ {ok, Hostname} = inet:gethostname(),
+
+ case lists:member(list_to_atom(Hostname),
+ ?config(ipv6_hosts, Config)) of
+ true ->
+ {DummyServerPid, Port} = dummy_server(self(), ipv6),
+
+ URL = "http://[" ++ ?IPV6_LOCAL_HOST ++ "]:" ++
+ integer_to_list(Port) ++ "/foobar.html",
+ {ok, {{_,200,_}, [_ | _], [_|_]}} =
+ http:request(get, {URL, []}, [], []),
+
+ DummyServerPid ! stop,
+ ok;
+ false ->
+ {skip, "Host does not support IPv6"}
+ end.
+
+
+%%-------------------------------------------------------------------------
+headers_as_is(doc) ->
+ ["Test the option headers_as_is"];
+headers_as_is(suite) ->
+ [];
+headers_as_is(Config) when is_list(Config) ->
+ Port = ?config(local_port, Config),
+ URL = ?URL_START ++ integer_to_list(Port) ++ "/dummy.html",
+ {ok, {{_,200,_}, [_|_], [_|_]}} =
+ http:request(get, {URL, [{"Host", "localhost"},{"Te", ""}]},
+ [], [{headers_as_is, true}]),
+
+ {ok, {{_,400,_}, [_|_], [_|_]}} =
+ http:request(get, {URL, [{"Te", ""}]},[], [{headers_as_is, true}]),
+ ok.
+
+
+%%-------------------------------------------------------------------------
+options(doc) ->
+ ["Test the option parameters."];
+options(suite) ->
+ [];
+options(Config) when is_list(Config) ->
+ case ?config(local_server, Config) of
+ ok ->
+ Port = ?config(local_port, Config),
+ URL = ?URL_START ++ integer_to_list(Port) ++ "/dummy.html",
+ {ok, {{_,200,_}, [_ | _], Bin}}
+ = http:request(get, {URL, []}, [{foo, bar}],
+ %% Ignore unknown options
+ [{body_format, binary}, {foo, bar}]),
+
+ true = is_binary(Bin),
+ {ok, {200, [_|_]}}
+ = http:request(get, {URL, []}, [{timeout, infinity}],
+ [{full_result, false}]);
+ _ ->
+ {skip, "Failed to start local http-server"}
+ end.
+
+
+%%-------------------------------------------------------------------------
+http_invalid_http(doc) ->
+ ["Test parse error"];
+http_invalid_http(suite) ->
+ [];
+http_invalid_http(Config) when is_list(Config) ->
+ ok = http:set_options([{ipfamily, inet}]),
+ {DummyServerPid, Port} = dummy_server(self(), ipv4),
+
+ URL = ?URL_START ++ integer_to_list(Port) ++ "/invalid_http.html",
+
+ {error, {could_not_parse_as_http, _} = Reason} =
+ http:request(get, {URL, []}, [], []),
+
+ test_server:format("Parse error: ~p ~n", [Reason]),
+ DummyServerPid ! stop,
+ ok = http:set_options([{ipfamily, inet6fb4}]), % ********** ipfamily = inet6 *************
+ ok.
+
+
+%%-------------------------------------------------------------------------
+
+hexed_query_otp_6191(doc) ->
+ [];
+hexed_query_otp_6191(suite) ->
+ [];
+hexed_query_otp_6191(Config) when is_list(Config) ->
+ Google = "www.google.com",
+ GoogleSearch = "http://" ++ Google ++ "/search",
+ Search1 = "?hl=en&q=a%D1%85%D1%83%D0%B9&btnG=Google+Search",
+ URI1 = GoogleSearch ++ Search1,
+ Search2 = "?hl=en&q=%25%25",
+ URI2 = GoogleSearch ++ Search2,
+ Search3 = "?hl=en&q=%foo",
+ URI3 = GoogleSearch ++ Search3,
+
+ {http, [], Google, 80, "/search", _} = http_uri:parse(URI1),
+ {http, [], Google, 80, "/search", _} = http_uri:parse(URI2),
+ {http, [], Google, 80, "/search", _} = http_uri:parse(URI3),
+ ok.
+
+
+%%-------------------------------------------------------------------------
+
+empty_body_otp_6243(doc) ->
+ ["An empty body was not returned directly. There was a delay for several"
+ "seconds."];
+empty_body_otp_6243(suite) ->
+ [];
+empty_body_otp_6243(Config) when is_list(Config) ->
+ Port = ?config(local_port, Config),
+ URL = ?URL_START ++ integer_to_list(Port) ++ "/empty.html",
+ {ok, {{_,200,_}, [_ | _], []}} =
+ http:request(get, {URL, []}, [{timeout, 500}], []).
+
+
+%%-------------------------------------------------------------------------
+
+transfer_encoding_otp_6807(doc) ->
+ ["Transfer encoding is case insensitive"];
+transfer_encoding_otp_6807(suite) ->
+ [];
+transfer_encoding_otp_6807(Config) when is_list(Config) ->
+ ok = http:set_options([{ipfamily, inet}]),
+ {DummyServerPid, Port} = dummy_server(self(), ipv4),
+
+ URL = ?URL_START ++ integer_to_list(Port) ++
+ "/capital_transfer_encoding.html",
+ {ok, {{_,200,_}, [_|_], [_ | _]}} = http:request(URL),
+ DummyServerPid ! stop,
+ ok = http:set_options([{ipfamily, inet6fb4}]), % ********** ipfamily = inet6 *************
+ ok.
+
+
+%%-------------------------------------------------------------------------
+
+proxy_not_modified_otp_6821(doc) ->
+ ["If unmodified no body should be returned"];
+proxy_not_modified_otp_6821(suite) ->
+ [];
+proxy_not_modified_otp_6821(Config) when is_list(Config) ->
+ case ?config(skip, Config) of
+ undefined ->
+ provocate_not_modified_bug(?PROXY_URL);
+ Reason ->
+ {skip, Reason}
+ end.
+
+
+%%-------------------------------------------------------------------------
+
+empty_response_header_otp_6830(doc) ->
+ ["Test the case that the HTTP server does not send any headers"];
+empty_response_header_otp_6830(suite) ->
+ [];
+empty_response_header_otp_6830(Config) when is_list(Config) ->
+ ok = http:set_options([{ipfamily, inet}]),
+ {DummyServerPid, Port} = dummy_server(self(), ipv4),
+
+ URL = ?URL_START ++ integer_to_list(Port) ++ "/no_headers.html",
+ {ok, {{_,200,_}, [], [_ | _]}} = http:request(URL),
+ DummyServerPid ! stop,
+ ok = http:set_options([{ipfamily, inet6fb4}]), % ********** ipfamily = inet6 *************
+ ok.
+
+
+%%-------------------------------------------------------------------------
+
+no_content_204_otp_6982(doc) ->
+ ["Test the case that the HTTP 204 no content header"];
+no_content_204_otp_6982(suite) ->
+ [];
+no_content_204_otp_6982(Config) when is_list(Config) ->
+ ok = http:set_options([{ipfamily, inet}]),
+ {DummyServerPid, Port} = dummy_server(self(), ipv4),
+
+ URL = ?URL_START ++ integer_to_list(Port) ++ "/no_content.html",
+ {ok, {{_,204,_}, [], []}} = http:request(URL),
+ DummyServerPid ! stop,
+ ok = http:set_options([{ipfamily, inet6fb4}]), % ********** ipfamily = inet6 *************
+ ok.
+
+
+%%-------------------------------------------------------------------------
+
+missing_CR_otp_7304(doc) ->
+ ["Test the case that the HTTP server uses only LF instead of CRLF"
+ "as delimitor"];
+missing_CR_otp_7304(suite) ->
+ [];
+missing_CR_otp_7304(Config) when is_list(Config) ->
+ ok = http:set_options([{ipfamily, inet}]),
+ {DummyServerPid, Port} = dummy_server(self(), ipv4),
+
+ URL = ?URL_START ++ integer_to_list(Port) ++ "/missing_CR.html",
+ {ok, {{_,200,_}, _, [_ | _]}} = http:request(URL),
+ DummyServerPid ! stop,
+ ok = http:set_options([{ipfamily, inet6fb4}]), % ********** ipfamily = inet6 *************
+ ok.
+
+
+%%-------------------------------------------------------------------------
+
+otp_7883(suite) ->
+ [otp_7883_1, otp_7883_2].
+
+otp_7883_1(doc) ->
+ ["OTP-7883-sync"];
+otp_7883_1(suite) ->
+ [];
+otp_7883_1(Config) when is_list(Config) ->
+ ok = http:set_options([{ipfamily, inet}]),
+
+ {DummyServerPid, Port} = dummy_server(self(), ipv4),
+
+ URL = ?URL_START ++ integer_to_list(Port) ++ "/just_close.html",
+ {error, socket_closed_remotely} = http:request(URL),
+ DummyServerPid ! stop,
+
+ ok = http:set_options([{ipfamily, inet6fb4}]), % ********** ipfamily = inet6 *************
+ ok.
+
+otp_7883_2(doc) ->
+ ["OTP-7883-async"];
+otp_7883_2(suite) ->
+ [];
+otp_7883_2(Config) when is_list(Config) ->
+ ok = http:set_options([{ipfamily, inet}]),
+
+ {DummyServerPid, Port} = dummy_server(self(), ipv4),
+
+ URL = ?URL_START ++ integer_to_list(Port) ++ "/just_close.html",
+ Method = get,
+ Request = {URL, []},
+ HttpOptions = [],
+ Options = [{sync, false}],
+ Profile = http:default_profile(),
+ {ok, RequestId} =
+ http:request(Method, Request, HttpOptions, Options, Profile),
+ ok =
+ receive
+ {http, {RequestId, {error, socket_closed_remotely}}} ->
+ ok
+ end,
+ DummyServerPid ! stop,
+
+ ok = http:set_options([{ipfamily, inet6fb4}]), % ********** ipfamily = inet6 *************
+ ok.
+
+
+%%-------------------------------------------------------------------------
+
+otp_8154(suite) ->
+ [otp_8154_1].
+
+otp_8154_1(doc) ->
+ ["OTP-8154"];
+otp_8154_1(suite) ->
+ [];
+otp_8154_1(Config) when is_list(Config) ->
+ start_inets(),
+ ReqSeqNumServer = start_sequence_number_server(),
+ RespSeqNumServer = start_sequence_number_server(),
+ {ok, Server, Port} = start_slow_server(RespSeqNumServer),
+ Clients = run_clients(105, Port, ReqSeqNumServer),
+ %% ok = wait_for_clients(Clients),
+ ok = wait4clients(Clients, timer:minutes(3)),
+ Server ! shutdown,
+ RespSeqNumServer ! shutdown,
+ ReqSeqNumServer ! shutdown,
+ ok.
+
+start_inets() ->
+ inets:start(),
+ ok.
+
+
+%% -----------------------------------------------------
+%% A sequence number handler
+%% The purpose is to be able to pair requests with responses.
+
+start_sequence_number_server() ->
+ proc_lib:spawn(fun() -> loop_sequence_number(1) end).
+
+loop_sequence_number(N) ->
+ receive
+ shutdown ->
+ ok;
+ {From, get_next} ->
+ From ! {next_is, N},
+ loop_sequence_number(N + 1)
+ end.
+
+get_next_sequence_number(SeqNumServer) ->
+ SeqNumServer ! {self(), get_next},
+ receive {next_is, N} -> N end.
+
+%% -----------------------------------------------------
+%% Client part
+%% Sends requests randomly parallel
+
+run_clients(NumClients, ServerPort, SeqNumServer) ->
+ io:format("start clients when"
+ "~n NumClients: ~w"
+ "~n ServerPort: ~w"
+ "~n SeqNumServer: ~w"
+ "~n", [NumClients, ServerPort, SeqNumServer]),
+ set_random_seed(),
+ lists:map(
+ fun(Id) ->
+ io:format("starting client ~w~n", [Id]),
+ Req = f("req~3..0w", [get_next_sequence_number(SeqNumServer)]),
+ Url = f(?URL_START ++ "~w/~s", [ServerPort, Req]),
+ Pid = proc_lib:spawn(
+ fun() ->
+ io:format("[~w] client started - "
+ "issue request~n", [Id]),
+ case http:request(Url) of
+ {ok, {{_,200,_}, _, Resp}} ->
+ io:format("[~w] 200 response: "
+ "~p~n", [Id, Resp]),
+ case lists:prefix(Req++"->", Resp) of
+ true -> exit(normal);
+ false -> exit({bad_resp,Req,Resp})
+ end;
+ {ok, {{_,EC,Reason},_,Resp}} ->
+ io:format("[~w] ~w response: "
+ "~s~n~s~n",
+ [Id, EC, Reason, Resp]),
+ exit({bad_resp,Req,Resp});
+ Crap ->
+ io:format("[~w] bad response: ~p",
+ [Id, Crap]),
+ exit({bad_resp, Req, Crap})
+ end
+ end),
+ MRef = erlang:monitor(process, Pid),
+ timer:sleep(10 + random:uniform(1334)),
+ {Id, Pid, MRef}
+
+ end,
+ lists:seq(1, NumClients)).
+
+%% wait_for_clients(Clients) ->
+%% lists:foreach(
+%% fun({Id, Pid, MRef}) ->
+%% io:format("waiting for client ~w termination~n", [Id]),
+%% receive
+%% {'DOWN', MRef, process, Pid, normal} ->
+%% io:format("waiting for clients: "
+%% "normal exit from ~w (~p)~n",
+%% [Id, Pid]),
+%% ok;
+%% {'DOWN', MRef, process, Pid, Reason} ->
+%% io:format("waiting for clients: "
+%% "unexpected exit from ~w (~p):"
+%% "~n Reason: ~p"
+%% "~n", [Id, Pid, Reason]),
+%% erlang:error(Reason)
+%% end
+%% end,
+%% Clients).
+
+
+wait4clients([], _Timeout) ->
+ ok;
+wait4clients(Clients, Timeout) when Timeout > 0 ->
+ io:format("wait4clients -> entry with"
+ "~n length(Clients): ~w"
+ "~n Timeout: ~w"
+ "~n", [length(Clients), Timeout]),
+ T = t(),
+ receive
+ {'DOWN', _MRef, process, Pid, normal} ->
+ case lists:keysearch(Pid, 2, Clients) of
+ {value, {Id, _, _}} ->
+ io:format("receive normal exit message "
+ "from client ~p (~p)", [Id, Pid]),
+ NewClients =
+ lists:keydelete(Id, 1, Clients),
+ wait4clients(NewClients,
+ Timeout - (t() - T));
+ false ->
+ io:format("receive normal exit message "
+ "from unknown process: ~p", [Pid]),
+ wait4clients(Clients, Timeout - (t() - T))
+ end;
+
+ {'DOWN', _MRef, process, Pid, Reason} ->
+ case lists:keysearch(Pid, 2, Clients) of
+ {value, {Id, _, _}} ->
+ io:format("receive bad exit message "
+ "from client ~p (~p):"
+ "~n ~p", [Id, Pid, Reason]),
+ erlang:error({bad_client_termination, Id, Reason});
+ false ->
+ io:format("receive normal exit message "
+ "from unknown process: ~p", [Pid]),
+ wait4clients(Clients, Timeout - (t() - T))
+ end
+
+ after Timeout ->
+ erlang:error({client_timeout, Clients})
+ end;
+wait4clients(Clients, _) ->
+ erlang:error({client_timeout, Clients}).
+
+
+%% Time in milli seconds
+t() ->
+ {A,B,C} = erlang:now(),
+ A*1000000000+B*1000+(C div 1000).
+
+
+%% -----------------------------------------------------
+%% Webserver part:
+%% Implements a web server that sends responses one character
+%% at a time, with random delays between the characters.
+
+start_slow_server(SeqNumServer) ->
+ io:format("start slow server when"
+ "~n SeqNumServer: ~w"
+ "~n", [SeqNumServer]),
+ proc_lib:start(
+ erlang, apply, [fun() -> init_slow_server(SeqNumServer) end, []]).
+
+init_slow_server(SeqNumServer) ->
+ io:format("[webserver ~w] init slow server"
+ "~n", [SeqNumServer]),
+ {ok, LSock} = gen_tcp:listen(0, [binary, {packet,0}, {active,true},
+ {backlog, 100}]),
+ io:format("[webserver ~w] LSock: ~p"
+ "~n", [SeqNumServer, LSock]),
+ {ok, {_IP, Port}} = inet:sockname(LSock),
+ io:format("[webserver ~w] Port: ~w"
+ "~n", [SeqNumServer, Port]),
+ proc_lib:init_ack({ok, self(), Port}),
+ loop_slow_server(LSock, SeqNumServer).
+
+loop_slow_server(LSock, SeqNumServer) ->
+ io:format("[webserver ~w] entry with"
+ "~n LSock: ~p"
+ "~n", [SeqNumServer, LSock]),
+ Master = self(),
+ Acceptor = proc_lib:spawn(
+ fun() -> client_handler(Master, LSock, SeqNumServer) end),
+ io:format("[webserver ~w] acceptor started"
+ "~n Acceptor: ~p"
+ "~n", [SeqNumServer, Acceptor]),
+ receive
+ {accepted, Acceptor} ->
+ io:format("[webserver ~w] accepted"
+ "~n", [SeqNumServer]),
+ loop_slow_server(LSock, SeqNumServer);
+ shutdown ->
+ gen_tcp:close(LSock),
+ exit(Acceptor, kill)
+ end.
+
+
+%% Handle one client connection
+client_handler(Master, LSock, SeqNumServer) ->
+ io:format("[acceptor ~w] await accept"
+ "~n", [SeqNumServer]),
+ {ok, CSock} = gen_tcp:accept(LSock),
+ io:format("[acceptor ~w] accepted"
+ "~n CSock: ~p"
+ "~n", [SeqNumServer, CSock]),
+ Master ! {accepted, self()},
+ set_random_seed(),
+ loop_client(1, CSock, SeqNumServer).
+
+loop_client(N, CSock, SeqNumServer) ->
+ %% Await request, don't bother parsing it too much,
+ %% assuming the entire request arrives in one packet.
+ io:format("[acceptor ~w] await request"
+ "~n N: ~p"
+ "~n", [SeqNumServer, N]),
+ receive
+ {tcp, CSock, Req} ->
+ ReqNum = parse_req_num(Req),
+ RespSeqNum = get_next_sequence_number(SeqNumServer),
+ Response = f("~s->resp~3..0w/~2..0w", [ReqNum, RespSeqNum, N]),
+ Txt = f("Slow server (~p) got ~p, answering with ~p",
+ [self(), Req, Response]),
+ io:format("~s...~n", [Txt]),
+ slowly_send_response(CSock, Response),
+ case parse_connection_type(Req) of
+ keep_alive ->
+ io:format("~s...done~n", [Txt]),
+ loop_client(N+1, CSock, SeqNumServer);
+ close ->
+ io:format("~s...done (closing)~n", [Txt]),
+ gen_tcp:close(CSock)
+ end
+ end.
+
+slowly_send_response(CSock, Answer) ->
+ Response = f("HTTP/1.1 200 OK\r\nContent-Length: ~w\r\n\r\n~s",
+ [length(Answer), Answer]),
+ lists:foreach(
+ fun(Char) ->
+ timer:sleep(random:uniform(500)),
+ gen_tcp:send(CSock, <<Char>>)
+ end,
+ Response).
+
+parse_req_num(Request) ->
+ Opts = [caseless,{capture,all_but_first,list}],
+ {match, [ReqNum]} = re:run(Request, "GET /(.*) HTTP", Opts),
+ ReqNum.
+
+parse_connection_type(Request) ->
+ Opts = [caseless,{capture,all_but_first,list}],
+ {match,[CType]} = re:run(Request, "connection: *(keep-alive|close)", Opts),
+ case string:to_lower(CType) of
+ "close" -> close;
+ "keep-alive" -> keep_alive
+ end.
+
+
+set_random_seed() ->
+ {_, _, Micros} = now(),
+ A = erlang:phash2([make_ref(), self(), Micros]),
+ random:seed(A, A, A).
+
+f(F, A) -> lists:flatten(io_lib:format(F,A)).
+
+
+
+
+%%-------------------------------------------------------------------------
+
+otp_8106(suite) ->
+ [
+ otp_8106_pid,
+ otp_8106_fun,
+ otp_8106_mfa
+ ].
+
+
+otp_8106_pid(doc) ->
+ ["OTP-8106 - deliver reply info using \"other\" pid"];
+otp_8106_pid(suite) ->
+ [];
+otp_8106_pid(Config) when is_list(Config) ->
+ case ?config(local_server, Config) of
+ ok ->
+ ReceiverPid = create_receiver(pid),
+ Receiver = ReceiverPid,
+
+ otp8106(ReceiverPid, Receiver, Config),
+
+ stop_receiver(ReceiverPid),
+
+ ok;
+ _ ->
+ {skip, "Failed to start local http-server"}
+ end.
+
+
+otp_8106_fun(doc) ->
+ ["OTP-8106 - deliver reply info using fun"];
+otp_8106_fun(suite) ->
+ [];
+otp_8106_fun(Config) when is_list(Config) ->
+ case ?config(local_server, Config) of
+ ok ->
+ ReceiverPid = create_receiver(function),
+ Receiver = otp_8106_deliver_fun(ReceiverPid),
+
+ otp8106(ReceiverPid, Receiver, Config),
+
+ stop_receiver(ReceiverPid),
+
+ ok;
+ _ ->
+ {skip, "Failed to start local http-server"}
+ end.
+
+
+otp_8106_mfa(doc) ->
+ ["OTP-8106 - deliver reply info using mfa callback"];
+otp_8106_mfa(suite) ->
+ [];
+otp_8106_mfa(Config) when is_list(Config) ->
+ case ?config(local_server, Config) of
+ ok ->
+ ReceiverPid = create_receiver(mfa),
+ Receiver = {?MODULE, otp_8106_deliver, [mfa, ReceiverPid]},
+
+ otp8106(ReceiverPid, Receiver, Config),
+
+ stop_receiver(ReceiverPid),
+
+ ok;
+ _ ->
+ {skip, "Failed to start local http-server"}
+ end.
+
+
+ otp8106(ReceiverPid, Receiver, Config) ->
+ Port = ?config(local_port, Config),
+ URL = ?URL_START ++ integer_to_list(Port) ++ "/dummy.html",
+ Request = {URL, []},
+ HTTPOptions = [],
+ Options = [{sync, false}, {receiver, Receiver}],
+
+ {ok, RequestId} =
+ httpc:request(get, Request, HTTPOptions, Options),
+
+ Body =
+ receive
+ {reply, ReceiverPid, {RequestId, {{_, 200, _}, _, B}}} ->
+ B;
+ {reply, ReceiverPid, Msg} ->
+ tsf(Msg);
+ {bad_reply, ReceiverPid, Msg} ->
+ tsf(Msg)
+ end,
+
+ inets_test_lib:check_body(binary_to_list(Body)),
+ ok.
+
+
+create_receiver(Type) ->
+ Parent = self(),
+ Receiver = fun() -> receiver(Type, Parent) end,
+ spawn_link(Receiver).
+
+stop_receiver(Pid) ->
+ Pid ! {stop, self()}.
+
+receiver(Type, Parent) ->
+ receive
+ {stop, Parent} ->
+ exit(normal);
+
+ {http, ReplyInfo} when (Type =:= pid) ->
+ Parent ! {reply, self(), ReplyInfo},
+ receiver(Type, Parent);
+
+ {Type, ReplyInfo} ->
+ Parent ! {reply, self(), ReplyInfo},
+ receiver(Type, Parent);
+
+ Crap ->
+ Parent ! {reply, self(), {bad_reply, Crap}},
+ receiver(Type, Parent)
+ end.
+
+
+otp_8106_deliver_fun(ReceiverPid) ->
+ fun(ReplyInfo) -> otp_8106_deliver(ReplyInfo, function, ReceiverPid) end.
+
+otp_8106_deliver(ReplyInfo, Type, ReceiverPid) ->
+ ReceiverPid ! {Type, ReplyInfo},
+ ok.
+
+
+
+%%-------------------------------------------------------------------------
+
+otp_8056(doc) ->
+ "OTP-8056";
+otp_8056(suite) ->
+ [];
+otp_8056(Config) when is_list(Config) ->
+ Method = get,
+ Port = ?config(local_port, Config),
+ URL = ?URL_START ++ integer_to_list(Port) ++ "/dummy.html",
+ Request = {URL, []},
+ HTTPOptions = [],
+ Options1 = [{sync, true}, {stream, {self, once}}],
+ Options2 = [{sync, true}, {stream, self}],
+ {error, streaming_error} = httpc:request(Method, Request,
+ HTTPOptions, Options1),
+ tsp("request 1 failed as expected"),
+ {error, streaming_error} = httpc:request(Method, Request,
+ HTTPOptions, Options2),
+ tsp("request 2 failed as expected"),
+ ok.
+
+
+%%-------------------------------------------------------------------------
+
+otp_8352(doc) ->
+ "OTP-8352";
+otp_8352(suite) ->
+ [];
+otp_8352(Config) when is_list(Config) ->
+ tsp("otp_8352 -> entry with"
+ "~n Config: ~p", [Config]),
+ case ?config(local_server, Config) of
+ ok ->
+ tsp("local-server running"),
+
+ tsp("initial profile info(1): ~p", [httpc:info()]),
+
+ MaxSessions = 5,
+ MaxKeepAlive = 10,
+ KeepAliveTimeout = timer:minutes(2),
+ ConnOptions = [{max_sessions, MaxSessions},
+ {max_keep_alive_length, MaxKeepAlive},
+ {keep_alive_timeout, KeepAliveTimeout}],
+ http:set_options(ConnOptions),
+
+ Method = get,
+ Port = ?config(local_port, Config),
+ URL = ?URL_START ++ integer_to_list(Port) ++ "/dummy.html",
+ Request = {URL, []},
+ Timeout = timer:seconds(1),
+ ConnTimeout = Timeout + timer:seconds(1),
+ HttpOptions1 = [{timeout, Timeout}, {connect_timeout, ConnTimeout}],
+ Options1 = [{socket_opts, [{tos, 87},
+ {recbuf, 16#FFFF},
+ {sndbuf, 16#FFFF}]}],
+ case http:request(Method, Request, HttpOptions1, Options1) of
+ {ok, {{_,200,_}, [_ | _], ReplyBody1 = [_ | _]}} ->
+ %% equivaliant to http:request(get, {URL, []}, [], []),
+ inets_test_lib:check_body(ReplyBody1);
+ {ok, UnexpectedReply1} ->
+ tsf({unexpected_reply, UnexpectedReply1});
+ {error, _} = Error1 ->
+ tsf({bad_reply, Error1})
+ end,
+
+ tsp("profile info (2): ~p", [httpc:info()]),
+
+ HttpOptions2 = [],
+ Options2 = [{socket_opts, [{tos, 84},
+ {recbuf, 32#1FFFF},
+ {sndbuf, 32#1FFFF}]}],
+ case http:request(Method, Request, HttpOptions2, Options2) of
+ {ok, {{_,200,_}, [_ | _], ReplyBody2 = [_ | _]}} ->
+ %% equivaliant to http:request(get, {URL, []}, [], []),
+ inets_test_lib:check_body(ReplyBody2);
+ {ok, UnexpectedReply2} ->
+ tsf({unexpected_reply, UnexpectedReply2});
+ {error, _} = Error2 ->
+ tsf({bad_reply, Error2})
+ end,
+ tsp("profile info (3): ~p", [httpc:info()]),
+ ok;
+
+ _ ->
+ {skip, "Failed to start local http-server"}
+ end.
+
+
+%%-------------------------------------------------------------------------
+
+otp_8371(doc) ->
+ ["OTP-8371"];
+otp_8371(suite) ->
+ [];
+otp_8371(Config) when is_list(Config) ->
+ ok = http:set_options([{ipv6, disabled}]), % also test the old option
+ {DummyServerPid, Port} = dummy_server(self(), ipv4),
+
+ URL = ?URL_START ++ integer_to_list(Port) ++
+ "/ensure_host_header_with_port.html",
+
+ case http:request(get, {URL, []}, [], []) of
+ {ok, Result} ->
+ case Result of
+ {{_, 200, _}, _Headers, Body} ->
+ tsp("expected response with"
+ "~n Body: ~p", [Body]),
+ ok;
+ {StatusLine, Headers, Body} ->
+ tsp("expected response with"
+ "~n StatusLine: ~p"
+ "~n Headers: ~p"
+ "~n Body: ~p", [StatusLine, Headers, Body]),
+ tsf({unexpected_result,
+ [{status_line, StatusLine},
+ {headers, Headers},
+ {body, Body}]});
+ _ ->
+ tsf({unexpected_result, Result})
+ end;
+ Error ->
+ tsf({request_failed, Error})
+ end,
+
+ DummyServerPid ! stop,
+ ok = http:set_options([{ipv6, enabled}]),
+ ok.
+
+
+%%-------------------------------------------------------------------------
+
+otp_8739(doc) ->
+ ["OTP-8739"];
+otp_8739(suite) ->
+ [];
+otp_8739(Config) when is_list(Config) ->
+ {_DummyServerPid, Port} = otp_8739_dummy_server(),
+ URL = ?URL_START ++ integer_to_list(Port) ++ "/dummy.html",
+ Method = get,
+ Request = {URL, []},
+ HttpOptions = [{connect_timeout, 500}, {timeout, 1}],
+ Options = [{sync, true}],
+ case http:request(Method, Request, HttpOptions, Options) of
+ {error, timeout} ->
+ %% And now we check the size of the handler db
+ Info = httpc:info(),
+ tsp("Info: ~p", [Info]),
+ {value, {handlers, Handlers}} =
+ lists:keysearch(handlers, 1, Info),
+ case Handlers of
+ [] ->
+ ok;
+ _ ->
+ tsf({unexpected_handlers, Handlers})
+ end;
+ Unexpected ->
+ tsf({unexpected, Unexpected})
+ end.
+
+
+otp_8739_dummy_server() ->
+ Parent = self(),
+ Pid = spawn_link(fun() -> otp_8739_dummy_server_init(Parent) end),
+ receive
+ {port, Port} ->
+ {Pid, Port}
+ end.
+
+otp_8739_dummy_server_init(Parent) ->
+ {ok, ListenSocket} =
+ gen_tcp:listen(0, [binary, inet, {packet, 0},
+ {reuseaddr,true},
+ {active, false}]),
+ {ok, Port} = inet:port(ListenSocket),
+ Parent ! {port, Port},
+ otp_8739_dummy_server_main(Parent, ListenSocket).
+
+otp_8739_dummy_server_main(_Parent, ListenSocket) ->
+ case gen_tcp:accept(ListenSocket) of
+ {ok, Sock} ->
+ %% Ignore the request, and simply wait for the socket to close
+ receive
+ {tcp_closed, Sock} ->
+ (catch gen_tcp:close(ListenSocket)),
+ exit(normal);
+ {tcp_error, Sock, Reason} ->
+ tsp("socket error: ~p", [Reason]),
+ (catch gen_tcp:close(ListenSocket)),
+ exit(normal)
+ after 10000 ->
+ %% Just in case
+ (catch gen_tcp:close(Sock)),
+ (catch gen_tcp:close(ListenSocket)),
+ exit(timeout)
+ end;
+ Error ->
+ exit(Error)
+ end.
+
+
+
+%%--------------------------------------------------------------------
+%% Internal functions
+%%--------------------------------------------------------------------
+setup_server_dirs(ServerRoot, DocRoot, DataDir) ->
+ ConfDir = filename:join(ServerRoot, "conf"),
+ CgiDir = filename:join(ServerRoot, "cgi-bin"),
+ ok = file:make_dir(ServerRoot),
+ ok = file:make_dir(DocRoot),
+ ok = file:make_dir(ConfDir),
+ ok = file:make_dir(CgiDir),
+
+ {ok, Files} = file:list_dir(DataDir),
+
+ lists:foreach(fun(File) -> case lists:suffix(".html", File) of
+ true ->
+ inets_test_lib:copy_file(File,
+ DataDir,
+ DocRoot);
+ false ->
+ ok
+ end
+ end, Files),
+
+ Cgi = case test_server:os_type() of
+ {win32, _} ->
+ "cgi_echo.exe";
+ _ ->
+ "cgi_echo"
+ end,
+
+ inets_test_lib:copy_file(Cgi, DataDir, CgiDir),
+ inets_test_lib:copy_file("mime.types", DataDir, ConfDir).
+
+create_config(FileName, ComType, Port, PrivDir, ServerRoot, DocRoot,
+ SSLDir) ->
+ MaxHdrSz = io_lib:format("~p", [256]),
+ MaxHdrAct = io_lib:format("~p", [close]),
+ SSL =
+ case ComType of
+ ssl ->
+ [cline(["SSLCertificateFile ",
+ filename:join(SSLDir, "ssl_server_cert.pem")]),
+ cline(["SSLCertificateKeyFile ",
+ filename:join(SSLDir, "ssl_server_cert.pem")]),
+ cline(["SSLVerifyClient 0"])];
+ _ ->
+ []
+ end,
+
+ Mod_order = "Modules mod_alias mod_auth mod_esi mod_actions mod_cgi"
+ " mod_include mod_dir mod_get mod_head"
+ " mod_log mod_disk_log mod_trace",
+
+ HttpConfig = [
+ cline(["Port ", integer_to_list(Port)]),
+ cline(["ServerName ", "httpc_test"]),
+ cline(["SocketType ", atom_to_list(ComType)]),
+ cline([Mod_order]),
+ cline(["ServerRoot ", ServerRoot]),
+ cline(["DocumentRoot ", DocRoot]),
+ cline(["MaxHeaderSize ",MaxHdrSz]),
+ cline(["MaxHeaderAction ",MaxHdrAct]),
+ cline(["DirectoryIndex ", "index.html "]),
+ cline(["DefaultType ", "text/plain"]),
+ cline(["ScriptAlias /cgi-bin/ ",
+ filename:join(ServerRoot, "cgi-bin"), "/"]),
+ SSL],
+ ConfigFile = filename:join([PrivDir,FileName]),
+ {ok, Fd} = file:open(ConfigFile, [write]),
+ ok = file:write(Fd, lists:flatten(HttpConfig)),
+ ok = file:close(Fd).
+
+cline(List) ->
+ lists:flatten([List, "\r\n"]).
+
+is_proxy_available(Proxy, Port) ->
+ case gen_tcp:connect(Proxy, Port, []) of
+ {ok, Socket} ->
+ gen_tcp:close(Socket),
+ true;
+ _ ->
+ false
+ end.
+
+receive_streamed_body(RequestId, Body) ->
+ receive
+ {http, {RequestId, stream, BinBodyPart}} ->
+ receive_streamed_body(RequestId,
+ <<Body/binary, BinBodyPart/binary>>);
+ {http, {RequestId, stream_end, _Headers}} ->
+ Body;
+ {http, Msg} ->
+ test_server:fail(Msg)
+ end.
+
+receive_streamed_body(RequestId, Body, Pid) ->
+ http:stream_next(Pid),
+ test_server:format("~p:receive_streamed_body -> requested next stream ~n", [?MODULE]),
+ receive
+ {http, {RequestId, stream, BinBodyPart}} ->
+ receive_streamed_body(RequestId,
+ <<Body/binary, BinBodyPart/binary>>,
+ Pid);
+ {http, {RequestId, stream_end, _Headers}} ->
+ Body;
+ {http, Msg} ->
+ test_server:fail(Msg)
+ end.
+
+
+
+dummy_server(Caller, IpV) ->
+ Pid = spawn(httpc_SUITE, dummy_server_init, [Caller, IpV]),
+ receive
+ {port, Port} ->
+ {Pid, Port}
+ end.
+
+dummy_server_init(Caller, IpV) ->
+ {ok, ListenSocket} =
+ case IpV of
+ ipv4 ->
+ gen_tcp:listen(0, [binary, inet, {packet, 0},
+ {reuseaddr,true},
+ {active, false}]);
+ ipv6 ->
+ gen_tcp:listen(0, [binary, inet6, {packet, 0},
+ {reuseaddr,true},
+ {active, false}])
+ end,
+ {ok, Port} = inet:port(ListenSocket),
+ tsp("dummy_server_init -> Port: ~p", [Port]),
+ Caller ! {port, Port},
+ dummy_server_loop({httpd_request, parse, [?HTTP_MAX_HEADER_SIZE]},
+ [], ListenSocket).
+
+dummy_server_loop(MFA, Handlers, ListenSocket) ->
+ receive
+ stop ->
+ lists:foreach(fun(Handler) -> Handler ! stop end, Handlers)
+ after 0 ->
+ {ok, Socket} = gen_tcp:accept(ListenSocket),
+ HandlerPid = dummy_request_handler(MFA, Socket),
+ gen_tcp:controlling_process(Socket, HandlerPid),
+ HandlerPid ! controller,
+ dummy_server_loop(MFA, [HandlerPid | Handlers],
+ ListenSocket)
+ end.
+
+dummy_request_handler(MFA, Socket) ->
+ spawn(httpc_SUITE, dummy_request_handler_init, [MFA, Socket]).
+
+dummy_request_handler_init(MFA, Socket) ->
+ receive
+ controller ->
+ inet:setopts(Socket, [{active, true}])
+ end,
+ dummy_request_handler_loop(MFA, Socket).
+
+dummy_request_handler_loop({Module, Function, Args}, Socket) ->
+ tsp("dummy_request_handler_loop -> entry with"
+ "~n Module: ~p"
+ "~n Function: ~p"
+ "~n Args: ~p", [Module, Function, Args]),
+ receive
+ {tcp, _, Data} ->
+ tsp("dummy_request_handler_loop -> Data ~p", [Data]),
+ case handle_request(Module, Function, [Data | Args], Socket) of
+ stop ->
+ gen_tcp:close(Socket);
+ NewMFA ->
+ dummy_request_handler_loop(NewMFA, Socket)
+ end;
+ stop ->
+ gen_tcp:close(Socket)
+ end.
+
+handle_request(Module, Function, Args, Socket) ->
+ tsp("handle_request -> entry with"
+ "~n Module: ~p"
+ "~n Function: ~p"
+ "~n Args: ~p", [Module, Function, Args]),
+ case Module:Function(Args) of
+ {ok, Result} ->
+ tsp("handle_request -> ok"
+ "~n Result: ~p", [Result]),
+ case (catch handle_http_msg(Result, Socket)) of
+ stop ->
+ stop;
+ <<>> ->
+ tsp("handle_request -> empty data"),
+ {httpd_request, parse, [[<<>>, ?HTTP_MAX_HEADER_SIZE]]};
+ Data ->
+ handle_request(httpd_request, parse,
+ [Data |[?HTTP_MAX_HEADER_SIZE]], Socket)
+ end;
+ NewMFA ->
+ tsp("handle_request -> "
+ "~n NewMFA: ~p", [NewMFA]),
+ NewMFA
+ end.
+
+handle_http_msg({_, RelUri, _, {_, Headers}, Body}, Socket) ->
+ tsp("handle_http_msg -> entry with: "
+ "~n RelUri: ~p"
+ "~n Headers: ~p"
+ "~n Body: ~p", [RelUri, Headers, Body]),
+ NextRequest =
+ case RelUri of
+ "/dummy_headers.html" ->
+ <<>>;
+ "/no_headers.html" ->
+ stop;
+ "/just_close.html" ->
+ stop;
+ _ ->
+ ContentLength = content_length(Headers),
+ case size(Body) - ContentLength of
+ 0 ->
+ <<>>;
+ _ ->
+ <<_BodyThisReq:ContentLength/binary,
+ Next/binary>> = Body,
+ Next
+ end
+ end,
+
+ tsp("handle_http_msg -> NextRequest: ~p", [NextRequest]),
+ case (catch ets:lookup(cookie, cookies)) of
+ [{cookies, true}]->
+ tsp("handle_http_msg -> check cookies ~p", []),
+ check_cookie(Headers);
+ _ ->
+ ok
+ end,
+
+ DefaultResponse = "HTTP/1.1 200 ok\r\n" ++
+ "Content-Length:32\r\n\r\n"
+ "<HTML><BODY>foobar</BODY></HTML>",
+
+ Msg =
+ case RelUri of
+ "/just_close.html" ->
+ close;
+ "/no_content.html" ->
+ "HTTP/1.0 204 No Content\r\n\r\n";
+ "/no_headers.html" ->
+ "HTTP/1.0 200 OK\r\n\r\nTEST";
+ "/ensure_host_header_with_port.html" ->
+ %% tsp("handle_http_msg -> validate host with port"),
+ case ensure_host_header_with_port(Headers) of
+ true ->
+ B =
+ "<HTML><BODY>" ++
+ "host with port" ++
+ "</BODY></HTML>",
+ Len = integer_to_list(length(B)),
+ "HTTP/1.1 200 ok\r\n" ++
+ "Content-Length:" ++ Len ++ "\r\n\r\n" ++ B;
+ false ->
+ B =
+ "<HTML><BODY>" ++
+ "Internal Server Error - host without port" ++
+ "</BODY></HTML>",
+ Len = integer_to_list(length(B)),
+ "HTTP/1.1 500 Internal Server Error\r\n" ++
+ "Content-Length:" ++ Len ++ "\r\n\r\n" ++ B
+ end;
+ "/300.html" ->
+ NewUri = ?URL_START ++
+ integer_to_list(?IP_PORT) ++ "/dummy.html",
+ "HTTP/1.1 300 Multiple Choices\r\n" ++
+ "Location:" ++ NewUri ++ "\r\n" ++
+ "Content-Length:0\r\n\r\n";
+ "/301.html" ->
+ NewUri = ?URL_START ++
+ integer_to_list(?IP_PORT) ++ "/dummy.html",
+ "HTTP/1.1 301 Moved Permanently\r\n" ++
+ "Location:" ++ NewUri ++ "\r\n" ++
+ "Content-Length:80\r\n\r\n" ++
+ "<HTML><BODY><a href=" ++ NewUri ++
+ ">New place</a></BODY></HTML>";
+ "/302.html" ->
+ NewUri = ?URL_START ++
+ integer_to_list(?IP_PORT) ++ "/dummy.html",
+ "HTTP/1.1 302 Found \r\n" ++
+ "Location:" ++ NewUri ++ "\r\n" ++
+ "Content-Length:80\r\n\r\n" ++
+ "<HTML><BODY><a href=" ++ NewUri ++
+ ">New place</a></BODY></HTML>";
+ "/307.html" ->
+ NewUri = ?URL_START ++
+ integer_to_list(?IP_PORT) ++ "/dummy.html",
+ "HTTP/1.1 307 Temporary Rediect \r\n" ++
+ "Location:" ++ NewUri ++ "\r\n" ++
+ "Content-Length:80\r\n\r\n" ++
+ "<HTML><BODY><a href=" ++ NewUri ++
+ ">New place</a></BODY></HTML>";
+ "/500.html" ->
+ "HTTP/1.1 500 Internal Server Error\r\n" ++
+ "Content-Length:47\r\n\r\n" ++
+ "<HTML><BODY>Internal Server Error</BODY></HTML>";
+ "/503.html" ->
+ case ets:lookup(unavailable, 503) of
+ [{503, unavailable}] ->
+ ets:insert(unavailable, {503, available}),
+ "HTTP/1.1 503 Service Unavailable\r\n" ++
+ "Retry-After:5\r\n" ++
+ "Content-Length:47\r\n\r\n" ++
+ "<HTML><BODY>Internal Server Error</BODY></HTML>";
+ [{503, available}] ->
+ DefaultResponse;
+ [{503, long_unavailable}] ->
+ "HTTP/1.1 503 Service Unavailable\r\n" ++
+ "Retry-After:120\r\n" ++
+ "Content-Length:47\r\n\r\n" ++
+ "<HTML><BODY>Internal Server Error</BODY></HTML>"
+ end;
+ "/redirectloop.html" -> %% Create a potential endless loop!
+ {ok, Port} = inet:port(Socket),
+ NewUri = ?URL_START ++
+ integer_to_list(Port) ++ "/redirectloop.html",
+ "HTTP/1.1 300 Multiple Choices\r\n" ++
+ "Location:" ++ NewUri ++ "\r\n" ++
+ "Content-Length:0\r\n\r\n";
+ "/userinfo.html" ->
+ Challange = "HTTP/1.1 401 Unauthorized \r\n" ++
+ "WWW-Authenticate:Basic" ++"\r\n" ++
+ "Content-Length:0\r\n\r\n",
+ case auth_header(Headers) of
+ {ok, Value} ->
+ handle_auth(Value, Challange, DefaultResponse);
+ _ ->
+ Challange
+ end;
+ "/dummy_headers.html" ->
+ %% The client will only care about the Transfer-Encoding
+ %% header the rest of these headers are left to the
+ %% user to evaluate. This is not a valid response
+ %% it only tests that the header handling code works.
+ Head = "HTTP/1.1 200 ok\r\n" ++
+ "Content-Length:32\r\n" ++
+ "Pragma:1#no-cache\r\n" ++
+ "Via:1.0 fred, 1.1 nowhere.com (Apache/1.1)\r\n" ++
+ "Warning:1#pseudonym foobar\r\n" ++
+ "Vary:*\r\n" ++
+ "Trailer:Other:inets_test\r\n" ++
+ "Upgrade:HTTP/2.0\r\n" ++
+ "Age:4711\r\n" ++
+ "Transfer-Encoding:chunked\r\n" ++
+ "Content-Encoding:foo\r\n" ++
+ "Content-Language:en\r\n" ++
+ "Content-Location:http://www.foobar.se\r\n" ++
+ "Content-MD5:104528739076276072743283077410617235478\r\n"
+ ++
+ "Content-Range:Sat, 29 Oct 1994 19:43:31 GMT\r\n" ++
+ "Expires:Sat, 29 Oct 1994 19:43:31 GMT\r\n" ++
+ "Proxy-Authenticate:#1Basic" ++
+ "\r\n\r\n",
+ gen_tcp:send(Socket, Head),
+ gen_tcp:send(Socket, http_chunk:encode("<HTML><BODY>fo")),
+ gen_tcp:send(Socket, http_chunk:encode("obar</BODY></HTML>")),
+ http_chunk:encode_last();
+ "/capital_transfer_encoding.html" ->
+ Head = "HTTP/1.1 200 ok\r\n" ++
+ "Transfer-Encoding:Chunked\r\n\r\n",
+ gen_tcp:send(Socket, Head),
+ gen_tcp:send(Socket, http_chunk:encode("<HTML><BODY>fo")),
+ gen_tcp:send(Socket, http_chunk:encode("obar</BODY></HTML>")),
+ http_chunk:encode_last();
+ "/cookie.html" ->
+ "HTTP/1.1 200 ok\r\n" ++
+ "set-cookie:" ++ "test_cookie=true; path=/;" ++
+ "max-age=60000\r\n" ++
+ "Content-Length:32\r\n\r\n"++
+ "<HTML><BODY>foobar</BODY></HTML>";
+ "/missing_crlf.html" ->
+ "HTTP/1.1 200 ok" ++
+ "Content-Length:32\r\n" ++
+ "<HTML><BODY>foobar</BODY></HTML>";
+ "/wrong_statusline.html" ->
+ "ok 200 HTTP/1.1\r\n\r\n" ++
+ "Content-Length:32\r\n\r\n" ++
+ "<HTML><BODY>foobar</BODY></HTML>";
+ "/once_chunked.html" ->
+ Head = "HTTP/1.1 200 ok\r\n" ++
+ "Transfer-Encoding:Chunked\r\n\r\n",
+ gen_tcp:send(Socket, Head),
+ gen_tcp:send(Socket, http_chunk:encode("<HTML><BODY>fo")),
+ gen_tcp:send(Socket,
+ http_chunk:encode("obar</BODY></HTML>")),
+ http_chunk:encode_last();
+ "/once.html" ->
+ Head = "HTTP/1.1 200 ok\r\n" ++
+ "Content-Length:32\r\n\r\n",
+ gen_tcp:send(Socket, Head),
+ gen_tcp:send(Socket, "<HTML><BODY>fo"),
+ test_server:sleep(1000),
+ gen_tcp:send(Socket, "ob"),
+ test_server:sleep(1000),
+ gen_tcp:send(Socket, "ar</BODY></HTML>");
+ "/invalid_http.html" ->
+ "HTTP/1.1 301\r\nDate:Sun, 09 Dec 2007 13:04:18 GMT\r\n" ++
+ "Transfer-Encoding:chunked\r\n\r\n";
+ "/missing_reason_phrase.html" ->
+ "HTTP/1.1 200\r\n" ++
+ "Content-Length: 32\r\n\r\n"
+ "<HTML><BODY>foobar</BODY></HTML>";
+ "/missing_CR.html" ->
+ "HTTP/1.1 200 ok\n" ++
+ "Content-Length:32\r\n\n"
+ "<HTML><BODY>foobar</BODY></HTML>";
+ _ ->
+ DefaultResponse
+ end,
+
+ tsp("handle_http_msg -> Msg: ~p", [Msg]),
+ case Msg of
+ ok ->
+ %% Previously, this resulted in an {error, einval}. Now what?
+ ok;
+ close ->
+ %% Nothing to send, just close
+ gen_tcp:close(Socket);
+ _ when is_list(Msg) orelse is_binary(Msg) ->
+ gen_tcp:send(Socket, Msg)
+ end,
+ tsp("handle_http_msg -> done"),
+ NextRequest.
+
+ensure_host_header_with_port([]) ->
+ false;
+ensure_host_header_with_port(["host: " ++ Host| _]) ->
+ case string:tokens(Host, [$:]) of
+ [ActualHost, Port] ->
+ tsp("ensure_host_header_with_port -> "
+ "~n ActualHost: ~p"
+ "~n Port: ~p", [ActualHost, Port]),
+ true;
+ _ ->
+ false
+ end;
+ensure_host_header_with_port([_|T]) ->
+ ensure_host_header_with_port(T).
+
+auth_header([]) ->
+ auth_header_not_found;
+auth_header(["authorization:" ++ Value | _]) ->
+ {ok, string:strip(Value)};
+auth_header([_ | Tail]) ->
+ auth_header(Tail).
+
+handle_auth("Basic " ++ UserInfo, Challange, DefaultResponse) ->
+ case string:tokens(base64:decode_to_string(UserInfo), ":") of
+ ["alladin", "sesame"] = Auth ->
+ test_server:format("Auth: ~p~n", [Auth]),
+ DefaultResponse;
+ Other ->
+ test_server:format("UnAuth: ~p~n", [Other]),
+ Challange
+ end.
+
+check_cookie([]) ->
+ test_server:fail(no_cookie_header);
+check_cookie(["cookie:" ++ _Value | _]) ->
+ ok;
+check_cookie([_Head | Tail]) ->
+ check_cookie(Tail).
+
+content_length([]) ->
+ 0;
+content_length(["content-length:" ++ Value | _]) ->
+ list_to_integer(string:strip(Value));
+content_length([_Head | Tail]) ->
+ content_length(Tail).
+
+provocate_not_modified_bug(Url) ->
+ tsp("provocate_not_modified_bug -> entry with"
+ "~n Url: ~p", [Url]),
+
+ Timeout = 15000, %% 15s should be plenty
+
+ case http:request(get, {Url, []}, [{timeout, Timeout}], []) of
+ {ok, {{_, 200, _}, ReplyHeaders, _Body}} ->
+ tsp("provocate_not_modified_bug -> received 200 reply"
+ "~n ReplyHeaders: ~p", [ReplyHeaders]),
+ Etag = pick_header(ReplyHeaders, "ETag"),
+ Last = pick_header(ReplyHeaders, "last-modified"),
+ case http:request(get, {Url, [{"If-None-Match", Etag},
+ {"If-Modified-Since", Last}]},
+ [{timeout, 15000}],
+ []) of
+ {ok, {{_, 304, _}, _, _}} -> %% The expected reply
+ tsp("provocate_not_modified_bug -> unchanged", []),
+ page_unchanged;
+ {ok, {{_, 200, _}, _, _}} ->
+ %% If the page has changed since the
+ %% last request we retry to
+ %% trigger the bug
+ tsp("provocate_not_modified_bug -> changed", []),
+ provocate_not_modified_bug(Url);
+ {error, timeout} ->
+ %% Not what we expected. Tcpdump can be used to
+ %% verify that we receive the complete http-reply
+ %% but still time out.
+ tsp("provocate_not_modified_bug -> timeout", []),
+ incorrect_result
+ end;
+ {ok, UnexpectedReply, ReplyHeaders, _} ->
+ tsp("provocate_not_modified_bug -> received unexpected reply"
+ "~n UnexpectedReply: ~p"
+ "~n ReplyHeaders: ~p", [UnexpectedReply, ReplyHeaders]),
+ unexpected_reply;
+ {error, Reason} ->
+ tsp("provocate_not_modified_bug -> unexpected failure"
+ "~n Reason: ~p", [Reason]),
+ unexpected_error
+ end.
+
+pick_header(Headers, Name) ->
+ case lists:keysearch(string:to_lower(Name), 1,
+ [{string:to_lower(X), Y} || {X, Y} <- Headers]) of
+ false ->
+ [];
+ {value, {_Key, Val}} ->
+ Val
+ end.
+
+
+not_implemented_yet() ->
+ exit(not_implemented_yet).
+
+
+expect(Command, Verify) ->
+ Result = (catch Command()),
+ Verify(Result).
+
+p(F) ->
+ p(F, []).
+
+p(F, A) ->
+ io:format("~p ~w:" ++ F ++ "~n", [self(), ?MODULE | A]).
+
+tsp(F) ->
+ tsp(F, []).
+tsp(F, A) ->
+ Timestamp = formated_timestamp(),
+ test_server:format("** ~s ** ~p ~p:" ++ F ++ "~n",
+ [Timestamp, self(), ?MODULE | A]).
+
+formated_timestamp() ->
+ format_timestamp( os:timestamp() ).
+
+format_timestamp({_N1, _N2, N3} = Now) ->
+ {Date, Time} = calendar:now_to_datetime(Now),
+ {YYYY,MM,DD} = Date,
+ {Hour,Min,Sec} = Time,
+ FormatDate =
+ io_lib:format("~.4w:~.2.0w:~.2.0w ~.2.0w:~.2.0w:~.2.0w 4~w",
+ [YYYY,MM,DD,Hour,Min,Sec,round(N3/1000)]),
+ lists:flatten(FormatDate).
+
+tsf(Reason) ->
+ test_server:fail(Reason).
+
+skip(Reason) ->
+ {skip, Reason}.
+
diff --git a/lib/inets/test/httpc_SUITE_data/Makefile.src b/lib/inets/test/httpc_SUITE_data/Makefile.src
new file mode 120000
index 0000000000..ad6e7bf9c8
--- /dev/null
+++ b/lib/inets/test/httpc_SUITE_data/Makefile.src
@@ -0,0 +1 @@
+../httpd_SUITE_data/Makefile.src \ No newline at end of file
diff --git a/lib/inets/test/httpc_SUITE_data/cgi_echo.c b/lib/inets/test/httpc_SUITE_data/cgi_echo.c
new file mode 120000
index 0000000000..38e06fe0d2
--- /dev/null
+++ b/lib/inets/test/httpc_SUITE_data/cgi_echo.c
@@ -0,0 +1 @@
+../httpd_SUITE_data/cgi_echo.c \ No newline at end of file
diff --git a/lib/inets/test/httpc_SUITE_data/dummy.html b/lib/inets/test/httpc_SUITE_data/dummy.html
new file mode 100644
index 0000000000..9a960ecc8a
--- /dev/null
+++ b/lib/inets/test/httpc_SUITE_data/dummy.html
@@ -0,0 +1,12 @@
+<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">
+<html>
+<head>
+<title>Dummy</title>
+</head>
+
+<body>
+<h1>Dummy</h1>
+
+<p>This is a dummy html file! </p>
+</body>
+</html>
diff --git a/lib/inets/test/httpc_SUITE_data/empty.html b/lib/inets/test/httpc_SUITE_data/empty.html
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/lib/inets/test/httpc_SUITE_data/empty.html
diff --git a/lib/inets/test/httpc_SUITE_data/mime.types b/lib/inets/test/httpc_SUITE_data/mime.types
new file mode 100644
index 0000000000..d2f81e4e5e
--- /dev/null
+++ b/lib/inets/test/httpc_SUITE_data/mime.types
@@ -0,0 +1,465 @@
+# This is a comment. I love comments.
+
+# MIME type Extension
+application/EDI-Consent
+application/EDI-X12
+application/EDIFACT
+application/activemessage
+application/andrew-inset ez
+application/applefile
+application/atomicmail
+application/batch-SMTP
+application/beep+xml
+application/cals-1840
+application/commonground
+application/cybercash
+application/dca-rft
+application/dec-dx
+application/dvcs
+application/eshop
+application/http
+application/hyperstudio
+application/iges
+application/index
+application/index.cmd
+application/index.obj
+application/index.response
+application/index.vnd
+application/iotp
+application/ipp
+application/isup
+application/font-tdpfr
+application/mac-binhex40 hqx
+application/mac-compactpro cpt
+application/macwriteii
+application/marc
+application/mathematica
+application/mathematica-old
+application/msword doc
+application/news-message-id
+application/news-transmission
+application/ocsp-request
+application/ocsp-response
+application/octet-stream bin dms lha lzh exe class so dll
+application/oda oda
+application/parityfec
+application/pdf pdf
+application/pgp-encrypted
+application/pgp-keys
+application/pgp-signature
+application/pkcs10
+application/pkcs7-mime
+application/pkcs7-signature
+application/pkix-cert
+application/pkix-crl
+application/pkixcmp
+application/postscript ai eps ps
+application/prs.alvestrand.titrax-sheet
+application/prs.cww
+application/prs.nprend
+application/qsig
+application/remote-printing
+application/riscos
+application/rtf
+application/sdp
+application/set-payment
+application/set-payment-initiation
+application/set-registration
+application/set-registration-initiation
+application/sgml
+application/sgml-open-catalog
+application/sieve
+application/slate
+application/smil smi smil
+application/timestamp-query
+application/timestamp-reply
+application/vemmi
+application/vnd.3M.Post-it-Notes
+application/vnd.FloGraphIt
+application/vnd.accpac.simply.aso
+application/vnd.accpac.simply.imp
+application/vnd.acucobol
+application/vnd.aether.imp
+application/vnd.anser-web-certificate-issue-initiation
+application/vnd.anser-web-funds-transfer-initiation
+application/vnd.audiograph
+application/vnd.businessobjects
+application/vnd.bmi
+application/vnd.canon-cpdl
+application/vnd.canon-lips
+application/vnd.claymore
+application/vnd.commerce-battelle
+application/vnd.commonspace
+application/vnd.comsocaller
+application/vnd.contact.cmsg
+application/vnd.cosmocaller
+application/vnd.cups-postscript
+application/vnd.cups-raster
+application/vnd.cups-raw
+application/vnd.ctc-posml
+application/vnd.cybank
+application/vnd.dna
+application/vnd.dpgraph
+application/vnd.dxr
+application/vnd.ecdis-update
+application/vnd.ecowin.chart
+application/vnd.ecowin.filerequest
+application/vnd.ecowin.fileupdate
+application/vnd.ecowin.series
+application/vnd.ecowin.seriesrequest
+application/vnd.ecowin.seriesupdate
+application/vnd.enliven
+application/vnd.epson.esf
+application/vnd.epson.msf
+application/vnd.epson.quickanime
+application/vnd.epson.salt
+application/vnd.epson.ssf
+application/vnd.ericsson.quickcall
+application/vnd.eudora.data
+application/vnd.fdf
+application/vnd.ffsns
+application/vnd.framemaker
+application/vnd.fsc.weblaunch
+application/vnd.fujitsu.oasys
+application/vnd.fujitsu.oasys2
+application/vnd.fujitsu.oasys3
+application/vnd.fujitsu.oasysgp
+application/vnd.fujitsu.oasysprs
+application/vnd.fujixerox.ddd
+application/vnd.fujixerox.docuworks
+application/vnd.fujixerox.docuworks.binder
+application/vnd.fut-misnet
+application/vnd.grafeq
+application/vnd.groove-account
+application/vnd.groove-identity-message
+application/vnd.groove-injector
+application/vnd.groove-tool-message
+application/vnd.groove-tool-template
+application/vnd.groove-vcard
+application/vnd.hhe.lesson-player
+application/vnd.hp-HPGL
+application/vnd.hp-PCL
+application/vnd.hp-PCLXL
+application/vnd.hp-hpid
+application/vnd.hp-hps
+application/vnd.httphone
+application/vnd.hzn-3d-crossword
+application/vnd.ibm.afplinedata
+application/vnd.ibm.MiniPay
+application/vnd.ibm.modcap
+application/vnd.informix-visionary
+application/vnd.intercon.formnet
+application/vnd.intertrust.digibox
+application/vnd.intertrust.nncp
+application/vnd.intu.qbo
+application/vnd.intu.qfx
+application/vnd.irepository.package+xml
+application/vnd.is-xpr
+application/vnd.japannet-directory-service
+application/vnd.japannet-jpnstore-wakeup
+application/vnd.japannet-payment-wakeup
+application/vnd.japannet-registration
+application/vnd.japannet-registration-wakeup
+application/vnd.japannet-setstore-wakeup
+application/vnd.japannet-verification
+application/vnd.japannet-verification-wakeup
+application/vnd.koan
+application/vnd.lotus-1-2-3
+application/vnd.lotus-approach
+application/vnd.lotus-freelance
+application/vnd.lotus-notes
+application/vnd.lotus-organizer
+application/vnd.lotus-screencam
+application/vnd.lotus-wordpro
+application/vnd.mcd
+application/vnd.mediastation.cdkey
+application/vnd.meridian-slingshot
+application/vnd.mif mif
+application/vnd.minisoft-hp3000-save
+application/vnd.mitsubishi.misty-guard.trustweb
+application/vnd.mobius.daf
+application/vnd.mobius.dis
+application/vnd.mobius.msl
+application/vnd.mobius.plc
+application/vnd.mobius.txf
+application/vnd.motorola.flexsuite
+application/vnd.motorola.flexsuite.adsi
+application/vnd.motorola.flexsuite.fis
+application/vnd.motorola.flexsuite.gotap
+application/vnd.motorola.flexsuite.kmr
+application/vnd.motorola.flexsuite.ttc
+application/vnd.motorola.flexsuite.wem
+application/vnd.mozilla.xul+xml
+application/vnd.ms-artgalry
+application/vnd.ms-asf
+application/vnd.ms-excel xls
+application/vnd.ms-lrm
+application/vnd.ms-powerpoint ppt
+application/vnd.ms-project
+application/vnd.ms-tnef
+application/vnd.ms-works
+application/vnd.mseq
+application/vnd.msign
+application/vnd.music-niff
+application/vnd.musician
+application/vnd.netfpx
+application/vnd.noblenet-directory
+application/vnd.noblenet-sealer
+application/vnd.noblenet-web
+application/vnd.novadigm.EDM
+application/vnd.novadigm.EDX
+application/vnd.novadigm.EXT
+application/vnd.osa.netdeploy
+application/vnd.palm
+application/vnd.pg.format
+application/vnd.pg.osasli
+application/vnd.powerbuilder6
+application/vnd.powerbuilder6-s
+application/vnd.powerbuilder7
+application/vnd.powerbuilder7-s
+application/vnd.powerbuilder75
+application/vnd.powerbuilder75-s
+application/vnd.previewsystems.box
+application/vnd.publishare-delta-tree
+application/vnd.pvi.ptid1
+application/vnd.pwg-xhtml-print+xml
+application/vnd.rapid
+application/vnd.s3sms
+application/vnd.seemail
+application/vnd.shana.informed.formdata
+application/vnd.shana.informed.formtemplate
+application/vnd.shana.informed.interchange
+application/vnd.shana.informed.package
+application/vnd.sss-cod
+application/vnd.sss-dtf
+application/vnd.sss-ntf
+application/vnd.street-stream
+application/vnd.svd
+application/vnd.swiftview-ics
+application/vnd.triscape.mxs
+application/vnd.trueapp
+application/vnd.truedoc
+application/vnd.tve-trigger
+application/vnd.ufdl
+application/vnd.uplanet.alert
+application/vnd.uplanet.alert-wbxml
+application/vnd.uplanet.bearer-choice-wbxml
+application/vnd.uplanet.bearer-choice
+application/vnd.uplanet.cacheop
+application/vnd.uplanet.cacheop-wbxml
+application/vnd.uplanet.channel
+application/vnd.uplanet.channel-wbxml
+application/vnd.uplanet.list
+application/vnd.uplanet.list-wbxml
+application/vnd.uplanet.listcmd
+application/vnd.uplanet.listcmd-wbxml
+application/vnd.uplanet.signal
+application/vnd.vcx
+application/vnd.vectorworks
+application/vnd.vidsoft.vidconference
+application/vnd.visio
+application/vnd.vividence.scriptfile
+application/vnd.wap.sic
+application/vnd.wap.slc
+application/vnd.wap.wbxml wbxml
+application/vnd.wap.wmlc wmlc
+application/vnd.wap.wmlscriptc wmlsc
+application/vnd.webturbo
+application/vnd.wrq-hp3000-labelled
+application/vnd.wt.stf
+application/vnd.xara
+application/vnd.xfdl
+application/vnd.yellowriver-custom-menu
+application/whoispp-query
+application/whoispp-response
+application/wita
+application/wordperfect5.1
+application/x-bcpio bcpio
+application/x-cdlink vcd
+application/x-chess-pgn pgn
+application/x-compress
+application/x-cpio cpio
+application/x-csh csh
+application/x-director dcr dir dxr
+application/x-dvi dvi
+application/x-futuresplash spl
+application/x-gtar gtar
+application/x-gzip
+application/x-hdf hdf
+application/x-javascript js
+application/x-koan skp skd skt skm
+application/x-latex latex
+application/x-netcdf nc cdf
+application/x-sh sh
+application/x-shar shar
+application/x-shockwave-flash swf
+application/x-stuffit sit
+application/x-sv4cpio sv4cpio
+application/x-sv4crc sv4crc
+application/x-tar tar
+application/x-tcl tcl
+application/x-tex tex
+application/x-texinfo texinfo texi
+application/x-troff t tr roff
+application/x-troff-man man
+application/x-troff-me me
+application/x-troff-ms ms
+application/x-ustar ustar
+application/x-wais-source src
+application/x400-bp
+application/xml
+application/xml-dtd
+application/xml-external-parsed-entity
+application/zip zip
+audio/32kadpcm
+audio/basic au snd
+audio/g.722.1
+audio/l16
+audio/midi mid midi kar
+audio/mp4a-latm
+audio/mpa-robust
+audio/mpeg mpga mp2 mp3
+audio/parityfec
+audio/prs.sid
+audio/telephone-event
+audio/tone
+audio/vnd.cisco.nse
+audio/vnd.cns.anp1
+audio/vnd.cns.inf1
+audio/vnd.digital-winds
+audio/vnd.everad.plj
+audio/vnd.lucent.voice
+audio/vnd.nortel.vbk
+audio/vnd.nuera.ecelp4800
+audio/vnd.nuera.ecelp7470
+audio/vnd.nuera.ecelp9600
+audio/vnd.octel.sbc
+audio/vnd.qcelp
+audio/vnd.rhetorex.32kadpcm
+audio/vnd.vmx.cvsd
+audio/x-aiff aif aiff aifc
+audio/x-mpegurl m3u
+audio/x-pn-realaudio ram rm
+audio/x-pn-realaudio-plugin rpm
+audio/x-realaudio ra
+audio/x-wav wav
+chemical/x-pdb pdb
+chemical/x-xyz xyz
+image/bmp bmp
+image/cgm
+image/g3fax
+image/gif gif
+image/ief ief
+image/jpeg jpeg jpg jpe
+image/naplps
+image/png png
+image/prs.btif
+image/prs.pti
+image/tiff tiff tif
+image/vnd.cns.inf2
+image/vnd.dwg
+image/vnd.dxf
+image/vnd.fastbidsheet
+image/vnd.fpx
+image/vnd.fst
+image/vnd.fujixerox.edmics-mmr
+image/vnd.fujixerox.edmics-rlc
+image/vnd.mix
+image/vnd.net-fpx
+image/vnd.svf
+image/vnd.wap.wbmp wbmp
+image/vnd.xiff
+image/x-cmu-raster ras
+image/x-portable-anymap pnm
+image/x-portable-bitmap pbm
+image/x-portable-graymap pgm
+image/x-portable-pixmap ppm
+image/x-rgb rgb
+image/x-xbitmap xbm
+image/x-xpixmap xpm
+image/x-xwindowdump xwd
+message/delivery-status
+message/disposition-notification
+message/external-body
+message/http
+message/news
+message/partial
+message/rfc822
+message/s-http
+model/iges igs iges
+model/mesh msh mesh silo
+model/vnd.dwf
+model/vnd.flatland.3dml
+model/vnd.gdl
+model/vnd.gs-gdl
+model/vnd.gtw
+model/vnd.mts
+model/vnd.vtu
+model/vrml wrl vrml
+multipart/alternative
+multipart/appledouble
+multipart/byteranges
+multipart/digest
+multipart/encrypted
+multipart/form-data
+multipart/header-set
+multipart/mixed
+multipart/parallel
+multipart/related
+multipart/report
+multipart/signed
+multipart/voice-message
+text/calendar
+text/css css
+text/directory
+text/enriched
+text/html html htm
+text/parityfec
+text/plain asc txt
+text/prs.lines.tag
+text/rfc822-headers
+text/richtext rtx
+text/rtf rtf
+text/sgml sgml sgm
+text/tab-separated-values tsv
+text/t140
+text/uri-list
+text/vnd.DMClientScript
+text/vnd.IPTC.NITF
+text/vnd.IPTC.NewsML
+text/vnd.abc
+text/vnd.curl
+text/vnd.flatland.3dml
+text/vnd.fly
+text/vnd.fmi.flexstor
+text/vnd.in3d.3dml
+text/vnd.in3d.spot
+text/vnd.latex-z
+text/vnd.motorola.reflex
+text/vnd.ms-mediapackage
+text/vnd.wap.si
+text/vnd.wap.sl
+text/vnd.wap.wml wml
+text/vnd.wap.wmlscript wmls
+text/x-setext etx
+text/x-server-parsed-html shtml
+text/xml xml xsl
+text/xml-external-parsed-entity
+video/mp4v-es
+video/mpeg mpeg mpg mpe
+video/parityfec
+video/pointer
+video/quicktime qt mov
+video/vnd.fvt
+video/vnd.motorola.video
+video/vnd.motorola.videop
+video/vnd.mpegurl mxu
+video/vnd.mts
+video/vnd.nokia.interleaved-multimedia
+video/vnd.vivo
+video/x-msvideo avi
+video/x-sgi-movie movie
+x-conference/x-cooltalk ice
+
+
+
diff --git a/lib/inets/test/httpc_SUITE_data/redirect.html b/lib/inets/test/httpc_SUITE_data/redirect.html
new file mode 100644
index 0000000000..7034461ed6
--- /dev/null
+++ b/lib/inets/test/httpc_SUITE_data/redirect.html
@@ -0,0 +1,10 @@
+<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">
+<html> <head>
+<meta http-eqviv="Refresh", content="10;URL=http://localhost:8888/dummy.html">
+<title>Redirect</title>
+
+</head>
+
+<body>
+<p> You will be redirected</p>
+</body> </html>
diff --git a/lib/inets/test/httpc_SUITE_data/ssl_client_cert.pem b/lib/inets/test/httpc_SUITE_data/ssl_client_cert.pem
new file mode 100644
index 0000000000..f274d2021d
--- /dev/null
+++ b/lib/inets/test/httpc_SUITE_data/ssl_client_cert.pem
@@ -0,0 +1,22 @@
+-----BEGIN RSA PRIVATE KEY-----
+MIIBOwIBAAJBANz7eFvORmJDi1XJMM2U3uHC5wmp/DXTLMw08XaEvtZ73wgVg84E
+V0oyX3Kh1thRE3Hch9AyrHjgpizCj9/Ra38CAwEAAQJACzpz2SZYCTIpaEh6xFdm
+I86FcsZCXHHIeu/NvRntoHQ+nfM7Np379+z6XNJWIcWh/QgG/jNJalR1BO+eyc6/
+YQIhAP3m8M0LDxJwSgHFtGAGatQqaqw9l48Kq5xdMFqvdpiHAiEA3s7lld6yCJYu
+6q7fZjTH+eKUwgg0vpgJutP7Fsok60kCIHHesQBEhW3vjkFdOZgXSLH+k/jLZr1w
+O6bU5GrHZpjhAiEAyTvGYcjDtTunXjDY9l+fadK6FlEBCk8ZIpNIiTnDhHkCIQDr
+QxxLLuNHRj8iWNbuVVZ99SJy8zC33pMgPFaFKaZesQ==
+-----END RSA PRIVATE KEY-----
+-----BEGIN CERTIFICATE-----
+MIIB7jCCAZgCAQAwDQYJKoZIhvcNAQEEBQAwgYExCzAJBgNVBAYTAlNFMRIwEAYD
+VQQHEwlTdG9ja2hvbG0xETAPBgNVBAoTCEVyaWNzc29uMQwwCgYDVQQLEwNFVFgx
+FjAUBgNVBAMTDUhlbGVuIEFpcml5YW4xJTAjBgkqhkiG9w0BCQEWFmhlbGVuQGVy
+aXguZXJpY3Nzb24uc2UwHhcNOTcwNzI4MDcxNDI1WhcNOTgxMjEwMDcxNDI1WjCB
+gTELMAkGA1UEBhMCU0UxEjAQBgNVBAcTCVN0b2NraG9sbTERMA8GA1UEChMIRXJp
+Y3Nzb24xDDAKBgNVBAsTA0VUWDEWMBQGA1UEAxMNSGVsZW4gQWlyaXlhbjElMCMG
+CSqGSIb3DQEJARYWaGVsZW5AZXJpeC5lcmljc3Nvbi5zZTBcMA0GCSqGSIb3DQEB
+AQUAA0sAMEgCQQDc+3hbzkZiQ4tVyTDNlN7hwucJqfw10yzMNPF2hL7We98IFYPO
+BFdKMl9yodbYURNx3IfQMqx44KYswo/f0Wt/AgMBAAEwDQYJKoZIhvcNAQEEBQAD
+QQC2++hLIaQJ4ChCjFE9UCfXO9cZ3Vq/FT9VjE+G4MRBDo4LQ5mBKNXcPF6EFZmi
+7XrlvopXkVPlRguTi2SLRPkY
+-----END CERTIFICATE-----
diff --git a/lib/inets/test/httpc_SUITE_data/ssl_server_cert.pem b/lib/inets/test/httpc_SUITE_data/ssl_server_cert.pem
new file mode 100644
index 0000000000..f01b6c992b
--- /dev/null
+++ b/lib/inets/test/httpc_SUITE_data/ssl_server_cert.pem
@@ -0,0 +1,22 @@
+-----BEGIN RSA PRIVATE KEY-----
+MIIBOQIBAAJBAMe2WhP6s+JeKOwWPEjI9susfN4Vjn2dd1X4QUlOETcWVLoF916m
+M4JU+ms7+ciMR8GRNCsIeqZGY8/GSqm74ccCAwEAAQJAF08YKlbLYfM9cXiS5qfV
+7iWemUkIzW5wfC8yZ3zeE4Cp6R9ViUfs/dadQ/23Cw0Bpo2t8UdTUdCa4KpmqOem
+cQIhAOnxTWZ5eo6h6PXDp7L5FZUACg8+wT3qf5f2is2mbSZPAiEA2orUY8JZDTSk
+Rm7q9WxLiLNtORsXdTCmnCWhqBOYpwkCIErdowRxScxNekz0IT3AQqzdR1rbnWHg
+IpcSGhd39CQ3AiA1XvQxjLP8wp9fyBS/bPwhXVhOOuyGpSP7PEF3b5m3KQIgGQWc
+/a5wuWx3pc3mLx0ILwNoJr2ubFEuW1PJPsPJPv0=
+-----END RSA PRIVATE KEY-----
+-----BEGIN CERTIFICATE-----
+MIIB7jCCAZgCAQAwDQYJKoZIhvcNAQEEBQAwgYExCzAJBgNVBAYTAlNFMRIwEAYD
+VQQHEwlTdG9ja2hvbG0xETAPBgNVBAoTCEVyaWNzc29uMQwwCgYDVQQLEwNFVFgx
+FjAUBgNVBAMTDUhlbGVuIEFpcml5YW4xJTAjBgkqhkiG9w0BCQEWFmhlbGVuQGVy
+aXguZXJpY3Nzb24uc2UwHhcNOTcwNzI4MDcyMTAwWhcNOTgxMjEwMDcyMTAwWjCB
+gTELMAkGA1UEBhMCU0UxEjAQBgNVBAcTCVN0b2NraG9sbTERMA8GA1UEChMIRXJp
+Y3Nzb24xDDAKBgNVBAsTA0VUWDEWMBQGA1UEAxMNSGVsZW4gQWlyaXlhbjElMCMG
+CSqGSIb3DQEJARYWaGVsZW5AZXJpeC5lcmljc3Nvbi5zZTBcMA0GCSqGSIb3DQEB
+AQUAA0sAMEgCQQDHtloT+rPiXijsFjxIyPbLrHzeFY59nXdV+EFJThE3FlS6Bfde
+pjOCVPprO/nIjEfBkTQrCHqmRmPPxkqpu+HHAgMBAAEwDQYJKoZIhvcNAQEEBQAD
+QQCnU1TkxmfbLdUwjdECb5x9QHCevAR7AmTms4Csn2oOEyPX+bgF2d94xhrV1sxO
+Rs0yigk1PtN17Ci0Dey0LYkR
+-----END CERTIFICATE-----
diff --git a/lib/inets/test/httpc_cookie_SUITE.erl b/lib/inets/test/httpc_cookie_SUITE.erl
new file mode 100644
index 0000000000..ad5df656c6
--- /dev/null
+++ b/lib/inets/test/httpc_cookie_SUITE.erl
@@ -0,0 +1,451 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 2005-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(httpc_cookie_SUITE).
+
+-include("test_server.hrl").
+-include_lib("stdlib/include/ms_transform.hrl").
+
+%% Test server specific exports
+-export([all/1, init_per_testcase/2, end_per_testcase/2]).
+
+%% Test cases must be exported.
+-export([session_cookies_only/1, netscape_cookies/1,
+ cookie_cancel/1, cookie_expires/1, persistent_cookie/1,
+ domain_cookie/1, secure_cookie/1, update_cookie/1,
+ update_cookie_session/1, cookie_attributes/1]).
+
+-define(URL, "http://myhost.cookie.test.org").
+-define(URL_DOMAIN, "http://myhost2.cookie.test.org").
+-define(URL_SECURE, "https://myhost.cookie.test.org").
+
+%% Test server callback functions
+
+%%--------------------------------------------------------------------
+%% 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: Initiation 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: Initiation before each test case
+%%--------------------------------------------------------------------
+init_per_testcase(session_cookies_only = Case, Config0) ->
+ tsp("init_per_testcase(~p) -> entry with"
+ "~n Config0: ~p", [Case, Config0]),
+ Config = init_workdir(Case, Config0),
+ application:start(inets),
+ http:set_options([{cookies, verify}]),
+ watch_dog(Config);
+
+init_per_testcase(Case, Config0) ->
+ tsp("init_per_testcase(~p) -> entry with"
+ "~n Config0: ~p", [Case, Config0]),
+ Config = init_workdir(Case, Config0),
+ CaseDir = ?config(case_top_dir, Config),
+ application:load(inets),
+ application:set_env(inets, services, [{httpc, {default, CaseDir}}]),
+ application:start(inets),
+ http:set_options([{cookies, verify}]),
+ watch_dog(Config).
+
+watch_dog(Config) ->
+ Dog = test_server:timetrap(inets_test_lib:minutes(10)),
+ NewConfig = lists:keydelete(watchdog, 1, Config),
+ [{watchdog, Dog} | NewConfig].
+
+init_workdir(Case, Config) ->
+ PrivDir = ?config(priv_dir, Config),
+ SuiteTopDir = filename:join(PrivDir, ?MODULE),
+ case file:make_dir(SuiteTopDir) of
+ ok ->
+ ok;
+ {error, eexist} ->
+ ok;
+ Error ->
+ tsf({failed_creating_subsuite_top_dir, Error})
+ end,
+
+ CaseTopDir = filename:join(SuiteTopDir, Case),
+ ?line ok = file:make_dir(CaseTopDir),
+ [{suite_top_dir, SuiteTopDir},
+ {case_top_dir, CaseTopDir} | 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(Case, Config) ->
+ tsp("end_per_testcase(~p) -> entry with"
+ "~n Config: ~p", [Case, Config]),
+ application:stop(inets),
+ Dog = ?config(watchdog, Config),
+ test_server:timetrap_cancel(Dog),
+ ok.
+
+%%--------------------------------------------------------------------
+%% Function: all(Clause) -> TestCases
+%% Clause - atom() - suite | doc
+%% TestCases - [Case]
+%% Case - atom()
+%% Name of a test case.
+%% Description: Returns a list of all test cases in this test suite
+%%--------------------------------------------------------------------
+all(doc) ->
+ ["Describe the main purpose of this suite"];
+
+all(suite) ->
+ [
+ session_cookies_only,
+ netscape_cookies,
+ cookie_cancel,
+ cookie_expires,
+ persistent_cookie,
+ domain_cookie,
+ secure_cookie,
+ update_cookie,
+ update_cookie_session,
+ cookie_attributes
+ ].
+
+%% Test cases starts here.
+%%--------------------------------------------------------------------
+session_cookies_only(doc) ->
+ ["Test that all cookies are handled as session cookies if there"
+ "does not exist a directory to save presitent cookies in."];
+session_cookies_only(suite) ->
+ [];
+session_cookies_only(Config) when is_list(Config) ->
+ tsp("session_cookies_only -> Cookies 1: ~p", [httpc:which_cookies()]),
+
+ SetCookieHeaders = [{"set-cookie", "test_cookie=true; path=/;"
+ ";max-age=60000"}],
+ http:verify_cookies(SetCookieHeaders, ?URL),
+ {"cookie","$Version=0; test_cookie=true; $Path=/"}
+ = http:cookie_header(?URL),
+ application:stop(inets),
+ application:start(inets),
+ {"cookie",""} = http:cookie_header(?URL),
+
+ tsp("session_cookies_only -> Cookies 2: ~p", [httpc:which_cookies()]),
+ ok.
+
+netscape_cookies(doc) ->
+ ["Test that the old (original) format of cookies are accepted."];
+netscape_cookies(suite) ->
+ [];
+netscape_cookies(Config) when is_list(Config) ->
+ tsp("netscape_cookies -> Cookies 1: ~p", [httpc:which_cookies()]),
+
+ Expires = future_netscape_date(),
+ SetCookieHeaders = [{"set-cookie", "test_cookie=true; path=/; "
+ "expires=" ++ Expires}],
+ http:verify_cookies(SetCookieHeaders, ?URL),
+ {"cookie","$Version=0; test_cookie=true; $Path=/"} =
+ http:cookie_header(?URL),
+
+ tsp("netscape_cookies -> Cookies 2: ~p", [httpc:which_cookies()]),
+ ok.
+
+cookie_cancel(doc) ->
+ ["A cookie can be canceld by sending the same cookie with max-age=0 "
+ "this test cheks that cookie is canceled."];
+cookie_cancel(suite) ->
+ [];
+cookie_cancel(Config) when is_list(Config) ->
+ tsp("cookie_cancel -> Cookies 1: ~p", [httpc:which_cookies()]),
+
+ SetCookieHeaders = [{"set-cookie", "test_cookie=true; path=/;"
+ "max-age=60000"}],
+ http:verify_cookies(SetCookieHeaders, ?URL),
+ {"cookie","$Version=0; test_cookie=true; $Path=/"}
+ = http:cookie_header(?URL),
+ NewSetCookieHeaders = [{"set-cookie", "test_cookie=true; path=/;"
+ "max-age=0"}],
+ http:verify_cookies(NewSetCookieHeaders, ?URL),
+ {"cookie", ""} = http:cookie_header(?URL),
+
+ tsp("cookie_cancel -> Cookies 2: ~p", [httpc:which_cookies()]),
+ ok.
+
+cookie_expires(doc) ->
+ ["Test that a cookie is not used when it has expired"];
+cookie_expires(suite) ->
+ [];
+cookie_expires(Config) when is_list(Config) ->
+ tsp("cookie_expires -> Cookies 1: ~p", [httpc:which_cookies()]),
+
+ SetCookieHeaders = [{"set-cookie", "test_cookie=true; path=/;"
+ "max-age=5"}],
+ http:verify_cookies(SetCookieHeaders, ?URL),
+ {"cookie","$Version=0; test_cookie=true; $Path=/"}
+ = http:cookie_header(?URL),
+ test_server:sleep(10000),
+ {"cookie", ""} = http:cookie_header(?URL),
+
+ tsp("cookie_expires -> Cookies 2: ~p", [httpc:which_cookies()]),
+ ok.
+
+persistent_cookie(doc) ->
+ ["Test domian cookie attribute"];
+persistent_cookie(suite) ->
+ [];
+persistent_cookie(Config) when is_list(Config)->
+ tsp("persistent_cookie -> Cookies 1: ~p", [httpc:which_cookies()]),
+
+ SetCookieHeaders = [{"set-cookie", "test_cookie=true; path=/;"
+ "max-age=60000"}],
+ http:verify_cookies(SetCookieHeaders, ?URL),
+ {"cookie","$Version=0; test_cookie=true; $Path=/"} =
+ http:cookie_header(?URL),
+ CaseDir = ?config(case_top_dir, Config),
+ application:stop(inets),
+ application:load(inets),
+ application:set_env(inets, services, [{httpc, {default, CaseDir}}]),
+ application:start(inets),
+ http:set_options([{cookies, enabled}]),
+ {"cookie","$Version=0; test_cookie=true; $Path=/"} = http:cookie_header(?URL),
+
+ tsp("persistent_cookie -> Cookies 2: ~p", [httpc:which_cookies()]),
+ ok.
+
+
+domain_cookie(doc) ->
+ ["Test the domian cookie attribute"];
+domain_cookie(suite) ->
+ [];
+domain_cookie(Config) when is_list(Config) ->
+ tsp("domain_cookie -> Cookies 1: ~p", [httpc:which_cookies()]),
+
+ SetCookieHeaders = [{"set-cookie", "test_cookie=true; path=/;"
+ "domain=.cookie.test.org"}],
+ http:verify_cookies(SetCookieHeaders, ?URL),
+ {"cookie","$Version=0; test_cookie=true; $Path=/; "
+ "$Domain=.cookie.test.org"} =
+ http:cookie_header(?URL_DOMAIN),
+
+ tsp("domain_cookie -> Cookies 2: ~p", [httpc:which_cookies()]),
+ ok.
+
+
+secure_cookie(doc) ->
+ ["Test the secure cookie attribute"];
+secure_cookie(suite) ->
+ [];
+secure_cookie(Config) when is_list(Config) ->
+ tsp("secure_cookie -> entry with"
+ "~n Config: ~p", [Config]),
+
+ inets:enable_trace(max, io, httpc),
+
+ %% httpc:reset_cookies(),
+
+ tsp("secure_cookie -> Cookies 1: ~p", [httpc:which_cookies()]),
+
+ SetCookieHeaders = [{"set-cookie", "test_cookie=true; path=/; secure"}],
+ tsp("secure_cookie -> verify cookies (1)"),
+ ok = http:verify_cookies(SetCookieHeaders, ?URL),
+
+ tsp("secure_cookie -> Cookies 2: ~p", [httpc:which_cookies()]),
+
+ tsp("secure_cookie -> check cookie (secure)"),
+ check_cookie("$Version=0; test_cookie=true; $Path=/", ?URL_SECURE),
+
+ tsp("secure_cookie -> check cookie (plain)"),
+ check_cookie("", ?URL),
+
+ tsp("secure_cookie -> verify cookies (2)"),
+ SetCookieHeaders1 = [{"set-cookie", "test1_cookie=true; path=/; secure"}],
+ ok = http:verify_cookies(SetCookieHeaders1, ?URL),
+
+ tsp("secure_cookie -> Cookies 3: ~p", [httpc:which_cookies()]),
+
+ tsp("secure_cookie -> cookie header (3)"),
+ check_cookie("$Version=0; test_cookie=true; $Path=/; "
+ "test1_cookie=true; $Path=/",
+ ?URL_SECURE),
+%% {"cookie","$Version=0; test_cookie=true; $Path=/; "
+%% "test1_cookie=true; $Path=/"} = http:cookie_header(?URL_SECURE),
+
+ tsp("secure_cookie -> Cookies 4: ~p", [httpc:which_cookies()]),
+
+ inets:disable_trace(),
+ tsp("secure_cookie -> done"),
+ ok.
+
+update_cookie(doc)->
+ ["Test that a cookie can be updated."];
+update_cookie(suite) ->
+ [];
+update_cookie(Config) when is_list(Config)->
+ SetCookieHeaders = [{"set-cookie", "test_cookie=true; path=/;"
+ "max-age=6500"},
+ {"set-cookie", "test_cookie2=true; path=/;"
+ "max-age=6500"}],
+ http:verify_cookies(SetCookieHeaders, ?URL),
+ {"cookie", "$Version=0; test_cookie2=true; $Path=/; "
+ "test_cookie=true; $Path=/"} = http:cookie_header(?URL),
+ NewSetCookieHeaders = [{"set-cookie", "test_cookie=false; "
+ "path=/;max-age=6500"}],
+ http:verify_cookies(NewSetCookieHeaders, ?URL),
+ {"cookie", "$Version=0; test_cookie2=true; $Path=/; "
+ "test_cookie=false; $Path=/"} = http:cookie_header(?URL).
+
+update_cookie_session(doc)->
+ ["Test that a cookie can be updated."];
+update_cookie_session(suite) ->
+ [];
+update_cookie_session(Config) when is_list(Config)->
+ SetCookieHeaders = [{"set-cookie", "test_cookie=true; path=/"},
+ {"set-cookie", "test_cookie2=true; path=/"}],
+ http:verify_cookies(SetCookieHeaders, ?URL),
+ {"cookie", "$Version=0; test_cookie2=true; $Path=/; "
+ "test_cookie=true; $Path=/"} = http:cookie_header(?URL),
+ NewSetCookieHeaders = [{"set-cookie", "test_cookie=false; path=/"}],
+ http:verify_cookies(NewSetCookieHeaders, ?URL),
+ {"cookie", "$Version=0; test_cookie2=true; $Path=/; "
+ "test_cookie=false; $Path=/"} = http:cookie_header(?URL).
+
+
+cookie_attributes(doc) ->
+ ["Test attribute not covered by the other test cases"];
+cookie_attributes(suite) ->
+ [];
+cookie_attributes(Config) when is_list(Config) ->
+ SetCookieHeaders = [{"set-cookie", "test_cookie=true;version=1;"
+ "comment=foobar; "%% Comment
+ "foo=bar;" %% Nonsense should be ignored
+ "max-age=60000"}],
+ http:verify_cookies(SetCookieHeaders, ?URL),
+ {"cookie","$Version=1; test_cookie=true"} = http:cookie_header(?URL),
+ ok.
+
+
+%%--------------------------------------------------------------------
+%%% Internal functions
+%%--------------------------------------------------------------------
+
+check_cookie(Expect, URL) ->
+ case http:cookie_header(URL) of
+ {"cookie", Expect} ->
+ ok;
+ {"cookie", Unexpected} ->
+ case lists:prefix(Expect, Unexpected) of
+ true ->
+ Extra = Unexpected -- Expect,
+ tsf({extra_cookie_info, Extra});
+ false ->
+ tsf({unknown_cookie, Expect, Unexpected})
+ end;
+ Bad ->
+ tsf({bad_cookies, Bad})
+ end.
+
+
+future_netscape_date() ->
+ [Day, DD, Mon, YYYY] = netscape_date(date()),
+ lists:flatten(io_lib:format("~s, ~s ~s ~s 12:30:00 GMT",
+ [Day, DD, Mon, YYYY])).
+
+netscape_date({Year, 12, _}) ->
+ NewYear = Year + 1,
+ NewMonth = 1,
+ NewDay = calendar:last_day_of_the_month(NewYear, NewMonth),
+ WeekDay = calendar:day_of_the_week(NewYear, NewMonth, NewDay),
+ WeekDayNrStr = day_nr_str(NewDay),
+ NewDayStr = week_day_str(WeekDay),
+ MonthStr = month_str(NewMonth),
+ [NewDayStr, WeekDayNrStr, MonthStr, integer_to_list(NewYear)];
+
+netscape_date({Year, Month, _}) ->
+ NewMonth = Month + 1,
+ NewDay = calendar:last_day_of_the_month(Year, NewMonth),
+ WeekDay = calendar:day_of_the_week(Year, NewMonth, NewDay),
+ WeekDayNrStr = day_nr_str(NewDay),
+ NewDayStr = week_day_str(WeekDay),
+ MonthStr = month_str(NewMonth),
+ [NewDayStr, WeekDayNrStr, MonthStr, integer_to_list(Year)].
+
+week_day_str(1) ->
+ "Mon";
+week_day_str(2) ->
+ "Tus";
+week_day_str(3) ->
+ "Wdy";
+week_day_str(4) ->
+ "Thu";
+week_day_str(5) ->
+ "Fri";
+week_day_str(6) ->
+ "Sat";
+week_day_str(7) ->
+ "Sun".
+
+day_nr_str(1) ->
+ "01";
+day_nr_str(2) ->
+ "02";
+day_nr_str(3) ->
+ "03";
+day_nr_str(4) ->
+ "04";
+day_nr_str(5) ->
+ "05";
+day_nr_str(6) ->
+ "06";
+day_nr_str(7) ->
+ "07";
+day_nr_str(8) ->
+ "08";
+day_nr_str(0) ->
+ "09";
+day_nr_str(N) ->
+ integer_to_list(N).
+
+month_str(1) ->"Jan";
+month_str(2) ->"Feb";
+month_str(3) ->"Mar";
+month_str(4) ->"Apr";
+month_str(5) ->"May";
+month_str(6) ->"Jun";
+month_str(7) ->"Jul";
+month_str(8) ->"Aug";
+month_str(9) ->"Sep";
+month_str(10) ->"Oct";
+month_str(11) ->"Nov";
+month_str(12) ->"Dec".
+
+
+tsp(F) ->
+ tsp(F, []).
+tsp(F, A) ->
+ test_server:format("~p ~p:" ++ F ++ "~n", [self(), ?MODULE | A]).
+
+tsf(Reason) ->
+ test_server:fail(Reason).
+
diff --git a/lib/inets/test/httpc_internal.hrl b/lib/inets/test/httpc_internal.hrl
new file mode 120000
index 0000000000..bef2c94879
--- /dev/null
+++ b/lib/inets/test/httpc_internal.hrl
@@ -0,0 +1 @@
+../src/http_client/httpc_internal.hrl \ No newline at end of file
diff --git a/lib/inets/test/httpd_1_1.erl b/lib/inets/test/httpd_1_1.erl
new file mode 100644
index 0000000000..07d94ea97a
--- /dev/null
+++ b/lib/inets/test/httpd_1_1.erl
@@ -0,0 +1,502 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 2005-2011. All Rights Reserved.
+%%
+%% The contents of this file are subject to the Erlang Public License,
+%% Version 1.1, (the "License"); you may not use this file except in
+%% compliance with the License. You should have received a copy of the
+%% Erlang Public License along with this software. If not, it can be
+%% retrieved online at http://www.erlang.org/.
+%%
+%% Software distributed under the License is distributed on an "AS IS"
+%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+%% the License for the specific language governing rights and limitations
+%% under the License.
+%%
+%% %CopyrightEnd%
+%%
+%%
+
+-module(httpd_1_1).
+
+-include("test_server.hrl").
+-include("test_server_line.hrl").
+-include_lib("kernel/include/file.hrl").
+
+-export([host/4, chunked/4, expect/4, range/4, if_test/5, http_trace/4,
+ head/4, mod_cgi_chunked_encoding_test/5]).
+
+%% -define(all_keys_lower_case,true).
+-ifndef(all_keys_lower_case).
+-define(CONTENT_LENGTH, "Content-Length: ").
+-define(CONTENT_RANGE, "Content-Range: ").
+-define(CONTENT_TYPE, "Content-Type: ").
+-else.
+-define(CONTENT_LENGTH, "content-length:").
+-define(CONTENT_RANGE, "content-range:").
+-define(CONTENT_TYPE, "content-type:").
+-endif.
+
+
+%%-------------------------------------------------------------------------
+%% Test cases starts here.
+%%-------------------------------------------------------------------------
+host(Type, Port, Host, Node) ->
+ %% No host needed for HTTP/1.0
+ ok = httpd_test_lib:verify_request(Type, Host, Port, Node,
+ "GET / HTTP/1.0\r\n\r\n",
+ [{statuscode, 200},
+ {version, "HTTP/1.0"}]),
+ %% No host must generate an error
+ ok = httpd_test_lib:verify_request(Type, Host, Port, Node,
+ "GET / HTTP/1.1\r\n\r\n",
+ [{statuscode, 400}]),
+
+ %% If it is a fully qualified URL no host is needed
+ ok = httpd_test_lib:verify_request(Type, Host, Port, Node,
+ "GET HTTP://"++ Host ++ ":" ++
+ integer_to_list(Port)++
+ "/ HTTP/1.1\r\n\r\n",
+ [{statuscode, 200}]),
+
+ %% If both look at the url.
+ ok = httpd_test_lib:verify_request(Type, Host, Port, Node,
+ "GET HTTP://"++ Host ++ ":"++
+ integer_to_list(Port) ++
+ "/ HTTP/1.1\r\nHost:"++ Host ++
+ "\r\n\r\n",[{statuscode, 200}]),
+
+ %% Allow the request if its a Host field
+ ok = httpd_test_lib:verify_request(Type, Host, Port, Node,
+ "GET / HTTP/1.1\r\nHost:"++
+ Host ++ "\r\n\r\n",
+ [{statuscode, 200}]),
+ ok.
+
+chunked(Type, Port, Host, Node)->
+ ok = httpd_test_lib:verify_request(Type, Host, Port, Node,
+ "GET / HTTP/1.1\r\n"
+ "Host:"++ Host ++"\r\n"
+ "Transfer-Encoding:chunked\r\n"
+ "\r\n"
+ "A\r\n"
+ "1234567890\r\n"
+ "4\r\n"
+ "HEJ!\r\n"
+ "0\r\n\r\n",
+ [{statuscode, 200}]),
+
+ ok = httpd_test_lib:verify_request(Type, Host, Port, Node,
+ "GET / HTTP/1.1\r\n"
+ "Host:"++ Host ++"\r\n"
+ "Transfer-Encoding:chunked\r\n"
+ "Trailer:Content-Type\r\n"
+ "\r\n"
+ "A\r\n"
+ "1234567890\r\n"
+ "4\r\n"
+ "HEJ!\r\n"
+ "0\r\n"
+ "Content-Type:text/plain\r\n\r\n",
+ [{statuscode, 200}]),
+ ok.
+
+expect(Type, Port, Host, Node)->
+ Request="GET / HTTP/1.1\r\nHost:" ++ Host ++
+ "\r\nContent-Length:22\r\nExpect:100-continue\r\n\r\n",
+
+ ok = httpd_test_lib:verify_request(Type, Host, Port, Node,
+ Request,
+ [{statuscode, 100}]).
+range(Type, Port, Host, Node)->
+
+ ok = httpd_test_lib:verify_request(Type, Host, Port, Node,
+ "GET /range.txt HTTP/1.1\r\nHost:"
+ ++ Host
+ ++ "\r\nRange:bytes=110-120\r\n\r\n",
+ [{statuscode,416}]),
+ %%The simples of all range request a range
+ Request1="GET /range.txt HTTP/1.1\r\nHost:" ++ Host ++
+ "\r\nRange:bytes=0-9\r\n\r\n",
+ {ok, Socket1} = inets_test_lib:connect_byte(Type, Host, Port),
+ inets_test_lib:send(Type, Socket1,Request1),
+ ok = validateRangeRequest(Socket1,[],"1234567890",$2,$0,$6),
+ inets_test_lib:close(Type,Socket1),
+
+ %% Request the end of the file
+ Request2 =
+ "GET /range.txt HTTP/1.1\r\nHost:" ++ Host ++
+ "\r\nRange:bytes=90-\r\n\r\n",
+
+ {ok, Socket2} = inets_test_lib:connect_byte(Type, Host, Port),
+ inets_test_lib:send(Type, Socket2, Request2),
+ ok = validateRangeRequest(Socket2,[],"1234567890",$2,$0,$6),
+ inets_test_lib:close(Type,Socket2),
+
+ %% The last byte in the file
+ Request3 =
+ "GET /range.txt HTTP/1.1\r\nHost:"++
+ Host ++ "\r\nRange:bytes=-1\r\n\r\n",
+ {ok, Socket3} = inets_test_lib:connect_byte(Type, Host, Port),
+ inets_test_lib:send(Type, Socket3,Request3),
+ ok = validateRangeRequest(Socket3,[],"0",$2,$0,$6),
+ inets_test_lib:close(Type, Socket3),
+
+ %%Multi Range
+ Request4 = "GET /range.txt HTTP/1.1\r\nHost:" ++ Host ++
+ "\r\nRange:bytes=0-0,2-2,-1\r\n\r\n",
+ {ok, Socket4} = inets_test_lib:connect_byte(Type, Host, Port),
+ inets_test_lib:send(Type, Socket4, Request4),
+ ok = validateRangeRequest(Socket4,[],"130",$2,$0,$6),
+ inets_test_lib:close(Type, Socket4).
+
+if_test(Type, Port, Host, Node, DocRoot)->
+ {ok, FileInfo} =
+ file:read_file_info(filename:join([DocRoot,"index.html"])),
+ CreatedSec =
+ calendar:datetime_to_gregorian_seconds(FileInfo#file_info.mtime),
+
+ Mod = httpd_util:rfc1123_date(calendar:gregorian_seconds_to_datetime(
+ CreatedSec-1)),
+
+ %% Test that we get the data when the file is modified
+ ok = httpd_test_lib:verify_request(Type, Host, Port, Node,
+ "GET / HTTP/1.1\r\nHost:" ++ Host ++
+ "\r\nIf-Modified-Since:" ++
+ Mod ++ "\r\n\r\n",
+ [{statuscode, 200}]),
+ Mod1 = httpd_util:rfc1123_date(calendar:gregorian_seconds_to_datetime(
+ CreatedSec+100)),
+ ok = httpd_test_lib:verify_request(Type,Host,Port,Node,
+ "GET / HTTP/1.1\r\nHost:"
+ ++ Host ++"\r\nIf-Modified-Since:"
+ ++ Mod1 ++"\r\n\r\n",
+ [{statuscode, 304}]),
+
+
+ ok = httpd_test_lib:verify_request(Type, Host, Port, Node,
+ "GET / HTTP/1.1\r\nHost:" ++ Host ++
+ "\r\nIf-Modified-Since:" ++
+ "AAA[...]AAAA" ++ "\r\n\r\n",
+ [{statuscode, 400}]),
+
+
+ Mod2 = httpd_util:rfc1123_date(calendar:gregorian_seconds_to_datetime(
+ CreatedSec+1)),
+ %% Control that the If-Unmodified-Header lmits the response
+ ok = httpd_test_lib:verify_request(Type,Host,Port,Node,
+ "GET / HTTP/1.1\r\nHost:"
+ ++ Host ++
+ "\r\nIf-Unmodified-Since:" ++ Mod2
+ ++ "\r\n\r\n",
+ [{statuscode, 200}]),
+ Mod3 = httpd_util:rfc1123_date(calendar:gregorian_seconds_to_datetime(
+ CreatedSec-1)),
+
+ ok = httpd_test_lib:verify_request(Type, Host, Port, Node,
+ "GET / HTTP/1.1\r\nHost:"
+ ++ Host ++
+ "\r\nIf-Unmodified-Since:"++ Mod3
+ ++"\r\n\r\n",
+ [{statuscode, 412}]),
+
+ %% Control that we get the body when the etag match
+ ok = httpd_test_lib:verify_request(Type, Host, Port, Node,
+ "GET / HTTP/1.1\r\nHost:" ++ Host
+ ++"\r\n"++
+ "If-Match:"++
+ httpd_util:create_etag(FileInfo)++
+ "\r\n\r\n",
+ [{statuscode, 200}]),
+ ok = httpd_test_lib:verify_request(Type, Host, Port, Node,
+ "GET / HTTP/1.1\r\nHost:" ++
+ Host ++ "\r\n"++
+ "If-Match:NotEtag\r\n\r\n",
+ [{statuscode, 412}]),
+
+ %% Control the response when the if-none-match header is there
+ ok = httpd_test_lib:verify_request(Type, Host, Port, Node,
+ "GET / HTTP/1.1\r\nHost:"
+ ++ Host ++"\r\n"++
+ "If-None-Match:NoTaag," ++
+ httpd_util:create_etag(FileInfo) ++
+ "\r\n\r\n",
+ [{statuscode, 304}]),
+
+ ok = httpd_test_lib:verify_request(Type, Host, Port, Node,
+ "GET / HTTP/1.1\r\nHost:"
+ ++ Host ++ "\r\n"++
+ "If-None-Match:NotEtag,"
+ "NeihterEtag\r\n\r\n",
+ [{statuscode,200}]),
+ ok.
+
+http_trace(Type, Port, Host, Node)->
+ ok = httpd_test_lib:verify_request(Type, Host, Port, Node,
+ "TRACE / HTTP/1.1\r\n" ++
+ "Host:" ++ Host ++ "\r\n" ++
+ "Max-Forwards:2\r\n\r\n",
+ [{statuscode, 200}]),
+ ok = httpd_test_lib:verify_request(Type, Host, Port, Node,
+ "TRACE / HTTP/1.0\r\n\r\n",
+ [{statuscode, 501},
+ {version, "HTTP/1.0"}]).
+head(Type, Port, Host, Node)->
+ %% mod_include
+ ok = httpd_test_lib:verify_request(Type, Host, Port, Node,
+ "HEAD /fsize.shtml HTTP/1.0\r\n\r\n",
+ [{statuscode, 200},
+ {version, "HTTP/1.0"}]),
+ ok = httpd_test_lib:verify_request(Type, Host, Port, Node,
+ "HEAD /fsize.shtml HTTP/1.1\r\nhost:" ++
+ Host ++ "\r\n\r\n", [{statuscode, 200}]),
+ %% mod_esi
+ ok = httpd_test_lib:verify_request(Type, Host, Port, Node,
+ "HEAD /cgi-bin/erl/httpd_example/newformat"
+ " HTTP/1.0\r\n\r\n", [{statuscode, 200},
+ {version, "HTTP/1.0"}]),
+ ok = httpd_test_lib:verify_request(Type, Host, Port, Node,
+ "HEAD /cgi-bin/erl/httpd_example/newformat "
+ "HTTP/1.1\r\nhost:" ++ Host ++ "\r\n\r\n",
+ [{statuscode, 200}]),
+ %% mod_cgi
+ Script =
+ case test_server:os_type() of
+ {win32, _} ->
+ "printenv.bat";
+ _ ->
+ "printenv.sh"
+ end,
+ ok = httpd_test_lib:verify_request(Type,Host,Port,Node,"HEAD /cgi-bin/"
+ ++ Script ++ " HTTP/1.0\r\n\r\n",
+ [{statuscode, 200},
+ {version, "HTTP/1.0"}]),
+ ok = httpd_test_lib:verify_request(Type,Host,Port,Node, "HEAD /cgi-bin/"
+ ++ Script ++ " HTTP/1.1\r\nhost:" ++
+ Host ++ "\r\n\r\n",
+ [{statuscode, 200}]).
+
+mod_cgi_chunked_encoding_test(_, _, _, _, [])->
+ ok;
+mod_cgi_chunked_encoding_test(Type, Port, Host, Node, [Request| Rest])->
+ ok = httpd_test_lib:verify_request(Type, Host, Port, Node, Request,
+ [{statuscode, 200}]),
+ mod_cgi_chunked_encoding_test(Type, Port, Host, Node, Rest).
+
+%%--------------------------------------------------------------------
+%% Internal functions
+%%--------------------------------------------------------------------
+validateRangeRequest(Socket,Response,ValidBody,C,O,DE)->
+ receive
+ {tcp,Socket,Data} ->
+ case string:str(Data,"\r\n") of
+ 0->
+ validateRangeRequest(Socket,
+ Response ++ Data,
+ ValidBody, C, O, DE);
+ _N ->
+ case Response ++ Data of
+ [$H,$T,$T,$P,$/,$1,$.,$1,$ ,C,O,DE | _Rest]->
+ case [C,O,DE] of
+ "206" ->
+ validateRangeRequest1(Socket,
+ Response ++ Data,
+ ValidBody);
+ _ ->
+ bad_code
+ end;
+ _->
+ error
+ end
+ end;
+ _Error ->
+ error
+ end.
+
+validateRangeRequest1(Socket, Response, ValidBody) ->
+ case end_of_header(Response) of
+ false ->
+ receive
+ {tcp,Socket,Data} ->
+ validateRangeRequest1(Socket, Response ++ Data,
+ ValidBody);
+ _->
+ error
+ end;
+ {true, Head1, Body, _Size} ->
+ %% In this case size will be 0 if it is a multipart so
+ %% don't use it.
+ validateRangeRequest2(Socket, Head1, Body, ValidBody,
+ getRangeSize(Head1))
+ end.
+
+validateRangeRequest2(Socket, Head, Body, ValidBody, {multiPart,Boundary})->
+ case endReached(Body,Boundary) of
+ true ->
+ validateMultiPartRangeRequest(Body, ValidBody, Boundary);
+ false->
+ receive
+ {tcp, Socket, Data} ->
+ validateRangeRequest2(Socket, Head, Body ++ Data,
+ ValidBody, {multiPart, Boundary});
+ {tcp_closed, Socket} ->
+ error;
+ _ ->
+ error
+ end
+ end;
+
+validateRangeRequest2(Socket, Head, Body, ValidBody, BodySize)
+ when is_integer(BodySize) ->
+ case length(Body) of
+ Size when Size =:= BodySize ->
+ case Body of
+ ValidBody ->
+ ok;
+ Body ->
+ error
+ end;
+ Size when Size < BodySize ->
+ receive
+ {tcp, Socket, Data} ->
+ validateRangeRequest2(Socket, Head,
+ Body ++ Data, ValidBody, BodySize);
+ _ ->
+ error
+ end;
+ _ ->
+ error
+ end.
+
+
+validateMultiPartRangeRequest(Body, ValidBody, Boundary)->
+ case inets_regexp:split(Body,"--"++Boundary++"--") of
+ %%Last is the epilogue and must be ignored
+ {ok,[First | _Last]}->
+ %%First is now the actuall http request body.
+ case inets_regexp:split(First, "--" ++ Boundary) of
+ %%Parts is now a list of ranges and the heads for each range
+ %%Gues we try to split out the body
+ {ok,Parts}->
+ case lists:flatten(lists:map(fun splitRange/1,Parts)) of
+ ValidBody->
+ ok;
+ ParsedBody->
+ error = ParsedBody
+ end
+ end;
+ _ ->
+ error
+ end.
+
+
+splitRange(Part)->
+ case inets_regexp:split(Part, "\r\n\r\n") of
+ {ok,[_, Body]} ->
+ string:substr(Body, 1, length(Body) - 2);
+ _ ->
+ []
+ end.
+
+endReached(Body, Boundary)->
+ EndBound = "--" ++ Boundary ++ "--",
+ case string:str(Body, EndBound) of
+ 0 ->
+ false;
+ _ ->
+ true
+ end.
+
+getRangeSize(Head)->
+ case controlMimeType(Head) of
+ {multiPart, BoundaryString}->
+ {multiPart, BoundaryString};
+ _X1 ->
+ case inets_regexp:match(Head, ?CONTENT_RANGE "bytes=.*\r\n") of
+ {match, Start, Lenght} ->
+ %% Get the range data remove the fieldname and the
+ %% end of line.
+ RangeInfo = string:substr(Head, Start + 20,
+ Lenght - (20 - 2)),
+ rangeSize(RangeInfo);
+ _X2 ->
+ error
+ end
+ end.
+%%RangeInfo is NNN1-NNN2/NNN3
+%%NNN1=RangeStartByte
+%%NNN2=RangeEndByte
+%%NNN3=total amount of bytes in file
+rangeSize([$=|RangeInfo]) ->
+ rangeSize(RangeInfo);
+rangeSize(RangeInfo) ->
+ StartByte = lists:takewhile(fun(X)->
+ num(X, true)
+ end, RangeInfo),
+ RangeInfo2 = string:substr(RangeInfo, length(StartByte) + 2),
+ EndByte = lists:takewhile(fun(X)->
+ num(X,true)
+ end, RangeInfo2),
+ case list_to_integer(EndByte) - list_to_integer(StartByte) of
+ Val when is_number(Val) ->
+ %%Add one since it is startByte to endbyte ie 0-0 is 1
+ %%byte 0-99 is 100 bytes
+ Val + 1;
+ _Val ->
+ error
+ end.
+
+num(CharVal, RetVal) when (CharVal >= 48) andalso (CharVal =< 57) ->
+ RetVal;
+num(_CharVal, true) ->
+ false;
+num(_CharVal, false) ->
+ true.
+
+controlMimeType(Head)->
+ case inets_regexp:match(Head,?CONTENT_TYPE "multipart/byteranges.*\r\n") of
+ {match,Start,Length}->
+ FieldNameLen = length(?CONTENT_TYPE "multipart/byteranges"),
+ case clearBoundary(string:substr(Head, Start + FieldNameLen,
+ Length - (FieldNameLen+2))) of
+ error ->
+ error;
+ BoundaryStr ->
+ {multiPart,BoundaryStr}
+ end;
+ nomatch->
+ 0;
+ _ ->
+ error
+ end.
+
+clearBoundary(Boundary)->
+ case inets_regexp:match(Boundary, "boundary=.*\$") of
+ {match, Start1, Length1}->
+ BoundLen = length("boundary="),
+ string:substr(Boundary, Start1 + BoundLen, Length1 - BoundLen);
+ _ ->
+ error
+ end.
+
+
+end_of_header(HeaderPart) ->
+ case httpd_util:split(HeaderPart,"\r\n\r\n",2) of
+ {ok, [Head, Body]} ->
+ {true, Head, Body, get_body_size(Head)};
+ _Pos ->
+ false
+ end.
+
+get_body_size(Head) ->
+ case inets_regexp:match(Head,?CONTENT_LENGTH ".*\r\n") of
+ {match, Start, Length} ->
+ %% 15 is length of Content-Length,
+ %% 17 Is length of Content-Length and \r\
+ S = list_to_integer(
+ string:strip(string:substr(Head, Start + 15, Length-17))),
+ S;
+ _->
+ 0
+ end.
diff --git a/lib/inets/test/httpd_SUITE.erl b/lib/inets/test/httpd_SUITE.erl
new file mode 100644
index 0000000000..731a50c70b
--- /dev/null
+++ b/lib/inets/test/httpd_SUITE.erl
@@ -0,0 +1,2081 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 2005-2011. All Rights Reserved.
+%%
+%% The contents of this file are subject to the Erlang Public License,
+%% Version 1.1, (the "License"); you may not use this file except in
+%% compliance with the License. You should have received a copy of the
+%% Erlang Public License along with this software. If not, it can be
+%% retrieved online at http://www.erlang.org/.
+%%
+%% Software distributed under the License is distributed on an "AS IS"
+%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+%% the License for the specific language governing rights and limitations
+%% under the License.
+%%
+%% %CopyrightEnd%
+%%
+%%
+
+-module(httpd_SUITE).
+
+-include("test_server.hrl").
+-include("test_server_line.hrl").
+-include("inets_test_lib.hrl").
+
+-include_lib("kernel/include/file.hrl").
+
+%% Test server specific exports
+-export([all/1]).
+-export([init_per_testcase/2, end_per_testcase/2,
+ init_per_suite/1, end_per_suite/1]).
+
+%% Test cases must be exported.
+-export([ip/1, ssl/1, http_1_1_ip/1, http_1_0_ip/1, http_0_9_ip/1,
+ ipv6/1, tickets/1]).
+
+%% Core Server tests
+-export([ip_mod_alias/1, ip_mod_actions/1, ip_mod_security/1, ip_mod_auth/1,
+ ip_mod_auth_api/1, ip_mod_auth_mnesia_api/1,
+ ip_mod_htaccess/1, ip_mod_cgi/1, ip_mod_esi/1,
+ ip_mod_get/1, ip_mod_head/1, ip_mod_all/1, ip_load_light/1,
+ ip_load_medium/1, ip_load_heavy/1, ip_dos_hostname/1,
+ ip_time_test/1, ip_block_disturbing_idle/1,
+ ip_block_non_disturbing_idle/1, ip_block_503/1,
+ ip_block_disturbing_active/1, ip_block_non_disturbing_active/1,
+ ip_block_disturbing_active_timeout_not_released/1,
+ ip_block_disturbing_active_timeout_released/1,
+ ip_block_non_disturbing_active_timeout_not_released/1,
+ ip_block_non_disturbing_active_timeout_released/1,
+ ip_block_disturbing_blocker_dies/1,
+ ip_block_non_disturbing_blocker_dies/1,
+ ip_restart_no_block/1, ip_restart_disturbing_block/1,
+ ip_restart_non_disturbing_block/1
+ ]).
+
+-export([ssl_mod_alias/1, ssl_mod_actions/1, ssl_mod_security/1,
+ ssl_mod_auth/1, ssl_mod_auth_api/1,
+ ssl_mod_auth_mnesia_api/1, ssl_mod_htaccess/1,
+ ssl_mod_cgi/1, ssl_mod_esi/1, ssl_mod_get/1, ssl_mod_head/1,
+ ssl_mod_all/1, ssl_load_light/1, ssl_load_medium/1,
+ ssl_load_heavy/1, ssl_dos_hostname/1, ssl_time_test/1,
+ ssl_restart_no_block/1, ssl_restart_disturbing_block/1,
+ ssl_restart_non_disturbing_block/1, ssl_block_disturbing_idle/1,
+ ssl_block_non_disturbing_idle/1, ssl_block_503/1,
+ ssl_block_disturbing_active/1, ssl_block_non_disturbing_active/1,
+ ssl_block_disturbing_active_timeout_not_released/1,
+ ssl_block_disturbing_active_timeout_released/1,
+ ssl_block_non_disturbing_active_timeout_not_released/1,
+ ssl_block_non_disturbing_active_timeout_released/1,
+ ssl_block_disturbing_blocker_dies/1,
+ ssl_block_non_disturbing_blocker_dies/1]).
+
+%%% HTTP 1.1 tests
+-export([ip_host/1, ip_chunked/1, ip_expect/1, ip_range/1,
+ ip_if_test/1, ip_http_trace/1, ip_http1_1_head/1,
+ ip_mod_cgi_chunked_encoding_test/1]).
+
+%%% HTTP 1.0 tests
+-export([ip_head_1_0/1, ip_get_1_0/1, ip_post_1_0/1]).
+
+%%% HTTP 0.9 tests
+-export([ip_get_0_9/1]).
+
+%%% Ticket tests
+-export([ticket_5775/1,ticket_5865/1,ticket_5913/1,ticket_6003/1,
+ ticket_7304/1]).
+
+%%% Misc
+-export([ipv6_hostname/1, ipv6_address/1]).
+
+%% Help functions
+-export([cleanup_mnesia/0, setup_mnesia/0, setup_mnesia/1]).
+
+-define(IP_PORT, 8898).
+-define(SSL_PORT, 8899).
+-define(MAX_HEADER_SIZE, 256).
+-define(IPV6_LOCAL_HOST, "0:0:0:0:0:0:0:1").
+
+%% Minutes before failed auths timeout.
+-define(FAIL_EXPIRE_TIME,1).
+
+%% Seconds before successful auths timeout.
+-define(AUTH_TIMEOUT,5).
+
+-record(httpd_user, {user_name, password, user_data}).
+-record(httpd_group,{group_name, userlist}).
+
+
+%%--------------------------------------------------------------------
+%% all(Arg) -> [Doc] | [Case] | {skip, Comment}
+%% Arg - doc | suite
+%% Doc - string()
+%% Case - atom()
+%% Name of a test case function.
+%% Comment - string()
+%% Description: Returns documentation/test cases in this test suite
+%% or a skip tuple if the platform is not supported.
+%%--------------------------------------------------------------------
+all(doc) ->
+ ["Test the http server in the intes application."];
+all(suite) ->
+ [
+ ip,
+ ssl,
+ http_1_1_ip,
+ http_1_0_ip,
+ http_0_9_ip,
+ ipv6,
+ tickets
+ ].
+
+%%--------------------------------------------------------------------
+%% Function: init_per_suite(Config) -> Config
+%% Config - [tuple()]
+%% A list of key/value pairs, holding the test case configuration.
+%% Description: Initiation 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) ->
+ io:format(user, "init_per_suite -> entry with"
+ "~n Config: ~p"
+ "~n", [Config]),
+
+ PrivDir = ?config(priv_dir, Config),
+ SuiteTopDir = filename:join(PrivDir, ?MODULE),
+ case file:make_dir(SuiteTopDir) of
+ ok ->
+ ok;
+ {error, eexist} ->
+ ok;
+ Error ->
+ throw({error, {failed_creating_suite_top_dir, Error}})
+ end,
+
+ [{suite_top_dir, SuiteTopDir},
+ {node, node()},
+ {host, inets_test_lib:hostname()},
+ {address, getaddr()} | 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) ->
+ %% SuiteTopDir = ?config(suite_top_dir, Config),
+ %% inets_test_lib:del_dirs(SuiteTopDir),
+ ok.
+
+
+%%--------------------------------------------------------------------
+%% Function: init_per_testcase(Case, 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: Initiation 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.
+%%--------------------------------------------------------------------
+init_per_testcase(Case, Config) ->
+ NewConfig = init_per_testcase2(Case, Config),
+ init_per_testcase3(Case, NewConfig).
+
+
+init_per_testcase2(Case, Config) ->
+
+ io:format(user, "~w:init_per_testcase2(~w) -> entry with"
+ "~n Config: ~p"
+ "~n", [?MODULE, Case, Config]),
+
+ IpNormal = integer_to_list(?IP_PORT) ++ ".conf",
+ IpHtacess = integer_to_list(?IP_PORT) ++ "htacess.conf",
+ SslNormal = integer_to_list(?SSL_PORT) ++ ".conf",
+ SslHtacess = integer_to_list(?SSL_PORT) ++ "htacess.conf",
+
+ DataDir = ?config(data_dir, Config),
+ SuiteTopDir = ?config(suite_top_dir, Config),
+
+ io:format(user, "~w:init_per_testcase2(~w) -> "
+ "~n SuiteDir: ~p"
+ "~n DataDir: ~p"
+ "~n", [?MODULE, Case, SuiteTopDir, DataDir]),
+
+ TcTopDir = filename:join(SuiteTopDir, Case),
+ ?line ok = file:make_dir(TcTopDir),
+
+ io:format(user, "~w:init_per_testcase2(~w) -> "
+ "~n TcTopDir: ~p"
+ "~n", [?MODULE, Case, TcTopDir]),
+
+ DataSrc = filename:join([DataDir, "server_root"]),
+ ServerRoot = filename:join([TcTopDir, "server_root"]),
+
+ io:format(user, "~w:init_per_testcase2(~w) -> "
+ "~n DataSrc: ~p"
+ "~n ServerRoot: ~p"
+ "~n", [?MODULE, Case, DataSrc, ServerRoot]),
+
+ ok = file:make_dir(ServerRoot),
+ ok = file:make_dir(filename:join([TcTopDir, "logs"])),
+
+ NewConfig = [{tc_top_dir, TcTopDir}, {server_root, ServerRoot} | Config],
+
+ io:format(user, "~w:init_per_testcase2(~w) -> "
+ "copy DataSrc to ServerRoot~n",
+ [?MODULE, Case]),
+
+ inets_test_lib:copy_dirs(DataSrc, ServerRoot),
+
+ io:format(user, "~w:init_per_testcase2(~w) -> fix cgi~n",
+ [?MODULE, Case]),
+ EnvCGI = filename:join([ServerRoot, "cgi-bin", "printenv.sh"]),
+ {ok, FileInfo} = file:read_file_info(EnvCGI),
+ ok = file:write_file_info(EnvCGI,
+ FileInfo#file_info{mode = 8#00755}),
+
+ EchoCGI = case test_server:os_type() of
+ {win32, _} ->
+ "cgi_echo.exe";
+ _ ->
+ "cgi_echo"
+ end,
+ CGIDir = filename:join([ServerRoot, "cgi-bin"]),
+ inets_test_lib:copy_file(EchoCGI, DataDir, CGIDir),
+ NewEchoCGI = filename:join([CGIDir, EchoCGI]),
+ {ok, FileInfo1} = file:read_file_info(NewEchoCGI),
+ ok = file:write_file_info(NewEchoCGI,
+ FileInfo1#file_info{mode = 8#00755}),
+
+ %% To be used by IP test cases
+ io:format(user, "~w:init_per_testcase2(~w) -> ip testcase setups~n",
+ [?MODULE, Case]),
+ create_config([{port, ?IP_PORT}, {sock_type, ip_comm} | NewConfig],
+ normal_acess, IpNormal),
+ create_config([{port, ?IP_PORT}, {sock_type, ip_comm} | NewConfig],
+ mod_htaccess, IpHtacess),
+
+ %% To be used by SSL test cases
+ io:format(user, "~w:init_per_testcase2(~w) -> ssl testcase setups~n",
+ [?MODULE, Case]),
+ create_config([{port, ?SSL_PORT}, {sock_type, ssl} | NewConfig],
+ normal_acess, SslNormal),
+ create_config([{port, ?SSL_PORT}, {sock_type, ssl} | NewConfig],
+ mod_htaccess, SslHtacess),
+
+ %% To be used by IPv6 test cases. Case-clause is so that
+ %% you can do ts:run(inets, httpd_SUITE, <test case>)
+ %% for all cases except the ipv6 cases as they depend
+ %% on 'test_host_ipv6_only' that will only be present
+ %% when you run the whole test suite due to shortcomings
+ %% of the test server.
+ %% case (catch ?config(test_host_ipv6_only, Config)) of
+ %% {_,IPv6Host,IPv6Adress,_,_} ->
+ %% create_ipv6_config([{port, ?IP_PORT},
+ %% {sock_type, ip_comm} | NewConfig],
+ %% "ipv6_hostname.conf", IPv6Host),
+ %% create_ipv6_config([{port, ?IP_PORT},
+ %% {sock_type, ip_comm} | NewConfig],
+ %% "ipv6_address.conf", IPv6Adress);
+ %% _ ->
+ %% ok
+ %% end,
+
+ io:format(user, "~w:init_per_testcase2(~w) -> done~n",
+ [?MODULE, Case]),
+
+ NewConfig.
+
+
+init_per_testcase3(Case, Config) ->
+ io:format(user, "~w:init_per_testcase3(~w) -> entry with"
+ "~n Config: ~p", [?MODULE, Case, Config]),
+
+ %% Clean up (we do not want this clean up in end_per_testcase
+ %% if init_per_testcase crases for some testcase it will
+ %% have contaminated the environment and there will be no clean up.)
+ %% This init can take a few different paths so that one crashes
+ %% does not mean that all invocations will.
+
+ application:unset_env(inets, services),
+ application:stop(inets),
+ application:stop(ssl),
+ cleanup_mnesia(),
+
+ %% TraceLevel = max,
+ TraceLevel = 70,
+ TraceDest = io,
+ inets:enable_trace(TraceLevel, TraceDest),
+
+ %% Start initialization
+ io:format(user, "~w:init_per_testcase3(~w) -> start init",
+ [?MODULE, Case]),
+
+ Dog = test_server:timetrap(inets_test_lib:minutes(10)),
+ NewConfig = lists:keydelete(watchdog, 1, Config),
+ TcTopDir = ?config(tc_top_dir, Config),
+ CaseRest =
+ case atom_to_list(Case) of
+ "ip_mod_htaccess" ->
+ inets_test_lib:start_http_server(
+ filename:join(TcTopDir,
+ integer_to_list(?IP_PORT) ++
+ "htacess.conf")),
+ "mod_htaccess";
+ "ip_" ++ Rest ->
+ inets_test_lib:start_http_server(
+ filename:join(TcTopDir,
+ integer_to_list(?IP_PORT) ++ ".conf")),
+ Rest;
+ "ticket_5913" ->
+ HttpdOptions =
+ [{file,
+ filename:join(TcTopDir,
+ integer_to_list(?IP_PORT) ++ ".conf")},
+ {accept_timeout,30000},
+ {debug,[{exported_functions,
+ [httpd_manager,httpd_request_handler]}]}],
+ inets_test_lib:start_http_server(HttpdOptions);
+ "ticket_"++Rest ->
+ %% OTP-5913 use the new syntax of inets.config
+ inets_test_lib:start_http_server([{file,
+ filename:join(TcTopDir,
+ integer_to_list(?IP_PORT) ++ ".conf")}]),
+ Rest;
+ "ssl_mod_htaccess" ->
+ case inets_test_lib:start_http_server_ssl(
+ filename:join(TcTopDir,
+ integer_to_list(?SSL_PORT) ++
+ "htacess.conf")) of
+ ok ->
+ "mod_htaccess";
+ Other ->
+ error_logger:info_report("Other: ~p~n", [Other]),
+ {skip, "SSL does not seem to be supported"}
+ end;
+ "ssl_" ++ Rest ->
+ case inets_test_lib:start_http_server_ssl(
+ filename:join(TcTopDir,
+ integer_to_list(?SSL_PORT) ++
+ ".conf")) of
+ ok ->
+ Rest;
+ Other ->
+ error_logger:info_report("Other: ~p~n", [Other]),
+ {skip, "SSL does not seem to be supported"}
+ end;
+ "ipv6_" ++ _ = TestCaseStr ->
+ {ok, Hostname} = inet:gethostname(),
+
+ case lists:member(list_to_atom(Hostname),
+ ?config(ipv6_hosts, Config)) of
+ true ->
+ inets_test_lib:start_http_server(
+ filename:join(TcTopDir,
+ TestCaseStr ++ ".conf"));
+
+ false ->
+ {skip, "Host does not support IPv6"}
+ end
+ end,
+
+ case CaseRest of
+ {skip, _} = Skip ->
+ Skip;
+ "mod_auth_" ++ _ ->
+ start_mnesia(?config(node, Config)),
+ [{watchdog, Dog} | NewConfig];
+ "mod_htaccess" ->
+ ServerRoot = ?config(server_root, Config),
+ Path = filename:join([ServerRoot, "htdocs"]),
+ catch remove_htacess(Path),
+ create_htacess_data(Path, ?config(address, Config)),
+ [{watchdog, Dog} | NewConfig];
+ "range" ->
+ ServerRoot = ?config(server_root, Config),
+ Path = filename:join([ServerRoot, "htdocs"]),
+ create_range_data(Path),
+ [{watchdog, Dog} | NewConfig];
+ _ ->
+ [{watchdog, Dog} | NewConfig]
+ end.
+
+
+%%--------------------------------------------------------------------
+%% Function: end_per_testcase(Case, 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(Case, Config) ->
+ Dog = ?config(watchdog, Config),
+ test_server:timetrap_cancel(Dog),
+ end_per_testcase2(Case, lists:keydelete(watchdog, 1, Config)),
+ ok.
+
+end_per_testcase2(Case, Config) ->
+ io:format(user, "~w:end_per_testcase2(~w) -> entry with"
+ "~n Config: ~p~n",
+ [?MODULE, Case, Config]),
+ application:unset_env(inets, services),
+ application:stop(inets),
+ application:stop(ssl),
+ cleanup_mnesia(),
+ io:format(user, "~w:end_per_testcase2(~w) -> done~n",
+ [?MODULE, Case]),
+ ok.
+
+
+%%-------------------------------------------------------------------------
+%% Test cases starts here.
+%%-------------------------------------------------------------------------
+ip(doc) ->
+ ["HTTP tests using TCP/IP"];
+ip(suite) ->
+ [
+ ip_mod_alias,
+ ip_mod_actions,
+ ip_mod_security,
+ ip_mod_auth,
+ ip_mod_auth_api,
+ ip_mod_auth_mnesia_api,
+ ip_mod_htaccess,
+ ip_mod_cgi,
+ ip_mod_esi,
+ ip_mod_get,
+ ip_mod_head,
+ ip_mod_all,
+ ip_load_light,
+ ip_load_medium,
+ ip_load_heavy,
+ ip_dos_hostname,
+ ip_time_test,
+ ip_block_disturbing_idle,
+ ip_block_non_disturbing_idle,
+ ip_block_503,
+ ip_block_disturbing_active,
+ ip_block_non_disturbing_active,
+ ip_block_disturbing_active_timeout_not_released,
+ ip_block_disturbing_active_timeout_released,
+ ip_block_non_disturbing_active_timeout_not_released,
+ ip_block_non_disturbing_active_timeout_released,
+ ip_block_disturbing_blocker_dies,
+ ip_block_non_disturbing_blocker_dies,
+ ip_restart_no_block,
+ ip_restart_disturbing_block,
+ ip_restart_non_disturbing_block
+ ].
+
+%%-------------------------------------------------------------------------
+ssl(doc) ->
+ ["HTTP test using SSL"];
+ssl(suite) ->
+ [
+ ssl_mod_alias,
+ ssl_mod_actions,
+ ssl_mod_security,
+ ssl_mod_auth,
+ ssl_mod_auth_api,
+ ssl_mod_auth_mnesia_api,
+ ssl_mod_htaccess,
+ ssl_mod_cgi,
+ ssl_mod_esi,
+ ssl_mod_get,
+ ssl_mod_head,
+ ssl_mod_all,
+ ssl_load_light,
+ ssl_load_medium,
+ ssl_load_heavy,
+ ssl_dos_hostname,
+ ssl_time_test,
+ ssl_restart_no_block,
+ ssl_restart_disturbing_block,
+ ssl_restart_non_disturbing_block,
+ ssl_block_disturbing_idle,
+ ssl_block_non_disturbing_idle,
+ ssl_block_503,
+ ssl_block_disturbing_active,
+ ssl_block_non_disturbing_active,
+ ssl_block_disturbing_active_timeout_not_released,
+ ssl_block_disturbing_active_timeout_released,
+ ssl_block_non_disturbing_active_timeout_not_released,
+ ssl_block_non_disturbing_active_timeout_released,
+ ssl_block_disturbing_blocker_dies,
+ ssl_block_non_disturbing_blocker_dies
+ ].
+
+%%-------------------------------------------------------------------------
+http_1_1_ip(doc) ->
+ ["HTTP/1.1"];
+http_1_1_ip(suite) ->
+ [
+ %% ip_host,
+ %% ip_chunked,
+ %% ip_expect,
+ %% ip_range,
+ ip_if_test%% ,
+ %% ip_http_trace,
+ %% ip_http1_1_head,
+ %% ip_mod_cgi_chunked_encoding_test
+ ].
+
+%%-------------------------------------------------------------------------
+http_1_0_ip(doc) ->
+ ["HTTP/1.0"];
+http_1_0_ip(suite) ->
+ [
+ ip_head_1_0,
+ ip_get_1_0,
+ ip_post_1_0
+ ].
+
+%%-------------------------------------------------------------------------
+http_0_9_ip(doc) ->
+ ["HTTP/0.9"];
+http_0_9_ip(suite) ->
+ [
+ ip_get_0_9
+ ].
+
+%%-------------------------------------------------------------------------
+ipv6(doc) ->
+ ["Tests ipv6 functionality."];
+ipv6(suite) ->
+ [
+ ipv6_hostname,
+ ipv6_address
+ ].
+
+%%-------------------------------------------------------------------------
+tickets(doc) ->
+ ["Test cases for reported bugs."];
+tickets(suite) ->
+ [
+ ticket_5775,
+ ticket_5865,
+ ticket_5913,
+ ticket_6003,
+ ticket_7304
+ ].
+
+%%-------------------------------------------------------------------------
+ip_mod_alias(doc) ->
+ ["Module test: mod_alias"];
+ip_mod_alias(suite) ->
+ [];
+ip_mod_alias(Config) when is_list(Config) ->
+ httpd_mod:alias(ip_comm, ?IP_PORT,
+ ?config(host, Config), ?config(node, Config)),
+ ok.
+%%-------------------------------------------------------------------------
+ip_mod_actions(doc) ->
+ ["Module test: mod_actions"];
+ip_mod_actions(suite) ->
+ [];
+ip_mod_actions(Config) when is_list(Config) ->
+ httpd_mod:actions(ip_comm, ?IP_PORT,
+ ?config(host, Config), ?config(node, Config)),
+ ok.
+%%-------------------------------------------------------------------------
+ip_mod_security(doc) ->
+ ["Module test: mod_security"];
+ip_mod_security(suite) ->
+ [];
+ip_mod_security(Config) when is_list(Config) ->
+ ServerRoot = ?config(server_root, Config),
+ httpd_mod:security(ServerRoot, ip_comm, ?IP_PORT,
+ ?config(host, Config), ?config(node, Config)),
+ ok.
+
+%%-------------------------------------------------------------------------
+ip_mod_auth(doc) ->
+ ["Module test: mod_auth"];
+ip_mod_auth(suite) ->
+ [];
+ip_mod_auth(Config) when is_list(Config) ->
+ httpd_mod:auth(ip_comm, ?IP_PORT,
+ ?config(host, Config), ?config(node, Config)),
+ ok.
+
+%%-------------------------------------------------------------------------
+ip_mod_auth_api(doc) ->
+ ["Module test: mod_auth_api"];
+ip_mod_auth_api(suite) ->
+ [];
+ip_mod_auth_api(Config) when is_list(Config) ->
+ ServerRoot = ?config(server_root, Config),
+ Host = ?config(host, Config),
+ Node = ?config(node, Config),
+ httpd_mod:auth_api(ServerRoot, "", ip_comm, ?IP_PORT, Host, Node),
+ httpd_mod:auth_api(ServerRoot, "dets_", ip_comm, ?IP_PORT, Host, Node),
+ httpd_mod:auth_api(ServerRoot, "mnesia_", ip_comm, ?IP_PORT, Host, Node),
+ ok.
+%%-------------------------------------------------------------------------
+ip_mod_auth_mnesia_api(doc) ->
+ ["Module test: mod_auth_mnesia_api"];
+ip_mod_auth_mnesia_api(suite) ->
+ [];
+ip_mod_auth_mnesia_api(Config) when is_list(Config) ->
+ httpd_mod:auth_mnesia_api(ip_comm, ?IP_PORT,
+ ?config(host, Config), ?config(node, Config)),
+ ok.
+%%-------------------------------------------------------------------------
+ip_mod_htaccess(doc) ->
+ ["Module test: mod_htaccess"];
+ip_mod_htaccess(suite) ->
+ [];
+ip_mod_htaccess(Config) when is_list(Config) ->
+ httpd_mod:htaccess(ip_comm, ?IP_PORT,
+ ?config(host, Config), ?config(node, Config)),
+ ok.
+%%-------------------------------------------------------------------------
+ip_mod_cgi(doc) ->
+ ["Module test: mod_cgi"];
+ip_mod_cgi(suite) ->
+ [];
+ip_mod_cgi(Config) when is_list(Config) ->
+ case test_server:os_type() of
+ vxworks ->
+ {skip, cgi_not_supported_on_vxwoks};
+ _ ->
+ httpd_mod:cgi(ip_comm, ?IP_PORT,
+ ?config(host, Config), ?config(node, Config)),
+ ok
+ end.
+%%-------------------------------------------------------------------------
+ip_mod_esi(doc) ->
+ ["Module test: mod_esi"];
+ip_mod_esi(suite) ->
+ [];
+ip_mod_esi(Config) when is_list(Config) ->
+ httpd_mod:esi(ip_comm, ?IP_PORT,
+ ?config(host, Config), ?config(node, Config)),
+ ok.
+
+%%-------------------------------------------------------------------------
+ip_mod_get(doc) ->
+ ["Module test: mod_get"];
+ip_mod_get(suite) ->
+ [];
+ip_mod_get(Config) when is_list(Config) ->
+ httpd_mod:get(ip_comm, ?IP_PORT,
+ ?config(host, Config), ?config(node, Config)),
+ ok.
+
+%%-------------------------------------------------------------------------
+ip_mod_head(doc) ->
+ ["Module test: mod_head"];
+ip_mod_head(suite) ->
+ [];
+ip_mod_head(Config) when is_list(Config) ->
+ httpd_mod:head(ip_comm, ?IP_PORT,
+ ?config(host, Config), ?config(node, Config)),
+ ok.
+%%-------------------------------------------------------------------------
+ip_mod_all(doc) ->
+ ["All modules test"];
+ip_mod_all(suite) ->
+ [];
+ip_mod_all(Config) when is_list(Config) ->
+ httpd_mod:all(ip_comm, ?IP_PORT,
+ ?config(host, Config), ?config(node, Config)),
+ ok.
+%%-------------------------------------------------------------------------
+ip_load_light(doc) ->
+ ["Test light load"];
+ip_load_light(suite) ->
+ [];
+ip_load_light(Config) when is_list(Config) ->
+ httpd_load:load_test(ip_comm, ?IP_PORT, ?config(host, Config),
+ ?config(node, Config),
+ get_nof_clients(ip_comm, light)),
+ ok.
+%%-------------------------------------------------------------------------
+ip_load_medium(doc) ->
+ ["Test medium load"];
+ip_load_medium(suite) ->
+ [];
+ip_load_medium(Config) when is_list(Config) ->
+ httpd_load:load_test(ip_comm, ?IP_PORT, ?config(host, Config),
+ ?config(node, Config),
+ get_nof_clients(ip_comm, medium)),
+ ok.
+%%-------------------------------------------------------------------------
+ip_load_heavy(doc) ->
+ ["Test heavy load"];
+ip_load_heavy(suite) ->
+ [];
+ip_load_heavy(Config) when is_list(Config) ->
+ httpd_load:load_test(ip_comm, ?IP_PORT, ?config(host, Config),
+ ?config(node, Config),
+ get_nof_clients(ip_comm, heavy)),
+ ok.
+%%-------------------------------------------------------------------------
+ip_dos_hostname(doc) ->
+ ["Denial Of Service (DOS) attack test case"];
+ip_dos_hostname(suite) ->
+ [];
+ip_dos_hostname(Config) when is_list(Config) ->
+ dos_hostname(ip_comm, ?IP_PORT, ?config(host, Config),
+ ?config(node, Config), ?MAX_HEADER_SIZE),
+ ok.
+%%-------------------------------------------------------------------------
+ip_time_test(doc) ->
+ [""];
+ip_time_test(suite) ->
+ [];
+ip_time_test(Config) when is_list(Config) ->
+ %% <CONDITIONAL-SKIP>
+ Skippable = [win32],
+ Condition = fun() -> ?OS_BASED_SKIP(Skippable) end,
+ ?NON_PC_TC_MAYBE_SKIP(Config, Condition),
+ %% </CONDITIONAL-SKIP>
+
+ httpd_time_test:t(ip_comm, ?config(host, Config), ?IP_PORT),
+ ok.
+
+%%-------------------------------------------------------------------------
+ip_block_503(doc) ->
+ ["Check that you will receive status code 503 when the server"
+ " is blocked and 200 when its not blocked."];
+ip_block_503(suite) ->
+ [];
+ip_block_503(Config) when is_list(Config) ->
+ httpd_block:block_503(ip_comm, ?IP_PORT, ?config(host, Config),
+ ?config(node, Config)),
+ ok.
+%%-------------------------------------------------------------------------
+ip_block_disturbing_idle(doc) ->
+ ["Check that you can block/unblock an idle server. The strategy "
+ "distribing does not really make a difference in this case."];
+ip_block_disturbing_idle(suite) ->
+ [];
+ip_block_disturbing_idle(Config) when is_list(Config) ->
+ httpd_block:block_disturbing_idle(ip_comm, ?IP_PORT,
+ ?config(host, Config),
+ ?config(node, Config)),
+ ok.
+%%-------------------------------------------------------------------------
+ip_block_non_disturbing_idle(doc) ->
+ ["Check that you can block/unblock an idle server. The strategy "
+ "non distribing does not really make a difference in this case."];
+ip_block_non_disturbing_idle(suite) ->
+ [];
+ip_block_non_disturbing_idle(Config) when is_list(Config) ->
+ httpd_block:block_non_disturbing_idle(ip_comm, ?IP_PORT,
+ ?config(host, Config),
+ ?config(node, Config)),
+ ok.
+%%-------------------------------------------------------------------------
+ip_block_disturbing_active(doc) ->
+ ["Check that you can block/unblock an active server. The strategy "
+ "distribing means ongoing requests should be terminated."];
+ip_block_disturbing_active(suite) ->
+ [];
+ip_block_disturbing_active(Config) when is_list(Config) ->
+ httpd_block:block_disturbing_active(ip_comm, ?IP_PORT,
+ ?config(host, Config),
+ ?config(node, Config)),
+ ok.
+%%-------------------------------------------------------------------------
+ip_block_non_disturbing_active(doc) ->
+ ["Check that you can block/unblock an idle server. The strategy "
+ "non distribing means the ongoing requests should be compleated."];
+ip_block_non_disturbing_active(suite) ->
+ [];
+ip_block_non_disturbing_active(Config) when is_list(Config) ->
+ httpd_block:block_non_disturbing_idle(ip_comm, ?IP_PORT,
+ ?config(host, Config),
+ ?config(node, Config)),
+ ok.
+
+%%-------------------------------------------------------------------------
+ip_block_disturbing_active_timeout_not_released(doc) ->
+ ["Check that you can block an active server. The strategy "
+ "distribing means ongoing requests should be compleated"
+ "if the timeout does not occur."];
+ip_block_disturbing_active_timeout_not_released(suite) ->
+ [];
+ip_block_disturbing_active_timeout_not_released(Config)
+ when is_list(Config) ->
+ httpd_block:block_disturbing_active_timeout_not_released(ip_comm,
+ ?IP_PORT,
+ ?config(host,
+ Config),
+ ?config(node,
+ Config)),
+ ok.
+%%-------------------------------------------------------------------------
+ip_block_disturbing_active_timeout_released(doc) ->
+ ["Check that you can block an active server. The strategy "
+ "distribing means ongoing requests should be terminated when"
+ "the timeout occurs."];
+ip_block_disturbing_active_timeout_released(suite) ->
+ [];
+ip_block_disturbing_active_timeout_released(Config)
+ when is_list(Config) ->
+ httpd_block:block_disturbing_active_timeout_released(ip_comm,
+ ?IP_PORT,
+ ?config(host,
+ Config),
+ ?config(node,
+ Config)),
+ ok.
+
+%%-------------------------------------------------------------------------
+ip_block_non_disturbing_active_timeout_not_released(doc) ->
+ ["Check that you can block an active server. The strategy "
+ "non non distribing means ongoing requests should be completed."];
+ip_block_non_disturbing_active_timeout_not_released(suite) ->
+ [];
+ip_block_non_disturbing_active_timeout_not_released(Config)
+ when is_list(Config) ->
+ httpd_block:
+ block_non_disturbing_active_timeout_not_released(ip_comm,
+ ?IP_PORT,
+ ?config(host,
+ Config),
+ ?config(node,
+ Config)),
+ ok.
+%%-------------------------------------------------------------------------
+ip_block_non_disturbing_active_timeout_released(doc) ->
+ ["Check that you can block an active server. The strategy "
+ "non non distribing means ongoing requests should be completed. "
+ "When the timeout occurs the block operation sohould be canceled." ];
+ip_block_non_disturbing_active_timeout_released(suite) ->
+ [];
+ip_block_non_disturbing_active_timeout_released(Config)
+ when is_list(Config) ->
+ httpd_block:
+ block_non_disturbing_active_timeout_released(ip_comm,
+ ?IP_PORT,
+ ?config(host,
+ Config),
+ ?config(node,
+ Config)),
+ ok.
+%%-------------------------------------------------------------------------
+ip_block_disturbing_blocker_dies(doc) ->
+ [];
+ip_block_disturbing_blocker_dies(suite) ->
+ [];
+ip_block_disturbing_blocker_dies(Config) when is_list(Config) ->
+ httpd_block:disturbing_blocker_dies(ip_comm, ?IP_PORT,
+ ?config(host, Config),
+ ?config(node, Config)),
+ ok.
+%%-------------------------------------------------------------------------
+ip_block_non_disturbing_blocker_dies(doc) ->
+ [];
+ip_block_non_disturbing_blocker_dies(suite) ->
+ [];
+ip_block_non_disturbing_blocker_dies(Config) when is_list(Config) ->
+ httpd_block:non_disturbing_blocker_dies(ip_comm, ?IP_PORT,
+ ?config(host, Config),
+ ?config(node, Config)),
+ ok.
+%%-------------------------------------------------------------------------
+ip_restart_no_block(doc) ->
+ [""];
+ip_restart_no_block(suite) ->
+ [];
+ip_restart_no_block(Config) when is_list(Config) ->
+ httpd_block:restart_no_block(ip_comm, ?IP_PORT, ?config(host, Config),
+ ?config(node, Config)),
+ ok.
+%%-------------------------------------------------------------------------
+ip_restart_disturbing_block(doc) ->
+ [""];
+ip_restart_disturbing_block(suite) ->
+ [];
+ip_restart_disturbing_block(Config) when is_list(Config) ->
+ %% <CONDITIONAL-SKIP>
+ Condition =
+ fun() ->
+ case os:type() of
+ {unix, linux} ->
+ HW = string:strip(os:cmd("uname -m"), right, $\n),
+ case HW of
+ "ppc" ->
+ case inet:gethostname() of
+ {ok, "peach"} ->
+ true;
+ _ ->
+ false
+ end;
+ _ ->
+ false
+ end;
+ _ ->
+ false
+ end
+ end,
+ ?NON_PC_TC_MAYBE_SKIP(Config, Condition),
+ %% </CONDITIONAL-SKIP>
+
+ httpd_block:restart_disturbing_block(ip_comm, ?IP_PORT,
+ ?config(host, Config),
+ ?config(node, Config)),
+ ok.
+
+%%-------------------------------------------------------------------------
+ip_restart_non_disturbing_block(doc) ->
+ [""];
+ip_restart_non_disturbing_block(suite) ->
+ [];
+ip_restart_non_disturbing_block(Config) when is_list(Config) ->
+ %% <CONDITIONAL-SKIP>
+ Condition =
+ fun() ->
+ case os:type() of
+ {unix, linux} ->
+ HW = string:strip(os:cmd("uname -m"), right, $\n),
+ case HW of
+ "ppc" ->
+ case inet:gethostname() of
+ {ok, "peach"} ->
+ true;
+ _ ->
+ false
+ end;
+ _ ->
+ false
+ end;
+ _ ->
+ false
+ end
+ end,
+ ?NON_PC_TC_MAYBE_SKIP(Config, Condition),
+ %% </CONDITIONAL-SKIP>
+
+ httpd_block:restart_non_disturbing_block(ip_comm, ?IP_PORT,
+ ?config(host, Config),
+ ?config(node, Config)),
+ ok.
+
+%%-------------------------------------------------------------------------
+ssl_mod_alias(doc) ->
+ ["Module test: mod_alias"];
+ssl_mod_alias(suite) ->
+ [];
+ssl_mod_alias(Config) when is_list(Config) ->
+ httpd_mod:alias(ssl, ?SSL_PORT,
+ ?config(host, Config), ?config(node, Config)),
+ ok.
+%%-------------------------------------------------------------------------
+ssl_mod_actions(doc) ->
+ ["Module test: mod_actions"];
+ssl_mod_actions(suite) ->
+ [];
+ssl_mod_actions(Config) when is_list(Config) ->
+ httpd_mod:actions(ssl, ?SSL_PORT,
+ ?config(host, Config), ?config(node, Config)),
+ ok.
+%%-------------------------------------------------------------------------
+ssl_mod_security(doc) ->
+ ["Module test: mod_security"];
+ssl_mod_security(suite) ->
+ [];
+ssl_mod_security(Config) when is_list(Config) ->
+ ServerRoot = ?config(server_root, Config),
+ httpd_mod:security(ServerRoot, ssl, ?SSL_PORT,
+ ?config(host, Config), ?config(node, Config)),
+ ok.
+%%-------------------------------------------------------------------------
+ssl_mod_auth(doc) ->
+ ["Module test: mod_auth"];
+ssl_mod_auth(suite) ->
+ [];
+ssl_mod_auth(Config) when is_list(Config) ->
+ httpd_mod:auth(ssl, ?SSL_PORT,
+ ?config(host, Config), ?config(node, Config)),
+ ok.
+%%-------------------------------------------------------------------------
+ssl_mod_auth_api(doc) ->
+ ["Module test: mod_auth"];
+ssl_mod_auth_api(suite) ->
+ [];
+ssl_mod_auth_api(Config) when is_list(Config) ->
+ ServerRoot = ?config(server_root, Config),
+ Host = ?config(host, Config),
+ Node = ?config(node, Config),
+ httpd_mod:auth_api(ServerRoot, "", ssl, ?SSL_PORT, Host, Node),
+ httpd_mod:auth_api(ServerRoot, "dets_", ssl, ?SSL_PORT, Host, Node),
+ httpd_mod:auth_api(ServerRoot, "mnesia_", ssl, ?SSL_PORT, Host, Node),
+ ok.
+
+%%-------------------------------------------------------------------------
+ssl_mod_auth_mnesia_api(doc) ->
+ ["Module test: mod_auth_mnesia_api"];
+ssl_mod_auth_mnesia_api(suite) ->
+ [];
+ssl_mod_auth_mnesia_api(Config) when is_list(Config) ->
+ httpd_mod:auth_mnesia_api(ssl, ?SSL_PORT,
+ ?config(host, Config), ?config(node, Config)),
+ ok.
+%%-------------------------------------------------------------------------
+ssl_mod_htaccess(doc) ->
+ ["Module test: mod_htaccess"];
+ssl_mod_htaccess(suite) ->
+ [];
+ssl_mod_htaccess(Config) when is_list(Config) ->
+ httpd_mod:htaccess(ssl, ?SSL_PORT,
+ ?config(host, Config), ?config(node, Config)),
+ ok.
+%%-------------------------------------------------------------------------
+ssl_mod_cgi(doc) ->
+ ["Module test: mod_cgi"];
+ssl_mod_cgi(suite) ->
+ [];
+ssl_mod_cgi(Config) when is_list(Config) ->
+ case test_server:os_type() of
+ vxworks ->
+ {skip, cgi_not_supported_on_vxwoks};
+ _ ->
+ httpd_mod:cgi(ssl, ?SSL_PORT,
+ ?config(host, Config), ?config(node, Config)),
+ ok
+ end.
+%%-------------------------------------------------------------------------
+ssl_mod_esi(doc) ->
+ ["Module test: mod_esi"];
+ssl_mod_esi(suite) ->
+ [];
+ssl_mod_esi(Config) when is_list(Config) ->
+ httpd_mod:esi(ssl, ?SSL_PORT,
+ ?config(host, Config), ?config(node, Config)),
+ ok.
+
+%%-------------------------------------------------------------------------
+ssl_mod_get(doc) ->
+ ["Module test: mod_get"];
+ssl_mod_get(suite) ->
+ [];
+ssl_mod_get(Config) when is_list(Config) ->
+ httpd_mod:get(ssl, ?SSL_PORT,
+ ?config(host, Config), ?config(node, Config)),
+ ok.
+%%-------------------------------------------------------------------------
+ssl_mod_head(doc) ->
+ ["Module test: mod_head"];
+ssl_mod_head(suite) ->
+ [];
+ssl_mod_head(Config) when is_list(Config) ->
+ httpd_mod:head(ssl, ?SSL_PORT,
+ ?config(host, Config), ?config(node, Config)),
+ ok.
+%%-------------------------------------------------------------------------
+ssl_mod_all(doc) ->
+ ["All modules test"];
+ssl_mod_all(suite) ->
+ [];
+ssl_mod_all(Config) when is_list(Config) ->
+ httpd_mod:all(ssl, ?SSL_PORT,
+ ?config(host, Config), ?config(node, Config)),
+ ok.
+
+%%-------------------------------------------------------------------------
+ssl_load_light(doc) ->
+ ["Test light load"];
+ssl_load_light(suite) ->
+ [];
+ssl_load_light(Config) when is_list(Config) ->
+ httpd_load:load_test(ssl, ?SSL_PORT, ?config(host, Config),
+ ?config(node, Config),
+ get_nof_clients(ssl, light)),
+ ok.
+
+%%-------------------------------------------------------------------------
+ssl_load_medium(doc) ->
+ ["Test medium load"];
+ssl_load_medium(suite) ->
+ [];
+ssl_load_medium(Config) when is_list(Config) ->
+ %% <CONDITIONAL-SKIP>
+ Skippable = [win32],
+ Condition = fun() -> ?OS_BASED_SKIP(Skippable) end,
+ ?NON_PC_TC_MAYBE_SKIP(Config, Condition),
+ %% </CONDITIONAL-SKIP>
+
+ httpd_load:load_test(ssl, ?SSL_PORT, ?config(host, Config),
+ ?config(node, Config),
+ get_nof_clients(ssl, medium)),
+ ok.
+
+%%-------------------------------------------------------------------------
+ssl_load_heavy(doc) ->
+ ["Test heavy load"];
+ssl_load_heavy(suite) ->
+ [];
+ssl_load_heavy(Config) when is_list(Config) ->
+ %% <CONDITIONAL-SKIP>
+ Skippable = [win32],
+ Condition = fun() -> ?OS_BASED_SKIP(Skippable) end,
+ ?NON_PC_TC_MAYBE_SKIP(Config, Condition),
+ %% </CONDITIONAL-SKIP>
+
+ httpd_load:load_test(ssl, ?SSL_PORT, ?config(host, Config),
+ ?config(node, Config),
+ get_nof_clients(ssl, heavy)),
+ ok.
+
+%%-------------------------------------------------------------------------
+ssl_dos_hostname(doc) ->
+ ["Denial Of Service (DOS) attack test case"];
+ssl_dos_hostname(suite) ->
+ [];
+ssl_dos_hostname(Config) when is_list(Config) ->
+ dos_hostname(ssl, ?SSL_PORT, ?config(host, Config),
+ ?config(node, Config), ?MAX_HEADER_SIZE),
+ ok.
+%%-------------------------------------------------------------------------
+ssl_time_test(doc) ->
+ [""];
+ssl_time_test(suite) ->
+ [];
+ssl_time_test(Config) when is_list(Config) ->
+ %% <CONDITIONAL-SKIP>
+ Condition = fun() -> true end,
+ ?NON_PC_TC_MAYBE_SKIP(Config, Condition),
+ %% </CONDITIONAL-SKIP>
+
+ httpd_time_test:t(ssl, ?config(host, Config), ?SSL_PORT),
+ ok.
+
+%%-------------------------------------------------------------------------
+ssl_block_503(doc) ->
+ ["Check that you will receive status code 503 when the server"
+ " is blocked and 200 when its not blocked."];
+ssl_block_503(suite) ->
+ [];
+ssl_block_503(Config) when is_list(Config) ->
+ httpd_block:block_503(ssl, ?SSL_PORT, ?config(host, Config),
+ ?config(node, Config)),
+ ok.
+%%-------------------------------------------------------------------------
+ssl_block_disturbing_idle(doc) ->
+ ["Check that you can block/unblock an idle server. The strategy "
+ "distribing does not really make a difference in this case."];
+ssl_block_disturbing_idle(suite) ->
+ [];
+ssl_block_disturbing_idle(Config) when is_list(Config) ->
+ httpd_block:block_disturbing_idle(ssl, ?SSL_PORT,
+ ?config(host, Config),
+ ?config(node, Config)),
+ ok.
+%%-------------------------------------------------------------------------
+ssl_block_non_disturbing_idle(doc) ->
+ ["Check that you can block/unblock an idle server. The strategy "
+ "non distribing does not really make a difference in this case."];
+ssl_block_non_disturbing_idle(suite) ->
+ [];
+ssl_block_non_disturbing_idle(Config) when is_list(Config) ->
+ httpd_block:block_non_disturbing_idle(ssl, ?SSL_PORT,
+ ?config(host, Config),
+ ?config(node, Config)),
+ ok.
+%%-------------------------------------------------------------------------
+ssl_block_disturbing_active(doc) ->
+ ["Check that you can block/unblock an active server. The strategy "
+ "distribing means ongoing requests should be terminated."];
+ssl_block_disturbing_active(suite) ->
+ [];
+ssl_block_disturbing_active(Config) when is_list(Config) ->
+ httpd_block:block_disturbing_active(ssl, ?SSL_PORT,
+ ?config(host, Config),
+ ?config(node, Config)),
+ ok.
+%%-------------------------------------------------------------------------
+ssl_block_non_disturbing_active(doc) ->
+ ["Check that you can block/unblock an idle server. The strategy "
+ "non distribing means the ongoing requests should be compleated."];
+ssl_block_non_disturbing_active(suite) ->
+ [];
+ssl_block_non_disturbing_active(Config) when is_list(Config) ->
+ httpd_block:block_non_disturbing_idle(ssl, ?SSL_PORT,
+ ?config(host, Config),
+ ?config(node, Config)),
+ ok.
+
+%%-------------------------------------------------------------------------
+ssl_block_disturbing_active_timeout_not_released(doc) ->
+ ["Check that you can block an active server. The strategy "
+ "distribing means ongoing requests should be compleated"
+ "if the timeout does not occur."];
+ssl_block_disturbing_active_timeout_not_released(suite) ->
+ [];
+ssl_block_disturbing_active_timeout_not_released(Config)
+ when is_list(Config) ->
+ httpd_block:
+ block_disturbing_active_timeout_not_released(ssl,
+ ?SSL_PORT,
+ ?config(host,
+ Config),
+ ?config(node,
+ Config)),
+ ok.
+%%-------------------------------------------------------------------------
+ssl_block_disturbing_active_timeout_released(doc) ->
+ ["Check that you can block an active server. The strategy "
+ "distribing means ongoing requests should be terminated when"
+ "the timeout occurs."];
+ssl_block_disturbing_active_timeout_released(suite) ->
+ [];
+ssl_block_disturbing_active_timeout_released(Config)
+ when is_list(Config) ->
+ httpd_block:block_disturbing_active_timeout_released(ssl,
+ ?SSL_PORT,
+ ?config(host,
+ Config),
+ ?config(node,
+ Config)),
+ ok.
+
+%%-------------------------------------------------------------------------
+ssl_block_non_disturbing_active_timeout_not_released(doc) ->
+ ["Check that you can block an active server. The strategy "
+ "non non distribing means ongoing requests should be completed."];
+ssl_block_non_disturbing_active_timeout_not_released(suite) ->
+ [];
+ssl_block_non_disturbing_active_timeout_not_released(Config)
+ when is_list(Config) ->
+ httpd_block:
+ block_non_disturbing_active_timeout_not_released(ssl,
+ ?SSL_PORT,
+ ?config(host,
+ Config),
+ ?config(node,
+ Config)),
+ ok.
+%%-------------------------------------------------------------------------
+ssl_block_non_disturbing_active_timeout_released(doc) ->
+ ["Check that you can block an active server. The strategy "
+ "non non distribing means ongoing requests should be completed. "
+ "When the timeout occurs the block operation sohould be canceled." ];
+ssl_block_non_disturbing_active_timeout_released(suite) ->
+ [];
+ssl_block_non_disturbing_active_timeout_released(Config)
+ when is_list(Config) ->
+ httpd_block:
+ block_non_disturbing_active_timeout_released(ssl,
+ ?SSL_PORT,
+ ?config(host,
+ Config),
+ ?config(node,
+ Config)),
+ ok.
+
+%%-------------------------------------------------------------------------
+ssl_block_disturbing_blocker_dies(doc) ->
+ [];
+ssl_block_disturbing_blocker_dies(suite) ->
+ [];
+ssl_block_disturbing_blocker_dies(Config) when is_list(Config) ->
+ httpd_block:disturbing_blocker_dies(ssl, ?SSL_PORT,
+ ?config(host, Config),
+ ?config(node, Config)),
+ ok.
+%%-------------------------------------------------------------------------
+ssl_block_non_disturbing_blocker_dies(doc) ->
+ [];
+ssl_block_non_disturbing_blocker_dies(suite) ->
+ [];
+ssl_block_non_disturbing_blocker_dies(Config) when is_list(Config) ->
+ httpd_block:non_disturbing_blocker_dies(ssl, ?SSL_PORT,
+ ?config(host, Config),
+ ?config(node, Config)),
+ ok.
+%%-------------------------------------------------------------------------
+ssl_restart_no_block(doc) ->
+ [""];
+ssl_restart_no_block(suite) ->
+ [];
+ssl_restart_no_block(Config) when is_list(Config) ->
+ httpd_block:restart_no_block(ssl, ?SSL_PORT, ?config(host, Config),
+ ?config(node, Config)),
+ ok.
+%%-------------------------------------------------------------------------
+ssl_restart_disturbing_block(doc) ->
+ [""];
+ssl_restart_disturbing_block(suite) ->
+ [];
+ssl_restart_disturbing_block(Config) when is_list(Config) ->
+ %% <CONDITIONAL-SKIP>
+ Condition =
+ fun() ->
+ case os:type() of
+ {unix, linux} ->
+ HW = string:strip(os:cmd("uname -m"), right, $\n),
+ case HW of
+ "ppc" ->
+ case inet:gethostname() of
+ {ok, "peach"} ->
+ true;
+ _ ->
+ false
+ end;
+ _ ->
+ false
+ end;
+ _ ->
+ false
+ end
+ end,
+ ?NON_PC_TC_MAYBE_SKIP(Config, Condition),
+ %% </CONDITIONAL-SKIP>
+
+ httpd_block:restart_disturbing_block(ssl, ?SSL_PORT,
+ ?config(host, Config),
+ ?config(node, Config)),
+ ok.
+
+%%-------------------------------------------------------------------------
+ssl_restart_non_disturbing_block(doc) ->
+ [""];
+ssl_restart_non_disturbing_block(suite) ->
+ [];
+ssl_restart_non_disturbing_block(Config) when is_list(Config) ->
+ %% <CONDITIONAL-SKIP>
+ Condition =
+ fun() ->
+ case os:type() of
+ {unix, linux} ->
+ HW = string:strip(os:cmd("uname -m"), right, $\n),
+ case HW of
+ "ppc" ->
+ case inet:gethostname() of
+ {ok, "peach"} ->
+ true;
+ _ ->
+ false
+ end;
+ _ ->
+ false
+ end;
+ _ ->
+ false
+ end
+ end,
+ ?NON_PC_TC_MAYBE_SKIP(Config, Condition),
+ %% </CONDITIONAL-SKIP>
+
+ httpd_block:restart_non_disturbing_block(ssl, ?SSL_PORT,
+ ?config(host, Config),
+ ?config(node, Config)),
+ ok.
+
+%%-------------------------------------------------------------------------
+ip_host(doc) ->
+ ["Control that the server accepts/rejects requests with/ without host"];
+ip_host(suite)->
+ [];
+ip_host(Config) when is_list(Config) ->
+ httpd_1_1:host(ip_comm, ?IP_PORT, ?config(host, Config),
+ ?config(node, Config)),
+ ok.
+%%-------------------------------------------------------------------------
+ip_chunked(doc) ->
+ ["Control that the server accepts chunked requests"];
+ip_chunked(suite) ->
+ [];
+ip_chunked(Config) when is_list(Config) ->
+ httpd_1_1:chunked(ip_comm, ?IP_PORT, ?config(host, Config),
+ ?config(node, Config)),
+ ok.
+%%-------------------------------------------------------------------------
+ip_expect(doc) ->
+ ["Control that the server handles request with the expect header "
+ "field appropiate"];
+ip_expect(suite)->
+ [];
+ip_expect(Config) when is_list(Config) ->
+ httpd_1_1:expect(ip_comm, ?IP_PORT, ?config(host, Config),
+ ?config(node, Config)),
+ ok.
+%%-------------------------------------------------------------------------
+ip_range(doc) ->
+ ["Control that the server can handle range requests to plain files"];
+ip_range(suite)->
+ [];
+ip_range(Config) when is_list(Config) ->
+ httpd_1_1:range(ip_comm, ?IP_PORT, ?config(host, Config),
+ ?config(node, Config)),
+ ok.
+%%-------------------------------------------------------------------------
+ip_if_test(doc) ->
+ ["Test that the if - request header fields is handled correclty"];
+ip_if_test(suite) ->
+ [];
+ip_if_test(Config) when is_list(Config) ->
+ ServerRoot = ?config(server_root, Config),
+ DocRoot = filename:join([ServerRoot, "htdocs"]),
+ httpd_1_1:if_test(ip_comm, ?IP_PORT, ?config(host, Config),
+ ?config(node, Config), DocRoot),
+ ok.
+%%-------------------------------------------------------------------------
+ip_http_trace(doc) ->
+ ["Test the trace module "];
+ip_http_trace(suite) ->
+ [];
+ip_http_trace(Config) when is_list(Config) ->
+ httpd_1_1:http_trace(ip_comm, ?IP_PORT, ?config(host, Config),
+ ?config(node, Config)),
+ ok.
+%%-------------------------------------------------------------------------
+ip_http1_1_head(doc) ->
+ ["Test the trace module "];
+ip_http1_1_head(suite)->
+ [];
+ip_http1_1_head(Config) when is_list(Config) ->
+ httpd_1_1:head(ip_comm, ?IP_PORT, ?config(host, Config),
+ ?config(node, Config)),
+ ok.
+
+%%-------------------------------------------------------------------------
+ip_get_0_9(doc) ->
+ ["Test simple HTTP/0.9 GET"];
+ip_get_0_9(suite)->
+ [];
+ip_get_0_9(Config) when is_list(Config) ->
+ Host = ?config(host, Config),
+ Node = ?config(node, Config),
+ ok = httpd_test_lib:verify_request(ip_comm, Host, ?IP_PORT, Node,
+ "GET / \r\n\r\n",
+ [{statuscode, 200},
+ {version, "HTTP/0.9"} ]),
+ %% Without space after uri
+ ok = httpd_test_lib:verify_request(ip_comm, Host, ?IP_PORT, Node,
+ "GET /\r\n\r\n",
+ [{statuscode, 200},
+ {version, "HTTP/0.9"} ]),
+ ok = httpd_test_lib:verify_request(ip_comm, Host, ?IP_PORT, Node,
+ "GET / HTTP/0.9\r\n\r\n",
+ [{statuscode, 200},
+ {version, "HTTP/0.9"}]),
+
+ ok.
+%%-------------------------------------------------------------------------
+ip_head_1_0(doc) ->
+ ["Test HTTP/1.0 HEAD"];
+ip_head_1_0(suite)->
+ [];
+ip_head_1_0(Config) when is_list(Config) ->
+ Host = ?config(host, Config),
+ Node = ?config(node, Config),
+ ok = httpd_test_lib:verify_request(ip_comm, Host, ?IP_PORT, Node,
+ "HEAD / HTTP/1.0\r\n\r\n", [{statuscode, 200},
+ {version, "HTTP/1.0"}]),
+
+ ok.
+%%-------------------------------------------------------------------------
+ip_get_1_0(doc) ->
+ ["Test HTTP/1.0 GET"];
+ip_get_1_0(suite)->
+ [];
+ip_get_1_0(Config) when is_list(Config) ->
+ Host = ?config(host, Config),
+ Node = ?config(node, Config),
+ ok = httpd_test_lib:verify_request(ip_comm, Host, ?IP_PORT, Node,
+ "GET / HTTP/1.0\r\n\r\n", [{statuscode, 200},
+ {version, "HTTP/1.0"}]),
+
+ ok.
+%%-------------------------------------------------------------------------
+ip_post_1_0(doc) ->
+ ["Test HTTP/1.0 POST"];
+ip_post_1_0(suite)->
+ [];
+ip_post_1_0(Config) when is_list(Config) ->
+ Host = ?config(host, Config),
+ Node = ?config(node, Config),
+ %% Test the post message formatin 1.0! Real post are testes elsewhere
+ ok = httpd_test_lib:verify_request(ip_comm, Host, ?IP_PORT, Node,
+ "POST / HTTP/1.0\r\n\r\n "
+ "Content-Length:6 \r\n\r\nfoobar",
+ [{statuscode, 500}, {version, "HTTP/1.0"}]),
+
+ ok.
+%%-------------------------------------------------------------------------
+ip_mod_cgi_chunked_encoding_test(doc) ->
+ ["Test the trace module "];
+ip_mod_cgi_chunked_encoding_test(suite)->
+ [];
+ip_mod_cgi_chunked_encoding_test(Config) when is_list(Config) ->
+ Host = ?config(host, Config),
+ Script =
+ case test_server:os_type() of
+ {win32, _} ->
+ "/cgi-bin/printenv.bat";
+ _ ->
+ "/cgi-bin/printenv.sh"
+ end,
+ Requests =
+ ["GET " ++ Script ++ " HTTP/1.1\r\nHost:"++ Host ++"\r\n\r\n",
+ "GET /cgi-bin/erl/httpd_example/newformat HTTP/1.1\r\nHost:"
+ ++ Host ++"\r\n\r\n"],
+ httpd_1_1:mod_cgi_chunked_encoding_test(ip_comm, ?IP_PORT,
+ Host,
+ ?config(node, Config),
+ Requests),
+ ok.
+
+%-------------------------------------------------------------------------
+ipv6_hostname(doc) ->
+ ["Test standard ipv6 address"];
+ipv6_hostname(suite)->
+ [];
+ipv6_hostname(Config) when is_list(Config) ->
+ Host = ?config(host, Config),
+ httpd_test_lib:verify_request(ip_comm, Host, ?IP_PORT, node(),
+ "GET / HTTP/1.1\r\n\r\n",
+ [{statuscode, 200},
+ {version, "HTTP/1.1"}]),
+ ok.
+
+%%-------------------------------------------------------------------------
+ipv6_address(doc) ->
+ ["Test standard ipv6 address"];
+ipv6_address(suite)->
+ [];
+ipv6_address(Config) when is_list(Config) ->
+ httpd_test_lib:verify_request(ip_comm, ?IPV6_LOCAL_HOST, ?IP_PORT,
+ node(), "GET / HTTP/1.1\r\n\r\n",
+ [{statuscode, 200},
+ {version, "HTTP/1.1"}]),
+ ok.
+
+%%--------------------------------------------------------------------
+ticket_5775(doc) ->
+ ["Tests that content-length is correct"];
+ticket_5775(suite) ->
+ [];
+ticket_5775(Config) ->
+ ok=httpd_test_lib:verify_request(ip_comm, ?config(host, Config),
+ ?IP_PORT, ?config(node, Config),
+ "GET /cgi-bin/erl/httpd_example:get_bin "
+ "HTTP/1.0\r\n\r\n",
+ [{statuscode, 200},
+ {version, "HTTP/1.0"}]),
+ ok.
+ticket_5865(doc) ->
+ ["Tests that a header without last-modified is handled"];
+ticket_5865(suite) ->
+ [];
+ticket_5865(Config) ->
+ Host = ?config(host,Config),
+ ServerRoot = ?config(server_root, Config),
+ DocRoot = filename:join([ServerRoot, "htdocs"]),
+ File = filename:join([DocRoot,"last_modified.html"]),
+
+ Bad_mtime = case test_server:os_type() of
+ {win32, _} ->
+ {{1600,12,31},{23,59,59}};
+ {unix, _} ->
+ {{1969,12,31},{23,59,59}}
+ end,
+
+ {ok,FI}=file:read_file_info(File),
+
+ case file:write_file_info(File,FI#file_info{mtime=Bad_mtime}) of
+ ok ->
+ ok = httpd_test_lib:verify_request(ip_comm, Host,
+ ?IP_PORT, ?config(node, Config),
+ "GET /last_modified.html"
+ " HTTP/1.1\r\nHost:"
+ ++Host++"\r\n\r\n",
+ [{statuscode, 200},
+ {no_last_modified,
+ "last-modified"}]),
+ ok;
+ {error, Reason} ->
+ Fault =
+ io_lib:format("Attempt to change the file info to set the"
+ " preconditions of the test case failed ~p~n",
+ [Reason]),
+ {skip, Fault}
+ end.
+
+ticket_5913(doc) ->
+ ["Tests that a header without last-modified is handled"];
+ticket_5913(suite) -> [];
+ticket_5913(Config) ->
+ ok = httpd_test_lib:verify_request(ip_comm, ?config(host, Config),
+ ?IP_PORT, ?config(node, Config),
+ "GET /cgi-bin/erl/httpd_example:get_bin "
+ "HTTP/1.0\r\n\r\n",
+ [{statuscode, 200},
+ {version, "HTTP/1.0"}]),
+ ok.
+
+ticket_6003(doc) ->
+ ["Tests that a URI with a bad hexadecimal code is handled"];
+ticket_6003(suite) -> [];
+ticket_6003(Config) ->
+ ok = httpd_test_lib:verify_request(ip_comm, ?config(host, Config),
+ ?IP_PORT, ?config(node, Config),
+ "GET http://www.erlang.org/%skalle "
+ "HTTP/1.0\r\n\r\n",
+ [{statuscode, 400},
+ {version, "HTTP/1.0"}]),
+ ok.
+
+ticket_7304(doc) ->
+ ["Tests missing CR in delimiter"];
+ticket_7304(suite) ->
+ [];
+ticket_7304(Config) ->
+ ok = httpd_test_lib:verify_request(ip_comm, ?config(host, Config),
+ ?IP_PORT, ?config(node, Config),
+ "GET / HTTP/1.0\r\n\n",
+ [{statuscode, 200},
+ {version, "HTTP/1.0"}]),
+ ok.
+
+%%--------------------------------------------------------------------
+%% Internal functions
+%%--------------------------------------------------------------------
+dos_hostname(Type, Port, Host, Node, Max) ->
+ H1 = {"", 200},
+ H2 = {"dummy-host.ericsson.se", 200},
+ TooLongHeader = lists:append(lists:duplicate(Max + 1, "a")),
+ H3 = {TooLongHeader, 403},
+ Hosts = [H1,H2,H3],
+ dos_hostname_poll(Type, Host, Port, Node, Hosts).
+
+%% make_ipv6(T) when is_tuple(T) andalso (size(T) =:= 8) ->
+%% make_ipv6(tuple_to_list(T));
+
+%% make_ipv6([_, _, _, _, _, _, _, _] = IPV6) ->
+%% lists:flatten(io_lib:format("~s:~s:~s:~s:~s:~s:~s:~s", IPV6)).
+
+
+%%--------------------------------------------------------------------
+%% Other help functions
+create_config(Config, Access, FileName) ->
+ ServerRoot = ?config(server_root, Config),
+ TcTopDir = ?config(tc_top_dir, Config),
+ Port = ?config(port, Config),
+ Type = ?config(sock_type, Config),
+ Host = ?config(host, Config),
+ Mods = io_lib:format("~p", [httpd_mod]),
+ Funcs = io_lib:format("~p", [ssl_password_cb]),
+ MaxHdrSz = io_lib:format("~p", [256]),
+ MaxHdrAct = io_lib:format("~p", [close]),
+ SSL =
+ case Type of
+ ssl ->
+ [cline(["SSLCertificateFile ",
+ filename:join(ServerRoot, "ssl/ssl_server.pem")]),
+ cline(["SSLCertificateKeyFile ",
+ filename:join(ServerRoot, "ssl/ssl_server.pem")]),
+ cline(["SSLCACertificateFile ",
+ filename:join(ServerRoot, "ssl/ssl_server.pem")]),
+ cline(["SSLPasswordCallbackModule ", Mods]),
+ cline(["SSLPasswordCallbackFunction ", Funcs]),
+ cline(["SSLVerifyClient 0"]),
+ cline(["SSLVerifyDepth 1"])];
+ _ ->
+ []
+ end,
+ Mod_order = case Access of
+ mod_htaccess ->
+ "Modules mod_alias mod_htaccess mod_auth "
+ "mod_security "
+ "mod_responsecontrol mod_trace mod_esi "
+ "mod_actions mod_cgi mod_include mod_dir "
+ "mod_range mod_get "
+ "mod_head mod_log mod_disk_log";
+ _ ->
+ "Modules mod_alias mod_auth mod_security "
+ "mod_responsecontrol mod_trace mod_esi "
+ "mod_actions mod_cgi mod_include mod_dir "
+ "mod_range mod_get "
+ "mod_head mod_log mod_disk_log"
+ end,
+
+%% The test suite currently does not handle an explicit BindAddress.
+%% They assume any has been used, that is Addr is always set to undefined!
+
+%% {ok, Hostname} = inet:gethostname(),
+%% {ok, Addr} = inet:getaddr(Hostname, inet6),
+%% AddrStr = make_ipv6(Addr),
+%% BindAddress = lists:flatten(io_lib:format("~s|inet6", [AddrStr])),
+
+ %% BindAddress = "*|inet",
+ BindAddress = "*",
+
+ HttpConfig = [
+ cline(["Port ", integer_to_list(Port)]),
+ cline(["ServerName ", Host]),
+ cline(["SocketType ", atom_to_list(Type)]),
+ cline([Mod_order]),
+ %% cline(["LogFormat ", "erlang"]),
+ cline(["ServerAdmin [email protected]"]),
+ cline(["BindAddress ", BindAddress]),
+ cline(["ServerRoot ", ServerRoot]),
+ cline(["ErrorLog ", TcTopDir,
+ "/logs/error_log_", integer_to_list(Port)]),
+ cline(["TransferLog ", TcTopDir,
+ "/logs/access_log_", integer_to_list(Port)]),
+ cline(["SecurityLog ", TcTopDir,
+ "/logs/security_log_", integer_to_list(Port)]),
+ cline(["ErrorDiskLog ", TcTopDir,
+ "/logs/error_disk_log_", integer_to_list(Port)]),
+ cline(["ErrorDiskLogSize ", "190000 ", "11"]),
+ cline(["TransferDiskLog ", TcTopDir,
+ "/logs/access_disk_log_", integer_to_list(Port)]),
+ cline(["TransferDiskLogSize ", "200000 ", "10"]),
+ cline(["SecurityDiskLog ", TcTopDir,
+ "/logs/security_disk_log_", integer_to_list(Port)]),
+ cline(["SecurityDiskLogSize ", "210000 ", "9"]),
+ cline(["MaxClients 10"]),
+ cline(["MaxHeaderSize ", MaxHdrSz]),
+ cline(["MaxHeaderAction ", MaxHdrAct]),
+ cline(["DocumentRoot ",
+ filename:join(ServerRoot, "htdocs")]),
+ cline(["DirectoryIndex ", "index.html ", "welcome.html"]),
+ cline(["DefaultType ", "text/plain"]),
+ SSL,
+ mod_alias_config(ServerRoot),
+
+ config_directory(filename:join([ServerRoot,"htdocs",
+ "open"]),
+ "Open Area",
+ filename:join(ServerRoot, "auth/passwd"),
+ filename:join(ServerRoot, "auth/group"),
+ plain,
+ "user one Aladdin",
+ filename:join(ServerRoot, "security_data")),
+ config_directory(filename:join([ServerRoot,"htdocs",
+ "secret"]),
+ "Secret Area",
+ filename:join(ServerRoot, "auth/passwd"),
+ filename:join(ServerRoot, "auth/group"),
+ plain,
+ "group group1 group2",
+ filename:join(ServerRoot, "security_data")),
+ config_directory(filename:join([ServerRoot,"htdocs",
+ "secret",
+ "top_secret"]),
+ "Top Secret Area",
+ filename:join(ServerRoot, "auth/passwd"),
+ filename:join(ServerRoot, "auth/group"),
+ plain,
+ "group group3",
+ filename:join(ServerRoot, "security_data")),
+
+ config_directory(filename:join([ServerRoot,"htdocs",
+ "dets_open"]),
+ "Dets Open Area",
+ filename:join(ServerRoot, "passwd"),
+ filename:join(ServerRoot, "group"),
+ dets,
+ "user one Aladdin",
+ filename:join(ServerRoot, "security_data")),
+ config_directory(filename:join([ServerRoot,"htdocs",
+ "dets_secret"]),
+ "Dets Secret Area",
+ filename:join(ServerRoot, "passwd"),
+ filename:join(ServerRoot, "group"),
+ dets,
+ "group group1 group2",
+ filename:join(ServerRoot, "security_data")),
+ config_directory(filename:join([ServerRoot,"htdocs",
+ "dets_secret",
+ "top_secret"]),
+ "Dets Top Secret Area",
+ filename:join(ServerRoot, "passwd"),
+ filename:join(ServerRoot, "group"),
+ dets,
+ "group group3",
+ filename:join(ServerRoot, "security_data")),
+
+ config_directory(filename:join([ServerRoot,"htdocs",
+ "mnesia_open"]),
+ "Mnesia Open Area",
+ false,
+ false,
+ mnesia,
+ "user one Aladdin",
+ filename:join(ServerRoot, "security_data")),
+ config_directory(filename:join([ServerRoot,"htdocs",
+ "mnesia_secret"]),
+ "Mnesia Secret Area",
+ false,
+ false,
+ mnesia,
+ "group group1 group2",
+ filename:join(ServerRoot, "security_data")),
+ config_directory(filename:join(
+ [ServerRoot, "htdocs", "mnesia_secret",
+ "top_secret"]),
+ "Mnesia Top Secret Area",
+ false,
+ false,
+ mnesia,
+ "group group3",
+ filename:join(ServerRoot, "security_data"))
+ ],
+ ConfigFile = filename:join([TcTopDir, FileName]),
+ {ok, Fd} = file:open(ConfigFile, [write]),
+ ok = file:write(Fd, lists:flatten(HttpConfig)),
+ ok = file:close(Fd).
+
+config_directory(Dir, AuthName, AuthUserFile, AuthGroupFile, AuthDBType,
+ Require, SF) ->
+ file:delete(SF),
+ [
+ cline(["<Directory ", Dir, ">"]),
+ cline(["SecurityDataFile ", SF]),
+ cline(["SecurityMaxRetries 3"]),
+ cline(["SecurityFailExpireTime ", integer_to_list(?FAIL_EXPIRE_TIME)]),
+ cline(["SecurityBlockTime 1"]),
+ cline(["SecurityAuthTimeout ", integer_to_list(?AUTH_TIMEOUT)]),
+ cline(["SecurityCallbackModule ", "httpd_mod"]),
+ cline_if_set("AuthUserFile", AuthUserFile),
+ cline_if_set("AuthGroupFile", AuthGroupFile),
+ cline_if_set("AuthName", AuthName),
+ cline_if_set("AuthDBType", AuthDBType),
+ cline(["require ", Require]),
+ cline(["</Directory>\r\n"])
+ ].
+
+mod_alias_config(Root) ->
+ [
+ cline(["Alias /icons/ ", filename:join(Root,"icons"), "/"]),
+ cline(["Alias /pics/ ", filename:join(Root, "icons"), "/"]),
+ cline(["ScriptAlias /cgi-bin/ ", filename:join(Root, "cgi-bin"), "/"]),
+ cline(["ScriptAlias /htbin/ ", filename:join(Root, "cgi-bin"), "/"]),
+ cline(["ErlScriptAlias /cgi-bin/erl httpd_example io"]),
+ cline(["EvalScriptAlias /eval httpd_example io"])
+ ].
+
+cline(List) ->
+ lists:flatten([List, "\r\n"]).
+
+cline_if_set(_, false) ->
+ [];
+cline_if_set(Name, Var) when is_list(Var) ->
+ cline([Name, " ", Var]);
+cline_if_set(Name, Var) when is_atom(Var) ->
+ cline([Name, " ", atom_to_list(Var)]).
+
+getaddr() ->
+ {ok,HostName} = inet:gethostname(),
+ {ok,{A1,A2,A3,A4}} = inet:getaddr(HostName,inet),
+ lists:flatten(io_lib:format("~p.~p.~p.~p",[A1,A2,A3,A4])).
+
+start_mnesia(Node) ->
+ case rpc:call(Node, ?MODULE, cleanup_mnesia, []) of
+ ok ->
+ ok;
+ Other ->
+ test_server:fail({failed_to_cleanup_mnesia, Other})
+ end,
+ case rpc:call(Node, ?MODULE, setup_mnesia, []) of
+ {atomic, ok} ->
+ ok;
+ Other2 ->
+ test_server:fail({failed_to_setup_mnesia, Other2})
+ end,
+ ok.
+
+setup_mnesia() ->
+ setup_mnesia([node()]).
+
+setup_mnesia(Nodes) ->
+ ok = mnesia:create_schema(Nodes),
+ ok = mnesia:start(),
+ {atomic, ok} = mnesia:create_table(httpd_user,
+ [{attributes,
+ record_info(fields, httpd_user)},
+ {disc_copies,Nodes}, {type, set}]),
+ {atomic, ok} = mnesia:create_table(httpd_group,
+ [{attributes,
+ record_info(fields,
+ httpd_group)},
+ {disc_copies,Nodes}, {type,bag}]).
+
+cleanup_mnesia() ->
+ mnesia:start(),
+ mnesia:delete_table(httpd_user),
+ mnesia:delete_table(httpd_group),
+ stopped = mnesia:stop(),
+ mnesia:delete_schema([node()]),
+ ok.
+
+create_htacess_data(Path, IpAddress)->
+ create_htacess_dirs(Path),
+
+ create_html_file(filename:join([Path,"ht/open/dummy.html"])),
+ create_html_file(filename:join([Path,"ht/blocknet/dummy.html"])),
+ create_html_file(filename:join([Path,"ht/secret/dummy.html"])),
+ create_html_file(filename:join([Path,"ht/secret/top_secret/dummy.html"])),
+
+ create_htacess_file(filename:join([Path,"ht/open/.htaccess"]),
+ Path, "user one Aladdin"),
+ create_htacess_file(filename:join([Path,"ht/secret/.htaccess"]),
+ Path, "group group1 group2"),
+ create_htacess_file(filename:join([Path,
+ "ht/secret/top_secret/.htaccess"]),
+ Path, "user four"),
+ create_htacess_file(filename:join([Path,"ht/blocknet/.htaccess"]),
+ Path, nouser, IpAddress),
+
+ create_user_group_file(filename:join([Path,"ht","users.file"]),
+ "one:OnePassword\ntwo:TwoPassword\nthree:"
+ "ThreePassword\nfour:FourPassword\nAladdin:"
+ "AladdinPassword"),
+ create_user_group_file(filename:join([Path,"ht","groups.file"]),
+ "group1: two one\ngroup2: two three").
+
+create_html_file(PathAndFileName)->
+ file:write_file(PathAndFileName,list_to_binary(
+ "<html><head><title>test</title></head>
+ <body>testar</body></html>")).
+
+create_htacess_file(PathAndFileName, BaseDir, RequireData)->
+ file:write_file(PathAndFileName,
+ list_to_binary(
+ "AuthUserFile "++ BaseDir ++
+ "/ht/users.file\nAuthGroupFile "++ BaseDir
+ ++ "/ht/groups.file\nAuthName Test\nAuthType"
+ " Basic\n<Limit>\nrequire " ++ RequireData ++
+ "\n</Limit>")).
+
+create_htacess_file(PathAndFileName, BaseDir, nouser, IpAddress)->
+ file:write_file(PathAndFileName,list_to_binary(
+ "AuthUserFile "++ BaseDir ++
+ "/ht/users.file\nAuthGroupFile " ++
+ BaseDir ++ "/ht/groups.file\nAuthName"
+ " Test\nAuthType"
+ " Basic\n<Limit GET>\n\tallow from " ++
+ format_ip(IpAddress,
+ string:rchr(IpAddress,$.)) ++
+ "\n</Limit>")).
+
+create_user_group_file(PathAndFileName, Data)->
+ file:write_file(PathAndFileName, list_to_binary(Data)).
+
+create_htacess_dirs(Path)->
+ ok = file:make_dir(filename:join([Path,"ht"])),
+ ok = file:make_dir(filename:join([Path,"ht/open"])),
+ ok = file:make_dir(filename:join([Path,"ht/blocknet"])),
+ ok = file:make_dir(filename:join([Path,"ht/secret"])),
+ ok = file:make_dir(filename:join([Path,"ht/secret/top_secret"])).
+
+remove_htacess_dirs(Path)->
+ file:del_dir(filename:join([Path,"ht/secret/top_secret"])),
+ file:del_dir(filename:join([Path,"ht/secret"])),
+ file:del_dir(filename:join([Path,"ht/blocknet"])),
+ file:del_dir(filename:join([Path,"ht/open"])),
+ file:del_dir(filename:join([Path,"ht"])).
+
+format_ip(IpAddress,Pos)when Pos > 0->
+ case lists:nth(Pos,IpAddress) of
+ $.->
+ case lists:nth(Pos-2,IpAddress) of
+ $.->
+ format_ip(IpAddress,Pos-3);
+ _->
+ lists:sublist(IpAddress,Pos-2) ++ "."
+ end;
+ _ ->
+ format_ip(IpAddress,Pos-1)
+ end;
+
+format_ip(IpAddress, _Pos)->
+ "1" ++ IpAddress.
+
+remove_htacess(Path)->
+ file:delete(filename:join([Path,"ht/open/dummy.html"])),
+ file:delete(filename:join([Path,"ht/secret/dummy.html"])),
+ file:delete(filename:join([Path,"ht/secret/top_secret/dummy.html"])),
+ file:delete(filename:join([Path,"ht/blocknet/dummy.html"])),
+ file:delete(filename:join([Path,"ht/blocknet/.htaccess"])),
+ file:delete(filename:join([Path,"ht/open/.htaccess"])),
+ file:delete(filename:join([Path,"ht/secret/.htaccess"])),
+ file:delete(filename:join([Path,"ht/secret/top_secret/.htaccess"])),
+ file:delete(filename:join([Path,"ht","users.file"])),
+ file:delete(filename:join([Path,"ht","groups.file"])),
+ remove_htacess_dirs(Path).
+
+
+dos_hostname_poll(Type, Host, Port, Node, Hosts) ->
+ [dos_hostname_poll1(Type, Host, Port, Node, Host1, Code)
+ || {Host1,Code} <- Hosts].
+
+dos_hostname_poll1(Type, Host, Port, Node, Host1, Code) ->
+ ok = httpd_test_lib:verify_request(Type, Host, Port, Node,
+ dos_hostname_request(Host1),
+ [{statuscode, Code},
+ {version, "HTTP/1.0"}]).
+
+dos_hostname_request(Host) ->
+ "GET / HTTP/1.0\r\n" ++ Host ++ "\r\n\r\n".
+
+get_nof_clients(Mode, Load) ->
+ get_nof_clients(test_server:os_type(), Mode, Load).
+
+get_nof_clients(vxworks, _, light) -> 1;
+get_nof_clients(vxworks, ip_comm, medium) -> 3;
+get_nof_clients(vxworks, ssl, medium) -> 3;
+get_nof_clients(vxworks, ip_comm, heavy) -> 5;
+get_nof_clients(vxworks, ssl, heavy) -> 5;
+get_nof_clients(_, ip_comm, light) -> 5;
+get_nof_clients(_, ssl, light) -> 2;
+get_nof_clients(_, ip_comm, medium) -> 10;
+get_nof_clients(_, ssl, medium) -> 4;
+get_nof_clients(_, ip_comm, heavy) -> 20;
+get_nof_clients(_, ssl, heavy) -> 6.
+
+%% Make a file 100 bytes long containing 012...9*10
+create_range_data(Path)->
+ PathAndFileName=filename:join([Path,"range.txt"]),
+ file:write_file(PathAndFileName,list_to_binary(["12345678901234567890",
+ "12345678901234567890",
+ "12345678901234567890",
+ "12345678901234567890",
+ "12345678901234567890"])).
+
+%% create_ipv6_config(Config, FileName, Ipv6Address) ->
+%% ServerRoot = ?config(server_root, Config),
+%% TcTopDir = ?config(tc_top_dir, Config),
+%% Port = ?config(port, Config),
+%% SockType = ?config(sock_type, Config),
+%%
+%% MaxHdrSz = io_lib:format("~p", [256]),
+%% MaxHdrAct = io_lib:format("~p", [close]),
+%%
+%% Mod_order = "Modules mod_alias mod_auth mod_esi mod_actions mod_cgi"
+%% " mod_include mod_dir mod_get mod_head"
+%% " mod_log mod_disk_log mod_trace",
+%%
+%% HttpConfig = [cline(["BindAddress ", "[" ++ Ipv6Address ++"]|inet6"]),
+%% cline(["Port ", integer_to_list(Port)]),
+%% cline(["ServerName ", "httpc_test"]),
+%% cline(["SocketType ", atom_to_list(SockType)]),
+%% cline([Mod_order]),
+%% cline(["ServerRoot ", ServerRoot]),
+%% cline(["DocumentRoot ",
+%% filename:join(ServerRoot, "htdocs")]),
+%% cline(["MaxHeaderSize ",MaxHdrSz]),
+%% cline(["MaxHeaderAction ",MaxHdrAct]),
+%% cline(["DirectoryIndex ", "index.html "]),
+%% cline(["DefaultType ", "text/plain"])],
+%% ConfigFile = filename:join([TcTopDir,FileName]),
+%% {ok, Fd} = file:open(ConfigFile, [write]),
+%% ok = file:write(Fd, lists:flatten(HttpConfig)),
+%% ok = file:close(Fd).
diff --git a/lib/inets/test/httpd_SUITE_data/Makefile.src b/lib/inets/test/httpd_SUITE_data/Makefile.src
new file mode 100644
index 0000000000..b0fdb43d8d
--- /dev/null
+++ b/lib/inets/test/httpd_SUITE_data/Makefile.src
@@ -0,0 +1,14 @@
+CC = @CC@
+LD = @LD@
+CFLAGS = @CFLAGS@ -I@erl_include@ @DEFS@
+CROSSLDFLAGS = @CROSSLDFLAGS@
+
+PROGS = cgi_echo@exe@
+
+all: $(PROGS)
+
+cgi_echo@exe@: cgi_echo@obj@
+ $(LD) $(CROSSLDFLAGS) -o cgi_echo cgi_echo@obj@ @LIBS@
+
+cgi_echo@obj@: cgi_echo.c
+ $(CC) -c -o cgi_echo@obj@ $(CFLAGS) cgi_echo.c
diff --git a/lib/inets/test/httpd_SUITE_data/cgi_echo.c b/lib/inets/test/httpd_SUITE_data/cgi_echo.c
new file mode 100644
index 0000000000..580f860e96
--- /dev/null
+++ b/lib/inets/test/httpd_SUITE_data/cgi_echo.c
@@ -0,0 +1,97 @@
+#include <stdlib.h>
+#include <stdio.h>
+
+#if defined __WIN32__
+#include <windows.h>
+#include <fcntl.h>
+#endif
+
+static int read_exact(char *buffer, int len);
+static int write_exact(char *buffer, int len);
+
+int main(void)
+{
+ char msg[100];
+ int msg_len;
+#ifdef __WIN32__
+ _setmode(_fileno( stdin), _O_BINARY);
+ _setmode(_fileno( stdout), _O_BINARY);
+#endif
+ msg_len = read_exact(msg, 100);
+
+ write_exact("Content-type: text/plain\r\n\r\n", 28);
+ write_exact(msg, msg_len);
+ exit(EXIT_SUCCESS);
+}
+
+
+/* read from stdin */
+#ifdef __WIN32__
+static int read_exact(char *buffer, int len)
+{
+ HANDLE standard_input = GetStdHandle(STD_INPUT_HANDLE);
+
+ unsigned read_result;
+ unsigned sofar = 0;
+
+ if (!len) { /* Happens for "empty packages */
+ return 0;
+ }
+ for (;;) {
+ if (!ReadFile(standard_input, buffer + sofar,
+ len - sofar, &read_result, NULL)) {
+ return -1; /* EOF */
+ }
+ if (!read_result) {
+ return -2; /* Interrupted while reading? */
+ }
+ sofar += read_result;
+ if (sofar == len) {
+ return len;
+ }
+ }
+}
+#else
+static int read_exact(char *buffer, int len) {
+ int i, got = 0;
+
+ do {
+ if ((i = read(0, buffer + got, len - got)) <= 0)
+ return(i);
+ got += i;
+ } while (got < len);
+ return len;
+
+}
+#endif
+
+/* write to stdout */
+#ifdef __WIN32__
+ static int write_exact(char *buffer, int len)
+ {
+ HANDLE standard_output = GetStdHandle(STD_OUTPUT_HANDLE);
+ unsigned written;
+
+ if (!WriteFile(standard_output, buffer, len, &written, NULL)) {
+ return -1; /* Broken Pipe */
+ }
+ if (written < ((unsigned) len)) {
+ /* This should not happen, standard output is not blocking? */
+ return -2;
+ }
+
+ return (int) written;
+}
+
+#else
+ static int write_exact(char *buffer, int len) {
+ int i, wrote = 0;
+
+ do {
+ if ((i = write(1, buffer + wrote, len - wrote)) <= 0)
+ return i;
+ wrote += i;
+ } while (wrote < len);
+ return len;
+ }
+#endif
diff --git a/lib/inets/test/httpd_SUITE_data/server_root/auth/group b/lib/inets/test/httpd_SUITE_data/server_root/auth/group
new file mode 100644
index 0000000000..b3da0ccbd3
--- /dev/null
+++ b/lib/inets/test/httpd_SUITE_data/server_root/auth/group
@@ -0,0 +1,3 @@
+group1: one two
+group2: two three
+group3: three Aladdin
diff --git a/lib/inets/test/httpd_SUITE_data/server_root/auth/passwd b/lib/inets/test/httpd_SUITE_data/server_root/auth/passwd
new file mode 100644
index 0000000000..8c980ff547
--- /dev/null
+++ b/lib/inets/test/httpd_SUITE_data/server_root/auth/passwd
@@ -0,0 +1,4 @@
+one:onePassword
+two:twoPassword
+three:threePassword
+Aladdin:AladdinPassword
diff --git a/lib/inets/test/httpd_SUITE_data/server_root/cgi-bin/printenv.bat b/lib/inets/test/httpd_SUITE_data/server_root/cgi-bin/printenv.bat
new file mode 100644
index 0000000000..25a49a1536
--- /dev/null
+++ b/lib/inets/test/httpd_SUITE_data/server_root/cgi-bin/printenv.bat
@@ -0,0 +1,9 @@
+@echo off
+echo tomrad > c:\cygwin\tmp\hej
+echo Content-type: text/html
+echo.
+echo ^<HTML^> ^<HEAD^> ^<TITLE^>OS Environment^</TITLE^> ^</HEAD^> ^<BODY^>^<PRE^>
+set
+echo ^</PRE^>^</BODY^>^</HTML^>
+
+
diff --git a/lib/inets/test/httpd_SUITE_data/server_root/cgi-bin/printenv.sh b/lib/inets/test/httpd_SUITE_data/server_root/cgi-bin/printenv.sh
new file mode 100755
index 0000000000..de81de9bde
--- /dev/null
+++ b/lib/inets/test/httpd_SUITE_data/server_root/cgi-bin/printenv.sh
@@ -0,0 +1,6 @@
+#!/bin/sh
+echo "Content-type: text/html"
+echo ""
+echo "<HTML> <HEAD> <TITLE>OS Environment</TITLE> </HEAD> <BODY><PRE>"
+env
+echo "</PRE></BODY></HTML>" \ No newline at end of file
diff --git a/lib/inets/test/httpd_SUITE_data/server_root/conf/8080.conf b/lib/inets/test/httpd_SUITE_data/server_root/conf/8080.conf
new file mode 100644
index 0000000000..48e66f0114
--- /dev/null
+++ b/lib/inets/test/httpd_SUITE_data/server_root/conf/8080.conf
@@ -0,0 +1,79 @@
+Port 8080
+#ServerName your.server.net
+SocketType ip_comm
+Modules mod_alias mod_auth mod_esi mod_actions mod_cgi mod_include mod_dir mod_get mod_head mod_log mod_disk_log
+ServerAdmin [email protected]
+ServerRoot /var/tmp/server_root
+ErrorLog logs/error_log_8080
+TransferLog logs/access_log_8080
+SecurityLog logs/security_log_8080
+ErrorDiskLog logs/error_disk_log_8080
+ErrorDiskLogSize 200000 10
+TransferDiskLog logs/access_disk_log_8080
+TransferDiskLogSize 200000 10
+SecurityDiskLog logs/security_disk_log
+SecurityDiskLogSize 200000 10
+MaxClients 50
+#KeepAlive 5
+#KeepAliveTimeout 10
+DocumentRoot /var/tmp/server_root/htdocs
+DirectoryIndex index.html welcome.html
+DefaultType text/plain
+Alias /icons/ /var/tmp/server_root/icons/
+Alias /pics/ /var/tmp/server_root/icons/
+ScriptAlias /cgi-bin/ /var/tmp/server_root/cgi-bin/
+ScriptAlias /htbin/ /var/tmp/server_root/cgi-bin/
+ErlScriptAlias /cgi-bin/erl httpd_example io
+EvalScriptAlias /eval httpd_example io
+#Script HEAD /cgi-bin/printenv.sh
+#Action image/gif /cgi-bin/printenv.sh
+
+<Directory /var/tmp/server_root/htdocs/open>
+AuthDBType plain
+AuthName Open Area
+AuthUserFile /var/tmp/server_root/auth/passwd
+AuthGroupFile /var/tmp/server_root/auth/group
+require user one Aladdin
+</Directory>
+
+<Directory /var/tmp/server_root/htdocs/secret>
+AuthDBType plain
+AuthName Secret Area
+AuthUserFile /var/tmp/server_root/auth/passwd
+AuthGroupFile /var/tmp/server_root/auth/group
+require group group1 group2
+</Directory>
+
+<Directory /var/tmp/server_root/htdocs/secret/top_secret>
+AuthDBType plain
+AuthName Top Secret Area
+AuthUserFile /var/tmp/server_root/auth/passwd
+AuthGroupFile /var/tmp/server_root/auth/group
+require group group3
+</Directory>
+
+<Directory /var/tmp/server_root/htdocs/mnesia_open>
+AuthDBType mnesia
+AuthName Open Area
+require user one Aladdin
+</Directory>
+
+<Directory /var/tmp/server_root/htdocs/mnesia_secret>
+AuthDBType mnesia
+AuthName Secret Area
+require group group1 group2
+</Directory>
+
+<Directory /var/tmp/server_root/htdocs/mnesia_secret/top_secret>
+AuthDBType mnesia
+AuthName Top Secret Area
+require group group3
+allow from 130.100.34 130.100.35
+deny from 100.234.22.12 194.100.34.1 130.100.34.25
+SecurityDataFile logs/security_data
+SecurityMaxRetries 3
+SecurityBlockTime 10
+SecurityFailExpireTime 1
+SecurityAuthTimeout 1
+SecurityCallbackModule security_callback
+</Directory>
diff --git a/lib/inets/test/httpd_SUITE_data/server_root/conf/8888.conf b/lib/inets/test/httpd_SUITE_data/server_root/conf/8888.conf
new file mode 100644
index 0000000000..79bb7fcca4
--- /dev/null
+++ b/lib/inets/test/httpd_SUITE_data/server_root/conf/8888.conf
@@ -0,0 +1,63 @@
+Port 8888
+#ServerName your.server.net
+SocketType ip_comm
+Modules mod_alias mod_auth mod_esi mod_actions mod_cgi mod_include mod_dir mod_get mod_head mod_log mod_disk_log
+ServerAdmin [email protected]
+ServerRoot /var/tmp/server_root
+ErrorLog logs/error_log_8888
+TransferLog logs/access_log_8888
+ErrorDiskLog logs/error_disk_log_8888
+ErrorDiskLogSize 200000 10
+TransferDiskLog logs/access_disk_log_8888
+TransferDiskLogSize 200000 10
+MaxClients 150
+DocumentRoot /var/tmp/server_root/htdocs
+DirectoryIndex index.html welcome.html
+DefaultType text/plain
+Alias /icons/ /var/tmp/server_root/icons/
+Alias /pics/ /var/tmp/server_root/icons/
+ScriptAlias /cgi-bin/ /var/tmp/server_root/cgi-bin/
+ScriptAlias /htbin/ /var/tmp/server_root/cgi-bin/
+ErlScriptAlias /cgi-bin/erl httpd_example io
+EvalScriptAlias /eval httpd_example io
+#Script HEAD /cgi-bin/printenv.sh
+#Action image/gif /cgi-bin/printenv.sh
+
+<Directory /var/tmp/server_root/htdocs/open>
+AuthName Open Area
+AuthUserFile /var/tmp/server_root/auth/passwd
+AuthGroupFile /var/tmp/server_root/auth/group
+require user one Aladdin
+</Directory>
+
+<Directory /var/tmp/server_root/htdocs/secret>
+AuthName Secret Area
+AuthUserFile /var/tmp/server_root/auth/passwd
+AuthGroupFile /var/tmp/server_root/auth/group
+require group group1 group2
+</Directory>
+
+<Directory /var/tmp/server_root/htdocs/secret/top_secret>
+AuthName Top Secret Area
+AuthUserFile /var/tmp/server_root/auth/passwd
+AuthGroupFile /var/tmp/server_root/auth/group
+require group group3
+</Directory>
+
+<Directory /var/tmp/server_root/htdocs/mnesia_open>
+AuthName Open Area
+AuthMnesiaDB On
+require user one Aladdin
+</Directory>
+
+<Directory /var/tmp/server_root/htdocs/mnesia_secret>
+AuthName Secret Area
+AuthMnesiaDB On
+require group group1 group2
+</Directory>
+
+<Directory /var/tmp/server_root/htdocs/mnesia_secret/top_secret>
+AuthName Top Secret Area
+AuthMnesiaDB On
+require group group3
+</Directory>
diff --git a/lib/inets/test/httpd_SUITE_data/server_root/conf/httpd.conf b/lib/inets/test/httpd_SUITE_data/server_root/conf/httpd.conf
new file mode 100644
index 0000000000..8a74ed1afd
--- /dev/null
+++ b/lib/inets/test/httpd_SUITE_data/server_root/conf/httpd.conf
@@ -0,0 +1,268 @@
+#
+# %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%
+#
+#
+
+# Port: The port the standalone listens to. For ports < 1023, you will
+# need httpd to be run as root initially.
+
+Port 8888
+
+# BindAddress: This directive is used to tell the server which IP address
+# to listen to. It can either contain "*", an IP address, or a fully
+# qualified Internet domain name.
+#
+# It is also possible to specify the ip-family with the directive.
+# There ar three possible value: inet, inet6 and inet6fb4
+# inet: Use IpFamily inet when retreiving the address and
+# fail if that does not work.
+# inet6: Use IpFamily inet6 when retreiving the address and
+# fail if that does not work.
+# inet6fb4: First IpFamily inet6 is tried and if that does not work,
+# inet is used as fallback.
+# Default value for ip-family is inet6fb4
+#
+# The syntax is: <address>[|<ip-family>]
+#
+#BindAddress *
+#BindAddress *|inet
+
+
+# ServerName allows you to set a host name which is sent back to clients for
+# your server if it's different than the one the program would get (i.e. use
+# "www" instead of the host's real name).
+#
+# Note: You cannot just invent host names and hope they work. The name you
+# define here must be a valid DNS name for your host. If you don't understand
+# this, ask your network administrator.
+
+#ServerName your.server.net
+
+# SocketType is either ip_comm, sockets or ssl.
+
+SocketType ip_comm
+
+# Modules: Server run-time plug-in modules written using the Erlang
+# Web Server API (EWSAPI). The server API make it easy to add functionality
+# to the server. Read more about EWSAPI in the Reference Manual.
+# WARNING! Do not tamper with this directive unless you are familiar with
+# EWSAPI.
+
+Modules mod_alias mod_auth mod_esi mod_actions mod_cgi mod_responsecontrol mod_trace mod_range mod_head mod_include mod_dir mod_get mod_log mod_disk_log
+
+# ServerAdmin: Your address, where problems with the server should be
+# e-mailed.
+
+ServerAdmin [email protected]
+
+# ServerRoot: The directory the server's config, error, and log files
+# are kept in
+
+ServerRoot /var/tmp/server_root
+
+# ErrorLog: The location of the error log file. If this does not start
+# with /, ServerRoot is prepended to it.
+
+ErrorLog logs/error_log
+
+# TransferLog: The location of the transfer log file. If this does not
+# start with /, ServerRoot is prepended to it.
+
+TransferLog logs/access_log
+
+# SecurityLog: The location of the security log file (mod_security required)
+#
+SecurityLog logs/security_log
+
+# ErrorDiskLog: The location of the error log file. If this does not
+# start with /, ServerRoot is prepended to it. This log file is managed
+# with the disk_log module [See disk_log(3)]. The ErrorDiskLogSize directive
+# takes two argument, i.e. MaxBytes and MaxFiles. The wrap log writes at most
+# MaxBytes bytes on each file, and it uses MaxFiles files before it wraps, and
+# truncates the first file.
+
+ErrorDiskLog logs/error_disk_log
+ErrorDiskLogSize 200000 10
+
+# TransferDiskLog: The location of the transfer log file. If this does not
+# start with /, ServerRoot is prepended to it. This log file is managed
+# with the disk_log module [See disk_log(3)]. The TransferDiskLogSize directive
+# takes two argument, i.e. MaxBytes and MaxFiles. The wrap log writes at most
+# MaxBytes bytes on each file, and it uses MaxFiles files before it wraps, and
+# truncates the first file.
+
+TransferDiskLog logs/access_disk_log
+TransferDiskLogSize 200000 10
+
+# SecurityDiskLog: The location of the security log file. If this does not
+# start with /, ServerRoot is prepended to it. This log file is managed
+# with the disk_log module [See disk_log(3)]. The SecurityDiskLogSize directive
+# takes two argument, i.e. MaxBytes and MaxFiles. The wrap log writes at most
+# MaxBytes bytes on each file, and it uses MaxFiles files before it wraps, and
+# truncates the first file.
+
+SecurityDiskLog logs/security_disk_log
+SecurityDiskLogSize 200000 10
+
+# Limit on total number of servers running, i.e., limit on the number
+# of clients who can simultaneously connect --- if this limit is ever
+# reached, clients will be LOCKED OUT, so it should NOT BE SET TOO LOW.
+# It is intended mainly as a brake to keep a runaway server from taking
+# the server with it as it spirals down...
+
+MaxClients 50
+
+# KeepAlive set the flag for persistent connections. For peristent connections
+# set KeepAlive to on. To use One request per connection set the flag to off
+# Note: The value has changed since previous version of INETS.
+KeepAlive on
+
+# KeepAliveTimeout sets the number of seconds before a persistent connection
+# times out and closes.
+KeepAliveTimeout 10
+
+# MaxKeepAliveRequests sets the number of seconds before a persistent connection
+# times out and closes.
+MaxKeepAliveRequests 10
+
+
+
+# DocumentRoot: The directory out of which you will serve your
+# documents. By default, all requests are taken from this directory, but
+# symbolic links and aliases may be used to point to other locations.
+
+DocumentRoot /var/tmp/server_root/htdocs
+
+# DirectoryIndex: Name of the file or files to use as a pre-written HTML
+# directory index. Separate multiple entries with spaces.
+
+DirectoryIndex index.html welcome.html
+
+# DefaultType is the default MIME type for documents which the server
+# cannot find the type of from filename extensions.
+
+DefaultType text/plain
+
+# Aliases: Add here as many aliases as you need (with no limit). The format is
+# Alias fakename realname
+
+Alias /icons/ /var/tmp/server_root/icons/
+Alias /pics/ /var/tmp/server_root/icons/
+
+# ScriptAlias: This controls which directories contain server scripts.
+# Format: ScriptAlias fakename realname
+
+ScriptAlias /cgi-bin/ /var/tmp/server_root/cgi-bin/
+ScriptAlias /htbin/ /var/tmp/server_root/cgi-bin/
+
+# This directive adds an action, which will activate cgi-script when a
+# file is requested using the method of method, which can be one of
+# GET, POST and HEAD. It sends the URL and file path of the requested
+# document using the standard CGI PATH_INFO and PATH_TRANSLATED
+# environment variables.
+
+#Script HEAD /cgi-bin/printenv.sh
+
+# This directive adds an action, which will activate cgi-script when a
+# file of content type mime-type is requested. It sends the URL and
+# file path of the requested document using the standard CGI PATH_INFO
+# and PATH_TRANSLATED environment variables.
+
+#Action image/gif /cgi-bin/printenv.sh
+
+# ErlScriptAlias: This specifies how "Erl" server scripts are called.
+# Format: ErlScriptAlias fakename realname allowed_modules
+
+ErlScriptAlias /down/erl httpd_example io
+
+# EvalScriptAlias: This specifies how "Eval" server scripts are called.
+# Format: EvalScriptAlias fakename realname allowed_modules
+
+EvalScriptAlias /eval httpd_example io
+
+# Point SSLCertificateFile at a PEM encoded certificate.
+
+SSLCertificateFile /var/tmp/server_root/ssl/ssl_server.pem
+
+# If the key is not combined with the certificate, use this directive to
+# point at the key file.
+
+SSLCertificateKeyFile /var/tmp/server_root/ssl/ssl_server.pem
+
+# Set SSLVerifyClient to:
+# 0 if no certicate is required
+# 1 if the client may present a valid certificate
+# 2 if the client must present a valid certificate
+# 3 if the client may present a valid certificate but it is not required to
+# have a valid CA
+
+SSLVerifyClient 0
+
+# Each directory to which INETS has access, can be configured with respect
+# to which services and features are allowed and/or disabled in that
+# directory (and its subdirectories).
+
+<Directory /var/tmp/server_root/htdocs/open>
+AuthDBType plain
+AuthName Open Area
+AuthUserFile /var/tmp/server_root/auth/passwd
+AuthGroupFile /var/tmp/server_root/auth/group
+require user one Aladdin
+</Directory>
+
+<Directory /var/tmp/server_root/htdocs/secret>
+AuthDBType plain
+AuthName Secret Area
+AuthUserFile /var/tmp/server_root/auth/passwd
+AuthGroupFile /var/tmp/server_root/auth/group
+require group group1 group2
+</Directory>
+
+<Directory /var/tmp/server_root/htdocs/secret/top_secret>
+AuthDBType plain
+AuthName Top Secret Area
+AuthUserFile /var/tmp/server_root/auth/passwd
+AuthGroupFile /var/tmp/server_root/auth/group
+require group group3
+</Directory>
+
+<Directory /var/tmp/server_root/htdocs/mnesia_open>
+AuthDBType mnesia
+AuthName Open Area
+require user one Aladdin
+</Directory>
+
+<Directory /var/tmp/server_root/htdocs/mnesia_secret>
+AuthDBType mnesia
+AuthName Secret Area
+require group group1 group2
+</Directory>
+
+<Directory /var/tmp/server_root/htdocs/mnesia_secret/top_secret>
+AuthDBType mnesia
+AuthName Top Secret Area
+require group group3
+allow from 130.100.34 130.100.35
+deny from 100.234.22.12 194.100.34.1 130.100.34.25
+SecurityDataFile logs/security_data
+SecurityMaxRetries 3
+SecurityBlockTime 10
+SecurityFailExpireTime 1
+SecurityAuthTimeout 1
+SecurityCallbackModule security_callback
+</Directory>
diff --git a/lib/inets/test/httpd_SUITE_data/server_root/conf/mime.types b/lib/inets/test/httpd_SUITE_data/server_root/conf/mime.types
new file mode 100644
index 0000000000..d2f81e4e5e
--- /dev/null
+++ b/lib/inets/test/httpd_SUITE_data/server_root/conf/mime.types
@@ -0,0 +1,465 @@
+# This is a comment. I love comments.
+
+# MIME type Extension
+application/EDI-Consent
+application/EDI-X12
+application/EDIFACT
+application/activemessage
+application/andrew-inset ez
+application/applefile
+application/atomicmail
+application/batch-SMTP
+application/beep+xml
+application/cals-1840
+application/commonground
+application/cybercash
+application/dca-rft
+application/dec-dx
+application/dvcs
+application/eshop
+application/http
+application/hyperstudio
+application/iges
+application/index
+application/index.cmd
+application/index.obj
+application/index.response
+application/index.vnd
+application/iotp
+application/ipp
+application/isup
+application/font-tdpfr
+application/mac-binhex40 hqx
+application/mac-compactpro cpt
+application/macwriteii
+application/marc
+application/mathematica
+application/mathematica-old
+application/msword doc
+application/news-message-id
+application/news-transmission
+application/ocsp-request
+application/ocsp-response
+application/octet-stream bin dms lha lzh exe class so dll
+application/oda oda
+application/parityfec
+application/pdf pdf
+application/pgp-encrypted
+application/pgp-keys
+application/pgp-signature
+application/pkcs10
+application/pkcs7-mime
+application/pkcs7-signature
+application/pkix-cert
+application/pkix-crl
+application/pkixcmp
+application/postscript ai eps ps
+application/prs.alvestrand.titrax-sheet
+application/prs.cww
+application/prs.nprend
+application/qsig
+application/remote-printing
+application/riscos
+application/rtf
+application/sdp
+application/set-payment
+application/set-payment-initiation
+application/set-registration
+application/set-registration-initiation
+application/sgml
+application/sgml-open-catalog
+application/sieve
+application/slate
+application/smil smi smil
+application/timestamp-query
+application/timestamp-reply
+application/vemmi
+application/vnd.3M.Post-it-Notes
+application/vnd.FloGraphIt
+application/vnd.accpac.simply.aso
+application/vnd.accpac.simply.imp
+application/vnd.acucobol
+application/vnd.aether.imp
+application/vnd.anser-web-certificate-issue-initiation
+application/vnd.anser-web-funds-transfer-initiation
+application/vnd.audiograph
+application/vnd.businessobjects
+application/vnd.bmi
+application/vnd.canon-cpdl
+application/vnd.canon-lips
+application/vnd.claymore
+application/vnd.commerce-battelle
+application/vnd.commonspace
+application/vnd.comsocaller
+application/vnd.contact.cmsg
+application/vnd.cosmocaller
+application/vnd.cups-postscript
+application/vnd.cups-raster
+application/vnd.cups-raw
+application/vnd.ctc-posml
+application/vnd.cybank
+application/vnd.dna
+application/vnd.dpgraph
+application/vnd.dxr
+application/vnd.ecdis-update
+application/vnd.ecowin.chart
+application/vnd.ecowin.filerequest
+application/vnd.ecowin.fileupdate
+application/vnd.ecowin.series
+application/vnd.ecowin.seriesrequest
+application/vnd.ecowin.seriesupdate
+application/vnd.enliven
+application/vnd.epson.esf
+application/vnd.epson.msf
+application/vnd.epson.quickanime
+application/vnd.epson.salt
+application/vnd.epson.ssf
+application/vnd.ericsson.quickcall
+application/vnd.eudora.data
+application/vnd.fdf
+application/vnd.ffsns
+application/vnd.framemaker
+application/vnd.fsc.weblaunch
+application/vnd.fujitsu.oasys
+application/vnd.fujitsu.oasys2
+application/vnd.fujitsu.oasys3
+application/vnd.fujitsu.oasysgp
+application/vnd.fujitsu.oasysprs
+application/vnd.fujixerox.ddd
+application/vnd.fujixerox.docuworks
+application/vnd.fujixerox.docuworks.binder
+application/vnd.fut-misnet
+application/vnd.grafeq
+application/vnd.groove-account
+application/vnd.groove-identity-message
+application/vnd.groove-injector
+application/vnd.groove-tool-message
+application/vnd.groove-tool-template
+application/vnd.groove-vcard
+application/vnd.hhe.lesson-player
+application/vnd.hp-HPGL
+application/vnd.hp-PCL
+application/vnd.hp-PCLXL
+application/vnd.hp-hpid
+application/vnd.hp-hps
+application/vnd.httphone
+application/vnd.hzn-3d-crossword
+application/vnd.ibm.afplinedata
+application/vnd.ibm.MiniPay
+application/vnd.ibm.modcap
+application/vnd.informix-visionary
+application/vnd.intercon.formnet
+application/vnd.intertrust.digibox
+application/vnd.intertrust.nncp
+application/vnd.intu.qbo
+application/vnd.intu.qfx
+application/vnd.irepository.package+xml
+application/vnd.is-xpr
+application/vnd.japannet-directory-service
+application/vnd.japannet-jpnstore-wakeup
+application/vnd.japannet-payment-wakeup
+application/vnd.japannet-registration
+application/vnd.japannet-registration-wakeup
+application/vnd.japannet-setstore-wakeup
+application/vnd.japannet-verification
+application/vnd.japannet-verification-wakeup
+application/vnd.koan
+application/vnd.lotus-1-2-3
+application/vnd.lotus-approach
+application/vnd.lotus-freelance
+application/vnd.lotus-notes
+application/vnd.lotus-organizer
+application/vnd.lotus-screencam
+application/vnd.lotus-wordpro
+application/vnd.mcd
+application/vnd.mediastation.cdkey
+application/vnd.meridian-slingshot
+application/vnd.mif mif
+application/vnd.minisoft-hp3000-save
+application/vnd.mitsubishi.misty-guard.trustweb
+application/vnd.mobius.daf
+application/vnd.mobius.dis
+application/vnd.mobius.msl
+application/vnd.mobius.plc
+application/vnd.mobius.txf
+application/vnd.motorola.flexsuite
+application/vnd.motorola.flexsuite.adsi
+application/vnd.motorola.flexsuite.fis
+application/vnd.motorola.flexsuite.gotap
+application/vnd.motorola.flexsuite.kmr
+application/vnd.motorola.flexsuite.ttc
+application/vnd.motorola.flexsuite.wem
+application/vnd.mozilla.xul+xml
+application/vnd.ms-artgalry
+application/vnd.ms-asf
+application/vnd.ms-excel xls
+application/vnd.ms-lrm
+application/vnd.ms-powerpoint ppt
+application/vnd.ms-project
+application/vnd.ms-tnef
+application/vnd.ms-works
+application/vnd.mseq
+application/vnd.msign
+application/vnd.music-niff
+application/vnd.musician
+application/vnd.netfpx
+application/vnd.noblenet-directory
+application/vnd.noblenet-sealer
+application/vnd.noblenet-web
+application/vnd.novadigm.EDM
+application/vnd.novadigm.EDX
+application/vnd.novadigm.EXT
+application/vnd.osa.netdeploy
+application/vnd.palm
+application/vnd.pg.format
+application/vnd.pg.osasli
+application/vnd.powerbuilder6
+application/vnd.powerbuilder6-s
+application/vnd.powerbuilder7
+application/vnd.powerbuilder7-s
+application/vnd.powerbuilder75
+application/vnd.powerbuilder75-s
+application/vnd.previewsystems.box
+application/vnd.publishare-delta-tree
+application/vnd.pvi.ptid1
+application/vnd.pwg-xhtml-print+xml
+application/vnd.rapid
+application/vnd.s3sms
+application/vnd.seemail
+application/vnd.shana.informed.formdata
+application/vnd.shana.informed.formtemplate
+application/vnd.shana.informed.interchange
+application/vnd.shana.informed.package
+application/vnd.sss-cod
+application/vnd.sss-dtf
+application/vnd.sss-ntf
+application/vnd.street-stream
+application/vnd.svd
+application/vnd.swiftview-ics
+application/vnd.triscape.mxs
+application/vnd.trueapp
+application/vnd.truedoc
+application/vnd.tve-trigger
+application/vnd.ufdl
+application/vnd.uplanet.alert
+application/vnd.uplanet.alert-wbxml
+application/vnd.uplanet.bearer-choice-wbxml
+application/vnd.uplanet.bearer-choice
+application/vnd.uplanet.cacheop
+application/vnd.uplanet.cacheop-wbxml
+application/vnd.uplanet.channel
+application/vnd.uplanet.channel-wbxml
+application/vnd.uplanet.list
+application/vnd.uplanet.list-wbxml
+application/vnd.uplanet.listcmd
+application/vnd.uplanet.listcmd-wbxml
+application/vnd.uplanet.signal
+application/vnd.vcx
+application/vnd.vectorworks
+application/vnd.vidsoft.vidconference
+application/vnd.visio
+application/vnd.vividence.scriptfile
+application/vnd.wap.sic
+application/vnd.wap.slc
+application/vnd.wap.wbxml wbxml
+application/vnd.wap.wmlc wmlc
+application/vnd.wap.wmlscriptc wmlsc
+application/vnd.webturbo
+application/vnd.wrq-hp3000-labelled
+application/vnd.wt.stf
+application/vnd.xara
+application/vnd.xfdl
+application/vnd.yellowriver-custom-menu
+application/whoispp-query
+application/whoispp-response
+application/wita
+application/wordperfect5.1
+application/x-bcpio bcpio
+application/x-cdlink vcd
+application/x-chess-pgn pgn
+application/x-compress
+application/x-cpio cpio
+application/x-csh csh
+application/x-director dcr dir dxr
+application/x-dvi dvi
+application/x-futuresplash spl
+application/x-gtar gtar
+application/x-gzip
+application/x-hdf hdf
+application/x-javascript js
+application/x-koan skp skd skt skm
+application/x-latex latex
+application/x-netcdf nc cdf
+application/x-sh sh
+application/x-shar shar
+application/x-shockwave-flash swf
+application/x-stuffit sit
+application/x-sv4cpio sv4cpio
+application/x-sv4crc sv4crc
+application/x-tar tar
+application/x-tcl tcl
+application/x-tex tex
+application/x-texinfo texinfo texi
+application/x-troff t tr roff
+application/x-troff-man man
+application/x-troff-me me
+application/x-troff-ms ms
+application/x-ustar ustar
+application/x-wais-source src
+application/x400-bp
+application/xml
+application/xml-dtd
+application/xml-external-parsed-entity
+application/zip zip
+audio/32kadpcm
+audio/basic au snd
+audio/g.722.1
+audio/l16
+audio/midi mid midi kar
+audio/mp4a-latm
+audio/mpa-robust
+audio/mpeg mpga mp2 mp3
+audio/parityfec
+audio/prs.sid
+audio/telephone-event
+audio/tone
+audio/vnd.cisco.nse
+audio/vnd.cns.anp1
+audio/vnd.cns.inf1
+audio/vnd.digital-winds
+audio/vnd.everad.plj
+audio/vnd.lucent.voice
+audio/vnd.nortel.vbk
+audio/vnd.nuera.ecelp4800
+audio/vnd.nuera.ecelp7470
+audio/vnd.nuera.ecelp9600
+audio/vnd.octel.sbc
+audio/vnd.qcelp
+audio/vnd.rhetorex.32kadpcm
+audio/vnd.vmx.cvsd
+audio/x-aiff aif aiff aifc
+audio/x-mpegurl m3u
+audio/x-pn-realaudio ram rm
+audio/x-pn-realaudio-plugin rpm
+audio/x-realaudio ra
+audio/x-wav wav
+chemical/x-pdb pdb
+chemical/x-xyz xyz
+image/bmp bmp
+image/cgm
+image/g3fax
+image/gif gif
+image/ief ief
+image/jpeg jpeg jpg jpe
+image/naplps
+image/png png
+image/prs.btif
+image/prs.pti
+image/tiff tiff tif
+image/vnd.cns.inf2
+image/vnd.dwg
+image/vnd.dxf
+image/vnd.fastbidsheet
+image/vnd.fpx
+image/vnd.fst
+image/vnd.fujixerox.edmics-mmr
+image/vnd.fujixerox.edmics-rlc
+image/vnd.mix
+image/vnd.net-fpx
+image/vnd.svf
+image/vnd.wap.wbmp wbmp
+image/vnd.xiff
+image/x-cmu-raster ras
+image/x-portable-anymap pnm
+image/x-portable-bitmap pbm
+image/x-portable-graymap pgm
+image/x-portable-pixmap ppm
+image/x-rgb rgb
+image/x-xbitmap xbm
+image/x-xpixmap xpm
+image/x-xwindowdump xwd
+message/delivery-status
+message/disposition-notification
+message/external-body
+message/http
+message/news
+message/partial
+message/rfc822
+message/s-http
+model/iges igs iges
+model/mesh msh mesh silo
+model/vnd.dwf
+model/vnd.flatland.3dml
+model/vnd.gdl
+model/vnd.gs-gdl
+model/vnd.gtw
+model/vnd.mts
+model/vnd.vtu
+model/vrml wrl vrml
+multipart/alternative
+multipart/appledouble
+multipart/byteranges
+multipart/digest
+multipart/encrypted
+multipart/form-data
+multipart/header-set
+multipart/mixed
+multipart/parallel
+multipart/related
+multipart/report
+multipart/signed
+multipart/voice-message
+text/calendar
+text/css css
+text/directory
+text/enriched
+text/html html htm
+text/parityfec
+text/plain asc txt
+text/prs.lines.tag
+text/rfc822-headers
+text/richtext rtx
+text/rtf rtf
+text/sgml sgml sgm
+text/tab-separated-values tsv
+text/t140
+text/uri-list
+text/vnd.DMClientScript
+text/vnd.IPTC.NITF
+text/vnd.IPTC.NewsML
+text/vnd.abc
+text/vnd.curl
+text/vnd.flatland.3dml
+text/vnd.fly
+text/vnd.fmi.flexstor
+text/vnd.in3d.3dml
+text/vnd.in3d.spot
+text/vnd.latex-z
+text/vnd.motorola.reflex
+text/vnd.ms-mediapackage
+text/vnd.wap.si
+text/vnd.wap.sl
+text/vnd.wap.wml wml
+text/vnd.wap.wmlscript wmls
+text/x-setext etx
+text/x-server-parsed-html shtml
+text/xml xml xsl
+text/xml-external-parsed-entity
+video/mp4v-es
+video/mpeg mpeg mpg mpe
+video/parityfec
+video/pointer
+video/quicktime qt mov
+video/vnd.fvt
+video/vnd.motorola.video
+video/vnd.motorola.videop
+video/vnd.mpegurl mxu
+video/vnd.mts
+video/vnd.nokia.interleaved-multimedia
+video/vnd.vivo
+video/x-msvideo avi
+video/x-sgi-movie movie
+x-conference/x-cooltalk ice
+
+
+
diff --git a/lib/inets/test/httpd_SUITE_data/server_root/conf/ssl.conf b/lib/inets/test/httpd_SUITE_data/server_root/conf/ssl.conf
new file mode 100644
index 0000000000..8b8c57a98b
--- /dev/null
+++ b/lib/inets/test/httpd_SUITE_data/server_root/conf/ssl.conf
@@ -0,0 +1,66 @@
+Port 8088
+#ServerName your.server.net
+SocketType ssl
+Modules mod_alias mod_auth mod_esi mod_actions mod_cgi mod_include mod_dir mod_get mod_head mod_log mod_disk_log
+ServerAdmin [email protected]
+ServerRoot /var/tmp/server_root
+ErrorLog logs/error_log_8088
+TransferLog logs/access_log_8088
+ErrorDiskLog logs/error_disk_log_8088
+ErrorDiskLogSize 200000 10
+TransferDiskLog logs/access_disk_log_8088
+TransferDiskLogSize 200000 10
+MaxClients 150
+DocumentRoot /var/tmp/server_root/htdocs
+DirectoryIndex index.html welcome.html
+DefaultType text/plain
+Alias /icons/ /var/tmp/server_root/icons/
+Alias /pics/ /var/tmp/server_root/icons/
+ScriptAlias /cgi-bin/ /var/tmp/server_root/cgi-bin/
+ScriptAlias /htbin/ /var/tmp/server_root/cgi-bin/
+ErlScriptAlias /cgi-bin/erl httpd_example io
+EvalScriptAlias /eval httpd_example io
+SSLCertificateFile /var/tmp/server_root/ssl/ssl_server.pem
+SSLCertificateKeyFile /var/tmp/server_root/ssl/ssl_server.pem
+SSLVerifyClient 0
+#Script HEAD /cgi-bin/printenv.sh
+#Action image/gif /cgi-bin/printenv.sh
+
+<Directory /var/tmp/server_root/htdocs/open>
+AuthName Open Area
+AuthUserFile /var/tmp/server_root/auth/passwd
+AuthGroupFile /var/tmp/server_root/auth/group
+require user one Aladdin
+</Directory>
+
+<Directory /var/tmp/server_root/htdocs/secret>
+AuthName Secret Area
+AuthUserFile /var/tmp/server_root/auth/passwd
+AuthGroupFile /var/tmp/server_root/auth/group
+require group group1 group2
+</Directory>
+
+<Directory /var/tmp/server_root/htdocs/secret/top_secret>
+AuthName Top Secret Area
+AuthUserFile /var/tmp/server_root/auth/passwd
+AuthGroupFile /var/tmp/server_root/auth/group
+require group group3
+</Directory>
+
+<Directory /var/tmp/server_root/htdocs/mnesia_open>
+AuthName Open Area
+AuthMnesiaDB On
+require user one Aladdin
+</Directory>
+
+<Directory /var/tmp/server_root/htdocs/mnesia_secret>
+AuthName Secret Area
+AuthMnesiaDB On
+require group group1 group2
+</Directory>
+
+<Directory /var/tmp/server_root/htdocs/mnesia_secret/top_secret>
+AuthName Top Secret Area
+AuthMnesiaDB On
+require group group3
+</Directory>
diff --git a/lib/inets/test/httpd_SUITE_data/server_root/htdocs/config.shtml b/lib/inets/test/httpd_SUITE_data/server_root/htdocs/config.shtml
new file mode 100644
index 0000000000..107e3ff610
--- /dev/null
+++ b/lib/inets/test/httpd_SUITE_data/server_root/htdocs/config.shtml
@@ -0,0 +1,70 @@
+<HTML>
+<HEAD>
+<TITLE>/ssi.html (17-Apr-1997)</TITLE>
+</HEAD>
+<BODY>
+<H1>/ssi.html</H1>
+
+<!-- ************* CONFIG ************* -->
+
+<!--#config timefmt="%a %b %e %T %Z %Y" sizefmt="abbrev"-->
+<!--#config errmsg="[an especially ugly error occurred while processing this directive]"-->
+
+<!-- ************* INCLUDE ************* -->
+
+<P>Include /misc/friedrich.html:
+<!--#include virtual="/misc/friedrich.html"-->
+<P>Include /misc/not_defined.html: <!--#include virtual="/misc/not_defined.html"-->
+<P>Include misc/friedrich.html:
+<!--#include file="misc/friedrich.html"-->
+<P>Include not_defined.html: <!--#include file="not_defined.html"-->
+
+<P><HR>
+
+<!-- ************* ECHO ************* -->
+
+<P>DOCUMENT_NAME: <!--#echo var="DOCUMENT_NAME"-->
+<P>DOCUMENT_URI: <!--#echo var="DOCUMENT_URI"-->
+<P>QUERY_STRING_UNESCAPED: <!--#echo var="QUERY_STRING_UNESCAPED"-->
+<P>DATE_LOCAL: <!--#echo var="DATE_LOCAL"-->
+<P>DATE_GMT: <!--#echo var="DATE_GMT"-->
+<P>LAST_MODIFIED: <!--#echo var="LAST_MODIFIED"-->
+<P>NOT_DEFINED: <!--#echo var="NOT_DEFINED"-->
+
+<P><HR>
+
+<!-- ************* FSIZE ************* -->
+
+<P>Size of index.html: <!--#fsize file="index.html"-->
+<P>Size of not_defined.html: <!--#fsize file="not_defined.html"-->
+<!--#config sizefmt="bytes"-->
+<P>Size of /misc/friedrich.html: <!--#fsize virtual="/misc/friedrich.html"-->
+<P>Size of /misc/not_defined.html: <!--#fsize virtual="/misc/not_defined.html"-->
+
+<P><HR>
+
+<!-- ************* FLASTMOD ************* -->
+
+<P>Last modification of index.html: <!--#flastmod file="index.html"-->
+<P>Last modification of not_defined.html: <!--#flastmod file="not_defined.html"-->
+<P>Last modification of /misc/friedrich.html: <!--#flastmod virtual="/misc/friedrich.html"-->
+<P>Last modification of /misc/not_defined.html: <!--#flastmod virtual="/misc/not_defined.html"-->
+
+<!--#exec cmd="ls"-->
+<!--#exec cmd="printenv"-->
+<!--#exec cmd="sunemaja"-->
+
+<!--#exec cgi="/cgi-bin/printenv.sh"-->
+
+</BODY>
+</HTML>
+
+
+
+
+
+
+
+
+
+
diff --git a/lib/inets/test/httpd_SUITE_data/server_root/htdocs/dets_open/dummy.html b/lib/inets/test/httpd_SUITE_data/server_root/htdocs/dets_open/dummy.html
new file mode 100644
index 0000000000..a6e8a35a04
--- /dev/null
+++ b/lib/inets/test/httpd_SUITE_data/server_root/htdocs/dets_open/dummy.html
@@ -0,0 +1,10 @@
+<HTML>
+<HEAD>
+<TITLE>/open/dummy.html (17-Apr-1997)</TITLE>
+<!-- Created by: Joakim Greben�, 17-Apr-1997 -->
+<!-- Changed by: Joakim Greben�, 17-Apr-1997 -->
+</HEAD>
+<BODY>
+<H1>/open/dummy.html</H1>
+</BODY>
+</HTML>
diff --git a/lib/inets/test/httpd_SUITE_data/server_root/htdocs/dets_secret/dummy.html b/lib/inets/test/httpd_SUITE_data/server_root/htdocs/dets_secret/dummy.html
new file mode 100644
index 0000000000..016b04e540
--- /dev/null
+++ b/lib/inets/test/httpd_SUITE_data/server_root/htdocs/dets_secret/dummy.html
@@ -0,0 +1,10 @@
+<HTML>
+<HEAD>
+<TITLE>/secret/dummy.html (17-Apr-1997)</TITLE>
+<!-- Created by: Joakim Greben�, 17-Apr-1997 -->
+<!-- Changed by: Joakim Greben�, 17-Apr-1997 -->
+</HEAD>
+<BODY>
+<H1>/secret/dummy.html</H1>
+</BODY>
+</HTML>
diff --git a/lib/inets/test/httpd_SUITE_data/server_root/htdocs/dets_secret/top_secret/index.html b/lib/inets/test/httpd_SUITE_data/server_root/htdocs/dets_secret/top_secret/index.html
new file mode 100644
index 0000000000..34db3d5d1a
--- /dev/null
+++ b/lib/inets/test/httpd_SUITE_data/server_root/htdocs/dets_secret/top_secret/index.html
@@ -0,0 +1,9 @@
+<HTML>
+<HEAD>
+<TITLE>/secret/top_secret/index.html (04-Feb-1998)</TITLE>
+<!-- Created by: Mattias Nilsson, 04-Feb-1998 -->
+</HEAD>
+<BODY>
+<H1>/secret/top_secret/index.html</H1>
+</BODY>
+</HTML>
diff --git a/lib/inets/test/httpd_SUITE_data/server_root/htdocs/echo.shtml b/lib/inets/test/httpd_SUITE_data/server_root/htdocs/echo.shtml
new file mode 100644
index 0000000000..141db5be59
--- /dev/null
+++ b/lib/inets/test/httpd_SUITE_data/server_root/htdocs/echo.shtml
@@ -0,0 +1,35 @@
+<HTML>
+<HEAD>
+<TITLE>/echo.shtml</TITLE>
+</HEAD>
+<BODY>
+<H1>/echo.shtml</H1>
+
+<P>DOCUMENT_NAME: <!--#echo var="DOCUMENT_NAME"-->
+
+<P>DOCUMENT_URI: <!--#echo var="DOCUMENT_URI"-->
+
+<P>QUERY_STRING_UNESCAPED: <!--#echo var="QUERY_STRING_UNESCAPED"-->
+
+<P>DATE_LOCAL: <!--#echo var="DATE_LOCAL"-->
+
+<P>DATE_GMT: <!--#echo var="DATE_GMT"-->
+
+<P>LAST_MODIFIED: <!--#echo var="LAST_MODIFIED"-->
+
+<P>NOT_DEFINED: <!--#echo var="NOT_DEFINED"-->
+
+<P>[<A HREF="ssi.html">Back</A>]
+
+</BODY>
+</HTML>
+
+
+
+
+
+
+
+
+
+
diff --git a/lib/inets/test/httpd_SUITE_data/server_root/htdocs/exec.shtml b/lib/inets/test/httpd_SUITE_data/server_root/htdocs/exec.shtml
new file mode 100644
index 0000000000..97333da898
--- /dev/null
+++ b/lib/inets/test/httpd_SUITE_data/server_root/htdocs/exec.shtml
@@ -0,0 +1,30 @@
+<HTML>
+<HEAD>
+<TITLE>/exec.shtml</TITLE>
+</HEAD>
+<BODY>
+<H1>/exec.shtml</H1>
+<PRE>
+<!--#exec cmd="ls"-->
+<HR>
+<!--#exec cmd="printenv"-->
+<HR>
+<!--#exec cmd="sunemaja"-->
+<HR>
+<!--#exec cgi="/cgi-bin/printenv.sh"-->
+</PRE>
+
+<P>[<A HREF="ssi.html">Back</A>]
+
+</BODY>
+</HTML>
+
+
+
+
+
+
+
+
+
+
diff --git a/lib/inets/test/httpd_SUITE_data/server_root/htdocs/flastmod.shtml b/lib/inets/test/httpd_SUITE_data/server_root/htdocs/flastmod.shtml
new file mode 100644
index 0000000000..d54c36fe50
--- /dev/null
+++ b/lib/inets/test/httpd_SUITE_data/server_root/htdocs/flastmod.shtml
@@ -0,0 +1,29 @@
+<HTML>
+<HEAD>
+<TITLE>/flastmod.shtml</TITLE>
+</HEAD>
+<BODY>
+<H1>/flastmod.shtml</H1>
+
+<P>Last modification of index.html: <!--#flastmod file="index.html"-->
+
+<P>Last modification of not_defined.html: <!--#flastmod file="not_defined.html"-->
+
+<P>Last modification of /misc/friedrich.html: <!--#flastmod virtual="/misc/friedrich.html"-->
+
+<P>Last modification of /misc/not_defined.html: <!--#flastmod virtual="/misc/not_defined.html"-->
+
+<P>[<A HREF="ssi.html">Back</A>]
+
+</BODY>
+</HTML>
+
+
+
+
+
+
+
+
+
+
diff --git a/lib/inets/test/httpd_SUITE_data/server_root/htdocs/fsize.shtml b/lib/inets/test/httpd_SUITE_data/server_root/htdocs/fsize.shtml
new file mode 100644
index 0000000000..570ee9cf6d
--- /dev/null
+++ b/lib/inets/test/httpd_SUITE_data/server_root/htdocs/fsize.shtml
@@ -0,0 +1,29 @@
+<HTML>
+<HEAD>
+<TITLE>/fsize.shtml</TITLE>
+</HEAD>
+<BODY>
+<H1>/fsize.shtml</H1>
+
+<P>Size of index.html: <!--#fsize file="index.html"-->
+
+<P>Size of not_defined.html: <!--#fsize file="not_defined.html"-->
+
+<P>Size of /misc/friedrich.html: <!--#fsize virtual="/misc/friedrich.html"-->
+
+<P>Size of /misc/not_defined.html: <!--#fsize virtual="/misc/not_defined.html"-->
+
+<P>[<A HREF="ssi.html">Back</A>]
+
+</BODY>
+</HTML>
+
+
+
+
+
+
+
+
+
+
diff --git a/lib/inets/test/httpd_SUITE_data/server_root/htdocs/include.shtml b/lib/inets/test/httpd_SUITE_data/server_root/htdocs/include.shtml
new file mode 100644
index 0000000000..529aad0437
--- /dev/null
+++ b/lib/inets/test/httpd_SUITE_data/server_root/htdocs/include.shtml
@@ -0,0 +1,33 @@
+<HTML>
+<HEAD>
+<TITLE>/include.shtml</TITLE>
+</HEAD>
+<BODY>
+<H1>/include.shtml</H1>
+
+<P>Include /misc/friedrich.html:
+<!--#include virtual="/misc/friedrich.html"-->
+
+<P>Include /misc/not_defined.html:
+<!--#include virtual="/misc/not_defined.html"-->
+
+<P>Include misc/friedrich.html:
+<!--#include file="misc/friedrich.html"-->
+
+<P>Include not_defined.html:
+<!--#include file="not_defined.html"-->
+
+<P>[<A HREF="ssi.html">Back</A>]
+
+</BODY>
+</HTML>
+
+
+
+
+
+
+
+
+
+
diff --git a/lib/inets/test/httpd_SUITE_data/server_root/htdocs/index.html b/lib/inets/test/httpd_SUITE_data/server_root/htdocs/index.html
new file mode 100644
index 0000000000..cfdc9f9ab7
--- /dev/null
+++ b/lib/inets/test/httpd_SUITE_data/server_root/htdocs/index.html
@@ -0,0 +1,25 @@
+<HTML>
+<HEAD>
+<TITLE>/index.html</TITLE>
+</HEAD>
+<BODY>
+<H1>/index.html</H1>
+
+<STRONG>Server-Side Include (SSI) commands:</STRONG><BR>
+<A HREF="config.shtml">config</A><BR>
+<A HREF="echo.shtml">echo</A><BR>
+<A HREF="exec.shtml">exec</A><BR>
+<A HREF="flastmod.shtml">flastmod</A><BR>
+<A HREF="fsize.shtml">fsize</A><BR>
+<A HREF="include.shtml">include</A><BR>
+
+<BR>
+<BR>
+
+<STRONG>ESI callback:</STRING><BR>
+<A HREF="cgi-bin/erl/httpd_example/get">cgi-bin/erl/httpd_example/get</A><BR>
+<A HREF="cgi-bin/erl/httpd_example/yahoo">cgi-bin/erl/httpd_example/yahoo</A><BR>
+<A HREF="cgi-bin/erl/httpd_example/test1">cgi-bin/erl/httpd_example/test1</A><BR>
+
+</BODY>
+</HTML>
diff --git a/lib/inets/test/httpd_SUITE_data/server_root/htdocs/last_modified.html b/lib/inets/test/httpd_SUITE_data/server_root/htdocs/last_modified.html
new file mode 100644
index 0000000000..65c1790813
--- /dev/null
+++ b/lib/inets/test/httpd_SUITE_data/server_root/htdocs/last_modified.html
@@ -0,0 +1,22 @@
+<HTML>
+<HEAD>
+<TITLE>/last_modified.html</TITLE>
+</HEAD>
+<BODY>
+<H1>/last_modified.html</H1>
+
+<P>This document is only used for test of illegal last-modified date.</P>
+
+
+</BODY>
+</HTML>
+
+
+
+
+
+
+
+
+
+
diff --git a/lib/inets/test/httpd_SUITE_data/server_root/htdocs/misc/friedrich.html b/lib/inets/test/httpd_SUITE_data/server_root/htdocs/misc/friedrich.html
new file mode 100644
index 0000000000..d7953d5df4
--- /dev/null
+++ b/lib/inets/test/httpd_SUITE_data/server_root/htdocs/misc/friedrich.html
@@ -0,0 +1,7 @@
+<P><CITE>
+Talking much about oneself can also be a means to conceal oneself.<BR>
+-- Friedrich Nietzsche
+</CITE>
+
+<P>Nested Include:
+<!--#include file="misc/oech.html"-->
diff --git a/lib/inets/test/httpd_SUITE_data/server_root/htdocs/misc/oech.html b/lib/inets/test/httpd_SUITE_data/server_root/htdocs/misc/oech.html
new file mode 100644
index 0000000000..506064bf04
--- /dev/null
+++ b/lib/inets/test/httpd_SUITE_data/server_root/htdocs/misc/oech.html
@@ -0,0 +1,4 @@
+<P><CITE>
+What excuses stand in your way? How can you eliminate them?<BR>
+-- Roger von Oech
+</CITE>
diff --git a/lib/inets/test/httpd_SUITE_data/server_root/htdocs/misc/welcome.html b/lib/inets/test/httpd_SUITE_data/server_root/htdocs/misc/welcome.html
new file mode 100644
index 0000000000..8c17451f91
--- /dev/null
+++ b/lib/inets/test/httpd_SUITE_data/server_root/htdocs/misc/welcome.html
@@ -0,0 +1 @@
+<HTML></HTML>
diff --git a/lib/inets/test/httpd_SUITE_data/server_root/htdocs/mnesia_open/dummy.html b/lib/inets/test/httpd_SUITE_data/server_root/htdocs/mnesia_open/dummy.html
new file mode 100644
index 0000000000..a6e8a35a04
--- /dev/null
+++ b/lib/inets/test/httpd_SUITE_data/server_root/htdocs/mnesia_open/dummy.html
@@ -0,0 +1,10 @@
+<HTML>
+<HEAD>
+<TITLE>/open/dummy.html (17-Apr-1997)</TITLE>
+<!-- Created by: Joakim Greben�, 17-Apr-1997 -->
+<!-- Changed by: Joakim Greben�, 17-Apr-1997 -->
+</HEAD>
+<BODY>
+<H1>/open/dummy.html</H1>
+</BODY>
+</HTML>
diff --git a/lib/inets/test/httpd_SUITE_data/server_root/htdocs/mnesia_secret/dummy.html b/lib/inets/test/httpd_SUITE_data/server_root/htdocs/mnesia_secret/dummy.html
new file mode 100644
index 0000000000..016b04e540
--- /dev/null
+++ b/lib/inets/test/httpd_SUITE_data/server_root/htdocs/mnesia_secret/dummy.html
@@ -0,0 +1,10 @@
+<HTML>
+<HEAD>
+<TITLE>/secret/dummy.html (17-Apr-1997)</TITLE>
+<!-- Created by: Joakim Greben�, 17-Apr-1997 -->
+<!-- Changed by: Joakim Greben�, 17-Apr-1997 -->
+</HEAD>
+<BODY>
+<H1>/secret/dummy.html</H1>
+</BODY>
+</HTML>
diff --git a/lib/inets/test/httpd_SUITE_data/server_root/htdocs/mnesia_secret/top_secret/index.html b/lib/inets/test/httpd_SUITE_data/server_root/htdocs/mnesia_secret/top_secret/index.html
new file mode 100644
index 0000000000..2d17e8b596
--- /dev/null
+++ b/lib/inets/test/httpd_SUITE_data/server_root/htdocs/mnesia_secret/top_secret/index.html
@@ -0,0 +1,9 @@
+<HTML>
+<HEAD>
+<TITLE>/mnesia_secret/top_secret/index.html (04-Feb-1998)</TITLE>
+<!-- Created by: Mattias Nilsson, 04-Feb-1998 -->
+</HEAD>
+<BODY>
+<H1>/mnesia_secret/top_secret/index.html</H1>
+</BODY>
+</HTML>
diff --git a/lib/inets/test/httpd_SUITE_data/server_root/htdocs/open/dummy.html b/lib/inets/test/httpd_SUITE_data/server_root/htdocs/open/dummy.html
new file mode 100644
index 0000000000..a6e8a35a04
--- /dev/null
+++ b/lib/inets/test/httpd_SUITE_data/server_root/htdocs/open/dummy.html
@@ -0,0 +1,10 @@
+<HTML>
+<HEAD>
+<TITLE>/open/dummy.html (17-Apr-1997)</TITLE>
+<!-- Created by: Joakim Greben�, 17-Apr-1997 -->
+<!-- Changed by: Joakim Greben�, 17-Apr-1997 -->
+</HEAD>
+<BODY>
+<H1>/open/dummy.html</H1>
+</BODY>
+</HTML>
diff --git a/lib/inets/test/httpd_SUITE_data/server_root/htdocs/secret/dummy.html b/lib/inets/test/httpd_SUITE_data/server_root/htdocs/secret/dummy.html
new file mode 100644
index 0000000000..016b04e540
--- /dev/null
+++ b/lib/inets/test/httpd_SUITE_data/server_root/htdocs/secret/dummy.html
@@ -0,0 +1,10 @@
+<HTML>
+<HEAD>
+<TITLE>/secret/dummy.html (17-Apr-1997)</TITLE>
+<!-- Created by: Joakim Greben�, 17-Apr-1997 -->
+<!-- Changed by: Joakim Greben�, 17-Apr-1997 -->
+</HEAD>
+<BODY>
+<H1>/secret/dummy.html</H1>
+</BODY>
+</HTML>
diff --git a/lib/inets/test/httpd_SUITE_data/server_root/htdocs/secret/top_secret/index.html b/lib/inets/test/httpd_SUITE_data/server_root/htdocs/secret/top_secret/index.html
new file mode 100644
index 0000000000..34db3d5d1a
--- /dev/null
+++ b/lib/inets/test/httpd_SUITE_data/server_root/htdocs/secret/top_secret/index.html
@@ -0,0 +1,9 @@
+<HTML>
+<HEAD>
+<TITLE>/secret/top_secret/index.html (04-Feb-1998)</TITLE>
+<!-- Created by: Mattias Nilsson, 04-Feb-1998 -->
+</HEAD>
+<BODY>
+<H1>/secret/top_secret/index.html</H1>
+</BODY>
+</HTML>
diff --git a/lib/inets/test/httpd_SUITE_data/server_root/icons/README b/lib/inets/test/httpd_SUITE_data/server_root/icons/README
new file mode 100644
index 0000000000..a1fc5a5a9c
--- /dev/null
+++ b/lib/inets/test/httpd_SUITE_data/server_root/icons/README
@@ -0,0 +1,161 @@
+Public Domain Icons
+
+ These icons were originally made for Mosaic for X and have been
+ included in the NCSA httpd and Apache server distributions in the
+ past. They are in the public domain and may be freely included in any
+ application. The originals were done by Kevin Hughes ([email protected]).
+
+ Many thanks to Andy Polyakov for tuning the icon colors and adding a
+ few new images. If you'd like to contribute additions or ideas to
+ this set, please let me know.
+
+ The distribution site for these icons is at:
+
+ http://www.eit.com/goodies/www.icons/
+
+ Kevin Hughes
+ September 11, 1995
+
+
+Suggested Uses
+
+The following are a few suggestions, to serve as a starting point for ideas.
+Please feel free to tweak and rename the icons as you like.
+
+ a.gif
+ This might be used to represent PostScript or text layout
+ languages.
+
+ alert.black.gif, alert.red.gif
+ These can be used to highlight any important items, such as a
+ README file in a directory.
+
+ back.gif, forward.gif
+ These can be used as links to go to previous and next areas.
+
+ ball.gray.gif, ball.red.gif
+ These might be used as bullets.
+
+ binary.gif
+ This can be used to represent binary files.
+
+ binhex.gif
+ This can represent BinHex-encoded data.
+
+ blank.gif
+ This can be used as a placeholder or a spacing element.
+
+ bomb.gif
+ This can be used to repreesnt core files.
+
+ box1.gif, box2.gif
+ These icons can be used to represent generic 3D applications and
+ related files.
+
+ broken.gif
+ This can represent corrupted data.
+
+ burst.gif
+ This can call attention to new and important items.
+
+ c.gif
+ This might represent C source code.
+
+ comp.blue.gif, comp.red.gif
+ These little computer icons can stand for telnet or FTP
+ sessions.
+
+ compressed.gif
+ This may represent compressed data.
+
+ continued.gif
+ This can be a link to a continued listing of a directory.
+
+ down.gif, up.gif, left.gif, right.gif
+ These can be used to scroll up, down, left and right in a
+ listing or may be used to denote items in an outline.
+
+ dvi.gif
+ This can represent DVI files.
+
+ f.gif
+ This might represent FORTRAN or Forth source code.
+
+ folder.gif, folder.open.gif, folder.sec.gif
+ The folder can represent directories. There is also a version
+ that can represent secure directories or directories that cannot
+ be viewed.
+
+ generic.gif, generic.sec.gif, generic.red.gif
+ These can represent generic files, secure files, and important
+ files, respectively.
+
+ hand.right.gif, hand.up.gif
+ These can point out important items (pun intended).
+
+ image1.gif, image2.gif, image3.gif
+ These can represent image formats of various types.
+
+ index.gif
+ This might represent a WAIS index or search facility.
+
+ layout.gif
+ This might represent files and formats that contain graphics as
+ well as text layout, such as HTML and PDF files.
+
+ link.gif
+ This might represent files that are symbolic links.
+
+ movie.gif
+ This can represent various movie formats.
+
+ p.gif
+ This may stand for Perl or Python source code.
+
+ pie0.gif ... pie8.gif
+ These icons can be used in applications where a list of
+ documents is returned from a search. The little pie chart images
+ can denote how relevant the documents may be to your search
+ query.
+
+ patch.gif
+ This may stand for patches and diff files.
+
+ portal.gif
+ This might be a link to an online service or a 3D world.
+
+ ps.gif, quill.gif
+ These may represent PostScript files.
+
+ screw1.gif, screw2.gif
+ These may represent CAD or engineering data and formats.
+
+ script.gif
+ This can represent any of various interpreted languages, such as
+ Perl, python, TCL, and shell scripts, as well as server
+ configuration files.
+
+ sound1.gif, sound2.gif
+ These can represent sound files.
+
+ sphere1.gif, sphere2.gif
+ These can represent 3D worlds or rendering applications and
+ formats.
+
+ tex.gif
+ This can represent TeX files.
+
+ text.gif
+ This can represent generic (plain) text files.
+
+ transfer.gif
+ This can represent FTP transfers or uploads/downloads.
+
+ unknown.gif
+ This may represent a file of an unknown type.
+
+ uuencoded.gif
+ This can stand for uuencoded data.
+
+ world1.gif, world2.gif
+ These can represent 3D worlds or other 3D formats.
diff --git a/lib/inets/test/httpd_SUITE_data/server_root/icons/a.gif b/lib/inets/test/httpd_SUITE_data/server_root/icons/a.gif
new file mode 100644
index 0000000000..bb23d971f4
--- /dev/null
+++ b/lib/inets/test/httpd_SUITE_data/server_root/icons/a.gif
Binary files differ
diff --git a/lib/inets/test/httpd_SUITE_data/server_root/icons/alert.black.gif b/lib/inets/test/httpd_SUITE_data/server_root/icons/alert.black.gif
new file mode 100644
index 0000000000..eaecd2172a
--- /dev/null
+++ b/lib/inets/test/httpd_SUITE_data/server_root/icons/alert.black.gif
Binary files differ
diff --git a/lib/inets/test/httpd_SUITE_data/server_root/icons/alert.red.gif b/lib/inets/test/httpd_SUITE_data/server_root/icons/alert.red.gif
new file mode 100644
index 0000000000..a423894043
--- /dev/null
+++ b/lib/inets/test/httpd_SUITE_data/server_root/icons/alert.red.gif
Binary files differ
diff --git a/lib/inets/test/httpd_SUITE_data/server_root/icons/apache_pb.gif b/lib/inets/test/httpd_SUITE_data/server_root/icons/apache_pb.gif
new file mode 100644
index 0000000000..3a1c139fc4
--- /dev/null
+++ b/lib/inets/test/httpd_SUITE_data/server_root/icons/apache_pb.gif
Binary files differ
diff --git a/lib/inets/test/httpd_SUITE_data/server_root/icons/back.gif b/lib/inets/test/httpd_SUITE_data/server_root/icons/back.gif
new file mode 100644
index 0000000000..a694ae1ec3
--- /dev/null
+++ b/lib/inets/test/httpd_SUITE_data/server_root/icons/back.gif
Binary files differ
diff --git a/lib/inets/test/httpd_SUITE_data/server_root/icons/ball.gray.gif b/lib/inets/test/httpd_SUITE_data/server_root/icons/ball.gray.gif
new file mode 100644
index 0000000000..eb84268c4c
--- /dev/null
+++ b/lib/inets/test/httpd_SUITE_data/server_root/icons/ball.gray.gif
Binary files differ
diff --git a/lib/inets/test/httpd_SUITE_data/server_root/icons/ball.red.gif b/lib/inets/test/httpd_SUITE_data/server_root/icons/ball.red.gif
new file mode 100644
index 0000000000..a8425cb574
--- /dev/null
+++ b/lib/inets/test/httpd_SUITE_data/server_root/icons/ball.red.gif
Binary files differ
diff --git a/lib/inets/test/httpd_SUITE_data/server_root/icons/binary.gif b/lib/inets/test/httpd_SUITE_data/server_root/icons/binary.gif
new file mode 100644
index 0000000000..9a15cbae04
--- /dev/null
+++ b/lib/inets/test/httpd_SUITE_data/server_root/icons/binary.gif
Binary files differ
diff --git a/lib/inets/test/httpd_SUITE_data/server_root/icons/binhex.gif b/lib/inets/test/httpd_SUITE_data/server_root/icons/binhex.gif
new file mode 100644
index 0000000000..62d0363108
--- /dev/null
+++ b/lib/inets/test/httpd_SUITE_data/server_root/icons/binhex.gif
Binary files differ
diff --git a/lib/inets/test/httpd_SUITE_data/server_root/icons/blank.gif b/lib/inets/test/httpd_SUITE_data/server_root/icons/blank.gif
new file mode 100644
index 0000000000..0ccf01e198
--- /dev/null
+++ b/lib/inets/test/httpd_SUITE_data/server_root/icons/blank.gif
Binary files differ
diff --git a/lib/inets/test/httpd_SUITE_data/server_root/icons/bomb.gif b/lib/inets/test/httpd_SUITE_data/server_root/icons/bomb.gif
new file mode 100644
index 0000000000..270fdb1c06
--- /dev/null
+++ b/lib/inets/test/httpd_SUITE_data/server_root/icons/bomb.gif
Binary files differ
diff --git a/lib/inets/test/httpd_SUITE_data/server_root/icons/box1.gif b/lib/inets/test/httpd_SUITE_data/server_root/icons/box1.gif
new file mode 100644
index 0000000000..65dcd002ea
--- /dev/null
+++ b/lib/inets/test/httpd_SUITE_data/server_root/icons/box1.gif
Binary files differ
diff --git a/lib/inets/test/httpd_SUITE_data/server_root/icons/box2.gif b/lib/inets/test/httpd_SUITE_data/server_root/icons/box2.gif
new file mode 100644
index 0000000000..c43bc4faec
--- /dev/null
+++ b/lib/inets/test/httpd_SUITE_data/server_root/icons/box2.gif
Binary files differ
diff --git a/lib/inets/test/httpd_SUITE_data/server_root/icons/broken.gif b/lib/inets/test/httpd_SUITE_data/server_root/icons/broken.gif
new file mode 100644
index 0000000000..9f8cbe9f76
--- /dev/null
+++ b/lib/inets/test/httpd_SUITE_data/server_root/icons/broken.gif
Binary files differ
diff --git a/lib/inets/test/httpd_SUITE_data/server_root/icons/burst.gif b/lib/inets/test/httpd_SUITE_data/server_root/icons/burst.gif
new file mode 100644
index 0000000000..fbdcf575f7
--- /dev/null
+++ b/lib/inets/test/httpd_SUITE_data/server_root/icons/burst.gif
Binary files differ
diff --git a/lib/inets/test/httpd_SUITE_data/server_root/icons/button1.gif b/lib/inets/test/httpd_SUITE_data/server_root/icons/button1.gif
new file mode 100644
index 0000000000..eb97cb7333
--- /dev/null
+++ b/lib/inets/test/httpd_SUITE_data/server_root/icons/button1.gif
Binary files differ
diff --git a/lib/inets/test/httpd_SUITE_data/server_root/icons/button10.gif b/lib/inets/test/httpd_SUITE_data/server_root/icons/button10.gif
new file mode 100644
index 0000000000..fe0c97998c
--- /dev/null
+++ b/lib/inets/test/httpd_SUITE_data/server_root/icons/button10.gif
Binary files differ
diff --git a/lib/inets/test/httpd_SUITE_data/server_root/icons/button2.gif b/lib/inets/test/httpd_SUITE_data/server_root/icons/button2.gif
new file mode 100644
index 0000000000..7698455bf9
--- /dev/null
+++ b/lib/inets/test/httpd_SUITE_data/server_root/icons/button2.gif
Binary files differ
diff --git a/lib/inets/test/httpd_SUITE_data/server_root/icons/button3.gif b/lib/inets/test/httpd_SUITE_data/server_root/icons/button3.gif
new file mode 100644
index 0000000000..a8b8319232
--- /dev/null
+++ b/lib/inets/test/httpd_SUITE_data/server_root/icons/button3.gif
Binary files differ
diff --git a/lib/inets/test/httpd_SUITE_data/server_root/icons/button4.gif b/lib/inets/test/httpd_SUITE_data/server_root/icons/button4.gif
new file mode 100644
index 0000000000..0fd15a0d7f
--- /dev/null
+++ b/lib/inets/test/httpd_SUITE_data/server_root/icons/button4.gif
Binary files differ
diff --git a/lib/inets/test/httpd_SUITE_data/server_root/icons/button5.gif b/lib/inets/test/httpd_SUITE_data/server_root/icons/button5.gif
new file mode 100644
index 0000000000..64241e5c5d
--- /dev/null
+++ b/lib/inets/test/httpd_SUITE_data/server_root/icons/button5.gif
Binary files differ
diff --git a/lib/inets/test/httpd_SUITE_data/server_root/icons/button6.gif b/lib/inets/test/httpd_SUITE_data/server_root/icons/button6.gif
new file mode 100644
index 0000000000..867cfd1212
--- /dev/null
+++ b/lib/inets/test/httpd_SUITE_data/server_root/icons/button6.gif
Binary files differ
diff --git a/lib/inets/test/httpd_SUITE_data/server_root/icons/button7.gif b/lib/inets/test/httpd_SUITE_data/server_root/icons/button7.gif
new file mode 100644
index 0000000000..b3f5fb248f
--- /dev/null
+++ b/lib/inets/test/httpd_SUITE_data/server_root/icons/button7.gif
Binary files differ
diff --git a/lib/inets/test/httpd_SUITE_data/server_root/icons/button8.gif b/lib/inets/test/httpd_SUITE_data/server_root/icons/button8.gif
new file mode 100644
index 0000000000..7a308be8f6
--- /dev/null
+++ b/lib/inets/test/httpd_SUITE_data/server_root/icons/button8.gif
Binary files differ
diff --git a/lib/inets/test/httpd_SUITE_data/server_root/icons/button9.gif b/lib/inets/test/httpd_SUITE_data/server_root/icons/button9.gif
new file mode 100644
index 0000000000..9acba576c0
--- /dev/null
+++ b/lib/inets/test/httpd_SUITE_data/server_root/icons/button9.gif
Binary files differ
diff --git a/lib/inets/test/httpd_SUITE_data/server_root/icons/buttonl.gif b/lib/inets/test/httpd_SUITE_data/server_root/icons/buttonl.gif
new file mode 100644
index 0000000000..3883088e7a
--- /dev/null
+++ b/lib/inets/test/httpd_SUITE_data/server_root/icons/buttonl.gif
Binary files differ
diff --git a/lib/inets/test/httpd_SUITE_data/server_root/icons/buttonr.gif b/lib/inets/test/httpd_SUITE_data/server_root/icons/buttonr.gif
new file mode 100644
index 0000000000..c4dc3887db
--- /dev/null
+++ b/lib/inets/test/httpd_SUITE_data/server_root/icons/buttonr.gif
Binary files differ
diff --git a/lib/inets/test/httpd_SUITE_data/server_root/icons/c.gif b/lib/inets/test/httpd_SUITE_data/server_root/icons/c.gif
new file mode 100644
index 0000000000..7555b6c164
--- /dev/null
+++ b/lib/inets/test/httpd_SUITE_data/server_root/icons/c.gif
Binary files differ
diff --git a/lib/inets/test/httpd_SUITE_data/server_root/icons/comp.blue.gif b/lib/inets/test/httpd_SUITE_data/server_root/icons/comp.blue.gif
new file mode 100644
index 0000000000..f8d76a8c23
--- /dev/null
+++ b/lib/inets/test/httpd_SUITE_data/server_root/icons/comp.blue.gif
Binary files differ
diff --git a/lib/inets/test/httpd_SUITE_data/server_root/icons/comp.gray.gif b/lib/inets/test/httpd_SUITE_data/server_root/icons/comp.gray.gif
new file mode 100644
index 0000000000..7664cd0364
--- /dev/null
+++ b/lib/inets/test/httpd_SUITE_data/server_root/icons/comp.gray.gif
Binary files differ
diff --git a/lib/inets/test/httpd_SUITE_data/server_root/icons/compressed.gif b/lib/inets/test/httpd_SUITE_data/server_root/icons/compressed.gif
new file mode 100644
index 0000000000..39e732739f
--- /dev/null
+++ b/lib/inets/test/httpd_SUITE_data/server_root/icons/compressed.gif
Binary files differ
diff --git a/lib/inets/test/httpd_SUITE_data/server_root/icons/continued.gif b/lib/inets/test/httpd_SUITE_data/server_root/icons/continued.gif
new file mode 100644
index 0000000000..b0ffb7e0cc
--- /dev/null
+++ b/lib/inets/test/httpd_SUITE_data/server_root/icons/continued.gif
Binary files differ
diff --git a/lib/inets/test/httpd_SUITE_data/server_root/icons/dir.gif b/lib/inets/test/httpd_SUITE_data/server_root/icons/dir.gif
new file mode 100644
index 0000000000..48264601ae
--- /dev/null
+++ b/lib/inets/test/httpd_SUITE_data/server_root/icons/dir.gif
Binary files differ
diff --git a/lib/inets/test/httpd_SUITE_data/server_root/icons/down.gif b/lib/inets/test/httpd_SUITE_data/server_root/icons/down.gif
new file mode 100644
index 0000000000..a354c871cd
--- /dev/null
+++ b/lib/inets/test/httpd_SUITE_data/server_root/icons/down.gif
Binary files differ
diff --git a/lib/inets/test/httpd_SUITE_data/server_root/icons/dvi.gif b/lib/inets/test/httpd_SUITE_data/server_root/icons/dvi.gif
new file mode 100644
index 0000000000..791be33105
--- /dev/null
+++ b/lib/inets/test/httpd_SUITE_data/server_root/icons/dvi.gif
Binary files differ
diff --git a/lib/inets/test/httpd_SUITE_data/server_root/icons/f.gif b/lib/inets/test/httpd_SUITE_data/server_root/icons/f.gif
new file mode 100644
index 0000000000..fbe353c282
--- /dev/null
+++ b/lib/inets/test/httpd_SUITE_data/server_root/icons/f.gif
Binary files differ
diff --git a/lib/inets/test/httpd_SUITE_data/server_root/icons/folder.gif b/lib/inets/test/httpd_SUITE_data/server_root/icons/folder.gif
new file mode 100644
index 0000000000..48264601ae
--- /dev/null
+++ b/lib/inets/test/httpd_SUITE_data/server_root/icons/folder.gif
Binary files differ
diff --git a/lib/inets/test/httpd_SUITE_data/server_root/icons/folder.open.gif b/lib/inets/test/httpd_SUITE_data/server_root/icons/folder.open.gif
new file mode 100644
index 0000000000..30979cb528
--- /dev/null
+++ b/lib/inets/test/httpd_SUITE_data/server_root/icons/folder.open.gif
Binary files differ
diff --git a/lib/inets/test/httpd_SUITE_data/server_root/icons/folder.sec.gif b/lib/inets/test/httpd_SUITE_data/server_root/icons/folder.sec.gif
new file mode 100644
index 0000000000..75332d9e59
--- /dev/null
+++ b/lib/inets/test/httpd_SUITE_data/server_root/icons/folder.sec.gif
Binary files differ
diff --git a/lib/inets/test/httpd_SUITE_data/server_root/icons/forward.gif b/lib/inets/test/httpd_SUITE_data/server_root/icons/forward.gif
new file mode 100644
index 0000000000..b2959b4c85
--- /dev/null
+++ b/lib/inets/test/httpd_SUITE_data/server_root/icons/forward.gif
Binary files differ
diff --git a/lib/inets/test/httpd_SUITE_data/server_root/icons/generic.gif b/lib/inets/test/httpd_SUITE_data/server_root/icons/generic.gif
new file mode 100644
index 0000000000..de60b2940f
--- /dev/null
+++ b/lib/inets/test/httpd_SUITE_data/server_root/icons/generic.gif
Binary files differ
diff --git a/lib/inets/test/httpd_SUITE_data/server_root/icons/generic.red.gif b/lib/inets/test/httpd_SUITE_data/server_root/icons/generic.red.gif
new file mode 100644
index 0000000000..94743981d9
--- /dev/null
+++ b/lib/inets/test/httpd_SUITE_data/server_root/icons/generic.red.gif
Binary files differ
diff --git a/lib/inets/test/httpd_SUITE_data/server_root/icons/generic.sec.gif b/lib/inets/test/httpd_SUITE_data/server_root/icons/generic.sec.gif
new file mode 100644
index 0000000000..88d5240c3c
--- /dev/null
+++ b/lib/inets/test/httpd_SUITE_data/server_root/icons/generic.sec.gif
Binary files differ
diff --git a/lib/inets/test/httpd_SUITE_data/server_root/icons/hand.right.gif b/lib/inets/test/httpd_SUITE_data/server_root/icons/hand.right.gif
new file mode 100644
index 0000000000..5cdbc7206d
--- /dev/null
+++ b/lib/inets/test/httpd_SUITE_data/server_root/icons/hand.right.gif
Binary files differ
diff --git a/lib/inets/test/httpd_SUITE_data/server_root/icons/hand.up.gif b/lib/inets/test/httpd_SUITE_data/server_root/icons/hand.up.gif
new file mode 100644
index 0000000000..85a5d68317
--- /dev/null
+++ b/lib/inets/test/httpd_SUITE_data/server_root/icons/hand.up.gif
Binary files differ
diff --git a/lib/inets/test/httpd_SUITE_data/server_root/icons/htdig.gif b/lib/inets/test/httpd_SUITE_data/server_root/icons/htdig.gif
new file mode 100644
index 0000000000..35443fb63a
--- /dev/null
+++ b/lib/inets/test/httpd_SUITE_data/server_root/icons/htdig.gif
Binary files differ
diff --git a/lib/inets/test/httpd_SUITE_data/server_root/icons/icon.sheet.gif b/lib/inets/test/httpd_SUITE_data/server_root/icons/icon.sheet.gif
new file mode 100644
index 0000000000..ad1686e448
--- /dev/null
+++ b/lib/inets/test/httpd_SUITE_data/server_root/icons/icon.sheet.gif
Binary files differ
diff --git a/lib/inets/test/httpd_SUITE_data/server_root/icons/image1.gif b/lib/inets/test/httpd_SUITE_data/server_root/icons/image1.gif
new file mode 100644
index 0000000000..01e442bfa9
--- /dev/null
+++ b/lib/inets/test/httpd_SUITE_data/server_root/icons/image1.gif
Binary files differ
diff --git a/lib/inets/test/httpd_SUITE_data/server_root/icons/image2.gif b/lib/inets/test/httpd_SUITE_data/server_root/icons/image2.gif
new file mode 100644
index 0000000000..751faeea36
--- /dev/null
+++ b/lib/inets/test/httpd_SUITE_data/server_root/icons/image2.gif
Binary files differ
diff --git a/lib/inets/test/httpd_SUITE_data/server_root/icons/image3.gif b/lib/inets/test/httpd_SUITE_data/server_root/icons/image3.gif
new file mode 100644
index 0000000000..4f30484ff6
--- /dev/null
+++ b/lib/inets/test/httpd_SUITE_data/server_root/icons/image3.gif
Binary files differ
diff --git a/lib/inets/test/httpd_SUITE_data/server_root/icons/index.gif b/lib/inets/test/httpd_SUITE_data/server_root/icons/index.gif
new file mode 100644
index 0000000000..162478fb3a
--- /dev/null
+++ b/lib/inets/test/httpd_SUITE_data/server_root/icons/index.gif
Binary files differ
diff --git a/lib/inets/test/httpd_SUITE_data/server_root/icons/layout.gif b/lib/inets/test/httpd_SUITE_data/server_root/icons/layout.gif
new file mode 100644
index 0000000000..c96338a152
--- /dev/null
+++ b/lib/inets/test/httpd_SUITE_data/server_root/icons/layout.gif
Binary files differ
diff --git a/lib/inets/test/httpd_SUITE_data/server_root/icons/left.gif b/lib/inets/test/httpd_SUITE_data/server_root/icons/left.gif
new file mode 100644
index 0000000000..279e6710d4
--- /dev/null
+++ b/lib/inets/test/httpd_SUITE_data/server_root/icons/left.gif
Binary files differ
diff --git a/lib/inets/test/httpd_SUITE_data/server_root/icons/link.gif b/lib/inets/test/httpd_SUITE_data/server_root/icons/link.gif
new file mode 100644
index 0000000000..c5b6889a76
--- /dev/null
+++ b/lib/inets/test/httpd_SUITE_data/server_root/icons/link.gif
Binary files differ
diff --git a/lib/inets/test/httpd_SUITE_data/server_root/icons/movie.gif b/lib/inets/test/httpd_SUITE_data/server_root/icons/movie.gif
new file mode 100644
index 0000000000..0035183774
--- /dev/null
+++ b/lib/inets/test/httpd_SUITE_data/server_root/icons/movie.gif
Binary files differ
diff --git a/lib/inets/test/httpd_SUITE_data/server_root/icons/p.gif b/lib/inets/test/httpd_SUITE_data/server_root/icons/p.gif
new file mode 100644
index 0000000000..7b917b4e91
--- /dev/null
+++ b/lib/inets/test/httpd_SUITE_data/server_root/icons/p.gif
Binary files differ
diff --git a/lib/inets/test/httpd_SUITE_data/server_root/icons/patch.gif b/lib/inets/test/httpd_SUITE_data/server_root/icons/patch.gif
new file mode 100644
index 0000000000..39bc90e795
--- /dev/null
+++ b/lib/inets/test/httpd_SUITE_data/server_root/icons/patch.gif
Binary files differ
diff --git a/lib/inets/test/httpd_SUITE_data/server_root/icons/pdf.gif b/lib/inets/test/httpd_SUITE_data/server_root/icons/pdf.gif
new file mode 100644
index 0000000000..c88fd777c4
--- /dev/null
+++ b/lib/inets/test/httpd_SUITE_data/server_root/icons/pdf.gif
Binary files differ
diff --git a/lib/inets/test/httpd_SUITE_data/server_root/icons/pie0.gif b/lib/inets/test/httpd_SUITE_data/server_root/icons/pie0.gif
new file mode 100644
index 0000000000..6f7a0ae7a7
--- /dev/null
+++ b/lib/inets/test/httpd_SUITE_data/server_root/icons/pie0.gif
Binary files differ
diff --git a/lib/inets/test/httpd_SUITE_data/server_root/icons/pie1.gif b/lib/inets/test/httpd_SUITE_data/server_root/icons/pie1.gif
new file mode 100644
index 0000000000..03aa6be71e
--- /dev/null
+++ b/lib/inets/test/httpd_SUITE_data/server_root/icons/pie1.gif
Binary files differ
diff --git a/lib/inets/test/httpd_SUITE_data/server_root/icons/pie2.gif b/lib/inets/test/httpd_SUITE_data/server_root/icons/pie2.gif
new file mode 100644
index 0000000000..b04c5e0908
--- /dev/null
+++ b/lib/inets/test/httpd_SUITE_data/server_root/icons/pie2.gif
Binary files differ
diff --git a/lib/inets/test/httpd_SUITE_data/server_root/icons/pie3.gif b/lib/inets/test/httpd_SUITE_data/server_root/icons/pie3.gif
new file mode 100644
index 0000000000..4db9d023ed
--- /dev/null
+++ b/lib/inets/test/httpd_SUITE_data/server_root/icons/pie3.gif
Binary files differ
diff --git a/lib/inets/test/httpd_SUITE_data/server_root/icons/pie4.gif b/lib/inets/test/httpd_SUITE_data/server_root/icons/pie4.gif
new file mode 100644
index 0000000000..93471fdd88
--- /dev/null
+++ b/lib/inets/test/httpd_SUITE_data/server_root/icons/pie4.gif
Binary files differ
diff --git a/lib/inets/test/httpd_SUITE_data/server_root/icons/pie5.gif b/lib/inets/test/httpd_SUITE_data/server_root/icons/pie5.gif
new file mode 100644
index 0000000000..57aee93f07
--- /dev/null
+++ b/lib/inets/test/httpd_SUITE_data/server_root/icons/pie5.gif
Binary files differ
diff --git a/lib/inets/test/httpd_SUITE_data/server_root/icons/pie6.gif b/lib/inets/test/httpd_SUITE_data/server_root/icons/pie6.gif
new file mode 100644
index 0000000000..0dc327b569
--- /dev/null
+++ b/lib/inets/test/httpd_SUITE_data/server_root/icons/pie6.gif
Binary files differ
diff --git a/lib/inets/test/httpd_SUITE_data/server_root/icons/pie7.gif b/lib/inets/test/httpd_SUITE_data/server_root/icons/pie7.gif
new file mode 100644
index 0000000000..8661337f06
--- /dev/null
+++ b/lib/inets/test/httpd_SUITE_data/server_root/icons/pie7.gif
Binary files differ
diff --git a/lib/inets/test/httpd_SUITE_data/server_root/icons/pie8.gif b/lib/inets/test/httpd_SUITE_data/server_root/icons/pie8.gif
new file mode 100644
index 0000000000..59ddb34ce0
--- /dev/null
+++ b/lib/inets/test/httpd_SUITE_data/server_root/icons/pie8.gif
Binary files differ
diff --git a/lib/inets/test/httpd_SUITE_data/server_root/icons/portal.gif b/lib/inets/test/httpd_SUITE_data/server_root/icons/portal.gif
new file mode 100644
index 0000000000..0e6e506e00
--- /dev/null
+++ b/lib/inets/test/httpd_SUITE_data/server_root/icons/portal.gif
Binary files differ
diff --git a/lib/inets/test/httpd_SUITE_data/server_root/icons/poweredby.gif b/lib/inets/test/httpd_SUITE_data/server_root/icons/poweredby.gif
new file mode 100644
index 0000000000..d324ab80ea
--- /dev/null
+++ b/lib/inets/test/httpd_SUITE_data/server_root/icons/poweredby.gif
Binary files differ
diff --git a/lib/inets/test/httpd_SUITE_data/server_root/icons/ps.gif b/lib/inets/test/httpd_SUITE_data/server_root/icons/ps.gif
new file mode 100644
index 0000000000..0f565bc1db
--- /dev/null
+++ b/lib/inets/test/httpd_SUITE_data/server_root/icons/ps.gif
Binary files differ
diff --git a/lib/inets/test/httpd_SUITE_data/server_root/icons/quill.gif b/lib/inets/test/httpd_SUITE_data/server_root/icons/quill.gif
new file mode 100644
index 0000000000..818a5cdc7e
--- /dev/null
+++ b/lib/inets/test/httpd_SUITE_data/server_root/icons/quill.gif
Binary files differ
diff --git a/lib/inets/test/httpd_SUITE_data/server_root/icons/right.gif b/lib/inets/test/httpd_SUITE_data/server_root/icons/right.gif
new file mode 100644
index 0000000000..b256e5f75f
--- /dev/null
+++ b/lib/inets/test/httpd_SUITE_data/server_root/icons/right.gif
Binary files differ
diff --git a/lib/inets/test/httpd_SUITE_data/server_root/icons/screw1.gif b/lib/inets/test/httpd_SUITE_data/server_root/icons/screw1.gif
new file mode 100644
index 0000000000..af6ba2b097
--- /dev/null
+++ b/lib/inets/test/httpd_SUITE_data/server_root/icons/screw1.gif
Binary files differ
diff --git a/lib/inets/test/httpd_SUITE_data/server_root/icons/screw2.gif b/lib/inets/test/httpd_SUITE_data/server_root/icons/screw2.gif
new file mode 100644
index 0000000000..06dccb3e44
--- /dev/null
+++ b/lib/inets/test/httpd_SUITE_data/server_root/icons/screw2.gif
Binary files differ
diff --git a/lib/inets/test/httpd_SUITE_data/server_root/icons/script.gif b/lib/inets/test/httpd_SUITE_data/server_root/icons/script.gif
new file mode 100644
index 0000000000..d8a853bc58
--- /dev/null
+++ b/lib/inets/test/httpd_SUITE_data/server_root/icons/script.gif
Binary files differ
diff --git a/lib/inets/test/httpd_SUITE_data/server_root/icons/sound1.gif b/lib/inets/test/httpd_SUITE_data/server_root/icons/sound1.gif
new file mode 100644
index 0000000000..8efb49f55d
--- /dev/null
+++ b/lib/inets/test/httpd_SUITE_data/server_root/icons/sound1.gif
Binary files differ
diff --git a/lib/inets/test/httpd_SUITE_data/server_root/icons/sound2.gif b/lib/inets/test/httpd_SUITE_data/server_root/icons/sound2.gif
new file mode 100644
index 0000000000..48e6a7fb2f
--- /dev/null
+++ b/lib/inets/test/httpd_SUITE_data/server_root/icons/sound2.gif
Binary files differ
diff --git a/lib/inets/test/httpd_SUITE_data/server_root/icons/sphere1.gif b/lib/inets/test/httpd_SUITE_data/server_root/icons/sphere1.gif
new file mode 100644
index 0000000000..7067070da2
--- /dev/null
+++ b/lib/inets/test/httpd_SUITE_data/server_root/icons/sphere1.gif
Binary files differ
diff --git a/lib/inets/test/httpd_SUITE_data/server_root/icons/sphere2.gif b/lib/inets/test/httpd_SUITE_data/server_root/icons/sphere2.gif
new file mode 100644
index 0000000000..a9e462a377
--- /dev/null
+++ b/lib/inets/test/httpd_SUITE_data/server_root/icons/sphere2.gif
Binary files differ
diff --git a/lib/inets/test/httpd_SUITE_data/server_root/icons/star.gif b/lib/inets/test/httpd_SUITE_data/server_root/icons/star.gif
new file mode 100644
index 0000000000..4cfe0a5e0f
--- /dev/null
+++ b/lib/inets/test/httpd_SUITE_data/server_root/icons/star.gif
Binary files differ
diff --git a/lib/inets/test/httpd_SUITE_data/server_root/icons/star_blank.gif b/lib/inets/test/httpd_SUITE_data/server_root/icons/star_blank.gif
new file mode 100644
index 0000000000..a0c83cb85b
--- /dev/null
+++ b/lib/inets/test/httpd_SUITE_data/server_root/icons/star_blank.gif
Binary files differ
diff --git a/lib/inets/test/httpd_SUITE_data/server_root/icons/tar.gif b/lib/inets/test/httpd_SUITE_data/server_root/icons/tar.gif
new file mode 100644
index 0000000000..617e779efa
--- /dev/null
+++ b/lib/inets/test/httpd_SUITE_data/server_root/icons/tar.gif
Binary files differ
diff --git a/lib/inets/test/httpd_SUITE_data/server_root/icons/tex.gif b/lib/inets/test/httpd_SUITE_data/server_root/icons/tex.gif
new file mode 100644
index 0000000000..45e43233b8
--- /dev/null
+++ b/lib/inets/test/httpd_SUITE_data/server_root/icons/tex.gif
Binary files differ
diff --git a/lib/inets/test/httpd_SUITE_data/server_root/icons/text.gif b/lib/inets/test/httpd_SUITE_data/server_root/icons/text.gif
new file mode 100644
index 0000000000..4c623909fb
--- /dev/null
+++ b/lib/inets/test/httpd_SUITE_data/server_root/icons/text.gif
Binary files differ
diff --git a/lib/inets/test/httpd_SUITE_data/server_root/icons/transfer.gif b/lib/inets/test/httpd_SUITE_data/server_root/icons/transfer.gif
new file mode 100644
index 0000000000..33697dbb66
--- /dev/null
+++ b/lib/inets/test/httpd_SUITE_data/server_root/icons/transfer.gif
Binary files differ
diff --git a/lib/inets/test/httpd_SUITE_data/server_root/icons/unknown.gif b/lib/inets/test/httpd_SUITE_data/server_root/icons/unknown.gif
new file mode 100644
index 0000000000..32b1ea23fb
--- /dev/null
+++ b/lib/inets/test/httpd_SUITE_data/server_root/icons/unknown.gif
Binary files differ
diff --git a/lib/inets/test/httpd_SUITE_data/server_root/icons/up.gif b/lib/inets/test/httpd_SUITE_data/server_root/icons/up.gif
new file mode 100644
index 0000000000..6d6d6d1ebf
--- /dev/null
+++ b/lib/inets/test/httpd_SUITE_data/server_root/icons/up.gif
Binary files differ
diff --git a/lib/inets/test/httpd_SUITE_data/server_root/icons/uu.gif b/lib/inets/test/httpd_SUITE_data/server_root/icons/uu.gif
new file mode 100644
index 0000000000..4387d529f6
--- /dev/null
+++ b/lib/inets/test/httpd_SUITE_data/server_root/icons/uu.gif
Binary files differ
diff --git a/lib/inets/test/httpd_SUITE_data/server_root/icons/uuencoded.gif b/lib/inets/test/httpd_SUITE_data/server_root/icons/uuencoded.gif
new file mode 100644
index 0000000000..4387d529f6
--- /dev/null
+++ b/lib/inets/test/httpd_SUITE_data/server_root/icons/uuencoded.gif
Binary files differ
diff --git a/lib/inets/test/httpd_SUITE_data/server_root/icons/world1.gif b/lib/inets/test/httpd_SUITE_data/server_root/icons/world1.gif
new file mode 100644
index 0000000000..05b4ec2058
--- /dev/null
+++ b/lib/inets/test/httpd_SUITE_data/server_root/icons/world1.gif
Binary files differ
diff --git a/lib/inets/test/httpd_SUITE_data/server_root/icons/world2.gif b/lib/inets/test/httpd_SUITE_data/server_root/icons/world2.gif
new file mode 100644
index 0000000000..e3203f7a88
--- /dev/null
+++ b/lib/inets/test/httpd_SUITE_data/server_root/icons/world2.gif
Binary files differ
diff --git a/lib/inets/test/httpd_SUITE_data/server_root/logs/Dummy_File_Needed_By_WinZip b/lib/inets/test/httpd_SUITE_data/server_root/logs/Dummy_File_Needed_By_WinZip
new file mode 100644
index 0000000000..8d1c8b69c3
--- /dev/null
+++ b/lib/inets/test/httpd_SUITE_data/server_root/logs/Dummy_File_Needed_By_WinZip
@@ -0,0 +1 @@
+
diff --git a/lib/inets/test/httpd_SUITE_data/server_root/ssl/ssl_client.pem b/lib/inets/test/httpd_SUITE_data/server_root/ssl/ssl_client.pem
new file mode 100644
index 0000000000..8221139eb4
--- /dev/null
+++ b/lib/inets/test/httpd_SUITE_data/server_root/ssl/ssl_client.pem
@@ -0,0 +1,22 @@
+-----BEGIN RSA PRIVATE KEY-----
+MIIBPAIBAAJBAL6Ym/bgUvhhnPkw08sggGg8Tnp759ThGMEjkmDzhuJ3w3PfnF65
+mgHcgunku4G6LxAQfEUougJWf9Phmjj3oRUCAwEAAQJBAKMjvVvzZxFzfAlP4flc
+OI0AEayFokp04dtvtzuFN09f+aBo2dP18xHmKLCZvxrBOaRAROoQYscALiIVpN07
+GAECIQDfi+sSfAFaDlT3vzpL3xE5UEH6IzY8jWpaZfM1QaToJQIhANpEF50H4wGO
+8Sbh7dUutNd+s+NYUjsMySW2DjLKMsoxAiEAzzb2ftrdsempD0F+O0gZwiPIFKLB
+Kp33YLYyHEKuJtUCIDGi+pvDh2R7VWw6RRQOIyI+tjolg83aAoSI+oGiahqBAiEA
+xzmNNajwoaokvWvlaz0na8rhxu45grOvDrflBT9XvSQ=
+-----END RSA PRIVATE KEY-----
+-----BEGIN CERTIFICATE-----
+MIICDDCCAbYCAQAwDQYJKoZIhvcNAQEEBQAwgZAxCzAJBgNVBAYTAlNFMRIwEAYD
+VQQIEwlTdG9ja2hvbG0xDzANBgNVBAcTBkFsdnNqbzEMMAoGA1UEChMDRVRYMQ4w
+DAYDVQQLEwVETi9TUDEXMBUGA1UEAxMOSm9ha2ltIEdyZWJlbm8xJTAjBgkqhkiG
+9w0BCQEWFmpvY2tlQGVyaXguZXJpY3Nzb24uc2UwHhcNOTcwNzE1MTUzNDM2WhcN
+MDMwMjIyMTUzNDM2WjCBkDELMAkGA1UEBhMCU0UxEjAQBgNVBAgTCVN0b2NraG9s
+bTEPMA0GA1UEBxMGQWx2c2pvMQwwCgYDVQQKEwNFVFgxDjAMBgNVBAsTBUROL1NQ
+MRcwFQYDVQQDEw5Kb2FraW0gR3JlYmVubzElMCMGCSqGSIb3DQEJARYWam9ja2VA
+ZXJpeC5lcmljc3Nvbi5zZTBcMA0GCSqGSIb3DQEBAQUAA0sAMEgCQQC+mJv24FL4
+YZz5MNPLIIBoPE56e+fU4RjBI5Jg84bid8Nz35xeuZoB3ILp5LuBui8QEHxFKLoC
+Vn/T4Zo496EVAgMBAAEwDQYJKoZIhvcNAQEEBQADQQBYxQVfTydyZCE0UXvZd7Ei
+josNsAaWJk9fFIJaG9uyXCEfg2dVgoT2eBk3D9DI+7OB+78isM5CVlFbL7hilvP8
+-----END CERTIFICATE-----
diff --git a/lib/inets/test/httpd_SUITE_data/server_root/ssl/ssl_server.pem b/lib/inets/test/httpd_SUITE_data/server_root/ssl/ssl_server.pem
new file mode 100644
index 0000000000..fe739c15f7
--- /dev/null
+++ b/lib/inets/test/httpd_SUITE_data/server_root/ssl/ssl_server.pem
@@ -0,0 +1,22 @@
+-----BEGIN RSA PRIVATE KEY-----
+MIIBOwIBAAJBAL9Bozj3BIjL5Cy8b3rjMT2kPZRychX4wz9bHoIIiKnKo1xXHYjw
+g3N9zWM1f1ZzMADwVry1uAInA8q09+7hL20CAwEAAQJACwu2ao7RozjrV64WXimK
+6X131P/7GMvCMwGHNIlbozqoOqmZcYrbKaF61l+XuwA2QvTo3ywW1Ivxcyr6TeAr
+PQIhAOX+WXT6yiqqwjt08kjBCJyMgfZtdAO6pc/6pKjNWiZfAiEA1OH1iPW/OQe5
+tlQXpiRVdLyneNsPygPRJc4Bdwu3hbMCIQDbI5pA56QxOzqOREOGJsb5wrciAfAE
+jZbnr72sSN2YqQIgAWFpvzagw9Tp/mWzNY+cwkIK7/yzsIKv04fveH8p9IMCIQCr
+td4IiukeUwXmPSvYM4uCE/+J89wEL9qU8Mlc3gDLXA==
+-----END RSA PRIVATE KEY-----
+-----BEGIN CERTIFICATE-----
+MIICDDCCAbYCAQAwDQYJKoZIhvcNAQEEBQAwgZAxCzAJBgNVBAYTAlNFMRIwEAYD
+VQQIEwlTdG9ja2hvbG0xDzANBgNVBAcTBkFsdnNqbzEMMAoGA1UEChMDRVRYMQ4w
+DAYDVQQLEwVETi9TUDEXMBUGA1UEAxMOSm9ha2ltIEdyZWJlbm8xJTAjBgkqhkiG
+9w0BCQEWFmpvY2tlQGVyaXguZXJpY3Nzb24uc2UwHhcNOTcwNzE1MTUzMzQxWhcN
+MDMwMjIyMTUzMzQxWjCBkDELMAkGA1UEBhMCU0UxEjAQBgNVBAgTCVN0b2NraG9s
+bTEPMA0GA1UEBxMGQWx2c2pvMQwwCgYDVQQKEwNFVFgxDjAMBgNVBAsTBUROL1NQ
+MRcwFQYDVQQDEw5Kb2FraW0gR3JlYmVubzElMCMGCSqGSIb3DQEJARYWam9ja2VA
+ZXJpeC5lcmljc3Nvbi5zZTBcMA0GCSqGSIb3DQEBAQUAA0sAMEgCQQC/QaM49wSI
+y+QsvG964zE9pD2UcnIV+MM/Wx6CCIipyqNcVx2I8INzfc1jNX9WczAA8Fa8tbgC
+JwPKtPfu4S9tAgMBAAEwDQYJKoZIhvcNAQEEBQADQQAmXDY1CyJjzvQZX442kkHG
+ic9QFY1UuVfzokzNMwlHYl1Qx9zaodx0cJCrcH5GF9O9LJbhhV77LzoxT1Q5wZp5
+-----END CERTIFICATE-----
diff --git a/lib/inets/test/httpd_basic_SUITE.erl b/lib/inets/test/httpd_basic_SUITE.erl
new file mode 100644
index 0000000000..581c9c5782
--- /dev/null
+++ b/lib/inets/test/httpd_basic_SUITE.erl
@@ -0,0 +1,281 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 2007-2011. All Rights Reserved.
+%%
+%% The contents of this file are subject to the Erlang Public License,
+%% Version 1.1, (the "License"); you may not use this file except in
+%% compliance with the License. You should have received a copy of the
+%% Erlang Public License along with this software. If not, it can be
+%% retrieved online at http://www.erlang.org/.
+%%
+%% Software distributed under the License is distributed on an "AS IS"
+%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+%% the License for the specific language governing rights and limitations
+%% under the License.
+%%
+%% %CopyrightEnd%
+%%
+%%
+-module(httpd_basic_SUITE).
+
+-include("test_server.hrl").
+-include("test_server_line.hrl").
+
+%% Note: This directive should only be used in test suites.
+-compile(export_all).
+
+-define(URL_START, "http://localhost:").
+
+all(doc) ->
+ ["Basic test of httpd."];
+
+all(suite) ->
+ [
+ uri_too_long_414,
+ header_too_long_413,
+ escaped_url_in_error_body
+ ].
+
+%%--------------------------------------------------------------------
+%% Function: init_per_suite(Config) -> Config
+%% Config - [tuple()]
+%% A list of key/value pairs, holding the test case configuration.
+%% Description: Initiation 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) ->
+ ok = inets:start(),
+ PrivDir = ?config(priv_dir, Config),
+
+ Dummy =
+"<HTML>
+<HEAD>
+<TITLE>/index.html</TITLE>
+</HEAD>
+<BODY>
+DUMMY
+</BODY>
+</HTML>",
+
+ DummyFile = filename:join([PrivDir,"dummy.html"]),
+ {ok, Fd} = file:open(DummyFile, [write]),
+ ok = file:write(Fd, Dummy),
+ ok = file:close(Fd),
+ HttpdConf = [{port, 0},
+ {ipfamily, inet},
+ {server_name, "httpd_test"},
+ {server_root, PrivDir},
+ {document_root, PrivDir},
+ {bind_address, "localhost"}],
+
+ [{httpd_conf, HttpdConf} | 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) ->
+ inets:stop(),
+ ok.
+
+%%--------------------------------------------------------------------
+%% Function: init_per_testcase(Case, 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: Initiation 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.
+%%--------------------------------------------------------------------
+init_per_testcase(_Case, Config) ->
+ Config.
+
+%%--------------------------------------------------------------------
+%% Function: end_per_testcase(Case, 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(_, Config) ->
+ Config.
+
+%%-------------------------------------------------------------------------
+%% Test cases starts here.
+%%-------------------------------------------------------------------------
+uri_too_long_414(doc) ->
+ ["Test that too long uri's get 414 HTTP code"];
+uri_too_long_414(suite) ->
+ [];
+uri_too_long_414(Config) when is_list(Config) ->
+ HttpdConf = ?config(httpd_conf, Config),
+ {ok, Pid} = inets:start(httpd, [{port, 0}, {max_uri_size, 10}
+ | HttpdConf]),
+ Info = httpd:info(Pid),
+ Port = proplists:get_value(port, Info),
+ Address = proplists:get_value(bind_address, Info),
+ ok = httpd_test_lib:verify_request(ip_comm, Address, Port, node(),
+ "GET /morethantenchars "
+ "HTTP/1.1\r\n\r\n",
+ [{statuscode, 414},
+ %% Server will send lowest version
+ %% as it will not get to the
+ %% client version
+ %% before aborting
+ {version, "HTTP/0.9"}]),
+ inets:stop(httpd, Pid).
+
+
+%%-------------------------------------------------------------------------
+%%-------------------------------------------------------------------------
+
+header_too_long_413(doc) ->
+ ["Test that too long headers's get 413 HTTP code"];
+header_too_long_413(suite) ->
+ [];
+header_too_long_413(Config) when is_list(Config) ->
+ HttpdConf = ?config(httpd_conf, Config),
+ {ok, Pid} = inets:start(httpd, [{port, 0}, {max_header_size, 10}
+ | HttpdConf]),
+ Info = httpd:info(Pid),
+ Port = proplists:get_value(port, Info),
+ Address = proplists:get_value(bind_address, Info),
+ ok = httpd_test_lib:verify_request(ip_comm, Address, Port, node(),
+ "GET index.html "
+ "HTTP/1.1\r\n"
+ "Connection:close \r\n\r\n ",
+ [{statuscode, 413},
+ {version, "HTTP/1.1"}]),
+ inets:stop(httpd, Pid).
+
+
+%%-------------------------------------------------------------------------
+%%-------------------------------------------------------------------------
+
+escaped_url_in_error_body(doc) ->
+ ["Test Url-encoding see OTP-8940"];
+escaped_url_in_error_body(suite) ->
+ [];
+escaped_url_in_error_body(Config) when is_list(Config) ->
+ tsp("escaped_url_in_error_body -> entry"),
+ HttpdConf = ?config(httpd_conf, Config),
+ {ok, Pid} = inets:start(httpd, [{port, 0} | HttpdConf]),
+ Info = httpd:info(Pid),
+ Port = proplists:get_value(port, Info),
+ _Address = proplists:get_value(bind_address, Info),
+
+ %% Request 1
+ tsp("escaped_url_in_error_body -> request 1"),
+ URL1 = ?URL_START ++ integer_to_list(Port),
+ %% Make sure the server is ok, by making a request for a valid page
+ case httpc:request(get, {URL1 ++ "/dummy.html", []},
+ [{url_encode, false},
+ {version, "HTTP/1.0"}],
+ [{full_result, false}]) of
+ {ok, {200, _}} ->
+ %% Don't care about the the body, just that we get a ok response
+ ok;
+ {ok, UnexpectedOK1} ->
+ tsf({unexpected_ok_1, UnexpectedOK1})
+ end,
+
+ %% Request 2
+ tsp("escaped_url_in_error_body -> request 2"),
+ %% Make sure the server is ok, by making a request for a valid page
+ case httpc:request(get, {URL1 ++ "/dummy.html", []},
+ [{url_encode, true},
+ {version, "HTTP/1.0"}],
+ [{full_result, false}]) of
+ {ok, {200, _}} ->
+ %% Don't care about the the body, just that we get a ok response
+ ok;
+ {ok, UnexpectedOK2} ->
+ tsf({unexpected_ok_2, UnexpectedOK2})
+ end,
+
+ %% Request 3
+ tsp("escaped_url_in_error_body -> request 3"),
+ %% Ask for a non-existing page(1)
+ Path = "/<b>this_is_bold<b>",
+ HTMLEncodedPath = http_util:html_encode(Path),
+ URL2 = URL1 ++ Path,
+ case httpc:request(get, {URL2, []},
+ [{url_encode, true},
+ {version, "HTTP/1.0"}],
+ [{full_result, false}]) of
+ {ok, {404, Body3}} ->
+ case find_URL_path(string:tokens(Body3, " ")) of
+ HTMLEncodedPath ->
+ ok;
+ BadPath3 ->
+ tsf({unexpected_path_3, HTMLEncodedPath, BadPath3})
+ end;
+ {ok, UnexpectedOK3} ->
+ tsf({unexpected_ok_1, UnexpectedOK3})
+ end,
+
+ %% Request 4
+ tsp("escaped_url_in_error_body -> request 4"),
+ %% Ask for a non-existing page(2)
+ case httpc:request(get, {URL2, []},
+ [{url_encode, false},
+ {version, "HTTP/1.0"}],
+ [{full_result, false}]) of
+ {ok, {404, Body4}} ->
+ case find_URL_path(string:tokens(Body4, " ")) of
+ HTMLEncodedPath ->
+ ok;
+ BadPath4 ->
+ tsf({unexpected_path_2, HTMLEncodedPath, BadPath4})
+ end;
+ {ok, UnexpectedOK4} ->
+ tsf({unexpected_ok_4, UnexpectedOK4})
+ end,
+ tsp("escaped_url_in_error_body -> stop inets"),
+ inets:stop(httpd, Pid),
+ tsp("escaped_url_in_error_body -> done"),
+ ok.
+
+find_URL_path([]) ->
+ "";
+find_URL_path(["URL", URL | _]) ->
+ URL;
+find_URL_path([_ | Rest]) ->
+ find_URL_path(Rest).
+
+tsf(Reason) ->
+ test_server:fail(Reason).
+
+
+tsp(F) ->
+ tsp(F, []).
+tsp(F, A) ->
+ Timestamp = formated_timestamp(),
+ test_server:format("** ~s ** ~p ~p:" ++ F ++ "~n",
+ [Timestamp, self(), ?MODULE | A]).
+
+formated_timestamp() ->
+ format_timestamp( os:timestamp() ).
+
+format_timestamp({_N1, _N2, N3} = Now) ->
+ {Date, Time} = calendar:now_to_datetime(Now),
+ {YYYY,MM,DD} = Date,
+ {Hour,Min,Sec} = Time,
+ FormatDate =
+ io_lib:format("~.4w:~.2.0w:~.2.0w ~.2.0w:~.2.0w:~.2.0w 4~w",
+ [YYYY,MM,DD,Hour,Min,Sec,round(N3/1000)]),
+ lists:flatten(FormatDate).
+
+
+skip(Reason) ->
+ {skip, Reason}.
+
diff --git a/lib/inets/test/httpd_block.erl b/lib/inets/test/httpd_block.erl
new file mode 100644
index 0000000000..f967d8172a
--- /dev/null
+++ b/lib/inets/test/httpd_block.erl
@@ -0,0 +1,299 @@
+%%
+%% %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%
+%%
+%%
+-module(httpd_block).
+
+-include("test_server.hrl").
+-include("test_server_line.hrl").
+
+%% General testcases bodies called from httpd_SUITE
+-export([block_disturbing_idle/4, block_non_disturbing_idle/4,
+ block_503/4, block_disturbing_active/4,
+ block_non_disturbing_active/4,
+ block_disturbing_active_timeout_not_released/4,
+ block_disturbing_active_timeout_released/4,
+ block_non_disturbing_active_timeout_not_released/4,
+ block_non_disturbing_active_timeout_released/4,
+ disturbing_blocker_dies/4,
+ non_disturbing_blocker_dies/4, restart_no_block/4,
+ restart_disturbing_block/4, restart_non_disturbing_block/4
+ ]).
+
+%% Help functions
+-export([do_block_server/4, do_block_nd_server/5, do_long_poll/6]).
+
+-define(report(Label, Content),
+ inets:report_event(20, Label, test_case,
+ [{module, ?MODULE}, {line, ?LINE} | Content])).
+
+
+%%-------------------------------------------------------------------------
+%% Test cases starts here.
+%%-------------------------------------------------------------------------
+block_disturbing_idle(_Type, Port, Host, Node) ->
+ unblocked = get_admin_state(Node, Host, Port),
+ block_server(Node, Host, Port),
+ blocked = get_admin_state(Node, Host, Port),
+ unblock_server(Node, Host, Port),
+ unblocked = get_admin_state(Node, Host, Port).
+%%--------------------------------------------------------------------
+block_non_disturbing_idle(_Type, Port, Host, Node) ->
+ unblocked = get_admin_state(Node, Host, Port),
+ block_nd_server(Node, Host, Port),
+ blocked = get_admin_state(Node, Host, Port),
+ unblock_server(Node, Host, Port),
+ unblocked = get_admin_state(Node, Host, Port).
+%%--------------------------------------------------------------------
+block_503(Type, Port, Host, Node) ->
+ Req = "GET / HTTP/1.0\r\ndummy-host.ericsson.se:\r\n\r\n",
+ unblocked = get_admin_state(Node, Host, Port),
+ ok = httpd_test_lib:verify_request(Type, Host, Port, Node, Req,
+ [{statuscode, 200},
+ {version, "HTTP/1.0"}]),
+ ok = block_server(Node, Host, Port),
+ blocked = get_admin_state(Node, Host, Port),
+ ok = httpd_test_lib:verify_request(Type, Host, Port, Node, Req,
+ [{statuscode, 503},
+ {version, "HTTP/1.0"}]),
+ ok = unblock_server(Node, Host, Port),
+ unblocked = get_admin_state(Node, Host, Port),
+ ok = httpd_test_lib:verify_request(Type, Host, Port, Node, Req,
+ [{statuscode, 200},
+ {version, "HTTP/1.0"}]).
+%%--------------------------------------------------------------------
+block_disturbing_active(Type, Port, Host, Node) ->
+ process_flag(trap_exit, true),
+ Pid = long_poll(Type, Host, Port, Node, 200, 60000),
+ test_server:sleep(15000),
+ block_server(Node, Host, Port),
+ await_suite_failed_process_exit(Pid, "poller", 60000,
+ connection_closed),
+ blocked = get_admin_state(Node, Host, Port),
+ process_flag(trap_exit, false),
+ ok.
+%%--------------------------------------------------------------------
+block_non_disturbing_active(Type, Port, Host, Node) ->
+ process_flag(trap_exit, true),
+ Poller = long_poll(Type, Host, Port, Node, 200, 60000),
+ test_server:sleep(15000),
+ ok = block_nd_server(Node, Host, Port),
+ await_normal_process_exit(Poller, "poller", 60000),
+ blocked = get_admin_state(Node, Host, Port),
+ process_flag(trap_exit, false),
+ ok.
+
+%%--------------------------------------------------------------------
+block_disturbing_active_timeout_not_released(Type, Port, Host, Node) ->
+ process_flag(trap_exit, true),
+ Poller = long_poll(Type, Host, Port, Node, 200, 60000),
+ test_server:sleep(15000),
+ Blocker = blocker(Node, Host, Port, 50000),
+ await_normal_process_exit(Blocker, "blocker", 50000),
+ await_normal_process_exit(Poller, "poller", 30000),
+ blocked = get_admin_state(Node, Host, Port),
+ process_flag(trap_exit, false),
+ ok.
+
+%%--------------------------------------------------------------------
+block_disturbing_active_timeout_released(Type, Port, Host, Node) ->
+ process_flag(trap_exit, true),
+ Poller = long_poll(Type, Host, Port, Node, 200, 40000),
+ test_server:sleep(5000),
+ Blocker = blocker(Node, Host, Port, 10000),
+ await_normal_process_exit(Blocker, "blocker", 15000),
+ await_suite_failed_process_exit(Poller, "poller", 40000,
+ connection_closed),
+ blocked = get_admin_state(Node, Host, Port),
+ process_flag(trap_exit, false),
+ ok.
+%%--------------------------------------------------------------------
+block_non_disturbing_active_timeout_not_released(Type, Port, Host, Node) ->
+ process_flag(trap_exit, true),
+ Poller = long_poll(Type, Host, Port, Node, 200, 60000),
+ test_server:sleep(5000),
+ ok = block_nd_server(Node, Host, Port, 40000),
+ await_normal_process_exit(Poller, "poller", 60000),
+ blocked = get_admin_state(Node, Host, Port),
+ process_flag(trap_exit, false),
+ ok.
+
+%%--------------------------------------------------------------------
+block_non_disturbing_active_timeout_released(Type, Port, Host, Node) ->
+ process_flag(trap_exit, true),
+ Poller = long_poll(Type, Host, Port, Node, 200, 45000),
+ test_server:sleep(5000),
+ Blocker = blocker_nd(Node, Host, Port ,10000, {error,timeout}),
+ await_normal_process_exit(Blocker, "blocker", 15000),
+ await_normal_process_exit(Poller, "poller", 50000),
+ unblocked = get_admin_state(Node, Host, Port),
+ process_flag(trap_exit, false),
+ ok.
+%%--------------------------------------------------------------------
+disturbing_blocker_dies(Type, Port, Host, Node) ->
+ process_flag(trap_exit, true),
+ Poller = long_poll(Type, Host, Port, Node, 200, 60000),
+ test_server:sleep(5000),
+ Blocker = blocker(Node, Host, Port, 10000),
+ test_server:sleep(5000),
+ exit(Blocker,simulate_blocker_crash),
+ await_normal_process_exit(Poller, "poller", 60000),
+ unblocked = get_admin_state(Node, Host, Port),
+ process_flag(trap_exit, false),
+ ok.
+
+%%--------------------------------------------------------------------
+non_disturbing_blocker_dies(Type, Port, Host, Node) ->
+ process_flag(trap_exit, true),
+ Poller = long_poll(Type, Host, Port, Node, 200, 60000),
+ test_server:sleep(5000),
+ Blocker = blocker_nd(Node, Host, Port, 10000, ok),
+ test_server:sleep(5000),
+ exit(Blocker, simulate_blocker_crash),
+ await_normal_process_exit(Poller, "poller", 60000),
+ unblocked = get_admin_state(Node, Host, Port),
+ process_flag(trap_exit, false),
+ ok.
+%%--------------------------------------------------------------------
+restart_no_block(_, Port, Host, Node) ->
+ {error,_Reason} = restart_server(Node, Host, Port).
+
+%%--------------------------------------------------------------------
+restart_disturbing_block(_, Port, Host, Node) ->
+ ?report("restart_disturbing_block - get_admin_state (unblocked)", []),
+ unblocked = get_admin_state(Node, Host, Port),
+ ?report("restart_disturbing_block - block_server", []),
+ ok = block_server(Node, Host, Port),
+ ?report("restart_disturbing_block - restart_server", []),
+ ok = restart_server(Node, Host, Port),
+ ?report("restart_disturbing_block - unblock_server", []),
+ ok = unblock_server(Node, Host, Port),
+ ?report("restart_disturbing_block - get_admin_state (unblocked)", []),
+ unblocked = get_admin_state(Node, Host, Port).
+
+%%--------------------------------------------------------------------
+restart_non_disturbing_block(_, Port, Host, Node) ->
+ ?report("restart_non_disturbing_block - get_admin_state (unblocked)", []),
+ unblocked = get_admin_state(Node, Host, Port),
+ ?report("restart_non_disturbing_block - block_nd_server", []),
+ ok = block_nd_server(Node, Host, Port),
+ ?report("restart_non_disturbing_block - restart_server", []),
+ ok = restart_server(Node, Host, Port),
+ ?report("restart_non_disturbing_block - unblock_server", []),
+ ok = unblock_server(Node, Host, Port),
+ ?report("restart_non_disturbing_block - get_admin_state (unblocked)", []),
+ unblocked = get_admin_state(Node, Host, Port).
+
+%%--------------------------------------------------------------------
+%% Internal functions
+%%--------------------------------------------------------------------
+blocker(Node, Host, Port, Timeout) ->
+ spawn_link(?MODULE, do_block_server,[Node, Host, Port,Timeout]).
+
+do_block_server(Node, Host, Port, Timeout) ->
+ ok = block_server(Node, Host, Port, Timeout),
+ exit(normal).
+
+blocker_nd(Node, Host, Port, Timeout, Reply) ->
+ spawn_link(?MODULE, do_block_nd_server,
+ [Node, Host, Port, Timeout, Reply]).
+
+do_block_nd_server(Node, Host, Port, Timeout, Reply) ->
+ Reply = block_nd_server(Node, Host, Port, Timeout),
+ exit(normal).
+
+restart_server(Node, _Host, Port) ->
+ Addr = undefined,
+ rpc:call(Node, httpd, restart, [Addr, Port]).
+
+block_server(Node, _Host, Port) ->
+ Addr = undefined,
+ rpc:call(Node, httpd, block, [Addr, Port]).
+
+block_server(Node, _Host, Port, Timeout) ->
+ Addr = undefined,
+ rpc:call(Node, httpd, block, [Addr, Port, disturbing, Timeout]).
+
+block_nd_server(Node, _Host, Port) ->
+ Addr = undefined,
+ rpc:call(Node, httpd, block, [Addr, Port, non_disturbing]).
+
+block_nd_server(Node, _Host, Port, Timeout) ->
+ Addr = undefined,
+ rpc:call(Node, httpd, block, [Addr, Port, non_disturbing, Timeout]).
+
+unblock_server(Node, _Host, Port) ->
+ Addr = undefined,
+ rpc:call(Node, httpd, unblock, [Addr, Port]).
+
+get_admin_state(Node,_Host,Port) ->
+ Addr = undefined,
+ rpc:call(Node, httpd, get_admin_state, [Addr, Port]).
+
+await_normal_process_exit(Pid, Name, Timeout) ->
+ receive
+ {'EXIT', Pid, normal} ->
+ ok;
+ {'EXIT', Pid, Reason} ->
+ Err =
+ lists:flatten(
+ io_lib:format("expected normal exit, "
+ "unexpected exit of ~s process: ~p",
+ [Name, Reason])),
+ test_server:fail(Err)
+ after Timeout ->
+ test_server:fail("timeout while waiting for " ++ Name)
+ end.
+
+await_suite_failed_process_exit(Pid, Name, Timeout, Why) ->
+ receive
+ {'EXIT', Pid, {suite_failed, Why}} ->
+ ok;
+ {'EXIT', Pid, Reason} ->
+ Err =
+ lists:flatten(
+ io_lib:format("expected connection_closed, "
+ "unexpected exit of ~s process: ~p",
+ [Name, Reason])),
+ test_server:fail(Err)
+ after Timeout ->
+ test_server:fail("timeout while waiting for " ++ Name)
+ end.
+
+long_poll(Type, Host, Port, Node, StatusCode, Timeout) ->
+ spawn_link(?MODULE, do_long_poll, [Type, Host, Port, Node,
+ StatusCode, Timeout]).
+
+do_long_poll(Type, Host, Port, Node, StatusCode, Timeout) ->
+ Mod = "httpd_example",
+ Func = "delay",
+ Req = lists:flatten(io_lib:format("GET /eval?" ++ Mod ++ ":" ++ Func ++
+ "(~p) HTTP/1.0\r\n\r\n",[30000])),
+ case httpd_test_lib:verify_request(Type, Host, Port, Node, Req,
+ [{statuscode, StatusCode},
+ {version, "HTTP/1.0"}], Timeout) of
+ ok ->
+ exit(normal);
+ Reason ->
+ test_server:fail(Reason)
+ end.
+
+
+
+
+
diff --git a/lib/inets/test/httpd_load.erl b/lib/inets/test/httpd_load.erl
new file mode 100644
index 0000000000..9bb9f9f94e
--- /dev/null
+++ b/lib/inets/test/httpd_load.erl
@@ -0,0 +1,99 @@
+%%
+%% %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%
+%%
+%%
+
+-module(httpd_load).
+
+-include("test_server.hrl").
+-include("test_server_line.hrl").
+
+%% General testcases bodies called from httpd_SUITE
+-export([load_test/5]).
+
+%% Help functions
+-export([load_test_client/8]).
+
+%%-------------------------------------------------------------------------
+%% Test cases starts here.
+%%-------------------------------------------------------------------------
+load_test(Type, Port, Host, Node, NofTesters) ->
+ URIs =
+ [
+ "/index.html",
+ "/echo.shtml",
+ "/",
+ "/flastmod.shtml",
+ "/misc/"
+ ],
+ Fun = fun(Mod, Host1, Port1, Node1, Req, Exp) ->
+ ok = httpd_test_lib:verify_request(Mod, Host1, Port1,
+ Node1, Req, Exp)
+ end,
+ load_test(Fun, URIs ++ URIs, Type, Host, Port, Node, NofTesters, []).
+%%--------------------------------------------------------------------
+%% Internal functions
+%%--------------------------------------------------------------------
+
+load_test(_, _, _, _, _, _, 0, []) ->
+ ok;
+load_test(Fun, URIs, Type, Host, Port, Node, 0, List) ->
+ receive
+ {Pid, done} ->
+ load_test(Fun, URIs, Type, Host, Port, Node, 0,
+ lists:delete(Pid, List));
+ {'EXIT', Pid, normal} ->
+ load_test(Fun, URIs, Type, Host, Port, Node, 0,
+ lists:delete(Pid, List));
+ {'EXIT', Pid, Reason} ->
+ Str = lists:flatten(io_lib:format("client ~p exited: ~p",
+ [Pid,Reason])),
+ test_server:fail(Str);
+ _ ->
+ load_test(Fun, URIs, Type, Host, Port, Node, 0, List)
+ end;
+
+load_test(Fun, URIs, Type, Host, Port, Node, X, List) ->
+ Pid = spawn_link(?MODULE, load_test_client,
+ [Fun, URIs, Type, Host, Port, Node, self(), 100]),
+ load_test(Fun, lists:reverse(URIs), Type, Host, Port, Node, X-1,
+ [Pid | List]).
+
+load_test_client(_Fun, [], _Type, _Host, _Port, _Node, Boss, _Timeout) ->
+ load_test_client_done(Boss);
+load_test_client(Fun, [URI|URIs], Type, Host, Port, Node, Boss, Timeout) ->
+ Req = "GET "++URI++" HTTP/1.0\r\nConnection: Close\r\n"
+ "From: m@erix\r\nReferer: http://www.ericsson.se/\r\n\r\n",
+ Timeout1 =
+ case (catch Fun(Type, Host, Port, Node, Req,
+ [{statuscode, 200}, {statuscode, 500},
+ {statuscode, 503}, {version, "HTTP/1.0"}])) of
+ {'EXIT', {suite_failed, connection_closed, _, _}} ->
+ %% Some platforms seems to handle heavy load badly.
+ %% So, back off and see if this helps
+ %%?LOG("load_test_client->requestfailed:connection_closed"[]),
+ 2 * Timeout;
+ _ ->
+ Timeout
+ end,
+ test_server:sleep(Timeout1),
+ load_test_client(Fun, URIs, Type, Host, Port, Node, Boss, Timeout1).
+
+load_test_client_done(Boss) ->
+ Boss ! {self(), done}.
+
diff --git a/lib/inets/test/httpd_mod.erl b/lib/inets/test/httpd_mod.erl
new file mode 100644
index 0000000000..617851c77d
--- /dev/null
+++ b/lib/inets/test/httpd_mod.erl
@@ -0,0 +1,947 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 2005-2011. All Rights Reserved.
+%%
+%% The contents of this file are subject to the Erlang Public License,
+%% Version 1.1, (the "License"); you may not use this file except in
+%% compliance with the License. You should have received a copy of the
+%% Erlang Public License along with this software. If not, it can be
+%% retrieved online at http://www.erlang.org/.
+%%
+%% Software distributed under the License is distributed on an "AS IS"
+%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+%% the License for the specific language governing rights and limitations
+%% under the License.
+%%
+%% %CopyrightEnd%
+%%
+%%
+
+-module(httpd_mod).
+-author('[email protected]').
+
+-include("test_server.hrl").
+-include("test_server_line.hrl").
+
+%% General testcases bodies called from httpd_SUITE
+-export([alias/4, actions/4, security/5, auth/4, auth_api/6,
+ auth_mnesia_api/4, htaccess/4,
+ cgi/4, esi/4, get/4, head/4, all/4]).
+
+%% Help functions
+-export([event/4, ssl_password_cb/0]).
+
+%% Seconds before successful auths timeout.
+-define(AUTH_TIMEOUT,5).
+
+
+%%-------------------------------------------------------------------------
+%% Test cases starts here.
+%%-------------------------------------------------------------------------
+alias(Type, Port, Host, Node) ->
+ ok = httpd_test_lib:verify_request(Type, Host, Port, Node,
+ "GET /pics/icon.sheet.gif "
+ "HTTP/1.0\r\n\r\n",
+ [{statuscode, 200},
+ {header, "Content-Type","image/gif"},
+ {header, "Server"},
+ {header, "Date"},
+ {version, "HTTP/1.0"}]),
+
+ ok = httpd_test_lib:verify_request(Type, Host, Port, Node,
+ "GET / HTTP/1.0\r\n\r\n",
+ [{statuscode, 200},
+ {header, "Content-Type","text/html"},
+ {header, "Server"},
+ {header, "Date"},
+ {version, "HTTP/1.0"}]),
+
+ ok = httpd_test_lib:verify_request(Type,Host,Port,Node,
+ "GET /misc/ HTTP/1.0\r\n\r\n",
+ [{statuscode, 200},
+ {header, "Content-Type","text/html"},
+ {header, "Server"},
+ {header, "Date"},
+ {version, "HTTP/1.0"}]),
+
+ %% Check redirection if trailing slash is missing.
+ ok = httpd_test_lib:verify_request(Type,Host,Port,Node,
+ "GET /misc HTTP/1.0\r\n\r\n",
+ [{statuscode, 301},
+ {header, "Location"},
+ {header, "Content-Type","text/html"},
+ {version, "HTTP/1.0"}]).
+
+%%-------------------------------------------------------------------------
+actions(Type, Port, Host, Node) ->
+ ok = httpd_test_lib:verify_request(Type, Host, Port, Node,
+ "HEAD / HTTP/1.0\r\n\r\n",
+ [{statuscode, 200},
+ {version, "HTTP/1.0"}]).
+
+%%-------------------------------------------------------------------------
+security(ServerRoot, Type, Port, Host, Node) ->
+ %% io:format(user, "~w:security -> entry with"
+ %% "~n ServerRoot: ~p"
+ %% "~n Type: ~p"
+ %% "~n Port: ~p"
+ %% "~n Host: ~p"
+ %% "~n Node: ~p"
+ %% "~n", [?MODULE, ServerRoot, Type, Port, Host, Node]),
+
+ global:register_name(mod_security_test, self()), % Receive events
+
+ test_server:sleep(5000),
+
+ OpenDir = filename:join([ServerRoot, "htdocs", "open"]),
+
+ %% Test blocking / unblocking of users.
+
+ %% /open, require user one Aladdin
+ remove_users(Node, ServerRoot, Host, Port, "open"),
+
+ auth_request(Type, Host, Port, Node, "/open/", "one", "onePassword",
+ [{statuscode, 401}]),
+ receive_security_event({event, auth_fail, Port, OpenDir,
+ [{user, "one"}, {password, "onePassword"}]},
+ Node, Port),
+
+ auth_request(Type,Host,Port,Node,"/open/", "two", "twoPassword",
+ [{statuscode, 401}]),
+ receive_security_event({event, auth_fail, Port, OpenDir,
+ [{user, "two"}, {password, "twoPassword"}]},
+ Node, Port),
+
+ auth_request(Type, Host, Port, Node,"/open/", "Aladdin",
+ "AladdinPassword", [{statuscode, 401}]),
+ receive_security_event({event, auth_fail, Port, OpenDir,
+ [{user, "Aladdin"},
+ {password, "AladdinPassword"}]},
+ Node, Port),
+
+ add_user(Node, ServerRoot, Port, "open", "one", "onePassword", []),
+ add_user(Node, ServerRoot, Port, "open", "two", "twoPassword", []),
+
+ auth_request(Type, Host, Port, Node,"/open/", "one", "WrongPassword",
+ [{statuscode, 401}]),
+ receive_security_event({event, auth_fail, Port, OpenDir,
+ [{user, "one"}, {password, "WrongPassword"}]},
+ Node, Port),
+
+ auth_request(Type, Host, Port, Node,"/open/", "one", "WrongPassword",
+ [{statuscode, 401}]),
+ receive_security_event({event, auth_fail, Port, OpenDir,
+ [{user, "one"}, {password, "WrongPassword"}]},
+ Node, Port),
+
+ receive_security_event({event, user_block, Port, OpenDir,
+ [{user, "one"}]}, Node, Port),
+
+ global:unregister_name(mod_security_test), % No more events.
+
+ auth_request(Type, Host, Port, Node,"/open/", "one", "WrongPassword",
+ [{statuscode, 401}]),
+ auth_request(Type, Host, Port, Node,"/open/", "one", "onePassword",
+ [{statuscode, 403}]),
+
+ %% User "one" should be blocked now..
+ %% [{"one",_, Port, OpenDir,_}] = list_blocked_users(Node,Port),
+ case list_blocked_users(Node, Port) of
+ [{"one",_, Port, OpenDir,_}] ->
+ ok;
+ Blocked ->
+ %% io:format(user, "~w:security -> Blocked: ~p"
+ %% "~n", [?MODULE, Blocked]),
+ exit({unexpected_blocked, Blocked})
+ end,
+
+ [{"one",_, Port, OpenDir,_}] = list_blocked_users(Node,Port,OpenDir),
+
+ true = unblock_user(Node, "one", Port, OpenDir),
+ %% User "one" should not be blocked any more..
+ [] = list_blocked_users(Node, Port),
+ [] = list_blocked_users(Node, Port, OpenDir),
+ auth_request(Type, Host, Port, Node,"/open/", "one", "onePassword",
+ [{statuscode, 200}]),
+
+ %% Test list_auth_users & auth_timeout
+ ["one"] = list_auth_users(Node, Port),
+ ["one"] = list_auth_users(Node, Port, OpenDir),
+ auth_request(Type, Host, Port, Node,"/open/", "two", "onePassword",
+ [{statuscode, 401}]),
+ ["one"] = list_auth_users(Node, Port),
+ ["one"] = list_auth_users(Node, Port, OpenDir),
+ auth_request(Type, Host, Port, Node,"/open/", "two", "twoPassword",
+ [{statuscode, 401}]),
+ ["one"] = list_auth_users(Node, Port),
+ ["one"] = list_auth_users(Node, Port, OpenDir),
+ %% Wait for successful auth to timeout.
+ test_server:sleep(?AUTH_TIMEOUT*1001),
+ [] = list_auth_users(Node, Port),
+ [] = list_auth_users(Node, Port, OpenDir),
+ %% "two" is blocked.
+ true = unblock_user(Node, "two", Port, OpenDir),
+ %% Test explicit blocking. Block user 'two'.
+ [] = list_blocked_users(Node,Port,OpenDir),
+ true = block_user(Node, "two", Port, OpenDir, 10),
+ auth_request(Type, Host, Port, Node,"/open/", "two", "twoPassword",
+ [{statuscode, 401}]).
+
+%%-------------------------------------------------------------------------
+auth(Type, Port, Host, Node) ->
+ %% Authentication required!
+ ok = httpd_test_lib:verify_request(Type,Host,Port,Node,
+ "GET /open/ HTTP/1.0\r\n\r\n",
+ [{statuscode, 401},
+ {version, "HTTP/1.0"},
+ {header, "WWW-Authenticate"}]),
+ ok = httpd_test_lib:verify_request(Type,Host,Port,Node,
+ "GET /secret/ HTTP/1.0\r\n\r\n",
+ [{statuscode, 401},
+ {version, "HTTP/1.0"},
+ {header, "WWW-Authenticate"}]),
+ ok = httpd_test_lib:verify_request(Type,Host,Port,Node,
+ "GET /secret/top_secret/"
+ " HTTP/1.0\r\n\r\n",
+ [{statuscode, 401},
+ {version, "HTTP/1.0"},
+ {header, "WWW-Authenticate"}]),
+
+ %% Authentication OK! ["one:OnePassword" user first in user list]
+ auth_request(Type, Host, Port, Node, "/open/dummy.html", "one",
+ "onePassword", [{statuscode, 200}]),
+ %% Authentication OK and a directory listing is supplied!
+ %% ["Aladdin:open sesame" user second in user list]
+ auth_request(Type, Host, Port, Node, "/open/","Aladdin",
+ "AladdinPassword", [{statuscode, 200}]),
+
+ %% User correct but wrong password! ["one:one" user first in user list]
+ auth_request(Type, Host, Port, Node, "/open/", "one", "one",
+ [{statuscode, 401},{header, "WWW-Authenticate"}]),
+ %% Make sure Authenticate header is received even the second time
+ %% we try a incorrect password! Otherwise a browser client will hang!
+ auth_request(Type, Host, Port, Node, "/open/", "one", "one",
+ [{statuscode, 401},{header, "WWW-Authenticate"}]),
+
+ %% Neither user or password correct! ["dummy:dummy"]
+ auth_request(Type, Host, Port, Node, "/open/", "dummy", "dummy",
+ [{statuscode, 401}]),
+
+ %% Authentication OK! ["two:TwoPassword" user in first group]
+ auth_request(Type, Host, Port, Node, "/secret/dummy.html", "two",
+ "twoPassword", [{statuscode, 200}]),
+ %% Authentication OK and a directory listing is supplied!
+ %% ["three:ThreePassword" user in second group]
+ auth_request(Type, Host, Port, Node,"/secret/", "three",
+ "threePassword", [{statuscode, 200}]),
+
+ %% User correct but wrong password! ["two:two" user in first group]
+ auth_request(Type, Host, Port, Node, "/secret/", "two", "two",
+ [{statuscode, 401}]),
+ %% Neither user or password correct! ["dummy:dummy"]
+ auth_request(Type, Host, Port, Node,"/secret/", "dummy", "dummy",
+ [{statuscode, 401}]),
+
+ %% Nested secret/top_secret OK! ["Aladdin:open sesame"]
+ auth_request(Type, Host, Port, Node, "/secret/top_secret/", "Aladdin",
+ "AladdinPassword", [{statuscode, 200}]),
+ %% Authentication still required!
+ ok = httpd_test_lib:verify_request(Type, Host, Port, Node, "GET /open/ "
+ "HTTP/1.0\r\n\r\n",
+ [{statuscode, 401},
+ {version, "HTTP/1.0"},
+ {header, "WWW-Authenticate"}]),
+ ok = httpd_test_lib:verify_request(Type, Host, Port, Node, "GET /secret/ "
+ "HTTP/1.0\r\n\r\n",
+ [{statuscode, 401},
+ {version, "HTTP/1.0"},
+ {header, "WWW-Authenticate"}]),
+ ok = httpd_test_lib:verify_request(Type, Host, Port, Node,
+ "GET /secret/top_secret/ "
+ "HTTP/1.0\r\n\r\n",
+ [{statuscode, 401},
+ {version, "HTTP/1.0"},
+ {header, "WWW-Authenticate"}]).
+
+
+%%-------------------------------------------------------------------------
+%% What to test here:
+%%
+%% /open - plain, require user one Aladdin
+%% /secret - plain, require group group1 group2
+%% /secret/top_secret - plain, require group group3
+%% /dets_open - dets, require user one Aladdin
+%% /dets_secret - dets, require group group1 group2
+%% /dets_secret/top_secret - dets, require group group3
+%% /mnesia_open/ - mnesia, require user one Aladdin
+%% /mnesia_secret/ - mnesia, require group group1 group2
+%% /mnesia_secret/top_secret/ - mnesia, require group group3
+auth_api(ServerRoot, AuthStoreType, Type, Port, Host, Node) ->
+ ok = httpd_test_lib:verify_request(Type, Host, Port, Node,
+ "GET / HTTP/1.0\r\n\r\n",
+ [{statuscode, 200},
+ {version, "HTTP/1.0"}]),
+ auth_request(Type, Host, Port, Node, "/", "one", "WrongPassword",
+ [{statuscode, 200}]),
+
+ %% Make sure Authenticate header is received even the second time
+ %% we try a incorrect password! Otherwise a browser client will hang!
+ auth_request(Type, Host, Port, Node,"/" ++ AuthStoreType ++ "open/",
+ "dummy", "WrongPassword", [{statuscode, 401},
+ {header, "WWW-Authenticate"}]),
+ auth_request(Type, Host, Port, Node,"/" ++ AuthStoreType ++ "open/",
+ "dummy", "WrongPassword", [{statuscode, 401},
+ {header, "WWW-Authenticate"}]),
+
+ %% Change the password to DummyPassword then try to add a user
+ %% Get an error and set it to NoPassword
+ ok = update_password(Node, ServerRoot, Host, Port, AuthStoreType ++
+ "open", "NoPassword", "DummyPassword"),
+ {error,bad_password} =
+ add_user(Node, ServerRoot, Port, AuthStoreType ++ "open", "one",
+ "onePassword", []),
+ ok = update_password(Node, ServerRoot, Host, Port, AuthStoreType ++"open",
+ "DummyPassword", "NoPassword"),
+
+ %% Test /*open, require user one Aladdin
+ remove_users(Node, ServerRoot, Host, Port, AuthStoreType ++ "open"),
+
+ auth_request(Type, Host, Port, Node,"/" ++ AuthStoreType ++ "open/",
+ "one", "onePassword", [{statuscode, 401}]),
+
+ auth_request(Type, Host, Port, Node,"/" ++ AuthStoreType ++ "open/",
+ "two", "twoPassword", [{statuscode, 401}]),
+
+ auth_request(Type, Host, Port, Node,"/" ++ AuthStoreType ++ "open/",
+ "Aladdin", "onePassword", [{statuscode, 401}]),
+
+ add_user(Node, ServerRoot, Port, AuthStoreType ++ "open", "one",
+ "onePassword", []),
+ add_user(Node, ServerRoot, Port, AuthStoreType ++ "open", "two",
+ "twoPassword", []),
+ add_user(Node, ServerRoot, Port, AuthStoreType ++ "open", "Aladdin",
+ "AladdinPassword", []),
+
+ {ok, [_|_]} = list_users(Node, ServerRoot, Host, Port,
+ AuthStoreType++"open"),
+ auth_request(Type, Host, Port, Node, "/" ++ AuthStoreType ++ "open/",
+ "one", "WrongPassword", [{statuscode, 401}]),
+ auth_request(Type, Host, Port, Node, "/" ++ AuthStoreType ++ "open/",
+ "one", "onePassword", [{statuscode, 200}]),
+ auth_request(Type, Host, Port, Node,"/" ++ AuthStoreType ++ "open/",
+ "two", "twoPassword", [{statuscode, 401}]),
+ auth_request(Type, Host, Port, Node, "/" ++ AuthStoreType ++ "open/",
+ "Aladdin", "WrongPassword", [{statuscode, 401}]),
+ auth_request(Type, Host, Port, Node,"/" ++ AuthStoreType ++ "open/",
+ "Aladdin", "AladdinPassword", [{statuscode, 200}]),
+
+ remove_users(Node, ServerRoot, Host, Port, AuthStoreType++"open"),
+ {ok, []} = list_users(Node, ServerRoot, Host, Port,
+ AuthStoreType++"open"),
+
+ %% Phase 2
+ remove_users(Node, ServerRoot, Host, Port, AuthStoreType++"secret"),
+ {ok, []} = list_users(Node, ServerRoot, Host, Port, AuthStoreType ++
+ "secret"),
+ auth_request(Type, Host, Port, Node,"/" ++ AuthStoreType ++ "secret/",
+ "one", "onePassword", [{statuscode, 401}]),
+ auth_request(Type, Host, Port, Node,"/" ++ AuthStoreType ++ "secret/",
+ "two", "twoPassword", [{statuscode, 401}]),
+ auth_request(Type, Host, Port, Node, "/" ++ AuthStoreType ++ "secret/",
+ "three", "threePassword", [{statuscode, 401}]),
+ add_user(Node, ServerRoot, Port, AuthStoreType ++ "secret", "one",
+ "onePassword",
+ []),
+ add_user(Node, ServerRoot, Port, AuthStoreType ++ "secret",
+ "two", "twoPassword", []),
+ add_user(Node, ServerRoot, Port, AuthStoreType++"secret", "Aladdin",
+ "AladdinPassword",[]),
+ add_group_member(Node, ServerRoot, Port, AuthStoreType ++ "secret",
+ "one", "group1"),
+ add_group_member(Node, ServerRoot, Port, AuthStoreType ++ "secret",
+ "two", "group1"),
+ add_group_member(Node, ServerRoot, Port, AuthStoreType ++
+ "secret", "Aladdin", "group2"),
+ auth_request(Type, Host, Port, Node,"/" ++ AuthStoreType ++ "secret/",
+ "one", "onePassword", [{statuscode, 200}]),
+ auth_request(Type, Host, Port, Node,"/" ++ AuthStoreType ++ "secret/",
+ "two", "twoPassword", [{statuscode, 200}]),
+ auth_request(Type, Host, Port, Node,"/" ++ AuthStoreType ++ "secret/",
+ "Aladdin", "AladdinPassword", [{statuscode, 200}]),
+ auth_request(Type, Host, Port, Node,"/" ++ AuthStoreType ++ "secret/",
+ "three", "threePassword", [{statuscode, 401}]),
+ remove_users(Node, ServerRoot, Host, Port, AuthStoreType ++ "secret"),
+ {ok, []} = list_users(Node, ServerRoot, Host, Port,
+ AuthStoreType ++ "secret"),
+ remove_groups(Node, ServerRoot, Host, Port, AuthStoreType ++ "secret"),
+ Directory = filename:join([ServerRoot, "htdocs", AuthStoreType ++
+ "secret"]),
+ {ok, []} = list_groups(Node, ServerRoot, Host, Port, Directory),
+
+ %% Phase 3
+ remove_users(Node, ServerRoot, Host, Port, AuthStoreType ++
+ "secret/top_secret"),
+ remove_groups(Node, ServerRoot, Host, Port, AuthStoreType ++
+ "secret/top_secret"),
+ auth_request(Type, Host, Port, Node,"/" ++ AuthStoreType ++
+ "secret/top_secret/",
+ "three", "threePassword", [{statuscode, 401}]),
+ auth_request(Type, Host, Port, Node,"/" ++ AuthStoreType ++
+ "secret/top_secret/", "two", "twoPassword",
+ [{statuscode, 401}]),
+ add_user(Node, ServerRoot, Port, AuthStoreType ++
+ "secret/top_secret","three",
+ "threePassword",[]),
+ add_user(Node, ServerRoot, Port, AuthStoreType ++ "secret/top_secret",
+ "two","twoPassword", []),
+ add_group_member(Node, ServerRoot, Port, AuthStoreType ++
+ "secret/top_secret",
+ "three", "group3"),
+ auth_request(Type, Host, Port, Node,"/" ++ AuthStoreType ++
+ "secret/top_secret/", "three", "threePassword",
+ [{statuscode, 200}]),
+ auth_request(Type, Host, Port, Node,"/" ++ AuthStoreType ++
+ "secret/top_secret/", "two", "twoPassword",
+ [{statuscode, 401}]),
+ add_group_member(Node, ServerRoot, Port, AuthStoreType ++
+ "secret/top_secret",
+ "two", "group3"),
+ auth_request(Type,Host,Port,Node,"/" ++ AuthStoreType ++
+ "secret/top_secret/",
+ "two", "twoPassword", [{statuscode, 200}]),
+ remove_users(Node, ServerRoot, Host, Port, AuthStoreType ++
+ "secret/top_secret"),
+ {ok, []} = list_users(Node, ServerRoot, Host, Port,
+ AuthStoreType ++ "secret/top_secret"),
+ remove_groups(Node, ServerRoot, Host, Port, AuthStoreType ++
+ "secret/top_secret"),
+ Directory2 = filename:join([ServerRoot, "htdocs",
+ AuthStoreType ++ "secret/top_secret"]),
+ {ok, []} = list_groups(Node, ServerRoot, Host, Port, Directory2),
+ auth_request(Type, Host, Port, Node, "/" ++ AuthStoreType ++
+ "secret/top_secret/", "two", "twoPassword",
+ [{statuscode, 401}]),
+ auth_request(Type, Host, Port, Node, "/" ++ AuthStoreType ++
+ "secret/top_secret/","three", "threePassword",
+ [{statuscode, 401}]).
+
+%%--------------------------------------------------------------------------
+auth_mnesia_api(_Type, Port, _Host, _Node) ->
+ %% Create three groups:
+ %% group1 : one Aladdin
+ %% group2 : two
+ %% group3 : three
+ mod_auth_mnesia:store_user("one", "onePassword", Port,
+ "/mnesia_open", ""),
+ mod_auth_mnesia:store_user("Aladdin", "AladdinPassword", Port,
+ "/mnesia_open", ""),
+ mod_auth_mnesia:store_user("two", "twoPassword", Port,
+ "/mnesia_open", ""),
+ mod_auth_mnesia:store_user("three", "threePassword", Port,
+ "/mnesia_open", ""),
+ Users = mod_auth_mnesia:list_users(Port, "/mnesia_open"),
+
+ ok = check_lists_members(Users,["Aladdin","one","two","three"]),
+
+ true = mod_auth_mnesia:store_group_member("group1", "one", Port,
+ "/mnesia_open", ""),
+ true = mod_auth_mnesia:store_group_member("group1","Aladdin", Port,
+ "/mnesia_open", ""),
+ true = mod_auth_mnesia:store_group_member("group2","two", Port,
+ "/mnesia_open", ""),
+ true = mod_auth_mnesia:store_group_member("group3","three", Port,
+ "/mnesia_open", ""),
+ %% Check that all three created groups exist.
+ Groups = mod_auth_mnesia:list_groups(Port, "/mnesia_open"),
+ ok = check_lists_members(Groups, ["group1","group2","group3"]),
+
+ %% Check that the members of all groups are correct.
+ Group1 = mod_auth_mnesia:list_group_members("group1", Port,
+ "/mnesia_open"),
+ ok = check_lists_members(Group1,["one","Aladdin"]),
+ {ok,["two"]} = mod_auth_mnesia:list_group_members("group2", Port,
+ "/mnesia_open"),
+
+ {ok,["three"]} = mod_auth_mnesia:list_group_members("group3", Port,
+ "/mnesia_open"),
+
+ %% Delete user 'one' from group one and check that he was removed
+ %% correctly.
+ true = mod_auth_mnesia:remove_group_member("group1", "one", Port,
+ "/mnesia_open", ""),
+ {ok,["Aladdin"]} = mod_auth_mnesia:list_group_members("group1", Port,
+ "/mnesia_open"),
+
+ %% Remove group1 and check that the group was removed correctly.
+ true = mod_auth_mnesia:remove_group("group1", Port, "/mnesia_open", ""),
+ Groups_1 = mod_auth_mnesia:list_groups(Port, "/mnesia_open"),
+ ok = check_lists_members(Groups_1,["group2","group3"]),
+
+ %% Check that the other users still exist in their groups.
+ Users_1 = mod_auth_mnesia:list_users(Port, "/mnesia_open"),
+ ok = check_lists_members(Users_1,["Aladdin","one","two","three"]),
+ {ok,["two"]} = mod_auth_mnesia:list_group_members("group2", Port,
+ "/mnesia_open"),
+ {ok,["three"]} = mod_auth_mnesia:list_group_members("group3", Port,
+ "/mnesia_open"),
+
+ %% Remove the remaining groups/users and check that all
+ %% users/groups are removed.
+ true = mod_auth_mnesia:remove_group("group2", Port, "/mnesia_open", ""),
+ true = mod_auth_mnesia:remove_group("group3", Port, "/mnesia_open", ""),
+ {ok, []} = mod_auth_mnesia:list_groups(Port, "/mnesia_open"),
+ true = mod_auth_mnesia:remove_user("one", Port, "/mnesia_open", ""),
+ true = mod_auth_mnesia:remove_user("Aladdin", Port, "/mnesia_open", ""),
+ true = mod_auth_mnesia:remove_user("two", Port, "/mnesia_open", ""),
+ true = mod_auth_mnesia:remove_user("three", Port, "/mnesia_open", ""),
+ {ok, []} = mod_auth_mnesia:list_users(Port, "/mnesia_open"),
+ ok.
+%%--------------------------------------------------------------------------
+htaccess(Type, Port, Host, Node) ->
+ %% Control that authentication required!
+ %% Control that the pages that shall be
+ %% authenticated really need authenticatin
+ ok = httpd_test_lib:verify_request(Type, Host, Port, Node,
+ "GET /ht/open/ HTTP/1.0\r\n\r\n",
+ [{statuscode, 401},
+ {version, "HTTP/1.0"},
+ {header, "WWW-Authenticate"}]),
+ ok = httpd_test_lib:verify_request(Type, Host, Port, Node,
+ "GET /ht/secret/ HTTP/1.0\r\n\r\n",
+ [{statuscode, 401},
+ {version, "HTTP/1.0"},
+ {header, "WWW-Authenticate"}]),
+ ok = httpd_test_lib:verify_request(Type, Host, Port, Node,
+ "GET /ht/secret/top_secret/ "
+ "HTTP/1.0\r\n\r\n",
+ [{statuscode, 401},
+ {version, "HTTP/1.0"},
+ {header, "WWW-Authenticate"}]),
+
+ %% Make sure Authenticate header is received even the second time
+ %% we try a incorrect password! Otherwise a browser client will hang!
+ auth_request(Type, Host, Port, Node,"/ht/open/",
+ "dummy", "WrongPassword", [{statuscode, 401},
+ {header, "WWW-Authenticate"}]),
+ auth_request(Type, Host, Port, Node,"/ht/open/",
+ "dummy", "WrongPassword", [{statuscode, 401},
+ {header, "WWW-Authenticate"}]),
+
+ %% Control that not just the first user in the list is valid
+ %% Control the first user
+ %% Authennticating ["one:OnePassword" user first in user list]
+ auth_request(Type, Host, Port, Node, "/ht/open/dummy.html", "one",
+ "OnePassword", [{statuscode, 200}]),
+
+ %% Control the second user
+ %% Authentication OK and a directory listing is supplied!
+ %% ["Aladdin:open sesame" user second in user list]
+ auth_request(Type, Host, Port, Node, "/ht/open/","Aladdin",
+ "AladdinPassword", [{statuscode, 200}]),
+
+ %% Contro that bad passwords and userids get a good denial
+ %% User correct but wrong password! ["one:one" user first in user list]
+ auth_request(Type, Host, Port, Node, "/ht/open/", "one", "one",
+ [{statuscode, 401}]),
+ %% Neither user or password correct! ["dummy:dummy"]
+ auth_request(Type, Host, Port, Node, "/ht/open/", "dummy", "dummy",
+ [{statuscode, 401}]),
+
+ %% Control that authetication still works, even if its a member in a group
+ %% Authentication OK! ["two:TwoPassword" user in first group]
+ auth_request(Type, Host, Port, Node, "/ht/secret/dummy.html", "two",
+ "TwoPassword", [{statuscode, 200}]),
+
+ %% Authentication OK and a directory listing is supplied!
+ %% ["three:ThreePassword" user in second group]
+ auth_request(Type, Host, Port, Node,"/ht/secret/", "three",
+ "ThreePassword", [{statuscode, 200}]),
+
+ %% Deny users with bad passwords even if the user is a group member
+ %% User correct but wrong password! ["two:two" user in first group]
+ auth_request(Type, Host, Port, Node, "/ht/secret/", "two", "two",
+ [{statuscode, 401}]),
+ %% Neither user or password correct! ["dummy:dummy"]
+ auth_request(Type, Host, Port, Node,"/ht/secret/", "dummy", "dummy",
+ [{statuscode, 401}]),
+
+ %% control that we deny the users that are in subnet above the allowed
+ auth_request(Type, Host, Port, Node,"/ht/blocknet/dummy.html", "four",
+ "FourPassword", [{statuscode, 403}]),
+ %% Control that we only applies the rules to the right methods
+ ok = httpd_test_lib:verify_request(Type, Host, Port, Node,
+ "HEAD /ht/blocknet/dummy.html"
+ " HTTP/1.0\r\n\r\n",
+ [{statuscode, 200},
+ {version, "HTTP/1.0"}]),
+
+ %% Control that the rerquire directive can be overrideen
+ auth_request(Type, Host, Port, Node,
+ "/ht/secret/top_secret/", "Aladdin", "AladdinPassword",
+ [{statuscode, 401}]),
+
+ %% Authentication still required!
+ ok = httpd_test_lib:verify_request(Type, Host, Port, Node, "GET /ht/open/ "
+ "HTTP/1.0\r\n\r\n",
+ [{statuscode, 401},
+ {version, "HTTP/1.0"},
+ {header, "WWW-Authenticate"}]),
+ ok = httpd_test_lib:verify_request(Type, Host, Port, Node,
+ "GET /ht/secret/ HTTP/1.0\r\n\r\n",
+ [{statuscode, 401},
+ {version, "HTTP/1.0"},
+ {header, "WWW-Authenticate"}]),
+ ok = httpd_test_lib:verify_request(Type, Host, Port, Node,
+ "GET /ht/secret/top_secret/ "
+ "HTTP/1.0\r\n\r\n",
+ [{statuscode, 401},
+ {version, "HTTP/1.0"},
+ {header, "WWW-Authenticate"}]).
+%%--------------------------------------------------------------------
+cgi(Type, Port, Host, Node) ->
+ {Script, Script2, Script3} =
+ case test_server:os_type() of
+ {win32, _} ->
+ {"printenv.bat", "printenv.sh", "cgi_echo.exe"};
+ _ ->
+ {"printenv.sh", "printenv.bat", "cgi_echo"}
+ end,
+
+ %% The length (> 100) is intentional
+ ok = httpd_test_lib:
+ verify_request(Type, Host, Port, Node,
+ "POST /cgi-bin/" ++ Script3 ++
+ " HTTP/1.0\r\n"
+ "Content-Length:100 \r\n\r\n "
+ "ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ"
+ "ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ"
+ "ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ"
+ "ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ"
+ "ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ"
+ "ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ"
+ "ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ"
+ "ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ"
+ "ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ"
+ "ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ"
+ "ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ"
+ "ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ"
+ "ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ"
+ "ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ"
+ "ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ"
+ "ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ"
+ "ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ"
+ " \r\n\r\n",
+ [{statuscode, 200},
+ {version, "HTTP/1.0"},
+ {header, "content-type", "text/plain"}]),
+
+ ok = httpd_test_lib:verify_request(Type, Host, Port, Node,
+ "GET /cgi-bin/"++ Script ++
+ " HTTP/1.0\r\n\r\n",
+ [{statuscode, 200},
+ {version, "HTTP/1.0"}]),
+ ok = httpd_test_lib:verify_request(Type, Host, Port, Node,
+ "GET /cgi-bin/not_there "
+ "HTTP/1.0\r\n\r\n",
+ [{statuscode, 404},{statuscode, 500},
+ {version, "HTTP/1.0"}]),
+ ok = httpd_test_lib:verify_request(Type, Host, Port, Node,
+ "GET /cgi-bin/"++ Script ++
+ "?Nisse:kkk?sss/lll HTTP/1.0\r\n\r\n",
+ [{statuscode, 200},
+ {version, "HTTP/1.0"}]),
+ ok = httpd_test_lib:verify_request(Type, Host, Port, Node,
+ "POST /cgi-bin/"++ Script ++
+ " HTTP/1.0\r\n\r\n",
+ [{statuscode, 200},
+ {version, "HTTP/1.0"}]),
+ ok = httpd_test_lib:verify_request(Type, Host, Port, Node,
+ "GET /htbin/"++ Script ++
+ " HTTP/1.0\r\n\r\n",
+ [{statuscode, 200},
+ {version, "HTTP/1.0"}]),
+ ok = httpd_test_lib:verify_request(Type, Host, Port, Node,
+ "GET /htbin/not_there "
+ "HTTP/1.0\r\n\r\n",
+ [{statuscode, 404},{statuscode, 500},
+ {version, "HTTP/1.0"}]),
+ ok = httpd_test_lib:verify_request(Type, Host, Port, Node,
+ "GET /htbin/"++ Script ++
+ "?Nisse:kkk?sss/lll HTTP/1.0\r\n\r\n",
+ [{statuscode, 200},
+ {version, "HTTP/1.0"}]),
+ ok = httpd_test_lib:verify_request(Type, Host, Port, Node,
+ "POST /htbin/"++ Script ++
+ " HTTP/1.0\r\n\r\n",
+ [{statuscode, 200},
+ {version, "HTTP/1.0"}]),
+ ok = httpd_test_lib:verify_request(Type, Host, Port, Node,
+ "POST /htbin/"++ Script ++
+ " HTTP/1.0\r\n\r\n",
+ [{statuscode, 200},
+ {version, "HTTP/1.0"}]),
+
+ %% Execute an existing, but bad CGI script..
+ ok = httpd_test_lib:verify_request(Type, Host, Port, Node,
+ "POST /htbin/"++ Script2 ++
+ " HTTP/1.0\r\n\r\n",
+ [{statuscode, 404},
+ {version, "HTTP/1.0"}]),
+
+ ok = httpd_test_lib:verify_request(Type, Host, Port, Node,
+ "POST /cgi-bin/"++ Script2 ++
+ " HTTP/1.0\r\n\r\n",
+ [{statuscode, 404},
+ {version, "HTTP/1.0"}]),
+ ok.
+
+%%--------------------------------------------------------------------
+esi(Type, Port, Host, Node) ->
+ %% Check "ErlScriptAlias" and "EvalScriptAlias" directives
+ ok = httpd_test_lib:verify_request(Type, Host, Port, Node,
+ "GET /eval?httpd_example:print(\"Hi!\")"
+ " HTTP/1.0\r\n\r\n",
+ [{statuscode, 200},
+ {version, "HTTP/1.0"}]),
+ ok = httpd_test_lib:verify_request(Type, Host, Port, Node,
+ "GET /eval?not_allowed:print(\"Hi!\")"
+ " HTTP/1.0\r\n\r\n",
+ [{statuscode, 403},
+ {version, "HTTP/1.0"}]),
+ ok = httpd_test_lib:verify_request(Type, Host, Port, Node,
+ "GET /eval?httpd_example:undef(\"Hi!\")"
+ " HTTP/1.0\r\n\r\n",
+ [{statuscode, 500},
+ {version, "HTTP/1.0"}]),
+ ok = httpd_test_lib:verify_request(Type, Host, Port, Node,
+ "GET /cgi-bin/erl/httpd_example "
+ "HTTP/1.0\r\n\r\n",
+ [{statuscode, 400},
+ {version, "HTTP/1.0"}]),
+ ok = httpd_test_lib:verify_request(Type, Host, Port, Node,
+ "GET /cgi-bin/erl/httpd_example:get "
+ "HTTP/1.0\r\n\r\n",
+ [{statuscode, 200},
+ {version, "HTTP/1.0"}]),
+ ok = httpd_test_lib:verify_request(Type, Host, Port, Node,
+ "GET /cgi-bin/erl/httpd_example:"
+ "get?input=4711"
+ " HTTP/1.0\r\n\r\n",
+ [{statuscode, 200},
+ {version, "HTTP/1.0"}]),
+ ok = httpd_test_lib:verify_request(Type, Host, Port, Node,
+ "GET /cgi-bin/erl/httpd_example:"
+ "post HTTP/1.0\r\n\r\n",
+ [{statuscode, 200},
+ {version, "HTTP/1.0"}]),
+ ok = httpd_test_lib:verify_request(Type, Host, Port, Node,
+ "GET /cgi-bin/erl/not_allowed:post "
+ "HTTP/1.0\r\n\r\n",
+ [{statuscode, 403},
+ {version, "HTTP/1.0"}]),
+ ok = httpd_test_lib:verify_request(Type, Host, Port, Node,
+ "GET /cgi-bin/erl/httpd_example:undef "
+ "HTTP/1.0\r\n\r\n",
+ [{statuscode, 404},
+ {version, "HTTP/1.0"}]),
+ ok = httpd_test_lib:verify_request(Type, Host, Port, Node,
+ "GET /cgi-bin/erl/httpd_example/yahoo"
+ " HTTP/1.0\r\n\r\n",
+ [{statuscode, 302},
+ {version, "HTTP/1.0"}]),
+ ok.
+%%--------------------------------------------------------------------
+get(Type, Port, Host, Node) ->
+ ok = httpd_test_lib:verify_request(Type, Host, Port, Node,
+ "GET /index.html HTTP/1.0\r\n\r\n",
+ [{statuscode, 200},
+ {header, "Content-Type", "text/html"},
+ {header, "Date"},
+ {header, "Server"},
+ {version, "HTTP/1.0"}]),
+ ok = httpd_test_lib:verify_request(Type, Host, Port, Node,
+ "GET /fsize.shtml HTTP/1.1\r\nHost:"
+ ++ Host ++ "\r\n\r\n",
+ [{statuscode, 200},
+ {header, "Content-Type", "text/html"},
+ {header, "Date"},
+ {header, "Server"}]),
+ ok = httpd_test_lib:verify_request(Type, Host, Port, Node,
+ "GET /fsize.shtml HTTP/1.0\r\n\r\n",
+ [{statuscode, 200},
+ {header, "Content-Type"},
+ {header, "Server"},
+ {header, "Date"},
+ {version, "HTTP/1.0"}]),
+ ok = httpd_test_lib:verify_request(Type, Host, Port, Node,
+ "GET /secret/dummy.html "
+ "HTTP/1.0\r\n\r\n",
+ [{statuscode, 401},
+ {header, "WWW-Authenticate"},
+ {version, "HTTP/1.0"}]),
+ ok = httpd_test_lib:verify_request(Type, Host, Port, Node,
+ "GET /index.html HTTP/1.0\r\n\r\n",
+ [{statuscode, 200},
+ {header, "Server"},
+ {header, "Date"},
+ {header, "Content-Type",
+ "text/html"},
+ {version, "HTTP/1.0"}]),
+ ok.
+
+%%--------------------------------------------------------------------
+head(Type, Port, Host, Node) ->
+ ok = httpd_test_lib:verify_request(Type, Host, Port, Node,
+ "HEAD /index.html HTTP/1.0\r\n\r\n",
+ [{statuscode, 200},
+ {version, "HTTP/1.0"}]),
+ ok.
+%%--------------------------------------------------------------------
+all(Type, Port, Host, Node) ->
+ actions(Type, Port, Host, Node),
+ alias(Type, Port, Host, Node),
+ auth(Type, Port, Host, Node),
+ cgi(Type, Port, Host, Node),
+ esi(Type, Port, Host, Node),
+ get(Type, Port, Host, Node),
+ head(Type, Port, Host, Node),
+ ok.
+
+%%--------------------------------------------------------------------
+%% Internal functions
+%%--------------------------------------------------------------------
+auth_request(Type, Host, Port, Node, URI, User, Passwd, Expect) ->
+ Req = ["GET ", URI, " HTTP/1.0\r\n",
+ "Authorization: Basic ",
+ base64:encode_to_string(User++":"++Passwd),
+ "\r\n\r\n"],
+ ok = httpd_test_lib:verify_request(Type, Host, Port, Node,
+ lists:flatten(Req),
+ [{version, "HTTP/1.0"} | Expect]).
+
+remove_users(Node, ServerRoot, Host, Port, Dir) ->
+ %% List users, delete them, and make sure they are gone.
+ case list_users(Node, ServerRoot, Host, Port, Dir) of
+ {ok, Users} ->
+ lists:foreach(fun(User) ->
+ delete_user(Node, ServerRoot, Host,
+ Port, Dir, User)
+ end,
+ Users),
+ {ok, []} = list_users(Node, ServerRoot, Host, Port, Dir);
+ _ ->
+ ok
+ end.
+
+add_user(Node, Root, Port, Dir, User, Password, UserData) ->
+ Addr = undefined,
+ Directory = filename:join([Root, "htdocs", Dir]),
+ rpc:call(Node, mod_auth, add_user,
+ [User, Password, UserData, Addr, Port, Directory]).
+
+delete_user(Node, Root, _Host, Port, Dir, User) ->
+ Addr = undefined,
+ Directory = filename:join([Root, "htdocs", Dir]),
+ rpc:call(Node, mod_auth, delete_user, [User, Addr, Port, Directory]).
+
+list_users(Node, Root, _Host, Port, Dir) ->
+ Addr = undefined,
+ Directory = filename:join([Root, "htdocs", Dir]),
+ rpc:call(Node, mod_auth, list_users, [Addr, Port, Directory]).
+
+receive_security_event(Event, Node, Port) ->
+ %% io:format(user, "~w:receive_security_event -> entry with"
+ %% "~n Event: ~p"
+ %% "~n Node: ~p"
+ %% "~n Port: ~p"
+ %% "~n", [?MODULE, Event, Node, Port]),
+ receive
+ Event ->
+ ok;
+ {'EXIT', _, _} ->
+ receive_security_event(Event, Node, Port);
+ Other ->
+ test_server:fail({unexpected_event,
+ {expected, Event}, {received, Other}})
+ after 5000 ->
+ test_server:fail(no_event_recived)
+
+ end.
+
+list_blocked_users(Node,Port) ->
+ Addr = undefined, % Assumed to be on the same host
+ rpc:call(Node, mod_security, list_blocked_users, [Addr,Port]).
+
+list_blocked_users(Node,Port,Dir) ->
+ Addr = undefined, % Assumed to be on the same host
+ rpc:call(Node, mod_security, list_blocked_users, [Addr,Port,Dir]).
+
+block_user(Node,User,Port,Dir,Sec) ->
+ Addr = undefined, % Assumed to be on the same host
+ rpc:call(Node, mod_security, block_user, [User, Addr, Port, Dir, Sec]).
+
+unblock_user(Node,User,Port,Dir) ->
+ Addr = undefined, % Assumed to be on the same host
+ rpc:call(Node, mod_security, unblock_user, [User, Addr, Port, Dir]).
+
+list_auth_users(Node,Port) ->
+ Addr = undefined, % Assumed to be on the same host
+ rpc:call(Node, mod_security, list_auth_users, [Addr,Port]).
+
+list_auth_users(Node,Port,Dir) ->
+ Addr = undefined, % Assumed to be on the same host
+ rpc:call(Node, mod_security, list_auth_users, [Addr,Port,Dir]).
+
+update_password(Node, ServerRoot, _Address, Port, Dir, Old, New)->
+ Directory = filename:join([ServerRoot, "htdocs", Dir]),
+ rpc:call(Node, mod_auth, update_password,
+ [undefined, Port, Directory, Old, New, New]).
+
+remove_groups(Node, ServerRoot, Host, Port, Dir) ->
+ Directory = filename:join([ServerRoot, "htdocs", Dir]),
+ {ok, Groups} = list_groups(Node, ServerRoot, Host, Port, Directory),
+ lists:foreach(fun(Group) ->
+ delete_group(Node, Group, Port, Directory)
+ end,
+ Groups),
+ {ok, []} = list_groups(Node, ServerRoot, Host, Port, Directory),
+ ok.
+
+delete_group(Node, Group, Port, Dir) ->
+ Addr = undefined,
+ rpc:call(Node, mod_auth, delete_group, [Group, Addr, Port, Dir]).
+
+list_groups(Node, _, _, Port, Dir) ->
+ Addr = undefined,
+ rpc:call(Node, mod_auth, list_groups, [Addr, Port, Dir]).
+
+add_group_member(Node, ServerRoot, Port, Dir, User, Group) ->
+ Addr = undefined,
+ rpc:call(Node, mod_auth, add_group_member, [Group, User, Addr, Port,
+ filename:join(
+ [ServerRoot,
+ "htdocs",Dir])]).
+event(What, Port, Dir, Data) ->
+ Msg = {event, What, Port, Dir, Data},
+ case global:whereis_name(mod_security_test) of
+ undefined ->
+ ok;
+ _Pid ->
+ global:send(mod_security_test, Msg)
+ end.
+
+ssl_password_cb() ->
+ "dummy-ssl-password".
+
+check_lists_members({ok,L},L) ->
+ ok;
+check_lists_members({ok,L1},L2) ->
+ check_lists_members1(lists:sort(L1),lists:sort(L2));
+check_lists_members(Error,_L) ->
+ Error.
+
+check_lists_members1(L,L) ->
+ ok;
+check_lists_members1(L1,L2) ->
+ {error,{lists_not_equal,L1,L2}}.
diff --git a/lib/inets/test/httpd_poll.erl b/lib/inets/test/httpd_poll.erl
new file mode 100644
index 0000000000..1cc10365a7
--- /dev/null
+++ b/lib/inets/test/httpd_poll.erl
@@ -0,0 +1,496 @@
+%%
+%% %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(httpd_poll).
+-behaviour(gen_server).
+
+
+%% External API
+-export([start/0, start_appup/2, start/3,stop/0,verbosity/1,poll_time/1]).
+
+%% gen_server exports
+-export([init/1,
+ handle_call/3, handle_cast/2, handle_info/2, terminate/2]).
+
+
+-define(default_verbosity,error).
+-define(default_poll_time,60000). %% 60 seconds
+
+
+-record(state,{host = "", port = -1, ptime = -1, tref = none, uris = []}).
+
+
+%% start/0
+%%
+%% Description: Start polling HTTPD with default values
+%%
+start() ->
+ Options = default_options(otp),
+ start("gandalf", 8000, Options).
+
+start_appup(Host, Port) ->
+ Options = default_options(top),
+ start(Host, Port, Options).
+
+%% start/3
+%%
+%% Description: Start polling HTTPD
+%%
+%% Parameters:
+%% Host = string()
+%% Host name of HTTPD
+%% Port = integer()
+%% Port number of HTTPD
+%% Options = [Option]
+%% Option = {poll_time,integer()} | {verbosity,verbosity()} |
+%% {log_file,string()} | {uris,[uri()]}
+%% verbosity() = silence | error | log | debug | trace
+%% uri() = {string(),string}
+%% First part is a descriptive string and the second
+%% part is the actual URI.
+%%
+start(Host,Port,Options) ->
+ gen_server:start({local,httpd_tester},?MODULE,[Host,Port,Options],[]).
+
+stop() ->
+ gen_server:call(httpd_tester,stop).
+
+
+default_options(UriDesc) ->
+ Verbosity = {verbosity,?default_verbosity},
+ Uris = {uris,uris(UriDesc)},
+ PollTime = {poll_time,?default_poll_time},
+ Logging = {log_file,"httpd_poll.log"},
+ [Verbosity, Uris, PollTime, Logging].
+
+
+options(Options) ->
+ options(Options, default_options(otp), []).
+
+options([], Defaults, Options) ->
+ Options ++ Defaults;
+options([{Key,Val} = Opt|Opts], Defaults, Options) ->
+ options(Opts, lists:keydelete(Key, 1, Defaults), [Opt|Options]).
+
+
+verbosity(silence) ->
+ set_verbosity(silence);
+verbosity(error) ->
+ set_verbosity(error);
+verbosity(log) ->
+ set_verbosity(log);
+verbosity(debug) ->
+ set_verbosity(debug);
+verbosity(trace) ->
+ set_verbosity(trace).
+
+set_verbosity(Verbosity) ->
+ gen_server:cast(httpd_tester,{verbosity,Verbosity}).
+
+poll_time(NewTime) ->
+ gen_server:call(httpd_tester,{poll_time,NewTime}).
+
+
+%% ----------------------------------------------------------------------
+
+
+init([Host, Port, Options0]) ->
+ process_flag(trap_exit,true),
+ Options = options(Options0),
+ put(verbosity,get_verbosity(Options)),
+ log_open(get_log_file(Options)),
+ tstart(),
+ PollTime = get_poll_time(Options),
+ Ref = tcreate(PollTime),
+ log("created"),
+ {ok,#state{host = Host,
+ port = Port,
+ ptime = PollTime,
+ tref = Ref,
+ uris = get_uris(Options)}}.
+
+uris(top) ->
+ [uri_top_index()];
+
+uris(otp) ->
+ [
+ uri_top_index(),
+ uri_internal_product1(),
+ uri_internal_product2(),
+ uri_p7a_test_results(),
+ uri_bjorn1(),
+ uri_bjorn2(),
+ uri_top_ronja()
+ ].
+
+uri_top_index() ->
+ {"top page","/"}.
+
+uri_internal_product1() ->
+ {"product internal page (1)","/product/internal/"}.
+
+uri_internal_product2() ->
+ {"product internal page (2)","/product/internal"}.
+
+uri_p7a_test_results() ->
+ {"test summery index page",
+ "/product/internal/test/test_results/progress_P7A/index.html"}.
+
+uri_bjorn1() ->
+ {"bjorns home page (1)","/~bjorn/"}.
+
+uri_bjorn2() ->
+ {"bjorns home page (2)","/~bjorn"}.
+
+uri_top_ronja() ->
+ {"ronja top page","/ronja/"}.
+
+
+handle_call(stop, _From, State) ->
+ vlog("stop request"),
+ {stop, normal, ok, State};
+
+handle_call({poll_time,NewTime}, _From, State) ->
+ vlog("set new poll time: ~p",[NewTime]),
+ OldTime = State#state.ptime,
+ {stop, normal, OldTime, State#state{ptime = NewTime}};
+
+handle_call(Request, _From, State) ->
+ vlog("unexpected request(call): ~p",[Request]),
+ {reply, ok, State}.
+
+
+handle_cast({verbosity,Verbosity}, State) ->
+ vlog("set (new) verbosity to: ~p",[Verbosity]),
+ put(verbosity,Verbosity),
+ {noreply, State};
+
+handle_cast(Message, State) ->
+ vlog("unexpected message(call): ~p",[Message]),
+ {noreply, State}.
+
+
+handle_info(poll_time,State) ->
+ {{Description,Uri},Uris} = get_uri(State#state.uris),
+ vlog("poll time for ~s",[Description]),
+ do_poll(State#state.host,State#state.port,Uri),
+ Ref = tcreate(State#state.ptime),
+ {noreply, State#state{tref = Ref, uris = Uris}};
+
+handle_info(Info, State) ->
+ vlog("unexpected message(info): ~p",[Info]),
+ {noreply, State}.
+
+
+terminate(Reason,State) ->
+ tcancel(State#state.tref),
+ log_close(get(log_file)),
+ ok.
+
+
+get_uri([Uri|Uris]) ->
+ {Uri,Uris++[Uri]}.
+
+
+do_poll(Host,Port,Uri) ->
+ (catch poll(create(Host,Port),Uri,"200")).
+
+poll({ok,Socket},Uri,ExpStatus) ->
+ vtrace("poll -> entry with Socket: ~p",[Socket]),
+ put(latest_requested_uri,Uri),
+ Req = "GET " ++ Uri ++ " HTTP/1.0\r\n\r\n",
+ await_poll_response(send(Socket,Req),Socket,ExpStatus);
+poll({error,Reason},_Req,_ExpStatus) ->
+ verror("failed creating socket: ~p",[Reason]),
+ log("failed creating socket: ~p",[Reason]),
+ exit({error,Reason});
+poll(O,_Req,_ExpStatus) ->
+ verror("unexpected result from socket create: ~p",[O]),
+ log("unexpected result from socket create: ~p",[O]),
+ exit({unexpected_result,O}).
+
+await_poll_response(ok,Socket,ExpStatusCode) ->
+ vtrace("await_poll_response -> awaiting response with status ~s",
+ [ExpStatusCode]),
+ receive
+ {tcp_closed,Socket} ->
+ verror("connection closed when awaiting poll response"),
+ log("connection closed when awaiting reply to GET of '~s'",
+ [get(latest_requested_uri)]),
+ exit(connection_closed);
+ {tcp,Socket,Response} ->
+ vdebug("received response"),
+ validate(ExpStatusCode,Socket,Response)
+ after 10000 ->
+ verror("connection timeout waiting for poll response",[]),
+ log("connection timeout waiting for reply to GET of '~s'",
+ [get(latest_requested_uri)]),
+ exit(connection_timed_out)
+ end;
+await_poll_response(Error,_Socket,_ExpStatusCode) ->
+ verror("failed sending GET request for '~s' for reason: ~p",
+ [get(latest_requested_uri),Error]),
+ log("failed sending GET request for '~s' for reason: ~p",
+ [get(latest_requested_uri),Error]),
+ exit(Error).
+
+
+validate(ExpStatusCode,Socket,Response) ->
+ Sz = sz(Response),
+ vtrace("validate -> Entry with ~p bytes response",[Sz]),
+ Size = trash_the_rest(Socket,Sz),
+ close(Socket),
+ case inets_regexp:split(Response," ") of
+ {ok,["HTTP/1.0",ExpStatusCode|_]} ->
+ vlog("response (~p bytes) was ok",[Size]),
+ ok;
+ {ok,["HTTP/1.0",StatusCode|_]} ->
+ verror("unexpected response status received: ~s => ~s",
+ [StatusCode,status_to_message(StatusCode)]),
+ log("unexpected result to GET of '~s': ~s => ~s",
+ [get(latest_requested_uri),StatusCode,
+ status_to_message(StatusCode)]),
+ exit({unexpected_response_code,StatusCode,ExpStatusCode})
+ end.
+
+
+%% ------------------------------------------------------------------
+
+trash_the_rest(Socket,N) ->
+ receive
+ {tcp, Socket, Trash} ->
+ vtrace("trash_the_rest -> trash ~p bytes",[sz(Trash)]),
+ trash_the_rest(Socket,add(N,sz(Trash)));
+ {tcp_closed, Socket} ->
+ vdebug("socket closed after receiving ~p bytes",[N]),
+ N
+ after 10000 ->
+ verror("connection timeout waiting for message"),
+ exit(connection_timed_out)
+ end.
+
+
+add(N1,N2) when integer(N1),integer(N2) ->
+ N1 + N2;
+add(N1,N2) when integer(N1) ->
+ N1;
+add(N1,N2) when integer(N2) ->
+ N2.
+
+sz(L) when list(L) ->
+ length(lists:flatten(L));
+sz(B) when binary(B) ->
+ size(B);
+sz(O) ->
+ {unknown_size,O}.
+
+
+%% --------------------------------------------------------------
+%%
+%% Status code to printable string
+%%
+
+status_to_message(L) when list(L) ->
+ case (catch list_to_integer(L)) of
+ I when integer(I) ->
+ status_to_message(I);
+ _ ->
+ io_lib:format("UNKNOWN STATUS CODE: '~p'",[L])
+ end;
+status_to_message(100) -> "Section 10.1.1: Continue";
+status_to_message(101) -> "Section 10.1.2: Switching Protocols";
+status_to_message(200) -> "Section 10.2.1: OK";
+status_to_message(201) -> "Section 10.2.2: Created";
+status_to_message(202) -> "Section 10.2.3: Accepted";
+status_to_message(203) -> "Section 10.2.4: Non-Authoritative Information";
+status_to_message(204) -> "Section 10.2.5: No Content";
+status_to_message(205) -> "Section 10.2.6: Reset Content";
+status_to_message(206) -> "Section 10.2.7: Partial Content";
+status_to_message(300) -> "Section 10.3.1: Multiple Choices";
+status_to_message(301) -> "Section 10.3.2: Moved Permanently";
+status_to_message(302) -> "Section 10.3.3: Found";
+status_to_message(303) -> "Section 10.3.4: See Other";
+status_to_message(304) -> "Section 10.3.5: Not Modified";
+status_to_message(305) -> "Section 10.3.6: Use Proxy";
+status_to_message(307) -> "Section 10.3.8: Temporary Redirect";
+status_to_message(400) -> "Section 10.4.1: Bad Request";
+status_to_message(401) -> "Section 10.4.2: Unauthorized";
+status_to_message(402) -> "Section 10.4.3: Peyment Required";
+status_to_message(403) -> "Section 10.4.4: Forbidden";
+status_to_message(404) -> "Section 10.4.5: Not Found";
+status_to_message(405) -> "Section 10.4.6: Method Not Allowed";
+status_to_message(406) -> "Section 10.4.7: Not Acceptable";
+status_to_message(407) -> "Section 10.4.8: Proxy Authentication Required";
+status_to_message(408) -> "Section 10.4.9: Request Time-Out";
+status_to_message(409) -> "Section 10.4.10: Conflict";
+status_to_message(410) -> "Section 10.4.11: Gone";
+status_to_message(411) -> "Section 10.4.12: Length Required";
+status_to_message(412) -> "Section 10.4.13: Precondition Failed";
+status_to_message(413) -> "Section 10.4.14: Request Entity Too Large";
+status_to_message(414) -> "Section 10.4.15: Request-URI Too Large";
+status_to_message(415) -> "Section 10.4.16: Unsupported Media Type";
+status_to_message(416) -> "Section 10.4.17: Requested range not satisfiable";
+status_to_message(417) -> "Section 10.4.18: Expectation Failed";
+status_to_message(500) -> "Section 10.5.1: Internal Server Error";
+status_to_message(501) -> "Section 10.5.2: Not Implemented";
+status_to_message(502) -> "Section 10.5.3: Bad Gatteway";
+status_to_message(503) -> "Section 10.5.4: Service Unavailable";
+status_to_message(504) -> "Section 10.5.5: Gateway Time-out";
+status_to_message(505) -> "Section 10.5.6: HTTP Version not supported";
+status_to_message(Code) -> io_lib:format("Unknown status code: ~p",[Code]).
+
+
+%% ----------------------------------------------------------------
+
+create(Host,Port) ->
+ vtrace("create -> ~n\tHost: ~s~n\tPort: ~p",[Host,Port]),
+ case gen_tcp:connect(Host,Port,[{packet,0},{reuseaddr,true}]) of
+ {ok,Socket} ->
+ {ok,Socket};
+ {error,{enfile,_}} ->
+ {error,enfile};
+ Error ->
+ Error
+ end.
+
+close(Socket) ->
+ gen_tcp:close(Socket).
+
+
+send(Socket,Data) ->
+ vtrace("send -> send ~p bytes of data",[length(Data)]),
+ gen_tcp:send(Socket,Data).
+
+
+%% ----------------------------------------------------------------
+
+tstart() ->
+ timer:start().
+
+tcreate(Time) ->
+ {ok,Ref} = timer:send_after(Time,poll_time),
+ Ref.
+
+tcancel(Ref) ->
+ timer:cancel(Ref).
+
+%% ----------------------------------------------------------------
+
+log_open(undefined) ->
+ ok;
+log_open(FileName) ->
+ put(log_file,fopen(FileName)).
+
+log_close(undefined) ->
+ ok;
+log_close(Fd) ->
+ fclose(Fd).
+
+log(F) ->
+ log(F,[]).
+
+log(F,A) ->
+ {{Year,Month,Day},{Hour,Min,Sec}} = local_time(),
+ fwrite(get(log_file),
+ "~w.~w.~w ~w.~w.~w " ++ F ++ "~n",
+ [Year,Month,Day,Hour,Min,Sec] ++ A).
+
+%% ----------------------------------------------------------------
+
+fopen(Name) ->
+ {ok,Fd} = file:open(Name,[write]),
+ Fd.
+
+fclose(Fd) ->
+ file:close(Fd).
+
+fwrite(undefined,_F,_A) ->
+ ok;
+fwrite(Fd,F,A) ->
+ io:format(Fd,F,A).
+
+
+%% ----------------------------------------------------------------
+
+get_poll_time(Opts) ->
+ get_option(poll_time,Opts,?default_poll_time).
+
+get_log_file(Opts) ->
+ get_option(log_file,Opts).
+
+get_uris(Opts) ->
+ get_option(uris,Opts,[]).
+
+get_verbosity(Opts) ->
+ get_option(verbosity,Opts,?default_verbosity).
+
+get_option(Opt,Opts) ->
+ get_option(Opt,Opts,undefined).
+
+get_option(Opt,Opts,Default) ->
+ case lists:keysearch(Opt,1,Opts) of
+ {value,{Opt,Value}} ->
+ Value;
+ false ->
+ Default
+ end.
+
+%% ----------------------------------------------------------------
+
+%% sleep(T) -> receive after T -> ok end.
+
+%% ----------------------------------------------------------------
+
+%% vtrace(F) -> vprint(get(verbosity),trace,F,[]).
+vtrace(F,A) -> vprint(get(verbosity),trace,F,A).
+
+vdebug(F) -> vprint(get(verbosity),debug,F,[]).
+vdebug(F,A) -> vprint(get(verbosity),debug,F,A).
+
+vlog(F) -> vprint(get(verbosity),log,F,[]).
+vlog(F,A) -> vprint(get(verbosity),log,F,A).
+
+verror(F) -> vprint(get(verbosity),error,F,[]).
+verror(F,A) -> vprint(get(verbosity),error,F,A).
+
+vprint(trace,Severity,F,A) -> vprint(Severity,F,A);
+vprint(debug,trace,F,A) -> ok;
+vprint(debug,Severity,F,A) -> vprint(Severity,F,A);
+vprint(log,log,F,A) -> vprint(log,F,A);
+vprint(log,error,F,A) -> vprint(log,F,A);
+vprint(error,error,F,A) -> vprint(error,F,A);
+vprint(_Verbosity,_Severity,_F,_A) -> ok.
+
+vprint(Severity,F,A) ->
+ {{Year,Month,Day},{Hour,Min,Sec}} = local_time(),
+ io:format("~w.~w.~w ~w.~w.~w " ++ image_of(Severity) ++ F ++ "~n",
+ [Year,Month,Day,Hour,Min,Sec] ++ A).
+
+image_of(error) -> "ERR: ";
+image_of(log) -> "LOG: ";
+image_of(debug) -> "DBG: ";
+image_of(trace) -> "TRC: ".
+
+local_time() -> calendar:local_time().
+
+
+
+
+
diff --git a/lib/inets/test/httpd_test_data/server_root/auth/group b/lib/inets/test/httpd_test_data/server_root/auth/group
new file mode 100644
index 0000000000..b3da0ccbd3
--- /dev/null
+++ b/lib/inets/test/httpd_test_data/server_root/auth/group
@@ -0,0 +1,3 @@
+group1: one two
+group2: two three
+group3: three Aladdin
diff --git a/lib/inets/test/httpd_test_data/server_root/auth/passwd b/lib/inets/test/httpd_test_data/server_root/auth/passwd
new file mode 100644
index 0000000000..8c980ff547
--- /dev/null
+++ b/lib/inets/test/httpd_test_data/server_root/auth/passwd
@@ -0,0 +1,4 @@
+one:onePassword
+two:twoPassword
+three:threePassword
+Aladdin:AladdinPassword
diff --git a/lib/inets/test/httpd_test_data/server_root/cgi-bin/printenv.bat b/lib/inets/test/httpd_test_data/server_root/cgi-bin/printenv.bat
new file mode 100644
index 0000000000..25a49a1536
--- /dev/null
+++ b/lib/inets/test/httpd_test_data/server_root/cgi-bin/printenv.bat
@@ -0,0 +1,9 @@
+@echo off
+echo tomrad > c:\cygwin\tmp\hej
+echo Content-type: text/html
+echo.
+echo ^<HTML^> ^<HEAD^> ^<TITLE^>OS Environment^</TITLE^> ^</HEAD^> ^<BODY^>^<PRE^>
+set
+echo ^</PRE^>^</BODY^>^</HTML^>
+
+
diff --git a/lib/inets/test/httpd_test_data/server_root/cgi-bin/printenv.sh b/lib/inets/test/httpd_test_data/server_root/cgi-bin/printenv.sh
new file mode 100755
index 0000000000..de81de9bde
--- /dev/null
+++ b/lib/inets/test/httpd_test_data/server_root/cgi-bin/printenv.sh
@@ -0,0 +1,6 @@
+#!/bin/sh
+echo "Content-type: text/html"
+echo ""
+echo "<HTML> <HEAD> <TITLE>OS Environment</TITLE> </HEAD> <BODY><PRE>"
+env
+echo "</PRE></BODY></HTML>" \ No newline at end of file
diff --git a/lib/inets/test/httpd_test_data/server_root/conf/8080.conf b/lib/inets/test/httpd_test_data/server_root/conf/8080.conf
new file mode 100644
index 0000000000..48e66f0114
--- /dev/null
+++ b/lib/inets/test/httpd_test_data/server_root/conf/8080.conf
@@ -0,0 +1,79 @@
+Port 8080
+#ServerName your.server.net
+SocketType ip_comm
+Modules mod_alias mod_auth mod_esi mod_actions mod_cgi mod_include mod_dir mod_get mod_head mod_log mod_disk_log
+ServerAdmin [email protected]
+ServerRoot /var/tmp/server_root
+ErrorLog logs/error_log_8080
+TransferLog logs/access_log_8080
+SecurityLog logs/security_log_8080
+ErrorDiskLog logs/error_disk_log_8080
+ErrorDiskLogSize 200000 10
+TransferDiskLog logs/access_disk_log_8080
+TransferDiskLogSize 200000 10
+SecurityDiskLog logs/security_disk_log
+SecurityDiskLogSize 200000 10
+MaxClients 50
+#KeepAlive 5
+#KeepAliveTimeout 10
+DocumentRoot /var/tmp/server_root/htdocs
+DirectoryIndex index.html welcome.html
+DefaultType text/plain
+Alias /icons/ /var/tmp/server_root/icons/
+Alias /pics/ /var/tmp/server_root/icons/
+ScriptAlias /cgi-bin/ /var/tmp/server_root/cgi-bin/
+ScriptAlias /htbin/ /var/tmp/server_root/cgi-bin/
+ErlScriptAlias /cgi-bin/erl httpd_example io
+EvalScriptAlias /eval httpd_example io
+#Script HEAD /cgi-bin/printenv.sh
+#Action image/gif /cgi-bin/printenv.sh
+
+<Directory /var/tmp/server_root/htdocs/open>
+AuthDBType plain
+AuthName Open Area
+AuthUserFile /var/tmp/server_root/auth/passwd
+AuthGroupFile /var/tmp/server_root/auth/group
+require user one Aladdin
+</Directory>
+
+<Directory /var/tmp/server_root/htdocs/secret>
+AuthDBType plain
+AuthName Secret Area
+AuthUserFile /var/tmp/server_root/auth/passwd
+AuthGroupFile /var/tmp/server_root/auth/group
+require group group1 group2
+</Directory>
+
+<Directory /var/tmp/server_root/htdocs/secret/top_secret>
+AuthDBType plain
+AuthName Top Secret Area
+AuthUserFile /var/tmp/server_root/auth/passwd
+AuthGroupFile /var/tmp/server_root/auth/group
+require group group3
+</Directory>
+
+<Directory /var/tmp/server_root/htdocs/mnesia_open>
+AuthDBType mnesia
+AuthName Open Area
+require user one Aladdin
+</Directory>
+
+<Directory /var/tmp/server_root/htdocs/mnesia_secret>
+AuthDBType mnesia
+AuthName Secret Area
+require group group1 group2
+</Directory>
+
+<Directory /var/tmp/server_root/htdocs/mnesia_secret/top_secret>
+AuthDBType mnesia
+AuthName Top Secret Area
+require group group3
+allow from 130.100.34 130.100.35
+deny from 100.234.22.12 194.100.34.1 130.100.34.25
+SecurityDataFile logs/security_data
+SecurityMaxRetries 3
+SecurityBlockTime 10
+SecurityFailExpireTime 1
+SecurityAuthTimeout 1
+SecurityCallbackModule security_callback
+</Directory>
diff --git a/lib/inets/test/httpd_test_data/server_root/conf/8888.conf b/lib/inets/test/httpd_test_data/server_root/conf/8888.conf
new file mode 100644
index 0000000000..79bb7fcca4
--- /dev/null
+++ b/lib/inets/test/httpd_test_data/server_root/conf/8888.conf
@@ -0,0 +1,63 @@
+Port 8888
+#ServerName your.server.net
+SocketType ip_comm
+Modules mod_alias mod_auth mod_esi mod_actions mod_cgi mod_include mod_dir mod_get mod_head mod_log mod_disk_log
+ServerAdmin [email protected]
+ServerRoot /var/tmp/server_root
+ErrorLog logs/error_log_8888
+TransferLog logs/access_log_8888
+ErrorDiskLog logs/error_disk_log_8888
+ErrorDiskLogSize 200000 10
+TransferDiskLog logs/access_disk_log_8888
+TransferDiskLogSize 200000 10
+MaxClients 150
+DocumentRoot /var/tmp/server_root/htdocs
+DirectoryIndex index.html welcome.html
+DefaultType text/plain
+Alias /icons/ /var/tmp/server_root/icons/
+Alias /pics/ /var/tmp/server_root/icons/
+ScriptAlias /cgi-bin/ /var/tmp/server_root/cgi-bin/
+ScriptAlias /htbin/ /var/tmp/server_root/cgi-bin/
+ErlScriptAlias /cgi-bin/erl httpd_example io
+EvalScriptAlias /eval httpd_example io
+#Script HEAD /cgi-bin/printenv.sh
+#Action image/gif /cgi-bin/printenv.sh
+
+<Directory /var/tmp/server_root/htdocs/open>
+AuthName Open Area
+AuthUserFile /var/tmp/server_root/auth/passwd
+AuthGroupFile /var/tmp/server_root/auth/group
+require user one Aladdin
+</Directory>
+
+<Directory /var/tmp/server_root/htdocs/secret>
+AuthName Secret Area
+AuthUserFile /var/tmp/server_root/auth/passwd
+AuthGroupFile /var/tmp/server_root/auth/group
+require group group1 group2
+</Directory>
+
+<Directory /var/tmp/server_root/htdocs/secret/top_secret>
+AuthName Top Secret Area
+AuthUserFile /var/tmp/server_root/auth/passwd
+AuthGroupFile /var/tmp/server_root/auth/group
+require group group3
+</Directory>
+
+<Directory /var/tmp/server_root/htdocs/mnesia_open>
+AuthName Open Area
+AuthMnesiaDB On
+require user one Aladdin
+</Directory>
+
+<Directory /var/tmp/server_root/htdocs/mnesia_secret>
+AuthName Secret Area
+AuthMnesiaDB On
+require group group1 group2
+</Directory>
+
+<Directory /var/tmp/server_root/htdocs/mnesia_secret/top_secret>
+AuthName Top Secret Area
+AuthMnesiaDB On
+require group group3
+</Directory>
diff --git a/lib/inets/test/httpd_test_data/server_root/conf/httpd.conf b/lib/inets/test/httpd_test_data/server_root/conf/httpd.conf
new file mode 100644
index 0000000000..8a74ed1afd
--- /dev/null
+++ b/lib/inets/test/httpd_test_data/server_root/conf/httpd.conf
@@ -0,0 +1,268 @@
+#
+# %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%
+#
+#
+
+# Port: The port the standalone listens to. For ports < 1023, you will
+# need httpd to be run as root initially.
+
+Port 8888
+
+# BindAddress: This directive is used to tell the server which IP address
+# to listen to. It can either contain "*", an IP address, or a fully
+# qualified Internet domain name.
+#
+# It is also possible to specify the ip-family with the directive.
+# There ar three possible value: inet, inet6 and inet6fb4
+# inet: Use IpFamily inet when retreiving the address and
+# fail if that does not work.
+# inet6: Use IpFamily inet6 when retreiving the address and
+# fail if that does not work.
+# inet6fb4: First IpFamily inet6 is tried and if that does not work,
+# inet is used as fallback.
+# Default value for ip-family is inet6fb4
+#
+# The syntax is: <address>[|<ip-family>]
+#
+#BindAddress *
+#BindAddress *|inet
+
+
+# ServerName allows you to set a host name which is sent back to clients for
+# your server if it's different than the one the program would get (i.e. use
+# "www" instead of the host's real name).
+#
+# Note: You cannot just invent host names and hope they work. The name you
+# define here must be a valid DNS name for your host. If you don't understand
+# this, ask your network administrator.
+
+#ServerName your.server.net
+
+# SocketType is either ip_comm, sockets or ssl.
+
+SocketType ip_comm
+
+# Modules: Server run-time plug-in modules written using the Erlang
+# Web Server API (EWSAPI). The server API make it easy to add functionality
+# to the server. Read more about EWSAPI in the Reference Manual.
+# WARNING! Do not tamper with this directive unless you are familiar with
+# EWSAPI.
+
+Modules mod_alias mod_auth mod_esi mod_actions mod_cgi mod_responsecontrol mod_trace mod_range mod_head mod_include mod_dir mod_get mod_log mod_disk_log
+
+# ServerAdmin: Your address, where problems with the server should be
+# e-mailed.
+
+ServerAdmin [email protected]
+
+# ServerRoot: The directory the server's config, error, and log files
+# are kept in
+
+ServerRoot /var/tmp/server_root
+
+# ErrorLog: The location of the error log file. If this does not start
+# with /, ServerRoot is prepended to it.
+
+ErrorLog logs/error_log
+
+# TransferLog: The location of the transfer log file. If this does not
+# start with /, ServerRoot is prepended to it.
+
+TransferLog logs/access_log
+
+# SecurityLog: The location of the security log file (mod_security required)
+#
+SecurityLog logs/security_log
+
+# ErrorDiskLog: The location of the error log file. If this does not
+# start with /, ServerRoot is prepended to it. This log file is managed
+# with the disk_log module [See disk_log(3)]. The ErrorDiskLogSize directive
+# takes two argument, i.e. MaxBytes and MaxFiles. The wrap log writes at most
+# MaxBytes bytes on each file, and it uses MaxFiles files before it wraps, and
+# truncates the first file.
+
+ErrorDiskLog logs/error_disk_log
+ErrorDiskLogSize 200000 10
+
+# TransferDiskLog: The location of the transfer log file. If this does not
+# start with /, ServerRoot is prepended to it. This log file is managed
+# with the disk_log module [See disk_log(3)]. The TransferDiskLogSize directive
+# takes two argument, i.e. MaxBytes and MaxFiles. The wrap log writes at most
+# MaxBytes bytes on each file, and it uses MaxFiles files before it wraps, and
+# truncates the first file.
+
+TransferDiskLog logs/access_disk_log
+TransferDiskLogSize 200000 10
+
+# SecurityDiskLog: The location of the security log file. If this does not
+# start with /, ServerRoot is prepended to it. This log file is managed
+# with the disk_log module [See disk_log(3)]. The SecurityDiskLogSize directive
+# takes two argument, i.e. MaxBytes and MaxFiles. The wrap log writes at most
+# MaxBytes bytes on each file, and it uses MaxFiles files before it wraps, and
+# truncates the first file.
+
+SecurityDiskLog logs/security_disk_log
+SecurityDiskLogSize 200000 10
+
+# Limit on total number of servers running, i.e., limit on the number
+# of clients who can simultaneously connect --- if this limit is ever
+# reached, clients will be LOCKED OUT, so it should NOT BE SET TOO LOW.
+# It is intended mainly as a brake to keep a runaway server from taking
+# the server with it as it spirals down...
+
+MaxClients 50
+
+# KeepAlive set the flag for persistent connections. For peristent connections
+# set KeepAlive to on. To use One request per connection set the flag to off
+# Note: The value has changed since previous version of INETS.
+KeepAlive on
+
+# KeepAliveTimeout sets the number of seconds before a persistent connection
+# times out and closes.
+KeepAliveTimeout 10
+
+# MaxKeepAliveRequests sets the number of seconds before a persistent connection
+# times out and closes.
+MaxKeepAliveRequests 10
+
+
+
+# DocumentRoot: The directory out of which you will serve your
+# documents. By default, all requests are taken from this directory, but
+# symbolic links and aliases may be used to point to other locations.
+
+DocumentRoot /var/tmp/server_root/htdocs
+
+# DirectoryIndex: Name of the file or files to use as a pre-written HTML
+# directory index. Separate multiple entries with spaces.
+
+DirectoryIndex index.html welcome.html
+
+# DefaultType is the default MIME type for documents which the server
+# cannot find the type of from filename extensions.
+
+DefaultType text/plain
+
+# Aliases: Add here as many aliases as you need (with no limit). The format is
+# Alias fakename realname
+
+Alias /icons/ /var/tmp/server_root/icons/
+Alias /pics/ /var/tmp/server_root/icons/
+
+# ScriptAlias: This controls which directories contain server scripts.
+# Format: ScriptAlias fakename realname
+
+ScriptAlias /cgi-bin/ /var/tmp/server_root/cgi-bin/
+ScriptAlias /htbin/ /var/tmp/server_root/cgi-bin/
+
+# This directive adds an action, which will activate cgi-script when a
+# file is requested using the method of method, which can be one of
+# GET, POST and HEAD. It sends the URL and file path of the requested
+# document using the standard CGI PATH_INFO and PATH_TRANSLATED
+# environment variables.
+
+#Script HEAD /cgi-bin/printenv.sh
+
+# This directive adds an action, which will activate cgi-script when a
+# file of content type mime-type is requested. It sends the URL and
+# file path of the requested document using the standard CGI PATH_INFO
+# and PATH_TRANSLATED environment variables.
+
+#Action image/gif /cgi-bin/printenv.sh
+
+# ErlScriptAlias: This specifies how "Erl" server scripts are called.
+# Format: ErlScriptAlias fakename realname allowed_modules
+
+ErlScriptAlias /down/erl httpd_example io
+
+# EvalScriptAlias: This specifies how "Eval" server scripts are called.
+# Format: EvalScriptAlias fakename realname allowed_modules
+
+EvalScriptAlias /eval httpd_example io
+
+# Point SSLCertificateFile at a PEM encoded certificate.
+
+SSLCertificateFile /var/tmp/server_root/ssl/ssl_server.pem
+
+# If the key is not combined with the certificate, use this directive to
+# point at the key file.
+
+SSLCertificateKeyFile /var/tmp/server_root/ssl/ssl_server.pem
+
+# Set SSLVerifyClient to:
+# 0 if no certicate is required
+# 1 if the client may present a valid certificate
+# 2 if the client must present a valid certificate
+# 3 if the client may present a valid certificate but it is not required to
+# have a valid CA
+
+SSLVerifyClient 0
+
+# Each directory to which INETS has access, can be configured with respect
+# to which services and features are allowed and/or disabled in that
+# directory (and its subdirectories).
+
+<Directory /var/tmp/server_root/htdocs/open>
+AuthDBType plain
+AuthName Open Area
+AuthUserFile /var/tmp/server_root/auth/passwd
+AuthGroupFile /var/tmp/server_root/auth/group
+require user one Aladdin
+</Directory>
+
+<Directory /var/tmp/server_root/htdocs/secret>
+AuthDBType plain
+AuthName Secret Area
+AuthUserFile /var/tmp/server_root/auth/passwd
+AuthGroupFile /var/tmp/server_root/auth/group
+require group group1 group2
+</Directory>
+
+<Directory /var/tmp/server_root/htdocs/secret/top_secret>
+AuthDBType plain
+AuthName Top Secret Area
+AuthUserFile /var/tmp/server_root/auth/passwd
+AuthGroupFile /var/tmp/server_root/auth/group
+require group group3
+</Directory>
+
+<Directory /var/tmp/server_root/htdocs/mnesia_open>
+AuthDBType mnesia
+AuthName Open Area
+require user one Aladdin
+</Directory>
+
+<Directory /var/tmp/server_root/htdocs/mnesia_secret>
+AuthDBType mnesia
+AuthName Secret Area
+require group group1 group2
+</Directory>
+
+<Directory /var/tmp/server_root/htdocs/mnesia_secret/top_secret>
+AuthDBType mnesia
+AuthName Top Secret Area
+require group group3
+allow from 130.100.34 130.100.35
+deny from 100.234.22.12 194.100.34.1 130.100.34.25
+SecurityDataFile logs/security_data
+SecurityMaxRetries 3
+SecurityBlockTime 10
+SecurityFailExpireTime 1
+SecurityAuthTimeout 1
+SecurityCallbackModule security_callback
+</Directory>
diff --git a/lib/inets/test/httpd_test_data/server_root/conf/mime.types b/lib/inets/test/httpd_test_data/server_root/conf/mime.types
new file mode 100644
index 0000000000..d2f81e4e5e
--- /dev/null
+++ b/lib/inets/test/httpd_test_data/server_root/conf/mime.types
@@ -0,0 +1,465 @@
+# This is a comment. I love comments.
+
+# MIME type Extension
+application/EDI-Consent
+application/EDI-X12
+application/EDIFACT
+application/activemessage
+application/andrew-inset ez
+application/applefile
+application/atomicmail
+application/batch-SMTP
+application/beep+xml
+application/cals-1840
+application/commonground
+application/cybercash
+application/dca-rft
+application/dec-dx
+application/dvcs
+application/eshop
+application/http
+application/hyperstudio
+application/iges
+application/index
+application/index.cmd
+application/index.obj
+application/index.response
+application/index.vnd
+application/iotp
+application/ipp
+application/isup
+application/font-tdpfr
+application/mac-binhex40 hqx
+application/mac-compactpro cpt
+application/macwriteii
+application/marc
+application/mathematica
+application/mathematica-old
+application/msword doc
+application/news-message-id
+application/news-transmission
+application/ocsp-request
+application/ocsp-response
+application/octet-stream bin dms lha lzh exe class so dll
+application/oda oda
+application/parityfec
+application/pdf pdf
+application/pgp-encrypted
+application/pgp-keys
+application/pgp-signature
+application/pkcs10
+application/pkcs7-mime
+application/pkcs7-signature
+application/pkix-cert
+application/pkix-crl
+application/pkixcmp
+application/postscript ai eps ps
+application/prs.alvestrand.titrax-sheet
+application/prs.cww
+application/prs.nprend
+application/qsig
+application/remote-printing
+application/riscos
+application/rtf
+application/sdp
+application/set-payment
+application/set-payment-initiation
+application/set-registration
+application/set-registration-initiation
+application/sgml
+application/sgml-open-catalog
+application/sieve
+application/slate
+application/smil smi smil
+application/timestamp-query
+application/timestamp-reply
+application/vemmi
+application/vnd.3M.Post-it-Notes
+application/vnd.FloGraphIt
+application/vnd.accpac.simply.aso
+application/vnd.accpac.simply.imp
+application/vnd.acucobol
+application/vnd.aether.imp
+application/vnd.anser-web-certificate-issue-initiation
+application/vnd.anser-web-funds-transfer-initiation
+application/vnd.audiograph
+application/vnd.businessobjects
+application/vnd.bmi
+application/vnd.canon-cpdl
+application/vnd.canon-lips
+application/vnd.claymore
+application/vnd.commerce-battelle
+application/vnd.commonspace
+application/vnd.comsocaller
+application/vnd.contact.cmsg
+application/vnd.cosmocaller
+application/vnd.cups-postscript
+application/vnd.cups-raster
+application/vnd.cups-raw
+application/vnd.ctc-posml
+application/vnd.cybank
+application/vnd.dna
+application/vnd.dpgraph
+application/vnd.dxr
+application/vnd.ecdis-update
+application/vnd.ecowin.chart
+application/vnd.ecowin.filerequest
+application/vnd.ecowin.fileupdate
+application/vnd.ecowin.series
+application/vnd.ecowin.seriesrequest
+application/vnd.ecowin.seriesupdate
+application/vnd.enliven
+application/vnd.epson.esf
+application/vnd.epson.msf
+application/vnd.epson.quickanime
+application/vnd.epson.salt
+application/vnd.epson.ssf
+application/vnd.ericsson.quickcall
+application/vnd.eudora.data
+application/vnd.fdf
+application/vnd.ffsns
+application/vnd.framemaker
+application/vnd.fsc.weblaunch
+application/vnd.fujitsu.oasys
+application/vnd.fujitsu.oasys2
+application/vnd.fujitsu.oasys3
+application/vnd.fujitsu.oasysgp
+application/vnd.fujitsu.oasysprs
+application/vnd.fujixerox.ddd
+application/vnd.fujixerox.docuworks
+application/vnd.fujixerox.docuworks.binder
+application/vnd.fut-misnet
+application/vnd.grafeq
+application/vnd.groove-account
+application/vnd.groove-identity-message
+application/vnd.groove-injector
+application/vnd.groove-tool-message
+application/vnd.groove-tool-template
+application/vnd.groove-vcard
+application/vnd.hhe.lesson-player
+application/vnd.hp-HPGL
+application/vnd.hp-PCL
+application/vnd.hp-PCLXL
+application/vnd.hp-hpid
+application/vnd.hp-hps
+application/vnd.httphone
+application/vnd.hzn-3d-crossword
+application/vnd.ibm.afplinedata
+application/vnd.ibm.MiniPay
+application/vnd.ibm.modcap
+application/vnd.informix-visionary
+application/vnd.intercon.formnet
+application/vnd.intertrust.digibox
+application/vnd.intertrust.nncp
+application/vnd.intu.qbo
+application/vnd.intu.qfx
+application/vnd.irepository.package+xml
+application/vnd.is-xpr
+application/vnd.japannet-directory-service
+application/vnd.japannet-jpnstore-wakeup
+application/vnd.japannet-payment-wakeup
+application/vnd.japannet-registration
+application/vnd.japannet-registration-wakeup
+application/vnd.japannet-setstore-wakeup
+application/vnd.japannet-verification
+application/vnd.japannet-verification-wakeup
+application/vnd.koan
+application/vnd.lotus-1-2-3
+application/vnd.lotus-approach
+application/vnd.lotus-freelance
+application/vnd.lotus-notes
+application/vnd.lotus-organizer
+application/vnd.lotus-screencam
+application/vnd.lotus-wordpro
+application/vnd.mcd
+application/vnd.mediastation.cdkey
+application/vnd.meridian-slingshot
+application/vnd.mif mif
+application/vnd.minisoft-hp3000-save
+application/vnd.mitsubishi.misty-guard.trustweb
+application/vnd.mobius.daf
+application/vnd.mobius.dis
+application/vnd.mobius.msl
+application/vnd.mobius.plc
+application/vnd.mobius.txf
+application/vnd.motorola.flexsuite
+application/vnd.motorola.flexsuite.adsi
+application/vnd.motorola.flexsuite.fis
+application/vnd.motorola.flexsuite.gotap
+application/vnd.motorola.flexsuite.kmr
+application/vnd.motorola.flexsuite.ttc
+application/vnd.motorola.flexsuite.wem
+application/vnd.mozilla.xul+xml
+application/vnd.ms-artgalry
+application/vnd.ms-asf
+application/vnd.ms-excel xls
+application/vnd.ms-lrm
+application/vnd.ms-powerpoint ppt
+application/vnd.ms-project
+application/vnd.ms-tnef
+application/vnd.ms-works
+application/vnd.mseq
+application/vnd.msign
+application/vnd.music-niff
+application/vnd.musician
+application/vnd.netfpx
+application/vnd.noblenet-directory
+application/vnd.noblenet-sealer
+application/vnd.noblenet-web
+application/vnd.novadigm.EDM
+application/vnd.novadigm.EDX
+application/vnd.novadigm.EXT
+application/vnd.osa.netdeploy
+application/vnd.palm
+application/vnd.pg.format
+application/vnd.pg.osasli
+application/vnd.powerbuilder6
+application/vnd.powerbuilder6-s
+application/vnd.powerbuilder7
+application/vnd.powerbuilder7-s
+application/vnd.powerbuilder75
+application/vnd.powerbuilder75-s
+application/vnd.previewsystems.box
+application/vnd.publishare-delta-tree
+application/vnd.pvi.ptid1
+application/vnd.pwg-xhtml-print+xml
+application/vnd.rapid
+application/vnd.s3sms
+application/vnd.seemail
+application/vnd.shana.informed.formdata
+application/vnd.shana.informed.formtemplate
+application/vnd.shana.informed.interchange
+application/vnd.shana.informed.package
+application/vnd.sss-cod
+application/vnd.sss-dtf
+application/vnd.sss-ntf
+application/vnd.street-stream
+application/vnd.svd
+application/vnd.swiftview-ics
+application/vnd.triscape.mxs
+application/vnd.trueapp
+application/vnd.truedoc
+application/vnd.tve-trigger
+application/vnd.ufdl
+application/vnd.uplanet.alert
+application/vnd.uplanet.alert-wbxml
+application/vnd.uplanet.bearer-choice-wbxml
+application/vnd.uplanet.bearer-choice
+application/vnd.uplanet.cacheop
+application/vnd.uplanet.cacheop-wbxml
+application/vnd.uplanet.channel
+application/vnd.uplanet.channel-wbxml
+application/vnd.uplanet.list
+application/vnd.uplanet.list-wbxml
+application/vnd.uplanet.listcmd
+application/vnd.uplanet.listcmd-wbxml
+application/vnd.uplanet.signal
+application/vnd.vcx
+application/vnd.vectorworks
+application/vnd.vidsoft.vidconference
+application/vnd.visio
+application/vnd.vividence.scriptfile
+application/vnd.wap.sic
+application/vnd.wap.slc
+application/vnd.wap.wbxml wbxml
+application/vnd.wap.wmlc wmlc
+application/vnd.wap.wmlscriptc wmlsc
+application/vnd.webturbo
+application/vnd.wrq-hp3000-labelled
+application/vnd.wt.stf
+application/vnd.xara
+application/vnd.xfdl
+application/vnd.yellowriver-custom-menu
+application/whoispp-query
+application/whoispp-response
+application/wita
+application/wordperfect5.1
+application/x-bcpio bcpio
+application/x-cdlink vcd
+application/x-chess-pgn pgn
+application/x-compress
+application/x-cpio cpio
+application/x-csh csh
+application/x-director dcr dir dxr
+application/x-dvi dvi
+application/x-futuresplash spl
+application/x-gtar gtar
+application/x-gzip
+application/x-hdf hdf
+application/x-javascript js
+application/x-koan skp skd skt skm
+application/x-latex latex
+application/x-netcdf nc cdf
+application/x-sh sh
+application/x-shar shar
+application/x-shockwave-flash swf
+application/x-stuffit sit
+application/x-sv4cpio sv4cpio
+application/x-sv4crc sv4crc
+application/x-tar tar
+application/x-tcl tcl
+application/x-tex tex
+application/x-texinfo texinfo texi
+application/x-troff t tr roff
+application/x-troff-man man
+application/x-troff-me me
+application/x-troff-ms ms
+application/x-ustar ustar
+application/x-wais-source src
+application/x400-bp
+application/xml
+application/xml-dtd
+application/xml-external-parsed-entity
+application/zip zip
+audio/32kadpcm
+audio/basic au snd
+audio/g.722.1
+audio/l16
+audio/midi mid midi kar
+audio/mp4a-latm
+audio/mpa-robust
+audio/mpeg mpga mp2 mp3
+audio/parityfec
+audio/prs.sid
+audio/telephone-event
+audio/tone
+audio/vnd.cisco.nse
+audio/vnd.cns.anp1
+audio/vnd.cns.inf1
+audio/vnd.digital-winds
+audio/vnd.everad.plj
+audio/vnd.lucent.voice
+audio/vnd.nortel.vbk
+audio/vnd.nuera.ecelp4800
+audio/vnd.nuera.ecelp7470
+audio/vnd.nuera.ecelp9600
+audio/vnd.octel.sbc
+audio/vnd.qcelp
+audio/vnd.rhetorex.32kadpcm
+audio/vnd.vmx.cvsd
+audio/x-aiff aif aiff aifc
+audio/x-mpegurl m3u
+audio/x-pn-realaudio ram rm
+audio/x-pn-realaudio-plugin rpm
+audio/x-realaudio ra
+audio/x-wav wav
+chemical/x-pdb pdb
+chemical/x-xyz xyz
+image/bmp bmp
+image/cgm
+image/g3fax
+image/gif gif
+image/ief ief
+image/jpeg jpeg jpg jpe
+image/naplps
+image/png png
+image/prs.btif
+image/prs.pti
+image/tiff tiff tif
+image/vnd.cns.inf2
+image/vnd.dwg
+image/vnd.dxf
+image/vnd.fastbidsheet
+image/vnd.fpx
+image/vnd.fst
+image/vnd.fujixerox.edmics-mmr
+image/vnd.fujixerox.edmics-rlc
+image/vnd.mix
+image/vnd.net-fpx
+image/vnd.svf
+image/vnd.wap.wbmp wbmp
+image/vnd.xiff
+image/x-cmu-raster ras
+image/x-portable-anymap pnm
+image/x-portable-bitmap pbm
+image/x-portable-graymap pgm
+image/x-portable-pixmap ppm
+image/x-rgb rgb
+image/x-xbitmap xbm
+image/x-xpixmap xpm
+image/x-xwindowdump xwd
+message/delivery-status
+message/disposition-notification
+message/external-body
+message/http
+message/news
+message/partial
+message/rfc822
+message/s-http
+model/iges igs iges
+model/mesh msh mesh silo
+model/vnd.dwf
+model/vnd.flatland.3dml
+model/vnd.gdl
+model/vnd.gs-gdl
+model/vnd.gtw
+model/vnd.mts
+model/vnd.vtu
+model/vrml wrl vrml
+multipart/alternative
+multipart/appledouble
+multipart/byteranges
+multipart/digest
+multipart/encrypted
+multipart/form-data
+multipart/header-set
+multipart/mixed
+multipart/parallel
+multipart/related
+multipart/report
+multipart/signed
+multipart/voice-message
+text/calendar
+text/css css
+text/directory
+text/enriched
+text/html html htm
+text/parityfec
+text/plain asc txt
+text/prs.lines.tag
+text/rfc822-headers
+text/richtext rtx
+text/rtf rtf
+text/sgml sgml sgm
+text/tab-separated-values tsv
+text/t140
+text/uri-list
+text/vnd.DMClientScript
+text/vnd.IPTC.NITF
+text/vnd.IPTC.NewsML
+text/vnd.abc
+text/vnd.curl
+text/vnd.flatland.3dml
+text/vnd.fly
+text/vnd.fmi.flexstor
+text/vnd.in3d.3dml
+text/vnd.in3d.spot
+text/vnd.latex-z
+text/vnd.motorola.reflex
+text/vnd.ms-mediapackage
+text/vnd.wap.si
+text/vnd.wap.sl
+text/vnd.wap.wml wml
+text/vnd.wap.wmlscript wmls
+text/x-setext etx
+text/x-server-parsed-html shtml
+text/xml xml xsl
+text/xml-external-parsed-entity
+video/mp4v-es
+video/mpeg mpeg mpg mpe
+video/parityfec
+video/pointer
+video/quicktime qt mov
+video/vnd.fvt
+video/vnd.motorola.video
+video/vnd.motorola.videop
+video/vnd.mpegurl mxu
+video/vnd.mts
+video/vnd.nokia.interleaved-multimedia
+video/vnd.vivo
+video/x-msvideo avi
+video/x-sgi-movie movie
+x-conference/x-cooltalk ice
+
+
+
diff --git a/lib/inets/test/httpd_test_data/server_root/conf/ssl.conf b/lib/inets/test/httpd_test_data/server_root/conf/ssl.conf
new file mode 100644
index 0000000000..8b8c57a98b
--- /dev/null
+++ b/lib/inets/test/httpd_test_data/server_root/conf/ssl.conf
@@ -0,0 +1,66 @@
+Port 8088
+#ServerName your.server.net
+SocketType ssl
+Modules mod_alias mod_auth mod_esi mod_actions mod_cgi mod_include mod_dir mod_get mod_head mod_log mod_disk_log
+ServerAdmin [email protected]
+ServerRoot /var/tmp/server_root
+ErrorLog logs/error_log_8088
+TransferLog logs/access_log_8088
+ErrorDiskLog logs/error_disk_log_8088
+ErrorDiskLogSize 200000 10
+TransferDiskLog logs/access_disk_log_8088
+TransferDiskLogSize 200000 10
+MaxClients 150
+DocumentRoot /var/tmp/server_root/htdocs
+DirectoryIndex index.html welcome.html
+DefaultType text/plain
+Alias /icons/ /var/tmp/server_root/icons/
+Alias /pics/ /var/tmp/server_root/icons/
+ScriptAlias /cgi-bin/ /var/tmp/server_root/cgi-bin/
+ScriptAlias /htbin/ /var/tmp/server_root/cgi-bin/
+ErlScriptAlias /cgi-bin/erl httpd_example io
+EvalScriptAlias /eval httpd_example io
+SSLCertificateFile /var/tmp/server_root/ssl/ssl_server.pem
+SSLCertificateKeyFile /var/tmp/server_root/ssl/ssl_server.pem
+SSLVerifyClient 0
+#Script HEAD /cgi-bin/printenv.sh
+#Action image/gif /cgi-bin/printenv.sh
+
+<Directory /var/tmp/server_root/htdocs/open>
+AuthName Open Area
+AuthUserFile /var/tmp/server_root/auth/passwd
+AuthGroupFile /var/tmp/server_root/auth/group
+require user one Aladdin
+</Directory>
+
+<Directory /var/tmp/server_root/htdocs/secret>
+AuthName Secret Area
+AuthUserFile /var/tmp/server_root/auth/passwd
+AuthGroupFile /var/tmp/server_root/auth/group
+require group group1 group2
+</Directory>
+
+<Directory /var/tmp/server_root/htdocs/secret/top_secret>
+AuthName Top Secret Area
+AuthUserFile /var/tmp/server_root/auth/passwd
+AuthGroupFile /var/tmp/server_root/auth/group
+require group group3
+</Directory>
+
+<Directory /var/tmp/server_root/htdocs/mnesia_open>
+AuthName Open Area
+AuthMnesiaDB On
+require user one Aladdin
+</Directory>
+
+<Directory /var/tmp/server_root/htdocs/mnesia_secret>
+AuthName Secret Area
+AuthMnesiaDB On
+require group group1 group2
+</Directory>
+
+<Directory /var/tmp/server_root/htdocs/mnesia_secret/top_secret>
+AuthName Top Secret Area
+AuthMnesiaDB On
+require group group3
+</Directory>
diff --git a/lib/inets/test/httpd_test_data/server_root/htdocs/config.shtml b/lib/inets/test/httpd_test_data/server_root/htdocs/config.shtml
new file mode 100644
index 0000000000..107e3ff610
--- /dev/null
+++ b/lib/inets/test/httpd_test_data/server_root/htdocs/config.shtml
@@ -0,0 +1,70 @@
+<HTML>
+<HEAD>
+<TITLE>/ssi.html (17-Apr-1997)</TITLE>
+</HEAD>
+<BODY>
+<H1>/ssi.html</H1>
+
+<!-- ************* CONFIG ************* -->
+
+<!--#config timefmt="%a %b %e %T %Z %Y" sizefmt="abbrev"-->
+<!--#config errmsg="[an especially ugly error occurred while processing this directive]"-->
+
+<!-- ************* INCLUDE ************* -->
+
+<P>Include /misc/friedrich.html:
+<!--#include virtual="/misc/friedrich.html"-->
+<P>Include /misc/not_defined.html: <!--#include virtual="/misc/not_defined.html"-->
+<P>Include misc/friedrich.html:
+<!--#include file="misc/friedrich.html"-->
+<P>Include not_defined.html: <!--#include file="not_defined.html"-->
+
+<P><HR>
+
+<!-- ************* ECHO ************* -->
+
+<P>DOCUMENT_NAME: <!--#echo var="DOCUMENT_NAME"-->
+<P>DOCUMENT_URI: <!--#echo var="DOCUMENT_URI"-->
+<P>QUERY_STRING_UNESCAPED: <!--#echo var="QUERY_STRING_UNESCAPED"-->
+<P>DATE_LOCAL: <!--#echo var="DATE_LOCAL"-->
+<P>DATE_GMT: <!--#echo var="DATE_GMT"-->
+<P>LAST_MODIFIED: <!--#echo var="LAST_MODIFIED"-->
+<P>NOT_DEFINED: <!--#echo var="NOT_DEFINED"-->
+
+<P><HR>
+
+<!-- ************* FSIZE ************* -->
+
+<P>Size of index.html: <!--#fsize file="index.html"-->
+<P>Size of not_defined.html: <!--#fsize file="not_defined.html"-->
+<!--#config sizefmt="bytes"-->
+<P>Size of /misc/friedrich.html: <!--#fsize virtual="/misc/friedrich.html"-->
+<P>Size of /misc/not_defined.html: <!--#fsize virtual="/misc/not_defined.html"-->
+
+<P><HR>
+
+<!-- ************* FLASTMOD ************* -->
+
+<P>Last modification of index.html: <!--#flastmod file="index.html"-->
+<P>Last modification of not_defined.html: <!--#flastmod file="not_defined.html"-->
+<P>Last modification of /misc/friedrich.html: <!--#flastmod virtual="/misc/friedrich.html"-->
+<P>Last modification of /misc/not_defined.html: <!--#flastmod virtual="/misc/not_defined.html"-->
+
+<!--#exec cmd="ls"-->
+<!--#exec cmd="printenv"-->
+<!--#exec cmd="sunemaja"-->
+
+<!--#exec cgi="/cgi-bin/printenv.sh"-->
+
+</BODY>
+</HTML>
+
+
+
+
+
+
+
+
+
+
diff --git a/lib/inets/test/httpd_test_data/server_root/htdocs/dets_open/dummy.html b/lib/inets/test/httpd_test_data/server_root/htdocs/dets_open/dummy.html
new file mode 100644
index 0000000000..a6e8a35a04
--- /dev/null
+++ b/lib/inets/test/httpd_test_data/server_root/htdocs/dets_open/dummy.html
@@ -0,0 +1,10 @@
+<HTML>
+<HEAD>
+<TITLE>/open/dummy.html (17-Apr-1997)</TITLE>
+<!-- Created by: Joakim Greben�, 17-Apr-1997 -->
+<!-- Changed by: Joakim Greben�, 17-Apr-1997 -->
+</HEAD>
+<BODY>
+<H1>/open/dummy.html</H1>
+</BODY>
+</HTML>
diff --git a/lib/inets/test/httpd_test_data/server_root/htdocs/dets_secret/dummy.html b/lib/inets/test/httpd_test_data/server_root/htdocs/dets_secret/dummy.html
new file mode 100644
index 0000000000..016b04e540
--- /dev/null
+++ b/lib/inets/test/httpd_test_data/server_root/htdocs/dets_secret/dummy.html
@@ -0,0 +1,10 @@
+<HTML>
+<HEAD>
+<TITLE>/secret/dummy.html (17-Apr-1997)</TITLE>
+<!-- Created by: Joakim Greben�, 17-Apr-1997 -->
+<!-- Changed by: Joakim Greben�, 17-Apr-1997 -->
+</HEAD>
+<BODY>
+<H1>/secret/dummy.html</H1>
+</BODY>
+</HTML>
diff --git a/lib/inets/test/httpd_test_data/server_root/htdocs/dets_secret/top_secret/index.html b/lib/inets/test/httpd_test_data/server_root/htdocs/dets_secret/top_secret/index.html
new file mode 100644
index 0000000000..34db3d5d1a
--- /dev/null
+++ b/lib/inets/test/httpd_test_data/server_root/htdocs/dets_secret/top_secret/index.html
@@ -0,0 +1,9 @@
+<HTML>
+<HEAD>
+<TITLE>/secret/top_secret/index.html (04-Feb-1998)</TITLE>
+<!-- Created by: Mattias Nilsson, 04-Feb-1998 -->
+</HEAD>
+<BODY>
+<H1>/secret/top_secret/index.html</H1>
+</BODY>
+</HTML>
diff --git a/lib/inets/test/httpd_test_data/server_root/htdocs/echo.shtml b/lib/inets/test/httpd_test_data/server_root/htdocs/echo.shtml
new file mode 100644
index 0000000000..141db5be59
--- /dev/null
+++ b/lib/inets/test/httpd_test_data/server_root/htdocs/echo.shtml
@@ -0,0 +1,35 @@
+<HTML>
+<HEAD>
+<TITLE>/echo.shtml</TITLE>
+</HEAD>
+<BODY>
+<H1>/echo.shtml</H1>
+
+<P>DOCUMENT_NAME: <!--#echo var="DOCUMENT_NAME"-->
+
+<P>DOCUMENT_URI: <!--#echo var="DOCUMENT_URI"-->
+
+<P>QUERY_STRING_UNESCAPED: <!--#echo var="QUERY_STRING_UNESCAPED"-->
+
+<P>DATE_LOCAL: <!--#echo var="DATE_LOCAL"-->
+
+<P>DATE_GMT: <!--#echo var="DATE_GMT"-->
+
+<P>LAST_MODIFIED: <!--#echo var="LAST_MODIFIED"-->
+
+<P>NOT_DEFINED: <!--#echo var="NOT_DEFINED"-->
+
+<P>[<A HREF="ssi.html">Back</A>]
+
+</BODY>
+</HTML>
+
+
+
+
+
+
+
+
+
+
diff --git a/lib/inets/test/httpd_test_data/server_root/htdocs/exec.shtml b/lib/inets/test/httpd_test_data/server_root/htdocs/exec.shtml
new file mode 100644
index 0000000000..97333da898
--- /dev/null
+++ b/lib/inets/test/httpd_test_data/server_root/htdocs/exec.shtml
@@ -0,0 +1,30 @@
+<HTML>
+<HEAD>
+<TITLE>/exec.shtml</TITLE>
+</HEAD>
+<BODY>
+<H1>/exec.shtml</H1>
+<PRE>
+<!--#exec cmd="ls"-->
+<HR>
+<!--#exec cmd="printenv"-->
+<HR>
+<!--#exec cmd="sunemaja"-->
+<HR>
+<!--#exec cgi="/cgi-bin/printenv.sh"-->
+</PRE>
+
+<P>[<A HREF="ssi.html">Back</A>]
+
+</BODY>
+</HTML>
+
+
+
+
+
+
+
+
+
+
diff --git a/lib/inets/test/httpd_test_data/server_root/htdocs/flastmod.shtml b/lib/inets/test/httpd_test_data/server_root/htdocs/flastmod.shtml
new file mode 100644
index 0000000000..d54c36fe50
--- /dev/null
+++ b/lib/inets/test/httpd_test_data/server_root/htdocs/flastmod.shtml
@@ -0,0 +1,29 @@
+<HTML>
+<HEAD>
+<TITLE>/flastmod.shtml</TITLE>
+</HEAD>
+<BODY>
+<H1>/flastmod.shtml</H1>
+
+<P>Last modification of index.html: <!--#flastmod file="index.html"-->
+
+<P>Last modification of not_defined.html: <!--#flastmod file="not_defined.html"-->
+
+<P>Last modification of /misc/friedrich.html: <!--#flastmod virtual="/misc/friedrich.html"-->
+
+<P>Last modification of /misc/not_defined.html: <!--#flastmod virtual="/misc/not_defined.html"-->
+
+<P>[<A HREF="ssi.html">Back</A>]
+
+</BODY>
+</HTML>
+
+
+
+
+
+
+
+
+
+
diff --git a/lib/inets/test/httpd_test_data/server_root/htdocs/fsize.shtml b/lib/inets/test/httpd_test_data/server_root/htdocs/fsize.shtml
new file mode 100644
index 0000000000..570ee9cf6d
--- /dev/null
+++ b/lib/inets/test/httpd_test_data/server_root/htdocs/fsize.shtml
@@ -0,0 +1,29 @@
+<HTML>
+<HEAD>
+<TITLE>/fsize.shtml</TITLE>
+</HEAD>
+<BODY>
+<H1>/fsize.shtml</H1>
+
+<P>Size of index.html: <!--#fsize file="index.html"-->
+
+<P>Size of not_defined.html: <!--#fsize file="not_defined.html"-->
+
+<P>Size of /misc/friedrich.html: <!--#fsize virtual="/misc/friedrich.html"-->
+
+<P>Size of /misc/not_defined.html: <!--#fsize virtual="/misc/not_defined.html"-->
+
+<P>[<A HREF="ssi.html">Back</A>]
+
+</BODY>
+</HTML>
+
+
+
+
+
+
+
+
+
+
diff --git a/lib/inets/test/httpd_test_data/server_root/htdocs/include.shtml b/lib/inets/test/httpd_test_data/server_root/htdocs/include.shtml
new file mode 100644
index 0000000000..529aad0437
--- /dev/null
+++ b/lib/inets/test/httpd_test_data/server_root/htdocs/include.shtml
@@ -0,0 +1,33 @@
+<HTML>
+<HEAD>
+<TITLE>/include.shtml</TITLE>
+</HEAD>
+<BODY>
+<H1>/include.shtml</H1>
+
+<P>Include /misc/friedrich.html:
+<!--#include virtual="/misc/friedrich.html"-->
+
+<P>Include /misc/not_defined.html:
+<!--#include virtual="/misc/not_defined.html"-->
+
+<P>Include misc/friedrich.html:
+<!--#include file="misc/friedrich.html"-->
+
+<P>Include not_defined.html:
+<!--#include file="not_defined.html"-->
+
+<P>[<A HREF="ssi.html">Back</A>]
+
+</BODY>
+</HTML>
+
+
+
+
+
+
+
+
+
+
diff --git a/lib/inets/test/httpd_test_data/server_root/htdocs/index.html b/lib/inets/test/httpd_test_data/server_root/htdocs/index.html
new file mode 100644
index 0000000000..cfdc9f9ab7
--- /dev/null
+++ b/lib/inets/test/httpd_test_data/server_root/htdocs/index.html
@@ -0,0 +1,25 @@
+<HTML>
+<HEAD>
+<TITLE>/index.html</TITLE>
+</HEAD>
+<BODY>
+<H1>/index.html</H1>
+
+<STRONG>Server-Side Include (SSI) commands:</STRONG><BR>
+<A HREF="config.shtml">config</A><BR>
+<A HREF="echo.shtml">echo</A><BR>
+<A HREF="exec.shtml">exec</A><BR>
+<A HREF="flastmod.shtml">flastmod</A><BR>
+<A HREF="fsize.shtml">fsize</A><BR>
+<A HREF="include.shtml">include</A><BR>
+
+<BR>
+<BR>
+
+<STRONG>ESI callback:</STRING><BR>
+<A HREF="cgi-bin/erl/httpd_example/get">cgi-bin/erl/httpd_example/get</A><BR>
+<A HREF="cgi-bin/erl/httpd_example/yahoo">cgi-bin/erl/httpd_example/yahoo</A><BR>
+<A HREF="cgi-bin/erl/httpd_example/test1">cgi-bin/erl/httpd_example/test1</A><BR>
+
+</BODY>
+</HTML>
diff --git a/lib/inets/test/httpd_test_data/server_root/htdocs/last_modified.html b/lib/inets/test/httpd_test_data/server_root/htdocs/last_modified.html
new file mode 100644
index 0000000000..65c1790813
--- /dev/null
+++ b/lib/inets/test/httpd_test_data/server_root/htdocs/last_modified.html
@@ -0,0 +1,22 @@
+<HTML>
+<HEAD>
+<TITLE>/last_modified.html</TITLE>
+</HEAD>
+<BODY>
+<H1>/last_modified.html</H1>
+
+<P>This document is only used for test of illegal last-modified date.</P>
+
+
+</BODY>
+</HTML>
+
+
+
+
+
+
+
+
+
+
diff --git a/lib/inets/test/httpd_test_data/server_root/htdocs/misc/friedrich.html b/lib/inets/test/httpd_test_data/server_root/htdocs/misc/friedrich.html
new file mode 100644
index 0000000000..d7953d5df4
--- /dev/null
+++ b/lib/inets/test/httpd_test_data/server_root/htdocs/misc/friedrich.html
@@ -0,0 +1,7 @@
+<P><CITE>
+Talking much about oneself can also be a means to conceal oneself.<BR>
+-- Friedrich Nietzsche
+</CITE>
+
+<P>Nested Include:
+<!--#include file="misc/oech.html"-->
diff --git a/lib/inets/test/httpd_test_data/server_root/htdocs/misc/oech.html b/lib/inets/test/httpd_test_data/server_root/htdocs/misc/oech.html
new file mode 100644
index 0000000000..506064bf04
--- /dev/null
+++ b/lib/inets/test/httpd_test_data/server_root/htdocs/misc/oech.html
@@ -0,0 +1,4 @@
+<P><CITE>
+What excuses stand in your way? How can you eliminate them?<BR>
+-- Roger von Oech
+</CITE>
diff --git a/lib/inets/test/httpd_test_data/server_root/htdocs/misc/welcome.html b/lib/inets/test/httpd_test_data/server_root/htdocs/misc/welcome.html
new file mode 100644
index 0000000000..8c17451f91
--- /dev/null
+++ b/lib/inets/test/httpd_test_data/server_root/htdocs/misc/welcome.html
@@ -0,0 +1 @@
+<HTML></HTML>
diff --git a/lib/inets/test/httpd_test_data/server_root/htdocs/mnesia_open/dummy.html b/lib/inets/test/httpd_test_data/server_root/htdocs/mnesia_open/dummy.html
new file mode 100644
index 0000000000..a6e8a35a04
--- /dev/null
+++ b/lib/inets/test/httpd_test_data/server_root/htdocs/mnesia_open/dummy.html
@@ -0,0 +1,10 @@
+<HTML>
+<HEAD>
+<TITLE>/open/dummy.html (17-Apr-1997)</TITLE>
+<!-- Created by: Joakim Greben�, 17-Apr-1997 -->
+<!-- Changed by: Joakim Greben�, 17-Apr-1997 -->
+</HEAD>
+<BODY>
+<H1>/open/dummy.html</H1>
+</BODY>
+</HTML>
diff --git a/lib/inets/test/httpd_test_data/server_root/htdocs/mnesia_secret/dummy.html b/lib/inets/test/httpd_test_data/server_root/htdocs/mnesia_secret/dummy.html
new file mode 100644
index 0000000000..016b04e540
--- /dev/null
+++ b/lib/inets/test/httpd_test_data/server_root/htdocs/mnesia_secret/dummy.html
@@ -0,0 +1,10 @@
+<HTML>
+<HEAD>
+<TITLE>/secret/dummy.html (17-Apr-1997)</TITLE>
+<!-- Created by: Joakim Greben�, 17-Apr-1997 -->
+<!-- Changed by: Joakim Greben�, 17-Apr-1997 -->
+</HEAD>
+<BODY>
+<H1>/secret/dummy.html</H1>
+</BODY>
+</HTML>
diff --git a/lib/inets/test/httpd_test_data/server_root/htdocs/mnesia_secret/top_secret/index.html b/lib/inets/test/httpd_test_data/server_root/htdocs/mnesia_secret/top_secret/index.html
new file mode 100644
index 0000000000..2d17e8b596
--- /dev/null
+++ b/lib/inets/test/httpd_test_data/server_root/htdocs/mnesia_secret/top_secret/index.html
@@ -0,0 +1,9 @@
+<HTML>
+<HEAD>
+<TITLE>/mnesia_secret/top_secret/index.html (04-Feb-1998)</TITLE>
+<!-- Created by: Mattias Nilsson, 04-Feb-1998 -->
+</HEAD>
+<BODY>
+<H1>/mnesia_secret/top_secret/index.html</H1>
+</BODY>
+</HTML>
diff --git a/lib/inets/test/httpd_test_data/server_root/htdocs/open/dummy.html b/lib/inets/test/httpd_test_data/server_root/htdocs/open/dummy.html
new file mode 100644
index 0000000000..a6e8a35a04
--- /dev/null
+++ b/lib/inets/test/httpd_test_data/server_root/htdocs/open/dummy.html
@@ -0,0 +1,10 @@
+<HTML>
+<HEAD>
+<TITLE>/open/dummy.html (17-Apr-1997)</TITLE>
+<!-- Created by: Joakim Greben�, 17-Apr-1997 -->
+<!-- Changed by: Joakim Greben�, 17-Apr-1997 -->
+</HEAD>
+<BODY>
+<H1>/open/dummy.html</H1>
+</BODY>
+</HTML>
diff --git a/lib/inets/test/httpd_test_data/server_root/htdocs/secret/dummy.html b/lib/inets/test/httpd_test_data/server_root/htdocs/secret/dummy.html
new file mode 100644
index 0000000000..016b04e540
--- /dev/null
+++ b/lib/inets/test/httpd_test_data/server_root/htdocs/secret/dummy.html
@@ -0,0 +1,10 @@
+<HTML>
+<HEAD>
+<TITLE>/secret/dummy.html (17-Apr-1997)</TITLE>
+<!-- Created by: Joakim Greben�, 17-Apr-1997 -->
+<!-- Changed by: Joakim Greben�, 17-Apr-1997 -->
+</HEAD>
+<BODY>
+<H1>/secret/dummy.html</H1>
+</BODY>
+</HTML>
diff --git a/lib/inets/test/httpd_test_data/server_root/htdocs/secret/top_secret/index.html b/lib/inets/test/httpd_test_data/server_root/htdocs/secret/top_secret/index.html
new file mode 100644
index 0000000000..34db3d5d1a
--- /dev/null
+++ b/lib/inets/test/httpd_test_data/server_root/htdocs/secret/top_secret/index.html
@@ -0,0 +1,9 @@
+<HTML>
+<HEAD>
+<TITLE>/secret/top_secret/index.html (04-Feb-1998)</TITLE>
+<!-- Created by: Mattias Nilsson, 04-Feb-1998 -->
+</HEAD>
+<BODY>
+<H1>/secret/top_secret/index.html</H1>
+</BODY>
+</HTML>
diff --git a/lib/inets/test/httpd_test_data/server_root/icons/README b/lib/inets/test/httpd_test_data/server_root/icons/README
new file mode 100644
index 0000000000..a1fc5a5a9c
--- /dev/null
+++ b/lib/inets/test/httpd_test_data/server_root/icons/README
@@ -0,0 +1,161 @@
+Public Domain Icons
+
+ These icons were originally made for Mosaic for X and have been
+ included in the NCSA httpd and Apache server distributions in the
+ past. They are in the public domain and may be freely included in any
+ application. The originals were done by Kevin Hughes ([email protected]).
+
+ Many thanks to Andy Polyakov for tuning the icon colors and adding a
+ few new images. If you'd like to contribute additions or ideas to
+ this set, please let me know.
+
+ The distribution site for these icons is at:
+
+ http://www.eit.com/goodies/www.icons/
+
+ Kevin Hughes
+ September 11, 1995
+
+
+Suggested Uses
+
+The following are a few suggestions, to serve as a starting point for ideas.
+Please feel free to tweak and rename the icons as you like.
+
+ a.gif
+ This might be used to represent PostScript or text layout
+ languages.
+
+ alert.black.gif, alert.red.gif
+ These can be used to highlight any important items, such as a
+ README file in a directory.
+
+ back.gif, forward.gif
+ These can be used as links to go to previous and next areas.
+
+ ball.gray.gif, ball.red.gif
+ These might be used as bullets.
+
+ binary.gif
+ This can be used to represent binary files.
+
+ binhex.gif
+ This can represent BinHex-encoded data.
+
+ blank.gif
+ This can be used as a placeholder or a spacing element.
+
+ bomb.gif
+ This can be used to repreesnt core files.
+
+ box1.gif, box2.gif
+ These icons can be used to represent generic 3D applications and
+ related files.
+
+ broken.gif
+ This can represent corrupted data.
+
+ burst.gif
+ This can call attention to new and important items.
+
+ c.gif
+ This might represent C source code.
+
+ comp.blue.gif, comp.red.gif
+ These little computer icons can stand for telnet or FTP
+ sessions.
+
+ compressed.gif
+ This may represent compressed data.
+
+ continued.gif
+ This can be a link to a continued listing of a directory.
+
+ down.gif, up.gif, left.gif, right.gif
+ These can be used to scroll up, down, left and right in a
+ listing or may be used to denote items in an outline.
+
+ dvi.gif
+ This can represent DVI files.
+
+ f.gif
+ This might represent FORTRAN or Forth source code.
+
+ folder.gif, folder.open.gif, folder.sec.gif
+ The folder can represent directories. There is also a version
+ that can represent secure directories or directories that cannot
+ be viewed.
+
+ generic.gif, generic.sec.gif, generic.red.gif
+ These can represent generic files, secure files, and important
+ files, respectively.
+
+ hand.right.gif, hand.up.gif
+ These can point out important items (pun intended).
+
+ image1.gif, image2.gif, image3.gif
+ These can represent image formats of various types.
+
+ index.gif
+ This might represent a WAIS index or search facility.
+
+ layout.gif
+ This might represent files and formats that contain graphics as
+ well as text layout, such as HTML and PDF files.
+
+ link.gif
+ This might represent files that are symbolic links.
+
+ movie.gif
+ This can represent various movie formats.
+
+ p.gif
+ This may stand for Perl or Python source code.
+
+ pie0.gif ... pie8.gif
+ These icons can be used in applications where a list of
+ documents is returned from a search. The little pie chart images
+ can denote how relevant the documents may be to your search
+ query.
+
+ patch.gif
+ This may stand for patches and diff files.
+
+ portal.gif
+ This might be a link to an online service or a 3D world.
+
+ ps.gif, quill.gif
+ These may represent PostScript files.
+
+ screw1.gif, screw2.gif
+ These may represent CAD or engineering data and formats.
+
+ script.gif
+ This can represent any of various interpreted languages, such as
+ Perl, python, TCL, and shell scripts, as well as server
+ configuration files.
+
+ sound1.gif, sound2.gif
+ These can represent sound files.
+
+ sphere1.gif, sphere2.gif
+ These can represent 3D worlds or rendering applications and
+ formats.
+
+ tex.gif
+ This can represent TeX files.
+
+ text.gif
+ This can represent generic (plain) text files.
+
+ transfer.gif
+ This can represent FTP transfers or uploads/downloads.
+
+ unknown.gif
+ This may represent a file of an unknown type.
+
+ uuencoded.gif
+ This can stand for uuencoded data.
+
+ world1.gif, world2.gif
+ These can represent 3D worlds or other 3D formats.
diff --git a/lib/inets/test/httpd_test_data/server_root/icons/a.gif b/lib/inets/test/httpd_test_data/server_root/icons/a.gif
new file mode 100644
index 0000000000..bb23d971f4
--- /dev/null
+++ b/lib/inets/test/httpd_test_data/server_root/icons/a.gif
Binary files differ
diff --git a/lib/inets/test/httpd_test_data/server_root/icons/alert.black.gif b/lib/inets/test/httpd_test_data/server_root/icons/alert.black.gif
new file mode 100644
index 0000000000..eaecd2172a
--- /dev/null
+++ b/lib/inets/test/httpd_test_data/server_root/icons/alert.black.gif
Binary files differ
diff --git a/lib/inets/test/httpd_test_data/server_root/icons/alert.red.gif b/lib/inets/test/httpd_test_data/server_root/icons/alert.red.gif
new file mode 100644
index 0000000000..a423894043
--- /dev/null
+++ b/lib/inets/test/httpd_test_data/server_root/icons/alert.red.gif
Binary files differ
diff --git a/lib/inets/test/httpd_test_data/server_root/icons/apache_pb.gif b/lib/inets/test/httpd_test_data/server_root/icons/apache_pb.gif
new file mode 100644
index 0000000000..3a1c139fc4
--- /dev/null
+++ b/lib/inets/test/httpd_test_data/server_root/icons/apache_pb.gif
Binary files differ
diff --git a/lib/inets/test/httpd_test_data/server_root/icons/back.gif b/lib/inets/test/httpd_test_data/server_root/icons/back.gif
new file mode 100644
index 0000000000..a694ae1ec3
--- /dev/null
+++ b/lib/inets/test/httpd_test_data/server_root/icons/back.gif
Binary files differ
diff --git a/lib/inets/test/httpd_test_data/server_root/icons/ball.gray.gif b/lib/inets/test/httpd_test_data/server_root/icons/ball.gray.gif
new file mode 100644
index 0000000000..eb84268c4c
--- /dev/null
+++ b/lib/inets/test/httpd_test_data/server_root/icons/ball.gray.gif
Binary files differ
diff --git a/lib/inets/test/httpd_test_data/server_root/icons/ball.red.gif b/lib/inets/test/httpd_test_data/server_root/icons/ball.red.gif
new file mode 100644
index 0000000000..a8425cb574
--- /dev/null
+++ b/lib/inets/test/httpd_test_data/server_root/icons/ball.red.gif
Binary files differ
diff --git a/lib/inets/test/httpd_test_data/server_root/icons/binary.gif b/lib/inets/test/httpd_test_data/server_root/icons/binary.gif
new file mode 100644
index 0000000000..9a15cbae04
--- /dev/null
+++ b/lib/inets/test/httpd_test_data/server_root/icons/binary.gif
Binary files differ
diff --git a/lib/inets/test/httpd_test_data/server_root/icons/binhex.gif b/lib/inets/test/httpd_test_data/server_root/icons/binhex.gif
new file mode 100644
index 0000000000..62d0363108
--- /dev/null
+++ b/lib/inets/test/httpd_test_data/server_root/icons/binhex.gif
Binary files differ
diff --git a/lib/inets/test/httpd_test_data/server_root/icons/blank.gif b/lib/inets/test/httpd_test_data/server_root/icons/blank.gif
new file mode 100644
index 0000000000..0ccf01e198
--- /dev/null
+++ b/lib/inets/test/httpd_test_data/server_root/icons/blank.gif
Binary files differ
diff --git a/lib/inets/test/httpd_test_data/server_root/icons/bomb.gif b/lib/inets/test/httpd_test_data/server_root/icons/bomb.gif
new file mode 100644
index 0000000000..270fdb1c06
--- /dev/null
+++ b/lib/inets/test/httpd_test_data/server_root/icons/bomb.gif
Binary files differ
diff --git a/lib/inets/test/httpd_test_data/server_root/icons/box1.gif b/lib/inets/test/httpd_test_data/server_root/icons/box1.gif
new file mode 100644
index 0000000000..65dcd002ea
--- /dev/null
+++ b/lib/inets/test/httpd_test_data/server_root/icons/box1.gif
Binary files differ
diff --git a/lib/inets/test/httpd_test_data/server_root/icons/box2.gif b/lib/inets/test/httpd_test_data/server_root/icons/box2.gif
new file mode 100644
index 0000000000..c43bc4faec
--- /dev/null
+++ b/lib/inets/test/httpd_test_data/server_root/icons/box2.gif
Binary files differ
diff --git a/lib/inets/test/httpd_test_data/server_root/icons/broken.gif b/lib/inets/test/httpd_test_data/server_root/icons/broken.gif
new file mode 100644
index 0000000000..9f8cbe9f76
--- /dev/null
+++ b/lib/inets/test/httpd_test_data/server_root/icons/broken.gif
Binary files differ
diff --git a/lib/inets/test/httpd_test_data/server_root/icons/burst.gif b/lib/inets/test/httpd_test_data/server_root/icons/burst.gif
new file mode 100644
index 0000000000..fbdcf575f7
--- /dev/null
+++ b/lib/inets/test/httpd_test_data/server_root/icons/burst.gif
Binary files differ
diff --git a/lib/inets/test/httpd_test_data/server_root/icons/button1.gif b/lib/inets/test/httpd_test_data/server_root/icons/button1.gif
new file mode 100644
index 0000000000..eb97cb7333
--- /dev/null
+++ b/lib/inets/test/httpd_test_data/server_root/icons/button1.gif
Binary files differ
diff --git a/lib/inets/test/httpd_test_data/server_root/icons/button10.gif b/lib/inets/test/httpd_test_data/server_root/icons/button10.gif
new file mode 100644
index 0000000000..fe0c97998c
--- /dev/null
+++ b/lib/inets/test/httpd_test_data/server_root/icons/button10.gif
Binary files differ
diff --git a/lib/inets/test/httpd_test_data/server_root/icons/button2.gif b/lib/inets/test/httpd_test_data/server_root/icons/button2.gif
new file mode 100644
index 0000000000..7698455bf9
--- /dev/null
+++ b/lib/inets/test/httpd_test_data/server_root/icons/button2.gif
Binary files differ
diff --git a/lib/inets/test/httpd_test_data/server_root/icons/button3.gif b/lib/inets/test/httpd_test_data/server_root/icons/button3.gif
new file mode 100644
index 0000000000..a8b8319232
--- /dev/null
+++ b/lib/inets/test/httpd_test_data/server_root/icons/button3.gif
Binary files differ
diff --git a/lib/inets/test/httpd_test_data/server_root/icons/button4.gif b/lib/inets/test/httpd_test_data/server_root/icons/button4.gif
new file mode 100644
index 0000000000..0fd15a0d7f
--- /dev/null
+++ b/lib/inets/test/httpd_test_data/server_root/icons/button4.gif
Binary files differ
diff --git a/lib/inets/test/httpd_test_data/server_root/icons/button5.gif b/lib/inets/test/httpd_test_data/server_root/icons/button5.gif
new file mode 100644
index 0000000000..64241e5c5d
--- /dev/null
+++ b/lib/inets/test/httpd_test_data/server_root/icons/button5.gif
Binary files differ
diff --git a/lib/inets/test/httpd_test_data/server_root/icons/button6.gif b/lib/inets/test/httpd_test_data/server_root/icons/button6.gif
new file mode 100644
index 0000000000..867cfd1212
--- /dev/null
+++ b/lib/inets/test/httpd_test_data/server_root/icons/button6.gif
Binary files differ
diff --git a/lib/inets/test/httpd_test_data/server_root/icons/button7.gif b/lib/inets/test/httpd_test_data/server_root/icons/button7.gif
new file mode 100644
index 0000000000..b3f5fb248f
--- /dev/null
+++ b/lib/inets/test/httpd_test_data/server_root/icons/button7.gif
Binary files differ
diff --git a/lib/inets/test/httpd_test_data/server_root/icons/button8.gif b/lib/inets/test/httpd_test_data/server_root/icons/button8.gif
new file mode 100644
index 0000000000..7a308be8f6
--- /dev/null
+++ b/lib/inets/test/httpd_test_data/server_root/icons/button8.gif
Binary files differ
diff --git a/lib/inets/test/httpd_test_data/server_root/icons/button9.gif b/lib/inets/test/httpd_test_data/server_root/icons/button9.gif
new file mode 100644
index 0000000000..9acba576c0
--- /dev/null
+++ b/lib/inets/test/httpd_test_data/server_root/icons/button9.gif
Binary files differ
diff --git a/lib/inets/test/httpd_test_data/server_root/icons/buttonl.gif b/lib/inets/test/httpd_test_data/server_root/icons/buttonl.gif
new file mode 100644
index 0000000000..3883088e7a
--- /dev/null
+++ b/lib/inets/test/httpd_test_data/server_root/icons/buttonl.gif
Binary files differ
diff --git a/lib/inets/test/httpd_test_data/server_root/icons/buttonr.gif b/lib/inets/test/httpd_test_data/server_root/icons/buttonr.gif
new file mode 100644
index 0000000000..c4dc3887db
--- /dev/null
+++ b/lib/inets/test/httpd_test_data/server_root/icons/buttonr.gif
Binary files differ
diff --git a/lib/inets/test/httpd_test_data/server_root/icons/c.gif b/lib/inets/test/httpd_test_data/server_root/icons/c.gif
new file mode 100644
index 0000000000..7555b6c164
--- /dev/null
+++ b/lib/inets/test/httpd_test_data/server_root/icons/c.gif
Binary files differ
diff --git a/lib/inets/test/httpd_test_data/server_root/icons/comp.blue.gif b/lib/inets/test/httpd_test_data/server_root/icons/comp.blue.gif
new file mode 100644
index 0000000000..f8d76a8c23
--- /dev/null
+++ b/lib/inets/test/httpd_test_data/server_root/icons/comp.blue.gif
Binary files differ
diff --git a/lib/inets/test/httpd_test_data/server_root/icons/comp.gray.gif b/lib/inets/test/httpd_test_data/server_root/icons/comp.gray.gif
new file mode 100644
index 0000000000..7664cd0364
--- /dev/null
+++ b/lib/inets/test/httpd_test_data/server_root/icons/comp.gray.gif
Binary files differ
diff --git a/lib/inets/test/httpd_test_data/server_root/icons/compressed.gif b/lib/inets/test/httpd_test_data/server_root/icons/compressed.gif
new file mode 100644
index 0000000000..39e732739f
--- /dev/null
+++ b/lib/inets/test/httpd_test_data/server_root/icons/compressed.gif
Binary files differ
diff --git a/lib/inets/test/httpd_test_data/server_root/icons/continued.gif b/lib/inets/test/httpd_test_data/server_root/icons/continued.gif
new file mode 100644
index 0000000000..b0ffb7e0cc
--- /dev/null
+++ b/lib/inets/test/httpd_test_data/server_root/icons/continued.gif
Binary files differ
diff --git a/lib/inets/test/httpd_test_data/server_root/icons/dir.gif b/lib/inets/test/httpd_test_data/server_root/icons/dir.gif
new file mode 100644
index 0000000000..48264601ae
--- /dev/null
+++ b/lib/inets/test/httpd_test_data/server_root/icons/dir.gif
Binary files differ
diff --git a/lib/inets/test/httpd_test_data/server_root/icons/down.gif b/lib/inets/test/httpd_test_data/server_root/icons/down.gif
new file mode 100644
index 0000000000..a354c871cd
--- /dev/null
+++ b/lib/inets/test/httpd_test_data/server_root/icons/down.gif
Binary files differ
diff --git a/lib/inets/test/httpd_test_data/server_root/icons/dvi.gif b/lib/inets/test/httpd_test_data/server_root/icons/dvi.gif
new file mode 100644
index 0000000000..791be33105
--- /dev/null
+++ b/lib/inets/test/httpd_test_data/server_root/icons/dvi.gif
Binary files differ
diff --git a/lib/inets/test/httpd_test_data/server_root/icons/f.gif b/lib/inets/test/httpd_test_data/server_root/icons/f.gif
new file mode 100644
index 0000000000..fbe353c282
--- /dev/null
+++ b/lib/inets/test/httpd_test_data/server_root/icons/f.gif
Binary files differ
diff --git a/lib/inets/test/httpd_test_data/server_root/icons/folder.gif b/lib/inets/test/httpd_test_data/server_root/icons/folder.gif
new file mode 100644
index 0000000000..48264601ae
--- /dev/null
+++ b/lib/inets/test/httpd_test_data/server_root/icons/folder.gif
Binary files differ
diff --git a/lib/inets/test/httpd_test_data/server_root/icons/folder.open.gif b/lib/inets/test/httpd_test_data/server_root/icons/folder.open.gif
new file mode 100644
index 0000000000..30979cb528
--- /dev/null
+++ b/lib/inets/test/httpd_test_data/server_root/icons/folder.open.gif
Binary files differ
diff --git a/lib/inets/test/httpd_test_data/server_root/icons/folder.sec.gif b/lib/inets/test/httpd_test_data/server_root/icons/folder.sec.gif
new file mode 100644
index 0000000000..75332d9e59
--- /dev/null
+++ b/lib/inets/test/httpd_test_data/server_root/icons/folder.sec.gif
Binary files differ
diff --git a/lib/inets/test/httpd_test_data/server_root/icons/forward.gif b/lib/inets/test/httpd_test_data/server_root/icons/forward.gif
new file mode 100644
index 0000000000..b2959b4c85
--- /dev/null
+++ b/lib/inets/test/httpd_test_data/server_root/icons/forward.gif
Binary files differ
diff --git a/lib/inets/test/httpd_test_data/server_root/icons/generic.gif b/lib/inets/test/httpd_test_data/server_root/icons/generic.gif
new file mode 100644
index 0000000000..de60b2940f
--- /dev/null
+++ b/lib/inets/test/httpd_test_data/server_root/icons/generic.gif
Binary files differ
diff --git a/lib/inets/test/httpd_test_data/server_root/icons/generic.red.gif b/lib/inets/test/httpd_test_data/server_root/icons/generic.red.gif
new file mode 100644
index 0000000000..94743981d9
--- /dev/null
+++ b/lib/inets/test/httpd_test_data/server_root/icons/generic.red.gif
Binary files differ
diff --git a/lib/inets/test/httpd_test_data/server_root/icons/generic.sec.gif b/lib/inets/test/httpd_test_data/server_root/icons/generic.sec.gif
new file mode 100644
index 0000000000..88d5240c3c
--- /dev/null
+++ b/lib/inets/test/httpd_test_data/server_root/icons/generic.sec.gif
Binary files differ
diff --git a/lib/inets/test/httpd_test_data/server_root/icons/hand.right.gif b/lib/inets/test/httpd_test_data/server_root/icons/hand.right.gif
new file mode 100644
index 0000000000..5cdbc7206d
--- /dev/null
+++ b/lib/inets/test/httpd_test_data/server_root/icons/hand.right.gif
Binary files differ
diff --git a/lib/inets/test/httpd_test_data/server_root/icons/hand.up.gif b/lib/inets/test/httpd_test_data/server_root/icons/hand.up.gif
new file mode 100644
index 0000000000..85a5d68317
--- /dev/null
+++ b/lib/inets/test/httpd_test_data/server_root/icons/hand.up.gif
Binary files differ
diff --git a/lib/inets/test/httpd_test_data/server_root/icons/htdig.gif b/lib/inets/test/httpd_test_data/server_root/icons/htdig.gif
new file mode 100644
index 0000000000..35443fb63a
--- /dev/null
+++ b/lib/inets/test/httpd_test_data/server_root/icons/htdig.gif
Binary files differ
diff --git a/lib/inets/test/httpd_test_data/server_root/icons/icon.sheet.gif b/lib/inets/test/httpd_test_data/server_root/icons/icon.sheet.gif
new file mode 100644
index 0000000000..ad1686e448
--- /dev/null
+++ b/lib/inets/test/httpd_test_data/server_root/icons/icon.sheet.gif
Binary files differ
diff --git a/lib/inets/test/httpd_test_data/server_root/icons/image1.gif b/lib/inets/test/httpd_test_data/server_root/icons/image1.gif
new file mode 100644
index 0000000000..01e442bfa9
--- /dev/null
+++ b/lib/inets/test/httpd_test_data/server_root/icons/image1.gif
Binary files differ
diff --git a/lib/inets/test/httpd_test_data/server_root/icons/image2.gif b/lib/inets/test/httpd_test_data/server_root/icons/image2.gif
new file mode 100644
index 0000000000..751faeea36
--- /dev/null
+++ b/lib/inets/test/httpd_test_data/server_root/icons/image2.gif
Binary files differ
diff --git a/lib/inets/test/httpd_test_data/server_root/icons/image3.gif b/lib/inets/test/httpd_test_data/server_root/icons/image3.gif
new file mode 100644
index 0000000000..4f30484ff6
--- /dev/null
+++ b/lib/inets/test/httpd_test_data/server_root/icons/image3.gif
Binary files differ
diff --git a/lib/inets/test/httpd_test_data/server_root/icons/index.gif b/lib/inets/test/httpd_test_data/server_root/icons/index.gif
new file mode 100644
index 0000000000..162478fb3a
--- /dev/null
+++ b/lib/inets/test/httpd_test_data/server_root/icons/index.gif
Binary files differ
diff --git a/lib/inets/test/httpd_test_data/server_root/icons/layout.gif b/lib/inets/test/httpd_test_data/server_root/icons/layout.gif
new file mode 100644
index 0000000000..c96338a152
--- /dev/null
+++ b/lib/inets/test/httpd_test_data/server_root/icons/layout.gif
Binary files differ
diff --git a/lib/inets/test/httpd_test_data/server_root/icons/left.gif b/lib/inets/test/httpd_test_data/server_root/icons/left.gif
new file mode 100644
index 0000000000..279e6710d4
--- /dev/null
+++ b/lib/inets/test/httpd_test_data/server_root/icons/left.gif
Binary files differ
diff --git a/lib/inets/test/httpd_test_data/server_root/icons/link.gif b/lib/inets/test/httpd_test_data/server_root/icons/link.gif
new file mode 100644
index 0000000000..c5b6889a76
--- /dev/null
+++ b/lib/inets/test/httpd_test_data/server_root/icons/link.gif
Binary files differ
diff --git a/lib/inets/test/httpd_test_data/server_root/icons/movie.gif b/lib/inets/test/httpd_test_data/server_root/icons/movie.gif
new file mode 100644
index 0000000000..0035183774
--- /dev/null
+++ b/lib/inets/test/httpd_test_data/server_root/icons/movie.gif
Binary files differ
diff --git a/lib/inets/test/httpd_test_data/server_root/icons/p.gif b/lib/inets/test/httpd_test_data/server_root/icons/p.gif
new file mode 100644
index 0000000000..7b917b4e91
--- /dev/null
+++ b/lib/inets/test/httpd_test_data/server_root/icons/p.gif
Binary files differ
diff --git a/lib/inets/test/httpd_test_data/server_root/icons/patch.gif b/lib/inets/test/httpd_test_data/server_root/icons/patch.gif
new file mode 100644
index 0000000000..39bc90e795
--- /dev/null
+++ b/lib/inets/test/httpd_test_data/server_root/icons/patch.gif
Binary files differ
diff --git a/lib/inets/test/httpd_test_data/server_root/icons/pdf.gif b/lib/inets/test/httpd_test_data/server_root/icons/pdf.gif
new file mode 100644
index 0000000000..c88fd777c4
--- /dev/null
+++ b/lib/inets/test/httpd_test_data/server_root/icons/pdf.gif
Binary files differ
diff --git a/lib/inets/test/httpd_test_data/server_root/icons/pie0.gif b/lib/inets/test/httpd_test_data/server_root/icons/pie0.gif
new file mode 100644
index 0000000000..6f7a0ae7a7
--- /dev/null
+++ b/lib/inets/test/httpd_test_data/server_root/icons/pie0.gif
Binary files differ
diff --git a/lib/inets/test/httpd_test_data/server_root/icons/pie1.gif b/lib/inets/test/httpd_test_data/server_root/icons/pie1.gif
new file mode 100644
index 0000000000..03aa6be71e
--- /dev/null
+++ b/lib/inets/test/httpd_test_data/server_root/icons/pie1.gif
Binary files differ
diff --git a/lib/inets/test/httpd_test_data/server_root/icons/pie2.gif b/lib/inets/test/httpd_test_data/server_root/icons/pie2.gif
new file mode 100644
index 0000000000..b04c5e0908
--- /dev/null
+++ b/lib/inets/test/httpd_test_data/server_root/icons/pie2.gif
Binary files differ
diff --git a/lib/inets/test/httpd_test_data/server_root/icons/pie3.gif b/lib/inets/test/httpd_test_data/server_root/icons/pie3.gif
new file mode 100644
index 0000000000..4db9d023ed
--- /dev/null
+++ b/lib/inets/test/httpd_test_data/server_root/icons/pie3.gif
Binary files differ
diff --git a/lib/inets/test/httpd_test_data/server_root/icons/pie4.gif b/lib/inets/test/httpd_test_data/server_root/icons/pie4.gif
new file mode 100644
index 0000000000..93471fdd88
--- /dev/null
+++ b/lib/inets/test/httpd_test_data/server_root/icons/pie4.gif
Binary files differ
diff --git a/lib/inets/test/httpd_test_data/server_root/icons/pie5.gif b/lib/inets/test/httpd_test_data/server_root/icons/pie5.gif
new file mode 100644
index 0000000000..57aee93f07
--- /dev/null
+++ b/lib/inets/test/httpd_test_data/server_root/icons/pie5.gif
Binary files differ
diff --git a/lib/inets/test/httpd_test_data/server_root/icons/pie6.gif b/lib/inets/test/httpd_test_data/server_root/icons/pie6.gif
new file mode 100644
index 0000000000..0dc327b569
--- /dev/null
+++ b/lib/inets/test/httpd_test_data/server_root/icons/pie6.gif
Binary files differ
diff --git a/lib/inets/test/httpd_test_data/server_root/icons/pie7.gif b/lib/inets/test/httpd_test_data/server_root/icons/pie7.gif
new file mode 100644
index 0000000000..8661337f06
--- /dev/null
+++ b/lib/inets/test/httpd_test_data/server_root/icons/pie7.gif
Binary files differ
diff --git a/lib/inets/test/httpd_test_data/server_root/icons/pie8.gif b/lib/inets/test/httpd_test_data/server_root/icons/pie8.gif
new file mode 100644
index 0000000000..59ddb34ce0
--- /dev/null
+++ b/lib/inets/test/httpd_test_data/server_root/icons/pie8.gif
Binary files differ
diff --git a/lib/inets/test/httpd_test_data/server_root/icons/portal.gif b/lib/inets/test/httpd_test_data/server_root/icons/portal.gif
new file mode 100644
index 0000000000..0e6e506e00
--- /dev/null
+++ b/lib/inets/test/httpd_test_data/server_root/icons/portal.gif
Binary files differ
diff --git a/lib/inets/test/httpd_test_data/server_root/icons/poweredby.gif b/lib/inets/test/httpd_test_data/server_root/icons/poweredby.gif
new file mode 100644
index 0000000000..d324ab80ea
--- /dev/null
+++ b/lib/inets/test/httpd_test_data/server_root/icons/poweredby.gif
Binary files differ
diff --git a/lib/inets/test/httpd_test_data/server_root/icons/ps.gif b/lib/inets/test/httpd_test_data/server_root/icons/ps.gif
new file mode 100644
index 0000000000..0f565bc1db
--- /dev/null
+++ b/lib/inets/test/httpd_test_data/server_root/icons/ps.gif
Binary files differ
diff --git a/lib/inets/test/httpd_test_data/server_root/icons/quill.gif b/lib/inets/test/httpd_test_data/server_root/icons/quill.gif
new file mode 100644
index 0000000000..818a5cdc7e
--- /dev/null
+++ b/lib/inets/test/httpd_test_data/server_root/icons/quill.gif
Binary files differ
diff --git a/lib/inets/test/httpd_test_data/server_root/icons/right.gif b/lib/inets/test/httpd_test_data/server_root/icons/right.gif
new file mode 100644
index 0000000000..b256e5f75f
--- /dev/null
+++ b/lib/inets/test/httpd_test_data/server_root/icons/right.gif
Binary files differ
diff --git a/lib/inets/test/httpd_test_data/server_root/icons/screw1.gif b/lib/inets/test/httpd_test_data/server_root/icons/screw1.gif
new file mode 100644
index 0000000000..af6ba2b097
--- /dev/null
+++ b/lib/inets/test/httpd_test_data/server_root/icons/screw1.gif
Binary files differ
diff --git a/lib/inets/test/httpd_test_data/server_root/icons/screw2.gif b/lib/inets/test/httpd_test_data/server_root/icons/screw2.gif
new file mode 100644
index 0000000000..06dccb3e44
--- /dev/null
+++ b/lib/inets/test/httpd_test_data/server_root/icons/screw2.gif
Binary files differ
diff --git a/lib/inets/test/httpd_test_data/server_root/icons/script.gif b/lib/inets/test/httpd_test_data/server_root/icons/script.gif
new file mode 100644
index 0000000000..d8a853bc58
--- /dev/null
+++ b/lib/inets/test/httpd_test_data/server_root/icons/script.gif
Binary files differ
diff --git a/lib/inets/test/httpd_test_data/server_root/icons/sound1.gif b/lib/inets/test/httpd_test_data/server_root/icons/sound1.gif
new file mode 100644
index 0000000000..8efb49f55d
--- /dev/null
+++ b/lib/inets/test/httpd_test_data/server_root/icons/sound1.gif
Binary files differ
diff --git a/lib/inets/test/httpd_test_data/server_root/icons/sound2.gif b/lib/inets/test/httpd_test_data/server_root/icons/sound2.gif
new file mode 100644
index 0000000000..48e6a7fb2f
--- /dev/null
+++ b/lib/inets/test/httpd_test_data/server_root/icons/sound2.gif
Binary files differ
diff --git a/lib/inets/test/httpd_test_data/server_root/icons/sphere1.gif b/lib/inets/test/httpd_test_data/server_root/icons/sphere1.gif
new file mode 100644
index 0000000000..7067070da2
--- /dev/null
+++ b/lib/inets/test/httpd_test_data/server_root/icons/sphere1.gif
Binary files differ
diff --git a/lib/inets/test/httpd_test_data/server_root/icons/sphere2.gif b/lib/inets/test/httpd_test_data/server_root/icons/sphere2.gif
new file mode 100644
index 0000000000..a9e462a377
--- /dev/null
+++ b/lib/inets/test/httpd_test_data/server_root/icons/sphere2.gif
Binary files differ
diff --git a/lib/inets/test/httpd_test_data/server_root/icons/star.gif b/lib/inets/test/httpd_test_data/server_root/icons/star.gif
new file mode 100644
index 0000000000..4cfe0a5e0f
--- /dev/null
+++ b/lib/inets/test/httpd_test_data/server_root/icons/star.gif
Binary files differ
diff --git a/lib/inets/test/httpd_test_data/server_root/icons/star_blank.gif b/lib/inets/test/httpd_test_data/server_root/icons/star_blank.gif
new file mode 100644
index 0000000000..a0c83cb85b
--- /dev/null
+++ b/lib/inets/test/httpd_test_data/server_root/icons/star_blank.gif
Binary files differ
diff --git a/lib/inets/test/httpd_test_data/server_root/icons/tar.gif b/lib/inets/test/httpd_test_data/server_root/icons/tar.gif
new file mode 100644
index 0000000000..617e779efa
--- /dev/null
+++ b/lib/inets/test/httpd_test_data/server_root/icons/tar.gif
Binary files differ
diff --git a/lib/inets/test/httpd_test_data/server_root/icons/tex.gif b/lib/inets/test/httpd_test_data/server_root/icons/tex.gif
new file mode 100644
index 0000000000..45e43233b8
--- /dev/null
+++ b/lib/inets/test/httpd_test_data/server_root/icons/tex.gif
Binary files differ
diff --git a/lib/inets/test/httpd_test_data/server_root/icons/text.gif b/lib/inets/test/httpd_test_data/server_root/icons/text.gif
new file mode 100644
index 0000000000..4c623909fb
--- /dev/null
+++ b/lib/inets/test/httpd_test_data/server_root/icons/text.gif
Binary files differ
diff --git a/lib/inets/test/httpd_test_data/server_root/icons/transfer.gif b/lib/inets/test/httpd_test_data/server_root/icons/transfer.gif
new file mode 100644
index 0000000000..33697dbb66
--- /dev/null
+++ b/lib/inets/test/httpd_test_data/server_root/icons/transfer.gif
Binary files differ
diff --git a/lib/inets/test/httpd_test_data/server_root/icons/unknown.gif b/lib/inets/test/httpd_test_data/server_root/icons/unknown.gif
new file mode 100644
index 0000000000..32b1ea23fb
--- /dev/null
+++ b/lib/inets/test/httpd_test_data/server_root/icons/unknown.gif
Binary files differ
diff --git a/lib/inets/test/httpd_test_data/server_root/icons/up.gif b/lib/inets/test/httpd_test_data/server_root/icons/up.gif
new file mode 100644
index 0000000000..6d6d6d1ebf
--- /dev/null
+++ b/lib/inets/test/httpd_test_data/server_root/icons/up.gif
Binary files differ
diff --git a/lib/inets/test/httpd_test_data/server_root/icons/uu.gif b/lib/inets/test/httpd_test_data/server_root/icons/uu.gif
new file mode 100644
index 0000000000..4387d529f6
--- /dev/null
+++ b/lib/inets/test/httpd_test_data/server_root/icons/uu.gif
Binary files differ
diff --git a/lib/inets/test/httpd_test_data/server_root/icons/uuencoded.gif b/lib/inets/test/httpd_test_data/server_root/icons/uuencoded.gif
new file mode 100644
index 0000000000..4387d529f6
--- /dev/null
+++ b/lib/inets/test/httpd_test_data/server_root/icons/uuencoded.gif
Binary files differ
diff --git a/lib/inets/test/httpd_test_data/server_root/icons/world1.gif b/lib/inets/test/httpd_test_data/server_root/icons/world1.gif
new file mode 100644
index 0000000000..05b4ec2058
--- /dev/null
+++ b/lib/inets/test/httpd_test_data/server_root/icons/world1.gif
Binary files differ
diff --git a/lib/inets/test/httpd_test_data/server_root/icons/world2.gif b/lib/inets/test/httpd_test_data/server_root/icons/world2.gif
new file mode 100644
index 0000000000..e3203f7a88
--- /dev/null
+++ b/lib/inets/test/httpd_test_data/server_root/icons/world2.gif
Binary files differ
diff --git a/lib/inets/test/httpd_test_data/server_root/logs/Dummy_File_Needed_By_WinZip b/lib/inets/test/httpd_test_data/server_root/logs/Dummy_File_Needed_By_WinZip
new file mode 100644
index 0000000000..8d1c8b69c3
--- /dev/null
+++ b/lib/inets/test/httpd_test_data/server_root/logs/Dummy_File_Needed_By_WinZip
@@ -0,0 +1 @@
+
diff --git a/lib/inets/test/httpd_test_data/server_root/ssl/ssl_client.pem b/lib/inets/test/httpd_test_data/server_root/ssl/ssl_client.pem
new file mode 100644
index 0000000000..8221139eb4
--- /dev/null
+++ b/lib/inets/test/httpd_test_data/server_root/ssl/ssl_client.pem
@@ -0,0 +1,22 @@
+-----BEGIN RSA PRIVATE KEY-----
+MIIBPAIBAAJBAL6Ym/bgUvhhnPkw08sggGg8Tnp759ThGMEjkmDzhuJ3w3PfnF65
+mgHcgunku4G6LxAQfEUougJWf9Phmjj3oRUCAwEAAQJBAKMjvVvzZxFzfAlP4flc
+OI0AEayFokp04dtvtzuFN09f+aBo2dP18xHmKLCZvxrBOaRAROoQYscALiIVpN07
+GAECIQDfi+sSfAFaDlT3vzpL3xE5UEH6IzY8jWpaZfM1QaToJQIhANpEF50H4wGO
+8Sbh7dUutNd+s+NYUjsMySW2DjLKMsoxAiEAzzb2ftrdsempD0F+O0gZwiPIFKLB
+Kp33YLYyHEKuJtUCIDGi+pvDh2R7VWw6RRQOIyI+tjolg83aAoSI+oGiahqBAiEA
+xzmNNajwoaokvWvlaz0na8rhxu45grOvDrflBT9XvSQ=
+-----END RSA PRIVATE KEY-----
+-----BEGIN CERTIFICATE-----
+MIICDDCCAbYCAQAwDQYJKoZIhvcNAQEEBQAwgZAxCzAJBgNVBAYTAlNFMRIwEAYD
+VQQIEwlTdG9ja2hvbG0xDzANBgNVBAcTBkFsdnNqbzEMMAoGA1UEChMDRVRYMQ4w
+DAYDVQQLEwVETi9TUDEXMBUGA1UEAxMOSm9ha2ltIEdyZWJlbm8xJTAjBgkqhkiG
+9w0BCQEWFmpvY2tlQGVyaXguZXJpY3Nzb24uc2UwHhcNOTcwNzE1MTUzNDM2WhcN
+MDMwMjIyMTUzNDM2WjCBkDELMAkGA1UEBhMCU0UxEjAQBgNVBAgTCVN0b2NraG9s
+bTEPMA0GA1UEBxMGQWx2c2pvMQwwCgYDVQQKEwNFVFgxDjAMBgNVBAsTBUROL1NQ
+MRcwFQYDVQQDEw5Kb2FraW0gR3JlYmVubzElMCMGCSqGSIb3DQEJARYWam9ja2VA
+ZXJpeC5lcmljc3Nvbi5zZTBcMA0GCSqGSIb3DQEBAQUAA0sAMEgCQQC+mJv24FL4
+YZz5MNPLIIBoPE56e+fU4RjBI5Jg84bid8Nz35xeuZoB3ILp5LuBui8QEHxFKLoC
+Vn/T4Zo496EVAgMBAAEwDQYJKoZIhvcNAQEEBQADQQBYxQVfTydyZCE0UXvZd7Ei
+josNsAaWJk9fFIJaG9uyXCEfg2dVgoT2eBk3D9DI+7OB+78isM5CVlFbL7hilvP8
+-----END CERTIFICATE-----
diff --git a/lib/inets/test/httpd_test_data/server_root/ssl/ssl_server.pem b/lib/inets/test/httpd_test_data/server_root/ssl/ssl_server.pem
new file mode 100644
index 0000000000..fe739c15f7
--- /dev/null
+++ b/lib/inets/test/httpd_test_data/server_root/ssl/ssl_server.pem
@@ -0,0 +1,22 @@
+-----BEGIN RSA PRIVATE KEY-----
+MIIBOwIBAAJBAL9Bozj3BIjL5Cy8b3rjMT2kPZRychX4wz9bHoIIiKnKo1xXHYjw
+g3N9zWM1f1ZzMADwVry1uAInA8q09+7hL20CAwEAAQJACwu2ao7RozjrV64WXimK
+6X131P/7GMvCMwGHNIlbozqoOqmZcYrbKaF61l+XuwA2QvTo3ywW1Ivxcyr6TeAr
+PQIhAOX+WXT6yiqqwjt08kjBCJyMgfZtdAO6pc/6pKjNWiZfAiEA1OH1iPW/OQe5
+tlQXpiRVdLyneNsPygPRJc4Bdwu3hbMCIQDbI5pA56QxOzqOREOGJsb5wrciAfAE
+jZbnr72sSN2YqQIgAWFpvzagw9Tp/mWzNY+cwkIK7/yzsIKv04fveH8p9IMCIQCr
+td4IiukeUwXmPSvYM4uCE/+J89wEL9qU8Mlc3gDLXA==
+-----END RSA PRIVATE KEY-----
+-----BEGIN CERTIFICATE-----
+MIICDDCCAbYCAQAwDQYJKoZIhvcNAQEEBQAwgZAxCzAJBgNVBAYTAlNFMRIwEAYD
+VQQIEwlTdG9ja2hvbG0xDzANBgNVBAcTBkFsdnNqbzEMMAoGA1UEChMDRVRYMQ4w
+DAYDVQQLEwVETi9TUDEXMBUGA1UEAxMOSm9ha2ltIEdyZWJlbm8xJTAjBgkqhkiG
+9w0BCQEWFmpvY2tlQGVyaXguZXJpY3Nzb24uc2UwHhcNOTcwNzE1MTUzMzQxWhcN
+MDMwMjIyMTUzMzQxWjCBkDELMAkGA1UEBhMCU0UxEjAQBgNVBAgTCVN0b2NraG9s
+bTEPMA0GA1UEBxMGQWx2c2pvMQwwCgYDVQQKEwNFVFgxDjAMBgNVBAsTBUROL1NQ
+MRcwFQYDVQQDEw5Kb2FraW0gR3JlYmVubzElMCMGCSqGSIb3DQEJARYWam9ja2VA
+ZXJpeC5lcmljc3Nvbi5zZTBcMA0GCSqGSIb3DQEBAQUAA0sAMEgCQQC/QaM49wSI
+y+QsvG964zE9pD2UcnIV+MM/Wx6CCIipyqNcVx2I8INzfc1jNX9WczAA8Fa8tbgC
+JwPKtPfu4S9tAgMBAAEwDQYJKoZIhvcNAQEEBQADQQAmXDY1CyJjzvQZX442kkHG
+ic9QFY1UuVfzokzNMwlHYl1Qx9zaodx0cJCrcH5GF9O9LJbhhV77LzoxT1Q5wZp5
+-----END CERTIFICATE-----
diff --git a/lib/inets/test/httpd_test_lib.erl b/lib/inets/test/httpd_test_lib.erl
new file mode 100644
index 0000000000..8d748defd8
--- /dev/null
+++ b/lib/inets/test/httpd_test_lib.erl
@@ -0,0 +1,379 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 2001-2011. All Rights Reserved.
+%%
+%% The contents of this file are subject to the Erlang Public License,
+%% Version 1.1, (the "License"); you may not use this file except in
+%% compliance with the License. You should have received a copy of the
+%% Erlang Public License along with this software. If not, it can be
+%% retrieved online at http://www.erlang.org/.
+%%
+%% Software distributed under the License is distributed on an "AS IS"
+%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+%% the License for the specific language governing rights and limitations
+%% under the License.
+%%
+%% %CopyrightEnd%
+%%
+%%
+-module(httpd_test_lib).
+
+-include("inets_test_lib.hrl").
+
+%% Poll functions
+-export([verify_request/6, verify_request/7, is_expect/1]).
+
+-record(state, {request, % string()
+ socket, % socket()
+ status_line, % {Version, StatusCode, ReasonPharse}
+ headers, % #http_response_h{}
+ body, % binary()
+ mfa = {httpc_response, parse, [nolimit, false]},
+ canceled = [], % [RequestId]
+ max_header_size = nolimit, % nolimit | integer()
+ max_body_size = nolimit, % nolimit | integer()
+ print = false
+ }).
+
+%%% Part of http.hrl - Temporary solution %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%%% Response headers
+-record(http_response_h,{
+%%% --- Standard "General" headers
+ 'cache-control',
+ connection,
+ date,
+ pragma,
+ trailer,
+ 'transfer-encoding',
+ upgrade,
+ via,
+ warning,
+%%% --- Standard "Response" headers
+ 'accept-ranges',
+ age,
+ etag,
+ location,
+ 'proxy-authenticate',
+ 'retry-after',
+ server,
+ vary,
+ 'www-authenticate',
+%%% --- Standard "Entity" headers
+ allow,
+ 'content-encoding',
+ 'content-language',
+ 'content-length' = "0",
+ 'content-location',
+ 'content-md5',
+ 'content-range',
+ 'content-type',
+ expires,
+ 'last-modified',
+ other=[] % list() - Key/Value list with other headers
+ }).
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+%%--------------------------------------------------------------------
+%% API
+%%------------------------------------------------------------------
+verify_request(SocketType, Host, Port, Node, RequestStr, Options) ->
+ verify_request(SocketType, Host, Port, Node, RequestStr, Options, 30000).
+verify_request(SocketType, Host, Port, Node, RequestStr, Options, TimeOut) ->
+ tsp("verify_request -> connect to [~w] ~p:~w", [SocketType, Host, Port]),
+ {ok, Socket} = inets_test_lib:connect_bin(SocketType, Host, Port),
+
+ inets_test_lib:send(SocketType, Socket, RequestStr),
+
+ State = case inets_regexp:match(RequestStr, "printenv") of
+ nomatch ->
+ #state{};
+ _ ->
+ #state{print = true}
+ end,
+
+ case request(State#state{request = RequestStr, socket = Socket}, TimeOut) of
+ {error, Reson} ->
+ {error, Reson};
+ NewState ->
+ ValidateResult = validate(RequestStr, NewState, Options,
+ Node, Port),
+ inets_test_lib:close(SocketType, Socket),
+ ValidateResult
+ end.
+
+request(#state{mfa = {Module, Function, Args},
+ request = RequestStr,
+ socket = Socket} = State, TimeOut) ->
+ io:format("~p ~w[~w]request -> entry with"
+ "~n Module: ~p"
+ "~n Function: ~p"
+ "~n Args: ~p"
+ "~n", [self(), ?MODULE, ?LINE, Module, Function, Args]),
+ HeadRequest = lists:sublist(RequestStr, 1, 4),
+ receive
+ {tcp, Socket, Data} ->
+ io:format("~p ~w[~w]request -> received (tcp) data"
+ "~n Data: ~p"
+ "~n", [self(), ?MODULE, ?LINE, Data]),
+ print(tcp, Data, State),
+ case Module:Function([Data | Args]) of
+ {ok, Parsed} ->
+ handle_http_msg(Parsed, State);
+ {_, whole_body, _} when HeadRequest == "HEAD" ->
+ State#state{body = <<>>};
+ NewMFA ->
+ request(State#state{mfa = NewMFA}, TimeOut)
+ end;
+ {tcp_closed, Socket} when Function == whole_body ->
+ io:format("~p ~w[~w]request -> "
+ "received (tcp) closed when whole_body"
+ "~n", [self(), ?MODULE, ?LINE]),
+ print(tcp, "closed", State),
+ State#state{body = hd(Args)};
+ {tcp_closed, Socket} ->
+ io:format("~p ~w[~w]request -> received (tcp) closed"
+ "~n", [self(), ?MODULE, ?LINE]),
+ test_server:fail(connection_closed);
+ {tcp_error, Socket, Reason} ->
+ io:format("~p ~w[~w]request -> received (tcp) error"
+ "~n Reason: ~p"
+ "~n", [self(), ?MODULE, ?LINE, Reason]),
+ test_server:fail({tcp_error, Reason});
+ {ssl, Socket, Data} ->
+ print(ssl, Data, State),
+ case Module:Function([Data | Args]) of
+ {ok, Parsed} ->
+ handle_http_msg(Parsed, State);
+ {_, whole_body, _} when HeadRequest == "HEAD" ->
+ State#state{body = <<>>};
+ NewMFA ->
+ request(State#state{mfa = NewMFA}, TimeOut)
+ end;
+ {ssl_closed, Socket} when Function == whole_body ->
+ print(ssl, "closed", State),
+ State#state{body = hd(Args)};
+ {ssl_closed, Socket} ->
+ test_server:fail(connection_closed);
+ {ssl_error, Socket, Reason} ->
+ test_server:fail({ssl_error, Reason})
+ after TimeOut ->
+ io:format("~p ~w[~w]request -> timeout"
+ "~n", [self(), ?MODULE, ?LINE]),
+ test_server:fail(connection_timed_out)
+ end.
+
+handle_http_msg({Version, StatusCode, ReasonPharse, Headers, Body},
+ State = #state{request = RequestStr}) ->
+ io:format("~p ~w[~w]handle_http_msg -> entry with"
+ "~n Version: ~p"
+ "~n StatusCode: ~p"
+ "~n ReasonPharse: ~p"
+ "~n Headers: ~p"
+ "~n Body: ~p"
+ "~n", [self(), ?MODULE, ?LINE,
+ Version, StatusCode, ReasonPharse, Headers, Body]),
+ case is_expect(RequestStr) of
+ true ->
+ State#state{status_line = {Version,
+ StatusCode,
+ ReasonPharse},
+ headers = Headers};
+ false ->
+ handle_http_body(Body,
+ State#state{status_line = {Version,
+ StatusCode,
+ ReasonPharse},
+ headers = Headers})
+ end;
+
+handle_http_msg({ChunkedHeaders, Body},
+ State = #state{headers = Headers}) ->
+ NewHeaders = http_chunk:handle_headers(Headers, ChunkedHeaders),
+ State#state{headers = NewHeaders, body = Body};
+
+handle_http_msg(Body, State) ->
+ State#state{body = Body}.
+
+handle_http_body(<<>>, State = #state{request = "HEAD" ++ _}) ->
+ State#state{body = <<>>};
+
+handle_http_body(Body, State = #state{headers = Headers,
+ max_body_size = MaxBodySize}) ->
+ case Headers#http_response_h.'transfer-encoding' of
+ "chunked" ->
+ case http_chunk:decode(Body, State#state.max_body_size,
+ State#state.max_header_size) of
+ {Module, Function, Args} ->
+ request(State#state{mfa = {Module, Function, Args}},
+ 30000);
+ {ok, {ChunkedHeaders, NewBody}} ->
+ NewHeaders = http_chunk:handle_headers(Headers,
+ ChunkedHeaders),
+ State#state{headers = NewHeaders, body = NewBody}
+ end;
+ _ ->
+ Length =
+ list_to_integer(Headers#http_response_h.'content-length'),
+ case ((Length =< MaxBodySize) or (MaxBodySize == nolimit)) of
+ true ->
+ case httpc_response:whole_body(Body, Length) of
+ {ok, NewBody} ->
+ State#state{body = NewBody};
+ MFA ->
+ request(State#state{mfa = MFA}, 5000)
+ end;
+ false ->
+ test_server:fail(body_too_big)
+ end
+ end.
+
+validate(RequestStr, #state{status_line = {Version, StatusCode, _},
+ headers = Headers,
+ body = Body}, Options, N, P) ->
+
+ check_version(Version, Options),
+ case lists:keysearch(statuscode, 1, Options) of
+ {value, _} ->
+ check_status_code(StatusCode, Options, Options);
+ _ ->
+ ok
+ end,
+ do_validate(http_response:header_list(Headers), Options, N, P),
+ check_body(RequestStr, StatusCode,
+ Headers#http_response_h.'content-type',
+ list_to_integer(Headers#http_response_h.'content-length'),
+ Body).
+
+
+%%--------------------------------------------------------------------
+%% Internal functions
+%%------------------------------------------------------------------
+check_version(Version, Options) ->
+ case lists:keysearch(version, 1, Options) of
+ {value, {version, Version}} ->
+ ok;
+ {value, {version, Ver}} ->
+ tsf({wrong_version, [{got, Version},
+ {expected, Ver}]});
+ _ ->
+ case Version of
+ "HTTP/1.1" ->
+ ok;
+ _ ->
+ tsf({wrong_version, [{got, Version},
+ {expected, "HTTP/1.1"}]})
+ end
+ end.
+
+check_status_code(StatusCode, [], Options) ->
+ tsf({wrong_status_code, [{got, StatusCode}, {expected, Options}]});
+check_status_code(StatusCode, Current = [_ | Rest], Options) ->
+ case lists:keysearch(statuscode, 1, Current) of
+ {value, {statuscode, StatusCode}} ->
+ ok;
+ {value, {statuscode, _OtherStatus}} ->
+ check_status_code(StatusCode, Rest, Options);
+ false ->
+ tsf({wrong_status_code, [{got, StatusCode}, {expected, Options}]})
+ end.
+
+do_validate(_, [], _, _) ->
+ ok;
+do_validate(Header, [{statuscode, _Code} | Rest], N, P) ->
+ do_validate(Header, Rest, N, P);
+do_validate(Header, [{header, HeaderField}|Rest], N, P) ->
+ LowerHeaderField = http_util:to_lower(HeaderField),
+ case lists:keysearch(LowerHeaderField, 1, Header) of
+ {value, {LowerHeaderField, _Value}} ->
+ ok;
+ false ->
+ test_server:fail({missing_header_field, LowerHeaderField, Header});
+ _ ->
+ test_server:fail({missing_header_field, LowerHeaderField, Header})
+ end,
+ do_validate(Header, Rest, N, P);
+do_validate(Header, [{header, HeaderField, Value}|Rest],N,P) ->
+ LowerHeaderField = http_util:to_lower(HeaderField),
+ case lists:keysearch(LowerHeaderField, 1, Header) of
+ {value, {LowerHeaderField, Value}} ->
+ ok;
+ false ->
+ test_server:fail({wrong_header_field_value, LowerHeaderField,
+ Header});
+ _ ->
+ test_server:fail({wrong_header_field_value, LowerHeaderField,
+ Header})
+ end,
+ do_validate(Header, Rest, N, P);
+do_validate(Header,[{no_last_modified, HeaderField}|Rest],N,P) ->
+ case lists:keysearch(HeaderField,1,Header) of
+ {value,_} ->
+ test_server:fail({wrong_header_field_value, HeaderField,
+ Header});
+ _ ->
+ ok
+ end,
+ do_validate(Header, Rest, N, P);
+do_validate(Header, [_Unknown | Rest], N, P) ->
+ do_validate(Header, Rest, N, P).
+
+is_expect(RequestStr) ->
+ case inets_regexp:match(RequestStr, "xpect:100-continue") of
+ {match, _, _}->
+ true;
+ _ ->
+ false
+ end.
+
+%% OTP-5775, content-length
+check_body("GET /cgi-bin/erl/httpd_example:get_bin HTTP/1.0\r\n\r\n", 200, "text/html", Length, _Body) when (Length =/= 274) ->
+ tsf(content_length_error);
+check_body("GET /cgi-bin/cgi_echo HTTP/1.0\r\n\r\n", 200, "text/plain",
+ _, Body) ->
+ case size(Body) of
+ 100 ->
+ ok;
+ _ ->
+ tsf(content_length_error)
+ end;
+
+check_body(RequestStr, 200, "text/html", _, Body) ->
+ HeadRequest = lists:sublist(RequestStr, 1, 3),
+ case HeadRequest of
+ "GET" ->
+ inets_test_lib:check_body(binary_to_list(Body));
+ _ ->
+ ok
+ end;
+
+check_body(_, _, _, _,_) ->
+ ok.
+
+print(Proto, Data, #state{print = true}) ->
+ test_server:format("Received ~p: ~p~n", [Proto, Data]);
+print(_, _, #state{print = false}) ->
+ ok.
+
+tsf(Reason) ->
+ test_server:fail(Reason).
+
+%% tsp(F) ->
+%% tsp(F, []).
+tsp(F, A) ->
+ Timestamp = formated_timestamp(),
+ test_server:format("** ~s ** ~p ~p:" ++ F ++ "~n",
+ [Timestamp, self(), ?MODULE | A]).
+
+formated_timestamp() ->
+ format_timestamp( os:timestamp() ).
+
+format_timestamp({_N1, _N2, N3} = Now) ->
+ {Date, Time} = calendar:now_to_datetime(Now),
+ {YYYY,MM,DD} = Date,
+ {Hour,Min,Sec} = Time,
+ FormatDate =
+ io_lib:format("~.4w:~.2.0w:~.2.0w ~.2.0w:~.2.0w:~.2.0w 4~w",
+ [YYYY,MM,DD,Hour,Min,Sec,round(N3/1000)]),
+ lists:flatten(FormatDate).
+
diff --git a/lib/inets/test/httpd_time_test.erl b/lib/inets/test/httpd_time_test.erl
new file mode 100644
index 0000000000..7d6aa08542
--- /dev/null
+++ b/lib/inets/test/httpd_time_test.erl
@@ -0,0 +1,500 @@
+%%
+%% %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(httpd_time_test).
+
+-export([t/3, t1/2, t2/2]).
+
+-export([do/1, do/2, do/3, do/4, do/5]).
+
+-export([main/5, poller_main/4, poller_loop/4]).
+
+-include("inets_test_lib.hrl").
+
+-record(stat, {pid, time = undefined, count = undefined, res}).
+
+
+%%% -----------------------------------------------------------------
+%%% Test suite interface
+%%%
+
+t1(Host, Port) ->
+ t(ip_comm, Host, Port).
+
+
+t2(Host, Port) ->
+ t(ssl, Host, Port).
+
+
+t(SocketType, Host, Port) ->
+ %% put(dbg,true),
+ main(1, SocketType, Host, Port, 60000).
+
+
+
+%%% -----------------------------------------------------------------
+%%% Public interface when running the time test manually...
+%%%
+
+do(Port) ->
+ do(ip_comm, hostname(), Port).
+
+do(Port, Time) when is_integer(Port) andalso is_integer(Time) ->
+ do(ip_comm, hostname(), Port, Time);
+
+do(Host, Port) ->
+ do(ip_comm, Host, Port).
+
+do(Host, Port, Time) when is_integer(Port) andalso is_integer(Time) ->
+ do(1, ip_comm, Host, Port, Time);
+
+do(SocketType, Host, Port) when is_integer(Port) ->
+ do(1, SocketType, Host, Port, 60000).
+
+do(N, SocketType, Host, Port) when is_integer(N) andalso is_integer(Port) ->
+ do(N, SocketType, Host, Port, 60000);
+
+do(SocketType, Host, Port, Time)
+ when is_integer(Port) andalso is_integer(Time) ->
+ do(1, SocketType, Host, Port, Time).
+
+do(N, SocketType, Host, Port, Time)
+ when is_integer(N) andalso is_integer(Port) andalso is_integer(Time) ->
+ do_it(N, SocketType, Host, Port, Time).
+
+do_it(N, SocketType, Host, Port, Time) ->
+ d("do_it -> entry with"
+ "~n N: ~p"
+ "~n SocketType: ~p"
+ "~n Host: ~p"
+ "~n Port: ~p"
+ "~n Time: ~p", [N, SocketType, Host, Port, Time]),
+ proc_lib:spawn(?MODULE, main, [N, SocketType, Host, Port, Time]).
+
+
+
+%%% -----------------------------------------------------------------
+%%% Controller (main) process
+%%%
+
+main(N, SocketType, Host, Port, Time)
+ when is_integer(N) andalso
+ is_atom(SocketType) andalso
+ is_integer(Port) andalso
+ is_integer(Time) ->
+ process_flag(trap_exit,true),
+ put(sname,ctrl),
+ %% put(dbg,true),
+ d("main -> entry"),
+ Pollers = start_pollers(N, [self(), SocketType, Host, Port]),
+ d("main -> Pollers: ~p", [Pollers]),
+ loop(Pollers, Time).
+
+loop(Pollers, Timeout) ->
+ d("loop -> entry when"
+ "~n Timeout: ~p", [Timeout]),
+ Start = t(),
+ receive
+ {'EXIT', Pid, {poller_stat_failure, Time, Reason}} ->
+ case is_poller(Pid, Pollers) of
+ true ->
+ error_msg("received unexpected exit from poller ~p~n"
+ "befor completion of test "
+ "(after ~p micro sec):~n"
+ "~p~n", [Pid,Time,Reason]),
+ exit({fail, {poller_exit, Pid, Reason}});
+ false ->
+ error_msg("received unexpected ~p from ~p"
+ "befor completion of test", [Reason, Pid]),
+ loop(Pollers, to(Timeout, Start))
+ end;
+
+ {poller_stat_failure, Pid, {Time, Reason}} ->
+ error_msg("received stat failure ~p from poller ~p after ~p "
+ "befor completion of test", [Reason, Pid, Time]),
+ exit({fail, {poller_failure, Pid, Reason}});
+
+ {poller_stat_failure, Pid, Reason} ->
+ error_msg("received stat failure ~p from poller ~p "
+ "befor completion of test", [Reason, Pid]),
+ exit({fail, {poller_failure, Pid, Reason}});
+
+ Any ->
+ error_msg("received unexpected message befor completion of test: "
+ "~n ~p", [Any]),
+ exit({fail, Any})
+
+ after Timeout ->
+ d("loop -> timeout: stop pollers"),
+ stop_pollers(Pollers),
+ d("loop -> collect poller statistics"),
+ Stats = collect_poller_stat(Pollers, []),
+ d("loop -> Stats: ~p", [Stats]),
+ display_poller_stat(Stats, Timeout),
+ ok
+ end.
+
+collect_poller_stat([], PollersStat) ->
+ PollersStat;
+collect_poller_stat(Pollers, PollersStat) ->
+ d("collect_poller_stat -> entry with"
+ "~n Pollers: ~p"
+ "~n PollersStat: ~p", [Pollers, PollersStat]),
+ receive
+ {poller_statistics, Poller, {Time, Count}} ->
+ d("collect_poller_stat -> got statistics from ~p", [Poller]),
+ case lists:keysearch(Poller, 2, Pollers) of
+ {value, PollerStat} ->
+ d("collect_poller_stat -> current statistic record: ~p",
+ [PollerStat]),
+ P = lists:keydelete(Poller, 2, Pollers),
+ d("collect_poller_stat -> P: ~p", [P]),
+ S = PollerStat#stat{time = Time, count = Count, res = ok},
+ d("collect_poller_stat -> S: ~p", [S]),
+ collect_poller_stat(P, [S | PollersStat]);
+ false ->
+ error_msg("statistics already received for ~p", [Poller]),
+ collect_poller_stat(Pollers, PollersStat)
+ end;
+ {poller_stat_failure, Poller, Else} ->
+ error_msg("poller statistics failure for ~p with ~p",
+ [Poller, Else]),
+ case lists:keysearch(Poller, 2, Pollers) of
+ {value, PollerStat} ->
+ P = lists:keydelete(Poller, 2, Pollers),
+ S = PollerStat#stat{res = {error, Else}},
+ collect_poller_stat(P, [S | PollerStat]);
+ false ->
+ error_msg("statistics already received for ~p", [Poller]),
+ collect_poller_stat(Pollers, PollersStat)
+ end
+ end.
+
+
+display_poller_stat(Stats, T) ->
+ display_poller_stat(Stats, 1, T, 0).
+
+display_poller_stat([], _, TestTime, AccCount) ->
+ io:format("Total statistics:~n"
+ " Accumulated count: ~w~n"
+ " Average access time: ~w milli sec~n",
+ [AccCount, (TestTime/AccCount)]);
+display_poller_stat([#stat{res = ok} = Stat | Stats], N, TestTime, AccCount) ->
+ #stat{pid = Pid, time = Time, count = Count} = Stat,
+ io:format("Statistics for poller ~p (~p):~n"
+ " time: ~w seconds~n"
+ " count: ~w~n"
+ " Average access time: ~w milli sec~n",
+ [Pid, N, Time/(1000*1000), Count, (TestTime/Count)]),
+ display_poller_stat(Stats, N + 1, TestTime, AccCount+Count);
+display_poller_stat([Stat | Stats], N, TestTime, AccCount) ->
+ #stat{pid = Pid, res = Error} = Stat,
+ io:format("Statistics failed for poller ~p (~p):~n"
+ " ~p~n", [Pid, N, Error]),
+ display_poller_stat(Stats, N + 1, TestTime, AccCount).
+
+
+
+%%% -----------------------------------------------------------------
+%%% Poller process
+%%%
+
+start_pollers(N, Args) ->
+ start_pollers(N, Args, []).
+
+start_pollers(0, _Args, Pollers) ->
+ Pollers;
+start_pollers(N, Args, Pollers) ->
+ Pid = proc_lib:spawn_link(?MODULE, poller_main, Args),
+ start_pollers(N-1, Args, [#stat{pid = Pid} | Pollers]).
+
+stop_pollers(Pollers) ->
+ [Pid ! stop || #stat{pid = Pid} <- Pollers],
+ await_stop_pollers(Pollers).
+
+await_stop_pollers([]) ->
+ ok;
+await_stop_pollers(Pollers0) ->
+ receive
+ {'EXIT', Pid, _Reason} ->
+ Pollers = lists:keydelete(Pid, 2, Pollers0),
+ await_stop_pollers(Pollers)
+ after 5000 ->
+ [Pid ! shutdown || #stat{pid = Pid} <- Pollers0]
+ end.
+
+
+is_poller(_, []) ->
+ false;
+is_poller(Pid, [#stat{pid = Pid}|_]) ->
+ true;
+is_poller(Pid, [_|Rest]) ->
+ is_poller(Pid, Rest).
+
+
+poller_main(Parent, SocketType, Host, Port) ->
+ process_flag(trap_exit,true),
+ put(sname,poller),
+ case timer:tc(?MODULE, poller_loop, [SocketType, Host, Port, uris()]) of
+ {Time, Count} when is_integer(Time) andalso is_integer(Count) ->
+ Parent ! {poller_statistics, self(), {Time, Count}};
+ {Time, {'EXIT', Reason}} when is_integer(Time) ->
+ exit({poller_stat_failure, Time, Reason});
+ {Time, Other} when is_integer(Time) ->
+ Parent ! {poller_stat_failure, self(), {Time, Other}};
+ Else ->
+ Parent ! {poller_stat_failure, self(), Else}
+ end.
+
+
+uris() ->
+ uris(get(uris)).
+
+uris(L) when is_list(L) ->
+ L;
+uris(_) ->
+ ["/",
+ "/index.html"].
+
+
+poller_loop(SocketType, Host, Port, URIs) ->
+ poller_loop(SocketType, Host, Port, URIs, 0).
+
+poller_loop(SocketType, Host, Port, URIs, Count) ->
+ receive
+ stop ->
+ Count
+ after 0 ->
+ case poller_loop1(SocketType, Host, Port, URIs) of
+ done ->
+ poller_loop(SocketType, Host, Port, URIs,
+ Count + length(URIs));
+ {error, Reason, FailURI, FailURIs} ->
+ SuccessCount =
+ Count + (length(URIs) - (length(FailURIs) + 1)),
+ exit({Reason, FailURI, SuccessCount})
+ end
+ end.
+
+
+poller_loop1(_SocketType, _Host, _Port, []) ->
+ done;
+poller_loop1(SocketType, Host, Port, [URI | URIs]) ->
+ Res = inets_test_lib:connect_byte(SocketType, Host, Port),
+ case (catch poll(Res, SocketType, URI, "200")) of
+ ok ->
+ poller_loop1(SocketType, Host, Port, URIs);
+ {'EXIT', Reason} ->
+ {error, Reason, URI, URIs}
+ end.
+
+poll({ok, Socket}, SocketType, URI, ExpRes) ->
+ Req = "GET " ++ URI ++ " HTTP/1.0\r\n\r\n",
+ Res = inets_test_lib:send(SocketType, Socket, Req),
+ await_poll_response(Res, SocketType, Socket, ExpRes);
+poll({error, Reason}, _SocketType, _URI, _ExpRes) ->
+ exit({failed_creating_socket, Reason});
+poll(Error, _SocketType, _URI, _ExpRes) ->
+ exit({failed_creating_socket, Error}).
+
+await_poll_response(ok, SocketType, Socket, ExpStatusCode) ->
+ receive
+ %% SSL receives
+ {ssl, Socket, Data} ->
+ validate(ExpStatusCode, SocketType, Socket, Data);
+ {ssl_closed, Socket} ->
+ exit(connection_closed);
+ {ssl_error, Socket, Error} ->
+ exit({connection_error, Error});
+
+ %% TCP receives
+ {tcp, Socket, Response} ->
+ validate(ExpStatusCode, SocketType, Socket, Response);
+ {tcp_closed, Socket} ->
+ exit(connection_closed);
+ {tcp_error, Socket, Error} ->
+ exit({connection_error, Error})
+
+ after 10000 ->
+ exit(response_timed_out)
+ end;
+await_poll_response(Error, _SocketType, _Socket, _ExpStatusCode) ->
+ exit(Error).
+
+
+validate(ExpStatusCode, SocketType, Socket, Response) ->
+ Sz = sz(Response),
+ trash_the_rest(Socket, Sz),
+ inets_test_lib:close(SocketType, Socket),
+ case inets_regexp:split(Response," ") of
+ {ok,["HTTP/1.0", ExpStatusCode|_]} ->
+ ok;
+ {ok,["HTTP/1.0", StatusCode|_]} ->
+ error_msg("Unexpected status code: ~p (~s). "
+ "Expected status code: ~p (~s)",
+ [StatusCode, status_to_message(StatusCode),
+ ExpStatusCode, status_to_message(ExpStatusCode)]),
+ exit({unexpected_response_code, StatusCode, ExpStatusCode});
+ {ok,["HTTP/1.1", ExpStatusCode|_]} ->
+ ok;
+ {ok,["HTTP/1.1", StatusCode|_]} ->
+ error_msg("Unexpected status code: ~p (~s). "
+ "Expected status code: ~p (~s)",
+ [StatusCode, status_to_message(StatusCode),
+ ExpStatusCode, status_to_message(ExpStatusCode)]),
+ exit({unexpected_response_code, StatusCode, ExpStatusCode})
+ end.
+
+
+trash_the_rest(Socket, N) ->
+ receive
+ {ssl, Socket, Trash} ->
+ trash_the_rest(Socket, add(N,sz(Trash)));
+ {ssl_closed, Socket} ->
+ N;
+ {ssl_error, Socket, Error} ->
+ exit({connection_error, Error});
+
+ {tcp, Socket, Trash} ->
+ trash_the_rest(Socket, add(N,sz(Trash)));
+ {tcp_closed, Socket} ->
+ N;
+ {tcp_error, Socket, Error} ->
+ exit({connection_error, Error})
+
+ after 10000 ->
+ exit({connection_timed_out, N})
+ end.
+
+
+add(N1,N2) when is_integer(N1) andalso is_integer(N2) ->
+ N1 + N2;
+add(N1,_) when is_integer(N1) ->
+ N1;
+add(_,N2) when is_integer(N2) ->
+ N2.
+
+
+sz(L) when is_list(L) ->
+ length(lists:flatten(L));
+sz(B) when is_binary(B) ->
+ size(B);
+sz(O) ->
+ {unknown_size,O}.
+
+
+%% --------------------------------------------------------------
+%%
+%% Status code to printable string
+%%
+
+status_to_message(L) when is_list(L) ->
+ case (catch list_to_integer(L)) of
+ I when is_integer(I) ->
+ status_to_message(I);
+ _ ->
+ io_lib:format("UNKNOWN STATUS CODE: '~p'",[L])
+ end;
+status_to_message(100) -> "Section 10.1.1: Continue";
+status_to_message(101) -> "Section 10.1.2: Switching Protocols";
+status_to_message(200) -> "Section 10.2.1: OK";
+status_to_message(201) -> "Section 10.2.2: Created";
+status_to_message(202) -> "Section 10.2.3: Accepted";
+status_to_message(203) -> "Section 10.2.4: Non-Authoritative Information";
+status_to_message(204) -> "Section 10.2.5: No Content";
+status_to_message(205) -> "Section 10.2.6: Reset Content";
+status_to_message(206) -> "Section 10.2.7: Partial Content";
+status_to_message(300) -> "Section 10.3.1: Multiple Choices";
+status_to_message(301) -> "Section 10.3.2: Moved Permanently";
+status_to_message(302) -> "Section 10.3.3: Found";
+status_to_message(303) -> "Section 10.3.4: See Other";
+status_to_message(304) -> "Section 10.3.5: Not Modified";
+status_to_message(305) -> "Section 10.3.6: Use Proxy";
+status_to_message(307) -> "Section 10.3.8: Temporary Redirect";
+status_to_message(400) -> "Section 10.4.1: Bad Request";
+status_to_message(401) -> "Section 10.4.2: Unauthorized";
+status_to_message(402) -> "Section 10.4.3: Peyment Required";
+status_to_message(403) -> "Section 10.4.4: Forbidden";
+status_to_message(404) -> "Section 10.4.5: Not Found";
+status_to_message(405) -> "Section 10.4.6: Method Not Allowed";
+status_to_message(406) -> "Section 10.4.7: Not Acceptable";
+status_to_message(407) -> "Section 10.4.8: Proxy Authentication Required";
+status_to_message(408) -> "Section 10.4.9: Request Time-Out";
+status_to_message(409) -> "Section 10.4.10: Conflict";
+status_to_message(410) -> "Section 10.4.11: Gone";
+status_to_message(411) -> "Section 10.4.12: Length Required";
+status_to_message(412) -> "Section 10.4.13: Precondition Failed";
+status_to_message(413) -> "Section 10.4.14: Request Entity Too Large";
+status_to_message(414) -> "Section 10.4.15: Request-URI Too Large";
+status_to_message(415) -> "Section 10.4.16: Unsupported Media Type";
+status_to_message(416) -> "Section 10.4.17: Requested range not satisfiable";
+status_to_message(417) -> "Section 10.4.18: Expectation Failed";
+status_to_message(500) -> "Section 10.5.1: Internal Server Error";
+status_to_message(501) -> "Section 10.5.2: Not Implemented";
+status_to_message(502) -> "Section 10.5.3: Bad Gatteway";
+status_to_message(503) -> "Section 10.5.4: Service Unavailable";
+status_to_message(504) -> "Section 10.5.5: Gateway Time-out";
+status_to_message(505) -> "Section 10.5.6: HTTP Version not supported";
+status_to_message(Code) -> io_lib:format("Unknown status code: ~p",[Code]).
+
+%% ----------------------------------------------------------------
+
+to(To, Start) ->
+ To - (t() - Start).
+
+%% Time in milli seconds
+t() ->
+ {A,B,C} = erlang:now(),
+ A*1000000000+B*1000+(C div 1000).
+
+
+%% ----------------------------------------------------------------
+
+
+
+% close(Socket) ->
+% gen_tcp:close(Socket).
+
+% send(Socket, Data) ->
+% gen_tcp:send(Socket, Data).
+
+
+hostname() ->
+ {ok, Hostname} = inet:gethostname(),
+ hostname(Hostname).
+
+hostname(Hostname) when is_list(Hostname) ->
+ list_to_atom(Hostname);
+hostname(Hostname) ->
+ Hostname.
+
+%% ----------------------------------------------------------------
+
+error_msg(F,A) -> error_logger:error_msg(F ++ "~n",A).
+
+d(F) ->
+ d(get(dbg),F,[]).
+
+d(F,A) ->
+ d(get(dbg),F,A).
+
+d(true, F, A) ->
+ io:format("DBG ~p ~p " ++ F ++ "~n", [self(),get(sname)]++A);
+d(_,_,_) ->
+ ok.
diff --git a/lib/inets/test/inets.config b/lib/inets/test/inets.config
new file mode 100644
index 0000000000..6c9077594d
--- /dev/null
+++ b/lib/inets/test/inets.config
@@ -0,0 +1 @@
+[{inets,[{services,[{httpd,"/ldisk/tests/bmk/inets/priv_dir/8099.conf"}]}]}].
diff --git a/lib/inets/test/inets.spec b/lib/inets/test/inets.spec
new file mode 100644
index 0000000000..ba525f62c1
--- /dev/null
+++ b/lib/inets/test/inets.spec
@@ -0,0 +1,2 @@
+{topcase, {dir, "../inets_test"}}.
+{hosts, ["fobi"]}.
diff --git a/lib/inets/test/inets.spec.vxworks b/lib/inets/test/inets.spec.vxworks
new file mode 100644
index 0000000000..6886299226
--- /dev/null
+++ b/lib/inets/test/inets.spec.vxworks
@@ -0,0 +1,5 @@
+{topcase, {dir, "../inets_test"}}.
+{skip, {inets_SUITE, ip_mod_cgi, "Requires processes"}}.
+{skip, {inets_SUITE, ip_mod_all_modules, "Requires processes"}}.
+{skip, {inets_SUITE, ssl, "Requires SSL"}}.
+
diff --git a/lib/inets/test/inets_SUITE.erl b/lib/inets/test/inets_SUITE.erl
new file mode 100644
index 0000000000..56983caace
--- /dev/null
+++ b/lib/inets/test/inets_SUITE.erl
@@ -0,0 +1,583 @@
+%%
+%% %CopyrightBegin%
+%%
+%% 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(inets_SUITE).
+
+-include("test_server.hrl").
+-include("test_server_line.hrl").
+-include("inets_test_lib.hrl").
+
+%% Note: This directive should only be used in test suites.
+-compile(export_all).
+
+-define(NUM_DEFAULT_SERVICES, 1).
+
+all(doc) ->
+ ["Test suites for the inets application."];
+
+all(suite) ->
+ [
+ app_test,
+ appup_test,
+ services_test,
+ httpd_reload
+ ].
+
+services_test(suite) ->
+ [
+ start_inets,
+ start_httpc,
+ start_httpd,
+ start_ftpc,
+ start_tftpd
+ ].
+
+
+%%--------------------------------------------------------------------
+%% Function: init_per_suite(Config) -> Config
+%% Config - [tuple()]
+%% A list of key/value pairs, holding the test case configuration.
+%% Description: Initiation 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) ->
+ 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) ->
+ ok.
+
+%%--------------------------------------------------------------------
+%% Function: init_per_testcase(Case, 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: Initiation 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.
+%%--------------------------------------------------------------------
+init_per_testcase(_Case, Config) ->
+ inets:stop(),
+ Config.
+
+%%--------------------------------------------------------------------
+%% Function: end_per_testcase(Case, 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(_, Config) ->
+ Config.
+
+%%-------------------------------------------------------------------------
+%% Test cases starts here.
+%%-------------------------------------------------------------------------
+app_test(suite) ->
+ [{inets_app_test, all}].
+
+appup_test(suite) ->
+ [{inets_appup_test, all}].
+
+
+%%-------------------------------------------------------------------------
+
+start_inets(doc) ->
+ ["Test inets API functions"];
+start_inets(suite) ->
+ [];
+start_inets(Config) when is_list(Config) ->
+ [_|_] = inets:service_names(),
+
+ {error,inets_not_started} = inets:services(),
+ {error,inets_not_started} = inets:services_info(),
+
+ ok = inets:start(),
+
+ %% httpc default profile always started
+ [_|_] = inets:services(),
+ [_|_] = inets:services_info(),
+
+ {error,{already_started,inets}} = inets:start(),
+
+ ok = inets:stop(),
+ {error,{not_started,inets}} = inets:stop(),
+
+ ok = inets:start(transient),
+ ok = inets:stop(),
+
+ ok = inets:start(permanent),
+ ok = inets:stop().
+
+
+%%-------------------------------------------------------------------------
+
+start_httpc(doc) ->
+ ["Start/stop of httpc service"];
+start_httpc(suite) ->
+ [];
+start_httpc(Config) when is_list(Config) ->
+ process_flag(trap_exit, true),
+ tsp("start_httpc -> entry with"
+ "~n Config: ~p", [Config]),
+
+ PrivDir = ?config(priv_dir, Config),
+
+ tsp("start_httpc -> start (empty) inets"),
+ ok = inets:start(),
+
+ tsp("start_httpc -> start httpc (as inets service) with profile foo"),
+ {ok, Pid0} = inets:start(httpc, [{profile, foo}]),
+
+ tsp("start_httpc -> check running services"),
+ Pids0 = [ServicePid || {_, ServicePid} <- inets:services()],
+ true = lists:member(Pid0, Pids0),
+ [_|_] = inets:services_info(),
+
+ tsp("start_httpc -> stop httpc"),
+ inets:stop(httpc, Pid0),
+
+ tsp("start_httpc -> sleep some"),
+ test_server:sleep(100),
+
+ tsp("start_httpc -> check running services"),
+ Pids1 = [ServicePid || {_, ServicePid} <- inets:services()],
+ false = lists:member(Pid0, Pids1),
+
+ tsp("start_httpc -> start httpc (stand-alone) with profile bar"),
+ {ok, Pid1} = inets:start(httpc, [{profile, bar}], stand_alone),
+
+ tsp("start_httpc -> check running services"),
+ Pids2 = [ServicePid || {_, ServicePid} <- inets:services()],
+ false = lists:member(Pid1, Pids2),
+
+ tsp("start_httpc -> stop httpc"),
+ ok = inets:stop(stand_alone, Pid1),
+ receive
+ {'EXIT', Pid1, shutdown} ->
+ ok
+ after 100 ->
+ tsf(stand_alone_not_shutdown)
+ end,
+
+ tsp("start_httpc -> stop inets"),
+ ok = inets:stop(),
+
+ tsp("start_httpc -> unload inets"),
+ application:load(inets),
+
+ tsp("start_httpc -> set inets environment (httpc profile foo)"),
+ application:set_env(inets, services, [{httpc,[{profile, foo},
+ {data_dir, PrivDir}]}]),
+
+ tsp("start_httpc -> start inets"),
+ ok = inets:start(),
+
+ tsp("start_httpc -> check running services"),
+ (?NUM_DEFAULT_SERVICES + 1) = length(inets:services()),
+
+ tsp("start_httpc -> unset inets env"),
+ application:unset_env(inets, services),
+
+ tsp("start_httpc -> stop inets"),
+ ok = inets:stop(),
+
+ tsp("start_httpc -> start (empty) inets"),
+ ok = inets:start(),
+
+ tsp("start_httpc -> start inets httpc service with profile foo"),
+ {ok, Pid3} = inets:start(httpc, [{profile, foo}]),
+
+ tsp("start_httpc -> stop inets service httpc with profile foo"),
+ ok = inets:stop(httpc, foo),
+
+ tsp("start_httpc -> check running services"),
+ Pids3 = [ServicePid || {_, ServicePid} <- inets:services()],
+ false = lists:member(Pid3, Pids3),
+
+ tsp("start_httpc -> stop inets"),
+ ok = inets:stop(),
+
+ tsp("start_httpc -> done"),
+ ok.
+
+
+%%-------------------------------------------------------------------------
+
+start_httpd(doc) ->
+ ["Start/stop of httpd service"];
+start_httpd(suite) ->
+ [];
+start_httpd(Config) when is_list(Config) ->
+ process_flag(trap_exit, true),
+ i("start_httpd -> entry with"
+ "~n Config: ~p", [Config]),
+ PrivDir = ?config(priv_dir, Config),
+ HttpdConf = [{server_name, "httpd_test"}, {server_root, PrivDir},
+ {document_root, PrivDir}, {bind_address, "localhost"}],
+
+ i("start_httpd -> start inets"),
+ ok = inets:start(),
+
+ i("start_httpd -> start httpd service"),
+ {ok, Pid0} = inets:start(httpd, [{port, 0}, {ipfamily, inet} | HttpdConf]),
+ Pids0 = [ServicePid || {_, ServicePid} <- inets:services()],
+ true = lists:member(Pid0, Pids0),
+ [_|_] = inets:services_info(),
+
+ i("start_httpd -> stop httpd service"),
+ inets:stop(httpd, Pid0),
+ test_server:sleep(500),
+ Pids1 = [ServicePid || {_, ServicePid} <- inets:services()],
+ false = lists:member(Pid0, Pids1),
+ i("start_httpd -> start (stand-alone) httpd service"),
+ {ok, Pid1} =
+ inets:start(httpd, [{port, 0}, {ipfamily, inet} | HttpdConf],
+ stand_alone),
+ Pids2 = [ServicePid || {_, ServicePid} <- inets:services()],
+ false = lists:member(Pid1, Pids2),
+ i("start_httpd -> stop (stand-alone) httpd service"),
+ ok = inets:stop(stand_alone, Pid1),
+ receive
+ {'EXIT', Pid1, shutdown} ->
+ ok
+ after 100 ->
+ test_server:fail(stand_alone_not_shutdown)
+ end,
+ i("start_httpd -> stop inets"),
+ ok = inets:stop(),
+ File0 = filename:join(PrivDir, "httpd.conf"),
+ {ok, Fd0} = file:open(File0, [write]),
+ Str = io_lib:format("~p.~n", [[{port, 0}, {ipfamily, inet} | HttpdConf]]),
+ ok = file:write(Fd0, Str),
+ file:close(Fd0),
+
+ i("start_httpd -> [application] load inets"),
+ application:load(inets),
+ i("start_httpd -> [application] set httpd services env with proplist-file"),
+ application:set_env(inets,
+ services, [{httpd, [{proplist_file, File0}]}]),
+ i("start_httpd -> start inets"),
+ ok = inets:start(),
+ (?NUM_DEFAULT_SERVICES + 1) = length(inets:services()),
+ i("start_httpd -> [application] unset services env"),
+ application:unset_env(inets, services),
+ i("start_httpd -> stop inets"),
+ ok = inets:stop(),
+
+ File1 = filename:join(PrivDir, "httpd_apache.conf"),
+
+ {ok, Fd1} = file:open(File1, [write]),
+ file:write(Fd1, "ServerName httpd_test\r\n"),
+ file:write(Fd1, "ServerRoot " ++ PrivDir ++ "\r\n"),
+ file:write(Fd1, "DocumentRoot " ++ PrivDir ++" \r\n"),
+ file:write(Fd1, "BindAddress *|inet\r\n"),
+ file:write(Fd1, "Port 0\r\n"),
+ file:close(Fd1),
+
+ i("start_httpd -> [application] load inets"),
+ application:load(inets),
+ i("start_httpd -> [application] set httpd services env with file"),
+ application:set_env(inets,
+ services, [{httpd, [{file, File1}]}]),
+ i("start_httpd -> start inets"),
+ ok = inets:start(),
+ (?NUM_DEFAULT_SERVICES + 1) = length(inets:services()),
+ i("start_httpd -> [application] unset services env"),
+ application:unset_env(inets, services),
+ i("start_httpd -> stop inets"),
+ ok = inets:stop(),
+
+ %% OLD format
+ i("start_httpd -> [application] load inets"),
+ application:load(inets),
+ i("start_httpd -> [application] set httpd services OLD env"),
+ application:set_env(inets,
+ services, [{httpd, File1}]),
+ i("start_httpd -> start inets"),
+ ok = inets:start(),
+ (?NUM_DEFAULT_SERVICES + 1) = length(inets:services()),
+ i("start_httpd -> [application] unset services enc"),
+ application:unset_env(inets, services),
+ i("start_httpd -> stop inets"),
+ ok = inets:stop(),
+
+ i("start_httpd -> start inets"),
+ ok = inets:start(),
+ i("start_httpd -> try (and fail) start httpd service - server_name"),
+ {error, {missing_property, server_name}} =
+ inets:start(httpd, [{port, 0},
+ {server_root, PrivDir},
+ {document_root, PrivDir},
+ {bind_address, "localhost"}]),
+ i("start_httpd -> try (and fail) start httpd service - missing document_root"),
+ {error, {missing_property, document_root}} =
+ inets:start(httpd, [{port, 0},
+ {server_name, "httpd_test"},
+ {server_root, PrivDir},
+ {bind_address, "localhost"}]),
+ i("start_httpd -> try (and fail) start httpd service - missing server_root"),
+ {error, {missing_property, server_root}} =
+ inets:start(httpd, [{port, 0},
+ {server_name, "httpd_test"},
+ {document_root, PrivDir},
+ {bind_address, "localhost"}]),
+ i("start_httpd -> try (and fail) start httpd service - missing port"),
+ {error, {missing_property, port}} =
+ inets:start(httpd, HttpdConf),
+ i("start_httpd -> stop inets"),
+ ok = inets:stop(),
+ i("start_httpd -> done"),
+ ok.
+
+
+%%-------------------------------------------------------------------------
+
+start_ftpc(doc) ->
+ ["Start/stop of ftpc service"];
+start_ftpc(suite) ->
+ [];
+start_ftpc(Config) when is_list(Config) ->
+ process_flag(trap_exit, true),
+ inets:disable_trace(),
+ inets:enable_trace(max, io, ftpc),
+ ok = inets:start(),
+ try
+ begin
+ {_Tag, FtpdHost} = ftp_suite_lib:dirty_select_ftpd_host(Config),
+ case inets:start(ftpc, [{host, FtpdHost}]) of
+ {ok, Pid0} ->
+ Pids0 = [ServicePid || {_, ServicePid} <-
+ inets:services()],
+ true = lists:member(Pid0, Pids0),
+ [_|_] = inets:services_info(),
+ inets:stop(ftpc, Pid0),
+ test_server:sleep(100),
+ Pids1 = [ServicePid || {_, ServicePid} <-
+ inets:services()],
+ false = lists:member(Pid0, Pids1),
+ {ok, Pid1} =
+ inets:start(ftpc, [{host, FtpdHost}], stand_alone),
+ Pids2 = [ServicePid || {_, ServicePid} <-
+ inets:services()],
+ false = lists:member(Pid1, Pids2),
+ ok = inets:stop(stand_alone, Pid1),
+ receive
+ {'EXIT', Pid1, shutdown} ->
+ ok
+ after 100 ->
+ tsf(stand_alone_not_shutdown)
+ end,
+ ok = inets:stop(),
+ inets:disable_trace(),
+ ok;
+ _ ->
+ inets:disable_trace(),
+ {skip, "Unable to reach selected FTP server " ++ FtpdHost}
+ end
+ end
+ catch
+ throw:{error, not_found} ->
+ inets:disable_trace(),
+ {skip, "No available FTP servers"}
+ end.
+
+
+
+%%-------------------------------------------------------------------------
+
+start_tftpd(doc) ->
+ ["Start/stop of tfpd service"];
+start_tftpd(suite) ->
+ [];
+start_tftpd(Config) when is_list(Config) ->
+ process_flag(trap_exit, true),
+ ok = inets:start(),
+ {ok, Pid0} = inets:start(tftpd, [{host, "localhost"}, {port, 0}]),
+ Pids0 = [ServicePid || {_, ServicePid} <- inets:services()],
+ true = lists:member(Pid0, Pids0),
+ [_|_] = inets:services_info(),
+ inets:stop(tftpd, Pid0),
+ test_server:sleep(100),
+ Pids1 = [ServicePid || {_, ServicePid} <- inets:services()],
+ false = lists:member(Pid0, Pids1),
+ {ok, Pid1} =
+ inets:start(tftpd, [{host, "localhost"}, {port, 0}], stand_alone),
+ Pids2 = [ServicePid || {_, ServicePid} <- inets:services()],
+ false = lists:member(Pid1, Pids2),
+ ok = inets:stop(stand_alone, Pid1),
+ receive
+ {'EXIT', Pid1, shutdown} ->
+ ok
+ after 100 ->
+ test_server:fail(stand_alone_not_shutdown)
+ end,
+ ok = inets:stop(),
+ application:load(inets),
+ application:set_env(inets, services, [{tftpd,[{host, "localhost"},
+ {port, 0}]}]),
+ ok = inets:start(),
+ (?NUM_DEFAULT_SERVICES + 1) = length(inets:services()),
+ application:unset_env(inets, services),
+ ok = inets:stop().
+
+
+%%-------------------------------------------------------------------------
+
+httpd_reload(doc) ->
+ ["Reload httpd configuration without restarting service"];
+httpd_reload(suite) ->
+ [];
+httpd_reload(Config) when is_list(Config) ->
+ process_flag(trap_exit, true),
+ i("httpd_reload -> starting"),
+ PrivDir = ?config(priv_dir, Config),
+ DataDir = ?config(data_dir, Config),
+ HttpdConf = [{server_name, "httpd_test"},
+ {server_root, PrivDir},
+ {document_root, PrivDir},
+ {bind_address, "localhost"}],
+
+ inets:enable_trace(max, io),
+
+ i("httpd_reload -> start inets"),
+
+ ok = inets:start(),
+ test_server:sleep(5000),
+ i("httpd_reload -> inets started - start httpd service"),
+
+ {ok, Pid0} = inets:start(httpd, [{port, 0}, {ipfamily, inet} | HttpdConf]),
+ test_server:sleep(5000),
+ i("httpd_reload -> httpd service started (~p) - get port", [Pid0]),
+
+ [{port, Port0}] = httpd:info(Pid0, [port]),
+ test_server:sleep(5000),
+ i("httpd_reload -> Port: ~p - get document root", [Port0]),
+
+ [{document_root, PrivDir}] = httpd:info(Pid0, [document_root]),
+ test_server:sleep(5000),
+ i("httpd_reload -> document root: ~p - reload config", [PrivDir]),
+
+ ok = httpd:reload_config([{port, Port0}, {ipfamily, inet},
+ {server_name, "httpd_test"},
+ {server_root, PrivDir},
+ {document_root, DataDir},
+ {bind_address, "localhost"}], non_disturbing),
+ test_server:sleep(5000),
+ io:format("~w:~w:httpd_reload - reloaded - get document root~n", [?MODULE, ?LINE]),
+
+ [{document_root, DataDir}] = httpd:info(Pid0, [document_root]),
+ test_server:sleep(5000),
+ i("httpd_reload -> document root: ~p - reload config", [DataDir]),
+
+ ok = httpd:reload_config([{port, Port0}, {ipfamily, inet},
+ {server_name, "httpd_test"},
+ {server_root, PrivDir},
+ {document_root, PrivDir},
+ {bind_address, "localhost"}], disturbing),
+
+ [{document_root, PrivDir}] = httpd:info(Pid0, [document_root]),
+ ok = inets:stop(httpd, Pid0),
+ ok = inets:stop(),
+
+ File = filename:join(PrivDir, "httpd_apache.conf"),
+
+ {ok, Fd0} = file:open(File, [write]),
+ file:write(Fd0, "ServerName httpd_test\r\n"),
+ file:write(Fd0, "ServerRoot " ++ PrivDir ++ "\r\n"),
+ file:write(Fd0, "DocumentRoot " ++ PrivDir ++" \r\n"),
+ file:write(Fd0, "BindAddress *\r\n"),
+ file:write(Fd0, "Port 0\r\n"),
+ file:close(Fd0),
+
+ application:load(inets),
+ application:set_env(inets,
+ services, [{httpd, [{file, File}]}]),
+
+ ok = inets:start(),
+ [Pid1] = [HttpdPid || {httpd, HttpdPid} <- inets:services()],
+ [{server_name, "httpd_test"}] = httpd:info(Pid1, [server_name]),
+ [{port, Port1}] = httpd:info(Pid1, [port]),
+ {ok, Fd1} = file:open(File, [write]),
+ file:write(Fd1, "ServerName httpd_test2\r\n"),
+ file:write(Fd1, "ServerRoot " ++ PrivDir ++ "\r\n"),
+ file:write(Fd1, "DocumentRoot " ++ PrivDir ++" \r\n"),
+ file:write(Fd1, "BindAddress *\r\n"),
+ file:write(Fd1, "Port " ++ integer_to_list(Port1) ++ "\r\n"),
+ file:close(Fd1),
+
+ ok = httpd:reload_config(File, non_disturbing),
+ [{server_name, "httpd_test2"}] = httpd:info(Pid1, [server_name]),
+
+ {ok, Fd2} = file:open(File, [write]),
+ file:write(Fd2, "ServerName httpd_test\r\n"),
+ file:write(Fd2, "ServerRoot " ++ PrivDir ++ "\r\n"),
+ file:write(Fd2, "DocumentRoot " ++ PrivDir ++" \r\n"),
+ file:write(Fd2, "BindAddress *\r\n"),
+ file:write(Fd2, "Port " ++ integer_to_list(Port1) ++ "\r\n"),
+ file:close(Fd2),
+ ok = httpd:reload_config(File, disturbing),
+ [{server_name, "httpd_test"}] = httpd:info(Pid1, [server_name]),
+
+ ok = inets:stop(httpd, Pid1),
+ application:unset_env(inets, services),
+ ok = inets:stop(),
+ i("httpd_reload -> starting"),
+ ok.
+
+
+tsf(Reason) ->
+ test_server:fail(Reason).
+
+tsp(F) ->
+ tsp(F, []).
+tsp(F, A) ->
+ Timestamp = formated_timestamp(),
+ test_server:format("** ~s ** ~p ~p:" ++ F ++ "~n", [Timestamp, self(), ?MODULE | A]).
+
+i(F) ->
+ i(F, []).
+
+i(F, A) ->
+ Timestamp = formated_timestamp(),
+ io:format("*** ~s ~w:" ++ F ++ "~n", [Timestamp, ?MODULE | A]).
+
+formated_timestamp() ->
+ format_timestamp( os:timestamp() ).
+
+format_timestamp({_N1, _N2, N3} = Now) ->
+ {Date, Time} = calendar:now_to_datetime(Now),
+ {YYYY,MM,DD} = Date,
+ {Hour,Min,Sec} = Time,
+ FormatDate =
+ io_lib:format("~.4w:~.2.0w:~.2.0w ~.2.0w:~.2.0w:~.2.0w 4~w",
+ [YYYY,MM,DD,Hour,Min,Sec,round(N3/1000)]),
+ lists:flatten(FormatDate).
+
diff --git a/lib/inets/test/inets_SUITE_data/.gitignore b/lib/inets/test/inets_SUITE_data/.gitignore
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/lib/inets/test/inets_SUITE_data/.gitignore
diff --git a/lib/inets/test/inets_app_test.erl b/lib/inets/test/inets_app_test.erl
new file mode 100644
index 0000000000..6bdb9bb308
--- /dev/null
+++ b/lib/inets/test/inets_app_test.erl
@@ -0,0 +1,296 @@
+%%
+%% %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%
+%%
+%%
+%%----------------------------------------------------------------------
+%% Purpose: Verify the application specifics of the inets application
+%%----------------------------------------------------------------------
+-module(inets_app_test).
+
+-compile(export_all).
+
+-include("inets_test_lib.hrl").
+
+
+% t() -> megaco_test_lib:t(?MODULE).
+% t(Case) -> megaco_test_lib:t({?MODULE, Case}).
+
+
+%% Test server callbacks
+init_per_testcase(undef_funcs, Config) ->
+ NewConfig = lists:keydelete(watchdog, 1, Config),
+ Dog = test_server:timetrap(inets_test_lib:minutes(10)),
+ [{watchdog, Dog}| NewConfig];
+init_per_testcase(_, Config) ->
+ Config.
+
+fin_per_testcase(_Case, Config) ->
+ Config.
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+all(suite) ->
+ Cases =
+ [
+ fields,
+ modules,
+ exportall,
+ app_depend,
+ undef_funcs
+ ],
+ {req, [], {conf, app_init, Cases, app_fin}}.
+
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+app_init(suite) -> [];
+app_init(doc) -> [];
+app_init(Config) when is_list(Config) ->
+ case is_app(inets) of
+ {ok, AppFile} ->
+ io:format("AppFile: ~n~p~n", [AppFile]),
+ inets:print_version_info(),
+ [{app_file, AppFile}|Config];
+ {error, Reason} ->
+ fail(Reason)
+ end.
+
+is_app(App) ->
+ LibDir = code:lib_dir(App),
+ File = filename:join([LibDir, "ebin", atom_to_list(App) ++ ".app"]),
+ case file:consult(File) of
+ {ok, [{application, App, AppFile}]} ->
+ {ok, AppFile};
+ Error ->
+ {error, {invalid_format, Error}}
+ end.
+
+
+app_fin(suite) -> [];
+app_fin(doc) -> [];
+app_fin(Config) when is_list(Config) ->
+ Config.
+
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+fields(suite) ->
+ [];
+fields(doc) ->
+ [];
+fields(Config) when is_list(Config) ->
+ AppFile = key1search(app_file, Config),
+ Fields = [vsn, description, modules, registered, applications],
+ case check_fields(Fields, AppFile, []) of
+ [] ->
+ ok;
+ Missing ->
+ fail({missing_fields, Missing})
+ end.
+
+check_fields([], _AppFile, Missing) ->
+ Missing;
+check_fields([Field|Fields], AppFile, Missing) ->
+ check_fields(Fields, AppFile, check_field(Field, AppFile, Missing)).
+
+check_field(Name, AppFile, Missing) ->
+ io:format("checking field: ~p~n", [Name]),
+ case lists:keymember(Name, 1, AppFile) of
+ true ->
+ Missing;
+ false ->
+ [Name|Missing]
+ end.
+
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+modules(suite) ->
+ [];
+modules(doc) ->
+ [];
+modules(Config) when is_list(Config) ->
+ AppFile = key1search(app_file, Config),
+ Mods = key1search(modules, AppFile),
+ EbinList = get_ebin_mods(inets),
+ case missing_modules(Mods, EbinList, []) of
+ [] ->
+ ok;
+ Missing ->
+ throw({error, {missing_modules, Missing}})
+ end,
+ case extra_modules(Mods, EbinList, []) of
+ [] ->
+ ok;
+ Extra ->
+ throw({error, {extra_modules, Extra}})
+ end,
+ {ok, Mods}.
+
+get_ebin_mods(App) ->
+ LibDir = code:lib_dir(App),
+ EbinDir = filename:join([LibDir,"ebin"]),
+ {ok, Files0} = file:list_dir(EbinDir),
+ Files1 = [lists:reverse(File) || File <- Files0],
+ [list_to_atom(lists:reverse(Name)) || [$m,$a,$e,$b,$.|Name] <- Files1].
+
+
+missing_modules([], _Ebins, Missing) ->
+ Missing;
+missing_modules([Mod|Mods], Ebins, Missing) ->
+ case lists:member(Mod, Ebins) of
+ true ->
+ missing_modules(Mods, Ebins, Missing);
+ false ->
+ io:format("missing module: ~p~n", [Mod]),
+ missing_modules(Mods, Ebins, [Mod|Missing])
+ end.
+
+
+extra_modules(_Mods, [], Extra) ->
+ Extra;
+extra_modules(Mods, [Mod|Ebins], Extra) ->
+ case lists:member(Mod, Mods) of
+ true ->
+ extra_modules(Mods, Ebins, Extra);
+ false ->
+ io:format("supefluous module: ~p~n", [Mod]),
+ extra_modules(Mods, Ebins, [Mod|Extra])
+ end.
+
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+
+exportall(suite) ->
+ [];
+exportall(doc) ->
+ [];
+exportall(Config) when is_list(Config) ->
+ AppFile = key1search(app_file, Config),
+ Mods = key1search(modules, AppFile),
+ check_export_all(Mods).
+
+
+check_export_all([]) ->
+ ok;
+check_export_all([Mod|Mods]) ->
+ case (catch apply(Mod, module_info, [compile])) of
+ {'EXIT', {undef, _}} ->
+ check_export_all(Mods);
+ O ->
+ case lists:keysearch(options, 1, O) of
+ false ->
+ check_export_all(Mods);
+ {value, {options, List}} ->
+ case lists:member(export_all, List) of
+ true ->
+ throw({error, {export_all, Mod}});
+ false ->
+ check_export_all(Mods)
+ end
+ end
+ end.
+
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+app_depend(suite) ->
+ [];
+app_depend(doc) ->
+ [];
+app_depend(Config) when is_list(Config) ->
+ AppFile = key1search(app_file, Config),
+ Apps = key1search(applications, AppFile),
+ check_apps(Apps).
+
+
+check_apps([]) ->
+ ok;
+check_apps([App|Apps]) ->
+ case is_app(App) of
+ {ok, _} ->
+ check_apps(Apps);
+ Error ->
+ throw({error, {missing_app, {App, Error}}})
+ end.
+
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+undef_funcs(suite) ->
+ [];
+undef_funcs(doc) ->
+ [];
+undef_funcs(Config) when is_list(Config) ->
+ App = inets,
+ AppFile = key1search(app_file, Config),
+ Mods = key1search(modules, AppFile),
+ Root = code:root_dir(),
+ LibDir = code:lib_dir(App),
+ EbinDir = filename:join([LibDir,"ebin"]),
+ XRefTestName = undef_funcs_make_name(App, xref_test_name),
+ {ok, XRef} = xref:start(XRefTestName),
+ ok = xref:set_default(XRef,
+ [{verbose,false},{warnings,false}]),
+ XRefName = undef_funcs_make_name(App, xref_name),
+ {ok, XRefName} = xref:add_release(XRef, Root, {name,XRefName}),
+ {ok, App} = xref:replace_application(XRef, App, EbinDir),
+ {ok, Undefs} = xref:analyze(XRef, undefined_function_calls),
+ xref:stop(XRef),
+ analyze_undefined_function_calls(Undefs, Mods, []).
+
+analyze_undefined_function_calls([], _, []) ->
+ ok;
+analyze_undefined_function_calls([], _, AppUndefs) ->
+ exit({suite_failed, {undefined_function_calls, AppUndefs}});
+analyze_undefined_function_calls([{{Mod, _F, _A}, _C} = AppUndef|Undefs],
+ AppModules, AppUndefs) ->
+ %% Check that this module is our's
+ case lists:member(Mod,AppModules) of
+ true ->
+ {Calling,Called} = AppUndef,
+ {Mod1,Func1,Ar1} = Calling,
+ {Mod2,Func2,Ar2} = Called,
+ io:format("undefined function call: "
+ "~n ~w:~w/~w calls ~w:~w/~w~n",
+ [Mod1,Func1,Ar1,Mod2,Func2,Ar2]),
+ analyze_undefined_function_calls(Undefs, AppModules,
+ [AppUndef|AppUndefs]);
+ false ->
+ io:format("dropping ~p~n", [Mod]),
+ analyze_undefined_function_calls(Undefs, AppModules, AppUndefs)
+ end.
+
+%% This function is used simply to avoid cut-and-paste errors later...
+undef_funcs_make_name(App, PostFix) ->
+ list_to_atom(atom_to_list(App) ++ "_" ++ atom_to_list(PostFix)).
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+
+fail(Reason) ->
+ exit({suite_failed, Reason}).
+
+key1search(Key, L) ->
+ case lists:keysearch(Key, 1, L) of
+ undefined ->
+ fail({not_found, Key, L});
+ {value, {Key, Value}} ->
+ Value
+ end.
diff --git a/lib/inets/test/inets_appup_test.erl b/lib/inets/test/inets_appup_test.erl
new file mode 100644
index 0000000000..d580c6c4c5
--- /dev/null
+++ b/lib/inets/test/inets_appup_test.erl
@@ -0,0 +1,336 @@
+%%
+%% %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%
+%%
+%%
+%%----------------------------------------------------------------------
+%% Purpose: Verify the application specifics of the Megaco application
+%%----------------------------------------------------------------------
+-module(inets_appup_test).
+
+-compile(export_all).
+
+-include("inets_test_lib.hrl").
+
+
+% t() -> megaco_test_lib:t(?MODULE).
+% t(Case) -> megaco_test_lib:t({?MODULE, Case}).
+
+
+%% Test server callbacks
+init_per_testcase(_Case, Config) ->
+ Config.
+
+fin_per_testcase(_Case, Config) ->
+ Config.
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+all(suite) ->
+ Cases =
+ [
+ appup
+ ],
+ {req, [], {conf, appup_init, Cases, appup_fin}}.
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+appup_init(suite) -> [];
+appup_init(doc) -> [];
+appup_init(Config) when is_list(Config) ->
+ AppFile = file_name(inets, ".app"),
+ AppupFile = file_name(inets, ".appup"),
+ [{app_file, AppFile}, {appup_file, AppupFile}|Config].
+
+
+file_name(App, Ext) ->
+ LibDir = code:lib_dir(App),
+ filename:join([LibDir, "ebin", atom_to_list(App) ++ Ext]).
+
+
+appup_fin(suite) -> [];
+appup_fin(doc) -> [];
+appup_fin(Config) when is_list(Config) ->
+ Config.
+
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+appup(suite) ->
+ [];
+appup(doc) ->
+ "perform a simple check of the appup file";
+appup(Config) when is_list(Config) ->
+ AppupFile = key1search(appup_file, Config),
+ AppFile = key1search(app_file, Config),
+ Modules = modules(AppFile),
+ check_appup(AppupFile, Modules).
+
+modules(File) ->
+ case file:consult(File) of
+ {ok, [{application,inets,Info}]} ->
+ case lists:keysearch(modules,1,Info) of
+ {value, {modules, Modules}} ->
+ Modules;
+ false ->
+ fail({bad_appinfo, Info})
+ end;
+ Error ->
+ fail({bad_appfile, Error})
+ end.
+
+
+check_appup(AppupFile, Modules) ->
+ case file:consult(AppupFile) of
+ {ok, [{V, UpFrom, DownTo}]} ->
+% io:format("~p => "
+% "~n ~p"
+% "~n ~p"
+% "~n", [V, UpFrom, DownTo]),
+ check_appup(V, UpFrom, DownTo, Modules);
+ Else ->
+ fail({bad_appupfile, Else})
+ end.
+
+
+check_appup(V, UpFrom, DownTo, Modules) ->
+ check_version(V),
+ check_depends(up, UpFrom, Modules),
+ check_depends(down, DownTo, Modules),
+ ok.
+
+
+check_depends(_, [], _) ->
+ ok;
+check_depends(UpDown, [Dep|Deps], Modules) ->
+ check_depend(UpDown, Dep, Modules),
+ check_depends(UpDown, Deps, Modules).
+
+
+check_depend(UpDown, {V, Instructions}, Modules) ->
+ check_version(V),
+ case check_instructions(UpDown,
+ Instructions, Instructions, [], [], Modules) of
+ {_Good, []} ->
+ ok;
+ {_, Bad} ->
+ fail({bad_instructions, Bad, UpDown})
+ end.
+
+
+check_instructions(_, [], _, Good, Bad, _) ->
+ {lists:reverse(Good), lists:reverse(Bad)};
+check_instructions(UpDown, [Instr|Instrs], AllInstr, Good, Bad, Modules) ->
+ case (catch check_instruction(UpDown, Instr, AllInstr, Modules)) of
+ ok ->
+ check_instructions(UpDown, Instrs, AllInstr,
+ [Instr|Good], Bad, Modules);
+ {error, Reason} ->
+ check_instructions(UpDown, Instrs, AllInstr, Good,
+ [{Instr, Reason}|Bad], Modules)
+ end;
+check_instructions(UpDown, Instructions, _, _, _, _) ->
+ fail({bad_instructions, {UpDown, Instructions}}).
+
+%% A new module is added
+check_instruction(up, {add_module, Module}, _, Modules)
+ when is_atom(Module) ->
+ check_module(Module, Modules);
+
+%% An old module is re-added
+check_instruction(down, {add_module, Module}, _, Modules)
+ when is_atom(Module) ->
+ case (catch check_module(Module, Modules)) of
+ {error, {unknown_module, Module, Modules}} ->
+ ok;
+ ok ->
+ error({existing_readded_module, Module})
+ end;
+
+%% Removing a module on upgrade:
+%% - the module has been removed from the app-file.
+%% - check that no module depends on this (removed) module
+check_instruction(up, {remove, {Module, Pre, Post}}, _, Modules)
+ when is_atom(Module), is_atom(Pre), is_atom(Post) ->
+ case (catch check_module(Module, Modules)) of
+ {error, {unknown_module, Module, Modules}} ->
+ check_purge(Pre),
+ check_purge(Post);
+ ok ->
+ error({existing_removed_module, Module})
+ end;
+
+%% Removing a module on downgrade: the module exist
+%% in the app-file.
+check_instruction(down, {remove, {Module, Pre, Post}}, AllInstr, Modules)
+ when is_atom(Module), is_atom(Pre), is_atom(Post) ->
+ case (catch check_module(Module, Modules)) of
+ ok ->
+ check_purge(Pre),
+ check_purge(Post),
+ check_no_remove_depends(Module, AllInstr);
+ {error, {unknown_module, Module, Modules}} ->
+ error({nonexisting_removed_module, Module})
+ end;
+
+check_instruction(up, {load_module, Module, Pre, Post, Depend}, _, Modules)
+ when is_atom(Module), is_atom(Pre), is_atom(Post), is_list(Depend) ->
+ check_module(Module, Modules),
+ check_module_depend(Module, Depend, Modules),
+ check_purge(Pre),
+ check_purge(Post);
+
+check_instruction(down, {load_module, Module, Pre, Post, Depend}, _, Modules)
+ when is_atom(Module), is_atom(Pre), is_atom(Post), is_list(Depend) ->
+ check_module(Module, Modules),
+ % Can not be sure that the the dependent module exists in the new appfile
+ %%check_module_depend(Module, Depend, Modules),
+ check_purge(Pre),
+ check_purge(Post);
+
+
+
+check_instruction(up, {delete_module, Module}, _, Modules)
+ when is_atom(Module) ->
+ case (catch check_module(Module, Modules)) of
+ {error, {unknown_module, Module, Modules}} ->
+ ok;
+ ok ->
+ error({existing_module_deleted, Module})
+ end;
+
+check_instruction(down, {delete_module, Module}, _, Modules)
+ when is_atom(Module) ->
+ check_module(Module, Modules);
+
+
+check_instruction(_, {apply, {Module, Function, Args}}, _, _) when is_atom(Module), is_atom(Function), is_list(Args) ->
+ ok;
+
+check_instruction(_, {update, Module, supervisor}, _, Modules) when is_atom(Module) ->
+ check_module(Module, Modules);
+
+check_instruction(_, {update, Module, {advanced, _}, DepMods}, _, Modules) when is_atom(Module), is_list(DepMods) ->
+ check_module(Module, Modules),
+ check_module_depend(Module, DepMods, Modules);
+
+check_instruction(_, {update, Module, Change, Pre, Post, Depend}, _, Modules)
+ when is_atom(Module), is_atom(Pre), is_atom(Post), is_list(Depend) ->
+ check_module(Module, Modules),
+ check_module_depend(Module, Depend, Modules),
+ check_change(Change),
+ check_purge(Pre),
+ check_purge(Post);
+
+check_instruction(_, {restart_application, inets}, _AllInstr, _Modules) ->
+ ok;
+
+check_instruction(_, {update, Module, {advanced, _}}, _, Modules) ->
+ check_module(Module, Modules);
+
+check_instruction(_, Instr, _AllInstr, _Modules) ->
+ error({error, {unknown_instruction, Instr}}).
+
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+check_version(V) when is_list(V) ->
+ ok;
+check_version(V) ->
+ error({bad_version, V}).
+
+
+check_module(M, Modules) when is_atom(M) ->
+ case lists:member(M,Modules) of
+ true ->
+ ok;
+ false ->
+ error({unknown_module, M, Modules})
+ end;
+check_module(M, _) ->
+ error({bad_module, M}).
+
+
+check_module_depend(M, [], _) when is_atom(M) ->
+ ok;
+check_module_depend(M, Deps, Modules) when is_atom(M), is_list(Deps) ->
+ case [Dep || Dep <- Deps, lists:member(Dep, Modules) == false] of
+ [] ->
+ ok;
+ Unknown ->
+ error({unknown_depend_modules, Unknown})
+ end;
+check_module_depend(_M, D, _Modules) ->
+ error({bad_depend, D}).
+
+
+check_no_remove_depends(_Module, []) ->
+ ok;
+check_no_remove_depends(Module, [Instr|Instrs]) ->
+ check_no_remove_depend(Module, Instr),
+ check_no_remove_depends(Module, Instrs).
+
+check_no_remove_depend(Module, {load_module, Mod, _Pre, _Post, Depend}) ->
+ case lists:member(Module, Depend) of
+ true ->
+ error({removed_module_in_depend, load_module, Mod, Module});
+ false ->
+ ok
+ end;
+check_no_remove_depend(Module, {update, Mod, _Change, _Pre, _Post, Depend}) ->
+ case lists:member(Module, Depend) of
+ true ->
+ error({removed_module_in_depend, update, Mod, Module});
+ false ->
+ ok
+ end;
+check_no_remove_depend(_, _) ->
+ ok.
+
+
+check_change(soft) ->
+ ok;
+check_change({advanced, _Something}) ->
+ ok;
+check_change(Change) ->
+ error({bad_change, Change}).
+
+
+check_purge(soft_purge) ->
+ ok;
+check_purge(brutal_purge) ->
+ ok;
+check_purge(Purge) ->
+ error({bad_purge, Purge}).
+
+
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+error(Reason) ->
+ throw({error, Reason}).
+
+fail(Reason) ->
+ exit({suite_failed, Reason}).
+
+key1search(Key, L) ->
+ case lists:keysearch(Key, 1, L) of
+ undefined ->
+ fail({not_found, Key, L});
+ {value, {Key, Value}} ->
+ Value
+ end.
diff --git a/lib/inets/test/inets_internal.hrl b/lib/inets/test/inets_internal.hrl
new file mode 120000
index 0000000000..3228d7ef6a
--- /dev/null
+++ b/lib/inets/test/inets_internal.hrl
@@ -0,0 +1 @@
+../src/inets_app/inets_internal.hrl \ No newline at end of file
diff --git a/lib/inets/test/inets_sup_SUITE.erl b/lib/inets/test/inets_sup_SUITE.erl
new file mode 100644
index 0000000000..ba41e0960c
--- /dev/null
+++ b/lib/inets/test/inets_sup_SUITE.erl
@@ -0,0 +1,414 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 2004-2010. All Rights Reserved.
+%%
+%% The contents of this file are subject to the Erlang Public License,
+%% Version 1.1, (the "License"); you may not use this file except in
+%% compliance with the License. You should have received a copy of the
+%% Erlang Public License along with this software. If not, it can be
+%% retrieved online at http://www.erlang.org/.
+%%
+%% Software distributed under the License is distributed on an "AS IS"
+%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+%% the License for the specific language governing rights and limitations
+%% under the License.
+%%
+%% %CopyrightEnd%
+%%
+%%
+
+-module(inets_sup_SUITE).
+
+-include("test_server.hrl").
+-include("test_server_line.hrl").
+
+%% Note: This directive should only be used in test suites.
+-compile(export_all).
+
+all(doc) ->
+ ["Test that the inets supervisorstructur is the expected one."];
+all(suite) ->
+ [
+ default_tree,
+ ftpc_worker,
+ tftpd_worker,
+ httpd_subtree,
+ httpc_subtree
+ ].
+
+%%--------------------------------------------------------------------
+%% Function: init_per_suite(Config) -> Config
+%% Config - [tuple()]
+%% A list of key/value pairs, holding the test case configuration.
+%% Description: Initiation 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) ->
+ 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(_) ->
+ inets:stop(),
+ ok.
+
+%%--------------------------------------------------------------------
+%% Function: init_per_testcase(Case, 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: Initiation 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.
+%%--------------------------------------------------------------------
+init_per_testcase(httpd_subtree, Config) ->
+ io:format("init_per_testcase(httpd_subtree) -> entry with"
+ "~n Config: ~p"
+ "~n", [Config]),
+ Dog = test_server:timetrap(?t:minutes(1)),
+ NewConfig = lists:keydelete(watchdog, 1, Config),
+
+ DataDir = ?config(data_dir, Config),
+ PrivDir = ?config(priv_dir, Config),
+ ServerROOT = filename:join(PrivDir, "server_root"),
+ DocROOT = filename:join(PrivDir, "htdocs"),
+ ConfDir = filename:join(ServerROOT, "conf"),
+
+ io:format("init_per_testcase(httpd_subtree) -> create dir(s)"
+ "~n", []),
+ file:make_dir(ServerROOT), %% until http_test is cleaned up!
+ ok = file:make_dir(DocROOT),
+ ok = file:make_dir(ConfDir),
+
+ io:format("init_per_testcase(httpd_subtree) -> copy file(s)"
+ "~n", []),
+ {ok, _} = inets_test_lib:copy_file("simple.conf", DataDir, PrivDir),
+ {ok, _} = inets_test_lib:copy_file("mime.types", DataDir, ConfDir),
+
+ io:format("init_per_testcase(httpd_subtree) -> write file(s)"
+ "~n", []),
+ ConfFile = filename:join(PrivDir, "simple.conf"),
+ {ok, Fd} = file:open(ConfFile, [append]),
+ ok = file:write(Fd, "ServerRoot " ++ ServerROOT ++ "\n"),
+ ok = file:write(Fd, "DocumentRoot " ++ DocROOT ++ "\n"),
+ ok = file:close(Fd),
+
+ %% To make sure application:set_env is not overwritten by any
+ %% app-file settings.
+ io:format("init_per_testcase(httpd_subtree) -> load inets app"
+ "~n", []),
+ application:load(inets),
+ io:format("init_per_testcase(httpd_subtree) -> update inets env"
+ "~n", []),
+ ok = application:set_env(inets, services, [{httpd, ConfFile}]),
+
+ try
+ io:format("init_per_testcase(httpd_subtree) -> start inets app"
+ "~n", []),
+ ok = inets:start(),
+ io:format("init_per_testcase(httpd_subtree) -> done"
+ "~n", []),
+ [{watchdog, Dog}, {server_root, ServerROOT}, {doc_root, DocROOT},
+ {conf_dir, ConfDir}| NewConfig]
+ catch
+ _:Reason ->
+ io:format("init_per_testcase(httpd_subtree) -> "
+ "failed starting inets - cleanup"
+ "~n Reason: ~p"
+ "~n", [Reason]),
+ application:unset_env(inets, services),
+ application:unload(inets),
+ exit({failed_starting_inets, Reason})
+ end;
+
+
+init_per_testcase(Case, Config) ->
+ io:format("init_per_testcase(~p) -> entry with"
+ "~n Config: ~p"
+ "~n", [Case, Config]),
+ Dog = test_server:timetrap(?t:minutes(5)),
+ NewConfig = lists:keydelete(watchdog, 1, Config),
+ Stop = inets:stop(),
+ io:format("init_per_testcase(~p) -> Stop: ~p"
+ "~n", [Case, Stop]),
+ ok = inets:start(),
+ [{watchdog, Dog} | NewConfig].
+
+
+%%--------------------------------------------------------------------
+%% Function: end_per_testcase(Case, 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(httpd_subtree, Config) ->
+ Dog = ?config(watchdog, Config),
+ test_server:timetrap_cancel(Dog),
+ PrivDir = ?config(priv_dir, Config),
+ inets_test_lib:del_dirs(PrivDir),
+ ok;
+
+end_per_testcase(_, Config) ->
+ Dog = ?config(watchdog, Config),
+ test_server:timetrap_cancel(Dog),
+ inets:stop(),
+ ok.
+
+%%-------------------------------------------------------------------------
+%% Test cases starts here.
+%%-------------------------------------------------------------------------
+
+
+%%-------------------------------------------------------------------------
+%% default_tree
+%%-------------------------------------------------------------------------
+default_tree(doc) ->
+ ["Makes sure the correct processes are started and linked,"
+ "in the default case."];
+default_tree(suite) ->
+ [];
+default_tree(Config) when is_list(Config) ->
+ TopSupChildren = supervisor:which_children(inets_sup),
+ 4 = length(TopSupChildren),
+ {value, {httpd_sup, _, supervisor,[httpd_sup]}} =
+ lists:keysearch(httpd_sup, 1, TopSupChildren),
+ {value, {httpc_sup, _,supervisor,[httpc_sup]}} =
+ lists:keysearch(httpc_sup, 1, TopSupChildren),
+ {value, {ftp_sup,_,supervisor,[ftp_sup]}} =
+ lists:keysearch(ftp_sup, 1, TopSupChildren),
+ {value, {tftp_sup,_,supervisor,[tftp_sup]}} =
+ lists:keysearch(tftp_sup, 1, TopSupChildren),
+
+ HttpcSupChildren = supervisor:which_children(httpc_sup),
+ {value, {httpc_profile_sup,_, supervisor, [httpc_profile_sup]}} =
+ lists:keysearch(httpc_profile_sup, 1, HttpcSupChildren),
+ {value, {httpc_handler_sup,_, supervisor, [httpc_handler_sup]}} =
+ lists:keysearch(httpc_handler_sup, 1, HttpcSupChildren),
+
+ [] = supervisor:which_children(ftp_sup),
+
+ [] = supervisor:which_children(httpd_sup),
+
+ %% Default profile
+ [{httpc_manager, _, worker,[httpc_manager]}]
+ = supervisor:which_children(httpc_profile_sup),
+
+ [] = supervisor:which_children(httpc_handler_sup),
+
+ [] = supervisor:which_children(tftp_sup),
+
+ ok.
+
+
+%%-------------------------------------------------------------------------
+%% ftpc_worker
+%%-------------------------------------------------------------------------
+ftpc_worker(doc) ->
+ ["Makes sure the ftp worker processes are added and removed "
+ "appropriatly to/from the supervison tree."];
+ftpc_worker(suite) ->
+ [];
+ftpc_worker(Config) when is_list(Config) ->
+ inets:disable_trace(),
+ inets:enable_trace(max, io, ftpc),
+ [] = supervisor:which_children(ftp_sup),
+ try
+ begin
+ {_Tag, FtpdHost} = ftp_suite_lib:dirty_select_ftpd_host(Config),
+ case inets:start(ftpc, [{host, FtpdHost}]) of
+ {ok, Pid} ->
+ case supervisor:which_children(ftp_sup) of
+ [{_,_, worker, [ftp]}] ->
+ inets:stop(ftpc, Pid),
+ test_server:sleep(5000),
+ [] = supervisor:which_children(ftp_sup),
+ inets:disable_trace(),
+ ok;
+ Children ->
+ inets:disable_trace(),
+ exit({unexpected_children, Children})
+ end;
+ _ ->
+ inets:disable_trace(),
+ {skip, "Unable to reach test FTP server"}
+ end
+ end
+ catch
+ throw:{error, not_found} ->
+ inets:disable_trace(),
+ {skip, "No available FTP servers"}
+ end.
+
+
+%%-------------------------------------------------------------------------
+%% tftpd_worker
+%%-------------------------------------------------------------------------
+tftpd_worker(doc) ->
+ ["Makes sure the tftp sub tree is correct."];
+tftpd_worker(suite) ->
+ [];
+tftpd_worker(Config) when is_list(Config) ->
+ [] = supervisor:which_children(tftp_sup),
+ {ok, Pid0} = inets:start(tftpd, [{host, "localhost"},
+ {port, inet_port()}]),
+ {ok, _Pid1} = inets:start(tftpd, [{host, "localhost"},
+ {port, inet_port()}], stand_alone),
+
+ [{_,Pid0, worker, _}] = supervisor:which_children(tftp_sup),
+ inets:stop(tftpd, Pid0),
+ test_server:sleep(5000),
+ [] = supervisor:which_children(tftp_sup),
+ ok.
+
+
+%%-------------------------------------------------------------------------
+%% httpd_subtree
+%%-------------------------------------------------------------------------
+httpd_subtree(doc) ->
+ ["Makes sure the httpd sub tree is correct."];
+httpd_subtree(suite) ->
+ [];
+httpd_subtree(Config) when is_list(Config) ->
+ io:format("httpd_subtree -> entry with"
+ "~n Config: ~p"
+ "~n", [Config]),
+
+ %% Check that we have the httpd top supervisor
+ io:format("httpd_subtree -> verify inets~n", []),
+ {ok, _} = verify_child(inets_sup, httpd_sup, supervisor),
+
+ %% Check that we have the httpd instance supervisor
+ io:format("httpd_subtree -> verify httpd~n", []),
+ {ok, Id} = verify_child(httpd_sup, httpd_instance_sup, supervisor),
+ {httpd_instance_sup, Addr, Port} = Id,
+ Instance = httpd_util:make_name("httpd_instance_sup", Addr, Port),
+
+ %% Check that we have the expected httpd instance children
+ io:format("httpd_subtree -> verify httpd instance children "
+ "(acceptor, misc and manager)~n", []),
+ {ok, _} = verify_child(Instance, httpd_acceptor_sup, supervisor),
+ {ok, _} = verify_child(Instance, httpd_misc_sup, supervisor),
+ {ok, _} = verify_child(Instance, httpd_manager, worker),
+
+ %% Check that the httpd instance acc supervisor has children
+ io:format("httpd_subtree -> verify acc~n", []),
+ InstanceAcc = httpd_util:make_name("httpd_acc_sup", Addr, Port),
+ case supervisor:which_children(InstanceAcc) of
+ [_ | _] ->
+ ok;
+ InstanceAccUnexpectedChildren ->
+ exit({unexpected_children,
+ InstanceAcc, InstanceAccUnexpectedChildren})
+ end,
+
+ %% Check that the httpd instance misc supervisor has no children
+ io:format("httpd_subtree -> verify misc~n", []),
+ InstanceMisc = httpd_util:make_name("httpd_misc_sup", Addr, Port),
+ case supervisor:which_children(InstanceMisc) of
+ [] ->
+ ok;
+ InstanceMiscUnexpectedChildren ->
+ exit({unexpected_children,
+ InstanceMisc, InstanceMiscUnexpectedChildren})
+ end,
+ io:format("httpd_subtree -> done~n", []),
+ ok.
+
+
+verify_child(Parent, Child, Type) ->
+%% io:format("verify_child -> entry with"
+%% "~n Parent: ~p"
+%% "~n Child: ~p"
+%% "~n Type: ~p"
+%% "~n", [Parent, Child, Type]),
+ Children = supervisor:which_children(Parent),
+%% io:format("verify_child -> which children"
+%% "~n Children: ~p"
+%% "~n", [Children]),
+ verify_child(Children, Parent, Child, Type).
+
+verify_child([], Parent, Child, _Type) ->
+ {error, {child_not_found, Child, Parent}};
+verify_child([{Id, _Pid, Type2, Mods}|Children], Parent, Child, Type) ->
+ case lists:member(Child, Mods) of
+ true when (Type2 =:= Type) ->
+%% io:format("verify_child -> found with expected type"
+%% "~n Id: ~p"
+%% "~n", [Id]),
+ {ok, Id};
+ true when (Type2 =/= Type) ->
+%% io:format("verify_child -> found with unexpected type"
+%% "~n Type2: ~p"
+%% "~n Id: ~p"
+%% "~n", [Type2, Id]),
+ {error, {wrong_type, Type2, Child, Parent}};
+ false ->
+ verify_child(Children, Parent, Child, Type)
+ end.
+
+
+
+%%-------------------------------------------------------------------------
+%% httpc_subtree
+%%-------------------------------------------------------------------------
+httpc_subtree(doc) ->
+ ["Makes sure the httpc sub tree is correct."];
+httpc_subtree(suite) ->
+ [];
+httpc_subtree(Config) when is_list(Config) ->
+ tsp("httpc_subtree -> entry with"
+ "~n Config: ~p", [Config]),
+
+ tsp("httpc_subtree -> start inets service httpc with profile foo"),
+ {ok, Foo} = inets:start(httpc, [{profile, foo}]),
+
+ tsp("httpc_subtree -> "
+ "start stand-alone inets service httpc with profile bar"),
+ {ok, Bar} = inets:start(httpc, [{profile, bar}], stand_alone),
+
+ tsp("httpc_subtree -> retreive list of httpc instances"),
+ HttpcChildren = supervisor:which_children(httpc_profile_sup),
+ tsp("httpc_subtree -> HttpcChildren: ~n~p", [HttpcChildren]),
+
+ tsp("httpc_subtree -> verify httpc stand-alone instances"),
+ {value, {httpc_manager, _, worker, [httpc_manager]}} =
+ lists:keysearch(httpc_manager, 1, HttpcChildren),
+
+ tsp("httpc_subtree -> verify httpc (named) instances"),
+ {value,{{httpc,foo}, Pid, worker, [httpc_manager]}} =
+ lists:keysearch({httpc, foo}, 1, HttpcChildren),
+ false = lists:keysearch({httpc, bar}, 1, HttpcChildren),
+
+ tsp("httpc_subtree -> stop inets"),
+ inets:stop(httpc, Pid),
+
+ tsp("httpc_subtree -> done"),
+ ok.
+
+inet_port() ->
+ {ok, Socket} = gen_tcp:listen(0, [{reuseaddr, true}]),
+ {ok, Port} = inet:port(Socket),
+ gen_tcp:close(Socket),
+ Port.
+
+
+tsp(F) ->
+ tsp(F, []).
+tsp(F, A) ->
+ test_server:format("~p ~p:" ++ F ++ "~n", [self(), ?MODULE | A]).
+
+tsf(Reason) ->
+ test_server:fail(Reason).
+
diff --git a/lib/inets/test/inets_sup_SUITE_data/mime.types b/lib/inets/test/inets_sup_SUITE_data/mime.types
new file mode 100644
index 0000000000..e52d345ff7
--- /dev/null
+++ b/lib/inets/test/inets_sup_SUITE_data/mime.types
@@ -0,0 +1,3 @@
+# MIME type Extension
+text/html html htm
+text/plain asc txt
diff --git a/lib/inets/test/inets_sup_SUITE_data/simple.conf b/lib/inets/test/inets_sup_SUITE_data/simple.conf
new file mode 100644
index 0000000000..e1429b4a28
--- /dev/null
+++ b/lib/inets/test/inets_sup_SUITE_data/simple.conf
@@ -0,0 +1,6 @@
+Port 8888
+ServerName www.test
+SocketType ip_comm
+Modules mod_get
+ServerAdmin [email protected]
+
diff --git a/lib/inets/test/inets_test_lib.erl b/lib/inets/test/inets_test_lib.erl
new file mode 100644
index 0000000000..609bc89e15
--- /dev/null
+++ b/lib/inets/test/inets_test_lib.erl
@@ -0,0 +1,355 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 2001-2011. All Rights Reserved.
+%%
+%% The contents of this file are subject to the Erlang Public License,
+%% Version 1.1, (the "License"); you may not use this file except in
+%% compliance with the License. You should have received a copy of the
+%% Erlang Public License along with this software. If not, it can be
+%% retrieved online at http://www.erlang.org/.
+%%
+%% Software distributed under the License is distributed on an "AS IS"
+%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+%% the License for the specific language governing rights and limitations
+%% under the License.
+%%
+%% %CopyrightEnd%
+%%
+%%
+-module(inets_test_lib).
+
+-include("inets_test_lib.hrl").
+
+%% Various small utility functions
+-export([start_http_server/1, start_http_server_ssl/1]).
+-export([hostname/0]).
+-export([connect_bin/3, connect_byte/3, send/3, close/2]).
+-export([copy_file/3, copy_files/2, copy_dirs/2, del_dirs/1]).
+-export([info/4, log/4, debug/4, print/4]).
+-export([check_body/1]).
+-export([millis/0, millis_diff/2, hours/1, minutes/1, seconds/1, sleep/1]).
+-export([non_pc_tc_maybe_skip/4, os_based_skip/1]).
+
+start_http_server(Conf) ->
+ ?DEBUG("start_http_server -> entry with"
+ "~n Conf: ~p", [Conf]),
+ inets_ensure_loaded(),
+ inets_set_env(services, [{httpd, Conf}]),
+ inets_ensure_started(),
+ ok.
+
+
+start_http_server_ssl(FileName) ->
+ application:start(ssl),
+ catch start_http_server(FileName).
+
+inets_ensure_loaded() ->
+ ensure_loaded(inets).
+
+ensure_loaded(App) ->
+ case application:load(App) of
+ ok ->
+ ok;
+ {error, {already_loaded, _}} ->
+ ok;
+ LoadRes ->
+ ?LOG("start_http_server -> failed loading ~p: ~p", [App, LoadRes]),
+ tsf({failed_loading, LoadRes})
+ end.
+
+
+inets_set_env(Service, Config) ->
+ app_set_env(inets, Service, Config).
+
+app_set_env(App, Param, Value) ->
+ case application:set_env(App, Param, Value) of
+ ok ->
+ ?DEBUG("start_http_server -> env set", []),
+ ok;
+ SetEnvRes ->
+ ?LOG("start_http_server -> failed set env for ~p: ~p",
+ [App, SetEnvRes]),
+ exit({failed_set_env, App, SetEnvRes})
+ end.
+
+inets_ensure_started() ->
+ ensure_app_started(inets).
+
+ensure_app_started(App) ->
+ case application:start(App) of
+ ok ->
+ ?DEBUG("start_http_server -> ~p started", [App]),
+ ok;
+ {error, {already_started, _}} ->
+ ok;
+ StartRes ->
+ ?LOG("start_http_server -> failed starting ~p: ~p",
+ [App, StartRes]),
+ exit({failed_starting, App, StartRes})
+ end.
+
+
+%% ----------------------------------------------------------------------
+%% print functions
+%%
+
+info(F, A, Mod, Line) ->
+ print("INF ", F, A, Mod, Line).
+
+log(F, A, Mod, Line) ->
+ print("LOG ", F, A, Mod, Line).
+
+debug(F, A, Mod, Line) ->
+ print("DBG ", F, A, Mod, Line).
+
+print(P, F, A, Mod, Line) ->
+ io:format("~s[~p:~p:~p] : " ++ F ++ "~n", [P, self(), Mod, Line| A]).
+
+print(F, A, Mod, Line) ->
+ print("", F, A, Mod, Line).
+
+hostname() ->
+ from($@, atom_to_list(node())).
+from(H, [H | T]) -> T;
+from(H, [_ | T]) -> from(H, T);
+from(_, []) -> [].
+
+
+copy_file(File, From, To) ->
+ file:copy(filename:join(From, File), filename:join(To, File)).
+
+copy_files(FromDir, ToDir) ->
+ {ok, Files} = file:list_dir(FromDir),
+ lists:foreach(fun(File) ->
+ FullPath = filename:join(FromDir, File),
+ case filelib:is_file(FullPath) of
+ true ->
+ file:copy(FullPath,
+ filename:join(ToDir, File));
+ false ->
+ ok
+ end
+ end, Files).
+
+
+copy_dirs(FromDirRoot, ToDirRoot) ->
+%% io:format("~w:copy_dirs -> entry with"
+%% "~n FromDirRoot: ~p"
+%% "~n ToDirRoot: ~p"
+%% "~n", [?MODULE, FromDirRoot, ToDirRoot]),
+ {ok, Files} = file:list_dir(FromDirRoot),
+ lists:foreach(
+ fun(FileOrDir) ->
+ %% Check if it's a directory or a file
+%% io:format("~w:copy_dirs -> check ~p"
+%% "~n", [?MODULE, FileOrDir]),
+ case filelib:is_dir(filename:join(FromDirRoot, FileOrDir)) of
+ true ->
+%% io:format("~w:copy_dirs -> ~p is a directory"
+%% "~n", [?MODULE, FileOrDir]),
+ FromDir = filename:join([FromDirRoot, FileOrDir]),
+ ToDir = filename:join([ToDirRoot, FileOrDir]),
+ ok = file:make_dir(ToDir),
+ copy_dirs(FromDir, ToDir);
+ false ->
+%% io:format("~w:copy_dirs -> ~p is a file"
+%% "~n", [?MODULE, FileOrDir]),
+ copy_file(FileOrDir, FromDirRoot, ToDirRoot)
+ end
+ end, Files).
+
+del_dirs(Dir) ->
+ case file:list_dir(Dir) of
+ {ok, []} ->
+ file:del_dir(Dir);
+ {ok, Files} ->
+ lists:foreach(fun(File) ->
+ FullPath = filename:join(Dir,File),
+ case filelib:is_dir(FullPath) of
+ true ->
+ del_dirs(FullPath),
+ file:del_dir(FullPath);
+ false ->
+ file:delete(FullPath)
+ end
+ end, Files);
+ _ ->
+ ok
+ end.
+
+check_body(Body) ->
+ case string:rstr(Body, "</html>") of
+ 0 ->
+ case string:rstr(Body, "</HTML>") of
+ 0 ->
+ test_server:format("Body ~p~n", [Body]),
+ test_server:fail(did_not_receive_whole_body);
+ _ ->
+ ok
+ end;
+ _ ->
+ ok
+ end.
+
+%% ----------------------------------------------------------------
+%% Conditional skip of testcases
+%%
+
+non_pc_tc_maybe_skip(Config, Condition, File, Line)
+ when is_list(Config) andalso is_function(Condition) ->
+ %% Check if we shall skip the skip
+ case os:getenv("TS_OS_BASED_SKIP") of
+ "false" ->
+ ok;
+ _ ->
+ case lists:keysearch(ts, 1, Config) of
+ {value, {ts, inets}} ->
+ %% Always run the testcase if we are using our own
+ %% test-server...
+ ok;
+ _ ->
+ case (catch Condition()) of
+ true ->
+ skip(non_pc_testcase, File, Line);
+ _ ->
+ ok
+ end
+ end
+ end.
+
+
+os_based_skip(any) ->
+ true;
+os_based_skip(Skippable) when is_list(Skippable) ->
+ {OsFam, OsName} =
+ case os:type() of
+ {_Fam, _Name} = FamAndName ->
+ FamAndName;
+ Fam ->
+ {Fam, undefined}
+ end,
+ case lists:member(OsFam, Skippable) of
+ true ->
+ true;
+ false ->
+ case lists:keysearch(OsFam, 1, Skippable) of
+ {value, {OsFam, OsName}} ->
+ true;
+ {value, {OsFam, OsNames}} when is_list(OsNames) ->
+ lists:member(OsName, OsNames);
+ _ ->
+ false
+ end
+ end;
+os_based_skip(_) ->
+ false.
+
+
+%% ----------------------------------------------------------------------
+%% Socket functions:
+%% open(SocketType, Host, Port) -> {ok, Socket} | {error, Reason}
+%% SocketType -> ssl | ip_comm
+%% Host -> atom() | string() | {A, B, C, D}
+%% Port -> integer()
+
+connect_bin(ssl, Host, Port) ->
+ ssl:start(),
+ %% Does not support ipv6 in old ssl
+ case ssl:connect(Host, Port, [binary, {packet,0}]) of
+ {ok, Socket} ->
+ {ok, Socket};
+ {error, Reason} ->
+ {error, Reason};
+ Error ->
+ Error
+ end;
+connect_bin(ip_comm, Host, Port) ->
+ Opts = [inet6, binary, {packet,0}],
+ connect(ip_comm, Host, Port, Opts).
+
+
+connect(ip_comm, Host, Port, Opts) ->
+ test_server:format("gen_tcp:connect(~p, ~p, ~p) ~n", [Host, Port, Opts]),
+ case gen_tcp:connect(Host,Port, Opts) of
+ {ok, Socket} ->
+ test_server:format("connect success~n", []),
+ {ok, Socket};
+ {error, nxdomain} ->
+ test_server:format("nxdomain opts: ~p~n", [Opts]),
+ connect(ip_comm, Host, Port, lists:delete(inet6, Opts));
+ {error, eafnosupport} ->
+ test_server:format("eafnosupport opts: ~p~n", [Opts]),
+ connect(ip_comm, Host, Port, lists:delete(inet6, Opts));
+ {error, {enfile,_}} ->
+ test_server:format("Error enfile~n", []),
+ {error, enfile};
+ Error ->
+ test_server:format("Unexpected error: "
+ "~n Error: ~p"
+ "~nwhen"
+ "~n Host: ~p"
+ "~n Port: ~p"
+ "~n Opts: ~p"
+ "~n", [Error, Host, Port, Opts]),
+ Error
+ end.
+
+connect_byte(ip_comm, Host, Port) ->
+ Opts = [inet6, {packet,0}],
+ connect(ip_comm, Host, Port, Opts);
+
+connect_byte(ssl, Host, Port) ->
+ ssl:start(),
+ %% Does not support ipv6 in old ssl
+ case ssl:connect(Host,Port,[{packet,0}]) of
+ {ok,Socket} ->
+ {ok,Socket};
+ {error,{enfile,_}} ->
+ {error, enfile};
+ Error ->
+ Error
+ end.
+
+send(ssl, Socket, Data) ->
+ ssl:send(Socket, Data);
+send(ip_comm,Socket,Data) ->
+ gen_tcp:send(Socket,Data).
+
+
+close(ssl,Socket) ->
+ catch ssl:close(Socket);
+close(ip_comm,Socket) ->
+ catch gen_tcp:close(Socket).
+
+millis() ->
+ erlang:now().
+
+millis_diff(A,B) ->
+ T1 = (element(1,A)*1000000) + element(2,A) + (element(3,A)/1000000),
+ T2 = (element(1,B)*1000000) + element(2,B) + (element(3,B)/1000000),
+ T1 - T2.
+
+hours(N) -> trunc(N * 1000 * 60 * 60).
+minutes(N) -> trunc(N * 1000 * 60).
+seconds(N) -> trunc(N * 1000).
+
+
+sleep(infinity) ->
+ receive
+ after infinity ->
+ ok
+ end;
+sleep(MSecs) ->
+ receive
+ after trunc(MSecs) ->
+ ok
+ end,
+ ok.
+
+
+skip(Reason, File, Line) ->
+ exit({skipped, {Reason, File, Line}}).
+
+tsf(Reason) ->
+ test_server:fail(Reason).
diff --git a/lib/inets/test/inets_test_lib.hrl b/lib/inets/test/inets_test_lib.hrl
new file mode 100644
index 0000000000..12a43fa136
--- /dev/null
+++ b/lib/inets/test/inets_test_lib.hrl
@@ -0,0 +1,104 @@
+%%
+%% %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: Define common macros for testing
+%%----------------------------------------------------------------------
+
+%% - Print macros -
+
+-ifdef(inets_debug).
+-define(DEBUG(F,A), inets_test_lib:debug(F, A, ?MODULE, ?LINE)).
+-else.
+-define(DEBUG(F,A),ok).
+-endif.
+
+-ifdef(inets_log).
+-define(LOG(F,A), inets_test_lib:log(F, A, ?MODULE, ?LINE)).
+-else.
+-define(LOG(F,A),ok).
+-endif.
+
+-define(INFO(F,A), inets_test_lib:info(F, A, ?MODULE, ?LINE)).
+-define(PRINT(F,A), inets_test_lib:print(F, A, ?MODULE, ?LINE)).
+
+
+%% - Macros stolen from the test server -
+
+-ifndef(line).
+-define(line,put(test_server_loc,{?MODULE,?LINE}),).
+-endif.
+
+
+%% - Test case macros -
+
+-define(EXPANDABLE(I, C, F), inets_test_lib:expandable(I, C, F)).
+-define(OS_BASED_SKIP(Skippable),
+ inets_test_lib:os_based_skip(Skippable)).
+
+-define(NON_PC_TC_MAYBE_SKIP(Config, Condition),
+ inets_test_lib:non_pc_tc_maybe_skip(Config, Condition, ?MODULE, ?LINE)).
+
+
+
+%% - Misc macros -
+
+-define(UPDATE(K,V,C), inets_test_lib:update_config(K,V,C)).
+-define(CONFIG(K,C), inets_test_lib:get_config(K,C)).
+-define(HOSTNAME(), inets_test_lib:hostname()).
+-define(SZ(X), inets_test_lib:sz(X)).
+
+
+%% - Test case macros -
+
+-define(SKIP(Reason), inets_test_lib:skip(Reason)).
+-define(FAIL(Reason), inets_test_lib:fail(Reason, ?MODULE, ?LINE)).
+
+
+%% - Socket macros -
+
+-define(CONNECT(M,H,P), inets_test_lib:connect(M,H,P)).
+-define(SEND(M,S,D), inets_test_lib:send(M,S,D)).
+-define(CSEND(M,S,D,C,T), inets_test_lib:csend(M,S,D,C,T)).
+-define(CLOSE(M,S), inets_test_lib:close(M,S)).
+
+
+%% - Time macros -
+
+-define(HOURS(N), inets_test_lib:hours(N)).
+-define(MINS(N), inets_test_lib:minutes(N)).
+-define(SECS(N), inets_test_lib:seconds(N)).
+
+-define(WD_START(T), inets_test_lib:watchdog_start(T)).
+-define(WD_STOP(P), inets_test_lib:watchdog_stop(P)).
+
+-define(SLEEP(MSEC), inets_test_lib:sleep(MSEC)).
+-define(M(), inets_test_lib:millis()).
+-define(MDIFF(A,B), inets_test_lib:millis_diff(A,B)).
+
+
+%% - Process utility macros -
+
+-define(FLUSH(), inets_test_lib:flush_mqueue()).
+-define(ETRAP_GET(), inets_test_lib:trap_exit()).
+-define(ETRAP_SET(O), inets_test_lib:trap_exit(O)).
+
+
+
+
diff --git a/lib/inets/test/rules.mk b/lib/inets/test/rules.mk
new file mode 100644
index 0000000000..047c03b267
--- /dev/null
+++ b/lib/inets/test/rules.mk
@@ -0,0 +1,59 @@
+#-*-makefile-*- ; force emacs to enter makefile-mode
+# ----------------------------------------------------
+# Make include file for otp
+#
+# Copyright (C) 1996, Ericsson Telecommunications
+# Author: Lars Thorsen
+# ----------------------------------------------------
+.SUFFIXES: .hrl .erl .jam .beam
+
+
+# ----------------------------------------------------
+# Common macros
+# ----------------------------------------------------
+DEFAULT_TARGETS = opt debug instr release release_docs clean docs
+
+# ----------------------------------------------------
+# Erlang language section
+# ----------------------------------------------------
+EMULATOR = beam
+ifeq ($(findstring vxworks,$(TARGET)),vxworks)
+# VxWorks object files should be compressed.
+# Other object files should have debug_info.
+ERL_COMPILE_FLAGS += +compressed
+else
+ifdef BOOTSTRAP
+ERL_COMPILE_FLAGS += +slim
+else
+ERL_COMPILE_FLAGS += +debug_info
+endif
+endif
+ERLC_WFLAGS = -W
+ERLC = erlc $(ERLC_WFLAGS) $(ERLC_FLAGS)
+ERL.beam = erl.beam -boot start_clean
+ERL.jam = erl -boot start_clean
+ERL = $(ERL.$(EMULATOR))
+
+ifeq ($(EBIN),)
+EBIN = .
+endif
+
+ESRC = .
+
+
+$(EBIN)/%.jam: $(ESRC)/%.erl
+ $(ERLC) -bjam $(ERL_COMPILE_FLAGS) -o$(EBIN) $<
+
+$(EBIN)/%.beam: $(ESRC)/%.erl
+ $(ERLC) -bbeam $(ERL_COMPILE_FLAGS) -o$(EBIN) $<
+
+.erl.jam:
+ $(ERLC) -bjam $(ERL_COMPILE_FLAGS) -o$(dir $@) $<
+
+.erl.beam:
+ $(ERLC) -bbeam $(ERL_COMPILE_FLAGS) -o$(dir $@) $<
+
+
+
+
+
diff --git a/lib/inets/test/tftp_SUITE.erl b/lib/inets/test/tftp_SUITE.erl
new file mode 100644
index 0000000000..5768fff88b
--- /dev/null
+++ b/lib/inets/test/tftp_SUITE.erl
@@ -0,0 +1,903 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 2006-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(tftp_SUITE).
+
+-compile(export_all).
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%% Includes and defines
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+-include("tftp_test_lib.hrl").
+
+-define(START_DAEMON(PortX, OptionsX),
+ fun(Port, Options) ->
+ {ok, Pid} = ?VERIFY({ok, _Pid}, tftp:start([{port, Port} | Options])),
+ if
+ Port == 0 ->
+ {ok, ActualOptions} = ?IGNORE(tftp:info(Pid)),
+ {value, {port, ActualPort}} =
+ lists:keysearch(port, 1, ActualOptions),
+ {ActualPort, Pid};
+ true ->
+ {Port, Pid}
+ end
+ end(PortX, OptionsX)).
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%% API
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+t() ->
+ tftp_test_lib:t([{?MODULE, all}]).
+
+t(Cases) ->
+ tftp_test_lib:t(Cases, default_config()).
+
+t(Cases, Config) ->
+ tftp_test_lib:t(Cases, Config).
+
+default_config() ->
+ [].
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%% Test server callbacks
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+init_per_testcase(Case, Config) ->
+ tftp_test_lib:init_per_testcase(Case, Config).
+
+fin_per_testcase(Case, Config) when is_list(Config) ->
+ tftp_test_lib:fin_per_testcase(Case, Config).
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%% Top test case
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+all(doc) ->
+ ["Test suites for TFTP."];
+
+all(suite) ->
+ [
+ simple,
+ extra,
+ reuse_connection,
+ resend_client,
+ resend_server
+ ].
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%% Simple
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+simple(doc) ->
+ ["Start the daemon and perform simple a read and write."];
+simple(suite) ->
+ [];
+simple(Config) when is_list(Config) ->
+ ?VERIFY(ok, application:start(inets)),
+
+ {Port, DaemonPid} = ?IGNORE(?START_DAEMON(0, [{debug, brief}])),
+
+ %% Read fail
+ RemoteFilename = "tftp_temporary_remote_test_file.txt",
+ LocalFilename = "tftp_temporary_local_test_file.txt",
+ Blob = list_to_binary(lists:duplicate(2000, $1)),
+ %% Blob = <<"Some file contents\n">>,
+ Size = size(Blob),
+ ?IGNORE(file:delete(RemoteFilename)),
+ ?VERIFY({error, {client_open, enoent, _}},
+ tftp:read_file(RemoteFilename, binary, [{port, Port}])),
+
+ %% Write and read
+ ?VERIFY({ok, Size}, tftp:write_file(RemoteFilename, Blob, [{port, Port}])),
+ ?VERIFY({ok, Blob}, tftp:read_file(RemoteFilename, binary, [{port, Port}])),
+ ?IGNORE(file:delete(LocalFilename)),
+ ?VERIFY({ok, Size}, tftp:read_file(RemoteFilename, LocalFilename, [{port, Port}])),
+
+ %% Cleanup
+ unlink(DaemonPid),
+ exit(DaemonPid, kill),
+ ?VERIFY(ok, file:delete(LocalFilename)),
+ ?VERIFY(ok, file:delete(RemoteFilename)),
+ ?VERIFY(ok, application:stop(inets)),
+ ok.
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%% Extra
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+extra(doc) ->
+ ["Verify new stuff for IS 1.2."];
+extra(suite) ->
+ [];
+extra(Config) when is_list(Config) ->
+ ?VERIFY({'EXIT', {badarg,{fake_key, fake_flag}}},
+ tftp:start([{port, 0}, {fake_key, fake_flag}])),
+
+ {Port, DaemonPid} = ?IGNORE(?START_DAEMON(0, [{debug, brief}])),
+
+ RemoteFilename = "tftp_extra_temporary_remote_test_file.txt",
+ LocalFilename = "tftp_extra_temporary_local_test_file.txt",
+ Blob = <<"Some file contents\n">>,
+ Size = size(Blob),
+ Host = "127.0.0.1",
+ Peer = {inet, Host, Port},
+ Generic =
+ [
+ {state, []},
+ {prepare, fun extra_prepare/6},
+ {open, fun extra_open/6},
+ {read, fun extra_read/1},
+ {write, fun extra_write/2},
+ {abort, fun extra_abort/3 }
+ ],
+ Options = [{host, Host},
+ {port, Port},
+ %%{ debug,all},
+ {callback, {".*", tftp_test_lib, Generic}}],
+ ?VERIFY(ok, file:write_file(LocalFilename, Blob)),
+ ?VERIFY({ok, [{count, Size}, Peer]},
+ tftp:write_file(RemoteFilename, LocalFilename, Options)),
+ ?VERIFY(ok, file:delete(LocalFilename)),
+
+ ?VERIFY({ok,[{bin, Blob}, Peer]},
+ tftp:read_file(RemoteFilename, LocalFilename, Options)),
+
+ %% Cleanup
+ unlink(DaemonPid),
+ exit(DaemonPid, kill),
+ ?VERIFY(ok, file:delete(LocalFilename)),
+ ?VERIFY(ok, file:delete(RemoteFilename)),
+ ok.
+
+-record(extra_state, {file, blksize, count, acc, peer}).
+
+%%-------------------------------------------------------------------
+%% Prepare
+%%-------------------------------------------------------------------
+
+extra_prepare(Peer, Access, LocalFilename, Mode, SuggestedOptions, []) ->
+ %% Client side
+ BlkSize = list_to_integer(tftp_test_lib:lookup_option("blksize", "512", SuggestedOptions)),
+ State = #extra_state{blksize = BlkSize, peer = Peer},
+ extra_open(Peer, Access, LocalFilename, Mode, SuggestedOptions, State),
+ {ok, SuggestedOptions, State};
+extra_prepare(_Peer, _Access, _Bin, _Mode, _SuggestedOptions, _Initial) ->
+ {error, {undef, "Illegal callback options."}}.
+
+%%-------------------------------------------------------------------
+%% Open
+%%-------------------------------------------------------------------
+
+extra_open(Peer, Access, LocalFilename, Mode, SuggestedOptions, []) ->
+ %% Server side
+ case extra_prepare(Peer, Access, LocalFilename, Mode, SuggestedOptions, []) of
+ {ok, AcceptedOptions, []} ->
+ BlkSize = list_to_integer(tftp_test_lib:lookup_option("blksize", "512", AcceptedOptions)),
+ State = #extra_state{blksize = BlkSize, peer = Peer},
+ extra_open(Peer, Access, LocalFilename, Mode, AcceptedOptions, State);
+ {error, {Code, Text}} ->
+ {error, {Code, Text}}
+ end;
+extra_open(_Peer, Access, LocalFilename, _Mode, NegotiatedOptions, #extra_state{} = State) ->
+ {File, Acc} =
+ case Access of
+ read ->
+ if
+ is_binary(LocalFilename) ->
+ {undefined, LocalFilename};
+ is_list(LocalFilename) ->
+ {ok, Bin} = file:read_file(LocalFilename),
+ {LocalFilename, Bin}
+ end;
+ write ->
+ {LocalFilename, []}
+ end,
+ %% Both sides
+ State2 = State#extra_state{file = File, acc = Acc, count = 0},
+ {ok, NegotiatedOptions, State2}.
+
+%%-------------------------------------------------------------------
+%% Read
+%%-------------------------------------------------------------------
+
+extra_read(#extra_state{acc = Bin} = State) when is_binary(Bin) ->
+ BlkSize = State#extra_state.blksize,
+ Count = State#extra_state.count + size(Bin),
+ if
+ size(Bin) >= BlkSize ->
+ <<Block:BlkSize/binary, Bin2/binary>> = Bin,
+ State2 = State#extra_state{acc = Bin2, count = Count},
+ {more, Block, State2};
+ size(Bin) < BlkSize ->
+ Res = [{count, Count}, State#extra_state.peer],
+ {last, Bin, Res}
+ end.
+
+%%-------------------------------------------------------------------
+%% Write
+%%-------------------------------------------------------------------
+
+extra_write(Bin, #extra_state{acc = List} = State) when is_binary(Bin), is_list(List) ->
+ Size = size(Bin),
+ BlkSize = State#extra_state.blksize,
+ if
+ Size == BlkSize ->
+ {more, State#extra_state{acc = [Bin | List]}};
+ Size < BlkSize ->
+ Bin2 = list_to_binary(lists:reverse([Bin | List])),
+ Res = [{bin, Bin2}, State#extra_state.peer],
+ file:write_file(State#extra_state.file, Bin2),
+ {last, Res}
+ end.
+
+%%-------------------------------------------------------------------
+%% Abort
+%%-------------------------------------------------------------------
+
+extra_abort(_Code, _Text, #extra_state{}) ->
+ ok.
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%% Re-send client
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+resend_client(doc) ->
+ ["Verify that the server behaves correctly when the client re-sends packets."];
+resend_client(suite) ->
+ [];
+resend_client(Config) when is_list(Config) ->
+ Host = {127, 0, 0, 1},
+ {Port, DaemonPid} = ?IGNORE(?START_DAEMON(0, [{debug, all}])),
+
+ ?VERIFY(ok, resend_read_client(Host, Port, 10)),
+ ?VERIFY(ok, resend_read_client(Host, Port, 512)),
+ ?VERIFY(ok, resend_read_client(Host, Port, 1025)),
+
+ ?VERIFY(ok, resend_write_client(Host, Port, 10)),
+ ?VERIFY(ok, resend_write_client(Host, Port, 512)),
+ ?VERIFY(ok, resend_write_client(Host, Port, 1025)),
+
+ %% Cleanup
+ unlink(DaemonPid),
+ exit(DaemonPid, kill),
+ ok.
+
+resend_read_client(Host, Port, BlkSize) ->
+ RemoteFilename = "tftp_resend_read_client.tmp",
+ Block1 = lists:duplicate(BlkSize, $1),
+ Block2 = lists:duplicate(BlkSize, $2),
+ Block3 = lists:duplicate(BlkSize, $3),
+ Block4 = lists:duplicate(BlkSize, $4),
+ Block5 = lists:duplicate(BlkSize, $5),
+ Blocks = [Block1, Block2, Block3, Block4, Block5],
+ Blob = list_to_binary(Blocks),
+ ?VERIFY(ok, file:write_file(RemoteFilename, Blob)),
+
+ Timeout = timer:seconds(3),
+ ?VERIFY(timeout, recv(0)),
+
+ %% Open socket
+ {ok, Socket} = ?VERIFY({ok, _}, gen_udp:open(0, [binary, {reuseaddr, true}, {active, true}])),
+
+ ReadList = [0, 1, RemoteFilename, 0, "octet", 0],
+ Data1Bin = list_to_binary([0, 3, 0, 1 | Block1]),
+ NewPort =
+ if
+ BlkSize =:= 512 ->
+ %% Send READ
+ ReadBin = list_to_binary(ReadList),
+ ?VERIFY(ok, gen_udp:send(Socket, Host, Port, ReadBin)),
+
+ %% Sleep a while in order to provoke the server to re-send the packet
+ timer:sleep(Timeout + timer:seconds(1)),
+
+ %% Recv DATA #1 (the packet that the server think that we have lost)
+ {udp, _, _, NewPort0, _} = ?VERIFY({udp, Socket, Host, _, Data1Bin}, recv(Timeout)),
+ NewPort0;
+ true ->
+ %% Send READ
+ BlkSizeList = integer_to_list(BlkSize),
+ Options = ["blksize", 0, BlkSizeList, 0],
+ ReadBin = list_to_binary([ReadList | Options]),
+ ?VERIFY(ok, gen_udp:send(Socket, Host, Port, ReadBin)),
+
+ %% Recv OACK
+ OptionAckBin = list_to_binary([0, 6 | Options]),
+ {udp, _, _, NewPort0, _} = ?VERIFY({udp, Socket, Host, _, OptionAckBin}, recv(Timeout)),
+
+ %% Send ACK #0
+ Ack0Bin = <<0, 4, 0, 0>>,
+ ?VERIFY(ok, gen_udp:send(Socket, Host, NewPort0, Ack0Bin)),
+
+ %% Send ACK #0 AGAIN (pretend that we timed out)
+ timer:sleep(timer:seconds(1)),
+ ?VERIFY(ok, gen_udp:send(Socket, Host, NewPort0, Ack0Bin)),
+
+ %% Recv DATA #1 (the packet that the server think that we have lost)
+ ?VERIFY({udp, Socket, Host, NewPort0, Data1Bin}, recv(Timeout)),
+ NewPort0
+ end,
+
+ %% Recv DATA #1 AGAIN (the re-sent package)
+ ?VERIFY({udp, Socket, Host, NewPort, Data1Bin}, recv(Timeout)),
+
+ %% Send ACK #1
+ Ack1Bin = <<0, 4, 0, 1>>,
+ ?VERIFY(ok, gen_udp:send(Socket, Host, NewPort, Ack1Bin)),
+
+ %% Recv DATA #2
+ Data2Bin = list_to_binary([0, 3, 0, 2 | Block2]),
+ ?VERIFY({udp, Socket, Host, NewPort, Data2Bin}, recv(Timeout)),
+
+ %% Send ACK #2
+ Ack2Bin = <<0, 4, 0, 2>>,
+ ?VERIFY(ok, gen_udp:send(Socket, Host, NewPort, Ack2Bin)),
+
+ %% Recv DATA #3
+ Data3Bin = list_to_binary([0, 3, 0, 3 | Block3]),
+ ?VERIFY({udp, Socket, Host, NewPort, Data3Bin}, recv(Timeout)),
+
+ %% Send ACK #3
+ Ack3Bin = <<0, 4, 0, 3>>,
+ ?VERIFY(ok, gen_udp:send(Socket, Host, NewPort, Ack3Bin)),
+
+ %% Send ACK #3 AGAIN (pretend that we timed out)
+ timer:sleep(timer:seconds(1)),
+ ?VERIFY(ok, gen_udp:send(Socket, Host, NewPort, Ack3Bin)),
+
+ %% Recv DATA #4 (the packet that the server think that we have lost)
+ Data4Bin = list_to_binary([0, 3, 0, 4 | Block4]),
+ ?VERIFY({udp, Socket, Host, NewPort, Data4Bin}, recv(Timeout)),
+
+ %% Recv DATA #4 AGAIN (the re-sent package)
+ ?VERIFY({udp, Socket, Host, NewPort, Data4Bin}, recv(Timeout)),
+
+ %% Send ACK #2 which is out of range
+ ?VERIFY(ok, gen_udp:send(Socket, Host, NewPort, Ack2Bin)),
+
+ %% Send ACK #4
+ Ack4Bin = <<0, 4, 0, 4>>,
+ ?VERIFY(ok, gen_udp:send(Socket, Host, NewPort, Ack4Bin)),
+
+ %% Recv DATA #5
+ Data5Bin = list_to_binary([0, 3, 0, 5 | Block5]),
+ ?VERIFY({udp, Socket, Host, NewPort, Data5Bin}, recv(Timeout)),
+
+ %% Send ACK #5
+ Ack5Bin = <<0, 4, 0, 5>>,
+ ?VERIFY(ok, gen_udp:send(Socket, Host, NewPort, Ack5Bin)),
+
+ %% Close socket
+ ?VERIFY(ok, gen_udp:close(Socket)),
+
+ ?VERIFY(timeout, recv(Timeout)),
+ ?VERIFY(ok, file:delete(RemoteFilename)),
+ ok.
+
+resend_write_client(Host, Port, BlkSize) ->
+ RemoteFilename = "tftp_resend_write_client.tmp",
+ Block1 = lists:duplicate(BlkSize, $1),
+ Block2 = lists:duplicate(BlkSize, $2),
+ Block3 = lists:duplicate(BlkSize, $3),
+ Block4 = lists:duplicate(BlkSize, $4),
+ Block5 = lists:duplicate(BlkSize, $5),
+ Blocks = [Block1, Block2, Block3, Block4, Block5],
+ Blob = list_to_binary(Blocks),
+ ?IGNORE(file:delete(RemoteFilename)),
+ ?VERIFY({error, enoent}, file:read_file(RemoteFilename)),
+
+ Timeout = timer:seconds(3),
+ ?VERIFY(timeout, recv(0)),
+
+ %% Open socket
+ {ok, Socket} = ?VERIFY({ok, _}, gen_udp:open(0, [binary, {reuseaddr, true}, {active, true}])),
+
+ WriteList = [0, 2, RemoteFilename, 0, "octet", 0],
+ NewPort =
+ if
+ BlkSize =:= 512 ->
+ %% Send WRITE
+ WriteBin = list_to_binary(WriteList),
+ ?VERIFY(ok, gen_udp:send(Socket, Host, Port, WriteBin)),
+
+ %% Sleep a while in order to provoke the server to re-send the packet
+ timer:sleep(Timeout + timer:seconds(1)),
+
+ %% Recv ACK #0 (the packet that the server think that we have lost)
+ Ack0Bin = <<0, 4, 0, 0>>,
+ ?VERIFY({udp, Socket, Host, _, Ack0Bin}, recv(Timeout)),
+
+ %% Recv ACK #0 AGAIN (the re-sent package)
+ {udp, _, _, NewPort0, _} = ?VERIFY({udp, Socket, Host, _, Ack0Bin}, recv(Timeout)),
+ NewPort0;
+ true ->
+ %% Send WRITE
+ BlkSizeList = integer_to_list(BlkSize),
+ WriteBin = list_to_binary([WriteList, "blksize", 0, BlkSizeList, 0]),
+ ?VERIFY(ok, gen_udp:send(Socket, Host, Port, WriteBin)),
+
+ %% Sleep a while in order to provoke the server to re-send the packet
+ timer:sleep(timer:seconds(1)),
+
+ %% Recv OACK (the packet that the server think that we have lost)
+ OptionAckBin = list_to_binary([0, 6, "blksize",0, BlkSizeList, 0]),
+ ?VERIFY({udp, Socket, Host, _, OptionAckBin}, recv(Timeout)),
+
+ %% Recv OACK AGAIN (the re-sent package)
+ {udp, _, _, NewPort0, _} = ?VERIFY({udp, Socket, Host, _, OptionAckBin}, recv(Timeout)),
+ NewPort0
+ end,
+
+ %% Send DATA #1
+ Data1Bin = list_to_binary([0, 3, 0, 1 | Block1]),
+ ?VERIFY(ok, gen_udp:send(Socket, Host, NewPort, Data1Bin)),
+
+ %% Recv ACK #1
+ Ack1Bin = <<0, 4, 0, 1>>,
+ ?VERIFY({udp, Socket, Host, NewPort, Ack1Bin}, recv(Timeout)),
+
+ %% Send DATA #2
+ Data2Bin = list_to_binary([0, 3, 0, 2 | Block2]),
+ ?VERIFY(ok, gen_udp:send(Socket, Host, NewPort, Data2Bin)),
+
+ %% Recv ACK #2
+ Ack2Bin = <<0, 4, 0, 2>>,
+ ?VERIFY({udp, Socket, Host, NewPort, Ack2Bin}, recv(Timeout)),
+
+ %% Send DATA #3
+ Data3Bin = list_to_binary([0, 3, 0, 3 | Block3]),
+ ?VERIFY(ok, gen_udp:send(Socket, Host, NewPort, Data3Bin)),
+
+ %% Recv ACK #3
+ Ack3Bin = <<0, 4, 0, 3>>,
+ ?VERIFY({udp, Socket, Host, NewPort, Ack3Bin}, recv(Timeout)),
+
+ %% Send DATA #3 AGAIN (pretend that we timed out)
+ timer:sleep(timer:seconds(1)),
+ ?VERIFY(ok, gen_udp:send(Socket, Host, NewPort, Data3Bin)),
+
+ %% Recv ACK #3 AGAIN (the packet that the server think that we have lost)
+ ?VERIFY({udp, Socket, Host, NewPort, Ack3Bin}, recv(Timeout)),
+
+ %% Send DATA #2 which is out of range
+ ?VERIFY(ok, gen_udp:send(Socket, Host, NewPort, Data2Bin)),
+
+ %% Send DATA #4
+ Data4Bin = list_to_binary([0, 3, 0, 4 | Block4]),
+ ?VERIFY(ok, gen_udp:send(Socket, Host, NewPort, Data4Bin)),
+
+ %% Recv ACK #4
+ Ack4Bin = <<0, 4, 0, 4>>,
+ ?VERIFY({udp, Socket, Host, NewPort, Ack4Bin}, recv(Timeout)),
+
+ %% Send DATA #5
+ Data5Bin = list_to_binary([0, 3, 0, 5 | Block5]),
+ ?VERIFY(ok, gen_udp:send(Socket, Host, NewPort, Data5Bin)),
+
+ %% Recv ACK #5
+ Ack5Bin = <<0, 4, 0, 5>>,
+ ?VERIFY({udp, Socket, Host, NewPort, Ack5Bin}, recv(Timeout)),
+
+ %% Close socket
+ ?VERIFY(ok, gen_udp:close(Socket)),
+
+ ?VERIFY(timeout, recv(Timeout)),
+ ?VERIFY({ok, Blob}, file:read_file(RemoteFilename)),
+ ?VERIFY(ok, file:delete(RemoteFilename)),
+ ok.
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%% Re-send server
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+resend_server(doc) ->
+ ["Verify that the server behaves correctly when the server re-sends packets."];
+resend_server(suite) ->
+ [];
+resend_server(Config) when is_list(Config) ->
+ Host = {127, 0, 0, 1},
+
+ ?VERIFY(ok, resend_read_server(Host, 10)),
+ ?VERIFY(ok, resend_read_server(Host, 512)),
+ ?VERIFY(ok, resend_read_server(Host, 1025)),
+
+ ?VERIFY(ok, resend_write_server(Host, 10)),
+ ?VERIFY(ok, resend_write_server(Host, 512)),
+ ?VERIFY(ok, resend_write_server(Host, 1025)),
+ ok.
+
+resend_read_server(Host, BlkSize) ->
+ RemoteFilename = "tftp_resend_read_server.tmp",
+ Block1 = lists:duplicate(BlkSize, $1),
+ Block2 = lists:duplicate(BlkSize, $2),
+ Block3 = lists:duplicate(BlkSize, $3),
+ Block4 = lists:duplicate(BlkSize, $4),
+ Block5 = lists:duplicate(BlkSize, $5),
+ Block6 = [],
+ Blocks = [Block1, Block2, Block3, Block4, Block5, Block6],
+ Blob = list_to_binary(Blocks),
+
+ Timeout = timer:seconds(3),
+ ?VERIFY(timeout, recv(0)),
+
+ %% Open daemon socket
+ {ok, DaemonSocket} = ?VERIFY({ok, _}, gen_udp:open(0, [binary, {reuseaddr, true}, {active, true}])),
+ {ok, DaemonPort} = ?IGNORE(inet:port(DaemonSocket)),
+
+ %% Open server socket
+ {ok, ServerSocket} = ?VERIFY({ok, _}, gen_udp:open(0, [binary, {reuseaddr, true}, {active, true}])),
+ ?IGNORE(inet:port(ServerSocket)),
+
+ %% Prepare client process
+ ReplyTo = self(),
+ ClientFun =
+ fun(Extra) ->
+ Options = [{port, DaemonPort}, {debug, brief}] ++ Extra,
+ Res = ?VERIFY({ok, Blob}, tftp:read_file(RemoteFilename, binary, Options)),
+ ReplyTo ! {self(), {tftp_client_reply, Res}},
+ exit(normal)
+ end,
+
+ ReadList = [0, 1, RemoteFilename, 0, "octet", 0],
+ Data1Bin = list_to_binary([0, 3, 0, 1 | Block1]),
+ Ack1Bin = <<0, 4, 0, 1>>,
+ {ClientPort, ClientPid} =
+ if
+ BlkSize =:= 512 ->
+ %% Start client process
+ ClientPid0 = spawn_link(fun() -> ClientFun([]) end),
+
+ %% Recv READ
+ ReadBin = list_to_binary(ReadList),
+ {udp, _, _, ClientPort0, _} = ?VERIFY({udp, DaemonSocket, Host, _, ReadBin}, recv(Timeout)),
+
+ %% Send DATA #1
+ ?VERIFY(ok, gen_udp:send(ServerSocket, Host, ClientPort0, Data1Bin)),
+
+ %% Sleep a while in order to provoke the client to re-send the packet
+ timer:sleep(Timeout + timer:seconds(1)),
+
+ %% Recv ACK #1 (the packet that the server think that we have lost)
+ ?VERIFY({udp, ServerSocket, Host, ClientPort0, Ack1Bin}, recv(Timeout)),
+
+ %% Recv ACK #1 AGAIN (the re-sent package)
+ ?VERIFY({udp, ServerSocket, Host, _, Ack1Bin}, recv(Timeout)),
+ {ClientPort0, ClientPid0};
+ true ->
+ %% Start client process
+ BlkSizeList = integer_to_list(BlkSize),
+ ClientPid0 = spawn_link(fun() -> ClientFun([{"blksize", BlkSizeList}]) end),
+
+ %% Recv READ
+ Options = ["blksize", 0, BlkSizeList, 0],
+ ReadBin = list_to_binary([ReadList | Options]),
+ {udp, _, _, ClientPort0, _} = ?VERIFY({udp, DaemonSocket, Host, _, ReadBin}, recv(Timeout)),
+
+ %% Send OACK
+ BlkSizeList = integer_to_list(BlkSize),
+ OptionAckBin = list_to_binary([0, 6, "blksize",0, BlkSizeList, 0]),
+ ?VERIFY(ok, gen_udp:send(ServerSocket, Host, ClientPort0, OptionAckBin)),
+
+ %% Sleep a while in order to provoke the client to re-send the packet
+ timer:sleep(Timeout + timer:seconds(1)),
+
+ %% Recv ACK #0 (the packet that the server think that we have lost)
+ Ack0Bin = <<0, 4, 0, 0>>,
+ ?VERIFY({udp, ServerSocket, Host, ClientPort0, Ack0Bin}, recv(Timeout)),
+
+ %% Recv ACK #0 AGAIN (the re-sent package)
+ ?VERIFY({udp, ServerSocket, Host, ClientPort0, Ack0Bin}, recv(Timeout)),
+
+ %% Send DATA #1
+ ?VERIFY(ok, gen_udp:send(ServerSocket, Host, ClientPort0, Data1Bin)),
+
+ %% Recv ACK #1
+ ?VERIFY({udp, ServerSocket, Host, _, Ack1Bin}, recv(Timeout)),
+ {ClientPort0, ClientPid0}
+ end,
+
+ %% Send DATA #2
+ Data2Bin = list_to_binary([0, 3, 0, 2 | Block2]),
+ ?VERIFY(ok, gen_udp:send(ServerSocket, Host, ClientPort, Data2Bin)),
+
+ %% Recv ACK #2
+ Ack2Bin = <<0, 4, 0, 2>>,
+ ?VERIFY({udp, ServerSocket, Host, ClientPort, Ack2Bin}, recv(Timeout)),
+
+ %% Send DATA #3
+ Data3Bin = list_to_binary([0, 3, 0, 3 | Block3]),
+ ?VERIFY(ok, gen_udp:send(ServerSocket, Host, ClientPort, Data3Bin)),
+
+ %% Recv ACK #3
+ Ack3Bin = <<0, 4, 0, 3>>,
+ ?VERIFY({udp, ServerSocket, Host, ClientPort, Ack3Bin}, recv(Timeout)),
+
+ %% Send DATA #3 AGAIN (pretend that we timed out)
+ timer:sleep(timer:seconds(1)),
+ ?VERIFY(ok, gen_udp:send(ServerSocket, Host, ClientPort, Data3Bin)),
+
+ %% Recv ACK #3 AGAIN (the packet that the server think that we have lost)
+ ?VERIFY({udp, ServerSocket, Host, ClientPort, Ack3Bin}, recv(Timeout)),
+
+ %% Send DATA #4
+ Data4Bin = list_to_binary([0, 3, 0, 4 | Block4]),
+ ?VERIFY(ok, gen_udp:send(ServerSocket, Host, ClientPort, Data4Bin)),
+
+ %% Recv ACK #4
+ Ack4Bin = <<0, 4, 0, 4>>,
+ ?VERIFY({udp, ServerSocket, Host, ClientPort, Ack4Bin}, recv(Timeout)),
+
+ %% Send DATA #3 which is out of range
+ ?VERIFY(ok, gen_udp:send(ServerSocket, Host, ClientPort, Data3Bin)),
+
+ %% Send DATA #5
+ Data5Bin = list_to_binary([0, 3, 0, 5 | Block5]),
+ ?VERIFY(ok, gen_udp:send(ServerSocket, Host, ClientPort, Data5Bin)),
+
+ %% Recv ACK #5
+ Ack5Bin = <<0, 4, 0, 5>>,
+ ?VERIFY({udp, ServerSocket, Host, ClientPort, Ack5Bin}, recv(Timeout)),
+
+ %% Send DATA #6
+ Data6Bin = list_to_binary([0, 3, 0, 6 | Block6]),
+ ?VERIFY(ok, gen_udp:send(ServerSocket, Host, ClientPort, Data6Bin)),
+
+ %% Close daemon and server sockets
+ ?VERIFY(ok, gen_udp:close(ServerSocket)),
+ ?VERIFY(ok, gen_udp:close(DaemonSocket)),
+
+ ?VERIFY({ClientPid, {tftp_client_reply, {ok, Blob}}}, recv(Timeout)),
+
+ ?VERIFY(timeout, recv(Timeout)),
+ ok.
+
+resend_write_server(Host, BlkSize) ->
+ RemoteFilename = "tftp_resend_write_server.tmp",
+ Block1 = lists:duplicate(BlkSize, $1),
+ Block2 = lists:duplicate(BlkSize, $2),
+ Block3 = lists:duplicate(BlkSize, $3),
+ Block4 = lists:duplicate(BlkSize, $4),
+ Block5 = lists:duplicate(BlkSize, $5),
+ Block6 = [],
+ Blocks = [Block1, Block2, Block3, Block4, Block5, Block6],
+ Blob = list_to_binary(Blocks),
+ Size = size(Blob),
+
+ Timeout = timer:seconds(3),
+ ?VERIFY(timeout, recv(0)),
+
+ %% Open daemon socket
+ {ok, DaemonSocket} = ?VERIFY({ok, _}, gen_udp:open(0, [binary, {reuseaddr, true}, {active, true}])),
+ {ok, DaemonPort} = ?IGNORE(inet:port(DaemonSocket)),
+
+ %% Open server socket
+ {ok, ServerSocket} = ?VERIFY({ok, _}, gen_udp:open(0, [binary, {reuseaddr, true}, {active, true}])),
+ ?IGNORE(inet:port(ServerSocket)),
+
+ %% Prepare client process
+ ReplyTo = self(),
+ ClientFun =
+ fun(Extra) ->
+ Options = [{port, DaemonPort}, {debug, brief}] ++ Extra,
+ Res = ?VERIFY({ok, Size}, tftp:write_file(RemoteFilename, Blob, Options)),
+ ReplyTo ! {self(), {tftp_client_reply, Res}},
+ exit(normal)
+ end,
+
+ WriteList = [0, 2, RemoteFilename, 0, "octet", 0],
+ Data1Bin = list_to_binary([0, 3, 0, 1 | Block1]),
+ {ClientPort, ClientPid} =
+ if
+ BlkSize =:= 512 ->
+ %% Start client process
+ ClientPid0 = spawn_link(fun() -> ClientFun([]) end),
+
+ %% Recv WRITE
+ WriteBin = list_to_binary(WriteList),
+ io:format("WriteBin ~p\n", [WriteBin]),
+ {udp, _, _, ClientPort0, _} = ?VERIFY({udp, DaemonSocket, Host, _, WriteBin}, recv(Timeout)),
+
+ %% Send ACK #1
+ Ack0Bin = <<0, 4, 0, 0>>,
+ ?VERIFY(ok, gen_udp:send(ServerSocket, Host, ClientPort0, Ack0Bin)),
+
+ %% Sleep a while in order to provoke the client to re-send the packet
+ timer:sleep(Timeout + timer:seconds(1)),
+
+ %% Recv DATA #1 (the packet that the server think that we have lost)
+ ?VERIFY({udp, ServerSocket, Host, ClientPort0, Data1Bin}, recv(Timeout)),
+
+ %% Recv DATA #1 AGAIN (the re-sent package)
+ ?VERIFY({udp, ServerSocket, Host, _, Data1Bin}, recv(Timeout)),
+ {ClientPort0, ClientPid0};
+ true ->
+ %% Start client process
+ BlkSizeList = integer_to_list(BlkSize),
+ ClientPid0 = spawn_link(fun() -> ClientFun([{"blksize", BlkSizeList}]) end),
+
+ %% Recv WRITE
+ Options = ["blksize", 0, BlkSizeList, 0],
+ WriteBin = list_to_binary([WriteList | Options]),
+ {udp, _, _, ClientPort0, _} = ?VERIFY({udp, DaemonSocket, Host, _, WriteBin}, recv(Timeout)),
+
+ %% Send OACK
+ BlkSizeList = integer_to_list(BlkSize),
+ OptionAckBin = list_to_binary([0, 6, "blksize",0, BlkSizeList, 0]),
+ ?VERIFY(ok, gen_udp:send(ServerSocket, Host, ClientPort0, OptionAckBin)),
+
+ %% Sleep a while in order to provoke the client to re-send the packet
+ timer:sleep(Timeout + timer:seconds(1)),
+
+ %% Recv DATA #1 (the packet that the server think that we have lost)
+ ?VERIFY({udp, ServerSocket, Host, ClientPort0, Data1Bin}, recv(Timeout)),
+
+ %% Recv DATA #1 AGAIN (the re-sent package)
+ ?VERIFY({udp, ServerSocket, Host, ClientPort0, Data1Bin}, recv(Timeout)),
+ {ClientPort0, ClientPid0}
+ end,
+
+ %% Send ACK #1
+ Ack1Bin = <<0, 4, 0, 1>>,
+ ?VERIFY(ok, gen_udp:send(ServerSocket, Host, ClientPort, Ack1Bin)),
+
+ %% Recv DATA #2
+ Data2Bin = list_to_binary([0, 3, 0, 2 | Block2]),
+ ?VERIFY({udp, ServerSocket, Host, ClientPort, Data2Bin}, recv(Timeout)),
+
+ %% Send ACK #2
+ Ack2Bin = <<0, 4, 0, 2>>,
+ ?VERIFY(ok, gen_udp:send(ServerSocket, Host, ClientPort, Ack2Bin)),
+
+ %% Recv DATA #3
+ Data3Bin = list_to_binary([0, 3, 0, 3 | Block3]),
+ ?VERIFY({udp, ServerSocket, Host, ClientPort, Data3Bin}, recv(Timeout)),
+
+ %% Send ACK #3
+ Ack3Bin = <<0, 4, 0, 3>>,
+ ?VERIFY(ok, gen_udp:send(ServerSocket, Host, ClientPort, Ack3Bin)),
+
+ %% Send ACK #3 AGAIN (pretend that we timed out)
+ timer:sleep(timer:seconds(1)),
+ ?VERIFY(ok, gen_udp:send(ServerSocket, Host, ClientPort, Ack3Bin)),
+
+ %% Recv DATA #4 (the packet that the server think that we have lost)
+ Data4Bin = list_to_binary([0, 3, 0, 4 | Block4]),
+ ?VERIFY({udp, ServerSocket, Host, ClientPort, Data4Bin}, recv(Timeout)),
+
+ %% Recv DATA #4 AGAIN (the re-sent package)
+ ?VERIFY({udp, ServerSocket, Host, ClientPort, Data4Bin}, recv(Timeout)),
+
+ %% Send ACK #4
+ Ack4Bin = <<0, 4, 0, 4>>,
+ ?VERIFY(ok, gen_udp:send(ServerSocket, Host, ClientPort, Ack4Bin)),
+
+ %% Recv DATA #5
+ Data5Bin = list_to_binary([0, 3, 0, 5 | Block5]),
+ ?VERIFY({udp, ServerSocket, Host, ClientPort, Data5Bin}, recv(Timeout)),
+
+ %% Send ACK #3 which is out of range
+ ?VERIFY(ok, gen_udp:send(ServerSocket, Host, ClientPort, Ack3Bin)),
+
+ %% Send ACK #5
+ Ack5Bin = <<0, 4, 0, 5>>,
+ ?VERIFY(ok, gen_udp:send(ServerSocket, Host, ClientPort, Ack5Bin)),
+
+ %% Recv DATA #6
+ Data6Bin = list_to_binary([0, 3, 0, 6 | Block6]),
+ ?VERIFY({udp, ServerSocket, Host, ClientPort, Data6Bin}, recv(Timeout)),
+
+ %% Send ACK #6
+ Ack6Bin = <<0, 4, 0, 6>>,
+ ?VERIFY(ok, gen_udp:send(ServerSocket, Host, ClientPort, Ack6Bin)),
+
+ %% Close daemon and server sockets
+ ?VERIFY(ok, gen_udp:close(ServerSocket)),
+ ?VERIFY(ok, gen_udp:close(DaemonSocket)),
+
+ ?VERIFY({ClientPid, {tftp_client_reply, {ok, Size}}}, recv(Timeout)),
+
+ ?VERIFY(timeout, recv(Timeout)),
+ ok.
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+reuse_connection(doc) ->
+ ["Verify that the server can reuse an ongiong connection when same client resends request."];
+reuse_connection(suite) ->
+ [];
+reuse_connection(Config) when is_list(Config) ->
+ Host = {127, 0, 0, 1},
+ {Port, DaemonPid} = ?IGNORE(?START_DAEMON(0, [{debug, all}])),
+
+ RemoteFilename = "reuse_connection.tmp",
+ BlkSize = 512,
+ Block1 = lists:duplicate(BlkSize, $1),
+ Block2 = lists:duplicate(BlkSize div 2, $2),
+ Blocks = [Block1, Block2],
+ Blob = list_to_binary(Blocks),
+ ?VERIFY(ok, file:write_file(RemoteFilename, Blob)),
+
+ Seconds = 3,
+ Timeout = timer:seconds(Seconds),
+ ?VERIFY(timeout, recv(0)),
+
+ %% Open socket
+ {ok, Socket} = ?VERIFY({ok, _}, gen_udp:open(0, [binary, {reuseaddr, true}, {active, true}])),
+
+ ReadList = [0, 1, RemoteFilename, 0, "octet", 0],
+ Data1Bin = list_to_binary([0, 3, 0, 1 | Block1]),
+
+ %% Send READ
+ TimeoutList = integer_to_list(Seconds),
+ Options = ["timeout", 0, TimeoutList, 0],
+ ReadBin = list_to_binary([ReadList | Options]),
+ ?VERIFY(ok, gen_udp:send(Socket, Host, Port, ReadBin)),
+
+ %% Send yet another READ for same file
+ ?VERIFY(ok, gen_udp:send(Socket, Host, Port, ReadBin)),
+
+ %% Recv OACK
+ OptionAckBin = list_to_binary([0, 6 | Options]),
+ {udp, _, _, NewPort, _} = ?VERIFY({udp, Socket, Host, _, OptionAckBin}, recv(Timeout)),
+
+ %% Send ACK #0
+ Ack0Bin = <<0, 4, 0, 0>>,
+ ?VERIFY(ok, gen_udp:send(Socket, Host, NewPort, Ack0Bin)),
+
+ %% Recv DATA #1
+ ?VERIFY({udp, Socket, Host, NewPort, Data1Bin}, recv(Timeout)),
+
+ %% Send ACK #1
+ Ack1Bin = <<0, 4, 0, 1>>,
+ ?VERIFY(ok, gen_udp:send(Socket, Host, NewPort, Ack1Bin)),
+
+ %% Recv DATA #2
+ Data2Bin = list_to_binary([0, 3, 0, 2 | Block2]),
+ ?VERIFY({udp, Socket, Host, NewPort, Data2Bin}, recv(Timeout)),
+
+ %% Send ACK #2
+ Ack2Bin = <<0, 4, 0, 2>>,
+ ?VERIFY(ok, gen_udp:send(Socket, Host, NewPort, Ack2Bin)),
+
+ %% Close socket
+ ?VERIFY(ok, gen_udp:close(Socket)),
+
+ ?VERIFY(timeout, recv(Timeout)),
+ ?VERIFY(ok, file:delete(RemoteFilename)),
+
+ %% Cleanup
+ unlink(DaemonPid),
+ exit(DaemonPid, kill),
+ ok.
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%% Goodies
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+recv(Timeout) ->
+ receive
+ Msg ->
+ Msg
+ after Timeout ->
+ timeout
+ end.
diff --git a/lib/inets/test/tftp_test_lib.erl b/lib/inets/test/tftp_test_lib.erl
new file mode 100644
index 0000000000..3729309b0e
--- /dev/null
+++ b/lib/inets/test/tftp_test_lib.erl
@@ -0,0 +1,307 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 2007-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(tftp_test_lib).
+
+-compile(export_all).
+
+-include("tftp_test_lib.hrl").
+
+%%
+%% -----
+%%
+
+init_per_testcase(_Case, Config) when is_list(Config) ->
+ io:format("\n ", []),
+ ?IGNORE(application:stop(inets)),
+ Config.
+
+fin_per_testcase(_Case, Config) when is_list(Config) ->
+ ?IGNORE(application:stop(inets)),
+ Config.
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%% Infrastructure for test suite
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+error(Actual, Mod, Line) ->
+ (catch global:send(tftp_global_logger, {failed, Mod, Line})),
+ log("<ERROR> Bad result: ~p\n", [Actual], Mod, Line),
+ Label = lists:concat([Mod, "(", Line, ") unexpected result"]),
+ et:report_event(60, Mod, Mod, Label,
+ [{line, Mod, Line}, {error, Actual}]),
+ case global:whereis_name(tftp_test_case_sup) of
+ undefined ->
+ ignore;
+ Pid ->
+ Fail = #'REASON'{mod = Mod, line = Line, desc = Actual},
+ Pid ! {fail, self(), Fail}
+ end,
+ Actual.
+
+log(Format, Args, Mod, Line) ->
+ case global:whereis_name(tftp_global_logger) of
+ undefined ->
+ io:format(user, "~p(~p): " ++ Format,
+ [Mod, Line] ++ Args);
+ Pid ->
+ io:format(Pid, "~p(~p): " ++ Format,
+ [Mod, Line] ++ Args)
+ end.
+
+default_config() ->
+ [].
+
+t() ->
+ t([{?MODULE, all}]).
+
+t(Cases) ->
+ t(Cases, default_config()).
+
+t(Cases, Config) ->
+ process_flag(trap_exit, true),
+ Res = lists:flatten(do_test(Cases, Config)),
+ io:format("Res: ~p\n", [Res]),
+ display_result(Res),
+ Res.
+
+do_test({Mod, Fun}, Config) when is_atom(Mod), is_atom(Fun) ->
+ case catch apply(Mod, Fun, [suite]) of
+ [] ->
+ io:format("Eval: ~p:", [{Mod, Fun}]),
+ Res = eval(Mod, Fun, Config),
+ {R, _, _} = Res,
+ io:format(" ~p\n", [R]),
+ Res;
+
+ Cases when is_list(Cases) ->
+ io:format("Expand: ~p ...\n", [{Mod, Fun}]),
+ Map = fun(Case) when is_atom(Case)-> {Mod, Case};
+ (Case) -> Case
+ end,
+ do_test(lists:map(Map, Cases), Config);
+
+ {req, _, {conf, Init, Cases, Finish}} ->
+ case (catch apply(Mod, Init, [Config])) of
+ Conf when is_list(Conf) ->
+ io:format("Expand: ~p ...\n", [{Mod, Fun}]),
+ Map = fun(Case) when is_atom(Case)-> {Mod, Case};
+ (Case) -> Case
+ end,
+ Res = do_test(lists:map(Map, Cases), Conf),
+ (catch apply(Mod, Finish, [Conf])),
+ Res;
+
+ {'EXIT', {skipped, Reason}} ->
+ io:format(" => skipping: ~p\n", [Reason]),
+ [{skipped, {Mod, Fun}, Reason}];
+
+ Error ->
+ io:format(" => failed: ~p\n", [Error]),
+ [{failed, {Mod, Fun}, Error}]
+ end;
+
+ {'EXIT', {undef, _}} ->
+ io:format("Undefined: ~p\n", [{Mod, Fun}]),
+ [{nyi, {Mod, Fun}, ok}];
+
+ Error ->
+ io:format("Ignoring: ~p: ~p\n", [{Mod, Fun}, Error]),
+ [{failed, {Mod, Fun}, Error}]
+ end;
+do_test(Mod, Config) when is_atom(Mod) ->
+ Res = do_test({Mod, all}, Config),
+ Res;
+do_test(Cases, Config) when is_list(Cases) ->
+ [do_test(Case, Config) || Case <- Cases];
+do_test(Bad, _Config) ->
+ [{badarg, Bad, ok}].
+
+eval(Mod, Fun, Config) ->
+ TestCase = {?MODULE, Mod, Fun},
+ Label = lists:concat(["TEST CASE: ", Fun]),
+ et:report_event(40, ?MODULE, Mod, Label ++ " started",
+ [TestCase, Config]),
+ global:register_name(tftp_test_case_sup, self()),
+ Flag = process_flag(trap_exit, true),
+ Config2 = Mod:init_per_testcase(Fun, Config),
+ Pid = spawn_link(?MODULE, do_eval, [self(), Mod, Fun, Config2]),
+ R = wait_for_evaluator(Pid, Mod, Fun, Config2, []),
+ Mod:fin_per_testcase(Fun, Config2),
+ global:unregister_name(tftp_test_case_sup),
+ process_flag(trap_exit, Flag),
+ R.
+
+wait_for_evaluator(Pid, Mod, Fun, Config, Errors) ->
+ TestCase = {?MODULE, Mod, Fun},
+ Label = lists:concat(["TEST CASE: ", Fun]),
+ receive
+ {done, Pid, ok} when Errors == [] ->
+ et:report_event(40, Mod, ?MODULE, Label ++ " ok",
+ [TestCase, Config]),
+ {ok, {Mod, Fun}, Errors};
+ {done, Pid, {ok, _}} when Errors == [] ->
+ et:report_event(40, Mod, ?MODULE, Label ++ " ok",
+ [TestCase, Config]),
+ {ok, {Mod, Fun}, Errors};
+ {done, Pid, Fail} ->
+ et:report_event(20, Mod, ?MODULE, Label ++ " failed",
+ [TestCase, Config, {return, Fail}, Errors]),
+ {failed, {Mod,Fun}, Fail};
+ {'EXIT', Pid, {skipped, Reason}} ->
+ et:report_event(20, Mod, ?MODULE, Label ++ " skipped",
+ [TestCase, Config, {skipped, Reason}]),
+ {skipped, {Mod, Fun}, Errors};
+ {'EXIT', Pid, Reason} ->
+ et:report_event(20, Mod, ?MODULE, Label ++ " crashed",
+ [TestCase, Config, {'EXIT', Reason}]),
+ {crashed, {Mod, Fun}, [{'EXIT', Reason} | Errors]};
+ {fail, Pid, Reason} ->
+ wait_for_evaluator(Pid, Mod, Fun, Config, Errors ++ [Reason])
+ end.
+
+do_eval(ReplyTo, Mod, Fun, Config) ->
+ case (catch apply(Mod, Fun, [Config])) of
+ {'EXIT', {skipped, Reason}} ->
+ ReplyTo ! {'EXIT', self(), {skipped, Reason}};
+ Other ->
+ ReplyTo ! {done, self(), Other}
+ end,
+ unlink(ReplyTo),
+ exit(shutdown).
+
+display_result([]) ->
+ io:format("OK\n", []);
+display_result(Res) when is_list(Res) ->
+ Ok = [MF || {ok, MF, _} <- Res],
+ Nyi = [MF || {nyi, MF, _} <- Res],
+ Skipped = [{MF, Reason} || {skipped, MF, Reason} <- Res],
+ Failed = [{MF, Reason} || {failed, MF, Reason} <- Res],
+ Crashed = [{MF, Reason} || {crashed, MF, Reason} <- Res],
+ display_summary(Ok, Nyi, Skipped, Failed, Crashed),
+ display_skipped(Skipped),
+ display_failed(Failed),
+ display_crashed(Crashed).
+
+display_summary(Ok, Nyi, Skipped, Failed, Crashed) ->
+ io:format("\nTest case summary:\n", []),
+ display_summary(Ok, "successful"),
+ display_summary(Nyi, "not yet implemented"),
+ display_summary(Skipped, "skipped"),
+ display_summary(Failed, "failed"),
+ display_summary(Crashed, "crashed"),
+ io:format("\n", []).
+
+display_summary(Res, Info) ->
+ io:format(" ~w test cases ~s\n", [length(Res), Info]).
+
+display_skipped([]) ->
+ ok;
+display_skipped(Skipped) ->
+ io:format("Skipped test cases:\n", []),
+ F = fun({MF, Reason}) -> io:format(" ~p => ~p\n", [MF, Reason]) end,
+ lists:foreach(F, Skipped),
+ io:format("\n", []).
+
+
+display_failed([]) ->
+ ok;
+display_failed(Failed) ->
+ io:format("Failed test cases:\n", []),
+ F = fun({MF, Reason}) -> io:format(" ~p => ~p\n", [MF, Reason]) end,
+ lists:foreach(F, Failed),
+ io:format("\n", []).
+
+display_crashed([]) ->
+ ok;
+display_crashed(Crashed) ->
+ io:format("Crashed test cases:\n", []),
+ F = fun({MF, Reason}) -> io:format(" ~p => ~p\n", [MF, Reason]) end,
+ lists:foreach(F, Crashed),
+ io:format("\n", []).
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%% generic callback
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+-record(generic_state, {state, prepare, open, read, write, abort}).
+
+prepare(Peer, Access, LocalFilename, Mode, SuggestedOptions, Initial) when is_list(Initial) ->
+ State = lookup_option(state, mandatory, Initial),
+ Prepare = lookup_option(prepare, mandatory, Initial),
+ Open = lookup_option(open, mandatory, Initial),
+ Read = lookup_option(read, mandatory, Initial),
+ Write = lookup_option(write, mandatory, Initial),
+ Abort = lookup_option(abort, mandatory, Initial),
+ case Prepare(Peer, Access, LocalFilename, Mode, SuggestedOptions, State) of
+ {ok, AcceptedOptions, NewState} ->
+ {ok,
+ AcceptedOptions,
+ #generic_state{state = NewState,
+ prepare = Prepare,
+ open = Open,
+ read = Read,
+ write = Write,
+ abort = Abort}};
+ Other ->
+ Other
+ end.
+
+open(Peer, Access, LocalFilename, Mode, SuggestedOptions, Initial) when is_list(Initial) ->
+ case prepare(Peer, Access, LocalFilename, Mode, SuggestedOptions, Initial) of
+ {ok, SuggestedOptions2, GenericState} ->
+ open(Peer, Access, LocalFilename, Mode, SuggestedOptions2, GenericState);
+ Other ->
+ Other
+ end;
+open(Peer, Access, LocalFilename, Mode, SuggestedOptions, #generic_state{state = State, open = Open} = GenericState) ->
+ case Open(Peer, Access, LocalFilename, Mode, SuggestedOptions, State) of
+ {ok, SuggestedOptions2, NewState} ->
+ {ok, SuggestedOptions2, GenericState#generic_state{state = NewState}};
+ Other ->
+ Other
+ end.
+
+read(#generic_state{state = State, read = Read} = GenericState) ->
+ case Read(State) of
+ {more, DataBlock, NewState} ->
+ {more, DataBlock, GenericState#generic_state{state = NewState}};
+ Other ->
+ Other
+ end.
+
+write(DataBlock, #generic_state{state = State, write = Write} = GenericState) ->
+ case Write(DataBlock, State) of
+ {more, NewState} ->
+ {more, GenericState#generic_state{state = NewState}};
+ Other ->
+ Other
+ end.
+
+abort(Code, Text, #generic_state{state = State, abort = Abort}) ->
+ Abort(Code, Text, State).
+
+lookup_option(Key, Default, Options) ->
+ case lists:keysearch(Key, 1, Options) of
+ {value, {_, Val}} ->
+ Val;
+ false ->
+ Default
+ end.
+
diff --git a/lib/inets/test/tftp_test_lib.hrl b/lib/inets/test/tftp_test_lib.hrl
new file mode 100644
index 0000000000..da4b065976
--- /dev/null
+++ b/lib/inets/test/tftp_test_lib.hrl
@@ -0,0 +1,43 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 2007-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%
+%%
+
+-record('REASON', {mod, line, desc}).
+
+-define(LOG(Format, Args),
+ tftp_test_lib:log(Format, Args, ?MODULE, ?LINE)).
+
+-define(ERROR(Reason),
+ tftp_test_lib:error(Reason, ?MODULE, ?LINE)).
+
+-define(VERIFY(Expected, Expr),
+ fun() ->
+ AcTuAlReS = (catch (Expr)),
+ case AcTuAlReS of
+ Expected -> ?LOG("Ok, ~p\n", [AcTuAlReS]);
+ _ -> ?ERROR(AcTuAlReS)
+ end,
+ AcTuAlReS
+ end()).
+
+-define(IGNORE(Expr),
+ fun() ->
+ AcTuAlReS = (catch (Expr)),
+ ?LOG("Ok, ~p\n", [AcTuAlReS]),
+ AcTuAlReS
+ end()).
diff --git a/lib/inets/vsn.mk b/lib/inets/vsn.mk
index f80524e7e7..778b1ddaf7 100644
--- a/lib/inets/vsn.mk
+++ b/lib/inets/vsn.mk
@@ -1,37 +1,78 @@
-#-*-makefile-*- ; force emacs to enter makefile-mode
+APPLICATION = inets
+INETS_VSN = 5.3.6
+PRE_VSN =
+APP_VSN = "$(APPLICATION)-$(INETS_VSN)$(PRE_VSN)"
-# %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%
+TICKETS = OTP-9655 OTP-9674
-INETS_VSN = 5.2
-PRE_VSN =
-APP_VSN = "inets-$(INETS_VSN)$(PRE_VSN)"
+TICKETS_5_3_5 = OTP-8940
-TICKETS = OTP-8204 OTP-8206 OTP-8247 OTP-8248 OTP-8249 OTP-8258 OTP-8280
+TICKETS_5_3_4 = \
+ OTP-8739 \
+ OTP-8741 \
+ OTP-8742
-TICKETS_5_1_3 = OTP-8154
+TICKETS_5_3_3 = \
+ OTP-8609 \
+ OTP-8610 \
+ OTP-8624
-TICKETS_5_1_2 = OTP-7298 OTP-8101 OTP-8118
+TICKETS_5_3_2 = \
+ OTP-8542 \
+ OTP-8607
-TICKETS_5_1_1 = OTP-8052 OTP-8069
+TICKETS_5_3_1 = \
+ OTP-8508 \
+ OTP-8509
-TICKETS_5_1 = OTP-7994 OTP-7998 OTP-8001 OTP-8004 OTP-8005
+TICKETS_5_3 = \
+ OTP-8016 \
+ OTP-8056 \
+ OTP-8103 \
+ OTP-8106 \
+ OTP-8312 \
+ OTP-8315 \
+ OTP-8327 \
+ OTP-8349 \
+ OTP-8351 \
+ OTP-8352 \
+ OTP-8359 \
+ OTP-8371
-TICKETS_5_0_14 = OTP-7882 OTP-7883 OTP-7888 OTP-7950 OTP-7976
+TICKETS_5_2 = \
+ OTP-8204 \
+ OTP-8206 \
+ OTP-8247 \
+ OTP-8248 \
+ OTP-8249 \
+ OTP-8258 \
+ OTP-8280
+
+TICKETS_5_1_3 = \
+ OTP-8154
+
+TICKETS_5_1_2 = \
+ OTP-7298 \
+ OTP-8101 \
+ OTP-8118
+
+TICKETS_5_1_1 = \
+ OTP-8052 \
+ OTP-8069
+
+TICKETS_5_1 = \
+ OTP-7994 \
+ OTP-7998 \
+ OTP-8001 \
+ OTP-8004 \
+ OTP-8005
+
+TICKETS_5_0_14 = \
+ OTP-7882 \
+ OTP-7883 \
+ OTP-7888 \
+ OTP-7950 \
+ OTP-7976
TICKETS_5.0.13 = \
OTP-7723 \
@@ -41,41 +82,3 @@ TICKETS_5.0.13 = \
OTP-7815 \
OTP-7857
-# TICKETS_5.0.12 = \
-# OTP-7636
-#
-# TICKETS_5.0.11 = \
-# OTP-7574 \
-# OTP-7597 \
-# OTP-7598 \
-# OTP-7605
-#
-# TICKETS_5.0.10 = \
-# OTP-7450 \
-# OTP-7454 \
-# OTP-7490 \
-# OTP-7512
-#
-# TICKETS_5.0.9 = \
-# OTP-7257 \
-# OTP-7323 \
-# OTP-7341
-#
-# TICKETS_5.0.8 = \
-# OTP-7315 \
-# OTP-7321
-#
-# TICKETS_5.0.7 = \
-# OTP-7304
-#
-# TICKETS_5.0.6 = \
-# OTP-7266
-#
-# TICKETS_5.0.5 = \
-# OTP-7220 \
-# OTP-7221
-#
-# TICKETS_5.0.4 = \
-# OTP-7173
-#
-
diff --git a/lib/jinterface/doc/src/Makefile b/lib/jinterface/doc/src/Makefile
index c4cfde0e9c..acd5307dee 100644
--- a/lib/jinterface/doc/src/Makefile
+++ b/lib/jinterface/doc/src/Makefile
@@ -2,20 +2,20 @@
#
# %CopyrightBegin%
-#
-# Copyright Ericsson AB 2000-2009. All Rights Reserved.
-#
+#
+# Copyright Ericsson AB 2000-2010. All Rights Reserved.
+#
# The contents of this file are subject to the Erlang Public License,
# Version 1.1, (the "License"); you may not use this file except in
# compliance with the License. You should have received a copy of the
# Erlang Public License along with this software. If not, it can be
# retrieved online at http://www.erlang.org/.
-#
+#
# Software distributed under the License is distributed on an "AS IS"
# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
# the License for the specific language governing rights and limitations
# under the License.
-#
+#
# %CopyrightEnd%
#
include $(ERL_TOP)/make/target.mk
@@ -53,6 +53,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 = \
notes.gif \
ref_man.gif \
diff --git a/lib/jinterface/doc/src/notes.xml b/lib/jinterface/doc/src/notes.xml
index 90ac2991f3..977a7a7f98 100644
--- a/lib/jinterface/doc/src/notes.xml
+++ b/lib/jinterface/doc/src/notes.xml
@@ -4,7 +4,7 @@
<chapter>
<header>
<copyright>
- <year>2000</year><year>2009</year>
+ <year>2000</year><year>2010</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
@@ -13,12 +13,12 @@
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>Jinterface Release Notes</title>
@@ -30,6 +30,37 @@
</header>
<p>This document describes the changes made to the Jinterface application.</p>
+<section><title>Jinterface 1.5.3</title>
+
+ <section><title>Improvements and New Features</title>
+ <list>
+ <item>
+ <p>The documentation is now possible to build in an open
+ source environment after a number of bugs are fixed and
+ some features are added in the documentation build
+ process. </p>
+ <p>- The arity calculation is updated.</p>
+ <p>- The module prefix used in the function names for
+ bif's are removed in the generated links so the links
+ will look like
+ "http://www.erlang.org/doc/man/erlang.html#append_element-2"
+ instead of
+ "http://www.erlang.org/doc/man/erlang.html#erlang:append_element-2".</p>
+ <p>- Enhanced the menu positioning in the html
+ documentation when a new page is loaded.</p>
+ <p>- A number of corrections in the generation of man
+ pages (thanks to Sergei Golovan)</p>
+ <p>- The legal notice is taken from the xml book file so
+ OTP's build process can be used for non OTP
+ applications.</p>
+ <p>
+ Own Id: OTP-8343</p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
<section><title>Jinterface 1.5.2</title>
<section><title>Improvements and New Features</title>
diff --git a/lib/jinterface/test/Makefile b/lib/jinterface/test/Makefile
new file mode 100644
index 0000000000..36955d1e91
--- /dev/null
+++ b/lib/jinterface/test/Makefile
@@ -0,0 +1,84 @@
+#
+# %CopyrightBegin%
+#
+# Copyright Ericsson AB 2004-2010. All Rights Reserved.
+#
+# The contents of this file are subject to the Erlang Public License,
+# Version 1.1, (the "License"); you may not use this file except in
+# compliance with the License. You should have received a copy of the
+# Erlang Public License along with this software. If not, it can be
+# retrieved online at http://www.erlang.org/.
+#
+# Software distributed under the License is distributed on an "AS IS"
+# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+# the License for the specific language governing rights and limitations
+# under the License.
+#
+# %CopyrightEnd%
+#
+include $(ERL_TOP)/make/target.mk
+include $(ERL_TOP)/make/$(TARGET)/otp.mk
+
+# ----------------------------------------------------
+# Application version
+# ----------------------------------------------------
+include ../vsn.mk
+
+# ----------------------------------------------------
+# Release directory specification
+# ----------------------------------------------------
+RELSYSDIR = $(RELEASE_PATH)/jinterface_test
+
+# ----------------------------------------------------
+# Target Specs
+# ----------------------------------------------------
+TEST_SPEC_FILE = jinterface.dynspec
+
+MODULES = nc_SUITE \
+ jinterface_SUITE
+
+GEN_MODULES = jitu
+
+ERL_FILES = $(MODULES:%=%.erl) $(GEN_MODULES:%=%.erl)
+
+GEN_TARGET_FILES = $(GEN_MODULES:%=%.$(EMULATOR))
+
+SUITE_TARGET_FILES = $(MODULES:%=%.$(EMULATOR))
+
+TARGET_FILES = \
+ $(GEN_TARGET_FILES) \
+ $(SUITE_TARGET_FILES)
+
+# ----------------------------------------------------
+# PROGRAMS
+# ----------------------------------------------------
+
+# ----------------------------------------------------
+# Targets
+# ----------------------------------------------------
+tests debug opt:
+
+clean:
+ rm -f $(TARGET_FILES)
+ rm -f errs core *~
+
+docs:
+
+# ----------------------------------------------------
+# Special Targets
+# ----------------------------------------------------
+
+
+# ----------------------------------------------------
+# Release Targets
+# ----------------------------------------------------
+include $(ERL_TOP)/make/otp_release_targets.mk
+
+release_spec:
+
+release_docs_spec:
+
+release_tests_spec: tests
+ $(INSTALL_DIR) $(RELSYSDIR)
+ $(INSTALL_DATA) $(TEST_SPEC_FILE) $(ERL_FILES) $(RELSYSDIR)
+ @tar cf - *_SUITE_data | (cd $(RELSYSDIR); tar xf -)
diff --git a/lib/jinterface/test/jinterface.dynspec b/lib/jinterface/test/jinterface.dynspec
new file mode 100644
index 0000000000..44712521df
--- /dev/null
+++ b/lib/jinterface/test/jinterface.dynspec
@@ -0,0 +1,32 @@
+%% -*- erlang -*-
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 2006-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%
+%%
+%% You can test this file using this command.
+%% file:script("jinterface.dynspec", [{'Os',"Unix"}]).
+
+case case code:priv_dir(jinterface) of
+ {error,bad_name} -> false;
+ P -> filelib:is_dir(P) end of
+ true ->
+ [];
+ false ->
+ NoApp = "No jinterface application",
+ [{skip,{nc_SUITE,NoApp}},
+ {skip,{jinterface_SUITE,NoApp}}]
+end.
diff --git a/lib/jinterface/test/jinterface_SUITE.erl b/lib/jinterface/test/jinterface_SUITE.erl
new file mode 100644
index 0000000000..ea097680dd
--- /dev/null
+++ b/lib/jinterface/test/jinterface_SUITE.erl
@@ -0,0 +1,761 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 2004-2010. All Rights Reserved.
+%%
+%% The contents of this file are subject to the Erlang Public License,
+%% Version 1.1, (the "License"); you may not use this file except in
+%% compliance with the License. You should have received a copy of the
+%% Erlang Public License along with this software. If not, it can be
+%% retrieved online at http://www.erlang.org/.
+%%
+%% Software distributed under the License is distributed on an "AS IS"
+%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+%% the License for the specific language governing rights and limitations
+%% under the License.
+%%
+%% %CopyrightEnd%
+%%
+-module(jinterface_SUITE).
+
+-export([all/1, init_per_suite/1, end_per_suite/1,
+ init_per_testcase/2, end_per_testcase/2]).
+
+-export([nodename/1, register_and_whereis/1, get_names/1, boolean_atom/1,
+ node_ping/1, mbox_ping/1,
+ java_erlang_send_receive/1,
+ java_internal_send_receive_same_node/1,
+ java_internal_send_receive_different_nodes/1,
+ java_internal_send_receive_self/1,
+ java_link_and_exit/1, erl_link_and_exit/1,
+ erl_link_java_exit/1, java_link_erl_exit/1,
+ internal_link_linking_exits/1, internal_link_linked_exits/1,
+ internal_unlink_linking_exits/1, internal_unlink_linked_exits/1,
+ normal_exit/1, kill_mbox/1, kill_erl_proc_from_java/1,
+ kill_mbox_from_erlang/1, erl_exit_with_reason_any_term/1,
+ java_exit_with_reason_any_term/1,
+ status_handler_localStatus/1, status_handler_remoteStatus/1,
+ status_handler_connAttempt/1]).
+
+-include("test_server.hrl").
+-include("test_server_line.hrl").
+
+-define(debug,true).
+-ifdef(debug).
+-define(dbg(Str,Args), io:format(Str,Args)).
+-else.
+-define(dbg(Str,Args), ok).
+-endif.
+
+-define(link_test_reason,link_test_reason).
+
+%% Test cases in MboxSendReceive.java
+-define(java_erlang_send_receive,1).
+-define(java_internal_send_receive_same_node,2).
+-define(java_internal_send_receive_different_nodes,3).
+-define(java_internal_send_receive_self,4).
+
+%% Test cases in MboxLinkUnlink.java
+-define(java_link_and_exit, 1).
+-define(erl_link_and_exit, 2).
+-define(erl_link_java_exit, 3).
+-define(java_link_erl_exit, 4).
+-define(internal_link_linking_exits, 5).
+-define(internal_link_linked_exits, 6).
+-define(internal_unlink_linking_exits,7).
+-define(internal_unlink_linked_exits,8).
+-define(normal_exit,9).
+-define(kill_mbox,10).
+-define(kill_erl_proc_from_java,11).
+-define(kill_mbox_from_erlang,12).
+-define(erl_exit_with_reason_any_term,13).
+-define(java_exit_with_reason_any_term,14).
+
+
+%% Test cases in NodeStatusHandler.java
+-define(status_handler_localStatus,1).
+-define(status_handler_remoteStatus,2).
+-define(status_handler_connAttempt,3).
+
+%%%-----------------------------------------------------------------
+%%% INIT/END
+%%%-----------------------------------------------------------------
+all(suite) ->
+ lists:append([
+ fundamental(),
+ ping(),
+ send_receive(),
+ link_unlink(),
+ status_handler()
+ ]).
+
+fundamental() ->
+ [
+ nodename, % Nodename.java
+ register_and_whereis, % RegisterAndWhereis.java
+ get_names, % GetNames.java
+ boolean_atom % BooleanAtom.java
+ ].
+
+ping() ->
+ [
+ %% Implemented in NodePing.java
+ node_ping,
+
+ %% Implemented in MboxPing.java
+ mbox_ping
+ ].
+
+
+send_receive() ->
+ [
+ %% Implemented in MboxSendReceive.java
+ java_erlang_send_receive,
+ java_internal_send_receive_same_node,
+ java_internal_send_receive_different_nodes,
+ java_internal_send_receive_self
+ ].
+
+%% Note:
+%%
+%% The test cases in MboxLinkUnlink.java and in
+%% NodePing.java, all uses default cookie, and if there
+%% is a problem with having the same default cookie in
+%% erlang vs jinterface, e.g because the home directory
+%% does not get the same in some cases on Windows
+%% - they will all fail.
+
+link_unlink() ->
+ [
+ %% Implemented in MboxLinkUnlink.java
+ java_link_and_exit,
+ erl_link_and_exit,
+ erl_link_java_exit,
+ java_link_erl_exit,
+ internal_link_linking_exits,
+ internal_link_linked_exits,
+ internal_unlink_linking_exits,
+ internal_unlink_linked_exits,
+ normal_exit,
+ kill_mbox,
+ kill_erl_proc_from_java,
+ kill_mbox_from_erlang,
+ erl_exit_with_reason_any_term,
+ java_exit_with_reason_any_term
+ ].
+
+status_handler() ->
+ [
+ %% Implemented in NodeStatusHandler.java
+ status_handler_localStatus,
+ status_handler_remoteStatus,
+ status_handler_connAttempt
+ ].
+
+
+init_per_suite(Config) when is_list(Config) ->
+ jitu:init_all(Config).
+
+end_per_suite(Config) when is_list(Config) ->
+ jitu:finish_all(Config).
+
+init_per_testcase(_Case,Config) ->
+ Dog = ?t:timetrap({seconds,10}),
+ [{watch_dog,Dog}|Config].
+
+end_per_testcase(_Case,Config) ->
+ ?t:timetrap_cancel(?config(watch_dog,Config)),
+ ok.
+
+
+%%%-----------------------------------------------------------------
+%%% TEST CASES
+%%%-----------------------------------------------------------------
+nodename(doc) ->
+ ["Nodename.java: "
+ "Test OtpNode.node(), OtpNode.alive() and OtpNode.host()"];
+nodename(suite) ->
+ [];
+nodename(Config) when is_list(Config) ->
+ [_,Host] = string:tokens(atom_to_list(node()),"@"),
+ ok = jitu:java(?config(java, Config),
+ ?config(data_dir, Config),
+ "Nodename",
+ [list_to_atom(Host)]).
+
+%%%-----------------------------------------------------------------
+register_and_whereis(doc) ->
+ ["RegisterAndWhereis.java: "
+ "Test OtpNode.registerName(...), OtpMbox.registerName(...) and "
+ "OtpNode.whereis(...)"];
+register_and_whereis(suite) ->
+ [];
+register_and_whereis(Config) when is_list(Config) ->
+ ok = jitu:java(?config(java, Config),
+ ?config(data_dir, Config),
+ "RegisterAndWhereis",
+ []).
+
+%%%-----------------------------------------------------------------
+get_names(doc) ->
+ ["GetNames.java: "
+ "Test OtpNode.getNames()"];
+get_names(suite) ->
+ [];
+get_names(Config) when is_list(Config) ->
+ ok = jitu:java(?config(java, Config),
+ ?config(data_dir, Config),
+ "GetNames",
+ []).
+
+%%%-----------------------------------------------------------------
+boolean_atom(doc) ->
+ ["BooleanAtom.java: "
+ "Test OtpErlangAtom.booleanValue()"];
+boolean_atom(suite) ->
+ [];
+boolean_atom(Config) when is_list(Config) ->
+ ok = jitu:java(?config(java, Config),
+ ?config(data_dir, Config),
+ "BooleanAtom",
+ []).
+
+%%%-----------------------------------------------------------------
+node_ping(doc) ->
+ ["NodePing.java: "
+ "Test OtpNode.ping(java.lang.String node, long timeout)"];
+node_ping(suite) ->
+ [];
+node_ping(Config) when is_list(Config) ->
+ ok = jitu:java(?config(java, Config),
+ ?config(data_dir, Config),
+ "NodePing",
+ [erlang:get_cookie(),node()]).
+
+%%%-----------------------------------------------------------------
+mbox_ping(doc) ->
+ ["MboxPing.java: "
+ "Test OtpNode.createMbox(...) and OtpMbox.ping(...)"];
+mbox_ping(suite) ->
+ [];
+mbox_ping(Config) when is_list(Config) ->
+ ok = jitu:java(?config(java, Config),
+ ?config(data_dir, Config),
+ "MboxPing",
+ [erlang:get_cookie(),node()]).
+
+%%%-----------------------------------------------------------------
+java_erlang_send_receive(doc) ->
+ ["Test sending/receiving of erlang messages between erlang and java"];
+java_erlang_send_receive(suite) ->
+ [];
+java_erlang_send_receive(Config) when is_list(Config) ->
+ send_receive(?java_erlang_send_receive, fun echo_loop/0, Config).
+
+echo_loop() ->
+ receive
+ {From,Msg} ->
+ ?dbg("erl_send_receive_server received ~p",[{From,Msg}]),
+ ?dbg("erl_send_receive_server sending ~p",[Msg]),
+ From ! Msg,
+ echo_loop();
+ done ->
+ ok
+ end.
+
+
+%%%-----------------------------------------------------------------
+java_internal_send_receive_same_node(doc) ->
+ ["MboxSendReceive.java: "
+ "Test sending/receiving of erlang messages between mboxes "
+ "on the same java node."];
+java_internal_send_receive_same_node(suite) ->
+ [];
+java_internal_send_receive_same_node(Config) when is_list(Config) ->
+ send_receive(?java_internal_send_receive_same_node,
+ fun() -> receive done -> ok end end,
+ Config).
+
+%%%-----------------------------------------------------------------
+java_internal_send_receive_different_nodes(doc) ->
+ ["MboxSendReceive.java: "
+ "Test sending/receiving of erlang messages between mboxes "
+ "on different java nodes."];
+java_internal_send_receive_different_nodes(suite) ->
+ [];
+java_internal_send_receive_different_nodes(Config) when is_list(Config) ->
+ send_receive(?java_internal_send_receive_different_nodes,
+ fun() -> receive done -> ok end end,
+ Config).
+
+%%%-----------------------------------------------------------------
+java_internal_send_receive_self(doc) ->
+ ["MboxSendReceive.java: "
+ "Test sending/receiving of erlang messages from an mbox to itself"];
+java_internal_send_receive_self(suite) ->
+ [];
+java_internal_send_receive_self(Config) when is_list(Config) ->
+ send_receive(?java_internal_send_receive_self,
+ fun() -> receive done -> ok end end,
+ Config).
+
+%%%-----------------------------------------------------------------
+java_link_and_exit(doc) ->
+ ["MboxLinkUnlink.java: "
+ "Test link between erlang process and java mailbox."
+ "Java mailbox links and exits"];
+java_link_and_exit(suite) ->
+ [];
+java_link_and_exit(Config) when is_list(Config) ->
+ LinkFun =
+ fun(Mbox) ->
+ Mbox ! {?java_link_and_exit,self(),?link_test_reason},
+ receive after infinity -> ok end
+ end,
+ erl_java_link(LinkFun,java_link_and_exit,Config).
+
+
+%%%-----------------------------------------------------------------
+erl_link_and_exit(doc) ->
+ ["MboxLinkUnlink.java: "
+ "Test link between erlang process and java mailbox."
+ "Erlang process links and exits"];
+erl_link_and_exit(suite) ->
+ [];
+erl_link_and_exit(Config) when is_list(Config) ->
+ LinkFun = fun(Mbox) ->
+ link(Mbox),
+ Mbox ! {?erl_link_and_exit,self(),?link_test_reason},
+ receive ok -> ok end,
+ exit(?link_test_reason)
+ end,
+ erl_java_link(LinkFun,erl_link_and_exit,Config).
+
+%%%-----------------------------------------------------------------
+erl_link_java_exit(doc) ->
+ ["MboxLinkUnlink.java: "
+ "Test link between erlang process and java mailbox."
+ "Erlang process links and java mailbox exits"];
+erl_link_java_exit(suite) ->
+ [];
+erl_link_java_exit(Config) when is_list(Config) ->
+ LinkFun = fun(Mbox) ->
+ link(Mbox),
+ Mbox ! {?erl_link_java_exit,self(),?link_test_reason},
+ receive after infinity -> ok end
+ end,
+ erl_java_link(LinkFun,erl_link_java_exit,Config).
+
+
+%%%-----------------------------------------------------------------
+java_link_erl_exit(doc) ->
+ ["MboxLinkUnlink.java: "
+ "Test link between erlang process and java mailbox."
+ "Java mailbox links and erlang process exits"];
+java_link_erl_exit(suite) ->
+ [];
+java_link_erl_exit(Config) when is_list(Config) ->
+ LinkFun =
+ fun(Mbox) ->
+ Mbox ! {?java_link_erl_exit,self(),?link_test_reason},
+ receive ok -> ok end,
+ exit(?link_test_reason)
+ end,
+ erl_java_link(LinkFun,java_link_erl_exit,Config).
+
+%%%-----------------------------------------------------------------
+internal_link_linking_exits(doc) ->
+ ["MboxLinkUnlink.java: "
+ "Test link between two java mailboxes."
+ "The mailbox which creates the link is the one exiting"];
+internal_link_linking_exits(suite) ->
+ [];
+internal_link_linking_exits(Config) when is_list(Config) ->
+ internal_link_unlink(?internal_link_linking_exits,
+ internal_link_linking_exits,
+ Config).
+
+%%%-----------------------------------------------------------------
+internal_link_linked_exits(doc) ->
+ ["MboxLinkUnlink.java: "
+ "Test link between two java mailboxes."
+ "The mailbox which dies not create the link is the one exiting"];
+internal_link_linked_exits(suite) ->
+ [];
+internal_link_linked_exits(Config) when is_list(Config) ->
+ internal_link_unlink(?internal_link_linked_exits,
+ internal_link_linked_exits,
+ Config).
+
+%%%-----------------------------------------------------------------
+internal_unlink_linking_exits(doc) ->
+ ["MboxLinkUnlink.java: "
+ "Test link and unlink between two java mailboxes. "
+ "Mailbox1 creates a link to mailbox2 and removes it. "
+ "Then it creates another link and mailbox2 removes is. "
+ "Finally mailbox1 exits - mailbox2 must survive"];
+internal_unlink_linking_exits(suite) ->
+ [];
+internal_unlink_linking_exits(Config) when is_list(Config) ->
+ internal_link_unlink(?internal_unlink_linking_exits,
+ internal_unlink_linking_exits,
+ Config).
+
+%%%-----------------------------------------------------------------
+internal_unlink_linked_exits(doc) ->
+ ["MboxLinkUnlink.java: "
+ "Test link and unlink between two java mailboxes. "
+ "Mailbox1 creates a link to mailbox2 and removes it. "
+ "Then it creates another link and mailbox2 removes is. "
+ "Finally mailbox2 exits - mailbox1 must survive"];
+internal_unlink_linked_exits(suite) ->
+ [];
+internal_unlink_linked_exits(Config) when is_list(Config) ->
+ internal_link_unlink(?internal_unlink_linked_exits,
+ internal_unlink_linked_exits,
+ Config).
+
+%%%-----------------------------------------------------------------
+normal_exit(doc) ->
+ ["MboxLinkUnlink.java: "
+ "Test that mbox.close() uses exit reason 'normal', i.e. "
+ "that linked processes are not terminated."];
+normal_exit(suite) ->
+ [];
+normal_exit(Config) when is_list(Config) ->
+ Fun =
+ fun() ->
+ register(erl_link_server,self()),
+ process_flag(trap_exit,true),
+ receive
+ {Main,Mbox} when is_pid(Main), is_pid(Mbox) ->
+ ?dbg("Erlang sending \"~p\"",[normal_exit]),
+ link(Mbox),
+ Pid = spawn_link(fun() ->
+ link(Mbox),
+ Mbox ! {?normal_exit},
+ receive after infinity -> ok end
+ end),
+ receive
+ {'EXIT',Mbox,normal} ->
+ %% Make sure that we don't get the
+ %% exit signal from Pid, and Pid
+ %% should still be alive.
+ receive
+ {'EXIT',Pid,Reason} ->
+ ?dbg("Got unexpected exit signal: ~p",
+ [{'EXIT',Pid,Reason}]),
+ exit({unexpected,{'EXIT',Pid,Reason}})
+ after 500 ->
+ true = erlang:is_process_alive(Pid),
+ exit(Pid,kill)
+ end,
+ receive done -> Main ! done end
+ after 1000 ->
+ receive
+ Other ->
+ ?dbg("Got garbage when waiting for exit:"
+ " ~p", [Other]),
+ Main ! done,
+ exit({got_unexpected,Other})
+ after 0 ->
+ ok
+ end
+ end;
+ Other ->
+ ?dbg("Got garbage: ~p",[Other]),
+ exit(Other)
+ end
+ end,
+
+ spawn_link(Fun),
+ ok = jitu:java(?config(java, Config),
+ ?config(data_dir, Config),
+ "MboxLinkUnlink",
+ [erlang:get_cookie(),node()]).
+
+
+%%%-----------------------------------------------------------------
+kill_mbox(doc) ->
+ ["MboxLinkUnlink.java: "
+ "Test that mbox.exit(new OtpErlangAtom(\"kill\") causes linked "
+ "processes to exit with reason 'killed', which can be trapped."];
+kill_mbox(suite) ->
+ {skip, "Not yet implemented"};
+kill_mbox(Config) when is_list(Config) ->
+ Fun =
+ fun() ->
+ register(erl_link_server,self()),
+ process_flag(trap_exit,true),
+ receive
+ {Main,Mbox} when is_pid(Main), is_pid(Mbox) ->
+ ?dbg("Erlang sending \"~p\"",[kill_mbox]),
+ Pid = spawn_link(fun() ->
+ process_flag(trap_exit,true),
+ link(Mbox),
+ Mbox ! {?kill_mbox},
+ receive
+ {'EXIT',Mbox,killed} ->
+ exit(correct_reason);
+ {'EXIT',Mbox,R} ->
+ exit({faulty_reason,R})
+ end
+ end),
+ receive
+ {'EXIT',Pid,{faulty_reason,Reason}} ->
+ receive done -> Main ! done end,
+ exit({faulty_reason,Reason});
+ {'EXIT',Pid,im_killed} ->
+ receive done -> Main ! done end
+ after 1000 ->
+ receive
+ Other ->
+ ?dbg("Got garbage when waiting for exit:"
+ " ~p", [Other]),
+ Main ! done,
+ exit({got_unexpected,Other})
+ after 0 ->
+ ok
+ end
+ end;
+ Other ->
+ ?dbg("Got garbage: ~p",[Other]),
+ exit(Other)
+ end
+ end,
+
+ spawn_link(Fun),
+ ok = jitu:java(?config(java, Config),
+ ?config(data_dir, Config),
+ "MboxLinkUnlink",
+ [erlang:get_cookie(),node()]).
+
+%%%-----------------------------------------------------------------
+kill_erl_proc_from_java(doc) ->
+ ["MboxLinkUnlink.java: "
+ "Test that mbox.exit(pid, new OtpErlangAtom(\"kill\") causes erlang "
+ "processes <pid> to be killed, even if trapping exits"];
+kill_erl_proc_from_java(suite) ->
+ [];
+kill_erl_proc_from_java(Config) when is_list(Config) ->
+ LinkFun = fun(Mbox) ->
+ process_flag(trap_exit,true),
+ link(Mbox),
+ Mbox ! {?kill_erl_proc_from_java, self()},
+ receive after infinity -> ok end
+ end,
+ erl_java_link(LinkFun,kill_erl_proc_from_java,killed,Config).
+
+%%%-----------------------------------------------------------------
+kill_mbox_from_erlang(doc) ->
+ ["MboxLinkUnlink.java: "
+ "Test that exit(Mbox,kill) causes linked the Mbox to be killed, and"
+ "linked processes to exit with reason 'killed', even if trapping exits"];
+kill_mbox_from_erlang(suite) ->
+ {skip, "Not yet implemented"};
+kill_mbox_from_erlang(Config) when is_list(Config) ->
+ LinkFun = fun(Mbox) ->
+ link(Mbox),
+ Mbox ! {?kill_mbox_from_erlang},
+ exit(Mbox,kill),
+ receive after infinity -> ok end
+ end,
+ erl_java_link(LinkFun,kill_mbox_from_erlang,killed,Config).
+
+%%%-----------------------------------------------------------------
+erl_exit_with_reason_any_term(doc) ->
+ ["MboxLinkUnlink.java: "
+ "Test that any erlang term can be used as exit reason when erlang "
+ "process exits and is linked to an mbox."];
+erl_exit_with_reason_any_term(suite) ->
+ [];
+erl_exit_with_reason_any_term(Config) when is_list(Config) ->
+ Reason = [hei,self(),{this,is,"a",[different,"reason"]}],
+ LinkFun = fun(Mbox) ->
+ link(Mbox),
+ Mbox ! {?erl_exit_with_reason_any_term,self(),Reason},
+ receive ok -> ok end,
+ exit(Reason)
+ end,
+ erl_java_link(LinkFun,erl_exit_with_reason_any_term,Reason,Config).
+
+%%%-----------------------------------------------------------------
+java_exit_with_reason_any_term(doc) ->
+ ["MboxLinkUnlink.java: "
+ "Test that any erlang term can be used as exit reason when mbox "
+ "exits and is linked to an erlang process."];
+java_exit_with_reason_any_term(suite) ->
+ [];
+java_exit_with_reason_any_term(Config) when is_list(Config) ->
+ Reason = [hei,self(),{this,is,"a",[different,"reason"]}],
+ LinkFun =
+ fun(Mbox) ->
+ Mbox ! {?java_exit_with_reason_any_term,self(),Reason},
+ receive after infinity -> ok end
+ end,
+ erl_java_link(LinkFun,java_exit_with_reason_any_term,Reason,Config).
+
+
+%%%-----------------------------------------------------------------
+status_handler_localStatus(doc) ->
+ ["NodeStatusHandler.java: "
+ "Test OtpNode.registerStatusHandler(...) and the callback "
+ "OtpNodeStatus.localStatus(...)"];
+status_handler_localStatus(suite) ->
+ [];
+status_handler_localStatus(Config) when is_list(Config) ->
+ spawn_link(fun() ->
+ erl_status_server([{opt,{localStatus,"javanode1",true}},
+ {localStatus,"javanode1",false}])
+ end),
+ ok = jitu:java(?config(java, Config),
+ ?config(data_dir, Config),
+ "NodeStatusHandler",
+ [erlang:get_cookie(),node(),?status_handler_localStatus]).
+
+%%%-----------------------------------------------------------------
+status_handler_remoteStatus(doc) ->
+ ["NodeStatusHandler.java: "
+ "Test OtpNode.registerStatusHandler(...) and the callback "
+ "OtpNodeStatus.remoteStatus(...)"];
+status_handler_remoteStatus(suite) ->
+ [];
+status_handler_remoteStatus(Config) when is_list(Config) ->
+ spawn_link(fun() ->
+ erl_status_server([{opt,{localStatus,"javanode1",true}},
+ {remoteStatus,"javanode2",true},
+ {remoteStatus,"javanode2",false}])
+ end),
+ ok = jitu:java(?config(java, Config),
+ ?config(data_dir, Config),
+ "NodeStatusHandler",
+ [erlang:get_cookie(),node(),?status_handler_remoteStatus]).
+
+
+%%%-----------------------------------------------------------------
+status_handler_connAttempt(doc) ->
+ ["NodeStatusHandler.java: "
+ "Test OtpNode.registerStatusHandler(...) and the callback "
+ "OtpNodeStatus.connAttempt(...)"];
+status_handler_connAttempt(suite) ->
+ [];
+status_handler_connAttempt(Config) when is_list(Config) ->
+ spawn_link(fun() ->
+ erl_status_server([{opt,{localStatus,"javanode1",true}},
+ {connAttempt,"unknown",true},
+ {connAttempt,"javanode3",false}])
+ end),
+ ok = jitu:java(?config(java, Config),
+ ?config(data_dir, Config),
+ "NodeStatusHandler",
+ [erlang:get_cookie(),node(),?status_handler_connAttempt]).
+
+
+%%%-----------------------------------------------------------------
+%%% INTERNAL FUNCTIONS
+%%%-----------------------------------------------------------------
+send_receive(TestCaseTag,Fun,Config) ->
+ spawn(fun() ->
+ register(erl_send_receive_server,self()),
+ receive
+ From when is_pid(From) ->
+ JavaNode = node(From),
+ [JavaNode] = nodes(hidden),
+ From ! {TestCaseTag,self()},
+ Fun(),
+ unregister(erl_send_receive_server)
+ end
+ end),
+ ok = jitu:java(?config(java, Config),
+ ?config(data_dir, Config),
+ "MboxSendReceive",
+ [erlang:get_cookie(),node()]).
+
+
+internal_link_unlink(Tag,Msg,Config) ->
+ Fun =
+ fun() ->
+ register(erl_link_server,self()),
+ process_flag(trap_exit,true),
+ receive
+ {Main,Mbox} when is_pid(Main), is_pid(Mbox) ->
+ ?dbg("Erlang sending \"~p\"",[Msg]),
+ Mbox ! {Tag,self(),?link_test_reason},
+ receive done -> Main ! done end;
+ Other ->
+ ?dbg("Got garbage: ~p",[Other]),
+ exit(Other)
+ end
+ end,
+
+ spawn_link(Fun),
+ ok = jitu:java(?config(java, Config),
+ ?config(data_dir, Config),
+ "MboxLinkUnlink",
+ [erlang:get_cookie(),node()]).
+
+
+erl_java_link(LinkFun,Msg,Config) ->
+ erl_java_link(LinkFun,Msg,?link_test_reason,Config).
+
+erl_java_link(LinkFun,Msg,Reason,Config) ->
+ Fun =
+ fun() ->
+ register(erl_link_server,self()),
+ process_flag(trap_exit,true),
+ receive
+ {Main,Mbox} when is_pid(Mbox), is_pid(Mbox) ->
+ ?dbg("Erlang sending \"~p\"",[Msg]),
+ Pid = spawn_link(fun() -> LinkFun(Mbox) end),
+ receive
+ {'EXIT',Pid,Reason} ->
+ receive done -> Main ! done end
+ after 1000 ->
+ receive
+ Other ->
+ ?dbg("Got garbage when waiting for exit:"
+ " ~p", [Other]),
+ Main ! done,
+ exit({got_unexpected,Other})
+ after 0 ->
+ ok
+ end
+ end;
+ Other ->
+ ?dbg("Got garbage: ~p",[Other]),
+ exit(Other)
+ end
+ end,
+
+ spawn_link(Fun),
+ ok = jitu:java(?config(java, Config),
+ ?config(data_dir, Config),
+ "MboxLinkUnlink",
+ [erlang:get_cookie(),node()]).
+
+erl_status_server(List) ->
+ register(erl_status_server,self()),
+ erl_status_server(List,undefined).
+erl_status_server([{opt,{Tag,NodeName,Up}},{Tag2,NodeName2,Up2}|Rest],_) ->
+ receive
+ {Tag,Node,Up,From} = M ->
+ ?dbg("erl_status_server got: ~p",[M]),
+ true = lists:prefix(NodeName,Node),
+ erl_status_server([{Tag2,NodeName2,Up2}|Rest],From);
+ {Tag2,Node2,Up2,From2} = M2 ->
+ ?dbg("erl_status_server got: ~p",[M2]),
+ true = lists:prefix(NodeName2,Node2),
+ erl_status_server(Rest,From2)
+ end;
+erl_status_server([{Tag,NodeName,Up}|Rest],_) ->
+ receive
+ {Tag,Node,Up,From} = M ->
+ ?dbg("erl_status_server got: ~p",[M]),
+ true = lists:prefix(NodeName,Node),
+ erl_status_server(Rest,From);
+ Other ->
+ ?dbg("erl_status_server got garbage: ~p",[Other]),
+ exit(Other)
+ end;
+erl_status_server([],From) ->
+ From ! done.
diff --git a/lib/jinterface/test/jinterface_SUITE_data/BooleanAtom.java b/lib/jinterface/test/jinterface_SUITE_data/BooleanAtom.java
new file mode 100644
index 0000000000..9554d50c9f
--- /dev/null
+++ b/lib/jinterface/test/jinterface_SUITE_data/BooleanAtom.java
@@ -0,0 +1,46 @@
+/*
+ * %CopyrightBegin%
+ *
+ * Copyright Ericsson AB 2004-2010. All Rights Reserved.
+ *
+ * The contents of this file are subject to the Erlang Public License,
+ * Version 1.1, (the "License"); you may not use this file except in
+ * compliance with the License. You should have received a copy of the
+ * Erlang Public License along with this software. If not, it can be
+ * retrieved online at http://www.erlang.org/.
+ *
+ * Software distributed under the License is distributed on an "AS IS"
+ * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+ * the License for the specific language governing rights and limitations
+ * under the License.
+ *
+ * %CopyrightEnd%
+ */
+
+import com.ericsson.otp.erlang.*;
+
+class BooleanAtom {
+
+ /*
+ Implements test case jinterface_SUITE:boolean_atom/1
+
+ Test the function OtpErlangAtom.booleanValue()
+ */
+
+ public static void main(String argv[]) {
+
+ OtpErlangAtom atom = new OtpErlangAtom("true");
+ if (!atom.booleanValue()) fail(1);
+
+ atom = new OtpErlangAtom("false");
+ if (atom.booleanValue()) fail(2);
+
+ atom = new OtpErlangAtom("somethingelse");
+ if (atom.booleanValue()) fail(3);
+
+ }
+
+ private static void fail(int reason) {
+ System.exit(reason);
+ }
+}
diff --git a/lib/jinterface/test/jinterface_SUITE_data/GetNames.java b/lib/jinterface/test/jinterface_SUITE_data/GetNames.java
new file mode 100644
index 0000000000..3d2bc4ac84
--- /dev/null
+++ b/lib/jinterface/test/jinterface_SUITE_data/GetNames.java
@@ -0,0 +1,68 @@
+/*
+ * %CopyrightBegin%
+ *
+ * Copyright Ericsson AB 2004-2010. All Rights Reserved.
+ *
+ * The contents of this file are subject to the Erlang Public License,
+ * Version 1.1, (the "License"); you may not use this file except in
+ * compliance with the License. You should have received a copy of the
+ * Erlang Public License along with this software. If not, it can be
+ * retrieved online at http://www.erlang.org/.
+ *
+ * Software distributed under the License is distributed on an "AS IS"
+ * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+ * the License for the specific language governing rights and limitations
+ * under the License.
+ *
+ * %CopyrightEnd%
+ */
+
+import java.util.ArrayList;
+import com.ericsson.otp.erlang.*;
+
+class GetNames {
+
+ /*
+ Implements test case jinterface_SUITE:get_names/1
+
+ */
+
+ public static void main(String argv[]) {
+
+ try {
+ OtpNode node = new OtpNode("javanode");
+ OtpMbox mbox1 = node.createMbox();
+ mbox1.registerName("mbox1");
+ node.createMbox("mbox2");
+ OtpMbox mbox3 = node.createMbox();
+ node.registerName("mbox3",mbox3);
+
+ ArrayList existing_names = new ArrayList();
+ existing_names.add("mbox3");
+ existing_names.add("mbox2");
+ existing_names.add("mbox1");
+
+ String[] names = node.getNames();
+ if (names.length != existing_names.size()) fail(1);
+
+ for(int i=0; i<names.length; i++) {
+ System.out.println("" + names[i]);
+ existing_names.remove(names[i]);
+ }
+
+ if (!existing_names.isEmpty()) fail(2);
+ }
+ catch (Exception e) {
+ fail("" + e, 3);
+ }
+ }
+
+ private static void fail(int reason) {
+ System.exit(reason);
+ }
+
+ private static void fail(String str, int reason) {
+ System.out.println(str);
+ System.exit(reason);
+ }
+}
diff --git a/lib/jinterface/test/jinterface_SUITE_data/Makefile.src b/lib/jinterface/test/jinterface_SUITE_data/Makefile.src
new file mode 100644
index 0000000000..2a3dca463b
--- /dev/null
+++ b/lib/jinterface/test/jinterface_SUITE_data/Makefile.src
@@ -0,0 +1,62 @@
+#
+# %CopyrightBegin%
+#
+# Copyright Ericsson AB 2004-2010. All Rights Reserved.
+#
+# The contents of this file are subject to the Erlang Public License,
+# Version 1.1, (the "License"); you may not use this file except in
+# compliance with the License. You should have received a copy of the
+# Erlang Public License along with this software. If not, it can be
+# retrieved online at http://www.erlang.org/.
+#
+# Software distributed under the License is distributed on an "AS IS"
+# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+# the License for the specific language governing rights and limitations
+# under the License.
+#
+# %CopyrightEnd%
+#
+
+# Note: This file *must* work for both Unix and Windows
+#
+# We use both `rm' (Unix) and `del' (Windows) for removing files, but
+# with a `-' in front so that the error in not finding `rm' (`del') on
+# Windows (Unix) is ignored.
+#
+# VxWorks? XXX
+#
+
+.SUFFIXES:
+.SUFFIXES: .java
+
+
+JAVAC = @JAVAC@
+ERLC = erlc
+
+JINTERFACE_CLASSPATH = @jinterface_classpath@
+
+CLASSPATH = .@PS@$(JINTERFACE_CLASSPATH)@PS@
+
+JAVA_FILES = \
+ Nodename.java \
+ RegisterAndWhereis.java \
+ GetNames.java \
+ BooleanAtom.java \
+ NodePing.java \
+ MboxPing.java \
+ MboxSendReceive.java \
+ MboxLinkUnlink.java \
+ NodeStatusHandler.java
+
+CLASS_FILES = $(JAVA_FILES:.java=.class)
+
+all: $(CLASS_FILES)
+
+clean:
+ -rm -f $(CLASS_FILES)
+ -del /F /Q $(CLASS_FILES)
+
+$(CLASS_FILES) : $(JAVA_FILES)
+ $(JAVAC) -classpath $(CLASSPATH) $(JAVA_FILES)
+
+#
diff --git a/lib/jinterface/test/jinterface_SUITE_data/MboxLinkUnlink.java b/lib/jinterface/test/jinterface_SUITE_data/MboxLinkUnlink.java
new file mode 100644
index 0000000000..5d1d097cc8
--- /dev/null
+++ b/lib/jinterface/test/jinterface_SUITE_data/MboxLinkUnlink.java
@@ -0,0 +1,201 @@
+/*
+ * %CopyrightBegin%
+ *
+ * Copyright Ericsson AB 2004-2010. All Rights Reserved.
+ *
+ * The contents of this file are subject to the Erlang Public License,
+ * Version 1.1, (the "License"); you may not use this file except in
+ * compliance with the License. You should have received a copy of the
+ * Erlang Public License along with this software. If not, it can be
+ * retrieved online at http://www.erlang.org/.
+ *
+ * Software distributed under the License is distributed on an "AS IS"
+ * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+ * the License for the specific language governing rights and limitations
+ * under the License.
+ *
+ * %CopyrightEnd%
+ */
+
+import com.ericsson.otp.erlang.*;
+
+class MboxLinkUnlink {
+
+ /*
+ Implements test case jinterface_SUITE:mbox_link_unlink/1
+
+
+
+ */
+
+ private static final int java_link_and_exit = 1;
+ private static final int erl_link_and_exit = 2;
+ private static final int erl_link_java_exit = 3;
+ private static final int java_link_erl_exit = 4;
+ private static final int internal_link_linking_exits = 5;
+ private static final int internal_link_linked_exits = 6;
+ private static final int internal_unlink_linking_exits = 7;
+ private static final int internal_unlink_linked_exits = 8;
+ private static final int normal_exit = 9;
+ private static final int kill_mbox = 10;
+ private static final int kill_erl_proc_from_java = 11;
+ private static final int kill_mbox_from_erlang = 12;
+ private static final int erl_exit_with_reason_any_term = 13;
+ private static final int java_exit_with_reason_any_term = 14;
+
+ private static boolean dbg = true;
+
+
+ public static void main(String argv[]) {
+
+
+ //String cookie = argv[0];
+ String erlNode = argv[1];
+ OtpErlangObject expected = null;
+ boolean waiting = false;
+
+ try { //
+ OtpNode node = new OtpNode("javanode");
+ OtpMbox mainMbox = node.createMbox();
+
+ try {
+ // Initiate and set up connection to erlang process
+ OtpMbox mbox = node.createMbox();
+ OtpMbox mbox2;
+
+ OtpErlangObject[] msg = {mainMbox.self(),mbox.self()};
+ mbox.send("erl_link_server", erlNode, new OtpErlangTuple(msg));
+ OtpErlangObject o = mbox.receive(1000);
+ if (o == null) System.exit(1);
+ OtpErlangTuple tuple = (OtpErlangTuple)o;
+ int tag = (int)((OtpErlangLong)tuple.elementAt(0)).longValue();
+
+ switch (tag) {
+
+ case java_exit_with_reason_any_term:
+ case java_link_and_exit:
+ dbg("Java got \"java_link_and_exit\" or " +
+ "\"java_exit_with_reason_any_term\"");
+ mbox.link((OtpErlangPid)tuple.elementAt(1));
+ mbox.send((OtpErlangPid)tuple.elementAt(1),
+ new OtpErlangAtom("ok"));
+ mbox.exit(tuple.elementAt(2));
+ break;
+ case erl_exit_with_reason_any_term:
+ case erl_link_and_exit:
+ dbg("Java got \"erl_link_and_exit\" or " +
+ "\"erl_exit_with_reason_any_term\"");
+ mbox.send((OtpErlangPid)tuple.elementAt(1),
+ new OtpErlangAtom("ok"));
+ waiting = true;
+ expected = tuple.elementAt(2);
+ mbox.receive(1000);
+ System.exit(2);
+ case erl_link_java_exit:
+ dbg("Java got \"erl_link_java_exit\"");
+ mbox.exit(tuple.elementAt(2));
+ break;
+ case java_link_erl_exit:
+ dbg("Java got \"java_link_erl_exit\"");
+ mbox.link((OtpErlangPid)tuple.elementAt(1));
+ mbox.send((OtpErlangPid)tuple.elementAt(1),
+ new OtpErlangAtom("ok"));
+ waiting = true;
+ expected = tuple.elementAt(2);
+ mbox.receive(1000);
+ System.exit(3);
+ case internal_link_linking_exits:
+ dbg("Java got \"internal_link_linking_exits\"");
+ mbox2 = node.createMbox();
+ mbox.link(mbox2.self());
+ mbox.exit(tuple.elementAt(2));
+ waiting = true;
+ expected = tuple.elementAt(2);
+ mbox2.receive(1000); // hanging waiting for exit
+ System.exit(4); // got someting other than exit
+ case internal_link_linked_exits:
+ dbg("Java got \"internal_link_linked_exits\"");
+ mbox2 = node.createMbox();
+ mbox.link(mbox2.self());
+ mbox2.exit(tuple.elementAt(2));
+ waiting = true;
+ expected = tuple.elementAt(2);
+ mbox.receive(1000); // hanging waiting for exit
+ System.exit(5); // got someting other than exit
+ case internal_unlink_linking_exits:
+ dbg("Java got \"internal_unlink_linking_exits\"");
+ mbox2 = node.createMbox();
+ mbox.link(mbox2.self());
+ mbox.unlink(mbox2.self());
+ mbox.link(mbox2.self());
+ mbox2.unlink(mbox.self());
+ mbox2.exit(tuple.elementAt(2));
+ if (mbox.receive(500)!=null) System.exit(6);
+ break;
+ case internal_unlink_linked_exits:
+ dbg("Java got \"internal_unlink_linked_exits\"");
+ mbox2 = node.createMbox();
+ mbox.link(mbox2.self());
+ mbox.unlink(mbox2.self());
+ mbox.link(mbox2.self());
+ mbox2.unlink(mbox.self());
+ mbox.exit(tuple.elementAt(2));
+ if (mbox2.receive(500)!=null) System.exit(7);
+ break;
+ case normal_exit:
+ dbg("Java got \"normal_exit\"");
+ mbox.close();
+ break;
+ case kill_mbox:
+ dbg("Java got \"kill_mbox\"");
+ mbox.exit("kill");
+ break;
+ case kill_erl_proc_from_java:
+ dbg("Java got \"kill_erl_proc_from_java\"");
+ mbox.exit((OtpErlangPid)tuple.elementAt(1),"kill");
+ break;
+ case kill_mbox_from_erlang:
+ dbg("Java got \"kill_mbox_from_erlang\"");
+ /* This will make the testcase successful, but it is
+ not the correct way to do it...
+ Mbox should probably just die when the kill signal is
+ received from erlang (or other mbox).
+
+ try {
+ mbox.receive(1000);
+ System.exit(8);
+ }
+ catch (OtpErlangExit exit) {
+ if(!(exit.reason().equals(new OtpErlangAtom("kill"))))
+ System.exit(9);
+ mbox.exit("killed");
+ }
+ */
+ break;
+ }
+ }
+ catch (OtpErlangExit exit) {
+ dbg("Java got exit: " + exit.reason());
+ if(!(waiting && exit.reason().equals(expected)))
+ System.exit(10);
+ }
+
+ OtpErlangAtom done = new OtpErlangAtom("done");
+ mainMbox.send("erl_link_server", erlNode, done);
+ OtpErlangObject o = mainMbox.receive(1000);
+ if (o == null) System.exit(11);
+ else if (!((OtpErlangAtom)o).equals(done))
+ System.exit(12);
+
+ }
+ catch (Exception e) {
+ System.out.println("EXCEPTION: " + e);
+ System.exit(13);
+ }
+ }
+
+ private static void dbg(String str) {
+ if (dbg) System.out.println(str);
+ }
+
+}
diff --git a/lib/jinterface/test/jinterface_SUITE_data/MboxPing.java b/lib/jinterface/test/jinterface_SUITE_data/MboxPing.java
new file mode 100644
index 0000000000..3a8497028e
--- /dev/null
+++ b/lib/jinterface/test/jinterface_SUITE_data/MboxPing.java
@@ -0,0 +1,50 @@
+/*
+ * %CopyrightBegin%
+ *
+ * Copyright Ericsson AB 2004-2010. All Rights Reserved.
+ *
+ * The contents of this file are subject to the Erlang Public License,
+ * Version 1.1, (the "License"); you may not use this file except in
+ * compliance with the License. You should have received a copy of the
+ * Erlang Public License along with this software. If not, it can be
+ * retrieved online at http://www.erlang.org/.
+ *
+ * Software distributed under the License is distributed on an "AS IS"
+ * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+ * the License for the specific language governing rights and limitations
+ * under the License.
+ *
+ * %CopyrightEnd%
+ */
+
+import com.ericsson.otp.erlang.*;
+
+class MboxPing {
+
+ /*
+ Implements test case jinterface_SUITE:mbox_ping/1
+
+ Creates an OtpNode object with an OtpMbox object. The test_server
+ node is pinged from the OtpMbox.
+ */
+
+ public static void main(String argv[]) {
+
+ try {
+ OtpNode node = new OtpNode("javanode",argv[0]);
+ OtpMbox mbox = node.createMbox();
+ if (mbox.ping(argv[1],2000)) {
+ System.out.println("OtpMbox.ping(" + argv[1] + ") -> true");
+ }
+ else {
+ System.out.println("ERROR: OtpMbox.ping(" + argv[1] +
+ ") -> false");
+ System.exit(1);
+ }
+ }
+ catch (Exception e) {
+ System.out.println("" + e);
+ System.exit(2);
+ }
+ }
+}
diff --git a/lib/jinterface/test/jinterface_SUITE_data/MboxSendReceive.java b/lib/jinterface/test/jinterface_SUITE_data/MboxSendReceive.java
new file mode 100644
index 0000000000..2db71bb5cd
--- /dev/null
+++ b/lib/jinterface/test/jinterface_SUITE_data/MboxSendReceive.java
@@ -0,0 +1,229 @@
+/*
+ * %CopyrightBegin%
+ *
+ * Copyright Ericsson AB 2004-2010. All Rights Reserved.
+ *
+ * The contents of this file are subject to the Erlang Public License,
+ * Version 1.1, (the "License"); you may not use this file except in
+ * compliance with the License. You should have received a copy of the
+ * Erlang Public License along with this software. If not, it can be
+ * retrieved online at http://www.erlang.org/.
+ *
+ * Software distributed under the License is distributed on an "AS IS"
+ * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+ * the License for the specific language governing rights and limitations
+ * under the License.
+ *
+ * %CopyrightEnd%
+ */
+
+import com.ericsson.otp.erlang.*;
+
+class MboxSendReceive {
+
+ /*
+ Implements test case jinterface_SUITE:mbox_send_receive/1
+
+ Test OtpMbox.send(...) and OtpMbox.receive(...)
+ */
+
+ private static final boolean dbg = true;
+ private static final int recTime = 2000;
+
+ private static final int java_erlang_send_receive = 1;
+ private static final int java_internal_send_receive_same_node = 2;
+ private static final int java_internal_send_receive_different_nodes = 3;
+ private static final int java_internal_send_receive_self = 4;
+
+ public static void main(String argv[]) {
+
+ String cookie = argv[0];
+ String erlNode = argv[1];
+
+ OtpErlangObject[] msgArray = new OtpErlangObject[2];
+ msgArray[1] = new OtpErlangAtom("hello world");
+ OtpErlangTuple msg = null;
+
+ try {
+ // Initiate: create javanode and mboxes
+ OtpNode node = new OtpNode("javanode",cookie);
+ OtpMbox mbox = node.createMbox();
+ OtpMbox mbox2 = node.createMbox("java_echo_server2");
+
+ // Send the pid of mbox to erlang and wait for test case
+ // instruction: {TestCaseTag, Pid}
+ mbox.send("erl_send_receive_server", erlNode, mbox.self());
+ OtpErlangObject o = mbox.receive(recTime);
+ if (o == null) System.exit(1);
+ OtpErlangTuple testCase = (OtpErlangTuple)o;
+ dbg("mbox received " + testCase);
+ int tag = (int)((OtpErlangLong)testCase.elementAt(0)).longValue();
+ OtpErlangPid erlangPid = (OtpErlangPid)testCase.elementAt(1);
+
+ switch (tag) {
+
+ case java_erlang_send_receive:
+
+ // Test1 (happened during initiation):
+ // Send mbox pid to erlang process with registered name.
+ // Erlang process sent back its pid to the mbox pid.
+
+ // Test2: Register name and sent it to the erlang pid. Erlang
+ // process shall send message back to my registered name.
+
+ mbox.registerName("java_echo_server");
+ msgArray[0] = getNameNode("java_echo_server",node);
+ msg = new OtpErlangTuple(msgArray);
+
+ dbg("java_echo_server sending " + msg);
+ mbox.send(erlangPid,msg);
+
+ o = mbox.receive(recTime);
+ dbg("java_echo_server received " + o);
+ if (o == null) System.exit(2);
+ if (!((OtpErlangAtom)o).equals(msgArray[1])) System.exit(3);
+
+ // Test3: Same as Test2, but using a new mbox2 which
+ // got its name already when it is created - i.e. not
+ // using mbox.registerName
+ msgArray[0] = getNameNode("java_echo_server2",node);
+ msg = new OtpErlangTuple(msgArray);
+
+ dbg("java_echo_server2 sending " + msg);
+ mbox2.send(erlangPid,msg);
+
+ o = mbox2.receive(recTime);
+ dbg("java_echo_server received " + o);
+ if (o == null) System.exit(4);
+ if (!((OtpErlangAtom)o).equals(msgArray[1])) System.exit(5);
+
+ break;
+
+ case java_internal_send_receive_same_node:
+
+ // Test1: Sending message between mboxes on same node
+ // given registered name and node without host.
+ mbox.send("java_echo_server2","javanode",msgArray[1]);
+ o = mbox2.receive(recTime);
+ dbg("Mbox at same node: " + o);
+ if (o == null) System.exit(6);
+ if(!((OtpErlangAtom)o).equals(msgArray[1])) System.exit(7);
+
+ // Test2: Sending message between mboxes on same node
+ // given registered name and node with host.
+ mbox.send("java_echo_server2",mbox2.self().node(),msgArray[1]);
+ o = mbox2.receive(recTime);
+ dbg("Mbox at same node: " + o);
+ if (o == null) System.exit(8);
+ if(!((OtpErlangAtom)o).equals(msgArray[1])) System.exit(9);
+
+ // Test3: Sending message between mboxes on same node
+ // given registered name but not node.
+ mbox.send("java_echo_server2",msgArray[1]);
+ o = mbox2.receive(recTime);
+ dbg("Mbox at same node: " + o);
+ if (o == null) System.exit(10);
+ if(!((OtpErlangAtom)o).equals(msgArray[1])) System.exit(11);
+
+ // Test4: Sending message between mboxes on same node
+ // given pid.
+ mbox.send(mbox2.self(),msgArray[1]);
+ o = mbox2.receive(recTime);
+ dbg("Mbox at same node: " + o);
+ if (o == null) System.exit(12);
+ if(!((OtpErlangAtom)o).equals(msgArray[1])) System.exit(13);
+
+ break;
+
+ case java_internal_send_receive_different_nodes:
+
+ OtpNode node2 = new OtpNode("javanode2", cookie);
+ OtpMbox mboxOtherNode = node2.createMbox("mboxOtherNode");
+
+ // Test1: Sending message between mboxes on different
+ // nodes given registered name and node without host.
+ mbox.send("mboxOtherNode","javanode2",msgArray[1]);
+ o = mboxOtherNode.receive(recTime);
+ dbg("Mbox at same node: " + o);
+ if (o == null) System.exit(14);
+ if(!((OtpErlangAtom)o).equals(msgArray[1])) System.exit(15);
+
+ // Test2: Sending message between mboxes on different
+ // nodes given registered name and node with host.
+ mbox.send("mboxOtherNode",mboxOtherNode.self().node(),
+ msgArray[1]);
+ o = mboxOtherNode.receive(recTime);
+ dbg("Mbox at same node: " + o);
+ if (o == null) System.exit(16);
+ if(!((OtpErlangAtom)o).equals(msgArray[1])) System.exit(17);
+
+ // Test3: Sending message between mboxes on different
+ // nodes given pid.
+ mbox.send(mboxOtherNode.self(),msgArray[1]);
+ o = mboxOtherNode.receive(recTime);
+ dbg("Mbox at same node: " + o);
+ if (o == null) System.exit(18);
+ if(!((OtpErlangAtom)o).equals(msgArray[1])) System.exit(19);
+
+ break;
+
+
+ case java_internal_send_receive_self:
+
+ // Test1: Sending message to myself given registered
+ // name and node without host.
+ mbox2.send("java_echo_server2","javanode",msgArray[1]);
+ o = mbox2.receive(recTime);
+ dbg("Self: " + o);
+ if (o == null) System.exit(18);
+ if(!((OtpErlangAtom)o).equals(msgArray[1])) System.exit(19);
+
+ // Test2: Sending message to myself given registered
+ // name and node with host.
+ mbox2.send("java_echo_server2",mbox2.self().node(),msgArray[1]);
+ o = mbox2.receive(recTime);
+ dbg("Self: " + o);
+ if (o == null) System.exit(20);
+ if(!((OtpErlangAtom)o).equals(msgArray[1])) System.exit(21);
+
+ // Test3: Sending message to myself given registered
+ // name but not host.
+ mbox2.send("java_echo_server2",msgArray[1]);
+ o = mbox2.receive(recTime);
+ dbg("Self: " + o);
+ if (o == null) System.exit(22);
+ if(!((OtpErlangAtom)o).equals(msgArray[1])) System.exit(23);
+
+ // Test4: Sending message to myself given pid.
+ mbox2.send(mbox2.self(),msgArray[1]);
+ o = mbox2.receive(recTime);
+ dbg("Self: " + o);
+ if (o == null) System.exit(24);
+ if(!((OtpErlangAtom)o).equals(msgArray[1])) System.exit(25);
+
+ break;
+
+ }
+
+ // Closing erl_send_receive_server by sending the atom 'done' to it.
+ mbox.send(erlangPid,new OtpErlangAtom("done"));
+ }
+ catch (Exception e) {
+ System.out.println("" + e);
+ System.exit(26);
+ }
+ }
+
+ private static OtpErlangTuple getNameNode(String mboxName,OtpNode node) {
+ OtpErlangObject[] array = {new OtpErlangAtom(mboxName),
+ new OtpErlangAtom(node.node())};
+ return new OtpErlangTuple(array);
+
+ }
+
+ private static void dbg(String str) {
+ if (dbg) System.out.println(str);
+ }
+
+
+}
diff --git a/lib/jinterface/test/jinterface_SUITE_data/NodePing.java b/lib/jinterface/test/jinterface_SUITE_data/NodePing.java
new file mode 100644
index 0000000000..d0df5c46b5
--- /dev/null
+++ b/lib/jinterface/test/jinterface_SUITE_data/NodePing.java
@@ -0,0 +1,83 @@
+/*
+ * %CopyrightBegin%
+ *
+ * Copyright Ericsson AB 2004-2010. All Rights Reserved.
+ *
+ * The contents of this file are subject to the Erlang Public License,
+ * Version 1.1, (the "License"); you may not use this file except in
+ * compliance with the License. You should have received a copy of the
+ * Erlang Public License along with this software. If not, it can be
+ * retrieved online at http://www.erlang.org/.
+ *
+ * Software distributed under the License is distributed on an "AS IS"
+ * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+ * the License for the specific language governing rights and limitations
+ * under the License.
+ *
+ * %CopyrightEnd%
+ */
+
+import com.ericsson.otp.erlang.*;
+
+class NodePing {
+
+ /*
+ Implements test case jinterface_SUITE:node_ping/1
+
+ Creates three OtpNode objects. One with default cookie, one with
+ specified same cookie as the node running the test case and one
+ with a faulty cookie. From each OtpNode object the test_server
+ node is pinged.
+
+ Also the default cookie node pings itself, and the node with the
+ specified cookie pings the node with default cookie.
+ */
+
+ public static void main(String argv[]) {
+
+ String cookie = argv[0];
+ String erlNode = argv[1];
+
+ try {
+ OtpNode node1 = new OtpNode("javanode1");
+ ping(node1,erlNode,"Default cookie:",true,1);
+ ping(node1,node1.node(),"Self:",true,2);
+ ping(node1,"javanode1","Self:",true,3);
+
+ OtpNode node2 = new OtpNode("javanode2",cookie);
+ ping(node2,erlNode,"Specified cookie:",true,4);
+ ping(node2,"javanode1","Javanode (no host):",true,5);
+ ping(node2,node1.node(),"Javanode:",true,6);
+
+ OtpNode node3 = new OtpNode("javanode3","faultycookie");
+ ping(node3,erlNode,"Faulty cookie:",false,7);
+
+ // Test OtpNode.cookie() and OtpNode.setCookie(cookie) as well
+ if (!node3.cookie().equals("faultycookie"))
+ fail("Testing OtpNode.cookie()",8);
+ String old = node3.setCookie(cookie);
+ if (!old.equals("faultycookie"))
+ fail("Checking return of OtpNode.setCookie(cookie)",9);
+ ping(node3,erlNode,"setCookie:",true,10);
+ }
+ catch (Exception e) {
+ fail("" + e, 11);
+ }
+ }
+
+ private static void ping(OtpNode node, String remote, String descr,
+ boolean expected, int reason) {
+ if ( node.ping(remote,2000) == expected ) {
+ System.out.println(descr + " ping(" + remote + ") -> " + expected);
+ }
+ else {
+ fail("ERROR: " + descr + " ping(" + remote +") -> " + !expected,
+ reason);
+ }
+ }
+
+ private static void fail(String str, int reason) {
+ System.out.println(str);
+ System.exit(reason);
+ }
+}
diff --git a/lib/jinterface/test/jinterface_SUITE_data/NodeStatusHandler.java b/lib/jinterface/test/jinterface_SUITE_data/NodeStatusHandler.java
new file mode 100644
index 0000000000..51ea15b5ef
--- /dev/null
+++ b/lib/jinterface/test/jinterface_SUITE_data/NodeStatusHandler.java
@@ -0,0 +1,168 @@
+/*
+ * %CopyrightBegin%
+ *
+ * Copyright Ericsson AB 2004-2010. All Rights Reserved.
+ *
+ * The contents of this file are subject to the Erlang Public License,
+ * Version 1.1, (the "License"); you may not use this file except in
+ * compliance with the License. You should have received a copy of the
+ * Erlang Public License along with this software. If not, it can be
+ * retrieved online at http://www.erlang.org/.
+ *
+ * Software distributed under the License is distributed on an "AS IS"
+ * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+ * the License for the specific language governing rights and limitations
+ * under the License.
+ *
+ * %CopyrightEnd%
+ */
+
+import com.ericsson.otp.erlang.*;
+
+public class NodeStatusHandler extends OtpNodeStatus {
+ /*
+ Implements java side of test cases in jinterface_SUITE.erl
+
+ Test OtpNode.registerStatusHandler(...) and class OtpNodeStatus.
+ */
+
+ private static final boolean dbg = true;
+ private static final int recTime = 2000;
+
+ private static String erlNode = null;
+ private static String cookie = null;
+ private static OtpMbox mbox = null;
+
+ private static final int status_handler_localStatus = 1;
+ private static final int status_handler_remoteStatus = 2;
+ private static final int status_handler_connAttempt = 3;
+
+ public static void main(String argv[]) {
+
+ cookie = argv[0];
+ erlNode = argv[1];
+
+ try {
+ OtpNode javaNode = new OtpNode("javanode", cookie);
+ mbox = javaNode.createMbox();
+ }
+ catch (Exception e) {
+ dbg("EXCEPTION when creating javanode: " + e);
+ System.exit(1);
+ }
+
+ try {
+ OtpNode node1 = new OtpNode("javanode1", cookie);
+ node1.registerStatusHandler(new NodeStatusHandler());
+
+ switch (Integer.parseInt(argv[2])) {
+
+ case status_handler_localStatus:
+ dbg("java running test case \"status_handler_localStatus\"");
+
+ Thread.sleep(200); // Give 'nodeup' message a chance
+ // before closing
+ node1.close();
+ Thread.sleep(500);
+ break;
+
+ case status_handler_remoteStatus:
+ dbg("java running test case \"status_handler_remoteStatus\"");
+
+ OtpNode node2 = new OtpNode("javanode2", cookie);
+ node2.ping(node1.node(),2000);
+ node2.close();
+ Thread.sleep(500);
+ break;
+
+ case status_handler_connAttempt:
+ dbg("java running test case \"status_handler_connAttempt\"");
+
+ OtpNode node3 = new OtpNode("javanode3","othercookie");
+ node3.ping(node1.node(),2000);
+ node1.ping(node3.node(),2000);
+ break;
+
+ }
+
+ OtpErlangObject o = mbox.receive(recTime);
+ if (o == null) System.exit(2);
+ if (! ((OtpErlangAtom)o).atomValue().equals("done"))
+ System.exit(3);
+
+ }
+ catch (Exception e) {
+ dbg("EXCEPTION: " + e);
+ System.exit(4);
+ }
+
+ }
+
+
+
+ public void remoteStatus(String node, boolean up, Object info) {
+ try {
+ dbg("Got remoteStatus: " + node + " " + up + " " + info);
+ OtpErlangObject[] msgArray = new OtpErlangObject[4];
+ msgArray[0] = new OtpErlangAtom("remoteStatus");
+ msgArray[1] = new OtpErlangString(node);
+ msgArray[2] = new OtpErlangBoolean(up);
+ msgArray[3] = mbox.self();
+ OtpErlangTuple msg = new OtpErlangTuple(msgArray);
+ mbox.send("erl_status_server", erlNode, msg);
+
+ }
+ catch (Exception e) {
+ dbg("EXCEPTION in remoteStatus: " + e + "\nArgs: " +
+ node + " " + up + " " + info);
+ System.exit(5);
+ }
+ }
+
+
+ public void localStatus(String node, boolean up, Object info) {
+ try {
+ dbg("Got localStatus: " + node + " " + up + " " + info);
+ OtpErlangObject[] msgArray = new OtpErlangObject[4];
+ msgArray[0] = new OtpErlangAtom("localStatus");
+ msgArray[1] = new OtpErlangString(node);
+ msgArray[2] = new OtpErlangBoolean(up);
+ msgArray[3] = mbox.self();
+ OtpErlangTuple msg = new OtpErlangTuple(msgArray);
+ mbox.send("erl_status_server", erlNode, msg);
+
+ }
+ catch (Exception e) {
+ dbg("EXCEPTION in localStatus: " + e + "\nArgs: " +
+ node + " " + up + " " + info);
+ System.exit(6);
+ }
+ }
+
+
+
+ public void connAttempt(String node, boolean incoming, Object info) {
+ try {
+ dbg("Got connAttempt: " + node + " " + incoming + " " + info);
+ OtpErlangObject[] msgArray = new OtpErlangObject[4];
+ msgArray[0] = new OtpErlangAtom("connAttempt");
+ msgArray[1] = new OtpErlangString(node);
+ msgArray[2] = new OtpErlangBoolean(incoming);
+ msgArray[3] = mbox.self();
+ OtpErlangTuple msg = new OtpErlangTuple(msgArray);
+ mbox.send("erl_status_server", erlNode, msg);
+
+ }
+ catch (Exception e) {
+ dbg("EXCEPTION in connAttempt: " + e + "\nArgs: " +
+ node + " " + incoming + " " + info);
+ System.exit(7);
+ }
+ }
+
+
+ private static void dbg(String str) {
+ if (dbg) System.out.println(str);
+ }
+
+}
diff --git a/lib/jinterface/test/jinterface_SUITE_data/Nodename.java b/lib/jinterface/test/jinterface_SUITE_data/Nodename.java
new file mode 100644
index 0000000000..dc8cb9c49f
--- /dev/null
+++ b/lib/jinterface/test/jinterface_SUITE_data/Nodename.java
@@ -0,0 +1,54 @@
+/*
+ * %CopyrightBegin%
+ *
+ * Copyright Ericsson AB 2004-2010. All Rights Reserved.
+ *
+ * The contents of this file are subject to the Erlang Public License,
+ * Version 1.1, (the "License"); you may not use this file except in
+ * compliance with the License. You should have received a copy of the
+ * Erlang Public License along with this software. If not, it can be
+ * retrieved online at http://www.erlang.org/.
+ *
+ * Software distributed under the License is distributed on an "AS IS"
+ * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+ * the License for the specific language governing rights and limitations
+ * under the License.
+ *
+ * %CopyrightEnd%
+ */
+
+import com.ericsson.otp.erlang.*;
+
+class Nodename {
+
+ /*
+ Implements test case jinterface_SUITE:nodename/1
+
+ */
+
+ public static void main(String argv[]) {
+
+ String host = argv[0];
+
+ try {
+ OtpNode node = new OtpNode("javanode");
+ System.out.println("Given host: " + host +
+ " Host: " + node.host() +
+ " Alive: " + node.alive() +
+ " Node: " + node.node());
+
+ if (!node.host().equals(host)) fail(1);
+ if (!node.alive().equals("javanode")) fail(2);
+ if (!node.node().equals("javanode@" + host)) fail(3);
+ }
+ catch (Exception e) {
+ System.out.println("" + e);
+ fail(4);
+ }
+ }
+
+ private static void fail(int reason) {
+ System.exit(reason);
+ }
+
+}
diff --git a/lib/jinterface/test/jinterface_SUITE_data/RegisterAndWhereis.java b/lib/jinterface/test/jinterface_SUITE_data/RegisterAndWhereis.java
new file mode 100644
index 0000000000..9df01981b2
--- /dev/null
+++ b/lib/jinterface/test/jinterface_SUITE_data/RegisterAndWhereis.java
@@ -0,0 +1,79 @@
+/*
+ * %CopyrightBegin%
+ *
+ * Copyright Ericsson AB 2004-2010. All Rights Reserved.
+ *
+ * The contents of this file are subject to the Erlang Public License,
+ * Version 1.1, (the "License"); you may not use this file except in
+ * compliance with the License. You should have received a copy of the
+ * Erlang Public License along with this software. If not, it can be
+ * retrieved online at http://www.erlang.org/.
+ *
+ * Software distributed under the License is distributed on an "AS IS"
+ * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+ * the License for the specific language governing rights and limitations
+ * under the License.
+ *
+ * %CopyrightEnd%
+ */
+
+import com.ericsson.otp.erlang.*;
+
+class RegisterAndWhereis {
+
+ /*
+ Implements test case jinterface_SUITE:register_and_whereis/1
+
+ */
+
+ public static void main(String argv[]) {
+
+ try {
+ OtpNode node = new OtpNode("javanode");
+ OtpMbox mbox1 = node.createMbox();
+ mbox1.registerName("mbox1");
+ OtpMbox mbox2 = node.createMbox("mbox2");
+ OtpMbox mbox3 = node.createMbox();
+ node.registerName("mbox3",mbox3);
+
+ OtpErlangPid pid1 = mbox1.self();
+ OtpErlangPid pid2 = mbox2.self();
+ OtpErlangPid pid3 = mbox3.self();
+
+ if (!pid1.equals(node.whereis("mbox1"))) fail(1);
+ if (!pid1.equals(mbox1.whereis("mbox1"))) fail(2);
+ if (!pid1.equals(mbox2.whereis("mbox1"))) fail(3);
+ if (!pid1.equals(mbox3.whereis("mbox1"))) fail(4);
+ if (!pid2.equals(node.whereis("mbox2"))) fail(5);
+ if (!pid2.equals(mbox2.whereis("mbox2"))) fail(6);
+ if (!pid3.equals(node.whereis("mbox3"))) fail(7);
+ if (!pid3.equals(mbox3.whereis("mbox3"))) fail(8);
+
+ node.closeMbox(mbox1);
+ mbox2.close();
+
+ if (node.whereis("mbox1") != null) fail(9);
+ if (node.whereis("mbox2") != null) fail(10);
+ if (mbox3.whereis("mbox1") != null) fail(11);
+ if (mbox3.whereis("mbox2") != null) fail(12);
+
+ mbox3.close();
+ if (mbox2.whereis("mbox3") != null) fail(13);
+
+
+
+ }
+ catch (Exception e) {
+ fail("" + e, 14);
+ }
+ }
+
+ private static void fail(int reason) {
+ System.exit(reason);
+ }
+
+ private static void fail(String str, int reason) {
+ System.out.println(str);
+ System.exit(reason);
+ }
+}
diff --git a/lib/jinterface/test/jitu.erl b/lib/jinterface/test/jitu.erl
new file mode 100644
index 0000000000..c57fb9bfad
--- /dev/null
+++ b/lib/jinterface/test/jitu.erl
@@ -0,0 +1,156 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 2004-2010. All Rights Reserved.
+%%
+%% The contents of this file are subject to the Erlang Public License,
+%% Version 1.1, (the "License"); you may not use this file except in
+%% compliance with the License. You should have received a copy of the
+%% Erlang Public License along with this software. If not, it can be
+%% retrieved online at http://www.erlang.org/.
+%%
+%% Software distributed under the License is distributed on an "AS IS"
+%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+%% the License for the specific language governing rights and limitations
+%% under the License.
+%%
+%% %CopyrightEnd%
+%%
+
+%%----------------------------------------------------------------------
+%% JInterface Test Utils
+%%----------------------------------------------------------------------
+-module(jitu).
+
+
+-export([java/3,
+ java/4,
+ java/5,
+ init_all/1,
+ finish_all/1]).
+
+%%
+%% Lots of stuff here are originating from java_client_erl_server_SUITE.erl
+%% (ic) ...
+%%
+
+
+
+java(Java, Dir, ClassAndArgs) ->
+ cmd(Java++" -classpath "++classpath(Dir)++" "++ClassAndArgs).
+
+java(Java, Dir, Class, Args) ->
+ java(Java, Dir, Class++" "++to_string(Args)).
+
+java(Java, Dir, Class, Args, Props) ->
+ java(Java, Dir, Props++" "++Class, Args).
+
+
+
+
+init_all(Config) when list(Config) ->
+ case find_executable(["java"]) of
+ false -> {skip,"Found no Java VM"};
+ Path -> [{java,Path}|Config]
+ end.
+
+finish_all(Config) -> Config.
+
+%%
+%% Internal stuff...
+%%
+
+
+find_executable([]) ->
+ false;
+find_executable([E|T]) ->
+ case os:find_executable(E) of
+ false -> find_executable(T);
+ Path -> Path
+ end.
+
+to_string([H|T]) when integer(H) ->
+ integer_to_list(H)++" "++to_string(T);
+to_string([H|T]) when atom(H) ->
+ atom_to_list(H)++" "++to_string(T);
+to_string([H|T]) when pid(H) ->
+ pid_to_list(H)++" "++to_string(T);
+to_string([H|T]) when list(H) ->
+ lists:flatten(H)++" "++to_string(T);
+to_string([]) -> [].
+
+% javac(Dir, File) ->
+% cmd("javac -d "++Dir++" -classpath "++classpath(Dir)++" "++
+% filename:join(Dir, File)).
+
+classpath(Dir) ->
+ PS =
+ case os:type() of
+ {win32, _} -> ";";
+ _ -> ":"
+ end,
+ Dir++PS++
+ filename:join([code:lib_dir(jinterface),"priv","OtpErlang.jar"])++PS++
+ case os:getenv("CLASSPATH") of
+ false -> "";
+ Classpath -> Classpath
+ end.
+
+
+cmd(Cmd) ->
+ PortOpts = [{line,80},eof,exit_status,stderr_to_stdout],
+ io:format("cmd: ~s~n", [Cmd]),
+ case catch open_port({spawn,Cmd}, PortOpts) of
+ Port when port(Port) ->
+ Result = cmd_loop(Port, []),
+ io:format("cmd res: ~w~n", [Result]),
+ case Result of
+ 0 -> ok;
+ ExitCode when integer(ExitCode) -> {error,ExitCode};
+ Error -> Error
+ end;
+ {'EXIT',Reason} ->
+ {error,Reason}
+ end.
+
+cmd_loop(Port, Line) ->
+ receive
+ {Port,eof} ->
+ receive
+ {Port,{exit_status,ExitStatus}} ->
+ ExitStatus
+ after 1 ->
+ undefined
+ end;
+ {Port,{exit_status,ExitStatus}} ->
+ receive
+ {Port,eof} ->
+ ok after 1 -> ok end,
+ ExitStatus;
+ {Port,{data,{Tag,Data}}} ->
+ case Tag of
+ eol ->
+ io:put_chars([Line|cr_to_nl(Data)]),
+ io:nl(),
+ cmd_loop(Port, []);
+ noeol ->
+ cmd_loop(Port, [Line|cr_to_nl(Data)])
+ end;
+ {'EXIT',Port,Reason} ->
+ {error,Reason};
+ Other ->
+ io:format("WARNING: Unexpected at ~s:~p: ~p~n",
+ [?MODULE_STRING,?LINE,Other]),
+ cmd_loop(Port, Line)
+ end.
+
+%% Convert lonely CR to NL, and CRLF to NL
+%%
+cr_to_nl([$\r,$\n|T]) ->
+ [$\n|cr_to_nl(T)];
+cr_to_nl([$\r|T]) ->
+ [$\n|cr_to_nl(T)];
+cr_to_nl([C|T]) ->
+ [C|cr_to_nl(T)];
+cr_to_nl([]) ->
+ [].
diff --git a/lib/jinterface/test/nc_SUITE.erl b/lib/jinterface/test/nc_SUITE.erl
new file mode 100644
index 0000000000..82dd3c2535
--- /dev/null
+++ b/lib/jinterface/test/nc_SUITE.erl
@@ -0,0 +1,736 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 2004-2010. All Rights Reserved.
+%%
+%% The contents of this file are subject to the Erlang Public License,
+%% Version 1.1, (the "License"); you may not use this file except in
+%% compliance with the License. You should have received a copy of the
+%% Erlang Public License along with this software. If not, it can be
+%% retrieved online at http://www.erlang.org/.
+%%
+%% Software distributed under the License is distributed on an "AS IS"
+%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+%% the License for the specific language governing rights and limitations
+%% under the License.
+%%
+%% %CopyrightEnd%
+%%
+-module(nc_SUITE).
+
+
+-include("test_server.hrl").
+-include("test_server_line.hrl").
+
+
+-export([all/1,
+ init_per_suite/1,
+ end_per_suite/1,
+ init_per_testcase/2,
+ end_per_testcase/2]).
+
+-export([pid_roundtrip/1,
+ port_roundtrip/1,
+ ref_roundtrip/1,
+ new_float/1,
+ old_stuff/1,
+ binary_roundtrip/1,
+ decompress_roundtrip/1,
+ compress_roundtrip/1,
+ integer_roundtrip/1,
+ fun_roundtrip/1,
+ lists_roundtrip/1,
+ lists_roundtrip_2/1,
+ lists_iterator/1,
+ unicode/1,
+ unicode_list_to_string/1,
+ unicode_string_to_list/1,
+ connect/1]).
+
+
+%% Top of cases
+
+all(doc) -> [];
+all(suite) -> [pid_roundtrip,
+ port_roundtrip,
+ ref_roundtrip,
+ new_float,
+ old_stuff,
+ binary_roundtrip,
+ decompress_roundtrip,
+ compress_roundtrip,
+ integer_roundtrip,
+ fun_roundtrip,
+ lists_roundtrip,
+ lists_roundtrip_2,
+ lists_iterator,
+ unicode,
+ unicode_list_to_string,
+ unicode_string_to_list,
+ connect].
+
+
+
+
+init_per_suite(Config) when is_list(Config) ->
+ jitu:init_all(Config).
+
+end_per_suite(Config) ->
+ jitu:finish_all(Config).
+
+
+
+%% Add/remove watchdog before/after each test case.
+%%
+init_per_testcase(Case, Config) ->
+ T = case atom_to_list(Case) of
+ "unicode"++_ -> 240;
+ _ -> 20
+ end,
+ WatchDog = test_server:timetrap(test_server:seconds(T)),
+ [{watchdog, WatchDog}| Config].
+
+end_per_testcase(_Case, Config) ->
+ WatchDog = ?config(watchdog, Config),
+ test_server:timetrap_cancel(WatchDog).
+
+
+%%
+%% Test cases
+%%
+
+pid_roundtrip(doc) -> [];
+pid_roundtrip(suite) -> [];
+pid_roundtrip(Config) when is_list(Config)->
+ ThisNode = {node(), erlang:system_info(creation)},
+ RemNode = {gurka@sallad, 2},
+ do_echo([self(),
+ mk_pid(ThisNode, 4711, 4711),
+ mk_pid(ThisNode, 32767, 8191),
+ mk_pid(RemNode, 4711, 4711),
+ mk_pid(RemNode, 32767, 8191)],
+ Config).
+
+fun_roundtrip(doc) -> [];
+fun_roundtrip(suite) -> [];
+fun_roundtrip(Config) when is_list(Config)->
+ do_echo([fun(A, B) -> A + B end,
+ fun(A) -> lists:reverse(A) end,
+ fun() -> ok end,
+ fun fun_roundtrip/1],
+ Config).
+
+port_roundtrip(doc) -> [];
+port_roundtrip(suite) -> [];
+port_roundtrip(Config) when is_list(Config)->
+ ThisNode = {node(), erlang:system_info(creation)},
+ RemNode = {gurka@sallad, 2},
+ do_echo([hd(erlang:ports()),
+ mk_port(ThisNode, 4711),
+ mk_port(ThisNode, 268435455),
+ mk_port(RemNode, 4711),
+ mk_port(RemNode, 268435455)],
+ Config).
+
+ref_roundtrip(doc) -> [];
+ref_roundtrip(suite) -> [];
+ref_roundtrip(Config) when is_list(Config)->
+ ThisNode = {node(), erlang:system_info(creation)},
+ RemNode = {gurka@sallad, 2},
+ do_echo([make_ref(),
+ mk_ref(ThisNode, [4711]),
+ mk_ref(ThisNode, [4711, 4711, 4711]),
+ mk_ref(ThisNode, [262143, 4294967295, 4294967295]),
+ mk_ref(RemNode, [4711]),
+ mk_ref(RemNode, [4711, 4711, 4711]),
+ mk_ref(RemNode, [262143, 4294967295, 4294967295])],
+ Config).
+
+new_float(doc) -> [];
+new_float(suite) -> [];
+new_float(Config) when is_list(Config)->
+ Two16 = float(1 bsl 16),
+ X = math:sqrt(2),
+ Floats = lists:reverse(seq(1/X, 63, fun(Y) -> Y / Two16 end),
+ [0.0|seq(X, 63, fun(Y) -> Y * Two16 end)]),
+ io:format("~w", [Floats]),
+ do_echo(Floats, Config).
+
+old_stuff(doc) -> [];
+old_stuff(suite) -> [];
+old_stuff(Config) when is_list(Config)->
+ Terms = [0.0,math:sqrt(2)],
+ OutTrans =
+ fun (D) ->
+ {self(),term_to_binary(D, [{minor_version,0}]),binary}
+ end,
+ InTrans =
+ fun (Echoer, D, {Echoer,D,binary}) ->
+ ok
+ end,
+ do_echo(Terms, Config, OutTrans, InTrans).
+
+binary_roundtrip(doc) -> [];
+binary_roundtrip(suite) -> [];
+binary_roundtrip(Config) when is_list(Config) ->
+ do_echo([<<17>>,
+ <<1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17>>,
+ <<3:2>>,
+ <<3,7:3>>,
+ <<>>],
+ Config).
+
+decompress_roundtrip(doc) -> [];
+decompress_roundtrip(suite) -> [];
+decompress_roundtrip(Config) when is_list(Config) ->
+ Terms =
+ [0.0,
+ math:sqrt(2),
+ <<1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,31:5>>,
+ make_ref()],
+ OutTrans =
+ fun (D) ->
+ {self(),term_to_binary(D, [compressed]),binary}
+ end,
+ InTrans =
+ fun (Echoer, D, {Echoer,D,binary}) ->
+ ok
+ end,
+ do_echo(Terms, Config, OutTrans, InTrans).
+
+compress_roundtrip(doc) -> [];
+compress_roundtrip(suite) -> [];
+compress_roundtrip(Config) when is_list(Config) ->
+ Terms =
+ [0.0,
+ math:sqrt(2),
+ <<1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,31:5>>,
+ make_ref()],
+ OutTrans =
+ fun (D) ->
+ {self(),D,compress}
+ end,
+ InTrans =
+ fun (Echoer, D, {Echoer,B,compress}) ->
+ D = binary_to_term(B)
+ end,
+ do_echo(Terms, Config, OutTrans, InTrans).
+
+
+
+integer_roundtrip(doc) -> [];
+integer_roundtrip(suite) -> [];
+integer_roundtrip(Config) when is_list(Config) ->
+ Xs = [1 bsl X || X <- [26,27,28,29,30,31,32,33,
+ 62,63,64,65,
+ 126,127,128,129]],
+ Terms = [0,1,-1,-2]
+ ++lists:flatmap(fun (X) -> [X-2,X-1,X,-X+1,-X,-X-1] end,
+ Xs),
+ io:format("~w", [Terms]),
+ OutTrans =
+ fun (V) ->
+ {self(),V,bigint}
+ end,
+ InTrans =
+ fun (Echoer, V, {Echoer,{V,W,X,L,U},bigint}) ->
+ Bitlength = bitlength(V),
+ {w,W} = {w,signum(V) * Bitlength},
+ Y = V band 16#FFFFffffFFFFffff,
+ {y,Y} = {y,X band 16#FFFFffffFFFFffff},
+ {l,L} = {l,if V =:= X, Bitlength < 64 -> 1;
+ true -> 0 end},
+ {u,U} = {u,if V =:= Y, V >= 0, Bitlength =< 64 -> 1;
+ true -> 0 end}
+ end,
+ do_echo(Terms, Config, OutTrans, InTrans).
+
+signum(V) when is_integer(V), V > 0 -> 1;
+signum(V) when is_integer(V), V < 0 -> -1;
+signum(0) -> 0.
+
+bitlength(0) ->
+ 0;
+bitlength(-1) ->
+ 0;
+bitlength(V) when is_integer(V) ->
+ 1 + bitlength(V bsr 1).
+
+
+
+lists_roundtrip(doc) -> [];
+lists_roundtrip(suite) -> [];
+lists_roundtrip(Config) when is_list(Config) ->
+ Ls = [lists:seq(1,10),
+ lists:seq(11,17)++last_tail,
+ [{default}],
+ [car|cdr],
+ [[]],
+ []],
+ do_echo(Ls, Config).
+
+
+
+lists_roundtrip_2(doc) -> [];
+lists_roundtrip_2(suite) -> [];
+lists_roundtrip_2(Config) when is_list(Config) ->
+ Ls = [{[a,b],tail},
+ {[c,d,e],tail},
+ {[],tail},
+ {[f],tail},
+ {[g,h|i],tail},
+ {[j,k,l|m],tail},
+ {[n|o],tail},
+ {[z,1,2,3,4],tail3},
+ {[z,5,6,7],tail3},
+ {[z,8,9],tail3},
+ {[z,10],tail3},
+ {[],tail3},
+ {[z,11,12,13,14|15],tail3},
+ {[z,16,17,18|19],tail3},
+ {[z,20,21|22],tail3},
+ {[z,23|24],tail3},
+ {[z|25],tail3},
+ {"abc123",sub3atom},
+ {"abc",sub3atom}
+ ],
+ Trans =
+ fun ([_|T], tail) ->
+ T;
+ (L, tail) when is_list(L) ->
+ null;
+ ([_,_,_|T], tail3) ->
+ T;
+ (L, tail3) when is_list(L) ->
+ null;
+ ([_,_,_|L], sub3atom) ->
+ list_to_atom(L)
+ end,
+ OutTrans =
+ fun ({L,Twist}) ->
+ {self(),L,Twist}
+ end,
+ InTrans =
+ fun (Echoer, {L,Twist}, {Echoer,X,Twist}) ->
+ Y = Trans(L, Twist),
+ io:format("## ~w ~w ~w ~w~n", [L,Twist,X,Y]),
+ X = Y
+ end,
+ do_echo(Ls, Config, OutTrans, InTrans).
+
+
+
+
+lists_iterator(doc) -> [];
+lists_iterator(suite) -> [];
+lists_iterator(Config) when is_list(Config) ->
+ Ls = [["able ","was ","I ","ere ","I ","saw ","elba"]],
+ do_echo(Ls, Config,
+ fun (L) -> {self(),L,strcat} end,
+ fun (Echoer, L, {Echoer,X,strcat}) ->
+ io:format("## ~p ~p~n", [L,X]),
+ X = lists:flatten(L)
+ end).
+
+
+
+unicode(doc) -> [];
+unicode(suite) -> [];
+unicode(Config) when is_list(Config) ->
+ S1 = "plain ascii",
+ S2 = "iso-latin ��� �",
+ S3 = "Codepoints... ��� \x{1000}",
+ S4 = [0,1,31,32,63,64,127,128,255],
+ S5 = [0,1,127,128,255,256,16#d7ff,
+ 16#e000,16#fffd,16#10000,16#10ffff],
+ Ss = [S1,S2,S3,S4,S5],
+ do_echo(unicode_cp_gen([{S,valid} || S <- Ss] ++ cp_gen(71)), Config,
+ fun ({L,invalid}) -> {self(),L,utf8};
+ ({L,Tag}) -> {self(),L,Tag};
+ ({L}) -> {self(),L}
+ end,
+ fun (Echoer, {L,invalid}=Out, {Echoer,X,utf8}=In) ->
+ case L of
+ X -> ok;
+ _ ->
+ ?t:fail({mismatch,Out,In})
+ end;
+ (Echoer, {L,Tag}=Out, {Echoer,X,Tag}=In) ->
+ case unicode:characters_to_binary(L, utf8) of
+ X -> ok;
+ _ ->
+ ?t:fail({mismatch,Out,In})
+ end;
+ (Echoer, {L}=Out, {Echoer,X}=In) ->
+ case L of
+ X -> ok;
+ _ ->
+ ?t:fail({mismatch,Out,In})
+ end
+ end, ["unicode"]).
+
+%% Lazy wrapper to lazy list
+unicode_cp_gen([{S,valid}|Ss]) ->
+ [{S,utf8},{S}|unicode_cp_gen(Ss)];
+unicode_cp_gen([{S,invalid}=St|Ss]) ->
+ [St,{S}|unicode_cp_gen(Ss)];
+unicode_cp_gen([]) ->
+ [];
+unicode_cp_gen(Cont) when is_function(Cont, 0) ->
+ fun () ->
+ unicode_cp_gen(Cont())
+ end.
+
+
+
+unicode_list_to_string(doc) -> [];
+unicode_list_to_string(suite) -> [];
+unicode_list_to_string(Config) when is_list(Config) ->
+ do_echo(cp_gen(73), Config,
+ fun ({L,_}) -> {self(),L,to_string_neg_int_list} end,
+ fun (Echoer, {L,invalid}=Out, {Echoer,X,_}=In) ->
+ case L of
+ X -> ok;
+ _ ->
+ ?t:fail({mismatch,Out,In})
+ end;
+ (Echoer, {L,valid}=Out, {Echoer,X,_}=In) ->
+ B = unicode:characters_to_binary(L, unicode, {utf16,big}),
+ case [-D || <<D:16/big>> <= B] of
+ X -> ok;
+ _ ->
+ ?t:fail({mismatch,Out,In})
+ end
+ end).
+
+
+
+unicode_string_to_list(doc) -> [];
+unicode_string_to_list(suite) -> [];
+unicode_string_to_list(Config) when is_list(Config) ->
+ do_echo(cp_gen(79), Config,
+ fun ({L,_}) -> {self(),L,to_neg_int_list} end,
+ fun (Echoer, {L,invalid}=Out, {Echoer,X,_}=In) ->
+ case L of
+ X -> ok;
+ _ ->
+ ?t:fail({mismatch,Out,In})
+ end;
+ (Echoer, {L,valid}=Out, {Echoer,X,_}=In) ->
+ case [-C || C <- L] of
+ X -> ok;
+ _ ->
+ ?t:fail({mismatch,Out,In})
+ end
+ end, ["unicode"]).
+
+
+%% Lazy list
+cp_gen(N) ->
+ cp_gen(N, -1, 16#110000).
+
+cp_gen(N, Start, End) ->
+ cp_gen(N, Start, End, cp_validity(Start), [], 0, [], 0).
+
+cp_gen(N, U, End, PrevValidity, Acc, Len, Ss, Ls) when Len >= N ->
+ cp_gen(N, U, End, PrevValidity, [], 0, [{Acc,PrevValidity}|Ss], Ls+1);
+cp_gen(N, U, End, PrevValidity, Acc, Len, Ss, Ls) when Ls >= N ->
+ Ss ++ fun () ->
+ cp_gen(N, U, End, PrevValidity, Acc, Len, [], 0)
+ end;
+cp_gen(_, U, End, _, Acc, _, Ss, _) when U > End ->
+ [{Acc,valid}|Ss];
+cp_gen(N, U, End, PrevValidity, Acc, Len, Ss, Ls) ->
+ Validity = cp_validity(U),
+ NextU = U+1,
+ {NextAcc,NextLen} = case Validity of
+ valid -> {[U|Acc],Len+1};
+ invalid -> {Acc,Len}
+ end,
+ {NextSs,NextLs} = case Validity of
+ PrevValidity -> {Ss,Ls};
+ valid -> {[{[U-1],PrevValidity}|Ss],Ls+1};
+ invalid -> {[{[U],Validity}|Ss],Ls+1}
+ end,
+ cp_gen(N, NextU, End, Validity, NextAcc, NextLen, NextSs, NextLs).
+
+cp_validity(UnicodeCP) ->
+ try <<UnicodeCP/big-utf32>> of
+ _ -> valid
+ catch
+ error:_ -> invalid
+ end.
+
+
+
+connect(doc) -> [];
+connect(suite) -> [];
+connect(Config) when is_list(Config) ->
+ WD = filename:dirname(code:which(?MODULE)),
+ {ok,Other} = ?t:start_node(make_name(), slave, [{args,"-pa "++WD}]),
+ Action =
+ fun (Pid) ->
+ JName = node(Pid),
+ Hidden = [JName],
+ Pid ! {self(),Other},
+ receive
+ {Pid,Other,true} ->
+ ok;
+ Unexpected1 ->
+ ?t:fail({result,Unexpected1})
+ end,
+ Hidden = erlang:nodes(hidden),
+ Hidden = rpc:call(Other, erlang, nodes, [hidden]),
+ true =
+ rpc:call(Other, erlang, disconnect_node, [JName]),
+ [] =
+ rpc:call(Other, erlang, nodes, [hidden]),
+ Hidden = erlang:nodes(hidden),
+ %% Again
+ receive after 2000 -> ok end,
+ %% We have no way of knowing when the Java node
+ %% detects the nodedown.
+ Pid ! {self(),Other},
+ receive
+ {Pid,Other,true} ->
+ ok;
+ Unexpected2->
+ ?t:fail({result,Unexpected2})
+ end,
+ Hidden = rpc:call(Other, erlang, nodes, [hidden])
+ end,
+ run_server(connection_server, Config, Action, []).
+
+
+
+seq(_, 0, _) ->
+ [];
+seq(X, N, Fun) ->
+ [X|seq(Fun(X), N-1, Fun)].
+
+do_echo(DataList, Config) ->
+ do_echo(DataList, Config,
+ fun (D) -> % OutTrans
+ {self(),D}
+ end,
+ fun (Echoer, D, {Echoer,D}) -> % InTrans
+ ok
+ end, []).
+
+do_echo(DataList, Config, OutTrans, InTrans) ->
+ do_echo(DataList, Config, OutTrans, InTrans, []).
+
+do_echo(DataList, Config, OutTrans, InTrans, ExtraArgs)
+ when is_list(DataList), is_list(Config) ->
+ run_server(echo_server, Config,
+ fun (Echoer) ->
+ echo_loop(DataList, Echoer, OutTrans, InTrans, [])
+ end,
+ ExtraArgs).
+
+echo_loop([D|Ds], Echoer, OutTrans, InTrans, TermAcc) ->
+ OutMsg = OutTrans(D),
+ Echoer ! OutMsg,
+ io:format("echo_server ~p: ~p ! ~P~n", [self(),Echoer,OutMsg,10]),
+ receive
+ Reply ->
+ io:format("echo_server ~p: receive ~P~n",
+ [self(),Reply,10]),
+ InTrans(Echoer, D, Reply)
+ end,
+ Term = case OutMsg of
+ {_, T, _} -> T;
+ {_, T} -> T
+ end,
+ echo_loop(Ds, Echoer, OutTrans, InTrans, [Term | TermAcc]);
+echo_loop([], Echoer, _, _, TermAcc) ->
+ check_terms(Echoer, TermAcc);
+%% Lazy list
+echo_loop(Cont, Echoer, OutTrans, InTrans, TermAcc)
+ when is_function(Cont, 0) ->
+ check_terms(Echoer, TermAcc),
+ OutMsg = Echoer ! {self(),undefined,hash_clear},
+ io:format("echo_server ~p: ~p ! ~P~n", [self(),Echoer,OutMsg,10]),
+ receive
+ {Echoer,hash_cleared,hash_clear}=Reply ->
+ io:format("echo_server ~p: receive ~P~n",
+ [self(),Reply,10]),
+ ok;
+ Other ->
+ io:format("echo_server_terms unexpected ~p: receive ~P~n",
+ [self(),Other,10]),
+ ?t:fail({unexpected, Other})
+ end,
+ echo_loop(Cont(), Echoer, OutTrans, InTrans, []).
+
+check_terms(Echoer, [Term | Rest]) ->
+ OutMsg = {self(),Term,hash_lookup},
+ Echoer ! OutMsg,
+ io:format("check_terms ~p: ~p ! ~P~n", [self(),Echoer,OutMsg,10]),
+ receive
+ {Echoer,true,hash_lookup} = ReplyMsg ->
+ io:format("check_terms ~p: receive ~P~n",
+ [self(),ReplyMsg,10]),
+ check_terms(Echoer, Rest);
+ Other ->
+ io:format("check_terms unexpected ~p: receive ~P~n",
+ [self(),Other,10]),
+ ?t:fail({unexpected, Other})
+ end;
+check_terms(_, []) ->
+ ok.
+
+run_server(Server, Config, Action, ExtraArgs) ->
+ Name = make_name(),
+ true = register(Name, self()),
+ JName = make_name(),
+ spawn_link(fun () ->
+ ok = jitu:java(?config(java, Config),
+ ?config(data_dir, Config),
+ atom_to_list(Server),
+ [JName,
+ erlang:get_cookie(),
+ node(),
+ Name]++ExtraArgs
+ ),
+ %,"-DOtpConnection.trace=3"),
+ Name ! {done, JName}
+ end),
+ receive
+ {Server, JName, Pid} ->
+ ?t:format("~w: ~p (~p)~n",
+ [Server, Pid, node(Pid)]),
+ ?t:format("nodes(hidden): ~p~n",
+ [nodes(hidden)]),
+ Action(Pid),
+ Pid ! bye,
+ receive
+ {done, JName} ->
+ ok
+ end;
+ Other ->
+ ?t:fail({unexpected,Other})
+ end.
+
+%%
+%% Utils...
+%%
+
+make_name() ->
+ {A, B, C} = now(),
+ list_to_atom(atom_to_list(?MODULE)
+ ++ "-" ++ integer_to_list(A)
+ ++ "-" ++ integer_to_list(B)
+ ++ "-" ++ integer_to_list(C)).
+
+
+
+-define(VERSION_MAGIC, 131).
+
+-define(ATOM_EXT, 100).
+-define(REFERENCE_EXT, 101).
+-define(PORT_EXT, 102).
+-define(PID_EXT, 103).
+-define(NEW_REFERENCE_EXT, 114).
+
+uint32_be(Uint) when is_integer(Uint), 0 =< Uint, Uint < 1 bsl 32 ->
+ [(Uint bsr 24) band 16#ff,
+ (Uint bsr 16) band 16#ff,
+ (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/jinterface/test/nc_SUITE_data/Makefile.src b/lib/jinterface/test/nc_SUITE_data/Makefile.src
new file mode 100644
index 0000000000..3d131250be
--- /dev/null
+++ b/lib/jinterface/test/nc_SUITE_data/Makefile.src
@@ -0,0 +1,53 @@
+#
+# %CopyrightBegin%
+#
+# Copyright Ericsson AB 2004-2010. All Rights Reserved.
+#
+# The contents of this file are subject to the Erlang Public License,
+# Version 1.1, (the "License"); you may not use this file except in
+# compliance with the License. You should have received a copy of the
+# Erlang Public License along with this software. If not, it can be
+# retrieved online at http://www.erlang.org/.
+#
+# Software distributed under the License is distributed on an "AS IS"
+# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+# the License for the specific language governing rights and limitations
+# under the License.
+#
+# %CopyrightEnd%
+#
+
+# Makefile.src for java_client_erl_server test
+# Note: This file *must* work for both Unix and Windows
+#
+# We use both `rm' (Unix) and `del' (Windows) for removing files, but
+# with a `-' in front so that the error in not finding `rm' (`del') on
+# Windows (Unix) is ignored.
+#
+# VxWorks? XXX
+#
+
+.SUFFIXES:
+.SUFFIXES: .java
+
+
+JAVAC = @JAVAC@
+ERLC = erlc
+
+JINTERFACE_CLASSPATH = @jinterface_classpath@
+
+CLASSPATH = .@PS@$(JINTERFACE_CLASSPATH)@PS@
+
+JAVA_FILES = echo_server.java connection_server.java
+CLASS_FILES = $(JAVA_FILES:.java=.class)
+
+all: $(CLASS_FILES)
+
+clean:
+ -rm -f $(CLASS_FILES)
+ -del /F /Q $(CLASS_FILES)
+
+$(CLASS_FILES) : $(JAVA_FILES)
+ $(JAVAC) -classpath $(CLASSPATH) $(JAVA_FILES)
+
+#
diff --git a/lib/jinterface/test/nc_SUITE_data/connection_server.java b/lib/jinterface/test/nc_SUITE_data/connection_server.java
new file mode 100644
index 0000000000..19ed1c7d5c
--- /dev/null
+++ b/lib/jinterface/test/nc_SUITE_data/connection_server.java
@@ -0,0 +1,96 @@
+/*
+ * %CopyrightBegin%
+ *
+ * Copyright Ericsson AB 2004-2010. All Rights Reserved.
+ *
+ * The contents of this file are subject to the Erlang Public License,
+ * Version 1.1, (the "License"); you may not use this file except in
+ * compliance with the License. You should have received a copy of the
+ * Erlang Public License along with this software. If not, it can be
+ * retrieved online at http://www.erlang.org/.
+ *
+ * Software distributed under the License is distributed on an "AS IS"
+ * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+ * the License for the specific language governing rights and limitations
+ * under the License.
+ *
+ * %CopyrightEnd%
+ */
+
+import com.ericsson.otp.erlang.*;
+
+public class connection_server {
+ static java.lang.String Name = "connection_server";
+
+ public static void main(String[] argv) {
+ try {
+ System.out.println("connection_server booting...");
+
+ for (int j = 0; j < argv.length; j++)
+ System.out.println("argv[" + j + "] = \"" + argv[j] + "\"");
+
+ if (argv.length != 4) {
+ System.out.println("Wrong number of arguments!");
+ System.exit(1);
+ }
+
+ // Start node and mbox
+ OtpNode node = new OtpNode(argv[0], argv[1]);
+ OtpMbox mbox = node.createMbox();
+ if (! mbox.registerName(Name)) {
+ System.out.println("Could not register name " + Name);
+ System.exit(3);
+ }
+
+ // Announce our presence
+ OtpErlangObject[] amsg = new OtpErlangObject[3];
+ amsg[0] = new OtpErlangAtom(Name);
+ amsg[1] = new OtpErlangAtom(argv[0]);
+ amsg[2] = mbox.self();
+ OtpErlangTuple atuple = new OtpErlangTuple(amsg);
+ mbox.send(argv[3], argv[2], atuple);
+
+ // Do connects ...
+ while (true) {
+ OtpErlangObject o = mbox.receive();
+ if (o == null)
+ continue;
+ if (o instanceof OtpErlangTuple) {
+ OtpErlangTuple msg = (OtpErlangTuple) o;
+ OtpErlangPid from = (OtpErlangPid)(msg.elementAt(0));
+ OtpErlangAtom conn_node = (OtpErlangAtom) msg.elementAt(1);
+
+ System.out.println("Got request to connect to: "
+ + conn_node);
+ OtpErlangObject[] rmsg = new OtpErlangObject[3];
+ rmsg[0] = mbox.self();
+ rmsg[1] = conn_node;
+ if (node.ping(conn_node.atomValue(), 1000)) {
+ System.out.println("Successfully connected to "
+ + conn_node.toString());
+ rmsg[2] = new OtpErlangAtom("true");
+ }
+ else {
+ System.out.println("Failed to connect to "
+ + conn_node.toString());
+ rmsg[2] = new OtpErlangAtom("false");
+ }
+
+ OtpErlangTuple rtuple = new OtpErlangTuple(rmsg);
+
+ mbox.send(from, rtuple);
+ }
+ else { // probably 'bye'
+ System.out.println("connection_server halting...");
+ System.exit(0);
+ }
+ }
+ }
+ catch (Exception e) {
+ System.out.println("" + e);
+ System.exit(2);
+ }
+
+ }
+
+}
diff --git a/lib/jinterface/test/nc_SUITE_data/echo_server.java b/lib/jinterface/test/nc_SUITE_data/echo_server.java
new file mode 100644
index 0000000000..0550e4beb1
--- /dev/null
+++ b/lib/jinterface/test/nc_SUITE_data/echo_server.java
@@ -0,0 +1,261 @@
+/*
+ * %CopyrightBegin%
+ *
+ * Copyright Ericsson AB 2004-2010. All Rights Reserved.
+ *
+ * The contents of this file are subject to the Erlang Public License,
+ * Version 1.1, (the "License"); you may not use this file except in
+ * compliance with the License. You should have received a copy of the
+ * Erlang Public License along with this software. If not, it can be
+ * retrieved online at http://www.erlang.org/.
+ *
+ * Software distributed under the License is distributed on an "AS IS"
+ * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+ * the License for the specific language governing rights and limitations
+ * under the License.
+ *
+ * %CopyrightEnd%
+ */
+
+import java.io.UnsupportedEncodingException;
+import java.util.HashSet;
+
+import com.ericsson.otp.erlang.OtpErlangAtom;
+import com.ericsson.otp.erlang.OtpErlangBinary;
+import com.ericsson.otp.erlang.OtpErlangBoolean;
+import com.ericsson.otp.erlang.OtpErlangException;
+import com.ericsson.otp.erlang.OtpErlangInt;
+import com.ericsson.otp.erlang.OtpErlangList;
+import com.ericsson.otp.erlang.OtpErlangLong;
+import com.ericsson.otp.erlang.OtpErlangObject;
+import com.ericsson.otp.erlang.OtpErlangPid;
+import com.ericsson.otp.erlang.OtpErlangString;
+import com.ericsson.otp.erlang.OtpErlangTuple;
+import com.ericsson.otp.erlang.OtpExternal;
+import com.ericsson.otp.erlang.OtpInputStream;
+import com.ericsson.otp.erlang.OtpMbox;
+import com.ericsson.otp.erlang.OtpNode;
+import com.ericsson.otp.erlang.OtpOutputStream;
+
+public class echo_server {
+ private static boolean debug = false;
+
+ public static void main(final String[] argv) {
+ try {
+ System.out.println("echo_server booting...");
+
+ for (int j = 0; j < argv.length; j++) {
+ System.out.println("argv[" + j + "] = \"" + argv[j] + "\"");
+ }
+
+ if (argv.length != 4 && argv.length != 5) {
+ System.out.println("Wrong number of arguments!");
+ System.exit(1);
+ }
+
+ // Start node and mbox
+ final OtpNode node = new OtpNode(argv[0], argv[1]);
+ if (argv.length == 5 && argv[4].equals("unicode")) {
+ System.out.println("Setting unicode string mode.");
+ node.setFlags(OtpInputStream.DECODE_INT_LISTS_AS_STRINGS);
+ }
+ final OtpMbox mbox = node.createMbox();
+
+ // Announce our presence
+ final OtpErlangObject[] amsg = new OtpErlangObject[3];
+ amsg[0] = new OtpErlangAtom("echo_server");
+ amsg[1] = new OtpErlangAtom(argv[0]);
+ amsg[2] = mbox.self();
+ final OtpErlangTuple atuple = new OtpErlangTuple(amsg);
+ mbox.send(argv[3], argv[2], atuple);
+
+ // Do echoing...
+ while (true) {
+ final OtpErlangObject o = mbox.receive();
+ if (o == null) {
+ continue;
+ }
+ if (o instanceof OtpErlangTuple) {
+ final OtpErlangTuple msg = (OtpErlangTuple) o;
+ final int arity = msg.arity();
+ if (arity < 2) {
+ System.out
+ .println("Arity < 2; echo_server aborting...");
+ System.exit(2);
+ } else if (arity == 2) {
+ final OtpErlangPid from = (OtpErlangPid) msg
+ .elementAt(0);
+ if (debug) System.out.println("Echoing: "
+ + msg.elementAt(1));
+
+ final OtpErlangObject[] rmsg = new OtpErlangObject[2];
+ rmsg[0] = mbox.self();
+ rmsg[1] = msg.elementAt(1);
+ final OtpErlangTuple rtuple = new OtpErlangTuple(rmsg);
+
+ mbox.send(from, rtuple);
+ continue;
+ } else if (arity == 3) {
+ echoTwisted(mbox, msg);
+ continue;
+ } else {
+ System.out
+ .println("Arity > 3; echo_server aborting...");
+ System.exit(2);
+ }
+ } else if (o instanceof OtpErlangAtom) {
+ OtpErlangAtom a = (OtpErlangAtom) o;
+ if (a.atomValue().equals("debug")) {
+ debug = true;
+ } else if (a.atomValue().equals("bye")) {
+ System.out.println("echo_server halting...");
+ System.exit(0);
+ }
+ } else { // probably 'bye'
+ }
+ System.out.println("Unexpected: " + o +
+ " echo_server aborting...");
+ System.exit(2);
+ }
+ } catch (final Exception e) {
+ System.out.println("" + e);
+ System.exit(2);
+ }
+ }
+
+ private static void echoTwisted(final OtpMbox mbox,
+ final OtpErlangTuple msg)
+ throws OtpErlangException {
+ final OtpErlangPid from = (OtpErlangPid) msg.elementAt(0);
+
+ final OtpErlangObject[] rmsg = new OtpErlangObject[3];
+ if (debug) System.out.println("Echo in: " + msg);
+ rmsg[0] = mbox.self();
+ rmsg[1] = twist(msg.elementAt(1), rmsg[2] = msg.elementAt(2));
+ final OtpErlangTuple rtuple = new OtpErlangTuple(rmsg);
+ if (debug) System.out.println("Echo out: " + rtuple);
+
+ mbox.send(from, rtuple);
+ }
+
+ private static HashSet<OtpErlangObject> hash_set =
+ new HashSet<OtpErlangObject>();
+
+ private static OtpErlangObject twist(final OtpErlangObject i,
+ final OtpErlangObject t) throws OtpErlangException {
+ hash_set.add(i);
+ if (t instanceof OtpErlangAtom) {
+ final String atomValue = ((OtpErlangAtom) t).atomValue();
+ if (atomValue.equals("binary") && i instanceof OtpErlangBinary) {
+ final OtpErlangBinary b = (OtpErlangBinary) i;
+ final OtpInputStream bis = new OtpInputStream(b.binaryValue(),
+ 0);
+ final OtpErlangObject o = bis.read_any();
+ return o;
+ } else if (atomValue.equals("compress")) {
+ final OtpOutputStream oos = new OtpOutputStream();
+ oos.write1(OtpExternal.versionTag);
+ oos.write_compressed(i);
+ final OtpErlangBinary o =
+ new OtpErlangBinary(oos.toByteArray());
+ return o;
+ } else if (atomValue.equals("bigint")
+ && i instanceof OtpErlangLong) {
+ final OtpErlangLong l = (OtpErlangLong) i;
+ final int w = l.signum() * l.bitLength();
+ final OtpErlangLong x = new OtpErlangLong(l.longValue());
+ final java.math.BigInteger b = l.bigIntegerValue();
+ System.out.println("long: " + l + ": " + w + ": " + b.signum()
+ * b.bitLength() + ": " + x + ": " + l.isLong() + ": "
+ + l.isULong());
+ return new OtpErlangTuple(new OtpErlangObject[] { l,
+ new OtpErlangInt(w), x,
+ new OtpErlangInt(l.isLong() ? 1 : 0),
+ new OtpErlangInt(l.isULong() ? 1 : 0) });
+ } else if (atomValue.equals("tail")
+ && i instanceof OtpErlangList) {
+ final OtpErlangObject o = ((OtpErlangList) i).getTail();
+ if (o == null) {
+ return new OtpErlangAtom("null");
+ }
+ return o;
+ } else if (atomValue.equals("tail3")
+ && i instanceof OtpErlangList) {
+ final OtpErlangObject o = ((OtpErlangList) i).getNthTail(3);
+ if (o == null) {
+ return new OtpErlangAtom("null");
+ }
+ return o;
+ } else if (atomValue.equals("strcat")
+ && i instanceof OtpErlangList) {
+ final java.lang.StringBuffer b = new java.lang.StringBuffer();
+ final OtpErlangList l = (OtpErlangList) i;
+ for (final OtpErlangObject j : l) {
+ final OtpErlangString k = (OtpErlangString) j;
+ b.append(k.stringValue());
+ }
+ final OtpErlangObject o = new OtpErlangString(b.toString());
+ return o;
+ } else if (atomValue.equals("sub3atom")
+ && i instanceof OtpErlangString) {
+ final OtpErlangString s = (OtpErlangString) i;
+ final OtpErlangAtom o = new OtpErlangAtom(s.stringValue()
+ .substring(3));
+ return o;
+ } else if (atomValue.equals("utf8")) {
+ if (i instanceof OtpErlangString) {
+ final OtpErlangString s = (OtpErlangString) i;
+ byte[] bytes;
+ try {
+ bytes = s.stringValue().getBytes("UTF-8");
+ } catch (final UnsupportedEncodingException e) {
+ bytes = new byte[] { 'e', 'r', 'r', 'o', 'r' };
+ }
+ final OtpErlangBinary b = new OtpErlangBinary(bytes);
+ return b;
+ }
+ } else if(atomValue.equals("to_string_neg_int_list")) {
+ OtpErlangString oes = null;
+ if (i instanceof OtpErlangString) {
+ oes = (OtpErlangString) i;
+ } else if (i instanceof OtpErlangList) {
+ OtpErlangList oel = (OtpErlangList) i;
+ try {
+ oes = new OtpErlangString(oel);
+ } catch (final Exception e) {
+ }
+ }
+ if (oes != null) {
+ String s = oes.stringValue();
+ int n = s.length();
+ OtpErlangObject l[] = new OtpErlangObject[n];
+ for (int j = 0; j < n; j++) {
+ int c = s.charAt(j);
+ l[j] = new OtpErlangInt(-c);
+ }
+ return new OtpErlangList(l);
+ }
+ } else if(atomValue.equals("to_neg_int_list")) {
+ if (i instanceof OtpErlangString) {
+ OtpErlangString oes = (OtpErlangString) i;
+ OtpErlangList oel = new OtpErlangList(oes.stringValue());
+ int n = oel.arity();
+ OtpErlangObject l[] = new OtpErlangObject[n];
+ for (int j = 0; j < n; j++) {
+ OtpErlangLong c = (OtpErlangLong) oel.elementAt(j);
+ l[j] = new OtpErlangInt(-c.intValue());
+ }
+ return new OtpErlangList(l);
+ }
+ } else if (atomValue.equals("hash_lookup")) {
+ final boolean exists = hash_set.contains(i);
+ final OtpErlangBoolean b = new OtpErlangBoolean(exists);
+ return b;
+ } else if (atomValue.equals("hash_clear")) {
+ hash_set.clear();
+ return new OtpErlangAtom("hash_cleared");
+ }
+ }
+ return i;
+ }
+}
diff --git a/lib/jinterface/vsn.mk b/lib/jinterface/vsn.mk
index 243547cf1f..26613febbf 100644
--- a/lib/jinterface/vsn.mk
+++ b/lib/jinterface/vsn.mk
@@ -1,19 +1 @@
-##
-## %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%
-
-JINTERFACE_VSN = 1.5.2
+JINTERFACE_VSN = 1.5.3
diff --git a/lib/kernel/doc/src/file.xml b/lib/kernel/doc/src/file.xml
index 2303617542..f9f5443f68 100644
--- a/lib/kernel/doc/src/file.xml
+++ b/lib/kernel/doc/src/file.xml
@@ -1368,7 +1368,7 @@ f.txt: {person, "kalle", 25}.
</type>
<desc>
<p>Reads a line of bytes/characters from the file referenced by
- <c>IoDevice</c>. Lines are defined to be delimited by the linefeed (LF, <c>\\n</c>) character, but any carriage return (CR, <c>\\r</c>) followed by a newline is also treated as a single LF character (the carriage return is silently ignored). The line is returned <em>including</em> the LF, but excluding any CR immediately followed by a LF. This behaviour is consistent with the behaviour of <seealso marker="stdlib:io#get_line/2">io:get_line/2</seealso>. If end of file is reached without any LF ending the last line, a line with no trailing LF is returned.</p>
+ <c>IoDevice</c>. Lines are defined to be delimited by the linefeed (LF, <c>\n</c>) character, but any carriage return (CR, <c>\r</c>) followed by a newline is also treated as a single LF character (the carriage return is silently ignored). The line is returned <em>including</em> the LF, but excluding any CR immediately followed by a LF. This behaviour is consistent with the behaviour of <seealso marker="stdlib:io#get_line/2">io:get_line/2</seealso>. If end of file is reached without any LF ending the last line, a line with no trailing LF is returned.</p>
<p>The function can be used on files opened in <c>raw</c> mode. It is however inefficient to use it on <c>raw</c> files if the file is not opened with the option <c>{read_ahead, Size}</c> specified, why combining <c>raw</c> and <c>{read_ahead, Size}</c> is highly recommended when opening a text file for raw line oriented reading.</p>
<p>If <c>encoding</c> is set to something else than <c>latin1</c>, the <c>read_line/1</c> call will fail if the data contains characters larger than 255, why the <seealso marker="stdlib:io">io(3)</seealso> module is to be preferred when reading such a file.</p>
<p>The function returns:</p>
diff --git a/lib/kernel/doc/src/gen_sctp.xml b/lib/kernel/doc/src/gen_sctp.xml
index de41178a17..3a8011e28b 100644
--- a/lib/kernel/doc/src/gen_sctp.xml
+++ b/lib/kernel/doc/src/gen_sctp.xml
@@ -4,7 +4,7 @@
<erlref>
<header>
<copyright>
- <year>2007</year><year>2009</year>
+ <year>2007</year><year>2010</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
@@ -13,12 +13,12 @@
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>gen_sctp</title>
@@ -170,10 +170,19 @@
<p>Establishes a new association for the socket <c>Socket</c>,
with the peer (SCTP server socket) given by
<c>Addr</c> and <c>Port</c>. The <c>Timeout</c>,
- is expressed in milliseconds.</p>
- <p>A socket can be associated with multiple peers.
- <marker id="record-sctp_assoc_change"></marker>
+ is expressed in milliseconds. A socket can be associated with multiple peers.</p>
+ <p><b>WARNING:</b>Using a value of <c>Timeout</c> less than
+ the maximum time taken by the OS to establish an association (around 4.5 minutes
+ if the default values from RFC 4960 are used) can result in
+ inconsistent or incorrect return values. This is especially
+ relevant for associations sharing the same <c>Socket</c>
+ (i.e. source address and port) since the controlling process
+ blocks until <c>connect/*</c> returns.
+ <seealso marker="#connect_init/4">connect_init/*</seealso>
+ provides an alternative not subject to this limitation.</p>
+
+ <p><marker id="record-sctp_assoc_change"></marker>
The result of <c>connect/*</c> is an <c>#sctp_assoc_change{}</c>
event which contains, in particular, the new
<seealso marker="#type-assoc_id">Association ID:</seealso></p>
@@ -233,6 +242,45 @@
</desc>
</func>
<func>
+ <name>connect_init(Socket, Addr, Port, Opts) -&gt; ok | {error, posix()}</name>
+ <fsummary>Same as <c>connect_init(Socket, Addr, Port, Opts, infinity)</c>.</fsummary>
+ <desc>
+ <p>Same as <c>connect_init(Socket, Addr, Port, Opts, infinity)</c>.</p>
+ </desc>
+ </func>
+ <func>
+ <name>connect_init(Socket, Addr, Port, [Opt], Timeout) -&gt; ok | {error, posix()}</name>
+ <fsummary>Initiate a new association for the socket <c>Socket</c>, with a peer (SCTP server socket)</fsummary>
+ <type>
+ <v>Socket = sctp_socket()</v>
+ <v>Addr = ip_address() | Host</v>
+ <v>Port = port_number()</v>
+ <v>Opt = sctp_option()</v>
+ <v>Timeout = timeout()</v>
+ <v>Host = atom() | string()</v>
+ </type>
+ <desc>
+ <p>Initiates a new association for the socket <c>Socket</c>,
+ with the peer (SCTP server socket) given by
+ <c>Addr</c> and <c>Port</c>.</p>
+ <p>The fundamental difference between this API
+ and <c>connect/*</c> is that the return value is that of the
+ underlying OS connect(2) system call. If <c>ok</c> is returned
+ then the result of the association establishement is received
+ by the calling process as
+ an <seealso marker="#record-sctp_assoc_change">
+ #sctp_assoc_change{}</seealso>
+ event. The calling process must be prepared to receive this, or
+ poll for it using <c>recv/*</c> depending on the value of the
+ active option.</p>
+ <p>The parameters are as described
+ in <seealso marker="#connect/5">connect/*</seealso>, with the
+ exception of the <c>Timeout</c> value.</p>
+ <p>The timer associated with <c>Timeout</c> only supervises
+ IP resolution of <c>Addr</c></p>
+ </desc>
+ </func>
+ <func>
<name>controlling_process(sctp_socket(), pid()) -&gt; ok</name>
<fsummary>Assign a new controlling process pid to the socket</fsummary>
<desc>
@@ -1058,6 +1106,65 @@
gen_sctp:close(S). </pre>
<p></p>
</item>
+ <item>
+ <p>A very simple Erlang SCTP Client which uses the
+ connect_init API.</p>
+ <pre>
+-module(ex3).
+
+-export([client/4]).
+-include_lib("kernel/include/inet.hrl").
+-include_lib("kernel/include/inet_sctp.hrl").
+
+client(Peer1, Port1, Peer2, Port2)
+ when is_tuple(Peer1), is_integer(Port1), is_tuple(Peer2), is_integer(Port2) -&gt;
+ {ok,S} = gen_sctp:open(),
+ SctpInitMsgOpt = {sctp_initmsg,#sctp_initmsg{num_ostreams=5}},
+ ActiveOpt = {active, true},
+ Opts = [SctpInitMsgOpt, ActiveOpt],
+ ok = gen_sctp:connect(S, Peer1, Port1, Opts),
+ ok = gen_sctp:connect(S, Peer2, Port2, Opts),
+ io:format("Connections initiated~n", []),
+ client_loop(S, Peer1, Port1, undefined, Peer2, Port2, undefined).
+
+client_loop(S, Peer1, Port1, AssocId1, Peer2, Port2, AssocId2) -&gt;
+ receive
+ {sctp, S, Peer1, Port1, {_Anc, SAC}}
+ when is_record(SAC, sctp_assoc_change), AssocId1 == undefined -&gt;
+ io:format("Association 1 connect result: ~p. AssocId: ~p~n",
+ [SAC#sctp_assoc_change.state,
+ SAC#sctp_assoc_change.assoc_id]),
+ client_loop(S, Peer1, Port1, SAC#sctp_assoc_change.assoc_id,
+ Peer2, Port2, AssocId2);
+
+ {sctp, S, Peer2, Port2, {_Anc, SAC}}
+ when is_record(SAC, sctp_assoc_change), AssocId2 == undefined -&gt;
+ io:format("Association 2 connect result: ~p. AssocId: ~p~n",
+ [SAC#sctp_assoc_change.state, SAC#sctp_assoc_change.assoc_id]),
+ client_loop(S, Peer1, Port1, AssocId1, Peer2, Port2,
+ SAC#sctp_assoc_change.assoc_id);
+
+ {sctp, S, Peer1, Port1, Data} -&gt;
+ io:format("Association 1: received ~p~n", [Data]),
+ client_loop(S, Peer1, Port1, AssocId1,
+ Peer2, Port2, AssocId2);
+
+ {sctp, S, Peer2, Port2, Data} -&gt;
+ io:format("Association 2: received ~p~n", [Data]),
+ client_loop(S, Peer1, Port1, AssocId1,
+ Peer2, Port2, AssocId2);
+
+ Other -&gt;
+ io:format("Other ~p~n", [Other]),
+ client_loop(S, Peer1, Port1, AssocId1,
+ Peer2, Port2, AssocId2)
+
+ after 5000 -&gt;
+ ok
+ end.
+</pre>
+ <p></p>
+ </item>
</list>
</section>
diff --git a/lib/kernel/doc/src/inet.xml b/lib/kernel/doc/src/inet.xml
index cae5fef2f8..f502b30c8d 100644
--- a/lib/kernel/doc/src/inet.xml
+++ b/lib/kernel/doc/src/inet.xml
@@ -49,8 +49,8 @@
might be specified in this way. An example of starting an Erlang
node with all sockets using delayed send could look like this:</p>
<pre>
-$ <input>erl -sname test -kernel \\</input>
-<input>inet_default_connect_options '[{delay_send,true}]' \\</input>
+$ <input>erl -sname test -kernel \</input>
+<input>inet_default_connect_options '[{delay_send,true}]' \</input>
<input>inet_default_listen_options '[{delay_send,true}]'</input></pre>
<p>Note that the default option <c>{active, true}</c> currently
cannot be changed, for internal reasons.</p>
diff --git a/lib/kernel/doc/src/notes.xml b/lib/kernel/doc/src/notes.xml
index 5bac964535..5467cd8cde 100644
--- a/lib/kernel/doc/src/notes.xml
+++ b/lib/kernel/doc/src/notes.xml
@@ -4,7 +4,7 @@
<chapter>
<header>
<copyright>
- <year>2004</year><year>2009</year>
+ <year>2004</year><year>2010</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
@@ -13,12 +13,12 @@
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>Kernel Release Notes</title>
@@ -30,6 +30,173 @@
</header>
<p>This document describes the changes made to the Kernel application.</p>
+<section><title>Kernel 2.13.5.4</title>
+
+ <section><title>Fixed Bugs and Malfunctions</title>
+ <list>
+ <item>
+ <p>A bug introduced in kernel-2.13.5.3 has been fixed. If
+ running <c>net_kernel:set_net_ticktime/1</c> twice within
+ the <c>TransitionPerod</c> the second call caused the
+ net_kernel process to crash with a <c>badmatch</c>.</p>
+ <p>
+ Own Id: OTP-8787 Aux Id: seq11657, OTP-8643 </p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
+<section><title>Kernel 2.13.5.3</title>
+
+ <section><title>Fixed Bugs and Malfunctions</title>
+ <list>
+ <item>
+ <p>
+ A bug introduced in Kernel 2.13.5.2 has been fixed.</p>
+ <p>
+ Own Id: OTP-8686 Aux Id: OTP-8643</p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
+<section><title>Kernel 2.13.5.2</title>
+
+ <section><title>Fixed Bugs and Malfunctions</title>
+ <list>
+ <item>
+ <p>
+ Under certain circumstances the net kernel could hang.
+ (Thanks to Scott Lystig Fritchie.)</p>
+ <p>
+ Own Id: OTP-8643 Aux Id: seq11584</p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
+<section><title>Kernel 2.13.5.1</title>
+
+ <section><title>Fixed Bugs and Malfunctions</title>
+ <list>
+ <item>
+ <p>
+ A race condition in <c>os:cmd/1</c> could cause the
+ caller to get stuck in <c>os:cmd/1</c> forever.</p>
+ <p>
+ Own Id: OTP-8502</p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
+<section><title>Kernel 2.13.5</title>
+
+ <section><title>Fixed Bugs and Malfunctions</title>
+ <list>
+ <item>
+ <p>A race bug affecting <c>pg2:get_local_members/1</c>
+ has been fixed. The bug was introduced in R13B03.</p>
+ <p>
+ Own Id: OTP-8358</p>
+ </item>
+ <item>
+ <p>
+ The loading of native code was not properly atomic in the
+ SMP emulator, which could cause crashes. Also a per-MFA
+ information table for the native code has now been
+ protected with a lock since it turns that it could be
+ accessed concurrently in the SMP emulator. (Thanks to
+ Mikael Pettersson.)</p>
+ <p>
+ Own Id: OTP-8397</p>
+ </item>
+ <item>
+ <p>
+ user.erl (used in oldshell) is updated to handle unicode
+ in prompt strings (io:get_line/{1,2}). io_lib is also
+ updated to format prompts with the 't' modifier (i.e. ~ts
+ instead of ~s).</p>
+ <p>
+ Own Id: OTP-8418 Aux Id: OTP-8393 </p>
+ </item>
+ <item>
+ <p>
+ The resolver routines failed to look up the own node name
+ as hostname, if the OS native resolver was erroneously
+ configured, bug reported by Yogish Baliga, now fixed.</p>
+ <p>
+ The resolver routines now tries to parse the hostname as
+ an IP string as most OS resolvers do, unless the native
+ resolver is used.</p>
+ <p>
+ The DNS resolver inet_res and file resolver inet_hosts
+ now do not read OS configuration files until they are
+ needed. Since the native resolver is default, in most
+ cases they are never needed.</p>
+ <p>
+ The DNS resolver's automatic updating of OS configuration
+ file data (/etc/resolv.conf) now uses the 'domain'
+ keyword as default search domain if there is no 'search'
+ keyword.</p>
+ <p>
+ Own Id: OTP-8426 Aux Id: OTP-8381 </p>
+ </item>
+ </list>
+ </section>
+
+
+ <section><title>Improvements and New Features</title>
+ <list>
+ <item>
+ <p>
+ The expected return value for an on_load function has
+ been changed. (See the section about code loading in the
+ Reference manual.)</p>
+ <p>
+ *** POTENTIAL INCOMPATIBILITY ***</p>
+ <p>
+ Own Id: OTP-8339</p>
+ </item>
+ <item>
+ <p>
+ Explicit top directories in archive files are now
+ optional.</p>
+ <p>
+ For example, if an archive (app-vsn.ez) just contains an
+ app-vsn/ebin/mod.beam file, the file info for the app-vsn
+ and app-vsn/ebin directories are faked using the file
+ info from the archive file as origin. The virtual
+ direcories can also be listed. For short, the top
+ directories are virtual if they does not exist.</p>
+ <p>
+ Own Id: OTP-8387</p>
+ </item>
+ <item>
+ <p>
+ <c>code:clash/0</c> now looks inside archives (.ez
+ files). (Thanks to Tuncer Ayaz.)</p>
+ <p>
+ Own Id: OTP-8413</p>
+ </item>
+ <item>
+ <p>
+ There are new <c>gen_sctp:connect_init/*</c> functions
+ that initiate an SCTP connection without blocking for the
+ result. The result is delivered asynchronously as an
+ sctp_assoc_change event. (Thanks to Simon Cornish.)</p>
+ <p>
+ Own Id: OTP-8414</p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
<section><title>Kernel 2.13.4</title>
<section><title>Fixed Bugs and Malfunctions</title>
diff --git a/lib/kernel/src/Makefile b/lib/kernel/src/Makefile
index ef280058fb..9db6014a7d 100644
--- a/lib/kernel/src/Makefile
+++ b/lib/kernel/src/Makefile
@@ -1,19 +1,19 @@
#
# %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
# 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%
#
@@ -143,6 +143,9 @@ APPUP_TARGET= $(EBIN)/$(APPUP_FILE)
# FLAGS
# ----------------------------------------------------
+ifeq ($(NATIVE_LIBS_ENABLED),yes)
+ERL_COMPILE_FLAGS += +native
+endif
ERL_COMPILE_FLAGS += -I../include
# ----------------------------------------------------
@@ -154,7 +157,7 @@ debug opt: $(TARGET_FILES)
# Note: In the open-source build clean must not destroyed the preloaded
# beam files.
clean:
- rm -f $(NON_PRECIOUS_TARGETS)
+ rm -f $(TARGET_FILES)
rm -f core
diff --git a/lib/kernel/src/code.erl b/lib/kernel/src/code.erl
index fef11d7e6e..ffe58ae7a9 100644
--- a/lib/kernel/src/code.erl
+++ b/lib/kernel/src/code.erl
@@ -1,19 +1,19 @@
%%
%% %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
%% 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(code).
@@ -63,7 +63,7 @@
which/1,
where_is_file/1,
where_is_file/2,
- set_primary_archive/2,
+ set_primary_archive/3,
clash/0]).
-include_lib("kernel/include/file.hrl").
@@ -101,7 +101,7 @@
%% unstick_dir(Dir) -> ok | error
%% is_sticky(Module) -> true | false
%% which(Module) -> Filename
-%% set_primary_archive((FileName, Bin) -> ok | {error, Reason}
+%% set_primary_archive((FileName, Bin, FileInfo) -> ok | {error, Reason}
%% clash() -> -> print out
%%----------------------------------------------------------------------------
@@ -420,11 +420,15 @@ where_is_file(Path, File) when is_list(Path), is_list(File) ->
which(File, ".", Path)
end.
--spec set_primary_archive(ArchiveFile :: file:filename(), ArchiveBin :: binary()) -> 'ok' | {'error', atom()}.
+-spec set_primary_archive(ArchiveFile :: file:filename(),
+ ArchiveBin :: binary(),
+ FileInfo :: #file_info{})
+ -> 'ok' | {'error', atom()}.
-set_primary_archive(ArchiveFile0, ArchiveBin) when is_list(ArchiveFile0), is_binary(ArchiveBin) ->
+set_primary_archive(ArchiveFile0, ArchiveBin, FileInfo)
+ when is_list(ArchiveFile0), is_binary(ArchiveBin), is_record(FileInfo, file_info) ->
ArchiveFile = filename:absname(ArchiveFile0),
- case call({set_primary_archive, ArchiveFile, ArchiveBin}) of
+ case call({set_primary_archive, ArchiveFile, ArchiveBin, FileInfo}) of
{ok, []} ->
ok;
{ok, _Mode, Ebins} ->
@@ -461,7 +465,8 @@ search([{Dir, File} | Tail]) ->
build([]) -> [];
build([Dir|Tail]) ->
- Files = filter(objfile_extension(), Dir, file:list_dir(Dir)),
+ Files = filter(objfile_extension(), Dir,
+ erl_prim_loader:list_dir(Dir)),
[decorate(Files, Dir) | build(Tail)].
decorate([], _) -> [];
diff --git a/lib/kernel/src/code_server.erl b/lib/kernel/src/code_server.erl
index 018f7f41d2..7aeddb73d1 100644
--- a/lib/kernel/src/code_server.erl
+++ b/lib/kernel/src/code_server.erl
@@ -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%
%%
-module(code_server).
@@ -384,8 +384,8 @@ handle_call(stop,{_From,_Tag}, S) ->
handle_call({is_cached,_File}, {_From,_Tag}, S=#state{cache=no_cache}) ->
{reply, no, S};
-handle_call({set_primary_archive, File, ArchiveBin}, {_From,_Tag}, S=#state{mode=Mode}) ->
- case erl_prim_loader:set_primary_archive(File, ArchiveBin) of
+handle_call({set_primary_archive, File, ArchiveBin, FileInfo}, {_From,_Tag}, S=#state{mode=Mode}) ->
+ case erl_prim_loader:set_primary_archive(File, ArchiveBin, FileInfo) of
{ok, Files} ->
{reply, {ok, Mode, Files}, S};
{error, Reason} ->
@@ -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/file.erl b/lib/kernel/src/file.erl
index fa86d53dc9..a42771dfb6 100644
--- a/lib/kernel/src/file.erl
+++ b/lib/kernel/src/file.erl
@@ -1,19 +1,19 @@
%%
%% %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
%% 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(file).
@@ -73,6 +73,7 @@
%% data types
-type filename() :: string().
+-type file_info() :: #file_info{}.
-type io_device() :: pid() | #file_descriptor{}.
-type location() :: integer() | {'bof', integer()} | {'cur', integer()}
| {'eof', integer()} | 'bof' | 'cur' | 'eof'.
diff --git a/lib/kernel/src/gen_sctp.erl b/lib/kernel/src/gen_sctp.erl
index fcd1d1564a..5a31e3976f 100644
--- a/lib/kernel/src/gen_sctp.erl
+++ b/lib/kernel/src/gen_sctp.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2007-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 2007-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%
%%
@@ -27,7 +27,7 @@
-include("inet_sctp.hrl").
-export([open/0,open/1,open/2,close/1]).
--export([listen/2,connect/4,connect/5]).
+-export([listen/2,connect/4,connect/5,connect_init/4,connect_init/5]).
-export([eof/2,abort/2]).
-export([send/3,send/4,recv/1,recv/2]).
-export([error_string/1]).
@@ -80,7 +80,26 @@ listen(S, Flag) ->
connect(S, Addr, Port, Opts) ->
connect(S, Addr, Port, Opts, infinity).
-connect(S, Addr, Port, Opts, Timeout) when is_port(S), is_list(Opts) ->
+connect(S, Addr, Port, Opts, Timeout) ->
+ case do_connect(S, Addr, Port, Opts, Timeout, true) of
+ badarg ->
+ erlang:error(badarg, [S,Addr,Port,Opts,Timeout]);
+ Result ->
+ Result
+ end.
+
+connect_init(S, Addr, Port, Opts) ->
+ connect_init(S, Addr, Port, Opts, infinity).
+
+connect_init(S, Addr, Port, Opts, Timeout) ->
+ case do_connect(S, Addr, Port, Opts, Timeout, false) of
+ badarg ->
+ erlang:error(badarg, [S,Addr,Port,Opts,Timeout]);
+ Result ->
+ Result
+ end.
+
+do_connect(S, Addr, Port, Opts, Timeout, ConnWait) when is_port(S), is_list(Opts) ->
case inet_db:lookup_socket(S) of
{ok,Mod} ->
case Mod:getserv(Port) of
@@ -89,21 +108,26 @@ connect(S, Addr, Port, Opts, Timeout) when is_port(S), is_list(Opts) ->
Timer ->
try Mod:getaddr(Addr, Timer) of
{ok,IP} ->
- Mod:connect(S, IP, Port, Opts, Timer);
+ ConnectTimer = if ConnWait == false ->
+ nowait;
+ true ->
+ Timer
+ end,
+ Mod:connect(S, IP, Port, Opts, ConnectTimer);
Error -> Error
after
inet:stop_timer(Timer)
end
catch
error:badarg ->
- erlang:error(badarg, [S,Addr,Port,Opts,Timeout])
+ badarg
end;
Error -> Error
end;
Error -> Error
end;
-connect(S, Addr, Port, Opts, Timeout) ->
- erlang:error(badarg, [S,Addr,Port,Opts,Timeout]).
+do_connect(_S, _Addr, _Port, _Opts, _Timeout, _ConnWait) ->
+ badarg.
diff --git a/lib/kernel/src/hipe_unified_loader.erl b/lib/kernel/src/hipe_unified_loader.erl
index 7e26d57ced..f289b8110d 100644
--- a/lib/kernel/src/hipe_unified_loader.erl
+++ b/lib/kernel/src/hipe_unified_loader.erl
@@ -103,10 +103,15 @@ load_native_code(Mod, Bin) when is_atom(Mod), is_binary(Bin) ->
case code:get_chunk(Bin, ChunkTag) of
undefined -> no_native;
NativeCode when is_binary(NativeCode) ->
- OldReferencesToPatch = patch_to_emu_step1(Mod),
- case load_module(Mod, NativeCode, Bin, OldReferencesToPatch) of
- bad_crc -> no_native;
- Result -> Result
+ erlang:system_flag(multi_scheduling, block),
+ try
+ OldReferencesToPatch = patch_to_emu_step1(Mod),
+ case load_module(Mod, NativeCode, Bin, OldReferencesToPatch) of
+ bad_crc -> no_native;
+ Result -> Result
+ end
+ after
+ erlang:system_flag(multi_scheduling, unblock)
end
end
catch
@@ -121,8 +126,17 @@ load_native_code(Mod, Bin) when is_atom(Mod), is_binary(Bin) ->
post_beam_load(Mod) when is_atom(Mod) ->
Architecture = erlang:system_info(hipe_architecture),
- try chunk_name(Architecture) of _ChunkTag -> patch_to_emu(Mod)
- catch _:_ -> ok
+ try chunk_name(Architecture) of
+ _ChunkTag ->
+ erlang:system_flag(multi_scheduling, block),
+ try
+ patch_to_emu(Mod)
+ after
+ erlang:system_flag(multi_scheduling, unblock)
+ end
+ catch
+ _:_ ->
+ ok
end.
%%========================================================================
@@ -141,6 +155,14 @@ version_check(Version, Mod) when is_atom(Mod) ->
-spec load_module(Mod, binary(), _) -> 'bad_crc' | {'module',Mod}
when is_subtype(Mod,atom()).
load_module(Mod, Bin, Beam) ->
+ erlang:system_flag(multi_scheduling, block),
+ try
+ load_module_nosmp(Mod, Bin, Beam)
+ after
+ erlang:system_flag(multi_scheduling, unblock)
+ end.
+
+load_module_nosmp(Mod, Bin, Beam) ->
load_module(Mod, Bin, Beam, []).
load_module(Mod, Bin, Beam, OldReferencesToPatch) ->
@@ -154,6 +176,14 @@ load_module(Mod, Bin, Beam, OldReferencesToPatch) ->
-spec load(Mod, binary()) -> 'bad_crc' | {'module',Mod}
when is_subtype(Mod,atom()).
load(Mod, Bin) ->
+ erlang:system_flag(multi_scheduling, block),
+ try
+ load_nosmp(Mod, Bin)
+ after
+ erlang:system_flag(multi_scheduling, unblock)
+ end.
+
+load_nosmp(Mod, Bin) ->
?debug_msg("********* Loading funs in module ~w *********\n",[Mod]),
%% Loading just some functions in a module; patch closures separately.
put(hipe_patch_closures, true),
diff --git a/lib/kernel/src/inet.erl b/lib/kernel/src/inet.erl
index b86aa1839e..eb503235d8 100644
--- a/lib/kernel/src/inet.erl
+++ b/lib/kernel/src/inet.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(inet).
@@ -45,6 +45,7 @@
%% resolve
-export([gethostbyname/1, gethostbyname/2, gethostbyname/3,
gethostbyname_tm/3]).
+-export([gethostbyname_string/2, gethostbyname_self/2]).
-export([gethostbyaddr/1, gethostbyaddr/2,
gethostbyaddr_tm/2]).
@@ -411,7 +412,17 @@ gethostbyname(Name,Family,Timeout) ->
Res.
gethostbyname_tm(Name,Family,Timer) ->
- gethostbyname_tm(Name,Family,Timer,inet_db:res_option(lookup)).
+ Opts0 = inet_db:res_option(lookup),
+ Opts =
+ case (lists:member(native, Opts0) orelse
+ lists:member(string, Opts0) orelse
+ lists:member(nostring, Opts0)) of
+ true ->
+ Opts0;
+ false ->
+ [string|Opts0]
+ end,
+ gethostbyname_tm(Name, Family, Timer, Opts).
-spec gethostbyaddr(Address :: string() | ip_address()) ->
@@ -850,75 +861,61 @@ getaddrs_tm(Address, Family, Timer) ->
%%
%% gethostbyname with option search
%%
-gethostbyname_tm(Name, Type, Timer, [dns | Opts]) ->
- Res = inet_res:gethostbyname_tm(Name, Type, Timer),
- case Res of
- {ok,_} -> Res;
- {error,timeout} -> Res;
- {error,formerr} -> {error,einval};
- {error,_} -> gethostbyname_tm(Name,Type,Timer,Opts)
- end;
-gethostbyname_tm(Name, Type, Timer, [file | Opts]) ->
- case inet_hosts:gethostbyname(Name, Type) of
- {error,formerr} -> {error,einval};
- {error,_} -> gethostbyname_tm(Name,Type,Timer,Opts);
- Result -> Result
- end;
-gethostbyname_tm(Name, Type, Timer, [yp | Opts]) ->
+gethostbyname_tm(Name, Type, Timer, [string|_]=Opts) ->
+ Result = gethostbyname_string(Name, Type),
+ gethostbyname_tm(Name, Type, Timer, Opts, Result);
+gethostbyname_tm(Name, Type, Timer, [dns|_]=Opts) ->
+ Result = inet_res:gethostbyname_tm(Name, Type, Timer),
+ gethostbyname_tm(Name, Type, Timer, Opts, Result);
+gethostbyname_tm(Name, Type, Timer, [file|_]=Opts) ->
+ Result = inet_hosts:gethostbyname(Name, Type),
+ gethostbyname_tm(Name, Type, Timer, Opts, Result);
+gethostbyname_tm(Name, Type, Timer, [yp|_]=Opts) ->
gethostbyname_tm_native(Name, Type, Timer, Opts);
-gethostbyname_tm(Name, Type, Timer, [nis | Opts]) ->
+gethostbyname_tm(Name, Type, Timer, [nis|_]=Opts) ->
gethostbyname_tm_native(Name, Type, Timer, Opts);
-gethostbyname_tm(Name, Type, Timer, [nisplus | Opts]) ->
+gethostbyname_tm(Name, Type, Timer, [nisplus|_]=Opts) ->
gethostbyname_tm_native(Name, Type, Timer, Opts);
-gethostbyname_tm(Name, Type, Timer, [wins | Opts]) ->
+gethostbyname_tm(Name, Type, Timer, [wins|_]=Opts) ->
gethostbyname_tm_native(Name, Type, Timer, Opts);
-gethostbyname_tm(Name, Type, Timer, [native | Opts]) ->
+gethostbyname_tm(Name, Type, Timer, [native|_]=Opts) ->
gethostbyname_tm_native(Name, Type, Timer, Opts);
-gethostbyname_tm(_, _, _, [no_default|_]) ->
- %% If the native resolver has failed, we should not bother
- %% to try to be smarter and parse the IP address here.
- {error,nxdomain};
-gethostbyname_tm(Name, Type, Timer, [_ | Opts]) ->
+gethostbyname_tm(Name, Type, Timer, [_|_]=Opts) ->
gethostbyname_tm(Name, Type, Timer, Opts);
-%% Last resort - parse the hostname as address
-gethostbyname_tm(Name, inet, _Timer, []) ->
- case inet_parse:ipv4_address(Name) of
- {ok,IP4} ->
- {ok,make_hostent(Name, [IP4], [], inet)};
- _ ->
- gethostbyname_self(Name)
- end;
-gethostbyname_tm(Name, inet6, _Timer, []) ->
- case inet_parse:ipv6_address(Name) of
- {ok,IP6} ->
- {ok,make_hostent(Name, [IP6], [], inet6)};
- _ ->
- %% Even if Name is a valid IPv4 address, we can't
- %% assume it's correct to return it on a IPv6
- %% format ( {0,0,0,0,0,16#ffff,?u16(A,B),?u16(C,D)} ).
- %% This host might not support IPv6.
- gethostbyname_self(Name)
+%% Make sure we always can look up our own hostname.
+gethostbyname_tm(Name, Type, Timer, []) ->
+ Result = gethostbyname_self(Name, Type),
+ gethostbyname_tm(Name, Type, Timer, [], Result).
+
+gethostbyname_tm(Name, Type, Timer, Opts, Result) ->
+ case Result of
+ {ok,_} ->
+ Result;
+ {error,formerr} ->
+ {error,einval};
+ {error,_} when Opts =:= [] ->
+ {error,nxdomain};
+ {error,_} ->
+ gethostbyname_tm(Name, Type, Timer, tl(Opts))
end.
gethostbyname_tm_native(Name, Type, Timer, Opts) ->
%% Fixme: add (global) timeout to gethost_native
- case inet_gethost_native:gethostbyname(Name, Type) of
- {error,formerr} -> {error,einval};
- {error,timeout} -> {error,timeout};
- {error,_} -> gethostbyname_tm(Name, Type, Timer, Opts++[no_default]);
- Result -> Result
- end.
+ Result = inet_gethost_native:gethostbyname(Name, Type),
+ gethostbyname_tm(Name, Type, Timer, Opts, Result).
-%% Make sure we always can look up our own hostname.
-gethostbyname_self(Name) ->
- Type = case inet_db:res_option(inet6) of
- true -> inet6;
- false -> inet
- end,
+
+
+gethostbyname_self(Name, Type) when is_atom(Name) ->
+ gethostbyname_self(atom_to_list(Name), Type);
+gethostbyname_self(Name, Type)
+ when is_list(Name), Type =:= inet;
+ is_list(Name), Type =:= inet6 ->
case inet_db:gethostname() of
Name ->
- {ok,make_hostent(Name, [translate_ip(loopback, Type)],
- [], Type)};
+ {ok,make_hostent(Name,
+ [translate_ip(loopback, Type)],
+ [], Type)};
Self ->
case inet_db:res_option(domain) of
"" -> {error,nxdomain};
@@ -931,7 +928,31 @@ gethostbyname_self(Name) ->
_ -> {error,nxdomain}
end
end
- end.
+ end;
+gethostbyname_self(_, _) ->
+ {error,formerr}.
+
+gethostbyname_string(Name, Type) when is_atom(Name) ->
+ gethostbyname_string(atom_to_list(Name), Type);
+gethostbyname_string(Name, Type)
+ when is_list(Name), Type =:= inet;
+ is_list(Name), Type =:= inet6 ->
+ case
+ case Type of
+ inet ->
+ inet_parse:ipv4_address(Name);
+ inet6 ->
+ %% XXX should we really translate IPv4 addresses here
+ %% even if we do not know if this host can do IPv6?
+ inet_parse:ipv6_address(Name)
+ end of
+ {ok,IP} ->
+ {ok,make_hostent(Name, [IP], [], Type)};
+ {error,einval} ->
+ {error,nxdomain}
+ end;
+gethostbyname_string(_, _) ->
+ {error,formerr}.
make_hostent(Name, Addrs, Aliases, Type) ->
#hostent{h_name = Name,
diff --git a/lib/kernel/src/inet_config.erl b/lib/kernel/src/inet_config.erl
index b5317f72f5..311e6bc9f9 100644
--- a/lib/kernel/src/inet_config.erl
+++ b/lib/kernel/src/inet_config.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(inet_config).
@@ -130,21 +130,25 @@ init() ->
{unix,_} ->
%% The Etc variable enables us to run tests with other
%% configuration files than the normal ones
- Etc = case os:getenv("ERL_INET_ETC_DIR") of
- false -> ?DEFAULT_ETC;
- _EtcDir ->
- _EtcDir
- end,
+ Etc =
+ case os:getenv("ERL_INET_ETC_DIR") of
+ false ->
+ ?DEFAULT_ETC;
+ _EtcDir ->
+ _EtcDir
+ end,
case inet_db:res_option(resolv_conf) of
undefined ->
- inet_db:set_resolv_conf(filename:join(Etc,
- ?DEFAULT_RESOLV));
+ inet_db:res_option(
+ resolv_conf_name,
+ filename:join(Etc, ?DEFAULT_RESOLV));
_ -> ok
end,
case inet_db:res_option(hosts_file) of
undefined ->
- inet_db:set_hosts_file(filename:join(Etc,
- ?DEFAULT_HOSTS));
+ inet_db:res_option(
+ hosts_file_name,
+ filename:join(Etc, ?DEFAULT_HOSTS));
_ -> ok
end;
_ -> ok
diff --git a/lib/kernel/src/inet_db.erl b/lib/kernel/src/inet_db.erl
index 211847014f..a05b380855 100644
--- a/lib/kernel/src/inet_db.erl
+++ b/lib/kernel/src/inet_db.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%
%%
@@ -425,7 +425,9 @@ res_optname(usevc) -> res_usevc;
res_optname(edns) -> res_edns;
res_optname(udp_payload_size) -> res_udp_payload_size;
res_optname(resolv_conf) -> res_resolv_conf;
+res_optname(resolv_conf_name) -> res_resolv_conf;
res_optname(hosts_file) -> res_hosts_file;
+res_optname(hosts_file_name) -> res_hosts_file;
res_optname(_) -> undefined.
res_check_option(nameserver, NSs) -> %% Legacy
@@ -458,9 +460,15 @@ res_check_option(udp_payload_size, S) when is_integer(S), S >= 512 -> true;
res_check_option(resolv_conf, "") -> true;
res_check_option(resolv_conf, F) ->
res_check_option_absfile(F);
+res_check_option(resolv_conf_name, "") -> true;
+res_check_option(resolv_conf_name, F) ->
+ res_check_option_absfile(F);
res_check_option(hosts_file, "") -> true;
res_check_option(hosts_file, F) ->
res_check_option_absfile(F);
+res_check_option(hosts_file_name, "") -> true;
+res_check_option(hosts_file_name, F) ->
+ res_check_option_absfile(F);
res_check_option(_, _) -> false.
res_check_option_absfile(F) ->
@@ -503,7 +511,7 @@ res_update_hosts() ->
res_update(res_hosts_file, res_hosts_file_tm, res_hosts_file_info,
set_hosts_file_tm, fun set_hosts_file/1).
-res_update(Tag, TagTm, TagInfo, CallTag, SetFun) ->
+res_update(Tag, TagTm, TagInfo, TagSetTm, SetFun) ->
case db_get(TagTm) of
undefined -> ok;
TM ->
@@ -522,12 +530,12 @@ res_update(Tag, TagTm, TagInfo, CallTag, SetFun) ->
atime = undefined},
case db_get(TagInfo) of
Finfo ->
- call({CallTag, Now});
+ call({TagSetTm, Now});
_ ->
SetFun(File)
end;
_ ->
- call({CallTag, Now}),
+ call({TagSetTm, Now}),
error
end
end;
@@ -974,37 +982,55 @@ handle_call(Request, From, #state{db=Db}=State) ->
{reply, error, State}
end;
+ {res_set, hosts_file_name=Option, Fname} ->
+ handle_set_file(
+ Option, Fname, res_hosts_file_tm, res_hosts_file_info,
+ undefined, From, State);
+ {res_set, resolv_conf_name=Option, Fname} ->
+ handle_set_file(
+ Option, Fname, res_resolv_conf_tm, res_resolv_conf_info,
+ undefined, From, State);
+
{res_set, hosts_file=Option, Fname} ->
- handle_set_file(Option, Fname,
- res_hosts_file_tm, res_hosts_file_info,
- fun (Bin) ->
- case inet_parse:hosts(Fname,
- {chars,Bin}) of
- {ok,Opts} ->
- [{load_hosts_file,Opts}];
- _ -> error
- end
- end,
- From, State);
+ handle_set_file(
+ Option, Fname, res_hosts_file_tm, res_hosts_file_info,
+ fun (Bin) ->
+ case inet_parse:hosts(
+ Fname, {chars,Bin}) of
+ {ok,Opts} ->
+ [{load_hosts_file,Opts}];
+ _ -> error
+ end
+ end,
+ From, State);
%%
{res_set, resolv_conf=Option, Fname} ->
- handle_set_file(Option, Fname,
- res_resolv_conf_tm, res_resolv_conf_info,
- fun (Bin) ->
- case inet_parse:resolv(Fname,
- {chars,Bin}) of
- {ok,Opts} ->
- [del_ns,
- clear_search,
- clear_cache
- |[Opt ||
- {T,_}=Opt <- Opts,
- (T =:= nameserver orelse
- T =:= search)]];
- _ -> error
- end
- end,
- From, State);
+ handle_set_file(
+ Option, Fname, res_resolv_conf_tm, res_resolv_conf_info,
+ fun (Bin) ->
+ case inet_parse:resolv(
+ Fname, {chars,Bin}) of
+ {ok,Opts} ->
+ Search =
+ lists:foldl(
+ fun ({search,L}, _) ->
+ L;
+ ({domain,""}, S) ->
+ S;
+ ({domain,D}, _) ->
+ [D];
+ (_, S) ->
+ S
+ end, [], Opts),
+ [del_ns,
+ clear_search,
+ clear_cache,
+ {search,Search}
+ |[Opt || {nameserver,_}=Opt <- Opts]];
+ _ -> error
+ end
+ end,
+ From, State);
%%
{res_set, Opt, Value} ->
case res_optname(Opt) of
@@ -1156,6 +1182,12 @@ handle_set_file(Option, Fname, TagTm, TagInfo, ParseFun, From,
ets:delete(Db, TagInfo),
ets:delete(Db, TagTm),
handle_set_file(ParseFun, <<>>, From, State);
+ true when ParseFun =:= undefined ->
+ File = filename:flatten(Fname),
+ ets:insert(Db, {res_optname(Option), File}),
+ ets:insert(Db, {TagInfo, undefined}),
+ ets:insert(Db, {TagTm, 0}),
+ {reply,ok,State};
true ->
File = filename:flatten(Fname),
ets:insert(Db, {res_optname(Option), File}),
@@ -1178,7 +1210,8 @@ handle_set_file(Option, Fname, TagTm, TagInfo, ParseFun, From,
handle_set_file(ParseFun, Bin, From, State) ->
case ParseFun(Bin) of
- error -> {reply,error,State};
+ error ->
+ {reply,error,State};
Opts ->
handle_rc_list(Opts, From, State)
end.
diff --git a/lib/kernel/src/inet_gethost_native.erl b/lib/kernel/src/inet_gethost_native.erl
index abdbe2b8cf..fabe9bf8b3 100644
--- a/lib/kernel/src/inet_gethost_native.erl
+++ b/lib/kernel/src/inet_gethost_native.erl
@@ -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%
%%
-module(inet_gethost_native).
@@ -443,19 +443,23 @@ gethostbyname(Name) ->
gethostbyname(Name, inet).
gethostbyname(Name, inet) when is_list(Name) ->
- getit(?OP_GETHOSTBYNAME, ?PROTO_IPV4, Name);
+ getit(?OP_GETHOSTBYNAME, ?PROTO_IPV4, Name, Name);
gethostbyname(Name, inet6) when is_list(Name) ->
- getit(?OP_GETHOSTBYNAME, ?PROTO_IPV6, Name);
+ getit(?OP_GETHOSTBYNAME, ?PROTO_IPV6, Name, Name);
gethostbyname(Name, Type) when is_atom(Name) ->
gethostbyname(atom_to_list(Name), Type);
gethostbyname(_, _) ->
{error, formerr}.
-gethostbyaddr({A,B,C,D}) when ?VALID_V4(A), ?VALID_V4(B), ?VALID_V4(C), ?VALID_V4(D) ->
- getit(?OP_GETHOSTBYADDR, ?PROTO_IPV4, <<A,B,C,D>>);
-gethostbyaddr({A,B,C,D,E,F,G,H}) when ?VALID_V6(A), ?VALID_V6(B), ?VALID_V6(C), ?VALID_V6(D),
- ?VALID_V6(E), ?VALID_V6(F), ?VALID_V6(G), ?VALID_V6(H) ->
- getit(?OP_GETHOSTBYADDR, ?PROTO_IPV6, <<A:16,B:16,C:16,D:16,E:16,F:16,G:16,H:16>>);
+gethostbyaddr({A,B,C,D}=Addr)
+ when ?VALID_V4(A), ?VALID_V4(B), ?VALID_V4(C), ?VALID_V4(D) ->
+ getit(?OP_GETHOSTBYADDR, ?PROTO_IPV4, <<A,B,C,D>>, Addr);
+gethostbyaddr({A,B,C,D,E,F,G,H}=Addr)
+ when ?VALID_V6(A), ?VALID_V6(B), ?VALID_V6(C), ?VALID_V6(D),
+ ?VALID_V6(E), ?VALID_V6(F), ?VALID_V6(G), ?VALID_V6(H) ->
+ getit
+ (?OP_GETHOSTBYADDR, ?PROTO_IPV6,
+ <<A:16,B:16,C:16,D:16,E:16,F:16,G:16,H:16>>, Addr);
gethostbyaddr(Addr) when is_list(Addr) ->
case inet_parse:address(Addr) of
{ok, IP} -> gethostbyaddr(IP);
@@ -466,30 +470,30 @@ gethostbyaddr(Addr) when is_atom(Addr) ->
gethostbyaddr(_) -> {error, formerr}.
control({debug_level, Level}) when is_integer(Level) ->
- getit(?OP_CONTROL, ?SETOPT_DEBUG_LEVEL, <<Level:32>>);
+ getit(?OP_CONTROL, ?SETOPT_DEBUG_LEVEL, <<Level:32>>, undefined);
control(soft_restart) ->
- getit(restart_port);
+ getit(restart_port, undefined);
control(_) -> {error, formerr}.
-getit(Op, Proto, Data) ->
- getit({Op, Proto, Data}).
+getit(Op, Proto, Data, DefaultName) ->
+ getit({Op, Proto, Data}, DefaultName).
-getit(Req) ->
+getit(Req, DefaultName) ->
Pid = ensure_started(),
Ref = make_ref(),
Pid ! {{self(),Ref}, Req},
receive
{Ref, {ok,BinHostent}} ->
- parse_address(BinHostent);
- {Ref, Error} ->
- Error
+ parse_address(BinHostent, DefaultName);
+ {Ref, Result} ->
+ Result
after 5000 ->
Ref2 = erlang:monitor(process,Pid),
Res2 = receive
{Ref, {ok,BinHostent}} ->
- parse_address(BinHostent);
- {Ref, Error} ->
- Error;
+ parse_address(BinHostent, DefaultName);
+ {Ref, Result} ->
+ Result;
{'DOWN', Ref2, process,
Pid, Reason} ->
{error, Reason}
@@ -546,21 +550,23 @@ ensure_started() ->
Pid
end.
-parse_address(BinHostent) ->
+parse_address(BinHostent, DefaultName) ->
case catch
begin
case BinHostent of
<<?UNIT_ERROR, Errstring/binary>> ->
{error, list_to_atom(listify(Errstring))};
<<?UNIT_IPV4, Naddr:32, T0/binary>> ->
- {T1,Addresses} = pick_addresses_v4(Naddr, T0),
- [Name | Names] = pick_names(T1),
+ {T1, Addresses} = pick_addresses_v4(Naddr, T0),
+ {Name, Names} =
+ expand_default_name(pick_names(T1), DefaultName),
{ok, #hostent{h_addr_list = Addresses, h_addrtype = inet,
h_aliases = Names, h_length = ?UNIT_IPV4,
h_name = Name}};
<<?UNIT_IPV6, Naddr:32, T0/binary>> ->
- {T1,Addresses} = pick_addresses_v6(Naddr, T0),
- [Name | Names] = pick_names(T1),
+ {T1, Addresses} = pick_addresses_v6(Naddr, T0),
+ {Name, Names} =
+ expand_default_name(pick_names(T1), DefaultName),
{ok, #hostent{h_addr_list = Addresses, h_addrtype = inet6,
h_aliases = Names, h_length = ?UNIT_IPV6,
h_name = Name}};
@@ -573,7 +579,15 @@ parse_address(BinHostent) ->
Normal ->
Normal
end.
-
+
+expand_default_name([], DefaultName) when is_list(DefaultName) ->
+ {DefaultName, []};
+expand_default_name([], DefaultName) when is_tuple(DefaultName) ->
+ {inet_parse:ntoa(DefaultName), []};
+expand_default_name([Name|Names], DefaultName)
+ when is_list(DefaultName); is_tuple(DefaultName) ->
+ {Name, Names}.
+
listify(Bin) ->
N = byte_size(Bin) - 1,
<<Bin2:N/binary, Ch>> = Bin,
diff --git a/lib/kernel/src/inet_parse.erl b/lib/kernel/src/inet_parse.erl
index 62d44fb723..3bd5fa0958 100644
--- a/lib/kernel/src/inet_parse.erl
+++ b/lib/kernel/src/inet_parse.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(inet_parse).
@@ -34,6 +34,7 @@
-export([nsswitch_conf/1, nsswitch_conf/2]).
-export([ipv4_address/1, ipv6_address/1]).
+-export([ipv4strict_address/1, ipv6strict_address/1]).
-export([address/1]).
-export([visible_string/1, domain/1]).
-export([ntoa/1, dots/1]).
@@ -456,17 +457,15 @@ is_dom2(_) ->
%%
-%% Test ipv4 address or ipv6 address
+%% Parse ipv4 address or ipv6 address
%% Return {ok, Address} | {error, Reason}
%%
address(Cs) when is_list(Cs) ->
case ipv4_address(Cs) of
- {ok,IP} -> {ok,IP};
+ {ok,IP} ->
+ {ok,IP};
_ ->
- case ipv6_address(Cs) of
- {ok, IP} -> {ok, IP};
- Error -> Error
- end
+ ipv6strict_address(Cs)
end;
address(_) ->
{error, einval}.
@@ -477,49 +476,145 @@ address(_) ->
%% d1.d2.d4
%% d1.d4
%% d4
+%% Any d may be octal, hexadecimal or decimal by C language standards.
+%% d4 fills all LSB bytes. This is legacy behaviour from Solaris
+%% and FreeBSD. And partly Linux that behave the same except
+%% it does not accept hexadecimal.
%%
%% Return {ok, IP} | {error, einval}
%%
ipv4_address(Cs) ->
- case catch ipv4_addr(Cs) of
- {'EXIT',_} -> {error,einval};
- Addr -> {ok,Addr}
+ try ipv4_addr(Cs) of
+ Addr ->
+ {ok,Addr}
+ catch
+ error:badarg ->
+ {error,einval}
end.
-ipv4_addr(Cs) ->
- ipv4_addr(d3(Cs), []).
+ipv4_addr(Cs) ->
+ case ipv4_addr(Cs, []) of
+ [D] when D < (1 bsl 32) ->
+ <<D1,D2,D3,D4>> = <<D:32>>,
+ {D1,D2,D3,D4};
+ [D,D1] when D < (1 bsl 24), D1 < 256 ->
+ <<D2,D3,D4>> = <<D:24>>,
+ {D1,D2,D3,D4};
+ [D,D2,D1] when D < (1 bsl 16), (D2 bor D1) < 256 ->
+ <<D3,D4>> = <<D:16>>,
+ {D1,D2,D3,D4};
+ [D4,D3,D2,D1] when (D4 bor D3 bor D2 bor D1) < 256 ->
+ {D1,D2,D3,D4};
+ _ ->
+ erlang:error(badarg)
+ end.
-ipv4_addr({Cs0,[]}, A) when length(A) =< 3 ->
- case [tod(Cs0)|A] of
- [D4,D3,D2,D1] ->
+ipv4_addr([_|_], [_,_,_,_]) ->
+ %% Early bailout for extra characters
+ erlang:error(badarg);
+ipv4_addr("0x"++Cs, Ds) ->
+ ipv4_addr(strip0(Cs), Ds, [], 16, 8);
+ipv4_addr("0X"++Cs, Ds) ->
+ ipv4_addr(strip0(Cs), Ds, [], 16, 8);
+ipv4_addr("0"++Cs, Ds) ->
+ ipv4_addr(strip0(Cs), Ds, [$0], 8, 11);
+ipv4_addr(Cs, Ds) when is_list(Cs) ->
+ ipv4_addr(Cs, Ds, [], 10, 10).
+
+ipv4_addr(Cs0, Ds, Rs, Base, N) ->
+ case ipv4_field(Cs0, N, Rs, Base) of
+ {D,""} ->
+ [D|Ds];
+ {D,[$.|[_|_]=Cs]} ->
+ ipv4_addr(Cs, [D|Ds]);
+ {_,_} ->
+ erlang:error(badarg)
+ end.
+
+strip0("0"++Cs) ->
+ strip0(Cs);
+strip0(Cs) when is_list(Cs) ->
+ Cs.
+
+
+%%
+%% Parse IPv4 strict dotted decimal address, no leading zeros:
+%% d1.d2.d3.d4
+%%
+%% Return {ok, IP} | {error, einval}
+%%
+ipv4strict_address(Cs) ->
+ try ipv4strict_addr(Cs) of
+ Addr ->
+ {ok,Addr}
+ catch
+ error:badarg ->
+ {error,einval}
+ end.
+
+ipv4strict_addr(Cs) ->
+ case ipv4strict_addr(Cs, []) of
+ [D4,D3,D2,D1] when (D4 bor D3 bor D2 bor D1) < 256 ->
{D1,D2,D3,D4};
- [D4,D2,D1] ->
- {D1,D2,0,D4};
- [D4,D1] ->
- {D1,0,0,D4};
- [D4] ->
- {0,0,0,D4}
- end;
-ipv4_addr({Cs0,"."++Cs1}, A) when length(A) =< 2 ->
- ipv4_addr(d3(Cs1), [tod(Cs0)|A]).
+ _ ->
+ erlang:error(badarg)
+ end.
+
+ipv4strict_addr([_|_], [_,_,_,_]) ->
+ %% Early bailout for extra characters
+ erlang:error(badarg);
+ipv4strict_addr("0", Ds) ->
+ [0|Ds];
+ipv4strict_addr("0."++Cs, Ds) ->
+ ipv4strict_addr(Cs, [0|Ds]);
+ipv4strict_addr(Cs0, Ds) when is_list(Cs0) ->
+ case ipv4_field(Cs0, 3, [], 10) of
+ {D,""} ->
+ [D|Ds];
+ {D,[$.|[_|_]=Cs]} ->
+ ipv4strict_addr(Cs, [D|Ds]);
+ {_,_} ->
+ erlang:error(badarg)
+ end.
+
-d3(Cs) -> d3(Cs, []).
-d3([C|Cs], R) when C >= $0, C =< $9, length(R) =< 2 ->
- d3(Cs, [C|R]);
-d3(Cs, [_|_]=R) ->
- {lists:reverse(R),Cs}.
+ipv4_field("", _, Rs, Base) ->
+ {ipv4_field(Rs, Base),""};
+ipv4_field("."++_=Cs, _, Rs, Base) ->
+ {ipv4_field(Rs, Base),Cs};
+ipv4_field("0"++_, _, [], _) ->
+ erlang:error(badarg);
+ipv4_field([C|Cs], N, Rs, Base) when N > 0 ->
+ ipv4_field(Cs, N-1, [C|Rs], Base);
+ipv4_field(Cs, _, _, _) when is_list(Cs) ->
+ erlang:error(badarg).
+
+ipv4_field(Rs, Base) ->
+ V = erlang:list_to_integer(lists:reverse(Rs), Base),
+ if V < 0 ->
+ erlang:error(badarg);
+ true ->
+ V
+ end.
-tod(Cs) ->
- case erlang:list_to_integer(Cs) of
- D when D >= 0, D =< 255 ->
- D;
+
+
+%%
+%% Forgiving IPv6 address
+%%
+%% Accepts IPv4 address and returns it as a IPv4 compatible IPv6 address
+%%
+ipv6_address(Cs) ->
+ case ipv4_address(Cs) of
+ {ok,{D1,D2,D3,D4}} ->
+ {ok,{0,0,0,0,0,16#ffff,(D1 bsl 8) bor D2,(D3 bsl 8) bor D4}};
_ ->
- erlang:error(badarg, [Cs])
+ ipv6strict_address(Cs)
end.
%%
-%% Parse IPv6 address:
+%% Parse IPv6 address according to RFC 4291:
%% x1:x2:x3:x4:x5:x6:x7:x8
%% x1:x2::x7:x8
%% ::x7:x8
@@ -530,77 +625,89 @@ tod(Cs) ->
%% ::x5:x6:d7a.d7b.d8a.d8b
%% x1:x2::d7a.d7b.d8a.d8b
%% ::d7a.d7b.d8a.d8b
+%% etc
%%
%% Return {ok, IP} | {error, einval}
%%
-ipv6_address(Cs) ->
- case catch ipv6_addr(Cs) of
- {'EXIT',_} -> {error,einval};
- Addr -> {ok,Addr}
+ipv6strict_address(Cs) ->
+ try ipv6_addr(Cs) of
+ Addr ->
+ {ok,Addr}
+ catch
+ error:badarg ->
+ {error,einval}
end.
ipv6_addr("::") ->
- ipv6_addr_done([], []);
+ ipv6_addr_done([], [], 0);
ipv6_addr("::"++Cs) ->
- ipv6_addr(x4(Cs), [], []);
+ ipv6_addr(hex(Cs), [], [], 0);
ipv6_addr(Cs) ->
- ipv6_addr(x4(Cs), []).
+ ipv6_addr(hex(Cs), [], 0).
%% Before "::"
-ipv6_addr({Cs0,[]}, A) when length(A) =:= 7 ->
- ipv6_addr_done([tox(Cs0)|A]);
-ipv6_addr({Cs0,"::"}, A) when length(A) =< 6 ->
- ipv6_addr_done([tox(Cs0)|A], []);
-ipv6_addr({Cs0,"::"++Cs1}, A) when length(A) =< 5 ->
- ipv6_addr(x4(Cs1), [tox(Cs0)|A], []);
-ipv6_addr({Cs0,":"++Cs1}, A) when length(A) =< 6 ->
- ipv6_addr(x4(Cs1), [tox(Cs0)|A]);
-ipv6_addr({Cs0,"."++Cs1}, A) when length(A) =:= 6 ->
- ipv6_addr(d3(Cs1), A, [], [tod(Cs0)]).
+ipv6_addr({Cs0,[]}, A, N) when N == 7 ->
+ ipv6_addr_done([hex_to_int(Cs0)|A]);
+ipv6_addr({Cs0,"::"}, A, N) when N =< 6 ->
+ ipv6_addr_done([hex_to_int(Cs0)|A], [], N+1);
+ipv6_addr({Cs0,"::"++Cs1}, A, N) when N =< 5 ->
+ ipv6_addr(hex(Cs1), [hex_to_int(Cs0)|A], [], N+1);
+ipv6_addr({Cs0,":"++Cs1}, A, N) when N =< 6 ->
+ ipv6_addr(hex(Cs1), [hex_to_int(Cs0)|A], N+1);
+ipv6_addr({Cs0,"."++_=Cs1}, A, N) when N == 6 ->
+ ipv6_addr_done(A, [], N, ipv4strict_addr(Cs0++Cs1));
+ipv6_addr(_, _, _) ->
+ erlang:error(badarg).
%% After "::"
-ipv6_addr({Cs0,[]}, A, B) when length(A)+length(B) =< 6 ->
- ipv6_addr_done(A, [tox(Cs0)|B]);
-ipv6_addr({Cs0,":"++Cs1}, A, B) when length(A)+length(B) =< 5 ->
- ipv6_addr(x4(Cs1), A, [tox(Cs0)|B]);
-ipv6_addr({Cs0,"."++Cs1}, A, B) when length(A)+length(B) =< 5 ->
- ipv6_addr(x4(Cs1), A, B, [tod(Cs0)]).
+ipv6_addr({Cs0,[]}, A, B, N) when N =< 6 ->
+ ipv6_addr_done(A, [hex_to_int(Cs0)|B], N+1);
+ipv6_addr({Cs0,":"++Cs1}, A, B, N) when N =< 5 ->
+ ipv6_addr(hex(Cs1), A, [hex_to_int(Cs0)|B], N+1);
+ipv6_addr({Cs0,"."++_=Cs1}, A, B, N) when N =< 5 ->
+ ipv6_addr_done(A, B, N, ipv4strict_addr(Cs0++Cs1));
+ipv6_addr(_, _, _, _) ->
+ erlang:error(badarg).
-%% After "."
-ipv6_addr({Cs0,[]}, A, B, C) when length(C) =:= 3 ->
- ipv6_addr_done(A, B, [tod(Cs0)|C]);
-ipv6_addr({Cs0,"."++Cs1}, A, B, C) when length(C) =< 2 ->
- ipv6_addr(d3(Cs1), A, B, [tod(Cs0)|C]).
+ipv6_addr_done(Ar, Br, N, {D1,D2,D3,D4}) ->
+ ipv6_addr_done(Ar, [((D3 bsl 8) bor D4),((D1 bsl 8) bor D2)|Br], N+2).
-ipv6_addr_done(Ar, Br, [D4,D3,D2,D1]) ->
- ipv6_addr_done(Ar, [((D3 bsl 8) bor D4),((D1 bsl 8) bor D2)|Br]).
-
-ipv6_addr_done(Ar, Br) ->
- ipv6_addr_done(Br++dup(8-length(Ar)-length(Br), 0, Ar)).
+ipv6_addr_done(Ar, Br, N) ->
+ ipv6_addr_done(Br++dup(8-N, 0, Ar)).
ipv6_addr_done(Ar) ->
list_to_tuple(lists:reverse(Ar)).
-x4(Cs) -> x4(Cs, []).
-
-x4([C|Cs], R) when C >= $0, C =< $9, length(R) =< 3 ->
- x4(Cs, [C|R]);
-x4([C|Cs], R) when C >= $a, C =< $f, length(R) =< 3 ->
- x4(Cs, [C|R]);
-x4([C|Cs], R) when C >= $A, C =< $F, length(R) =< 3 ->
- x4(Cs, [C|R]);
-x4(Cs, [_|_]=R) ->
- {lists:reverse(R),Cs}.
-
-tox(Cs) ->
- erlang:list_to_integer(Cs, 16).
+%% Collect Hex digits
+hex(Cs) -> hex(Cs, []).
+%%
+hex([C|Cs], R) when C >= $0, C =< $9 ->
+ hex(Cs, [C|R]);
+hex([C|Cs], R) when C >= $a, C =< $f ->
+ hex(Cs, [C|R]);
+hex([C|Cs], R) when C >= $A, C =< $F ->
+ hex(Cs, [C|R]);
+hex(Cs, [_|_]=R) when is_list(Cs) ->
+ {lists:reverse(R),Cs};
+hex(_, _) ->
+ erlang:error(badarg).
+
+%% Hex string to integer
+hex_to_int(Cs0) ->
+ case strip0(Cs0) of
+ Cs when length(Cs) =< 4 ->
+ erlang:list_to_integer("0"++Cs, 16);
+ _ ->
+ erlang:error(badarg)
+ end.
+%% Dup onto head of existing list
dup(0, _, L) ->
L;
dup(N, E, L) when is_integer(N), N >= 1 ->
- dup(N-1, E, [E|L]);
-dup(N, E, L) ->
- erlang:error(badarg, [N,E,L]).
+ dup(N-1, E, [E|L]).
+
+
%% Convert IPv4 adress to ascii
%% Convert IPv6 / IPV4 adress to ascii (plain format)
@@ -674,7 +781,7 @@ separate(_E, [H], R) ->
lists:reverse(R, [H]).
%% convert to A.B decimal form
-dig_to_dec(0) -> [$0,$.,$0];
+dig_to_dec(0) -> "0.0";
dig_to_dec(X) ->
integer_to_list((X bsr 8) band 16#ff) ++ "." ++
integer_to_list(X band 16#ff).
diff --git a/lib/kernel/src/inet_sctp.erl b/lib/kernel/src/inet_sctp.erl
index 30c0e85dd9..795bf83807 100644
--- a/lib/kernel/src/inet_sctp.erl
+++ b/lib/kernel/src/inet_sctp.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2007-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 2007-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%
%%
%% SCTP protocol contribution by Leonid Timochouk and Serge Aleynikov.
@@ -64,16 +64,22 @@ close(S) ->
listen(S, Flag) ->
prim_inet:listen(S, Flag).
+%% A non-blocking connect is implemented when the initial call is to
+%% gen_sctp:connect_init which passes the value nowait as the Timer
connect(S, Addr, Port, Opts, Timer) ->
case prim_inet:chgopts(S, Opts) of
ok ->
case prim_inet:getopt(S, active) of
{ok,Active} ->
- Timeout = inet:timeout(Timer),
+ Timeout = if Timer =:= nowait ->
+ infinity; %% don't start driver timer in inet_drv
+ true ->
+ inet:timeout(Timer)
+ end,
case prim_inet:connect(S, Addr, Port, Timeout) of
- ok ->
+ ok when Timer =/= nowait ->
connect_get_assoc(S, Addr, Port, Active, Timer);
- Err1 -> Err1
+ OkOrErr1 -> OkOrErr1
end;
Err2 -> Err2
end;
@@ -89,10 +95,10 @@ connect(S, Addr, Port, Opts, Timer) ->
%% connect_get_assoc/5 below mistakes it for an invalid response
%% for a socket in {active,false} or {active,once} modes.
%%
-%% In {active,true} mode it probably gets right, but it is
-%% a blocking connect that is implemented even for {active,true},
-%% and that may be a shortcoming. A non-blocking connect
-%% would be nice to have.
+%% In {active,true} mode the window of time for the race is smaller,
+%% but it is possible and also it is a blocking connect that is
+%% implemented even for {active,true}, and that may be a
+%% shortcoming.
connect_get_assoc(S, Addr, Port, false, Timer) ->
case recv(S, inet:timeout(Timer)) of
diff --git a/lib/kernel/src/net_kernel.erl b/lib/kernel/src/net_kernel.erl
index 3afaedf274..9875044844 100644
--- a/lib/kernel/src/net_kernel.erl
+++ b/lib/kernel/src/net_kernel.erl
@@ -1,19 +1,19 @@
%%
%% %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
%% 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(net_kernel).
@@ -354,13 +354,13 @@ init({Name, LongOrShortNames, TickT}) ->
%% The response is delayed until the connection is up and
%% running.
%%
-handle_call({connect, _, Node}, _From, State) when Node =:= node() ->
- {reply, true, State};
+handle_call({connect, _, Node}, From, State) when Node =:= node() ->
+ async_reply({reply, true, State}, From);
handle_call({connect, Type, Node}, From, State) ->
verbose({connect, Type, Node}, 1, State),
case ets:lookup(sys_dist, Node) of
[Conn] when Conn#connection.state =:= up ->
- {reply, true, State};
+ async_reply({reply, true, State}, From);
[Conn] when Conn#connection.state =:= pending ->
Waiting = Conn#connection.waiting,
ets:insert(sys_dist, Conn#connection{waiting = [From|Waiting]}),
@@ -376,19 +376,19 @@ handle_call({connect, Type, Node}, From, State) ->
{noreply,State#state{conn_owners=Owners}};
_ ->
?connect_failure(Node, {setup_call, failed}),
- {reply, false, State}
+ async_reply({reply, false, State}, From)
end
end;
%%
%% Close the connection to Node.
%%
-handle_call({disconnect, Node}, _From, State) when Node =:= node() ->
- {reply, false, State};
-handle_call({disconnect, Node}, _From, State) ->
+handle_call({disconnect, Node}, From, State) when Node =:= node() ->
+ async_reply({reply, false, State}, From);
+handle_call({disconnect, Node}, From, State) ->
verbose({disconnect, Node}, 1, State),
{Reply, State1} = do_disconnect(Node, State),
- {reply, Reply, State1};
+ async_reply({reply, Reply, State1}, From);
%%
%% The spawn/4 BIF ends up here.
@@ -411,39 +411,40 @@ handle_call({spawn_opt,M,F,A,O,L,Gleader},{From,Tag},State) when is_pid(From) ->
%%
%% Only allow certain nodes.
%%
-handle_call({allow, Nodes}, _From, State) ->
+handle_call({allow, Nodes}, From, State) ->
case all_atoms(Nodes) of
true ->
Allowed = State#state.allowed,
- {reply,ok,State#state{allowed = Allowed ++ Nodes}};
+ async_reply({reply,ok,State#state{allowed = Allowed ++ Nodes}},
+ From);
false ->
- {reply,error,State}
+ async_reply({reply,error,State}, From)
end;
%%
%% authentication, used by auth. Simply works as this:
%% if the message comes through, the other node IS authorized.
%%
-handle_call({is_auth, _Node}, _From, State) ->
- {reply,yes,State};
+handle_call({is_auth, _Node}, From, State) ->
+ async_reply({reply,yes,State}, From);
%%
%% Not applicable any longer !?
%%
handle_call({apply,_Mod,_Fun,_Args}, {From,Tag}, State)
when is_pid(From), node(From) =:= node() ->
- gen_server:reply({From,Tag}, not_implemented),
+ async_gen_server_reply({From,Tag}, not_implemented),
% Port = State#state.port,
% catch apply(Mod,Fun,[Port|Args]),
{noreply,State};
-handle_call(longnames, _From, State) ->
- {reply, get(longnames), State};
+handle_call(longnames, From, State) ->
+ async_reply({reply, get(longnames), State}, From);
-handle_call({update_publish_nodes, Ns}, _From, State) ->
- {reply, ok, State#state{publish_on_nodes = Ns}};
+handle_call({update_publish_nodes, Ns}, From, State) ->
+ async_reply({reply, ok, State#state{publish_on_nodes = Ns}}, From);
-handle_call({publish_on_node, Node}, _From, State) ->
+handle_call({publish_on_node, Node}, From, State) ->
NewState = case State#state.publish_on_nodes of
undefined ->
State#state{publish_on_nodes =
@@ -457,11 +458,12 @@ handle_call({publish_on_node, Node}, _From, State) ->
Nodes ->
lists:member(Node, Nodes)
end,
- {reply, Publish, NewState};
+ async_reply({reply, Publish, NewState}, From);
-handle_call({verbose, Level}, _From, State) ->
- {reply, State#state.verbose, State#state{verbose = Level}};
+handle_call({verbose, Level}, From, State) ->
+ async_reply({reply, State#state.verbose, State#state{verbose = Level}},
+ From);
%%
%% Set new ticktime
@@ -471,16 +473,16 @@ handle_call({verbose, Level}, _From, State) ->
%% #tick_change{} record if the ticker process has been upgraded;
%% otherwise, an integer or an atom.
-handle_call(ticktime, _, #state{tick = #tick{time = T}} = State) ->
- {reply, T, State};
-handle_call(ticktime, _, #state{tick = #tick_change{time = T}} = State) ->
- {reply, {ongoing_change_to, T}, State};
+handle_call(ticktime, From, #state{tick = #tick{time = T}} = State) ->
+ async_reply({reply, T, State}, From);
+handle_call(ticktime, From, #state{tick = #tick_change{time = T}} = State) ->
+ async_reply({reply, {ongoing_change_to, T}, State}, From);
-handle_call({new_ticktime,T,_TP}, _, #state{tick = #tick{time = T}} = State) ->
+handle_call({new_ticktime,T,_TP}, From, #state{tick = #tick{time = T}} = State) ->
?tckr_dbg(no_tick_change),
- {reply, unchanged, State};
+ async_reply({reply, unchanged, State}, From);
-handle_call({new_ticktime,T,TP}, _, #state{tick = #tick{ticker = Tckr,
+handle_call({new_ticktime,T,TP}, From, #state{tick = #tick{ticker = Tckr,
time = OT}} = State) ->
?tckr_dbg(initiating_tick_change),
start_aux_ticker(T, OT, TP),
@@ -493,14 +495,15 @@ handle_call({new_ticktime,T,TP}, _, #state{tick = #tick{ticker = Tckr,
?tckr_dbg(shorter_ticktime),
shorter
end,
- {reply, change_initiated, State#state{tick = #tick_change{ticker = Tckr,
- time = T,
- how = How}}};
+ async_reply({reply, change_initiated,
+ State#state{tick = #tick_change{ticker = Tckr,
+ time = T,
+ how = How}}}, From);
-handle_call({new_ticktime,_,_},
- _,
+handle_call({new_ticktime,_T,_TP},
+ From,
#state{tick = #tick_change{time = T}} = State) ->
- {reply, {ongoing_change_to, T}, State}.
+ async_reply({reply, {ongoing_change_to, T}, State}, From).
%% ------------------------------------------------------------
%% handle_cast.
@@ -1063,11 +1066,12 @@ safesend(Pid, Mess) -> Pid ! Mess.
-endif.
do_spawn(SpawnFuncArgs, SpawnOpts, State) ->
+ [_,From|_] = SpawnFuncArgs,
case catch spawn_opt(?MODULE, spawn_func, SpawnFuncArgs, SpawnOpts) of
- {'EXIT', {Reason,_}} ->
- {reply, {'EXIT', {Reason,[]}}, State};
- {'EXIT', Reason} ->
- {reply, {'EXIT', {Reason,[]}}, State};
+ {'EXIT', {Reason,_}} ->
+ async_reply({reply, {'EXIT', {Reason,[]}}, State}, From);
+ {'EXIT', Reason} ->
+ async_reply({reply, {'EXIT', {Reason,[]}}, State}, From);
_ ->
{noreply,State}
end.
@@ -1409,7 +1413,7 @@ reply_waiting(_Node, Waiting, Rep) ->
reply_waiting1(lists:reverse(Waiting), Rep).
reply_waiting1([From|W], Rep) ->
- gen_server:reply(From, Rep),
+ async_gen_server_reply(From, Rep),
reply_waiting1(W, Rep);
reply_waiting1([], _) ->
ok.
@@ -1511,3 +1515,21 @@ verbose(_, _, _) ->
getnode(P) when is_pid(P) -> node(P);
getnode(P) -> P.
+
+async_reply({reply, Msg, State}, From) ->
+ async_gen_server_reply(From, Msg),
+ {noreply, State}.
+
+async_gen_server_reply(From, Msg) ->
+ {Pid, Tag} = From,
+ M = {Tag, Msg},
+ case catch erlang:send(Pid, M, [nosuspend, noconnect]) of
+ ok ->
+ ok;
+ nosuspend ->
+ spawn(fun() -> catch erlang:send(Pid, M, [noconnect]) end);
+ noconnect ->
+ ok; % The gen module takes care of this case.
+ {'EXIT', _}=EXIT ->
+ EXIT
+ end.
diff --git a/lib/kernel/src/os.erl b/lib/kernel/src/os.erl
index 196e6cdeb2..d0b498edc9 100644
--- a/lib/kernel/src/os.erl
+++ b/lib/kernel/src/os.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(os).
@@ -169,6 +169,7 @@ unix_cmd(Cmd) ->
%% $1 parameter for easy identification of the resident shell.
%%
-define(SHELL, "/bin/sh -s unix:cmd 2>&1").
+-define(PORT_CREATOR_NAME, os_cmd_port_creator).
%%
%% Serializing open_port through a process to avoid smp lock contention
@@ -176,18 +177,37 @@ unix_cmd(Cmd) ->
%%
-spec start_port() -> port().
start_port() ->
- {Ref,Client} = {make_ref(),self()},
- try (os_cmd_port_creator ! {Ref,Client})
- catch
- error:_ -> spawn(fun() -> start_port_srv({Ref,Client}) end)
- end,
+ Ref = make_ref(),
+ Request = {Ref,self()},
+ {Pid, Mon} = case whereis(?PORT_CREATOR_NAME) of
+ undefined ->
+ spawn_monitor(fun() ->
+ start_port_srv(Request)
+ end);
+ P ->
+ P ! Request,
+ M = erlang:monitor(process, P),
+ {P, M}
+ end,
receive
- {Ref,Port} when is_port(Port) -> Port;
- {Ref,Error} -> exit(Error)
+ {Ref, Port} when is_port(Port) ->
+ erlang:demonitor(Mon, [flush]),
+ Port;
+ {Ref, Error} ->
+ erlang:demonitor(Mon, [flush]),
+ exit(Error);
+ {'DOWN', Mon, process, Pid, _Reason} ->
+ start_port()
end.
start_port_srv(Request) ->
- StayAlive = try register(os_cmd_port_creator, self())
+ %% We don't want a group leader of some random application. Use
+ %% kernel_sup's group leader.
+ {group_leader, GL} = process_info(whereis(kernel_sup),
+ group_leader),
+ true = group_leader(GL, self()),
+ process_flag(trap_exit, true),
+ StayAlive = try register(?PORT_CREATOR_NAME, self())
catch
error:_ -> false
end,
@@ -196,7 +216,7 @@ start_port_srv(Request) ->
start_port_srv_loop({Ref,Client}, StayAlive) ->
Reply = try open_port({spawn, ?SHELL},[stream]) of
Port when is_port(Port) ->
- port_connect(Port, Client),
+ (catch port_connect(Port, Client)),
unlink(Port),
Port
catch
@@ -205,10 +225,19 @@ start_port_srv_loop({Ref,Client}, StayAlive) ->
end,
Client ! {Ref,Reply},
case StayAlive of
- true -> start_port_srv_loop(receive Msg -> Msg end, true);
+ true -> start_port_srv_loop(get_open_port_request(), true);
false -> exiting
end.
+get_open_port_request() ->
+ receive
+ {Ref, Client} = Request when is_reference(Ref),
+ is_pid(Client) ->
+ Request;
+ _Junk ->
+ get_open_port_request()
+ end.
+
%%
%% unix_get_data(Port) -> Result
%%
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/src/user.erl b/lib/kernel/src/user.erl
index edf650ec59..17dc5a56a2 100644
--- a/lib/kernel/src/user.erl
+++ b/lib/kernel/src/user.erl
@@ -1,19 +1,19 @@
%%
%% %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
%% 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(user).
@@ -698,7 +698,11 @@ get_chars_more(State, M, F, Xa, Port, Q, Fmt) ->
prompt(_Port, '') -> ok;
prompt(Port, Prompt) ->
- put_port(io_lib:format_prompt(Prompt), Port).
+ put_port(wrap_characters_to_binary(io_lib:format_prompt(Prompt),unicode,
+ case get(unicode) of
+ true -> unicode;
+ _ -> latin1
+ end), Port).
%% Convert error code to make it look as before
err_func(io_lib, get_until, {_,F,_}) ->
diff --git a/lib/kernel/test/Makefile b/lib/kernel/test/Makefile
index ffad998d96..293c368e2a 100644
--- a/lib/kernel/test/Makefile
+++ b/lib/kernel/test/Makefile
@@ -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%
#
include $(ERL_TOP)/make/target.mk
@@ -116,7 +116,7 @@ EBIN = .
make_emakefile:
$(ERL_TOP)/make/make_emakefile $(ERL_COMPILE_FLAGS) -o$(EBIN) '*_SUITE_make' \
- >> $(EMAKEFILE)
+ > $(EMAKEFILE)
$(ERL_TOP)/make/make_emakefile $(ERL_COMPILE_FLAGS) -o$(EBIN) $(MODULES) \
>> $(EMAKEFILE)
diff --git a/lib/kernel/test/bif_SUITE.erl b/lib/kernel/test/bif_SUITE.erl
index c78d82659f..ae2a3a08ff 100644
--- a/lib/kernel/test/bif_SUITE.erl
+++ b/lib/kernel/test/bif_SUITE.erl
@@ -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%
%%
-module(bif_SUITE).
@@ -66,7 +66,7 @@ spawn_opt_tests(suite) ->
spawn1(doc) -> ["Test spawn/1"];
spawn1(suite) ->
[];
-spawn1(Config) when list(Config) ->
+spawn1(Config) when is_list(Config) ->
?line Node = node(),
?line Parent = self(),
?line {_, _, FA, _} = fetch_proc_vals(self()),
@@ -83,7 +83,7 @@ spawn1(Config) when list(Config) ->
spawn2(doc) -> ["Test spawn/2"];
spawn2(suite) ->
[];
-spawn2(Config) when list(Config) ->
+spawn2(Config) when is_list(Config) ->
?line {ok, Node} = start_node(spawn2),
?line Parent = self(),
@@ -105,7 +105,7 @@ spawn2(Config) when list(Config) ->
spawn3(doc) -> ["Test spawn/3"];
spawn3(suite) ->
[];
-spawn3(Config) when list(Config) ->
+spawn3(Config) when is_list(Config) ->
?line Node = node(),
?line Parent = self(),
@@ -127,7 +127,7 @@ spawn3(Config) when list(Config) ->
spawn4(doc) -> ["Test spawn/4"];
spawn4(suite) ->
[];
-spawn4(Config) when list(Config) ->
+spawn4(Config) when is_list(Config) ->
?line {ok, Node} = start_node(spawn4),
?line Parent = self(),
@@ -154,7 +154,7 @@ spawn4(Config) when list(Config) ->
spawn_link1(doc) -> ["Test spawn_link/1"];
spawn_link1(suite) ->
[];
-spawn_link1(Config) when list(Config) ->
+spawn_link1(Config) when is_list(Config) ->
?line Node = node(),
?line Parent = self(),
?line {_, _, FA, _} = fetch_proc_vals(self()),
@@ -171,7 +171,7 @@ spawn_link1(Config) when list(Config) ->
spawn_link2(doc) -> ["Test spawn_link/2"];
spawn_link2(suite) ->
[];
-spawn_link2(Config) when list(Config) ->
+spawn_link2(Config) when is_list(Config) ->
?line {ok, Node} = start_node(spawn_link2),
?line Parent = self(),
@@ -192,7 +192,7 @@ spawn_link2(Config) when list(Config) ->
spawn_link3(doc) -> ["Test spawn_link/3"];
spawn_link3(suite) ->
[];
-spawn_link3(Config) when list(Config) ->
+spawn_link3(Config) when is_list(Config) ->
?line Node = node(),
?line Parent = self(),
@@ -214,7 +214,7 @@ spawn_link3(Config) when list(Config) ->
spawn_link4(doc) -> ["Test spawn_link/4"];
spawn_link4(suite) ->
[];
-spawn_link4(Config) when list(Config) ->
+spawn_link4(Config) when is_list(Config) ->
?line {ok, Node} = start_node(spawn_link4),
?line Parent = self(),
@@ -240,7 +240,7 @@ spawn_link4(Config) when list(Config) ->
spawn_opt2(doc) -> ["Test spawn_opt/2"];
spawn_opt2(suite) ->
[];
-spawn_opt2(Config) when list(Config) ->
+spawn_opt2(Config) when is_list(Config) ->
?line Node = node(),
?line Parent = self(),
?line {_, _, FA, _} = fetch_proc_vals(self()),
@@ -275,7 +275,7 @@ spawn_opt2(Config) when list(Config) ->
spawn_opt3(doc) -> ["Test spawn_opt/3"];
spawn_opt3(suite) ->
[];
-spawn_opt3(Config) when list(Config) ->
+spawn_opt3(Config) when is_list(Config) ->
?line {ok, Node} = start_node(spawn_opt3),
?line Parent = self(),
?line {_, _, FA, _} = fetch_proc_vals(self()),
@@ -312,7 +312,7 @@ spawn_opt3(Config) when list(Config) ->
spawn_opt4(doc) -> ["Test spawn_opt/4"];
spawn_opt4(suite) ->
[];
-spawn_opt4(Config) when list(Config) ->
+spawn_opt4(Config) when is_list(Config) ->
?line Node = node(),
?line Parent = self(),
?line {_, _, FA, _} = fetch_proc_vals(self()),
@@ -352,7 +352,7 @@ spawn_opt4(Config) when list(Config) ->
spawn_opt5(doc) -> ["Test spawn_opt/5"];
spawn_opt5(suite) ->
[];
-spawn_opt5(Config) when list(Config) ->
+spawn_opt5(Config) when is_list(Config) ->
?line {ok, Node} = start_node(spawn_opt5),
?line Parent = self(),
?line {_, _, FA, _} = fetch_proc_vals(self()),
@@ -396,7 +396,7 @@ spawn_failures(doc) ->
["Test failure behavior of spawn bifs"];
spawn_failures(suite) ->
[];
-spawn_failures(Config) when list(Config) ->
+spawn_failures(Config) when is_list(Config) ->
?line ThisNode = node(),
?line {ok, Node} = start_node(spawn_remote_failure),
@@ -556,7 +556,7 @@ wilderness(doc) ->
"wilderness of the heap are interpreted correct by the emulator "];
wilderness(suite) ->
[];
-wilderness(Config) when list(Config) ->
+wilderness(Config) when is_list(Config) ->
?line Dog = ?t:timetrap(?default_timeout),
?line OKParams = {512, 8},
?line Alloc = erlang:system_info(allocator),
@@ -604,11 +604,11 @@ run_wilderness_test({Set_tt, Set_tp}, {Exp_tt, Exp_tp}) ->
end,
stop_node(Node).
-to_string(X) when integer(X) ->
+to_string(X) when is_integer(X) ->
integer_to_list(X);
-to_string(X) when atom(X) ->
+to_string(X) when is_atom(X) ->
atom_to_list(X);
-to_string(X) when list(X) ->
+to_string(X) when is_list(X) ->
X.
get_nodenames(N, T) ->
diff --git a/lib/kernel/test/cleanup.erl b/lib/kernel/test/cleanup.erl
index 6e1a1edeac..831ceba8f5 100644
--- a/lib/kernel/test/cleanup.erl
+++ b/lib/kernel/test/cleanup.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(cleanup).
@@ -31,7 +31,7 @@ cleanup(_) ->
?line case nodes() of
[] ->
ok;
- Nodes when list(Nodes) ->
+ Nodes when is_list(Nodes) ->
Kill = fun(Node) -> spawn(Node, erlang, halt, []) end,
?line lists:foreach(Kill, Nodes),
?line test_server:fail({nodes_left, Nodes})
diff --git a/lib/kernel/test/code_SUITE.erl b/lib/kernel/test/code_SUITE.erl
index 9fda66711d..37b9200942 100644
--- a/lib/kernel/test/code_SUITE.erl
+++ b/lib/kernel/test/code_SUITE.erl
@@ -1,19 +1,19 @@
%%
%% %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
%% 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(code_SUITE).
@@ -26,28 +26,34 @@
delete/1, purge/1, soft_purge/1, is_loaded/1, all_loaded/1,
load_binary/1, dir_req/1, object_code/1, set_path_file/1,
sticky_dir/1, pa_pz_option/1, add_del_path/1,
- dir_disappeared/1, ext_mod_dep/1,
+ dir_disappeared/1, ext_mod_dep/1, clash/1,
load_cached/1, start_node_with_cache/1, add_and_rehash/1,
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,
delete, purge, soft_purge, is_loaded, all_loaded,
load_binary, dir_req, object_code, set_path_file,
pa_pz_option, add_del_path,
- dir_disappeared, ext_mod_dep,
+ dir_disappeared, ext_mod_dep, clash,
load_cached, start_node_with_cache, add_and_rehash,
where_is_file_no_cache, where_is_file_cached,
purge_stacktrace, mult_lib_roots, 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
@@ -525,7 +531,7 @@ pa_pz_option(Config) when is_list(Config) ->
add_del_path(suite) ->
[];
add_del_path(doc) -> ["add_path, del_path should not cause priv_dir(App) to fail"];
-add_del_path(Config) ->
+add_del_path(Config) when is_list(Config) ->
DDir = ?config(data_dir,Config),
Dir1 = filename:join(DDir,"dummy_app-1.0/ebin"),
Dir2 = filename:join(DDir,"dummy_app-2.0/ebin"),
@@ -539,9 +545,41 @@ add_del_path(Config) ->
ok.
+clash(Config) when is_list(Config) ->
+ DDir = ?config(data_dir,Config)++"clash/",
+ P = code:get_path(),
+
+ %% test non-clashing entries
+
+ %% remove "." to prevent clash with test-server path
+ ?line true = code:del_path("."),
+ ?line true = code:add_path(DDir++"foobar-0.1/ebin"),
+ ?line true = code:add_path(DDir++"zork-0.8/ebin"),
+ ?line test_server:capture_start(),
+ ?line code:clash(),
+ ?line test_server:capture_stop(),
+ ?line OKMsg = test_server:capture_get(),
+ ?line lists:prefix("** Found 0 name clashes in code paths", OKMsg),
+ ?line true = code:set_path(P),
+
+ %% test clashing entries
+
+ %% remove "." to prevent clash with test-server path
+ ?line true = code:del_path("."),
+ ?line true = code:add_path(DDir++"foobar-0.1/ebin"),
+ ?line true = code:add_path(DDir++"foobar-0.1.ez/foobar-0.1/ebin"),
+ ?line test_server:capture_start(),
+ ?line code:clash(),
+ ?line test_server:capture_stop(),
+ ?line [ErrMsg1|_] = test_server:capture_get(),
+ ?line {match, [" hides "]} = re:run(ErrMsg1, "\\*\\* .*( hides ).*",
+ [{capture,all_but_first,list}]),
+ ?line true = code:set_path(P),
+ ok.
+
ext_mod_dep(suite) ->
[];
-ext_mod_dep(doce) ->
+ext_mod_dep(doc) ->
["Every module that the code_server uses should be preloaded, "
"this test case verifies that"];
ext_mod_dep(Config) when is_list(Config) ->
@@ -671,6 +709,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 +1269,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/clash/foobar-0.1.ez b/lib/kernel/test/code_SUITE_data/clash/foobar-0.1.ez
new file mode 100644
index 0000000000..33d8a59b92
--- /dev/null
+++ b/lib/kernel/test/code_SUITE_data/clash/foobar-0.1.ez
Binary files differ
diff --git a/lib/kernel/test/code_SUITE_data/clash/foobar-0.1/ebin/baz.beam b/lib/kernel/test/code_SUITE_data/clash/foobar-0.1/ebin/baz.beam
new file mode 100644
index 0000000000..da87f32b9f
--- /dev/null
+++ b/lib/kernel/test/code_SUITE_data/clash/foobar-0.1/ebin/baz.beam
@@ -0,0 +1 @@
+baz 298734
diff --git a/lib/kernel/test/code_SUITE_data/clash/foobar-0.1/ebin/blarg.beam b/lib/kernel/test/code_SUITE_data/clash/foobar-0.1/ebin/blarg.beam
new file mode 100644
index 0000000000..e4c70c267c
--- /dev/null
+++ b/lib/kernel/test/code_SUITE_data/clash/foobar-0.1/ebin/blarg.beam
@@ -0,0 +1 @@
+baz 86234
diff --git a/lib/kernel/test/code_SUITE_data/clash/zork-0.8.ez b/lib/kernel/test/code_SUITE_data/clash/zork-0.8.ez
new file mode 100644
index 0000000000..051fa1efe4
--- /dev/null
+++ b/lib/kernel/test/code_SUITE_data/clash/zork-0.8.ez
Binary files differ
diff --git a/lib/kernel/test/code_SUITE_data/clash/zork-0.8/ebin/bork.beam b/lib/kernel/test/code_SUITE_data/clash/zork-0.8/ebin/bork.beam
new file mode 100644
index 0000000000..7b292c0b44
--- /dev/null
+++ b/lib/kernel/test/code_SUITE_data/clash/zork-0.8/ebin/bork.beam
@@ -0,0 +1 @@
+baz 23784
diff --git a/lib/kernel/test/code_SUITE_data/clash/zork-0.8/ebin/flarp.beam b/lib/kernel/test/code_SUITE_data/clash/zork-0.8/ebin/flarp.beam
new file mode 100644
index 0000000000..7b2f6a850f
--- /dev/null
+++ b/lib/kernel/test/code_SUITE_data/clash/zork-0.8/ebin/flarp.beam
@@ -0,0 +1 @@
+baz 3246238
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/kernel/test/erl_distribution_SUITE.erl b/lib/kernel/test/erl_distribution_SUITE.erl
index 8f2e2512e0..21a96f804a 100644
--- a/lib/kernel/test/erl_distribution_SUITE.erl
+++ b/lib/kernel/test/erl_distribution_SUITE.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(erl_distribution_SUITE).
@@ -62,7 +62,7 @@ all(suite) ->
table_waste, net_setuptime,
monitor_nodes].
-init_per_testcase(Func, Config) when atom(Func), list(Config) ->
+init_per_testcase(Func, Config) when is_atom(Func), is_list(Config) ->
Dog=?t:timetrap(?t:minutes(4)),
[{watchdog, Dog}|Config].
@@ -72,7 +72,7 @@ fin_per_testcase(_Func, Config) ->
tick(suite) -> [];
tick(doc) -> [];
-tick(Config) when list(Config) ->
+tick(Config) when is_list(Config) ->
?line Dog = test_server:timetrap(test_server:seconds(120)),
PaDir = filename:dirname(code:which(erl_distribution_SUITE)),
@@ -119,7 +119,7 @@ tick(Config) when list(Config) ->
monitor_node(Node, true),
receive
- {tick_test, T} when integer(T) ->
+ {tick_test, T} when is_integer(T) ->
stop_node(ServNode),
stop_node(Node),
T;
@@ -141,7 +141,7 @@ table_waste(doc) ->
["Checks that pinging nonexistyent nodes does not waste space in distribution table"];
table_waste(suite) ->
[];
-table_waste(Config) when list(Config) ->
+table_waste(Config) when is_list(Config) ->
?line {ok, HName} = inet:gethostname(),
F = fun(0,_F) -> [];
(N,F) ->
@@ -161,7 +161,7 @@ illegal_nodenames(doc) ->
["Test that pinging an illegal nodename does not kill the node"];
illegal_nodenames(suite) ->
[];
-illegal_nodenames(Config) when list(Config) ->
+illegal_nodenames(Config) when is_list(Config) ->
?line Dog=?t:timetrap(?t:minutes(2)),
PaDir = filename:dirname(code:which(erl_distribution_SUITE)),
?line {ok, Node}=start_node(illegal_nodenames, "-pa " ++ PaDir),
@@ -269,12 +269,13 @@ tick_cli_test1(Node) ->
tick_change(doc) -> ["OTP-4255"];
tick_change(suite) -> [];
-tick_change(Config) when list(Config) ->
+tick_change(Config) when is_list(Config) ->
?line PaDir = filename:dirname(code:which(?MODULE)),
?line [BN, CN] = get_nodenames(2, tick_change),
?line DefaultTT = net_kernel:get_net_ticktime(),
+ ?line unchanged = net_kernel:set_net_ticktime(DefaultTT, 60),
?line case DefaultTT of
- I when integer(I) -> ?line ok;
+ I when is_integer(I) -> ?line ok;
_ -> ?line ?t:fail(DefaultTT)
end,
@@ -377,6 +378,7 @@ run_tick_change_test(B, C, PrevTT, TT, PaDir) ->
end,
?line change_initiated = net_kernel:set_net_ticktime(TT,20),
+ ?line {ongoing_change_to,_} = net_kernel:set_net_ticktime(TT,20),
?line sleep(3),
?line change_initiated = rpc:call(B,net_kernel,set_net_ticktime,[TT,15]),
?line sleep(7),
@@ -445,7 +447,7 @@ hidden_node(doc) ->
["Basic test of hidden node"];
hidden_node(suite) ->
[];
-hidden_node(Config) when list(Config) ->
+hidden_node(Config) when is_list(Config) ->
?line Dog = ?t:timetrap(?t:seconds(40)),
PaDir = filename:dirname(code:which(?MODULE)),
VArgs = "-pa " ++ PaDir,
@@ -548,7 +550,7 @@ monitor_nodes(suite) ->
monitor_nodes_nodedown_reason(doc) -> [];
monitor_nodes_nodedown_reason(suite) -> [];
-monitor_nodes_nodedown_reason(Config) when list(Config) ->
+monitor_nodes_nodedown_reason(Config) when is_list(Config) ->
?line MonNodeState = monitor_node_state(),
?line ok = net_kernel:monitor_nodes(true),
?line ok = net_kernel:monitor_nodes(true, [nodedown_reason]),
@@ -603,7 +605,7 @@ monitor_nodes_nodedown_reason(Config) when list(Config) ->
monitor_nodes_complex_nodedown_reason(doc) -> [];
monitor_nodes_complex_nodedown_reason(suite) -> [];
-monitor_nodes_complex_nodedown_reason(Config) when list(Config) ->
+monitor_nodes_complex_nodedown_reason(Config) when is_list(Config) ->
?line MonNodeState = monitor_node_state(),
?line Me = self(),
?line ok = net_kernel:monitor_nodes(true, [nodedown_reason]),
@@ -885,7 +887,7 @@ monitor_nodes_errors(doc) ->
[];
monitor_nodes_errors(suite) ->
[];
-monitor_nodes_errors(Config) when list(Config) ->
+monitor_nodes_errors(Config) when is_list(Config) ->
?line MonNodeState = monitor_node_state(),
?line error = net_kernel:monitor_nodes(asdf),
?line {error,
@@ -922,7 +924,7 @@ monitor_nodes_combinations(doc) ->
[];
monitor_nodes_combinations(suite) ->
[];
-monitor_nodes_combinations(Config) when list(Config) ->
+monitor_nodes_combinations(Config) when is_list(Config) ->
?line MonNodeState = monitor_node_state(),
?line monitor_nodes_all_comb(true),
?line [VisibleName, HiddenName] = get_nodenames(2,
@@ -1044,7 +1046,7 @@ monitor_nodes_cleanup(doc) ->
[];
monitor_nodes_cleanup(suite) ->
[];
-monitor_nodes_cleanup(Config) when list(Config) ->
+monitor_nodes_cleanup(Config) when is_list(Config) ->
?line MonNodeState = monitor_node_state(),
?line Me = self(),
?line No = monitor_nodes_all_comb(true),
@@ -1076,7 +1078,7 @@ monitor_nodes_many(doc) ->
[];
monitor_nodes_many(suite) ->
[];
-monitor_nodes_many(Config) when list(Config) ->
+monitor_nodes_many(Config) when is_list(Config) ->
?line MonNodeState = monitor_node_state(),
?line [Name] = get_nodenames(1, monitor_nodes_many),
%% We want to perform more than 2^16 net_kernel:monitor_nodes
@@ -1139,10 +1141,10 @@ start_node(Name, Param, this) ->
start_node(Name, Param, "this") ->
NewParam = Param ++ " -pa " ++ filename:dirname(code:which(?MODULE)),
?t:start_node(Name, peer, [{args, NewParam}, {erl, [this]}]);
-start_node(Name, Param, Rel) when atom(Rel) ->
+start_node(Name, Param, Rel) when is_atom(Rel) ->
NewParam = Param ++ " -pa " ++ filename:dirname(code:which(?MODULE)),
?t:start_node(Name, peer, [{args, NewParam}, {erl, [{release, atom_to_list(Rel)}]}]);
-start_node(Name, Param, Rel) when list(Rel) ->
+start_node(Name, Param, Rel) when is_list(Rel) ->
NewParam = Param ++ " -pa " ++ filename:dirname(code:which(?MODULE)),
?t:start_node(Name, peer, [{args, NewParam}, {erl, [{release, Rel}]}]).
@@ -1216,9 +1218,9 @@ wait_until(Fun) ->
end
end.
-repeat(Fun, 0) when function(Fun) ->
+repeat(Fun, 0) when is_function(Fun) ->
ok;
-repeat(Fun, N) when function(Fun), integer(N), N > 0 ->
+repeat(Fun, N) when is_function(Fun), is_integer(N), N > 0 ->
Fun(),
repeat(Fun, N-1).
diff --git a/lib/kernel/test/erl_prim_loader_SUITE.erl b/lib/kernel/test/erl_prim_loader_SUITE.erl
index 4d090f4db5..19c84ab34c 100644
--- a/lib/kernel/test/erl_prim_loader_SUITE.erl
+++ b/lib/kernel/test/erl_prim_loader_SUITE.erl
@@ -1,19 +1,19 @@
%%
%% %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
%% 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_prim_loader_SUITE).
@@ -27,7 +27,7 @@
inet_existing/1, inet_coming_up/1, inet_disconnects/1,
multiple_slaves/1, file_requests/1,
local_archive/1, remote_archive/1,
- primary_archive/1]).
+ primary_archive/1, virtual_dir_in_archive/1]).
-export([init_per_testcase/2, fin_per_testcase/2]).
@@ -41,10 +41,11 @@ all(suite) ->
inet_existing, inet_coming_up,
inet_disconnects, multiple_slaves,
file_requests, local_archive,
- remote_archive, primary_archive
+ remote_archive, primary_archive,
+ virtual_dir_in_archive
].
-init_per_testcase(Func, Config) when atom(Func), list(Config) ->
+init_per_testcase(Func, Config) when is_atom(Func), is_list(Config) ->
Dog=?t:timetrap(?t:minutes(3)),
[{watchdog, Dog}|Config].
@@ -81,7 +82,7 @@ set_path(Config) when is_list(Config) ->
get_file(doc) -> [];
get_file(Config) when is_list(Config) ->
?line case erl_prim_loader:get_file("lists" ++ code:objfile_extension()) of
- {ok,Bin,File} when binary(Bin), list(File) ->
+ {ok,Bin,File} when is_binary(Bin), is_list(File) ->
ok;
_ ->
test_server:fail(get_valid_file)
@@ -344,8 +345,9 @@ local_archive(Config) when is_list(Config) ->
Node = node(),
BeamName = "inet.beam",
?line ok = test_archive(Node, Archive, KernelDir, BeamName),
- ?line ok = rpc:call(Node, erl_prim_loader, release_archives, []),
+ %% Cleanup
+ ?line ok = rpc:call(Node, erl_prim_loader, release_archives, []),
?line ok = file:delete(Archive),
ok.
@@ -365,6 +367,7 @@ remote_archive(Config) when is_list(Config) ->
BeamName = "inet.beam",
?line ok = test_archive(Node, Archive, KernelDir, BeamName),
+ %% Cleanup
?line stop_node(Node),
?line unlink(BootPid),
?line exit(BootPid, kill),
@@ -401,21 +404,22 @@ primary_archive(Config) when is_list(Config) ->
?line Args = " -setcookie " ++ Cookie,
?line {ok,Node} = start_node(primary_archive, Args),
?line wait_really_started(Node, 25),
+ ?line {_,_,_} = rpc:call(Node, erlang, date, []),
%% Set primary archive
- ?line {_,_,_} = rpc:call(Node, erlang, date, []),
- ?line {ok, Ebins} = rpc:call(Node, erl_prim_loader, set_primary_archive, [Archive, ArchiveBin]),
ExpectedEbins = [Archive, DictDir ++ "/ebin", DummyDir ++ "/ebin"],
io:format("ExpectedEbins: ~p\n", [ExpectedEbins]),
- ?line ExpectedEbins = lists:sort(Ebins),
+ ?line {ok, FileInfo} = prim_file:read_file_info(Archive),
+ ?line {ok, Ebins} = rpc:call(Node, erl_prim_loader, set_primary_archive, [Archive, ArchiveBin, FileInfo]),
+ ?line ExpectedEbins = lists:sort(Ebins), % assert
?line {ok, TopFiles2} = rpc:call(Node, erl_prim_loader, list_dir, [Archive]),
?line [DictDir, DummyDir] = lists:sort(TopFiles2),
BeamName = "primary_archive_dict_app.beam",
?line ok = test_archive(Node, Archive, DictDir, BeamName),
- ?line {ok, []} = rpc:call(Node, erl_prim_loader, set_primary_archive, [undefined, undefined]),
-
+ %% Cleanup
+ ?line {ok, []} = rpc:call(Node, erl_prim_loader, set_primary_archive, [undefined, undefined, undefined]),
?line stop_node(Node),
?line ok = file:delete(Archive),
ok.
@@ -461,6 +465,46 @@ create_archive(Archive, AppDirs) ->
io:format("zip:create(~p,\n\t~p,\n\t~p).\n", [Archive, AppDirs, Opts]),
zip:create(Archive, AppDirs, Opts).
+
+virtual_dir_in_archive(suite) ->
+ [];
+virtual_dir_in_archive(doc) ->
+ ["Read virtual directories from archive."];
+virtual_dir_in_archive(Config) when is_list(Config) ->
+ PrivDir = ?config(priv_dir, Config),
+ Data = <<"A little piece of data.">>,
+ ArchiveBase = "archive_with_virtual_dirs",
+ Archive = filename:join([PrivDir, ArchiveBase ++ init:archive_extension()]),
+ FileBase = "a_data_file.beam",
+ EbinBase = "ebin",
+ FileInArchive = filename:join([ArchiveBase, EbinBase, FileBase]),
+ BinFiles = [{FileInArchive, Data}],
+ Opts = [{compress, []}],
+ ?line file:delete(Archive),
+ io:format("zip:create(~p,\n\t~p,\n\t~p).\n", [Archive, BinFiles, Opts]),
+ ?line {ok, Archive} = zip:create(Archive, BinFiles, Opts),
+
+ %% Verify that there is no directories
+ ?line {ok, BinFiles} = zip:unzip(Archive, [memory]),
+
+ FullPath = filename:join([Archive, FileInArchive]),
+ ?line {ok, _} = erl_prim_loader:read_file_info(FullPath),
+
+ %% Read one virtual dir
+ EbinDir = filename:dirname(FullPath),
+ ?line {ok, _} = erl_prim_loader:read_file_info(EbinDir),
+ ?line {ok, [FileBase]} = erl_prim_loader:list_dir(EbinDir),
+
+ %% Read another virtual dir
+ AppDir = filename:dirname(EbinDir),
+ ?line {ok, _} = erl_prim_loader:read_file_info(AppDir),
+ ?line {ok, [EbinBase]} = erl_prim_loader:list_dir(AppDir),
+
+ %% Cleanup
+ ?line ok = erl_prim_loader:release_archives(),
+ ?line ok = file:delete(Archive),
+ ok.
+
%% Misc. functions
ip_str({A, B, C, D}) ->
diff --git a/lib/kernel/test/error_logger_SUITE.erl b/lib/kernel/test/error_logger_SUITE.erl
index a737949bbb..eda86861d5 100644
--- a/lib/kernel/test/error_logger_SUITE.erl
+++ b/lib/kernel/test/error_logger_SUITE.erl
@@ -1,19 +1,19 @@
%%
%% %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
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
-%%
+%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
-%%
+%%
%% %CopyrightEnd%
%%
-module(error_logger_SUITE).
@@ -45,7 +45,7 @@ all(suite) ->
error_report(suite) -> [];
error_report(doc) -> [];
-error_report(Config) when list(Config) ->
+error_report(Config) when is_list(Config) ->
?line error_logger:add_report_handler(?MODULE, self()),
Rep1 = [{tag1,"data1"},{tag2,data2},{tag3,3}],
Rep2 = [testing,"testing",{tag1,"tag1"}],
@@ -85,7 +85,7 @@ error_report(Config) when list(Config) ->
info_report(suite) -> [];
info_report(doc) -> [];
-info_report(Config) when list(Config) ->
+info_report(Config) when is_list(Config) ->
?line error_logger:add_report_handler(?MODULE, self()),
Rep1 = [{tag1,"data1"},{tag2,data2},{tag3,3}],
Rep2 = [testing,"testing",{tag1,"tag1"}],
@@ -125,7 +125,7 @@ info_report(Config) when list(Config) ->
error(suite) -> [];
error(doc) -> [];
-error(Config) when list(Config) ->
+error(Config) when is_list(Config) ->
?line error_logger:add_report_handler(?MODULE, self()),
Msg1 = "This is a plain text string~n",
Msg2 = "This is a text with arguments ~p~n",
@@ -160,7 +160,7 @@ error(Config) when list(Config) ->
info(suite) -> [];
info(doc) -> [];
-info(Config) when list(Config) ->
+info(Config) when is_list(Config) ->
?line error_logger:add_report_handler(?MODULE, self()),
Msg1 = "This is a plain text string~n",
Msg2 = "This is a text with arguments ~p~n",
@@ -188,7 +188,7 @@ info(Config) when list(Config) ->
emulator(suite) -> [];
emulator(doc) -> [];
-emulator(Config) when list(Config) ->
+emulator(Config) when is_list(Config) ->
?line error_logger:add_report_handler(?MODULE, self()),
spawn(?MODULE, generate_error, []),
reported(emulator),
@@ -215,7 +215,7 @@ tty(Config) when is_list(Config) ->
logfile(suite) -> [];
logfile(doc) -> [];
-logfile(Config) when list(Config) ->
+logfile(Config) when is_list(Config) ->
?line case error_logger:logfile(filename) of
{error, no_log_file} -> % Ok, we continues.
do_logfile();
@@ -236,7 +236,7 @@ do_logfile() ->
add(suite) -> [];
add(doc) -> [];
-add(Config) when list(Config) ->
+add(Config) when is_list(Config) ->
?line {'EXIT',_} = (catch error_logger:add_report_handler("dummy")),
?line {'EXIT',_} = error_logger:add_report_handler(non_existing),
?line my_error = error_logger:add_report_handler(?MODULE, [error]),
@@ -246,7 +246,7 @@ add(Config) when list(Config) ->
delete(suite) -> [];
delete(doc) -> [];
-delete(Config) when list(Config) ->
+delete(Config) when is_list(Config) ->
?line {'EXIT',_} = (catch error_logger:delete_report_handler("dummy")),
?line {error,_} = error_logger:delete_report_handler(non_existing),
ok.
@@ -265,7 +265,7 @@ reported(Tag, Type, Report) ->
reported(emulator) ->
receive
- {error, "~s~n", String} when list(String) ->
+ {error, "~s~n", String} when is_list(String) ->
test_server:messages_get(),
ok
after 1000 ->
@@ -277,9 +277,9 @@ reported(emulator) ->
%% Sends a notification to the Tester process about the events
%% generated by the Tester process.
%%-----------------------------------------------------------------
-init(Tester) when pid(Tester) ->
+init(Tester) when is_pid(Tester) ->
{ok, Tester};
-init(Config) when list(Config) ->
+init(Config) when is_list(Config) ->
my_error.
handle_event({Tag, _GL, {_EPid, Type, Report}}, Tester) ->
diff --git a/lib/kernel/test/file_SUITE.erl b/lib/kernel/test/file_SUITE.erl
index c645d0f842..d01e1f1fcf 100644
--- a/lib/kernel/test/file_SUITE.erl
+++ b/lib/kernel/test/file_SUITE.erl
@@ -1,19 +1,19 @@
%%
%% %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
%% 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%
%%
@@ -3371,7 +3371,7 @@ read_line_create_files(TestData) ->
[ Function(File) || {Function,File,_,_} <- TestData ].
read_line_remove_files(TestData) ->
- [ file:delete(File) || {Function,File,_,_} <- TestData ].
+ [ file:delete(File) || {_Function,File,_,_} <- TestData ].
read_line_1(suite) ->
[];
diff --git a/lib/kernel/test/gen_sctp_SUITE.erl b/lib/kernel/test/gen_sctp_SUITE.erl
index dd7d5f111a..9ba226864d 100644
--- a/lib/kernel/test/gen_sctp_SUITE.erl
+++ b/lib/kernel/test/gen_sctp_SUITE.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2007-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 2007-2011. All Rights Reserved.
+%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
-%%
+%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
-%%
+%%
%% %CopyrightEnd%
%%
-module(gen_sctp_SUITE).
@@ -24,10 +24,11 @@
%%-compile(export_all).
-export([all/1,init_per_testcase/2,fin_per_testcase/2,
- basic/1,xfer_min/1,xfer_active/1,api_open_close/1,api_listen/1]).
+ basic/1,api_open_close/1,api_listen/1,api_connect_init/1,api_opts/1,
+ xfer_min/1,xfer_active/1]).
all(suite) ->
- [basic,xfer_min,xfer_active,api_open_close,api_listen].
+ [basic,api_open_close,api_listen,api_connect_init,api_opts,xfer_min,xfer_active].
init_per_testcase(_Func, Config) ->
Dog = test_server:timetrap(test_server:seconds(15)),
@@ -171,7 +172,9 @@ xfer_active(Config) when is_list(Config) ->
?line test_server:fail({unexpected,flush()})
end,
?line io:format("SbAssocId=~p~n", [SbAssocId]),
- ?line ok = gen_sctp:send(Sa, SaAssocId, 0, Data),
+ ?line ok =
+ do_from_other_process(
+ fun () -> gen_sctp:send(Sa, SaAssocId, 0, Data) end),
?line receive
{sctp,Sb,Loopback,Pa,
{[#sctp_sndrcvinfo{stream=Stream,
@@ -325,7 +328,7 @@ api_listen(Config) when is_list(Config) ->
?line {ok,{Localhost,
Pb,[],
#sctp_assoc_change{
- state = comm_lost}}} =
+ state=comm_lost}}} =
gen_sctp:recv(Sa, infinity);
{error,#sctp_assoc_change{state=cant_assoc}} -> ok
end,
@@ -336,3 +339,93 @@ api_listen(Config) when is_list(Config) ->
?line ok = gen_sctp:close(Sa),
?line ok = gen_sctp:close(Sb),
ok.
+
+api_connect_init(doc) ->
+ "Test the API function connect_init/4";
+api_connect_init(suite) ->
+ [];
+api_connect_init(Config) when is_list(Config) ->
+ ?line Localhost = {127,0,0,1},
+
+ ?line {ok,S} = gen_sctp:open(),
+ ?line {ok,Pb} = inet:port(S),
+ ?line try gen_sctp:connect_init(S, Localhost, not_allowed_for_port, [])
+ catch error:badarg -> ok
+ end,
+ ?line try gen_sctp:connect_init(S, Localhost, 12345, not_allowed_for_opts)
+ catch error:badarg -> ok
+ end,
+ ?line ok = gen_sctp:close(S),
+ ?line {error,closed} = gen_sctp:connect_init(S, Localhost, 12345, []),
+
+ ?line {ok,Sb} = gen_sctp:open(Pb),
+ ?line {ok,Sa} = gen_sctp:open(),
+ ?line case gen_sctp:connect_init(Sa, localhost, Pb, []) of
+ {error,econnrefused} ->
+ ?line {ok,{Localhost,
+ Pb,[],
+ #sctp_assoc_change{state=comm_lost}}} =
+ gen_sctp:recv(Sa, infinity);
+ ok ->
+ ?line {ok,{Localhost,
+ Pb,[],
+ #sctp_assoc_change{state=cant_assoc}}} =
+ gen_sctp:recv(Sa, infinity)
+ end,
+ ?line ok = gen_sctp:listen(Sb, true),
+ ?line case gen_sctp:connect_init(Sa, localhost, Pb, []) of
+ ok ->
+ ?line {ok,{Localhost,
+ Pb,[],
+ #sctp_assoc_change{
+ state = comm_up}}} =
+ gen_sctp:recv(Sa, infinity)
+ end,
+ ?line ok = gen_sctp:close(Sa),
+ ?line ok = gen_sctp:close(Sb),
+ ok.
+
+api_opts(doc) ->
+ "Test socket options";
+api_opts(suite) ->
+ [];
+api_opts(Config) when is_list(Config) ->
+ ?line Sndbuf = 32768,
+ ?line Recbuf = 65536,
+ ?line {ok,S} = gen_sctp:open(0),
+ ?line ok = inet:setopts(S, [{sndbuf,Sndbuf}]),
+ ?line ok = inet:setopts(S, [{recbuf,Recbuf}]),
+ ?line case inet:getopts(S, [sndbuf]) of
+ {ok,[{sndbuf,SB}]} when SB >= Sndbuf -> ok
+ end,
+ ?line case inet:getopts(S, [recbuf]) of
+ {ok,[{recbuf,RB}]} when RB >= Recbuf -> ok
+ end.
+
+
+
+do_from_other_process(Fun) ->
+ Parent = self(),
+ Ref = make_ref(),
+ Child =
+ spawn(fun () ->
+ try Fun() of
+ Result ->
+ Parent ! {Ref,Result}
+ catch
+ Class:Reason ->
+ Stacktrace = erlang:get_stacktrace(),
+ Parent ! {Ref,Class,Reason,Stacktrace}
+ end
+ end),
+ Mref = erlang:monitor(process, Child),
+ receive
+ {Ref,Result} ->
+ receive {'DOWN',Mref,_,_,_} -> Result end;
+ {Ref,Class,Reason,Stacktrace} ->
+ receive {'DOWN',Mref,_,_,_} ->
+ erlang:raise(Class, Reason, Stacktrace)
+ end;
+ {'DOWN',Mref,_,_,Reason} ->
+ erlang:exit(Reason)
+ end.
diff --git a/lib/kernel/test/global_group_SUITE.erl b/lib/kernel/test/global_group_SUITE.erl
index a8b87390eb..430cc61267 100644
--- a/lib/kernel/test/global_group_SUITE.erl
+++ b/lib/kernel/test/global_group_SUITE.erl
@@ -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%
%%
@@ -42,7 +42,7 @@ all(suite) ->
-define(TESTCASE, testcase_name).
-define(testcase, ?config(?TESTCASE, Config)).
-init_per_testcase(Case, Config) when atom(Case), list(Config) ->
+init_per_testcase(Case, Config) when is_atom(Case), is_list(Config) ->
Dog=?t:timetrap(?t:minutes(5)),
[{?TESTCASE, Case}, {watchdog, Dog}|Config].
@@ -59,7 +59,7 @@ fin_per_testcase(_Func, Config) ->
start_gg_proc(suite) -> [];
start_gg_proc(doc) -> ["Check that the global_group processes are started automatically. "];
-start_gg_proc(Config) when list(Config) ->
+start_gg_proc(Config) when is_list(Config) ->
?line Dog = test_server:timetrap(test_server:seconds(120)),
?line Dir = ?config(priv_dir, Config),
@@ -94,7 +94,7 @@ start_gg_proc(Config) when list(Config) ->
no_gg_proc(suite) -> [];
no_gg_proc(doc) -> ["Start a system without global groups. Nodes are not "
"synced at start (sync_nodes_optional is not defined)"];
-no_gg_proc(Config) when list(Config) ->
+no_gg_proc(Config) when is_list(Config) ->
?line Dog = test_server:timetrap(test_server:seconds(200)),
?line Dir = ?config(priv_dir, Config),
@@ -267,7 +267,7 @@ no_gg_proc_sync(suite) -> [];
no_gg_proc_sync(doc) ->
["Start a system without global groups, but syncing the nodes by using "
"sync_nodes_optional."];
-no_gg_proc_sync(Config) when list(Config) ->
+no_gg_proc_sync(Config) when is_list(Config) ->
?line Dog = test_server:timetrap(test_server:seconds(200)),
?line Dir = ?config(priv_dir, Config),
@@ -441,7 +441,7 @@ no_gg_proc_sync(Config) when list(Config) ->
compatible(suite) -> [];
compatible(doc) ->
["Check that a system without global groups is compatible with the old R4 system."];
-compatible(Config) when list(Config) ->
+compatible(Config) when is_list(Config) ->
?line Dog = test_server:timetrap(test_server:seconds(200)),
?line Dir = ?config(priv_dir, Config),
@@ -614,7 +614,7 @@ compatible(Config) when list(Config) ->
one_grp(suite) -> [];
one_grp(doc) -> ["Test a system with only one global group. "];
-one_grp(Config) when list(Config) ->
+one_grp(Config) when is_list(Config) ->
?line Dog = test_server:timetrap(test_server:seconds(120)),
?line Dir = ?config(priv_dir, Config),
@@ -701,7 +701,7 @@ one_grp(Config) when list(Config) ->
one_grp_x(suite) -> [];
one_grp_x(doc) -> ["Check a system with only one global group. "
"Start the nodes with different time intervals. "];
-one_grp_x(Config) when list(Config) ->
+one_grp_x(Config) when is_list(Config) ->
?line Dog = test_server:timetrap(test_server:seconds(120)),
?line Dir = ?config(priv_dir, Config),
@@ -763,7 +763,7 @@ one_grp_x(Config) when list(Config) ->
two_grp(suite) -> [];
two_grp(doc) -> ["Test a two global group system. "];
-two_grp(Config) when list(Config) ->
+two_grp(Config) when is_list(Config) ->
?line Dog = test_server:timetrap(test_server:seconds(200)),
?line Dir = ?config(priv_dir, Config),
@@ -1063,7 +1063,7 @@ two_grp(Config) when list(Config) ->
hidden_groups(suite) -> [];
hidden_groups(doc) -> ["Test hidden global groups."];
-hidden_groups(Config) when list(Config) ->
+hidden_groups(Config) when is_list(Config) ->
?line Dog = test_server:timetrap(test_server:seconds(200)),
?line Dir = ?config(priv_dir, Config),
@@ -1138,7 +1138,7 @@ hidden_groups(Config) when list(Config) ->
test_exit(suite) -> [];
test_exit(doc) -> ["Checks when the search process exits. "];
-test_exit(Config) when list(Config) ->
+test_exit(Config) when is_list(Config) ->
?line Dog = test_server:timetrap(test_server:seconds(120)),
?line NN = node_name(atom_to_list(node())),
diff --git a/lib/kernel/test/heart_SUITE.erl b/lib/kernel/test/heart_SUITE.erl
index b06244db3c..0d0296238b 100644
--- a/lib/kernel/test/heart_SUITE.erl
+++ b/lib/kernel/test/heart_SUITE.erl
@@ -1,19 +1,19 @@
%%
%% %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
%% 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(heart_SUITE).
@@ -80,7 +80,7 @@ start_check(Type, Name) ->
end,
erlang:monitor_node(Node, true),
case rpc:call(Node, erlang, whereis, [heart]) of
- Pid when pid(Pid) ->
+ Pid when is_pid(Pid) ->
ok;
_ ->
test_server:fail(heart_not_started)
@@ -355,7 +355,7 @@ erl() ->
end.
name(Node) when is_list(Node) -> name(Node,[]);
-name(Node) when atom(Node) -> name(atom_to_list(Node),[]).
+name(Node) when is_atom(Node) -> name(atom_to_list(Node),[]).
name([$@|Node], Name) ->
case lists:member($., Node) of
@@ -368,7 +368,7 @@ name([H|T], Name) ->
name(T, [H|Name]).
-atom_conv(A) when atom(A) ->
+atom_conv(A) when is_atom(A) ->
atom_to_list(A);
atom_conv(A) when is_list(A) ->
A.
diff --git a/lib/kernel/test/inet_SUITE.erl b/lib/kernel/test/inet_SUITE.erl
index cf33e8b27f..eb8f918491 100644
--- a/lib/kernel/test/inet_SUITE.erl
+++ b/lib/kernel/test/inet_SUITE.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(inet_SUITE).
@@ -28,7 +28,7 @@
gethostnative_parallell/1, cname_loop/1,
gethostnative_soft_restart/1,gethostnative_debug_level/1,getif/1]).
--export([get_hosts/1, get_ipv6_hosts/1, parse_hosts/1,
+-export([get_hosts/1, get_ipv6_hosts/1, parse_hosts/1, parse_address/1,
kill_gethost/0, parallell_gethost/0]).
-export([init_per_testcase/2, end_per_testcase/2]).
@@ -249,14 +249,16 @@ t_getaddr_v6(Config) when is_list(Config) ->
?line {ok,IP46} = inet:getaddr(IP46, inet6),
?line {ok,IP46} = inet:getaddr(Name, inet6),
?line {ok,IP46} = inet:getaddr(FullName, inet6),
- ?line IP4toIP6 = inet:getaddr(IPStr, inet6),
- ?line case IP4toIP6 of
- {ok,IP46} -> % only native can do this
- ?line true = lists:member(native,
- inet_db:res_option(lookup));
- {error,nxdomain} ->
- ok
- end,
+ ?line {ok,IP46} = inet:getaddr(IPStr, inet6),
+%% ?line IP4toIP6 = inet:getaddr(IPStr, inet6),
+%% ?line case IP4toIP6 of
+%% {ok,IP46} ->
+%% ?line ok;
+%% {error,nxdomain} ->
+%% ?line false =
+%% lists:member(native,
+%% inet_db:res_option(lookup))
+%% end,
?line {Name6, FullName6, IPStr6, IP6, _} =
?config(test_host_ipv6_only, Config),
?line {ok,_} = inet:getaddr(list_to_atom(Name6), inet6),
@@ -301,7 +303,6 @@ ipv4_to_ipv6(Config) when is_list(Config) ->
end,
?line case {IP4to6Res,inet:gethostbyname(IPStr, inet6)} of
{true,{ok,HEnt}} ->
- ?line true = lists:member(native, inet_db:res_option(lookup)),
?line HEnt_ = HEnt#hostent{h_addrtype = inet6,
h_length = 16,
h_addr_list = [IP_46]},
@@ -374,9 +375,10 @@ get_hosts([C|Rest], Cur, Ip, Result) ->
get_hosts([], _, _, Result) ->
Result.
-parse(suite) -> [parse_hosts];
+parse(suite) -> [parse_hosts, parse_address];
parse(doc) -> ["Test that parsing of the hosts file or equivalent works,",
"and that erroneous lines are skipped"].
+
parse_hosts(Config) when is_list(Config) ->
?line DataDir = ?config(data_dir,Config),
?line HostFile = filename:join(DataDir, "hosts"),
@@ -388,6 +390,170 @@ parse_hosts(Config) when is_list(Config) ->
?line ResolvErr1 = filename:join(DataDir,"resolv.conf.err1"),
?line inet_parse:resolv(ResolvErr1).
+parse_address(Config) when is_list(Config) ->
+ V4Strict =
+ [{{0,0,0,0},"0.0.0.0"},
+ {{1,2,3,4},"1.2.3.4"},
+ {{253,252,251,250},"253.252.251.250"},
+ {{1,2,255,254},"1.2.255.254"}],
+ V6Strict =
+ [{{0,0,0,0,0,0,0,0},"::"},
+ {{15,0,0,0,0,0,0,2},"f::2"},
+ {{15,16#f11,0,0,0,0,256,2},"f:f11::0100:2"},
+ {{0,0,0,0,0,0,0,16#17},"::17"},
+ {{16#700,0,0,0,0,0,0,0},"0700::"},
+ {{0,0,0,0,0,0,2,1},"::2:1"},
+ {{0,0,0,0,0,3,2,1},"::3:2:1"},
+ {{0,0,0,0,4,3,2,1},"::4:3:2:1"},
+ {{0,0,0,5,4,3,2,1},"::5:4:3:2:1"},
+ {{0,0,6,5,4,3,2,1},"::6:5:4:3:2:1"},
+ {{0,7,6,5,4,3,2,1},"::7:6:5:4:3:2:1"},
+ {{7,0,0,0,0,0,0,0},"7::"},
+ {{7,6,0,0,0,0,0,0},"7:6::"},
+ {{7,6,5,0,0,0,0,0},"7:6:5::"},
+ {{7,6,5,4,0,0,0,0},"7:6:5:4::"},
+ {{7,6,5,4,3,0,0,0},"7:6:5:4:3::"},
+ {{7,6,5,4,3,2,0,0},"7:6:5:4:3:2::"},
+ {{7,6,5,4,3,2,1,0},"7:6:5:4:3:2:1::"},
+ {{16#c11,16#c22,16#5c33,16#c440,16#55c0,16#c66c,16#77,16#88},
+ "c11:0c22:5c33:c440:55c0:c66c:77:0088"},
+ {{16#c11,0,16#5c33,16#c440,16#55c0,16#c66c,16#77,16#88},
+ "c11::5c33:c440:55c0:c66c:77:0088"},
+ {{16#c11,16#c22,0,16#c440,16#55c0,16#c66c,16#77,16#88},
+ "c11:0c22::c440:55c0:c66c:77:0088"},
+ {{16#c11,16#c22,16#5c33,0,16#55c0,16#c66c,16#77,16#88},
+ "c11:0c22:5c33::55c0:c66c:77:0088"},
+ {{16#c11,16#c22,16#5c33,16#c440,0,16#c66c,16#77,16#88},
+ "c11:0c22:5c33:c440::c66c:77:0088"},
+ {{16#c11,16#c22,16#5c33,16#c440,16#55c0,0,16#77,16#88},
+ "c11:0c22:5c33:c440:55c0::77:0088"},
+ {{16#c11,16#c22,16#5c33,16#c440,16#55c0,16#c66c,0,16#88},
+ "c11:0c22:5c33:c440:55c0:c66c::0088"},
+ {{16#c11,0,0,16#c440,16#55c0,16#c66c,16#77,16#88},
+ "c11::c440:55c0:c66c:77:0088"},
+ {{16#c11,16#c22,0,0,16#55c0,16#c66c,16#77,16#88},
+ "c11:0c22::55c0:c66c:77:0088"},
+ {{16#c11,16#c22,16#5c33,0,0,16#c66c,16#77,16#88},
+ "c11:0c22:5c33::c66c:77:0088"},
+ {{16#c11,16#c22,16#5c33,16#c440,0,0,16#77,16#88},
+ "c11:0c22:5c33:c440::77:0088"},
+ {{16#c11,16#c22,16#5c33,16#c440,16#55c0,0,0,16#88},
+ "c11:0c22:5c33:c440:55c0::0088"},
+ {{16#c11,0,0,0,16#55c0,16#c66c,16#77,16#88},
+ "c11::55c0:c66c:77:0088"},
+ {{16#c11,16#c22,0,0,0,16#c66c,16#77,16#88},
+ "c11:0c22::c66c:77:0088"},
+ {{16#c11,16#c22,16#5c33,0,0,0,16#77,16#88},
+ "c11:0c22:5c33::77:0088"},
+ {{16#c11,16#c22,16#5c33,16#c440,0,0,0,16#88},
+ "c11:0c22:5c33:c440::0088"},
+ {{16#c11,0,0,0,0,16#c66c,16#77,16#88},
+ "c11::c66c:77:0088"},
+ {{16#c11,16#c22,0,0,0,0,16#77,16#88},
+ "c11:0c22::77:0088"},
+ {{16#c11,16#c22,16#5c33,0,0,0,0,16#88},
+ "c11:0c22:5c33::0088"},
+ {{16#c11,0,0,0,0,0,16#77,16#88},
+ "c11::77:0088"},
+ {{16#c11,16#c22,0,0,0,0,0,16#88},
+ "c11:0c22::0088"},
+ {{0,0,0,0,0,65535,258,65534},"::FFFF:1.2.255.254"},
+ {{16#ffff,16#ffff,16#ffff,16#ffff,16#ffff,16#ffff,16#ffff,16#ffff},
+ "ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff"}
+ |[{{D2,0,0,0,0,P,(D1 bsl 8) bor D2,(D3 bsl 8) bor D4},
+ erlang:integer_to_list(D2, 16)++"::"++Q++S}
+ || {{D1,D2,D3,D4},S} <- V4Strict,
+ {P,Q} <- [{0,""},{16#17,"17:"},{16#ff0,"0ff0:"}]]],
+ V4Sloppy =
+ [{{10,1,16#98,16#76},"10.0x019876"},
+ {{8#12,1,8#130,8#321},"012.01.054321"},
+ {{255,255,255,255},"255.255.255.0377"},
+ {{255,255,255,255},"0Xff.000000000377.0x0000ff.255"},
+ {{255,255,255,255},"255.255.65535"},
+ {{255,255,255,255},"255.0xFF.0177777"},
+ {{255,255,255,255},"255.16777215"},
+ {{255,255,255,255},"00377.0XFFFFFF"},
+ {{255,255,255,255},"4294967295"},
+ {{255,255,255,255},"0xffffffff"},
+ {{255,255,255,255},"00000000000037777777777"},
+ {{16#12,16#34,16#56,16#78},"0x12345678"},
+ {{16#12,16#34,16#56,16#78},"0x12.0x345678"},
+ {{16#12,16#34,16#56,16#78},"0x12.0X34.0x5678"},
+ {{16#12,16#34,16#56,16#78},"0x12.0X34.0x56.0X78"},
+ {{0,0,0,0},"0"},
+ {{0,0,0,0},"00"},
+ {{0,0,0,0},"0.0"},
+ {{0,0,0,0},"00.00.00"},
+ {{0,0,0,0},"0.00.0.0"},
+ {{0,0,0,0},"0.0.000000000000.0"}],
+ V6Sloppy =
+ [{{0,0,0,0,0,65535,(D1 bsl 8) bor D2,(D3 bsl 8) bor D4},S}
+ || {{D1,D2,D3,D4},S} <- V4Strict++V4Sloppy],
+ V4Err =
+ ["0.256.0.1",
+ "1.2.3.4.5",
+ "256.255.65535",
+ "4294967296",
+ "0x100000000",
+ "040000000000",
+ "1.2.3.-4",
+ "1.2.-3.4",
+ "1.-2.3.4",
+ "-1.2.3.4",
+ "10.",
+ "172.16.",
+ "198.168.0.",
+ "127.0.0.1."],
+ V6Err =
+ [":::",
+ "f:::2",
+ "::-1",
+ "::g",
+ "f:f11::10100:2",
+ "::17000",
+ "10000::",
+ "::8:7:6:5:4:3:2:1",
+ "8:7:6:5:4:3:2:1::",
+ "8:7:6:5:4::3:2:1",
+ "::1.2.3.4.5",
+ "::1.2.3.04",
+ "::1.256.3.4",
+ "::-5.4.3.2",
+ "::5.-4.3.2",
+ "::5.4.-3.2",
+ "::5.4.3.-2",
+ "::FFFF:1.2.3.4.5",
+ "::10.",
+ "::FFFF:172.16.",
+ "fe80::198.168.0.",
+ "fec0::fFfF:127.0.0.1."],
+ t_parse_address
+ (ipv6_address,
+ V6Strict++V6Sloppy++V6Err++V4Err),
+ t_parse_address
+ (ipv6strict_address,
+ V6Strict++V6Err++V4Err++[S || {_,S} <- V6Sloppy]),
+ t_parse_address
+ (ipv4_address,
+ V4Strict++V4Sloppy++V4Err++V6Err++[S || {_,S} <- V6Strict]),
+ t_parse_address
+ (ipv4strict_address,
+ V4Strict++V4Err++V6Err++[S || {_,S} <- V4Sloppy++V6Strict]).
+
+t_parse_address(Func, []) ->
+ io:format("~p done.~n", [Func]),
+ ok;
+t_parse_address(Func, [{Addr,String}|L]) ->
+ io:format("~p = ~p.~n", [Addr,String]),
+ {ok,Addr} = inet_parse:Func(String),
+ t_parse_address(Func, L);
+t_parse_address(Func, [String|L]) ->
+ io:format("~p.~n", [String]),
+ {error,einval} = inet_parse:Func(String),
+ t_parse_address(Func, L).
+
+
+
t_gethostnative(suite) ->[];
t_gethostnative(doc) ->[];
t_gethostnative(Config) when is_list(Config) ->
diff --git a/lib/kernel/test/inet_res_SUITE.erl b/lib/kernel/test/inet_res_SUITE.erl
index 659cfc5988..cc32d1f8f9 100644
--- a/lib/kernel/test/inet_res_SUITE.erl
+++ b/lib/kernel/test/inet_res_SUITE.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(inet_res_SUITE).
@@ -239,16 +239,37 @@ resolve(_Opts, []) -> ok;
resolve(Opts, [{Class,Type,Name,Answers,Authority}=Q|Qs]) ->
io:format("Query: ~p~nOptions: ~p~n", [Q,Opts]),
{ok,Msg} = inet_res:resolve(Name, Class, Type, Opts),
- if Answers =/= undefined ->
- AnList = lists:sort(Answers),
- AnList = lists:sort([inet_dns:rr(RR, data) ||
- RR <- inet_dns:msg(Msg, anlist)]);
- true -> ok end,
- if Authority =/= undefined ->
- NsList = lists:sort(Authority),
- NsList = lists:sort([inet_dns:rr(RR, data) ||
- RR <- inet_dns:msg(Msg, nslist)]);
- true -> ok end,
+ AnList =
+ if
+ Answers =/= undefined ->
+ lists:sort(Answers);
+ true ->
+ undefined
+ end,
+ NsList =
+ if
+ Authority =/= undefined ->
+ lists:sort(Authority);
+ true ->
+ undefined
+ end,
+ case {lists:sort
+ ([inet_dns:rr(RR, data) || RR <- inet_dns:msg(Msg, anlist)]),
+ lists:sort
+ ([inet_dns:rr(RR, data) || RR <- inet_dns:msg(Msg, nslist)])} of
+ {AnList,NsList} ->
+ ok;
+ {NsList,AnList} when Type =:= ns ->
+ %% This whole case statement is kind of inside out just
+ %% to accept this case when some legacy DNS resolvers
+ %% return the answer to a NS query in the answer section
+ %% instead of in the authority section.
+ ok;
+ {AnList,_} when NsList =:= undefined ->
+ ok;
+ {_,NsList} when AnList =:= undefined ->
+ ok
+ end,
Buf = inet_dns:encode(Msg),
{ok,Msg} = inet_dns:decode(Buf),
resolve(Opts, Qs).
@@ -292,10 +313,23 @@ edns0(Config) when is_list(Config) ->
MXs = lists:sort(inet_res_filter(inet_dns:msg(Msg2, anlist), in, mx)),
Buf2 = inet_dns:encode(Msg2),
{ok,Msg2} = inet_dns:decode(Buf2),
- [OptRR] = [RR || RR <- inet_dns:msg(Msg2, arlist),
- inet_dns:rr(RR, type) =:= opt],
- io:format("~p~n", [inet_dns:rr(OptRR)]),
- ok.
+ case [RR || RR <- inet_dns:msg(Msg2, arlist),
+ inet_dns:rr(RR, type) =:= opt] of
+ [OptRR] ->
+ io:format("~p~n", [inet_dns:rr(OptRR)]),
+ ok;
+ [] ->
+ case os:type() of
+ {unix,sunos} ->
+ case os:version() of
+ {M,V,_} when M < 5; M == 5, V =< 8 ->
+ %% In our test park only known platform
+ %% with an DNS resolver that can not do
+ %% EDNS0.
+ {comment,"No EDNS0"}
+ end
+ end
+ end.
inet_res_filter(Anlist, Class, Type) ->
[inet_dns:rr(RR, data) || RR <- Anlist,
@@ -331,11 +365,13 @@ files_monitor(suite) ->
files_monitor(doc) ->
["Tests monitoring of /etc/hosts and /etc/resolv.conf, but not them"];
files_monitor(Config) when is_list(Config) ->
+ Search = inet_db:res_option(search),
HostsFile = inet_db:res_option(hosts_file),
ResolvConf = inet_db:res_option(resolv_conf),
Inet6 = inet_db:res_option(inet6),
try do_files_monitor(Config)
after
+ inet_db:res_option(search, Search),
inet_db:res_option(resolv_conf, ResolvConf),
inet_db:res_option(hosts_file, HostsFile),
inet_db:res_option(inet6, Inet6)
@@ -344,7 +380,13 @@ files_monitor(Config) when is_list(Config) ->
do_files_monitor(Config) ->
Dir = ?config(priv_dir, Config),
{ok,Hostname} = inet:gethostname(),
- FQDN = Hostname++"."++inet_db:res_option(domain),
+ FQDN =
+ case inet_db:res_option(domain) of
+ "" ->
+ Hostname;
+ _ ->
+ Hostname++"."++inet_db:res_option(domain)
+ end,
HostsFile = filename:join(Dir, "files_monitor_hosts"),
ResolvConf = filename:join(Dir, "files_monitor_resolv.conf"),
ok = inet_db:res_option(resolv_conf, ResolvConf),
@@ -362,20 +404,20 @@ do_files_monitor(Config) ->
{error,nxdomain} = inet_res:gethostbyname(FQDN),
{ok,{127,0,0,10}} = inet:getaddr("mx.otptest", inet),
{ok,{0,0,0,0,0,0,32512,28}} = inet:getaddr("resolve.otptest", inet6),
- ok = inet_db:res_option(inet6, true),
{ok,#hostent{h_name = Hostname,
h_addrtype = inet6,
h_length = 16,
h_addr_list = [{0,0,0,0,0,0,0,1}]}} =
- inet:gethostbyname(Hostname),
+ inet:gethostbyname(Hostname, inet6),
{ok,#hostent{h_name = FQDN,
h_addrtype = inet6,
h_length = 16,
h_addr_list = [{0,0,0,0,0,0,0,1}]}} =
- inet:gethostbyname(FQDN),
+ inet:gethostbyname(FQDN, inet6),
{error,nxdomain} = inet_res:gethostbyname("resolve"),
%% XXX inet does not honour res_option inet6, might be a problem?
%% therefore inet_res is called here
+ ok = inet_db:res_option(inet6, true),
{ok,#hostent{h_name = "resolve.otptest",
h_addrtype = inet6,
h_length = 16,
diff --git a/lib/kernel/test/init_SUITE.erl b/lib/kernel/test/init_SUITE.erl
index 3d777f93a4..bbd8261197 100644
--- a/lib/kernel/test/init_SUITE.erl
+++ b/lib/kernel/test/init_SUITE.erl
@@ -1,19 +1,19 @@
%%
%% %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
%% 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_SUITE).
@@ -44,7 +44,7 @@ all(suite) ->
restart,
get_status, script_id, boot].
-init_per_testcase(Func, Config) when atom(Func), list(Config) ->
+init_per_testcase(Func, Config) when is_atom(Func), is_list(Config) ->
Dog=?t:timetrap(?t:seconds(?DEFAULT_TIMEOUT_SEC)),
[{watchdog, Dog}|Config].
@@ -477,7 +477,7 @@ script_id(Config) when is_list(Config) ->
?line {Name, Vsn} = init:script_id(),
?line if
- list(Name), list(Vsn) ->
+ is_list(Name), is_list(Vsn) ->
ok;
true ->
?t:fail(not_standard_script)
diff --git a/lib/kernel/test/kernel_SUITE.erl b/lib/kernel/test/kernel_SUITE.erl
index 225bc38b05..bb1d905de3 100644
--- a/lib/kernel/test/kernel_SUITE.erl
+++ b/lib/kernel/test/kernel_SUITE.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%
%%
%%%----------------------------------------------------------------
@@ -56,6 +56,6 @@ app_test(doc) ->
["Tests the applications consistency."];
app_test(suite) ->
[];
-app_test(Config) when list(Config) ->
+app_test(Config) when is_list(Config) ->
?line ok=?t:app_test(kernel),
ok.
diff --git a/lib/kernel/test/kernel_config_SUITE.erl b/lib/kernel/test/kernel_config_SUITE.erl
index 6b7d788e60..c72fc3f02d 100644
--- a/lib/kernel/test/kernel_config_SUITE.erl
+++ b/lib/kernel/test/kernel_config_SUITE.erl
@@ -1,19 +1,19 @@
%%
%% %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
%% 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(kernel_config_SUITE).
@@ -56,7 +56,7 @@ from(_, []) -> [].
%%-----------------------------------------------------------------
sync(doc) -> [];
sync(suite) -> [];
-sync(Conf) when list(Conf) ->
+sync(Conf) when is_list(Conf) ->
?line Dog = ?t:timetrap(?t:seconds(120)),
% Write a config file
Dir = ?config(priv_dir,Conf),
diff --git a/lib/kernel/test/loose_node.erl b/lib/kernel/test/loose_node.erl
index ac1ddb8d9a..87a4ef01c0 100644
--- a/lib/kernel/test/loose_node.erl
+++ b/lib/kernel/test/loose_node.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2004-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 2004-2010. All Rights Reserved.
+%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
-%%
+%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
-%%
+%%
%% %CopyrightEnd%
%%
@@ -55,7 +55,7 @@
%% Exported functions.
%%
-stop(Node) when atom(Node) ->
+stop(Node) when is_atom(Node) ->
rpc:cast(Node, erlang, halt, []),
io:format("Stopped loose node ~p~n", [Node]),
ok.
@@ -63,9 +63,10 @@ stop(Node) when atom(Node) ->
start(Name, Args) ->
start(Name, Args, -1).
-start(Name, Args, TimeOut) when atom(Name) ->
+start(Name, Args, TimeOut) when is_atom(Name) ->
start(atom_to_list(Name), Args, TimeOut);
-start(Name, Args, TimeOut) when list(Name), list(Args), integer(TimeOut) ->
+start(Name, Args, TimeOut)
+ when is_list(Name), is_list(Args), is_integer(TimeOut) ->
Parent = self(),
Ref = make_ref(),
Starter
@@ -119,7 +120,7 @@ start(Name, Args, TimeOut) when list(Name), list(Args), integer(TimeOut) ->
io:format("Trying to start loose node...~n"
" --> ~p~n", [Cmd]),
Res = case open_port({spawn, Cmd}, []) of
- P when port(P) ->
+ P when is_port(P) ->
receive
{loose_node_started,
Node,
@@ -150,14 +151,14 @@ start(Name, Args, TimeOut) when list(Name), list(Args), integer(TimeOut) ->
%% Exported functions for internal use.
%%
-loose_node_started([Name, Node, TimeOutSecs]) when list(Name),
- list(Node),
- list(TimeOutSecs) ->
+loose_node_started([Name, Node, TimeOutSecs]) when is_list(Name),
+ is_list(Node),
+ is_list(TimeOutSecs) ->
spawn_opt(fun () ->
process_flag(trap_exit, true),
Proc = {list_to_atom(Name), list_to_atom(Node)},
Timeout = case catch list_to_integer(TimeOutSecs) of
- I when integer(I), I >= 0 -> I*1000;
+ I when is_integer(I), I >= 0 -> I*1000;
_ -> infinity
end,
wait_until(fun () -> is_alive() end),
diff --git a/lib/kernel/test/os_SUITE.erl b/lib/kernel/test/os_SUITE.erl
index 667f267079..6a3534b094 100644
--- a/lib/kernel/test/os_SUITE.erl
+++ b/lib/kernel/test/os_SUITE.erl
@@ -1,38 +1,38 @@
%%
%% %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(os_SUITE).
-export([all/1]).
-export([space_in_cwd/1, quoting/1, space_in_name/1, bad_command/1,
- find_executable/1, unix_comment_in_command/1]).
+ find_executable/1, unix_comment_in_command/1, evil/1]).
-include("test_server.hrl").
all(suite) ->
[space_in_cwd, quoting, space_in_name, bad_command, find_executable,
- unix_comment_in_command].
+ unix_comment_in_command, evil].
space_in_cwd(doc) ->
"Test that executing a command in a current working directory "
"with space in its name works.";
space_in_cwd(suite) -> [];
-space_in_cwd(Config) when list(Config) ->
+space_in_cwd(Config) when is_list(Config) ->
?line PrivDir = ?config(priv_dir, Config),
?line Dirname = filename:join(PrivDir, "cwd with space"),
?line ok = file:make_dir(Dirname),
@@ -60,7 +60,7 @@ space_in_cwd(Config) when list(Config) ->
quoting(doc) -> "Test that various ways of quoting arguments work.";
quoting(suite) -> [];
-quoting(Config) when list(Config) ->
+quoting(Config) when is_list(Config) ->
?line DataDir = ?config(data_dir, Config),
?line Echo = filename:join(DataDir, "my_echo"),
@@ -78,7 +78,7 @@ quoting(Config) when list(Config) ->
space_in_name(doc) ->
"Test that program with a space in its name can be executed.";
space_in_name(suite) -> [];
-space_in_name(Config) when list(Config) ->
+space_in_name(Config) when is_list(Config) ->
?line PrivDir = ?config(priv_dir, Config),
?line DataDir = ?config(data_dir, Config),
?line Spacedir = filename:join(PrivDir, "program files"),
@@ -108,7 +108,7 @@ space_in_name(Config) when list(Config) ->
bad_command(doc) ->
"Check that a bad command doesn't crasch the server or the emulator (it used to).";
bad_command(suite) -> [];
-bad_command(Config) when list(Config) ->
+bad_command(Config) when is_list(Config) ->
?line catch os:cmd([a|b]),
?line catch os:cmd({bad, thing}),
@@ -120,7 +120,7 @@ bad_command(Config) when list(Config) ->
find_executable(suite) -> [];
find_executable(doc) -> [];
-find_executable(Config) when list(Config) ->
+find_executable(Config) when is_list(Config) ->
case os:type() of
{win32, _} ->
?line DataDir = filename:join(?config(data_dir, Config), "win32"),
@@ -159,7 +159,7 @@ find_exe(Where, Name, Ext, Path) ->
case os:find_executable(Name, Path) of
Expected ->
ok;
- Name when list(Name) ->
+ Name when is_list(Name) ->
case filename:absname(Name) of
Expected ->
ok;
@@ -176,7 +176,7 @@ find_exe(Where, Name, Ext, Path) ->
unix_comment_in_command(doc) ->
"OTP-1805: Test that os:cmd(\"ls #\") works correctly (used to hang).";
unix_comment_in_command(suite) -> [];
-unix_comment_in_command(Config) when list(Config) ->
+unix_comment_in_command(Config) when is_list(Config) ->
?line Dog = test_server:timetrap(test_server:seconds(20)),
?line Priv = ?config(priv_dir, Config),
?line ok = file:set_cwd(Priv),
@@ -186,6 +186,48 @@ unix_comment_in_command(Config) when list(Config) ->
?line test_server:timetrap_cancel(Dog),
ok.
+-define(EVIL_PROCS, 100).
+-define(EVIL_LOOPS, 100).
+-define(PORT_CREATOR, os_cmd_port_creator).
+evil(Config) when is_list(Config) ->
+ Dog = test_server:timetrap(test_server:minutes(5)),
+ Parent = self(),
+ Ps = lists:map(fun (N) ->
+ spawn_link(fun () ->
+ evil_loop(Parent, ?EVIL_LOOPS,N)
+ end)
+ end, lists:seq(1, ?EVIL_PROCS)),
+ Devil = spawn(fun () -> devil(hd(Ps), hd(lists:reverse(Ps))) end),
+ lists:foreach(fun (P) -> receive {P, done} -> ok end end, Ps),
+ exit(Devil, kill),
+ test_server:timetrap_cancel(Dog),
+ ok.
+
+devil(P1, P2) ->
+ erlang:display({?PORT_CREATOR, whereis(?PORT_CREATOR)}),
+ (catch ?PORT_CREATOR ! lists:seq(1,1000000)),
+ (catch ?PORT_CREATOR ! lists:seq(1,666)),
+ (catch ?PORT_CREATOR ! grrrrrrrrrrrrrrrr),
+ (catch ?PORT_CREATOR ! {'EXIT', P1, buhuuu}),
+ (catch ?PORT_CREATOR ! {'EXIT', hd(erlang:ports()), buhuuu}),
+ (catch ?PORT_CREATOR ! {'EXIT', P2, arggggggg}),
+ receive after 500 -> ok end,
+ (catch exit(whereis(?PORT_CREATOR), kill)),
+ (catch ?PORT_CREATOR ! ">8|"),
+ receive after 500 -> ok end,
+ (catch exit(whereis(?PORT_CREATOR), diiiiiiiiiiiiiiiiiiiie)),
+ receive after 100 -> ok end,
+ devil(P1, P2).
+
+evil_loop(Parent, Loops, N) ->
+ Res = integer_to_list(N),
+ evil_loop(Parent, Loops, Res, "echo " ++ Res).
+
+evil_loop(Parent, 0, _Res, _Cmd) ->
+ Parent ! {self(), done};
+evil_loop(Parent, Loops, Res, Cmd) ->
+ comp(Res, os:cmd(Cmd)),
+ evil_loop(Parent, Loops-1, Res, Cmd).
comp(Expected, Got) ->
case strip_nl(Got) of
diff --git a/lib/kernel/test/pdict_SUITE.erl b/lib/kernel/test/pdict_SUITE.erl
index 6aa434b614..87ee951a0c 100644
--- a/lib/kernel/test/pdict_SUITE.erl
+++ b/lib/kernel/test/pdict_SUITE.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 1999-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 1999-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(pdict_SUITE).
@@ -49,7 +49,7 @@ simple(doc) ->
["Tests simple functionality in process dictionary."];
simple(suite) ->
[];
-simple(Config) when list(Config) ->
+simple(Config) when is_list(Config) ->
XX = get(),
erase(),
L = [a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,
@@ -146,7 +146,7 @@ info(doc) ->
["Tests process_info(Pid, dictionary)"];
info(suite) ->
[];
-info(Config) when list(Config) ->
+info(Config) when is_list(Config) ->
L = [a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,
q,r,s,t,u,v,x,y,z,'A','B','C','D'],
process_flag(trap_exit,true),
diff --git a/lib/kernel/test/ram_file_SUITE.erl b/lib/kernel/test/ram_file_SUITE.erl
index 55c9497670..798a37d3dc 100644
--- a/lib/kernel/test/ram_file_SUITE.erl
+++ b/lib/kernel/test/ram_file_SUITE.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2001-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 2001-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%
%%
@@ -472,20 +472,25 @@ uuencode(Config) when is_list(Config) ->
%%
%% Uuencode and decode test
%%
- ?line {ok, 0} = ?FILE_MODULE:position(FdReal, bof),
- ?line {ok, 0} = ?FILE_MODULE:position(Fd, bof),
- ?line ok = ?FILE_MODULE:truncate(Fd),
- ?line {ok, Sz} = ?FILE_MODULE:copy(FdReal, Fd),
- ?line {ok, SzUu} = ?RAM_FILE_MODULE:uuencode(Fd),
- ?line true = (Sz =< SzUu),
- ?line {ok, Sz } = ?RAM_FILE_MODULE:uudecode(Fd),
- ?line {ok, 0} = ?FILE_MODULE:position(FdReal, bof),
- ?line {ok, 0} = ?FILE_MODULE:position(Fd, bof),
- ?line true = compare(FdReal, Fd),
- %%
+ F = fun(Offs) ->
+ Size = Sz - Offs,
+ ?line {ok, Offs} = ?FILE_MODULE:position(FdReal, {bof,Offs}),
+ ?line {ok, 0} = ?FILE_MODULE:position(Fd, bof),
+ ?line ok = ?FILE_MODULE:truncate(Fd),
+ ?line {ok, Size} = ?FILE_MODULE:copy(FdReal, Fd),
+ ?line {ok, SizeUu} = ?RAM_FILE_MODULE:uuencode(Fd),
+ ?line true = (Size =< SizeUu),
+ ?line {ok, Size} = ?RAM_FILE_MODULE:uudecode(Fd),
+ ?line {ok, Offs} = ?FILE_MODULE:position(FdReal, {bof,Offs}),
+ ?line {ok, 0} = ?FILE_MODULE:position(Fd, bof),
+ ?line true = compare(FdReal, Fd)
+ end,
+ lists:foreach(F, lists:seq(0,Sz-1, 43)),
+
?line ok = ?FILE_MODULE:close(FdReal),
?line ok = ?FILE_MODULE:close(Fd),
?line ok = ?FILE_MODULE:close(FdRealUu),
+ %%
ok.
diff --git a/lib/kernel/test/rpc_SUITE.erl b/lib/kernel/test/rpc_SUITE.erl
index 2b39e31a80..2b7de40797 100644
--- a/lib/kernel/test/rpc_SUITE.erl
+++ b/lib/kernel/test/rpc_SUITE.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2000-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 2000-2010. All Rights Reserved.
+%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
-%%
+%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
-%%
+%%
%% %CopyrightEnd%
%%
-module(rpc_SUITE).
@@ -333,7 +333,7 @@ suicide(exit, Reason) ->
suicide(erlang, exit, [Name, Reason]) when is_atom(Name) ->
case whereis(Name) of
- Pid when pid(Pid) -> suicide(erlang, exit, [Pid, Reason])
+ Pid when is_pid(Pid) -> suicide(erlang, exit, [Pid, Reason])
end;
suicide(Mod, Func, Args) ->
spawn_link(
@@ -448,7 +448,7 @@ call_benchmark(Config) when is_list(Config) ->
?t:timetrap_cancel(Timetrap),
ok.
-do_call_benchmark(Node, M) when integer(M), M > 0 ->
+do_call_benchmark(Node, M) when is_integer(M), M > 0 ->
do_call_benchmark(Node, erlang:now(), 0, M).
do_call_benchmark(Node, {A,B,C}, M, M) ->
diff --git a/lib/kernel/test/seq_trace_SUITE.erl b/lib/kernel/test/seq_trace_SUITE.erl
index f582b94c97..b557c7fb1e 100644
--- a/lib/kernel/test/seq_trace_SUITE.erl
+++ b/lib/kernel/test/seq_trace_SUITE.erl
@@ -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%
%%
-module(seq_trace_SUITE).
@@ -381,7 +381,7 @@ port(Config) when is_list(Config) ->
get_port_message(Port) ->
receive
- {Port,{data,Bin}} when binary(Bin) ->
+ {Port,{data,Bin}} when is_binary(Bin) ->
binary_to_term(Bin);
Other ->
?t:fail({unexpected,Other})
@@ -678,7 +678,7 @@ transparent_tracer() ->
receive {started, Ref} -> ok end,
fun(pid) ->
Pid;
- ({stop, N}) when integer(N), N >= 0 ->
+ ({stop, N}) when is_integer(N), N >= 0 ->
Mref = erlang:monitor(process, Pid),
receive
{'DOWN', Mref, _, _, _} ->
@@ -717,7 +717,7 @@ simple_tracer(Data, DN) ->
From ! {tracerlog,lists:reverse(Data)}
end.
-stop_tracer(N) when integer(N) ->
+stop_tracer(N) when is_integer(N) ->
case catch (seq_trace_SUITE_tracer ! {stop,N,self()}) of
{'EXIT', _} ->
{error, not_started};
diff --git a/lib/kernel/test/wrap_log_reader_SUITE.erl b/lib/kernel/test/wrap_log_reader_SUITE.erl
index 1d1570fbd9..ceac593e44 100644
--- a/lib/kernel/test/wrap_log_reader_SUITE.erl
+++ b/lib/kernel/test/wrap_log_reader_SUITE.erl
@@ -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%
%%
@@ -48,7 +48,7 @@
all(suite) ->
[no_file, one, two, four, wrap, wrapping, external, error].
-init_per_testcase(Func, Config) when atom(Func), list(Config) ->
+init_per_testcase(Func, Config) when is_atom(Func), is_list(Config) ->
Dog=?t:timetrap(?t:seconds(60)),
[{watchdog, Dog} | Config].
@@ -58,7 +58,7 @@ fin_per_testcase(_Func, _Config) ->
no_file(suite) -> [];
no_file(doc) -> ["No log file exists"];
-no_file(Conf) when list(Conf) ->
+no_file(Conf) when is_list(Conf) ->
?line code:add_path(?config(data_dir,Conf)),
Dir = ?privdir(Conf),
File = join(Dir, "sune.LOG"),
@@ -81,7 +81,7 @@ one(doc) -> ["One index file"].
one_empty(suite) -> [];
one_empty(doc) -> ["One empty index file"];
-one_empty(Conf) when list(Conf) ->
+one_empty(Conf) when is_list(Conf) ->
Dir = ?privdir(Conf),
File = join(Dir, "sune.LOG"),
delete_files(File),
@@ -107,7 +107,7 @@ one_empty(Conf) when list(Conf) ->
one_filled(suite) -> [];
one_filled(doc) -> ["One filled index file"];
-one_filled(Conf) when list(Conf) ->
+one_filled(Conf) when is_list(Conf) ->
Dir = ?privdir(Conf),
File = join(Dir, "sune.LOG"),
delete_files(File),
@@ -144,7 +144,7 @@ two(doc) -> ["Two index files"].
two_filled(suite) -> [];
two_filled(doc) -> ["Two filled index files"];
-two_filled(Conf) when list(Conf) ->
+two_filled(Conf) when is_list(Conf) ->
Dir = ?privdir(Conf),
File = list_to_atom(join(Dir, "sune.LOG")),
delete_files(File),
@@ -186,7 +186,7 @@ four(doc) -> ["Four index files"].
four_filled(suite) -> [];
four_filled(doc) -> ["Four filled index files"];
-four_filled(Conf) when list(Conf) ->
+four_filled(Conf) when is_list(Conf) ->
Dir = ?privdir(Conf),
File = join(Dir, "sune.LOG"),
delete_files(File),
@@ -231,7 +231,7 @@ wrap(doc) -> ["Wrap index file, first wrapping"].
wrap_filled(suite) -> [];
wrap_filled(doc) -> ["First wrap, open, filled index file"];
-wrap_filled(Conf) when list(Conf) ->
+wrap_filled(Conf) when is_list(Conf) ->
Dir = ?privdir(Conf),
File = join(Dir, "sune.LOG"),
delete_files(File),
@@ -274,7 +274,7 @@ test_wrap(File) ->
wrapping(suite) -> [];
wrapping(doc) -> ["Wrapping at the same time as reading"];
-wrapping(Conf) when list(Conf) ->
+wrapping(Conf) when is_list(Conf) ->
Dir = ?privdir(Conf),
File = join(Dir, "sune.LOG"),
delete_files(File),
@@ -329,7 +329,7 @@ wrapping(Conf) when list(Conf) ->
external(suite) -> [];
external(doc) -> ["External format"];
-external(Conf) when list(Conf) ->
+external(Conf) when is_list(Conf) ->
Dir = ?privdir(Conf),
File = join(Dir, "sune.LOG"),
delete_files(File),
@@ -349,7 +349,7 @@ external(Conf) when list(Conf) ->
error(suite) -> [];
error(doc) -> ["Error situations"];
-error(Conf) when list(Conf) ->
+error(Conf) when is_list(Conf) ->
Dir = ?privdir(Conf),
File = join(Dir, "sune.LOG"),
delete_files(File),
diff --git a/lib/kernel/vsn.mk b/lib/kernel/vsn.mk
index f93ad09b44..933600b501 100644
--- a/lib/kernel/vsn.mk
+++ b/lib/kernel/vsn.mk
@@ -1 +1 @@
-KERNEL_VSN = 2.13.4
+KERNEL_VSN = 2.13.5.4
diff --git a/lib/megaco/configure.in b/lib/megaco/configure.in
index 297d618369..8f94a4efcf 100644
--- a/lib/megaco/configure.in
+++ b/lib/megaco/configure.in
@@ -1,20 +1,20 @@
dnl Process this file with autoconf to produce a configure script. -*-m4-*-
dnl
dnl %CopyrightBegin%
-dnl
-dnl Copyright Ericsson AB 2001-2009. All Rights Reserved.
-dnl
+dnl
+dnl Copyright Ericsson AB 2001-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
@@ -145,12 +145,14 @@ AC_ARG_ENABLE(megaco_flex_scanner_lineno,
AC_SUBST(ENABLE_MEGACO_FLEX_SCANNER_LINENO)
+dnl This is the os flavour, should be unix, vxworks or win32
+if test "X$host" = "Xwin32"; then
+ ERLANG_OSTYPE=win32
+else
+ ERLANG_OSTYPE=unix
+fi
-dnl
-dnl C compiler (related) defs
-dnl
-
-AC_PROG_CC
+AC_SUBST(ERLANG_OSTYPE)
dnl Magic test for clearcase.
if test -d ../../system; then
@@ -158,33 +160,55 @@ if test -d ../../system; then
else
OTP_EXTRA_FLAGS=
fi
+AC_SUBST(OTP_EXTRA_FLAGS)
+
+dnl
+dnl If ${ERL_TOP}/make/otp_ded.mk.in exists and contains DED_MK_VSN > 0,
+dnl every thing releted to compiling Dynamic Erlang Drivers can be found
+dnl in $(ERL_TOP)/make/$(TARGET)/ded.mk at compile time. If not, try to
+dnl figure these things out.
+dnl
+
+AC_MSG_CHECKING([for usable Dynamic Erlang Driver configuration])
+[
+ ded_mk_in="${ERL_TOP}/make/otp_ded.mk.in"
+ ded_mk_vsn=
+ test -r "$ded_mk_in" &&
+ ded_mk_vsn=`sed -n "s/^DED_MK_VSN[ ]*=[ ]*\(.*\)/\1/p" < "$ded_mk_in"`
+ test "$ded_mk_vsn" != "" || ded_mk_vsn=0
+]
+
+if test $ded_mk_vsn -gt 0; then
+
+HAVE_USABLE_OTP_DED_MK=yes
+AC_MSG_RESULT([yes])
+CC=false
+AC_SUBST(CC)
+DED_LD=false
+AC_SUBST(DED_LD)
+
+else dnl --- begin no usable otp_ded.mk.in ---
+
+HAVE_USABLE_OTP_DED_MK=no
+AC_MSG_RESULT([no])
dnl
-dnl The ErlDrvEntry struct changed in R13 (another field)
+dnl C compiler (related) defs
dnl
-AC_CHECK_MEMBERS([struct ErlDrvEntry.stop_select],
- [
- CFLAGS="$CFLAGS -DMEGACO_DRV_ENTRY_HAS_STOP_SELECT"
- ],
- [],
- [
- #include "erl_driver.h"
- ])
+AC_PROG_CC
dnl
dnl Flags to the C compiler
dnl
-dnl make sure we find config.h
-CFLAGS="$CFLAGS -I${ERL_TOP}/erts/$host -I${ERL_TOP}/erts/include/$host $OTP_EXTRA_FLAGS"
if test "X$host" = "Xwin32"; then
DED_CFLAGS="$CFLAGS"
else
case $host_os in
darwin*)
- CFLAGS="$CFLAGS -no-cpp-precomp"
+ CFLAGS="$CFLAGS -no-cpp-precomp -fno-common"
;;
esac
@@ -196,22 +220,10 @@ else
fi
dnl emulator includes needed
-DED_INCLUDE="-I${ERL_TOP}/erts/emulator/beam -I${ERL_TOP}/erts/include -I${ERL_TOP}/erts/include/$host"
-
-DED_CFLAGS="$DED_INCLUDE $DED_CFLAGS"
-
-
+DED_INCLUDES="-I${ERL_TOP}/erts/emulator/beam -I${ERL_TOP}/erts/include -I${ERL_TOP}/erts/include/$host -I${ERL_TOP}/erts/include/internal -I${ERL_TOP}/erts/include/internal/$host -I${ERL_TOP}/erts/emulator/sys/$ERLANG_OSTYPE"
-AC_SUBST(DED_CFLAGS)
-
-
-AC_CHECK_PROGS(DED_LD, [ld.sh ld], no_ld)
-if test "$DED_LD" = no_ld; then
- AC_MSG_ERROR([ld is required to build the flex scanner!])
-fi
+DED_THR_DEFS="-D_THREAD_SAFE -D_REENTRANT"
-
-AC_MSG_CHECKING(for linker flags for loadable drivers)
case $host_os in
win32)
DED_LDFLAGS="-dll"
@@ -230,33 +242,36 @@ case $host_os in
# Mach-O linker, a shared lib and a loadable
# object file is not the same thing.
DED_LDFLAGS="-bundle -flat_namespace -undefined suppress"
- DED_CFLAGS="$DED_CFLAGS -fno-common"
+ DED_LD="$CC"
;;
*)
# assume GNU linker and ELF
DED_LDFLAGS="-shared"
;;
esac
+
+AC_CHECK_PROGS(DED_LD, [$LD ld.sh])
+AC_CHECK_TOOL(DED_LD, ld, no_ld)
+if test "$DED_LD" = no_ld; then
+ AC_MSG_ERROR([ld is required to build the flex scanner!])
+fi
+
+AC_MSG_CHECKING(for linker flags for loadable drivers)
DED_LDFLAGS="$LDFLAGS $DED_LDFLAGS"
AC_MSG_RESULT([$DED_LDFLAGS])
-AC_SUBST(DED_LDFLAGS)
+fi dnl --- end no usable otp_ded.mk.in ---
+
+AC_SUBST(HAVE_USABLE_OTP_DED_MK)
+AC_SUBST(DED_CFLAGS)
+AC_SUBST(DED_INCLUDES)
+AC_SUBST(DED_THR_DEFS)
+AC_SUBST(DED_LDFLAGS)
AC_CHECK_PROG(PERL, perl, perl, no_perl)
if test "$PERL" = no_perl; then
AC_MSG_ERROR([Perl is required to build the flex scanner!])
fi
-
-dnl This is the os flavour, should be unix, vxworks or win32
-if test "X$host" = "Xwin32"; then
- ERLANG_OSTYPE=win32
-else
- ERLANG_OSTYPE=unix
-fi
-
-AC_SUBST(ERLANG_OSTYPE)
-
-
AC_OUTPUT(src/flex/$host/Makefile:src/flex/Makefile.in)
diff --git a/lib/megaco/doc/src/Makefile b/lib/megaco/doc/src/Makefile
index 2c55e92914..2355a1b8b9 100644
--- a/lib/megaco/doc/src/Makefile
+++ b/lib/megaco/doc/src/Makefile
@@ -1,19 +1,19 @@
#
# %CopyrightBegin%
-#
-# Copyright Ericsson AB 2000-2009. All Rights Reserved.
-#
+#
+# Copyright Ericsson AB 2000-2010. All Rights Reserved.
+#
# The contents of this file are subject to the Erlang Public License,
# Version 1.1, (the "License"); you may not use this file except in
# compliance with the License. You should have received a copy of the
# Erlang Public License along with this software. If not, it can be
# retrieved online at http://www.erlang.org/.
-#
+#
# Software distributed under the License is distributed on an "AS IS"
# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
# the License for the specific language governing rights and limitations
# under the License.
-#
+#
# %CopyrightEnd%
include $(ERL_TOP)/make/target.mk
@@ -49,6 +49,9 @@ include files.mk
# ----------------------------------------------------
+XML_FILES = $(BOOK_FILES) $(XML_APPLICATION_FILES) $(XML_REF3_FILES) \
+ $(XML_PART_FILES) $(XML_CHAPTER_FILES)
+
INTERNAL_HTML_FILES = $(TECHNICAL_DESCR_FILES:%.xml=$(HTMLDIR)/%.html)
HTML_APP_FILES = $(XML_APPLICATION_FILES:%.xml=$(HTMLDIR)/%.html)
@@ -104,8 +107,10 @@ INDEX_SRC = $(INDEX_FILE).src
INDEX_TARGET = $(DOCDIR)/$(INDEX_FILE)
STANDARD_DIR = ../standard
-STANDARDS = $(STANDARD_DIR)/rfc3015.txt \
- $(STANDARD_DIR)/implementors_guide_v6.pdf
+STANDARDS = $(STANDARD_DIR)/rfc3525.txt \
+ $(STANDARD_DIR)/rfc4234.txt \
+ $(STANDARD_DIR)/rfc4566.txt \
+ $(STANDARD_DIR)/implementors_guide_v10-13.pdf
# ----------------------------------------------------
# FLAGS
diff --git a/lib/megaco/doc/src/megaco.xml b/lib/megaco/doc/src/megaco.xml
index 0fb9d5aac6..ae9e250965 100644
--- a/lib/megaco/doc/src/megaco.xml
+++ b/lib/megaco/doc/src/megaco.xml
@@ -4,7 +4,7 @@
<erlref>
<header>
<copyright>
- <year>2000</year><year>2009</year>
+ <year>2000</year><year>2010</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
@@ -13,12 +13,12 @@
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>megaco</title>
@@ -40,6 +40,16 @@
<section>
<title>DATA TYPES</title>
<code type="none"><![CDATA[
+megaco_mid() = ip4Address() | ip6Address() |
+ domainName() | deviceName() |
+ mtpAddress()
+ip4Address() = #'IP4Address'{}
+ip6Address() = #'IP6Address'{}
+domainName() = #'DomainName'{}
+deviceName() = pathName()
+pathName() = ia5String(1..64)
+mtpAddress() = octetString(2..4)
+
action_request() = #'ActionRequest'{}
action_reply() = #'ActionReply'{}
error_desc() = #'ErrorDescriptor'{}
diff --git a/lib/megaco/doc/src/megaco_codec_transform.xml b/lib/megaco/doc/src/megaco_codec_transform.xml
index 71f7fc689f..89ed3fd654 100644
--- a/lib/megaco/doc/src/megaco_codec_transform.xml
+++ b/lib/megaco/doc/src/megaco_codec_transform.xml
@@ -4,7 +4,7 @@
<erlref>
<header>
<copyright>
- <year>2002</year><year>2009</year>
+ <year>2002</year><year>2010</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
@@ -13,12 +13,12 @@
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>megaco_codec_transform</title>
@@ -36,8 +36,8 @@
<description>
<p>This module implements a simple megaco message transformation utility.</p>
- <p><em>Note</em> that this module is <em>not</em> included in the runtime part of
- the application.</p>
+ <p><em>Note</em> that this module is <em>not</em> included in the
+ runtime part of the application.</p>
<marker id="export_messages"></marker>
</description>
@@ -51,15 +51,16 @@
<v>MessagePackage = atom()</v>
</type>
<desc>
- <p>Export the messages in the <c>MessagePackage</c> (default is <c>time_test</c>). </p>
- <p>The out produced by this function is a directory structure with the
- following structure: </p>
+ <p>Export the messages in the <c>MessagePackage</c> (default
+ is <c>time_test</c>). </p>
+ <p>The output produced by this function is a directory structure
+ with the following structure: </p>
<code type="none"><![CDATA[
-\011 <message package>/pretty/<message-files>
-\011 compact/<message-files>
-\011 per/<message-files>
-\011 ber/<message-files>
-\011 erlang/<message-files>
+<message package>/pretty/<message-files>
+ compact/<message-files>
+ per/<message-files>
+ ber/<message-files>
+ erlang/<message-files>
]]></code>
</desc>
</func>
diff --git a/lib/megaco/doc/src/megaco_debug.xml b/lib/megaco/doc/src/megaco_debug.xml
index 1b99985341..2523a3be86 100644
--- a/lib/megaco/doc/src/megaco_debug.xml
+++ b/lib/megaco/doc/src/megaco_debug.xml
@@ -4,7 +4,7 @@
<chapter>
<header>
<copyright>
- <year>2000</year><year>2009</year>
+ <year>2000</year><year>2010</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
@@ -13,12 +13,12 @@
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>Testing and tools</title>
@@ -159,12 +159,12 @@
<p>When run as above (this will take some time), the measurement
process is done as follows:</p>
<pre>
-\011 For each codec:
-\011 For each message:
-\011 Read the message from the file
-\011 Detect message version
-\011 Measure decode
- Measure encode
+For each codec:
+ For each message:
+ Read the message from the file
+ Detect message version
+ Measure decode
+ Measure encode
Write results, encode, decode and total, to file
</pre>
</item>
@@ -218,11 +218,11 @@ message() = binary()
with the following structure:
</p>
<code type="none"><![CDATA[
-\011 <message package>/pretty/<message-files>
-\011 compact/
-\011 per/
-\011 ber/<message-files>
-\011 erlang/
+<message package>/pretty/<message-files>
+ compact/
+ per/
+ ber/<message-files>
+ erlang/
]]></code>
<p>The file includes both version 1, 2 and version 3 messages.</p>
</section>
diff --git a/lib/megaco/doc/src/megaco_mib.xml b/lib/megaco/doc/src/megaco_mib.xml
index 3c0a549590..f1abe08fb5 100644
--- a/lib/megaco/doc/src/megaco_mib.xml
+++ b/lib/megaco/doc/src/megaco_mib.xml
@@ -4,7 +4,7 @@
<chapter>
<header>
<copyright>
- <year>2002</year><year>2009</year>
+ <year>2002</year><year>2010</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
@@ -13,12 +13,12 @@
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>Megaco mib</title>
@@ -50,15 +50,15 @@
lightweight. I.e. the statistic counters are handled
separately by different entities of the application. For
instance our two transport module(s) (see <seealso marker="megaco_tcp#stats">megaco_tcp</seealso> and <seealso marker="megaco_udp#stats">megaco_udp</seealso>) maintain their
- own counters and the application engine (see <seealso marker="megaco#stats">megaco</seealso>) maintain it's own
+ own counters and the application engine (see <seealso marker="megaco#stats">megaco</seealso>) maintain its own
counters.</p>
<p>This also means that if a user implement their own transport
- service then it has to maintain it's own statistics.</p>
+ service then it has to maintain its own statistics.</p>
</section>
<section>
<title>Distribution</title>
- <p>Each megaco application maintains it's own set of counters. So
+ <p>Each megaco application maintains its own set of counters. So
in a large (distributed) MG/MGC it could be necessary to
collect the statistics from several nodes (each) running the
megaco application (only one of them with the transport).</p>
diff --git a/lib/megaco/doc/src/megaco_performance.xml b/lib/megaco/doc/src/megaco_performance.xml
index b34ee4f389..72b5c156ba 100644
--- a/lib/megaco/doc/src/megaco_performance.xml
+++ b/lib/megaco/doc/src/megaco_performance.xml
@@ -4,7 +4,7 @@
<chapter>
<header>
<copyright>
- <year>2002</year><year>2009</year>
+ <year>2002</year><year>2010</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
@@ -13,12 +13,12 @@
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>Performance comparison</title>
@@ -257,12 +257,12 @@ MEGACO/1 [124.124.124.222]
Transaction = 9998 {
Context = - {
ServiceChange = ROOT {
- \011Services {
- \011 Method = Restart,
- \011 ServiceChangeAddress = 55555,
- \011 Profile = ResGW/1,
- \011 Reason = "901 MG Cold Boot"
- \011}
+ Services {
+ Method = Restart,
+ ServiceChangeAddress = 55555,
+ Profile = ResGW/1,
+ Reason = "901 MG Cold Boot"
+ }
}
}
} </pre>
diff --git a/lib/megaco/doc/src/megaco_run.xml b/lib/megaco/doc/src/megaco_run.xml
index 3afc638bcf..9ed589b079 100644
--- a/lib/megaco/doc/src/megaco_run.xml
+++ b/lib/megaco/doc/src/megaco_run.xml
@@ -4,7 +4,7 @@
<chapter>
<header>
<copyright>
- <year>2000</year><year>2009</year>
+ <year>2000</year><year>2010</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
@@ -13,12 +13,12 @@
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>Running the stack</title>
@@ -365,7 +365,7 @@
then the specified max message size (see the
<seealso marker="megaco#user_info">max_pdu_size</seealso> option).
Finally, if segmentation is decided, then each action reply
- will make up it's own (segment) message.</p>
+ will make up its own (segment) message.</p>
</item>
</list>
</section>
diff --git a/lib/megaco/doc/src/megaco_user.xml b/lib/megaco/doc/src/megaco_user.xml
index 37942007bc..7332fa684d 100644
--- a/lib/megaco/doc/src/megaco_user.xml
+++ b/lib/megaco/doc/src/megaco_user.xml
@@ -4,7 +4,7 @@
<erlref>
<header>
<copyright>
- <year>2000</year><year>2009</year>
+ <year>2000</year><year>2010</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
@@ -13,12 +13,12 @@
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>megaco_user</title>
@@ -471,7 +471,7 @@ protocol_version() = integer() ]]></code>
<v>transaction_result() = action_reps()</v>
<v>segment_result() = {segment_no(), last_segment(), action_reps()}</v>
<v>action_reps() = [action_reply()]</v>
- <v>failure() = {error, reason()}</v>
+ <v>failure() = {error, reason()} | {error, ReplyNo, reason()}</v>
<v>reason() = transaction_reason() | segment_reason() | user_cancel_reason() | send_reason() | other_reason()</v>
<v>transaction_reason() = error_desc()</v>
<v>segment_reason() = {segment_no(), last_segment(), error_desc()}</v>
@@ -486,6 +486,7 @@ protocol_version() = integer() ]]></code>
<v>send_failed_reason() = {send_message_failed, reason_for_send_failure()}</v>
<v>reason_for_send_failure() = term()</v>
<v>ReplyData = reply_data()</v>
+ <v>ReplyNo = integer() > 0</v>
<v>reply_data() = term()</v>
<v>Extra = term()</v>
</type>
@@ -669,7 +670,7 @@ protocol_version() = integer() ]]></code>
<p>Invoked when a unexpected message is received</p>
<p>If a reply to a request is not received in time, the
megaco stack removes all info about the request from
- it's tables. If a reply should arrive after this has been
+ its tables. If a reply should arrive after this has been
done the app has no way of knowing where to send this message.
The message is delivered to the "user" by calling this
function on the local node (the node which has the link).</p>
diff --git a/lib/megaco/doc/src/notes.xml b/lib/megaco/doc/src/notes.xml
index 26c64f7c52..99a3784402 100644
--- a/lib/megaco/doc/src/notes.xml
+++ b/lib/megaco/doc/src/notes.xml
@@ -4,7 +4,7 @@
<chapter>
<header>
<copyright>
- <year>2000</year><year>2009</year>
+ <year>2000</year><year>2010</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
@@ -13,12 +13,12 @@
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>Megaco Release Notes</title>
@@ -36,6 +36,133 @@
section is the version number of Megaco.</p>
<section>
+ <title>Megaco 3.14.1</title>
+
+ <p>Version 3.14.1 supports code replacement in runtime from/to
+ version 3.14, 3.13, 3.12 and 3.11.3.</p>
+
+ <section>
+ <title>Improvements and new features</title>
+
+<!--
+ <p>-</p>
+-->
+
+ <list type="bulleted">
+ <item>
+ <p>A minor compiler related performance improvement. </p>
+ <p>Own Id: OTP-8561</p>
+ </item>
+
+ </list>
+
+ </section>
+
+ <section>
+ <title>Fixed bugs and malfunctions</title>
+<!--
+ <p>-</p>
+-->
+
+ <list type="bulleted">
+ <item>
+ <p>A raise condition when, during high load, processing
+ both the original and a resent message and delivering
+ this as two separate messages to the user. </p>
+ <p>Note that this solution only protects against multiple
+ reply deliveries! </p>
+ <p>Own Id: OTP-8529</p>
+ <p>Aux Id: Seq 10915</p>
+ </item>
+
+ <item>
+ <p>Fix shared libraries installation. </p>
+ <p>The flex shared lib(s) were incorrectly installed as data
+ files. </p>
+ <p>Peter Lemenkov</p>
+ <p>Own Id: OTP-8627</p>
+ </item>
+
+ <item>
+ <p>Eliminated a possible raise condition while creating
+ pending counters. </p>
+ <p>Own Id: OTP-8634</p>
+ <p>Aux Id: Seq 11579</p>
+ </item>
+
+ </list>
+
+ </section>
+
+ </section> <!-- 3.14.1 -->
+
+
+ <section>
+ <title>Megaco 3.14</title>
+
+ <p>Version 3.14 supports code replacement in runtime from/to
+ version 3.13, 3.12 and 3.11.3.</p>
+
+ <section>
+ <title>Improvements and new features</title>
+
+<!--
+ <p>-</p>
+-->
+
+ <list type="bulleted">
+ <item>
+ <p>Various changes to configure and makefile(s) to facilitate cross
+ compilation (and other build system improvements). </p>
+ <p>Own Id: OTP-8323</p>
+ </item>
+
+ <item>
+ <p>Added a help target in the test Makefile to explain
+ the most useful make targets, used when testing the
+ application using the test-server provided with megaco.</p>
+ <p>Own Id: OTP-8362</p>
+ </item>
+
+ <item>
+ <p>Adapted megaco_filter to the new internal format.</p>
+ <p>Own Id: OTP-8403</p>
+ </item>
+ </list>
+
+ </section>
+
+ <section>
+ <title>Fixed bugs and malfunctions</title>
+<!--
+ <p>-</p>
+-->
+
+ <list type="bulleted">
+ <item>
+ <p>Callbacks, when the callback module is unknown (undefined),
+ results in warning messages. </p>
+ <p>A raise condition scenario. As part of a cancelation operation,
+ replies with waiting acknowledgements is cancelled. This includes
+ informing the user (via a call to the handle_trans_ack callback
+ function). It is possible that at this point the connection data
+ has been removed, which makes it impossible for megaco to
+ perform this operation, resulting in the warning message. The
+ solution is to also store the callback module with the other
+ reply information, to be used when cleaning up after a
+ cancelation. </p>
+ <p>Own Id: OTP-8328</p>
+ <p>Aux Id: Seq 11384</p>
+ </item>
+
+ </list>
+
+ </section>
+
+ </section> <!-- 3.14 -->
+
+
+ <section>
<title>Megaco 3.13</title>
<p>Version 3.13 supports code replacement in runtime from/to
diff --git a/lib/megaco/doc/src/notes_history.xml b/lib/megaco/doc/src/notes_history.xml
index 97aa4c66a5..640b62230f 100644
--- a/lib/megaco/doc/src/notes_history.xml
+++ b/lib/megaco/doc/src/notes_history.xml
@@ -4,7 +4,7 @@
<chapter>
<header>
<copyright>
- <year>2006</year><year>2009</year>
+ <year>2006</year><year>2010</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
@@ -13,12 +13,12 @@
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>Megaco Release Notes history</title>
@@ -2764,7 +2764,7 @@
<p>Added a new configuration parameter, threaded.
This tells the megaco app, that all
transaction requests in a message should be executed
- in parallel (e.g. each in it's own process).
+ in parallel (e.g. each in its own process).
<br></br>See the
<seealso marker="megaco#user_info">threaded</seealso> parameter
of the user_info function (also conn_info).</p>
@@ -2911,7 +2911,7 @@
<title>Improvements and new features</title>
<list type="bulleted">
<item>
- <p>This is just a code up-/downgrade cleanup release. I.e. It's the
+ <p>This is just a code up-/downgrade cleanup release. I.e. it's the
same as version 1.2 minus the ugly stuff needed to handle up-/downgrade
from/to version 1.1.2, 1.1.1 and 1.1.0.</p>
</item>
diff --git a/lib/megaco/doc/standard/H.248.1-Corr1-200403.doc b/lib/megaco/doc/standard/H.248.1-Corr1-200403.doc
deleted file mode 100644
index 39ef6e4efa..0000000000
--- a/lib/megaco/doc/standard/H.248.1-Corr1-200403.doc
+++ /dev/null
Binary files differ
diff --git a/lib/megaco/doc/standard/rfc2327.txt b/lib/megaco/doc/standard/rfc2327.txt
deleted file mode 100644
index ce77de6128..0000000000
--- a/lib/megaco/doc/standard/rfc2327.txt
+++ /dev/null
@@ -1,2355 +0,0 @@
-
-
-
-
-
-
-Network Working Group M. Handley
-Request for Comments: 2327 V. Jacobson
-Category: Standards Track ISI/LBNL
- April 1998
-
-
- SDP: Session Description Protocol
-
-Status of this Memo
-
- This document specifies an Internet standards track protocol for the
- Internet community, and requests discussion and suggestions for
- improvements. Please refer to the current edition of the "Internet
- Official Protocol Standards" (STD 1) for the standardization state
- and status of this protocol. Distribution of this memo is unlimited.
-
-Copyright Notice
-
- Copyright (C) The Internet Society (1998). All Rights Reserved.
-
-Abstract
-
- This document defines the Session Description Protocol, SDP. SDP is
- intended for describing multimedia sessions for the purposes of
- session announcement, session invitation, and other forms of
- multimedia session initiation.
-
- This document is a product of the Multiparty Multimedia Session
- Control (MMUSIC) working group of the Internet Engineering Task
- Force. Comments are solicited and should be addressed to the working
- group's mailing list at [email protected] and/or the authors.
-
-1. Introduction
-
- On the Internet multicast backbone (Mbone), a session directory tool
- is used to advertise multimedia conferences and communicate the
- conference addresses and conference tool-specific information
- necessary for participation. This document defines a session
- description protocol for this purpose, and for general real-time
- multimedia session description purposes. This memo does not describe
- multicast address allocation or the distribution of SDP messages in
- detail. These are described in accompanying memos. SDP is not
- intended for negotiation of media encodings.
-
-
-
-
-
-
-
-
-Handley & Jacobson Standards Track [Page 1]
-
-RFC 2327 SDP April 1998
-
-
-2. Background
-
- The Mbone is the part of the internet that supports IP multicast, and
- thus permits efficient many-to-many communication. It is used
- extensively for multimedia conferencing. Such conferences usually
- have the property that tight coordination of conference membership is
- not necessary; to receive a conference, a user at an Mbone site only
- has to know the conference's multicast group address and the UDP
- ports for the conference data streams.
-
- Session directories assist the advertisement of conference sessions
- and communicate the relevant conference setup information to
- prospective participants. SDP is designed to convey such information
- to recipients. SDP is purely a format for session description - it
- does not incorporate a transport protocol, and is intended to use
- different transport protocols as appropriate including the Session
- Announcement Protocol [4], Session Initiation Protocol [11], Real-
- Time Streaming Protocol [12], electronic mail using the MIME
- extensions, and the Hypertext Transport Protocol.
-
- SDP is intended to be general purpose so that it can be used for a
- wider range of network environments and applications than just
- multicast session directories. However, it is not intended to
- support negotiation of session content or media encodings - this is
- viewed as outside the scope of session description.
-
-3. Glossary of Terms
-
- The following terms are used in this document, and have specific
- meaning within the context of this document.
-
- Conference
- A multimedia conference is a set of two or more communicating users
- along with the software they are using to communicate.
-
- Session
- A multimedia session is a set of multimedia senders and receivers
- and the data streams flowing from senders to receivers. A
- multimedia conference is an example of a multimedia session.
-
- Session Advertisement
- See session announcement.
-
- Session Announcement
- A session announcement is a mechanism by which a session
- description is conveyed to users in a proactive fashion, i.e., the
- session description was not explicitly requested by the user.
-
-
-
-
-Handley & Jacobson Standards Track [Page 2]
-
-RFC 2327 SDP April 1998
-
-
- Session Description
- A well defined format for conveying sufficient information to
- discover and participate in a multimedia session.
-
-3.1. Terminology
-
- The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT",
- "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this
- document are to be interpreted as described in RFC 2119.
-
-4. SDP Usage
-
-4.1. Multicast Announcements
-
- SDP is a session description protocol for multimedia sessions. A
- common mode of usage is for a client to announce a conference session
- by periodically multicasting an announcement packet to a well known
- multicast address and port using the Session Announcement Protocol
- (SAP).
-
- SAP packets are UDP packets with the following format:
-
- |--------------------|
- | SAP header |
- |--------------------|
- | text payload |
- |//////////
-
-
- The header is the Session Announcement Protocol header. SAP is
- described in more detail in a companion memo [4]
-
- The text payload is an SDP session description, as described in this
- memo. The text payload should be no greater than 1 Kbyte in length.
- If announced by SAP, only one session announcement is permitted in a
- single packet.
-
-4.2. Email and WWW Announcements
-
- Alternative means of conveying session descriptions include
- electronic mail and the World Wide Web. For both email and WWW
- distribution, the use of the MIME content type "application/sdp"
- should be used. This enables the automatic launching of applications
- for participation in the session from the WWW client or mail reader
- in a standard manner.
-
-
-
-
-
-
-Handley & Jacobson Standards Track [Page 3]
-
-RFC 2327 SDP April 1998
-
-
- Note that announcements of multicast sessions made only via email or
- the World Wide Web (WWW) do not have the property that the receiver
- of a session announcement can necessarily receive the session because
- the multicast sessions may be restricted in scope, and access to the
- WWW server or reception of email is possible outside this scope. SAP
- announcements do not suffer from this mismatch.
-
-5. Requirements and Recommendations
-
- The purpose of SDP is to convey information about media streams in
- multimedia sessions to allow the recipients of a session description
- to participate in the session. SDP is primarily intended for use in
- an internetwork, although it is sufficiently general that it can
- describe conferences in other network environments.
-
- A multimedia session, for these purposes, is defined as a set of
- media streams that exist for some duration of time. Media streams
- can be many-to-many. The times during which the session is active
- need not be continuous.
-
- Thus far, multicast based sessions on the Internet have differed from
- many other forms of conferencing in that anyone receiving the traffic
- can join the session (unless the session traffic is encrypted). In
- such an environment, SDP serves two primary purposes. It is a means
- to communicate the existence of a session, and is a means to convey
- sufficient information to enable joining and participating in the
- session. In a unicast environment, only the latter purpose is likely
- to be relevant.
-
- Thus SDP includes:
-
- o Session name and purpose
-
- o Time(s) the session is active
-
- o The media comprising the session
-
- o Information to receive those media (addresses, ports, formats and
- so on)
-
- As resources necessary to participate in a session may be limited,
- some additional information may also be desirable:
-
- o Information about the bandwidth to be used by the conference
-
- o Contact information for the person responsible for the session
-
-
-
-
-
-Handley & Jacobson Standards Track [Page 4]
-
-RFC 2327 SDP April 1998
-
-
- In general, SDP must convey sufficient information to be able to join
- a session (with the possible exception of encryption keys) and to
- announce the resources to be used to non-participants that may need
- to know.
-
-5.1. Media Information
-
- SDP includes:
-
- o The type of media (video, audio, etc)
-
- o The transport protocol (RTP/UDP/IP, H.320, etc)
-
- o The format of the media (H.261 video, MPEG video, etc)
-
- For an IP multicast session, the following are also conveyed:
-
- o Multicast address for media
-
- o Transport Port for media
-
- This address and port are the destination address and destination
- port of the multicast stream, whether being sent, received, or both.
-
- For an IP unicast session, the following are conveyed:
-
- o Remote address for media
-
- o Transport port for contact address
-
- The semantics of this address and port depend on the media and
- transport protocol defined. By default, this is the remote address
- and remote port to which data is sent, and the remote address and
- local port on which to receive data. However, some media may define
- to use these to establish a control channel for the actual media
- flow.
-
-5.2. Timing Information
-
- Sessions may either be bounded or unbounded in time. Whether or not
- they are bounded, they may be only active at specific times.
-
- SDP can convey:
-
- o An arbitrary list of start and stop times bounding the session
-
- o For each bound, repeat times such as "every Wednesday at 10am for
- one hour"
-
-
-
-Handley & Jacobson Standards Track [Page 5]
-
-RFC 2327 SDP April 1998
-
-
- This timing information is globally consistent, irrespective of local
- time zone or daylight saving time.
-
-5.3. Private Sessions
-
- It is possible to create both public sessions and private sessions.
- Private sessions will typically be conveyed by encrypting the session
- description to distribute it. The details of how encryption is
- performed are dependent on the mechanism used to convey SDP - see [4]
- for how this is done for session announcements.
-
- If a session announcement is private it is possible to use that
- private announcement to convey encryption keys necessary to decode
- each of the media in a conference, including enough information to
- know which encryption scheme is used for each media.
-
-5.4. Obtaining Further Information about a Session
-
- A session description should convey enough information to decide
- whether or not to participate in a session. SDP may include
- additional pointers in the form of Universal Resources Identifiers
- (URIs) for more information about the session.
-
-5.5. Categorisation
-
- When many session descriptions are being distributed by SAP or any
- other advertisement mechanism, it may be desirable to filter
- announcements that are of interest from those that are not. SDP
- supports a categorisation mechanism for sessions that is capable of
- being automated.
-
-5.6. Internationalization
-
- The SDP specification recommends the use of the ISO 10646 character
- sets in the UTF-8 encoding (RFC 2044) to allow many different
- languages to be represented. However, to assist in compact
- representations, SDP also allows other character sets such as ISO
- 8859-1 to be used when desired. Internationalization only applies to
- free-text fields (session name and background information), and not
- to SDP as a whole.
-
-6. SDP Specification
-
- SDP session descriptions are entirely textual using the ISO 10646
- character set in UTF-8 encoding. SDP field names and attributes names
- use only the US-ASCII subset of UTF-8, but textual fields and
- attribute values may use the full ISO 10646 character set. The
- textual form, as opposed to a binary encoding such as ASN/1 or XDR,
-
-
-
-Handley & Jacobson Standards Track [Page 6]
-
-RFC 2327 SDP April 1998
-
-
- was chosen to enhance portability, to enable a variety of transports
- to be used (e.g, session description in a MIME email message) and to
- allow flexible, text-based toolkits (e.g., Tcl/Tk ) to be used to
- generate and to process session descriptions. However, since the
- total bandwidth allocated to all SAP announcements is strictly
- limited, the encoding is deliberately compact. Also, since
- announcements may be transported via very unreliable means (e.g.,
- email) or damaged by an intermediate caching server, the encoding was
- designed with strict order and formatting rules so that most errors
- would result in malformed announcements which could be detected
- easily and discarded. This also allows rapid discarding of encrypted
- announcements for which a receiver does not have the correct key.
-
- An SDP session description consists of a number of lines of text of
- the form <type>=<value> <type> is always exactly one character and is
- case-significant. <value> is a structured text string whose format
- depends on <type>. It also will be case-significant unless a
- specific field defines otherwise. Whitespace is not permitted either
- side of the `=' sign. In general <value> is either a number of fields
- delimited by a single space character or a free format string.
-
- A session description consists of a session-level description
- (details that apply to the whole session and all media streams) and
- optionally several media-level descriptions (details that apply onto
- to a single media stream).
-
- An announcement consists of a session-level section followed by zero
- or more media-level sections. The session-level part starts with a
- `v=' line and continues to the first media-level section. The media
- description starts with an `m=' line and continues to the next media
- description or end of the whole session description. In general,
- session-level values are the default for all media unless overridden
- by an equivalent media-level value.
-
- When SDP is conveyed by SAP, only one session description is allowed
- per packet. When SDP is conveyed by other means, many SDP session
- descriptions may be concatenated together (the `v=' line indicating
- the start of a session description terminates the previous
- description). Some lines in each description are required and some
- are optional but all must appear in exactly the order given here (the
- fixed order greatly enhances error detection and allows for a simple
- parser). Optional items are marked with a `*'.
-
-Session description
- v= (protocol version)
- o= (owner/creator and session identifier).
- s= (session name)
- i=* (session information)
-
-
-
-Handley & Jacobson Standards Track [Page 7]
-
-RFC 2327 SDP April 1998
-
-
- u=* (URI of description)
- e=* (email address)
- p=* (phone number)
- c=* (connection information - not required if included in all media)
- b=* (bandwidth information)
- One or more time descriptions (see below)
- z=* (time zone adjustments)
- k=* (encryption key)
- a=* (zero or more session attribute lines)
- Zero or more media descriptions (see below)
-
-Time description
- t= (time the session is active)
- r=* (zero or more repeat times)
-
-Media description
- m= (media name and transport address)
- i=* (media title)
- c=* (connection information - optional if included at session-level)
- b=* (bandwidth information)
- k=* (encryption key)
- a=* (zero or more media attribute lines)
-
- The set of `type' letters is deliberately small and not intended to
- be extensible -- SDP parsers must completely ignore any announcement
- that contains a `type' letter that it does not understand. The
- `attribute' mechanism ("a=" described below) is the primary means for
- extending SDP and tailoring it to particular applications or media.
- Some attributes (the ones listed in this document) have a defined
- meaning but others may be added on an application-, media- or
- session-specific basis. A session directory must ignore any
- attribute it doesn't understand.
-
- The connection (`c=') and attribute (`a=') information in the
- session-level section applies to all the media of that session unless
- overridden by connection information or an attribute of the same name
- in the media description. For instance, in the example below, each
- media behaves as if it were given a `recvonly' attribute.
-
- An example SDP description is:
-
- v=0
- o=mhandley 2890844526 2890842807 IN IP4 126.16.64.4
- s=SDP Seminar
- i=A Seminar on the session description protocol
- u=http://www.cs.ucl.ac.uk/staff/M.Handley/sdp.03.ps
- [email protected] (Mark Handley)
- c=IN IP4 224.2.17.12/127
-
-
-
-Handley & Jacobson Standards Track [Page 8]
-
-RFC 2327 SDP April 1998
-
-
- t=2873397496 2873404696
- a=recvonly
- m=audio 49170 RTP/AVP 0
- m=video 51372 RTP/AVP 31
- m=application 32416 udp wb
- a=orient:portrait
-
- Text records such as the session name and information are bytes
- strings which may contain any byte with the exceptions of 0x00 (Nul),
- 0x0a (ASCII newline) and 0x0d (ASCII carriage return). The sequence
- CRLF (0x0d0a) is used to end a record, although parsers should be
- tolerant and also accept records terminated with a single newline
- character. By default these byte strings contain ISO-10646
- characters in UTF-8 encoding, but this default may be changed using
- the `charset' attribute.
-
- Protocol Version
-
- v=0
-
- The "v=" field gives the version of the Session Description Protocol.
- There is no minor version number.
-
- Origin
-
- o=<username> <session id> <version> <network type> <address type>
- <address>
-
- The "o=" field gives the originator of the session (their username
- and the address of the user's host) plus a session id and session
- version number.
-
- <username> is the user's login on the originating host, or it is "-"
- if the originating host does not support the concept of user ids.
- <username> must not contain spaces. <session id> is a numeric string
- such that the tuple of <username>, <session id>, <network type>,
- <address type> and <address> form a globally unique identifier for
- the session.
-
- The method of <session id> allocation is up to the creating tool, but
- it has been suggested that a Network Time Protocol (NTP) timestamp be
- used to ensure uniqueness [1].
-
- <version> is a version number for this announcement. It is needed
- for proxy announcements to detect which of several announcements for
- the same session is the most recent. Again its usage is up to the
-
-
-
-
-
-Handley & Jacobson Standards Track [Page 9]
-
-RFC 2327 SDP April 1998
-
-
- creating tool, so long as <version> is increased when a modification
- is made to the session data. Again, it is recommended (but not
- mandatory) that an NTP timestamp is used.
-
- <network type> is a text string giving the type of network.
- Initially "IN" is defined to have the meaning "Internet". <address
- type> is a text string giving the type of the address that follows.
- Initially "IP4" and "IP6" are defined. <address> is the globally
- unique address of the machine from which the session was created.
- For an address type of IP4, this is either the fully-qualified domain
- name of the machine, or the dotted-decimal representation of the IP
- version 4 address of the machine. For an address type of IP6, this
- is either the fully-qualified domain name of the machine, or the
- compressed textual representation of the IP version 6 address of the
- machine. For both IP4 and IP6, the fully-qualified domain name is
- the form that SHOULD be given unless this is unavailable, in which
- case the globally unique address may be substituted. A local IP
- address MUST NOT be used in any context where the SDP description
- might leave the scope in which the address is meaningful.
-
- In general, the "o=" field serves as a globally unique identifier for
- this version of this session description, and the subfields excepting
- the version taken together identify the session irrespective of any
- modifications.
-
- Session Name
-
- s=<session name>
-
- The "s=" field is the session name. There must be one and only one
- "s=" field per session description, and it must contain ISO 10646
- characters (but see also the `charset' attribute below).
-
- Session and Media Information
-
- i=<session description>
-
- The "i=" field is information about the session. There may be at
- most one session-level "i=" field per session description, and at
- most one "i=" field per media. Although it may be omitted, this is
- discouraged for session announcements, and user interfaces for
- composing sessions should require text to be entered. If it is
- present it must contain ISO 10646 characters (but see also the
- `charset' attribute below).
-
- A single "i=" field can also be used for each media definition. In
- media definitions, "i=" fields are primarily intended for labeling
- media streams. As such, they are most likely to be useful when a
-
-
-
-Handley & Jacobson Standards Track [Page 10]
-
-RFC 2327 SDP April 1998
-
-
- single session has more than one distinct media stream of the same
- media type. An example would be two different whiteboards, one for
- slides and one for feedback and questions.
-
- URI
-
- u=<URI>
-
- o A URI is a Universal Resource Identifier as used by WWW clients
-
- o The URI should be a pointer to additional information about the
- conference
-
- o This field is optional, but if it is present it should be specified
- before the first media field
-
- o No more than one URI field is allowed per session description
-
-
- Email Address and Phone Number
-
- e=<email address>
- p=<phone number>
-
- o These specify contact information for the person responsible for
- the conference. This is not necessarily the same person that
- created the conference announcement.
-
- o Either an email field or a phone field must be specified.
- Additional email and phone fields are allowed.
-
- o If these are present, they should be specified before the first
- media field.
-
- o More than one email or phone field can be given for a session
- description.
-
- o Phone numbers should be given in the conventional international
-
- format - preceded by a "+ and the international country code.
- There must be a space or a hyphen ("-") between the country code
- and the rest of the phone number. Spaces and hyphens may be used
- to split up a phone field to aid readability if desired. For
- example:
-
- p=+44-171-380-7777 or p=+1 617 253 6011
-
-
-
-
-
-Handley & Jacobson Standards Track [Page 11]
-
-RFC 2327 SDP April 1998
-
-
- o Both email addresses and phone numbers can have an optional free
- text string associated with them, normally giving the name of the
- person who may be contacted. This should be enclosed in
- parenthesis if it is present. For example:
-
- [email protected] (Mark Handley)
-
- The alternative RFC822 name quoting convention is also allowed for
- both email addresses and phone numbers. For example,
-
- e=Mark Handley <[email protected]>
-
- The free text string should be in the ISO-10646 character set with
- UTF-8 encoding, or alternatively in ISO-8859-1 or other encodings
- if the appropriate charset session-level attribute is set.
-
- Connection Data
-
- c=<network type> <address type> <connection address>
-
- The "c=" field contains connection data.
-
- A session announcement must contain one "c=" field in each media
- description (see below) or a "c=" field at the session-level. It may
- contain a session-level "c=" field and one additional "c=" field per
- media description, in which case the per-media values override the
- session-level settings for the relevant media.
-
- The first sub-field is the network type, which is a text string
- giving the type of network. Initially "IN" is defined to have the
- meaning "Internet".
-
- The second sub-field is the address type. This allows SDP to be used
- for sessions that are not IP based. Currently only IP4 is defined.
-
- The third sub-field is the connection address. Optional extra
- subfields may be added after the connection address depending on the
- value of the <address type> field.
-
- For IP4 addresses, the connection address is defined as follows:
-
- o Typically the connection address will be a class-D IP multicast
-
- group address. If the session is not multicast, then the
- connection address contains the fully-qualified domain name or the
- unicast IP address of the expected data source or data relay or
- data sink as determined by additional attribute fields. It is not
- expected that fully-qualified domain names or unicast addresses
-
-
-
-Handley & Jacobson Standards Track [Page 12]
-
-RFC 2327 SDP April 1998
-
-
- will be given in a session description that is communicated by a
- multicast announcement, though this is not prohibited. If a
- unicast data stream is to pass through a network address
- translator, the use of a fully-qualified domain name rather than an
- unicast IP address is RECOMMENDED. In other cases, the use of an
- IP address to specify a particular interface on a multi-homed host
- might be required. Thus this specification leaves the decision as
- to which to use up to the individual application, but all
- applications MUST be able to cope with receiving both formats.
-
- o Conferences using an IP multicast connection address must also have
- a time to live (TTL) value present in addition to the multicast
- address. The TTL and the address together define the scope with
- which multicast packets sent in this conference will be sent. TTL
- values must be in the range 0-255.
-
- The TTL for the session is appended to the address using a slash as
- a separator. An example is:
-
- c=IN IP4 224.2.1.1/127
-
- Hierarchical or layered encoding schemes are data streams where the
- encoding from a single media source is split into a number of
- layers. The receiver can choose the desired quality (and hence
- bandwidth) by only subscribing to a subset of these layers. Such
- layered encodings are normally transmitted in multiple multicast
- groups to allow multicast pruning. This technique keeps unwanted
- traffic from sites only requiring certain levels of the hierarchy.
- For applications requiring multiple multicast groups, we allow the
- following notation to be used for the connection address:
-
- <base multicast address>/<ttl>/<number of addresses>
-
- If the number of addresses is not given it is assumed to be one.
- Multicast addresses so assigned are contiguously allocated above
- the base address, so that, for example:
-
- c=IN IP4 224.2.1.1/127/3
-
- would state that addresses 224.2.1.1, 224.2.1.2 and 224.2.1.3 are
- to be used at a ttl of 127. This is semantically identical to
- including multiple "c=" lines in a media description:
-
- c=IN IP4 224.2.1.1/127
- c=IN IP4 224.2.1.2/127
- c=IN IP4 224.2.1.3/127
-
-
-
-
-
-Handley & Jacobson Standards Track [Page 13]
-
-RFC 2327 SDP April 1998
-
-
- Multiple addresses or "c=" lines can only be specified on a per-
- media basis, and not for a session-level "c=" field.
-
- It is illegal for the slash notation described above to be used for
- IP unicast addresses.
-
- Bandwidth
-
- b=<modifier>:<bandwidth-value>
-
- o This specifies the proposed bandwidth to be used by the session or
- media, and is optional.
-
- o <bandwidth-value> is in kilobits per second
-
- o <modifier> is a single alphanumeric word giving the meaning of the
- bandwidth figure.
-
- o Two modifiers are initially defined:
-
- CT Conference Total: An implicit maximum bandwidth is associated with
- each TTL on the Mbone or within a particular multicast
- administrative scope region (the Mbone bandwidth vs. TTL limits are
- given in the MBone FAQ). If the bandwidth of a session or media in
- a session is different from the bandwidth implicit from the scope,
- a `b=CT:...' line should be supplied for the session giving the
- proposed upper limit to the bandwidth used. The primary purpose of
- this is to give an approximate idea as to whether two or more
- conferences can co-exist simultaneously.
-
- AS Application-Specific Maximum: The bandwidth is interpreted to be
- application-specific, i.e., will be the application's concept of
- maximum bandwidth. Normally this will coincide with what is set on
- the application's "maximum bandwidth" control if applicable.
-
- Note that CT gives a total bandwidth figure for all the media at
- all sites. AS gives a bandwidth figure for a single media at a
- single site, although there may be many sites sending
- simultaneously.
-
- o Extension Mechanism: Tool writers can define experimental bandwidth
- modifiers by prefixing their modifier with "X-". For example:
-
- b=X-YZ:128
-
- SDP parsers should ignore bandwidth fields with unknown modifiers.
- Modifiers should be alpha-numeric and, although no length limit is
- given, they are recommended to be short.
-
-
-
-Handley & Jacobson Standards Track [Page 14]
-
-RFC 2327 SDP April 1998
-
-
- Times, Repeat Times and Time Zones
-
- t=<start time> <stop time>
-
- o "t=" fields specify the start and stop times for a conference
- session. Multiple "t=" fields may be used if a session is active
- at multiple irregularly spaced times; each additional "t=" field
- specifies an additional period of time for which the session will
- be active. If the session is active at regular times, an "r="
- field (see below) should be used in addition to and following a
- "t=" field - in which case the "t=" field specifies the start and
- stop times of the repeat sequence.
-
- o The first and second sub-fields give the start and stop times for
- the conference respectively. These values are the decimal
- representation of Network Time Protocol (NTP) time values in
- seconds [1]. To convert these values to UNIX time, subtract
- decimal 2208988800.
-
- o If the stop-time is set to zero, then the session is not bounded,
- though it will not become active until after the start-time. If
- the start-time is also zero, the session is regarded as permanent.
-
- User interfaces should strongly discourage the creation of
- unbounded and permanent sessions as they give no information about
- when the session is actually going to terminate, and so make
- scheduling difficult.
-
- The general assumption may be made, when displaying unbounded
- sessions that have not timed out to the user, that an unbounded
- session will only be active until half an hour from the current
- time or the session start time, whichever is the later. If
- behaviour other than this is required, an end-time should be given
- and modified as appropriate when new information becomes available
- about when the session should really end.
-
- Permanent sessions may be shown to the user as never being active
- unless there are associated repeat times which state precisely when
- the session will be active. In general, permanent sessions should
- not be created for any session expected to have a duration of less
- than 2 months, and should be discouraged for sessions expected to
- have a duration of less than 6 months.
-
- r=<repeat interval> <active duration> <list of offsets from start-
- time>
-
- o "r=" fields specify repeat times for a session. For example, if
- a session is active at 10am on Monday and 11am on Tuesday for one
-
-
-
-Handley & Jacobson Standards Track [Page 15]
-
-RFC 2327 SDP April 1998
-
-
- hour each week for three months, then the <start time> in the
- corresponding "t=" field would be the NTP representation of 10am on
- the first Monday, the <repeat interval> would be 1 week, the
- <active duration> would be 1 hour, and the offsets would be zero
- and 25 hours. The corresponding "t=" field stop time would be the
- NTP representation of the end of the last session three months
- later. By default all fields are in seconds, so the "r=" and "t="
- fields might be:
-
- t=3034423619 3042462419
- r=604800 3600 0 90000
-
- To make announcements more compact, times may also be given in units
- of days, hours or minutes. The syntax for these is a number
- immediately followed by a single case-sensitive character.
- Fractional units are not allowed - a smaller unit should be used
- instead. The following unit specification characters are allowed:
-
- d - days (86400 seconds)
- h - minutes (3600 seconds)
- m - minutes (60 seconds)
- s - seconds (allowed for completeness but not recommended)
-
- Thus, the above announcement could also have been written:
-
- r=7d 1h 0 25h
-
- Monthly and yearly repeats cannot currently be directly specified
- with a single SDP repeat time - instead separate "t" fields should
- be used to explicitly list the session times.
-
- z=<adjustment time> <offset> <adjustment time> <offset> ....
-
- o To schedule a repeated session which spans a change from daylight-
- saving time to standard time or vice-versa, it is necessary to
- specify offsets from the base repeat times. This is required
- because different time zones change time at different times of day,
- different countries change to or from daylight time on different
- dates, and some countries do not have daylight saving time at all.
-
- Thus in order to schedule a session that is at the same time winter
- and summer, it must be possible to specify unambiguously by whose
- time zone a session is scheduled. To simplify this task for
- receivers, we allow the sender to specify the NTP time that a time
- zone adjustment happens and the offset from the time when the
- session was first scheduled. The "z" field allows the sender to
- specify a list of these adjustment times and offsets from the base
- time.
-
-
-
-Handley & Jacobson Standards Track [Page 16]
-
-RFC 2327 SDP April 1998
-
-
- An example might be:
-
- z=2882844526 -1h 2898848070 0
-
- This specifies that at time 2882844526 the time base by which the
- session's repeat times are calculated is shifted back by 1 hour,
- and that at time 2898848070 the session's original time base is
- restored. Adjustments are always relative to the specified start
- time - they are not cumulative.
-
- o If a session is likely to last several years, it is expected
- that
- the session announcement will be modified periodically rather than
- transmit several years worth of adjustments in one announcement.
-
- Encryption Keys
-
- k=<method>
- k=<method>:<encryption key>
-
- o The session description protocol may be used to convey encryption
- keys. A key field is permitted before the first media entry (in
- which case it applies to all media in the session), or for each
- media entry as required.
-
- o The format of keys and their usage is outside the scope of this
- document, but see [3].
-
- o The method indicates the mechanism to be used to obtain a usable
- key by external means, or from the encoded encryption key given.
-
- The following methods are defined:
-
- k=clear:<encryption key>
- The encryption key (as described in [3] for RTP media streams
- under the AV profile) is included untransformed in this key
- field.
-
- k=base64:<encoded encryption key>
- The encryption key (as described in [3] for RTP media streams
- under the AV profile) is included in this key field but has been
- base64 encoded because it includes characters that are
- prohibited in SDP.
-
- k=uri:<URI to obtain key>
- A Universal Resource Identifier as used by WWW clients is
- included in this key field. The URI refers to the data
- containing the key, and may require additional authentication
-
-
-
-Handley & Jacobson Standards Track [Page 17]
-
-RFC 2327 SDP April 1998
-
-
- before the key can be returned. When a request is made to the
- given URI, the MIME content-type of the reply specifies the
- encoding for the key in the reply. The key should not be
- obtained until the user wishes to join the session to reduce
- synchronisation of requests to the WWW server(s).
-
- k=prompt
- No key is included in this SDP description, but the session or
- media stream referred to by this key field is encrypted. The
- user should be prompted for the key when attempting to join the
- session, and this user-supplied key should then be used to
- decrypt the media streams.
-
- Attributes
-
- a=<attribute>
- a=<attribute>:<value>
-
- Attributes are the primary means for extending SDP. Attributes may
- be defined to be used as "session-level" attributes, "media-level"
- attributes, or both.
-
- A media description may have any number of attributes ("a=" fields)
- which are media specific. These are referred to as "media-level"
- attributes and add information about the media stream. Attribute
- fields can also be added before the first media field; these
- "session-level" attributes convey additional information that applies
- to the conference as a whole rather than to individual media; an
- example might be the conference's floor control policy.
-
- Attribute fields may be of two forms:
-
- o property attributes. A property attribute is simply of the form
- "a=<flag>". These are binary attributes, and the presence of the
- attribute conveys that the attribute is a property of the session.
- An example might be "a=recvonly".
-
- o value attributes. A value attribute is of the form
- "a=<attribute>:<value>". An example might be that a whiteboard
- could have the value attribute "a=orient:landscape"
-
- Attribute interpretation depends on the media tool being invoked.
- Thus receivers of session descriptions should be configurable in
- their interpretation of announcements in general and of attributes in
- particular.
-
- Attribute names must be in the US-ASCII subset of ISO-10646/UTF-8.
-
-
-
-
-Handley & Jacobson Standards Track [Page 18]
-
-RFC 2327 SDP April 1998
-
-
- Attribute values are byte strings, and MAY use any byte value except
- 0x00 (Nul), 0x0A (LF), and 0x0D (CR). By default, attribute values
- are to be interpreted as in ISO-10646 character set with UTF-8
- encoding. Unlike other text fields, attribute values are NOT
- normally affected by the `charset' attribute as this would make
- comparisons against known values problematic. However, when an
- attribute is defined, it can be defined to be charset-dependent, in
- which case it's value should be interpreted in the session charset
- rather than in ISO-10646.
-
- Attributes that will be commonly used can be registered with IANA
- (see Appendix B). Unregistered attributes should begin with "X-" to
- prevent inadvertent collision with registered attributes. In either
- case, if an attribute is received that is not understood, it should
- simply be ignored by the receiver.
-
- Media Announcements
-
- m=<media> <port> <transport> <fmt list>
-
- A session description may contain a number of media descriptions.
- Each media description starts with an "m=" field, and is terminated
- by either the next "m=" field or by the end of the session
- description. A media field also has several sub-fields:
-
- o The first sub-field is the media type. Currently defined media are
- "audio", "video", "application", "data" and "control", though this
- list may be extended as new communication modalities emerge (e.g.,
- telepresense). The difference between "application" and "data" is
- that the former is a media flow such as whiteboard information, and
- the latter is bulk-data transfer such as multicasting of program
- executables which will not typically be displayed to the user.
- "control" is used to specify an additional conference control
- channel for the session.
-
- o The second sub-field is the transport port to which the media
- stream will be sent. The meaning of the transport port depends on
- the network being used as specified in the relevant "c" field and
- on the transport protocol defined in the third sub-field. Other
- ports used by the media application (such as the RTCP port, see
- [2]) should be derived algorithmically from the base media port.
-
- Note: For transports based on UDP, the value should be in the range
- 1024 to 65535 inclusive. For RTP compliance it should be an even
- number.
-
-
-
-
-
-
-Handley & Jacobson Standards Track [Page 19]
-
-RFC 2327 SDP April 1998
-
-
- For applications where hierarchically encoded streams are being
- sent to a unicast address, it may be necessary to specify multiple
- transport ports. This is done using a similar notation to that
- used for IP multicast addresses in the "c=" field:
-
- m=<media> <port>/<number of ports> <transport> <fmt list>
-
- In such a case, the ports used depend on the transport protocol.
- For RTP, only the even ports are used for data and the
- corresponding one-higher odd port is used for RTCP. For example:
-
- m=video 49170/2 RTP/AVP 31
-
- would specify that ports 49170 and 49171 form one RTP/RTCP pair and
- 49172 and 49173 form the second RTP/RTCP pair. RTP/AVP is the
- transport protocol and 31 is the format (see below).
-
- It is illegal for both multiple addresses to be specified in the
- "c=" field and for multiple ports to be specified in the "m=" field
- in the same session description.
-
- o The third sub-field is the transport protocol. The transport
- protocol values are dependent on the address-type field in the "c="
- fields. Thus a "c=" field of IP4 defines that the transport
- protocol runs over IP4. For IP4, it is normally expected that most
- media traffic will be carried as RTP over UDP. The following
- transport protocols are preliminarily defined, but may be extended
- through registration of new protocols with IANA:
-
- - RTP/AVP - the IETF's Realtime Transport Protocol using the
- Audio/Video profile carried over UDP.
-
- - udp - User Datagram Protocol
-
- If an application uses a single combined proprietary media format
- and transport protocol over UDP, then simply specifying the
- transport protocol as udp and using the format field to distinguish
- the combined protocol is recommended. If a transport protocol is
- used over UDP to carry several distinct media types that need to be
- distinguished by a session directory, then specifying the transport
- protocol and media format separately is necessary. RTP is an
- example of a transport-protocol that carries multiple payload
- formats that must be distinguished by the session directory for it
- to know how to start appropriate tools, relays, mixers or
- recorders.
-
-
-
-
-
-
-Handley & Jacobson Standards Track [Page 20]
-
-RFC 2327 SDP April 1998
-
-
- The main reason to specify the transport-protocol in addition to
- the media format is that the same standard media formats may be
- carried over different transport protocols even when the network
- protocol is the same - a historical example is vat PCM audio and
- RTP PCM audio. In addition, relays and monitoring tools that are
- transport-protocol-specific but format-independent are possible.
-
- For RTP media streams operating under the RTP Audio/Video Profile
- [3], the protocol field is "RTP/AVP". Should other RTP profiles be
- defined in the future, their profiles will be specified in the same
- way. For example, the protocol field "RTP/XYZ" would specify RTP
- operating under a profile whose short name is "XYZ".
-
- o The fourth and subsequent sub-fields are media formats. For audio
- and video, these will normally be a media payload type as defined
- in the RTP Audio/Video Profile.
-
- When a list of payload formats is given, this implies that all of
- these formats may be used in the session, but the first of these
- formats is the default format for the session.
-
- For media whose transport protocol is not RTP or UDP the format
- field is protocol specific. Such formats should be defined in an
- additional specification document.
-
- For media whose transport protocol is RTP, SDP can be used to
- provide a dynamic binding of media encoding to RTP payload type.
- The encoding names in the RTP AV Profile do not specify unique
- audio encodings (in terms of clock rate and number of audio
- channels), and so they are not used directly in SDP format fields.
- Instead, the payload type number should be used to specify the
- format for static payload types and the payload type number along
- with additional encoding information should be used for dynamically
- allocated payload types.
-
- An example of a static payload type is u-law PCM coded single
- channel audio sampled at 8KHz. This is completely defined in the
- RTP Audio/Video profile as payload type 0, so the media field for
- such a stream sent to UDP port 49232 is:
-
- m=video 49232 RTP/AVP 0
-
- An example of a dynamic payload type is 16 bit linear encoded
- stereo audio sampled at 16KHz. If we wish to use dynamic RTP/AVP
- payload type 98 for such a stream, additional information is
- required to decode it:
-
- m=video 49232 RTP/AVP 98
-
-
-
-Handley & Jacobson Standards Track [Page 21]
-
-RFC 2327 SDP April 1998
-
-
- a=rtpmap:98 L16/16000/2
-
- The general form of an rtpmap attribute is:
-
- a=rtpmap:<payload type> <encoding name>/<clock rate>[/<encoding
- parameters>]
-
- For audio streams, <encoding parameters> may specify the number of
- audio channels. This parameter may be omitted if the number of
- channels is one provided no additional parameters are needed. For
- video streams, no encoding parameters are currently specified.
-
- Additional parameters may be defined in the future, but
- codecspecific parameters should not be added. Parameters added to
- an rtpmap attribute should only be those required for a session
- directory to make the choice of appropriate media too to
- participate in a session. Codec-specific parameters should be
- added in other attributes.
-
- Up to one rtpmap attribute can be defined for each media format
- specified. Thus we might have:
-
- m=audio 49230 RTP/AVP 96 97 98
- a=rtpmap:96 L8/8000
- a=rtpmap:97 L16/8000
- a=rtpmap:98 L16/11025/2
-
- RTP profiles that specify the use of dynamic payload types must
- define the set of valid encoding names and/or a means to register
- encoding names if that profile is to be used with SDP.
-
- Experimental encoding formats can also be specified using rtpmap.
- RTP formats that are not registered as standard format names must
- be preceded by "X-". Thus a new experimental redundant audio
- stream called GSMLPC using dynamic payload type 99 could be
- specified as:
-
- m=video 49232 RTP/AVP 99
- a=rtpmap:99 X-GSMLPC/8000
-
- Such an experimental encoding requires that any site wishing to
- receive the media stream has relevant configured state in its
- session directory to know which tools are appropriate.
-
- Note that RTP audio formats typically do not include information
- about the number of samples per packet. If a non-default (as
- defined in the RTP Audio/Video Profile) packetisation is required,
- the "ptime" attribute is used as given below.
-
-
-
-Handley & Jacobson Standards Track [Page 22]
-
-RFC 2327 SDP April 1998
-
-
- For more details on RTP audio and video formats, see [3].
-
- o Formats for non-RTP media should be registered as MIME content
- types as described in Appendix B. For example, the LBL whiteboard
- application might be registered as MIME content-type application/wb
- with encoding considerations specifying that it operates over UDP,
- with no appropriate file format. In SDP this would then be
- expressed using a combination of the "media" field and the "fmt"
- field, as follows:
-
- m=application 32416 udp wb
-
- Suggested Attributes
-
- The following attributes are suggested. Since application writers
- may add new attributes as they are required, this list is not
- exhaustive.
-
- a=cat:<category>
- This attribute gives the dot-separated hierarchical category of
- the session. This is to enable a receiver to filter unwanted
- sessions by category. It would probably have been a compulsory
- separate field, except for its experimental nature at this time.
- It is a session-level attribute, and is not dependent on charset.
-
- a=keywds:<keywords>
- Like the cat attribute, this is to assist identifying wanted
- sessions at the receiver. This allows a receiver to select
- interesting session based on keywords describing the purpose of
- the session. It is a session-level attribute. It is a charset
- dependent attribute, meaning that its value should be interpreted
- in the charset specified for the session description if one is
- specified, or by default in ISO 10646/UTF-8.
-
- a=tool:<name and version of tool>
- This gives the name and version number of the tool used to create
- the session description. It is a session-level attribute, and is
- not dependent on charset.
-
- a=ptime:<packet time>
- This gives the length of time in milliseconds represented by the
- media in a packet. This is probably only meaningful for audio
- data. It should not be necessary to know ptime to decode RTP or
- vat audio, and it is intended as a recommendation for the
- encoding/packetisation of audio. It is a media attribute, and is
- not dependent on charset.
-
-
-
-
-
-Handley & Jacobson Standards Track [Page 23]
-
-RFC 2327 SDP April 1998
-
-
- a=recvonly
- This specifies that the tools should be started in receive-only
- mode where applicable. It can be either a session or media
- attribute, and is not dependent on charset.
-
- a=sendrecv
- This specifies that the tools should be started in send and
- receive mode. This is necessary for interactive conferences with
- tools such as wb which defaults to receive only mode. It can be
- either a session or media attribute, and is not dependent on
- charset.
-
- a=sendonly
- This specifies that the tools should be started in send-only
- mode. An example may be where a different unicast address is to
- be used for a traffic destination than for a traffic source. In
- such a case, two media descriptions may be use, one sendonly and
- one recvonly. It can be either a session or media attribute, but
- would normally only be used as a media attribute, and is not
- dependent on charset.
-
- a=orient:<whiteboard orientation>
- Normally this is only used in a whiteboard media specification.
- It specifies the orientation of a the whiteboard on the screen.
- It is a media attribute. Permitted values are `portrait',
- `landscape' and `seascape' (upside down landscape). It is not
- dependent on charset
-
- a=type:<conference type>
- This specifies the type of the conference. Suggested values are
- `broadcast', `meeting', `moderated', `test' and `H332'.
- `recvonly' should be the default for `type:broadcast' sessions,
- `type:meeting' should imply `sendrecv' and `type:moderated'
- should indicate the use of a floor control tool and that the
- media tools are started so as to "mute" new sites joining the
- conference.
-
- Specifying the attribute type:H332 indicates that this loosely
- coupled session is part of a H.332 session as defined in the ITU
- H.332 specification [10]. Media tools should be started
- `recvonly'.
-
- Specifying the attribute type:test is suggested as a hint that,
- unless explicitly requested otherwise, receivers can safely avoid
- displaying this session description to users.
-
- The type attribute is a session-level attribute, and is not
- dependent on charset.
-
-
-
-Handley & Jacobson Standards Track [Page 24]
-
-RFC 2327 SDP April 1998
-
-
- a=charset:<character set>
- This specifies the character set to be used to display the
- session name and information data. By default, the ISO-10646
- character set in UTF-8 encoding is used. If a more compact
- representation is required, other character sets may be used such
- as ISO-8859-1 for Northern European languages. In particular,
- the ISO 8859-1 is specified with the following SDP attribute:
-
- a=charset:ISO-8859-1
-
- This is a session-level attribute; if this attribute is present,
- it must be before the first media field. The charset specified
- MUST be one of those registered with IANA, such as ISO-8859-1.
- The character set identifier is a US-ASCII string and MUST be
- compared against the IANA identifiers using a case-insensitive
- comparison. If the identifier is not recognised or not
- supported, all strings that are affected by it SHOULD be regarded
- as byte strings.
-
- Note that a character set specified MUST still prohibit the use
- of bytes 0x00 (Nul), 0x0A (LF) and 0x0d (CR). Character sets
- requiring the use of these characters MUST define a quoting
- mechanism that prevents these bytes appearing within text fields.
-
- a=sdplang:<language tag>
- This can be a session level attribute or a media level attribute.
- As a session level attribute, it specifies the language for the
- session description. As a media level attribute, it specifies
- the language for any media-level SDP information field associated
- with that media. Multiple sdplang attributes can be provided
- either at session or media level if multiple languages in the
- session description or media use multiple languages, in which
- case the order of the attributes indicates the order of
- importance of the various languages in the session or media from
- most important to least important.
-
- In general, sending session descriptions consisting of multiple
- languages should be discouraged. Instead, multiple descriptions
- should be sent describing the session, one in each language.
- However this is not possible with all transport mechanisms, and
- so multiple sdplang attributes are allowed although not
- recommended.
-
- The sdplang attribute value must be a single RFC 1766 language
- tag in US-ASCII. It is not dependent on the charset attribute.
- An sdplang attribute SHOULD be specified when a session is of
-
-
-
-
-
-Handley & Jacobson Standards Track [Page 25]
-
-RFC 2327 SDP April 1998
-
-
- sufficient scope to cross geographic boundaries where the
- language of recipients cannot be assumed, or where the session is
- in a different language from the locally assumed norm.
-
- a=lang:<language tag>
- This can be a session level attribute or a media level attribute.
- As a session level attribute, it specifies the default language
- for the session being described. As a media level attribute, it
- specifies the language for that media, overriding any session-
- level language specified. Multiple lang attributes can be
- provided either at session or media level if multiple languages
- if the session description or media use multiple languages, in
- which case the order of the attributes indicates the order of
- importance of the various languages in the session or media from
- most important to least important.
-
- The lang attribute value must be a single RFC 1766 language tag
- in US-ASCII. It is not dependent on the charset attribute. A
- lang attribute SHOULD be specified when a session is of
- sufficient scope to cross geographic boundaries where the
- language of recipients cannot be assumed, or where the session is
- in a different language from the locally assumed norm.
-
- a=framerate:<frame rate>
- This gives the maximum video frame rate in frames/sec. It is
- intended as a recommendation for the encoding of video data.
- Decimal representations of fractional values using the notation
- "<integer>.<fraction>" are allowed. It is a media attribute, is
- only defined for video media, and is not dependent on charset.
-
- a=quality:<quality>
- This gives a suggestion for the quality of the encoding as an
- integer value.
-
- The intention of the quality attribute for video is to specify a
- non-default trade-off between frame-rate and still-image quality.
- For video, the value in the range 0 to 10, with the following
- suggested meaning:
-
- 10 - the best still-image quality the compression scheme can
- give.
-
- 5 - the default behaviour given no quality suggestion.
-
- 0 - the worst still-image quality the codec designer thinks is
- still usable.
-
- It is a media attribute, and is not dependent on charset.
-
-
-
-Handley & Jacobson Standards Track [Page 26]
-
-RFC 2327 SDP April 1998
-
-
- a=fmtp:<format> <format specific parameters>
- This attribute allows parameters that are specific to a
- particular format to be conveyed in a way that SDP doesn't have
- to understand them. The format must be one of the formats
- specified for the media. Format-specific parameters may be any
- set of parameters required to be conveyed by SDP and given
- unchanged to the media tool that will use this format.
-
- It is a media attribute, and is not dependent on charset.
-
-6.1. Communicating Conference Control Policy
-
- There is some debate over the way conference control policy should be
- communicated. In general, the authors believe that an implicit
- declarative style of specifying conference control is desirable where
- possible.
-
- A simple declarative style uses a single conference attribute field
- before the first media field, possibly supplemented by properties
- such as `recvonly' for some of the media tools. This conference
- attribute conveys the conference control policy. An example might be:
-
- a=type:moderated
-
- In some cases, however, it is possible that this may be insufficient
- to communicate the details of an unusual conference control policy.
- If this is the case, then a conference attribute specifying external
- control might be set, and then one or more "media" fields might be
- used to specify the conference control tools and configuration data
- for those tools. An example is an ITU H.332 session:
-
- c=IN IP4 224.5.6.7
- a=type:H332
- m=audio 49230 RTP/AVP 0
- m=video 49232 RTP/AVP 31
- m=application 12349 udp wb
- m=control 49234 H323 mc
- c=IN IP4 134.134.157.81
-
- In this example, a general conference attribute (type:H332) is
- specified stating that conference control will be provided by an
- external H.332 tool, and a contact addresses for the H.323 session
- multipoint controller is given.
-
- In this document, only the declarative style of conference control
- declaration is specified. Other forms of conference control should
- specify an appropriate type attribute, and should define the
- implications this has for control media.
-
-
-
-Handley & Jacobson Standards Track [Page 27]
-
-RFC 2327 SDP April 1998
-
-
-7. Security Considerations
-
- SDP is a session description format that describes multimedia
- sessions. A session description should not be trusted unless it has
- been obtained by an authenticated transport protocol from a trusted
- source. Many different transport protocols may be used to distribute
- session description, and the nature of the authentication will differ
- from transport to transport.
-
- One transport that will frequently be used to distribute session
- descriptions is the Session Announcement Protocol (SAP). SAP
- provides both encryption and authentication mechanisms but due to the
- nature of session announcements it is likely that there are many
- occasions where the originator of a session announcement cannot be
- authenticated because they are previously unknown to the receiver of
- the announcement and because no common public key infrastructure is
- available.
-
- On receiving a session description over an unauthenticated transport
- mechanism or from an untrusted party, software parsing the session
- should take a few precautions. Session description contain
- information required to start software on the receivers system.
- Software that parses a session description MUST not be able to start
- other software except that which is specifically configured as
- appropriate software to participate in multimedia sessions. It is
- normally considered INAPPROPRIATE for software parsing a session
- description to start, on a user's system, software that is
- appropriate to participate in multimedia sessions, without the user
- first being informed that such software will be started and giving
- their consent. Thus a session description arriving by session
- announcement, email, session invitation, or WWW page SHOULD not
- deliver the user into an {it interactive} multimedia session without
- the user being aware that this will happen. As it is not always
- simple to tell whether a session is interactive or not, applications
- that are unsure should assume sessions are interactive.
-
- In this specification, there are no attributes which would allow the
- recipient of a session description to be informed to start multimedia
- tools in a mode where they default to transmitting. Under some
- circumstances it might be appropriate to define such attributes. If
- this is done an application parsing a session description containing
- such attributes SHOULD either ignore them, or inform the user that
- joining this session will result in the automatic transmission of
- multimedia data. The default behaviour for an unknown attribute is
- to ignore it.
-
-
-
-
-
-
-Handley & Jacobson Standards Track [Page 28]
-
-RFC 2327 SDP April 1998
-
-
- Session descriptions may be parsed at intermediate systems such as
- firewalls for the purposes of opening a hole in the firewall to allow
- the participation in multimedia sessions. It is considered
- INAPPROPRIATE for a firewall to open such holes for unicast data
- streams unless the session description comes in a request from inside
- the firewall.
-
- For multicast sessions, it is likely that local administrators will
- apply their own policies, but the exclusive use of "local" or "site-
- local" administrative scope within the firewall and the refusal of
- the firewall to open a hole for such scopes will provide separation
- of global multicast sessions from local ones.
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-Handley & Jacobson Standards Track [Page 29]
-
-RFC 2327 SDP April 1998
-
-
-Appendix A: SDP Grammar
-
- This appendix provides an Augmented BNF grammar for SDP. ABNF is
- defined in RFC 2234.
-
-
- announcement = proto-version
- origin-field
- session-name-field
- information-field
- uri-field
- email-fields
- phone-fields
- connection-field
- bandwidth-fields
- time-fields
- key-field
- attribute-fields
- media-descriptions
-
- proto-version = "v=" 1*DIGIT CRLF
- ;this memo describes version 0
-
- origin-field = "o=" username space
- sess-id space sess-version space
- nettype space addrtype space
- addr CRLF
-
- session-name-field = "s=" text CRLF
-
- information-field = ["i=" text CRLF]
-
- uri-field = ["u=" uri CRLF]
-
- email-fields = *("e=" email-address CRLF)
-
- phone-fields = *("p=" phone-number CRLF)
-
-
- connection-field = ["c=" nettype space addrtype space
- connection-address CRLF]
- ;a connection field must be present
- ;in every media description or at the
- ;session-level
-
-
- bandwidth-fields = *("b=" bwtype ":" bandwidth CRLF)
-
-
-
-
-Handley & Jacobson Standards Track [Page 30]
-
-RFC 2327 SDP April 1998
-
-
- time-fields = 1*( "t=" start-time space stop-time
- *(CRLF repeat-fields) CRLF)
- [zone-adjustments CRLF]
-
-
- repeat-fields = "r=" repeat-interval space typed-time
- 1*(space typed-time)
-
-
- zone-adjustments = time space ["-"] typed-time
- *(space time space ["-"] typed-time)
-
-
- key-field = ["k=" key-type CRLF]
-
-
- key-type = "prompt" |
- "clear:" key-data |
- "base64:" key-data |
- "uri:" uri
-
-
- key-data = email-safe | "~" | "
-
-
- attribute-fields = *("a=" attribute CRLF)
-
-
- media-descriptions = *( media-field
- information-field
- *(connection-field)
- bandwidth-fields
- key-field
- attribute-fields )
-
-
- media-field = "m=" media space port ["/" integer]
- space proto 1*(space fmt) CRLF
-
-
- media = 1*(alpha-numeric)
- ;typically "audio", "video", "application"
- ;or "data"
-
- fmt = 1*(alpha-numeric)
- ;typically an RTP payload type for audio
- ;and video media
-
-
-
-
-Handley & Jacobson Standards Track [Page 31]
-
-RFC 2327 SDP April 1998
-
-
- proto = 1*(alpha-numeric)
- ;typically "RTP/AVP" or "udp" for IP4
-
-
- port = 1*(DIGIT)
- ;should in the range "1024" to "65535" inclusive
- ;for UDP based media
-
-
- attribute = (att-field ":" att-value) | att-field
-
-
- att-field = 1*(alpha-numeric)
-
-
- att-value = byte-string
-
-
- sess-id = 1*(DIGIT)
- ;should be unique for this originating username/host
-
-
- sess-version = 1*(DIGIT)
- ;0 is a new session
-
-
- connection-address = multicast-address
- | addr
-
-
- multicast-address = 3*(decimal-uchar ".") decimal-uchar "/" ttl
- [ "/" integer ]
- ;multicast addresses may be in the range
- ;224.0.0.0 to 239.255.255.255
-
- ttl = decimal-uchar
-
- start-time = time | "0"
-
- stop-time = time | "0"
-
- time = POS-DIGIT 9*(DIGIT)
- ;sufficient for 2 more centuries
-
-
- repeat-interval = typed-time
-
-
-
-
-
-Handley & Jacobson Standards Track [Page 32]
-
-RFC 2327 SDP April 1998
-
-
- typed-time = 1*(DIGIT) [fixed-len-time-unit]
-
-
- fixed-len-time-unit = "d" | "h" | "m" | "s"
-
-
- bwtype = 1*(alpha-numeric)
-
- bandwidth = 1*(DIGIT)
-
-
- username = safe
- ;pretty wide definition, but doesn't include space
-
-
- email-address = email | email "(" email-safe ")" |
- email-safe "<" email ">"
-
-
- email = ;defined in RFC822
-
-
- uri= ;defined in RFC1630
-
-
- phone-number = phone | phone "(" email-safe ")" |
- email-safe "<" phone ">"
-
-
- phone = "+" POS-DIGIT 1*(space | "-" | DIGIT)
- ;there must be a space or hyphen between the
- ;international code and the rest of the number.
-
-
- nettype = "IN"
- ;list to be extended
-
-
- addrtype = "IP4" | "IP6"
- ;list to be extended
-
-
- addr = FQDN | unicast-address
-
-
- FQDN = 4*(alpha-numeric|"-"|".")
- ;fully qualified domain name as specified in RFC1035
-
-
-
-
-Handley & Jacobson Standards Track [Page 33]
-
-RFC 2327 SDP April 1998
-
-
- unicast-address = IP4-address | IP6-address
-
-
- IP4-address = b1 "." decimal-uchar "." decimal-uchar "." b4
- b1 = decimal-uchar
- ;less than "224"; not "0" or "127"
- b4 = decimal-uchar
- ;not "0"
-
- IP6-address = ;to be defined
-
-
- text = byte-string
- ;default is to interpret this as IS0-10646 UTF8
- ;ISO 8859-1 requires a "a=charset:ISO-8859-1"
- ;session-level attribute to be used
-
-
- byte-string = 1*(0x01..0x09|0x0b|0x0c|0x0e..0xff)
- ;any byte except NUL, CR or LF
-
-
- decimal-uchar = DIGIT
- | POS-DIGIT DIGIT
- | ("1" 2*(DIGIT))
- | ("2" ("0"|"1"|"2"|"3"|"4") DIGIT)
- | ("2" "5" ("0"|"1"|"2"|"3"|"4"|"5"))
-
-
- integer = POS-DIGIT *(DIGIT)
-
-
- alpha-numeric = ALPHA | DIGIT
-
-
- DIGIT = "0" | POS-DIGIT
-
-
- POS-DIGIT = "1"|"2"|"3"|"4"|"5"|"6"|"7"|"8"|"9"
-
-
- ALPHA = "a"|"b"|"c"|"d"|"e"|"f"|"g"|"h"|"i"|"j"|"k"|
- "l"|"m"|"n"|"o "|"p"|"q"|"r"|"s"|"t"|"u"|"v"|
- "w"|"x"|"y"|"z"|"A"|"B"|"C "|"D"|"E"|"F"|"G"|
- "H"|"I"|"J"|"K"|"L"|"M"|"N"|"O"|"P"|" Q"|"R"|
- "S"|"T"|"U"|"V"|"W"|"X"|"Y"|"Z"
-
-
-
-
-
-Handley & Jacobson Standards Track [Page 34]
-
-RFC 2327 SDP April 1998
-
-
- email-safe = safe | space | tab
-
-
- safe = alpha-numeric |
- "'" | "'" | "-" | "." | "/" | ":" | "?" | """ |
- "#" | "$" | "&" | "*" | ";" | "=" | "@" | "[" |
- "]" | "^" | "_" | "`" | "{" | "|" | "}" | "+" |
- "~" | "
-
-
- space = %d32
- tab = %d9
- CRLF = %d13.10
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-Handley & Jacobson Standards Track [Page 35]
-
-RFC 2327 SDP April 1998
-
-
-Appendix B: Guidelines for registering SDP names with IANA
-
- There are seven field names that may be registered with IANA. Using
- the terminology in the SDP specification BNF, they are "media",
- "proto", "fmt", "att-field", "bwtype", "nettype" and "addrtype".
-
- "media" (eg, audio, video, application, data).
-
- Packetized media types, such as those used by RTP, share the
- namespace used by media types registry [RFC 2048] (i.e. "MIME
- types"). The list of valid media names is the set of top-level
- MIME content types. The set of media is intended to be small and
- not to be extended except under rare circumstances. (The MIME
- subtype corresponds to the "fmt" parameter below).
-
- "proto"
-
- In general this should be an IETF standards-track transport
- protocol identifier such as RTP/AVP (rfc 1889 under the rfc 1890
- profile).
-
- However, people will want to invent their own proprietary
- transport protocols. Some of these should be registered as a
- "fmt" using "udp" as the protocol and some of which probably
- can't be.
-
- Where the protocol and the application are intimately linked,
- such as with the LBL whiteboard wb which used a proprietary and
- special purpose protocol over UDP, the protocol name should be
- "udp" and the format name that should be registered is "wb". The
- rules for formats (see below) apply to such registrations.
-
- Where the proprietary transport protocol really carries many
- different data formats, it is possible to register a new protocol
- name with IANA. In such a case, an RFC MUST be produced
- describing the protocol and referenced in the registration. Such
- an RFC MAY be informational, although it is preferable if it is
- standards-track.
-
- "fmt"
-
- The format namespace is dependent on the context of the "proto"
- field, so a format cannot be registered without specifying one or
- more transport protocols that it applies to.
-
- Formats cover all the possible encodings that might want to be
- transported in a multimedia session.
-
-
-
-
-Handley & Jacobson Standards Track [Page 36]
-
-RFC 2327 SDP April 1998
-
-
- For RTP formats that have been assigned static payload types, the
- payload type number is used. For RTP formats using a dynamic
- payload type number, the dynamic payload type number is given as
- the format and an additional "rtpmap" attribute specifies the
- format and parameters.
-
- For non-RTP formats, any unregistered format name may be
- registered through the MIME-type registration process [RFC 2048].
- The type given here is the MIME subtype only (the top-level MIME
- content type is specified by the media parameter). The MIME type
- registration SHOULD reference a standards-track RFC which
- describes the transport protocol for this media type. If there
- is an existing MIME type for this format, the MIME registration
- should be augmented to reference the transport specification for
- this media type. If there is not an existing MIME type for this
- format, and there exists no appropriate file format, this should
- be noted in the encoding considerations as "no appropriate file
- format".
-
- "att-field" (Attribute names)
-
- Attribute field names MAY be registered with IANA, although this
- is not compulsory, and unknown attributes are simply ignored.
-
- When an attribute is registered, it must be accompanied by a
- brief specification stating the following:
-
- o contact name, email address and telephone number
-
- o attribute-name (as it will appear in SDP)
-
- o long-form attribute name in English
-
- o type of attribute (session level, media level, or both)
-
- o whether the attribute value is subject to the charset
- attribute.
-
- o a one paragraph explanation of the purpose of the attribute.
-
- o a specification of appropriate attribute values for this
- attribute.
-
- IANA will not sanity check such attribute registrations except to
- ensure that they do not clash with existing registrations.
-
-
-
-
-
-
-Handley & Jacobson Standards Track [Page 37]
-
-RFC 2327 SDP April 1998
-
-
- Although the above is the minimum that IANA will accept, if the
- attribute is expected to see widespread use and interoperability
- is an issue, authors are encouraged to produce a standards-track
- RFC that specifies the attribute more precisely.
-
- Submitters of registrations should ensure that the specification
- is in the spirit of SDP attributes, most notably that the
- attribute is platform independent in the sense that it makes no
- implicit assumptions about operating systems and does not name
- specific pieces of software in a manner that might inhibit
- interoperability.
-
- "bwtype" (bandwidth specifiers)
-
- A proliferation of bandwidth specifiers is strongly discouraged.
-
- New bandwidth specifiers may be registered with IANA. The
- submission MUST reference a standards-track RFC specifying the
- semantics of the bandwidth specifier precisely, and indicating
- when it should be used, and why the existing registered bandwidth
- specifiers do not suffice.
-
- "nettype" (Network Type)
-
- New network types may be registered with IANA if SDP needs to be
- used in the context of non-internet environments. Whilst these
- are not normally the preserve of IANA, there may be circumstances
- when an Internet application needs to interoperate with a non-
- internet application, such as when gatewaying an internet
- telephony call into the PSTN. The number of network types should
- be small and should be rarely extended. A new network type
- cannot be registered without registering at least one address
- type to be used with that network type. A new network type
- registration MUST reference an RFC which gives details of the
- network type and address type and specifies how and when they
- would be used. Such an RFC MAY be Informational.
-
- "addrtype" (Address Type)
-
- New address types may be registered with IANA. An address type
- is only meaningful in the context of a network type, and any
- registration of an address type MUST specify a registered network
- type, or be submitted along with a network type registration. A
- new address type registration MUST reference an RFC giving
- details of the syntax of the address type. Such an RFC MAY be
- Informational. Address types are not expected to be registered
- frequently.
-
-
-
-
-Handley & Jacobson Standards Track [Page 38]
-
-RFC 2327 SDP April 1998
-
-
- Registration Procedure
-
- To register a name the above guidelines should be followed regarding
- the required level of documentation that is required. The
- registration itself should be sent to IANA. Attribute registrations
- should include the information given above. Other registrations
- should include the following additional information:
-
- o contact name, email address and telephone number
-
- o name being registered (as it will appear in SDP)
-
- o long-form name in English
-
- o type of name ("media", "proto", "fmt", "bwtype", "nettype", or
- "addrtype")
-
- o a one paragraph explanation of the purpose of the registered name.
-
- o a reference to the specification (eg RFC number) of the registered
- name.
-
- IANA may refer any registration to the IESG or to any appropriate
- IETF working group for review, and may request revisions to be made
- before a registration will be made.
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-Handley & Jacobson Standards Track [Page 39]
-
-RFC 2327 SDP April 1998
-
-
-Appendix C: Authors' Addresses
-
- Mark Handley
- Information Sciences Institute
- c/o MIT Laboratory for Computer Science
- 545 Technology Square
- Cambridge, MA 02139
- United States
- electronic mail: [email protected]
-
- Van Jacobson
- MS 46a-1121
- Lawrence Berkeley Laboratory
- Berkeley, CA 94720
- United States
- electronic mail: [email protected]
-
-Acknowledgments
-
- Many people in the IETF MMUSIC working group have made comments and
- suggestions contributing to this document. In particular, we would
- like to thank Eve Schooler, Steve Casner, Bill Fenner, Allison
- Mankin, Ross Finlayson, Peter Parnes, Joerg Ott, Carsten Bormann, Rob
- Lanphier and Steve Hanna.
-
-References
-
- [1] Mills, D., "Network Time Protocol (version 3) specification and
- implementation", RFC 1305, March 1992.
-
- [2] Schulzrinne, H., Casner, S., Frederick, R. and V. Jacobson, "RTP:
- A Transport Protocol for Real-Time Applications", RFC 1889, January
- 1996.
-
- [3] Schulzrinne, H., "RTP Profile for Audio and Video Conferences
- with Minimal Control", RFC 1890, January 1996
-
- [4] Handley, M., "SAP - Session Announcement Protocol", Work in
- Progress.
-
- [5] V. Jacobson, S. McCanne, "vat - X11-based audio teleconferencing
- tool" vat manual page, Lawrence Berkeley Laboratory, 1994.
-
- [6] The Unicode Consortium, "The Unicode Standard -- Version 2.0",
- Addison-Wesley, 1996.
-
-
-
-
-
-
-Handley & Jacobson Standards Track [Page 40]
-
-RFC 2327 SDP April 1998
-
-
- [7] ISO/IEC 10646-1:1993. International Standard -- Information
- technol- ogy -- Universal Multiple-Octet Coded Character Set (UCS) --
- Part 1: Architecture and Basic Multilingual Plane. Five amendments
- and a techn- ical corrigendum have been published up to now. UTF-8
- is described in Annex R, published as Amendment 2.
-
- [8] Goldsmith, D., and M. Davis, "Using Unicode with MIME", RFC 1641,
- July 1994.
-
- [9] Yergeau, F., "UTF-8, a transformation format of Unicode and ISO
- 10646", RFC 2044, October 1996.
-
- [10] ITU-T Recommendation H.332 (1998): "Multimedia Terminal for
- Receiving Internet-based H.323 Conferences", ITU, Geneva.
-
- [11] Handley, M., Schooler, E., and H. Schulzrinne, "Session
- Initiation Protocol (SIP)", Work in Progress.
-
- [12] Schulzrinne, H., Rao, A., and R. Lanphier, "Real Time Streaming
- Protocol (RTSP)", RFC 2326, April 1998.
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-Handley & Jacobson Standards Track [Page 41]
-
-RFC 2327 SDP April 1998
-
-
-Full Copyright Statement
-
- Copyright (C) The Internet Society (1998). All Rights Reserved.
-
- This document and translations of it may be copied and furnished to
- others, and derivative works that comment on or otherwise explain it
- or assist in its implementation may be prepared, copied, published
- and distributed, in whole or in part, without restriction of any
- kind, provided that the above copyright notice and this paragraph are
- included on all such copies and derivative works. However, this
- document itself may not be modified in any way, such as by removing
- the copyright notice or references to the Internet Society or other
- Internet organizations, except as needed for the purpose of
- developing Internet standards in which case the procedures for
- copyrights defined in the Internet Standards process must be
- followed, or as required to translate it into languages other than
- English.
-
- The limited permissions granted above are perpetual and will not be
- revoked by the Internet Society or its successors or assigns.
-
- This document and the information contained herein is provided on an
- "AS IS" basis and THE INTERNET SOCIETY AND THE INTERNET ENGINEERING
- TASK FORCE DISCLAIMS ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING
- BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE INFORMATION
- HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED WARRANTIES OF
- MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-Handley & Jacobson Standards Track [Page 42]
-
diff --git a/lib/megaco/doc/standard/rfc3266.txt b/lib/megaco/doc/standard/rfc3266.txt
deleted file mode 100644
index f047f12a1f..0000000000
--- a/lib/megaco/doc/standard/rfc3266.txt
+++ /dev/null
@@ -1,283 +0,0 @@
-
-
-
-
-
-
-Network Working Group S. Olson
-Request for Comments: 3266 Microsoft
-Updates: 2327 G. Camarillo
-Category: Standards Track Ericsson
- A. B. Roach
- dynamicsoft
- June 2002
-
-
- Support for IPv6 in Session Description Protocol (SDP)
-
-Status of this Memo
-
- This document specifies an Internet standards track protocol for the
- Internet community, and requests discussion and suggestions for
- improvements. Please refer to the current edition of the "Internet
- Official Protocol Standards" (STD 1) for the standardization state
- and status of this protocol. Distribution of this memo is unlimited.
-
-Copyright Notice
-
- Copyright (C) The Internet Society (2002). All Rights Reserved.
-
-Abstract
-
- This document describes the use of Internet Protocol Version 6 (IPv6)
- addresses in conjunction with the Session Description Protocol (SDP).
- Specifically, this document clarifies existing text in SDP with
- regards to the syntax of IPv6 addresses.
-
-1. Introduction
-
- SDP is intended for describing multimedia sessions for the purposes
- of session announcement, session invitation, and other forms of
- multimedia session initiation. It is a text format description that
- provides many details of a multimedia session including: the
- originator of the session, a URL related to the session, the
- connection address for the session media(s), and optional attributes
- for the session media(s). Each of these pieces of information may
- involve one or more IPv6 addresses. The ABNF for IP addresses in SDP
- currently leaves the syntax for IPv6 addresses undefined. This
- document attempts to complete the ABNF to include IPv6 addresses.
-
- Accordingly, the address type "IP6" indicating an IPv6 address,
- should be allowed in the connection field, "c=", of the SDP. The
- ABNF already reflects this, though the "Connection Data" text under
- section 6 of RFC 2328 currently only defines the "IP4" address type.
-
-
-
-
-Olson, et. al. Standards Track [Page 1]
-
-RFC 3266 Support for IPv6 in Session Description Protocol June 2002
-
-
-2. Terminology
-
- The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT",
- "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this
- document are to be interpreted as described in RFC 2119 [5].
-
-3. Syntax
-
- RFC 2373 [1] gives an ABNF for the text representation of IPv6
- addresses in Appendix B. RFC 2732 [3] covers the text representation
- of IPv6 addresses when used within a URL. Using the ABNF described
- in these documents, the following updated ABNF for SDP is proposed.
-
- uri = ; defined in RFC1630 and RFC2732
-
- multicast-address = IP4-multicast / IP6-multicast
-
- IP4-multicast = m1 3*( "." decimal-uchar )
- "/" ttl [ "/" integer ]
- ; IPv4 multicast addresses may be in the
- ; range 224.0.0.0 to 239.255.255.255
-
- m1 = ("22" ("4"/"5"/"6"/"7"/"8"/"9")) /
- ("23" DIGIT ))
-
- IP6-multicast = hexpart
- ; IPv6 address starting with FF
-
- addr = FQDN / unicast-address
-
- FQDN = 4*(alpha-numeric/"-"/".")
- ; fully qualified domain name as specified
- ; in RFC1035
- unicast-address = IP4-address / IP6-address
-
- IP4-address = b1 3*("." decimal-uchar) / "0.0.0.0"
-
- b1 = decimal-uchar
- ; less than "224"; not "0" or "127"
-
- ; The following is from RFC2373 Appendix B. It is a direct copy.
- IP6-address = hexpart [ ":" IP4-address ]
-
- hexpart = hexseq / hexseq "::" [ hexseq ] /
- "::" [ hexseq ]
-
-
-
-
-
-
-Olson, et. al. Standards Track [Page 2]
-
-RFC 3266 Support for IPv6 in Session Description Protocol June 2002
-
-
- hexseq = hex4 *( ":" hex4)
-
- hex4 = 1*4HEXDIG
-
-4. Example SDP description with IPv6 addresses
-
- The following is an example SDP description using the above ABNF for
- IPv6 addresses. In particular, the origin and connection fields
- contain IPv6 addresses.
-
- v=0
- o=nasa1 971731711378798081 0 IN IP6 2201:056D::112E:144A:1E24
- s=(Almost) live video feed from Mars-II satellite
- p=+1 713 555 1234
- c=IN IP6 FF1E:03AD::7F2E:172A:1E24
- t=3338481189 3370017201
- m=audio 6000 RTP/AVP 2
- a=rtpmap:2 G726-32/8000
- m=video 6024 RTP/AVP 107
- a=rtpmap:107 H263-1998/90000
-
-5. Note for implementors
-
- An implementation may receive an SDP session description with an IPv6
- address whose format [1] is internally that of an IPv4 mapped
- address. Note that such an address is actually the address of an
- IPv4-only node, and implementors are warned to interpret IPv4 mapped
- addresses as equivalent to IP4.
-
-6. IANA Considerations
-
- This document updates the definition of the IP6 addrtype parameter
- found in RFC 2327.
-
-7. Security Considerations
-
- No additional considerations above what is stated in section 7 of RFC
- 2327.
-
-8. References
-
- [1] Hinden, R. and S. Deering, "IP Version 6 Addressing
- Architecture", RFC 2373, July 1998.
-
- [2] Handley, M. and V. Jacobson, "SDP: Session Description
- Protocol", RFC 2327, April 1998.
-
-
-
-
-
-Olson, et. al. Standards Track [Page 3]
-
-RFC 3266 Support for IPv6 in Session Description Protocol June 2002
-
-
- [3] Hinden, R., Carpenter, B. and L. Masinter, "Format for Literal
- IPv6 Addresses in URL's", RFC 2732, December 1999.
-
- [4] Crocker, D. and P. Overell, "Augmented BNF for Syntax
- Specifications: ABNF", RFC 2234, November 1997.
-
- [5] Bradner, S., "Key words for Use in RFCs to Indicate Requirement
- Levels", BCP 14, RFC 2119, March 1997.
-
-9. Authors' Addresses
-
- Sean Olson
- Microsoft
- One Microsoft Way
- Redmond, WA 98052
- USA
-
-
-
- Gonzalo Camarillo
- Ericsson
- Advanced Signalling Research Lab.
- FIN-02420 Jorvas
- Finland
-
- Phone: +358 9 299 3371
- Fax: +358 9 299 3118
-
-
- Adam Roach
- dynamicsoft
- 5100 Tennyson Parkway
- Suite 1200
- Plano, TX 75024
- USA
-
- Voice: <sip:[email protected]>
-
-
-
-
-
-
-
-
-
-
-
-Olson, et. al. Standards Track [Page 4]
-
-RFC 3266 Support for IPv6 in Session Description Protocol June 2002
-
-
-10. Full Copyright Statement
-
- Copyright (C) The Internet Society (2002). All Rights Reserved.
-
- This document and translations of it may be copied and furnished to
- others, and derivative works that comment on or otherwise explain it
- or assist in its implementation may be prepared, copied, published
- and distributed, in whole or in part, without restriction of any
- kind, provided that the above copyright notice and this paragraph are
- included on all such copies and derivative works. However, this
- document itself may not be modified in any way, such as by removing
- the copyright notice or references to the Internet Society or other
- Internet organizations, except as needed for the purpose of
- developing Internet standards in which case the procedures for
- copyrights defined in the Internet Standards process must be
- followed, or as required to translate it into languages other than
- English.
-
- The limited permissions granted above are perpetual and will not be
- revoked by the Internet Society or its successors or assigns.
-
- This document and the information contained herein is provided on an
- "AS IS" basis and THE INTERNET SOCIETY AND THE INTERNET ENGINEERING
- TASK FORCE DISCLAIMS ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING
- BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE INFORMATION
- HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED WARRANTIES OF
- MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
-
-Acknowledgement
-
- Funding for the RFC Editor function is currently provided by the
- Internet Society.
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-Olson, et. al. Standards Track [Page 5]
-
diff --git a/lib/megaco/examples/meas/meas.sh.skel b/lib/megaco/examples/meas/meas.sh.skel
index 4bbc6a5f7e..76745ed8f4 100644
--- a/lib/megaco/examples/meas/meas.sh.skel
+++ b/lib/megaco/examples/meas/meas.sh.skel
@@ -1,20 +1,20 @@
#!/bin/sh
# %CopyrightBegin%
-#
-# Copyright Ericsson AB 2007-2009. All Rights Reserved.
-#
+#
+# Copyright Ericsson AB 2007-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%
#
@@ -27,7 +27,7 @@ MEAS_HOME=$MEGACO_HOME/examples/meas
PATH=$ERL_HOME/bin:$PATH
# MEAS_TIME_TEST="-s megaco_codec_meas start time_test"
-MEAS_DEFAULT="-s megaco_codec_meas t"
+MEAS_DEFAULT="-s megaco_codec_meas start"
STOP="-s init stop"
ERL="erl \
diff --git a/lib/megaco/include/megaco.hrl b/lib/megaco/include/megaco.hrl
index 4045fa9461..87e830323f 100644
--- a/lib/megaco/include/megaco.hrl
+++ b/lib/megaco/include/megaco.hrl
@@ -1,19 +1,20 @@
-%% ``The contents of this file are subject to the Erlang Public License,
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 1999-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 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%
%%
%%----------------------------------------------------------------------
%% Purpose: Define common data structures and error codes
diff --git a/lib/megaco/src/app/megaco.appup.src b/lib/megaco/src/app/megaco.appup.src
index 163ff06651..f939f5e6cf 100644
--- a/lib/megaco/src/app/megaco.appup.src
+++ b/lib/megaco/src/app/megaco.appup.src
@@ -1,19 +1,20 @@
+%% This is an -*- erlang -*- file.
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2001-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 2001-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%
%%
@@ -120,43 +121,97 @@
%% |
%% v
%% 3.13
+%% |
+%% v
+%% 3.14
+%% |
+%% v
+%% 3.14.1
%%
%%
{"%VSN%",
[
+ {"3.14",
+ [
+ {load_module, megaco_messenger, soft_purge, soft_purge, [megaco_monitor]},
+ {update, megaco_monitor, soft, soft_purge, soft_purge, []},
+ {update, megaco_config, soft, soft_purge, soft_purge, []}
+ ]
+ },
+ {"3.13",
+ [
+ {load_module, megaco_messenger, soft_purge, soft_purge, [megaco_monitor]},
+ {load_module, megaco_filter, soft_purge, soft_purge, []},
+ {update, megaco_monitor, soft, soft_purge, soft_purge, []},
+ {update, megaco_config, soft, soft_purge, soft_purge, []},
+ {update, megaco_flex_scanner_handler, {advanced, downgrade_to_pre_3_13_1},
+ soft_purge, soft_purge, []}
+ ]
+ },
{"3.12",
[
+ {load_module, megaco_filter, soft_purge, soft_purge, []},
{load_module, megaco_udp, soft_purge, soft_purge, []},
{load_module, megaco_messenger, soft_purge, soft_purge, [megaco_monitor]},
- {update, megaco_monitor, soft, soft_purge, soft_purge, []}
+ {update, megaco_config, soft, soft_purge, soft_purge, []},
+ {update, megaco_monitor, soft, soft_purge, soft_purge, []},
+ {update, megaco_flex_scanner_handler, {advanced, downgrade_to_pre_3_13_1},
+ soft_purge, soft_purge, []}
]
},
{"3.11.3",
[
+ {load_module, megaco_filter, soft_purge, soft_purge, []},
{load_module, megaco_udp, soft_purge, soft_purge, []},
{load_module, megaco_messenger, soft_purge, soft_purge,
[megaco_config, megaco_monitor]},
{update, megaco_monitor, soft, soft_purge, soft_purge, []},
{update, megaco_config, {advanced, upgrade_from_pre_3_12},
+ soft_purge, soft_purge, []},
+ {update, megaco_flex_scanner_handler, {advanced, downgrade_to_pre_3_13_1},
soft_purge, soft_purge, []}
]
}
],
[
+ {"3.14",
+ [
+ {load_module, megaco_messenger, soft_purge, soft_purge, [megaco_monitor]},
+ {update, megaco_monitor, soft, soft_purge, soft_purge, []},
+ {update, megaco_config, soft, soft_purge, soft_purge, []}
+ ]
+ },
+ {"3.13",
+ [
+ {load_module, megaco_messenger, soft_purge, soft_purge, [megaco_monitor]},
+ {load_module, megaco_filter, soft_purge, soft_purge, []},
+ {update, megaco_monitor, soft, soft_purge, soft_purge, []},
+ {update, megaco_config, soft, soft_purge, soft_purge, []},
+ {update, megaco_flex_scanner_handler, {advanced, upgrade_from_pre_3_13_1},
+ soft_purge, soft_purge, []}
+ ]
+ },
{"3.12",
[
+ {load_module, megaco_filter, soft_purge, soft_purge, []},
{load_module, megaco_udp, soft_purge, soft_purge, []},
{load_module, megaco_messenger, soft_purge, soft_purge, [megaco_monitor]},
- {update, megaco_monitor, soft, soft_purge, soft_purge, []}
+ {update, megaco_config, soft, soft_purge, soft_purge, []},
+ {update, megaco_monitor, soft, soft_purge, soft_purge, []},
+ {update, megaco_flex_scanner_handler, {advanced, upgrade_from_pre_3_13_1},
+ soft_purge, soft_purge, []}
]
},
{"3.11.3",
[
+ {load_module, megaco_filter, soft_purge, soft_purge, []},
{load_module, megaco_udp, soft_purge, soft_purge, []},
{load_module, megaco_messenger, soft_purge, soft_purge,
[megaco_config, megaco_monitor]},
{update, megaco_monitor, soft, soft_purge, soft_purge, []},
{update, megaco_config, {advanced, downgrade_to_pre_3_12},
+ soft_purge, soft_purge, []},
+ {update, megaco_flex_scanner_handler, {advanced, upgrade_from_pre_3_13_1},
soft_purge, soft_purge, []}
]
}
diff --git a/lib/megaco/src/app/megaco_internal.hrl b/lib/megaco/src/app/megaco_internal.hrl
index adbaacacef..2c124e9060 100644
--- a/lib/megaco/src/app/megaco_internal.hrl
+++ b/lib/megaco/src/app/megaco_internal.hrl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 1999-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 1999-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%
%%
@@ -139,6 +139,22 @@
[?APPLICATION, ?MODULE, self()|A]))).
+-define(megaco_ereport(Label, Report),
+ ?megaco_report(error_report, Label, Report)).
+
+-define(megaco_wreport(Label, Report),
+ ?megaco_report(warning_report, Label, Report)).
+
+-define(megaco_ireport(Label, Report),
+ ?megaco_report(info_report, Label, Report)).
+
+-define(megaco_report(Func, Label, Report),
+ (catch error_logger:Func([{label, Label},
+ {application, ?APPLICATION},
+ {module, ?MODULE},
+ {process, self()} | Report]))).
+
+
%%%----------------------------------------------------------------------
%%% Default (ignore) value of the Extra argument to the
%%% megaco:receive_message/5 and process_received_message functions/5.
diff --git a/lib/megaco/src/engine/megaco_config.erl b/lib/megaco/src/engine/megaco_config.erl
index 2058c53973..6805db790d 100644
--- a/lib/megaco/src/engine/megaco_config.erl
+++ b/lib/megaco/src/engine/megaco_config.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2000-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 2000-2010. All Rights Reserved.
+%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
-%%
+%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
-%%
+%%
%% %CopyrightEnd%
%%
@@ -224,149 +224,278 @@ update_user_info(UserMid, orig_pending_limit, Val) ->
update_user_info(UserMid, Item, Val) ->
call({update_user_info, UserMid, Item, Val}).
-conn_info(CH, Item)
- when is_record(CH, megaco_conn_handle) andalso (Item /= cancel) ->
- case Item of
- conn_handle ->
- CH;
- mid ->
- CH#megaco_conn_handle.local_mid;
- local_mid ->
- CH#megaco_conn_handle.local_mid;
- remote_mid ->
- CH#megaco_conn_handle.remote_mid;
- conn_data ->
- case lookup_local_conn(CH) of
- [] ->
- exit({no_such_connection, CH});
- [ConnData] ->
- ConnData
- end;
- _ ->
- case lookup_local_conn(CH) of
- [] ->
- exit({no_such_connection, CH});
- [ConnData] ->
- conn_info(ConnData, Item)
- end
+
+conn_info(Data, Item) ->
+ %% The purpose of this is a compiler optimization...
+ %% Args are processed from left to right.
+ do_conn_info(Item, Data).
+
+do_conn_info(mid = _Item, #megaco_conn_handle{local_mid = Mid}) ->
+ Mid;
+do_conn_info(local_mid = _Item, #megaco_conn_handle{local_mid = LMid}) ->
+ LMid;
+do_conn_info(remote_mid = _Item, #megaco_conn_handle{remote_mid = RMid}) ->
+ RMid;
+do_conn_info(conn_handle = _Item, CH) when is_record(CH, megaco_conn_handle) ->
+ CH;
+do_conn_info(conn_data = _Item, CH) when is_record(CH, megaco_conn_handle) ->
+ case lookup_local_conn(CH) of
+ [] ->
+ exit({no_such_connection, CH});
+ [ConnData] ->
+ ConnData
+ end;
+do_conn_info(Item, CH) when is_record(CH, megaco_conn_handle) ->
+ case lookup_local_conn(CH) of
+ [] ->
+ exit({no_such_connection, CH});
+ [ConnData] ->
+ do_conn_info(Item, ConnData)
end;
-conn_info(#conn_data{conn_handle = CH}, cancel) ->
+
+do_conn_info(cancel = _Item, #conn_data{conn_handle = CH}) ->
+ %% To minimise raise-condition propabillity,
+ %% we always look in the table instead of
+ %% in the record for this one
+ ets:lookup_element(megaco_local_conn, CH, #conn_data.cancel);
+do_conn_info(cancel = _Item, CH) when is_record(CH, megaco_conn_handle) ->
%% To minimise raise-condition propabillity,
%% we always look in the table instead of
%% in the record for this one
ets:lookup_element(megaco_local_conn, CH, #conn_data.cancel);
-conn_info(CD, Item) when is_record(CD, conn_data) ->
- case Item of
- all ->
- Tags0 = record_info(fields, conn_data),
- Tags1 = replace(serial, trans_id, Tags0),
- Tags = [mid, local_mid, remote_mid] ++
- replace(max_serial, max_trans_id, Tags1),
- [{Tag, conn_info(CD,Tag)} || Tag <- Tags,
- Tag /= conn_data,
- Tag /= trans_sender,
- Tag /= cancel];
- conn_data -> CD;
- conn_handle -> CD#conn_data.conn_handle;
- mid -> (CD#conn_data.conn_handle)#megaco_conn_handle.local_mid;
- local_mid -> (CD#conn_data.conn_handle)#megaco_conn_handle.local_mid;
- remote_mid -> (CD#conn_data.conn_handle)#megaco_conn_handle.remote_mid;
- trans_id -> CH = CD#conn_data.conn_handle,
- LocalMid = CH#megaco_conn_handle.local_mid,
- Item2 = {LocalMid, trans_id_counter},
- case (catch ets:lookup(megaco_config, Item2)) of
- {'EXIT', _} ->
- undefined_serial;
- [] ->
- user_info(LocalMid, min_trans_id);
- [{_, Serial}] ->
- Max = CD#conn_data.max_serial,
- if
- ((Max =:= infinity) andalso
- is_integer(Serial) andalso
- (Serial < 4294967295)) ->
- Serial + 1;
- (Max =:= infinity) andalso
- is_integer(Serial) andalso
- (Serial =:= 4294967295) ->
- user_info(LocalMid,
- min_trans_id);
- Serial < Max ->
- Serial + 1;
- Serial =:= Max ->
- user_info(LocalMid,
- min_trans_id);
- Serial =:= 4294967295 ->
- user_info(LocalMid,
- min_trans_id);
- true ->
- undefined_serial
- end
- end;
- max_trans_id -> CD#conn_data.max_serial;
- request_timer -> CD#conn_data.request_timer;
- long_request_timer -> CD#conn_data.long_request_timer;
-
- auto_ack -> CD#conn_data.auto_ack;
-
- trans_ack -> CD#conn_data.trans_ack;
- trans_ack_maxcount -> CD#conn_data.trans_ack_maxcount;
-
- trans_req -> CD#conn_data.trans_req;
- trans_req_maxcount -> CD#conn_data.trans_req_maxcount;
- trans_req_maxsize -> CD#conn_data.trans_req_maxsize;
-
- trans_timer -> CD#conn_data.trans_timer;
-
- pending_timer -> CD#conn_data.pending_timer;
- orig_pending_limit -> CD#conn_data.sent_pending_limit;
- sent_pending_limit -> CD#conn_data.sent_pending_limit;
- recv_pending_limit -> CD#conn_data.recv_pending_limit;
- reply_timer -> CD#conn_data.reply_timer;
- control_pid -> CD#conn_data.control_pid;
- monitor_ref -> CD#conn_data.monitor_ref;
- send_mod -> CD#conn_data.send_mod;
- send_handle -> CD#conn_data.send_handle;
- encoding_mod -> CD#conn_data.encoding_mod;
- encoding_config -> CD#conn_data.encoding_config;
- protocol_version -> CD#conn_data.protocol_version;
- auth_data -> CD#conn_data.auth_data;
- user_mod -> CD#conn_data.user_mod;
- user_args -> CD#conn_data.user_args;
- reply_action -> CD#conn_data.reply_action;
- reply_data -> CD#conn_data.reply_data;
- threaded -> CD#conn_data.threaded;
- strict_version -> CD#conn_data.strict_version;
- long_request_resend -> CD#conn_data.long_request_resend;
- call_proxy_gc_timeout -> CD#conn_data.call_proxy_gc_timeout;
- cancel -> CD#conn_data.cancel;
- resend_indication -> CD#conn_data.resend_indication;
- segment_reply_ind -> CD#conn_data.segment_reply_ind;
- segment_recv_acc -> CD#conn_data.segment_recv_acc;
- segment_recv_timer -> CD#conn_data.segment_recv_timer;
- segment_send -> CD#conn_data.segment_send;
- segment_send_timer -> CD#conn_data.segment_send_timer;
- max_pdu_size -> CD#conn_data.max_pdu_size;
- request_keep_alive_timeout -> CD#conn_data.request_keep_alive_timeout;
- receive_handle ->
- LocalMid = (CD#conn_data.conn_handle)#megaco_conn_handle.local_mid,
- #megaco_receive_handle{local_mid = LocalMid,
- encoding_mod = CD#conn_data.encoding_mod,
- encoding_config = CD#conn_data.encoding_config,
- send_mod = CD#conn_data.send_mod};
- _ ->
- exit({no_such_item, Item})
+do_conn_info(all = _Item,
+ #conn_data{conn_handle = CH,
+ serial = TransId,
+ max_serial = MaxTransId,
+ request_timer = ReqTmr,
+ long_request_timer = LongReqTmr,
+ auto_ack = AutoAck,
+ trans_ack = TransAck,
+ trans_ack_maxcount = TransAckMaxCount,
+ trans_req = TransReq,
+ trans_req_maxcount = TransReqMaxCount,
+ trans_req_maxsize = TransReqMaxSz,
+ trans_timer = TransTmr,
+ %% trans_sender,
+ pending_timer = PendingTmr,
+ sent_pending_limit = SentPendingLimit,
+ recv_pending_limit = RecvPendingLimit,
+ reply_timer = ReplyTmr,
+ control_pid = CtrlPid,
+ monitor_ref = MonRef,
+ send_mod = SendMod,
+ send_handle = SendHandle,
+ encoding_mod = EncodingMod,
+ encoding_config = EncodingConf,
+ protocol_version = ProtoVersion,
+ auth_data = AuthData,
+ user_mod = UserMod,
+ user_args = UserArgs,
+ reply_action = ReplyAction,
+ reply_data = ReplyData,
+ threaded = Threaded,
+ strict_version = StrictVersion,
+ long_request_resend = LongReqResend,
+ call_proxy_gc_timeout = CallProxyGCTimeout,
+ %% cancel,
+ resend_indication = ResendInd,
+ segment_reply_ind = SegReplyInd,
+ segment_recv_acc = SegRecvAcc,
+ segment_recv_timer = SegRecvTmr,
+ segment_send = SegSend,
+ segment_send_timer = SegSendTmr,
+ max_pdu_size = MaxPduSz,
+ request_keep_alive_timeout = RequestKeepAliveTmr}) ->
+ [{conn_handle, CH},
+ {trans_id, TransId},
+ {max_trans_id, MaxTransId},
+ {request_timer, ReqTmr},
+ {long_request_timer, LongReqTmr},
+ {mid, CH#megaco_conn_handle.local_mid},
+ {local_mid, CH#megaco_conn_handle.local_mid},
+ {remote_mid, CH#megaco_conn_handle.remote_mid},
+ {auto_ack, AutoAck},
+ {trans_ack, TransAck},
+ {trans_ack_maxcount, TransAckMaxCount},
+ {trans_req, TransReq},
+ {trans_req_maxcount, TransReqMaxCount},
+ {trans_req_maxsize, TransReqMaxSz},
+ {trans_timer, TransTmr},
+ {pending_timer, PendingTmr},
+ {sent_pending_limit, SentPendingLimit},
+ {recv_pending_limit, RecvPendingLimit},
+ {reply_timer, ReplyTmr},
+ {control_pid, CtrlPid},
+ {monitor_ref, MonRef},
+ {send_mod, SendMod},
+ {send_handle, SendHandle},
+ {encoding_mod, EncodingMod},
+ {encoding_config, EncodingConf},
+ {protocol_version, ProtoVersion},
+ {auth_data, AuthData},
+ {user_mod, UserMod},
+ {user_args, UserArgs},
+ {reply_action, ReplyAction},
+ {reply_data, ReplyData},
+ {threaded, Threaded},
+ {strict_version, StrictVersion},
+ {long_request_resend, LongReqResend},
+ {call_proxy_gc_timeout, CallProxyGCTimeout},
+ {resend_indication, ResendInd},
+ {segment_reply_ind, SegReplyInd},
+ {segment_recv_acc, SegRecvAcc},
+ {segment_recv_timer, SegRecvTmr},
+ {segment_send, SegSend},
+ {segment_send_timer, SegSendTmr},
+ {max_pdu_size, MaxPduSz},
+ {request_keep_alive_timeout, RequestKeepAliveTmr}];
+
+do_conn_info(conn_data = _Item, CD) ->
+ CD;
+do_conn_info(conn_handle = _Item, #conn_data{conn_handle = Val}) ->
+ Val;
+do_conn_info(mid = _Item,
+ #conn_data{conn_handle = #megaco_conn_handle{local_mid = Val}}) ->
+ Val;
+do_conn_info(local_mid = _Item,
+ #conn_data{conn_handle = #megaco_conn_handle{local_mid = Val}}) ->
+ Val;
+do_conn_info(remote_mid = _Item,
+ #conn_data{conn_handle = #megaco_conn_handle{remote_mid = Val}}) ->
+ Val;
+do_conn_info(trans_id = _Item,
+ #conn_data{conn_handle = #megaco_conn_handle{local_mid = LMid},
+ max_serial = Max}) ->
+ Item2 = {LMid, trans_id_counter},
+ case (catch ets:lookup(megaco_config, Item2)) of
+ {'EXIT', _} ->
+ undefined_serial;
+ [] ->
+ user_info(LMid, min_trans_id);
+ [{_, Serial}] ->
+ if
+ ((Max =:= infinity) andalso
+ is_integer(Serial) andalso
+ (Serial < 4294967295)) ->
+ Serial + 1;
+ ((Max =:= infinity) andalso
+ is_integer(Serial) andalso
+ (Serial =:= 4294967295)) ->
+ user_info(LMid, min_trans_id);
+ Serial < Max ->
+ Serial + 1;
+ Serial =:= Max ->
+ user_info(LMid, min_trans_id);
+ Serial =:= 4294967295 ->
+ user_info(LMid, min_trans_id);
+ true ->
+ undefined_serial
+ end
end;
-conn_info(BadHandle, _Item) ->
- {error, {no_such_connection, BadHandle}}.
-
-replace(_, _, []) ->
- [];
-replace(Item, WithItem, [Item|List]) ->
- [WithItem|List];
-replace(Item, WithItem, [OtherItem|List]) ->
- [OtherItem | replace(Item, WithItem, List)].
+do_conn_info(max_trans_id = _Item, #conn_data{max_serial = Val}) ->
+ Val;
+do_conn_info(request_timer = _Item, #conn_data{request_timer = Val}) ->
+ Val;
+do_conn_info(long_request_timer = _Item, #conn_data{long_request_timer = Val}) ->
+ Val;
+do_conn_info(auto_ack = _Item, #conn_data{auto_ack = Val}) ->
+ Val;
+do_conn_info(trans_ack = _Item, #conn_data{trans_ack = Val}) ->
+ Val;
+do_conn_info(trans_ack_maxcount = _Item, #conn_data{trans_ack_maxcount = Val}) ->
+ Val;
+do_conn_info(trans_req = _Item, #conn_data{trans_req = Val}) ->
+ Val;
+do_conn_info(trans_req_maxcount = _Item, #conn_data{trans_req_maxcount = Val}) ->
+ Val;
+do_conn_info(trans_req_maxsize = _Item, #conn_data{trans_req_maxsize = Val}) ->
+ Val;
+do_conn_info(trans_timer = _Item, #conn_data{trans_timer = Val}) ->
+ Val;
+do_conn_info(pending_timer = _Item, #conn_data{pending_timer = Val}) ->
+ Val;
+do_conn_info(orig_pending_limit = _Item, #conn_data{sent_pending_limit = Val}) ->
+ Val;
+do_conn_info(sent_pending_limit = _Item, #conn_data{sent_pending_limit = Val}) ->
+ Val;
+do_conn_info(recv_pending_limit = _Item, #conn_data{recv_pending_limit = Val}) ->
+ Val;
+do_conn_info(reply_timer = _Item, #conn_data{reply_timer = Val}) ->
+ Val;
+do_conn_info(control_pid = _Item, #conn_data{control_pid = Val}) ->
+ Val;
+do_conn_info(send_mod = _Item, #conn_data{send_mod = Val}) ->
+ Val;
+do_conn_info(send_handle = _Item, #conn_data{send_handle = Val}) ->
+ Val;
+do_conn_info(encoding_mod = _Item, #conn_data{encoding_mod = Val}) ->
+ Val;
+do_conn_info(encoding_config = _Item, #conn_data{encoding_config = Val}) ->
+ Val;
+do_conn_info(protocol_version = _Item, #conn_data{protocol_version = Val}) ->
+ Val;
+do_conn_info(auth_data = _Item, #conn_data{auth_data = Val}) ->
+ Val;
+do_conn_info(user_mod = _Item, #conn_data{user_mod = Val}) ->
+ Val;
+do_conn_info(user_args = _Item, #conn_data{user_args = Val}) ->
+ Val;
+do_conn_info(reply_action = _Item, #conn_data{reply_action = Val}) ->
+ Val;
+do_conn_info(reply_data = _Item, #conn_data{reply_data = Val}) ->
+ Val;
+do_conn_info(threaded = _Item, #conn_data{threaded = Val}) ->
+ Val;
+do_conn_info(strict_version = _Item, #conn_data{strict_version = Val}) ->
+ Val;
+do_conn_info(long_request_resend = _Item,
+ #conn_data{long_request_resend = Val}) ->
+ Val;
+do_conn_info(call_proxy_gc_timeout = _Item,
+ #conn_data{call_proxy_gc_timeout = Val}) ->
+ Val;
+do_conn_info(resend_indication = _Item, #conn_data{resend_indication = Val}) ->
+ Val;
+do_conn_info(segment_reply_ind = _Item, #conn_data{segment_reply_ind = Val}) ->
+ Val;
+do_conn_info(segment_recv_acc = _Item, #conn_data{segment_recv_acc = Val}) ->
+ Val;
+do_conn_info(segment_recv_timer = _Item,
+ #conn_data{segment_recv_timer = Val}) ->
+ Val;
+do_conn_info(segment_send = _Item, #conn_data{segment_send = Val}) ->
+ Val;
+do_conn_info(segment_send_timer = _Item,
+ #conn_data{segment_send_timer = Val}) ->
+ Val;
+do_conn_info(max_pdu_size = _Item, #conn_data{max_pdu_size = Val}) ->
+ Val;
+do_conn_info(request_keep_alive_timeout = _Item,
+ #conn_data{request_keep_alive_timeout = Val}) ->
+ Val;
+do_conn_info(receive_handle = _Item,
+ #conn_data{conn_handle = #megaco_conn_handle{local_mid = LMid},
+ encoding_mod = EM,
+ encoding_config = EC,
+ send_mod = SM}) ->
+ #megaco_receive_handle{local_mid = LMid,
+ encoding_mod = EM,
+ encoding_config = EC,
+ send_mod = SM};
+do_conn_info(Item, Data)
+ when is_record(Data, conn_data) orelse is_record(Data, megaco_conn_handle) ->
+ exit({no_such_item, Item});
+do_conn_info(_Item, BadData) ->
+ {error, {no_such_connection, BadData}}.
+
+
+%% replace(_, _, []) ->
+%% [];
+%% replace(Item, WithItem, [Item|List]) ->
+%% [WithItem|List];
+%% replace(Item, WithItem, [OtherItem|List]) ->
+%% [OtherItem | replace(Item, WithItem, List)].
update_conn_info(#conn_data{conn_handle = CH}, Item, Val) ->
@@ -499,31 +628,19 @@ incr_counter(Item, Incr) ->
end
catch
error:_ ->
+ %% Counter does not exist, so try creat it
try
begin
cre_counter(Item, Incr)
end
catch
exit:_ ->
- %% Ok, some other process got there before us,
- %% so try again
+ %% This is a raise condition.
+ %% When we tried to update the counter above, it
+ %% did not exist, but now it does...
ets:update_counter(megaco_config, Item, Incr)
end
end.
-%% incr_counter(Item, Incr) ->
-%% case (catch ets:update_counter(megaco_config, Item, Incr)) of
-%% {'EXIT', _} ->
-%% case (catch cre_counter(Item, Incr)) of
-%% {'EXIT', _} ->
-%% %% Ok, some other process got there before us,
-%% %% so try again
-%% ets:update_counter(megaco_config, Item, Incr);
-%% NewVal ->
-%% NewVal
-%% end;
-%% NewVal ->
-%% NewVal
-%% end.
cre_counter(Item, Initial) ->
case whereis(?SERVER) =:= self() of
@@ -531,8 +648,8 @@ cre_counter(Item, Initial) ->
case call({cre_counter, Item, Initial}) of
{ok, Value} ->
Value;
- Error ->
- exit(Error)
+ {error, Reason} ->
+ exit({failed_creating_counter, Item, Initial, Reason})
end;
true ->
%% Check that the counter does not already exists
@@ -542,7 +659,7 @@ cre_counter(Item, Initial) ->
ets:insert(megaco_config, {Item, Initial}),
{ok, Initial};
[_] ->
- %% Ouch, now what?
+ %% Possibly a raise condition
{error, already_exists}
end
@@ -1432,7 +1549,7 @@ verify_val(Item, Val) ->
segment_send_timer -> verify_timer(Val);
max_pdu_size -> verify_int(Val) andalso (Val > 0);
request_keep_alive_timeout ->
- (verify_int(Val) andalso (Val >= 0)) orelse (Val =:= plain);
+ (verify_uint(Val) orelse (Val =:= plain));
_ -> false
end.
diff --git a/lib/megaco/src/engine/megaco_filter.erl b/lib/megaco/src/engine/megaco_filter.erl
index 23a91b1f1d..9df752789c 100644
--- a/lib/megaco/src/engine/megaco_filter.erl
+++ b/lib/megaco/src/engine/megaco_filter.erl
@@ -1,37 +1,83 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2000-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 2000-2010. All Rights Reserved.
+%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
-%%
+%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
-%%
+%%
%% %CopyrightEnd%
%%
%%
%%----------------------------------------------------------------------
-%% Purpose : megaco/H.248 customization of generic event tracer
+%% Purpose : Megaco/H.248 customization of the Event Tracer tool
%%----------------------------------------------------------------------
-module(megaco_filter).
--export([start/0, start/1, filter/1,
+-export([start/0, start/1, filter/1, raw_filter/1,
pretty_error/1, string_to_term/1]).
+
-include_lib("megaco/include/megaco.hrl").
-include_lib("megaco/include/megaco_message_v1.hrl").
-include_lib("megaco/src/app/megaco_internal.hrl").
-include_lib("et/include/et.hrl").
+%%----------------------------------------------------------------------
+%% BUGBUG: There are some opportunities for improvements:
+%%
+%% * This version of the module does only handle version 1 of the messages.
+%%
+%% * The record definition of megaco_transaction_reply is copied from
+%% megaco_message_internal.hrl as that header file contains some
+%% records that already are defined in megaco_message_{v1,v2,v3}.hrl.
+%% * The records megaco_udp and megaco_tcp are copied from the files
+%% megaco_udp.hrl and megaco_tcp.hrl respectively, as we cannot include
+%% both header files. They both defines the macros HEAP_SIZE and GC_MSG_LIMIT.
+
+%%-include("megaco_message_internal.hrl").
+-record('megaco_transaction_reply',
+ {
+ transactionId,
+ immAckRequired = asn1_NOVALUE,
+ transactionResult,
+ segmentNumber = asn1_NOVALUE,
+ segmentationComplete = asn1_NOVALUE
+ }).
+
+%% -include_lib("megaco/src/udp/megaco_udp.hrl").
+-record(megaco_udp,
+ {port,
+ options = [],
+ socket,
+ receive_handle,
+ module = megaco,
+ serialize = false % false: Spawn a new process for each message
+ }).
+
+%% -include_lib("megaco/src/tcp/megaco_tcp.hrl").
+-record(megaco_tcp,
+ {host,
+ port,
+ options = [],
+ socket,
+ proxy_pid,
+ receive_handle,
+ module = megaco,
+ serialize = false % false: Spawn a new process for each message
+ }).
+%%----------------------------------------------------------------------
+
start() ->
start([]).
@@ -47,11 +93,20 @@ start(ExtraOptions) ->
{title, "Megaco tracer - Erlang/OTP"} | ExtraOptions],
et_viewer:start(Options).
-filter(E) when is_record(E, event) ->
+filter(E) ->
+ case catch raw_filter(E) of
+ {'EXIT', Reason} = Error->
+ io:format("~p: ~p\n", [?MODULE, Error]),
+ exit(Reason);
+ E2 ->
+ E2
+ end.
+
+raw_filter(E) when is_record(E, event) ->
From = filter_actor(E#event.from),
To = filter_actor(E#event.to),
E2 = E#event{from = From, to = To},
- E3 = filter_contents(E#event.contents, E2, []),
+ E3 = filter_contents(E#event.contents, E2),
{true, E3}.
filter_actors(From, To, E)
@@ -101,6 +156,9 @@ filter_user_actor(Actor) ->
do_filter_actor(CH) when is_record(CH, megaco_conn_handle) ->
Mid = CH#megaco_conn_handle.local_mid,
do_filter_actor(Mid);
+do_filter_actor(RH) when is_record(RH, megaco_receive_handle) ->
+ Mid = RH#megaco_receive_handle.local_mid,
+ do_filter_actor(Mid);
do_filter_actor(Actor) ->
case Actor of
{ip4Address, {'IP4Address', [A1,A2,A3,A4], asn1_NOVALUE}} ->
@@ -130,86 +188,108 @@ do_filter_actor(Actor) ->
"UNKNOWN"
end.
-filter_contents([], E, Contents) ->
- E#event{contents = lists:flatten(lists:reverse(Contents))};
-filter_contents([H | T], E, Contents) ->
+
+filter_contents(Contents, E) ->
+ do_filter_contents(Contents, E, missing_conn_data, []).
+
+do_filter_contents([H | T], E, ConnData, Contents) ->
case H of
- {line, _Mod, _Line} ->
- filter_contents(T, E, Contents);
+ Udp when is_record(Udp, megaco_udp) ->
+ RH = Udp#megaco_udp.receive_handle,
+ Actor = filter_actor(RH),
+ E2 = E#event{from = Actor, to = Actor},
+ Pretty =
+ ["Port: ", integer_to_list(Udp#megaco_udp.port), "\n",
+ "Encoder: ", atom_to_list(RH#megaco_receive_handle.encoding_mod)],
+ do_filter_contents(T, E2, ConnData, [[Pretty, "\n"], Contents]);
+ Tcp when is_record(Tcp, megaco_tcp) ->
+ RH = Tcp#megaco_tcp.receive_handle,
+ Actor = filter_actor(RH),
+ E2 = E#event{from = Actor, to = Actor},
+ Pretty =
+ ["Port: ", integer_to_list(Tcp#megaco_tcp.port), "\n",
+ "Encoder: ", atom_to_list(RH#megaco_receive_handle.encoding_mod)],
+ do_filter_contents(T, E2, ConnData, [[Pretty, "\n"], Contents]);
CD when is_record(CD, conn_data) ->
CH = CD#conn_data.conn_handle,
From = CH#megaco_conn_handle.local_mid,
- To = CH#megaco_conn_handle.remote_mid,
+ To = CH#megaco_conn_handle.remote_mid,
E2 = filter_actors(From, To, E),
Serial = CD#conn_data.serial,
E3 = append_serial(Serial, E2),
- filter_contents(T, E3, Contents);
+ do_filter_contents(T, E3, CD, Contents);
CH when is_record(CH, megaco_conn_handle) ->
From = CH#megaco_conn_handle.local_mid,
- To = CH#megaco_conn_handle.remote_mid,
+ To = CH#megaco_conn_handle.remote_mid,
E2 = filter_actors(From, To, E),
- filter_contents(T, E2, Contents);
- {orig_conn_handle, _CH} ->
- filter_contents(T, E, Contents);
+ do_filter_contents(T, E2, ConnData, Contents);
RH when is_record(RH, megaco_receive_handle) ->
Actor = RH#megaco_receive_handle.local_mid,
E2 = filter_actors(Actor, Actor, E),
- filter_contents(T, E2, Contents);
- {pid, Pid} when is_pid(Pid) ->
- filter_contents(T, E, Contents);
- pending ->
- filter_contents(T, E, Contents);
- reply ->
- filter_contents(T, E, Contents);
+ do_filter_contents(T, E2, ConnData, Contents);
{error, Reason} ->
Pretty = pretty_error({error, Reason}),
E2 = prepend_error(E),
- filter_contents(T, E2, [[Pretty, "\n"], Contents]);
+ do_filter_contents(T, E2, ConnData, [[Pretty, "\n"], Contents]);
{'EXIT', Reason} ->
Pretty = pretty_error({'EXIT', Reason}),
E2 = prepend_error(E),
- filter_contents(T, E2, [[Pretty, "\n"], Contents]);
+ do_filter_contents(T, E2, ConnData, [[Pretty, "\n"], Contents]);
ED when is_record(ED, 'ErrorDescriptor') ->
Pretty = pretty_error(ED),
E2 = prepend_error(E),
- filter_contents(T, E2, [[Pretty, "\n"], Contents]);
+ do_filter_contents(T, E2, ConnData, [[Pretty, "\n"], Contents]);
Trans when is_record(Trans, 'TransactionRequest') ->
- Pretty = pretty({trans, {transactionRequest, Trans}}),
- filter_contents([], E, [[Pretty, "\n"], Contents]);
+ Pretty = pretty(ConnData, {trans, {transactionRequest, Trans}}),
+ do_filter_contents([], E, ConnData, [[Pretty, "\n"], Contents]);
+ {transactionRequest, Trans} when is_record(Trans, 'TransactionRequest') ->
+ Pretty = pretty(ConnData, {trans, {transactionRequest, Trans}}),
+ do_filter_contents([], E, ConnData, [[Pretty, "\n"], Contents]);
Trans when is_record(Trans, 'TransactionReply') ->
- Pretty = pretty({trans, {transactionReply, Trans}}),
- filter_contents([], E, [[Pretty, "\n"], Contents]);
+ Pretty = pretty(ConnData, {trans, {transactionReply, Trans}}),
+ do_filter_contents([], E, ConnData, [[Pretty, "\n"], Contents]);
+ Trans when is_record(Trans, megaco_transaction_reply) ->
+ %% BUGBUG: Version 1 special
+ TransV1 =
+ #'TransactionReply'{transactionId = Trans#megaco_transaction_reply.transactionId,
+ immAckRequired = Trans#megaco_transaction_reply.immAckRequired,
+ transactionResult = Trans#megaco_transaction_reply.transactionResult},
+ Pretty = pretty(ConnData, {trans, {transactionReply, TransV1}}),
+ do_filter_contents([], E, ConnData, [[Pretty, "\n"], Contents]);
Trans when is_record(Trans, 'TransactionPending') ->
- Pretty = pretty({trans, {transactionPending, Trans}}),
- filter_contents([], E, [[Pretty, "\n"], Contents]);
+ Pretty = pretty(ConnData, {trans, {transactionPending, Trans}}),
+ do_filter_contents([], E, ConnData, [[Pretty, "\n"], Contents]);
Trans when is_record(Trans, 'TransactionAck') ->
- Pretty = pretty({trans, {transactionResponseAck, [Trans]}}),
+ Pretty = pretty(ConnData, {trans, {transactionResponseAck, [Trans]}}),
case Trans#'TransactionAck'.lastAck of
asn1_NOVALUE ->
- filter_contents([], E, [[Pretty, "\n"], Contents]);
+ do_filter_contents([], E, ConnData, [[Pretty, "\n"], Contents]);
Last ->
Label = term_to_string(E#event.label),
E2 = E#event{label = Label ++ ".." ++ integer_to_list(Last)},
- filter_contents([], E2, [[Pretty, "\n"], Contents])
+ do_filter_contents([], E2, ConnData, [[Pretty, "\n"], Contents])
end;
{context_id, _ContextId} ->
- Pretty = pretty(H),
- filter_contents(T, E, [[Pretty, "\n"], Contents]);
+ Pretty = pretty(ConnData, H),
+ do_filter_contents(T, E, ConnData, [[Pretty, "\n"], Contents]);
{command_request, CmdReq} ->
- Pretty = pretty(CmdReq),
- filter_contents(T, E, [[Pretty, "\n"], Contents]);
+ Pretty = pretty(ConnData, CmdReq),
+ do_filter_contents(T, E, ConnData, [[Pretty, "\n"], Contents]);
{user_reply, {ok, ARS}} ->
- Pretty = [[pretty(AR), "\n"] || AR <- ARS],
- filter_contents(T, E, [["REPLY: \n", Pretty, "\n"], Contents]);
+ Pretty = [[pretty(ConnData, AR), "\n"] || AR <- ARS],
+ do_filter_contents(T, E, ConnData, [["USER REPLY OK: \n", Pretty, "\n"], Contents]);
{user_reply, Error} ->
Pretty = pretty_error(Error),
- filter_contents(T, E, [["REPLY: \n", Pretty, "\n"], Contents]);
+ do_filter_contents(T, E, ConnData, [["USER REPLY ERROR: \n", Pretty, "\n"], Contents]);
{actionReplies, ARS} ->
- Pretty = [[pretty(AR), "\n"] || AR <- ARS],
- filter_contents(T, E, [["REPLY: \n", Pretty, "\n"], Contents]);
+ Pretty = [[pretty(ConnData, AR), "\n"] || AR <- ARS],
+ do_filter_contents(T, E, ConnData, [["ACTION REPLIES: \n", Pretty, "\n"], Contents]);
MegaMsg when is_record(MegaMsg, 'MegacoMessage') ->
- Pretty = pretty(MegaMsg),
- filter_contents(T, E, [["MESSAGE: \n", Pretty, "\n"], Contents]);
+ Pretty = pretty(ConnData, MegaMsg),
+ do_filter_contents(T, E, ConnData, [Pretty, "\n", Contents]);
+ {message, MegaMsg} when is_record(MegaMsg, 'MegacoMessage') ->
+ Pretty = pretty(ConnData, MegaMsg),
+ do_filter_contents(T, E, ConnData, [Pretty, "\n", Contents]);
{bytes, Bin} when is_binary(Bin) ->
E2 =
case E#event.label of
@@ -223,15 +303,37 @@ filter_contents([H | T], E, Contents) ->
E
end,
CharList = erlang:binary_to_list(Bin),
- filter_contents(T, E2, [[CharList , "\n"], Contents]);
- [] ->
- filter_contents(T, E, Contents);
+ do_filter_contents(T, E2, ConnData, [[CharList , "\n"], Contents]);
+ List when is_list(List) ->
+ %% BUGBUG: Workaround as megaco_messenger puts nested lists in its traces
+ do_filter_contents(List ++ T, E, ConnData, Contents);
+ Int when is_integer(Int) ->
+ %% BUGBUG: Workaround as megaco_messenger puts nested lists in its traces
+ do_filter_contents(T, E, ConnData, Contents);
+ {line, _Mod, _Line} ->
+ do_filter_contents(T, E, ConnData, Contents);
+ {orig_conn_handle, _CH} ->
+ do_filter_contents(T, E, ConnData, Contents);
+ {pid, Pid} when is_pid(Pid) ->
+ do_filter_contents(T, E, ConnData, Contents);
+ pending ->
+ do_filter_contents(T, E, ConnData, Contents);
+ reply ->
+ do_filter_contents(T, E, ConnData, Contents);
{test_lib, _Mod, _Fun} ->
- filter_contents(T, E, Contents);
+ do_filter_contents(T, E, ConnData, Contents);
+ {trans_id, _TransId} ->
+ do_filter_contents(T, E, ConnData, Contents);
+ {send_func, _FunName} ->
+ do_filter_contents(T, E, ConnData, Contents);
+ Pid when is_pid(Pid) ->
+ do_filter_contents(T, E, ConnData, Contents);
Other ->
- Pretty = pretty(Other),
- filter_contents(T, E, [[Pretty, "\n"], Contents])
- end.
+ Pretty = pretty(ConnData, Other),
+ do_filter_contents(T, E, ConnData, [[Pretty, "\n"], Contents])
+ end;
+do_filter_contents([], E, _ConnData, Contents) ->
+ E#event{contents = lists:flatten(lists:reverse(Contents))}.
append_serial(Serial, E) when is_integer(Serial) ->
Label = term_to_string(E#event.label),
@@ -243,7 +345,7 @@ prepend_error(E) ->
Label = term_to_string(E#event.label),
E#event{label = "<ERROR> " ++ Label}.
-pretty({context_id, ContextId}) ->
+pretty(_ConnData, {context_id, ContextId}) ->
if
ContextId =:= ?megaco_null_context_id ->
["CONTEXT ID: -\n"];
@@ -254,61 +356,33 @@ pretty({context_id, ContextId}) ->
is_integer(ContextId) ->
["CONTEXT ID: ",integer_to_list(ContextId), "\n"]
end;
-pretty(MegaMsg) when is_record(MegaMsg, 'MegacoMessage') ->
- case catch megaco_pretty_text_encoder:encode_message([], MegaMsg) of
- {ok, Bin} ->
- term_to_string(Bin);
- _Bad ->
- term_to_string(MegaMsg)
- end;
-pretty(CmdReq) when is_record(CmdReq, 'CommandRequest') ->
- case catch megaco_pretty_text_encoder:encode_command_request(CmdReq) of
- {ok, IoList} ->
- IoList2 = lists:flatten(IoList),
- term_to_string(IoList2);
- _Bad ->
- term_to_string(CmdReq)
- end;
-pretty({complete_success, ContextId, RepList} = Res) ->
+pretty(_ConnData, MegaMsg) when is_record(MegaMsg, 'MegacoMessage') ->
+ {ok, Bin} = megaco_pretty_text_encoder:encode_message([], MegaMsg),
+ term_to_string(Bin);
+pretty(_ConnData, CmdReq) when is_record(CmdReq, 'CommandRequest') ->
+ {ok, IoList} = megaco_pretty_text_encoder:encode_command_request(CmdReq),
+ term_to_string(lists:flatten(IoList));
+pretty(_ConnData, {complete_success, ContextId, RepList}) ->
ActRep = #'ActionReply'{contextId = ContextId,
commandReply = RepList},
- case catch megaco_pretty_text_encoder:encode_action_reply(ActRep) of
- {ok, IoList} ->
- IoList2 = lists:flatten(IoList),
- term_to_string(IoList2);
- _Bad ->
- term_to_string(Res)
- end;
-pretty(AR) when is_record(AR, 'ActionReply') ->
- case catch megaco_pretty_text_encoder:encode_action_reply(AR) of
- {ok, IoList} ->
- IoList2 = lists:flatten(IoList),
- term_to_string(IoList2);
- _Bad ->
- term_to_string(AR)
- end;
-pretty({partial_failure, ContextId, RepList} = Res) ->
+ {ok, IoList} = megaco_pretty_text_encoder:encode_action_reply(ActRep),
+ term_to_string(lists:flatten(IoList));
+pretty(_ConnData, AR) when is_record(AR, 'ActionReply') ->
+ {ok, IoList} = megaco_pretty_text_encoder:encode_action_reply(AR),
+ term_to_string(lists:flatten(IoList));
+pretty(_ConnData, {partial_failure, ContextId, RepList}) ->
ActRep = #'ActionReply'{contextId = ContextId,
commandReply = RepList},
- case catch megaco_pretty_text_encoder:encode_action_reply(ActRep) of
- {ok, IoList} ->
- IoList2 = lists:flatten(IoList),
- term_to_string(IoList2);
- _Bad ->
- term_to_string(Res)
- end;
-pretty({trans, Trans}) ->
- case catch megaco_pretty_text_encoder:encode_transaction(Trans) of
+ {ok, IoList} = megaco_pretty_text_encoder:encode_action_reply(ActRep),
+ term_to_string(lists:flatten(IoList));
+pretty(_ConnData, {trans, Trans}) ->
+ case megaco_pretty_text_encoder:encode_transaction(Trans) of
{ok, Bin} when is_binary(Bin) ->
- IoList2 = lists:flatten(binary_to_list(Bin)),
- term_to_string(IoList2);
+ term_to_string(binary_to_list(Bin));
{ok, IoList} ->
- IoList2 = lists:flatten(IoList),
- term_to_string(IoList2);
- _Bad ->
- term_to_string(Trans)
+ term_to_string(lists:flatten(IoList))
end;
-pretty(Other) ->
+pretty(__ConnData, Other) ->
term_to_string(Other).
pretty_error({error, Reason}) ->
diff --git a/lib/megaco/src/engine/megaco_messenger.erl b/lib/megaco/src/engine/megaco_messenger.erl
index a9e4fd67b2..5fad29931b 100644
--- a/lib/megaco/src/engine/megaco_messenger.erl
+++ b/lib/megaco/src/engine/megaco_messenger.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 1999-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 1999-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,20 +99,22 @@
%% N.B. Update cancel/1 with '_' when a new field is added
-record(reply,
{
- trans_id,
- local_mid,
- state = prepare, % prepare | eval_request | waiting_for_ack | aborted
- pending_timer_ref,
- handler = undefined, % pid of the proc executing the callback func
- timer_ref,
- version,
- %% bytes: Sent reply data: not acknowledged
- bytes, % binary() | [{integer(), binary(), timer_ref()}]
- ack_action, % discard_ack | {handle_ack, Data}
- send_handle,
- %% segments: Not sent reply data (segments)
- segments = [] % [{integer(), binary()}]
- }).
+ trans_id,
+ local_mid,
+ state = prepare, % prepare | eval_request | waiting_for_ack | aborted
+ pending_timer_ref,
+ handler = undefined, % pid of the proc executing the callback func
+ timer_ref,
+ version,
+ %% bytes: Sent reply data: not acknowledged
+ bytes, % binary() | [{integer(), binary(), timer_ref()}]
+ ack_action, % discard_ack | {handle_ack, Data}
+ send_handle,
+ %% segments: Not sent reply data (segments)
+ segments = [], % [{integer(), binary()}]
+ user_mod,
+ user_args
+ }).
-record(trans_id,
{
@@ -1203,7 +1205,7 @@ prepare_request(ConnData, T, Rest, AckList, ReqList, Extra) ->
LocalMid = ConnHandle#megaco_conn_handle.local_mid,
TransId = to_remote_trans_id(ConnData),
?rt2("prepare request", [LocalMid, TransId]),
- case megaco_monitor:lookup_reply(TransId) of
+ case lookup_reply(ConnData, TransId) of
[] ->
?rt3("brand new request"),
@@ -1222,18 +1224,22 @@ prepare_request(ConnData, T, Rest, AckList, ReqList, Extra) ->
#conn_data{send_handle = SendHandle,
pending_timer = InitTimer,
- protocol_version = Version} = ConnData,
+ protocol_version = Version,
+ user_mod = UserMod,
+ user_args = UserArgs} = ConnData,
{WaitFor, CurrTimer} = megaco_timer:init(InitTimer),
M = ?MODULE,
F = pending_timeout,
- A = [ConnHandle, TransId, CurrTimer],
+ A = [ConnHandle, TransId, CurrTimer],
PendingRef = megaco_monitor:apply_after(M, F, A, WaitFor),
Rep = #reply{send_handle = SendHandle,
trans_id = TransId,
local_mid = LocalMid,
pending_timer_ref = PendingRef,
handler = self(),
- version = Version},
+ version = Version,
+ user_mod = UserMod,
+ user_args = UserArgs},
case megaco_monitor:insert_reply_new(Rep) of
true ->
prepare_normal_trans(ConnData, Rest, AckList,
@@ -1250,9 +1256,14 @@ prepare_request(ConnData, T, Rest, AckList, ReqList, Extra) ->
Extra)
end;
- [#reply{state = State,
+ %% We can ignore the Converted value here as we *know*
+ %% conn-data to be correct (not faked), so even if
+ %% the record was converted, it will now have correct
+ %% values for user_mod and user_args.
+ {_Converted,
+ #reply{state = State,
handler = Pid,
- pending_timer_ref = Ref} = Rep]
+ pending_timer_ref = Ref} = Rep}
when (State =:= prepare) orelse (State =:= eval_request) ->
?rt2("request resend", [State, Pid, Ref]),
@@ -1364,9 +1375,14 @@ prepare_request(ConnData, T, Rest, AckList, ReqList, Extra) ->
end;
- [#reply{state = waiting_for_ack,
+ %% We can ignore the Converted value here as we *know*
+ %% conn-data to be correct (not faked), so even if
+ %% the record was converted, it will now have correct
+ %% values for user_mod and user_args.
+ {_Converted,
+ #reply{state = waiting_for_ack,
bytes = Bin,
- version = Version} = Rep] ->
+ version = Version} = Rep} ->
?rt3("request resend when waiting for ack"),
%% We have already sent a reply, but the receiver
@@ -1384,7 +1400,13 @@ prepare_request(ConnData, T, Rest, AckList, ReqList, Extra) ->
end,
prepare_normal_trans(ConnData2, Rest, AckList, ReqList, Extra);
- [#reply{state = aborted} = Rep] ->
+
+ %% We can ignore the Converted value here as we *know*
+ %% conn-data to be correct (not faked), so even if
+ %% the record was converted, it will now have correct
+ %% values for user_mod and user_args.
+ {_Converted,
+ #reply{state = aborted} = Rep} ->
?rt3("request resend when already in aborted state"),
%% OTP-4956:
@@ -1424,15 +1446,15 @@ prepare_ack(ConnData, [], Rest, AckList, ReqList, Extra) ->
do_prepare_ack(ConnData, T, AckList) ->
TransId = to_remote_trans_id(ConnData),
- case megaco_monitor:lookup_reply(TransId) of
+ case lookup_reply(ConnData, TransId) of
[] ->
%% The reply has already been garbage collected. Ignore.
?report_trace(ConnData, "discard ack (no receiver)", [T]),
AckList;
- [Rep] when Rep#reply.state =:= waiting_for_ack ->
+ {_Converted, Rep} when Rep#reply.state =:= waiting_for_ack ->
%% Don't care about Msg and Rep version diff
[{ConnData, Rep, T} | AckList];
- [_Rep] ->
+ {_Converted, _Rep} ->
%% Protocol violation from the sender of this ack
?report_important(ConnData, "<ERROR> discard trans",
[T, {error, "got ack before reply was sent"}]),
@@ -1519,30 +1541,6 @@ check_pending_limit(Limit, Direction, TransId) ->
aborted
end.
-%% check_pending_limit(infinity, _, _) ->
-%% {ok, 0};
-%% check_pending_limit(Limit, Direction, TransId) ->
-%% ?rt2("check pending limit", [Direction, Limit, TransId]),
-%% case (catch megaco_config:get_pending_counter(Direction, TransId)) of
-%% {'EXIT', _} ->
-%% %% This function is only called when we "know" the
-%% %% counter to exist. So, the only reason that this
-%% %% would happen is of the counter has been removed.
-%% %% This only happen if the pending limit has been
-%% %% reached. In any case, this is basically the same
-%% %% as aborted!
-%% ?rt2("check pending limit - exit", []),
-%% aborted;
-%% Val when Val =< Limit ->
-%% %% Since we have no intention to increment here, it
-%% %% is ok to be _at_ the limit
-%% ?rt2("check pending limit - ok", [Val]),
-%% {ok, Val};
-%% _Val ->
-%% ?rt2("check pending limit - aborted", [_Val]),
-%% aborted
-%% end.
-
check_and_maybe_incr_pending_limit(infinity, _, _) ->
ok;
@@ -1550,59 +1548,42 @@ check_and_maybe_incr_pending_limit(Limit, Direction, TransId) ->
%%
%% We need this kind of test to detect when we _pass_ the limit
%%
- ?rt2("check and maybe incr pending limit", [Direction, Limit, TransId]),
+ ?rt2("check and maybe incr pending limit", [{direction, Direction},
+ {transaction_id, TransId},
+ {counter_limit, Limit}]),
try megaco_config:get_pending_counter(Direction, TransId) of
Val when Val > Limit ->
- ?rt2("check and maybe incr - aborted", [Direction, Val, Limit]),
+ ?rt2("check and maybe incr - aborted", [{counter_value, Val}]),
aborted; % Already passed the limit
Val ->
- ?rt2("check and maybe incr - incr", [Direction, Val, Limit]),
+ ?rt2("check and maybe incr - incr", [{counter_value, Val}]),
megaco_config:incr_pending_counter(Direction, TransId),
if
Val < Limit ->
ok; % Still within the limit
true ->
?rt2("check and maybe incr - error",
- [Direction, Val, Limit]),
+ [{counter_value, Val}]),
error % Passed the limit
end
catch
_:_ ->
%% Has not been created yet (connect).
- megaco_config:cre_pending_counter(Direction, TransId, 1),
- ok
+ %% Try create it, but bevare of possible raise condition
+ try
+ begin
+ megaco_config:cre_pending_counter(Direction, TransId, 1),
+ ok
+ end
+ catch
+ _:_ ->
+ %% Ouch, raise condition, increment instead...
+ megaco_config:incr_pending_counter(Direction, TransId),
+ ok
+ end
end.
-%% check_and_maybe_incr_pending_limit(infinity, _, _) ->
-%% ok;
-%% check_and_maybe_incr_pending_limit(Limit, Direction, TransId) ->
-%% %%
-%% %% We need this kind of test to detect when we _pass_ the limit
-%% %%
-%% ?rt2("check and maybe incr pending limit", [Direction, Limit, TransId]),
-%% case (catch megaco_config:get_pending_counter(Direction, TransId)) of
-%% {'EXIT', _} ->
-%% %% Has not been created yet (connect).
-%% megaco_config:cre_pending_counter(Direction, TransId, 1),
-%% ok;
-%% Val when Val > Limit ->
-%% ?rt2("check and maybe incr - aborted", [Direction, Val, Limit]),
-%% aborted; % Already passed the limit
-%% Val ->
-%% ?rt2("check and maybe incr - incr", [Direction, Val, Limit]),
-%% megaco_config:incr_pending_counter(Direction, TransId),
-%% if
-%% Val < Limit ->
-%% ok; % Still within the limit
-%% true ->
-%% ?rt2("check and maybe incr - error",
-%% [Direction, Val, Limit]),
-%% error % Passed the limit
-%% end
-%% end.
-
-
%% BUGBUG BUGBUG BUGBUG
%%
%% Do we know that the Rep is still valid? A previous transaction
@@ -1657,8 +1638,8 @@ handle_request(ConnData, TransId, T, Extra) ->
%% Furthermore, the reply timer has not been started,
%% so do the cleanup now
?rt1(ConnData, "pending limit already passed", [TransId]),
- case megaco_monitor:lookup_reply(TransId) of
- [Rep] ->
+ case lookup_reply(ConnData, TransId) of
+ {_Converted, Rep} ->
cancel_reply(ConnData, Rep, aborted);
_ ->
ok
@@ -1671,8 +1652,8 @@ do_handle_request(_, ignore, _ConnData, _TransId) ->
ignore;
do_handle_request(_, ignore_trans_request, ConnData, TransId) ->
?rt1(ConnData, "ignore trans request: don't reply", [TransId]),
- case megaco_monitor:lookup_reply(TransId) of
- [#reply{} = Rep] ->
+ case lookup_reply(ConnData, TransId) of
+ {_Converted, #reply{} = Rep} ->
cancel_reply(ConnData, Rep, ignore);
_ ->
ignore
@@ -1689,8 +1670,8 @@ do_handle_request({pending, RequestData}, _SendReply, _ConnData, _) ->
do_handle_request(AckAction, {ok, Bin}, ConnData, TransId)
when is_binary(Bin) ->
?rt1(ConnData, "handle request - ok", [AckAction, TransId]),
- case megaco_monitor:lookup_reply(TransId) of
- [#reply{pending_timer_ref = PendingRef} = Rep] ->
+ case lookup_reply(ConnData, TransId) of
+ {_Converted, #reply{pending_timer_ref = PendingRef} = Rep} ->
#conn_data{reply_timer = InitTimer,
conn_handle = ConnHandle} = ConnData,
@@ -1729,8 +1710,8 @@ do_handle_request(AckAction, {ok, {Sent, NotSent}}, ConnData, TransId)
?rt1(ConnData, "handle request - ok [segmented reply]",
[AckAction, TransId]),
- case megaco_monitor:lookup_reply(TransId) of
- [#reply{pending_timer_ref = PendingRef} = Rep] ->
+ case lookup_reply(ConnData, TransId) of
+ {_Converted, #reply{pending_timer_ref = PendingRef} = Rep} ->
%% d("do_handle_request -> found reply record:"
%% "~n Rep: ~p", [Rep]),
@@ -1772,8 +1753,8 @@ do_handle_request(AckAction, {ok, {Sent, NotSent}}, ConnData, TransId)
end;
do_handle_request(_, {error, aborted}, ConnData, TransId) ->
?report_trace(ConnData, "aborted during our absence", [TransId]),
- case megaco_monitor:lookup_reply(TransId) of
- [Rep] ->
+ case lookup_reply(ConnData, TransId) of
+ {_Converted, Rep} ->
cancel_reply(ConnData, Rep, aborted);
_ ->
ok
@@ -1781,8 +1762,8 @@ do_handle_request(_, {error, aborted}, ConnData, TransId) ->
ignore;
do_handle_request(AckAction, {error, Reason}, ConnData, TransId) ->
?report_trace(ConnData, "error", [TransId, Reason]),
- case megaco_monitor:lookup_reply(TransId) of
- [Rep] ->
+ case lookup_reply(ConnData, TransId) of
+ {_Converted, Rep} ->
Rep2 = Rep#reply{state = waiting_for_ack,
ack_action = AckAction},
cancel_reply(ConnData, Rep2, Reason);
@@ -2626,33 +2607,84 @@ handle_reply(
handle_reply(#conn_data{conn_handle = CH} = CD, T, Extra) ->
TransId = to_local_trans_id(CD),
?rt2("handle reply", [T, TransId]),
- case megaco_monitor:lookup_request(TransId) of
- [Req] when (is_record(Req, request) andalso
- (CD#conn_data.cancel =:= true)) ->
+ case {megaco_monitor:request_lockcnt_inc(TransId),
+ megaco_monitor:lookup_request(TransId)} of
+ {_Cnt, [Req]} when (is_record(Req, request) andalso
+ (CD#conn_data.cancel =:= true)) ->
?TC_AWAIT_REPLY_EVENT(true),
+ ?report_trace(CD, "trans reply - cancel(1)", [T]),
do_handle_reply_cancel(CD, Req, T);
- [#request{remote_mid = RMid} = Req] when ((RMid =:= preliminary_mid) orelse
- (RMid =:= CH#megaco_conn_handle.remote_mid)) ->
+ {Cnt, [#request{remote_mid = RMid} = Req]} when
+ ((Cnt =:= 1) andalso
+ ((RMid =:= preliminary_mid) orelse
+ (RMid =:= CH#megaco_conn_handle.remote_mid))) ->
?TC_AWAIT_REPLY_EVENT(false),
%% Just in case conn_data got update after our lookup
%% but before we looked up the request record, we
%% check the cancel field again.
case megaco_config:conn_info(CD, cancel) of
true ->
+ ?report_trace(CD, "trans reply - cancel(2)", [T]),
+ megaco_monitor:request_lockcnt_del(TransId),
do_handle_reply_cancel(CD, Req, T);
false ->
+ ?report_trace(CD, "trans reply", [T]),
do_handle_reply(CD, Req, TransId, T, Extra)
end;
- [#request{user_mod = UserMod,
- user_args = UserArgs,
- reply_action = Action,
- reply_data = UserData,
- remote_mid = RMid}] ->
+ {Cnt, [#request{remote_mid = RMid} = _Req]} when
+ (is_integer(Cnt) andalso
+ ((RMid =:= preliminary_mid) orelse
+ (RMid =:= CH#megaco_conn_handle.remote_mid))) ->
+ ?TC_AWAIT_REPLY_EVENT(false),
+ %% Ok, someone got there before me, now what?
+ %% This is a plain old raise condition
+ ?report_important(CD, "trans reply - raise condition",
+ [T, {request_lockcnt, Cnt}]),
+ megaco_monitor:request_lockcnt_dec(TransId);
+
+ %% no counter
+ {_Cnt, [#request{remote_mid = RMid} = Req]} when
+ ((RMid =:= preliminary_mid) orelse
+ (RMid =:= CH#megaco_conn_handle.remote_mid)) ->
+ ?TC_AWAIT_REPLY_EVENT(false),
+ %% The counter does not exist.
+ %% This can only mean a code upgrade raise condition.
+ %% That is, this request record was created before
+ %% this feature (the counters) was instroduced.
+ %% The simples solution is this is to behave exactly as
+ %% before, that is pass it along, and leave it to the
+ %% user to figure out.
+
+ %% Just in case conn_data got update after our lookup
+ %% but before we looked up the request record, we
+ %% check the cancel field again.
+ ?report_verbose(CD, "trans reply - old style", [T]),
+ case megaco_config:conn_info(CD, cancel) of
+ true ->
+ megaco_monitor:request_lockcnt_del(TransId),
+ do_handle_reply_cancel(CD, Req, T);
+ false ->
+ do_handle_reply(CD, Req, TransId, T, Extra)
+ end;
+
+ {Cnt, [#request{user_mod = UserMod,
+ user_args = UserArgs,
+ reply_action = Action,
+ reply_data = UserData,
+ remote_mid = RMid}]} ->
?report_trace(CD,
"received trans reply with invalid remote mid",
- [T, RMid]),
+ [{transaction, T},
+ {remote_mid, RMid},
+ {request_lockcnt, Cnt}]),
+ if
+ is_integer(Cnt) ->
+ megaco_monitor:request_lockcnt_dec(TransId);
+ true ->
+ ok
+ end,
WrongMid = CH#megaco_conn_handle.remote_mid,
T2 = transform_transaction_reply_enc(CD#conn_data.protocol_version,
T),
@@ -2663,7 +2695,15 @@ handle_reply(#conn_data{conn_handle = CH} = CD, T, Extra) ->
reply_data = UserData},
return_reply(CD2, TransId, UserReply, Extra);
- [] ->
+ {Cnt, []} when is_integer(Cnt) ->
+ ?TC_AWAIT_REPLY_EVENT(undefined),
+ ?report_trace(CD, "trans reply (no receiver)",
+ [T, {request_lockcnt, Cnt}]),
+ megaco_monitor:request_lockcnt_dec(TransId),
+ return_unexpected_trans(CD, T, Extra);
+
+ %% No counter
+ {_Cnt, []} ->
?TC_AWAIT_REPLY_EVENT(undefined),
?report_trace(CD, "trans reply (no receiver)", [T]),
return_unexpected_trans(CD, T, Extra)
@@ -2694,6 +2734,7 @@ do_handle_reply(CD,
%% This is the first reply (maybe of many)
megaco_monitor:delete_request(TransId),
+ megaco_monitor:request_lockcnt_del(TransId),
megaco_monitor:cancel_apply_after(Ref), % OTP-4843
megaco_config:del_pending_counter(recv, TransId), % OTP-7189
@@ -2819,9 +2860,10 @@ handle_segment_reply(CD,
{segment_no, SN},
{segmentation_complete, SC}]),
TransId2 = to_remote_trans_id(CD#conn_data{serial = TransId}),
- case megaco_monitor:lookup_reply(TransId2) of
- [#reply{bytes = Sent,
- segments = []} = Rep] when is_list(Sent) ->
+ case lookup_reply(CD, TransId2) of
+ {_Converted,
+ #reply{bytes = Sent,
+ segments = []} = Rep} when is_list(Sent) ->
?rt2("no unsent segments", [Sent]),
handle_segment_reply_callback(CD, TransId, SN, SC, Extra),
case lists:keysearch(SN, 1, Sent) of
@@ -2845,8 +2887,9 @@ handle_segment_reply(CD,
ok
end;
- [#reply{bytes = Sent,
- segments = NotSent}] when is_list(Sent) andalso
+ {_Converted,
+ #reply{bytes = Sent,
+ segments = NotSent}} when is_list(Sent) andalso
is_list(NotSent) ->
?rt2("unsent segments", [Sent, NotSent]),
handle_segment_reply_callback(CD, TransId, SN, SC, Extra),
@@ -2883,7 +2926,8 @@ handle_segment_reply(CD,
ok
end;
- [#reply{state = State}] ->
+ {_Converted,
+ #reply{state = State}} ->
%% We received a segment reply for a segmented reply we have
%% not yet sent? This is either some sort of race condition
%% or the "the other side" is really confused.
@@ -3012,7 +3056,7 @@ handle_ack_callback(ConnData, AckStatus, {handle_ack, AckData}, T, Extra) ->
_ ->
[ConnHandle, Version, AckStatus, AckData, Extra | UserArgs]
end,
- Res = (catch apply(UserMod, handle_trans_ack, Args)),
+ Res = (catch handle_callback(ConnData, UserMod, handle_trans_ack, Args)),
?report_debug(ConnData, "return: trans ack", [T, AckData, {return, Res}]),
case Res of
ok ->
@@ -3024,6 +3068,14 @@ handle_ack_callback(ConnData, AckStatus, {handle_ack, AckData}, T, Extra) ->
Res.
+handle_callback(ConnData, undefined = _UserMod, Func, Args) ->
+ ?report_important(ConnData, "callback: unknown callback module",
+ [{func, Func}, {args, Args}]),
+ ok;
+handle_callback(_ConnData, UserMod, Func, Args) ->
+ (catch apply(UserMod, Func, Args)).
+
+
handle_message_error(ConnData, _Error, _Extra)
when ConnData#conn_data.monitor_ref == undefined_monitor_ref ->
%% May occur if another process already has setup a
@@ -3706,6 +3758,11 @@ insert_requests(ConnData, ConnHandle,
insert_request(ConnData, ConnHandle, TransId,
Action, Data, InitTimer, LongTimer) ->
+ %% We dont check the result of the lock-counter creation because
+ %% the only way it could already exist is if the transaction-id
+ %% range has wrapped and an old counter was not deleted.
+ megaco_monitor:request_lockcnt_cre(TransId),
+
#megaco_conn_handle{remote_mid = RemoteMid} = ConnHandle,
#conn_data{protocol_version = Version,
user_mod = UserMod,
@@ -4290,6 +4347,7 @@ cancel_request(ConnData, Req, Reason) ->
cancel_request2(ConnData, TransId, UserReply) ->
megaco_monitor:delete_request(TransId),
+ megaco_monitor:request_lockcnt_del(TransId),
megaco_config:del_pending_counter(recv, TransId), % OTP-7189
Serial = TransId#trans_id.serial,
ConnData2 = ConnData#conn_data{serial = Serial},
@@ -4347,34 +4405,76 @@ receive_reply_remote(ConnData, UserReply) ->
receive_reply_remote(ConnData, UserReply, Extra) ->
TransId = to_local_trans_id(ConnData),
- case (catch megaco_monitor:lookup_request(TransId)) of
- [#request{timer_ref = {_Type, Ref}} = Req] -> %% OTP-4843
+ case {megaco_monitor:request_lockcnt_inc(TransId),
+ (catch megaco_monitor:lookup_request(TransId))} of
+ {Cnt, [Req]} when (Cnt =:= 1) andalso is_record(Req, request) ->
%% Don't care about Req and Rep version diff
- megaco_monitor:delete_request(TransId),
- megaco_monitor:cancel_apply_after(Ref), % OTP-4843
- megaco_config:del_pending_counter(recv, TransId), % OTP-7189
-
- UserMod = Req#request.user_mod,
- UserArgs = Req#request.user_args,
- Action = Req#request.reply_action,
- UserData = Req#request.reply_data,
- ConnData2 = ConnData#conn_data{user_mod = UserMod,
- user_args = UserArgs,
- reply_action = Action,
- reply_data = UserData},
- return_reply(ConnData2, TransId, UserReply, Extra);
-
+ do_receive_reply_remote(ConnData, TransId, Req, UserReply, Extra);
+
+ {Cnt, [Req]} when is_integer(Cnt) andalso is_record(Req, request) ->
+ %% Another process is accessing, handle as unexpected
+ %% (so it has a possibillity to get logged).
+ ?report_important(ConnData, "trans reply (no receiver)",
+ [{user_reply, UserReply},
+ {request_lockcnt, Cnt}]),
+ megaco_monitor:request_lockcnt_dec(TransId),
+ return_unexpected_trans_reply(ConnData, TransId, UserReply, Extra);
+
+ %% no counter
+ {_Cnt, [Req]} when is_record(Req, request) ->
+ %% The counter does not exist.
+ %% This can only mean a code upgrade raise condition.
+ %% That is, this request record was created before
+ %% this feature (the counters) was instroduced.
+ %% The simples solution to this is to behave exactly as
+ %% before, that is, pass it along, and leave it to the
+ %% user to figure out.
+ ?report_trace(ConnData,
+ "remote reply - "
+ "code upgrade raise condition",
+ [{user_reply, UserReply}]),
+ do_receive_reply_remote(ConnData, TransId, Req, UserReply, Extra);
+
+ {Cnt, _} when is_integer(Cnt) ->
+ ?report_trace(ConnData, "trans reply (no receiver)",
+ [{user_reply, UserReply}, {request_lockcnt, Cnt}]),
+ megaco_monitor:request_lockcnt_dec(TransId),
+ return_unexpected_trans_reply(ConnData, TransId, UserReply, Extra);
+
_ ->
?report_trace(ConnData, "remote reply (no receiver)",
- [UserReply]),
+ [{user_reply, UserReply}]),
return_unexpected_trans_reply(ConnData, TransId, UserReply, Extra)
end.
-cancel_reply(ConnData, #reply{state = waiting_for_ack} = Rep, Reason) ->
+do_receive_reply_remote(ConnData, TransId,
+ #request{timer_ref = {_Type, Ref},
+ user_mod = UserMod,
+ user_args = UserArgs,
+ reply_action = Action,
+ reply_data = UserData} = _Req,
+ UserReply, Extra) ->
+ megaco_monitor:delete_request(TransId),
+ megaco_monitor:request_lockcnt_del(TransId),
+ megaco_monitor:cancel_apply_after(Ref), % OTP-4843
+ megaco_config:del_pending_counter(recv, TransId), % OTP-7189
+
+ ConnData2 = ConnData#conn_data{user_mod = UserMod,
+ user_args = UserArgs,
+ reply_action = Action,
+ reply_data = UserData},
+ return_reply(ConnData2, TransId, UserReply, Extra).
+
+
+cancel_reply(ConnData, #reply{state = waiting_for_ack,
+ user_mod = UserMod,
+ user_args = UserArgs} = Rep, Reason) ->
?report_trace(ignore, "cancel reply [waiting_for_ack]", [Rep]),
megaco_monitor:cancel_apply_after(Rep#reply.pending_timer_ref),
Serial = (Rep#reply.trans_id)#trans_id.serial,
- ConnData2 = ConnData#conn_data{serial = Serial},
+ ConnData2 = ConnData#conn_data{serial = Serial,
+ user_mod = UserMod,
+ user_args = UserArgs},
T = #'TransactionAck'{firstAck = Serial},
Extra = ?default_user_callback_extra,
handle_ack(ConnData2, {error, Reason}, Rep, T, Extra);
@@ -4558,16 +4658,30 @@ reply_timeout(ConnHandle, TransId, {_, timeout}) ->
reply_timeout(ConnHandle, TransId, Timer) ->
?report_trace(ConnHandle, "reply timeout", [Timer, TransId]),
- case megaco_monitor:lookup_reply(TransId) of
+ case lookup_reply(undefined, TransId) of
[] ->
reply_not_found_ignore;
- [#reply{state = waiting_for_ack,
- ack_action = {handle_ack, _}} = Rep] ->
+ {Converted,
+ #reply{state = waiting_for_ack,
+ ack_action = {handle_ack, _}} = Rep} ->
case megaco_config:lookup_local_conn(ConnHandle) of
[CD] when (CD#conn_data.cancel =:= true) ->
cancel_in_progress_ignore;
- [CD] ->
+ [CD] when (Converted =:= true) ->
+ incNumTimerRecovery(ConnHandle),
+ %% When we did the reply record lookup, we had no
+ %% conn_data record, and the reply record was
+ %% converted. This means that the reply record
+ %% has no valid info about user_mod or user_args.
+ %% Therefor, the user_mod and user_args of the
+ %% conn_data record is better then nothing.
+ #conn_data{user_mod = UserMod,
+ user_args = UserArgs} = CD,
+ Rep2 = Rep#reply{user_mod = UserMod,
+ user_args = UserArgs},
+ do_reply_timeout(ConnHandle, TransId, CD, Timer, Rep2);
+ [CD] when (Converted =:= false) ->
incNumTimerRecovery(ConnHandle),
do_reply_timeout(ConnHandle, TransId, CD, Timer, Rep);
[] ->
@@ -4576,10 +4690,25 @@ reply_timeout(ConnHandle, TransId, Timer) ->
do_reply_timeout(ConnHandle, TransId, CD, Timer, Rep)
end;
- [#reply{state = waiting_for_ack,
- bytes = Sent} = Rep] when is_list(Sent) ->
+ {Converted,
+ #reply{state = waiting_for_ack,
+ bytes = Sent} = Rep} when is_list(Sent) ->
case megaco_config:lookup_local_conn(ConnHandle) of
- [ConnData] ->
+ [ConnData] when (Converted =:= true) ->
+ incNumTimerRecovery(ConnHandle),
+ %% When we did the reply record lookup, we had no
+ %% conn_data record, and the reply record was
+ %% converted. This means that the reply record
+ %% has no valid info about user_mod or user_args.
+ %% Therefor, the user_mod and user_args of the
+ %% conn_data record is better then nothing.
+ #conn_data{user_mod = UserMod,
+ user_args = UserArgs} = ConnData,
+ Rep2 = Rep#reply{user_mod = UserMod,
+ user_args = UserArgs},
+ do_reply_timeout(ConnHandle, TransId, ConnData,
+ Timer, Rep2);
+ [ConnData] when (Converted =:= false) ->
incNumTimerRecovery(ConnHandle),
do_reply_timeout(ConnHandle, TransId, ConnData,
Timer, Rep);
@@ -4590,10 +4719,12 @@ reply_timeout(ConnHandle, TransId, Timer) ->
Timer, Rep)
end;
- [#reply{state = waiting_for_ack} = Rep] ->
+ {_Converted,
+ #reply{state = waiting_for_ack} = Rep} ->
do_reply_timeout(ConnHandle, TransId, Timer, Rep);
- [#reply{state = aborted} = Rep] ->
+ {_Converted,
+ #reply{state = aborted} = Rep} ->
do_reply_timeout(ConnHandle, TransId, Timer, Rep);
_ ->
@@ -4686,22 +4817,41 @@ handle_reply_timer_timeout(ConnHandle, TransId) ->
?report_trace(ConnHandle, "handle reply timeout", [timeout, TransId]),
incNumTimerRecovery(ConnHandle),
%% OTP-4378
- case megaco_monitor:lookup_reply(TransId) of
- [#reply{state = waiting_for_ack} = Rep] ->
+ case lookup_reply(undefined, TransId) of
+ {Converted,
+ #reply{state = waiting_for_ack} = Rep} ->
Serial = (Rep#reply.trans_id)#trans_id.serial,
- ConnData =
+ {Rep2, ConnData} =
case megaco_config:lookup_local_conn(ConnHandle) of
- [ConnData0] ->
- ConnData0;
- [] ->
- fake_conn_data(ConnHandle)
+ [ConnData0] when (Converted =:= false) ->
+ #reply{user_mod = UserMod,
+ user_args = UserArgs} = Rep,
+ {Rep,
+ ConnData0#conn_data{user_mod = UserMod,
+ user_args = UserArgs}};
+ [ConnData0] when (Converted =:= true) ->
+ {Rep#reply{user_mod = ConnData0#conn_data.user_mod,
+ user_args = ConnData0#conn_data.user_args},
+ ConnData0};
+ [] when (Converted =:= false) ->
+ ConnData0 = fake_conn_data(ConnHandle),
+ #reply{user_mod = UserMod,
+ user_args = UserArgs} = Rep,
+ {Rep,
+ ConnData0#conn_data{user_mod = UserMod,
+ user_args = UserArgs}};
+ [] when (Converted =:= true) ->
+ %% We have no valid info about user_mod and user_args
+ {Rep, fake_conn_data(ConnHandle)}
end,
ConnData2 = ConnData#conn_data{serial = Serial},
T = #'TransactionAck'{firstAck = Serial},
Extra = ?default_user_callback_extra,
- handle_ack(ConnData2, {error, timeout}, Rep, T, Extra);
- [#reply{pending_timer_ref = Ref, % aborted?
- bytes = SegSent}] -> % may be a binary
+ handle_ack(ConnData2, {error, timeout}, Rep2, T, Extra);
+
+ {_Converted,
+ #reply{pending_timer_ref = Ref, % aborted?
+ bytes = SegSent}} -> % may be a binary
megaco_monitor:cancel_apply_after(Ref),
cancel_segment_timers(SegSent),
megaco_monitor:delete_reply(TransId),
@@ -4803,9 +4953,10 @@ pending_timeout(ConnHandle, TransId, Timer) ->
handle_pending_timeout(CD, TransId, Timer) ->
?report_trace(CD, "handle pending timeout", []),
- case megaco_monitor:lookup_reply(TransId) of
- [#reply{state = State,
- handler = Pid} = Rep] when (State =:= prepare) orelse
+ case lookup_reply(CD, TransId) of
+ {_Converted,
+ #reply{state = State,
+ handler = Pid} = Rep} when (State =:= prepare) orelse
(State =:= eval_request) ->
#conn_data{sent_pending_limit = Limit,
@@ -4885,12 +5036,14 @@ handle_pending_timeout(CD, TransId, Timer) ->
[] ->
reply_not_found; % Trace ??
- [#reply{state = waiting_for_ack}] ->
+ {_Converted,
+ #reply{state = waiting_for_ack}} ->
%% The reply has already been sent
%% No need for any pending trans reply
reply_has_been_sent;
- [#reply{state = aborted} = Rep] ->
+ {_Converted,
+ #reply{state = aborted} = Rep} ->
%% glitch, but cleanup just the same
cancel_reply(CD, Rep, aborted),
reply_aborted_state
@@ -5096,7 +5249,65 @@ make_transaction_reply(_, TransId, IAR, TransRes) ->
%%-----------------------------------------------------------------
+%% This function is used as a wrapper for reply-record lookups.
+%% The intention is that during upgrade, this function
+%% can perform on-the-fly conversions of reply-records.
+lookup_reply(CD, TransId) ->
+ case megaco_monitor:lookup_reply(TransId) of
+ [#reply{} = Rep] ->
+ {false, Rep};
+
+ %% Old (pre-3.13.1) version of the record => Convert to new version
+ [{reply, TransId,
+ LocalMid, State, PendingTmrRef, Handler, TimerRef,
+ Version, Bytes, AckAction, SendHandle, Segments}]
+ when is_record(CD, conn_data) ->
+ #conn_data{user_mod = UserMod,
+ user_args = UserArgs} = CD,
+ Rep = #reply{trans_id = TransId,
+ local_mid = LocalMid,
+ state = State,
+ pending_timer_ref = PendingTmrRef,
+ handler = Handler,
+ timer_ref = TimerRef,
+ version = Version,
+ bytes = Bytes,
+ ack_action = AckAction,
+ send_handle = SendHandle,
+ segments = Segments,
+ user_mod = UserMod,
+ user_args = UserArgs},
+ {true, Rep};
+
+ %% Old (pre-3.13.1) version of the record => Convert to new version
+ [{reply, TransId,
+ LocalMid, State, PendingTmrRef, Handler, TimerRef,
+ Version, Bytes, AckAction, SendHandle, Segments}] ->
+ %% ConnData is not known here, so ignore for now
+ Rep = #reply{trans_id = TransId,
+ local_mid = LocalMid,
+ state = State,
+ pending_timer_ref = PendingTmrRef,
+ handler = Handler,
+ timer_ref = TimerRef,
+ version = Version,
+ bytes = Bytes,
+ ack_action = AckAction,
+ send_handle = SendHandle,
+ segments = Segments},
+ {true, Rep};
+
+ Else ->
+ Else
+ end.
+
+
%%-----------------------------------------------------------------
+
+%%-----------------------------------------------------------------
+%% info_msg(F, A) ->
+%% ?megaco_info(F, A).
+
warning_msg(F, A) ->
?megaco_warning(F, A).
@@ -5131,7 +5342,7 @@ error_msg(F, A) ->
%% Time in milli seconds
t() ->
- {A,B,C} = erlang:now(),
+ {A,B,C} = os:timestamp(),
A*1000000000+B*1000+(C div 1000).
@@ -5156,3 +5367,4 @@ incNum(Cnt) ->
Old
end.
+
diff --git a/lib/megaco/src/engine/megaco_monitor.erl b/lib/megaco/src/engine/megaco_monitor.erl
index f95a20cf58..29275371be 100644
--- a/lib/megaco/src/engine/megaco_monitor.erl
+++ b/lib/megaco/src/engine/megaco_monitor.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2000-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 2000-2010. All Rights Reserved.
+%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
-%%
+%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
-%%
+%%
%% %CopyrightEnd%
%%
@@ -51,6 +51,11 @@
update_request_field/3, update_request_fields/2,
delete_request/1,
+ request_lockcnt_cre/1,
+ request_lockcnt_del/1,
+ request_lockcnt_inc/1,
+ request_lockcnt_dec/1,
+
lookup_reply/1,
lookup_reply_field/2,
match_replies/1,
@@ -115,6 +120,24 @@ update_request_fields(Key, NewFields) when is_list(NewFields) ->
delete_request(Key) ->
ets:delete(megaco_requests, Key).
+
+request_lockcnt_cre(TransId) ->
+ Key = {TransId, lockcnt},
+ ets:insert_new(megaco_requests, {Key, 1}).
+
+request_lockcnt_del(TransId) ->
+ Key = {TransId, lockcnt},
+ ets:delete(megaco_requests, Key).
+
+request_lockcnt_inc(TransId) ->
+ Key = {TransId, lockcnt},
+ (catch ets:update_counter(megaco_requests, Key, 1)).
+
+request_lockcnt_dec(TransId) ->
+ Key = {TransId, lockcnt},
+ (catch ets:update_counter(megaco_requests, Key, -1)).
+
+
lookup_reply(Key) ->
ets:lookup(megaco_replies, Key).
diff --git a/lib/megaco/src/flex/Makefile.in b/lib/megaco/src/flex/Makefile.in
index 782d6a4807..5af651d89b 100644
--- a/lib/megaco/src/flex/Makefile.in
+++ b/lib/megaco/src/flex/Makefile.in
@@ -1,19 +1,19 @@
#
# %CopyrightBegin%
-#
-# Copyright Ericsson AB 2001-2009. All Rights Reserved.
-#
+#
+# Copyright Ericsson AB 2001-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%
include $(ERL_TOP)/make/target.mk
@@ -23,13 +23,30 @@ MEGACO_INCLUDEDIR = ../../include
include $(ERL_TOP)/make/$(TARGET)/otp.mk
-
# ----------------------------------------------------
# Application version
# ----------------------------------------------------
include ../../vsn.mk
VSN=$(MEGACO_VSN)
+# ----------------------------------------------------
+# Dynamic Erlang Driver
+# ----------------------------------------------------
+HAVE_USABLE_OTP_DED_MK = @HAVE_USABLE_OTP_DED_MK@
+
+ifeq ($(HAVE_USABLE_OTP_DED_MK),yes)
+# otp_ded.mk will be used on R13B04 and later
+include $(ERL_TOP)/make/$(TARGET)/otp_ded.mk
+else
+# megacos configure provide the info instead
+DED_CC = @CC@
+DED__NOWARN_NOTHR_CFLAGS = @DED_CFLAGS@
+DED_THR_DEFS = @DED_THR_DEFS@
+DED_LD = @DED_LD@
+DED_LDFLAGS = @DED_LDFLAGS@
+DED_INCLUDES = @DED_INCLUDES@
+DED_EXT = so
+endif
# ----------------------------------------------------
# The following variables differ on different systems, we set
@@ -39,16 +56,16 @@ VSN=$(MEGACO_VSN)
FLEX_VSN = $(shell flex --version)
-TMP_CFLAGS = @DED_CFLAGS@
+TMP_CFLAGS = $(DED__NOWARN_NOTHR_CFLAGS) @OTP_EXTRA_FLAGS@
ifeq ($(TYPE),valgrind)
CFLAGS = $(subst -O2, , $(TMP_CFLAGS)) -DVALGRIND
else
CFLAGS = $(TMP_CFLAGS)
endif
-CC = @CC@
-CFLAGS_MT = $(CFLAGS) -D_THREAD_SAFE -D_REENTRANT
-LD = @DED_LD@
-LDFLAGS = @DED_LDFLAGS@
+CC = $(DED_CC)
+CFLAGS_MT = $(CFLAGS) $(DED_THR_DEFS)
+LD = $(DED_LD)
+LDFLAGS = $(DED_LDFLAGS)
LEX = @LEX@
LEXLIB = @LEXLIB@
PERL = @PERL@
@@ -87,18 +104,13 @@ ENABLE_MEGACO_FLEX_SCANNER_LINENO = @ENABLE_MEGACO_FLEX_SCANNER_LINENO@
endif
endif
-
-SYSINCLUDE = -I$(ERL_TOP)/erts/emulator/beam \
- -I$(ERL_TOP)/erts/emulator/sys/$(ERLANG_OSTYPE)
ifeq ($(findstring vxworks,$(TARGET)),vxworks)
- SYSINCLUDE += -I$(ERL_TOP)/erts/etc/vxworks
+ DED_INCLUDES += -I$(ERL_TOP)/erts/etc/vxworks
endif
-DRIVER_INCLUDES = $(SYSINCLUDE)
-
PRIVDIR = ../../priv
LIBDIR = $(PRIVDIR)/lib/$(TARGET)
-
+OBJDIR = $(PRIVDIR)/obj/$(TARGET)
# ----------------------------------------------------
# Release directory specification
@@ -138,8 +150,8 @@ ifeq ($(findstring vxworks,$(TARGET)),vxworks)
FLEX_SCANNER_SO =
SOLIBS = $(FLEX_SCANNER_SO)
else
-FLEX_SCANNER_SO = $(LIBDIR)/$(STD_DRV).so
-FLEX_SCANNER_MT_SO = $(LIBDIR)/$(MT_DRV).so
+FLEX_SCANNER_SO = $(LIBDIR)/$(STD_DRV).$(DED_EXT)
+FLEX_SCANNER_MT_SO = $(LIBDIR)/$(MT_DRV).$(DED_EXT)
SOLIBS = $(FLEX_SCANNER_SO) $(FLEX_SCANNER_MT_SO)
endif
endif
@@ -175,7 +187,7 @@ else
CFLAGS += -DMFS_FLEX_DEBUG=0
endif
-CFLAGS += $(DRIVER_INCLUDES) $(DRV_FLAGS) -funroll-loops -Wall
+CFLAGS += $(DED_INCLUDES) -I$(ERL_TOP)/erts/$(TARGET) $(DRV_FLAGS) -funroll-loops -Wall
#ifneq ($(FLEX_VSN),)
#CFLAGS += -DFLEX_VERSION="$(FLEX_VSN)"
@@ -268,7 +280,7 @@ release_spec: opt
$(INSTALL_DATA) $(TARGET_FILES) $(RELSYSDIR)/ebin
ifeq ($(ENABLE_MEGACO_FLEX_SCANNER),true)
$(INSTALL_DATA) $(FLEX_FILES) $(C_TARGETS) $(RELSYSDIR)/src/flex
- $(INSTALL_DATA) $(SOLIBS) $(RELSYSDIR)/priv/lib
+ $(INSTALL_PROGRAM) $(SOLIBS) $(RELSYSDIR)/priv/lib
endif
@@ -379,18 +391,30 @@ $(STD_DRV).c: $(STD_DRV).flex
$(MT_DRV).c: $(MT_DRV).flex
$(LEX) $(MT_LEX_FLAGS) -P$* -o$@ $<
-solibs: $(LIBDIR) $(SOLIBS)
+solibs: $(LIBDIR) $(OBJDIR) $(SOLIBS)
+
+$(OBJDIR)/$(STD_DRV).o: $(STD_DRV).c
+ @echo "compiling std driver:"
+ $(CC) -c $(STD_DRV_NAME) $(CFLAGS) -o $@ $<
+
+$(OBJDIR)/$(MT_DRV).o: $(MT_DRV).c
+ @echo "compiling multi-threaded driver:"
+ $(CC) -c $(MT_DRV_NAME) $(CFLAGS_MT) -o $@ $<
+
# No need to link with -lfl as we have also defined %option noyywrap -
# and having -lfl doesn't work under Darwin for some reason. - Sean
-$(LIBDIR)/$(STD_DRV).so: $(STD_DRV).c
- @echo "std driver:"
- $(CC) $(STD_DRV_NAME) $(CFLAGS) $(LDFLAGS) -o $(LIBDIR)/$(STD_DRV).so $<
+$(LIBDIR)/$(STD_DRV).$(DED_EXT): $(OBJDIR)/$(STD_DRV).o
+ @echo "linking std driver:"
+ $(LD) $(LDFLAGS) -o $@ $<
-$(LIBDIR)/$(MT_DRV).so: $(MT_DRV).c
- @echo "multi-threaded driver:"
- $(CC) $(MT_DRV_NAME) $(CFLAGS_MT) $(LDFLAGS) -o $(LIBDIR)/$(MT_DRV).so $<
+$(LIBDIR)/$(MT_DRV).$(DED_EXT): $(OBJDIR)/$(MT_DRV).o
+ @echo "linking multi-threaded driver:"
+ $(LD) $(LDFLAGS) -o $@ $<
$(LIBDIR):
-mkdir -p $(LIBDIR)
+$(OBJDIR):
+ -mkdir -p $(OBJDIR)
+
diff --git a/lib/megaco/src/flex/megaco_flex_scanner_drv.flex.src b/lib/megaco/src/flex/megaco_flex_scanner_drv.flex.src
index 3520c34d50..96621193e8 100644
--- a/lib/megaco/src/flex/megaco_flex_scanner_drv.flex.src
+++ b/lib/megaco/src/flex/megaco_flex_scanner_drv.flex.src
@@ -8,12 +8,12 @@
* 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%
*
* ----------------------------------------------------------------------
@@ -361,9 +361,6 @@ static ErlDrvEntry mfs_entry = {
MEGACO_DRIVER_FLAGS, /* driver_flags, used for port lock indication */
NULL, /* handle2, emulator internal use */
NULL /* process_exit, Called when a process monitor fires */
-#if defined(MEGACO_DRV_ENTRY_HAS_STOP_SELECT)
- ,NULL /* stop_select, Called to close an event object */
-#endif
};
diff --git a/lib/megaco/src/flex/megaco_flex_scanner_handler.erl b/lib/megaco/src/flex/megaco_flex_scanner_handler.erl
index d09e0c6fff..420202134e 100644
--- a/lib/megaco/src/flex/megaco_flex_scanner_handler.erl
+++ b/lib/megaco/src/flex/megaco_flex_scanner_handler.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2001-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 2001-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%
%%
@@ -180,27 +180,28 @@ terminate(_Reason, _S) ->
%% Purpose: Called to change the internal state
%% Returns: {ok, NewState}
%%----------------------------------------------------------------------
-%% code_change({down, _Vsn}, #state{conf = Conf} = State, downgrade_to_pre_3_8) ->
-%% Port = downgrade_flex_scanner(Conf),
-%% {ok, State#state{conf = {flex, Port}}};
+
+code_change({down, _Vsn}, #state{conf = Conf} = State, downgrade_to_pre_3_13_1) ->
+ NewPorts = bump_flex_scanner(Conf),
+ {ok, State#state{conf = {flex, NewPorts}}};
+
+code_change(_Vsn, #state{conf = Conf} = State, upgrade_from_pre_3_13_1) ->
+ NewPorts = bump_flex_scanner(Conf),
+ {ok, State#state{conf = {flex, NewPorts}}};
code_change(_Vsn, State, _Extra) ->
{ok, State}.
-%% downgrade_flex_scanner({flex, Port}) when is_port(Port) ->
-%% Port;
-%% downgrade_flex_scanner({flex, [Port]}) when is_port(Port) ->
-%% Port;
-%% downgrade_flex_scanner({flex, Ports}) when is_list(Ports) ->
-%% megaco_flex_scanner:stop(Ports),
-%% case megaco_flex_scanner:start() of
-%% {ok, Port} ->
-%% Port;
-%% Error ->
-%% exit(Error)
-%% end;
-%% downgrade_flex_scanner(BadConfig) ->
-%% exit({invalid_config, BadConfig}).
+bump_flex_scanner({flex, Ports}) ->
+ megaco_flex_scanner:stop(Ports),
+ case start_flex_scanners() of
+ {ok, NewPorts} ->
+ NewPorts;
+ Error ->
+ exit(Error)
+ end;
+bump_flex_scanner(BadConfig) ->
+ exit({invalid_config, BadConfig}).
%%%----------------------------------------------------------------------
diff --git a/lib/megaco/test/Makefile b/lib/megaco/test/Makefile
index a6f50f87c4..682b83d368 100644
--- a/lib/megaco/test/Makefile
+++ b/lib/megaco/test/Makefile
@@ -1,19 +1,19 @@
#
# %CopyrightBegin%
-#
-# Copyright Ericsson AB 1999-2009. All Rights Reserved.
-#
+#
+# Copyright Ericsson AB 1999-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%
include $(ERL_TOP)/make/target.mk
@@ -52,13 +52,15 @@ endif
include modules.mk
+EBIN = .
+
HRL_FILES = megaco_test_lib.hrl
ERL_FILES = $(MODULES:%=%.erl)
-TARGET_FILES = $(MODULES:%=%.$(EMULATOR))
+SOURCE = $(HRL_FILES) $(ERL_FILES)
-COVER_SPEC_FILE = megaco.cover
+TARGET_FILES = $(MODULES:%=%.$(EMULATOR))
APP_CASES = app appup
@@ -71,6 +73,18 @@ OP_CASES = mess mib mreq pending trans actions load
ALL_CASES = $(APP_CASES) $(CODEC_CASES) $(MISC_CASES) $(OP_CASES)
+EMAKEFILE = Emakefile
+MAKE_EMAKE = $(wildcard $(ERL_TOP)/make/make_emakefile)
+
+ifeq ($(MAKE_EMAKE),)
+BUILDTARGET = $(TARGET_FILES)
+RELTEST_FILES = $(TEST_SPEC_FILE) $(COVER_SPEC_FILE) $(SOURCE)
+else
+BUILDTARGET = emakebuild
+RELTEST_FILES = $(EMAKEFILE) $(TEST_SPEC_FILE) $(COVER_SPEC_FILE) $(SOURCE)
+endif
+
+
# ----------------------------------------------------
# FLAGS
# ----------------------------------------------------
@@ -128,19 +142,153 @@ endif
# Targets
# ----------------------------------------------------
-tests debug opt: $(TARGET_FILES)
+tests debug opt: $(BUILDTARGET)
+
+targets: $(TARGET_FILES)
+
+.PHONY: emakebuild
+
+emakebuild: $(EMAKEFILE)
+
+$(EMAKEFILE):
+ $(MAKE_EMAKE) $(ERL_COMPILE_FLAGS) -o$(EBIN) '*_SUITE_make' | grep -v Warning > $(EMAKEFILE)
+ $(MAKE_EMAKE) $(ERL_COMPILE_FLAGS) -o$(EBIN) $(MODULES) | grep -v Warning >> $(EMAKEFILE)
clean:
+ rm -f $(EMAKEFILE)
rm -f $(TARGET_FILES)
rm -f errs core *~
docs:
info:
+ @echo "MAKE_EMAKE = $(MAKE_EMAKE)"
+ @echo "EMAKEFILE = $(EMAKEFILE)"
+ @echo "BUILDTARGET = $(BUILDTARGET)"
+ @echo ""
@echo "ERL_COMPILE_FLAGS = $(ERL_COMPILE_FLAGS)"
@echo "ERL = $(ERL)"
@echo "MERL = $(MERL)"
@echo ""
+ @echo "ARGS = $(ARGS)"
+ @echo ""
+ @echo "HRL_FILES = $(HRL_FILES)"
+ @echo "ERL_FILES = $(ERL_FILES)"
+ @echo "TARGET_FILES = $(TARGET_FILES)"
+ @echo ""
+
+help:
+ @echo ""
+ @echo "This Makefile controls the test of the $(APPLICATION) application. "
+ @echo ""
+ @echo "There are two separate ways to perform the test of $(APPLICATION)."
+ @echo ""
+ @echo " a) Run the official OTP test-server (which we do not describe here)"
+ @echo ""
+ @echo " b) Run the test-server provided with this application. "
+ @echo " There are a number of targets to run the entire or parts"
+ @echo " of this applications ($(APPLICATION)) test-suite"
+ @echo ""
+ @echo "Targets:"
+ @echo ""
+ @echo " help"
+ @echo " Print this info"
+ @echo ""
+ @echo " info"
+ @echo " Prints various environment variables. "
+ @echo " May be useful when debugging the Makefile. "
+ @echo ""
+ @echo " tests | debug | opt "
+ @echo " Compile all test-code. "
+ @echo ""
+ @echo " clean "
+ @echo " Remove all targets. "
+ @echo ""
+ @echo " test"
+ @echo " Run the entire $(APPLICATION) test-suite. "
+ @echo ""
+ @echo " app"
+ @echo " Run the $(APPLICATION) application sub-test-suite. "
+ @echo ""
+ @echo " appup"
+ @echo " Run the $(APPLICATION) application upgrade (appup) sub-test-suite. "
+ @echo ""
+ @echo " conf"
+ @echo " Run the $(APPLICATION) config sub-test-suite. "
+ @echo " Checks various aspects of the megaco configuration. "
+ @echo ""
+ @echo " codec"
+ @echo " Run the $(APPLICATION) codec sub-test-suite(s). "
+ @echo ""
+ @echo " flex"
+ @echo " Run the $(APPLICATION) flex-scanner sub-test-suite. "
+ @echo " This sub-test-suite does not test the function of the scanner itself"
+ @echo " (that is done by the codec sub-test-suite(s)), instead, this"
+ @echo " sub-test-suite tests the *handling* of the flex-scanner linked-in driver."
+ @echo ""
+ @echo " dm"
+ @echo " Run the $(APPLICATION) digit-map sub-test-suite. "
+ @echo ""
+ @echo " tid"
+ @echo " Run the $(APPLICATION) binary term-id sub-test-suite. "
+ @echo ""
+ @echo " sdp"
+ @echo " Run the $(APPLICATION) SDP sub-test-suite. "
+ @echo ""
+ @echo " action"
+ @echo " Run the $(APPLICATION) actions sub-test-suite. "
+ @echo " Actions are building blocks of a $(APPLICATION) message. "
+ @echo " This sub-test-suite attempts to perform tests related to this, "
+ @echo " using all the supported codecs. "
+ @echo ""
+ @echo " mess"
+ @echo " Run the $(APPLICATION) message sub-test-suite"
+ @echo " This is basic message processing test-cases"
+ @echo ""
+ @echo " trans"
+ @echo " Run the $(APPLICATION) transaction sender sub-test-suite"
+ @echo " This is basic message processing for a megaco application "
+ @echo " configured to be using the transaction sender. "
+ @echo ""
+ @echo " mib"
+ @echo " Run the $(APPLICATION) $(APPLICATION)-mib sub-test-suite"
+ @echo " Tests related to the basic support for the $(APPLICATION) mib"
+ @echo " primarily counters"
+ @echo ""
+ @echo " mreq"
+ @echo " Run the $(APPLICATION) mreq sub-test-suite"
+ @echo " This is yet another sub-test-suite with message processing "
+ @echo " test-cases. "
+ @echo ""
+ @echo " pending"
+ @echo " Run the $(APPLICATION) pending-limit sub-test-suite"
+ @echo ""
+ @echo " udp"
+ @echo " Run the $(APPLICATION) UDP transport component sub-test-suite"
+ @echo ""
+ @echo " tcp"
+ @echo " Run the $(APPLICATION) TCP transport component sub-test-suite"
+ @echo ""
+ @echo " load"
+ @echo " Run the $(APPLICATION) load sub-test-suite"
+ @echo " This sub-test-suite performs load test test-cases using "
+ @echo " \"high\" message traffic. "
+ @echo ""
+ @echo " segment"
+ @echo " Run the $(APPLICATION) message segmentation sub-test-suite"
+ @echo " If using the UDP transport protocol, it is possible to send "
+ @echo " and receive segmented megaco replies (in version 3 of the protocol) "
+ @echo " This sub-test-suite tests this feature. "
+ @echo ""
+ @echo " timer"
+ @echo " Run the $(APPLICATION) timer sub-test-suite"
+ @echo " Basic test-suite for the megaco-timers"
+ @echo ""
+ @echo " ex"
+ @echo " Run the $(APPLICATION) example sub-test-suite"
+ @echo " The $(APPLICATION) application contains one example,"
+ @echo " this is a sub-test-suite based on the code,"
+ @echo ""
# ----------------------------------------------------
@@ -195,8 +343,6 @@ all: make
make: targets
-targets: $(TARGET_FILES)
-
test: make
$(MERL) $(ARGS) -sname megaco_test $(ERL_PATH) \
-s megaco_test_lib t $(SUITE) \
@@ -603,9 +749,10 @@ release_docs_spec:
release_tests_spec: tests
$(INSTALL_DIR) $(RELSYSDIR)
- $(INSTALL_DATA) $(TEST_SPEC_FILE) $(COVER_SPEC_FILE) \
- $(HRL_FILES) $(ERL_FILES) \
- $(RELSYSDIR)
- $(INSTALL_DATA) $(TARGET_FILES) $(RELSYSDIR)
+ $(INSTALL_DATA) $(RELTEST_FILES) $(RELSYSDIR)
+# $(INSTALL_DATA) $(TEST_SPEC_FILE) $(COVER_SPEC_FILE) \
+# $(HRL_FILES) $(ERL_FILES) \
+# $(RELSYSDIR)
+#
chmod -f -R u+w $(RELSYSDIR)
diff --git a/lib/megaco/test/megaco_app_test.erl b/lib/megaco/test/megaco_app_test.erl
index 8e2148c236..597ec26338 100644
--- a/lib/megaco/test/megaco_app_test.erl
+++ b/lib/megaco/test/megaco_app_test.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2002-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 2002-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%
%%
@@ -87,6 +87,10 @@ is_app(App) ->
case file:consult(File) of
{ok, [{application, App, AppFile}]} ->
{ok, AppFile};
+ {error, {LineNo, Mod, Code}} ->
+ IoList = lists:concat([File, ":", LineNo, ": ",
+ Mod:format_error(Code)]),
+ {error, list_to_atom(lists:flatten(IoList))};
Error ->
{error, {invalid_format, Error}}
end.
diff --git a/lib/megaco/test/megaco_config_test.erl b/lib/megaco/test/megaco_config_test.erl
index 453c1b8964..9ab1a7d90d 100644
--- a/lib/megaco/test/megaco_config_test.erl
+++ b/lib/megaco/test/megaco_config_test.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2000-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 2000-2010. All Rights Reserved.
+%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
-%%
+%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
-%%
+%%
%% %CopyrightEnd%
%%
@@ -106,166 +106,197 @@ config(Config) when is_list(Config) ->
Evil = 400,
End = 500,
+ InitialCmd =
+ fun(No, Desc, Cmd, VerifyVal) ->
+ initial_command(Initial + No, Desc, Cmd, VerifyVal)
+ end,
+
+ VerifyCmd =
+ fun(M, No, Key, V) ->
+ verify_user_default_command(M, Verify + No, Key, V)
+ end,
+
+ NiceCmd =
+ fun(M, No, Key, Val) ->
+ nice_user_update_command(M, Nice + No, Key, Val)
+ end,
+
+ EvilCmd =
+ fun(M, No, Key, Val) ->
+ evil_user_update_command(M, Evil + No, Key, Val)
+ end,
+
+ %% End commands
+ ExitCmd =
+ fun(No, Desc, Cmd) ->
+ exit_command(End + No, Desc, Cmd)
+ end,
+ ErrorCmd =
+ fun(No, Desc, Cmd, MainReason, TS) ->
+ error_command(End + No, Desc, Cmd, MainReason, TS)
+ end,
+ PlainCmd =
+ fun(No, Desc, Cmd, V) ->
+ command(End + No, Desc, Cmd, V)
+ end,
+
Commands =
[
%% Initial commands
- initial_command( Initial + 0,
- "enable trace",
- fun() -> megaco:enable_trace(100, io) end, ok),
- initial_command( Initial + 1,
- "start",
- fun() -> megaco:start() end, ok),
- initial_command( Initial + 2,
- "Verify no active requests",
- fun() -> megaco:system_info(n_active_requests) end,
- 0),
- initial_command( Initial + 3,
- "Verify no active replies",
- fun() -> megaco:system_info(n_active_replies) end,
- 0),
- initial_command( Initial + 4,
- "Verify no active connections",
- fun() ->
- megaco:system_info(n_active_connections)
- end,
- 0),
- initial_command( Initial + 5,
- "Verify no connections",
- fun() -> megaco:system_info(connections) end, []),
- initial_command( Initial + 6,
- "Verify no users",
- fun() -> megaco:system_info(users) end, []),
- initial_command( Initial + 7,
- "Start user",
- fun() -> megaco:start_user(Mid, []) end, ok),
-
+ InitialCmd(0,
+ "enable trace",
+ fun() -> megaco:enable_trace(100, io) end,
+ ok),
+ InitialCmd(1,
+ "start",
+ fun() -> megaco:start() end,
+ ok),
+ InitialCmd(2,
+ "Verify no active requests",
+ fun() -> megaco:system_info(n_active_requests) end,
+ 0),
+ InitialCmd(3,
+ "Verify no active replies",
+ fun() -> megaco:system_info(n_active_replies) end,
+ 0),
+ InitialCmd(4,
+ "Verify no active connections",
+ fun() -> megaco:system_info(n_active_connections) end,
+ 0),
+ InitialCmd(5,
+ "Verify no connections",
+ fun() -> megaco:system_info(connections) end,
+ []),
+ InitialCmd(6,
+ "Verify no users",
+ fun() -> megaco:system_info(users) end,
+ []),
+ InitialCmd(7,
+ "Start user",
+ fun() -> megaco:start_user(Mid, []) end,
+ ok),
+
%% Verify user defaults
- verify_user_default_command(Mid, Verify + 1, connections, []),
- verify_user_default_command(Mid, Verify + 2, min_trans_id, 1),
- verify_user_default_command(Mid, Verify + 3, max_trans_id, infinity),
- verify_user_default_command(Mid, Verify + 4, request_timer,
- #megaco_incr_timer{}),
- verify_user_default_command(Mid, Verify + 5, long_request_timer, timer:seconds(60)),
- verify_user_default_command(Mid, Verify + 6, auto_ack, false),
- verify_user_default_command(Mid, Verify + 7, pending_timer, 30000),
- verify_user_default_command(Mid, Verify + 8, reply_timer, 30000),
- verify_user_default_command(Mid, Verify + 9, send_mod, megaco_tcp),
- verify_user_default_command(Mid, Verify + 10, encoding_mod,
- megaco_pretty_text_encoder),
- verify_user_default_command(Mid, Verify + 11, encoding_config, []),
- verify_user_default_command(Mid, Verify + 12, protocol_version, 1),
- verify_user_default_command(Mid, Verify + 13, reply_data, undefined),
- verify_user_default_command(Mid, Verify + 14, receive_handle,
- fun(H) when is_record(H, megaco_receive_handle) -> {ok, H};
- (R) -> {error, R}
- end),
+ VerifyCmd(Mid, 1, connections, []),
+ VerifyCmd(Mid, 2, min_trans_id, 1),
+ VerifyCmd(Mid, 3, max_trans_id, infinity),
+ VerifyCmd(Mid, 4, request_timer, #megaco_incr_timer{}),
+ VerifyCmd(Mid, 5, long_request_timer, timer:seconds(60)),
+ VerifyCmd(Mid, 6, auto_ack, false),
+ VerifyCmd(Mid, 7, pending_timer, 30000),
+ VerifyCmd(Mid, 8, reply_timer, 30000),
+ VerifyCmd(Mid, 9, send_mod, megaco_tcp),
+ VerifyCmd(Mid, 10, encoding_mod, megaco_pretty_text_encoder),
+ VerifyCmd(Mid, 11, encoding_config, []),
+ VerifyCmd(Mid, 12, protocol_version, 1),
+ VerifyCmd(Mid, 13, reply_data, undefined),
+ VerifyCmd(Mid, 14, receive_handle,
+ fun(H) when is_record(H, megaco_receive_handle) ->
+ {ok, H};
+ (R) ->
+ {error, R}
+ end),
%% Nice update
- nice_user_update_command(Mid, Nice + 1, min_trans_id, Int),
- nice_user_update_command(Mid, Nice + 2, max_trans_id, Int),
- nice_user_update_command(Mid, Nice + 3, max_trans_id, infinity),
- nice_user_update_command(Mid, Nice + 4, request_timer, Int),
- nice_user_update_command(Mid, Nice + 5, request_timer, infinity),
- nice_user_update_command(Mid, Nice + 6, request_timer, IT),
- nice_user_update_command(Mid, Nice + 7, long_request_timer, Int),
- nice_user_update_command(Mid, Nice + 8, long_request_timer, infinity),
- nice_user_update_command(Mid, Nice + 9, long_request_timer, IT),
- nice_user_update_command(Mid, Nice + 10, auto_ack, true),
- nice_user_update_command(Mid, Nice + 11, auto_ack, false),
- nice_user_update_command(Mid, Nice + 12, pending_timer, Int),
- nice_user_update_command(Mid, Nice + 13, pending_timer, infinity),
- nice_user_update_command(Mid, Nice + 14, pending_timer, IT),
- nice_user_update_command(Mid, Nice + 15, reply_timer, Int),
- nice_user_update_command(Mid, Nice + 16, reply_timer, infinity),
- nice_user_update_command(Mid, Nice + 17, reply_timer, IT),
- nice_user_update_command(Mid, Nice + 18, send_mod, an_atom),
- nice_user_update_command(Mid, Nice + 19, encoding_mod, an_atom),
- nice_user_update_command(Mid, Nice + 20, encoding_config, []),
- nice_user_update_command(Mid, Nice + 21, protocol_version, Int),
- nice_user_update_command(Mid, Nice + 23, reply_data, IT),
- nice_user_update_command(Mid, Nice + 23, resend_indication, true),
- nice_user_update_command(Mid, Nice + 24, resend_indication, false),
- nice_user_update_command(Mid, Nice + 25, resend_indication, flag),
+ NiceCmd(Mid, 1, min_trans_id, Int),
+ NiceCmd(Mid, 2, max_trans_id, Int),
+ NiceCmd(Mid, 3, max_trans_id, infinity),
+ NiceCmd(Mid, 4, request_timer, Int),
+ NiceCmd(Mid, 5, request_timer, infinity),
+ NiceCmd(Mid, 6, request_timer, IT),
+ NiceCmd(Mid, 7, long_request_timer, Int),
+ NiceCmd(Mid, 8, long_request_timer, infinity),
+ NiceCmd(Mid, 9, long_request_timer, IT),
+ NiceCmd(Mid, 10, auto_ack, true),
+ NiceCmd(Mid, 11, auto_ack, false),
+ NiceCmd(Mid, 12, pending_timer, Int),
+ NiceCmd(Mid, 13, pending_timer, infinity),
+ NiceCmd(Mid, 14, pending_timer, IT),
+ NiceCmd(Mid, 15, reply_timer, Int),
+ NiceCmd(Mid, 16, reply_timer, infinity),
+ NiceCmd(Mid, 17, reply_timer, IT),
+ NiceCmd(Mid, 18, send_mod, an_atom),
+ NiceCmd(Mid, 19, encoding_mod, an_atom),
+ NiceCmd(Mid, 20, encoding_config, []),
+ NiceCmd(Mid, 21, protocol_version, Int),
+ NiceCmd(Mid, 23, reply_data, IT),
+ NiceCmd(Mid, 23, resend_indication, true),
+ NiceCmd(Mid, 24, resend_indication, false),
+ NiceCmd(Mid, 25, resend_indication, flag),
%% Evil update
- evil_user_update_command(Mid, Evil + 1, min_trans_id, NonInt),
- evil_user_update_command(Mid, Evil + 2, max_trans_id, NonInt),
- evil_user_update_command(Mid, Evil + 3, max_trans_id, non_infinity),
- evil_user_update_command(Mid, Evil + 4, request_timer, NonInt),
- evil_user_update_command(Mid, Evil + 5, request_timer, non_infinity),
- evil_user_update_command(Mid, Evil + 6, request_timer, IT2),
- evil_user_update_command(Mid, Evil + 7, request_timer, IT3),
- evil_user_update_command(Mid, Evil + 8, request_timer, IT4),
- evil_user_update_command(Mid, Evil + 9, request_timer, IT5),
- evil_user_update_command(Mid, Evil + 10, long_request_timer, NonInt),
- evil_user_update_command(Mid, Evil + 11, long_request_timer, non_infinity),
- evil_user_update_command(Mid, Evil + 12, long_request_timer, IT2),
- evil_user_update_command(Mid, Evil + 13, long_request_timer, IT3),
- evil_user_update_command(Mid, Evil + 14, long_request_timer, IT4),
- evil_user_update_command(Mid, Evil + 15, long_request_timer, IT5),
- evil_user_update_command(Mid, Evil + 16, auto_ack, non_bool),
- evil_user_update_command(Mid, Evil + 17, pending_timer, NonInt),
- evil_user_update_command(Mid, Evil + 18, pending_timer, non_infinity),
- evil_user_update_command(Mid, Evil + 19, pending_timer, IT2),
- evil_user_update_command(Mid, Evil + 20, pending_timer, IT3),
- evil_user_update_command(Mid, Evil + 21, pending_timer, IT4),
- evil_user_update_command(Mid, Evil + 22, pending_timer, IT5),
- evil_user_update_command(Mid, Evil + 23, reply_timer, NonInt),
- evil_user_update_command(Mid, Evil + 24, reply_timer, non_infinity),
- evil_user_update_command(Mid, Evil + 25, reply_timer, IT2),
- evil_user_update_command(Mid, Evil + 26, reply_timer, IT3),
- evil_user_update_command(Mid, Evil + 27, reply_timer, IT4),
- evil_user_update_command(Mid, Evil + 28, reply_timer, IT5),
- evil_user_update_command(Mid, Evil + 29, send_mod, {non_atom}),
- evil_user_update_command(Mid, Evil + 30, encoding_mod, {non_atom}),
- evil_user_update_command(Mid, Evil + 31, encoding_config, non_list),
- evil_user_update_command(Mid, Evil + 32, protocol_version, NonInt),
- evil_user_update_command(Mid, Evil + 33, resend_indication, flagg),
-
-
- exit_command(End + 1,
- "Verify non-existing system info",
- fun() -> megaco:system_info(non_exist) end),
- exit_command(End + 2,
- "Verify non-existing user user info",
- fun() -> megaco:user_info(non_exist, trans_id) end),
- exit_command(End + 3, "Verify non-existing user info",
- fun() -> megaco:user_info(Mid, non_exist) end),
-
- error_command(End + 4,
- "Try updating user info for non-existing user",
- fun() ->
- megaco:update_user_info(non_exist, trans_id, 1)
- end,
- no_such_user, 2),
- error_command(End + 11,
- "Try updating non-existing user info",
- fun() ->
- megaco:update_user_info(Mid, trans_id, 4711)
- end,
- bad_user_val, 4),
- error_command(End + 12,
- "Try start already started user",
- fun() ->
- megaco:start_user(Mid, [])
- end,
- user_already_exists, 2),
-
- command(End + 13, "Verify started users",
- fun() -> megaco:system_info(users) end, [Mid]),
- command(End + 14, "Stop user", fun() -> megaco:stop_user(Mid) end, ok),
- command(End + 15, "Verify started users",
- fun() -> megaco:system_info(users) end, []),
- error_command(End + 16, "Try stop not started user",
- fun() -> megaco:stop_user(Mid) end, no_such_user, 2),
- error_command(End + 17, "Try start megaco (it's already started)",
- fun() -> megaco:start() end, already_started, 2),
- command(End + 18, "Stop megaco", fun() -> megaco:stop() end, ok),
- error_command(End + 19, "Try stop megaco (it's not running)",
- fun() -> megaco:stop() end, not_started, 2)
+ EvilCmd(Mid, 1, min_trans_id, NonInt),
+ EvilCmd(Mid, 2, max_trans_id, NonInt),
+ EvilCmd(Mid, 3, max_trans_id, non_infinity),
+ EvilCmd(Mid, 4, request_timer, NonInt),
+ EvilCmd(Mid, 5, request_timer, non_infinity),
+ EvilCmd(Mid, 6, request_timer, IT2),
+ EvilCmd(Mid, 7, request_timer, IT3),
+ EvilCmd(Mid, 8, request_timer, IT4),
+ EvilCmd(Mid, 9, request_timer, IT5),
+ EvilCmd(Mid, 10, long_request_timer, NonInt),
+ EvilCmd(Mid, 11, long_request_timer, non_infinity),
+ EvilCmd(Mid, 12, long_request_timer, IT2),
+ EvilCmd(Mid, 13, long_request_timer, IT3),
+ EvilCmd(Mid, 14, long_request_timer, IT4),
+ EvilCmd(Mid, 15, long_request_timer, IT5),
+ EvilCmd(Mid, 16, auto_ack, non_bool),
+ EvilCmd(Mid, 17, pending_timer, NonInt),
+ EvilCmd(Mid, 18, pending_timer, non_infinity),
+ EvilCmd(Mid, 19, pending_timer, IT2),
+ EvilCmd(Mid, 20, pending_timer, IT3),
+ EvilCmd(Mid, 21, pending_timer, IT4),
+ EvilCmd(Mid, 22, pending_timer, IT5),
+ EvilCmd(Mid, 23, reply_timer, NonInt),
+ EvilCmd(Mid, 24, reply_timer, non_infinity),
+ EvilCmd(Mid, 25, reply_timer, IT2),
+ EvilCmd(Mid, 26, reply_timer, IT3),
+ EvilCmd(Mid, 27, reply_timer, IT4),
+ EvilCmd(Mid, 28, reply_timer, IT5),
+ EvilCmd(Mid, 29, send_mod, {non_atom}),
+ EvilCmd(Mid, 30, encoding_mod, {non_atom}),
+ EvilCmd(Mid, 31, encoding_config, non_list),
+ EvilCmd(Mid, 32, protocol_version, NonInt),
+ EvilCmd(Mid, 33, resend_indication, flagg),
+
+
+ %% End
+ ExitCmd(1, "Verify non-existing system info",
+ fun() -> megaco:system_info(non_exist) end),
+ ExitCmd(2, "Verify non-existing user user info",
+ fun() -> megaco:user_info(non_exist, trans_id) end),
+ ExitCmd(3, "Verify non-existing user info",
+ fun() -> megaco:user_info(Mid, non_exist) end),
+
+ ErrorCmd(4, "Try updating user info for non-existing user",
+ fun() ->
+ megaco:update_user_info(non_exist, trans_id, 1)
+ end,
+ no_such_user, 2),
+ ErrorCmd(11, "Try updating non-existing user info",
+ fun() ->
+ megaco:update_user_info(Mid, trans_id, 4711)
+ end,
+ bad_user_val, 4),
+ ErrorCmd(12, "Try start already started user",
+ fun() -> megaco:start_user(Mid, []) end,
+ user_already_exists, 2),
+
+ PlainCmd(13, "Verify started users",
+ fun() -> megaco:system_info(users) end, [Mid]),
+ PlainCmd(14, "Stop user", fun() -> megaco:stop_user(Mid) end, ok),
+ PlainCmd(15, "Verify started users",
+ fun() -> megaco:system_info(users) end, []),
+ ErrorCmd(16, "Try stop not started user",
+ fun() -> megaco:stop_user(Mid) end, no_such_user, 2),
+ ErrorCmd(17, "Try start megaco (it's already started)",
+ fun() -> megaco:start() end, already_started, 2),
+ PlainCmd(18, "Stop megaco", fun() -> megaco:stop() end, ok),
+ ErrorCmd(19, "Try stop megaco (it's not running)",
+ fun() -> megaco:stop() end, not_started, 2)
],
@@ -279,7 +310,7 @@ exec([#command{id = No,
desc = Desc,
cmd = Cmd,
verify = Verify}|Commands]) ->
- io:format("Executing command ~2w: ~s: ", [No, Desc]),
+ io:format("Executing command ~3w: ~s: ", [No, Desc]),
case (catch Verify((catch Cmd()))) of
{ok, OK} ->
io:format("ok => ~p~n", [OK]),
@@ -320,7 +351,7 @@ nice_user_update_command(Mid, No, Key, Val) ->
evil_user_update_command(Mid, No, Key, Val) ->
- Desc = lists:flatten(io_lib:format("Evil: Update ~w", [Key])),
+ Desc = lists:flatten(io_lib:format("Evil - Update ~w", [Key])),
Cmd = fun() ->
case (catch megaco:user_info(Mid, Key)) of
{'EXIT', R} ->
@@ -371,14 +402,19 @@ error_command(No, Desc, Cmd, MainReason, TS) when is_function(Cmd) ->
end,
command(No, Desc, Cmd, Verify).
-command(No, Desc, Cmd, Verify) when is_integer(No) and is_list(Desc) and
- is_function(Cmd) and is_function(Verify) ->
+command(No, Desc, Cmd, Verify)
+ when (is_integer(No) andalso
+ is_list(Desc) andalso
+ is_function(Cmd) andalso
+ is_function(Verify)) ->
#command{id = No,
desc = Desc,
cmd = Cmd,
verify = Verify};
-command(No, Desc, Cmd, VerifyVal) when is_integer(No) and is_list(Desc) and
- is_function(Cmd) ->
+command(No, Desc, Cmd, VerifyVal)
+ when (is_integer(No) andalso
+ is_list(Desc) andalso
+ is_function(Cmd)) ->
Verify = fun(Val) ->
case Val of
VerifyVal ->
@@ -881,6 +917,12 @@ otp_8167(Config) when is_list(Config) ->
p("connect ok: CD = ~n~p", [CD]),
CH = CD#conn_data.conn_handle,
+ p("get value for item cancel from connection: ~p", [CH]),
+ false = megaco_config:conn_info(CH, cancel),
+
+ p("get value for item cancel from connection data", []),
+ false = megaco_config:conn_info(CD, cancel),
+
p("get value for item call_proxy_gc_timeout for connection: ~p", [CH]),
10101 = megaco_config:conn_info(CH, call_proxy_gc_timeout),
diff --git a/lib/megaco/test/modules.mk b/lib/megaco/test/modules.mk
index 0186a84c26..049d8babe2 100644
--- a/lib/megaco/test/modules.mk
+++ b/lib/megaco/test/modules.mk
@@ -1,24 +1,26 @@
#-*-makefile-*- ; force emacs to enter makefile-mode
# %CopyrightBegin%
-#
-# Copyright Ericsson AB 2001-2009. All Rights Reserved.
-#
+#
+# Copyright Ericsson AB 2001-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%
TEST_SPEC_FILE = megaco.spec
+COVER_SPEC_FILE = megaco.cover
+
BEHAVIOUR_MODULES = \
megaco_test_generator
diff --git a/lib/megaco/vsn.mk b/lib/megaco/vsn.mk
index 6ec7f3192a..63c9ab0ef7 100644
--- a/lib/megaco/vsn.mk
+++ b/lib/megaco/vsn.mk
@@ -1,27 +1,13 @@
-#-*-makefile-*- ; force emacs to enter makefile-mode
-
-# %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%
-
-MEGACO_VSN = 3.13
+APPLICATION = megaco
+MEGACO_VSN = 3.14.1
PRE_VSN =
-APP_VSN = "megaco-$(MEGACO_VSN)$(PRE_VSN)"
+APP_VSN = "$(APPLICATION)-$(MEGACO_VSN)$(PRE_VSN)"
-TICKETS = OTP-8205 OTP-8239 OTP-8249
+TICKETS = OTP-8529 OTP-8561 OTP-8627 OTP-8634
+
+TICKETS_3_14 = OTP-8317 OTP-8323 OTP-8328 OTP-8362 OTP-8403
+
+TICKETS_3_13 = OTP-8205 OTP-8239 OTP-8249
TICKETS_3_12 = OTP-8183 OTP-8212
diff --git a/lib/mnesia/doc/src/mnesia.xml b/lib/mnesia/doc/src/mnesia.xml
index 3484cd104a..d76471d922 100644
--- a/lib/mnesia/doc/src/mnesia.xml
+++ b/lib/mnesia/doc/src/mnesia.xml
@@ -4,7 +4,7 @@
<erlref>
<header>
<copyright>
- <year>1996</year><year>2009</year>
+ <year>1996</year><year>2010</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
@@ -13,12 +13,12 @@
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>mnesia</title>
@@ -360,6 +360,9 @@ If a new item is inserted with the same key as
</p>
<list type="bulleted">
<item>
+ <p>mnesia:lock/2 (read_lock_table/1, write_lock_table/1)</p>
+ </item>
+ <item>
<p>mnesia:write/3 (write/1, s_write/1)</p>
</item>
<item>
@@ -396,9 +399,6 @@ If a new item is inserted with the same key as
<p>mnesia:index_read/3</p>
</item>
<item>
- <p>mnesia:lock/2 (read_lock_table/1, write_lock_table/1)</p>
- </item>
- <item>
<p>mnesia:table_info/2</p>
</item>
</list>
@@ -3045,6 +3045,17 @@ raise(Name, Amount) ->
</p>
</item>
<item>
+ <p><c>-mnesia send_compressed Level</c> specifies the level of
+ compression to be used when copying a table from the local node to
+ another one. The default level is 0.
+ </p>
+ <p><c>Level</c> must be an integer in the interval [0, 9], with 0
+ representing no compression and 9 representing maximum compression.
+ Before setting it to a non-zero value, make sure the remote nodes
+ understand this configuration.
+ </p>
+ </item>
+ <item>
<p><c>-mnesia schema_location Loc</c> controls where
Mnesia will look for its schema. The parameter
<c>Loc</c> may be one of the following atoms: </p>
diff --git a/lib/mnesia/doc/src/notes.xml b/lib/mnesia/doc/src/notes.xml
index 69f2185cd8..66242398d9 100644
--- a/lib/mnesia/doc/src/notes.xml
+++ b/lib/mnesia/doc/src/notes.xml
@@ -4,7 +4,7 @@
<chapter>
<header>
<copyright>
- <year>1996</year><year>2009</year>
+ <year>1996</year><year>2010</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
@@ -13,12 +13,12 @@
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>Mnesia Release Notes</title>
@@ -38,6 +38,35 @@
thus constitutes one section in this document. The title of each
section is the version number of Mnesia.</p>
+ <section><title>Mnesia 4.4.13</title>
+
+ <section><title>Fixed Bugs and Malfunctions</title>
+ <list>
+ <item>
+ <p>
+ Transactions could be left hanging if a node went down
+ when invoking mnesia:sync_transaction/[1,2]. Thanks Igor
+ Ribeiro Sucupira.</p>
+ <p>
+ Own Id: OTP-8402</p>
+ </item>
+ </list>
+ </section>
+
+
+ <section><title>Improvements and New Features</title>
+ <list>
+ <item>
+ <p>
+ Igor Ribeiro Sucupira added the option to compress data
+ when copying tables between Mnesia nodes.</p>
+ <p>
+ Own Id: OTP-8406</p>
+ </item>
+ </list>
+ </section>
+
+ </section>
<section><title>Mnesia 4.4.12</title>
<section><title>Improvements and New Features</title>
diff --git a/lib/mnesia/src/mnesia.appup.src b/lib/mnesia/src/mnesia.appup.src
index cad63bf8df..b3b9297db2 100644
--- a/lib/mnesia/src/mnesia.appup.src
+++ b/lib/mnesia/src/mnesia.appup.src
@@ -1,14 +1,30 @@
%% -*- erlang -*-
{"%VSN%",
[
+ {"4.4.12",
+ [
+ {update, mnesia, soft, soft_purge, soft_purge, []},
+ {update, mnesia_loader, soft, soft_purge, soft_purge, []},
+ {update, mnesia_monitor, soft, soft_purge, soft_purge, []},
+ {update, mnesia_tm, soft, soft_purge, soft_purge, []}
+ ]
+ },
{"4.4.11",
[
+ {update, mnesia, soft, soft_purge, soft_purge, []},
+ {update, mnesia_loader, soft, soft_purge, soft_purge, []},
+ {update, mnesia_monitor, soft, soft_purge, soft_purge, []},
+ {update, mnesia_tm, soft, soft_purge, soft_purge, []},
{update, mnesia_locker, soft, soft_purge, soft_purge, []},
{update, mnesia_controller, soft, soft_purge, soft_purge, []}
]
},
{"4.4.10",
[
+ {update, mnesia, soft, soft_purge, soft_purge, []},
+ {update, mnesia_loader, soft, soft_purge, soft_purge, []},
+ {update, mnesia_monitor, soft, soft_purge, soft_purge, []},
+ {update, mnesia_tm, soft, soft_purge, soft_purge, []},
{update, mnesia_locker, soft, soft_purge, soft_purge, []},
{update, mnesia_controller, soft, soft_purge, soft_purge, []}
]
@@ -18,14 +34,30 @@
{"4.4.7", [{restart_application, mnesia}]}
],
[
+ {"4.4.12",
+ [
+ {update, mnesia, soft, soft_purge, soft_purge, []},
+ {update, mnesia_loader, soft, soft_purge, soft_purge, []},
+ {update, mnesia_monitor, soft, soft_purge, soft_purge, []},
+ {update, mnesia_tm, soft, soft_purge, soft_purge, []}
+ ]
+ },
{"4.4.11",
[
+ {update, mnesia, soft, soft_purge, soft_purge, []},
+ {update, mnesia_loader, soft, soft_purge, soft_purge, []},
+ {update, mnesia_monitor, soft, soft_purge, soft_purge, []},
+ {update, mnesia_tm, soft, soft_purge, soft_purge, []},
{update, mnesia_locker, soft, soft_purge, soft_purge, []},
{update, mnesia_controller, soft, soft_purge, soft_purge, []}
]
},
{"4.4.10",
[
+ {update, mnesia, soft, soft_purge, soft_purge, []},
+ {update, mnesia_loader, soft, soft_purge, soft_purge, []},
+ {update, mnesia_monitor, soft, soft_purge, soft_purge, []},
+ {update, mnesia_tm, soft, soft_purge, soft_purge, []},
{update, mnesia_locker, soft, soft_purge, soft_purge, []},
{update, mnesia_controller, soft, soft_purge, soft_purge, []}
]
diff --git a/lib/mnesia/src/mnesia.erl b/lib/mnesia/src/mnesia.erl
index 9a630f18eb..fb29007780 100644
--- a/lib/mnesia/src/mnesia.erl
+++ b/lib/mnesia/src/mnesia.erl
@@ -1,19 +1,19 @@
%%
%% %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
%% 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%
%%
@@ -2200,6 +2200,7 @@ system_info2(transaction_log_writes) -> mnesia_dumper:get_log_writes();
system_info2(core_dir) -> mnesia_monitor:get_env(core_dir);
system_info2(no_table_loaders) -> mnesia_monitor:get_env(no_table_loaders);
system_info2(dc_dump_limit) -> mnesia_monitor:get_env(dc_dump_limit);
+system_info2(send_compressed) -> mnesia_monitor:get_env(send_compressed);
system_info2(Item) -> exit({badarg, Item}).
@@ -2244,6 +2245,7 @@ system_info_items(yes) ->
core_dir,
no_table_loaders,
dc_dump_limit,
+ send_compressed,
version
];
system_info_items(no) ->
diff --git a/lib/mnesia/src/mnesia_loader.erl b/lib/mnesia/src/mnesia_loader.erl
index 77c317abc5..3de329503e 100644
--- a/lib/mnesia/src/mnesia_loader.erl
+++ b/lib/mnesia/src/mnesia_loader.erl
@@ -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%
%%
@@ -438,6 +438,9 @@ make_table_fun(Pid, TabRec) ->
get_data(Pid, TabRec) ->
receive
+ {Pid, {more_z, CompressedRecs}} when is_binary(CompressedRecs) ->
+ Pid ! {TabRec, more},
+ {zlib_uncompress(CompressedRecs), make_table_fun(Pid,TabRec)};
{Pid, {more, Recs}} ->
Pid ! {TabRec, more},
{Recs, make_table_fun(Pid,TabRec)};
@@ -769,6 +772,27 @@ dets_bchunk(Tab, Chunk) -> %% Arrg
Else -> Else
end.
+zlib_compress(Data, Level) ->
+ BinData = term_to_binary(Data),
+ Z = zlib:open(),
+ zlib:deflateInit(Z, Level),
+ Bs = zlib:deflate(Z, BinData, finish),
+ zlib:deflateEnd(Z),
+ zlib:close(Z),
+ list_to_binary(Bs).
+
+zlib_uncompress(Data) when is_binary(Data) ->
+ binary_to_term(zlib:uncompress(Data)).
+
+compression_level() ->
+ NoCompression = 0,
+ case ?catch_val(send_compressed) of
+ {'EXIT', _} ->
+ mnesia_lib:set(send_compressed, NoCompression),
+ NoCompression;
+ Val -> Val
+ end.
+
send_packet(N, Pid, _Chunk, '$end_of_table', OldNode) ->
case OldNode of
true -> ignore; %% Old nodes can't handle the new no_more
@@ -779,8 +803,15 @@ send_packet(N, Pid, Chunk, {[], Cont}, OldNode) ->
send_packet(N, Pid, Chunk, Chunk(Cont), OldNode);
send_packet(N, Pid, Chunk, {Recs, Cont}, OldNode) when N < ?MAX_NOPACKETS ->
case OldNode of
- true -> Pid ! {self(), {more, [Recs]}}; %% Old need's wrapping list
- false -> Pid ! {self(), {more, Recs}}
+ true ->
+ Pid ! {self(), {more, [Recs]}}; %% Old need's wrapping list
+ false ->
+ case compression_level() of
+ 0 ->
+ Pid ! {self(), {more, Recs}};
+ Level ->
+ Pid ! {self(), {more_z, zlib_compress(Recs, Level)}}
+ end
end,
send_packet(N+1, Pid, Chunk, Chunk(Cont), OldNode);
send_packet(_N, _Pid, _Chunk, DataState, _OldNode) ->
diff --git a/lib/mnesia/src/mnesia_monitor.erl b/lib/mnesia/src/mnesia_monitor.erl
index 05ae943e3b..5df5df4969 100644
--- a/lib/mnesia/src/mnesia_monitor.erl
+++ b/lib/mnesia/src/mnesia_monitor.erl
@@ -1,19 +1,19 @@
%%
%% %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
%% 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%
%%
@@ -497,7 +497,7 @@ handle_cast({mnesia_down, mnesia_locker, Node}, State) ->
process_q(State3);
false ->
%% No pending remote monitors
- {noreply, State2}
+ process_q(State2)
end;
handle_cast({disconnect, Node}, State) ->
@@ -674,7 +674,8 @@ env() ->
core_dir,
pid_sort_order,
no_table_loaders,
- dc_dump_limit
+ dc_dump_limit,
+ send_compressed
].
default_env(access_module) ->
@@ -717,7 +718,9 @@ default_env(pid_sort_order) ->
default_env(no_table_loaders) ->
2;
default_env(dc_dump_limit) ->
- 4.
+ 4;
+default_env(send_compressed) ->
+ 0.
check_type(Env, Val) ->
case catch do_check_type(Env, Val) of
@@ -763,7 +766,8 @@ do_check_type(pid_sort_order, standard) -> standard;
do_check_type(pid_sort_order, "standard") -> standard;
do_check_type(pid_sort_order, _) -> false;
do_check_type(no_table_loaders, N) when is_integer(N), N > 0 -> N;
-do_check_type(dc_dump_limit,N) when is_number(N), N > 0 -> N.
+do_check_type(dc_dump_limit,N) when is_number(N), N > 0 -> N;
+do_check_type(send_compressed, L) when is_integer(L), L >= 0, L =< 9 -> L.
bool(true) -> true;
bool(false) -> false.
diff --git a/lib/mnesia/src/mnesia_tm.erl b/lib/mnesia/src/mnesia_tm.erl
index 3f3a10a9c1..d42109c3da 100644
--- a/lib/mnesia/src/mnesia_tm.erl
+++ b/lib/mnesia/src/mnesia_tm.erl
@@ -1,19 +1,19 @@
%%
%% %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
%% 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%
%%
@@ -1389,6 +1389,7 @@ multi_commit(sync_sym_trans, Tid, CR, Store) ->
{Outcome, []} = rec_all(WaitFor, Tid, do_commit, []),
?eval_debug_fun({?MODULE, multi_commit_sym_sync},
[{tid, Tid}, {outcome, Outcome}]),
+ [?ets_insert(Store, {waiting_for_commit_ack, Node}) || Node <- WaitFor],
rpc:abcast(DiscNs -- [node()], ?MODULE, {Tid, Outcome}),
rpc:abcast(RamNs -- [node()], ?MODULE, {Tid, Outcome}),
case Outcome of
diff --git a/lib/mnesia/test/Makefile b/lib/mnesia/test/Makefile
new file mode 100644
index 0000000000..a4f32e3f78
--- /dev/null
+++ b/lib/mnesia/test/Makefile
@@ -0,0 +1,118 @@
+#
+# %CopyrightBegin%
+#
+# Copyright Ericsson AB 1996-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= \
+ mt \
+ mnesia_SUITE \
+ mnesia_test_lib \
+ mnesia_install_test \
+ mnesia_registry_test \
+ mnesia_config_test \
+ mnesia_frag_test \
+ mnesia_inconsistent_database_test \
+ mnesia_config_backup \
+ mnesia_config_event \
+ mnesia_examples_test \
+ mnesia_nice_coverage_test \
+ mnesia_evil_coverage_test \
+ mnesia_evil_backup \
+ mnesia_trans_access_test \
+ mnesia_dirty_access_test \
+ mnesia_atomicity_test \
+ mnesia_consistency_test \
+ mnesia_isolation_test \
+ mnesia_durability_test \
+ mnesia_recovery_test \
+ mnesia_qlc_test \
+ mnesia_schema_recovery_test \
+ mnesia_measure_test \
+ mnesia_cost \
+ mnesia_dbn_meters
+
+MnesiaExamplesDir := ../examples
+
+ExampleModules = \
+ company \
+ company_o \
+ bup \
+ mnesia_meter \
+ mnesia_tpcb
+ExamplesHrl = \
+ company.hrl \
+ company_o.hrl
+
+ERL_FILES= $(MODULES:%=%.erl) $(ExampleModules:%=$(MnesiaExamplesDir)/%.erl)
+
+HRL_FILES= mnesia_test_lib.hrl $(ExamplesHrl:%=$(MnesiaExamplesDir)/%)
+
+TARGET_FILES= \
+ $(MODULES:%=$(EBIN)/%.$(EMULATOR)) $(ExampleModules:%=$(EBIN)/%.$(EMULATOR))
+
+INSTALL_PROGS= $(TARGET_FILES)
+
+# ----------------------------------------------------
+# Release directory specification
+# ----------------------------------------------------
+RELSYSDIR = $(RELEASE_PATH)/mnesia_test
+
+# ----------------------------------------------------
+# FLAGS
+# ----------------------------------------------------
+#ERL_COMPILE_FLAGS +=
+
+EBIN = .
+
+# ----------------------------------------------------
+# Targets
+# ----------------------------------------------------
+
+tests debug opt: $(TARGET_FILES)
+
+$(EBIN)/%.beam: $(MnesiaExamplesDir)/%.erl
+ $(ERLC) -bbeam $(ERL_COMPILE_FLAGS) -o$(EBIN) $<
+
+clean:
+ rm -f $(TARGET_FILES)
+ rm -f core
+
+docs:
+
+# ----------------------------------------------------
+# Release Target
+# ----------------------------------------------------
+include $(ERL_TOP)/make/otp_release_targets.mk
+
+release_spec: opt
+
+release_tests_spec: opt
+ $(INSTALL_DIR) $(RELSYSDIR)
+ $(INSTALL_DATA) mnesia.spec mnesia.spec.vxworks $(ERL_FILES) $(HRL_FILES) $(RELSYSDIR)
+ $(INSTALL_PROGRAM) mt $(INSTALL_PROGS) $(RELSYSDIR)
+# chmod -f -R u+w $(RELSYSDIR)
+# @tar cf - *_SUITE_data | (cd $(RELSYSDIR); tar xf -)
+
+release_docs_spec:
+
+
diff --git a/lib/mnesia/test/README b/lib/mnesia/test/README
new file mode 100644
index 0000000000..e0ced7399d
--- /dev/null
+++ b/lib/mnesia/test/README
@@ -0,0 +1,107 @@
+This directory contains the test suite of Mnesia.
+Compile it with "erl -make".
+
+Test cases are identified with a {Mod, Fun} tuple that maps
+to a function Mod:Fun(Config), where the test case hopefully
+is implemented. The test suite is organized in a hierarchy
+with {mnesia_SUITE, all} as the top.
+
+The module called mt, implements various convenience functions
+to ease up the execution of test cases. It does also provide
+aliases for some test cases. For example the atom Mod is an
+alias for {Mod, all}, the atom all for {mnesia_SUITE, all},
+evil for mnesia_evil_coverage_test etc.
+
+ mt:struct(TestCase)
+
+ Displays the test case structure from TestCase
+ and downwards the hierarchy. E.g. mt:struct(all)
+ will display the entire test suite.
+
+ mt:t(TestCase), mt:t(TestCase, Config)
+
+ Runs a single test case or a hierarchy of test cases.
+ mt:t(silly) is be a good starter, but you may also
+ try mt:t(all) directly if you feel lucky.
+
+ The identity of the last run test case and the outcome of
+ it is stored on file. mt:t() will re-run the last test case.
+
+ The Config argument contains various configuration
+ parameters for the test cases, such as which nodes that
+ are available for running the test suite. The default
+ settings should be enough for the most. Use mt:read_config()
+ to get the current default setting and change it with
+ mt:write_config(Config).
+
+ mt:doc(TestCase)
+
+ Generates html documentation for the test suite.
+
+In order to be able to run the test suite, the Erlang node must
+be started with the distribution enabled and the code path must
+be set to the mnesia/ebin, mnesia/examples, and mnesia/test
+directories. E.g. the following would do:
+
+ erl -sname a -pa $top/examples -pa $top/src -pa $top/ebin
+
+where $top is the path to the Mnesia installation. Many test
+cases needs 2 or 3 nodes. The node names may explicitly be
+stated as test suite configuration parameters, but by default
+the extra node names are generated. In this example the names
+will be: a, a1 and a2. It is enough to start the first node
+manually, the extra nodes will automatically be started if
+neccessary.
+
+The attached UNIX shell script mt, does not work on all
+platforms, but it may be used as a source for inspiration. It
+starts three Erlang nodes in one xterm's each. The main xterm
+(a@localhost) logs all output in the Erlang shell to a
+file. The file is piped thru grep to easily find successful
+test cases (i.e. test cases that encountered an error).
+
+During development we want to be able to run the test cases
+in the debugger. This demands a little bit of preparations:
+
+ - Start the neccessary number of nodes (normally 3).
+ This may either be done by running the mt script or
+ by starting the main node and then invoke mt:start_nodes()
+ to start the extra nodes with slave.
+
+ - Ensure that the nodes are connected. The easiest way to do
+ this is by invoking mt:ping().
+
+ - Load all files that needs to be interpreted. This is typically
+ all Mnesia files plus the test case. By invoking mnesia:ni()
+ and mnesia:ni([TestModule]) the neccessary modules will be
+ loaded on all CONNECTED nodes.
+
+The test case execution is supervised in order to ensure that no test
+case exceeds its maximum time limit, which by default is 5 minutes.
+When the limit is reached, the running test case gets aborted and the
+test server runs the next test case in line. This behaviour is useful
+when running the entire test suite during the night, but it is really
+annoying during debugging.
+
+ Use the "erl -mnesia_test_timeout" flag to disable the test case
+ time limit mechanism.
+
+Some mechanisms in Mnesia are almost impossible to test with a
+white box technique. In order to be able to write predictable
+test cases which tests the same thing every time it is run,
+Mnesia has been instrumented with debug functions. These may be
+controlled from a test program. For example to verify that the
+commit protocols work it is essential that it is possible to
+ensure that we are able to kill Mnesia in the most critical
+situations. Normally Mnesia is compiled with the debug
+functions disabled and this means that test cases which
+requires this functionality will be skipped. The mnesia:ni(),
+mentioned above, functions ensures that the interpreted code is
+instrumented with Mnesia's debug functionality. The mnesia:nc()
+functions compiles Mnesia with the debug setting enabled.
+
+Happy bug hunting!
+
+ Hakan Mattsson <[email protected]>
+
+
diff --git a/lib/mnesia/test/mnesia.spec b/lib/mnesia/test/mnesia.spec
new file mode 100644
index 0000000000..596f8b917d
--- /dev/null
+++ b/lib/mnesia/test/mnesia.spec
@@ -0,0 +1,23 @@
+{topcase, {dir, "../mnesia_test"}}.
+{require_nodenames, 2}.
+{skip, {mnesia_measure_test, ram_meter, "Takes to long time"}}.
+{skip, {mnesia_measure_test, disc_meter, "Takes to long time"}}.
+{skip, {mnesia_measure_test, disc_only_meter, "Takes to long time"}}.
+{skip, {mnesia_measure_test, cost, "Takes to long time"}}.
+{skip, {mnesia_measure_test, dbn_meters, "Takes to long time"}}.
+{skip, {mnesia_measure_test, tpcb, "Takes to long time"}}.
+{skip, {mnesia_measure_test, prediction, "Not yet implemented"}}.
+{skip, {mnesia_measure_test, consumption, "Not yet implemented"}}.
+{skip, {mnesia_measure_test, scalability, "Not yet implemented"}}.
+{skip, {mnesia_measure_test, tpcb, "Takes too much time and memory"}}.
+{skip, {mnesia_measure_test, measure_all_api_functions, "Not yet implemented"}}.
+{skip, {mnesia_measure_test, mnemosyne_vs_mnesia_kernel, "Not yet implemented"}}.
+{skip, {mnesia_examples_test, company, "Not yet implemented"}}.
+{skip, {mnesia_config_test, ignore_fallback_at_startup, "Not yet implemented"}}.
+{skip, {mnesia_evil_backup, local_backup_checkpoint, "Not yet implemented"}}.
+{skip, {mnesia_config_test, max_wait_for_decision, "Not yet implemented"}}.
+{skip, {mnesia_recovery_test, after_full_disc_partition, "Not yet implemented"}}.
+{skip, {mnesia_recovery_test, system_upgrade, "Not yet implemented"}}.
+{skip, {mnesia_consistency_test, consistency_after_change_table_copy_type, "Not yet implemented"}}.
+{skip, {mnesia_consistency_test, consistency_after_transform_table, "Not yet implemented"}}.
+{skip, {mnesia_consistency_test, consistency_after_rename_of_node, "Not yet implemented"}}.
diff --git a/lib/mnesia/test/mnesia.spec.vxworks b/lib/mnesia/test/mnesia.spec.vxworks
new file mode 100644
index 0000000000..11c01ea3fe
--- /dev/null
+++ b/lib/mnesia/test/mnesia.spec.vxworks
@@ -0,0 +1,362 @@
+{topcase, {dir, "../mnesia_test"}}.
+{require_nodenames, 3}.
+{diskless, true}.
+{skip, {mnesia_measure_test, all, "Too heavy"}}.
+%{mnesia_install_test, silly_durability} 'IMPL'
+%{mnesia_install_test, silly_move} 'IMPL'
+{skip, {mnesia_install_test, silly_upgrade, "Uses disk"}}.
+%{mnesia_install_test, conflict} 'IMPL'
+%{mnesia_install_test, dist} 'IMPL'
+{skip, {mnesia_examples_test, all, "Uses disk"}}.
+{skip, {mnesia_nice_coverage_test, all, "Uses disk"}}.
+
+%{mnesia_evil_coverage_test, system_info} 'IMPL'
+%{mnesia_evil_coverage_test, table_info} 'IMPL'
+%{mnesia_evil_coverage_test, error_description} 'IMPL'
+{skip, {mnesia_evil_coverage_test, db_node_lifecycle, "Uses disk"}}.
+{skip, {mnesia_evil_coverage_test, local_content, "Uses disk"}}.
+%{mnesia_evil_coverage_test, start_and_stop} 'IMPL'
+%{mnesia_evil_coverage_test, transaction} 'IMPL'
+{skip, {mnesia_evil_coverage_test, checkpoint, "Uses disk"}}.
+{skip, {mnesia_evil_backup, backup, "Uses disk"}}.
+{skip, {mnesia_evil_backup, global_backup_checkpoint, "Uses disk"}}.
+{skip, {mnesia_evil_backup, incremental_backup_checkpoint, "Uses disk"}}.
+{skip, {mnesia_evil_backup, local_backup_checkpoint, "Uses disk"}}.
+{skip, {mnesia_evil_backup, selective_backup_checkpoint, "Uses disk"}}.
+{skip, {mnesia_evil_backup, restore_errors, "Uses disk"}}.
+{skip, {mnesia_evil_backup, restore_clear, "Uses disk"}}.
+{skip, {mnesia_evil_backup, restore_keep, "Uses disk"}}.
+{skip, {mnesia_evil_backup, restore_recreate, "Uses disk"}}.
+{skip, {mnesia_evil_backup, traverse_backup, "Uses disk"}}.
+{skip, {mnesia_evil_backup, install_fallback, "Uses disk"}}.
+{skip, {mnesia_evil_backup, uninstall_fallback, "Uses disk"}}.
+{skip, {mnesia_evil_backup, local_fallback, "Uses disk"}}.
+%{mnesia_evil_coverage_test, table_lifecycle} 'IMPL'
+{skip, {mnesia_evil_coverage_test, replica_management, "Uses disk"}}.
+%{mnesia_evil_coverage_test, change_table_access_mode} 'IMPL'
+%{mnesia_evil_coverage_test, change_table_load_order} 'IMPL'
+{skip, {mnesia_evil_coverage_test, set_master_nodes, "Uses disk"}}.
+{skip, {mnesia_evil_coverage_test, offline_set_master_nodes, "Uses disk"}}.
+{skip, {mnesia_evil_coverage_test, replica_location, "Uses disk"}}.
+%{mnesia_evil_coverage_test, add_table_index_ram} 'IMPL'
+{skip, {mnesia_trans_access_test, add_table_index_disc, "Uses disc"}}.
+{skip, {mnesia_trans_access_test, add_table_index_disc_only, "Uses disc"}}.
+%{mnesia_evil_coverage_test, create_live_table_index_ram} 'IMPL'
+{skip, {mnesia_trans_access_test, create_live_table_index_disc, "Uses disc"}}.
+{skip, {mnesia_trans_access_test, create_live_table_index_disc_only, "Uses disc"}}.
+%{mnesia_evil_coverage_test, del_table_index_ram} 'IMPL'
+{skip, {mnesia_trans_access_test, del_table_index_disc, "Uses disc"}}.
+{skip, {mnesia_trans_access_test, del_table_index_disc_only, "Uses disc"}}.
+{skip, {mnesia_trans_access_test, idx_schema_changes_ram, "Uses disk"}}.
+{skip, {mnesia_trans_access_test, idx_schema_changes_disc, "Uses disc"}}.
+{skip, {mnesia_trans_access_test, idx_schema_changes_disc_only, "Uses disc"}}.
+%{mnesia_dirty_access_test, dirty_write_ram} 'IMPL'
+
+{skip, {mnesia_dirty_access_test, dirty_write_disc, "Uses disc"}}.
+{skip, {mnesia_dirty_access_test, dirty_write_disc_only, "Uses disc"}}.
+%{mnesia_dirty_access_test, dirty_read_ram} 'IMPL'
+{skip, {mnesia_dirty_access_test, dirty_read_disc, "Uses disc"}}.
+{skip, {mnesia_dirty_access_test, dirty_read_disc_only, "Uses disc"}}.
+%{mnesia_dirty_access_test, dirty_update_counter_ram} 'IMPL'
+{skip, {mnesia_dirty_access_test, dirty_update_counter_disc, "Uses disc"}}.
+{skip, {mnesia_dirty_access_test, dirty_update_counter_disc_only, "Uses disc"}}.
+%{mnesia_dirty_access_test, dirty_delete_ram} 'IMPL'
+{skip, {mnesia_dirty_access_test, dirty_delete_disc, "Uses disc"}}.
+{skip, {mnesia_dirty_access_test, dirty_delete_disc_only, "Uses disc"}}.
+%{mnesia_dirty_access_test, dirty_delete_object_ram} 'IMPL'
+{skip, {mnesia_dirty_access_test, dirty_delete_object_disc, "Uses disc"}}.
+{skip, {mnesia_dirty_access_test, dirty_delete_object_disc_only, "Uses disc"}}.
+%{mnesia_dirty_access_test, dirty_match_object_ram} 'IMPL'
+{skip, {mnesia_dirty_access_test, dirty_match_object_disc, "Uses disc"}}.
+{skip, {mnesia_dirty_access_test, dirty_match_object_disc_only, "Uses disc"}}.
+%{mnesia_dirty_access_test, dirty_index_match_object_ram} 'IMPL'
+{skip, {mnesia_dirty_access_test, dirty_index_match_object_disc, "Uses disc"}}.
+{skip, {mnesia_dirty_access_test, dirty_index_match_object_disc_only, "Uses disc"}}.
+%{mnesia_dirty_access_test, dirty_index_read_ram} 'IMPL'
+{skip, {mnesia_dirty_access_test, dirty_index_read_disc, "Uses disc"}}.
+{skip, {mnesia_dirty_access_test, dirty_index_read_disc_only, "Uses disc"}}.
+%{mnesia_dirty_access_test, dirty_index_update_set_ram} 'IMPL'
+{skip, {mnesia_dirty_access_test, dirty_index_update_set_disc, "Uses disc"}}.
+{skip, {mnesia_dirty_access_test, dirty_index_update_set_disc_only, "Uses disc"}}.
+%{mnesia_dirty_access_test, dirty_index_update_bag_ram} 'IMPL'
+{skip, {mnesia_dirty_access_test, dirty_index_update_bag_disc, "Uses disc"}}.
+{skip, {mnesia_dirty_access_test, dirty_index_update_bag_disc_only, "Uses disc"}}.
+%{mnesia_dirty_access_test, dirty_iter_ram} 'IMPL'
+{skip, {mnesia_dirty_access_test, dirty_iter_disc, "Uses disc"}}.
+{skip, {mnesia_dirty_access_test, dirty_iter_disc_only, "Uses disc"}}.
+{skip, {mnesia_dirty_access_test, admin_tests, "Uses disk"}}.
+
+%{mnesia_trans_access_test, write} 'IMPL'
+%{mnesia_trans_access_test, read} 'IMPL'
+%{mnesia_trans_access_test, wread} 'IMPL'
+%{mnesia_trans_access_test, delete} 'IMPL'
+%{mnesia_trans_access_test, delete_object} 'IMPL'
+%{mnesia_trans_access_test, match_object} 'IMPL'
+%{mnesia_trans_access_test, all_keys} 'IMPL'
+%{mnesia_trans_access_test, index_match_object} 'IMPL'
+%{mnesia_trans_access_test, index_read} 'IMPL'
+%{mnesia_trans_access_test, index_update_set} 'IMPL'
+%{mnesia_trans_access_test, index_update_bag} 'IMPL'
+{skip, {mnesia_evil_coverage_test, dump_tables, "Uses disk"}}.
+{skip, {mnesia_evil_coverage_test, dump_log, "Uses disk"}}.
+%{mnesia_evil_coverage_test, wait_for_tables} 'IMPL'
+{skip, {mnesia_evil_coverage_test, force_load_table, "Uses disk"}}.
+%{mnesia_evil_coverage_test, user_properties} 'IMPL'
+%{mnesia_evil_coverage_test, record_name_dirty_access_ram} 'IMPL'
+{skip, {mnesia_evil_coverage_test, record_name_dirty_access_disc, "Uses disc"}}.
+{skip, {mnesia_evil_coverage_test, record_name_dirty_access_disc_only, "Uses disc"}}.
+%{mnesia_evil_coverage_test, snmp_open_table} 'IMPL'
+%{mnesia_evil_coverage_test, snmp_close_table} 'IMPL'
+%{mnesia_evil_coverage_test, snmp_get_next_index} 'IMPL'
+%{mnesia_evil_coverage_test, snmp_get_row} 'IMPL'
+%{mnesia_evil_coverage_test, snmp_get_mnesia_key} 'IMPL'
+%{mnesia_evil_coverage_test, snmp_update_counter} 'IMPL'
+%{mnesia_evil_coverage_test, info} 'IMPL'
+%{mnesia_evil_coverage_test, schema_0} 'IMPL'
+%{mnesia_evil_coverage_test, schema_1} 'IMPL'
+%{mnesia_evil_coverage_test, view_0} 'IMPL'
+{skip, {mnesia_evil_coverage_test, view_1, "Uses disk"}}.
+{skip, {mnesia_evil_coverage_test, view_2, "Uses disk"}}.
+%{mnesia_evil_coverage_test, lkill} 'IMPL'
+%{mnesia_evil_coverage_test, kill} 'IMPL'
+
+%{mnesia_config_test, access_module} 'IMPL'
+%{mnesia_config_test, auto_repair} 'IMPL'
+{skip, {mnesia_config_test, backup_module, "Uses disk"}}.
+{skip, {mnesia_config_test, dynamic_connect, "Uses disk"}}.
+%{mnesia_config_test, debug} 'IMPL'
+%{mnesia_config_test, dir} 'IMPL'
+{skip, {mnesia_config_test, dump_log_load_regulation, "Uses disk"}}.
+{skip, {mnesia_config_test, dump_log_time_threshold, "Uses disk"}}.
+{skip, {mnesia_config_test, dump_log_write_threshold, "Uses disk"}}.
+{skip, {mnesia_config_test, dump_log_update_in_place, "Uses disk"}}.
+{skip, {mnesia_config_test, embedded_mnemosyne, "Uses Mnemosyne"}}.
+%{mnesia_config_test, event_module} 'IMPL'
+{skip, {mnesia_config_test, ignore_fallback_at_startup, "Not Yet impl"}}.
+%{mnesia_config_test, inconsistent_database} 'IMPL'
+{skip, {mnesia_config_test, max_wait_for_decision, "Not Yet impl"}}.
+{skip, {mnesia_config_test, start_one_disc_full_then_one_disc_less, "Uses disc"}}.
+{skip, {mnesia_config_test, start_first_one_disc_less_then_one_disc_full, "Uses disc"}}.
+%%{skip, {mnesia_config_test, start_first_one_disc_less_then_two_more_disc_less, "Uses disc"}}.
+{skip, {mnesia_config_test, schema_location_and_extra_db_nodes_combinations, "Uses disk"}}.
+{skip, {mnesia_config_test, table_load_to_disc_less_nodes, "Uses disc"}}.
+{skip, {mnesia_config_test, schema_merge, "Uses Disc"}}.
+%{mnesia_config_test, unknown_config} 'IMPL'
+%{mnesia_registry_test, good_dump} 'IMPL'
+%{mnesia_registry_test, bad_dump} 'IMPL'
+
+%{mnesia_atomicity_test, explicit_abort_in_middle_of_trans} 'IMPL'
+%{mnesia_atomicity_test, runtime_error_in_middle_of_trans} 'IMPL'
+%{mnesia_atomicity_test, kill_self_in_middle_of_trans} 'IMPL'
+%{mnesia_atomicity_test, throw_in_middle_of_trans} 'IMPL'
+%{mnesia_atomicity_test, mnesia_down_during_infinite_trans} 'IMPL'
+%{mnesia_atomicity_test, lock_waiter_sw_rt} 'IMPL'
+%{mnesia_atomicity_test, lock_waiter_sw_wt} 'IMPL'
+%{mnesia_atomicity_test, lock_waiter_wr_r} 'IMPL'
+%{mnesia_atomicity_test, lock_waiter_sw_sw} 'IMPL'
+%{mnesia_atomicity_test, lock_waiter_sw_w} 'IMPL'
+%{mnesia_atomicity_test, lock_waiter_sw_wr} 'IMPL'
+%{mnesia_atomicity_test, lock_waiter_wr_wt} 'IMPL'
+%{mnesia_atomicity_test, lock_waiter_wr_sw} 'IMPL'
+%{mnesia_atomicity_test, lock_waiter_wr_w} 'IMPL'
+%{mnesia_atomicity_test, lock_waiter_r_sw} 'IMPL'
+%{mnesia_atomicity_test, lock_waiter_r_w} 'IMPL'
+%{mnesia_atomicity_test, lock_waiter_r_wt} 'IMPL'
+%{mnesia_atomicity_test, lock_waiter_rt_sw} 'IMPL'
+%{mnesia_atomicity_test, lock_waiter_rt_w} 'IMPL'
+%{mnesia_atomicity_test, lock_waiter_rt_wt} 'IMPL'
+%{mnesia_atomicity_test, lock_waiter_wt_r} 'IMPL'
+%{mnesia_atomicity_test, lock_waiter_wt_w} 'IMPL'
+%{mnesia_atomicity_test, lock_waiter_wt_rt} 'IMPL'
+%{mnesia_atomicity_test, lock_waiter_wt_wt} 'IMPL'
+%{mnesia_atomicity_test, lock_waiter_wt_wr} 'IMPL'
+%{mnesia_atomicity_test, lock_waiter_wt_sw} 'IMPL'
+%{mnesia_atomicity_test, lock_waiter_w_wr} 'IMPL'
+%{mnesia_atomicity_test, lock_waiter_w_sw} 'IMPL'
+%{mnesia_atomicity_test, lock_waiter_w_r} 'IMPL'
+%{mnesia_atomicity_test, lock_waiter_w_w} 'IMPL'
+%{mnesia_atomicity_test, lock_waiter_w_rt} 'IMPL'
+%{mnesia_atomicity_test, lock_waiter_w_wt} 'IMPL'
+%{mnesia_atomicity_test, restart_r_one} 'IMPL'
+%{mnesia_atomicity_test, restart_w_one} 'IMPL'
+%{mnesia_atomicity_test, restart_rt_one} 'IMPL'
+%{mnesia_atomicity_test, restart_wt_one} 'IMPL'
+%{mnesia_atomicity_test, restart_wr_one} 'IMPL'
+%{mnesia_atomicity_test, restart_sw_one} 'IMPL'
+%{mnesia_atomicity_test, restart_r_two} 'IMPL'
+%{mnesia_atomicity_test, restart_w_two} 'IMPL'
+%{mnesia_atomicity_test, restart_rt_two} 'IMPL'
+%{mnesia_atomicity_test, restart_wt_two} 'IMPL'
+%{mnesia_atomicity_test, restart_wr_two} 'IMPL'
+%{mnesia_atomicity_test, restart_sw_two} 'IMPL'
+
+%{mnesia_isolation_test, no_conflict} 'IMPL'
+%{mnesia_isolation_test, simple_queue_conflict} 'IMPL'
+%{mnesia_isolation_test, advanced_queue_conflict} 'IMPL'
+%{mnesia_isolation_test, simple_deadlock_conflict} 'IMPL'
+%{mnesia_isolation_test, advanced_deadlock_conflict} 'IMPL'
+%{mnesia_isolation_test, lock_burst} 'IMPL'
+%{mnesia_isolation_test, basic_sticky_functionality} 'IMPL'
+%{mnesia_isolation_test, create_table} 'IMPL'
+%{mnesia_isolation_test, delete_table} 'IMPL'
+%{mnesia_isolation_test, move_table_copy} 'IMPL'
+%{mnesia_isolation_test, add_table_index} 'IMPL'
+%{mnesia_isolation_test, del_table_index} 'IMPL'
+%{mnesia_isolation_test, transform_table} 'IMPL'
+%{mnesia_isolation_test, snmp_open_table} 'IMPL'
+%{mnesia_isolation_test, snmp_close_table} 'IMPL'
+{skip, {mnesia_isolation_test, change_table_copy_type, "Uses disk"}}.
+%{mnesia_isolation_test, change_table_access} 'IMPL'
+%{mnesia_isolation_test, add_table_copy} 'IMPL'
+%{mnesia_isolation_test, del_table_copy} 'IMPL'
+{skip, {mnesia_isolation_test, dump_tables, "Uses disk"}}.
+{skip, {mnesia_isolation_test, extra_admin_tests, "Uses disk"}}.
+%{mnesia_isolation_test, del_table_copy_1} 'IMPL'
+%{mnesia_isolation_test, del_table_copy_2} 'IMPL'
+%{mnesia_isolation_test, del_table_copy_3} 'IMPL'
+%{mnesia_isolation_test, add_table_copy_1} 'IMPL'
+%{mnesia_isolation_test, add_table_copy_2} 'IMPL'
+%{mnesia_isolation_test, add_table_copy_3} 'IMPL'
+%{mnesia_isolation_test, add_table_copy_4} 'IMPL'
+%{mnesia_isolation_test, move_table_copy_1} 'IMPL'
+%{mnesia_isolation_test, move_table_copy_2} 'IMPL'
+%{mnesia_isolation_test, move_table_copy_3} 'IMPL'
+%{mnesia_isolation_test, move_table_copy_4} 'IMPL'
+%{mnesia_isolation_test, dirty_updates_visible_direct} 'IMPL'
+%{mnesia_isolation_test, dirty_reads_regardless_of_trans} 'IMPL'
+%{mnesia_isolation_test, trans_update_invisibible_outside_trans} 'IMPL'
+%{mnesia_isolation_test, trans_update_visible_inside_trans} 'IMPL'
+%{mnesia_isolation_test, write_shadows} 'IMPL'
+%{mnesia_isolation_test, delete_shadows} 'IMPL'
+%{mnesia_isolation_test, write_delete_shadows_bag} 'IMPL'
+
+{skip, {mnesia_durability_test, all, "Uses disk "}}.
+%{mnesia_durability_test, load_local_contents_directly} 'IMPL'
+%{mnesia_durability_test, load_directly_when_all_are_ram_copiesA} 'IMPL'
+%{mnesia_durability_test, load_directly_when_all_are_ram_copiesB} 'IMPL'
+%{skip, {mnesia_durability_test, late_load_when_all_are_ram_copies_on_ram_nodes1, "Uses disk schema"}}.
+%{skip, {mnesia_durability_test, late_load_when_all_are_ram_copies_on_ram_nodes2, "Uses disk schema"}}.
+%{skip, {mnesia_durability_test, load_when_last_replica_becomes_available, "Uses disk"}}.
+%{skip, {mnesia_durability_test, load_when_we_have_down_from_all_other_replica_nodes, "Uses disk"}}.
+%{skip, {mnesia_durability_test, late_load_transforms_into_disc_load, "Uses disc"}}.
+%{mnesia_durability_test, late_load_leads_to_hanging} 'IMPL'
+%{mnesia_durability_test, force_load_when_nobody_intents_to_load} 'IMPL'
+%{mnesia_durability_test, force_load_when_someone_has_decided_to_load} 'IMPL'
+%{mnesia_durability_test, force_load_when_someone_else_already_has_loaded} 'IMPL'
+%{mnesia_durability_test, force_load_when_we_has_loaded} 'IMPL'
+%{mnesia_durability_test, force_load_on_a_non_local_table} 'IMPL'
+%{mnesia_durability_test, force_load_when_the_table_does_not_exist} 'IMPL'
+%{mnesia_durability_test, master_nodes} 'IMPL'
+%{mnesia_durability_test, master_on_non_local_tables} 'IMPL'
+%{mnesia_durability_test, remote_force_load_with_local_master_node} 'IMPL'
+%{mnesia_durability_test, dump_ram_copies} 'IMPL'
+%{skip, {mnesia_durability_test, dump_disc_copies, "Uses disc"}}.
+%{skip, {mnesia_durability_test, dump_disc_only, "Uses disc"}}.
+%{skip, {mnesia_durability_test, durability_of_disc_copies, "Uses disc"}}.
+%{skip, {mnesia_durability_test, durability_of_disc_only_copies, "Uses disc"}}.
+
+{skip, {mnesia_recovery_test, mnesia_down, "Uses Disk"}}.
+%{mnesia_recovery_test, no_master_2} 'IMPL'
+%{mnesia_recovery_test, no_master_3} 'IMPL'
+%{mnesia_recovery_test, one_master_2} 'IMPL'
+%{mnesia_recovery_test, one_master_3} 'IMPL'
+%{mnesia_recovery_test, two_master_2} 'IMPL'
+%{mnesia_recovery_test, two_master_3} 'IMPL'
+%{mnesia_recovery_test, all_master_2} 'IMPL'
+%{mnesia_recovery_test, all_master_3} 'IMPL'
+{skip, {mnesia_recovery_test, mnesia_down_during_startup_disk_ram, "Uses disk"}}.
+%{mnesia_recovery_test, mnesia_down_during_startup_init_ram} 'IMPL'
+{skip, {mnesia_recovery_test, mnesia_down_during_startup_init_disc, "Uses disc"}}.
+{skip, {mnesia_recovery_test, mnesia_down_during_startup_init_disc_only, "Uses disc"}}.
+%{mnesia_recovery_test, mnesia_down_during_startup_tm_ram} 'IMPL'
+{skip, {mnesia_recovery_test, mnesia_down_during_startup_tm_disc, "Uses disc"}}.
+{skip, {mnesia_recovery_test, mnesia_down_during_startup_tm_disc_only, "Uses disc"}}.
+%{mnesia_recovery_test, explicit_stop_during_snmp} 'IMPL'
+
+{skip, {mnesia_recovery_test, schema_trans, "Uses Disk, needs disk log"}}.
+{skip, {mnesia_recovery_test, async_dirty, "Uses disc"}}.
+{skip, {mnesia_recovery_test, sync_dirty, "Uses disc"}}.
+{skip, {mnesia_recovery_test, sym_trans, "Uses disc"}}.
+{skip, {mnesia_recovery_test, asym_trans, "Uses disc"}}.
+
+{skip, {mnesia_recovery_test, after_full_disc_partition, "Not Yet impl"}}.
+{skip, {mnesia_recovery_test, after_corrupt_files, "Uses disk"}}.
+
+%{mnesia_evil_coverage_test, subscriptions} 'IMPL'
+%{mnesia_evil_coverage_test, nested_trans_both_ok} 'IMPL'
+%{mnesia_evil_coverage_test, nested_trans_child_dies} 'IMPL'
+%{mnesia_evil_coverage_test, nested_trans_parent_dies} 'IMPL'
+%{mnesia_evil_coverage_test, nested_trans_both_dies} 'IMPL'
+%{mnesia_evil_coverage_test, mix_of_trans_sync_dirty} 'IMPL'
+%{mnesia_evil_coverage_test, mix_of_trans_async_dirty} 'IMPL'
+%{mnesia_evil_coverage_test, mix_of_trans_ets} 'IMPL'
+
+{skip, {mnesia_recovery_test, disc_less, "Uses disc (on the other nodes)"}}.
+{skip, {mnesia_recovery_test, system_upgrade, "Not Yet impl"}}.
+%{mnesia_consistency_test, consistency_after_restart_1_ram} 'IMPL'
+{skip, {mnesia_consistency_test, consistency_after_restart_1_disc, "Uses disc"}}.
+{skip, {mnesia_consistency_test, consistency_after_restart_1_disc_only, "Uses disc"}}.
+%{mnesia_consistency_test, consistency_after_restart_2_ram} 'IMPL'
+{skip, {mnesia_consistency_test, consistency_after_restart_2_disc, "Uses disc"}}.
+{skip, {mnesia_consistency_test, consistency_after_restart_2_disc_only, "Uses disc"}}.
+{skip, {mnesia_consistency_test, consistency_after_dump_tables_1_ram, "Uses disk"}}.
+{skip, {mnesia_consistency_test, consistency_after_dump_tables_2_ram, "Uses disk"}}.
+%{mnesia_consistency_test, consistency_after_add_replica_2_ram} 'IMPL'
+{skip, {mnesia_consistency_test, consistency_after_add_replica_2_disc, "Uses disc"}}.
+{skip, {mnesia_consistency_test, consistency_after_add_replica_2_disc_only, "Uses disc"}}.
+%{mnesia_consistency_test, consistency_after_add_replica_3_ram} 'IMPL'
+{skip, {mnesia_consistency_test, consistency_after_add_replica_3_disc, "Uses disc"}}.
+{skip, {mnesia_consistency_test, consistency_after_add_replica_3_disc_only, "Uses disc"}}.
+%{mnesia_consistency_test, consistency_after_del_replica_2_ram} 'IMPL'
+{skip, {mnesia_consistency_test, consistency_after_del_replica_2_disc, "Uses disc"}}.
+{skip, {mnesia_consistency_test, consistency_after_del_replica_2_disc_only, "Uses disc"}}.
+%{mnesia_consistency_test, consistency_after_del_replica_3_ram} 'IMPL'
+{skip, {mnesia_consistency_test, consistency_after_del_replica_3_disc, "Uses disc"}}.
+{skip, {mnesia_consistency_test, consistency_after_del_replica_3_disc_only, "Uses disc"}}.
+%{mnesia_consistency_test, consistency_after_move_replica_2_ram} 'IMPL'
+{skip, {mnesia_consistency_test, consistency_after_move_replica_2_disc, "Uses disc"}}.
+{skip, {mnesia_consistency_test, consistency_after_move_replica_2_disc_only, "Uses disc"}}.
+%{mnesia_consistency_test, consistency_after_move_replica_3_ram} 'IMPL'
+{skip, {mnesia_consistency_test, consistency_after_move_replica_3_disc, "Uses disc"}}.
+{skip, {mnesia_consistency_test, consistency_after_move_replica_3_disc_only, "Uses disc"}}.
+{skip, {mnesia_consistency_test, consistency_after_transform_table, "Not yet implemented"}}.
+{skip, {mnesia_consistency_test, consistency_after_change_table_copy_type, "Not yet implemented"}}.
+{skip, {mnesia_consistency_test, consistency_after_fallback_2_ram, "Uses disk"}}.
+{skip, {mnesia_consistency_test, consistency_after_fallback_2_disc, "Uses disc"}}.
+{skip, {mnesia_consistency_test, consistency_after_fallback_2_disc_only, "Uses disc"}}.
+{skip, {mnesia_consistency_test, consistency_after_fallback_3_ram, "Uses disk"}}.
+{skip, {mnesia_consistency_test, consistency_after_fallback_3_disc, "Uses disc"}}.
+{skip, {mnesia_consistency_test, consistency_after_fallback_3_disc_only, "Uses disc"}}.
+{skip, {mnesia_consistency_test, consistency_after_restore_clear_ram, "Uses disk"}}.
+{skip, {mnesia_consistency_test, consistency_after_restore_clear_disc, "Uses disc"}}.
+{skip, {mnesia_consistency_test, consistency_after_restore_clear_disc_only, "Uses disc"}}.
+{skip, {mnesia_consistency_test, consistency_after_restore_recreate_ram, "Uses disk"}}.
+{skip, {mnesia_consistency_test, consistency_after_restore_recreate_disc, "Uses disc"}}.
+{skip, {mnesia_consistency_test, consistency_after_restore_recreate_disc_only, "Uses disc"}}.
+{skip, {mnesia_consistency_test, consistency_after_rename_of_node, "Not yet implemented"}}.
+{skip, {mnesia_consistency_test, updates_during_checkpoint_activation, "Uses disk"}}.
+%{skip, {mnesia_consistency_test, updates_during_checkpoint_activation_2_disc, "Uses disc"}}.
+%{skip, {mnesia_consistency_test, updates_during_checkpoint_activation_2_disc_only, "Uses disc"}}.
+%%{mnesia_consistency_test, updates_during_checkpoint_activation_3_ram} 'IMPL'
+%{skip, {mnesia_consistency_test, updates_during_checkpoint_activation_3_disc, "Uses disc"}}.
+%{skip, {mnesia_consistency_test, updates_during_checkpoint_activation_3_disc_only, "Uses disc"}}.
+{skip, {mnesia_consistency_test, updates_during_checkpoint_iteration, "Uses disk"}}.
+%{skip, {mnesia_consistency_test, updates_during_checkpoint_iteration_2_disc, "Uses disc"}}.
+%{skip, {mnesia_consistency_test, updates_during_checkpoint_iteration_2_disc_only, "Uses disc"}}.
+{skip, {mnesia_consistency_test, load_table_with_activated_checkpoint_ram, "Uses disk"}}.
+{skip, {mnesia_consistency_test, load_table_with_activated_checkpoint_disc, "Uses disc"}}.
+{skip, {mnesia_consistency_test, load_table_with_activated_checkpoint_disc_only, "Uses disc"}}.
+{skip, {mnesia_consistency_test, add_table_copy_to_table_with_activated_checkpoint_ram, "Uses disk"}}.
+{skip, {mnesia_consistency_test, add_table_copy_to_table_with_activated_checkpoint_disc, "Uses disc"}}.
+{skip, {mnesia_consistency_test, add_table_copy_to_table_with_activated_checkpoint_disc_only, "Uses disc"}}.
+{skip, {mnesia_consistency_test, inst_fallback_process_dies, "Uses disk"}}.
+{skip, {mnesia_consistency_test, fatal_when_inconsistency, "Uses disk"}}.
+{skip, {mnesia_consistency_test, after_delete, "Uses disk"}}.
+{skip, {mnesia_consistency_test, mnesia_down_during_backup_causes_switch, "Uses disk"}}.
+{skip, {mnesia_consistency_test, mnesia_down_during_backup_causes_abort, "Uses disk"}}.
+%{mnesia_consistency_test, cause_switch_after} 'IMPL'
+%{mnesia_consistency_test, cause_abort_before} 'IMPL'
+%{mnesia_consistency_test, cause_abort_after} 'IMPL'
+%{mnesia_consistency_test, change_schema_before} 'IMPL'
+%{mnesia_consistency_test, change_schema_after} 'IMPL'
+
diff --git a/lib/mnesia/test/mnesia_SUITE.erl b/lib/mnesia/test/mnesia_SUITE.erl
new file mode 100644
index 0000000000..b28deaf330
--- /dev/null
+++ b/lib/mnesia/test/mnesia_SUITE.erl
@@ -0,0 +1,203 @@
+%%
+%% %CopyrightBegin%
+%%
+%% 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(mnesia_SUITE).
+-author('[email protected]').
+-compile([export_all]).
+-include("mnesia_test_lib.hrl").
+
+init_per_testcase(Func, Conf) ->
+ mnesia_test_lib:init_per_testcase(Func, Conf).
+
+fin_per_testcase(Func, Conf) ->
+ mnesia_test_lib:fin_per_testcase(Func, Conf).
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+all(doc) ->
+ ["Verify that Mnesia really is a distributed real-time DBMS",
+ "This is the test suite of the Mnesia DBMS. The test suite",
+ "covers many aspects of usage and is indended to be developed",
+ "incrementally. The test suite is divided into a hierarchy of test",
+ "suites where the leafs actually implements the test cases.",
+ "The intention of each test case and sub test suite can be",
+ "read in comments where they are implemented or in worst cases",
+ "from their long mnemonic names. ",
+ "",
+ "The most simple test case of them all is called 'silly'",
+ "and is useful to run now and then, e.g. when some new fatal",
+ "bug has been introduced. It may be run even if Mnesia is in",
+ "such a bad shape that the test machinery cannot be used.",
+ "NB! Invoke the function directly with mnesia_SUITE:silly()",
+ "and do not involve the normal test machinery."];
+all(suite) ->
+ [
+ light,
+ medium,
+ heavy,
+ clean_up_suite
+ ].
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+silly() ->
+ mnesia_install_test:silly().
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+light(doc) ->
+ ["The 'light' test suite runs a selected set of test suites and is",
+ "intended to be the smallest test suite that is meaningful",
+ "to run. It starts with an installation test (which in essence is the",
+ "'silly' test case) and then it covers all functions in the API in",
+ "various depths. All configuration parameters and examples are also",
+ "covered."];
+light(suite) ->
+ [
+ install,
+ nice,
+ evil,
+ {mnesia_frag_test, light},
+ qlc,
+ registry,
+ config,
+ examples
+ ].
+
+install(suite) ->
+ [{mnesia_install_test, all}].
+
+nice(suite) ->
+ [{mnesia_nice_coverage_test, all}].
+
+evil(suite) ->
+ [{mnesia_evil_coverage_test, all}].
+
+qlc(suite) ->
+ [{mnesia_qlc_test, all}].
+
+registry(suite) ->
+ [{mnesia_registry_test, all}].
+
+config(suite) ->
+ [{mnesia_config_test, all}].
+
+examples(suite) ->
+ [{mnesia_examples_test, all}].
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+medium(doc) ->
+ ["The 'medium' test suite verfies the ACID (atomicity, consistency",
+ "isolation and durability) properties and various recovery scenarios",
+ "These tests may take quite while to run."];
+medium(suite) ->
+ [
+ install,
+ atomicity,
+ isolation,
+ durability,
+ recovery,
+ consistency,
+ {mnesia_frag_test, medium}
+ ].
+
+atomicity(suite) ->
+ [{mnesia_atomicity_test, all}].
+
+isolation(suite) ->
+ [{mnesia_isolation_test, all}].
+
+durability(suite) ->
+ [{mnesia_durability_test, all}].
+
+recovery(suite) ->
+ [{mnesia_recovery_test, all}].
+
+consistency(suite) ->
+ [{mnesia_consistency_test, all}].
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+heavy(doc) ->
+ ["The 'heavy' test suite runs some resource consuming tests and",
+ "benchmarks"];
+heavy(suite) ->
+ [measure].
+
+measure(suite) ->
+ [{mnesia_measure_test, all}].
+
+prediction(suite) ->
+ [{mnesia_measure_test, prediction}].
+
+fairness(suite) ->
+ [{mnesia_measure_test, fairness}].
+
+benchmarks(suite) ->
+ [{mnesia_measure_test, benchmarks}].
+
+consumption(suite) ->
+ [{mnesia_measure_test, consumption}].
+
+scalability(suite) ->
+ [{mnesia_measure_test, scalability}].
+
+
+clean_up_suite(doc) -> ["Not a test case only kills mnesia and nodes, that where"
+ "started during the tests"];
+clean_up_suite(suite) ->
+ [];
+clean_up_suite(Config) when is_list(Config)->
+ mnesia:kill(),
+ Slaves = mnesia_test_lib:lookup_config(nodenames, Config),
+ Nodes = lists:delete(node(), Slaves),
+ rpc:multicall(Nodes, erlang, halt, []),
+ ok.
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+otp_r4b(doc) ->
+ ["This test suite is an extract of the grand Mnesia suite",
+ "it contains OTP R4B specific test cases"];
+otp_r4b(suite) ->
+ [
+ {mnesia_config_test, access_module},
+ {mnesia_config_test, dump_log_load_regulation},
+ {mnesia_config_test, embedded_mnemosyne},
+ {mnesia_config_test, ignore_fallback_at_startup},
+ {mnesia_config_test, max_wait_for_decision},
+ {mnesia_consistency_test, consistency_after_restore},
+ {mnesia_evil_backup, restore},
+ {mnesia_evil_coverage_test, offline_set_master_nodes},
+ {mnesia_evil_coverage_test, record_name},
+ {mnesia_evil_coverage_test, user_properties},
+ {mnesia_registry_test, all},
+ otp_2363
+ ].
+
+otp_2363(doc) ->
+ ["Index on disc only tables"];
+otp_2363(suite) ->
+ [
+ {mnesia_dirty_access_test, dirty_index_match_object_disc_only},
+ {mnesia_dirty_access_test,dirty_index_read_disc_only},
+ {mnesia_dirty_access_test,dirty_index_update_bag_disc_only},
+ {mnesia_dirty_access_test,dirty_index_update_set_disc_only},
+ {mnesia_evil_coverage_test, create_live_table_index_disc_only}
+ ].
+
+
+
diff --git a/lib/mnesia/test/mnesia_atomicity_test.erl b/lib/mnesia/test/mnesia_atomicity_test.erl
new file mode 100644
index 0000000000..645c203a91
--- /dev/null
+++ b/lib/mnesia/test/mnesia_atomicity_test.erl
@@ -0,0 +1,839 @@
+%%
+%% %CopyrightBegin%
+%%
+%% 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(mnesia_atomicity_test).
+-author('[email protected]').
+-author('[email protected]').
+-compile([export_all]).
+-include("mnesia_test_lib.hrl").
+
+init_per_testcase(Func, Conf) ->
+ mnesia_test_lib:init_per_testcase(Func, Conf).
+
+fin_per_testcase(Func, Conf) ->
+ mnesia_test_lib:fin_per_testcase(Func, Conf).
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+all(doc) ->
+ ["Verify atomicity of transactions",
+ "Verify that transactions are atomic, i.e. either all operations",
+ "in a transaction will be performed or none of them. It must be",
+ "assured that no partitially completed operations leaves any",
+ "effects in the database."];
+all(suite) ->
+ [
+ explicit_abort_in_middle_of_trans,
+ runtime_error_in_middle_of_trans,
+ kill_self_in_middle_of_trans,
+ throw_in_middle_of_trans,
+ mnesia_down_in_middle_of_trans
+ ].
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+explicit_abort_in_middle_of_trans(suite) -> [];
+explicit_abort_in_middle_of_trans(Config) when is_list(Config) ->
+ [Node1] = Nodes = ?acquire_nodes(1, Config),
+ Tab = explicit_abort_in_middle_of_trans,
+
+ Rec1A = {Tab, 1, a},
+ Rec1B = {Tab, 1, b},
+
+ ?match({atomic, ok}, mnesia:create_table([{name, Tab},
+ {ram_copies, [Node1]}])),
+ %% Start a transaction on one node
+ {success, [A]} = ?start_activities([Node1]),
+
+ %% store an object in the Tab - first tranaction
+ ?start_transactions([A]),
+ A ! fun() ->
+ mnesia:write(Rec1A) % returns ok when successful
+ end,
+ ?match_receive({A, ok}),
+ A ! end_trans,
+ ?match_receive({A, {atomic, end_trans}}),
+
+ %% second transaction: store some new objects and abort before the
+ %% transaction is finished -> the new changes should be invisable
+ ?start_transactions([A]),
+ A ! fun() ->
+ mnesia:write(Rec1B),
+ exit(abort_by_purpose) %does that stop the process A ???
+ end,
+ ?match_receive({A, {aborted, abort_by_purpose}}),
+
+
+ %?match_receive({A, {'EXIT', Pid, normal}}), % A died and sends EXIT
+
+
+ %% Start a second transactionprocess, after the first failed
+ {success, [B]} = ?start_activities([Node1]),
+
+ %% check, whether the interupted transaction had no influence on the db
+ ?start_transactions([B]),
+ B ! fun() ->
+ ?match([Rec1A], mnesia:read({Tab, 1})),
+ ok
+ end,
+ ?match_receive({B, ok}),
+ B ! end_trans,
+ ?match_receive({B, {atomic, end_trans}}),
+
+ ?verify_mnesia(Nodes, []).
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+runtime_error_in_middle_of_trans(suite) -> [];
+runtime_error_in_middle_of_trans(Config) when is_list(Config) ->
+ [Node1] = Nodes = ?acquire_nodes(1, Config),
+ Tab = runtime_error_in_middle_of_trans,
+
+ Rec1A = {Tab, 1, a},
+ Rec1B = {Tab, 1, b},
+ Rec1C = {Tab, 1, c},
+
+ ?match({atomic, ok}, mnesia:create_table([{name, Tab},
+ {ram_copies, [Node1]}])),
+ %% Start a transaction on one node
+ {success, [A]} = ?start_activities([Node1]),
+
+ %% store an object in the Tab - first tranaction
+ ?start_transactions([A]),
+ A ! fun() ->
+ mnesia:write(Rec1A) % returns ok when successful
+ end,
+ ?match_receive({A, ok}),
+ A ! end_trans,
+ ?match_receive({A, {atomic, end_trans}}),
+
+ %% second transaction: store some new objects and abort before the
+ %% transaction is finished -> the new changes should be invisable
+ ?start_transactions([A]),
+ A ! fun() ->
+ mnesia:write(Rec1B),
+ erlang:error(foo), % that should provoke a runtime error
+ mnesia:write(Rec1C)
+ end,
+ ?match_receive({A, {aborted, _Reason}}),
+
+ %?match_receive({A, {'EXIT', Msg1}), % A died and sends EXIT
+
+
+ %% Start a second transactionprocess, after the first failed
+ {success, [B]} = ?start_activities([Node1]),
+
+ %% check, whether the interupted transaction had no influence on the db
+ ?start_transactions([B]),
+ B ! fun() ->
+ ?match([Rec1A], mnesia:read({Tab, 1})),
+ ok
+ end,
+ ?match_receive({B, ok}),
+ B ! end_trans,
+ ?match_receive({B, {atomic, end_trans}}),
+
+ ?verify_mnesia(Nodes, []).
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+kill_self_in_middle_of_trans(suite) -> [];
+kill_self_in_middle_of_trans(Config) when is_list(Config) ->
+ [Node1] = Nodes = ?acquire_nodes(1, Config),
+ Tab = kill_self_in_middle_of_trans,
+
+ Rec1A = {Tab, 1, a},
+ Rec1B = {Tab, 1, b},
+ Rec1C = {Tab, 1, c},
+
+ ?match({atomic, ok}, mnesia:create_table([{name, Tab},
+ {ram_copies, [Node1]}])),
+ %% Start a transaction on one node
+ {success, [A]} = ?start_activities([Node1]),
+
+ %% store an object in the Tab - first tranaction
+ ?start_transactions([A]),
+ A ! fun() ->
+ mnesia:write(Rec1A) % returns ok when successful
+ end,
+ ?match_receive({A, ok}),
+ A ! end_trans,
+ ?match_receive({A, {atomic, end_trans}}),
+
+ %% second transaction: store some new objects and abort before the
+ %% transaction is finished -> the new changes should be invisable
+ ?start_transactions([A]),
+ A ! fun() ->
+ mnesia:write(Rec1B),
+ exit(self(), kill), % that should kill the process himself
+ % - poor guy !
+ mnesia:write(Rec1C)
+ end,
+ %%
+ %% exit(.., kill) : the transaction can't trap this error - thus no
+ %% proper result can be send by the test server
+
+ % ?match_receive({A, {aborted, Reason}}),
+
+ ?match_receive({'EXIT', _Pid, killed}), % A is killed and sends EXIT
+
+ %% Start a second transactionprocess, after the first failed
+ {success, [B]} = ?start_activities([Node1]),
+
+ %% check, whether the interupted transaction had no influence on the db
+ ?start_transactions([B]),
+ B ! fun() ->
+ ?match([Rec1A], mnesia:read({Tab, 1})),
+ ok
+ end,
+ ?match_receive({B, ok}),
+ B ! end_trans,
+ ?match_receive({B, {atomic, end_trans}}),
+
+ ?verify_mnesia(Nodes, []).
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+throw_in_middle_of_trans(suite) -> [];
+throw_in_middle_of_trans(Config) when is_list(Config) ->
+ [Node1] = Nodes = ?acquire_nodes(1, Config),
+ Tab = throw_in_middle_of_trans,
+
+ Rec1A = {Tab, 1, a},
+ Rec1B = {Tab, 1, b},
+ Rec1C = {Tab, 1, c},
+
+ ?match({atomic, ok}, mnesia:create_table([{name, Tab},
+ {ram_copies, [Node1]}])),
+ %% Start a transaction on one node
+ {success, [A]} = ?start_activities([Node1]),
+
+ %% store an object in the Tab - first tranaction
+ ?start_transactions([A]),
+ A ! fun() ->
+ mnesia:write(Rec1A) % returns ok when successful
+ end,
+ ?match_receive({A, ok}),
+ A ! end_trans,
+ ?match_receive({A, {atomic, end_trans}}),
+
+ %% second transaction: store some new objects and abort before the
+ %% transaction is finished -> the new changes should be invisable
+ ?start_transactions([A]),
+ A ! fun() ->
+ mnesia:write(Rec1B),
+ throw(exit_transactian_by_a_throw),
+ mnesia:write(Rec1C)
+ end,
+ ?match_receive({A, {aborted, {throw, exit_transactian_by_a_throw}}}),
+ % A ! end_trans, % is A still alive ?
+ % ?match_receive({A, {atomic, end_trans}}), % {'EXIT', Pid, normal}
+
+ %?match_receive({A, {'EXIT', Pid, normal}}), % A died and sends EXIT
+
+ %% Start a second transactionprocess, after the first failed
+ {success, [B]} = ?start_activities([Node1]),
+
+ %% check, whether the interupted transaction had no influence on the db
+ ?start_transactions([B]),
+ B ! fun() ->
+ ?match([Rec1A], mnesia:read({Tab, 1})),
+ ok
+ end,
+ ?match_receive({B, ok}),
+ B ! end_trans,
+ ?match_receive({B, {atomic, end_trans}}),
+
+ ?verify_mnesia(Nodes, []).
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+mnesia_down_in_middle_of_trans(suite) ->
+ [
+ mnesia_down_during_infinite_trans,
+ lock_waiter,
+ restart_check
+ ].
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+mnesia_down_during_infinite_trans(suite) -> [];
+mnesia_down_during_infinite_trans(Config) when is_list(Config) ->
+ [Node1, Node2] = ?acquire_nodes(2, Config),
+ Tab = mnesia_down_during_infinite_trans,
+
+ ?match({atomic, ok},
+ mnesia:create_table([{name, Tab}, {ram_copies, [Node1, Node2]}])),
+ %% Start a transaction on one node
+ {success, [A2, A1]} = ?start_activities([Node2, Node1]),
+ %% Start order of the transactions are important
+ %% We also needs to sync the tid counter
+ ?match({atomic, ok},
+ mnesia:transaction(fun() -> mnesia:write({Tab, 1, test_ok}) end)),
+ mnesia_test_lib:start_sync_transactions([A2, A1]),
+
+ %% Obtain a write lock and wait forever
+ RecA = {Tab, 1, test_not_ok},
+ A1 ! fun() -> mnesia:write(RecA) end,
+ ?match_receive({A1, ok}),
+
+ A1 ! fun() -> process_flag(trap_exit, true), timer:sleep(infinity) end,
+ ?match_receive(timeout),
+
+ %% Try to get read lock, but gets queued
+ A2 ! fun() -> mnesia:read({Tab, 1}) end,
+ ?match_receive(timeout),
+
+ %% Kill Mnesia on other node
+ mnesia_test_lib:kill_mnesia([Node1]),
+
+ %% Second transaction gets the read lock
+ ?match_receive({A2, [{Tab, 1, test_ok}]}),
+ exit(A1, kill), % Needed since we trap exit
+
+ ?verify_mnesia([Node2], [Node1]).
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+lock_waiter(doc) ->
+ ["The purpose of this test case is to test the following situation:",
+ "process B locks an object, process A accesses that object as",
+ "well, but A has to wait for the lock to be released. Then",
+ "mnesia of B goes down. Question: will A get the lock ?",
+ "important: the transaction of A is the oldest one !!! (= a little tricky)",
+ "",
+ "several different access operations shall be tested",
+ "rt = read_lock_table, wt = write_lock_table, r = read,",
+ "sw = s_write, w = write, wr = wread"];
+lock_waiter(suite) ->
+ [
+ lock_waiter_sw_r,
+ lock_waiter_sw_rt,
+ lock_waiter_sw_wt,
+ lock_waiter_wr_r,
+ lock_waiter_srw_r,
+ lock_waiter_sw_sw,
+ lock_waiter_sw_w,
+ lock_waiter_sw_wr,
+ lock_waiter_sw_srw,
+ lock_waiter_wr_wt,
+ lock_waiter_srw_wt,
+ lock_waiter_wr_sw,
+ lock_waiter_srw_sw,
+ lock_waiter_wr_w,
+ lock_waiter_srw_w,
+ lock_waiter_r_sw,
+ lock_waiter_r_w,
+ lock_waiter_r_wt,
+ lock_waiter_rt_sw,
+ lock_waiter_rt_w,
+ lock_waiter_rt_wt,
+ lock_waiter_wr_wr,
+ lock_waiter_srw_srw,
+ lock_waiter_wt_r,
+ lock_waiter_wt_w,
+ lock_waiter_wt_rt,
+ lock_waiter_wt_wt,
+ lock_waiter_wt_wr,
+ lock_waiter_wt_srw,
+ lock_waiter_wt_sw,
+ lock_waiter_w_wr,
+ lock_waiter_w_srw,
+ lock_waiter_w_sw,
+ lock_waiter_w_r,
+ lock_waiter_w_w,
+ lock_waiter_w_rt,
+ lock_waiter_w_wt
+ ].
+
+lock_waiter_sw_r(suite) -> [];
+lock_waiter_sw_r(Config) when is_list(Config) ->
+ start_lock_waiter(sw, r, Config).
+
+lock_waiter_sw_rt(suite) -> [];
+lock_waiter_sw_rt(Config) when is_list(Config) ->
+ start_lock_waiter(sw, rt, Config).
+
+lock_waiter_sw_wt(suite) -> [];
+lock_waiter_sw_wt(Config) when is_list(Config) ->
+ start_lock_waiter(sw, wt,Config).
+
+lock_waiter_wr_r(suite) -> [];
+lock_waiter_wr_r(Config) when is_list(Config) ->
+ start_lock_waiter(wr, r, Config).
+
+lock_waiter_srw_r(suite) -> [];
+lock_waiter_srw_r(Config) when is_list(Config) ->
+ start_lock_waiter(srw, r, Config).
+
+lock_waiter_sw_sw(suite) -> [];
+lock_waiter_sw_sw(Config) when is_list(Config) ->
+ start_lock_waiter(sw, sw,Config).
+
+lock_waiter_srw_srw(suite) -> [];
+lock_waiter_srw_srw(Config) when is_list(Config) ->
+ start_lock_waiter(srw, srw,Config).
+
+lock_waiter_wr_wr(suite) -> [];
+lock_waiter_wr_wr(Config) when is_list(Config) ->
+ start_lock_waiter(wr, wr,Config).
+
+lock_waiter_sw_w(suite) -> [];
+lock_waiter_sw_w(Config) when is_list(Config) ->
+ start_lock_waiter(sw, w,Config).
+
+lock_waiter_sw_wr(suite) -> [];
+lock_waiter_sw_wr(Config) when is_list(Config) ->
+ start_lock_waiter(sw, wr,Config).
+
+lock_waiter_sw_srw(suite) -> [];
+lock_waiter_sw_srw(Config) when is_list(Config) ->
+ start_lock_waiter(sw, srw,Config).
+
+lock_waiter_wr_wt(suite) -> [];
+lock_waiter_wr_wt(Config) when is_list(Config) ->
+ start_lock_waiter(wr, wt,Config).
+
+lock_waiter_srw_wt(suite) -> [];
+lock_waiter_srw_wt(Config) when is_list(Config) ->
+ start_lock_waiter(srw, wt,Config).
+
+lock_waiter_wr_sw(suite) -> [];
+lock_waiter_wr_sw(Config) when is_list(Config) ->
+ start_lock_waiter(wr, sw,Config).
+
+lock_waiter_srw_sw(suite) -> [];
+lock_waiter_srw_sw(Config) when is_list(Config) ->
+ start_lock_waiter(srw, sw,Config).
+
+lock_waiter_wr_w(suite) -> [];
+lock_waiter_wr_w(Config) when is_list(Config) ->
+ start_lock_waiter(wr, w,Config).
+
+lock_waiter_srw_w(suite) -> [];
+lock_waiter_srw_w(Config) when is_list(Config) ->
+ start_lock_waiter(srw, w,Config).
+
+lock_waiter_r_sw(suite) -> [];
+lock_waiter_r_sw(Config) when is_list(Config) ->
+ start_lock_waiter(r, sw,Config).
+
+lock_waiter_r_w(suite) -> [];
+lock_waiter_r_w(Config) when is_list(Config) ->
+ start_lock_waiter(r, w,Config).
+
+lock_waiter_r_wt(suite) -> [];
+lock_waiter_r_wt(Config) when is_list(Config) ->
+ start_lock_waiter(r, wt,Config).
+
+lock_waiter_rt_sw(suite) -> [];
+lock_waiter_rt_sw(Config) when is_list(Config) ->
+ start_lock_waiter(rt, sw,Config).
+
+lock_waiter_rt_w(suite) -> [];
+lock_waiter_rt_w(Config) when is_list(Config) ->
+ start_lock_waiter(rt, w,Config).
+
+lock_waiter_rt_wt(suite) -> [];
+lock_waiter_rt_wt(Config) when is_list(Config) ->
+ start_lock_waiter(rt, wt,Config).
+
+lock_waiter_wt_r(suite) -> [];
+lock_waiter_wt_r(Config) when is_list(Config) ->
+ start_lock_waiter(wt, r,Config).
+
+lock_waiter_wt_w(suite) -> [];
+lock_waiter_wt_w(Config) when is_list(Config) ->
+ start_lock_waiter(wt, w,Config).
+
+lock_waiter_wt_rt(suite) -> [];
+lock_waiter_wt_rt(Config) when is_list(Config) ->
+ start_lock_waiter(wt, rt,Config).
+
+lock_waiter_wt_wt(suite) -> [];
+lock_waiter_wt_wt(Config) when is_list(Config) ->
+ start_lock_waiter(wt, wt,Config).
+
+lock_waiter_wt_wr(suite) -> [];
+lock_waiter_wt_wr(Config) when is_list(Config) ->
+ start_lock_waiter(wt, wr,Config).
+
+lock_waiter_wt_srw(suite) -> [];
+lock_waiter_wt_srw(Config) when is_list(Config) ->
+ start_lock_waiter(wt, srw,Config).
+
+lock_waiter_wt_sw(suite) -> [];
+lock_waiter_wt_sw(Config) when is_list(Config) ->
+ start_lock_waiter(wt, sw,Config).
+
+lock_waiter_w_wr(suite) -> [];
+lock_waiter_w_wr(Config) when is_list(Config) ->
+ start_lock_waiter(w, wr, Config).
+
+lock_waiter_w_srw(suite) -> [];
+lock_waiter_w_srw(Config) when is_list(Config) ->
+ start_lock_waiter(w, srw, Config).
+
+lock_waiter_w_sw(suite) -> [];
+lock_waiter_w_sw(Config) when is_list(Config) ->
+ start_lock_waiter(w, sw, Config).
+
+lock_waiter_w_r(suite) -> [];
+lock_waiter_w_r(Config) when is_list(Config) ->
+ start_lock_waiter(w, r, Config).
+
+lock_waiter_w_w(suite) -> [];
+lock_waiter_w_w(Config) when is_list(Config) ->
+ start_lock_waiter(w, w, Config).
+
+lock_waiter_w_rt(suite) -> [];
+lock_waiter_w_rt(Config) when is_list(Config) ->
+ start_lock_waiter(w, rt, Config).
+
+lock_waiter_w_wt(suite) -> [];
+lock_waiter_w_wt(Config) when is_list(Config) ->
+ start_lock_waiter(w, wt, Config).
+
+start_lock_waiter(BlockOpA, BlockOpB, Config) ->
+ [N1, N2] = Nodes = ?acquire_nodes(2, Config),
+
+ TabName = mk_tab_name(lock_waiter_),
+ ?match({atomic, ok}, mnesia:create_table(TabName,
+ [{ram_copies, [N1, N2]}])),
+
+ %% initialize the table with object {1, c} - when there
+ %% is a read transaction, the read will find that value
+ ?match({atomic, ok}, mnesia:sync_transaction(fun() -> mnesia:write({TabName, 1, c}) end)),
+ rpc:call(N2, ?MODULE, sync_tid_release, []),
+
+ Tester = self(),
+ Fun_A =fun() ->
+ NewCounter = incr_restart_counter(),
+ if
+ NewCounter == 1 ->
+ Tester ! go_ahead_test,
+ receive go_ahead -> ok end;
+ true -> ok
+ end,
+ lock_waiter_fun(BlockOpA, TabName, a),
+ NewCounter
+ end,
+
+ %% it's not possible to just spawn the transaction, because
+ %% the result shall be evaluated
+ A = spawn_link(N1, ?MODULE, perform_restarted_transaction, [Fun_A]),
+
+ ?match(ok, receive go_ahead_test -> ok after 10000 -> timeout end),
+
+ mnesia_test_lib:sync_trans_tid_serial([N1, N2]),
+
+ Fun_B = fun() ->
+ lock_waiter_fun(BlockOpB, TabName, b),
+ A ! go_ahead,
+ wait(infinity)
+ end,
+
+ B = spawn_link(N2, mnesia, transaction, [Fun_B, 100]),
+
+ io:format("waiting for A (~p on ~p) to be in the queue ~n", [A, [N1, N2]]),
+ wait_for_a(A, [N1, N2]),
+
+ io:format("Queus ~p~n",
+ [[{N,rpc:call(N, mnesia, system_info, [lock_queue])} || N <- Nodes]]),
+
+ KillNode = node(B),
+ io:format("A was in the queue, time to kill Mnesia on B's node (~p on ~p)~n",
+ [B, KillNode]),
+
+ mnesia_test_lib:kill_mnesia([KillNode]), % kill mnesia of fun B
+
+ %% Read Ops does not need to be restarted
+ ExpectedCounter =
+ if
+ BlockOpA == sw, BlockOpB == w -> 1;
+ BlockOpA == sw, BlockOpB == wt -> 1;
+ BlockOpA == sw, BlockOpB == wr -> 1;
+ BlockOpA == srw, BlockOpB == w -> 1;
+ BlockOpA == srw, BlockOpB == wt -> 1;
+ BlockOpA == srw, BlockOpB == wr -> 1;
+ BlockOpA == r, BlockOpB /= sw -> 1;
+ BlockOpA == rt, BlockOpB /= sw -> 1;
+ true -> 2
+ end,
+ ?match_multi_receive([{'EXIT', A, {atomic, ExpectedCounter}},
+ {'EXIT', B, killed}]),
+
+ %% the expected result depends on the transaction of
+ %% fun A - when that doesn't change the object in the
+ %% table (e.g. it is a read) then the predefined
+ %% value {Tabname, 1, c} is expected to be the result here
+ ExpectedResult =
+ case BlockOpA of
+ w -> {TabName, 1, a};
+ sw ->{TabName, 1, a};
+ _all_other -> {TabName, 1, c}
+ end,
+
+ ?match({atomic, [ExpectedResult]},
+ mnesia:transaction(fun() -> mnesia:read({TabName, 1}) end, 100)),
+ ?verify_mnesia([N1], [N2]).
+
+mk_tab_name(Prefix) ->
+ {Mega, Sec, Micro} = erlang:now(),
+ list_to_atom(lists:concat([Prefix , Mega, '_', Sec, '_', Micro])).
+
+lock_waiter_fun(Op, TabName, Val) ->
+ case Op of
+ rt -> mnesia:read_lock_table(TabName);
+ wt -> mnesia:write_lock_table(TabName);
+ r -> mnesia:read({TabName, 1});
+ w -> mnesia:write({TabName, 1, Val});
+ wr -> mnesia:wread({TabName, 1});
+ srw -> mnesia:read(TabName, 1, sticky_write);
+ sw -> mnesia:s_write({TabName, 1, Val})
+ end.
+
+wait_for_a(Pid, Nodes) ->
+ wait_for_a(Pid, Nodes, 5).
+
+wait_for_a(_P, _N, 0) ->
+ ?error("Timeout while waiting for lock on a~n", []);
+
+wait_for_a(Pid, Nodes, Count) ->
+ %% io:format("WAIT_FOR_A ~p ON ~w ~n", [Pid, Nodes]),
+ List = [rpc:call(N, mnesia, system_info, [lock_queue]) || N <- Nodes],
+ Q = lists:append(List),
+ check_q(Pid, Q, Nodes, Count).
+
+check_q(Pid, [{{_Oid,_Tid}, _Op, Pid, _WFT} | _Tail], _N, _Count) ->
+ ok;
+check_q(Pid, [{_Oid, _Op, Pid, _Tid, _WFT} | _Tail], _N, _Count) ->
+ ok;
+check_q(Pid, [_ | Tail], N, Count) ->
+ check_q(Pid, Tail, N, Count);
+check_q(Pid, [], N, Count) ->
+ timer:sleep(500),
+ wait_for_a(Pid, N, Count - 1).
+
+perform_restarted_transaction (Fun_Trans) ->
+ %% the result of the transaction shall be:
+ %% - undefined (if the transaction was never executed)
+ %% - Times ( number of times that the transaction has been executed)
+
+ Result = mnesia:transaction(Fun_Trans, 100),
+ exit(Result).
+
+%% Returns new val
+incr_restart_counter() ->
+ NewCount =
+ case get(count_restart_of_transaction) of
+ undefined -> 1;
+ OldCount -> OldCount + 1
+ end,
+ put(count_restart_of_transaction, NewCount),
+ NewCount.
+
+wait(Mseconds) ->
+ receive
+ after Mseconds -> ok
+ end.
+
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+restart_check (doc) ->
+ [
+ "test case:'A' performs a transaction on a table which",
+ "is only replicated on node B. During that transaction",
+ "mnesia on node B is killed. The transaction of A should",
+ "be stopped, since there is no further replica",
+ "rt = read_lock_table, wt = write_lock_table, r = read,",
+ "sw = s_write, w = write, wr = wread,"];
+restart_check(suite) ->
+ [
+ restart_r_one,
+ restart_w_one,
+ restart_rt_one,
+ restart_wt_one,
+ restart_wr_one,
+ restart_sw_one,
+ restart_r_two,
+ restart_w_two,
+ restart_rt_two,
+ restart_wt_two,
+ restart_wr_two,
+ restart_sw_two
+ ].
+
+restart_r_one(suite) -> [];
+restart_r_one(Config) when is_list(Config) ->
+ start_restart_check(r, one, Config).
+
+restart_w_one(suite) -> [];
+restart_w_one(Config) when is_list(Config) ->
+ start_restart_check(w, one, Config).
+
+restart_rt_one(suite) -> [];
+restart_rt_one(Config) when is_list(Config) ->
+ start_restart_check(rt, one, Config).
+
+restart_wt_one(suite) -> [];
+restart_wt_one(Config) when is_list(Config) ->
+ start_restart_check(wt, one, Config).
+
+restart_wr_one(suite) -> [];
+restart_wr_one(Config) when is_list(Config) ->
+ start_restart_check(wr, one, Config).
+
+restart_sw_one(suite) -> [];
+restart_sw_one(Config) when is_list(Config) ->
+ start_restart_check(sw, one, Config).
+
+restart_r_two(suite) -> [];
+restart_r_two(Config) when is_list(Config) ->
+ start_restart_check(r, two, Config).
+
+restart_w_two(suite) -> [];
+restart_w_two(Config) when is_list(Config) ->
+ start_restart_check(w, two, Config).
+
+restart_rt_two(suite) -> [];
+restart_rt_two(Config) when is_list(Config) ->
+ start_restart_check(rt, two, Config).
+
+restart_wt_two(suite) -> [];
+restart_wt_two(Config) when is_list(Config) ->
+ start_restart_check(wt, two, Config).
+
+restart_wr_two(suite) -> [];
+restart_wr_two(Config) when is_list(Config) ->
+ start_restart_check(wr, two, Config).
+
+restart_sw_two(suite) -> [];
+restart_sw_two(Config) when is_list(Config) ->
+ start_restart_check(sw, two, Config).
+
+start_restart_check(RestartOp, ReplicaNeed, Config) ->
+ [N1, N2, N3] = Nodes = ?acquire_nodes(3, Config),
+
+ {TabName, _TabNodes} = create_restart_table(ReplicaNeed, Nodes),
+
+ %% initialize the table with object {1, c} - when there
+ %% is a read transaction, the read will find that value
+ ?match({atomic, ok}, mnesia:sync_transaction(fun() -> mnesia:write({TabName, 1, c}) end)),
+
+ %% Really sync tid_release
+ rpc:multicall([N2,N3], ?MODULE, sync_tid_release, []),
+ Coord = self(),
+
+ Fun_A = fun() ->
+ NewCounter = incr_restart_counter(),
+ case NewCounter of
+ 1 ->
+ mnesia:write({TabName, 1, d}),
+ %% send a message to the test proc
+ Coord ! {self(),fun_a_is_blocked},
+ receive go_ahead -> ok end;
+ _ ->
+ %% the fun will NOT be blocked here
+ restart_fun_A(RestartOp, TabName)
+ end,
+ NewCounter
+ end,
+
+ A = spawn_link(N1, ?MODULE, perform_restarted_transaction, [Fun_A]),
+ ?match_receive({A,fun_a_is_blocked}),
+
+ %% mnesia shall be killed at that node, where A is reading
+ %% the information from
+ kill_where_to_read(TabName, N1, [N2, N3]),
+
+ %% wait some time to let mnesia go down and spread those news around
+ %% fun A shall be able to finish its job before being restarted
+ wait(500),
+ A ! go_ahead,
+
+ %% the sticky write doesnt work on remote nodes !!!
+ ExpectedMsg =
+ case RestartOp of
+ sw when ReplicaNeed == two ->
+ {'EXIT',A,{aborted, {not_local, TabName}}};
+ _all_other ->
+ case ReplicaNeed of
+ one ->
+ {'EXIT',A,{aborted, {no_exists, TabName}}};
+ two ->
+ {'EXIT',A,{atomic, 2}}
+ end
+ end,
+
+ ?match_receive(ExpectedMsg),
+
+ %% now mnesia has to be started again on the node KillNode
+ %% because the next test suite will need it
+ ?match([], mnesia_test_lib:start_mnesia(Nodes, [TabName])),
+
+
+ %% the expected result depends on the transaction of
+ %% fun A - when that doesnt change the object in the
+ %% table (e.g. it is a read) then the predefined
+ %% value {Tabname, 1, c} is expected to be the result here
+
+ ExpectedResult =
+ case ReplicaNeed of
+ one ->
+ [];
+ two ->
+ case RestartOp of
+ w -> [{TabName, 1, a}];
+ _ ->[ {TabName, 1, c}]
+ end
+ end,
+
+ ?match({atomic, ExpectedResult},
+ mnesia:transaction(fun() -> mnesia:read({TabName, 1}) end,100)),
+ ?verify_mnesia(Nodes, []).
+
+create_restart_table(ReplicaNeed, [_N1, N2, N3]) ->
+ TabNodes =
+ case ReplicaNeed of
+ one -> [N2];
+ two -> [N2, N3]
+ end,
+ TabName = mk_tab_name(restart_check_),
+ ?match({atomic, ok}, mnesia:create_table(TabName, [{ram_copies, TabNodes}])),
+ {TabName, TabNodes}.
+
+restart_fun_A(Op, TabName) ->
+ case Op of
+ rt -> mnesia:read_lock_table(TabName);
+ wt -> mnesia:write_lock_table(TabName);
+ r -> mnesia:read( {TabName, 1});
+ w -> mnesia:write({TabName, 1, a});
+ wr -> mnesia:wread({TabName, 1});
+ sw -> mnesia:s_write({TabName, 1, a})
+ end.
+
+kill_where_to_read(TabName, N1, Nodes) ->
+ Read = rpc:call(N1,mnesia,table_info, [TabName, where_to_read]),
+ case lists:member(Read, Nodes) of
+ true ->
+ mnesia_test_lib:kill_mnesia([Read]);
+ false ->
+ ?error("Fault while killing Mnesia: ~p~n", [Read]),
+ mnesia_test_lib:kill_mnesia(Nodes)
+ end.
+
+sync_tid_release() ->
+ sys:get_status(whereis(mnesia_tm)),
+ sys:get_status(whereis(mnesia_locker)),
+ ok.
+
diff --git a/lib/mnesia/test/mnesia_config_backup.erl b/lib/mnesia/test/mnesia_config_backup.erl
new file mode 100644
index 0000000000..a33ec6ac5c
--- /dev/null
+++ b/lib/mnesia/test/mnesia_config_backup.erl
@@ -0,0 +1,105 @@
+%%
+%% %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(mnesia_config_backup).
+-author('[email protected]').
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%%
+%% This module is used for testing the backup module config parameter.
+%%
+%% This module is an impostor for the mnesia_backup module.
+%%
+%%
+%% Original doc below:
+%%
+%% This module contains one implementation of callback functions
+%% used by Mnesia at backup and restore. The user may however
+%% write an own module the same interface as mnesia_backup and
+%% configure Mnesia so the alternate module performs the actual
+%% accesses to the backup media. This means that the user may put
+%% the backup on medias that Mnesia does not know about, possibly
+%% on hosts where Erlang is not running.
+%%
+%% The OpaqueData argument is never interpreted by other parts of
+%% Mnesia. It is the property of this module. Alternate implementations
+%% of this module may have different interpretations of OpaqueData.
+%% The OpaqueData argument given to open_write/1 and open_read/1
+%% are forwarded directly from the user.
+%%
+%% All functions must return {ok, NewOpaqueData} or {error, Reason}.
+%%
+%% The NewOpaqueData arguments returned by backup callback functions will
+%% be given as input when the next backup callback function is invoked.
+%% If any return value does not match {ok, _} the backup will be aborted.
+%%
+%% The NewOpaqueData arguments returned by restore callback functions will
+%% be given as input when the next restore callback function is invoked
+%% If any return value does not match {ok, _} the restore will be aborted.
+%%
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+-export([
+ open_write/1, write/2, commit_write/1, abort_write/1,
+ open_read/1, read/1, close_read/1
+ ]).
+
+-record(backup, {name, mode, items}).
+
+open_write(Name) ->
+ file:delete(Name),
+ {ok, #backup{name = Name, mode = write, items = []}}.
+
+write(Opaque, Item) when Opaque#backup.mode == write ->
+ %% Build the list in reverse order
+ {ok, Opaque#backup{items = [Item | Opaque#backup.items]}}.
+
+commit_write(Opaque) when Opaque#backup.mode == write ->
+ Bin = term_to_binary(Opaque#backup.items),
+ case file:write_file(Opaque#backup.name, Bin) of
+ ok ->
+ {ok, Opaque#backup{mode = closed, items = []}};
+ {error, Reason} ->
+ {error, {commit_write, Reason}}
+ end.
+
+abort_write(Opaque) ->
+ {ok, Opaque#backup{mode = closed, items = []}}.
+
+open_read(Name) ->
+ case file:read_file(Name) of
+ {ok, Bin} ->
+ ReverseList = binary_to_term(Bin),
+ List = lists:reverse(ReverseList),
+ {ok, #backup{name = Name, mode = read, items = List}};
+ {error, Reason} ->
+ {error, {open_read, Reason}}
+ end.
+
+read(Opaque) when Opaque#backup.mode == read ->
+ case Opaque#backup.items of
+ [Head | Tail] ->
+ {ok, Opaque#backup{items = Tail}, Head};
+ [] ->
+ {ok, Opaque#backup{mode = closed}, []}
+ end.
+
+close_read(Opaque) ->
+ {ok, Opaque#backup{mode = closed, items = []}}.
diff --git a/lib/mnesia/test/mnesia_config_event.erl b/lib/mnesia/test/mnesia_config_event.erl
new file mode 100644
index 0000000000..6c1dea7ed5
--- /dev/null
+++ b/lib/mnesia/test/mnesia_config_event.erl
@@ -0,0 +1,74 @@
+%%
+%% %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(mnesia_config_event).
+-author('[email protected]').
+
+-behaviour(gen_event).
+
+%%
+%% This module was stolen from Mnesia
+%%
+
+
+%% gen_event callback interface
+-export([init/1, handle_event/2, handle_call/2, handle_info/2,
+ terminate/2, code_change/3]).
+
+
+init(_Args) ->
+ {ok, []}.
+
+handle_event(Msg, State) ->
+ handle_any_event(Msg, State).
+
+handle_info(Msg, State) ->
+ handle_any_event(Msg, State).
+
+
+handle_call(Msg, State) ->
+ handle_any_event(Msg, State).
+
+
+%% The main...
+
+handle_any_event({get_log, Pid}, State) ->
+ Pid ! {log, State},
+ {ok, State};
+handle_any_event(Msg, State) ->
+ io:format("Got event: ~p~n", [Msg]),
+ {ok, [Msg | State]}.
+
+%%-----------------------------------------------------------------
+%% terminate(Reason, State) ->
+%% AnyVal
+%%-----------------------------------------------------------------
+
+terminate(_Reason, _State) ->
+ ok.
+
+%%----------------------------------------------------------------------
+%% Func: code_change/3
+%% Purpose: Upgrade process when its code is to be changed
+%% Returns: {ok, NewState}
+%%----------------------------------------------------------------------
+code_change(_OldVsn, _State, _Extra) ->
+ exit(not_supported).
+
diff --git a/lib/mnesia/test/mnesia_config_test.erl b/lib/mnesia/test/mnesia_config_test.erl
new file mode 100644
index 0000000000..7b62c63a62
--- /dev/null
+++ b/lib/mnesia/test/mnesia_config_test.erl
@@ -0,0 +1,1466 @@
+%%
+%% %CopyrightBegin%
+%%
+%% 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(mnesia_config_test).
+-author('[email protected]').
+
+-include("mnesia_test_lib.hrl").
+
+-record(test_table,{i,a1,a2,a3}).
+-record(test_table2,{i, b}).
+
+-export([
+ all/1,
+ access_module/1,
+ auto_repair/1,
+ backup_module/1,
+ debug/1,
+ dir/1,
+ dump_log_load_regulation/1,
+ dump_log_thresholds/1,
+ dump_log_update_in_place/1,
+ embedded_mnemosyne/1,
+ event_module/1,
+ ignore_fallback_at_startup/1,
+ inconsistent_database/1,
+ max_wait_for_decision/1,
+ send_compressed/1,
+
+ app_test/1,
+ schema_config/1,
+ schema_merge/1,
+ unknown_config/1,
+
+ dump_log_time_threshold/1,
+ dump_log_write_threshold/1,
+
+ start_one_disc_full_then_one_disc_less/1,
+ start_first_one_disc_less_then_one_disc_full/1,
+ start_first_one_disc_less_then_two_more_disc_less/1,
+ schema_location_and_extra_db_nodes_combinations/1,
+ table_load_to_disc_less_nodes/1,
+ dynamic_connect/1,
+ dynamic_basic/1,
+ dynamic_ext/1,
+ dynamic_bad/1,
+
+ init_per_testcase/2,
+ fin_per_testcase/2,
+ c_nodes/0
+ ]).
+
+-export([check_logs/1]).
+
+-define(init(N, Config),
+ mnesia_test_lib:prepare_test_case([{init_test_case, [mnesia]},
+ delete_schema,
+ {reload_appls, [mnesia]}],
+ N, Config, ?FILE, ?LINE)).
+-define(acquire(N, Config),
+ mnesia_test_lib:prepare_test_case([{init_test_case, [mnesia]},
+ delete_schema,
+ {reload_appls, [mnesia]},
+ create_schema,
+ {start_appls, [mnesia]}],
+ N, Config, ?FILE, ?LINE)).
+-define(acquire_schema(N, Config),
+ mnesia_test_lib:prepare_test_case([{init_test_case, [mnesia]},
+ delete_schema,
+ {reload_appls, [mnesia]},
+ create_schema],
+ N, Config, ?FILE, ?LINE)).
+-define(cleanup(N, Config),
+ mnesia_test_lib:prepare_test_case([{reload_appls, [mnesia]}],
+ N, Config, ?FILE, ?LINE)).
+-define(trans(Fun),
+ ?match({atomic, ok}, mnesia:transaction(Fun))).
+
+init_per_testcase(Func, Conf) ->
+ mnesia_test_lib:init_per_testcase(Func, Conf).
+
+fin_per_testcase(Func, Conf) ->
+ mnesia_test_lib:fin_per_testcase(Func, Conf).
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+
+all(doc) ->
+ [
+ "Test all configuration parameters",
+ "Perform an exhaustive test of all the various parameters that",
+ "may be used to configure the Mnesia application.",
+ "",
+ "Hint: Check out the unofficial function mnesia:start/1.",
+ " But be careful to cleanup all configuration parameters",
+ " afterwards since the rest of the test suite may rely on",
+ " these default configurations. Perhaps it is best to run",
+ " these tests in a separate node which is dropped afterwards.",
+ "Are really all configuration parameters covered?"];
+
+all(suite) ->
+ [
+ access_module,
+ auto_repair,
+ backup_module,
+ debug,
+ dir,
+ dump_log_load_regulation,
+ dump_log_thresholds,
+ dump_log_update_in_place,
+ embedded_mnemosyne,
+ event_module,
+ ignore_fallback_at_startup,
+ inconsistent_database,
+ max_wait_for_decision,
+ send_compressed,
+
+ app_test,
+ schema_config,
+ unknown_config
+ ].
+
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+access_module(doc) ->
+ ["Replace the activity access module with another module and ",
+ "use it to read and write to some alternate table storage"];
+access_module(suite) -> [];
+access_module(Config) when is_list(Config) ->
+ Nodes = ?acquire_schema(1, Config),
+ ?match(ok, mnesia:start([{access_module, mnesia_frag}])),
+
+ ?match(mnesia_frag, mnesia:system_info(access_module)),
+
+ access_tab(ram_copies, Nodes),
+ case mnesia_test_lib:diskless(Config) of
+ true -> skip;
+ false ->
+ access_tab(disc_copies, Nodes)
+ , access_tab(disc_only_copies, Nodes)
+ end,
+
+ ?verify_mnesia(Nodes, []),
+ ?cleanup(1, Config).
+
+access_tab(Storage, Nodes) ->
+ Tab = list_to_atom(lists:concat([access_tab_, Storage])),
+ RecName = some_access,
+ Attr = val,
+ TabDef = [{Storage, Nodes},
+ {type, bag},
+ {index, [Attr]},
+ {record_name, RecName}],
+ ?match({atomic,ok}, mnesia:create_table(Tab, TabDef)),
+
+ Activity = fun(Kind) ->
+ A = [Kind, Tab, RecName, Attr, Nodes],
+ io:format("kind: ~w, storage: ~w~n", [Kind, Storage]),
+ mnesia:activity(Kind, fun do_access/5, A)
+ end,
+ ModActivity = fun(Kind, M) ->
+ io:format("kind: ~w, storage: ~w. module: ~w~n",
+ [Kind, Storage, M]),
+ A = [Kind, Tab, RecName, Attr, Nodes],
+ mnesia:activity(Kind, fun do_access/5, A, M)
+ end,
+ ?match(ok, Activity(transaction)),
+ ?match(ok, Activity({transaction, 47})),
+ ?match(ok, ModActivity(transaction, mnesia)),
+ ?match(ok, ModActivity(transaction, mnesia_frag)),
+
+ ?match(ok, Activity(async_dirty)),
+ ?match(ok, Activity(sync_dirty)),
+ case Storage of
+ ram_copies ->
+ ?match(ok, Activity(ets));
+ _ ->
+ ignore
+ end.
+
+do_access(Kind, Tab, RecName, Attr, Nodes) ->
+ Tens = lists:sort([{RecName, 1, 10}, {RecName, 3, 10}]),
+ {OptNodes, OptTens} =
+ case Kind of
+ transaction -> {Nodes, Tens};
+ {transaction, _} -> {Nodes, Tens};
+ async_dirty -> {[], Tens};
+ sync_dirty -> {[], Tens};
+ ets -> {[], []}
+ end,
+ ?match(RecName, mnesia:table_info(Tab, record_name)),
+
+ ?match(ok, mnesia:write(Tab, {RecName, 1, 10}, write)),
+ ?match(ok, mnesia:write(Tab, {RecName, 2, 20}, sticky_write)),
+ ?match(ok, mnesia:write(Tab, {RecName, 2, 21}, sticky_write)),
+ ?match(ok, mnesia:write(Tab, {RecName, 2, 22}, write)),
+ ?match(ok, mnesia:write(Tab, {RecName, 3, 10}, write)),
+
+ Twos = [{RecName, 2, 20}, {RecName, 2, 21}, {RecName, 2, 22}],
+ ?match(Twos, lists:sort(mnesia:read(Tab, 2, read))),
+
+ ?match(ok, mnesia:delete_object(Tab, {RecName, 2, 21}, sticky_write)),
+
+ TenPat = {RecName, '_', 10},
+ ?match(Tens, lists:sort(mnesia:match_object(Tab, TenPat, read))),
+ ?match(OptTens, lists:sort(mnesia:index_match_object(Tab, TenPat, Attr, read) )),
+ ?match(OptTens, lists:sort(mnesia:index_read(Tab, 10, Attr))),
+ Keys = [1, 2, 3],
+ ?match(Keys, lists:sort(mnesia:all_keys(Tab))),
+
+ First = mnesia:first(Tab),
+ Mid = mnesia:next(Tab, First),
+ Last = mnesia:next(Tab, Mid),
+ ?match('$end_of_table', mnesia:next(Tab, Last)),
+ ?match(Keys, lists:sort([First,Mid,Last])),
+
+ %% For set and bag these last, prev works as first and next
+ First2 = mnesia:last(Tab),
+ Mid2 = mnesia:prev(Tab, First2),
+ Last2 = mnesia:prev(Tab, Mid2),
+ ?match('$end_of_table', mnesia:prev(Tab, Last2)),
+ ?match(Keys, lists:sort([First2,Mid2,Last2])),
+
+ ?match([ok, ok, ok], [mnesia:delete(Tab, K, write) || K <- Keys]),
+ W = wild_pattern,
+ ?match([], mnesia:match_object(Tab, mnesia:table_info(Tab, W), read)),
+ ?log("Safe fixed ~p~n", [catch ets:info(Tab, safe_fixed)]),
+ ?log("Fixed ~p ~n", [catch ets:info(Tab, fixed)]),
+
+ ?match(OptNodes, mnesia:lock({global, some_lock_item, Nodes}, write)),
+ ?match(OptNodes, mnesia:lock({global, some_lock_item, Nodes}, read)),
+ ?match(OptNodes, mnesia:lock({table, Tab}, read)),
+ ?match(OptNodes, mnesia:lock({table, Tab}, write)),
+
+ ok.
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+auto_repair(doc) ->
+ ["Try the auto_repair mechanism on the various disk_logs and dets files.",
+ "",
+ "The case tests both normal values of the parameter, and also",
+ "one crazy value.",
+ "The test of the real auto_repair functionality is made in the",
+ "dets suite"
+ ];
+auto_repair(suite) -> [];
+auto_repair(Config) when is_list(Config) ->
+ ?init(1, Config),
+ ?match(ok, mnesia:start()), % Check default true
+ ?match(true, mnesia:system_info(auto_repair)),
+ ?match(stopped, mnesia:stop()),
+ ?match(ok, mnesia:start([{auto_repair, true}])),
+ ?match(true, mnesia:system_info(auto_repair)),
+ ?match(stopped, mnesia:stop()),
+ ?match(ok, mnesia:start([{auto_repair, false}])),
+ ?match(false, mnesia:system_info(auto_repair)),
+ ?match(stopped, mnesia:stop()),
+ ?match({error, {bad_type, auto_repair, your_mama}},
+ mnesia:start([{auto_repair, your_mama}])),
+ ?match(stopped, mnesia:stop()),
+ ?cleanup(1, Config),
+ ok.
+
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+backup_module(doc) ->
+ ["Replace the backup module with another module and use it to",
+ "read and write to an alternate backup media, e.g stored in",
+ "the internal state of a simple process."];
+backup_module(suite) -> [];
+backup_module(Config) when is_list(Config) ->
+ Nodes = ?acquire_schema(1, Config),
+ ?match(ok, mnesia:start([{backup_module, mnesia_config_backup}])),
+ ?match({atomic,ok},
+ mnesia:create_table(test_table,
+ [{disc_copies, Nodes},
+ {attributes,
+ record_info(fields,test_table)}])),
+
+ ?match({atomic,ok},
+ mnesia:create_table(test_table2,
+ [{disc_copies, Nodes},
+ {attributes,
+ record_info(fields,test_table2)}])),
+ %% Write in test table
+ ?trans(fun() -> mnesia:write(#test_table{i=1}) end),
+ ?trans(fun() -> mnesia:write(#test_table{i=2}) end),
+
+ %% Write in test table 2
+ ?trans(fun() -> mnesia:write(#test_table2{i=3}) end),
+ ?trans(fun() -> mnesia:write(#test_table2{i=4}) end),
+ mnesia_test_lib:sync_tables(Nodes, [test_table, test_table2]),
+
+ File = whow,
+ %% Now make a backup
+ ?match(ok, mnesia:backup(File)),
+
+ ?match(ok, mnesia:install_fallback(File)),
+
+ %% Now add things
+ ?trans(fun() -> mnesia:write(#test_table{i=2.5}) end),
+ ?trans(fun() -> mnesia:write(#test_table2{i=3.5}) end),
+
+ mnesia_test_lib:kill_mnesia(Nodes),
+ receive after 2000 -> ok end,
+ ?match([], mnesia_test_lib:start_mnesia(Nodes, [test_table, test_table2])),
+
+ %% Now check newly started tables
+ ?match({atomic, [1,2]},
+ mnesia:transaction(fun() -> lists:sort(mnesia:all_keys(test_table)) end)),
+ ?match({atomic, [3,4]},
+ mnesia:transaction(fun() -> lists:sort(mnesia:all_keys(test_table2)) end)),
+
+ file:delete(File),
+ ?verify_mnesia(Nodes, []),
+ ?cleanup(1, Config),
+ ok.
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+debug(doc) ->
+ ["Try out the four debug levels and ensure that the",
+ "expected events are generated."];
+debug(suite) -> [];
+debug(Config) when is_list(Config) ->
+ Nodes = ?init(1, Config),
+ case application:get_env(mnesia,debug) of
+ undefined ->
+ ?match(none, mnesia:system_info(debug));
+ {ok, false} ->
+ ?match(none, mnesia:system_info(debug));
+ {ok, true} ->
+ ?match(debug, mnesia:system_info(debug));
+ {ok, Env} ->
+ ?match(Env, mnesia:system_info(debug))
+ end,
+
+ ?match(ok, mnesia:start([{debug, verbose}])),
+ ?match(verbose, mnesia:system_info(debug)),
+ mnesia_test_lib:kill_mnesia(Nodes),
+ receive after 2000 -> ok end,
+
+ ?match(ok, mnesia:start([{debug, debug}])),
+ ?match(debug, mnesia:system_info(debug)),
+ mnesia_test_lib:kill_mnesia(Nodes),
+ receive after 2000 -> ok end,
+
+ ?match(ok, mnesia:start([{debug, trace}])),
+ ?match(trace, mnesia:system_info(debug)),
+ mnesia_test_lib:kill_mnesia(Nodes),
+ receive after 2000 -> ok end,
+
+ ?match(ok, mnesia:start([{debug, true}])),
+ ?match(debug, mnesia:system_info(debug)),
+ mnesia_test_lib:kill_mnesia(Nodes),
+ receive after 2000 -> ok end,
+
+ ?match(ok, mnesia:start([{debug, false}])),
+ ?match(none, mnesia:system_info(debug)),
+
+ ?verify_mnesia(Nodes, []),
+ ?cleanup(1, Config),
+ ok.
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+dir(doc) ->
+ ["Try to use alternate Mnesia directories"];
+dir(suite) -> [];
+dir(Config) when is_list(Config) ->
+ Nodes = ?init(1, Config),
+
+ ?match(ok, mnesia:start([{dir, tuff}])),
+ Dir = filename:join([element(2, file:get_cwd()), "tuff"]),
+ ?match(Dir, mnesia:system_info(directory)),
+ mnesia_test_lib:kill_mnesia(Nodes),
+
+ ?cleanup(1, Config),
+ ok.
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+dump_log_update_in_place(doc) ->
+ ["Change the update in place policy for the transaction log dumper."];
+dump_log_update_in_place(suite) -> [];
+dump_log_update_in_place(Config) when is_list(Config) ->
+ Nodes = ?acquire(1, Config),
+ ?match(true, mnesia:system_info(dump_log_update_in_place)),
+ ?match({atomic,ok},
+ mnesia:create_table(test_table,
+ [{disc_copies, Nodes},
+ {attributes,
+ record_info(fields,test_table)}])),
+
+ mnesia_test_lib:kill_mnesia(Nodes),
+ receive after 2000 -> ok end,
+
+ ?match(ok, mnesia:start([{dump_log_update_in_place, false}])),
+ ?match(false, mnesia:system_info(dump_log_update_in_place)),
+
+ mnesia_test_lib:sync_tables(Nodes, [schema, test_table]),
+
+ %% Now provoke some log dumps
+
+ L = lists:map(
+ fun(Num) ->
+ %% Write something on one end ...
+ mnesia:transaction(
+ fun() ->
+ mnesia:write(#test_table{i=Num}) end
+ ) end,
+ lists:seq(1, 110)),
+
+ L2 = lists:duplicate(110, {atomic, ok}),
+
+ %% If this fails then some of the 110 writes above failed
+ ?match(true, L==L2),
+ if L==L2 -> ok;
+ true ->
+ ?verbose("***** List1 len: ~p, List2 len: ~p~n",
+ [length(L), length(L2)]),
+ ?verbose("L: ~p~nL2:~p~n", [L, L2])
+ end,
+
+ %% If we still can write, then Mnesia is probably alive
+ ?trans(fun() -> mnesia:write(#test_table{i=115}) end),
+
+ ?verify_mnesia(Nodes, []),
+ ?cleanup(1, Config),
+ ok.
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+dump_log_thresholds(doc) ->
+ ["Elaborate with various values of the dump log thresholds and how",
+ "they affects each others. Both the dump_log_time_threshold and the",
+ "dump_log_write_threshold must be covered. Do also check that both",
+ "kinds of overload events are generated as expected.",
+ "",
+ "Logs are checked by first doing whatever has to be done to trigger ",
+ "a dump, and then stopping Mnesia and then look in the ",
+ "data files and see that the correct amount of transactions ",
+ "have been done."];
+dump_log_thresholds(suite) ->
+ [
+ dump_log_time_threshold,
+ dump_log_write_threshold
+ ].
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+dump_log_write_threshold(doc)->
+ ["This test case must be rewritten.",
+ "Dump logs are tested by doing transactions, then killing Mnesia and ",
+ "then examining the table data files and see if they are correct.",
+ "The test_table is used as a counter, test_table. is stepped once ",
+ "for each transaction."];
+dump_log_write_threshold(suite)->[];
+dump_log_write_threshold(Config) when is_list(Config) ->
+ [N1] = ?acquire_schema(1, Config),
+
+ Threshold = 3,
+ ?match(ok,mnesia:start([{dump_log_write_threshold, Threshold}])),
+
+ ?match({atomic,ok},
+ mnesia:create_table(test_table,
+ [{disc_copies, [N1]},
+ {attributes,
+ record_info(fields,test_table)}])),
+ ?match(dumped, mnesia:dump_log()),
+
+ ?match(ok, do_trans(2)), % Shall not have dumped
+ check_logs(0),
+
+ ?match(ok, do_trans(Threshold - 2)), % Trigger a dump
+ receive after 1000 -> ok end,
+ check_logs(Threshold),
+
+
+ ?match(ok, do_trans(Threshold - 1)),
+ ?match(dumped, mnesia:dump_log()), %% This should trigger ets2dcd dump
+ check_logs(0), %% and leave no dcl file
+
+ ?match(stopped, mnesia:stop()),
+
+ %% Check bad threshold value
+ ?match({error,{bad_type,dump_log_write_threshold,0}},
+ mnesia:start([{dump_log_write_threshold,0}])),
+
+ ?verify_mnesia([], [N1]),
+ ?cleanup(1, Config),
+ ok.
+
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+dump_log_time_threshold(doc)->
+ ["See doc on above."];
+dump_log_time_threshold(suite)->[];
+dump_log_time_threshold(Config) when is_list(Config) ->
+ Nodes = ?acquire_schema(1, Config),
+ Time = 4000,
+
+ %% Check bad threshold value
+ ?match({error,{bad_type,dump_log_time_threshold,0}},
+ mnesia:start([{dump_log_time_threshold,0}])),
+
+
+ ?match(ok,mnesia:start([{dump_log_write_threshold,100},
+ {dump_log_time_threshold, Time}])),
+
+ ?match({atomic,ok},mnesia:create_table(test_table,
+ [{disc_copies, Nodes},
+ {attributes,
+ record_info(fields,
+ test_table)}])),
+
+ %% Check that nothing is dumped when within time threshold
+ ?match(ok, do_trans(1)),
+ check_logs(0),
+
+ ?match(Time, mnesia:system_info(dump_log_time_threshold)),
+
+ %% Check that things get dumped when time threshold exceeded
+ ?match(ok, do_trans(5)),
+ receive after Time+2000 -> ok end,
+ check_logs(6),
+
+ ?verify_mnesia([node()], []),
+ ?cleanup(1, Config),
+ ok.
+
+%%%%%%%%
+%%
+%% Help functions for dump log
+
+%% Do a transaction N times
+do_trans(0) -> ok;
+do_trans(N) ->
+ Fun = fun() ->
+ XX=incr(),
+ mnesia:write(#test_table{i=XX})
+ end,
+ {atomic, ok} = mnesia:transaction(Fun),
+ do_trans(N-1).
+
+%% An increasing number
+incr() ->
+ case get(bloody_counter) of
+ undefined -> put(bloody_counter, 2), 1;
+ Num -> put(bloody_counter, Num+1)
+ end.
+
+%%
+%% Check that the correct number of transactions have been recorded.
+%%-record(test_table,{i,a1,a2,a3}).
+check_logs(N) ->
+ File = mnesia_lib:tab2dcl(test_table),
+ Args = [{file, File}, {name, testing}, {repair, true}, {mode, read_only}],
+
+ if N == 0 ->
+ ?match(false, mnesia_lib:exists(File));
+ true ->
+ ?match(true, mnesia_lib:exists(File)),
+ ?match({ok, _Log}, disk_log:open(Args)),
+
+ {Cont, Terms} = disk_log:chunk(testing, start),
+ ?match(eof, disk_log:chunk(testing, Cont)),
+ %%?verbose("N: ~p, L: ~p~n", [N, L]),
+ disk_log:close(testing),
+
+ %% Correct number of records in file
+ ?match({N, N}, {N, length(Terms) -1 }) %% Ignore Header
+ end.
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+dump_log_load_regulation(doc) ->
+ ["Test the load regulation of the dumper"];
+dump_log_load_regulation(suite) ->
+ [];
+dump_log_load_regulation(Config) when is_list(Config) ->
+ Nodes = ?acquire_nodes(1, Config),
+ Param = dump_log_load_regulation,
+
+ %% Normal
+ NoReg = false,
+ ?match(NoReg, mnesia:system_info(Param)),
+ ?match([], mnesia_test_lib:stop_mnesia(Nodes)),
+
+ %% Bad
+ Bad = arne_anka,
+ ?match({error, {bad_type, Param, Bad}},
+ mnesia:start([{Param, Bad}])),
+
+ %% Regulation activated
+ Reg = true,
+ ?match(ok,mnesia:start([{Param, Reg}])),
+ ?match(Reg, mnesia:system_info(Param)),
+
+ Args =
+ [{db_nodes, Nodes},
+ {driver_nodes, Nodes},
+ {replica_nodes, Nodes},
+ {n_drivers_per_node, 5},
+ {n_branches, length(Nodes) * 10},
+ {n_accounts_per_branch, 5},
+ {replica_type, disc_copies},
+ {stop_after, timer:seconds(30)},
+ {report_interval, timer:seconds(10)},
+ {use_running_mnesia, true},
+ {reuse_history_id, true}],
+
+ ?match({ok, _}, mnesia_tpcb:start(Args)),
+
+ ?verify_mnesia(Nodes, []),
+ ?cleanup(1, Config),
+ ok.
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+embedded_mnemosyne(doc) ->
+ ["Start Mnemosyne as an embedded part of Mnesia",
+ "on some of the nodes"];
+embedded_mnemosyne(suite) ->
+ [];
+embedded_mnemosyne(Config) when is_list(Config) ->
+ Nodes = ?acquire_nodes(1, Config),
+ Param = embedded_mnemosyne,
+
+ %% Normal
+ NoMnem = false,
+ ?match(NoMnem, mnesia:system_info(Param)),
+ ?match(undefined, whereis(mnemosyne_catalog)),
+ ?match([], mnesia_test_lib:stop_mnesia(Nodes)),
+
+ %% Bad
+ Bad = arne_anka,
+ ?match({error, {bad_type, Param, Bad}},
+ mnesia:start([{Param, Bad}])),
+
+ case code:priv_dir(mnemosyne) of
+ {error, _} -> %% No mnemosyne on later systems
+ ok;
+ _ ->
+ %% Mnemosyne as embedded application
+ Mnem = true,
+ ?match(undefined, whereis(mnemosyne_catalog)),
+ ?match(ok,mnesia:start([{Param, Mnem}])),
+ ?match(Mnem, mnesia:system_info(Param)),
+ ?match(Pid when is_pid(Pid), whereis(mnemosyne_catalog)),
+ ?match([], mnesia_test_lib:stop_mnesia(Nodes)),
+ ?match(undefined, whereis(mnemosyne_catalog))
+ end,
+ ?verify_mnesia([], Nodes),
+ ?cleanup(1, Config),
+ ok.
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+ignore_fallback_at_startup(doc) ->
+ ["Start Mnesia without rollback of the database to the fallback. ",
+ "Once Mnesia has been (re)started the installed fallback should",
+ "be handled as a normal active fallback.",
+ "Install a customized event module which disables the termination",
+ "of Mnesia when mnesia_down occurrs with an active fallback."].
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+max_wait_for_decision(doc) ->
+ ["Provoke Mnesia to make a forced decision of the outome",
+ "of a heavy weight transaction."].
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+send_compressed(doc) -> [];
+send_compressed(suite) -> [];
+send_compressed(Config) ->
+ [N1,N2] = Nodes = ?acquire_nodes(2, Config),
+ ?match({atomic,ok}, mnesia:create_table(t0, [{ram_copies,[N1,N2]}])),
+ ?match({atomic,ok}, mnesia:create_table(t1, [{disc_copies,[N1,N2]}])),
+ ?match({atomic,ok}, mnesia:create_table(t2, [{disc_only_copies,[N1,N2]}])),
+
+ Max = 1000,
+ Create = fun(Tab) -> [mnesia:write({Tab, N, {N, "FILLER-123490878345asdasd"}})
+ || N <- lists:seq(1, Max)],
+ ok
+ end,
+
+ ?match([], mnesia_test_lib:kill_mnesia([N2])),
+
+ ?match([], mnesia_test_lib:kill_mnesia([N1])),
+ ?match(ok, mnesia:start([{send_compressed, 9}])),
+ ?match(ok, mnesia:wait_for_tables([t0,t1,t2], 5000)),
+
+ ?match({atomic, ok}, mnesia:transaction(Create, [t0])),
+ ?match({atomic, ok}, mnesia:transaction(Create, [t1])),
+ ?match({atomic, ok}, mnesia:transaction(Create, [t2])),
+
+ ?match([], mnesia_test_lib:start_mnesia([N2], [t0,t1,t2])),
+
+ Verify = fun(Tab) ->
+ [ [{Tab,N,{N,_}}] = mnesia:read(Tab, N) || N <- lists:seq(1, Max)],
+ ok
+ end,
+ ?match({atomic, ok}, rpc:call(N1, mnesia, transaction, [Verify, [t0]])),
+ ?match({atomic, ok}, rpc:call(N1, mnesia, transaction, [Verify, [t1]])),
+ ?match({atomic, ok}, rpc:call(N1, mnesia, transaction, [Verify, [t2]])),
+
+ ?match({atomic, ok}, rpc:call(N2, mnesia, transaction, [Verify, [t0]])),
+ ?match({atomic, ok}, rpc:call(N2, mnesia, transaction, [Verify, [t1]])),
+ ?match({atomic, ok}, rpc:call(N2, mnesia, transaction, [Verify, [t2]])),
+
+ ?verify_mnesia(Nodes, []),
+ ?cleanup(1, Config),
+ ok.
+
+app_test(doc) -> [];
+app_test(suite) -> [];
+app_test(_Config) ->
+ ?match(ok,test_server:app_test(mnesia)),
+ ok.
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+event_module(doc) ->
+ ["Replace the event module with another module and use it as",
+ "receiver of the various system and table events. Provoke",
+ "coverage of all kinds of events."];
+event_module(suite) -> [];
+event_module(Config) when is_list(Config) ->
+ Filter = fun({mnesia_system_event,{mnesia_info, _, _}}) -> false;
+ (_) -> true
+ end,
+
+ [_N1, N2]=Nodes=?acquire_schema(2, Config),
+
+ Def = case mnesia_test_lib:diskless(Config) of
+ true -> [{event_module, mnesia_config_event},
+ {extra_db_nodes, Nodes}];
+ false ->
+ [{event_module, mnesia_config_event}]
+ end,
+
+ ?match({[ok, ok], []}, rpc:multicall(Nodes, mnesia, start, [Def])),
+ receive after 1000 -> ok end,
+ mnesia_event ! {get_log, self()},
+ DebugLog1 = receive
+ {log, L1} -> L1
+ after 10000 -> [timeout]
+ end,
+ ?match([{mnesia_system_event,{mnesia_up,N2}}],
+ lists:filter(Filter, DebugLog1)),
+ mnesia_test_lib:kill_mnesia([N2]),
+ receive after 2000 -> ok end,
+
+ ?match({[ok], []}, rpc:multicall([N2], mnesia, start, [])),
+
+ receive after 1000 -> ok end,
+ mnesia_event ! {get_log, self()},
+ DebugLog = receive
+ {log, L} -> L
+ after 10000 -> [timeout]
+ end,
+ ?match([{mnesia_system_event,{mnesia_up,N2}},
+ {mnesia_system_event,{mnesia_down,N2}},
+ {mnesia_system_event,{mnesia_up, N2}}],
+ lists:filter(Filter, DebugLog)),
+ ?verify_mnesia(Nodes, []),
+ ?cleanup(1, Config),
+ ok.
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+schema_config(doc) ->
+ ["Try many configurations with various schema_location's with and",
+ "without explicit extra_db_nodes. Do also provoke various schema merge",
+ "situations. Most of the other test suites focusses on tests where the",
+ "schema is residing on disc. Now it is time to perform an exhaustive",
+ "elaboration with various disc less configurations."];
+schema_config(suite) ->
+ [
+ start_one_disc_full_then_one_disc_less,
+ start_first_one_disc_less_then_one_disc_full,
+ start_first_one_disc_less_then_two_more_disc_less,
+ schema_location_and_extra_db_nodes_combinations,
+ table_load_to_disc_less_nodes,
+ schema_merge,
+ dynamic_connect
+ ].
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+start_one_disc_full_then_one_disc_less(doc)->
+ ["Start a disk node and then a disk less one. Distribute some",
+ "tables between them."];
+start_one_disc_full_then_one_disc_less(suite) -> [];
+start_one_disc_full_then_one_disc_less(Config) when is_list(Config) ->
+ [N1, N2] = ?init(2, Config),
+ ?match(ok, mnesia:create_schema([N1])),
+ ?match([], mnesia_test_lib:start_mnesia([N1])),
+
+ ?match({atomic, ok}, mnesia:add_table_copy(schema, N2, ram_copies)),
+
+ ?match(ok, rpc:call(N2, mnesia, start, [[{schema_location, ram},
+ {extra_db_nodes, [N1]}]])),
+ mnesia_test_lib:sync_tables([N1, N2], [schema]),
+
+ %% Now create some tables
+ ?match({atomic,ok},
+ mnesia:create_table(test_table,
+ [{ram_copies, [N1, N2]},
+ {attributes,
+ record_info(fields,test_table)}])),
+
+ ?match({atomic,ok},
+ rpc:call(
+ N2, mnesia,create_table, [test_table2,
+ [{ram_copies, [N1, N2]},
+ {attributes,
+ record_info(fields,test_table2)}]])),
+
+ %% Write something on one end ...
+ Rec = #test_table{i=55},
+ ?match({atomic, ok},
+ mnesia:transaction(fun() -> mnesia:write(Rec) end)),
+
+ %% ... and read it in the other
+ ?match({atomic, [Rec]},
+ rpc:call(N2, mnesia, transaction,
+ [fun() -> mnesia:read({test_table, 55}) end])),
+
+
+ %% Then do the same but start at the other end
+ Rec2 = #test_table2{i=155},
+ ?match({atomic, ok},
+ rpc:call(N2, mnesia, transaction,
+ [fun() ->
+ mnesia:write(Rec2) end
+ ])),
+
+ ?match({atomic, [Rec2]},
+ mnesia:transaction(fun() -> mnesia:read({test_table2, 155}) end)),
+
+ ?verify_mnesia([N1, N2], []),
+ ?cleanup(2, Config),
+ ok.
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+start_first_one_disc_less_then_one_disc_full(doc)->
+ ["no_doc"];
+start_first_one_disc_less_then_one_disc_full(suite) -> [];
+start_first_one_disc_less_then_one_disc_full(Config) when is_list(Config) ->
+ [N1, N2] = Nodes = ?init(2, Config),
+ ?match(ok, mnesia:create_schema([N1])),
+ ?match([], mnesia_test_lib:start_mnesia([N1])),
+
+ ?match({atomic, ok}, mnesia:add_table_copy(schema, N2, ram_copies)),
+
+ ?match(ok, rpc:call(N2, mnesia, start, [[{schema_location, ram},
+ {extra_db_nodes, Nodes}]])),
+
+ mnesia_test_lib:sync_tables([N1, N2], [schema]),
+
+ mnesia_test_lib:kill_mnesia(Nodes),
+ receive after 2000 -> ok end,
+ ?match([], mnesia_test_lib:start_mnesia(Nodes)),
+
+ mnesia_test_lib:sync_tables([N1, N2], [schema]),
+
+ %% Now create some tables
+ ?match({atomic,ok},
+ rpc:call(
+ N1, mnesia,create_table, [test_table,
+ [%%{disc_copies, [node()]},
+ {ram_copies, [N1, N2]},
+ {attributes,
+ record_info(fields,test_table)}]])),
+ mnesia_test_lib:sync_tables([N1, N2], [test_table]),
+
+ ?match({atomic,ok},
+ rpc:call(
+ N2, mnesia,create_table, [test_table2,
+ [%%{disc_copies, [node()]},
+ {ram_copies, [N1, N2]},
+ {attributes,
+ record_info(fields,test_table2)}]])),
+
+ mnesia_test_lib:sync_tables([N1, N2], [test_table, test_table2]),
+
+ %% Assure tables loaded
+ ?match({[ok, ok], []},
+ rpc:multicall([N1, N2], mnesia, wait_for_tables,
+ [[schema, test_table, test_table2], 10000])),
+
+ %% Write something on one end ...
+ Rec = #test_table{i=55},
+ ?match({atomic, ok},
+ rpc:call(N1, mnesia, transaction,
+ [fun() -> mnesia:write(Rec) end])),
+
+ %% ... and read it in the other
+ ?match({atomic, [Rec]},
+ rpc:call(N2, mnesia, transaction,
+ [fun() -> mnesia:read({test_table, 55}) end])),
+
+ %% Then do the same but start at the other end
+ Rec2 = #test_table2{i=155},
+ ?match({atomic, ok},
+ rpc:call(N2, mnesia, transaction,
+ [fun() ->
+ mnesia:write(Rec2) end
+ ])),
+
+ ?match({atomic, [Rec2]},
+ rpc:call(N1, mnesia, transaction,
+ [fun() -> mnesia:read({test_table2, 155}) end])),
+
+ ?verify_mnesia(Nodes, []),
+ ?cleanup(1, Config),
+ ok.
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+start_first_one_disc_less_then_two_more_disc_less(doc)->
+ ["no doc"];
+start_first_one_disc_less_then_two_more_disc_less(suite) -> [];
+start_first_one_disc_less_then_two_more_disc_less(Config) when is_list(Config) ->
+ Nodes = [N1, N2, N3] = ?init(3, Config),
+
+ ?match(ok, rpc:call(N1, mnesia, start, [[{schema_location, ram}]])),
+
+ %% Really should use test_lib:mnesia_start for these ones but ...
+ ?match({atomic, ok},
+ rpc:call(N1, mnesia,add_table_copy, [schema, N2, ram_copies])),
+ ?match({atomic, ok},
+ rpc:call(N1, mnesia,add_table_copy, [schema, N3, ram_copies])),
+
+ ?match(ok, rpc:call(N2, mnesia, start, [[{schema_location, ram},
+ {extra_db_nodes, [N1]}]])),
+ ?match(ok, rpc:call(N3, mnesia, start, [[{schema_location, ram},
+ {extra_db_nodes, [N1, N2]}]])),
+
+ %% Now create some tables
+ ?match({atomic,ok},
+ rpc:call(
+ N1, mnesia,create_table, [test_table,
+ [%%{disc_copies, [node()]},
+ {ram_copies, [N1, N2, N3]},
+ {attributes,
+ record_info(fields,test_table)}]])),
+
+ %% Assure tables loaded
+ ?match({[ok, ok, ok], []},
+ rpc:multicall([N1, N2, N3], mnesia, wait_for_tables,
+ [[test_table], 1000])),
+
+ %% Write something on one end ...
+ ?match({atomic, ok},
+ rpc:call(N1, mnesia, transaction,
+ [fun() -> mnesia:write(#test_table{i=44}) end])),
+
+ %% Force synchronicity
+ ?match({atomic, ok},
+ rpc:call(N1, mnesia, transaction,
+ [fun() -> mnesia:write_lock_table(test_table) end])),
+
+ %% ... and read it in the others
+ ?match({[{atomic, [{test_table, 44, _, _, _}]},
+ {atomic, [{test_table, 44, _, _, _}]}], []},
+ rpc:multicall([N2, N3], mnesia, transaction,
+ [fun() -> mnesia:read({test_table, 44}) end])),
+
+ %% Then do the other way around
+ ?match({atomic, ok},
+ rpc:call(N3, mnesia, transaction,
+ [fun() -> mnesia:write(#test_table{i=33}) end])),
+ %% Force synchronicity
+ ?match({atomic, ok},
+ rpc:call(N3, mnesia, transaction,
+ [fun() -> mnesia:write_lock_table(test_table) end])),
+
+ ?match({[{atomic, [{test_table, 44, _, _, _}]},
+ {atomic, [{test_table, 44, _, _, _}]}], []},
+ rpc:multicall([N1, N2], mnesia, transaction,
+ [fun() -> mnesia:read({test_table, 44}) end])),
+
+ mnesia_test_lib:reload_appls([mnesia], Nodes),
+ ok.
+
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+schema_location_and_extra_db_nodes_combinations(doc)->
+ ["Test schema loaction and extra_db_nodes combinations."];
+schema_location_and_extra_db_nodes_combinations(suite) -> [];
+schema_location_and_extra_db_nodes_combinations(Config) when is_list(Config) ->
+ [N1, N2] = Nodes = ?init(2, Config),
+ ?match(ok, mnesia:create_schema([N1])),
+ ?match([], mnesia_test_lib:start_mnesia([N1])),
+
+ %% Really should use test_lib:mnesia_start for these ones but ...
+ ?match({atomic, ok},
+ rpc:call(N1, mnesia,add_table_copy, [schema, N2, ram_copies])),
+
+ ?match(ok, rpc:call(N2, mnesia, start, [[{schema_location, ram},
+ {extra_db_nodes, [N1]}]])),
+
+ %% Assure tables loaded
+ ?match({[ok, ok], []},
+ rpc:multicall([N1, N2], mnesia, wait_for_tables,
+ [[schema], 10000])),
+
+ ?verify_mnesia(Nodes, []),
+ ?cleanup(2, Config),
+ ok.
+
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+table_load_to_disc_less_nodes(doc)->
+ ["Load tables to disc less nodes"];
+table_load_to_disc_less_nodes(suite) -> [];
+table_load_to_disc_less_nodes(Config) when is_list(Config) ->
+ [N1, N2] = ?init(2, Config),
+
+ ?match(ok, rpc:call(N1, mnesia, start, [[{schema_location, ram}]])),
+
+ %% Really should use test_lib:mnesia_start for these ones but ...
+ ?match({atomic, ok},
+ rpc:call(N1, mnesia,add_table_copy, [schema, N2, ram_copies])),
+
+ ?match(ok, rpc:call(N2, mnesia, start, [[{schema_location, ram},
+ {extra_db_nodes, [N1]}]])),
+
+ %% Now create some tables
+ ?match({atomic,ok},
+ rpc:call(
+ N1, mnesia,create_table, [test_table,
+ [%%{disc_copies, [node()]},
+ {ram_copies, [N1, N2]},
+ {attributes,
+ record_info(fields,test_table)}]])),
+
+ %% Assure tables loaded
+ ?match({[ok, ok], []},
+ rpc:multicall([N1, N2], mnesia, wait_for_tables,
+ [[test_table], 1000])),
+
+ %% Write something on one end ...
+ ?match({atomic, ok},
+ rpc:call(N1, mnesia, transaction,
+ [fun() -> mnesia:write(#test_table{i=44}) end])),
+
+ %% Force synchronicity
+ ?match({atomic, ok},
+ rpc:call(N1, mnesia, transaction,
+ [fun() -> mnesia:write_lock_table(test_table) end])),
+
+ %% ... and read it in the others
+ ?match({atomic, [{test_table, 44, _, _, _}]},
+ rpc:call(N2, mnesia, transaction,
+ [fun() -> mnesia:read({test_table, 44}) end])),
+
+ ?cleanup(2, Config),
+ ok.
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+schema_merge(doc) ->
+ ["Provoke various schema merge situations.",
+ "Perform various schema updates while some nodes are down,",
+ "stop the started nodes, start the stopped nodes and perform",
+ "schema updates. Now we have a situation were some of the table",
+ "definitions have been changed on two or more nodes independently",
+ "of each other and when Mnesia on the nodes tries to connect",
+ "to each other at restart the schema will be merged.",
+ "Do also try to provoke schema merge situations were the",
+ "schema cannot be merged."];
+
+schema_merge(suite) -> [];
+
+schema_merge(Config) when is_list(Config) ->
+ [N1, N2]=Nodes=?acquire(2,Config),
+
+ mnesia_test_lib:kill_mnesia([N2]),
+ receive after 1000 -> ok end,
+
+ Storage = mnesia_test_lib:storage_type(disc_copies, Config),
+ ?match({atomic,ok},
+ rpc:call(
+ N1, mnesia,create_table,
+ [test_table,
+ [{Storage, [N1]},
+ {attributes,
+ record_info(fields,test_table)}]])),
+
+ ?match({atomic, ok},
+ rpc:call(N1, mnesia, transaction,
+ [fun() -> mnesia:write(#test_table{i=44}) end])),
+
+ mnesia_test_lib:kill_mnesia([N1]),
+ receive after 2000 -> ok end,
+ %% Can't use std start because it waits for schema
+ ?match(ok, rpc:call(N2, mnesia, start, [])),
+
+ ?match({atomic,ok},
+ rpc:call(
+ N2, mnesia,create_table,
+ [test_table2,
+ [{Storage, [N2]},
+ {attributes,
+ record_info(fields,test_table2)}]])),
+
+ receive after 5000 -> ok end,
+
+ ?match({atomic, ok},
+ rpc:call(N2, mnesia, transaction,
+ [fun() -> mnesia:write(#test_table2{i=33}) end])),
+
+ %% Can't use std start because it waits for schema
+ ?match(ok, rpc:call(N1, mnesia, start, [])),
+
+ %% Assure tables loaded
+ ?match({[ok, ok], []},
+ rpc:multicall([N1, N2], mnesia, wait_for_tables,
+ [[schema, test_table, test_table2], 10000])),
+
+ %% ... and read it in the others
+ ?match({[{atomic, [{test_table, 44, _, _, _}]},
+ {atomic, [{test_table, 44, _, _, _}]}], []},
+ rpc:multicall([N1, N2], mnesia, transaction,
+ [fun() -> mnesia:read({test_table, 44}) end])),
+
+ ?match({[{atomic, [{test_table2, 33, _}]},
+ {atomic, [{test_table2, 33, _}]}], []},
+ rpc:multicall([N1, N2], mnesia, transaction,
+ [fun() -> mnesia:read({test_table2, 33}) end])),
+
+ ?verify_mnesia(Nodes, []),
+ ?cleanup(2, Config),
+ ok.
+
+
+-define(connect(Nodes), mnesia:change_config(extra_db_nodes, Nodes)).
+-define(rpc_connect(From, Nodes),
+ rpc:call(From, mnesia, change_config, [extra_db_nodes, Nodes])).
+
+
+sort({ok, NS}) ->
+ {ok, lists:sort(NS)};
+sort(Ns) when is_tuple(Ns) ->
+ Ns;
+sort(NS) when is_list(NS) ->
+ lists:sort(NS).
+
+
+dynamic_connect(doc) ->
+ ["Test the new functionality where we start mnesia first and then "
+ "connect to the other mnesia nodes"];
+dynamic_connect(suite) ->
+ [
+ dynamic_basic,
+ dynamic_ext,
+ dynamic_bad
+ ].
+
+
+dynamic_basic(suite) -> [];
+dynamic_basic(Config) when is_list(Config) ->
+ Nodes = [N1, N2, N3] = ?acquire_nodes(3, Config),
+ SNs = lists:sort(Nodes),
+
+ ?match({atomic, ok}, mnesia:create_table(tab1, [{ram_copies, Nodes--[N1]}, {disc_copies, [N1]}])),
+ ?match({atomic, ok}, mnesia:create_table(tab2, [{disc_copies, Nodes}])),
+
+ ?match({ok, SNs}, sort(?rpc_connect(N1, Nodes))), %% What shall happen?
+ ?match({ok, []}, sort(?rpc_connect(N1, [nonode@nothosted]))), %% What shall happen?
+
+ ?match([], mnesia_test_lib:kill_mnesia([N2])),
+ ?match(ok, mnesia:delete_schema([N2])),
+
+ ?match(ok, mnesia:dirty_write({tab1, 1, 1})),
+ ?match(ok, mnesia:dirty_write({tab2, 1, 1})),
+
+ ?match(ok, rpc:call(N2, mnesia, start, [[{extra_db_nodes, [N1]}]])),
+ ?match(ok, rpc:call(N2, mnesia, wait_for_tables, [[tab1,tab2],5000])),
+ io:format("Here ~p ~n",[?LINE]),
+ check_storage(N2, N1, [N3]),
+ ?match(SNs, sort(rpc:call(N1, mnesia, system_info, [running_db_nodes]))),
+ ?match(SNs, sort(rpc:call(N2, mnesia, system_info, [running_db_nodes]))),
+
+ ?match([], mnesia_test_lib:kill_mnesia([N3])),
+ ?match(ok, mnesia:delete_schema([N3])),
+
+ io:format("T1 ~p ~n",[rpc:call(N3,?MODULE,c_nodes,[])]),
+ ?match(ok, rpc:call(N3, mnesia, start, [])),
+ io:format("T2 ~p ~n",[rpc:call(N3,?MODULE,c_nodes,[])]),
+ timer:sleep(2000),
+ io:format("T3 ~p ~n",[rpc:call(N3,?MODULE,c_nodes,[])]),
+ ?match({ok, [N1]}, sort(?rpc_connect(N3, [N1]))),
+ io:format("T4 ~p ~n",[rpc:call(N3,?MODULE,c_nodes,[])]),
+ ?match(ok, rpc:call(N3, mnesia, wait_for_tables, [[tab1,tab2],5000])),
+ io:format("Here ~p ~n",[?LINE]),
+ check_storage(N3, N1, [N2]),
+ ?match(SNs, sort(rpc:call(N1, mnesia, system_info, [running_db_nodes]))),
+ ?match(SNs, sort(rpc:call(N2, mnesia, system_info, [running_db_nodes]))),
+
+ ?match([], mnesia_test_lib:kill_mnesia([N3])),
+ ?match(ok, mnesia:delete_schema([N3])),
+
+ ?match(ok, rpc:call(N3, mnesia, start, [])),
+ ?match({ok, [N3]}, sort(?rpc_connect(N1, [N3]))),
+ ?match(ok, rpc:call(N3, mnesia, wait_for_tables, [[tab1,tab2],5000])),
+ io:format("Here ~p ~n",[?LINE]),
+ check_storage(N3, N1, [N2]),
+ ?match(SNs, sort(rpc:call(N1, mnesia, system_info, [running_db_nodes]))),
+ ?match(SNs, sort(rpc:call(N2, mnesia, system_info, [running_db_nodes]))),
+
+ mnesia_test_lib:kill_mnesia([N2]),
+ ?match(ok, mnesia:delete_schema([N2])),
+ ?match({atomic, ok}, mnesia:del_table_copy(schema, N2)),
+
+ % Ok, we have now removed references to node N2 from the other nodes
+ % mnesia should come up now.
+ ?match({atomic, ok}, mnesia:add_table_copy(tab1, N2, ram_copies)),
+
+ ?match(ok, rpc:call(N2, mnesia, start, [])),
+ ?match({ok, _}, sort(?rpc_connect(N2, [N3]))),
+
+ ?match(SNs, sort(rpc:call(N1, mnesia, system_info, [running_db_nodes]))),
+ ?match(SNs, sort(rpc:call(N2, mnesia, system_info, [running_db_nodes]))),
+ ?match(SNs, sort(rpc:call(N3, mnesia, system_info, [running_db_nodes]))),
+
+ ?match(ok, rpc:call(N2, mnesia, wait_for_tables, [[tab1], 1000])),
+ ?match([{tab1, 1, 1}], rpc:call(N2, mnesia, dirty_read, [tab1, 1])),
+
+ mnesia_test_lib:kill_mnesia([N2]),
+
+ %%% SYNC!!!
+ timer:sleep(1000),
+
+ ?match([N3,N1], sort(rpc:call(N1, mnesia, system_info, [running_db_nodes]))),
+ ?match([N3,N1], sort(rpc:call(N3, mnesia, system_info, [running_db_nodes]))),
+
+ ?match(ok, rpc:call(N2, mnesia, start, [])),
+ ?match({ok, _}, sort(?rpc_connect(N3, [N2]))),
+
+ ?match(SNs, sort(rpc:call(N1, mnesia, system_info, [running_db_nodes]))),
+ ?match(SNs, sort(rpc:call(N2, mnesia, system_info, [running_db_nodes]))),
+ ?match(SNs, sort(rpc:call(N3, mnesia, system_info, [running_db_nodes]))),
+
+ ?match(ok, rpc:call(N2, mnesia, wait_for_tables, [[tab1], 1000])),
+ ?match([{tab1, 1, 1}], rpc:call(N2, mnesia, dirty_read, [tab1, 1])),
+
+ ?verify_mnesia(Nodes, []),
+%% ?cleanup(3, Config).
+ ok.
+
+c_nodes() ->
+ {mnesia_lib:val({current, db_nodes}),mnesia_lib:val(recover_nodes)}.
+
+
+dynamic_ext(suite) -> [];
+dynamic_ext(Config) when is_list(Config) ->
+ Ns = [N1,N2] = ?acquire_nodes(2, Config),
+ SNs = lists:sort([N1,N2]),
+
+ ?match({atomic, ok}, mnesia:create_table(tab0, [{disc_copies, [N1,N2]}])),
+ ?match({atomic, ok}, mnesia:create_table(tab1, [{ram_copies, [N2]}])),
+ ?match({atomic, ok}, mnesia:create_table(tab2, [{disc_copies, [N2]}])),
+ ?match({atomic, ok}, mnesia:create_table(tab3, [{disc_only_copies, [N2]}])),
+
+ mnesia_test_lib:kill_mnesia([N2]),
+ ?match(ok, mnesia:delete_schema([N2])),
+ ?match(ok, rpc:call(N2, mnesia, start, [[{extra_db_nodes, [N1]}]])),
+
+ ?match(SNs, sort(rpc:call(N1, mnesia, system_info, [running_db_nodes]))),
+ ?match(SNs, sort(rpc:call(N2, mnesia, system_info, [running_db_nodes]))),
+
+ ?match(ok, rpc:call(N2, mnesia, wait_for_tables, [[tab0,tab1,tab2,tab3], 2000])),
+
+ Check = fun({Tab,Storage}) ->
+ ?match(Storage, rpc:call(N2, mnesia, table_info, [Tab, storage_type])),
+ ?match([{N2,Storage}],
+ lists:sort(rpc:call(N2, mnesia, table_info, [Tab, where_to_commit])))
+ end,
+ [Check(Test) || Test <- [{tab1, ram_copies},{tab2, disc_copies},{tab3, disc_only_copies}]],
+
+ T = now(),
+ ?match(ok, mnesia:dirty_write({tab0, 42, T})),
+ ?match(ok, mnesia:dirty_write({tab1, 42, T})),
+ ?match(ok, mnesia:dirty_write({tab2, 42, T})),
+ ?match(ok, mnesia:dirty_write({tab3, 42, T})),
+
+ ?match(stopped, rpc:call(N2, mnesia, stop, [])),
+ ?match(ok, rpc:call(N2, mnesia, start, [])),
+ ?match(SNs, sort(rpc:call(N2, mnesia, system_info, [running_db_nodes]))),
+ ?match(ok, mnesia:wait_for_tables([tab0,tab1,tab2,tab3], 10000)),
+ ?match(ok, rpc:call(N2, mnesia, wait_for_tables, [[tab1,tab2,tab3], 100])),
+ ?match([], mnesia:dirty_read({tab1, 41})),
+ ?match([{tab2,42,T}], mnesia:dirty_read({tab2, 42})),
+ ?match([{tab3,42,T}], mnesia:dirty_read({tab3, 42})),
+
+ mnesia_test_lib:kill_mnesia([N2]),
+ ?match(ok, mnesia:delete_schema([N2])),
+
+ ?match(stopped, rpc:call(N1, mnesia, stop, [])),
+
+ ?match(ok, rpc:call(N2, mnesia, start, [[{extra_db_nodes,[N1,N2]}]])),
+ ?match({timeout,[tab0]}, rpc:call(N2, mnesia, wait_for_tables, [[tab0], 500])),
+
+ ?match(ok, rpc:call(N1, mnesia, start, [[{extra_db_nodes, [N1,N2]}]])),
+ ?match(ok, rpc:call(N1, mnesia, wait_for_tables, [[tab0], 1500])),
+ ?match(ok, rpc:call(N2, mnesia, wait_for_tables, [[tab0], 1500])),
+ ?match([{tab0,42,T}], mnesia:dirty_read({tab0, 42})),
+ ?match([{tab0,42,T}], rpc:call(N2, mnesia,dirty_read,[{tab0,42}])),
+
+ ?match(stopped, rpc:call(N1, mnesia, stop, [])),
+ mnesia_test_lib:kill_mnesia([N2]),
+ ?match(ok, mnesia:delete_schema([N2])),
+ ?match(ok, rpc:call(N1, mnesia, start, [[{extra_db_nodes, [N1,N2]}]])),
+ ?match({timeout,[tab0]}, rpc:call(N1, mnesia, wait_for_tables, [[tab0], 500])),
+
+ ?match(ok, rpc:call(N2, mnesia, start, [[{extra_db_nodes,[N1,N2]}]])),
+ ?match(ok, rpc:call(N1, mnesia, wait_for_tables, [[tab0], 1500])),
+ ?match(ok, rpc:call(N2, mnesia, wait_for_tables, [[tab0], 1500])),
+ ?match([{tab0,42,T}], mnesia:dirty_read({tab0, 42})),
+ ?match([{tab0,42,T}], rpc:call(N2,mnesia,dirty_read,[{tab0,42}])),
+
+ ?verify_mnesia(Ns, []),
+ ok.
+
+check_storage(Me, Orig, Other) ->
+ io:format("Nodes ~p ~p ~p~n",[Me,Orig,Other]),
+ rpc:multicall(Other, sys, status, [mnesia_locker]),
+ rpc:call(Me, sys, status, [mnesia_locker]),
+ rpc:call(Orig, sys, status, [mnesia_locker]),
+ rpc:multicall(Other, sys, status, [mnesia_controller]),
+ rpc:call(Me, sys, status, [mnesia_controller]),
+ rpc:call(Orig, sys, status, [mnesia_controller]),
+ %% Verify disc_copies
+ W2C = lists:sort([{Node,disc_copies} || Node <- [Me,Orig|Other]]),
+ W2W = lists:sort([Me,Orig|Other]),
+ ?match(disc_copies, rpc:call(Orig, mnesia, table_info, [schema, storage_type])),
+ ?match(disc_copies, rpc:call(Me, mnesia, table_info, [schema, storage_type])),
+ ?match(W2C, lists:sort(rpc:call(Orig, mnesia, table_info, [schema, where_to_commit]))),
+ ?match(W2C, lists:sort(rpc:call(Me, mnesia, table_info, [schema, where_to_commit]))),
+
+ ?match(disc_copies, rpc:call(Orig, mnesia, table_info, [tab2, storage_type])),
+ ?match(disc_copies, rpc:call(Me, mnesia, table_info, [tab2, storage_type])),
+ ?match(W2W, lists:sort(rpc:call(Me, mnesia, table_info, [tab2, where_to_write]))),
+ ?match(Me, rpc:call(Me, mnesia, table_info, [tab2, where_to_read])),
+
+ ?match(W2C, lists:sort(rpc:call(Orig, mnesia, table_info, [tab2, where_to_commit]))),
+ ?match(W2C, lists:sort(rpc:call(Me, mnesia, table_info, [tab2, where_to_commit]))),
+
+ ?match([{tab1,1,1}], mnesia:dirty_read(tab1,1)),
+ ?match([{tab2,1,1}], mnesia:dirty_read(tab2,1)),
+ ?match([{tab1,1,1}], rpc:call(Me, mnesia, dirty_read, [tab1,1])),
+ ?match([{tab2,1,1}], rpc:call(Me, mnesia, dirty_read, [tab2,1])),
+
+ ?match(true, rpc:call(Me, mnesia_monitor, use_dir, [])),
+ ?match(disc_copies, rpc:call(Me, mnesia_lib, val, [{schema, storage_type}])),
+
+ mnesia_test_lib:kill_mnesia([Orig]),
+ mnesia_test_lib:kill_mnesia(Other),
+ T = now(),
+ ?match(ok, rpc:call(Me, mnesia, dirty_write, [{tab2, 42, T}])),
+ ?match(stopped, rpc:call(Me, mnesia, stop, [])),
+ ?match(ok, rpc:call(Me, mnesia, start, [])),
+ ?match([], mnesia_test_lib:start_mnesia([Orig|Other], [tab1,tab2])),
+ ?match([{tab2,42,T}], rpc:call(Me, mnesia, dirty_read, [{tab2, 42}])),
+ ?match([{tab2,42,T}], rpc:call(Orig, mnesia, dirty_read, [{tab2, 42}])),
+
+ ?match([{tab1,1,1}], mnesia:dirty_read(tab1,1)),
+ ?match([{tab2,1,1}], mnesia:dirty_read(tab2,1)),
+ ?match([{tab1,1,1}], rpc:call(Me, mnesia, dirty_read, [tab1,1])),
+ ?match([{tab2,1,1}], rpc:call(Me, mnesia, dirty_read, [tab2,1])),
+ ok.
+
+
+dynamic_bad(suite) -> [];
+dynamic_bad(Config) when is_list(Config) ->
+ Ns = [N1, N2, N3] = ?acquire_nodes(3, Config),
+ SNs = lists:sort([N2,N3]),
+
+ ?match({atomic, ok}, mnesia:change_table_copy_type(schema, N2, ram_copies)),
+ ?match({atomic, ok}, mnesia:change_table_copy_type(schema, N3, ram_copies)),
+ ?match({atomic, ok}, mnesia:create_table(tab1, [{ram_copies, Ns -- [N1]},
+ {disc_copies, [N1]}])),
+ ?match(ok, mnesia:dirty_write({tab1, 1, 1})),
+
+ mnesia_test_lib:kill_mnesia(Ns),
+ ?match({[ok, ok], []}, rpc:multicall(Ns -- [N1], mnesia, start, [])),
+ ?match({ok, [N2]}, ?rpc_connect(N3, [N2])),
+ ?match(SNs, sort(rpc:call(N2, mnesia, system_info, [running_db_nodes]))),
+ ?match(SNs, sort(rpc:call(N3, mnesia, system_info, [running_db_nodes]))),
+ ?match({badrpc, {'EXIT', {aborted, {no_exists, _, _}}}},
+ rpc:call(N2, mnesia, table_info, [tab1, where_to_read])),
+
+ ?match(ok, mnesia:start()),
+ ?match(ok, rpc:call(N2, mnesia, wait_for_tables, [[tab1], 1000])),
+ ?match(N2, rpc:call(N2, mnesia, table_info, [tab1, where_to_read])),
+ ?match([{tab1, 1, 1}], rpc:call(N2, mnesia, dirty_read, [tab1, 1])),
+
+ mnesia_test_lib:kill_mnesia(Ns),
+ ?match({[ok, ok], []}, rpc:multicall(Ns -- [N1], mnesia, start, [])),
+ ?match({ok, [N2]}, ?rpc_connect(N3, [N2])),
+ % Make a merge conflict
+ ?match({atomic, ok}, rpc:call(N3, mnesia, create_table, [tab1, []])),
+
+ io:format("We expect a mnesia crash here~n", []),
+ ?match({error,{_, _}}, mnesia:start()),
+
+ ?verify_mnesia(Ns -- [N1], []),
+ ok.
+
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+unknown_config(doc) ->
+ ["Try some unknown configuration parameters and see that expected",
+ "things happens."];
+unknown_config(suite)-> [];
+unknown_config(Config) when is_list(Config) ->
+ ?init(1, Config),
+ %% NOTE: case 1 & 2 below do not respond the same
+ ?match({error, Res} when element(1, Res) == bad_type,
+ mnesia:start([{undefined_config,[]}])),
+ %% Below does not work, but the "correct" behaviour would be to have
+ %% case 1 above to behave as the one below.
+
+ %% in mnesia-1.3 {error,{bad_type,{[],undefined_config}}}
+ ?match({error, Res} when element(1, Res) == bad_type,
+ mnesia:start([{[],undefined_config}])),
+ ?cleanup(1, Config),
+ ok.
+
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+inconsistent_database(doc) ->
+ ["Replace the event module with another module and use it as",
+ "receiver of the various system and table events. Provoke",
+ "coverage of all kinds of events."];
+inconsistent_database(suite) -> [];
+inconsistent_database(Config) when is_list(Config) ->
+ Nodes = mnesia_test_lib:prepare_test_case([{init_test_case, [mnesia]}],
+ 2, Config, ?FILE, ?LINE),
+ KillAfter = length(Nodes) * timer:minutes(5),
+ ?acquire_schema(2, Config ++ [{tc_timeout, KillAfter}]),
+
+ Ok = [ok || _N <- Nodes],
+ StartArgs = [{event_module, mnesia_inconsistent_database_test}],
+ ?match({Ok, []}, rpc:multicall(Nodes, mnesia, start, [StartArgs])),
+ ?match([], mnesia_test_lib:kill_mnesia(Nodes)),
+
+ ?match(ok, mnesia_meter:go(ram_copies, Nodes)),
+
+ mnesia_test_lib:reload_appls([mnesia], Nodes),
+ ok.
+
diff --git a/lib/mnesia/test/mnesia_consistency_test.erl b/lib/mnesia/test/mnesia_consistency_test.erl
new file mode 100644
index 0000000000..ffe8ab7ac3
--- /dev/null
+++ b/lib/mnesia/test/mnesia_consistency_test.erl
@@ -0,0 +1,1612 @@
+%%
+%% %CopyrightBegin%
+%%
+%% 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(mnesia_consistency_test).
+-author('[email protected]').
+-compile([export_all]).
+
+-include("mnesia_test_lib.hrl").
+
+init_per_testcase(Func, Conf) ->
+ mnesia_test_lib:init_per_testcase(Func, Conf).
+
+fin_per_testcase(Func, Conf) ->
+ mnesia_test_lib:fin_per_testcase(Func, Conf).
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+all(doc) ->
+ ["Verify transaction consistency",
+ "Consistency is the property of the application that requires any",
+ "execution of the transaction to take the database from one",
+ "consistent state to another. Verify that the database is",
+ "consistent at any point in time.",
+ "Verify for various configurations.",
+ " Verify for both set and bag"];
+all(suite) ->
+ [
+ consistency_after_restart,
+ consistency_after_dump_tables,
+ consistency_after_add_replica,
+ consistency_after_del_replica,
+ consistency_after_move_replica,
+ consistency_after_transform_table,
+ consistency_after_change_table_copy_type,
+ consistency_after_fallback,
+ consistency_after_restore,
+ consistency_after_rename_of_node,
+ checkpoint_retainer_consistency,
+ backup_consistency
+ ].
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% stolen from mnesia_tpcb.erl:
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%%% Account record, total size must be at least 100 bytes
+
+-define(ACCOUNT_FILLER,
+ {123456789012345678901234567890123456789012345678901234567890,
+ 123456789012345678901234567890123456789012345678901234567890,
+ 123456789012345678901234567890123456789012345678901234}).
+
+-record(account,
+ {
+ id = 0, %% Unique account id
+ branch_id = 0, %% Branch where the account is held
+ balance = 0, %% Account balance
+ filler = ?ACCOUNT_FILLER %% Gap filler to ensure size >= 100 bytes
+ }).
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%%% Branch record, total size must be at least 100 bytes
+
+-define(BRANCH_FILLER,
+ {123456789012345678901234567890123456789012345678901234567890,
+ 123456789012345678901234567890123456789012345678901234567890,
+ 123456789012345678901234567890123456789012345678901234567890}).
+
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%%% Teller record, total size must be at least 100 bytes
+
+-define(TELLER_FILLER,
+ {123456789012345678901234567890123456789012345678901234567890,
+ 123456789012345678901234567890123456789012345678901234567890,
+ 1234567890123456789012345678901234567890123456789012345678}).
+
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%%% History record, total size must be at least 50 bytes
+
+-define(HISTORY_FILLER, 1234567890).
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+-record(tab_config,
+ {
+ db_nodes = [node()],
+ replica_nodes = [node()],
+ replica_type = ram_copies,
+ use_running_mnesia = false,
+ n_branches = 1,
+ n_tellers_per_branch = 10, %% Must be 10
+ n_accounts_per_branch = 100000, %% Must be 100000
+ branch_filler = ?BRANCH_FILLER,
+ account_filler = ?ACCOUNT_FILLER,
+ teller_filler = ?TELLER_FILLER
+ }).
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% stolen from mnesia_tpcb.erl:
+
+list2rec(List, Fields, DefaultTuple) ->
+ [Name|Defaults] = tuple_to_list(DefaultTuple),
+ List2 = list2rec(List, Fields, Defaults, []),
+ list_to_tuple([Name] ++ List2).
+
+list2rec(_List, [], [], Acc) ->
+ Acc;
+list2rec(List, [F|Fields], [D|Defaults], Acc) ->
+ {Val, List2} =
+ case lists:keysearch(F, 1, List) of
+ false ->
+ {D, List};
+ {value, {F, NewVal}} ->
+ {NewVal, lists:keydelete(F, 1, List)}
+ end,
+ list2rec(List2, Fields, Defaults, Acc ++ [Val]).
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+tpcb_config(ReplicaType, _NodeConfig, Nodes, NoDriverNodes) ->
+ [{n_branches, 10},
+ {n_drivers_per_node, 10},
+ {replica_nodes, Nodes},
+ {driver_nodes, Nodes -- NoDriverNodes},
+ {use_running_mnesia, true},
+ {report_interval, infinity},
+ {n_accounts_per_branch, 100},
+ {replica_type, ReplicaType},
+ {reuse_history_id, true}].
+
+%% Stolen from mnesia_tpcb:dist
+tpcb_config_dist(ReplicaType, _NodeConfig, Nodes, _Config) ->
+ [{db_nodes, Nodes},
+ {driver_nodes, Nodes},
+ {replica_nodes, Nodes},
+ {n_drivers_per_node, 10},
+ {n_branches, 1},
+ {use_running_mnesia, true},
+ {n_accounts_per_branch, 10},
+ {replica_type, ReplicaType},
+ {stop_after, timer:minutes(15)},
+ {report_interval, timer:seconds(10)},
+ {reuse_history_id, true}].
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% stolen from mnesia_recovery_test.erl:
+
+receive_messages([]) -> [];
+receive_messages(ListOfMsgs) ->
+ receive
+ {Pid, Msg} ->
+ case lists:member(Msg, ListOfMsgs) of
+ false ->
+ ?warning("I (~p) have received unexpected msg~n ~p ~n",
+ [self(),{Pid, Msg}]),
+ receive_messages(ListOfMsgs);
+ true ->
+ ?verbose("I (~p) got msg ~p from ~p ~n", [self(),Msg, Pid]),
+ [{Pid, Msg} | receive_messages(ListOfMsgs -- [Msg])]
+ end;
+ Else -> ?warning("Recevied unexpected Msg~n ~p ~n", [Else])
+ after timer:minutes(3) ->
+ ?error("Timeout in receive msgs while waiting for ~p~n",
+ [ListOfMsgs])
+ end.
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+consistency_after_restart(suite) ->
+ [
+ consistency_after_restart_1_ram,
+ consistency_after_restart_1_disc,
+ consistency_after_restart_1_disc_only,
+ consistency_after_restart_2_ram,
+ consistency_after_restart_2_disc,
+ consistency_after_restart_2_disc_only
+ ].
+
+consistency_after_restart_1_ram(suite) -> [];
+consistency_after_restart_1_ram(Config) when is_list(Config) ->
+ consistency_after_restart(ram_copies, 2, Config).
+
+consistency_after_restart_1_disc(suite) -> [];
+consistency_after_restart_1_disc(Config) when is_list(Config) ->
+ consistency_after_restart(disc_copies, 2, Config).
+
+consistency_after_restart_1_disc_only(suite) -> [];
+consistency_after_restart_1_disc_only(Config) when is_list(Config) ->
+ consistency_after_restart(disc_only_copies, 2, Config).
+
+consistency_after_restart_2_ram(suite) -> [];
+consistency_after_restart_2_ram(Config) when is_list(Config) ->
+ consistency_after_restart(ram_copies, 3, Config).
+
+consistency_after_restart_2_disc(suite) -> [];
+consistency_after_restart_2_disc(Config) when is_list(Config) ->
+ consistency_after_restart(disc_copies, 3, Config).
+
+consistency_after_restart_2_disc_only(suite) -> [];
+consistency_after_restart_2_disc_only(Config) when is_list(Config) ->
+ consistency_after_restart(disc_only_copies, 3, Config).
+
+consistency_after_restart(ReplicaType, NodeConfig, Config) ->
+ [Node1 | _] = Nodes = ?acquire_nodes(NodeConfig, Config),
+ {success, [A]} = ?start_activities([Node1]),
+ ?log("consistency_after_restart with ~p on ~p~n",
+ [ReplicaType, Nodes]),
+ TpcbConfig = tpcb_config(ReplicaType, NodeConfig, Nodes, [Node1]),
+ mnesia_tpcb:init(TpcbConfig),
+ A ! fun () -> mnesia_tpcb:run(TpcbConfig) end,
+ timer:sleep(timer:seconds(10)),
+ mnesia_test_lib:kill_mnesia([Node1]),
+ %% Start and wait for tables to be loaded on all nodes
+ timer:sleep(timer:seconds(3)),
+ ?match([], mnesia_test_lib:start_mnesia(Nodes,[account,branch,teller, history])),
+ mnesia_tpcb:stop(),
+ ?match(ok, mnesia_tpcb:verify_tabs()),
+ ?verify_mnesia(Nodes, []).
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+consistency_after_dump_tables(suite) ->
+ [
+ consistency_after_dump_tables_1_ram,
+ consistency_after_dump_tables_2_ram
+ ].
+
+consistency_after_dump_tables_1_ram(suite) -> [];
+consistency_after_dump_tables_1_ram(Config) when is_list(Config) ->
+ consistency_after_dump_tables(ram_copies, 1, Config).
+
+consistency_after_dump_tables_2_ram(suite) -> [];
+consistency_after_dump_tables_2_ram(Config) when is_list(Config) ->
+ consistency_after_dump_tables(ram_copies, 2, Config).
+
+consistency_after_dump_tables(ReplicaType, NodeConfig, Config) ->
+ [Node1 | _] = Nodes = ?acquire_nodes(NodeConfig, Config),
+ {success, [A]} = ?start_activities([Node1]),
+ ?log("consistency_after_dump_tables with ~p on ~p~n",
+ [ReplicaType, Nodes]),
+ TpcbConfig = tpcb_config(ReplicaType, NodeConfig, Nodes, []),
+ mnesia_tpcb:init(TpcbConfig),
+ A ! fun() -> mnesia_tpcb:run(TpcbConfig) end,
+ timer:sleep(timer:seconds(10)),
+ ?match({atomic, ok}, rpc:call(Node1, mnesia, dump_tables,
+ [[branch, teller, account, history]])),
+ mnesia_tpcb:stop(),
+ ?match(ok, mnesia_tpcb:verify_tabs()),
+
+ mnesia_test_lib:kill_mnesia(Nodes),
+ timer:sleep(timer:seconds(1)),
+ ?match([], mnesia_test_lib:start_mnesia(Nodes,[account, branch,
+ teller, history])),
+ mnesia_tpcb:stop(),
+ ?match(ok, mnesia_tpcb:verify_tabs()),
+ ?verify_mnesia(Nodes, []).
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+consistency_after_add_replica(suite) ->
+ [
+ consistency_after_add_replica_2_ram,
+ consistency_after_add_replica_2_disc,
+ consistency_after_add_replica_2_disc_only,
+ consistency_after_add_replica_3_ram,
+ consistency_after_add_replica_3_disc,
+ consistency_after_add_replica_3_disc_only
+ ].
+
+consistency_after_add_replica_2_ram(suite) -> [];
+consistency_after_add_replica_2_ram(Config) when is_list(Config) ->
+ consistency_after_add_replica(ram_copies, 2, Config).
+
+consistency_after_add_replica_2_disc(suite) -> [];
+consistency_after_add_replica_2_disc(Config) when is_list(Config) ->
+ consistency_after_add_replica(disc_copies, 2, Config).
+
+consistency_after_add_replica_2_disc_only(suite) -> [];
+consistency_after_add_replica_2_disc_only(Config) when is_list(Config) ->
+ consistency_after_add_replica(disc_only_copies, 2, Config).
+
+consistency_after_add_replica_3_ram(suite) -> [];
+consistency_after_add_replica_3_ram(Config) when is_list(Config) ->
+ consistency_after_add_replica(ram_copies, 3, Config).
+
+consistency_after_add_replica_3_disc(suite) -> [];
+consistency_after_add_replica_3_disc(Config) when is_list(Config) ->
+ consistency_after_add_replica(disc_copies, 3, Config).
+
+consistency_after_add_replica_3_disc_only(suite) -> [];
+consistency_after_add_replica_3_disc_only(Config) when is_list(Config) ->
+ consistency_after_add_replica(disc_only_copies, 3, Config).
+
+consistency_after_add_replica(ReplicaType, NodeConfig, Config) ->
+ Nodes0 = ?acquire_nodes(NodeConfig, Config),
+ AddNode = lists:last(Nodes0),
+ Nodes = Nodes0 -- [AddNode],
+ Node1 = hd(Nodes),
+ {success, [A]} = ?start_activities([Node1]),
+ ?log("consistency_after_add_replica with ~p on ~p~n",
+ [ReplicaType, Nodes0]),
+ TpcbConfig = tpcb_config(ReplicaType, NodeConfig, Nodes, []),
+ mnesia_tpcb:init(TpcbConfig),
+ A ! fun () -> mnesia_tpcb:run(TpcbConfig) end,
+ timer:sleep(timer:seconds(10)),
+ ?match({atomic, ok}, mnesia:add_table_copy(account, AddNode, ReplicaType)),
+ mnesia_tpcb:stop(),
+ ?match(ok, mnesia_tpcb:verify_tabs()),
+ ?verify_mnesia(Nodes0, []).
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+consistency_after_del_replica(suite) ->
+ [
+ consistency_after_del_replica_2_ram,
+ consistency_after_del_replica_2_disc,
+ consistency_after_del_replica_2_disc_only,
+ consistency_after_del_replica_3_ram,
+ consistency_after_del_replica_3_disc,
+ consistency_after_del_replica_3_disc_only
+ ].
+
+consistency_after_del_replica_2_ram(suite) -> [];
+consistency_after_del_replica_2_ram(Config) when is_list(Config) ->
+ consistency_after_del_replica(ram_copies, 2, Config).
+
+consistency_after_del_replica_2_disc(suite) -> [];
+consistency_after_del_replica_2_disc(Config) when is_list(Config) ->
+ consistency_after_del_replica(disc_copies, 2, Config).
+
+consistency_after_del_replica_2_disc_only(suite) -> [];
+consistency_after_del_replica_2_disc_only(Config) when is_list(Config) ->
+ consistency_after_del_replica(disc_only_copies, 2, Config).
+
+consistency_after_del_replica_3_ram(suite) -> [];
+consistency_after_del_replica_3_ram(Config) when is_list(Config) ->
+ consistency_after_del_replica(ram_copies, 3, Config).
+
+consistency_after_del_replica_3_disc(suite) -> [];
+consistency_after_del_replica_3_disc(Config) when is_list(Config) ->
+ consistency_after_del_replica(disc_copies, 3, Config).
+
+consistency_after_del_replica_3_disc_only(suite) -> [];
+consistency_after_del_replica_3_disc_only(Config) when is_list(Config) ->
+ consistency_after_del_replica(disc_only_copies, 3, Config).
+
+consistency_after_del_replica(ReplicaType, NodeConfig, Config) ->
+ Nodes = ?acquire_nodes(NodeConfig, Config),
+ Node1 = hd(Nodes),
+ Node2 = lists:last(Nodes),
+ {success, [A]} = ?start_activities([Node1]),
+ ?log("consistency_after_del_replica with ~p on ~p~n",
+ [ReplicaType, Nodes]),
+ TpcbConfig = tpcb_config(ReplicaType, NodeConfig, Nodes, []),
+ mnesia_tpcb:init(TpcbConfig),
+ A ! fun () -> mnesia_tpcb:run(TpcbConfig) end,
+ timer:sleep(timer:seconds(10)),
+ ?match({atomic, ok}, mnesia:del_table_copy(account, Node2)),
+ mnesia_tpcb:stop(),
+ ?match(ok, mnesia_tpcb:verify_tabs()),
+ ?verify_mnesia(Nodes, []).
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+consistency_after_move_replica(suite) ->
+ [
+ consistency_after_move_replica_2_ram,
+ consistency_after_move_replica_2_disc,
+ consistency_after_move_replica_2_disc_only,
+ consistency_after_move_replica_3_ram,
+ consistency_after_move_replica_3_disc,
+ consistency_after_move_replica_3_disc_only
+ ].
+
+consistency_after_move_replica_2_ram(suite) -> [];
+consistency_after_move_replica_2_ram(Config) when is_list(Config) ->
+ consistency_after_move_replica(ram_copies, 2, Config).
+
+consistency_after_move_replica_2_disc(suite) -> [];
+consistency_after_move_replica_2_disc(Config) when is_list(Config) ->
+ consistency_after_move_replica(disc_copies, 2, Config).
+
+consistency_after_move_replica_2_disc_only(suite) -> [];
+consistency_after_move_replica_2_disc_only(Config) when is_list(Config) ->
+ consistency_after_move_replica(disc_only_copies, 2, Config).
+
+consistency_after_move_replica_3_ram(suite) -> [];
+consistency_after_move_replica_3_ram(Config) when is_list(Config) ->
+ consistency_after_move_replica(ram_copies, 3, Config).
+
+consistency_after_move_replica_3_disc(suite) -> [];
+consistency_after_move_replica_3_disc(Config) when is_list(Config) ->
+ consistency_after_move_replica(disc_copies, 3, Config).
+
+consistency_after_move_replica_3_disc_only(suite) -> [];
+consistency_after_move_replica_3_disc_only(Config) when is_list(Config) ->
+ consistency_after_move_replica(disc_only_copies, 3, Config).
+
+consistency_after_move_replica(ReplicaType, NodeConfig, Config) ->
+ Nodes = ?acquire_nodes(NodeConfig, Config ++ [{tc_timeout, timer:minutes(10)}]),
+ Node1 = hd(Nodes),
+ Node2 = lists:last(Nodes),
+ {success, [A]} = ?start_activities([Node1]),
+ ?log("consistency_after_move_replica with ~p on ~p~n",
+ [ReplicaType, Nodes]),
+ TpcbConfig = tpcb_config(ReplicaType, NodeConfig, Nodes -- [Node2], []),
+ mnesia_tpcb:init(TpcbConfig),
+ A ! fun () -> mnesia_tpcb:run(TpcbConfig) end,
+ timer:sleep(timer:seconds(10)),
+ ?match({atomic, ok}, mnesia:move_table_copy(account, Node1, Node2)),
+ ?log("First move completed from node ~p to ~p ~n", [Node1, Node2]),
+ ?match({atomic, ok}, mnesia:move_table_copy(account, Node2, Node1)),
+ mnesia_tpcb:stop(),
+ ?match(ok, mnesia_tpcb:verify_tabs()),
+ ?verify_mnesia(Nodes, []).
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+consistency_after_transform_table(doc) ->
+ ["Check that the database is consistent after transform_table.",
+ " While applications are updating the involved tables. "];
+
+consistency_after_transform_table(suite) ->
+ [
+ consistency_after_transform_table_ram,
+ consistency_after_transform_table_disc,
+ consistency_after_transform_table_disc_only
+ ].
+
+
+consistency_after_transform_table_ram(suite) -> [];
+consistency_after_transform_table_ram(Config) when is_list(Config) ->
+ consistency_after_transform_table(ram_copies, Config).
+
+consistency_after_transform_table_disc(suite) -> [];
+consistency_after_transform_table_disc(Config) when is_list(Config) ->
+ consistency_after_transform_table(disc_copies, Config).
+
+consistency_after_transform_table_disc_only(suite) -> [];
+consistency_after_transform_table_disc_only(Config) when is_list(Config) ->
+ consistency_after_transform_table(disc_only_copies, Config).
+
+consistency_after_transform_table(Type, Config) ->
+ Nodes = [N1, N2,_N3] = ?acquire_nodes(3, Config),
+
+ ?match({atomic, ok}, mnesia:create_table(tab1, [{index, [3]}, {Type, [N1]}])),
+ ?match({atomic, ok}, mnesia:create_table(tab2, [{index, [3]}, {Type, [N1,N2]}])),
+ ?match({atomic, ok}, mnesia:create_table(tab3, [{index, [3]}, {Type, Nodes}])),
+ ?match({atomic, ok}, mnesia:create_table(empty, [{index, [3]},{Type, Nodes}])),
+
+ Tabs = lists:sort([tab1, tab2, tab3, empty]),
+
+ [[mnesia:dirty_write({Tab, N, N}) || N <- lists:seq(1,10)] ||
+ Tab <- Tabs -- [empty, tab4]],
+ mnesia:dump_log(),
+
+ Ok = lists:duplicate(4, {atomic, ok}),
+ ?match(Ok, [mnesia:transform_table(Tab, fun({T, N, N}) -> {T, N, N, ok} end,
+ [k,a,n]) || Tab <- Tabs]),
+ [?match([k,a,n], mnesia:table_info(Tab, attributes)) || Tab <- Tabs],
+
+ Filter = fun(Tab) -> mnesia:foldl(fun(A, Acc) when size(A) == 3 -> [A|Acc];
+ (A, Acc) when size(A) == 4 -> Acc
+ end, [], Tab)
+ end,
+
+ ?match([[],[],[],[]], [element(2,mnesia:transaction(Filter, [Tab])) || Tab <- Tabs]),
+
+ mnesia_test_lib:kill_mnesia(Nodes),
+ mnesia_test_lib:start_mnesia(Nodes, Tabs),
+
+ ?match([Tabs, Tabs, Tabs],
+ [lists:sort(rpc:call(Node, mnesia,system_info, [tables]) -- [schema]) || Node <- Nodes]),
+
+ ?match([[],[],[],[]], [element(2,mnesia:transaction(Filter, [Tab])) || Tab <- Tabs]),
+ [?match([k,a,n], mnesia:table_info(Tab, attributes)) || Tab <- Tabs],
+
+ ?verify_mnesia(Nodes, []).
+
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+consistency_after_change_table_copy_type(doc) ->
+ ["Check that the database is consistent after change of copy type.",
+ " While applications are updating the involved tables. "].
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+consistency_after_fallback(doc) ->
+ ["Check that installed fallbacks are consistent. Check this by starting ",
+ "some nodes, run tpcb on them, take a backup at any time, install it ",
+ "as a fallback, kill all nodes, start mnesia again and check for ",
+ "any inconsistencies"];
+consistency_after_fallback(suite) ->
+ [
+ consistency_after_fallback_2_ram,
+ consistency_after_fallback_2_disc,
+ consistency_after_fallback_2_disc_only,
+ consistency_after_fallback_3_ram,
+ consistency_after_fallback_3_disc
+ , consistency_after_fallback_3_disc_only
+ ].
+
+consistency_after_fallback_2_ram(suite) -> [];
+consistency_after_fallback_2_ram(Config) when is_list(Config) ->
+ consistency_after_fallback(ram_copies, 2, Config).
+
+consistency_after_fallback_2_disc(suite) -> [];
+consistency_after_fallback_2_disc(Config) when is_list(Config) ->
+ consistency_after_fallback(disc_copies, 2, Config).
+
+consistency_after_fallback_2_disc_only(suite) -> [];
+consistency_after_fallback_2_disc_only(Config) when is_list(Config) ->
+ consistency_after_fallback(disc_only_copies, 2, Config).
+
+consistency_after_fallback_3_ram(suite) -> [];
+consistency_after_fallback_3_ram(Config) when is_list(Config) ->
+ consistency_after_fallback(ram_copies, 3, Config).
+
+consistency_after_fallback_3_disc(suite) -> [];
+consistency_after_fallback_3_disc(Config) when is_list(Config) ->
+ consistency_after_fallback(disc_copies, 3, Config).
+
+consistency_after_fallback_3_disc_only(suite) -> [];
+consistency_after_fallback_3_disc_only(Config) when is_list(Config) ->
+ consistency_after_fallback(disc_only_copies, 3, Config).
+
+consistency_after_fallback(ReplicaType, NodeConfig, Config) ->
+ %%?verbose("Starting consistency_after_fallback2 at ~p~n", [self()]),
+ Delay = 5,
+ Nodes = ?acquire_nodes(NodeConfig, [{tc_timeout, timer:minutes(10)} | Config]),
+ Node1 = hd(Nodes),
+ %%?verbose("Mnesia info: ~p~n", [mnesia:info()]),
+
+ {success, [A]} = ?start_activities([Node1]),
+ ?log("consistency_after_fallback with ~p on ~p~n",
+ [ReplicaType, Nodes]),
+ TpcbConfig = tpcb_config(ReplicaType, NodeConfig, Nodes, []),
+ mnesia_tpcb:init(TpcbConfig),
+ A ! fun () -> mnesia_tpcb:run(TpcbConfig) end,
+ timer:sleep(timer:seconds(Delay)),
+
+ %% Make a backup
+ ?verbose("Doing backup~n", []),
+ ?match(ok, mnesia:backup(consistency_after_fallback2)),
+
+ %% Install the backup as a fallback
+ ?verbose("Doing fallback~n", []),
+ ?match(ok, mnesia:install_fallback(consistency_after_fallback2)),
+ timer:sleep(timer:seconds(Delay)),
+
+ %% Stop tpcb
+ ?verbose("Stopping TPC-B~n", []),
+ mnesia_tpcb:stop(),
+ ?match(ok, mnesia_tpcb:verify_tabs()),
+
+ %% Stop and then start mnesia and check table consistency
+ %%?verbose("Restarting Mnesia~n", []),
+ mnesia_test_lib:kill_mnesia(Nodes),
+ mnesia_test_lib:start_mnesia(Nodes,[account,branch,teller,history]),
+
+ ?match(ok, mnesia_tpcb:verify_tabs()),
+ if
+ ReplicaType == ram_copies ->
+ %% Test that change_table_copy work i.e. no account.dcd file exists.
+ ?match({atomic, ok}, mnesia:change_table_copy_type(account, node(), disc_copies));
+ true ->
+ ignore
+ end,
+ file:delete(consistency_after_fallback2),
+ ?verify_mnesia(Nodes, []).
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+consistency_after_restore(doc) ->
+ ["Verify consistency after restore operations."];
+
+consistency_after_restore(suite) ->
+ [
+ consistency_after_restore_clear_ram,
+ consistency_after_restore_clear_disc,
+ consistency_after_restore_clear_disc_only,
+ consistency_after_restore_recreate_ram,
+ consistency_after_restore_recreate_disc,
+ consistency_after_restore_recreate_disc_only
+ ].
+
+consistency_after_restore_clear_ram(suite) -> [];
+consistency_after_restore_clear_ram(Config) when is_list(Config) ->
+ consistency_after_restore(ram_copies, clear_tables, Config).
+
+consistency_after_restore_clear_disc(suite) -> [];
+consistency_after_restore_clear_disc(Config) when is_list(Config) ->
+ consistency_after_restore(disc_copies, clear_tables, Config).
+
+consistency_after_restore_clear_disc_only(suite) -> [];
+consistency_after_restore_clear_disc_only(Config) when is_list(Config) ->
+ consistency_after_restore(disc_only_copies, clear_tables, Config).
+
+consistency_after_restore_recreate_ram(suite) -> [];
+consistency_after_restore_recreate_ram(Config) when is_list(Config) ->
+ consistency_after_restore(ram_copies, recreate_tables, Config).
+
+consistency_after_restore_recreate_disc(suite) -> [];
+consistency_after_restore_recreate_disc(Config) when is_list(Config) ->
+ consistency_after_restore(disc_copies, recreate_tables, Config).
+
+consistency_after_restore_recreate_disc_only(suite) -> [];
+consistency_after_restore_recreate_disc_only(Config) when is_list(Config) ->
+ consistency_after_restore(disc_only_copies, recreate_tables, Config).
+
+consistency_after_restore(ReplicaType, Op, Config) ->
+ Delay = 1,
+ Nodes = ?acquire_nodes(3, [{tc_timeout, timer:minutes(10)} | Config]),
+ [Node1, Node2, _Node3] = Nodes,
+ File = "cons_backup_restore",
+
+ ?log("consistency_after_restore with ~p on ~p~n",
+ [ReplicaType, Nodes]),
+ Tabs = [carA, carB, carC, carD],
+
+ ?match({atomic, ok}, mnesia:create_table(carA, [{ReplicaType, Nodes}])),
+ ?match({atomic, ok}, mnesia:create_table(carB, [{ReplicaType, Nodes -- [Node1]}])),
+ ?match({atomic, ok}, mnesia:create_table(carC, [{ReplicaType, Nodes -- [Node2]}])),
+ ?match({atomic, ok}, mnesia:create_table(carD, [{ReplicaType, [Node2]}])),
+
+ NList = lists:seq(0, 20),
+ [lists:foreach(fun(E) -> ok = mnesia:dirty_write({Tab, E, 1}) end, NList) ||
+ Tab <- Tabs],
+
+ {ok, Name, _} = mnesia:activate_checkpoint([{max, [schema | Tabs]},
+ {ram_overrides_dump, true}]),
+ ?verbose("Doing backup~n", []),
+ ?match(ok, mnesia:backup_checkpoint(Name, File)),
+ ?match(ok, mnesia:deactivate_checkpoint(Name)),
+
+ [lists:foreach(fun(E) -> ok = mnesia:dirty_write({Tab, E, 2}) end, NList) ||
+ Tab <- Tabs],
+
+ Pids1 = [{'EXIT', spawn_link(?MODULE, change_tab, [self(), carA, Op]), ok} || _ <- lists:seq(1, 5)],
+ Pids2 = [{'EXIT', spawn_link(?MODULE, change_tab, [self(), carB, Op]), ok} || _ <- lists:seq(1, 5)],
+ Pids3 = [{'EXIT', spawn_link(?MODULE, change_tab, [self(), carC, Op]), ok} || _ <- lists:seq(1, 5)],
+ Pids4 = [{'EXIT', spawn_link(?MODULE, change_tab, [self(), carD, Op]), ok} || _ <- lists:seq(1, 5)],
+
+ AllPids = Pids1 ++ Pids2 ++ Pids3 ++ Pids4,
+
+ Restore = fun(F, Args) ->
+ case mnesia:restore(F, Args) of
+ {atomic, List} -> lists:sort(List);
+ Else -> Else
+ end
+ end,
+
+ timer:sleep(timer:seconds(Delay)), %% Let changers grab locks
+ ?verbose("Doing restore~n", []),
+ ?match(Tabs, Restore(File, [{default_op, Op}])),
+
+ timer:sleep(timer:seconds(Delay)), %% Let em die
+
+ ?match_multi_receive(AllPids),
+
+ case ?match(ok, restore_verify_tabs(Tabs)) of
+ {success, ok} ->
+ file:delete(File);
+ _ ->
+ {T, M, S} = time(),
+ File2 = ?flat_format("consistency_error~w~w~w.BUP", [T, M, S]),
+ file:rename(File, File2)
+ end,
+ ?verify_mnesia(Nodes, []).
+
+change_tab(Father, Tab, Test) ->
+ Key = random:uniform(20),
+ Update = fun() ->
+ case mnesia:read({Tab, Key}) of
+ [{Tab, Key, 1}] ->
+ quit;
+ [{Tab, Key, _N}] ->
+ mnesia:write({Tab, Key, 3})
+ end
+ end,
+ case mnesia:transaction(Update) of
+ {atomic, quit} ->
+ exit(ok);
+ {aborted, {no_exists, Tab}} when Test == recreate_tables ->%% I'll allow this
+ change_tab(Father, Tab, Test);
+ {atomic, ok} ->
+ change_tab(Father, Tab, Test)
+ end.
+
+restore_verify_tabs([Tab | R]) ->
+ ?match({atomic, ok},
+ mnesia:transaction(fun() -> mnesia:foldl(fun({_, _, 1}, ok) ->
+ ok;
+ (Else, Acc) ->
+ [Else|Acc]
+ end, ok, Tab)
+ end)),
+ restore_verify_tabs(R);
+restore_verify_tabs([]) ->
+ ok.
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+consistency_after_rename_of_node(doc) ->
+ ["Skipped because it is an unimportant case."].
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+checkpoint_retainer_consistency(doc) ->
+ ["Verify that the contents of a checkpoint retainer has the expected",
+ "contents in various situations."];
+checkpoint_retainer_consistency(suite) ->
+ [
+ updates_during_checkpoint_activation,
+ updates_during_checkpoint_iteration,
+ load_table_with_activated_checkpoint,
+ add_table_copy_to_table_with_activated_checkpoint
+ ].
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+updates_during_checkpoint_activation(doc) ->
+ ["Perform updates while the checkpoint getting activated",
+ "and verify that all checkpoint retainers associated with",
+ "different replicas of the same table really has the same",
+ "contents."];
+updates_during_checkpoint_activation(suite) ->
+ [
+ updates_during_checkpoint_activation_2_ram,
+ updates_during_checkpoint_activation_2_disc,
+ updates_during_checkpoint_activation_2_disc_only,
+ updates_during_checkpoint_activation_3_ram,
+ updates_during_checkpoint_activation_3_disc
+ , updates_during_checkpoint_activation_3_disc_only
+ ].
+
+updates_during_checkpoint_activation_2_ram(suite) -> [];
+updates_during_checkpoint_activation_2_ram(Config) when is_list(Config) ->
+ updates_during_checkpoint_activation(ram_copies, 2, Config).
+
+updates_during_checkpoint_activation_2_disc(suite) -> [];
+updates_during_checkpoint_activation_2_disc(Config) when is_list(Config) ->
+ updates_during_checkpoint_activation(disc_copies, 2, Config).
+
+updates_during_checkpoint_activation_2_disc_only(suite) -> [];
+updates_during_checkpoint_activation_2_disc_only(Config) when is_list(Config) ->
+ updates_during_checkpoint_activation(disc_only_copies, 2, Config).
+
+updates_during_checkpoint_activation_3_ram(suite) -> [];
+updates_during_checkpoint_activation_3_ram(Config) when is_list(Config) ->
+ updates_during_checkpoint_activation(ram_copies, 3, Config).
+
+updates_during_checkpoint_activation_3_disc(suite) -> [];
+updates_during_checkpoint_activation_3_disc(Config) when is_list(Config) ->
+ updates_during_checkpoint_activation(disc_copies, 3, Config).
+
+updates_during_checkpoint_activation_3_disc_only(suite) -> [];
+updates_during_checkpoint_activation_3_disc_only(Config) when is_list(Config) ->
+ updates_during_checkpoint_activation(disc_only_copies, 3, Config).
+
+updates_during_checkpoint_activation(ReplicaType,NodeConfig,Config) ->
+ %%?verbose("updates_during_checkpoint_activation2 at ~p~n", [self()]),
+ Delay = 5,
+ Nodes = ?acquire_nodes(NodeConfig, Config),
+ Node1 = hd(Nodes),
+ %%?verbose("Mnesia info: ~p~n", [mnesia:info()]),
+
+ {success, [A]} = ?start_activities([Node1]),
+ ?log("consistency_after_fallback with ~p on ~p~n",
+ [ReplicaType, Nodes]),
+ TpcbConfig = tpcb_config_dist(ReplicaType, NodeConfig, Nodes, Config),
+ %%TpcbConfig = tpcb_config(ReplicaType, NodeConfig, Nodes),
+ mnesia_tpcb:init(TpcbConfig),
+ A ! fun () -> mnesia_tpcb:run(TpcbConfig) end,
+ timer:sleep(timer:seconds(Delay)),
+
+ {ok, CPName, _NodeList} =
+ mnesia:activate_checkpoint([{max, mnesia:system_info(tables)}]),
+ timer:sleep(timer:seconds(Delay)),
+
+ %% Stop tpcb
+ ?verbose("Stopping TPC-B~n", []),
+ mnesia_tpcb:stop(),
+ ?match(ok, mnesia_tpcb:verify_tabs()),
+
+ ?match(ok, mnesia:backup_checkpoint(CPName,
+ updates_during_checkpoint_activation2)),
+ timer:sleep(timer:seconds(Delay)),
+
+ ?match(ok, mnesia:install_fallback(updates_during_checkpoint_activation2)),
+
+ %% Stop and then start mnesia and check table consistency
+ %%?verbose("Restarting Mnesia~n", []),
+ mnesia_test_lib:kill_mnesia(Nodes),
+ file:delete(updates_during_checkpoint_activation2),
+ mnesia_test_lib:start_mnesia(Nodes,[account,branch,teller, history]),
+
+ ?match(ok, mnesia_tpcb:verify_tabs()),
+ ?verify_mnesia(Nodes, []).
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+updates_during_checkpoint_iteration(doc) ->
+ ["Perform updates while someone is iterating over a checkpoint",
+ "and verify that the iterator really finds the expected data",
+ "regardless of ongoing upates."];
+
+updates_during_checkpoint_iteration(suite) ->
+ [
+ updates_during_checkpoint_iteration_2_ram,
+ updates_during_checkpoint_iteration_2_disc
+ , updates_during_checkpoint_iteration_2_disc_only
+ ].
+
+updates_during_checkpoint_iteration_2_ram(suite) -> [];
+updates_during_checkpoint_iteration_2_ram(Config) when is_list(Config) ->
+ updates_during_checkpoint_iteration(ram_copies, 2, Config).
+
+updates_during_checkpoint_iteration_2_disc(suite) -> [];
+updates_during_checkpoint_iteration_2_disc(Config) when is_list(Config) ->
+ updates_during_checkpoint_iteration(disc_copies, 2, Config).
+
+updates_during_checkpoint_iteration_2_disc_only(suite) -> [];
+updates_during_checkpoint_iteration_2_disc_only(Config) when is_list(Config) ->
+ updates_during_checkpoint_iteration(disc_only_copies, 2, Config).
+
+updates_during_checkpoint_iteration(ReplicaType,NodeConfig,Config) ->
+ %?verbose("updates_during_checkpoint_iteration2 at ~p~n", [self()]),
+ Delay = 5,
+ Nodes = ?acquire_nodes(NodeConfig, Config),
+ Node1 = hd(Nodes),
+ %?verbose("Mnesia info: ~p~n", [mnesia:info()]),
+ File = updates_during_checkpoint_iteration2,
+ {success, [A]} = ?start_activities([Node1]),
+ ?log("updates_during_checkpoint_iteration with ~p on ~p~n",
+ [ReplicaType, Nodes]),
+ TpcbConfig = tpcb_config_dist(ReplicaType, NodeConfig, Nodes, Config),
+ %%TpcbConfig = tpcb_config(ReplicaType, NodeConfig, Nodes),
+ TpcbConfigRec = list2rec(TpcbConfig,
+ record_info(fields,tab_config),
+ #tab_config{}),
+ mnesia_tpcb:init(TpcbConfig),
+ ?match(ok, mnesia_tpcb:verify_tabs()),
+
+ {ok, CPName, _NodeList} =
+ mnesia:activate_checkpoint([{max, mnesia:system_info(tables)},
+ {ram_overrides_dump,true}]),
+ A ! fun () -> mnesia:backup_checkpoint(CPName, File) end,
+
+ do_changes_during_backup(TpcbConfigRec),
+
+ ?match_receive({A,ok}),
+
+ timer:sleep(timer:seconds(Delay)),
+ ?match(ok, mnesia:install_fallback(File)),
+ timer:sleep(timer:seconds(Delay)),
+
+ ?match({error,{"Bad balance",_,_}}, mnesia_tpcb:verify_tabs()),
+
+ mnesia_test_lib:kill_mnesia(Nodes),
+ mnesia_test_lib:start_mnesia(Nodes,[account,branch,teller, history]),
+
+ ?match(ok, mnesia_tpcb:verify_tabs()),
+
+ ?match(ok, file:delete(File)),
+ ?verify_mnesia(Nodes, []).
+
+do_changes_during_backup(TpcbConfig) ->
+ loop_branches(TpcbConfig#tab_config.n_branches,
+ TpcbConfig#tab_config.n_accounts_per_branch).
+
+loop_branches(N_br,N_acc) when N_br >= 1 ->
+ loop_accounts(N_br,N_acc),
+ loop_branches(N_br-1,N_acc);
+loop_branches(_,_) -> done.
+
+loop_accounts(N_br, N_acc) when N_acc >= 1 ->
+ A = #account{id=N_acc, branch_id=N_br, balance = 4711},
+ ok = mnesia:dirty_write(A),
+ loop_accounts(N_br, N_acc-1);
+
+loop_accounts(_,_) -> done.
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+load_table_with_activated_checkpoint(doc) ->
+ ["Load a table with a checkpoint attached to it and verify that the",
+ "newly loaded replica also gets a checkpoint retainer attached to it",
+ "and that it is consistent with the original retainer."];
+
+load_table_with_activated_checkpoint(suite) ->
+ [
+ load_table_with_activated_checkpoint_ram,
+ load_table_with_activated_checkpoint_disc,
+ load_table_with_activated_checkpoint_disc_only
+ ].
+
+load_table_with_activated_checkpoint_ram(suite) -> [];
+load_table_with_activated_checkpoint_ram(Config) when is_list(Config) ->
+ load_table_with_activated_checkpoint(ram_copies, Config).
+
+load_table_with_activated_checkpoint_disc(suite) -> [];
+load_table_with_activated_checkpoint_disc(Config) when is_list(Config) ->
+ load_table_with_activated_checkpoint(disc_copies, Config).
+
+load_table_with_activated_checkpoint_disc_only(suite) -> [];
+load_table_with_activated_checkpoint_disc_only(Config) when is_list(Config) ->
+ load_table_with_activated_checkpoint(disc_only_copies, Config).
+
+load_table_with_activated_checkpoint(Type, Config) ->
+ Nodes = ?acquire_nodes(2, Config),
+ Node1 = hd(Nodes),
+ Tab = load_test,
+ Def = [{attributes, [key, value]},
+ {Type, Nodes}], %% ??? important that RAM ???
+
+ ?match({atomic, ok}, mnesia:create_table(Tab, Def)),
+ ?match(ok, mnesia:dirty_write({Tab, 1, 4711})),
+ ?match(ok, mnesia:dirty_write({Tab, 2, 42})),
+ ?match(ok, mnesia:dirty_write({Tab, 3, 256})),
+
+ timer:sleep(timer:seconds(1)),
+
+ {ok, CPName, _NodeList} =
+ mnesia:activate_checkpoint([{max, mnesia:system_info(tables)},
+ {ram_overrides_dump,true}]),
+
+ mnesia_test_lib:stop_mnesia([Node1]),
+ mnesia_test_lib:start_mnesia([Node1],[Tab]),
+ %%--- check, whether the checkpiont is attached to both replicas
+ {success, [A,B]} = ?start_activities(Nodes),
+
+ A ! fun () ->
+ mnesia:table_info(Tab,checkpoints)
+ end,
+ ?match_receive({A,[CPName]}),
+
+ B ! fun () ->
+ mnesia:table_info(Tab,checkpoints)
+ end,
+ ?match_receive({B,[CPName]}),
+
+ %%--- check, whether both retainers are consistent
+ ?match(ok, mnesia:dirty_write({Tab, 1, 815})),
+ A ! fun () ->
+ mnesia:backup_checkpoint(CPName, load_table_a)
+ end,
+ ?match_receive({A,ok}),
+ B ! fun () ->
+ mnesia:backup_checkpoint(CPName, load_table_b)
+ end,
+ ?match_receive({B,ok}),
+
+ Mod = mnesia_backup, %% Assume local files
+ List_a = view(load_table_a, Mod),
+ List_b = view(load_table_b, Mod),
+
+ ?match(List_a, List_b),
+
+ ?match(ok,file:delete(load_table_a)),
+ ?match(ok,file:delete(load_table_b)),
+ ?verify_mnesia(Nodes, []).
+
+view(Source, Mod) ->
+ View = fun(Item, Acc) ->
+ ?verbose("tab - item : ~p ~n",[Item]),
+ case Item of
+ {schema, Tab, Cs} -> %% Remove cookie information
+ NewCs = lists:keyreplace(cookie, 1, Cs,
+ {cookie, skip_cookie}),
+ Item2 = {schema, Tab, NewCs},
+ {[Item], [Item2|Acc]};
+ _ ->
+ {[Item], [Item|Acc]}
+ end
+ end,
+ {ok,TabList} =
+ mnesia:traverse_backup(Source, Mod, dummy, read_only, View, []),
+ lists:sort(TabList).
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+add_table_copy_to_table_with_activated_checkpoint(doc) ->
+ ["Add a replica to a table with a checkpoint attached to it",
+ "and verify that the new replica also gets a checkpoint",
+ "retainer attached to it and that it is consistent with the",
+ "original retainer."];
+
+add_table_copy_to_table_with_activated_checkpoint(suite) ->
+ [
+ add_table_copy_to_table_with_activated_checkpoint_ram,
+ add_table_copy_to_table_with_activated_checkpoint_disc,
+ add_table_copy_to_table_with_activated_checkpoint_disc_only
+ ].
+
+add_table_copy_to_table_with_activated_checkpoint_ram(suite) -> [];
+add_table_copy_to_table_with_activated_checkpoint_ram(Config) when is_list(Config) ->
+ add_table_copy_to_table_with_activated_checkpoint(ram_copies, Config).
+
+add_table_copy_to_table_with_activated_checkpoint_disc(suite) -> [];
+add_table_copy_to_table_with_activated_checkpoint_disc(Config) when is_list(Config) ->
+ add_table_copy_to_table_with_activated_checkpoint(disc_copies, Config).
+
+add_table_copy_to_table_with_activated_checkpoint_disc_only(suite) -> [];
+add_table_copy_to_table_with_activated_checkpoint_disc_only(Config) when is_list(Config) ->
+ add_table_copy_to_table_with_activated_checkpoint(disc_only_copies, Config).
+
+add_table_copy_to_table_with_activated_checkpoint(Type,Config) ->
+ Nodes = ?acquire_nodes(2, Config),
+ %?verbose("NODES = ~p ~n",[Nodes]),
+ [Node1,Node2] = Nodes,
+
+ Tab = add_test,
+ Def = [{attributes, [key, value]},
+ {Type, [Node1]}], %% ??? important that RAM ???
+
+ ?match({atomic, ok}, mnesia:create_table(Tab, Def)),
+ ?match(ok, mnesia:dirty_write({Tab, 1, 4711})),
+ ?match(ok, mnesia:dirty_write({Tab, 2, 42})),
+ ?match(ok, mnesia:dirty_write({Tab, 3, 256})),
+
+ {ok, CPName, _NodeList} =
+ mnesia:activate_checkpoint([{max, mnesia:system_info(tables)},
+ {ram_overrides_dump,true}]),
+
+ ?match({atomic,ok},mnesia:add_table_copy(Tab,Node2,ram_copies)),
+
+ %%--- check, whether the checkpiont is attached to both replicas
+ {success, [A,B]} = ?start_activities(Nodes),
+
+ A ! fun () ->
+ mnesia:table_info(Tab,checkpoints)
+ end,
+ ?match_receive({A,[CPName]}),
+
+ B ! fun () ->
+ mnesia:table_info(Tab,checkpoints)
+ end,
+ ?match_receive({B,[CPName]}),
+
+ %%--- check, whether both retainers are consistent
+
+ ?match(ok, mnesia:dirty_write({Tab, 1, 815})),
+ ?match(ok, mnesia:dirty_write({Tab, 2, 815})),
+
+ A ! fun () ->
+ mnesia:backup_checkpoint(CPName, add_table_a)
+ end,
+ ?match_receive({A,ok}),
+ B ! fun () ->
+ mnesia:backup_checkpoint(CPName, add_table_b)
+ end,
+ ?match_receive({B,ok}),
+
+ Mod = mnesia_backup, %% Assume local files
+
+ List_a = view(add_table_a, Mod),
+ List_b = view(add_table_b, Mod),
+
+ ?match(List_a, List_b),
+
+ ?match(ok,file:delete(add_table_a)),
+ ?match(ok, file:delete(add_table_b)),
+ ?verify_mnesia(Nodes, []).
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+backup_consistency(suite) ->
+ [
+ interupted_install_fallback,
+ interupted_uninstall_fallback,
+ mnesia_down_during_backup_causes_switch,
+ mnesia_down_during_backup_causes_abort,
+ schema_transactions_during_backup
+ ].
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+interupted_install_fallback(doc) ->
+ ["Verify that a interrupted install_fallback really",
+ "is performed on all nodes or none"];
+
+interupted_install_fallback(suite) ->
+ [
+ inst_fallback_process_dies,
+ fatal_when_inconsistency
+ ].
+
+inst_fallback_process_dies(suite) ->
+ [];
+inst_fallback_process_dies(Config) when is_list(Config) ->
+ ?is_debug_compiled,
+
+ Nodes = ?acquire_nodes(3, Config ++ [{tc_timeout, timer:minutes(2)}]),
+ {success, [A,_B,_C]} = ?start_activities(Nodes),
+
+ TestPid = self(),
+ DebugId = {mnesia_bup, fallback_receiver_loop, pre_swap},
+ DebugFun =
+ fun(PrevContext, _EvalContext) ->
+ ?verbose("fallback_receiver_loop - pre_swap pid ~p #~p~n",
+ [self(),PrevContext]),
+ TestPid ! {self(),fallback_preswap},
+ case receive_messages([fallback_continue]) of
+ [{TestPid,fallback_continue}] ->
+ ?deactivate_debug_fun(DebugId),
+ PrevContext+1
+ end
+ end,
+ ?activate_debug_fun(DebugId, DebugFun, 1),
+
+ Tab = install_table,
+ Def = [{attributes, [key, value]}, {disc_copies, Nodes}],
+
+ ?match({atomic, ok}, mnesia:create_table(Tab, Def)),
+
+ ?match(ok, mnesia:dirty_write({Tab, 1, 4711})),
+ ?match(ok, mnesia:dirty_write({Tab, 2, 42})),
+ ?match(ok, mnesia:dirty_write({Tab, 3, 256})),
+
+ {ok, CPName, _NodeList} =
+ mnesia:activate_checkpoint([{max, mnesia:system_info(tables)},
+ {ram_overrides_dump,true}]),
+
+ ?match(ok, mnesia:backup_checkpoint(CPName, install_backup)),
+
+ A ! fun() -> mnesia:install_fallback(install_backup) end,
+ [{AnsPid,fallback_preswap}] = receive_messages([fallback_preswap]),
+ exit(A, kill),
+ AnsPid ! {self(), fallback_continue},
+ ?match_receive({'EXIT', A, killed}),
+ timer:sleep(2000), %% Wait till fallback is installed everywhere
+
+ mnesia_test_lib:kill_mnesia(Nodes),
+ ?verbose("~n---->Mnesia is stopped everywhere<-----~n", []),
+ ?match([], mnesia_test_lib:start_mnesia(Nodes,[Tab])),
+
+ check_data(Nodes, Tab),
+ ?match(ok, file:delete(install_backup)),
+ ?verify_mnesia(Nodes, []).
+
+check_data([N1 | R], Tab) ->
+ ?match([{Tab, 1, 4711}], rpc:call(N1, mnesia, dirty_read, [{Tab, 1}])),
+ ?match([{Tab, 2, 42}], rpc:call(N1, mnesia, dirty_read, [{Tab, 2}])),
+ ?match([{Tab, 3, 256}], rpc:call(N1, mnesia, dirty_read, [{Tab, 3}])),
+ check_data(R, Tab);
+check_data([], _Tab) ->
+ ok.
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+fatal_when_inconsistency(suite) ->
+ [];
+fatal_when_inconsistency(Config) when is_list(Config) ->
+ ?is_debug_compiled,
+
+ [Node1, Node2, Node3] = Nodes =
+ ?acquire_nodes(3, Config ++ [{tc_timeout, timer:minutes(2)}]),
+ {success, [A,_B,_C]} = ?start_activities(Nodes),
+
+ TestPid = self(),
+ DebugId = {mnesia_bup, fallback_receiver_loop, pre_swap},
+ DebugFun =
+ fun(PrevContext, _EvalContext) ->
+ ?verbose("fallback_receiver_loop - pre_swap pid ~p #~p~n",
+ [self(),PrevContext]),
+ TestPid ! {self(),fallback_preswap},
+ case receive_messages([fallback_continue]) of
+ [{TestPid,fallback_continue}] ->
+ ?deactivate_debug_fun(DebugId),
+ PrevContext+1
+ end
+ end,
+ ?activate_debug_fun(DebugId, DebugFun, 1),
+
+ Tab = install_table,
+ Def = [{attributes, [key, value]}, {disc_copies, Nodes}],
+
+ ?match({atomic, ok}, mnesia:create_table(Tab, Def)),
+
+ ?match(ok, mnesia:dirty_write({Tab, 1, 4711})),
+ ?match(ok, mnesia:dirty_write({Tab, 2, 42})),
+ ?match(ok, mnesia:dirty_write({Tab, 3, 256})),
+
+ {ok, CPName, _NodeList} =
+ mnesia:activate_checkpoint([{max, mnesia:system_info(tables)},
+ {ram_overrides_dump,true}]),
+
+ ?match(ok, mnesia:backup_checkpoint(CPName, install_backup)),
+ ?match(ok, mnesia:dirty_write({Tab, 2, 42424242})),
+
+ A ! fun() ->
+ mnesia:install_fallback(install_backup)
+ end,
+
+ [{AnsPid,fallback_preswap}] = receive_messages([fallback_preswap]),
+ exit(AnsPid, kill), %% Kill install-fallback on local node will
+ AnsPid ! {self(), fallback_continue},
+ ?deactivate_debug_fun(DebugId),
+
+ ?match_receive({A,{error,{"Cannot install fallback",
+ {'EXIT',AnsPid,killed}}}}),
+ mnesia_test_lib:kill_mnesia(Nodes),
+ ?verbose("EXPECTING FATAL from 2 nodes WITH CORE DUMP~n", []),
+
+ ?match([], mnesia_test_lib:start_mnesia([Node1],[])),
+ is_running(Node1, yes),
+ ?match([{Node2, mnesia, _}], mnesia_test_lib:start_mnesia([Node2],[])),
+ is_running(Node2, no),
+ ?match([{Node3, mnesia, _}], mnesia_test_lib:start_mnesia([Node3],[])),
+ is_running(Node3, no),
+ mnesia_test_lib:kill_mnesia(Nodes),
+
+ ?match(ok, mnesia:install_fallback(install_backup)),
+ mnesia_test_lib:start_mnesia(Nodes,[Tab]),
+
+ check_data(Nodes, Tab),
+
+ ?match(ok,file:delete(install_backup)),
+ ?verify_mnesia(Nodes, []).
+
+is_running(Node, Shouldbe) ->
+ timer:sleep(1000),
+ Running = rpc:call(Node, mnesia, system_info, [is_running]),
+ case Running of
+ Shouldbe -> ok;
+ _ -> is_running(Node, Shouldbe)
+ end.
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+interupted_uninstall_fallback(doc) ->
+ ["Verify that a interrupted uninstall_fallback really",
+ "is performed on all nodes or none"];
+interupted_uninstall_fallback(suite) ->
+ [
+ after_delete
+ ].
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+after_delete(doc) ->
+ ["interrupt the uninstall after deletion of ",
+ "fallback files - there shall be no fallback"];
+after_delete(suite) -> [];
+after_delete(Config) when is_list(Config) ->
+ do_uninstall(Config, post_delete).
+
+%%%%%%%%%%%%%%%%%%%%%%%%%
+
+do_uninstall(Config,DebugPoint) ->
+ ?is_debug_compiled,
+
+ Nodes = ?acquire_nodes(3, Config),
+ %%?verbose("NODES = ~p ~n",[Nodes]),
+
+ {success, [P1,P2,P3]} = ?start_activities(Nodes),
+
+ NP1 = node(P1),
+ NP2 = node(P2),
+
+ {A,B,C} = case node() of
+ NP1 ->
+ %%?verbose("first case ~n"),
+ {P3,P2,P1};
+ NP2 ->
+ %%?verbose("second case ~n"),
+ {P3, P1, P2};
+ _ ->
+ { P1, P2, P3}
+ end,
+
+ Node1 = node(A),
+ Node2 = node(B),
+ Node3 = node(C),
+
+ ?verbose(" A pid:~p node:~p ~n",[A,Node1]),
+ ?verbose(" B pid:~p node:~p ~n",[B,Node2]),
+ ?verbose(" C pid:~p node:~p ~n",[C,Node3]),
+
+
+ TestPid = self(),
+ %%?verbose("TestPid : ~p~n",[TestPid]),
+ DebugId = {mnesia_bup, uninstall_fallback2, DebugPoint},
+ DebugFun = fun(PrevContext, _EvalContext) ->
+ ?verbose("uninstall_fallback pid ~p #~p~n"
+ ,[self(),PrevContext]),
+ TestPid ! {self(),uninstall_predelete},
+ case receive_messages([uninstall_continue]) of
+ [{TestPid,uninstall_continue}] ->
+ ?deactivate_debug_fun(DebugId),
+ %%?verbose("uninstall_fallback continues~n"),
+ PrevContext+1
+ end
+ end,
+ ?remote_activate_debug_fun(Node1,DebugId, DebugFun, 1),
+
+ Tab = install_table,
+ Def = [{attributes, [key, value]},
+ {ram_copies, Nodes}], %% necessary to test different types ???
+
+ ?match({atomic, ok}, mnesia:create_table(Tab, Def)),
+
+ ?match(ok, mnesia:dirty_write({Tab, 1, 4711})),
+ ?match(ok, mnesia:dirty_write({Tab, 2, 42})),
+ ?match(ok, mnesia:dirty_write({Tab, 3, 256})),
+
+ {ok, CPName, _NodeList} =
+ mnesia:activate_checkpoint([{max, mnesia:system_info(tables)},
+ {ram_overrides_dump,true}]),
+
+ ?match(ok, mnesia:backup_checkpoint(CPName,install_backup)),
+ timer:sleep(timer:seconds(1)),
+
+ A ! fun () ->
+ mnesia:install_fallback(install_backup)
+ end,
+ ?match_receive({A,ok}),
+
+ A ! fun () ->
+ mnesia:uninstall_fallback()
+ end,
+ %%
+ %% catch the debug entry in mnesia and kill one Mnesia node
+ %%
+
+
+ [{AnsPid,uninstall_predelete}] = receive_messages([uninstall_predelete]),
+
+ ?verbose("AnsPid : ~p~n",[AnsPid]),
+
+ mnesia_test_lib:kill_mnesia([Node2]),
+ timer:sleep(timer:seconds(1)),
+
+ AnsPid ! {self(),uninstall_continue},
+
+ ?match_receive({A,ok}),
+
+ mnesia_test_lib:kill_mnesia(Nodes) ,
+ mnesia_test_lib:start_mnesia(Nodes,[Tab]),
+
+ A ! fun () ->
+ R1 = mnesia:dirty_read({Tab,1}),
+ R2 = mnesia:dirty_read({Tab,2}),
+ R3 = mnesia:dirty_read({Tab,3}),
+ {R1,R2,R3}
+ end,
+ ?match_receive({ A, {[],[],[]} }),
+
+ B ! fun () ->
+ R1 = mnesia:dirty_read({Tab,1}),
+ R2 = mnesia:dirty_read({Tab,2}),
+ R3 = mnesia:dirty_read({Tab,3}),
+ {R1,R2,R3}
+ end,
+ ?match_receive({ B, {[],[],[]} }),
+
+ C ! fun () ->
+ R1 = mnesia:dirty_read({Tab,1}),
+ R2 = mnesia:dirty_read({Tab,2}),
+ R3 = mnesia:dirty_read({Tab,3}),
+ {R1,R2,R3}
+ end,
+ ?match_receive({ C, {[],[],[]} }),
+
+ ?match(ok,file:delete(install_backup)),
+ ?verify_mnesia(Nodes, []).
+
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+mnesia_down_during_backup_causes_switch(doc) ->
+ ["Verify that an ongoing backup is not disturbed",
+ "even if the node hosting the replica that currently",
+ "is being backup'ed is stopped. The backup utility",
+ "is expected to switch over to another replica and",
+ "fulfill the backup."];
+mnesia_down_during_backup_causes_switch(suite) ->
+ [
+ cause_switch_before,
+ cause_switch_after
+ ].
+
+%%%%%%%%%%%%%%%
+
+cause_switch_before(doc) ->
+ ["interrupt the backup before iterating the retainer"];
+cause_switch_before(suite) -> [];
+cause_switch_before(Config) when is_list(Config) ->
+ do_something_during_backup(cause_switch,pre,Config).
+
+%%%%%%%%%%%%%%%
+
+cause_switch_after(doc) ->
+ ["interrupt the backup after iterating the retainer"];
+cause_switch_after(suite) -> [];
+cause_switch_after(Config) when is_list(Config) ->
+ do_something_during_backup(cause_switch,post,Config).
+
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+mnesia_down_during_backup_causes_abort(doc) ->
+ ["Verify that an ongoing backup is aborted nicely",
+ "without leaving any backup file if the last replica",
+ "of a table becomes unavailable due to a node down",
+ "or some crash."];
+mnesia_down_during_backup_causes_abort(suite) ->
+ [
+ cause_abort_before,
+ cause_abort_after
+ ].
+
+%%%%%%%%%%%%%%%%%%
+
+cause_abort_before(doc) ->
+ ["interrupt the backup before iterating the retainer"];
+
+cause_abort_before(suite) -> [];
+cause_abort_before(Config) when is_list(Config) ->
+ do_something_during_backup(cause_abort,pre,Config).
+
+%%%%%%%%%%%%%%%%%%
+
+cause_abort_after(doc) ->
+ ["interrupt the backup after iterating the retainer"];
+
+cause_abort_after(suite) -> [];
+cause_abort_after(Config) when is_list(Config) ->
+ do_something_during_backup(cause_abort,post,Config).
+
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+schema_transactions_during_backup(doc) ->
+ ["Verify that an schema transactions does not",
+ "affect an ongoing backup."];
+schema_transactions_during_backup(suite) ->
+ [
+ change_schema_before,
+ change_schema_after
+ ].
+
+%%%%%%%%%%%%%
+
+change_schema_before(doc) ->
+ ["interrupt the backup before iterating the retainer"];
+change_schema_before(suite) -> [];
+change_schema_before(Config) when is_list(Config) ->
+ do_something_during_backup(change_schema,pre,Config).
+
+%%%%%%%%%%%%%%%%
+
+change_schema_after(doc) ->
+ ["interrupt the backup after iterating the retainer"];
+change_schema_after(suite) -> [];
+change_schema_after(Config) when is_list(Config) ->
+ do_something_during_backup(change_schema,post,Config).
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+do_something_during_backup(Action,DebugPoint,Config) ->
+ ?is_debug_compiled,
+
+ Nodes = ?acquire_nodes(3, Config),
+
+ {success, [A,B,C]} = ?start_activities(Nodes),
+
+ Node1 = node(A),
+ Node2 = node(B),
+ Node3 = node(C),
+
+ TestPid = self(),
+ %%?verbose("TestPid : ~p~n",[TestPid]),
+
+ Tab = interrupt_table,
+ Bak = interrupt_backup,
+ Def = [{attributes, [key, value]},
+ {ram_copies, [Node2,Node3]}],
+ %% necessary to test different types ???
+
+ ?match({atomic, ok}, mnesia:create_table(Tab, Def)),
+
+
+
+ DebugId = {mnesia_log, tab_copier, DebugPoint},
+ DebugFun = fun(PrevContext, EvalContext) ->
+ ?verbose("interrupt backup pid ~p #~p ~n context ~p ~n"
+ ,[self(),PrevContext,EvalContext]),
+ TestPid ! {self(),interrupt_backup_pre},
+ global:set_lock({{lock_for_backup, Tab}, self()},
+ Nodes,
+ infinity),
+
+ %%?verbose("interrupt backup - continues ~n"),
+ ?deactivate_debug_fun(DebugId),
+ PrevContext+1
+ end,
+ ?remote_activate_debug_fun(Node1,DebugId, DebugFun, 1),
+
+ ?match(ok, mnesia:dirty_write({Tab, 1, 4711})),
+ ?match(ok, mnesia:dirty_write({Tab, 2, 42})),
+ ?match(ok, mnesia:dirty_write({Tab, 3, 256})),
+
+ {ok, CPName, _NodeList} =
+ mnesia:activate_checkpoint([{max, mnesia:system_info(tables)},
+ {ram_overrides_dump,true}]),
+
+ A ! fun () ->
+ %%?verbose("node: ~p pid: ~p ~n",[node(),self()]),
+ mnesia:table_info(Tab,where_to_read)
+ end,
+
+ ReadNode_a = receive { A, ReadNode_a_tmp } -> ReadNode_a_tmp end,
+ ?verbose("ReadNode ~p ~n",[ReadNode_a]),
+
+ global:set_lock({{lock_for_backup, Tab}, self()}, Nodes, infinity),
+
+ A ! fun () -> %% A shall perform the backup, so the test proc is
+ %% able to do further actions in between
+ mnesia:backup_checkpoint(CPName, Bak)
+ end,
+
+ %% catch the debug function of mnesia, stop the backup process
+ %% kill the node ReadNode_a and continue the backup process
+ %% As there is a second replica of the table, the backup shall continue
+
+ case receive_messages([interrupt_backup_pre]) of
+ [{_AnsPid,interrupt_backup_pre}] -> ok
+ end,
+
+ case Action of
+ cause_switch ->
+ mnesia_test_lib:kill_mnesia([ReadNode_a]),
+ timer:sleep(timer:seconds(1));
+ cause_abort ->
+ mnesia_test_lib:kill_mnesia([Node2,Node3]),
+ timer:sleep(timer:seconds(1));
+ change_schema ->
+ Tab2 = second_interrupt_table,
+ Def2 = [{attributes, [key, value]},
+ {ram_copies, Nodes}],
+
+ ?match({atomic, ok}, mnesia:create_table(Tab2, Def2))
+ end,
+
+ %% AnsPid ! {self(),interrupt_backup_continue},
+ global:del_lock({{lock_for_backup, Tab}, self()}, Nodes),
+
+ case Action of
+ cause_abort ->
+
+ %% answer of A when finishing the backup
+ ?match_receive({A,{error, _}}),
+
+ ?match({error,{"Cannot install fallback",_}},
+ mnesia:install_fallback(Bak));
+ _ -> %% cause_switch, change_schema
+
+ ?match_receive({A,ok}), %% answer of A when finishing the backup
+
+ %% send a fun to that node where mnesia is still running
+ WritePid = case ReadNode_a of
+ Node2 -> C; %% node(C) == Node3
+ Node3 -> B
+ end,
+ WritePid ! fun () ->
+ ?match(ok, mnesia:dirty_write({Tab, 1, 815})),
+ ?match(ok, mnesia:dirty_write({Tab, 2, 816})),
+ ok
+ end,
+ ?match_receive({ WritePid, ok }),
+ ?match(ok, mnesia:install_fallback(Bak))
+ end,
+
+ %% Stop and then start mnesia and check table consistency
+ %%?verbose("Restarting Mnesia~n", []),
+ mnesia_test_lib:kill_mnesia(Nodes),
+ mnesia_test_lib:start_mnesia(Nodes,[Tab]),
+
+ case Action of
+ cause_switch ->
+ %% the backup should exist
+ cross_check_tables([A,B,C],Tab,{[{Tab,1,4711}],
+ [{Tab,2,42}],
+ [{Tab,3,256}] }),
+ ?match(ok,file:delete(Bak));
+ cause_abort ->
+ %% the backup should NOT exist
+ cross_check_tables([A,B,C],Tab,{[],[],[]}),
+ %% file does not exist
+ ?match({error, _},file:delete(Bak));
+ change_schema ->
+ %% the backup should exist
+ cross_check_tables([A,B,C],Tab,{[{Tab,1,4711}],
+ [{Tab,2,42}],
+ [{Tab,3,256}] }),
+ ?match(ok,file:delete(Bak))
+ end,
+ ?verify_mnesia(Nodes, []).
+
+%% check the contents of the table
+cross_check_tables([],_tab,_elements) -> ok;
+cross_check_tables([Pid|Rest],Tab,{Val1,Val2,Val3}) ->
+ Pid ! fun () ->
+ R1 = mnesia:dirty_read({Tab,1}),
+ R2 = mnesia:dirty_read({Tab,2}),
+ R3 = mnesia:dirty_read({Tab,3}),
+ {R1,R2,R3}
+ end,
+ ?match_receive({ Pid, {Val1, Val2, Val3 } }),
+ cross_check_tables(Rest,Tab,{Val1,Val2,Val3} ).
diff --git a/lib/mnesia/test/mnesia_cost.erl b/lib/mnesia/test/mnesia_cost.erl
new file mode 100644
index 0000000000..54cb2b3064
--- /dev/null
+++ b/lib/mnesia/test/mnesia_cost.erl
@@ -0,0 +1,222 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 1996-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(mnesia_cost).
+-compile(export_all).
+
+%% This code exercises the mnesia system and produces a bunch
+%% of measurements on what various things cost
+
+-define(TIMES, 1000). %% set to at least 1000 when running for real !!
+
+%% This is the record we perform all ops on in this test
+
+-record(item, {a = 1234,
+ b = foobar,
+ c = "1.2.3.4",
+ d = {'Lennart', 'Hyland'},
+ e = true
+ }).
+
+go() ->
+ go([node() | nodes()]).
+
+go(Nodes) when hd(Nodes) == node() ->
+ {ok, Out} = file:open("MNESIA_COST", write),
+ put(out, Out),
+
+ rpc:multicall(Nodes, mnesia, lkill, []),
+ ok = mnesia:delete_schema(Nodes),
+ ok = mnesia:create_schema(Nodes),
+ rpc:multicall(Nodes, mnesia, start, []),
+ TabDef = [{attributes, record_info(fields, item)}],
+ {atomic, ok} = mnesia:create_table(item, TabDef),
+
+ round("single ram copy", "no index"),
+ {atomic, ok} = mnesia:add_table_index(item, #item.e),
+ round("single ram copy", "One index"),
+
+ {atomic, ok} = mnesia:add_table_index(item, #item.c),
+ round("single ram copy", "Two indexes"),
+
+ {atomic, ok} = mnesia:del_table_index(item, #item.e),
+ {atomic, ok} = mnesia:del_table_index(item, #item.c),
+
+ {atomic, ok} = mnesia:change_table_copy_type(item, node(), disc_copies),
+ round("single disc copy", "no index"),
+
+ {atomic, ok} = mnesia:change_table_copy_type(item, node(), ram_copies),
+
+ case length(Nodes) of
+ Len when Len < 2 ->
+ format("<WARNING> replication skipped. Too few nodes.", []);
+ _Len ->
+ N2 = lists:nth(2, Nodes),
+ {atomic, ok} = mnesia:add_table_copy(item, N2, ram_copies),
+ round("2 replicated ram copy", "no index")
+ end,
+ file:close(Out),
+ erase(out),
+ ok.
+
+round(Replication, Index) ->
+ run(Replication, Index, [write],
+ fun() -> mnesia:write(#item{}) end),
+
+
+ run(Replication, Index, [read],
+ fun() -> mnesia:read({item, 1234}) end),
+
+ run(Replication, Index, [read, write],
+ fun() -> mnesia:read({item, 1234}),
+ mnesia:write(#item{}) end),
+
+ run(Replication, Index, [wread, write],
+ fun() -> mnesia:wread({item, 1234}),
+ mnesia:write(#item{}) end),
+
+
+ run(Replication, Index, [match, write, write, write],
+ fun() -> mnesia:match_object({item, 1, '_', '_', '_', true}),
+ mnesia:write(#item{a =1}),
+ mnesia:write(#item{a =2}),
+ mnesia:write(#item{a =3}) end).
+
+
+format(F, As) ->
+ io:format(get(out), F, As).
+
+run(What, OtherInfo, Ops, F) ->
+ run(t, What, OtherInfo, Ops, F).
+
+run(How, What, OtherInfo, Ops, F) ->
+ T1 = erlang:now(),
+ statistics(runtime),
+ do_times(How, ?TIMES, F),
+ {_, RunTime} = statistics(runtime),
+ T2 = erlang:now(),
+ RealTime = subtr(T1, T2),
+ report(How, What, OtherInfo, Ops, RunTime, RealTime).
+
+report(t, What, OtherInfo, Ops, RunTime, RealTime) ->
+ format("~s, ~s, transaction call ", [What, OtherInfo]),
+ format("Ops is ", []),
+ lists:foreach(fun(Op) -> format("~w-", [Op]) end, Ops),
+
+ format("~n ~w/~w Millisecs/Trans ~w/~w MilliSecs/Operation ~n~n",
+ [RunTime/?TIMES,
+ RealTime/?TIMES,
+ RunTime/(?TIMES*length(Ops)),
+ RealTime/(?TIMES*length(Ops))]);
+
+report(dirty, What, OtherInfo, Ops, RunTime, RealTime) ->
+ format("~s, ~s, dirty calls ", [What, OtherInfo]),
+ format("Ops is ", []),
+ lists:foreach(fun(Op) -> format("~w-", [Op]) end, Ops),
+
+ format("~n ~w/~w Millisecs/Bunch ~w/~w MilliSecs/Operation ~n~n",
+ [RunTime/?TIMES,
+ RealTime/?TIMES,
+ RunTime/(?TIMES*length(Ops)),
+ RealTime/(?TIMES*length(Ops))]).
+
+
+subtr(Before, After) ->
+ E =(element(1,After)*1000000000000
+ +element(2,After)*1000000+element(3,After)) -
+ (element(1,Before)*1000000000000
+ +element(2,Before)*1000000+element(3,Before)),
+ E div 1000.
+
+do_times(t, I, F) ->
+ do_trans_times(I, F);
+do_times(dirty, I, F) ->
+ do_dirty(I, F).
+
+do_trans_times(I, F) when I /= 0 ->
+ {atomic, _} = mnesia:transaction(F),
+ do_trans_times(I-1, F);
+do_trans_times(_,_) -> ok.
+
+do_dirty(I, F) when I /= 0 ->
+ F(),
+ do_dirty(I-1, F);
+do_dirty(_,_) -> ok.
+
+
+
+table_load([N1,N2| _ ] = Ns) ->
+ Nodes = [N1,N2],
+ rpc:multicall(Ns, mnesia, lkill, []),
+ ok = mnesia:delete_schema(Ns),
+ ok = mnesia:create_schema(Nodes),
+ rpc:multicall(Nodes, mnesia, start, []),
+ TabDef = [{disc_copies,[N1]},{ram_copies,[N2]},
+ {attributes,record_info(fields,item)},{record_name,item}],
+ Tabs = [list_to_atom("tab" ++ integer_to_list(I)) || I <- lists:seq(1,400)],
+
+ [mnesia:create_table(Tab,TabDef) || Tab <- Tabs],
+
+%% InitTab = fun(Tab) ->
+%% mnesia:write_lock_table(Tab),
+%% InitRec = fun(Key) -> mnesia:write(Tab,#item{a=Key},write) end,
+%% lists:foreach(InitRec, lists:seq(1,100))
+%% end,
+%%
+%% {Time,{atomic,ok}} = timer:tc(mnesia,transaction, [fun() ->lists:foreach(InitTab, Tabs) end]),
+ mnesia:dump_log(),
+%% io:format("Init took ~p msec ~n", [Time/1000]),
+ rpc:call(N2, mnesia, stop, []), timer:sleep(1000),
+ mnesia:stop(), timer:sleep(500),
+ %% Warmup
+ ok = mnesia:start([{no_table_loaders, 1}]),
+ timer:tc(mnesia, wait_for_tables, [Tabs, infinity]),
+ mnesia:dump_log(),
+ rpc:call(N2, mnesia, dump_log, []),
+ io:format("Initialized ~n",[]),
+
+ mnesia:stop(), timer:sleep(1000),
+ ok = mnesia:start([{no_table_loaders, 1}]),
+ {T1, ok} = timer:tc(mnesia, wait_for_tables, [Tabs, infinity]),
+ io:format("Loading from disc with 1 loader ~p msec~n",[T1/1000]),
+ mnesia:stop(), timer:sleep(1000),
+ ok = mnesia:start([{no_table_loaders, 4}]),
+ {T2, ok} = timer:tc(mnesia, wait_for_tables, [Tabs, infinity]),
+ io:format("Loading from disc with 4 loader ~p msec~n",[T2/1000]),
+
+ %% Warmup
+ rpc:call(N2, ?MODULE, remote_load, [Tabs,4]),
+ io:format("Initialized ~n",[]),
+
+
+ T3 = rpc:call(N2, ?MODULE, remote_load, [Tabs,1]),
+ io:format("Loading from net with 1 loader ~p msec~n",[T3/1000]),
+
+ T4 = rpc:call(N2, ?MODULE, remote_load, [Tabs,4]),
+ io:format("Loading from net with 4 loader ~p msec~n",[T4/1000]),
+
+ ok.
+
+remote_load(Tabs,Loaders) ->
+ ok = mnesia:start([{no_table_loaders, Loaders}]),
+%% io:format("~p ~n", [mnesia_controller:get_info(500)]),
+ {Time, ok} = timer:tc(mnesia, wait_for_tables, [Tabs, infinity]),
+ timer:sleep(1000), mnesia:stop(), timer:sleep(1000),
+ Time.
diff --git a/lib/mnesia/test/mnesia_dbn_meters.erl b/lib/mnesia/test/mnesia_dbn_meters.erl
new file mode 100644
index 0000000000..feaf90ee75
--- /dev/null
+++ b/lib/mnesia/test/mnesia_dbn_meters.erl
@@ -0,0 +1,242 @@
+%%
+%% %CopyrightBegin%
+%%
+%% 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
+%% 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(mnesia_dbn_meters).
+-export([
+ start/0,
+ local_start/0,
+ distr_start/1,
+ start/3
+ ]).
+
+-record(simple,{key,val=0}).
+-define(key,1).
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%% Configuration and start
+
+start() ->
+ local_start(),
+ distr_start(nodes()).
+
+local_start() ->
+ start(one_ram_only,[node()],some_meters()),
+ start(one_disc_only,[node()],some_meters()).
+
+distr_start([]) ->
+ local_only;
+distr_start(OtherNodes) when is_list(OtherNodes) ->
+ start(ram_and_ram,[node()|OtherNodes],some_meters()),
+ start(disc_and_disc,[node()|OtherNodes],some_meters()).
+
+start(Config,Nodes,Meters) ->
+ Attrs = record_info(fields,simple),
+ Schema = [{name,simple},{type,set},{attributes,Attrs}] ++ config(Config,Nodes),
+ L = '====================',
+ io:format("~n~p dbn_meters: ~p ~p~nSchema = ~p.~n~n",[L,Config,L,Schema]),
+ ok = mnesia:delete_schema(Nodes),
+ ok = mnesia:create_schema(Nodes),
+ rpc:multicall(Nodes, mnesia, start, []),
+ {atomic,_} = mnesia:create_table(Schema),
+ lists:foreach(fun report_meter/1,Meters),
+ {atomic, ok} = mnesia:delete_table(simple),
+ rpc:multicall(Nodes, mnesia, stop, []),
+ ok.
+
+config(one_ram_only,[Single|_]) ->
+ [{ram_copies,[Single]}];
+config(ram_and_ram,[Master|[Slave|_]]) ->
+ [{ram_copies,[Master,Slave]}];
+config(one_disc_only,[Single|_]) ->
+ [{disc_copies,[Single]}];
+config(disc_and_disc,[Master|[Slave|_]]) ->
+ [{disc_copies,[Master,Slave]}];
+config(Config,Nodes) ->
+ io:format("<ERROR> Config ~p not supported or too few nodes ~p given~n",[Config,Nodes]).
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%% The various DBN meters
+some_meters() ->
+ [create,
+ open_safe_read,
+ open_dirty_read,
+ get_int,
+ open_update,
+ put_int,
+ put_int_and_copy,
+ dirty_put_int_and_copy,
+ start_trans,
+ commit_one_update,
+ delete,
+ dirty_delete
+ ].
+
+report_meter(Meter) ->
+ Times = 100,
+ Micros = repeat_meter(Meter,{atomic,{0,ignore}},Times) div Times,
+ io:format("\t~-30w ~-10w micro seconds (mean of ~p repetitions)~n",[Meter,Micros,Times]).
+
+repeat_meter(_Meter,{atomic,{Micros,_Result}},0) ->
+ Micros;
+repeat_meter(Meter,{atomic,{Micros,_Result}},Times) when Times > 0 ->
+ repeat_meter(Meter,catch meter(Meter),Times-1) + Micros;
+repeat_meter(Meter,{aborted,Reason},Times) when Times > 0 ->
+ io:format("<ERROR>\t~-20w\t,aborted, because ~p~n",[Meter,Reason]),
+ 0;
+repeat_meter(Meter,{'EXIT',Reason},Times) when Times > 0 ->
+ io:format("<ERROR>\t~-20w\tcrashed, because ~p~n",[Meter,Reason]),
+ 0.
+
+meter(create) ->
+ Key = 1,
+ mnesia:transaction(fun() -> mnesia:delete({simple,Key}) end),
+ Fun = fun() ->
+ BeforeT = erlang:now(),
+ R = mnesia:write(#simple{key=Key}),
+ AfterT = erlang:now(),
+ elapsed_time(BeforeT,AfterT,R)
+ end,
+ mnesia:transaction(Fun);
+
+meter(open_safe_read) ->
+ Key = 2,
+ mnesia:transaction(fun() -> mnesia:write(#simple{key=Key}) end),
+ Fun = fun() ->
+ BeforeT = erlang:now(),
+ R = mnesia:read({simple,Key}),
+ AfterT = erlang:now(),
+ elapsed_time(BeforeT,AfterT,R)
+ end,
+ mnesia:transaction(Fun);
+
+meter(open_dirty_read) ->
+ Key = 21,
+ mnesia:transaction(fun() -> mnesia:write(#simple{key=Key}) end),
+ Fun = fun() ->
+ BeforeT = erlang:now(),
+ R = mnesia:dirty_read({simple,Key}),
+ AfterT = erlang:now(),
+ elapsed_time(BeforeT,AfterT,R)
+ end,
+ mnesia:transaction(Fun);
+
+meter(get_int) ->
+ Key = 3,
+ mnesia:transaction(fun() -> mnesia:write(#simple{key=Key}) end),
+ Fun = fun() ->
+ [Simple] = mnesia:read({simple,Key}),
+ BeforeT = erlang:now(),
+ Int = Simple#simple.val,
+ AfterT = erlang:now(),
+ elapsed_time(BeforeT,AfterT,Int)
+ end,
+ mnesia:transaction(Fun);
+
+meter(open_update) ->
+ Key = 3,
+ mnesia:transaction(fun() -> mnesia:write(#simple{key=Key}) end),
+ Fun = fun() ->
+ BeforeT = erlang:now(),
+ R = mnesia:wread({simple,Key}),
+ AfterT = erlang:now(),
+ elapsed_time(BeforeT,AfterT,R)
+ end,
+ mnesia:transaction(Fun);
+
+meter(put_int) ->
+ Key = 4,
+ mnesia:transaction(fun() -> mnesia:write(#simple{key=Key}) end),
+ Fun = fun() ->
+ [Simple] = mnesia:wread({simple,Key}),
+ BeforeT = erlang:now(),
+ R = Simple#simple{val=7},
+ AfterT = erlang:now(),
+ elapsed_time(BeforeT,AfterT,R)
+ end,
+ mnesia:transaction(Fun);
+
+meter(put_int_and_copy) ->
+ Key = 5,
+ mnesia:transaction(fun() -> mnesia:write(#simple{key=Key}) end),
+ Fun = fun() ->
+ [Simple] = mnesia:wread({simple,Key}),
+ BeforeT = erlang:now(),
+ Simple2 = Simple#simple{val=17},
+ R = mnesia:write(Simple2),
+ AfterT = erlang:now(),
+ elapsed_time(BeforeT,AfterT,R)
+ end,
+ mnesia:transaction(Fun);
+
+meter(dirty_put_int_and_copy) ->
+ Key = 55,
+ mnesia:dirty_write(#simple{key=Key}),
+ [Simple] = mnesia:dirty_read({simple,Key}),
+ BeforeT = erlang:now(),
+ Simple2 = Simple#simple{val=17},
+ R = mnesia:dirty_write(Simple2),
+ AfterT = erlang:now(),
+ {atomic,elapsed_time(BeforeT,AfterT,R)};
+
+meter(start_trans) ->
+ BeforeT = erlang:now(),
+ {atomic,AfterT} = mnesia:transaction(fun() -> erlang:now() end),
+ {atomic,elapsed_time(BeforeT,AfterT,ok)};
+
+meter(commit_one_update) ->
+ Key = 6,
+ mnesia:transaction(fun() -> mnesia:write(#simple{key=Key}) end),
+ Fun = fun() ->
+ [Simple] = mnesia:wread({simple,Key}),
+ Simple2 = Simple#simple{val=27},
+ _R = mnesia:write(Simple2),
+ erlang:now()
+ end,
+ {atomic,BeforeT} = mnesia:transaction(Fun),
+ AfterT = erlang:now(),
+ {atomic,elapsed_time(BeforeT,AfterT,ok)};
+
+meter(delete) ->
+ Key = 7,
+ mnesia:transaction(fun() -> mnesia:write(#simple{key=Key}) end),
+ Fun = fun() ->
+ BeforeT = erlang:now(),
+ R = mnesia:delete({simple,Key}),
+ AfterT = erlang:now(),
+ elapsed_time(BeforeT,AfterT,R)
+ end,
+ mnesia:transaction(Fun);
+
+meter(dirty_delete) ->
+ Key = 75,
+ mnesia:dirty_write(#simple{key=Key}),
+ BeforeT = erlang:now(),
+ R = mnesia:dirty_delete({simple,Key}),
+ AfterT = erlang:now(),
+ {atomic, elapsed_time(BeforeT,AfterT,R)}.
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%% Calculate the elapsed time
+elapsed_time(BeforeT,AfterT,Result) ->
+ {(element(1,AfterT)*1000000000000
+ +element(2,AfterT)*1000000+element(3,AfterT)) -
+ (element(1,BeforeT)*1000000000000
+ +element(2,BeforeT)*1000000+element(3,BeforeT)),Result}.
diff --git a/lib/mnesia/test/mnesia_dirty_access_test.erl b/lib/mnesia/test/mnesia_dirty_access_test.erl
new file mode 100644
index 0000000000..5f9f2a9733
--- /dev/null
+++ b/lib/mnesia/test/mnesia_dirty_access_test.erl
@@ -0,0 +1,927 @@
+%%
+%% %CopyrightBegin%
+%%
+%% 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
+%% 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(mnesia_dirty_access_test).
+-author('[email protected]').
+-compile([export_all]).
+-include("mnesia_test_lib.hrl").
+
+init_per_testcase(Func, Conf) ->
+ mnesia_test_lib:init_per_testcase(Func, Conf).
+
+fin_per_testcase(Func, Conf) ->
+ mnesia_test_lib:fin_per_testcase(Func, Conf).
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+all(doc) ->
+ ["Evil dirty access, regardless of transaction scope.",
+ "Invoke all functions in the API and try to cover all legal uses",
+ "cases as well the illegal dito. This is a complement to the",
+ "other more explicit test cases."];
+all(suite) ->
+ [
+ dirty_write,
+ dirty_read,
+ dirty_update_counter,
+ dirty_delete,
+ dirty_delete_object,
+ dirty_match_object,
+ dirty_index,
+ dirty_iter,
+ admin_tests
+ ].
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%% Write records dirty
+
+dirty_write(suite) ->
+ [
+ dirty_write_ram,
+ dirty_write_disc,
+ dirty_write_disc_only
+ ].
+
+dirty_write_ram(suite) -> [];
+dirty_write_ram(Config) when is_list(Config) ->
+ dirty_write(Config, ram_copies).
+
+dirty_write_disc(suite) -> [];
+dirty_write_disc(Config) when is_list(Config) ->
+ dirty_write(Config, disc_copies).
+
+dirty_write_disc_only(suite) -> [];
+dirty_write_disc_only(Config) when is_list(Config) ->
+ dirty_write(Config, disc_only_copies).
+
+dirty_write(Config, Storage) ->
+ [Node1] = Nodes = ?acquire_nodes(1, Config),
+ Tab = dirty_write,
+ Def = [{attributes, [k, v]}, {Storage, [Node1]}],
+ ?match({atomic, ok}, mnesia:create_table(Tab, Def)),
+
+ ?match({'EXIT', _}, mnesia:dirty_write([])),
+ ?match({'EXIT', _}, mnesia:dirty_write({Tab, 2})),
+ ?match({'EXIT', _}, mnesia:dirty_write({foo, 2})),
+ ?match(ok, mnesia:dirty_write({Tab, 1, 2})),
+
+ ?match({atomic, ok}, mnesia:transaction(fun() ->
+ mnesia:dirty_write({Tab, 1, 2}) end)),
+ ?verify_mnesia(Nodes, []).
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%% Read records dirty
+
+dirty_read(suite) ->
+ [
+ dirty_read_ram,
+ dirty_read_disc,
+ dirty_read_disc_only
+ ].
+
+dirty_read_ram(suite) -> [];
+dirty_read_ram(Config) when is_list(Config) ->
+ dirty_read(Config, ram_copies).
+
+dirty_read_disc(suite) -> [];
+dirty_read_disc(Config) when is_list(Config) ->
+ dirty_read(Config, disc_copies).
+
+dirty_read_disc_only(suite) -> [];
+dirty_read_disc_only(Config) when is_list(Config) ->
+ dirty_read(Config, disc_only_copies).
+
+dirty_read(Config, Storage) ->
+ [Node1] = Nodes = ?acquire_nodes(1, Config),
+ Tab = dirty_read,
+ Def = [{type, bag}, {attributes, [k, v]}, {Storage, [Node1]}],
+ ?match({atomic, ok}, mnesia:create_table(Tab, Def)),
+
+ ?match({'EXIT', _}, mnesia:dirty_read([])),
+ ?match({'EXIT', _}, mnesia:dirty_read({Tab})),
+ ?match({'EXIT', _}, mnesia:dirty_read({Tab, 1, 2})),
+ ?match([], mnesia:dirty_read({Tab, 1})),
+ ?match(ok, mnesia:dirty_write({Tab, 1, 2})),
+ ?match([{Tab, 1, 2}], mnesia:dirty_read({Tab, 1})),
+ ?match(ok, mnesia:dirty_write({Tab, 1, 3})),
+ ?match([{Tab, 1, 2}, {Tab, 1, 3}], mnesia:dirty_read({Tab, 1})),
+
+ ?match({atomic, [{Tab, 1, 2}, {Tab, 1, 3}]},
+ mnesia:transaction(fun() -> mnesia:dirty_read({Tab, 1}) end)),
+
+ ?match(false, mnesia:async_dirty(fun() -> mnesia:is_transaction() end)),
+ ?match(false, mnesia:sync_dirty(fun() -> mnesia:is_transaction() end)),
+ ?match(false, mnesia:ets(fun() -> mnesia:is_transaction() end)),
+ ?match(false, mnesia:activity(async_dirty, fun() -> mnesia:is_transaction() end)),
+ ?match(false, mnesia:activity(sync_dirty, fun() -> mnesia:is_transaction() end)),
+ ?match(false, mnesia:activity(ets, fun() -> mnesia:is_transaction() end)),
+
+ ?verify_mnesia(Nodes, []).
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%% Update counter record dirty
+
+dirty_update_counter(suite) ->
+ [
+ dirty_update_counter_ram,
+ dirty_update_counter_disc,
+ dirty_update_counter_disc_only
+ ].
+
+dirty_update_counter_ram(suite) -> [];
+dirty_update_counter_ram(Config) when is_list(Config) ->
+ dirty_update_counter(Config, ram_copies).
+
+dirty_update_counter_disc(suite) -> [];
+dirty_update_counter_disc(Config) when is_list(Config) ->
+ dirty_update_counter(Config, disc_copies).
+
+dirty_update_counter_disc_only(suite) -> [];
+dirty_update_counter_disc_only(Config) when is_list(Config) ->
+ dirty_update_counter(Config, disc_only_copies).
+
+dirty_update_counter(Config, Storage) ->
+ [Node1] = Nodes = ?acquire_nodes(1, Config),
+ Tab = dirty_update_counter,
+ Def = [{attributes, [k, v]}, {Storage, [Node1]}],
+ ?match({atomic, ok}, mnesia:create_table(Tab, Def)),
+ ?match(ok, mnesia:dirty_write({Tab, 1, 2})),
+
+ ?match({'EXIT', _}, mnesia:dirty_update_counter({Tab, 1}, [])),
+ ?match({'EXIT', _}, mnesia:dirty_update_counter({Tab}, 3)),
+ ?match({'EXIT', _}, mnesia:dirty_update_counter({foo, 1}, 3)),
+ ?match(5, mnesia:dirty_update_counter({Tab, 1}, 3)),
+ ?match([{Tab, 1, 5}], mnesia:dirty_read({Tab, 1})),
+
+ ?match({atomic, 8}, mnesia:transaction(fun() ->
+ mnesia:dirty_update_counter({Tab, 1}, 3) end)),
+
+ ?match(1, mnesia:dirty_update_counter({Tab, foo}, 1)),
+ ?match([{Tab, foo,1}], mnesia:dirty_read({Tab,foo})),
+
+ ?verify_mnesia(Nodes, []).
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%% Delete record dirty
+
+dirty_delete(suite) ->
+ [
+ dirty_delete_ram,
+ dirty_delete_disc,
+ dirty_delete_disc_only
+ ].
+
+dirty_delete_ram(suite) -> [];
+dirty_delete_ram(Config) when is_list(Config) ->
+ dirty_delete(Config, ram_copies).
+
+dirty_delete_disc(suite) -> [];
+dirty_delete_disc(Config) when is_list(Config) ->
+ dirty_delete(Config, disc_copies).
+
+dirty_delete_disc_only(suite) -> [];
+dirty_delete_disc_only(Config) when is_list(Config) ->
+ dirty_delete(Config, disc_only_copies).
+
+dirty_delete(Config, Storage) ->
+ [Node1] = Nodes = ?acquire_nodes(1, Config),
+ Tab = dirty_delete,
+ Def = [{type, bag}, {attributes, [k, v]}, {Storage, [Node1]}],
+ ?match({atomic, ok}, mnesia:create_table(Tab, Def)),
+
+ ?match({'EXIT', _}, mnesia:dirty_delete([])),
+ ?match({'EXIT', _}, mnesia:dirty_delete({Tab})),
+ ?match({'EXIT', _}, mnesia:dirty_delete({Tab, 1, 2})),
+ ?match(ok, mnesia:dirty_delete({Tab, 1})),
+ ?match(ok, mnesia:dirty_write({Tab, 1, 2})),
+ ?match(ok, mnesia:dirty_delete({Tab, 1})),
+ ?match(ok, mnesia:dirty_write({Tab, 1, 2})),
+ ?match(ok, mnesia:dirty_write({Tab, 1, 2})),
+ ?match(ok, mnesia:dirty_delete({Tab, 1})),
+
+ ?match(ok, mnesia:dirty_write({Tab, 1, 2})),
+ ?match({atomic, ok}, mnesia:transaction(fun() ->
+ mnesia:dirty_delete({Tab, 1}) end)),
+ ?verify_mnesia(Nodes, []).
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%% Delete matching record dirty
+
+dirty_delete_object(suite) ->
+ [
+ dirty_delete_object_ram,
+ dirty_delete_object_disc,
+ dirty_delete_object_disc_only
+ ].
+
+dirty_delete_object_ram(suite) -> [];
+dirty_delete_object_ram(Config) when is_list(Config) ->
+ dirty_delete_object(Config, ram_copies).
+
+dirty_delete_object_disc(suite) -> [];
+dirty_delete_object_disc(Config) when is_list(Config) ->
+ dirty_delete_object(Config, disc_copies).
+
+dirty_delete_object_disc_only(suite) -> [];
+dirty_delete_object_disc_only(Config) when is_list(Config) ->
+ dirty_delete_object(Config, disc_only_copies).
+
+dirty_delete_object(Config, Storage) ->
+ [Node1] = Nodes = ?acquire_nodes(1, Config),
+ Tab = dirty_delete_object,
+ Def = [{type, bag}, {attributes, [k, v]}, {Storage, [Node1]}],
+ ?match({atomic, ok}, mnesia:create_table(Tab, Def)),
+
+ OneRec = {Tab, 1, 2},
+ ?match({'EXIT', _}, mnesia:dirty_delete_object([])),
+ ?match({'EXIT', _}, mnesia:dirty_delete_object({Tab})),
+ ?match({'EXIT', _}, mnesia:dirty_delete_object({Tab, 1})),
+ ?match(ok, mnesia:dirty_delete_object(OneRec)),
+ ?match(ok, mnesia:dirty_write(OneRec)),
+ ?match(ok, mnesia:dirty_delete_object(OneRec)),
+ ?match(ok, mnesia:dirty_write(OneRec)),
+ ?match(ok, mnesia:dirty_write(OneRec)),
+ ?match(ok, mnesia:dirty_delete_object(OneRec)),
+
+ ?match(ok, mnesia:dirty_write(OneRec)),
+ ?match({atomic, ok}, mnesia:transaction(fun() ->
+ mnesia:dirty_delete_object(OneRec) end)),
+
+ ?match({'EXIT', {aborted, {bad_type, Tab, _}}}, mnesia:dirty_delete_object(Tab, {Tab, {['_']}, 21})),
+ ?match({'EXIT', {aborted, {bad_type, Tab, _}}}, mnesia:dirty_delete_object(Tab, {Tab, {['$5']}, 21})),
+
+ ?verify_mnesia(Nodes, []).
+
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%% Read matching records dirty
+
+dirty_match_object(suite) ->
+ [
+ dirty_match_object_ram,
+ dirty_match_object_disc,
+ dirty_match_object_disc_only
+ ].
+
+dirty_match_object_ram(suite) -> [];
+dirty_match_object_ram(Config) when is_list(Config) ->
+ dirty_match_object(Config, ram_copies).
+
+dirty_match_object_disc(suite) -> [];
+dirty_match_object_disc(Config) when is_list(Config) ->
+ dirty_match_object(Config, disc_copies).
+
+dirty_match_object_disc_only(suite) -> [];
+dirty_match_object_disc_only(Config) when is_list(Config) ->
+ dirty_match_object(Config, disc_only_copies).
+
+dirty_match_object(Config, Storage) ->
+ [Node1] = Nodes = ?acquire_nodes(1, Config),
+ Tab = dirty_match,
+ Def = [{attributes, [k, v]}, {Storage, [Node1]}],
+ ?match({atomic, ok}, mnesia:create_table(Tab, Def)),
+
+ OneRec = {Tab, 1, 2},
+ OnePat = {Tab, '$1', 2},
+ ?match([], mnesia:dirty_match_object(OnePat)),
+ ?match(ok, mnesia:dirty_write(OneRec)),
+ ?match([OneRec], mnesia:dirty_match_object(OnePat)),
+ ?match({atomic, [OneRec]}, mnesia:transaction(fun() ->
+ mnesia:dirty_match_object(OnePat) end)),
+
+ ?match({'EXIT', _}, mnesia:dirty_match_object({foo, '$1', 2})),
+ ?match({'EXIT', _}, mnesia:dirty_match_object({[], '$1', 2})),
+ ?verify_mnesia(Nodes, []).
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+dirty_index(suite) ->
+ [
+ dirty_index_match_object,
+ dirty_index_read,
+ dirty_index_update
+ ].
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%% Dirty read matching records by using an index
+
+dirty_index_match_object(suite) ->
+ [
+ dirty_index_match_object_ram,
+ dirty_index_match_object_disc,
+ dirty_index_match_object_disc_only
+ ].
+
+dirty_index_match_object_ram(suite) -> [];
+dirty_index_match_object_ram(Config) when is_list(Config) ->
+ dirty_index_match_object(Config, ram_copies).
+
+dirty_index_match_object_disc(suite) -> [];
+dirty_index_match_object_disc(Config) when is_list(Config) ->
+ dirty_index_match_object(Config, disc_copies).
+
+dirty_index_match_object_disc_only(suite) -> [];
+dirty_index_match_object_disc_only(Config) when is_list(Config) ->
+ dirty_index_match_object(Config, disc_only_copies).
+
+dirty_index_match_object(Config, Storage) ->
+ [Node1] = Nodes = ?acquire_nodes(1, Config),
+ Tab = dirty_index_match_object,
+ ValPos = 3,
+ BadValPos = ValPos + 1,
+ Def = [{attributes, [k, v]}, {Storage, [Node1]}, {index, [ValPos]}],
+ ?match({atomic, ok}, mnesia:create_table(Tab, Def)),
+
+ ?match([], mnesia:dirty_index_match_object({Tab, '$1', 2}, ValPos)),
+ OneRec = {Tab, 1, 2},
+ ?match(ok, mnesia:dirty_write(OneRec)),
+
+ ?match([OneRec], mnesia:dirty_index_match_object({Tab, '$1', 2}, ValPos)),
+ ?match({'EXIT', _}, mnesia:dirty_index_match_object({Tab, '$1', 2}, BadValPos)),
+ ?match({'EXIT', _}, mnesia:dirty_index_match_object({foo, '$1', 2}, ValPos)),
+ ?match({'EXIT', _}, mnesia:dirty_index_match_object({[], '$1', 2}, ValPos)),
+ ?match({atomic, [OneRec]}, mnesia:transaction(fun() ->
+ mnesia:dirty_index_match_object({Tab, '$1', 2}, ValPos) end)),
+
+ ?verify_mnesia(Nodes, []).
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%% Read records by using an index
+
+dirty_index_read(suite) ->
+ [
+ dirty_index_read_ram,
+ dirty_index_read_disc,
+ dirty_index_read_disc_only
+ ].
+
+dirty_index_read_ram(suite) -> [];
+dirty_index_read_ram(Config) when is_list(Config) ->
+ dirty_index_read(Config, ram_copies).
+
+dirty_index_read_disc(suite) -> [];
+dirty_index_read_disc(Config) when is_list(Config) ->
+ dirty_index_read(Config, disc_copies).
+
+dirty_index_read_disc_only(suite) -> [];
+dirty_index_read_disc_only(Config) when is_list(Config) ->
+ dirty_index_read(Config, disc_only_copies).
+
+dirty_index_read(Config, Storage) ->
+ [Node1] = Nodes = ?acquire_nodes(1, Config),
+ Tab = dirty_index_read,
+ ValPos = 3,
+ BadValPos = ValPos + 1,
+ Def = [{type, set},
+ {attributes, [k, v]},
+ {Storage, [Node1]},
+ {index, [ValPos]}],
+ ?match({atomic, ok}, mnesia:create_table(Tab, Def)),
+
+ OneRec = {Tab, 1, 2},
+ ?match([], mnesia:dirty_index_read(Tab, 2, ValPos)),
+ ?match(ok, mnesia:dirty_write(OneRec)),
+ ?match([OneRec], mnesia:dirty_index_read(Tab, 2, ValPos)),
+ ?match({atomic, [OneRec]},
+ mnesia:transaction(fun() -> mnesia:dirty_index_read(Tab, 2, ValPos) end)),
+ ?match(42, mnesia:dirty_update_counter({Tab, 1}, 40)),
+ ?match([{Tab,1,42}], mnesia:dirty_read({Tab, 1})),
+ ?match([], mnesia:dirty_index_read(Tab, 2, ValPos)),
+ ?match([{Tab, 1, 42}], mnesia:dirty_index_read(Tab, 42, ValPos)),
+
+ ?match({'EXIT', _}, mnesia:dirty_index_read(Tab, 2, BadValPos)),
+ ?match({'EXIT', _}, mnesia:dirty_index_read(foo, 2, ValPos)),
+ ?match({'EXIT', _}, mnesia:dirty_index_read([], 2, ValPos)),
+
+ ?verify_mnesia(Nodes, []).
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+dirty_index_update(suite) ->
+ [
+ dirty_index_update_set_ram,
+ dirty_index_update_set_disc,
+ dirty_index_update_set_disc_only,
+ dirty_index_update_bag_ram,
+ dirty_index_update_bag_disc,
+ dirty_index_update_bag_disc_only
+ ];
+dirty_index_update(doc) ->
+ ["See Ticket OTP-2083, verifies that a table with a index is "
+ "update in the correct way i.e. the index finds the correct "
+ "records after a update"].
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+dirty_index_update_set_ram(suite) -> [];
+dirty_index_update_set_ram(Config) when is_list(Config) ->
+ dirty_index_update_set(Config, ram_copies).
+
+dirty_index_update_set_disc(suite) -> [];
+dirty_index_update_set_disc(Config) when is_list(Config) ->
+ dirty_index_update_set(Config, disc_copies).
+
+dirty_index_update_set_disc_only(suite) -> [];
+dirty_index_update_set_disc_only(Config) when is_list(Config) ->
+ dirty_index_update_set(Config, disc_only_copies).
+
+dirty_index_update_set(Config, Storage) ->
+ [Node1] = Nodes = ?acquire_nodes(1, Config),
+ Tab = index_test,
+ ValPos = v1,
+ ValPos2 = v3,
+ Def = [{attributes, [k, v1, v2, v3]},
+ {Storage, [Node1]},
+ {index, [ValPos]}],
+ ?match({atomic, ok}, mnesia:create_table(Tab, Def)),
+
+ Pat1 = {Tab, '$1', 2, '$2', '$3'},
+ Pat2 = {Tab, '$1', '$2', '$3', '$4'},
+
+ Rec1 = {Tab, 1, 2, 3, 4},
+ Rec2 = {Tab, 2, 2, 13, 14},
+ Rec3 = {Tab, 1, 12, 13, 14},
+ Rec4 = {Tab, 4, 2, 13, 14},
+
+ ?match([], mnesia:dirty_index_read(Tab, 2, ValPos)),
+ ?match(ok, mnesia:dirty_write(Rec1)),
+ ?match([Rec1], mnesia:dirty_index_read(Tab, 2, ValPos)),
+
+ ?match(ok, mnesia:dirty_write(Rec2)),
+ R1 = mnesia:dirty_index_read(Tab, 2, ValPos),
+ ?match([Rec1, Rec2], lists:sort(R1)),
+
+ ?match(ok, mnesia:dirty_write(Rec3)),
+ R2 = mnesia:dirty_index_read(Tab, 2, ValPos),
+ ?match([Rec2], lists:sort(R2)),
+ ?match([Rec2], mnesia:dirty_index_match_object(Pat1, ValPos)),
+
+ {atomic, R3} = mnesia:transaction(fun() -> mnesia:match_object(Pat2) end),
+ ?match([Rec3, Rec2], lists:sort(R3)),
+
+ ?match(ok, mnesia:dirty_write(Rec4)),
+ R4 = mnesia:dirty_index_read(Tab, 2, ValPos),
+ ?match([Rec2, Rec4], lists:sort(R4)),
+
+ ?match(ok, mnesia:dirty_delete({Tab, 4})),
+ ?match([Rec2], mnesia:dirty_index_read(Tab, 2, ValPos)),
+
+ ?match({atomic, ok}, mnesia:del_table_index(Tab, ValPos)),
+ ?match({atomic, ok}, mnesia:transaction(fun() -> mnesia:write(Rec4) end)),
+ ?match({atomic, ok}, mnesia:add_table_index(Tab, ValPos)),
+ ?match({atomic, ok}, mnesia:add_table_index(Tab, ValPos2)),
+
+ R5 = mnesia:dirty_match_object(Pat2),
+ ?match([Rec3, Rec2, Rec4], lists:sort(R5)),
+
+ R6 = mnesia:dirty_index_read(Tab, 2, ValPos),
+ ?match([Rec2, Rec4], lists:sort(R6)),
+ ?match([], mnesia:dirty_index_read(Tab, 4, ValPos2)),
+ R7 = mnesia:dirty_index_read(Tab, 14, ValPos2),
+ ?match([Rec3, Rec2, Rec4], lists:sort(R7)),
+
+ ?match({atomic, ok}, mnesia:transaction(fun() -> mnesia:write(Rec1) end)),
+ R8 = mnesia:dirty_index_read(Tab, 2, ValPos),
+ ?match([Rec1, Rec2, Rec4], lists:sort(R8)),
+ ?match([Rec1], mnesia:dirty_index_read(Tab, 4, ValPos2)),
+ R9 = mnesia:dirty_index_read(Tab, 14, ValPos2),
+ ?match([Rec2, Rec4], lists:sort(R9)),
+
+ ?match({atomic, ok}, mnesia:transaction(fun() -> mnesia:delete_object(Rec2) end)),
+ R10 = mnesia:dirty_index_read(Tab, 2, ValPos),
+ ?match([Rec1, Rec4], lists:sort(R10)),
+ ?match([Rec1], mnesia:dirty_index_read(Tab, 4, ValPos2)),
+ ?match([Rec4], mnesia:dirty_index_read(Tab, 14, ValPos2)),
+
+ ?match(ok, mnesia:dirty_delete({Tab, 4})),
+ R11 = mnesia:dirty_index_read(Tab, 2, ValPos),
+ ?match([Rec1], lists:sort(R11)),
+ ?match([Rec1], mnesia:dirty_index_read(Tab, 4, ValPos2)),
+ ?match([], mnesia:dirty_index_read(Tab, 14, ValPos2)),
+
+ ?verify_mnesia(Nodes, []).
+
+dirty_index_update_bag_ram(suite) -> [];
+dirty_index_update_bag_ram(Config)when is_list(Config) ->
+ dirty_index_update_bag(Config, ram_copies).
+
+dirty_index_update_bag_disc(suite) -> [];
+dirty_index_update_bag_disc(Config)when is_list(Config) ->
+ dirty_index_update_bag(Config, disc_copies).
+
+dirty_index_update_bag_disc_only(suite) -> [];
+dirty_index_update_bag_disc_only(Config)when is_list(Config) ->
+ dirty_index_update_bag(Config, disc_only_copies).
+
+dirty_index_update_bag(Config, Storage) ->
+ [Node1] = Nodes = ?acquire_nodes(1, Config),
+ Tab = index_test,
+ ValPos = v1,
+ ValPos2 = v3,
+ Def = [{type, bag},
+ {attributes, [k, v1, v2, v3]},
+ {Storage, [Node1]},
+ {index, [ValPos]}],
+ ?match({atomic, ok}, mnesia:create_table(Tab, Def)),
+
+ Pat1 = {Tab, '$1', 2, '$2', '$3'},
+ Pat2 = {Tab, '$1', '$2', '$3', '$4'},
+
+ Rec1 = {Tab, 1, 2, 3, 4},
+ Rec2 = {Tab, 2, 2, 13, 14},
+ Rec3 = {Tab, 1, 12, 13, 14},
+ Rec4 = {Tab, 4, 2, 13, 4},
+ Rec5 = {Tab, 1, 2, 234, 14},
+
+ %% Simple Index
+ ?match([], mnesia:dirty_index_read(Tab, 2, ValPos)),
+ ?match(ok, mnesia:dirty_write(Rec1)),
+ ?match([Rec1], mnesia:dirty_index_read(Tab, 2, ValPos)),
+
+ ?match({atomic, ok}, mnesia:transaction(fun() -> mnesia:write(Rec2) end)),
+ R1 = mnesia:dirty_index_read(Tab, 2, ValPos),
+ ?match([Rec1, Rec2], lists:sort(R1)),
+
+ ?match(ok, mnesia:dirty_write(Rec3)),
+ R2 = mnesia:dirty_index_read(Tab, 2, ValPos),
+ ?match([Rec1, Rec2], lists:sort(R2)),
+
+ R3 = mnesia:dirty_index_match_object(Pat1, ValPos),
+ ?match([Rec1, Rec2], lists:sort(R3)),
+
+ R4 = mnesia:dirty_match_object(Pat2),
+ ?match([Rec1, Rec3, Rec2], lists:sort(R4)),
+
+ ?match({atomic, ok}, mnesia:transaction(fun() -> mnesia:write(Rec4) end)),
+ R5 = mnesia:dirty_index_read(Tab, 2, ValPos),
+ ?match([Rec1, Rec2, Rec4], lists:sort(R5)),
+
+ ?match({atomic, ok}, mnesia:transaction(fun() -> mnesia:delete({Tab, 4}) end)),
+ R6 = mnesia:dirty_index_read(Tab, 2, ValPos),
+ ?match([Rec1, Rec2], lists:sort(R6)),
+
+ ?match(ok, mnesia:dirty_delete_object(Rec1)),
+ ?match([Rec2], mnesia:dirty_index_read(Tab, 2, ValPos)),
+ R7 = mnesia:dirty_match_object(Pat2),
+ ?match([Rec3, Rec2], lists:sort(R7)),
+
+ %% Two indexies
+ ?match({atomic, ok}, mnesia:del_table_index(Tab, ValPos)),
+ ?match({atomic, ok}, mnesia:transaction(fun() -> mnesia:write(Rec1) end)),
+ ?match({atomic, ok}, mnesia:transaction(fun() -> mnesia:write(Rec4) end)),
+ ?match({atomic, ok}, mnesia:add_table_index(Tab, ValPos)),
+ ?match({atomic, ok}, mnesia:add_table_index(Tab, ValPos2)),
+
+ R8 = mnesia:dirty_index_read(Tab, 2, ValPos),
+ ?match([Rec1, Rec2, Rec4], lists:sort(R8)),
+
+ R9 = mnesia:dirty_index_read(Tab, 4, ValPos2),
+ ?match([Rec1, Rec4], lists:sort(R9)),
+ R10 = mnesia:dirty_index_read(Tab, 14, ValPos2),
+ ?match([Rec3, Rec2], lists:sort(R10)),
+
+ ?match({atomic, ok}, mnesia:transaction(fun() -> mnesia:write(Rec5) end)),
+ R11 = mnesia:dirty_index_read(Tab, 2, ValPos),
+ ?match([Rec1, Rec5, Rec2, Rec4], lists:sort(R11)),
+ R12 = mnesia:dirty_index_read(Tab, 4, ValPos2),
+ ?match([Rec1, Rec4], lists:sort(R12)),
+ R13 = mnesia:dirty_index_read(Tab, 14, ValPos2),
+ ?match([Rec5, Rec3, Rec2], lists:sort(R13)),
+
+ ?match({atomic, ok}, mnesia:transaction(fun() -> mnesia:delete_object(Rec1) end)),
+ R14 = mnesia:dirty_index_read(Tab, 2, ValPos),
+ ?match([Rec5, Rec2, Rec4], lists:sort(R14)),
+ ?match([Rec4], mnesia:dirty_index_read(Tab, 4, ValPos2)),
+ R15 = mnesia:dirty_index_read(Tab, 14, ValPos2),
+ ?match([Rec5, Rec3, Rec2], lists:sort(R15)),
+
+ ?match(ok, mnesia:dirty_delete_object(Rec5)),
+ R16 = mnesia:dirty_index_read(Tab, 2, ValPos),
+ ?match([Rec2, Rec4], lists:sort(R16)),
+ ?match([Rec4], mnesia:dirty_index_read(Tab, 4, ValPos2)),
+ R17 = mnesia:dirty_index_read(Tab, 14, ValPos2),
+ ?match([Rec3, Rec2], lists:sort(R17)),
+
+ ?match(ok, mnesia:dirty_write(Rec1)),
+ ?match(ok, mnesia:dirty_delete({Tab, 1})),
+ R18 = mnesia:dirty_index_read(Tab, 2, ValPos),
+ ?match([Rec2, Rec4], lists:sort(R18)),
+ ?match([Rec4], mnesia:dirty_index_read(Tab, 4, ValPos2)),
+ R19 = mnesia:dirty_index_read(Tab, 14, ValPos2),
+ ?match([Rec2], lists:sort(R19)),
+
+ ?verify_mnesia(Nodes, []).
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%% Dirty iteration
+%% dirty_slot, dirty_first, dirty_next
+
+dirty_iter(suite) ->
+ [
+ dirty_iter_ram,
+ dirty_iter_disc,
+ dirty_iter_disc_only
+ ].
+
+dirty_iter_ram(suite) -> [];
+dirty_iter_ram(Config) when is_list(Config) ->
+ dirty_iter(Config, ram_copies).
+
+dirty_iter_disc(suite) -> [];
+dirty_iter_disc(Config) when is_list(Config) ->
+ dirty_iter(Config, disc_copies).
+
+dirty_iter_disc_only(suite) -> [];
+dirty_iter_disc_only(Config) when is_list(Config) ->
+ dirty_iter(Config, disc_only_copies).
+
+dirty_iter(Config, Storage) ->
+ [Node1] = Nodes = ?acquire_nodes(1, Config),
+ Tab = dirty_iter,
+ Def = [{type, bag}, {attributes, [k, v]}, {Storage, [Node1]}],
+ ?match({atomic, ok}, mnesia:create_table(Tab, Def)),
+
+ ?match([], all_slots(Tab)),
+ ?match([], all_nexts(Tab)),
+
+ Keys = lists:seq(1, 5),
+ Records = [{Tab, A, B} || A <- Keys, B <- lists:seq(1, 2)],
+ lists:foreach(fun(Rec) -> ?match(ok, mnesia:dirty_write(Rec)) end, Records),
+
+ SortedRecords = lists:sort(Records),
+ ?match(SortedRecords, lists:sort(all_slots(Tab))),
+ ?match(Keys, lists:sort(all_nexts(Tab))),
+
+ ?match({'EXIT', _}, mnesia:dirty_first(foo)),
+ ?match({'EXIT', _}, mnesia:dirty_next(foo, foo)),
+ ?match({'EXIT', _}, mnesia:dirty_slot(foo, 0)),
+ ?match({'EXIT', _}, mnesia:dirty_slot(foo, [])),
+ ?match({atomic, Keys},
+ mnesia:transaction(fun() -> lists:sort(all_nexts(Tab)) end)),
+ ?verify_mnesia(Nodes, []).
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+%% Returns a list of all keys in table
+all_slots(Tab) ->
+ all_slots(Tab, [], 0).
+
+all_slots(_Tab, '$end_of_table', _) ->
+ [];
+all_slots(Tab, PrevRecords, PrevSlot) ->
+ Records = mnesia:dirty_slot(Tab, PrevSlot),
+ PrevRecords ++ all_slots(Tab, Records, PrevSlot + 1).
+
+%% Returns a list of all keys in table
+
+all_nexts(Tab) ->
+ FirstKey = mnesia:dirty_first(Tab),
+ all_nexts(Tab, FirstKey).
+
+all_nexts(_Tab, '$end_of_table') ->
+ [];
+all_nexts(Tab, PrevKey) ->
+ Key = mnesia:dirty_next(Tab, PrevKey),
+ [PrevKey] ++ all_nexts(Tab, Key).
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+admin_tests(doc) ->
+ ["Verifies that dirty operations work during schema operations"];
+
+admin_tests(suite) ->
+ [del_table_copy_1,
+ del_table_copy_2,
+ del_table_copy_3,
+ add_table_copy_1,
+ add_table_copy_2,
+ add_table_copy_3,
+ add_table_copy_4,
+ move_table_copy_1,
+ move_table_copy_2,
+ move_table_copy_3,
+ move_table_copy_4].
+
+update_trans(Tab, Key, Acc) ->
+ Update =
+ fun() ->
+ Res = (catch mnesia:read({Tab, Key})),
+ case Res of
+ [{Tab, Key, Extra, Acc}] ->
+ mnesia:write({Tab,Key,Extra, Acc+1});
+ Val ->
+ {read, Val, {acc, Acc}}
+ end
+ end,
+ receive
+ {Pid, quit} -> Pid ! {self(), Acc}
+ after
+ 3 ->
+ case catch mnesia:sync_dirty(Update) of
+ ok ->
+ update_trans(Tab, Key, Acc+1);
+ Else ->
+ ?error("Dirty Operation failed on ~p (update no ~p) with ~p~n"
+ "Info w2read ~p w2write ~p w2commit ~p storage ~p ~n",
+ [node(),
+ Acc,
+ Else,
+ mnesia:table_info(Tab, where_to_read),
+ mnesia:table_info(Tab, where_to_write),
+ mnesia:table_info(Tab, where_to_commit),
+ mnesia:table_info(Tab, storage_type)])
+ end
+ end.
+
+del_table_copy_1(suite) -> [];
+del_table_copy_1(Config) when is_list(Config) ->
+ [_Node1, Node2, _Node3] = Nodes = ?acquire_nodes(3, Config),
+ del_table(Node2, Node2, Nodes). %Called on same Node as deleted
+del_table_copy_2(suite) -> [];
+del_table_copy_2(Config) when is_list(Config) ->
+ [Node1, Node2, _Node3] = Nodes = ?acquire_nodes(3, Config),
+ del_table(Node1, Node2, Nodes). %Called from other Node
+del_table_copy_3(suite) -> [];
+del_table_copy_3(Config) when is_list(Config) ->
+ [_Node1, Node2, Node3] = Nodes = ?acquire_nodes(3, Config),
+ del_table(Node3, Node2, Nodes). %Called from Node w.o. table
+
+del_table(CallFrom, DelNode, [Node1, Node2, Node3]) ->
+ Tab = schema_ops,
+ Def = [{disc_only_copies, [Node1]}, {ram_copies, [Node2]},
+ {attributes, [key, attr1, attr2]}],
+ ?log("Test case removing table from ~w, with ~w~n", [DelNode, Def]),
+ ?match({atomic, ok}, mnesia:create_table(Tab, Def)),
+ insert(Tab, 1000),
+
+ Pid1 = spawn_link(Node1, ?MODULE, update_trans, [Tab, 1, 0]),
+ Pid2 = spawn_link(Node2, ?MODULE, update_trans, [Tab, 2, 0]),
+ Pid3 = spawn_link(Node3, ?MODULE, update_trans, [Tab, 3, 0]),
+
+
+ dbg:tracer(process, {fun(Msg,_) -> tracer(Msg) end, void}),
+ %% dbg:n(Node2),
+ %% dbg:n(Node3),
+ %% dbg:tp('_', []),
+ %% dbg:tpl(dets, [timestamp]),
+ dbg:p(Pid1, [m,c,timestamp]),
+
+ ?match({atomic, ok},
+ rpc:call(CallFrom, mnesia, del_table_copy, [Tab, DelNode])),
+
+ Pid1 ! {self(), quit}, R1 =
+ receive {Pid1, Res1} -> Res1
+ after
+ 5000 -> io:format("~p~n",[process_info(Pid1)]),error
+ end,
+ Pid2 ! {self(), quit}, R2 =
+ receive {Pid2, Res2} -> Res2
+ after
+ 5000 -> error
+ end,
+ Pid3 ! {self(), quit}, R3 =
+ receive {Pid3, Res3} -> Res3
+ after
+ 5000 -> error
+ end,
+ verify_oids(Tab, Node1, Node2, Node3, R1, R2, R3),
+ ?verify_mnesia([Node1, Node2, Node3], []).
+
+tracer({trace_ts, _, send, Msg, Pid, {_,S,Ms}}) ->
+ io:format("~p:~p ~p >> ~w ~n",[S,Ms,Pid,Msg]);
+tracer({trace_ts, _, 'receive', Msg, {_,S,Ms}}) ->
+ io:format("~p:~p << ~w ~n",[S,Ms,Msg]);
+
+
+tracer(Msg) ->
+ io:format("UMsg ~p ~n",[Msg]),
+ ok.
+
+
+
+add_table_copy_1(suite) -> [];
+add_table_copy_1(Config) when is_list(Config) ->
+ [Node1, Node2, Node3] = Nodes = ?acquire_nodes(3, Config),
+ Def = [{ram_copies, [Node1, Node2]},
+ {attributes, [key, attr1, attr2]}],
+ add_table(Node1, Node3, Nodes, Def).
+%% Not so much diff from 1 but I got a feeling of a bug
+%% should behave exactly the same but just checking the internal ordering
+add_table_copy_2(suite) -> [];
+add_table_copy_2(Config) when is_list(Config) ->
+ [Node1, Node2, Node3] = Nodes = ?acquire_nodes(3, Config),
+ Def = [{ram_copies, [Node1, Node2]},
+ {attributes, [key, attr1, attr2]}],
+ add_table(Node2, Node3, Nodes, Def).
+add_table_copy_3(suite) -> [];
+add_table_copy_3(Config) when is_list(Config) ->
+ [Node1, Node2, Node3] = Nodes = ?acquire_nodes(3, Config),
+ Def = [{ram_copies, [Node1, Node2]},
+ {attributes, [key, attr1, attr2]}],
+ add_table(Node3, Node3, Nodes, Def).
+add_table_copy_4(suite) -> [];
+add_table_copy_4(Config) when is_list(Config) ->
+ [Node1, Node2, Node3] = Nodes = ?acquire_nodes(3, Config),
+ Def = [{disc_only_copies, [Node1]},
+ {attributes, [key, attr1, attr2]}],
+ add_table(Node2, Node3, Nodes, Def).
+
+add_table(CallFrom, AddNode, [Node1, Node2, Node3], Def) ->
+ ?log("Test case adding table at ~w, with ~w~n", [AddNode, Def]),
+ Tab = schema_ops,
+ ?match({atomic, ok}, mnesia:create_table(Tab, Def)),
+ insert(Tab, 1002),
+
+ Pid1 = spawn_link(Node1, ?MODULE, update_trans, [Tab, 1, 0]),
+ Pid2 = spawn_link(Node2, ?MODULE, update_trans, [Tab, 2, 0]),
+ Pid3 = spawn_link(Node3, ?MODULE, update_trans, [Tab, 3, 0]),
+
+ ?match({atomic, ok}, rpc:call(CallFrom, mnesia, add_table_copy,
+ [Tab, AddNode, ram_copies])),
+ Pid1 ! {self(), quit}, R1 = receive {Pid1, Res1} -> Res1 after 5000 -> error end,
+ Pid2 ! {self(), quit}, R2 = receive {Pid2, Res2} -> Res2 after 5000 -> error end,
+ Pid3 ! {self(), quit}, R3 = receive {Pid3, Res3} -> Res3 after 5000 -> error end,
+ verify_oids(Tab, Node1, Node2, Node3, R1, R2, R3),
+ ?verify_mnesia([Node1, Node2, Node3], []).
+
+move_table_copy_1(suite) -> [];
+move_table_copy_1(Config) when is_list(Config) ->
+ [Node1, Node2, Node3] = Nodes = ?acquire_nodes(3, Config),
+ Def = [{ram_copies, [Node1, Node2]},
+ {attributes, [key, attr1, attr2]}],
+ move_table(Node1, Node1, Node3, Nodes, Def).
+move_table_copy_2(suite) -> [];
+move_table_copy_2(Config) when is_list(Config) ->
+ [Node1, Node2, Node3] = Nodes = ?acquire_nodes(3, Config),
+ Def = [{ram_copies, [Node1, Node2]},
+ {attributes, [key, attr1, attr2]}],
+ move_table(Node2, Node1, Node3, Nodes, Def).
+move_table_copy_3(suite) -> [];
+move_table_copy_3(Config) when is_list(Config) ->
+ [Node1, Node2, Node3] = Nodes = ?acquire_nodes(3, Config),
+ Def = [{ram_copies, [Node1, Node2]},
+ {attributes, [key, attr1, attr2]}],
+ move_table(Node3, Node1, Node3, Nodes, Def).
+move_table_copy_4(suite) -> [];
+move_table_copy_4(Config) when is_list(Config) ->
+ [Node1, Node2, Node3] = Nodes = ?acquire_nodes(3, Config),
+ Def = [{ram_copies, [Node1]},
+ {attributes, [key, attr1, attr2]}],
+ move_table(Node2, Node1, Node3, Nodes, Def).
+
+move_table(CallFrom, FromNode, ToNode, [Node1, Node2, Node3], Def) ->
+ ?log("Test case move table from ~w to ~w, with ~w~n", [FromNode, ToNode, Def]),
+ Tab = schema_ops,
+ ?match({atomic, ok}, mnesia:create_table(Tab, Def)),
+ insert(Tab, 1002),
+
+ Pid1 = spawn_link(Node1, ?MODULE, update_trans, [Tab, 1, 0]),
+ Pid2 = spawn_link(Node2, ?MODULE, update_trans, [Tab, 2, 0]),
+ Pid3 = spawn_link(Node3, ?MODULE, update_trans, [Tab, 3, 0]),
+
+ ?match({atomic, ok}, rpc:call(CallFrom, mnesia, move_table_copy,
+ [Tab, FromNode, ToNode])),
+ Pid1 ! {self(), quit},
+ R1 = receive {Pid1, Res1} -> Res1 after 5000 -> ?error("timeout pid1~n", []) end,
+ Pid2 ! {self(), quit},
+ R2 = receive {Pid2, Res2} -> Res2 after 5000 -> ?error("timeout pid2~n", []) end,
+ Pid3 ! {self(), quit},
+ R3 = receive {Pid3, Res3} -> Res3 after 5000 -> ?error("timeout pid3~n", []) end,
+ verify_oids(Tab, Node1, Node2, Node3, R1, R2, R3),
+ ?verify_mnesia([Node1, Node2, Node3], []).
+
+% Verify consistency between different nodes
+% Due to limitations in the current dirty_ops this can wrong from time to time!
+verify_oids(Tab, N1, N2, N3, R1, R2, R3) ->
+ io:format("DEBUG 1=>~p 2=>~p 3=>~p~n", [R1,R2,R3]),
+ ?match([{_, _, _, R1}], rpc:call(N1, mnesia, dirty_read, [{Tab, 1}])),
+ ?match([{_, _, _, R1}], rpc:call(N2, mnesia, dirty_read, [{Tab, 1}])),
+ ?match([{_, _, _, R1}], rpc:call(N3, mnesia, dirty_read, [{Tab, 1}])),
+ ?match([{_, _, _, R2}], rpc:call(N1, mnesia, dirty_read, [{Tab, 2}])),
+ ?match([{_, _, _, R2}], rpc:call(N2, mnesia, dirty_read, [{Tab, 2}])),
+ ?match([{_, _, _, R2}], rpc:call(N3, mnesia, dirty_read, [{Tab, 2}])),
+ ?match([{_, _, _, R3}], rpc:call(N1, mnesia, dirty_read, [{Tab, 3}])),
+ ?match([{_, _, _, R3}], rpc:call(N2, mnesia, dirty_read, [{Tab, 3}])),
+ ?match([{_, _, _, R3}], rpc:call(N3, mnesia, dirty_read, [{Tab, 3}])).
+
+insert(_Tab, 0) -> ok;
+insert(Tab, N) when N > 0 ->
+ ok = mnesia:sync_dirty(fun() -> false = mnesia:is_transaction(), mnesia:write({Tab, N, N, 0}) end),
+ insert(Tab, N-1).
+
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
diff --git a/lib/mnesia/test/mnesia_durability_test.erl b/lib/mnesia/test/mnesia_durability_test.erl
new file mode 100644
index 0000000000..b917b0ca40
--- /dev/null
+++ b/lib/mnesia/test/mnesia_durability_test.erl
@@ -0,0 +1,1470 @@
+%%
+%% %CopyrightBegin%
+%%
+%% 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(mnesia_durability_test).
+-author('[email protected]').
+-compile([export_all]).
+-include("mnesia_test_lib.hrl").
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+init_per_testcase(Func, Conf) ->
+ mnesia_test_lib:init_per_testcase(Func, Conf).
+
+fin_per_testcase(Func, Conf) ->
+ mnesia_test_lib:fin_per_testcase(Func, Conf).
+
+-record(test_rec,{key,val}).
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+all(doc) ->
+ ["Verify durability",
+ "Verify that the effects of committed transactions are durable.",
+ "The content of the tables tables must be restored at startup."];
+all(suite) ->
+ [
+ load_tables,
+ durability_of_dump_tables,
+ durability_of_disc_copies,
+ durability_of_disc_only_copies
+ ].
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+load_tables(doc) ->
+ ["Try to provoke all kinds of table load scenarios."];
+load_tables(suite) ->
+ [
+ load_latest_data,
+ load_local_contents_directly,
+ load_directly_when_all_are_ram_copiesA,
+ load_directly_when_all_are_ram_copiesB,
+ late_load_when_all_are_ram_copies_on_ram_nodes,
+ load_when_last_replica_becomes_available,
+ load_when_we_have_down_from_all_other_replica_nodes,
+ late_load_transforms_into_disc_load,
+ late_load_leads_to_hanging,
+ force_load_when_nobody_intents_to_load,
+ force_load_when_someone_has_decided_to_load,
+ force_load_when_someone_else_already_has_loaded,
+ force_load_when_we_has_loaded,
+ force_load_on_a_non_local_table,
+ force_load_when_the_table_does_not_exist,
+ load_tables_with_master_tables
+ ].
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+load_latest_data(doc) ->
+ ["Base functionality, verify that the latest data is loaded"];
+load_latest_data(suite) -> [];
+load_latest_data(Config) when is_list(Config) ->
+ [N1,N2,N3] = Nodes = ?acquire_nodes(3, Config),
+ %%Create a replicated local table
+ ?match({atomic,ok}, mnesia:create_table(t0, [{disc_copies,[N1,N2]}])),
+ ?match({atomic,ok}, mnesia:create_table(t1, [{disc_copies,[N1,N2]}])),
+ ?match({atomic,ok}, mnesia:create_table(t2, [{disc_copies,[N1,N2]}])),
+ ?match({atomic,ok}, mnesia:create_table(t3, [{disc_copies,[N1,N2]}])),
+ ?match({atomic,ok}, mnesia:create_table(t4, [{disc_copies,[N1,N2]}])),
+ ?match({atomic,ok}, mnesia:create_table(t5, [{disc_copies,[N1,N2]}])),
+ Rec1 = {t1, test, ok},
+ Rec2 = {t1, test, 2},
+
+ ?match([], mnesia_test_lib:kill_mnesia([N1])),
+ ?match(ok, rpc:call(N2, mnesia, dirty_write, [Rec2])),
+ ?match([], mnesia_test_lib:kill_mnesia([N2])),
+ ?match([], mnesia_test_lib:kill_mnesia([N3])),
+
+ ?match([], mnesia_test_lib:start_mnesia([N1], [])),
+ %% Should wait for N2
+ ?match({timeout, [t1]}, rpc:call(N1, mnesia, wait_for_tables, [[t1], 3000])),
+ ?match([], mnesia_test_lib:start_mnesia([N3], [])),
+ ?match({timeout, [t1]}, rpc:call(N1, mnesia, wait_for_tables, [[t1], 3000])),
+
+
+ ?match([], mnesia_test_lib:start_mnesia([N2], [])),
+ ?match(ok, rpc:call(N2, mnesia, wait_for_tables, [[t1], 3000])),
+ ?match(ok, rpc:call(N1, mnesia, wait_for_tables, [[t1], 3000])),
+ %% We should find the record
+ ?match([Rec2], rpc:call(N1, mnesia, dirty_read, [t1, test])),
+ ?match([Rec2], rpc:call(N2, mnesia, dirty_read, [t1, test])),
+
+ %% ok, lets switch order
+ ?match(ok, mnesia:dirty_delete_object(Rec1)),
+ ?match(ok, mnesia:dirty_delete_object(Rec2)),
+ %% redo
+
+ ?match([], mnesia_test_lib:kill_mnesia([N2])),
+ ?match(ok, mnesia:dirty_write(Rec1)),
+ ?match([], mnesia_test_lib:kill_mnesia([N1])),
+ ?match([], mnesia_test_lib:kill_mnesia([N3])),
+
+ ?match([], mnesia_test_lib:start_mnesia([N2], [])),
+ %% Should wait for N1
+ ?match({timeout, [t1]}, rpc:call(N2, mnesia, wait_for_tables, [[t1], 2000])),
+ ?match([], mnesia_test_lib:start_mnesia([N3], [])),
+ ?match({timeout, [t1]}, rpc:call(N2, mnesia, wait_for_tables, [[t1], 2000])),
+ ?match([], mnesia_test_lib:start_mnesia([N1], [])),
+ ?match(ok, rpc:call(N2, mnesia, wait_for_tables, [[t1], 1000])),
+ ?match(ok, rpc:call(N1, mnesia, wait_for_tables, [[t1], 1000])),
+ %% We should find the record
+ ?match([Rec1], rpc:call(N1, mnesia, dirty_read, [t1, test])),
+ ?match([Rec1], rpc:call(N2, mnesia, dirty_read, [t1, test])),
+
+ ?verify_mnesia(Nodes, []).
+
+
+load_local_contents_directly(doc) ->
+ ["Local contents shall always be loaded. Check this by having a local ",
+ "table on two nodes N1, N2, stopping N1 before N2, an then verifying ",
+ "that N1 can start without N2 being started."];
+load_local_contents_directly(suite) -> [];
+load_local_contents_directly(Config) when is_list(Config) ->
+ [N1, N2] = Nodes = ?acquire_nodes(2, Config),
+ %%Create a replicated local table
+ ?match({atomic,ok},
+ mnesia:create_table(test_rec,
+ [{local_content,true},
+ {disc_copies,Nodes},
+ {attributes,record_info(fields,test_rec)}]
+ ) ),
+ %%Verify that it has local contents.
+ ?match( true, mnesia:table_info(test_rec,local_content) ),
+ %%Helper Funs
+ Write_one = fun(Value) -> mnesia:write(#test_rec{key=1,val=Value}) end,
+ Read_one = fun(Key) -> mnesia:read( {test_rec, Key}) end,
+ %%Write a value one N1 that we may test against later
+ ?match({atomic,ok},
+ rpc:call( N1, mnesia, transaction, [Write_one,[11]] ) ),
+ %%Stop Mnesia on N1
+ %?match([], mnesia_test_lib:stop_mnesia([N1])),
+ ?match([], mnesia_test_lib:kill_mnesia([N1])),
+
+ %%Write a value on N2, same key but a different value
+ ?match({atomic,ok},
+ rpc:call( N2, mnesia, transaction, [Write_one,[22]] ) ),
+ %%Stop Mnesia on N2
+ %?match([], mnesia_test_lib:stop_mnesia([N2])),
+ ?match([], mnesia_test_lib:kill_mnesia([N2])),
+
+ %%Restart Mnesia on N1 verify that we can read from it without
+ %%starting Mnesia on N2.
+ ?match(ok, rpc:call(N1, mnesia, start, [])),
+ ?match(ok, rpc:call(N1, mnesia, wait_for_tables, [[test_rec], 30000])),
+ %%Read back the value
+ ?match( {atomic,[#test_rec{key=1,val=11}]},
+ rpc:call(N1, mnesia, transaction, [Read_one,[1]] ) ),
+ %%Restart Mnesia on N2 and verify the contents there.
+ ?match(ok, rpc:call(N2, mnesia, start, [])),
+ ?match(ok, rpc:call(N2, mnesia, wait_for_tables, [[test_rec], 30000])),
+ ?match( {atomic,[#test_rec{key=1,val=22}]},
+ rpc:call(N2, mnesia, transaction, [Read_one,[1]] ) ),
+ %%Check that the start of Mnesai on N2 did not affect the contents on N1
+ ?match( {atomic,[#test_rec{key=1,val=11}]},
+ rpc:call(N1, mnesia, transaction, [Read_one,[1]] ) ),
+ ?verify_mnesia(Nodes, []).
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+load_directly_when_all_are_ram_copiesA(doc) ->
+ ["Tables that are RAM copies only shall also be loaded directly. ",
+ "1. N1 and N2 has RAM copies of a table, stop N1 before N2. ",
+ "2. When N1 starts he shall have access to the table ",
+ " without having to start N2" ];
+load_directly_when_all_are_ram_copiesA(suite) -> [];
+load_directly_when_all_are_ram_copiesA(Config) when is_list(Config) ->
+ [N1, N2] = Nodes = ?acquire_nodes(2, Config),
+
+ ?match({atomic,ok},
+ mnesia:create_table(test_rec,
+ [{ram_copies,Nodes},
+ {attributes,record_info(fields,test_rec)}]
+ ) ),
+ ?match( Nodes, mnesia:table_info(test_rec,ram_copies) ),
+ ?match( [], mnesia:table_info(test_rec,disc_copies) ),
+ ?match( [], mnesia:table_info(test_rec,disc_only_copies) ),
+ Write_one = fun(Value) -> mnesia:write(#test_rec{key=2,val=Value}) end,
+ Read_one = fun() -> mnesia:read({test_rec,2}) end,
+ %%Write a value one N1 that we may test against later
+ ?match({atomic,ok},
+ rpc:call( N1, mnesia, transaction, [Write_one,[11]] ) ),
+ %%Stop Mnesia on N1
+ ?match([], mnesia_test_lib:kill_mnesia([N1])),
+ %%Write a value and check result (on N2; not possible on N1
+ %%since Mnesia is stopped there).
+ ?match({atomic,ok}, rpc:call(N2,mnesia,transaction,[Write_one,[22]]) ),
+ ?match({atomic,[#test_rec{key=2,val=22}]},
+ rpc:call(N2,mnesia,transaction,[Read_one]) ),
+ %%Stop Mnesia on N2
+ ?match([], mnesia_test_lib:kill_mnesia([N2])),
+ %%Restart Mnesia on N1 verify that we can access test_rec from
+ %%N1 without starting Mnesia on N2.
+ ?match(ok, rpc:call(N1, mnesia, start, [])),
+ ?match(ok, rpc:call(N1, mnesia, wait_for_tables, [[test_rec], 30000])),
+ ?match({atomic,[]}, rpc:call(N1,mnesia,transaction,[Read_one])),
+ ?match({atomic,ok}, rpc:call(N1,mnesia,transaction,[Write_one,[33]])),
+ ?match({atomic,[#test_rec{key=2,val=33}]},
+ rpc:call(N1,mnesia,transaction,[Read_one])),
+ %%Restart Mnesia on N2 and verify the contents there.
+ ?match([], mnesia_test_lib:start_mnesia([N2], [test_rec])),
+ ?match( {atomic,[#test_rec{key=2,val=33}]},
+ rpc:call(N2, mnesia, transaction, [Read_one] ) ),
+ %%Check that the start of Mnesai on N2 did not affect the contents on N1
+ ?match( {atomic,[#test_rec{key=2,val=33}]},
+ rpc:call(N1, mnesia, transaction, [Read_one] ) ),
+ ?verify_mnesia(Nodes, []).
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+load_directly_when_all_are_ram_copiesB(doc) ->
+ ["Tables that are RAM copies only shall be loaded from a replicat ",
+ "when possible. ",
+ "1. N1 and N2 has RAM copies of a table, stop N1 before N2.",
+ "2. Now start N2 first and then N1, N1 shall then load the table ",
+ " from N2."];
+load_directly_when_all_are_ram_copiesB(suite) -> [];
+load_directly_when_all_are_ram_copiesB(Config) when is_list(Config) ->
+ [N1, N2] = Nodes = ?acquire_nodes(2, Config),
+ ?match({atomic,ok},
+ mnesia:create_table(test_rec,
+ [{ram_copies,Nodes},
+ {attributes,record_info(fields,test_rec)}]
+ ) ),
+ ?match( Nodes, mnesia:table_info(test_rec,ram_copies) ),
+ ?match( [], mnesia:table_info(test_rec,disc_copies) ),
+ ?match( [], mnesia:table_info(test_rec,disc_only_copies) ),
+ Write_one = fun(Value) -> mnesia:write(#test_rec{key=3,val=Value}) end,
+ Read_one = fun() -> mnesia:read( {test_rec, 3}) end,
+ %%Write a value one N1 that we may test against later
+ ?match({atomic,ok},
+ rpc:call( N1, mnesia, transaction, [Write_one,[11]] ) ),
+ ?match({atomic,[#test_rec{key=3,val=11}]},
+ rpc:call(N2,mnesia,transaction,[Read_one]) ),
+ %%Stop Mnesia on N1
+ ?match([], mnesia_test_lib:kill_mnesia([N1])),
+ %%Write a value and check result (on N2; not possible on N1
+ %%since Mnesia is stopped there).
+ ?match({atomic,ok}, rpc:call(N2,mnesia,transaction,[Write_one,[22]]) ),
+ ?match({atomic,[#test_rec{key=3,val=22}]},
+ rpc:call(N2,mnesia,transaction,[Read_one]) ),
+ %%Stop Mnesia on N2
+ ?match([], mnesia_test_lib:kill_mnesia([N2])),
+ %%Restart Mnesia on N2 verify that we can access test_rec from
+ %%N2 without starting Mnesia on N1.
+ ?match(ok, rpc:call(N2, mnesia, start, [])),
+ ?match(ok, rpc:call(N2, mnesia, wait_for_tables, [[test_rec], 30000])),
+ ?match({atomic,[]}, rpc:call(N2,mnesia,transaction,[Read_one])),
+ ?match({atomic,ok}, rpc:call(N2,mnesia,transaction,[Write_one,[33]])),
+ ?match({atomic,[#test_rec{key=3,val=33}]},
+ rpc:call(N2,mnesia,transaction,[Read_one])),
+ %%Restart Mnesia on N1 and verify the contents there.
+ ?match([], mnesia_test_lib:start_mnesia([N1], [test_rec])),
+ ?match( {atomic,[#test_rec{key=3,val=33}]},
+ rpc:call(N1,mnesia,transaction,[Read_one])),
+ %%Check that the start of Mnesai on N1 did not affect the contents on N2
+ ?match( {atomic,[#test_rec{key=3,val=33}]},
+ rpc:call(N2,mnesia,transaction,[Read_one])),
+ ?verify_mnesia(Nodes, []).
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+late_load_when_all_are_ram_copies_on_ram_nodes(doc) ->
+ ["Load of ram_copies tables when all replicas resides on disc less nodes"];
+late_load_when_all_are_ram_copies_on_ram_nodes(suite) ->
+ [
+ late_load_when_all_are_ram_copies_on_ram_nodes1,
+ late_load_when_all_are_ram_copies_on_ram_nodes2
+ ].
+
+late_load_when_all_are_ram_copies_on_ram_nodes1(suite) -> [];
+late_load_when_all_are_ram_copies_on_ram_nodes1(Config) when is_list(Config) ->
+ [N1, N2] = mnesia_test_lib:prepare_test_case([{init_test_case, [mnesia]},
+ delete_schema,
+ {reload_appls, [mnesia]}],
+ 2, Config, ?FILE, ?LINE),
+ Res = late_load_when_all_are_ram_copies_on_ram_nodes(N1, [N2], Config),
+ mnesia_test_lib:prepare_test_case([{reload_appls, [mnesia]}],
+ 2, Config, ?FILE, ?LINE),
+ Res.
+
+late_load_when_all_are_ram_copies_on_ram_nodes2(suite) -> [];
+late_load_when_all_are_ram_copies_on_ram_nodes2(Config) when is_list(Config) ->
+ [N1, N2, N3] = mnesia_test_lib:prepare_test_case([{init_test_case, [mnesia]},
+ delete_schema,
+ {reload_appls, [mnesia]}],
+ 3, Config, ?FILE, ?LINE),
+ Res = late_load_when_all_are_ram_copies_on_ram_nodes(N1, [N2, N3], Config),
+ mnesia_test_lib:prepare_test_case([{reload_appls, [mnesia]}],
+ 3, Config, ?FILE, ?LINE),
+ Res.
+
+late_load_when_all_are_ram_copies_on_ram_nodes(DiscNode, RamNs, _Config)
+ when DiscNode == node() ->
+ ?match(ok, mnesia:create_schema([DiscNode])),
+ ?match(ok, mnesia:start()),
+ Nodes = [DiscNode | RamNs],
+ Extra = [{extra_db_nodes, Nodes}],
+ Ok = [ok || _ <- RamNs],
+ ?match({Ok, []}, rpc:multicall(RamNs, mnesia, start, [Extra])),
+ ?match([], wait_until_running(Nodes)),
+
+ LastRam = lists:last(RamNs),
+ %% ?match({atomic, ok},
+ %% mnesia:add_table_copy(schema, LastRam, ram_copies)),
+ Def = [{ram_copies, RamNs}, {attributes, record_info(fields, test_rec)}],
+ ?match({atomic,ok}, mnesia:create_table(test_rec, Def)),
+ ?verify_mnesia(Nodes, []),
+ ?match([], mnesia_test_lib:stop_mnesia(RamNs)),
+ ?match(stopped, mnesia:stop()),
+ ?match(ok, mnesia:start()),
+
+ Rec1 = #test_rec{key=3, val=33},
+ Rec2 = #test_rec{key=4, val=44},
+
+ FirstRam = hd(RamNs),
+ ?match(ok, rpc:call(FirstRam, mnesia, start, [Extra])),
+ ?match(ok, rpc:call(FirstRam, mnesia, wait_for_tables,
+ [[test_rec], 30000])),
+ ?match(ok, rpc:call(FirstRam, mnesia, dirty_write,[Rec1])),
+ ?match(ok, mnesia:wait_for_tables([test_rec], 30000)),
+ mnesia:dirty_write(Rec2),
+
+ if
+ FirstRam /= LastRam ->
+ ?match(ok, rpc:call(LastRam, mnesia, start, [Extra])),
+ ?match(ok, rpc:call(LastRam, mnesia, wait_for_tables,
+ [[test_rec], 30000]));
+ true ->
+ ignore
+ end,
+ ?match([Rec1], rpc:call(LastRam, mnesia, dirty_read, [{test_rec, 3}])),
+ ?match([Rec2], rpc:call(LastRam, mnesia, dirty_read, [{test_rec, 4}])),
+ ?verify_mnesia(Nodes, []).
+
+wait_until_running(Nodes) ->
+ wait_until_running(Nodes, 30).
+
+wait_until_running(Nodes, Times) when Times > 0->
+ Alive = mnesia:system_info(running_db_nodes),
+ case Nodes -- Alive of
+ [] ->
+ [];
+ Remaining ->
+ timer:sleep(timer:seconds(1)),
+ wait_until_running(Remaining, Times - 1)
+ end;
+wait_until_running(Nodes, _) ->
+ Nodes.
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+load_when_last_replica_becomes_available(doc) ->
+ ["Check that when all Mnesia nodes die at the same instant, then the ",
+ "replicated table shall be accessible when the last node is started ",
+ "again.",
+ "Checked by cheating. Start Mnesia on N1, N2, N3. Have a table ",
+ "replicated on disc on all three nodes, fill in some transactions, ",
+ "install a fallback. Restart mnesia on all nodes"
+ "This is the cheat and it simulates that all nodes died at the same ",
+ "time. Check that the table is only accessible after the last node ",
+ "has come up."];
+load_when_last_replica_becomes_available(suite) -> [];
+load_when_last_replica_becomes_available(Config) when is_list(Config) ->
+ [N1, N2, N3] = Nodes = ?acquire_nodes(3, Config),
+ ?match({atomic,ok},
+ mnesia:create_table(test_rec,
+ [{disc_copies,Nodes},
+ {attributes,record_info(fields,test_rec)}]
+ ) ),
+ ?match( [], mnesia:table_info(test_rec,ram_copies) ),
+ ?match( Nodes, mnesia:table_info(test_rec,disc_copies) ),
+ ?match( [], mnesia:table_info(test_rec,disc_only_copies) ),
+ Write_one = fun(Key,Val)->mnesia:write(#test_rec{key=Key,val=Val}) end,
+ Read_one = fun(Key) ->mnesia:read( {test_rec, Key}) end,
+ %%Write one value from each node.
+ ?match({atomic,ok},rpc:call(N1,mnesia,transaction,[Write_one,[1,11]])),
+ ?match({atomic,ok},rpc:call(N2,mnesia,transaction,[Write_one,[2,22]])),
+ ?match({atomic,ok},rpc:call(N3,mnesia,transaction,[Write_one,[3,33]])),
+ %%Check the values
+ ?match({atomic,[#test_rec{key=1,val=11}]},
+ rpc:call(N2,mnesia,transaction,[Read_one,[1]]) ),
+ ?match({atomic,[#test_rec{key=2,val=22}]},
+ rpc:call(N3,mnesia,transaction,[Read_one,[2]]) ),
+ ?match({atomic,[#test_rec{key=3,val=33}]},
+ rpc:call(N1,mnesia,transaction,[Read_one,[3]]) ),
+
+ ?match(ok, mnesia:backup("test_last_replica")),
+ ?match(ok, mnesia:install_fallback("test_last_replica")),
+ file:delete("test_last_replica"),
+ %%Stop Mnesia on all three nodes
+ ?match([], mnesia_test_lib:kill_mnesia(Nodes)),
+
+ %%Start Mnesia on one node, make sure that test_rec is not available
+ ?match(ok, rpc:call(N2, mnesia, start, [])),
+ ?match({timeout,[test_rec]},
+ rpc:call(N2, mnesia, wait_for_tables, [[test_rec], 10000])),
+ ?match(ok, rpc:call(N1, mnesia, start, [])),
+ ?match({timeout,[test_rec]},
+ rpc:call(N1, mnesia, wait_for_tables, [[test_rec], 10000])),
+ %%Start the third node
+ ?match(ok, rpc:call(N3, mnesia, start, [])),
+ %%Make sure that the table is loaded everywhere
+ ?match(ok, rpc:call(N3, mnesia, wait_for_tables, [[test_rec], 30000])),
+ ?match(ok, rpc:call(N2, mnesia, wait_for_tables, [[test_rec], 30000])),
+ ?match(ok, rpc:call(N1, mnesia, wait_for_tables, [[test_rec], 30000])),
+
+ %%Check the values
+ ?match({atomic,[#test_rec{key=1,val=11}]},
+ rpc:call(N2,mnesia,transaction,[Read_one,[1]]) ),
+ ?match({atomic,[#test_rec{key=2,val=22}]},
+ rpc:call(N3,mnesia,transaction,[Read_one,[2]]) ),
+ ?match({atomic,[#test_rec{key=3,val=33}]},
+ rpc:call(N1,mnesia,transaction,[Read_one,[3]]) ),
+ ?verify_mnesia(Nodes, []).
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+load_when_we_have_down_from_all_other_replica_nodes(doc) ->
+ ["The table can be loaded if this node was the last one surviving. ",
+ "Check this by having N1, N2, N3 and a table replicated on all those ",
+ "nodes. Then kill them in the N1, N2, N3 order. Then start N3 and ",
+ "verify that the table is available with correct contents."];
+load_when_we_have_down_from_all_other_replica_nodes(suite) -> [];
+load_when_we_have_down_from_all_other_replica_nodes(Config) when is_list(Config) ->
+ [N1, N2, N3] = Nodes = ?acquire_nodes(3, Config),
+ ?match({atomic,ok},
+ mnesia:create_table(test_rec,
+ [{disc_copies,Nodes},
+ {attributes,record_info(fields,test_rec)}]
+ ) ),
+ ?match( [], mnesia:table_info(test_rec,ram_copies) ),
+ ?match( Nodes, mnesia:table_info(test_rec,disc_copies) ),
+ ?match( [], mnesia:table_info(test_rec,disc_only_copies) ),
+ Write_one = fun(Key,Val)->mnesia:write(#test_rec{key=Key,val=Val}) end,
+ Read_one = fun(Key) ->mnesia:read( {test_rec, Key}) end,
+ %%Write one value from each node.
+ ?match({atomic,ok},rpc:call(N1,mnesia,transaction,[Write_one,[1,111]])),
+ ?match({atomic,ok},rpc:call(N2,mnesia,transaction,[Write_one,[2,222]])),
+ ?match({atomic,ok},rpc:call(N3,mnesia,transaction,[Write_one,[3,333]])),
+ %%Check the values
+ ?match({atomic,[#test_rec{key=1,val=111}]},
+ rpc:call(N2,mnesia,transaction,[Read_one,[1]]) ),
+ ?match({atomic,[#test_rec{key=2,val=222}]},
+ rpc:call(N3,mnesia,transaction,[Read_one,[2]]) ),
+ ?match({atomic,[#test_rec{key=3,val=333}]},
+ rpc:call(N1,mnesia,transaction,[Read_one,[3]]) ),
+ %%Stop Mnesia on all three nodes
+ ?match([], mnesia_test_lib:kill_mnesia([N1])),
+ ?match({atomic,ok},rpc:call(N2,mnesia,transaction,[Write_one,[22,22]])),
+ ?match([], mnesia_test_lib:kill_mnesia([N2])),
+ ?match({atomic,ok},rpc:call(N3,mnesia,transaction,[Write_one,[33,33]])),
+ ?match([], mnesia_test_lib:kill_mnesia([N3])),
+ ?verbose("Mnesia stoped on all three nodes.~n",[]),
+
+ %%Start Mnesia on N3; wait for 'test_rec' table to load
+ ?match(ok, rpc:call(N3, mnesia, start, [])),
+ ?match(ok, rpc:call(N3, mnesia, wait_for_tables, [[test_rec], 30000])),
+
+ %%Check the values
+ ?match({atomic,[#test_rec{key=1,val=111}]},
+ rpc:call(N3,mnesia,transaction,[Read_one,[1]]) ),
+ ?match({atomic,[#test_rec{key=2,val=222}]},
+ rpc:call(N3,mnesia,transaction,[Read_one,[2]]) ),
+ ?match({atomic,[#test_rec{key=3,val=333}]},
+ rpc:call(N3,mnesia,transaction,[Read_one,[3]]) ),
+ ?match({atomic,[#test_rec{key=22,val=22}]},
+ rpc:call(N3,mnesia,transaction,[Read_one,[22]]) ),
+ ?match({atomic,[#test_rec{key=33,val=33}]},
+ rpc:call(N3,mnesia,transaction,[Read_one,[33]]) ),
+ ?verify_mnesia([N3], [N1, N2]).
+
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+late_load_transforms_into_disc_load(doc) ->
+ ["Difficult case that needs instrumentation of Mnesia.",
+ "A table is force loaded, and Mnesia decides to load it from another ",
+ "Mnesia node because it is avaliable there. The other Mnesia node then ",
+ "dies in mid copy which shall make the first Mnesia node to really ",
+ "force load from disc.",
+ "Check this by starting N1 and N2 and replicating a table between ",
+ "them. Then kill N1 before N2. The idea is to start N2 first, then ",
+ "N1 and then do a force load on N1. This force load will load from ",
+ "N2 BUT N2 must be killed after the decision to load from it has ",
+ "been made. tricky."];
+
+late_load_transforms_into_disc_load(suite) -> [];
+late_load_transforms_into_disc_load(Config) when is_list(Config) ->
+ ?is_debug_compiled,
+
+ [Node1, Node2] = Nodes = ?acquire_nodes(2, Config),
+
+ {success, [A, B]} = ?start_activities(Nodes),
+
+ ?match(Node1, node(A)),
+ ?match(Node2, node(B)),
+
+ Tab = late_load_table,
+ Def = [{attributes, [key, value]},
+ {disc_copies, Nodes}],
+ ?match({atomic, ok}, mnesia:create_table(Tab, Def)),
+ ?match(ok, mnesia:dirty_write({Tab, 111, 4711})),
+ ?match(ok, mnesia:dirty_write({Tab, 222, 42})),
+
+ TestPid = self(),
+ DebugId = {mnesia_loader, do_get_network_copy},
+ DebugFun = fun(PrevContext, EvalContext) ->
+ ?verbose("interrupt late load, pid ~p #~p ~n context ~p ~n",
+ [self(),PrevContext,EvalContext]),
+
+ mnesia_test_lib:kill_mnesia([Node2]),
+ TestPid ! {self(),debug_fun_was_called},
+
+ ?verbose("interrupt late_log - continues ~n",[]),
+ ?deactivate_debug_fun(DebugId),
+ PrevContext+1
+ end,
+ ?remote_activate_debug_fun(Node1,DebugId, DebugFun, 1),
+
+ %% kill mnesia on node1
+ mnesia_test_lib:kill_mnesia([Node1]),
+ %% wait a while, so that mnesia is really down
+ timer:sleep(timer:seconds(1)),
+
+ ?match(ok, rpc:call(Node2, mnesia, dirty_write, [{Tab, 222, 815}])),
+
+ %% start Mnesia on node1
+ ?match(ok,mnesia:start()),
+ ?match(yes, mnesia:force_load_table(Tab)),
+ ?match(ok, mnesia:wait_for_tables([Tab],timer:seconds(30))),
+
+ receive_messages([debug_fun_was_called]),
+
+ check_tables([A],[{Tab,111},{Tab,222}],[[{Tab,111,4711}],[{Tab,222,42}]]),
+ ?verify_mnesia([Node1], [Node2]).
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+late_load_leads_to_hanging(doc) ->
+ ["Difficult case that needs instrumentation of Mnesia.",
+ "A table is loaded, and Mnesia decides to load it from another ",
+ "Mnesia node because it has the latest copy there. ",
+ "The other Mnesia node then ",
+ "dies in mid copy which shall make the first Mnesia node not to ",
+ "force load from disc but to wait for the other node to come up again",
+ "Check this by starting N1 and N2 and replicating a table between ",
+ "them. Then kill N1 before N2. The idea is to start N2 first, then ",
+ "N1. This load will load from ",
+ "N2 BUT N2 must be killed after the decision to load from it has ",
+ "been made. tricky."];
+
+late_load_leads_to_hanging(suite) -> [];
+late_load_leads_to_hanging(Config) when is_list(Config) ->
+ ?is_debug_compiled,
+
+ [Node1, Node2] = Nodes = ?acquire_nodes(2, Config),
+
+ Tab = late_load_table,
+ Def = [{attributes, [key, value]},
+ {disc_copies, Nodes}],
+
+ ?match({atomic, ok}, mnesia:create_table(Tab, Def)),
+ ?match(ok, mnesia:dirty_write({Tab, 111, 4711})),
+ ?match(ok, mnesia:dirty_write({Tab, 222, 42})),
+
+ DebugId = {mnesia_loader, do_get_network_copy},
+ DebugFun = fun(PrevContext, EvalContext) ->
+ ?verbose("interrupt late load, pid ~p #~p ~n context ~p ~n",
+ [self(), PrevContext, EvalContext]),
+ mnesia_test_lib:kill_mnesia([Node2]),
+ ?verbose("interrupt late load - continues ~n",[]),
+ ?deactivate_debug_fun(DebugId),
+ PrevContext+1
+ end,
+
+ ?remote_activate_debug_fun(Node1,DebugId, DebugFun, 1),
+ mnesia_test_lib:kill_mnesia([Node1]),
+ %% wait a while, so that mnesia is really down
+ timer:sleep(timer:seconds(1)),
+
+ ?match(ok, rpc:call(Node2, mnesia, dirty_write, [{Tab, 333, 666}])),
+
+ %% start Mnesia on node1
+ ?match(ok, mnesia:start()),
+
+ ?match({timeout, [Tab]}, mnesia:wait_for_tables([Tab], timer:seconds(2))),
+
+ ?match({'EXIT', {aborted, _}}, mnesia:dirty_read({Tab, 222})),
+ %% mnesia on node1 is waiting for node2 coming up
+
+ ?match(ok, rpc:call(Node2, mnesia, start, [])),
+ ?match(ok, mnesia:wait_for_tables([Tab], timer:seconds(30))),
+ ?match([{Tab, 333, 666}], mnesia:dirty_read({Tab, 333})),
+ ?verify_mnesia([Node2, Node1], []).
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+force_load_when_nobody_intents_to_load(doc) ->
+ ["Normal force load. Start N1 N2, kill in N1, N2 order. Start N1 do ",
+ "force load. Did it work?"];
+force_load_when_nobody_intents_to_load(suite) -> [];
+force_load_when_nobody_intents_to_load(Config) when is_list(Config) ->
+ [N1, N2] = Nodes = ?acquire_nodes(2, Config),
+ Table = test_rec,
+ Trec1a = #test_rec{key=1,val=111},
+ Trec1b = #test_rec{key=1,val=333},
+ Trec2a = #test_rec{key=2,val=222},
+ Trec3a = #test_rec{key=3,val=333},
+ Trec3b = #test_rec{key=3,val=666},
+
+ ?match({atomic,ok}, rpc:call(N1, mnesia,create_table,
+ [Table,
+ [{disc_copies,Nodes},
+ {attributes,record_info(fields,test_rec)}
+ ] ] ) ),
+ ?match( [], mnesia:table_info(Table,ram_copies) ),
+ ?match( Nodes, mnesia:table_info(Table,disc_copies) ),
+ ?match( [], mnesia:table_info(Table,disc_only_copies) ),
+ Write_one = fun(Rec) -> mnesia:write(Rec) end,
+ Read_one = fun(Key) -> mnesia:read({Table, Key}) end,
+ %%Write one value
+ ?match({atomic,ok},rpc:call(N1,mnesia,transaction,[Write_one,[Trec1a]])),
+ %%Check it
+ ?match({atomic,[Trec1a]},rpc:call(N2,mnesia,transaction,[Read_one,[1]]) ),
+ %%Shut down mnesia on N1
+ ?match([], mnesia_test_lib:stop_mnesia([N1])),
+ %%Write and check value while N1 is down
+ ?match({atomic,ok},rpc:call(N2,mnesia,transaction,[Write_one,[Trec1b]])),
+ ?match({atomic,ok},rpc:call(N2,mnesia,transaction,[Write_one,[Trec2a]])),
+ ?match({atomic,ok},rpc:call(N2,mnesia,transaction,[Write_one,[Trec3a]])),
+ ?match({aborted,{node_not_running,N1}},
+ rpc:call(N1,mnesia,transaction,[Read_one,[2]]) ),
+ ?match({atomic,[Trec1b]},rpc:call(N2,mnesia,transaction,[Read_one,[1]]) ),
+ ?match({atomic,[Trec2a]},rpc:call(N2,mnesia,transaction,[Read_one,[2]]) ),
+ ?match({atomic,[Trec3a]},rpc:call(N2,mnesia,transaction,[Read_one,[3]]) ),
+ %%Shut down Mnesia on N2
+ ?match([], mnesia_test_lib:stop_mnesia([N2])),
+
+ %%Restart Mnesia on N1
+ ?match(ok, rpc:call(N1, mnesia, start, [])),
+ %%Check that table is not available (waiting for N2)
+ ?match({timeout,[Table]},
+ rpc:call(N1, mnesia, wait_for_tables, [[Table], 3000])),
+
+ %%Force load on N1
+ ?match(yes,rpc:call(N1,mnesia,force_load_table,[Table])),
+ %%Check values
+ ?match({atomic,[Trec1a]},rpc:call(N1,mnesia,transaction,[Read_one,[1]]) ),
+ ?match({atomic,[]}, rpc:call(N1,mnesia,transaction,[Read_one,[2]]) ),
+ ?match({atomic,[]}, rpc:call(N1,mnesia,transaction,[Read_one,[3]]) ),
+ %%Write a value for key=3
+ ?match({atomic,ok},rpc:call(N1,mnesia,transaction,[Write_one,[Trec3b]])),
+
+ %%Restart N2 and check values
+ ?match(ok, rpc:call(N2, mnesia, start, [])),
+ ?match(ok, rpc:call(N2, mnesia, wait_for_tables, [[Table], 30000])),
+
+ ?match({atomic,[Trec1a]},rpc:call(N1,mnesia,transaction,[Read_one,[1]]) ),
+ ?match({atomic,[Trec1a]},rpc:call(N2,mnesia,transaction,[Read_one,[1]]) ),
+
+ ?match({atomic,[]},rpc:call(N1,mnesia,transaction,[Read_one,[2]]) ),
+ ?match({atomic,[]},rpc:call(N2,mnesia,transaction,[Read_one,[2]]) ),
+
+ ?match({atomic,[Trec3b]},rpc:call(N1,mnesia,transaction,[Read_one,[3]]) ),
+ ?match({atomic,[Trec3b]},rpc:call(N2,mnesia,transaction,[Read_one,[3]]) ),
+ ?verify_mnesia(Nodes, []).
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+force_load_when_someone_has_decided_to_load(doc) ->
+ ["Difficult case that needs instrumentation of Mnesia.",
+ "Start N1 and N2, replicate table, kill in N1, N2 order. Start N2 ",
+ "and start N1 before N2 has really loaded the table but after N2 has ",
+ "decided to load it."];
+
+force_load_when_someone_has_decided_to_load(suite) -> [];
+force_load_when_someone_has_decided_to_load(Config) when is_list(Config) ->
+ ?is_debug_compiled,
+
+ [Node1, Node2] = Nodes = ?acquire_nodes(2, Config),
+ {success, [A, B]} = ?start_activities(Nodes),
+ ?match(Node1, node(A)), %% Just to check :)
+ ?match(Node2, node(B)),
+
+ Tab = late_load_table,
+ Def = [{attributes, [key, value]}, {disc_copies, Nodes}],
+
+ ?match({atomic, ok}, mnesia:create_table(Tab, Def)),
+ ?match(ok, mnesia:dirty_write({Tab, 111, 4711})),
+ ?match(ok, mnesia:dirty_write({Tab, 222, 42})),
+
+ Self = self(),
+ DebugId = {mnesia_controller, late_disc_load},
+ DebugFun = fun(PrevContext, EvalContext) ->
+ ?verbose("interrupt late disc load,
+ pid ~p #~p ~n context ~p ~n",
+ [self(),PrevContext,EvalContext]),
+ Self ! {self(), fun_in_postion},
+ wait_for_signal(),
+ ?verbose("interrupt late disc load - continues ~n",[]),
+ ?deactivate_debug_fun(DebugId),
+ PrevContext+1
+ end,
+
+ %% kill mnesia on node1
+ mnesia_test_lib:kill_mnesia([Node1]),
+ %% wait a while, so that mnesia is really down
+ timer:sleep(timer:seconds(1)),
+
+ ?match(ok, rpc:call(Node2, mnesia, dirty_write, [{Tab, 222, 815}])),
+ %% kill mnesia on node2
+ mnesia_test_lib:kill_mnesia([Node2]),
+ %% wait a while, so that mnesia is really down
+ timer:sleep(timer:seconds(1)),
+
+ ?remote_activate_debug_fun(Node2,DebugId, DebugFun, 1),
+
+ B ! fun() -> mnesia:start() end,
+ [{Mnesia_Pid, fun_in_postion}] = receive_messages([fun_in_postion]),
+
+ %% start Mnesia on node1
+ A ! fun() -> mnesia:start() end,
+ ?match_receive(timeout),
+% Got some problem with this testcase when we modified mnesia init
+% These test cases are very implementation dependent!
+% A ! fun() -> mnesia:wait_for_tables([Tab], 3000) end,
+% ?match_receive({A, {timeout, [Tab]}}),
+ A ! fun() -> mnesia:force_load_table(Tab) end,
+ ?match_receive(timeout),
+
+ Mnesia_Pid ! continue,
+ ?match_receive({B, ok}),
+ ?match_receive({A, ok}),
+ ?match_receive({A, yes}),
+
+ B ! fun() -> mnesia:wait_for_tables([Tab], 10000) end,
+ ?match_receive({B, ok}),
+ ?match(ok, mnesia:wait_for_tables([Tab], timer:seconds(30))),
+ ?match([{Tab, 222, 815}], mnesia:dirty_read({Tab, 222})),
+ ?verify_mnesia(Nodes, []).
+
+wait_for_signal() ->
+ receive
+ continue -> ok
+ %% Don't eat any other mnesia internal msg's
+ after
+ timer:minutes(2) -> ?error("Timedout in wait_for_signal~n", [])
+ end.
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+force_load_when_someone_else_already_has_loaded(doc) ->
+ ["Normal case. Do a force load when somebody else has loaded the table. ",
+ "Start N1, N2, kill in N1, N2 order. Start N2 load the table, start N1 ",
+ "force load. Did it work? (i.e: did N1 load the table from N2 as that",
+ "one is the latest version and it is available on N2)"];
+
+force_load_when_someone_else_already_has_loaded(suite) -> [];
+force_load_when_someone_else_already_has_loaded(Config) when is_list(Config) ->
+ [N1, N2] = Nodes = ?acquire_nodes(2, Config),
+ Table = test_rec,
+ Trec1 = #test_rec{key=1,val=111},
+ Trec2 = #test_rec{key=1,val=222},
+
+ ?match({atomic,ok}, rpc:call(N1, mnesia,create_table,
+ [Table,
+ [{disc_copies,Nodes},
+ {attributes,record_info(fields,test_rec)}
+ ] ] ) ),
+ ?match( [], mnesia:table_info(Table,ram_copies) ),
+ ?match( Nodes, mnesia:table_info(Table,disc_copies) ),
+ ?match( [], mnesia:table_info(Table,disc_only_copies) ),
+ Write_one = fun(Rec) -> mnesia:write(Rec) end,
+ Read_one = fun(Key) -> mnesia:read({Table, Key}) end,
+ %%Write one value
+ ?match({atomic,ok},rpc:call(N1,mnesia,transaction,[Write_one,[Trec1]])),
+ %%Check it
+ ?match({atomic,[Trec1]},rpc:call(N2,mnesia,transaction,[Read_one,[1]]) ),
+ %%Shut down mnesia
+ ?match([], mnesia_test_lib:stop_mnesia([N1])),
+ timer:sleep(500),
+ ?match([], mnesia_test_lib:stop_mnesia([N2])),
+ %%Restart Mnesia on N2;wait for tables to load
+ ?match(ok, rpc:call(N2, mnesia, start, [])),
+ ?match(ok, rpc:call(N2, mnesia, wait_for_tables, [[test_rec], 30000])),
+ %%Write one value
+ ?match({atomic,ok},rpc:call(N2,mnesia,transaction,[Write_one,[Trec2]])),
+ %%Start on N1; force load
+ ?match(ok, rpc:call(N1, mnesia, start, [])),
+ %%Force load from file
+ ?match(yes, rpc:call(N1,mnesia,force_load_table,[Table])),
+ %%Check the value
+ ?match({atomic,[Trec2]},rpc:call(N1,mnesia,transaction,[Read_one,[1]]) ),
+ %% === there must be a Trec2 here !!!!
+ ?verify_mnesia(Nodes, []).
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+force_load_when_we_has_loaded(doc) ->
+ ["Force load a table we already have loaded"];
+force_load_when_we_has_loaded(suite) -> [];
+force_load_when_we_has_loaded(Config) when is_list(Config) ->
+ [N1] = Nodes = ?acquire_nodes(1, Config),
+ Table = test_rec,
+ Trec1 = #test_rec{key=1,val=111},
+ Trec2 = #test_rec{key=1,val=222},
+
+ ?match({atomic,ok}, rpc:call(N1, mnesia,create_table,
+ [Table,
+ [{disc_copies,Nodes},
+ {attributes,record_info(fields,test_rec)}
+ ] ] ) ),
+ ?match( [], mnesia:table_info(Table,ram_copies) ),
+ ?match( Nodes, mnesia:table_info(Table,disc_copies) ),
+ ?match( [], mnesia:table_info(Table,disc_only_copies) ),
+ Write_one = fun(Rec) -> mnesia:write(Rec) end,
+ Read_one = fun(Key) -> mnesia:read({Table, Key}) end,
+ %%Write one value
+ ?match({atomic,ok},rpc:call(N1,mnesia,transaction,[Write_one,[Trec1]])),
+ %%Check it
+ ?match({atomic,[Trec1]},rpc:call(N1,mnesia,transaction,[Read_one,[1]]) ),
+ %%Shut down mnesia
+ ?match([], mnesia_test_lib:stop_mnesia(Nodes)),
+ %%Restart Mnesia;wait for tables to load
+ ?match([], mnesia_test_lib:start_mnesia(Nodes, [Table])),
+ %%Write one value
+ ?match({atomic,ok},rpc:call(N1,mnesia,transaction,[Write_one,[Trec2]])),
+ %%Force load from file
+ ?match(yes, rpc:call(N1,mnesia,force_load_table,[Table])),
+ %%Check the value
+ ?match({atomic,[Trec2]},rpc:call(N1,mnesia,transaction,[Read_one,[1]]) ),
+ ?verify_mnesia(Nodes, []).
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+force_load_on_a_non_local_table(doc) ->
+ ["This is NOT allowed, the test case is a negative test",
+ "Force load on a table that isn't replicated on this node."];
+force_load_on_a_non_local_table(suite) -> [];
+force_load_on_a_non_local_table(Config) when is_list(Config) ->
+ [N1, N2, N3] = Nodes = ?acquire_nodes( 3, Config),
+ TableNodes = lists:sublist(Nodes,2),
+ Table = test_rec,
+ Trec1 = #test_rec{key=1,val=11},
+
+ ?match({atomic,ok}, rpc:call(N1, mnesia,create_table,
+ [Table,
+ [{disc_copies,TableNodes},
+ {attributes,record_info(fields,test_rec)}
+ ] ] ) ),
+ ?match( [], mnesia:table_info(Table,ram_copies) ),
+ ?match( TableNodes, mnesia:table_info(Table,disc_copies) ),
+ ?match( [], mnesia:table_info(Table,disc_only_copies) ),
+ Write_one = fun(Rec) -> mnesia:write(Rec) end,
+ Read_one = fun(Key) -> mnesia:read({Table, Key}) end,
+ %%Write one value
+ ?match({atomic,ok},rpc:call(N1,mnesia,transaction,[Write_one,[Trec1]])),
+ %%Check it from the other nodes
+ ?match({atomic,[Trec1]},rpc:call(N2,mnesia,transaction,[Read_one,[1]]) ),
+ ?match({atomic,[Trec1]},rpc:call(N3,mnesia,transaction,[Read_one,[1]]) ),
+
+ %%Make sure that Table is non-local
+ ?match_inverse(N3, rpc:call(N3,mnesia,table_info,[Table,where_to_read])),
+ %%Try to force load it
+ ?match(yes, rpc:call(N3,mnesia,force_load_table,[Table])),
+ ?verify_mnesia(Nodes, []).
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+force_load_when_the_table_does_not_exist(doc) ->
+ ["This is NOT allowed, the test case is a negative test",
+ "Force load on a table that doesn't exist."];
+force_load_when_the_table_does_not_exist(suite) -> [];
+force_load_when_the_table_does_not_exist(Config) when is_list(Config) ->
+ Nodes = ?acquire_nodes( 2, Config),
+
+ %%Dummy table
+ ?match({atomic,ok},
+ mnesia:create_table(test_rec,
+ [{disc_copies,Nodes},
+ {attributes,record_info(fields,test_rec)}]
+ ) ),
+ ?match( [], mnesia:table_info(test_rec,ram_copies) ),
+ ?match( Nodes, mnesia:table_info(test_rec,disc_copies) ),
+ ?match( [], mnesia:table_info(test_rec,disc_only_copies) ),
+ Tab = dummy,
+ %%Make sure that Tab is an unknown table
+ ?match( false, lists:member(Tab,mnesia:system_info(tables)) ),
+ ?match( {error, {no_exists, Tab}}, mnesia:force_load_table(Tab) ),
+ ?verify_mnesia(Nodes, []).
+
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+load_tables_with_master_tables(doc) ->
+ ["Verifies the semantics of different master nodes settings",
+ "The semantics should be:",
+ "1. Mnesia downs, Normally decides from where mnesia should load tables",
+ "2. Master tables (overrides mnesia downs) ",
+ "3. Force load (overrides Master tables) ",
+ "--- 1st from active master nodes",
+ "--- 2nd from active nodes",
+ "--- 3rd get local copy (if ram create new one)"
+ ];
+
+load_tables_with_master_tables(suite) ->
+ [master_nodes,
+ starting_master_nodes,
+ master_on_non_local_tables,
+ remote_force_load_with_local_master_node].
+
+
+-define(SDwrite(Tup), fun() -> mnesia:write(Tup) end).
+
+master_nodes(suite) -> [];
+master_nodes(Config) when is_list(Config) ->
+ [A, B, C] = Nodes = ?acquire_nodes(3, Config),
+ Tab = test_table_master_nodes,
+ ?match({atomic,ok}, mnesia:create_table(Tab, [{disc_copies, Nodes}])),
+
+ %% Test one: Master A and the table should be loaded from A
+
+ ?match(ok, rpc:call(A, mnesia, set_master_nodes, [Tab, [A]])),
+ ?match({atomic, ok}, mnesia:sync_transaction(?SDwrite({Tab, 1, init}))),
+
+ mnesia_test_lib:stop_mnesia([A]),
+ ?match({atomic, ok}, rpc:call(B, mnesia, sync_transaction, [?SDwrite({Tab, 1, updated})])),
+ ?match(ok, rpc:call(A, mnesia, start, [])),
+ ?match(ok, rpc:call(A, mnesia, wait_for_tables, [[Tab], 3000])),
+
+ ?match([{Tab, 1, init}], rpc:call(A, mnesia, dirty_read, [{Tab, 1}])),
+ ?match([{Tab, 1, updated}], rpc:call(B, mnesia, dirty_read, [{Tab, 1}])),
+ ?match([{Tab, 1, updated}], rpc:call(C, mnesia, dirty_read, [{Tab, 1}])),
+
+ %% Test 2: Master [A,B] and B is Up the table should be loaded from B
+
+ ?match(ok, rpc:call(A, mnesia, set_master_nodes, [Tab, [A, B]])),
+ ?match({atomic, ok}, mnesia:sync_transaction(?SDwrite({Tab, 1, init}))),
+
+ mnesia_test_lib:stop_mnesia([A]),
+ ?match({atomic, ok}, rpc:call(B, mnesia, sync_transaction, [?SDwrite({Tab, 1, updated})])),
+ ?match(ok, rpc:call(A, mnesia, start, [])),
+ ?match(ok, rpc:call(A, mnesia, wait_for_tables, [[Tab], 3000])),
+
+ ?match([{Tab, 1, updated}], rpc:call(A, mnesia, dirty_read, [{Tab, 1}])),
+ ?match([{Tab, 1, updated}], rpc:call(B, mnesia, dirty_read, [{Tab, 1}])),
+ ?match([{Tab, 1, updated}], rpc:call(C, mnesia, dirty_read, [{Tab, 1}])),
+
+ %% Test 3: Master [A,B] and B is down the table should be loaded from A
+
+ ?match(ok, rpc:call(A, mnesia, set_master_nodes, [Tab, [A, B]])),
+ ?match({atomic, ok}, mnesia:sync_transaction(?SDwrite({Tab, 1, init}))),
+
+ mnesia_test_lib:stop_mnesia([A]),
+ ?match({atomic, ok}, rpc:call(B, mnesia, sync_transaction, [?SDwrite({Tab, 1, updated})])),
+ mnesia_test_lib:stop_mnesia([B]),
+ ?match(ok, rpc:call(A, mnesia, start, [])),
+ ?match(ok, rpc:call(A, mnesia, wait_for_tables, [[Tab], 3000])),
+
+ ?match(ok, rpc:call(B, mnesia, start, [])),
+ ?match(ok, rpc:call(B, mnesia, wait_for_tables, [[Tab], 3000])),
+
+ ?match([{Tab, 1, init}], rpc:call(A, mnesia, dirty_read, [{Tab, 1}])),
+ ?match([{Tab, 1, _Unknown}], rpc:call(B, mnesia, dirty_read, [{Tab, 1}])),
+ ?match([{Tab, 1, updated}], rpc:call(C, mnesia, dirty_read, [{Tab, 1}])),
+
+ %% Test 4: Master [B] and B is Up the table should be loaded from B
+
+ ?match(ok, rpc:call(A, mnesia, set_master_nodes, [Tab, [B]])),
+ ?match({atomic, ok}, mnesia:sync_transaction(?SDwrite({Tab, 1, init}))),
+
+ mnesia_test_lib:stop_mnesia([A]),
+ ?match({atomic, ok}, rpc:call(B, mnesia, sync_transaction, [?SDwrite({Tab, 1, updated})])),
+ ?match(ok, rpc:call(A, mnesia, start, [])),
+ ?match(ok, rpc:call(A, mnesia, wait_for_tables, [[Tab], 3000])),
+
+ ?match([{Tab, 1, updated}], rpc:call(A, mnesia, dirty_read, [{Tab, 1}])),
+ ?match([{Tab, 1, updated}], rpc:call(B, mnesia, dirty_read, [{Tab, 1}])),
+ ?match([{Tab, 1, updated}], rpc:call(C, mnesia, dirty_read, [{Tab, 1}])),
+
+ %% Test 5: Master [B] and B is down the table should not be loaded
+
+ ?match(ok, rpc:call(A, mnesia, set_master_nodes, [Tab, [B]])),
+ ?match({atomic, ok}, mnesia:sync_transaction(?SDwrite({Tab, 1, init}))),
+
+ mnesia_test_lib:stop_mnesia([A]),
+ ?match({atomic, ok}, rpc:call(B, mnesia, sync_transaction, [?SDwrite({Tab, 1, updated})])),
+ mnesia_test_lib:stop_mnesia([B]),
+ ?match({atomic, ok}, rpc:call(C, mnesia, sync_transaction, [?SDwrite({Tab, 1, update_2})])),
+ ?match(ok, rpc:call(A, mnesia, start, [])),
+ ?match({timeout, [Tab]}, rpc:call(A, mnesia, wait_for_tables, [[Tab], 2000])),
+
+ %% Test 6: Force load on table that couldn't be loaded due to master
+ %% table setttings, loads other active replicas i.e. from C
+
+ ?match(yes, rpc:call(A, mnesia, force_load_table, [Tab])),
+ ?match(ok, rpc:call(A, mnesia, wait_for_tables, [[Tab], 3000])),
+
+ ?match(ok, rpc:call(B, mnesia, start, [])),
+ ?match(ok, rpc:call(B, mnesia, wait_for_tables, [[Tab], 3000])),
+
+ ?match([{Tab, 1, update_2}], rpc:call(A, mnesia, dirty_read, [{Tab, 1}])),
+ ?match([{Tab, 1, update_2}], rpc:call(B, mnesia, dirty_read, [{Tab, 1}])),
+ ?match([{Tab, 1, update_2}], rpc:call(C, mnesia, dirty_read, [{Tab, 1}])),
+
+ %% Test 7: Master [B] and B is down the table should not be loaded,
+ %% force_load when there are no active replicas availible
+ %% should generate a load of a local table
+
+ ?match(ok, rpc:call(A, mnesia, set_master_nodes, [Tab, [B]])),
+ ?match({atomic, ok}, mnesia:sync_transaction(?SDwrite({Tab, 1, init}))),
+
+ mnesia_test_lib:stop_mnesia([A]),
+ ?match({atomic, ok}, rpc:call(B, mnesia, sync_transaction, [?SDwrite({Tab, 1, updated})])),
+ mnesia_test_lib:stop_mnesia([B, C]),
+ ?match(ok, rpc:call(A, mnesia, start, [])),
+ ?match({timeout, [Tab]}, rpc:call(A, mnesia, wait_for_tables, [[Tab], 2000])),
+
+ ?match(yes, rpc:call(A, mnesia, force_load_table, [Tab])),
+ ?match([{Tab, 1, init}], rpc:call(A, mnesia, dirty_read, [{Tab, 1}])),
+
+ ?verify_mnesia([A], [B,C]).
+
+starting_master_nodes(suite) -> [];
+starting_master_nodes(doc) ->
+ ["Complementory to TEST 5 and 6 above, if the master node (B) starts"
+ " and loads the table it should be loaded on the waiting node (A) "];
+starting_master_nodes(Config) when is_list(Config) ->
+ [A, B, C] = Nodes = ?acquire_nodes(3, Config),
+ Tab = starting_master_nodes,
+ ?match({atomic,ok}, mnesia:create_table(Tab, [{disc_copies, Nodes}])),
+ %% Start by checking TEST 5 above.
+
+ ?match(ok, rpc:call(A, mnesia, set_master_nodes, [Tab, [B]])),
+ ?match({atomic, ok}, mnesia:sync_transaction(?SDwrite({Tab, 1, init}))),
+ mnesia_test_lib:stop_mnesia([A]),
+ ?match({atomic, ok}, rpc:call(B, mnesia, sync_transaction, [?SDwrite({Tab, 1, updated})])),
+ mnesia_test_lib:stop_mnesia([B]),
+ ?match({atomic, ok}, rpc:call(C, mnesia, sync_transaction, [?SDwrite({Tab, 1, update_2})])),
+
+ ?match(ok, rpc:call(A, mnesia, start, [])),
+ ?match({timeout, [Tab]}, rpc:call(A, mnesia, wait_for_tables, [[Tab], 2000])),
+ %% Start the B node and the table should be loaded on A!
+ ?match(ok, rpc:call(B, mnesia, start, [])),
+ ?match(ok, rpc:call(B, mnesia, wait_for_tables, [[Tab], 3000])),
+ ?match(ok, rpc:call(A, mnesia, wait_for_tables, [[Tab], 3000])),
+
+ ?verify_mnesia([A,B,C], []).
+
+
+master_on_non_local_tables(suite) -> [];
+master_on_non_local_tables(Config) when is_list(Config) ->
+ [A, B, C] = Nodes = ?acquire_nodes(3, Config),
+ Tab = test_table_non_local,
+ ?match({atomic,ok}, mnesia:create_table(Tab, [{disc_copies, [B, C]}])),
+
+ ?match(ok, rpc:call(A, mnesia, set_master_nodes, [Tab, [B]])),
+ ?match({atomic, ok}, mnesia:sync_transaction(?SDwrite({Tab, 1, init}))),
+
+ %% Test 1: Test that table info are updated when master node comes up
+
+ mnesia_test_lib:stop_mnesia([A, B]),
+ ?match({atomic, ok}, rpc:call(C, mnesia, sync_transaction, [?SDwrite({Tab, 1, updated})])),
+ ?match(ok, rpc:call(A, mnesia, start, [])),
+
+ ?match({timeout, [Tab]}, rpc:call(A, mnesia, wait_for_tables, [[Tab], 2000])),
+ ErrorRead = {badrpc,{'EXIT', {aborted,{no_exists,[test_table_non_local,1]}}}},
+ ErrorWrite = {badrpc,{'EXIT', {aborted,{no_exists,test_table_non_local}}}},
+ ?match(ErrorRead, rpc:call(A, mnesia, dirty_read, [{Tab, 1}])),
+ ?match(ErrorWrite, rpc:call(A, mnesia, dirty_write, [{Tab, 1, updated_twice}])),
+
+ ?match(ok, rpc:call(B, mnesia, start, [])),
+ ?match(ok, rpc:call(A, mnesia, wait_for_tables, [[Tab], 2000])),
+
+ ?match([{Tab, 1, updated}], rpc:call(A, mnesia, dirty_read, [{Tab, 1}])),
+ ?match(B, rpc:call(A, mnesia, table_info, [Tab, where_to_read])),
+ ?match({atomic, ok}, rpc:call(A, mnesia, sync_transaction, [?SDwrite({Tab, 1, init})])),
+
+ %% Test 2: Test that table info are updated after force_load
+
+ mnesia_test_lib:stop_mnesia([A, B]),
+ ?match({atomic, ok}, rpc:call(C, mnesia, sync_transaction, [?SDwrite({Tab, 1, updated})])),
+ ?match(ok, rpc:call(A, mnesia, start, [])),
+
+ ?match({timeout, [Tab]}, rpc:call(A, mnesia, wait_for_tables, [[Tab], 2000])),
+ ?match(yes, rpc:call(A, mnesia, force_load_table, [Tab])),
+ ?match(C, rpc:call(A, mnesia, table_info, [Tab, where_to_read])),
+
+ ?match([{Tab, 1, updated}], rpc:call(A, mnesia, dirty_read, [{Tab, 1}])),
+ ?match({atomic, ok}, rpc:call(A, mnesia, sync_transaction, [?SDwrite({Tab, 1, updated_twice})])),
+
+ ?match(ok, rpc:call(B, mnesia, start, [])),
+ ?match(ok, rpc:call(B, mnesia, wait_for_tables, [[Tab], 10000])),
+
+ ?match([{Tab, 1, updated_twice}], rpc:call(A, mnesia, dirty_read, [{Tab, 1}])),
+ ?match([{Tab, 1, updated_twice}], rpc:call(B, mnesia, dirty_read, [{Tab, 1}])),
+ ?match([{Tab, 1, updated_twice}], rpc:call(C, mnesia, dirty_read, [{Tab, 1}])),
+
+ ?verify_mnesia(Nodes, []).
+
+remote_force_load_with_local_master_node(doc) ->
+ ["Force load a table on a remote node while the ",
+ "local node is down. Start the local node and ",
+ "verfify that the tables is loaded from disc locally "
+ "if the local node has itself as master node and ",
+ "the remote node has both the local and remote node ",
+ "as master nodes"];
+remote_force_load_with_local_master_node(suite) -> [];
+remote_force_load_with_local_master_node(Config) when is_list(Config) ->
+ [A, B] = Nodes = ?acquire_nodes(2, Config),
+
+ Tab = remote_force_load_with_local_master_node,
+ ?match({atomic,ok}, mnesia:create_table(Tab, [{disc_copies, Nodes}])),
+ ?match(ok, rpc:call(A, mnesia, set_master_nodes, [Tab, [A, B]])),
+ ?match(ok, rpc:call(B, mnesia, set_master_nodes, [Tab, [B]])),
+
+ W = fun(Who) -> mnesia:write({Tab, who, Who}) end,
+ ?match({atomic, ok}, rpc:call(A,mnesia, sync_transaction, [W, [a]])),
+ ?match(stopped, rpc:call(A, mnesia, stop, [])),
+ ?match({atomic, ok}, rpc:call(B, mnesia, sync_transaction, [W, [b]])),
+ ?match(stopped, rpc:call(B, mnesia, stop, [])),
+
+ ?match(ok, rpc:call(A, mnesia, start, [])),
+ ?match(ok, rpc:call(A, mnesia, wait_for_tables, [[Tab], 3000])),
+ ?match([{Tab, who, a}], rpc:call(A, mnesia, dirty_read, [{Tab, who}])),
+
+ ?match(ok, rpc:call(B, mnesia, start, [])),
+ ?match(ok, rpc:call(B, mnesia, wait_for_tables, [[Tab], 3000])),
+ ?match([{Tab, who, b}], rpc:call(B, mnesia, dirty_read, [{Tab, who}])),
+
+ ?verify_mnesia(Nodes, []).
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+durability_of_dump_tables(doc) ->
+ [ "Verify that all tables contain the correct data when Mnesia",
+ "is restarted and tables are loaded from disc to recover",
+ " their previous contents. " ];
+durability_of_dump_tables(suite) -> [dump_ram_copies,
+ dump_disc_copies,
+ dump_disc_only].
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+dump_ram_copies(doc) ->
+ ["Check that ram_copies tables are loaded with the"
+ "contents that had been dumped before Mnesia",
+ "was restarted. " ];
+dump_ram_copies(suite) -> [];
+dump_ram_copies(Config) when is_list(Config) ->
+ Nodes = ?acquire_nodes(3, Config),
+ {success, [P1,P2,P3]} = ?start_activities(Nodes),
+
+ NP1 = node(P1),
+ NP2 = node(P2),
+
+ {A,B,C} = case node() of
+ NP1 ->
+ %?verbose("first case ~n"),
+ {P3,P2,P1};
+ NP2 ->
+ %?verbose("second case ~n"),
+ {P3,P1,P2};
+ _ ->
+ {P1,P2,P3}
+ end,
+
+ Node1 = node(A),
+ Node2 = node(B),
+ Node3 = node(C),
+
+ ?verbose(" A pid:~p node:~p ~n",[A,Node1]),
+ ?verbose(" B pid:~p node:~p ~n",[B,Node2]),
+ ?verbose(" C pid:~p node:~p ~n",[C,Node3]),
+
+
+ %% ram copies table on 2 nodes
+
+ Tab = dump_table,
+ Def = [{attributes, [key, value]},
+ {ram_copies, [Node1,Node2]}],
+
+ ?match({atomic, ok}, mnesia:create_table(Tab, Def)),
+
+ ?match(ok, mnesia:dirty_write({Tab, 1, 4711})),
+ ?match(ok, mnesia:dirty_write({Tab, 2, 42})),
+ ?match(ok, mnesia:dirty_write({Tab, 3, 256})),
+
+ %% dump the table
+
+ ?match( {atomic,ok}, mnesia:dump_tables([Tab])),
+
+ %% perform updates (they shall be lost after kill Mnesia )
+
+ ?match(ok, mnesia:dirty_write({Tab, 1, 815})),
+ ?match(ok, mnesia:dirty_write({Tab, 2, 915})),
+
+ %% add another replica on node3
+ mnesia:add_table_copy(Tab,Node3,ram_copies),
+
+ %% all 3 replicas shall have the new contents
+ cross_check_tables([A,B,C],Tab,
+ {[{Tab,1,815}],[{Tab,2,915}],[{Tab,3,256}]}),
+
+ %% kill mnesia on node 3
+ mnesia_test_lib:kill_mnesia([Node3]),
+
+ %% wait a while, so that mnesia is really down
+ timer:sleep(timer:seconds(2)),
+
+ mnesia_test_lib:kill_mnesia([Node1,Node2]), %% kill them as well
+ timer:sleep(timer:seconds(2)),
+
+ %% start Mnesia only on node 3
+ ?verbose("starting mnesia on Node3~n",[]),
+
+ %% test_lib:mnesia_start doesnt work, because it waits
+ %% for the schema on all nodes ... ???
+ ?match(ok,rpc:call(Node3,mnesia,start,[]) ),
+ ?match(ok,rpc:call(Node3,mnesia,wait_for_tables,
+ [[Tab],timer:seconds(30)] ) ),
+
+ %% node3 shall have the conents of the dump
+ cross_check_tables([C],Tab,{[{Tab,1,4711}],[{Tab,2,42}],[{Tab,3,256}]}),
+
+ %% start Mnesia on the other 2 nodes, too
+ mnesia_test_lib:start_mnesia([Node1,Node2],[Tab]),
+
+ cross_check_tables([A,B,C],Tab,
+ {[{Tab,1,4711}],[{Tab,2,42}],[{Tab,3,256}]}),
+ ?verify_mnesia(Nodes, []).
+
+%% check the contents of the table
+
+cross_check_tables([],_tab,_elements) -> ok;
+cross_check_tables([Pid|Rest],Tab,{Val1,Val2,Val3}) ->
+ Pid ! fun () ->
+ R1 = mnesia:dirty_read({Tab,1}),
+ R2 = mnesia:dirty_read({Tab,2}),
+ R3 = mnesia:dirty_read({Tab,3}),
+ {R1,R2,R3}
+ end,
+ ?match_receive({ Pid, {Val1, Val2, Val3 } }),
+ cross_check_tables(Rest,Tab,{Val1,Val2,Val3} ).
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+%% Should be in evil test suite !!!
+
+dump_disc_copies(doc) ->
+ ["Check that it is not possible to dump disc_copies tables"];
+dump_disc_copies(suite) -> [];
+dump_disc_copies(Config) when is_list(Config) ->
+ do_dump_copies(Config, disc_copies).
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+%% Should be in evil test suite !!!
+dump_disc_only(doc) ->
+ ["Check that it is not possible to dump disc_only_copies tables"];
+dump_disc_only(suite) -> [];
+dump_disc_only(Config) when is_list(Config) ->
+ do_dump_copies(Config,disc_only_copies).
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+do_dump_copies(Config,Copies) ->
+ [Node1] = Nodes = ?acquire_nodes(1, Config),
+
+ Tab = dump_copies,
+ Def = [{attributes, [key, value]},
+ {Copies, [Node1]}],
+
+ ?match({atomic, ok}, mnesia:create_table(Tab, Def)),
+
+ ?match(ok, mnesia:dirty_write({Tab, 1, 4711})),
+ ?match(ok, mnesia:dirty_write({Tab, 2, 42})),
+ ?match(ok, mnesia:dirty_write({Tab, 3, 256})),
+
+ %% dump the table
+ ?match( {aborted, {"Only allowed on ram_copies",Tab,[Node1]}},
+ mnesia:dump_tables([Tab])),
+
+ ?match(ok, mnesia:dirty_write({Tab, 1, 815})),
+ ?match(ok, mnesia:dirty_write({Tab, 2, 915})),
+
+ %% kill mnesia on node1
+ mnesia_test_lib:kill_mnesia([Node1]),
+
+ %% wait a while, so that mnesia is really down
+ timer:sleep(timer:seconds(1)),
+
+ mnesia_test_lib:start_mnesia([Node1],[Tab]),
+
+ ?match([{Tab, 1, 815}], mnesia:dirty_read({Tab,1}) ),
+ ?match([{Tab, 2, 915}], mnesia:dirty_read({Tab,2}) ),
+ ?match([{Tab, 3, 256}], mnesia:dirty_read({Tab,3}) ),
+ ?verify_mnesia(Nodes, []).
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+durability_of_disc_copies(doc) ->
+ ["Perform all possible kinds of updates on tables and check"
+ "whether no data is lost after a restart of Mnesia.",
+ "This test is done for disc_copies"];
+
+durability_of_disc_copies(suite) -> [];
+durability_of_disc_copies(Config) when is_list(Config) ->
+ do_disc_durability(Config,disc_copies).
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+durability_of_disc_only_copies(doc) ->
+ ["Perform all possible kinds of updates on tables and check"
+ "whether no data is lost after a restart of Mnesia.",
+ "This test is done for disc_only_copies"];
+durability_of_disc_only_copies(suite) -> [];
+durability_of_disc_only_copies(Config) when is_list(Config) ->
+ do_disc_durability(Config,disc_only_copies).
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+do_disc_durability(Config,CopyType) ->
+ Nodes = ?acquire_nodes(3, Config ++ [{tc_timeout, timer:minutes(1)}]),
+ {success, [A,B,C]} = ?start_activities(Nodes),
+
+ Tab_set = disc_durability_set,
+ Def_set = [{attributes, [key, value]},
+ {CopyType, Nodes}],
+
+ Tab_bag = disc_durability_bag,
+ Def_bag = [{attributes, [key, value]},
+ {type, bag},
+ {CopyType, Nodes}],
+
+ ?match({atomic, ok}, mnesia:create_table(Tab_set, Def_set)),
+ ?match({atomic, ok}, mnesia:create_table(Tab_bag, Def_bag)),
+
+ %% do updates
+ ?match({atomic, ok},
+ mnesia:transaction(fun()->
+ mnesia:write({Tab_set, 11, 1111}),
+ mnesia:write({Tab_set, 22, 2222}),
+ mnesia:write({Tab_set, 33, 3333}),
+ mnesia:write({Tab_set, 55, 5555})
+ end)),
+ mnesia:dirty_write({Tab_set, 44, 4444}),
+
+ ?match({atomic, ok},
+ mnesia:transaction(fun()->
+ mnesia:write({Tab_bag, 11, a_1111}),
+ mnesia:write({Tab_bag, 11, b_1111}),
+ mnesia:write({Tab_bag, 22, a_2222}),
+ mnesia:write({Tab_bag, 22, b_2222}),
+ mnesia:write({Tab_bag, 33, a_3333}),
+ mnesia:write({Tab_bag, 33, b_3333})
+ end)),
+ ?match({atomic, ok},
+ mnesia:transaction(fun()-> mnesia:delete({Tab_set, 22}) end)),
+ ?match(ok, mnesia:dirty_delete({Tab_set, 33})),
+ ?match(5558, mnesia:dirty_update_counter({Tab_set, 55}, 3)),
+ ?match({atomic, ok},
+ mnesia:transaction(fun()->
+ mnesia:delete_object({Tab_bag, 22, b_2222})
+ end)),
+ ?match(ok, mnesia:dirty_delete_object({Tab_bag, 33, b_3333})),
+ ?match(10, mnesia:dirty_update_counter({Tab_set, counter}, 10)),
+ ?match({atomic, ok}, % Also syncs update_counter
+ mnesia:sync_transaction(fun() -> mnesia:write({Tab_set,66,6666}) end)),
+
+ Updated = {[[{Tab_set,counter,10}],
+ [{Tab_set,counter,10}],
+ [{Tab_set,counter,10}]],[]},
+ ?match(Updated, rpc:multicall(Nodes, mnesia, dirty_read, [Tab_set,counter])),
+
+ %% kill mnesia on all nodes, start it again and check the data
+ mnesia_test_lib:kill_mnesia(Nodes),
+ mnesia_test_lib:start_mnesia(Nodes,[Tab_set,Tab_bag]),
+
+ ?log("Flushed ~p ~n", [mnesia_test_lib:flush()]), %% Debugging strange msgs..
+ ?log("Processes ~p ~p ~p~n", [A,B,C]),
+ check_tables([A,B,C],
+ [{Tab_set,11}, {Tab_set,22},{Tab_set,33},
+ {Tab_set,44},{Tab_set,55}, {Tab_set,66},
+ {Tab_bag,11}, {Tab_bag,22},{Tab_bag,33},
+ {Tab_set, counter}],
+ [[{Tab_set, 11, 1111}], [], [], [{Tab_set, 44, 4444}],
+ [{Tab_set, 55, 5558}], [{Tab_set, 66, 6666}],
+ lists:sort([{Tab_bag, 11, a_1111},{Tab_bag, 11, b_1111}]),
+ [{Tab_bag, 22, a_2222}], [{Tab_bag, 33, a_3333}],
+ [{Tab_set, counter, 10}]]),
+
+ timer:sleep(1000), %% Debugging strange msgs..
+ ?log("Flushed ~p ~n", [mnesia_test_lib:flush()]),
+ ?verify_mnesia(Nodes, []).
+
+%% check the contents of the table
+%%
+%% all the processes in the PidList shall find all
+%% table entries in ValList
+
+check_tables([],_vallist,_resultList) -> ok;
+check_tables([Pid|Rest],ValList,ResultList) ->
+ Pid ! fun () ->
+ check_values(ValList)
+ end,
+ ?match_receive({ Pid, ResultList }),
+ check_tables(Rest,ValList,ResultList).
+
+check_values([]) -> [];
+check_values([{Tab,Key}|Rest]) ->
+ Ret = lists:sort(mnesia:dirty_read({Tab,Key})),
+ [Ret|check_values(Rest)].
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% stolen from mnesia_recovery_test.erl:
+
+receive_messages([]) -> [];
+receive_messages(ListOfMsgs) ->
+ receive
+ timeout ->
+ case lists:member(timeout, ListOfMsgs) of
+ false ->
+ ?warning("I (~p) have received unexpected msg~n ~p ~n",
+ [self(),timeout]),
+ receive_messages(ListOfMsgs);
+ true ->
+ ?verbose("I (~p) got msg ~p ~n", [self(),timeout]),
+ [ timeout | receive_messages(ListOfMsgs -- [timeout])]
+ end;
+
+ {Pid, Msg} ->
+ case lists:member(Msg, ListOfMsgs) of
+ false ->
+ ?warning("I (~p) have received unexpected msg~n ~p ~n",
+ [self(),{Pid, Msg}]),
+ receive_messages(ListOfMsgs);
+ true ->
+ ?verbose("I (~p) got msg ~p from ~p ~n", [self(),Msg, Pid]),
+ [{Pid, Msg} | receive_messages(ListOfMsgs -- [Msg])]
+ end;
+
+ Else -> ?warning("Recevied unexpected Msg~n ~p ~n", [Else])
+ after timer:seconds(40) ->
+ ?error("Timeout in receive msgs while waiting for ~p~n",
+ [ListOfMsgs])
+ end.
+
diff --git a/lib/mnesia/test/mnesia_evil_backup.erl b/lib/mnesia/test/mnesia_evil_backup.erl
new file mode 100644
index 0000000000..bbbebeb02c
--- /dev/null
+++ b/lib/mnesia/test/mnesia_evil_backup.erl
@@ -0,0 +1,750 @@
+%%
+%% %CopyrightBegin%
+%%
+%% 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%
+%%
+
+%%
+%%%----------------------------------------------------------------------
+%%% File : mnesia_evil_backup.erl
+%%% Author : Dan Gudmundsson <dgud@legolas>
+%%% Purpose : Evil backup tests
+%%% Created : 3 Jun 1998 by Dan Gudmundsson <[email protected]>
+%%%----------------------------------------------------------------------
+
+-module(mnesia_evil_backup).
+-author('[email protected]').
+-compile(export_all).
+-include("mnesia_test_lib.hrl").
+
+%%-export([Function/Arity, ...]).
+
+init_per_testcase(Func, Conf) ->
+ mnesia_test_lib:init_per_testcase(Func, Conf).
+
+fin_per_testcase(Func, Conf) ->
+ mnesia_test_lib:fin_per_testcase(Func, Conf).
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+all(doc) ->
+ ["Checking all the functionality regarding ",
+ "to the backup and different ",
+ "kinds of restore and fallback interface"];
+
+all(suite) ->
+ [
+ backup,
+ bad_backup,
+ global_backup_checkpoint,
+ restore_tables,
+ traverse_backup,
+ selective_backup_checkpoint,
+ incremental_backup_checkpoint,
+%% local_backup_checkpoint,
+ install_fallback,
+ uninstall_fallback,
+ local_fallback,
+ sops_with_checkpoint
+ ].
+
+backup(doc) -> ["Checking the interface to the function backup",
+ "We don't check that the backups can be used here",
+ "That is checked in install_fallback and in restore"];
+backup(suite) -> [];
+backup(Config) when is_list(Config) ->
+ [Node1, Node2] = _Nodes = ?acquire_nodes(2, Config),
+ Tab = backup_tab,
+ Def = [{disc_copies, [Node1]}, {ram_copies, [Node2]}],
+ ?match({atomic, ok}, mnesia:create_table(Tab, Def)),
+ ?match(ok, mnesia:dirty_write({Tab, 1, test_ok})),
+ File = "backup_test.BUP",
+ ?match(ok, mnesia:backup(File)),
+
+ File2 = "backup_test2.BUP",
+ Tab2 = backup_tab2,
+ Def2 = [{disc_only_copies, [Node2]}],
+ ?match({atomic, ok}, mnesia:create_table(Tab2, Def2)),
+ ?match(ok, mnesia:backup(File2, mnesia_backup)),
+
+ File3 = "backup_test3.BUP",
+ mnesia_test_lib:kill_mnesia([Node2]),
+ ?match({error, _}, mnesia:backup(File3, mnesia_backup)),
+
+ ?match(ok, file:delete(File)),
+ ?match(ok, file:delete(File2)),
+ ?match({error, _}, file:delete(File3)),
+ ?verify_mnesia([Node1], [Node2]).
+
+
+bad_backup(suite) -> [];
+bad_backup(Config) when is_list(Config) ->
+ [Node1] = ?acquire_nodes(1, Config),
+ Tab = backup_tab,
+ Def = [{disc_copies, [Node1]}],
+ ?match({atomic, ok}, mnesia:create_table(Tab, Def)),
+ ?match(ok, mnesia:dirty_write({Tab, 1, test_ok})),
+ File = "backup_test.BUP",
+ ?match(ok, mnesia:backup(File)),
+ file:write_file(File, "trash", [append]),
+ ?match(ok, mnesia:dirty_write({Tab, 1, test_bad})),
+ ?match({atomic,[Tab]}, mnesia:restore(File, [{clear_tables, [Tab]}])),
+ ?match([{Tab,1,test_ok}], mnesia:dirty_read(Tab, 1)),
+
+ ?match(ok, file:delete(File)),
+ ?verify_mnesia([Node1], []).
+
+
+
+global_backup_checkpoint(doc) ->
+ ["Checking the interface to the function backup_checkpoint",
+ "We don't check that the backups can be used here",
+ "That is checked in install_fallback and in restore"];
+global_backup_checkpoint(suite) -> [];
+global_backup_checkpoint(Config) when is_list(Config) ->
+ [Node1, Node2] = Nodes = ?acquire_nodes(2, Config),
+ Tab = backup_cp,
+ Def = [{disc_copies, [Node1]}, {ram_copies, [Node2]}],
+ File = "backup_checkpoint.BUP",
+ File2 = "backup_checkpoint2.BUP",
+ ?match({atomic, ok}, mnesia:create_table(Tab, Def)),
+ ?match(ok, mnesia:dirty_write({Tab, 1, test_ok})),
+ ?match({error, _}, mnesia:backup_checkpoint(cp_name, File)),
+ Spec = [{name, cp_name}, {max, mnesia:system_info(tables)}],
+ ?match({ok, _Name, _Ns}, mnesia:activate_checkpoint(Spec)),
+ ?match(ok, mnesia:backup_checkpoint(cp_name, File)),
+ ?match({error, _}, mnesia:backup_checkpoint(cp_name_nonexist, File)),
+ ?match(ok, mnesia:backup_checkpoint(cp_name, File2, mnesia_backup)),
+ ?match({error, _}, file:delete(File)),
+ ?match(ok, file:delete(File2)),
+ ?verify_mnesia(Nodes, []).
+
+restore_tables(doc) ->
+ ["Tests the interface of restore"];
+
+restore_tables(suite) ->
+ [
+ restore_errors,
+ restore_clear,
+ restore_keep,
+ restore_recreate,
+ restore_clear_ram
+ ].
+
+restore_errors(suite) -> [];
+restore_errors(Config) when is_list(Config) ->
+ [_Node] = ?acquire_nodes(1, Config),
+ ?match({aborted, enoent}, mnesia:restore(notAfile, [])),
+ ?match({aborted, {badarg, _}}, mnesia:restore(notAfile, not_a_list)),
+ ?match({aborted, {badarg, _}}, mnesia:restore(notAfile, [test_badarg])),
+ ?match({aborted, {badarg, _}}, mnesia:restore(notAfile, [{test_badarg, xxx}])),
+ ?match({aborted, {badarg, _}}, mnesia:restore(notAfile, [{skip_tables, xxx}])),
+ ?match({aborted, {badarg, _}}, mnesia:restore(notAfile, [{recreate_tables, [schema]}])),
+ ?match({aborted, {badarg, _}}, mnesia:restore(notAfile, [{default_op, asdklasd}])),
+ ok.
+
+restore_clear(suite) -> [];
+restore_clear(Config) when is_list(Config) ->
+ restore(Config, clear_tables).
+
+restore_keep(suite) -> [];
+restore_keep(Config) when is_list(Config) ->
+ restore(Config, keep_tables).
+
+restore_recreate(suite) -> [];
+restore_recreate(Config) when is_list(Config) ->
+ restore(Config, recreate_tables).
+
+check_tab(Records, Line) ->
+ Verify = fun({Table, Key, Val}) ->
+ case catch mnesia:dirty_read({Table, Key}) of
+ [{Table, Key, Val}] -> ok;
+ Else ->
+ mnesia_test_lib:error("Not matching on Node ~p ~n"
+ " Expected ~p~n Actual ~p~n",
+ [node(), {Table, Key, Val}, Else],
+ ?MODULE, Line),
+ exit(error)
+ end;
+ (Recs) ->
+ [{Tab, Key, _}, _] = Recs,
+ SRecs = lists:sort(Recs),
+ R_Recs = lists:sort(catch mnesia:dirty_read({Tab, Key})),
+ case R_Recs of
+ SRecs -> ok;
+ Else ->
+ mnesia_test_lib:error("Not matching on Node ~p ~n"
+ " Expected ~p~n Actual ~p~n",
+ [node(), SRecs, Else],
+ ?MODULE, Line),
+ exit(error)
+ end
+ end,
+ lists:foreach(Verify, Records).
+
+restore(Config, Op) ->
+ [Node1, Node2, _Node3] = Nodes = ?acquire_nodes(3, Config),
+
+ Tab1 = ram_snmp,
+ Def1 = [{snmp, [{key, integer}]}, {ram_copies, [Node1]}],
+ Tab2 = disc_index,
+ Def2 = [{index, [val]}, {disc_copies, [Node1, Node2]}],
+ Tab3 = dionly_bag,
+ Def3 = [{type, bag}, {disc_only_copies, Nodes}],
+ ?match({atomic, ok}, mnesia:create_table(Tab1, Def1)),
+ ?match({atomic, ok}, mnesia:create_table(Tab2, Def2)),
+ ?match({atomic, ok}, mnesia:create_table(Tab3, Def3)),
+
+ File1 = "restore1.BUP",
+ File2 = "restore2.BUP",
+
+ Restore = fun(O, A) ->
+ case mnesia:restore(O, A) of
+ {atomic, Tabs} when is_list(Tabs) -> {atomic, lists:sort(Tabs)};
+ Other -> Other
+ end
+ end,
+ Tabs = lists:sort([Tab1, Tab2, Tab3]),
+
+ [mnesia:dirty_write({Tab1, N, N+42}) || N <- lists:seq(1, 10)],
+ [mnesia:dirty_write({Tab2, N, N+43}) || N <- lists:seq(1, 10)],
+ [mnesia:dirty_write({Tab3, N, N+44}) || N <- lists:seq(1, 10)],
+
+ Res1 = [{Tab1, N, N+42} || N <- lists:seq(1, 10)],
+ Res2 = [{Tab2, N, N+43} || N <- lists:seq(1, 10)],
+ Res3 = [{Tab3, N, N+44} || N <- lists:seq(1, 10)],
+
+ {ok, Name, _} = mnesia:activate_checkpoint([{min, Tabs}, {ram_overrides_dump, true}]),
+ file:delete(File1),
+
+ %% Test standard Restore on one table on one node
+ ?match(ok, mnesia:backup_checkpoint(Name, File1)),
+ ?match(ok, mnesia:deactivate_checkpoint(Name)),
+ ?match(ok, mnesia:backup(File2)),
+ [mnesia:dirty_write({Tab1, N, N+1}) || N <- lists:seq(1, 11)],
+ [mnesia:dirty_write({Tab2, N, N+1}) || N <- lists:seq(1, 11)],
+ [mnesia:dirty_write({Tab3, N, N+1}) || N <- lists:seq(1, 11)],
+ _Res11 = [{Tab1, N, N+1} || N <- lists:seq(1, 11)],
+ Res21 = [{Tab2, N, N+1} || N <- lists:seq(1, 11)],
+ Res31 = [[{Tab3, N, N+1}, {Tab3, N, N+44}] || N <- lists:seq(1, 10)],
+
+ ?match({atomic, [Tab1]}, Restore(File1, [{Op, [Tab1]},
+ {skip_tables, Tabs -- [Tab1]}])),
+ case Op of
+ keep_tables ->
+ ?match([{Tab1, 11, 12}], mnesia:dirty_read({Tab1, 11}));
+ clear_tables ->
+ ?match([], mnesia:dirty_read({Tab1, 11}));
+ recreate_tables ->
+ ?match([], mnesia:dirty_read({Tab1, 11}))
+ end,
+ [rpc:call(Node, ?MODULE, check_tab, [Res1, ?LINE]) || Node <- Nodes],
+ [rpc:call(Node, ?MODULE, check_tab, [Res21, ?LINE]) || Node <- Nodes],
+ [rpc:call(Node, ?MODULE, check_tab, [Res31, ?LINE]) || Node <- Nodes],
+
+ %% Restore all tables on it's nodes
+ mnesia_schema:clear_table(Tab1),
+ mnesia_schema:clear_table(Tab2),
+ mnesia_schema:clear_table(Tab3),
+ [mnesia:dirty_write({Tab1, N, N+1}) || N <- lists:seq(1, 11)],
+ [mnesia:dirty_write({Tab2, N, N+1}) || N <- lists:seq(1, 11)],
+ [mnesia:dirty_write({Tab3, N, N+1}) || N <- lists:seq(1, 11)],
+
+ ?match({atomic, ok}, mnesia:del_table_copy(Tab2, Node1)),
+
+ ?match({ok, Node1}, mnesia:subscribe({table, Tab1})),
+
+ ?match({atomic, Tabs}, Restore(File1, [{default_op, Op},
+ {module, mnesia_backup}])),
+ case Op of
+ clear_tables ->
+ ?match_receive({mnesia_table_event, {delete, {schema, Tab1}, _}}),
+ ?match_receive({mnesia_table_event, {write, {schema, Tab1, _}, _}}),
+ check_subscr(Tab1),
+ [rpc:call(Node, ?MODULE, check_tab, [Res1, ?LINE]) || Node <- Nodes],
+ [rpc:call(Node, ?MODULE, check_tab, [Res2, ?LINE]) || Node <- Nodes],
+ [rpc:call(Node, ?MODULE, check_tab, [Res3, ?LINE]) || Node <- Nodes],
+ ?match([], mnesia:dirty_read({Tab1, 11})),
+ ?match([], mnesia:dirty_read({Tab2, 11})),
+ ?match([], mnesia:dirty_read({Tab3, 11})),
+ %% Check Index
+ ?match([{Tab2, 10, 53}], mnesia:dirty_index_read(Tab2, 53, val)),
+ ?match([], mnesia:dirty_index_read(Tab2, 11, val)),
+ %% Check Snmp
+ ?match({ok, [1]}, mnesia:snmp_get_next_index(Tab1,[])),
+ ?match({ok, {Tab1, 1, 43}}, mnesia:snmp_get_row(Tab1, [1])),
+ ?match(undefined, mnesia:snmp_get_row(Tab1, [11])),
+ %% Check schema info
+ ?match([Node2], mnesia:table_info(Tab2, where_to_write));
+ keep_tables ->
+ check_subscr(Tab1),
+ [rpc:call(Node, ?MODULE, check_tab, [Res1, ?LINE]) || Node <- Nodes],
+ [rpc:call(Node, ?MODULE, check_tab, [Res2, ?LINE]) || Node <- Nodes],
+ [rpc:call(Node, ?MODULE, check_tab, [Res31, ?LINE]) || Node <- Nodes],
+ ?match([{Tab1, 11, 12}], mnesia:dirty_read({Tab1, 11})),
+ ?match([{Tab2, 11, 12}], mnesia:dirty_read({Tab2, 11})),
+ ?match([{Tab3, 11, 12}], mnesia:dirty_read({Tab3, 11})),
+ ?match([{Tab2, 10, 53}], mnesia:dirty_index_read(Tab2, 53, val)),
+ %% Check Index
+ ?match([], mnesia:dirty_index_read(Tab2, 11, val)),
+ ?match({ok, [1]}, mnesia:snmp_get_next_index(Tab1,[])),
+ %% Check Snmp
+ ?match({ok, {Tab1, 1, 43}}, mnesia:snmp_get_row(Tab1, [1])),
+ ?match({ok, {Tab1, 11, 12}}, mnesia:snmp_get_row(Tab1, [11])),
+ %% Check schema info
+ ?match([Node2], mnesia:table_info(Tab2, where_to_write));
+ recreate_tables ->
+ check_subscr(Tab1, 0),
+ [rpc:call(Node, ?MODULE, check_tab, [Res1, ?LINE]) || Node <- Nodes],
+ [rpc:call(Node, ?MODULE, check_tab, [Res2, ?LINE]) || Node <- Nodes],
+ [rpc:call(Node, ?MODULE, check_tab, [Res3, ?LINE]) || Node <- Nodes],
+ ?match([], mnesia:dirty_read({Tab1, 11})),
+ ?match([], mnesia:dirty_read({Tab2, 11})),
+ ?match([], mnesia:dirty_read({Tab3, 11})),
+ %% Check Index
+ ?match([{Tab2, 10, 53}], mnesia:dirty_index_read(Tab2, 53, val)),
+ ?match([], mnesia:dirty_index_read(Tab2, 11, val)),
+ %% Check Snmp
+ ?match({ok, [1]}, mnesia:snmp_get_next_index(Tab1,[])),
+ ?match({ok, {Tab1, 1, 43}}, mnesia:snmp_get_row(Tab1, [1])),
+ ?match(undefined, mnesia:snmp_get_row(Tab1, [11])),
+ %% Check schema info
+ Ns = lists:sort([Node1, Node2]),
+ ?match(Ns, lists:sort(mnesia:table_info(Tab2, where_to_write)))
+ end,
+ ?match(ok, file:delete(File1)),
+ ?match(ok, file:delete(File2)),
+ ?verify_mnesia(Nodes, []).
+
+
+check_subscr(Tab) ->
+ check_subscr(Tab, 10).
+
+check_subscr(_Tab, 0) ->
+ receive
+ Msg ->
+ ?error("Too many msgs ~p~n", [Msg])
+ after 500 ->
+ ok
+ end;
+check_subscr(Tab, N) ->
+ V = N +42,
+ receive
+ {mnesia_table_event, {write, {Tab, N, V}, _}} ->
+ check_subscr(Tab, N-1)
+ after 500 ->
+ ?error("Missing ~p~n", [{Tab, N, V}])
+ end.
+
+restore_clear_ram(suite) -> [];
+restore_clear_ram(Config) when is_list(Config) ->
+ Nodes = ?acquire_nodes(3, [{diskless, true}|Config]),
+
+ ?match({atomic, ok}, mnesia:create_table(a, [{ram_copies, Nodes}])),
+
+ Write = fun(What) ->
+ mnesia:write({a,1,What}),
+ mnesia:write({a,2,What}),
+ mnesia:write({a,3,What})
+ end,
+ Bup = "restore_clear_ram.BUP",
+
+ ?match({atomic, ok}, mnesia:transaction(Write, [initial])),
+ ?match({ok, _, _}, mnesia:activate_checkpoint([{name,test},
+ {min, [schema, a]},
+ {ram_overrides_dump, true}])),
+ ?match(ok, mnesia:backup_checkpoint(test, Bup)),
+
+ ?match({atomic, ok}, mnesia:transaction(Write, [data])),
+ ?match({atomic, [a]}, mnesia:restore(Bup, [{clear_tables,[a]},{default_op,skip_tables}])),
+
+ restore_clear_ram_loop(100, Nodes, Bup),
+
+ ok.
+
+restore_clear_ram_loop(N, Nodes = [N1,N2,N3], Bup) when N > 0 ->
+ ?match([], mnesia_test_lib:stop_mnesia(Nodes)),
+ ?match({_, []}, rpc:multicall([N1,N2], mnesia, start, [[{extra_db_nodes, Nodes}]])),
+ Key = rpc:async_call(N3, mnesia, start, [[{extra_db_nodes, Nodes}]]),
+ ?match({atomic, ok}, mnesia:create_table(a, [{ram_copies, Nodes}])),
+ ?match({atomic, [a]}, mnesia:restore(Bup, [{clear_tables,[a]},{default_op,skip_tables}])),
+ ?match(ok, rpc:yield(Key)),
+ ?match(ok, rpc:call(N3, mnesia, wait_for_tables, [[a], 3000])),
+ case rpc:multicall(Nodes, mnesia, table_info, [a,size]) of
+ {[3,3,3], []} ->
+ restore_clear_ram_loop(N-1, Nodes, Bup);
+ Error ->
+ ?match(3, Error)
+ end;
+restore_clear_ram_loop(_,_,_) ->
+ ok.
+
+traverse_backup(doc) ->
+ ["Testing the traverse_backup interface, the resulting file is not tested though",
+ "See install_fallback for result using the output file from traverse_backup",
+ "A side effect is that the backup file contents are tested"];
+traverse_backup(suite) -> [];
+traverse_backup(Config) when is_list(Config) ->
+ [Node1, Node2] = Nodes = ?acquire_nodes(2, Config),
+ Tab = backup_tab,
+ Def = [{disc_copies, [Node1]}, {ram_copies, [Node2]}],
+ ?match({atomic, ok}, mnesia:create_table(Tab, Def)),
+ ?match(ok, mnesia:dirty_write({Tab, 1, test_nok})),
+ ?match(ok, mnesia:dirty_write({Tab, 2, test_nok})),
+ ?match(ok, mnesia:dirty_write({Tab, 3, test_nok})),
+ ?match(ok, mnesia:dirty_write({Tab, 4, test_nok})),
+ ?match(ok, mnesia:dirty_write({Tab, 5, test_nok})),
+ File = "_treverse_backup.BUP",
+ File2 = "traverse_backup2.BUP",
+ File3 = "traverse_backup3.BUP",
+ ?match(ok, mnesia:backup(File)),
+
+ Fun = fun({backup_tab, N, _}, Acc) -> {[{backup_tab, N, test_ok}], Acc+1};
+ (Other, Acc) -> {[Other], Acc}
+ end,
+
+ ?match({ok, 5}, mnesia:traverse_backup(File, read_only, Fun, 0)),
+ ?match(ok, file:delete(read_only)),
+
+ ?match({ok, 5}, mnesia:traverse_backup(File, mnesia_backup,
+ dummy, read_only, Fun, 0)),
+
+ ?match({ok, 5}, mnesia:traverse_backup(File, File2, Fun, 0)),
+ ?match({ok, 5}, mnesia:traverse_backup(File2, mnesia_backup,
+ File3, mnesia_backup, Fun, 0)),
+
+ BadFun = fun({bad_tab, _N, asd}, Acc) -> {{error, error}, Acc} end,
+ ?match({error, _}, mnesia:traverse_backup(File, read_only, BadFun, 0)),
+ ?match({error, _}, file:delete(read_only)),
+ ?match(ok, file:delete(File)),
+ ?match(ok, file:delete(File2)),
+ ?match(ok, file:delete(File3)),
+ ?verify_mnesia(Nodes, []).
+
+
+install_fallback(doc) ->
+ ["This tests the install_fallback intf.",
+ "It also verifies that the output from backup_checkpoint and traverse_backup",
+ "is valid"];
+install_fallback(suite) -> [];
+install_fallback(Config) when is_list(Config) ->
+ [Node1, Node2] = Nodes = ?acquire_nodes(2, Config),
+ Tab = fallbacks_test,
+ Def = [{disc_copies, [Node1]}, {ram_copies, [Node2]}],
+ ?match({atomic, ok}, mnesia:create_table(Tab, Def)),
+ ?match(ok, mnesia:dirty_write({Tab, 1, test_nok})),
+ ?match(ok, mnesia:dirty_write({Tab, 2, test_nok})),
+ ?match(ok, mnesia:dirty_write({Tab, 3, test_nok})),
+ ?match(ok, mnesia:dirty_write({Tab, 4, test_nok})),
+ ?match(ok, mnesia:dirty_write({Tab, 5, test_nok})),
+
+ Tab2 = fallbacks_test2,
+ Def2 = [{disc_copies, [node()]}],
+ ?match({atomic, ok}, mnesia:create_table(Tab2, Def2)),
+ Tab3 = fallbacks_test3,
+ ?match({atomic, ok}, mnesia:create_table(Tab3, Def2)),
+ Fun2 = fun(Key) ->
+ Rec = {Tab2, Key, test_ok},
+ mnesia:dirty_write(Rec),
+ [Rec]
+ end,
+ TabSize3 = 1000,
+ OldRecs2 = [Fun2(K) || K <- lists:seq(1, TabSize3)],
+
+ Spec =[{name, cp_name}, {max, mnesia:system_info(tables)}],
+ ?match({ok, _Name, Nodes}, mnesia:activate_checkpoint(Spec)),
+ ?match(ok, mnesia:dirty_write({Tab, 6, test_nok})),
+ [mnesia:dirty_write({Tab2, K, test_nok}) || K <- lists:seq(1, TabSize3 + 10)],
+ File = "install_fallback.BUP",
+ File2 = "install_fallback2.BUP",
+ File3 = "install_fallback3.BUP",
+ ?match(ok, mnesia:backup_checkpoint(cp_name, File)),
+
+ Fun = fun({T, N, _}, Acc) when T == Tab ->
+ case N rem 2 of
+ 0 ->
+ io:format("write ~p -> ~p~n", [N, T]),
+ {[{T, N, test_ok}], Acc + 1};
+ 1 ->
+ io:format("write ~p -> ~p~n", [N, Tab3]),
+ {[{Tab3, N, test_ok}], Acc + 1}
+ end;
+ ({T, N}, Acc) when T == Tab ->
+ case N rem 2 of
+ 0 ->
+ io:format("delete ~p -> ~p~n", [N, T]),
+ {[{T, N}], Acc + 1};
+ 1 ->
+ io:format("delete ~p -> ~p~n", [N, Tab3]),
+ {[{Tab3, N}], Acc + 1}
+ end;
+ (Other, Acc) ->
+ {[Other], Acc}
+ end,
+ ?match({ok, _}, mnesia:traverse_backup(File, File2, Fun, 0)),
+ ?match(ok, mnesia:install_fallback(File2)),
+
+ mnesia_test_lib:kill_mnesia([Node1, Node2]),
+ timer:sleep(timer:seconds(1)), % Let it die!
+
+ ?match([], mnesia_test_lib:start_mnesia([Node1, Node2], [Tab, Tab2, Tab3])),
+
+ % Verify
+ ?match([], mnesia:dirty_read({Tab, 1})),
+ ?match([{Tab3, 1, test_ok}], mnesia:dirty_read({Tab3, 1})),
+ ?match([{Tab, 2, test_ok}], mnesia:dirty_read({Tab, 2})),
+ ?match([], mnesia:dirty_read({Tab3, 2})),
+ ?match([], mnesia:dirty_read({Tab, 3})),
+ ?match([{Tab3, 3, test_ok}], mnesia:dirty_read({Tab3, 3})),
+ ?match([{Tab, 4, test_ok}], mnesia:dirty_read({Tab, 4})),
+ ?match([], mnesia:dirty_read({Tab3, 4})),
+ ?match([], mnesia:dirty_read({Tab, 5})),
+ ?match([{Tab3, 5, test_ok}], mnesia:dirty_read({Tab3, 5})),
+ ?match([], mnesia:dirty_read({Tab, 6})),
+ ?match([], mnesia:dirty_read({Tab3, 6})),
+ ?match([], [mnesia:dirty_read({Tab2, K}) || K <- lists:seq(1, TabSize3)] -- OldRecs2),
+ ?match(TabSize3, mnesia:table_info(Tab2, size)),
+
+ % Check the interface
+ file:delete(File3),
+ ?match({error, _}, mnesia:install_fallback(File3)),
+ ?match({error, _}, mnesia:install_fallback(File2, mnesia_badmod)),
+ ?match(ok, mnesia:install_fallback(File2, mnesia_backup)),
+ ?match(ok, file:delete(File)),
+ ?match(ok, file:delete(File2)),
+ ?match({error, _}, file:delete(File3)),
+ ?verify_mnesia(Nodes, []).
+
+uninstall_fallback(suite) -> [];
+uninstall_fallback(Config) when is_list(Config) ->
+ [Node1, Node2] = Nodes = ?acquire_nodes(2, Config),
+ Tab = uinst_fallbacks_test,
+ File = "uinst_fallback.BUP",
+ File2 = "uinst_fallback2.BUP",
+ Def = [{disc_copies, [Node1]}, {ram_copies, [Node2]}],
+ ?match({atomic, ok}, mnesia:create_table(Tab, Def)),
+ ?match(ok, mnesia:dirty_write({Tab, 1, test_ok})),
+ ?match(ok, mnesia:backup(File)),
+ Fun = fun({T, N, _}, Acc) when T == Tab ->
+ {[{T, N, test_nok}], Acc+1};
+ (Other, Acc) -> {[Other], Acc}
+ end,
+ ?match({ok, _}, mnesia:traverse_backup(File, File2, Fun, 0)),
+ ?match({error, enoent}, mnesia:uninstall_fallback()),
+ ?match(ok, mnesia:install_fallback(File2)),
+ ?match(ok, file:delete(File)),
+ ?match(ok, file:delete(File2)),
+ ?match(ok, mnesia:uninstall_fallback()),
+
+ mnesia_test_lib:kill_mnesia([Node1, Node2]),
+ timer:sleep(timer:seconds(1)), % Let it die!
+ ?match([], mnesia_test_lib:start_mnesia([Node1, Node2], [Tab])),
+ ?match([{Tab, 1, test_ok}], mnesia:dirty_read({Tab, 1})),
+ ?verify_mnesia(Nodes, []).
+
+local_fallback(suite) -> [];
+local_fallback(Config) when is_list(Config) ->
+ [Node1, Node2] = Nodes = ?acquire_nodes(2, Config),
+ Tab = local_fallback,
+ File = "local_fallback.BUP",
+ Def = [{disc_copies, Nodes}],
+ Key = foo,
+ Pre = {Tab, Key, pre},
+ Post = {Tab, Key, post},
+ ?match({atomic, ok}, mnesia:create_table(Tab, Def)),
+ ?match(ok, mnesia:dirty_write(Pre)),
+ ?match(ok, mnesia:backup(File)),
+ ?match(ok, mnesia:dirty_write(Post)),
+ Local = [{scope, local}],
+ ?match({error, enoent}, mnesia:uninstall_fallback(Local)),
+ ?match(ok, mnesia:install_fallback(File, Local)),
+ ?match(true, mnesia:system_info(fallback_activated)),
+ ?match(ok, mnesia:uninstall_fallback(Local)),
+ ?match(false, mnesia:system_info(fallback_activated)),
+ ?match(ok, mnesia:install_fallback(File, Local)),
+ ?match(true, mnesia:system_info(fallback_activated)),
+
+ ?match(false, rpc:call(Node2, mnesia, system_info , [fallback_activated])),
+ ?match(ok, rpc:call(Node2, mnesia, install_fallback , [File, Local])),
+ ?match([Post], mnesia:dirty_read({Tab, Key})),
+ ?match([Post], rpc:call(Node2, mnesia, dirty_read, [{Tab, Key}])),
+
+ ?match([], mnesia_test_lib:kill_mnesia(Nodes)),
+ ?match([], mnesia_test_lib:start_mnesia(Nodes, [Tab])),
+ ?match([Pre], mnesia:dirty_read({Tab, Key})),
+ ?match([Pre], rpc:call(Node2, mnesia, dirty_read, [{Tab, Key}])),
+ Dir = rpc:call(Node2, mnesia, system_info , [directory]),
+
+ ?match(ok, mnesia:dirty_write(Post)),
+ ?match([Post], mnesia:dirty_read({Tab, Key})),
+ ?match([], mnesia_test_lib:kill_mnesia([Node2])),
+ ?match(ok, mnesia:install_fallback(File, Local ++ [{mnesia_dir, Dir}])),
+ ?match([], mnesia_test_lib:kill_mnesia([Node1])),
+
+ ?match([], mnesia_test_lib:start_mnesia([Node2], [])),
+ ?match(yes, rpc:call(Node2, mnesia, force_load_table, [Tab])),
+ ?match([], mnesia_test_lib:start_mnesia(Nodes, [Tab])),
+ ?match([Pre], mnesia:dirty_read({Tab, Key})),
+
+ ?match(ok, file:delete(File)),
+ ?verify_mnesia(Nodes, []).
+
+selective_backup_checkpoint(doc) ->
+ ["Perform a selective backup of a checkpoint"];
+selective_backup_checkpoint(suite) -> [];
+selective_backup_checkpoint(Config) when is_list(Config) ->
+ [Node1, Node2] = Nodes = ?acquire_nodes(2, Config),
+ Tab = sel_backup,
+ OmitTab = sel_backup_omit,
+ CpName = sel_cp,
+ Def = [{disc_copies, [Node1, Node2]}],
+ File = "selective_backup_checkpoint.BUP",
+ ?match({atomic, ok}, mnesia:create_table(Tab, Def)),
+ ?match({atomic, ok}, mnesia:create_table(OmitTab, Def)),
+ ?match(ok, mnesia:dirty_write({Tab, 1, test_ok})),
+ ?match(ok, mnesia:dirty_write({OmitTab, 1, test_ok})),
+ CpSpec = [{name, CpName}, {max, mnesia:system_info(tables)}],
+ ?match({ok, CpName, _Ns}, mnesia:activate_checkpoint(CpSpec)),
+
+ BupSpec = [{tables, [Tab]}],
+ ?match(ok, mnesia:backup_checkpoint(CpName, File, BupSpec)),
+
+ ?match([schema, sel_backup], bup_tables(File, mnesia_backup)),
+ ?match(ok, file:delete(File)),
+
+ BupSpec2 = [{tables, [Tab, OmitTab]}],
+ ?match(ok, mnesia:backup_checkpoint(CpName, File, BupSpec2)),
+
+ ?match([schema, sel_backup, sel_backup_omit],
+ bup_tables(File, mnesia_backup)),
+ ?match(ok, file:delete(File)),
+ ?verify_mnesia(Nodes, []).
+
+bup_tables(File, Mod) ->
+ Fun = fun(Rec, Tabs) ->
+ Tab = element(1, Rec),
+ Tabs2 = [Tab | lists:delete(Tab, Tabs)],
+ {[Rec], Tabs2}
+ end,
+ case mnesia:traverse_backup(File, Mod, dummy, read_only, Fun, []) of
+ {ok, Tabs} ->
+ lists:sort(Tabs);
+ {error, Reason} ->
+ exit(Reason)
+ end.
+
+incremental_backup_checkpoint(doc) ->
+ ["Perform a incremental backup of a checkpoint"];
+incremental_backup_checkpoint(suite) -> [];
+incremental_backup_checkpoint(Config) when is_list(Config) ->
+ [Node1] = Nodes = ?acquire_nodes(1, Config),
+ Tab = incr_backup,
+ Def = [{disc_copies, [Node1]}],
+ ?match({atomic, ok}, mnesia:create_table(Tab, Def)),
+ OldRecs = [{Tab, K, -K} || K <- lists:seq(1, 5)],
+ ?match([ok|_], [mnesia:dirty_write(R) || R <- OldRecs]),
+ OldCpName = old_cp,
+ OldCpSpec = [{name, OldCpName}, {min, [Tab]}],
+ ?match({ok, OldCpName, _Ns}, mnesia:activate_checkpoint(OldCpSpec)),
+
+ BupSpec = [{tables, [Tab]}],
+ OldFile = "old_full_backup.BUP",
+ ?match(ok, mnesia:backup_checkpoint(OldCpName, OldFile, BupSpec)),
+ ?match(OldRecs, bup_records(OldFile, mnesia_backup)),
+ ?match(ok, mnesia:dirty_delete({Tab, 1})),
+ ?match(ok, mnesia:dirty_write({Tab, 2, 2})),
+ ?match(ok, mnesia:dirty_write({Tab, 3, -3})),
+
+ NewCpName = new_cp,
+ NewCpSpec = [{name, NewCpName}, {min, [Tab]}],
+ ?match({ok, NewCpName, _Ns}, mnesia:activate_checkpoint(NewCpSpec)),
+ ?match(ok, mnesia:dirty_write({Tab, 4, 4})),
+
+ NewFile = "new_full_backup.BUP",
+ ?match(ok, mnesia:backup_checkpoint(NewCpName, NewFile, BupSpec)),
+ NewRecs = [{Tab, 2, 2}, {Tab, 3, -3},
+ {Tab, 4, 4}, {Tab, 4}, {Tab, 4, -4}, {Tab, 5, -5}],
+ ?match(NewRecs, bup_records(NewFile, mnesia_backup)),
+
+ DiffFile = "diff_backup.BUP",
+ DiffBupSpec = [{tables, [Tab]}, {incremental, OldCpName}],
+ ?match(ok, mnesia:backup_checkpoint(NewCpName, DiffFile, DiffBupSpec)),
+ DiffRecs = [{Tab, 1}, {Tab, 2}, {Tab, 2, 2}, {Tab, 3}, {Tab, 3, -3},
+ {Tab, 4}, {Tab, 4, 4}, {Tab, 4}, {Tab, 4, -4}],
+ ?match(DiffRecs, bup_records(DiffFile, mnesia_backup)),
+
+ ?match(ok, mnesia:deactivate_checkpoint(OldCpName)),
+ ?match(ok, mnesia:deactivate_checkpoint(NewCpName)),
+ ?match(ok, file:delete(OldFile)),
+ ?match(ok, file:delete(NewFile)),
+ ?match(ok, file:delete(DiffFile)),
+
+ ?verify_mnesia(Nodes, []).
+
+bup_records(File, Mod) ->
+ Fun = fun(Rec, Recs) when element(1, Rec) == schema ->
+ {[Rec], Recs};
+ (Rec, Recs) ->
+ {[Rec], [Rec | Recs]}
+ end,
+ case mnesia:traverse_backup(File, Mod, dummy, read_only, Fun, []) of
+ {ok, Recs} ->
+ lists:keysort(1, lists:keysort(2, lists:reverse(Recs)));
+ {error, Reason} ->
+ exit(Reason)
+ end.
+
+sops_with_checkpoint(doc) ->
+ ["Test schema operations during a checkpoint"];
+sops_with_checkpoint(suite) -> [];
+sops_with_checkpoint(Config) when is_list(Config) ->
+ Ns = ?acquire_nodes(2, Config),
+
+ ?match({ok, cp1, Ns}, mnesia:activate_checkpoint([{name, cp1},{max,mnesia:system_info(tables)}])),
+ Tab = tab,
+ ?match({atomic, ok}, mnesia:create_table(Tab, [{disc_copies,Ns}])),
+ OldRecs = [{Tab, K, -K} || K <- lists:seq(1, 5)],
+ [mnesia:dirty_write(R) || R <- OldRecs],
+
+ ?match({ok, cp2, Ns}, mnesia:activate_checkpoint([{name, cp2},{max,mnesia:system_info(tables)}])),
+ File1 = "cp1_delete_me.BUP",
+ ?match(ok, mnesia:dirty_write({Tab,6,-6})),
+ ?match(ok, mnesia:backup_checkpoint(cp1, File1)),
+ ?match(ok, mnesia:dirty_write({Tab,7,-7})),
+ File2 = "cp2_delete_me.BUP",
+ ?match(ok, mnesia:backup_checkpoint(cp2, File2)),
+
+ ?match(ok, mnesia:deactivate_checkpoint(cp1)),
+ ?match(ok, mnesia:backup_checkpoint(cp2, File1)),
+ ?match(ok, mnesia:dirty_write({Tab,8,-8})),
+
+ ?match({atomic,ok}, mnesia:delete_table(Tab)),
+ ?match({error,_}, mnesia:backup_checkpoint(cp2, File2)),
+ ?match({'EXIT',_}, mnesia:dirty_write({Tab,9,-9})),
+
+ ?match({atomic,_}, mnesia:restore(File1, [{default_op, recreate_tables}])),
+ Test = fun(N) when N > 5 -> ?error("To many records in backup ~p ~n", [N]);
+ (N) -> case mnesia:dirty_read(Tab,N) of
+ [{Tab,N,B}] when -B =:= N -> ok;
+ Other -> ?error("Not matching ~p ~p~n", [N,Other])
+ end
+ end,
+ [Test(N) || N <- mnesia:dirty_all_keys(Tab)],
+ ?match({aborted,enoent}, mnesia:restore(File2, [{default_op, recreate_tables}])),
+
+ file:delete(File1), file:delete(File2),
+
+ ?verify_mnesia(Ns, []).
diff --git a/lib/mnesia/test/mnesia_evil_coverage_test.erl b/lib/mnesia/test/mnesia_evil_coverage_test.erl
new file mode 100644
index 0000000000..06674d9eef
--- /dev/null
+++ b/lib/mnesia/test/mnesia_evil_coverage_test.erl
@@ -0,0 +1,2167 @@
+%%
+%% %CopyrightBegin%
+%%
+%% 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
+%% 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(mnesia_evil_coverage_test).
+-author('[email protected]').
+-include("mnesia_test_lib.hrl").
+
+-compile([export_all]).
+
+-define(cleanup(N, Config),
+ mnesia_test_lib:prepare_test_case([{reload_appls, [mnesia]}],
+ N, Config, ?FILE, ?LINE)).
+init_per_testcase(Func, Conf) ->
+ mnesia_test_lib:init_per_testcase(Func, Conf).
+
+fin_per_testcase(Func, Conf) ->
+ mnesia_test_lib:fin_per_testcase(Func, Conf).
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+all(doc) ->
+ ["Evil usage of the API.",
+ "Invoke all functions in the API and try to cover all legal uses",
+ "cases as well the illegal dito. This is a complement to the",
+ "other more explicit test cases."];
+all(suite) ->
+ [
+ system_info,
+ table_info,
+ error_description,
+ db_node_lifecycle,
+ evil_delete_db_node,
+ start_and_stop,
+ checkpoint,
+ table_lifecycle,
+ add_copy_conflict,
+ add_copy_when_going_down,
+ replica_management,
+ schema_availability,
+ local_content,
+ table_access_modifications,
+ replica_location,
+ table_sync,
+ user_properties,
+ unsupp_user_props,
+ record_name,
+ snmp_access,
+ iteration,
+ debug_support,
+ sorted_ets,
+ {mnesia_dirty_access_test, all},
+ {mnesia_trans_access_test, all},
+ {mnesia_evil_backup, all}
+ ].
+
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%% Get meta info about Mnesia
+
+system_info(suite) -> [];
+system_info(Config) when is_list(Config) ->
+ Nodes = ?acquire_nodes(all, Config),
+ Ns = ?sort(Nodes),
+ ?match(yes, mnesia:system_info(is_running)),
+ ?match(Ns, ?sort(mnesia:system_info(db_nodes))),
+ ?match(Ns, ?sort(mnesia:system_info(running_db_nodes))),
+ ?match(A when is_atom(A), mnesia:system_info(debug)),
+ ?match(L when is_list(L), mnesia:system_info(directory)),
+ ?match(L when is_list(L), mnesia:system_info(log_version)),
+ ?match({_, _}, mnesia:system_info(schema_version)),
+ ?match(L when is_list(L), mnesia:system_info(tables)),
+ ?match(L when is_list(L), mnesia:system_info(local_tables)),
+ ?match(L when is_list(L), mnesia:system_info(held_locks)),
+ ?match(L when is_list(L), mnesia:system_info(lock_queue)),
+ ?match(L when is_list(L), mnesia:system_info(transactions)),
+ ?match(I when is_integer(I), mnesia:system_info(transaction_failures)),
+ ?match(I when is_integer(I), mnesia:system_info(transaction_commits)),
+ ?match(I when is_integer(I), mnesia:system_info(transaction_restarts)),
+ ?match(L when is_list(L), mnesia:system_info(checkpoints)),
+ ?match(A when is_atom(A), mnesia:system_info(backup_module)),
+ ?match(true, mnesia:system_info(auto_repair)),
+ ?match({_, _}, mnesia:system_info(dump_log_interval)),
+ ?match(A when is_atom(A), mnesia:system_info(dump_log_update_in_place)),
+ ?match(I when is_integer(I), mnesia:system_info(transaction_log_writes)),
+ ?match(I when is_integer(I), mnesia:system_info(send_compressed)),
+ ?match(L when is_list(L), mnesia:system_info(all)),
+ ?match({'EXIT', {aborted, Reason }} when element(1, Reason) == badarg
+ , mnesia:system_info(ali_baba)),
+ ?verify_mnesia(Nodes, []).
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%% Get meta info about table
+
+table_info(suite) -> [];
+table_info(Config) when is_list(Config) ->
+ [Node1, Node2, Node3] = Nodes = ?acquire_nodes(3, Config),
+
+ Tab = table_info,
+ Type = bag,
+ ValPos = 3,
+ Attrs = [k, v],
+ Arity = length(Attrs) +1,
+
+ Schema =
+ case mnesia_test_lib:diskless(Config) of
+ true -> [{type, Type}, {attributes, Attrs}, {index, [ValPos]},
+ {ram_copies, Nodes}];
+ false ->
+ [{type, Type}, {attributes, Attrs}, {index, [ValPos]},
+ {disc_only_copies, [Node1]}, {ram_copies, [Node2]},
+ {disc_copies, [Node3]}]
+ end,
+ ?match({atomic, ok}, mnesia:create_table(Tab, Schema)),
+
+ Size = 10,
+ Keys = lists:seq(1, Size),
+ Records = [{Tab, A, 7} || A <- Keys],
+ lists:foreach(fun(Rec) -> ?match(ok, mnesia:dirty_write(Rec)) end, Records),
+ ?match(Mem when is_integer(Mem), mnesia:table_info(Tab, memory)),
+ ?match(Size, mnesia:table_info(Tab, size)),
+ ?match(Type, mnesia:table_info(Tab, type)),
+
+ case mnesia_test_lib:diskless(Config) of
+ true ->
+ ?match(Nodes, mnesia:table_info(Tab, ram_copies));
+ false ->
+ ?match([Node3], mnesia:table_info(Tab, mnesia_test_lib:storage_type(disc_copies, Config))),
+ ?match([Node2], mnesia:table_info(Tab, ram_copies)),
+ ?match([Node1], mnesia:table_info(Tab, mnesia_test_lib:storage_type(disc_only_copies, Config)))
+ end,
+ Read = [Node1, Node2, Node3],
+ ?match(true, lists:member(mnesia:table_info(Tab, where_to_read), Read)),
+ Write = ?sort([Node1, Node2, Node3]),
+ ?match(Write, ?sort(mnesia:table_info(Tab, where_to_write))),
+ ?match([ValPos], mnesia:table_info(Tab, index)),
+ ?match(Arity, mnesia:table_info(Tab, arity)),
+ ?match(Attrs, mnesia:table_info(Tab, attributes)),
+ ?match({Tab, '_', '_'}, mnesia:table_info(Tab, wild_pattern)),
+ ?match({atomic, Attrs}, mnesia:transaction(fun() ->
+ mnesia:table_info(Tab, attributes) end)),
+
+ ?match(L when is_list(L), mnesia:table_info(Tab, all)),
+
+ %% Table info when table not loaded
+ ?match({atomic, ok},
+ mnesia:create_table(tab_info, Schema)),
+ ?match(stopped, mnesia:stop()),
+ ?match(stopped, rpc:call(Node2, mnesia, stop, [])),
+ ?match(ok, mnesia:start()),
+ ?match(ok, mnesia:wait_for_tables([tab_info], 5000)),
+ ?match(0, mnesia:table_info(tab_info, size)),
+ ?verify_mnesia([Node1, Node3], [Node2]).
+
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%% Check the error descriptions
+
+error_description(suite) -> [];
+error_description(Config) when is_list(Config) ->
+ ?acquire_nodes(1, Config),
+ Errors = [nested_transaction, badarg, no_transaction, combine_error,
+ bad_index, already_exists, index_exists, no_exists, system_limit,
+ mnesia_down, not_a_db_node, bad_type, node_not_running,
+ truncated_binary_file, active, illegal
+ ],
+ ?match(X when is_atom(X), mnesia:error_description({error, bad_error_msg})),
+ ?match(X when is_tuple(X), mnesia:error_description({'EXIT', pid, bad})),
+ %% This is real error msg
+ ?match(X when is_tuple(X), mnesia:error_description(
+ {error,
+ {"Cannot prepare checkpoint (bad reply)",
+ {{877,957351,758147},a@legolas},
+ {error,{node_not_running,a1@legolas}}}})),
+ check_errors(error, Errors),
+ check_errors(aborted, Errors),
+ check_errors('EXIT', Errors).
+
+check_errors(_Err, []) -> ok;
+check_errors(Err, [Desc|R]) ->
+ ?match(X when is_list(X), mnesia:error_description({Err, Desc})),
+ check_errors(Err, R).
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%% Add and drop db nodes
+
+db_node_lifecycle(suite) -> [];
+db_node_lifecycle(Config) when is_list(Config) ->
+ [Node1, Node2, Node3] = AllNodes = ?acquire_nodes(3, Config),
+ Tab = db_node_lifecycle,
+
+ Who = fun(T) ->
+ L1 = mnesia:table_info(T, ram_copies),
+ L2 = mnesia:table_info(T, disc_copies),
+ L3 = mnesia:table_info(T, disc_only_copies),
+ L1 ++ L2 ++ L3
+ end,
+
+ SNs = ?sort(AllNodes),
+
+ Schema = [{name, Tab}, {ram_copies, [Node1, Node2]}],
+ ?match({atomic, ok}, mnesia:create_table(Schema)),
+
+ ?match([], mnesia_test_lib:stop_mnesia(AllNodes)),
+ ?match(ok, mnesia:delete_schema(AllNodes)),
+ ?match({error, _}, mnesia:create_schema(foo)),
+ ?match({error, _}, mnesia:create_schema([foo])),
+ ?match({error, _}, mnesia:create_schema([foo@bar])),
+ ?match(ok, mnesia:start()),
+ ?match(false, mnesia:system_info(use_dir)),
+ ?match({atomic, ok}, mnesia:create_table(Tab, [])),
+ ?match({aborted, {has_no_disc, Node1}}, mnesia:dump_tables([Tab])),
+ ?match({aborted, {has_no_disc, Node1}}, mnesia:change_table_copy_type(Tab, node(), disc_copies)),
+ ?match({aborted, {has_no_disc, Node1}}, mnesia:change_table_copy_type(Tab, node(), disc_only_copies)),
+
+ ?match(stopped, mnesia:stop()),
+
+ ?match(ok, mnesia:create_schema(AllNodes)),
+ ?match([], mnesia_test_lib:start_mnesia(AllNodes)),
+
+ ?match([SNs, SNs, SNs],
+ lists:map({lists, sort},
+ element(1, rpc:multicall(AllNodes, mnesia, table_info,
+ [schema, disc_copies])))),
+
+ ?match({aborted, {already_exists, schema, Node2, _}},
+ mnesia:change_table_copy_type(schema, Node2, disc_copies)),
+ ?match({atomic, ok},
+ mnesia:change_table_copy_type(schema, Node2, ram_copies)),
+ ?match({aborted, {already_exists, schema, Node2, _}},
+ mnesia:change_table_copy_type(schema, Node2, ram_copies)),
+
+ ?match({atomic, ok},
+ mnesia:change_table_copy_type(schema, Node2, disc_copies)),
+
+ ?match([SNs, SNs, SNs],
+ lists:map({lists, sort},
+ element(1, rpc:multicall(AllNodes, mnesia, table_info,
+ [schema, disc_copies])))),
+
+ %% Delete the DB
+
+ Tab2 = disk_tab,
+ Tab3 = not_local,
+ Tab4 = local,
+ Tab5 = remote,
+
+ Tabs = [Schema,
+ [{name, Tab2}, {disc_copies, AllNodes}],
+ [{name, Tab3}, {ram_copies, [Node2, Node3]}],
+ [{name, Tab4}, {disc_only_copies, [Node1]}],
+ [{name, Tab5}, {disc_only_copies, [Node2]}]],
+
+ [?match({atomic, ok}, mnesia:create_table(T)) || T <- Tabs ],
+
+ ?match({aborted, {active, _, Node2}},
+ mnesia:del_table_copy(schema, Node2)),
+
+ ?match([], mnesia_test_lib:stop_mnesia([Node1])),
+ ?match({aborted, {node_not_running, Node1}},
+ mnesia:del_table_copy(schema, Node2)),
+
+ ?match([], mnesia_test_lib:start_mnesia([Node1],[Tab2,Tab4])),
+ ?match([], mnesia_test_lib:stop_mnesia([Node2])),
+ ?match({atomic, ok},
+ mnesia:del_table_copy(schema, Node2)),
+
+ %% Check
+ RemNodes = AllNodes -- [Node2],
+
+ ?match(RemNodes, mnesia:system_info(db_nodes)),
+ ?match([Node1], Who(Tab)),
+ ?match(RemNodes, Who(Tab2)),
+ ?match([Node3], Who(Tab3)),
+ ?match([Node1], Who(Tab4)),
+ ?match({'EXIT', {aborted, {no_exists, _, _}}}, Who(Tab5)),
+
+ ?match({atomic, ok},
+ mnesia:change_table_copy_type(Tab2, Node3, ram_copies)),
+
+ ?match({atomic, ok},
+ mnesia:change_table_copy_type(schema, Node3, ram_copies)),
+
+ ?match([], mnesia_test_lib:stop_mnesia([Node3])),
+ ?match({atomic, ok},
+ mnesia:del_table_copy(schema, Node3)),
+ ?match([Node1], mnesia:system_info(db_nodes)),
+ ?match([Node1], Who(Tab)),
+ ?match([Node1], Who(Tab2)),
+ ?match({'EXIT', {aborted, {no_exists, _, _}}}, Who(Tab3)),
+ ?match([Node1], Who(Tab4)),
+ ?match({'EXIT', {aborted, {no_exists, _, _}}}, Who(Tab5)),
+
+ ?verify_mnesia([Node1], []).
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%% Drop a db node when several disk resident nodes are down
+
+evil_delete_db_node(suite) -> [];
+evil_delete_db_node(Config) when is_list(Config) ->
+ [Node1, Node2, Node3] = AllNodes = ?acquire_nodes(3, Config),
+ Tab = evil_delete_db_node,
+
+ ?match({atomic, ok}, mnesia:create_table(Tab, [{disc_copies, AllNodes}])),
+
+ ?match([], mnesia_test_lib:stop_mnesia([Node2, Node3])),
+
+ ?match({atomic, ok}, mnesia:del_table_copy(schema, Node2)),
+
+ RemNodes = AllNodes -- [Node2],
+
+ ?match(RemNodes, mnesia:system_info(db_nodes)),
+ ?match(RemNodes, mnesia:table_info(Tab, disc_copies)),
+
+ ?verify_mnesia([Node1], []).
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%% Start and stop the system
+
+start_and_stop(suite) -> [];
+start_and_stop(Config) when is_list(Config) ->
+ [Node1 | _] = Nodes = ?acquire_nodes(all, Config),
+
+ ?match(stopped, rpc:call(Node1, mnesia, stop, [])),
+ ?match(stopped, rpc:call(Node1, mnesia, stop, [])),
+ ?match(ok, rpc:call(Node1, mnesia, start, [])),
+ ?match(ok, rpc:call(Node1, mnesia, start, [])),
+ ?match(stopped, rpc:call(Node1, mnesia, stop, [])),
+ ?verify_mnesia(Nodes -- [Node1], [Node1]),
+ ?match([], mnesia_test_lib:start_mnesia(Nodes)),
+ ?verify_mnesia(Nodes, []).
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%% Checkpoints and backup management
+
+checkpoint(suite) -> [];
+checkpoint(Config) when is_list(Config) ->
+ checkpoint(2, Config),
+ checkpoint(3, Config).
+
+checkpoint(NodeConfig, Config) ->
+ [Node1 | _] = TabNodes = ?acquire_nodes(NodeConfig, Config),
+ CreateTab = fun(Type, N, Ns) ->
+ Tab0 = lists:concat(["local_checkpoint_", Type, N]),
+ Tab = list_to_atom(Tab0),
+ catch mnesia:delete_table(Tab),
+ ?match({atomic, ok},
+ mnesia:create_table(Tab, [{Type, Ns}])),
+ Tab
+ end,
+ CreateTabs = fun(Type, Acc) ->
+ [CreateTab(Type, 1, [hd(TabNodes)]),
+ CreateTab(Type, 2, TabNodes),
+ CreateTab(Type, 3, [lists:last(TabNodes)])] ++
+ Acc
+ end,
+ Types = [ram_copies, disc_copies, disc_only_copies],
+ Tabs = lists:foldl(CreateTabs, [], Types),
+ Recs = ?sort([{T, N, N} || T <- Tabs, N <- lists:seq(1, 10)]),
+ lists:foreach(fun(R) -> ?match(ok, mnesia:dirty_write(R)) end, Recs),
+
+ CpName = a_checkpoint_name,
+ MinArgs = [{name, CpName}, {min, Tabs}, {allow_remote, false}],
+ ?match({error, _}, rpc:call(Node1, mnesia, activate_checkpoint, [MinArgs])),
+
+ MaxArgs = [{name, CpName}, {max, Tabs}, {allow_remote, true}],
+ ?match({ok, CpName, L} when is_list(L),
+ rpc:call(Node1, mnesia, activate_checkpoint, [MaxArgs])),
+ ?match(ok, rpc:call(Node1, mnesia, deactivate_checkpoint, [CpName])),
+
+ Args = [{name, CpName}, {min, Tabs}, {allow_remote, true}],
+ ?match({ok, CpName, L} when is_list(L),
+ rpc:call(Node1, mnesia, activate_checkpoint, [Args])),
+ Recs2 = ?sort([{T, K, 0} || {T, K, _} <- Recs]),
+ lists:foreach(fun(R) -> ?match(ok, mnesia:dirty_write(R)) end, Recs2),
+ ?match(ok, rpc:call(Node1, mnesia, deactivate_checkpoint, [CpName])),
+
+ ?match({error, Reason1 } when element(1, Reason1) == no_exists,
+ mnesia:deactivate_checkpoint(CpName)),
+ ?match({error, Reason2 } when element(1, Reason2) == badarg,
+ mnesia:activate_checkpoint(foo)),
+ ?match({error, Reason3 } when element(1, Reason3) == badarg,
+ mnesia:activate_checkpoint([{foo, foo}])),
+ ?match({error, Reason4 } when element(1, Reason4) == badarg,
+ mnesia:activate_checkpoint([{max, foo}])),
+ ?match({error, Reason5 } when element(1, Reason5) == badarg,
+ mnesia:activate_checkpoint([{min, foo}])),
+ ?match({error, _}, mnesia:activate_checkpoint([{min, [foo@bar]}])),
+ ?match({error, Reason6 } when element(1, Reason6) == badarg,
+ mnesia:activate_checkpoint([{allow_remote, foo}])),
+
+ Fun = fun(Tab) -> ?match({atomic, ok}, mnesia:delete_table(Tab)) end,
+ lists:foreach(Fun, Tabs),
+ ?verify_mnesia(TabNodes, []).
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%% Create and delete tables
+
+%% Get meta info about table
+
+-define(vrl, mnesia_test_lib:verify_replica_location).
+
+replica_location(suite) -> [];
+replica_location(Config) when is_list(Config) ->
+ [Node1, Node2, Node3] = Nodes = ?acquire_nodes(3, Config),
+ Tab = replica_location,
+
+ %% Create three replicas
+ Schema = [{name, Tab}, {disc_only_copies, [Node1]},
+ {ram_copies, [Node2]}, {disc_copies, [Node3]}],
+ ?match({atomic, ok}, mnesia:create_table(Schema)),
+ ?match([], ?vrl(Tab, [Node1], [Node2], [Node3], Nodes)),
+
+ %% Delete one replica
+ ?match({atomic, ok}, mnesia:del_table_copy(Tab, Node2)),
+ ?match([], ?vrl(Tab, [Node1], [], [Node3], Nodes)),
+
+ %% Move one replica
+ ?match({atomic, ok}, mnesia:move_table_copy(Tab, Node1, Node2)),
+ ?match([], ?vrl(Tab, [Node2], [], [Node3], Nodes)),
+
+ %% Change replica type
+ ?match({atomic, ok}, mnesia:change_table_copy_type(Tab, Node2, ram_copies)),
+ ?match([], ?vrl(Tab, [], [Node2], [Node3], Nodes)),
+
+ ?verify_mnesia(Nodes, []).
+
+table_lifecycle(suite) -> [];
+table_lifecycle(Config) when is_list(Config) ->
+ [Node1, Node2] = Nodes = ?acquire_nodes(2, Config),
+
+ ?match({atomic, ok}, mnesia:create_table([{type, bag},
+ {ram_copies, [Node1]},
+ {attributes, [rajtan, tajtan]},
+ {name, order_of_args}])),
+ ?match([], mnesia:dirty_read({order_of_args, 4711})),
+ ?match({atomic, ok}, mnesia:create_table([{name, already_exists},
+ {ram_copies, [Node1]}])),
+ ?match({aborted, Reason23 } when element(1, Reason23) ==already_exists,
+ mnesia:create_table([{name, already_exists},
+ {ram_copies, [Node1]}])),
+ ?match({aborted, Reason21 } when element(1, Reason21) == bad_type,
+ mnesia:create_table([{name, bad_node}, {ram_copies, ["foo"]}])),
+ ?match({aborted, Reason2} when element(1, Reason2) == bad_type,
+ mnesia:create_table([{name, zero_arity}, {attributes, []}])),
+ ?match({aborted, Reason3} when element(1, Reason3) == badarg,
+ mnesia:create_table([])),
+ ?match({aborted, Reason4} when element(1, Reason4) == badarg,
+ mnesia:create_table(atom)),
+ ?match({aborted, Reason5} when element(1, Reason5) == badarg,
+ mnesia:create_table({cstruct, table_name_as_atom})),
+ ?match({aborted, Reason6 } when element(1, Reason6) == bad_type,
+ mnesia:create_table([{name, no_host}, {ram_copies, foo}])),
+ ?match({aborted, Reason7 } when element(1, Reason7) == bad_type,
+ mnesia:create_table([{name, no_host}, {disc_only_copies, foo}])),
+ ?match({aborted, Reason8} when element(1, Reason8) == bad_type,
+ mnesia:create_table([{name, no_host}, {disc_copies, foo}])),
+
+ CreateFun =
+ fun() -> ?match({aborted, nested_transaction},
+ mnesia:create_table([{name, nested_trans}])), ok
+ end,
+ ?match({atomic, ok}, mnesia:transaction(CreateFun)),
+ ?match({atomic, ok}, mnesia:create_table([{name, remote_tab},
+ {ram_copies, [Node2]}])),
+
+ ?match({atomic, ok}, mnesia:create_table([{name, a_brand_new_tab},
+ {ram_copies, [Node1]}])),
+ ?match([], mnesia:dirty_read({a_brand_new_tab, 4711})),
+ ?match({atomic, ok}, mnesia:delete_table(a_brand_new_tab)),
+ ?match({'EXIT', {aborted, Reason31}} when element(1, Reason31) == no_exists,
+ mnesia:dirty_read({a_brand_new_tab, 4711})),
+ ?match({aborted, Reason41} when element(1, Reason41) == no_exists,
+ mnesia:delete_table(a_brand_new_tab)),
+ ?match({aborted, Reason9} when element(1, Reason9) == badarg,
+ mnesia:create_table([])),
+
+ ?match({atomic, ok}, mnesia:create_table([{name, nested_del_trans},
+ {ram_copies, [Node1]}])),
+
+ DeleteFun = fun() -> ?match({aborted, nested_transaction},
+ mnesia:delete_table(nested_del_trans)), ok end,
+ ?match({atomic, ok}, mnesia:transaction(DeleteFun)),
+
+ ?match({aborted, Reason10} when element(1, Reason10) == bad_type,
+ mnesia:create_table([{name, create_with_index}, {index, 2}])),
+ ?match({aborted, Reason32} when element(1, Reason32) == bad_type,
+ mnesia:create_table([{name, create_with_index}, {index, [-1]}])),
+ ?match({aborted, Reason33} when element(1, Reason33) == bad_type,
+ mnesia:create_table([{name, create_with_index}, {index, [0]}])),
+ ?match({aborted, Reason34} when element(1, Reason34) == bad_type,
+ mnesia:create_table([{name, create_with_index}, {index, [1]}])),
+ ?match({aborted, Reason35} when element(1, Reason35) == bad_type,
+ mnesia:create_table([{name, create_with_index}, {index, [2]}])),
+ ?match({atomic, ok},
+ mnesia:create_table([{name, create_with_index}, {index, [3]},
+ {ram_copies, [Node1]}])),
+ ets:new(ets_table, [named_table]),
+
+ ?match({aborted, _}, mnesia:create_table(ets_table, [{ram_copies, Nodes}])),
+
+ ?verify_mnesia(Nodes, []).
+
+add_copy_conflict(suite) -> [];
+add_copy_conflict(doc) ->
+ ["Verify that OTP-5065 doesn't happen again, whitebox testing"];
+add_copy_conflict(Config) when is_list(Config) ->
+ Nodes = [Node1, Node2] =
+ ?acquire_nodes(2, Config ++ [{tc_timeout, timer:minutes(2)}]),
+
+ ?match({atomic, ok}, mnesia:create_table(a, [{ram_copies, Nodes}])),
+ ?match({atomic, ok}, mnesia:create_table(b, [{ram_copies, Nodes}])),
+ ?match({atomic, ok}, mnesia:create_table(test, [{ram_copies, [Node2]}])),
+ mnesia:stop(),
+ ?match(ok,mnesia:start([{no_table_loaders, 1}])),
+
+ verify_ll_queue(10),
+
+ Self = self(),
+ Test = fun() ->
+ Res = mnesia:add_table_copy(test, Node1, ram_copies),
+ Self ! {test, Res}
+ end,
+ %% Create conflict with loader queue.
+ spawn_link(Test),
+ ?match_receive(timeout),
+ %% Conflict ok
+ mnesia_controller:unblock_controller(),
+
+ ?match_receive({test, {atomic,ok}}),
+
+ ?verify_mnesia(Nodes, []),
+ ?cleanup(1, Config).
+
+verify_ll_queue(0) ->
+ ?error("Couldn't find anything in queue~n",[]);
+verify_ll_queue(N) ->
+ ?match(granted,mnesia_controller:block_controller()),
+ case mnesia_controller:get_info(1000) of
+ {info,{state,_,true,[],_Loader,[],[],[],_,_,_,_,_,_}} ->
+ %% Very slow SMP machines havn't loaded it yet..
+ mnesia_controller:unblock_controller(),
+ timer:sleep(10),
+ verify_ll_queue(N-1);
+ {info,{state,_,true,[],Loader,LL,[],[],_,_,_,_,_,_}} ->
+ io:format("~p~n", [{Loader,LL}]),
+ ?match([_], LL); %% Verify that something is in the loader queue
+ Else ->
+ ?error("No match ~p maybe the internal format has changed~n",[Else])
+ end.
+
+add_copy_when_going_down(suite) -> [];
+add_copy_when_going_down(doc) ->
+ ["Tests abort when node we load from goes down"];
+add_copy_when_going_down(Config) ->
+ [Node1, Node2] =
+ ?acquire_nodes(2, Config ++ [{tc_timeout, timer:minutes(2)}]),
+ ?match({atomic, ok}, mnesia:create_table(a, [{ram_copies, [Node1]}])),
+ %% Grab a write lock
+ WriteAndWait = fun() ->
+ mnesia:write({a,1,1}),
+ receive continue -> ok
+ end
+ end,
+ _Lock = spawn(fun() -> mnesia:transaction(WriteAndWait) end),
+ Tester = self(),
+ spawn_link(fun() -> Res = rpc:call(Node2,mnesia, add_table_copy,
+ [a, Node2, ram_copies]),
+ Tester ! {test, Res}
+ end),
+ %% We have a lock here we should get a timeout
+ ?match_receive(timeout),
+ mnesia_test_lib:kill_mnesia([Node1]),
+ ?match_receive({test,{aborted,_}}),
+ ?verify_mnesia([Node2], []).
+
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%% Add, drop and move replicas, change storage types
+%% Change table layout (only arity change supported)
+
+-record(replica_management, {k, v}).
+-record(new_replica_management, {k, v, extra}).
+
+-define(SS(R), lists:sort(element(1,R))).
+
+replica_management(doc) ->
+ "Add, drop and move replicas, change storage types.";
+replica_management(suite) ->
+ [];
+replica_management(Config) when is_list(Config) ->
+ %% add_table_copy/3, del_table_copy/2, move_table_copy/3,
+ %% change_table_copy_type/3, transform_table/3
+
+ Nodes = [Node1, Node2, Node3] = ?acquire_nodes(3, Config),
+
+ Tab = replica_management,
+ Attrs = record_info(fields, replica_management),
+
+ %%
+ %% Add, delete and change replicas
+ %%
+ ?match({atomic, ok},
+ mnesia:create_table([{name, Tab}, {attributes, Attrs},
+ {ram_copies, [Node1, Node3]}])),
+ [?match(ok, mnesia:dirty_write({Tab, K, K + 2})) || K <-lists:seq(1, 10)],
+ ?match([], ?vrl(Tab, [], [Node1, Node3], [], Nodes)),
+ %% R - -
+ ?match({atomic, ok}, mnesia:dump_tables([Tab])),
+ ?match({aborted, Reason50 } when element(1, Reason50) == combine_error,
+ mnesia:add_table_copy(Tab, Node2, disc_copies)),
+ ?match({aborted, Reason51 } when element(1, Reason51) == combine_error,
+ mnesia:change_table_copy_type(Tab, Node1, disc_copies)),
+ ?match({atomic, ok}, mnesia:clear_table(Tab)),
+ SyncedCheck = fun() ->
+ mnesia:lock({record,Tab,0}, write),
+ ?match([0,0,0], ?SS(rpc:multicall(Nodes, mnesia, table_info, [Tab, size])))
+ end,
+ mnesia:transaction(SyncedCheck),
+
+ ?match({[0,0,0], []}, rpc:multicall(Nodes, mnesia, table_info, [Tab, size])),
+ ?match({atomic, ok}, mnesia:del_table_copy(Tab, Node1)),
+ ?match({atomic, ok}, mnesia:del_table_copy(Tab, Node3)),
+ ?match([], ?vrl(Tab, [], [], [], Nodes)),
+ %% - - -
+ ?match({aborted,Reason52} when element(1, Reason52) == no_exists,
+ mnesia:add_table_copy(Tab, Node3, ram_copies)),
+
+ ?match({atomic, ok}, mnesia:create_table([{name, Tab},
+ {attributes, Attrs},
+ {disc_copies, [Node1]}])),
+ ?match([], ?vrl(Tab, [], [], [Node1], Nodes)),
+ %% D - -
+ [?match(ok, mnesia:dirty_write({Tab, K, K + 2})) || K <-lists:seq(1, 10)],
+
+ ?match({aborted, Reason53} when element(1, Reason53) == badarg,
+ mnesia:add_table_copy(Tab, Node2, bad_storage_type)),
+ ?match({atomic, ok}, mnesia:add_table_copy(Tab, Node2, disc_only_copies)),
+ ?match([], ?vrl(Tab, [Node2], [], [Node1], Nodes)),
+ ?match([0,10,10], ?SS(rpc:multicall(Nodes, mnesia, table_info, [Tab, size]))),
+ %% D DO -
+ ?match({atomic, ok}, mnesia:add_table_copy(Tab, Node3, ram_copies)),
+ ?match([], ?vrl(Tab, [Node2], [Node3], [Node1], Nodes)),
+ ?match([10,10,10], ?SS(rpc:multicall(Nodes, mnesia, table_info, [Tab, size]))),
+ %% D DO R
+ ?match({atomic, ok},
+ mnesia:change_table_copy_type(Tab, Node1, disc_only_copies)),
+ ?match([], ?vrl(Tab, [Node1, Node2], [Node3], [], Nodes)),
+ ?match([10,10,10], ?SS(rpc:multicall(Nodes, mnesia, table_info, [Tab, size]))),
+ %% DO DO R
+ ?match({aborted, Reason54} when element(1, Reason54) == already_exists,
+ mnesia:add_table_copy(Tab, Node3, ram_copies)),
+ ?match({atomic, ok}, mnesia:del_table_copy(Tab, Node1)),
+ ?match([], ?vrl(Tab, [Node2], [Node3], [], Nodes)),
+ %% - DO R
+ ?match({aborted, _}, mnesia:del_table_copy(Tab, Node1)),
+ ?match(Tab, ets:new(Tab, [named_table])),
+ ?match({aborted, _}, mnesia:add_table_copy(Tab, Node1, disc_copies)),
+ ?match(true, ets:delete(Tab)),
+ ?match({atomic, ok}, mnesia:add_table_copy(Tab, Node1, disc_copies)),
+ ?match([], ?vrl(Tab, [Node2], [Node3], [Node1], Nodes)),
+ ?match([10,10,10], ?SS(rpc:multicall(Nodes, mnesia, table_info, [Tab, size]))),
+ %% D DO R
+ ?match({atomic, ok},mnesia:change_table_copy_type(Tab, Node3, disc_only_copies)),
+ ?match([], ?vrl(Tab, [Node2, Node3], [], [Node1], Nodes)),
+ ?match([10,10,10], ?SS(rpc:multicall(Nodes, mnesia, table_info, [Tab, size]))),
+
+ %% D DO D0
+ ?match({atomic, ok}, mnesia:change_table_copy_type(Tab, Node3, ram_copies)),
+ ?match([], ?vrl(Tab, [Node2], [Node3], [Node1], Nodes)),
+ ?match([10,10,10], ?SS(rpc:multicall(Nodes, mnesia, table_info, [Tab, size]))),
+ %% D DO R
+ ?match({atomic, ok},
+ mnesia:change_table_copy_type(Tab, Node2, disc_copies)),
+ ?match([], ?vrl(Tab, [], [Node3], [Node1,Node2], Nodes)),
+ ?match([10,10,10], ?SS(rpc:multicall(Nodes, mnesia, table_info, [Tab, size]))),
+
+ %% D D R
+ ?match({atomic, ok}, mnesia:change_table_copy_type(Tab, Node1, disc_only_copies)),
+ ?match([], ?vrl(Tab, [Node1], [Node3], [Node2], Nodes)),
+ ?match([10,10,10], ?SS(rpc:multicall(Nodes, mnesia, table_info, [Tab, size]))),
+
+ %% DO D R
+ ?match(Tab, ets:new(Tab, [named_table])),
+ ?match({aborted, _}, mnesia:change_table_copy_type(Tab, Node1, ram_copies)),
+ ?match(true, ets:delete(Tab)),
+ ?match({atomic, ok}, mnesia:change_table_copy_type(Tab, Node1, ram_copies)),
+ ?match([], ?vrl(Tab, [], [Node3,Node1], [Node2], Nodes)),
+ ?match([10,10,10], ?SS(rpc:multicall(Nodes, mnesia, table_info, [Tab, size]))),
+ %% R D R
+ ?match({atomic, ok}, mnesia:change_table_copy_type(Tab, Node1, disc_copies)),
+ ?match([], ?vrl(Tab, [], [Node3], [Node2,Node1], Nodes)),
+ ?match([10,10,10], ?SS(rpc:multicall(Nodes, mnesia, table_info, [Tab, size]))),
+
+ %% D D R
+ ?match({atomic, ok}, mnesia:change_table_copy_type(Tab, Node2, disc_only_copies)),
+ ?match([], ?vrl(Tab, [Node2], [Node3], [Node1], Nodes)),
+ ?match([10,10,10], ?SS(rpc:multicall(Nodes, mnesia, table_info, [Tab, size]))),
+
+ %% D DO R
+ ?match({atomic, ok}, mnesia:change_table_copy_type(Tab, Node3, disc_only_copies)),
+ ?match([], ?vrl(Tab, [Node2, Node3], [], [Node1], Nodes)),
+ ?match([10,10,10], ?SS(rpc:multicall(Nodes, mnesia, table_info, [Tab, size]))),
+ %% D DO DO
+ %% test clear
+ ?match({atomic, ok}, mnesia:clear_table(Tab)),
+ mnesia:transaction(SyncedCheck),
+
+ %% rewrite for rest of testcase
+ [?match(ok, mnesia:dirty_write({Tab, K, K + 2})) || K <-lists:seq(1, 10)],
+
+ %% D DO DO
+ ?match({atomic, ok}, mnesia:del_table_copy(Tab, Node2)),
+ ?match([], ?vrl(Tab, [Node3], [], [Node1], Nodes)),
+ %% D - DO
+ ?match({aborted, Reason55} when element(1, Reason55) == already_exists,
+ mnesia:change_table_copy_type(Tab, Node1, disc_copies)),
+
+ %%
+ %% Move replica
+ %%
+ ?match({atomic, ok}, mnesia:move_table_copy(Tab, Node1, Node2)),
+ ?match([], ?vrl(Tab, [Node3], [], [Node2], Nodes)),
+ ?match([0,10,10], ?SS(rpc:multicall(Nodes, mnesia, table_info, [Tab, size]))),
+ %% - D DO
+ ?match({aborted, _}, mnesia:move_table_copy(Tab, Node1, Node2)),
+ ?match([], mnesia_test_lib:stop_mnesia([Node3])),
+ ?match({atomic,ok}, mnesia:transaction(fun() -> mnesia:write({Tab, 43, sync_me}) end)),
+ ?match([], ?vrl(Tab, [Node3], [], [Node2],Nodes -- [Node3])),
+ %% - D DO
+ ?match({aborted,Reason56} when element(1, Reason56) == not_active,
+ mnesia:move_table_copy(Tab, Node3, Node1)),
+ ?match([], ?vrl(Tab, [Node3], [], [Node2],Nodes -- [Node3])),
+ %% DO D -
+ ?match([], mnesia_test_lib:start_mnesia([Node3])),
+ ?match([], ?vrl(Tab, [Node3], [], [Node2], Nodes)),
+ %% DO D -
+
+ %%
+ %% Transformer
+ %%
+
+ NewAttrs = record_info(fields, new_replica_management),
+ Transformer =
+ fun(Rec) when is_record(Rec, replica_management) ->
+ #new_replica_management{k = Rec#replica_management.k,
+ v = Rec#replica_management.v,
+ extra = Rec#replica_management.k * 2}
+ end,
+ ?match({atomic, ok}, mnesia:transform_table(Tab, fun(R) -> R end, Attrs)),
+ ?match({atomic, ok}, mnesia:transform_table(Tab, Transformer, NewAttrs, new_replica_management)),
+
+ ERlist = [#new_replica_management{k = K, v = K+2, extra = K*2} || K <- lists:seq(1, 10)],
+ ARlist = [hd(mnesia:dirty_read(Tab, K)) || K <- lists:seq(1, 10)],
+
+ ?match(ERlist, ARlist),
+
+ ?match({aborted, Reason56} when element(1, Reason56) == bad_type,
+ mnesia:transform_table(Tab, Transformer, 0)),
+ ?match({aborted, Reason57} when element(1, Reason57) == bad_type,
+ mnesia:transform_table(Tab, Transformer, -1)),
+ ?match({aborted, Reason58} when element(1, Reason58) == bad_type,
+ mnesia:transform_table(Tab, Transformer, [])),
+ ?match({aborted, Reason59} when element(1, Reason59) == bad_type,
+ mnesia:transform_table(Tab, no_fun, NewAttrs)),
+ ?match({aborted, Reason59} when element(1, Reason59) == bad_type,
+ mnesia:transform_table(Tab, fun(X) -> X end, NewAttrs, {tuple})),
+
+ %% OTP-3878
+ ?match({atomic, ok}, mnesia:transform_table(Tab, ignore,
+ NewAttrs ++ [dummy])),
+ ?match({atomic, ok}, mnesia:transform_table(Tab, ignore,
+ NewAttrs ++ [dummy], last_rec)),
+
+ ARlist = [hd(mnesia:dirty_read(Tab, K)) || K <- lists:seq(1, 10)],
+ ?match({'EXIT',{aborted,{bad_type,_}}},
+ mnesia:dirty_write(Tab, #new_replica_management{})),
+ ?match(ok, mnesia:dirty_write(Tab, {last_rec, k, v, e, dummy})),
+
+ ?verify_mnesia(Nodes, []).
+
+schema_availability(doc) ->
+ ["Test that schema succeeds (or fails) as intended when some db nodes are down."];
+schema_availability(suite) ->
+ [];
+schema_availability(Config) when is_list(Config) ->
+ [N1, _N2, N3] = Nodes = ?acquire_nodes(3, Config),
+ Tab = schema_availability,
+ Storage = mnesia_test_lib:storage_type(ram_copies, Config),
+ Def1 = [{Storage, [N1, N3]}],
+ ?match({atomic, ok}, mnesia:create_table(Tab, Def1)),
+
+ N = 10,
+ ?match(ok, mnesia:sync_dirty(fun() -> [mnesia:write({Tab, K, K + 2}) || K <- lists:seq(1, N)], ok end)),
+ ?match({[N,0,N], []}, rpc:multicall(Nodes, mnesia, table_info, [Tab, size])),
+ ?match([], mnesia_test_lib:kill_mnesia([N3])),
+ ?match({[N,0,0], []}, rpc:multicall(Nodes, mnesia, table_info, [Tab, size])),
+
+ ?match([], mnesia_test_lib:start_mnesia([N3], [Tab])),
+ ?match({[N,0,N], []}, rpc:multicall(Nodes, mnesia, table_info, [Tab, size])),
+ ?match([], mnesia_test_lib:kill_mnesia([N3])),
+
+ ?match({atomic, ok}, mnesia:clear_table(Tab)),
+ ?match({[0,0,0], []}, rpc:multicall(Nodes, mnesia, table_info, [Tab, size])),
+
+ ?match([], mnesia_test_lib:start_mnesia([N3], [Tab])),
+ ?match({[0,0,0], []}, rpc:multicall(Nodes, mnesia, table_info, [Tab, size])),
+
+ ?verify_mnesia(Nodes, []).
+
+-define(badrpc(Tab), {badrpc, {'EXIT', {aborted,{no_exists,Tab}}}}).
+
+local_content(doc) ->
+ ["Test local_content functionality, we want to see that correct"
+ " properties gets propageted correctly between nodes"];
+local_content(suite) -> [];
+local_content(Config) when is_list(Config) ->
+ [Node1, Node2, Node3] = Nodes = ?acquire_nodes(3, Config),
+ Tab1 = local1,
+ Def1 = [{local_content, true}, {ram_copies, Nodes}],
+ Tab2 = local2,
+ Def2 = [{local_content, true}, {disc_copies, [Node1]}],
+ Tab3 = local3,
+ Def3 = [{local_content, true}, {disc_only_copies, [Node1]}],
+ Tab4 = local4,
+ Def4 = [{local_content, true}, {ram_copies, [Node1]}],
+
+ ?match({atomic, ok}, mnesia:create_table(Tab1, Def1)),
+ ?match({atomic, ok}, mnesia:create_table(Tab2, Def2)),
+ ?match({atomic, ok}, mnesia:create_table(Tab3, Def3)),
+ ?match({atomic, ok}, mnesia:create_table(Tab4, Def4)),
+
+ ?match(ok, rpc:call(Node1, mnesia, dirty_write, [{Tab1, 1, Node1}])),
+ ?match(ok, rpc:call(Node2, mnesia, dirty_write, [{Tab1, 1, Node2}])),
+ ?match(ok, rpc:call(Node3, mnesia, dirty_write, [{Tab1, 1, Node3}])),
+ ?match(ok, rpc:call(Node1, mnesia, dirty_write, [{Tab2, 1, Node1}])),
+ ?match(ok, rpc:call(Node1, mnesia, dirty_write, [{Tab3, 1, Node1}])),
+ ?match(ok, rpc:call(Node1, mnesia, dirty_write, [{Tab4, 1, Node1}])),
+
+ ?match(?badrpc(Tab2), rpc:call(Node2, mnesia, dirty_write, [{Tab2, 1, Node2}])),
+ ?match(?badrpc(Tab3), rpc:call(Node2, mnesia, dirty_write, [{Tab3, 1, Node2}])),
+ ?match(?badrpc(Tab4), rpc:call(Node2, mnesia, dirty_write, [{Tab4, 1, Node2}])),
+
+ ?match({atomic, ok}, rpc:call(Node1, mnesia, add_table_copy, [Tab2, Node2, ram_copies])),
+ ?match({atomic, ok}, rpc:call(Node2, mnesia, add_table_copy, [Tab3, Node2, disc_copies])),
+ ?match({atomic, ok}, rpc:call(Node3, mnesia, add_table_copy, [Tab4, Node2, disc_only_copies])),
+ ?match([], rpc:call(Node2, mnesia, dirty_read, [{Tab2, 1}])),
+ ?match([], rpc:call(Node2, mnesia, dirty_read, [{Tab3, 1}])),
+ ?match([], rpc:call(Node2, mnesia, dirty_read, [{Tab4, 1}])),
+
+ ?match(ok, rpc:call(Node2, mnesia, dirty_write, [{Tab2, 1, Node2}])),
+ ?match(ok, rpc:call(Node2, mnesia, dirty_write, [{Tab3, 1, Node2}])),
+ ?match(ok, rpc:call(Node2, mnesia, dirty_write, [{Tab4, 1, Node2}])),
+
+ ?match([{Tab1, 1, Node1}], rpc:call(Node1, mnesia, dirty_read, [{Tab1, 1}])),
+ ?match([{Tab2, 1, Node1}], rpc:call(Node1, mnesia, dirty_read, [{Tab2, 1}])),
+ ?match([{Tab3, 1, Node1}], rpc:call(Node1, mnesia, dirty_read, [{Tab3, 1}])),
+ ?match([{Tab4, 1, Node1}], rpc:call(Node1, mnesia, dirty_read, [{Tab4, 1}])),
+
+ ?match([{Tab1, 1, Node2}], rpc:call(Node2, mnesia, dirty_read, [{Tab1, 1}])),
+ ?match([{Tab2, 1, Node2}], rpc:call(Node2, mnesia, dirty_read, [{Tab2, 1}])),
+ ?match([{Tab3, 1, Node2}], rpc:call(Node2, mnesia, dirty_read, [{Tab3, 1}])),
+ ?match([{Tab4, 1, Node2}], rpc:call(Node2, mnesia, dirty_read, [{Tab4, 1}])),
+
+ ?match([{Tab1, 1, Node3}], rpc:call(Node3, mnesia, dirty_read, [{Tab1, 1}])),
+ ?match(?badrpc([_Tab2, 1]), rpc:call(Node3, mnesia, dirty_read, [{Tab2, 1}])),
+ ?match(?badrpc([_Tab3, 1]), rpc:call(Node3, mnesia, dirty_read, [{Tab3, 1}])),
+ ?match(?badrpc([_Tab4, 1]), rpc:call(Node3, mnesia, dirty_read, [{Tab4, 1}])),
+
+ ?match({atomic, ok},
+ mnesia:change_table_copy_type(schema, Node3, ram_copies)),
+ ?match([], mnesia_test_lib:stop_mnesia([Node3])),
+
+ %% Added for OTP-44306
+ ?match(ok, rpc:call(Node3, mnesia, start, [])),
+ ?match({ok, _}, mnesia:change_config(extra_db_nodes, [Node3])),
+
+ mnesia_test_lib:sync_tables([Node3], [Tab1]),
+
+ ?match([], rpc:call(Node3, mnesia, dirty_read, [{Tab1, 1}])),
+
+ ?match({atomic, ok}, rpc:call(Node1, mnesia, clear_table, [Tab1])),
+
+ SyncedCheck = fun(Tab) ->
+ mnesia:lock({record,Tab,0}, write),
+ {OK, []} = rpc:multicall(Nodes, mnesia, table_info, [Tab, size]),
+ OK
+ end,
+ ?match({atomic, [0,1,0]}, mnesia:transaction(SyncedCheck, [Tab1])),
+ ?match({atomic, ok}, rpc:call(Node2, mnesia, clear_table, [Tab2])),
+ ?match({atomic, [1,0,0]}, mnesia:transaction(SyncedCheck, [Tab2])),
+ ?match({atomic, ok}, rpc:call(Node2, mnesia, clear_table, [Tab3])),
+ ?match({atomic, [1,0,0]}, mnesia:transaction(SyncedCheck, [Tab3])),
+
+ ?verify_mnesia(Nodes, []).
+
+table_access_modifications(suite) ->
+ [
+ change_table_access_mode,
+ change_table_load_order,
+ set_master_nodes,
+ offline_set_master_nodes
+ ].
+
+change_table_access_mode(suite) -> [];
+change_table_access_mode(Config) when is_list(Config) ->
+ [Node1, Node2, Node3] = Nodes = ?acquire_nodes(3, Config),
+ Tab = test_access_mode_tab,
+
+ Def = case mnesia_test_lib:diskless(Config) of
+ true -> [{name, Tab}, {ram_copies, Nodes}];
+ false -> [{name, Tab}, {ram_copies, [Node1]},
+ {disc_copies, [Node2]},
+ {disc_only_copies, [Node3]}]
+ end,
+ ?match({atomic, ok}, mnesia:create_table(Def)),
+
+ Write = fun(What) -> mnesia:write({Tab, 1, What}) end,
+ Read = fun() -> mnesia:read({Tab, 1}) end,
+
+ ?match({atomic, ok}, mnesia:transaction(Write, [test_ok])),
+ %% test read_only
+ ?match({atomic, ok}, mnesia:change_table_access_mode(Tab, read_only)),
+ ?match({aborted, _}, mnesia:transaction(Write, [nok])),
+ ?match({'EXIT', {aborted, _}}, mnesia:dirty_write({Tab, 1, [nok]})),
+ ?match({aborted, _}, rpc:call(Node2, mnesia, transaction, [Write, [nok]])),
+ ?match({aborted, _}, rpc:call(Node3, mnesia, transaction, [Write, [nok]])),
+ ?match({atomic, [{Tab, 1, test_ok}]}, mnesia:transaction(Read)),
+ %% test read_write
+ ?match({atomic, ok}, mnesia:change_table_access_mode(Tab, read_write)),
+ ?match({atomic, ok}, mnesia:transaction(Write, [test_ok1])),
+ ?match({atomic, [{Tab, 1, test_ok1}]}, mnesia:transaction(Read)),
+ ?match({atomic, ok}, rpc:call(Node2, mnesia, transaction, [Write, [test_ok2]])),
+ ?match({atomic, [{Tab, 1, test_ok2}]}, mnesia:transaction(Read)),
+ ?match({atomic, ok}, rpc:call(Node3, mnesia, transaction, [Write, [test_ok3]])),
+ ?match({atomic, [{Tab, 1, test_ok3}]}, mnesia:transaction(Read)),
+
+ ?match({atomic, ok}, mnesia:delete_table(Tab)),
+
+ Def4 = [{name, Tab}, {access_mode, read_only_bad}],
+ ?match({aborted, {bad_type, _, _}}, mnesia:create_table(Def4)),
+
+ Def2 = [{name, Tab}, {access_mode, read_only}],
+ ?match({atomic, ok}, mnesia:create_table(Def2)),
+ ?match({aborted, _}, mnesia:transaction(Write, [nok])),
+
+ ?match({atomic, ok}, mnesia:change_table_access_mode(Tab, read_write)),
+ ?match({atomic, ok}, mnesia:delete_table(Tab)),
+
+ Def3 = [{name, Tab}, {mnesia_test_lib:storage_type(disc_copies, Config),
+ [Node1, Node2]},
+ {access_mode, read_write}],
+ ?match({atomic, ok}, mnesia:create_table(Def3)),
+ ?match({atomic, ok}, mnesia:transaction(Write, [ok])),
+ ?match({atomic, ok}, mnesia:change_table_access_mode(Tab, read_only)),
+ ?match({aborted, _}, mnesia:del_table_copy(Tab, Node2)),
+ ?match({aborted, _}, mnesia:del_table_copy(Tab, Node1)),
+ ?match({aborted, _}, mnesia:delete_table(Tab)),
+ ?match({atomic, ok}, mnesia:change_table_access_mode(Tab, read_write)),
+
+ ?match({aborted, {bad_type, _, _}},
+ mnesia:change_table_access_mode(Tab, strange_atom)),
+ ?match({atomic, ok}, mnesia:delete_table(Tab)),
+
+ ?match({aborted, {no_exists, _}},
+ mnesia:change_table_access_mode(err_tab, read_only)),
+ ?match({aborted, {no_exists, _}},
+ mnesia:change_table_access_mode([Tab], read_only)),
+ ?verify_mnesia(Nodes, []).
+
+change_table_load_order(suite) -> [];
+change_table_load_order(Config) when is_list(Config) ->
+ [Node1, Node2, Node3] = Nodes = ?acquire_nodes(3, Config),
+ Tab1 = load_order_tab1,
+ Tab2 = load_order_tab2,
+ Tab3 = load_order_tab3,
+
+ Def = case mnesia_test_lib:diskless(Config) of
+ true -> [{ram_copies, Nodes}];
+ false ->
+ [{ram_copies, [Node1]},
+ {disc_copies, [Node2]},
+ {disc_only_copies, [Node3]}]
+ end,
+ ?match({atomic, ok}, mnesia:create_table(Tab1, Def)),
+ ?match({atomic, ok}, mnesia:create_table(Tab2, Def)),
+ ?match({atomic, ok}, mnesia:create_table(Tab3, Def)),
+
+ ?match({aborted, _}, mnesia:change_table_load_order(Tab1, should_be_integer)),
+ ?match({aborted, _}, mnesia:change_table_load_order(err_tab, 5)),
+ ?match({aborted, _}, mnesia:change_table_load_order([err_tab], 5)),
+ ?match({atomic, ok}, mnesia:change_table_load_order(Tab1, 5)),
+ ?match({atomic, ok}, mnesia:change_table_load_order(Tab2, 4)),
+ ?match({atomic, ok}, mnesia:change_table_load_order(Tab3, 73)),
+
+ ?match({aborted, _}, mnesia:change_table_load_order(schema, -32)),
+
+ ?verify_mnesia(Nodes, []).
+
+set_master_nodes(suite) -> [];
+set_master_nodes(Config) when is_list(Config) ->
+ [Node1, Node2, Node3] = Nodes = ?acquire_nodes(3, Config),
+ Tab1 = master_node_tab1,
+ Tab2 = master_node_tab2,
+ Tab3 = master_node_tab3,
+ Def1 = [{ram_copies, [Node1, Node2]}],
+ Def2 = [{disc_copies, [Node2, Node3]}],
+ Def3 = [{disc_only_copies, [Node3, Node1]}],
+ ?match({atomic, ok}, mnesia:create_table(Tab1, Def1)),
+ ?match({atomic, ok}, mnesia:create_table(Tab2, Def2)),
+ ?match({atomic, ok}, mnesia:create_table(Tab3, Def3)),
+
+ ?match({error, _}, mnesia:set_master_nodes(schema, ['[email protected]'])),
+ ?match({error, _}, mnesia:set_master_nodes(badtab, [Node2, Node3])),
+ ?match({error, _}, mnesia:set_master_nodes(Tab1, [Node3])),
+ ?match([], mnesia:table_info(Tab1, master_nodes)),
+
+ ?match(ok, mnesia:set_master_nodes(schema, [Node3, Node1])),
+ ?match([Node3, Node1], mnesia:table_info(schema, master_nodes)),
+ ?match(ok, mnesia:set_master_nodes(Tab1, [Node2])),
+ ?match([Node2], mnesia:table_info(Tab1, master_nodes)),
+ ?match(ok, mnesia:set_master_nodes(Tab1, [Node2, Node1])),
+ ?match([Node2, Node1], mnesia:table_info(Tab1, master_nodes)),
+ ?match(ok, mnesia:set_master_nodes(Tab2, [Node2])), % Should set where_to_read to Node2!
+ ?match([Node2], mnesia:table_info(Tab2, master_nodes)),
+ ?match(ok, mnesia:set_master_nodes(Tab3, [Node3])),
+ ?match([Node3], mnesia:table_info(Tab3, master_nodes)),
+ ?match(ok, mnesia:set_master_nodes(Tab3, [])),
+ ?match([], mnesia:table_info(Tab3, master_nodes)),
+
+ ?match(ok, mnesia:set_master_nodes([Node1])),
+ ?match([Node1], mnesia:table_info(schema, master_nodes)),
+ ?match([Node1], mnesia:table_info(Tab1, master_nodes)),
+ ?match([], mnesia:table_info(Tab2, master_nodes)),
+ ?match([Node1], mnesia:table_info(Tab3, master_nodes)),
+
+ ?match(ok, mnesia:set_master_nodes([Node1, Node2])),
+ ?match([Node1, Node2], mnesia:table_info(schema, master_nodes)),
+ ?match([Node1, Node2], mnesia:table_info(Tab1, master_nodes)),
+ ?match([Node2], mnesia:table_info(Tab2, master_nodes)),
+ ?match([Node1], mnesia:table_info(Tab3, master_nodes)),
+
+ ?verify_mnesia(Nodes, []).
+
+offline_set_master_nodes(suite) -> [];
+offline_set_master_nodes(Config) when is_list(Config) ->
+ [Node] = Nodes = ?acquire_nodes(1, Config),
+ Tab1 = offline_master_node_tab1,
+ Tab2 = offline_master_node_tab2,
+ Tab3 = offline_master_node_tab3,
+ Tabs = ?sort([Tab1, Tab2, Tab3]),
+ Def1 = [{ram_copies, [Node]}],
+ Def2 = [{disc_copies, [Node]}],
+ Def3 = [{disc_only_copies, [Node]}],
+ ?match({atomic, ok}, mnesia:create_table(Tab1, Def1)),
+ ?match({atomic, ok}, mnesia:create_table(Tab2, Def2)),
+ ?match({atomic, ok}, mnesia:create_table(Tab3, Def3)),
+ ?match([], mnesia:system_info(master_node_tables)),
+ ?match([], mnesia_test_lib:stop_mnesia([Node])),
+
+ ?match(ok, mnesia:set_master_nodes(Tab1, [Node])),
+ ?match(ok, mnesia:set_master_nodes(Tab2, [Node])),
+ ?match(ok, mnesia:set_master_nodes(Tab3, [Node])),
+ ?match([], mnesia_test_lib:start_mnesia([Node])),
+ ?match(Tabs, ?sort(mnesia:system_info(master_node_tables))),
+
+ ?match([], mnesia_test_lib:stop_mnesia([Node])),
+ ?match(ok, mnesia:set_master_nodes(Tab1, [])),
+ ?match(ok, mnesia:set_master_nodes(Tab2, [])),
+ ?match(ok, mnesia:set_master_nodes(Tab3, [])),
+ ?match([], mnesia_test_lib:start_mnesia([Node])),
+ ?match([], mnesia:system_info(master_node_tables)),
+
+ ?match([], mnesia_test_lib:stop_mnesia([Node])),
+ ?match(ok, mnesia:set_master_nodes([Node])),
+ ?match([], mnesia_test_lib:start_mnesia([Node])),
+ AllTabs = ?sort([schema | Tabs]),
+ ?match(AllTabs, ?sort(mnesia:system_info(master_node_tables))),
+
+ ?match([], mnesia_test_lib:stop_mnesia([Node])),
+ ?match(ok, mnesia:set_master_nodes([])),
+ ?match([], mnesia_test_lib:start_mnesia([Node])),
+ ?match([], mnesia:system_info(master_node_tables)),
+
+ ?verify_mnesia(Nodes, []).
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%% Syncronize table with log or disc
+%%
+table_sync(suite) ->
+ [
+ dump_tables,
+ dump_log,
+ wait_for_tables,
+ force_load_table
+ ].
+
+%% Dump ram tables on disc
+dump_tables(suite) -> [];
+dump_tables(Config) when is_list(Config) ->
+ [Node1, Node2] = Nodes = ?acquire_nodes(2, Config),
+ Tab = dump_tables,
+ Schema = [{name, Tab}, {attributes, [k, v]}, {ram_copies, [Node2]}],
+ ?match({atomic, ok}, mnesia:create_table(Schema)),
+
+ %% Dump 10 records
+ Size = 10,
+ Keys = lists:seq(1, Size),
+ Records = [{Tab, A, 7} || A <- Keys],
+ lists:foreach(fun(Rec) -> ?match(ok, mnesia:dirty_write(Rec)) end, Records),
+
+ AllKeys = fun() -> ?sort(mnesia:all_keys(Tab)) end,
+
+ ?match({atomic, Keys}, mnesia:transaction(AllKeys)),
+ ?match({atomic, ok}, mnesia:dump_tables([Tab])),
+
+ %% Delete one record
+ ?match(ok, mnesia:dirty_delete({Tab, 5})),
+ Keys2 = lists:delete(5, Keys),
+
+ ?match({atomic, Keys2}, mnesia:transaction(AllKeys)),
+
+ %% Check that all 10 is restored after a stop
+ ?match([], mnesia_test_lib:stop_mnesia([Node1, Node2])),
+ ?match([], mnesia_test_lib:start_mnesia([Node1, Node2])),
+ ?match(ok, mnesia:wait_for_tables([Tab], infinity)),
+
+ ?match({atomic, Keys}, mnesia:transaction(AllKeys)),
+
+ ?match({aborted,Reason} when element(1, Reason) == no_exists,
+ mnesia:dump_tables([foo])),
+ ?verify_mnesia(Nodes, []).
+
+dump_log(suite) -> [];
+dump_log(Config) when is_list(Config) ->
+ [Node1, Node2] = Nodes = ?acquire_nodes(2, Config),
+ Tab = dump_log,
+ Schema = [{name, Tab}, {attributes, [k, v]}, {ram_copies, [Node1, Node2]}],
+ ?match({atomic, ok}, mnesia:create_table(Schema)),
+ Tab1 = dump_log1,
+ Schema1 = [{name, Tab1}, {attributes, [k, v]}, {disc_copies, [Node1]}],
+ ?match({atomic, ok}, mnesia:create_table(Schema1)),
+ Tab2 = dump_log2,
+ Schema2 = [{name, Tab2}, {attributes, [k, v]}, {disc_only_copies, [Node1]}],
+ ?match({atomic, ok}, mnesia:create_table(Schema2)),
+
+ ?match(ok, mnesia:dirty_write({Tab, 1, ok})),
+ ?match(ok, mnesia:dirty_write({Tab1, 1, ok})),
+ ?match(ok, mnesia:dirty_write({Tab2, 1, ok})),
+
+ ?match(dumped, mnesia:dump_log()),
+ ?match(dumped, rpc:call(Node2, mnesia, dump_log, [])),
+
+ ?match({atomic, ok}, mnesia:change_table_copy_type(schema, Node2, ram_copies)),
+ ?match(dumped, rpc:call(Node2, mnesia, dump_log, [])),
+
+ Self = self(),
+ spawn(fun() -> dump_log(100, Self) end),
+ spawn(fun() -> dump_log(100, Self) end),
+
+ ?match(ok, receive finished -> ok after 3000 -> timeout end),
+ ?match(ok, receive finished -> ok after 3000 -> timeout end),
+
+ ?verify_mnesia(Nodes, []).
+
+dump_log(N, Tester) when N > 0 ->
+ mnesia:dump_log(),
+ dump_log(N-1, Tester);
+dump_log(_, Tester) ->
+ Tester ! finished.
+
+
+wait_for_tables(doc) ->
+ ["Intf. test of wait_for_tables, see also force_load_table"];
+wait_for_tables(suite) -> [];
+wait_for_tables(Config) when is_list(Config) ->
+ [Node1, Node2] = Nodes = ?acquire_nodes(2, Config),
+ Tab = wf_tab,
+ Schema = [{name, Tab}, {ram_copies, [Node1, Node2]}],
+ ?match({atomic, ok}, mnesia:create_table(Schema)),
+ ?match(ok, mnesia:wait_for_tables([wf_tab], infinity)),
+ ?match(ok, mnesia:wait_for_tables([], timer:seconds(5))),
+ ?match({timeout, [bad_tab]}, mnesia:wait_for_tables([bad_tab], timer:seconds(5))),
+ ?match(ok, mnesia:wait_for_tables([wf_tab], 0)),
+ ?match({error,_}, mnesia:wait_for_tables([wf_tab], -1)),
+ ?verify_mnesia(Nodes, []).
+
+force_load_table(suite) -> [];
+force_load_table(Config) when is_list(Config) ->
+ [Node1, Node2] = ?acquire_nodes(2, Config),
+ Tab = wf_tab,
+
+ Schema = [{name, Tab}, {disc_copies, [Node1, Node2]}],
+ ?match({atomic, ok}, mnesia:create_table(Schema)),
+ ?match(ok, mnesia:dirty_write({Tab, 1, test_ok})),
+ mnesia_test_lib:kill_mnesia([Node1]),
+ ?match(ok, rpc:call(Node2, mnesia, dirty_write, [{Tab, 1, test_nok}])),
+ mnesia_test_lib:kill_mnesia([Node2]),
+ %% timer:sleep(timer:seconds(5)),
+ ?match(ok, mnesia:start()),
+ ?match({timeout, [Tab]}, mnesia:wait_for_tables([Tab], 5)),
+ ?match({'EXIT', _}, mnesia:dirty_read({Tab, 1})),
+ ?match(yes, mnesia:force_load_table(Tab)),
+ ?match([{Tab, 1, test_ok}], mnesia:dirty_read({Tab, 1})),
+
+ ?match({error, _}, mnesia:force_load_table(error_tab)),
+ ?verify_mnesia([Node1], [Node2]).
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+user_properties(doc) ->
+ ["Test of reading, writing and deletion of user properties",
+ "Plus initialization of user properties when a table is created",
+ "Do also test mnesia:table_info(Tab, user_properties)"];
+user_properties(suite) -> [];
+user_properties(Config) when is_list(Config) ->
+ [Node] = Nodes = ?acquire_nodes(1, Config),
+ Tab1 = user_properties_1,
+ Tab2 = user_properties_2,
+ Tab3 = user_properties_3,
+ Def1 = [{ram_copies, [Node]}, {user_properties, []}],
+ Def2 = [{mnesia_test_lib:storage_type(disc_copies, Config), [Node]}],
+ Def3 = [{mnesia_test_lib:storage_type(disc_only_copies, Config), [Node]},
+ {user_properties, []}],
+
+ PropKey = my_prop,
+ Prop = {PropKey, some, elements},
+ Prop2 = {PropKey, some, other, elements},
+ YourProp= {your_prop},
+ ?match({atomic, ok}, mnesia:create_table(Tab1, Def1)),
+ ?match({atomic, ok}, mnesia:create_table(Tab2, Def2)),
+ ?match({atomic, ok}, mnesia:create_table(Tab3, Def3)),
+
+ ?match([], mnesia:table_info(Tab1, user_properties)),
+ ?match([], mnesia:table_info(Tab2, user_properties)),
+ ?match([], mnesia:table_info(Tab3, user_properties)),
+
+ ?match({'EXIT', {no_exists, {Tab1, user_property, PropKey}}},
+ mnesia:read_table_property(Tab1, PropKey)),
+ ?match({'EXIT', {no_exists, {Tab2, user_property, PropKey}}},
+ mnesia:read_table_property(Tab2, PropKey)),
+ ?match({'EXIT', {no_exists, {Tab3, user_property, PropKey}}},
+ mnesia:read_table_property(Tab3, PropKey)),
+
+ ?match({atomic, ok}, mnesia:write_table_property(Tab1, Prop)),
+ ?match({atomic, ok}, mnesia:write_table_property(Tab2, Prop)),
+ ?match({atomic, ok}, mnesia:write_table_property(Tab3, Prop)),
+ ?match({atomic, ok}, mnesia:write_table_property(Tab1, YourProp)),
+ ?match({atomic, ok}, mnesia:write_table_property(Tab2, YourProp)),
+ ?match({atomic, ok}, mnesia:write_table_property(Tab3, YourProp)),
+
+ ?match(Prop, mnesia:read_table_property(Tab1, PropKey)),
+ ?match(Prop, mnesia:read_table_property(Tab2, PropKey)),
+ ?match(Prop, mnesia:read_table_property(Tab3, PropKey)),
+
+ ?match({atomic, ok}, mnesia:write_table_property(Tab1, Prop2)),
+ ?match({atomic, ok}, mnesia:write_table_property(Tab2, Prop2)),
+ ?match({atomic, ok}, mnesia:write_table_property(Tab3, Prop2)),
+ ?match(Prop2, mnesia:read_table_property(Tab1, PropKey)),
+ ?match(Prop2, mnesia:read_table_property(Tab2, PropKey)),
+ ?match(Prop2, mnesia:read_table_property(Tab3, PropKey)),
+
+ ?match({atomic, ok}, mnesia:delete_table_property(Tab1, PropKey)),
+ ?match({atomic, ok}, mnesia:delete_table_property(Tab2, PropKey)),
+ ?match({atomic, ok}, mnesia:delete_table_property(Tab3, PropKey)),
+
+ ?match([YourProp], mnesia:table_info(Tab1, user_properties)),
+ ?match([YourProp], mnesia:table_info(Tab2, user_properties)),
+ ?match([YourProp], mnesia:table_info(Tab3, user_properties)),
+
+ Tab4 = user_properties_4,
+ ?match({atomic, ok},
+ mnesia:create_table(Tab4, [{user_properties, [Prop]}])),
+
+ ?match([Prop], mnesia:table_info(Tab4, user_properties)),
+
+ %% Some error cases
+
+ ?match({aborted, {bad_type, Tab1, {}}},
+ mnesia:write_table_property(Tab1, {})),
+ ?match({aborted, {bad_type, Tab1, ali}},
+ mnesia:write_table_property(Tab1, ali)),
+
+ Tab5 = user_properties_5,
+ ?match({aborted, {bad_type, Tab5, {user_properties, {}}}},
+ mnesia:create_table(Tab5, [{user_properties, {}}])),
+ ?match({aborted, {bad_type, Tab5, {user_properties, ali}}},
+ mnesia:create_table(Tab5, [{user_properties, ali}])),
+ ?match({aborted, {bad_type, Tab5, {user_properties, [{}]}}},
+ mnesia:create_table(Tab5, [{user_properties, [{}]}])),
+ ?match({aborted, {bad_type, Tab5, {user_properties, [ali]}}},
+ mnesia:create_table(Tab5, [{user_properties, [ali]}])),
+
+ ?verify_mnesia(Nodes, []).
+
+
+unsupp_user_props(doc) ->
+ ["Simple test of adding user props in a schema_transaction"];
+unsupp_user_props(suite) -> [];
+unsupp_user_props(Config) when is_list(Config) ->
+ [Node1] = ?acquire_nodes(1, Config),
+ Tab1 = silly1,
+ Tab2 = silly2,
+ Storage = mnesia_test_lib:storage_type(ram_copies, Config),
+
+ ?match({atomic, ok}, rpc:call(Node1, mnesia,
+ create_table, [Tab1, [{Storage, [Node1]}]])),
+ ?match({atomic, ok}, rpc:call(Node1, mnesia,
+ create_table, [Tab2, [{Storage, [Node1]}]])),
+
+ F1 = fun() ->
+ mnesia_schema:do_write_table_property(
+ silly1, {prop, propval1}),
+ mnesia_schema:do_write_table_property(
+ silly2, {prop, propval2}), % same key as above
+ mnesia_schema:do_write_table_property(
+ schema, {prop, propval3}) % same key as above
+ end,
+ ?match({atomic, ok}, rpc:call(Node1, mnesia_schema,
+ schema_transaction, [F1])),
+
+ ?match([{prop,propval1}], rpc:call(Node1, mnesia,
+ table_info, [silly1, user_properties])),
+ ?match([{prop,propval2}], rpc:call(Node1, mnesia,
+ table_info, [silly2, user_properties])),
+ ?match([{prop,propval3}], rpc:call(Node1, mnesia,
+ table_info, [schema, user_properties])),
+
+ F2 = fun() ->
+ mnesia_schema:do_write_table_property(
+ silly1, {prop, propval1a}),
+ mnesia_schema:do_write_table_property(
+ silly1, {prop, propval1b}) % same key as above
+ end,
+ ?match({atomic, ok}, rpc:call(Node1, mnesia_schema,
+ schema_transaction, [F2])),
+
+ ?match([{prop,propval1b}], rpc:call(Node1, mnesia,
+ table_info,
+ [silly1, user_properties])),
+ ?verify_mnesia([Node1], []).
+
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+snmp_access(doc) ->
+ ["Make Mnesia table accessible via SNMP"];
+
+snmp_access(suite) ->
+ [
+ snmp_open_table,
+ snmp_close_table,
+ snmp_get_next_index,
+ snmp_get_row,
+ snmp_get_mnesia_key,
+ snmp_update_counter,
+ snmp_order
+ ].
+
+snmp_open_table(suite) -> [];
+snmp_open_table(Config) when is_list(Config) ->
+ [Node1, Node2] = Nodes = ?acquire_nodes(2, Config),
+ Tab1 = local_snmp_table,
+
+ Storage = mnesia_test_lib:storage_type(disc_copies, Config),
+ Def1 =
+ case mnesia_test_lib:diskless(Config) of
+ true -> [{ram_copies, Nodes}];
+ false ->
+ [{disc_copies, [Node1]}, {ram_copies, [Node2]}]
+ end,
+
+ Tab2 = ext_snmp_table,
+ Def2 = [{Storage, [Node2]}],
+ ErrTab = non_existing_tab,
+ ?match({atomic, ok}, mnesia:create_table(Tab1, Def1)),
+ ?match({atomic, ok}, mnesia:create_table(Tab2, Def2)),
+ ?match({atomic, ok}, mnesia:snmp_open_table(Tab1, [{key, integer}])),
+ ?match({atomic, ok}, mnesia:snmp_open_table(Tab2, [{key, integer}])),
+ ?match({aborted, _}, mnesia:snmp_open_table(ErrTab, [{key, integer}])),
+ ?verify_mnesia(Nodes, []).
+
+snmp_close_table(suite) -> [];
+snmp_close_table(Config) when is_list(Config) ->
+ [Node1, Node2] = Nodes = ?acquire_nodes(2, Config),
+ Tab1 = local_snmp_table,
+ Storage = mnesia_test_lib:storage_type(disc_copies, Config),
+ Def1 =
+ case mnesia_test_lib:diskless(Config) of
+ true -> [{ram_copies, Nodes}];
+ false ->
+ [{disc_copies, [Node1]}, {ram_copies, [Node2]}]
+ end,
+
+ Tab2 = ext_snmp_table,
+ Def2 = [{snmp, [{key, integer}]}, {Storage, [Node2]}],
+ ErrTab = non_existing_tab,
+ ?match({atomic, ok}, mnesia:create_table(Tab1, Def1)),
+ ?match({atomic, ok}, mnesia:create_table(Tab2, Def2)),
+ ?match({atomic, ok}, mnesia:create_table(no_snmp_tab, [])),
+ add_some_records(Tab1, Tab2, 3),
+ ?match({atomic, ok}, mnesia:snmp_open_table(Tab1, [{key, integer}])),
+ add_some_records(Tab1, Tab2, 5),
+ ?match({atomic, ok}, mnesia:snmp_close_table(Tab1)),
+
+ Transform = fun(Tab, Key) ->
+ [{T,K,V}] = mnesia:read(Tab, Key, write),
+ mnesia:delete(T,K, write),
+ mnesia:write({T, {K,K}, V, 43+V})
+ end,
+
+ ?match({atomic, ok}, mnesia:transform_table(Tab1, ignore, [key,val,new])),
+ ?match({atomic, ok},
+ mnesia:transaction(fun() ->
+ mnesia:write_lock_table(Tab1),
+ Keys = mnesia:select(Tab1, [{{'_','$1','_'}, [],
+ ['$1']}]),
+ [Transform(Tab1, Key) || Key <- Keys],
+ ok
+ end)),
+ ?match([{Tab1, {1, 1}, 1, 44}], mnesia:dirty_read(Tab1, {1, 1})),
+ ?match({atomic, ok}, mnesia:snmp_open_table(Tab1, [{key,{integer,integer}}])),
+
+ ?match({atomic, ok}, mnesia:snmp_close_table(Tab2)),
+ ?match({atomic, ok}, mnesia:transform_table(Tab2, ignore, [key,val,new])),
+ ?match({atomic, ok},
+ mnesia:transaction(fun() ->
+ mnesia:write_lock_table(Tab2),
+ Keys = mnesia:select(Tab2, [{{'_','$1','_'}, [],
+ ['$1']}]),
+ [Transform(Tab2, Key) || Key <- Keys],
+ ok
+ end)),
+
+ ?match({atomic, ok}, mnesia:snmp_open_table(Tab2, [{key,{integer,integer}}])),
+
+ %% Should be aborted ????
+ ?match({atomic, ok}, mnesia:snmp_close_table(no_snmp_tab)),
+ ?match({aborted, _}, mnesia:snmp_close_table(ErrTab)),
+ ?verify_mnesia(Nodes, []).
+
+snmp_get_next_index(suite) -> [];
+snmp_get_next_index(Config) when is_list(Config) ->
+ [Node1, Node2] = Nodes = ?acquire_nodes(2, Config),
+ Tab1 = local_snmp_table,
+ Storage = mnesia_test_lib:storage_type(disc_copies, Config),
+ Def1 =
+ case mnesia_test_lib:diskless(Config) of
+ true -> [{ram_copies, Nodes}];
+ false ->
+ [{disc_copies, [Node1]}, {ram_copies, [Node2]}]
+ end,
+
+ Tab2 = ext_snmp_table,
+ Def2 = [{Storage, [Node2]}],
+ ?match({atomic, ok}, mnesia:create_table(Tab1, Def1)),
+ ?match({atomic, ok}, mnesia:create_table(Tab2, Def2)),
+ ?match({atomic, ok}, mnesia:snmp_open_table(Tab1, [{key, integer}])),
+ ?match({atomic, ok}, mnesia:snmp_open_table(Tab2, [{key, integer}])),
+ add_some_records(Tab1, Tab2, 1),
+ Test =
+ fun() ->
+ %% Test local tables
+ {success, Res11} = ?match({ok, _}, mnesia:snmp_get_next_index(Tab1,[])),
+ {ok, Index11} = Res11,
+ {success, _Res12} =
+ ?match(endOfTable, mnesia:snmp_get_next_index(Tab1, Index11)),
+ ?match({'EXIT',_}, mnesia:snmp_get_next_index(Tab1, endOfTable)),
+
+ %% Test external table
+ {success, Res21} =
+ ?match({ok, _}, mnesia:snmp_get_next_index(Tab2, [])),
+ {ok, Index21} = Res21,
+ {success, _Res22} =
+ ?match(endOfTable, mnesia:snmp_get_next_index(Tab2, Index21)),
+
+ {ok, Row} = mnesia:snmp_get_row(Tab1, Index11),
+ ?match(ok, mnesia:dirty_delete(Tab1, hd(Index11))),
+
+ ?match(endOfTable, mnesia:snmp_get_next_index(Tab1,[])),
+
+ ok = mnesia:dirty_write(Row), %% Reset to coming tests
+
+ %% Test of non existing table
+ %%?match(endOfTable, mnesia:snmp_get_next_index(ErrTab, [])),
+ ok
+ end,
+ ?match(ok, Test()),
+ ?match({atomic,ok}, mnesia:transaction(Test)),
+ ?match(ok, mnesia:sync_dirty(Test)),
+ ?match(ok, mnesia:activity(transaction,Test,mnesia)),
+
+ %%io:format("**********Before ~p~n", [mnesia_lib:val({Tab1,snmp})]),
+ %%io:format(" ~p ~n", [ets:tab2list(mnesia_lib:val({local_snmp_table,{index,snmp}}))]),
+ ?match([], mnesia_test_lib:stop_mnesia(Nodes)),
+ ?match([], mnesia_test_lib:start_mnesia(Nodes, [Tab1, Tab2])),
+ %%io:format("**********After ~p~n", [mnesia_lib:val({Tab1,snmp})]),
+ %%io:format(" ~p ~n", [ets:tab2list(mnesia_lib:val({local_snmp_table,{index,snmp}}))]),
+
+ ?match(ok, Test()),
+ ?match({atomic,ok}, mnesia:transaction(Test)),
+ ?match(ok, mnesia:sync_dirty(Test)),
+ ?match(ok, mnesia:activity(transaction,Test,mnesia)),
+
+ ?verify_mnesia(Nodes, []).
+
+add_some_records(Tab1, Tab2, N) ->
+ Recs1 = [{Tab1, I, I} || I <- lists:reverse(lists:seq(1, N))],
+ Recs2 = [{Tab2, I, I} || I <- lists:reverse(lists:seq(20, 20+N-1))],
+ lists:foreach(fun(R) -> mnesia:dirty_write(R) end, Recs1),
+ Fun = fun(R) -> mnesia:write(R) end,
+ Trans = fun() -> lists:foreach(Fun, Recs2) end,
+ {atomic, ok} = mnesia:transaction(Trans),
+ %% Sync things, so everything gets everywhere!
+ {atomic, ok} = mnesia:sync_transaction(fun() -> mnesia:write(lists:last(Recs1)) end),
+ {atomic, ok} = mnesia:sync_transaction(fun() -> mnesia:write(lists:last(Recs2)) end),
+ ?sort(Recs1 ++ Recs2).
+
+snmp_get_row(suite) -> [];
+snmp_get_row(Config) when is_list(Config) ->
+ [Node1, Node2] = Nodes = ?acquire_nodes(2, Config),
+ Tab1 = local_snmp_table,
+ Storage = mnesia_test_lib:storage_type(disc_copies, Config),
+ Def1 =
+ case mnesia_test_lib:diskless(Config) of
+ true -> [{ram_copies, Nodes}];
+ false ->
+ [{disc_copies, [Node1]}, {ram_copies, [Node2]}]
+ end,
+ Tab2 = ext_snmp_table,
+ Def2 = [{Storage, [Node2]}],
+ Tab3 = snmp_table,
+ Def3 = [{Storage, [Node1]},
+ {attributes, [key, data1, data2]}],
+
+ Setup = fun() ->
+ ?match({atomic, ok}, mnesia:create_table(Tab1, Def1)),
+ ?match({atomic, ok}, mnesia:create_table(Tab2, Def2)),
+ ?match({atomic, ok}, mnesia:create_table(Tab3, Def3)),
+ ?match({atomic, ok}, mnesia:snmp_open_table(Tab1, [{key, integer}])),
+ ?match({atomic, ok}, mnesia:snmp_open_table(Tab2, [{key, integer}])),
+ ?match({atomic, ok}, mnesia:snmp_open_table(
+ Tab3, [{key, {fix_string,integer}}])),
+ add_some_records(Tab1, Tab2, 1)
+ end,
+ Clear = fun() ->
+ ?match({atomic, ok}, mnesia:delete_table(Tab1)),
+ ?match({atomic, ok}, mnesia:delete_table(Tab2)),
+ ?match({atomic, ok}, mnesia:delete_table(Tab3))
+ end,
+ Test =
+ fun() ->
+ %% Test local tables
+ {success, Res11} =
+ ?match({ok, [1]}, mnesia:snmp_get_next_index(Tab1,[])),
+ {ok, Index11} = Res11,
+ ?match({ok, {Tab1,1,1}}, mnesia:snmp_get_row(Tab1, Index11)),
+ ?match(endOfTable, mnesia:snmp_get_next_index(Tab1, Index11)),
+ ?match({'EXIT',_}, mnesia:snmp_get_row(Tab1, endOfTable)),
+ ?match(undefined, mnesia:snmp_get_row(Tab1, [73])),
+
+ Add = fun() -> mnesia:write({Tab3, {"f_string", 3}, data1, data2}) end,
+ ?match({atomic, ok}, mnesia:transaction(Add)),
+ {success, {ok, Index31}} = ?match({ok, RowIndex31} when is_list(RowIndex31),
+ mnesia:snmp_get_next_index(Tab3,[])),
+ ?match({ok, Row31} when is_tuple(Row31),
+ mnesia:snmp_get_row(Tab3, Index31)),
+ ?match(endOfTable, mnesia:snmp_get_next_index(Tab3, Index31)),
+ Del = fun() -> mnesia:delete({Tab3,{"f_string",3}}) end,
+ ?match({atomic, ok}, mnesia:transaction(Del)),
+ ?match(undefined, mnesia:snmp_get_row(Tab3, "f_string" ++ [3])),
+ ?match(undefined, mnesia:snmp_get_row(Tab3, "f_string" ++ [73])),
+
+ %% Test external table
+ {success, Res21} = ?match({ok,[20]}, mnesia:snmp_get_next_index(Tab2, [])),
+ {ok, Index21} = Res21,
+ ?match({ok, Row2} when is_tuple(Row2), mnesia:snmp_get_row(Tab2, Index21)),
+ ?match(endOfTable, mnesia:snmp_get_next_index(Tab2, Index21)),
+ %% Test of non existing table
+ %% ?match(endOfTable, mnesia:snmp_get_next_index(ErrTab, [])),
+ ok
+ end,
+ Setup(),
+ ?match(ok, Test()),
+ Clear(), Setup(),
+ ?match({atomic,ok}, mnesia:transaction(Test)),
+ Clear(), Setup(),
+ ?match(ok, mnesia:sync_dirty(Test)),
+ Clear(), Setup(),
+ ?match(ok, mnesia:activity(transaction,Test,mnesia)),
+
+ Clear(), Setup(),
+ ?match([], mnesia_test_lib:stop_mnesia(Nodes)),
+ ?match([], mnesia_test_lib:start_mnesia(Nodes, [Tab1, Tab2])),
+ ?match(ok, Test()),
+ Clear(), Setup(),
+ ?match([], mnesia_test_lib:stop_mnesia(Nodes)),
+ ?match([], mnesia_test_lib:start_mnesia(Nodes, [Tab1, Tab2])),
+ ?match({atomic,ok}, mnesia:transaction(Test)),
+
+ ?verify_mnesia(Nodes, []).
+
+snmp_get_mnesia_key(suite) -> [];
+snmp_get_mnesia_key(Config) when is_list(Config) ->
+ [Node1, Node2] = Nodes = ?acquire_nodes(2, Config),
+ Tab1 = local_snmp_table,
+ Storage = mnesia_test_lib:storage_type(disc_copies, Config),
+ Def1 =
+ case mnesia_test_lib:diskless(Config) of
+ true -> [{ram_copies, Nodes}];
+ false ->
+ [{disc_copies, [Node1]}, {ram_copies, [Node2]}]
+ end,
+
+ Tab2 = ext_snmp_table,
+ Def2 = [{Storage, [Node2]}],
+
+ Tab3 = fix_string,
+ Setup = fun() ->
+ ?match({atomic, ok}, mnesia:create_table(Tab1, Def1)),
+ ?match({atomic, ok}, mnesia:create_table(Tab2, Def2)),
+ ?match({atomic, ok}, mnesia:create_table(Tab3, Def1)),
+ ?match({atomic, ok}, mnesia:snmp_open_table(Tab1, [{key, integer}])),
+ ?match({atomic, ok}, mnesia:snmp_open_table(Tab2, [{key, integer}])),
+ ?match({atomic, ok}, mnesia:snmp_open_table(Tab3, [{key, {fix_string,integer}}])),
+
+ add_some_records(Tab1, Tab2, 1)
+ end,
+ Clear = fun() ->
+ ?match({atomic, ok}, mnesia:delete_table(Tab1)),
+ ?match({atomic, ok}, mnesia:delete_table(Tab2)),
+ ?match({atomic, ok}, mnesia:delete_table(Tab3))
+ end,
+ Test =
+ fun() ->
+ %% Test local tables
+ {success, Res11} =
+ ?match({ok, [1]}, mnesia:snmp_get_next_index(Tab1,[])),
+ {ok, Index11} = Res11,
+ ?match({ok, 1}, mnesia:snmp_get_mnesia_key(Tab1, Index11)),
+ %% Test external tables
+ {success, Res21} =
+ ?match({ok, [20]}, mnesia:snmp_get_next_index(Tab2, [])),
+ {ok, Index21} = Res21,
+ ?match({ok, 20}, mnesia:snmp_get_mnesia_key(Tab2, Index21)),
+ ?match(undefined, mnesia:snmp_get_mnesia_key(Tab2, [97])),
+ ?match({'EXIT', _}, mnesia:snmp_get_mnesia_key(Tab2, 97)),
+
+ ?match({atomic,ok}, mnesia:transaction(fun() -> mnesia:delete({Tab1,1}) end)),
+ ?match(undefined, mnesia:snmp_get_mnesia_key(Tab1, Index11)),
+
+ ?match({atomic,ok},mnesia:transaction(fun() -> mnesia:write({Tab1,73,7}) end)),
+ ?match({ok, 73}, mnesia:snmp_get_mnesia_key(Tab1, [73])),
+ ?match({atomic,ok}, mnesia:transaction(fun() -> mnesia:delete({Tab1,73}) end)),
+ ?match(undefined, mnesia:snmp_get_mnesia_key(Tab1, [73])),
+
+ ?match({atomic,ok},mnesia:transaction(fun() -> mnesia:write({Tab3,{"S",5},7}) end)),
+ ?match({ok,{"S",5}}, mnesia:snmp_get_mnesia_key(Tab3, [$S,5])),
+ ?match({atomic,ok},mnesia:transaction(fun() -> mnesia:delete({Tab3,{"S",5}}) end)),
+ ?match(undefined, mnesia:snmp_get_mnesia_key(Tab3, [$S,5])),
+
+ ok
+ end,
+ Setup(),
+ ?match(ok, Test()),
+ Clear(), Setup(),
+ ?match({atomic,ok}, mnesia:transaction(Test)),
+ Clear(), Setup(),
+ ?match(ok, mnesia:sync_dirty(Test)),
+ Clear(), Setup(),
+ ?match(ok, mnesia:activity(transaction,Test,mnesia)),
+ ?verify_mnesia(Nodes, []).
+
+snmp_update_counter(doc) ->
+ ["Verify that counters may be updated for tables with SNMP property"];
+snmp_update_counter(suite) -> [];
+snmp_update_counter(Config) when is_list(Config) ->
+ [Node1] = Nodes = ?acquire_nodes(1, Config),
+ Tab = snmp_update_counter,
+ Def = [{attributes, [key, value]},
+ {snmp, [{key, integer}]},
+ {ram_copies, [Node1]}
+ ],
+ ?match({atomic, ok}, mnesia:create_table(Tab, Def)),
+ Oid = {Tab, 1},
+ ?match([], mnesia:dirty_read(Oid)),
+ ?match(ok, mnesia:dirty_write({Tab, 1, 1})),
+ ?match([{Tab, _Key, 1}], mnesia:dirty_read(Oid)),
+ ?match(3, mnesia:dirty_update_counter(Oid, 2)),
+ ?match([{Tab, _Key, 3}], mnesia:dirty_read(Oid)),
+ ?verify_mnesia(Nodes, []).
+
+snmp_order(doc) ->
+ ["Verify that sort order is correct in transactions and dirty variants"];
+snmp_order(suite) -> [];
+snmp_order(Config) when is_list(Config) ->
+ [Node1] = Nodes = ?acquire_nodes(1, Config),
+ Tab = snmp_order,
+ Def = [{attributes, [key, value]},
+ {snmp, [{key, {integer, integer, integer}}]},
+ {ram_copies, [Node1]}
+ ],
+ ?match({atomic, ok}, mnesia:create_table(Tab, Def)),
+ Oid = {Tab, 1},
+ ?match([], mnesia:dirty_read(Oid)),
+ ?match({'EXIT', {aborted, _}}, mnesia:dirty_write({Tab, 1, 1})),
+ [mnesia:dirty_write({Tab, {A,B,2}, default}) ||
+ A <- lists:seq(1, 9, 2),
+ B <- lists:seq(2, 8, 2)],
+
+ Test1 = fun() ->
+ Keys0 = get_keys(Tab, []),
+ ?match(Keys0, lists:sort(Keys0)),
+ ?match([[1,2,2]|_], Keys0),
+ Keys1 = get_keys(Tab, [5]),
+ ?match(Keys1, lists:sort(Keys1)),
+ ?match([[5,2,2]|_], Keys1),
+ Keys2 = get_keys(Tab, [7, 4]),
+ ?match(Keys2, lists:sort(Keys2)),
+ ?match([[7,4,2]|_], Keys2),
+ ok
+ end,
+ ?match(ok, Test1()),
+ ?match({atomic, ok},mnesia:transaction(Test1)),
+ ?match(ok,mnesia:sync_dirty(Test1)),
+
+ Test2 = fun() ->
+ mnesia:write(Tab, {Tab,{0,0,2},updated}, write),
+ mnesia:write(Tab, {Tab,{5,3,2},updated}, write),
+ mnesia:write(Tab, {Tab,{10,10,2},updated}, write),
+ Keys0 = get_keys(Tab, []),
+ ?match([[0,0,2],[1,2,2]|_], Keys0),
+ ?match(Keys0, lists:sort(Keys0)),
+
+ Keys1 = get_keys(Tab, [5]),
+ ?match([[5,2,2],[5,3,2]|_], Keys1),
+ ?match(Keys1, lists:sort(Keys1)),
+
+ Keys2 = get_keys(Tab, [7,4]),
+ ?match([[7,4,2]|_], Keys2),
+ ?match(Keys2, lists:sort(Keys2)),
+ ?match([10,10,2], lists:last(Keys0)),
+ ?match([10,10,2], lists:last(Keys1)),
+ ?match([10,10,2], lists:last(Keys2)),
+
+ ?match([[10,10,2]], get_keys(Tab, [10])),
+ ok
+ end,
+
+ ?match({atomic, ok},mnesia:transaction(Test2)),
+
+ ?verify_mnesia(Nodes, []).
+
+get_keys(Tab, Key) ->
+ case mnesia:snmp_get_next_index(Tab, Key) of
+ endOfTable -> [];
+ {ok, Next} ->
+ [Next|get_keys(Tab, Next)]
+ end.
+
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+iteration(doc) ->
+ ["Verify that the iteration functions works as expected"];
+iteration(suite) ->
+ [foldl].
+
+
+foldl(suite) ->
+ [];
+foldl(doc) ->
+ [""];
+foldl(Config) when is_list(Config) ->
+ Nodes = [_N1, N2] = ?acquire_nodes(2, Config),
+ Tab1 = fold_local,
+ Tab2 = fold_remote,
+ Tab3 = fold_ordered,
+ ?match({atomic, ok}, mnesia:create_table(Tab1, [{ram_copies, Nodes}])),
+ ?match({atomic, ok}, mnesia:create_table(Tab2, [{ram_copies, [N2]}, {type, bag}])),
+ ?match({atomic, ok}, mnesia:create_table(Tab3, [{ram_copies, Nodes},
+ {type, ordered_set}])),
+
+ Tab1Els = [{Tab1, N, N} || N <- lists:seq(1, 10)],
+ Tab2Els = ?sort([{Tab2, 1, 2} | [{Tab2, N, N} || N <- lists:seq(1, 10)]]),
+ Tab3Els = [{Tab3, N, N} || N <- lists:seq(1, 10)],
+
+ [mnesia:sync_transaction(fun() -> mnesia:write(E) end) || E <- Tab1Els],
+ [mnesia:sync_transaction(fun() -> mnesia:write(E) end) || E <- Tab2Els],
+ [mnesia:sync_transaction(fun() -> mnesia:write(E) end) || E <- Tab3Els],
+
+ Fold = fun(Tab) ->
+ lists:reverse(mnesia:foldl(fun(E, A) -> [E | A] end, [], Tab))
+ end,
+ Fold2 = fun(Tab, Lock) ->
+ lists:reverse(mnesia:foldl(fun(E, A) -> [E | A] end, [], Tab, Lock))
+ end,
+ Exit = fun(Tab) ->
+ lists:reverse(mnesia:foldl(fun(_E, _A) -> exit(testing) end, [], Tab))
+ end,
+ %% Errors
+ ?match({aborted, _}, mnesia:transaction(Fold, [error])),
+ ?match({aborted, _}, mnesia:transaction(fun(Tab) -> mnesia:foldl(badfun,[],Tab) end,
+ [Tab1])),
+ ?match({aborted, testing}, mnesia:transaction(Exit, [Tab1])),
+ ?match({aborted, _}, mnesia:transaction(Fold2, [Tab1, read_lock])),
+
+ %% Success
+ ?match({atomic, Tab1Els}, sort_res(mnesia:transaction(Fold, [Tab1]))),
+ ?match({atomic, Tab2Els}, sort_res(mnesia:transaction(Fold, [Tab2]))),
+ ?match({atomic, Tab3Els}, mnesia:transaction(Fold, [Tab3])),
+
+ ?match({atomic, Tab1Els}, sort_res(mnesia:transaction(Fold2, [Tab1, read]))),
+ ?match({atomic, Tab1Els}, sort_res(mnesia:transaction(Fold2, [Tab1, write]))),
+
+ ?match(Tab1Els, sort_res(mnesia:sync_dirty(Fold, [Tab1]))),
+ ?match(Tab2Els, sort_res(mnesia:async_dirty(Fold, [Tab2]))),
+
+ ?verify_mnesia(Nodes, []).
+
+sort_res({atomic, List}) ->
+ {atomic, ?sort(List)};
+sort_res(Else) when is_list(Else) ->
+ ?sort(Else);
+sort_res(Else) ->
+ Else.
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+debug_support(doc) ->
+ ["Check that the debug support has not decayed."];
+debug_support(suite) ->
+ [
+ info,
+ schema_0,
+ schema_1,
+ view_0,
+ view_1,
+ view_2,
+ lkill,
+ kill
+ ].
+
+info(suite) -> [];
+info(Config) when is_list(Config) ->
+ Nodes = ?acquire_nodes(1, Config),
+ ?match(ok, mnesia:info()),
+ ?verify_mnesia(Nodes, []).
+
+schema_0(suite) -> [];
+schema_0(Config) when is_list(Config) ->
+ Nodes = ?acquire_nodes(1, Config),
+ ?match(ok, mnesia:schema()),
+ ?verify_mnesia(Nodes, []).
+
+schema_1(suite) -> [];
+schema_1(Config) when is_list(Config) ->
+ Nodes = ?acquire_nodes(1, Config),
+ Tab = schema_1,
+ ?match({atomic, ok}, mnesia:create_table(Tab, [])),
+ ?match(ok, mnesia:schema(Tab)),
+ ?verify_mnesia(Nodes, []).
+
+view_0(suite) -> [];
+view_0(Config) when is_list(Config) ->
+ Nodes = ?acquire_nodes(1, Config),
+ ?match(ok, mnesia_lib:view()),
+ ?verify_mnesia(Nodes, []).
+
+view_1(suite) -> [];
+view_1(Config) when is_list(Config) ->
+ Nodes = ?acquire_nodes(1, Config),
+ BinCore = mnesia_lib:mkcore({crashinfo, "Just testing..."}),
+ CoreFile = lists:concat(["MnesiaCore.", node(), ".view_1.", ?MODULE]),
+ ?match(ok, file:write_file(CoreFile, BinCore)),
+ ?match(ok, mnesia_lib:view(CoreFile)),
+ ?match(ok, file:delete(CoreFile)),
+
+ ?match(stopped, mnesia:stop()),
+ Dir = mnesia:system_info(directory),
+ ?match(eof, mnesia_lib:view(filename:join(Dir, "LATEST.LOG"))),
+ ?match(ok, mnesia_lib:view(filename:join(Dir, "schema.DAT"))),
+ ?verify_mnesia([], Nodes).
+
+view_2(suite) -> [];
+view_2(Config) when is_list(Config) ->
+ Nodes = ?acquire_nodes(1, Config),
+ BinCore = mnesia_lib:mkcore({crashinfo, "More testing..."}),
+ File = lists:concat([?MODULE, "view_2.", node()]),
+ ?match(ok, file:write_file(File, BinCore)),
+ ?match(ok, mnesia_lib:view(File, core)),
+ ?match(ok, file:delete(File)),
+
+ ?match(stopped, mnesia:stop()),
+ Dir = mnesia:system_info(directory),
+ ?match(ok, file:rename(filename:join(Dir, "LATEST.LOG"), File)),
+ ?match(eof, mnesia_lib:view(File, log)),
+ ?match(ok, file:delete(File)),
+
+ ?match(ok, file:rename(filename:join(Dir, "schema.DAT"), File)),
+ ?match(ok, mnesia_lib:view(File, dat)),
+ ?match(ok, file:delete(File)),
+ ?verify_mnesia([], Nodes).
+
+lkill(suite) -> [];
+lkill(Config) when is_list(Config) ->
+ [Node1, Node2] = ?acquire_nodes(2, Config),
+
+ ?match(yes, rpc:call(Node1, mnesia, system_info, [is_running])),
+ ?match(yes, rpc:call(Node2, mnesia, system_info, [is_running])),
+ ?match(ok, rpc:call(Node2, mnesia, lkill, [])),
+ ?match(yes, rpc:call(Node1, mnesia, system_info, [is_running])),
+ ?match(no, rpc:call(Node2, mnesia, system_info, [is_running])),
+ ?verify_mnesia([Node1], [Node2]).
+
+kill(suite) -> [];
+kill(Config) when is_list(Config) ->
+ [Node1, Node2] = ?acquire_nodes(2, Config),
+
+ ?match(yes, rpc:call(Node1, mnesia, system_info, [is_running])),
+ ?match(yes, rpc:call(Node2, mnesia, system_info, [is_running])),
+ ?match({_, []}, rpc:call(Node2, mnesia, kill, [])),
+ ?match(no, rpc:call(Node1, mnesia, system_info, [is_running])),
+ ?match(no, rpc:call(Node2, mnesia, system_info, [is_running])),
+ ?verify_mnesia([], [Node1, Node2]).
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+record_name(doc) ->
+ ["Verify that record names may be differ from the name of ",
+ "the hosting table. Check at least access, restore, "
+ "registry, subscriptions and traveres_backup"];
+record_name(suite) ->
+ [
+ record_name_dirty_access
+ ].
+
+record_name_dirty_access(suite) ->
+ [
+ record_name_dirty_access_ram,
+ record_name_dirty_access_disc,
+ record_name_dirty_access_disc_only
+ ].
+
+record_name_dirty_access_ram(suite) ->
+ [];
+record_name_dirty_access_ram(Config) when is_list(Config) ->
+ record_name_dirty_access(ram_copies, Config).
+
+record_name_dirty_access_disc(suite) ->
+ [];
+record_name_dirty_access_disc(Config) when is_list(Config) ->
+ record_name_dirty_access(disc_copies, Config).
+
+record_name_dirty_access_disc_only(suite) ->
+ [];
+record_name_dirty_access_disc_only(Config) when is_list(Config) ->
+ record_name_dirty_access(disc_only_copies, Config).
+
+record_name_dirty_access(Storage, Config) ->
+ [Node1, _Node2] = Nodes = ?acquire_nodes(2, Config),
+
+ List = lists:concat([record_name_dirty_access_, Storage]),
+ Tab = list_to_atom(List),
+ RecName = some_record,
+ Attr = val,
+ TabDef = [{type, bag},
+ {record_name, RecName},
+ {index, [Attr]},
+ {Storage, Nodes}],
+ ?match({atomic, ok}, mnesia:create_table(Tab, TabDef)),
+
+ ?match(RecName, mnesia:table_info(Tab, record_name)),
+
+ ?match(ok, mnesia:dirty_write(Tab, {RecName, 2, 20})),
+ ?match(ok, mnesia:dirty_write(Tab, {RecName, 2, 21})),
+ ?match(ok, mnesia:dirty_write(Tab, {RecName, 2, 22})),
+
+ %% Backup test
+ BupFile = List ++ ".BUP",
+ CpName = cpname,
+ CpArgs = [{name, CpName}, {min, [Tab]}, {ram_overrides_dump, true}],
+ ?match({ok, CpName, _}, mnesia:activate_checkpoint(CpArgs)),
+ ?match(ok, mnesia:backup_checkpoint(CpName, BupFile)),
+ ?match(ok, mnesia:deactivate_checkpoint(CpName)),
+
+ ?match(ok, mnesia:dirty_write(Tab, {RecName, 1, 10})),
+ ?match({ok, Node1}, mnesia:subscribe({table, Tab})),
+ ?match(ok, mnesia:dirty_write(Tab, {RecName, 3, 10})),
+
+ Twos =?sort( [{RecName, 2, 20}, {RecName, 2, 21}, {RecName, 2, 22}]),
+ ?match(Twos, ?sort(mnesia:dirty_read(Tab, 2))),
+
+ ?match(ok, mnesia:dirty_delete_object(Tab, {RecName, 2, 21})),
+
+ Tens = ?sort([{RecName, 1, 10}, {RecName, 3, 10}]),
+ TenPat = {RecName, '_', 10},
+ ?match(Tens, ?sort(mnesia:dirty_match_object(Tab, TenPat))),
+ ?match(Tens, ?sort(mnesia:dirty_select(Tab, [{TenPat, [], ['$_']}]))),
+
+ %% Subscription test
+ E = mnesia_table_event,
+ ?match_receive({E, {write, {Tab, 3, 10}, _}}),
+ ?match_receive({E, {delete_object, {Tab, 2, 21}, _}}),
+ ?match({ok, Node1}, mnesia:unsubscribe({table, Tab})),
+
+ ?match([], mnesia_test_lib:stop_mnesia([Node1])),
+ ?match([], mnesia_test_lib:start_mnesia(Nodes, [Tab])),
+
+ ?match(Tens, ?sort(mnesia:dirty_index_match_object(Tab, TenPat, Attr) )),
+ ?match(Tens, ?sort(mnesia:dirty_index_read(Tab, 10, Attr))),
+
+ ?match([1, 2, 3], ?sort(mnesia:dirty_all_keys(Tab))),
+
+ ?match({ok, Node1}, mnesia:subscribe({table, Tab})),
+ ?match(ok, mnesia:dirty_delete(Tab, 2)),
+ ?match([], mnesia:dirty_read(Tab, 2)),
+
+ ?match_receive({E, {delete, {Tab, 2}, _}}),
+ ?match([], mnesia_test_lib:flush()),
+ ?match({ok, Node1}, mnesia:unsubscribe({table, Tab})),
+
+ %% Restore test
+ ?match({atomic, [Tab]}, mnesia:restore(BupFile, [{recreate_tables, [Tab]}])),
+ ?match(RecName, mnesia:table_info(Tab, record_name)),
+
+ ?match(Twos, ?sort(mnesia:dirty_match_object(Tab, mnesia:table_info(Tab, wild_pattern)))),
+ ?match(Twos, ?sort(mnesia:dirty_select(Tab,
+ [{mnesia:table_info(Tab, wild_pattern),
+ [],['$_']}]))),
+
+ %% Traverse backup test
+
+ Fun = fun(Rec, {Good, Bad}) ->
+ ?verbose("BUP: ~p~n", [Rec]),
+ case Rec of
+ {T, K, V} when T == Tab ->
+ Good2 = Good ++ [{RecName, K, V}],
+ {[Rec], {?sort(Good2), Bad}};
+ {T, K} when T == Tab ->
+ Good2 = [G || G <- Good, element(2, G) /= K],
+ {[Rec], {?sort(Good2), Bad}};
+ _ when element(1, Rec) == schema ->
+ {[Rec], {Good, Bad}};
+ _ ->
+ Bad2 = Bad ++ [Rec],
+ {[Rec], {Good, ?sort(Bad2)}}
+ end
+ end,
+
+ ?match({ok, {Twos, []}}, mnesia:traverse_backup(BupFile, mnesia_backup,
+ dummy, read_only,
+ Fun, {[], []})),
+ ?match(ok, file:delete(BupFile)),
+
+ %% Update counter test
+
+ CounterTab = list_to_atom(lists:concat([Tab, "_counter"])),
+ CounterTabDef = [{record_name, some_counter}],
+ C = my_counter,
+ ?match({atomic, ok}, mnesia:create_table(CounterTab, CounterTabDef)),
+ ?match(some_counter, mnesia:table_info(CounterTab, record_name)),
+ ?match(0, mnesia:dirty_update_counter(CounterTab, gurka, -10)),
+ ?match(10, mnesia:dirty_update_counter(CounterTab, C, 10)),
+ ?match(11, mnesia:dirty_update_counter(CounterTab, C, 1)),
+ ?match(4711, mnesia:dirty_update_counter(CounterTab, C, 4700)),
+ ?match([{some_counter, C, 4711}], mnesia:dirty_read(CounterTab, C)),
+ ?match(0, mnesia:dirty_update_counter(CounterTab, C, -4747)),
+
+ %% Registry tests
+
+ RegTab = list_to_atom(lists:concat([Tab, "_registry"])),
+ RegTabDef = [{record_name, some_reg}],
+ ?match(ok, mnesia_registry:create_table(RegTab, RegTabDef)),
+ ?match(some_reg, mnesia:table_info(RegTab, record_name)),
+ {success, RegRecs} =
+ ?match([_ | _], mnesia_registry_test:dump_registry(node(), RegTab)),
+
+ R = ?sort(RegRecs),
+ ?match(R, ?sort(mnesia_registry_test:restore_registry(node(), RegTab))),
+
+ ?verify_mnesia(Nodes, []).
+
+sorted_ets(suite) ->
+ [];
+sorted_ets(Config) when is_list(Config) ->
+ [N1, N2, N3] = All = ?acquire_nodes(3, Config),
+
+ Tab = sorted_tab,
+ Def = case mnesia_test_lib:diskless(Config) of
+ true -> [{name, Tab}, {type, ordered_set}, {ram_copies, All}];
+ false -> [{name, Tab}, {type, ordered_set},
+ {ram_copies, [N1]},
+ {disc_copies,[N2, N3]}]
+ end,
+
+ ?match({atomic, ok}, mnesia:create_table(Def)),
+ ?match({aborted, _}, mnesia:create_table(fel, [{disc_only_copies, N1}])),
+
+ ?match([ok | _],
+ [mnesia:dirty_write({Tab, {dirty, N}, N}) || N <- lists:seq(1, 10)]),
+ ?match({atomic, _},
+ mnesia:sync_transaction(fun() ->
+ [mnesia:write({Tab, {trans, N}, N}) ||
+ N <- lists:seq(1, 10)]
+ end)),
+
+ List = mnesia:dirty_match_object({Tab, '_', '_'}),
+ ?match(List, ?sort(List)),
+ ?match(List, rpc:call(N2, mnesia, dirty_match_object, [{Tab, '_', '_'}])),
+ ?match(List, rpc:call(N3, mnesia, dirty_match_object, [{Tab, '_', '_'}])),
+
+ mnesia_test_lib:stop_mnesia(All),
+ mnesia_test_lib:start_mnesia(All, [sorted_tab]),
+
+ List = mnesia:dirty_match_object({Tab, '_', '_'}),
+ ?match(List, ?sort(List)),
+ ?match(List, rpc:call(N2, mnesia, dirty_match_object, [{Tab, '_', '_'}])),
+ ?match(List, rpc:call(N3, mnesia, dirty_match_object, [{Tab, '_', '_'}])),
+
+ ?match(List, rpc:call(N3, mnesia, dirty_select, [Tab, [{{Tab, '_', '_'},[],['$_']}]])),
+
+ TransMatch = fun() ->
+ mnesia:write({Tab, {trans, 0}, 0}),
+ mnesia:write({Tab, {trans, 11}, 11}),
+ mnesia:match_object({Tab, '_', '_'})
+ end,
+ TransSelect = fun() ->
+ mnesia:write({Tab, {trans, 0}, 0}),
+ mnesia:write({Tab, {trans, 11}, 11}),
+ mnesia:select(Tab, [{{Tab, '_', '_'},[],['$_']}])
+ end,
+
+ TList = mnesia:transaction(TransMatch),
+ STList = ?sort(TList),
+ ?match(STList, TList),
+ ?match(STList, rpc:call(N2, mnesia, transaction, [TransMatch])),
+ ?match(STList, rpc:call(N3, mnesia, transaction, [TransMatch])),
+
+ TSel = mnesia:transaction(TransSelect),
+ ?match(STList, TSel),
+ ?match(STList, rpc:call(N2, mnesia, transaction, [TransSelect])),
+ ?match(STList, rpc:call(N3, mnesia, transaction, [TransSelect])),
+
+ ?match({atomic, ok}, mnesia:create_table(rec, [{type, ordered_set}])),
+ [ok = mnesia:dirty_write(R) || R <- [{rec,1,1}, {rec,2,1}]],
+ ?match({atomic, ok}, mnesia:add_table_index(rec, 3)),
+ TestIt = fun() ->
+ ok = mnesia:write({rec,1,1}),
+ mnesia:index_read(rec, 1, 3)
+ end,
+ ?match({atomic, [{rec,1,1}, {rec,2,1}]}, mnesia:transaction(TestIt)).
+
+
diff --git a/lib/mnesia/test/mnesia_examples_test.erl b/lib/mnesia/test/mnesia_examples_test.erl
new file mode 100644
index 0000000000..d1b1409c9d
--- /dev/null
+++ b/lib/mnesia/test/mnesia_examples_test.erl
@@ -0,0 +1,160 @@
+%%
+%% %CopyrightBegin%
+%%
+%% 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(mnesia_examples_test).
+-author('[email protected]').
+-compile([export_all]).
+-include("mnesia_test_lib.hrl").
+
+init_per_testcase(Func, Conf) ->
+ mnesia_test_lib:init_per_testcase(Func, Conf).
+
+fin_per_testcase(Func, Conf) ->
+ mnesia_test_lib:fin_per_testcase(Func, Conf).
+
+-define(init(N, Config),
+ mnesia_test_lib:prepare_test_case([{init_test_case, [mnesia]},
+ delete_schema],
+ N, Config, ?FILE, ?LINE)).
+
+opt_net_load(ExampleMod) ->
+ opt_net_load([node() | nodes()], ExampleMod, ok).
+
+opt_net_load([Node | Nodes], ExampleMod, Res) ->
+ case rpc:call(Node, ?MODULE, opt_load, [ExampleMod]) of
+ {module, ExampleMod} ->
+ opt_net_load(Nodes, ExampleMod, Res);
+ {error, Reason} ->
+ Error = {opt_net_load, ExampleMod, Node, Reason},
+ opt_net_load(Nodes, ExampleMod, {error, Error});
+ {badrpc, Reason} ->
+ Error = {opt_net_load, ExampleMod, Node, Reason},
+ opt_net_load(Nodes, ExampleMod, {error, Error})
+ end;
+opt_net_load([], _ExampleMod, Res) ->
+ Res.
+
+opt_load(Mod) ->
+ case code:is_loaded(Mod) of
+ {file, _} ->
+ {module, Mod};
+ false ->
+ Abs = filename:join([code:lib_dir(mnesia), examples, Mod]),
+ code:load_abs(Abs)
+ end.
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+all(doc) ->
+ ["Run all examples mentioned in the documentation",
+ "Are really all examples covered?"];
+all(suite) ->
+ [
+ bup,
+ company,
+ meter,
+ tpcb
+ ].
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+bup(doc) -> ["Run the backup examples in bup.erl"];
+bup(suite) -> [];
+bup(Config) when is_list(Config) ->
+ Nodes = ?init(3, Config),
+ opt_net_load(bup),
+ ?match(ok, bup:test(Nodes)).
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+company(doc) ->
+ ["Run the company examples in company.erl and company_o.erl"].
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+tpcb(doc) ->
+ ["Run the sample configurations of the stress tests in mnesia_tpcb.erl"];
+tpcb(suite) ->
+ [
+ replica_test,
+ sticky_replica_test,
+ dist_test,
+ conflict_test,
+ frag_test,
+ frag2_test,
+ remote_test,
+ remote_frag2_test
+ ].
+
+replica_test(suite) -> [];
+replica_test(Config) when is_list(Config) ->
+ ?init(3, Config),
+ opt_net_load(mnesia_tpcb),
+ ?match({ok, _}, mnesia_tpcb:start(mnesia_tpcb:config(replica_test, ram_copies))).
+
+sticky_replica_test(suite) -> [];
+sticky_replica_test(Config) when is_list(Config) ->
+ ?init(3, Config),
+ opt_net_load(mnesia_tpcb),
+ ?match({ok, _}, mnesia_tpcb:start(mnesia_tpcb:config(sticky_replica_test, ram_copies))).
+
+dist_test(suite) -> [];
+dist_test(Config) when is_list(Config) ->
+ ?init(3, [{tc_timeout, timer:minutes(10)} | Config]),
+ opt_net_load(mnesia_tpcb),
+ ?match({ok, _}, mnesia_tpcb:start(mnesia_tpcb:config(dist_test, ram_copies))).
+
+conflict_test(suite) -> [];
+conflict_test(Config) when is_list(Config) ->
+ ?init(3, Config),
+ opt_net_load(mnesia_tpcb),
+ ?match({ok, _}, mnesia_tpcb:start(mnesia_tpcb:config(conflict_test, ram_copies))).
+
+frag_test(suite) -> [];
+frag_test(Config) when is_list(Config) ->
+ ?init(3, Config),
+ opt_net_load(mnesia_tpcb),
+ ?match({ok, _}, mnesia_tpcb:start(mnesia_tpcb:config(frag_test, ram_copies))).
+
+frag2_test(suite) -> [];
+frag2_test(Config) when is_list(Config) ->
+ ?init(3, Config),
+ opt_net_load(mnesia_tpcb),
+ ?match({ok, _}, mnesia_tpcb:start(mnesia_tpcb:config(frag2_test, ram_copies))).
+
+remote_test(suite) -> [];
+remote_test(Config) when is_list(Config) ->
+ ?init(3, Config),
+ opt_net_load(mnesia_tpcb),
+ ?match({ok, _}, mnesia_tpcb:start(mnesia_tpcb:config(remote_test, ram_copies))).
+
+remote_frag2_test(suite) -> [];
+remote_frag2_test(Config) when is_list(Config) ->
+ ?init(3, Config),
+ opt_net_load(mnesia_tpcb),
+ ?match({ok, _}, mnesia_tpcb:start(mnesia_tpcb:config(remote_frag2_test, ram_copies))).
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+meter(doc) ->
+ ["Run the meter example in mnesia_meter.erl"];
+meter(suite) ->
+ [];
+meter(Config) when is_list(Config) ->
+ [N | _] = ?init(3, Config),
+ opt_net_load(mnesia_meter),
+ ?match(ok, mnesia_meter:go(ram_copies, [N])).
+
+
diff --git a/lib/mnesia/test/mnesia_frag_test.erl b/lib/mnesia/test/mnesia_frag_test.erl
new file mode 100644
index 0000000000..4add340254
--- /dev/null
+++ b/lib/mnesia/test/mnesia_frag_test.erl
@@ -0,0 +1,875 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 1999-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(mnesia_frag_test).
+-author('[email protected]').
+-include("mnesia_test_lib.hrl").
+
+-compile([export_all]).
+
+init_per_testcase(Func, Conf) ->
+ mnesia_test_lib:init_per_testcase(Func, Conf).
+
+fin_per_testcase(Func, Conf) ->
+ mnesia_test_lib:fin_per_testcase(Func, Conf).
+
+-define(match_dist(ExpectedRes, Expr),
+ case ?match(ExpectedRes, Expr) of
+
+ mnesia_test_lib:error(Format, Args,?FILE,?LINE)).
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+all(doc) ->
+ ["Verify the functionality of fragmented tables"];
+all(suite) ->
+ [
+ light,
+ medium
+ ].
+
+light(suite) ->
+ [
+ nice,
+ evil
+ ].
+
+medium(suite) ->
+ [
+ consistency
+ ].
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+nice(suite) ->
+ [
+ nice_single,
+ nice_multi,
+ nice_access,
+ iter_access
+ ].
+
+nice_single(suite) -> [];
+nice_single(Config) when is_list(Config) ->
+ [Node1, Node2] = Nodes = ?acquire_nodes(2, Config),
+
+ %% Create a table with 2 fragments and 12 records
+ Tab = nice_frag,
+ Props = [{n_fragments, 2}, {node_pool, [Node1]}],
+ ?match({atomic, ok}, mnesia:create_table(Tab, [{frag_properties, Props}])),
+ Records = [{Tab, N, -N} || N <- lists:seq(1, 12)],
+ [frag_write(Tab, R) || R <- Records],
+ ?match([{Node1, 2}], frag_dist(Tab)),
+ ?match([8, 4], frag_rec_dist(Tab)),
+
+ %% Adding a new node to pool should not affect distribution
+ ?match({atomic, ok}, mnesia:change_table_frag(Tab, {add_node, Node2})),
+ Dist = frag_dist(Tab),
+ ?match([{Node2, 0}, {Node1, 2}], Dist),
+ ?match([8, 4], frag_rec_dist(Tab)),
+
+ %% Add new fragment hopefully on the new node
+ ?match({atomic, ok}, mnesia:change_table_frag(Tab, {add_frag, Dist})),
+ Dist2 = frag_dist(Tab),
+ ?match([{Node2, 1}, {Node1, 2}], Dist2),
+ ?match([3, 4, 5], frag_rec_dist(Tab)),
+
+ %% Add new fragment hopefully on the new node
+ ?match({atomic, ok}, mnesia:change_table_frag(Tab, {add_frag, Dist2})),
+ Dist3 = frag_dist(Tab),
+ ?match([{Node1, 2}, {Node2, 2}], Dist3),
+ ?match([3, 2, 5, 2], frag_rec_dist(Tab)),
+
+ %% Add new fragment hopefully on the new node
+ ?match({atomic, ok}, mnesia:change_table_frag(Tab, {add_frag, Dist3})),
+ Dist4 = frag_dist(Tab),
+ ?match([{Node2, 2}, {Node1, 3}], Dist4),
+ ?match([_, _, _, _, _], frag_rec_dist(Tab)),
+
+ %% Dropping a node in pool should not affect distribution
+ ?match({atomic, ok}, mnesia:change_table_frag(Tab, {del_node, Node1})),
+ ?match([{Node2, 2}, {Node1, 3}], frag_dist(Tab)),
+ ?match([_, _, _, _, _], frag_rec_dist(Tab)),
+
+ %% Dropping a fragment
+ ?match({atomic, ok}, mnesia:change_table_frag(Tab, del_frag)),
+ Dist5 = frag_dist(Tab),
+ ?match([{Node2, 2}, {Node1, 2}], Dist5),
+ ?match([3, 2, 5, 2], frag_rec_dist(Tab)),
+
+ %% Add new fragment hopefully on the new node
+ ?match({atomic, ok}, mnesia:change_table_frag(Tab, {add_frag, Dist5})),
+ Dist6 = frag_dist(Tab),
+ ?match([{Node2, 3}, {Node1, 2}], Dist6),
+ ?match([_, _, _, _, _], frag_rec_dist(Tab)),
+
+ %% Dropping all fragments but one
+ ?match({atomic, ok}, mnesia:change_table_frag(Tab, del_frag)),
+ ?match([3, 2, 5, 2], frag_rec_dist(Tab)),
+ ?match({atomic, ok}, mnesia:change_table_frag(Tab, del_frag)),
+ ?match([3, 4, 5], frag_rec_dist(Tab)),
+ ?match({atomic, ok}, mnesia:change_table_frag(Tab, del_frag)),
+ ?match([8, 4], frag_rec_dist(Tab)),
+ ?match({atomic, ok}, mnesia:change_table_frag(Tab, del_frag)),
+ ?match([{Node2, 0}, {Node1, 1}], frag_dist(Tab)),
+ ?match([12], frag_rec_dist(Tab)),
+
+ %% Defragmenting the table clears frag_properties
+ ?match(Len when Len > 0,
+ length(mnesia:table_info(Tab, frag_properties))),
+ ?match({atomic, ok}, mnesia:change_table_frag(Tab, deactivate)),
+ ?match(0, length(mnesia:table_info(Tab, frag_properties))),
+
+ %% Making the table fragmented again
+ Props2 = [{n_fragments, 1}],
+ ?match({atomic, ok}, mnesia:change_table_frag(Tab, {activate, Props2})),
+ ?match({atomic, ok}, mnesia:change_table_frag(Tab, {add_frag, frag_dist(Tab)})),
+ Dist7 = frag_dist(Tab),
+ ?match([{Node1, 1}, {Node2, 1}], Dist7),
+ ?match([8, 4], frag_rec_dist(Tab)),
+
+ %% Deleting the fragmented table
+ ?match({atomic, ok}, mnesia:delete_table(Tab)),
+ ?match(false, lists:member(Tab, mnesia:system_info(tables))),
+
+ ?verify_mnesia(Nodes, []).
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+nice_multi(doc) ->
+ ["Extending the nice case with one more node, ",
+ "one more replica and a foreign key"];
+nice_multi(suite) -> [];
+nice_multi(Config) when is_list(Config) ->
+ [Node1, Node2, Node3] = Nodes = ?acquire_nodes(3, Config),
+
+ %% Create a table with 2 fragments and 8 records
+ Tab = frag_master,
+ Name = frag_rec,
+ Type = case mnesia_test_lib:diskless(Config) of
+ true -> n_ram_copies;
+ false -> n_disc_copies
+ end,
+ Props = [{n_fragments, 2},
+ {Type, 2},
+ {node_pool, [Node2, Node1]}],
+ Def = [{frag_properties, Props},
+ {attributes, [id, data]},
+ {record_name, Name}],
+ ?match({atomic, ok}, mnesia:create_table(Tab, Def)),
+ [frag_write(Tab, {Name, Id, -Id}) || Id <- lists:seq(1, 8)],
+ ?match([6, 2], frag_rec_dist(Tab)),
+ ?match([{Node2, 2}, {Node1, 2}], frag_dist(Tab)),
+
+ %% And connect another table to it, via a foreign key
+ TabF = frag_slave,
+ PropsF = [{foreign_key, {Tab, foreign_id}}],
+ DefF = [{frag_properties, PropsF},
+ {attributes, [id, foreign_id]}],
+
+ ?match({atomic, ok}, mnesia:create_table(TabF, DefF)),
+ [frag_write(TabF, {TabF, {Id}, Id}) || Id <- lists:seq(1, 16)],
+ ?match([10, 6], frag_rec_dist(TabF)),
+ ?match([{Node2, 2}, {Node1, 2}], frag_dist(TabF)),
+
+ %% Adding a new node to pool should not affect distribution
+ ?match({atomic, ok}, mnesia:change_table_frag(Tab, {add_node, Node3})),
+ Dist = frag_dist(Tab),
+ ?match([{Node3, 0}, {Node2, 2}, {Node1, 2}], Dist),
+ ?match([6, 2], frag_rec_dist(Tab)),
+ DistF = frag_dist(TabF),
+ ?match([{Node3, 0}, {Node2, 2}, {Node1, 2}], DistF),
+ ?match([10, 6], frag_rec_dist(TabF)),
+
+ %% Add new fragment hopefully on the new node
+ ?match({atomic, ok}, mnesia:change_table_frag(Tab, {add_frag, Dist})),
+ Dist2 = frag_dist(Tab),
+ ?match([{Node3, 1},{Node1, 2},{Node2,3}], Dist2),
+ ?match([_, _, _], frag_rec_dist(Tab)),
+ DistF2 = frag_dist(TabF),
+ ?match([{Node3, 1},{Node1, 2},{Node2,3}], DistF2),
+ ?match([_, _, _], frag_rec_dist(TabF)),
+
+ %% Add new fragment hopefully on the new node
+ ?match({atomic, ok}, mnesia:change_table_frag(Tab, {add_frag, Dist2})),
+ Dist3 = frag_dist(Tab),
+ ?match([{Node3, 2},{Node2,3},{Node1, 3}], Dist3),
+ ?match([3, 0, 3, 2], frag_rec_dist(Tab)),
+ DistF3 = frag_dist(TabF),
+ ?match([{Node3, 2},{Node2,3},{Node1, 3}], DistF3),
+ ?match([3, 3, 7, 3], frag_rec_dist(TabF)),
+
+ %% Add new fragment hopefully on the new node
+ ?match({atomic, ok}, mnesia:change_table_frag(Tab, {add_frag, Dist3})),
+ Dist4 = frag_dist(Tab),
+ ?match([{Node1, 3}, {Node3, 3},{Node2, 4}], Dist4),
+ ?match([_, _, _, _, _], frag_rec_dist(Tab)),
+ DistF4 = frag_dist(TabF),
+ ?match([{Node1, 3}, {Node3, 3},{Node2, 4}], DistF4),
+ ?match([_, _, _, _, _], frag_rec_dist(TabF)),
+
+ %% Dropping a node in pool should not affect distribution
+ ?match({atomic, ok}, mnesia:change_table_frag(Tab, {del_node, Node1})),
+ ?match([{Node3, 3},{Node2, 4}, {Node1, 3}], frag_dist(Tab)),
+ ?match([_, _, _, _, _], frag_rec_dist(Tab)),
+ ?match([{Node3, 3},{Node2, 4}, {Node1, 3}], frag_dist(TabF)),
+ ?match([_, _, _, _, _], frag_rec_dist(TabF)),
+
+ %% Dropping a fragment
+ ?match({atomic, ok}, mnesia:change_table_frag(Tab, del_frag)),
+ Dist5 = frag_dist(Tab),
+ ?match([{Node3, 2},{Node2,3},{Node1, 3}], Dist5),
+ ?match([3, 0, 3, 2], frag_rec_dist(Tab)),
+ DistF5 = frag_dist(Tab),
+ ?match([{Node3, 2},{Node2,3},{Node1, 3}], DistF5),
+ ?match([3, 3, 7, 3], frag_rec_dist(TabF)),
+
+ %% Add new fragment hopefully on the new node
+ ?match({atomic, ok}, mnesia:change_table_frag(Tab, {add_frag, Dist5})),
+ Dist6 = frag_dist(Tab),
+ ?match([{Node3, 3},{Node2, 4},{Node1, 3}], Dist6),
+ ?match([_, _, _, _, _], frag_rec_dist(Tab)),
+ DistF6 = frag_dist(TabF),
+ ?match([{Node3, 3},{Node2, 4},{Node1, 3}], DistF6),
+ ?match([_, _, _, _, _], frag_rec_dist(TabF)),
+
+ %% Dropping all fragments but one
+ ?match({atomic, ok}, mnesia:change_table_frag(Tab, del_frag)),
+ ?match([3, 0, 3, 2], frag_rec_dist(Tab)),
+ ?match([3, 3, 7, 3], frag_rec_dist(TabF)),
+ ?match({atomic, ok}, mnesia:change_table_frag(Tab, del_frag)),
+ ?match([_, _, _], frag_rec_dist(Tab)),
+ ?match([_, _, _], frag_rec_dist(TabF)),
+ ?match({atomic, ok}, mnesia:change_table_frag(Tab, del_frag)),
+ ?match([6, 2], frag_rec_dist(Tab)),
+ ?match([10, 6], frag_rec_dist(TabF)),
+ ?match({atomic, ok}, mnesia:change_table_frag(Tab, del_frag)),
+ ?match([{Node3, 0}, {Node2, 1}, {Node1, 1}], frag_dist(Tab)),
+ ?match([8], frag_rec_dist(Tab)),
+ ?match([{Node3, 0}, {Node2, 1}, {Node1, 1}], frag_dist(TabF)),
+ ?match([16], frag_rec_dist(TabF)),
+
+ %% Defragmenting the tables clears frag_properties
+ ?match(Len when Len > 0,
+ length(mnesia:table_info(TabF, frag_properties))),
+ ?match({atomic, ok}, mnesia:change_table_frag(TabF, deactivate)),
+ ?match(0, length(mnesia:table_info(TabF, frag_properties))),
+ ?match(Len when Len > 0,
+ length(mnesia:table_info(Tab, frag_properties))),
+ ?match({atomic, ok}, mnesia:change_table_frag(Tab, deactivate)),
+ ?match(0, length(mnesia:table_info(Tab, frag_properties))),
+
+ %% Making the tables fragmented again
+ Props2 = [{n_fragments, 1}, {node_pool, [Node1, Node2]}],
+ ?match({atomic, ok}, mnesia:change_table_frag(Tab, {activate, Props2})),
+ ?match({atomic, ok}, mnesia:delete_table(TabF)),
+ ?match({atomic, ok}, mnesia:create_table(TabF, DefF)),
+ [frag_write(TabF, {TabF, {Id}, Id}) || Id <- lists:seq(1, 16)],
+ ?match({atomic, ok}, mnesia:change_table_frag(Tab, {add_frag, frag_dist(Tab)})),
+ ?match([{Node1, 2}, {Node2, 2}], frag_dist(Tab)),
+ ?match([6, 2], frag_rec_dist(Tab)),
+ ?match([{Node1, 2}, {Node2, 2}], frag_dist(TabF)),
+ ?match([10, 6], frag_rec_dist(TabF)),
+
+ %% Deleting the fragmented tables
+ ?match({atomic, ok}, mnesia:delete_table(TabF)),
+ ?match(false, lists:member(TabF, mnesia:system_info(tables))),
+ ?match({atomic, ok}, mnesia:delete_table(Tab)),
+ ?match(false, lists:member(Tab, mnesia:system_info(tables))),
+
+ ?verify_mnesia(Nodes, []).
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+nice_access(doc) ->
+ ["Cover entire callback interface"];
+nice_access(suite) -> [];
+nice_access(Config) when is_list(Config) ->
+ Nodes = ?acquire_nodes(3, Config),
+
+ Tab = frag_access,
+ Pool = lists:sort(Nodes),
+ Props = [{n_fragments, 20},
+ {n_ram_copies, 2},
+ {node_pool, Pool}],
+ Def = [{frag_properties, Props},
+ {type, ordered_set},
+ {index, [val]}],
+ ?match({atomic, ok}, mnesia:create_table(Tab, Def)),
+ [frag_write(Tab, {Tab, Id, Id}) || Id <- lists:seq(1, 400)],
+
+ %% And connect another table to it, via a foreign key
+ TabF = frag_access_slave,
+ PropsF = [{foreign_key, {Tab, val}}],
+ DefF = [{frag_properties, PropsF},
+ {index, [val]}],
+ ?match({atomic, ok}, mnesia:create_table(TabF, DefF)),
+ [frag_write(TabF, {TabF, Id, Id}) || Id <- lists:seq(1, 400)],
+
+ ?match(done, mnesia:activity(transaction, fun do_access/3, [Tab, Tab, Pool], mnesia_frag)),
+ ?match(done, mnesia:activity(transaction, fun do_access/3, [TabF, Tab, Pool], mnesia_frag)),
+
+ ?verify_mnesia(Nodes, []).
+
+do_access(Tab, Master, Pool) ->
+ ?match(20, mnesia:table_info(Tab, n_fragments)),
+ ?match(Pool, mnesia:table_info(Tab, node_pool)),
+ ?match(2, mnesia:table_info(Tab, n_ram_copies)),
+ ?match(0, mnesia:table_info(Tab, n_disc_copies)),
+ ?match(0, mnesia:table_info(Tab, n_disc_only_copies)),
+ ?match(20, length(mnesia:table_info(Tab, frag_names))),
+ ?match(20, length(mnesia:table_info(Tab, frag_size))),
+ ?match(20, length(mnesia:table_info(Tab, frag_memory))),
+ PoolSize = length(Pool),
+ ?match(PoolSize, length(mnesia:table_info(Tab, frag_dist))),
+ ?match(400, mnesia:table_info(Tab, size)),
+ ?match(I when is_integer(I), mnesia:table_info(Tab, memory)),
+ ?match(Tab, mnesia:table_info(Tab, base_table)),
+
+ Foreign =
+ if
+ Master == Tab ->
+ ?match(undefined, mnesia:table_info(Tab, foreign_key)),
+ ?match([_], mnesia:table_info(Tab, foreigners)),
+ ?match({'EXIT', {aborted, {combine_error, Tab, frag_properties, {foreign_key, undefined}}}},
+ mnesia:read({Tab, 5}, 5, read)),
+ fun({T, _K}) -> T end;
+ true ->
+ ?match({Master, 3}, mnesia:table_info(Tab, foreign_key)),
+ ?match([], mnesia:table_info(Tab, foreigners)),
+ fun({T, K}) -> {T, K} end
+ end,
+
+ Attr = val,
+ ?match(400, mnesia:table_info(Tab, size)),
+ Count = fun(_, N) -> N + 1 end,
+ ?match(400, mnesia:foldl(Count, 0, Tab)),
+ ?match(400, mnesia:foldr(Count, 0, Tab)),
+ ?match(ok, mnesia:write({Tab, [-1], 1})),
+ ?match(401, length(mnesia:match_object(Tab, {Tab, '_', '_'}, read))),
+ ?match(401, length(mnesia:select(Tab, [{{Tab, '_', '$1'}, [], ['$1']}], read))),
+
+ First = mnesia:select(Tab, [{{Tab, '_', '$1'}, [], ['$1']}], 10, read),
+ TestCont = fun('$end_of_table', Total, _This) ->
+ Total;
+ ({Res,Cont1}, Total, This) ->
+ Cont = mnesia:select(Cont1),
+ This(Cont, length(Res) + Total, This)
+ end,
+ ?match(401, TestCont(First, 0, TestCont)),
+
+ %% OTP
+ [_, Frag2|_] = frag_names(Tab),
+ Frag2key = mnesia:dirty_first(Frag2),
+ ?match({[Frag2key],_},mnesia:select(Tab,[{{Tab,Frag2key,'$1'},[],['$1']}],100,read)),
+
+ ?match([{Tab, [-1], 1}], mnesia:read(Foreign({Tab, 1}), [-1], read)),
+ ?match(401, mnesia:foldl(Count, 0, Tab)),
+ ?match(401, mnesia:foldr(Count, 0, Tab)),
+ ?match(ok, mnesia:delete(Foreign({Tab, 2}), 2, write)),
+ ?match([], mnesia:read(Foreign({Tab, 2}), 2, read)),
+ ?match([{Tab, 3, 3}], mnesia:read(Foreign({Tab, 3}), 3, read)),
+ ?match(400, mnesia:foldl(Count, 0, Tab)),
+ ?match(400, mnesia:foldr(Count, 0, Tab)),
+ ?match(ok, mnesia:delete_object({Tab, 3, 3})),
+ ?match([], mnesia:read(Foreign({Tab, 3}), 3, read)),
+ One = lists:sort([{Tab, 1, 1}, {Tab, [-1], 1}]),
+ Pat = {Tab, '$1', 1},
+ ?match(One, lists:sort(mnesia:match_object(Tab, Pat, read))),
+ ?match([1,[-1]], lists:sort(mnesia:select(Tab, [{Pat, [], ['$1']}], read))),
+ ?match([[[-1]]], lists:sort(mnesia:select(Tab, [{Pat, [{is_list, '$1'}], [['$1']]}], read))),
+ ?match([[1, 100]], lists:sort(mnesia:select(Tab, [{Pat, [{is_integer, '$1'}], [['$1',100]]}], read))),
+ ?match([1,[-1]], lists:sort(mnesia:select(Tab, [{Pat, [{is_list, '$1'}], ['$1']},{Pat, [{is_integer, '$1'}], ['$1']}], read))),
+ ?match(One, lists:sort(mnesia:index_match_object(Tab, Pat, Attr, read) )),
+ ?match(One, lists:sort(mnesia:index_read(Tab, 1, Attr))),
+ Keys = mnesia:all_keys(Tab),
+ ?match([-1], lists:max(Keys)), %% OTP-3779
+ ?match(399, length(Keys)),
+ ?match(399, mnesia:foldl(Count, 0, Tab)),
+ ?match(399, mnesia:foldr(Count, 0, Tab)),
+
+ ?match(Pool, lists:sort(mnesia:lock({table, Tab}, write))),
+
+ done.
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+iter_access(doc) ->
+ ["Cover table iteration via callback interface"];
+iter_access(suite) -> [];
+iter_access(Config) when is_list(Config) ->
+ Nodes = ?acquire_nodes(3, Config),
+
+ Tab = frag_access,
+ Pool = lists:sort(Nodes),
+ Props = [{n_fragments, 20},
+ {n_ram_copies, 2},
+ {node_pool, Pool}],
+ Def = [{frag_properties, Props},
+ {type, ordered_set},
+ {index, [val]}],
+ ?match({atomic, ok}, mnesia:create_table(Tab, Def)),
+ [frag_write(Tab, {Tab, Id, Id}) || Id <- lists:seq(1, 400)],
+
+ FragNames = frag_names(Tab),
+ RawRead =
+ fun(Frag) ->
+ Node = mnesia:table_info(Frag, where_to_read),
+ {Frag, rpc:call(Node, ets, tab2list, [Frag])}
+ end,
+
+ ?match(done, mnesia:activity(transaction, fun nice_iter_access/3, [Tab, FragNames, RawRead], mnesia_frag)),
+
+ FragNames = frag_names(Tab),
+ [First, Second | _] = FragNames,
+ [Last, LastButOne | _] = lists:reverse(FragNames),
+
+ ?match({atomic, ok}, mnesia:clear_table(First)),
+ ?match({atomic, ok}, mnesia:clear_table(Second)),
+ ?match({atomic, ok}, mnesia:clear_table(lists:nth(8, FragNames))),
+ ?match({atomic, ok}, mnesia:clear_table(lists:nth(9, FragNames))),
+ ?match({atomic, ok}, mnesia:clear_table(lists:nth(10, FragNames))),
+ ?match({atomic, ok}, mnesia:clear_table(lists:nth(11, FragNames))),
+ ?match({atomic, ok}, mnesia:clear_table(LastButOne)),
+ ?match({atomic, ok}, mnesia:clear_table(Last)),
+
+ ?match(done, mnesia:activity(transaction, fun evil_iter_access/3, [Tab, FragNames, RawRead], mnesia_frag)),
+ Size = fun(Table) -> mnesia:table_info(Table, size) end,
+ ?match(true, 0 < mnesia:activity(transaction, Size, [Tab], mnesia_frag)),
+ ?match({atomic, ok}, mnesia:activity(ets, fun() -> mnesia:clear_table(Tab) end, mnesia_frag)),
+ ?match(0, mnesia:activity(transaction, Size, [Tab], mnesia_frag)),
+
+ ?verify_mnesia(Nodes, []).
+
+nice_iter_access(Tab, FragNames, RawRead) ->
+ RawData = ?ignore(lists:map(RawRead, FragNames)),
+ Keys = [K || {_, Recs} <- RawData, {_, K, _} <- Recs],
+ ExpectedFirst = hd(Keys),
+ ?match(ExpectedFirst, mnesia:first(Tab)),
+ ExpectedLast = lists:last(Keys),
+ ?match(ExpectedLast, mnesia:last(Tab)),
+
+ ExpectedAllPrev = ['$end_of_table' | lists:reverse(tl(lists:reverse(Keys)))],
+ ?match(ExpectedAllPrev, lists:map(fun(K) -> mnesia:prev(Tab, K) end, Keys)),
+
+ ExpectedAllNext = tl(Keys) ++ ['$end_of_table'],
+ ?match(ExpectedAllNext, lists:map(fun(K) -> mnesia:next(Tab, K) end, Keys)),
+
+ done.
+
+evil_iter_access(Tab, FragNames, RawRead) ->
+ RawData = ?ignore(lists:map(RawRead, FragNames)),
+ Keys = [K || {_, Recs} <- RawData, {_, K, _} <- Recs],
+ ExpectedFirst = hd(Keys),
+ ?match(ExpectedFirst, mnesia:first(Tab)),
+ ExpectedLast = lists:last(Keys),
+ ?match(ExpectedLast, mnesia:last(Tab)),
+
+ ExpectedAllPrev = ['$end_of_table' | lists:reverse(tl(lists:reverse(Keys)))],
+ ?match(ExpectedAllPrev, lists:map(fun(K) -> mnesia:prev(Tab, K) end, Keys)),
+
+ ExpectedAllNext = tl(Keys) ++ ['$end_of_table'],
+ ?match(ExpectedAllNext, lists:map(fun(K) -> mnesia:next(Tab, K) end, Keys)),
+
+ done.
+
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+consistency(doc) ->
+ ["Add and delete fragments during TPC-B"];
+consistency(suite) -> [];
+consistency(Config) when is_list(Config) ->
+ ?skip("Not yet implemented (NYI).~n", []),
+ Nodes = ?acquire_nodes(2, Config),
+ ?verify_mnesia(Nodes, []).
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+evil(doc) ->
+ ["Evil coverage of fragmentation API."];
+evil(suite) ->
+ [
+ evil_create,
+ evil_delete,
+ evil_change,
+ evil_combine,
+ evil_loop,
+ evil_delete_db_node
+ ].
+
+evil_create(suite) -> [];
+evil_create(Config) when is_list(Config) ->
+ [Node1, _Node2] = Nodes = ?acquire_nodes(2, Config),
+
+ Create = fun(T, D, P) -> mnesia:create_table(T, [{frag_properties, P}| D]) end,
+
+ Tab = evil_create,
+ %% Props in general
+ ?match({aborted, {badarg, Tab, {frag_properties, no_list}}},
+ Create(Tab, [], no_list)),
+ ?match({aborted, {badarg,Tab , [no_tuple]}},
+ Create(Tab, [], [no_tuple])),
+ ?match({aborted,{badarg, Tab, bad_key}},
+ Create(Tab, [], [{bad_key, 7}])),
+
+ %% n_fragments
+ ?match({aborted,{badarg, Tab, [{n_fragments}]}},
+ Create(Tab, [], [{n_fragments}])),
+ ?match({aborted,{badarg, Tab, [{n_fragments, 1, 1}]}},
+ Create(Tab, [], [{n_fragments, 1, 1}])),
+ ?match({aborted, {bad_type,Tab, {n_fragments, a}}},
+ Create(Tab, [], [{n_fragments, a}])),
+ ?match({aborted, {bad_type, Tab, {n_fragments, 0}}},
+ Create(Tab, [], [{n_fragments, 0}])),
+
+ %% *_copies
+ ?match({aborted, {bad_type, Tab, {n_ram_copies, -1}}},
+ Create(Tab, [], [{n_ram_copies, -1}, {n_fragments, 1}])),
+ ?match({aborted, {bad_type, Tab, {n_disc_copies, -1}}},
+ Create(Tab, [], [{n_disc_copies, -1}, {n_fragments, 1}])),
+ ?match({aborted, {bad_type, Tab, {n_disc_only_copies, -1}}},
+ Create(Tab, [], [{n_disc_only_copies, -1}, {n_fragments, 1}])),
+
+ %% node_pool
+ ?match({aborted, {bad_type, Tab, {node_pool, 0}}},
+ Create(Tab, [], [{node_pool, 0}])),
+ ?match({aborted, {combine_error, Tab, "Too few nodes in node_pool"}},
+ Create(Tab, [], [{n_ram_copies, 2}, {node_pool, [Node1]}])),
+
+ %% foreign_key
+ ?match({aborted, {bad_type, Tab, {foreign_key, bad_key}}},
+ Create(Tab, [], [{foreign_key, bad_key}])),
+ ?match({aborted,{bad_type, Tab, {foreign_key, {bad_key}}}},
+ Create(Tab, [], [{foreign_key, {bad_key}}])),
+ ?match({aborted, {no_exists, {bad_tab, frag_properties}}},
+ Create(Tab, [], [{foreign_key, {bad_tab, val}}])),
+ ?match({aborted, {combine_error, Tab, {Tab, val}}},
+ Create(Tab, [], [{foreign_key, {Tab, val}}])),
+ ?match({atomic, ok},
+ Create(Tab, [], [{n_fragments, 1}])),
+
+ ?match({aborted, {already_exists, Tab}},
+ Create(Tab, [], [{n_fragments, 1}])),
+
+ Tab2 = evil_create2,
+ ?match({aborted, {bad_type, no_attr}},
+ Create(Tab2, [], [{foreign_key, {Tab, no_attr}}])),
+ ?match({aborted, {combine_error, Tab2, _, _, _}},
+ Create(Tab2, [], [{foreign_key, {Tab, val}},
+ {node_pool, [Node1]}])),
+ ?match({aborted, {combine_error, Tab2, _, _, _}},
+ Create(Tab2, [], [{foreign_key, {Tab, val}},
+ {n_fragments, 2}])),
+ ?match({atomic, ok},
+ Create(Tab2, [{attributes, [a, b, c]}], [{foreign_key, {Tab, c}}])),
+ Tab3 = evil_create3,
+ ?match({aborted, {combine_error, Tab3, _, _, _}},
+ Create(Tab3, [{attributes, [a, b]}], [{foreign_key, {Tab2, b}}])),
+ ?match({atomic, ok},
+ Create(Tab3, [{attributes, [a, b]}], [{foreign_key, {Tab, b}}])),
+
+ ?verify_mnesia(Nodes, []).
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+evil_delete(suite) -> [];
+evil_delete(Config) when is_list(Config) ->
+ ?skip("Not yet implemented (NYI).~n", []),
+ Nodes = ?acquire_nodes(2, Config),
+ ?verify_mnesia(Nodes, []).
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+evil_change(suite) -> [];
+evil_change(Config) when is_list(Config) ->
+ [N1,N2,_N3] = Nodes = ?acquire_nodes(3, Config),
+ Create = fun(T, D, P) -> mnesia:create_table(T, [{frag_properties, P}| D]) end,
+ Props1 = [{n_fragments, 2}, {node_pool, [N1]}],
+ Tab1 = evil_change_ram,
+ ?match({atomic, ok}, Create(Tab1, [], Props1)),
+
+ ?match({atomic,ok}, mnesia:change_table_frag(Tab1, {add_frag, Nodes})),
+ Dist10 = frag_dist(Tab1),
+ ?match([{N1,3}], Dist10),
+ ?match({atomic, ok}, mnesia:change_table_frag(Tab1, {add_node, N2})),
+ Dist11 = frag_dist(Tab1),
+ ?match([{N2,0},{N1,3}], Dist11),
+ mnesia_test_lib:kill_mnesia([N2]),
+ ?match({aborted,_}, mnesia:change_table_frag(Tab1, {add_frag, [N2,N1]})),
+ ?verbose("~p~n",[frag_dist(Tab1)]),
+ mnesia_test_lib:start_mnesia([N2]),
+
+ Tab2 = evil_change_disc,
+ ?match({atomic,ok}, Create(Tab2,[],[{n_disc_copies,1},{n_fragments,1},{node_pool,[N1,N2]}])),
+ ?verbose("~p~n", [frag_dist(Tab2)]),
+ ?match({atomic,ok}, mnesia:change_table_frag(Tab2, {add_frag, [N1,N2]})),
+ _Dist20 = frag_dist(Tab2),
+ mnesia_test_lib:kill_mnesia([N2]),
+ ?match({atomic,ok}, mnesia:change_table_frag(Tab2, {add_frag, [N1,N2]})),
+ ?match({aborted,_}, mnesia:change_table_frag(Tab2, {add_frag, [N2,N1]})),
+
+ mnesia_test_lib:start_mnesia([N2]),
+ ?verify_mnesia(Nodes, []).
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+evil_combine(doc) -> ["Bug in mnesia_4.1.5. and earlier"];
+evil_combine(suite) -> [];
+evil_combine(Config) when is_list(Config) ->
+ [Node1] = Nodes = ?acquire_nodes(1, Config),
+ ?match({atomic, ok},mnesia:create_table(tab1, [{disc_copies, [Node1]},
+ {frag_properties, [{n_fragments, 2},
+ {node_pool, [Node1]},
+ {n_disc_copies, 1}]}])),
+ ?match({atomic, ok},mnesia:create_table(tab2, [{disc_copies, [Node1]}])),
+ mnesia:wait_for_tables([tab1, tab2], infinity),
+
+ Add2 = fun() ->
+ mnesia:transaction(fun() ->
+ mnesia:write({tab2,1,1})
+ end)
+ end,
+ Fun = fun() ->
+ Add2(),
+ mnesia:write({tab1,9,10})
+ end,
+ ?match(ok, mnesia:activity({transaction, 1}, Fun, [], mnesia_frag)),
+
+ Read = fun(T, K) ->
+ mnesia:read(T, K, read)
+ end,
+
+ ?match([{tab1,9,10}],mnesia:activity(async_dirty, Read, [tab1, 9], mnesia_frag)),
+ ?match([{tab2,1,1}],mnesia:activity(async_dirty, Read, [tab2, 1], mnesia_frag)),
+
+ ?verify_mnesia(Nodes, []).
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+evil_loop(doc) -> ["Test select/[14]"];
+evil_loop(suite) -> [];
+evil_loop(Config) when is_list(Config) ->
+ [Node1,_Node2] = ?acquire_nodes(2, Config),
+ Tab1 = ss_oset,
+ Tab2 = ss_set,
+ Tab3 = ss_bag,
+ Tabs = [Tab1, Tab2, Tab3],
+ RecName = ss,
+ ?match({atomic, ok}, mnesia:create_table([{name, Tab1},
+ {ram_copies, [Node1]},
+ {record_name, RecName},
+ {type, ordered_set}])),
+ ?match({atomic, ok}, mnesia:create_table([{name, Tab2},
+ {record_name, RecName},
+ {ram_copies, [Node1]},
+ {type, set}])),
+ ?match({atomic, ok}, mnesia:create_table([{name, Tab3},
+ {record_name, RecName},
+ {ram_copies, [Node1]},
+ {type, bag}])),
+ Keys = [-3, -2] ++ lists:seq(1, 5, 2) ++ lists:seq(6, 10),
+ Recs = [{RecName, K, K} || K <- Keys],
+ [mnesia:dirty_write(Tab1, R) || R <- Recs],
+ [mnesia:dirty_write(Tab2, R) || R <- Recs],
+ [mnesia:dirty_write(Tab3, R) || R <- Recs],
+
+ Activate =
+ fun(Tab) ->
+ ?match({atomic, ok}, mnesia:change_table_frag(Tab, {activate, []})),
+ Dist = frag_dist(Tab),
+ ?match({atomic, ok}, mnesia:change_table_frag(Tab, {add_frag, Dist}))
+ end,
+
+ Activate(Tab1),
+ Activate(Tab2),
+ Activate(Tab3),
+
+ Match = fun(Tab) -> mnesia:match_object(Tab, {'_', '_', '_'}, write) end,
+ Select = fun(Tab) -> mnesia:select(Tab, [{'_', [], ['$_']}]) end,
+ Trans = fun(Fun, Args) -> mnesia:activity(transaction, Fun, Args, mnesia_frag) end,
+ LoopHelp = fun('$end_of_table',_) ->
+ [];
+ ({Res,Cont},Fun) ->
+ Sel = mnesia:select(Cont),
+ Res ++ Fun(Sel, Fun)
+ end,
+ SelLoop = fun(Table) ->
+ Sel = mnesia:select(Table, [{'_', [], ['$_']}], 1, read),
+ LoopHelp(Sel, LoopHelp)
+ end,
+
+ R1 = {RecName, 2, 2},
+ R2 = {RecName, 4, 4},
+ R3 = {RecName, 2, 3},
+ R4 = {RecName, 3, 1},
+ R5 = {RecName, 104, 104},
+ W1 = fun(Tab,Search) ->
+ mnesia:write(Tab,R1,write),
+ mnesia:write(Tab,R2,write),
+ Search(Tab)
+ end,
+ S1 = lists:sort([R1, R2| Recs]),
+ ?match(S1, sort_res(Trans(W1, [Tab1, Select]))),
+ ?match(S1, sort_res(Trans(W1, [Tab1, Match]))),
+ ?match(S1, sort_res(Trans(W1, [Tab1, SelLoop]))),
+ ?match(S1, sort_res(Trans(W1, [Tab2, Select]))),
+ ?match(S1, sort_res(Trans(W1, [Tab2, SelLoop]))),
+ ?match(S1, sort_res(Trans(W1, [Tab2, Match]))),
+ ?match(S1, sort_res(Trans(W1, [Tab3, Select]))),
+ ?match(S1, sort_res(Trans(W1, [Tab3, SelLoop]))),
+ ?match(S1, sort_res(Trans(W1, [Tab3, Match]))),
+ [mnesia:dirty_delete_object(Frag, R) || R <- [R1, R2],
+ Tab <- Tabs,
+ Frag <- frag_names(Tab)],
+
+ W2 = fun(Tab, Search) ->
+ mnesia:write(Tab, R3, write),
+ mnesia:write(Tab, R1, write),
+ Search(Tab)
+ end,
+ S2 = lists:sort([R1 | Recs]),
+ S2Bag = lists:sort([R1, R3 | Recs]),
+ io:format("S2 = ~p\n", [S2]),
+ ?match(S2, sort_res(Trans(W2, [Tab1, Select]))),
+ ?match(S2, sort_res(Trans(W2, [Tab1, SelLoop]))),
+ ?match(S2, sort_res(Trans(W2, [Tab1, Match]))),
+ ?match(S2, sort_res(Trans(W2, [Tab2, Select]))),
+ ?match(S2, sort_res(Trans(W2, [Tab2, SelLoop]))),
+ ?match(S2, sort_res(Trans(W2, [Tab2, Match]))),
+ io:format("S2Bag = ~p\n", [S2Bag]),
+ ?match(S2Bag, sort_res(Trans(W2, [Tab3, Select]))),
+ ?match(S2Bag, sort_res(Trans(W2, [Tab3, SelLoop]))),
+ ?match(S2Bag, sort_res(Trans(W2, [Tab3, Match]))),
+
+ W3 = fun(Tab,Search) ->
+ mnesia:write(Tab, R4, write),
+ mnesia:delete(Tab, element(2, R1), write),
+ Search(Tab)
+ end,
+ S3Bag = lists:sort([R4 | lists:delete(R1, Recs)]),
+ S3 = lists:delete({RecName, 3, 3}, S3Bag),
+ ?match(S3, sort_res(Trans(W3, [Tab1, Select]))),
+ ?match(S3, sort_res(Trans(W3, [Tab1, SelLoop]))),
+ ?match(S3, sort_res(Trans(W3, [Tab1, Match]))),
+ ?match(S3, sort_res(Trans(W3, [Tab2, SelLoop]))),
+ ?match(S3, sort_res(Trans(W3, [Tab2, Select]))),
+ ?match(S3, sort_res(Trans(W3, [Tab2, Match]))),
+ ?match(S3Bag, sort_res(Trans(W3, [Tab3, Select]))),
+ ?match(S3Bag, sort_res(Trans(W3, [Tab3, SelLoop]))),
+ ?match(S3Bag, sort_res(Trans(W3, [Tab3, Match]))),
+
+ W4 = fun(Tab,Search) ->
+ mnesia:delete(Tab, -1, write),
+ mnesia:delete(Tab, 4 , write),
+ mnesia:delete(Tab, 17, write),
+ mnesia:delete_object(Tab, {RecName, -1, x}, write),
+ mnesia:delete_object(Tab, {RecName, 4, x}, write),
+ mnesia:delete_object(Tab, {RecName, 42, x}, write),
+ mnesia:delete_object(Tab, R2, write),
+ mnesia:write(Tab, R5, write),
+ Search(Tab)
+ end,
+ S4Bag = lists:sort([R5 | S3Bag]),
+ S4 = lists:sort([R5 | S3]),
+ ?match(S4, sort_res(Trans(W4, [Tab1, Select]))),
+ ?match(S4, sort_res(Trans(W4, [Tab1, SelLoop]))),
+ ?match(S4, sort_res(Trans(W4, [Tab1, Match]))),
+ ?match(S4, sort_res(Trans(W4, [Tab2, Select]))),
+ ?match(S4, sort_res(Trans(W4, [Tab2, SelLoop]))),
+ ?match(S4, sort_res(Trans(W4, [Tab2, Match]))),
+ ?match(S4Bag, sort_res(Trans(W4, [Tab3, Select]))),
+ ?match(S4Bag, sort_res(Trans(W4, [Tab3, SelLoop]))),
+ ?match(S4Bag, sort_res(Trans(W4, [Tab3, Match]))),
+ [mnesia:dirty_delete_object(Tab, R) || R <- [{RecName, 3, 3}, R5], Tab <- Tabs],
+
+ %% hmmm anything more??
+
+ ?verify_mnesia([Node1], []).
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+evil_delete_db_node(doc) ->
+ ["Delete db_node with a repicated table with foreign key"];
+evil_delete_db_node(suite) -> [];
+evil_delete_db_node(Config) when is_list(Config) ->
+ Nodes = lists:sort(?acquire_nodes(2, Config)),
+ Local = node(),
+ Remote = hd(Nodes -- [Local]),
+
+ Type = case mnesia_test_lib:diskless(Config) of
+ true -> n_ram_copies;
+ false -> n_disc_copies
+ end,
+ Tab = frag_master,
+ ?match({atomic, ok}, mnesia:create_table(Tab, [{frag_properties, [{Type, 2}, {node_pool, Nodes}]}])),
+ ExtraTab = frag_foreigner,
+ ?match({atomic, ok}, mnesia:create_table(ExtraTab, [{frag_properties, [{foreign_key, {Tab, key}}, {node_pool, Nodes}]}])),
+
+ GetPool = fun(T) ->
+ case lists:keysearch(node_pool, 1, mnesia:table_info (T, frag_properties)) of
+ {value, {node_pool, N}} -> lists:sort(N);
+ false -> []
+ end
+ end,
+ ?match(Nodes, GetPool(Tab)),
+ ?match(Nodes, GetPool(ExtraTab)),
+
+
+ ?match(stopped, rpc:call(Remote, mnesia, stop, [])),
+ ?match({atomic, ok}, mnesia:del_table_copy(schema, Remote)),
+
+ ?match([Local], GetPool(Tab)),
+ ?match([Local], GetPool(ExtraTab)),
+
+ ?verify_mnesia([Local], []).
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%% Misc convenient helpers
+
+frag_write(Tab, Rec) ->
+ Fun = fun() -> mnesia:write(Tab, Rec, write) end,
+ mnesia:activity(sync_dirty, Fun, mnesia_frag).
+
+frag_dist(Tab) ->
+ Fun = fun() -> mnesia:table_info(Tab, frag_dist) end,
+ mnesia:activity(sync_dirty, Fun, mnesia_frag).
+
+frag_names(Tab) ->
+ Fun = fun() -> mnesia:table_info(Tab, frag_names) end,
+ mnesia:activity(sync_dirty, Fun, mnesia_frag).
+
+frag_rec_dist(Tab) ->
+ Fun = fun() -> mnesia:table_info(Tab, frag_size) end,
+ [Size || {_, Size} <- mnesia:activity(sync_dirty, Fun, mnesia_frag)].
+
+table_size(Tab) ->
+ Node = mnesia:table_info(Tab, where_to_read),
+ rpc:call(Node, mnesia, table_info, [Tab, size]).
+
+sort_res(List) when is_list(List) ->
+ lists:sort(List);
+sort_res(Else) ->
+ Else.
+
+rev_res(List) when is_list(List) ->
+ lists:reverse(List);
+rev_res(Else) ->
+ Else.
diff --git a/lib/mnesia/test/mnesia_inconsistent_database_test.erl b/lib/mnesia/test/mnesia_inconsistent_database_test.erl
new file mode 100644
index 0000000000..b19cd8e01b
--- /dev/null
+++ b/lib/mnesia/test/mnesia_inconsistent_database_test.erl
@@ -0,0 +1,74 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 1998-2009. All Rights Reserved.
+%%
+%% The contents of this file are subject to the Erlang Public License,
+%% Version 1.1, (the "License"); you may not use this file except in
+%% compliance with the License. You should have received a copy of the
+%% Erlang Public License along with this software. If not, it can be
+%% retrieved online at http://www.erlang.org/.
+%%
+%% Software distributed under the License is distributed on an "AS IS"
+%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+%% the License for the specific language governing rights and limitations
+%% under the License.
+%%
+%% %CopyrightEnd%
+%%
+
+%%
+-module(mnesia_inconsistent_database_test).
+-author('[email protected]').
+
+-behaviour(gen_event).
+
+%%-compile([export_all]).
+-include("mnesia_test_lib.hrl").
+
+%% gen_event callback interface
+-export([init/1, handle_event/2, handle_call/2, handle_info/2,
+ terminate/2, code_change/3]).
+
+
+init(_Args) ->
+ ?verbose("~p installed as event_module~n", [?MODULE]),
+ {ok, []}.
+
+handle_event(Msg, State) ->
+ handle_any_event(Msg, State).
+
+handle_info(Msg, State) ->
+ handle_any_event(Msg, State).
+
+
+handle_call(Msg, State) ->
+ handle_any_event(Msg, State).
+
+
+%% The main...
+
+handle_any_event({mnesia_system_event, Event}, State)
+ when element(1, Event) == inconsistent_database ->
+ ?error("Got event: ~p~n", [Event]),
+ {ok, State};
+handle_any_event(Msg, State) ->
+ ?verbose("Got event: ~p~n", [Msg]),
+ {ok, State}.
+
+%%-----------------------------------------------------------------
+%% terminate(Reason, State) ->
+%% AnyVal
+%%-----------------------------------------------------------------
+
+terminate(_Reason, _State) ->
+ ok.
+
+%%----------------------------------------------------------------------
+%% Func: code_change/3
+%% Purpose: Upgrade process when its code is to be changed
+%% Returns: {ok, NewState}
+%%----------------------------------------------------------------------
+code_change(_OldVsn, _State, _Extra) ->
+ exit(not_supported).
+
diff --git a/lib/mnesia/test/mnesia_install_test.erl b/lib/mnesia/test/mnesia_install_test.erl
new file mode 100644
index 0000000000..42a2a19f37
--- /dev/null
+++ b/lib/mnesia/test/mnesia_install_test.erl
@@ -0,0 +1,342 @@
+%%
+%% %CopyrightBegin%
+%%
+%% 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
+%% 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(mnesia_install_test).
+-author('[email protected]').
+
+-compile([export_all]).
+-include("mnesia_test_lib.hrl").
+
+init_per_testcase(Func, Conf) ->
+ mnesia_test_lib:init_per_testcase(Func, Conf).
+
+fin_per_testcase(Func, Conf) ->
+ mnesia_test_lib:fin_per_testcase(Func, Conf).
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+all(doc) ->
+ ["Run some small but demanding test cases in order to verify",
+ "that the basic functionality in Mnesia still works.",
+ "",
+ "Try some very simple things to begin with and increase the",
+ "difficulty stepwise. This test suite should be run before",
+ "all the others if you expect to find bugs.",
+ "",
+ "The function mnesia_install_test:silly() does not use the whole",
+ "infra structure of the test suite. Invoke it on a single node to",
+ "begin with. If that works, proceed with pong = net_adm:ping(SomeOtherNode)",
+ "and rerun silly() in order to perform some distributed tests."];
+all(suite) ->
+ [
+ silly_durability,
+ silly_move,
+ silly_upgrade
+ %,stress
+ ].
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%% Stepwise of more and more advanced features
+silly() ->
+ Nodes = [node()] ++ nodes(),
+ mnesia_test_lib:kill_mnesia(Nodes),
+ Config = [{nodes, Nodes}],
+ mnesia_test_lib:eval_test_case(?MODULE, silly2, Config).
+
+silly2(Config) when is_list(Config) ->
+ [Node1 | _] = Nodes = ?acquire_nodes(3, Config),
+ mnesia_test_lib:kill_mnesia(Nodes),
+ ?ignore([mnesia:delete_schema([N]) || N <- Nodes]),
+ ?match(ok, mnesia:create_schema([Node1])),
+ ?match(ok, rpc:call(Node1, mnesia, start, [])),
+ ?match(ok, rpc:call(Node1, mnesia, wait_for_tables,
+ [[schema], infinity])),
+ Res = silly_durability(Config),
+ StressFun = fun(F) -> apply(?MODULE, F, [Config]) end,
+ R =
+ case length(Nodes) of
+ L when L > 1 ->
+ Node2 = lists:nth(2, Nodes),
+ AddDb = [schema, Node2, ram_copies],
+ ?match({atomic, ok},
+ rpc:call(Node1, mnesia, add_table_copy, AddDb)),
+ Args = [[{extra_db_nodes, [Node1]}]],
+ ?match(ok, rpc:call(Node2, mnesia, start, Args)),
+ ChangeDb = [schema, Node2, disc_copies],
+ ?match({atomic, ok},
+ rpc:call(Node1, mnesia, change_table_copy_type,
+ ChangeDb)),
+ ?match([], mnesia_test_lib:sync_tables([Node1, Node2],
+ [schema])),
+ MoveRes = silly_move(Config),
+ UpgradeRes = silly_upgrade(Config),
+ StressRes = [StressFun(F) || F <- stress(suite)],
+ ?verify_mnesia([Node2], []),
+ [Res, MoveRes, UpgradeRes] ++ StressRes;
+ _ ->
+ StressRes = [StressFun(F) || F <- stress(suite)],
+ ?warning("Too few nodes. Perform net_adm:ping(OtherNode) "
+ "and rerun!!!~n", []),
+ [Res | StressRes]
+ end,
+ ?verify_mnesia([Node1], []),
+ R.
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+silly_durability(doc) ->
+ ["Simple test of durability"];
+silly_durability(suite) -> [];
+silly_durability(Config) when is_list(Config) ->
+ [Node1] = ?acquire_nodes(1, Config),
+ Tab = silly,
+ Storage = mnesia_test_lib:storage_type(disc_copies, Config),
+
+ ?match({atomic, ok}, rpc:call(Node1, mnesia,
+ create_table, [Tab, [{Storage, [Node1]}]])),
+
+ Read = fun() -> mnesia:read({Tab, a}) end,
+ Write = fun() -> mnesia:write({Tab, a, b}) end,
+
+ ?match({atomic, []},
+ rpc:call(Node1, mnesia, transaction, [Read])),
+ ?match({atomic, ok},
+ rpc:call(Node1, mnesia, transaction, [Write])),
+ ?match({atomic, [{Tab, a, b}]},
+ rpc:call(Node1, mnesia, transaction, [Read])),
+
+ ?match(stopped, rpc:call(Node1, mnesia, stop, [])),
+ ?match(ok, rpc:call(Node1, mnesia, start, [])),
+ case mnesia_test_lib:diskless(Config) of
+ true ->
+ skip;
+ false ->
+ ?match(ok, rpc:call(Node1, mnesia, wait_for_tables, [[Tab], infinity])),
+ ?match({atomic, [{Tab, a, b}]},
+ rpc:call(Node1, mnesia, transaction, [Read]))
+ end,
+ ?verify_mnesia([Node1], []).
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+silly_move(doc) ->
+ ["Simple test of movement of a replica from one node to another"];
+silly_move(suite) -> [];
+silly_move(Config) when is_list(Config) ->
+ [Node1, Node2] = ?acquire_nodes(2, Config),
+ Tab = silly_move,
+ ?match({atomic, ok},
+ rpc:call(Node1, mnesia,
+ create_table, [Tab, [{ram_copies, [Node2]}]])),
+ ?match([], mnesia_test_lib:sync_tables([Node1, Node2], [Tab])),
+
+ Read = fun() -> mnesia:read({Tab, a}) end,
+ Write = fun() -> mnesia:write({Tab, a, b}) end,
+
+ ?match({atomic, []},
+ rpc:call(Node1, mnesia, transaction, [Read])),
+ ?match({atomic, ok},
+ rpc:call(Node1, mnesia, transaction, [Write])),
+ ?match({atomic, [{Tab, a, b}]},
+ rpc:call(Node1, mnesia, transaction, [Read])),
+
+ case mnesia_test_lib:diskless(Config) of
+ true -> skip;
+ false ->
+ ?match({atomic, ok},
+ rpc:call(Node1, mnesia,
+ change_table_copy_type, [Tab, Node2, disc_only_copies])),
+ ?match([], mnesia_test_lib:sync_tables([Node1, Node2], [Tab]))
+ end,
+ ?match({atomic, [{Tab, a, b}]}, rpc:call(Node1, mnesia, transaction, [Read])),
+
+ ?match({atomic, ok},
+ rpc:call(Node1, mnesia,
+ move_table_copy, [Tab, Node2, Node1])),
+ ?match([], mnesia_test_lib:sync_tables([Node1, Node2], [Tab])),
+ ?match({atomic, [{Tab, a, b}]},
+ rpc:call(Node1, mnesia, transaction, [Read])),
+ ?verify_mnesia([Node1], []).
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+silly_upgrade(doc) ->
+ ["Simple test of a schema upgrade and restore from backup"];
+silly_upgrade(suite) -> [];
+silly_upgrade(Config) when is_list(Config) ->
+ [Node1, Node2] = Nodes = ?acquire_nodes(2, Config),
+ Name = silly_upgrade,
+ Tab1 = silly_upgrade1,
+ Tab2 = silly_upgrade2,
+ Bup = "silly_upgrade.BUP",
+ Bup2 = "silly_upgrade_part.BUP",
+ ?match({atomic, ok}, mnesia:create_table(Tab1, [{ram_copies, Nodes}])),
+ ?match({atomic, ok}, mnesia:create_table(Tab2, [{disc_only_copies, Nodes}])),
+
+ CpState = add_some_records(Tab1, Tab2, []),
+ ?match(match, verify_state(Tab1, Tab2, CpState)),
+ file:delete(Bup),
+ ?match(ok, mnesia:backup(Bup)),
+ Args = [{name, Name}, {ram_overrides_dump, true},
+ {min, [Tab1, schema]}, {max, [Tab2]}],
+ ?match({ok, Name, _}, mnesia:activate_checkpoint(Args)),
+
+ IgnoreState = add_more_records(Tab1, Tab2, CpState),
+ ?match(match, verify_state(Tab1, Tab2, IgnoreState)),
+ ?match({mismatch, _, _}, verify_state(Tab1, Tab2, CpState)),
+ ?match({atomic, ok}, mnesia:del_table_copy(Tab2, Node1)),
+ file:delete(Bup2),
+ ?match(ok, mnesia:backup_checkpoint(Name, Bup2)),
+
+ UpgradeState = transform_some_records(Tab1, Tab2, IgnoreState),
+ ?match({mismatch, _, _}, verify_state(Tab1, Tab2, CpState)),
+ ?match({mismatch, _, _}, verify_state(Tab1, Tab2, IgnoreState)),
+ ?match(match, verify_state(Tab1, Tab2, UpgradeState)),
+
+ ?match(ok, mnesia:deactivate_checkpoint(Name)),
+ ?match(match, verify_state(Tab1, Tab2, UpgradeState)),
+
+ ?match(ok, mnesia:install_fallback(Bup2)),
+ file:delete(Bup2),
+ %% Will generate intentional crash, fatal error
+ ?match([], mnesia_test_lib:stop_mnesia([Node2])),
+ wait_till_dead([Node1, Node2]),
+ ?match([], mnesia_test_lib:start_mnesia([Node1, Node2], [Tab1, Tab2])),
+ ?match(match, verify_state(Tab1, Tab2, CpState)),
+
+ ?match(ok, mnesia:install_fallback(Bup)),
+ file:delete(Bup),
+ %% Will generate intentional crash, fatal error
+ ?match([], mnesia_test_lib:stop_mnesia([Node1, Node2])),
+ wait_till_dead([Node1, Node2]),
+ ?match([], mnesia_test_lib:start_mnesia([Node1, Node2], [Tab1, Tab2])),
+ CpState2 = [X || X <- CpState, element(1, X) /= Tab1],
+ ?match(match, verify_state(Tab1, Tab2, CpState2)),
+ ?verify_mnesia(Nodes, []).
+
+wait_till_dead([]) -> ok;
+wait_till_dead([N|Ns]) ->
+ Apps = rpc:call(N, application, which_applications, []),
+ case lists:keymember(mnesia, 1, Apps) of
+ true ->
+ timer:sleep(10),
+ wait_till_dead([N|Ns]);
+ false ->
+ wait_till_dead(Ns)
+ end.
+
+add_some_records(Tab1, Tab2, Old) ->
+ Recs1 = [{Tab1, I, I} || I <- lists:seq(1, 30)],
+ Recs2 = [{Tab2, I, I} || I <- lists:seq(20, 40)],
+ lists:foreach(fun(R) -> mnesia:dirty_write(R) end, Recs1),
+ Fun = fun(R) -> mnesia:write(R) end,
+ Trans = fun() -> lists:foreach(Fun, Recs2) end,
+ ?match({atomic, _}, mnesia:transaction(Trans)),
+ lists:sort(Old ++ Recs1 ++ Recs2).
+
+add_more_records(Tab1, Tab2, Old) ->
+ Change1 = [{T, K, V+100} || {T, K, V} <- Old, K==23],
+ Change2 = [{T, K, V+100} || {T, K, V} <- Old, K==24],
+ Del = [{T, K} || {T, K, _V} <- Old, K>=25],
+ New = [{Tab1, 50, 50}, {Tab2, 50, 50}],
+ lists:foreach(fun(R) -> mnesia:dirty_write(R) end, Change1),
+ lists:foreach(fun(R) -> mnesia:dirty_delete(R) end, Del),
+ Fun = fun(R) -> mnesia:write(R) end,
+ Trans = fun() -> lists:foreach(Fun, Change2 ++ New) end,
+ ?match({atomic, ok}, mnesia:transaction(Trans)),
+ Recs = [{T, K, V} || {T, K, V} <- Old, K<23] ++ Change1 ++ Change2 ++ New,
+ lists:sort(Recs).
+
+
+verify_state(Tab1, Tab2, Exp) ->
+ Fun = fun() ->
+ Act1 = [mnesia:read({Tab1, K}) || K <- mnesia:all_keys(Tab1)],
+ Act2 = [mnesia:read({Tab2, K}) || K <- mnesia:all_keys(Tab2)],
+ Act = lists:append(Act1) ++ lists:append(Act2),
+ {ok, Act -- Exp, Exp -- Act}
+ end,
+ case mnesia:transaction(Fun) of
+ {atomic, {ok, [], []}} -> match;
+ {atomic, {ok, More, Less}} -> {mismatch, More, Less};
+ {aborted, Reason} -> {error, Reason}
+ end.
+
+transform_some_records(Tab1, _Tab2, Old) ->
+ Fun = fun(Rec) ->
+ list_to_tuple(tuple_to_list(Rec) ++ [4711])
+ end,
+ ?match({atomic, ok},
+ mnesia:transform_table(Tab1, Fun, [key, val, extra])),
+ Filter = fun(Rec) when element(1, Rec) == Tab1 -> {true, Fun(Rec)};
+ (_) -> true
+ end,
+ lists:sort(lists:zf(Filter, Old)).
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+stress(doc) ->
+ ["Stress the system a little"];
+stress(suite) ->
+ [
+ conflict,
+ dist
+ ].
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+dist(doc) ->
+ ["Avoid lock conflicts in order to maximize thruput",
+ "Ten drivers per node, tables replicated to all nodes, lots of branches"];
+dist(suite) -> [];
+dist(Config) when is_list(Config) ->
+ Nodes = ?acquire_nodes(3, Config ++ [{tc_timeout, 10 * 60000}]),
+ Storage = mnesia_test_lib:storage_type(disc_copies, Config),
+ ?match({ok, _}, mnesia_tpcb:start(dist_args(Nodes, Storage))).
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+conflict(doc) ->
+ ["Provoke a lot of lock conflicts.",
+ "Ten drivers per node, tables replicated to all nodes, single branch"];
+conflict(suite) -> [];
+conflict(Config) when is_list(Config) ->
+ Nodes = ?acquire_nodes(3, Config ++ [{tc_timeout, 10 * 60000}]),
+ Storage = mnesia_test_lib:storage_type(disc_copies, Config),
+ ?match({ok, _}, mnesia_tpcb:start(conflict_args(Nodes, Storage))).
+
+conflict_args(Nodes, ReplicaType) ->
+ [{db_nodes, Nodes},
+ {driver_nodes, Nodes},
+ {replica_nodes, Nodes},
+ {n_drivers_per_node, 10},
+ {n_branches, 1},
+ {n_accounts_per_branch, 10},
+ {replica_type, ReplicaType},
+ {stop_after, timer:minutes(5)},
+ {report_interval, timer:seconds(10)},
+ {use_running_mnesia, true},
+ {reuse_history_id, true}].
+
+dist_args(Nodes, ReplicaType) ->
+ [{db_nodes, Nodes},
+ {driver_nodes, Nodes},
+ {replica_nodes, Nodes},
+ {n_drivers_per_node, 10},
+ {n_branches, length(Nodes) * 100},
+ {n_accounts_per_branch, 10},
+ {replica_type, ReplicaType},
+ {stop_after, timer:minutes(5)},
+ {report_interval, timer:seconds(10)},
+ {use_running_mnesia, true},
+ {reuse_history_id, true}].
+
diff --git a/lib/mnesia/test/mnesia_isolation_test.erl b/lib/mnesia/test/mnesia_isolation_test.erl
new file mode 100644
index 0000000000..4fc6e8fe58
--- /dev/null
+++ b/lib/mnesia/test/mnesia_isolation_test.erl
@@ -0,0 +1,2419 @@
+%%
+%% %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(mnesia_isolation_test).
+-author('[email protected]').
+
+-compile([export_all]).
+-include("mnesia_test_lib.hrl").
+
+init_per_testcase(Func, Conf) ->
+ mnesia_test_lib:init_per_testcase(Func, Conf).
+
+fin_per_testcase(Func, Conf) ->
+ mnesia_test_lib:fin_per_testcase(Func, Conf).
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+all(doc) ->
+ ["Verify the isolation property.",
+ "Operations of concurrent transactions must yield results which",
+ "are indistinguishable from the results which would be obtained by",
+ "forcing each transaction to be serially executed to completion in",
+ "some order. This means that repeated reads of the same records",
+ "within any committed transaction must have returned identical",
+ "data when run concurrently with any mix of arbitary transactions.",
+ "Updates in one transaction must not be visible in any other",
+ "transaction before the transaction has been committed."];
+all(suite) ->
+ [
+ locking,
+ visibility
+ ].
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+locking(doc) ->
+ ["Verify locking semantics for various configurations",
+ " NoLock = lock_funs(no_lock, any_granularity)",
+ " SharedLock = lock_funs(shared_lock, any_granularity)",
+ " ExclusiveLock = lock_funs(exclusive_lock, any_granularity)",
+ " AnyLock = lock_funs(any_lock, any_granularity)"];
+locking(suite) ->
+ [no_conflict,
+ simple_queue_conflict,
+ advanced_queue_conflict,
+ simple_deadlock_conflict,
+ advanced_deadlock_conflict,
+ lock_burst,
+ sticky_locks,
+ unbound_locking,
+ admin_conflict,
+%% removed_resources,
+ nasty
+ ].
+
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+no_conflict(suite) -> [];
+no_conflict(Config) when is_list(Config) ->
+ [Node1] = ?acquire_nodes(1, Config),
+ Tab = no_conflict,
+ create_conflict_table(Tab, [Node1]),
+ Fun = fun(OtherOid, Lock1, Lock2) ->
+ %% Start two transactions
+ {success, [B, A]} = ?start_activities([Node1, Node1]),
+ ?start_transactions([B, A]),
+
+ A ! fun() -> Lock1(one_oid(Tab)), ok end,
+ ?match_receive({A, ok}),
+ B ! fun() -> Lock2(OtherOid), ok end,
+ ?match_receive({B, ok}),
+ A ! fun() -> mnesia:abort(ok) end,
+ ?match_receive({A, {aborted, ok}}),
+ B ! fun() -> mnesia:abort(ok) end,
+ ?match_receive({B, {aborted, ok}})
+ end,
+ NoLocks = lock_funs(no_lock, any_granularity),
+ SharedLocks = lock_funs(shared_lock, any_granularity),
+ AnyLocks = lock_funs(any_lock, any_granularity),
+ OneOneFun = fun(Lock1, Lock2) -> Fun(one_oid(Tab), Lock1, Lock2) end,
+ fun_loop(OneOneFun, NoLocks, AnyLocks),
+ fun_loop(OneOneFun, AnyLocks, NoLocks),
+ fun_loop(OneOneFun, SharedLocks, SharedLocks),
+
+ %% Lock different objects
+ OneOtherFun = fun(Lock1, Lock2) -> Fun(other_oid(Tab), Lock1, Lock2) end,
+ OneSharedLocks = lock_funs(shared_lock, one),
+ OneExclusiveLocks = lock_funs(exclusive_lock, one),
+ fun_loop(OneOtherFun, OneSharedLocks, OneExclusiveLocks),
+ fun_loop(OneOtherFun, OneExclusiveLocks, OneSharedLocks),
+ fun_loop(OneOtherFun, OneExclusiveLocks, OneExclusiveLocks),
+ ok.
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+simple_queue_conflict(suite) -> [];
+simple_queue_conflict(Config) when is_list(Config) ->
+ [Node1] = ?acquire_nodes(1, Config),
+ Tab = simple_queue_conflict,
+ create_conflict_table(Tab, [Node1]),
+ Fun = fun(OneLock, OtherLock) ->
+ %% Start two transactions
+ {success, [B, A]} = ?start_activities([Node1, Node1]),
+ ?start_transactions([B, A]),
+
+ A ! fun() -> OneLock(one_oid(Tab)), ok end,
+ ?match_receive({A, ok}),
+ B ! fun() -> OtherLock(one_oid(Tab)), ok end,
+ wait_for_lock(B, [Node1], 20), % Max 10 sec
+ A ! end_trans,
+ ?match_multi_receive([{A, {atomic, end_trans}}, {B, ok}]),
+ B ! fun() -> mnesia:abort(ok) end,
+ ?match_receive({B, {aborted, ok}})
+ end,
+ OneSharedLocks = lock_funs(shared_lock, one),
+ AllSharedLocks = lock_funs(shared_lock, all),
+ OneExclusiveLocks = lock_funs(exclusive_lock, one),
+ AllExclusiveLocks = lock_funs(exclusive_lock, all),
+ fun_loop(Fun, OneExclusiveLocks, OneExclusiveLocks),
+ fun_loop(Fun, AllExclusiveLocks, AllExclusiveLocks),
+ fun_loop(Fun, OneExclusiveLocks, AllExclusiveLocks),
+ fun_loop(Fun, AllExclusiveLocks, OneExclusiveLocks),
+ fun_loop(Fun, OneSharedLocks, AllExclusiveLocks),
+ fun_loop(Fun, AllSharedLocks, OneExclusiveLocks),
+ ok.
+
+wait_for_lock(Pid, _Nodes, 0) ->
+ Queue = mnesia:system_info(lock_queue),
+ ?error("Timeout while waiting for lock on Pid ~p in queue ~p~n", [Pid, Queue]);
+wait_for_lock(Pid, Nodes, N) ->
+ rpc:multicall(Nodes, sys, get_status, [mnesia_locker]),
+ List = [rpc:call(Node, mnesia, system_info, [lock_queue]) || Node <- Nodes],
+ Q = lists:append(List),
+ check_q(Pid, Q, Nodes, N).
+
+check_q(Pid, [{_Oid, _Op, Pid, _Tid, _WFT} | _Tail], _N, _Count) -> ok;
+check_q(Pid, [_ | Tail], N, Count) -> check_q(Pid, Tail, N, Count);
+check_q(Pid, [], N, Count) ->
+ timer:sleep(500),
+ wait_for_lock(Pid, N, Count - 1).
+
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+advanced_queue_conflict(suite) -> [];
+advanced_queue_conflict(Config) when is_list(Config) ->
+ [Node1] = ?acquire_nodes(1, Config),
+ Tab = advanced_queue_conflict,
+ create_conflict_table(Tab, [Node1]),
+ OneRec = {Tab, 3, 3},
+ OneOid = {Tab, 3},
+ OtherRec = {Tab, 4, 4},
+ OtherOid = {Tab, 4},
+
+ %% Start four transactions
+ {success, [D, C, B, A]} = ?start_activities(lists:duplicate(4, Node1)),
+ ?start_transactions([D, C, B, A]),
+ sys:get_status(whereis(mnesia_locker)), % Explicit sync, release locks is async
+ ?match([], mnesia:system_info(held_locks)),
+ ?match([], mnesia:system_info(lock_queue)),
+
+ %% Acquire some locks
+ A ! fun() -> mnesia:write(OneRec) end,
+ ?match_receive({A, ok}),
+ A ! fun() -> mnesia:read(OneOid) end,
+ ?match_receive({A, [OneRec]}),
+
+ B ! fun() -> mnesia:write(OtherRec) end,
+ ?match_receive({B, ok}),
+ B ! fun() -> mnesia:read(OneOid) end,
+ ?match_receive(timeout),
+
+ C ! fun() -> mnesia:read(OtherOid) end,
+ ?match_receive(timeout),
+ D ! fun() -> mnesia:wread(OtherOid) end,
+ ?match_receive(timeout),
+
+ %% and release them in a certain order
+ A ! end_trans,
+ ?match_multi_receive([{A, {atomic, end_trans}}, {B, [OneRec]}]),
+ B ! end_trans,
+ ?match_multi_receive([{B, {atomic, end_trans}}, {C, [OtherRec]}]),
+ C ! end_trans,
+ ?match_multi_receive([{C, {atomic, end_trans}}, {D, [OtherRec]}]),
+ D ! end_trans,
+ ?match_receive({D, {atomic, end_trans}}),
+
+ sys:get_status(whereis(mnesia_locker)), % Explicit sync, release locks is async
+ ?match([], mnesia:system_info(held_locks)),
+ ?match([], mnesia:system_info(lock_queue)),
+ ok.
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+simple_deadlock_conflict(suite) -> [];
+simple_deadlock_conflict(Config) when is_list(Config) ->
+ [Node1] = ?acquire_nodes(1, Config),
+ Tab = simple_deadlock_conflict,
+ create_conflict_table(Tab, [Node1]),
+ Rec = {Tab, 4, 4},
+ Oid = {Tab, 4},
+
+ %% Start two transactions
+ {success, [B, A]} = ?start_activities(lists:duplicate(2, Node1)),
+ mnesia_test_lib:start_transactions([B, A], 0), % A is newest
+ sys:get_status(whereis(mnesia_locker)), % Explicit sync, release locks is async
+ ?match([], mnesia:system_info(held_locks)),
+ ?match([], mnesia:system_info(lock_queue)),
+
+ B ! fun() -> mnesia:write(Rec) end,
+ ?match_receive({B, ok}),
+ A ! fun() -> mnesia:read(Oid) end,
+ ?match_receive({A, {aborted, nomore}}),
+ B ! end_trans,
+ ?match_receive({B, {atomic, end_trans}}),
+
+ sys:get_status(whereis(mnesia_locker)), % Explicit sync, release locks is async
+ ?match([], mnesia:system_info(held_locks)),
+ ?match([], mnesia:system_info(lock_queue)),
+ ok.
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+advanced_deadlock_conflict(suite) -> [];
+advanced_deadlock_conflict(Config) when is_list(Config) ->
+ [Node1, Node2] = ?acquire_nodes(2, Config),
+ Tab = advanced_deadlock_conflict,
+ create_conflict_table(Tab, [Node2]),
+ sys:get_status(whereis(mnesia_locker)), % Explicit sync, release locks is async
+ Rec = {Tab, 4, 4},
+ Oid = {Tab, 4},
+
+ %% Start two transactions
+ {success, [B, A]} = ?start_activities([Node1, Node2]),
+ mnesia_test_lib:start_sync_transactions([B, A], 0), % A is newest
+ sys:get_status(whereis(mnesia_locker)), % Explicit sync, release locks is async
+ ?match([], mnesia:system_info(held_locks)),
+ ?match([], mnesia:system_info(lock_queue)),
+
+ B ! fun() -> mnesia:write(Rec) end,
+ ?match_receive({B, ok}),
+ A ! fun() -> mnesia:read(Oid) end,
+ ?match_receive({A, {aborted, nomore}}),
+ B ! end_trans,
+ ?match_receive({B, {atomic, end_trans}}),
+
+ sys:get_status(whereis(mnesia_locker)), % Explicit sync, release locks is async
+ ?match([], mnesia:system_info(held_locks)),
+ ?match([], mnesia:system_info(lock_queue)),
+ ok.
+
+one_oid(Tab) -> {Tab, 1}.
+other_oid(Tab) -> {Tab, 2}.
+
+create_conflict_table(Tab, Nodes) ->
+ ?match({atomic, ok}, mnesia:create_table([{name, Tab},
+ {ram_copies, Nodes},
+ {attributes, [key, val]},
+ {index, [val]}
+ ])),
+ ?match([], mnesia_test_lib:sync_tables(Nodes, [Tab])),
+ init_conflict_table(Tab).
+
+init_conflict_table(Tab) ->
+ Recs = mnesia:dirty_match_object({Tab, '_', '_'}),
+ lists:foreach(fun(R) -> mnesia:dirty_delete_object(R) end, Recs),
+ Keys = [one_oid(Tab), other_oid(Tab)],
+ [mnesia:dirty_write({T, K, K}) || {T, K} <- Keys].
+
+%% Apply Fun for each X and Y
+fun_loop(Fun, Xs, Ys) ->
+ lists:foreach(fun(X) -> lists:foreach(fun(Y) -> do_fun(Fun, X, Y) end, Ys) end, Xs).
+
+do_fun(Fun, X, Y) ->
+ Pid = spawn_link(?MODULE, do_fun, [self(), Fun, X, Y]),
+ receive
+ {done_fun, Pid} -> done_fun
+ end.
+
+do_fun(Monitor, Fun, X, Y) ->
+ ?log("{do_fun ~p~n", [[Fun, X, Y]]),
+ sys:get_status(whereis(mnesia_locker)), % Explicit sync, release locks is async
+ ?match([], mnesia:system_info(held_locks)),
+ ?match([], mnesia:system_info(lock_queue)),
+ Fun(X, Y),
+ sys:get_status(whereis(mnesia_locker)), % Explicit sync, release locks is async
+ ?match([], mnesia:system_info(held_locks)),
+ ?match([], mnesia:system_info(lock_queue)),
+ unlink(Monitor),
+ Monitor ! {done_fun, self()},
+ exit(done_fun).
+
+%% Returns a list of fun's
+lock_funs(no_lock, one) ->
+ [
+ fun(Oid) -> mnesia:dirty_read(Oid) end,
+ fun({Tab, Key}) -> mnesia:dirty_write({Tab, Key, Key}) end,
+ fun({Tab, Key}) -> mnesia:dirty_write({Tab, Key, Key}),
+ mnesia:dirty_update_counter({Tab, Key}, 0) end,
+ fun(Oid) -> mnesia:dirty_delete(Oid) end,
+ fun({Tab, Key}) -> mnesia:dirty_delete_object({Tab, Key, Key}) end,
+ fun({Tab, Key}) -> mnesia:dirty_match_object({Tab, Key, Key}) end,
+ fun({Tab, Key}) -> mnesia:dirty_index_match_object({Tab, Key, Key}, val) end,
+ fun({Tab, Key}) -> mnesia:dirty_index_read(Tab, Key, val) end,
+ fun({Tab, Key}) -> mnesia:dirty_index_match_object({Tab, '_', Key}, val) end
+ ];
+lock_funs(no_lock, all) ->
+ [
+ fun({Tab, _}) -> mnesia:dirty_match_object({Tab, '_', '_'}) end,
+ fun({Tab, _}) -> slot_iter(Tab) end,
+ fun({Tab, _}) -> key_iter(Tab) end
+ ];
+lock_funs(shared_lock, one) ->
+
+ [
+ fun(Oid) -> mnesia:read(Oid) end,
+ fun({Tab, Key}) ->
+ init_conflict_table(Tab),
+ mnesia:dirty_delete(other_oid(Tab)),
+ mnesia:match_object({Tab, Key, Key}) end
+ ];
+lock_funs(shared_lock, all) ->
+ [
+ fun({Tab, _}) -> mnesia:read_lock_table(Tab) end,
+ fun({Tab, Key}) -> mnesia:match_object({Tab, '_', Key}) end,
+ fun({Tab, _}) -> mnesia:match_object({Tab, '_', '_'}) end,
+ fun({Tab, _}) -> mnesia:all_keys(Tab) end,
+ fun({Tab, Key}) -> mnesia:index_match_object({Tab, '_', Key}, val) end,
+ fun({Tab, Key}) -> mnesia:index_read(Tab, Key, val) end
+ ];
+lock_funs(exclusive_lock, one) ->
+ [
+ fun(Oid) -> mnesia:wread(Oid) end,
+ fun({Tab, Key}) -> mnesia:write({Tab, Key, Key}) end,
+ fun(Oid) -> mnesia:delete(Oid) end,
+ fun({Tab, Key}) -> mnesia:delete_object({Tab, Key, Key}) end,
+ fun({Tab, Key}) -> mnesia:s_write({Tab, Key, Key}) end,
+ fun(Oid) -> mnesia:s_delete(Oid) end,
+ fun({Tab, Key}) -> mnesia:s_delete_object({Tab, Key, Key}) end
+ ];
+lock_funs(exclusive_lock, all) ->
+ [
+ fun({Tab, _}) -> mnesia:write_lock_table(Tab) end
+ ];
+lock_funs(Compatibility, any_granularity) ->
+ lists:append([lock_funs(Compatibility, Granularity) ||
+ Granularity <- [one, all]]);
+lock_funs(any_lock, Granularity) ->
+ lists:append([lock_funs(Compatibility, Granularity) ||
+ Compatibility <- [no_lock, shared_lock, exclusive_lock]]).
+
+slot_iter(Tab) ->
+ slot_iter(Tab, mnesia:dirty_slot(Tab, 0), 1).
+slot_iter(_Tab, '$end_of_table', _) ->
+ [];
+slot_iter(Tab, Recs, Slot) ->
+ Recs ++ slot_iter(Tab, mnesia:dirty_slot(Tab, Slot), Slot+1).
+
+key_iter(Tab) ->
+ key_iter(Tab, mnesia:dirty_first(Tab)).
+key_iter(_Tab, '$end_of_table') ->
+ [];
+key_iter(Tab, Key) ->
+ [Key | key_iter(Tab, mnesia:dirty_next(Tab, Key))].
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+lock_burst(suite) -> [];
+lock_burst(Config) when is_list(Config) ->
+ [Node1] = ?acquire_nodes(1, Config),
+ Tab = burst,
+ ?match({atomic, ok}, mnesia:create_table(Tab,
+ [{attributes, [a, b]},
+ {ram_copies, [Node1]}])),
+ sys:get_status(whereis(mnesia_locker)), % Explicit sync, release locks is async
+ ?match([], mnesia:system_info(held_locks)),
+ ?match([], mnesia:system_info(lock_queue)),
+ ?match(ok, burst_em(Tab, 1000)),
+ ?match([{burst,1,1000}], mnesia:dirty_read(Tab,1)),
+ sys:get_status(whereis(mnesia_locker)), % Explicit sync, release locks is async
+ ?match([], mnesia:system_info(held_locks)),
+ ?match([], mnesia:system_info(lock_queue)),
+ ok.
+
+burst_em(Tab, N) ->
+ spawn_link(?MODULE, burst_counter, [self(), Tab, N]),
+ receive
+ burst_counter_done -> ok
+ end.
+
+burst_counter(Monitor, Tab, N) when N > 0 ->
+ ?match(ok, burst_gen(Tab, N, self())),
+ Monitor ! burst_receiver(N).
+
+burst_receiver(0) ->
+ burst_counter_done;
+burst_receiver(N) ->
+ receive
+ burst_incr_done ->
+ burst_receiver(N-1)
+ end.
+
+burst_gen(_, 0, _) ->
+ ok;
+burst_gen(Tab, N, Father) when is_integer(N), N > 0 ->
+ spawn_link(?MODULE, burst_incr, [Tab, Father]),
+ burst_gen(Tab, N-1, Father).
+
+burst_incr(Tab, Father) ->
+ Fun = fun() ->
+ Val =
+ case mnesia:read({Tab, 1}) of
+ [{Tab, 1, V}] -> V;
+ [] -> 0
+ end,
+ mnesia:write({Tab, 1, Val+1})
+ end,
+ ?match({atomic, ok}, mnesia:transaction(Fun)),
+ Father ! burst_incr_done.
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+sticky_locks(doc) ->
+ ["Simple Tests of sticky locks"];
+
+sticky_locks(suite) ->
+ [
+ basic_sticky_functionality
+ %% Needs to be expandand a little bit further
+ ].
+
+basic_sticky_functionality(suite) -> [];
+basic_sticky_functionality(Config) when is_list(Config) ->
+ [N1, N2] = Nodes = ?acquire_nodes(2, Config),
+ Tab = basic_table,
+ Storage = mnesia_test_lib:storage_type(disc_copies, Config),
+ ?match({atomic, ok}, mnesia:create_table(Tab, [{Storage, Nodes}])),
+ ?match({atomic, ok}, mnesia:create_table(sync, [{ram_copies, Nodes}])),
+ Trans1 = fun() ->
+ ?match(ok, mnesia:s_write({Tab, 1, 2})),
+ ?match([{Tab, 1, 2}], mnesia:read({Tab, 1})),
+ ?match(timeout, receive M -> M after 500 -> timeout end),
+ ?match(ok, mnesia:s_write({Tab, 2, 2})),
+ ?match(ok, mnesia:write({Tab, 42, 4711}))
+ end,
+ Trans2 = fun() ->
+ ?match([{Tab, 1, 2}], mnesia:read({Tab, 1})),
+ ?match(timeout, receive M -> M after 500 -> timeout end),
+ ?match(ok, mnesia:write({Tab, 1, 4711})),
+ ?match(ok, mnesia:s_write({Tab, 2, 4})),
+ ?match(ok, mnesia:delete({Tab, 42}))
+ end,
+ rpc:call(N1, mnesia, transaction, [Trans1]),
+ ?match([{Tab,N1}], rpc:call(N1, ?MODULE, get_sticky, [])),
+ ?match([{Tab,N1}], rpc:call(N2, ?MODULE, get_sticky, [])),
+
+ rpc:call(N2, mnesia, transaction, [Trans2]),
+ ?match([], rpc:call(N1, ?MODULE, get_sticky, [])),
+ ?match([], rpc:call(N2, ?MODULE, get_sticky, [])),
+
+ Slock = fun() -> mnesia:read({sync,sync}),get_sticky() end,
+ ?match({atomic, [{Tab,1, 4711}]}, mnesia:transaction(fun() -> mnesia:read({Tab, 1}) end)),
+ ?match({atomic, [{Tab,2, 4}]}, mnesia:transaction(fun() -> mnesia:read({Tab, 2}) end)),
+ ?match({atomic, [{Tab,N1}]}, rpc:call(N1, mnesia, transaction,
+ [fun() -> mnesia:s_write({Tab, 1, 3}),Slock() end])),
+ ?match([{Tab,N1}], rpc:call(N2, ?MODULE, get_sticky, [])),
+
+ ?match({atomic,[]}, rpc:call(N2, mnesia, transaction,
+ [fun() -> mnesia:s_write({Tab, 1, 4}),Slock() end])),
+
+ ?match([], rpc:call(N1, ?MODULE, get_sticky, [])),
+ ?match([], rpc:call(N2, ?MODULE, get_sticky, [])),
+
+ ?match({atomic,[{Tab,N2}]}, rpc:call(N2, mnesia, transaction,
+ [fun() -> mnesia:s_write({Tab, 1, 4}),Slock() end])),
+
+ ?match({atomic,[]}, rpc:call(N1, mnesia, transaction,
+ [fun() -> mnesia:s_write({Tab, 1, 5}),Slock() end])),
+ ?match({atomic,[{Tab,N1}]}, rpc:call(N1, mnesia, transaction,
+ [fun() -> mnesia:s_write({Tab, 1, 5}),Slock() end])),
+ ?match({atomic,[]}, rpc:call(N2, mnesia, transaction,
+ [fun() -> mnesia:s_write({Tab, 1, 6}),Slock() end])),
+ ?match({atomic,[{Tab,N2}]}, rpc:call(N2, mnesia, transaction,
+ [fun() -> mnesia:s_write({Tab, 1, 7}),Slock() end])),
+
+ ?match([{Tab,N2}], get_sticky()),
+ ?match({atomic, [{Tab,1, 7}]}, mnesia:transaction(fun() -> mnesia:read({Tab, 1}) end)),
+ ?match([{Tab,N2}], get_sticky()),
+ ?match({atomic, [{Tab,2, 4}]}, mnesia:transaction(fun() -> mnesia:read({Tab, 2}) end)),
+ ?match([{Tab,N2}], get_sticky()),
+ ?match({atomic,[{Tab,N2}]}, rpc:call(N2, mnesia, transaction,
+ [fun() -> mnesia:s_write({Tab, 1, 6}),Slock() end])),
+ ?match([{Tab,N2}], get_sticky()),
+ ?match({atomic, [{Tab,1, 6}]}, mnesia:transaction(fun() -> mnesia:read({Tab, 1}) end)),
+ ?match([{Tab,N2}], get_sticky()),
+ ?match({atomic, [{Tab,2, 4}]}, mnesia:transaction(fun() -> mnesia:read({Tab, 2}) end)),
+ ?match([{Tab,N2}], get_sticky()),
+ ?verify_mnesia(Nodes, []).
+
+get_sticky() ->
+ mnesia_locker ! {get_table, self(), mnesia_sticky_locks},
+ receive {mnesia_sticky_locks, Locks} -> Locks end.
+
+get_held() ->
+ mnesia_locker ! {get_table, self(), mnesia_sticky_locks},
+ receive {mnesia_sticky_locks, Locks} -> Locks end.
+
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+unbound_locking(suite) ->
+ [unbound1, unbound2];
+
+unbound_locking(doc) ->
+ ["Check that mnesia handles unbound key variables, GPRS bug."
+ "Ticket id: OTP-3342"].
+
+unbound1(suite) -> [];
+unbound1(Config) when is_list(Config) ->
+ [Node1] = ?acquire_nodes(1, Config),
+
+ ?match({atomic, ok}, mnesia:create_table(ul, [])),
+
+ Tester = self(),
+ Write = fun() ->
+ mnesia:write({ul, {key, {17,42}}, val}),
+ ?log("~p Got write lock waiting...~n", [self()]),
+ Tester ! continue,
+ receive
+ continue ->
+ ok
+ end,
+ ?log("..continuing~n", []),
+ ok
+ end,
+
+ {success, [A]} = ?start_activities([Node1]),
+ ?start_transactions([A]),
+ A ! Write,
+
+ receive continue -> ok end,
+
+ Match = fun() ->
+ case catch mnesia:match_object({ul, {key, {'_', '$0'}}, '_'}) of
+ {'EXIT', What} -> %% Cyclic first time
+ ?log("Cyclic Restarting~n", []),
+ A ! continue,
+ A ! end_trans,
+ exit(What);
+ Res ->
+ ?log("Got match log ~p...~n", [Res]),
+ Res
+ end
+ end,
+ ?match({atomic, [{ul,{key,{17,42}},val}]}, mnesia:transaction(Match)),
+
+ ?match_receive({A, ok}),
+ ?match_receive({A, {atomic, end_trans}}),
+ ok.
+
+unbound2(suite) -> [];
+unbound2(Config) when is_list(Config) ->
+ [Node1] = ?acquire_nodes(1, Config),
+
+ ?match({atomic, ok}, mnesia:create_table(ul, [])),
+
+ {success, [B, A]} = ?start_activities([Node1, Node1]),
+
+ Me = self(),
+
+ Write = fun() ->
+ mnesia:write({ul, {key, {17,42}}, val}),
+ ?log("~p Got write lock waiting... Tid ~p ~n",
+ [self(), get(mnesia_activity_state)]),
+ Me ! ok_lock,
+ receive
+ continue ->
+ ok
+ end,
+ ?log("..continuing~n", []),
+ ok
+ end,
+
+ Match = fun() ->
+ receive
+ continueB ->
+ ?log("~p, moving on TID ~p~n",
+ [self(), get(mnesia_activity_state)]),
+ Me ! {self(), continuing}
+ end,
+ case catch mnesia:match_object({ul, {key, {'_', '$0'}},
+ '_'}) of
+ {'EXIT', What} -> %% Cyclic first time
+ ?log("Cyclic Restarting ~p ~n", [What]),
+ {should_not_happen,What};
+ Res ->
+ ?log("Got match log ~p...~n", [Res]),
+ Res
+ end
+ end,
+
+ B ! fun() -> mnesia:transaction(Match) end,
+ timer:sleep(100), %% Let B be started first..
+ A ! fun() -> mnesia:transaction(Write) end,
+
+ receive ok_lock -> ok end,
+
+ B ! continueB,
+ ?match_receive({B, continuing}),
+
+ %% B should now be in lock queue.
+ A ! continue,
+ ?match_receive({A, {atomic, ok}}),
+ ?match_receive({B, {atomic, [{ul,{key,{17,42}},val}]}}),
+ ok.
+
+receiver() ->
+ receive
+ {_Pid, begin_trans} ->
+ receiver();
+ Else ->
+ Else
+ after
+ 10000 ->
+ timeout
+ end.
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+admin_conflict(doc) ->
+ ["Provoke lock conflicts with schema transactions and checkpoints."];
+admin_conflict(suite) ->
+ [
+ create_table,
+ delete_table,
+ move_table_copy,
+ add_table_index,
+ del_table_index,
+ transform_table,
+ snmp_open_table,
+ snmp_close_table,
+ change_table_copy_type,
+ change_table_access,
+ add_table_copy,
+ del_table_copy,
+ dump_tables,
+ extra_admin_tests
+ ].
+
+create_table(suite) -> [];
+create_table(Config) when is_list(Config) ->
+ [ThisNode, Node2] = ?acquire_nodes(2, Config),
+ Tab = c_t_tab,
+ Def = [{ram_copies, [ThisNode]}, {attributes, [key, attr1, attr2]}],
+ ?match({atomic, ok}, mnesia:create_table(Tab, Def)),
+ insert(Tab, 50),
+ {success, [A]} = ?start_activities([ThisNode]),
+ mnesia_test_lib:start_sync_transactions([A], 0),
+
+ A ! fun() -> mnesia:write({Tab, 1, 1, updated}) end,
+ ?match_receive({A, ok}), %% A is executed
+
+ DiskMaybe = mnesia_test_lib:storage_type(disc_copies, Config),
+
+ Pid = spawn_link(?MODULE, op, [self(), mnesia, create_table,
+ [test_tab1, [{DiskMaybe, [ThisNode]}]]]),
+ ?match_multi_receive([{Pid, {atomic, ok}},
+ {'EXIT', Pid, normal}]), %% No Locks! op should be exec.
+
+ Pid2 = spawn_link(?MODULE, op, [self(), mnesia, create_table,
+ [test_tab2, [{ram_copies, [Node2]}]]]),
+
+ ?match_multi_receive([{Pid2, {atomic, ok}},
+ {'EXIT', Pid2, normal}]), %% No Locks! op should be exec.
+
+ A ! end_trans,
+ ?match_receive({A,{atomic,end_trans}}),
+
+ sys:get_status(whereis(mnesia_locker)), % Explicit sync, release locks is async
+ ?match([], mnesia:system_info(held_locks)),
+ ?match([], mnesia:system_info(lock_queue)),
+ ok.
+
+delete_table(suite) -> [];
+delete_table(Config) when is_list(Config) ->
+ [ThisNode, Node2] = ?acquire_nodes(2, Config),
+ Tab = d_t_tab,
+ Def = [{ram_copies, [ThisNode, Node2]}, {attributes, [key, attr1, attr2]}],
+ ?match({atomic, ok}, mnesia:create_table(Tab, Def)),
+ insert(Tab, 50),
+ {success, [A]} = ?start_activities([ThisNode]),
+ mnesia_test_lib:start_sync_transactions([A], 0),
+
+ A ! fun() -> mnesia:read({Tab, 1}) end,
+ ?match_receive({A, [{Tab, 1, 1, 0}]}), %% A is executed
+
+ Pid = spawn_link(?MODULE, op, [self(), mnesia, delete_table,
+ [Tab]]),
+
+ ?match_receive(timeout), %% op waits for locks occupied by A
+
+ A ! end_trans, %% Kill A, locks should be released
+ ?match_receive({A,{atomic,end_trans}}),
+
+ receive
+ Msg -> ?match({Pid, {atomic, ok}}, Msg)
+ after
+ timer:seconds(20) -> ?error("Operation timed out", [])
+ end,
+
+ sys:get_status(whereis(mnesia_locker)), % Explicit sync, release locks is async
+ ?match([], mnesia:system_info(held_locks)),
+ ?match([], mnesia:system_info(lock_queue)),
+ ok.
+
+move_table_copy(suite) -> [];
+move_table_copy(Config) when is_list(Config) ->
+ [ThisNode, Node2] = ?acquire_nodes(2, Config),
+ Tab = m_t_c_tab,
+ Def = [{ram_copies, [ThisNode]}, {attributes, [key, attr1, attr2]}],
+ ?match({atomic, ok}, mnesia:create_table(Tab, Def)),
+ insert(Tab, 50),
+ {success, [A]} = ?start_activities([ThisNode]),
+ mnesia_test_lib:start_sync_transactions([A], 0),
+
+ A ! fun() -> mnesia:write({Tab, 1, 2, 3}) end,
+ ?match_receive({A, ok}), %% A is executed
+
+ Pid = spawn_link(?MODULE, op, [self(), mnesia, move_table_copy,
+ [Tab, ThisNode, Node2]]),
+
+ ?match_receive(timeout), %% op waits for locks occupied by A
+
+ A ! end_trans, %% Kill A, locks should be released
+ ?match_receive({A,{atomic,end_trans}}),
+
+ receive
+ Msg -> ?match({Pid, {atomic, ok}}, Msg)
+ after
+ timer:seconds(20) -> ?error("Operation timed out", [])
+ end,
+
+ timer:sleep(500), %% Don't know how to sync this !!!
+ sys:get_status(whereis(mnesia_locker)), % Explicit sync, release locks is async
+ sys:get_status(whereis(mnesia_tm)), % Explicit sync, release locks is async
+ sys:get_status(whereis(mnesia_locker)), % Explicit sync, release locks is async
+ ?match([], mnesia:system_info(held_locks)),
+ ?match([], mnesia:system_info(lock_queue)),
+ ok.
+
+add_table_index(suite) -> [];
+add_table_index(Config) when is_list(Config) ->
+ [ThisNode, _Node2] = ?acquire_nodes(2, Config ++ [{tc_timeout, 60000}]),
+ Tab = a_t_i_tab,
+ Def = [{ram_copies, [ThisNode]}, {attributes, [key, attr1, attr2]}],
+ ?match({atomic, ok}, mnesia:create_table(Tab, Def)),
+ insert(Tab, 50),
+ {success, [A]} = ?start_activities([ThisNode]),
+ mnesia_test_lib:start_sync_transactions([A], 0),
+
+ A ! fun() -> mnesia:write({Tab, 1, 1, updated}) end,
+ ?match_receive({A, ok}), %% A is executed
+
+ Pid = spawn_link(?MODULE, op, [self(), mnesia,
+ add_table_index, [Tab, attr1]]),
+
+ ?match_receive(timeout), %% op waits for locks occupied by A
+
+ A ! end_trans, %% Kill A, locks should be released
+ ?match_receive({A,{atomic,end_trans}}),
+
+ receive
+ Msg -> ?match({Pid, {atomic, ok}}, Msg)
+ after
+ timer:seconds(20) -> ?error("Operation timed out", [])
+ end,
+
+ sys:get_status(whereis(mnesia_locker)), % Explicit sync, release locks is async
+ ?match([], mnesia:system_info(held_locks)),
+ ?match([], mnesia:system_info(lock_queue)),
+ ok.
+
+del_table_index(suite) -> [];
+del_table_index(Config) when is_list(Config) ->
+ [ThisNode, _Node2] = ?acquire_nodes(2, Config),
+ Tab = d_t_i_tab,
+ Def = [{ram_copies, [ThisNode]}, {attributes, [key, attr1, attr2]}],
+ ?match({atomic, ok}, mnesia:create_table(Tab, Def)),
+ insert(Tab, 50),
+ ?match({atomic, ok}, mnesia:add_table_index(Tab, attr1)),
+
+ {success, [A]} = ?start_activities([ThisNode]),
+ mnesia_test_lib:start_sync_transactions([A], 0),
+
+ A ! fun() -> mnesia:write({Tab, 51, 51, attr2}) end,
+ ?match_receive({A, ok}), %% A is executed
+
+ Pid = spawn_link(?MODULE, op, [self(), mnesia, del_table_index,
+ [Tab, attr1]]),
+
+ ?match_receive(timeout), %% op waits for locks occupied by A
+
+ A ! end_trans, %% Kill A, locks should be released
+ ?match_receive({A,{atomic,end_trans}}),
+ %% Locks released! op should be exec.
+ receive
+ Msg -> ?match({Pid, {atomic, ok}}, Msg)
+ after
+ timer:seconds(20) -> ?error("Operation timed out", [])
+ end,
+
+ sys:get_status(whereis(mnesia_locker)), % Explicit sync, release locks is async
+ ?match([], mnesia:system_info(held_locks)),
+ ?match([], mnesia:system_info(lock_queue)),
+ ok.
+
+transform_table(suite) -> [];
+transform_table(Config) when is_list(Config) ->
+ [ThisNode, Node2] = ?acquire_nodes(2, Config),
+ Tab = t_t_tab,
+ Def = [{ram_copies, [ThisNode, Node2]}, {attributes, [key, attr1, attr2]}],
+ ?match({atomic, ok}, mnesia:create_table(Tab, Def)),
+ insert(Tab, 50),
+ {success, [A]} = ?start_activities([ThisNode]),
+ mnesia_test_lib:start_sync_transactions([A], 0),
+
+ A ! fun() -> mnesia:read({Tab, 1}) end,
+ ?match_receive({A, [{Tab, 1, 1, 0}]}), %% A is executed
+
+ Transform = fun({Table, Key, Attr1, Attr2}) -> % Need todo a transform
+ {Table, Key, {Attr1, Attr2}} end,
+ Pid = spawn_link(?MODULE, op, [self(), mnesia, transform_table,
+ [Tab, Transform, [key, attr1]]]),
+ ?match_receive(timeout), %% op waits for locks occupied by A
+
+ A ! end_trans, %% Kill A, locks should be released
+ ?match_receive({A,{atomic,end_trans}}),
+
+ receive
+ Msg -> ?match({Pid, {atomic, ok}}, Msg)
+ after
+ timer:seconds(20) -> ?error("Operation timed out", [])
+ end,
+
+ sys:get_status(whereis(mnesia_locker)), % Explicit sync, release locks is async
+ ?match([], mnesia:system_info(held_locks)),
+ ?match([], mnesia:system_info(lock_queue)),
+ ok.
+
+snmp_open_table(suite) -> [];
+snmp_open_table(Config) when is_list(Config) ->
+ [ThisNode, _Node2] = ?acquire_nodes(2, Config),
+ Tab = s_o_t_tab,
+ Def = [{ram_copies, [ThisNode]}, {attributes, [key, attr1, attr2]}],
+ ?match({atomic, ok}, mnesia:create_table(Tab, Def)),
+ insert(Tab, 50),
+ {success, [A]} = ?start_activities([ThisNode]),
+ mnesia_test_lib:start_sync_transactions([A], 0),
+
+ A ! fun() -> mnesia:write({Tab, 1, 1, 100}) end,
+ ?match_receive({A, ok}), %% A is executed
+
+ Pid = spawn_link(?MODULE, op, [self(), mnesia, snmp_open_table,
+ [Tab, [{key, integer}]]]),
+
+ ?match_receive(timeout), %% op waits for locks occupied by A
+
+ A ! end_trans, %% Kill A, locks should be released
+ ?match_receive({A,{atomic,end_trans}}),
+
+ %% Locks released! op should be exec. Can take a while (thats the timeout)
+ receive
+ Msg -> ?match({Pid, {atomic, ok}}, Msg)
+ after
+ timer:seconds(20) -> ?error("Operation timed out", [])
+ end,
+
+ sys:get_status(whereis(mnesia_locker)), % Explicit sync, release locks is async
+ ?match([], mnesia:system_info(held_locks)),
+ ?match([], mnesia:system_info(lock_queue)),
+ ok.
+
+snmp_close_table(suite) -> [];
+snmp_close_table(Config) when is_list(Config) ->
+ [ThisNode, _Node2] = ?acquire_nodes(2, Config),
+ Tab = s_c_t_tab,
+ Def = [{ram_copies, [ThisNode]}, {attributes, [key, attr1, attr2]}],
+ ?match({atomic, ok}, mnesia:create_table(Tab, Def)),
+ ?match({atomic, ok}, mnesia:snmp_open_table(Tab, [{key, integer}])),
+ insert(Tab, 50),
+ {success, [A]} = ?start_activities([ThisNode]),
+ mnesia_test_lib:start_sync_transactions([A], 0),
+
+ A ! fun() -> mnesia:write({Tab, 1, 1, 100}) end,
+ ?match_receive({A, ok}), %% A is executed
+
+ Pid = spawn_link(?MODULE, op, [self(), mnesia, snmp_close_table, [Tab]]),
+ ?match_receive(timeout), %% op waits for locks occupied by A
+
+ A ! end_trans, %% Kill A, locks should be released
+ ?match_receive({A,{atomic,end_trans}}),
+
+ %% Locks released! op should be exec. Can take a while (thats the timeout)
+ receive
+ Msg -> ?match({Pid, {atomic, ok}}, Msg)
+ after
+ timer:seconds(20) -> ?error("Operation timed out", [])
+ end,
+
+ sys:get_status(whereis(mnesia_locker)), % Explicit sync, release locks is async
+ ?match([], mnesia:system_info(held_locks)),
+ ?match([], mnesia:system_info(lock_queue)),
+ ok.
+
+change_table_copy_type(suite) -> [];
+change_table_copy_type(Config) when is_list(Config) ->
+ [ThisNode, _Node2] = ?acquire_nodes(2, Config),
+ Tab = c_t_c_t_tab,
+ Def = [{ram_copies, [ThisNode]}, {attributes, [key, attr1, attr2]}],
+ ?match({atomic, ok}, mnesia:create_table(Tab, Def)),
+ insert(Tab, 50),
+ {success, [A]} = ?start_activities([ThisNode]),
+ mnesia_test_lib:start_sync_transactions([A], 0),
+ A ! fun() -> mnesia:write({Tab, 1, 1, updated}) end,
+ ?match_receive({A, ok}), %% A is executed
+
+ Pid = spawn_link(?MODULE, op, [self(), mnesia, change_table_copy_type,
+ [Tab, ThisNode, disc_copies]]),
+
+ ?match_receive(timeout), %% op waits for locks occupied by A
+
+ A ! end_trans, %% Kill A, locks should be released
+ ?match_receive({A,{atomic,end_trans}}),
+
+ receive
+ Msg -> ?match({Pid, {atomic, ok}}, Msg)
+ after
+ timer:seconds(20) -> ?error("Operation timed out", [])
+ end,
+
+ sys:get_status(whereis(mnesia_locker)), % Explicit sync, release locks is async
+ ?match([], mnesia:system_info(held_locks)),
+ ?match([], mnesia:system_info(lock_queue)),
+ ok.
+
+change_table_access(suite) -> [];
+change_table_access(Config) when is_list(Config) ->
+ [ThisNode, _Node2] = ?acquire_nodes(2, Config),
+ Tab = c_t_a_tab,
+ Def = [{ram_copies, [ThisNode]}, {attributes, [key, attr1, attr2]}],
+ ?match({atomic, ok}, mnesia:create_table(Tab, Def)),
+ insert(Tab, 50),
+ {success, [A]} = ?start_activities([ThisNode]),
+ mnesia_test_lib:start_sync_transactions([A], 0),
+
+ A ! fun() -> mnesia:write({Tab, 1, 1, updated}) end,
+ ?match_receive({A, ok}), %% A is executed
+
+ Pid = spawn_link(?MODULE, op, [self(), mnesia, change_table_access_mode,
+ [Tab, read_only]]),
+
+
+ ?match_receive(timeout), %% op waits for locks occupied by A
+
+ A ! end_trans, %% Kill A, locks should be released
+ ?match_receive({A,{atomic,end_trans}}),
+
+ receive
+ Msg -> ?match({Pid, {atomic, ok}}, Msg)
+ after
+ timer:seconds(20) -> ?error("Operation timed out", [])
+ end,
+
+ sys:get_status(whereis(mnesia_locker)), % Explicit sync, release locks is async
+ ?match([], mnesia:system_info(held_locks)),
+ ?match([], mnesia:system_info(lock_queue)),
+ ok.
+
+add_table_copy(suite) -> [];
+add_table_copy(Config) when is_list(Config) ->
+ [ThisNode, Node2] = ?acquire_nodes(2, Config),
+ Tab = a_t_c_tab,
+ Def = [{ram_copies, [ThisNode]}, {attributes, [key, attr1, attr2]}],
+ ?match({atomic, ok}, mnesia:create_table(Tab, Def)),
+ insert(Tab, 50),
+ {success, [A]} = ?start_activities([ThisNode]),
+ mnesia_test_lib:start_sync_transactions([A], 0),
+
+ A ! fun() -> mnesia:write({Tab, 1, 1, updated}) end,
+ ?match_receive({A, ok}), %% A is executed
+
+ Pid = spawn_link(?MODULE, op, [self(), mnesia, add_table_copy,
+ [Tab, Node2, ram_copies]]),
+
+ ?match_receive(timeout), %% op waits for locks occupied by A
+
+ A ! end_trans, %% Kill A, locks should be released
+ ?match_receive({A,{atomic,end_trans}}),
+
+ receive
+ Msg -> ?match({Pid, {atomic, ok}}, Msg)
+ after
+ timer:seconds(20) -> ?error("Operation timed out", [])
+ end,
+
+ sys:get_status(whereis(mnesia_locker)), % Explicit sync, release locks is async
+ ?match([], mnesia:system_info(held_locks)),
+ ?match([], mnesia:system_info(lock_queue)),
+ ok.
+
+del_table_copy(suite) -> [];
+del_table_copy(Config) when is_list(Config) ->
+ [ThisNode, Node2] = ?acquire_nodes(2, Config),
+ Tab = d_t_c_tab,
+ Def = [{ram_copies, [ThisNode, Node2]}, {attributes, [key, attr1, attr2]}],
+ ?match({atomic, ok}, mnesia:create_table(Tab, Def)),
+ insert(Tab, 50),
+ {success, [A]} = ?start_activities([ThisNode]),
+ mnesia_test_lib:start_sync_transactions([A], 0),
+ A ! fun() -> mnesia:write({Tab, 1, 2, 5}) end,
+ ?match_receive({A, ok}), %% A is executed
+
+ Pid = spawn_link(?MODULE, op, [self(), mnesia, del_table_copy,
+ [Tab, ThisNode]]),
+
+ ?match_receive(timeout), %% op waits for locks occupied by A
+ A ! end_trans, %% Kill A, locks should be released
+ ?match_receive({A, {atomic,end_trans}}),
+
+ ?match_receive({Pid, {atomic, ok}}),
+ ?match_receive({'EXIT', Pid, normal}),
+
+ timer:sleep(500), %% Don't know how to sync this !!!
+ sys:get_status(whereis(mnesia_locker)), % Explicit sync, release locks is async
+ sys:get_status(whereis(mnesia_tm)), % Explicit sync, release locks is async
+ sys:get_status(whereis(mnesia_locker)), % Explicit sync, release locks is async
+ ?match([], mnesia:system_info(held_locks)),
+ ?match([], mnesia:system_info(lock_queue)),
+ ok.
+
+dump_tables(suite) -> [];
+dump_tables(Config) when is_list(Config) ->
+ [ThisNode, Node2] = ?acquire_nodes(2, Config),
+ Tab = dump_t_tab,
+ Def = [{ram_copies, [ThisNode, Node2]}, {attributes, [key, attr1, attr2]}],
+ ?match({atomic, ok}, mnesia:create_table(Tab, Def)),
+ insert(Tab, 50),
+ {success, [A]} = ?start_activities([ThisNode]),
+ mnesia_test_lib:start_sync_transactions([A], 0),
+ A ! fun() -> mnesia:write({Tab, 1, 1, updated}) end,
+ ?match_receive({A, ok}), %% A is executed
+
+ Pid = spawn_link(?MODULE, op, [self(), mnesia, dump_tables,
+ [[Tab]]]),
+
+ ?match_receive(timeout), %% op waits for locks occupied by A
+
+ A ! end_trans, %% Kill A, locks should be released
+ ?match_receive({A,{atomic,end_trans}}),
+
+ receive
+ Msg -> ?match({Pid, {atomic, ok}}, Msg)
+ after
+ timer:seconds(20) -> ?error("Operation timed out", [])
+ end,
+
+ sys:get_status(whereis(mnesia_locker)), % Explicit sync, release locks is async
+ ?match([], mnesia:system_info(held_locks)),
+ ?match([], mnesia:system_info(lock_queue)),
+ ok.
+
+op(Father, Mod, Fun, Args) ->
+ Res = apply(Mod, Fun, Args),
+ Father ! {self(), Res}.
+
+insert(_Tab, 0) -> ok;
+insert(Tab, N) when N > 0 ->
+ ok = mnesia:sync_dirty(fun() -> mnesia:write({Tab, N, N, 0}) end),
+ insert(Tab, N-1).
+
+extra_admin_tests(suite) ->
+ [del_table_copy_1,
+ del_table_copy_2,
+ del_table_copy_3,
+ add_table_copy_1,
+ add_table_copy_2,
+ add_table_copy_3,
+ add_table_copy_4,
+ move_table_copy_1,
+ move_table_copy_2,
+ move_table_copy_3,
+ move_table_copy_4].
+
+update_own(Tab, Key, Acc) ->
+ Update =
+ fun() ->
+ Res = mnesia:read({Tab, Key}),
+ case Res of
+ [{Tab, Key, Extra, Acc}] ->
+ mnesia:write({Tab,Key,Extra, Acc+1});
+ Val ->
+ {read, Val, {acc, Acc}}
+ end
+ end,
+ receive
+ {Pid, quit} -> Pid ! {self(), Acc}
+ after
+ 0 ->
+ case mnesia:transaction(Update) of
+ {atomic, ok} ->
+ update_own(Tab, Key, Acc+1);
+ Else ->
+ ?error("Trans failed on ~p with ~p~n"
+ "Info w2read ~p w2write ~p w2commit ~p storage ~p ~n",
+ [node(),
+ Else,
+ mnesia:table_info(Tab, where_to_read),
+ mnesia:table_info(Tab, where_to_write),
+ mnesia:table_info(Tab, where_to_commit),
+ mnesia:table_info(Tab, storage_type)])
+ end
+ end.
+
+update_shared(Tab, Me, Acc) ->
+ Update =
+ fun() ->
+ W2R = mnesia:table_info(Tab, where_to_read),
+ Res = mnesia:read({Tab, 0}),
+ case Res of
+ [{Tab, Key, Extra, Val}] when element(Me, Extra) == Acc ->
+ Extra1 = setelement(Me, Extra, Acc+1),
+ Term = {Tab, Key, Extra1, Val+1},
+ ok = mnesia:write(Term),
+% ?log("At ~p: ~p w2r ~p w2w ~p ~n",
+% [node(), Term,
+% mnesia:table_info(Tab, where_to_read),
+ W2W = mnesia:table_info(Tab, where_to_write),
+ W2C = mnesia:table_info(Tab, where_to_commit),
+%% mnesia:table_info(Tab, storage_type)
+% ]),
+ {_Mod, Tid, Ts} = get(mnesia_activity_state),
+ io:format("~p ~p~n", [Tid, ets:tab2list(element(2,Ts))]),
+ {ok,Term,{W2R,W2W,W2C}};
+ Val ->
+ Info = [{acc, Acc}, {me, Me},
+ {tid, element(2, mnesia:get_activity_id())},
+ {locks, mnesia:system_info(held_locks)}],
+ {read, Val, Info}
+ end
+ end,
+ receive
+ {Pid, quit} -> Pid ! {self(), Acc}
+ after
+ 0 ->
+ case mnesia:transaction(Update) of
+ {atomic, {ok,Term,W2}} ->
+ io:format("~p:~p:(~p,~p) ~w@~w~n", [erlang:now(),node(),Me,Acc,Term,W2]),
+ update_shared(Tab, Me, Acc+1);
+ Else ->
+ ?error("Trans failed on ~p with ~p~n"
+ "Info w2read ~p w2write ~p w2commit ~p storage ~p ~n",
+ [node(),
+ Else,
+ mnesia:table_info(Tab, where_to_read),
+ mnesia:table_info(Tab, where_to_write),
+ mnesia:table_info(Tab, where_to_commit),
+ mnesia:table_info(Tab, storage_type)
+ ])
+ end
+ end.
+
+init_admin(Def, N1, N2, N3) ->
+ Tab = schema_ops,
+ ?match({atomic, ok}, mnesia:create_table(Tab, Def)),
+ insert(Tab, 1002),
+
+ Pid1 = spawn_link(N1, ?MODULE, update_own, [Tab, 1, 0]),
+ Pid2 = spawn_link(N2, ?MODULE, update_own, [Tab, 2, 0]),
+ Pid3 = spawn_link(N3, ?MODULE, update_own, [Tab, 3, 0]),
+
+ ?match({atomic, ok},
+ mnesia:transaction(fun() -> mnesia:write({Tab, 0, {0,0,0}, 0}) end)),
+
+ Pid4 = spawn_link(N1, ?MODULE, update_shared, [Tab, 1, 0]),
+ Pid5 = spawn_link(N2, ?MODULE, update_shared, [Tab, 2, 0]),
+ Pid6 = spawn_link(N3, ?MODULE, update_shared, [Tab, 3, 0]),
+
+ {Pid1, Pid2, Pid3, Pid4, Pid5, Pid6}.
+
+verify_results({P1, P2, P3, P4, P5, P6}) ->
+ Tab = schema_ops, N1 = node(P1), N2 = node(P2), N3 = node(P3),
+
+ try
+ P1 ! {self(), quit},
+ R1 = receive {P1, Res1} -> Res1 after 9000 -> throw({timeout,P1}) end,
+ P2 ! {self(), quit},
+ R2 = receive {P2, Res2} -> Res2 after 9000 -> throw({timeout,P2}) end,
+ P3 ! {self(), quit},
+ R3 = receive {P3, Res3} -> Res3 after 9000 -> throw({timeout,P3}) end,
+
+ P4 ! {self(), quit},
+ R4 = receive {P4, Res4} -> Res4 after 9000 -> throw({timeout,P4}) end,
+ P5 ! {self(), quit},
+ R5 = receive {P5, Res5} -> Res5 after 9000 -> throw({timeout,P5}) end,
+ P6 ! {self(), quit},
+ R6 = receive {P6, Res6} -> Res6 after 9000 -> throw({timeout,P6}) end,
+
+ ?match({atomic, ok}, mnesia:transaction(fun() -> mnesia:write_lock_table(Tab) end)),
+ ?log("Should be ~p~n", [R1]),
+ ?match([{_, _, _, R1}], rpc:call(N1, mnesia, dirty_read, [{Tab, 1}])),
+ ?match([{_, _, _, R1}], rpc:call(N2, mnesia, dirty_read, [{Tab, 1}])),
+ ?match([{_, _, _, R1}], rpc:call(N3, mnesia, dirty_read, [{Tab, 1}])),
+ ?log("Should be ~p~n", [R2]),
+ ?match([{_, _, _, R2}], rpc:call(N1, mnesia, dirty_read, [{Tab, 2}])),
+ ?match([{_, _, _, R2}], rpc:call(N2, mnesia, dirty_read, [{Tab, 2}])),
+ ?match([{_, _, _, R2}], rpc:call(N3, mnesia, dirty_read, [{Tab, 2}])),
+ ?log("Should be ~p~n", [R3]),
+ ?match([{_, _, _, R3}], rpc:call(N1, mnesia, dirty_read, [{Tab, 3}])),
+ ?match([{_, _, _, R3}], rpc:call(N2, mnesia, dirty_read, [{Tab, 3}])),
+ ?match([{_, _, _, R3}], rpc:call(N3, mnesia, dirty_read, [{Tab, 3}])),
+
+ Res = R4+R5+R6,
+ ?log("Should be {~p+~p+~p}= ~p~n", [R4, R5, R6, Res]),
+ ?match([{_, _, {R4,R5,R6}, Res}], rpc:call(N1, mnesia, dirty_read, [{Tab, 0}])),
+ ?match([{_, _, {R4,R5,R6}, Res}], rpc:call(N2, mnesia, dirty_read, [{Tab, 0}])),
+ ?match([{_, _, {R4,R5,R6}, Res}], rpc:call(N3, mnesia, dirty_read, [{Tab, 0}]))
+ catch throw:{timeout, Pid} ->
+ mnesia_lib:dist_coredump(),
+ ?error("Timeout ~p ~n", [Pid])
+ end.
+
+
+get_info(Tab) ->
+ Info = mnesia:table_info(Tab, all),
+ mnesia_lib:verbose("~p~n", [Info]).
+
+del_table_copy_1(suite) -> [];
+del_table_copy_1(Config) when is_list(Config) ->
+ [_Node1, Node2, _Node3] = Nodes = ?acquire_nodes(3, Config),
+ del_table(Node2, Node2, Nodes). %Called on same Node as deleted
+del_table_copy_2(suite) -> [];
+del_table_copy_2(Config) when is_list(Config) ->
+ [Node1, Node2, _Node3] = Nodes = ?acquire_nodes(3, Config),
+ del_table(Node1, Node2, Nodes). %Called from other Node
+del_table_copy_3(suite) -> [];
+del_table_copy_3(Config) when is_list(Config) ->
+ [_Node1, Node2, Node3] = Nodes = ?acquire_nodes(3, Config),
+ del_table(Node3, Node2, Nodes). %Called from Node w.o. table
+
+%%% The actual test
+del_table(CallFrom, DelNode, [Node1, Node2, Node3]) ->
+ Def = [{ram_copies, [Node1]}, {disc_copies, [Node2]},
+ {attributes, [key, attr1, attr2]}],
+ Tab = schema_ops,
+ Pids = init_admin(Def, Node1, Node2, Node3),
+
+ ?log("Call from ~p delete table from ~p ~n", [CallFrom, DelNode]),
+ rpc:multicall([Node1, Node2, Node3], ?MODULE, get_info, [Tab]),
+
+ ?match({atomic, ok},
+ rpc:call(CallFrom, mnesia, del_table_copy, [Tab, DelNode])),
+
+ verify_results(Pids),
+ rpc:multicall([Node1, Node2, Node3], ?MODULE, get_info, [Tab]),
+ ?verify_mnesia([Node1, Node2, Node3], []).
+
+add_table_copy_1(suite) -> [];
+add_table_copy_1(Config) when is_list(Config) ->
+ [Node1, Node2, Node3] = Nodes = ?acquire_nodes(3, Config),
+ Def = [{disc_only_copies, [Node1, Node2]},
+ {attributes, [key, attr1, attr2]}],
+ add_table(Node1, Node3, Nodes, Def).
+add_table_copy_2(suite) -> [];
+add_table_copy_2(Config) when is_list(Config) ->
+ [Node1, Node2, Node3] = Nodes = ?acquire_nodes(3, Config),
+ Def = [{disc_only_copies, [Node1, Node2]},
+ {attributes, [key, attr1, attr2]}],
+ add_table(Node2, Node3, Nodes, Def).
+add_table_copy_3(suite) -> [];
+add_table_copy_3(Config) when is_list(Config) ->
+ [Node1, Node2, Node3] = Nodes = ?acquire_nodes(3, Config),
+ Def = [{disc_only_copies, [Node1, Node2]},
+ {attributes, [key, attr1, attr2]}],
+ add_table(Node3, Node3, Nodes, Def).
+add_table_copy_4(suite) -> [];
+add_table_copy_4(Config) when is_list(Config) ->
+ [Node1, Node2, Node3] = Nodes = ?acquire_nodes(3, Config),
+ Def = [{disc_only_copies, [Node1]},
+ {attributes, [key, attr1, attr2]}],
+ add_table(Node2, Node3, Nodes, Def).
+%%% The actual test
+add_table(CallFrom, AddNode, [Node1, Node2, Node3], Def) ->
+ Pids = init_admin(Def, Node1, Node2, Node3),
+ Tab = schema_ops,
+ ?log("Call from ~p add table to ~p ~n", [CallFrom, AddNode]),
+ rpc:multicall([Node1, Node2, Node3], ?MODULE, get_info, [Tab]),
+ ?match({atomic, ok}, rpc:call(CallFrom, mnesia, add_table_copy,
+ [Tab, AddNode, ram_copies])),
+ verify_results(Pids),
+ rpc:multicall([Node1, Node2, Node3], ?MODULE, get_info, [Tab]),
+ ?verify_mnesia([Node1, Node2, Node3], []).
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+move_table_copy_1(suite) -> [];
+move_table_copy_1(Config) when is_list(Config) ->
+ [Node1, Node2, Node3] = Nodes = ?acquire_nodes(3, Config),
+ Def = [{disc_copies, [Node1, Node2]},
+ {attributes, [key, attr1, attr2]}],
+ move_table(Node1, Node1, Node3, Nodes, Def).
+move_table_copy_2(suite) -> [];
+move_table_copy_2(Config) when is_list(Config) ->
+ [Node1, Node2, Node3] = Nodes = ?acquire_nodes(3, Config),
+ Def = [{disc_copies, [Node1, Node2]},
+ {attributes, [key, attr1, attr2]}],
+ move_table(Node2, Node1, Node3, Nodes, Def).
+move_table_copy_3(suite) -> [];
+move_table_copy_3(Config) when is_list(Config) ->
+ [Node1, Node2, Node3] = Nodes = ?acquire_nodes(3, Config),
+ Def = [{disc_copies, [Node1, Node2]},
+ {attributes, [key, attr1, attr2]}],
+ move_table(Node3, Node1, Node3, Nodes, Def).
+move_table_copy_4(suite) -> [];
+move_table_copy_4(Config) when is_list(Config) ->
+ [Node1, Node2, Node3] = Nodes = ?acquire_nodes(3, Config),
+ Def = [{disc_copies, [Node1]},
+ {attributes, [key, attr1, attr2]}],
+ move_table(Node2, Node1, Node3, Nodes, Def).
+%%% The actual test
+move_table(CallFrom, FromNode, ToNode, [Node1, Node2, Node3], Def) ->
+ Pids = init_admin(Def, Node1, Node2, Node3),
+ Tab = schema_ops,
+ ?log("Call from ~p move table from ~p to ~p ~n", [CallFrom, FromNode, ToNode]),
+ rpc:multicall([Node1, Node2, Node3], ?MODULE, get_info, [Tab]),
+ ?match({atomic, ok}, rpc:call(CallFrom, mnesia, move_table_copy,
+ [Tab, FromNode, ToNode])),
+ verify_results(Pids),
+ rpc:multicall([Node1, Node2, Node3], ?MODULE, get_info, [Tab]),
+ ?verify_mnesia([Node1, Node2, Node3], []).
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+visibility(doc) ->
+ ["Verify the visibility semantics for various configurations"];
+visibility(suite) ->
+ [
+ dirty_updates_visible_direct,
+ dirty_reads_regardless_of_trans,
+ trans_update_invisibible_outside_trans,
+ trans_update_visible_inside_trans,
+ write_shadows,
+ delete_shadows,
+%% delete_shadows2,
+ write_delete_shadows_bag,
+ write_delete_shadows_bag2,
+ iteration,
+ shadow_search,
+ snmp_shadows
+ ].
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+dirty_updates_visible_direct(doc) ->
+ ["One process can immediately see dirty updates of another"];
+dirty_updates_visible_direct(suite) -> [];
+dirty_updates_visible_direct(Config) when is_list(Config) ->
+ dirty_visibility(outside_trans, Config).
+
+dirty_reads_regardless_of_trans(doc) ->
+ ["Dirty reads are not affected by transaction context"];
+dirty_reads_regardless_of_trans(suite) -> [];
+dirty_reads_regardless_of_trans(Config) when is_list(Config) ->
+ dirty_visibility(inside_trans, Config).
+
+dirty_visibility(Mode, Config) ->
+ [Node1] = ?acquire_nodes(1, Config),
+ Tab = list_to_atom(lists:concat([dirty_visibility, '_', Mode])),
+
+ ?match({atomic, ok}, mnesia:create_table([{name, Tab}, {ram_copies, [Node1]}])),
+ ValPos = 3,
+
+ ?match({atomic, ok}, mnesia:add_table_index(Tab, ValPos)),
+
+ %% Start two processes
+ {success, [A]} = ?start_activities([Node1]),
+
+ case Mode of
+ inside_trans ->
+ ?start_transactions([A]),
+ A ! fun() ->
+ mnesia:write({Tab, a, 11}),
+ mnesia:write({Tab, b, 22}),
+ mnesia:write({Tab, c, 1}),
+ mnesia:write({Tab, d, 2}),
+ mnesia:write({Tab, e, 3}),
+ lists:sort(mnesia:all_keys(Tab))
+ end,
+ ?match_receive({A, [a, b, c, d, e]});
+ outside_trans ->
+ ignore
+ end,
+
+ RecA = {Tab, a, 1},
+ PatA = {Tab, '$1', 1},
+ RecB = {Tab, b, 3},
+ PatB = {Tab, '$1', 3},
+ RecB2 = {Tab, b, 2},
+ PatB2 = {Tab, '$1', 2},
+ ?match([], mnesia:dirty_read({Tab, a})),
+ ?match([], mnesia:dirty_read({Tab, b})),
+ ?match([], mnesia:dirty_match_object(PatA)),
+ ?match([], mnesia:dirty_match_object(PatB)),
+ ?match([], mnesia:dirty_match_object(PatB2)),
+ ?match([], mnesia:dirty_index_read(Tab, 1, ValPos)),
+ ?match([], mnesia:dirty_index_read(Tab, 3, ValPos)),
+ ?match([], mnesia:dirty_index_match_object(PatA, ValPos)),
+ ?match([], mnesia:dirty_index_match_object(PatB, ValPos)),
+ ?match([], mnesia:dirty_index_match_object(PatB2, ValPos)),
+ ?match('$end_of_table', mnesia:dirty_first(Tab)),
+
+ %% dirty_write
+ A ! fun() -> mnesia:dirty_write(RecA) end,
+ ?match_receive({A, ok}),
+ ?match([RecA], mnesia:dirty_read({Tab, a})),
+ ?match([RecA], mnesia:dirty_match_object(PatA)),
+ ?match(a, mnesia:dirty_first(Tab)),
+ ?match([RecA], mnesia:dirty_index_read(Tab, 1, ValPos)),
+ ?match([RecA], mnesia:dirty_index_match_object(PatA, ValPos)),
+ ?match('$end_of_table', mnesia:dirty_next(Tab, a)),
+
+ %% dirty_create
+ A ! fun() -> mnesia:dirty_write(RecB) end,
+ ?match_receive({A, ok}),
+ ?match([RecB], mnesia:dirty_read({Tab, b})),
+ ?match([RecB], mnesia:dirty_match_object(PatB)),
+ ?match([RecB], mnesia:dirty_index_read(Tab, 3, ValPos)),
+ ?match([RecB], mnesia:dirty_index_match_object(PatB, ValPos)),
+ ?match('$end_of_table',
+ mnesia:dirty_next(Tab, mnesia:dirty_next(Tab, mnesia:dirty_first(Tab)))),
+
+ %% dirty_update_counter
+ A ! fun() -> mnesia:dirty_update_counter({Tab, b}, -1) end,
+ ?match_receive({A, _}),
+ ?match([RecB2], mnesia:dirty_read({Tab, b})),
+ ?match([], mnesia:dirty_match_object(PatB)),
+ ?match([RecB2], mnesia:dirty_match_object(PatB2)),
+ ?match([RecB2], mnesia:dirty_index_read(Tab, 2, ValPos)),
+ ?match([], mnesia:dirty_index_match_object(PatB, ValPos)),
+ ?match([RecB2], mnesia:dirty_index_match_object(PatB2, ValPos)),
+ ?match('$end_of_table',
+ mnesia:dirty_next(Tab, mnesia:dirty_next(Tab, mnesia:dirty_first(Tab)))),
+
+ %% dirty_delete
+ A ! fun() -> mnesia:dirty_delete({Tab, b}) end,
+ ?match_receive({A, ok}),
+ ?match([], mnesia:dirty_read({Tab, b})),
+ ?match([], mnesia:dirty_match_object(PatB2)),
+ ?match([], mnesia:dirty_index_read(Tab, 3, ValPos)),
+ ?match([], mnesia:dirty_index_match_object(PatB2, ValPos)),
+ ?match(a, mnesia:dirty_first(Tab)),
+ ?match('$end_of_table', mnesia:dirty_next(Tab, a)),
+
+ %% dirty_delete_object
+ ?match([RecA], mnesia:dirty_match_object(PatA)),
+ A ! fun() -> mnesia:dirty_delete_object(RecA) end,
+ ?match_receive({A, ok}),
+ ?match([], mnesia:dirty_read({Tab, a})),
+ ?match([], mnesia:dirty_match_object(PatA)),
+ ?match([], mnesia:dirty_index_read(Tab, 1, ValPos)),
+ ?match([], mnesia:dirty_index_match_object(PatA, ValPos)),
+ ?match('$end_of_table', mnesia:dirty_first(Tab)),
+
+ case Mode of
+ inside_trans ->
+ A ! end_trans,
+ ?match_receive({A, {atomic, end_trans}});
+ outside_trans ->
+ ignore
+ end,
+ ok.
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+trans_update_invisibible_outside_trans(doc) ->
+ ["Updates in a transaction are invisible outside the transaction"];
+trans_update_invisibible_outside_trans(suite) -> [];
+trans_update_invisibible_outside_trans(Config) when is_list(Config) ->
+ [Node1] = ?acquire_nodes(1, Config),
+ Tab = trans_update_invisibible_outside_trans,
+
+ ?match({atomic, ok}, mnesia:create_table([{name, Tab},
+ {ram_copies, [Node1]}])),
+ ValPos = 3,
+ RecA = {Tab, a, 1},
+ PatA = {Tab, '$1', 1},
+ RecB = {Tab, b, 3},
+ PatB = {Tab, '$1', 3},
+ ?match({atomic, ok}, mnesia:add_table_index(Tab, ValPos)),
+
+ Verify =
+ fun() ->
+ ?match([], mnesia:dirty_read({Tab, a})),
+ ?match([], mnesia:dirty_read({Tab, b})),
+ ?match([], mnesia:dirty_match_object(PatA)),
+ ?match([], mnesia:dirty_match_object(PatB)),
+ ?match([], mnesia:dirty_index_read(Tab, 1, ValPos)),
+ ?match([], mnesia:dirty_index_read(Tab, 3, ValPos)),
+ ?match([], mnesia:dirty_index_match_object(PatA, ValPos)),
+ ?match([], mnesia:dirty_index_match_object(PatB, ValPos)),
+ ?match('$end_of_table', mnesia:dirty_first(Tab))
+ end,
+
+ Fun = fun() ->
+ ?match(ok, mnesia:write(RecA)),
+ Verify(),
+
+ ?match(ok, mnesia:write(RecB)),
+ Verify(),
+
+ ?match(ok, mnesia:delete({Tab, b})),
+ Verify(),
+
+ ?match([RecA], mnesia:match_object(PatA)),
+ Verify(),
+
+ ?match(ok, mnesia:delete_object(RecA)),
+ Verify(),
+ ok
+ end,
+ ?match({atomic, ok}, mnesia:transaction(Fun)),
+ Verify(),
+ ok.
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+trans_update_visible_inside_trans(doc) ->
+ ["Updates in a transaction are visible in the same transaction"];
+trans_update_visible_inside_trans(suite) -> [];
+trans_update_visible_inside_trans(Config) when is_list(Config) ->
+ [Node1] = ?acquire_nodes(1, Config),
+ Tab = trans_update_visible_inside_trans,
+
+ ?match({atomic, ok}, mnesia:create_table([{name, Tab},
+ {ram_copies, [Node1]}])),
+ ValPos = 3,
+ RecA = {Tab, a, 1},
+ PatA = {Tab, '$1', 1},
+ RecB = {Tab, b, 3},
+ PatB = {Tab, '$1', 3},
+ ?match({atomic, ok}, mnesia:add_table_index(Tab, ValPos)),
+
+ Fun = fun() ->
+ %% write
+ ?match(ok, mnesia:write(RecA)),
+ ?match([RecA], mnesia:read({Tab, a})),
+ ?match([RecA], mnesia:wread({Tab, a})),
+ ?match([RecA], mnesia:match_object(PatA)),
+ ?match([a], mnesia:all_keys(Tab)),
+ ?match([RecA], mnesia:index_match_object(PatA, ValPos)),
+ ?match([RecA], mnesia:index_read(Tab, 1, ValPos)),
+
+ %% create
+ ?match(ok, mnesia:write(RecB)),
+ ?match([RecB], mnesia:read({Tab, b})),
+ ?match([RecB], mnesia:wread({Tab, b})),
+ ?match([RecB], mnesia:match_object(PatB)),
+ ?match([RecB], mnesia:index_match_object(PatB, ValPos)),
+ ?match([RecB], mnesia:index_read(Tab, 3, ValPos)),
+
+ %% delete
+ ?match(ok, mnesia:delete({Tab, b})),
+ ?match([], mnesia:read({Tab, b})),
+ ?match([], mnesia:wread({Tab, b})),
+ ?match([], mnesia:match_object(PatB)),
+ ?match([a], mnesia:all_keys(Tab)),
+ ?match([], mnesia:index_match_object(PatB, ValPos)),
+ ?match([], mnesia:index_read(Tab, 2, ValPos)),
+ ?match([], mnesia:index_read(Tab, 3, ValPos)),
+
+ %% delete_object
+ ?match(ok, mnesia:delete_object(RecA)),
+ ?match([], mnesia:read({Tab, a})),
+ ?match([], mnesia:wread({Tab, a})),
+ ?match([], mnesia:match_object(PatA)),
+ ?match([], mnesia:all_keys(Tab)),
+ ?match([], mnesia:index_match_object(PatA, ValPos)),
+ ?match([], mnesia:index_read(Tab, 2, ValPos)),
+ ?match([], mnesia:index_read(Tab, 3, ValPos)),
+ ok
+ end,
+ ?match({atomic, ok}, mnesia:transaction(Fun)),
+ ok.
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+write_shadows(doc) ->
+ ["Tests whether the shadow shows the correct object when",
+ "writing to the table"];
+write_shadows(suite) -> [];
+write_shadows(Config) when is_list(Config) ->
+ [Node1] = ?acquire_nodes(1, Config),
+ Tab = write_shadows,
+
+ ?match({atomic, ok}, mnesia:create_table([{name, Tab},
+ {ram_copies, [Node1]},
+ {type, set}])),
+ ValPos = 3,
+ RecA1 = {Tab, a, 1},
+ PatA1 = {Tab, '$1', 1},
+ RecA2 = {Tab, a, 2},
+ PatA2 = {Tab, '$1', 2},
+
+
+ ?match({atomic, ok}, mnesia:add_table_index(Tab, ValPos)),
+
+ Fun1 = fun() ->
+ ?match(ok, mnesia:write(RecA1)),
+ ok
+ end,
+
+ ?match({atomic, ok}, mnesia:transaction(Fun1)),
+
+ Fun2 = fun() ->
+ %% write shadow old write - is the confirmed value visable
+ %% in the shadow ?
+ ?match([RecA1], mnesia:read({Tab, a})),
+ ?match([RecA1], mnesia:wread({Tab, a})),
+ ?match([RecA1], mnesia:match_object(PatA1)),
+ ?match([a], mnesia:all_keys(Tab)),
+ ?match([RecA1], mnesia:index_match_object(PatA1, ValPos)),
+ ?match([RecA1], mnesia:index_read(Tab, 1, ValPos)),
+
+ %% write shadow new write - is a new value visable instead
+ %% of the old value ?
+ ?match(ok, mnesia:write(RecA2)),
+
+ ?match([RecA2], mnesia:read({Tab, a})),
+ ?match([RecA2], mnesia:wread({Tab, a})),
+ ?match([RecA2], mnesia:match_object(PatA2)), %% delete shadow old but not new write - is the new value visable
+
+ ?match([a], mnesia:all_keys(Tab)),
+ ?match([RecA2], mnesia:index_match_object(PatA2, ValPos)),
+ ?match([RecA2], mnesia:index_read(Tab, 2, ValPos)),
+ ok
+
+ end,
+ ?match({atomic, ok}, mnesia:transaction(Fun2)),
+ ok.
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+delete_shadows(doc) ->
+ ["Test whether the shadow shows the correct object when deleting objects"];
+delete_shadows(suite) -> [];
+delete_shadows(Config) when is_list(Config) ->
+ [Node1] = ?acquire_nodes(1, Config),
+ Tab = delete_shadows,
+
+ ?match({atomic, ok}, mnesia:create_table([{name, Tab},
+ {ram_copies, [Node1]},
+ {type, set}])),
+ ValPos = 3,
+ OidA = {Tab, a},
+ RecA1 = {Tab, a, 1},
+ PatA1 = {Tab, '$1', 1},
+ RecA2 = {Tab, a, 2},
+ PatA2 = {Tab, '$1', 2},
+
+
+ ?match({atomic, ok}, mnesia:add_table_index(Tab, ValPos)),
+
+ Fun1 = fun() ->
+ ?match(ok, mnesia:write(RecA1)),
+ ok
+ end,
+
+ ?match({atomic, ok}, mnesia:transaction(Fun1)),
+
+ Fun2 = fun() ->
+
+
+ %% delete shadow old write - is the confirmed value invisible
+ %% when deleted in the transaction ?
+ ?match(ok, mnesia:delete(OidA)),
+
+ ?match([], mnesia:read({Tab, a})),
+ ?match([], mnesia:wread({Tab, a})),
+ ?match([], mnesia:match_object(PatA1)),
+ ?match([], mnesia:all_keys(Tab)),
+ ?match([], mnesia:index_match_object(PatA1, ValPos)),
+ ?match([], mnesia:index_read(Tab, 1, ValPos)),
+
+ %% delete shadow old but not new write - is the new value visable
+ %% when the old one was deleted ?
+ ?match(ok, mnesia:write(RecA2)),
+
+ ?match([RecA2], mnesia:read({Tab, a})),
+ ?match([RecA2], mnesia:wread({Tab, a})),
+ ?match([RecA2], mnesia:match_object(PatA2)),
+ ?match([a], mnesia:all_keys(Tab)),
+ ?match([RecA2], mnesia:index_match_object(PatA2, ValPos)),
+ ?match([RecA2], mnesia:index_read(Tab, 2, ValPos)),
+
+ %% delete shadow old and new write - is the new value invisable
+ %% when deleted ?
+ ?match(ok, mnesia:delete(OidA)),
+
+ ?match([], mnesia:read({Tab, a})),
+ ?match([], mnesia:wread({Tab, a})),
+ ?match([], mnesia:match_object(PatA2)),
+ ?match([], mnesia:all_keys(Tab)),
+ ?match([], mnesia:index_match_object(PatA2, ValPos)),
+ ?match([], mnesia:index_read(Tab, 2, ValPos)),
+ ok
+
+ end,
+ ?match({atomic, ok}, mnesia:transaction(Fun2)),
+ ok.
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+write_delete_shadows_bag(doc) ->
+ ["Test the visibility of written and deleted objects in an bag type table"];
+write_delete_shadows_bag(suite) -> [];
+write_delete_shadows_bag(Config) when is_list(Config) ->
+ [Node1] = ?acquire_nodes(1, Config),
+ Tab = write_delete_shadows_bag,
+
+ ?match({atomic, ok}, mnesia:create_table([{name, Tab},
+ {ram_copies, [Node1]},
+ {type, bag}])),
+ ValPos = 3,
+ OidA = {Tab, a},
+
+ RecA1 = {Tab, a, 1},
+ PatA1 = {Tab, '$1', 1},
+
+ RecA2 = {Tab, a, 2},
+ PatA2 = {Tab, '$1', 2},
+
+ RecA3 = {Tab, a, 3},
+ PatA3 = {Tab, '$1', 3},
+
+ PatA = {Tab, a, '_'},
+
+
+ ?match({atomic, ok}, mnesia:add_table_index(Tab, ValPos)),
+
+ Fun1 = fun() ->
+ ?match(ok, mnesia:write(RecA1)),
+ ?match(ok, mnesia:write(RecA2)),
+ ok
+ end,
+
+ ?match({atomic, ok}, mnesia:transaction(Fun1)),
+
+ Fun2 = fun() ->
+ %% delete shadow old write - is the confirmed value invisible
+ %% when deleted in the transaction ?
+ ?match(ok, mnesia:delete_object(RecA1)),
+
+ ?match([RecA2], mnesia:read({Tab, a})),
+ ?match([RecA2], mnesia:wread({Tab, a})),
+ ?match([RecA2], mnesia:match_object(PatA2)),
+ ?match([a], mnesia:all_keys(Tab)),
+ ?match([RecA2], mnesia:index_match_object(PatA2, ValPos)),
+ ?match([RecA2], mnesia:index_read(Tab, 2, ValPos)),
+
+ ?match(ok, mnesia:delete(OidA)),
+
+ ?match([], mnesia:read({Tab, a})),
+ ?match([], mnesia:wread({Tab, a})),
+ ?match([], mnesia:match_object(PatA1)),
+ ?match([], mnesia:all_keys(Tab)),
+ ?match([], mnesia:index_match_object(PatA1, ValPos)),
+ ?match([], mnesia:index_read(Tab, 1, ValPos)),
+
+ %% delete shadow old but not new write - are both new value visable
+ %% when the old one was deleted ?
+ ?match(ok, mnesia:write(RecA2)),
+ ?match(ok, mnesia:write(RecA3)),
+
+
+ ?match([RecA2, RecA3], lists:sort(mnesia:read({Tab, a}))),
+ ?match([RecA2, RecA3], lists:sort(mnesia:wread({Tab, a}))),
+ ?match([RecA2], mnesia:match_object(PatA2)),
+ ?match([a], mnesia:all_keys(Tab)),
+ ?match([RecA2, RecA3], lists:sort(mnesia:match_object(PatA))),
+ ?match([RecA2], mnesia:index_match_object(PatA2, ValPos)),
+ ?match([RecA3], mnesia:index_match_object(PatA3, ValPos)),
+ ?match([RecA2], mnesia:index_read(Tab, 2, ValPos)),
+
+ %% delete shadow old and new write - is the new value invisable
+ %% when deleted ?
+ ?match(ok, mnesia:delete(OidA)),
+
+ ?match([], mnesia:read({Tab, a})),
+ ?match([], mnesia:wread({Tab, a})),
+ ?match([], mnesia:match_object(PatA2)),
+ ?match([], mnesia:all_keys(Tab)),
+ ?match([], mnesia:index_match_object(PatA2, ValPos)),
+ ?match([], mnesia:index_read(Tab, 2, ValPos)),
+ ok
+ end,
+ ?match({atomic, ok}, mnesia:transaction(Fun2)),
+ ok.
+
+write_delete_shadows_bag2(doc) ->
+ ["Test the visibility of written and deleted objects in an bag type table "
+ "and verifies the results"];
+write_delete_shadows_bag2(suite) -> [];
+write_delete_shadows_bag2(Config) when is_list(Config) ->
+
+ [Node1] = ?acquire_nodes(1, Config),
+ Tab = w_d_s_b,
+
+ ?match({atomic, ok}, mnesia:create_table([{name, Tab},
+ {ram_copies, [Node1]},
+ {type, bag}])),
+ Del = fun() ->
+ R1 = mnesia:read({Tab, 1}),
+ mnesia:delete({Tab, 1}),
+ R2 = mnesia:read({Tab, 1}),
+ mnesia:write({Tab, 1, 1}),
+ mnesia:write({Tab, 1, 2}),
+ R3 = mnesia:read({Tab, 1}),
+ {R1, R2, R3}
+ end,
+ DelObj = fun() ->
+ R1 = mnesia:read({Tab, 2}),
+ mnesia:delete_object({Tab, 2, 2}),
+ R2 = mnesia:read({Tab, 2}),
+ mnesia:write({Tab, 2, 1}),
+ mnesia:write({Tab, 2, 2}),
+ R3 = mnesia:read({Tab, 2}),
+ {R1, R2, R3}
+ end,
+ Both1 = [{Tab, 1, 1}, {Tab, 1, 2}],
+ Both2 = [{Tab, 2, 1}, {Tab, 2, 2}],
+ ?match({atomic, {[], [], Both1}}, mnesia:transaction(Del)),
+ ?match({atomic, {Both1, [], Both1}}, mnesia:transaction(Del)),
+ ?match({atomic, Both1}, mnesia:transaction(fun() -> mnesia:read({Tab, 1}) end)),
+ ?match({atomic, {[], [], Both2}}, mnesia:transaction(DelObj)),
+ ?match({atomic, {Both2, [{Tab, 2, 1}], Both2}}, mnesia:transaction(DelObj)),
+ ?match({atomic, Both2}, mnesia:transaction(fun() -> mnesia:read({Tab, 2}) end)),
+ ?verify_mnesia([Node1], []).
+
+shadow_search(doc) ->
+ ["Verifies that ordered_set tables are ordered, and the order is kept"
+ "even when table is shadowed by transaction updates"];
+shadow_search(suite) -> [];
+shadow_search(Config) when is_list(Config) ->
+ [Node1] = ?acquire_nodes(1, Config),
+ Tab1 = ss_oset,
+ Tab2 = ss_set,
+ Tab3 = ss_bag,
+ Tabs = [Tab1,Tab2,Tab3],
+ RecName = ss,
+ ?match({atomic, ok}, mnesia:create_table([{name, Tab1},
+ {ram_copies, [Node1]},
+ {record_name, RecName},
+ {type, ordered_set}])),
+ ?match({atomic, ok}, mnesia:create_table([{name, Tab2},
+ {record_name, RecName},
+ {ram_copies, [Node1]},
+ {type, set}])),
+ ?match({atomic, ok}, mnesia:create_table([{name, Tab3},
+ {record_name, RecName},
+ {ram_copies, [Node1]},
+ {type, bag}])),
+ Recs = [{RecName, K, K} || K <- [1,3,5]],
+ [mnesia:dirty_write(Tab1, R) || R <- Recs],
+ [mnesia:dirty_write(Tab2, R) || R <- Recs],
+ [mnesia:dirty_write(Tab3, R) || R <- Recs],
+
+ Match = fun(Tab) -> mnesia:match_object(Tab, {'_','_','_'}, write) end,
+ Select = fun(Tab) -> mnesia:select(Tab, [{'_', [], ['$_']}]) end,
+% Trans = fun(Fun,Args) -> mnesia:transaction(Fun,Args) end,
+ LoopHelp = fun('$end_of_table',_) -> [];
+ ({Res,Cont},Fun) ->
+ Sel = mnesia:select(Cont),
+ Res ++ Fun(Sel, Fun)
+ end,
+ SelLoop = fun(Table) ->
+ Sel = mnesia:select(Table, [{'_', [], ['$_']}], 1, read),
+ LoopHelp(Sel,LoopHelp)
+ end,
+
+ R1 = {RecName, 2, 2}, R2 = {RecName, 4, 4},
+ R3 = {RecName, 2, 3}, R4 = {RecName, 3, 1},
+ R5 = {RecName, 104, 104},
+ W1 = fun(Tab,Search) -> mnesia:write(Tab,R1,write),
+ mnesia:write(Tab,R2,write),
+ Search(Tab)
+ end,
+ S1 = lists:sort([R1,R2|Recs]),
+ ?match({atomic,S1}, mnesia:transaction(W1, [Tab1,Select])),
+ ?match({atomic,S1}, mnesia:transaction(W1, [Tab1,Match])),
+ ?match({atomic,S1}, mnesia:transaction(W1, [Tab1,SelLoop])),
+ ?match({atomic,S1}, sort_res(mnesia:transaction(W1, [Tab2,Select]))),
+ ?match({atomic,S1}, sort_res(mnesia:transaction(W1, [Tab2,SelLoop]))),
+ ?match({atomic,S1}, sort_res(mnesia:transaction(W1, [Tab2,Match]))),
+ ?match({atomic,S1}, sort_res(mnesia:transaction(W1, [Tab3,Select]))),
+ ?match({atomic,S1}, sort_res(mnesia:transaction(W1, [Tab3,SelLoop]))),
+ ?match({atomic,S1}, sort_res(mnesia:transaction(W1, [Tab3,Match]))),
+ [mnesia:dirty_delete_object(Tab,R) || R <- [R1,R2], Tab <- Tabs],
+
+ W2 = fun(Tab,Search) ->
+ mnesia:write(Tab,R3,write),
+ mnesia:write(Tab,R1,write),
+ Search(Tab)
+ end,
+ S2 = lists:sort([R1|Recs]),
+ S2Bag = lists:sort([R1,R3|Recs]),
+ ?match({atomic,S2}, mnesia:transaction(W2, [Tab1,Select])),
+ ?match({atomic,S2}, mnesia:transaction(W2, [Tab1,SelLoop])),
+ ?match({atomic,S2}, mnesia:transaction(W2, [Tab1,Match])),
+ ?match({atomic,S2}, sort_res(mnesia:transaction(W2, [Tab2,Select]))),
+ ?match({atomic,S2}, sort_res(mnesia:transaction(W2, [Tab2,SelLoop]))),
+ ?match({atomic,S2}, sort_res(mnesia:transaction(W2, [Tab2,Match]))),
+ ?match({atomic,S2Bag}, sort_res(mnesia:transaction(W2, [Tab3,Select]))),
+ ?match({atomic,S2Bag}, sort_res(mnesia:transaction(W2, [Tab3,SelLoop]))),
+ ?match({atomic,S2Bag}, sort_res(mnesia:transaction(W2, [Tab3,Match]))),
+%% [mnesia:dirty_delete_object(Tab,R) || R <- [R1,R3], Tab <- Tabs],
+
+ W3 = fun(Tab,Search) ->
+ mnesia:write(Tab,R4,write),
+ mnesia:delete(Tab,element(2,R1),write),
+ Search(Tab)
+ end,
+ S3Bag = lists:sort([R4|lists:delete(R1,Recs)]),
+ S3 = lists:delete({RecName,3,3},S3Bag),
+ ?match({atomic,S3}, mnesia:transaction(W3, [Tab1,Select])),
+ ?match({atomic,S3}, mnesia:transaction(W3, [Tab1,SelLoop])),
+ ?match({atomic,S3}, mnesia:transaction(W3, [Tab1,Match])),
+ ?match({atomic,S3}, sort_res(mnesia:transaction(W3, [Tab2,SelLoop]))),
+ ?match({atomic,S3}, sort_res(mnesia:transaction(W3, [Tab2,Select]))),
+ ?match({atomic,S3}, sort_res(mnesia:transaction(W3, [Tab2,Match]))),
+ ?match({atomic,S3Bag}, sort_res(mnesia:transaction(W3, [Tab3,Select]))),
+ ?match({atomic,S3Bag}, sort_res(mnesia:transaction(W3, [Tab3,SelLoop]))),
+ ?match({atomic,S3Bag}, sort_res(mnesia:transaction(W3, [Tab3,Match]))),
+
+ W4 = fun(Tab,Search) ->
+ mnesia:delete(Tab,-1,write),
+ mnesia:delete(Tab,4 ,write),
+ mnesia:delete(Tab,17,write),
+ mnesia:delete_object(Tab,{RecName, -1, x},write),
+ mnesia:delete_object(Tab,{RecName, 4, x},write),
+ mnesia:delete_object(Tab,{RecName, 42, x},write),
+ mnesia:delete_object(Tab,R2,write),
+ mnesia:write(Tab, R5, write),
+ Search(Tab)
+ end,
+ S4Bag = lists:sort([R5|S3Bag]),
+ S4 = lists:sort([R5|S3]),
+ ?match({atomic,S4}, mnesia:transaction(W4, [Tab1,Select])),
+ ?match({atomic,S4}, mnesia:transaction(W4, [Tab1,SelLoop])),
+ ?match({atomic,S4}, mnesia:transaction(W4, [Tab1,Match])),
+ ?match({atomic,S4}, sort_res(mnesia:transaction(W4, [Tab2,Select]))),
+ ?match({atomic,S4}, sort_res(mnesia:transaction(W4, [Tab2,SelLoop]))),
+ ?match({atomic,S4}, sort_res(mnesia:transaction(W4, [Tab2,Match]))),
+ ?match({atomic,S4Bag}, sort_res(mnesia:transaction(W4, [Tab3,Select]))),
+ ?match({atomic,S4Bag}, sort_res(mnesia:transaction(W4, [Tab3,SelLoop]))),
+ ?match({atomic,S4Bag}, sort_res(mnesia:transaction(W4, [Tab3,Match]))),
+ [mnesia:dirty_delete_object(Tab,R) || R <- [{RecName,3,3},R5], Tab <- Tabs],
+
+ %% hmmm anything more??
+
+ ?verify_mnesia([Node1], []).
+
+removed_resources(suite) ->
+ [rr_kill_copy];
+removed_resources(doc) ->
+ ["Verify that the locking behave when resources are removed"].
+
+rr_kill_copy(suite) -> [];
+rr_kill_copy(Config) when is_list(Config) ->
+ Ns = ?acquire_nodes(3,Config ++ [{tc_timeout, 60000}]),
+ DeleteMe = fun(_Tab,Where2read) ->
+ ?match([], mnesia_test_lib:kill_mnesia([Where2read]))
+ end,
+ Del = removed_resources(Ns, DeleteMe),
+ ?verify_mnesia(Ns -- [Del], []).
+
+removed_resources([_N1,N2,N3], DeleteRes) ->
+ Tab = del_res,
+ ?match({atomic, ok}, mnesia:create_table(Tab,[{ram_copies, [N2,N3]}])),
+
+ Init = fun() -> [mnesia:write({Tab,Key,Key}) || Key <- lists:seq(0,99)] end,
+ ?match([], [Bad || Bad <- mnesia:sync_dirty(Init), Bad /= ok]),
+
+ Where2Read = mnesia:table_info(Tab, where_to_read),
+ [Keep] = [N2,N3] -- [Where2Read],
+ Tester = self(),
+
+ Conflict = fun() ->
+ %% Read a value..
+ [{Tab,1,Val}] = mnesia:read({Tab,1}),
+ case get(restart) of
+ undefined ->
+ Tester ! {pid_1, self()},
+ %% Wait for sync, the read value have been
+ %% updated and this function should be restarted.
+ receive {Tester,sync} -> ok end,
+ put(restart, restarted);
+ restarted ->
+ ok
+ end,
+ mnesia:write({Tab,1,Val+10})
+ end,
+ Lucky = fun() ->
+ [{Tab,1,Val}] = mnesia:read({Tab,1}),
+ mnesia:write({Tab,1,Val+100})
+ end,
+
+ CPid = spawn_link(fun() -> Tester ! {self(), mnesia:transaction(Conflict)} end),
+
+ %% sync first transaction
+ receive {pid_1, CPid} -> synced end,
+
+ DeleteRes(Tab, Where2Read),
+
+ ?match(Keep, mnesia:table_info(Tab, where_to_read)),
+
+ %% Run the other/Lucky transaction, this should work since
+ %% it won't grab a lock on the conflicting transactions Where2Read node.
+
+ LPid = spawn_link(Keep, fun() -> Tester ! {self(),mnesia:transaction(Lucky)} end),
+ ?match_receive({LPid,{atomic,ok}}),
+
+ %% Continue Transaction no 1
+ CPid ! {self(), sync},
+
+ ?match(ok, receive {CPid,{atomic,ok}} -> ok after 2000 -> process_info(self()) end),
+
+ ?match({atomic,[{del_res,1,111}]}, mnesia:transaction(fun() -> mnesia:read({Tab,1}) end)),
+ Where2Read.
+
+nasty(suite) -> [];
+
+nasty(doc) ->
+ ["Tries to fullfill a rather nasty locking scenario, where we have had "
+ "bugs, the testcase tries a combination of locks in locker queue"];
+
+%% This testcase no longer works as it was intended to show errors when
+%% tablelocks was allowed to be placed in the queue though locks existed
+%% in the queue with less Tid's. This is no longer allowed and the testcase
+%% has been update.
+
+nasty(Config) ->
+ ?acquire_nodes(1, Config),
+ Tab = nasty,
+ ?match({atomic, ok}, mnesia:create_table(Tab, [])),
+ Coord = self(),
+ Write = fun(Key) ->
+ mnesia:write({Tab, Key, write}),
+ Coord ! {write, Key, self(), mnesia:get_activity_id()},
+ receive
+ continue ->
+ ok
+ end,
+ Coord ! {done, {write, Key}, self()}
+ end,
+
+ Update = fun(Key) ->
+ Coord ! {update, Key, self(), mnesia:get_activity_id()},
+ receive
+ continue ->
+ ok
+ end,
+ mnesia:read({Tab, Key}),
+ mnesia:write({Tab, Key, update}),
+ receive
+ continue ->
+ ok
+ end,
+
+ Coord ! {done, {update, Key}, self()}
+ end,
+
+ TabLock = fun() ->
+ Coord ! {tablock, Tab, self(), mnesia:get_activity_id()},
+ receive
+ continue ->
+ ok
+ end,
+ mnesia:lock({table, Tab}, write),
+ Coord ! {done, {tablock, Tab}, self()}
+ end,
+
+ Up = spawn_link(mnesia, transaction, [Update, [0]]),
+ ?match_receive({update, 0, Up, _Tid}),
+ TL = spawn_link(mnesia, transaction, [TabLock]),
+ ?match_receive({tablock, Tab, _Tl, _Tid}),
+ W0 = spawn_link(mnesia, transaction, [Write, [0]]),
+ ?match_receive({write, 0, W0, _Tid}),
+ W1 = spawn_link(mnesia, transaction, [Write, [1]]),
+ ?match_receive({write, 1, W1, _Tid}),
+
+ %% Nothing should be in msg queue!
+ ?match(timeout, receive A -> A after 1000 -> timeout end),
+ Up ! continue, %% Should be queued
+ ?match(timeout, receive A -> A after 1000 -> timeout end),
+ TL ! continue, %% Should be restarted
+% ?match({tablock, _, _, _}, receive A -> A after 1000 -> timeout end),
+ ?match(timeout, receive A -> A after 1000 -> timeout end),
+
+ LQ1 = mnesia_locker:get_lock_queue(),
+ ?match({2, _}, {length(LQ1), LQ1}),
+ W0 ! continue, % Up should be in queue
+ ?match_receive({done, {write, 0}, W0}),
+ ?match_receive({'EXIT', W0, normal}),
+
+ TL ! continue, % Should stay in queue W1
+ ?match(timeout, receive A -> A after 1000 -> timeout end),
+ Up ! continue, % Should stay in queue (TL got higher tid)
+ ?match(timeout, receive A -> A after 1000 -> timeout end),
+
+ LQ2 = mnesia_locker:get_lock_queue(),
+ ?match({2, _}, {length(LQ2), LQ2}),
+
+ W1 ! continue,
+ ?match_receive({done, {write, 1}, W1}),
+ get_exit(W1),
+ get_exit(TL),
+ ?match_receive({done, {tablock,Tab}, TL}),
+ get_exit(Up),
+ ?match_receive({done, {update, 0}, Up}),
+
+ ok.
+
+get_exit(Pid) ->
+ receive
+ {'EXIT', Pid, normal} ->
+ ok
+ after 10000 ->
+ ?error("Timeout EXIT ~p~n", [Pid])
+ end.
+
+iteration(doc) ->
+ ["Verify that the updates before/during iteration are visable "
+ "and that the order is preserved for ordered_set tables"];
+iteration(suite) ->
+ [foldl,first_next].
+
+foldl(doc) ->
+ [""];
+foldl(suite) ->
+ [];
+foldl(Config) when is_list(Config) ->
+ Nodes = [_,N2] = ?acquire_nodes(2, Config),
+ Tab1 = foldl_local,
+ Tab2 = foldl_remote,
+ Tab3 = foldl_ordered,
+ Tab11 = foldr_local,
+ Tab21 = foldr_remote,
+ Tab31 = foldr_ordered,
+ ?match({atomic, ok}, mnesia:create_table(Tab1, [{ram_copies, Nodes}])),
+ ?match({atomic, ok}, mnesia:create_table(Tab2, [{ram_copies, [N2]}, {type, bag}])),
+ ?match({atomic, ok}, mnesia:create_table(Tab3, [{ram_copies, Nodes},
+ {type, ordered_set}])),
+ ?match({atomic, ok}, mnesia:create_table(Tab11, [{ram_copies, Nodes}])),
+ ?match({atomic, ok}, mnesia:create_table(Tab21, [{ram_copies, [N2]}, {type, bag}])),
+ ?match({atomic, ok}, mnesia:create_table(Tab31, [{ram_copies, Nodes},
+ {type, ordered_set}])),
+
+
+ Tab1Els = [{Tab1, N, N} || N <- lists:seq(1, 10)],
+ Tab2Els = [{Tab2, 1, 2} | [{Tab2, N, N} || N <- lists:seq(1, 10)]],
+ Tab3Els = [{Tab3, N, N} || N <- lists:seq(1, 10)],
+ Tab11Els = [{Tab11, N, N} || N <- lists:seq(1, 10)],
+ Tab21Els = [{Tab21, 1, 2} | [{Tab21, N, N} || N <- lists:seq(1, 10)]],
+ Tab31Els = [{Tab31, N, N} || N <- lists:seq(1, 10)],
+
+ [mnesia:sync_dirty(fun() -> mnesia:write(E) end) || E <- Tab1Els],
+ [mnesia:sync_dirty(fun() -> mnesia:write(E) end) || E <- Tab2Els],
+ [mnesia:sync_dirty(fun() -> mnesia:write(E) end) || E <- Tab3Els],
+ [mnesia:sync_dirty(fun() -> mnesia:write(E) end) || E <- Tab11Els],
+ [mnesia:sync_dirty(fun() -> mnesia:write(E) end) || E <- Tab21Els],
+ [mnesia:sync_dirty(fun() -> mnesia:write(E) end) || E <- Tab31Els],
+
+ Get = fun(E, A) -> [E | A] end,
+
+ %% Before
+ AddB = fun(Tab, Func) ->
+ mnesia:write({Tab, 0, 0}),
+ mnesia:write({Tab, 1, 0}),
+ mnesia:write({Tab, 11, 0}),
+ mnesia:Func(Get, [], Tab)
+ end,
+ AddT1 = [{Tab1, 0, 0}, {Tab1, 1, 0}] ++ tl(Tab1Els) ++ [{Tab1, 11, 0}],
+ AddT2 = lists:sort([{Tab2, 0, 0}, {Tab2, 1, 0}] ++ Tab2Els ++ [{Tab2, 11, 0}]),
+ AddT3 = [{Tab3, 0, 0}, {Tab3, 1, 0}] ++ tl(Tab3Els) ++ [{Tab3, 11, 0}],
+ AddT11 = [{Tab11, 0, 0}, {Tab11, 1, 0}] ++ tl(Tab11Els) ++ [{Tab11, 11, 0}],
+ AddT21 = lists:sort([{Tab21, 0, 0}, {Tab21, 1, 0}] ++ Tab21Els ++ [{Tab21, 11, 0}]),
+ AddT31 = [{Tab31, 0, 0}, {Tab31, 1, 0}] ++ tl(Tab31Els) ++ [{Tab31, 11, 0}],
+
+ ?match({atomic, AddT1}, sort_res(mnesia:transaction(AddB, [Tab1, foldl]))),
+ ?match({atomic, AddT2}, sort_res(mnesia:transaction(AddB, [Tab2, foldl]))),
+ ?match({atomic, AddT3}, rev_res(mnesia:transaction(AddB, [Tab3, foldl]))),
+ ?match({atomic, AddT11}, sort_res(mnesia:transaction(AddB, [Tab11, foldr]))),
+ ?match({atomic, AddT21}, sort_res(mnesia:transaction(AddB, [Tab21, foldr]))),
+ ?match({atomic, AddT31}, mnesia:transaction(AddB, [Tab31, foldr])),
+
+ ?match({atomic, ok}, mnesia:create_table(copy, [{ram_copies, [N2]},
+ {record_name, Tab1}])),
+ CopyRec = fun(NewRec, Acc) ->
+ %% OTP-5495
+ W = fun() -> mnesia:write(copy, NewRec, write), [NewRec| Acc] end,
+ {atomic,Res} = sort_res(mnesia:transaction(W)),
+ Res
+ end,
+ Copy = fun() ->
+ AddT1 = mnesia:foldl(CopyRec, [], Tab1),
+ AddT1 = sort_res(mnesia:foldl(Get, [], copy))
+ end,
+ ?match({atomic, AddT1}, sort_res(mnesia:transaction(Copy))),
+
+ Del = fun(E, A) -> mnesia:delete_object(E), [E|A] end,
+ DelD = fun(Tab) ->
+ mnesia:write({Tab, 12, 12}),
+ mnesia:delete({Tab, 0}),
+ mnesia:foldr(Del, [], Tab),
+ mnesia:foldl(Get, [], Tab)
+ end,
+ ?match({atomic, []}, sort_res(mnesia:transaction(DelD, [Tab1]))),
+ ?match({atomic, []}, sort_res(mnesia:transaction(DelD, [Tab2]))),
+ ?match({atomic, []}, rev_res(mnesia:transaction(DelD, [Tab3]))),
+
+ ListWrite = fun(Tab) -> %% OTP-3893
+ mnesia:write({Tab, [12], 12}),
+ mnesia:foldr(Get, [], Tab)
+ end,
+ ?match({atomic, [{Tab1, [12], 12}]}, sort_res(mnesia:transaction(ListWrite, [Tab1]))),
+ ?match({atomic, [{Tab2, [12], 12}]}, sort_res(mnesia:transaction(ListWrite, [Tab2]))),
+ ?match({atomic, [{Tab3, [12], 12}]}, rev_res(mnesia:transaction(ListWrite, [Tab3]))),
+
+ ?verify_mnesia(Nodes, []).
+
+sort_res({atomic, List}) when is_list(List) ->
+ {atomic, lists:sort(List)};
+sort_res(Else) when is_list(Else) ->
+ lists:sort(Else);
+sort_res(Else) ->
+ Else.
+
+rev_res({atomic, List}) ->
+ {atomic, lists:reverse(List)};
+rev_res(Else) ->
+ Else.
+
+
+first_next(doc) -> [""];
+first_next(suite) -> [];
+first_next(Config) when is_list(Config) ->
+ Nodes = [_,N2] = ?acquire_nodes(2, Config),
+ Tab1 = local,
+ Tab2 = remote,
+ Tab3 = ordered,
+ Tab4 = bag,
+ Tabs = [Tab1,Tab2,Tab3,Tab4],
+
+ ?match({atomic, ok}, mnesia:create_table(Tab1, [{ram_copies, Nodes}])),
+ ?match({atomic, ok}, mnesia:create_table(Tab2, [{ram_copies, [N2]}])),
+ ?match({atomic, ok}, mnesia:create_table(Tab3, [{ram_copies, Nodes},
+ {type, ordered_set}])),
+ ?match({atomic, ok}, mnesia:create_table(Tab4, [{ram_copies, Nodes},
+ {type, bag}])),
+
+ %% Some Helpers
+ Trans = fun(Fun) -> mnesia:transaction(Fun) end,
+ Continue = fun(first) -> next;
+ (last) -> prev
+ end,
+ LoopHelp = fun('$end_of_table',_,_,_Fun) -> [];
+ (Key,Tab,Op,Fun) ->
+ Next = mnesia:Op(Tab,Key),
+ [Next |Fun(Next,Tab,Op,Fun)]
+ end,
+ Loop = fun(Tab,Start) ->
+ First = mnesia:Start(Tab),
+ Res = [First|LoopHelp(First,Tab,Continue(Start),LoopHelp)],
+ case mnesia:table_info(Tab, type) of
+ ordered_set when Start == first -> Res;
+ ordered_set ->
+ {L1,L2} = lists:split(length(Res)-1,Res),
+ lists:reverse(L1) ++ L2;
+ _ -> lists:sort(Res)
+ end
+ end,
+
+ %% Verify empty tables
+ [?match({atomic, ['$end_of_table']},
+ Trans(fun() -> Loop(Tab,first) end))
+ || Tab <- Tabs],
+ [?match({atomic, ['$end_of_table']},
+ Trans(fun() -> Loop(Tab,last) end))
+ || Tab <- Tabs],
+ %% Verify that trans write is visible inside trans
+ [?match({atomic, [0,10,'$end_of_table']},
+ Trans(fun() ->
+ mnesia:write({Tab,0,0}),
+ mnesia:write({Tab,10,10}),
+ Loop(Tab,first) end))
+ || Tab <- Tabs],
+ [?match({atomic, ['$end_of_table']},
+ Trans(fun() ->
+ mnesia:delete({Tab,0}),
+ mnesia:delete({Tab,10}),
+ Loop(Tab,first) end))
+ || Tab <- Tabs],
+
+ [?match({atomic, [0,10,'$end_of_table']},
+ Trans(fun() ->
+ mnesia:write({Tab,0,0}),
+ mnesia:write({Tab,10,10}),
+ Loop(Tab,last) end))
+ || Tab <- Tabs],
+ [?match({atomic, ['$end_of_table']},
+ Trans(fun() ->
+ mnesia:delete({Tab,0}),
+ mnesia:delete({Tab,10}),
+ Loop(Tab,last) end))
+ || Tab <- Tabs],
+
+ Tab1Els = [{Tab1, N, N} || N <- lists:seq(1, 5)],
+ Tab2Els = [{Tab2, N, N} || N <- lists:seq(1, 5)],
+ Tab3Els = [{Tab3, N, N} || N <- lists:seq(1, 5)],
+ Tab4Els = [{Tab4, 1, 2} | [{Tab4, N, N} || N <- lists:seq(1, 5)]],
+
+ [mnesia:sync_dirty(fun() -> mnesia:write(E) end) || E <- Tab1Els],
+ [mnesia:sync_dirty(fun() -> mnesia:write(E) end) || E <- Tab2Els],
+ [mnesia:sync_dirty(fun() -> mnesia:write(E) end) || E <- Tab3Els],
+ [mnesia:sync_dirty(fun() -> mnesia:write(E) end) || E <- Tab4Els],
+ Keys = lists:sort(mnesia:dirty_all_keys(Tab1)),
+ R1 = Keys++ ['$end_of_table'],
+ [?match({atomic, R1}, Trans(fun() -> Loop(Tab,first) end))
+ || Tab <- Tabs],
+
+ [?match({atomic, R1}, Trans(fun() -> Loop(Tab,last) end))
+ || Tab <- Tabs],
+ R2 = R1 -- [3],
+
+ [?match({atomic, R2}, Trans(fun() -> mnesia:delete({Tab,3}),Loop(Tab,first) end))
+ || Tab <- Tabs],
+ [?match({atomic, R1}, Trans(fun() -> mnesia:write({Tab,3,3}),Loop(Tab,first) end))
+ || Tab <- Tabs],
+ [?match({atomic, R2}, Trans(fun() -> mnesia:delete({Tab,3}),Loop(Tab,last) end))
+ || Tab <- Tabs],
+ [?match({atomic, R1}, Trans(fun() -> mnesia:write({Tab,3,3}),Loop(Tab,last) end))
+ || Tab <- Tabs],
+ [?match({atomic, R1}, Trans(fun() -> mnesia:write({Tab,4,19}),Loop(Tab,first) end))
+ || Tab <- Tabs],
+ [?match({atomic, R1}, Trans(fun() -> mnesia:write({Tab,4,4}),Loop(Tab,last) end))
+ || Tab <- Tabs],
+
+ ?verify_mnesia(Nodes, []).
+
+
+snmp_shadows(doc) -> [""];
+snmp_shadows(suite) -> [];
+snmp_shadows(Config) when is_list(Config) ->
+ Nodes = ?acquire_nodes(1, Config),
+ Tab = snmp_shadows,
+ io:format("With fixstring~n", []),
+ ?match({atomic, ok}, mnesia:create_table(Tab,[{snmp,[{key,{fix_string,integer}}]}])),
+ snmp_shadows_test(Tab),
+ ?match({atomic, ok}, mnesia:delete_table(Tab)),
+ io:format("Without fixstring~n", []),
+ ?match({atomic, ok}, mnesia:create_table(Tab,[{snmp,[{key,{string,integer}}]}])),
+ snmp_shadows_test(Tab),
+ ?verify_mnesia(Nodes, []).
+
+snmp_shadows_test(Tab) ->
+ [mnesia:dirty_write({Tab, {"string", N}, {N, init}}) || N <- lists:seq(2,8,2)],
+
+ CheckOrder = fun(A={_,_,{_,_,State}}, Prev) ->
+ ?match({true, A, Prev}, {Prev < A, A, Prev}),
+ {State,A}
+ end,
+ R1 = mnesia:sync_dirty(fun() -> loop_snmp(Tab, []) end),
+ lists:mapfoldl(CheckOrder, {[],foo,foo}, R1),
+ R2 = mnesia:transaction(fun() -> loop_snmp(Tab, []) end),
+ ?match({atomic, R1}, R2),
+
+ Shadow = fun() ->
+ ok = mnesia:write({Tab, {"string",1}, {1,update}}),
+ ok = mnesia:write({Tab, {"string",4}, {4,update}}),
+ ok = mnesia:write({Tab, {"string",6}, {6,update}}),
+ ok = mnesia:delete({Tab, {"string",6}}),
+ ok = mnesia:write({Tab, {"string",9}, {9,update}}),
+ ok = mnesia:write({Tab, {"string",3}, {3,update}}),
+ ok = mnesia:write({Tab, {"string",5}, {5,update}}),
+ [Row5] = mnesia:read({Tab, {"string",5}}),
+ ok = mnesia:delete_object(Row5),
+ loop_snmp(Tab, [])
+ end,
+ R3 = mnesia:sync_dirty(Shadow),
+ {L3,_} = lists:mapfoldl(CheckOrder, {[],foo,foo}, R3),
+ ?match([{1,update},{2,init},{3,update},{4,update},{8,init},{9,update}], L3),
+ ?match({atomic, ok}, mnesia:clear_table(Tab)),
+
+ [mnesia:dirty_write({Tab, {"string", N}, {N, init}}) || N <- lists:seq(2,8,2)],
+ {atomic, R3} = mnesia:transaction(Shadow),
+ {L4,_} = lists:mapfoldl(CheckOrder, {[],foo,foo}, R3),
+ ?match([{1,update},{2,init},{3,update},{4,update},{8,init},{9,update}], L4),
+ ok.
+
+loop_snmp(Tab,Prev) ->
+ case mnesia:snmp_get_next_index(Tab,Prev) of
+ {ok, SKey} ->
+ {{ok,Row},_} = {mnesia:snmp_get_row(Tab, SKey),{?LINE,Prev,SKey}},
+ {{ok,MKey},_} = {mnesia:snmp_get_mnesia_key(Tab,SKey),{?LINE,Prev,SKey}},
+ ?match({[Row],Row,SKey,MKey}, {mnesia:read({Tab,MKey}),Row,SKey,MKey}),
+ [{SKey, MKey, Row} | loop_snmp(Tab, SKey)];
+ endOfTable ->
+ []
+ end.
diff --git a/lib/mnesia/test/mnesia_measure_test.erl b/lib/mnesia/test/mnesia_measure_test.erl
new file mode 100644
index 0000000000..fbf804dbec
--- /dev/null
+++ b/lib/mnesia/test/mnesia_measure_test.erl
@@ -0,0 +1,203 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 1996-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(mnesia_measure_test).
+-author('[email protected]').
+-compile([export_all]).
+
+-include("mnesia_test_lib.hrl").
+
+init_per_testcase(Func, Conf) ->
+ mnesia_test_lib:init_per_testcase(Func, Conf).
+
+fin_per_testcase(Func, Conf) ->
+ mnesia_test_lib:fin_per_testcase(Func, Conf).
+
+-define(init(N, Config),
+ mnesia_test_lib:prepare_test_case([{init_test_case, [mnesia]},
+ delete_schema],
+ N, Config, ?FILE, ?LINE)).
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+all(doc) ->
+ ["Measure various aspects of Mnesia",
+ "Verify that Mnesia has predictable response times,",
+ "that the transaction system has fair algoritms,",
+ "resource consumption, scalabilitym system limits etc.",
+ "Perform some benchmarks."];
+all(suite) ->
+ [
+ prediction,
+ consumption,
+ scalability,
+ benchmarks
+ ].
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+prediction(doc) ->
+ ["The system must have predictable response times.",
+ "The maintenance of the system should not impact on the",
+ "availability. Make sure that the response times does not vary too",
+ "much from the undisturbed normal usage.",
+ "Verify that deadlocks never occurs."];
+prediction(suite) ->
+ [
+ reader_disturbed_by_node_down,
+ writer_disturbed_by_node_down,
+ reader_disturbed_by_node_up,
+ writer_disturbed_by_node_up,
+ reader_disturbed_by_schema_ops,
+ writer_disturbed_by_schema_ops,
+ reader_disturbed_by_checkpoint,
+ writer_disturbed_by_checkpoint,
+ reader_disturbed_by_dump_log,
+ writer_disturbed_by_dump_log,
+ reader_disturbed_by_backup,
+ writer_disturbed_by_backup,
+ reader_disturbed_by_restore,
+ writer_disturbed_by_restore,
+ fairness
+ ].
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+fairness(doc) ->
+ ["Verify that the transaction system behaves fair, even under intense",
+ "stress. Combine different access patterns (transaction profiles)",
+ "in order to verify that concurrent applications gets a fair share",
+ "of the database resource. Verify that starvation never may occur."];
+fairness(suite) ->
+ [
+ reader_competing_with_reader,
+ reader_competing_with_writer,
+ writer_competing_with_reader,
+ writer_competing_with_writer
+ ].
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+consumption(doc) ->
+ ["Measure the resource consumption and publish the outcome. Make",
+ "sure that resources are released after failures."];
+consumption(suite) ->
+ [
+ measure_resource_consumption,
+ determine_resource_leakage
+ ].
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+scalability(doc) ->
+ ["Try out where the system limits are. We must at least meet the",
+ "documented system limits.",
+ "Redo the performance meters for various configurations and load,",
+ "especially near system limits."];
+scalability(suite) ->
+ [
+ determine_system_limits,
+ performance_at_min_config,
+ performance_at_max_config,
+ performance_at_full_load,
+ resource_consumption_at_min_config,
+ resource_consumption_at_max_config,
+ resource_consumption_at_full_load
+ ].
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+benchmarks(doc) ->
+ ["Measure typical database operations and publish them. Try to",
+ "verify that new releases of Mnesia always outperforms old",
+ "releases, or at least that the meters does not get worse."];
+benchmarks(suite) ->
+ [
+ meter,
+ cost,
+ dbn_meters,
+ measure_all_api_functions,
+ tpcb,
+ mnemosyne_vs_mnesia_kernel
+ ].
+
+dbn_meters(suite) -> [];
+dbn_meters(Config) when is_list(Config) ->
+ _Nodes = ?init(3, Config),
+ ?match(ok, mnesia_dbn_meters:start()),
+ ok.
+
+tpcb(suite) ->
+ [
+ ram_tpcb,
+ disc_tpcb,
+ disc_only_tpcb
+ ].
+
+tpcb(ReplicaType, Config) ->
+ HarakiriDelay = {tc_timeout, timer:minutes(20)},
+ Nodes = ?acquire_nodes(2, Config ++ [HarakiriDelay]),
+ Args = [{n_branches, 2},
+ {n_drivers_per_node, 1},
+ {replica_nodes, Nodes},
+ {driver_nodes, [hd(Nodes)]},
+ {use_running_mnesia, true},
+ {use_sticky_locks, true},
+ {replica_type, ReplicaType}],
+ ?match({ok, _}, mnesia_tpcb:start(Args)),
+ ?verify_mnesia(Nodes, []).
+
+ram_tpcb(suite) -> [];
+ram_tpcb(Config) when is_list(Config) ->
+ tpcb(ram_copies, Config).
+
+disc_tpcb(suite) -> [];
+disc_tpcb(Config) when is_list(Config) ->
+ tpcb(disc_copies, Config).
+
+disc_only_tpcb(suite) -> [];
+disc_only_tpcb(Config) when is_list(Config) ->
+ tpcb(disc_only_copies, Config).
+
+meter(suite) ->
+ [
+ ram_meter,
+ disc_meter,
+ disc_only_meter
+ ].
+
+ram_meter(suite) -> [];
+ram_meter(Config) when is_list(Config) ->
+ HarakiriDelay = [{tc_timeout, timer:minutes(20)}],
+ Nodes = ?init(3, Config ++ HarakiriDelay),
+ ?match(ok, mnesia_meter:go(ram_copies, Nodes)).
+
+disc_meter(suite) -> [];
+disc_meter(Config) when is_list(Config) ->
+ HarakiriDelay = [{tc_timeout, timer:minutes(20)}],
+ Nodes = ?init(3, Config ++ HarakiriDelay),
+ ?match(ok, mnesia_meter:go(disc_copies, Nodes)).
+
+disc_only_meter(suite) -> [];
+disc_only_meter(Config) when is_list(Config) ->
+ HarakiriDelay = [{tc_timeout, timer:minutes(20)}],
+ Nodes = ?init(3, Config ++ HarakiriDelay),
+ ?match(ok, mnesia_meter:go(disc_only_copies, Nodes)).
+
+cost(suite) -> [];
+cost(Config) when is_list(Config) ->
+ Nodes = ?init(3, Config),
+ ?match(ok, mnesia_cost:go(Nodes)),
+ file:delete("MNESIA_COST").
diff --git a/lib/mnesia/test/mnesia_meter.erl b/lib/mnesia/test/mnesia_meter.erl
new file mode 100644
index 0000000000..68094c4431
--- /dev/null
+++ b/lib/mnesia/test/mnesia_meter.erl
@@ -0,0 +1,465 @@
+%%
+%% %CopyrightBegin%
+%%
+%% 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%
+%%
+
+%%
+%% Getting started:
+%%
+%% 1 Start one or more distributed Erlang nodes
+%% 2a Connect the nodes, e.g. with net_adm:ping/1
+%% 3a Run mnesia_meter:go()
+%% 3b Run mnesia_meter:go(ReplicaType)
+%% 3c Run mnesia_meter:go(ReplicaType, Nodes)
+
+-module(mnesia_meter).
+-author('[email protected]').
+-export([
+ go/0,
+ go/1,
+ go/2,
+ repeat_meter/2
+ ]).
+
+-record(person, {name, %% atomic, unique key
+ data, %% compound structure
+ married_to, %% name of partner or undefined
+ children}). %% list of children
+
+-record(meter, {desc, init, meter, micros}).
+
+-record(result, {desc, list}).
+
+-define(TIMES, 1000).
+
+go() ->
+ go(ram_copies).
+
+go(ReplicaType) ->
+ go(ReplicaType, [node() | nodes()]).
+
+go(ReplicaType, Nodes) ->
+ {ok, FunOverhead} = tc(fun(_) -> {atomic, ok} end, ?TIMES),
+ Size = size(term_to_binary(#person{})),
+ io:format("A fun apply costs ~p micro seconds. Record size is ~p bytes.~n",
+ [FunOverhead, Size]),
+ Res = go(ReplicaType, Nodes, [], FunOverhead, []),
+ NewRes = rearrange(Res, []),
+ DescHeader = lists:flatten(io_lib:format("~w on ~w", [ReplicaType, Nodes])),
+ ItemHeader = lists:seq(1, length(Nodes)),
+ Header = #result{desc = DescHeader, list = ItemHeader},
+ SepList = ['--------' || _ <- Nodes],
+ Separator = #result{desc = "", list = SepList},
+ display([Separator, Header, Separator | NewRes] ++ [Separator]).
+
+go(_ReplicaType, [], _Config, _FunOverhead, Acc) ->
+ Acc;
+go(ReplicaType, [H | T], OldNodes, FunOverhead, Acc) ->
+ Nodes = [H | OldNodes],
+ Config = [{ReplicaType, Nodes}],
+ Res = run(Nodes, Config, FunOverhead),
+ go(ReplicaType, T, Nodes, FunOverhead, [{ReplicaType, Nodes, Res} | Acc]).
+
+rearrange([{_ReplicaType, _Nodes, Meters} | Tail], Acc) ->
+ Acc2 = [add_meter(M, Acc) || M <- Meters],
+ rearrange(Tail, Acc2);
+rearrange([], Acc) ->
+ Acc.
+
+add_meter(M, Acc) ->
+ case lists:keysearch(M#meter.desc, #result.desc, Acc) of
+ {value, R} ->
+ R#result{list = [M#meter.micros | R#result.list]};
+ false ->
+ #result{desc = M#meter.desc, list = [M#meter.micros]}
+ end.
+
+display(Res) ->
+ MaxDesc = lists:max([length(R#result.desc) || R <- Res]),
+ Format = lists:concat(["! ~-", MaxDesc, "s"]),
+ display(Res, Format, MaxDesc).
+
+display([R | Res], Format, MaxDesc) ->
+ case R#result.desc of
+ "" ->
+ io:format(Format, [lists:duplicate(MaxDesc, "-")]);
+ Desc ->
+ io:format(Format, [Desc])
+ end,
+ display_items(R#result.list, R#result.desc),
+ io:format(" !~n", []),
+ display(Res, Format, MaxDesc);
+display([], _Format, _MaxDesc) ->
+ ok.
+
+display_items([_Item | Items], "") ->
+ io:format(" ! ~s", [lists:duplicate(10, $-)]),
+ display_items(Items, "");
+display_items([Micros | Items], Desc) ->
+ io:format(" ! ~10w", [Micros]),
+ display_items(Items, Desc);
+display_items([], _Desc) ->
+ ok.
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+meters() ->
+ [#meter{desc = "transaction update two records with read and write",
+ init = fun write_records/2,
+ meter = fun update_records/1},
+ #meter{desc = "transaction update two records with wread and write",
+ init = fun write_records/2,
+ meter = fun w_update_records/1},
+ #meter{desc = "transaction update two records with read and s_write",
+ init = fun s_write_records/2,
+ meter = fun s_update_records/1},
+ #meter{desc = "sync_dirty update two records with read and write",
+ init = fun sync_dirty_write_records/2,
+ meter = fun sync_dirty_update_records/1},
+ #meter{desc = "async_dirty update two records with read and write",
+ init = fun async_dirty_write_records/2,
+ meter = fun async_dirty_update_records/1},
+ #meter{desc = "plain fun update two records with dirty_read and dirty_write",
+ init = fun dirty_write_records/2,
+ meter = fun dirty_update_records/1},
+ #meter{desc = "ets update two records with read and write (local only)",
+ init = fun ets_opt_write_records/2,
+ meter = fun ets_update_records/1},
+ #meter{desc = "plain fun update two records with ets:lookup and ets:insert (local only)",
+ init = fun bif_opt_write_records/2,
+ meter = fun bif_update_records/1},
+ #meter{desc = "plain fun update two records with dets:lookup and dets:insert (local only)",
+ init = fun dets_opt_write_records/2,
+ meter = fun dets_update_records/1},
+
+ #meter{desc = "transaction write two records with write",
+ init = fun write_records/2,
+ meter = fun(X) -> write_records(X, 0-X) end},
+ #meter{desc = "transaction write two records with s_write",
+ init = fun s_write_records/2,
+ meter = fun(X) -> s_write_records(X, 0-X) end},
+ #meter{desc = "sync_dirty write two records with write",
+ init = fun sync_dirty_write_records/2,
+ meter = fun(X) -> sync_dirty_write_records(X, 0-X) end},
+ #meter{desc = "async_dirty write two records with write",
+ init = fun async_dirty_write_records/2,
+ meter = fun(X) -> async_dirty_write_records(X, 0-X) end},
+ #meter{desc = "plain fun write two records with dirty_write",
+ init = fun dirty_write_records/2,
+ meter = fun(X) -> dirty_write_records(X, 0-X) end},
+ #meter{desc = "ets write two records with write (local only)",
+ init = fun ets_opt_write_records/2,
+ meter = fun(X) -> ets_write_records(X, 0-X) end},
+ #meter{desc = "plain fun write two records with ets:insert (local only)",
+ init = fun bif_opt_write_records/2,
+ meter = fun(X) -> bif_write_records(X, 0-X) end},
+ #meter{desc = "plain fun write two records with dets:insert (local only)",
+ init = fun dets_opt_write_records/2,
+ meter = fun(X) -> dets_write_records(X, 0-X) end},
+
+ #meter{desc = "transaction read two records with read",
+ init = fun write_records/2,
+ meter = fun(X) -> read_records(X, 0-X) end},
+ #meter{desc = "sync_dirty read two records with read",
+ init = fun sync_dirty_write_records/2,
+ meter = fun(X) -> sync_dirty_read_records(X, 0-X) end},
+ #meter{desc = "async_dirty read two records with read",
+ init = fun async_dirty_write_records/2,
+ meter = fun(X) -> async_dirty_read_records(X, 0-X) end},
+ #meter{desc = "plain fun read two records with dirty_read",
+ init = fun dirty_write_records/2,
+ meter = fun(X) -> dirty_read_records(X, 0-X) end},
+ #meter{desc = "ets read two records with read",
+ init = fun ets_opt_write_records/2,
+ meter = fun(X) -> ets_read_records(X, 0-X) end},
+ #meter{desc = "plain fun read two records with ets:lookup",
+ init = fun bif_opt_write_records/2,
+ meter = fun(X) -> bif_read_records(X, 0-X) end},
+ #meter{desc = "plain fun read two records with dets:lookup",
+ init = fun dets_opt_write_records/2,
+ meter = fun(X) -> dets_read_records(X, 0-X) end}
+ ].
+
+update_fun(Name) ->
+ fun() ->
+ case mnesia:read({person, Name}) of
+ [] ->
+ mnesia:abort(no_such_person);
+ [Pers] ->
+ [Partner] = mnesia:read({person, Pers#person.married_to}),
+ mnesia:write(Pers#person{married_to = undefined}),
+ mnesia:write(Partner#person{married_to = undefined})
+ end
+ end.
+
+update_records(Name) ->
+ mnesia:transaction(update_fun(Name)).
+
+sync_dirty_update_records(Name) ->
+ {atomic, mnesia:sync_dirty(update_fun(Name))}.
+
+async_dirty_update_records(Name) ->
+ {atomic, mnesia:async_dirty(update_fun(Name))}.
+
+ets_update_records(Name) ->
+ {atomic, mnesia:ets(update_fun(Name))}.
+
+w_update_records(Name) ->
+ F = fun() ->
+ case mnesia:wread({person, Name}) of
+ [] ->
+ mnesia:abort(no_such_person);
+ [Pers] ->
+ [Partner] = mnesia:wread({person, Pers#person.married_to}),
+ mnesia:write(Pers#person{married_to = undefined}),
+ mnesia:write(Partner#person{married_to = undefined})
+ end
+ end,
+ mnesia:transaction(F).
+
+s_update_records(Name) ->
+ F = fun() ->
+ case mnesia:read({person, Name}) of
+ [] ->
+ mnesia:abort(no_such_person);
+ [Pers] ->
+ [Partner] = mnesia:read({person, Pers#person.married_to}),
+ mnesia:s_write(Pers#person{married_to = undefined}),
+ mnesia:s_write(Partner#person{married_to = undefined})
+ end
+ end,
+ mnesia:transaction(F).
+
+dirty_update_records(Name) ->
+ case mnesia:dirty_read({person, Name}) of
+ [] ->
+ mnesia:abort(no_such_person);
+ [Pers] ->
+ [Partner] = mnesia:dirty_read({person, Pers#person.married_to}),
+ mnesia:dirty_write(Pers#person{married_to = undefined}),
+ mnesia:dirty_write(Partner#person{married_to = undefined})
+ end,
+ {atomic, ok}.
+
+bif_update_records(Name) ->
+ case ets:lookup(person, Name) of
+ [] ->
+ mnesia:abort(no_such_person);
+ [Pers] ->
+ [Partner] = ets:lookup(person, Pers#person.married_to),
+ ets:insert(person, Pers#person{married_to = undefined}),
+ ets:insert(person, Partner#person{married_to = undefined})
+ end,
+ {atomic, ok}.
+
+dets_update_records(Name) ->
+ case dets:lookup(person, Name) of
+ [] ->
+ mnesia:abort(no_such_person);
+ [Pers] ->
+ [Partner] = dets:lookup(person, Pers#person.married_to),
+ dets:insert(person, Pers#person{married_to = undefined}),
+ dets:insert(person, Partner#person{married_to = undefined})
+ end,
+ {atomic, ok}.
+
+write_records_fun(Pers, Partner) ->
+ fun() ->
+ P = #person{children = [ulla, bella]},
+ mnesia:write(P#person{name = Pers, married_to = Partner}),
+ mnesia:write(P#person{name = Partner, married_to = Pers})
+ end.
+
+write_records(Pers, Partner) ->
+ mnesia:transaction(write_records_fun(Pers, Partner)).
+
+sync_dirty_write_records(Pers, Partner) ->
+ {atomic, mnesia:sync_dirty(write_records_fun(Pers, Partner))}.
+
+async_dirty_write_records(Pers, Partner) ->
+ {atomic, mnesia:async_dirty(write_records_fun(Pers, Partner))}.
+
+ets_write_records(Pers, Partner) ->
+ {atomic, mnesia:ets(write_records_fun(Pers, Partner))}.
+
+s_write_records(Pers, Partner) ->
+ F = fun() ->
+ P = #person{children = [ulla, bella]},
+ mnesia:s_write(P#person{name = Pers, married_to = Partner}),
+ mnesia:s_write(P#person{name = Partner, married_to = Pers})
+ end,
+ mnesia:transaction(F).
+
+dirty_write_records(Pers, Partner) ->
+ P = #person{children = [ulla, bella]},
+ mnesia:dirty_write(P#person{name = Pers, married_to = Partner}),
+ mnesia:dirty_write(P#person{name = Partner, married_to = Pers}),
+ {atomic, ok}.
+
+ets_opt_write_records(Pers, Partner) ->
+ case mnesia:table_info(person, where_to_commit) of
+ [{N, ram_copies}] when N == node() ->
+ ets_write_records(Pers, Partner);
+ _ ->
+ throw(skipped)
+ end.
+
+bif_opt_write_records(Pers, Partner) ->
+ case mnesia:table_info(person, where_to_commit) of
+ [{N, ram_copies}] when N == node() ->
+ bif_write_records(Pers, Partner);
+ _ ->
+ throw(skipped)
+ end.
+
+bif_write_records(Pers, Partner) ->
+ P = #person{children = [ulla, bella]},
+ ets:insert(person, P#person{name = Pers, married_to = Partner}),
+ ets:insert(person, P#person{name = Partner, married_to = Pers}),
+ {atomic, ok}.
+
+dets_opt_write_records(Pers, Partner) ->
+ case mnesia:table_info(person, where_to_commit) of
+ [{N, disc_only_copies}] when N == node() ->
+ dets_write_records(Pers, Partner);
+ _ ->
+ throw(skipped)
+ end.
+
+dets_write_records(Pers, Partner) ->
+ P = #person{children = [ulla, bella]},
+ dets:insert(person, P#person{name = Pers, married_to = Partner}),
+ dets:insert(person, P#person{name = Partner, married_to = Pers}),
+ {atomic, ok}.
+
+read_records_fun(Pers, Partner) ->
+ fun() ->
+ case {mnesia:read({person, Pers}),
+ mnesia:read({person, Partner})} of
+ {[_], [_]} ->
+ ok;
+ _ ->
+ mnesia:abort(no_such_person)
+ end
+ end.
+
+read_records(Pers, Partner) ->
+ mnesia:transaction(read_records_fun(Pers, Partner)).
+
+sync_dirty_read_records(Pers, Partner) ->
+ {atomic, mnesia:sync_dirty(read_records_fun(Pers, Partner))}.
+
+async_dirty_read_records(Pers, Partner) ->
+ {atomic, mnesia:async_dirty(read_records_fun(Pers, Partner))}.
+
+ets_read_records(Pers, Partner) ->
+ {atomic, mnesia:ets(read_records_fun(Pers, Partner))}.
+
+dirty_read_records(Pers, Partner) ->
+ case {mnesia:dirty_read({person, Pers}),
+ mnesia:dirty_read({person, Partner})} of
+ {[_], [_]} ->
+ {atomic, ok};
+ _ ->
+ mnesia:abort(no_such_person)
+ end.
+
+bif_read_records(Pers, Partner) ->
+ case {ets:lookup(person, Pers),
+ ets:lookup(person, Partner)} of
+ {[_], [_]} ->
+ {atomic, ok};
+ _ ->
+ mnesia:abort(no_such_person)
+ end.
+
+dets_read_records(Pers, Partner) ->
+ case {dets:lookup(person, Pers),
+ dets:lookup(person, Partner)} of
+ {[_], [_]} ->
+ {atomic, ok};
+ _ ->
+ mnesia:abort(no_such_person)
+ end.
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+run(Nodes, Config, FunOverhead) ->
+ Meters = meters(),
+ io:format("Run ~w meters with table config: ~w~n", [length(Meters), Config]),
+ rpc:multicall(Nodes, mnesia, lkill, []),
+ start(Nodes, Config),
+ Res = [run_meter(Data, Nodes, FunOverhead) || Data <- Meters],
+ stop(Nodes),
+ Res.
+
+run_meter(M, Nodes, FunOverhead) when is_record(M, meter) ->
+ io:format(".", []),
+ case catch init_records(M#meter.init, ?TIMES) of
+ {atomic, ok} ->
+ rpc:multicall(Nodes, mnesia, dump_log, []),
+ case tc(M#meter.meter, ?TIMES) of
+ {ok, Micros} ->
+ M#meter{micros = lists:max([0, Micros - FunOverhead])};
+ {error, Reason} ->
+ M#meter{micros = Reason}
+ end;
+ Res ->
+ M#meter{micros = Res}
+ end.
+
+start(Nodes, Config) ->
+ mnesia:delete_schema(Nodes),
+ ok = mnesia:create_schema(Nodes),
+ Args = [[{dump_log_write_threshold, ?TIMES div 2},
+ {dump_log_time_threshold, timer:hours(10)}]],
+ lists:foreach(fun(Node) -> rpc:call(Node, mnesia, start, Args) end, Nodes),
+ Attrs = record_info(fields, person),
+ TabDef = [{attributes, Attrs} | Config],
+ {atomic, _} = mnesia:create_table(person, TabDef).
+
+stop(Nodes) ->
+ rpc:multicall(Nodes, mnesia, stop, []).
+
+%% Generate some dummy persons
+init_records(_Fun, 0) ->
+ {atomic, ok};
+init_records(Fun, Times) ->
+ {atomic, ok} = Fun(Times, 0 - Times),
+ init_records(Fun, Times - 1).
+
+tc(Fun, Times) ->
+ case catch timer:tc(?MODULE, repeat_meter, [Fun, Times]) of
+ {Micros, ok} ->
+ {ok, Micros div Times};
+ {_Micros, {error, Reason}} ->
+ {error, Reason};
+ {'EXIT', Reason} ->
+ {error, Reason}
+ end.
+
+%% The meter must return {atomic, ok}
+repeat_meter(Meter, Times) ->
+ repeat_meter(Meter, {atomic, ok}, Times).
+
+repeat_meter(_, {atomic, ok}, 0) ->
+ ok;
+repeat_meter(Meter, {atomic, _Result}, Times) when Times > 0 ->
+ repeat_meter(Meter, Meter(Times), Times - 1);
+repeat_meter(_Meter, Reason, _Times) ->
+ {error, Reason}.
+
diff --git a/lib/mnesia/test/mnesia_nice_coverage_test.erl b/lib/mnesia/test/mnesia_nice_coverage_test.erl
new file mode 100644
index 0000000000..aa9339f6b9
--- /dev/null
+++ b/lib/mnesia/test/mnesia_nice_coverage_test.erl
@@ -0,0 +1,227 @@
+%%
+%% %CopyrightBegin%
+%%
+%% 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
+%% 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(mnesia_nice_coverage_test).
+-author('[email protected]').
+-compile([export_all]).
+-include("mnesia_test_lib.hrl").
+
+-record(nice_tab, {key, val}).
+
+init_per_testcase(Func, Conf) ->
+ mnesia_test_lib:init_per_testcase(Func, Conf).
+
+fin_per_testcase(Func, Conf) ->
+ mnesia_test_lib:fin_per_testcase(Func, Conf).
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+all(doc) ->
+ ["Test nice usage of the entire API",
+ "Invoke all functions in the API, at least once.",
+ "Try to verify that all functions exists and that they perform",
+ "reasonable things when used in the most simple way."];
+all(suite) -> [nice].
+
+nice(doc) -> [""];
+nice(suite) -> [];
+nice(Config) when is_list(Config) ->
+ %% The whole test suite is one huge test case for the time beeing
+
+ [Node1, Node2] = Nodes = ?acquire_nodes(2, Config),
+ Attrs = record_info(fields, nice_tab),
+
+ initialize(Attrs, Node1),
+ dirty_access(Node1),
+ success_and_fail(),
+ index_mgt(),
+
+ adm(Attrs, Node1, Node2),
+ snmp(Node1, Node2),
+ backup(Node1),
+ ?verify_mnesia(Nodes, []).
+
+initialize(Attrs, Node1) ->
+ ?match(Version when is_list(Version), mnesia:system_info(version)),
+
+ Schema = [{name, nice_tab},
+ {attributes, Attrs}, {ram_copies, [Node1]}],
+
+ ?match({_, _}, mnesia:system_info(schema_version)),
+ ?match({atomic, ok}, mnesia:create_table(Schema)),
+
+ ?match(ok, mnesia:info()),
+ ?match(set, mnesia:table_info(nice_tab, type)),
+ ?match(ok, mnesia:schema()),
+ ?match(ok, mnesia:schema(nice_tab)),
+ ok.
+
+dirty_access(Node1) ->
+ TwoThree = #nice_tab{key=23, val=23},
+ TwoFive = #nice_tab{key=25, val=25},
+ ?match([], mnesia:dirty_slot(nice_tab, 0)),
+ ?match(ok, mnesia:dirty_write(TwoThree)),
+ ?match([TwoThree], mnesia:dirty_read({nice_tab, 23})),
+ ?match(ok, mnesia:dirty_write(TwoFive)),
+ ?match(ok, mnesia:dirty_delete_object(TwoFive)),
+
+ ?match(23, mnesia:dirty_first(nice_tab)),
+ ?match('$end_of_table', mnesia:dirty_next(nice_tab, 23)),
+ ?match([TwoThree], mnesia:dirty_match_object(TwoThree)),
+ ?match(ok, mnesia:dirty_delete({nice_tab, 23})),
+
+ CounterSchema = [{ram_copies, [Node1]}],
+ ?match({atomic, ok}, mnesia:create_table(nice_counter_tab, CounterSchema)),
+ TwoFour = {nice_counter_tab, 24, 24},
+ ?match(ok, mnesia:dirty_write(TwoFour)),
+ ?match(34, mnesia:dirty_update_counter({nice_counter_tab, 24}, 10)),
+ TF = {nice_counter_tab, 24, 34},
+ ?match([TF], mnesia:dirty_read({nice_counter_tab, 24})),
+ ?match(ok, mnesia:dirty_delete({nice_counter_tab, 24})),
+ ?match(ok, mnesia:dirty_delete_object(TF)),
+ ok.
+
+success_and_fail() ->
+ ?match({atomic, a_good_trans}, mnesia:transaction(fun() ->good_trans()end)),
+
+ BadFun =
+ fun() ->
+ Two = #nice_tab{key=2, val=12},
+ ?match([Two], mnesia:match_object(#nice_tab{key='$1', val=12})),
+ ?match([#nice_tab{key=3, val=13}], mnesia:wread({nice_tab, 3})),
+ ?match(ok, mnesia:delete({nice_tab, 1})),
+ ?match(ok, mnesia:delete_object(Two)),
+ mnesia:abort(bad_trans),
+ ?match(bad, trans)
+ end,
+ ?match({aborted, bad_trans}, mnesia:transaction(BadFun)),
+ ?match(L when is_list(L), mnesia:error_description(no_exists)),
+ ?match({atomic, ok}, mnesia:transaction(fun(A) -> lock(), A end, [ok])),
+ ?match({atomic, ok}, mnesia:transaction(fun(A) -> lock(), A end, [ok], 3)),
+ ok.
+
+good_trans() ->
+ ?match([], mnesia:read(nice_tab, 3)),
+ ?match([], mnesia:read({nice_tab, 3})),
+ ?match(ok, mnesia:write(#nice_tab{key=14, val=4})),
+ ?match([14], mnesia:all_keys(nice_tab)),
+
+ Records = [ #nice_tab{key=K, val=K+10} || K <- lists:seq(1, 10) ],
+ Ok = [ ok || _ <- Records],
+ ?match(Ok, lists:map(fun(R) -> mnesia:write(R) end, Records)),
+ a_good_trans.
+
+
+lock() ->
+ ?match(ok, mnesia:s_write(#nice_tab{key=22, val=22})),
+ ?match(ok, mnesia:read_lock_table(nice_tab)),
+ ?match(ok, mnesia:write_lock_table(nice_tab)),
+ ok.
+
+index_mgt() ->
+ UniversalRec = #nice_tab{key=4711, val=4711},
+ ?match(ok, mnesia:dirty_write(UniversalRec)),
+ ValPos = #nice_tab.val,
+ ?match({atomic, ok}, mnesia:add_table_index(nice_tab, ValPos)),
+
+ IndexFun =
+ fun() ->
+ ?match([UniversalRec],
+ mnesia:index_read(nice_tab, 4711, ValPos)),
+ Pat = #nice_tab{key='$1', val=4711},
+ ?match([UniversalRec],
+ mnesia:index_match_object(Pat, ValPos)),
+ index_trans
+ end,
+ ?match({atomic, index_trans}, mnesia:transaction(IndexFun, infinity)),
+ ?match([UniversalRec],
+ mnesia:dirty_index_read(nice_tab, 4711, ValPos)),
+ ?match([UniversalRec],
+ mnesia:dirty_index_match_object(#nice_tab{key='$1', val=4711}, ValPos)),
+
+ ?match({atomic, ok}, mnesia:del_table_index(nice_tab, ValPos)),
+ ok.
+
+adm(Attrs, Node1, Node2) ->
+ This = node(),
+ ?match({ok, This}, mnesia:subscribe(system)),
+ ?match({atomic, ok},
+ mnesia:add_table_copy(nice_tab, Node2, disc_only_copies)),
+ ?match({atomic, ok},
+ mnesia:change_table_copy_type(nice_tab, Node2, ram_copies)),
+ ?match({atomic, ok}, mnesia:del_table_copy(nice_tab, Node1)),
+ ?match(stopped, rpc:call(Node1, mnesia, stop, [])),
+ ?match([], mnesia_test_lib:start_mnesia([Node1, Node2], [nice_tab])),
+ ?match(ok, mnesia:wait_for_tables([schema], infinity)),
+
+ Transformer = fun(Rec) ->
+ list_to_tuple(tuple_to_list(Rec) ++ [initial_value])
+ end,
+ ?match({atomic, ok},
+ mnesia:transform_table(nice_tab, Transformer, Attrs ++ [extra])),
+
+ ?match({atomic, ok}, mnesia:delete_table(nice_tab)),
+ DumpSchema = [{name, nice_tab}, {attributes, Attrs}, {ram_copies, [Node2]}],
+ ?match({atomic, ok}, mnesia:create_table(DumpSchema)),
+ ?match({atomic, ok}, mnesia:dump_tables([nice_tab])),
+ ?match({atomic, ok}, mnesia:move_table_copy(nice_tab, Node2, Node1)),
+
+ ?match(yes, mnesia:force_load_table(nice_counter_tab)),
+ ?match(dumped, mnesia:dump_log()),
+ ok.
+
+backup(Node1) ->
+ Tab = backup_nice,
+ Def = [{disc_copies, [Node1]}],
+ ?match({atomic, ok}, mnesia:create_table(Tab, Def)),
+ ?match({ok,_,_}, mnesia:activate_checkpoint([{name, cp}, {max, [Tab]}])),
+ File = "nice_backup.BUP",
+ File2 = "nice_backup2.BUP",
+ File3 = "nice_backup3.BUP",
+ ?match(ok, mnesia:backup_checkpoint(cp, File)),
+ ?match(ok, mnesia:backup_checkpoint(cp, File, mnesia_backup)),
+ ?match(ok, mnesia:deactivate_checkpoint(cp)),
+ ?match(ok, mnesia:backup(File)),
+ ?match(ok, mnesia:backup(File, mnesia_backup)),
+
+ Fun = fun(X, Acc) -> {[X], Acc} end,
+ ?match({ok, 0}, mnesia:traverse_backup(File, File2, Fun, 0)),
+ ?match({ok, 0}, mnesia:traverse_backup(File, mnesia_backup, dummy, read_only, Fun, 0)),
+ ?match(ok, mnesia:install_fallback(File)),
+ ?match(ok, mnesia:uninstall_fallback()),
+ ?match(ok, mnesia:install_fallback(File, mnesia_backup)),
+ ?match(ok, mnesia:dump_to_textfile(File3)),
+ ?match({atomic, ok}, mnesia:load_textfile(File3)),
+ ?match(ok, file:delete(File)),
+ ?match(ok, file:delete(File2)),
+ ?match(ok, file:delete(File3)),
+ ok.
+
+snmp(Node1, Node2) ->
+ Tab = nice_snmp,
+ Def = [{disc_copies, [Node1]}, {ram_copies, [Node2]}],
+ ?match({atomic, ok}, mnesia:create_table(Tab, Def)),
+ ?match({aborted, {badarg, Tab, _}}, mnesia:snmp_open_table(Tab, [])),
+ ?match({atomic, ok}, mnesia:snmp_open_table(Tab, [{key, integer}])),
+ ?match(endOfTable, mnesia:snmp_get_next_index(Tab, [0])),
+ ?match(undefined, mnesia:snmp_get_row(Tab, [0])),
+ ?match(undefined, mnesia:snmp_get_mnesia_key(Tab, [0])),
+ ?match({atomic, ok}, mnesia:snmp_close_table(Tab)),
+ ok.
+
diff --git a/lib/mnesia/test/mnesia_qlc_test.erl b/lib/mnesia/test/mnesia_qlc_test.erl
new file mode 100644
index 0000000000..1e4f776c7d
--- /dev/null
+++ b/lib/mnesia/test/mnesia_qlc_test.erl
@@ -0,0 +1,475 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 2004-2010. All Rights Reserved.
+%%
+%% The contents of this file are subject to the Erlang Public License,
+%% Version 1.1, (the "License"); you may not use this file except in
+%% compliance with the License. You should have received a copy of the
+%% Erlang Public License along with this software. If not, it can be
+%% retrieved online at http://www.erlang.org/.
+%%
+%% Software distributed under the License is distributed on an "AS IS"
+%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+%% the License for the specific language governing rights and limitations
+%% under the License.
+%%
+%% %CopyrightEnd%
+%%
+
+%%
+-module(mnesia_qlc_test).
+
+-compile(export_all).
+
+-export([all/1]).
+
+-include("mnesia_test_lib.hrl").
+-include_lib("stdlib/include/qlc.hrl").
+
+init_per_testcase(Func, Conf) ->
+ setup(Conf),
+ mnesia_test_lib:init_per_testcase(Func, Conf).
+
+fin_per_testcase(Func, Conf) ->
+ mnesia_test_lib:fin_per_testcase(Func, Conf).
+
+all(doc) ->
+ ["Test that the qlc mnesia interface works as expected."];
+all(suite) ->
+ case code:which(qlc) of
+ non_existing -> [];
+ _ ->
+ all_qlc()
+ end.
+
+all_qlc() ->
+ [dirty, trans, frag, info, mnesia_down].
+
+init_testcases(Type,Config) ->
+ Nodes = [N1,N2] = ?acquire_nodes(2, Config),
+ ?match({atomic, ok}, mnesia:create_table(a, [{Type,[N1]}, {index,[3]}])),
+ ?match({atomic, ok}, mnesia:create_table(b, [{Type,[N2]}])),
+ Write = fun(Id) ->
+ ok = mnesia:write({a, {a,Id}, 100 - Id}),
+ ok = mnesia:write({b, {b,100-Id}, Id})
+ end,
+ All = fun() -> [Write(Id) || Id <- lists:seq(1,10)], ok end,
+ ?match({atomic, ok}, mnesia:sync_transaction(All)),
+ Nodes.
+
+%% Test cases
+dirty(suite) ->
+ [dirty_nice_ram_copies,
+ dirty_nice_disc_copies,
+ dirty_nice_disc_only_copies].
+
+dirty_nice_ram_copies(Setup) -> dirty_nice(Setup,ram_copies).
+dirty_nice_disc_copies(Setup) -> dirty_nice(Setup,disc_copies).
+dirty_nice_disc_only_copies(Setup) -> dirty_nice(Setup,disc_only_copies).
+
+dirty_nice(suite, _) -> [];
+dirty_nice(doc, _) -> [];
+dirty_nice(Config, Type) when is_list(Config) ->
+ Ns = init_testcases(Type,Config),
+ QA = handle(<<"[Q || Q = {_,{_,Key},Val} <- mnesia:table(a),"
+ " Val == 90 + Key]">>),
+ QB = handle(<<"[Q || Q = {_,{_,Key},Val} <- mnesia:table(b),"
+ " Key == 90 + Val]">>),
+ QC = qlc:sort(mnesia:table(a, [{n_objects,1}, {lock,write}, {traverse, select}])),
+ QD = qlc:sort(mnesia:table(a, [{n_objects,1}, {traverse,{select,[{'$1',[],['$1']}]}}])),
+
+ FA = fun() -> qlc:e(QA) end,
+ FB = fun() -> qlc:e(QB) end,
+ FC = fun() -> qlc:e(QC) end,
+ FD = fun() -> qlc:e(QD) end,
+
+ %% Currently unsupported
+ ?match({'EXIT',{aborted,no_transaction}}, FA()),
+ ?match({'EXIT',{aborted,no_transaction}}, FB()),
+ %%
+ CRes = lists:sort(mnesia:dirty_match_object(a, {'_','_','_'})),
+ ?match([{a,{a,5},95}], mnesia:async_dirty(FA)),
+ ?match([{b,{b,95},5}], mnesia:async_dirty(FB)),
+ ?match(CRes, mnesia:async_dirty(FC)),
+ ?match(CRes, mnesia:async_dirty(FD)),
+ ?match([{a,{a,5},95}], mnesia:sync_dirty(FA)),
+ ?match([{b,{b,95},5}], mnesia:sync_dirty(FB)),
+ ?match(CRes, mnesia:sync_dirty(FC)),
+ ?match([{a,{a,5},95}], mnesia:activity(async_dirty, FA)),
+ ?match([{b,{b,95},5}], mnesia:activity(async_dirty, FB)),
+ ?match([{a,{a,5},95}], mnesia:activity(sync_dirty, FA)),
+ ?match([{b,{b,95},5}], mnesia:activity(sync_dirty, FB)),
+ ?match(CRes, mnesia:activity(async_dirty,FC)),
+ case Type of
+ disc_only_copies -> skip;
+ _ ->
+ ?match([{a,{a,5},95}], mnesia:ets(FA)),
+ ?match([{a,{a,5},95}], mnesia:activity(ets, FA))
+ end,
+ ?verify_mnesia(Ns, []).
+
+trans(suite) ->
+ [trans_nice_ram_copies,
+ trans_nice_disc_copies,
+ trans_nice_disc_only_copies,
+ atomic
+ ].
+
+trans_nice_ram_copies(Setup) -> trans_nice(Setup,ram_copies).
+trans_nice_disc_copies(Setup) -> trans_nice(Setup,disc_copies).
+trans_nice_disc_only_copies(Setup) -> trans_nice(Setup,disc_only_copies).
+
+trans_nice(suite, _) -> [];
+trans_nice(doc, _) -> [];
+trans_nice(Config, Type) when is_list(Config) ->
+ Ns = init_testcases(Type,Config),
+ QA = handle(<<"[Q || Q = {_,{_,Key},Val} <- mnesia:table(a),"
+ " Val == 90 + Key]">>),
+ QB = handle(<<"[Q || Q = {_,{_,Key},Val} <- mnesia:table(b),"
+ " Key == 90 + Val]">>),
+ QC = handle(recs(),
+ <<"[Q || Q = #a{v=91} <- mnesia:table(a)]"
+ >>),
+
+ QD = qlc:sort(mnesia:table(a, [{n_objects,1}, {lock,write}, {traverse, select}])),
+ QE = qlc:sort(mnesia:table(a, [{n_objects,1}, {traverse,{select,[{'$1',[],['$1']}]}}])),
+
+ DRes = lists:sort(mnesia:dirty_match_object(a, {'_','_','_'})),
+
+ FA = fun() -> qlc:e(QA) end,
+ FB = fun() -> qlc:e(QB) end,
+ FC = fun() -> qlc:e(QC) end,
+ FD = fun() -> qlc:e(QD) end,
+ FE = fun() -> qlc:e(QE) end,
+
+ ?match({atomic,[{a,{a,5},95}]}, mnesia:transaction(FA)),
+ ?match({atomic,[{b,{b,95},5}]}, mnesia:transaction(FB)),
+ ?match({atomic,[{a,{a,9},91}]}, mnesia:transaction(FC)),
+ ?match({atomic,[{a,{a,5},95}]}, mnesia:sync_transaction(FA)),
+ ?match({atomic,[{b,{b,95},5}]}, mnesia:sync_transaction(FB)),
+ ?match({atomic,[{a,{a,9},91}]}, mnesia:sync_transaction(FC)),
+ ?match([{a,{a,5},95}], mnesia:activity(transaction,FA)),
+ ?match([{b,{b,95},5}], mnesia:activity(transaction,FB)),
+ ?match([{a,{a,9},91}], mnesia:activity(transaction,FC)),
+ ?match([{a,{a,5},95}], mnesia:activity(sync_transaction,FA)),
+ ?match([{b,{b,95},5}], mnesia:activity(sync_transaction,FB)),
+ ?match([{a,{a,9},91}], mnesia:activity(sync_transaction,FC)),
+
+ ?match({atomic, DRes}, mnesia:transaction(FD)),
+ ?match({atomic, DRes}, mnesia:transaction(FE)),
+
+ Rest = fun(Cursor,Loop) ->
+ case qlc:next_answers(Cursor, 1) of
+ [] -> [];
+ [A]-> [A|Loop(Cursor,Loop)]
+ end
+ end,
+ Loop = fun() ->
+ Cursor = qlc:cursor(QD),
+ Rest(Cursor,Rest)
+ end,
+ ?match({atomic, DRes}, mnesia:transaction(Loop)),
+
+ ?verify_mnesia(Ns, []).
+
+%% -record(a, {k,v}).
+%% -record(b, {k,v}).
+%% -record(k, {t,v}).
+
+recs() ->
+ <<"-record(a, {k,v}). "
+ "-record(b, {k,v}). "
+ "-record(k, {t,v}). "
+ >>.
+
+atomic(suite) -> [atomic_eval];
+atomic(doc) -> [].
+
+atomic_eval(suite) -> [];
+atomic_eval(doc) -> [];
+atomic_eval(Config) ->
+ Ns = init_testcases(ram_copies, Config),
+ Q1 = handle(recs(),
+ <<"[Q || Q = #a{k={_,9}} <- mnesia:table(a)]"
+ >>),
+ Eval = fun(Q) ->
+ {qlc:e(Q),
+ mnesia:system_info(held_locks)}
+ end,
+ Self = self(),
+ ?match({[{a,{a,9},91}], [{{a,'______WHOLETABLE_____'},read,{tid,_,Self}}]},
+ ok(Eval,[Q1])),
+
+ Q2 = handle(recs(),
+ <<"[Q || Q = #a{k={a,9}} <- mnesia:table(a)]"
+ >>),
+
+ ?match({[{a,{a,9},91}],[{{a,{a,9}},read,{tid,_,Self}}]},
+ ok(Eval,[Q2])),
+
+ Flush = fun(Loop) -> %% Clean queue
+ receive _ -> Loop(Loop)
+ after 0 -> ok end
+ end,
+
+ Flush(Flush),
+
+ GrabLock = fun(Father) ->
+ mnesia:read(a, {a,9}, write),
+ Father ! locked,
+ receive cont -> ok end end,
+
+ Pid1 = spawn(fun() -> ?match(ok, ok(GrabLock, [Self])) end),
+ ?match(locked,receive locked -> locked after 5000 -> timeout end), %% Wait
+
+ put(count,0),
+ Restart = fun(Locker,Fun) ->
+ Count = get(count),
+ case {Count,(catch Fun())} of
+ {0, {'EXIT', R}} ->
+ Locker ! cont,
+ put(count, Count+1),
+ erlang:yield(),
+ exit(R);
+ Else ->
+ Else
+ end
+ end,
+
+ ?match({1,{[{a,{a,9},91}], [{{a,'______WHOLETABLE_____'},read,{tid,_,Self}}]}},
+ ok(Restart,[Pid1,fun() -> Eval(Q1) end])),
+
+ Pid2 = spawn(fun() -> ?match(ok, ok(GrabLock, [Self])) end),
+ ?match(locked,receive locked -> locked after 5000 -> timeout end), %% Wait
+ put(count,0),
+ ?match({1,{[{a,{a,9},91}],[{{a,{a,9}},read,{tid,_,Self}}]}},
+ ok(Restart,[Pid2, fun() -> Eval(Q2) end])),
+
+%% Basic test
+ Cursor = fun() ->
+ QC = qlc:cursor(Q1),
+ qlc:next_answers(QC)
+ end,
+
+ ?match([{a,{a,9},91}], ok(Cursor, [])),
+ %% Lock
+
+ Pid3 = spawn(fun() -> ?match(ok, ok(GrabLock, [Self])) end),
+ ?match(locked,receive locked -> locked after 5000 -> timeout end), %% Wait
+ put(count,0),
+
+ ?match({1,[{a,{a,9},91}]}, ok(Restart,[Pid3, Cursor])),
+ QC1 = ok(fun() -> qlc:cursor(Q1) end, []),
+ ?match({'EXIT', _}, qlc:next_answers(QC1)),
+ ?match({aborted,_}, ok(fun()->qlc:next_answers(QC1)end,[])),
+ ?verify_mnesia(Ns, []).
+
+
+frag(suite) -> [];
+frag(doc) -> [];
+frag(Config) ->
+ Ns = init_testcases(ram_copies,Config),
+ QA = handle(<<"[Q || Q = {_,{_,Key},Val} <- mnesia:table(a),"
+ " Val == 90 + Key]">>),
+ QB = handle(<<"[Q || Q = {_,{_,Key},Val} <- mnesia:table(b),"
+ " Key == 90 + Val]">>),
+
+ Activate =
+ fun(Tab) ->
+ ?match({atomic,ok},mnesia:change_table_frag(Tab, {activate, []})),
+ Dist = mnesia_frag_test:frag_dist(Tab),
+ ?match({atomic,ok},mnesia:change_table_frag(Tab,{add_frag,Dist}))
+ end,
+ Activate(a),
+ Activate(b),
+
+ Fun = fun(Tab) -> mnesia:table_info(Tab, frag_names) end,
+ FTs = mnesia:activity(sync_dirty, Fun, [a], mnesia_frag) ++
+ mnesia:activity(sync_dirty, Fun, [b], mnesia_frag),
+ Size = fun(Tab) -> mnesia:dirty_rpc(Tab, mnesia, table_info, [Tab,size]) end,
+
+ %% Verify that all data doesn't belong to the same frag.
+ ?match([], [{Tab,Size(Tab)} || Tab <- FTs,
+ Size(Tab) =< 0]),
+
+ FA = fun() -> qlc:e(QA) end,
+ FB = fun() -> qlc:e(QB) end,
+ ?match([{a,{a,5},95}], mnesia:activity(transaction,FA,[],mnesia_frag)),
+ ?match([{b,{b,95},5}], mnesia:activity(transaction,FB,[],mnesia_frag)),
+
+ ?verify_mnesia(Ns, []).
+
+info(suite) -> [];
+info(doc) -> [];
+info(Config) ->
+ Ns = init_testcases(ram_copies, Config),
+ Q1 = handle(recs(),
+ <<"[Q || Q = #a{k={_,9}} <- mnesia:table(a)]"
+ >>),
+
+ Q2 = handle(recs(),
+ <<"[Q || Q = #a{k={a,9}} <- mnesia:table(a)]"
+ >>),
+
+ Q3 = handle(recs(),
+ <<"[Q || Q = #a{v=91} <- mnesia:table(a)]"
+ >>),
+
+ %% FIXME compile and check results!
+
+ ?match(ok,io:format("~s~n",[qlc:info(Q1)])),
+ ?match(ok,io:format("~s~n",[qlc:info(Q2)])),
+ ?match(ok,io:format("~s~n",[qlc:info(Q3)])),
+
+ ?verify_mnesia(Ns, []).
+
+ok(Fun,A) ->
+ case mnesia:transaction(Fun,A) of
+ {atomic, R} -> R;
+ E -> E
+ end.
+
+
+mnesia_down(suite) -> [];
+mnesia_down(doc) ->
+ ["Test bug OTP-7968, which crashed mnesia when a"
+ "mnesia_down came after qlc had been invoked"];
+mnesia_down(Config) when is_list(Config) ->
+ [N1,N2] = init_testcases(ram_copies,Config),
+ QB = handle(<<"[Q || Q = {_,{_,Key},Val} <- mnesia:table(b),"
+ " Val == Key - 90]">>),
+
+ Tester = self(),
+
+ Eval = fun() ->
+ Cursor = qlc:cursor(QB), %% Forces another process
+ Res = qlc:next_answers(Cursor),
+ Tester ! {qlc, self(), Res},
+ {Mod, Tid, Ts} = get(mnesia_activity_state),
+ receive
+ continue ->
+ io:format("Continuing ~p ~p ~n",[self(), {Mod, Tid, Ts}]),
+ io:format("ETS ~p~n",[ets:tab2list(element(2,Ts))]),
+ io:format("~p~n",[process_info(self(),messages)]),
+ Res
+ end
+ end,
+ spawn(fun() -> TransRes = mnesia:transaction(Eval), Tester ! {test,TransRes} end),
+
+ TMInfo = fun() ->
+ TmInfo = mnesia_tm:get_info(5000),
+ mnesia_tm:display_info(user, TmInfo)
+ end,
+ receive
+ {qlc, QPid, QRes} ->
+ ?match([{b,{b,95},5}], QRes),
+ TMInfo(),
+ mnesia_test_lib:kill_mnesia([N2]),
+ %%timer:sleep(1000),
+ QPid ! continue
+ after 2000 ->
+ exit(timeout1)
+ end,
+
+ receive
+ {test, QRes2} ->
+ ?match({atomic, [{b,{b,95},5}]}, QRes2)
+ after 2000 ->
+ exit(timeout2)
+ end,
+
+ ?verify_mnesia([N1], [N2]).
+
+
+nested_qlc(suite) -> [];
+nested_qlc(doc) ->
+ ["Test bug in OTP-7968 (the second problem) where nested"
+ "transaction don't work as expected"];
+nested_qlc(Config) when is_list(Config) ->
+ Ns = init_testcases(ram_copies,Config),
+ Res = as_with_bs(),
+ ?match([_|_], Res),
+ top_as_with_some_bs(10),
+
+ ?verify_mnesia(Ns, []).
+
+
+%% Code from Daniel
+bs_by_a_id(A_id) ->
+ find(qlc:q([ B || B={_,_,F_id} <- mnesia:table(b), F_id == A_id])).
+
+as_with_bs() ->
+ find(qlc:q([ {A,bs_by_a_id(Id)} ||
+ A = {_, {a,Id}, _} <- mnesia:table(a)])).
+
+top_as_with_some_bs(Limit) ->
+ top(
+ qlc:q([ {A,bs_by_a_id(Id)} ||
+ A = {_, {a,Id}, _} <- mnesia:table(a)]),
+ Limit,
+ fun(A1,A2) -> A1 < A2 end
+ ).
+
+% --- utils
+
+find(Q) ->
+ F = fun() -> qlc:e(Q) end,
+ {atomic, Res} = mnesia:transaction(F),
+ Res.
+
+% --- it returns top Limit results from query Q ordered by Order sort function
+top(Q, Limit, Order) ->
+ Do = fun() ->
+ OQ = qlc:sort(Q, [{order,Order}]),
+ QC = qlc:cursor(OQ),
+ Res = qlc:next_answers(QC, Limit),
+ qlc:delete_cursor(QC),
+ Res
+ end,
+ {atomic, Res} = mnesia:transaction(Do),
+ Res.
+
+%% To keep mnesia suite backward compatible,
+%% we compile the queries in runtime when qlc is available
+%% Compiles and returns a handle to a qlc
+handle(Expr) ->
+ handle(<<>>,Expr).
+handle(Records,Expr) ->
+ case catch handle2(Records,Expr) of
+ {ok, Handle} ->
+ Handle;
+ Else ->
+ ?match(ok, Else)
+ end.
+
+handle2(Records,Expr) ->
+ {FN,Mod} = temp_name(),
+ ModStr = list_to_binary("-module(" ++ atom_to_list(Mod) ++ ").\n"),
+ Prog = <<
+ ModStr/binary,
+ "-include_lib(\"stdlib/include/qlc.hrl\").\n",
+ "-export([tmp/0]).\n",
+ Records/binary,"\n",
+ "tmp() ->\n",
+%% " _ = (catch throw(fvalue_not_reset)),"
+ " qlc:q( ",
+ Expr/binary,").\n">>,
+
+ ?match(ok,file:write_file(FN,Prog)),
+ {ok,Forms} = epp:parse_file(FN,"",""),
+ {ok,Mod,Bin} = compile:forms(Forms),
+ code:load_binary(Mod,FN,Bin),
+ {ok, Mod:tmp()}.
+
+setup(Config) ->
+ put(mts_config,Config),
+ put(mts_tf_counter,0).
+
+temp_name() ->
+ Conf = get(mts_config),
+ C = get(mts_tf_counter),
+ put(mts_tf_counter,C+1),
+ {filename:join([proplists:get_value(priv_dir,Conf, "."),
+ "tempfile"++integer_to_list(C)++".tmp"]),
+ list_to_atom("tmp" ++ integer_to_list(C))}.
diff --git a/lib/mnesia/test/mnesia_recovery_test.erl b/lib/mnesia/test/mnesia_recovery_test.erl
new file mode 100644
index 0000000000..f6ecf2ce2e
--- /dev/null
+++ b/lib/mnesia/test/mnesia_recovery_test.erl
@@ -0,0 +1,1701 @@
+%%
+%% %CopyrightBegin%
+%%
+%% 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
+%% 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(mnesia_recovery_test).
+-author('[email protected]').
+-compile([export_all]).
+
+-include("mnesia_test_lib.hrl").
+-include_lib("kernel/include/file.hrl").
+
+init_per_testcase(Func, Conf) ->
+ mnesia_test_lib:init_per_testcase(Func, Conf).
+
+fin_per_testcase(Func, Conf) ->
+ mnesia_test_lib:fin_per_testcase(Func, Conf).
+
+-define(receive_messages(Msgs), receive_messages(Msgs, ?FILE, ?LINE)).
+
+% First Some debug logging
+-define(dgb, true).
+-ifdef(dgb).
+-define(dl(X, Y), ?verbose("**TRACING: " ++ X ++ "**~n", Y)).
+-else.
+-define(dl(X, Y), ok).
+-endif.
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+all(doc) ->
+ ["Verify recoverability",
+ "Verify that the effects of committed transactions are preserved",
+ "after recovery from system failures. It must be possible to",
+ "restore the tables to a consistent state on a node, from (any kind",
+ "of) replica on other nodes as well as from local disk on the failed",
+ "node. The system must also recover from instantaneous",
+ "interruption causing disk files to not be completely synchronized."];
+
+all(suite) ->
+ [
+ mnesia_down,
+ explicit_stop,
+ coord_dies,
+ schema_trans,
+ async_dirty,
+ sync_dirty,
+ sym_trans,
+ asym_trans,
+ after_full_disc_partition,
+ after_corrupt_files,
+ disc_less,
+ garb_decision,
+ system_upgrade
+ ].
+
+schema_trans(suite) ->
+ [{mnesia_schema_recovery_test, all}].
+
+tpcb_config(ReplicaType, _NodeConfig, Nodes) ->
+ [{n_branches, 5},
+ {n_drivers_per_node, 5},
+ {replica_nodes, Nodes},
+ {driver_nodes, Nodes},
+ {use_running_mnesia, true},
+ {report_interval, infinity},
+ {n_accounts_per_branch, 20},
+ {replica_type, ReplicaType}].
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+mnesia_down(doc) ->
+ [" Various tests about recovery when mnesia goes down on one or several nodes."];
+mnesia_down(suite) ->
+ [
+ mnesia_down_during_startup,
+ master_node_tests,
+ read_during_down,
+ with_checkpoint,
+ delete_during_start
+ ].
+
+master_node_tests(doc) ->
+ ["Verify that mnesia loads the correct data after it has been down, regarding master node settings."];
+master_node_tests(suite) ->
+ [
+ no_master_2,
+ no_master_3,
+ one_master_2,
+ one_master_3,
+ two_master_2,
+ two_master_3,
+ all_master_2,
+ all_master_3
+ ].
+
+no_master_2(suite) -> [];
+no_master_2(Config) when is_list(Config) -> mnesia_down_2(no, Config).
+
+no_master_3(suite) -> [];
+no_master_3(Config) when is_list(Config) -> mnesia_down_3(no, Config).
+
+one_master_2(suite) -> [];
+one_master_2(Config) when is_list(Config) -> mnesia_down_2(one, Config).
+
+one_master_3(suite) -> [];
+one_master_3(Config) when is_list(Config) -> mnesia_down_3(one, Config).
+
+two_master_2(suite) -> [];
+two_master_2(Config) when is_list(Config) -> mnesia_down_2(two, Config).
+
+two_master_3(suite) -> [];
+two_master_3(Config) when is_list(Config) -> mnesia_down_3(two, Config).
+
+all_master_2(suite) -> [];
+all_master_2(Config) when is_list(Config) -> mnesia_down_2(all, Config).
+
+all_master_3(suite) -> [];
+all_master_3(Config) when is_list(Config) -> mnesia_down_3(all, Config).
+
+mnesia_down_2(Masters, Config) ->
+ Nodes = [N1, N2] = ?acquire_nodes(2, Config),
+ ?match({atomic, ok}, mnesia:create_table(tab1, [{ram_copies, Nodes}])),
+ ?match({atomic, ok}, mnesia:create_table(tab2, [{disc_copies, Nodes}])),
+ ?match({atomic, ok}, mnesia:create_table(tab3, [{disc_only_copies, Nodes}])),
+ ?match({atomic, ok}, mnesia:create_table(tab4, [{ram_copies, [N1]}])),
+ ?match({atomic, ok}, mnesia:create_table(tab5, [{ram_copies, [N2]}])),
+ ?match({atomic, ok}, mnesia:create_table(tab6, [{disc_copies, [N1]}])),
+ ?match({atomic, ok}, mnesia:create_table(tab7, [{disc_copies, [N2]}])),
+ ?match({atomic, ok}, mnesia:create_table(tab8, [{disc_only_copies, [N1]}])),
+ ?match({atomic, ok}, mnesia:create_table(tab9, [{disc_only_copies, [N2]}])),
+ ?match({atomic, ok}, mnesia:create_table(tab10, [{ram_copies, [N1]}, {disc_copies, [N2]}])),
+ ?match({atomic, ok}, mnesia:create_table(tab11, [{ram_copies, [N2]}, {disc_copies, [N1]}])),
+ ?match({atomic, ok}, mnesia:create_table(tab12, [{ram_copies, [N1]}, {disc_only_copies, [N2]}])),
+ ?match({atomic, ok}, mnesia:create_table(tab13, [{ram_copies, [N2]}, {disc_only_copies, [N1]}])),
+ ?match({atomic, ok}, mnesia:create_table(tab14, [{disc_only_copies, [N1]}, {disc_copies, [N2]}])),
+ ?match({atomic, ok}, mnesia:create_table(tab15, [{disc_only_copies, [N2]}, {disc_copies, [N1]}])),
+
+ Tabs = [tab1, tab2, tab3, tab4, tab5, tab6, tab7, tab8,
+ tab9, tab10, tab11, tab12, tab13, tab14, tab15],
+ [?match(ok, rpc:call(Node, mnesia, wait_for_tables, [Tabs, 10000])) || Node <- Nodes],
+ [insert_data(Tab, 20) || Tab <- Tabs],
+
+ VTabs =
+ case Masters of
+ no ->
+ Tabs -- [tab4, tab5]; % ram copies
+ one ->
+ ?match(ok, rpc:call(N1, mnesia, set_master_nodes, [[N1]])),
+ Tabs -- [tab1, tab4, tab5, tab10, tab12]; % ram_copies
+ two ->
+ ?match(ok, rpc:call(N1, mnesia, set_master_nodes, [Nodes])),
+ Tabs -- [tab4, tab5];
+ all ->
+ [?match(ok, rpc:call(Node, mnesia, set_master_nodes, [[Node]])) || Node <- Nodes],
+ Tabs -- [tab1, tab4, tab5, tab10, tab11, tab12, tab13]
+ end,
+
+ mnesia_test_lib:kill_mnesia([N1]),
+ ?match([], mnesia_test_lib:start_mnesia(Nodes, Tabs)),
+
+ ?match([], mnesia_test_lib:kill_mnesia([N2])),
+ ?match([], mnesia_test_lib:start_mnesia(Nodes, Tabs)),
+
+ [?match(ok, rpc:call(N1, ?MODULE, verify_data, [Tab, 20])) || Tab <- VTabs],
+ [?match(ok, rpc:call(N2, ?MODULE, verify_data, [Tab, 20])) || Tab <- VTabs],
+ ?verify_mnesia(Nodes, []).
+
+mnesia_down_3(Masters, Config) ->
+ Nodes = [N1, N2, N3] = ?acquire_nodes(3, Config),
+ ?match({atomic, ok}, mnesia:create_table(tab1, [{ram_copies, Nodes}])),
+ ?match({atomic, ok}, mnesia:create_table(tab2, [{disc_copies, Nodes}])),
+ ?match({atomic, ok}, mnesia:create_table(tab3, [{disc_only_copies, Nodes}])),
+ ?match({atomic, ok}, mnesia:create_table(tab4, [{ram_copies, [N1]}])),
+ ?match({atomic, ok}, mnesia:create_table(tab5, [{ram_copies, [N2]}])),
+ ?match({atomic, ok}, mnesia:create_table(tab16, [{ram_copies, [N3]}])),
+ ?match({atomic, ok}, mnesia:create_table(tab6, [{disc_copies, [N1]}])),
+ ?match({atomic, ok}, mnesia:create_table(tab7, [{disc_copies, [N2]}])),
+ ?match({atomic, ok}, mnesia:create_table(tab17, [{disc_copies, [N3]}])),
+ ?match({atomic, ok}, mnesia:create_table(tab8, [{disc_only_copies, [N1]}])),
+ ?match({atomic, ok}, mnesia:create_table(tab9, [{disc_only_copies, [N2]}])),
+ ?match({atomic, ok}, mnesia:create_table(tab18, [{disc_only_copies, [N3]}])),
+ ?match({atomic, ok}, mnesia:create_table(tab10, [{ram_copies, [N1]}, {disc_copies, [N2, N3]}])),
+ ?match({atomic, ok}, mnesia:create_table(tab11, [{ram_copies, [N2]}, {disc_copies, [N3, N1]}])),
+ ?match({atomic, ok}, mnesia:create_table(tab19, [{ram_copies, [N3]}, {disc_copies, [N1, N2]}])),
+ ?match({atomic, ok}, mnesia:create_table(tab12, [{ram_copies, [N1]}, {disc_only_copies, [N2, N3]}])),
+ ?match({atomic, ok}, mnesia:create_table(tab13, [{ram_copies, [N2]}, {disc_only_copies, [N3, N1]}])),
+ ?match({atomic, ok}, mnesia:create_table(tab20, [{ram_copies, [N3]}, {disc_only_copies, [N1, N2]}])),
+ ?match({atomic, ok}, mnesia:create_table(tab14, [{disc_only_copies, [N1]}, {disc_copies, [N2, N3]}])),
+ ?match({atomic, ok}, mnesia:create_table(tab15, [{disc_only_copies, [N2]}, {disc_copies, [N3, N1]}])),
+ ?match({atomic, ok}, mnesia:create_table(tab21, [{disc_only_copies, [N3]}, {disc_copies, [N1, N2]}])),
+
+ Tabs = [tab1, tab2, tab3, tab4, tab5, tab6, tab7, tab8,
+ tab9, tab10, tab11, tab12, tab13, tab14, tab15,
+ tab16, tab17, tab18, tab19, tab20, tab21],
+ [?match(ok, rpc:call(Node, mnesia, wait_for_tables, [Tabs, 10000])) || Node <- Nodes],
+ [insert_data(Tab, 20) || Tab <- Tabs],
+
+ VTabs =
+ case Masters of
+ no ->
+ Tabs -- [tab4, tab5, tab16]; % ram copies
+ one ->
+ ?match(ok, rpc:call(N1, mnesia, set_master_nodes, [[N1]])),
+ Tabs -- [tab1, tab4, tab5, tab16, tab10, tab12]; % ram copies
+ two ->
+ ?match(ok, rpc:call(N1, mnesia, set_master_nodes, [Nodes])),
+ Tabs -- [tab4, tab5, tab16]; % ram copies
+ all ->
+ [?match(ok, rpc:call(Node, mnesia, set_master_nodes, [[Node]])) || Node <- Nodes],
+ Tabs -- [tab1, tab4, tab5, tab16, tab10,
+ tab11, tab19, tab12, tab13, tab20] % ram copies
+ end,
+
+ mnesia_test_lib:kill_mnesia([N1]),
+ ?match([], mnesia_test_lib:start_mnesia(Nodes, Tabs)),
+
+ ?match([], mnesia_test_lib:kill_mnesia([N2])),
+ ?match([], mnesia_test_lib:start_mnesia(Nodes, Tabs)),
+
+ ?match([], mnesia_test_lib:kill_mnesia([N3])),
+ ?match([], mnesia_test_lib:start_mnesia(Nodes, Tabs)),
+
+ ?match([], mnesia_test_lib:kill_mnesia([N2, N1])),
+ ?match([], mnesia_test_lib:start_mnesia(Nodes, Tabs)),
+
+ ?match([], mnesia_test_lib:kill_mnesia([N2, N3])),
+ ?match([], mnesia_test_lib:start_mnesia(Nodes, Tabs)),
+
+ ?match([], mnesia_test_lib:kill_mnesia([N1, N3])),
+ ?match([], mnesia_test_lib:start_mnesia(Nodes, Tabs)),
+
+ [?match(ok, rpc:call(N1, ?MODULE, verify_data, [Tab, 20])) || Tab <- VTabs],
+ [?match(ok, rpc:call(N2, ?MODULE, verify_data, [Tab, 20])) || Tab <- VTabs],
+ [?match(ok, rpc:call(N3, ?MODULE, verify_data, [Tab, 20])) || Tab <- VTabs],
+
+ ?verify_mnesia(Nodes, []).
+
+
+read_during_down(doc) ->
+ ["Verify that read operation can continue to read when mnesia goes down"];
+read_during_down(suite) ->
+ [
+ dirty_read_during_down,
+ trans_read_during_down
+ ].
+
+dirty_read_during_down(suite) ->
+ [];
+dirty_read_during_down(Config) when is_list(Config) ->
+ read_during_down(dirty, Config).
+
+trans_read_during_down(suite) ->
+ [];
+trans_read_during_down(Config) when is_list(Config) ->
+ read_during_down(trans, Config).
+
+
+read_during_down(Op, Config) when is_list(Config) ->
+ Ns = [N1|TNs] = ?acquire_nodes(3, Config),
+ Tabs = [ram, disc, disco],
+
+ ?match({atomic, ok}, mnesia:create_table(ram, [{ram_copies, TNs}])),
+ ?match({atomic, ok}, mnesia:create_table(disc, [{disc_copies, TNs}])),
+ ?match({atomic, ok}, mnesia:create_table(disco, [{disc_only_copies, TNs}])),
+
+ %% Create some work for mnesia_controller when a node goes down
+ [{atomic, ok} = mnesia:create_table(list_to_atom("temp" ++ integer_to_list(N)),
+ [{ram_copies, Ns}]) || N <- lists:seq(1, 50)],
+
+ Write = fun(Tab) -> mnesia:write({Tab, key, val}) end,
+ ?match([ok,ok,ok],
+ [mnesia:sync_dirty(Write, [Tab]) || Tab <- Tabs]),
+
+ Readers = [spawn_link(N1, ?MODULE, reader, [Tab, Op]) || Tab <- Tabs],
+ [_|_] = W2R= [mnesia:table_info(Tab, where_to_read) || Tab <- Tabs],
+ ?log("W2R ~p~n", [W2R]),
+ loop_and_kill_mnesia(10, hd(W2R), Tabs),
+ [Pid ! self() || Pid <- Readers],
+ ?match([ok, ok, ok], [receive ok -> ok after 1000 -> {Pid, mnesia_lib:dist_coredump()} end || Pid <- Readers]),
+ ?verify_mnesia(Ns, []).
+
+reader(Tab, OP) ->
+ Res = case OP of
+ dirty ->
+ catch mnesia:dirty_read({Tab, key});
+ trans ->
+ Read = fun() -> mnesia:read({Tab, key}) end,
+ {_, Temp} = mnesia:transaction(Read),
+ Temp
+ end,
+ case Res of
+ [{Tab, key, val}] -> ok;
+ Else ->
+ ?error("Expected ~p Got ~p ~n", [[{Tab, key, val}], Else]),
+ erlang:error(test_failed)
+ end,
+ receive Pid ->
+ Pid ! ok
+ after 50 ->
+ reader(Tab, OP)
+ end.
+
+loop_and_kill_mnesia(0, _Node, _Tabs) -> ok;
+loop_and_kill_mnesia(N, Node, Tabs) ->
+ mnesia_test_lib:kill_mnesia([Node]),
+ timer:sleep(100),
+ ?match([], mnesia_test_lib:start_mnesia([Node], Tabs)),
+ [KN | _] = W2R= [mnesia:table_info(Tab, where_to_read) || Tab <- Tabs],
+ ?match([KN, KN,KN], W2R),
+ timer:sleep(100),
+ loop_and_kill_mnesia(N-1, KN, Tabs).
+
+mnesia_down_during_startup(doc) ->
+ ["Verify that mnesia can come back up again in a consistent state",
+ "after it has gone down during startup (with different store and",
+ "when it goes down in different situations"];
+mnesia_down_during_startup(suite) ->
+ [
+ mnesia_down_during_startup_disk_ram,
+ mnesia_down_during_startup_init_ram,
+ mnesia_down_during_startup_init_disc,
+ mnesia_down_during_startup_init_disc_only,
+ mnesia_down_during_startup_tm_ram,
+ mnesia_down_during_startup_tm_disc,
+ mnesia_down_during_startup_tm_disc_only
+ ].
+
+mnesia_down_during_startup_disk_ram(suite) -> [];
+mnesia_down_during_startup_disk_ram(Config) when is_list(Config)->
+ [Node1, Node2] = ?acquire_nodes(2, Config ++
+ [{tc_timeout, timer:minutes(2)}]),
+ Tab = down_during_startup,
+ Def = [{ram_copies, [Node2]}, {disc_copies, [Node1]}],
+
+ ?match({atomic, ok}, mnesia:create_table(Tab, Def)),
+ ?match(ok, mnesia:dirty_write({Tab, 876234, test_ok})),
+ timer:sleep(500),
+ mnesia_test_lib:kill_mnesia([Node1, Node2]),
+ timer:sleep(500),
+ mnesia_test_lib:start_mnesia([Node1, Node2], [Tab]),
+ mnesia_test_lib:kill_mnesia([Node1]),
+ timer:sleep(500),
+ ?match([], mnesia_test_lib:start_mnesia([Node1], [Tab])),
+ ?match([{Tab, 876234, test_ok}], mnesia:dirty_read({Tab,876234})),
+ ?verify_mnesia([Node1, Node2], []).
+
+mnesia_down_during_startup_init_ram(suite) -> [];
+mnesia_down_during_startup_init_ram(Config) when is_list(Config) ->
+ ?is_debug_compiled,
+ DP = {mnesia_loader, do_get_network_copy},
+ Type = ram_copies,
+ mnesia_down_during_startup2(Config, Type, DP, self()).
+
+mnesia_down_during_startup_init_disc(suite) -> [];
+mnesia_down_during_startup_init_disc(Config) when is_list(Config) ->
+ ?is_debug_compiled,
+ DP = {mnesia_loader, do_get_network_copy},
+ Type = disc_copies,
+ mnesia_down_during_startup2(Config, Type, DP, self()).
+
+mnesia_down_during_startup_init_disc_only(suite) -> [];
+mnesia_down_during_startup_init_disc_only(Config) when is_list(Config) ->
+ ?is_debug_compiled,
+ DP = {mnesia_loader, do_get_network_copy},
+ Type = disc_only_copies,
+ mnesia_down_during_startup2(Config, Type, DP, self()).
+
+mnesia_down_during_startup_tm_ram(suite) -> [];
+mnesia_down_during_startup_tm_ram(Config) when is_list(Config) ->
+ ?is_debug_compiled,
+ DP = {mnesia_tm, init},
+ Type = ram_copies,
+ mnesia_down_during_startup2(Config, Type, DP, self()).
+
+mnesia_down_during_startup_tm_disc(suite) -> [];
+mnesia_down_during_startup_tm_disc(Config) when is_list(Config) ->
+ ?is_debug_compiled,
+ DP = {mnesia_tm, init},
+ Type = disc_copies,
+ mnesia_down_during_startup2(Config, Type, DP, self()).
+
+mnesia_down_during_startup_tm_disc_only(suite) -> [];
+mnesia_down_during_startup_tm_disc_only(Config) when is_list(Config) ->
+ ?is_debug_compiled,
+ DP = {mnesia_tm, init},
+ Type = disc_only_copies,
+ mnesia_down_during_startup2(Config, Type, DP, self()).
+
+mnesia_down_during_startup2(Config, ReplicaType, Debug_Point, _Father) ->
+ ?log("TC~n mnesia_down_during_startup with type ~w and stops at ~w~n",
+ [ReplicaType, Debug_Point]),
+ Tpcb_tabs = [history,teller,account,branch],
+ Nodes = ?acquire_nodes(2, Config),
+ Node1 = hd(Nodes),
+ {success, [A]} = ?start_activities([Node1]),
+ TpcbConfig = tpcb_config(ReplicaType, 2, Nodes),
+ mnesia_tpcb:init(TpcbConfig),
+ A ! fun () -> mnesia_tpcb:run(TpcbConfig) end,
+ ?match_receive(timeout),
+ timer:sleep(timer:seconds(10)), % Let tpcb run for a while
+ mnesia_tpcb:stop(),
+ ?match(ok, mnesia_tpcb:verify_tabs()),
+ mnesia_test_lib:kill_mnesia([Node1]),
+ timer:sleep(timer:seconds(2)),
+ Self = self(),
+ TestFun = fun(_MnesiaEnv, _EvalEnv) ->
+ ?deactivate_debug_fun(Debug_Point),
+ Self ! fun_done,
+ spawn(mnesia_test_lib, kill_mnesia, [[Node1]])
+ end,
+ ?activate_debug_fun(Debug_Point, TestFun, []), % Kill when debug has been reached
+ mnesia:start(),
+ Res = receive fun_done -> ok after timer:minutes(3) -> timeout end, % Wait till it's killed
+ ?match(ok, Res),
+ ?match(ok, timer:sleep(timer:seconds(2))), % Wait a while, at least till it dies;
+ ?match([], mnesia_test_lib:start_mnesia([Node1], Tpcb_tabs)),
+ ?match(ok, mnesia_tpcb:verify_tabs()), % Verify it
+ ?verify_mnesia(Nodes, []).
+
+
+with_checkpoint(doc) ->
+ ["Restart mnesia with checkpoint"];
+with_checkpoint(suite) ->
+ [with_checkpoint_same, with_checkpoint_other].
+
+with_checkpoint_same(suite) -> [];
+with_checkpoint_same(Config) when is_list(Config) ->
+ with_checkpoint(Config, same).
+
+with_checkpoint_other(suite) -> [];
+with_checkpoint_other(Config) when is_list(Config) ->
+ with_checkpoint(Config, other).
+
+with_checkpoint(Config, Type) when is_list(Config) ->
+ Nodes = [Node1, Node2] = ?acquire_nodes(2, Config),
+ Kill = case Type of
+ same -> %% Node1 is the one used for creating the checkpoint
+ Node1; %% and which we bring down
+ other ->
+ Node2 %% Here we bring node2 down..
+ end,
+
+ ?match({atomic, ok}, mnesia:create_table(ram, [{ram_copies, Nodes}])),
+ ?match({atomic, ok}, mnesia:create_table(disc, [{disc_copies, Nodes}])),
+ ?match({atomic, ok}, mnesia:create_table(disco, [{disc_only_copies, Nodes}])),
+ Tabs = [ram, disc, disco],
+
+ ?match({ok, sune, _}, mnesia:activate_checkpoint([{name, sune},
+ {max, mnesia:system_info(tables)},
+ {ram_overrides_dump, true}])),
+
+ ?match([], check_retainers(sune, Nodes)),
+
+ ?match(ok, mnesia:deactivate_checkpoint(sune)),
+ ?match([], check_chkp(Nodes)),
+
+ timer:sleep(500), %% Just to help debugging the io:formats now comes in the
+ %% correct order... :-)
+
+ ?match({ok, sune, _}, mnesia:activate_checkpoint([{name, sune},
+ {max, mnesia:system_info(tables)},
+ {ram_overrides_dump, true}])),
+
+ [[mnesia:dirty_write({Tab,Key,Key}) || Key <- lists:seq(1,10)] || Tab <- Tabs],
+
+ mnesia_test_lib:kill_mnesia([Kill]),
+ timer:sleep(100),
+ mnesia_test_lib:start_mnesia([Kill], Tabs),
+ io:format("Mnesia on ~p started~n", [Kill]),
+ ?match([], check_retainers(sune, Nodes)),
+ ?match(ok, mnesia:deactivate_checkpoint(sune)),
+ ?match([], check_chkp(Nodes)),
+
+ case Kill of
+ Node1 ->
+ ignore;
+ Node2 ->
+ mnesia_test_lib:kill_mnesia([Kill]),
+ timer:sleep(500), %% Just to help debugging
+ ?match({ok, sune, _}, mnesia:activate_checkpoint([{name, sune},
+ {max, mnesia:system_info(tables)},
+ {ram_overrides_dump, true}])),
+
+ [[mnesia:dirty_write({Tab,Key,Key+2}) || Key <- lists:seq(1,10)] ||
+ Tab <- Tabs],
+
+ mnesia_test_lib:start_mnesia([Kill], Tabs),
+ io:format("Mnesia on ~p started ~n", [Kill]),
+ ?match([], check_retainers(sune, Nodes)),
+ ?match(ok, mnesia:deactivate_checkpoint(sune)),
+ ?match([], check_chkp(Nodes)),
+ ok
+ end,
+ ?verify_mnesia(Nodes, []).
+
+check_chkp(Nodes) ->
+ {Good, Bad} = rpc:multicall(Nodes, ?MODULE, check, []),
+ lists:flatten(Good ++ Bad).
+
+check() ->
+ [PCP] = ets:match_object(mnesia_gvar, {pending_checkpoint_pids, '_'}),
+ [PC] = ets:match_object(mnesia_gvar, {pending_checkpoints, '_'}),
+ [CPN] = ets:match_object(mnesia_gvar, {checkpoints, '_'}),
+ F = lists:filter(fun({_, []}) -> false; (_W) -> true end,
+ [PCP,PC,CPN]),
+ CPP = ets:match_object(mnesia_gvar, {{checkpoint, '_'}, '_'}),
+ Rt = ets:match_object(mnesia_gvar, {{'_', {retainer, '_'}}, '_'}),
+ F ++ CPP ++ Rt.
+
+
+check_retainers(CHP, Nodes) ->
+ {[R1,R2], []} = rpc:multicall(Nodes, ?MODULE, get_all_retainers, [CHP]),
+ (R1 -- R2) ++ (R2 -- R1).
+
+get_all_retainers(CHP) ->
+ Tabs = mnesia:system_info(local_tables),
+ Iter = fun(Tab) ->
+ {ok, Res} =
+ mnesia_checkpoint:iterate(CHP, Tab, fun(R, A) -> [R|A] end, [],
+ retainer, checkpoint),
+%% io:format("Retainer content ~w ~n", [Res]),
+ Res
+ end,
+ Elements = [Iter(Tab) || Tab <- Tabs],
+ lists:sort(lists:flatten(Elements)).
+
+delete_during_start(doc) ->
+ ["Test that tables can be delete during start, hopefully with tables"
+ " in the loader queue or soon to be"];
+delete_during_start(suite) -> [];
+delete_during_start(Config) when is_list(Config) ->
+ [N1, N2, N3] = Nodes = ?acquire_nodes(3, Config),
+ Tabs = [list_to_atom("tab" ++ integer_to_list(I)) || I <- lists:seq(1, 30)],
+ ?match({atomic, ok}, mnesia:change_table_copy_type(schema, N2, ram_copies)),
+ ?match({atomic, ok}, mnesia:change_table_copy_type(schema, N3, ram_copies)),
+
+ [?match({atomic, ok},mnesia:create_table(Tab, [{ram_copies,Nodes}])) || Tab <- Tabs],
+ lists:foldl(fun(Tab, I) ->
+ ?match({atomic, ok},
+ mnesia:change_table_load_order(Tab,I)),
+ I+1
+ end, 1, Tabs),
+ mnesia_test_lib:kill_mnesia([N2,N3]),
+%% timer:sleep(500),
+ ?match({[ok,ok],[]}, rpc:multicall([N2,N3], mnesia,start,
+ [[{extra_db_nodes,[N1]}]])),
+ [Tab1,Tab2,Tab3|_] = Tabs,
+ ?match({atomic, ok}, mnesia:delete_table(Tab1)),
+ ?match({atomic, ok}, mnesia:delete_table(Tab2)),
+
+ ?log("W4T ~p~n", [rpc:multicall([N2,N3], mnesia, wait_for_tables, [[Tab1,Tab2,Tab3],1])]),
+
+ Remain = Tabs--[Tab1,Tab2],
+ ?match(ok, rpc:call(N2, mnesia, wait_for_tables, [Remain,10000])),
+ ?match(ok, rpc:call(N3, mnesia, wait_for_tables, [Remain,10000])),
+
+ ?match(ok, rpc:call(N2, ?MODULE, verify_where2read, [Remain])),
+ ?match(ok, rpc:call(N3, ?MODULE, verify_where2read, [Remain])),
+
+ ?verify_mnesia(Nodes, []).
+
+verify_where2read([Tab|Tabs]) ->
+ true = (node() == mnesia:table_info(Tab,where_to_read)),
+ verify_where2read(Tabs);
+verify_where2read([]) -> ok.
+
+
+%%-------------------------------------------------------------------------------------------
+explicit_stop(doc) ->
+ ["Stop Mnesia in different situations"];
+explicit_stop(suite) ->
+ [explicit_stop_during_snmp].
+%% This is a bad implementation, but at least gives a indication if something is wrong
+explicit_stop_during_snmp(suite) -> [];
+explicit_stop_during_snmp(Config) when is_list(Config) ->
+ Nodes = ?acquire_nodes(2, Config),
+ [Node1, Node2] = Nodes,
+ Tab = snmp_tab,
+ Def = [{attributes, [key, value]},
+ {snmp, [{key, integer}]},
+ {mnesia_test_lib:storage_type(disc_copies, Config),
+ [Node1, Node2]}],
+ ?match({atomic, ok}, mnesia:create_table(Tab, Def)),
+ ?match({atomic, ok}, mnesia:transaction(fun() -> mnesia:write({Tab, 1, 1}) end)),
+
+ Do_trans_Pid1 = spawn_link(Node2, ?MODULE, do_trans_loop, [Tab, self()]),
+ Do_trans_Pid2 = spawn_link(?MODULE, do_trans_loop, [Tab, self()]),
+ Start_stop_Pid = spawn_link(?MODULE, start_stop, [Node1, 10, self()]),
+ receive
+ test_done ->
+ ok
+ after timer:minutes(5) ->
+ ?error("test case time out~n", [])
+ end,
+ ?verify_mnesia(Nodes, []),
+ exit(Do_trans_Pid1, kill),
+ exit(Do_trans_Pid2, kill),
+ exit(Start_stop_Pid, kill),
+ ok.
+
+do_trans_loop(Tab, Father) ->
+ %% Do not trap exit
+ do_trans_loop2(Tab, Father).
+do_trans_loop2(Tab, Father) ->
+ Trans =
+ fun() ->
+ [{Tab, 1, Val}] = mnesia:read({Tab, 1}),
+ mnesia:write({Tab, 1, Val + 1})
+ end,
+ case mnesia:transaction(Trans) of
+ {atomic, ok} ->
+ timer:sleep(200),
+ do_trans_loop2(Tab, Father);
+ {aborted, {node_not_running, N}} when N == node() ->
+ timer:sleep(200),
+ do_trans_loop2(Tab, Father);
+ {aborted, {no_exists, Tab}} ->
+ timer:sleep(200),
+ do_trans_loop2(Tab, Father);
+ Else ->
+ ?error("Transaction failed: ~p ~n", [Else]),
+ Father ! test_done,
+ exit(shutdown)
+ end.
+
+start_stop(_Node1, 0, Father) ->
+ Father ! test_done,
+ exit(shutdown);
+start_stop(Node1, N, Father) when N > 0->
+ timer:sleep(timer:seconds(5)),
+ ?match(stopped, rpc:call(Node1, mnesia, stop, [])),
+ timer:sleep(timer:seconds(2)),
+ ?match([], mnesia_test_lib:start_mnesia([Node1])),
+ start_stop(Node1, N-1, Father).
+
+coord_dies(suite) -> [];
+coord_dies(doc) -> [""];
+coord_dies(Config) when is_list(Config) ->
+ Nodes = [N1, N2] = ?acquire_nodes(2, Config),
+ ?match({atomic, ok}, mnesia:create_table(tab1, [{ram_copies, Nodes}])),
+ ?match({atomic, ok}, mnesia:create_table(tab2, [{ram_copies, [N1]}])),
+ ?match({atomic, ok}, mnesia:create_table(tab3, [{ram_copies, [N2]}])),
+ Tester = self(),
+
+ U1 = fun(Tab) ->
+ [{Tab,key,Val}] = mnesia:read(Tab,key,write),
+ mnesia:write({Tab,key, Val+1}),
+ Tester ! {self(),continue},
+ receive
+ continue -> exit(crash)
+ end
+ end,
+ U2 = fun(Tab) ->
+ [{Tab,key,Val}] = mnesia:read(Tab,key,write),
+ mnesia:write({Tab,key, Val+1}),
+ mnesia:transaction(U1, [Tab])
+ end,
+ [mnesia:dirty_write(Tab,{Tab,key,0}) || Tab <- [tab1,tab2,tab3]],
+ Pid1 = spawn(fun() -> mnesia:transaction(U2, [tab1]) end),
+ Pid2 = spawn(fun() -> mnesia:transaction(U2, [tab2]) end),
+ Pid3 = spawn(fun() -> mnesia:transaction(U2, [tab3]) end),
+ [receive {Pid,continue} -> ok end || Pid <- [Pid1,Pid2,Pid3]],
+ Pid1 ! continue, Pid2 ! continue, Pid3 ! continue,
+ ?match({atomic,[{_,key,1}]}, mnesia:transaction(fun() -> mnesia:read({tab1,key}) end)),
+ ?match({atomic,[{_,key,1}]}, mnesia:transaction(fun() -> mnesia:read({tab2,key}) end)),
+ ?match({atomic,[{_,key,1}]}, mnesia:transaction(fun() -> mnesia:read({tab3,key}) end)),
+
+ Pid4 = spawn(fun() -> mnesia:transaction(U2, [tab1]) end),
+ Pid5 = spawn(fun() -> mnesia:transaction(U2, [tab2]) end),
+ Pid6 = spawn(fun() -> mnesia:transaction(U2, [tab3]) end),
+ erlang:monitor(process, Pid4),erlang:monitor(process, Pid5),erlang:monitor(process, Pid6),
+
+ [receive {Pid,continue} -> ok end || Pid <- [Pid4,Pid5,Pid6]],
+ exit(Pid4,crash),
+ ?match_receive({'DOWN',_,_,Pid4, _}),
+ ?match({atomic,[{_,key,1}]}, mnesia:transaction(fun() -> mnesia:read({tab1,key}) end)),
+ exit(Pid5,crash),
+ ?match_receive({'DOWN',_,_,Pid5, _}),
+ ?match({atomic,[{_,key,1}]}, mnesia:transaction(fun() -> mnesia:read({tab2,key}) end)),
+ exit(Pid6,crash),
+ ?match_receive({'DOWN',_,_,Pid6, _}),
+ ?match({atomic,[{_,key,1}]}, mnesia:transaction(fun() -> mnesia:read({tab3,key}) end)),
+
+ ?verify_mnesia(Nodes, []).
+
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+sym_trans(doc) ->
+ ["Recovery of symmetrical transactions in a couple of different",
+ "situations; when coordinator or participant or node dies"];
+
+sym_trans(suite) ->
+ [sym_trans_before_commit_kill_coord_node, %% coordinator node dies
+ sym_trans_before_commit_kill_coord_pid, %% coordinator process dies
+ sym_trans_before_commit_kill_part_after_ask, %% participating node dies
+ sym_trans_before_commit_kill_part_before_ask,
+ sym_trans_after_commit_kill_coord_node,
+ sym_trans_after_commit_kill_coord_pid,
+ sym_trans_after_commit_kill_part_after_ask,
+ sym_trans_after_commit_kill_part_do_commit_pre,
+ sym_trans_after_commit_kill_part_do_commit_post].
+
+%kill_after_debug_point(Config, TestCase, {Debug_node, Debug_Point}, TransFun, Tab)
+
+sym_trans_before_commit_kill_coord_node(suite) -> [];
+sym_trans_before_commit_kill_coord_node(Config) when is_list(Config) ->
+ ?is_debug_compiled,
+ Nodes = ?acquire_nodes(3, Config ++ [{tc_timeout, timer:minutes(2)}]),
+ [Coord, Part1, Part2] = Nodes,
+ Tab = sym_trans_before_commit_kill_coord,
+ Def = [{attributes, [key, value]}, {ram_copies, [Part2]},{disc_copies, [Coord, Part1]}],
+ kill_after_debug_point(Coord, {Coord, {mnesia_tm, multi_commit_sym}},
+ do_sym_trans, [{Tab, Def}], Nodes).
+
+sym_trans_before_commit_kill_coord_pid(suite) -> [];
+sym_trans_before_commit_kill_coord_pid(Config) when is_list(Config) ->
+ ?is_debug_compiled,
+ Nodes = ?acquire_nodes(3, Config ++ [{tc_timeout, timer:minutes(2)}]),
+ [Coord, Part1, Part2] = Nodes,
+ Tab = sym_trans_before_commit_kill_coord,
+ Def = [{attributes, [key, value]},{ram_copies, [Part2]},{disc_copies, [Coord, Part1]}],
+ kill_after_debug_point(coord_pid, {Coord, {mnesia_tm, multi_commit_sym}},
+ do_sym_trans, [{Tab, Def}], Nodes).
+
+sym_trans_before_commit_kill_part_after_ask(suite) -> [];
+sym_trans_before_commit_kill_part_after_ask(Config) when is_list(Config) ->
+ ?is_debug_compiled,
+ Nodes = ?acquire_nodes(3, Config ++ [{tc_timeout, timer:minutes(2)}]),
+ [Coord, Part1, Part2] = Nodes,
+ Tab = sym_trans_before_commit_kill_part_after_ask,
+ Def = [{attributes, [key, value]},{ram_copies, [Part2]},{disc_copies, [Coord, Part1]}],
+ kill_after_debug_point(Part1, {Coord, {mnesia_tm, multi_commit_sym}},
+ do_sym_trans, [{Tab, Def}], Nodes).
+
+sym_trans_before_commit_kill_part_before_ask(suite) -> [];
+sym_trans_before_commit_kill_part_before_ask(Config) when is_list(Config) ->
+ ?is_debug_compiled,
+ Nodes = ?acquire_nodes(3, Config ++ [{tc_timeout, timer:minutes(2)}]),
+ [Coord, Part1, Part2] = Nodes,
+ Tab = sym_trans_before_commit_kill_part_before_ask,
+ Def = [{attributes, [key, value]},{ram_copies, [Part2]},{disc_copies, [Coord, Part1]}],
+ kill_after_debug_point(Part1, {Part1, {mnesia_tm, doit_ask_commit}},
+ do_sym_trans, [{Tab, Def}], Nodes).
+
+sym_trans_after_commit_kill_coord_node(suite) -> [];
+sym_trans_after_commit_kill_coord_node(Config) when is_list(Config) ->
+ ?is_debug_compiled,
+ Nodes = ?acquire_nodes(3, Config ++ [{tc_timeout, timer:minutes(2)}]),
+ [Coord, Part1, Part2] = Nodes,
+ Tab = sym_trans_after_commit_kill_coord,
+ Def = [{attributes, [key, value]},{ram_copies, [Part2]},{disc_copies, [Coord, Part1]}],
+ kill_after_debug_point(Coord, {Coord, {mnesia_tm, multi_commit_sym, post}},
+ do_sym_trans, [{Tab, Def}], Nodes).
+
+sym_trans_after_commit_kill_coord_pid(suite) -> [];
+sym_trans_after_commit_kill_coord_pid(Config) when is_list(Config) ->
+ ?is_debug_compiled,
+ Nodes = ?acquire_nodes(3, Config ++ [{tc_timeout, timer:minutes(2)}]),
+ [Coord, Part1, Part2] = Nodes,
+ Tab = sym_trans_after_commit_kill_coord,
+ Def = [{attributes, [key, value]},{ram_copies, [Part2]},{disc_copies, [Coord, Part1]}],
+ kill_after_debug_point(coord_pid, {Coord, {mnesia_tm, multi_commit_sym, post}},
+ do_sym_trans, [{Tab,Def}], Nodes).
+
+sym_trans_after_commit_kill_part_after_ask(suite) -> [];
+sym_trans_after_commit_kill_part_after_ask(Config) when is_list(Config) ->
+ ?is_debug_compiled,
+ Nodes = ?acquire_nodes(3, Config ++ [{tc_timeout, timer:minutes(2)}]),
+ [Coord, Part1, Part2] = Nodes,
+ Tab = sym_trans_after_commit_kill_part_after_ask,
+ Def = [{attributes, [key, value]},{ram_copies, [Part2]},{disc_copies, [Coord, Part1]}],
+ kill_after_debug_point(Part1, {Coord, {mnesia_tm, multi_commit_sym, post}},
+ do_sym_trans, [{Tab, Def}], Nodes).
+
+sym_trans_after_commit_kill_part_do_commit_pre(suite) -> [];
+sym_trans_after_commit_kill_part_do_commit_pre(Config) when is_list(Config) ->
+ ?is_debug_compiled,
+ Nodes = ?acquire_nodes(3, Config ++ [{tc_timeout, timer:minutes(2)}]),
+ [Coord, Part1, Part2] = Nodes,
+ Tab = sym_trans_after_commit_kill_part_do_commit_pre,
+ Def = [{attributes, [key, value]},{ram_copies, [Part2]},{disc_copies, [Coord, Part1]}],
+ TransFun = do_sym_trans,
+ kill_after_debug_point(Part1, {Part1, {mnesia_tm, do_commit, pre}},
+ TransFun, [{Tab, Def}], Nodes).
+
+sym_trans_after_commit_kill_part_do_commit_post(suite) -> [];
+sym_trans_after_commit_kill_part_do_commit_post(Config) when is_list(Config) ->
+ ?is_debug_compiled,
+ Nodes = ?acquire_nodes(3, Config ++ [{tc_timeout, timer:minutes(2)}]),
+ [Coord, Part1, Part2] = Nodes,
+ Tab = sym_trans_after_commit_kill_part_do_commit_post,
+ Def = [{attributes, [key, value]},{ram_copies, [Part2]},{disc_copies, [Coord, Part1]}],
+ TransFun = do_sym_trans,
+ kill_after_debug_point(Part1, {Part1, {mnesia_tm, do_commit, post}},
+ TransFun, [{Tab, Def}], Nodes).
+
+do_sym_trans([Tab], _Fahter) ->
+ ?dl("Starting SYM_TRANS with active debug fun ", []),
+ Trans = fun() ->
+ [{_,_,Val}] = mnesia:read({Tab, 1}),
+ mnesia:write({Tab, 1, Val+1})
+ end,
+ Res = mnesia:transaction(Trans),
+ case Res of
+ {atomic, ok} -> ok;
+ {aborted, _Reason} -> ok;
+ Else -> ?error("Wrong output from mensia:transaction(FUN):~n ~p~n",
+ [Else])
+ end,
+ ?dl("SYM_TRANSACTION done: ~p (deactiv dbgfun) ", [Res]),
+ ok.
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+sync_dirty(doc) ->
+ ["Verify recovery of synchronously operations in a couple of different",
+ "situations"];
+sync_dirty(suite) ->
+ [sync_dirty_pre_kill_part,
+ sync_dirty_pre_kill_coord_node,
+ sync_dirty_pre_kill_coord_pid,
+ sync_dirty_post_kill_part,
+ sync_dirty_post_kill_coord_node,
+ sync_dirty_post_kill_coord_pid
+ ].
+
+sync_dirty_pre_kill_part(suite) -> [];
+sync_dirty_pre_kill_part(Config) when is_list(Config) ->
+ ?is_debug_compiled,
+ Nodes = ?acquire_nodes(3, Config ++ [{tc_timeout, timer:minutes(2)}]),
+ [Coord, Part1, Part2] = Nodes,
+ Tab = sync_dirty_pre,
+ Def = [{attributes, [key, value]},{ram_copies, [Part2]},{disc_copies, [Coord, Part1]}],
+ TransFun = do_sync_dirty,
+ kill_after_debug_point(Part1, {Part1, {mnesia_tm, sync_dirty, pre}},
+ TransFun, [{Tab, Def}], Nodes).
+
+sync_dirty_pre_kill_coord_node(suite) -> [];
+sync_dirty_pre_kill_coord_node(Config) when is_list(Config) ->
+ ?is_debug_compiled,
+ Nodes = ?acquire_nodes(3, Config ++ [{tc_timeout, timer:minutes(2)}]),
+ [Coord, Part1, Part2] = Nodes,
+ Tab = sync_dirty_pre,
+ Def = [{attributes, [key, value]},{ram_copies, [Part2]},{disc_copies, [Coord, Part1]}],
+ TransFun = do_sync_dirty,
+ kill_after_debug_point(Coord, {Part1, {mnesia_tm, sync_dirty, pre}},
+ TransFun, [{Tab, Def}], Nodes).
+
+sync_dirty_pre_kill_coord_pid(suite) -> [];
+sync_dirty_pre_kill_coord_pid(Config) when is_list(Config) ->
+ ?is_debug_compiled,
+ Nodes = ?acquire_nodes(3, Config ++ [{tc_timeout, timer:minutes(2)}]),
+ [Coord, Part1, Part2] = Nodes,
+ Tab = sync_dirty_pre,
+ Def = [{attributes, [key, value]},{ram_copies, [Part2]},{disc_copies, [Coord, Part1]}],
+ TransFun = do_sync_dirty,
+ kill_after_debug_point(coord_pid, {Part1, {mnesia_tm, sync_dirty, pre}},
+ TransFun, [{Tab, Def}], Nodes).
+
+sync_dirty_post_kill_part(suite) -> [];
+sync_dirty_post_kill_part(Config) when is_list(Config) ->
+ ?is_debug_compiled,
+ Nodes = ?acquire_nodes(3, Config ++ [{tc_timeout, timer:minutes(2)}]),
+ [Coord, Part1, Part2] = Nodes,
+ Tab = sync_dirty_post,
+ Def = [{attributes, [key, value]},{ram_copies, [Part2]},{disc_copies, [Coord, Part1]}],
+ TransFun = do_sync_dirty,
+ kill_after_debug_point(Part1, {Part1, {mnesia_tm, sync_dirty, post}},
+ TransFun, [{Tab, Def}], Nodes).
+
+sync_dirty_post_kill_coord_node(suite) -> [];
+sync_dirty_post_kill_coord_node(Config) when is_list(Config) ->
+ ?is_debug_compiled,
+ Nodes = ?acquire_nodes(3, Config ++ [{tc_timeout, timer:minutes(2)}]),
+ [Coord, Part1, Part2] = Nodes,
+ Tab = sync_dirty_post,
+ Def = [{attributes, [key, value]},{ram_copies, [Part2]},{disc_copies, [Coord, Part1]}],
+ TransFun = do_sync_dirty,
+ kill_after_debug_point(Coord, {Part1, {mnesia_tm, sync_dirty, post}},
+ TransFun, [{Tab, Def}], Nodes).
+
+sync_dirty_post_kill_coord_pid(suite) -> [];
+sync_dirty_post_kill_coord_pid(Config) when is_list(Config) ->
+ ?is_debug_compiled,
+ Nodes = ?acquire_nodes(3, Config ++ [{tc_timeout, timer:minutes(2)}]),
+ [Coord, Part1, Part2] = Nodes,
+ Tab = sync_dirty_post,
+ Def = [{attributes, [key, value]},{ram_copies, [Part2]},{disc_copies, [Coord, Part1]}],
+ TransFun = do_sync_dirty,
+ kill_after_debug_point(coord_pid, {Part1, {mnesia_tm, sync_dirty, post}},
+ TransFun, [{Tab, Def}], Nodes).
+
+do_sync_dirty([Tab], _Father) ->
+ ?dl("Starting SYNC_DIRTY", []),
+ SYNC = fun() ->
+ [{_,_,Val}] = mnesia:read({Tab, 1}),
+ mnesia:write({Tab, 1, Val+1})
+ end,
+ {_, Res} = ?match(ok, mnesia:sync_dirty(SYNC)),
+ ?dl("SYNC_DIRTY done: ~p ", [Res]),
+ ok.
+
+async_dirty(doc) ->
+ ["Verify recovery of asynchronously dirty operations in a couple of different",
+ "situations"];
+async_dirty(suite) ->
+ [async_dirty_pre_kill_part,
+ async_dirty_pre_kill_coord_node,
+ async_dirty_pre_kill_coord_pid,
+ async_dirty_post_kill_part,
+ async_dirty_post_kill_coord_node,
+ async_dirty_post_kill_coord_pid].
+
+async_dirty_pre_kill_part(suite) -> [];
+async_dirty_pre_kill_part(Config) when is_list(Config) ->
+ ?is_debug_compiled,
+ Nodes = ?acquire_nodes(3, Config ++ [{tc_timeout, timer:minutes(2)}]),
+ [Coord, Part1, Part2] = Nodes,
+ Tab = async_dirty_pre,
+ Def = [{attributes, [key, value]},{ram_copies, [Part2]},{disc_copies, [Coord, Part1]}],
+ TransFun = do_async_dirty,
+ kill_after_debug_point(Part1, {Part1, {mnesia_tm, async_dirty, pre}},
+ TransFun, [{Tab, Def}], Nodes).
+
+async_dirty_pre_kill_coord_node(suite) -> [];
+async_dirty_pre_kill_coord_node(Config) when is_list(Config) ->
+ ?is_debug_compiled,
+ Nodes = ?acquire_nodes(3, Config ++ [{tc_timeout, timer:minutes(2)}]),
+ [Coord, Part1, Part2] = Nodes,
+ Tab = async_dirty_pre,
+ Def = [{attributes, [key, value]},{ram_copies, [Part2]},{disc_copies, [Coord, Part1]}],
+ TransFun = do_async_dirty,
+ kill_after_debug_point(Coord, {Part1, {mnesia_tm, async_dirty, pre}},
+ TransFun, [{Tab, Def}], Nodes).
+
+async_dirty_pre_kill_coord_pid(suite) -> [];
+async_dirty_pre_kill_coord_pid(Config) when is_list(Config) ->
+ ?is_debug_compiled,
+ Nodes = ?acquire_nodes(3, Config ++ [{tc_timeout, timer:minutes(2)}]),
+ [Coord, Part1, Part2] = Nodes,
+ Tab = async_dirty_pre,
+ Def = [{attributes, [key, value]},{ram_copies, [Part2]},{disc_copies, [Coord, Part1]}],
+ TransFun = do_async_dirty,
+ kill_after_debug_point(coord_pid, {Part1, {mnesia_tm, async_dirty, pre}},
+ TransFun, [{Tab, Def}], Nodes).
+
+async_dirty_post_kill_part(suite) -> [];
+async_dirty_post_kill_part(Config) when is_list(Config) ->
+ ?is_debug_compiled,
+ Nodes = ?acquire_nodes(3, Config ++ [{tc_timeout, timer:minutes(2)}]),
+ [Coord, Part1, Part2] = Nodes,
+ Tab = async_dirty_post,
+ Def = [{attributes, [key, value]},{ram_copies, [Part2]},{disc_copies, [Coord, Part1]}],
+ TransFun = do_async_dirty,
+ kill_after_debug_point(Part1, {Part1, {mnesia_tm, async_dirty, post}},
+ TransFun, [{Tab, Def}], Nodes).
+
+async_dirty_post_kill_coord_node(suite) -> [];
+async_dirty_post_kill_coord_node(Config) when is_list(Config) ->
+ ?is_debug_compiled,
+ Nodes = ?acquire_nodes(3, Config ++ [{tc_timeout, timer:minutes(2)}]),
+ [Coord, Part1, Part2] = Nodes,
+ Tab = async_dirty_post,
+ Def = [{attributes, [key, value]},{ram_copies, [Part2]},{disc_copies, [Coord, Part1]}],
+ TransFun = do_async_dirty,
+ kill_after_debug_point(Coord, {Part1, {mnesia_tm, async_dirty, post}},
+ TransFun, [{Tab, Def}], Nodes).
+
+async_dirty_post_kill_coord_pid(suite) -> [];
+async_dirty_post_kill_coord_pid(Config) when is_list(Config) ->
+ ?is_debug_compiled,
+ Nodes = ?acquire_nodes(3, Config ++ [{tc_timeout, timer:minutes(2)}]),
+ [Coord, Part1, Part2] = Nodes,
+ Tab = async_dirty_post,
+ Def = [{attributes, [key, value]},{ram_copies, [Part2]},{disc_copies, [Coord, Part1]}],
+ TransFun = do_async_dirty,
+ kill_after_debug_point(coord_pid, {Part1, {mnesia_tm, async_dirty, post}},
+ TransFun, [{Tab, Def}], Nodes).
+
+do_async_dirty([Tab], _Fahter) ->
+ ?dl("Starting ASYNC", []),
+ ASYNC = fun() ->
+ [{_,_,Val}] = mnesia:read({Tab, 1}),
+ mnesia:write({Tab, 1, Val+1})
+ end,
+ {_, Res} = ?match(ok, mnesia:async_dirty(ASYNC)),
+ ?dl("ASYNC done: ~p ", [Res]),
+ ok.
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+asym_trans(doc) ->
+ ["Recovery of asymmetrical transactions in a couple of different",
+ "situations, currently the error cases are not covered, i.e. ",
+ "not tested are the situations when we kill mnesia or a process",
+ "during a recovery"];
+asym_trans(suite) ->
+ [
+ asym_trans_kill_part_ask,
+ asym_trans_kill_part_commit_vote,
+ asym_trans_kill_part_pre_commit,
+ asym_trans_kill_part_log_commit,
+ asym_trans_kill_part_do_commit,
+ asym_trans_kill_coord_got_votes,
+ asym_trans_kill_coord_pid_got_votes,
+ asym_trans_kill_coord_log_commit_rec,
+ asym_trans_kill_coord_pid_log_commit_rec,
+ asym_trans_kill_coord_log_commit_dec,
+ asym_trans_kill_coord_pid_log_commit_dec,
+ asym_trans_kill_coord_rec_acc_pre_commit_log_commit,
+ asym_trans_kill_coord_pid_rec_acc_pre_commit_log_commit,
+ asym_trans_kill_coord_rec_acc_pre_commit_done_commit,
+ asym_trans_kill_coord_pid_rec_acc_pre_commit_done_commit
+ ].
+
+asym_trans_kill_part_ask(suite) -> [];
+asym_trans_kill_part_ask(Config) when is_list(Config) ->
+ ?is_debug_compiled,
+ Nodes = ?acquire_nodes(3, Config ++ [{tc_timeout, timer:minutes(2)}]),
+ [Coord, Part1, Part2] = Nodes,
+ Tab1 = {asym1, [{ram_copies, [Part2]}, {disc_copies, [Coord]}]},
+ Tab2 = {asym2, [{ram_copies, [Coord]}, {disc_copies, [Part1]}]},
+ TransFun = do_asym_trans,
+ kill_after_debug_point(Part1, {Part1, {mnesia_tm, doit_ask_commit}},
+ TransFun, [Tab1, Tab2], Nodes).
+
+asym_trans_kill_part_commit_vote(suite) -> [];
+asym_trans_kill_part_commit_vote(Config) when is_list(Config) ->
+ ?is_debug_compiled,
+ Nodes = ?acquire_nodes(3, Config ++ [{tc_timeout, timer:minutes(2)}]),
+ [Coord, Part1, Part2] = Nodes,
+ Tab1 = {asym1, [{ram_copies, [Part2]}, {disc_copies, [Coord]}]},
+ Tab2 = {asym2, [{ram_copies, [Coord]}, {disc_copies, [Part1]}]},
+ TransFun = do_asym_trans,
+ kill_after_debug_point(Part1, {Part1, {mnesia_tm, commit_participant, vote_yes}},
+ TransFun, [Tab1, Tab2], Nodes).
+
+asym_trans_kill_part_pre_commit(suite) -> [];
+asym_trans_kill_part_pre_commit(Config) when is_list(Config) ->
+ ?is_debug_compiled,
+ Nodes = ?acquire_nodes(3, Config ++ [{tc_timeout, timer:minutes(2)}]),
+ [Coord, Part1, Part2] = Nodes,
+ Tab1 = {asym1, [{ram_copies, [Part2]}, {disc_copies, [Coord]}]},
+ Tab2 = {asym2, [{ram_copies, [Coord]}, {disc_copies, [Part1]}]},
+ TransFun = do_asym_trans,
+ kill_after_debug_point(Part1, {Part1, {mnesia_tm, commit_participant, pre_commit}},
+ TransFun, [Tab1, Tab2], Nodes).
+
+asym_trans_kill_part_log_commit(suite) -> [];
+asym_trans_kill_part_log_commit(Config) when is_list(Config) ->
+ ?is_debug_compiled,
+ Nodes = ?acquire_nodes(3, Config ++ [{tc_timeout, timer:minutes(2)}]),
+ [Coord, Part1, Part2] = Nodes,
+ Tab1 = {asym1, [{ram_copies, [Part2]}, {disc_copies, [Coord]}]},
+ Tab2 = {asym2, [{ram_copies, [Coord]}, {disc_copies, [Part1]}]},
+ TransFun = do_asym_trans,
+ kill_after_debug_point(Part1, {Part1, {mnesia_tm, commit_participant, log_commit}},
+ TransFun, [Tab1, Tab2], Nodes).
+
+asym_trans_kill_part_do_commit(suite) -> [];
+asym_trans_kill_part_do_commit(Config) when is_list(Config) ->
+ ?is_debug_compiled,
+ Nodes = ?acquire_nodes(3, Config ++ [{tc_timeout, timer:minutes(2)}]),
+ [Coord, Part1, Part2] = Nodes,
+ Tab1 = {asym1, [{ram_copies, [Part2]}, {disc_copies, [Coord]}]},
+ Tab2 = {asym2, [{ram_copies, [Coord]}, {disc_copies, [Part1]}]},
+ TransFun = do_asym_trans,
+ kill_after_debug_point(Part1, {Part1, {mnesia_tm, commit_participant, do_commit}},
+ TransFun, [Tab1, Tab2], Nodes).
+
+asym_trans_kill_coord_got_votes(suite) -> [];
+asym_trans_kill_coord_got_votes(Config) when is_list(Config) ->
+ ?is_debug_compiled,
+ Nodes = ?acquire_nodes(3, Config ++ [{tc_timeout, timer:minutes(2)}]),
+ [Coord, Part1, Part2] = Nodes,
+ Tab1 = {asym1, [{ram_copies, [Part2]}, {disc_copies, [Coord]}]},
+ Tab2 = {asym2, [{ram_copies, [Coord]}, {disc_copies, [Part1]}]},
+ TransFun = do_asym_trans,
+ kill_after_debug_point(Coord, {Coord, {mnesia_tm, multi_commit_asym_got_votes}},
+ TransFun, [Tab1, Tab2], Nodes).
+
+asym_trans_kill_coord_pid_got_votes(suite) -> [];
+asym_trans_kill_coord_pid_got_votes(Config) when is_list(Config) ->
+ ?is_debug_compiled,
+ Nodes = ?acquire_nodes(3, Config ++ [{tc_timeout, timer:minutes(2)}]),
+ [Coord, Part1, Part2] = Nodes,
+ Tab1 = {asym1, [{ram_copies, [Part2]}, {disc_copies, [Coord]}]},
+ Tab2 = {asym2, [{ram_copies, [Coord]}, {disc_copies, [Part1]}]},
+ TransFun = do_asym_trans,
+ kill_after_debug_point(coord_pid, {Coord, {mnesia_tm, multi_commit_asym_got_votes}},
+ TransFun, [Tab1, Tab2], Nodes).
+
+asym_trans_kill_coord_log_commit_rec(suite) -> [];
+asym_trans_kill_coord_log_commit_rec(Config) when is_list(Config) ->
+ ?is_debug_compiled,
+ Nodes = ?acquire_nodes(3, Config ++ [{tc_timeout, timer:minutes(2)}]),
+ [Coord, Part1, Part2] = Nodes,
+ Tab1 = {asym1, [{ram_copies, [Part2]}, {disc_copies, [Coord]}]},
+ Tab2 = {asym2, [{ram_copies, [Coord]}, {disc_copies, [Part1]}]},
+ TransFun = do_asym_trans,
+ kill_after_debug_point(Coord, {Coord, {mnesia_tm, multi_commit_asym_log_commit_rec}},
+ TransFun, [Tab1, Tab2], Nodes).
+
+asym_trans_kill_coord_pid_log_commit_rec(suite) -> [];
+asym_trans_kill_coord_pid_log_commit_rec(Config) when is_list(Config) ->
+ ?is_debug_compiled,
+ Nodes = ?acquire_nodes(3, Config ++ [{tc_timeout, timer:minutes(2)}]),
+ [Coord, Part1, Part2] = Nodes,
+ Tab1 = {asym1, [{ram_copies, [Part2]}, {disc_copies, [Coord]}]},
+ Tab2 = {asym2, [{ram_copies, [Coord]}, {disc_copies, [Part1]}]},
+ TransFun = do_asym_trans,
+ kill_after_debug_point(coord_pid, {Coord, {mnesia_tm, multi_commit_asym_log_commit_rec}},
+ TransFun, [Tab1, Tab2], Nodes).
+
+asym_trans_kill_coord_log_commit_dec(suite) -> [];
+asym_trans_kill_coord_log_commit_dec(Config) when is_list(Config) ->
+ ?is_debug_compiled,
+ Nodes = ?acquire_nodes(3, Config ++ [{tc_timeout, timer:minutes(2)}]),
+ [Coord, Part1, Part2] = Nodes,
+ Tab1 = {asym1, [{ram_copies, [Part2]}, {disc_copies, [Coord]}]},
+ Tab2 = {asym2, [{ram_copies, [Coord]}, {disc_copies, [Part1]}]},
+ TransFun = do_asym_trans,
+ kill_after_debug_point(Coord, {Coord, {mnesia_tm, multi_commit_asym_log_commit_dec}},
+ TransFun, [Tab1, Tab2], Nodes).
+
+asym_trans_kill_coord_pid_log_commit_dec(suite) -> [];
+asym_trans_kill_coord_pid_log_commit_dec(Config) when is_list(Config) ->
+ ?is_debug_compiled,
+ Nodes = ?acquire_nodes(3, Config ++ [{tc_timeout, timer:minutes(2)}]),
+ [Coord, Part1, Part2] = Nodes,
+ Tab1 = {asym1, [{ram_copies, [Part2]}, {disc_copies, [Coord]}]},
+ Tab2 = {asym2, [{ram_copies, [Coord]}, {disc_copies, [Part1]}]},
+ TransFun = do_asym_trans,
+ kill_after_debug_point(coord_pid, {Coord, {mnesia_tm, multi_commit_asym_log_commit_dec}},
+ TransFun, [Tab1, Tab2], Nodes).
+
+asym_trans_kill_coord_rec_acc_pre_commit_log_commit(suite) -> [];
+asym_trans_kill_coord_rec_acc_pre_commit_log_commit(Config) when is_list(Config) ->
+ ?is_debug_compiled,
+ Nodes = ?acquire_nodes(3, Config ++ [{tc_timeout, timer:minutes(2)}]),
+ [Coord, Part1, Part2] = Nodes,
+ Tab1 = {asym1, [{ram_copies, [Part2]}, {disc_copies, [Coord]}]},
+ Tab2 = {asym2, [{ram_copies, [Coord]}, {disc_copies, [Part1]}]},
+ TransFun = do_asym_trans,
+ kill_after_debug_point(Coord, {Coord, {mnesia_tm, rec_acc_pre_commit_log_commit}},
+ TransFun, [Tab1, Tab2], Nodes).
+
+asym_trans_kill_coord_pid_rec_acc_pre_commit_log_commit(suite) -> [];
+asym_trans_kill_coord_pid_rec_acc_pre_commit_log_commit(Config) when is_list(Config) ->
+ ?is_debug_compiled,
+ Nodes = ?acquire_nodes(3, Config ++ [{tc_timeout, timer:minutes(2)}]),
+ [Coord, Part1, Part2] = Nodes,
+ Tab1 = {asym1, [{ram_copies, [Part2]}, {disc_copies, [Coord]}]},
+ Tab2 = {asym2, [{ram_copies, [Coord]}, {disc_copies, [Part1]}]},
+ TransFun = do_asym_trans,
+ kill_after_debug_point(coord_pid, {Coord, {mnesia_tm, rec_acc_pre_commit_log_commit}},
+ TransFun, [Tab1, Tab2], Nodes).
+
+asym_trans_kill_coord_rec_acc_pre_commit_done_commit(suite) -> [];
+asym_trans_kill_coord_rec_acc_pre_commit_done_commit(Config) when is_list(Config) ->
+ ?is_debug_compiled,
+ Nodes = ?acquire_nodes(3, Config ++ [{tc_timeout, timer:minutes(2)}]),
+ [Coord, Part1, Part2] = Nodes,
+ Tab1 = {asym1, [{ram_copies, [Part2]}, {disc_copies, [Coord]}]},
+ Tab2 = {asym2, [{ram_copies, [Coord]}, {disc_copies, [Part1]}]},
+ TransFun = do_asym_trans,
+ kill_after_debug_point(Coord, {Coord, {mnesia_tm, rec_acc_pre_commit_done_commit}},
+ TransFun, [Tab1, Tab2], Nodes).
+
+asym_trans_kill_coord_pid_rec_acc_pre_commit_done_commit(suite) -> [];
+asym_trans_kill_coord_pid_rec_acc_pre_commit_done_commit(Config) when is_list(Config) ->
+ ?is_debug_compiled,
+ Nodes = ?acquire_nodes(3, Config ++ [{tc_timeout, timer:minutes(2)}]),
+ [Coord, Part1, Part2] = Nodes,
+ Tab1 = {asym1, [{ram_copies, [Part2]}, {disc_copies, [Coord]}]},
+ Tab2 = {asym2, [{ram_copies, [Coord]}, {disc_copies, [Part1]}]},
+ TransFun = do_asym_trans,
+ kill_after_debug_point(coord_pid, {Coord, {mnesia_tm, rec_acc_pre_commit_done_commit}},
+ TransFun, [Tab1, Tab2], Nodes).
+
+do_asym_trans([Tab1, Tab2 | _R], Garbhandler) ->
+ ?dl("Starting asym trans ", []),
+ ASym_Trans = fun() ->
+ TidTs = {_Mod, Tid, _Store} =
+ mnesia:get_activity_id(),
+ ?verbose("===> asym_trans: ~w~n", [TidTs]),
+ Garbhandler ! {trans_id, Tid},
+ [{_, _, Val1}] = mnesia:read({Tab1, 1}),
+ [{_, _, Val2}] = mnesia:read({Tab2, 1}),
+ mnesia:write({Tab1, 1, Val1+1}),
+ mnesia:write({Tab2, 1, Val2+1})
+ end,
+ Res = mnesia:transaction(ASym_Trans),
+ case Res of
+ {atomic, ok} -> ok;
+ {aborted, _Reason} -> ok;
+ _Else -> ?error("Wrong output from mensia:transaction(FUN):~n ~p~n", [Res])
+ end,
+ ?dl("Asym trans finished with: ~p ", [Res]).
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+kill_after_debug_point(Kill, {DebugNode, Debug_Point}, TransFun, TabsAndDefs, Nodes) ->
+ [Coord | _rest] = Nodes,
+
+ Create = fun({Tab, Def}) -> ?match({atomic, ok}, mnesia:create_table(Tab, Def)) end,
+ lists:foreach(Create, TabsAndDefs),
+ Tabs = [T || {T, _} <- TabsAndDefs],
+ Write = fun(Tab) -> ?match(ok, mnesia:dirty_write({Tab, 1, 100})) end,
+ lists:foreach(Write, Tabs),
+
+ Self = self(),
+ SyncFun = fun(_Env1, _Env2) -> % Just Sync with test prog
+ Self ! {self(), fun_in_position},
+ ?dl("SyncFun, sending fun_in_position ", []),
+ receive continue ->
+ ?dl("SyncFun received continue ",[]),
+ ok
+ after timer:seconds(60) ->
+ ?error("Timeout in sync_fun on ~p~n", [node()])
+ end
+ end,
+
+ Garb_handler = spawn_link(?MODULE, garb_handler, [[]]),
+
+ ?remote_activate_debug_fun(DebugNode, Debug_Point, SyncFun, []),
+ ?dl("fun_in_position activated at ~p with ~p", [DebugNode, Debug_Point]),
+ %% Spawn and do the transaction
+ Pid = spawn(Coord, ?MODULE, TransFun, [Tabs, Garb_handler]),
+ %% Wait till all the Nodes are in correct position
+ [{StoppedPid,_}] = ?receive_messages([fun_in_position]),
+ ?dl("Received fun_in_position; Removing the debug funs ~p", [DebugNode]),
+ ?remote_deactivate_debug_fun(DebugNode, Debug_Point),
+
+ case Kill of
+ coord_pid ->
+ ?dl("Intentionally killing pid ~p ", [Pid]),
+ exit(Pid, normal);
+ Node ->
+ mnesia_test_lib:kill_mnesia([Node])
+ end,
+
+ StoppedPid ! continue, %% Send continue, it may still be alive
+
+ %% Start and check that the databases are consistent
+ ?dl("Done, Restarting and verifying result ",[]),
+ case Kill of
+ coord_pid -> ok;
+ _ -> % Ok, mnesia on some node was killed restart it
+ timer:sleep(timer:seconds(3)), %% Just let it have the time to die
+ ?match(ok, rpc:call(Kill, mnesia, start, [[]])),
+ ?match(ok, rpc:call(Kill, mnesia, wait_for_tables, [Tabs, 60000]))
+ end,
+ Trans_res = verify_tabs(Tabs, Nodes),
+ case TransFun of
+ do_asym_trans ->
+ %% Verifies that decisions are garbed, only valid for asym_tran
+ Garb_handler ! {get_tids, self()},
+ Tid_list = receive
+ {tids, List} ->
+ ?dl("Fun rec ~w", [List]),
+ List
+ end,
+ garb_of_decisions(Kill, Nodes, Tid_list, Trans_res);
+ _ ->
+ ignore
+ end,
+ ?verify_mnesia(Nodes, []).
+
+garb_of_decisions(Kill, Nodes, Tid_list, Trans_res) ->
+ [Coord, Part1, Part2] = Nodes,
+ %% Check that decision log is empty on all nodes after the trans is finished
+ verify_garb_decision_log(Nodes, Tid_list),
+ case Trans_res of
+ aborted ->
+ %% Check that aborted trans have not been restarted!!
+ ?match(1, length(Tid_list)),
+ %% Check the transient decision logs
+ %% A transaction should only be aborted in an early stage of
+ %% the trans before the any Node have logged anything
+ verify_garb_transient_logs(Nodes, Tid_list, aborted),
+ %% And only when the coordinator are have died
+ %% Else he would have restarted the transaction
+ ?match(Kill, Coord);
+ updated ->
+ case length(Tid_list) of
+ 1 ->
+ %% If there was only one transaction, it should be logged as
+ %% comitted on every node!
+ [Tid1] = Tid_list,
+ verify_garb_transient_logs(Nodes, [Tid1], committed);
+ 2 ->
+ %% If there is two transaction id, then the first
+ %% TID should have been aborted and the transaction
+ %% restarted with a new TID
+ [Tid1, Tid2] = Tid_list,
+ verify_garb_transient_logs(Nodes, [Tid1], aborted),
+ %% If mnesia is killed on a node i.e Coord and Part1 than they
+ %% won't know about the restarted trans! The rest of the nodes
+ %% should know that the trans was committed
+ case Kill of
+ coord_pid ->
+ verify_garb_transient_logs(Nodes, [Tid2], committed);
+ Coord ->
+ verify_garb_transient_logs([Part1, Part2], [Tid2], committed),
+ verify_garb_transient_logs([Coord], [Tid2], not_found);
+ Part1 ->
+ verify_garb_transient_logs([Coord, Part2], [Tid2], committed),
+ verify_garb_transient_logs([Part1], [Tid2], not_found)
+ end
+ end
+ end.
+
+verify_garb_decision_log([], _Tids) -> ok;
+verify_garb_decision_log([Node|R], Tids) ->
+ Check = fun(Tid) -> %% Node, Tid used in debugging!
+ ?match({{not_found, _}, Node, Tid},
+ {outcome(Tid, [mnesia_decision]), Node, Tid})
+ end,
+ rpc:call(Node, lists, foreach, [Check, Tids]),
+ verify_garb_decision_log(R, Tids).
+
+verify_garb_transient_logs([], _Tids, _) -> ok;
+verify_garb_transient_logs([Node|R], Tids, Exp_Res) ->
+ Check = fun(Tid) ->
+ LatestTab = mnesia_lib:val(latest_transient_decision),
+ PrevTabs = mnesia_lib:val(previous_transient_decisions),
+ case outcome(Tid, [LatestTab | PrevTabs]) of
+ {found, {_, [{_,_Tid, Exp_Res}]}} -> ok;
+ {not_found, _} when Exp_Res == not_found -> ok;
+ {not_found, _} when Exp_Res == aborted -> ok;
+ Else -> ?error("Expected ~p in trans ~p on ~p got ~p~n",
+ [Exp_Res, Tid, Node, Else])
+ end
+ end,
+ rpc:call(Node, lists, foreach, [Check, Tids]),
+ verify_garb_transient_logs(R, Tids, Exp_Res).
+
+outcome(Tid, Tabs) ->
+ outcome(Tid, Tabs, Tabs).
+
+outcome(Tid, [Tab | Tabs], AllTabs) ->
+ case catch ets:lookup(Tab, Tid) of
+ {'EXIT', _} ->
+ outcome(Tid, Tabs, AllTabs);
+ [] ->
+ outcome(Tid, Tabs, AllTabs);
+ Val ->
+ {found, {Tab, Val}}
+ end;
+outcome(_Tid, [], AllTabs) ->
+ {not_found, AllTabs}.
+
+
+verify_tabs([Tab|R], Nodes) ->
+ [_Coord, Part1, Part2 | _rest] = Nodes,
+ Read = fun() -> mnesia:read({Tab, 1}) end,
+ {success, A} = ?match({atomic, _}, mnesia:transaction(Read)),
+ ?match(A, rpc:call(Part1, mnesia, transaction, [Read])),
+ ?match(A, rpc:call(Part2, mnesia, transaction, [Read])),
+ {atomic, [{Tab, 1, Res}]} = A,
+ verify_tabs(R, Nodes, Res).
+
+verify_tabs([], _Nodes, Res) ->
+ case Res of
+ 100 -> aborted;
+ 101 -> updated
+ end;
+
+verify_tabs([Tab | Rest], Nodes, Res) ->
+ [Coord, Part1, Part2 | _rest] = Nodes,
+ Read = fun() -> mnesia:read({Tab, 1}) end,
+ Exp = {atomic, [{Tab, 1, Res}]},
+ ?match(Exp, rpc:call(Coord, mnesia, transaction, [Read])),
+ ?match(Exp, rpc:call(Part1, mnesia, transaction, [Read])),
+ ?match(Exp, rpc:call(Part2, mnesia, transaction, [Read])),
+ verify_tabs(Rest, Nodes, Res).
+
+%% Gather TIDS and send them to requesting process and exit!
+garb_handler(List) ->
+ receive
+ {trans_id, ID} -> garb_handler([ID|List]);
+ {get_tids, Pid} -> Pid ! {tids, lists:reverse(List)}
+ end.
+
+%%%%%%%%%%%%%%%%%%%%%%%
+receive_messages([], _File, _Line) -> [];
+receive_messages(ListOfMsgs, File, Line) ->
+ receive
+ {Pid, Msg} ->
+ case lists:member(Msg, ListOfMsgs) of
+ false ->
+ mnesia_test_lib:log("<>WARNING<>~n"
+ "Received unexpected msg~n ~p ~n"
+ "While waiting for ~p~n",
+ [{Pid, Msg}, ListOfMsgs], File, Line),
+ receive_messages(ListOfMsgs, File, Line);
+ true ->
+ ?dl("Got msg ~p from ~p ", [Msg, node(Pid)]),
+ [{Pid, Msg} | receive_messages(ListOfMsgs -- [Msg], File, Line)]
+ end;
+ Else -> mnesia_test_lib:log("<>WARNING<>~n"
+ "Recevied unexpected or bad formatted msg~n ~p ~n"
+ "While waiting for ~p~n",
+ [Else, ListOfMsgs], File, Line),
+ receive_messages(ListOfMsgs, File, Line)
+ after timer:minutes(2) ->
+ ?error("Timeout in receive msgs while waiting for ~p~n",
+ [ListOfMsgs])
+ end.
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+after_full_disc_partition(doc) ->
+ ["Verify that the database does not get corrupt",
+ "when Mnesia encounters a full disc partition"].
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%% interrupted_fallback_start
+%% is implemented in consistency interupted_install_fallback!
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+after_corrupt_files(doc) ->
+ ["Verify that mnesia (and dets) can handle corrupt files"];
+after_corrupt_files(suite) -> % cope with unsynced disks
+ [after_corrupt_files_decision_log_head,
+ after_corrupt_files_decision_log_tail,
+ after_corrupt_files_latest_log_head,
+ after_corrupt_files_latest_log_tail,
+ after_corrupt_files_table_dat_head,
+ after_corrupt_files_table_dat_tail,
+ after_corrupt_files_schema_dat_head,
+ after_corrupt_files_schema_dat_tail
+ ].
+
+after_corrupt_files_decision_log_head(suite) -> [];
+after_corrupt_files_decision_log_head(Config) when is_list(Config) ->
+ after_corrupt_files(Config, "DECISION.LOG", head, repair).
+
+after_corrupt_files_decision_log_tail(suite) -> [];
+after_corrupt_files_decision_log_tail(Config) when is_list(Config) ->
+ after_corrupt_files(Config, "DECISION.LOG", tail, repair).
+
+after_corrupt_files_latest_log_head(suite) -> [];
+after_corrupt_files_latest_log_head(Config) when is_list(Config) ->
+ after_corrupt_files(Config, "LATEST.LOG", head, repair).
+
+after_corrupt_files_latest_log_tail(suite) -> [];
+after_corrupt_files_latest_log_tail(Config) when is_list(Config) ->
+ after_corrupt_files(Config, "LATEST.LOG", tail, repair).
+
+after_corrupt_files_table_dat_head(suite) -> [];
+after_corrupt_files_table_dat_head(Config) when is_list(Config) ->
+ after_corrupt_files(Config, "rec_files.DAT", head, crash).
+
+after_corrupt_files_table_dat_tail(suite) -> [];
+after_corrupt_files_table_dat_tail(Config) when is_list(Config) ->
+ after_corrupt_files(Config, "rec_files.DAT", tail, repair).
+
+after_corrupt_files_schema_dat_head(suite) -> [];
+after_corrupt_files_schema_dat_head(Config) when is_list(Config) ->
+ after_corrupt_files(Config, "schema.DAT", head, crash).
+
+after_corrupt_files_schema_dat_tail(suite) -> [];
+after_corrupt_files_schema_dat_tail(Config) when is_list(Config) ->
+ after_corrupt_files(Config, "schema.DAT", tail, crash).
+
+
+
+%%% BUGBUG: We should also write testcase's for autorepair=false i.e.
+%%% not the standard case!
+after_corrupt_files(Config, File, Where, Behaviour) ->
+ [Node] = ?acquire_nodes(1, Config ++ [{tc_timeout, timer:minutes(2)}]),
+ Tab = rec_files,
+ Def = [{disc_only_copies, [Node]}],
+ ?match({atomic, ok}, mnesia:create_table(Tab, Def)),
+ insert_data(Tab, 100),
+ Dir = mnesia:system_info(directory),
+ mnesia_test_lib:kill_mnesia([Node]),
+ timer:sleep(timer:seconds(10)), % Let dets finish whatever it does
+
+ DirFile = Dir ++ "/" ++ File,
+
+ {ok, Fd} = file:open(DirFile, read_write),
+ {ok, FileInfo} = file:read_file_info(DirFile),
+ case Where of
+ head ->
+ ?match({ok, _NewP}, file:position(Fd, {bof, 1})),
+ ?match(ok, file:write(Fd, [255, 255, 255, 255, 255, 255, 255, 255, 254])),
+ ok;
+ tail ->
+ Size = FileInfo#file_info.size,
+ Half = Size div 2,
+
+ ?dl(" Size = ~p Half = ~p ", [Size, Half]),
+ ?match({ok, _NewP}, file:position(Fd, {bof, Half})),
+ ?match(ok, file:truncate(Fd)),
+ ok
+ end,
+ ?match(ok, file:close(Fd)),
+
+ ?warning("++++++SOME OF THE after_corrupt* TEST CASES WILL INTENTIONALLY CRASH MNESIA+++++++~n", []),
+ Pid = spawn_link(?MODULE, mymnesia_start, [self()]),
+ receive
+ {Pid, ok} ->
+ ?match(ok, mnesia:wait_for_tables([schema, Tab], 10000)),
+ ?match(ok, verify_data(Tab, 100)),
+ case mnesia_monitor:get_env(auto_repair) of
+ false ->
+ ?error("Mnesia should have crashed in ~p ~p ~n",
+ [File, Where]);
+ true ->
+ ok
+ end,
+ ?verify_mnesia([Node], []);
+ {Pid, {error, ED}} ->
+ case {mnesia_monitor:get_env(auto_repair), Behaviour} of
+ {true, repair} ->
+ ?error("Mnesia crashed with ~p: in ~p ~p ~n",
+ [ED, File, Where]);
+ _ -> %% Every other can crash!
+ ok
+ end,
+ ?verify_mnesia([], [Node]);
+ Msg ->
+ ?error("~p ~p: Got ~p during start of Mnesia~n",
+ [File, Where, Msg])
+ end.
+
+mymnesia_start(Tester) ->
+ Res = mnesia:start(),
+ unlink(Tester),
+ Tester ! {self(), Res}.
+
+verify_data(_, 0) -> ok;
+verify_data(Tab, N) ->
+ Actual = mnesia:dirty_read({Tab, N}),
+ Expected = [{Tab, N, N}],
+ if
+ Expected == Actual ->
+ verify_data(Tab, N - 1);
+ true ->
+ mnesia:schema(Tab),
+ {not_equal, node(), Expected, Actual}
+ end.
+
+insert_data(_Tab, 0) -> ok;
+insert_data(Tab, N) ->
+ ok = mnesia:sync_dirty(fun() -> mnesia:write({Tab, N, N}) end),
+ insert_data(Tab, N-1).
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+disc_less(doc) ->
+ ["Here is a simple test case of a simple recovery of a disc less node. "
+ "However a lot more test cases involving disc less nodes should "
+ "be written"];
+disc_less(suite) -> [];
+disc_less(Config) when is_list(Config) ->
+ [Node1, Node2, Node3] = Nodes = ?acquire_nodes(3, Config),
+ case mnesia_test_lib:diskless(Config) of
+ true -> skip;
+ false ->
+ ?match({atomic, ok}, mnesia:change_table_copy_type(schema, Node3, ram_copies))
+ end,
+ Tab1 = disc_less1,
+ Tab2 = disc_less2,
+ Tab3 = disc_less3,
+ Def1 = [{ram_copies, [Node3]}, {disc_copies, [Node1, Node2]}],
+ Def2 = [{ram_copies, [Node3]}, {disc_copies, [Node1]}],
+ Def3 = [{ram_copies, [Node3]}, {disc_copies, [Node2]}],
+ ?match({atomic, ok}, mnesia:create_table(Tab1, Def1)),
+ ?match({atomic, ok}, mnesia:create_table(Tab2, Def2)),
+ ?match({atomic, ok}, mnesia:create_table(Tab3, Def3)),
+ insert_data(Tab1, 100),
+ insert_data(Tab2, 100),
+ insert_data(Tab3, 100),
+
+ mnesia_test_lib:kill_mnesia([Node1, Node2]),
+ timer:sleep(500),
+ mnesia_test_lib:kill_mnesia([Node3]),
+ ?match(ok, rpc:call(Node1, mnesia, start, [])),
+ ?match(ok, rpc:call(Node2, mnesia, start, [])),
+
+ timer:sleep(500),
+ ?match(ok, rpc:call(Node3, mnesia, start, [[{extra_db_nodes, [Node1, Node2]}]])),
+ ?match(ok, rpc:call(Node3, mnesia, wait_for_tables, [[Tab1, Tab2, Tab3], 20000])),
+
+ ?match(ok, rpc:call(Node3, ?MODULE, verify_data, [Tab1, 100])),
+ ?match(ok, rpc:call(Node3, ?MODULE, verify_data, [Tab2, 100])),
+ ?match(ok, rpc:call(Node3, ?MODULE, verify_data, [Tab3, 100])),
+
+
+ ?match(ok, rpc:call(Node2, ?MODULE, verify_data, [Tab1, 100])),
+ ?match(ok, rpc:call(Node2, ?MODULE, verify_data, [Tab2, 100])),
+ ?match(ok, rpc:call(Node2, ?MODULE, verify_data, [Tab3, 100])),
+
+ ?match(ok, rpc:call(Node1, ?MODULE, verify_data, [Tab1, 100])),
+ ?match(ok, rpc:call(Node1, ?MODULE, verify_data, [Tab2, 100])),
+ ?match(ok, rpc:call(Node1, ?MODULE, verify_data, [Tab3, 100])),
+ ?verify_mnesia(Nodes, []).
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+system_upgrade(doc) ->
+ ["Test on-line and off-line upgrade of the Mnesia application"].
+
+garb_decision(doc) ->
+ ["Test that decisions are garbed correctly."];
+garb_decision(suite) -> [];
+garb_decision(Config) when is_list(Config) ->
+ [Node1, Node2, Node3] = Nodes = ?acquire_nodes(3, Config),
+ check_garb(Nodes),
+ ?match({atomic, ok},mnesia:create_table(a, [{disc_copies, Nodes}])),
+ check_garb(Nodes),
+ ?match({atomic, ok},mnesia:create_table(b, [{ram_copies, Nodes}])),
+ check_garb(Nodes),
+ ?match({atomic, ok},mnesia:create_table(c, [{ram_copies, [Node1, Node3]},
+ {disc_copies, [Node2]}])),
+ check_garb(Nodes),
+ ?match({atomic, ok},mnesia:create_table(d, [{disc_copies, [Node1, Node3]},
+ {ram_copies, [Node2]}])),
+ check_garb(Nodes),
+
+ W = fun(Tab) -> mnesia:write({Tab,1,1}) end,
+ A = fun(Tab) -> mnesia:write({Tab,1,1}), exit(1) end,
+
+ ?match({atomic, ok}, mnesia:transaction(W,[a])),
+ check_garb(Nodes),
+ ?match({atomic, ok}, mnesia:transaction(W,[b])),
+ check_garb(Nodes),
+ ?match({atomic, ok}, mnesia:transaction(W,[c])),
+ check_garb(Nodes),
+ ?match({atomic, ok}, mnesia:transaction(W,[d])),
+ check_garb(Nodes),
+ ?match({aborted,1}, mnesia:transaction(A,[a])),
+ check_garb(Nodes),
+ ?match({aborted,1}, mnesia:transaction(A,[b])),
+ check_garb(Nodes),
+ ?match({aborted,1}, mnesia:transaction(A,[c])),
+ check_garb(Nodes),
+ ?match({aborted,1}, mnesia:transaction(A,[d])),
+ check_garb(Nodes),
+
+ rpc:call(Node2, mnesia, lkill, []),
+ ?match({atomic, ok}, mnesia:transaction(W,[a])),
+ ?match({atomic, ok}, mnesia:transaction(W,[b])),
+ ?match({atomic, ok}, mnesia:transaction(W,[c])),
+ ?match({atomic, ok}, mnesia:transaction(W,[d])),
+ check_garb(Nodes),
+ ?match([], mnesia_test_lib:start_mnesia([Node2])),
+ check_garb(Nodes),
+ timer:sleep(2000),
+ check_garb(Nodes),
+ %%%%%% Check transient_decision logs %%%%%
+
+ ?match(dumped, mnesia:dump_log()), sys:get_status(mnesia_recover), % sync
+ [{atomic, ok} = mnesia:transaction(W,[a]) || _ <- lists:seq(1,30)],
+ ?match(dumped, mnesia:dump_log()), sys:get_status(mnesia_recover), % sync
+ TD0 = mnesia_lib:val(latest_transient_decision),
+ ?match(0, ets:info(TD0, size)),
+ {atomic, ok} = mnesia:transaction(W,[a]),
+ ?match(dumped, mnesia:dump_log()), sys:get_status(mnesia_recover), % sync
+ ?match(TD0, mnesia_lib:val(latest_transient_decision)),
+ [{atomic, ok} = mnesia:transaction(W,[a]) || _ <- lists:seq(1,30)],
+ ?match(dumped, mnesia:dump_log()), sys:get_status(mnesia_recover), % sync
+ ?match(false, TD0 =:= mnesia_lib:val(latest_transient_decision)),
+ ?match(true, lists:member(TD0, mnesia_lib:val(previous_transient_decisions))),
+ ?verify_mnesia(Nodes, []).
+
+check_garb(Nodes) ->
+ rpc:multicall(Nodes, sys, get_status, [mnesia_recover]),
+ ?match({_, []},rpc:multicall(Nodes, erlang, apply, [fun check_garb/0, []])).
+
+check_garb() ->
+ try
+ Ds = ets:tab2list(mnesia_decision),
+ Check = fun({trans_tid,serial, _}) -> false;
+ ({mnesia_down,_,_,_}) -> false;
+ (_Else) -> true
+ end,
+ Node = node(),
+ ?match({Node, []}, {node(), lists:filter(Check, Ds)})
+ catch _:_ -> ok
+ end,
+ ok.
diff --git a/lib/mnesia/test/mnesia_registry_test.erl b/lib/mnesia/test/mnesia_registry_test.erl
new file mode 100644
index 0000000000..2305ef93b7
--- /dev/null
+++ b/lib/mnesia/test/mnesia_registry_test.erl
@@ -0,0 +1,137 @@
+%%
+%% %CopyrightBegin%
+%%
+%% 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%
+%%
+
+%%
+-module(mnesia_registry_test).
+-author('[email protected]').
+-compile([export_all]).
+-include("mnesia_test_lib.hrl").
+
+init_per_testcase(Func, Conf) ->
+ mnesia_test_lib:init_per_testcase(Func, Conf).
+
+fin_per_testcase(Func, Conf) ->
+ mnesia_test_lib:fin_per_testcase(Func, Conf).
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+all(doc) ->
+ ["Test the mnesia_registry module"];
+all(suite) ->
+ [
+ good_dump,
+ bad_dump
+ ].
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+good_dump(doc) ->
+ ["Dump a faked C-node registry"];
+good_dump(suite) -> [];
+good_dump(Config) when is_list(Config) ->
+ [Node] = Nodes = ?acquire_nodes(1, Config),
+ T1 = gordon,
+ ?match(ok, mnesia_registry:create_table(T1)),
+ One = {T1, 1, 0, integer, 0, 10},
+ Two = {T1, "two", 3, integer, 0, 20},
+ Three = {T1, 3, 0, string, 6, "thirty"},
+ ?match(ok, mnesia:dirty_write(One)),
+ ?match(ok, mnesia:dirty_write(Two)),
+ ?match(ok, mnesia:dirty_write(Three)),
+ ?match([One], mnesia:dirty_read({T1, 1})),
+ ?match([_ | _], dump_registry(Node, T1)),
+
+ NewOne = {T1, 1, 0, integer, 0, 1},
+ NewFour = {T1, "4", 1, string, 4, "four"},
+
+ ?match([NewOne], mnesia:dirty_read({T1, 1})),
+ ?match([Two], mnesia:dirty_read({T1, "two"})),
+ ?match([], mnesia:dirty_read({T1, 3})),
+ ?match([NewFour], mnesia:dirty_read({T1, "4"})),
+
+ T2 = blixt,
+ ?match({'EXIT', {aborted, {no_exists, _}}},
+ mnesia:dirty_read({T2, 1})),
+ ?match([_ |_], dump_registry(Node, T2)),
+
+ NewOne2 = setelement(1, NewOne, T2),
+ NewFour2 = setelement(1, NewFour, T2),
+
+ ?match([NewOne2], mnesia:dirty_read({T2, 1})),
+ ?match([], mnesia:dirty_read({T2, "two"})),
+ ?match([], mnesia:dirty_read({T2, 3})),
+ ?match([NewFour2], mnesia:dirty_read({T2, "4"})),
+ ?match([_One2, NewFour2], lists:sort(restore_registry(Node, T2))),
+
+ ?verify_mnesia(Nodes, []).
+
+dump_registry(Node, Tab) ->
+ case rpc:call(Node, mnesia_registry, start_dump, [Tab, self()]) of
+ Pid when is_pid(Pid) ->
+ Pid ! {write, 1, 0, integer, 0, 1},
+ Pid ! {delete, 3},
+ Pid ! {write, "4", 1, string, 4, "four"},
+ Pid ! {commit, self()},
+ receive
+ {ok, Pid} ->
+ [{Tab, "4", 1, string, 4, "four"},
+ {Tab, 1, 0, integer, 0, 1}];
+ {'EXIT', Pid, Reason} ->
+ exit(Reason)
+ end;
+ {badrpc, Reason} ->
+ exit(Reason)
+ end.
+
+restore_registry(Node, Tab) ->
+ case rpc:call(Node, mnesia_registry, start_restore, [Tab, self()]) of
+ {size, Pid, N, _LargestKeySize, _LargestValSize} ->
+ Pid ! {send_records, self()},
+ receive_records(Tab, N);
+ {badrpc, Reason} ->
+ exit(Reason)
+ end.
+
+receive_records(Tab, N) when N > 0 ->
+ receive
+ {restore, KeySize, ValSize, ValType, Key, Val} ->
+ [{Tab, Key, KeySize, ValType, ValSize, Val} | receive_records(Tab, N -1)];
+ {'EXIT', _Pid, Reason} ->
+ exit(Reason)
+ end;
+receive_records(_Tab, 0) ->
+ [].
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+bad_dump(doc) ->
+ ["Intentionally fail with the dump of a faked C-node registry"];
+bad_dump(suite) -> [];
+bad_dump(Config) when is_list(Config) ->
+ [Node] = Nodes = ?acquire_nodes(1, Config),
+
+ OldTab = ming,
+ ?match({'EXIT', {aborted, _}}, mnesia_registry:start_restore(no_tab, self())),
+ ?match({atomic, ok}, mnesia:create_table(OldTab, [{attributes, [a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q]}])),
+ ?match({'EXIT',{aborted,{bad_type,_}}}, dump_registry(Node, OldTab)),
+ ?match(stopped, mnesia:stop()),
+
+ ?match({'EXIT', {aborted, _}}, mnesia_registry:create_table(down_table)),
+ ?match({'EXIT', {aborted, _}}, mnesia_registry:start_restore(no_tab, self())),
+ ?match({'EXIT', {aborted, _}}, dump_registry(Node, down_dump)),
+
+ ?verify_mnesia([], Nodes).
+
diff --git a/lib/mnesia/test/mnesia_schema_recovery_test.erl b/lib/mnesia/test/mnesia_schema_recovery_test.erl
new file mode 100644
index 0000000000..387238ae6b
--- /dev/null
+++ b/lib/mnesia/test/mnesia_schema_recovery_test.erl
@@ -0,0 +1,787 @@
+%%
+%% %CopyrightBegin%
+%%
+%% 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%
+%%
+
+%%
+-module(mnesia_schema_recovery_test).
+-author('[email protected]').
+-compile([export_all]).
+-include("mnesia_test_lib.hrl").
+
+init_per_testcase(Func, Conf) ->
+ mnesia_test_lib:init_per_testcase(Func, Conf).
+
+fin_per_testcase(Func, Conf) ->
+ mnesia_test_lib:fin_per_testcase(Func, Conf).
+
+-define(receive_messages(Msgs), receive_messages(Msgs, ?FILE, ?LINE)).
+
+% First Some debug logging
+-define(dgb, true).
+-ifdef(dgb).
+-define(dl(X, Y), ?verbose("**TRACING: " ++ X ++ "**~n", Y)).
+-else.
+-define(dl(X, Y), ok).
+-endif.
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+all(doc) ->
+ ["Verify recoverabiliy of schema transactions.",
+ " Verify that a schema transaction",
+ " can be completed when it has been logged correctly and Mnesia",
+ " crashed before the log has been dumped. Then the transaction ",
+ " should be handled during the log dump at startup"
+ ];
+all(suite) ->
+ [interrupted_before_log_dump,
+ interrupted_after_log_dump].
+
+interrupted_before_log_dump(suite) ->
+ [interrupted_before_create_ram,
+ interrupted_before_create_disc,
+ interrupted_before_create_disc_only,
+ interrupted_before_create_nostore,
+ interrupted_before_delete_ram,
+ interrupted_before_delete_disc,
+ interrupted_before_delete_disc_only,
+ interrupted_before_add_ram,
+ interrupted_before_add_disc,
+ interrupted_before_add_disc_only,
+ interrupted_before_add_kill_copier,
+ interrupted_before_move_ram,
+ interrupted_before_move_disc,
+ interrupted_before_move_disc_only,
+ interrupted_before_move_kill_copier,
+ interrupted_before_delcopy_ram,
+ interrupted_before_delcopy_disc,
+ interrupted_before_delcopy_disc_only,
+ interrupted_before_delcopy_kill_copier,
+ interrupted_before_addindex_ram,
+ interrupted_before_addindex_disc,
+ interrupted_before_addindex_disc_only,
+ interrupted_before_delindex_ram,
+ interrupted_before_delindex_disc,
+ interrupted_before_delindex_disc_only,
+ interrupted_before_change_type_ram2disc,
+ interrupted_before_change_type_ram2disc_only,
+ interrupted_before_change_type_disc2ram,
+ interrupted_before_change_type_disc2disc_only,
+ interrupted_before_change_type_disc_only2ram,
+ interrupted_before_change_type_disc_only2disc,
+ interrupted_before_change_type_other_node,
+ interrupted_before_change_schema_type %% Change schema table copy type!!
+ ].
+
+interrupted_after_log_dump(suite) ->
+ [interrupted_after_create_ram,
+ interrupted_after_create_disc,
+ interrupted_after_create_disc_only,
+ interrupted_after_create_nostore,
+ interrupted_after_delete_ram,
+ interrupted_after_delete_disc,
+ interrupted_after_delete_disc_only,
+ interrupted_after_add_ram,
+ interrupted_after_add_disc,
+ interrupted_after_add_disc_only,
+ interrupted_after_add_kill_copier,
+ interrupted_after_move_ram,
+ interrupted_after_move_disc,
+ interrupted_after_move_disc_only,
+ interrupted_after_move_kill_copier,
+ interrupted_after_delcopy_ram,
+ interrupted_after_delcopy_disc,
+ interrupted_after_delcopy_disc_only,
+ interrupted_after_delcopy_kill_copier,
+ interrupted_after_addindex_ram,
+ interrupted_after_addindex_disc,
+ interrupted_after_addindex_disc_only,
+ interrupted_after_delindex_ram,
+ interrupted_after_delindex_disc,
+ interrupted_after_delindex_disc_only,
+ interrupted_after_change_type_ram2disc,
+ interrupted_after_change_type_ram2disc_only,
+ interrupted_after_change_type_disc2ram,
+ interrupted_after_change_type_disc2disc_only,
+ interrupted_after_change_type_disc_only2ram,
+ interrupted_after_change_type_disc_only2disc,
+ interrupted_after_change_type_other_node,
+ interrupted_after_change_schema_type %% Change schema table copy type!!
+
+% interrupted_before_change_access_mode,
+% interrupted_before_transform,
+% interrupted_before_restore,
+ ].
+
+interrupted_before_create_ram(suite) -> [];
+interrupted_before_create_ram(Config) when is_list(Config) ->
+ KillAt = {mnesia_dumper, dump_schema_op},
+ interrupted_create(Config, ram_copies, all, KillAt).
+
+interrupted_before_create_disc(suite) -> [];
+interrupted_before_create_disc(Config) when is_list(Config) ->
+ KillAt = {mnesia_dumper, dump_schema_op},
+ interrupted_create(Config, disc_copies, all, KillAt).
+
+interrupted_before_create_disc_only(suite) -> [];
+interrupted_before_create_disc_only(Config) when is_list(Config) ->
+ KillAt = {mnesia_dumper, dump_schema_op},
+ interrupted_create(Config, disc_only_copies, all, KillAt).
+
+interrupted_before_create_nostore(suite) -> [];
+interrupted_before_create_nostore(Config) when is_list(Config) ->
+ KillAt = {mnesia_dumper, dump_schema_op},
+ interrupted_create(Config, ram_copies, one, KillAt).
+
+interrupted_after_create_ram(suite) -> [];
+interrupted_after_create_ram(Config) when is_list(Config) ->
+ KillAt = {mnesia_dumper, post_dump},
+ interrupted_create(Config, ram_copies, all, KillAt).
+
+interrupted_after_create_disc(suite) -> [];
+interrupted_after_create_disc(Config) when is_list(Config) ->
+ KillAt = {mnesia_dumper, post_dump},
+ interrupted_create(Config, disc_copies, all, KillAt).
+
+interrupted_after_create_disc_only(suite) -> [];
+interrupted_after_create_disc_only(Config) when is_list(Config) ->
+ KillAt = {mnesia_dumper, post_dump},
+ interrupted_create(Config, disc_only_copies, all, KillAt).
+
+interrupted_after_create_nostore(suite) -> [];
+interrupted_after_create_nostore(Config) when is_list(Config) ->
+ KillAt = {mnesia_dumper, post_dump},
+ interrupted_create(Config, ram_copies, one, KillAt).
+
+%%% After dump don't need debug point
+interrupted_create(Config, Type, _Where, {mnesia_dumper, post_dump}) ->
+ [Node1] = Nodes = ?acquire_nodes(1, [{tc_timeout, timer:seconds(30)} | Config]),
+ ?match({atomic, ok},mnesia:create_table(itrpt, [{Type, Nodes}])),
+ ?match({atomic, ok},mnesia:create_table(test, [{disc_copies,[Node1]}])),
+ ?match(ok, mnesia:dirty_write({itrpt, before, 1})),
+ ?match(ok, mnesia:dirty_write({test, found_in_log, 1})),
+ ?match(stopped, mnesia:stop()),
+ ?match([], mnesia_test_lib:start_mnesia([Node1], [itrpt,test])),
+ %% Verify
+ ?match([{test, found_in_log, 1}], mnesia:dirty_read({test, found_in_log})),
+ case Type of
+ ram_copies ->
+ ?match([], mnesia:dirty_read({itrpt, before}));
+ _ ->
+ ?match([{itrpt, before, 1}], mnesia:dirty_read({itrpt, before}))
+ end,
+ ?verify_mnesia(Nodes, []);
+interrupted_create(Config, Type, Where, KillAt) ->
+ ?is_debug_compiled,
+ [Node1, Node2] = Nodes = ?acquire_nodes(2, [{tc_timeout, timer:seconds(30)} | Config]),
+ {success, [A]} = ?start_activities([Node2]),
+ setup_dbgpoint(KillAt, Node2),
+
+ if %% CREATE TABLE
+ Where == all -> % tables on both nodes
+ A ! fun() -> mnesia:create_table(itrpt, [{Type, Nodes}]) end;
+ true -> % no table on the killed node
+ A ! fun() -> mnesia:create_table(itrpt, [{Type, [Node1]}]) end
+ end,
+
+ kill_at_debug(),
+ ?match([], mnesia_test_lib:start_mnesia([Node2], [itrpt])),
+ %% Verify
+ ?match(ok, mnesia:dirty_write({itrpt, before, 1})),
+ verify_tab(Node1, Node2),
+ ?verify_mnesia(Nodes, []).
+
+interrupted_before_delete_ram(suite) -> [];
+interrupted_before_delete_ram(Config) when is_list(Config) ->
+ Debug_Point = {mnesia_dumper, dump_schema_op},
+ interrupted_delete(Config, ram_copies, Debug_Point).
+interrupted_before_delete_disc(suite) -> [];
+interrupted_before_delete_disc(Config) when is_list(Config) ->
+ Debug_Point = {mnesia_dumper, dump_schema_op},
+ interrupted_delete(Config, disc_copies, Debug_Point).
+interrupted_before_delete_disc_only(suite) -> [];
+interrupted_before_delete_disc_only(Config) when is_list(Config) ->
+ Debug_Point = {mnesia_dumper, dump_schema_op},
+ interrupted_delete(Config, disc_only_copies, Debug_Point).
+
+interrupted_after_delete_ram(suite) -> [];
+interrupted_after_delete_ram(Config) when is_list(Config) ->
+ Debug_Point = {mnesia_dumper, post_dump},
+ interrupted_delete(Config, ram_copies, Debug_Point).
+interrupted_after_delete_disc(suite) -> [];
+interrupted_after_delete_disc(Config) when is_list(Config) ->
+ Debug_Point = {mnesia_dumper, post_dump},
+ interrupted_delete(Config, disc_copies, Debug_Point).
+interrupted_after_delete_disc_only(suite) -> [];
+interrupted_after_delete_disc_only(Config) when is_list(Config) ->
+ Debug_Point = {mnesia_dumper, post_dump},
+ interrupted_delete(Config, disc_only_copies, Debug_Point).
+
+interrupted_delete(Config, Type, KillAt) ->
+ ?is_debug_compiled,
+ [Node1, Node2] = Nodes = ?acquire_nodes(2, [{tc_timeout, timer:seconds(30)} | Config]),
+ Tab = itrpt,
+ ?match({atomic, ok}, mnesia:create_table(Tab, [{Type, [Node2]}])),
+ ?match(ok, mnesia:dirty_write({Tab, before, 1})),
+ {_Alive, Kill} = {Node1, Node2},
+ {success, [A]} = ?start_activities([Kill]),
+
+ setup_dbgpoint(KillAt, Kill),
+ A ! fun() -> mnesia:delete_table(Tab) end,
+
+ kill_at_debug(),
+ ?match([], mnesia_test_lib:start_mnesia([Node2], [])),
+ Bad = {badrpc, {'EXIT', {aborted,{no_exists, Tab, all}}}},
+ ?match(Bad, rpc:call(Node1, mnesia, table_info, [Tab, all])),
+ ?match(Bad, rpc:call(Node2, mnesia, table_info, [Tab, all])),
+ ?verify_mnesia(Nodes, []).
+
+interrupted_before_add_ram(suite) -> [];
+interrupted_before_add_ram(Config) when is_list(Config) ->
+ Debug_Point = {mnesia_dumper, dump_schema_op},
+ interrupted_add(Config, ram_copies, kill_reciever, Debug_Point).
+interrupted_before_add_disc(suite) -> [];
+interrupted_before_add_disc(Config) when is_list(Config) ->
+ Debug_Point = {mnesia_dumper, dump_schema_op},
+ interrupted_add(Config, disc_copies, kill_reciever, Debug_Point).
+interrupted_before_add_disc_only(suite) -> [];
+interrupted_before_add_disc_only(Config) when is_list(Config) ->
+ Debug_Point = {mnesia_dumper, dump_schema_op},
+ interrupted_add(Config, disc_only_copies, kill_reciever, Debug_Point).
+interrupted_before_add_kill_copier(suite) -> [];
+interrupted_before_add_kill_copier(Config) when is_list(Config) ->
+ Debug_Point = {mnesia_dumper, dump_schema_op},
+ interrupted_add(Config, ram_copies, kill_copier, Debug_Point).
+
+interrupted_after_add_ram(suite) -> [];
+interrupted_after_add_ram(Config) when is_list(Config) ->
+ Debug_Point = {mnesia_dumper, post_dump},
+ interrupted_add(Config, ram_copies, kill_reciever, Debug_Point).
+interrupted_after_add_disc(suite) -> [];
+interrupted_after_add_disc(Config) when is_list(Config) ->
+ Debug_Point = {mnesia_dumper, post_dump},
+ interrupted_add(Config, disc_copies, kill_reciever, Debug_Point).
+interrupted_after_add_disc_only(suite) -> [];
+interrupted_after_add_disc_only(Config) when is_list(Config) ->
+ Debug_Point = {mnesia_dumper, post_dump},
+ interrupted_add(Config, disc_only_copies, kill_reciever, Debug_Point).
+interrupted_after_add_kill_copier(suite) -> [];
+interrupted_after_add_kill_copier(Config) when is_list(Config) ->
+ Debug_Point = {mnesia_dumper, post_dump},
+ interrupted_add(Config, ram_copies, kill_copier, Debug_Point).
+
+%%% After dump don't need debug point
+interrupted_add(Config, Type, _Where, {mnesia_dumper, post_dump}) ->
+ [Node1, Node2] = Nodes =
+ ?acquire_nodes(2, [{tc_timeout, timer:seconds(30)} | Config]),
+ Tab = itrpt,
+ ?match({atomic, ok}, mnesia:create_table(Tab, [{Type, [Node2]}, {local_content,true}])),
+ ?match({atomic, ok},mnesia:create_table(test, [{disc_copies,[Node1]}])),
+ ?match({atomic, ok}, mnesia:add_table_copy(Tab, Node1, Type)),
+ ?match(ok, mnesia:dirty_write({itrpt, before, 1})),
+ ?match(ok, mnesia:dirty_write({test, found_in_log, 1})),
+ ?match(stopped, mnesia:stop()),
+ ?match([], mnesia_test_lib:start_mnesia([Node1], [itrpt,test])),
+ %% Verify
+ ?match([{test, found_in_log, 1}], mnesia:dirty_read({test, found_in_log})),
+ case Type of
+ ram_copies ->
+ ?match([], mnesia:dirty_read({itrpt, before}));
+ _ ->
+ ?match([{itrpt, before, 1}], mnesia:dirty_read({itrpt, before}))
+ end,
+ ?verify_mnesia(Nodes, []);
+interrupted_add(Config, Type, Who, KillAt) ->
+ ?is_debug_compiled,
+ [Node1, Node2] = Nodes =
+ ?acquire_nodes(2, [{tc_timeout, timer:seconds(30)} | Config]),
+ {_Alive, Kill} =
+ if Who == kill_reciever ->
+ {Node1, Node2};
+ true ->
+ {Node2, Node1}
+ end,
+ {success, [A]} = ?start_activities([Kill]),
+ Tab = itrpt,
+ ?match({atomic, ok}, mnesia:create_table(Tab, [{Type, [Node1]}])),
+ ?match(ok, mnesia:dirty_write({Tab, before, 1})),
+
+ setup_dbgpoint(KillAt, Kill),
+
+ A ! fun() -> mnesia:add_table_copy(Tab, Node2, Type) end,
+ kill_at_debug(),
+ ?match([], mnesia_test_lib:start_mnesia([Kill], [itrpt])),
+ verify_tab(Node1, Node2),
+ ?verify_mnesia(Nodes, []).
+
+interrupted_before_move_ram(suite) -> [];
+interrupted_before_move_ram(Config) when is_list(Config) ->
+ Debug_Point = {mnesia_dumper, dump_schema_op},
+ interrupted_move(Config, ram_copies, kill_reciever, Debug_Point).
+interrupted_before_move_disc(suite) -> [];
+interrupted_before_move_disc(Config) when is_list(Config) ->
+ Debug_Point = {mnesia_dumper, dump_schema_op},
+ interrupted_move(Config, disc_copies, kill_reciever, Debug_Point).
+interrupted_before_move_disc_only(suite) -> [];
+interrupted_before_move_disc_only(Config) when is_list(Config) ->
+ Debug_Point = {mnesia_dumper, dump_schema_op},
+ interrupted_move(Config, disc_only_copies, kill_reciever, Debug_Point).
+interrupted_before_move_kill_copier(suite) -> [];
+interrupted_before_move_kill_copier(Config) when is_list(Config) ->
+ Debug_Point = {mnesia_dumper, dump_schema_op},
+ interrupted_move(Config, ram_copies, kill_copier, Debug_Point).
+
+interrupted_after_move_ram(suite) -> [];
+interrupted_after_move_ram(Config) when is_list(Config) ->
+ Debug_Point = {mnesia_dumper, post_dump},
+ interrupted_move(Config, ram_copies, kill_reciever, Debug_Point).
+interrupted_after_move_disc(suite) -> [];
+interrupted_after_move_disc(Config) when is_list(Config) ->
+ Debug_Point = {mnesia_dumper, post_dump},
+ interrupted_move(Config, disc_copies, kill_reciever, Debug_Point).
+interrupted_after_move_disc_only(suite) -> [];
+interrupted_after_move_disc_only(Config) when is_list(Config) ->
+ Debug_Point = {mnesia_dumper, post_dump},
+ interrupted_move(Config, disc_only_copies, kill_reciever, Debug_Point).
+interrupted_after_move_kill_copier(suite) -> [];
+interrupted_after_move_kill_copier(Config) when is_list(Config) ->
+ Debug_Point = {mnesia_dumper, post_dump},
+ interrupted_move(Config, ram_copies, kill_copier, Debug_Point).
+
+%%% After dump don't need debug point
+interrupted_move(Config, Type, _Where, {mnesia_dumper, post_dump}) ->
+ [Node1, Node2] = Nodes =
+ ?acquire_nodes(2, [{tc_timeout, timer:seconds(30)} | Config]),
+ Tab = itrpt,
+ ?match({atomic, ok},mnesia:create_table(test, [{disc_copies,[Node1]}])),
+ ?match({atomic, ok}, mnesia:create_table(Tab, [{Type, [Node1]}])),
+ ?match(ok, mnesia:dirty_write({itrpt, before, 1})),
+ ?match({atomic, ok}, mnesia:move_table_copy(Tab, Node1, Node2)),
+ ?match(ok, mnesia:dirty_write({itrpt, aFter, 1})),
+ ?match(ok, mnesia:dirty_write({test, found_in_log, 1})),
+ ?match(stopped, mnesia:stop()),
+ ?match([], mnesia_test_lib:start_mnesia([Node1], [itrpt,test])),
+ %% Verify
+ ?match([{test, found_in_log, 1}], mnesia:dirty_read({test, found_in_log})),
+ ?match([{itrpt, before, 1}], mnesia:dirty_read({itrpt, before})),
+ ?match([{itrpt, aFter, 1}], mnesia:dirty_read({itrpt, aFter})),
+ ?verify_mnesia(Nodes, []);
+interrupted_move(Config, Type, Who, KillAt) ->
+ ?is_debug_compiled,
+ [Node1, Node2] = Nodes =
+ ?acquire_nodes(2, [{tc_timeout, timer:seconds(30)} | Config]),
+ Tab = itrpt,
+ ?match({atomic, ok}, mnesia:create_table(Tab, [{Type, [Node1]}])),
+ ?match(ok, mnesia:dirty_write({Tab, before, 1})),
+
+ {_Alive, Kill} =
+ if Who == kill_reciever ->
+ if Type == ram_copies ->
+ {atomic, ok} = mnesia:dump_tables([Tab]);
+ true ->
+ ignore
+ end,
+ {Node1, Node2};
+ true ->
+ {Node2, Node1}
+ end,
+
+ {success, [A]} = ?start_activities([Kill]),
+
+ setup_dbgpoint(KillAt, Kill),
+ A ! fun() -> mnesia:move_table_copy(Tab, Node1, Node2) end,
+ kill_at_debug(),
+ ?match([], mnesia_test_lib:start_mnesia([Kill], [itrpt])),
+ verify_tab(Node1, Node2),
+ ?verify_mnesia(Nodes, []).
+
+interrupted_before_delcopy_ram(suite) -> [];
+interrupted_before_delcopy_ram(Config) when is_list(Config) ->
+ Debug_Point = {mnesia_dumper, dump_schema_op},
+ interrupted_delcopy(Config, ram_copies, kill_reciever, Debug_Point).
+interrupted_before_delcopy_disc(suite) -> [];
+interrupted_before_delcopy_disc(Config) when is_list(Config) ->
+ Debug_Point = {mnesia_dumper, dump_schema_op},
+ interrupted_delcopy(Config, disc_copies, kill_reciever, Debug_Point).
+interrupted_before_delcopy_disc_only(suite) -> [];
+interrupted_before_delcopy_disc_only(Config) when is_list(Config) ->
+ Debug_Point = {mnesia_dumper, dump_schema_op},
+ interrupted_delcopy(Config, disc_only_copies, kill_reciever, Debug_Point).
+interrupted_before_delcopy_kill_copier(suite) -> [];
+interrupted_before_delcopy_kill_copier(Config) when is_list(Config) ->
+ Debug_Point = {mnesia_dumper, dump_schema_op},
+ interrupted_delcopy(Config, ram_copies, kill_copier, Debug_Point).
+
+interrupted_after_delcopy_ram(suite) -> [];
+interrupted_after_delcopy_ram(Config) when is_list(Config) ->
+ Debug_Point = {mnesia_dumper, post_dump},
+ interrupted_delcopy(Config, ram_copies, kill_reciever, Debug_Point).
+interrupted_after_delcopy_disc(suite) -> [];
+interrupted_after_delcopy_disc(Config) when is_list(Config) ->
+ Debug_Point = {mnesia_dumper, post_dump},
+ interrupted_delcopy(Config, disc_copies, kill_reciever, Debug_Point).
+interrupted_after_delcopy_disc_only(suite) -> [];
+interrupted_after_delcopy_disc_only(Config) when is_list(Config) ->
+ Debug_Point = {mnesia_dumper, post_dump},
+ interrupted_delcopy(Config, disc_only_copies, kill_reciever, Debug_Point).
+interrupted_after_delcopy_kill_copier(suite) -> [];
+interrupted_after_delcopy_kill_copier(Config) when is_list(Config) ->
+ Debug_Point = {mnesia_dumper, post_dump},
+ interrupted_delcopy(Config, ram_copies, kill_copier, Debug_Point).
+
+
+%%% After dump don't need debug point
+interrupted_delcopy(Config, Type, _Where, {mnesia_dumper, post_dump}) ->
+ [Node1, Node2] = Nodes =
+ ?acquire_nodes(2, [{tc_timeout, timer:seconds(30)} | Config]),
+ Tab = itrpt,
+ ?match({atomic, ok},mnesia:create_table(test, [{disc_copies,[Node1]}])),
+ ?match({atomic, ok}, mnesia:create_table(Tab, [{Type, [Node1,Node2]}])),
+ ?match({atomic, ok}, mnesia:del_table_copy(Tab, Node1)),
+ ?match(ok, mnesia:dirty_write({test, found_in_log, 1})),
+ ?match(stopped, mnesia:stop()),
+ ?match([], mnesia_test_lib:start_mnesia([Node1], [test])),
+ %% Verify
+ ?match([{test, found_in_log, 1}], mnesia:dirty_read({test, found_in_log})),
+ ?match([Node2], mnesia:table_info(itrpt,Type)),
+ ?verify_mnesia(Nodes, []);
+interrupted_delcopy(Config, Type, Who, KillAt) ->
+ ?is_debug_compiled,
+ [Node1, Node2] = Nodes =
+ ?acquire_nodes(2, [{tc_timeout, timer:seconds(30)} | Config]),
+ Tab = itrpt,
+ ?match({atomic, ok}, mnesia:create_table(Tab, [{Type, [Node1, Node2]}])),
+ ?match(ok, mnesia:dirty_write({Tab, before, 1})),
+
+ {_Alive, Kill} =
+ if Who == kill_reciever ->
+ {Node1, Node2};
+ true ->
+ if
+ Type == ram_copies ->
+ {atomic, ok} = mnesia:dump_tables([Tab]);
+ true ->
+ ignore
+ end,
+ {Node2, Node1}
+ end,
+
+ {success, [A]} = ?start_activities([Kill]),
+ setup_dbgpoint(KillAt, Kill),
+ A ! fun() -> mnesia:del_table_copy(Tab, Node2) end,
+ kill_at_debug(),
+ ?match([], mnesia_test_lib:start_mnesia([Kill], [itrpt])),
+ verify_tab(Node1, Node2),
+ ?verify_mnesia(Nodes, []).
+
+interrupted_before_addindex_ram(suite) -> [];
+interrupted_before_addindex_ram(Config) when is_list(Config) ->
+ Debug_Point = {mnesia_dumper, dump_schema_op},
+ interrupted_addindex(Config, ram_copies, Debug_Point).
+interrupted_before_addindex_disc(suite) -> [];
+interrupted_before_addindex_disc(Config) when is_list(Config) ->
+ Debug_Point = {mnesia_dumper, dump_schema_op},
+ interrupted_addindex(Config, disc_copies, Debug_Point).
+interrupted_before_addindex_disc_only(suite) -> [];
+interrupted_before_addindex_disc_only(Config) when is_list(Config) ->
+ Debug_Point = {mnesia_dumper, dump_schema_op},
+ interrupted_addindex(Config, disc_only_copies, Debug_Point).
+
+interrupted_after_addindex_ram(suite) -> [];
+interrupted_after_addindex_ram(Config) when is_list(Config) ->
+ Debug_Point = {mnesia_dumper, post_dump},
+ interrupted_addindex(Config, ram_copies, Debug_Point).
+interrupted_after_addindex_disc(suite) -> [];
+interrupted_after_addindex_disc(Config) when is_list(Config) ->
+ Debug_Point = {mnesia_dumper, post_dump},
+ interrupted_addindex(Config, disc_copies, Debug_Point).
+interrupted_after_addindex_disc_only(suite) -> [];
+interrupted_after_addindex_disc_only(Config) when is_list(Config) ->
+ Debug_Point = {mnesia_dumper, post_dump},
+ interrupted_addindex(Config, disc_only_copies, Debug_Point).
+
+
+%%% After dump don't need debug point
+interrupted_addindex(Config, Type, {mnesia_dumper, post_dump}) ->
+ [Node1] = Nodes = ?acquire_nodes(1, [{tc_timeout, timer:seconds(30)} | Config]),
+ Tab = itrpt,
+ ?match({atomic,ok},mnesia:create_table(Tab, [{Type, Nodes}])),
+ ?match({atomic,ok},mnesia:create_table(test, [{disc_copies,[Node1]}])),
+ ?match({atomic,ok}, mnesia:add_table_index(Tab, val)),
+ ?match(ok, mnesia:dirty_write({itrpt, before, 1})),
+ ?match(ok, mnesia:dirty_write({test, found_in_log, 1})),
+ ?match(stopped, mnesia:stop()),
+ ?match([], mnesia_test_lib:start_mnesia([Node1], [itrpt,test])),
+ %% Verify
+ ?match([{test, found_in_log, 1}], mnesia:dirty_read({test, found_in_log})),
+ case Type of
+ ram_copies ->
+ ?match([], mnesia:dirty_index_read(itrpt, 1, val));
+ _ ->
+ ?match([{itrpt, before, 1}], mnesia:dirty_index_read(itrpt, 1, val))
+ end,
+ ?verify_mnesia(Nodes, []);
+interrupted_addindex(Config, Type, KillAt) ->
+ ?is_debug_compiled,
+ [Node1, Node2] = Nodes = ?acquire_nodes(2, [{tc_timeout, timer:seconds(30)} | Config]),
+ Tab = itrpt,
+ ?match({atomic, ok}, mnesia:create_table(Tab, [{Type, [Node1]}])),
+ ?match(ok, mnesia:dirty_write({Tab, before, 1})),
+ {_Alive, Kill} = {Node1, Node2},
+ {success, [A]} = ?start_activities([Kill]),
+
+ setup_dbgpoint(KillAt, Kill),
+ A ! fun() -> mnesia:add_table_index(Tab, val) end,
+ kill_at_debug(),
+ ?match([], mnesia_test_lib:start_mnesia([Node2], [])),
+
+ verify_tab(Node1, Node2),
+ ?match([{Tab, b, a}, {Tab, a, a}],
+ rpc:call(Node1, mnesia, dirty_index_read, [itrpt, a, val])),
+ ?match([{Tab, b, a}, {Tab, a, a}],
+ rpc:call(Node2, mnesia, dirty_index_read, [itrpt, a, val])),
+ ?verify_mnesia(Nodes, []).
+
+interrupted_before_delindex_ram(suite) -> [];
+interrupted_before_delindex_ram(Config) when is_list(Config) ->
+ Debug_Point = {mnesia_dumper, dump_schema_op},
+ interrupted_delindex(Config, ram_copies, Debug_Point).
+interrupted_before_delindex_disc(suite) -> [];
+interrupted_before_delindex_disc(Config) when is_list(Config) ->
+ Debug_Point = {mnesia_dumper, dump_schema_op},
+ interrupted_delindex(Config, disc_copies, Debug_Point).
+interrupted_before_delindex_disc_only(suite) -> [];
+interrupted_before_delindex_disc_only(Config) when is_list(Config) ->
+ Debug_Point = {mnesia_dumper, dump_schema_op},
+ interrupted_delindex(Config, disc_only_copies, Debug_Point).
+
+interrupted_after_delindex_ram(suite) -> [];
+interrupted_after_delindex_ram(Config) when is_list(Config) ->
+ Debug_Point = {mnesia_dumper, post_dump},
+ interrupted_delindex(Config, ram_copies, Debug_Point).
+interrupted_after_delindex_disc(suite) -> [];
+interrupted_after_delindex_disc(Config) when is_list(Config) ->
+ Debug_Point = {mnesia_dumper, post_dump},
+ interrupted_delindex(Config, disc_copies, Debug_Point).
+interrupted_after_delindex_disc_only(suite) -> [];
+interrupted_after_delindex_disc_only(Config) when is_list(Config) ->
+ Debug_Point = {mnesia_dumper, post_dump},
+ interrupted_delindex(Config, disc_only_copies, Debug_Point).
+
+%%% After dump don't need debug point
+interrupted_delindex(Config, Type, {mnesia_dumper, post_dump}) ->
+ [Node1] = Nodes = ?acquire_nodes(1, [{tc_timeout, timer:seconds(30)} | Config]),
+ Tab = itrpt,
+ ?match({atomic,ok},mnesia:create_table(Tab, [{Type, Nodes},{index,[val]}])),
+ ?match({atomic,ok},mnesia:create_table(test, [{disc_copies,[Node1]}])),
+ ?match({atomic,ok}, mnesia:del_table_index(Tab, val)),
+ ?match(ok, mnesia:dirty_write({itrpt, before, 1})),
+ ?match(ok, mnesia:dirty_write({test, found_in_log, 1})),
+ ?match(stopped, mnesia:stop()),
+ ?match([], mnesia_test_lib:start_mnesia([Node1], [itrpt,test])),
+ %% Verify
+ ?match([{test, found_in_log, 1}], mnesia:dirty_read({test, found_in_log})),
+ ?match({'EXIT',{aborted,{badarg,_}}}, mnesia:dirty_index_read(itrpt, 1, val)),
+ ?verify_mnesia(Nodes, []);
+
+interrupted_delindex(Config, Type, KillAt) ->
+ ?is_debug_compiled,
+ [Node1, Node2] = Nodes = ?acquire_nodes(2, [{tc_timeout, timer:seconds(30)} | Config]),
+ Tab = itrpt,
+ ?match({atomic, ok}, mnesia:create_table(Tab, [{index, [val]},
+ {Type, [Node1]}])),
+ ?match(ok, mnesia:dirty_write({Tab, before, 1})),
+ {_Alive, Kill} = {Node1, Node2},
+ {success, [A]} = ?start_activities([Kill]),
+ setup_dbgpoint(KillAt, Kill),
+ A ! fun() -> mnesia:del_table_index(Tab, val) end,
+ kill_at_debug(),
+ ?match([], mnesia_test_lib:start_mnesia([Node2], [])),
+ verify_tab(Node1, Node2),
+ ?match({badrpc, _}, rpc:call(Node1, mnesia, dirty_index_read, [itrpt, a, val])),
+ ?match({badrpc, _}, rpc:call(Node2, mnesia, dirty_index_read, [itrpt, a, val])),
+ ?match([], rpc:call(Node1, mnesia, table_info, [Tab, index])),
+ ?match([], rpc:call(Node2, mnesia, table_info, [Tab, index])),
+ ?verify_mnesia(Nodes, []).
+
+interrupted_before_change_type_ram2disc(suite) -> [];
+interrupted_before_change_type_ram2disc(Config) when is_list(Config) ->
+ Debug_Point = {mnesia_dumper, dump_schema_op},
+ interrupted_change_type(Config, ram_copies, disc_copies, changer, Debug_Point).
+interrupted_before_change_type_ram2disc_only(suite) -> [];
+interrupted_before_change_type_ram2disc_only(Config) when is_list(Config) ->
+ Debug_Point = {mnesia_dumper, dump_schema_op},
+ interrupted_change_type(Config, ram_copies, disc_only_copies, changer, Debug_Point).
+interrupted_before_change_type_disc2ram(suite) -> [];
+interrupted_before_change_type_disc2ram(Config) when is_list(Config) ->
+ Debug_Point = {mnesia_dumper, dump_schema_op},
+ interrupted_change_type(Config, disc_copies, ram_copies, changer, Debug_Point).
+interrupted_before_change_type_disc2disc_only(suite) -> [];
+interrupted_before_change_type_disc2disc_only(Config) when is_list(Config) ->
+ Debug_Point = {mnesia_dumper, dump_schema_op},
+ interrupted_change_type(Config, disc_copies, disc_only_copies, changer, Debug_Point).
+interrupted_before_change_type_disc_only2ram(suite) -> [];
+interrupted_before_change_type_disc_only2ram(Config) when is_list(Config) ->
+ Debug_Point = {mnesia_dumper, dump_schema_op},
+ interrupted_change_type(Config, disc_only_copies, ram_copies, changer, Debug_Point).
+interrupted_before_change_type_disc_only2disc(suite) -> [];
+interrupted_before_change_type_disc_only2disc(Config) when is_list(Config) ->
+ Debug_Point = {mnesia_dumper, dump_schema_op},
+ interrupted_change_type(Config, disc_only_copies, disc_copies, changer, Debug_Point).
+interrupted_before_change_type_other_node(suite) -> [];
+interrupted_before_change_type_other_node(Config) when is_list(Config) ->
+ Debug_Point = {mnesia_dumper, dump_schema_op},
+ interrupted_change_type(Config, ram_copies, disc_copies, the_other_one, Debug_Point).
+
+interrupted_after_change_type_ram2disc(suite) -> [];
+interrupted_after_change_type_ram2disc(Config) when is_list(Config) ->
+ Debug_Point = {mnesia_dumper, post_dump},
+ interrupted_change_type(Config, ram_copies, disc_copies, changer, Debug_Point).
+interrupted_after_change_type_ram2disc_only(suite) -> [];
+interrupted_after_change_type_ram2disc_only(Config) when is_list(Config) ->
+ Debug_Point = {mnesia_dumper, post_dump},
+ interrupted_change_type(Config, ram_copies, disc_only_copies, changer, Debug_Point).
+interrupted_after_change_type_disc2ram(suite) -> [];
+interrupted_after_change_type_disc2ram(Config) when is_list(Config) ->
+ Debug_Point = {mnesia_dumper, post_dump},
+ interrupted_change_type(Config, disc_copies, ram_copies, changer, Debug_Point).
+interrupted_after_change_type_disc2disc_only(suite) -> [];
+interrupted_after_change_type_disc2disc_only(Config) when is_list(Config) ->
+ Debug_Point = {mnesia_dumper, post_dump},
+ interrupted_change_type(Config, disc_copies, disc_only_copies, changer, Debug_Point).
+interrupted_after_change_type_disc_only2ram(suite) -> [];
+interrupted_after_change_type_disc_only2ram(Config) when is_list(Config) ->
+ Debug_Point = {mnesia_dumper, post_dump},
+ interrupted_change_type(Config, disc_only_copies, ram_copies, changer, Debug_Point).
+interrupted_after_change_type_disc_only2disc(suite) -> [];
+interrupted_after_change_type_disc_only2disc(Config) when is_list(Config) ->
+ Debug_Point = {mnesia_dumper, post_dump},
+ interrupted_change_type(Config, disc_only_copies, disc_copies, changer, Debug_Point).
+interrupted_after_change_type_other_node(suite) -> [];
+interrupted_after_change_type_other_node(Config) when is_list(Config) ->
+ Debug_Point = {mnesia_dumper, post_dump},
+ interrupted_change_type(Config, ram_copies, disc_copies, the_other_one, Debug_Point).
+
+interrupted_change_type(Config, FromType, ToType, Who, KillAt) ->
+ ?is_debug_compiled,
+ [Node1, Node2] = Nodes = ?acquire_nodes(2, [{tc_timeout, timer:seconds(30)} | Config]),
+ Tab = itrpt,
+ ?match({atomic, ok}, mnesia:create_table(Tab, [{FromType, [Node2, Node1]}])),
+ ?match(ok, mnesia:dirty_write({Tab, before, 1})),
+
+ {_Alive, Kill} =
+ if Who == changer -> {Node1, Node2};
+ true -> {Node2, Node1}
+ end,
+
+ {success, [A]} = ?start_activities([Kill]),
+ setup_dbgpoint(KillAt, Kill),
+ A ! fun() -> mnesia:change_table_copy_type(Tab, Node2, ToType) end,
+ kill_at_debug(),
+ ?match([], mnesia_test_lib:start_mnesia(Nodes, [itrpt])),
+ verify_tab(Node1, Node2),
+ ?match(FromType, rpc:call(Node1, mnesia, table_info, [Tab, storage_type])),
+ ?match(ToType, rpc:call(Node2, mnesia, table_info, [Tab, storage_type])),
+ ?verify_mnesia(Nodes, []).
+
+interrupted_before_change_schema_type(suite) -> [];
+interrupted_before_change_schema_type(Config) when is_list(Config) ->
+ KillAt = {mnesia_dumper, dump_schema_op},
+ interrupted_change_schema_type(Config, KillAt).
+
+interrupted_after_change_schema_type(suite) -> [];
+interrupted_after_change_schema_type(Config) when is_list(Config) ->
+ KillAt = {mnesia_dumper, post_dump},
+ interrupted_change_schema_type(Config, KillAt).
+
+-define(cleanup(N, Config),
+ mnesia_test_lib:prepare_test_case([{reload_appls, [mnesia]}],
+ N, Config, ?FILE, ?LINE)).
+
+interrupted_change_schema_type(Config, KillAt) ->
+ ?is_debug_compiled,
+ [Node1, Node2] = Nodes = ?acquire_nodes(2, [{tc_timeout, timer:seconds(30)} | Config]),
+
+ Tab = itrpt,
+ ?match({atomic, ok}, mnesia:create_table(Tab, [{ram_copies, [Node2, Node1]}])),
+ ?match(ok, mnesia:dirty_write({Tab, before, 1})),
+
+ {success, [A]} = ?start_activities([Node2]),
+ setup_dbgpoint(KillAt, Node2),
+
+ A ! fun() -> mnesia:change_table_copy_type(schema, Node2, ram_copies) end,
+ kill_at_debug(),
+ ?match(ok, rpc:call(Node2, mnesia, start, [[{extra_db_nodes, [Node1, Node2]}]])),
+ ?match(ok, rpc:call(Node2, mnesia, wait_for_tables, [[itrpt, schema], 2000])),
+ ?match(disc_copies, rpc:call(Node1, mnesia, table_info, [schema, storage_type])),
+ ?match(ram_copies, rpc:call(Node2, mnesia, table_info, [schema, storage_type])),
+
+ %% Go back to disc_copies !!
+ {success, [B]} = ?start_activities([Node2]),
+ setup_dbgpoint(KillAt, Node2),
+ B ! fun() -> mnesia:change_table_copy_type(schema, Node2, disc_copies) end,
+ kill_at_debug(),
+
+ ?match(ok, rpc:call(Node2, mnesia, start, [[{extra_db_nodes, [Node1, Node2]}]])),
+ ?match(ok, rpc:call(Node2, mnesia, wait_for_tables, [[itrpt, schema], 2000])),
+ ?match(disc_copies, rpc:call(Node1, mnesia, table_info, [schema, storage_type])),
+ ?match(disc_copies, rpc:call(Node2, mnesia, table_info, [schema, storage_type])),
+
+ ?verify_mnesia(Nodes, []),
+ ?cleanup(2, Config).
+
+%%% Helpers
+verify_tab(Node1, Node2) ->
+ ?match({atomic, ok},
+ rpc:call(Node1, mnesia, transaction, [fun() -> mnesia:dirty_write({itrpt, a, a}) end])),
+ ?match({atomic, ok},
+ rpc:call(Node2, mnesia, transaction, [fun() -> mnesia:dirty_write({itrpt, b, a}) end])),
+ ?match([{itrpt,a,a}], rpc:call(Node1, mnesia, dirty_read, [{itrpt, a}])),
+ ?match([{itrpt,a,a}], rpc:call(Node2, mnesia, dirty_read, [{itrpt, a}])),
+ ?match([{itrpt,b,a}], rpc:call(Node1, mnesia, dirty_read, [{itrpt, b}])),
+ ?match([{itrpt,b,a}], rpc:call(Node2, mnesia, dirty_read, [{itrpt, b}])),
+ ?match([{itrpt,before,1}], rpc:call(Node1, mnesia, dirty_read, [{itrpt, before}])),
+ ?match([{itrpt,before,1}], rpc:call(Node2, mnesia, dirty_read, [{itrpt, before}])).
+
+setup_dbgpoint(DbgPoint, Where) ->
+ Self = self(),
+ TestFun = fun(_, [InitBy]) ->
+ case InitBy of
+ schema_prepare ->
+ ignore;
+ schema_begin ->
+ ignore;
+ _Other ->
+ ?deactivate_debug_fun(DbgPoint),
+ unlink(Self),
+ Self ! {fun_done, node()},
+ timer:sleep(infinity)
+ end
+ end,
+ %% Kill when debug has been reached
+ ?remote_activate_debug_fun(Where, DbgPoint, TestFun, []).
+
+kill_at_debug() ->
+ %% Wait till it's killed
+ receive
+ {fun_done, Node} ->
+ ?match([], mnesia_test_lib:kill_mnesia([Node]))
+ after
+ timer:minutes(1) -> ?error("Timeout in kill_at_debug", [])
+ end.
+
diff --git a/lib/mnesia/test/mnesia_test_lib.erl b/lib/mnesia/test/mnesia_test_lib.erl
new file mode 100644
index 0000000000..1e98f017f7
--- /dev/null
+++ b/lib/mnesia/test/mnesia_test_lib.erl
@@ -0,0 +1,1058 @@
+%%
+%% %CopyrightBegin%
+%%
+%% 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
+%% 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: Hakan Mattsson [email protected]
+%%% Purpose: Test case support library
+%%%
+%%% This test suite may be run as a part of the Grand Test Suite
+%%% of Erlang. The Mnesia test suite is structured in a hierarchy.
+%%% Each test case is implemented as an exported function with arity 1.
+%%% Test case identifiers must have the following syntax: {Module, Function}.
+%%%
+%%% The driver of the test suite runs in two passes as follows:
+%%% first the test case function is invoked with the atom 'suite' as
+%%% single argument. The returned value is treated as a list of sub
+%%% test cases. If the list of sub test cases is [] the test case
+%%% function is invoked again, this time with a list of nodes as
+%%% argument. If the list of sub test cases is not empty, the test
+%%% case driver applies the algorithm recursively on each element
+%%% in the list.
+%%%
+%%% All test cases are written in such a manner
+%%% that they start to invoke ?acquire_nodes(X, Config)
+%%% in order to prepare the test case execution. When that is
+%%% done, the test machinery ensures that at least X number
+%%% of nodes are connected to each other. If too few nodes was
+%%% specified in the Config, the test case is skipped. If there
+%%% was enough node names in the Config, X of them are selected
+%%% and if some of them happens to be down they are restarted
+%%% via the slave module. When all nodes are up and running a
+%%% disk resident schema is created on all nodes and Mnesia is
+%%% started a on all nodes. This means that all test cases may
+%%% assume that Mnesia is up and running on all acquired nodes.
+%%%
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%%%
+%%% doc(TestCases)
+%%%
+%%% Generates a test spec from parts of the test case structure
+%%%
+%%% struct(TestCases)
+%%%
+%%% Prints out the test case structure
+%%%
+%%% test(TestCases)
+%%%
+%%% Run parts of the test suite. Uses test/2.
+%%% Reads Config from mnesia_test.config and starts them if neccessary.
+%%% Kills Mnesia and wipes out the Mnesia directories as a starter.
+%%%
+%%% test(TestCases, Config)
+%%%
+%%% Run parts of the test suite on the given Nodes,
+%%% assuming that the nodes are up and running.
+%%% Kills Mnesia and wipes out the Mnesia directories as a starter.
+%%%
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+-module(mnesia_test_lib).
+-author('[email protected]').
+-export([
+ log/2,
+ log/4,
+ verbose/4,
+ default_config/0,
+ diskless/1,
+ eval_test_case/3,
+ test_driver/2,
+ test_case_evaluator/3,
+ activity_evaluator/1,
+ flush/0,
+ pick_msg/0,
+ start_activities/1,
+ start_transactions/1,
+ start_transactions/2,
+ start_sync_transactions/1,
+ start_sync_transactions/2,
+ sync_trans_tid_serial/1,
+ prepare_test_case/5,
+ select_nodes/4,
+ init_nodes/3,
+ error/4,
+ slave_start_link/0,
+ slave_start_link/1,
+ slave_sup/0,
+
+ start_mnesia/1,
+ start_mnesia/2,
+ start_appls/2,
+ start_appls/3,
+ start_wait/2,
+ storage_type/2,
+ stop_mnesia/1,
+ stop_appls/2,
+ sort/1,
+ kill_mnesia/1,
+ kill_appls/2,
+ verify_mnesia/4,
+ shutdown/0,
+ verify_replica_location/5,
+ lookup_config/2,
+ sync_tables/2,
+ remote_start/3,
+ remote_stop/1,
+ remote_kill/1,
+
+ reload_appls/2,
+
+ remote_activate_debug_fun/6,
+ do_remote_activate_debug_fun/6,
+
+ test/1,
+ test/2,
+ doc/1,
+ struct/1,
+ init_per_testcase/2,
+ fin_per_testcase/2,
+ kill_tc/2
+ ]).
+
+-include("mnesia_test_lib.hrl").
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+%% included for test server compatibility
+%% assume that all test cases only takes Config as sole argument
+init_per_testcase(_Func, Config) ->
+ global:register_name(mnesia_global_logger, group_leader()),
+ Config.
+
+fin_per_testcase(_Func, Config) ->
+ global:unregister_name(mnesia_global_logger),
+ %% Nodes = select_nodes(all, Config, ?FILE, ?LINE),
+ %% rpc:multicall(Nodes, mnesia, lkill, []),
+ Config.
+
+%% Use ?log(Format, Args) as wrapper
+log(Format, Args, LongFile, Line) ->
+ File = filename:basename(LongFile),
+ Format2 = lists:concat([File, "(", Line, ")", ": ", Format]),
+ log(Format2, Args).
+
+log(Format, Args) ->
+ case global:whereis_name(mnesia_global_logger) of
+ undefined ->
+ io:format(user, Format, Args);
+ Pid ->
+ io:format(Pid, Format, Args)
+ end.
+
+verbose(Format, Args, File, Line) ->
+ Arg = mnesia_test_verbose,
+ case get(Arg) of
+ false ->
+ ok;
+ true ->
+ log(Format, Args, File, Line);
+ undefined ->
+ case init:get_argument(Arg) of
+ {ok, List} when is_list(List) ->
+ case lists:last(List) of
+ ["true"] ->
+ put(Arg, true),
+ log(Format, Args, File, Line);
+ _ ->
+ put(Arg, false),
+ ok
+ end;
+ _ ->
+ put(Arg, false),
+ ok
+ end
+ end.
+
+-record('REASON', {file, line, desc}).
+
+error(Format, Args, File, Line) ->
+ global:send(mnesia_global_logger, {failed, File, Line}),
+ Fail = #'REASON'{file = filename:basename(File),
+ line = Line,
+ desc = Args},
+ case global:whereis_name(mnesia_test_case_sup) of
+ undefined ->
+ ignore;
+ Pid ->
+ Pid ! Fail
+%% global:send(mnesia_test_case_sup, Fail),
+ end,
+ log("<>ERROR<>~n" ++ Format, Args, File, Line).
+
+storage_type(Default, Config) ->
+ case diskless(Config) of
+ true ->
+ ram_copies;
+ false ->
+ Default
+ end.
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+default_config() ->
+ [{nodes, default_nodes()}].
+
+default_nodes() ->
+ mk_nodes(3, []).
+
+mk_nodes(0, Nodes) ->
+ Nodes;
+mk_nodes(N, []) ->
+ mk_nodes(N - 1, [node()]);
+mk_nodes(N, Nodes) when N > 0 ->
+ Head = hd(Nodes),
+ [Name, Host] = node_to_name_and_host(Head),
+ Nodes ++ [mk_node(I, Name, Host) || I <- lists:seq(1, N)].
+
+mk_node(N, Name, Host) ->
+ list_to_atom(lists:concat([Name ++ integer_to_list(N) ++ "@" ++ Host])).
+
+slave_start_link() ->
+ slave_start_link(node()).
+
+slave_start_link(Node) ->
+ [Local, Host] = node_to_name_and_host(Node),
+ {Mega, Sec, Micro} = erlang:now(),
+ List = [Local, "_", Mega, "_", Sec, "_", Micro],
+ Name = list_to_atom(lists:concat(List)),
+ slave_start_link(list_to_atom(Host), Name).
+
+slave_start_link(Host, Name) ->
+ slave_start_link(Host, Name, 10).
+
+slave_start_link(Host, Name, Retries) ->
+ Debug = atom_to_list(mnesia:system_info(debug)),
+ Args = "-mnesia debug " ++ Debug ++
+ " -pa " ++
+ filename:dirname(code:which(?MODULE)) ++
+ " -pa " ++
+ filename:dirname(code:which(mnesia)),
+ case starter(Host, Name, Args) of
+ {ok, NewNode} ->
+ ?match(pong, net_adm:ping(NewNode)),
+ {ok, Cwd} = file:get_cwd(),
+ Path = code:get_path(),
+ ok = rpc:call(NewNode, file, set_cwd, [Cwd]),
+ true = rpc:call(NewNode, code, set_path, [Path]),
+ spawn_link(NewNode, ?MODULE, slave_sup, []),
+ rpc:multicall([node() | nodes()], global, sync, []),
+ {ok, NewNode};
+ {error, Reason} when Retries == 0->
+ {error, Reason};
+ {error, Reason} ->
+ io:format("Could not start slavenode ~p ~p retrying~n",
+ [{Host, Name, Args}, Reason]),
+ timer:sleep(500),
+ slave_start_link(Host, Name, Retries - 1)
+ end.
+
+starter(Host, Name, Args) ->
+ case os:type() of
+ vxworks ->
+ X = test_server:start_node(Name, slave, [{args,Args}]),
+ timer:sleep(5000),
+ X;
+ _ ->
+ slave:start(Host, Name, Args)
+ end.
+
+slave_sup() ->
+ process_flag(trap_exit, true),
+ receive
+ {'EXIT', _, _} ->
+ case os:type() of
+ vxworks ->
+ erlang:halt();
+ _ ->
+ ignore
+ end
+ end.
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%% Index the test case structure
+
+doc(TestCases) when is_list(TestCases) ->
+ test(TestCases, suite),
+ SuiteFname = "index.html",
+ io:format("Generating HTML test specification to file: ~s~n",
+ [SuiteFname]),
+ {ok, Fd} = file:open(SuiteFname, [write]),
+ io:format(Fd, "<TITLE>Test specification for ~p</TITLE>.~n", [TestCases]),
+ io:format(Fd, "<H1>Test specification for ~p</H1>~n", [TestCases]),
+ io:format(Fd, "Test cases which not are implemented yet are written in <B>bold face</B>.~n~n", []),
+
+ io:format(Fd, "<BR><BR>~n", []),
+ io:format(Fd, "~n<DL>~n", []),
+ do_doc(Fd, TestCases, []),
+ io:format(Fd, "</DL>~n", []),
+ file:close(Fd);
+doc(TestCases) ->
+ doc([TestCases]).
+
+do_doc(Fd, [H | T], List) ->
+ case H of
+ {Module, TestCase} when is_atom(Module), is_atom(TestCase) ->
+ do_doc(Fd, Module, TestCase, List);
+ TestCase when is_atom(TestCase), List == [] ->
+ do_doc(Fd, mnesia_SUITE, TestCase, List);
+ TestCase when is_atom(TestCase) ->
+ do_doc(Fd, hd(List), TestCase, List)
+ end,
+ do_doc(Fd, T, List);
+do_doc(_, [], _) ->
+ ok.
+
+do_doc(Fd, Module, TestCase, List) ->
+ case get_suite(Module, TestCase) of
+ [] ->
+ %% Implemented leaf test case
+ Head = ?flat_format("<A HREF=~p.html#~p_1>{~p, ~p}</A>}",
+ [Module, TestCase, Module, TestCase]),
+ print_doc(Fd, Module, TestCase, Head);
+ Suite when is_list(Suite) ->
+ %% Test suite
+ Head = ?flat_format("{~p, ~p}", [Module, TestCase]),
+ print_doc(Fd, Module, TestCase, Head),
+ io:format(Fd, "~n<DL>~n", []),
+ do_doc(Fd, Suite, [Module | List]),
+ io:format(Fd, "</DL>~n", []);
+ 'NYI' ->
+ %% Not yet implemented
+ Head = ?flat_format("<B>{~p, ~p}</B>", [Module, TestCase]),
+ print_doc(Fd, Module, TestCase, Head)
+ end.
+
+print_doc(Fd, Mod, Fun, Head) ->
+ case catch (apply(Mod, Fun, [doc])) of
+ {'EXIT', _} ->
+ io:format(Fd, "<DT>~s</DT>~n", [Head]);
+ Doc when is_list(Doc) ->
+ io:format(Fd, "<DT><U>~s</U><BR><DD>~n", [Head]),
+ print_rows(Fd, Doc),
+ io:format(Fd, "</DD><BR><BR>~n", [])
+ end.
+
+print_rows(_Fd, []) ->
+ ok;
+print_rows(Fd, [H | T]) when is_list(H) ->
+ io:format(Fd, "~s~n", [H]),
+ print_rows(Fd, T);
+print_rows(Fd, [H | T]) when is_integer(H) ->
+ io:format(Fd, "~s~n", [[H | T]]).
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%% Show the test case structure
+
+struct(TestCases) ->
+ T = test(TestCases, suite),
+ struct(T, "").
+
+struct({Module, TestCase}, Indentation)
+ when is_atom(Module), is_atom(TestCase) ->
+ log("~s{~p, ~p} ...~n", [Indentation, Module, TestCase]);
+struct({Module, TestCase, Other}, Indentation)
+ when is_atom(Module), is_atom(TestCase) ->
+ log("~s{~p, ~p} ~p~n", [Indentation, Module, TestCase, Other]);
+struct([], _) ->
+ ok;
+struct([TestCase | TestCases], Indentation) ->
+ struct(TestCase, Indentation),
+ struct(TestCases, Indentation);
+struct({TestCase, []}, Indentation) ->
+ struct(TestCase, Indentation);
+struct({TestCase, SubTestCases}, Indentation) when is_list(SubTestCases) ->
+ struct(TestCase, Indentation),
+ struct(SubTestCases, Indentation ++ " ").
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%% Execute the test cases
+
+test(TestCases) ->
+ test(TestCases, []).
+
+test(TestCases, suite) when is_list(TestCases) ->
+ test_driver(TestCases, suite);
+test(TestCases, Config) when is_list(TestCases) ->
+ D1 = lists:duplicate(10, $=),
+ D2 = lists:duplicate(10, $ ),
+ log("~n~s TEST CASES: ~p~n ~sCONFIG: ~p~n~n", [D1, TestCases, D2, Config]),
+ test_driver(TestCases, Config);
+test(TestCase, Config) ->
+ test([TestCase], Config).
+
+test_driver([], _Config) ->
+ [];
+test_driver([T|TestCases], Config) ->
+ L1 = test_driver(T, Config),
+ L2 = test_driver(TestCases, Config),
+ [L1|L2];
+test_driver({Module, TestCases}, Config) when is_list(TestCases)->
+ test_driver(default_module(Module, TestCases), Config);
+test_driver({_, {Module, TestCase}}, Config) ->
+ test_driver({Module, TestCase}, Config);
+test_driver({Module, TestCase}, Config) ->
+ Sec = timer:seconds(1) * 1000,
+ case get_suite(Module, TestCase) of
+ [] when Config == suite ->
+ {Module, TestCase, 'IMPL'};
+ [] ->
+ log("Eval test case: ~w~n", [{Module, TestCase}]),
+ {T, Res} =
+ timer:tc(?MODULE, eval_test_case, [Module, TestCase, Config]),
+ log("Tested ~w in ~w sec~n", [TestCase, T div Sec]),
+ {T div Sec, Res};
+ Suite when is_list(Suite), Config == suite ->
+ Res = test_driver(default_module(Module, Suite), Config),
+ {{Module, TestCase}, Res};
+ Suite when is_list(Suite) ->
+ log("Expand test case ~w~n", [{Module, TestCase}]),
+ Def = default_module(Module, Suite),
+ {T, Res} = timer:tc(?MODULE, test_driver, [Def, Config]),
+ {T div Sec, {{Module, TestCase}, Res}};
+ 'NYI' when Config == suite ->
+ {Module, TestCase, 'NYI'};
+ 'NYI' ->
+ log("<WARNING> Test case ~w NYI~n", [{Module, TestCase}]),
+ {0, {skip, {Module, TestCase}, "NYI"}}
+ end;
+test_driver(TestCase, Config) ->
+ DefaultModule = mnesia_SUITE,
+ log("<>WARNING<> Missing module in test case identifier. "
+ "{~w, ~w} assumed~n", [DefaultModule, TestCase]),
+ test_driver({DefaultModule, TestCase}, Config).
+
+default_module(DefaultModule, TestCases) when is_list(TestCases) ->
+ Fun = fun(T) ->
+ case T of
+ {_, _} -> true;
+ T -> {true, {DefaultModule, T}}
+ end
+ end,
+ lists:zf(Fun, TestCases).
+
+%% Returns a list (possibly empty) or the atom 'NYI'
+get_suite(Mod, Fun) ->
+ case catch (apply(Mod, Fun, [suite])) of
+ {'EXIT', _} -> 'NYI';
+ List when is_list(List) -> List
+ end.
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+eval_test_case(Mod, Fun, Config) ->
+ flush(),
+ global:register_name(mnesia_test_case_sup, self()),
+ Flag = process_flag(trap_exit, true),
+ Pid = spawn_link(?MODULE, test_case_evaluator, [Mod, Fun, [Config]]),
+ R = wait_for_evaluator(Pid, Mod, Fun, Config),
+ global:unregister_name(mnesia_test_case_sup),
+ process_flag(trap_exit, Flag),
+ R.
+
+flush() ->
+ receive Msg -> [Msg | flush()]
+ after 0 -> []
+ end.
+
+wait_for_evaluator(Pid, Mod, Fun, Config) ->
+ receive
+ {'EXIT', Pid, {test_case_ok, _PidRes}} ->
+ Errors = flush(),
+ Res =
+ case Errors of
+ [] -> ok;
+ Errors -> failed
+ end,
+ {Res, {Mod, Fun}, Errors};
+ {'EXIT', Pid, {skipped, Reason}} ->
+ log("<WARNING> Test case ~w skipped, because ~p~n",
+ [{Mod, Fun}, Reason]),
+ Mod:fin_per_testcase(Fun, Config),
+ {skip, {Mod, Fun}, Reason};
+ {'EXIT', Pid, Reason} ->
+ log("<>ERROR<> Eval process ~w exited, because ~p~n",
+ [{Mod, Fun}, Reason]),
+ Mod:fin_per_testcase(Fun, Config),
+ {crash, {Mod, Fun}, Reason}
+ end.
+
+test_case_evaluator(Mod, Fun, [Config]) ->
+ NewConfig = Mod:init_per_testcase(Fun, Config),
+ R = apply(Mod, Fun, [NewConfig]),
+ Mod:fin_per_testcase(Fun, NewConfig),
+ exit({test_case_ok, R}).
+
+activity_evaluator(Coordinator) ->
+ activity_evaluator_loop(Coordinator),
+ exit(normal).
+
+activity_evaluator_loop(Coordinator) ->
+ receive
+ begin_trans ->
+ transaction(Coordinator, 0);
+ {begin_trans, MaxRetries} ->
+ transaction(Coordinator, MaxRetries);
+ end_trans ->
+ end_trans;
+ Fun when is_function(Fun) ->
+ Coordinator ! {self(), Fun()},
+ activity_evaluator_loop(Coordinator);
+% {'EXIT', Coordinator, Reason} ->
+% Reason;
+ ExitExpr ->
+% ?error("activity_evaluator_loop ~p ~p: exit(~p)~n}", [Coordinator, self(), ExitExpr]),
+ exit(ExitExpr)
+ end.
+
+transaction(Coordinator, MaxRetries) ->
+ Fun = fun() ->
+ Coordinator ! {self(), begin_trans},
+ activity_evaluator_loop(Coordinator)
+ end,
+ Coordinator ! {self(), mnesia:transaction(Fun, MaxRetries)},
+ activity_evaluator_loop(Coordinator).
+
+pick_msg() ->
+ receive
+ Message -> Message
+ after 4000 -> timeout
+ end.
+
+start_activities(Nodes) ->
+ Fun = fun(N) -> spawn_link(N, ?MODULE, activity_evaluator, [self()]) end,
+ Pids = mapl(Fun, Nodes),
+ {success, Pids}.
+
+mapl(Fun, [H|T]) ->
+ Res = Fun(H),
+ [Res|mapl(Fun, T)];
+mapl(_Fun, []) ->
+ [].
+
+diskless(Config) ->
+ case lists:keysearch(diskless, 1, Config) of
+ {value, {diskless, true}} ->
+ true;
+ _Else ->
+ false
+ end.
+
+
+start_transactions(Pids) ->
+ Fun = fun(Pid) ->
+ Pid ! begin_trans,
+ ?match_receive({Pid, begin_trans})
+ end,
+ mapl(Fun, Pids).
+
+start_sync_transactions(Pids) ->
+ Nodes = [node(Pid) || Pid <- Pids],
+ Fun = fun(Pid) ->
+ sync_trans_tid_serial(Nodes),
+ Pid ! begin_trans,
+ ?match_receive({Pid, begin_trans})
+ end,
+ mapl(Fun, Pids).
+
+
+start_transactions(Pids, MaxRetries) ->
+ Fun = fun(Pid) ->
+ Pid ! {begin_trans, MaxRetries},
+ ?match_receive({Pid, begin_trans})
+ end,
+ mapl(Fun, Pids).
+
+start_sync_transactions(Pids, MaxRetries) ->
+ Nodes = [node(Pid) || Pid <- Pids],
+ Fun = fun(Pid) ->
+ sync_trans_tid_serial(Nodes),
+ Pid ! {begin_trans, MaxRetries},
+ ?match_receive({Pid, begin_trans})
+ end,
+ mapl(Fun, Pids).
+
+sync_trans_tid_serial(Nodes) ->
+ Fun = fun() -> mnesia:write_lock_table(schema) end,
+ rpc:multicall(Nodes, mnesia, transaction, [Fun]).
+
+select_nodes(N, Config, File, Line) ->
+ prepare_test_case([], N, Config, File, Line).
+
+prepare_test_case(Actions, N, Config, File, Line) ->
+ NodeList1 = lookup_config(nodes, Config),
+ NodeList2 = lookup_config(nodenames, Config), %% For testserver
+ NodeList3 = append_unique(NodeList1, NodeList2),
+ This = node(),
+ All = [This | lists:delete(This, NodeList3)],
+ Selected = pick_nodes(N, All, File, Line),
+ case diskless(Config) of
+ true ->
+ ok;
+ false ->
+ rpc:multicall(Selected, application, set_env,[mnesia, schema_location, opt_disc])
+ end,
+ do_prepare(Actions, Selected, All, Config, File, Line).
+
+do_prepare([], Selected, _All, _Config, _File, _Line) ->
+ Selected;
+do_prepare([{init_test_case, Appls} | Actions], Selected, All, Config, File, Line) ->
+ set_kill_timer(Config),
+ Started = init_nodes(Selected, File, Line),
+ All2 = append_unique(Started, All),
+ Alive = mnesia_lib:intersect(nodes() ++ [node()], All2),
+ kill_appls(Appls, Alive),
+ process_flag(trap_exit, true),
+ do_prepare(Actions, Started, All2, Config, File, Line);
+do_prepare([delete_schema | Actions], Selected, All, Config, File, Line) ->
+ Alive = mnesia_lib:intersect(nodes() ++ [node()], All),
+ case diskless(Config) of
+ true ->
+ skip;
+ false ->
+ Del = fun(Node) ->
+ case mnesia:delete_schema([Node]) of
+ ok -> ok;
+ {error, {"All nodes not running",_}} ->
+ ok;
+ Else ->
+ ?log("Delete schema error ~p ~n", [Else])
+ end
+ end,
+ lists:foreach(Del, Alive)
+ end,
+ do_prepare(Actions, Selected, All, Config, File, Line);
+do_prepare([create_schema | Actions], Selected, All, Config, File, Line) ->
+ case diskless(Config) of
+ true ->
+ skip;
+ _Else ->
+ case mnesia:create_schema(Selected) of
+ ok ->
+ ignore;
+ BadNodes ->
+ ?fatal("Cannot create Mnesia schema on ~p~n", [BadNodes])
+ end
+ end,
+ do_prepare(Actions, Selected, All, Config, File, Line);
+do_prepare([{start_appls, Appls} | Actions], Selected, All, Config, File, Line) ->
+ case start_appls(Appls, Selected, Config) of
+ [] -> ok;
+ Bad -> ?fatal("Cannot start appls ~p: ~p~n", [Appls, Bad])
+ end,
+ do_prepare(Actions, Selected, All, Config, File, Line);
+do_prepare([{reload_appls, Appls} | Actions], Selected, All, Config, File, Line) ->
+ reload_appls(Appls, Selected),
+ do_prepare(Actions, Selected, All, Config, File, Line).
+
+set_kill_timer(Config) ->
+ case init:get_argument(mnesia_test_timeout) of
+ {ok, _ } -> ok;
+ _ ->
+ Time0 =
+ case lookup_config(tc_timeout, Config) of
+ [] -> timer:minutes(5);
+ ConfigTime when is_integer(ConfigTime) -> ConfigTime
+ end,
+ Mul = try
+ test_server:timetrap_scale_factor()
+ catch _:_ -> 1 end,
+ (catch test_server:timetrap(Mul*Time0 + 1000)),
+ spawn_link(?MODULE, kill_tc, [self(),Time0*Mul])
+ end.
+
+kill_tc(Pid, Time) ->
+ receive
+ after Time ->
+ case process_info(Pid) of
+ undefined -> ok;
+ _ ->
+ ?error("Watchdog in test case timed out "
+ "in ~p min~n", [Time div (1000*60)]),
+ Files = mnesia_lib:dist_coredump(),
+ ?log("Cores dumped to:~n ~p~n", [Files]),
+ %% Genarate erlang crashdumps.
+ %% GenDump = fun(Node) ->
+ %% File = "CRASH_" ++ atom_to_list(Node) ++ ".dump",
+ %% rpc:call(Node, os, putenv, ["ERL_CRASH_DUMP", File]),
+ %% rpc:cast(Node, erlang, halt, ["RemoteTimeTrap"])
+ %% end,
+ %% [GenDump(Node) || Node <- nodes()],
+
+ %% erlang:halt("DebugTimeTrap"),
+ exit(Pid, kill)
+ end
+ end.
+
+
+append_unique([], List) -> List;
+append_unique([H|R], List) ->
+ case lists:member(H, List) of
+ true -> append_unique(R, List);
+ false -> [H | append_unique(R, List)]
+ end.
+
+pick_nodes(all, Nodes, File, Line) ->
+ pick_nodes(length(Nodes), Nodes, File, Line);
+pick_nodes(N, [H | T], File, Line) when N > 0 ->
+ [H | pick_nodes(N - 1, T, File, Line)];
+pick_nodes(0, _Nodes, _File, _Line) ->
+ [];
+pick_nodes(N, [], File, Line) ->
+ ?skip("Test case (~p(~p)) ignored: ~p nodes missing~n",
+ [File, Line, N]).
+
+init_nodes([Node | Nodes], File, Line) ->
+ case net_adm:ping(Node) of
+ pong ->
+ [Node | init_nodes(Nodes, File, Line)];
+ pang ->
+ [Name, Host] = node_to_name_and_host(Node),
+ case slave_start_link(Host, Name) of
+ {ok, Node1} ->
+ Path = code:get_path(),
+ true = rpc:call(Node1, code, set_path, [Path]),
+ [Node1 | init_nodes(Nodes, File, Line)];
+ Other ->
+ ?skip("Test case (~p(~p)) ignored: cannot start node ~p: ~p~n",
+ [File, Line, Node, Other])
+ end
+ end;
+init_nodes([], _File, _Line) ->
+ [].
+
+%% Returns [Name, Host]
+node_to_name_and_host(Node) ->
+ string:tokens(atom_to_list(Node), [$@]).
+
+lookup_config(Key,Config) ->
+ case lists:keysearch(Key,1,Config) of
+ {value,{Key,Val}} ->
+ Val;
+ _ ->
+ []
+ end.
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+start_appls(Appls, Nodes) ->
+ start_appls(Appls, Nodes, [], [schema]).
+
+start_appls(Appls, Nodes, Config) ->
+ start_appls(Appls, Nodes, Config, [schema]).
+
+start_appls([Appl | Appls], Nodes, Config, Tabs) ->
+ {Started, BadStarters} =
+ rpc:multicall(Nodes, ?MODULE, remote_start, [Appl, Config, Nodes]),
+ BadS = [{Node, Appl, Res} || {Node, Res} <- Started, Res /= ok],
+ BadN = [{BadNode, Appl, bad_start} || BadNode <- BadStarters],
+ Bad = BadS ++ BadN,
+ case Appl of
+ mnesia when Bad == [] ->
+ sync_tables(Nodes, Tabs);
+ _ ->
+ ignore
+ end,
+ Bad ++ start_appls(Appls, Nodes, Config, Tabs);
+start_appls([], _Nodes, _Config, _Tabs) ->
+ [].
+
+remote_start(mnesia, Config, Nodes) ->
+ case diskless(Config) of
+ true ->
+ application_controller:set_env(mnesia,
+ extra_db_nodes,
+ Nodes -- [node()]),
+ application_controller:set_env(mnesia,
+ schema_location,
+ ram);
+ false ->
+ application_controller:set_env(mnesia,
+ schema_location,
+ opt_disc),
+ ignore
+ end,
+ {node(), mnesia:start()};
+remote_start(Appl, _Config, _Nodes) ->
+ Res =
+ case application:start(Appl) of
+ {error, {already_started, Appl}} ->
+ ok;
+ Other ->
+ Other
+ end,
+ {node(), Res}.
+
+%% Start Mnesia on all given nodes and wait for specified
+%% tables to be accessible on each node. The atom all means
+%% that we should wait for all tables to be loaded
+%%
+%% Returns a list of error tuples {BadNode, mnesia, Reason}
+start_mnesia(Nodes) ->
+ start_appls([mnesia], Nodes).
+start_mnesia(Nodes, Tabs) when is_list(Nodes) ->
+ start_appls([mnesia], Nodes, [], Tabs).
+
+%% Wait for the tables to be accessible from all nodes in the list
+%% and that all nodes are aware of that the other nodes also ...
+sync_tables(Nodes, Tabs) ->
+ Res = send_wait(Nodes, Tabs, []),
+ if
+ Res == [] ->
+ mnesia:transaction(fun() -> mnesia:write_lock_table(schema) end),
+ Res;
+ true ->
+ Res
+ end.
+
+send_wait([Node | Nodes], Tabs, Pids) ->
+ Pid = spawn_link(Node, ?MODULE, start_wait, [self(), Tabs]),
+ send_wait(Nodes, Tabs, [Pid | Pids]);
+send_wait([], _Tabs, Pids) ->
+ rec_wait(Pids, []).
+
+rec_wait([Pid | Pids], BadRes) ->
+ receive
+ {'EXIT', Pid, R} ->
+ rec_wait(Pids, [{node(Pid), bad_wait, R} | BadRes]);
+ {Pid, ok} ->
+ rec_wait(Pids, BadRes);
+ {Pid, {error, R}} ->
+ rec_wait(Pids, [{node(Pid), bad_wait, R} | BadRes])
+ end;
+rec_wait([], BadRes) ->
+ BadRes.
+
+start_wait(Coord, Tabs) ->
+ process_flag(trap_exit, true),
+ Mon = whereis(mnesia_monitor),
+ case catch link(Mon) of
+ {'EXIT', _} ->
+ unlink(Coord),
+ Coord ! {self(), {error, {node_not_running, node()}}};
+ _ ->
+ Res = start_wait_loop(Tabs),
+ unlink(Mon),
+ unlink(Coord),
+ Coord ! {self(), Res}
+ end.
+
+start_wait_loop(Tabs) ->
+ receive
+ {'EXIT', Pid, Reason} ->
+ {error, {start_wait, Pid, Reason}}
+ after 0 ->
+ case mnesia:wait_for_tables(Tabs, timer:seconds(30)) of
+ ok ->
+ verify_nodes(Tabs);
+ {timeout, BadTabs} ->
+ log("<>WARNING<> Wait for tables ~p: ~p~n", [node(), Tabs]),
+ start_wait_loop(BadTabs);
+ {error, Reason} ->
+ {error, {start_wait, Reason}}
+ end
+ end.
+
+verify_nodes(Tabs) ->
+ verify_nodes(Tabs, 0).
+
+verify_nodes([], _) ->
+ ok;
+
+verify_nodes([Tab| Tabs], N) ->
+ ?match(X when is_atom(X), mnesia_lib:val({Tab, where_to_read})),
+ Nodes = mnesia:table_info(Tab, where_to_write),
+ Copies =
+ mnesia:table_info(Tab, disc_copies) ++
+ mnesia:table_info(Tab, disc_only_copies) ++
+ mnesia:table_info(Tab, ram_copies),
+ Local = mnesia:table_info(Tab, local_content),
+ case Copies -- Nodes of
+ [] ->
+ verify_nodes(Tabs, 0);
+ _Else when Local == true, Nodes /= [] ->
+ verify_nodes(Tabs, 0);
+ Else ->
+ N2 =
+ if
+ N > 20 ->
+ log("<>WARNING<> ~w Waiting for table: ~p on ~p ~n",
+ [node(), Tab, Else]),
+ 0;
+ true -> N+1
+ end,
+ timer:sleep(500),
+ verify_nodes([Tab| Tabs], N2)
+ end.
+
+
+%% Nicely stop Mnesia on all given nodes
+%%
+%% Returns a list of error tuples {BadNode, Reason}
+stop_mnesia(Nodes) when is_list(Nodes) ->
+ stop_appls([mnesia], Nodes).
+
+stop_appls([Appl | Appls], Nodes) when is_list(Nodes) ->
+ {Stopped, BadNodes} = rpc:multicall(Nodes, ?MODULE, remote_stop, [Appl]),
+ BadS =[{Node, Appl, Res} || {Node, Res} <- Stopped, Res /= stopped],
+ BadN =[{BadNode, Appl, bad_node} || BadNode <- BadNodes],
+ BadS ++ BadN ++ stop_appls(Appls, Nodes);
+stop_appls([], _Nodes) ->
+ [].
+
+remote_stop(mnesia) ->
+ {node(), mnesia:stop()};
+remote_stop(Appl) ->
+ {node(), application:stop(Appl)}.
+
+remote_kill([Appl | Appls]) ->
+ catch Appl:lkill(),
+ application:stop(Appl),
+ remote_kill(Appls);
+remote_kill([]) ->
+ ok.
+
+%% Abruptly kill Mnesia on all given nodes
+%% Returns []
+kill_appls(Appls, Nodes) when is_list(Nodes) ->
+ verbose("<>WARNING<> Intentionally killing ~p: ~w...~n",
+ [Appls, Nodes], ?FILE, ?LINE),
+ rpc:multicall(Nodes, ?MODULE, remote_kill, [Appls]),
+ [].
+
+kill_mnesia(Nodes) when is_list(Nodes) ->
+ kill_appls([mnesia], Nodes).
+
+reload_appls([Appl | Appls], Selected) ->
+ kill_appls([Appl], Selected),
+ timer:sleep(1000),
+ Ok = {[ok || _N <- Selected], []},
+ {Ok2temp, Empty} = rpc:multicall(Selected, application, unload, [Appl]),
+ Conv = fun({error,{not_loaded,mnesia}}) -> ok; (Else) -> Else end,
+ Ok2 = {lists:map(Conv, Ok2temp), Empty},
+
+ Ok3 = rpc:multicall(Selected, application, load, [Appl]),
+ if
+ Ok /= Ok2 ->
+ ?fatal("Cannot unload appl ~p: ~p~n", [Appl, Ok2]);
+ Ok /= Ok3 ->
+ ?fatal("Cannot load appl ~p: ~p~n", [Appl, Ok3]);
+ true ->
+ ok
+ end,
+ reload_appls(Appls, Selected);
+reload_appls([], _Selected) ->
+ ok.
+
+shutdown() ->
+ log("<>WARNING<> Intentionally shutting down all nodes... ~p~n",
+ [nodes() ++ [node()]]),
+ rpc:multicall(nodes(), erlang, halt, []),
+ erlang:halt().
+
+verify_mnesia(Ups, Downs, File, Line) when is_list(Ups), is_list(Downs) ->
+ BadUps =
+ [N || N <- Ups, rpc:call(N, mnesia, system_info, [is_running]) /= yes],
+ BadDowns =
+ [N || N <- Downs, rpc:call(N, mnesia, system_info, [is_running]) == yes],
+ if
+ BadUps == [] ->
+ ignore;
+ true ->
+ error("Mnesia is not running as expected: ~p~n",
+ [BadUps], File, Line)
+ end,
+ if
+ BadDowns == [] ->
+ ignore;
+ true ->
+ error("Mnesia is not stopped as expected: ~p~n",
+ [BadDowns], File, Line)
+ end,
+ ok.
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+verify_replica_location(Tab, [], [], [], _) ->
+ ?match({'EXIT', _}, mnesia:table_info(Tab, ram_copies)),
+ ?match({'EXIT', _}, mnesia:table_info(Tab, disc_copies)),
+ ?match({'EXIT', _}, mnesia:table_info(Tab, disc_only_copies)),
+ ?match({'EXIT', _}, mnesia:table_info(Tab, where_to_write)),
+ ?match({'EXIT', _}, mnesia:table_info(Tab, where_to_read)),
+ [];
+
+verify_replica_location(Tab, DiscOnly0, Ram0, Disc0, AliveNodes0) ->
+%% sync_tables(AliveNodes0, [Tab]),
+ AliveNodes = lists:sort(AliveNodes0),
+ DiscOnly = lists:sort(DiscOnly0),
+ Ram = lists:sort(Ram0),
+ Disc = lists:sort(Disc0),
+ Write = ignore_dead(DiscOnly ++ Ram ++ Disc, AliveNodes),
+ Read = ignore_dead(DiscOnly ++ Ram ++ Disc, AliveNodes),
+ This = node(),
+
+ timer:sleep(100),
+
+ S1 = ?match(AliveNodes, lists:sort(mnesia:system_info(running_db_nodes))),
+ S2 = ?match(DiscOnly, lists:sort(mnesia:table_info(Tab, disc_only_copies))),
+ S3 = ?match(Ram, lists:sort(mnesia:table_info(Tab, ram_copies))),
+ S4 = ?match(Disc, lists:sort(mnesia:table_info(Tab, disc_copies))),
+ S5 = ?match(Write, lists:sort(mnesia:table_info(Tab, where_to_write))),
+ S6 = case lists:member(This, Read) of
+ true ->
+ ?match(This, mnesia:table_info(Tab, where_to_read));
+ false ->
+ ?match(true, lists:member(mnesia:table_info(Tab, where_to_read), Read))
+ end,
+ lists:filter(fun({success,_}) -> false; (_) -> true end, [S1,S2,S3,S4,S5,S6]).
+
+ignore_dead(Nodes, AliveNodes) ->
+ Filter = fun(Node) -> lists:member(Node, AliveNodes) end,
+ lists:sort(lists:zf(Filter, Nodes)).
+
+
+remote_activate_debug_fun(N, I, F, C, File, Line) ->
+ Pid = spawn_link(N, ?MODULE, do_remote_activate_debug_fun, [self(), I, F, C, File, Line]),
+ receive
+ {activated, Pid} -> ok;
+ {'EXIT', Pid, Reason} -> {error, Reason}
+ end.
+
+do_remote_activate_debug_fun(From, I, F, C, File, Line) ->
+ mnesia_lib:activate_debug_fun(I, F, C, File, Line),
+ From ! {activated, self()},
+ timer:sleep(infinity). % Dies whenever the test process dies !!
+
+
+sort(L) when is_list(L) ->
+ lists:sort(L);
+sort({atomic, L}) when is_list(L) ->
+ {atomic, lists:sort(L)};
+sort({ok, L}) when is_list(L) ->
+ {ok, lists:sort(L)};
+sort(W) ->
+ W.
diff --git a/lib/mnesia/test/mnesia_test_lib.hrl b/lib/mnesia/test/mnesia_test_lib.hrl
new file mode 100644
index 0000000000..85f12200d4
--- /dev/null
+++ b/lib/mnesia/test/mnesia_test_lib.hrl
@@ -0,0 +1,132 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 1996-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%
+%%
+
+%%
+-define(log(Format,Args),mnesia_test_lib:log(Format,Args,?FILE,?LINE)).
+-define(warning(Format,Args),?log("<>WARNING<>~n " ++ Format,Args)).
+-define(error(Format,Args),
+ mnesia_test_lib:error(Format,Args,?FILE,?LINE)).
+-define(verbose(Format,Args),mnesia_test_lib:verbose(Format,Args,?FILE,?LINE)).
+
+-define(fatal(Format,Args),
+ ?error(Format, Args),
+ exit({test_case_fatal, Format, Args, ?FILE, ?LINE})).
+
+-define(skip(Format,Args),
+ ?warning(Format, Args),
+ exit({skipped, ?flat_format(Format, Args)})).
+
+-define(flat_format(Format,Args),
+ lists:flatten(io_lib:format(Format, Args))).
+
+-define(sort(What), mnesia_test_lib:sort(What)).
+
+-define(ignore(Expr),
+ fun() ->
+ AcTuAlReS = (catch (Expr)),
+ ?verbose("ok, ~n Result as expected:~p~n",[AcTuAlReS]),
+ AcTuAlReS
+ end()).
+
+-define(match(ExpectedRes,Expr),
+ fun() ->
+ AcTuAlReS = (catch (Expr)),
+ case AcTuAlReS of
+ ExpectedRes ->
+ ?verbose("ok, ~n Result as expected:~p~n",[AcTuAlReS]),
+ {success,AcTuAlReS};
+ _ ->
+ ?error("Not Matching Actual result was:~n ~p~n",
+ [AcTuAlReS]),
+ {fail,AcTuAlReS}
+ end
+ end()).
+
+-define(match_inverse(NotExpectedRes,Expr),
+ fun() ->
+ AcTuAlReS = (catch (Expr)),
+ case AcTuAlReS of
+ NotExpectedRes ->
+ ?error("Not matching Actual result was:~n ~p~n",
+ [AcTuAlReS]),
+ {fail,AcTuAlReS};
+ _ ->
+ ?verbose("ok, ~n Result as expected: ~p~n",[AcTuAlReS]),
+ {success,AcTuAlReS}
+ end
+ end()).
+
+-define(match_receive(ExpectedMsg),
+ ?match(ExpectedMsg,mnesia_test_lib:pick_msg())).
+
+%% ExpectedMsgs must be completely bound
+-define(match_multi_receive(ExpectedMsgs),
+ fun() ->
+ TmPeXpCtEdMsGs = lists:sort(ExpectedMsgs),
+ ?match(TmPeXpCtEdMsGs,
+ lists:sort(lists:map(fun(_) ->
+ mnesia_test_lib:pick_msg()
+ end,
+ TmPeXpCtEdMsGs)))
+ end()).
+
+-define(start_activities(Nodes),
+ mnesia_test_lib:start_activities(Nodes)).
+
+-define(start_transactions(Pids),
+ mnesia_test_lib:start_transactions(Pids)).
+
+-define(acquire_nodes(N, Config),
+ mnesia_test_lib:prepare_test_case([{init_test_case, [mnesia]},
+ delete_schema,
+ create_schema,
+ {start_appls, [mnesia]}],
+ N, Config, ?FILE, ?LINE)).
+
+-define(activate_debug_fun(I, F, C),
+ mnesia_lib:activate_debug_fun(I, F, C, ?FILE, ?LINE)).
+
+-define(remote_activate_debug_fun(N, I, F, C),
+ ?match(ok, mnesia_test_lib:remote_activate_debug_fun(N, I, F, C,
+ ?FILE, ?LINE))).
+
+-define(deactivate_debug_fun(I),
+ mnesia_lib:deactivate_debug_fun(I, ?FILE, ?LINE)).
+
+-define(remote_deactivate_debug_fun(N, I),
+ rpc:call(N, mnesia_lib, deactivate_debug_fun, [I, ?FILE, ?LINE])).
+
+-define(is_debug_compiled,
+ case mnesia_lib:is_debug_compiled() of
+ false ->
+ ?skip("Mnesia is not debug compiled, test case ignored.~n", []);
+ _OhTeR ->
+ ok
+ end).
+
+-define(needs_disc(Config),
+ case mnesia_test_lib:diskless(Config) of
+ false ->
+ ok;
+ true ->
+ ?skip("Must have disc, test case ignored.~n", [])
+ end).
+
+-define(verify_mnesia(Ups, Downs),
+ mnesia_test_lib:verify_mnesia(Ups, Downs, ?FILE, ?LINE)).
diff --git a/lib/mnesia/test/mnesia_tpcb.erl b/lib/mnesia/test/mnesia_tpcb.erl
new file mode 100644
index 0000000000..903c53a21c
--- /dev/null
+++ b/lib/mnesia/test/mnesia_tpcb.erl
@@ -0,0 +1,1268 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 1996-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
+%%
+%% mnesia_tpcb - TPC-B benchmarking of Mnesia
+%%
+%% DESCRIPTION
+%%
+%% The metrics used in the TPC-B benchmark are throughput as measured
+%% in transactions per second (TPS). The benchmark uses a single,
+%% simple update-intensive transaction to load the database system.
+%% The single transaction type provides a simple, repeatable
+%% unit of work, and is designed to exercise the basic components of
+%% a database system.
+%%
+%% The definition of the TPC-B states lots of detailed rules and
+%% conditions that must be fullfilled, e.g. how the ACID (atomicity,
+%% consistency, isolation and durability) properties are verified,
+%% how the random numbers must be distributed, minimum sizes of
+%% the different types of records, minimum duration of the benchmark,
+%% formulas to calculate prices (dollars per tps), disclosure issues
+%% etc. Please, see http://www.tpc.org/ about the nitty gritty details.
+%%
+%% The TPC-B benchmark is stated in terms of a hypothetical bank. The
+%% bank has one or more branches. Each branch has multiple tellers. The
+%% bank has many customers, each with an account. The database represents
+%% the cash position of each entity (branch, teller and account) and a
+%% history of recent transactions run by the bank. The transaction
+%% represents the work done when a customer makes a deposit or a
+%% withdrawal against his account. The transaction is performed by a
+%% teller at some branch.
+%%
+%% Each process that performs TPC-B transactions is called a driver.
+%% Drivers generates teller_id, account_id and delta amount of
+%% money randomly. An account, a teller and a branch are read, their
+%% balances are adjusted and a history record is created. The driver
+%% measures the time for 3 reads, 3 writes and 1 create.
+%%
+%% GETTING STARTED
+%%
+%% Generate tables and run with default configuration:
+%%
+%% mnesia_tpcb:start().
+%%
+%% A little bit more advanced;
+%%
+%% spawn(mnesia_tpcb, start, [[[{n_drivers_per_node, 8}, {stop_after, infinity}]]),
+%% mnesia_tpcb:stop().
+%%
+%% Really advanced;
+%%
+%% mnesia_tpcb:init(([{n_branches, 8}, {replica_type, disc_only_copies}]),
+%% mnesia_tpcb:run(([{n_drivers_per_node, 8}]),
+%% mnesia_tpcb:run(([{n_drivers_per_node, 64}]).
+%%
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+-module(mnesia_tpcb).
+-author('[email protected]').
+
+-export([
+ config/2,
+ count_balance/0,
+ driver_init/2,
+ init/1,
+ reporter_init/2,
+ run/1,
+ start/0,
+ start/1,
+ start/2,
+ stop/0,
+ real_trans/5,
+ verify_tabs/0,
+ reply_gen_branch/3,
+ frag_add_delta/7,
+
+ conflict_test/1,
+ dist_test/1,
+ replica_test/1,
+ sticky_replica_test/1,
+ remote_test/1,
+ remote_frag2_test/1
+ ]).
+
+-define(SECOND, 1000000).
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%%% Account record, total size must be at least 100 bytes
+
+-define(ACCOUNT_FILLER,
+ {123456789012345678901234567890123456789012345678901234567890,
+ 123456789012345678901234567890123456789012345678901234567890,
+ 123456789012345678901234567890123456789012345678901234}).
+
+-record(account,
+ {
+ id = 0, % Unique account id
+ branch_id = 0, % Branch where the account is held
+ balance = 0, % Account balance
+ filler = ?ACCOUNT_FILLER % Gap filler to ensure size >= 100 bytes
+ }).
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%%% Branch record, total size must be at least 100 bytes
+
+-define(BRANCH_FILLER,
+ {123456789012345678901234567890123456789012345678901234567890,
+ 123456789012345678901234567890123456789012345678901234567890,
+ 123456789012345678901234567890123456789012345678901234567890}).
+
+-record(branch,
+ {
+ id = 0, % Unique branch id
+ balance = 0, % Total balance of whole branch
+ filler = ?BRANCH_FILLER % Gap filler to ensure size >= 100 bytes
+ }).
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%%% Teller record, total size must be at least 100 bytes
+
+-define(TELLER_FILLER,
+ {123456789012345678901234567890123456789012345678901234567890,
+ 123456789012345678901234567890123456789012345678901234567890,
+ 1234567890123456789012345678901234567890123456789012345678}).
+
+-record(teller,
+ {
+ id = 0, % Unique teller id
+ branch_id = 0, % Branch where the teller is located
+ balance = 0, % Teller balance
+ filler = ?TELLER_FILLER % Gap filler to ensure size >= 100 bytes
+ }).
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%%% History record, total size must be at least 50 bytes
+
+-define(HISTORY_FILLER, 1234567890).
+
+-record(history,
+ {
+ history_id = {0, 0}, % {DriverId, DriverLocalHistoryid}
+ time_stamp = now(), % Time point during active transaction
+ branch_id = 0, % Branch associated with teller
+ teller_id = 0, % Teller invlolved in transaction
+ account_id = 0, % Account updated by transaction
+ amount = 0, % Amount (delta) specified by transaction
+ filler = ?HISTORY_FILLER % Gap filler to ensure size >= 50 bytes
+ }).
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+-record(tab_config,
+ {
+ db_nodes = [node()],
+ n_replicas = 1, % Ignored for non-fragmented tables
+ replica_nodes = [node()],
+ replica_type = ram_copies,
+ use_running_mnesia = false,
+ n_fragments = 0,
+ n_branches = 1,
+ n_tellers_per_branch = 10, % Must be 10
+ n_accounts_per_branch = 100000, % Must be 100000
+ branch_filler = ?BRANCH_FILLER,
+ account_filler = ?ACCOUNT_FILLER,
+ teller_filler = ?TELLER_FILLER
+ }).
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+-record(run_config,
+ {
+ driver_nodes = [node()],
+ n_drivers_per_node = 1,
+ use_running_mnesia = false,
+ stop_after = timer:minutes(15), % Minimum 15 min
+ report_interval = timer:minutes(1),
+ use_sticky_locks = false,
+ spawn_near_branch = false,
+ activity_type = transaction,
+ reuse_history_id = false
+ }).
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+-record(time,
+ {
+ n_trans = 0,
+ min_n = 0,
+ max_n = 0,
+ acc_time = 0,
+ max_time = 0
+ }).
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+-record(driver_state,
+ {
+ driver_id,
+ driver_node,
+ seed,
+ n_local_branches,
+ local_branches,
+ tab_config,
+ run_config,
+ history_id,
+ time = #time{},
+ acc_time = #time{},
+ reuse_history_id
+ }).
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+-record(reporter_state,
+ {
+ driver_pids,
+ starter_pid,
+ n_iters = 0,
+ prev_tps = 0,
+ curr = #time{},
+ acc = #time{},
+ init_micros,
+ prev_micros,
+ run_config
+ }).
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%% One driver on each node, table not replicated
+
+config(frag_test, ReplicaType) ->
+ Remote = nodes(),
+ Local = node(),
+ Nodes = [Local | Remote],
+ [
+ {n_branches, length(Nodes)},
+ {n_fragments, length(Nodes)},
+ {replica_nodes, Nodes},
+ {db_nodes, Nodes},
+ {driver_nodes, Nodes},
+ {n_accounts_per_branch, 100},
+ {replica_type, ReplicaType},
+ {stop_after, timer:minutes(1)},
+ {report_interval, timer:seconds(10)},
+ {reuse_history_id, true}
+ ];
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%% One driver on each node, table replicated to two nodes.
+
+config(frag2_test, ReplicaType) ->
+ Remote = nodes(),
+ Local = node(),
+ Nodes = [Local | Remote],
+ [
+ {n_branches, length(Nodes)},
+ {n_fragments, length(Nodes)},
+ {n_replicas, 2},
+ {replica_nodes, Nodes},
+ {db_nodes, Nodes},
+ {driver_nodes, Nodes},
+ {n_accounts_per_branch, 100},
+ {replica_type, ReplicaType},
+ {stop_after, timer:minutes(1)},
+ {report_interval, timer:seconds(10)},
+ {reuse_history_id, true}
+ ];
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%% One driver on this node, table replicated to all nodes.
+
+config(replica_test, ReplicaType) ->
+ Remote = nodes(),
+ Local = node(),
+ Nodes = [Local | Remote],
+ [
+ {db_nodes, Nodes},
+ {driver_nodes, [Local]},
+ {replica_nodes, Nodes},
+ {n_accounts_per_branch, 100},
+ {replica_type, ReplicaType},
+ {stop_after, timer:minutes(1)},
+ {report_interval, timer:seconds(10)},
+ {reuse_history_id, true}
+ ];
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%% One driver on this node, table replicated to all nodes.
+
+config(sticky_replica_test, ReplicaType) ->
+ Remote = nodes(),
+ Local = node(),
+ Nodes = [Local | Remote],
+ [
+ {db_nodes, Nodes},
+ {driver_nodes, [node()]},
+ {replica_nodes, Nodes},
+ {n_accounts_per_branch, 100},
+ {replica_type, ReplicaType},
+ {use_sticky_locks, true},
+ {stop_after, timer:minutes(1)},
+ {report_interval, timer:seconds(10)},
+ {reuse_history_id, true}
+ ];
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%% Ten drivers per node, tables replicated to all nodes, lots of branches
+
+config(dist_test, ReplicaType) ->
+ Remote = nodes(),
+ Local = node(),
+ Nodes = [Local | Remote],
+ [
+ {db_nodes, Nodes},
+ {driver_nodes, Nodes},
+ {replica_nodes, Nodes},
+ {n_drivers_per_node, 10},
+ {n_branches, 10 * length(Nodes) * 100},
+ {n_accounts_per_branch, 10},
+ {replica_type, ReplicaType},
+ {stop_after, timer:minutes(1)},
+ {report_interval, timer:seconds(10)},
+ {reuse_history_id, true}
+ ];
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%% Ten drivers per node, tables replicated to all nodes, single branch
+
+config(conflict_test, ReplicaType) ->
+ Remote = nodes(),
+ Local = node(),
+ Nodes = [Local | Remote],
+ [
+ {db_nodes, Nodes},
+ {driver_nodes, Nodes},
+ {replica_nodes, Nodes},
+ {n_drivers_per_node, 10},
+ {n_branches, 1},
+ {n_accounts_per_branch, 10},
+ {replica_type, ReplicaType},
+ {stop_after, timer:minutes(1)},
+ {report_interval, timer:seconds(10)},
+ {reuse_history_id, true}
+ ];
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%% One driver on this node, table replicated to all other nodes.
+
+config(remote_test, ReplicaType) ->
+ Remote = nodes(),
+ Local = node(),
+ Nodes = [Local | Remote],
+ [
+ {db_nodes, Nodes},
+ {driver_nodes, [Local]},
+ {replica_nodes, Remote},
+ {n_accounts_per_branch, 100},
+ {replica_type, ReplicaType},
+ {stop_after, timer:minutes(1)},
+ {report_interval, timer:seconds(10)},
+ {reuse_history_id, true}
+ ];
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%% One driver on this node, table replicated to two other nodes.
+
+config(remote_frag2_test, ReplicaType) ->
+ Remote = nodes(),
+ Local = node(),
+ Nodes = [Local | Remote],
+ [
+ {n_branches, length(Remote)},
+ {n_fragments, length(Remote)},
+ {n_replicas, 2},
+ {replica_nodes, Remote},
+ {db_nodes, Nodes},
+ {driver_nodes, [Local]},
+ {n_accounts_per_branch, 100},
+ {replica_type, ReplicaType},
+ {stop_after, timer:minutes(1)},
+ {report_interval, timer:seconds(10)},
+ {reuse_history_id, true}
+ ].
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+start(What, ReplicaType) ->
+ spawn_link(?MODULE, start, [config(What, ReplicaType)]).
+
+replica_test(ReplicaType) ->
+ start(replica_test, ReplicaType).
+
+sticky_replica_test(ReplicaType) ->
+ start(sticky_replica_test, ReplicaType).
+
+dist_test(ReplicaType) ->
+ start(dist_test, ReplicaType).
+
+conflict_test(ReplicaType) ->
+ start(conflict_test, ReplicaType).
+
+remote_test(ReplicaType) ->
+ start(remote_test, ReplicaType).
+
+remote_frag2_test(ReplicaType) ->
+ start(remote_frag2_test, ReplicaType).
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%% Args is a list of {Key, Val} tuples where Key is a field name
+%% in either the record tab_config or run_config. Unknown keys are ignored.
+
+start() ->
+ start([]).
+start(Args) ->
+ init(Args),
+ run(Args).
+
+list2rec(List, Fields, DefaultTuple) ->
+ [Name|Defaults] = tuple_to_list(DefaultTuple),
+ List2 = list2rec(List, Fields, Defaults, []),
+ list_to_tuple([Name] ++ List2).
+
+list2rec(_List, [], [], Acc) ->
+ Acc;
+list2rec(List, [F|Fields], [D|Defaults], Acc) ->
+ {Val, List2} =
+ case lists:keysearch(F, 1, List) of
+ false ->
+ {D, List};
+ {value, {F, NewVal}} ->
+ {NewVal, lists:keydelete(F, 1, List)}
+ end,
+ list2rec(List2, Fields, Defaults, Acc ++ [Val]).
+
+stop() ->
+ case whereis(mnesia_tpcb) of
+ undefined ->
+ {error, not_running};
+ Pid ->
+ sync_stop(Pid)
+ end.
+
+sync_stop(Pid) ->
+ Pid ! {self(), stop},
+ receive
+ {Pid, {stopped, Res}} -> Res
+ after timer:minutes(1) ->
+ exit(Pid, kill),
+ {error, brutal_kill}
+ end.
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%%% Initialization
+
+%% Args is a list of {Key, Val} tuples where Key is a field name
+%% in the record tab_config, unknown keys are ignored.
+
+init(Args) ->
+ TabConfig0 = list2rec(Args, record_info(fields, tab_config), #tab_config{}),
+ TabConfig =
+ if
+ TabConfig0#tab_config.n_fragments =:= 0 ->
+ TabConfig0#tab_config{n_replicas = length(TabConfig0#tab_config.replica_nodes)};
+ true ->
+ TabConfig0
+ end,
+ Tags = record_info(fields, tab_config),
+ Fun = fun(F, Pos) -> {{F, element(Pos, TabConfig)}, Pos + 1} end,
+ {List, _} = lists:mapfoldl(Fun, 2, Tags),
+ io:format("TPC-B: Table config: ~p ~n", [List]),
+
+ DbNodes = TabConfig#tab_config.db_nodes,
+ stop(),
+ if
+ TabConfig#tab_config.use_running_mnesia =:= true ->
+ ignore;
+ true ->
+ rpc:multicall(DbNodes, mnesia, lkill, []),
+ case mnesia:delete_schema(DbNodes) of
+ ok ->
+ case mnesia:create_schema(DbNodes) of
+ ok ->
+ {Replies, BadNodes} =
+ rpc:multicall(DbNodes, mnesia, start, []),
+ case [Res || Res <- Replies, Res =/= ok] of
+ [] when BadNodes =:= [] ->
+ ok;
+ BadRes ->
+ io:format("TPC-B: <ERROR> "
+ "Failed to start ~p: ~p~n",
+ [BadNodes, BadRes]),
+ exit({start_failed, BadRes, BadNodes})
+ end;
+ {error, Reason} ->
+ io:format("TPC-B: <ERROR> "
+ "Failed to create schema on disc: ~p~n",
+ [Reason]),
+ exit({create_schema_failed, Reason})
+ end;
+ {error, Reason} ->
+ io:format("TPC-B: <ERROR> "
+ "Failed to delete schema on disc: ~p~n",
+ [Reason]),
+ exit({delete_schema_failed, Reason})
+ end
+ end,
+ gen_tabs(TabConfig).
+
+gen_tabs(TC) ->
+ create_tab(TC, branch, record_info(fields, branch),
+ undefined),
+ create_tab(TC, account, record_info(fields, account),
+ {branch, #account.branch_id}),
+ create_tab(TC, teller, record_info(fields, teller),
+ {branch, #teller.branch_id}),
+ create_tab(TC, history, record_info(fields, history),
+ {branch, #history.branch_id}),
+
+ NB = TC#tab_config.n_branches,
+ NT = TC#tab_config.n_tellers_per_branch,
+ NA = TC#tab_config.n_accounts_per_branch,
+ io:format("TPC-B: Generating ~p branches a ~p bytes~n",
+ [NB, size(term_to_binary(default_branch(TC)))]),
+ io:format("TPC-B: Generating ~p * ~p tellers a ~p bytes~n",
+ [NB, NT, size(term_to_binary(default_teller(TC)))]),
+ io:format("TPC-B: Generating ~p * ~p accounts a ~p bytes~n",
+ [NB, NA, size(term_to_binary(default_account(TC)))]),
+ io:format("TPC-B: Generating 0 history records a ~p bytes~n",
+ [size(term_to_binary(default_history(TC)))]),
+ gen_branches(TC),
+
+ case verify_tabs() of
+ ok ->
+ ignore;
+ {error, Reason} ->
+ io:format("TPC-B: <ERROR> Inconsistent tables: ~w~n",
+ [Reason]),
+ exit({inconsistent_tables, Reason})
+ end.
+
+create_tab(TC, Name, Attrs, _ForeignKey) when TC#tab_config.n_fragments =:= 0 ->
+ Nodes = TC#tab_config.replica_nodes,
+ Type = TC#tab_config.replica_type,
+ Def = [{Type, Nodes}, {attributes, Attrs}],
+ create_tab(Name, Def);
+create_tab(TC, Name, Attrs, ForeignKey) ->
+ NReplicas = TC#tab_config.n_replicas,
+ NodePool = TC#tab_config.replica_nodes,
+ Type = TC#tab_config.replica_type,
+ NF = TC#tab_config.n_fragments,
+ Props = [{n_fragments, NF},
+ {node_pool, NodePool},
+ {n_copies(Type), NReplicas},
+ {foreign_key, ForeignKey}],
+ Def = [{frag_properties, Props},
+ {attributes, Attrs}],
+ create_tab(Name, Def).
+
+create_tab(Name, Def) ->
+ mnesia:delete_table(Name),
+ case mnesia:create_table(Name, Def) of
+ {atomic, ok} ->
+ ok;
+ {aborted, Reason} ->
+ io:format("TPC-B: <ERROR> failed to create table ~w ~w: ~p~n",
+ [Name, Def, Reason]),
+ exit({create_table_failed, Reason})
+ end.
+
+n_copies(Type) ->
+ case Type of
+ ram_copies -> n_ram_copies;
+ disc_copies -> n_disc_copies;
+ disc_only_copies -> n_disc_only_copies
+ end.
+
+gen_branches(TC) ->
+ First = 0,
+ Last = First + TC#tab_config.n_branches - 1,
+ GenPids = gen_branches(TC, First, Last, []),
+ wait_for_gen(GenPids).
+
+wait_for_gen([]) ->
+ ok;
+wait_for_gen(Pids) ->
+ receive
+ {branch_generated, Pid} -> wait_for_gen(lists:delete(Pid, Pids));
+ Exit ->
+ exit({tpcb_failed, Exit})
+ end.
+
+gen_branches(TC, BranchId, Last, UsedNs) when BranchId =< Last ->
+ UsedNs2 = get_branch_nodes(BranchId, UsedNs),
+ Node = hd(UsedNs2),
+ Pid = spawn_link(Node, ?MODULE, reply_gen_branch,
+ [self(), TC, BranchId]),
+ [Pid | gen_branches(TC, BranchId + 1, Last, UsedNs2)];
+gen_branches(_, _, _, _) ->
+ [].
+
+reply_gen_branch(ReplyTo, TC, BranchId) ->
+ gen_branch(TC, BranchId),
+ ReplyTo ! {branch_generated, self()},
+ unlink(ReplyTo).
+
+%% Returns a new list of nodes with the best node as head
+get_branch_nodes(BranchId, UsedNs) ->
+ WriteNs = table_info({branch, BranchId}, where_to_write),
+ WeightedNs = [{n_duplicates(N, UsedNs, 0), N} || N <- WriteNs],
+ [{_, LeastUsed} | _ ] = lists:sort(WeightedNs),
+ [LeastUsed | UsedNs].
+
+n_duplicates(_N, [], Count) ->
+ Count;
+n_duplicates(N, [N | Tail], Count) ->
+ n_duplicates(N, Tail, Count + 1);
+n_duplicates(N, [_ | Tail], Count) ->
+ n_duplicates(N, Tail, Count).
+
+gen_branch(TC, BranchId) ->
+ A = default_account(TC),
+ NA = TC#tab_config.n_accounts_per_branch,
+ FirstA = BranchId * NA,
+ ArgsA = [FirstA, FirstA + NA - 1, BranchId, A],
+ ok = mnesia:activity(async_dirty, fun gen_accounts/4, ArgsA, mnesia_frag),
+
+ T = default_teller(TC),
+ NT = TC#tab_config.n_tellers_per_branch,
+ FirstT = BranchId * NT,
+ ArgsT = [FirstT, FirstT + NT - 1, BranchId, T],
+ ok = mnesia:activity(async_dirty, fun gen_tellers/4, ArgsT, mnesia_frag),
+
+ B = default_branch(TC),
+ FunB = fun() -> mnesia:write(branch, B#branch{id = BranchId}, write) end,
+ ok = mnesia:activity(sync_dirty, FunB, [], mnesia_frag).
+
+gen_tellers(Id, Last, BranchId, T) when Id =< Last ->
+ mnesia:write(teller, T#teller{id = Id, branch_id=BranchId}, write),
+ gen_tellers(Id + 1, Last, BranchId, T);
+gen_tellers(_, _, _, _) ->
+ ok.
+
+gen_accounts(Id, Last, BranchId, A) when Id =< Last ->
+ mnesia:write(account, A#account{id = Id, branch_id=BranchId}, write),
+ gen_accounts(Id + 1, Last, BranchId, A);
+gen_accounts(_, _, _, _) ->
+ ok.
+
+default_branch(TC) -> #branch{filler = TC#tab_config.branch_filler}.
+default_teller(TC) -> #teller{filler = TC#tab_config.teller_filler}.
+default_account(TC) -> #account{filler = TC#tab_config.account_filler}.
+default_history(_TC) -> #history{}.
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%%% Run the benchmark
+
+%% Args is a list of {Key, Val} tuples where Key is a field name
+%% in the record run_config, unknown keys are ignored.
+run(Args) ->
+ RunConfig = list2rec(Args, record_info(fields, run_config), #run_config{}),
+ Tags = record_info(fields, run_config),
+ Fun = fun(F, Pos) -> {{F, element(Pos, RunConfig)}, Pos + 1} end,
+ {List, _} = lists:mapfoldl(Fun, 2, Tags),
+ io:format("TPC-B: Run config: ~p ~n", [List]),
+
+ Pid = spawn_link(?MODULE, reporter_init, [self(), RunConfig]),
+ receive
+ {Pid, {stopped, Res}} ->
+ Res; % Stopped by other process
+ Else ->
+ {tpcb_got, Else}
+ after RunConfig#run_config.stop_after ->
+ sync_stop(Pid)
+ end.
+
+reporter_init(Starter, RC) ->
+ register(mnesia_tpcb, self()),
+ process_flag(trap_exit, true),
+ DbNodes = mnesia:system_info(db_nodes),
+ if
+ RC#run_config.use_running_mnesia =:= true ->
+ ignore;
+ true ->
+ {Replies, BadNodes} =
+ rpc:multicall(DbNodes, mnesia, start, []),
+ case [Res || Res <- Replies, Res =/= ok] of
+ [] when BadNodes =:= [] ->
+ ok;
+ BadRes ->
+ io:format("TPC-B: <ERROR> "
+ "Failed to start ~w: ~p~n",
+ [BadNodes, BadRes]),
+ exit({start_failed, BadRes, BadNodes})
+ end,
+ verify_tabs()
+ end,
+
+ N = table_info(branch, size),
+ NT = table_info(teller, size) div N,
+ NA = table_info(account, size) div N,
+
+ {Type, NF, RepNodes} = table_storage(branch),
+ TC = #tab_config{n_fragments = NF,
+ n_branches = N,
+ n_tellers_per_branch = NT,
+ n_accounts_per_branch = NA,
+ db_nodes = DbNodes,
+ replica_nodes = RepNodes,
+ replica_type = Type
+ },
+ Drivers = start_drivers(RC, TC),
+ Now = now_to_micros(erlang:now()),
+ State = #reporter_state{driver_pids = Drivers,
+ run_config = RC,
+ starter_pid = Starter,
+ init_micros = Now,
+ prev_micros = Now
+ },
+ case catch reporter_loop(State) of
+ {'EXIT', Reason} ->
+ io:format("TPC-B: Abnormal termination: ~p~n", [Reason]),
+ if
+ RC#run_config.use_running_mnesia =:= true ->
+ ignore;
+ true ->
+ rpc:multicall(DbNodes, mnesia, lkill, [])
+ end,
+ unlink(Starter),
+ Starter ! {self(), {stopped, {error, Reason}}}, % To be sure
+ exit(shutdown);
+ {ok, Stopper, State2} ->
+ Time = State2#reporter_state.acc,
+ Res =
+ case verify_tabs() of
+ ok ->
+ {ok, Time};
+ {error, Reason} ->
+ io:format("TPC-B: <ERROR> Inconsistent tables, ~p~n",
+ [{error, Reason}]),
+ {error, Reason}
+ end,
+ if
+ RC#run_config.use_running_mnesia =:= true ->
+ ignore;
+ true ->
+ rpc:multicall(DbNodes, mnesia, stop, [])
+ end,
+ unlink(Starter),
+ Starter ! {self(), {stopped, Res}},
+ if
+ Stopper =/= Starter ->
+ Stopper ! {self(), {stopped, Res}};
+ true ->
+ ignore
+ end,
+ exit(shutdown)
+ end.
+
+table_info(Tab, Item) ->
+ Fun = fun() -> mnesia:table_info(Tab, Item) end,
+ mnesia:activity(sync_dirty, Fun, mnesia_frag).
+
+%% Returns {Storage, NFragments, ReplicaNodes}
+table_storage(Tab) ->
+ case mnesia:table_info(branch, frag_properties) of
+ [] ->
+ NFO = 0,
+ NR = length(mnesia:table_info(Tab, ram_copies)),
+ ND = length(mnesia:table_info(Tab, disc_copies)),
+ NDO = length(mnesia:table_info(Tab, disc_only_copies)),
+ if
+ NR =/= 0 -> {ram_copies, NFO, NR};
+ ND =/= 0 -> {disc_copies, NFO, ND};
+ NDO =/= 0 -> {disc_copies, NFO, NDO}
+ end;
+ Props ->
+ {value, NFO} = lists:keysearch(n_fragments, 1, Props),
+ NR = table_info(Tab, n_ram_copies),
+ ND = table_info(Tab, n_disc_copies),
+ NDO = table_info(Tab, n_disc_only_copies),
+ if
+ NR =/= 0 -> {ram_copies, NFO, NR};
+ ND =/= 0 -> {disc_copies, NFO, ND};
+ NDO =/= 0 -> {disc_copies, NFO, NDO}
+ end
+ end.
+
+reporter_loop(State) ->
+ RC = State#reporter_state.run_config,
+ receive
+ {From, stop} ->
+ {ok, From, call_drivers(State, stop)};
+ {'EXIT', Pid, Reason} when Pid =:= State#reporter_state.starter_pid ->
+ %% call_drivers(State, stop),
+ exit({starter_died, Pid, Reason})
+ after RC#run_config.report_interval ->
+ Iters = State#reporter_state.n_iters,
+ State2 = State#reporter_state{n_iters = Iters + 1},
+ case call_drivers(State2, report) of
+ State3 when State3#reporter_state.driver_pids =/= [] ->
+ State4 = State3#reporter_state{curr = #time{}},
+ reporter_loop(State4);
+ _ ->
+ exit(drivers_died)
+ end
+ end.
+
+call_drivers(State, Msg) ->
+ Drivers = State#reporter_state.driver_pids,
+ lists:foreach(fun(Pid) -> Pid ! {self(), Msg} end, Drivers),
+ State2 = show_report(calc_reports(Drivers, State)),
+ case Msg =:= stop of
+ true ->
+ Acc = State2#reporter_state.acc,
+ Init = State2#reporter_state.init_micros,
+ show_report(State2#reporter_state{n_iters = 0,
+ curr = Acc,
+ prev_micros = Init});
+ false ->
+ ignore
+ end,
+ State2.
+
+calc_reports([], State) ->
+ State;
+calc_reports([Pid|Drivers], State) ->
+ receive
+ {'EXIT', P, Reason} when P =:= State#reporter_state.starter_pid ->
+ exit({starter_died, P, Reason});
+ {'EXIT', Pid, Reason} ->
+ exit({driver_died, Pid, Reason});
+ {Pid, Time} when is_record(Time, time) ->
+ %% io:format("~w: ~w~n", [Pid, Time]),
+ A = add_time(State#reporter_state.acc, Time),
+ C = add_time(State#reporter_state.curr, Time),
+ State2 = State#reporter_state{acc = A, curr = C},
+ calc_reports(Drivers, State2)
+ end.
+
+add_time(Acc, New) ->
+ Acc#time{n_trans = New#time.n_trans + Acc#time.n_trans,
+ min_n = lists:min([New#time.n_trans, Acc#time.min_n] -- [0]),
+ max_n = lists:max([New#time.n_trans, Acc#time.max_n]),
+ acc_time = New#time.acc_time + Acc#time.acc_time,
+ max_time = lists:max([New#time.max_time, Acc#time.max_time])}.
+
+-define(AVOID_DIV_ZERO(_What_), try (_What_) catch _:_ -> 0 end).
+
+show_report(State) ->
+ Now = now_to_micros(erlang:now()),
+ Iters = State#reporter_state.n_iters,
+ Time = State#reporter_state.curr,
+ Max = Time#time.max_time,
+ N = Time#time.n_trans,
+ Avg = ?AVOID_DIV_ZERO(Time#time.acc_time div N),
+ AliveN = length(State#reporter_state.driver_pids),
+ Tps = ?AVOID_DIV_ZERO((?SECOND * AliveN) div Avg),
+ PrevTps= State#reporter_state.prev_tps,
+ {DiffSign, DiffTps} = signed_diff(Iters, Tps, PrevTps),
+ Unfairness = ?AVOID_DIV_ZERO(Time#time.max_n / Time#time.min_n),
+ BruttoAvg = ?AVOID_DIV_ZERO((Now - State#reporter_state.prev_micros) div N),
+%% io:format("n_iters=~p, n_trans=~p, n_drivers=~p, avg=~p, now=~p, prev=~p~n",
+%% [Iters, N, AliveN, BruttoAvg, Now, State#reporter_state.prev_micros]),
+ BruttoTps = ?AVOID_DIV_ZERO(?SECOND div BruttoAvg),
+ case Iters > 0 of
+ true ->
+ io:format("TPC-B: ~p iter ~s~p diff ~p (~p) tps ~p avg micros ~p max micros ~p unfairness~n",
+ [Iters, DiffSign, DiffTps, Tps, BruttoTps, Avg, Max, Unfairness]);
+ false ->
+ io:format("TPC-B: ~p (~p) transactions per second, "
+ "duration of longest transaction was ~p milliseconds~n",
+ [Tps, BruttoTps, Max div 1000])
+ end,
+ State#reporter_state{prev_tps = Tps, prev_micros = Now}.
+
+signed_diff(Iters, Curr, Prev) ->
+ case Iters > 1 of
+ true -> sign(Curr - Prev);
+ false -> sign(0)
+ end.
+
+sign(N) when N > 0 -> {"+", N};
+sign(N) -> {"", N}.
+
+now_to_micros({Mega, Secs, Micros}) ->
+ DT = calendar:now_to_datetime({Mega, Secs, 0}),
+ S = calendar:datetime_to_gregorian_seconds(DT),
+ (S * ?SECOND) + Micros.
+
+start_drivers(RC, TC) ->
+ LastHistoryId = table_info(history, size),
+ Reuse = RC#run_config.reuse_history_id,
+ DS = #driver_state{tab_config = TC,
+ run_config = RC,
+ n_local_branches = 0,
+ local_branches = [],
+ history_id = LastHistoryId,
+ reuse_history_id = Reuse},
+ Nodes = RC#run_config.driver_nodes,
+ NB = TC#tab_config.n_branches,
+ First = 0,
+ AllBranches = lists:seq(First, First + NB - 1),
+ ND = RC#run_config.n_drivers_per_node,
+ Spawn = fun(Spec) ->
+ Node = Spec#driver_state.driver_node,
+ spawn_link(Node, ?MODULE, driver_init, [Spec, AllBranches])
+ end,
+ Specs = [DS#driver_state{driver_id = Id, driver_node = N}
+ || N <- Nodes,
+ Id <- lists:seq(1, ND)],
+ Specs2 = lists:sort(lists:flatten(Specs)),
+ {Specs3, OrphanBranches} = alloc_local_branches(AllBranches, Specs2, []),
+ case length(OrphanBranches) of
+ N when N =< 10 ->
+ io:format("TPC-B: Orphan branches: ~p~n", [OrphanBranches]);
+ N ->
+ io:format("TPC-B: Orphan branches: ~p~n", [N])
+ end,
+ [Spawn(Spec) || Spec <- Specs3].
+
+alloc_local_branches([BranchId | Tail], Specs, OrphanBranches) ->
+ Nodes = table_info({branch, BranchId}, where_to_write),
+ LocalSpecs = [DS || DS <- Specs,
+ lists:member(DS#driver_state.driver_node, Nodes)],
+ case lists:keysort(#driver_state.n_local_branches, LocalSpecs) of
+ [] ->
+ alloc_local_branches(Tail, Specs, [BranchId | OrphanBranches]);
+ [DS | _] ->
+ LocalNB = DS#driver_state.n_local_branches + 1,
+ LocalBranches = [BranchId | DS#driver_state.local_branches],
+ DS2 = DS#driver_state{n_local_branches = LocalNB,
+ local_branches = LocalBranches},
+ Specs2 = Specs -- [DS],
+ Specs3 = [DS2 | Specs2],
+ alloc_local_branches(Tail, Specs3, OrphanBranches)
+ end;
+alloc_local_branches([], Specs, OrphanBranches) ->
+ {Specs, OrphanBranches}.
+
+driver_init(DS, AllBranches) ->
+ Seed = erlang:now(),
+ DS2 =
+ if
+ DS#driver_state.n_local_branches =:= 0 ->
+ DS#driver_state{seed = Seed,
+ n_local_branches = length(AllBranches),
+ local_branches = AllBranches};
+ true ->
+ DS#driver_state{seed = Seed}
+ end,
+ io:format("TPC-B: Driver ~p started as ~p on node ~p with ~p local branches~n",
+ [DS2#driver_state.driver_id, self(), node(), DS2#driver_state.n_local_branches]),
+ driver_loop(DS2).
+
+driver_loop(DS) ->
+ receive
+ {From, report} ->
+ From ! {self(), DS#driver_state.time},
+ Acc = add_time(DS#driver_state.time, DS#driver_state.acc_time),
+ DS2 = DS#driver_state{time=#time{}, acc_time = Acc}, % Reset timer
+ DS3 = calc_trans(DS2),
+ driver_loop(DS3);
+ {From, stop} ->
+ Acc = add_time(DS#driver_state.time, DS#driver_state.acc_time),
+ io:format("TPC-B: Driver ~p (~p) on node ~p stopped: ~w~n",
+ [DS#driver_state.driver_id, self(), node(self()), Acc]),
+ From ! {self(), DS#driver_state.time},
+ unlink(From),
+ exit(stopped)
+ after 0 ->
+ DS2 = calc_trans(DS),
+ driver_loop(DS2)
+ end.
+
+calc_trans(DS) ->
+ {Micros, DS2} = time_trans(DS),
+ Time = DS2#driver_state.time,
+ Time2 = Time#time{n_trans = Time#time.n_trans + 1,
+ acc_time = Time#time.acc_time + Micros,
+ max_time = lists:max([Micros, Time#time.max_time])
+ },
+ case DS#driver_state.reuse_history_id of
+ false ->
+ HistoryId = DS#driver_state.history_id + 1,
+ DS2#driver_state{time=Time2, history_id = HistoryId};
+ true ->
+ DS2#driver_state{time=Time2}
+ end.
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+%% Generate teller_id, account_id and delta
+%% Time the TPC-B transaction
+time_trans(DS) ->
+ OldSeed = get(random_seed), % Avoid interference with Mnesia
+ put(random_seed, DS#driver_state.seed),
+ Random = random:uniform(),
+ NewSeed = get(random_seed),
+ case OldSeed of
+ undefined -> erase(random_seed);
+ _ -> put(random_seed, OldSeed)
+ end,
+
+ TC = DS#driver_state.tab_config,
+ RC = DS#driver_state.run_config,
+ {Branchid, Args} = random_to_args(Random, DS),
+ {Fun, Mod} = trans_type(TC, RC),
+ {Time, Res} = timer:tc(?MODULE, real_trans, [RC, Branchid, Fun, Args, Mod]),
+
+ case Res of
+ AccountBal when is_integer(AccountBal) ->
+ {Time, DS#driver_state{seed = NewSeed}};
+ Other ->
+ exit({crash, Other, Args, Random, DS})
+ end.
+
+random_to_args(Random, DS) ->
+ DriverId = DS#driver_state.driver_id,
+ TC = DS#driver_state.tab_config,
+ HistoryId = DS#driver_state.history_id,
+ Delta = trunc(Random * 1999998) - 999999, % -999999 <= Delta <= +999999
+
+ Branches = DS#driver_state.local_branches,
+ NB = DS#driver_state.n_local_branches,
+ NT = TC#tab_config.n_tellers_per_branch,
+ NA = TC#tab_config.n_accounts_per_branch,
+ Tmp = trunc(Random * NB * NT),
+ BranchPos = (Tmp div NT) + 1,
+ BranchId =
+ case TC#tab_config.n_fragments of
+ 0 -> BranchPos - 1;
+ _ -> lists:nth(BranchPos, Branches)
+ end,
+ RelativeTellerId = Tmp div NT,
+ TellerId = (BranchId * NT) + RelativeTellerId,
+ {AccountBranchId, AccountId} =
+ if
+ Random >= 0.85, NB > 1 ->
+ %% Pick from a remote account
+ TmpAccountId= trunc(Random * (NB - 1) * NA),
+ TmpAccountBranchId = TmpAccountId div NA,
+ if
+ TmpAccountBranchId =:= BranchId ->
+ {TmpAccountBranchId + 1, TmpAccountId + NA};
+ true ->
+ {TmpAccountBranchId, TmpAccountId}
+ end;
+ true ->
+ %% Pick from a local account
+ RelativeAccountId = trunc(Random * NA),
+ TmpAccountId = (BranchId * NA) + RelativeAccountId,
+ {BranchId, TmpAccountId}
+ end,
+
+ {BranchId, [DriverId, BranchId, TellerId, AccountBranchId, AccountId, HistoryId, Delta]}.
+
+real_trans(RC, BranchId, Fun, Args, Mod) ->
+ Type = RC#run_config.activity_type,
+ case RC#run_config.spawn_near_branch of
+ false ->
+ mnesia:activity(Type, Fun, Args, Mod);
+ true ->
+ Node = table_info({branch, BranchId}, where_to_read),
+ case rpc:call(Node, mnesia, activity, [Type, Fun, Args, Mod]) of
+ {badrpc, Reason} -> exit(Reason);
+ Other -> Other
+ end
+ end.
+
+trans_type(TC, RC) ->
+ if
+ TC#tab_config.n_fragments =:= 0,
+ RC#run_config.use_sticky_locks =:= false ->
+ {fun add_delta/7, mnesia};
+ TC#tab_config.n_fragments =:= 0,
+ RC#run_config.use_sticky_locks =:= true ->
+ {fun sticky_add_delta/7, mnesia};
+ TC#tab_config.n_fragments > 0,
+ RC#run_config.use_sticky_locks =:= false ->
+ {fun frag_add_delta/7, mnesia_frag}
+ end.
+
+%%
+%% Runs the TPC-B defined transaction and returns NewAccountBalance
+%%
+
+add_delta(DriverId, BranchId, TellerId, _AccountBranchId, AccountId, HistoryId, Delta) ->
+ %% Grab write lock already when the record is read
+
+ %% Add delta to branch balance
+ [B] = mnesia:read(branch, BranchId, write),
+ NewB = B#branch{balance = B#branch.balance + Delta},
+ ok = mnesia:write(branch, NewB, write),
+
+ %% Add delta to teller balance
+ [T] = mnesia:read(teller, TellerId, write),
+ NewT = T#teller{balance = T#teller.balance + Delta},
+ ok = mnesia:write(teller, NewT, write),
+
+ %% Add delta to account balance
+ [A] = mnesia:read(account, AccountId, write),
+ NewA = A#account{balance = A#account.balance + Delta},
+ ok = mnesia:write(account, NewA, write),
+
+ %% Append to history log
+ History = #history{history_id = {DriverId, HistoryId},
+ account_id = AccountId,
+ teller_id = TellerId,
+ branch_id = BranchId,
+ amount = Delta
+ },
+ ok = mnesia:write(history, History, write),
+
+ %% Return account balance
+ NewA#account.balance.
+
+sticky_add_delta(DriverId, BranchId, TellerId, _AccountBranchId, AccountId, HistoryId, Delta) ->
+ %% Grab orinary read lock when the record is read
+ %% Grab sticky write lock when the record is written
+ %% This transaction would benefit of an early stick_write lock at read
+
+ %% Add delta to branch balance
+ [B] = mnesia:read(branch, BranchId, read),
+ NewB = B#branch{balance = B#branch.balance + Delta},
+ ok = mnesia:write(branch, NewB, sticky_write),
+
+ %% Add delta to teller balance
+ [T] = mnesia:read(teller, TellerId, read),
+ NewT = T#teller{balance = T#teller.balance + Delta},
+ ok = mnesia:write(teller, NewT, sticky_write),
+
+ %% Add delta to account balance
+ [A] = mnesia:read(account, AccountId, read),
+ NewA = A#account{balance = A#account.balance + Delta},
+ ok = mnesia:write(account, NewA, sticky_write),
+
+ %% Append to history log
+ History = #history{history_id = {DriverId, HistoryId},
+ account_id = AccountId,
+ teller_id = TellerId,
+ branch_id = BranchId,
+ amount = Delta
+ },
+ ok = mnesia:write(history, History, sticky_write),
+
+ %% Return account balance
+ NewA#account.balance.
+
+frag_add_delta(DriverId, BranchId, TellerId, AccountBranchId, AccountId, HistoryId, Delta) ->
+ %% Access fragmented table
+ %% Grab write lock already when the record is read
+
+ %% Add delta to branch balance
+ [B] = mnesia:read(branch, BranchId, write),
+ NewB = B#branch{balance = B#branch.balance + Delta},
+ ok = mnesia:write(NewB),
+
+ %% Add delta to teller balance
+ [T] = mnesia:read({teller, BranchId}, TellerId, write),
+ NewT = T#teller{balance = T#teller.balance + Delta},
+ ok = mnesia:write(NewT),
+
+ %% Add delta to account balance
+ %%io:format("frag_add_delta(~p): ~p\n", [node(), {account, BranchId, AccountId}]),
+ [A] = mnesia:read({account, AccountBranchId}, AccountId, write),
+ NewA = A#account{balance = A#account.balance + Delta},
+ ok = mnesia:write(NewA),
+
+ %% Append to history log
+ History = #history{history_id = {DriverId, HistoryId},
+ account_id = AccountId,
+ teller_id = TellerId,
+ branch_id = BranchId,
+ amount = Delta
+ },
+ ok = mnesia:write(History),
+
+ %% Return account balance
+ NewA#account.balance.
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%% Verify table consistency
+
+verify_tabs() ->
+ Nodes = mnesia:system_info(running_db_nodes),
+ case lists:member(node(), Nodes) of
+ true ->
+ Tabs = [branch, teller, account, history],
+ io:format("TPC-B: Verifying tables: ~w~n", [Tabs]),
+ rpc:multicall(Nodes, mnesia, wait_for_tables, [Tabs, infinity]),
+
+ Fun = fun() ->
+ mnesia:write_lock_table(branch),
+ mnesia:write_lock_table(teller),
+ mnesia:write_lock_table(account),
+ mnesia:write_lock_table(history),
+ {Res, BadNodes} =
+ rpc:multicall(Nodes, ?MODULE, count_balance, []),
+ check_balance(Res, BadNodes)
+ end,
+ case mnesia:transaction(Fun) of
+ {atomic, Res} -> Res;
+ {aborted, Reason} -> {error, Reason}
+ end;
+ false ->
+ {error, "Must be initiated from a running db_node"}
+ end.
+
+%% Returns a list of {Table, Node, Balance} tuples
+%% Assumes that no updates are performed
+
+-record(summary, {table, node, balance, size}).
+
+count_balance() ->
+ [count_balance(branch, #branch.balance),
+ count_balance(teller, #teller.balance),
+ count_balance(account, #account.balance)].
+
+count_balance(Tab, BalPos) ->
+ Frags = table_info(Tab, frag_names),
+ count_balance(Tab, Frags, 0, 0, BalPos).
+
+count_balance(Tab, [Frag | Frags], Bal, Size, BalPos) ->
+ First = mnesia:dirty_first(Frag),
+ {Bal2, Size2} = count_frag_balance(Frag, First, Bal, Size, BalPos),
+ count_balance(Tab, Frags, Bal2, Size2, BalPos);
+count_balance(Tab, [], Bal, Size, _BalPos) ->
+ #summary{table = Tab, node = node(), balance = Bal, size = Size}.
+
+count_frag_balance(_Frag, '$end_of_table', Bal, Size, _BalPos) ->
+ {Bal, Size};
+count_frag_balance(Frag, Key, Bal, Size, BalPos) ->
+ [Record] = mnesia:dirty_read({Frag, Key}),
+ Bal2 = Bal + element(BalPos, Record),
+ Next = mnesia:dirty_next(Frag, Key),
+ count_frag_balance(Frag, Next, Bal2, Size + 1, BalPos).
+
+check_balance([], []) ->
+ mnesia:abort({"No balance"});
+check_balance(Summaries, []) ->
+ [One | Rest] = lists:flatten(Summaries),
+ Balance = One#summary.balance,
+ %% Size = One#summary.size,
+ case [S || S <- Rest, S#summary.balance =/= Balance] of
+ [] ->
+ ok;
+ BadSummaries ->
+ mnesia:abort({"Bad balance", One, BadSummaries})
+ end;
+check_balance(_, BadNodes) ->
+ mnesia:abort({"Bad nodes", BadNodes}).
diff --git a/lib/mnesia/test/mnesia_trans_access_test.erl b/lib/mnesia/test/mnesia_trans_access_test.erl
new file mode 100644
index 0000000000..c67382e694
--- /dev/null
+++ b/lib/mnesia/test/mnesia_trans_access_test.erl
@@ -0,0 +1,1254 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 1996-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(mnesia_trans_access_test).
+-author('[email protected]').
+-compile([export_all]).
+-include("mnesia_test_lib.hrl").
+
+init_per_testcase(Func, Conf) ->
+ mnesia_test_lib:init_per_testcase(Func, Conf).
+
+fin_per_testcase(Func, Conf) ->
+ mnesia_test_lib:fin_per_testcase(Func, Conf).
+
+-define(receive_messages(Msgs), mnesia_recovery_test:receive_messages(Msgs, ?FILE, ?LINE)).
+
+% First Some debug logging
+-define(dgb, true).
+-ifdef(dgb).
+-define(dl(X, Y), ?verbose("**TRACING: " ++ X ++ "**~n", Y)).
+-else.
+-define(dl(X, Y), ok).
+-endif.
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+all(doc) ->
+ ["Evil access of records in the scope of transactions",
+ "Invoke all functions in the API and try to cover all legal uses",
+ "cases as well the illegal dito. This is a complement to the",
+ "other more explicit test cases."];
+all(suite) ->
+ [
+ write, read, wread, delete, delete_object,
+ match_object, select, select14, all_keys,
+ transaction, nested_activities,
+ index_tabs, index_lifecycle
+ ].
+
+%% Write records
+
+write(suite) -> [];
+write(Config) when is_list(Config) ->
+ [Node1] = Nodes = ?acquire_nodes(1, Config),
+ Tab = write,
+ Schema = [{name, Tab}, {attributes, [k, v]}, {ram_copies, [Node1]}],
+ ?match({atomic, ok}, mnesia:create_table(Schema)),
+
+ ?match({aborted, {bad_type, _}},
+ mnesia:transaction(fun() -> mnesia:write([]) end)),
+ ?match({aborted, {bad_type, _}},
+ mnesia:transaction(fun() -> mnesia:write({Tab, 2}) end)),
+ ?match({aborted, _},
+ mnesia:transaction(fun() -> mnesia:write({foo, 2}) end)),
+ ?match({atomic, ok},
+ mnesia:transaction(fun() -> mnesia:write({Tab, 1, 2}) end)),
+
+ ?match({'EXIT', {aborted, no_transaction}}, mnesia:write({Tab, 1, 2})),
+ ?verify_mnesia(Nodes, []).
+
+%% Read records
+
+read(suite) -> [];
+read(Config) when is_list(Config) ->
+ [Node1] = Nodes = ?acquire_nodes(1, Config),
+ Tab = read,
+ Schema = [{name, Tab}, {type, bag}, {attributes, [k, v]}, {ram_copies, [Node1]}],
+ ?match({atomic, ok}, mnesia:create_table(Schema)),
+
+ OneRec = {Tab, 1, 2},
+ TwoRec = {Tab, 1, 3},
+ ?match({aborted, {bad_type, _}},
+ mnesia:transaction(fun() -> mnesia:read([]) end)),
+ ?match({aborted, {bad_type, _}},
+ mnesia:transaction(fun() -> mnesia:read({Tab}) end)),
+ ?match({aborted, {bad_type, _}}
+ , mnesia:transaction(fun() -> mnesia:read(OneRec) end)),
+ ?match({atomic, []},
+ mnesia:transaction(fun() -> mnesia:read({Tab, 1}) end)),
+ ?match({atomic, ok},
+ mnesia:transaction(fun() -> mnesia:write(OneRec) end)),
+ ?match({atomic, [OneRec]},
+ mnesia:transaction(fun() -> mnesia:read({Tab, 1}) end)),
+ ?match({atomic, ok},
+ mnesia:transaction(fun() -> mnesia:write(TwoRec) end)),
+ ?match({atomic, [OneRec, TwoRec]},
+ mnesia:transaction(fun() -> mnesia:read({Tab, 1}) end)),
+
+ ?match({'EXIT', {aborted, no_transaction}}, mnesia:read({Tab, 1})),
+ ?verify_mnesia(Nodes, []).
+
+%% Read records and set write lock
+
+wread(suite) -> [];
+wread(Config) when is_list(Config) ->
+ [Node1] = Nodes = ?acquire_nodes(1, Config),
+ Tab = wread,
+ Schema = [{name, Tab}, {type, set}, {attributes, [k, v]}, {ram_copies, [Node1]}],
+ ?match({atomic, ok}, mnesia:create_table(Schema)),
+
+ OneRec = {Tab, 1, 2},
+ TwoRec = {Tab, 1, 3},
+ ?match({aborted, {bad_type, _}},
+ mnesia:transaction(fun() -> mnesia:wread([]) end)),
+ ?match({aborted, {bad_type, _}},
+ mnesia:transaction(fun() -> mnesia:wread({Tab}) end)),
+ ?match({aborted, {bad_type, _}}
+ , mnesia:transaction(fun() -> mnesia:wread(OneRec) end)),
+
+ ?match({atomic, []},
+ mnesia:transaction(fun() -> mnesia:wread({Tab, 1}) end)),
+ ?match({atomic, ok},
+ mnesia:transaction(fun() -> mnesia:write(OneRec) end)),
+
+ ?match({atomic, [OneRec]},
+ mnesia:transaction(fun() -> mnesia:wread({Tab, 1}) end)),
+ ?match({atomic, ok},
+ mnesia:transaction(fun() -> mnesia:write(TwoRec) end)),
+ ?match({atomic, [TwoRec]},
+ mnesia:transaction(fun() -> mnesia:wread({Tab, 1}) end)),
+
+ ?match({'EXIT', {aborted, no_transaction}}, mnesia:wread({Tab, 1})),
+ ?verify_mnesia(Nodes, []).
+
+%% Delete record
+
+delete(suite) -> [];
+delete(Config) when is_list(Config) ->
+ [Node1] = Nodes = ?acquire_nodes(1, Config),
+ Tab = delete,
+ Schema = [{name, Tab}, {type, bag}, {attributes, [k, v]}, {ram_copies, [Node1]}],
+ ?match({atomic, ok}, mnesia:create_table(Schema)),
+
+ ?match({aborted, {bad_type, _}},
+ mnesia:transaction(fun() -> mnesia:delete([]) end)),
+ ?match({aborted, {bad_type, _}},
+ mnesia:transaction(fun() -> mnesia:delete({Tab}) end)),
+ ?match({aborted, {bad_type, _}}
+ , mnesia:transaction(fun() -> mnesia:delete({Tab, 1, 2}) end)),
+ ?match({atomic, ok},
+ mnesia:transaction(fun() -> mnesia:delete({Tab, 1}) end)),
+ ?match({atomic, ok},
+ mnesia:transaction(fun() -> mnesia:write({Tab, 1, 2}) end)),
+ ?match({atomic, ok},
+ mnesia:transaction(fun() -> mnesia:delete({Tab, 1}) end)),
+ ?match({atomic, ok},
+ mnesia:transaction(fun() -> mnesia:write({Tab, 1, 2}) end)),
+ ?match({atomic, ok},
+ mnesia:transaction(fun() -> mnesia:write({Tab, 1, 2}) end)),
+ ?match({atomic, ok},
+ mnesia:transaction(fun() -> mnesia:delete({Tab, 1}) end)),
+
+ ?match({'EXIT', {aborted, no_transaction}}, mnesia:delete({Tab, 1})),
+ ?verify_mnesia(Nodes, []).
+
+%% Delete matching record
+
+delete_object(suite) -> [];
+delete_object(Config) when is_list(Config) ->
+ [Node1] = Nodes = ?acquire_nodes(1, Config),
+ Tab = delete_object,
+ Schema = [{name, Tab}, {type, bag}, {attributes, [k, v]}, {ram_copies, [Node1]}],
+ ?match({atomic, ok}, mnesia:create_table(Schema)),
+
+ OneRec = {Tab, 1, 2},
+ ?match({aborted, {bad_type, _}},
+ mnesia:transaction(fun() -> mnesia:delete_object([]) end)),
+ ?match({aborted, {bad_type, _}},
+ mnesia:transaction(fun() -> mnesia:delete_object({Tab}) end)),
+ ?match({aborted, {bad_type, _}},
+ mnesia:transaction(fun() -> mnesia:delete_object({Tab, 1}) end)),
+ ?match({atomic, ok},
+ mnesia:transaction(fun() -> mnesia:delete_object(OneRec) end)),
+ ?match({atomic, ok},
+ mnesia:transaction(fun() -> mnesia:write(OneRec) end)),
+ ?match({atomic, ok},
+ mnesia:transaction(fun() -> mnesia:delete_object(OneRec) end)),
+ ?match({atomic, ok},
+ mnesia:transaction(fun() -> mnesia:write(OneRec) end)),
+ ?match({atomic, ok},
+ mnesia:transaction(fun() -> mnesia:write(OneRec) end)),
+ ?match({atomic, ok},
+ mnesia:transaction(fun() -> mnesia:delete_object(OneRec) end)),
+
+ ?match({'EXIT', {aborted, no_transaction}}, mnesia:delete_object(OneRec)),
+
+ ?match({aborted, {bad_type, Tab, _}},
+ mnesia:transaction(fun() -> mnesia:delete_object({Tab, {['_']}, 21}) end)),
+ ?match({aborted, {bad_type, Tab, _}},
+ mnesia:transaction(fun() -> mnesia:delete_object({Tab, {['$5']}, 21}) end)),
+
+ ?verify_mnesia(Nodes, []).
+
+%% Read matching records
+
+match_object(suite) -> [];
+match_object(Config) when is_list(Config) ->
+ [Node1] = Nodes = ?acquire_nodes(1, Config),
+ Tab = match,
+ Schema = [{name, Tab}, {attributes, [k, v]}, {ram_copies, [Node1]}],
+ ?match({atomic, ok}, mnesia:create_table(Schema)),
+
+ OneRec = {Tab, 1, 2},
+ OnePat = {Tab, '$1', 2},
+ ?match({atomic, []},
+ mnesia:transaction(fun() -> mnesia:match_object(OnePat) end)),
+ ?match({atomic, ok},
+ mnesia:transaction(fun() -> mnesia:write(OneRec) end)),
+ ?match({atomic, [OneRec]},
+ mnesia:transaction(fun() -> mnesia:match_object(OnePat) end)),
+
+ ?match({aborted, _},
+ mnesia:transaction(fun() -> mnesia:match_object({foo, '$1', 2}) end)),
+ ?match({aborted, _},
+ mnesia:transaction(fun() -> mnesia:match_object({[], '$1', 2}) end)),
+
+ ?match({'EXIT', {aborted, no_transaction}}, mnesia:match_object(OnePat)),
+ ?verify_mnesia(Nodes, []).
+
+%% select
+select(suite) -> [];
+select(Config) when is_list(Config) ->
+ [Node1] = Nodes = ?acquire_nodes(1, Config),
+ Tab = match,
+ Schema = [{name, Tab}, {attributes, [k, v]}, {ram_copies, [Node1]}],
+ ?match({atomic, ok}, mnesia:create_table(Schema)),
+
+ OneRec = {Tab, 1, 2},
+ TwoRec = {Tab, 2, 3},
+ OnePat = [{{Tab, '$1', 2}, [], ['$_']}],
+ ?match({atomic, []},
+ mnesia:transaction(fun() -> mnesia:select(Tab, OnePat) end)),
+ ?match({atomic, ok},
+ mnesia:transaction(fun() -> mnesia:write(OneRec) end)),
+ ?match({atomic, ok},
+ mnesia:transaction(fun() -> mnesia:write(TwoRec) end)),
+ ?match({atomic, [OneRec]},
+ mnesia:transaction(fun() -> mnesia:select(Tab, OnePat) end)),
+
+ ?match({aborted, _},
+ mnesia:transaction(fun() -> mnesia:select(Tab, {match, '$1', 2}) end)),
+ ?match({aborted, _},
+ mnesia:transaction(fun() -> mnesia:select(Tab, [{'_', [], '$1'}]) end)),
+
+ ?match({'EXIT', {aborted, no_transaction}}, mnesia:select(Tab, OnePat)),
+ ?verify_mnesia(Nodes, []).
+
+
+%% more select
+select14(suite) -> [];
+select14(Config) when is_list(Config) ->
+ [Node1,Node2] = Nodes = ?acquire_nodes(2, Config),
+ Tab1 = select14_ets,
+ Tab2 = select14_dets,
+ Tab3 = select14_remote,
+ Tab4 = select14_remote_dets,
+ Schemas = [[{name, Tab1}, {attributes, [k, v]}, {ram_copies, [Node1]}],
+ [{name, Tab2}, {attributes, [k, v]}, {disc_only_copies, [Node1]}],
+ [{name, Tab3}, {attributes, [k, v]}, {ram_copies, [Node2]}],
+ [{name, Tab4}, {attributes, [k, v]}, {disc_only_copies, [Node2]}]],
+ [?match({atomic, ok}, mnesia:create_table(Schema)) || Schema <- Schemas],
+
+ %% Some Helpers
+ Trans = fun(Fun) -> mnesia:transaction(Fun) end,
+ LoopHelp = fun('$end_of_table',_) -> [];
+ ({Recs,Cont},Fun) ->
+ Sel = mnesia:select(Cont),
+ Recs ++ Fun(Sel, Fun)
+ end,
+ Loop = fun(Table,Pattern) ->
+ Sel = mnesia:select(Table, Pattern, 1, read),
+ Res = LoopHelp(Sel,LoopHelp),
+ case mnesia:table_info(Table, type) of
+ ordered_set -> Res;
+ _ -> lists:sort(Res)
+ end
+ end,
+ Test =
+ fun(Tab) ->
+ OneRec = {Tab, 1, 2},
+ TwoRec = {Tab, 2, 3},
+ OnePat = [{{Tab, '$1', 2}, [], ['$_']}],
+ All = [OneRec,TwoRec],
+ AllPat = [{'_', [], ['$_']}],
+
+ ?match({atomic, []}, Trans(fun() -> Loop(Tab, OnePat) end)),
+ ?match({atomic, ok}, mnesia:transaction(fun() -> mnesia:write(OneRec) end)),
+ ?match({atomic, ok}, mnesia:transaction(fun() -> mnesia:write(TwoRec) end)),
+ ?match({atomic, [OneRec]}, Trans(fun() -> Loop(Tab, OnePat) end)),
+ ?match({atomic, All}, Trans(fun() -> Loop(Tab, AllPat) end)),
+
+ {atomic,{_, Cont}} = Trans(fun() -> mnesia:select(Tab, OnePat, 1, read) end),
+ ?match({aborted, wrong_transaction}, Trans(fun() -> mnesia:select(Cont) end)),
+
+ ?match({aborted, _}, Trans(fun() -> mnesia:select(Tab, {match, '$1', 2},1,read) end)),
+ ?match({aborted, _}, Trans(fun() -> mnesia:select(Tab, [{'_', [], '$1'}],1,read) end)),
+ ?match({aborted, _}, Trans(fun() -> mnesia:select(sune) end)),
+ ?match({'EXIT', {aborted, no_transaction}}, mnesia:select(Tab, OnePat,1,read)),
+ ?match({aborted, {badarg,sune}},
+ Trans(fun() -> mnesia:select(sune) end))
+ end,
+ Test(Tab1),
+ Test(Tab2),
+ Test(Tab3),
+ Test(Tab4),
+ ?verify_mnesia(Nodes, []).
+
+
+%% Pick all keys from table
+
+all_keys(suite) ->[];
+all_keys(Config) when is_list(Config) ->
+ [Node1] = Nodes = ?acquire_nodes(1, Config),
+ Tab = all_keys,
+ Schema = [{name, Tab}, {type, bag}, {attributes, [k, v]}, {ram_copies, [Node1]}],
+ ?match({atomic, ok}, mnesia:create_table(Schema)),
+
+ Write = fun() -> mnesia:write({Tab, 14, 4}) end,
+ AllKeys = fun() -> mnesia:all_keys(Tab) end,
+
+ ?match({atomic, []}, mnesia:transaction(AllKeys)),
+
+ ?match({atomic, ok}, mnesia:transaction(Write)),
+ ?match({atomic, [14]}, mnesia:transaction(AllKeys)),
+
+ ?match({atomic, ok}, mnesia:transaction(Write)),
+ ?match({atomic, [14]}, mnesia:transaction(AllKeys)),
+
+ ?match({aborted, _},
+ mnesia:transaction(fun() -> mnesia:all_keys(foo) end)),
+ ?match({aborted, _},
+ mnesia:transaction(fun() -> mnesia:all_keys([]) end)),
+
+ ?match({'EXIT', {aborted, no_transaction}}, mnesia:all_keys(Tab)),
+ ?verify_mnesia(Nodes, []).
+
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%% Use and misuse transactions
+
+transaction(suite) -> [];
+transaction(Config) when is_list(Config) ->
+ [Node1] = Nodes = ?acquire_nodes(1, Config),
+ ?match({atomic, ali_baba}, mnesia:transaction(fun() -> ali_baba end)),
+ ?match({aborted, _}, mnesia:transaction(no_fun)),
+ ?match({aborted, _}, mnesia:transaction(?MODULE, no_fun, [foo])),
+
+ {success, [A, B, C, D, E, F, G, H]} =
+ ?start_activities(lists:duplicate(8, Node1)),
+ ?start_transactions([A, B, C, D, E, F, G, H]),
+
+ A ! fun() -> mnesia:abort(abort_bad_trans) end,
+ ?match_receive({A, {aborted, abort_bad_trans}}),
+
+ B ! fun() -> erlang:error(exit_here) end,
+ ?match_receive({B, {aborted, _}}),
+
+ C ! fun() -> throw(throw_bad_trans) end,
+ ?match_receive({C, {aborted, {throw, throw_bad_trans}}}),
+
+ D ! fun() -> exit(exit_bad_trans) end,
+ ?match_receive({D, {aborted, exit_bad_trans}}),
+
+ E ! fun() -> exit(normal) end,
+ ?match_receive({E, {aborted, normal}}),
+
+ F ! fun() -> exit(abnormal) end,
+ ?match_receive({F, {aborted, abnormal}}),
+
+ G ! fun() -> exit(G, abnormal) end,
+ ?match_receive({'EXIT', G, abnormal}),
+
+ H ! fun() -> exit(H, kill) end,
+ ?match_receive({'EXIT', H, killed}),
+
+ ?match({atomic, ali_baba},
+ mnesia:transaction(fun() -> ali_baba end, infinity)),
+ ?match({atomic, ali_baba}, mnesia:transaction(fun() -> ali_baba end, 1)),
+ ?match({atomic, ali_baba}, mnesia:transaction(fun() -> ali_baba end, 0)),
+ ?match({aborted, Reason8} when element(1, Reason8) == badarg, mnesia:transaction(fun() -> ali_baba end, -1)),
+ ?match({aborted, Reason1} when element(1, Reason1) == badarg, mnesia:transaction(fun() -> ali_baba end, foo)),
+ Fun = fun() ->
+ ?match(true, mnesia:is_transaction()),
+ ?match({atomic, ok},
+ mnesia:transaction(fun() -> ?match(true, mnesia:is_transaction()),ok end)), ok end,
+ ?match({atomic, ok}, mnesia:transaction(Fun)),
+ ?verify_mnesia(Nodes, []).
+
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+nested_activities(suite) ->
+ [
+ basic_nested,
+ nested_transactions,
+ mix_of_nested_activities
+ ].
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+%% ensure that nested transactions behave correctly
+%% We create a particular table that is used by this test only
+-record(ntab, {a, b}).
+basic_nested(doc) -> ["Test the basic functionality of nested transactions"];
+basic_nested(suite) -> [];
+basic_nested(Config) when is_list(Config) ->
+ Nodes = ?acquire_nodes(3, Config),
+ Args = [{ram_copies, Nodes},
+ {attributes, record_info(fields, ntab)}],
+ ?match({atomic, ok}, mnesia:create_table(ntab, Args)),
+ do_nested(top),
+ case mnesia_test_lib:diskless(Config) of
+ false ->
+ lists:foreach(fun(N) ->
+ ?match({atomic, ok},
+ mnesia:change_table_copy_type(ntab, N, disc_only_copies))
+ end, Nodes),
+ do_nested(top);
+ true ->
+ skip
+ end,
+ ?verify_mnesia(Nodes, []).
+
+do_nested(How) ->
+ F1 = fun() ->
+ mnesia:write(#ntab{a= 1}),
+ mnesia:write(#ntab{a= 2})
+ end,
+ F2 = fun() ->
+ mnesia:read({ntab, 1})
+ end,
+ ?match({atomic, ok}, mnesia:transaction(F1)),
+ ?match({atomic, _}, mnesia:transaction(F2)),
+
+ ?match({atomic, {aborted, _}},
+ mnesia:transaction(fun() -> n_f1(),
+ mnesia:transaction(fun() -> n_f2() end)
+ end)),
+
+ ?match({atomic, {aborted, _}},
+ mnesia:transaction(fun() -> n_f1(),
+ mnesia:transaction(fun() -> n_f3() end)
+ end)),
+ ?match({atomic, {atomic, [#ntab{a = 5}]}},
+ mnesia:transaction(fun() -> mnesia:write(#ntab{a = 5}),
+ mnesia:transaction(fun() -> n_f4() end)
+ end)),
+ Cyclic = fun() -> mnesia:abort({cyclic,a,a,a,a,a}) end, %% Ugly
+ NodeNotR = fun() -> mnesia:abort({node_not_running, testNode}) end,
+
+ TestAbort = fun(Fun) ->
+ case get(restart_counter) of
+ undefined ->
+ put(restart_counter, 1),
+ Fun();
+ _ ->
+ erase(restart_counter),
+ ok
+ end
+ end,
+
+ ?match({atomic,{atomic,ok}},
+ mnesia:transaction(fun()->mnesia:transaction(TestAbort,
+ [Cyclic])end)),
+
+ ?match({atomic,{atomic,ok}},
+ mnesia:transaction(fun()->mnesia:transaction(TestAbort,
+ [NodeNotR])end)),
+
+ %% Now try the restart thingie
+ case How of
+ top ->
+ Pids = [spawn(?MODULE, do_nested, [{spawned, self()}]),
+ spawn(?MODULE, do_nested, [{spawned, self()}]),
+ spawn(?MODULE, do_nested, [{spawned, self()}]),
+ spawn(?MODULE, do_nested, [{spawned, self()}])],
+ ?match({info, _, _}, mnesia_tm:get_info(2000)),
+ lists:foreach(fun(P) -> receive
+ {P, ok} -> ok
+ end
+ end, Pids),
+ ?match([], [Tab || Tab <- ets:all(), mnesia_trans_store == ets:info(Tab, name)]);
+
+ {spawned, Pid} ->
+ ?match({info, _, _}, mnesia_tm:get_info(2000)),
+ Pid ! {self(), ok},
+ exit(normal)
+ end.
+
+
+n_f1() ->
+ mnesia:read({ntab, 1}),
+ mnesia:write(#ntab{a = 3}).
+
+n_f2() ->
+ mnesia:write(#ntab{a = 4}),
+ erlang:error(exit_here).
+
+n_f3() ->
+ mnesia:write(#ntab{a = 4}),
+ throw(funky).
+
+n_f4() ->
+ mnesia:read({ntab, 5}).
+
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+nested_transactions(doc) ->
+ ["Verify that nested_transactions are handled as expected"];
+nested_transactions(suite) ->
+ [nested_trans_both_ok,
+ nested_trans_child_dies,
+ nested_trans_parent_dies,
+ nested_trans_both_dies].
+
+nested_trans_both_ok(suite) -> [];
+nested_trans_both_ok(Config) when is_list(Config) ->
+ nested_transactions(Config, ok, ok).
+
+nested_trans_child_dies(suite) -> [];
+nested_trans_child_dies(Config) when is_list(Config) ->
+ nested_transactions(Config, abort, ok).
+
+nested_trans_parent_dies(suite) -> [];
+nested_trans_parent_dies(Config) when is_list(Config) ->
+ nested_transactions(Config, ok, abort).
+
+nested_trans_both_dies(suite) -> [];
+nested_trans_both_dies(Config) when is_list(Config) ->
+ nested_transactions(Config, abort, abort).
+
+nested_transactions(Config, Child, Father) ->
+ [Node1, Node2, Node3] = Nodes = ?acquire_nodes(3, Config),
+ Tab = nested_trans,
+
+ Def =
+ case mnesia_test_lib:diskless(Config) of
+ true ->
+ [{name, Tab}, {ram_copies, Nodes}];
+ false ->
+ [{name, Tab}, {ram_copies, [Node1]},
+ {disc_copies, [Node2]}, {disc_only_copies, [Node3]}]
+ end,
+
+ ?match({atomic, ok}, mnesia:create_table(Def)),
+ ?match(ok, mnesia:dirty_write({Tab, father, not_updated})),
+ ?match(ok, mnesia:dirty_write({Tab, child, not_updated})),
+
+ ChildOk = fun() -> mnesia:write({Tab, child, updated}) end,
+ ChildAbort = fun() ->
+ mnesia:write({Tab, child, updated}),
+ erlang:error(exit_here)
+ end,
+
+ Child_Fun = % Depending of test case
+ case Child of
+ ok -> ChildOk;
+ abort -> ChildAbort
+ end,
+
+ FatherOk = fun() -> mnesia:transaction(Child_Fun),
+ mnesia:write({Tab, father, updated})
+ end,
+
+ FatherAbort = fun() -> mnesia:transaction(Child_Fun),
+ mnesia:write({Tab, father, updated}),
+ erlang:error(exit_here)
+ end,
+
+ {FatherRes, ChildRes} = % Depending of test case
+ case Father of
+ ok -> ?match({atomic, ok}, mnesia:transaction(FatherOk)),
+ case Child of
+ ok -> {[{Tab, father, updated}], [{Tab, child, updated}]};
+ _ -> {[{Tab, father, updated}], [{Tab, child, not_updated}]}
+ end;
+ abort -> ?match({aborted, _}, mnesia:transaction(FatherAbort)),
+ {[{Tab, father, not_updated}], [{Tab, child, not_updated}]}
+ end,
+
+ %% Syncronize things!!
+ ?match({atomic, ok}, mnesia:sync_transaction(fun() -> mnesia:write({Tab, sync, sync}) end)),
+
+ ?match(ChildRes, rpc:call(Node1, mnesia, dirty_read, [{Tab, child}])),
+ ?match(ChildRes, rpc:call(Node2, mnesia, dirty_read, [{Tab, child}])),
+ ?match(ChildRes, rpc:call(Node3, mnesia, dirty_read, [{Tab, child}])),
+
+ ?match(FatherRes, rpc:call(Node1, mnesia, dirty_read, [{Tab, father}])),
+ ?match(FatherRes, rpc:call(Node2, mnesia, dirty_read, [{Tab, father}])),
+ ?match(FatherRes, rpc:call(Node3, mnesia, dirty_read, [{Tab, father}])),
+ ?verify_mnesia(Nodes, []).
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+mix_of_nested_activities(doc) ->
+ ["Verify that dirty operations in a transaction are handled like ",
+ "normal transactions"];
+mix_of_nested_activities(suite) -> [];
+mix_of_nested_activities(Config) when is_list(Config) ->
+ [Node1, Node2, Node3] = Nodes = ?acquire_nodes(3, Config),
+ Tab = tab,
+
+ Def =
+ case mnesia_test_lib:diskless(Config) of
+ true -> [{ram_copies, Nodes}];
+ false ->
+ [{ram_copies, [Node1]},
+ {disc_copies, [Node2]},
+ {disc_only_copies, [Node3]}]
+ end,
+
+ ?match({atomic, ok}, mnesia:create_table(Tab, [{type,bag}|Def])),
+ Activities = [transaction, sync_transaction,
+ ets, async_dirty, sync_dirty],
+ %% Make a test for all 3000 combinations
+ Tests = [[A,B,C,D,E] ||
+ A <- Activities,
+ B <- Activities,
+ C <- Activities,
+ D <- Activities,
+ E <- Activities],
+ Foreach =
+ fun(Test,No) ->
+ Result = lists:reverse(Test),
+ ?match({No,Result},{No,catch apply_op({Tab,No},Test)}),
+ No+1
+ end,
+ lists:foldl(Foreach, 0, Tests),
+ ?verify_mnesia(Nodes, []).
+
+apply_op(Oid,[Type]) ->
+ check_res(Type,mnesia:Type(fun() -> [Type|read_op(Oid)] end));
+apply_op(Oid = {Tab,Key},[Type|Next]) ->
+ check_res(Type,mnesia:Type(fun() ->
+ Prev = read_op(Oid),
+ mnesia:write({Tab,Key,[Type|Prev]}),
+ apply_op(Oid,Next)
+ end)).
+
+check_res(transaction, {atomic,Res}) ->
+ Res;
+check_res(sync_transaction, {atomic,Res}) ->
+ Res;
+check_res(async_dirty, Res) when is_list(Res) ->
+ Res;
+check_res(sync_dirty, Res) when is_list(Res) ->
+ Res;
+check_res(ets, Res) when is_list(Res) ->
+ Res;
+check_res(Type,Res) ->
+ ?match(bug,{Type,Res}).
+
+read_op(Oid) ->
+ case lists:reverse(mnesia:read(Oid)) of
+ [] -> [];
+ [{_,_,Ops}|_] ->
+ Ops
+ end.
+
+index_tabs(suite) ->
+ [
+ index_match_object,
+ index_read,
+ index_update,
+ index_write
+ ].
+
+%% Read matching records by using an index
+
+index_match_object(suite) -> [];
+index_match_object(Config) when is_list(Config) ->
+ [Node1, Node2] = Nodes = ?acquire_nodes(2, Config),
+ Tab = index_match_object,
+ Schema = [{name, Tab}, {attributes, [k, v, e]}, {ram_copies, [Node1]}],
+ ?match({atomic, ok}, mnesia:create_table(Schema)),
+ ValPos = 3,
+ BadValPos = ValPos + 2,
+ ?match({atomic, ok}, mnesia:add_table_index(Tab, ValPos)),
+
+ ?match({atomic, []},
+ mnesia:transaction(fun() -> mnesia:index_match_object({Tab, '$1', 2}, ValPos) end)),
+ OneRec = {Tab, {1, 1}, 2, {1, 1}},
+ OnePat = {Tab, '$1', 2, '_'},
+ BadPat = {Tab, '$1', '$2', '_'}, %% See ref guide
+
+ ?match({atomic, ok},
+ mnesia:transaction(fun() -> mnesia:write(OneRec) end)),
+
+ Imatch = fun(Patt, Pos) ->
+ mnesia:transaction(fun() -> lists:sort(mnesia:index_match_object(Patt, Pos)) end)
+ end,
+ ?match({atomic, [OneRec]}, Imatch(OnePat, ValPos)),
+ ?match({aborted, _}, Imatch(OnePat, BadValPos)),
+ ?match({aborted, _}, Imatch({foo, '$1', 2, '_'}, ValPos)),
+ ?match({aborted, _}, Imatch({[], '$1', 2, '_'}, ValPos)),
+ ?match({aborted, _}, Imatch(BadPat, ValPos)),
+ ?match({'EXIT', {aborted, no_transaction}}, mnesia:index_match_object(OnePat, ValPos)),
+
+ Another = {Tab, {3,1}, 2, {4,4}},
+ ?match({atomic, ok},
+ mnesia:transaction(fun() -> mnesia:write(Another) end)),
+ ?match({atomic, ok},
+ mnesia:transaction(fun() -> mnesia:write({Tab, {4, 4}, 3, {4, 4}}) end)),
+
+ ?match({atomic, [OneRec]}, Imatch({Tab, {1,1}, 2, {1,1}}, ValPos)),
+ ?match({atomic, [OneRec]}, Imatch({Tab, {1,1}, 2, '$1'}, ValPos)),
+ ?match({atomic, [OneRec]}, Imatch({Tab, '$1', 2, {1,1}}, ValPos)),
+ ?match({atomic, [OneRec]}, Imatch({Tab, '$1', 2, '$1'}, ValPos)),
+ ?match({atomic, [OneRec]}, Imatch({Tab, {1, '$1'}, 2, '_'}, ValPos)),
+ ?match({atomic, [OneRec]}, Imatch({Tab, {'$2', '$1'}, 2, {'_', '$1'}}, ValPos)),
+ ?match({atomic, [OneRec, Another]}, Imatch({Tab, '_', 2, '_'}, ValPos)),
+
+ ?match({atomic, ok},
+ mnesia:transaction(fun() -> mnesia:write({Tab, 4, 5, {7, 4}}) end)),
+ ?match({atomic, ok},
+ mnesia:transaction(fun() -> mnesia:write({Tab, 7, 5, {7, 5}}) end)),
+
+ ?match({atomic, [{Tab, 4, 5, {7, 4}}]}, Imatch({Tab, '$1', 5, {'_', '$1'}}, ValPos)),
+
+ ?match({atomic, [OneRec]}, rpc:call(Node2, mnesia, transaction,
+ [fun() ->
+ lists:sort(mnesia:index_match_object({Tab, {1,1}, 2,
+ {1,1}}, ValPos))
+ end])),
+ ?verify_mnesia(Nodes, []).
+
+%% Read records by using an index
+
+index_read(suite) -> [];
+index_read(Config) when is_list(Config) ->
+ [Node1] = Nodes = ?acquire_nodes(1, Config),
+ Tab = index_read,
+ Schema = [{name, Tab}, {attributes, [k, v]}, {ram_copies, [Node1]}],
+ ?match({atomic, ok}, mnesia:create_table(Schema)),
+ ValPos = 3,
+ BadValPos = ValPos + 1,
+ ?match({atomic, ok}, mnesia:add_table_index(Tab, ValPos)),
+
+ OneRec = {Tab, 1, 2},
+ ?match({atomic, []},
+ mnesia:transaction(fun() -> mnesia:index_read(Tab, 2, ValPos) end)),
+ ?match({atomic, ok},
+ mnesia:transaction(fun() -> mnesia:write(OneRec) end)),
+ ?match({atomic, [OneRec]},
+ mnesia:transaction(fun() -> mnesia:index_read(Tab, 2, ValPos) end)),
+ ?match({aborted, _},
+ mnesia:transaction(fun() -> mnesia:index_read(Tab, 2, BadValPos) end)),
+ ?match({aborted, _},
+ mnesia:transaction(fun() -> mnesia:index_read(foo, 2, ValPos) end)),
+ ?match({aborted, _},
+ mnesia:transaction(fun() -> mnesia:index_read([], 2, ValPos) end)),
+
+ ?match({'EXIT', {aborted, no_transaction}}, mnesia:index_read(Tab, 2, ValPos)),
+ ?verify_mnesia(Nodes, []).
+
+index_update(suite) -> [index_update_set, index_update_bag];
+index_update(doc) -> ["See Ticket OTP-2083, verifies that a table with a index is "
+ "update in the correct way i.e. the index finds the correct "
+ "records after a update"].
+index_update_set(suite) -> [];
+index_update_set(Config)when is_list(Config) ->
+ [Node1] = Nodes = ?acquire_nodes(1, Config),
+ Tab = index_test,
+ Schema = [{name, Tab}, {attributes, [k, v1, v2, v3]}, {ram_copies, [Node1]}],
+ ?match({atomic, ok}, mnesia:create_table(Schema)),
+ ValPos = v1,
+ ValPos2 = v3,
+ ?match({atomic, ok}, mnesia:add_table_index(Tab, ValPos)),
+
+ Pat1 = {Tab, '$1', 2, '$2', '$3'},
+ Pat2 = {Tab, '$1', '$2', '$3', '$4'},
+
+ Rec1 = {Tab, 1, 2, 3, 4},
+ Rec2 = {Tab, 2, 2, 13, 14},
+ Rec3 = {Tab, 1, 12, 13, 14},
+ Rec4 = {Tab, 4, 2, 13, 14},
+
+ ?match({atomic, []},
+ mnesia:transaction(fun() -> mnesia:index_read(Tab, 2, ValPos) end)),
+ ?match({atomic, ok},
+ mnesia:transaction(fun() -> mnesia:write(Rec1) end)),
+ ?match({atomic, [Rec1]},
+ mnesia:transaction(fun() -> mnesia:index_read(Tab, 2, ValPos) end)),
+
+ ?match({atomic, ok},
+ mnesia:transaction(fun() -> mnesia:write(Rec2) end)),
+ {atomic, R1} = mnesia:transaction(fun() -> mnesia:index_read(Tab, 2, ValPos) end),
+ ?match([Rec1, Rec2], lists:sort(R1)),
+
+ ?match({atomic, ok},
+ mnesia:transaction(fun() -> mnesia:write(Rec3) end)),
+ {atomic, R2} = mnesia:transaction(fun() -> mnesia:index_read(Tab, 2, ValPos) end),
+ ?match([Rec2], lists:sort(R2)),
+ ?match({atomic, [Rec2]},
+ mnesia:transaction(fun() -> mnesia:index_match_object(Pat1, ValPos) end)),
+
+ {atomic, R3} = mnesia:transaction(fun() -> mnesia:match_object(Pat2) end),
+ ?match([Rec3, Rec2], lists:sort(R3)),
+
+ ?match({atomic, ok},
+ mnesia:transaction(fun() -> mnesia:write(Rec4) end)),
+ {atomic, R4} = mnesia:transaction(fun() -> mnesia:index_read(Tab, 2, ValPos) end),
+ ?match([Rec2, Rec4], lists:sort(R4)),
+
+ ?match({atomic, ok},
+ mnesia:transaction(fun() -> mnesia:delete({Tab, 4}) end)),
+ ?match({atomic, [Rec2]},
+ mnesia:transaction(fun() -> mnesia:index_read(Tab, 2, ValPos) end)),
+
+ ?match({atomic, ok}, mnesia:del_table_index(Tab, ValPos)),
+ ?match({atomic, ok}, mnesia:transaction(fun() -> mnesia:write(Rec4) end)),
+ ?match({atomic, ok}, mnesia:add_table_index(Tab, ValPos)),
+ ?match({atomic, ok}, mnesia:add_table_index(Tab, ValPos2)),
+
+ {atomic, R5} = mnesia:transaction(fun() -> mnesia:match_object(Pat2) end),
+ ?match([Rec3, Rec2, Rec4], lists:sort(R5)),
+
+ {atomic, R6} = mnesia:transaction(fun() -> mnesia:index_read(Tab, 2, ValPos) end),
+ ?match([Rec2, Rec4], lists:sort(R6)),
+
+ ?match({atomic, []},
+ mnesia:transaction(fun() -> mnesia:index_read(Tab, 4, ValPos2) end)),
+ {atomic, R7} = mnesia:transaction(fun() -> mnesia:index_read(Tab, 14, ValPos2) end),
+ ?match([Rec3, Rec2, Rec4], lists:sort(R7)),
+
+ ?match({atomic, ok}, mnesia:transaction(fun() -> mnesia:write(Rec1) end)),
+ {atomic, R8} = mnesia:transaction(fun() -> mnesia:index_read(Tab, 2, ValPos) end),
+ ?match([Rec1, Rec2, Rec4], lists:sort(R8)),
+ ?match({atomic, [Rec1]},
+ mnesia:transaction(fun() -> mnesia:index_read(Tab, 4, ValPos2) end)),
+ {atomic, R9} = mnesia:transaction(fun() -> mnesia:index_read(Tab, 14, ValPos2) end),
+ ?match([Rec2, Rec4], lists:sort(R9)),
+
+ ?match({atomic, ok}, mnesia:transaction(fun() -> mnesia:delete_object(Rec2) end)),
+ {atomic, R10} = mnesia:transaction(fun() -> mnesia:index_read(Tab, 2, ValPos) end),
+ ?match([Rec1, Rec4], lists:sort(R10)),
+ ?match({atomic, [Rec1]},
+ mnesia:transaction(fun() -> mnesia:index_read(Tab, 4, ValPos2) end)),
+ ?match({atomic, [Rec4]},
+ mnesia:transaction(fun() -> mnesia:index_read(Tab, 14, ValPos2) end)),
+
+ ?match({atomic, ok}, mnesia:transaction(fun() -> mnesia:delete({Tab, 4}) end)),
+ {atomic, R11} = mnesia:transaction(fun() -> mnesia:index_read(Tab, 2, ValPos) end),
+ ?match([Rec1], lists:sort(R11)),
+ ?match({atomic, [Rec1]},mnesia:transaction(fun() -> mnesia:index_read(Tab, 4, ValPos2) end)),
+ ?match({atomic, []},mnesia:transaction(fun() -> mnesia:index_read(Tab, 14, ValPos2) end)),
+
+ ?verify_mnesia(Nodes, []).
+
+index_update_bag(suite) -> [];
+index_update_bag(Config)when is_list(Config) ->
+ [Node1] = Nodes = ?acquire_nodes(1, Config),
+ Tab = index_test,
+ Schema = [{name, Tab},
+ {type, bag},
+ {attributes, [k, v1, v2, v3]},
+ {ram_copies, [Node1]}],
+ ?match({atomic, ok}, mnesia:create_table(Schema)),
+ ValPos = v1,
+ ValPos2 = v3,
+
+ ?match({atomic, ok}, mnesia:add_table_index(Tab, ValPos)),
+
+ Pat1 = {Tab, '$1', 2, '$2', '$3'},
+ Pat2 = {Tab, '$1', '$2', '$3', '$4'},
+
+ Rec1 = {Tab, 1, 2, 3, 4},
+ Rec2 = {Tab, 2, 2, 13, 14},
+ Rec3 = {Tab, 1, 12, 13, 14},
+ Rec4 = {Tab, 4, 2, 13, 4},
+ Rec5 = {Tab, 1, 2, 234, 14},
+
+ %% Simple Index
+ ?match({atomic, []},
+ mnesia:transaction(fun() -> mnesia:index_read(Tab, 2, ValPos) end)),
+ ?match({atomic, ok},
+ mnesia:transaction(fun() -> mnesia:write(Rec1) end)),
+ ?match({atomic, [Rec1]},
+ mnesia:transaction(fun() -> mnesia:index_read(Tab, 2, ValPos) end)),
+
+ ?match({atomic, ok},
+ mnesia:transaction(fun() -> mnesia:write(Rec2) end)),
+ {atomic, R1} = mnesia:transaction(fun() -> mnesia:index_read(Tab, 2, ValPos) end),
+ ?match([Rec1, Rec2], lists:sort(R1)),
+
+ ?match({atomic, ok},
+ mnesia:transaction(fun() -> mnesia:write(Rec3) end)),
+ {atomic, R2} = mnesia:transaction(fun() -> mnesia:index_read(Tab, 2, ValPos) end),
+ ?match([Rec1, Rec2], lists:sort(R2)),
+
+ {atomic, R3} = mnesia:transaction(fun() -> mnesia:index_match_object(Pat1, ValPos) end),
+ ?match([Rec1, Rec2], lists:sort(R3)),
+
+ {atomic, R4} = mnesia:transaction(fun() -> mnesia:match_object(Pat2) end),
+ ?match([Rec1, Rec3, Rec2], lists:sort(R4)),
+
+ ?match({atomic, ok},
+ mnesia:transaction(fun() -> mnesia:write(Rec4) end)),
+ {atomic, R5} = mnesia:transaction(fun() -> mnesia:index_read(Tab, 2, ValPos) end),
+ ?match([Rec1, Rec2, Rec4], lists:sort(R5)),
+
+ ?match({atomic, ok}, mnesia:transaction(fun() -> mnesia:delete({Tab, 4}) end)),
+ {atomic, R6} = mnesia:transaction(fun() -> mnesia:index_read(Tab, 2, ValPos) end),
+ ?match([Rec1, Rec2], lists:sort(R6)),
+
+ %% OTP-6587 Needs some whitebox testing to see that the index table is cleaned correctly
+
+ [IPos] = mnesia_lib:val({Tab,index}),
+ ITab = mnesia_lib:val({index_test,{index, IPos}}),
+ io:format("~n Index ~p @ ~p => ~p ~n~n",[IPos,ITab, ets:tab2list(ITab)]),
+ ?match([{2,1},{2,2},{12,1}], ets:tab2list(ITab)),
+
+ ?match({atomic, ok}, mnesia:transaction(fun() -> mnesia:write(Rec5) end)),
+ {atomic, R60} = mnesia:transaction(fun() -> mnesia:index_read(Tab, 2, ValPos) end),
+ ?match([Rec1,Rec5,Rec2], lists:sort(R60)),
+
+ ?match([{2,1},{2,2},{12,1}], ets:tab2list(ITab)),
+
+ ?match({atomic, ok}, mnesia:transaction(fun() -> mnesia:delete_object(Rec3) end)),
+ {atomic, R61} = mnesia:transaction(fun() -> mnesia:index_read(Tab, 2, ValPos) end),
+ ?match([Rec1,Rec5,Rec2], lists:sort(R61)),
+ {atomic, R62} = mnesia:transaction(fun() -> mnesia:index_read(Tab,12, ValPos) end),
+ ?match([], lists:sort(R62)),
+ ?match([{2,1},{2,2}], ets:tab2list(ITab)),
+
+ %% reset for rest of testcase
+ ?match({atomic, ok}, mnesia:transaction(fun() -> mnesia:write(Rec3) end)),
+ ?match({atomic, ok}, mnesia:transaction(fun() -> mnesia:delete_object(Rec5) end)),
+ {atomic, R6} = mnesia:transaction(fun() -> mnesia:index_read(Tab, 2, ValPos) end),
+ ?match([Rec1, Rec2], lists:sort(R6)),
+ %% OTP-6587
+
+ ?match({atomic, ok}, mnesia:transaction(fun() -> mnesia:delete_object(Rec1) end)),
+ ?match({atomic, [Rec2]},
+ mnesia:transaction(fun() -> mnesia:index_read(Tab, 2, ValPos) end)),
+ {atomic, R7} = mnesia:transaction(fun() -> mnesia:match_object(Pat2) end),
+ ?match([Rec3, Rec2], lists:sort(R7)),
+
+ %% Two indexies
+ ?match({atomic, ok}, mnesia:del_table_index(Tab, ValPos)),
+ ?match({atomic, ok}, mnesia:transaction(fun() -> mnesia:write(Rec1) end)),
+ ?match({atomic, ok}, mnesia:transaction(fun() -> mnesia:write(Rec4) end)),
+ ?match({atomic, ok}, mnesia:add_table_index(Tab, ValPos)),
+ ?match({atomic, ok}, mnesia:add_table_index(Tab, ValPos2)),
+
+ {atomic, R8} = mnesia:transaction(fun() -> mnesia:index_read(Tab, 2, ValPos) end),
+ ?match([Rec1, Rec2, Rec4], lists:sort(R8)),
+
+ {atomic, R9} = mnesia:transaction(fun() -> mnesia:index_read(Tab, 4, ValPos2) end),
+ ?match([Rec1, Rec4], lists:sort(R9)),
+ {atomic, R10} = mnesia:transaction(fun() -> mnesia:index_read(Tab, 14, ValPos2) end),
+ ?match([Rec3, Rec2], lists:sort(R10)),
+
+ ?match({atomic, ok}, mnesia:transaction(fun() -> mnesia:write(Rec5) end)),
+ {atomic, R11} = mnesia:transaction(fun() -> mnesia:index_read(Tab, 2, ValPos) end),
+ ?match([Rec1, Rec5, Rec2, Rec4], lists:sort(R11)),
+ {atomic, R12} = mnesia:transaction(fun() -> mnesia:index_read(Tab, 4, ValPos2) end),
+ ?match([Rec1, Rec4], lists:sort(R12)),
+ {atomic, R13} = mnesia:transaction(fun() -> mnesia:index_read(Tab, 14, ValPos2) end),
+ ?match([Rec5, Rec3, Rec2], lists:sort(R13)),
+
+ ?match({atomic, ok}, mnesia:transaction(fun() -> mnesia:delete_object(Rec1) end)),
+ {atomic, R14} = mnesia:transaction(fun() -> mnesia:index_read(Tab, 2, ValPos) end),
+ ?match([Rec5, Rec2, Rec4], lists:sort(R14)),
+ ?match({atomic, [Rec4]},
+ mnesia:transaction(fun() -> mnesia:index_read(Tab, 4, ValPos2) end)),
+ {atomic, R15} = mnesia:transaction(fun() -> mnesia:index_read(Tab, 14, ValPos2) end),
+ ?match([Rec5, Rec3, Rec2], lists:sort(R15)),
+
+ ?match({atomic, ok}, mnesia:transaction(fun() -> mnesia:delete_object(Rec5) end)),
+ {atomic, R16} = mnesia:transaction(fun() -> mnesia:index_read(Tab, 2, ValPos) end),
+ ?match([Rec2, Rec4], lists:sort(R16)),
+ ?match({atomic, [Rec4]}, mnesia:transaction(fun()->mnesia:index_read(Tab, 4, ValPos2) end)),
+ {atomic, R17} = mnesia:transaction(fun() -> mnesia:index_read(Tab, 14, ValPos2) end),
+ ?match([Rec3, Rec2], lists:sort(R17)),
+
+ ?match({atomic, ok}, mnesia:transaction(fun() -> mnesia:write(Rec1) end)),
+ ?match({atomic, ok}, mnesia:transaction(fun() -> mnesia:delete({Tab, 1}) end)),
+ {atomic, R18} = mnesia:transaction(fun() -> mnesia:index_read(Tab, 2, ValPos) end),
+ ?match([Rec2, Rec4], lists:sort(R18)),
+ ?match({atomic, [Rec4]}, mnesia:transaction(fun()->mnesia:index_read(Tab, 4, ValPos2) end)),
+ {atomic, R19} = mnesia:transaction(fun() -> mnesia:index_read(Tab, 14, ValPos2) end),
+ ?match([Rec2], lists:sort(R19)),
+
+ ?verify_mnesia(Nodes, []).
+
+
+index_write(suite) -> [];
+index_write(doc) -> ["See ticket OTP-8072"];
+index_write(Config)when is_list(Config) ->
+ Nodes = ?acquire_nodes(1, Config),
+ mnesia:create_table(a, [{index, [val]}]),
+ mnesia:create_table(counter, []),
+
+ CreateIfNonExist =
+ fun(Index) ->
+ case mnesia:index_read(a, Index, 3) of
+ [] ->
+ Id = mnesia:dirty_update_counter(counter, id, 1),
+ New = {a, Id, Index},
+ mnesia:write(New),
+ New;
+ [Found] ->
+ Found
+ end
+ end,
+
+ Trans = fun(A) ->
+ mnesia:transaction(CreateIfNonExist, [A])
+ %% This works better most of the time
+ %% And it is allowed to fail since it's dirty
+ %% mnesia:async_dirty(CreateIfNonExist, [A])
+ end,
+
+ Self = self(),
+ Update = fun() ->
+ Res = lists:map(Trans, lists:seq(1,10)),
+ Self ! {self(), Res}
+ end,
+
+ Pids = [spawn(Update) || _ <- lists:seq(1,5)],
+
+ Gather = fun(Pid, Acc) -> receive {Pid, Res} -> [Res|Acc] end end,
+ Results = lists:foldl(Gather, [], Pids),
+ Expected = hd(Results),
+ Check = fun(Res) -> ?match(Expected, Res) end,
+ lists:foreach(Check, Results),
+ ?verify_mnesia(Nodes, []).
+
+
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%% Add and drop indecies
+
+index_lifecycle(suite) ->
+ [
+ add_table_index_ram,
+ add_table_index_disc,
+ add_table_index_disc_only,
+ create_live_table_index_ram,
+ create_live_table_index_disc,
+ create_live_table_index_disc_only,
+ del_table_index_ram,
+ del_table_index_disc,
+ del_table_index_disc_only,
+ idx_schema_changes
+ ].
+
+add_table_index_ram(suite) -> [];
+add_table_index_ram(Config) when is_list(Config) ->
+ add_table_index(Config, ram_copies).
+
+add_table_index_disc(suite) -> [];
+add_table_index_disc(Config) when is_list(Config) ->
+ add_table_index(Config, disc_copies).
+
+add_table_index_disc_only(suite) -> [];
+add_table_index_disc_only(Config) when is_list(Config) ->
+ add_table_index(Config, disc_only_copies).
+
+%% Add table index
+
+add_table_index(Config, Storage) ->
+ [Node1] = Nodes = ?acquire_nodes(1, Config),
+ Tab = add_table_index,
+ Schema = [{name, Tab}, {attributes, [k, v]}, {Storage, [Node1]}],
+ ?match({atomic, ok}, mnesia:create_table(Schema)),
+ ValPos = 3,
+ BadValPos = ValPos + 1,
+ ?match({aborted, Reason41 } when element(1, Reason41) == bad_type,
+ mnesia:add_table_index(Tab, BadValPos)),
+ ?match({aborted,Reason42 } when element(1, Reason42) == bad_type,
+ mnesia:add_table_index(Tab, 2)),
+ ?match({aborted, Reason43 } when element(1, Reason43) == bad_type,
+ mnesia:add_table_index(Tab, 1)),
+ ?match({aborted, Reason44 } when element(1, Reason44) == bad_type,
+ mnesia:add_table_index(Tab, 0)),
+ ?match({aborted, Reason45 } when element(1, Reason45) == bad_type,
+ mnesia:add_table_index(Tab, -1)),
+ ?match({atomic, ok}, mnesia:add_table_index(Tab, ValPos)),
+ ?match({aborted, Reason46 } when element(1, Reason46) == already_exists,
+ mnesia:add_table_index(Tab, ValPos)),
+
+ NestedFun = fun() ->
+ ?match({aborted, nested_transaction},
+ mnesia:add_table_index(Tab, ValPos)),
+ ok
+ end,
+ ?match({atomic, ok}, mnesia:transaction(NestedFun)),
+ ?verify_mnesia(Nodes, []).
+
+create_live_table_index_ram(suite) -> [];
+create_live_table_index_ram(Config) when is_list(Config) ->
+ create_live_table_index(Config, ram_copies).
+
+create_live_table_index_disc(suite) -> [];
+create_live_table_index_disc(Config) when is_list(Config) ->
+ create_live_table_index(Config, disc_copies).
+
+create_live_table_index_disc_only(suite) -> [];
+create_live_table_index_disc_only(Config) when is_list(Config) ->
+ create_live_table_index(Config, disc_only_copies).
+
+create_live_table_index(Config, Storage) ->
+ [Node1] = Nodes = ?acquire_nodes(1, Config),
+ Tab = create_live_table_index,
+ Schema = [{name, Tab}, {attributes, [k, v]}, {Storage, [Node1]}],
+ ?match({atomic, ok}, mnesia:create_table(Schema)),
+ ValPos = 3,
+ mnesia:dirty_write({Tab, 1, 2}),
+
+ Fun = fun() ->
+ ?match(ok, mnesia:write({Tab, 2, 2})),
+ ok
+ end,
+ ?match({atomic, ok}, mnesia:transaction(Fun)),
+ ?match({atomic, ok}, mnesia:add_table_index(Tab, ValPos)),
+ ?match({atomic, [{Tab, 1, 2},{Tab, 2, 2}]},
+ mnesia:transaction(fun() -> lists:sort(mnesia:index_read(Tab, 2, ValPos))
+ end)),
+ ?verify_mnesia(Nodes, []).
+
+%% Drop table index
+
+del_table_index_ram(suite) ->[];
+del_table_index_ram(Config) when is_list(Config) ->
+ del_table_index(Config, ram_copies).
+
+del_table_index_disc(suite) ->[];
+del_table_index_disc(Config) when is_list(Config) ->
+ del_table_index(Config, disc_copies).
+
+del_table_index_disc_only(suite) ->[];
+del_table_index_disc_only(Config) when is_list(Config) ->
+ del_table_index(Config, disc_only_copies).
+
+del_table_index(Config, Storage) ->
+ [Node1] = Nodes = ?acquire_nodes(1, Config),
+ Tab = del_table_index,
+ Schema = [{name, Tab}, {attributes, [k, v]}, {Storage, [Node1]}],
+ ?match({atomic, ok}, mnesia:create_table(Schema)),
+ ValPos = 3,
+ BadValPos = ValPos + 1,
+ ?match({atomic, ok}, mnesia:add_table_index(Tab, ValPos)),
+ ?match({aborted,Reason} when element(1, Reason) == no_exists,
+ mnesia:del_table_index(Tab, BadValPos)),
+ ?match({atomic, ok}, mnesia:del_table_index(Tab, ValPos)),
+
+ ?match({aborted,Reason1} when element(1, Reason1) == no_exists,
+ mnesia:del_table_index(Tab, ValPos)),
+ NestedFun =
+ fun() ->
+ ?match({aborted, nested_transaction},
+ mnesia:del_table_index(Tab, ValPos)),
+ ok
+ end,
+ ?match({atomic, ok}, mnesia:transaction(NestedFun)),
+ ?verify_mnesia(Nodes, []).
+
+idx_schema_changes(suite) -> [idx_schema_changes_ram,
+ idx_schema_changes_disc,
+ idx_schema_changes_disc_only];
+idx_schema_changes(doc) ->
+ ["Tests that index tables are handled correctly when schema changes.",
+ "For example when a replica is deleted or inserted",
+ "TICKET OTP-2XXX (ELVIRA)"].
+
+idx_schema_changes_ram(suite) -> [];
+idx_schema_changes_ram(Config) when is_list(Config) ->
+ idx_schema_changes(Config, ram_copies).
+idx_schema_changes_disc(suite) -> [];
+idx_schema_changes_disc(Config) when is_list(Config) ->
+ idx_schema_changes(Config, disc_copies).
+idx_schema_changes_disc_only(suite) -> [];
+idx_schema_changes_disc_only(Config) when is_list(Config) ->
+ idx_schema_changes(Config, disc_only_copies).
+
+idx_schema_changes(Config, Storage) ->
+ [N1, N2] = Nodes = ?acquire_nodes(2, Config),
+ Tab = index_schema_changes,
+ Idx = 3,
+ Schema = [{name, Tab}, {index, [Idx]}, {attributes, [k, v]}, {Storage, Nodes}],
+ ?match({atomic, ok}, mnesia:create_table(Schema)),
+
+ {Storage1, Storage2} =
+ case Storage of
+ disc_only_copies ->
+ {ram_copies, disc_copies};
+ disc_copies ->
+ {disc_only_copies, ram_copies};
+ ram_copies ->
+ {disc_copies, disc_only_copies}
+ end,
+
+ Write = fun(N) ->
+ mnesia:write({Tab, N, N+50})
+ end,
+
+ [mnesia:sync_transaction(Write, [N]) || N <- lists:seq(1, 10)],
+ ?match([{Tab, 1, 51}], rpc:call(N1, mnesia, dirty_index_read, [Tab, 51, Idx])),
+ ?match([{Tab, 1, 51}], rpc:call(N2, mnesia, dirty_index_read, [Tab, 51, Idx])),
+
+ ?match({atomic, ok}, mnesia:change_table_copy_type(Tab, N1, Storage1)),
+
+ ?match({atomic, ok}, rpc:call(N1, mnesia, sync_transaction, [Write, [17]])),
+ ?match({atomic, ok}, rpc:call(N2, mnesia, sync_transaction, [Write, [18]])),
+
+ ?match([{Tab, 17, 67}], rpc:call(N2, mnesia, dirty_index_read, [Tab, 67, Idx])),
+ ?match([{Tab, 18, 68}], rpc:call(N1, mnesia, dirty_index_read, [Tab, 68, Idx])),
+
+ ?match({atomic, ok}, mnesia:del_table_copy(Tab, N1)),
+ ?match({atomic, ok}, rpc:call(N1, mnesia, sync_transaction, [Write, [11]])),
+ ?match({atomic, ok}, rpc:call(N2, mnesia, sync_transaction, [Write, [12]])),
+
+ ?match([{Tab, 11, 61}], rpc:call(N2, mnesia, dirty_index_read, [Tab, 61, Idx])),
+ ?match([{Tab, 12, 62}], rpc:call(N1, mnesia, dirty_index_read, [Tab, 62, Idx])),
+
+ ?match({atomic, ok}, mnesia:move_table_copy(Tab, N2, N1)),
+ ?match({atomic, ok}, rpc:call(N1, mnesia, sync_transaction, [Write, [19]])),
+ ?match({atomic, ok}, rpc:call(N2, mnesia, sync_transaction, [Write, [20]])),
+
+ ?match([{Tab, 19, 69}], rpc:call(N2, mnesia, dirty_index_read, [Tab, 69, Idx])),
+ ?match([{Tab, 20, 70}], rpc:call(N1, mnesia, dirty_index_read, [Tab, 70, Idx])),
+
+ ?match({atomic, ok}, mnesia:add_table_copy(Tab, N2, Storage)),
+ ?match({atomic, ok}, rpc:call(N1, mnesia, sync_transaction, [Write, [13]])),
+ ?match({atomic, ok}, rpc:call(N2, mnesia, sync_transaction, [Write, [14]])),
+
+ ?match([{Tab, 13, 63}], rpc:call(N2, mnesia, dirty_index_read, [Tab, 63, Idx])),
+ ?match([{Tab, 14, 64}], rpc:call(N1, mnesia, dirty_index_read, [Tab, 64, Idx])),
+
+ ?match({atomic, ok}, mnesia:change_table_copy_type(Tab, N2, Storage2)),
+
+ ?match({atomic, ok}, rpc:call(N1, mnesia, sync_transaction, [Write, [15]])),
+ ?match({atomic, ok}, rpc:call(N2, mnesia, sync_transaction, [Write, [16]])),
+
+ ?match([{Tab, 15, 65}], rpc:call(N2, mnesia, dirty_index_read, [Tab, 65, Idx])),
+ ?match([{Tab, 16, 66}], rpc:call(N1, mnesia, dirty_index_read, [Tab, 66, Idx])),
+
+ ?verify_mnesia(Nodes, []).
diff --git a/lib/mnesia/test/mt b/lib/mnesia/test/mt
new file mode 100755
index 0000000000..25243f1149
--- /dev/null
+++ b/lib/mnesia/test/mt
@@ -0,0 +1,60 @@
+#! /bin/sh -f
+# ``The contents of this file are subject to the Erlang Public License,
+# Version 1.1, (the "License"); you may not use this file except in
+# compliance with the License. You should have received a copy of the
+# Erlang Public License along with this software. If not, it can be
+# retrieved via the world wide web at http://www.erlang.org/.
+#
+# Software distributed under the License is distributed on an "AS IS"
+# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+# the License for the specific language governing rights and limitations
+# under the License.
+#
+# The Initial Developer of the Original Code is Ericsson Utvecklings AB.
+# Portions created by Ericsson are Copyright 1999, Ericsson Utvecklings
+# AB. All Rights Reserved.''
+#
+# $Id$
+#
+#
+# Author: Hakan Mattsson <[email protected]>
+# Purpose: Simplified execution of the test suite
+#
+# Usage: mt <args to erlang startup script>
+
+#top=".."
+top="$ERL_TOP/lib/mnesia"
+h=`hostname`
+p="-pa $top/examples -pa $top/ebin -pa $top/test -mnesia_test_verbose true"
+log=test_log$$
+latest=test_log_latest
+args=${1+"$@"}
+erlcmd="erl -sname a $p $args -mnesia_test_timeout"
+erlcmd1="erl -sname a1 $p $args"
+erlcmd2="erl -sname a2 $p $args"
+
+xterm -geometry 70x20+0+550 -T a1 -e $erlcmd1 &
+xterm -geometry 70x20+450+550 -T a2 -e $erlcmd2 &
+
+rm "$latest" 2>/dev/null
+ln -s "$log" "$latest"
+touch "$log"
+
+echo "$erlcmd1"
+echo ""
+echo "$erlcmd2"
+echo ""
+echo "$erlcmd"
+echo ""
+echo "Give the following command in order to see the outcome from node a@$h"":"
+echo ""
+echo " less test_log$$"
+
+ostype=`uname -s`
+if [ "$ostype" = "SunOS" ] ; then
+ /usr/openwin/bin/xterm -geometry 145x40+0+0 -T a -l -lf "$log" -e $erlcmd &
+else
+ xterm -geometry 145x40+0+0 -T a -e script -f -c "$erlcmd" "$log" &
+fi
+tail -f "$log" | egrep 'Eval|<>ERROR|NYI'
+
diff --git a/lib/mnesia/test/mt.erl b/lib/mnesia/test/mt.erl
new file mode 100644
index 0000000000..f69c4a11fd
--- /dev/null
+++ b/lib/mnesia/test/mt.erl
@@ -0,0 +1,262 @@
+%%
+%% %CopyrightBegin%
+%%
+%% 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%
+%%
+
+%%
+%%% Author: Hakan Mattsson [email protected]
+%%% Purpose: Nice shortcuts intended for testing of Mnesia
+%%%
+%%% See the mnesia_SUITE module about the structure of
+%%% the test suite.
+%%%
+%%% See the mnesia_test_lib module about the test case execution.
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+-module(mt).
+-author('[email protected]').
+-export([
+ t/0, t/1, t/2, t/3, % Run test cases
+ loop/1, loop/2, loop/3, % loop test cases
+ doc/0, doc/1, % Generate test case doc
+ struct/0, struct/1, % View test suite struct
+ shutdown/0, ping/0, start_nodes/0, % Node admin
+ read_config/0, write_config/1 % Config admin
+ ]).
+
+-include("mnesia_test_lib.hrl").
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%% Aliases for the (sub) test suites
+alias(all) -> mnesia_SUITE;
+alias(atomicity) -> mnesia_atomicity_test;
+alias(backup) -> mnesia_evil_backup;
+alias(config) -> mnesia_config_test;
+alias(consistency) -> mnesia_consistency_test;
+alias(dirty) -> mnesia_dirty_access_test;
+alias(durability) -> mnesia_durability_test;
+alias(evil) -> mnesia_evil_coverage_test;
+alias(qlc) -> mnesia_qlc_test;
+alias(examples) -> mnesia_examples_test;
+alias(frag) -> mnesia_frag_test;
+alias(heavy) -> {mnesia_SUITE, heavy};
+alias(install) -> mnesia_install_test;
+alias(isolation) -> mnesia_isolation_test;
+alias(light) -> {mnesia_SUITE, light};
+alias(measure) -> mnesia_measure_test;
+alias(medium) -> {mnesia_SUITE, medium};
+alias(nice) -> mnesia_nice_coverage_test;
+alias(recover) -> mnesia_recover_test;
+alias(recovery) -> mnesia_recovery_test;
+alias(registry) -> mnesia_registry_test;
+alias(suite) -> mnesia_SUITE;
+alias(trans) -> mnesia_trans_access_test;
+alias(Other) -> Other.
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%% Resolves the name of test suites and test cases
+%% according to the alias definitions. Single atoms
+%% are assumed to be the name of a test suite.
+resolve(Suite0) when is_atom(Suite0) ->
+ case alias(Suite0) of
+ Suite when is_atom(Suite) ->
+ {Suite, all};
+ {Suite, Case} ->
+ {Suite, Case}
+ end;
+resolve({Suite0, Case}) when is_atom(Suite0), is_atom(Case) ->
+ case alias(Suite0) of
+ Suite when is_atom(Suite) ->
+ {Suite, Case};
+ {Suite, Case2} ->
+ {Suite, Case2}
+ end;
+resolve(List) when is_list(List) ->
+ [resolve(Case) || Case <- List].
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%% Run one or more test cases
+
+%% Run the default test case with default config
+t() ->
+ t(read_test_case()).
+
+%% Resolve the test case name and run the test case
+%% The test case is noted as default test case
+%% and the outcome of the tests are written to
+%% to a file.
+t(silly) ->
+ mnesia_install_test:silly();
+t(diskless) ->
+ %% Run the default test case with default config,
+ %% but diskless
+ t(read_test_case(), diskless);
+t(Case) ->
+ %% Use the default config
+ t(Case, read_config()).
+
+t(Case, Config) when Config == diskless ->
+ %% Run the test case with default config, but diskless
+ Config2 = [{diskless, true} | read_config()],
+ t(Case, Config2);
+t(Mod, Fun) when is_atom(Mod), is_atom(Fun) ->
+ %% Run the test case with default config
+ t({Mod, Fun}, read_config());
+t(RawCase, Config) when is_list(Config) ->
+ %% Resolve the test case name and run the test case
+ Case = resolve(RawCase),
+ write_test_case(Case),
+ Res = mnesia_test_lib:test(Case, Config),
+ append_test_case_info(Case, Res).
+
+t(Mod, Fun, Config) when Config == diskless ->
+ t({Mod, Fun}, diskless).
+
+config_fname() ->
+ "mnesia_test_case_config".
+
+%% Read default config file
+read_config() ->
+ Fname = config_fname(),
+ mnesia_test_lib:log("Consulting file ~s...~n", [Fname]),
+ case file:consult(Fname) of
+ {ok, Config} ->
+ mnesia_test_lib:log("Read config ~w~n", [Config]),
+ Config;
+ _Error ->
+ Config = mnesia_test_lib:default_config(),
+ mnesia_test_lib:log("<>WARNING<> Using default config: ~w~n", [Config]),
+ Config
+ end.
+
+%% Write new default config file
+write_config(Config) when is_list(Config) ->
+ Fname = config_fname(),
+ {ok, Fd} = file:open(Fname, write),
+ write_list(Fd, Config),
+ file:close(Fd).
+
+write_list(Fd, [H | T]) ->
+ ok = io:format(Fd, "~p.~n",[H]),
+ write_list(Fd, T);
+write_list(_, []) ->
+ ok.
+
+test_case_fname() ->
+ "mnesia_test_case_info".
+
+%% Read name of test case
+read_test_case() ->
+ Fname = test_case_fname(),
+ case file:open(Fname, [read]) of
+ {ok, Fd} ->
+ Res = io:read(Fd, []),
+ file:close(Fd),
+ case Res of
+ {ok, TestCase} ->
+ mnesia_test_lib:log("Using test case ~w from file ~s~n",
+ [TestCase, Fname]),
+ TestCase;
+ {error, _} ->
+ default_test_case(Fname)
+ end;
+ {error, _} ->
+ default_test_case(Fname)
+ end.
+
+default_test_case(Fname) ->
+ TestCase = all,
+ mnesia_test_lib:log("<>WARNING<> Cannot read file ~s, "
+ "using default test case: ~w~n",
+ [Fname, TestCase]),
+ TestCase.
+
+write_test_case(TestCase) ->
+ Fname = test_case_fname(),
+ {ok, Fd} = file:open(Fname, write),
+ ok = io:format(Fd, "~p.~n",[TestCase]),
+ file:close(Fd).
+
+append_test_case_info(TestCase, TestCaseInfo) ->
+ Fname = test_case_fname(),
+ {ok, Fd} = file:open(Fname, [read, write]),
+ ok = io:format(Fd, "~p.~n",[TestCase]),
+ ok = io:format(Fd, "~p.~n",[TestCaseInfo]),
+ file:close(Fd),
+ TestCaseInfo.
+
+%% Generate HTML pages from the test case structure
+doc() ->
+ doc(suite).
+
+doc(Case) ->
+ mnesia_test_lib:doc(resolve(Case)).
+
+%% Display out the test case structure
+struct() ->
+ struct(suite).
+
+struct(Case) ->
+ mnesia_test_lib:struct([resolve(Case)]).
+
+%% Shutdown all nodes with erlang:halt/0
+shutdown() ->
+ mnesia_test_lib:shutdown().
+
+%% Ping all nodes in config spec
+ping() ->
+ Config = read_config(),
+ Nodes = mnesia_test_lib:select_nodes(all, Config, ?FILE, ?LINE),
+ [{N, net_adm:ping(N)} || N <- Nodes].
+
+%% Slave start all nodes in config spec
+start_nodes() ->
+ Config = read_config(),
+ Nodes = mnesia_test_lib:select_nodes(all, Config, ?FILE, ?LINE),
+ mnesia_test_lib:init_nodes(Nodes, ?FILE, ?LINE),
+ ping().
+
+%% loop one testcase /suite until it fails
+
+loop(Case) ->
+ loop_1(Case,-1,read_config()).
+
+loop(M,F) when is_atom(F) ->
+ loop_1({M,F},-1,read_config());
+loop(Case,N) when is_integer(N) ->
+ loop_1(Case, N,read_config()).
+
+loop(M,F,N) when is_integer(N) ->
+ loop_1({M,F},N,read_config()).
+
+loop_1(Case,N,Config) when N /= 0 ->
+ io:format("Loop test ~p ~n", [abs(N)]),
+ case ok_result(Res = t(Case,Config)) of
+ true ->
+ loop_1(Case,N-1,Config);
+ error ->
+ Res
+ end;
+loop_1(_,_,_) ->
+ ok.
+
+ok_result([{_T,{ok,_,_}}|R]) ->
+ ok_result(R);
+ok_result([{_T,{TC,List}}|R]) when is_tuple(TC), is_list(List) ->
+ ok_result(List) andalso ok_result(R);
+ok_result([]) -> true;
+ok_result(_) -> error.
diff --git a/lib/mnesia/vsn.mk b/lib/mnesia/vsn.mk
index 2de3658bf3..31cc8f8513 100644
--- a/lib/mnesia/vsn.mk
+++ b/lib/mnesia/vsn.mk
@@ -1,7 +1,8 @@
-MNESIA_VSN = 4.4.12
+MNESIA_VSN = 4.4.13
-TICKETS = OTP-8250
+TICKETS = OTP-8402 OTP-8406
+#TICKETS_4.4.12 = OTP-8250
#TICKETS_4.4.11 = OTP-8074
#TICKETS_4.4.10 = OTP-7928 OTP-7968 OTP-8002
#TICKETS_4.4.9 = OTP-7911
diff --git a/lib/observer/doc/src/notes.xml b/lib/observer/doc/src/notes.xml
index 20fc19694b..48c7c21363 100644
--- a/lib/observer/doc/src/notes.xml
+++ b/lib/observer/doc/src/notes.xml
@@ -4,7 +4,7 @@
<chapter>
<header>
<copyright>
- <year>2004</year><year>2009</year>
+ <year>2004</year><year>2010</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
@@ -13,12 +13,12 @@
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>Observer Release Notes</title>
@@ -31,6 +31,21 @@
<p>This document describes the changes made to the Observer
application.</p>
+<section><title>Observer 0.9.8.2</title>
+
+ <section><title>Improvements and New Features</title>
+ <list>
+ <item>
+ <p>
+ Misc updates</p>
+ <p>
+ Own Id: OTP-8456</p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
<section><title>Observer 0.9.8.1</title>
<section><title>Improvements and New Features</title>
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/observer/vsn.mk b/lib/observer/vsn.mk
index 84b19f78bb..ff06fb992d 100644
--- a/lib/observer/vsn.mk
+++ b/lib/observer/vsn.mk
@@ -1 +1 @@
-OBSERVER_VSN = 0.9.8.1
+OBSERVER_VSN = 0.9.8.2
diff --git a/lib/odbc/aclocal.m4 b/lib/odbc/aclocal.m4
new file mode 120000
index 0000000000..151fd5ea5a
--- /dev/null
+++ b/lib/odbc/aclocal.m4
@@ -0,0 +1 @@
+../../erts/aclocal.m4 \ No newline at end of file
diff --git a/lib/odbc/c_src/Makefile.in b/lib/odbc/c_src/Makefile.in
index 6a9a174417..ed3eeb1d42 100644
--- a/lib/odbc/c_src/Makefile.in
+++ b/lib/odbc/c_src/Makefile.in
@@ -1,19 +1,19 @@
#
# %CopyrightBegin%
-#
-# Copyright Ericsson AB 1999-2009. All Rights Reserved.
-#
+#
+# Copyright Ericsson AB 1999-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%
#
@@ -78,11 +78,11 @@ ODBC_INCLUDE = @ODBC_INCLUDE@
# FLAGS
# ----------------------------------------------------
CC = @CC@
-CFLAGS = $(TYPEFLAGS) @CFLAGS@
+CFLAGS = $(TYPEFLAGS) @CFLAGS@ @THR_DEFS@ @DEFS@
EI_LDFLAGS = -L$(EI_ROOT)/obj$(TYPEMARKER)/$(TARGET)
-LD = @DED_LD@
+LD = @LD@
LDFLAGS = $(ODBC_LIB) $(EI_LDFLAGS)
-LIBS = @LIBS@ $(EI_LIB)
+LIBS = @LIBS@ @THR_LIBS@ $(EI_LIB)
INCLUDES = -I. $(ODBC_INCLUDE) $(EI_INCLUDE)
TARGET_FLAGS = @TARGET_FLAGS@
@@ -106,17 +106,17 @@ docs:
# ----------------------------------------------------
ifdef UNIX_TARGET
-$(UNIX_TARGET): $(BIN_DIR) $(OBJ_DIR)/odbcserver.o
+$(UNIX_TARGET): $(OBJ_DIR)/odbcserver.o
$(CC) $(CFLAGS) -o $@ $(OBJ_DIR)/odbcserver.o $(LDFLAGS) $(LIBS)
endif
ifdef WIN32_TARGET
-$(WIN32_TARGET): $(BIN_DIR) $(OBJ_DIR)/odbcserver.o
+$(WIN32_TARGET): $(OBJ_DIR)/odbcserver.o
$(LD) $(LDFLAGS) -o $@ $(OBJ_DIR)/odbcserver.o $(ENTRY_OBJ) \
$(LIBS) $(ENTRY_LDFLAGS)
endif
-$(OBJ_DIR)/odbcserver.o: $(OBJ_DIR) odbcserver.c
+$(OBJ_DIR)/odbcserver.o: odbcserver.c
$(CC) $(CFLAGS) $(INCLUDES) $(TARGET_FLAGS) -o $@ -c odbcserver.c
create_dirs:
diff --git a/lib/odbc/c_src/odbcserver.c b/lib/odbc/c_src/odbcserver.c
index 63177121bc..aaaea20a10 100644
--- a/lib/odbc/c_src/odbcserver.c
+++ b/lib/odbc/c_src/odbcserver.c
@@ -1,19 +1,19 @@
/*
* %CopyrightBegin%
- *
- * Copyright Ericsson AB 1999-2009. All Rights Reserved.
- *
+ *
+ * Copyright Ericsson AB 1999-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%
*
@@ -119,6 +119,7 @@
#include <sys/socket.h>
#include <sys/uio.h>
#include <netdb.h>
+#include <netinet/in.h>
#endif
#include <limits.h>
@@ -749,11 +750,12 @@ static db_result_msg db_param_query(byte *buffer, db_state *state)
byte *sql;
db_result_msg msg;
int i, num_param_values, ver = 0,
- erl_type = 0, index = 0, size = 0, cols = 0;
+ erl_type = 0, index = 0, size = 0, cols = 0;
long long_num_param_values;
param_status param_status;
diagnos diagnos;
- param_array *params;
+ param_array *params;
+ SQLRETURN result;
if (associated_result_set(state)) {
clean_state(state);
@@ -784,10 +786,16 @@ static db_result_msg db_param_query(byte *buffer, db_state *state)
num_param_values, state);
if(params != NULL) {
- if(!sql_success(SQLExecDirect(statement_handle(state),
- sql, SQL_NTS))) {
- diagnos = get_diagnos(SQL_HANDLE_STMT, statement_handle(state));
- msg = encode_error_message(diagnos.error_msg);
+
+ result = SQLExecDirect(statement_handle(state), sql, SQL_NTS);
+ if (!sql_success(result) || result == SQL_NO_DATA) {
+ diagnos = get_diagnos(SQL_HANDLE_STMT, statement_handle(state));
+ }
+ /* SQL_NO_DATA and SQLSTATE 00000 indicate success for
+ updates/deletes that affect no rows */
+ if(!sql_success(result) &&
+ !(result == SQL_NO_DATA && !strcmp((char *)diagnos.sqlState, INFO))) {
+ msg = encode_error_message(diagnos.error_msg);
} else {
for (i = 0; i < param_status.params_processed; i++) {
switch (param_status.param_status_array[i]) {
@@ -2452,6 +2460,7 @@ static diagnos get_diagnos(SQLSMALLINT handleType, SQLHANDLE handle)
int acc_errmsg_size;
byte *current_errmsg_pos;
SQLCHAR current_sql_state[SQL_STATE_SIZE];
+ SQLRETURN result;
diagnos.error_msg[0] = 0;
@@ -2464,10 +2473,10 @@ static diagnos get_diagnos(SQLSMALLINT handleType, SQLHANDLE handle)
/* Foreach diagnostic record in the current set of diagnostic records
the error message is obtained */
for(record_nr = 1; ;record_nr++) {
- if(SQLGetDiagRec(handleType, handle, record_nr, current_sql_state,
+ result = SQLGetDiagRec(handleType, handle, record_nr, current_sql_state,
&nativeError, current_errmsg_pos,
- (SQLSMALLINT)errmsg_buffer_size, &errmsg_size)
- != SQL_SUCCESS) {
+ (SQLSMALLINT)errmsg_buffer_size, &errmsg_size);
+ if(result != SQL_SUCCESS && result != SQL_NO_DATA) {
break;
diff --git a/lib/odbc/configure.in b/lib/odbc/configure.in
index 77b576ee88..24e286c290 100644
--- a/lib/odbc/configure.in
+++ b/lib/odbc/configure.in
@@ -25,6 +25,15 @@ else
host_os=win32
fi
+if test "$with_odbc" = "no"; then
+
+ rm -f "$ERL_TOP/lib/odbc/SKIP"
+ echo "odbc disabled by user." > "$ERL_TOP/lib/odbc/SKIP"
+
+else dnl "$with_odbc" != "no"
+
+ERL_XCOMP_SYSROOT_INIT
+
dnl Checks for programs.
AC_PROG_CC
@@ -48,8 +57,11 @@ fi
AC_SUBST(MIXED_CYGWIN_VC)
AC_PROG_MAKE_SET
-AC_CHECK_PROGS(DED_LD, [ld.sh ld], '$(CC)')
-AC_SUBST(DED_LD)
+
+AC_CHECK_PROG(LD, ld.sh)
+AC_CHECK_TOOL(LD, ld, '$(CC)')
+
+AC_SUBST(LD)
# Sockets
#--------------------------------------------------------------------
@@ -83,50 +95,6 @@ AC_CHECK_FUNC(gethostbyname, , AC_CHECK_LIB(nsl, main, [LIBS="$LIBS -lnsl"]))
dnl Checks for header files.
AC_HEADER_STDC
-case $have_pthread_lib-$host_os in
- yes-linux*)
- dnl NPTL test stolen from $ERL_TOP/erts/aclocal.m4
- 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
- AC_MSG_RESULT($nptl)
- if test $nptl = yes; then
- need_nptl_incldir=no
- 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_ws_path=
- save_ifs="$IFS"; IFS=":"
- for dir in $nptl_path; do
- if test "x$dir" != "x"; then
- nptl_ws_path="$nptl_ws_path $dir"
- fi
- done
- IFS=$save_ifs
- nptl_incldir=
- for dir in $nptl_ws_path; do
- AC_CHECK_HEADER($dir/nptl/pthread.h,
- nptl_incldir=$dir/nptl)
- if test "x$nptl_incldir" != "x"; then
- CFLAGS="$CFLAGS -isystem $nptl_incldir"
- dnl CPPFLAGS is for configure internal use
- CPPFLAGS="$CPPFLAGS -isystem $nptl_incldir"
- break
- fi
- done
- if test "x$nptl_incldir" = "x"; then
- AC_MSG_ERROR(Failed to locate nptl system include directory)
- fi
- fi
- fi
- ;;
- *)
- ;;
-esac
AC_CHECK_HEADERS([fcntl.h netdb.h stdlib.h string.h sys/socket.h])
dnl Checks for typedefs, structures, and compiler characteristics.
@@ -137,20 +105,18 @@ dnl Checks for library functions.
AC_CHECK_FUNCS([memset socket])
# ODBC
-/bin/rm -f $ERL_TOP/lib/odbc/SKIP
+/bin/rm -f "$ERL_TOP/lib/odbc/SKIP"
-have_pthread_lib=no
-have_odbc_lib=no
-
+LM_CHECK_THR_LIB
+AC_SUBST(THR_DEFS)
+AC_SUBST(THR_LIBS)
+
+odbc_lib_link_success=no
AC_SUBST(TARGET_FLAGS)
case $host_os in
darwin*)
TARGET_FLAGS="-DUNIX"
- AC_CHECK_LIB(pthread, pthread_create,
- [AC_DEFINE(HAVE_LIBPTHREAD, 1, [Define if you have the pthread library (-lpthread).])
- LIBS="$LIBS -lpthread"
- have_pthread_lib=yes])
- if test ! -d "$with_odbc"; then
+ if test ! -d "$with_odbc" || test "$with_odbc" = "yes" ; then
ODBC_LIB= -L"/usr/lib"
ODBC_INCLUDE="-I/usr/lib/include"
else
@@ -158,7 +124,7 @@ AC_SUBST(TARGET_FLAGS)
ODBC_INCLUDE="-I$with_odbc/include"
fi
- AC_CHECK_LIB(iodbc, SQLAllocHandle,[ODBC_LIB="$ODBC_LIB -liodbc" odbc_lib_link_sucess=yes])
+ AC_CHECK_LIB(iodbc, SQLAllocHandle,[ODBC_LIB="$ODBC_LIB -liodbc"; odbc_lib_link_success=yes])
;;
win32|cygwin)
TARGET_FLAGS="-DWIN32"
@@ -170,48 +136,64 @@ AC_SUBST(TARGET_FLAGS)
ODBC_LIB=-L"$with_odbc/lib"
ODBC_INCLUDE="-I$with_odbc/include"
fi
- AC_CHECK_LIB(odbc32, main, [ODBC_LIB="$ODBC_LIB -lodbc32" odbc_lib_link_sucess=yes])
+ AC_CHECK_LIB(odbc32, main, [ODBC_LIB="$ODBC_LIB -lodbc32"; odbc_lib_link_success=yes])
;;
*)
- TARGET_FLAGS="-DUNIX"
- AC_CHECK_LIB(pthread, pthread_create,
- [AC_DEFINE(HAVE_LIBPTHREAD, 1, [Define if you have the pthread library (-lpthread).])
- LIBS="$LIBS -lpthread"
- have_pthread_lib=yes])
- if test ! -d "$with_odbc"; then
- AC_MSG_CHECKING([for odbc in standard locations])
- for dir in /usr/local/odbc /usr/local /usr/odbc \
- /usr /opt/local/pgm/odbc /usr/local/pgm/odbc
- do
- if test -f "$dir/include/sql.h"; then
- is_odbc_std_location=yes
- ODBC_LIB=-L"$dir/lib"
- ODBC_INCLUDE="-I$dir/include"
- break
- fi
- done
- if test "x$is_odbc_std_location" != "xyes"; then
- AC_MSG_RESULT(no)
- AC_MSG_WARN([No odbc library found skipping odbc])
- echo "No odbc library found" > $ERL_TOP/lib/odbc/SKIP
- else
- AC_MSG_RESULT($ODBC_LIB)
- AC_CHECK_LIB(odbc, SQLAllocHandle,[ODBC_LIB="$ODBC_LIB -lodbc" odbc_lib_link_sucess=yes])
- fi
- else
- ODBC_LIB=-L"$with_odbc/lib"
- ODBC_INCLUDE="-I$with_odbc/include"
- AC_CHECK_LIB(odbc, SQLAllocHandle,[ODBC_LIB="$ODBC_LIB -lodbc" odbc_lib_link_sucess=yes])
- fi
+ TARGET_FLAGS="-DUNIX"
+ case "$erl_xcomp_without_sysroot-$with_odbc" in
+ yes-yes | yes- )
+ msg="Dont know where to search for odbc (setting erl_xcomp_sysroot will help)"
+ AC_MSG_WARN([$msg])
+ echo "$msg" > "$ERL_TOP/lib/odbc/SKIP"
+ odbc_lib_link_success=wont_try
+ ;;
+ no- )
+ AC_CHECK_SIZEOF(void *)
+ AC_MSG_CHECKING([for odbc in standard locations])
+ for rdir in /usr/local/odbc /usr/local /usr/odbc \
+ /usr /opt/local/pgm/odbc /usr/local/pgm/odbc; do
+ test -f "$erl_xcomp_isysroot$rdir/include/sql.h" || continue
+ is_odbc_std_location=yes
+ libdir="$erl_xcomp_sysroot$rdir/lib"
+ if test "$ac_cv_sizeof_void_p" = "8"; then
+ dnl "/." in test is important (dir symlinks)
+ if test -d "${libdir}64/."; then
+ libdir="${libdir}64"
+ elif test -d "${libdir}/64/."; then
+ libdir="${libdir}/64"
+ fi
+ fi
+ ODBC_LIB="-L$libdir"
+ ODBC_INCLUDE="-I$erl_xcomp_isysroot$rdir/include"
+ break
+ done
+ if test "x$is_odbc_std_location" != "xyes"; then
+ AC_MSG_RESULT(no)
+ AC_MSG_WARN([No odbc library found skipping odbc])
+ echo "No odbc library found" > "$ERL_TOP/lib/odbc/SKIP"
+ else
+ AC_MSG_RESULT($ODBC_LIB)
+ AC_CHECK_LIB(odbc, SQLAllocHandle,[ODBC_LIB="$ODBC_LIB -lodbc"; odbc_lib_link_success=yes])
+ fi
+ ;;
+
+ no-*)
+ ODBC_LIB=-L"$with_odbc/lib"
+ ODBC_INCLUDE="-I$with_odbc/include"
+ AC_CHECK_LIB(odbc, SQLAllocHandle,[ODBC_LIB="$ODBC_LIB -lodbc"; odbc_lib_link_success=yes])
+ ;;
+ esac
;;
esac
-if test "x$odbc_lib_link_sucess" != "xyes"; then
+if test $odbc_lib_link_success = no; then
AC_MSG_WARN(["ODBC library - link check failed"])
echo "ODBC library - link check failed" > $ERL_TOP/lib/odbc/SKIP
fi
-
+
AC_SUBST(ODBC_LIB)
AC_SUBST(ODBC_INCLUDE)
+fi dnl "$with_odbc" != "no"
+
AC_OUTPUT(c_src/$host/Makefile:c_src/Makefile.in)
diff --git a/lib/odbc/doc/src/Makefile b/lib/odbc/doc/src/Makefile
index 136ddfb980..e2f09733d0 100644
--- a/lib/odbc/doc/src/Makefile
+++ b/lib/odbc/doc/src/Makefile
@@ -1,19 +1,19 @@
#
# %CopyrightBegin%
-#
-# Copyright Ericsson AB 1999-2009. All Rights Reserved.
-#
+#
+# Copyright Ericsson AB 1999-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%
#
@@ -63,6 +63,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 \
odbc.gif \
diff --git a/lib/odbc/doc/src/notes.xml b/lib/odbc/doc/src/notes.xml
index 1f9b3b4290..99584efec9 100644
--- a/lib/odbc/doc/src/notes.xml
+++ b/lib/odbc/doc/src/notes.xml
@@ -4,7 +4,7 @@
<chapter>
<header>
<copyright>
- <year>2004</year><year>2009</year>
+ <year>2004</year><year>2010</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
@@ -13,12 +13,12 @@
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>ODBC Release Notes</title>
@@ -31,7 +31,127 @@
<p>This document describes the changes made to the odbc application.
</p>
- <section><title>ODBC 2.10.6</title>
+ <section><title>ODBC 2.10.7</title>
+
+ <section><title>Fixed Bugs and Malfunctions</title>
+ <list>
+ <item>
+ <p>
+ The odbc application can now be compiled on FreeBSD.
+ (Thanks to Kenji Rikitake.)</p>
+ <p>
+ Own Id: OTP-8444</p>
+ </item>
+ </list>
+ </section>
+
+
+ <section><title>Improvements and New Features</title>
+ <list>
+ <item>
+ <p>Cross compilation improvements and other build system
+ improvements.</p>
+ <p>Most notable:</p> <list><item> Lots of cross
+ compilation improvements. The old cross compilation
+ support was more or less non-existing as well as broken.
+ Please, note that the cross compilation support should
+ still be considered as experimental. Also note that old
+ cross compilation configurations cannot be used without
+ modifications. For more information on cross compiling
+ Erlang/OTP see the <c>$ERL_TOP/INSTALL-CROSS.md</c> file.
+ </item><item> Support for staged install using <url
+ href="http://www.gnu.org/prep/standards/html_node/DESTDIR.html">DESTDIR</url>.
+ The old broken <c>INSTALL_PREFIX</c> has also been fixed.
+ For more information see the <c>$ERL_TOP/INSTALL.md</c>
+ file. </item><item> Documentation of the <c>release</c>
+ target of the top <c>Makefile</c>. For more information
+ see the <c>$ERL_TOP/INSTALL.md</c> file. </item><item>
+ <c>make install</c> now by default creates relative
+ symbolic links instead of absolute ones. For more
+ information see the <c>$ERL_TOP/INSTALL.md</c> file.
+ </item><item> <c>$ERL_TOP/configure --help=recursive</c>
+ now works and prints help for all applications with
+ <c>configure</c> scripts. </item><item> Doing <c>make
+ install</c>, or <c>make release</c> directly after
+ <c>make all</c> no longer triggers miscellaneous
+ rebuilds. </item><item> Existing bootstrap system is now
+ used when doing <c>make install</c>, or <c>make
+ release</c> without a preceding <c>make all</c>.
+ </item><item> The <c>crypto</c> and <c>ssl</c>
+ applications use the same runtime library path when
+ dynamically linking against <c>libssl.so</c> and
+ <c>libcrypto.so</c>. The runtime library search path has
+ also been extended. </item><item> The <c>configure</c>
+ scripts of <c>erl_interface</c> and <c>odbc</c> now
+ search for thread libraries and thread library quirks the
+ same way as <c>erts</c> do. </item><item> The
+ <c>configure</c> script of the <c>odbc</c> application
+ now also looks for odbc libraries in <c>lib64</c> and
+ <c>lib/64</c> directories when building on a 64-bit
+ system. </item><item> The <c>config.h.in</c> file in the
+ <c>erl_interface</c> application is now automatically
+ generated in instead of statically updated which reduces
+ the risk of <c>configure</c> tests without any effect.
+ </item></list>
+ <p>(Thanks to Henrik Riomar for suggestions and
+ testing)</p>
+ <p>(Thanks to Winston Smith for the AVR32-Linux cross
+ configuration and testing)</p>
+ <p>
+ *** POTENTIAL INCOMPATIBILITY ***</p>
+ <p>
+ Own Id: OTP-8323</p>
+ </item>
+ <item>
+ <p>The documentation is now possible to build in an open
+ source environment after a number of bugs are fixed and
+ some features are added in the documentation build
+ process. </p>
+ <p>- The arity calculation is updated.</p>
+ <p>- The module prefix used in the function names for
+ bif's are removed in the generated links so the links
+ will look like
+ "http://www.erlang.org/doc/man/erlang.html#append_element-2"
+ instead of
+ "http://www.erlang.org/doc/man/erlang.html#erlang:append_element-2".</p>
+ <p>- Enhanced the menu positioning in the html
+ documentation when a new page is loaded.</p>
+ <p>- A number of corrections in the generation of man
+ pages (thanks to Sergei Golovan)</p>
+ <p>- The legal notice is taken from the xml book file so
+ OTP's build process can be used for non OTP
+ applications.</p>
+ <p>
+ Own Id: OTP-8343</p>
+ </item>
+ <item>
+ <p>
+ odbc:param_query() now properly indicates if nothing was
+ updated. (Thanks to Paul Oliver.)</p>
+ <p>
+ Own Id: OTP-8347</p>
+ </item>
+ </list>
+ </section>
+
+
+ <section><title>Known Bugs and Problems</title>
+ <list>
+ <item>
+ <p>
+ The ODBC test cases are failing for linux and MacOSX
+ There is problems with setting of options on
+ odbc-connections, and the odbcserver just exits with an
+ exit code.</p>
+ <p>
+ Own Id: OTP-8407</p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
+<section><title>ODBC 2.10.6</title>
<section><title>Fixed Bugs and Malfunctions</title>
<list>
diff --git a/lib/odbc/vsn.mk b/lib/odbc/vsn.mk
index e5daf58815..92540d90f8 100644
--- a/lib/odbc/vsn.mk
+++ b/lib/odbc/vsn.mk
@@ -1,6 +1,6 @@
-ODBC_VSN = 2.10.6
+ODBC_VSN = 2.10.7
-TICKETS = \
+TICKETS_2.10.6 = \
OTP-8250 \
OTP-8291
diff --git a/lib/orber/COSS/CosNaming/orber_cosnaming_utils.erl b/lib/orber/COSS/CosNaming/orber_cosnaming_utils.erl
index 7792839e22..768653c898 100644
--- a/lib/orber/COSS/CosNaming/orber_cosnaming_utils.erl
+++ b/lib/orber/COSS/CosNaming/orber_cosnaming_utils.erl
@@ -2,7 +2,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1999-2009. All Rights Reserved.
+%% Copyright Ericsson AB 1999-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
@@ -536,8 +536,15 @@ lookup(_, _Ctx) ->
receive_msg(Socket, Acc, Timeout) ->
receive
{tcp_closed, Socket} ->
- [_Header, Body] = re:split(Acc,"\r\n\r\n",[{return,list}]),
- Body;
+ case re:split(Acc,"\r\n\r\n",[{return,list}]) of
+ [_Header, Body] ->
+ Body;
+ What ->
+ orber:dbg("[~p] orber_cosnaming_utils:receive_msg();~n"
+ "HTTP server closed the connection before sending a complete reply: ~p.",
+ [?LINE, What], ?DEBUG_LEVEL),
+ corba:raise(#'COMM_FAILURE'{completion_status=?COMPLETED_NO})
+ end;
{tcp, Socket, Response} ->
receive_msg(Socket, Acc ++ Response, Timeout);
{tcp_error, Socket, Reason} ->
diff --git a/lib/orber/doc/src/CosNaming.xml b/lib/orber/doc/src/CosNaming.xml
index db087aedb1..e8c639b59a 100644
--- a/lib/orber/doc/src/CosNaming.xml
+++ b/lib/orber/doc/src/CosNaming.xml
@@ -4,23 +4,21 @@
<erlref>
<header>
<copyright>
- <year>1997</year>
- <year>2007</year>
- <holder>Ericsson AB, All Rights Reserved</holder>
+ <year>1997</year><year>2010</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/.
+ The 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.
+ 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>CosNaming</title>
@@ -66,8 +64,6 @@ typedef sequence <Binding> BindingList;
<item>NamingContext</item>
<item>BindingIterator</item>
</list>
- <p>IDL specification for CosNaming:</p>
- <codeinclude file="../../COSS/CosNaming/cos_naming.idl" tag="" type="c"></codeinclude>
</description>
</erlref>
diff --git a/lib/orber/doc/src/Makefile b/lib/orber/doc/src/Makefile
index 40f5ef8708..b8e26d5ba3 100644
--- a/lib/orber/doc/src/Makefile
+++ b/lib/orber/doc/src/Makefile
@@ -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%
#
#
@@ -64,7 +64,6 @@ XML_REF3_FILES = \
orber_acl.xml
XML_PART_FILES = \
- part_notes_history.xml \
part.xml \
part_notes.xml
@@ -75,7 +74,6 @@ XML_CHAPTER_FILES = \
ch_ifr.xml \
ch_install.xml \
ch_idl_to_erlang_mapping.xml \
- ch_example.xml \
ch_naming_service.xml \
ch_stubs.xml \
ch_security.xml \
@@ -85,10 +83,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 +118,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
deleted file mode 100644
index d4cc5ceddc..0000000000
--- a/lib/orber/doc/src/ch_example.xml
+++ /dev/null
@@ -1,170 +0,0 @@
-<?xml version="1.0" encoding="latin1" ?>
-<!DOCTYPE chapter SYSTEM "chapter.dtd">
-
-<chapter>
- <header>
- <copyright>
- <year>1997</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 Examples</title>
- <prepared></prepared>
- <docno></docno>
- <date>1997-05-20</date>
- <rev>A</rev>
- <file>ch_example.xml</file>
- </header>
-
- <section>
- <title>A Tutorial on How to Create a Simple Service</title>
-
- <section>
- <title>Interface Design</title>
- <p>This example uses a very simple stack server. The specification
- contains two interfaces: the first is the Stack itself and the
- other is the StackFactory which is used to create new stacks.
- The specification is in the file <c>stack.idl</c>.</p>
- <codeinclude file="../../examples/Stack/stack.idl" tag="" type="c"></codeinclude>
- </section>
-
- <section>
- <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").
- </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.
- This will produce among other files a stack API module called
- <c>StackModule_Stack.erl</c> which contains the client stub and
- the server skeleton. </p>
- </section>
-
- <section>
- <title>Implementation of Interface</title>
- <p>After generating the API stubs and the server skeletons it is time to
- implement the servers and if no special options are sent
- to the IDL compiler the file name should be
- <c><![CDATA[<global interface name>_impl.erl]]></c>, in our case
- <c>StackModule_Stack_impl.erl</c>.</p>
- <codeinclude file="../../examples/Stack/StackModule_Stack_impl.erl" tag="" type="erl"></codeinclude>
- <p>We also have the factory interface which is used to create new stacks
- and that implementation is in the file
- <c>StackModule_StackFactory_impl.erl</c>.</p>
- <codeinclude file="../../examples/Stack/StackModule_StackFactory_impl.erl" tag="" type="erl"></codeinclude>
- <p>To start the factory server one executes the function
- <c>StackModule_StackFactory:oe_create/0</c> which in this
- example is done in the module <c>stack_factory.erl</c> where
- the started service is also registered in the name service.</p>
- <codeinclude file="../../examples/Stack/stack_factory.erl" tag="" type="erl"></codeinclude>
- </section>
-
- <section>
- <title>Writing a Client in Erlang</title>
- <p>At last we will write a client to access our service.</p>
- <codeinclude file="../../examples/Stack/stack_client.erl" tag="" type="erl"></codeinclude>
- </section>
-
- <section>
- <title>Writing a Client in Java</title>
- <p>To write a Java client for Orber you must have another
- ORB that uses IIOP for client-server communication and supports a
- Java language mapping. It must also have support for
- <c>IDL:CosNaming/NamingContext</c> or <c>IDL:CosNaming/NamingContextExt</c>.
- If the client ORB support Interoperable Naming Service the Java Client
- can look like:</p>
- <codeinclude file="../../examples/Stack/StackClient.java" tag="" type="c"></codeinclude>
- <note>
- <p>If an ORB does not support CosNaming at all the <c>cos_naming.idl</c>
- file must be compiled and imported.</p>
- </note>
- </section>
-
- <section>
- <title>Building the Example</title>
- <p>To build the example for access from a Java client you need a Java
- enabled ORB (e.g. JavaIDL). The example below is based on JDK-1.4.</p>
- <code type="none">
-fingolfin 127> erl
-Erlang (BEAM) emulator version 5.5.4.3 [async-threads:0] [hipe] [kernel-poll:false]
-
-Eshell V5.5.4.3 (abort with ^G)
-1> ic:gen(stack).
-Erlang IDL compiler version 4.2.12
-ok
-2> make:all().
-Recompile: StackModule_EmptyStack
-Recompile: StackModule_Stack
-Recompile: StackModule_StackFactory
-Recompile: StackModule_StackFactory_impl
-Recompile: StackModule_Stack_impl
-Recompile: oe_stack
-Recompile: stack_client
-Recompile: stack_factory
-up_to_date
-3>
-BREAK: (a)bort (c)ontinue (p)roc info (i)nfo (l)oaded
- (v)ersion (k)ill (D)b-tables (d)istribution
-a
-fingolfin 128> idlj stack.idl
-fingolfin 129> javac StackModule/*.java
-fingolfin 130> javac *.java
-fingolfin 131> cp StackClient.class StackModule/
- </code>
- </section>
-
- <section>
- <title>How to Run Everything</title>
- <p>Below is a short transcript on how to run Orber.</p>
- <code type="none">
-
-fingolfin 143> erl
-Erlang (BEAM) emulator version 5.5.4.3 [async-threads:0] [hipe] [kernel-poll:false]
-
-Eshell V5.5.4.3 (abort with ^G)
-1> orber:jump_start([{interceptors, {native, [orber_iiop_tracer_silent]}}]).
-ok
-2> oe_stack:oe_register().
-ok
-3> stack_factory:start().
-ok
-4> stack_client:run().
-1
-1
-7
-4
-ok
-5>
- </code>
- <p>Before testing the Java part of this example generate and compile Java classes for
- <c>orber/examples/stack.idl</c> as seen in the build example.
- To run the Java client use the following command:</p>
- <code type="none">
-
-fingolfin 38> java StackModule.StackClient "corbaname::localhost:4001#StackFactory"
-1
-1
-7
-4
-Empty stack
-fingolfin 39>
- </code>
- </section>
- </section>
-
-</chapter>
-
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..964ae3e92d 100644
--- a/lib/orber/doc/src/ch_idl_to_erlang_mapping.xml
+++ b/lib/orber/doc/src/ch_idl_to_erlang_mapping.xml
@@ -4,7 +4,7 @@
<chapter>
<header>
<copyright>
- <year>1997</year><year>2009</year>
+ <year>1997</year><year>2010</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
@@ -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>
@@ -445,7 +445,19 @@ void op(in myEnum a);</cell>
<section>
<title>Struct Data Type</title>
<p>A <c>struct</c> may have Basic, Template, Scoped Names and Constructed
- types as members.</p>
+ types as members. By using forward declaration we can define a recursive struct:</p>
+ <code type="none"><![CDATA[
+struct myStruct; // Forward declaration
+typedef sequence<myStruct> myStructSeq;
+struct myStruct {
+ myStructSeq chain;
+};
+
+// Deprecated definition (anonymous) not supported by IC
+struct myStruct {
+ sequence<myStruct> chain;
+};
+ ]]></code>
</section>
<section>
@@ -510,6 +522,25 @@ union LongUnion2 switch(long) {
default: boolean DefaultValue;
};
</code>
+ <p>In the same way as structs, unions can be recursive if forward
+ declaration is used (anonymous types is deprecated and not supported):</p>
+ <code type="none"><![CDATA[
+// Forward declaration
+union myUnion;
+typedef sequence<myUnion>myUnionSeq;
+union myUnion switch (long) {
+ case 1 : myUnionSeq chain;
+ default: boolean DefaultValue;
+};
+ ]]></code>
+
+ <note>
+ <p>Recursive types (union and struct) require Light IFR. I.e. the
+ IC option {light_ifr, true} is used and that Orber is configured in such a way that
+ Light IFR is activated. Recursive TypeCode is currently not supported, which is
+ why these cannot be encapsulated in an any data type.</p>
+ </note>
+
</section>
<warning>
<p>Every field in, for example, a struct must be initiated. Otherwise
@@ -697,14 +728,14 @@ module DB {
module x {
struct y_z {
-\011...
+ ...
};
interface y {
-\011struct z {
-\011 ...
-\011};
+ struct z {
+ ...
+ };
};
};
</code>
@@ -815,7 +846,7 @@ module m {
const float pi = 3.14;
interface i {
-\011const float pi = 3.1415;
+ const float pi = 3.1415;
};
};
</code>
@@ -890,7 +921,7 @@ attribute long RWAttribute;
object internal state with its object reference. The object internal state is
an Erlang term which has a format defined by the user.</p>
<note>
- <p>It is is not always the case that the internal state will be the first parameter, as stubs can use their own object reference as the first parameter (see the IC documentation).</p>
+ <p>It is not always the case that the internal state will be the first parameter, as stubs can use their own object reference as the first parameter (see the IC documentation).</p>
</note>
<p>A function call will invoke an operation. The first
parameter of the function should be the object reference and then
@@ -1036,19 +1067,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 +1095,7 @@ logon(State, ID, PW) ->
%% Description: Initiates the server
%%----------------------------------------------------------------------
init(_Env) ->
-\011{ok, #state{}}.
+ {ok, #state{}}.
%%----------------------------------------------------------------------
@@ -1076,7 +1107,7 @@ init(_Env) ->
%% Description: Invoked when the object is terminating.
%%----------------------------------------------------------------------
terminate(_Reason, _State) ->
-\011ok.
+ ok.
%%----------------------------------------------------------------------
@@ -1090,7 +1121,7 @@ terminate(_Reason, _State) ->
%% due to code replacement.
%%----------------------------------------------------------------------
code_change(_OldVsn, State, _Extra) ->
-\011{ok, State}.
+ {ok, State}.
%%----------------------------------------------------------------------
@@ -1104,7 +1135,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 +1452,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..dde4bf4006 100644
--- a/lib/orber/doc/src/ch_install.xml
+++ b/lib/orber/doc/src/ch_install.xml
@@ -4,7 +4,7 @@
<chapter>
<header>
<copyright>
- <year>1997</year><year>2009</year>
+ <year>1997</year><year>2010</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
@@ -13,12 +13,12 @@
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>Installing Orber</title>
@@ -234,6 +234,16 @@ nodeB@hostB> orber:start().
<cell align="left" valign="middle">0</cell>
</row>
<row>
+ <cell align="left" valign="middle">iiop_out_ports_attempts</cell>
+ <cell align="left" valign="middle">integer() > 0</cell>
+ <cell align="left" valign="middle">1</cell>
+ </row>
+ <row>
+ <cell align="left" valign="middle">iiop_out_ports_random</cell>
+ <cell align="left" valign="middle">true | false</cell>
+ <cell align="left" valign="middle">false</cell>
+ </row>
+ <row>
<cell align="left" valign="middle">iiop_max_fragments</cell>
<cell align="left" valign="middle">integer() > 0 | infinity</cell>
<cell align="left" valign="middle">infinity</cell>
@@ -483,7 +493,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>
@@ -506,6 +516,13 @@ nodeB@hostB> orber:start().
If communicating via SSL, make sure you use a version that supports
the local <c>{port, Port}</c> option. See also
<seealso marker="ch_install#firewall">Firewall Configuration</seealso>.</item>
+ <tag><em>iiop_out_ports_random</em></tag>
+ <item>Requires that <c>iiop_out_ports</c> define a port range. If that is the
+ case Orber will select a port randomly from that sequence.</item>
+ <tag><em>iiop_out_ports_attempts</em></tag>
+ <item>Requires that <c>iiop_out_ports</c> define a port range. If so Orber will
+ accept a number of timeouts, defined by this parameter, when trying to connect
+ to another ORB.</item>
<tag><em>iiop_max_fragments</em></tag>
<item>Limits the number of IIOP fragments allowed per request.</item>
<tag><em>iiop_max_in_requests</em></tag>
@@ -595,7 +612,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 +622,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/example_part.xml b/lib/orber/doc/src/example_part.xml
index 2f549df888..9adb8fa7cf 100644
--- a/lib/orber/doc/src/example_part.xml
+++ b/lib/orber/doc/src/example_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>2010</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/.
+ The 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.
+ 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>Service Implementation</title>
@@ -32,7 +30,6 @@
<description>
<p>This chapter describe how to implement Orber based CORBA services.</p>
</description>
- <include file="ch_example"></include>
<include file="ch_stubs"></include>
</part>
diff --git a/lib/orber/doc/src/make.dep b/lib/orber/doc/src/make.dep
index f19cc18c90..cf5aad747d 100644
--- a/lib/orber/doc/src/make.dep
+++ b/lib/orber/doc/src/make.dep
@@ -12,7 +12,7 @@
book.dvi: CosNaming.tex CosNaming_BindingIterator.tex \
CosNaming_NamingContext.tex CosNaming_NamingContextExt.tex \
Module_Interface.tex any.tex book.tex ch_contents.tex \
- ch_debugging.tex ch_example.tex ch_exceptions.tex \
+ ch_debugging.tex ch_exceptions.tex \
ch_idl_to_erlang_mapping.tex ch_ifr.tex ch_install.tex \
ch_interceptors.tex ch_introduction.tex ch_naming_service.tex \
ch_orber_kernel.tex ch_orberweb.tex ch_security.tex \
@@ -26,15 +26,8 @@ book.dvi: CosNaming.tex CosNaming_BindingIterator.tex \
# Source inlined when transforming from source to LaTeX
# ----------------------------------------------------
-CosNaming.tex: ../../COSS/CosNaming/cos_naming.idl
-
book.tex: ref_man.xml
-ch_example.tex: ../../examples/Stack/StackClient.java ../../examples/Stack/StackModule_StackFactory_impl.erl \
- ../../examples/Stack/StackModule_Stack_impl.erl \
- ../../examples/Stack/stack.idl ../../examples/Stack/stack_client.erl \
- ../../examples/Stack/stack_factory.erl
-
ch_contents.tex: ../../../../system/doc/definitions/term.defs
ch_idl_to_erlang_mapping.tex: ../../../../system/doc/definitions/term.defs
diff --git a/lib/orber/doc/src/notes.xml b/lib/orber/doc/src/notes.xml
index 08bbf4b29c..ba16682f0b 100644
--- a/lib/orber/doc/src/notes.xml
+++ b/lib/orber/doc/src/notes.xml
@@ -4,7 +4,7 @@
<chapter>
<header>
<copyright>
- <year>1997</year><year>2009</year>
+ <year>1997</year><year>2010</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
@@ -13,12 +13,12 @@
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</title>
@@ -33,6 +33,137 @@
</header>
<section>
+ <title>Orber 3.6.19</title>
+
+ <section>
+ <title>Improvements and New Features</title>
+ <list type="bulleted">
+ <item>
+ <p>
+ Partial support for recursive structs and unions.
+ Only available for the erl_corba backend and requires
+ that Light IFR is used. I.e. the IC option {light_ifr, true}
+ and that Orber is configured in such a way that Light IFR
+ is activated. Recursive TypeCode is currently not supported.</p>
+ <p>
+ Own Id: OTP-8868 Aux Id: seq11633</p>
+ </item>
+ </list>
+ </section>
+ <section>
+ <title>Fixed Bugs and Malfunctions</title>
+ <list type="bulleted">
+ <item>
+ <p>The SSL option {ssl_imp, old} was not used if ssl_generation was
+ set to 2. Only R14B was affected by this.</p>
+ <p>Own Id: OTP-8994 Aux Id: seq11747</p>
+ </item>
+ </list>
+ </section>
+ </section>
+
+ <section>
+ <title>Orber 3.6.18</title>
+ <section>
+ <title>Fixed Bugs and Malfunctions</title>
+ <list type="bulleted">
+ <item>
+ <p>A corbaloc http string could return an EXIT message, instead
+ of a system exception, if the HTTP server closed the socket
+ without returning a complete message. I.e. header and a body
+ containing a stringified IOR.</p>
+ <p>Own Id: OTP-8900 Aux Id: seq11704</p>
+ </item>
+ </list>
+ </section>
+ </section>
+
+ <section>
+ <title>Orber 3.6.17</title>
+
+ <section>
+ <title>Improvements and New Features</title>
+ <list type="bulleted">
+ <item>
+ <p>
+ Eliminated warnings for auto-imported BIF clashes.</p>
+ <p>
+ Own Id: OTP-8840</p>
+ </item>
+ </list>
+ </section>
+ </section>
+
+ <section>
+ <title>Orber 3.6.16</title>
+
+ <section>
+ <title>Improvements and New Features</title>
+ <list type="bulleted">
+ <item>
+ <p>
+ Test suites published.</p>
+ <p>
+ Own Id: OTP-8543O Aux Id:</p>
+ </item>
+ </list>
+ </section>
+
+ <section>
+ <title>Fixed Bugs and Malfunctions</title>
+ <list type="bulleted">
+ <item>
+ <p>Added missing trailing bracket to define in hrl-file.</p>
+ <p>Own Id: OTP-8489 Aux Id:</p>
+ </item>
+ </list>
+ </section>
+ </section>
+
+ <section>
+ <title>Orber 3.6.15</title>
+
+ <section>
+ <title>Improvements and New Features</title>
+ <list type="bulleted">
+ <item>
+ <p>
+ Added the configuration parameters iiop_out_ports_attempts and
+ iiop_out_ports_random.</p>
+ <p>
+ Own Id: OTP-8448 Aux Id: seq11498</p>
+ </item>
+ <item>
+ <p>
+ Removed obsolete SSL dependency.</p>
+ <p>
+ Own Id: OTP-8374 Aux Id:</p>
+ </item>
+ <item>
+ <p>
+ Removed the usage of the codeinclude tag in the documentation.</p>
+ <p>
+ Own Id: OTP-8409 Aux Id:</p>
+ </item>
+ </list>
+ </section>
+
+ <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>
@@ -58,7 +189,7 @@
<item>
<p>Obsolete guards, e.g. record vs is_record, has been changed
to avoid compiler warnings.</p>
- <p>Own id: OTP-7987</p>
+ <p>Own Id: OTP-7987</p>
</item>
</list>
</section>
@@ -76,7 +207,7 @@
Naming Service (INS) instead. INS is a part of the OMG
standard specification.</p>
<p>*** POTENTIAL INCOMPATIBILITY ***</p>
- <p>Own id: OTP-7906 Aux Id: seq11243</p>
+ <p>Own Id: OTP-7906 Aux Id: seq11243</p>
</item>
</list>
</section>
@@ -90,7 +221,7 @@
<list type="bulleted">
<item>
<p>Updated file headers.</p>
- <p>Own id: OTP-7837</p>
+ <p>Own Id: OTP-7837</p>
</item>
</list>
</section>
@@ -104,7 +235,7 @@
<list type="bulleted">
<item>
<p>Documentation source included in open source releases.</p>
- <p>Own id: OTP-7595</p>
+ <p>Own Id: OTP-7595</p>
</item>
</list>
</section>
@@ -118,11 +249,11 @@
<list type="bulleted">
<item>
<p>Updated file headers.</p>
- <p>Own id: OTP-7011</p>
+ <p>Own Id: OTP-7011</p>
</item>
<item>
<p>Now compliant with the new behavior of stdlib.</p>
- <p>Own id: OTP-7030 Aux Id: seq10827</p>
+ <p>Own Id: OTP-7030 Aux Id: seq10827</p>
</item>
</list>
</section>
@@ -403,8 +534,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..5e38e4cf9f 100644
--- a/lib/orber/doc/src/orber.xml
+++ b/lib/orber/doc/src/orber.xml
@@ -4,7 +4,7 @@
<erlref>
<header>
<copyright>
- <year>1997</year><year>2009</year>
+ <year>1997</year><year>2010</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
@@ -13,12 +13,12 @@
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</title>
@@ -162,13 +162,33 @@
</func>
<func>
<name>iiop_out_ports() -> 0 | {Min, Max}</name>
- <fsummary>Display the ports Orber may use when connecting to another ORB</fsummary>
+ <fsummary>Display the ports Orber may use when connecting to another ORB</fsummary>
<desc>
<p>The return value of this operation is what the configuration
parameter <seealso marker="ch_install#config">iiop_out_ports</seealso>
- have been set to.</p>
+ has been set to.</p>
+ </desc>
+ </func>
+
+ <func>
+ <name>iiop_out_ports_random() -> true | false</name>
+ <fsummary>Determine if Orber should select local ports randomly</fsummary>
+ <desc>
+ <p>Return the value of the configuration parameter
+ <seealso marker="ch_install#config">iiop_out_ports_random</seealso>.</p>
</desc>
</func>
+
+ <func>
+ <name>iiop_out_ports_attempts() -> int()</name>
+ <fsummary>Display if Orber should accept more than one timeout connecting to another ORB</fsummary>
+ <desc>
+ <p>Return the value of the configuration parameter
+ <seealso marker="ch_install#config">iiop_out_ports_attempts</seealso>.</p>
+ </desc>
+ </func>
+
+
<func>
<name>iiop_ssl_port() -> int()</name>
<fsummary>Display the IIOP port number used for secure connections</fsummary>
@@ -558,7 +578,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.xml b/lib/orber/doc/src/part.xml
index c23456deef..a131db0bad 100644
--- a/lib/orber/doc/src/part.xml
+++ b/lib/orber/doc/src/part.xml
@@ -4,7 +4,7 @@
<part xmlns:xi="http://www.w3.org/2001/XInclude">
<header>
<copyright>
- <year>1997</year><year>2009</year>
+ <year>1997</year><year>2010</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
@@ -13,12 +13,12 @@
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 User's Guide</title>
@@ -39,7 +39,6 @@
<xi:include href="ch_idl_to_erlang_mapping.xml"/>
<xi:include href="ch_naming_service.xml"/>
<xi:include href="ch_security.xml"/>
- <xi:include href="ch_example.xml"/>
<xi:include href="ch_stubs.xml"/>
<xi:include href="ch_exceptions.xml"/>
<xi:include href="ch_interceptors.xml"/>
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/src/cdr_decode.erl b/lib/orber/src/cdr_decode.erl
index 9d30098940..36ef6ce02f 100644
--- a/lib/orber/src/cdr_decode.erl
+++ b/lib/orber/src/cdr_decode.erl
@@ -2,7 +2,7 @@
%%
%% %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
@@ -898,9 +898,13 @@ dec_sequence_struct(Version, Message, N, TypeCodeList, Len, ByteOrder, Buff, C,
{Seq, Rest2, Len2, NewC2} = dec_sequence_struct(Version, Rest1, N - 1, TypeCodeList, Len1, ByteOrder,
Buff, NewC, Name),
{[list_to_tuple([Name |Struct]) | Seq], Rest2, Len2, NewC2}.
-dec_sequence_union(_, Message, 0, _DiscrTC, _Default, _ElementList, Len, _ByteOrder, _Buff, C, _Name) ->
+
+
+dec_sequence_union(_, Message, 0, _DiscrTC, _Default, _ElementList,
+ Len, _ByteOrder, _Buff, C, _Name) ->
{[], Message, Len, C};
-dec_sequence_union(Version, Message, N, DiscrTC, Default, ElementList, Len, ByteOrder, Buff, C, Name) ->
+dec_sequence_union(Version, Message, N, DiscrTC, Default, ElementList,
+ Len, ByteOrder, Buff, C, Name) when is_list(ElementList) ->
{Label, Rest1, Len1, NewC} = dec_type(DiscrTC, Version, Message, Len, ByteOrder, Buff, C),
Result = dec_union(Version, stringify_enum(DiscrTC, Label), ElementList, Default,
@@ -916,7 +920,20 @@ dec_sequence_union(Version, Message, N, DiscrTC, Default, ElementList, Len, Byte
DiscrTC, Default, ElementList,
Len2, ByteOrder,
Buff, NewC3, Name),
- {[{Name, Label, Value} | Seq], Rest3, Len3, NewC4}.
+ {[{Name, Label, Value} | Seq], Rest3, Len3, NewC4};
+dec_sequence_union(Version, Message, N, _DiscrTC, _Default, Module,
+ Len, ByteOrder, Buff, C, Name) when is_atom(Module) ->
+ case catch Module:tc() of
+ {tk_union, _, _, DiscrTC, Default, ElementList} ->
+ dec_sequence_union(Version, Message, N, DiscrTC, Default, ElementList,
+ Len, ByteOrder, Buff, C, Name);
+ What ->
+ orber:dbg("[~p] ~p:dec_sequence_union(~p). Union module doesn't exist or incorrect.",
+ [?LINE, ?MODULE, What], ?DEBUG_LEVEL),
+ corba:raise(#'MARSHAL'{completion_status=?COMPLETED_MAYBE})
+ end.
+
+
%% A special case; when something is encapsulated (i.e. sent as octet-sequence)
%% we sometimes don not want the result to be converted to a list.
@@ -993,14 +1010,16 @@ dec_wstring(Version, Message, Len, ByteOrder, Buff, C) ->
%% Func: dec_union/9
%%-----------------------------------------------------------------
%% ## NEW IIOP 1.2 ##
-dec_union(Version, ?SYSTEM_TYPE, Name, DiscrTC, Default, ElementList, Bytes, Len, ByteOrder, Buff, C) ->
+dec_union(Version, ?SYSTEM_TYPE, Name, DiscrTC, Default, ElementList, Bytes,
+ Len, ByteOrder, Buff, C) ->
{Label, Rest1, Len1, NewC} = dec_type(DiscrTC, Version, Bytes, Len, ByteOrder, Buff, C),
{Value, Rest2, Len2, NewC3} = dec_union(Version, Label, ElementList, Default,
Rest1, Len1, ByteOrder, Buff, NewC),
{{Name, Label, Value}, Rest2, Len2, NewC3};
-dec_union(Version, IFRId, _, DiscrTC, Default, ElementList, Bytes, Len, ByteOrder, Buff, C) ->
+dec_union(Version, IFRId, _, DiscrTC, Default, ElementList, Bytes, Len,
+ ByteOrder, Buff, C) when is_list(ElementList) ->
{Label, Rest1, Len1, NewC} = dec_type(DiscrTC, Version, Bytes, Len, ByteOrder, Buff, C),
Result = dec_union(Version, stringify_enum(DiscrTC, Label), ElementList, Default,
Rest1, Len1, ByteOrder, Buff, NewC),
@@ -1012,7 +1031,20 @@ dec_union(Version, IFRId, _, DiscrTC, Default, ElementList, Bytes, Len, ByteOrde
X
end,
Name = ifrid_to_name(IFRId, ?IFR_UnionDef),
- {{Name, Label, Value}, Rest2, Len2, NewC3}.
+ {{Name, Label, Value}, Rest2, Len2, NewC3};
+dec_union(Version, IFRId, _, _DiscrTC, _Default, Module, Bytes, Len,
+ ByteOrder, Buff, C) when is_atom(Module) ->
+ case catch Module:tc() of
+ {tk_union, _, Name, DiscrTC, Default, ElementList} ->
+ dec_union(Version, IFRId, Name, DiscrTC, Default, ElementList, Bytes, Len,
+ ByteOrder, Buff, C);
+ What ->
+ orber:dbg("[~p] ~p:dec_union(~p). Union module doesn't exist or incorrect.",
+ [?LINE, ?MODULE, What], ?DEBUG_LEVEL),
+ corba:raise(#'MARSHAL'{completion_status=?COMPLETED_MAYBE})
+ end.
+
+
dec_union(_, _, [], Default, Message, Len, _, _Buff, C) when Default < 0 ->
{undefined, Message, Len, C};
@@ -1047,7 +1079,16 @@ dec_struct1(_, [], Message, Len, _ByteOrder, _, C) ->
dec_struct1(Version, [{_ElemName, ElemType} | TypeCodeList], Message, Len, ByteOrder, Buff, C) ->
{Element, Rest, Len1, NewC} = dec_type(ElemType, Version, Message, Len, ByteOrder, Buff, C),
{Struct, Rest1, Len2, NewC2} = dec_struct1(Version, TypeCodeList, Rest, Len1, ByteOrder, Buff, NewC),
- {[Element |Struct], Rest1, Len2, NewC2}.
+ {[Element |Struct], Rest1, Len2, NewC2};
+dec_struct1(Version, Module, Message, Len, ByteOrder, Buff, C) ->
+ case catch Module:tc() of
+ {tk_struct, _, _, TypeCodeList} ->
+ dec_struct1(Version, TypeCodeList, Message, Len, ByteOrder, Buff, C);
+ What ->
+ orber:dbg("[~p] ~p:dec_struct1(~p). Struct module doesn't exist or incorrect.",
+ [?LINE, ?MODULE, What], ?DEBUG_LEVEL),
+ corba:raise(#'MARSHAL'{completion_status=?COMPLETED_MAYBE})
+ end.
ifrid_to_name([], Type) ->
orber:dbg("[~p] ~p:ifrid_to_name([], ~p). No Id supplied.",
@@ -1232,7 +1273,9 @@ get_user_exception_type(TypeId) ->
%%-----------------------------------------------------------------
dec_type_code(Version, Message, Len, ByteOrder, Buff, C) ->
{TypeNo, Message1, Len1, NewC} = dec_type('tk_ulong', Version, Message, Len, ByteOrder, Buff, C),
- dec_type_code(TypeNo, Version, Message1, Len1, ByteOrder, Buff, NewC).
+ TC = dec_type_code(TypeNo, Version, Message1, Len1, ByteOrder, Buff, NewC),
+ erase(orber_indirection),
+ TC.
%%-----------------------------------------------------------------
%% Func: dec_type_code/5
@@ -1441,13 +1484,22 @@ dec_type_code(33, Version, Message, Len, ByteOrder, Buff, C) ->
{"name", {'tk_string', 0}}]},
Version, Rest1, 1, ByteOrder1, Buff, C+1+Ex),
{{'tk_local_interface', RepId, Name}, Message1, Len1, NewC};
-dec_type_code(16#ffffffff, Version, Message, Len, ByteOrder, Buff, C) -> %% placeholder
+dec_type_code(16#ffffffff, Version, Message, Len, ByteOrder, Buff, C) ->
{Indirection, Message1, Len1, NewC} =
dec_type('tk_long', Version, Message, Len, ByteOrder, Buff, C),
Position = C+Indirection,
- <<_:Position/binary, SubBuff/binary>> = Buff,
- {TC, _, _, _} = dec_type_code(Version, SubBuff, Position, ByteOrder, Buff, Position),
- {TC, Message1, Len1, NewC};
+ case put(orber_indirection, Position) of
+ Position ->
+%% {{'none', Indirection}, Message1, Len1, NewC};
+ %% Recursive TypeCode. Break the loop.
+ orber:dbg("[~p] cdr_decode:dec_type_code(~p); Recursive TC not supported.",
+ [?LINE,Position], ?DEBUG_LEVEL),
+ corba:raise(#'MARSHAL'{completion_status=?COMPLETED_NO});
+ _ ->
+ <<_:Position/binary, SubBuff/binary>> = Buff,
+ {TC, _, _, _} = dec_type_code(Version, SubBuff, Position, ByteOrder, Buff, Position),
+ {TC, Message1, Len1, NewC}
+ end;
dec_type_code(Type, _, _, _, _, _, _) ->
orber:dbg("[~p] cdr_decode:dec_type_code(~p); No match.",
[?LINE, Type], ?DEBUG_LEVEL),
diff --git a/lib/orber/src/cdr_encode.erl b/lib/orber/src/cdr_encode.erl
index 3ecb8833f5..eaf3c5b7dc 100644
--- a/lib/orber/src/cdr_encode.erl
+++ b/lib/orber/src/cdr_encode.erl
@@ -2,7 +2,7 @@
%%
%% %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
@@ -815,11 +815,21 @@ enc_wstring(Env, String, MaxLength, Bytes, Len) ->
%%-----------------------------------------------------------------
%% Func: enc_union/5
%%-----------------------------------------------------------------
-enc_union(Env, {_, Label, Value}, DiscrTC, Default, TypeCodeList, Bytes, Len) ->
+enc_union(Env, {_, Label, Value}, DiscrTC, Default, TypeCodeList,
+ Bytes, Len) when is_list(TypeCodeList) ->
{ByteSequence, Len1} = enc_type(DiscrTC, Env, Label, Bytes, Len),
Label2 = stringify_enum(DiscrTC,Label),
enc_union2(Env, {Label2, Value},TypeCodeList, Default,
- ByteSequence, Len1, undefined).
+ ByteSequence, Len1, undefined);
+enc_union(Env, Value, _DiscrTC, _Default, Module, Bytes, Len) when is_atom(Module) ->
+ case catch Module:tc() of
+ {tk_union, _, _, DiscrTC, Default, ElementList} ->
+ enc_union(Env, Value, DiscrTC, Default, ElementList, Bytes, Len);
+ What ->
+ orber:dbg("[~p] ~p:enc_union(~p). Union module doesn't exist or incorrect.",
+ [?LINE, ?MODULE, What], ?DEBUG_LEVEL),
+ corba:raise(#'MARSHAL'{completion_status=?COMPLETED_MAYBE})
+ end.
enc_union2(_Env, _What, [], Default, Bytes, Len, _) when Default < 0 ->
{Bytes, Len};
@@ -840,9 +850,19 @@ stringify_enum(_, Label) ->
%%-----------------------------------------------------------------
%% Func: enc_struct/4
%%-----------------------------------------------------------------
-enc_struct(Env, Struct, TypeCodeList, Bytes, Len) ->
+enc_struct(Env, Struct, TypeCodeList, Bytes, Len) when is_list(TypeCodeList) ->
[_Name | StructList] = tuple_to_list(Struct),
- enc_struct1(Env, StructList, TypeCodeList, Bytes, Len).
+ enc_struct1(Env, StructList, TypeCodeList, Bytes, Len);
+enc_struct(Env, Struct, Module, Bytes, Len) ->
+ [Module | StructList] = tuple_to_list(Struct),
+ case catch Module:tc() of
+ {tk_struct, _, _, TypeCodeList} ->
+ enc_struct1(Env, StructList, TypeCodeList, Bytes, Len);
+ What ->
+ orber:dbg("[~p] ~p:enc_struct([], ~p). Struct module doesn't exist or incorrect.",
+ [?LINE, ?MODULE, What], ?DEBUG_LEVEL),
+ corba:raise(#'MARSHAL'{completion_status=?COMPLETED_MAYBE})
+ end.
enc_struct1(_Env, [], [], Bytes, Len) ->
{Bytes, Len};
diff --git a/lib/orber/src/orber.erl b/lib/orber/src/orber.erl
index e9c6822551..c3d37ad1fb 100644
--- a/lib/orber/src/orber.erl
+++ b/lib/orber/src/orber.erl
@@ -1,20 +1,20 @@
%%--------------------------------------------------------------------
%%
%% %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%
%%
%%
@@ -34,7 +34,8 @@
%% External exports
%%-----------------------------------------------------------------
-export([start/0, start/1, stop/0, install/1, install/2, orber_nodes/0, iiop_port/0,
- domain/0, iiop_ssl_port/0, iiop_out_ports/0,
+ domain/0, iiop_ssl_port/0, iiop_out_ports/0, iiop_out_ports_random/0,
+ iiop_out_ports_attempts/0,
ssl_server_certfile/0, ssl_client_certfile/0, set_ssl_client_certfile/1,
ssl_server_verify/0, ssl_client_verify/0, set_ssl_client_verify/1,
ssl_server_depth/0, ssl_client_depth/0, set_ssl_client_depth/1,
@@ -305,6 +306,12 @@ nat_iiop_port() ->
iiop_out_ports() ->
orber_env:iiop_out_ports().
+iiop_out_ports_random() ->
+ orber_env:iiop_out_ports_random().
+
+iiop_out_ports_attempts() ->
+ orber_env:iiop_out_ports_attempts().
+
orber_nodes() ->
case catch mnesia:table_info(orber_objkeys,ram_copies) of
Nodes when is_list(Nodes) ->
diff --git a/lib/orber/src/orber_env.erl b/lib/orber/src/orber_env.erl
index 79f852eee0..d80edb4ee0 100644
--- a/lib/orber/src/orber_env.erl
+++ b/lib/orber/src/orber_env.erl
@@ -1,20 +1,20 @@
%%--------------------------------------------------------------------
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2004-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 2004-2010. All Rights Reserved.
+%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
-%%
+%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
-%%
+%%
%% %CopyrightEnd%
%%
%%
@@ -43,8 +43,8 @@
-export([iiop_acl/0, iiop_port/0, nat_iiop_port/0, nat_iiop_port/1, iiop_out_ports/0,
domain/0, ip_address_variable_defined/0, nat_host/0, nat_host/1, host/0,
- ip_address/0, ip_address/1, giop_version/0, iiop_timeout/0,
- iiop_connection_timeout/0, iiop_setup_connection_timeout/0,
+ ip_address/0, ip_address/1, giop_version/0, iiop_timeout/0, iiop_out_ports_random/0,
+ iiop_connection_timeout/0, iiop_setup_connection_timeout/0, iiop_out_ports_attempts/0,
iiop_in_connection_timeout/0, iiop_max_fragments/0, iiop_max_in_requests/0,
iiop_max_in_connections/0, iiop_backlog/0, objectkeys_gc_time/0,
get_ORBInitRef/0, get_ORBDefaultInitRef/0, get_interceptors/0,
@@ -234,6 +234,8 @@ create_main_info() ->
"IIOP out connection timeout...: ~p msec~n"
"IIOP setup connection timeout.: ~p msec~n"
"IIOP out ports................: ~p~n"
+ "IIOP out ports attempts.......: ~p~n"
+ "IIOP out ports random.........: ~p~n"
"IIOP out connections..........: ~p~n"
"IIOP out connections (pending): ~p~n"
"IIOP out keepalive............: ~p~n"
@@ -256,7 +258,8 @@ create_main_info() ->
nat_host(), ip_address_local(),
orber:orber_nodes(), Major, Minor,
iiop_timeout(), iiop_connection_timeout(),
- iiop_setup_connection_timeout(), iiop_out_ports(),
+ iiop_setup_connection_timeout(), iiop_out_ports(),
+ iiop_out_ports_attempts(), iiop_out_ports_random(),
orber:iiop_connections(out), orber:iiop_connections_pending(),
iiop_out_keepalive(), orber:iiop_connections(in),
iiop_in_connection_timeout(), iiop_in_keepalive(),
@@ -389,6 +392,23 @@ iiop_out_ports() ->
0
end.
+iiop_out_ports_random() ->
+ case application:get_env(orber, iiop_out_ports_random) of
+ {ok, true} ->
+ true;
+ _ ->
+ false
+ end.
+
+iiop_out_ports_attempts() ->
+ case application:get_env(orber, iiop_out_ports_attempts) of
+ {ok, No} when is_integer(No) andalso No > 0 ->
+ No;
+ _ ->
+ 1
+ end.
+
+
domain() ->
case application:get_env(orber, domain) of
{ok, Domain} when is_list(Domain) ->
@@ -1251,6 +1271,12 @@ configure(nat_ip_address, {local, Value1, Value2}, Status) when is_list(Value1)
%% Set the range of ports we may use on this machine when connecting to a server.
configure(iiop_out_ports, {Min, Max}, Status) when is_integer(Min) andalso is_integer(Max) ->
do_safe_configure(iiop_out_ports, {Min, Max}, Status);
+configure(iiop_out_ports_attempts, Max, Status) when is_integer(Max) andalso Max > 0 ->
+ do_safe_configure(iiop_out_ports_attempts, Max, Status);
+configure(iiop_out_ports_random, true, Status) ->
+ do_safe_configure(iiop_out_ports_random, true, Status);
+configure(iiop_out_ports_random, false, Status) ->
+ do_safe_configure(iiop_out_ports_random, false, Status);
%% Set the lightweight option.
configure(lightweight, Value, Status) when is_list(Value) ->
do_safe_configure(lightweight, Value, Status);
diff --git a/lib/orber/src/orber_socket.erl b/lib/orber/src/orber_socket.erl
index 2a64bd4e75..84ed193ebb 100644
--- a/lib/orber/src/orber_socket.erl
+++ b/lib/orber/src/orber_socket.erl
@@ -1,20 +1,20 @@
%%--------------------------------------------------------------------
%%
%% %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%
%%
%%
@@ -82,17 +82,17 @@ connect(Type, Host, Port, Options) ->
end,
case orber:iiop_out_ports() of
{Min, Max} when Type == normal ->
- multi_connect(Min, Max, Type, Host, Port,
- [binary, {reuseaddr, true},
- {packet,cdr}| Options2], Timeout);
+ multi_connect(get_port_sequence(Min, Max), orber_env:iiop_out_ports_attempts(),
+ Type, Host, Port, [binary, {reuseaddr, true},
+ {packet,cdr}| Options2], Timeout);
{Min, Max} when Generation > 2 ->
- multi_connect(Min, Max, Type, Host, Port,
- [binary, {reuseaddr, true},
- {packet,cdr}| Options2], Timeout);
+ multi_connect(get_port_sequence(Min, Max), orber_env:iiop_out_ports_attempts(),
+ Type, Host, Port, [binary, {reuseaddr, true},
+ {packet,cdr}| Options2], Timeout);
{Min, Max} ->
%% reuseaddr not available for older SSL versions
- multi_connect(Min, Max, Type, Host, Port,
- [binary, {packet,cdr}| Options2], Timeout);
+ multi_connect(get_port_sequence(Min, Max), orber_env:iiop_out_ports_attempts(),
+ Type, Host, Port, [binary, {packet,cdr}| Options2], Timeout);
_ ->
connect(Type, Host, Port, [binary, {packet,cdr}| Options2], Timeout)
end.
@@ -130,17 +130,17 @@ connect(ssl, Host, Port, Options, Timeout) ->
corba:raise(#'COMM_FAILURE'{completion_status=?COMPLETED_NO})
end.
-multi_connect(CurrentPort, Max, Type, Host, Port, Options, _) when CurrentPort > Max ->
+multi_connect([], _Retries, Type, Host, Port, Options, _) ->
orber:dbg("[~p] orber_socket:multi_connect(~p, ~p, ~p, ~p);~n"
"Unable to use any of the sockets defined by 'iiop_out_ports'.~n"
"Either all ports are in use or to many connections already exists.",
[?LINE, Type, Host, Port, Options], ?DEBUG_LEVEL),
corba:raise(#'IMP_LIMIT'{minor=(?ORBER_VMCID bor 1), completion_status=?COMPLETED_NO});
-multi_connect(CurrentPort, Max, normal, Host, Port, Options, Timeout) ->
+multi_connect([CurrentPort|Rest], Retries, normal, Host, Port, Options, Timeout) ->
case catch gen_tcp:connect(Host, Port, [{port, CurrentPort}|Options], Timeout) of
{ok, Socket} ->
Socket;
- {error, timeout} ->
+ {error, timeout} when Retries =< 1 ->
orber:dbg("[~p] orber_socket:multi_connect(normal, ~p, ~p, ~p);~n"
"Timeout after ~p msec.",
[?LINE, Host, Port, [{port, CurrentPort}|Options],
@@ -148,13 +148,13 @@ multi_connect(CurrentPort, Max, normal, Host, Port, Options, Timeout) ->
corba:raise(#'COMM_FAILURE'{minor=(?ORBER_VMCID bor 4),
completion_status=?COMPLETED_NO});
_ ->
- multi_connect(CurrentPort+1, Max, normal, Host, Port, Options, Timeout)
+ multi_connect(Rest, Retries - 1, normal, Host, Port, Options, Timeout)
end;
-multi_connect(CurrentPort, Max, ssl, Host, Port, Options, Timeout) ->
+multi_connect([CurrentPort|Rest], Retries, ssl, Host, Port, Options, Timeout) ->
case catch ssl:connect(Host, Port, [{port, CurrentPort}|Options], Timeout) of
{ok, Socket} ->
Socket;
- {error, timeout} ->
+ {error, timeout} when Retries =< 1 ->
orber:dbg("[~p] orber_socket:multi_connect(ssl, ~p, ~p, ~p);~n"
"Timeout after ~p msec.",
[?LINE, Host, Port, [{port, CurrentPort}|Options],
@@ -162,10 +162,28 @@ multi_connect(CurrentPort, Max, ssl, Host, Port, Options, Timeout) ->
corba:raise(#'COMM_FAILURE'{minor=(?ORBER_VMCID bor 4),
completion_status=?COMPLETED_NO});
_ ->
- multi_connect(CurrentPort+1, Max, ssl, Host, Port, Options, Timeout)
+ multi_connect(Rest, Retries - 1, ssl, Host, Port, Options, Timeout)
end.
+get_port_sequence(Min, Max) ->
+ case orber_env:iiop_out_ports_random() of
+ true ->
+ {A1,A2,A3} = now(),
+ random:seed(A1, A2, A3),
+ Seq = lists:seq(Min, Max),
+ random_sequence((Max - Min) + 1, Seq, []);
+ _ ->
+ lists:seq(Min, Max)
+ end.
+
+random_sequence(0, _, Acc) ->
+ Acc;
+random_sequence(Length, Seq, Acc) ->
+ Nth = random:uniform(Length),
+ Value = lists:nth(Nth, Seq),
+ NewSeq = lists:delete(Value, Seq),
+ random_sequence(Length-1, NewSeq, [Value|Acc]).
%%-----------------------------------------------------------------
%% Create a listen socket at Port in CDR mode for
@@ -478,27 +496,17 @@ check_port(Port, _, _) ->
%%-----------------------------------------------------------------
%% Check Options.
-%% We need this as a work-around since the SSL-app doesn't allow us
-%% to pass 'inet' as an option. Also needed for R9B :-(
check_options(normal, Options, _Generation) ->
- case orber:ip_version() of
- inet ->
- Options;
- inet6 ->
- %% Necessary for R9B. Should be [orber:ip_version()|Options];
- [inet6|Options]
- end;
+ [orber:ip_version()|Options];
check_options(ssl, Options, Generation) ->
case orber:ip_version() of
inet when Generation > 2 ->
[{ssl_imp, new}|Options];
inet ->
- Options;
+ [{ssl_imp, old}|Options];
inet6 when Generation > 2 ->
[{ssl_imp, new}, inet6|Options];
inet6 ->
- %% Will fail until SSL supports this option.
- %% Note, we want this happen!
- [inet6|Options]
+ [{ssl_imp, old}, inet6|Options]
end.
diff --git a/lib/orber/test/Makefile b/lib/orber/test/Makefile
new file mode 100644
index 0000000000..5495735318
--- /dev/null
+++ b/lib/orber/test/Makefile
@@ -0,0 +1,232 @@
+#
+# %CopyrightBegin%
+#
+# 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%
+#
+#
+include $(ERL_TOP)/make/target.mk
+include $(ERL_TOP)/make/$(TARGET)/otp.mk
+
+# ----------------------------------------------------
+# Application version
+# ----------------------------------------------------
+include ../vsn.mk
+VSN=$(ORBER_VSN)
+# ----------------------------------------------------
+# Release directory specification
+# ----------------------------------------------------
+RELSYSDIR = $(RELEASE_PATH)/orber_test
+
+# ----------------------------------------------------
+# Target Specs
+# ----------------------------------------------------
+TEST_SPEC_FILE = orber.spec
+
+
+IDL_FILES = \
+ orber_test.idl \
+ iiop_test.idl \
+ orber_test_server.idl
+
+IDLOUTDIR = idl_output
+
+MODULES = \
+ cdrcoding_11_SUITE \
+ cdrcoding_10_SUITE \
+ cdrcoding_12_SUITE \
+ cdrlib_SUITE \
+ corba_SUITE \
+ iop_ior_11_SUITE \
+ iop_ior_10_SUITE \
+ iop_ior_12_SUITE \
+ iiop_module_do_test_impl \
+ iiop_module_test_impl \
+ lname_SUITE \
+ naming_context_SUITE \
+ orber_SUITE \
+ orber_test_server_impl \
+ orber_test_timeout_server_impl \
+ orber_test_lib \
+ csiv2_SUITE \
+ multi_ORB_SUITE \
+ data_types_SUITE \
+ tc_SUITE \
+ generated_SUITE \
+ orber_web_SUITE \
+ interceptors_SUITE \
+ orber_acl_SUITE \
+ orber_firewall_ipv4_in_SUITE \
+ orber_firewall_ipv6_in_SUITE \
+ orber_firewall_ipv4_out_SUITE \
+ orber_firewall_ipv6_out_SUITE \
+ orber_nat_SUITE
+
+GEN_MOD_ORBER = \
+ oe_orber_test \
+ Module_Except1 \
+ Module_Except2 \
+ Module_Except3 \
+ Module_Except4 \
+ Module_HEADER \
+ Module_I1 \
+ Module_I2 \
+ Module_Struct0 \
+ Module_Struct1 \
+ Module_Struct2 \
+ Module_Union \
+ Module_Union1 \
+ Module_Union2
+
+GEN_HRL_ORBER = \
+ oe_orber_test.hrl \
+ Module.hrl \
+ Module_I1.hrl \
+ Module_I2.hrl
+
+GEN_MOD_IIOP = \
+ oe_iiop_test \
+ iiop_module_Except1 \
+ iiop_module_Struct1 \
+ iiop_module_Union1 \
+ iiop_module_do_test \
+ iiop_module_test \
+ iiop_module_test_retval
+
+GEN_HRL_IIOP = \
+ oe_iiop_test.hrl \
+ iiop_module.hrl \
+ iiop_module_do_test.hrl \
+ iiop_module_test.hrl
+
+GEN_MOD_TEST_SERVER = \
+ oe_orber_test_server \
+ orber_test_server \
+ orber_test_server_ComplexUserDefinedException \
+ orber_test_server_UserDefinedException \
+ orber_test_server_struc \
+ orber_test_server_uni \
+ orber_test_server_uni_d \
+ orber_test_timeout_server \
+ orber_parent_inherrit \
+ orber_test_server_rec_struct \
+ orber_test_server_rec_struct_seq \
+ orber_test_server_rec_union \
+ orber_test_server_rec_union_seq
+
+GEN_HRL_TEST_SERVER = \
+ oe_orber_test_server.hrl \
+ orber_test_server.hrl \
+ orber_test_timeout_server.hrl
+
+GEN_MODULES = $(GEN_MOD_ORBER) $(GEN_MOD_IIOP) \
+ $(GEN_MOD_TEST_SERVER)
+
+ERL_FILES = $(MODULES:%=%.erl)
+
+HRL_FILES =
+
+GEN_HRL_FILES = $(GEN_HRL_ORBER) $(GEN_HRL_IIOP) \
+ $(GEN_HRL_TEST_SERVER)
+
+GEN_FILES = \
+ $(GEN_HRL_FILES:%=$(IDLOUTDIR)/%) \
+ $(GEN_MODULES:%=$(IDLOUTDIR)/%.erl)
+
+GEN_TARGET_FILES = $(GEN_MODULES:%=$(IDLOUTDIR)/%.$(EMULATOR))
+
+SUITE_TARGET_FILES = $(MODULES:%=%.$(EMULATOR))
+
+TARGET_FILES = \
+ $(GEN_TARGET_FILES) \
+ $(SUITE_TARGET_FILES)
+
+# ----------------------------------------------------
+# FLAGS
+# ----------------------------------------------------
+ERL_IDL_FLAGS += -pa $(ERL_TOP)/lib/orber/ebin -pa $(ERL_TOP)/lib/ic/ebin
+
+ERL_COMPILE_FLAGS += $(ERL_IDL_FLAGS) \
+ -pa $(ERL_TOP)/lib/test_server/ebin \
+ -pa $(ERL_TOP)/lib/ic/ebin \
+ -pa $(ERL_TOP)/lib/orber/ebin \
+ -I$(ERL_TOP)/lib/orber \
+ -I$(ERL_TOP)/lib/orber/test/$(IDLOUTDIR) \
+ -I$(ERL_TOP)/lib/test_server/include
+
+# ----------------------------------------------------
+# Targets
+# ----------------------------------------------------
+tests debug opt: $(TARGET_FILES)
+
+clean:
+ rm -f idl_output/*
+ rm -f $(TARGET_FILES)
+ rm -f errs core *~
+
+
+docs:
+
+# ----------------------------------------------------
+# Special Targets
+# ----------------------------------------------------
+
+#
+# Each IDL file produces many target files so no pattern
+# rule can be used.
+#
+TGT_ORBER = \
+ $(GEN_HRL_ORBER:%=$(IDLOUTDIR)/%) \
+ $(GEN_MOD_ORBER:%=$(IDLOUTDIR)/%.erl)
+TGT_IIOP = \
+ $(GEN_HRL_IIOP:%=$(IDLOUTDIR)/%) \
+ $(GEN_MOD_IIOP:%=$(IDLOUTDIR)/%.erl)
+
+TGT_TEST_SERVER = \
+ $(GEN_HRL_TEST_SERVER:%=$(IDLOUTDIR)/%) \
+ $(GEN_MOD_TEST_SERVER:%=$(IDLOUTDIR)/%.erl)
+
+$(TGT_ORBER): orber_test.idl
+ erlc $(ERL_IDL_FLAGS) -o$(IDLOUTDIR) orber_test.idl
+
+$(TGT_IIOP): iiop_test.idl
+ erlc $(ERL_IDL_FLAGS) -o$(IDLOUTDIR) \
+ +'{preproc_flags,"-I../COSS/CosNaming"}' iiop_test.idl
+
+$(TGT_TEST_SERVER): orber_test_server.idl
+ erlc $(ERL_IDL_FLAGS) -o$(IDLOUTDIR) \
+ +'{cfgfile,"orber_test_server.cfg"}' orber_test_server.idl
+
+# ----------------------------------------------------
+# Release Targets
+# ----------------------------------------------------
+# We don't copy generated intermediate erlang and hrl files
+
+include $(ERL_TOP)/make/otp_release_targets.mk
+
+release_spec:
+
+release_docs_spec:
+
+release_tests_spec: tests
+ $(INSTALL_DIR) $(RELSYSDIR)
+ $(INSTALL_DATA) $(IDL_FILES) $(TEST_SPEC_FILE) \
+ $(ERL_FILES) $(RELSYSDIR)
+ $(INSTALL_DATA) $(SUITE_TARGET_FILES) $(RELSYSDIR)
+ chmod -f -R u+w $(RELSYSDIR)
+ $(INSTALL_DIR) $(RELSYSDIR)/$(IDLOUTDIR)
+ $(INSTALL_DATA) $(GEN_TARGET_FILES) $(GEN_FILES) \
+ $(RELSYSDIR)/$(IDLOUTDIR)
+
diff --git a/lib/orber/test/cdrcoding_10_SUITE.erl b/lib/orber/test/cdrcoding_10_SUITE.erl
new file mode 100644
index 0000000000..d5d030538f
--- /dev/null
+++ b/lib/orber/test/cdrcoding_10_SUITE.erl
@@ -0,0 +1,616 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 1999-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%
+%%
+%%
+%%-----------------------------------------------------------------
+%%
+%% Description:
+%% Test suite for the CDR encode/decode functions
+%%
+%%-----------------------------------------------------------------
+-module(cdrcoding_10_SUITE).
+
+
+-include("idl_output/Module.hrl").
+-include("test_server.hrl").
+-include_lib("orber/include/corba.hrl").
+-include_lib("orber/src/orber_iiop.hrl").
+
+-define(default_timeout, ?t:minutes(20)).
+
+%%-----------------------------------------------------------------
+%% External exports
+%%-----------------------------------------------------------------
+-export([all/1]).
+
+%%-----------------------------------------------------------------
+%% Internal exports
+%%-----------------------------------------------------------------
+-export([]).
+-compile(export_all).
+
+%%-----------------------------------------------------------------
+%% Func: all/1
+%% Args:
+%% Returns:
+%%-----------------------------------------------------------------
+all(doc) -> ["Description", "more description"];
+all(suite) -> {req,
+ [mnesia],
+ {conf, init_all, cases(), finish_all}}.
+
+cases() ->
+ [types, reply, cancel_request, close_connection, message_error].
+%% request, locate_request, locate_reply].
+
+%%-----------------------------------------------------------------
+%% Init and cleanup functions.
+%%-----------------------------------------------------------------
+
+init_per_testcase(_Case, Config) ->
+ Path = code:which(?MODULE),
+ code:add_pathz(filename:join(filename:dirname(Path), "idl_output")),
+ ?line Dog=test_server:timetrap(?default_timeout),
+ [{watchdog, Dog}|Config].
+
+
+fin_per_testcase(_Case, Config) ->
+ Path = code:which(?MODULE),
+ code:del_path(filename:join(filename:dirname(Path), "idl_output")),
+ Dog = ?config(watchdog, Config),
+ test_server:timetrap_cancel(Dog),
+ ok.
+
+init_all(Config) when is_list(Config) ->
+ orber:jump_start(0),
+ if
+ is_list(Config) ->
+ Config;
+ true ->
+ exit("Config not a list")
+ end.
+
+finish_all(Config) when is_list(Config) ->
+ orber:jump_stop(),
+ Config.
+
+%%-----------------------------------------------------------------
+%% Test Case: type encoding tests
+%% Description: Just testing the complex types, the others are
+%% tested in the cdrlib SUITE.
+%%-----------------------------------------------------------------
+types(doc) -> ["Description", "more description"];
+types(suite) -> [do_register, null_type, void_type, principal_type,
+ objref_type, struct_type, union_type, string_type,
+ array_type, any_type, typecode_type, alias_type,
+ exception_type, do_unregister].
+%types(Config) when list(Config) ->
+% 'oe_orber_test':'oe_register'(),
+% null_type(),
+% void_type(),
+% principal_type(),
+% objref_type(),
+% struct_type(),
+% union_type(),
+% string_type(),
+% array_type(),
+% any_type(),
+% typecode_type(),
+% alias_type(),
+% exception_type(),
+% 'oe_orber_test':'oe_unregister'(),
+% ok.
+
+do_register(doc) -> [];
+do_register(suite) -> [];
+do_register(Config) when is_list(Config) ->
+ io:format("Pwd: ~p, mod: ~p~n",[c:pwd(), c:m('oe_orber_test')]),
+ 'oe_orber_test':'oe_register'(),
+ ok.
+do_unregister(doc) -> [];
+do_unregister(suite) -> [];
+do_unregister(Config) when is_list(Config) ->
+ 'oe_orber_test':'oe_unregister'(),
+ ok.
+%%-----------------------------------------------------------------
+%% Encode/decode test of type: null
+%%-----------------------------------------------------------------
+null_type(doc) -> [];
+null_type(suite) -> [];
+null_type(Config) when is_list(Config) ->
+ ?line B = cdr_encode:enc_type(#giop_env{version = {1, 0}}, 'tk_null', 'null'),
+ ?line {'null', <<>>, _} = cdr_decode:dec_type('tk_null', {1, 0}, B, 0, big),
+ ok.
+
+%%-----------------------------------------------------------------
+%% Encode/decode test of type: void
+%%-----------------------------------------------------------------
+void_type(doc) -> [];
+void_type(suite) -> [];
+void_type(Config) when is_list(Config) ->
+ ?line B = cdr_encode:enc_type(#giop_env{version = {1, 0}}, 'tk_void', 'ok'),
+ ?line {'ok', <<>>, _} = cdr_decode:dec_type('tk_void', {1, 0}, B, 0, big),
+ ok.
+
+%%-----------------------------------------------------------------
+%% Encode/decode test of type: principal
+%%-----------------------------------------------------------------
+principal_type(doc) -> [];
+principal_type(suite) -> [];
+principal_type(Config) when is_list(Config) ->
+ ?line B0 = cdr_encode:enc_type(#giop_env{version = {1, 0}}, 'tk_Principal', "principal"),
+ ?line {"principal", <<>>, _} = cdr_decode:dec_type('tk_Principal', {1, 0}, B0, 0, big),
+ ?line B1 = cdr_encode:enc_type(#giop_env{version = {1, 0}}, 'tk_Principal', ""),
+ ?line {"", <<>>, _} = cdr_decode:dec_type('tk_Principal', {1, 0}, B1, 0, big),
+ ?line B2 = cdr_encode:enc_type(#giop_env{version = {1, 0}}, 'tk_Principal', "principal"),
+ ?line {"principal", <<>>, _} =
+ cdr_decode:dec_type('tk_Principal', {1, 0}, B2, 0, big),
+ ok.
+
+%%-----------------------------------------------------------------
+%% Encode/decode test of type: object reference
+%%-----------------------------------------------------------------
+version() -> #'IIOP_Version'{major=1,minor=0}.
+
+objref(0) ->
+ PB = #'IIOP_ProfileBody_1_0'{iiop_version=version(),
+ host="my.hostname.org",
+ port=4040,
+ object_key="ExternalKey: which is an arbitary octet sequence"},
+ TP = #'IOP_TaggedProfile'{tag=?TAG_INTERNET_IOP, profile_data=PB},
+ #'IOP_IOR'{type_id="IDL:Module/Interface:1.0", profiles=[TP]};
+objref(1) ->
+ K = corba_fake_mk_objkey("IDL:Module/Interface:1.0", key,
+ list_to_pid("<0.100.0>")),
+ PB = #'IIOP_ProfileBody_1_0'{iiop_version=version(),
+ host="my.hostname.org",
+ port=4040,
+ object_key=K},
+ TP = #'IOP_TaggedProfile'{tag=?TAG_INTERNET_IOP, profile_data=PB},
+ #'IOP_IOR'{type_id="IDL:Module/Interface:1.0", profiles=[TP]};
+objref(2) ->
+ K = corba_fake_mk_objkey("IDL:Module/Interface:1.0", registered,
+ list_to_atom("orber_nameservice")),
+ PB = #'IIOP_ProfileBody_1_0'{iiop_version=version(),
+ host="my.hostname.org",
+ port=4040,
+ object_key=K},
+ TP = #'IOP_TaggedProfile'{tag=?TAG_INTERNET_IOP, profile_data=PB},
+ #'IOP_IOR'{type_id="IDL:Module/Interface:1.0", profiles=[TP]}.
+
+objref_type(doc) -> [];
+objref_type(suite) -> [];
+objref_type(Config) when is_list(Config) ->
+ T = {'tk_objref', "IDL:Module/Interface:1.0", "Interface"},
+ Objref0 = objref(0),
+ ?line B0 = cdr_encode:enc_type(#giop_env{version = {1, 0}}, T, Objref0),
+ ?line {Objref0, <<>>, _} = cdr_decode:dec_type(T, {1, 0}, B0, 0, big),
+ Objref1 = objref(1),
+ ?line B1 = cdr_encode:enc_type(#giop_env{version = {1, 0}}, T, Objref1),
+ ?line {Objref1, <<>>, _} = cdr_decode:dec_type(T, {1, 0}, B1, 0, big),
+ Objref2 = objref(2),
+ ?line B2 = cdr_encode:enc_type(#giop_env{version = {1, 0}}, T, Objref2),
+ ?line {Objref2, <<>>, _} = cdr_decode:dec_type(T, {1, 0}, B2, 0, big),
+ ok.
+
+
+
+%%-----------------------------------------------------------------
+%% Encode/decode test of type: struct
+%%-----------------------------------------------------------------
+struct_type(doc) -> [];
+struct_type(suite) -> [];
+struct_type(Config) when is_list(Config) ->
+ T0 = {'tk_struct',"IDL:Module/Struct0:1.0", "Module_Struct0",
+ [{"long", 'tk_long'}, {"short", 'tk_short'}, {"character", 'tk_char'}]},
+ S0 = #'Module_Struct0'{l=-4711, s=17, c=$a},
+ ?line B0 = cdr_encode:enc_type({1, 0}, T0, S0),
+ ?line {S0, <<>>, _} = cdr_decode:dec_type(T0, {1, 0}, B0, 0, big),
+
+ T1 = {'tk_struct', "IDL:Module/Struct1:1.0", "Module_Struct1",
+ [{"string", {'tk_string', 0}}, {"ushort", 'tk_ushort'}, {"ulong", 'tk_ulong'}]},
+ S1 = #'Module_Struct1'{s="Hi !!!!", us=17, ul=4711},
+ ?line B1 = cdr_encode:enc_type({1, 0}, T1, S1),
+ ?line {S1, <<>>, _} = cdr_decode:dec_type(T1, {1, 0}, B1, 0, big),
+
+ T2 = {'tk_struct', "IDL:Module/Struct2:1.0", "Module_Struct2",
+ [{"long_sequence", {'tk_sequence', 'tk_long', 0}},
+ {"enum", {'tk_enum', "IDL:Module/Enum:1.0", "Module_Enum", ["horse", "pig", "cow"]}},
+ {"octet", 'tk_octet'}]},
+ S2 = #'Module_Struct2'{long_sequence=[4711, 350000, 0, -3030, -600000], e=cow, o=$X},
+ ?line B2 = cdr_encode:enc_type({1, 0}, T2, S2),
+ ?line {S2, <<>>, _} = cdr_decode:dec_type(T2, {1, 0}, B2, 0, big),
+ ok.
+
+%%-----------------------------------------------------------------
+%% Encode/decode test of type: union
+%%-----------------------------------------------------------------
+union_type(doc) -> [];
+union_type(suite) -> [];
+union_type(Config) when is_list(Config) ->
+ T0 = {'tk_union', "IDL:Module/Union:1.0", "Union", 'tk_short', 2,
+ [{0, "First", 'tk_short'},
+ {1, "Second", {'tk_string', 0}},
+ {2, "Third", 'tk_char'}]},
+ S0 = #'Module_Union'{label=1, value="Foo Bar !"},
+ ?line B0 = cdr_encode:enc_type({1, 0}, T0, S0),
+ ?line {S0, <<>>, _} = cdr_decode:dec_type(T0, {1, 0}, B0, 0, big),
+ S1 = #'Module_Union'{label=0, value=-17},
+ ?line B1 = cdr_encode:enc_type({1, 0}, T0, S1),
+ ?line {S1, <<>>, _} = cdr_decode:dec_type(T0, {1, 0}, B1, 0, big),
+ S2 = #'Module_Union'{label=2, value=$X},
+ ?line B2 = cdr_encode:enc_type({1, 0}, T0, S2),
+ ?line {S2, <<>>, _} = cdr_decode:dec_type(T0, {1, 0}, B2, 0, big),
+ T1 = {'tk_union', "IDL:Module/Union1:1.0", "Union1",
+ {'tk_enum', "IDL:Module/Enum:1.0",
+ "Module_Enum", ["horse", "pig", "cow"]}, "pig",
+ [{"horse", "First", 'tk_ushort'},
+ {"pig", "Second", {'tk_sequence', {'tk_string', 0}, 0}},
+ {"cow", "Third", {'tk_enum', "IDL:Module/Enum1:1.0",
+ "Module_Enum1", ["orange", "banana", "apple"]}}]},
+ S3 = #'Module_Union1'{label=pig, value=["Foo", "Bar", "!"]},
+ ?line B3 = cdr_encode:enc_type({1, 0}, T1, S3),
+ ?line {S3, <<>>, _} = cdr_decode:dec_type(T1, {1, 0}, B3, 0, big),
+ S4 = #'Module_Union1'{label=cow, value=apple},
+ ?line B4 = cdr_encode:enc_type({1, 0}, T1, S4),
+ ?line {S4, <<>>, _} = cdr_decode:dec_type(T1, {1, 0}, B4, 0, big),
+ S5 = #'Module_Union1'{label=horse, value=17},
+ ?line B5 = cdr_encode:enc_type({1, 0}, T1, S5),
+ ?line {S5, <<>>, _} = cdr_decode:dec_type(T1, {1, 0}, B5, 0, big),
+ T2 = {'tk_union', "IDL:Module/Union2:1.0", "Union2",
+ {'tk_enum', "IDL:Module/Enum:1.0",
+ "Module_Enum", ["horse", "pig", "cow"]}, "pig",
+ [{"horse", "First", {'tk_array', 'tk_long', 3}},
+ {"pig", "Second",
+ {'tk_union', "IDL:Module/Union:1.0", "Union", 'tk_short', 2,
+ [{0, "First", 'tk_short'},
+ {1, "Second", {'tk_string', 0}},
+ {2, "Third", 'tk_char'}]}},
+ {"cow", "Third", {'tk_union', "IDL:Module/Union1:1.0", "Union1",
+ {'tk_enum', "IDL:Module/Enum:1.0",
+ "Module_Enum", ["horse", "pig", "cow"]}, "pig",
+ [{"horse", "First", 'tk_ushort'},
+ {"pig", "Second", {'tk_sequence',
+ {'tk_string', 0}, 0}},
+ {"cow", "Third", {'tk_enum',
+ "IDL:Module/Enum1:1.0",
+ "Module_Enum1",
+ ["orange", "banana",
+ "apple"]}}]}}]},
+ S6 = #'Module_Union2'{label=pig, value=#'Module_Union'{label=0, value=-17}},
+ ?line B6 = cdr_encode:enc_type({1, 0}, T2, S6),
+ ?line {S6, <<>>, _} = cdr_decode:dec_type(T2, {1, 0}, B6, 0, big),
+ S7 = #'Module_Union2'{label=cow, value=#'Module_Union1'{label=pig,
+ value=["Foo", "Bar", "!"]}},
+ ?line B7 = cdr_encode:enc_type({1, 0}, T2, S7),
+ ?line {S7, <<>>, _} = cdr_decode:dec_type(T2, {1, 0}, B7, 0, big),
+ S8 = #'Module_Union2'{label=horse, value={-17, 1234567890, -987654321}},
+ ?line B8 = cdr_encode:enc_type({1, 0}, T2, S8),
+ ?line {S8, <<>>, _} = cdr_decode:dec_type(T2, {1, 0}, B8, 0, big),
+ ok.
+
+%%-----------------------------------------------------------------
+%% Encode/decode test of type: string
+%%-----------------------------------------------------------------
+string_type(doc) -> [];
+string_type(suite) -> [];
+string_type(Config) when is_list(Config) ->
+ S0 = "Foo Bar ???",
+ ?line B0 = cdr_encode:enc_type({1, 0}, {'tk_string', 0}, S0),
+ ?line {S0, <<>>, _} = cdr_decode:dec_type({'tk_string', 0}, {1, 0}, B0, 0, big),
+ S1 = "Yes, Foo Bar !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! more than 5000 characters",
+ ?line B1 = cdr_encode:enc_type({1, 0}, {'tk_string', 0}, S1),
+ ?line {S1, <<>>, _} = cdr_decode:dec_type({'tk_string', 0}, {1, 0}, B1, 0, big),
+ S2 = "",
+ ?line B2 = cdr_encode:enc_type({1, 0}, {'tk_string', 0}, S2),
+ ?line {S2, <<>>, _} = cdr_decode:dec_type({'tk_string', 0}, {1, 0}, B2, 0, big),
+ S3 = "\0",
+ ?line B3 = cdr_encode:enc_type({1, 0}, {'tk_string', 0}, S3),
+ ?line {S3, <<>>, _} = cdr_decode:dec_type({'tk_string', 0}, {1, 0}, B3, 0, big),
+ S4 = "~n",
+ ?line B4 = cdr_encode:enc_type({1, 0}, {'tk_string', 0}, S4),
+ ?line {S4, <<>>, _} = cdr_decode:dec_type({'tk_string', 0}, {1, 0}, B4, 0, big),
+ ok.
+
+%%-----------------------------------------------------------------
+%% Encode/decode test of type: array
+%%-----------------------------------------------------------------
+array_type(doc) -> [];
+array_type(suite) -> [];
+array_type(Config) when is_list(Config) ->
+ T0 = {'tk_array', 'tk_long', 5},
+ S0 = {-100, 0, 30000, -900100900, 123456789},
+ ?line B0 = cdr_encode:enc_type(#giop_env{version = {1, 0}}, T0, S0),
+ ?line {S0, <<>>, _} = cdr_decode:dec_type(T0, {1, 0}, B0, 0, big),
+ T1 = {'tk_array', {'tk_enum', "IDL:Module/Enum:1.0", "Module_Enum", ["horse", "pig", "cow"]}, 2},
+ S1 = {pig, cow},
+ ?line B1 = cdr_encode:enc_type(#giop_env{version = {1, 0}}, T1, S1),
+ ?line {S1, <<>>, _} = cdr_decode:dec_type(T1, {1, 0}, B1, 0, big),
+ T2 = {'tk_array', {'tk_union', "IDL:Module/Union:1.0", "Union",
+ {'tk_enum', "IDL:Module/Enum:1.0", "Module_Enum", ["horse", "pig", "cow"]}, "pig",
+ [{"horse", "First", 'tk_ushort'},
+ {"pig", "Second", {'tk_sequence', {'tk_string', 0}, 0}},
+ {"cow", "Third", {'tk_enum', "IDL:Module/Enum1:1.0",
+ "Module_Enum1", ["orange", "banana", "apple"]}}]}, 2},
+ S2 = {#'Module_Union'{label=cow, value=banana}, #'Module_Union'{label=pig, value=["This", "is", "a", "test", ""]}},
+ ?line B2 = cdr_encode:enc_type(#giop_env{version = {1, 0}}, T2, S2),
+ ?line {S2, <<>>, _} = cdr_decode:dec_type(T2, {1, 0}, B2, 0, big),
+ T3 = {'tk_array', {'tk_objref', "IDL:Module/Interface:1.0", "Interface"}, 3},
+ S3 = {objref(0), objref(1), objref(2)},
+ ?line B3 = cdr_encode:enc_type(#giop_env{version = {1, 0}}, T3, S3),
+ ?line {S3, <<>>, _} = cdr_decode:dec_type(T3, {1, 0}, B3, 0, big),
+ ok.
+%%-----------------------------------------------------------------
+%% Encode/decode test of type: TypeCode
+%%-----------------------------------------------------------------
+any_type(doc) -> [];
+any_type(suite) -> [];
+any_type(Config) when is_list(Config) ->
+ T = 'tk_any',
+ TC = {'tk_struct', "IDL:Module/Struct2:1.0", "Module_Struct2",
+ [{"long_sequence", {'tk_sequence', 'tk_long', 0}},
+ {"enum", {'tk_enum', "IDL:Module/Enum:1.0", "Module_Enum",
+ ["horse", "pig", "cow"]}},
+ {"octet", 'tk_octet'}]},
+ S = #'Module_Struct2'{long_sequence=[4711, 350000, 0, -3030, -600000],
+ e=cow, o=$X},
+ Any = #any{typecode=TC,value=S},
+ ?line B = cdr_encode:enc_type(#giop_env{version = {1, 0}}, T,Any),
+ ?line {Any, <<>>, _} = cdr_decode:dec_type(T, {1, 0}, B, 0, big),
+ TC1 = {'tk_array', {'tk_union', "IDL:Module/Union:1.0", "Union",
+ {'tk_enum', "IDL:Module/Enum:1.0", "Module_Enum",
+ ["horse", "pig", "cow"]}, 1,
+ [{"horse", "First", 'tk_ushort'},
+ {"pig", "Second", {'tk_sequence', {'tk_string', 0}, 0}},
+ {"cow", "Third", {'tk_enum', "IDL:Module/Enum1:1.0",
+ "Module_Enum1", ["orange", "banana",
+ "apple"]}}]},2},
+ S1 = {#'Module_Union'{label=cow, value=banana}, #'Module_Union'{label=pig, value=["This", "is", "a", "test", ""]}},
+ Any1 = #any{typecode=TC1,value=S1},
+ ?line B1 = cdr_encode:enc_type(#giop_env{version = {1, 0}}, T,Any1),
+ ?line {Any1, <<>>, _} = cdr_decode:dec_type(T, {1, 0}, B1, 0, big),
+ ok.
+
+
+%%-----------------------------------------------------------------
+%% Encode/decode test of type: TypeCode
+%%-----------------------------------------------------------------
+typecode_type(doc) -> [];
+typecode_type(suite) -> [];
+typecode_type(Config) when is_list(Config) ->
+ T = 'tk_TypeCode',
+ TC = {'tk_array', {'tk_union', "IDL:Module/Union:1.0", "Union",
+ {'tk_enum', "IDL:Module/Enum:1.0", "Module_Enum",
+ ["horse", "pig", "cow"]}, 1,
+ [{"horse", "First", 'tk_ushort'},
+ {"pig", "Second", {'tk_sequence', {'tk_string', 0}, 0}},
+ {"cow", "Third", {'tk_enum', "IDL:Module/Enum1:1.0",
+ "Module_Enum1", ["orange", "banana",
+ "apple"]}}]}, 10},
+ ?line B = cdr_encode:enc_type(#giop_env{version = {1, 0}}, T,TC),
+ ?line {TC, <<>>, _} = cdr_decode:dec_type(T, {1, 0}, B, 0, big),
+ TC1 = {'tk_union', "IDL:Module/Union2:1.0", "Union2",
+ {'tk_enum', "IDL:Module/Enum:1.0",
+ "Module_Enum", ["horse", "pig", "cow"]}, 2,
+ [{"horse", "First", 'tk_long'},
+ {"pig", "Second",
+ {'tk_union', "IDL:Module/Union:1.0", "Union", 'tk_short', 2,
+ [{0, "First", 'tk_short'},
+ {1, "Second", {'tk_string', 0}},
+ {2, "Third", 'tk_char'}]}},
+ {"cow", "Third", {'tk_union', "IDL:Module/Union1:1.0", "Union1",
+ {'tk_enum', "IDL:Module/Enum:1.0",
+ "Module_Enum", ["horse", "pig", "cow"]}, 2,
+ [{"horse", "First", 'tk_ushort'},
+ {"pig", "Second", {'tk_sequence',
+ {'tk_string', 0}, 0}},
+ {"cow", "Third", {'tk_enum',
+ "IDL:Module/Enum1:1.0",
+ "Module_Enum1",
+ ["orange", "banana",
+ "apple"]}}]}}]},
+ ?line B1 = cdr_encode:enc_type(#giop_env{version = {1, 0}}, T, TC1),
+ ?line {TC1, <<>>, _} = cdr_decode:dec_type(T, {1, 0}, B1, 0, big),
+ ok.
+
+%%-----------------------------------------------------------------
+%% Encode/decode test of type: TypeCode
+%%-----------------------------------------------------------------
+alias_type(doc) -> [];
+alias_type(suite) -> [];
+alias_type(Config) when is_list(Config) ->
+ T = {'tk_alias', "IDL:Module/Alias:1.0", "Alias",
+ {'tk_struct', "IDL:Module/Struct2:1.0", "Module_Struct2",
+ [{"long_sequence", {'tk_sequence', 'tk_long', 0}},
+ {"enum", {'tk_enum', "IDL:Module/Enum:1.0", "Module_Enum",
+ ["horse", "pig", "cow"]}},
+ {"octet", 'tk_octet'}]}},
+ S = #'Module_Struct2'{long_sequence=[4711, 350000, 0, -3030, -600000],
+ e=cow, o=$X},
+ ?line B = cdr_encode:enc_type(#giop_env{version = {1, 0}}, T,S),
+ ?line {S, <<>>, _} = cdr_decode:dec_type(T, {1, 0}, B, 0, big),
+ T1 = {'tk_alias', "IDL:Module/Alias1:1.0", "Alias1",
+ {'tk_sequence', {'tk_union', "IDL:Module/Union:1.0", "Union",
+ {'tk_enum', "IDL:Module/Enum:1.0", "Module_Enum",
+ ["horse", "pig", "cow"]}, 2,
+ [{"horse", "First", 'tk_ushort'},
+ {"pig", "Second", {'tk_sequence', {'tk_string', 0}, 0}},
+ {"cow", "Third", {'tk_enum', "IDL:Module/Enum1:1.0",
+ "Module_Enum1", ["orange", "banana",
+ "apple"]}}]},0}},
+ S1 = [#'Module_Union'{label=cow, value=banana}, #'Module_Union'{label=pig, value=["This", "is", "a", "test", ""]}],
+ ?line B1 = cdr_encode:enc_type(#giop_env{version = {1, 0}}, T1, S1),
+ ?line {S1, <<>>, _} = cdr_decode:dec_type(T1, {1, 0}, B1, 0, big),
+ ok.
+
+%%-----------------------------------------------------------------
+%% Encode/decode test of type: exception
+%%-----------------------------------------------------------------
+exception_type(doc) -> [];
+exception_type(suite) -> [];
+exception_type(Config) when is_list(Config) ->
+ system_exceptions(),
+ user_exceptions(),
+ ok.
+
+system_exceptions() ->
+ E = #'UNKNOWN'{completion_status=?COMPLETED_YES},
+ {system_exception, T, E} = orber_exceptions:get_def(E),
+ ?line B = cdr_encode:enc_type(#giop_env{version = {1, 0}}, T,E),
+ ?line {E, _} = cdr_decode:dec_system_exception({1, 0}, B, 0, big),
+ E1 = #'INV_OBJREF'{completion_status=?COMPLETED_NO},
+ {system_exception, T1, E1} = orber_exceptions:get_def(E1),
+ ?line B1 = cdr_encode:enc_type(#giop_env{version = {1, 0}}, T1,E1),
+ ?line {E1, _} = cdr_decode:dec_system_exception({1, 0}, B1, 0, big),
+ E2 = #'BAD_OPERATION'{completion_status=?COMPLETED_NO},
+ {system_exception, T2, E2} = orber_exceptions:get_def(E2),
+ ?line B2 = cdr_encode:enc_type(#giop_env{version = {1, 0}}, T2,E2),
+ ?line {E2, _} = cdr_decode:dec_system_exception({1, 0}, B2, 0, big),
+ E3 = #'INTF_REPOS'{completion_status=?COMPLETED_MAYBE},
+ {system_exception, T3, E3} = orber_exceptions:get_def(E3),
+ ?line B3 = cdr_encode:enc_type(#giop_env{version = {1, 0}}, T3,E3),
+ ?line {E3, _} = cdr_decode:dec_system_exception({1, 0}, B3, 0, big),
+ ok.
+
+user_exceptions() ->
+ E = #'Module_Except1'{rest_of_name=["I","am","testing","exceptions"], why="Error"},
+ {user_exception, T, E} = orber_exceptions:get_def(E),
+ ?line B = cdr_encode:enc_type(#giop_env{version = {1, 0}}, T, E),
+ ?line {E, _} = cdr_decode:dec_user_exception({1, 0}, B, 0, big),
+ E1 = #'Module_Except2'{e=banana,
+ s=#'Module_Struct2'{long_sequence=[12,-4040,
+ 1234567898],
+ e=horse,
+ o=$a}},
+ {user_exception, T1, E1} = orber_exceptions:get_def(E1),
+ ?line B1 = cdr_encode:enc_type(#giop_env{version = {1, 0}}, T1, E1),
+ ?line {E1, _} = cdr_decode:dec_user_exception({1, 0}, B1, 0, big),
+ E2 = #'Module_Except3'{u=#'Module_Union1'{label=pig,value=["high","and","low"]},s=1313, o=objref(0)},
+ {user_exception, T2, E2} = orber_exceptions:get_def(E2),
+ ?line B2 = cdr_encode:enc_type(#giop_env{version = {1, 0}}, T2, E2),
+ ?line {E2, _} = cdr_decode:dec_user_exception({1, 0}, B2, 0, big),
+ E3 = #'Module_Except4'{},
+ {user_exception, T3, E3} = orber_exceptions:get_def(E3),
+ ?line B3 = cdr_encode:enc_type(#giop_env{version = {1, 0}}, T3, E3),
+ ?line {E3, _} = cdr_decode:dec_user_exception({1, 0}, B3, 0, big),
+ ok.
+
+%%-----------------------------------------------------------------
+%% Test Case: request encoding test
+%% Description: Precondition the stack must be started so the
+%% objectkey is valid.
+%%-----------------------------------------------------------------
+%request(suite) -> [];
+%request(_) ->
+% exit(not_implemented).
+
+%%-----------------------------------------------------------------
+%% Test Case: reply encoding test
+%% Description:
+%%-----------------------------------------------------------------
+reply(doc) -> ["Description", "more description"];
+reply(suite) -> [];
+reply(Config) when is_list(Config) ->
+ R = #reply_header{service_context=[], request_id=1,
+ reply_status='no_exception'},
+ ?line B = cdr_encode:enc_reply(
+ #giop_env{version = {1, 0}, request_id = 1,
+ reply_status = 'no_exception',
+ tc = {'tk_long', [], [{'tk_sequence',
+ {'tk_string', 0}, 0}]},
+ result = 1200, parameters = [["foo","Bar"]],
+ ctx = []}),
+ ?line {R, 1200, [["foo","Bar"]]} =
+ cdr_decode:dec_message({'tk_long', [], [{'tk_sequence', {'tk_string', 0},0}]},
+ B),
+ ok.
+
+%%-----------------------------------------------------------------
+%% Test Case: cancel_request encoding test
+%% Description:
+%%-----------------------------------------------------------------
+cancel_request(doc) -> ["Description", "more description"];
+cancel_request(suite) -> [];
+cancel_request(Config) when is_list(Config) ->
+ R = #cancel_request_header{request_id=1},
+ ?line B = cdr_encode:enc_cancel_request(#giop_env{version = {1, 0},
+ request_id = 1}),
+ ?line R = cdr_decode:dec_message([], B),
+ ok.
+
+%%-----------------------------------------------------------------
+%% Test Case: locate_request encoding test
+%% Description:
+%%-----------------------------------------------------------------
+locate_request(doc) -> ["Description", "more description"];
+locate_request(suite) -> [];
+locate_request(Config) when is_list(Config) ->
+ io:format("Function not imlpemented yet"),
+ exit(not_implemented).
+
+%%-----------------------------------------------------------------
+%% Test Case: locate_reply encoding test
+%% Description:
+%%-----------------------------------------------------------------
+locate_reply(doc) -> ["Description", "more description"];
+locate_reply(suite) -> [];
+locate_reply(Config) when is_list(Config) ->
+ io:format("Function not imlpemented yet"),
+ exit(not_implemented).
+
+%%-----------------------------------------------------------------
+%% Test Case: close_connection encoding test
+%% Description:
+%%-----------------------------------------------------------------
+close_connection(doc) -> ["Description", "more description"];
+close_connection(suite) -> [];
+close_connection(Config) when is_list(Config) ->
+ ?line B = cdr_encode:enc_close_connection(#giop_env{version = {1, 0}}),
+ ?line 'close_connection' = cdr_decode:dec_message([], B),
+ ok.
+
+%%-----------------------------------------------------------------
+%% Test Case: message_error encoding test
+%% Description:
+%%-----------------------------------------------------------------
+message_error(doc) -> ["Description", "more description"];
+message_error(suite) -> [];
+message_error(Config) when is_list(Config) ->
+ ?line B = cdr_encode:enc_message_error(#giop_env{version = {1, 0}}),
+ ?line 'message_error' = cdr_decode:dec_message([], B),
+ ok.
+
+
+
+%%-----------------------------------------------------------------
+%% Internal functions
+%%-----------------------------------------------------------------
+corba_fake_mk_objkey(Id, 'key', Pid) when is_pid(Pid) ->
+ Key = make_objkey(),
+ {list_to_binary(Id), 'key', Key, term_to_binary(undefined),
+ term_to_binary(undefined), term_to_binary(undefined)};
+corba_fake_mk_objkey(Id, 'key', RegName) when is_atom(RegName) ->
+ Key = term_to_binary(RegName),
+ {list_to_binary(Id), 'key', Key, term_to_binary(undefined),
+ term_to_binary(undefined), term_to_binary(undefined)};
+corba_fake_mk_objkey(Id, 'registered', RegName) when is_atom(RegName) ->
+ {list_to_binary(Id), 'registered', RegName, term_to_binary(undefined),
+ term_to_binary(undefined), term_to_binary(undefined)}.
+
+make_objkey() ->
+ term_to_binary({now(), node()}).
diff --git a/lib/orber/test/cdrcoding_11_SUITE.erl b/lib/orber/test/cdrcoding_11_SUITE.erl
new file mode 100644
index 0000000000..d62fe6eb3a
--- /dev/null
+++ b/lib/orber/test/cdrcoding_11_SUITE.erl
@@ -0,0 +1,615 @@
+%%
+%% %CopyrightBegin%
+%%
+%% 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%
+%%
+%%
+%%-----------------------------------------------------------------
+%%
+%% Description:
+%% Test suite for the CDR encode/decode functions
+%%
+%%-----------------------------------------------------------------
+-module(cdrcoding_11_SUITE).
+
+
+-include("idl_output/Module.hrl").
+-include("test_server.hrl").
+-include_lib("orber/include/corba.hrl").
+-include_lib("orber/src/orber_iiop.hrl").
+
+-define(default_timeout, ?t:minutes(5)).
+
+%%-----------------------------------------------------------------
+%% External exports
+%%-----------------------------------------------------------------
+-export([all/1]).
+
+%%-----------------------------------------------------------------
+%% Internal exports
+%%-----------------------------------------------------------------
+-export([]).
+-compile(export_all).
+
+%%-----------------------------------------------------------------
+%% Func: all/1
+%% Args:
+%% Returns:
+%%-----------------------------------------------------------------
+all(doc) -> ["Description", "more description"];
+all(suite) -> {req,
+ [mnesia],
+ {conf, init_all, cases(), finish_all}}.
+
+cases() ->
+ [types, reply, cancel_request, close_connection, message_error].
+%% request, locate_request, locate_reply].
+
+%%-----------------------------------------------------------------
+%% Init and cleanup functions.
+%%-----------------------------------------------------------------
+
+init_per_testcase(_Case, Config) ->
+ Path = code:which(?MODULE),
+ code:add_pathz(filename:join(filename:dirname(Path), "idl_output")),
+ ?line Dog=test_server:timetrap(?default_timeout),
+ [{watchdog, Dog}|Config].
+
+
+fin_per_testcase(_Case, Config) ->
+ Path = code:which(?MODULE),
+ code:del_path(filename:join(filename:dirname(Path), "idl_output")),
+ Dog = ?config(watchdog, Config),
+ test_server:timetrap_cancel(Dog),
+ ok.
+
+init_all(Config) when is_list(Config) ->
+ orber:jump_start(0),
+ if
+ is_list(Config) ->
+ Config;
+ true ->
+ exit("Config not a list")
+ end.
+
+finish_all(Config) when is_list(Config) ->
+ orber:jump_stop(),
+ Config.
+
+%%-----------------------------------------------------------------
+%% Test Case: type encoding tests
+%% Description: Just testing the complex types, the others are
+%% tested in the cdrlib SUITE.
+%%-----------------------------------------------------------------
+types(doc) -> ["Description", "more description"];
+types(suite) -> [do_register, null_type, void_type, principal_type,
+ objref_type, struct_type, union_type, string_type,
+ array_type, any_type, typecode_type, alias_type,
+ exception_type, do_unregister].
+%types(Config) when list(Config) ->
+% 'oe_orber_test':'oe_register'(),
+% null_type(),
+% void_type(),
+% principal_type(),
+% objref_type(),
+% struct_type(),
+% union_type(),
+% string_type(),
+% array_type(),
+% any_type(),
+% typecode_type(),
+% alias_type(),
+% exception_type(),
+% 'oe_orber_test':'oe_unregister'(),
+% ok.
+
+do_register(doc) -> [];
+do_register(suite) -> [];
+do_register(Config) when is_list(Config) ->
+ 'oe_orber_test':'oe_register'(),
+ ok.
+do_unregister(doc) -> [];
+do_unregister(suite) -> [];
+do_unregister(Config) when is_list(Config) ->
+ 'oe_orber_test':'oe_unregister'(),
+ ok.
+%%-----------------------------------------------------------------
+%% Encode/decode test of type: null
+%%-----------------------------------------------------------------
+null_type(doc) -> [];
+null_type(suite) -> [];
+null_type(Config) when is_list(Config) ->
+ ?line B = cdr_encode:enc_type(#giop_env{version = {1, 1}}, 'tk_null', 'null'),
+ ?line {'null', <<>>, _} = cdr_decode:dec_type('tk_null', {1, 1}, B, 0, big),
+ ok.
+
+%%-----------------------------------------------------------------
+%% Encode/decode test of type: void
+%%-----------------------------------------------------------------
+void_type(doc) -> [];
+void_type(suite) -> [];
+void_type(Config) when is_list(Config) ->
+ ?line B = cdr_encode:enc_type(#giop_env{version = {1, 1}}, 'tk_void', 'ok'),
+ ?line {'ok', <<>>, _} = cdr_decode:dec_type('tk_void', {1, 1}, B, 0, big),
+ ok.
+
+%%-----------------------------------------------------------------
+%% Encode/decode test of type: principal
+%%-----------------------------------------------------------------
+principal_type(doc) -> [];
+principal_type(suite) -> [];
+principal_type(Config) when is_list(Config) ->
+ ?line B0 = cdr_encode:enc_type(#giop_env{version = {1, 1}}, 'tk_Principal', "principal"),
+ ?line {"principal", <<>>, _} = cdr_decode:dec_type('tk_Principal', {1, 1}, B0, 0, big),
+ ?line B1 = cdr_encode:enc_type(#giop_env{version = {1, 1}}, 'tk_Principal', ""),
+ ?line {"", <<>>, _} = cdr_decode:dec_type('tk_Principal', {1, 1}, B1, 0, big),
+ ?line B2 = cdr_encode:enc_type(#giop_env{version = {1, 1}}, 'tk_Principal', "principal"),
+ ?line {"principal", <<>>, _} =
+ cdr_decode:dec_type('tk_Principal', {1, 1}, B2, 0, big),
+ ok.
+
+%%-----------------------------------------------------------------
+%% Encode/decode test of type: object reference
+%%-----------------------------------------------------------------
+version() -> #'IIOP_Version'{major=1,minor=1}.
+
+objref(0) ->
+ PB = #'IIOP_ProfileBody_1_1'{iiop_version=version(),
+ host="my.hostname.org",
+ port=4040,
+ object_key="ExternalKey: which is an arbitary octet sequence",
+ components=[]},
+ TP = #'IOP_TaggedProfile'{tag=?TAG_INTERNET_IOP, profile_data=PB},
+ #'IOP_IOR'{type_id="IDL:Module/Interface:1.0", profiles=[TP]};
+objref(1) ->
+ K = corba_fake_mk_objkey("IDL:Module/Interface:1.0", key,
+ list_to_pid("<0.100.0>")),
+ PB = #'IIOP_ProfileBody_1_1'{iiop_version=version(),
+ host="my.hostname.org",
+ port=4040,
+ object_key=K, components=[]},
+ TP = #'IOP_TaggedProfile'{tag=?TAG_INTERNET_IOP, profile_data=PB},
+ #'IOP_IOR'{type_id="IDL:Module/Interface:1.0", profiles=[TP]};
+objref(2) ->
+ K = corba_fake_mk_objkey("IDL:Module/Interface:1.0", registered,
+ list_to_atom("orber_nameservice")),
+ PB = #'IIOP_ProfileBody_1_1'{iiop_version=version(),
+ host="my.hostname.org",
+ port=4040,
+ object_key=K, components=[]},
+ TP = #'IOP_TaggedProfile'{tag=?TAG_INTERNET_IOP, profile_data=PB},
+ #'IOP_IOR'{type_id="IDL:Module/Interface:1.0", profiles=[TP]}.
+
+objref_type(doc) -> [];
+objref_type(suite) -> [];
+objref_type(Config) when is_list(Config) ->
+ T = {'tk_objref', "IDL:Module/Interface:1.0", "Interface"},
+ Objref0 = objref(0),
+ ?line B0 = cdr_encode:enc_type(#giop_env{version = {1, 1}}, T, Objref0),
+ ?line {Objref0, <<>>, _} = cdr_decode:dec_type(T, {1, 1}, B0, 0, big),
+ Objref1 = objref(1),
+ ?line B1 = cdr_encode:enc_type(#giop_env{version = {1, 1}}, T, Objref1),
+ ?line {Objref1, <<>>, _} = cdr_decode:dec_type(T, {1, 1}, B1, 0, big),
+ Objref2 = objref(2),
+ ?line B2 = cdr_encode:enc_type(#giop_env{version = {1, 1}}, T, Objref2),
+ ?line {Objref2, <<>>, _} = cdr_decode:dec_type(T, {1, 1}, B2, 0, big),
+ ok.
+
+
+
+%%-----------------------------------------------------------------
+%% Encode/decode test of type: struct
+%%-----------------------------------------------------------------
+struct_type(doc) -> [];
+struct_type(suite) -> [];
+struct_type(Config) when is_list(Config) ->
+ T0 = {'tk_struct',"IDL:Module/Struct0:1.0", "Module_Struct0",
+ [{"long", 'tk_long'}, {"short", 'tk_short'}, {"character", 'tk_char'}]},
+ S0 = #'Module_Struct0'{l=-4711, s=17, c=$a},
+ ?line B0 = cdr_encode:enc_type(#giop_env{version = {1, 1}}, T0, S0),
+ ?line {S0, <<>>, _} = cdr_decode:dec_type(T0, {1, 1}, B0, 0, big),
+
+ T1 = {'tk_struct', "IDL:Module/Struct1:1.0", "Module_Struct1",
+ [{"string", {'tk_string', 0}}, {"ushort", 'tk_ushort'}, {"ulong", 'tk_ulong'}]},
+ S1 = #'Module_Struct1'{s="Hi !!!!", us=17, ul=4711},
+ ?line B1 = cdr_encode:enc_type(#giop_env{version = {1, 1}}, T1, S1),
+ ?line {S1, <<>>, _} = cdr_decode:dec_type(T1, {1, 1}, B1, 0, big),
+
+ T2 = {'tk_struct', "IDL:Module/Struct2:1.0", "Module_Struct2",
+ [{"long_sequence", {'tk_sequence', 'tk_long', 0}},
+ {"enum", {'tk_enum', "IDL:Module/Enum:1.0", "Module_Enum", ["horse", "pig", "cow"]}},
+ {"octet", 'tk_octet'}]},
+ S2 = #'Module_Struct2'{long_sequence=[4711, 350000, 0, -3030, -600000], e=cow, o=$X},
+ ?line B2 = cdr_encode:enc_type(#giop_env{version = {1, 1}}, T2, S2),
+ ?line {S2, <<>>, _} = cdr_decode:dec_type(T2, {1, 1}, B2, 0, big),
+ ok.
+
+%%-----------------------------------------------------------------
+%% Encode/decode test of type: union
+%%-----------------------------------------------------------------
+union_type(doc) -> [];
+union_type(suite) -> [];
+union_type(Config) when is_list(Config) ->
+ T0 = {'tk_union', "IDL:Module/Union:1.0", "Union", 'tk_short', 2,
+ [{0, "First", 'tk_short'},
+ {1, "Second", {'tk_string', 0}},
+ {2, "Third", 'tk_char'}]},
+ S0 = #'Module_Union'{label=1, value="Foo Bar !"},
+ ?line B0 = cdr_encode:enc_type(#giop_env{version = {1, 1}}, T0, S0),
+ ?line {S0, <<>>, _} = cdr_decode:dec_type(T0, {1, 1}, B0, 0, big),
+ S1 = #'Module_Union'{label=0, value=-17},
+ ?line B1 = cdr_encode:enc_type(#giop_env{version = {1, 1}}, T0, S1),
+ ?line {S1, <<>>, _} = cdr_decode:dec_type(T0, {1, 1}, B1, 0, big),
+ S2 = #'Module_Union'{label=2, value=$X},
+ ?line B2 = cdr_encode:enc_type(#giop_env{version = {1, 1}}, T0, S2),
+ ?line {S2, <<>>, _} = cdr_decode:dec_type(T0, {1, 1}, B2, 0, big),
+ T1 = {'tk_union', "IDL:Module/Union1:1.0", "Union1",
+ {'tk_enum', "IDL:Module/Enum:1.0",
+ "Module_Enum", ["horse", "pig", "cow"]}, "pig",
+ [{"horse", "First", 'tk_ushort'},
+ {"pig", "Second", {'tk_sequence', {'tk_string', 0}, 0}},
+ {"cow", "Third", {'tk_enum', "IDL:Module/Enum1:1.0",
+ "Module_Enum1", ["orange", "banana", "apple"]}}]},
+ S3 = #'Module_Union1'{label=pig, value=["Foo", "Bar", "!"]},
+ ?line B3 = cdr_encode:enc_type(#giop_env{version = {1, 1}}, T1, S3),
+ ?line {S3, <<>>, _} = cdr_decode:dec_type(T1, {1, 1}, B3, 0, big),
+ S4 = #'Module_Union1'{label=cow, value=apple},
+ ?line B4 = cdr_encode:enc_type(#giop_env{version = {1, 1}}, T1, S4),
+ ?line {S4, <<>>, _} = cdr_decode:dec_type(T1, {1, 1}, B4, 0, big),
+ S5 = #'Module_Union1'{label=horse, value=17},
+ ?line B5 = cdr_encode:enc_type(#giop_env{version = {1, 1}}, T1, S5),
+ ?line {S5, <<>>, _} = cdr_decode:dec_type(T1, {1, 1}, B5, 0, big),
+ T2 = {'tk_union', "IDL:Module/Union2:1.0", "Union2",
+ {'tk_enum', "IDL:Module/Enum:1.0",
+ "Module_Enum", ["horse", "pig", "cow"]}, "pig",
+ [{"horse", "First", {'tk_array', 'tk_long', 3}},
+ {"pig", "Second",
+ {'tk_union', "IDL:Module/Union:1.0", "Union", 'tk_short', 2,
+ [{0, "First", 'tk_short'},
+ {1, "Second", {'tk_string', 0}},
+ {2, "Third", 'tk_char'}]}},
+ {"cow", "Third", {'tk_union', "IDL:Module/Union1:1.0", "Union1",
+ {'tk_enum', "IDL:Module/Enum:1.0",
+ "Module_Enum", ["horse", "pig", "cow"]}, "pig",
+ [{"horse", "First", 'tk_ushort'},
+ {"pig", "Second", {'tk_sequence',
+ {'tk_string', 0}, 0}},
+ {"cow", "Third", {'tk_enum',
+ "IDL:Module/Enum1:1.0",
+ "Module_Enum1",
+ ["orange", "banana",
+ "apple"]}}]}}]},
+ S6 = #'Module_Union2'{label=pig, value=#'Module_Union'{label=0, value=-17}},
+ ?line B6 = cdr_encode:enc_type(#giop_env{version = {1, 1}}, T2, S6),
+ ?line {S6, <<>>, _} = cdr_decode:dec_type(T2, {1, 1}, B6, 0, big),
+ S7 = #'Module_Union2'{label=cow, value=#'Module_Union1'{label=pig,
+ value=["Foo", "Bar", "!"]}},
+ ?line B7 = cdr_encode:enc_type(#giop_env{version = {1, 1}}, T2, S7),
+ ?line {S7, <<>>, _} = cdr_decode:dec_type(T2, {1, 1}, B7, 0, big),
+ S8 = #'Module_Union2'{label=horse, value={-17, 1234567890, -987654321}},
+ ?line B8 = cdr_encode:enc_type(#giop_env{version = {1, 1}}, T2, S8),
+ ?line {S8, <<>>, _} = cdr_decode:dec_type(T2, {1, 1}, B8, 0, big),
+ ok.
+
+%%-----------------------------------------------------------------
+%% Encode/decode test of type: string
+%%-----------------------------------------------------------------
+string_type(doc) -> [];
+string_type(suite) -> [];
+string_type(Config) when is_list(Config) ->
+ S0 = "Foo Bar ???",
+ ?line B0 = cdr_encode:enc_type(#giop_env{version = {1, 1}}, {'tk_string', 0}, S0),
+ ?line {S0, <<>>, _} = cdr_decode:dec_type({'tk_string', 0}, {1, 1}, B0, 0, big),
+ S1 = "Yes, Foo Bar !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! more than 5000 characters",
+ ?line B1 = cdr_encode:enc_type(#giop_env{version = {1, 1}}, {'tk_string', 0}, S1),
+ ?line {S1, <<>>, _} = cdr_decode:dec_type({'tk_string', 0}, {1, 1}, B1, 0, big),
+ S2 = "",
+ ?line B2 = cdr_encode:enc_type(#giop_env{version = {1, 1}}, {'tk_string', 0}, S2),
+ ?line {S2, <<>>, _} = cdr_decode:dec_type({'tk_string', 0}, {1, 1}, B2, 0, big),
+ S3 = "\0",
+ ?line B3 = cdr_encode:enc_type(#giop_env{version = {1, 1}}, {'tk_string', 0}, S3),
+ ?line {S3, <<>>, _} = cdr_decode:dec_type({'tk_string', 0}, {1, 1}, B3, 0, big),
+ S4 = "~n",
+ ?line B4 = cdr_encode:enc_type(#giop_env{version = {1, 1}}, {'tk_string', 0}, S4),
+ ?line {S4, <<>>, _} = cdr_decode:dec_type({'tk_string', 0}, {1, 1}, B4, 0, big),
+ ok.
+
+%%-----------------------------------------------------------------
+%% Encode/decode test of type: array
+%%-----------------------------------------------------------------
+array_type(doc) -> [];
+array_type(suite) -> [];
+array_type(Config) when is_list(Config) ->
+ T0 = {'tk_array', 'tk_long', 5},
+ S0 = {-100, 0, 30000, -900100900, 123456789},
+ ?line B0 = cdr_encode:enc_type(#giop_env{version = {1, 1}}, T0, S0),
+ ?line {S0, <<>>, _} = cdr_decode:dec_type(T0, {1, 1}, B0, 0, big),
+ T1 = {'tk_array', {'tk_enum', "IDL:Module/Enum:1.0", "Module_Enum", ["horse", "pig", "cow"]}, 2},
+ S1 = {pig, cow},
+ ?line B1 = cdr_encode:enc_type(#giop_env{version = {1, 1}}, T1, S1),
+ ?line {S1, <<>>, _} = cdr_decode:dec_type(T1, {1, 1}, B1, 0, big),
+ T2 = {'tk_array', {'tk_union', "IDL:Module/Union:1.0", "Union",
+ {'tk_enum', "IDL:Module/Enum:1.0", "Module_Enum", ["horse", "pig", "cow"]}, "pig",
+ [{"horse", "First", 'tk_ushort'},
+ {"pig", "Second", {'tk_sequence', {'tk_string', 0}, 0}},
+ {"cow", "Third", {'tk_enum', "IDL:Module/Enum1:1.0",
+ "Module_Enum1", ["orange", "banana", "apple"]}}]}, 2},
+ S2 = {#'Module_Union'{label=cow, value=banana}, #'Module_Union'{label=pig, value=["This", "is", "a", "test", ""]}},
+ ?line B2 = cdr_encode:enc_type(#giop_env{version = {1, 1}}, T2, S2),
+ ?line {S2, <<>>, _} = cdr_decode:dec_type(T2, {1, 1}, B2, 0, big),
+ T3 = {'tk_array', {'tk_objref', "IDL:Module/Interface:1.0", "Interface"}, 3},
+ S3 = {objref(0), objref(1), objref(2)},
+ ?line B3 = cdr_encode:enc_type(#giop_env{version = {1, 1}}, T3, S3),
+ ?line {S3, <<>>, _} = cdr_decode:dec_type(T3, {1, 1}, B3, 0, big),
+ ok.
+%%-----------------------------------------------------------------
+%% Encode/decode test of type: TypeCode
+%%-----------------------------------------------------------------
+any_type(doc) -> [];
+any_type(suite) -> [];
+any_type(Config) when is_list(Config) ->
+ T = 'tk_any',
+ TC = {'tk_struct', "IDL:Module/Struct2:1.0", "Module_Struct2",
+ [{"long_sequence", {'tk_sequence', 'tk_long', 0}},
+ {"enum", {'tk_enum', "IDL:Module/Enum:1.0", "Module_Enum",
+ ["horse", "pig", "cow"]}},
+ {"octet", 'tk_octet'}]},
+ S = #'Module_Struct2'{long_sequence=[4711, 350000, 0, -3030, -600000],
+ e=cow, o=$X},
+ Any = #any{typecode=TC,value=S},
+ ?line B = cdr_encode:enc_type(#giop_env{version = {1, 1}}, T,Any),
+ ?line {Any, <<>>, _} = cdr_decode:dec_type(T, {1, 1}, B, 0, big),
+ TC1 = {'tk_array', {'tk_union', "IDL:Module/Union:1.0", "Union",
+ {'tk_enum', "IDL:Module/Enum:1.0", "Module_Enum",
+ ["horse", "pig", "cow"]}, 1,
+ [{"horse", "First", 'tk_ushort'},
+ {"pig", "Second", {'tk_sequence', {'tk_string', 0}, 0}},
+ {"cow", "Third", {'tk_enum', "IDL:Module/Enum1:1.0",
+ "Module_Enum1", ["orange", "banana",
+ "apple"]}}]},2},
+ S1 = {#'Module_Union'{label=cow, value=banana}, #'Module_Union'{label=pig, value=["This", "is", "a", "test", ""]}},
+ Any1 = #any{typecode=TC1,value=S1},
+ ?line B1 = cdr_encode:enc_type(#giop_env{version = {1, 1}}, T,Any1),
+ ?line {Any1, <<>>, _} = cdr_decode:dec_type(T, {1, 1}, B1, 0, big),
+ ok.
+
+
+%%-----------------------------------------------------------------
+%% Encode/decode test of type: TypeCode
+%%-----------------------------------------------------------------
+typecode_type(doc) -> [];
+typecode_type(suite) -> [];
+typecode_type(Config) when is_list(Config) ->
+ T = 'tk_TypeCode',
+ TC = {'tk_array', {'tk_union', "IDL:Module/Union:1.0", "Union",
+ {'tk_enum', "IDL:Module/Enum:1.0", "Module_Enum",
+ ["horse", "pig", "cow"]}, 1,
+ [{"horse", "First", 'tk_ushort'},
+ {"pig", "Second", {'tk_sequence', {'tk_string', 0}, 0}},
+ {"cow", "Third", {'tk_enum', "IDL:Module/Enum1:1.0",
+ "Module_Enum1", ["orange", "banana",
+ "apple"]}}]}, 10},
+ ?line B = cdr_encode:enc_type(#giop_env{version = {1, 1}}, T,TC),
+ ?line {TC, <<>>, _} = cdr_decode:dec_type(T, {1, 1}, B, 0, big),
+ TC1 = {'tk_union', "IDL:Module/Union2:1.0", "Union2",
+ {'tk_enum', "IDL:Module/Enum:1.0",
+ "Module_Enum", ["horse", "pig", "cow"]}, 2,
+ [{"horse", "First", 'tk_long'},
+ {"pig", "Second",
+ {'tk_union', "IDL:Module/Union:1.0", "Union", 'tk_short', 2,
+ [{0, "First", 'tk_short'},
+ {1, "Second", {'tk_string', 0}},
+ {2, "Third", 'tk_char'}]}},
+ {"cow", "Third", {'tk_union', "IDL:Module/Union1:1.0", "Union1",
+ {'tk_enum', "IDL:Module/Enum:1.0",
+ "Module_Enum", ["horse", "pig", "cow"]}, 2,
+ [{"horse", "First", 'tk_ushort'},
+ {"pig", "Second", {'tk_sequence',
+ {'tk_string', 0}, 0}},
+ {"cow", "Third", {'tk_enum',
+ "IDL:Module/Enum1:1.0",
+ "Module_Enum1",
+ ["orange", "banana",
+ "apple"]}}]}}]},
+ ?line B1 = cdr_encode:enc_type(#giop_env{version = {1, 1}}, T, TC1),
+ ?line {TC1, <<>>, _} = cdr_decode:dec_type(T, {1, 1}, B1, 0, big),
+ ok.
+
+%%-----------------------------------------------------------------
+%% Encode/decode test of type: TypeCode
+%%-----------------------------------------------------------------
+alias_type(doc) -> [];
+alias_type(suite) -> [];
+alias_type(Config) when is_list(Config) ->
+ T = {'tk_alias', "IDL:Module/Alias:1.0", "Alias",
+ {'tk_struct', "IDL:Module/Struct2:1.0", "Module_Struct2",
+ [{"long_sequence", {'tk_sequence', 'tk_long', 0}},
+ {"enum", {'tk_enum', "IDL:Module/Enum:1.0", "Module_Enum",
+ ["horse", "pig", "cow"]}},
+ {"octet", 'tk_octet'}]}},
+ S = #'Module_Struct2'{long_sequence=[4711, 350000, 0, -3030, -600000],
+ e=cow, o=$X},
+ ?line B = cdr_encode:enc_type(#giop_env{version = {1, 1}}, T,S),
+ ?line {S, <<>>, _} = cdr_decode:dec_type(T, {1, 1}, B, 0, big),
+ T1 = {'tk_alias', "IDL:Module/Alias1:1.0", "Alias1",
+ {'tk_sequence', {'tk_union', "IDL:Module/Union:1.0", "Union",
+ {'tk_enum', "IDL:Module/Enum:1.0", "Module_Enum",
+ ["horse", "pig", "cow"]}, 2,
+ [{"horse", "First", 'tk_ushort'},
+ {"pig", "Second", {'tk_sequence', {'tk_string', 0}, 0}},
+ {"cow", "Third", {'tk_enum', "IDL:Module/Enum1:1.0",
+ "Module_Enum1", ["orange", "banana",
+ "apple"]}}]},0}},
+ S1 = [#'Module_Union'{label=cow, value=banana}, #'Module_Union'{label=pig, value=["This", "is", "a", "test", ""]}],
+ ?line B1 = cdr_encode:enc_type(#giop_env{version = {1, 1}}, T1, S1),
+ ?line {S1, <<>>, _} = cdr_decode:dec_type(T1, {1, 1}, B1, 0, big),
+ ok.
+
+%%-----------------------------------------------------------------
+%% Encode/decode test of type: exception
+%%-----------------------------------------------------------------
+exception_type(doc) -> [];
+exception_type(suite) -> [];
+exception_type(Config) when is_list(Config) ->
+ system_exceptions(),
+ user_exceptions(),
+ ok.
+
+system_exceptions() ->
+ E = #'UNKNOWN'{completion_status=?COMPLETED_YES},
+ {system_exception, T, E} = orber_exceptions:get_def(E),
+ ?line B = cdr_encode:enc_type(#giop_env{version = {1, 1}}, T,E),
+ ?line {E, _} = cdr_decode:dec_system_exception({1, 1}, B, 0, big),
+ E1 = #'INV_OBJREF'{completion_status=?COMPLETED_NO},
+ {system_exception, T1, E1} = orber_exceptions:get_def(E1),
+ ?line B1 = cdr_encode:enc_type(#giop_env{version = {1, 1}}, T1,E1),
+ ?line {E1, _} = cdr_decode:dec_system_exception({1, 1}, B1, 0, big),
+ E2 = #'BAD_OPERATION'{completion_status=?COMPLETED_NO},
+ {system_exception, T2, E2} = orber_exceptions:get_def(E2),
+ ?line B2 = cdr_encode:enc_type(#giop_env{version = {1, 1}}, T2,E2),
+ ?line {E2, _} = cdr_decode:dec_system_exception({1, 1}, B2, 0, big),
+ E3 = #'INTF_REPOS'{completion_status=?COMPLETED_MAYBE},
+ {system_exception, T3, E3} = orber_exceptions:get_def(E3),
+ ?line B3 = cdr_encode:enc_type(#giop_env{version = {1, 1}}, T3,E3),
+ ?line {E3, _} = cdr_decode:dec_system_exception({1, 1}, B3, 0, big),
+ ok.
+
+user_exceptions() ->
+ E = #'Module_Except1'{rest_of_name=["I","am","testing","exceptions"], why="Error"},
+ {user_exception, T, E} = orber_exceptions:get_def(E),
+ ?line B = cdr_encode:enc_type(#giop_env{version = {1, 1}}, T, E),
+ ?line {E, _} = cdr_decode:dec_user_exception({1, 1}, B, 0, big),
+ E1 = #'Module_Except2'{e=banana,
+ s=#'Module_Struct2'{long_sequence=[12,-4040,
+ 1234567898],
+ e=horse,
+ o=$a}},
+ {user_exception, T1, E1} = orber_exceptions:get_def(E1),
+ ?line B1 = cdr_encode:enc_type(#giop_env{version = {1, 1}}, T1, E1),
+ ?line {E1, _} = cdr_decode:dec_user_exception({1, 1}, B1, 0, big),
+ E2 = #'Module_Except3'{u=#'Module_Union1'{label=pig,value=["high","and","low"]},s=1313, o=objref(0)},
+ {user_exception, T2, E2} = orber_exceptions:get_def(E2),
+ ?line B2 = cdr_encode:enc_type(#giop_env{version = {1, 1}}, T2, E2),
+ ?line {E2, _} = cdr_decode:dec_user_exception({1, 1}, B2, 0, big),
+ E3 = #'Module_Except4'{},
+ {user_exception, T3, E3} = orber_exceptions:get_def(E3),
+ ?line B3 = cdr_encode:enc_type(#giop_env{version = {1, 1}}, T3, E3),
+ ?line {E3, _} = cdr_decode:dec_user_exception({1, 1}, B3, 0, big),
+ ok.
+
+%%-----------------------------------------------------------------
+%% Test Case: request encoding test
+%% Description: Precondition the stack must be started so the
+%% objectkey is valid.
+%%-----------------------------------------------------------------
+%request(suite) -> [];
+%request(_) ->
+% exit(not_implemented).
+
+%%-----------------------------------------------------------------
+%% Test Case: reply encoding test
+%% Description:
+%%-----------------------------------------------------------------
+reply(doc) -> ["Description", "more description"];
+reply(suite) -> [];
+reply(Config) when is_list(Config) ->
+ R = #reply_header{service_context=[], request_id=1,
+ reply_status='no_exception'},
+ ?line B = cdr_encode:enc_reply(#giop_env{version = {1, 1}, request_id = 1,
+ reply_status = 'no_exception',
+ tc = {'tk_long', [], [{'tk_sequence',
+ {'tk_string', 0}, 0}]},
+ result = 1200, parameters = [["foo","Bar"]],
+ ctx = []}),
+ ?line {R, 1200, [["foo","Bar"]]} =
+ cdr_decode:dec_message({'tk_long', [], [{'tk_sequence', {'tk_string', 0},0}]},
+ B),
+ ok.
+
+%%-----------------------------------------------------------------
+%% Test Case: cancel_request encoding test
+%% Description:
+%%-----------------------------------------------------------------
+cancel_request(doc) -> ["Description", "more description"];
+cancel_request(suite) -> [];
+cancel_request(Config) when is_list(Config) ->
+ R = #cancel_request_header{request_id=1},
+ ?line B = cdr_encode:enc_cancel_request(#giop_env{version = {1, 1},
+ request_id = 1}),
+ ?line R = cdr_decode:dec_message([], B),
+ ok.
+
+%%-----------------------------------------------------------------
+%% Test Case: locate_request encoding test
+%% Description:
+%%-----------------------------------------------------------------
+locate_request(doc) -> ["Description", "more description"];
+locate_request(suite) -> [];
+locate_request(Config) when is_list(Config) ->
+ io:format("Function not imlpemented yet"),
+ exit(not_implemented).
+
+%%-----------------------------------------------------------------
+%% Test Case: locate_reply encoding test
+%% Description:
+%%-----------------------------------------------------------------
+locate_reply(doc) -> ["Description", "more description"];
+locate_reply(suite) -> [];
+locate_reply(Config) when is_list(Config) ->
+ io:format("Function not imlpemented yet"),
+ exit(not_implemented).
+
+%%-----------------------------------------------------------------
+%% Test Case: close_connection encoding test
+%% Description:
+%%-----------------------------------------------------------------
+close_connection(doc) -> ["Description", "more description"];
+close_connection(suite) -> [];
+close_connection(Config) when is_list(Config) ->
+ ?line B = cdr_encode:enc_close_connection(#giop_env{version = {1, 1}}),
+ ?line 'close_connection' = cdr_decode:dec_message([], B),
+ ok.
+
+%%-----------------------------------------------------------------
+%% Test Case: message_error encoding test
+%% Description:
+%%-----------------------------------------------------------------
+message_error(doc) -> ["Description", "more description"];
+message_error(suite) -> [];
+message_error(Config) when is_list(Config) ->
+ ?line B = cdr_encode:enc_message_error(#giop_env{version = {1, 1}}),
+ ?line 'message_error' = cdr_decode:dec_message([], B),
+ ok.
+
+
+
+%%-----------------------------------------------------------------
+%% Internal functions
+%%-----------------------------------------------------------------
+corba_fake_mk_objkey(Id, 'key', Pid) when is_pid(Pid) ->
+ Key = make_objkey(),
+ {list_to_binary(Id), 'key', Key, term_to_binary(undefined),
+ term_to_binary(undefined), term_to_binary(undefined)};
+corba_fake_mk_objkey(Id, 'key', RegName) when is_atom(RegName) ->
+ Key = term_to_binary(RegName),
+ {list_to_binary(Id), 'key', Key, term_to_binary(undefined),
+ term_to_binary(undefined), term_to_binary(undefined)};
+corba_fake_mk_objkey(Id, 'registered', RegName) when is_atom(RegName) ->
+ {list_to_binary(Id), 'registered', RegName, term_to_binary(undefined),
+ term_to_binary(undefined), term_to_binary(undefined)}.
+
+make_objkey() ->
+ term_to_binary({now(), node()}).
diff --git a/lib/orber/test/cdrcoding_12_SUITE.erl b/lib/orber/test/cdrcoding_12_SUITE.erl
new file mode 100644
index 0000000000..18e8eaa08a
--- /dev/null
+++ b/lib/orber/test/cdrcoding_12_SUITE.erl
@@ -0,0 +1,603 @@
+%%----------------------------------------------------------------------
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 2000-2010. All Rights Reserved.
+%%
+%% The contents of this file are subject to the Erlang Public License,
+%% Version 1.1, (the "License"); you may not use this file except in
+%% compliance with the License. You should have received a copy of the
+%% Erlang Public License along with this software. If not, it can be
+%% retrieved online at http://www.erlang.org/.
+%%
+%% Software distributed under the License is distributed on an "AS IS"
+%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+%% the License for the specific language governing rights and limitations
+%% under the License.
+%%
+%% %CopyrightEnd%
+%%
+%%
+%%-----------------------------------------------------------------
+%%
+%% Description:
+%% Test suite for the CDR encode/decode functions
+%%
+%%-----------------------------------------------------------------
+
+-module(cdrcoding_12_SUITE).
+
+-include("idl_output/Module.hrl").
+-include("test_server.hrl").
+-include_lib("orber/include/corba.hrl").
+-include_lib("orber/src/orber_iiop.hrl").
+
+-define(default_timeout, ?t:minutes(5)).
+
+%%-----------------------------------------------------------------
+%% External exports
+%%-----------------------------------------------------------------
+-export([all/1]).
+
+%%-----------------------------------------------------------------
+%% Internal exports
+%%-----------------------------------------------------------------
+-export([]).
+-compile(export_all).
+
+%%-----------------------------------------------------------------
+%% Func: all/1
+%% Args:
+%% Returns:
+%%-----------------------------------------------------------------
+all(doc) -> ["Description", "more description"];
+all(suite) -> {req,
+ [mnesia],
+ {conf, init_all, cases(), finish_all}}.
+
+cases() ->
+ [types, reply, cancel_request, close_connection, message_error].
+%% request, locate_request, locate_reply].
+
+%%-----------------------------------------------------------------
+%% Init and cleanup functions.
+%%-----------------------------------------------------------------
+
+init_per_testcase(_Case, Config) ->
+ Path = code:which(?MODULE),
+ code:add_pathz(filename:join(filename:dirname(Path), "idl_output")),
+ ?line Dog=test_server:timetrap(?default_timeout),
+ [{watchdog, Dog}|Config].
+
+
+fin_per_testcase(_Case, Config) ->
+ Path = code:which(?MODULE),
+ code:del_path(filename:join(filename:dirname(Path), "idl_output")),
+ Dog = ?config(watchdog, Config),
+ test_server:timetrap_cancel(Dog),
+ ok.
+
+init_all(Config) when is_list(Config) ->
+ orber:jump_start(0),
+ if
+ is_list(Config) ->
+ Config;
+ true ->
+ exit("Config not a list")
+ end.
+
+finish_all(Config) when is_list(Config) ->
+ orber:jump_stop(),
+ Config.
+
+%%-----------------------------------------------------------------
+%% Test Case: type encoding tests
+%% Description: Just testing the complex types, the others are
+%% tested in the cdrlib SUITE.
+%%-----------------------------------------------------------------
+types(doc) -> ["Description", "more description"];
+types(suite) -> [do_register, null_type, void_type, principal_type,
+ objref_type, struct_type, union_type, string_type,
+ array_type, any_type, typecode_type, alias_type,
+ exception_type, do_unregister].
+
+do_register(doc) -> [];
+do_register(suite) -> [];
+do_register(Config) when is_list(Config) ->
+ 'oe_orber_test':'oe_register'(),
+ ok.
+do_unregister(doc) -> [];
+do_unregister(suite) -> [];
+do_unregister(Config) when is_list(Config) ->
+ 'oe_orber_test':'oe_unregister'(),
+ ok.
+%%-----------------------------------------------------------------
+%% Encode/decode test of type: null
+%%-----------------------------------------------------------------
+null_type(doc) -> [];
+null_type(suite) -> [];
+null_type(Config) when is_list(Config) ->
+ ?line B = cdr_encode:enc_type(#giop_env{version = {1, 2}}, 'tk_null', 'null'),
+ ?line {'null', <<>>, _} = cdr_decode:dec_type('tk_null', {1, 2}, B, 0, big),
+ ok.
+
+%%-----------------------------------------------------------------
+%% Encode/decode test of type: void
+%%-----------------------------------------------------------------
+void_type(doc) -> [];
+void_type(suite) -> [];
+void_type(Config) when is_list(Config) ->
+ ?line B = cdr_encode:enc_type(#giop_env{version = {1, 2}}, 'tk_void', 'ok'),
+ ?line {'ok', <<>>, _} = cdr_decode:dec_type('tk_void', {1, 2}, B, 0, big),
+ ok.
+
+%%-----------------------------------------------------------------
+%% Encode/decode test of type: principal
+%%-----------------------------------------------------------------
+principal_type(doc) -> [];
+principal_type(suite) -> [];
+principal_type(Config) when is_list(Config) ->
+ ?line B0 = cdr_encode:enc_type(#giop_env{version = {1, 2}}, 'tk_Principal', "principal"),
+ ?line {"principal", <<>>, _} = cdr_decode:dec_type('tk_Principal', {1, 2}, B0, 0, big),
+ ?line B1 = cdr_encode:enc_type(#giop_env{version = {1, 2}}, 'tk_Principal', ""),
+ ?line {"", <<>>, _} = cdr_decode:dec_type('tk_Principal', {1, 2}, B1, 0, big),
+ ?line B2 = cdr_encode:enc_type(#giop_env{version = {1, 2}}, 'tk_Principal', "principal"),
+ ?line {"principal", <<>>, _} =
+ cdr_decode:dec_type('tk_Principal', {1, 2}, B2, 0, big),
+ ok.
+
+%%-----------------------------------------------------------------
+%% Encode/decode test of type: object reference
+%%-----------------------------------------------------------------
+version() -> #'IIOP_Version'{major=1,minor=2}.
+
+objref(0) ->
+ PB = #'IIOP_ProfileBody_1_1'{iiop_version=version(),
+ host="my.hostname.org",
+ port=4040,
+ object_key="ExternalKey: which is an arbitary octet sequence",
+ components=[]},
+ TP = #'IOP_TaggedProfile'{tag=?TAG_INTERNET_IOP, profile_data=PB},
+ #'IOP_IOR'{type_id="IDL:Module/Interface:1.0", profiles=[TP]};
+objref(1) ->
+ K = corba_fake_mk_objkey("IDL:Module/Interface:1.0", key,
+ list_to_pid("<0.100.0>")),
+ PB = #'IIOP_ProfileBody_1_1'{iiop_version=version(),
+ host="my.hostname.org",
+ port=4040,
+ object_key=K, components=[]},
+ TP = #'IOP_TaggedProfile'{tag=?TAG_INTERNET_IOP, profile_data=PB},
+ #'IOP_IOR'{type_id="IDL:Module/Interface:1.0", profiles=[TP]};
+objref(2) ->
+ K = corba_fake_mk_objkey("IDL:Module/Interface:1.0", registered,
+ list_to_atom("orber_nameservice")),
+ PB = #'IIOP_ProfileBody_1_1'{iiop_version=version(),
+ host="my.hostname.org",
+ port=4040,
+ object_key=K, components=[]},
+ TP = #'IOP_TaggedProfile'{tag=?TAG_INTERNET_IOP, profile_data=PB},
+ #'IOP_IOR'{type_id="IDL:Module/Interface:1.0", profiles=[TP]}.
+
+objref_type(doc) -> [];
+objref_type(suite) -> [];
+objref_type(Config) when is_list(Config) ->
+ T = {'tk_objref', "IDL:Module/Interface:1.0", "Interface"},
+ Objref0 = objref(0),
+ ?line B0 = cdr_encode:enc_type(#giop_env{version = {1, 2}}, T, Objref0),
+ ?line {Objref0, <<>>, _} = cdr_decode:dec_type(T, {1, 2}, B0, 0, big),
+ Objref1 = objref(1),
+ ?line B1 = cdr_encode:enc_type(#giop_env{version = {1, 2}}, T, Objref1),
+ ?line {Objref1, <<>>, _} = cdr_decode:dec_type(T, {1, 2}, B1, 0, big),
+ Objref2 = objref(2),
+ ?line B2 = cdr_encode:enc_type(#giop_env{version = {1, 2}}, T, Objref2),
+ ?line {Objref2, <<>>, _} = cdr_decode:dec_type(T, {1, 2}, B2, 0, big),
+ ok.
+
+
+
+%%-----------------------------------------------------------------
+%% Encode/decode test of type: struct
+%%-----------------------------------------------------------------
+struct_type(doc) -> [];
+struct_type(suite) -> [];
+struct_type(Config) when is_list(Config) ->
+ T0 = {'tk_struct',"IDL:Module/Struct0:1.0", "Module_Struct0",
+ [{"long", 'tk_long'}, {"short", 'tk_short'}, {"character", 'tk_char'}]},
+ S0 = #'Module_Struct0'{l=-4711, s=17, c=$a},
+ ?line B0 = cdr_encode:enc_type(#giop_env{version = {1, 2}}, T0, S0),
+ ?line {S0, <<>>, _} = cdr_decode:dec_type(T0, {1, 2}, B0, 0, big),
+
+ T1 = {'tk_struct', "IDL:Module/Struct1:1.0", "Module_Struct1",
+ [{"string", {'tk_string', 0}}, {"ushort", 'tk_ushort'}, {"ulong", 'tk_ulong'}]},
+ S1 = #'Module_Struct1'{s="Hi !!!!", us=17, ul=4711},
+ ?line B1 = cdr_encode:enc_type(#giop_env{version = {1, 2}}, T1, S1),
+ ?line {S1, <<>>, _} = cdr_decode:dec_type(T1, {1, 2}, B1, 0, big),
+
+ T2 = {'tk_struct', "IDL:Module/Struct2:1.0", "Module_Struct2",
+ [{"long_sequence", {'tk_sequence', 'tk_long', 0}},
+ {"enum", {'tk_enum', "IDL:Module/Enum:1.0", "Module_Enum", ["horse", "pig", "cow"]}},
+ {"octet", 'tk_octet'}]},
+ S2 = #'Module_Struct2'{long_sequence=[4711, 350000, 0, -3030, -600000], e=cow, o=$X},
+ ?line B2 = cdr_encode:enc_type(#giop_env{version = {1, 2}}, T2, S2),
+ ?line {S2, <<>>, _} = cdr_decode:dec_type(T2, {1, 2}, B2, 0, big),
+ ok.
+
+%%-----------------------------------------------------------------
+%% Encode/decode test of type: union
+%%-----------------------------------------------------------------
+union_type(doc) -> [];
+union_type(suite) -> [];
+union_type(Config) when is_list(Config) ->
+ T0 = {'tk_union', "IDL:Module/Union:1.0", "Union", 'tk_short', 2,
+ [{0, "First", 'tk_short'},
+ {1, "Second", {'tk_string', 0}},
+ {2, "Third", 'tk_char'}]},
+ S0 = #'Module_Union'{label=1, value="Foo Bar !"},
+ ?line B0 = cdr_encode:enc_type(#giop_env{version = {1, 2}}, T0, S0),
+ ?line {S0, <<>>, _} = cdr_decode:dec_type(T0, {1, 2}, B0, 0, big),
+ S1 = #'Module_Union'{label=0, value=-17},
+ ?line B1 = cdr_encode:enc_type(#giop_env{version = {1, 2}}, T0, S1),
+ ?line {S1, <<>>, _} = cdr_decode:dec_type(T0, {1, 2}, B1, 0, big),
+ S2 = #'Module_Union'{label=2, value=$X},
+ ?line B2 = cdr_encode:enc_type(#giop_env{version = {1, 2}}, T0, S2),
+ ?line {S2, <<>>, _} = cdr_decode:dec_type(T0, {1, 2}, B2, 0, big),
+ T1 = {'tk_union', "IDL:Module/Union1:1.0", "Union1",
+ {'tk_enum', "IDL:Module/Enum:1.0",
+ "Module_Enum", ["horse", "pig", "cow"]}, "pig",
+ [{"horse", "First", 'tk_ushort'},
+ {"pig", "Second", {'tk_sequence', {'tk_string', 0}, 0}},
+ {"cow", "Third", {'tk_enum', "IDL:Module/Enum1:1.0",
+ "Module_Enum1", ["orange", "banana", "apple"]}}]},
+ S3 = #'Module_Union1'{label=pig, value=["Foo", "Bar", "!"]},
+ ?line B3 = cdr_encode:enc_type(#giop_env{version = {1, 2}}, T1, S3),
+ ?line {S3, <<>>, _} = cdr_decode:dec_type(T1, {1, 2}, B3, 0, big),
+ S4 = #'Module_Union1'{label=cow, value=apple},
+ ?line B4 = cdr_encode:enc_type(#giop_env{version = {1, 2}}, T1, S4),
+ ?line {S4, <<>>, _} = cdr_decode:dec_type(T1, {1, 2}, B4, 0, big),
+ S5 = #'Module_Union1'{label=horse, value=17},
+ ?line B5 = cdr_encode:enc_type(#giop_env{version = {1, 2}}, T1, S5),
+ ?line {S5, <<>>, _} = cdr_decode:dec_type(T1, {1, 2}, B5, 0, big),
+ T2 = {'tk_union', "IDL:Module/Union2:1.0", "Union2",
+ {'tk_enum', "IDL:Module/Enum:1.0",
+ "Module_Enum", ["horse", "pig", "cow"]}, "pig",
+ [{"horse", "First", {'tk_array', 'tk_long', 3}},
+ {"pig", "Second",
+ {'tk_union', "IDL:Module/Union:1.0", "Union", 'tk_short', 2,
+ [{0, "First", 'tk_short'},
+ {1, "Second", {'tk_string', 0}},
+ {2, "Third", 'tk_char'}]}},
+ {"cow", "Third", {'tk_union', "IDL:Module/Union1:1.0", "Union1",
+ {'tk_enum', "IDL:Module/Enum:1.0",
+ "Module_Enum", ["horse", "pig", "cow"]}, "pig",
+ [{"horse", "First", 'tk_ushort'},
+ {"pig", "Second", {'tk_sequence',
+ {'tk_string', 0}, 0}},
+ {"cow", "Third", {'tk_enum',
+ "IDL:Module/Enum1:1.0",
+ "Module_Enum1",
+ ["orange", "banana",
+ "apple"]}}]}}]},
+ S6 = #'Module_Union2'{label=pig, value=#'Module_Union'{label=0, value=-17}},
+ ?line B6 = cdr_encode:enc_type(#giop_env{version = {1, 2}}, T2, S6),
+ ?line {S6, <<>>, _} = cdr_decode:dec_type(T2, {1, 2}, B6, 0, big),
+ S7 = #'Module_Union2'{label=cow, value=#'Module_Union1'{label=pig,
+ value=["Foo", "Bar", "!"]}},
+ ?line B7 = cdr_encode:enc_type(#giop_env{version = {1, 2}}, T2, S7),
+ ?line {S7, <<>>, _} = cdr_decode:dec_type(T2, {1, 2}, B7, 0, big),
+ S8 = #'Module_Union2'{label=horse, value={-17, 1234567890, -987654321}},
+ ?line B8 = cdr_encode:enc_type(#giop_env{version = {1, 2}}, T2, S8),
+ ?line {S8, <<>>, _} = cdr_decode:dec_type(T2, {1, 2}, B8, 0, big),
+ ok.
+
+%%-----------------------------------------------------------------
+%% Encode/decode test of type: string
+%%-----------------------------------------------------------------
+string_type(doc) -> [];
+string_type(suite) -> [];
+string_type(Config) when is_list(Config) ->
+ S0 = "Foo Bar ???",
+ ?line B0 = cdr_encode:enc_type(#giop_env{version = {1, 2}}, {'tk_string', 0}, S0),
+ ?line {S0, <<>>, _} = cdr_decode:dec_type({'tk_string', 0}, {1, 2}, B0, 0, big),
+ S1 = "Yes, Foo Bar !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! more than 5000 characters",
+ ?line B1 = cdr_encode:enc_type(#giop_env{version = {1, 2}}, {'tk_string', 0}, S1),
+ ?line {S1, <<>>, _} = cdr_decode:dec_type({'tk_string', 0}, {1, 2}, B1, 0, big),
+ S2 = "",
+ ?line B2 = cdr_encode:enc_type(#giop_env{version = {1, 2}}, {'tk_string', 0}, S2),
+ ?line {S2, <<>>, _} = cdr_decode:dec_type({'tk_string', 0}, {1, 2}, B2, 0, big),
+ S3 = "\0",
+ ?line B3 = cdr_encode:enc_type(#giop_env{version = {1, 2}}, {'tk_string', 0}, S3),
+ ?line {S3, <<>>, _} = cdr_decode:dec_type({'tk_string', 0}, {1, 2}, B3, 0, big),
+ S4 = "~n",
+ ?line B4 = cdr_encode:enc_type(#giop_env{version = {1, 2}}, {'tk_string', 0}, S4),
+ ?line {S4, <<>>, _} = cdr_decode:dec_type({'tk_string', 0}, {1, 2}, B4, 0, big),
+ ok.
+
+%%-----------------------------------------------------------------
+%% Encode/decode test of type: array
+%%-----------------------------------------------------------------
+array_type(doc) -> [];
+array_type(suite) -> [];
+array_type(Config) when is_list(Config) ->
+ T0 = {'tk_array', 'tk_long', 5},
+ S0 = {-100, 0, 30000, -900100900, 123456789},
+ ?line B0 = cdr_encode:enc_type(#giop_env{version = {1, 2}}, T0, S0),
+ ?line {S0, <<>>, _} = cdr_decode:dec_type(T0, {1, 2}, B0, 0, big),
+ T1 = {'tk_array', {'tk_enum', "IDL:Module/Enum:1.0", "Module_Enum", ["horse", "pig", "cow"]}, 2},
+ S1 = {pig, cow},
+ ?line B1 = cdr_encode:enc_type(#giop_env{version = {1, 2}}, T1, S1),
+ ?line {S1, <<>>, _} = cdr_decode:dec_type(T1, {1, 2}, B1, 0, big),
+ T2 = {'tk_array', {'tk_union', "IDL:Module/Union:1.0", "Union",
+ {'tk_enum', "IDL:Module/Enum:1.0", "Module_Enum", ["horse", "pig", "cow"]}, "pig",
+ [{"horse", "First", 'tk_ushort'},
+ {"pig", "Second", {'tk_sequence', {'tk_string', 0}, 0}},
+ {"cow", "Third", {'tk_enum', "IDL:Module/Enum1:1.0",
+ "Module_Enum1", ["orange", "banana", "apple"]}}]}, 2},
+ S2 = {#'Module_Union'{label=cow, value=banana}, #'Module_Union'{label=pig, value=["This", "is", "a", "test", ""]}},
+ ?line B2 = cdr_encode:enc_type(#giop_env{version = {1, 2}}, T2, S2),
+ ?line {S2, <<>>, _} = cdr_decode:dec_type(T2, {1, 2}, B2, 0, big),
+ T3 = {'tk_array', {'tk_objref', "IDL:Module/Interface:1.0", "Interface"}, 3},
+ S3 = {objref(0), objref(1), objref(2)},
+ ?line B3 = cdr_encode:enc_type(#giop_env{version = {1, 2}}, T3, S3),
+ ?line {S3, <<>>, _} = cdr_decode:dec_type(T3, {1, 2}, B3, 0, big),
+ ok.
+%%-----------------------------------------------------------------
+%% Encode/decode test of type: TypeCode
+%%-----------------------------------------------------------------
+any_type(doc) -> [];
+any_type(suite) -> [];
+any_type(Config) when is_list(Config) ->
+ T = 'tk_any',
+ TC = {'tk_struct', "IDL:Module/Struct2:1.0", "Module_Struct2",
+ [{"long_sequence", {'tk_sequence', 'tk_long', 0}},
+ {"enum", {'tk_enum', "IDL:Module/Enum:1.0", "Module_Enum",
+ ["horse", "pig", "cow"]}},
+ {"octet", 'tk_octet'}]},
+ S = #'Module_Struct2'{long_sequence=[4711, 350000, 0, -3030, -600000],
+ e=cow, o=$X},
+ Any = #any{typecode=TC,value=S},
+ ?line B = cdr_encode:enc_type(#giop_env{version = {1, 2}}, T,Any),
+ ?line {Any, <<>>, _} = cdr_decode:dec_type(T, {1, 2}, B, 0, big),
+ TC1 = {'tk_array', {'tk_union', "IDL:Module/Union:1.0", "Union",
+ {'tk_enum', "IDL:Module/Enum:1.0", "Module_Enum",
+ ["horse", "pig", "cow"]}, 1,
+ [{"horse", "First", 'tk_ushort'},
+ {"pig", "Second", {'tk_sequence', {'tk_string', 0}, 0}},
+ {"cow", "Third", {'tk_enum', "IDL:Module/Enum1:1.0",
+ "Module_Enum1", ["orange", "banana",
+ "apple"]}}]},2},
+ S1 = {#'Module_Union'{label=cow, value=banana}, #'Module_Union'{label=pig, value=["This", "is", "a", "test", ""]}},
+ Any1 = #any{typecode=TC1,value=S1},
+ ?line B1 = cdr_encode:enc_type(#giop_env{version = {1, 2}}, T,Any1),
+ ?line {Any1, <<>>, _} = cdr_decode:dec_type(T, {1, 2}, B1, 0, big),
+ ok.
+
+
+%%-----------------------------------------------------------------
+%% Encode/decode test of type: TypeCode
+%%-----------------------------------------------------------------
+typecode_type(doc) -> [];
+typecode_type(suite) -> [];
+typecode_type(Config) when is_list(Config) ->
+ T = 'tk_TypeCode',
+ TC = {'tk_array', {'tk_union', "IDL:Module/Union:1.0", "Union",
+ {'tk_enum', "IDL:Module/Enum:1.0", "Module_Enum",
+ ["horse", "pig", "cow"]}, 1,
+ [{"horse", "First", 'tk_ushort'},
+ {"pig", "Second", {'tk_sequence', {'tk_string', 0}, 0}},
+ {"cow", "Third", {'tk_enum', "IDL:Module/Enum1:1.0",
+ "Module_Enum1", ["orange", "banana",
+ "apple"]}}]}, 10},
+ ?line B = cdr_encode:enc_type(#giop_env{version = {1, 2}}, T,TC),
+ ?line {TC, <<>>, _} = cdr_decode:dec_type(T, {1, 2}, B, 0, big),
+ TC1 = {'tk_union', "IDL:Module/Union2:1.0", "Union2",
+ {'tk_enum', "IDL:Module/Enum:1.0",
+ "Module_Enum", ["horse", "pig", "cow"]}, 2,
+ [{"horse", "First", 'tk_long'},
+ {"pig", "Second",
+ {'tk_union', "IDL:Module/Union:1.0", "Union", 'tk_short', 2,
+ [{0, "First", 'tk_short'},
+ {1, "Second", {'tk_string', 0}},
+ {2, "Third", 'tk_char'}]}},
+ {"cow", "Third", {'tk_union', "IDL:Module/Union1:1.0", "Union1",
+ {'tk_enum', "IDL:Module/Enum:1.0",
+ "Module_Enum", ["horse", "pig", "cow"]}, 2,
+ [{"horse", "First", 'tk_ushort'},
+ {"pig", "Second", {'tk_sequence',
+ {'tk_string', 0}, 0}},
+ {"cow", "Third", {'tk_enum',
+ "IDL:Module/Enum1:1.0",
+ "Module_Enum1",
+ ["orange", "banana",
+ "apple"]}}]}}]},
+ ?line B1 = cdr_encode:enc_type(#giop_env{version = {1, 2}}, T, TC1),
+ ?line {TC1, <<>>, _} = cdr_decode:dec_type(T, {1, 2}, B1, 0, big),
+ ok.
+
+%%-----------------------------------------------------------------
+%% Encode/decode test of type: TypeCode
+%%-----------------------------------------------------------------
+alias_type(doc) -> [];
+alias_type(suite) -> [];
+alias_type(Config) when is_list(Config) ->
+ T = {'tk_alias', "IDL:Module/Alias:1.0", "Alias",
+ {'tk_struct', "IDL:Module/Struct2:1.0", "Module_Struct2",
+ [{"long_sequence", {'tk_sequence', 'tk_long', 0}},
+ {"enum", {'tk_enum', "IDL:Module/Enum:1.0", "Module_Enum",
+ ["horse", "pig", "cow"]}},
+ {"octet", 'tk_octet'}]}},
+ S = #'Module_Struct2'{long_sequence=[4711, 350000, 0, -3030, -600000],
+ e=cow, o=$X},
+ ?line B = cdr_encode:enc_type(#giop_env{version = {1, 2}}, T,S),
+ ?line {S, <<>>, _} = cdr_decode:dec_type(T, {1, 2}, B, 0, big),
+ T1 = {'tk_alias', "IDL:Module/Alias1:1.0", "Alias1",
+ {'tk_sequence', {'tk_union', "IDL:Module/Union:1.0", "Union",
+ {'tk_enum', "IDL:Module/Enum:1.0", "Module_Enum",
+ ["horse", "pig", "cow"]}, 2,
+ [{"horse", "First", 'tk_ushort'},
+ {"pig", "Second", {'tk_sequence', {'tk_string', 0}, 0}},
+ {"cow", "Third", {'tk_enum', "IDL:Module/Enum1:1.0",
+ "Module_Enum1", ["orange", "banana",
+ "apple"]}}]},0}},
+ S1 = [#'Module_Union'{label=cow, value=banana}, #'Module_Union'{label=pig, value=["This", "is", "a", "test", ""]}],
+ ?line B1 = cdr_encode:enc_type(#giop_env{version = {1, 2}}, T1, S1),
+ ?line {S1, <<>>, _} = cdr_decode:dec_type(T1, {1, 2}, B1, 0, big),
+ ok.
+
+%%-----------------------------------------------------------------
+%% Encode/decode test of type: exception
+%%-----------------------------------------------------------------
+exception_type(doc) -> [];
+exception_type(suite) -> [];
+exception_type(Config) when is_list(Config) ->
+ system_exceptions(),
+ user_exceptions(),
+ ok.
+
+system_exceptions() ->
+ E = #'UNKNOWN'{completion_status=?COMPLETED_YES},
+ {system_exception, T, E} = orber_exceptions:get_def(E),
+ ?line B = cdr_encode:enc_type(#giop_env{version = {1, 2}}, T,E),
+ ?line {E, _} = cdr_decode:dec_system_exception({1, 2}, B, 0, big),
+ E1 = #'INV_OBJREF'{completion_status=?COMPLETED_NO},
+ {system_exception, T1, E1} = orber_exceptions:get_def(E1),
+ ?line B1 = cdr_encode:enc_type(#giop_env{version = {1, 2}}, T1,E1),
+ ?line {E1, _} = cdr_decode:dec_system_exception({1, 2}, B1, 0, big),
+ E2 = #'BAD_OPERATION'{completion_status=?COMPLETED_NO},
+ {system_exception, T2, E2} = orber_exceptions:get_def(E2),
+ ?line B2 = cdr_encode:enc_type(#giop_env{version = {1, 2}}, T2,E2),
+ ?line {E2, _} = cdr_decode:dec_system_exception({1, 2}, B2, 0, big),
+ E3 = #'INTF_REPOS'{completion_status=?COMPLETED_MAYBE},
+ {system_exception, T3, E3} = orber_exceptions:get_def(E3),
+ ?line B3 = cdr_encode:enc_type(#giop_env{version = {1, 2}}, T3,E3),
+ ?line {E3, _} = cdr_decode:dec_system_exception({1, 2}, B3, 0, big),
+ ok.
+
+user_exceptions() ->
+ E = #'Module_Except1'{rest_of_name=["I","am","testing","exceptions"], why="Error"},
+ {user_exception, T, E} = orber_exceptions:get_def(E),
+ ?line B = cdr_encode:enc_type(#giop_env{version = {1, 2}}, T, E),
+ ?line {E, _} = cdr_decode:dec_user_exception({1, 2}, B, 0, big),
+ E1 = #'Module_Except2'{e=banana,
+ s=#'Module_Struct2'{long_sequence=[12,-4040,
+ 1234567898],
+ e=horse,
+ o=$a}},
+ {user_exception, T1, E1} = orber_exceptions:get_def(E1),
+ ?line B1 = cdr_encode:enc_type(#giop_env{version = {1, 2}}, T1, E1),
+ ?line {E1, _} = cdr_decode:dec_user_exception({1, 2}, B1, 0, big),
+ E2 = #'Module_Except3'{u=#'Module_Union1'{label=pig,value=["high","and","low"]},s=1313, o=objref(0)},
+ {user_exception, T2, E2} = orber_exceptions:get_def(E2),
+ ?line B2 = cdr_encode:enc_type(#giop_env{version = {1, 2}}, T2, E2),
+ ?line {E2, _} = cdr_decode:dec_user_exception({1, 2}, B2, 0, big),
+ E3 = #'Module_Except4'{},
+ {user_exception, T3, E3} = orber_exceptions:get_def(E3),
+ ?line B3 = cdr_encode:enc_type(#giop_env{version = {1, 2}}, T3, E3),
+ ?line {E3, _} = cdr_decode:dec_user_exception({1, 2}, B3, 0, big),
+ ok.
+
+%%-----------------------------------------------------------------
+%% Test Case: request encoding test
+%% Description: Precondition the stack must be started so the
+%% objectkey is valid.
+%%-----------------------------------------------------------------
+%request(suite) -> [];
+%request(_) ->
+% exit(not_implemented).
+
+%%-----------------------------------------------------------------
+%% Test Case: reply encoding test
+%% Description:
+%%-----------------------------------------------------------------
+reply(doc) -> ["Description", "more description"];
+reply(suite) -> [];
+reply(Config) when is_list(Config) ->
+ R = #reply_header{service_context=[], request_id=1,
+ reply_status='no_exception'},
+ ?line B = cdr_encode:enc_reply(#giop_env{version = {1, 2}, request_id = 1,
+ reply_status = 'no_exception',
+ tc = {'tk_long', [], [{'tk_sequence',
+ {'tk_string', 0}, 0}]},
+ result = 1200,
+ parameters = [["foo","Bar"]],
+ ctx = []}),
+
+ ?line {R, 1200, [["foo","Bar"]]} =
+ cdr_decode:dec_message({'tk_long', [], [{'tk_sequence', {'tk_string', 0},0}]},
+ B),
+
+ ok.
+
+%%-----------------------------------------------------------------
+%% Test Case: cancel_request encoding test
+%% Description:
+%%-----------------------------------------------------------------
+cancel_request(doc) -> ["Description", "more description"];
+cancel_request(suite) -> [];
+cancel_request(Config) when is_list(Config) ->
+ R = #cancel_request_header{request_id=1},
+ ?line B = cdr_encode:enc_cancel_request(#giop_env{version = {1, 2},
+ request_id = 1}),
+ ?line R = cdr_decode:dec_message([], B),
+ ok.
+
+%%-----------------------------------------------------------------
+%% Test Case: locate_request encoding test
+%% Description:
+%%-----------------------------------------------------------------
+locate_request(doc) -> ["Description", "more description"];
+locate_request(suite) -> [];
+locate_request(Config) when is_list(Config) ->
+ io:format("Function not imlpemented yet"),
+ exit(not_implemented).
+
+%%-----------------------------------------------------------------
+%% Test Case: locate_reply encoding test
+%% Description:
+%%-----------------------------------------------------------------
+locate_reply(doc) -> ["Description", "more description"];
+locate_reply(suite) -> [];
+locate_reply(Config) when is_list(Config) ->
+ io:format("Function not imlpemented yet"),
+ exit(not_implemented).
+
+%%-----------------------------------------------------------------
+%% Test Case: close_connection encoding test
+%% Description:
+%%-----------------------------------------------------------------
+close_connection(doc) -> ["Description", "more description"];
+close_connection(suite) -> [];
+close_connection(Config) when is_list(Config) ->
+ ?line B = cdr_encode:enc_close_connection(#giop_env{version = {1, 2}}),
+ ?line 'close_connection' = cdr_decode:dec_message([], B),
+ ok.
+
+%%-----------------------------------------------------------------
+%% Test Case: message_error encoding test
+%% Description:
+%%-----------------------------------------------------------------
+message_error(doc) -> ["Description", "more description"];
+message_error(suite) -> [];
+message_error(Config) when is_list(Config) ->
+ ?line B = cdr_encode:enc_message_error(#giop_env{version = {1, 2}}),
+ ?line 'message_error' = cdr_decode:dec_message([], B),
+ ok.
+
+
+
+%%-----------------------------------------------------------------
+%% Internal functions
+%%-----------------------------------------------------------------
+corba_fake_mk_objkey(Id, 'key', Pid) when is_pid(Pid) ->
+ Key = make_objkey(),
+ {list_to_binary(Id), 'key', Key, term_to_binary(undefined),
+ term_to_binary(undefined), term_to_binary(undefined)};
+corba_fake_mk_objkey(Id, 'key', RegName) when is_atom(RegName) ->
+ Key = term_to_binary(RegName),
+ {list_to_binary(Id), 'key', Key, term_to_binary(undefined),
+ term_to_binary(undefined), term_to_binary(undefined)};
+corba_fake_mk_objkey(Id, 'registered', RegName) when is_atom(RegName) ->
+ {list_to_binary(Id), 'registered', RegName, term_to_binary(undefined),
+ term_to_binary(undefined), term_to_binary(undefined)}.
+
+make_objkey() ->
+ term_to_binary({now(), node()}).
diff --git a/lib/orber/test/cdrlib_SUITE.erl b/lib/orber/test/cdrlib_SUITE.erl
new file mode 100644
index 0000000000..fa2d7f2a30
--- /dev/null
+++ b/lib/orber/test/cdrlib_SUITE.erl
@@ -0,0 +1,487 @@
+%%
+%% %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%
+%%
+%%
+%%-----------------------------------------------------------------
+%%
+%% Description:
+%% Test suite for the CDR basic type encode/decode functions
+%%
+%%-----------------------------------------------------------------
+-module(cdrlib_SUITE).
+
+-include("test_server.hrl").
+
+-define(default_timeout, ?t:minutes(3)).
+
+%%-----------------------------------------------------------------
+%% External exports
+%%-----------------------------------------------------------------
+-export([all/1]).
+
+%%-----------------------------------------------------------------
+%% Internal exports
+%%-----------------------------------------------------------------
+-export([]).
+-compile(export_all).
+
+%%-----------------------------------------------------------------
+%% Func: all/1
+%% Args:
+%% Returns:
+%%-----------------------------------------------------------------
+all(doc) -> ["Description", "more description"];
+all(suite) ->
+ [short, ushort, long, ulong, longlong, ulonglong, boolean, character, octet,
+ float, double, enum].
+
+%%-----------------------------------------------------------------
+%% Init and cleanup functions.
+%%-----------------------------------------------------------------
+
+init_per_testcase(_Case, Config) ->
+ ?line Dog=test_server:timetrap(?default_timeout),
+ [{watchdog, Dog}|Config].
+
+
+fin_per_testcase(_Case, Config) ->
+ Dog = ?config(watchdog, Config),
+ test_server:timetrap_cancel(Dog),
+ ok.
+
+%%-----------------------------------------------------------------
+%% Test Case: short integer test
+%% Description:
+%%-----------------------------------------------------------------
+short(doc) -> ["Description", "more description"];
+short(suite) -> [];
+short(_) ->
+ short_big_loop([-32768, -4040, -1, 0, 4040, 32767]),
+ short_little_loop([-32768, -4040, -1, 0, 4040, 32767]),
+ bad_short().
+
+short_big_loop([]) ->
+ ok;
+short_big_loop([X |List]) ->
+ ?line [CodedType] = cdrlib:enc_short(X, []),
+ ?line {X, <<>>} = cdrlib:dec_short(big, CodedType),
+ short_big_loop(List),
+ ok.
+
+short_little_loop([]) ->
+ ok;
+short_little_loop([X |List]) ->
+ ?line CodedType = enc_short_little(X, []),
+ ?line {X, <<>>} = cdrlib:dec_short(little, CodedType),
+ short_little_loop(List),
+ ok.
+
+enc_short_little(X, Message) ->
+ list_to_binary([(X) band 16#ff, ((X) bsr 8) band 16#ff | Message]).
+
+bad_short() ->
+ ?line {'EXCEPTION', _} = (catch cdrlib:enc_short('atom', [])),
+ ?line [CodedType] = cdrlib:enc_char($a, []),
+ ?line {'EXIT', _} = (catch cdrlib:dec_short(big, CodedType)),
+ ok.
+%%-----------------------------------------------------------------
+%% Test Case: unsigned short integer test
+%% Description:
+%%-----------------------------------------------------------------
+ushort(doc) -> ["Description", "more description"];
+ushort(suite) -> [];
+ushort(_) ->
+ ushort_big_loop([0, 4040, 65535]),
+ ushort_little_loop([0, 4040, 65535]),
+ bad_ushort().
+
+ushort_big_loop([]) ->
+ ok;
+ushort_big_loop([X |List]) ->
+ ?line [CodedType] = cdrlib:enc_unsigned_short(X, []),
+ ?line {X, <<>>} = cdrlib:dec_unsigned_short(big, CodedType),
+ ushort_big_loop(List),
+ ok.
+
+ushort_little_loop([]) ->
+ ok;
+ushort_little_loop([X |List]) ->
+ ?line CodedType = enc_ushort_little(X, []),
+ ?line {X, <<>>} = cdrlib:dec_unsigned_short(little, CodedType),
+ ushort_little_loop(List),
+ ok.
+
+enc_ushort_little(X, Message) ->
+ list_to_binary([(X) band 16#ff, ((X) bsr 8) band 16#ff | Message]).
+
+bad_ushort() ->
+ ok.
+%%-----------------------------------------------------------------
+%% Test Case: long integer test
+%% Description:
+%%-----------------------------------------------------------------
+long(doc) -> ["Description", "more description"];
+long(suite) -> [];
+long(_) ->
+ long_big_loop([-2147483648, -40404040, -32768, -4040, -1,
+ 0, 4040, 32767, 40404040, 2147483647]),
+ long_little_loop([-2147483648, -40404040, -32768, -4040, -1,
+ 0, 4040, 32767, 40404040, 2147483647]),
+ bad_long().
+
+
+long_big_loop([]) ->
+ ok;
+long_big_loop([X |List]) ->
+ ?line [CodedType] = cdrlib:enc_long(X, []),
+ ?line {X, <<>>} = cdrlib:dec_long(big, CodedType),
+ long_big_loop(List),
+ ok.
+
+long_little_loop([]) ->
+ ok;
+long_little_loop([X |List]) ->
+ ?line CodedType = enc_long_little(X, []),
+ ?line {X, <<>>} = cdrlib:dec_long(little, CodedType),
+ long_little_loop(List),
+ ok.
+
+enc_long_little(X, Message) ->
+ list_to_binary([(X) band 16#ff, ((X) bsr 8) band 16#ff, ((X) bsr 16) band 16#ff,
+ ((X) bsr 24) band 16#ff | Message]).
+
+bad_long() ->
+ ok.
+
+%%-----------------------------------------------------------------
+%% Test Case: unsigned long integer test
+%% Description:
+%%-----------------------------------------------------------------
+ulong(doc) -> ["Description", "more description"];
+ulong(suite) -> [];
+ulong(_) ->
+ ulong_big_loop([0, 4040, 65535, 40404040, 2147483647, 4294967295]),
+ ulong_little_loop([0, 4040, 65535, 40404040, 2147483647, 4294967295]),
+ bad_ulong().
+
+
+ulong_big_loop([]) ->
+ ok;
+ulong_big_loop([X |List]) ->
+ ?line [CodedType] = cdrlib:enc_unsigned_long(X, []),
+ ?line {X, <<>>} = cdrlib:dec_unsigned_long(big, CodedType),
+ ulong_big_loop(List),
+ ok.
+
+ulong_little_loop([]) ->
+ ok;
+ulong_little_loop([X |List]) ->
+ ?line CodedType = enc_ulong_little(X, []),
+ ?line {X, <<>>} = cdrlib:dec_unsigned_long(little, CodedType),
+ ulong_little_loop(List),
+ ok.
+
+enc_ulong_little(X, Message) ->
+ list_to_binary([(X) band 16#ff, ((X) bsr 8) band 16#ff, ((X) bsr 16) band 16#ff,
+ ((X) bsr 24) band 16#ff | Message]).
+
+
+bad_ulong() ->
+ ok.
+
+%%-----------------------------------------------------------------
+%% Test Case: long integer test
+%% Description:
+%%-----------------------------------------------------------------
+longlong(doc) -> ["Description", "more description"];
+longlong(suite) -> [];
+longlong(_) ->
+ longlong_big_loop([-2147483648, -40404040, -32768, -4040, -1,
+ 0, 4040, 32767, 40404040, 2147483647]),
+ longlong_little_loop([-2147483648, -40404040, -32768, -4040, -1,
+ 0, 4040, 32767, 40404040, 2147483647]),
+ bad_longlong().
+
+
+longlong_big_loop([]) ->
+ ok;
+longlong_big_loop([X |List]) ->
+ ?line [CodedType] = cdrlib:enc_longlong(X, []),
+ ?line {X, <<>>} = cdrlib:dec_longlong(big, CodedType),
+ longlong_big_loop(List),
+ ok.
+
+longlong_little_loop([]) ->
+ ok;
+longlong_little_loop([X |List]) ->
+ ?line CodedType = enc_longlong_little(X, []),
+ ?line {X, <<>>} = cdrlib:dec_longlong(little, CodedType),
+ longlong_little_loop(List),
+ ok.
+
+enc_longlong_little(X, Message) ->
+ list_to_binary([(X) band 16#ff, ((X) bsr 8) band 16#ff, ((X) bsr 16) band 16#ff,
+ ((X) bsr 24) band 16#ff, ((X) bsr 32) band 16#ff, ((X) bsr 40) band 16#ff,
+ ((X) bsr 48) band 16#ff, ((X) bsr 56) band 16#ff | Message]).
+
+bad_longlong() ->
+ ok.
+
+%%-----------------------------------------------------------------
+%% Test Case: unsigned long integer test
+%% Description:
+%%-----------------------------------------------------------------
+ulonglong(doc) -> ["Description", "more description"];
+ulonglong(suite) -> [];
+ulonglong(_) ->
+ ulonglong_big_loop([0, 4040, 65535, 40404040, 2147483647, 4294967295]),
+ ulonglong_little_loop([0, 4040, 65535, 40404040, 2147483647, 4294967295]),
+ bad_ulonglong().
+
+
+ulonglong_big_loop([]) ->
+ ok;
+ulonglong_big_loop([X |List]) ->
+ ?line [CodedType] = cdrlib:enc_unsigned_longlong(X, []),
+ ?line {X, <<>>} = cdrlib:dec_unsigned_longlong(big, CodedType),
+ ulonglong_big_loop(List),
+ ok.
+
+ulonglong_little_loop([]) ->
+ ok;
+ulonglong_little_loop([X |List]) ->
+ ?line CodedType = enc_ulonglong_little(X, []),
+ ?line {X, <<>>} = cdrlib:dec_unsigned_longlong(little, CodedType),
+ ulonglong_little_loop(List),
+ ok.
+
+enc_ulonglong_little(X, Message) ->
+ list_to_binary([(X) band 16#ff, ((X) bsr 8) band 16#ff, ((X) bsr 16) band 16#ff,
+ ((X) bsr 24) band 16#ff, ((X) bsr 32) band 16#ff, ((X) bsr 40) band 16#ff,
+ ((X) bsr 48) band 16#ff, ((X) bsr 56) band 16#ff | Message]).
+
+bad_ulonglong() ->
+ ok.
+
+
+
+%%-----------------------------------------------------------------
+%% Test Case: boolean test
+%% Description:
+%%-----------------------------------------------------------------
+boolean(doc) -> ["Description", "more description"];
+boolean(suite) -> [];
+boolean(_) ->
+ ?line [CodedTrue] = cdrlib:enc_bool('true', []),
+ ?line {'true', <<>>} = cdrlib:dec_bool(CodedTrue),
+ ?line [CodedFalse] = cdrlib:enc_bool('false', []),
+ ?line {'false', <<>>} = cdrlib:dec_bool(CodedFalse),
+ ok.
+
+%%-----------------------------------------------------------------
+%% Test Case: character test
+%% Description:
+%%-----------------------------------------------------------------
+character(doc) -> ["Description", "more description"];
+character(suite) -> [];
+character(_) ->
+ ?line [Coded_0] = cdrlib:enc_char($0, []),
+ ?line {$0, <<>>} = cdrlib:dec_char(Coded_0),
+ ?line [Coded_a] = cdrlib:enc_char($a, []),
+ ?line {$a, <<>>} = cdrlib:dec_char(Coded_a),
+ ?line [Coded_Z] = cdrlib:enc_char($Z, []),
+ ?line {$Z, <<>>} = cdrlib:dec_char(Coded_Z),
+ ?line [Coded_dollar] = cdrlib:enc_char($$, []),
+ ?line {$$, <<>>} = cdrlib:dec_char(Coded_dollar),
+ ok.
+
+%%-----------------------------------------------------------------
+%% Test Case: octet test
+%% Description:
+%%-----------------------------------------------------------------
+octet(doc) -> ["Description", "more description"];
+octet(suite) -> [];
+octet(_) ->
+ ?line [Coded_ff] = cdrlib:enc_octet(16#ff, []),
+ ?line {16#ff, <<>>} = cdrlib:dec_octet(Coded_ff),
+ ?line [Coded_00] = cdrlib:enc_octet(16#00, []),
+ ?line {16#00, <<>>} = cdrlib:dec_octet(Coded_00),
+ ?line [Coded_5a] = cdrlib:enc_octet(16#5a, []),
+ ?line {16#5a, <<>>} = cdrlib:dec_octet(Coded_5a),
+ ?line [Coded_48] = cdrlib:enc_octet(16#48, []),
+ ?line {16#48, <<>>} = cdrlib:dec_octet(Coded_48),
+ ok.
+
+
+
+%%-----------------------------------------------------------------
+%% Test Case: float test
+%% Description:
+%%-----------------------------------------------------------------
+float(doc) -> ["Description", "more description"];
+float(suite) -> [];
+float(_) ->
+ G = 16#7fffff / 16#800000 + 1.0,
+ H1 = math:pow(2, 127),
+ H2 = math:pow(2, -126),
+ float_big_loop([-H1 * G, -H1 * 1.0, -H2 * G, -H2 * 1.0,
+ -4040.313131, -3.141592, 0.0, 3.141592, 4040.313131,
+ H1 * G, H1 * 1.0, H2 * G, H2 * 1.0]),
+ float_little_loop([-H1 * G, -H1 * 1.0, -H2 * G, -H2 * 1.0,
+ -4040.313131, -3.141592, 0.0, 3.141592, 4040.313131,
+ H1 * G, H1 * 1.0, H2 * G, H2 * 1.0]),
+ ok.
+
+float_big_loop([]) ->
+ ok;
+float_big_loop([X |List]) ->
+ ?line [CodedType] = cdrlib:enc_float(X, []),
+ ?line {Y, <<>>} = cdrlib:dec_float(big, CodedType),
+ ?line float_comp(X,Y),
+ float_big_loop(List),
+ ok.
+
+float_little_loop([]) ->
+ ok;
+float_little_loop([X |List]) ->
+ ?line [CodedType] = enc_float_little(X, []),
+ ?line {Y, <<>>} = cdrlib:dec_float(little, CodedType),
+ ?line float_comp(X,Y),
+ float_little_loop(List),
+ ok.
+
+float_comp(X,Y) when X == 0.0, Y == 0.0 ->
+ ok;
+float_comp(X,Y) ->
+ Div = abs(Y) / abs(X),
+ %% io:format("~p~n", [float_to_list(Div)]),
+ ?line true = (Div < 1.0000001),
+ ?line true = (Div > 0.9999999),
+ ok.
+
+enc_float_little(X, Message) ->
+ [ <<X:32/little-float>> | Message].
+
+%%-----------------------------------------------------------------
+%% Test Case: double test
+%% Description:
+%%-----------------------------------------------------------------
+double(doc) -> ["Description", "more description"];
+double(suite) -> [];
+double(_) ->
+ F = 16#0fffffffffffff / 16#10000000000000 + 1.0,
+ E1 = math:pow(2, 1023),
+ E2 = math:pow(2, -1022),
+ G = 16#7fffff / 16#800000 + 1.0,
+ H1 = math:pow(2, 128),
+ H2 = math:pow(2, -127),
+ double_big_loop([-E1 * F, -E1 * 1.0, -E2 * F, -E2 * 1.0,
+ -H1 * G, -H1 * 1.0, -H2 * G, -H2 * 1.0,
+ -4040.313131, -3.141592, 0.0, 3.141592, 4040.313131,
+ H1 * G, H1 * 1.0, H2 * G, H2 * 1.0,
+ E1 * F, E1 * 1.0, E2 * F, E2 * 1.0]),
+ double_little_loop([-E1 * F, -E1 * 1.0, -E2 * F, -E2 * 1.0,
+ -H1 * G, -H1 * 1.0, -H2 * G, -H2 * 1.0,
+ -4040.313131, -3.141592, 0.0, 3.141592, 4040.313131,
+ H1 * G, H1 * 1.0, H2 * G, H2 * 1.0,
+ E1 * F, E1 * 1.0, E2 * F, E2 * 1.0]),
+ ok.
+
+double_big_loop([]) ->
+ ok;
+double_big_loop([X |List]) ->
+ ?line [CodedType] = cdrlib:enc_double(X, []),
+ ?line {Y, <<>>} = cdrlib:dec_double(big, CodedType),
+ ?line double_comp(X,Y),
+ double_big_loop(List),
+ ok.
+
+double_little_loop([]) ->
+ ok;
+double_little_loop([X |List]) ->
+ ?line [CodedType] = enc_double_little(X, []),
+ ?line {Y, <<>>} = cdrlib:dec_double(little, CodedType),
+ ?line double_comp(X,Y),
+ double_little_loop(List),
+ ok.
+
+enc_double_little(X, Message) ->
+ [ <<X:64/little-float>> | Message].
+
+double_comp(X,Y) when X == 0.0, Y == 0.0 ->
+ ok;
+double_comp(X,Y) ->
+ Div = abs(Y) / abs(X),
+ %% io:format("~p~n", [float_to_list(Div)]),
+ ?line true = (Div < 1.00000000000001),
+ ?line true = (Div > 0.99999999999999),
+ ok.
+
+double_should_be_ok(doc) -> ["Description", "more description"];
+double_should_be_ok(suite) -> [];
+double_should_be_ok(_) ->
+ F = 16#0fffffffffffff / 16#10000000000000 + 1.0,
+ E1 = math:pow(2, 1024), % erlang can't handle this.
+ E2 = math:pow(2, -1023),
+ double_big_loop([-E1 * F, -E1 * 1.0, -E2 * F, -E2 * 1.0,
+ E1 * F, E1 * 1.0, E2 * F, E2 * 1.0]),
+ double_little_loop([-E1 * F, -E1 * 1.0, -E2 * F, -E2 * 1.0,
+ E1 * F, E1 * 1.0, E2 * F, E2 * 1.0]),
+ ok.
+
+%%-----------------------------------------------------------------
+%% Test Case: enum test
+%% Description:
+%%-----------------------------------------------------------------
+enum(doc) -> ["Description", "more description"];
+enum(suite) -> [];
+enum(_) ->
+ enum_big(),
+ enum_little(),
+ ok.
+
+enum_big() ->
+ ?line [Coded_a] = cdrlib:enc_enum(a,[a,b,c],[]),
+ ?line {a, <<>>} = cdrlib:dec_enum(big, ["a","b","c"], Coded_a),
+ ?line [Coded_b] = cdrlib:enc_enum(b,[a,b,c],[]),
+ ?line {b, <<>>} = cdrlib:dec_enum(big, ["a","b","c"], Coded_b),
+ ?line [Coded_c] = cdrlib:enc_enum(c,[a,b,c],[]),
+ ?line {c, <<>>} = cdrlib:dec_enum(big, ["a","b","c"], Coded_c),
+ ok.
+
+enum_little() ->
+ ?line Coded_a = enc_r_enum(a,[a,b,c],[]),
+ ?line {a, <<>>} = cdrlib:dec_enum(little, ["a","b","c"], Coded_a),
+ ?line Coded_b = enc_r_enum(b,[a,b,c],[]),
+ ?line {b, <<>>} = cdrlib:dec_enum(little, ["a","b","c"], Coded_b),
+ ?line Coded_c = enc_r_enum(c,[a,b,c],[]),
+ ?line {c, <<>>} = cdrlib:dec_enum(little, ["a","b","c"], Coded_c),
+ ok.
+
+enc_r_enum(Enum, ElemList, Message) ->
+ Val = getEnumValue(ElemList,Enum, 0),
+ enc_r_unsigned_long(Val, Message).
+
+getEnumValue([Enum |_List], Enum, N) ->
+ N;
+getEnumValue([_ |List], Enum, N) ->
+ getEnumValue(List, Enum, N + 1).
+
+enc_r_unsigned_long(X, Message) ->
+ list_to_binary([(X) band 16#ff, ((X) bsr 8) band 16#ff,
+ ((X) bsr 16) band 16#ff, ((X) bsr 24) band 16#ff | Message]).
diff --git a/lib/orber/test/corba_SUITE.erl b/lib/orber/test/corba_SUITE.erl
new file mode 100644
index 0000000000..dae8fcbefc
--- /dev/null
+++ b/lib/orber/test/corba_SUITE.erl
@@ -0,0 +1,909 @@
+%%
+%% %CopyrightBegin%
+%%
+%% 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%
+%%
+%%
+%%-----------------------------------------------------------------
+%%
+%% Description:
+%% Test suite for corba/boa/object/orber API functions
+%%
+%%-----------------------------------------------------------------
+-module(corba_SUITE).
+
+-include("test_server.hrl").
+-include_lib("orber/include/corba.hrl").
+-include_lib("orber/COSS/CosNaming/CosNaming.hrl").
+-include_lib("orber/src/orber_iiop.hrl").
+
+
+-define(default_timeout, ?t:minutes(5)).
+
+-define(match(ExpectedRes,Expr),
+ fun() ->
+ AcTuAlReS = (catch (Expr)),
+ case AcTuAlReS of
+ ExpectedRes ->
+ io:format("------ CORRECT RESULT ------~n~p~n",
+ [AcTuAlReS]),
+ AcTuAlReS;
+ _ ->
+ io:format("###### ERROR ERROR ######~nRESULT: ~p~n",
+ [AcTuAlReS]),
+ exit(AcTuAlReS)
+ end
+ end()).
+
+%%-----------------------------------------------------------------
+%% External exports
+%%-----------------------------------------------------------------
+-export([all/1]).
+
+%%-----------------------------------------------------------------
+%% Internal exports
+%%-----------------------------------------------------------------
+-export([pseudo_calls/2, pseudo_casts/2]).
+-compile(export_all).
+
+%%-----------------------------------------------------------------
+%% Func: all/1
+%% Args:
+%% Returns:
+%%-----------------------------------------------------------------
+all(doc) -> ["API tests for the CORBA/BOA/Object/orber interfaces", ""];
+all(suite) -> {req,
+ [mnesia],
+ {conf, init_all, cases(), finish_all}}.
+
+cases() ->
+ [exception_info_api, corba_api, object_api, orber_api,
+ orber_objectkeys_api, orber_pseudo_objects, callback_ok_api,
+ callback_arity_api, callback_module_api, callback_function_api,
+ callback_precond_api, callback_postcond_api, callback_exit_api,
+ callback_badarith_api, callback_case_clause_api,
+ callback_function_clause_api].
+
+%% boa_api, request, locate_request, locate_reply].
+
+%%-----------------------------------------------------------------
+%% Init and cleanup functions.
+%%-----------------------------------------------------------------
+
+init_per_testcase(_Case, Config) ->
+ Path = code:which(?MODULE),
+ code:add_pathz(filename:join(filename:dirname(Path), "idl_output")),
+ ?line Dog=test_server:timetrap(?default_timeout),
+ [{watchdog, Dog}|Config].
+
+
+fin_per_testcase(_Case, Config) ->
+ Path = code:which(?MODULE),
+ code:del_path(filename:join(filename:dirname(Path), "idl_output")),
+ Dog = ?config(watchdog, Config),
+ test_server:timetrap_cancel(Dog),
+ ok.
+
+init_all(Config) ->
+ corba:orb_init([{orber_debug_level, 10}, {giop_version, {1,2}},
+ {iiop_port, 0}]),
+ mnesia:delete_schema([node()]),
+ mnesia:create_schema([node()]),
+ orber:install([node()]),
+ application:start(mnesia),
+ application:start(orber),
+ if
+ is_list(Config) ->
+ Config;
+ true ->
+ exit("Config not a list")
+ end.
+
+finish_all(Config) ->
+ application:stop(orber),
+ application:stop(mnesia),
+ mnesia:delete_schema([node()]),
+ Config.
+
+%%-----------------------------------------------------------------
+%% API tests for pseudo interface CORBA
+%%-----------------------------------------------------------------
+corba_api(doc) -> ["CORBA API tests", ""];
+corba_api(suite) -> [];
+corba_api(_) ->
+ NIL = corba:create_nil_objref(),
+ ?line ok = corba:dispose(NIL),
+ ?line NS = corba:resolve_initial_references("NameService"),
+ ?line List = corba:list_initial_services(),
+ ?line ["NameService"] = List,
+ ?line NSstring = corba:object_to_string(NS),
+ ?line NS1 = corba:string_to_object(NSstring),
+ ?line NSstring = corba:object_to_string(NS1),
+ ?line true = corba:add_initial_service("MyData", NS),
+ ?line NS = corba:resolve_initial_references("MyData"),
+ ?line [_,_] = corba:list_initial_services(),
+ ?line false = corba:remove_initial_service("Wrong"),
+ ?line NIL = corba:resolve_initial_references("Wrong"),
+ ?line NS = corba:string_to_object("corbaloc:rir:/MyData"),
+ ?line true = corba:remove_initial_service("MyData"),
+ ?line ["NameService"] = corba:list_initial_services(),
+
+ %% This is a collection of different stringified IOR:s (correct & incorrect)
+ %% which we use to test IOR encode/decode.
+ ?line IOR1 = ?match({'IOP_IOR',_,_}, corba:string_to_object("IOR:000303030000000d49444c3a746573743a312e3000030303000000040000000000000100000102010000000a3132372e302e302e31009d610000002dabacab3131303432343836383731005f526f6f74504f4100414c4c5f504f410000cafebabe3e2316570000000003030300000002000000210000007800010202000000010040020200000022000000080003030300000000004000400000000806066781020101010000001b0401000806066781020101010000000b40616469726f6e2e636f6d010400000000000000000000020000000806066781020101010000000b06092a864886f712010202010000000f000000010000002c00030303000100010000000400010020000101090001010005010001000101090000000200010100050100010000000000000184000102010000000a3132372e302e302e310000000000002dabacab3131303432343836383731005f526f6f74504f4100414c4c5f504f410000cafebabe3e231657000000000303030000000300000021000000ec000102020000000200060202000000240000001c0001006600060202000000010000000a3132372e302e302e31009d600000000000000000000000000400000000000000000000020000000806066781020101010000000b06092a864886f712010202010000000f00460202000000240000001c0001006600060202000000010000000a3132372e302e302e31009d62004000400000000806066781020101010000001b0401000806066781020101010000000b40616469726f6e2e636f6d010400000000000000000000020000000806066781020101010000000b06092a864886f712010202010000000f00000014000000080001006600069d5e000000010000002c000303030001000100000004000100200001010900010100050100010001010900000002000101000501000100000000000000dc000102010000000a3132372e302e302e31009d5f0000002dabacab3131303432343836383731005f526f6f74504f4100414c4c5f504f410000cafebabe3e23165700000000030303000000020000002100000054000102020000000100000202000000220000000800030303000000000000000000000000000000000400000000000000000000020000000806066781020101010000000b06092a864886f712010202010000000f000000010000002c00030303000100010000000400010020000101090001010005010001000101090000000200010100050100010000000000000080000102010000000a3132372e302e302e31009d5d0000002dabacab3131303432343836383731005f526f6f74504f4100414c4c5f504f410000cafebabe3e2316570000000003030300000001000000010000002c0003030300010001000000040001002000010109000101000501000100010109000000020001010005010001")),
+ ?line IOR2 = ?match({'IOP_IOR',_,_}, corba:string_to_object("IOR:000303030000000d49444c3a746573743a312e30000303030000000100000000000000e0000102010000000a3132372e302e302e31009d5f00000034abacab3131303432343836383731005f526f6f74504f410049494f505f43534976325f504f410000cafebabe3e23165700000000000000020000002100000054000102020000000100000202000000220000000800030303000000000000000000000000000000000400000000000000000000020000000806066781020101010000000b06092a864886f712010202010000000f000000010000002c0003030300010001000000040001002000010109000101000501000100010109000000020001010005010001")),
+ ?line IOR3 = ?match({'IOP_IOR',_,_}, corba:string_to_object("IOR:000303030000000d49444c3a746573743a312e3000030303000000010000000000000108000102010000000a3132372e302e302e31009d6100000037abacab3131303432343836383731005f526f6f74504f410049494f505f43534976325f55505f504f410000cafebabe3e231657000000000100000002000000210000007800010202000000010040020200000022000000080003030300000000004000400000000806066781020101010000001b0401000806066781020101010000000b40616469726f6e2e636f6d010400000000000000000000020000000806066781020101010000000b06092a864886f712010202010000000f000000010000002c0003030300010001000000040001002000010109000101000501000100010109000000020001010005010001")),
+ ?line IOR4 = ?match({'IOP_IOR',_,_}, corba:string_to_object("IOR:000303030000000d49444c3a746573743a312e3000030303000000010000000000000080000102010000000a3132372e302e302e31009d5d0000002eabacab3131303432343836383731005f526f6f74504f410049494f505f504f410000cafebabe3e23165700000000020200000001000000010000002c0003030300010001000000040001002000010109000101000501000100010109000000020001010005010001")),
+ ?line IOR5 = ?match({'IOP_IOR',_,_}, corba:string_to_object("IOR:000303030000000d49444c3a746573743a312e30000303030000000100000000000000fc000102010000000a3132372e302e302e3100000000000033abacab3131303432343836383731005f526f6f74504f4100544c535f43534976325f504f410000cafebabe3e231657000000000100000002000000210000007000010202000000010006020200000024000000220001006600060202000000010000000f3132382e3233302e3230382e353500019d6000000000020200000000000000000400000000000000000000020000000806066781020101010000000b06092a864886f712010202010000000f000000010000002c0003030300010001000000040001002000010109000101000501000100010109000000020001010005010001")),
+ ?line IOR6 = ?match({'IOP_IOR',_,_}, corba:string_to_object("IOR:000303030000000d49444c3a746573743a312e3000030303000000010000000000000124000102010000000a3132372e302e302e3100000000000036abacab3131303432343836383731005f526f6f74504f4100544c535f43534976325f55505f504f410000cafebabe3e23165700000000020200000002000000210000009400010202000000010046020200000024000000220001006600060202000000010000000f3132382e3233302e3230382e353500019d620040004002020000000806066781020101010000001b0401000806066781020101010000000b40616469726f6e2e636f6d010400000000000000000000020000000806066781020101010000000b06092a864886f712010202010000000f000000010000002c0003030300010001000000040001002000010109000101000501000100010109000000020001010005010001")),
+ ?line IOR7 = ?match({'IOP_IOR',_,_}, corba:string_to_object("IOR:000303030000000d49444c3a746573743a312e3000030303000000010000000000000090000102010000000a3132372e302e302e310000000000002dabacab3131303432343836383731005f526f6f74504f4100544c535f504f410000cafebabe3e231657000000000303030000000200000014000000080001006600069d5e000000010000002c0003030300010001000000040001002000010109000101000501000100010109000000020001010005010001")),
+ ?line IOR1 = corba:string_to_object(corba:object_to_string(IOR1)),
+ ?line IOR2 = corba:string_to_object(corba:object_to_string(IOR2)),
+ ?line IOR3 = corba:string_to_object(corba:object_to_string(IOR3)),
+ ?line IOR4 = corba:string_to_object(corba:object_to_string(IOR4)),
+ ?line IOR5 = corba:string_to_object(corba:object_to_string(IOR5)),
+ ?line IOR6 = corba:string_to_object(corba:object_to_string(IOR6)),
+ ?line IOR7 = corba:string_to_object(corba:object_to_string(IOR7)),
+ ?line ?match(ok, corba:print_object(IOR1)),
+ ?line ?match(ok, corba:print_object(IOR2)),
+ ?line ?match(ok, corba:print_object(IOR3)),
+ ?line ?match(ok, corba:print_object(IOR4)),
+ ?line ?match(ok, corba:print_object(IOR5)),
+ ?line ?match(ok, corba:print_object(IOR6)),
+ ?line ?match(ok, corba:print_object(IOR7)),
+ ?line ?match(ok, corba:print_object("IOR:000303030000000d49444c3a746573743a312e300003030300000002000000000000003000010001000000136d792e686f73742e65726c616e672e6f72670001801a02020000000c424f410a00000a0000070a010000000100000024000303030000000100000001000000140003030300010001000000000001010900000000")),
+ [IP] = ?match([_], orber:host()),
+ ?match(#'IOP_IOR'{profiles=[#'IOP_TaggedProfile'
+ {tag=?TAG_INTERNET_IOP,
+ profile_data=#'IIOP_ProfileBody_1_1'
+ {host = IP}}]},
+ corba:string_to_object(corba:object_to_string(NS))),
+ ?match(#'IOP_IOR'{profiles=[#'IOP_TaggedProfile'
+ {tag=?TAG_INTERNET_IOP,
+ profile_data=#'IIOP_ProfileBody_1_1'
+ {host = "127.0.0.1"}}]},
+ corba:string_to_object(corba:object_to_string(NS, ["127.0.0.1"]))),
+ ?match(#'IOP_IOR'{profiles=[#'IOP_TaggedProfile'
+ {tag=?TAG_INTERNET_IOP,
+ profile_data=#'IIOP_ProfileBody_1_1'
+ {host = "127.0.0.1", port = 5468}}]},
+ corba:string_to_object(corba:object_to_string(NS, ["127.0.0.1"],
+ 5468))),
+ ok.
+
+%%-----------------------------------------------------------------
+%% API tests for interface BOA
+%%-----------------------------------------------------------------
+boa_api(doc) -> ["BOA API tests", ""];
+boa_api(suite) -> [];
+boa_api(_) ->
+ ok.
+
+%%-----------------------------------------------------------------
+%% API tests for interface OBJECT
+%%-----------------------------------------------------------------
+object_api(doc) -> ["Object API tests", ""];
+object_api(suite) -> [];
+object_api(_) ->
+ ?line oe_orber_test_server:oe_register(),
+ ?line EC = orber_test_server:oe_create(),
+ ?line NS = corba:resolve_initial_references("NameService"),
+ %% testing corba_object:is_a(Obj, IFRID) locally.
+ ?line orber_test_lib:corba_object_tests(EC, NS),
+
+ ?line ?match(false, corba_object:non_existent(NS)),
+
+ ?line corba:dispose(EC),
+ ?line oe_orber_test_server:oe_unregister(),
+ ok.
+
+%%-----------------------------------------------------------------
+%% API tests for orbers main module
+%%-----------------------------------------------------------------
+orber_api(doc) -> ["orber API tests", ""];
+orber_api(suite) -> [];
+orber_api(_) ->
+ ?line ok = orber:uninstall(),
+ ?line orber:install([node()]),
+ ?line application:start(orber),
+ ?line NodeList = orber:orber_nodes(),
+ ?line NL = node(),
+ ?line [NL] = NodeList,
+ ok.
+
+%%-----------------------------------------------------------------
+%% API tests for exception mapping
+%%-----------------------------------------------------------------
+exception_info_api(doc) -> ["orber API tests", ""];
+exception_info_api(suite) -> [];
+exception_info_api(_) ->
+ ?line {ok, S1} = orber:exception_info({'EXCEPTION',{'MARSHAL',[],1163001858,'COMPLETED_NO'}}),
+ ?line {ok, S2} = orber:exception_info({'EXCEPTION',{'MARSHAL',[],1330446337,'COMPLETED_NO'}}),
+ ?line {ok, S3} = orber:exception_info({'EXCEPTION',{'MARSHAL',[],1398079490,'COMPLETED_NO'}}),
+ ?line {ok, S4} = orber:exception_info({'EXCEPTION',{'MARSHAL',[],1347813377,'COMPLETED_NO'}}),
+ ?line {ok, S5} = orber:exception_info({'EXCEPTION', {'CosNaming_NamingContext_InvalidName',"IDL:omg.org/CosNaming/NamingContext/InvalidName:1.0"}}),
+ ?line error_logger:info_msg("~s", [S1]),
+ ?line error_logger:info_msg("~s", [S2]),
+ ?line error_logger:info_msg("~s", [S3]),
+ ?line error_logger:info_msg("~s", [S4]),
+ ?line error_logger:info_msg("~s", [S5]),
+ ok.
+
+%%-----------------------------------------------------------------
+%% API tests for orbers pseudo objects.
+%%-----------------------------------------------------------------
+orber_pseudo_objects(doc) -> ["orber_pseudo_objects API tests", ""];
+orber_pseudo_objects(suite) -> [];
+orber_pseudo_objects(_) ->
+ ?line oe_orber_test_server:oe_register(),
+ Obj1=(catch orber_test_server:oe_create(state,[{pseudo,true},
+ {local_typecheck, true}])),
+ ?line ?match({_,pseudo,orber_test_server_impl, _,_, _}, Obj1),
+ Obj2=(catch orber_test_server:oe_create([],[{pseudo, truce}])),
+ ?line ?match({'EXCEPTION',{'BAD_PARAM',[],_,'COMPLETED_NO'}}, Obj2),
+ spawn(?MODULE, pseudo_calls, [20, Obj1]),
+ ?line ?match({ok, 10000}, orber_test_server:pseudo_call_delay(Obj1, 10000)),
+ spawn(?MODULE, pseudo_casts, [20, Obj1]),
+ ?line ?match(ok, orber_test_server:pseudo_cast_delay(Obj1, 10000)),
+
+ ?line ?match('object_here', corba:locate(Obj1)),
+
+ ?line NS = corba:resolve_initial_references("NameService"),
+
+ ?line orber_test_lib:corba_object_tests(Obj1, NS),
+
+ ?line ?match("IDL:omg.org/orber_test/server:1.0",orber_test_server:typeID()),
+
+ %% Test if exceptions are handled properly.
+ ?line ?match({'EXCEPTION',{'BAD_QOS',_,_,_}},
+ orber_test_server:pseudo_call_raise_exc(Obj1, 1)),
+ ?line ?match({'EXCEPTION',{'BAD_QOS',_,_,_}},
+ orber_test_server:pseudo_call_raise_exc(Obj1, 2)),
+
+ %% Test if exit is handled properly.
+ ?line ?match({'EXCEPTION',{'TRANSIENT',_,_,_}},
+ orber_test_server:stop_brutal(Obj1)),
+
+ orber_test_lib:test_coding(Obj1, true),
+
+ %% possible to use subobject key?
+ ?line ?match(state, binary_to_term(corba:get_subobject_key(Obj1))),
+
+ ?line ?match({'EXCEPTION',{'INV_OBJREF',[],_,'COMPLETED_NO'}},
+ corba:get_pid(Obj1)),
+ ?line ?match(false, corba_object:non_existent(Obj1)),
+
+ ?line ?match(ok, corba:dispose(Obj1)),
+
+ ?line ?match(false, corba_object:non_existent(Obj1)),
+
+ %% Try if it's possible to stringify and recover the object reference.
+ IOR_string = (catch corba:object_to_string(Obj1)),
+ Obj3 =(catch corba:string_to_object(IOR_string)),
+ ?line ?match(IOR_string, corba:object_to_string(Obj3)),
+
+ Obj4=(catch orber_test_server:oe_create(undefined,[{pseudo,true}])),
+ ?line ?match(ok, corba:dispose(Obj4)),
+ ?line oe_orber_test_server:oe_unregister(),
+ ok.
+
+%%-----------------------------------------------------------------
+%% API tests for orbers objectkeys server.
+%%-----------------------------------------------------------------
+orber_objectkeys_api(doc) -> ["orber_objectkeys API tests", ""];
+orber_objectkeys_api(suite) -> [];
+orber_objectkeys_api(_) ->
+ Obj0=(catch orber_test_server:oe_create([], [{sup_child, true}])),
+ Obj1=(catch orber_test_server:oe_create([], [{persistent, true},
+ {regname, {local,obj1}}])),
+ Obj2=(catch orber_test_server:oe_create([], [{persistent, true},
+ {regname, {global,{obj2, 12345}}}])),
+
+ %% Obj0 is supposed to be a child started by a supervisor (r6) which
+ %% handles not only {ok, Pid} but also {ok,Pid, Returnvalue}. In our
+ %% case the Returnvalue is an ObjectRef.
+ ?line ?match({ok,_,{_,key,_, _,_, _}}, Obj0),
+ {ok,_,Obj0Ref} = Obj0,
+ corba:dispose(Obj0Ref),
+
+ %% Only 'global' servers are at the moment allowed to be persistent.
+ ?line ?match({'EXCEPTION',{'BAD_PARAM',[],_,'COMPLETED_NO'}}, Obj1),
+
+ %% We created a persistent object successfully.
+ ?line ?match({_,key,_,_,_, _}, Obj2),
+
+ %% Get key and Pid
+ {_,_,Key,_,_, _} = Obj2,
+ PID=(catch orber_objectkeys:get_pid(Key)),
+
+ %% Use the two different ways to look up if the server is persistent.
+ ?line ?match(true, orber_objectkeys:is_persistent(Key)),
+ ?line ?match(true, orber_objectkeys:is_persistent(PID)),
+
+ %% Create servers using every possible way.
+ O1=(catch orber_test_server:oe_create()),
+ O2=(catch orber_test_server:oe_create_link()),
+ O3=(catch orber_test_server:oe_create([])),
+ O4=(catch orber_test_server:oe_create_link([])),
+ %% NOTE!!! Next four lines requires that we still support RegName instead of
+ %% only OptionList as the second argument to oe_create*/2. Remove these when that
+ %% is no longer the case.
+ O5=(catch orber_test_server:oe_create([], {'local', o5})),
+ O6=(catch orber_test_server:oe_create([], {'global', {o6, obj}})),
+ O7=(catch orber_test_server:oe_create_link([], {'local', o7})),
+ O8=(catch orber_test_server:oe_create_link([], {'global', {o8, obj}})),
+
+ %% Test if all the object references are correct.
+ ?line ?match({_,key,_,_,_, _}, O1),
+ ?line ?match({_,key,_,_,_, _}, O2),
+ ?line ?match({_,key,_,_,_, _}, O3),
+ ?line ?match({_,key,_,_,_, _}, O4),
+ ?line ?match({_, registered, o5, _,_, _}, O5),
+ ?line ?match({_,key,_,_,_, _}, O6),
+ ?line ?match({_, registered, o7, _,_, _}, O7),
+ ?line ?match({_,key,_,_,_, _}, O8),
+
+ %% Test if persistent.
+ {_,_,Key1,_,_, _} = O1,
+ PID1=(catch orber_objectkeys:get_pid(Key1)),
+ ?line ?match(false, orber_objectkeys:is_persistent(Key1)),
+ ?line ?match(false, orber_objectkeys:is_persistent(PID1)),
+
+ %% all the servers are alive(?!).
+ ?line ?match(false, corba_object:non_existent(O1)),
+ ?line ?match(false, corba_object:non_existent(O2)),
+ ?line ?match(false, corba_object:non_existent(O3)),
+ ?line ?match(false, corba_object:non_existent(O4)),
+ ?line ?match(false, corba_object:non_existent(O5)),
+ ?line ?match(false, corba_object:non_existent(O6)),
+ ?line ?match(false, corba_object:non_existent(O7)),
+ ?line ?match(false, corba_object:non_existent(O8)),
+ ?line ?match(false, corba_object:non_existent(Obj2)),
+
+ %% Does locate work?
+ ?line ?match('object_here', corba:locate(O1)),
+ ?line ?match('object_here', corba:locate(O2)),
+ ?line ?match('object_here', corba:locate(O3)),
+ ?line ?match('object_here', corba:locate(O4)),
+ ?line ?match('object_here', corba:locate(O5)),
+ ?line ?match('object_here', corba:locate(O6)),
+ ?line ?match('object_here', corba:locate(O7)),
+ ?line ?match('object_here', corba:locate(O8)),
+ ?line ?match('object_here', corba:locate(Obj2)),
+
+ %% Terminate all servers with reason 'normal'.
+ catch corba:dispose(O1),
+ catch corba:dispose(O2),
+ catch corba:dispose(O3),
+ catch corba:dispose(O4),
+ catch corba:dispose(O5),
+ catch corba:dispose(O6),
+ catch corba:dispose(O7),
+ catch corba:dispose(O8),
+ catch corba:dispose(Obj2),
+
+
+ %% To make sure that orber_objectkeys-server is able to
+ %% clean up we wait.
+ timer:sleep(2000),
+
+ %% all the servers are dead(?!). If one of these test-cases
+ %% fails the only error can be that we didn't sleep long enough, i.e.,
+ %% try a longer timeout. If still fails something is wrong.
+ ?line ?match(true, corba_object:non_existent(O1)),
+ ?line ?match(true, corba_object:non_existent(O2)),
+ ?line ?match(true, corba_object:non_existent(O3)),
+ ?line ?match(true, corba_object:non_existent(O4)),
+ ?line ?match(true, corba_object:non_existent(O5)),
+ ?line ?match(true, corba_object:non_existent(O6)),
+ ?line ?match(true, corba_object:non_existent(O7)),
+ ?line ?match(true, corba_object:non_existent(O8)),
+ ?line ?match(true, corba_object:non_existent(Obj2)),
+
+ %% Create a new persistent server.
+ Obj3=(catch orber_test_server:oe_create([],
+ [{persistent, true},
+ {regname, {global,{obj2, 12345}}}])),
+
+ %% OK?!
+ ?line ?match({_,key,_,_,_, _}, Obj3),
+
+ %% Try to create a server with the same name (naturally it fails).
+ ?line ?match({'EXCEPTION',{'INTERNAL',[],_,'COMPLETED_NO'}},
+ orber_test_server:oe_create([],
+ [{persistent, true},
+ {regname, {global,{obj2, 12345}}}])),
+ %% Try to remove all 'dead' servers. No server should be removed.
+ orber_objectkeys:gc(0),
+
+ %% Kill object brutal, i.e., not with reason 'normal' or 'shutdown'.
+ P3 = corba:get_pid(Obj3),
+ exit(P3, kill),
+
+ {_,_,Key3,_,_, _} = Obj3,
+
+ %% Give time to clean up.
+ timer:sleep(2000),
+ ?line ?match({'EXCEPTION',{'TRANSIENT',[],_,'COMPLETED_NO'}},
+ gen_server:call(orber_objkeyserver,
+ {get_pid, Key3},
+ infinity)),
+
+ ?line ?match(false,corba_object:non_existent(Obj3)),
+
+ %% Run gc wit a "huge" time-limit. Will not erase the dead object.
+ orber_objectkeys:gc(10000),
+ ?line ?match(false,corba_object:non_existent(Obj3)),
+
+ %% Run gc with minimum time-limit. Will erase the dead object.
+ orber_objectkeys:gc(0),
+ ?line ?match(true,corba_object:non_existent(Obj3)),
+
+ %% Create a new persistent server.
+ Obj4=(catch orber_test_server:oe_create([],
+ [{persistent, true},
+ {regname, {global,{obj2, 12345}}}])),
+
+ %% OK?!
+ ?match({_,key,_,_,_, _}, Obj4),
+ %% Kill object brutal, i.e., not with reason 'normal' or 'shutdown'.
+ P4 = corba:get_pid(Obj4),
+ exit(P4, kill),
+
+ %% Give time to clean up.
+ timer:sleep(2000),
+% ?line ?match({'EXCEPTION',{'COMM_FAILURE',[],0,'COMPLETED_NO'}},
+ ?line ?match({error, _},
+ corba:get_pid(Obj4)),
+
+ ?line ?match(false,corba_object:non_existent(Obj4)),
+
+ %% Restart the object.
+ Obj5=(catch orber_test_server:oe_create([],
+ [{persistent, true},
+ {regname, {global,{obj2, 12345}}}])),
+ %% OK?!
+ ?line ?match({_,key,_,_,_, _}, Obj5),
+
+ %% Run gc with minimum time-limit.
+ orber_objectkeys:gc(0),
+ ?line ?match(false,corba_object:non_existent(Obj5)),
+ corba:dispose(Obj5),
+ ok.
+
+
+%%-----------------------------------------------------------------
+%% API tests for callback functions
+%%-----------------------------------------------------------------
+-define(DO_EXIT_FLAG, 0).
+-define(NO_EXIT_FLAG, 16#10).
+
+-define(DO_EXIT, {is, 0}).
+-define(NO_EXIT, {is, 16#10}).
+
+
+
+callback_ok_api(doc) -> ["Successful callbak API tests", ""];
+callback_ok_api(suite) -> [];
+callback_ok_api(_) ->
+ %% Init
+ ?line ?match({ok, {?DO_EXIT, state}}, corba:handle_init(?MODULE, {?DO_EXIT_FLAG, state})),
+ %% Terminate
+ ?line ?match(ok, corba:handle_terminate(?MODULE, "reason", {?DO_EXIT, state})),
+ %% Handle_call
+ ?line ?match({reply,ok,{?DO_EXIT,state}},
+ corba:handle_call(?MODULE, foo, [],
+ {?DO_EXIT, state}, [], false, false)),
+ %% Handle_cast
+ ?line ?match({noreply, {?DO_EXIT,state}},
+ corba:handle_cast(?MODULE, foo_1w, [],
+ {?DO_EXIT, state}, [], false)),
+ %% Handle_call precond/postcond
+ ?line ?match({reply, ok, {?DO_EXIT, state}},
+ corba:handle_call(?MODULE, foo, [],
+ {?DO_EXIT, state}, [], false, false, {?MODULE, precond},
+ {?MODULE, postcond}, ?MODULE)),
+ %% Handle_cast precond/postcond
+ ?line ?match({noreply, {?DO_EXIT, state}},
+ corba:handle_cast(?MODULE, foo_1w, [],
+ {?DO_EXIT, state}, [], false, {?MODULE, precond},
+ {?MODULE, postcond}, ?MODULE)),
+ %% Handle_info
+ ?line ?match({noreply, {?DO_EXIT, state}},
+ corba:handle_info(?MODULE, "info", {?DO_EXIT, state})),
+ ok.
+
+callback_arity_api(doc) -> ["callbak arity API tests", ""];
+callback_arity_api(suite) -> [];
+callback_arity_api(_) ->
+ %% Handle_call - stay-alive == false
+ ?line ?match({'EXIT', {undef,_}},
+ corba:handle_call(?MODULE, foo, [to, many, arguments],
+ {?DO_EXIT, state}, [], false, false)),
+ %% Handle_call - stay-alive == true
+ ?line ?match({reply, {'EXCEPTION', #'OBJ_ADAPTER'{}}, _},
+ corba:handle_call(?MODULE, foo, [to, many, arguments],
+ {?NO_EXIT, state}, [], false, false)),
+ %% Handle_call - stay-alive == false
+ ?line ?match({'EXIT', _},
+ corba:handle_call(?MODULE, foo, [],
+ {?DO_EXIT, arity}, [], false, false)),
+ %% Handle_call - stay-alive == true
+ ?line ?match({reply, {'EXCEPTION', #'OBJ_ADAPTER'{}}, _},
+ corba:handle_call(?MODULE, foo, [],
+ {?NO_EXIT, arity}, [], false, false)),
+ %% Handle_cast - stay-alive == false
+ ?line ?match({'EXIT', {undef,_}},
+ corba:handle_cast(?MODULE, foo_1w, [to, many, arguments],
+ {?DO_EXIT, state}, [], false)),
+ %% Handle_cast - stay-alive == true
+ ?line ?match({noreply, {?NO_EXIT, state}},
+ corba:handle_cast(?MODULE, foo_1w, [to, many, arguments],
+ {?NO_EXIT, state}, [], false)),
+ %% Handle_cast - stay-alive == false
+ ?line ?match({'EXIT', _},
+ corba:handle_cast(?MODULE, foo_1w, [],
+ {?DO_EXIT, arity}, [], false)),
+ %% Handle_cast - stay-alive == true
+ ?line ?match({noreply, {?NO_EXIT, arity}},
+ corba:handle_cast(?MODULE, foo_1w, [],
+ {?NO_EXIT, arity}, [], false)),
+ %% Handle_info - stay-alive == false
+ ?line ?match({'EXIT', _},
+ corba:handle_info(?MODULE, "info", {?DO_EXIT, arity})),
+
+ %% Handle_info - stay-alive == true
+ ?line ?match({noreply, {?NO_EXIT, arity}},
+ corba:handle_info(?MODULE, "info", {?NO_EXIT, arity})),
+ ok.
+
+callback_module_api(doc) -> ["Module callbak API tests", ""];
+callback_module_api(suite) -> [];
+callback_module_api(_) ->
+ %% Handle_call - stay-alive == false
+ ?line ?match({'EXIT', {undef,_}},
+ corba:handle_call(wrong_mod, foo, [],
+ {?DO_EXIT, state}, [], false, false)),
+ %% Handle_call - stay-alive == true
+ ?line ?match({reply, {'EXCEPTION', #'OBJ_ADAPTER'{}}, _},
+ corba:handle_call(wrong_mod, foo, [],
+ {?NO_EXIT, state}, [], false, false)),
+ %% Handle_cast - stay-alive == false
+ ?line ?match({'EXIT', {undef,_}},
+ corba:handle_cast(wrong_mod, foo_1w, [],
+ {?DO_EXIT, state}, [], false)),
+ %% Handle_cast - stay-alive == true
+ ?line ?match({noreply, {?NO_EXIT, state}},
+ corba:handle_cast(wrong_mod, foo_1w, [],
+ {?NO_EXIT, state}, [], false)),
+ %% Handle_info - stay-alive == false.
+ ?line ?match({'EXIT', _},
+ corba:handle_info(wrong_mod, "info", {?DO_EXIT, state})),
+
+ %% Handle_info - stay-alive == true.
+ ?line ?match({noreply, {?NO_EXIT, state}},
+ corba:handle_info(wrong_mod, "info", {?NO_EXIT, state})),
+ ok.
+
+callback_function_api(doc) -> ["Function callbak API tests", ""];
+callback_function_api(suite) -> [];
+callback_function_api(_) ->
+ %% Handle_call - stay-alive == false
+ ?line ?match({'EXIT', {undef,_}},
+ corba:handle_call(?MODULE, bad_function, [],
+ {?DO_EXIT, state}, [], false, false)),
+ %% Handle_call - stay-alive == true
+ ?line ?match({reply, {'EXCEPTION', #'OBJ_ADAPTER'{}}, _},
+ corba:handle_call(?MODULE, bad_function, [],
+ {?NO_EXIT, state}, [], false, false)),
+ %% Handle_cast - stay-alive == false
+ ?line ?match({'EXIT', {undef,_}},
+ corba:handle_cast(?MODULE, bad_function, [],
+ {?DO_EXIT, state}, [], false)),
+ %% Handle_cast - stay-alive == true
+ ?line ?match({noreply, {?NO_EXIT, state}},
+ corba:handle_cast(?MODULE, bad_function, [],
+ {?NO_EXIT, state}, [], false)),
+ %% Handle_info - stay-alive == false. Note, we cannot use ?MODULE here.
+ ?line ?match({'EXIT', _},
+ corba:handle_info(corba, "info", {?DO_EXIT, state})),
+
+ %% Handle_info - stay-alive == true. Note, we cannot use ?MODULE here.
+ ?line ?match({noreply, {?NO_EXIT, state}},
+ corba:handle_info(corba, "info", {?NO_EXIT, state})),
+ ok.
+
+callback_precond_api(doc) -> ["Precond callbak API tests", ""];
+callback_precond_api(suite) -> [];
+callback_precond_api(_) ->
+ %% Handle_call - stay-alive == false
+ ?line ?match({'EXIT', _},
+ corba:handle_call(?MODULE, foo, [],
+ {?DO_EXIT, state}, [], false, false, {wrong_mod, precond},
+ {?MODULE, postcond}, ?MODULE)),
+ %% Handle_call - stay-alive == false
+ ?line ?match({'EXIT', _},
+ corba:handle_call(?MODULE, foo, [],
+ {?DO_EXIT, state}, [], false, false, {?MODULE, bad_precond},
+ {?MODULE, postcond}, ?MODULE)),
+ %% Handle_call - stay-alive == true
+ ?line ?match({reply, {'EXCEPTION', #'OBJ_ADAPTER'{}},_},
+ corba:handle_call(?MODULE, foo, [],
+ {?NO_EXIT, state}, [], false, false, {wrong_mod, precond},
+ {?MODULE, postcond}, ?MODULE)),
+ %% Handle_call - stay-alive == true
+ ?line ?match({reply, {'EXCEPTION', #'OBJ_ADAPTER'{}},_},
+ corba:handle_call(?MODULE, foo, [],
+ {?NO_EXIT, state}, [], false, false, {?MODULE, bad_precond},
+ {?MODULE, postcond}, ?MODULE)),
+ %% Handle_cast - stay-alive == false
+ ?line ?match({'EXIT', _},
+ corba:handle_cast(?MODULE, foo_1w, [],
+ {?DO_EXIT, state}, [], false, {wrong_mod, precond},
+ {?MODULE, postcond}, ?MODULE)),
+ %% Handle_cast - stay-alive == false
+ ?line ?match({'EXIT', _},
+ corba:handle_cast(?MODULE, foo_1w, [],
+ {?DO_EXIT, state}, [], false, {?MODULE, bad_precond},
+ {?MODULE, postcond}, ?MODULE)),
+ %% Handle_cast - stay-alive == true
+ ?line ?match({noreply, {?NO_EXIT, state}},
+ corba:handle_cast(?MODULE, foo_1w, [],
+ {?NO_EXIT, state}, [], false, {wrong_mod, precond},
+ {?MODULE, postcond}, ?MODULE)),
+ %% Handle_cast - stay-alive == true
+ ?line ?match({noreply, {?NO_EXIT, state}},
+ corba:handle_cast(?MODULE, foo_1w, [],
+ {?NO_EXIT, state}, [], false, {?MODULE, bad_precond},
+ {?MODULE, postcond}, ?MODULE)),
+ ok.
+
+
+callback_postcond_api(doc) -> ["Postcond callbak API tests", ""];
+callback_postcond_api(suite) -> [];
+callback_postcond_api(_) ->
+ %% Handle_call - stay-alive == false
+ ?line ?match({'EXIT', _},
+ corba:handle_call(?MODULE, foo, [],
+ {?DO_EXIT, state}, [], false, false, {?MODULE, precond},
+ {wrong_mod, postcond}, ?MODULE)),
+ %% Handle_call - stay-alive == false
+ ?line ?match({'EXIT', _},
+ corba:handle_call(?MODULE, foo, [],
+ {?DO_EXIT, state}, [], false, false, {?MODULE, precond},
+ {?MODULE, bad_postcond}, ?MODULE)),
+ %% Handle_call - stay-alive == true
+ ?line ?match({reply, {'EXCEPTION', #'OBJ_ADAPTER'{}},_},
+ corba:handle_call(?MODULE, foo, [],
+ {?NO_EXIT, state}, [], false, false, {?MODULE, precond},
+ {wrong_mod, postcond}, ?MODULE)),
+ %% Handle_call - stay-alive == true
+ ?line ?match({reply, {'EXCEPTION', #'OBJ_ADAPTER'{}},_},
+ corba:handle_call(?MODULE, foo, [],
+ {?NO_EXIT, state}, [], false, false, {?MODULE, precond},
+ {?MODULE, bad_postcond}, ?MODULE)),
+ %% Handle_cast - stay-alive == false
+ ?line ?match({'EXIT', _},
+ corba:handle_cast(?MODULE, foo_1w, [],
+ {?DO_EXIT, state}, [], false, {?MODULE, precond},
+ {wrong_mod, postcond}, ?MODULE)),
+ %% Handle_cast - stay-alive == false
+ ?line ?match({'EXIT', _},
+ corba:handle_cast(?MODULE, foo_1w, [],
+ {?DO_EXIT, state}, [], false, {?MODULE, precond},
+ {?MODULE, bad_postcond}, ?MODULE)),
+ %% Handle_cast - stay-alive == true
+ ?line ?match({noreply, {?NO_EXIT, state}},
+ corba:handle_cast(?MODULE, foo_1w, [],
+ {?NO_EXIT, state}, [], false, {?MODULE, precond},
+ {wrong_mod, postcond}, ?MODULE)),
+ %% Handle_cast - stay-alive == true
+ ?line ?match({noreply, {?NO_EXIT, state}},
+ corba:handle_cast(?MODULE, foo_1w, [],
+ {?NO_EXIT, state}, [], false, {?MODULE, precond},
+ {?MODULE, bad_postcond}, ?MODULE)),
+ ok.
+
+
+callback_exit_api(doc) -> ["Callbak exit API tests", ""];
+callback_exit_api(suite) -> [];
+callback_exit_api(_) ->
+ %% Handle_call - stay-alive == false
+ ?line ?match({'EXIT', _},
+ corba:handle_call(?MODULE, foo, [],
+ {?DO_EXIT, exit}, [], false, false)),
+ %% Handle_call - stay-alive == true
+ ?line ?match({reply, {'EXCEPTION', #'OBJ_ADAPTER'{}}, _},
+ corba:handle_call(?MODULE, foo, [],
+ {?NO_EXIT, exit}, [], false, false)),
+ %% Handle_cast - stay-alive == false
+ ?line ?match({'EXIT', _},
+ corba:handle_cast(?MODULE, foo_1w, [],
+ {?DO_EXIT, exit}, [], false)),
+ %% Handle_cast - stay-alive == true
+ ?line ?match({noreply, {?NO_EXIT, exit}},
+ corba:handle_cast(?MODULE, foo_1w, [],
+ {?NO_EXIT, exit}, [], false)),
+ %% Handle_info - stay-alive == false
+ ?line ?match({'EXIT', _},
+ corba:handle_info(?MODULE, "info", {?DO_EXIT, exit})),
+
+ %% Handle_info - stay-alive == true
+ ?line ?match({noreply, {?NO_EXIT, exit}},
+ corba:handle_info(?MODULE, "info", {?NO_EXIT, exit})),
+ ok.
+
+
+callback_badarith_api(doc) -> ["callbak badarith API tests", ""];
+callback_badarith_api(suite) -> [];
+callback_badarith_api(_) ->
+ %% Handle_call - stay-alive == false
+ ?line ?match({'EXIT', _},
+ corba:handle_call(?MODULE, foo, [],
+ {?DO_EXIT, badarith}, [], false, false)),
+ %% Handle_call - stay-alive == true
+ ?line ?match({reply, {'EXCEPTION', #'OBJ_ADAPTER'{}},_},
+ corba:handle_call(?MODULE, foo, [],
+ {?NO_EXIT, badarith}, [], false, false)),
+ %% Handle_cast - stay-alive == false
+ ?line ?match({'EXIT', _},
+ corba:handle_cast(?MODULE, foo_1w, [],
+ {?DO_EXIT, badarith}, [], false)),
+ %% Handle_cast - stay-alive == true
+ ?line ?match({noreply, {?NO_EXIT, badarith}},
+ corba:handle_cast(?MODULE, foo_1w, [],
+ {?NO_EXIT, badarith}, [], false)),
+ %% Handle_info - stay-alive == false
+ ?line ?match({'EXIT', _},
+ corba:handle_info(?MODULE, "info", {?DO_EXIT, badarith})),
+
+ %% Handle_info - stay-alive == true
+ ?line ?match({noreply, {?NO_EXIT, badarith}},
+ corba:handle_info(?MODULE, "info", {?NO_EXIT, badarith})),
+ ok.
+
+callback_case_clause_api(doc) -> ["callbak case_clause API tests", ""];
+callback_case_clause_api(suite) -> [];
+callback_case_clause_api(_) ->
+ %% Handle_call - stay-alive == false
+ ?line ?match({'EXIT', _},
+ corba:handle_call(?MODULE, foo, [],
+ {?DO_EXIT, case_clause}, [], false, false)),
+ %% Handle_call - stay-alive == true
+ ?line ?match({reply, {'EXCEPTION', #'OBJ_ADAPTER'{}}, _},
+ corba:handle_call(?MODULE, foo, [],
+ {?NO_EXIT, case_clause}, [], false, false)),
+ %% Handle_cast - stay-alive == false
+ ?line ?match({'EXIT', _},
+ corba:handle_cast(?MODULE, foo_1w, [],
+ {?DO_EXIT, case_clause}, [], false)),
+ %% Handle_cast - stay-alive == true
+ ?line ?match({noreply, {?NO_EXIT, case_clause}},
+ corba:handle_cast(?MODULE, foo_1w, [],
+ {?NO_EXIT, case_clause}, [], false)),
+ %% Handle_info - stay-alive == false
+ ?line ?match({'EXIT', _},
+ corba:handle_info(?MODULE, "info", {?DO_EXIT, case_clause})),
+
+ %% Handle_info - stay-alive == true
+ ?line ?match({noreply, {?NO_EXIT, case_clause}},
+ corba:handle_info(?MODULE, "info", {?NO_EXIT, case_clause})),
+ ok.
+
+callback_function_clause_api(doc) -> ["callbak function_clause API tests", ""];
+callback_function_clause_api(suite) -> [];
+callback_function_clause_api(_) ->
+ %% Handle_call - stay-alive == false
+ ?line ?match({'EXIT', _},
+ corba:handle_call(?MODULE, foo, [],
+ {?DO_EXIT, function_clause}, [], false, false)),
+ %% Handle_call - stay-alive == true
+ ?line ?match({reply, {'EXCEPTION', #'OBJ_ADAPTER'{}}, _},
+ corba:handle_call(?MODULE, foo, [],
+ {?NO_EXIT, function_clause}, [], false, false)),
+ %% Handle_cast - stay-alive == false
+ ?line ?match({'EXIT', _},
+ corba:handle_cast(?MODULE, foo_1w, [],
+ {?DO_EXIT, function_clause}, [], false)),
+ %% Handle_cast - stay-alive == true
+ ?line ?match({noreply, {?NO_EXIT, function_clause}},
+ corba:handle_cast(?MODULE, foo_1w, [],
+ {?NO_EXIT, function_clause}, [], false)),
+ %% Handle_info - stay-alive == false
+ ?line ?match({'EXIT', _},
+ corba:handle_info(?MODULE, "info", {?DO_EXIT, function_clause})),
+ %% Handle_info - stay-alive == true
+ ?line ?match({noreply, {?NO_EXIT, function_clause}},
+ corba:handle_info(?MODULE, "info", {?NO_EXIT, function_clause})),
+ ok.
+
+%% Faked mandatory operations
+init(State) ->
+ evaluate_state(State),
+ {ok, State}.
+terminate(_Reason, State) ->
+ evaluate_state(State),
+ ok.
+
+code_change(_OldVsn, State, _Extra) ->
+ evaluate_state(State),
+ {ok, State}.
+handle_call(_,_, State) ->
+ evaluate_state(State),
+ {noreply, State}.
+handle_cast(_, State) ->
+ evaluate_state(State),
+ {noreply, State}.
+handle_info(_Info, State) ->
+ evaluate_state(State),
+ {noreply, State}.
+
+foo(State) ->
+ evaluate_state(State),
+ {reply, ok, State}.
+foo(State, _Arg) ->
+ evaluate_state(State),
+ {reply, ok, State}.
+
+foo_1w(State) ->
+ evaluate_state(State),
+ {noreply, State}.
+foo_1w(State, _Arg) ->
+ evaluate_state(State),
+ {noreply, State}.
+
+precond(_Module, _Function, _Args) ->
+ ok.
+
+postcond(_Module, _Function, _Args, _Result) ->
+ ok.
+
+evaluate_state(exit) ->
+ exit("exit on purpose");
+evaluate_state(badarith) ->
+ 10 * atom;
+evaluate_state(case_clause) ->
+ case 10 of
+ false ->
+ ok
+ end;
+evaluate_state(module) ->
+ non_existing_module:bar();
+evaluate_state(function) ->
+ ?MODULE:non_existing_function();
+evaluate_state(arity) ->
+ ?MODULE:foo(to, many, arguments);
+evaluate_state(function_clause) ->
+ evaluate_state(incorrect_state);
+evaluate_state(state) ->
+ ok.
+
+%%-----------------------------------------------------------------
+%% Local functions.
+%%-----------------------------------------------------------------
+
+pseudo_calls(0, _) ->
+ ok;
+pseudo_calls(Times, Obj) ->
+ orber_test_server:pseudo_call(Obj),
+ New = Times - 1,
+ pseudo_calls(New, Obj).
+pseudo_casts(0, _) ->
+ ok;
+pseudo_casts(Times, Obj) ->
+ orber_test_server:pseudo_cast(Obj),
+ New = Times - 1,
+ pseudo_casts(New, Obj).
diff --git a/lib/orber/test/csiv2_SUITE.erl b/lib/orber/test/csiv2_SUITE.erl
new file mode 100644
index 0000000000..8103fd81ac
--- /dev/null
+++ b/lib/orber/test/csiv2_SUITE.erl
@@ -0,0 +1,940 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 2005-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(csiv2_SUITE).
+
+-include("test_server.hrl").
+-include_lib("orber/include/corba.hrl").
+-include_lib("orber/COSS/CosNaming/CosNaming.hrl").
+-include_lib("orber/src/orber_iiop.hrl").
+-include_lib("orber/src/ifr_objects.hrl").
+-include("idl_output/orber_test_server.hrl").
+-include_lib("orber/COSS/CosNaming/CosNaming_NamingContextExt.hrl").
+-include_lib("orber/COSS/CosNaming/CosNaming_NamingContext.hrl").
+%%-include_lib("orber/src/OrberCSIv2.hrl").
+
+-define(default_timeout, ?t:minutes(5)).
+
+-define(match(ExpectedRes,Expr),
+ fun() ->
+ AcTuAlReS = (catch (Expr)),
+ case AcTuAlReS of
+ ExpectedRes ->
+ io:format("------ CORRECT RESULT ------~n~p~n",
+ [AcTuAlReS]),
+ AcTuAlReS;
+ _ ->
+ io:format("###### ERROR ERROR ######~nRESULT: ~p~n",
+ [AcTuAlReS]),
+ ?line exit(AcTuAlReS)
+ end
+ end()).
+
+-define(REQUEST_ID, 0).
+
+-define(REPLY_FRAG_1, <<71,73,79,80,1,2,2,1,0,0,0,41,0,0,0,?REQUEST_ID,0,0,0,0,0,0,0,1,78,69,79,0,0,0,0,2,0,10,0,0,0,0,0,0,0,0,0,18,0,0,0,0,0,0,0,4,49>>).
+%% The fragments are identical for requests and replies.
+-define(FRAG_2, <<71,73,79,80,1,2,2,7,0,0,0,5,0,0,0,?REQUEST_ID,50>>).
+-define(FRAG_3, <<71,73,79,80,1,2,2,7,0,0,0,5,0,0,0,?REQUEST_ID,51>>).
+-define(FRAG_4, <<71,73,79,80,1,2,0,7,0,0,0,5,0,0,0,?REQUEST_ID,0>>).
+
+%% Should X509 DER generated by, for example, OpenSSL
+-define(X509DER,
+ <<42>>).
+
+%% Should X509 PEM generated by, for example, OpenSSL
+-define(X509PEM,
+ <<42>>).
+
+%% IOR exported by VB (CSIv2 activated).
+-define(VB_IOR,
+ #'IOP_IOR'
+ {type_id = "IDL:omg.org/CosNotifyComm/SequencePushConsumer:1.0",
+ profiles =
+ [#'IOP_TaggedProfile'
+ {tag = ?TAG_INTERNET_IOP,
+ profile_data =
+ #'IIOP_ProfileBody_1_1'{
+ iiop_version = #'IIOP_Version'{major = 1,
+ minor = 2},
+ host = "127.0.0.1",
+ port = 0,
+ object_key = [0,86,66,1,0,0,0,24,47,70,77,65,95,67,73,82,80,77,65,78,95,80,79,65,95,83,69,67,85,82,69,0,0,0,0,4,0,0,4,186,0,0,2,10,81,218,65,185],
+ components =
+ [#'IOP_TaggedComponent'{tag = ?TAG_SSL_SEC_TRANS,
+ component_data = #'SSLIOP_SSL'{
+ target_supports = 102,
+ target_requires = 66,
+ port = 49934}},
+ #'IOP_TaggedComponent'{tag = ?TAG_CSI_SEC_MECH_LIST,
+ component_data =
+ #'CSIIOP_CompoundSecMechList'{stateful = true,
+ mechanism_list =
+ [#'CSIIOP_CompoundSecMech'
+ {target_requires = 66,
+ transport_mech = #'IOP_TaggedComponent'{
+ tag = ?TAG_TLS_SEC_TRANS,
+ component_data =
+ #'CSIIOP_TLS_SEC_TRANS'{
+ target_supports = 102,
+ target_requires = 66,
+ addresses =
+ [#'CSIIOP_TransportAddress'
+ {host_name = "127.0.0.1",
+ port = 49934}]}},
+ as_context_mech =
+ #'CSIIOP_AS_ContextSec'{
+ target_supports = 0,
+ target_requires = 0,
+ client_authentication_mech = [],
+ target_name = []},
+ sas_context_mech =
+ #'CSIIOP_SAS_ContextSec'{
+ target_supports = 1024,
+ target_requires = 0,
+ privilege_authorities =
+ [#'CSIIOP_ServiceConfiguration'
+ {syntax = 1447174401,
+ name = "Borland"}],
+ supported_naming_mechanisms = [[6,
+ 6,
+ 103,
+ 129,
+ 2,
+ 1,
+ 1,
+ 1]],
+ supported_identity_types = 15}}]}},
+ #'IOP_TaggedComponent'
+ {tag = ?TAG_CODE_SETS,
+ component_data =
+ #'CONV_FRAME_CodeSetComponentInfo'{'ForCharData' =
+ #'CONV_FRAME_CodeSetComponent'{
+ native_code_set = 65537,
+ conversion_code_sets = [83951617]},
+ 'ForWcharData' =
+ #'CONV_FRAME_CodeSetComponent'{
+ native_code_set = 65801,
+ conversion_code_sets = []}}},
+ #'IOP_TaggedComponent'{tag = ?TAG_ORB_TYPE,
+ component_data = 1447645952},
+ #'IOP_TaggedComponent'{tag = 1447645955,
+ component_data = [0,5,7,1,127]}]}}]}).
+
+%% Common basic types
+-define(OID, {2,23,130,1,1,1}).
+
+-define(OCTET_STR, [1,2,3,4]).
+
+-define(BIT_STR, [0,1,0,1,1]).
+
+-define(BOOLEAN, false).
+
+-define(ANY, [19,5,111,116,112,67,65]).
+
+-ifdef(false).
+%% PKIX1Explicit88
+-define(AlgorithmIdentifier,
+ #'AlgorithmIdentifier'{algorithm = ?OID,
+ parameters = ?ANY}).
+
+-define(Validity, #'Validity'{notBefore = {utcTime, "19820102070533.8"},
+ notAfter = {generalTime, "19820102070533.8"}}).
+
+-define(SubjectPublicKeyInfo,
+ #'SubjectPublicKeyInfo'{algorithm = ?AlgorithmIdentifier,
+ subjectPublicKey = ?BIT_STR}).
+
+-define(AttributeTypeAndValue,
+ #'AttributeTypeAndValue'{type = ?OID,
+ value = <<19,11,69,114,105,99,115,115,111,110,32,65,66>>}).
+
+-define(RelativeDistinguishedName, [?AttributeTypeAndValue]).
+
+-define(RDNSequence, [?RelativeDistinguishedName]).
+
+-define(Name, {rdnSequence, ?RDNSequence}).
+
+-define(Version, v3).
+
+-define(CertificateSerialNumber, 1).
+
+-define(UniqueIdentifier, ?BIT_STR).
+
+-define(Extension, #'Extension'{extnID = ?OID,
+ critical = ?BOOLEAN,
+ extnValue = ?OCTET_STR}).
+
+-define(Extensions, [?Extension]).
+
+-define(TBSCertificate,
+ #'TBSCertificate'{version = ?Version,
+ serialNumber = ?CertificateSerialNumber,
+ signature = ?AlgorithmIdentifier,
+ issuer = ?Name,
+ validity = ?Validity,
+ subject = ?Name,
+ subjectPublicKeyInfo = ?SubjectPublicKeyInfo,
+ issuerUniqueID = ?UniqueIdentifier,
+ subjectUniqueID = ?UniqueIdentifier,
+ extensions = ?Extensions}).
+
+-define(Certificate, #'Certificate'{tbsCertificate = ?TBSCertificate,
+ signatureAlgorithm = ?AlgorithmIdentifier,
+ signature = ?BIT_STR}).
+
+%% PKIX1Implicit88
+
+-define(GeneralName, {registeredID, ?OID}).
+
+-define(GeneralNames, [?GeneralName]).
+
+%% PKIXAttributeCertificate
+-define(AttCertValidityPeriod,
+ #'AttCertValidityPeriod'{notBeforeTime = "19820102070533.8",
+ notAfterTime = "19820102070533.8"}).
+
+
+-define(Attribute, #'Attribute'{type = ?OID,
+ values = []}).
+
+-define(Attributes, [?Attribute]).
+
+-define(IssuerSerial, #'IssuerSerial'{issuer = ?GeneralNames,
+ serial = ?CertificateSerialNumber,
+ issuerUID = ?UniqueIdentifier}).
+
+-define(DigestedObjectType, publicKey). %% Enum
+
+-define(ObjectDigestInfo,
+ #'ObjectDigestInfo'{digestedObjectType = ?DigestedObjectType,
+ otherObjectTypeID = ?OID,
+ digestAlgorithm = ?AlgorithmIdentifier,
+ objectDigest = ?BIT_STR}).
+
+-define(V2Form, #'V2Form'{issuerName = ?GeneralNames,
+ baseCertificateID = ?IssuerSerial,
+ objectDigestInfo = ?ObjectDigestInfo}).
+
+-define(AttCertVersion, v2).
+
+-define(Holder, #'Holder'{baseCertificateID = ?IssuerSerial,
+ entityName = ?GeneralNames,
+ objectDigestInfo = ?ObjectDigestInfo}).
+
+-define(AttCertIssuer, {v2Form, ?V2Form}).
+
+-define(AttributeCertificateInfo,
+ #'AttributeCertificateInfo'{version = ?AttCertVersion,
+ holder = ?Holder,
+ issuer = ?AttCertIssuer,
+ signature = ?AlgorithmIdentifier,
+ serialNumber = ?CertificateSerialNumber,
+ attrCertValidityPeriod = ?AttCertValidityPeriod,
+ attributes = ?Attributes,
+ issuerUniqueID = ?UniqueIdentifier,
+ extensions = ?Extensions}).
+
+-define(AttributeCertificate,
+ #'AttributeCertificate'{acinfo = ?AttributeCertificateInfo,
+ signatureAlgorithm = ?AlgorithmIdentifier,
+ signatureValue = ?BIT_STR}).
+
+
+%% OrberCSIv2
+-define(AttributeCertChain,
+ #'AttributeCertChain'{attributeCert = ?AttributeCertificate,
+ certificateChain = ?CertificateChain}).
+
+-define(CertificateChain, [?Certificate]).
+
+-define(VerifyingCertChain, [?Certificate]).
+
+-endif.
+
+%%-----------------------------------------------------------------
+%% External exports
+%%-----------------------------------------------------------------
+-export([all/1, cases/0, init_all/1, finish_all/1,
+ init_per_testcase/2, fin_per_testcase/2,
+% code_CertificateChain_api/1,
+% code_AttributeCertChain_api/1,
+% code_VerifyingCertChain_api/1,
+% code_AttributeCertificate_api/1,
+% code_Certificate_api/1,
+% code_TBSCertificate_api/1,
+% code_CertificateSerialNumber_api/1,
+% code_Version_api/1,
+% code_AlgorithmIdentifier_api/1,
+% code_Name_api/1,
+% code_RDNSequence_api/1,
+% code_RelativeDistinguishedName_api/1,
+% code_AttributeTypeAndValue_api/1,
+% code_Attribute_api/1,
+% code_Validity_api/1,
+% code_SubjectPublicKeyInfo_api/1,
+% code_UniqueIdentifier_api/1,
+% code_Extensions_api/1,
+% code_Extension_api/1,
+% code_AttributeCertificateInfo_api/1,
+% code_AttCertVersion_api/1,
+% code_Holder_api/1,
+% code_AttCertIssuer_api/1,
+% code_AttCertValidityPeriod_api/1,
+% code_V2Form_api/1,
+% code_IssuerSerial_api/1,
+% code_ObjectDigestInfo_api/1,
+% code_OpenSSL509_api/1,
+ ssl_server_peercert_api/1,
+ ssl_client_peercert_api/1]).
+
+
+%%-----------------------------------------------------------------
+%% Internal exports
+%%-----------------------------------------------------------------
+-export([fake_server_ORB/5]).
+
+%%-----------------------------------------------------------------
+%% Func: all/1
+%% Args:
+%% Returns:
+%%-----------------------------------------------------------------
+all(doc) -> ["API tests for multi orber interfaces using CSIv2"];
+all(suite) -> {req,
+ [mnesia],
+ {conf, init_all, cases(), finish_all}}.
+
+%% NOTE - the fragment test cases must bu first since we explicitly set a request
+%% id. Otherwise, the request-id counter would be increased and we cannot know
+%% what it is.
+cases() ->
+ [
+% code_CertificateChain_api,
+% code_AttributeCertChain_api,
+% code_VerifyingCertChain_api,
+% code_AttributeCertificate_api,
+% code_Certificate_api,
+% code_TBSCertificate_api,
+% code_CertificateSerialNumber_api,
+% code_Version_api,
+% code_AlgorithmIdentifier_api,
+% code_Name_api,
+% code_RDNSequence_api,
+% code_RelativeDistinguishedName_api,
+% code_AttributeTypeAndValue_api,
+% code_Attribute_api,
+% code_Validity_api,
+% code_SubjectPublicKeyInfo_api,
+% code_UniqueIdentifier_api,
+% code_Extensions_api,
+% code_Extension_api,
+% code_AttributeCertificateInfo_api,
+% code_AttCertVersion_api,
+% code_Holder_api,
+% code_AttCertIssuer_api,
+% code_AttCertValidityPeriod_api,
+% code_V2Form_api,
+% code_IssuerSerial_api,
+% code_ObjectDigestInfo_api,
+% code_OpenSSL509_api,
+ ssl_server_peercert_api,
+ ssl_client_peercert_api].
+
+%%-----------------------------------------------------------------
+%% Init and cleanup functions.
+%%-----------------------------------------------------------------
+
+init_per_testcase(_Case, Config) ->
+ Path = code:which(?MODULE),
+ code:add_pathz(filename:join(filename:dirname(Path), "idl_output")),
+ Dog=test_server:timetrap(?default_timeout),
+ orber:jump_start(0),
+ oe_orber_test_server:oe_register(),
+ [{watchdog, Dog}|Config].
+
+
+fin_per_testcase(_Case, Config) ->
+ oe_orber_test_server:oe_unregister(),
+ orber:jump_stop(),
+ Path = code:which(?MODULE),
+ code:del_path(filename:join(filename:dirname(Path), "idl_output")),
+ Dog = ?config(watchdog, Config),
+ test_server:timetrap_cancel(Dog),
+ ok.
+
+init_all(Config) ->
+ if
+ is_list(Config) ->
+ Config;
+ true ->
+ exit("Config not a list")
+ end.
+
+finish_all(Config) ->
+ Config.
+
+%%-----------------------------------------------------------------
+%% API tests for ORB to ORB, no security
+%%-----------------------------------------------------------------
+
+
+%%-----------------------------------------------------------------
+%% Encode and decode ASN.1 X509
+%%-----------------------------------------------------------------
+
+-ifdef(false).
+%% OrberCSIv2
+code_CertificateChain_api(doc) -> ["Code CertificateChain"];
+code_CertificateChain_api(suite) -> [];
+code_CertificateChain_api(_Config) ->
+ {ok, Enc} =
+ ?match({ok, _},
+ 'OrberCSIv2':encode('CertificateChain', ?CertificateChain)),
+ ?match({ok, [#'Certificate'{}]},
+ 'OrberCSIv2':decode('CertificateChain', list_to_binary(Enc))),
+ ok.
+
+code_AttributeCertChain_api(doc) -> ["Code AttributeCertChain"];
+code_AttributeCertChain_api(suite) -> [];
+code_AttributeCertChain_api(_Config) ->
+ {ok, Enc} =
+ ?match({ok, _},
+ 'OrberCSIv2':encode('AttributeCertChain', ?AttributeCertChain)),
+ ?match({ok, #'AttributeCertChain'{}},
+ 'OrberCSIv2':decode('AttributeCertChain', list_to_binary(Enc))),
+ ok.
+
+code_VerifyingCertChain_api(doc) -> ["Code VerifyingCertChain"];
+code_VerifyingCertChain_api(suite) -> [];
+code_VerifyingCertChain_api(_Config) ->
+ {ok, Enc} =
+ ?match({ok, _},
+ 'OrberCSIv2':encode('VerifyingCertChain', ?VerifyingCertChain)),
+ ?match({ok, [#'Certificate'{}]},
+ 'OrberCSIv2':decode('VerifyingCertChain', list_to_binary(Enc))),
+ ok.
+
+%% PKIXAttributeCertificate
+code_AttributeCertificate_api(doc) -> ["Code AttributeCertificate"];
+code_AttributeCertificate_api(suite) -> [];
+code_AttributeCertificate_api(_Config) ->
+ {ok, Enc} =
+ ?match({ok, _},
+ 'OrberCSIv2':encode('AttributeCertificate', ?AttributeCertificate)),
+ ?match({ok, #'AttributeCertificate'{}},
+ 'OrberCSIv2':decode('AttributeCertificate', list_to_binary(Enc))),
+ ok.
+
+code_AttributeCertificateInfo_api(doc) -> ["Code AttributeCertificateInfo"];
+code_AttributeCertificateInfo_api(suite) -> [];
+code_AttributeCertificateInfo_api(_Config) ->
+ {ok, Enc} =
+ ?match({ok, _},
+ 'OrberCSIv2':encode('AttributeCertificateInfo', ?AttributeCertificateInfo)),
+ ?match({ok, #'AttributeCertificateInfo'{}},
+ 'OrberCSIv2':decode('AttributeCertificateInfo', list_to_binary(Enc))),
+ ok.
+
+code_AttCertVersion_api(doc) -> ["Code AttCertVersion"];
+code_AttCertVersion_api(suite) -> [];
+code_AttCertVersion_api(_Config) ->
+ {ok, Enc} =
+ ?match({ok, _},
+ 'OrberCSIv2':encode('AttCertVersion', ?AttCertVersion)),
+ ?match({ok, ?AttCertVersion},
+ 'OrberCSIv2':decode('AttCertVersion', list_to_binary(Enc))),
+ ok.
+
+code_Holder_api(doc) -> ["Code Holder"];
+code_Holder_api(suite) -> [];
+code_Holder_api(_Config) ->
+ {ok, Enc} =
+ ?match({ok, _},
+ 'OrberCSIv2':encode('Holder', ?Holder)),
+ ?match({ok, #'Holder'{}},
+ 'OrberCSIv2':decode('Holder', list_to_binary(Enc))),
+ ok.
+
+code_AttCertIssuer_api(doc) -> ["Code AttCertIssuer"];
+code_AttCertIssuer_api(suite) -> [];
+code_AttCertIssuer_api(_Config) ->
+ {ok, Enc} =
+ ?match({ok, _},
+ 'OrberCSIv2':encode('AttCertIssuer', ?AttCertIssuer)),
+ ?match({ok, {v2Form, _}},
+ 'OrberCSIv2':decode('AttCertIssuer', list_to_binary(Enc))),
+ ok.
+
+code_AttCertValidityPeriod_api(doc) -> ["Code AttCertValidityPeriod"];
+code_AttCertValidityPeriod_api(suite) -> [];
+code_AttCertValidityPeriod_api(_Config) ->
+ {ok, Enc} =
+ ?match({ok, _}, 'OrberCSIv2':encode('AttCertValidityPeriod', ?AttCertValidityPeriod)),
+ ?match({ok, #'AttCertValidityPeriod'{}},
+ 'OrberCSIv2':decode('AttCertValidityPeriod', list_to_binary(Enc))),
+ ok.
+
+code_V2Form_api(doc) -> ["Code V2Form"];
+code_V2Form_api(suite) -> [];
+code_V2Form_api(_Config) ->
+ {ok, Enc} =
+ ?match({ok, _},
+ 'OrberCSIv2':encode('V2Form', ?V2Form)),
+ ?match({ok, #'V2Form'{}},
+ 'OrberCSIv2':decode('V2Form', list_to_binary(Enc))),
+ ok.
+
+code_IssuerSerial_api(doc) -> ["Code IssuerSerial"];
+code_IssuerSerial_api(suite) -> [];
+code_IssuerSerial_api(_Config) ->
+ {ok, Enc} =
+ ?match({ok, _},
+ 'OrberCSIv2':encode('IssuerSerial', ?IssuerSerial)),
+ ?match({ok, #'IssuerSerial'{}},
+ 'OrberCSIv2':decode('IssuerSerial', list_to_binary(Enc))),
+ ok.
+
+code_ObjectDigestInfo_api(doc) -> ["Code ObjectDigestInfo"];
+code_ObjectDigestInfo_api(suite) -> [];
+code_ObjectDigestInfo_api(_Config) ->
+ {ok, Enc} =
+ ?match({ok, _},
+ 'OrberCSIv2':encode('ObjectDigestInfo', ?ObjectDigestInfo)),
+ ?match({ok, #'ObjectDigestInfo'{}},
+ 'OrberCSIv2':decode('ObjectDigestInfo', list_to_binary(Enc))),
+ ok.
+
+%% PKIX1Explicit88
+code_Certificate_api(doc) -> ["Code Certificate"];
+code_Certificate_api(suite) -> [];
+code_Certificate_api(_Config) ->
+ {ok, Enc} =
+ ?match({ok, _},
+ 'OrberCSIv2':encode('Certificate', ?Certificate)),
+ ?match({ok, #'Certificate'{}},
+ 'OrberCSIv2':decode('Certificate', list_to_binary(Enc))),
+ ok.
+
+code_TBSCertificate_api(doc) -> ["Code TBSCertificate"];
+code_TBSCertificate_api(suite) -> [];
+code_TBSCertificate_api(_Config) ->
+ {ok, Enc} =
+ ?match({ok, _},
+ 'OrberCSIv2':encode('TBSCertificate', ?TBSCertificate)),
+ ?match({ok, #'TBSCertificate'{}},
+ 'OrberCSIv2':decode('TBSCertificate', list_to_binary(Enc))),
+ ok.
+
+code_CertificateSerialNumber_api(doc) -> ["Code CertificateSerialNumber"];
+code_CertificateSerialNumber_api(suite) -> [];
+code_CertificateSerialNumber_api(_Config) ->
+ {ok, Enc} =
+ ?match({ok, _},
+ 'OrberCSIv2':encode('CertificateSerialNumber', ?CertificateSerialNumber)),
+ ?match({ok, ?CertificateSerialNumber},
+ 'OrberCSIv2':decode('CertificateSerialNumber', list_to_binary(Enc))),
+ ok.
+
+code_Version_api(doc) -> ["Code Version"];
+code_Version_api(suite) -> [];
+code_Version_api(_Config) ->
+ {ok, Enc} =
+ ?match({ok, _}, 'OrberCSIv2':encode('Version', ?Version)),
+ ?match({ok, ?Version}, 'OrberCSIv2':decode('Version', list_to_binary(Enc))),
+ ok.
+
+code_AlgorithmIdentifier_api(doc) -> ["Code AlgorithmIdentifier"];
+code_AlgorithmIdentifier_api(suite) -> [];
+code_AlgorithmIdentifier_api(_Config) ->
+ {ok, Enc} =
+ ?match({ok, _}, 'OrberCSIv2':encode('AlgorithmIdentifier', ?AlgorithmIdentifier)),
+ ?match({ok, #'AlgorithmIdentifier'{}},
+ 'OrberCSIv2':decode('AlgorithmIdentifier', list_to_binary(Enc))),
+ ok.
+
+code_Name_api(doc) -> ["Code Name"];
+code_Name_api(suite) -> [];
+code_Name_api(_Config) ->
+ {ok, Enc} =
+ ?match({ok, _}, 'OrberCSIv2':encode('Name', ?Name)),
+ ?match({ok, {rdnSequence,_}},
+ 'OrberCSIv2':decode('Name', list_to_binary(Enc))),
+ ok.
+
+code_RDNSequence_api(doc) -> ["Code RDNSequence"];
+code_RDNSequence_api(suite) -> [];
+code_RDNSequence_api(_Config) ->
+ {ok, Enc} =
+ ?match({ok, _}, 'OrberCSIv2':encode('RDNSequence', ?RDNSequence)),
+ ?match({ok, [[#'AttributeTypeAndValue'{}]]},
+ 'OrberCSIv2':decode('RDNSequence', list_to_binary(Enc))),
+ ok.
+
+code_RelativeDistinguishedName_api(doc) -> ["Code RelativeDistinguishedName"];
+code_RelativeDistinguishedName_api(suite) -> [];
+code_RelativeDistinguishedName_api(_Config) ->
+ {ok, Enc} =
+ ?match({ok, _}, 'OrberCSIv2':encode('RelativeDistinguishedName', ?RelativeDistinguishedName)),
+ ?match({ok, [#'AttributeTypeAndValue'{}]},
+ 'OrberCSIv2':decode('RelativeDistinguishedName', list_to_binary(Enc))),
+ ok.
+
+code_AttributeTypeAndValue_api(doc) -> ["Code AttributeTypeAndValue"];
+code_AttributeTypeAndValue_api(suite) -> [];
+code_AttributeTypeAndValue_api(_Config) ->
+ {ok, Enc} =
+ ?match({ok, _}, 'OrberCSIv2':encode('AttributeTypeAndValue', ?AttributeTypeAndValue)),
+ ?match({ok, #'AttributeTypeAndValue'{}},
+ 'OrberCSIv2':decode('AttributeTypeAndValue', list_to_binary(Enc))),
+ ok.
+
+code_Attribute_api(doc) -> ["Code Attribute"];
+code_Attribute_api(suite) -> [];
+code_Attribute_api(_Config) ->
+ {ok, Enc} =
+ ?match({ok, _}, 'OrberCSIv2':encode('Attribute', ?Attribute)),
+ ?match({ok, #'Attribute'{}},
+ 'OrberCSIv2':decode('Attribute', list_to_binary(Enc))),
+ ok.
+
+code_Validity_api(doc) -> ["Code Validity"];
+code_Validity_api(suite) -> [];
+code_Validity_api(_Config) ->
+ {ok, Enc} =
+ ?match({ok, _}, 'OrberCSIv2':encode('Validity', ?Validity)),
+ ?match({ok, #'Validity'{}},
+ 'OrberCSIv2':decode('Validity', list_to_binary(Enc))),
+ ok.
+
+code_SubjectPublicKeyInfo_api(doc) -> ["Code SubjectPublicKeyInfo"];
+code_SubjectPublicKeyInfo_api(suite) -> [];
+code_SubjectPublicKeyInfo_api(_Config) ->
+ {ok, Enc} =
+ ?match({ok, _}, 'OrberCSIv2':encode('SubjectPublicKeyInfo', ?SubjectPublicKeyInfo)),
+ ?match({ok, #'SubjectPublicKeyInfo'{}},
+ 'OrberCSIv2':decode('SubjectPublicKeyInfo', list_to_binary(Enc))),
+ ok.
+
+code_UniqueIdentifier_api(doc) -> ["Code UniqueIdentifier"];
+code_UniqueIdentifier_api(suite) -> [];
+code_UniqueIdentifier_api(_Config) ->
+ {ok, Enc} =
+ ?match({ok, _}, 'OrberCSIv2':encode('UniqueIdentifier', ?UniqueIdentifier)),
+ ?match({ok, _}, 'OrberCSIv2':decode('UniqueIdentifier', list_to_binary(Enc))),
+ ok.
+
+code_Extensions_api(doc) -> ["Code Extensions"];
+code_Extensions_api(suite) -> [];
+code_Extensions_api(_Config) ->
+ {ok, Enc} =
+ ?match({ok, _}, 'OrberCSIv2':encode('Extensions', ?Extensions)),
+ ?match({ok, [#'Extension'{}]},
+ 'OrberCSIv2':decode('Extensions', list_to_binary(Enc))),
+ ok.
+
+code_Extension_api(doc) -> ["Code Extension"];
+code_Extension_api(suite) -> [];
+code_Extension_api(_Config) ->
+ {ok, Enc} =
+ ?match({ok, _}, 'OrberCSIv2':encode('Extension', ?Extension)),
+ ?match({ok, #'Extension'{}},
+ 'OrberCSIv2':decode('Extension', list_to_binary(Enc))),
+ ok.
+
+%% OpenSSL generated x509 Certificate
+code_OpenSSL509_api(doc) -> ["Code OpenSSL generated x509 Certificate"];
+code_OpenSSL509_api(suite) -> [];
+code_OpenSSL509_api(_Config) ->
+ {ok, Cert} =
+ ?match({ok, #'Certificate'{}},
+ 'OrberCSIv2':decode('Certificate', ?X509DER)),
+ AttrCertChain = #'AttributeCertChain'{attributeCert = ?AttributeCertificate,
+ certificateChain = [Cert]},
+ {ok, EAttrCertChain} =
+ ?match({ok, _}, 'OrberCSIv2':encode('AttributeCertChain', AttrCertChain)),
+ ?match({ok, #'AttributeCertChain'{}},
+ 'OrberCSIv2':decode('AttributeCertChain', list_to_binary(EAttrCertChain))),
+ ok.
+
+-endif.
+
+%%-----------------------------------------------------------------
+%% Test ssl:peercert
+%%-----------------------------------------------------------------
+ssl_server_peercert_api(doc) -> ["Test ssl:peercert (server side)"];
+ssl_server_peercert_api(suite) -> [];
+ssl_server_peercert_api(_Config) ->
+ case os:type() of
+ vxworks ->
+ {skipped, "No SSL-support for VxWorks."};
+ _ ->
+ Options = orber_test_lib:get_options(iiop_ssl, server,
+ 2, [{iiop_ssl_port, 0}]),
+ {ok, ServerNode, ServerHost} =
+ ?match({ok,_,_}, orber_test_lib:js_node(Options)),
+ ServerPort = orber_test_lib:remote_apply(ServerNode, orber, iiop_ssl_port, []),
+ SSLOptions = orber_test_lib:get_options(ssl, client),
+ {ok, Socket} =
+ ?match({ok, _}, fake_client_ORB(ssl, ServerHost, ServerPort, SSLOptions)),
+ {ok, _PeerCert} = ?match({ok, _}, orber_socket:peercert(ssl, Socket)),
+ ?match({ok, {rdnSequence, _}}, orber_socket:peercert(ssl, Socket, [pkix, subject])),
+ ?match({ok, {rdnSequence, _}}, orber_socket:peercert(ssl, Socket, [ssl, subject])),
+% ?match({ok, #'Certificate'{}},
+% 'OrberCSIv2':decode('Certificate', PeerCert)),
+ destroy_fake_ORB(ssl, Socket),
+ ok
+ end.
+
+ssl_client_peercert_api(doc) -> ["Test ssl:peercert (client side)"];
+ssl_client_peercert_api(suite) -> [];
+ssl_client_peercert_api(_Config) ->
+ case os:type() of
+ vxworks ->
+ {skipped, "No SSL-support for VxWorks."};
+ _ ->
+ Options = orber_test_lib:get_options(iiop_ssl, client,
+ 2, [{iiop_ssl_port, 0}]),
+ {ok, ClientNode, _ClientHost} =
+ ?match({ok,_,_}, orber_test_lib:js_node(Options)),
+ crypto:start(),
+ ssl:start(),
+ ssl:seed("testing"),
+ SSLOptions = orber_test_lib:get_options(ssl, server),
+ {ok, LSock} = ?match({ok, _}, ssl:listen(0, SSLOptions)),
+ {ok, {_Address, LPort}} = ?match({ok, {_, _}}, ssl:sockname(LSock)),
+ IOR = ?match({'IOP_IOR',_,_},
+ iop_ior:create_external({1, 2}, "IDL:FAKE:1.0",
+ "localhost", 6004, "FAKE",
+ [#'IOP_TaggedComponent'
+ {tag=?TAG_SSL_SEC_TRANS,
+ component_data=#'SSLIOP_SSL'
+ {target_supports = 2,
+ target_requires = 2,
+ port = LPort}}])),
+ spawn(orber_test_lib, remote_apply,
+ [ClientNode, corba_object, non_existent, [IOR]]),
+ {ok, Socket} = ?match({ok, _}, ssl:transport_accept(LSock)),
+ ?match(ok, ssl:ssl_accept(Socket)),
+
+ {ok, _PeerCert} = ?match({ok, _}, orber_socket:peercert(ssl, Socket)),
+ ?match({ok, {rdnSequence, _}}, orber_socket:peercert(ssl, Socket, [pkix, subject])),
+ ?match({ok, {rdnSequence, _}}, orber_socket:peercert(ssl, Socket, [ssl, subject])),
+% ?match({ok, #'Certificate'{}},
+% 'OrberCSIv2':decode('Certificate', PeerCert)),
+ ssl:close(Socket),
+ ssl:close(LSock),
+ ssl:stop(),
+ ok
+ end.
+
+%%-----------------------------------------------------------------
+%% Local functions.
+%%-----------------------------------------------------------------
+-ifdef(false).
+%% Not used yet.
+context_test(Obj) ->
+ IDToken1 = #'CSI_IdentityToken'{label = ?CSI_IdentityTokenType_ITTAbsent,
+ value = true},
+ IDToken2 = #'CSI_IdentityToken'{label = ?CSI_IdentityTokenType_ITTAnonymous,
+ value = false},
+ IDToken3 = #'CSI_IdentityToken'{label = ?CSI_IdentityTokenType_ITTPrincipalName,
+ value = [0,255]},
+ IDToken4 = #'CSI_IdentityToken'{label = ?CSI_IdentityTokenType_ITTX509CertChain,
+ value = [1,255]},
+ IDToken5 = #'CSI_IdentityToken'{label = ?CSI_IdentityTokenType_ITTDistinguishedName,
+ value = [2,255]},
+ IDToken6 = #'CSI_IdentityToken'{label = ?ULONGMAX,
+ value = [3,255]},
+
+ MTEstablishContext1 = #'CSI_SASContextBody'
+ {label = ?CSI_MsgType_MTEstablishContext,
+ value = #'CSI_EstablishContext'{client_context_id = ?ULONGLONGMAX,
+ authorization_token =
+ [#'CSI_AuthorizationElement'
+ {the_type = ?ULONGMAX,
+ the_element = [0,255]}],
+ identity_token = IDToken1,
+ client_authentication_token = [1, 255]}},
+ MTEstablishContext2 = #'CSI_SASContextBody'
+ {label = ?CSI_MsgType_MTEstablishContext,
+ value = #'CSI_EstablishContext'{client_context_id = ?ULONGLONGMAX,
+ authorization_token =
+ [#'CSI_AuthorizationElement'
+ {the_type = ?ULONGMAX,
+ the_element = [0,255]}],
+ identity_token = IDToken2,
+ client_authentication_token = [1, 255]}},
+ MTEstablishContext3 = #'CSI_SASContextBody'
+ {label = ?CSI_MsgType_MTEstablishContext,
+ value = #'CSI_EstablishContext'{client_context_id = ?ULONGLONGMAX,
+ authorization_token =
+ [#'CSI_AuthorizationElement'
+ {the_type = ?ULONGMAX,
+ the_element = [0,255]}],
+ identity_token = IDToken3,
+ client_authentication_token = [1, 255]}},
+ MTEstablishContext4 = #'CSI_SASContextBody'
+ {label = ?CSI_MsgType_MTEstablishContext,
+ value = #'CSI_EstablishContext'{client_context_id = ?ULONGLONGMAX,
+ authorization_token =
+ [#'CSI_AuthorizationElement'
+ {the_type = ?ULONGMAX,
+ the_element = [0,255]}],
+ identity_token = IDToken4,
+ client_authentication_token = [1, 255]}},
+ MTEstablishContext5 = #'CSI_SASContextBody'
+ {label = ?CSI_MsgType_MTEstablishContext,
+ value = #'CSI_EstablishContext'{client_context_id = ?ULONGLONGMAX,
+ authorization_token =
+ [#'CSI_AuthorizationElement'
+ {the_type = ?ULONGMAX,
+ the_element = [0,255]}],
+ identity_token = IDToken5,
+ client_authentication_token = [1, 255]}},
+ MTEstablishContext6 = #'CSI_SASContextBody'
+ {label = ?CSI_MsgType_MTEstablishContext,
+ value = #'CSI_EstablishContext'{client_context_id = ?ULONGLONGMAX,
+ authorization_token =
+ [#'CSI_AuthorizationElement'
+ {the_type = ?ULONGMAX,
+ the_element = [0,255]}],
+ identity_token = IDToken6,
+ client_authentication_token = [1, 255]}},
+ MTCompleteEstablishContext = #'CSI_SASContextBody'
+ {label = ?CSI_MsgType_MTCompleteEstablishContext,
+ value = #'CSI_CompleteEstablishContext'{client_context_id = ?ULONGLONGMAX,
+ context_stateful = false,
+ final_context_token = [1, 255]}},
+ MTContextError = #'CSI_SASContextBody'
+ {label = ?CSI_MsgType_MTContextError,
+ value = #'CSI_ContextError'{client_context_id = ?ULONGLONGMAX,
+ major_status = 1,
+ minor_status = 2,
+ error_token = [2,255]}},
+ MTMessageInContext = #'CSI_SASContextBody'
+ {label = ?CSI_MsgType_MTMessageInContext,
+ value = #'CSI_MessageInContext'{client_context_id = ?ULONGLONGMAX,
+ discard_context = true}},
+ Ctx = [#'IOP_ServiceContext'{context_id=?IOP_SecurityAttributeService,
+ context_data = MTEstablishContext1},
+ #'IOP_ServiceContext'{context_id=?IOP_SecurityAttributeService,
+ context_data = MTEstablishContext2},
+ #'IOP_ServiceContext'{context_id=?IOP_SecurityAttributeService,
+ context_data = MTEstablishContext3},
+ #'IOP_ServiceContext'{context_id=?IOP_SecurityAttributeService,
+ context_data = MTEstablishContext4},
+ #'IOP_ServiceContext'{context_id=?IOP_SecurityAttributeService,
+ context_data = MTEstablishContext5},
+ #'IOP_ServiceContext'{context_id=?IOP_SecurityAttributeService,
+ context_data = MTEstablishContext6},
+ #'IOP_ServiceContext'{context_id=?IOP_SecurityAttributeService,
+ context_data = MTCompleteEstablishContext},
+ #'IOP_ServiceContext'{context_id=?IOP_SecurityAttributeService,
+ context_data = MTContextError},
+ #'IOP_ServiceContext'{context_id=?IOP_SecurityAttributeService,
+ context_data = MTMessageInContext}],
+ ?line ?match(ok, orber_test_server:testing_iiop_context(Obj, [{context, Ctx}])).
+
+
+fake_server_ORB(Type, Port, Options) ->
+ start_ssl(Type),
+ {ok, ListenSocket, NewPort} =
+ orber_socket:listen(Type, Port,
+ [{active, false}|Options]),
+ Socket = orber_socket:accept(Type, ListenSocket),
+ orber_socket:post_accept(Type, Socket),
+ {ok, Socket, NewPort}.
+
+-endif.
+
+fake_server_ORB(Type, Port, Options, Action, Data) ->
+ start_ssl(Type),
+ {ok, ListenSocket, _NewPort} =
+ orber_socket:listen(Type, Port, [{active, false}|Options]),
+ Socket = orber_socket:accept(Type, ListenSocket),
+ orber_socket:post_accept(Type, Socket),
+ do_server_action(Type, Socket, Action, Data),
+ orber_socket:close(Type, Socket),
+ ok.
+
+start_ssl(ssl) ->
+ crypto:start(),
+ ssl:start(),
+ ssl:seed("testing");
+start_ssl(_) ->
+ ok.
+
+
+destroy_fake_ORB(ssl, Socket) ->
+ orber_socket:close(ssl, Socket),
+ ssl:stop();
+destroy_fake_ORB(Type, Socket) ->
+ orber_socket:close(Type, Socket).
+
+fake_client_ORB(Type, Host, Port, Options) ->
+ start_ssl(Type),
+ Socket = orber_socket:connect(Type, Host, Port, [{active, false}|Options]),
+ {ok, Socket}.
+
+-ifdef(false).
+%% Not used yet.
+
+fake_client_ORB(Type, Host, Port, Options, Action, Data) ->
+ start_ssl(Type),
+ Socket = orber_socket:connect(Type, Host, Port, [{active, false}|Options]),
+ Result = do_client_action(Type, Socket, Action, Data),
+ orber_socket:close(Type, Socket),
+ Result.
+
+do_client_action(Type, Socket, fragments, FragList) ->
+ ok = send_data(Type, Socket, FragList),
+ {ok, Bytes} = gen_tcp:recv(Socket, 0),
+ {#reply_header{request_id = ?REQUEST_ID, reply_status = no_exception}, ok, [Par]} =
+ cdr_decode:dec_message({tk_void,[tk_any],[tk_any]}, Bytes),
+ Par;
+do_client_action(Type, Socket, fragments_max, FragList) ->
+ ok = send_data(Type, Socket, FragList),
+ {ok, Bytes} = gen_tcp:recv(Socket, 0),
+ {#reply_header{request_id = ?REQUEST_ID, reply_status = system_exception}, Exc, []} =
+ cdr_decode:dec_message({tk_void,[tk_any],[tk_any]}, Bytes),
+ Exc;
+do_client_action(Type, Socket, message_error, Data) ->
+ ok = send_data(Type, Socket, Data),
+ {ok,Bytes} = gen_tcp:recv(Socket, 0),
+ 'message_error' = cdr_decode:dec_message({tk_void,[tk_any],[tk_any]}, Bytes),
+ ok;
+do_client_action(_Type, _Socket, _Action, _Data) ->
+ ok.
+
+-endif.
+
+do_server_action(Type, Socket, fragments, FragList) ->
+ {ok, _B} = gen_tcp:recv(Socket, 0),
+ ok = send_data(Type, Socket, FragList);
+do_server_action(_Type, _Socket, _Action, _Data) ->
+ ok.
+
+
+send_data(_Type, _Socket, []) ->
+ ok;
+send_data(Type, Socket, [H|T]) ->
+ orber_socket:write(Type, Socket, H),
+ send_data(Type, Socket, T).
+
diff --git a/lib/orber/test/data_types_SUITE.erl b/lib/orber/test/data_types_SUITE.erl
new file mode 100644
index 0000000000..1feb0b3b58
--- /dev/null
+++ b/lib/orber/test/data_types_SUITE.erl
@@ -0,0 +1,173 @@
+%%-----------------------------------------------------------------
+%%
+%% %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%
+%%
+%%
+%%-----------------------------------------------------------------
+%% File : data_types_SUITE.erl
+%% Purpose :
+%%-----------------------------------------------------------------
+
+-module(data_types_SUITE).
+
+-include("test_server.hrl").
+-include_lib("orber/include/corba.hrl").
+
+-define(default_timeout, ?t:minutes(3)).
+
+-define(match(ExpectedRes, Expr),
+ fun() ->
+ AcTuAlReS = (catch (Expr)),
+ case AcTuAlReS of
+ ExpectedRes ->
+ io:format("------ CORRECT RESULT ------~n~p~n",
+ [AcTuAlReS]),
+ AcTuAlReS;
+ _ ->
+ io:format("###### ERROR ERROR ######~n~p~n",
+ [AcTuAlReS]),
+ ?line exit(AcTuAlReS)
+ end
+ end()).
+
+%%-----------------------------------------------------------------
+%% External exports
+%%-----------------------------------------------------------------
+-export([all/1]).
+
+%%-----------------------------------------------------------------
+%% Internal exports
+%%-----------------------------------------------------------------
+-export([]).
+-compile(export_all).
+
+%%-----------------------------------------------------------------
+%% Func: all/1
+%% Args:
+%% Returns:
+%%-----------------------------------------------------------------
+all(doc) -> ["This suite is for testing more or less complex data types"];
+all(suite) ->
+ [fixed_type, any_type].
+
+%%-----------------------------------------------------------------
+%% Init and cleanup functions.
+%%-----------------------------------------------------------------
+init_per_testcase(_Case, Config) ->
+ Path = code:which(?MODULE),
+ code:add_pathz(filename:join(filename:dirname(Path), "idl_output")),
+ ?line Dog=test_server:timetrap(?default_timeout),
+ [{watchdog, Dog}|Config].
+
+
+fin_per_testcase(_Case, Config) ->
+ Path = code:which(?MODULE),
+ code:del_path(filename:join(filename:dirname(Path), "idl_output")),
+ Dog = ?config(watchdog, Config),
+ test_server:timetrap_cancel(Dog),
+ ok.
+
+
+%%-----------------------------------------------------------------
+%% Test Case: name component handling tests
+%% Description:
+%%-----------------------------------------------------------------
+fixed_type(doc) -> ["Test the Fixed Point Datatype."];
+fixed_type(suite) -> [];
+fixed_type(_) ->
+ Val1 = ?match({fixed,3,2,314}, orber_test_server:val1()),
+ _Val2 = ?match({fixed,3,2,314}, orber_test_server:val2()),
+ _Val3 = ?match({fixed,3,2,314}, orber_test_server:val3()),
+ Val4 = ?match({fixed,3,2,314}, orber_test_server:val4()),
+ Val5 = ?match({fixed,2,2,14}, orber_test_server:val5()),
+ _Val6 = ?match({fixed,1,0,3}, orber_test_server:val6()),
+ Val7 = ?match({fixed,2,2,-14}, orber_test_server:val7()),
+ _Val8 = ?match({fixed,1,0,-3}, orber_test_server:val8()),
+ Val9 = ?match({fixed,3,2,328}, orber_test_server:val9()),
+ Val10 = ?match({fixed,4,4,4396}, orber_test_server:val10()),
+ Val11 = ?match({fixed,31,29,2242857142857142857142857142857}, orber_test_server:val11()),
+ Val12 = ?match({fixed,9,6,123140001}, orber_test_server:val12()),
+ Val13 = ?match({fixed,9,1,123140001}, orber_test_server:val13()),
+ Val14 = ?match({fixed,14,6,-12313876959999}, orber_test_server:val14()),
+ Val15 = ?match({fixed,14,6,12314123240001}, orber_test_server:val15()),
+ Val16 = ?match({fixed,17,7,15163459846280001}, orber_test_server:val16()),
+ _Val17 = ?match({fixed,3,2,402}, orber_test_server:val17()),
+ _Val18 = ?match({fixed,5,4,40401}, orber_test_server:val18()),
+ _Val19 = ?match({fixed,3,0,200}, orber_test_server:val19()),
+ Val20 = ?match({fixed,31,0,1999999999999999999999999999999}, orber_test_server:val20()),
+ Val21 = ?match({fixed,1,0,0}, orber_test_server:val21()),
+ Val22 = ?match({fixed,31,0,9999999999999999999999999999998}, orber_test_server:val22()),
+ Val23 = ?match({fixed,1,0,1}, orber_test_server:val23()),
+ _Val24 = ?match({fixed,5,0,19998}, orber_test_server:val24()),
+ _Val25 = ?match({fixed,2,0,40}, orber_test_server:val25()),
+ Val26 = ?match({fixed,31,0,9999999999999999999999999999999}, orber_test_server:val26()),
+
+ ?match(Val1, fixed:create(3,2,314)),
+ Val27 = ?match({fixed,6,2,314}, fixed:create(6,2,314)),
+
+ ?match({tk_fixed,3,2}, fixed:get_typecode(Val1)),
+ ?match({tk_fixed,6,2}, fixed:get_typecode(Val27)),
+ ?match({'EXCEPTION',{'BAD_PARAM',_,_,_}}, fixed:create(3,2,3140)),
+ ?match({'EXCEPTION',{'BAD_PARAM',_,_,_}}, fixed:create(5,6,314)),
+ ?match({'EXCEPTION',{'BAD_PARAM',_,_,_}}, fixed:create(32,2,314)),
+ ?match(Val10, fixed:multiply(Val4, Val5)),
+ ?match(Val16, fixed:multiply(Val12, Val13)),
+ ?match(Val22, fixed:multiply(Val26, Val26)),
+
+ ?match(Val9, fixed:add(Val4, Val5)),
+ ?match(Val15, fixed:add(Val12, Val13)),
+ ?match(Val20, fixed:add(Val26, Val26)),
+
+ ?match(Val11, fixed:divide(Val4, Val5)),
+ ?match(Val23, fixed:divide(Val26, Val26)),
+
+ ?match(Val14, fixed:subtract(Val12, Val13)),
+ ?match(Val21, fixed:subtract(Val26, Val26)),
+
+ ?match(Val7, fixed:unary_minus(Val5)),
+ ?match(Val5, fixed:unary_minus(Val7)),
+
+
+
+ ok.
+
+%%-----------------------------------------------------------------
+%% Test Case: any type
+%% Description:
+%%-----------------------------------------------------------------
+any_type(doc) -> ["Test the Any Datatype."];
+any_type(suite) -> [];
+any_type(_) ->
+ ?match(#any{typecode=undefined, value=undefined},
+ any:create()),
+ ?match(#any{typecode=tk_short, value=undefined},
+ any:set_typecode(any:create(), tk_short)),
+ ?match({'EXCEPTION', #'BAD_TYPECODE'{}},
+ any:set_typecode(any:create(), "wrong")),
+ ?match({'EXCEPTION', #'BAD_TYPECODE'{}},
+ any:create("wrong", 1)),
+ ?match(#any{typecode=tk_short, value = 1},
+ any:create(tk_short, 1)),
+ ?match(tk_short,
+ any:get_typecode(any:create(tk_short, 1))),
+ ?match(1,
+ any:get_value(any:create(tk_short, 1))),
+ ?match(#any{typecode=tk_short, value=2},
+ any:set_value(any:create(tk_short, 1), 2)),
+
+ ok.
diff --git a/lib/orber/test/generated_SUITE.erl b/lib/orber/test/generated_SUITE.erl
new file mode 100644
index 0000000000..1cd1674fc4
--- /dev/null
+++ b/lib/orber/test/generated_SUITE.erl
@@ -0,0 +1,385 @@
+%%-----------------------------------------------------------------
+%%
+%% %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%
+%%
+%%
+%%-----------------------------------------------------------------
+%% File : generated_SUITE.erl
+%% Purpose :
+%%-----------------------------------------------------------------
+
+-module(generated_SUITE).
+
+-include("test_server.hrl").
+-include_lib("orber/include/corba.hrl").
+
+-define(default_timeout, ?t:minutes(3)).
+
+-define(match(ExpectedRes, Expr),
+ fun() ->
+ AcTuAlReS = (catch (Expr)),
+ case AcTuAlReS of
+ ExpectedRes ->
+ AcTuAlReS;
+ _ ->
+ io:format("###### ERROR ERROR ######~n~p~n",
+ [AcTuAlReS]),
+ ?line exit(AcTuAlReS)
+ end
+ end()).
+
+-define(nomatch(Not, Expr),
+ fun() ->
+ AcTuAlReS = (catch (Expr)),
+ case AcTuAlReS of
+ Not ->
+ io:format("###### ERROR ERROR ######~n~p~n",
+ [AcTuAlReS]),
+ ?line exit(AcTuAlReS);
+ _ ->
+ AcTuAlReS
+ end
+ end()).
+
+
+-define(checktc(_Op),
+ fun(TC) ->
+ case orber_tc:check_tc(TC) of
+ false ->
+ io:format("###### ERROR ERROR ######~n~p - ~p~n", [Op, TC]),
+ ?line exit(TC);
+ true ->
+ true
+ end
+ end).
+
+%%-----------------------------------------------------------------
+%% External exports
+%%-----------------------------------------------------------------
+-export([all/1]).
+
+%%-----------------------------------------------------------------
+%% Internal exports
+%%-----------------------------------------------------------------
+-export([]).
+-compile(export_all).
+
+%%-----------------------------------------------------------------
+%% Func: all/1
+%% Args:
+%% Returns:
+%%-----------------------------------------------------------------
+all(doc) -> ["This suite is for testing IC generated files"];
+all(suite) ->
+ ['OrberApp_IFR',
+ erlang_binary, erlang_pid, erlang_port, erlang_ref,
+ 'CosNaming_Binding', 'CosNaming_BindingList', 'CosNaming_Name',
+ 'CosNaming_NameComponent', 'CosNaming_NamingContextExt_InvalidAddress',
+ 'CosNaming_NamingContext_AlreadyBound', 'CosNaming_NamingContext_CannotProceed',
+ 'CosNaming_NamingContext_InvalidName', 'CosNaming_NamingContext_NotEmpty',
+ 'CosNaming_NamingContext_NotFound', 'CosNaming_BindingIterator',
+ 'CosNaming_NamingContext', 'CosNaming_NamingContextExt'].
+
+%%-----------------------------------------------------------------
+%% Init and cleanup functions.
+%%-----------------------------------------------------------------
+init_per_testcase(_Case, Config) ->
+ ?line Dog=test_server:timetrap(?default_timeout),
+ [{watchdog, Dog}|Config].
+
+
+fin_per_testcase(_Case, Config) ->
+ Dog = ?config(watchdog, Config),
+ test_server:timetrap_cancel(Dog),
+ ok.
+
+%%-----------------------------------------------------------------
+%% Test Case:'OrberApp_IFR'
+%% Description:
+%%-----------------------------------------------------------------
+'OrberApp_IFR'(doc) -> [""];
+'OrberApp_IFR'(suite) -> [];
+'OrberApp_IFR'(_) ->
+ ?nomatch(undefined, 'OrberApp_IFR':oe_tc(get_absolute_name)),
+ ?nomatch(undefined, 'OrberApp_IFR':oe_tc(get_user_exception_type)),
+ ?match(undefined, 'OrberApp_IFR':oe_tc(undefined)),
+ ?match([_|_], 'OrberApp_IFR':oe_get_interface()),
+ ?match("IDL:OrberApp/IFR:1.0", 'OrberApp_IFR':typeID()),
+ check_tc('OrberApp_IFR':oe_get_interface()),
+ ?match(true, 'OrberApp_IFR':oe_is_a('OrberApp_IFR':typeID())),
+ ?match(false, 'OrberApp_IFR':oe_is_a("wrong")),
+ ok.
+
+
+%%-----------------------------------------------------------------
+%% Test Case: erlang_binary
+%% Description:
+%%-----------------------------------------------------------------
+erlang_binary(doc) -> [""];
+erlang_binary(suite) -> [];
+erlang_binary(_) ->
+ ?match(true, orber_tc:check_tc(erlang_binary:tc())),
+ ?match("IDL:erlang/binary:1.0", erlang_binary:id()),
+ ?match("erlang_binary", erlang_binary:name()),
+ ok.
+
+%%-----------------------------------------------------------------
+%% Test Case: erlang_pid
+%% Description:
+%%-----------------------------------------------------------------
+erlang_pid(doc) -> [""];
+erlang_pid(suite) -> [];
+erlang_pid(_) ->
+ ?match(true, orber_tc:check_tc(erlang_pid:tc())),
+ ?match("IDL:erlang/pid:1.0", erlang_pid:id()),
+ ?match("erlang_pid", erlang_pid:name()),
+ ok.
+
+%%-----------------------------------------------------------------
+%% Test Case: erlang_port
+%% Description:
+%%-----------------------------------------------------------------
+erlang_port(doc) -> [""];
+erlang_port(suite) -> [];
+erlang_port(_) ->
+ ?match(true, orber_tc:check_tc(erlang_port:tc())),
+ ?match("IDL:erlang/port:1.0", erlang_port:id()),
+ ?match("erlang_port", erlang_port:name()),
+ ok.
+
+%%-----------------------------------------------------------------
+%% Test Case: erlang_ref
+%% Description:
+%%-----------------------------------------------------------------
+erlang_ref(doc) -> [""];
+erlang_ref(suite) -> [];
+erlang_ref(_) ->
+ ?match(true, orber_tc:check_tc(erlang_ref:tc())),
+ ?match("IDL:erlang/ref:1.0", erlang_ref:id()),
+ ?match("erlang_ref", erlang_ref:name()),
+ ok.
+
+%%-----------------------------------------------------------------
+%% Test Case: 'CosNaming_Binding'
+%% Description:
+%%-----------------------------------------------------------------
+'CosNaming_Binding'(doc) -> [""];
+'CosNaming_Binding'(suite) -> [];
+'CosNaming_Binding'(_) ->
+ ?match(true, orber_tc:check_tc('CosNaming_Binding':tc())),
+ ?match("IDL:omg.org/CosNaming/Binding:1.0", 'CosNaming_Binding':id()),
+ ?match("CosNaming_Binding", 'CosNaming_Binding':name()),
+ ok.
+
+%%-----------------------------------------------------------------
+%% Test Case: 'CosNaming_BindingList'
+%% Description:
+%%-----------------------------------------------------------------
+'CosNaming_BindingList'(doc) -> [""];
+'CosNaming_BindingList'(suite) -> [];
+'CosNaming_BindingList'(_) ->
+ ?match(true, orber_tc:check_tc('CosNaming_BindingList':tc())),
+ ?match("IDL:omg.org/CosNaming/BindingList:1.0", 'CosNaming_BindingList':id()),
+ ?match("CosNaming_BindingList", 'CosNaming_BindingList':name()),
+ ok.
+
+%%-----------------------------------------------------------------
+%% Test Case: 'CosNaming_Name'
+%% Description:
+%%-----------------------------------------------------------------
+'CosNaming_Name'(doc) -> [""];
+'CosNaming_Name'(suite) -> [];
+'CosNaming_Name'(_) ->
+ ?match(true, orber_tc:check_tc('CosNaming_Name':tc())),
+ ?match("IDL:omg.org/CosNaming/Name:1.0", 'CosNaming_Name':id()),
+ ?match("CosNaming_Name", 'CosNaming_Name':name()),
+ ok.
+
+%%-----------------------------------------------------------------
+%% Test Case: 'CosNaming_NameComponent'
+%% Description:
+%%-----------------------------------------------------------------
+'CosNaming_NameComponent'(doc) -> [""];
+'CosNaming_NameComponent'(suite) -> [];
+'CosNaming_NameComponent'(_) ->
+ ?match(true, orber_tc:check_tc('CosNaming_NameComponent':tc())),
+ ?match("IDL:omg.org/CosNaming/NameComponent:1.0", 'CosNaming_NameComponent':id()),
+ ?match("CosNaming_NameComponent", 'CosNaming_NameComponent':name()),
+ ok.
+
+%%-----------------------------------------------------------------
+%% Test Case: 'CosNaming_NamingContextExt_InvalidAddress'
+%% Description:
+%%-----------------------------------------------------------------
+'CosNaming_NamingContextExt_InvalidAddress'(doc) -> [""];
+'CosNaming_NamingContextExt_InvalidAddress'(suite) -> [];
+'CosNaming_NamingContextExt_InvalidAddress'(_) ->
+ ?match(true, orber_tc:check_tc('CosNaming_NamingContextExt_InvalidAddress':tc())),
+ ?match("IDL:omg.org/CosNaming/NamingContextExt/InvalidAddress:1.0", 'CosNaming_NamingContextExt_InvalidAddress':id()),
+ ?match("CosNaming_NamingContextExt_InvalidAddress", 'CosNaming_NamingContextExt_InvalidAddress':name()),
+ ok.
+
+%%-----------------------------------------------------------------
+%% Test Case: 'CosNaming_NamingContext_AlreadyBound'
+%% Description:
+%%-----------------------------------------------------------------
+'CosNaming_NamingContext_AlreadyBound'(doc) -> [""];
+'CosNaming_NamingContext_AlreadyBound'(suite) -> [];
+'CosNaming_NamingContext_AlreadyBound'(_) ->
+ ?match(true, orber_tc:check_tc('CosNaming_NamingContext_AlreadyBound':tc())),
+ ?match("IDL:omg.org/CosNaming/NamingContext/AlreadyBound:1.0", 'CosNaming_NamingContext_AlreadyBound':id()),
+ ?match("CosNaming_NamingContext_AlreadyBound", 'CosNaming_NamingContext_AlreadyBound':name()),
+ ok.
+
+%%-----------------------------------------------------------------
+%% Test Case: 'CosNaming_NamingContext_CannotProceed'
+%% Description:
+%%-----------------------------------------------------------------
+'CosNaming_NamingContext_CannotProceed'(doc) -> [""];
+'CosNaming_NamingContext_CannotProceed'(suite) -> [];
+'CosNaming_NamingContext_CannotProceed'(_) ->
+ ?match(true, orber_tc:check_tc('CosNaming_NamingContext_CannotProceed':tc())),
+ ?match("IDL:omg.org/CosNaming/NamingContext/CannotProceed:1.0", 'CosNaming_NamingContext_CannotProceed':id()),
+ ?match("CosNaming_NamingContext_CannotProceed", 'CosNaming_NamingContext_CannotProceed':name()),
+ ok.
+
+%%-----------------------------------------------------------------
+%% Test Case: 'CosNaming_NamingContext_InvalidName'
+%% Description:
+%%-----------------------------------------------------------------
+'CosNaming_NamingContext_InvalidName'(doc) -> [""];
+'CosNaming_NamingContext_InvalidName'(suite) -> [];
+'CosNaming_NamingContext_InvalidName'(_) ->
+ ?match(true, orber_tc:check_tc('CosNaming_NamingContext_InvalidName':tc())),
+ ?match("IDL:omg.org/CosNaming/NamingContext/InvalidName:1.0", 'CosNaming_NamingContext_InvalidName':id()),
+ ?match("CosNaming_NamingContext_InvalidName", 'CosNaming_NamingContext_InvalidName':name()),
+ ok.
+
+%%-----------------------------------------------------------------
+%% Test Case: 'CosNaming_NamingContext_NotEmpty'
+%% Description:
+%%-----------------------------------------------------------------
+'CosNaming_NamingContext_NotEmpty'(doc) -> [""];
+'CosNaming_NamingContext_NotEmpty'(suite) -> [];
+'CosNaming_NamingContext_NotEmpty'(_) ->
+ ?match(true, orber_tc:check_tc('CosNaming_NamingContext_NotEmpty':tc())),
+ ?match("IDL:omg.org/CosNaming/NamingContext/NotEmpty:1.0", 'CosNaming_NamingContext_NotEmpty':id()),
+ ?match("CosNaming_NamingContext_NotEmpty", 'CosNaming_NamingContext_NotEmpty':name()),
+ ok.
+
+%%-----------------------------------------------------------------
+%% Test Case: 'CosNaming_NamingContext_NotFound'
+%% Description:
+%%-----------------------------------------------------------------
+'CosNaming_NamingContext_NotFound'(doc) -> [""];
+'CosNaming_NamingContext_NotFound'(suite) -> [];
+'CosNaming_NamingContext_NotFound'(_) ->
+ ?match(true, orber_tc:check_tc('CosNaming_NamingContext_NotFound':tc())),
+ ?match("IDL:omg.org/CosNaming/NamingContext/NotFound:1.0", 'CosNaming_NamingContext_NotFound':id()),
+ ?match("CosNaming_NamingContext_NotFound", 'CosNaming_NamingContext_NotFound':name()),
+ ok.
+
+%%-----------------------------------------------------------------
+%% Test Case: 'CosNaming_BindingIterator'
+%% Description:
+%%-----------------------------------------------------------------
+'CosNaming_BindingIterator'(doc) -> [""];
+'CosNaming_BindingIterator'(suite) -> [];
+'CosNaming_BindingIterator'(_) ->
+ ?nomatch(undefined, 'CosNaming_BindingIterator':oe_tc(next_one)),
+ ?nomatch(undefined, 'CosNaming_BindingIterator':oe_tc(next_n)),
+ ?nomatch(undefined, 'CosNaming_BindingIterator':oe_tc(destroy)),
+ ?match(undefined, 'CosNaming_BindingIterator':oe_tc(undefined)),
+ ?match([_|_], 'CosNaming_BindingIterator':oe_get_interface()),
+ ?match("IDL:omg.org/CosNaming/BindingIterator:1.0",
+ 'CosNaming_BindingIterator':typeID()),
+ check_tc('CosNaming_BindingIterator':oe_get_interface()),
+ ?match(true, 'CosNaming_BindingIterator':oe_is_a('CosNaming_BindingIterator':typeID())),
+ ?match(false, 'CosNaming_BindingIterator':oe_is_a("wrong")),
+ ok.
+
+
+%%-----------------------------------------------------------------
+%% Test Case: 'CosNaming_NamingContext'
+%% Description:
+%%-----------------------------------------------------------------
+'CosNaming_NamingContext'(doc) -> [""];
+'CosNaming_NamingContext'(suite) -> [];
+'CosNaming_NamingContext'(_) ->
+ ?nomatch(undefined, 'CosNaming_NamingContext':oe_tc(bind)),
+ ?nomatch(undefined, 'CosNaming_NamingContext':oe_tc(rebind)),
+ ?nomatch(undefined, 'CosNaming_NamingContext':oe_tc(bind_context)),
+ ?nomatch(undefined, 'CosNaming_NamingContext':oe_tc(rebind_context)),
+ ?nomatch(undefined, 'CosNaming_NamingContext':oe_tc(resolve)),
+ ?nomatch(undefined, 'CosNaming_NamingContext':oe_tc(unbind)),
+ ?nomatch(undefined, 'CosNaming_NamingContext':oe_tc(new_context)),
+ ?nomatch(undefined, 'CosNaming_NamingContext':oe_tc(bind_new_context)),
+ ?nomatch(undefined, 'CosNaming_NamingContext':oe_tc(destroy)),
+ ?nomatch(undefined, 'CosNaming_NamingContext':oe_tc(list)),
+ ?match(undefined, 'CosNaming_NamingContext':oe_tc(undefined)),
+ ?match([_|_], 'CosNaming_NamingContext':oe_get_interface()),
+ ?match("IDL:omg.org/CosNaming/NamingContext:1.0",
+ 'CosNaming_NamingContext':typeID()),
+ check_tc('CosNaming_NamingContext':oe_get_interface()),
+ ?match(true, 'CosNaming_NamingContext':oe_is_a('CosNaming_NamingContext':typeID())),
+ ?match(false, 'CosNaming_NamingContext':oe_is_a("wrong")),
+ ok.
+
+
+%%-----------------------------------------------------------------
+%% Test Case: 'CosNaming_NamingContexExt'
+%% Description:
+%%-----------------------------------------------------------------
+'CosNaming_NamingContextExt'(doc) -> [""];
+'CosNaming_NamingContextExt'(suite) -> [];
+'CosNaming_NamingContextExt'(_) ->
+ ?nomatch(undefined, 'CosNaming_NamingContextExt':oe_tc(to_string)),
+ ?nomatch(undefined, 'CosNaming_NamingContextExt':oe_tc(to_name)),
+ ?nomatch(undefined, 'CosNaming_NamingContextExt':oe_tc(to_url)),
+ ?nomatch(undefined, 'CosNaming_NamingContextExt':oe_tc(resolve_str)),
+ ?nomatch(undefined, 'CosNaming_NamingContextExt':oe_tc(bind)),
+ ?nomatch(undefined, 'CosNaming_NamingContextExt':oe_tc(rebind)),
+ ?nomatch(undefined, 'CosNaming_NamingContextExt':oe_tc(bind_context)),
+ ?nomatch(undefined, 'CosNaming_NamingContextExt':oe_tc(rebind_context)),
+ ?nomatch(undefined, 'CosNaming_NamingContextExt':oe_tc(new_context)),
+ ?nomatch(undefined, 'CosNaming_NamingContextExt':oe_tc(bind_new_context)),
+ ?nomatch(undefined, 'CosNaming_NamingContextExt':oe_tc(destroy)),
+ ?nomatch(undefined, 'CosNaming_NamingContextExt':oe_tc(list)),
+ ?match(undefined, 'CosNaming_NamingContextExt':oe_tc(undefined)),
+ ?match([_|_], 'CosNaming_NamingContextExt':oe_get_interface()),
+ ?match("IDL:omg.org/CosNaming/NamingContextExt:1.0",
+ 'CosNaming_NamingContextExt':typeID()),
+ check_tc('CosNaming_NamingContextExt':oe_get_interface()),
+ ?match(true, 'CosNaming_NamingContextExt':oe_is_a('CosNaming_NamingContextExt':typeID())),
+ ?match(true, 'CosNaming_NamingContextExt':oe_is_a('CosNaming_NamingContext':typeID())),
+ ?match(false, 'CosNaming_NamingContextExt':oe_is_a("wrong")),
+ ok.
+
+
+%%-----------------------------------------------------------------
+%% MISC functions
+%%-----------------------------------------------------------------
+check_tc([]) ->
+ ok;
+check_tc([{Op, {RetType, InParameters, OutParameters}}|T]) ->
+ io:format("checked - ~s~n", [Op]),
+ lists:all(?checktc(Op), [RetType|InParameters]),
+ lists:all(?checktc(Op), OutParameters),
+ check_tc(T).
+
+
diff --git a/lib/orber/test/idl_output/.gitignore b/lib/orber/test/idl_output/.gitignore
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/lib/orber/test/idl_output/.gitignore
diff --git a/lib/orber/test/iiop_module_do_test_impl.erl b/lib/orber/test/iiop_module_do_test_impl.erl
new file mode 100644
index 0000000000..bf171a3097
--- /dev/null
+++ b/lib/orber/test/iiop_module_do_test_impl.erl
@@ -0,0 +1,112 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 1998-2009. All Rights Reserved.
+%%
+%% The contents of this file are subject to the Erlang Public License,
+%% Version 1.1, (the "License"); you may not use this file except in
+%% compliance with the License. You should have received a copy of the
+%% Erlang Public License along with this software. If not, it can be
+%% retrieved online at http://www.erlang.org/.
+%%
+%% Software distributed under the License is distributed on an "AS IS"
+%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+%% the License for the specific language governing rights and limitations
+%% under the License.
+%%
+%% %CopyrightEnd%
+%%
+%%
+
+-module(iiop_module_do_test_impl).
+
+
+-export([run_all/3, run_userexception/2, run_systemexception/2]).
+-export([createTestContext/0]).
+
+-export([start/0, stop/0]).
+-export([init/1, terminate/2]).
+
+
+init(_) ->
+ {ok, []}.
+
+terminate(Reason, _State) ->
+ io:format("~p terminating with reason ~p~n", [?MODULE, Reason]),
+ ok.
+
+createTestContext() ->
+ NS = corba:resolve_initial_references("NameService"),
+ NC = lname_component:set_id(lname_component:create(), "iiop_test"),
+ N = lname:insert_component(lname:create(), 1, NC),
+ 'CosNaming_NamingContext':bind_new_context(NS, N).
+
+start() ->
+ SFok = corba:create('iiop_module_do_test', "IDL:iiop_module/do_test:1.0"),
+ NS = corba:resolve_initial_references("NameService"),
+ NC1 = lname_component:set_id(lname_component:create(), "iiop_test"),
+ NC2 = lname_component:set_id(lname_component:create(), "erl_dotest"),
+ N = lname:insert_component(lname:create(), 1, NC1),
+ N1 = lname:insert_component(N, 2, NC2),
+ 'CosNaming_NamingContext':bind(NS, N1, SFok),
+ SFok.
+
+stop() ->
+ NS = corba:resolve_initial_references("NameService"),
+ NC1 = lname_component:set_id(lname_component:create(), "iiop_test"),
+ NC2 = lname_component:set_id(lname_component:create(), "erl_dotest"),
+ N = lname:insert_component(lname:create(), 1, NC1),
+ N1 = lname:insert_component(N, 2, NC2),
+ 'CosNaming_NamingContext':unbind(NS, N1).
+
+run_all(S, X, TL) ->
+ ok = iiop_module_test:send_void(X),
+ {tk_short, P1} = lists:nth(1, TL),
+ {R1, IO1, O1} = iiop_module_test:send_short(X, P1, P1),
+ RL1= [{tk_short, R1}],
+ IOL1= [{tk_short, IO1}],
+ OL1= [{tk_short, O1}],
+ {tk_ushort, P2} = lists:nth(2, TL),
+ {R2, IO2, O2} = iiop_module_test:send_ushort(X, P2, P2),
+ RL2= [{tk_ushort, R2}|RL1],
+ IOL2= [{tk_ushort, IO2}|IOL1],
+ OL2= [{tk_ushort, O2}|OL1],
+ {tk_long, P3} = lists:nth(3, TL),
+ {R3, IO3, O3} = iiop_module_test:send_long(X, P3, P3),
+ RL3= [{tk_long, R3}|RL2],
+ IOL3= [{tk_long, IO3}|IOL2],
+ OL3= [{tk_long, O3}|OL2],
+ {tk_ulong, P4} = lists:nth(4, TL),
+ {R4, IO4, O4} = iiop_module_test:send_ulong(X, P4, P4),
+ RL4= [{tk_ulong, R4}|RL3],
+ IOL4= [{tk_ulong, IO4}|IOL3],
+ OL4= [{tk_ulong, O4}|OL3],
+ {tk_float, P5} = lists:nth(5, TL),
+ {R5, IO5, O5} = iiop_module_test:send_float(X, P5, P5),
+ RL5= [{tk_float, R5}|RL4],
+ IOL5= [{tk_float, IO5}|IOL4],
+ OL5= [{tk_float, O5}|OL4],
+ {tk_double, P6} = lists:nth(6, TL),
+ {R6, IO6, O6} = iiop_module_test:send_double(X, P6, P6),
+ RL6= [{tk_double, R6}|RL5],
+ IOL6= [{tk_double, IO6}|IOL5],
+ OL6= [{tk_double, O6}|OL5],
+ {tk_boolean, P7} = lists:nth(7, TL),
+ {R7, IO7, O7} = iiop_module_test:send_boolean(X, P7, P7),
+ RL7= [{tk_boolean, R7}|RL6],
+ IOL7= [{tk_boolean, IO7}|IOL6],
+ OL7= [{tk_boolean, O7}|OL6],
+ {tk_char, P8} = lists:nth(8, TL),
+ {R8, IO8, O8} = iiop_module_test:send_char(X, P8, P8),
+ RL= [{tk_char, R8} |RL7],
+ IOL= [{tk_char, IO8} |IOL7],
+ OL= [{tk_char, O8} |OL7],
+ {{lists:reverse(RL),lists:reverse(IOL),lists:reverse(OL)}, S}.
+
+run_systemexception(S, X) ->
+ iiop_module_test:ret_systemexception(X),
+ {ok, S}.
+
+run_userexception(S, X) ->
+ iiop_module_test:ret_userexception(X),
+ {ok, S}.
diff --git a/lib/orber/test/iiop_module_test_impl.erl b/lib/orber/test/iiop_module_test_impl.erl
new file mode 100644
index 0000000000..fe334e1b26
--- /dev/null
+++ b/lib/orber/test/iiop_module_test_impl.erl
@@ -0,0 +1,128 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 1998-2009. All Rights Reserved.
+%%
+%% The contents of this file are subject to the Erlang Public License,
+%% Version 1.1, (the "License"); you may not use this file except in
+%% compliance with the License. You should have received a copy of the
+%% Erlang Public License along with this software. If not, it can be
+%% retrieved online at http://www.erlang.org/.
+%%
+%% Software distributed under the License is distributed on an "AS IS"
+%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+%% the License for the specific language governing rights and limitations
+%% under the License.
+%%
+%% %CopyrightEnd%
+%%
+%%
+
+-module(iiop_module_test_impl).
+-include_lib("orber/include/corba.hrl").
+-include("idl_output/iiop_module.hrl").
+
+
+-export([send_void/1, send_short/3, send_ushort/3]).
+-export([send_long/3, send_ulong/3, send_float/3]).
+-export([send_double/3, send_boolean/3, send_char/3]).
+-export([send_octet/3, send_any/3, send_object/3]).
+-export([send_struct1/3, send_union1/3, send_enum1/3]).
+-export([send_string/3, send_sequence1/3, send_array1/3]).
+-export([ret_systemexception/1, ret_userexception/1]).
+
+
+
+-export([start/0, stop/0]).
+-export([init/1, terminate/2]).
+
+
+init(_) ->
+ {ok, []}.
+
+terminate(Reason, _State) ->
+ io:format("~p terminating with reason ~p~n", [?MODULE, Reason]),
+ ok.
+
+
+start() ->
+ SFok = corba:create('iiop_module_test', "IDL:iiop_module/test:1.0"),
+ NS = corba:resolve_initial_references("NameService"),
+ NC1 = lname_component:set_id(lname_component:create(), "iiop_test"),
+ NC2 = lname_component:set_id(lname_component:create(), "erl_test"),
+ N = lname:insert_component(lname:create(), 1, NC1),
+ N1 = lname:insert_component(N, 2, NC2),
+ 'CosNaming_NamingContext':bind(NS, N1, SFok),
+ SFok.
+
+stop() ->
+ NS = corba:resolve_initial_references("NameService"),
+ NC1 = lname_component:set_id(lname_component:create(), "iiop_test"),
+ NC2 = lname_component:set_id(lname_component:create(), "erl_test"),
+ N = lname:insert_component(lname:create(), 1, NC1),
+ N1 = lname:insert_component(N, 2, NC2),
+ 'CosNaming_NamingContext':unbind(NS, N1).
+
+
+
+send_void(S) ->
+ {ok, S}.
+
+send_short(S, P1, P2) ->
+ {{P1, P1, P2}, S}.
+
+send_ushort(S, P1, P2) ->
+ {{P1, P1, P2}, S}.
+
+send_long(S, P1, P2) ->
+ {{P1, P1, P2}, S}.
+
+send_ulong(S, P1, P2) ->
+ {{P1, P1, P2}, S}.
+
+send_float(S, P1, P2) ->
+ {{P1, P1, P2}, S}.
+
+send_double(S, P1, P2) ->
+ {{P1, P1, P2}, S}.
+
+send_boolean(S, P1, P2) ->
+ {{P1, P1, P2}, S}.
+
+send_char(S, P1, P2) ->
+ {{P1, P1, P2}, S}.
+
+send_octet(S, P1, P2) ->
+ {{P1, P1, P2}, S}.
+
+send_any(S, P1, P2) ->
+ {{P1, P1, P2}, S}.
+
+send_object(S, P1, P2) ->
+ {{P1, P1, P2}, S}.
+
+send_struct1(S, P1, P2) ->
+ {{P1, P1, P2}, S}.
+
+send_union1(S, P1, P2) ->
+ {{P1, P1, P2}, S}.
+
+send_enum1(S, P1, P2) ->
+ {{P1, P1, P2}, S}.
+
+send_string(S, P1, P2) ->
+ {{P1, P1, P2}, S}.
+
+send_sequence1(S, P1, P2) ->
+ {{P1, P1, P2}, S}.
+
+send_array1(S, P1, P2) ->
+ {{P1, P1, P2}, S}.
+
+ret_systemexception(S) ->
+ throw(#'BAD_PARAM'{}),
+ {ok, S}.
+
+ret_userexception(S) ->
+ throw(#iiop_module_Except1{why="not readable",rest_of_name=["foo", "bar"]}),
+ {ok, S}.
diff --git a/lib/orber/test/iiop_test.idl b/lib/orber/test/iiop_test.idl
new file mode 100644
index 0000000000..339678106e
--- /dev/null
+++ b/lib/orber/test/iiop_test.idl
@@ -0,0 +1,111 @@
+//
+// %CopyrightBegin%
+//
+// 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%
+//
+#include "cos_naming.idl"
+
+module iiop_module
+{
+
+ typedef long Array1[10];
+
+ enum Enum1 {horse, pig, cow};
+
+ typedef sequence<long> Sequence1;
+
+ typedef Sequence1 Sequence2;
+
+ struct Struct1 {
+ string s;
+ unsigned short us;
+ unsigned long ul;
+ };
+
+ union Union1 switch (short) {
+ case 0: short First;
+ case 1: string Second;
+ case 2: char Third;
+ };
+
+ exception Except1 {
+ string why;
+ sequence <string> rest_of_name;
+ };
+
+ typedef sequence<any> test_values;
+ struct test_retval {
+ test_values R;
+ test_values InOut;
+ test_values Out;
+ };
+
+ interface test;
+
+ interface do_test {
+ void run_systemexception(in test x)
+ raises(CosNaming::NamingContext::NotFound,
+ CosNaming::NamingContext::CannotProceed,
+ CosNaming::NamingContext::InvalidName);
+ void run_userexception(in test x)
+ raises(iiop_module::Except1,
+ CosNaming::NamingContext::NotFound,
+ CosNaming::NamingContext::CannotProceed,
+ CosNaming::NamingContext::InvalidName);
+ test_retval run_all(in test x, in test_values tlist)
+ raises(iiop_module::Except1,
+ CosNaming::NamingContext::NotFound,
+ CosNaming::NamingContext::CannotProceed,
+ CosNaming::NamingContext::InvalidName);
+ };
+
+ interface test {
+ // Function to run all tests from java to erlang
+ // and return the answers
+ // Primitive types
+ void send_void();
+ short send_short(in short p1, inout short p2, out short p3);
+ unsigned short send_ushort(in unsigned short p1, inout unsigned short p2,
+ out unsigned short p3);
+ long send_long(in long p1, inout long p2, out long p3);
+ unsigned long send_ulong(in unsigned long p1, inout unsigned long p2,
+ out unsigned long p3);
+ float send_float(in float p1, inout float p2, out float p3);
+ double send_double(in double p1, inout double p2, out double p3);
+ boolean send_boolean(in boolean p1, inout boolean p2, out boolean p3);
+ char send_char(in char p1, inout char p2, out char p3);
+ octet send_octet(in octet p1, inout octet p2, out octet p3);
+ any send_any(in any p1, inout any p2, out any p3);
+ Object send_object(in Object p1, inout Object p2, out Object p3);
+ // TypeCode send_typecode(in TypeCode p1, inout TypeCode p2, out TypeCode p3);
+ // Principal send_principal(in Principal p); //tested in every request
+
+ // Complex types
+ Struct1 send_struct1(in Struct1 p1, inout Struct1 p2, out Struct1 p3);
+ Union1 send_union1(in Union1 p1, inout Union1 p2, out Union1 p3);
+ Enum1 send_enum1(in Enum1 p1, inout Enum1 p2, out Enum1 p3);
+ string send_string(in string p1, inout string p2, out string p3);
+ Sequence1 send_sequence1(in Sequence1 p1, inout Sequence1 p2,
+ out Sequence1 p3);
+ Array1 send_array1(in Array1 p1, inout Array1 p2, out Array1 p3);
+
+ void ret_systemexception();
+ void ret_userexception() raises(iiop_module::Except1);
+
+
+ };
+
+};
diff --git a/lib/orber/test/iiop_test_impl.erl b/lib/orber/test/iiop_test_impl.erl
new file mode 100644
index 0000000000..fd92109c09
--- /dev/null
+++ b/lib/orber/test/iiop_test_impl.erl
@@ -0,0 +1,34 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 1998-2009. All Rights Reserved.
+%%
+%% The contents of this file are subject to the Erlang Public License,
+%% Version 1.1, (the "License"); you may not use this file except in
+%% compliance with the License. You should have received a copy of the
+%% Erlang Public License along with this software. If not, it can be
+%% retrieved online at http://www.erlang.org/.
+%%
+%% Software distributed under the License is distributed on an "AS IS"
+%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+%% the License for the specific language governing rights and limitations
+%% under the License.
+%%
+%% %CopyrightEnd%
+%%
+%%
+-module(iiop_test_impl).
+-include_lib("orber/include/corba.hrl").
+-include_lib("orber/test/iiop_test.hrl").
+-export([]).
+
+
+init(Env) ->
+ {ok, []}.
+
+terminate(From, Reason) ->
+ ok.
+
+send_void(State) ->
+ {ok, State}.
+
diff --git a/lib/orber/test/interceptors_SUITE.erl b/lib/orber/test/interceptors_SUITE.erl
new file mode 100644
index 0000000000..27e23a9433
--- /dev/null
+++ b/lib/orber/test/interceptors_SUITE.erl
@@ -0,0 +1,338 @@
+%%-----------------------------------------------------------------
+%%
+%% %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%
+%%
+%%
+%%-----------------------------------------------------------------
+%% File : interceptors_SUITE.erl
+%% Purpose :
+%%-----------------------------------------------------------------
+
+-module(interceptors_SUITE).
+
+-include("test_server.hrl").
+-include_lib("orber/include/corba.hrl").
+-include_lib("orber/src/orber_iiop.hrl").
+
+-define(default_timeout, ?t:minutes(3)).
+
+-define(match(ExpectedRes, Expr),
+ fun() ->
+ AcTuAlReS = (catch (Expr)),
+ case AcTuAlReS of
+ ExpectedRes ->
+ io:format("------ CORRECT RESULT ------~n~p~n",
+ [AcTuAlReS]),
+ AcTuAlReS;
+ _ ->
+ io:format("###### ERROR ERROR ######~n~p~n",
+ [AcTuAlReS]),
+ ?line exit(AcTuAlReS)
+ end
+ end()).
+
+-define(nomatch(Not, Expr),
+ fun() ->
+ AcTuAlReS = (catch (Expr)),
+ case AcTuAlReS of
+ Not ->
+ io:format("###### ERROR ERROR ######~n~p~n",
+ [AcTuAlReS]),
+ ?line exit(AcTuAlReS);
+ _ ->
+ io:format("------ CORRECT RESULT ------~n~p~n",
+ [AcTuAlReS]),
+ AcTuAlReS
+ end
+ end()).
+
+
+%%-----------------------------------------------------------------
+%% External exports
+%%-----------------------------------------------------------------
+-export([all/1]).
+
+%%-----------------------------------------------------------------
+%% Internal exports
+%%-----------------------------------------------------------------
+-export([in_reply/6, out_request/6]).
+-compile(export_all).
+
+%%-----------------------------------------------------------------
+%% Func: all/1
+%% Args:
+%% Returns:
+%%-----------------------------------------------------------------
+all(doc) -> ["This suite is for testing Orber Interceptors"];
+all(suite) ->
+ [local_pseudo, local_default, local_local, local_global].
+
+%%-----------------------------------------------------------------
+%% Init and cleanup functions.
+%%-----------------------------------------------------------------
+init_per_testcase(_Case, Config) ->
+ ?line Dog=test_server:timetrap(?default_timeout),
+ Path = code:which(?MODULE),
+ code:add_pathz(filename:join(filename:dirname(Path), "idl_output")),
+ corba:orb_init([{flags, (?ORB_ENV_USE_PI bor ?ORB_ENV_LOCAL_TYPECHECKING)},
+ {local_interceptors, {native, [?MODULE]}}]),
+ orber:jump_start(2945),
+ oe_orber_test_server:oe_register(),
+ [{watchdog, Dog}|Config].
+
+
+fin_per_testcase(_Case, Config) ->
+ oe_orber_test_server:oe_unregister(),
+ orber:jump_stop(),
+ Path = code:which(?MODULE),
+ code:del_path(filename:join(filename:dirname(Path), "idl_output")),
+ Dog = ?config(watchdog, Config),
+ test_server:timetrap_cancel(Dog),
+ ok.
+
+%%-----------------------------------------------------------------
+%% Test Case: local_pseudo
+%% Description:
+%%-----------------------------------------------------------------
+local_pseudo(doc) -> [""];
+local_pseudo(suite) -> [];
+local_pseudo(_) ->
+ ?match({native, [?MODULE]}, orber:get_local_interceptors()),
+ %% Global settings
+ Obj1 = orber_test_server:oe_create(state,[{pseudo,true}]),
+ Result11 = orber_test_server:testing_iiop_ushort(Obj1, ?USHORTMAX),
+ ?match([?USHORTMAX], put(out_request, undefined)),
+ ?match(Result11, put(in_reply, undefined)),
+
+ Result12 = ?match({'EXCEPTION',_},
+ orber_test_server:testing_iiop_ushort(Obj1, ?USHORTMAX+1)),
+ ?match([(?USHORTMAX+1)], put(out_request, undefined)),
+ ?nomatch(Result12, put(in_reply, undefined)),
+
+ Result13 = orber_test_server:testing_iiop_oneway_delay(Obj1, 0),
+ ?match([0], put(out_request, undefined)),
+ ?nomatch(Result13, put(in_reply, undefined)),
+
+ Result14 = ?match({'EXCEPTION', _},
+ orber_test_server:raise_local_exception(Obj1)),
+ ?match([], put(out_request, undefined)),
+ ?match(Result14, put(in_reply, undefined)),
+
+ Result15 = ?match({'EXCEPTION',_}, orber_test_server:stop_brutal(Obj1)),
+ ?match([], put(out_request, undefined)),
+ ?match(Result15, put(in_reply, undefined)),
+
+ %% Per-object
+ Obj2 = orber_test_server:oe_create(state,[{pseudo,true},
+ {local_interceptors, false}]),
+
+ Result21 = orber_test_server:testing_iiop_ushort(Obj2, ?USHORTMAX),
+ ?nomatch([?USHORTMAX], put(out_request, undefined)),
+ ?nomatch(Result21, put(in_reply, undefined)),
+
+ Obj3 = orber_test_server:oe_create(state,[{pseudo,true},
+ {local_interceptors, true}]),
+
+ Result31 = orber_test_server:testing_iiop_ushort(Obj3, ?USHORTMAX),
+ ?match([?USHORTMAX], put(out_request, undefined)),
+ ?match(Result31, put(in_reply, undefined)),
+
+ ok.
+
+%%-----------------------------------------------------------------
+%% Test Case: local_default
+%% Description:
+%%-----------------------------------------------------------------
+local_default(doc) -> [""];
+local_default(suite) -> [];
+local_default(_) ->
+ ?match({native, [?MODULE]}, orber:get_local_interceptors()),
+ %% Global settings
+ Obj1 = orber_test_server:oe_create(state, []),
+ Result11 = orber_test_server:testing_iiop_ushort(Obj1, ?USHORTMAX),
+ ?match([?USHORTMAX], put(out_request, undefined)),
+ ?match(Result11, put(in_reply, undefined)),
+
+ Result12 = ?match({'EXCEPTION',_},
+ orber_test_server:testing_iiop_ushort(Obj1, ?USHORTMAX+1)),
+ ?match([(?USHORTMAX+1)], put(out_request, undefined)),
+ ?nomatch(Result12, put(in_reply, undefined)),
+
+ Result13 = orber_test_server:testing_iiop_oneway_delay(Obj1, 0),
+ ?match([0], put(out_request, undefined)),
+ ?nomatch(Result13, put(in_reply, undefined)),
+
+ Result14 = ?match({'EXCEPTION', _},
+ orber_test_server:raise_local_exception(Obj1)),
+ ?match([], put(out_request, undefined)),
+ ?match(Result14, put(in_reply, undefined)),
+
+ Result15 = ?match({'EXCEPTION',_}, orber_test_server:stop_brutal(Obj1)),
+ ?match([], put(out_request, undefined)),
+ ?match(Result15, put(in_reply, undefined)),
+
+
+ %% Per-object
+ Obj2 = orber_test_server:oe_create(state,[{local_interceptors, false}]),
+
+ Result21 = orber_test_server:testing_iiop_ushort(Obj2, ?USHORTMAX),
+ ?nomatch([?USHORTMAX], put(out_request, undefined)),
+ ?nomatch(Result21, put(in_reply, undefined)),
+ corba:dispose(Obj2),
+
+ Obj3 = orber_test_server:oe_create(state,[{local_interceptors, true}]),
+
+ Result31 = orber_test_server:testing_iiop_ushort(Obj3, ?USHORTMAX),
+ ?match([?USHORTMAX], put(out_request, undefined)),
+ ?match(Result31, put(in_reply, undefined)),
+ corba:dispose(Obj3),
+ ok.
+
+%%-----------------------------------------------------------------
+%% Test Case: local_local
+%% Description:
+%%-----------------------------------------------------------------
+local_local(doc) -> [""];
+local_local(suite) -> [];
+local_local(_) ->
+ ?match({native, [?MODULE]}, orber:get_local_interceptors()),
+ %% Global settings
+ Obj1 = orber_test_server:oe_create(state, [{regname, {local, regname}}]),
+ Result11 = orber_test_server:testing_iiop_ushort(Obj1, ?USHORTMAX),
+ ?match([?USHORTMAX], put(out_request, undefined)),
+ ?match(Result11, put(in_reply, undefined)),
+
+ Result12 = ?match({'EXCEPTION',_},
+ orber_test_server:testing_iiop_ushort(Obj1, ?USHORTMAX+1)),
+ ?match([(?USHORTMAX+1)], put(out_request, undefined)),
+ ?nomatch(Result12, put(in_reply, undefined)),
+
+ Result13 = orber_test_server:testing_iiop_oneway_delay(Obj1, 0),
+ ?match([0], put(out_request, undefined)),
+ ?nomatch(Result13, put(in_reply, undefined)),
+
+ Result14 = ?match({'EXCEPTION', _},
+ orber_test_server:raise_local_exception(Obj1)),
+ ?match([], put(out_request, undefined)),
+ ?match(Result14, put(in_reply, undefined)),
+
+ Result15 = ?match({'EXCEPTION',_}, orber_test_server:stop_brutal(Obj1)),
+ ?match([], put(out_request, undefined)),
+ ?match(Result15, put(in_reply, undefined)),
+
+ %% Per-object
+ Obj2 = orber_test_server:oe_create(state,[{regname, {local, regname}},
+ {local_interceptors, false}]),
+
+ Result21 = orber_test_server:testing_iiop_ushort(Obj2, ?USHORTMAX),
+ ?nomatch([?USHORTMAX], put(out_request, undefined)),
+ ?nomatch(Result21, put(in_reply, undefined)),
+ corba:dispose(Obj2),
+
+ Obj3 = orber_test_server:oe_create(state,[{regname, {local, regname}},
+ {local_interceptors, true}]),
+
+ Result31 = orber_test_server:testing_iiop_ushort(Obj3, ?USHORTMAX),
+ ?match([?USHORTMAX], put(out_request, undefined)),
+ ?match(Result31, put(in_reply, undefined)),
+ corba:dispose(Obj3),
+ ok.
+
+%%-----------------------------------------------------------------
+%% Test Case: local_global
+%% Description:
+%%-----------------------------------------------------------------
+local_global(doc) -> [""];
+local_global(suite) -> [];
+local_global(_) ->
+ ?match({native, [?MODULE]}, orber:get_local_interceptors()),
+ %% Global settings
+ Obj1 = orber_test_server:oe_create(state, [{regname, {global, regname}}]),
+ Result11 = orber_test_server:testing_iiop_ushort(Obj1, ?USHORTMAX),
+ ?match([?USHORTMAX], put(out_request, undefined)),
+ ?match(Result11, put(in_reply, undefined)),
+
+ Result12 = ?match({'EXCEPTION',_},
+ orber_test_server:testing_iiop_ushort(Obj1, ?USHORTMAX+1)),
+ ?match([(?USHORTMAX+1)], put(out_request, undefined)),
+ ?nomatch(Result12, put(in_reply, undefined)),
+
+ Result13 = orber_test_server:testing_iiop_oneway_delay(Obj1, 0),
+ ?match([0], put(out_request, undefined)),
+ ?nomatch(Result13, put(in_reply, undefined)),
+
+ Result14 = ?match({'EXCEPTION', _},
+ orber_test_server:raise_local_exception(Obj1)),
+ ?match([], put(out_request, undefined)),
+ ?match(Result14, put(in_reply, undefined)),
+
+ Result15 = ?match({'EXCEPTION',_}, orber_test_server:stop_brutal(Obj1)),
+ ?match([], put(out_request, undefined)),
+ ?match(Result15, put(in_reply, undefined)),
+
+ %% Per-object
+ Obj2 = orber_test_server:oe_create(state,[{regname, {global, regname}},
+ {local_interceptors, false}]),
+
+ Result21 = orber_test_server:testing_iiop_ushort(Obj2, ?USHORTMAX),
+ ?nomatch([?USHORTMAX], put(out_request, undefined)),
+ ?nomatch(Result21, put(in_reply, undefined)),
+ corba:dispose(Obj2),
+
+ Obj3 = orber_test_server:oe_create(state,[{regname, {global, regname}},
+ {local_interceptors, true}]),
+
+ Result31 = orber_test_server:testing_iiop_ushort(Obj3, ?USHORTMAX),
+ ?match([?USHORTMAX], put(out_request, undefined)),
+ ?match(Result31, put(in_reply, undefined)),
+ corba:dispose(Obj3),
+ ok.
+
+
+
+
+%%-----------------------------------------------------------------
+%% Local functions
+%%-----------------------------------------------------------------
+%%-----------------------------------------------------------------
+%% function : in_reply
+%%-----------------------------------------------------------------
+in_reply(Ref, _ObjKey, Ctx, Op, Reply, _Args) ->
+ error_logger:info_msg("=============== in_reply =================
+Connection: ~p
+Operation : ~p
+Reply : ~p
+Context : ~p
+==========================================~n",
+ [Ref, Op, Reply, Ctx]),
+ put(in_reply, Reply),
+ {Reply, "NewArgs"}.
+
+%%-----------------------------------------------------------------
+%% function : out_request
+%%-----------------------------------------------------------------
+out_request(Ref, _ObjKey, Ctx, Op, Params, _Args) ->
+ error_logger:info_msg("=============== out_request ==============
+Connection: ~p
+Operation : ~p
+Parameters: ~p
+Context : ~p
+==========================================~n",
+ [Ref, Op, Params, Ctx]),
+ put(out_request, Params),
+ {Params, "NewArgs"}.
diff --git a/lib/orber/test/iop_ior_10_SUITE.erl b/lib/orber/test/iop_ior_10_SUITE.erl
new file mode 100644
index 0000000000..1000c7f113
--- /dev/null
+++ b/lib/orber/test/iop_ior_10_SUITE.erl
@@ -0,0 +1,167 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 1999-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%
+%%
+%%
+%%-----------------------------------------------------------------
+%%
+%% Description:
+%% Test suite for the IOR functions
+%%
+%%-----------------------------------------------------------------
+-module(iop_ior_10_SUITE).
+
+-include("test_server.hrl").
+-include_lib("orber/src/orber_iiop.hrl").
+
+-define(default_timeout, ?t:minutes(3)).
+
+%%-----------------------------------------------------------------
+%% External exports
+%%-----------------------------------------------------------------
+-export([all/1]).
+
+%%-----------------------------------------------------------------
+%% Internal exports
+%%-----------------------------------------------------------------
+-export([]).
+-compile(export_all).
+
+%%-----------------------------------------------------------------
+%% Func: all/1
+%% Args:
+%% Returns:
+%%-----------------------------------------------------------------
+all(doc) -> ["Description", "more description"];
+all(suite) ->
+ [encoding, create_and_get_ops].
+
+%%-----------------------------------------------------------------
+%% Init and cleanup functions.
+%%-----------------------------------------------------------------
+
+init_per_testcase(_Case, Config) ->
+ ?line Dog=test_server:timetrap(?default_timeout),
+ [{watchdog, Dog}|Config].
+
+
+fin_per_testcase(_Case, Config) ->
+ Dog = ?config(watchdog, Config),
+ test_server:timetrap_cancel(Dog),
+ ok.
+
+%%-----------------------------------------------------------------
+%% Test Case: IOR encoding test
+%% Description: Just testing the string_encoding function because the
+%% other encodings is called from them.
+%%-----------------------------------------------------------------
+encoding(doc) -> ["Description", "more description"];
+encoding(suite) -> [];
+encoding(_) ->
+ V = #'IIOP_Version'{major=1,minor=0},
+ M0 = 'Module_Interface',
+ T0 = "IDL:Module/Interface:1.0",
+ H0 = "my.hostname.org",
+ P0 = 4040,
+ N0 = 'name',
+ ?line O0 = corba_fake_mk_objkey(M0, registered, N0),
+ PB0 = #'IIOP_ProfileBody_1_0'{iiop_version=V, host=H0, port=P0, object_key=O0},
+ TP0 = #'IOP_TaggedProfile'{tag=?TAG_INTERNET_IOP, profile_data=PB0},
+ S0 = #'IOP_IOR'{type_id=T0, profiles=[TP0]},
+ N1 = list_to_pid("<0.100.0>"),
+ ?line O1 = corba_fake_mk_objkey(M0, key, N1),
+ PB1 = #'IIOP_ProfileBody_1_0'{iiop_version=V, host=H0, port=P0, object_key=O1},
+ TP1 = #'IOP_TaggedProfile'{tag=?TAG_INTERNET_IOP, profile_data=PB1},
+ S1 = #'IOP_IOR'{type_id=T0, profiles=[TP1]},
+ O2 = "This is an external objectkey",
+ PB2 = #'IIOP_ProfileBody_1_0'{iiop_version=V, host=H0, port=P0, object_key=O2},
+ TP2 = #'IOP_TaggedProfile'{tag=?TAG_INTERNET_IOP, profile_data=PB2},
+ S2 = #'IOP_IOR'{type_id=T0, profiles=[TP2]},
+ ?line C0 = iop_ior:string_code(S0),
+ ?line {S0, <<>>, _} = iop_ior:string_decode(C0),
+ ?line C1 = iop_ior:string_code(S1),
+ ?line {S1, <<>>, _} = iop_ior:string_decode(C1),
+ ?line C2 = iop_ior:string_code(S2),
+ ?line {S2, <<>>, _} = iop_ior:string_decode(C2),
+ ok.
+
+
+%%-----------------------------------------------------------------
+%% Test Case: IOR creation test
+%% Description:
+%%-----------------------------------------------------------------
+create_and_get_ops(doc) -> ["Description", "more description"];
+create_and_get_ops(suite) -> [];
+create_and_get_ops(_) ->
+ V = #'IIOP_Version'{major=1,minor=0},
+ M0 = 'Module_Interface',
+ T0 = "IDL:Module/Interface:1.0",
+ H0 = "my.hostname.org",
+ P0 = 4040,
+ N0 = 'name',
+ ?line O0 = corba_fake_mk_objkey(M0, registered, N0),
+ PB0 = #'IIOP_ProfileBody_1_0'{iiop_version=V, host=H0, port=P0, object_key=O0},
+ TP0 = #'IOP_TaggedProfile'{tag=?TAG_INTERNET_IOP, profile_data=PB0},
+ S0 = #'IOP_IOR'{type_id=T0, profiles=[TP0]},
+ ?line S0 = iop_ior:create({1, 0}, T0, [H0], P0, -1, O0, [], 0, 0),
+ N1 = list_to_pid("<0.100.0>"),
+ ?line O1 = corba_fake_mk_objkey(M0, key, N1),
+ {_,_,K1,_,_,_} = O1,
+ PB1 = #'IIOP_ProfileBody_1_0'{iiop_version=V, host=H0, port=P0, object_key=O1},
+ TP1 = #'IOP_TaggedProfile'{tag=?TAG_INTERNET_IOP, profile_data=PB1},
+ S1 = #'IOP_IOR'{type_id=T0, profiles=[TP1]},
+ ?line S1 = iop_ior:create({1, 0}, T0, [H0], P0, -1, O1, [], 0, 0),
+ O2 = "This is an external objectkey",
+ PB2 = #'IIOP_ProfileBody_1_0'{iiop_version=V, host=H0, port=P0, object_key=O2},
+ TP2 = #'IOP_TaggedProfile'{tag=?TAG_INTERNET_IOP, profile_data=PB2},
+ S2 = #'IOP_IOR'{type_id=T0, profiles=[TP2]},
+ ?line {'internal_registered', N0, _, _, M0} = iop_ior:get_key(S0),
+ ?line {'internal', K1, _, _, M0} = iop_ior:get_key(S1),
+ ?line {'external', {H0, P0, O2, _,_,
+ #host_data{protocol = normal,
+ ssl_data = undefined,
+ version = {1,0},
+ csiv2_mech = undefined,
+ csiv2_statefull = false,
+ charset = 65537,
+ wcharset = 65801,
+ ft_heartbeat = false,
+ ft_primary = false,
+ ft_group = undefined,
+ csiv2_addresses = []}}}
+ = iop_ior:get_key(S2),
+ ?line T0 = iop_ior:get_typeID(S0),
+ ?line O0 = iop_ior:get_objkey(S0),
+ ?line O1 = iop_ior:get_objkey(S1),
+ ?line O2 = iop_ior:get_objkey(S2),
+ ok.
+
+%%-----------------------------------------------------------------
+%% Internal functions
+%%-----------------------------------------------------------------
+corba_fake_mk_objkey(Id, 'key', Pid) when is_pid(Pid) ->
+ Key = make_objkey(),
+ {Id, 'key', Key, term_to_binary(undefined), 0, 0};
+corba_fake_mk_objkey(Id, 'key', RegName) when is_atom(RegName) ->
+ Key = term_to_binary(RegName),
+ {Id, 'key', Key, term_to_binary(undefined), 0, 0};
+corba_fake_mk_objkey(Id, 'registered', RegName) when is_atom(RegName) ->
+ {Id, 'registered', RegName, term_to_binary(undefined), 0, 0}.
+
+
+make_objkey() ->
+ term_to_binary({now(), node()}).
diff --git a/lib/orber/test/iop_ior_11_SUITE.erl b/lib/orber/test/iop_ior_11_SUITE.erl
new file mode 100644
index 0000000000..35d01789ee
--- /dev/null
+++ b/lib/orber/test/iop_ior_11_SUITE.erl
@@ -0,0 +1,186 @@
+%%
+%% %CopyrightBegin%
+%%
+%% 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%
+%%
+%%
+%%-----------------------------------------------------------------
+%%
+%% Description:
+%% Test suite for the IOR functions
+%%
+%%-----------------------------------------------------------------
+-module(iop_ior_11_SUITE).
+
+-include("test_server.hrl").
+-include_lib("orber/src/orber_iiop.hrl").
+
+-define(default_timeout, ?t:minutes(3)).
+
+%%-----------------------------------------------------------------
+%% External exports
+%%-----------------------------------------------------------------
+-export([all/1]).
+
+%%-----------------------------------------------------------------
+%% Internal exports
+%%-----------------------------------------------------------------
+-export([]).
+-compile(export_all).
+
+%%-----------------------------------------------------------------
+%% Func: all/1
+%% Args:
+%% Returns:
+%%-----------------------------------------------------------------
+all(doc) -> ["Description", "more description"];
+all(suite) ->
+ [encoding, create_and_get_ops].
+
+%%-----------------------------------------------------------------
+%% Init and cleanup functions.
+%%-----------------------------------------------------------------
+
+init_per_testcase(_Case, Config) ->
+ ?line Dog=test_server:timetrap(?default_timeout),
+ [{watchdog, Dog}|Config].
+
+
+fin_per_testcase(_Case, Config) ->
+ Dog = ?config(watchdog, Config),
+ test_server:timetrap_cancel(Dog),
+ ok.
+
+%%-----------------------------------------------------------------
+%% Test Case: IOR encoding test
+%% Description: Just testing the string_encoding function because the
+%% other encodings is called from them.
+%%-----------------------------------------------------------------
+encoding(doc) -> ["Description", "more description"];
+encoding(suite) -> [];
+encoding(_) ->
+ V = #'IIOP_Version'{major=1,minor=1},
+ M0 = 'Module_Interface',
+ T0 = "IDL:Module/Interface:1.0",
+ H0 = "my.hostname.org",
+ P0 = 4040,
+ N0 = 'name',
+ Components = case orber:iiop_ssl_port() of
+ -1 ->
+ [];
+ SSLPort ->
+ [#'IOP_TaggedComponent'{tag=?TAG_SSL_SEC_TRANS,
+ component_data=[0 |
+ cdrlib:enc_unsigned_short(2,
+ cdrlib:enc_unsigned_short(2,
+ cdrlib:enc_unsigned_short(SSLPort, [])))]}]
+ end,
+ ?line O0 = corba_fake_mk_objkey(M0, registered, N0),
+ PB0 = #'IIOP_ProfileBody_1_1'{iiop_version=V, host=H0, port=P0, object_key=O0,
+ components=Components},
+ TP0 = #'IOP_TaggedProfile'{tag=?TAG_INTERNET_IOP, profile_data=PB0},
+ S0 = #'IOP_IOR'{type_id=T0, profiles=[TP0]},
+ N1 = list_to_pid("<0.100.0>"),
+ ?line O1 = corba_fake_mk_objkey(M0, key, N1),
+ PB1 = #'IIOP_ProfileBody_1_1'{iiop_version=V, host=H0, port=P0, object_key=O1,
+ components=[]},
+ TP1 = #'IOP_TaggedProfile'{tag=?TAG_INTERNET_IOP, profile_data=PB1},
+ S1 = #'IOP_IOR'{type_id=T0, profiles=[TP1]},
+ O2 = "This is an external objectkey",
+ PB2 = #'IIOP_ProfileBody_1_1'{iiop_version=V, host=H0, port=P0, object_key=O2,
+ components=[]},
+ TP2 = #'IOP_TaggedProfile'{tag=?TAG_INTERNET_IOP, profile_data=PB2},
+ S2 = #'IOP_IOR'{type_id=T0, profiles=[TP2]},
+ ?line C0 = iop_ior:string_code(S0),
+ ?line {S0, <<>>, _} = iop_ior:string_decode(C0),
+ ?line C1 = iop_ior:string_code(S1),
+ ?line {S1, <<>>, _} = iop_ior:string_decode(C1),
+ ?line C2 = iop_ior:string_code(S2),
+ ?line {S2, <<>>, _} = iop_ior:string_decode(C2),
+ ok.
+
+
+%%-----------------------------------------------------------------
+%% Test Case: IOR creation test
+%% Description:
+%%-----------------------------------------------------------------
+create_and_get_ops(doc) -> ["Description", "more description"];
+create_and_get_ops(suite) -> [];
+create_and_get_ops(_) ->
+ V = #'IIOP_Version'{major=1,minor=1},
+ CSC = #'IOP_TaggedComponent'{tag=?TAG_CODE_SETS,
+ component_data=?DEFAULT_CODESETS},
+ M0 = 'Module_Interface',
+ T0 = "IDL:Module/Interface:1.0",
+ H0 = "my.hostname.org",
+ P0 = 4040,
+ N0 = 'name',
+ ?line O0 = corba_fake_mk_objkey(M0, registered, N0),
+ PB0 = #'IIOP_ProfileBody_1_1'
+ {iiop_version=V, host=H0, port=P0, object_key=O0,
+ components=[CSC]},
+ TP0 = #'IOP_TaggedProfile'{tag=?TAG_INTERNET_IOP, profile_data=PB0},
+ S0 = #'IOP_IOR'{type_id=T0, profiles=[TP0]},
+ ?line S0 = iop_ior:create({1, 1}, T0, [H0], P0, -1, O0, [CSC], 0, 0),
+ N1 = list_to_pid("<0.100.0>"),
+ ?line O1 = corba_fake_mk_objkey(M0, key, N1),
+ {_,_,K1,_,_,_} = O1,
+ PB1 = #'IIOP_ProfileBody_1_1'
+ {iiop_version=V, host=H0, port=P0, object_key=O1,
+ components=[CSC]},
+ TP1 = #'IOP_TaggedProfile'{tag=?TAG_INTERNET_IOP, profile_data=PB1},
+ S1 = #'IOP_IOR'{type_id=T0, profiles=[TP1]},
+ ?line S1 = iop_ior:create({1, 1}, T0, [H0], P0, -1, O1, [CSC], 0, 0),
+ O2 = "This is an external objectkey",
+ PB2 = #'IIOP_ProfileBody_1_1'{iiop_version=V, host=H0, port=P0, object_key=O2,
+ components=[]},
+ TP2 = #'IOP_TaggedProfile'{tag=?TAG_INTERNET_IOP, profile_data=PB2},
+ S2 = #'IOP_IOR'{type_id=T0, profiles=[TP2]},
+ ?line {'internal_registered', N0, _, _, M0} = iop_ior:get_key(S0),
+ ?line {'internal', K1, _, _, M0} = iop_ior:get_key(S1),
+ ?line {'external', {H0, P0, O2, _,_,
+ #host_data{protocol = normal,
+ ssl_data = undefined,
+ version = {1,1},
+ csiv2_mech = undefined,
+ csiv2_statefull = false,
+ charset = 65537,
+ wcharset = 65801,
+ ft_heartbeat = false,
+ ft_primary = false,
+ ft_group = undefined,
+ csiv2_addresses = []}}} =
+ iop_ior:get_key(S2),
+ ?line T0 = iop_ior:get_typeID(S0),
+ ?line O0 = iop_ior:get_objkey(S0),
+ ?line O1 = iop_ior:get_objkey(S1),
+ ?line O2 = iop_ior:get_objkey(S2),
+ ok.
+
+%%-----------------------------------------------------------------
+%% Internal functions
+%%-----------------------------------------------------------------
+corba_fake_mk_objkey(Id, 'key', Pid) when is_pid(Pid) ->
+ Key = make_objkey(),
+ {Id, 'key', Key, term_to_binary(undefined), 0, 0};
+corba_fake_mk_objkey(Id, 'key', RegName) when is_atom(RegName) ->
+ Key = term_to_binary(RegName),
+ {Id, 'key', Key, term_to_binary(undefined), 0, 0};
+corba_fake_mk_objkey(Id, 'registered', RegName) when is_atom(RegName) ->
+ {Id, 'registered', RegName, term_to_binary(undefined), 0, 0}.
+
+make_objkey() ->
+ term_to_binary({now(), node()}).
diff --git a/lib/orber/test/iop_ior_12_SUITE.erl b/lib/orber/test/iop_ior_12_SUITE.erl
new file mode 100644
index 0000000000..42db130e54
--- /dev/null
+++ b/lib/orber/test/iop_ior_12_SUITE.erl
@@ -0,0 +1,187 @@
+%%----------------------------------------------------------------------
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 2000-2010. All Rights Reserved.
+%%
+%% The contents of this file are subject to the Erlang Public License,
+%% Version 1.1, (the "License"); you may not use this file except in
+%% compliance with the License. You should have received a copy of the
+%% Erlang Public License along with this software. If not, it can be
+%% retrieved online at http://www.erlang.org/.
+%%
+%% Software distributed under the License is distributed on an "AS IS"
+%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+%% the License for the specific language governing rights and limitations
+%% under the License.
+%%
+%% %CopyrightEnd%
+%%
+%%
+%%-----------------------------------------------------------------
+%% File : iop_ior_12_SUITE.erl
+%% Description : Test suite for the IOR functions
+%%
+%%----------------------------------------------------------------------
+-module(iop_ior_12_SUITE).
+
+
+-include("test_server.hrl").
+-include_lib("orber/src/orber_iiop.hrl").
+
+-define(default_timeout, ?t:minutes(3)).
+
+%%-----------------------------------------------------------------
+%% External exports
+%%-----------------------------------------------------------------
+-export([all/1]).
+
+%%-----------------------------------------------------------------
+%% Internal exports
+%%-----------------------------------------------------------------
+-export([]).
+-compile(export_all).
+
+%%-----------------------------------------------------------------
+%% Func: all/1
+%% Args:
+%% Returns:
+%%-----------------------------------------------------------------
+all(doc) -> ["Description", "more description"];
+all(suite) ->
+ [encoding, create_and_get_ops].
+
+%%-----------------------------------------------------------------
+%% Init and cleanup functions.
+%%-----------------------------------------------------------------
+
+init_per_testcase(_Case, Config) ->
+ ?line Dog=test_server:timetrap(?default_timeout),
+ [{watchdog, Dog}|Config].
+
+
+fin_per_testcase(_Case, Config) ->
+ Dog = ?config(watchdog, Config),
+ test_server:timetrap_cancel(Dog),
+ ok.
+
+%%-----------------------------------------------------------------
+%% Test Case: IOR encoding test
+%% Description: Just testing the string_encoding function because the
+%% other encodings is called from them.
+%%-----------------------------------------------------------------
+encoding(doc) -> ["Description", "more description"];
+encoding(suite) -> [];
+encoding(_) ->
+ V = #'IIOP_Version'{major=1,minor=2},
+ M0 = 'Module_Interface',
+ T0 = "IDL:Module/Interface:1.0",
+ H0 = "my.hostname.org",
+ P0 = 4040,
+ N0 = 'name',
+ Components = case orber:iiop_ssl_port() of
+ -1 ->
+ [];
+ SSLPort ->
+ [#'IOP_TaggedComponent'{tag=?TAG_SSL_SEC_TRANS,
+ component_data=[0 |
+ cdrlib:enc_unsigned_short(2,
+ cdrlib:enc_unsigned_short(2,
+ cdrlib:enc_unsigned_short(SSLPort, [])))]}]
+ end,
+ ?line O0 = corba_fake_mk_objkey(M0, registered, N0),
+ PB0 = #'IIOP_ProfileBody_1_1'{iiop_version=V, host=H0, port=P0, object_key=O0,
+ components=Components},
+ TP0 = #'IOP_TaggedProfile'{tag=?TAG_INTERNET_IOP, profile_data=PB0},
+ S0 = #'IOP_IOR'{type_id=T0, profiles=[TP0]},
+ N1 = list_to_pid("<0.100.0>"),
+ ?line O1 = corba_fake_mk_objkey(M0, key, N1),
+ PB1 = #'IIOP_ProfileBody_1_1'{iiop_version=V, host=H0, port=P0, object_key=O1,
+ components=[]},
+ TP1 = #'IOP_TaggedProfile'{tag=?TAG_INTERNET_IOP, profile_data=PB1},
+ S1 = #'IOP_IOR'{type_id=T0, profiles=[TP1]},
+ O2 = "This is an external objectkey",
+ PB2 = #'IIOP_ProfileBody_1_1'{iiop_version=V, host=H0, port=P0, object_key=O2,
+ components=[]},
+ TP2 = #'IOP_TaggedProfile'{tag=?TAG_INTERNET_IOP, profile_data=PB2},
+ S2 = #'IOP_IOR'{type_id=T0, profiles=[TP2]},
+ ?line C0 = iop_ior:string_code(S0),
+ ?line {S0, <<>>, _} = iop_ior:string_decode(C0),
+ ?line C1 = iop_ior:string_code(S1),
+ ?line {S1, <<>>, _} = iop_ior:string_decode(C1),
+ ?line C2 = iop_ior:string_code(S2),
+ ?line {S2, <<>>, _} = iop_ior:string_decode(C2),
+ ok.
+
+
+%%-----------------------------------------------------------------
+%% Test Case: IOR creation test
+%% Description:
+%%-----------------------------------------------------------------
+create_and_get_ops(doc) -> ["Description", "more description"];
+create_and_get_ops(suite) -> [];
+create_and_get_ops(_) ->
+ V = #'IIOP_Version'{major=1,minor=2},
+ CSC = #'IOP_TaggedComponent'{tag=?TAG_CODE_SETS,
+ component_data=?DEFAULT_CODESETS},
+ M0 = 'Module_Interface',
+ T0 = "IDL:Module/Interface:1.0",
+ H0 = "my.hostname.org",
+ P0 = 4040,
+ N0 = 'name',
+ ?line O0 = corba_fake_mk_objkey(M0, registered, N0),
+ PB0 = #'IIOP_ProfileBody_1_1'
+ {iiop_version=V, host=H0, port=P0, object_key=O0,
+ components=[CSC]},
+ TP0 = #'IOP_TaggedProfile'{tag=?TAG_INTERNET_IOP, profile_data=PB0},
+ S0 = #'IOP_IOR'{type_id=T0, profiles=[TP0]},
+ ?line S0 = iop_ior:create({1, 2}, T0, [H0], P0, -1, O0, [CSC], 0, 0),
+ N1 = list_to_pid("<0.100.0>"),
+ ?line O1 = corba_fake_mk_objkey(M0, key, N1),
+ {_,_,K1,_,_,_} = O1,
+ PB1 = #'IIOP_ProfileBody_1_1'
+ {iiop_version=V, host=H0, port=P0, object_key=O1,
+ components=[CSC]},
+ TP1 = #'IOP_TaggedProfile'{tag=?TAG_INTERNET_IOP, profile_data=PB1},
+ S1 = #'IOP_IOR'{type_id=T0, profiles=[TP1]},
+ ?line S1 = iop_ior:create({1, 2}, T0, [H0], P0, -1, O1, [CSC], 0, 0),
+ O2 = "This is an external objectkey",
+ PB2 = #'IIOP_ProfileBody_1_1'{iiop_version=V, host=H0, port=P0, object_key=O2,
+ components=[]},
+ TP2 = #'IOP_TaggedProfile'{tag=?TAG_INTERNET_IOP, profile_data=PB2},
+ S2 = #'IOP_IOR'{type_id=T0, profiles=[TP2]},
+ ?line {'internal_registered', N0, _, _, M0} = iop_ior:get_key(S0),
+ ?line {'internal', K1, _, _, M0} = iop_ior:get_key(S1),
+ ?line {'external', {H0, P0, O2,_,_,
+ #host_data{protocol = normal,
+ ssl_data = undefined,
+ version = {1,2},
+ csiv2_mech = undefined,
+ csiv2_statefull = false,
+ charset = 65537,
+ wcharset = 65801,
+ ft_heartbeat = false,
+ ft_primary = false,
+ ft_group = undefined,
+ csiv2_addresses = []}}}
+ = iop_ior:get_key(S2),
+ ?line T0 = iop_ior:get_typeID(S0),
+ ?line O0 = iop_ior:get_objkey(S0),
+ ?line O1 = iop_ior:get_objkey(S1),
+ ?line O2 = iop_ior:get_objkey(S2),
+ ok.
+
+%%-----------------------------------------------------------------
+%% Internal functions
+%%-----------------------------------------------------------------
+corba_fake_mk_objkey(Id, 'key', Pid) when is_pid(Pid) ->
+ Key = make_objkey(),
+ {Id, 'key', Key, term_to_binary(undefined), 0, 0};
+corba_fake_mk_objkey(Id, 'key', RegName) when is_atom(RegName) ->
+ Key = term_to_binary(RegName),
+ {Id, 'key', Key, term_to_binary(undefined), 0, 0};
+corba_fake_mk_objkey(Id, 'registered', RegName) when is_atom(RegName) ->
+ {Id, 'registered', RegName, term_to_binary(undefined), 0, 0}.
+
+make_objkey() ->
+ term_to_binary({now(), node()}).
diff --git a/lib/orber/test/lname_SUITE.erl b/lib/orber/test/lname_SUITE.erl
new file mode 100644
index 0000000000..d1f0e7cf0e
--- /dev/null
+++ b/lib/orber/test/lname_SUITE.erl
@@ -0,0 +1,198 @@
+%%
+%% %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%
+%%
+%%
+%%-----------------------------------------------------------------
+%%
+%% Description:
+%% Test suite for the Names Library module
+%%
+%%-----------------------------------------------------------------
+-module(lname_SUITE).
+
+-include("test_server.hrl").
+-include_lib("orber/COSS/CosNaming/CosNaming.hrl").
+-include_lib("orber/COSS/CosNaming/lname.hrl").
+
+-define(default_timeout, ?t:minutes(3)).
+
+%%-----------------------------------------------------------------
+%% External exports
+%%-----------------------------------------------------------------
+-export([all/1]).
+
+%%-----------------------------------------------------------------
+%% Internal exports
+%%-----------------------------------------------------------------
+-export([]).
+-compile(export_all).
+
+%%-----------------------------------------------------------------
+%% Func: all/1
+%% Args:
+%% Returns:
+%%-----------------------------------------------------------------
+all(doc) -> ["Description", "more description"];
+all(suite) ->
+ [lname_component, lname].
+
+%%-----------------------------------------------------------------
+%% Init and cleanup functions.
+%%-----------------------------------------------------------------
+
+init_per_testcase(_Case, Config) ->
+ ?line Dog=test_server:timetrap(?default_timeout),
+ [{watchdog, Dog}|Config].
+
+
+fin_per_testcase(_Case, Config) ->
+ Dog = ?config(watchdog, Config),
+ test_server:timetrap_cancel(Dog),
+ ok.
+
+
+%%-----------------------------------------------------------------
+%% Test Case: name component handling tests
+%% Description:
+%%-----------------------------------------------------------------
+lname_component(doc) -> ["Description", "more description"];
+lname_component(suite) -> [];
+lname_component(_) ->
+ create_test(),
+ get_tests(),
+ set_tests().
+
+create_test() ->
+ ?line #'CosNaming_NameComponent'{} = lname_component:create(),
+ ok.
+
+get_tests() ->
+ NC = #'CosNaming_NameComponent'{id="first", kind="apple"},
+ NC1 = #'CosNaming_NameComponent'{id="", kind="apple"},
+ NC2 = #'CosNaming_NameComponent'{id="first", kind=""},
+ ?line "first" = lname_component:get_id(NC),
+ ?line "apple" = lname_component:get_kind(NC),
+ ?line {'EXCEPTION', #'LNameComponent_NotSet'{}} =
+ (catch lname_component:get_id(NC1)),
+ ?line {'EXCEPTION', #'LNameComponent_NotSet'{}} =
+ (catch lname_component:get_kind(NC2)),
+ ok.
+
+set_tests() ->
+ NC = #'CosNaming_NameComponent'{id="first", kind="apple"},
+ ?line #'CosNaming_NameComponent'{id="second", kind="apple"} =
+ lname_component:set_id(NC, "second"),
+ ?line #'CosNaming_NameComponent'{id="first", kind="pear"} =
+ lname_component:set_kind(NC, "pear"),
+ ok.
+
+%%-----------------------------------------------------------------
+%% Test Case: name handling tests
+%% Description:
+%%-----------------------------------------------------------------
+lname(doc) -> ["Description", "more description"];
+lname(suite) -> [];
+lname(_) ->
+ Name = [#'CosNaming_NameComponent'{id="first", kind="apple"},
+ #'CosNaming_NameComponent'{id="last", kind="peach"},
+ #'CosNaming_NameComponent'{id="and", kind="plum"},
+ #'CosNaming_NameComponent'{id="always", kind="orange"}],
+ insert_tests(Name),
+ get_tests(Name),
+ delete_tests(Name),
+ comparision_tests(Name),
+ convertion_tests(Name).
+
+insert_tests(Name) ->
+ NC = #'CosNaming_NameComponent'{id="new", kind="pear"},
+ ?line [NC, #'CosNaming_NameComponent'{id="first", kind="apple"},
+ #'CosNaming_NameComponent'{id="last", kind="peach"},
+ #'CosNaming_NameComponent'{id="and", kind="plum"},
+ #'CosNaming_NameComponent'{id="always", kind="orange"}] =
+ lname:insert_component(Name, 1, NC),
+ ?line [#'CosNaming_NameComponent'{id="first", kind="apple"},
+ #'CosNaming_NameComponent'{id="last", kind="peach"},
+ #'CosNaming_NameComponent'{id="and", kind="plum"},
+ #'CosNaming_NameComponent'{id="always", kind="orange"}, NC] =
+ lname:insert_component(Name, 5, NC),
+ ?line [#'CosNaming_NameComponent'{id="first", kind="apple"},
+ #'CosNaming_NameComponent'{id="last", kind="peach"},
+ #'CosNaming_NameComponent'{id="and", kind="plum"}, NC,
+ #'CosNaming_NameComponent'{id="always", kind="orange"}] =
+ lname:insert_component(Name, 4, NC),
+ ?line [#'CosNaming_NameComponent'{id="first", kind="apple"},
+ #'CosNaming_NameComponent'{id="last", kind="peach"}, NC,
+ #'CosNaming_NameComponent'{id="and", kind="plum"},
+ #'CosNaming_NameComponent'{id="always", kind="orange"}] =
+ lname:insert_component(Name, 3, NC),
+ ?line {'EXCEPTION', #'LName_NoComponent'{}} =
+ (catch lname:insert_component(Name, 6, NC)),
+ ?line {'EXCEPTION', #'LName_NoComponent'{}} =
+ (catch lname:insert_component(Name, 0, NC)),
+ ?line {'EXCEPTION', #'LName_NoComponent'{}} =
+ (catch lname:insert_component(Name, -2, NC)),
+ ok.
+
+get_tests(Name) ->
+ ?line #'CosNaming_NameComponent'{id="first", kind="apple"} =
+ lname:get_component(Name, 1),
+ ?line #'CosNaming_NameComponent'{id="always", kind="orange"} =
+ lname:get_component(Name, 4),
+ ?line #'CosNaming_NameComponent'{id="and", kind="plum"} =
+ lname:get_component(Name, 3),
+ ?line {'EXCEPTION', #'LName_NoComponent'{}} =
+ (catch lname:get_component(Name, 5)),
+ ?line {'EXCEPTION', #'LName_NoComponent'{}} =
+ (catch lname:get_component(Name, 0)),
+ ?line {'EXCEPTION', #'LName_NoComponent'{}} =
+ (catch lname:get_component(Name, -2)),
+ ok.
+
+delete_tests(Name) ->
+ ?line [#'CosNaming_NameComponent'{id="last", kind="peach"},
+ #'CosNaming_NameComponent'{id="and", kind="plum"},
+ #'CosNaming_NameComponent'{id="always", kind="orange"}] =
+ lname:delete_component(Name, 1),
+ ?line [#'CosNaming_NameComponent'{id="first", kind="apple"},
+ #'CosNaming_NameComponent'{id="last", kind="peach"},
+ #'CosNaming_NameComponent'{id="and", kind="plum"}] =
+ lname:delete_component(Name, 4),
+ ?line [#'CosNaming_NameComponent'{id="first", kind="apple"},
+ #'CosNaming_NameComponent'{id="last", kind="peach"},
+ #'CosNaming_NameComponent'{id="always", kind="orange"}] =
+ lname:delete_component(Name, 3),
+ ?line {'EXCEPTION', #'LName_NoComponent'{}} =
+ (catch lname:delete_component(Name, 6)),
+ ?line {'EXCEPTION', #'LName_NoComponent'{}} =
+ (catch lname:delete_component(Name, 0)),
+ ?line {'EXCEPTION', #'LName_NoComponent'{}} =
+ (catch lname:delete_component(Name, -2)),
+ ok.
+
+comparision_tests(Name) ->
+ ?line true = lname:equal(Name, Name),
+ ?line false = lname:equal(Name, lname:delete_component(Name, 2)),
+ ?line true = lname:less_than(lname:delete_component(Name, 2), Name),
+ ?line false = lname:less_than(Name, Name),
+ ?line false = lname:less_than(Name, lname:delete_component(Name, 2)),
+ ok.
+
+convertion_tests(Name) ->
+ ?line Name = lname:from_idl_form(Name),
+ ?line Name = lname:to_idl_form(Name),
+ ok.
diff --git a/lib/orber/test/multi_ORB_SUITE.erl b/lib/orber/test/multi_ORB_SUITE.erl
new file mode 100644
index 0000000000..d1931f5393
--- /dev/null
+++ b/lib/orber/test/multi_ORB_SUITE.erl
@@ -0,0 +1,2352 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 1999-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(multi_ORB_SUITE).
+
+-include("test_server.hrl").
+-include_lib("orber/include/corba.hrl").
+-include_lib("orber/COSS/CosNaming/CosNaming.hrl").
+-include_lib("orber/src/orber_iiop.hrl").
+-include_lib("orber/src/ifr_objects.hrl").
+-include("idl_output/orber_test_server.hrl").
+-include_lib("orber/COSS/CosNaming/CosNaming_NamingContextExt.hrl").
+-include_lib("orber/COSS/CosNaming/CosNaming_NamingContext.hrl").
+
+
+-define(default_timeout, ?t:minutes(15)).
+
+-define(match(ExpectedRes,Expr),
+ fun() ->
+ AcTuAlReS = (catch (Expr)),
+ case AcTuAlReS of
+ ExpectedRes ->
+ io:format("------ CORRECT RESULT ------~n~p~n",
+ [AcTuAlReS]),
+ AcTuAlReS;
+ _ ->
+ io:format("###### ERROR ERROR ######~nRESULT: ~p~n",
+ [AcTuAlReS]),
+ ?line exit(AcTuAlReS)
+ end
+ end()).
+
+%%-----------------------------------------------------------------
+%% External exports
+%%-----------------------------------------------------------------
+-export([all/1, cases/0, init_all/1, finish_all/1, basic_PI_api/1, multi_orber_api/1,
+ init_per_testcase/2, fin_per_testcase/2, multi_pseudo_orber_api/1,
+ light_orber_api/1, light_orber2_api/1,
+ ssl_1_multi_orber_api/1, ssl_2_multi_orber_api/1, ssl_reconfigure_api/1,
+ iiop_timeout_api/1, iiop_timeout_added_api/1, setup_connection_timeout_api/1,
+ setup_multi_connection_timeout_api/1, setup_multi_connection_timeout_random_api/1,
+ setup_multi_connection_timeout_attempts_api/1,
+ fragments_server_api/1, fragments_max_server_api/1,
+ fragments_max_server_added_api/1, fragments_client_api/1,
+ light_ifr_api/1, max_requests_api/1, max_requests_added_api/1,
+ max_connections_api/1, max_packet_size_exceeded_api/1,
+ max_packet_size_ok_api/1, proxy_interface_api/1, proxy_interface_ipv6_api/1,
+ multiple_accept_api/1, implicit_context_api/1,
+ pseudo_implicit_context_api/1, pseudo_two_implicit_context_api/1,
+ oneway_implicit_context_api/1, implicit_context_roundtrip_api/1,
+ oneway_pseudo_implicit_context_api/1, flags_added_api/1,
+ oneway_pseudo_two_implicit_context_api/1,
+ local_interface_api/1, local_interface_ctx_override_api/1,
+ local_interface_acl_override_api/1, bad_giop_header_api/1,
+ bad_fragment_id_client_api/1, bad_id_cancel_request_api/1,
+ close_connections_api/1, close_connections_local_interface_api/1,
+ close_connections_local_interface_ctx_override_api/1, ssl_reconfigure_generation_3_api/1,
+ ssl_1_multi_orber_generation_3_api/1, ssl_2_multi_orber_generation_3_api/1,
+ close_connections_alt_iiop_addr_api/1, close_connections_multiple_profiles_api/1]).
+
+
+%%-----------------------------------------------------------------
+%% Internal exports
+%%-----------------------------------------------------------------
+-export([pseudo_calls/2, pseudo_casts/2, create_fake_server_ORB/5, do_connect/3]).
+
+%%-----------------------------------------------------------------
+%% Func: all/1
+%% Args:
+%% Returns:
+%%-----------------------------------------------------------------
+all(doc) -> ["API tests for multi orber interfaces",
+ "This suite test intra-ORB communication. There are three scenarios:",
+ "* No security at all (multi_orber_api)",
+ "* Two secure orbs using ssl (ssl_multi_orb_api)",
+ "* One secure and one orb with no security. (ssl_multi_orb_api)"];
+all(suite) -> {req,
+ [mnesia],
+ {conf, init_all, cases(), finish_all}}.
+
+%% NOTE - the fragment test cases must be first since we explicitly set a request
+%% id. Otherwise, the request-id counter would be increased and we cannot know
+%% what it is.
+cases() ->
+ [fragments_server_api,
+ fragments_max_server_api,
+ fragments_max_server_added_api,
+ fragments_client_api,
+ flags_added_api,
+ bad_fragment_id_client_api,
+ bad_giop_header_api,
+ bad_id_cancel_request_api,
+ implicit_context_api,
+ pseudo_implicit_context_api,
+ pseudo_two_implicit_context_api,
+ implicit_context_roundtrip_api,
+ oneway_implicit_context_api,
+ oneway_pseudo_implicit_context_api,
+ oneway_pseudo_two_implicit_context_api,
+ proxy_interface_api,
+ proxy_interface_ipv6_api,
+ local_interface_api,
+ local_interface_ctx_override_api,
+ local_interface_acl_override_api,
+ close_connections_api,
+ close_connections_local_interface_api,
+ close_connections_local_interface_ctx_override_api,
+ close_connections_alt_iiop_addr_api,
+ close_connections_multiple_profiles_api,
+ multiple_accept_api,
+ max_requests_api,
+ max_requests_added_api,
+ max_connections_api,
+ max_packet_size_exceeded_api,
+ max_packet_size_ok_api,
+ light_ifr_api,
+ multi_pseudo_orber_api,
+ multi_orber_api,
+ light_orber_api,
+ light_orber2_api,
+ basic_PI_api,
+ iiop_timeout_api,
+ iiop_timeout_added_api,
+ setup_connection_timeout_api,
+ setup_multi_connection_timeout_api,
+ setup_multi_connection_timeout_attempts_api,
+ setup_multi_connection_timeout_random_api,
+ ssl_1_multi_orber_api,
+ ssl_1_multi_orber_generation_3_api,
+ ssl_2_multi_orber_api,
+ ssl_2_multi_orber_generation_3_api,
+ ssl_reconfigure_generation_3_api,
+ ssl_reconfigure_api
+ ].
+
+%%-----------------------------------------------------------------
+%% Init and cleanup functions.
+%%-----------------------------------------------------------------
+
+init_per_testcase(_Case, Config) ->
+ Path = code:which(?MODULE),
+ code:add_pathz(filename:join(filename:dirname(Path), "idl_output")),
+ Dog=test_server:timetrap(?default_timeout),
+ orber:jump_start(0),
+ oe_orber_test_server:oe_register(),
+ [{watchdog, Dog}|Config].
+
+
+fin_per_testcase(_Case, Config) ->
+ oe_orber_test_server:oe_unregister(),
+ orber:jump_stop(),
+ Path = code:which(?MODULE),
+ code:del_path(filename:join(filename:dirname(Path), "idl_output")),
+ Dog = ?config(watchdog, Config),
+ test_server:timetrap_cancel(Dog),
+ ok.
+
+init_all(Config) ->
+ if
+ is_list(Config) ->
+ Config;
+ true ->
+ exit("Config not a list")
+ end.
+
+finish_all(Config) ->
+ Config.
+
+%%-----------------------------------------------------------------
+%% API tests for ORB to ORB, no security
+%%-----------------------------------------------------------------
+
+implicit_context_api(doc) -> ["IIOP Implicit Contex tests"];
+implicit_context_api(suite) -> [];
+implicit_context_api(_Config) ->
+ IP = orber_test_lib:get_host(),
+ Loopback = orber_test_lib:get_loopback_interface(),
+ {ok, ServerNode, _ServerHost} =
+ ?match({ok,_,_}, orber_test_lib:js_node([{flags, ?ORB_ENV_LOCAL_INTERFACE},
+ {ip_address, IP}])),
+ ServerPort = orber_test_lib:remote_apply(ServerNode, orber, iiop_port, []),
+ %% Create a remote server
+ ?match(ok, orber_test_lib:remote_apply(ServerNode, orber_test_lib,
+ install_test_data,
+ [nameservice])),
+ IOR = ?match(#'IOP_IOR'{},
+ corba:string_to_object("corbaname::1.2@"++IP++":"++integer_to_list(ServerPort)++"/NameService#mamba")),
+
+ Relay = ?match({_,_,_,_,_,_}, orber_test_server:oe_create([])),
+ ?match(ok,
+ orber_test_server:
+ relay_call(Relay,
+ [{context,
+ [#'IOP_ServiceContext'{context_id=?ORBER_GENERIC_CTX_ID,
+ context_data = {interface,
+ Loopback}}]}],
+ IOR)),
+
+ ?match([_,_], orber:iiop_connections(out)),
+ Conns = ?match([_,_],
+ orber_test_lib:remote_apply(ServerNode, orber, iiop_connections, [in])),
+ ?match(true, lists:keymember(Loopback, 1, Conns)),
+ ok.
+
+implicit_context_roundtrip_api(doc) ->
+ ["IIOP Implicit Contex roundtrip tests"];
+implicit_context_roundtrip_api(suite) -> [];
+implicit_context_roundtrip_api(_Config) ->
+ IP = orber_test_lib:get_host(),
+ Loopback = orber_test_lib:get_loopback_interface(),
+ {ok, ServerNode, _ServerHost} =
+ ?match({ok,_,_}, orber_test_lib:js_node([{flags, ?ORB_ENV_LOCAL_INTERFACE},
+ {ip_address, IP}])),
+ ServerPort = orber_test_lib:remote_apply(ServerNode, orber, iiop_port, []),
+ %% Create a remote server
+ ?match(ok, orber_test_lib:remote_apply(ServerNode, orber_test_lib,
+ install_test_data,
+ [nameservice])),
+ Relay = ?match(#'IOP_IOR'{},
+ corba:string_to_object("corbaname::1.2@"++IP++":"++integer_to_list(ServerPort)++"/NameService#mamba")),
+
+ IOR = ?match({_,_,_,_,_,_}, orber_test_server:oe_create([], [])),
+ ?match(ok,
+ orber_test_server:
+ relay_call(Relay,
+ [{context,
+ [#'IOP_ServiceContext'{context_id=?ORBER_GENERIC_CTX_ID,
+ context_data = {interface,
+ Loopback}}]}],
+ IOR)),
+ ?match([_,_], orber:iiop_connections(out)),
+ Conns = ?match([_,_],
+ orber_test_lib:remote_apply(ServerNode, orber, iiop_connections, [in])),
+ ?match(true, lists:keymember(Loopback, 1, Conns)),
+ ok.
+
+
+
+oneway_implicit_context_api(doc) -> ["IIOP Implicit Contex oneway tests"];
+oneway_implicit_context_api(suite) -> [];
+oneway_implicit_context_api(_Config) ->
+ IP = orber_test_lib:get_host(),
+ Loopback = orber_test_lib:get_loopback_interface(),
+ {ok, ServerNode, _ServerHost} =
+ ?match({ok,_,_}, orber_test_lib:js_node([{flags, ?ORB_ENV_LOCAL_INTERFACE},
+ {ip_address, IP}])),
+ ServerPort = orber_test_lib:remote_apply(ServerNode, orber, iiop_port, []),
+ %% Create a remote server
+ ?match(ok, orber_test_lib:remote_apply(ServerNode, orber_test_lib,
+ install_test_data,
+ [nameservice])),
+ IOR = ?match(#'IOP_IOR'{},
+ corba:string_to_object("corbaname::1.2@"++IP++":"++integer_to_list(ServerPort)++"/NameService#mamba")),
+
+ Relay = ?match({_,_,_,_,_,_}, orber_test_server:oe_create([])),
+ ?match(ok,
+ orber_test_server:
+ relay_cast(Relay,
+ [{context,
+ [#'IOP_ServiceContext'{context_id=?ORBER_GENERIC_CTX_ID,
+ context_data = {interface,
+ Loopback}}]}],
+ IOR)),
+
+ %% We must wait for a few seconds for the client to be able to set up the
+ %% connection (since it's a oneway operation).
+ timer:sleep(5000),
+ ?match([_,_], orber:iiop_connections(out)),
+ Conns = ?match([_,_],
+ orber_test_lib:remote_apply(ServerNode, orber, iiop_connections, [in])),
+ ?match(true, lists:keymember(Loopback, 1, Conns)),
+ ok.
+
+
+pseudo_implicit_context_api(doc) -> ["IIOP Implicit Contex tests (via pseudo object)"];
+pseudo_implicit_context_api(suite) -> [];
+pseudo_implicit_context_api(_Config) ->
+ IP = orber_test_lib:get_host(),
+ Loopback = orber_test_lib:get_loopback_interface(),
+ {ok, ServerNode, _ServerHost} =
+ ?match({ok,_,_}, orber_test_lib:js_node([{flags, ?ORB_ENV_LOCAL_INTERFACE},
+ {ip_address, IP}])),
+ ServerPort = orber_test_lib:remote_apply(ServerNode, orber, iiop_port, []),
+ %% Create a remote server
+ ?match(ok, orber_test_lib:remote_apply(ServerNode, orber_test_lib,
+ install_test_data,
+ [nameservice])),
+ IOR = ?match(#'IOP_IOR'{},
+ corba:string_to_object("corbaname::1.2@"++IP++":"++integer_to_list(ServerPort)++"/NameService#mamba")),
+
+ Relay = ?match({_,_,_,_,_,_}, orber_test_server:oe_create([], [{pseudo,true}])),
+ ?match(ok,
+ orber_test_server:
+ relay_call(Relay,
+ [{context,
+ [#'IOP_ServiceContext'{context_id=?ORBER_GENERIC_CTX_ID,
+ context_data = {interface,
+ Loopback}}]}],
+ IOR)),
+ ?match([_,_], orber:iiop_connections(out)),
+ Conns = ?match([_,_],
+ orber_test_lib:remote_apply(ServerNode, orber, iiop_connections, [in])),
+ ?match(true, lists:keymember(Loopback, 1, Conns)),
+ ok.
+
+pseudo_two_implicit_context_api(doc) ->
+ ["IIOP two Implicit Contex tests (via pseudo object)"];
+pseudo_two_implicit_context_api(suite) -> [];
+pseudo_two_implicit_context_api(_Config) ->
+ IP = orber_test_lib:get_host(),
+ Loopback = orber_test_lib:get_loopback_interface(),
+ {ok, ServerNode, _ServerHost} =
+ ?match({ok,_,_}, orber_test_lib:js_node([{flags, ?ORB_ENV_LOCAL_INTERFACE},
+ {ip_address, IP}])),
+ ServerPort = orber_test_lib:remote_apply(ServerNode, orber, iiop_port, []),
+ %% Create a remote server
+ ?match(ok, orber_test_lib:remote_apply(ServerNode, orber_test_lib,
+ install_test_data,
+ [nameservice])),
+ IOR = ?match(#'IOP_IOR'{},
+ corba:string_to_object("corbaname::1.2@"++IP++":"++integer_to_list(ServerPort)++"/NameService#mamba")),
+
+ Relay = ?match({_,_,_,_,_,_}, orber_test_server:oe_create([], [{pseudo,true}])),
+ put(oe_server_in_context,
+ [#'IOP_ServiceContext'{context_id=?ORBER_GENERIC_CTX_ID,
+ context_data = {interface,
+ IP}}]),
+ ?match(ok,
+ orber_test_server:
+ relay_call(Relay,
+ [{context,
+ [#'IOP_ServiceContext'{context_id=?ORBER_GENERIC_CTX_ID,
+ context_data = {interface,
+ Loopback}}]}],
+ IOR)),
+ ?match([_,_], orber:iiop_connections(out)),
+ Conns = ?match([_,_],
+ orber_test_lib:remote_apply(ServerNode, orber, iiop_connections, [in])),
+ ?match(true, lists:keymember(Loopback, 1, Conns)),
+ ok.
+
+oneway_pseudo_implicit_context_api(doc) -> ["IIOP Implicit Contex tests (via pseudo object oneway)"];
+oneway_pseudo_implicit_context_api(suite) -> [];
+oneway_pseudo_implicit_context_api(_Config) ->
+ IP = orber_test_lib:get_host(),
+ Loopback = orber_test_lib:get_loopback_interface(),
+ {ok, ServerNode, _ServerHost} =
+ ?match({ok,_,_}, orber_test_lib:js_node([{flags, ?ORB_ENV_LOCAL_INTERFACE},
+ {ip_address, IP}])),
+ ServerPort = orber_test_lib:remote_apply(ServerNode, orber, iiop_port, []),
+ %% Create a remote server
+ ?match(ok, orber_test_lib:remote_apply(ServerNode, orber_test_lib,
+ install_test_data,
+ [nameservice])),
+ IOR = ?match(#'IOP_IOR'{},
+ corba:string_to_object("corbaname::1.2@"++IP++":"++integer_to_list(ServerPort)++"/NameService#mamba")),
+
+ Relay = ?match({_,_,_,_,_,_}, orber_test_server:oe_create([], [{pseudo,true}])),
+ ?match(ok,
+ orber_test_server:
+ relay_cast(Relay,
+ [{context,
+ [#'IOP_ServiceContext'{context_id=?ORBER_GENERIC_CTX_ID,
+ context_data = {interface,
+ Loopback}}]}],
+ IOR)),
+ ?match([_,_], orber:iiop_connections(out)),
+ Conns = ?match([_,_],
+ orber_test_lib:remote_apply(ServerNode, orber, iiop_connections, [in])),
+ ?match(true, lists:keymember(Loopback, 1, Conns)),
+ ok.
+
+oneway_pseudo_two_implicit_context_api(doc) ->
+ ["IIOP two Implicit Contex tests (via pseudo object oneway)"];
+oneway_pseudo_two_implicit_context_api(suite) -> [];
+oneway_pseudo_two_implicit_context_api(_Config) ->
+ IP = orber_test_lib:get_host(),
+ Loopback = orber_test_lib:get_loopback_interface(),
+ {ok, ServerNode, _ServerHost} =
+ ?match({ok,_,_}, orber_test_lib:js_node([{flags, ?ORB_ENV_LOCAL_INTERFACE},
+ {ip_address, IP}])),
+ ServerPort = orber_test_lib:remote_apply(ServerNode, orber, iiop_port, []),
+ %% Create a remote server
+ ?match(ok, orber_test_lib:remote_apply(ServerNode, orber_test_lib,
+ install_test_data,
+ [nameservice])),
+ IOR = ?match(#'IOP_IOR'{},
+ corba:string_to_object("corbaname::1.2@"++IP++":"++integer_to_list(ServerPort)++"/NameService#mamba")),
+
+ Relay = ?match({_,_,_,_,_,_}, orber_test_server:oe_create([], [{pseudo,true}])),
+ %% Add incoming implicit context which must be removed.
+ put(oe_server_in_context,
+ [#'IOP_ServiceContext'{context_id=?ORBER_GENERIC_CTX_ID,
+ context_data = {interface,
+ IP}}]),
+ ?match(ok,
+ orber_test_server:
+ relay_cast(Relay,
+ [{context,
+ [#'IOP_ServiceContext'{context_id=?ORBER_GENERIC_CTX_ID,
+ context_data = {interface,
+ Loopback}}]}],
+ IOR)),
+ ?match([_,_], orber:iiop_connections(out)),
+ Conns = ?match([_,_],
+ orber_test_lib:remote_apply(ServerNode, orber, iiop_connections, [in])),
+ ?match(true, lists:keymember(Loopback, 1, Conns)),
+ ok.
+
+
+
+multiple_accept_api(doc) -> ["IIOP Multiple Accept tests"];
+multiple_accept_api(suite) -> [];
+multiple_accept_api(_Config) ->
+ IP = orber_test_lib:get_host(),
+ Loopback = orber_test_lib:get_loopback_interface(),
+ {ok, ServerNode, _ServerHost} =
+ ?match({ok,_,_}, orber_test_lib:js_node([{flags, ?ORB_ENV_LOCAL_INTERFACE},
+ {ip_address, IP}])),
+ ServerPort = orber_test_lib:remote_apply(ServerNode, orber, iiop_port, []),
+ %% The server ORB doesn't listen to 127.0.0.1
+ ?match({'EXCEPTION',_},
+ corba:string_to_object("corbaloc::1.2@" ++Loopback++":"++integer_to_list(ServerPort)++"/NameService")),
+ ?match([], orber:iiop_connections(out)),
+
+ IOR1 = ?match(#'IOP_IOR'{},
+ corba:string_to_object("corbaloc::1.2@"++IP++":"++integer_to_list(ServerPort)++"/NameService")),
+ ?match({'external', {IP, ServerPort, _ObjectKey, _Counter, _TP, _NewHD}},
+ iop_ior:get_key(IOR1)),
+ ?match([_], orber:iiop_connections(out)),
+
+ {ok, Ref1} = ?match({ok, _},
+ orber_test_lib:remote_apply(ServerNode, orber,
+ add_listen_interface,
+ [Loopback, normal])),
+
+ IOR2 = ?match(#'IOP_IOR'{},
+ corba:string_to_object("corbaloc::1.2@"++Loopback++":"++integer_to_list(ServerPort)++"/NameService")),
+ ?match({'external', {Loopback, ServerPort, _ObjectKey, _Counter, _TP, _NewHD}},
+ iop_ior:get_key(IOR2)),
+ ?match([_,_], orber:iiop_connections(out)),
+
+ {ok, Ref2} = ?match({ok, _},
+ orber_test_lib:remote_apply(ServerNode, orber,
+ add_listen_interface,
+ [Loopback, normal, 9543])),
+ ?match({error, eaddrinuse},
+ orber_test_lib:remote_apply(ServerNode, orber,
+ add_listen_interface,
+ [Loopback, normal, 9543])),
+
+ IOR3 = ?match(#'IOP_IOR'{},
+ corba:string_to_object("corbaloc::1.2@"++Loopback++":9543/NameService")),
+ ?match({'external', {Loopback, 9543, _ObjectKey, _Counter, _TP, _NewHD}},
+ iop_ior:get_key(IOR3)),
+ ?match([_,_,_], orber:iiop_connections(out)),
+
+ ?match(ok,
+ orber_test_lib:remote_apply(ServerNode, orber,
+ remove_listen_interface, [Ref1])),
+ %% Wait a few seconds to be sure that the connections really has been removed.
+ timer:sleep(4000),
+ ?match([_,_], orber:iiop_connections(out)),
+
+ ?match(ok,
+ orber_test_lib:remote_apply(ServerNode, orber,
+ remove_listen_interface, [Ref2])),
+ %% Wait a few seconds to be sure that the connections really has been removed.
+ timer:sleep(4000),
+ ?match([_], orber:iiop_connections(out)),
+
+ ?match({'EXCEPTION',_},
+ corba:string_to_object("corbaloc::1.2@"++Loopback++":9543/NameService")),
+ ?match({'EXCEPTION',_},
+ corba:string_to_object("corbaloc::1.2@"++Loopback++":"++integer_to_list(ServerPort)++"/NameService")),
+
+ IOR4 = ?match(#'IOP_IOR'{},
+ corba:string_to_object("corbaloc::1.2@"++IP++":"++integer_to_list(ServerPort)++"/NameService")),
+ ?match({'external', {IP, ServerPort, _ObjectKey, _Counter, _TP, _NewHD}},
+ iop_ior:get_key(IOR4)),
+
+ ok.
+
+
+proxy_interface_api(doc) -> ["IIOP Proxy Interface tests",
+ "This case test if the server ORB use the correct",
+ "interface when exporting IOR:s"];
+proxy_interface_api(suite) -> [];
+proxy_interface_api(_Config) ->
+ IP = orber_test_lib:get_host(),
+ Loopback = orber_test_lib:get_loopback_interface(),
+ {ok, ServerNode, _ServerHost} =
+ ?match({ok,_,_}, orber_test_lib:js_node([{flags, ?ORB_ENV_LOCAL_INTERFACE}])),
+ ServerPort = orber_test_lib:remote_apply(ServerNode, orber, iiop_port, []),
+ IOR1 = ?match(#'IOP_IOR'{},
+ corba:string_to_object("corbaloc::1.2@"++IP++":"++integer_to_list(ServerPort)++"/NameService")),
+ ?match({'external', {IP, ServerPort, _ObjectKey, _Counter, _TP, _NewHD}},
+ iop_ior:get_key(IOR1)),
+ IOR2 = ?match(#'IOP_IOR'{},
+ corba:string_to_object("corbaloc::1.2@"++Loopback++":"++integer_to_list(ServerPort)++"/NameService")),
+ ?match({'external', {Loopback, ServerPort, _ObjectKey, _Counter, _TP, _NewHD}},
+ iop_ior:get_key(IOR2)),
+ ok.
+
+proxy_interface_ipv6_api(doc) -> ["IIOP Proxy Interface tests",
+ "This case test if the server ORB use the correct",
+ "IPv6 interface when exporting IOR:s"];
+proxy_interface_ipv6_api(suite) -> [];
+proxy_interface_ipv6_api(_Config) ->
+ case orber_test_lib:version_ok() of
+ true ->
+ proxy_interface_ipv6_api2();
+ Reason ->
+ Reason
+ end.
+
+proxy_interface_ipv6_api2() ->
+ Loopback = orber_test_lib:get_loopback_interface(inet6),
+ {ok, ServerNode, _ServerHost} =
+ ?match({ok,_,_}, orber_test_lib:js_node([{flags, (?ORB_ENV_USE_IPV6 bor
+ ?ORB_ENV_LOCAL_INTERFACE)}])),
+ ServerPort = orber_test_lib:remote_apply(ServerNode, orber, iiop_port, []),
+
+ {ok, ClientNode, _ClientHost} =
+ ?match({ok,_,_}, orber_test_lib:js_node([{flags, ?ORB_ENV_USE_IPV6}])),
+
+ IP = orber_test_lib:remote_apply(ClientNode, orber_test_lib, get_host, []),
+
+ IOR1 = ?match(#'IOP_IOR'{},
+ orber_test_lib:remote_apply(ClientNode, corba, string_to_object,
+ ["corbaloc::1.2@"++IP++":"++integer_to_list(ServerPort)++"/NameService"])),
+ ?match({'external', {IP, ServerPort, _ObjectKey, _Counter, _TP, _NewHD}},
+ orber_test_lib:remote_apply(ClientNode, iop_ior, get_key, [IOR1])),
+ IOR2 = ?match(#'IOP_IOR'{},
+ orber_test_lib:remote_apply(ClientNode, corba, string_to_object,
+ ["corbaloc::1.2@"++Loopback++":"++integer_to_list(ServerPort)++"/NameService"])),
+ ?match({'external', {Loopback, ServerPort, _ObjectKey, _Counter, _TP, _NewHD}},
+ orber_test_lib:remote_apply(ClientNode, iop_ior, get_key, [IOR2])),
+ ok.
+
+local_interface_api(doc) -> ["IIOP Local Interface tests",
+ "This case test if the server ORB use the correct",
+ "local interface when connecting to another ORB"];
+local_interface_api(suite) -> [];
+local_interface_api(_Config) ->
+ IP = orber_test_lib:get_host(),
+ Loopback = orber_test_lib:get_loopback_interface(),
+ {ok, ClientNode, _ClientHost} =
+ ?match({ok,_,_}, orber_test_lib:js_node([{ip_address_local, Loopback}])),
+ Port = orber:iiop_port(),
+ ?match(#'IOP_IOR'{},
+ orber_test_lib:remote_apply(ClientNode, corba, string_to_object,
+ ["corbaloc::1.2@"++IP++":"++integer_to_list(Port)++"/NameService"])),
+ [{Loopback, RemotePort}] =
+ ?match([{Loopback,_RemotePort}], orber:iiop_connections(in)),
+
+ ?match([{IP, Port}],
+ orber_test_lib:remote_apply(ClientNode, orber,
+ iiop_connections, [out])),
+ ?match([{IP, Port}], orber:find_sockname_by_peername(Loopback,RemotePort)),
+ ?match([{Loopback, RemotePort}], orber:find_peername_by_sockname(IP, Port)),
+
+ ?match([{Loopback, RemotePort}],
+ orber_test_lib:remote_apply(ClientNode, orber,
+ find_sockname_by_peername,
+ [IP, Port])),
+ ?match([{IP, Port}],
+ orber_test_lib:remote_apply(ClientNode, orber,
+ find_peername_by_sockname,
+ [Loopback,RemotePort])),
+
+
+ ok.
+
+local_interface_ctx_override_api(doc) ->
+ ["IIOP Local Interface tests",
+ "This case test if the server ORB use the correct",
+ "local interface when connecting to another ORB"];
+local_interface_ctx_override_api(suite) -> [];
+local_interface_ctx_override_api(_Config) ->
+ IP = orber_test_lib:get_host(),
+ Loopback = orber_test_lib:get_loopback_interface(),
+ {ok, ClientNode, _ClientHost} =
+ ?match({ok,_,_}, orber_test_lib:js_node([{ip_address_local, IP}])),
+ Port = orber:iiop_port(),
+ ?match(#'IOP_IOR'{},
+ orber_test_lib:remote_apply(ClientNode, corba, string_to_object,
+ ["corbaloc::1.2@"++IP++":"++integer_to_list(Port)++"/NameService",
+ [#'IOP_ServiceContext'
+ {context_id=?ORBER_GENERIC_CTX_ID,
+ context_data = {interface, Loopback}}]])),
+ [{Loopback, RemotePort}] =
+ ?match([{Loopback,_RemotePort}], orber:iiop_connections(in)),
+
+ ?match([{IP, Port, Loopback}],
+ orber_test_lib:remote_apply(ClientNode, orber,
+ iiop_connections, [out])),
+ ?match([{IP, Port}], orber:find_sockname_by_peername(Loopback,RemotePort)),
+ ?match([{Loopback, RemotePort}], orber:find_peername_by_sockname(IP, Port)),
+
+ ?match([{Loopback, RemotePort}],
+ orber_test_lib:remote_apply(ClientNode, orber,
+ find_sockname_by_peername,
+ [IP, Port])),
+ ?match([{IP, Port}],
+ orber_test_lib:remote_apply(ClientNode, orber,
+ find_peername_by_sockname,
+ [Loopback,RemotePort])),
+
+ ok.
+
+local_interface_acl_override_api(doc) ->
+ ["IIOP Local Interface tests",
+ "This case test if the server ORB use the correct",
+ "local interface when connecting to another ORB"];
+local_interface_acl_override_api(suite) -> [];
+local_interface_acl_override_api(_Config) ->
+ IP = orber_test_lib:get_host(),
+ Loopback = orber_test_lib:get_loopback_interface(),
+ ACL = [{tcp_out, IP ++ "/18", [Loopback]}],
+ {ok, ClientNode, _ClientHost} =
+ ?match({ok,_,_}, orber_test_lib:js_node([{ip_address_local, IP},
+ {iiop_acl, ACL},
+ {flags, ?ORB_ENV_USE_ACL_OUTGOING}])),
+ Port = orber:iiop_port(),
+ ?match(#'IOP_IOR'{},
+ orber_test_lib:remote_apply(ClientNode, corba, string_to_object,
+ ["corbaloc::1.2@"++IP++":"++integer_to_list(Port)++"/NameService",
+ [#'IOP_ServiceContext'
+ {context_id=?ORBER_GENERIC_CTX_ID,
+ context_data = {interface, IP}}]])),
+ ?match([{Loopback,_RemotePort}], orber:iiop_connections(in)),
+ ?match(#'IOP_IOR'{},
+ orber_test_lib:remote_apply(ClientNode, corba, string_to_object,
+ ["corbaloc::1.2@"++IP++":"++integer_to_list(Port)++"/NameService"])),
+
+ [{Loopback, RemotePort}] =
+ ?match([{Loopback,_RemotePort}], orber:iiop_connections(in)),
+ ?match([{IP, Port, IP}], orber_test_lib:remote_apply(ClientNode, orber,
+ iiop_connections, [out])),
+ ?match([{IP, Port}], orber:find_sockname_by_peername(Loopback,RemotePort)),
+ ?match([{Loopback, RemotePort}], orber:find_peername_by_sockname(IP, Port)),
+
+ ?match([{Loopback, RemotePort}],
+ orber_test_lib:remote_apply(ClientNode, orber,
+ find_sockname_by_peername,
+ [IP, Port])),
+ ?match([{IP, Port}],
+ orber_test_lib:remote_apply(ClientNode, orber,
+ find_peername_by_sockname,
+ [Loopback,RemotePort])),
+
+ ok.
+
+
+iiop_timeout_api(doc) -> ["IIOP TIMEOUT API tests",
+ "This case test if timeout configuration behaves correctly"];
+iiop_timeout_api(suite) -> [];
+iiop_timeout_api(_Config) ->
+
+ %% Install two secure orber.
+ {ok, ClientNode, ClientHost} =
+ ?match({ok,_,_}, orber_test_lib:js_node([{iiop_timeout, 6},
+ {iiop_connection_timeout, 3},
+ {iiop_in_connection_timeout, 3}])),
+ ClientPort = orber_test_lib:remote_apply(ClientNode, orber, iiop_port, []),
+
+ {ok, ServerNode, ServerHost} =
+ ?match({ok,_,_}, orber_test_lib:js_node([{iiop_timeout, 6},
+ {iiop_connection_timeout, 3},
+ {iiop_in_connection_timeout, 12}])),
+ ServerPort = orber_test_lib:remote_apply(ServerNode, orber, iiop_port, []),
+
+ ?match(ok, orber_test_lib:remote_apply(ServerNode, orber_test_lib,
+ install_test_data,
+ [timeout])),
+
+ %% Tell client_orb to interoperate with server_orb.
+ ?match(ok, orber_test_lib:remote_apply(ClientNode, orber_test_lib,
+ lookup,
+ [ServerHost, ServerPort])),
+ %% Interop worked fine, perform delay tests.
+ ?match(ok, orber_test_lib:remote_apply(ClientNode, orber_test_lib,
+ timeouts,
+ [ServerHost, ServerPort, 6000])),
+
+ %% Create a connection to the "client_orb", which will now act as server.
+ ?match({'IOP_IOR',_,_},
+ corba:string_to_object("corbaloc::1.2@"++ClientHost++":"++integer_to_list(ClientPort)++"/NameService")),
+ %% Check that the connection is established.
+ ?match([{_, ClientPort}], orber:iiop_connections(out)),
+ %% Wait >3 seconds (i.e. iiop_in_connection_timeout) and check if the connection
+ %% have been closed.
+ timer:sleep(8000),
+ ?match([], orber:iiop_connections(out)),
+
+ ?match(ok, orber_test_lib:remote_apply(ServerNode, orber_test_lib,
+ uninstall_test_data,
+ [timeout])),
+ ok.
+
+iiop_timeout_added_api(doc) -> ["IIOP TIMEOUT API tests",
+ "This case test if timeout configuration behaves correctly"];
+iiop_timeout_added_api(suite) -> [];
+iiop_timeout_added_api(_Config) ->
+ IP = orber_test_lib:get_host(),
+ {ok, Node, _Host} = ?match({ok,_,_}, orber_test_lib:js_node([])),
+ Port = 1 + orber_test_lib:remote_apply(Node, orber, iiop_port, []),
+ ?match({ok, _},
+ orber_test_lib:remote_apply(Node, orber,
+ add_listen_interface,
+ [IP, normal,
+ [{iiop_in_connection_timeout, 3},
+ {flags, ?ORB_ENV_LOCAL_INTERFACE},
+ {iiop_port, Port}]])),
+
+ ?match(ok, orber_test_lib:remote_apply(Node, orber_test_lib,
+ install_test_data,
+ [timeout])),
+
+ ?match({'IOP_IOR',_,_},
+ corba:string_to_object("corbaloc::1.2@"++IP++":"++integer_to_list(Port)++"/NameService")),
+ %% Check that the connection is established.
+ ?match([{_, Port}], orber:iiop_connections(out)),
+ %% Wait >3 seconds (i.e. iiop_in_connection_timeout) and check if the connection
+ %% have been closed.
+ timer:sleep(8000),
+ ?match([], orber:iiop_connections(out)),
+
+ ?match(ok, orber_test_lib:remote_apply(Node, orber_test_lib,
+ uninstall_test_data,
+ [timeout])),
+ ok.
+
+%%-----------------------------------------------------------------
+%% API tests for ORB to ORB using pseudo call/cast, no security
+%%-----------------------------------------------------------------
+
+multi_pseudo_orber_api(doc) ->
+ ["MULTI ORB PSEUDO API tests",
+ "This case test if data encode/decode (IIOP) for pseudo objects",
+ "produce the correct result, i.e., the test_server echos",
+ "the input parameter or an exception is raised (MARSHAL)."];
+multi_pseudo_orber_api(suite) -> [];
+multi_pseudo_orber_api(_Config) ->
+ %% --- Create a slave-node ---
+ {ok, Node, Host} =
+ ?match({ok,_,_}, orber_test_lib:js_node()),
+ Port = orber_test_lib:remote_apply(Node, orber, iiop_port, []),
+
+ ?match(ok, orber_test_lib:remote_apply(Node, orber_test_lib,
+ install_test_data,
+ [pseudo])),
+
+ NSR = ?match({'IOP_IOR',"IDL:omg.org/CosNaming/NamingContextExt:1.0",_},
+ corba:string_to_object("corbaloc::1.1@"++Host++":"++
+ integer_to_list(Port)++"/NameService")),
+ Obj =
+ ?match({'IOP_IOR',"IDL:omg.org/orber_test/server:1.0",_},
+ 'CosNaming_NamingContext':resolve(NSR, lname:new(["mamba"]))),
+ orber_test_lib:corba_object_tests(Obj, NSR),
+
+ %% Can we even contact the object?
+ ?match(ok, orber_test_server:print(Obj)),
+
+ %% Invoke one blocking call followed by several invokations.
+ spawn(?MODULE, pseudo_calls, [5, Obj]),
+ ?match({ok, 10000}, orber_test_server:pseudo_call_delay(Obj, 10000)),
+ spawn(?MODULE, pseudo_casts, [5, Obj]),
+ ?match(ok, orber_test_server:pseudo_cast_delay(Obj, 10000)),
+
+ %%--- Testing code and decode arguments ---
+ orber_test_lib:test_coding(Obj),
+
+ %% Test if exit is handled properly.
+ ?match({'EXCEPTION',{'TRANSIENT',_,_,_}},
+ orber_test_server:stop_brutal(Obj)),
+
+ ?match(ok, orber_test_lib:remote_apply(Node, orber_test_lib,
+ uninstall_test_data,
+ [pseudo])),
+ ok.
+
+
+%%-----------------------------------------------------------------
+%% API tests for ORB to ORB with local flags definition set.
+%%-----------------------------------------------------------------
+flags_added_api(doc) ->
+ ["MULTI ORB PSEUDO with local flags definition set"];
+flags_added_api(suite) -> [];
+flags_added_api(_Config) ->
+ %% --- Create a slave-node ---
+ IP = orber_test_lib:get_host(),
+ {ok, Node, _Host} =
+ ?match({ok,_,_}, orber_test_lib:js_node([])),
+ Port = 1 + orber_test_lib:remote_apply(Node, orber, iiop_port, []),
+ ?match({ok, _},
+ orber_test_lib:remote_apply(Node, orber,
+ add_listen_interface,
+ [IP, normal,
+ [{flags, (?ORB_ENV_LOCAL_INTERFACE bor
+ ?ORB_ENV_EXCLUDE_CODESET_COMPONENT)},
+ {iiop_port, Port}]])),
+
+ ?match(ok, orber_test_lib:remote_apply(Node, orber_test_lib,
+ install_test_data,
+ [pseudo])),
+ Obj = ?match({'IOP_IOR',"IDL:omg.org/orber_test/server:1.0",_},
+ corba:string_to_object("corbaname::1.1@"++IP++":"++
+ integer_to_list(Port)++"/NameService#mamba")),
+ ?match({'external', {IP, Port, _ObjectKey, _Counter,
+ #'IOP_TaggedProfile'{tag=?TAG_INTERNET_IOP,
+ profile_data=
+ #'IIOP_ProfileBody_1_1'{components=[]}},
+ _NewHD}},
+ iop_ior:get_key(Obj)),
+ ?match(ok, orber_test_lib:remote_apply(Node, orber_test_lib,
+ uninstall_test_data,
+ [pseudo])),
+
+ ok.
+
+
+
+%%-----------------------------------------------------------------
+%% API tests for ORB to ORB with limited concurrent requests
+%%-----------------------------------------------------------------
+max_requests_api(doc) ->
+ ["MULTI ORB PSEUDO with limited concurrent requests tests"];
+max_requests_api(suite) -> [];
+max_requests_api(_Config) ->
+ %% --- Create a slave-node ---
+ {ok, Node, Host} =
+ ?match({ok,_,_}, orber_test_lib:js_node([{iiop_max_in_requests, 1}])),
+ Port = orber_test_lib:remote_apply(Node, orber, iiop_port, []),
+ max_requests(Node, Host, Port).
+
+max_requests_added_api(doc) ->
+ ["MULTI ORB PSEUDO with limited concurrent requests tests"];
+max_requests_added_api(suite) -> [];
+max_requests_added_api(_Config) ->
+ %% --- Create a slave-node ---
+ [IP] = ?match([_], orber:host()),
+ {ok, Node, _Host} =
+ ?match({ok,_,_}, orber_test_lib:js_node([])),
+ Port = 1 + orber_test_lib:remote_apply(Node, orber, iiop_port, []),
+ ?match({ok, _},
+ orber_test_lib:remote_apply(Node, orber,
+ add_listen_interface,
+ [IP, normal,
+ [{iiop_max_in_requests, 1},
+ {flags, ?ORB_ENV_LOCAL_INTERFACE},
+ {iiop_port, Port}]])),
+ max_requests(Node, IP, Port).
+
+max_requests(Node, Host, Port) ->
+ ?match(ok, orber_test_lib:remote_apply(Node, orber_test_lib,
+ install_test_data,
+ [pseudo])),
+ Obj = ?match({'IOP_IOR',"IDL:omg.org/orber_test/server:1.0",_},
+ corba:string_to_object("corbaname::1.1@"++Host++":"++
+ integer_to_list(Port)++"/NameService#mamba")),
+
+ %% Can we even contact the object?
+ ?match(ok, orber_test_server:print(Obj)),
+
+ %% Invoke one blocking call followed by several invokations.
+ spawn(orber_test_server, pseudo_call_delay, [Obj, 15000]),
+ %% Wait for a second to be sure that the previous request has been sent
+ timer:sleep(1000),
+ {MegaSecsB, Before, _} = now(),
+ pseudo_calls(5, Obj),
+ {MegaSecsA, After, _} = now(),
+ %% Normally we we can perform hundreds of pseudo-calls per second. Hence,
+ %% if we add 8 seconds to 'Before' it should still be less since we only
+ %% allow one request at a time to the target ORB.
+ ?match(true, (MegaSecsB + (Before+8)*1000000) < (MegaSecsA + After*1000000)),
+
+ ?match(ok, orber_test_lib:remote_apply(Node, orber_test_lib,
+ uninstall_test_data,
+ [pseudo])),
+
+ ok.
+
+%%-----------------------------------------------------------------
+%% API tests for ORB to ORB with limited concurrent connections
+%%-----------------------------------------------------------------
+max_connections_api(doc) ->
+ ["MULTI ORB PSEUDO with limited concurrent connections tests"];
+max_connections_api(suite) -> [];
+max_connections_api(_Config) ->
+ %% --- Create a slave-node ---
+ {ok, ServerNode, ServerHost} =
+ ?match({ok,_,_}, orber_test_lib:js_node([{iiop_backlog, 0},
+ {iiop_max_in_connections, 2}])),
+ ServerPort = orber_test_lib:remote_apply(ServerNode, orber, iiop_port, []),
+ ?match(ok, orber_test_lib:remote_apply(ServerNode, orber_test_lib,
+ install_test_data,
+ [nameservice])),
+
+ %% Claim connection 1 & 2
+ Obj = ?match({'IOP_IOR',"IDL:omg.org/orber_test/server:1.0",_},
+ corba:string_to_object("corbaname::1.2@"++ServerHost++":"++
+ integer_to_list(ServerPort)++"/NameService#mamba")),
+ %% Claim backlog
+ {ok, ClientNode, _ClientHost} =
+ ?match({ok,_,_}, orber_test_lib:js_node()),
+
+ spawn(ClientNode, orber_test_server, print, [Obj]),
+ timer:sleep(5000),
+ ?match([_], orber_test_lib:remote_apply(ClientNode, orber,
+ iiop_connections, [])),
+
+ %% Try to connect. Should fail. Due to the behavior of different TCP stacks, backlog 1
+ %% might not be the precise value. Hence, we also need to define the iiop_timeout. Otherwise
+ %% this test case will fail. For the same reason we must GC this connection.
+ {ok, ClientNodeII, _ClientHostII} =
+ ?match({ok,_,_}, orber_test_lib:js_node([{iiop_setup_connection_timeout, 5},
+ {iiop_timeout, 5},
+ {iiop_connection_timeout, 8}])),
+
+ ?match({'EXCEPTION', _},
+ orber_test_lib:remote_apply(ClientNodeII, orber_test_server,
+ testing_iiop_string, [Obj, "Fail"])),
+
+ %% Remove 2 connections. We need to wait a moment so that both sides has detected it.
+ timer:sleep(5000),
+ ?match([_,_], orber:iiop_connections()),
+ ?match(ok, orber_iiop_pm:close_connection([{ServerHost, ServerPort}])),
+ timer:sleep(5000),
+ [{Host, Port}] = ?match([_], orber:iiop_connections()),
+ ?match(ok, orber_iiop_pm:close_connection([{Host, Port}])),
+ timer:sleep(5000),
+ ?match([], orber:iiop_connections()),
+
+ ?match([_], orber_test_lib:remote_apply(ClientNode, orber,
+ iiop_connections, [])),
+
+ ?match([], orber_test_lib:remote_apply(ClientNodeII, orber,
+ iiop_connections, [])),
+
+ ?match({ok, "OK"},
+ orber_test_lib:remote_apply(ClientNodeII, orber_test_server,
+ testing_iiop_string, [Obj, "OK"])),
+
+ timer:sleep(4000),
+ ?match([_], orber_test_lib:remote_apply(ClientNodeII, orber,
+ iiop_connections, [])),
+
+ ?match(ok, orber_test_lib:remote_apply(ServerNode, orber_test_lib,
+ uninstall_test_data,
+ [pseudo])),
+
+ ok.
+
+
+%%-----------------------------------------------------------------
+%% API tests for terminating connection by using an IOR.
+%%-----------------------------------------------------------------
+close_connections_api(doc) ->
+ ["Close outgoing connection "];
+close_connections_api(suite) -> [];
+close_connections_api(_Config) ->
+ %% --- Create a slave-node ---
+ IP = orber_test_lib:get_host(),
+ Loopback = orber_test_lib:get_loopback_interface(),
+ {ok, ServerNode, _ServerHost} =
+ ?match({ok,_,_}, orber_test_lib:js_node([{ip_address, IP}])),
+ ServerPort = orber_test_lib:remote_apply(ServerNode, orber, iiop_port, []),
+ ?match(ok, orber_test_lib:remote_apply(ServerNode, orber_test_lib,
+ install_test_data,
+ [nameservice])),
+ orber_test_lib:remote_apply(ServerNode, orber, iiop_port, []),
+ IP = orber_test_lib:get_host(),
+
+ %% Create a connection
+ Obj = ?match({'IOP_IOR',"IDL:omg.org/orber_test/server:1.0",_},
+ corba:string_to_object("corbaname::1.2@"++IP++":"++
+ integer_to_list(ServerPort)++"/NameService#mamba")),
+ %% Check that it's up.
+ ?match([{IP, ServerPort}], orber:iiop_connections(out)),
+ %% Try to close using the wronge interface.
+ ?match(ok, orber:close_connection(Obj, Loopback)),
+ %% Should still be up.
+ ?match([{IP, ServerPort}], orber:iiop_connections(out)),
+ %% Try to close it properly
+ ?match(ok, orber:close_connection(Obj)),
+ %% Wait a moment so that both sides has detected it.
+ timer:sleep(5000),
+ %% Worked?
+ ?match([], orber:iiop_connections(out)),
+ ok.
+
+
+close_connections_local_interface_api(doc) ->
+ ["IIOP Local Interface disconnect tests",
+ "This case test if the server ORB use the correct",
+ "local interface when connecting to another ORB"];
+close_connections_local_interface_api(suite) -> [];
+close_connections_local_interface_api(_Config) ->
+ IP = orber_test_lib:get_host(),
+ Loopback = orber_test_lib:get_loopback_interface(),
+ {ok, ClientNode, _ClientHost} =
+ ?match({ok,_,_}, orber_test_lib:js_node([{ip_address_local, Loopback}])),
+ {ok, ServerNode, _ServerHost} =
+ ?match({ok,_,_}, orber_test_lib:js_node([{ip_address, IP}])),
+ Port = orber_test_lib:remote_apply(ServerNode, orber, iiop_port, []),
+ IOR = ?match(#'IOP_IOR'{},
+ orber_test_lib:remote_apply(ClientNode, corba, string_to_object,
+ ["corbaloc::1.2@"++IP++":"++integer_to_list(Port)++"/NameService"])),
+
+ %% Check that the connnection is up and running using the default interface
+ ?match([{Loopback,_RemotePort}], orber_test_lib:remote_apply(ServerNode, orber,
+ iiop_connections, [in])),
+ ?match([{IP, Port}],
+ orber_test_lib:remote_apply(ClientNode, orber,
+ iiop_connections, [out])),
+ %% Try to close the connection
+ ?match(ok, orber_test_lib:remote_apply(ClientNode, orber,
+ close_connection, [IOR])),
+ %% Wait a moment so that both sides has detected it.
+ timer:sleep(5000),
+ %% Now the connection shall be gone.
+ ?match([], orber_test_lib:remote_apply(ClientNode, orber,
+ iiop_connections, [out])),
+ ?match([], orber_test_lib:remote_apply(ServerNode, orber,
+ iiop_connections, [in])),
+
+ ok.
+
+close_connections_local_interface_ctx_override_api(doc) ->
+ ["IIOP Local Interface disconnect tests",
+ "This case test if the server ORB use the correct",
+ "local interface when connecting to another ORB"];
+close_connections_local_interface_ctx_override_api(suite) -> [];
+close_connections_local_interface_ctx_override_api(_Config) ->
+ IP = orber_test_lib:get_host(),
+ Loopback = orber_test_lib:get_loopback_interface(),
+ {ok, ClientNode, _ClientHost} =
+ ?match({ok,_,_}, orber_test_lib:js_node([{ip_address_local, IP},
+ {ip_address, IP}])),
+ {ok, ServerNode, _ServerHost} =
+ ?match({ok,_,_}, orber_test_lib:js_node([{ip_address, IP}])),
+ Port = orber_test_lib:remote_apply(ServerNode, orber, iiop_port, []),
+ IOR = ?match(#'IOP_IOR'{},
+ orber_test_lib:remote_apply(ClientNode, corba, string_to_object,
+ ["corbaloc::1.2@"++IP++":"++integer_to_list(Port)++"/NameService",
+ [#'IOP_ServiceContext'
+ {context_id=?ORBER_GENERIC_CTX_ID,
+ context_data = {interface, Loopback}}]])),
+
+ timer:sleep(2000),
+ %% Check that the connnection is up and running using the default interface
+ ?match([{Loopback,_RemotePort}], orber_test_lib:remote_apply(ServerNode, orber,
+ iiop_connections, [in])),
+
+ ?match([{IP, Port, Loopback}],
+ orber_test_lib:remote_apply(ClientNode, orber,
+ iiop_connections, [out])),
+ %% Try to close not supplying the interface.
+ ?match(ok, orber_test_lib:remote_apply(ClientNode, orber,
+ close_connection, [IOR])),
+
+ timer:sleep(2000),
+ %% The connection shall still be up and running
+ ?match([{Loopback,_RemotePort}], orber_test_lib:remote_apply(ServerNode, orber,
+ iiop_connections, [in])),
+ ?match([{IP, Port, Loopback}],
+ orber_test_lib:remote_apply(ClientNode, orber,
+ iiop_connections, [out])),
+ %% Try to close not supplying the interface.
+ ?match(ok, orber_test_lib:remote_apply(ClientNode, orber,
+ close_connection, [IOR, IP])),
+
+ timer:sleep(2000),
+ %% The connection shall still be up and running
+ ?match([{Loopback,_RemotePort}], orber_test_lib:remote_apply(ServerNode, orber,
+ iiop_connections, [in])),
+ ?match([{IP, Port, Loopback}],
+ orber_test_lib:remote_apply(ClientNode, orber,
+ iiop_connections, [out])),
+
+ %% Try to close supplying the correct interface.
+ ?match(ok, orber_test_lib:remote_apply(ClientNode, orber,
+ close_connection, [IOR, Loopback])),
+ %% Wait a moment so that both sides has detected it.
+ timer:sleep(5000),
+ %% Now the connection shall be gone.
+ ?match([], orber_test_lib:remote_apply(ServerNode, orber,
+ iiop_connections, [in])),
+ ?match([], orber_test_lib:remote_apply(ClientNode, orber,
+ iiop_connections, [out])),
+ ok.
+
+close_connections_alt_iiop_addr_api(doc) ->
+ ["IIOP alternate address disconnect tests",
+ "This case test if the server ORB use the correct",
+ "local interface when connecting to another ORB"];
+close_connections_alt_iiop_addr_api(suite) -> [];
+close_connections_alt_iiop_addr_api(_Config) ->
+ %% --- Create a slave-node ---
+ Loopback = orber_test_lib:get_loopback_interface(),
+ IP = orber_test_lib:get_host(),
+ {ok, ServerNode, _ServerHost} =
+ ?match({ok,_,_}, orber_test_lib:js_node([{giop_version, {1, 2}},
+ {ip_address, {multiple, [IP, Loopback]}}])),
+ ServerPort = orber_test_lib:remote_apply(ServerNode, orber, iiop_port, []),
+ ?match(ok, orber_test_lib:remote_apply(ServerNode, orber_test_lib,
+ install_test_data,
+ [{nameservice, Loopback, ServerPort}])),
+ %% Create two connections
+ Obj = ?match({'IOP_IOR',"IDL:omg.org/orber_test/server:1.0",_},
+ corba:string_to_object("corbaname::1.2@"++IP++":"++
+ integer_to_list(ServerPort)++"/NameService#mamba")),
+ ?match({'IOP_IOR',"IDL:omg.org/orber_test/server:1.0",_},
+ corba:string_to_object("corbaname::1.2@"++Loopback++":"++
+ integer_to_list(ServerPort)++"/NameService#mamba")),
+ timer:sleep(2000),
+ %% The connection shall still be up and running
+ ?match([{_,_}, {_,_}], orber:iiop_connections(out)),
+ ?match([{_,_}, {_,_}],
+ orber_test_lib:remote_apply(ServerNode, orber,
+ iiop_connections, [in])),
+
+ %% Try to close the connection
+ ?match(ok, orber:close_connection(Obj)),
+ %% Wait a moment so that both sides has detected it.
+ timer:sleep(5000),
+ %% Now the connections shall be gone.
+ ?match([], orber:iiop_connections(out)),
+ ?match([], orber_test_lib:remote_apply(ServerNode, orber,
+ iiop_connections, [in])),
+ ok.
+
+close_connections_multiple_profiles_api(doc) ->
+ ["IIOP alternate address disconnect tests",
+ "This case test if the server ORB use the correct",
+ "local interface when connecting to another ORB"];
+close_connections_multiple_profiles_api(suite) -> [];
+close_connections_multiple_profiles_api(_Config) ->
+ IP = orber_test_lib:get_host(),
+ Loopback = orber_test_lib:get_loopback_interface(),
+ %% --- Create a slave-node ---
+ {ok, ServerNode, _ServerHost} =
+ ?match({ok,_,_}, orber_test_lib:js_node([{ip_address,
+ {multiple, [Loopback, IP]}}])),
+ ServerPort = orber_test_lib:remote_apply(ServerNode, orber, iiop_port, []),
+ ?match(ok, orber_test_lib:remote_apply(ServerNode, orber_test_lib,
+ install_test_data, [nameservice])),
+ %% Create two connections
+ Obj = ?match({'IOP_IOR',"IDL:omg.org/orber_test/server:1.0",_},
+ corba:string_to_object("corbaname::1.2@"++IP++":"++
+ integer_to_list(ServerPort)++"/NameService#mamba")),
+ ?match({'IOP_IOR',"IDL:omg.org/orber_test/server:1.0",_},
+ corba:string_to_object("corbaname::1.2@"++Loopback++":"++
+ integer_to_list(ServerPort)++"/NameService#mamba")),
+ %% The connection shall still be up and running
+ ?match([{_,_}, {_,_}], orber:iiop_connections(out)),
+ ?match([{_,_}, {_,_}],
+ orber_test_lib:remote_apply(ServerNode, orber,
+ iiop_connections, [in])),
+
+ %% Try to close the connection
+ ?match(ok, orber:close_connection(Obj)),
+ %% Wait a moment so that both sides has detected it.
+ timer:sleep(5000),
+ %% Now the connections shall be gone.
+ ?match([], orber:iiop_connections(out)),
+ ?match([], orber_test_lib:remote_apply(ServerNode, orber,
+ iiop_connections, [in])),
+ ok.
+
+%%-----------------------------------------------------------------
+%% API tests for ORB to ORB with iiop_packet_size set
+%%-----------------------------------------------------------------
+max_packet_size_exceeded_api(doc) ->
+ ["Exceed the maximum request size"];
+max_packet_size_exceeded_api(suite) -> [];
+max_packet_size_exceeded_api(_Config) ->
+ case catch gen_tcp:listen(0, [{packet,cdr}, {packet_size, 14}]) of
+ {'EXIT',badarg} ->
+ {skipped, "The inet option {packet_size, Max} not supported"};
+ {ok, LS} ->
+ (catch gen_tcp:close(LS)),
+ %% --- Create a slave-node ---
+ {ok, ServerNode, ServerHost} =
+ ?match({ok,_,_}, orber_test_lib:js_node([{iiop_packet_size, 1}])),
+ ServerPort = orber_test_lib:remote_apply(ServerNode, orber,
+ iiop_port, []),
+ ?match({'EXCEPTION', #'CosNaming_NamingContextExt_InvalidAddress'{}},
+ corba:string_to_object("corbaloc::1.2@"++ServerHost++":"++integer_to_list(ServerPort)++"/NameService")),
+ ok
+ end.
+
+%%-----------------------------------------------------------------
+%% API tests for ORB to ORB with iiop_packet_size set
+%%-----------------------------------------------------------------
+max_packet_size_ok_api(doc) ->
+ ["Not exceed the maximum request size"];
+max_packet_size_ok_api(suite) -> [];
+max_packet_size_ok_api(_Config) ->
+ case catch gen_tcp:listen(0, [{packet,cdr}, {packet_size, 14}]) of
+ {'EXIT',badarg} ->
+ {skipped, "The inet option {packet_size, Max} not supported"};
+ {ok, LS} ->
+ (catch gen_tcp:close(LS)),
+ %% --- Create a slave-node ---
+ {ok, ServerNode, ServerHost} =
+ ?match({ok,_,_}, orber_test_lib:js_node([{iiop_packet_size, 5000}])),
+ ServerPort = orber_test_lib:remote_apply(ServerNode, orber,
+ iiop_port, []),
+ ?match({'IOP_IOR',_,_},
+ corba:string_to_object("corbaloc::1.2@"++ServerHost++":"++integer_to_list(ServerPort)++"/NameService")),
+ ok
+ end.
+
+
+
+%%-----------------------------------------------------------------
+%% API tests for ORB to ORB, no security
+%%-----------------------------------------------------------------
+
+light_ifr_api(doc) -> ["LIGHT IFR ORB API tests"];
+light_ifr_api(suite) -> [];
+light_ifr_api(_Config) ->
+
+ {ok, ClientNode, _ClientHost} =
+ ?match({ok,_,_}, orber_test_lib:js_node([{flags, 128}])),
+
+ ?match([_,_,_,_], orber_test_lib:remote_apply(ClientNode, orber, get_tables, [])),
+ ?match(ok, orber_test_lib:remote_apply(ClientNode, orber_test_lib,
+ install_test_data,
+ [nameservice])),
+
+
+ {ok, ServerNode, ServerHost} =
+ ?match({ok,_,_}, orber_test_lib:js_node([{flags, 128}])),
+ ServerPort = orber_test_lib:remote_apply(ServerNode, orber, iiop_port, []),
+ ?match(ok, orber_test_lib:remote_apply(ServerNode, orber_test_lib,
+ install_test_data,
+ [nameservice])),
+ ?match([_,_,_,_], orber_test_lib:remote_apply(ServerNode, orber, get_tables, [])),
+
+ Obj = ?match({'IOP_IOR',_,_},
+ corba:string_to_object("corbaname::1.2@"++ServerHost++":"++integer_to_list(ServerPort)++"/NameService#mamba")),
+ ?match(ok, orber_test_lib:remote_apply(ClientNode, orber_test_lib, test_coding, [Obj])),
+
+ ?match(0, orber_test_lib:remote_apply(ClientNode, orber_diagnostics, missing_modules, [])),
+
+ ?match(ok, orber_test_lib:remote_apply(ClientNode, mnesia, dirty_write,
+ [#orber_light_ifr{id = "FakeId1",
+ module=non_existing,
+ type=?IFR_StructDef}])),
+ ?match(ok, orber_test_lib:remote_apply(ClientNode, mnesia, dirty_write,
+ [#orber_light_ifr{id = "FakeId2",
+ module=non_existing,
+ type=?IFR_UnionDef}])),
+ ?match(ok, orber_test_lib:remote_apply(ClientNode, mnesia, dirty_write,
+ [#orber_light_ifr{id = "FakeId3",
+ module=non_existing,
+ type=?IFR_ExceptionDef}])),
+ ?match(ok, orber_test_lib:remote_apply(ClientNode, mnesia, dirty_write,
+ [#orber_light_ifr{id = "FakeId4",
+ module=non_existing,
+ type=?IFR_InterfaceDef}])),
+ ?match(ok, orber_test_lib:remote_apply(ClientNode, mnesia, dirty_write,
+ [#orber_light_ifr{id = "FakeId5",
+ module=orber_test_lib,
+ type=?IFR_InterfaceDef}])),
+ ?match(5, orber_test_lib:remote_apply(ClientNode, orber_diagnostics, missing_modules, [])),
+
+
+ ?match(ok, mnesia:dirty_write(#ir_UnionDef{ir_Internal_ID = "FakedIId1",
+ absolute_name="::Module::NonExisting"})),
+ ?match(ok, mnesia:dirty_write(#ir_StructDef{ir_Internal_ID = "FakedIId2",
+ absolute_name="::Module::NonExisting"})),
+ ?match(ok, mnesia:dirty_write(#ir_ExceptionDef{ir_Internal_ID = "FakedIId3",
+ absolute_name="::Module::NonExisting"})),
+ ?match(ok, mnesia:dirty_write(#ir_InterfaceDef{ir_Internal_ID = "FakedIId4",
+ absolute_name="::Module::NonExisting"})),
+ ?match(ok, mnesia:dirty_write(#ir_InterfaceDef{ir_Internal_ID = "FakedIId5",
+ absolute_name="::orber::test::lib"})),
+
+ ?match(5, orber_diagnostics:missing_modules()),
+
+ ?match(ok, orber_test_lib:remote_apply(ServerNode, orber_test_lib,
+ uninstall_test_data,
+ [nameservice])),
+ ?match(ok, orber_test_lib:remote_apply(ClientNode, orber_test_lib,
+ uninstall_test_data,
+ [nameservice])),
+ ok.
+
+%%-----------------------------------------------------------------
+%% API tests for ORB to ORB, no security
+%%-----------------------------------------------------------------
+
+light_orber_api(doc) -> ["LIGHT ORB API tests",
+ "This case test if a light Orber can communicate correctly",
+ "with an fully installed Orber."];
+light_orber_api(suite) -> [];
+light_orber_api(_Config) ->
+ %% --- Create a slave-node ---
+ LocalHost = net_adm:localhost(),
+ {ok, Node, _Host} =
+ ?match({ok,_,_}, orber_test_lib:js_node([{lightweight, ["iiop://"++LocalHost++":"++integer_to_list(orber:iiop_port())]}],
+ lightweight)),
+ ?match(ok, orber:info(io)),
+ ?match([_], orber_test_lib:remote_apply(Node, orber_env, get_lightweight_nodes,[])),
+
+ ?match(ok, orber_test_lib:remote_apply(Node, orber_test_lib,
+ install_test_data,
+ [light])),
+
+ Obj1=(catch orber_test_server:oe_create(state,[{pseudo,true}])),
+ ?match({_,pseudo,orber_test_server_impl, _,_, _}, Obj1),
+ Obj2=(catch orber_test_server:oe_create(state,[])),
+ ?match({_,key,_, _,_, _}, Obj2),
+
+ NS = corba:resolve_initial_references("NameService"),
+ 'CosNaming_NamingContext':bind(NS, lname:new(["mamba"]), Obj1),
+ 'CosNaming_NamingContext':bind(NS, lname:new(["viper"]), Obj2),
+
+ ?match(ok, orber_test_lib:remote_apply(Node, orber_test_lib,
+ light_tests,
+ [LocalHost,
+ orber:iiop_port(), "viper"])),
+ ?match(ok, orber_test_lib:remote_apply(Node, orber_test_lib,
+ light_tests,
+ [LocalHost,
+ orber:iiop_port(), "mamba"])),
+
+ %% Clean up.
+
+ catch corba:dispose(Obj1),
+ catch corba:dispose(Obj2),
+ catch 'CosNaming_NamingContext':destroy(NS),
+
+ ?match(ok, orber_test_lib:remote_apply(Node, orber_test_lib,
+ uninstall_test_data,
+ [light])),
+ ok.
+%%-----------------------------------------------------------------
+%% API tests for ORB to ORB, no security
+%%-----------------------------------------------------------------
+
+light_orber2_api(doc) -> ["LIGHT ORB API tests",
+ "This case test if a light Orber can communicate correctly",
+ "with an fully installed Orber. This case test if we can",
+ "start as lightweight without first setting the environment",
+ "variable"];
+light_orber2_api(suite) -> [];
+light_orber2_api(_Config) ->
+ %% --- Create a slave-node ---
+ LocalHost = net_adm:localhost(),
+ {ok, Node, _Host} =
+ ?match({ok,_,_}, orber_test_lib:js_node([],
+ {lightweigth, ["iiop://"++LocalHost++":"++integer_to_list(orber:iiop_port())]})),
+ ?match(ok, orber:info(io)),
+ ?match([_], orber_test_lib:remote_apply(Node, orber_env, get_lightweight_nodes,[])),
+
+ ?match(ok, orber_test_lib:remote_apply(Node, orber_test_lib,
+ install_test_data,
+ [light])),
+
+ Obj1=(catch orber_test_server:oe_create(state,[{pseudo,true}])),
+ ?match({_,pseudo,orber_test_server_impl, _,_, _}, Obj1),
+ Obj2=(catch orber_test_server:oe_create(state,[])),
+ ?match({_,key,_, _,_, _}, Obj2),
+
+ NS = corba:resolve_initial_references("NameService"),
+ 'CosNaming_NamingContext':bind(NS, lname:new(["mamba"]), Obj1),
+ 'CosNaming_NamingContext':bind(NS, lname:new(["viper"]), Obj2),
+
+ ?match(ok, orber_test_lib:remote_apply(Node, orber_test_lib,
+ light_tests,
+ [LocalHost,
+ orber:iiop_port(), "viper"])),
+ ?match(ok, orber_test_lib:remote_apply(Node, orber_test_lib,
+ light_tests,
+ [LocalHost,
+ orber:iiop_port(), "mamba"])),
+
+ %% Clean up.
+
+ catch corba:dispose(Obj1),
+ catch corba:dispose(Obj2),
+ catch 'CosNaming_NamingContext':destroy(NS),
+
+ ?match(ok, orber_test_lib:remote_apply(Node, orber_test_lib,
+ uninstall_test_data,
+ [light])),
+ ok.
+
+%%-----------------------------------------------------------------
+%% API tests for ORB to ORB, no security
+%%-----------------------------------------------------------------
+
+multi_orber_api(doc) -> ["MULTI ORB API tests",
+ "This case test if data encode/decode (IIOP)",
+ "produce the correct result, i.e., the test_server echos",
+ "the input parameter or an exception is raised (MARSHAL)."];
+multi_orber_api(suite) -> [];
+multi_orber_api(_Config) ->
+
+ NewICObj1 = ?match({_,_,_,_,_,_}, orber_test_server:oe_create([])),
+ NewICObj2 = ?match({_,_,_,_,_,_}, orber_test_server:oe_create([], [{regname, {local, newic2}}])),
+ NewICObj3 = ?match({_,_,_,_,_,_}, orber_test_server:oe_create([], [{regname, {global, newic3}}])),
+ ?match(ok, orber_test_server:print(NewICObj1)),
+ ?match(ok, orber_test_server:print(NewICObj2)),
+ ?match(ok, orber_test_server:print(NewICObj3)),
+ catch corba:dispose(NewICObj1),
+ catch corba:dispose(NewICObj2),
+ catch corba:dispose(NewICObj3),
+
+ %% --- Create a slave-node ---
+ {ok, Node, Host} =
+ ?match({ok,_,_}, orber_test_lib:js_node()),
+ Port = orber_test_lib:remote_apply(Node, orber, iiop_port, []),
+
+ ?match(ok, orber_test_lib:remote_apply(Node, orber_test_lib,
+ install_test_data,
+ [nameservice])),
+
+ NSR = ?match({'IOP_IOR',"IDL:omg.org/CosNaming/NamingContextExt:1.0",_},
+ corba:string_to_object("corbaloc::1.2@"++Host++":"++
+ integer_to_list(Port)++"/NameService")),
+
+ ?match({'EXCEPTION',{'CosNaming_NamingContext_NotFound',_,_,_}},
+ 'CosNaming_NamingContext':resolve(NSR, lname:new(["not_exist"]))),
+
+ Obj = ?match({'IOP_IOR',"IDL:omg.org/orber_test/server:1.0",_},
+ 'CosNaming_NamingContext':resolve(NSR, lname:new(["mamba"]))),
+ ?match(ok, orber_test_server:print(Obj)),
+
+ Obj12B = ?match({'IOP_IOR',_,_},
+ corba:string_to_object("corbaloc::1.2@"++Host++":"++integer_to_list(Port)++"/Mamba")),
+
+ Obj11B = ?match({'IOP_IOR',_,_},
+ corba:string_to_object("corbaloc::1.1@"++Host++":"++integer_to_list(Port)++"/Mamba")),
+
+ Obj10B = ?match({'IOP_IOR',_,_},
+ corba:string_to_object("corbaloc::1.0@"++Host++":"++integer_to_list(Port)++"/Mamba")),
+
+ context_test(Obj12B),
+ context_test(Obj11B),
+
+ ?match(ok, orber_test_server:print(Obj12B)),
+ ?match(ok, orber_test_server:print(Obj11B)),
+ ?match(ok, orber_test_server:print(Obj10B)),
+ ?match({'EXCEPTION',{'CosNaming_NamingContextExt_InvalidAddress',_}},
+ corba:string_to_object("corbaloc::1.0@"++Host++":"++integer_to_list(Port)++"/Wrong")),
+
+ ?match(ok, orber_test_lib:corba_object_tests(Obj12B, NSR)),
+ ?match(ok, orber_test_lib:corba_object_tests(Obj11B, NSR)),
+ ?match(ok, orber_test_lib:corba_object_tests(Obj10B, NSR)),
+
+ %%--- Testing code and decode arguments ---
+ orber_test_lib:test_coding(Obj),
+
+ ?match({'EXCEPTION',#'BAD_CONTEXT'{}},
+ orber_test_server:
+ print(Obj12B,
+ [{context,
+ [#'IOP_ServiceContext'{context_id=?ORBER_GENERIC_CTX_ID,
+ context_data = {interface,
+ {127,0,0,1}}}]}])),
+
+ ?match({'EXCEPTION',{'TRANSIENT',_,_,_}},
+ orber_test_server:stop_brutal(Obj12B)),
+ ?match({'EXCEPTION',{'TRANSIENT',_,_,_}},
+ orber_test_server:print(Obj12B)),
+
+ ?match(ok, orber_test_lib:remote_apply(Node, orber_test_lib,
+ uninstall_test_data,
+ [nameservice])),
+ ok.
+
+
+%%-----------------------------------------------------------------
+%% API tests for ORB to ORB, no security, using basic interceptors
+%%-----------------------------------------------------------------
+basic_PI_api(doc) -> ["MULTI ORB API tests",
+ "This case test if data encode/decode (IIOP)",
+ "produce the correct result when using basic interceptors,",
+ "i.e., the test_server echos",
+ "the input parameter or an exception is raised (MARSHAL)."];
+basic_PI_api(suite) -> [];
+basic_PI_api(_Config) ->
+ %% Change configuration to use Basic Interceptors.
+ orber:configure_override(interceptors, {native, [orber_test_lib]}),
+ %% --- Create a slave-node ---
+ {ok, Node, Host} =
+ ?match({ok,_,_}, orber_test_lib:js_node([{interceptors, {native, [orber_test_lib]}}])),
+ Port = orber_test_lib:remote_apply(Node, orber, iiop_port, []),
+
+ ?match(ok, orber_test_lib:remote_apply(Node, orber_test_lib,
+ install_test_data,
+ [nameservice])),
+
+ Obj12 = ?match({'IOP_IOR',"IDL:omg.org/orber_test/server:1.0",_},
+ corba:string_to_object("corbaname::1.2@"++Host++":"++integer_to_list(Port)++"/NameService#mamba")),
+
+ Obj11 = ?match({'IOP_IOR',"IDL:omg.org/orber_test/server:1.0",_},
+ corba:string_to_object("corbaname::1.1@"++Host++":"++integer_to_list(Port)++"/NameService#mamba")),
+
+ Obj10 = ?match({'IOP_IOR',"IDL:omg.org/orber_test/server:1.0",_},
+ corba:string_to_object("corbaname::1.0@"++Host++":"++integer_to_list(Port)++"/NameService#mamba")),
+
+ ?match(ok, corba:print_object(Obj12)),
+ ?match(ok, corba:print_object(Obj11, error_report)),
+ ?match(ok, corba:print_object(Obj10, {error_report, "Reason"})),
+
+ ?match(ok, orber_test_server:print(Obj12)),
+ ?match(ok, orber_test_server:print(Obj11)),
+ ?match(ok, orber_test_server:print(Obj10)),
+
+
+ Obj12B = ?match({'IOP_IOR',_,_},
+ corba:string_to_object("corbaloc::1.2@"++Host++":"++integer_to_list(Port)++"/Mamba")),
+
+ Obj11B = ?match({'IOP_IOR',_,_},
+ corba:string_to_object("corbaloc::1.1@"++Host++":"++integer_to_list(Port)++"/Mamba")),
+
+ Obj10B = ?match({'IOP_IOR',_,_},
+ corba:string_to_object("corbaloc::1.0@"++Host++":"++integer_to_list(Port)++"/Mamba")),
+
+ ?match(ok, corba:print_object(Obj12B, info_msg)),
+ ?match(ok, corba:print_object(Obj11B, {info_msg, "Comment"})),
+ ?match([_|_], corba:print_object(Obj10B, string)),
+
+ ?match(ok, orber_test_server:print(Obj12B)),
+ ?match(ok, orber_test_server:print(Obj11B)),
+ ?match(ok, orber_test_server:print(Obj10B)),
+ ?match({'EXCEPTION',{'CosNaming_NamingContextExt_InvalidAddress',_}},
+ corba:string_to_object("corbaloc::1.0@"++Host++":"++integer_to_list(Port)++"/Wrong")),
+
+ ?match(ok, orber_test_lib:alternate_iiop_address(Host, Port)),
+
+ context_test(Obj12B),
+ context_test(Obj11B),
+
+ %%--- Testing code and decode arguments ---
+ orber_test_lib:test_coding(Obj12),
+ orber_test_lib:test_coding(Obj11),
+ orber_test_lib:test_coding(Obj10),
+
+ application:set_env(orber, interceptors, false),
+
+ ?match(ok, orber_test_lib:remote_apply(Node, orber_test_lib,
+ uninstall_test_data,
+ [nameservice])),
+ ok.
+
+
+%%-----------------------------------------------------------------
+%% API tests for ORB to ORB, ssl security depth 1
+%%-----------------------------------------------------------------
+
+ssl_1_multi_orber_api(doc) -> ["SECURE MULTI ORB API tests (SSL depth 1)",
+ "This case set up two secure orbs and test if they can",
+ "communicate. The case also test to access one of the",
+ "secure orbs which must raise a NO_PERMISSION exception."];
+ssl_1_multi_orber_api(suite) -> [];
+ssl_1_multi_orber_api(_Config) ->
+ case os:type() of
+ vxworks ->
+ {skipped, "No SSL-support for VxWorks."};
+ _ ->
+ ServerOptions = orber_test_lib:get_options(iiop_ssl, server,
+ 1, [{iiop_ssl_port, 0}]),
+ ClientOptions = orber_test_lib:get_options(iiop_ssl, client,
+ 1, [{iiop_ssl_port, 0}]),
+ ssl_suite(ServerOptions, ClientOptions),
+ ok
+ end.
+
+ssl_1_multi_orber_generation_3_api(doc) -> ["SECURE MULTI ORB API tests (SSL depth 1)",
+ "This case set up two secure orbs and test if they can",
+ "communicate. The case also test to access one of the",
+ "secure orbs which must raise a NO_PERMISSION exception."];
+ssl_1_multi_orber_generation_3_api(suite) -> [];
+ssl_1_multi_orber_generation_3_api(_Config) ->
+ case os:type() of
+ vxworks ->
+ {skipped, "No SSL-support for VxWorks."};
+ _ ->
+ case orber_test_lib:ssl_version() of
+ 3 ->
+ ServerOptions = orber_test_lib:get_options(iiop_ssl, server,
+ 1, [{ssl_generation, 3},
+ {iiop_ssl_port, 0}]),
+ ClientOptions = orber_test_lib:get_options(iiop_ssl, client,
+ 1, [{ssl_generation, 3},
+ {iiop_ssl_port, 0}]),
+ ssl_suite(ServerOptions, ClientOptions),
+ ok;
+ _ ->
+ {skipped, "Required SSL generation not available"}
+ end
+ end.
+
+
+%%-----------------------------------------------------------------
+%% API tests for ORB to ORB, ssl security depth 2
+%%-----------------------------------------------------------------
+
+ssl_2_multi_orber_api(doc) -> ["SECURE MULTI ORB API tests (SSL depth 2)",
+ "This case set up two secure orbs and test if they can",
+ "communicate. The case also test to access one of the",
+ "secure orbs which must raise a NO_PERMISSION exception."];
+ssl_2_multi_orber_api(suite) -> [];
+ssl_2_multi_orber_api(_Config) ->
+ case os:type() of
+ vxworks ->
+ {skipped, "No SSL-support for VxWorks."};
+ _ ->
+ ServerOptions = orber_test_lib:get_options(iiop_ssl, server,
+ 2, [{iiop_ssl_port, 0}]),
+ ClientOptions = orber_test_lib:get_options(iiop_ssl, client,
+ 2, [{iiop_ssl_port, 0}]),
+ ssl_suite(ServerOptions, ClientOptions),
+ ok
+ end.
+
+ssl_2_multi_orber_generation_3_api(doc) -> ["SECURE MULTI ORB API tests (SSL depth 2)",
+ "This case set up two secure orbs and test if they can",
+ "communicate. The case also test to access one of the",
+ "secure orbs which must raise a NO_PERMISSION exception."];
+ssl_2_multi_orber_generation_3_api(suite) -> [];
+ssl_2_multi_orber_generation_3_api(_Config) ->
+ case os:type() of
+ vxworks ->
+ {skipped, "No SSL-support for VxWorks."};
+ _ ->
+ case orber_test_lib:ssl_version() of
+ 3 ->
+ ServerOptions = orber_test_lib:get_options(iiop_ssl, server,
+ 2, [{ssl_generation, 3},
+ {iiop_ssl_port, 0}]),
+ ClientOptions = orber_test_lib:get_options(iiop_ssl, client,
+ 2, [{ssl_generation, 3},
+ {iiop_ssl_port, 0}]),
+ ssl_suite(ServerOptions, ClientOptions),
+ ok;
+ _ ->
+ {skipped, "Required SSL generation not available"}
+ end
+ end.
+%%-----------------------------------------------------------------
+%% API tests for ORB to ORB, ssl security depth 2
+%%-----------------------------------------------------------------
+
+ssl_reconfigure_api(doc) -> ["SECURE MULTI ORB API tests (SSL depth 2)",
+ "This case set up two secure orbs and test if they can",
+ "communicate. The case also test to access one of the",
+ "secure orbs which must raise a NO_PERMISSION exception."];
+ssl_reconfigure_api(suite) -> [];
+ssl_reconfigure_api(_Config) ->
+ ssl_reconfigure([]).
+
+ssl_reconfigure_generation_3_api(doc) -> ["SECURE MULTI ORB API tests (SSL depth 2)",
+ "This case set up two secure orbs and test if they can",
+ "communicate. The case also test to access one of the",
+ "secure orbs which must raise a NO_PERMISSION exception."];
+ssl_reconfigure_generation_3_api(suite) -> [];
+ssl_reconfigure_generation_3_api(_Config) ->
+ case orber_test_lib:ssl_version() of
+ 3 ->
+ ssl_reconfigure([{ssl_generation, 3}]);
+
+ _ ->
+ {skipped, "Required SSL generation not available"}
+ end.
+
+ssl_reconfigure(ExtraSSLOptions) ->
+ case os:type() of
+ vxworks ->
+ {skipped, "No SSL-support for VxWorks."};
+ _ ->
+ IP = orber_test_lib:get_host(),
+ Loopback = orber_test_lib:get_loopback_interface(),
+ {ok, ServerNode, _ServerHost} =
+ ?match({ok,_,_},
+ orber_test_lib:js_node([{iiop_port, 0},
+ {flags, ?ORB_ENV_LOCAL_INTERFACE},
+ {ip_address, IP}|ExtraSSLOptions])),
+ orber_test_lib:remote_apply(ServerNode, ssl, start, []),
+ orber_test_lib:remote_apply(ServerNode, crypto, start, []),
+ orber_test_lib:remote_apply(ServerNode, ssl, seed, ["testing"]),
+ ?match(ok, orber_test_lib:remote_apply(ServerNode, orber_test_lib,
+ install_test_data,
+ [ssl])),
+ ?match({ok, _},
+ orber_test_lib:remote_apply(ServerNode, orber,
+ add_listen_interface,
+ [Loopback, normal, [{iiop_port, 5648},
+ {iiop_ssl_port, 5649},
+ {interceptors, {native, [orber_iiop_tracer_silent]}}|ExtraSSLOptions]])),
+ ServerOptions = orber_test_lib:get_options(iiop_ssl, server,
+ 2, [{flags, ?ORB_ENV_LOCAL_INTERFACE},
+ {iiop_port, 5648},
+ {iiop_ssl_port, 5649},
+ {interceptors, {native, [orber_iiop_tracer_silent]}}|ExtraSSLOptions]),
+ ?match({ok, _},
+ orber_test_lib:remote_apply(ServerNode, orber,
+ add_listen_interface,
+ [Loopback, ssl, ServerOptions])),
+
+ ClientOptions = orber_test_lib:get_options(iiop_ssl, client,
+ 2, [{iiop_ssl_port, 0}|ExtraSSLOptions]),
+ {ok, ClientNode, _ClientHost} =
+ ?match({ok,_,_}, orber_test_lib:js_node(ClientOptions)),
+
+ ?match(ok, orber_test_lib:remote_apply(ClientNode, orber_test_lib,
+ install_test_data,
+ [ssl])),
+ orber_test_lib:remote_apply(ClientNode, ssl, start, []),
+ orber_test_lib:remote_apply(ServerNode, crypto, start, []),
+ orber_test_lib:remote_apply(ClientNode, ssl, seed, ["testing"]),
+ Obj = ?match(#'IOP_IOR'{},
+ orber_test_lib:remote_apply(ClientNode, corba,
+ string_to_object, ["corbaname:iiop:1.1@"++Loopback++":5648/NameService#mamba",
+ [{context, [#'IOP_ServiceContext'{context_id=?ORBER_GENERIC_CTX_ID,
+ context_data = {configuration, ClientOptions}}]}]])),
+ ?match(ok, orber_test_lib:remote_apply(ClientNode, orber_test_server,
+ print, [Obj])),
+
+ ok
+ end.
+
+
+
+%%-----------------------------------------------------------------
+%% API tests for Orber to Java ORB, no security
+%%-----------------------------------------------------------------
+
+%orber_java_api(doc) -> ["ERLANG-ORB <-> JAVA-ORB API tests",
+% "This case test if data encode/decode (IIOP)",
+% "produce the correct result, i.e., the test_server echos",
+% "the input parameter or an exception is raised (MARSHAL)."];
+%orber_java_api(suite) -> [];
+%orber_java_api(Config) ->
+% ok.
+
+%%------------------------------------------------------------
+%% function : ssl_suite
+%% Arguments: Config
+%% Depth
+%% Returns : ok
+%% Effect :
+%%------------------------------------------------------------
+
+ssl_suite(ServerOptions, ClientOptions) ->
+
+ {ok, ServerNode, ServerHost} =
+ ?match({ok,_,_}, orber_test_lib:js_node(ServerOptions)),
+ ServerPort = orber_test_lib:remote_apply(ServerNode, orber, iiop_port, []),
+ SSLServerPort = orber_test_lib:remote_apply(ServerNode, orber, iiop_ssl_port, []),
+
+ {ok, ClientNode, _ClientHost} =
+ ?match({ok,_,_}, orber_test_lib:js_node(ClientOptions)),
+
+ ?match(ok, orber_test_lib:remote_apply(ServerNode, orber_test_lib,
+ install_test_data,
+ [ssl])),
+ %% Tell the client to interoperate with the server. The purpose of this
+ %% operation is to look up, using NameService, an object reference and
+ %% use it to contact the object.
+ ?match(ok, orber_test_lib:remote_apply(ClientNode, orber_test_lib,
+ lookup,
+ [ServerHost, ServerPort])),
+
+ ?match(ok, orber_test_lib:remote_apply(ClientNode, orber_test_lib,
+ alternate_ssl_iiop_address,
+ [ServerHost, ServerPort, SSLServerPort])),
+
+ %% 'This' node is not secure. Contact the server. Must refuse connection.
+ NSR = ?match({'IOP_IOR',"IDL:omg.org/CosNaming/NamingContextExt:1.0",_},
+ corba:string_to_object("corbaloc::1.2@"++ServerHost++":"++
+ integer_to_list(ServerPort)++"/NameService")),
+
+ %% Should be 'NO_PERMISSION'??
+ ?match({'EXCEPTION',{'COMM_FAILURE',_,_,_}},
+ 'CosNaming_NamingContext':resolve(NSR, lname:new(["not_exist"]))),
+
+ %% Should be 'NO_PERMISSION'??
+ ?match({'EXCEPTION',{'COMM_FAILURE',_,_,_}},
+ 'CosNaming_NamingContext':resolve(NSR, lname:new(["mamba"]))),
+
+ %% Uninstall.
+ ?match(ok, orber_test_lib:remote_apply(ServerNode, orber_test_lib,
+ uninstall_test_data,
+ [ssl])),
+ ok.
+
+%%-----------------------------------------------------------------
+%% iiop_setup_connection_timeout API tests for ORB to ORB.
+%%-----------------------------------------------------------------
+setup_connection_timeout_api(doc) -> ["iiop_setup_connection_timeout API tests for ORB to ORB."];
+setup_connection_timeout_api(suite) -> [];
+setup_connection_timeout_api(_Config) ->
+ ?match(ok, application:set_env(orber, iiop_backlog, 0)),
+ %% Wait to be sure that the configuration has kicked in.
+ timer:sleep(2000),
+ {ok, Ref, Port} = create_fake_server_ORB(normal, 0, [], listen, []),
+ ?match(ok, orber:configure(iiop_setup_connection_timeout, 5)),
+ ?match(ok, orber:info(io)),
+ IP = orber_test_lib:get_host(),
+ spawn(?MODULE, do_connect, [IP, Port, [{active, false}]]),
+ spawn(?MODULE, do_connect, [IP, Port, [{active, false}]]),
+ spawn(?MODULE, do_connect, [IP, Port, [{active, false}]]),
+ spawn(?MODULE, do_connect, [IP, Port, [{active, false}]]),
+ spawn(?MODULE, do_connect, [IP, Port, [{active, false}]]),
+ timer:sleep(2000),
+ Corbaloc = "corbaloc::1.2@"++IP++":"++integer_to_list(Port)++"/NameService",
+ ?match({'EXCEPTION', _E}, corba:string_to_object(Corbaloc)),
+ destroy_fake_ORB(Ref),
+ ?match(ok, application:set_env(orber, iiop_backlog, 5)),
+ ok.
+
+%%-----------------------------------------------------------------
+%% iiop_setup_connection_timeout API tests for ORB to ORB.
+%%-----------------------------------------------------------------
+setup_multi_connection_timeout_api(doc) ->
+ ["iiop_multi_setup_connection_timeout API tests for ORB to ORB."];
+setup_multi_connection_timeout_api(suite) -> [];
+setup_multi_connection_timeout_api(_Config) ->
+ ?match(ok, application:set_env(orber, iiop_backlog, 0)),
+ %% Wait to be sure that the configuration has kicked in.
+ timer:sleep(2000),
+ {ok, Ref, Port} = create_fake_server_ORB(normal, 0, [], listen, []),
+ ?match(ok, application:set_env(orber, iiop_out_ports, {6042, 6234})),
+ ?match(ok, orber:configure(iiop_setup_connection_timeout, 5)),
+ ?match(ok, orber:info(io)),
+ IP = orber_test_lib:get_host(),
+ spawn(?MODULE, do_connect, [IP, Port, [{active, false}]]),
+ spawn(?MODULE, do_connect, [IP, Port, [{active, false}]]),
+ spawn(?MODULE, do_connect, [IP, Port, [{active, false}]]),
+ spawn(?MODULE, do_connect, [IP, Port, [{active, false}]]),
+ spawn(?MODULE, do_connect, [IP, Port, [{active, false}]]),
+ Corbaloc = "corbaloc::1.2@"++IP++":"++integer_to_list(Port)++"/NameService",
+ timer:sleep(2000),
+ ?match({'EXCEPTION', _E}, corba:string_to_object(Corbaloc)),
+ destroy_fake_ORB(Ref),
+ ?match(ok, application:set_env(orber, iiop_backlog, 5)),
+ ?match(ok, application:set_env(orber, iiop_out_ports, undefined)),
+ ok.
+
+setup_multi_connection_timeout_attempts_api(doc) ->
+ ["iiop_multi_setup_connection_timeout API tests for ORB to ORB."];
+setup_multi_connection_timeout_attempts_api(suite) -> [];
+setup_multi_connection_timeout_attempts_api(_Config) ->
+ ?match(ok, application:set_env(orber, iiop_backlog, 0)),
+ %% Wait to be sure that the configuration has kicked in.
+ timer:sleep(2000),
+ {ok, Ref, Port} = create_fake_server_ORB(normal, 0, [], listen, []),
+ ?match(ok, application:set_env(orber, iiop_out_ports, {6042, 6234})),
+ ?match(ok, application:set_env(orber, iiop_out_ports_attempts, 1)),
+ ?match(ok, orber:configure(iiop_setup_connection_timeout, 5)),
+ ?match(ok, orber:info(io)),
+ IP = orber_test_lib:get_host(),
+ spawn(?MODULE, do_connect, [IP, Port, [{active, false}]]),
+ spawn(?MODULE, do_connect, [IP, Port, [{active, false}]]),
+ spawn(?MODULE, do_connect, [IP, Port, [{active, false}]]),
+ spawn(?MODULE, do_connect, [IP, Port, [{active, false}]]),
+ spawn(?MODULE, do_connect, [IP, Port, [{active, false}]]),
+ Corbaloc = "corbaloc::1.2@"++IP++":"++integer_to_list(Port)++"/NameService",
+ timer:sleep(2000),
+ ?match({'EXCEPTION', _E}, corba:string_to_object(Corbaloc)),
+ destroy_fake_ORB(Ref),
+ ?match(ok, application:set_env(orber, iiop_backlog, 5)),
+ ?match(ok, application:set_env(orber, iiop_out_ports, undefined)),
+ ok.
+
+setup_multi_connection_timeout_random_api(doc) ->
+ ["iiop_multi_setup_connection_timeout API tests for ORB to ORB."];
+setup_multi_connection_timeout_random_api(suite) -> [];
+setup_multi_connection_timeout_random_api(_Config) ->
+ ?match(ok, application:set_env(orber, iiop_backlog, 0)),
+ %% Wait to be sure that the configuration has kicked in.
+ timer:sleep(2000),
+ {ok, Ref, Port} = create_fake_server_ORB(normal, 0, [], listen, []),
+ ?match(ok, application:set_env(orber, iiop_out_ports, {6042, 6234})),
+ ?match(ok, application:set_env(orber, iiop_out_ports_random, true)),
+ ?match(ok, orber:configure(iiop_setup_connection_timeout, 5)),
+ ?match(ok, orber:info(io)),
+ IP = orber_test_lib:get_host(),
+ spawn(?MODULE, do_connect, [IP, Port, [{active, false}]]),
+ spawn(?MODULE, do_connect, [IP, Port, [{active, false}]]),
+ spawn(?MODULE, do_connect, [IP, Port, [{active, false}]]),
+ spawn(?MODULE, do_connect, [IP, Port, [{active, false}]]),
+ spawn(?MODULE, do_connect, [IP, Port, [{active, false}]]),
+ Corbaloc = "corbaloc::1.2@"++IP++":"++integer_to_list(Port)++"/NameService",
+ timer:sleep(2000),
+ ?match({'EXCEPTION', _E}, corba:string_to_object(Corbaloc)),
+ destroy_fake_ORB(Ref),
+ ?match(ok, application:set_env(orber, iiop_backlog, 5)),
+ ?match(ok, application:set_env(orber, iiop_out_ports, undefined)),
+ ok.
+
+%%-----------------------------------------------------------------
+%% Sending an incorrect header to the server-side ORB.
+%%-----------------------------------------------------------------
+bad_giop_header_api(doc) -> ["Sending an incorrect header to the server-side ORB."];
+bad_giop_header_api(suite) -> [];
+bad_giop_header_api(_Config) ->
+ orber:configure_override(interceptors, {native,[orber_iiop_tracer]}),
+ orber:configure(orber_debug_level, 10),
+ ?match(ok, orber:info(io)),
+ {ok, ServerNode, ServerHost} =
+ ?match({ok,_,_}, orber_test_lib:js_node()),
+ ServerPort = orber_test_lib:remote_apply(ServerNode, orber, iiop_port, []),
+ Req = <<"GIOP",1,2,0,100,0,0,0,5,0,0,0,10,50>> ,
+ ?match(ok, fake_client_ORB(normal, ServerHost, ServerPort, [],
+ message_error, [Req])),
+
+ application:set_env(orber, interceptors, false),
+ orber:configure(orber_debug_level, 0),
+ ok.
+
+
+%%-----------------------------------------------------------------
+%% Fragmented IIOP tests (Server-side).
+%%-----------------------------------------------------------------
+-define(REQUEST_ID, 0).
+
+-define(REPLY_FRAG_1, <<71,73,79,80,1,2,2,1,0,0,0,41,0,0,0,?REQUEST_ID,0,0,0,0,0,0,0,1,78,69,79,0,0,0,0,2,0,10,0,0,0,0,0,0,0,0,0,18,0,0,0,0,0,0,0,4,49>>).
+%% The fragments are identical for requests and replies.
+-define(FRAG_2, <<71,73,79,80,1,2,2,7,0,0,0,5,0,0,0,?REQUEST_ID,50>>).
+-define(FRAG_3, <<71,73,79,80,1,2,2,7,0,0,0,5,0,0,0,?REQUEST_ID,51>>).
+-define(FRAG_4, <<71,73,79,80,1,2,0,7,0,0,0,5,0,0,0,?REQUEST_ID,0>>).
+
+
+fragments_server_api(doc) -> ["fragments API tests for server-side ORB."];
+fragments_server_api(suite) -> [];
+fragments_server_api(_Config) ->
+ %% --- Create a slave-node ---
+ {ok, Node, Host} =
+ ?match({ok,_,_}, orber_test_lib:js_node()),
+ Port = orber_test_lib:remote_apply(Node, orber, iiop_port, []),
+
+ ?match(ok, orber_test_lib:remote_apply(Node, orber_test_lib,
+ install_test_data,
+ [nameservice])),
+
+ NSR = ?match({'IOP_IOR',"IDL:omg.org/CosNaming/NamingContextExt:1.0",_},
+ corba:string_to_object("corbaloc::1.2@"++Host++":"++
+ integer_to_list(Port)++"/NameService")),
+
+ Obj = ?match({'IOP_IOR',"IDL:omg.org/orber_test/server:1.0",_},
+ 'CosNaming_NamingContext':resolve(NSR, lname:new(["mamba"]))),
+
+ Any = #any{typecode = {tk_string,0},
+ value = "123"},
+ Target = #'GIOP_TargetAddress'{label = ?GIOP_KeyAddr,
+ value = iop_ior:get_objkey(Obj)},
+ %% Fix a request header.
+ {Hdr, Body, HdrLen, _What, _Flags} =
+ cdr_encode:enc_request_split(
+ #giop_env{version = {1,2}, objkey = Target,
+ request_id = ?REQUEST_ID,
+ response_expected = true,
+ op = testing_iiop_any,
+ parameters = [49], ctx = [],
+ tc = {tk_void,[tk_char],[]},
+ host = [orber_test_lib:get_host()],
+ iiop_port = orber:iiop_port(),
+ iiop_ssl_port = orber:iiop_ssl_port(),
+ domain = orber:domain(),
+ partial_security = orber:partial_security()}),
+ NewBody =
+ case size(Body) of
+ 1 ->
+ <<0,0,0,18,0,0,0,0,0,0,0,4,49>> ;
+ Size ->
+ Aligned = Size -1,
+ <<AligmnetData:Aligned/binary,49>> = Body,
+ list_to_binary([AligmnetData, <<0,0,0,18,0,0,0,0,0,0,0,4,49>> ])
+ end,
+
+ MessSize = HdrLen+size(NewBody),
+ ReqFrag = list_to_binary([ <<"GIOP",1:8,2:8,2:8,0:8,
+ MessSize:32/big-unsigned-integer>> , Hdr |NewBody]),
+ ?match(Any, fake_client_ORB(normal, Host, Port, [], fragments,
+ [ReqFrag, ?FRAG_2, ?FRAG_3, ?FRAG_4])),
+
+ ok.
+
+%%-----------------------------------------------------------------
+%% Fragmented IIOP tests (Server-side). Exceeding Maximum.
+%%-----------------------------------------------------------------
+fragments_max_server_api(doc) -> ["Maximum fragments API tests for server-side ORB."];
+fragments_max_server_api(suite) -> [];
+fragments_max_server_api(_Config) ->
+ %% --- Create a slave-node ---
+ IP = orber_test_lib:get_host(),
+ {ok, ServerNode, _ServerHost} =
+ ?match({ok,_,_}, orber_test_lib:js_node([{iiop_max_fragments, 2},
+ {ip_address, IP}])),
+ ServerPort = orber_test_lib:remote_apply(ServerNode, orber, iiop_port, []),
+ fragments_max_server(ServerNode, IP, ServerPort).
+
+fragments_max_server_added_api(doc) -> ["Maximum fragments API tests for server-side ORB."];
+fragments_max_server_added_api(suite) -> [];
+fragments_max_server_added_api(_Config) ->
+ %% --- Create a slave-node ---
+ IP = orber_test_lib:get_host(),
+ {ok, ServerNode, _ServerHost} =
+ ?match({ok,_,_}, orber_test_lib:js_node([])),
+ ServerPort = 1 + orber_test_lib:remote_apply(ServerNode, orber, iiop_port, []),
+ ?match({ok, _},
+ orber_test_lib:remote_apply(ServerNode, orber,
+ add_listen_interface,
+ [IP, normal,
+ [{iiop_max_fragments, 2},
+ {flags, ?ORB_ENV_LOCAL_INTERFACE},
+ {iiop_port, ServerPort}]])),
+ fragments_max_server(ServerNode, IP, ServerPort).
+
+fragments_max_server(ServerNode, ServerHost, ServerPort) ->
+ ?match(ok, orber_test_lib:remote_apply(ServerNode, orber_test_lib,
+ install_test_data,
+ [nameservice])),
+ Obj = ?match({'IOP_IOR',"IDL:omg.org/orber_test/server:1.0",_},
+ corba:string_to_object("corbaname::1.2@"++ServerHost++":"++
+ integer_to_list(ServerPort)++"/NameService#mamba")),
+ Target = #'GIOP_TargetAddress'{label = ?GIOP_KeyAddr,
+ value = iop_ior:get_objkey(Obj)},
+ %% Fix a request header.
+ {Hdr, Body, HdrLen, _What, _Flags} =
+ cdr_encode:enc_request_split(
+ #giop_env{version = {1,2},
+ objkey = Target,
+ request_id = ?REQUEST_ID,
+ response_expected = true,
+ op = testing_iiop_any,
+ parameters = [49], ctx = [],
+ tc = {tk_void,[tk_char],[]},
+ host = [orber_test_lib:get_host()],
+ iiop_port = orber:iiop_port(),
+ iiop_ssl_port = orber:iiop_ssl_port(),
+ domain = orber:domain(),
+ partial_security = orber:partial_security()}),
+ NewBody =
+ case size(Body) of
+ 1 ->
+ <<0,0,0,18,0,0,0,0,0,0,0,4,49>> ;
+ Size ->
+ Aligned = Size -1,
+ <<AligmnetData:Aligned/binary,49>> = Body,
+ list_to_binary([AligmnetData, <<0,0,0,18,0,0,0,0,0,0,0,4,49>> ])
+ end,
+
+ MessSize = HdrLen+size(NewBody),
+ ReqFrag = list_to_binary([ <<"GIOP",1:8,2:8,2:8,0:8,
+ MessSize:32/big-unsigned-integer>> , Hdr |NewBody]),
+ ?match(#'IMP_LIMIT'{},
+ fake_client_ORB(normal, ServerHost, ServerPort, [], fragments_max,
+ [ReqFrag, ?FRAG_2, ?FRAG_3, ?FRAG_4])),
+
+ ok.
+
+%%-----------------------------------------------------------------
+%% Fragmented IIOP tests (Client-side).
+%%-----------------------------------------------------------------
+fragments_client_api(doc) -> ["fragments API tests for client-side ORB."];
+fragments_client_api(suite) -> [];
+fragments_client_api(_Config) ->
+ Any = #any{typecode = {tk_string,0},
+ value = "123"},
+ application:set_env(orber, interceptors, {native,[orber_iiop_tracer]}),
+ orber:configure(orber_debug_level, 10),
+ orber:info(),
+ IOR = ?match({'IOP_IOR',_,_},
+ iop_ior:create_external({1, 2}, "IDL:FAKE:1.0",
+ "localhost", 6004, "FAKE", [])),
+ spawn(?MODULE, create_fake_server_ORB, [normal, 6004, [], fragments,
+ [?REPLY_FRAG_1, ?FRAG_2,
+ ?FRAG_3, ?FRAG_4]]),
+ ?match({ok, Any}, orber_test_server:testing_iiop_any(IOR, Any)),
+ application:set_env(orber, interceptors, false),
+ orber:configure(orber_debug_level, 0),
+ ok.
+
+%%-----------------------------------------------------------------
+%% Fragmented IIOP tests (Client-side).
+%%-----------------------------------------------------------------
+bad_fragment_id_client_api(doc) -> ["fragments API tests for client-side ORB."];
+bad_fragment_id_client_api(suite) -> [];
+bad_fragment_id_client_api(_Config) ->
+ application:set_env(orber, interceptors, {native,[orber_iiop_tracer]}),
+ orber:configure(orber_debug_level, 10),
+ orber:info(),
+ {ok, ServerNode, ServerHost} =
+ ?match({ok,_,_}, orber_test_lib:js_node()),
+ ServerPort = orber_test_lib:remote_apply(ServerNode, orber, iiop_port, []),
+ Req = <<71,73,79,80,1,2,2,7,0,0,0,5,0,0,0,100,50>> ,
+ ?match(ok, fake_client_ORB(normal, ServerHost, ServerPort, [],
+ message_error, [Req])),
+
+ application:set_env(orber, interceptors, false),
+ orber:configure(orber_debug_level, 0),
+
+ ok.
+
+%%-----------------------------------------------------------------
+%% Non-existing request id
+%%-----------------------------------------------------------------
+bad_id_cancel_request_api(doc) -> ["Description", "more description"];
+bad_id_cancel_request_api(suite) -> [];
+bad_id_cancel_request_api(Config) when is_list(Config) ->
+ Req10 = cdr_encode:enc_cancel_request(#giop_env{version = {1, 0},
+ request_id = 556}),
+ Req11 = cdr_encode:enc_cancel_request(#giop_env{version = {1, 1},
+ request_id = 556}),
+ Req12 = cdr_encode:enc_cancel_request(#giop_env{version = {1, 2},
+ request_id = 556}),
+ {ok, ServerNode, ServerHost} =
+ ?match({ok,_,_}, orber_test_lib:js_node()),
+ ServerPort = orber_test_lib:remote_apply(ServerNode, orber, iiop_port, []),
+ ?match(ok, fake_client_ORB(normal, ServerHost, ServerPort, [],
+ message_error, [Req10])),
+ ?match(ok, fake_client_ORB(normal, ServerHost, ServerPort, [],
+ message_error, [Req11])),
+ ?match(ok, fake_client_ORB(normal, ServerHost, ServerPort, [],
+ message_error, [Req12])),
+ ok.
+
+%%-----------------------------------------------------------------
+%% Local functions.
+%%-----------------------------------------------------------------
+
+do_connect(Host, Port, Options) ->
+ gen_tcp:connect(Host, Port, Options),
+ timer:sleep(20000).
+
+pseudo_calls(0, _) ->
+ ok;
+pseudo_calls(Times, Obj) ->
+ orber_test_server:pseudo_call(Obj),
+ New = Times - 1,
+ pseudo_calls(New, Obj).
+pseudo_casts(0, _) ->
+ ok;
+pseudo_casts(Times, Obj) ->
+ orber_test_server:pseudo_cast(Obj),
+ New = Times - 1,
+ pseudo_casts(New, Obj).
+
+context_test(Obj) ->
+ CodeSetCtx = #'CONV_FRAME_CodeSetContext'{char_data = 65537,
+ wchar_data = 65801},
+ FTGrp = #'FT_FTGroupVersionServiceContext'{object_group_ref_version = ?ULONGMAX},
+ FTReq = #'FT_FTRequestServiceContext'{client_id = "ClientId",
+ retention_id = ?LONGMAX,
+ expiration_time = ?ULONGLONGMAX},
+
+ IDToken1 = #'CSI_IdentityToken'{label = ?CSI_IdentityTokenType_ITTAbsent,
+ value = true},
+ IDToken2 = #'CSI_IdentityToken'{label = ?CSI_IdentityTokenType_ITTAnonymous,
+ value = false},
+ IDToken3 = #'CSI_IdentityToken'{label = ?CSI_IdentityTokenType_ITTPrincipalName,
+ value = [0,255]},
+ IDToken4 = #'CSI_IdentityToken'{label = ?CSI_IdentityTokenType_ITTX509CertChain,
+ value = [1,255]},
+ IDToken5 = #'CSI_IdentityToken'{label = ?CSI_IdentityTokenType_ITTDistinguishedName,
+ value = [2,255]},
+ IDToken6 = #'CSI_IdentityToken'{label = ?ULONGMAX,
+ value = [3,255]},
+
+ MTEstablishContext1 = #'CSI_SASContextBody'
+ {label = ?CSI_MsgType_MTEstablishContext,
+ value = #'CSI_EstablishContext'{client_context_id = ?ULONGLONGMAX,
+ authorization_token =
+ [#'CSI_AuthorizationElement'
+ {the_type = ?ULONGMAX,
+ the_element = [0,255]}],
+ identity_token = IDToken1,
+ client_authentication_token = [1, 255]}},
+ MTEstablishContext2 = #'CSI_SASContextBody'
+ {label = ?CSI_MsgType_MTEstablishContext,
+ value = #'CSI_EstablishContext'{client_context_id = ?ULONGLONGMAX,
+ authorization_token =
+ [#'CSI_AuthorizationElement'
+ {the_type = ?ULONGMAX,
+ the_element = [0,255]}],
+ identity_token = IDToken2,
+ client_authentication_token = [1, 255]}},
+ MTEstablishContext3 = #'CSI_SASContextBody'
+ {label = ?CSI_MsgType_MTEstablishContext,
+ value = #'CSI_EstablishContext'{client_context_id = ?ULONGLONGMAX,
+ authorization_token =
+ [#'CSI_AuthorizationElement'
+ {the_type = ?ULONGMAX,
+ the_element = [0,255]}],
+ identity_token = IDToken3,
+ client_authentication_token = [1, 255]}},
+ MTEstablishContext4 = #'CSI_SASContextBody'
+ {label = ?CSI_MsgType_MTEstablishContext,
+ value = #'CSI_EstablishContext'{client_context_id = ?ULONGLONGMAX,
+ authorization_token =
+ [#'CSI_AuthorizationElement'
+ {the_type = ?ULONGMAX,
+ the_element = [0,255]}],
+ identity_token = IDToken4,
+ client_authentication_token = [1, 255]}},
+ MTEstablishContext5 = #'CSI_SASContextBody'
+ {label = ?CSI_MsgType_MTEstablishContext,
+ value = #'CSI_EstablishContext'{client_context_id = ?ULONGLONGMAX,
+ authorization_token =
+ [#'CSI_AuthorizationElement'
+ {the_type = ?ULONGMAX,
+ the_element = [0,255]}],
+ identity_token = IDToken5,
+ client_authentication_token = [1, 255]}},
+ MTEstablishContext6 = #'CSI_SASContextBody'
+ {label = ?CSI_MsgType_MTEstablishContext,
+ value = #'CSI_EstablishContext'{client_context_id = ?ULONGLONGMAX,
+ authorization_token =
+ [#'CSI_AuthorizationElement'
+ {the_type = ?ULONGMAX,
+ the_element = [0,255]}],
+ identity_token = IDToken6,
+ client_authentication_token = [1, 255]}},
+ MTCompleteEstablishContext = #'CSI_SASContextBody'
+ {label = ?CSI_MsgType_MTCompleteEstablishContext,
+ value = #'CSI_CompleteEstablishContext'{client_context_id = ?ULONGLONGMAX,
+ context_stateful = false,
+ final_context_token = [1, 255]}},
+ MTContextError = #'CSI_SASContextBody'
+ {label = ?CSI_MsgType_MTContextError,
+ value = #'CSI_ContextError'{client_context_id = ?ULONGLONGMAX,
+ major_status = 1,
+ minor_status = 2,
+ error_token = [2,255]}},
+ MTMessageInContext = #'CSI_SASContextBody'
+ {label = ?CSI_MsgType_MTMessageInContext,
+ value = #'CSI_MessageInContext'{client_context_id = ?ULONGLONGMAX,
+ discard_context = true}},
+ Ctx = [#'IOP_ServiceContext'{context_id=?IOP_CodeSets,
+ context_data = CodeSetCtx},
+ #'IOP_ServiceContext'{context_id=?IOP_FT_GROUP_VERSION,
+ context_data = FTGrp},
+ #'IOP_ServiceContext'{context_id=?IOP_FT_REQUEST,
+ context_data = FTReq},
+ #'IOP_ServiceContext'{context_id=?IOP_SecurityAttributeService,
+ context_data = MTEstablishContext1},
+ #'IOP_ServiceContext'{context_id=?IOP_SecurityAttributeService,
+ context_data = MTEstablishContext2},
+ #'IOP_ServiceContext'{context_id=?IOP_SecurityAttributeService,
+ context_data = MTEstablishContext3},
+ #'IOP_ServiceContext'{context_id=?IOP_SecurityAttributeService,
+ context_data = MTEstablishContext4},
+ #'IOP_ServiceContext'{context_id=?IOP_SecurityAttributeService,
+ context_data = MTEstablishContext5},
+ #'IOP_ServiceContext'{context_id=?IOP_SecurityAttributeService,
+ context_data = MTEstablishContext6},
+ #'IOP_ServiceContext'{context_id=?IOP_SecurityAttributeService,
+ context_data = MTCompleteEstablishContext},
+ #'IOP_ServiceContext'{context_id=?IOP_SecurityAttributeService,
+ context_data = MTContextError},
+ #'IOP_ServiceContext'{context_id=?IOP_SecurityAttributeService,
+ context_data = MTMessageInContext},
+ #'IOP_ServiceContext'{context_id=?ORBER_GENERIC_CTX_ID,
+ context_data = {any_kind_of_data, {127,0,0,1}, 4001}}],
+ ?match(ok, orber_test_server:testing_iiop_context(Obj, [{context, Ctx}])).
+
+
+create_fake_server_ORB(Type, Port, Options, listen, _Data) ->
+ {ok, _ListenSocket, NewPort} =
+ orber_socket:listen(Type, Port,
+ [{backlog, 0}, {active, false}|Options]),
+ Socket = orber_socket:connect(Type, 'localhost', NewPort, [{active, false}|Options]),
+ {ok, {Type, Socket}, NewPort};
+create_fake_server_ORB(Type, Port, Options, Action, Data) ->
+ {ok, ListenSocket, _NewPort} =
+ orber_socket:listen(Type, Port, [{active, false}|Options]),
+ Socket = orber_socket:accept(Type, ListenSocket),
+ do_server_action(Type, Socket, Action, Data),
+ orber_socket:close(Type, Socket),
+ ok.
+
+destroy_fake_ORB({Type, Socket}) ->
+ orber_socket:close(Type, Socket);
+destroy_fake_ORB(_) ->
+ ok.
+
+fake_client_ORB(Type, Host, Port, Options, connect, _Data) ->
+ Socket = orber_socket:connect(Type, Host, Port, [{active, false}|Options]),
+ {Type, Socket};
+fake_client_ORB(Type, Host, Port, Options, Action, Data) ->
+ Socket = orber_socket:connect(Type, Host, Port, [{active, false}|Options]),
+ Result = do_client_action(Type, Socket, Action, Data),
+ orber_socket:close(Type, Socket),
+ Result.
+
+
+
+do_server_action(Type, Socket, fragments, FragList) ->
+ timer:sleep(3000),
+ {ok, _B} = gen_tcp:recv(Socket, 0),
+ ok = send_data(Type, Socket, FragList);
+do_server_action(_Type, _Socket, _Action, _Data) ->
+ ok.
+
+do_client_action(Type, Socket, fragments, FragList) ->
+ ok = send_data(Type, Socket, FragList),
+ timer:sleep(3000),
+ {ok, Bytes} = gen_tcp:recv(Socket, 0),
+ {#reply_header{request_id = ?REQUEST_ID, reply_status = no_exception}, ok, [Par]} =
+ cdr_decode:dec_message({tk_void,[tk_any],[tk_any]}, Bytes),
+ Par;
+do_client_action(Type, Socket, fragments_max, FragList) ->
+ ok = send_data(Type, Socket, FragList),
+ timer:sleep(3000),
+ {ok, Bytes} = gen_tcp:recv(Socket, 0),
+ {#reply_header{request_id = ?REQUEST_ID, reply_status = system_exception}, Exc, []} =
+ cdr_decode:dec_message({tk_void,[tk_any],[tk_any]}, Bytes),
+ Exc;
+do_client_action(Type, Socket, message_error, Data) ->
+ ok = send_data(Type, Socket, Data),
+ timer:sleep(3000),
+ {ok,Bytes} = gen_tcp:recv(Socket, 0),
+ 'message_error' = cdr_decode:dec_message({tk_void,[tk_any],[tk_any]}, Bytes),
+ ok;
+do_client_action(_Type, _Socket, _Action, _Data) ->
+ ok.
+
+send_data(_Type, _Socket, []) ->
+ ok;
+send_data(Type, Socket, [H|T]) ->
+ orber_socket:write(Type, Socket, H),
+ send_data(Type, Socket, T).
+
diff --git a/lib/orber/test/naming_context_SUITE.erl b/lib/orber/test/naming_context_SUITE.erl
new file mode 100644
index 0000000000..4406e01d5a
--- /dev/null
+++ b/lib/orber/test/naming_context_SUITE.erl
@@ -0,0 +1,385 @@
+%%
+%% %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%
+%%
+%%
+%%-----------------------------------------------------------------
+%%
+%% Description:
+%% Test suite for Name service
+%%
+%%-----------------------------------------------------------------
+-module(naming_context_SUITE).
+
+-include("test_server.hrl").
+-include_lib("orber/COSS/CosNaming/CosNaming.hrl").
+-include_lib("orber/src/orber_iiop.hrl").
+-include_lib("orber/include/corba.hrl").
+
+-define(default_timeout, ?t:minutes(5)).
+
+%%-----------------------------------------------------------------
+%% External exports
+%%-----------------------------------------------------------------
+-export([all/1]).
+
+%%-----------------------------------------------------------------
+%% Internal exports
+%%-----------------------------------------------------------------
+
+-export([name_context/1, check_list/1, name_context_ext/1]).
+
+-export([init_all/1, finish_all/1, init_per_testcase/2, fin_per_testcase/2]).
+
+
+%%-----------------------------------------------------------------
+%% Macros
+%%-----------------------------------------------------------------
+-define(REMAP_EXCEPT(F), case catch F of
+ {'EXCEPTION', E} -> exit(E);
+ {'EXIT', E} -> exit(E);
+ R -> R
+ end).
+
+-define(match(ExpectedRes, Expr),
+ fun() ->
+ AcTuAlReS = (catch (Expr)),
+ case AcTuAlReS of
+ ExpectedRes ->
+ io:format("------ CORRECT RESULT ------~n~p~n",
+ [AcTuAlReS]),
+ AcTuAlReS;
+ _ ->
+ io:format("###### ERROR ERROR ######~n~p~n",
+ [AcTuAlReS]),
+ ?line exit(AcTuAlReS)
+ end
+ end()).
+
+%%-----------------------------------------------------------------
+%% Func: all/1
+%% Args:
+%% Returns:
+%%-----------------------------------------------------------------
+all(doc) -> ["Description", "more description"];
+all(suite) -> {req,
+ [mnesia],
+ {conf, init_all, cases(), finish_all}}.
+
+cases() ->
+ [name_context, check_list, name_context_ext].
+
+%%-----------------------------------------------------------------
+%% Init and cleanup functions.
+%%-----------------------------------------------------------------
+
+init_per_testcase(_Case, Config) ->
+ Path = code:which(?MODULE),
+ code:add_pathz(filename:join(filename:dirname(Path), "idl_output")),
+ ?line Dog=test_server:timetrap(?default_timeout),
+ orber:jump_start(0),
+ [{watchdog, Dog}|Config].
+
+
+fin_per_testcase(_Case, Config) ->
+ Path = code:which(?MODULE),
+ code:del_path(filename:join(filename:dirname(Path), "idl_output")),
+ orber:jump_stop(),
+ Dog = ?config(watchdog, Config),
+ test_server:timetrap_cancel(Dog),
+ ok.
+
+init_all(Config) ->
+ Config.
+
+finish_all(Config) ->
+ Config.
+
+%%-----------------------------------------------------------------
+%% Test Case: name handling tests
+%% Description:
+%%-----------------------------------------------------------------
+name_context(doc) -> ["Description", "more description"];
+name_context(suite) -> [];
+name_context(_) ->
+ ?REMAP_EXCEPT(name_context_run()).
+
+name_context_run() ->
+ ?line Ns = corba:resolve_initial_references("NameService"),
+
+ ?match({'EXCEPTION', #'NO_PERMISSION'{}},
+ 'CosNaming_NamingContextExt':destroy(Ns)),
+
+ %% Create a test context.
+ ?line Tc = 'CosNaming_NamingContext':bind_new_context(Ns,
+ [#'CosNaming_NameComponent'{id="testcontext",
+ kind=""}]),
+ %% Start testing
+ ?line 'CosNaming_NamingContext':bind(Tc, [#'CosNaming_NameComponent'
+ {id="hej",
+ kind=""}], Ns),
+ ?line Ns = 'CosNaming_NamingContext':resolve(Tc,
+ [#'CosNaming_NameComponent'{id="hej",
+ kind=""}]),
+ ?line Nc = 'CosNaming_NamingContext':new_context(Tc),
+ ?line 'CosNaming_NamingContext':bind(Tc, [#'CosNaming_NameComponent'
+ {id="stop",
+ kind=""}], Nc),
+ ?line Nc = 'CosNaming_NamingContext':resolve(Tc,
+ [#'CosNaming_NameComponent'{id="stop",
+ kind=""}]),
+ ?line {'EXCEPTION', E0} =
+ (catch 'CosNaming_NamingContext':bind(Tc,
+ [#'CosNaming_NameComponent'{id="stop",
+ kind=""}], Ns)),
+ ?line ok = 'CosNaming_NamingContext':rebind(Tc,
+ [#'CosNaming_NameComponent'{id="stop",
+ kind=""}], Ns),
+ ?line {'CosNaming_NamingContext_AlreadyBound', _} = E0,
+ ?line 'CosNaming_NamingContext':bind_context(Tc,
+ [#'CosNaming_NameComponent'{id="evaluate",
+ kind=""}], Nc),
+ ?line Nc =
+ 'CosNaming_NamingContext':resolve(Tc,
+ [#'CosNaming_NameComponent'{id="evaluate",
+ kind=""}]),
+ ?line 'CosNaming_NamingContext':bind(Tc,
+ [#'CosNaming_NameComponent'{id="evaluate",
+ kind=""},
+ #'CosNaming_NameComponent'{id="hej",
+ kind=""}], Ns),
+ ?line ok = 'CosNaming_NamingContext':rebind(Tc,
+ [#'CosNaming_NameComponent'{id="evaluate",
+ kind=""},
+ #'CosNaming_NameComponent'{id="hej",
+ kind=""}], Ns),
+ ?line Ns = 'CosNaming_NamingContext':resolve(Tc,
+ [#'CosNaming_NameComponent'{id="evaluate",
+ kind=""},
+ #'CosNaming_NameComponent'{id="hej",
+ kind=""}]),
+ ?line {'EXCEPTION', E1} =
+ (catch 'CosNaming_NamingContext':resolve(Tc,
+ [#'CosNaming_NameComponent'{id="stop",
+ kind=""},
+ #'CosNaming_NameComponent'{id="hej",
+ kind=""}])),
+ ?line ?match(ok, orber_diagnostics:nameservice()),
+
+ ?line {'CosNaming_NamingContext_CannotProceed', _,_,_} = E1,
+ ?line {'EXCEPTION', E2} = (catch 'CosNaming_NamingContext':destroy(Nc)),
+ ?line {'CosNaming_NamingContext_NotEmpty', _} = E2,
+ ?line ok = 'CosNaming_NamingContext':unbind(Tc,
+ [#'CosNaming_NameComponent'{id="evaluate",
+ kind=""},
+ #'CosNaming_NameComponent'{id="hej",
+ kind=""}]),
+ ?line ok = 'CosNaming_NamingContext':destroy(Nc),
+ ?line ok = 'CosNaming_NamingContext':unbind(Tc,
+ [#'CosNaming_NameComponent'{id="evaluate",
+ kind=""}]),
+ ?line ok = 'CosNaming_NamingContext':unbind(Tc,
+ [#'CosNaming_NameComponent'{id="stop",
+ kind=""}]),
+ ?line ok = 'CosNaming_NamingContext':unbind(Tc,
+ [#'CosNaming_NameComponent'{id="hej",
+ kind=""}]),
+ ?line case 'CosNaming_NamingContext':list(Tc, 3) of
+ {ok, [], ?ORBER_NIL_OBJREF} ->
+ ok;
+ _ ->
+ exit(not_empty)
+ end,
+ ?line ok = 'CosNaming_NamingContext':unbind(Ns,
+ [#'CosNaming_NameComponent'{id="testcontext",
+ kind=""}]),
+ ?line ok = 'CosNaming_NamingContext':destroy(Tc),
+ ok.
+
+
+
+check_list(doc) ->
+ ["Check that the CosNaming::NamingContext::list()",
+ "returns ok.",
+ "Own Id: OTP-2023"];
+check_list(suite) -> [];
+check_list(Config) when is_list(Config) ->
+ ?REMAP_EXCEPT(check_list_run(Config)).
+
+check_list_run(_Config) ->
+ create_default_contexts(),
+ ?line Ns = corba:resolve_initial_references("NameService"),
+ ?line {_, BL, _} = ?match({ok, _, ?ORBER_NIL_OBJREF},
+ 'CosNaming_NamingContext':list(Ns, 256)),
+
+ FF = fun(X) -> XX = hd(X#'CosNaming_Binding'.binding_name),
+ XX#'CosNaming_NameComponent'.id end,
+
+ L = lists:sort(lists:map(FF, BL)),
+ ?line ["host", "workgroup"] = L,
+
+ %% Test next_n/2
+ ?line {_, _, BI} = ?match({ok, [], _BI}, 'CosNaming_NamingContext':list(Ns, 0)),
+ ?line ?match({true, []}, 'CosNaming_BindingIterator':next_n(BI, 0)),
+ ?line ?match({true, [_]}, 'CosNaming_BindingIterator':next_n(BI, 1)),
+ ?line ?match({false, [_]}, 'CosNaming_BindingIterator':next_n(BI, 1)),
+ ?line ?match({false, []}, 'CosNaming_BindingIterator':next_n(BI, 1)),
+ ?line ?match(ok, 'CosNaming_BindingIterator':destroy(BI)),
+
+ ?line {_, _, BI2} = ?match({ok, [], _BI2}, 'CosNaming_NamingContext':list(Ns, 0)),
+ ?line ?match({true, _}, 'CosNaming_BindingIterator':next_one(BI2)),
+ ?line ?match({true, _}, 'CosNaming_BindingIterator':next_one(BI2)),
+ ?line ?match({false, _}, 'CosNaming_BindingIterator':next_one(BI2)),
+ ?line ?match(ok, 'CosNaming_BindingIterator':destroy(BI2)),
+ ?line ?match(ok, orber_diagnostics:nameservice()),
+ ok.
+
+create_default_contexts() ->
+ HostComponent = lname_component:set_id(lname_component:create(),
+ "host"),
+ HostsComponent = lname_component:set_id(lname_component:create(),
+ "hosts"),
+ ResourcesComponent = lname_component:set_id(lname_component:create(),
+ "resources"),
+ DevelopmentComponent = lname_component:set_id(lname_component:create(),
+ "development"),
+ FactoriesComponent = lname_component:set_id(lname_component:create(),
+ "factories"),
+ WGComponent = lname_component:set_id(lname_component:create(),
+ "workgroup"),
+ %% Creation of Naming Context host and it's subcontexts
+ NS = corba:resolve_initial_references("NameService"),
+ H = 'CosNaming_NamingContext':bind_new_context(NS,
+ lname:insert_component(lname:create(), 1, HostComponent)),
+ HR = 'CosNaming_NamingContext':bind_new_context(H,
+ lname:insert_component(lname:create(), 1, ResourcesComponent)),
+ 'CosNaming_NamingContext':bind_new_context(HR,
+ lname:insert_component(lname:create(), 1, FactoriesComponent)),
+ HD = 'CosNaming_NamingContext':bind_new_context(H,
+ lname:insert_component(lname:create(), 1, DevelopmentComponent)),
+ HDR = 'CosNaming_NamingContext':bind_new_context(HD,
+ lname:insert_component(lname:create(), 1, ResourcesComponent)),
+ 'CosNaming_NamingContext':bind_new_context(HDR,
+ lname:insert_component(lname:create(), 1, FactoriesComponent)),
+ %% Creation of Naming Context workgroup and it's subcontexts
+ W = 'CosNaming_NamingContext':bind_new_context(NS,
+ lname:insert_component(lname:create(), 1, WGComponent)),
+ 'CosNaming_NamingContext':bind_new_context(W,
+ lname:insert_component(lname:create(), 1, HostsComponent)),
+ WR = 'CosNaming_NamingContext':bind_new_context(W,
+ lname:insert_component(lname:create(), 1, ResourcesComponent)),
+ 'CosNaming_NamingContext':bind_new_context(WR,
+ lname:insert_component(lname:create(), 1, FactoriesComponent)),
+ WD = 'CosNaming_NamingContext':bind_new_context(W,
+ lname:insert_component(lname:create(), 1, DevelopmentComponent)),
+ WDR = 'CosNaming_NamingContext':bind_new_context(WD,
+ lname:insert_component(lname:create(), 1, ResourcesComponent)),
+ 'CosNaming_NamingContext':bind_new_context(WDR,
+ lname:insert_component(lname:create(), 1, FactoriesComponent)),
+ ok.
+
+%%-----------------------------------------------------------------
+%% Test Case:
+%% Description:
+%%-----------------------------------------------------------------
+name_context_ext(doc) -> ["Description", "more description"];
+name_context_ext(suite) -> [];
+name_context_ext(_Config) ->
+ ?REMAP_EXCEPT(name_context_ext_run()).
+
+name_context_ext_run() ->
+ ?line NS = ?match({_,pseudo,_, _,_, _},
+ corba:resolve_initial_references("NameService")),
+
+ Name1 = [#'CosNaming_NameComponent'{id="\\<id1\\>", kind="kind1"},
+ #'CosNaming_NameComponent'{id="id2", kind="kind2"}],
+ String1 = "\\<id1\\>.kind1/id2.kind2",
+ Name2 = [#'CosNaming_NameComponent'{id="id1", kind=""},
+ #'CosNaming_NameComponent'{id="id2", kind=""},
+ #'CosNaming_NameComponent'{id="id3", kind=""}],
+ String2 = "id1/id2/id3",
+ Name3 = [#'CosNaming_NameComponent'{id="id1", kind="kind1"},
+ #'CosNaming_NameComponent'{id="", kind=""},
+ #'CosNaming_NameComponent'{id="id3", kind="kind3"}],
+ String3 = "id1.kind1/./id3.kind3",
+ Name4 = [#'CosNaming_NameComponent'{id="id1", kind="kind1"},
+ #'CosNaming_NameComponent'{id="i.d.2", kind="kind2"},
+ #'CosNaming_NameComponent'{id="id3", kind="kind3"}],
+ String4 = "id1.kind1/i\\.d\\.2.kind2/id3.kind3",
+ Name5 = [#'CosNaming_NameComponent'{id="id1", kind=""},
+ #'CosNaming_NameComponent'{id="i/d/2", kind="kind2"},
+ #'CosNaming_NameComponent'{id="id3", kind=""}],
+ String5 = "id1/i\\/d\\/2.kind2/id3",
+
+ BadString1 = "id1./id2/id3",
+ BadString2 = "id1//id3",
+
+ ?match(String1, 'CosNaming_NamingContextExt':to_string(NS, Name1)),
+ ?match(String2, 'CosNaming_NamingContextExt':to_string(NS, Name2)),
+ ?match(String3, 'CosNaming_NamingContextExt':to_string(NS, Name3)),
+ ?match(String4, 'CosNaming_NamingContextExt':to_string(NS, Name4)),
+ ?match(String5, 'CosNaming_NamingContextExt':to_string(NS, Name5)),
+ ?match(Name1, 'CosNaming_NamingContextExt':to_name(NS, String1)),
+ ?match(Name2, 'CosNaming_NamingContextExt':to_name(NS, String2)),
+ ?match(Name3, 'CosNaming_NamingContextExt':to_name(NS, String3)),
+ ?match(Name4, 'CosNaming_NamingContextExt':to_name(NS, String4)),
+ ?match(Name5, 'CosNaming_NamingContextExt':to_name(NS, String5)),
+
+ ?match({'EXCEPTION', {'CosNaming_NamingContext_InvalidName',_}},
+ 'CosNaming_NamingContextExt':to_name(NS, BadString1)),
+ ?match({'EXCEPTION', {'CosNaming_NamingContext_InvalidName',_}},
+ 'CosNaming_NamingContextExt':to_name(NS, BadString2)),
+
+ %% Create a test context.
+ ?line Tc = ?match({_,pseudo,_, _,_, _},
+ 'CosNaming_NamingContext':bind_new_context(NS,
+ [#'CosNaming_NameComponent'{id="testcontext",
+ kind=""}])),
+ ?match(ok, 'CosNaming_NamingContext':bind(Tc, [#'CosNaming_NameComponent'
+ {id="hej",
+ kind=""}], NS)),
+
+ ?match(NS, 'CosNaming_NamingContextExt':resolve_str(Tc, "hej")),
+
+ ?match("corbaloc:rir:", 'CosNaming_NamingContextExt':to_url(Tc, "rir:", "")),
+ ?match("corbaname:rir:/NameService#org/erlang/",
+ 'CosNaming_NamingContextExt':to_url(Tc, "rir:/NameService", "org/erlang/")),
+ ?match("corbaloc::1.1@555%3cxyz.com:9999/Dev/NameService",
+ 'CosNaming_NamingContextExt':to_url(Tc, ":1.1@555\\<xyz.com:9999/Dev/NameService", "")),
+
+ %% Bad port
+ ?match({'EXCEPTION', {'CosNaming_NamingContextExt_InvalidAddress',_}},
+ 'CosNaming_NamingContextExt':to_url(Tc, ":[email protected]:99a9/", "")),
+ %% BAd IIOP-version
+ ?match({'EXCEPTION', {'CosNaming_NamingContextExt_InvalidAddress',_}},
+ 'CosNaming_NamingContextExt':to_url(Tc, ":[email protected]:99a9/", "")),
+ %% Bad IIOP-version
+ ?match({'EXCEPTION', {'CosNaming_NamingContextExt_InvalidAddress',_}},
+ 'CosNaming_NamingContextExt':to_url(Tc, ":@555xyz.com:99a9/", "")),
+ %% Bad protocol
+ ?match({'EXCEPTION', {'CosNaming_NamingContextExt_InvalidAddress',_}},
+ 'CosNaming_NamingContextExt':to_url(Tc, "iop:@555xyz.com:99a9/", "")),
+ %% Unsupported protocol
+ ?match({'EXCEPTION', {'CosNaming_NamingContextExt_InvalidAddress',_}},
+ 'CosNaming_NamingContextExt':to_url(Tc, "atm:@555xyz.com:9999/", "")),
+ %% Bad Name
+ ?match({'EXCEPTION', {'CosNaming_NamingContext_InvalidName',_}},
+ 'CosNaming_NamingContextExt':to_url(Tc, ":555xyz.com:9999/", "id1./id2.kind2")),
+
+ ok.
+
+
diff --git a/lib/orber/test/orber.spec b/lib/orber/test/orber.spec
new file mode 100644
index 0000000000..9d19ea7fc1
--- /dev/null
+++ b/lib/orber/test/orber.spec
@@ -0,0 +1,19 @@
+%%
+%% %CopyrightBegin%
+%%
+%% 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%
+%%
+{topcase, {dir, "../orber_test"}}.
diff --git a/lib/orber/test/orber_SUITE.erl b/lib/orber/test/orber_SUITE.erl
new file mode 100644
index 0000000000..f54da02c0e
--- /dev/null
+++ b/lib/orber/test/orber_SUITE.erl
@@ -0,0 +1,179 @@
+%%
+%% %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(orber_SUITE).
+-include("test_server.hrl").
+
+
+-define(default_timeout, ?t:minutes(15)).
+-define(application, orber).
+
+% Test server specific exports
+-export([all/1]).
+-export([init_per_testcase/2, fin_per_testcase/2]).
+
+% Test cases must be exported.
+-export([app_test/1, undefined_functions/1, install_load_order/1,
+ install_local_content/1]).
+
+%%
+%% all/1
+%%
+all(doc) ->
+ [];
+all(suite) ->
+ [app_test, undefined_functions,
+ install_load_order, install_local_content].
+
+init_per_testcase(_Case, Config) ->
+ ?line Dog=test_server:timetrap(?default_timeout),
+ [{watchdog, Dog}|Config].
+
+fin_per_testcase(_Case, Config) ->
+ Dog=?config(watchdog, Config),
+ test_server:timetrap_cancel(Dog),
+ ok.
+
+%
+% Test cases starts here.
+%
+app_test(doc) -> [];
+app_test(suite) -> [];
+app_test(_Config) ->
+ ?line ok=?t:app_test(orber),
+ ok.
+
+%% Install Orber using the load_order option.
+install_load_order(suite) ->
+ [];
+install_load_order(doc) ->
+ [];
+install_load_order(_Config) ->
+ orber:jump_stop(),
+ case catch install_load_order2() of
+ ok ->
+ orber:jump_stop();
+ What ->
+ orber:jump_stop(),
+ exit(What)
+ end.
+
+install_load_order2() ->
+ application:load(orber),
+ mnesia:start(),
+ corba:orb_init([{iiop_port, 0}]),
+ orber:install([node()], [{ifr_storage_type, ram_copies},
+ {load_order, 10}]),
+ orber:start(),
+ [H|_] = orber:get_tables(),
+ 10 = mnesia:table_info(H, load_order),
+ ok.
+
+%% Install Orber using the local_content option.
+install_local_content(suite) ->
+ [];
+install_local_content(doc) ->
+ [];
+install_local_content(_Config) ->
+ orber:jump_stop(),
+ case catch install_local_content2() of
+ ok ->
+ orber:jump_stop();
+ What ->
+ orber:jump_stop(),
+ exit(What)
+ end.
+
+install_local_content2() ->
+ application:load(orber),
+ mnesia:start(),
+ corba:orb_init([{iiop_port, 0}]),
+ orber:install([node()], [{ifr_storage_type, ram_copies},
+ {local_content, true}]),
+ orber:start(),
+ [H|_] = orber:get_tables(),
+ true = mnesia:table_info(H, local_content),
+ ok.
+
+
+
+%% Check for undefined functions
+undefined_functions(suite) ->
+ [];
+undefined_functions(doc) ->
+ [];
+undefined_functions(_Config) ->
+ App = orber,
+ Root = code:root_dir(),
+ LibDir = code:lib_dir(App),
+ EbinDir = filename:join([LibDir,"ebin"]),
+ AppFilePath = filename:join([LibDir,"ebin", "orber.app"]),
+ {ok, [{application,orber,AppFile}]} = file:consult(AppFilePath),
+ io:format("Using ~p~n~p~n", [AppFilePath, AppFile]),
+ Mods = key1search(modules, AppFile),
+ XRefTestName = undef_funcs_make_name(App, xref_test_name),
+ {ok, XRef} = xref:start(XRefTestName),
+ ok = xref:set_default(XRef,
+ [{verbose,false},{warnings,false}]),
+ XRefName = undef_funcs_make_name(App, xref_name),
+ {ok, XRefName} = xref:add_release(XRef, Root, {name,XRefName}),
+ {ok, App} = xref:replace_application(XRef, App, EbinDir),
+ {ok, Undefs} = xref:analyze(XRef, undefined_function_calls),
+ xref:stop(XRef),
+ analyze_undefined_function_calls(Undefs, Mods, []).
+
+analyze_undefined_function_calls([], _, []) ->
+ ok;
+analyze_undefined_function_calls([], _, AppUndefs) ->
+ exit({suite_failed, {undefined_function_calls, AppUndefs}});
+analyze_undefined_function_calls([{{Mod, _F, _A}, _C} = AppUndef|Undefs],
+ AppModules, AppUndefs) ->
+ %% Check that this module is our's
+ case lists:member(Mod,AppModules) of
+ true ->
+ {Calling,Called} = AppUndef,
+ {Mod1,Func1,Ar1} = Calling,
+ {Mod2,Func2,Ar2} = Called,
+ io:format("undefined function call: "
+ "~n ~w:~w/~w calls ~w:~w/~w~n",
+ [Mod1,Func1,Ar1,Mod2,Func2,Ar2]),
+ analyze_undefined_function_calls(Undefs, AppModules,
+ [AppUndef|AppUndefs]);
+ false ->
+ io:format("dropping ~p~n", [Mod]),
+ analyze_undefined_function_calls(Undefs, AppModules, AppUndefs)
+ end.
+
+%% This function is used simply to avoid cut-and-paste errors later...
+undef_funcs_make_name(App, PostFix) ->
+ list_to_atom(atom_to_list(App) ++ "_" ++ atom_to_list(PostFix)).
+
+key1search(Key, L) ->
+ case lists:keysearch(Key, 1, L) of
+ false ->
+ fail({not_found, Key, L});
+ {value, {Key, Value}} ->
+ Value
+ end.
+
+fail(Reason) ->
+ exit({suite_failed, Reason}).
+
+
+
diff --git a/lib/orber/test/orber_acl_SUITE.erl b/lib/orber/test/orber_acl_SUITE.erl
new file mode 100644
index 0000000000..2c2a768af2
--- /dev/null
+++ b/lib/orber/test/orber_acl_SUITE.erl
@@ -0,0 +1,303 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 2004-2010. All Rights Reserved.
+%%
+%% The contents of this file are subject to the Erlang Public License,
+%% Version 1.1, (the "License"); you may not use this file except in
+%% compliance with the License. You should have received a copy of the
+%% Erlang Public License along with this software. If not, it can be
+%% retrieved online at http://www.erlang.org/.
+%%
+%% Software distributed under the License is distributed on an "AS IS"
+%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+%% the License for the specific language governing rights and limitations
+%% under the License.
+%%
+%% %CopyrightEnd%
+%%
+%%
+%%-----------------------------------------------------------------
+%%
+%% Description:
+%% Test suite for the ACL functions
+%%
+%%-----------------------------------------------------------------
+-module(orber_acl_SUITE).
+
+-include("test_server.hrl").
+
+-define(default_timeout, ?t:minutes(5)).
+
+-define(match(ExpectedRes,Expr),
+ fun() ->
+ AcTuAlReS = (catch (Expr)),
+ case AcTuAlReS of
+ ExpectedRes ->
+ io:format("------ CORRECT RESULT ------~n~p~n",
+ [AcTuAlReS]),
+ AcTuAlReS;
+ _ ->
+ io:format("###### ERROR ERROR ######~nRESULT: ~p~n",
+ [AcTuAlReS]),
+ ?line exit(AcTuAlReS)
+ end
+ end()).
+
+%%-----------------------------------------------------------------
+%% External exports
+%%-----------------------------------------------------------------
+-export([all/1]).
+
+%%-----------------------------------------------------------------
+%% Internal exports
+%%-----------------------------------------------------------------
+-compile(export_all).
+
+%%-----------------------------------------------------------------
+%% Func: all/1
+%% Args:
+%% Returns:
+%%-----------------------------------------------------------------
+all(doc) -> ["Testing API for ACL (Access Control List)"];
+all(suite) ->
+ [ipv4_verify, ipv4_range, ipv4_interfaces, ipv4_bm,
+ ipv6_verify, ipv6_range, ipv6_interfaces, ipv6_bm].
+
+%%-----------------------------------------------------------------
+%% Init and cleanup functions.
+%%-----------------------------------------------------------------
+init_all(Config) ->
+ if
+ list(Config) ->
+ Config;
+ true ->
+ exit("Config not a list")
+ end.
+
+finish_all(Config) ->
+ Config.
+
+
+init_per_testcase(_Case, Config) ->
+ ?line Dog=test_server:timetrap(?default_timeout),
+ [{watchdog, Dog}|Config].
+
+
+fin_per_testcase(_Case, Config) ->
+ Dog = ?config(watchdog, Config),
+ test_server:timetrap_cancel(Dog),
+ ok.
+
+%%-----------------------------------------------------------------
+%% Test Case :
+%% Description:
+%%-----------------------------------------------------------------
+ipv4_verify(doc) -> ["Testing IPv4 Verify Operation."];
+ipv4_verify(suite) -> [];
+ipv4_verify(_) ->
+ ?match(true, orber_acl:verify("192.168.64.148", "192.168.64.0/17", inet)),
+ ?match({false,"192.168.128.0","192.168.255.255"},
+ orber_acl:verify("192.168.64.148", "192.168.255.0/17", inet)),
+ ?match(true, orber_acl:verify("192.168.255.148", "192.168.128.0/17", inet)),
+ ?match(true, orber_acl:verify("192.168.128.148", "192.168.128.0/17", inet)),
+ ?match(true, orber_acl:verify("192.168.255.255", "192.168.128.0/16", inet)),
+ ?match({false,"192.168.0.0","192.168.255.255"},
+ orber_acl:verify("192.169.255.255", "192.168.128.0/16", inet)),
+ ?match(true, orber_acl:verify("192.168.128.255", "192.168.128.0/24", inet)),
+ ?match({false,"192.168.128.0","192.168.128.255"},
+ orber_acl:verify("192.168.255.255", "192.168.128.0/24", inet)),
+ ?match({false,"192.168.128.0","192.168.128.127"},
+ orber_acl:verify("192.168.128.255", "192.168.128.0/25", inet)),
+ ?match(true, orber_acl:verify("192.168.128.255", "192.168.128.128/25", inet)),
+ ?match(true, orber_acl:verify("192.168.128.128", "192.168.128.128/32", inet)),
+ ?match({false,"192.168.128.128.","192.168.128.128."},
+ orber_acl:verify("192.168.128.255", "192.168.128.128/32", inet)),
+ ?match(true, orber_acl:verify("192.168.128.128", "192.168.128.128", inet)),
+ ?match({false,"192.168.128.128.","192.168.128.128."},
+ orber_acl:verify("192.168.128.255", "192.168.128.128", inet)),
+ ?match(true, orber_acl:verify("192.168.128.255", "192.168.128.128/7", inet)),
+ ok.
+
+%%-----------------------------------------------------------------
+%% Test Case :
+%% Description:
+%%-----------------------------------------------------------------
+ipv4_range(doc) -> ["Testing IPv4 Range Operation."];
+ipv4_range(suite) -> [];
+ipv4_range(_) ->
+ ?match({ok,"192.168.0.0", "192.168.127.255"},
+ orber_acl:range("192.168.64.0/17")),
+ ?match({ok, "192.168.128.0", "192.168.255.255"},
+ orber_acl:range("192.168.255.0/17")),
+ ?match({ok,"192.168.128.0","192.168.255.255"},
+ orber_acl:range("192.168.128.0/17")),
+ ?match({ok,"192.168.0.0","192.168.255.255"},
+ orber_acl:range("192.168.128.0/16")),
+ ?match({ok,"192.168.128.0","192.168.128.255"},
+ orber_acl:range("192.168.128.0/24")),
+ ?match({ok,"192.168.128.0","192.168.128.127"},
+ orber_acl:range("192.168.128.0/25")),
+ ?match({ok,"192.168.128.128","192.168.128.255"},
+ orber_acl:range("192.168.128.128/25")),
+ ?match({ok,"192.168.128.128.","192.168.128.128."},
+ orber_acl:range("192.168.128.128/32")),
+ ?match({ok,"192.168.128.128.","192.168.128.128."},
+ orber_acl:range("192.168.128.128")),
+ ?match({ok,"192.0.0.0","193.255.255.255"},
+ orber_acl:range("192.168.128.128/7")),
+ ok.
+
+%%-----------------------------------------------------------------
+%% Test Case :
+%% Description:
+%%-----------------------------------------------------------------
+ipv4_interfaces(doc) -> ["Testing IPv4 Interfaces Operation."];
+ipv4_interfaces(suite) -> [];
+ipv4_interfaces(_) ->
+ ?match({ok, _},
+ orber_acl:init_acl([{tcp_in, "192.168.128.0/18", ["10.1.1.1"]},
+ {tcp_in, "192.167.64.0/18#4001/5001", ["10.1.1.2"]},
+ {tcp_in, "192.166.192.0/18"}], inet)),
+ {ok, IPTuple1} = ?match({ok, _}, inet:getaddr("192.168.128.0", inet)),
+ ?match({true, ["10.1.1.1"], 0}, orber_acl:match(IPTuple1, tcp_in, true)),
+ ?match({false, [], 0}, orber_acl:match(IPTuple1, tcp_out, true)),
+ {ok, IPTuple2} = ?match({ok, _}, inet:getaddr("192.167.64.0", inet)),
+ ?match({true, ["10.1.1.2"], {4001,5001}}, orber_acl:match(IPTuple2, tcp_in, true)),
+ ?match({false, [], 0}, orber_acl:match(IPTuple2, tcp_out, true)),
+ {ok, IPTuple3} = ?match({ok, _}, inet:getaddr("192.166.192.0", inet)),
+ ?match({true, [], 0}, orber_acl:match(IPTuple3, tcp_in, true)),
+ ?match(false, orber_acl:match(IPTuple3, tcp_out)),
+ ?match(ok, orber_acl:clear_acl()),
+ ok.
+
+%%-----------------------------------------------------------------
+%% Test Case :
+%% Description:
+%%-----------------------------------------------------------------
+ipv4_bm(doc) -> ["Benchmarking runtime critical IPv4 Operations."];
+ipv4_bm(suite) -> [];
+ipv4_bm(_) ->
+ ?match({ok, _, _, _}, bm2([{tcp_in, "192.168.64.0/17"}], inet, "192.168.64.148")),
+ ok.
+%%-----------------------------------------------------------------
+%% Test Case :
+%% Description:
+%%-----------------------------------------------------------------
+ipv6_verify(doc) -> ["Testing IPv6 Verify Operation."];
+ipv6_verify(suite) -> [];
+ipv6_verify(_) ->
+ case orber_test_lib:version_ok() of
+ true ->
+ ?match(true, orber_acl:verify("2002:C0A8:0:0:0:0:0:0", "2002:C0A8::/48", inet6)),
+ ?match(true, orber_acl:verify("2002:C0A8:0:FFFF:FFFF:FFFF:FFFF:FFFF", "2002:C0A8::/48", inet6)),
+ ?match({false,"2002:C0A8:0:0:0:0:0:0", "2002:C0A8:0:FFFF:FFFF:FFFF:FFFF:FFFF"},
+ orber_acl:verify("2002:C0A8:1:FFFF:FFFF:FFFF:FFFF:FFFF", "2002:C0A8::/48", inet6)),
+ ?match(true, orber_acl:verify("2002:C0A8:1:FFFF:FFFF:FFFF:FFFF:FFFF", "2002:C0A8::/47", inet6)),
+ ?match({false,"2002:C0A8:0:0:0:0:0:0", "2002:C0A8:1:FFFF:FFFF:FFFF:FFFF:FFFF"},
+ orber_acl:verify("2002:C0A8:2:FFFF:FFFF:FFFF:FFFF:FFFF", "2002:C0A8::/47", inet6)),
+ ok;
+ Reason ->
+ Reason
+ end.
+
+%%-----------------------------------------------------------------
+%% Test Case :
+%% Description:
+%%-----------------------------------------------------------------
+ipv6_range(doc) -> ["Testing IPv6 Range Operation."];
+ipv6_range(suite) -> [];
+ipv6_range(_) ->
+ case orber_test_lib:version_ok() of
+ true ->
+ ?match({ok,"2002:C0A8:0:0:0:0:0:0", "2002:C0A8:0:FFFF:FFFF:FFFF:FFFF:FFFF"},
+ orber_acl:range("2002:C0A8::/48", inet6)),
+ ?match({ok,"2002:C0A8:0:0:0:0:0:0", "2002:C0A8:1:FFFF:FFFF:FFFF:FFFF:FFFF"},
+ orber_acl:range("2002:C0A8::/47", inet6)),
+ ok;
+ Reason ->
+ Reason
+ end.
+
+%%-----------------------------------------------------------------
+%% Test Case :
+%% Description:
+%%-----------------------------------------------------------------
+ipv6_interfaces(doc) -> ["Testing IPv6 Interfaces Operation."];
+ipv6_interfaces(suite) -> [];
+ipv6_interfaces(_) ->
+ case orber_test_lib:version_ok() of
+ true ->
+ ?match({ok, _}, orber_acl:init_acl([{tcp_in, "2002:C0A8::/49", ["0:0:0:0:0:0:10.1.1.1"]}], inet6)),
+ {ok, IPTuple1} = ?match({ok, _}, inet:getaddr("2002:C0A8:0:7FFF:FFFF:FFFF:FFFF:FFFF", inet6)),
+ ?match({true, ["0:0:0:0:0:0:10.1.1.1"], 0}, orber_acl:match(IPTuple1, tcp_in, true)),
+ ?match(false, orber_acl:match(IPTuple1, tcp_out)),
+ ?match(ok, orber_acl:clear_acl()),
+ ok;
+ Reason ->
+ Reason
+ end.
+
+%%-----------------------------------------------------------------
+%% Test Case :
+%% Description:
+%%-----------------------------------------------------------------
+ipv6_bm(doc) -> ["Benchmarking runtime critical IPv6 Operations."];
+ipv6_bm(suite) -> [];
+ipv6_bm(_) ->
+ case orber_test_lib:version_ok() of
+ true ->
+ ?match({ok, _, _, _}, bm2([{tcp_in, "2002:C0A8::/48"}], inet6, "2002:C0A8:0:0:0:0:0:0")),
+ ok;
+ Reason ->
+ Reason
+ end.
+
+%%-----------------------------------------------------------------
+%% Local Functions
+%%-----------------------------------------------------------------
+-define(NO_OF_TIMES, 1000).
+
+bm2(Filters, Family, Ip) ->
+ {ok, IPTuple} = inet:getaddr(Ip, Family),
+ orber_acl:init_acl(Filters, Family),
+ TimeBefore1 = erlang:now(),
+ bm_loop(IPTuple, ?NO_OF_TIMES),
+ TimeAfter1 = erlang:now(),
+ orber_acl:clear_acl(),
+ Time1 = computeTime(TimeBefore1, TimeAfter1),
+ orber_acl:init_acl(Filters, Family),
+ TimeBefore2 = erlang:now(),
+ bm_loop2(Ip, ?NO_OF_TIMES, Family),
+ TimeAfter2 = erlang:now(),
+ orber_acl:clear_acl(),
+ Time2 = computeTime(TimeBefore2, TimeAfter2),
+ orber_acl:init_acl(Filters, Family),
+ TimeBefore3 = erlang:now(),
+ bm_loop2(IPTuple, ?NO_OF_TIMES, Family),
+ TimeAfter3 = erlang:now(),
+ orber_acl:clear_acl(),
+ Time3 = computeTime(TimeBefore3, TimeAfter3),
+ {ok, round(?NO_OF_TIMES/Time1), round(?NO_OF_TIMES/Time2), round(?NO_OF_TIMES/Time3)}.
+
+
+bm_loop(_Ip, 0) ->
+ ok;
+bm_loop(Ip, N) ->
+ true = orber_acl:match(Ip, tcp_in),
+ bm_loop(Ip, N-1).
+
+bm_loop2(_Ip, 0, _Family) ->
+ ok;
+bm_loop2(Ip, N, Family) ->
+ {ok, IPTuple} = inet:getaddr(Ip, Family),
+ true = orber_acl:match(IPTuple, tcp_in),
+ bm_loop2(Ip, N-1, Family).
+
+computeTime({_MegaSecb, Secb, MicroSecb}, {_MegaSeca, Seca, MicroSeca}) ->
+ (Seca - Secb) + ((MicroSeca - MicroSecb) / 1000000).
+
+
+%%-----------------------------------------------------------------
+%% END OF MODULE
+%%-----------------------------------------------------------------
diff --git a/lib/orber/test/orber_firewall_ipv4_in_SUITE.erl b/lib/orber/test/orber_firewall_ipv4_in_SUITE.erl
new file mode 100644
index 0000000000..3ac0cb7921
--- /dev/null
+++ b/lib/orber/test/orber_firewall_ipv4_in_SUITE.erl
@@ -0,0 +1,280 @@
+%%
+%% %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(orber_firewall_ipv4_in_SUITE).
+
+-include("test_server.hrl").
+-include_lib("orber/include/corba.hrl").
+-include_lib("orber/COSS/CosNaming/CosNaming.hrl").
+-include_lib("orber/src/orber_iiop.hrl").
+-include_lib("orber/src/ifr_objects.hrl").
+-include("idl_output/orber_test_server.hrl").
+-include_lib("orber/COSS/CosNaming/CosNaming_NamingContextExt.hrl").
+-include_lib("orber/COSS/CosNaming/CosNaming_NamingContext.hrl").
+
+-define(default_timeout, ?t:minutes(15)).
+
+-define(match(ExpectedRes,Expr),
+ fun() ->
+ AcTuAlReS = (catch (Expr)),
+ case AcTuAlReS of
+ ExpectedRes ->
+ io:format("------ CORRECT RESULT ------~n~p~n",
+ [AcTuAlReS]),
+ AcTuAlReS;
+ _ ->
+ io:format("###### ERROR ERROR ######~nRESULT: ~p~n",
+ [AcTuAlReS]),
+ ?line exit(AcTuAlReS)
+ end
+ end()).
+
+%%-----------------------------------------------------------------
+%% External exports
+%%-----------------------------------------------------------------
+-export([all/1, cases/0, init_all/1, finish_all/1,
+ init_per_testcase/2, fin_per_testcase/2,
+ deny_port_api/1, deny_port_range_api/1, deny_host_api/1,
+ deny_peerhost_api/1, allow_port_range_api/1,
+ allow_host_api/1, allow_peerhost_api/1, check_address_api/1]).
+
+%%-----------------------------------------------------------------
+%% Func: all/1
+%% Args:
+%% Returns:
+%%-----------------------------------------------------------------
+all(doc) -> ["API tests for orber's firewall functionallity."];
+all(suite) -> {req,
+ [mnesia],
+ {conf, init_all, cases(), finish_all}}.
+
+%% NOTE - the fragment test cases must bu first since we explicitly set a request
+%% id. Otherwise, the request-id counter would be increased and we cannot know
+%% what it is.
+cases() ->
+ [deny_port_api, deny_port_range_api, deny_host_api, deny_peerhost_api,
+ allow_port_range_api, allow_host_api, allow_peerhost_api, check_address_api].
+
+
+init_per_testcase(_Case, Config) ->
+ ?line Dog=test_server:timetrap(?default_timeout),
+ [{watchdog, Dog}|Config].
+
+
+fin_per_testcase(_Case, Config) ->
+ Dog = ?config(watchdog, Config),
+ test_server:timetrap_cancel(Dog),
+ ok.
+
+init_all(Config) ->
+ if
+ is_list(Config) ->
+ orber:jump_start([{iiop_port, 0},
+ {iiop_out_ports, {5980, 6000}}]),
+ Config;
+ true ->
+ exit("Config not a list")
+ end.
+
+finish_all(Config) ->
+ orber:jump_stop(),
+ Config.
+
+%%-----------------------------------------------------------------
+%% Incomming connections - Deny
+%%-----------------------------------------------------------------
+deny_port_api(doc) -> ["Deny Access due to invalid local port"];
+deny_port_api(suite) -> [];
+deny_port_api(_Config) ->
+ [IP] = ?match([_], orber:host()),
+ {ok, ServerNode, _ServerHost} =
+ ?match({ok,_,_}, orber_test_lib:js_node([{flags, ?ORB_ENV_USE_ACL_INCOMING},
+ {iiop_acl, [{tcp_in, IP++"/32#7000"}]}])),
+ ServerPort = orber_test_lib:remote_apply(ServerNode, orber, iiop_port, []),
+ ?match({'EXCEPTION', #'CosNaming_NamingContextExt_InvalidAddress'{}},
+ corba:string_to_object("corbaloc::1.2@"++IP++":"++integer_to_list(ServerPort)++"/NameService")),
+% ?line catch orber_test_lib:destroy_node(ServerNode, timeout),
+ ok.
+
+deny_port_range_api(doc) -> ["Deny Access due to invalid local port range"];
+deny_port_range_api(suite) -> [];
+deny_port_range_api(_Config) ->
+ [IP] = ?match([_], orber:host()),
+ {ok, ServerNode, _ServerHost} =
+ ?match({ok,_,_}, orber_test_lib:js_node([{flags, ?ORB_ENV_USE_ACL_INCOMING},
+ {iiop_acl, [{tcp_in, IP++"/32#7000/8000"}]}])),
+ ServerPort = orber_test_lib:remote_apply(ServerNode, orber, iiop_port, []),
+ ?match({'EXCEPTION', #'CosNaming_NamingContextExt_InvalidAddress'{}},
+ corba:string_to_object("corbaloc::1.2@"++IP++":"++integer_to_list(ServerPort)++"/NameService")),
+% ?line catch orber_test_lib:destroy_node(ServerNode, timeout),
+ ok.
+
+
+deny_host_api(doc) -> ["Deny Access due to invalid host"];
+deny_host_api(suite) -> [];
+deny_host_api(_Config) ->
+ [IP] = ?match([_], orber:host()),
+ {ok, ServerNode, _ServerHost} =
+ ?match({ok,_,_}, orber_test_lib:js_node([{flags, ?ORB_ENV_USE_ACL_INCOMING},
+ {iiop_acl, [{tcp_in, "123.123.123.123/32"}]}])),
+ ServerPort = orber_test_lib:remote_apply(ServerNode, orber, iiop_port, []),
+ ?match({'EXCEPTION', #'CosNaming_NamingContextExt_InvalidAddress'{}},
+ corba:string_to_object("corbaloc::1.2@"++IP++":"++integer_to_list(ServerPort)++"/NameService")),
+% ?line catch orber_test_lib:destroy_node(ServerNode, timeout),
+ ok.
+
+deny_peerhost_api(doc) -> ["Deny Access due to invalid peerhost"];
+deny_peerhost_api(suite) -> [];
+deny_peerhost_api(_Config) ->
+ [IP] = ?match([_], orber:host()),
+ {ok, ServerNode, _ServerHost} =
+ ?match({ok,_,_}, orber_test_lib:js_node([{flags, ?ORB_ENV_USE_ACL_INCOMING},
+ {iiop_acl, [{tcp_in, IP++"/32", ["123.123.123.123"]}]}])),
+ ServerPort = orber_test_lib:remote_apply(ServerNode, orber, iiop_port, []),
+ ?match({'EXCEPTION', #'CosNaming_NamingContextExt_InvalidAddress'{}},
+ corba:string_to_object("corbaloc::1.2@"++IP++":"++integer_to_list(ServerPort)++"/NameService")),
+% ?line catch orber_test_lib:destroy_node(ServerNode, timeout),
+ ok.
+
+%%-----------------------------------------------------------------
+%% Incomming connections - Allow
+%%-----------------------------------------------------------------
+allow_port_range_api(doc) -> ["Allow Access due to valid local port range"];
+allow_port_range_api(suite) -> [];
+allow_port_range_api(_Config) ->
+ [IP] = ?match([_], orber:host()),
+ {ok, ServerNode, _ServerHost} =
+ ?match({ok,_,_}, orber_test_lib:js_node([{flags, ?ORB_ENV_USE_ACL_INCOMING},
+ {iiop_acl, [{tcp_in, IP++"/32#5980/6000"}]}])),
+ ServerPort = orber_test_lib:remote_apply(ServerNode, orber, iiop_port, []),
+ IOR =
+ ?match({'IOP_IOR',_,_},
+ corba:string_to_object("corbaloc::1.2@"++IP++":"++integer_to_list(ServerPort)++"/NameService")),
+ ?match(false, corba_object:not_existent(IOR)),
+% ?line catch orber_test_lib:destroy_node(ServerNode, timeout),
+ ok.
+
+
+allow_host_api(doc) -> ["Allow Access due to valid host"];
+allow_host_api(suite) -> [];
+allow_host_api(_Config) ->
+ [IP] = ?match([_], orber:host()),
+ {ok, ServerNode, _ServerHost} =
+ ?match({ok,_,_}, orber_test_lib:js_node([{flags, ?ORB_ENV_USE_ACL_INCOMING},
+ {iiop_acl, [{tcp_in, IP++"/32"}]}])),
+ ServerPort = orber_test_lib:remote_apply(ServerNode, orber, iiop_port, []),
+ IOR =
+ ?match({'IOP_IOR',_,_},
+ corba:string_to_object("corbaloc::1.2@"++IP++":"++integer_to_list(ServerPort)++"/NameService")),
+ ?match(false, corba_object:not_existent(IOR)),
+% ?line catch orber_test_lib:destroy_node(ServerNode, timeout),
+ ok.
+
+allow_peerhost_api(doc) -> ["Allow Access due to valid peerhost"];
+allow_peerhost_api(suite) -> [];
+allow_peerhost_api(_Config) ->
+ [IP] = ?match([_], orber:host()),
+ {ok, ServerNode, _ServerHost} =
+ ?match({ok,_,_}, orber_test_lib:js_node([{flags, ?ORB_ENV_USE_ACL_INCOMING},
+ {iiop_acl, [{tcp_in, IP++"/32", [IP]}]}])),
+ ServerPort = orber_test_lib:remote_apply(ServerNode, orber, iiop_port, []),
+ IOR =
+ ?match({'IOP_IOR',_,_},
+ corba:string_to_object("corbaloc::1.2@"++IP++":"++integer_to_list(ServerPort)++"/NameService",
+ [#'IOP_ServiceContext'
+ {context_id=?ORBER_GENERIC_CTX_ID,
+ context_data = {interface, IP}}])),
+ ?match(false, corba_object:not_existent(IOR,
+ [#'IOP_ServiceContext'
+ {context_id=?ORBER_GENERIC_CTX_ID,
+ context_data = {interface, IP}}])),
+% ?line catch orber_test_lib:destroy_node(ServerNode, timeout),
+ ok.
+
+%%-----------------------------------------------------------------
+%% Test corbaloc strings
+%%-----------------------------------------------------------------
+check_address_api(doc) -> ["Test corbaloc strings"];
+check_address_api(suite) -> [];
+check_address_api(_Config) ->
+ ?match({[[iiop,{1,0},"10.0.0.1",2809]],"NameService"},
+ orber_cosnaming_utils:addresses(":10.0.0.1/NameService")),
+ ?match({[[iiop,{1,0},"10.0.0.1",2809]],[]},
+ orber_cosnaming_utils:addresses(":10.0.0.1")),
+ ?match({[[iiop,{1,2},"10.0.0.1",2809]],"NameService"},
+ orber_cosnaming_utils:addresses(":[email protected]/NameService")),
+ ?match({[[iiop,{1,0},"10.0.0.1",4001]],"NameService"},
+ orber_cosnaming_utils:addresses(":10.0.0.1:4001/NameService")),
+ ?match({[[iiop,{1,1},"10.0.0.1",4001]],"NameService"},
+ orber_cosnaming_utils:addresses(":[email protected]:4001/NameService")),
+ ?match({[[iiop,{1,1},"10.0.0.1",4001]],[]},
+ orber_cosnaming_utils:addresses(":[email protected]:4001")),
+ ?match({[[iiop,{1,1},"10.0.0.1",4001]],[]},
+ orber_cosnaming_utils:addresses("iiop:[email protected]:4001")),
+ ?match({[[iiop,{1,1},"10.0.0.1",4001]],[]},
+ orber_cosnaming_utils:addresses("iiop:[email protected]:4001/")),
+
+ ?match({[[iiop,{1,1},"myhost",4001]],[]},
+ orber_cosnaming_utils:addresses("iiop:1.1@myhost:4001")),
+ ?match({[[iiop,{1,1},"myhost.full.name",4001]],"NameService"},
+ orber_cosnaming_utils:addresses("iiop:[email protected]:4001/NameService")),
+ ?match({[[iiop,{1,1},"myhost",4001],
+ [iiop,{1,1},"myhost.full.name",2809]],"NameService"},
+ orber_cosnaming_utils:addresses("iiop:1.1@myhost:4001,iiop:[email protected]/NameService")),
+
+ ?match({[[iiop,{1,1},"123.12.23.2",4001],
+ [iiop,{1,1},"10.0.0.1",4001]], "NameService"},
+ orber_cosnaming_utils:addresses(":[email protected]:4001,:[email protected]:4001/NameService")),
+ ?match({[[iiop,{1,1},"123.12.23.2",4001],
+ [iiop,{1,1},"10.0.0.1",4001]], []},
+ orber_cosnaming_utils:addresses(":[email protected]:4001,:[email protected]:4001")),
+ ?match({[[iiop,{1,0},"123.12.23.2",4001],
+ [iiop,{1,1},"10.0.0.1",4001]], "NameService"},
+ orber_cosnaming_utils:addresses(":123.12.23.2:4001,:[email protected]:4001/NameService")),
+ ?match({[[iiop,{1,1},"123.12.23.2",4001],
+ [iiop,{1,0},"10.0.0.1",4001]], "NameService"},
+ orber_cosnaming_utils:addresses(":[email protected]:4001,:10.0.0.1:4001/NameService")),
+ ?match({[[iiop,{1,1},"123.12.23.2",2809],
+ [iiop,{1,1},"10.0.0.1",4001]], "NameService"},
+ orber_cosnaming_utils:addresses(":[email protected],:[email protected]:4001/NameService")),
+ ?match({[[iiop,{1,1},"123.12.23.2",4001],
+ [iiop,{1,1},"10.0.0.1",2809]], "NameService"},
+ orber_cosnaming_utils:addresses(":[email protected]:4001,:[email protected]/NameService")),
+ ?match({[[iiop,{1,0},"123.12.23.2",2809],
+ [iiop,{1,0},"10.0.0.1",2809]], "NameService"},
+ orber_cosnaming_utils:addresses(":123.12.23.2,:10.0.0.1/NameService")),
+ ?match({[[iiop,{1,0},"123.12.23.2",2809],
+ [iiop,{1,0},"10.0.0.1",2809]], []},
+ orber_cosnaming_utils:addresses(":123.12.23.2,:10.0.0.1/")),
+ ?match({[[iiop,{1,0},"123.12.23.2",2809],
+ [iiop,{1,0},"10.0.0.1",2809]], []},
+ orber_cosnaming_utils:addresses("iiop:123.12.23.2,:10.0.0.1/")),
+
+ [IP] = ?match([_], orber:host()),
+ {ok, ServerNode, _ServerHost} =
+ ?match({ok,_,_}, orber_test_lib:js_node([{flags, ?ORB_ENV_USE_ACL_INCOMING},
+ {iiop_acl, [{tcp_in, IP++"/32"}]}])),
+ ServerPort = orber_test_lib:remote_apply(ServerNode, orber, iiop_port, []),
+ ?match({'IOP_IOR',_,_},
+ corba:string_to_object("corbaloc::1.2@"++IP++":"++integer_to_list(ServerPort)++"/NameService")),
+% ?line catch orber_test_lib:destroy_node(ServerNode, timeout),
+
+ ok.
+
diff --git a/lib/orber/test/orber_firewall_ipv4_out_SUITE.erl b/lib/orber/test/orber_firewall_ipv4_out_SUITE.erl
new file mode 100644
index 0000000000..193fc72f7c
--- /dev/null
+++ b/lib/orber/test/orber_firewall_ipv4_out_SUITE.erl
@@ -0,0 +1,224 @@
+%%
+%% %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(orber_firewall_ipv4_out_SUITE).
+
+-include("test_server.hrl").
+-include_lib("orber/include/corba.hrl").
+-include_lib("orber/COSS/CosNaming/CosNaming.hrl").
+-include_lib("orber/src/orber_iiop.hrl").
+-include_lib("orber/src/ifr_objects.hrl").
+-include("idl_output/orber_test_server.hrl").
+-include_lib("orber/COSS/CosNaming/CosNaming_NamingContextExt.hrl").
+-include_lib("orber/COSS/CosNaming/CosNaming_NamingContext.hrl").
+
+-define(default_timeout, ?t:minutes(15)).
+
+-define(match(ExpectedRes,Expr),
+ fun() ->
+ AcTuAlReS = (catch (Expr)),
+ case AcTuAlReS of
+ ExpectedRes ->
+ io:format("------ CORRECT RESULT ------~n~p~n",
+ [AcTuAlReS]),
+ AcTuAlReS;
+ _ ->
+ io:format("###### ERROR ERROR ######~nRESULT: ~p~n",
+ [AcTuAlReS]),
+ ?line exit(AcTuAlReS)
+ end
+ end()).
+
+%%-----------------------------------------------------------------
+%% External exports
+%%-----------------------------------------------------------------
+-export([all/1, cases/0, init_all/1, finish_all/1,
+ init_per_testcase/2, fin_per_testcase/2,
+ deny_port_api/1, deny_port_range_api/1, deny_host_api/1,
+ allow_port_api/1, allow_port_range_api/1, allow_host_api/1,
+ local_interface_api/1]).
+
+%%-----------------------------------------------------------------
+%% Func: all/1
+%% Args:
+%% Returns:
+%%-----------------------------------------------------------------
+all(doc) -> ["API tests for orber's firewall functionallity."];
+all(suite) -> {req,
+ [mnesia],
+ {conf, init_all, cases(), finish_all}}.
+
+%% NOTE - the fragment test cases must bu first since we explicitly set a request
+%% id. Otherwise, the request-id counter would be increased and we cannot know
+%% what it is.
+cases() ->
+ [deny_port_api, deny_port_range_api, deny_host_api,
+ allow_port_api, allow_port_range_api, allow_host_api,
+ local_interface_api].
+
+
+init_per_testcase(_Case, Config) ->
+ ?line Dog=test_server:timetrap(?default_timeout),
+ [{watchdog, Dog}|Config].
+
+
+fin_per_testcase(_Case, Config) ->
+ Dog = ?config(watchdog, Config),
+ test_server:timetrap_cancel(Dog),
+ ok.
+
+init_all(Config) ->
+ if
+ is_list(Config) ->
+ orber:jump_start([{iiop_port, 0},
+ {iiop_out_ports, {5980, 6000}}]),
+ Config;
+ true ->
+ exit("Config not a list")
+ end.
+
+finish_all(Config) ->
+ orber:jump_stop(),
+ Config.
+
+%%-----------------------------------------------------------------
+%% Incomming connections - Deny
+%%-----------------------------------------------------------------
+deny_port_api(doc) -> ["Deny Access due to invalid local port"];
+deny_port_api(suite) -> [];
+deny_port_api(_Config) ->
+ [IP] = ?match([_], orber:host()),
+ ServerPort = orber:iiop_port(),
+ {ok, ClientNode, _ClientHost} =
+ ?match({ok,_,_}, orber_test_lib:js_node([{flags, ?ORB_ENV_USE_ACL_OUTGOING},
+ {iiop_acl, [{tcp_out, IP++"/32#" ++ integer_to_list(ServerPort+10)}]}])),
+ ?match({'EXCEPTION', #'CosNaming_NamingContextExt_InvalidAddress'{}},
+ orber_test_lib:remote_apply(ClientNode, corba, string_to_object,
+ ["corbaloc::1.2@"++IP++":"++integer_to_list(ServerPort)++"/NameService"])),
+% ?line catch orber_test_lib:destroy_node(ClientNode, timeout),
+ ok.
+
+deny_port_range_api(doc) -> ["Deny Access due to invalid local port range"];
+deny_port_range_api(suite) -> [];
+deny_port_range_api(_Config) ->
+ [IP] = ?match([_], orber:host()),
+ ServerPort = orber:iiop_port(),
+ {ok, ClientNode, _ClientHost} =
+ ?match({ok,_,_}, orber_test_lib:js_node([{flags, ?ORB_ENV_USE_ACL_OUTGOING},
+ {iiop_acl, [{tcp_out, IP++"/32#"++integer_to_list(ServerPort+100)++ "/" ++ integer_to_list(ServerPort+120)}]}])),
+ ?match({'EXCEPTION', #'CosNaming_NamingContextExt_InvalidAddress'{}},
+ orber_test_lib:remote_apply(ClientNode, corba, string_to_object,
+ ["corbaloc::1.2@"++IP++":"++integer_to_list(ServerPort)++"/NameService"])),
+% ?line catch orber_test_lib:destroy_node(ClientNode, timeout),
+ ok.
+
+
+deny_host_api(doc) -> ["Deny Access due to invalid host"];
+deny_host_api(suite) -> [];
+deny_host_api(_Config) ->
+ [IP] = ?match([_], orber:host()),
+ {ok, ClientNode, _ClientHost} =
+ ?match({ok,_,_}, orber_test_lib:js_node([{flags, ?ORB_ENV_USE_ACL_OUTGOING},
+ {iiop_acl, [{tcp_out, "123.123.123.123/32"}]}])),
+ ServerPort = orber:iiop_port(),
+ ?match({'EXCEPTION', #'CosNaming_NamingContextExt_InvalidAddress'{}},
+ orber_test_lib:remote_apply(ClientNode, corba, string_to_object,
+ ["corbaloc::1.2@"++IP++":"++integer_to_list(ServerPort)++"/NameService"])),
+% ?line catch orber_test_lib:destroy_node(ClientNode, timeout),
+ ok.
+
+%%-----------------------------------------------------------------
+%% Incomming connections - Allow
+%%-----------------------------------------------------------------
+allow_port_api(doc) -> ["Allow Access due to valid local port range"];
+allow_port_api(suite) -> [];
+allow_port_api(_Config) ->
+ [IP] = ?match([_], orber:host()),
+ ServerPort = orber:iiop_port(),
+ {ok, ClientNode, _ClientHost} =
+ ?match({ok,_,_}, orber_test_lib:js_node([{flags, ?ORB_ENV_USE_ACL_OUTGOING},
+ {iiop_acl, [{tcp_out, IP++"/32#"++integer_to_list(ServerPort)}]}])),
+ IOR =
+ ?match({'IOP_IOR',_,_},
+ orber_test_lib:remote_apply(ClientNode, corba, string_to_object,
+ ["corbaloc::1.2@"++IP++":"++integer_to_list(ServerPort)++"/NameService"])),
+ ?match(false,
+ orber_test_lib:remote_apply(ClientNode, corba_object, not_existent, [IOR])),
+% ?line catch orber_test_lib:destroy_node(ClientNode, timeout),
+ ok.
+
+allow_port_range_api(doc) -> ["Allow Access due to valid local port range"];
+allow_port_range_api(suite) -> [];
+allow_port_range_api(_Config) ->
+ [IP] = ?match([_], orber:host()),
+ ServerPort = orber:iiop_port(),
+ {ok, ClientNode, _ClientHost} =
+ ?match({ok,_,_}, orber_test_lib:js_node([{flags, ?ORB_ENV_USE_ACL_OUTGOING},
+ {iiop_acl, [{tcp_out, IP++"/32#" ++ integer_to_list(ServerPort-10) ++ "/" ++ integer_to_list(ServerPort+10)}]}])),
+ IOR =
+ ?match({'IOP_IOR',_,_},
+ orber_test_lib:remote_apply(ClientNode, corba, string_to_object,
+ ["corbaloc::1.2@"++IP++":"++integer_to_list(ServerPort)++"/NameService"])),
+ ?match(false,
+ orber_test_lib:remote_apply(ClientNode, corba_object, not_existent, [IOR])),
+% ?line catch orber_test_lib:destroy_node(ClientNode, timeout),
+ ok.
+
+
+allow_host_api(doc) -> ["Allow Access due to valid host"];
+allow_host_api(suite) -> [];
+allow_host_api(_Config) ->
+ [IP] = ?match([_], orber:host()),
+ {ok, ClientNode, _ClientHost} =
+ ?match({ok,_,_}, orber_test_lib:js_node([{flags, ?ORB_ENV_USE_ACL_OUTGOING},
+ {iiop_acl, [{tcp_out, IP++"/32"}]}])),
+ ServerPort = orber:iiop_port(),
+ IOR =
+ ?match({'IOP_IOR',_,_},
+ orber_test_lib:remote_apply(ClientNode, corba, string_to_object,
+ ["corbaloc::1.2@"++IP++":"++integer_to_list(ServerPort)++"/NameService"])),
+ ?match(false,
+ orber_test_lib:remote_apply(ClientNode, corba_object, not_existent, [IOR])),
+% ?line catch orber_test_lib:destroy_node(ClientNode, timeout),
+ ok.
+
+local_interface_api(doc) -> ["Allow Access due to valid host via a spcific interface"];
+local_interface_api(suite) -> [];
+local_interface_api(_Config) ->
+ IP = orber_test_lib:get_host(),
+ Loopback = orber_test_lib:get_loopback_interface(),
+ {ok, ServerNode, _ServerHost} =
+ ?match({ok,_,_}, orber_test_lib:js_node([{iiop_port, 0},
+ {iiop_out_ports, {5980, 6000}},
+ {ip_address, IP}])),
+ ServerPort = orber_test_lib:remote_apply(ServerNode, orber, iiop_port, []),
+
+ {ok, ClientNode, _ClientHost} =
+ ?match({ok,_,_}, orber_test_lib:js_node([{flags, ?ORB_ENV_USE_ACL_OUTGOING},
+ {iiop_acl, [{tcp_out, IP, [Loopback]}]}])),
+ IOR =
+ ?match({'IOP_IOR',_,_},
+ orber_test_lib:remote_apply(ClientNode, corba, string_to_object,
+ ["corbaloc::1.2@"++IP++":"++integer_to_list(ServerPort)++"/NameService"])),
+ ?match(false,
+ orber_test_lib:remote_apply(ClientNode, corba_object, not_existent, [IOR])),
+% ?line catch orber_test_lib:destroy_node(ClientNode, timeout),
+ ok.
+
diff --git a/lib/orber/test/orber_firewall_ipv6_in_SUITE.erl b/lib/orber/test/orber_firewall_ipv6_in_SUITE.erl
new file mode 100644
index 0000000000..83f48cba0c
--- /dev/null
+++ b/lib/orber/test/orber_firewall_ipv6_in_SUITE.erl
@@ -0,0 +1,311 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 2004-2010. All Rights Reserved.
+%%
+%% The contents of this file are subject to the Erlang Public License,
+%% Version 1.1, (the "License"); you may not use this file except in
+%% compliance with the License. You should have received a copy of the
+%% Erlang Public License along with this software. If not, it can be
+%% retrieved online at http://www.erlang.org/.
+%%
+%% Software distributed under the License is distributed on an "AS IS"
+%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+%% the License for the specific language governing rights and limitations
+%% under the License.
+%%
+%% %CopyrightEnd%
+%%
+%%
+
+-module(orber_firewall_ipv6_in_SUITE).
+
+-include("test_server.hrl").
+-include_lib("orber/include/corba.hrl").
+-include_lib("orber/COSS/CosNaming/CosNaming.hrl").
+-include_lib("orber/src/orber_iiop.hrl").
+-include_lib("orber/src/ifr_objects.hrl").
+-include("idl_output/orber_test_server.hrl").
+-include_lib("orber/COSS/CosNaming/CosNaming_NamingContextExt.hrl").
+-include_lib("orber/COSS/CosNaming/CosNaming_NamingContext.hrl").
+
+-define(default_timeout, ?t:minutes(15)).
+
+-define(match(ExpectedRes,Expr),
+ fun() ->
+ AcTuAlReS = (catch (Expr)),
+ case AcTuAlReS of
+ ExpectedRes ->
+ io:format("------ CORRECT RESULT ------~n~p~n",
+ [AcTuAlReS]),
+ AcTuAlReS;
+ _ ->
+ io:format("###### ERROR ERROR ######~nRESULT: ~p~n",
+ [AcTuAlReS]),
+ ?line exit(AcTuAlReS)
+ end
+ end()).
+
+%%-----------------------------------------------------------------
+%% External exports
+%%-----------------------------------------------------------------
+-export([all/1, cases/0, init_all/1, finish_all/1,
+ init_per_testcase/2, fin_per_testcase/2,
+ deny_port_api/1, deny_port_range_api/1, deny_host_api/1,
+ deny_peerhost_api/1, allow_port_range_api/1,
+ allow_host_api/1, allow_peerhost_api/1, check_address_api/1]).
+
+%%-----------------------------------------------------------------
+%% Func: all/1
+%% Args:
+%% Returns:
+%%-----------------------------------------------------------------
+all(doc) -> ["API tests for orber's firewall functionallity."];
+all(suite) -> {req,
+ [mnesia],
+ {conf, init_all, cases(), finish_all}}.
+
+%% NOTE - the fragment test cases must bu first since we explicitly set a request
+%% id. Otherwise, the request-id counter would be increased and we cannot know
+%% what it is.
+cases() ->
+ [deny_port_api, deny_port_range_api, deny_host_api, deny_peerhost_api,
+ allow_port_range_api, allow_host_api, allow_peerhost_api,
+ check_address_api].
+
+
+init_per_testcase(_Case, Config) ->
+ ?line Dog=test_server:timetrap(?default_timeout),
+ orber:jump_start([{iiop_port, 0},
+ {iiop_out_ports, {5980, 6000}},
+ {flags, ?ORB_ENV_USE_IPV6}]),
+ [{watchdog, Dog}|Config].
+
+
+fin_per_testcase(_Case, Config) ->
+ orber:jump_stop(),
+ Dog = ?config(watchdog, Config),
+ test_server:timetrap_cancel(Dog),
+ ok.
+
+init_all(Config) ->
+ case orber_test_lib:version_ok() of
+ true ->
+ if
+ is_list(Config) ->
+ Config;
+ true ->
+ exit("Config not a list")
+ end;
+ Reason ->
+ Reason
+ end.
+
+finish_all(Config) ->
+ Config.
+
+
+%%-----------------------------------------------------------------
+%% Incomming connections - Deny
+%%-----------------------------------------------------------------
+deny_port_api(doc) -> ["Deny Access due to invalid local port"];
+deny_port_api(suite) -> [];
+deny_port_api(_Config) ->
+ [IP] = ?match([_], orber:host()),
+ {ok, ServerNode, ServerHost} =
+ ?match({ok,_,_}, orber_test_lib:js_node([{flags, (?ORB_ENV_USE_IPV6 bor
+ ?ORB_ENV_USE_ACL_INCOMING)},
+ {iiop_acl, [{tcp_in, IP++"/128#7000"}]}])),
+ ServerPort = orber_test_lib:remote_apply(ServerNode, orber, iiop_port, []),
+ ?match({'EXCEPTION', #'CosNaming_NamingContextExt_InvalidAddress'{}},
+ corba:string_to_object("corbaloc::1.2@"++ServerHost++":"++integer_to_list(ServerPort)++"/NameService")),
+ % ?line catch orber_test_lib:destroy_node(ServerNode, timeout),
+ ok.
+
+deny_port_range_api(doc) -> ["Deny Access due to invalid local port range"];
+deny_port_range_api(suite) -> [];
+deny_port_range_api(_Config) ->
+ [IP] = ?match([_], orber:host()),
+ {ok, ServerNode, ServerHost} =
+ ?match({ok,_,_}, orber_test_lib:js_node([{flags, (?ORB_ENV_USE_IPV6 bor
+ ?ORB_ENV_USE_ACL_INCOMING)},
+ {iiop_acl, [{tcp_in, IP++"/128#7000/8000"}]}])),
+ ServerPort = orber_test_lib:remote_apply(ServerNode, orber, iiop_port, []),
+ ?match({'EXCEPTION', #'CosNaming_NamingContextExt_InvalidAddress'{}},
+ corba:string_to_object("corbaloc::1.2@"++ServerHost++":"++integer_to_list(ServerPort)++"/NameService")),
+% ?line catch orber_test_lib:destroy_node(ServerNode, timeout),
+ ok.
+
+
+deny_host_api(doc) -> ["Deny Access due to invalid host"];
+deny_host_api(suite) -> [];
+deny_host_api(_Config) ->
+ {ok, ServerNode, ServerHost} =
+ ?match({ok,_,_}, orber_test_lib:js_node([{flags, (?ORB_ENV_USE_IPV6 bor
+ ?ORB_ENV_USE_ACL_INCOMING)},
+ {iiop_acl, [{tcp_in, "0:0:0:0:0:0:10.1.1.1/128"}]}])),
+ ServerPort = orber_test_lib:remote_apply(ServerNode, orber, iiop_port, []),
+ ?match({'EXCEPTION', #'CosNaming_NamingContextExt_InvalidAddress'{}},
+ corba:string_to_object("corbaloc::1.2@"++ServerHost++":"++integer_to_list(ServerPort)++"/NameService")),
+% ?line catch orber_test_lib:destroy_node(ServerNode, timeout),
+ ok.
+
+deny_peerhost_api(doc) -> ["Deny Access due to invalid peer host"];
+deny_peerhost_api(suite) -> [];
+deny_peerhost_api(_Config) ->
+ [IP] = ?match([_], orber:host()),
+ {ok, ServerNode, ServerHost} =
+ ?match({ok,_,_},
+ orber_test_lib:js_node([{flags, (?ORB_ENV_USE_IPV6 bor
+ ?ORB_ENV_USE_ACL_INCOMING)},
+ {iiop_acl, [{tcp_in, IP++"/128", ["0:0:0:0:0:0:10.1.1.1"]}]}])),
+ ServerPort = orber_test_lib:remote_apply(ServerNode, orber, iiop_port, []),
+ ?match({'EXCEPTION', #'CosNaming_NamingContextExt_InvalidAddress'{}},
+ corba:string_to_object("corbaloc::1.2@"++ServerHost++":"++integer_to_list(ServerPort)++"/NameService")),
+% ?line catch orber_test_lib:destroy_node(ServerNode, timeout),
+ ok.
+
+%%-----------------------------------------------------------------
+%% Incomming connections - Allow
+%%-----------------------------------------------------------------
+allow_port_range_api(doc) -> ["Allow Access due to valid local port range"];
+allow_port_range_api(suite) -> [];
+allow_port_range_api(_Config) ->
+ [IP] = ?match([_], orber:host()),
+ {ok, ServerNode, ServerHost} =
+ ?match({ok,_,_}, orber_test_lib:js_node([{flags, (?ORB_ENV_USE_IPV6 bor
+ ?ORB_ENV_USE_ACL_INCOMING)},
+ {iiop_acl, [{tcp_in, IP++"/128#5980/6000"}]}])),
+ ServerPort = orber_test_lib:remote_apply(ServerNode, orber, iiop_port, []),
+ IOR =
+ ?match({'IOP_IOR',_,_},
+ corba:string_to_object("corbaloc::1.2@"++ServerHost++":"++integer_to_list(ServerPort)++"/NameService")),
+ ?match(false, corba_object:not_existent(IOR)),
+% ?line catch orber_test_lib:destroy_node(ServerNode, timeout),
+ ok.
+
+
+allow_host_api(doc) -> ["Allow Access due to valid host"];
+allow_host_api(suite) -> [];
+allow_host_api(_Config) ->
+ [IP] = ?match([_], orber:host()),
+ {ok, ServerNode, ServerHost} =
+ ?match({ok,_,_}, orber_test_lib:js_node([{flags, (?ORB_ENV_USE_IPV6 bor
+ ?ORB_ENV_USE_ACL_INCOMING)},
+ {iiop_acl, [{tcp_in, IP++"/128"}]}])),
+ ServerPort = orber_test_lib:remote_apply(ServerNode, orber, iiop_port, []),
+ IOR =
+ ?match({'IOP_IOR',_,_},
+ corba:string_to_object("corbaloc::1.2@"++ServerHost++":"++integer_to_list(ServerPort)++"/NameService")),
+ ?match(false, corba_object:not_existent(IOR)),
+
+% ?line catch orber_test_lib:destroy_node(ServerNode, timeout),
+ ok.
+
+allow_peerhost_api(doc) -> ["Allow Access due to valid host"];
+allow_peerhost_api(suite) -> [];
+allow_peerhost_api(_Config) ->
+ [IP] = ?match([_], orber:host()),
+ {ok, ServerNode, ServerHost} =
+ ?match({ok,_,_}, orber_test_lib:js_node([{flags, (?ORB_ENV_USE_IPV6 bor
+ ?ORB_ENV_USE_ACL_INCOMING)},
+ {iiop_acl, [{tcp_in, IP++"/128", [IP]}]}])),
+ ServerPort = orber_test_lib:remote_apply(ServerNode, orber, iiop_port, []),
+ IOR =
+ ?match({'IOP_IOR',_,_},
+ corba:string_to_object("corbaloc::1.2@"++ServerHost++":"++integer_to_list(ServerPort)++"/NameService",
+ [#'IOP_ServiceContext'
+ {context_id=?ORBER_GENERIC_CTX_ID,
+ context_data = {interface, IP}}])),
+ ?match(false, corba_object:not_existent(IOR,
+ [#'IOP_ServiceContext'
+ {context_id=?ORBER_GENERIC_CTX_ID,
+ context_data = {interface, IP}}])),
+
+% ?line catch orber_test_lib:destroy_node(ServerNode, timeout),
+ ok.
+
+%%-----------------------------------------------------------------
+%% Test corbaloc strings
+%%-----------------------------------------------------------------
+check_address_api(doc) -> ["Test corbaloc strings"];
+check_address_api(suite) -> [];
+check_address_api(_Config) ->
+ ?match({[[iiop,{1,0},"0:0:0:0:0:FFFF:C02A:2A2A",2809]],"NameService"},
+ orber_cosnaming_utils:addresses(":0:0:0:0:0:FFFF:C02A:2A2A/NameService")),
+ ?match({[[iiop,{1,0},"0:0:0:0:0:FFFF:C02A:2A2A",2809]],[]},
+ orber_cosnaming_utils:addresses(":0:0:0:0:0:FFFF:C02A:2A2A")),
+ ?match({[[iiop,{1,2},"0:0:0:0:0:FFFF:C02A:2A2A",2809]],"NameService"},
+ orber_cosnaming_utils:addresses(":1.2@0:0:0:0:0:FFFF:C02A:2A2A/NameService")),
+ ?match({[[iiop,{1,0},"0:0:0:0:0:FFFF:C02A:2A2A",4001]],"NameService"},
+ orber_cosnaming_utils:addresses(":0:0:0:0:0:FFFF:C02A:2A2A:4001/NameService")),
+ ?match({[[iiop,{1,1},"0:0:0:0:0:FFFF:C02A:2A2A",4001]],"NameService"},
+ orber_cosnaming_utils:addresses(":1.1@0:0:0:0:0:FFFF:C02A:2A2A:4001/NameService")),
+ ?match({[[iiop,{1,1},"0:0:0:0:0:FFFF:C02A:2A2A",4001]],[]},
+ orber_cosnaming_utils:addresses(":1.1@0:0:0:0:0:FFFF:C02A:2A2A:4001")),
+ ?match({[[iiop,{1,1},"0:0:0:0:0:FFFF:C02A:2A2A",4001]],[]},
+ orber_cosnaming_utils:addresses("iiop:1.1@0:0:0:0:0:FFFF:C02A:2A2A:4001")),
+
+ ?match({[[iiop,{1,0},"0:0:0:0:0:FFFF:10.11.11.11",2809]],"NameService"},
+ orber_cosnaming_utils:addresses(":0:0:0:0:0:FFFF:10.11.11.11/NameService")),
+ ?match({[[iiop,{1,0},"0:0:0:0:0:FFFF:10.11.11.11",2809]],[]},
+ orber_cosnaming_utils:addresses(":0:0:0:0:0:FFFF:10.11.11.11")),
+ ?match({[[iiop,{1,2},"0:0:0:0:0:FFFF:10.11.11.11",2809]],"NameService"},
+ orber_cosnaming_utils:addresses(":1.2@0:0:0:0:0:FFFF:10.11.11.11/NameService")),
+ ?match({[[iiop,{1,0},"0:0:0:0:0:FFFF:10.11.11.11",4001]],"NameService"},
+ orber_cosnaming_utils:addresses(":0:0:0:0:0:FFFF:10.11.11.11:4001/NameService")),
+ ?match({[[iiop,{1,1},"0:0:0:0:0:FFFF:10.11.11.11",4001]],"NameService"},
+ orber_cosnaming_utils:addresses(":1.1@0:0:0:0:0:FFFF:10.11.11.11:4001/NameService")),
+ ?match({[[iiop,{1,1},"0:0:0:0:0:FFFF:10.11.11.11",4001]],[]},
+ orber_cosnaming_utils:addresses(":1.1@0:0:0:0:0:FFFF:10.11.11.11:4001/")),
+ ?match({[[iiop,{1,1},"0:0:0:0:0:FFFF:10.11.11.11",4001]],[]},
+ orber_cosnaming_utils:addresses("iiop:1.1@0:0:0:0:0:FFFF:10.11.11.11:4001/")),
+
+ ?match({[[iiop,{1,1},"myhost",4001]],[]},
+ orber_cosnaming_utils:addresses("iiop:1.1@myhost:4001")),
+ ?match({[[iiop,{1,1},"myhost.full.name",4001]],"NameService"},
+ orber_cosnaming_utils:addresses("iiop:[email protected]:4001/NameService")),
+ ?match({[[iiop,{1,1},"myhost",4001],
+ [iiop,{1,1},"myhost.full.name",2809]],"NameService"},
+ orber_cosnaming_utils:addresses("iiop:1.1@myhost:4001,iiop:[email protected]/NameService")),
+
+ ?match({[[iiop,{1,1},"0:0:0:0:0:FFFF:10.11.11.11",4001],
+ [iiop,{1,1},"0:0:0:0:0:FFFF:C02A:2A2A",4001]], "NameService"},
+ orber_cosnaming_utils:addresses(":1.1@0:0:0:0:0:FFFF:10.11.11.11:4001,:1.1@0:0:0:0:0:FFFF:C02A:2A2A:4001/NameService")),
+ ?match({[[iiop,{1,1},"0:0:0:0:0:FFFF:10.11.11.11",4001],
+ [iiop,{1,1},"0:0:0:0:0:FFFF:C02A:2A2A",4001]], []},
+ orber_cosnaming_utils:addresses(":1.1@0:0:0:0:0:FFFF:10.11.11.11:4001,:1.1@0:0:0:0:0:FFFF:C02A:2A2A:4001")),
+ ?match({[[iiop,{1,0},"0:0:0:0:0:FFFF:10.11.11.11",4001],
+ [iiop,{1,1},"0:0:0:0:0:FFFF:C02A:2A2A",4001]], "NameService"},
+ orber_cosnaming_utils:addresses(":0:0:0:0:0:FFFF:10.11.11.11:4001,:1.1@0:0:0:0:0:FFFF:C02A:2A2A:4001/NameService")),
+ ?match({[[iiop,{1,1},"0:0:0:0:0:FFFF:10.11.11.11",4001],
+ [iiop,{1,0},"0:0:0:0:0:FFFF:C02A:2A2A",4001]], "NameService"},
+ orber_cosnaming_utils:addresses(":1.1@0:0:0:0:0:FFFF:10.11.11.11:4001,:0:0:0:0:0:FFFF:C02A:2A2A:4001/NameService")),
+ ?match({[[iiop,{1,1},"0:0:0:0:0:FFFF:10.11.11.11",2809],
+ [iiop,{1,1},"0:0:0:0:0:FFFF:C02A:2A2A",4001]], "NameService"},
+ orber_cosnaming_utils:addresses(":1.1@0:0:0:0:0:FFFF:10.11.11.11,:1.1@0:0:0:0:0:FFFF:C02A:2A2A:4001/NameService")),
+ ?match({[[iiop,{1,1},"0:0:0:0:0:FFFF:10.11.11.11",4001],
+ [iiop,{1,1},"0:0:0:0:0:FFFF:C02A:2A2A",2809]], "NameService"},
+ orber_cosnaming_utils:addresses(":1.1@0:0:0:0:0:FFFF:10.11.11.11:4001,:1.1@0:0:0:0:0:FFFF:C02A:2A2A/NameService")),
+ ?match({[[iiop,{1,0},"0:0:0:0:0:FFFF:10.11.11.11",2809],
+ [iiop,{1,0},"0:0:0:0:0:FFFF:C02A:2A2A",2809]], "NameService"},
+ orber_cosnaming_utils:addresses(":0:0:0:0:0:FFFF:10.11.11.11,:0:0:0:0:0:FFFF:C02A:2A2A/NameService")),
+ ?match({[[iiop,{1,0},"0:0:0:0:0:FFFF:10.11.11.11",2809],
+ [iiop,{1,0},"0:0:0:0:0:FFFF:C02A:2A2A",2809]], []},
+ orber_cosnaming_utils:addresses(":0:0:0:0:0:FFFF:10.11.11.11,:0:0:0:0:0:FFFF:C02A:2A2A/")),
+ ?match({[[iiop,{1,0},"0:0:0:0:0:FFFF:10.11.11.11",2809],
+ [iiop,{1,0},"0:0:0:0:0:FFFF:C02A:2A2A",2809]], []},
+ orber_cosnaming_utils:addresses("iiop:0:0:0:0:0:FFFF:10.11.11.11,:0:0:0:0:0:FFFF:C02A:2A2A/")),
+
+ [IP] = ?match([_], orber:host()),
+ {ok, ServerNode, _ServerHost} =
+ ?match({ok,_,_}, orber_test_lib:js_node([{flags, (?ORB_ENV_USE_IPV6 bor
+ ?ORB_ENV_USE_ACL_INCOMING)},
+ {iiop_acl, [{tcp_in, IP++"/128"}]}])),
+ ServerPort = orber_test_lib:remote_apply(ServerNode, orber, iiop_port, []),
+ ?match({'IOP_IOR',_,_},
+ corba:string_to_object("corbaloc::1.2@"++IP++":"++integer_to_list(ServerPort)++"/NameService")),
+% ?line catch orber_test_lib:destroy_node(ServerNode, timeout),
+ ok.
+
+
diff --git a/lib/orber/test/orber_firewall_ipv6_out_SUITE.erl b/lib/orber/test/orber_firewall_ipv6_out_SUITE.erl
new file mode 100644
index 0000000000..e1856b9a47
--- /dev/null
+++ b/lib/orber/test/orber_firewall_ipv6_out_SUITE.erl
@@ -0,0 +1,231 @@
+%%
+%% %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(orber_firewall_ipv6_out_SUITE).
+
+-include("test_server.hrl").
+-include_lib("orber/include/corba.hrl").
+-include_lib("orber/COSS/CosNaming/CosNaming.hrl").
+-include_lib("orber/src/orber_iiop.hrl").
+-include_lib("orber/src/ifr_objects.hrl").
+-include("idl_output/orber_test_server.hrl").
+-include_lib("orber/COSS/CosNaming/CosNaming_NamingContextExt.hrl").
+-include_lib("orber/COSS/CosNaming/CosNaming_NamingContext.hrl").
+
+-define(default_timeout, ?t:minutes(15)).
+
+-define(match(ExpectedRes,Expr),
+ fun() ->
+ AcTuAlReS = (catch (Expr)),
+ case AcTuAlReS of
+ ExpectedRes ->
+ io:format("------ CORRECT RESULT ------~n~p~n",
+ [AcTuAlReS]),
+ AcTuAlReS;
+ _ ->
+ io:format("###### ERROR ERROR ######~nRESULT: ~p~n",
+ [AcTuAlReS]),
+ ?line exit(AcTuAlReS)
+ end
+ end()).
+
+%%-----------------------------------------------------------------
+%% External exports
+%%-----------------------------------------------------------------
+-export([all/1, cases/0, init_all/1, finish_all/1,
+ init_per_testcase/2, fin_per_testcase/2,
+ deny_port_api/1, deny_port_range_api/1, deny_host_api/1,
+ allow_port_api/1, allow_port_range_api/1, allow_host_api/1,
+ local_interface_api/1]).
+
+%%-----------------------------------------------------------------
+%% Func: all/1
+%% Args:
+%% Returns:
+%%-----------------------------------------------------------------
+all(doc) -> ["API tests for orber's firewall functionallity."];
+all(suite) -> {req,
+ [mnesia],
+ {conf, init_all, cases(), finish_all}}.
+
+%% NOTE - the fragment test cases must bu first since we explicitly set a request
+%% id. Otherwise, the request-id counter would be increased and we cannot know
+%% what it is.
+cases() ->
+ [deny_port_api, deny_port_range_api, deny_host_api,
+ allow_port_api, allow_port_range_api, allow_host_api,
+ local_interface_api].
+
+
+init_per_testcase(_Case, Config) ->
+ ?line Dog=test_server:timetrap(?default_timeout),
+ orber:jump_start([{iiop_port, 0},
+ {iiop_out_ports, {5980, 6000}},
+ {flags, ?ORB_ENV_USE_IPV6}]),
+ [{watchdog, Dog}|Config].
+
+
+fin_per_testcase(_Case, Config) ->
+ orber:jump_stop(),
+ Dog = ?config(watchdog, Config),
+ test_server:timetrap_cancel(Dog),
+ ok.
+
+init_all(Config) ->
+ case orber_test_lib:version_ok() of
+ true ->
+ if
+ is_list(Config) ->
+ Config;
+ true ->
+ exit("Config not a list")
+ end;
+ Reason ->
+ Reason
+ end.
+
+finish_all(Config) ->
+ Config.
+
+
+%%-----------------------------------------------------------------
+%% Incomming connections - Deny
+%%-----------------------------------------------------------------
+deny_port_api(doc) -> ["Deny Access due to invalid local port"];
+deny_port_api(suite) -> [];
+deny_port_api(_Config) ->
+ [IP] = ?match([_], orber:host()),
+ ServerPort = orber:iiop_port(),
+ {ok, ServerNode, ServerHost} =
+ ?match({ok,_,_}, orber_test_lib:js_node([{flags, (?ORB_ENV_USE_IPV6 bor
+ ?ORB_ENV_USE_ACL_OUTGOING)},
+ {iiop_acl, [{tcp_out, IP++"/128#" ++ integer_to_list(ServerPort+10)}]}])),
+ ?match({'EXCEPTION', #'CosNaming_NamingContextExt_InvalidAddress'{}},
+ orber_test_lib:remote_apply(ServerNode, corba, string_to_object,
+ ["corbaloc::1.2@"++ServerHost++":"++integer_to_list(ServerPort)++"/NameService"])),
+% ?line catch orber_test_lib:destroy_node(ServerNode, timeout),
+ ok.
+
+deny_port_range_api(doc) -> ["Deny Access due to invalid local port range"];
+deny_port_range_api(suite) -> [];
+deny_port_range_api(_Config) ->
+ [IP] = ?match([_], orber:host()),
+ ServerPort = orber:iiop_port(),
+ {ok, ServerNode, ServerHost} =
+ ?match({ok,_,_}, orber_test_lib:js_node([{flags, (?ORB_ENV_USE_IPV6 bor
+ ?ORB_ENV_USE_ACL_OUTGOING)},
+ {iiop_acl, [{tcp_out, IP++"/128#"++integer_to_list(ServerPort+100)++ "/" ++ integer_to_list(ServerPort+120)}]}])),
+ ?match({'EXCEPTION', #'CosNaming_NamingContextExt_InvalidAddress'{}},
+ orber_test_lib:remote_apply(ServerNode, corba, string_to_object,
+ ["corbaloc::1.2@"++ServerHost++":"++integer_to_list(ServerPort)++"/NameService"])),
+% ?line catch orber_test_lib:destroy_node(ServerNode, timeout),
+ ok.
+
+
+deny_host_api(doc) -> ["Deny Access due to invalid host"];
+deny_host_api(suite) -> [];
+deny_host_api(_Config) ->
+ {ok, ServerNode, ServerHost} =
+ ?match({ok,_,_}, orber_test_lib:js_node([{flags, (?ORB_ENV_USE_IPV6 bor
+ ?ORB_ENV_USE_ACL_OUTGOING)},
+ {iiop_acl, [{tcp_out, "0:0:0:0:0:0:10.1.1.1/128"}]}])),
+ ServerPort = orber:iiop_port(),
+ ?match({'EXCEPTION', #'CosNaming_NamingContextExt_InvalidAddress'{}},
+ orber_test_lib:remote_apply(ServerNode, corba, string_to_object,
+ ["corbaloc::1.2@"++ServerHost++":"++integer_to_list(ServerPort)++"/NameService"])),
+% ?line catch orber_test_lib:destroy_node(ServerNode, timeout),
+ ok.
+
+%%-----------------------------------------------------------------
+%% Incomming connections - Allow
+%%-----------------------------------------------------------------
+allow_port_api(doc) -> ["Allow Access due to valid local port"];
+allow_port_api(suite) -> [];
+allow_port_api(_Config) ->
+ [IP] = ?match([_], orber:host()),
+ ServerPort = orber:iiop_port(),
+ {ok, ServerNode, ServerHost} =
+ ?match({ok,_,_}, orber_test_lib:js_node([{flags, (?ORB_ENV_USE_IPV6 bor
+ ?ORB_ENV_USE_ACL_OUTGOING)},
+ {iiop_acl, [{tcp_out, IP++"/128#" ++ integer_to_list(ServerPort)}]}])),
+ IOR =
+ ?match({'IOP_IOR',_,_},
+ orber_test_lib:remote_apply(ServerNode, corba, string_to_object,
+ ["corbaloc::1.2@"++ServerHost++":"++integer_to_list(ServerPort)++"/NameService"])),
+ ?match(false,
+ orber_test_lib:remote_apply(ServerNode, corba_object, not_existent, [IOR])),
+% ?line catch orber_test_lib:destroy_node(ServerNode, timeout),
+ ok.
+
+allow_port_range_api(doc) -> ["Allow Access due to valid local port range"];
+allow_port_range_api(suite) -> [];
+allow_port_range_api(_Config) ->
+ [IP] = ?match([_], orber:host()),
+ ServerPort = orber:iiop_port(),
+ {ok, ServerNode, ServerHost} =
+ ?match({ok,_,_}, orber_test_lib:js_node([{flags, (?ORB_ENV_USE_IPV6 bor
+ ?ORB_ENV_USE_ACL_OUTGOING)},
+ {iiop_acl, [{tcp_out, IP++"/128#" ++ integer_to_list(ServerPort-10) ++ "/" ++ integer_to_list(ServerPort+10)}]}])),
+ IOR =
+ ?match({'IOP_IOR',_,_},
+ orber_test_lib:remote_apply(ServerNode, corba, string_to_object,
+ ["corbaloc::1.2@"++ServerHost++":"++integer_to_list(ServerPort)++"/NameService"])),
+ ?match(false,
+ orber_test_lib:remote_apply(ServerNode, corba_object, not_existent, [IOR])),
+% ?line catch orber_test_lib:destroy_node(ServerNode, timeout),
+ ok.
+
+
+allow_host_api(doc) -> ["Allow Access due to valid host"];
+allow_host_api(suite) -> [];
+allow_host_api(_Config) ->
+ [IP] = ?match([_], orber:host()),
+ {ok, ServerNode, ServerHost} =
+ ?match({ok,_,_}, orber_test_lib:js_node([{flags, (?ORB_ENV_USE_IPV6 bor
+ ?ORB_ENV_USE_ACL_OUTGOING)},
+ {iiop_acl, [{tcp_out, IP}]}])),
+ ServerPort = orber:iiop_port(),
+ IOR =
+ ?match({'IOP_IOR',_,_},
+ orber_test_lib:remote_apply(ServerNode, corba, string_to_object,
+ ["corbaloc::1.2@"++ServerHost++":"++integer_to_list(ServerPort)++"/NameService"])),
+ ?match(false,
+ orber_test_lib:remote_apply(ServerNode, corba_object, not_existent, [IOR])),
+% ?line catch orber_test_lib:destroy_node(ServerNode, timeout),
+ ok.
+
+local_interface_api(doc) -> ["Allow Access due to valid host via a spcific interface"];
+local_interface_api(suite) -> [];
+local_interface_api(_Config) ->
+ [IP] = ?match([_], orber:host()),
+ {ok, ServerNode, ServerHost} =
+ ?match({ok,_,_}, orber_test_lib:js_node([{flags, (?ORB_ENV_USE_IPV6 bor
+ ?ORB_ENV_USE_ACL_OUTGOING)},
+ {iiop_acl, [{tcp_out, IP, [IP]}]}])),
+ ServerPort = orber:iiop_port(),
+ IOR =
+ ?match({'IOP_IOR',_,_},
+ orber_test_lib:remote_apply(ServerNode, corba, string_to_object,
+ ["corbaloc::1.2@"++ServerHost++":"++integer_to_list(ServerPort)++"/NameService"])),
+ ?match(false,
+ orber_test_lib:remote_apply(ServerNode, corba_object, not_existent, [IOR])),
+% ?line catch orber_test_lib:destroy_node(ServerNode, timeout),
+ ok.
+
diff --git a/lib/orber/test/orber_nat_SUITE.erl b/lib/orber/test/orber_nat_SUITE.erl
new file mode 100644
index 0000000000..5b295dd1aa
--- /dev/null
+++ b/lib/orber/test/orber_nat_SUITE.erl
@@ -0,0 +1,372 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 2006-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(orber_nat_SUITE).
+
+-include("test_server.hrl").
+-include_lib("orber/include/corba.hrl").
+-include_lib("orber/COSS/CosNaming/CosNaming.hrl").
+-include_lib("orber/src/orber_iiop.hrl").
+-include_lib("orber/src/ifr_objects.hrl").
+-include("idl_output/orber_test_server.hrl").
+-include_lib("orber/COSS/CosNaming/CosNaming_NamingContextExt.hrl").
+-include_lib("orber/COSS/CosNaming/CosNaming_NamingContext.hrl").
+
+
+-define(default_timeout, ?t:minutes(15)).
+
+-define(match(ExpectedRes,Expr),
+ fun() ->
+ AcTuAlReS = (catch (Expr)),
+ case AcTuAlReS of
+ ExpectedRes ->
+ io:format("------ CORRECT RESULT ------~n~p~n",
+ [AcTuAlReS]),
+ AcTuAlReS;
+ _ ->
+ io:format("###### ERROR ERROR ######~nRESULT: ~p~n",
+ [AcTuAlReS]),
+ ?line exit(AcTuAlReS)
+ end
+ end()).
+
+%%-----------------------------------------------------------------
+%% External exports
+%%-----------------------------------------------------------------
+-export([all/1, cases/0, init_all/1, finish_all/1,
+ init_per_testcase/2, fin_per_testcase/2,
+ nat_ip_address/1, nat_ip_address_multiple/1,
+ nat_ip_address_local/1, nat_ip_address_local_local/1,
+ nat_iiop_port/1, nat_iiop_port_local/1,
+ nat_iiop_port_local_local/1, nat_iiop_ssl_port/1,
+ nat_iiop_ssl_port_local/1]).
+
+
+%%-----------------------------------------------------------------
+%% Internal exports
+%%-----------------------------------------------------------------
+
+%%-----------------------------------------------------------------
+%% Func: all/1
+%% Args:
+%% Returns:
+%%-----------------------------------------------------------------
+all(doc) -> ["API tests for multi orber interfaces",
+ "This suite test intra-ORB communication. There are three scenarios:",
+ "* No security at all (multi_orber_api)",
+ "* Two secure orbs using ssl (ssl_multi_orb_api)",
+ "* One secure and one orb with no security. (ssl_multi_orb_api)"];
+all(suite) -> {req,
+ [mnesia],
+ {conf, init_all, cases(), finish_all}}.
+
+cases() ->
+ [
+ nat_ip_address,
+ nat_ip_address_multiple,
+ nat_ip_address_local,
+ nat_iiop_port,
+ nat_iiop_port_local,
+ nat_ip_address_local_local,
+ nat_iiop_port_local_local,
+ nat_iiop_ssl_port,
+ nat_iiop_ssl_port_local
+ ].
+
+%%-----------------------------------------------------------------
+%% Init and cleanup functions.
+%%-----------------------------------------------------------------
+
+init_per_testcase(_Case, Config) ->
+ Path = code:which(?MODULE),
+ code:add_pathz(filename:join(filename:dirname(Path), "idl_output")),
+ Dog=test_server:timetrap(?default_timeout),
+ orber:jump_start([{iiop_port, 0},
+ {flags, 0}]),
+ oe_orber_test_server:oe_register(),
+ [{watchdog, Dog}|Config].
+
+
+fin_per_testcase(_Case, Config) ->
+ oe_orber_test_server:oe_unregister(),
+ orber:jump_stop(),
+ Path = code:which(?MODULE),
+ code:del_path(filename:join(filename:dirname(Path), "idl_output")),
+ Dog = ?config(watchdog, Config),
+ test_server:timetrap_cancel(Dog),
+ ok.
+
+init_all(Config) ->
+ if
+ is_list(Config) ->
+ Config;
+ true ->
+ exit("Config not a list")
+ end.
+
+finish_all(Config) ->
+ Config.
+
+%%-----------------------------------------------------------------
+%% API tests for NAT
+%%-----------------------------------------------------------------
+
+nat_ip_address(doc) -> ["This case test if the server ORB use the correct",
+ "interface when exporting IOR:s"];
+nat_ip_address(suite) -> [];
+nat_ip_address(_Config) ->
+ IP = orber_test_lib:get_host(),
+ Loopback = orber_test_lib:get_loopback_interface(),
+ {ok, ServerNode, _ServerHost} =
+ ?match({ok,_,_}, orber_test_lib:js_node([{flags, ?ORB_ENV_ENABLE_NAT},
+ {nat_ip_address, Loopback}])),
+ ServerPort = orber_test_lib:remote_apply(ServerNode, orber, iiop_port, []),
+ IOR = ?match(#'IOP_IOR'{},
+ corba:string_to_object("corbaloc::1.2@"++IP++":"++integer_to_list(ServerPort)++"/NameService")),
+ ?match({'external', {Loopback, ServerPort, _ObjectKey, _Counter, _TP, _NewHD}},
+ iop_ior:get_key(IOR)),
+ ok.
+
+nat_ip_address_multiple(doc) -> ["This case test if the server ORB use the correct",
+ "interface when exporting IOR:s"];
+nat_ip_address_multiple(suite) -> [];
+nat_ip_address_multiple(_Config) ->
+ IP = orber_test_lib:get_host(),
+
+ {ok, ServerNode, _ServerHost} =
+ ?match({ok,_,_}, orber_test_lib:js_node([{flags, ?ORB_ENV_ENABLE_NAT},
+ {nat_ip_address, {multiple, ["10.0.0.1"]}}])),
+ ServerPort = orber_test_lib:remote_apply(ServerNode, orber, iiop_port, []),
+ IOR = ?match(#'IOP_IOR'{},
+ corba:string_to_object("corbaloc::1.2@"++IP++":"++integer_to_list(ServerPort)++"/NameService")),
+ ?match({'external', {"10.0.0.1", ServerPort, _ObjectKey, _Counter, _TP, _NewHD}},
+ iop_ior:get_key(IOR)),
+ ok.
+
+nat_ip_address_local(doc) -> ["This case test if the server ORB use the correct",
+ "interface when exporting IOR:s"];
+nat_ip_address_local(suite) -> [];
+nat_ip_address_local(_Config) ->
+ IP = orber_test_lib:get_host(),
+ {ok, ServerNode, _ServerHost} =
+ ?match({ok,_,_}, orber_test_lib:js_node([{flags, ?ORB_ENV_ENABLE_NAT},
+ {nat_ip_address, {local, "10.0.0.1", [{IP, "127.0.0.1"}]}}])),
+ ServerPort = orber_test_lib:remote_apply(ServerNode, orber, iiop_port, []),
+ IOR = ?match(#'IOP_IOR'{},
+ corba:string_to_object("corbaloc::1.2@"++IP++":"++integer_to_list(ServerPort)++"/NameService")),
+ ?match({'external', {"10.0.0.1", ServerPort, _ObjectKey, _Counter, _TP, _NewHD}},
+ iop_ior:get_key(IOR)),
+ ok.
+
+nat_ip_address_local_local(doc) -> ["This case test if the server ORB use the correct",
+ "interface when exporting IOR:s"];
+nat_ip_address_local_local(suite) -> [];
+nat_ip_address_local_local(_Config) ->
+ IP = orber_test_lib:get_host(),
+ Loopback = orber_test_lib:get_loopback_interface(),
+ {ok, ServerNode, _ServerHost} =
+ ?match({ok,_,_}, orber_test_lib:js_node([{flags,
+ (?ORB_ENV_LOCAL_INTERFACE bor
+ ?ORB_ENV_ENABLE_NAT)},
+ {nat_ip_address, {local, "10.0.0.1", [{IP, "10.0.0.2"}]}}])),
+ ServerPort = orber_test_lib:remote_apply(ServerNode, orber, iiop_port, []),
+ IOR1 = ?match(#'IOP_IOR'{},
+ corba:string_to_object("corbaloc::1.2@"++IP++":"++integer_to_list(ServerPort)++"/NameService")),
+ ?match({'external', {"10.0.0.2", ServerPort, _ObjectKey, _Counter, _TP, _NewHD}},
+ iop_ior:get_key(IOR1)),
+ IOR2 = ?match(#'IOP_IOR'{},
+ corba:string_to_object("corbaloc::1.2@"++Loopback++":"++integer_to_list(ServerPort)++"/NameService")),
+ ?match({'external', {"10.0.0.1", ServerPort, _ObjectKey, _Counter, _TP, _NewHD}},
+ iop_ior:get_key(IOR2)),
+ ok.
+
+nat_iiop_port(doc) -> ["This case test if the server ORB use the correct",
+ "port when exporting IOR:s"];
+nat_iiop_port(suite) -> [];
+nat_iiop_port(_Config) ->
+ IP = orber_test_lib:get_host(),
+ {ok, ServerNode, _ServerHost} =
+ ?match({ok,_,_}, orber_test_lib:js_node([{flags, ?ORB_ENV_ENABLE_NAT},
+ {nat_iiop_port, 42}])),
+ ServerPort = orber_test_lib:remote_apply(ServerNode, orber, iiop_port, []),
+ IOR = ?match(#'IOP_IOR'{},
+ corba:string_to_object("corbaloc::1.2@"++IP++":"++integer_to_list(ServerPort)++"/NameService")),
+ ?match({'external', {_IP, 42, _ObjectKey, _Counter, _TP, _NewHD}},
+ iop_ior:get_key(IOR)),
+ ok.
+
+nat_iiop_port_local(doc) -> ["This case test if the server ORB use the correct",
+ "port when exporting IOR:s"];
+nat_iiop_port_local(suite) -> [];
+nat_iiop_port_local(_Config) ->
+ IP = orber_test_lib:get_host(),
+ {ok, ServerNode, _ServerHost} =
+ ?match({ok,_,_}, orber_test_lib:js_node([{flags, ?ORB_ENV_ENABLE_NAT},
+ {nat_iiop_port, {local, 42, [{4001, 43}]}}])),
+ ServerPort = orber_test_lib:remote_apply(ServerNode, orber, iiop_port, []),
+ IOR = ?match(#'IOP_IOR'{},
+ corba:string_to_object("corbaloc::1.2@"++IP++":"++integer_to_list(ServerPort)++"/NameService")),
+ ?match({'external', {_IP, 42, _ObjectKey, _Counter, _TP, _NewHD}},
+ iop_ior:get_key(IOR)),
+ ok.
+
+nat_iiop_port_local_local(doc) -> ["This case test if the server ORB use the correct",
+ "port when exporting IOR:s"];
+nat_iiop_port_local_local(suite) -> [];
+nat_iiop_port_local_local(_Config) ->
+ IP = orber_test_lib:get_host(),
+ Loopback = orber_test_lib:get_loopback_interface(),
+ {ok, ServerNode, _ServerHost} =
+ ?match({ok,_,_}, orber_test_lib:js_node([{flags,
+ (?ORB_ENV_LOCAL_INTERFACE bor
+ ?ORB_ENV_ENABLE_NAT)},
+ {ip_address, IP}])),
+ ServerPort = orber_test_lib:remote_apply(ServerNode, orber, iiop_port, []),
+ orber_test_lib:remote_apply(ServerNode, orber_env, configure_override, [nat_iiop_port, {local, 42, [{ServerPort, 43}]}]),
+ IOR1 = ?match(#'IOP_IOR'{},
+ corba:string_to_object("corbaloc::1.2@"++IP++":"++integer_to_list(ServerPort)++"/NameService")),
+ ?match({'external', {IP, 43, _ObjectKey, _Counter, _TP, _NewHD}},
+ iop_ior:get_key(IOR1)),
+ {ok, Ref} = ?match({ok, _},
+ orber_test_lib:remote_apply(ServerNode, orber,
+ add_listen_interface,
+ [Loopback, normal, 10088])),
+ IOR2 = ?match(#'IOP_IOR'{},
+ corba:string_to_object("corbaloc::1.2@"++Loopback++":10088/NameService")),
+ ?match({'external', {IP, 42, _ObjectKey, _Counter, _TP, _NewHD}},
+ iop_ior:get_key(IOR2)),
+ ?match(ok,
+ orber_test_lib:remote_apply(ServerNode, orber,
+ remove_listen_interface, [Ref])),
+ ok.
+
+
+%%-----------------------------------------------------------------
+%% API tests for ORB to ORB, ssl security depth 1
+%%-----------------------------------------------------------------
+
+nat_iiop_ssl_port(doc) -> ["SECURE MULTI ORB API tests (SSL depth 1)",
+ "Make sure NAT works for SSL"];
+nat_iiop_ssl_port(suite) -> [];
+nat_iiop_ssl_port(_Config) ->
+ case os:type() of
+ vxworks ->
+ {skipped, "No SSL-support for VxWorks."};
+ _ ->
+ IP = orber_test_lib:get_host(),
+ ServerOptions = orber_test_lib:get_options(iiop_ssl, server,
+ 1, [{iiop_ssl_port, 0},
+ {flags, ?ORB_ENV_ENABLE_NAT},
+ {ip_address, IP}]),
+ ClientOptions = orber_test_lib:get_options(iiop_ssl, client,
+ 1, [{iiop_ssl_port, 0}]),
+ {ok, ServerNode, _ServerHost} =
+ ?match({ok,_,_}, orber_test_lib:js_node(ServerOptions)),
+ ServerPort = orber_test_lib:remote_apply(ServerNode, orber, iiop_port, []),
+ SSLServerPort = orber_test_lib:remote_apply(ServerNode, orber, iiop_ssl_port, []),
+ NATSSLServerPort = SSLServerPort+1,
+ {ok, Ref} = ?match({ok, _},
+ orber_test_lib:remote_apply(ServerNode, orber,
+ add_listen_interface,
+ [IP, ssl, NATSSLServerPort])),
+ orber_test_lib:remote_apply(ServerNode, orber_env, configure_override,
+ [nat_iiop_ssl_port,
+ {local, NATSSLServerPort, [{4001, 43}]}]),
+
+ {ok, ClientNode, _ClientHost} =
+ ?match({ok,_,_}, orber_test_lib:js_node(ClientOptions)),
+ ?match(ok, orber_test_lib:remote_apply(ServerNode, orber_test_lib,
+ install_test_data,
+ [ssl])),
+
+ IOR1 = ?match(#'IOP_IOR'{},
+ orber_test_lib:remote_apply(ClientNode, corba,
+ string_to_object,
+ ["corbaname::1.2@"++IP++":"++
+ integer_to_list(ServerPort)++"/NameService#mamba"])),
+
+ ?match({'external', {_IP, _Port, _ObjectKey, _Counter, _TP,
+ #host_data{protocol = ssl,
+ ssl_data = #'SSLIOP_SSL'{port = NATSSLServerPort}}}},
+ iop_ior:get_key(IOR1)),
+ ?match(ok, orber_test_lib:remote_apply(ServerNode, orber_test_lib,
+ uninstall_test_data,
+ [ssl])),
+ ?match(ok,
+ orber_test_lib:remote_apply(ServerNode, orber,
+ remove_listen_interface, [Ref])),
+ ok
+ end.
+
+nat_iiop_ssl_port_local(doc) -> ["SECURE MULTI ORB API tests (SSL depth 1)",
+ "Make sure NAT works for SSL"];
+nat_iiop_ssl_port_local(suite) -> [];
+nat_iiop_ssl_port_local(_Config) ->
+ case os:type() of
+ vxworks ->
+ {skipped, "No SSL-support for VxWorks."};
+ _ ->
+ IP = orber_test_lib:get_host(),
+ ServerOptions = orber_test_lib:get_options(iiop_ssl, server,
+ 1, [{iiop_ssl_port, 0},
+ {flags,
+ (?ORB_ENV_LOCAL_INTERFACE bor
+ ?ORB_ENV_ENABLE_NAT)},
+ {ip_address, IP}]),
+ ClientOptions = orber_test_lib:get_options(iiop_ssl, client,
+ 1, [{iiop_ssl_port, 0}]),
+ {ok, ServerNode, _ServerHost} =
+ ?match({ok,_,_}, orber_test_lib:js_node(ServerOptions)),
+ ServerPort = orber_test_lib:remote_apply(ServerNode, orber, iiop_port, []),
+ SSLServerPort = orber_test_lib:remote_apply(ServerNode, orber, iiop_ssl_port, []),
+ NATSSLServerPort = SSLServerPort+1,
+ {ok, Ref} = ?match({ok, _},
+ orber_test_lib:remote_apply(ServerNode, orber,
+ add_listen_interface,
+ [IP, ssl, NATSSLServerPort])),
+ orber_test_lib:remote_apply(ServerNode, orber_env, configure_override,
+ [nat_iiop_ssl_port,
+ {local, NATSSLServerPort, [{NATSSLServerPort, NATSSLServerPort}]}]),
+
+ {ok, ClientNode, _ClientHost} =
+ ?match({ok,_,_}, orber_test_lib:js_node(ClientOptions)),
+ ?match(ok, orber_test_lib:remote_apply(ServerNode, orber_test_lib,
+ install_test_data,
+ [ssl])),
+
+ IOR1 = ?match(#'IOP_IOR'{},
+ orber_test_lib:remote_apply(ClientNode, corba,
+ string_to_object,
+ ["corbaname::1.2@"++IP++":"++
+ integer_to_list(ServerPort)++"/NameService#mamba"])),
+
+ ?match({'external', {_IP, _Port, _ObjectKey, _Counter, _TP,
+ #host_data{protocol = ssl,
+ ssl_data = #'SSLIOP_SSL'{port = NATSSLServerPort}}}},
+ iop_ior:get_key(IOR1)),
+ ?match(ok, orber_test_lib:remote_apply(ServerNode, orber_test_lib,
+ uninstall_test_data,
+ [ssl])),
+ ?match(ok,
+ orber_test_lib:remote_apply(ServerNode, orber,
+ remove_listen_interface, [Ref])),
+ ok
+ end.
+
diff --git a/lib/orber/test/orber_test.idl b/lib/orber/test/orber_test.idl
new file mode 100644
index 0000000000..3d943f2d18
--- /dev/null
+++ b/lib/orber/test/orber_test.idl
@@ -0,0 +1,95 @@
+//
+// %CopyrightBegin%
+//
+// 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 Module
+{
+
+ enum Enum {horse, pig, cow};
+
+ struct Struct0 {
+ long l;
+ short s;
+ char c;
+ };
+
+ struct Struct1 {
+ string s;
+ unsigned short us;
+ unsigned long ul;
+ };
+
+ struct Struct2 {
+ sequence <long> long_sequence;
+ Enum e;
+ octet o;
+ };
+
+ struct HEADER {
+ short EID;
+ short NDW;
+ short SSID;
+ };
+
+ enum Enum1 {orange,banana, apple};
+
+ union Union switch (short) {
+ case 0: short First;
+ case 1: string Second;
+ case 2: char Third;
+ };
+
+ union Union1 switch (Enum){
+ case horse: short horse;
+ case pig: sequence <string> Second;
+ case cow: Enum1 Third;
+ };
+
+ union Union2 switch (Enum){
+ case horse: long a[10];
+ case pig: Union u;
+ case cow: Union1 u1;
+ };
+
+ exception Except1 {
+ string why;
+ sequence <string> rest_of_name;
+ };
+
+ exception Except2 {
+ Enum1 e;
+ Struct2 s;
+ };
+
+ exception Except3 {
+ Union1 u;
+ unsigned short s;
+ Object o ;
+ };
+
+ exception Except4 {};
+
+ interface I1 {
+ void a();
+ };
+
+ interface I2 {
+ void a();
+ };
+
+};
+
diff --git a/lib/orber/test/orber_test_lib.erl b/lib/orber/test/orber_test_lib.erl
new file mode 100644
index 0000000000..b95cf4b0ec
--- /dev/null
+++ b/lib/orber/test/orber_test_lib.erl
@@ -0,0 +1,1514 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 1999-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(orber_test_lib).
+-include("test_server.hrl").
+-include_lib("orber/include/corba.hrl").
+-include_lib("orber/include/ifr_types.hrl").
+-include_lib("orber/src/orber_iiop.hrl").
+-include("idl_output/orber_test_server.hrl").
+-include_lib("orber/COSS/CosNaming/CosNaming.hrl").
+
+-define(match(ExpectedRes,Expr),
+ fun() ->
+ AcTuAlReS = (catch (Expr)),
+ case AcTuAlReS of
+ ExpectedRes ->
+ io:format("------ CORRECT RESULT ------~n~p~n",
+ [AcTuAlReS]),
+ AcTuAlReS;
+ _ ->
+ io:format("###### ERROR ERROR ######~nRESULT: ~p~n",
+ [AcTuAlReS]),
+ ?line exit(AcTuAlReS)
+ end
+ end()).
+
+-export([js_node/2,
+ js_node/1,
+ js_node/0,
+ slave_sup/0,
+ remote_apply/4,
+ install_test_data/1,
+ light_tests/3,
+ uninstall_test_data/1,
+ destroy_node/2,
+ lookup/2,
+ alternate_iiop_address/2,
+ create_alternate_iiop_address/2,
+ alternate_ssl_iiop_address/3,
+ create_alternate_ssl_iiop_address/3,
+ test_coding/1,
+ test_coding/2,
+ corba_object_tests/2,
+ timeouts/3,
+ precond/3,
+ postcond/4,
+ oe_get_interface/0,
+ create_components_IOR/1,
+ get_options/2,
+ get_options/3,
+ get_options/4,
+ version_ok/0,
+ ssl_version/0,
+ get_loopback_interface/0,
+ get_loopback_interface/1,
+ get_host/0,
+ get_host/1]).
+
+%% Interceptor functions.
+-export([new_out_connection/3,
+ 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]).
+
+%%------------------------------------------------------------
+%% function : ssl_version
+%% Arguments:
+%% Returns : integer()
+%% Effect :
+%%
+%%------------------------------------------------------------
+ssl_version() ->
+ case catch erlang:system_info(otp_release) of
+ Version when is_list(Version) ->
+ if
+ "R12B" < Version ->
+ 3;
+ true ->
+ 2
+ end;
+ _ ->
+ 2
+ end.
+
+%%------------------------------------------------------------
+%% function : version_ok
+%% Arguments:
+%% Returns : true | {skipped, Reason}
+%% Effect :
+%%
+%%------------------------------------------------------------
+version_ok() ->
+ {ok, Hostname} = inet:gethostname(),
+ case inet:getaddr(Hostname, inet6) of
+ {error,nxdomain} ->
+ {skipped, "Inet cannot handle IPv6"};
+ _ ->
+ case inet:getaddr("0:0:0:0:0:FFFF:127.0.0.1", inet6) of
+ {error,nxdomain} ->
+ {skipped, "Inet cannot handle IPv6"};
+ _ ->
+ case gen_tcp:listen(0, [{reuseaddr, true}, inet6]) of
+ {ok, LSock} ->
+ gen_tcp:close(LSock),
+ true;
+ {error, _} ->
+ {skipped, "Inet cannot handle IPv6"}
+ end
+ end
+ end.
+%%------------------------------------------------------------
+%% function : get_host
+%% Arguments: Family - inet | inet6
+%% Returns : string()
+%% Effect :
+%%
+%%------------------------------------------------------------
+get_host() ->
+ get_host(inet).
+get_host(Family) ->
+ case os:type() of
+ {win32, _} ->
+ case os:version() of
+ {6, _, _} when Family == inet ->
+ "127.0.0.1";
+ {6, _, _} ->
+ "0:0:0:0:0:FFFF:7F00:0001";
+ _ ->
+ [IP] = ?match([_], orber:host()),
+ IP
+ end;
+ _ ->
+ [IP] = ?match([_], orber:host()),
+ IP
+ end.
+
+%%------------------------------------------------------------
+%% function : get_loopback_interface
+%% Arguments: Family - inet | inet6
+%% Returns : string()
+%% Effect :
+%%
+%%------------------------------------------------------------
+get_loopback_interface() ->
+ get_loopback_interface(inet).
+get_loopback_interface(Family) ->
+ case os:type() of
+ {win32, _} ->
+ case os:version() of
+ {6, _, _} when Family == inet ->
+ "127.0.0.2";
+ {6, _, _} ->
+ "0:0:0:0:0:FFFF:7F00:0002";
+ _ when Family == inet ->
+ "127.0.0.1";
+ _ ->
+ "0:0:0:0:0:FFFF:7F00:0001"
+ end;
+ _ when Family == inet ->
+ "127.0.0.1";
+ _ ->
+ "0:0:0:0:0:FFFF:7F00:0001"
+ end.
+
+%%------------------------------------------------------------
+%% function : js_node/4
+%% Arguments: Port - which iiop_port (integer())
+%% InitOptions - [{Key, Value}]
+%% {Type, StartOptions} - {lightweight, [{Key, Value}]}
+%% Returns : {ok, Node} | {error, _}
+%% Effect : Starts a new slave-node with given (optinally)
+%% extra arguments. If fails it retries 'Retries' times.
+%%------------------------------------------------------------
+js_node() ->
+ js_node([], []).
+
+js_node(InitOptions) when is_list(InitOptions) ->
+ js_node(InitOptions, []).
+
+js_node(InitOptions, StartOptions) when is_list(InitOptions) ->
+ {A,B,C} = erlang:now(),
+ [_, Host] = string:tokens(atom_to_list(node()), [$@]),
+ _NewInitOptions = check_options(InitOptions),
+ js_node_helper(Host, 0, lists:concat([A,'_',B,'_',C]),
+ InitOptions, 10, StartOptions).
+
+js_node_helper(Host, Port, Name, Options, Retries, StartOptions) ->
+ case starter(Host, Name, create_paths()) of
+ {ok, NewNode} ->
+ case net_adm:ping(NewNode) of
+ pong ->
+ start_ssl(lists:member({secure, ssl}, Options), NewNode),
+ {ok, Cwd} = file:get_cwd(),
+ Path = code:get_path(),
+ ok = rpc:call(NewNode, file, set_cwd, [Cwd]),
+ true = rpc:call(NewNode, code, set_path, [Path]),
+ rpc:call(NewNode, application, load, [orber]),
+ ok = rpc:call(NewNode, corba, orb_init,
+ [[{iiop_port, Port},
+ {orber_debug_level, 10}|Options]]),
+ start_orber(StartOptions, NewNode),
+ spawn_link(NewNode, ?MODULE, slave_sup, []),
+ rpc:multicall([node() | nodes()], global, sync, []),
+ ok = rpc:call(NewNode, orber, info, [io]),
+ {ok, NewNode, Host};
+ _ ->
+ {error, "net_adm:ping(Node) failed"}
+ end;
+ {error, Reason} when Retries == 0 ->
+ {error, Reason};
+ {error, Reason} ->
+ io:format("Could not start slavenode ~p:~p due to: ~p~n",
+ [Host, Port, Reason]),
+ timer:sleep(500),
+ js_node_helper(Host, Port, Name, Options, Retries-1, StartOptions)
+ end.
+
+check_options(Options) ->
+ case {os:type(), os:version()} of
+ {{win32, _}, {6, _, _}} ->
+ %% Vista, need to run additional checks.
+ case {orber_tb:keysearch(ip_address, Options),
+ orber_tb:keysearch(flags, Options, 0)} of
+ {undefined, Flags} ->
+ case ?ORB_FLAG_TEST(Flags, ?ORB_ENV_USE_IPV6) of
+ true ->
+ [{ip_address, get_host(inet6)}|Options];
+ false ->
+ [{ip_address, get_host(inet)}|Options]
+ end;
+ _ ->
+ Options
+ end;
+ _ ->
+ Options
+ end.
+
+starter(Host, Name, Args) ->
+ case os:type() of
+ vxworks ->
+ test_server:start_node(Name, slave, [{args,Args}]);
+ _ ->
+ slave:start_link(Host, Name, Args)
+ end.
+
+slave_sup() ->
+ process_flag(trap_exit, true),
+ receive
+ {'EXIT', _, _} ->
+ case os:type() of
+ vxworks ->
+ erlang:halt();
+ _ ->
+ ignore
+ end
+ end.
+
+start_ssl(true, Node) ->
+ rpc:call(Node, ssl, start, []),
+ rpc:call(Node, crypto, start, []),
+ rpc:call(Node, ssl, seed, ["testing"]);
+start_ssl(_, _) ->
+ ok.
+
+start_orber({lightweigth, Options}, Node) ->
+ ok = rpc:call(Node, orber, start_lightweight, [Options]);
+start_orber(lightweight, Node) ->
+ ok = rpc:call(Node, orber, start_lightweight, []);
+start_orber(_, Node) ->
+ ok = rpc:call(Node, orber, jump_start, []).
+
+
+%%-----------------------------------------------------------------
+%% Type - ssl | iiop_ssl
+%% Role - 'server' | 'client'
+%% Options - [{Key, Value}]
+%%-----------------------------------------------------------------
+get_options(Type, Role) ->
+ get_options(Type, Role, 2, []).
+
+get_options(ssl, Role, Level) ->
+ get_options(ssl, Role, Level, []).
+
+get_options(ssl, Role, 2, Options) ->
+ Dir = filename:join([code:lib_dir(ssl), "examples", "certs", "etc"]),
+ [{depth, 2},
+ {verify, 2},
+ {keyfile, filename:join([Dir, Role, "key.pem"])},
+ {cacertfile, filename:join([Dir, Role, "cacerts.pem"])},
+ {certfile, filename:join([Dir, Role, "cert.pem"])}|Options];
+get_options(iiop_ssl, _Role, 2, Options) ->
+ Dir = filename:join([code:lib_dir(ssl), "examples", "certs", "etc"]),
+ [{ssl_server_depth, 2},
+ {ssl_server_verify, 2},
+ {ssl_server_certfile, filename:join([Dir, "server", "cert.pem"])},
+ {ssl_server_cacertfile, filename:join([Dir, "server", "cacerts.pem"])},
+ {ssl_server_keyfile, filename:join([Dir, "server", "key.pem"])},
+ {ssl_client_depth, 2},
+ {ssl_client_verify, 2},
+ {ssl_client_certfile, filename:join([Dir, "client", "cert.pem"])},
+ {ssl_client_cacertfile, filename:join([Dir, "client", "cacerts.pem"])},
+ {ssl_client_keyfile, filename:join([Dir, "client", "key.pem"])},
+ {secure, ssl}|Options];
+get_options(iiop_ssl, _Role, 1, Options) ->
+ Dir = filename:join([code:lib_dir(ssl), "examples", "certs", "etc"]),
+ [{ssl_server_depth, 1},
+ {ssl_server_verify, 0},
+ {ssl_server_certfile, filename:join([Dir, "server", "cert.pem"])},
+ {ssl_server_cacertfile, filename:join([Dir, "server", "cacerts.pem"])},
+ {ssl_server_keyfile, filename:join([Dir, "server", "key.pem"])},
+ {ssl_client_depth, 1},
+ {ssl_client_verify, 0},
+ {ssl_client_certfile, filename:join([Dir, "client", "cert.pem"])},
+ {ssl_client_cacertfile, filename:join([Dir, "client", "cacerts.pem"])},
+ {ssl_client_keyfile, filename:join([Dir, "client", "key.pem"])},
+ {secure, ssl}|Options].
+
+
+create_paths() ->
+ Path = filename:dirname(code:which(?MODULE)),
+ " -pa " ++ Path ++ " -pa " ++
+ filename:join(Path, "idl_output") ++
+ " -pa " ++
+ filename:join(Path, "all_SUITE_data") ++
+ " -pa " ++
+ filename:dirname(code:which(orber)).
+
+%%------------------------------------------------------------
+%% function : destroy_node
+%% Arguments: Node - which node to destroy.
+%% Type - normal | ssl
+%% Returns :
+%% Effect :
+%%------------------------------------------------------------
+
+destroy_node(Node, Type) ->
+ stopper(Node, Type).
+
+stopper(Node, _Type) ->
+ case os:type() of
+ vxworks ->
+ test_server:stop_node(Node);
+ _ ->
+ slave:stop(Node)
+ end.
+
+
+%%------------------------------------------------------------
+%% function : remote_apply
+%% Arguments: N - Node, M - Module,
+%% F - Function, A - Arguments (list)
+%% Returns :
+%% Effect :
+%%------------------------------------------------------------
+remote_apply(N, M,F,A) ->
+ case rpc:call(N, M, F, A) of
+ {badrpc, Reason} ->
+ exit(Reason);
+ Other ->
+ Other
+ end.
+
+
+
+%%------------------------------------------------------------
+%% function : install_test_data
+%% Arguments: WhichSuite
+%% Returns : ok
+%% Effect : Installs test data associated with 'WhichSuite'
+%%------------------------------------------------------------
+
+install_test_data(nameservice) ->
+ oe_orber_test_server:oe_register(),
+ Mamba = orber_test_server:oe_create([], [{regname, {local, mamba}}]),
+ true = corba:add_initial_service("Mamba", Mamba),
+ NS = corba:resolve_initial_references("NameService"),
+ NC1 = lname_component:set_id(lname_component:create(), "mamba"),
+ N = lname:insert_component(lname:create(), 1, NC1),
+ 'CosNaming_NamingContext':bind(NS, N,Mamba);
+
+install_test_data({nameservice, AltAddr, AltPort}) ->
+ oe_orber_test_server:oe_register(),
+ Obj = orber_test_server:oe_create([], [{regname, {local, mamba}}]),
+ Mamba = corba:add_alternate_iiop_address(Obj, AltAddr, AltPort),
+ true = corba:add_initial_service("Mamba", Mamba),
+ NS = corba:resolve_initial_references("NameService"),
+ NC1 = lname_component:set_id(lname_component:create(), "mamba"),
+ N = lname:insert_component(lname:create(), 1, NC1),
+ 'CosNaming_NamingContext':bind(NS, N,Mamba);
+
+install_test_data(timeout) ->
+ oe_orber_test_server:oe_register(),
+ Mamba = orber_test_server:oe_create([], {local, mamba}),
+ Viper = orber_test_timeout_server:oe_create([], {local, viper}),
+ NS = corba:resolve_initial_references("NameService"),
+ NC1 = lname_component:set_id(lname_component:create(), "mamba"),
+ N1 = lname:insert_component(lname:create(), 1, NC1),
+ NC2 = lname_component:set_id(lname_component:create(), "viper"),
+ N2 = lname:insert_component(lname:create(), 1, NC2),
+ 'CosNaming_NamingContext':bind(NS, N1, Mamba),
+ 'CosNaming_NamingContext':bind(NS, N2, Viper);
+
+install_test_data(pseudo) ->
+ oe_orber_test_server:oe_register(),
+ Mamba = orber_test_server:oe_create([], [{pseudo,true}]),
+ NS = corba:resolve_initial_references("NameService"),
+ NC1 = lname_component:set_id(lname_component:create(), "mamba"),
+ N = lname:insert_component(lname:create(), 1, NC1),
+ 'CosNaming_NamingContext':bind(NS, N,Mamba);
+
+install_test_data(ssl) ->
+ oe_orber_test_server:oe_register(),
+ Mamba = orber_test_server:oe_create([], [{regname, {local, mamba}}]),
+ NS = corba:resolve_initial_references("NameService"),
+ NC1 = lname_component:set_id(lname_component:create(), "mamba"),
+ N = lname:insert_component(lname:create(), 1, NC1),
+ 'CosNaming_NamingContext':bind(NS, N,Mamba);
+
+install_test_data(ssl_simple) ->
+ oe_orber_test_server:oe_register();
+
+install_test_data(light) ->
+ %% Nothing to do at the moment but we might in the future
+ ok;
+
+install_test_data(_) ->
+ {error, "no_implement"}.
+
+
+%%------------------------------------------------------------
+%% function : uninstall_test_data
+%% Arguments: WhichSuite
+%% Returns : ok
+%% Effect : Uninstalls test data associated with 'WhichSuite'
+%%------------------------------------------------------------
+
+uninstall_test_data(pseudo) ->
+ NS = corba:resolve_initial_references("NameService"),
+ NC1 = lname_component:set_id(lname_component:create(), "mamba"),
+ N = lname:insert_component(lname:create(), 1, NC1),
+ _Obj = (catch 'CosNaming_NamingContext':resolve(NS, N)),
+ catch 'CosNaming_NamingContext':destroy(NS),
+ oe_orber_test_server:oe_unregister();
+
+uninstall_test_data(timeout) ->
+ NS = corba:resolve_initial_references("NameService"),
+ NC1 = lname_component:set_id(lname_component:create(), "mamba"),
+ N1 = lname:insert_component(lname:create(), 1, NC1),
+
+ NC2 = lname_component:set_id(lname_component:create(), "viper"),
+ N2 = lname:insert_component(lname:create(), 1, NC2),
+ Mamba = (catch 'CosNaming_NamingContext':resolve(NS, N1)),
+ Viper = (catch 'CosNaming_NamingContext':resolve(NS, N2)),
+ catch corba:dispose(Mamba),
+ catch corba:dispose(Viper),
+ catch 'CosNaming_NamingContext':destroy(NS),
+ oe_orber_test_server:oe_unregister();
+
+uninstall_test_data(nameservice) ->
+ true = corba:remove_initial_service("Mamba"),
+ NS = corba:resolve_initial_references("NameService"),
+ NC1 = lname_component:set_id(lname_component:create(), "mamba"),
+ N = lname:insert_component(lname:create(), 1, NC1),
+ Obj = (catch 'CosNaming_NamingContext':resolve(NS, N)),
+ catch corba:dispose(Obj),
+ catch 'CosNaming_NamingContext':destroy(NS),
+ oe_orber_test_server:oe_unregister();
+
+uninstall_test_data(ssl) ->
+ NS = corba:resolve_initial_references("NameService"),
+ NC1 = lname_component:set_id(lname_component:create(), "mamba"),
+ N = lname:insert_component(lname:create(), 1, NC1),
+ Obj = (catch 'CosNaming_NamingContext':resolve(NS, N)),
+ catch corba:dispose(Obj),
+ catch 'CosNaming_NamingContext':destroy(NS),
+ oe_orber_test_server:oe_unregister();
+
+uninstall_test_data(ssl_simple) ->
+ oe_orber_test_server:oe_unregister();
+
+uninstall_test_data(light) ->
+ %% Nothing to do at the moment but we might in the future
+ ok;
+
+uninstall_test_data(_) ->
+ {error, "no_implement"}.
+
+%%------------------------------------------------------------
+%% function : corba_object_tests
+%% Arguments: TestServerObj a orber_test_server ref
+%% OtherObj - any other Orber object.
+%% Returns : term()
+%% Effect :
+%%------------------------------------------------------------
+
+corba_object_tests(TestServerObj, OtherObj) ->
+ ?match(false,
+ corba_object:is_a(TestServerObj, "IDL:orber_parent/inherrit:1.0")),
+ ?match(true,
+ corba_object:is_a(TestServerObj, "IDL:omg.org/orber_parent/inherrit:1.0")),
+ ?match(true,
+ corba_object:is_a(TestServerObj, "IDL:omg.org/orber_test/server:1.0")),
+ ?match(false,
+ corba_object:is_a(TestServerObj, "IDL:orber_test/server:1.0")),
+ ?match(false,
+ corba_object:is_a(TestServerObj, "IDL:omg.org/orber_parent/inherrit:1.1")),
+ ?match(false,
+ corba_object:is_a(TestServerObj, "NotValidIFRID")),
+ ?match(false,
+ corba_object:is_nil(TestServerObj)),
+ ?match(false,
+ corba_object:is_equivalent(OtherObj,TestServerObj)),
+ ?match(true,
+ corba_object:is_equivalent(TestServerObj,TestServerObj)),
+ ?match(false, corba_object:non_existent(TestServerObj)),
+ ?match(false, corba_object:not_existent(TestServerObj)),
+ ?match(#fullinterfacedescription{}, corba_object:get_interface(TestServerObj)),
+
+ ok.
+
+%%------------------------------------------------------------
+%% function : lookup
+%% Arguments: Port - which port the other orb uses.
+%% Returns : term()
+%% Effect :
+%%------------------------------------------------------------
+
+lookup(Host, Port) ->
+ Key = Host++":"++integer_to_list(Port),
+ NSR = corba:resolve_initial_references_remote("NameService",
+ ["iiop://"++Key]),
+
+ NC1 = lname_component:set_id(lname_component:create(), "not_exist"),
+ N1 = lname:insert_component(lname:create(), 1, NC1),
+ ?match({'EXCEPTION',{'CosNaming_NamingContext_NotFound',_,_,_}},
+ 'CosNaming_NamingContext':resolve(NSR, N1)),
+
+ NC2 = lname_component:set_id(lname_component:create(), "mamba"),
+ N2 = lname:insert_component(lname:create(), 1, NC2),
+ Obj = ?match({'IOP_IOR',"IDL:omg.org/orber_test/server:1.0",_},
+ 'CosNaming_NamingContext':resolve(NSR, N2)),
+ orber_test_server:print(Obj),
+ Obj2 = ?match({'IOP_IOR',"IDL:omg.org/orber_test/server:1.0",_},
+ corba:string_to_object("corbaname:iiop:1.1@"++Key++"/NameService#mamba")),
+
+ orber_test_server:print(Obj2),
+
+ NSR2 = ?match({'IOP_IOR',"IDL:omg.org/CosNaming/NamingContextExt:1.0",_},
+ corba:string_to_object("corbaloc:iiop:1.1@"++Key++"/NameService")),
+ Obj3 = ?match({'IOP_IOR',"IDL:omg.org/orber_test/server:1.0",_},
+ 'CosNaming_NamingContext':resolve(NSR2, N2)),
+ orber_test_server:print(Obj3).
+
+%%------------------------------------------------------------
+%% function : alternate_iiop_address
+%% Arguments: Port - which port the other orb uses.
+%% Returns : term()
+%% Effect :
+%%------------------------------------------------------------
+alternate_iiop_address(Host, Port) ->
+ IOR = create_alternate_iiop_address(Host, Port),
+
+ ?match(false, corba_object:non_existent(IOR)),
+ ?match({'object_forward',_}, corba:locate(IOR)),
+ ?match({'object_forward',_}, corba:locate(IOR, 10000)),
+ ok.
+
+%%------------------------------------------------------------
+%% function : create_alternate_iiop_address
+%% Arguments: Port - which port the other orb uses.
+%% Returns : term()
+%% Effect :
+%%------------------------------------------------------------
+create_alternate_iiop_address(Host, Port) ->
+ MC = [#'IOP_TaggedComponent'{tag = ?TAG_ORB_TYPE,
+ component_data = ?ORBER_ORB_TYPE_1},
+ #'IOP_TaggedComponent'{tag = ?TAG_CODE_SETS,
+ component_data = ?DEFAULT_CODESETS},
+ #'IOP_TaggedComponent'{tag = ?TAG_ALTERNATE_IIOP_ADDRESS,
+ component_data = #'ALTERNATE_IIOP_ADDRESS'{
+ 'HostID' = Host,
+ 'Port' = Port}},
+ #'IOP_TaggedComponent'{tag = ?TAG_ALTERNATE_IIOP_ADDRESS,
+ component_data = #'ALTERNATE_IIOP_ADDRESS'{
+ 'HostID' = Host,
+ 'Port' = 8000}},
+ #'IOP_TaggedComponent'{tag = ?TAG_ALTERNATE_IIOP_ADDRESS,
+ component_data = #'ALTERNATE_IIOP_ADDRESS'{
+ 'HostID' = Host,
+ 'Port' = 8000}}],
+ #'IOP_IOR'{type_id=TypeID,
+ profiles=P1} = _IORA = iop_ior:create({1,2},
+ "IDL:omg.org/CosNaming/NamingContextExt:1.0",
+ [Host], 8000, -1,
+ "NameService", MC, 0, 0),
+ #'IOP_IOR'{profiles=P2} = _IORB = iop_ior:create({1,1},
+ "IDL:omg.org/CosNaming/NamingContextExt:1.0",
+ [Host], 8000, -1,
+ "NameService", [], 0, 0),
+ #'IOP_IOR'{type_id=TypeID, profiles=P2++P1}.
+
+
+%%------------------------------------------------------------
+%% function : create_components_IOR
+%% Arguments:
+%% Returns : term()
+%% Effect :
+%%------------------------------------------------------------
+create_components_IOR(Version) ->
+ MC = [#'IOP_TaggedComponent'{tag = ?TAG_ORB_TYPE,
+ component_data = ?ORBER_ORB_TYPE_1},
+ #'IOP_TaggedComponent'{tag = ?TAG_CODE_SETS,
+ component_data = ?DEFAULT_CODESETS},
+ #'IOP_TaggedComponent'{tag = ?TAG_ALTERNATE_IIOP_ADDRESS,
+ component_data = #'ALTERNATE_IIOP_ADDRESS'{
+ 'HostID' = "127.0.0.1",
+ 'Port' = 4001}},
+ #'IOP_TaggedComponent'{tag = ?TAG_SSL_SEC_TRANS,
+ component_data = #'SSLIOP_SSL'{target_supports = 0,
+ target_requires = 1,
+ port = 2}},
+ #'IOP_TaggedComponent'{tag = ?TAG_FT_GROUP,
+ component_data =
+ #'FT_TagFTGroupTaggedComponent'
+ {version = #'GIOP_Version'{major = 1,
+ minor = 2},
+ ft_domain_id = "FT_FTDomainId",
+ object_group_id = ?ULONGLONGMAX,
+ object_group_ref_version = ?LONGMAX}},
+ #'IOP_TaggedComponent'{tag = ?TAG_FT_PRIMARY,
+ component_data =
+ #'FT_TagFTPrimaryTaggedComponent'{primary = true}},
+ #'IOP_TaggedComponent'{tag = ?TAG_FT_HEARTBEAT_ENABLED,
+ component_data =
+ #'FT_TagFTHeartbeatEnabledTaggedComponent'{heartbeat_enabled = true}},
+ #'IOP_TaggedComponent'{tag = ?TAG_CSI_SEC_MECH_LIST,
+ component_data =
+ #'CSIIOP_CompoundSecMechList'
+ {stateful = false,
+ mechanism_list =
+ [#'CSIIOP_CompoundSecMech'
+ {target_requires = 6,
+ transport_mech =
+ #'IOP_TaggedComponent'
+ {tag=?TAG_TLS_SEC_TRANS,
+ component_data=#'CSIIOP_TLS_SEC_TRANS'
+ {target_supports = 7,
+ target_requires = 8,
+ addresses =
+ [#'CSIIOP_TransportAddress'{host_name = "127.0.0.1",
+ port = 6001}]}},
+ as_context_mech =
+ #'CSIIOP_AS_ContextSec'
+ {target_supports = 9, target_requires = 10,
+ client_authentication_mech = [1, 255],
+ target_name = [2,255]},
+ sas_context_mech =
+ #'CSIIOP_SAS_ContextSec'
+ {target_supports = 11, target_requires = 12,
+ privilege_authorities =
+ [#'CSIIOP_ServiceConfiguration'
+ {syntax = ?ULONGMAX,
+ name = [3,255]}],
+ supported_naming_mechanisms = [[4,255],[5,255]],
+ supported_identity_types = ?ULONGMAX}},
+ #'CSIIOP_CompoundSecMech'
+ {target_requires = 6,
+ transport_mech =
+ #'IOP_TaggedComponent'
+ {tag=?TAG_NULL_TAG,
+ component_data=[]},
+ as_context_mech =
+ #'CSIIOP_AS_ContextSec'
+ {target_supports = 9, target_requires = 10,
+ client_authentication_mech = [1, 255],
+ target_name = [2,255]},
+ sas_context_mech =
+ #'CSIIOP_SAS_ContextSec'
+ {target_supports = 11, target_requires = 12,
+ privilege_authorities =
+ [#'CSIIOP_ServiceConfiguration'
+ {syntax = ?ULONGMAX,
+ name = [3,255]}],
+ supported_naming_mechanisms = [[4,255],[5,255]],
+ supported_identity_types = ?ULONGMAX}},
+ #'CSIIOP_CompoundSecMech'
+ {target_requires = 6,
+ transport_mech =
+ #'IOP_TaggedComponent'
+ {tag=?TAG_SECIOP_SEC_TRANS,
+ component_data=#'CSIIOP_SECIOP_SEC_TRANS'
+ {target_supports = 7,
+ target_requires = 8,
+ mech_oid = [0,255],
+ target_name = [0,255],
+ addresses =
+ [#'CSIIOP_TransportAddress'{host_name = "127.0.0.1",
+ port = 6001}]}},
+ as_context_mech =
+ #'CSIIOP_AS_ContextSec'
+ {target_supports = 9, target_requires = 10,
+ client_authentication_mech = [1, 255],
+ target_name = [2,255]},
+ sas_context_mech =
+ #'CSIIOP_SAS_ContextSec'
+ {target_supports = 11, target_requires = 12,
+ privilege_authorities =
+ [#'CSIIOP_ServiceConfiguration'
+ {syntax = ?ULONGMAX,
+ name = [3,255]}],
+ supported_naming_mechanisms = [[4,255],[5,255]],
+ supported_identity_types = ?ULONGMAX}}]}}],
+ iop_ior:create(Version, "IDL:omg.org/CosNaming/NamingContextExt:1.0",
+ ["127.0.0.1"], 5001, -1,
+ "NameService", MC, 0, 0).
+
+
+%%------------------------------------------------------------
+%% function : alternate_ssl_iiop_address
+%% Arguments: Port - which port the other orb uses.
+%% Returns : term()
+%% Effect :
+%%------------------------------------------------------------
+alternate_ssl_iiop_address(Host, Port, SSLPort) ->
+ IOR = create_alternate_ssl_iiop_address(Host, Port, SSLPort),
+
+ ?match(false, corba_object:non_existent(IOR)),
+ ?match({'object_forward',_}, corba:locate(IOR)),
+ ?match({'object_forward',_}, corba:locate(IOR, 10000)),
+ ok.
+
+
+%%------------------------------------------------------------
+%% function : create_alternate_ssl_iiop_address
+%% Arguments: Port - which port the other orb uses.
+%% Returns : term()
+%% Effect :
+%%------------------------------------------------------------
+create_alternate_ssl_iiop_address(Host, Port, SSLPort) ->
+ MC = [#'IOP_TaggedComponent'{tag = ?TAG_ORB_TYPE,
+ component_data = ?ORBER_ORB_TYPE_1},
+ #'IOP_TaggedComponent'{tag = ?TAG_CODE_SETS,
+ component_data = ?DEFAULT_CODESETS},
+ #'IOP_TaggedComponent'{tag = ?TAG_ALTERNATE_IIOP_ADDRESS,
+ component_data = #'ALTERNATE_IIOP_ADDRESS'{
+ 'HostID' = Host,
+ 'Port' = Port}},
+ #'IOP_TaggedComponent'{tag = ?TAG_ALTERNATE_IIOP_ADDRESS,
+ component_data = #'ALTERNATE_IIOP_ADDRESS'{
+ 'HostID' = Host,
+ 'Port' = 8000}},
+ #'IOP_TaggedComponent'{tag = ?TAG_ALTERNATE_IIOP_ADDRESS,
+ component_data = #'ALTERNATE_IIOP_ADDRESS'{
+ 'HostID' = Host,
+ 'Port' = 8000}},
+ #'IOP_TaggedComponent'{tag=?TAG_SSL_SEC_TRANS,
+ component_data=#'SSLIOP_SSL'{target_supports = 2,
+ target_requires = 2,
+ port = SSLPort}}],
+ #'IOP_IOR'{type_id=TypeID,
+ profiles=P1} = _IORA = iop_ior:create_external({1,2},
+ "IDL:omg.org/CosNaming/NamingContextExt:1.0",
+ Host, 8000,
+ "NameService", MC),
+ #'IOP_IOR'{profiles=P2} = _IORB = iop_ior:create_external({1,1},
+ "IDL:omg.org/CosNaming/NamingContextExt:1.0",
+ Host, 8000,
+ "NameService", []),
+ #'IOP_IOR'{type_id=TypeID, profiles=P2++P1}.
+
+
+%%------------------------------------------------------------
+%% function : timeouts
+%% Arguments: Port - which port the other orb uses.
+%% Returns : term()
+%% Effect :
+%%------------------------------------------------------------
+
+timeouts(Host, Port, ReqT) ->
+ NSR = corba:resolve_initial_references_remote("NameService",
+ ["iiop://"++Host++":"++integer_to_list(Port)]),
+ NC1 = lname_component:set_id(lname_component:create(), "mamba"),
+ N1 = lname:insert_component(lname:create(), 1, NC1),
+ NC2 = lname_component:set_id(lname_component:create(), "viper"),
+ N2 = lname:insert_component(lname:create(), 1, NC2),
+ Mamba = 'CosNaming_NamingContext':resolve(NSR, N1),
+ Viper = 'CosNaming_NamingContext':resolve(NSR, N2),
+
+ ?match({'EXCEPTION',{'TIMEOUT',_,_,_}},
+ orber_test_timeout_server:twoway_function(Viper, ReqT, ReqT*2)),
+ ?match(ok, orber_test_timeout_server:oneway_function(Viper, ReqT*2)),
+
+ ?match({'EXCEPTION',{'TIMEOUT',_,_,_}},
+ orber_test_server:testing_iiop_twoway_delay(Mamba, ReqT)),
+ ?match(ok, orber_test_server:testing_iiop_oneway_delay(Mamba, ReqT)),
+
+ %% Since the objects are stalled we must wait until they are available again
+ %% to be able to run any more tests and get the correct results.
+ timer:sleep(ReqT*4),
+
+ ?match(ok, orber_test_timeout_server:twoway_function(Viper, ReqT*2, ReqT)),
+ ?match(ok, orber_test_timeout_server:oneway_function(Viper, ReqT*2)),
+
+ ?match(ok, orber_test_server:testing_iiop_twoway_delay(Mamba, 0)),
+ ?match(ok, orber_test_server:testing_iiop_oneway_delay(Mamba, 0)),
+
+ timer:sleep(ReqT*4),
+ ok.
+
+%%------------------------------------------------------------
+%% function : light_tests
+%% Arguments: Host - which node to contact.
+%% Port - which port the other orb uses.
+%% Returns : term()
+%% Effect :
+%%------------------------------------------------------------
+
+light_tests(Host, Port, ObjName) ->
+ NSR = corba:resolve_initial_references_remote("NameService",
+ ["iiop://"++Host++":"++integer_to_list(Port)]),
+ NC1 = lname_component:set_id(lname_component:create(), "not_exist"),
+ N1 = lname:insert_component(lname:create(), 1, NC1),
+ %% We cannot handle any unknown replies (besides those found in stub).
+ ?match({'EXCEPTION',
+ {'CosNaming_NamingContext_NotFound',
+ "IDL:omg.org/CosNaming/NamingContext/NotFound:1.0",_,_}},
+ 'CosNaming_NamingContext':resolve(NSR, N1)),
+ NC2 = lname_component:set_id(lname_component:create(), ObjName),
+ N2 = lname:insert_component(lname:create(), 1, NC2),
+ Obj = ?match({'IOP_IOR',"IDL:omg.org/orber_test/server:1.0",_},
+ 'CosNaming_NamingContext':resolve(NSR, N2)),
+ Nodes = orber:get_lightweight_nodes(),
+ io:format("Light Nodes: ~p~n", [Nodes]),
+ orber_test_server:print(Obj),
+ test_coding(Obj),
+ ok.
+
+
+%%------------------------------------------------------------
+%% function : test_coding_simple
+%% Arguments: ObjReference
+%% Returns : term()
+%% Effect : test encode/decode for all simple datatypes.
+%%------------------------------------------------------------
+
+test_coding(Obj) ->
+ test_coding(Obj, false).
+
+test_coding(Obj, Local) ->
+ %%--- Testing code and decode arguments ---
+ ?match({ok, 1.5}, orber_test_server:testing_iiop_float(Obj, 1.5)),
+ ?match({'EXCEPTION',{'MARSHAL',_,_,_}},
+ orber_test_server:testing_iiop_float(Obj, atom)),
+
+ ?match({ok,1.0}, orber_test_server:testing_iiop_double(Obj, 1.0)),
+ ?match({'EXCEPTION',{'MARSHAL',_,_,_}},
+ orber_test_server:testing_iiop_double(Obj, "wrong")),
+
+ ?match({ok,0}, orber_test_server:testing_iiop_short(Obj, 0)),
+ ?match({ok,?SHORTMAX}, orber_test_server:testing_iiop_short(Obj, ?SHORTMAX)),
+ ?match({ok,?SHORTMIN}, orber_test_server:testing_iiop_short(Obj, ?SHORTMIN)),
+ ?match({'EXCEPTION',{'MARSHAL',_,_,_}},
+ orber_test_server:testing_iiop_short(Obj, atomic)),
+ ?match({'EXCEPTION',{'MARSHAL',_,_,_}},
+ orber_test_server:testing_iiop_short(Obj, ?SHORTMAX+1)),
+ ?match({'EXCEPTION',{'MARSHAL',_,_,_}},
+ orber_test_server:testing_iiop_short(Obj, ?SHORTMIN-1)),
+
+ ?match({ok,0}, orber_test_server:testing_iiop_ushort(Obj, 0)),
+ ?match({ok,?USHORTMAX}, orber_test_server:testing_iiop_ushort(Obj, ?USHORTMAX)),
+ ?match({ok,?USHORTMIN}, orber_test_server:testing_iiop_ushort(Obj, ?USHORTMIN)),
+ ?match({'EXCEPTION',{'MARSHAL',_,_,_}},
+ orber_test_server:testing_iiop_ushort(Obj, ?USHORTMAX+1)),
+ ?match({'EXCEPTION',{'MARSHAL',_,_,_}},
+ orber_test_server:testing_iiop_ushort(Obj, ?USHORTMIN-1)),
+
+ ?match({ok,0}, orber_test_server:testing_iiop_long(Obj, 0)),
+ ?match({ok,?LONGMAX}, orber_test_server:testing_iiop_long(Obj, ?LONGMAX)),
+ ?match({ok,?LONGMIN}, orber_test_server:testing_iiop_long(Obj, ?LONGMIN)),
+ ?match({'EXCEPTION',{'MARSHAL',_,_,_}},
+ orber_test_server:testing_iiop_long(Obj, "wrong")),
+ ?match({'EXCEPTION',{'MARSHAL',_,_,_}},
+ orber_test_server:testing_iiop_long(Obj, ?LONGMAX+1)),
+ ?match({'EXCEPTION',{'MARSHAL',_,_,_}},
+ orber_test_server:testing_iiop_long(Obj, ?LONGMIN-1)),
+
+ ?match({ok,0}, orber_test_server:testing_iiop_longlong(Obj, 0)),
+ ?match({ok,?LONGLONGMAX}, orber_test_server:testing_iiop_longlong(Obj, ?LONGLONGMAX)),
+ ?match({ok,?LONGLONGMIN}, orber_test_server:testing_iiop_longlong(Obj, ?LONGLONGMIN)),
+ ?match({'EXCEPTION',{'MARSHAL',_,_,_}},
+ orber_test_server:testing_iiop_longlong(Obj, "wrong")),
+ ?match({'EXCEPTION',{'MARSHAL',_,_,_}},
+ orber_test_server:testing_iiop_longlong(Obj, ?LONGLONGMAX+1)),
+ ?match({'EXCEPTION',{'MARSHAL',_,_,_}},
+ orber_test_server:testing_iiop_longlong(Obj, ?LONGLONGMIN-1)),
+
+ ?match({ok,0}, orber_test_server:testing_iiop_ulong(Obj, 0)),
+ ?match({ok,?ULONGMAX}, orber_test_server:testing_iiop_ulong(Obj, ?ULONGMAX)),
+ ?match({ok,?ULONGMIN}, orber_test_server:testing_iiop_ulong(Obj, ?ULONGMIN)),
+ ?match({'EXCEPTION',{'MARSHAL',_,_,_}},
+ orber_test_server:testing_iiop_ulong(Obj, ?ULONGMAX+1)),
+ ?match({'EXCEPTION',{'MARSHAL',_,_,_}},
+ orber_test_server:testing_iiop_ulong(Obj, ?ULONGMIN-1)),
+
+ ?match({ok,0}, orber_test_server:testing_iiop_ulonglong(Obj, 0)),
+ ?match({ok,?ULONGLONGMAX}, orber_test_server:testing_iiop_ulonglong(Obj, ?ULONGLONGMAX)),
+ ?match({ok,?ULONGLONGMIN}, orber_test_server:testing_iiop_ulonglong(Obj, ?ULONGLONGMIN)),
+ ?match({'EXCEPTION',{'MARSHAL',_,_,_}},
+ orber_test_server:testing_iiop_ulonglong(Obj, ?ULONGLONGMAX+1)),
+ ?match({'EXCEPTION',{'MARSHAL',_,_,_}},
+ orber_test_server:testing_iiop_ulonglong(Obj, ?ULONGLONGMIN-1)),
+
+ ?match({ok,98}, orber_test_server:testing_iiop_char(Obj, 98)),
+ ?match({ok,$b}, orber_test_server:testing_iiop_char(Obj, $b)),
+
+ ?match({'EXCEPTION',{'MARSHAL',_,_,_}},
+ orber_test_server:testing_iiop_char(Obj, atomic)),
+
+ ?match({ok,65535}, orber_test_server:testing_iiop_wchar(Obj, 65535)),
+ ?match({ok,$b}, orber_test_server:testing_iiop_wchar(Obj, $b)),
+
+ ?match({'EXCEPTION',{'MARSHAL',_,_,_}},
+ orber_test_server:testing_iiop_wchar(Obj, atomic)),
+
+ ?match({ok,true}, orber_test_server:testing_iiop_bool(Obj, true)),
+ ?match({ok,false}, orber_test_server:testing_iiop_bool(Obj, false)),
+ ?match({'EXCEPTION',{'MARSHAL',_,_,_}},
+ orber_test_server:testing_iiop_bool(Obj, atom)),
+
+ ?match({ok,1}, orber_test_server:testing_iiop_octet(Obj, 1)),
+% No real guards for this case.
+% ?match({'EXCEPTION',{'MARSHAL',_,_,_}},
+% orber_test_server:testing_iiop_octet(Obj, 1.5)),
+ IOR12 = create_components_IOR({1,2}),
+ ?match({ok,Obj}, orber_test_server:testing_iiop_obj(Obj, Obj)),
+ ?match({ok,IOR12}, orber_test_server:testing_iiop_obj(Obj, IOR12)),
+ PObj = orber_test_server:oe_create([], [{pseudo,true}]),
+ ?match({ok, _}, orber_test_server:testing_iiop_obj(Obj, PObj)),
+ ?match({'EXCEPTION',{'MARSHAL',_,_,_}},
+ orber_test_server:testing_iiop_obj(Obj, "no_object")),
+ ?match({ok,"string"}, orber_test_server:testing_iiop_string(Obj, "string")),
+ ?match({'EXCEPTION',{'MARSHAL',_,_,_}},
+ orber_test_server:testing_iiop_string(Obj, "ToLongString")),
+ ?match({'EXCEPTION',{'MARSHAL',_,_,_}},
+ orber_test_server:testing_iiop_string(Obj, atomic)),
+
+ ?match({ok,[65535]}, orber_test_server:testing_iiop_wstring(Obj, [65535])),
+ ?match({'EXCEPTION',{'MARSHAL',_,_,_}},
+ orber_test_server:testing_iiop_wstring(Obj, "ToLongWstring")),
+ ?match({'EXCEPTION',{'MARSHAL',_,_,_}},
+ orber_test_server:testing_iiop_wstring(Obj, atomic)),
+
+ ?match({ok, one},
+ orber_test_server:testing_iiop_enum(Obj, one)),
+ ?match({'EXCEPTION',{'MARSHAL',_,_,_}},
+ orber_test_server:testing_iiop_enum(Obj, three)),
+ ?match({ok,[1,2,3]},
+ orber_test_server:testing_iiop_seq(Obj, [1,2,3])),
+ ?match({'EXCEPTION',{'MARSHAL',_,_,_}},
+ orber_test_server:testing_iiop_seq(Obj, [1,2,3,4])),
+ ?match({'EXCEPTION',{'MARSHAL',_,_,_}},
+ orber_test_server:testing_iiop_seq(Obj, false)),
+
+
+ ?match({ok,[#orber_test_server_struc{a=1, b=2}]},
+ orber_test_server:testing_iiop_struc_seq(Obj,
+ [#orber_test_server_struc{a=1, b=2}])),
+ ?match({'EXCEPTION',{'MARSHAL',_,_,_}},
+ orber_test_server:testing_iiop_struc_seq(Obj, false)),
+
+ ?match({ok,[#orber_test_server_uni{label=1, value=66}]},
+ orber_test_server:testing_iiop_uni_seq(Obj,
+ [#orber_test_server_uni{label=1, value=66}])),
+ ?match({'EXCEPTION',{'MARSHAL',_,_,_}},
+ orber_test_server:testing_iiop_uni_seq(Obj, false)),
+
+ ?match({ok,{"one", "two"}},
+ orber_test_server:testing_iiop_array(Obj, {"one", "two"})),
+ ?match({'EXCEPTION',{'MARSHAL',_,_,_}},
+ orber_test_server:testing_iiop_array(Obj, {"one", "two", "three"})),
+ ?match({ok,#orber_test_server_struc{a=1, b=2}},
+ orber_test_server:testing_iiop_struct(Obj,
+ #orber_test_server_struc{a=1, b=2})),
+ ?match({'EXCEPTION',{'MARSHAL',_,_,_}},
+ orber_test_server:testing_iiop_struct(Obj,
+ #orber_test_server_struc{a="WRONG", b=2})),
+ ?match({ok,#orber_test_server_uni{label=1, value=66}},
+ orber_test_server:testing_iiop_union(Obj,
+ #orber_test_server_uni{label=1, value=66})),
+
+ ?match({ok,#orber_test_server_uni_d{label=1, value=66}},
+ orber_test_server:testing_iiop_union_d(Obj,
+ #orber_test_server_uni_d{label=1, value=66})),
+
+ ?match({ok,#orber_test_server_uni_d{label=2, value=true}},
+ orber_test_server:testing_iiop_union_d(Obj,
+ #orber_test_server_uni_d{label=2, value=true})),
+
+ ?match({'EXCEPTION',{'MARSHAL',_,_,_}},
+ orber_test_server:testing_iiop_union_d(Obj,
+ #orber_test_server_uni_d{label=2, value=66})),
+
+ case Local of
+ true ->
+ ?match({ok,#orber_test_server_uni{label=2, value=66}},
+ orber_test_server:testing_iiop_union(Obj,
+ #orber_test_server_uni{label=2, value=66}));
+ false ->
+ ?match({ok,#orber_test_server_uni{label=2, value=undefined}},
+ orber_test_server:testing_iiop_union(Obj,
+ #orber_test_server_uni{label=2, value=66}))
+ end,
+
+ C1 = orber_test_server:fixed52const1(),
+ C2 = orber_test_server:fixed52const2(),
+ C3 = orber_test_server:fixed52const3(),
+
+ C4 = orber_test_server:fixed52negconst1(),
+ C5 = orber_test_server:fixed52negconst2(),
+ C6 = orber_test_server:fixed52negconst3(),
+
+ ?match({ok,C1}, orber_test_server:testing_iiop_fixed(Obj, C1)),
+ ?match({ok,C2}, orber_test_server:testing_iiop_fixed(Obj, C2)),
+ ?match({ok,C3}, orber_test_server:testing_iiop_fixed(Obj, C3)),
+ ?match({ok,C4}, orber_test_server:testing_iiop_fixed(Obj, C4)),
+ ?match({ok,C5}, orber_test_server:testing_iiop_fixed(Obj, C5)),
+ ?match({ok,C6}, orber_test_server:testing_iiop_fixed(Obj, C6)),
+ ?match({'EXCEPTION',{'MARSHAL',_,_,_}},
+ orber_test_server:testing_iiop_fixed(Obj, #fixed{digits = 5,
+ scale = 2,
+ value = 123450})),
+
+ ?match(ok, orber_test_server:testing_iiop_void(Obj)),
+
+ ?match({'EXCEPTION',{'BAD_QOS',_,_,_}},
+ orber_test_server:pseudo_call_raise_exc(Obj, 1)),
+ ?match({'EXCEPTION',{'BAD_QOS',_,_,_}},
+ orber_test_server:pseudo_call_raise_exc(Obj, 2)),
+ ?match({'EXCEPTION',{'orber_test_server_UserDefinedException',_}},
+ orber_test_server:raise_local_exception(Obj)),
+ ?match({'EXCEPTION',{'orber_test_server_ComplexUserDefinedException',_,
+ [#orber_test_server_struc{a=1, b=2}]}},
+ orber_test_server:raise_complex_local_exception(Obj)),
+ %% Test all TypeCodes
+ ?match({ok, #any{typecode = tk_long, value = 1}},
+ orber_test_server:testing_iiop_any(Obj, #any{typecode = tk_long,
+ value = 1})),
+ ?match({'EXCEPTION',{'MARSHAL',_,_,_}},
+ orber_test_server:testing_iiop_any(Obj, #any{typecode = tk_long,
+ value = "wrong"})),
+ ?match({ok, #any{typecode = tk_float, value = 1.5}},
+ orber_test_server:testing_iiop_any(Obj, #any{typecode = tk_float,
+ value = 1.5})),
+ ?match({'EXCEPTION',{'MARSHAL',_,_,_}},
+ orber_test_server:testing_iiop_any(Obj, #any{typecode = tk_long,
+ value = "wrong"})),
+ ?match({ok, #any{typecode = tk_double}},
+ orber_test_server:testing_iiop_any(Obj, #any{typecode = tk_double,
+ value = 1.0})),
+ ?match({'EXCEPTION',{'MARSHAL',_,_,_}},
+ orber_test_server:testing_iiop_any(Obj, #any{typecode = tk_double,
+ value = "wrong"})),
+ ?match({ok, #any{typecode = tk_short, value = -1}},
+ orber_test_server:testing_iiop_any(Obj, #any{typecode = tk_short,
+ value = -1})),
+ ?match({'EXCEPTION',{'MARSHAL',_,_,_}},
+ orber_test_server:testing_iiop_any(Obj, #any{typecode = tk_short,
+ value = atomic})),
+ ?match({ok, #any{typecode = tk_ushort, value = 1}},
+ orber_test_server:testing_iiop_any(Obj, #any{typecode = tk_ushort,
+ value = 1})),
+ ?match({'EXCEPTION',{'MARSHAL',_,_,_}},
+ orber_test_server:testing_iiop_any(Obj, #any{typecode = tk_ushort,
+ value = -1})),
+ ?match({ok, #any{typecode = tk_long, value = 1}},
+ orber_test_server:testing_iiop_any(Obj, #any{typecode = tk_long,
+ value = 1})),
+ ?match({'EXCEPTION',{'MARSHAL',_,_,_}},
+ orber_test_server:testing_iiop_any(Obj, #any{typecode = tk_long,
+ value = "wrong"})),
+ ?match({ok, #any{typecode = tk_longlong, value = 1}},
+ orber_test_server:testing_iiop_any(Obj, #any{typecode = tk_longlong,
+ value = 1})),
+ ?match({'EXCEPTION',{'MARSHAL',_,_,_}},
+ orber_test_server:testing_iiop_any(Obj, #any{typecode = tk_longlong,
+ value = "wrong"})),
+ ?match({ok, #any{typecode = tk_ulong, value = 1}},
+ orber_test_server:testing_iiop_any(Obj, #any{typecode = tk_ulong,
+ value = 1})),
+ ?match({ok, #any{typecode = tk_ulong, value = 4294967295}},
+ orber_test_server:testing_iiop_any(Obj, #any{typecode = tk_ulong,
+ value = 4294967295})),
+ ?match({'EXCEPTION',{'MARSHAL',_,_,_}},
+ orber_test_server:testing_iiop_any(Obj, #any{typecode = tk_ulong,
+ value = 4294967296})),
+ ?match({'EXCEPTION',{'MARSHAL',_,_,_}},
+ orber_test_server:testing_iiop_any(Obj, #any{typecode = tk_ulong,
+ value = -1})),
+ ?match({ok, #any{typecode = tk_ulonglong, value = 1}},
+ orber_test_server:testing_iiop_any(Obj, #any{typecode = tk_ulonglong,
+ value = 1})),
+ ?match({'EXCEPTION',{'MARSHAL',_,_,_}},
+ orber_test_server:testing_iiop_any(Obj, #any{typecode = tk_ulonglong,
+ value = -1})),
+ ?match({ok, #any{typecode = tk_char, value = 98}},
+ orber_test_server:testing_iiop_any(Obj, #any{typecode = tk_char,
+ value = 98})),
+ ?match({ok, #any{typecode = tk_char, value = $b}},
+ orber_test_server:testing_iiop_any(Obj, #any{typecode = tk_char,
+ value = $b})),
+ ?match({'EXCEPTION',{'MARSHAL',_,_,_}},
+ orber_test_server:testing_iiop_any(Obj, #any{typecode = tk_char,
+ value = atomic})),
+ ?match({ok, #any{typecode = tk_wchar, value = 65535}},
+ orber_test_server:testing_iiop_any(Obj, #any{typecode = tk_wchar,
+ value = 65535})),
+ ?match({ok, #any{typecode = tk_wchar, value = $b}},
+ orber_test_server:testing_iiop_any(Obj, #any{typecode = tk_wchar,
+ value = $b})),
+ ?match({'EXCEPTION',{'MARSHAL',_,_,_}},
+ orber_test_server:testing_iiop_any(Obj, #any{typecode = tk_wchar,
+ value = atomic})),
+ ?match({ok, #any{typecode = tk_boolean, value = true}},
+ orber_test_server:testing_iiop_any(Obj, #any{typecode = tk_boolean,
+ value = true})),
+ ?match({ok, #any{typecode = tk_boolean, value = false}},
+ orber_test_server:testing_iiop_any(Obj, #any{typecode = tk_boolean,
+ value = false})),
+ ?match({'EXCEPTION',{'MARSHAL',_,_,_}},
+ orber_test_server:testing_iiop_any(Obj, #any{typecode = tk_boolean,
+ value = 1})),
+ ?match({ok, #any{typecode = tk_octet, value = 1}},
+ orber_test_server:testing_iiop_any(Obj, #any{typecode = tk_octet,
+ value = 1})),
+ ?match({ok, #any{typecode = {tk_objref, "IDL:omg.org/orber_test/server:1.0", "server"}, value = Obj}},
+ orber_test_server:testing_iiop_any(Obj, #any{typecode = {tk_objref, "IDL:omg.org/orber_test/server:1.0", "server"},
+ value = Obj})),
+ ?match({'EXCEPTION',{'MARSHAL',_,_,_}},
+ orber_test_server:testing_iiop_any(Obj, #any{typecode = {tk_objref, "IDL:omg.org/orber_test/server:1.0", "server"},
+ value = "No Object"})),
+ ?match({ok, #any{typecode = {tk_string, 6}, value = "string"}},
+ orber_test_server:testing_iiop_any(Obj, #any{typecode = {tk_string, 6},
+ value = "string"})),
+ ?match({'EXCEPTION',{'MARSHAL',_,_,_}},
+ orber_test_server:testing_iiop_any(Obj, #any{typecode = tk_string,
+ value = atomic})),
+ ?match({ok, #any{typecode = {tk_wstring, 1}, value = [65535]}},
+ orber_test_server:testing_iiop_any(Obj, #any{typecode = {tk_wstring, 1},
+ value = [65535]})),
+ ?match({'EXCEPTION',{'MARSHAL',_,_,_}},
+ orber_test_server:testing_iiop_any(Obj, #any{typecode = {tk_wstring, 1},
+ value = atomic})),
+ ?match({ok, #any{typecode = {tk_enum, "IDL:omg.org/orber_test/server/enumerant:1.0", "enumerant", ["one","two"]},
+ value = two}},
+ orber_test_server:testing_iiop_any(Obj, #any{typecode = {tk_enum, "IDL:omg.org/orber_test/server/enumerant:1.0", "enumerant", ["one","two"]},
+ value = two})),
+ ?match({'EXCEPTION',{'MARSHAL',_,_,_}},
+ orber_test_server:testing_iiop_any(Obj, #any{typecode = {tk_enum, "IDL:omg.org/orber_test/server/enumerant:1.0", "enumerant", ["one","two"]},
+ value = three})),
+
+
+ ?match({ok, #any{typecode = {tk_sequence, tk_long, 3},
+ value = [1,2,3]}},
+ orber_test_server:testing_iiop_any(Obj, #any{typecode = {tk_sequence, tk_long, 3},
+ value = [1,2,3]})),
+ ?match({'EXCEPTION',{'MARSHAL',_,_,_}},
+ orber_test_server:testing_iiop_any(Obj, #any{typecode = {tk_sequence, tk_long, 3},
+ value = false})),
+
+
+
+ ?match({ok, #any{typecode = {tk_array,{tk_string,0},2},
+ value = {"one", "two"}}},
+ orber_test_server:testing_iiop_any(Obj, #any{typecode = {tk_array,{tk_string,0},2},
+ value = {"one", "two"}})),
+ ?match({'EXCEPTION',{'MARSHAL',_,_,_}},
+ orber_test_server:testing_iiop_any(Obj, #any{typecode = {tk_array,{tk_string,0},2},
+ value = {"one", "two", "three"}})),
+ ?match({'EXCEPTION',{'MARSHAL',_,_,_}},
+ orber_test_server:testing_iiop_any(Obj, #any{typecode = {tk_array,{tk_string,0},2},
+ value = {1, 2}})),
+ ?match({ok, #any{typecode = {tk_struct,"IDL:omg.org/orber_test/server/struc:1.0",
+ "struc",
+ [{"a",tk_long},{"b",tk_short}]},
+ value = #orber_test_server_struc{a=1, b=2}}},
+ orber_test_server:testing_iiop_any(Obj, #any{typecode = {tk_struct,"IDL:omg.org/orber_test/server/struc:1.0",
+ "struc",
+ [{"a",tk_long},{"b",tk_short}]},
+ value = #orber_test_server_struc{a=1, b=2}})),
+ ?match({'EXCEPTION',{'MARSHAL',_,_,_}},
+ orber_test_server:testing_iiop_any(Obj, #any{typecode = {tk_struct,"IDL:omg.org/orber_test/server/struc:1.0",
+ "struc",
+ [{"a",tk_long},{"b",tk_short}]},
+ value = #orber_test_server_struc{a=1, b="string"}})),
+ ?match({ok, #any{typecode =
+ {tk_union,"IDL:omg.org/orber_test/server/uni:1.0",
+ "uni", tk_long, -1, [{1,"a",tk_long}]},
+ value = #orber_test_server_uni{label=1, value=66}}},
+ orber_test_server:
+ testing_iiop_any(Obj,
+ #any{typecode =
+ {tk_union,"IDL:omg.org/orber_test/server/uni:1.0",
+ "uni", tk_long, -1, [{1,"a",tk_long}]},
+ value = #orber_test_server_uni{label=1, value=66}})),
+ case Local of
+ true ->
+ ?match({ok, #any{typecode =
+ {tk_union,"IDL:omg.org/orber_test/server/uni:1.0",
+ "uni", tk_long, -1, [{1,"a",tk_long}]},
+ value = #orber_test_server_uni{label=2, value=66}}},
+ orber_test_server:
+ testing_iiop_any(Obj,
+ #any{typecode =
+ {tk_union,"IDL:omg.org/orber_test/server/uni:1.0",
+ "uni", tk_long, -1, [{1,"a",tk_long}]},
+ value = #orber_test_server_uni{label=2, value=66}}));
+ false ->
+ ?match({ok, #any{typecode =
+ {tk_union,"IDL:omg.org/orber_test/server/uni:1.0",
+ "uni", tk_long, -1, [{1,"a",tk_long}]},
+ value = #orber_test_server_uni{label=2, value=undefined}}},
+ orber_test_server:
+ testing_iiop_any(Obj,
+ #any{typecode =
+ {tk_union,"IDL:omg.org/orber_test/server/uni:1.0",
+ "uni", tk_long, -1, [{1,"a",tk_long}]},
+ value = #orber_test_server_uni{label=2, value=66}}))
+ end,
+ ?match({'EXCEPTION',{'MARSHAL',_,_,_}},
+ orber_test_server:
+ testing_iiop_any(Obj,
+ #any{typecode =
+ {tk_union,"IDL:omg.org/orber_test/server/uni:1.0",
+ "uni", tk_long, -1, [{1,"a",tk_long}]},
+ value = #orber_test_server_uni{label=1, value="string"}})),
+
+ ?match({ok, #any{typecode = {tk_fixed,5,2},
+ value = #fixed{digits = 5, scale = 2, value = 12345}}},
+ orber_test_server:testing_iiop_any(Obj, #any{typecode = {tk_fixed,5,2},
+ value = #fixed{digits = 5,
+ scale = 2,
+ value = 12345}})),
+ ?match({ok, #any{typecode = {tk_fixed,10,2},
+ value = #fixed{digits = 10, scale = 2, value = 1234567890}}},
+ orber_test_server:testing_iiop_any(Obj, #any{typecode = {tk_fixed,10,2},
+ value = #fixed{digits = 10,
+ scale = 2,
+ value = 1234567890}})),
+ ?match({ok, #any{typecode = {tk_fixed,6,2},
+ value = #fixed{digits = 6, scale = 2, value = 300000}}},
+ orber_test_server:testing_iiop_any(Obj, #any{typecode = {tk_fixed,6,2},
+ value = #fixed{digits = 6,
+ scale = 2,
+ value = 300000}})),
+ ?match({'EXCEPTION',{'MARSHAL',_,_,_}},
+ orber_test_server:
+ testing_iiop_server_marshal(Obj, "string")),
+
+ RecS = #orber_test_server_rec_struct{chain = [#orber_test_server_rec_struct{chain = []}]},
+ ?match(RecS, orber_test_server:testing_iiop_rec_struct(Obj, RecS)),
+
+ RecU = #orber_test_server_rec_union{label = 'RecursiveType',
+ value = [#orber_test_server_rec_union{label = 'RecursiveType',
+ value = []}]},
+ ?match(RecU, orber_test_server:testing_iiop_rec_union(Obj, RecU)),
+
+%% RecA1 = #any{typecode = unsupported, value = RecS},
+%% RecA2 = #any{typecode = unsupported, value = RecU},
+%% ?match(RecA1,
+%% orber_test_server:testing_iiop_rec_any(Obj, RecA1)),
+%% ?match(RecA2,
+%% orber_test_server:testing_iiop_rec_any(Obj, RecA2)),
+
+ ok.
+
+%%--------------- Testing Post- & Pre-cond -------------------
+precond(Module, Function, Args) ->
+ error_logger:info_msg("=============== pre-condition ============
+Module : ~p
+Function : ~p
+Arguments : ~p
+==========================================~n", [Module, Function, Args]),
+ ok.
+
+postcond(Module, Function, Args, Result) ->
+ error_logger:info_msg("=============== post-condition ===========
+Module : ~p
+Function : ~p
+Arguments : ~p
+Result : ~p
+==========================================~n", [Module, Function, Args, Result]),
+ ok.
+
+%%--------------- Testing Missing Module ---------------------
+oe_get_interface() ->
+ non_existing_module:tc(foo).
+
+%%--------------- INTERCEPTOR FUNCTIONS ----------------------
+%%------------------------------------------------------------
+%% function : new_in_connection
+%% Arguments:
+%% Returns :
+%%------------------------------------------------------------
+new_in_connection(Arg, CHost, Port) ->
+ Host = node(),
+ [{SHost, SPort}] = orber:find_sockname_by_peername(CHost, Port),
+ Peers = orber:find_peername_by_sockname(SHost, SPort),
+ error_logger:info_msg("=============== new_in_connection ========
+Node : ~p
+From Host : ~p
+From Port : ~p
+To Host : ~p
+To Port : ~p
+Peers : ~p
+Arg : ~p
+==========================================~n",
+ [Host, CHost, Port, SHost, SPort, Peers, Arg]),
+ {Host}.
+
+%%------------------------------------------------------------
+%% function : new_out_connection
+%% Arguments:
+%% Returns :
+%%------------------------------------------------------------
+new_out_connection(Arg, SHost, Port) ->
+ Host = node(),
+ error_logger:info_msg("=============== new_out_connection =======
+Node : ~p
+To Host : ~p
+To Port : ~p
+Arg : ~p
+==========================================~n",
+ [Host, SHost, Port, Arg]),
+ {Host}.
+
+%%------------------------------------------------------------
+%% function : closed_in_connection
+%% Arguments:
+%% Returns :
+%%------------------------------------------------------------
+closed_in_connection(Arg) ->
+ error_logger:info_msg("=============== closed_in_connection =====
+Node : ~p
+Connection: ~p
+==========================================~n",
+ [node(), Arg]),
+ Arg.
+
+%%------------------------------------------------------------
+%% function : closed_out_connection
+%% Arguments:
+%% Returns :
+%%------------------------------------------------------------
+closed_out_connection(Arg) ->
+ error_logger:info_msg("=============== closed_out_connection ====
+Node : ~p
+Connection: ~p
+==========================================~n",
+ [node(), Arg]),
+ Arg.
+
+%%------------------------------------------------------------
+%% function : in_request_encoded
+%% Arguments:
+%% Returns :
+%%------------------------------------------------------------
+in_request_encoded(Ref, _ObjKey, Ctx, Op,
+ <<100:8,101:8,102:8,103:8,104:8,105:8,106:8,107:8,108:8,109:8,110:8,T/binary>>, _Args) ->
+ error_logger:info_msg("=============== in_request_encoded =======
+Connection: ~p
+Operation : ~p
+Body : ~p
+Context : ~p
+==========================================~n",
+ [Ref, Op, T, Ctx]),
+ {T, "NewArgs"}.
+
+%%------------------------------------------------------------
+%% function : in_reply_encoded
+%% Arguments:
+%% Returns :
+%%------------------------------------------------------------
+in_reply_encoded(Ref, _ObjKey, Ctx, Op,
+ <<100:8,101:8,102:8,103:8,104:8,105:8,106:8,107:8,108:8,109:8,110:8,T/binary>>,
+ _Args) ->
+ error_logger:info_msg("============== in_reply_encoded ==========
+Connection: ~p
+Operation : ~p
+Body : ~p
+Context : ~p
+==========================================~n",
+ [Ref, Op, T, Ctx]),
+ {T, "NewArgs"}.
+
+%%------------------------------------------------------------
+%% function : out_reply_encoded
+%% Arguments:
+%% Returns :
+%%------------------------------------------------------------
+out_reply_encoded(Ref, _ObjKey, Ctx, Op, List, _Args) ->
+ error_logger:info_msg("============== out_reply_encoded =========
+Connection: ~p
+Operation : ~p
+Body : ~p
+Context : ~p
+==========================================~n",
+ [Ref, Op, List, Ctx]),
+ {list_to_binary([<<100:8,101:8,102:8,103:8,104:8,105:8,106:8,107:8,108:8,109:8,110:8>>|List]), "NewArgs"}.
+
+%%------------------------------------------------------------
+%% function : out_request_encoded
+%% Arguments:
+%% Returns :
+%%------------------------------------------------------------
+out_request_encoded(Ref, _ObjKey, Ctx, Op, List, _Args) ->
+ error_logger:info_msg("============== out_request_encoded =======
+Connection: ~p
+Operation : ~p
+Body : ~p
+Context : ~p
+==========================================~n",
+ [Ref, Op, List, Ctx]),
+ {list_to_binary([<<100:8,101:8,102:8,103:8,104:8,105:8,106:8,107:8,108:8,109:8,110:8>>|List]), "NewArgs"}.
+
+%%------------------------------------------------------------
+%% function : in_request
+%% Arguments:
+%% Returns :
+%%------------------------------------------------------------
+in_request(Ref, _ObjKey, Ctx, Op, Params, _Args) ->
+ error_logger:info_msg("=============== in_request ===============
+Connection: ~p
+Operation : ~p
+Parameters: ~p
+Context : ~p
+==========================================~n",
+ [Ref, Op, Params, Ctx]),
+ {Params, "NewArgs"}.
+
+%%------------------------------------------------------------
+%% function : in_reply
+%% Arguments:
+%% Returns :
+%%------------------------------------------------------------
+in_reply(Ref, _ObjKey, Ctx, Op, Reply, _Args) ->
+ error_logger:info_msg("=============== in_reply =================
+Connection: ~p
+Operation : ~p
+Reply : ~p
+Context : ~p
+==========================================~n",
+ [Ref, Op, Reply, Ctx]),
+ {Reply, "NewArgs"}.
+
+%%------------------------------------------------------------
+%% function : postinvoke
+%% Arguments:
+%% Returns :
+%%------------------------------------------------------------
+out_reply(Ref, _ObjKey, Ctx, Op, Reply, _Args) ->
+ error_logger:info_msg("=============== out_reply ================
+Connection: ~p
+Operation : ~p
+Reply : ~p
+Context : ~p
+==========================================~n",
+ [Ref, Op, Reply, Ctx]),
+ {Reply, "NewArgs"}.
+
+%%------------------------------------------------------------
+%% function : postinvoke
+%% Arguments:
+%% Returns :
+%%------------------------------------------------------------
+out_request(Ref, _ObjKey, Ctx, Op, Params, _Args) ->
+ error_logger:info_msg("=============== out_request ==============
+Connection: ~p
+Operation : ~p
+Parameters: ~p
+Context : ~p
+==========================================~n",
+ [Ref, Op, Params, Ctx]),
+ {Params, "NewArgs"}.
+
+
+%%--------------- END OF MODULE ------------------------------
+
+
+
diff --git a/lib/orber/test/orber_test_server.cfg b/lib/orber/test/orber_test_server.cfg
new file mode 100644
index 0000000000..84c671f795
--- /dev/null
+++ b/lib/orber/test/orber_test_server.cfg
@@ -0,0 +1,27 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 1999-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%
+%%
+{timeout, "orber_test::timeout_server"}.
+{this, "orber_test::timeout_server"}.
+{{handle_info, "orber_test::timeout_server"}, true}.
+{this, "orber_test::server"}.
+{{handle_info, "orber_test::server"}, true}.
+{{postcond, "orber_test::server::testing_iiop_union_d"}, {orber_test_lib, postcond}}.
+{{postcond, "orber_test::server::testing_iiop_array"}, {orber_test_lib, postcond}}.
+{{precond, "orber_test::server::testing_iiop_array"}, {orber_test_lib, precond}}.
+{{precond, "orber_test::server::testing_iiop_enum"}, {orber_test_lib, precond}}.
diff --git a/lib/orber/test/orber_test_server.idl b/lib/orber/test/orber_test_server.idl
new file mode 100644
index 0000000000..438c10e19b
--- /dev/null
+++ b/lib/orber/test/orber_test_server.idl
@@ -0,0 +1,176 @@
+//
+// %CopyrightBegin%
+//
+// Copyright Ericsson AB 1999-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%
+//
+
+#ifndef _ORBER_TEST_SERVER_IDL
+#define _ORBER_TEST_SERVER_IDL
+#pragma prefix "omg.org"
+
+module orber_parent {
+ interface inherrit {
+ void print();
+ };
+};
+
+module orber_test {
+
+ // interface server
+ interface server : orber_parent::inherrit {
+ typedef string array[2];
+ typedef sequence <long, 3> seq;
+ typedef wstring<6> WstrLength6;
+ typedef string<6> StrLength6;
+
+ struct struc {long a; short b;};
+ union uni switch(long) {
+ case 1: long a;};
+
+ union uni_d switch(long) {
+ case 1: long a;
+ default: boolean b;
+ };
+ enum enumerant {one, two};
+
+ exception UserDefinedException {};
+
+ typedef sequence<struc> StrucSeq;
+ typedef sequence<uni> UniSeq;
+ exception ComplexUserDefinedException { StrucSeq strseq; };
+
+ // Testing fixed
+ const fixed val1 = 3.14D;
+ const fixed val2 = 003.14D;
+ const fixed val3 = 003.1400D;
+ const fixed val4 = 3.1400D;
+ const fixed val5 = .1400D;
+ const fixed val6 = 3.D;
+ const fixed val7 = -.1400D;
+ const fixed val8 = -3.D;
+ const fixed val9 = val4+val5;
+ const fixed val10 = val4*val5;
+ const fixed val11 = val4/val5;
+ const fixed val12 = 123.140001D;
+ const fixed val13 = 12314000.1D;
+ const fixed val14 = val12-val13;
+ const fixed val15 = val12+val13;
+ const fixed val16 = val12*val13;
+ const fixed val17 = 2.01D+2.01D;
+ const fixed val18 = 2.01D*2.01D;
+ const fixed val19 = 200D;
+ const fixed val20 = 9999999999999999999999999999999D+9999999999999999999999999999999D;
+ const fixed val21 = 9999999999999999999999999999999D-9999999999999999999999999999999D;
+ const fixed val22 = 9999999999999999999999999999999D*9999999999999999999999999999999D;
+ const fixed val23 = 9999999999999999999999999999999D/9999999999999999999999999999999D;
+ const fixed val24 = 9999D+9999D;
+ const fixed val25 = 400D/10D;
+ const fixed val26 = 9999999999999999999999999999999D;
+
+
+ typedef fixed<5,2> fixed52;
+ const fixed52 fixed52const1 = 123.45d;
+ const fixed52 fixed52const2 = 123.00d;
+ const fixed52 fixed52const3 = 023.00d;
+ const fixed52 fixed52negconst1 = -123.45d;
+ const fixed52 fixed52negconst2 = -123.00d;
+ const fixed52 fixed52negconst3 = -023.00d;
+
+ struct rec_struct; // Forward declaration
+ typedef sequence<rec_struct> rec_struct_seq;
+ struct rec_struct {
+ rec_struct_seq chain;
+ };
+
+
+ union rec_union; // Forward declaration
+ typedef sequence<rec_union>rec_union_seq;
+
+ enum MyEnum {RecursiveType, NameType};
+
+ union rec_union switch (MyEnum) {
+ case RecursiveType : rec_union_seq chain;
+ case NameType : string aName;
+ };
+
+ void stop_normal();
+
+ void stop_brutal();
+
+ // Testing encode and decode
+ void testing_iiop_float(inout float Fl);
+ void testing_iiop_double(inout double Do);
+ void testing_iiop_short(inout short Sh);
+ void testing_iiop_ushort(inout unsigned short Us);
+ void testing_iiop_long(inout long Lo);
+ void testing_iiop_longlong(inout long long LLo);
+ void testing_iiop_ulong(inout unsigned long Ulo);
+ void testing_iiop_ulonglong(inout unsigned long long LLo);
+ void testing_iiop_char(inout char Ch);
+ void testing_iiop_wchar(inout wchar WCh);
+ void testing_iiop_bool(inout boolean Bool);
+ void testing_iiop_octet(inout octet Oct);
+ void testing_iiop_any(inout any AnyType);
+ void testing_iiop_obj(inout Object Obj);
+ void testing_iiop_string(inout StrLength6 Str);
+ void testing_iiop_wstring(inout WstrLength6 WStr);
+ void testing_iiop_struct(inout struc Stru);
+ void testing_iiop_union(inout uni Uni);
+ void testing_iiop_union_d(inout uni_d Uni);
+ void testing_iiop_enum(inout enumerant Enumerant);
+ void testing_iiop_seq(inout seq Seq);
+ void testing_iiop_uni_seq(inout UniSeq USeq);
+ void testing_iiop_struc_seq(inout StrucSeq SSeq);
+ void testing_iiop_array(inout array Arr);
+ void testing_iiop_fixed(inout fixed52 MyFixed);
+ void testing_iiop_void();
+ void testing_iiop_context();
+ void testing_iiop_server_marshal(inout StrLength6 Str);
+
+ // Recursive types
+ any testing_iiop_rec_any(in any RecType);
+ rec_struct testing_iiop_rec_struct(in rec_struct RecS);
+ rec_union testing_iiop_rec_union(in rec_union RecU);
+
+
+ oneway void testing_iiop_oneway_delay(in long Time);
+ void testing_iiop_twoway_delay(in long Time);
+
+ // Testing relay calls/casts to, for example, test that sending implicit
+ // Contexts works.
+ void relay_call(in Object Target);
+ oneway void relay_cast(in Object Target);
+
+ // Testing pseudo calls/casts
+ void pseudo_call();
+ oneway void pseudo_cast();
+ void pseudo_call_delay(inout long Lo);
+ oneway void pseudo_cast_delay(in long Lo);
+ void pseudo_call_raise_exc(in long Lo);
+ void raise_local_exception()
+ raises(UserDefinedException);
+ void raise_complex_local_exception()
+ raises(ComplexUserDefinedException);
+ };
+
+ interface timeout_server {
+ oneway void oneway_function(in long time);
+ void twoway_function(in long time);
+ };
+
+};
+
+#endif
diff --git a/lib/orber/test/orber_test_server_impl.erl b/lib/orber/test/orber_test_server_impl.erl
new file mode 100644
index 0000000000..10a9caf242
--- /dev/null
+++ b/lib/orber/test/orber_test_server_impl.erl
@@ -0,0 +1,275 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 1999-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(orber_test_server_impl).
+-include_lib("orber/include/corba.hrl").
+-include("idl_output/orber_test_server.hrl").
+
+%%--------------- specified functions ------------------------
+-export([stop_normal/2,
+ stop_brutal/2,
+ print/2,
+ %% Testing code and decode arguments
+ testing_iiop_float/3,
+ testing_iiop_double/3,
+ testing_iiop_short/3,
+ testing_iiop_ushort/3,
+ testing_iiop_long/3,
+ testing_iiop_longlong/3,
+ testing_iiop_ulong/3,
+ testing_iiop_ulonglong/3,
+ testing_iiop_char/3,
+ testing_iiop_wchar/3,
+ testing_iiop_bool/3,
+ testing_iiop_octet/3,
+ testing_iiop_any/3,
+ testing_iiop_obj/3,
+ testing_iiop_string/3,
+ testing_iiop_wstring/3,
+ testing_iiop_struct/3,
+ testing_iiop_union/3,
+ testing_iiop_union_d/3,
+ testing_iiop_enum/3,
+ testing_iiop_seq/3,
+ testing_iiop_uni_seq/3,
+ testing_iiop_struc_seq/3,
+ testing_iiop_array/3,
+ testing_iiop_fixed/3,
+ testing_iiop_void/2,
+ testing_iiop_context/2,
+ testing_iiop_server_marshal/3,
+ testing_iiop_rec_any/3,
+ testing_iiop_rec_struct/3,
+ testing_iiop_rec_union/3,
+ relay_call/3,
+ relay_cast/3,
+ %% Testing pseudo calls.
+ pseudo_call/2,
+ pseudo_cast/2,
+ pseudo_call_delay/3,
+ pseudo_cast_delay/3,
+ pseudo_call_raise_exc/3,
+ %% Testing raise locally defined exception.
+ raise_local_exception/2,
+ raise_complex_local_exception/2,
+ %% Test timeout functionality
+ testing_iiop_oneway_delay/3,
+ testing_iiop_twoway_delay/3]).
+
+
+%%--------------- gen_server specific ------------------------
+-export([init/1, terminate/2]).
+-export([handle_call/3, handle_cast/2, handle_info/2, code_change/3]).
+
+%%--------------- LOCAL DATA ---------------------------------
+
+%%------------------------------------------------------------
+%% function : init, terminate
+%%------------------------------------------------------------
+init(State) ->
+ process_flag(trap_exit,true),
+ {ok, State}.
+
+terminate(Reason, State) ->
+ io:format("orber_test_server:terminate(~p ~p)~n",[Reason, State]),
+ ok.
+
+code_change(_OldVsn, State, _Extra) ->
+ {ok, State}.
+handle_call(_,_, State) ->
+ {noreply, State}.
+handle_cast(_, State) ->
+ {noreply, State}.
+handle_info(_Info, State) ->
+ {noreply, State}.
+
+%%--------------- SERVER FUNCTIONS ---------------------------
+
+print(Self, State) ->
+ io:format("orber_test_server:print(~p ~p)~n",[Self, State]),
+ {reply, ok, State}.
+
+stop_normal(_Self, State) ->
+ {stop, normal, ok, State}.
+
+stop_brutal(_Self, _State) ->
+ exit("killed_brutal").
+
+
+%% Testing code and decode arguments
+testing_iiop_float(_Self, State, Float) ->
+ {reply, {ok, Float}, State}.
+
+testing_iiop_double(_Self, State, Double) ->
+ {reply, {ok, Double}, State}.
+
+testing_iiop_short(_Self, State, Short) ->
+ {reply, {ok, Short}, State}.
+
+testing_iiop_ushort(_Self, State, Ushort) ->
+ {reply, {ok, Ushort}, State}.
+
+testing_iiop_long(_Self, State, Long) ->
+ {reply, {ok, Long}, State}.
+
+testing_iiop_longlong(_Self, State, LLong) ->
+ {reply, {ok, LLong}, State}.
+
+testing_iiop_ulong(_Self, State, Ulong) ->
+ {reply, {ok, Ulong}, State}.
+
+testing_iiop_ulonglong(_Self, State, ULlong) ->
+ {reply, {ok, ULlong}, State}.
+
+testing_iiop_char(_Self, State, Char) ->
+ {reply, {ok, Char}, State}.
+
+testing_iiop_wchar(_Self, State, WChar) ->
+ {reply, {ok, WChar}, State}.
+
+testing_iiop_bool(_Self, State, Boolean) ->
+ {reply, {ok, Boolean}, State}.
+
+testing_iiop_octet(_Self, State, Octet) ->
+ {reply, {ok, Octet}, State}.
+
+testing_iiop_any(_Self, State, Any) ->
+ {reply, {ok, Any}, State}.
+
+testing_iiop_obj(_Self, State, Obj) ->
+ {reply, {ok, Obj}, State}.
+
+testing_iiop_string(_Self, State, String) ->
+ {reply, {ok, String}, State}.
+
+testing_iiop_wstring(_Self, State, WString) ->
+ {reply, {ok, WString}, State}.
+
+testing_iiop_struct(_Self, State, Struct) ->
+ {reply, {ok, Struct}, State}.
+
+testing_iiop_union(_Self, State, Union) ->
+ {reply, {ok, Union}, State}.
+
+testing_iiop_union_d(_Self, State, Union) ->
+ {reply, {ok, Union}, State}.
+
+testing_iiop_enum(_Self, State, Enum) ->
+ {reply, {ok, Enum}, State}.
+
+testing_iiop_seq(_Self, State, Sequence) ->
+ {reply, {ok, Sequence}, State}.
+
+testing_iiop_uni_seq(_Self, State, Sequence) ->
+ {reply, {ok, Sequence}, State}.
+
+testing_iiop_struc_seq(_Self, State, Sequence) ->
+ {reply, {ok, Sequence}, State}.
+
+testing_iiop_array(_Self, State, Array) ->
+ {reply, {ok, Array}, State}.
+
+testing_iiop_fixed(_Self, State, Fixed) ->
+ {reply, {ok, Fixed}, State}.
+
+testing_iiop_void(_Self, State) ->
+ {reply, ok, State}.
+
+testing_iiop_context(_Self, State) ->
+ Ctx = get(oe_server_in_context),
+ io:format("orber_test_server:testing_iiop_context( ~p )~n", [Ctx]),
+ {reply, ok, State}.
+
+testing_iiop_server_marshal(_Self, State, _String) ->
+ {reply, {ok, false}, State}.
+
+testing_iiop_rec_any(_Self, State, RAny) ->
+ {reply, RAny, State}.
+
+testing_iiop_rec_struct(_Self, State, RecS) ->
+ {reply, RecS, State}.
+
+testing_iiop_rec_union(_Self, State, RecU) ->
+ {reply, RecU, State}.
+
+
+testing_iiop_oneway_delay(_Self, State, Time) ->
+ timer:sleep(Time),
+ {noreply, State}.
+
+testing_iiop_twoway_delay(_Self, State, Time) ->
+ timer:sleep(Time),
+ {reply, ok, State}.
+
+raise_local_exception(_Self, State) ->
+ corba:raise(#'orber_test_server_UserDefinedException'{}),
+ {reply, ok, State}.
+
+raise_complex_local_exception(_Self, State) ->
+ corba:raise(#'orber_test_server_ComplexUserDefinedException'{strseq=
+ [#orber_test_server_struc{a=1, b=2}]}),
+ {reply, ok, State}.
+
+%% Testing relay calls/casts to, for example, test that sending implicit
+%% Contexts works.
+relay_call(_Self, State, Target) ->
+ io:format("orber_test_server:relay_call( ~p ) Pre~n", [get(oe_server_in_context)]),
+ orber_test_server:testing_iiop_context(Target),
+ io:format("orber_test_server:relay_call( ~p ) Post~n", [get(oe_server_in_context)]),
+ {reply, ok, State}.
+
+relay_cast(_Self, State, Target) ->
+ io:format("orber_test_server:relay_cast( ~p ) Pre~n", [get(oe_server_in_context)]),
+ orber_test_server:testing_iiop_context(Target),
+ io:format("orber_test_server:relay_cast( ~p ) Post~n", [get(oe_server_in_context)]),
+ {noreply, State}.
+
+%% Testing pseudo calls.
+pseudo_call(_Self, State) ->
+ io:format("orber_test_server:pseudo_call( ~p )~n", [now()]),
+ {reply, ok, State}.
+
+pseudo_cast(_Self, State) ->
+ io:format("orber_test_server:pseudo_cast( ~p )~n", [now()]),
+ {noreply, State}.
+pseudo_call_delay(_Self, State, Time) ->
+ io:format("orber_test_server:pseudo_call_delay( ~p )~n", [now()]),
+ timer:sleep(Time),
+ io:format("orber_test_server:pseudo_call_delay( ~p )~n", [now()]),
+ {reply, {ok, Time}, State}.
+
+pseudo_cast_delay(_Self, State, Time) ->
+ io:format("orber_test_server:pseudo_cast_delay( ~p )~n", [now()]),
+ timer:sleep(Time),
+ io:format("orber_test_server:pseudo_cast_delay( ~p )~n", [now()]),
+ {noreply, State}.
+
+pseudo_call_raise_exc(_Self, State, 1) ->
+ io:format("orber_test_server:pseudo_call_raise_exc( ~p )~n",[1]),
+ {reply, {'EXCEPTION', #'BAD_QOS'{completion_status=?COMPLETED_NO}}, State};
+pseudo_call_raise_exc(_Self, State, 2) ->
+ io:format("orber_test_server:pseudo_call_raise_exc( ~p )~n",[2]),
+ corba:raise(#'BAD_QOS'{completion_status=?COMPLETED_NO}),
+ {reply, ok, State}.
+
+%%--------------- LOCAL FUNCTIONS ----------------------------
+
+%%--------------- END OF MODULE ------------------------------
+
diff --git a/lib/orber/test/orber_test_timeout_server_impl.erl b/lib/orber/test/orber_test_timeout_server_impl.erl
new file mode 100644
index 0000000000..138eb51d92
--- /dev/null
+++ b/lib/orber/test/orber_test_timeout_server_impl.erl
@@ -0,0 +1,65 @@
+%%--------------------------------------------------------------------
+%%
+%% %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%
+%%
+%%
+%%----------------------------------------------------------------------
+%% File : orber_test_timeout_server_impl.erl
+%% Purpose :
+%%----------------------------------------------------------------------
+
+-module(orber_test_timeout_server_impl).
+
+-export([oneway_function/3, twoway_function/3]).
+
+
+%%--------------- gen_server specific ------------------------
+-export([init/1, terminate/2, code_change/3, handle_info/2]).
+
+%%------------------------------------------------------------
+%% function : server specific
+%%------------------------------------------------------------
+init(State) ->
+ %% 'trap_exit' optional
+ process_flag(trap_exit,true),
+ {ok, State}.
+
+terminate(_Reason, _State) ->
+ ok.
+
+code_change(_OldVsn, State, _Extra) ->
+ {ok, State}.
+
+%% If use IC option {{handle_info, "Module::Interface"}, true}
+handle_info(_Info, State) ->
+ %% Await the next invocation.
+ {noreply, State}.
+
+%%--- two-way ------------------------------------------------
+twoway_function(_OE_THIS, State, Time) ->
+ timer:sleep(Time),
+ {reply, ok, State}.
+
+
+%%--- one-way ------------------------------------------------
+oneway_function(_OE_THIS, State, Time) ->
+ timer:sleep(Time),
+ {noreply, State}.
+
+%%--------------- END OF MODULE ------------------------------
+
diff --git a/lib/orber/test/orber_web_SUITE.erl b/lib/orber/test/orber_web_SUITE.erl
new file mode 100644
index 0000000000..ffa7468853
--- /dev/null
+++ b/lib/orber/test/orber_web_SUITE.erl
@@ -0,0 +1,443 @@
+%%-----------------------------------------------------------------
+%%
+%% %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%
+%%
+%%
+%%-----------------------------------------------------------------
+%% File : orber_web_SUITE.erl
+%% Purpose :
+%%-----------------------------------------------------------------
+
+-module(orber_web_SUITE).
+
+-include("test_server.hrl").
+-include_lib("orber/include/corba.hrl").
+-include_lib("orber/src/orber_iiop.hrl").
+
+-define(default_timeout, ?t:minutes(3)).
+
+-define(match(ExpectedRes, Expr),
+ fun() ->
+ AcTuAlReS = (catch (Expr)),
+ case AcTuAlReS of
+ ExpectedRes ->
+ io:format("------ CORRECT RESULT ------~n~p~n",
+ [AcTuAlReS]),
+ AcTuAlReS;
+ _ ->
+ io:format("###### ERROR ERROR ######~n~p~n",
+ [AcTuAlReS]),
+ ?line exit(AcTuAlReS)
+ end
+ end()).
+
+-define(nomatch(Not, Expr),
+ fun() ->
+ AcTuAlReS = (catch (Expr)),
+ case AcTuAlReS of
+ Not ->
+ io:format("###### ERROR ERROR ######~n~p~n",
+ [AcTuAlReS]),
+ ?line exit(AcTuAlReS);
+ _ ->
+ io:format("------ CORRECT RESULT ------~n~p~n",
+ [AcTuAlReS]),
+ AcTuAlReS
+ end
+ end()).
+
+
+%%-----------------------------------------------------------------
+%% External exports
+%%-----------------------------------------------------------------
+-export([all/1]).
+
+%%-----------------------------------------------------------------
+%% Internal exports
+%%-----------------------------------------------------------------
+-export([]).
+-compile(export_all).
+
+%%-----------------------------------------------------------------
+%% Func: all/1
+%% Args:
+%% Returns:
+%%-----------------------------------------------------------------
+all(doc) -> ["This suite is for testing the Orber Web API"];
+all(suite) ->
+ [menu, configure, info, nameservice, ifr_select, ifr_data,
+ create, delete_ctx, add_ctx, delete_obj, server].
+
+%%-----------------------------------------------------------------
+%% Init and cleanup functions.
+%%-----------------------------------------------------------------
+init_per_testcase(_Case, Config) ->
+ ?line Dog=test_server:timetrap(?default_timeout),
+ Path = code:which(?MODULE),
+ code:add_pathz(filename:join(filename:dirname(Path), "idl_output")),
+ orber:jump_start(2875),
+ oe_orber_test_server:oe_register(),
+ [{watchdog, Dog}|Config].
+
+
+fin_per_testcase(_Case, Config) ->
+ oe_orber_test_server:oe_unregister(),
+ orber:jump_stop(),
+ Path = code:which(?MODULE),
+ code:del_path(filename:join(filename:dirname(Path), "idl_output")),
+ Dog = ?config(watchdog, Config),
+ test_server:timetrap_cancel(Dog),
+ ok.
+
+%%-----------------------------------------------------------------
+%% Test Case: menu
+%% Description:
+%%-----------------------------------------------------------------
+menu(doc) -> [""];
+menu(suite) -> [];
+menu(_) ->
+ Node = atom_to_list(node()),
+ OK = orber_web:menu(env, [{"node", Node}]),
+ ?match(OK, orber_web:menu(env, [])),
+ ?match(OK, orber_web:menu(env, [42, {"node", Node}, "wrong"])),
+ ?match({'EXIT', _E}, orber_web:menu(env, [{"node", localhost}])),
+ ok.
+
+%%-----------------------------------------------------------------
+%% Test Case: configure
+%% Description:
+%%-----------------------------------------------------------------
+configure(doc) -> [""];
+configure(suite) -> [];
+configure(_) ->
+ Node = atom_to_list(node()),
+ ?match({'EXIT', _}, orber_web:configure(env, [])),
+ ?match({'EXIT', _}, orber_web:configure(env, [{"node", localhost},
+ {"data", atom}])),
+ ?match([_H|_T], orber_web:configure(env, [{"node", Node}, {"data", ""}])),
+ ?match([_H|_T], orber_web:configure(env, [{"node", Node},
+ {"data", "[{orber_debug_level, 9}]"}])),
+ ?match({ok, 9}, application:get_env(orber, orber_debug_level)),
+ ?match([_H|_T], orber_web:configure(env, [{"node", "bad_node"},
+ {"data", "[{orber_debug_level, 9}]"}])),
+ ?match({error, _}, orber_web:configure(env, [{"node", Node},
+ {"data", "{orber_debug_level 9}"}])),
+ ok.
+
+%%-----------------------------------------------------------------
+%% Test Case: info
+%% Description:
+%%-----------------------------------------------------------------
+info(doc) -> [""];
+info(suite) -> [];
+info(_) ->
+ ?match({'EXIT', _}, orber_web:info(env, [])),
+ ?match({'EXIT', _}, orber_web:info(env, [{"node", localhost}])),
+ ?match([_H|_T], orber_web:info(env, [{"node", atom_to_list(node())}])),
+ ok.
+
+%%-----------------------------------------------------------------
+%% Test Case: nameservice
+%% Description:
+%%-----------------------------------------------------------------
+nameservice(doc) -> [""];
+nameservice(suite) -> [];
+nameservice(_) ->
+ NodeStr = atom_to_list(node()),
+ ?match({'EXIT', _}, orber_web:nameservice(env, [{"node", localhost},
+ {"context", "root"}])),
+ ?match({'EXIT', _}, orber_web:nameservice(env, [{"node", localhost},
+ {"context", "id1"}])),
+ ?match([_H|_T], orber_web:nameservice(env, [{"node", "bad_node"},
+ {"context", "root"}])),
+ ?match([_,_,_,NodeStr|_], orber_web:nameservice(env, [{"node", NodeStr},
+ {"context", "root"}])),
+ ?match({ok,_}, orber_web:nameservice(env, [{"node", NodeStr},
+ {"context", "id1"}])),
+ ?match([_H|_T], orber_web:add_ctx(env, [{"node", NodeStr},
+ {"context", "root"},
+ {"id", "id1"}])),
+ ?match([_H|_T], orber_web:add_ctx(env, [{"node", NodeStr},
+ {"context", "id1"},
+ {"id", "id2"}])),
+ [_,_,_,IOR] =
+ ?match([_,_,_,_], orber_web:create(env, [{"node", NodeStr},
+ {"module", "orber_test_server"},
+ {"arguments", "[]"},
+ {"options", "[{pseudo, true}]"},
+ {"namestr", "id1/id2/id3"},
+ {"bind", "rebind"}])),
+ ?match(#'IOP_IOR'{}, corba:string_to_object(IOR)),
+
+ ?match([_,"id1"|_], orber_web:nameservice(env, [{"node", NodeStr},
+ {"context", "id1"}])),
+ ?nomatch({error, _}, orber_web:nameservice(env, [{"node", NodeStr},
+ {"context", "id1/id2"},
+ {"object", "id3"}])),
+
+ ok.
+
+%%-----------------------------------------------------------------
+%% Test Case: ifr_select
+%% Description:
+%%-----------------------------------------------------------------
+ifr_select(doc) -> [""];
+ifr_select(suite) -> [];
+ifr_select(_) ->
+ ?match({'EXIT', _}, orber_web:ifr_select(env, [])),
+ ?match({'EXIT', _}, orber_web:ifr_select(env, [{"node", localhost}])),
+ ?match([_H|_T], orber_web:ifr_select(env, [{"node", "bad_node"}])),
+ ?match([_H|_T], orber_web:ifr_select(env, [{"node", atom_to_list(node())}])),
+ ok.
+
+%%-----------------------------------------------------------------
+%% Test Case: ifr_data
+%% Description:
+%%-----------------------------------------------------------------
+ifr_data(doc) -> [""];
+ifr_data(suite) -> [];
+ifr_data(_) ->
+ ?match({'EXIT', _}, orber_web:ifr_data(env, [])),
+ ?match({'EXIT', _}, orber_web:ifr_data(env, [{"node", localhost},
+ {"table", "ir_ModuleDef"}])),
+ ?match({error, _}, orber_web:ifr_data(env, [{"node", "bad_host"},
+ {"table", "ir_ModuleDef"}])),
+ ?match({'EXIT', _}, orber_web:ifr_data(env, [{"node", atom_to_list(node())},
+ {"table", "bad_table"}])),
+ ?match([_H|_T], orber_web:ifr_data(env, [{"node", atom_to_list(node())},
+ {"table", "ir_ModuleDef"}])),
+ ?match([_H|_T], orber_web:ifr_data(env, [{"node", atom_to_list(node())},
+ {"table", "ir_InterfaceDef"}])),
+ ?match([_H|_T], orber_web:ifr_data(env, [{"node", atom_to_list(node())},
+ {"table", "ir_StructDef"}])),
+ ?match([_H|_T], orber_web:ifr_data(env, [{"node", atom_to_list(node())},
+ {"table", "ir_ExceptionDef"}])),
+ ?match([_H|_T], orber_web:ifr_data(env, [{"node", atom_to_list(node())},
+ {"table", "ir_ConstantDef"}])),
+ ?match([_H|_T], orber_web:ifr_data(env, [{"node", atom_to_list(node())},
+ {"table", "ir_EnumDef"}])),
+ ?match([_H|_T], orber_web:ifr_data(env, [{"node", atom_to_list(node())},
+ {"table", "ir_AliasDef"}])),
+ ?match([_H|_T], orber_web:ifr_data(env, [{"node", atom_to_list(node())},
+ {"table", "ir_AttributeDef"}])),
+ ?match([_H|_T], orber_web:ifr_data(env, [{"node", atom_to_list(node())},
+ {"table", "ir_OperationDef"}])),
+ ?match([_H|_T], orber_web:ifr_data(env, [{"node", atom_to_list(node())},
+ {"table", "ir_Contained"}])),
+ ?match([_H|_T], orber_web:ifr_data(env, [{"node", atom_to_list(node())},
+ {"table", "ir_TypedefDef"}])),
+ ok.
+
+%%-----------------------------------------------------------------
+%% Test Case: create
+%% Description:
+%%-----------------------------------------------------------------
+create(doc) -> [""];
+create(suite) -> [];
+create(_) ->
+ NodeStr = atom_to_list(node()),
+ ?match({'EXIT', _}, orber_web:create(env, [])),
+ ?match({'EXIT', _}, orber_web:create(env, [{"node", localhost}])),
+ ?match({error, _}, orber_web:create(env, [{"node", NodeStr},
+ {"module", "orber_test_server"},
+ {"arguments", "[]"},
+ {"options", "[bad_option 42]"},
+ {"namestr", "[]"},
+ {"bind", "rebind"}])),
+ ?match({error, _}, orber_web:create(env, [{"node", NodeStr},
+ {"module", "orber_test_server"},
+ {"arguments", "[bad_argument 42]"},
+ {"options", "[]"},
+ {"namestr", "[]"},
+ {"bind", "rebind"}])),
+
+ ?match([_, NodeStr|_T], orber_web:create(env, [{"node", NodeStr}])),
+
+ [_,IOR] = ?match([_,_], orber_web:create(env, [{"node", NodeStr},
+ {"module", "orber_test_server"},
+ {"arguments", "[]"},
+ {"options", "[]"},
+ {"namestr", ""},
+ {"bind", "rebind"}])),
+ ?match(#'IOP_IOR'{}, corba:string_to_object(IOR)),
+
+ [_,_,_,_,_,IOR2] =
+ ?match([_,_,_,_,_,_], orber_web:create(env, [{"node", NodeStr},
+ {"module", "orber_test_server"},
+ {"arguments", "[]"},
+ {"options", "[]"},
+ {"namestr", "id1"},
+ {"bind", "rebind"}])),
+ ?match(#'IOP_IOR'{}, corba:string_to_object(IOR2)),
+
+ [_,_,_,IOR3] =
+ ?match([_,_,_,_], orber_web:create(env, [{"node", NodeStr},
+ {"module", "orber_test_server"},
+ {"arguments", "[]"},
+ {"options", "[{pseudo, true}]"},
+ {"namestr", "id2"},
+ {"bind", "rebind"}])),
+ ?match(#'IOP_IOR'{}, corba:string_to_object(IOR3)),
+
+ [_,IOR4] =?match([_,_], orber_web:create(env, [{"node", NodeStr},
+ {"module", "orber_test_server"},
+ {"arguments", "[]"},
+ {"options", "[{pseudo, true}]"},
+ {"namestr", ""},
+ {"bind", "rebind"}])),
+ ?match(#'IOP_IOR'{}, corba:string_to_object(IOR4)),
+
+ ?match([_], orber_web:create(env, [{"node", NodeStr},
+ {"module", "orber_test_server"},
+ {"arguments", "[]"},
+ {"options", "[{unknown, option}]"},
+ {"namestr", "id1"},
+ {"bind", "rebind"}])),
+
+ ?match([_, "id1"], orber_web:create(env, [{"node", NodeStr},
+ {"module", "orber_test_server"},
+ {"arguments", "[]"},
+ {"options", "[]"},
+ {"namestr", "id1"},
+ {"bind", "bind"}])),
+
+ ?match([_, "id2"], orber_web:create(env, [{"node", NodeStr},
+ {"module", "orber_test_server"},
+ {"arguments", "[]"},
+ {"options", "[{pseudo, true}]"},
+ {"namestr", "id2"},
+ {"bind", "bind"}])),
+ ok.
+
+%%-----------------------------------------------------------------
+%% Test Case: delete_ctx
+%% Description:
+%%-----------------------------------------------------------------
+delete_ctx(doc) -> [""];
+delete_ctx(suite) -> [];
+delete_ctx(_) ->
+ ?match({ok, _}, orber_web:delete_ctx(env, [{"node", atom_to_list(node())},
+ {"context", "id1"}])),
+ ?match([_H|_T], orber_web:add_ctx(env, [{"node", atom_to_list(node())},
+ {"context", "root"},
+ {"id", "id1"}])),
+ ?match([_H|_T], orber_web:delete_ctx(env, [{"node", atom_to_list(node())},
+ {"context", "id1"}])),
+ ok.
+
+%%-----------------------------------------------------------------
+%% Test Case: add_ctx
+%% Description:
+%%-----------------------------------------------------------------
+add_ctx(doc) -> [""];
+add_ctx(suite) -> [];
+add_ctx(_) ->
+ ?match({error, _}, orber_web:add_ctx(env, [{"node", "bad_node"},
+ {"context", "root"},
+ {"id", "id1"}])),
+ ?match([_H|_T], orber_web:add_ctx(env, [{"node", atom_to_list(node())},
+ {"context", "root"},
+ {"id", ""}])),
+ ?match([_H|_T], orber_web:add_ctx(env, [{"node", atom_to_list(node())},
+ {"context", "root"},
+ {"id", "id1"}])),
+ ?match([_H|_T], orber_web:add_ctx(env, [{"node", atom_to_list(node())},
+ {"context", "id1"},
+ {"id", "id2"}])),
+ ok.
+
+%%-----------------------------------------------------------------
+%% Test Case: delete_obj
+%% Description:
+%%-----------------------------------------------------------------
+delete_obj(doc) -> [""];
+delete_obj(suite) -> [];
+delete_obj(_) ->
+ NodeStr = atom_to_list(node()),
+ ?match({error, _}, orber_web:delete_obj(env, [{"node", "bad_node"},
+ {"context", "id1"},
+ {"action", "unbind"}])),
+ ?match({error, _}, orber_web:delete_obj(env, [{"node", "bad_node"},
+ {"context", "id1"},
+ {"action", "both"}])),
+ ?match({'EXIT', _}, orber_web:delete_obj(env, [{"node", bad_node},
+ {"context", "id1"},
+ {"action", "both"}])),
+ ?match({error, _}, orber_web:delete_obj(env, [{"node", NodeStr},
+ {"context", "non/existing"},
+ {"action", "unbind"}])),
+ [_,_,_,_,_,IOR2] =
+ ?match([_,_,_,_,_,_], orber_web:create(env, [{"node", NodeStr},
+ {"module", "orber_test_server"},
+ {"arguments", "[]"},
+ {"options", "[]"},
+ {"namestr", "id1"},
+ {"bind", "rebind"}])),
+ ?match(#'IOP_IOR'{}, corba:string_to_object(IOR2)),
+
+ ?match({error, _}, orber_web:delete_obj(env, [{"node", NodeStr},
+ {"context", "bad/INS./id"},
+ {"action", "unbind"}])),
+
+ [_,_,_,IOR3] =
+ ?match([_,_,_,_], orber_web:create(env, [{"node", NodeStr},
+ {"module", "orber_test_server"},
+ {"arguments", "[]"},
+ {"options", "[{pseudo, true}]"},
+ {"namestr", "id2"},
+ {"bind", "rebind"}])),
+ ?match(#'IOP_IOR'{}, corba:string_to_object(IOR3)),
+
+ ?match([_, "id1"|_], orber_web:delete_obj(env, [{"node", NodeStr},
+ {"context", "id1"},
+ {"action", "unbind"}])),
+ ?match([_, "id2"|_], orber_web:delete_obj(env, [{"node", NodeStr},
+ {"context", "id2"},
+ {"action", "unbind"}])),
+
+
+ ok.
+
+%%-----------------------------------------------------------------
+%% Test Case: server
+%% Description:
+%%-----------------------------------------------------------------
+server(doc) -> [""];
+server(suite) -> [];
+server(_) ->
+ NodeStr = "node=" ++ atom_to_list(node()),
+ {ok, Pid} = ?match({ok,_}, orber_web_server:start()),
+ ?match({error,{already_started, Pid}}, orber_web_server:start_link()),
+ ?match({error,{already_started,Pid}}, orber_web_server:start()),
+ ?match({orber, _}, orber_web_server:config_data()),
+ ?match([_H|_T], orber_web_server:ifr_select(env, "node=badnode")),
+ ?match([_H|_T], orber_web_server:ifr_select(env, "node=" ++ NodeStr)),
+ ?match([_H|_T], orber_web_server:menu(env, NodeStr)),
+ ?match([_H|_T], orber_web_server:configure(env, NodeStr ++ "&data=[{orber_debug_level, 9}]")),
+ ?match([_H|_T], orber_web_server:nameservice(env, NodeStr ++ "&context=root")),
+ ?match([_H|_T], orber_web_server:info(env, NodeStr)),
+ ?match([_H|_T], orber_web_server:ifr_data(env, NodeStr ++ "&table=ir_ModuleDef")),
+ ?match([_H|_T], orber_web_server:create(env, NodeStr)),
+ ?match([_H|_T], orber_web_server:add_ctx(env, NodeStr ++ "&context=root&id=id1")),
+ ?match([_H|_T], orber_web_server:delete_ctx(env, NodeStr++"&context=id1")),
+ ?match([_H|_T], orber_web_server:delete_obj(env, NodeStr++"&context=id1&action=unbind")),
+ ?match([_H|_T], orber_web_server:default_selection(env, NodeStr)),
+ ?match(ok, orber_web_server:stop()),
+ ok.
+
+
diff --git a/lib/orber/test/tc_SUITE.erl b/lib/orber/test/tc_SUITE.erl
new file mode 100644
index 0000000000..807a663219
--- /dev/null
+++ b/lib/orber/test/tc_SUITE.erl
@@ -0,0 +1,661 @@
+%%
+%% %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%
+%%
+%%
+%%-----------------------------------------------------------------
+%%
+%% Description:
+%% Test suite for the basic typecode functions
+%%
+%%-----------------------------------------------------------------
+-module(tc_SUITE).
+
+-include("test_server.hrl").
+-include_lib("orber/src/orber_iiop.hrl").
+
+-define(default_timeout, ?t:minutes(3)).
+
+-define(match(Expr),
+ fun() ->
+ case (catch (Expr)) of
+ AcTuAlReS when is_binary(AcTuAlReS)->
+ io:format("###### ERROR ERROR ######~nRESULT: ~p~n",
+ [AcTuAlReS]),
+ exit(AcTuAlReS);
+ _ ->
+ ok
+ end
+ end()).
+-define(SUB_ELIST, [{"null", orber_tc:null()},
+ {"void", orber_tc:void()},
+ {"short", orber_tc:short()},
+ {"unsigned_short", orber_tc:unsigned_short()},
+ {"long", orber_tc:long()},
+ {"unsigned_long", orber_tc:unsigned_long()},
+ {"long_long", orber_tc:long_long()},
+ {"unsigned_long_long", orber_tc:unsigned_long_long()},
+ {"float", orber_tc:'float'()},
+ {"double", orber_tc:double()},
+ {"longdouble", orber_tc:longdouble()},
+ {"boolean", orber_tc:boolean()},
+ {"char", orber_tc:char()},
+ {"wchar", orber_tc:wchar()},
+ {"octet", orber_tc:octet()},
+ {"any", orber_tc:any()},
+ {"typecode", orber_tc:typecode()},
+ {"principal", orber_tc:principal()},
+ {"object_reference", orber_tc:object_reference("Id", "Name")}]).
+
+-define(ELIST, [{"null", orber_tc:null()},
+ {"void", orber_tc:void()},
+ {"short", orber_tc:short()},
+ {"unsigned_short", orber_tc:unsigned_short()},
+ {"long", orber_tc:long()},
+ {"unsigned_long", orber_tc:unsigned_long()},
+ {"long_long", orber_tc:long_long()},
+ {"unsigned_long_long", orber_tc:unsigned_long_long()},
+ {"float", orber_tc:'float'()},
+ {"double", orber_tc:double()},
+ {"longdouble", orber_tc:longdouble()},
+ {"boolean", orber_tc:boolean()},
+ {"char", orber_tc:char()},
+ {"wchar", orber_tc:wchar()},
+ {"octet", orber_tc:octet()},
+ {"any", orber_tc:any()},
+ {"typecode", orber_tc:typecode()},
+ {"principal", orber_tc:principal()},
+ {"object_reference", orber_tc:object_reference("Id", "Name")},
+ {"struct", orber_tc:struct("Id", "Name", ?SUB_ELIST)},
+ {"enum", orber_tc:enum("Id", "Name", ["E1", "E2"])},
+ {"string", orber_tc:string(1)},
+ {"wstring", orber_tc:wstring(0)},
+ {"sequence", orber_tc:sequence(orber_tc:enum("Id", "Name",
+ ["E1", "E2"]), 0)},
+ {"array", orber_tc:array(orber_tc:enum("Id", "Name",
+ ["E1", "E2"]), 2)},
+ {"alias", orber_tc:alias("id", "name",
+ orber_tc:enum("Id", "Name",
+ ["E1", "E2"]))},
+ {"exception", orber_tc:exception("Id", "Name", ?SUB_ELIST)}]).
+
+-define(VELIST, [{"null", orber_tc:null(), 42},
+ {"void", orber_tc:void(), 42},
+ {"short", orber_tc:short(), 42},
+ {"unsigned_short", orber_tc:unsigned_short(), 42},
+ {"long", orber_tc:long(), 42},
+ {"unsigned_long", orber_tc:unsigned_long(), 42},
+ {"long_long", orber_tc:long_long(), 42},
+ {"unsigned_long_long", orber_tc:unsigned_long_long(), 42},
+ {"float", orber_tc:'float'(), 42},
+ {"double", orber_tc:double(), 42},
+ {"longdouble", orber_tc:longdouble(), 42},
+ {"boolean", orber_tc:boolean(), 42},
+ {"char", orber_tc:char(), 42},
+ {"wchar", orber_tc:wchar(), 42},
+ {"octet", orber_tc:octet(), 42},
+ {"any", orber_tc:any(), 42},
+ {"typecode", orber_tc:typecode(), 42},
+ {"principal", orber_tc:principal(), 42},
+ {"object_reference", orber_tc:object_reference("Id", "Name"), 42},
+ {"struct", orber_tc:struct("Id", "Name", ?SUB_ELIST), 42},
+ {"enum", orber_tc:enum("Id", "Name", ["E1", "E2"]), 42},
+ {"string", orber_tc:string(1), 42},
+ {"wstring", orber_tc:wstring(0), 42},
+ {"sequence", orber_tc:sequence(orber_tc:enum("Id", "Name",
+ ["E1", "E2"]), 0), 42},
+ {"array", orber_tc:array(orber_tc:enum("Id", "Name",
+ ["E1", "E2"]), 2), 42},
+ {"alias", orber_tc:alias("id", "name",
+ orber_tc:enum("Id", "Name",
+ ["E1", "E2"])), 42},
+ {"exception", orber_tc:exception("Id", "Name", ?SUB_ELIST), 42}]).
+
+%%-----------------------------------------------------------------
+%% External exports
+%%-----------------------------------------------------------------
+-export([all/1]).
+
+%%-----------------------------------------------------------------
+%% Internal exports
+%%-----------------------------------------------------------------
+-export([]).
+-compile(export_all).
+
+%%-----------------------------------------------------------------
+%% Func: all/1
+%% Args:
+%% Returns:
+%%-----------------------------------------------------------------
+all(doc) -> ["Description", "more description"];
+all(suite) ->
+ [null, void,
+ short, ushort,
+ long, ulong,
+ longlong, ulonglong,
+ boolean, char, wchar, octet,
+ float, double, longdouble,
+ any, typecode, principal, object_reference,
+ struct, union, enum, string, wstring, sequence, array,
+ alias, exception, fixed, value, value_box, native,
+ abstract_interface, indirection, get_tc].
+
+%%-----------------------------------------------------------------
+%% Init and cleanup functions.
+%%-----------------------------------------------------------------
+
+init_per_testcase(_Case, Config) ->
+ ?line Dog=test_server:timetrap(?default_timeout),
+ [{watchdog, Dog}|Config].
+
+
+fin_per_testcase(_Case, Config) ->
+ Dog = ?config(watchdog, Config),
+ test_server:timetrap_cancel(Dog),
+ ok.
+
+%%-----------------------------------------------------------------
+%% Test Case: null test
+%% Description:
+%%-----------------------------------------------------------------
+null(doc) -> [];
+null(suite) -> [];
+null(_) ->
+ ?line true = orber_tc:check_tc(orber_tc:null()),
+ ?line code(orber_tc:null()),
+ ok.
+
+%%-----------------------------------------------------------------
+%% Test Case: void test
+%% Description:
+%%-----------------------------------------------------------------
+void(doc) -> [];
+void(suite) -> [];
+void(_) ->
+ ?line true = orber_tc:check_tc(orber_tc:void()),
+ ?line code(orber_tc:void()),
+ ok.
+
+%%-----------------------------------------------------------------
+%% Test Case: short integer test
+%% Description:
+%%-----------------------------------------------------------------
+short(doc) -> [];
+short(suite) -> [];
+short(_) ->
+ ?line true = orber_tc:check_tc(orber_tc:short()),
+ ?line code(orber_tc:short()),
+ ok.
+
+%%-----------------------------------------------------------------
+%% Test Case: unsigned short integer test
+%% Description:
+%%-----------------------------------------------------------------
+ushort(doc) -> [];
+ushort(suite) -> [];
+ushort(_) ->
+ ?line true = orber_tc:check_tc(orber_tc:unsigned_short()),
+ ?line code(orber_tc:unsigned_short()),
+ ok.
+
+%%-----------------------------------------------------------------
+%% Test Case: long integer test
+%% Description:
+%%-----------------------------------------------------------------
+long(doc) -> [];
+long(suite) -> [];
+long(_) ->
+ ?line true = orber_tc:check_tc(orber_tc:long()),
+ ?line code(orber_tc:long()),
+ ok.
+
+%%-----------------------------------------------------------------
+%% Test Case: unsigned long integer test
+%% Description:
+%%-----------------------------------------------------------------
+ulong(doc) -> [];
+ulong(suite) -> [];
+ulong(_) ->
+ ?line true = orber_tc:check_tc(orber_tc:unsigned_long()),
+ ?line code(orber_tc:unsigned_long()),
+ ok.
+
+
+%%-----------------------------------------------------------------
+%% Test Case: long integer test
+%% Description:
+%%-----------------------------------------------------------------
+longlong(doc) -> [];
+longlong(suite) -> [];
+longlong(_) ->
+ ?line true = orber_tc:check_tc(orber_tc:long_long()),
+ ?line code(orber_tc:long_long()),
+ ok.
+
+%%-----------------------------------------------------------------
+%% Test Case: unsigned long integer test
+%% Description:
+%%-----------------------------------------------------------------
+ulonglong(doc) -> [];
+ulonglong(suite) -> [];
+ulonglong(_) ->
+ ?line true = orber_tc:check_tc(orber_tc:unsigned_long_long()),
+ ?line code(orber_tc:unsigned_long_long()),
+ ok.
+
+
+%%-----------------------------------------------------------------
+%% Test Case: float test
+%% Description:
+%%-----------------------------------------------------------------
+float(doc) -> [];
+float(suite) -> [];
+float(_) ->
+ ?line true = orber_tc:check_tc(orber_tc:'float'()),
+ ?line code(orber_tc:'float'()),
+ ok.
+
+%%-----------------------------------------------------------------
+%% Test Case: double test
+%% Description:
+%%-----------------------------------------------------------------
+double(doc) -> [];
+double(suite) -> [];
+double(_) ->
+ ?line true = orber_tc:check_tc(orber_tc:double()),
+ ?line code(orber_tc:double()),
+ ok.
+
+%%-----------------------------------------------------------------
+%% Test Case: longdouble test
+%% Description:
+%%-----------------------------------------------------------------
+longdouble(doc) -> [];
+longdouble(suite) -> [];
+longdouble(_) ->
+ ?line true = orber_tc:check_tc(orber_tc:longdouble()),
+ ?line code(orber_tc:longdouble()),
+ ok.
+
+%%-----------------------------------------------------------------
+%% Test Case: boolean test
+%% Description:
+%%-----------------------------------------------------------------
+boolean(doc) -> [];
+boolean(suite) -> [];
+boolean(_) ->
+ ?line true = orber_tc:check_tc(orber_tc:boolean()),
+ ?line code(orber_tc:boolean()),
+ ok.
+
+%%-----------------------------------------------------------------
+%% Test Case: character test
+%% Description:
+%%-----------------------------------------------------------------
+char(doc) -> [];
+char(suite) -> [];
+char(_) ->
+ ?line true = orber_tc:check_tc(orber_tc:char()),
+ ?line code(orber_tc:char()),
+ ok.
+
+%%-----------------------------------------------------------------
+%% Test Case: character test
+%% Description:
+%%-----------------------------------------------------------------
+wchar(doc) -> [];
+wchar(suite) -> [];
+wchar(_) ->
+ ?line true = orber_tc:check_tc(orber_tc:wchar()),
+ ?line code(orber_tc:wchar()),
+ ok.
+
+%%-----------------------------------------------------------------
+%% Test Case: octet test
+%% Description:
+%%-----------------------------------------------------------------
+octet(doc) -> [];
+octet(suite) -> [];
+octet(_) ->
+ ?line true = orber_tc:check_tc(orber_tc:octet()),
+ ?line code(orber_tc:octet()),
+ ok.
+
+%%-----------------------------------------------------------------
+%% Test Case: any test
+%% Description:
+%%-----------------------------------------------------------------
+any(doc) -> [];
+any(suite) -> [];
+any(_) ->
+ ?line true = orber_tc:check_tc(orber_tc:any()),
+ ?line code(orber_tc:any()),
+ ok.
+
+%%-----------------------------------------------------------------
+%% Test Case: typecode test
+%% Description:
+%%-----------------------------------------------------------------
+typecode(doc) -> [];
+typecode(suite) -> [];
+typecode(_) ->
+ ?line true = orber_tc:check_tc(orber_tc:typecode()),
+ ?line code(orber_tc:typecode()),
+ ok.
+
+%%-----------------------------------------------------------------
+%% Test Case: principal test
+%% Description:
+%%-----------------------------------------------------------------
+principal(doc) -> [];
+principal(suite) -> [];
+principal(_) ->
+ ?line true = orber_tc:check_tc(orber_tc:principal()),
+ ?line code(orber_tc:principal()),
+ ok.
+
+
+%%-----------------------------------------------------------------
+%% Test Case: object_reference test
+%% Description:
+%%-----------------------------------------------------------------
+object_reference(doc) -> [];
+object_reference(suite) -> [];
+object_reference(_) ->
+ ?line true = orber_tc:check_tc(orber_tc:object_reference("Id", "Name")),
+ ?line false = orber_tc:check_tc(orber_tc:object_reference(42, "Name")),
+ ?line false = orber_tc:check_tc(orber_tc:object_reference("Id", 42)),
+ ?line code(orber_tc:object_reference("Id", "Name")),
+ ?line ?match(code(orber_tc:object_reference(42, "Name"))),
+ ?line ?match(code(orber_tc:object_reference("Id", 42))),
+ ok.
+
+%%-----------------------------------------------------------------
+%% Test Case: struct
+%% Description:
+%%-----------------------------------------------------------------
+struct(doc) -> [];
+struct(suite) -> [];
+struct(_) ->
+ ?line true = orber_tc:check_tc(orber_tc:struct("Id", "Name", ?ELIST)),
+ ?line false = orber_tc:check_tc(orber_tc:struct(42, "Name", ?ELIST)),
+ ?line false = orber_tc:check_tc(orber_tc:struct("Id", false, ?ELIST)),
+ ?line false = orber_tc:check_tc(orber_tc:struct("Id", "Name", ?VELIST)),
+ ?line false = orber_tc:check_tc(orber_tc:struct("Id", "Name", "wrong")),
+ ?line code(orber_tc:struct("Id", "Name", ?ELIST)),
+ ?line ?match(code(orber_tc:struct(42, "Name", ?ELIST))),
+ ?line ?match(code(orber_tc:struct("Id", false, ?ELIST))),
+ ?line ?match(code(orber_tc:struct("Id", "Name", ?VELIST))),
+ ?line ?match(code(orber_tc:struct("Id", "Name", "wrong"))),
+ ok.
+
+%%-----------------------------------------------------------------
+%% Test Case: union
+%% Description:
+%%-----------------------------------------------------------------
+union(doc) -> [];
+union(suite) -> [];
+union(_) ->
+ ?line true = orber_tc:check_tc(orber_tc:union("Id", "Name", orber_tc:long(),
+ -1, [{1, "long", orber_tc:long()},
+ {2, "longlong", orber_tc:long()}])),
+ ?line false = orber_tc:check_tc(orber_tc:union("Id", "Name", orber_tc:long(),
+ -1, ?ELIST)),
+ ?line false = orber_tc:check_tc(orber_tc:union(42, "Name", orber_tc:long(),
+ -1, [{1, "long", orber_tc:long()},
+ {2, "longlong", orber_tc:long()}])),
+ ?line false = orber_tc:check_tc(orber_tc:union("Id", false, orber_tc:long(),
+ -1, [{1, "long", orber_tc:long()},
+ {2, "longlong", orber_tc:long()}])),
+ ?line false = orber_tc:check_tc(orber_tc:union("Id", "Name", bad_tc,
+ -1, [{1, "long", orber_tc:long()},
+ {2, "longlong", orber_tc:long()}])),
+ ?line false = orber_tc:check_tc(orber_tc:union("Id", "Name", orber_tc:long(),
+ "wrong", [{1, "long", orber_tc:long()},
+ {2, "longlong", orber_tc:long()}])),
+
+ ?line code(orber_tc:union("Id", "Name", orber_tc:long(),
+ -1, [{1, "long", orber_tc:long()},
+ {2, "longlong", orber_tc:long()}])),
+ ok.
+
+
+%%-----------------------------------------------------------------
+%% Test Case: enum test
+%% Description:
+%%-----------------------------------------------------------------
+enum(doc) -> [];
+enum(suite) -> [];
+enum(_) ->
+ ?line true = orber_tc:check_tc(orber_tc:enum("Id", "Name",
+ ["E1", "E2", "E3"])),
+ ?line false = orber_tc:check_tc(orber_tc:enum(42, "Name",
+ ["E1", "E2", "E3"])),
+ ?line false = orber_tc:check_tc(orber_tc:enum("Id", false,
+ ["E1", "E2", "E3"])),
+ ?line false = orber_tc:check_tc(orber_tc:enum("Id", "Name",
+ ["E1", false, "E3"])),
+ ?line code(orber_tc:enum("Id", "Name", ["E1", "E2", "E3"])),
+ ?line ?match(code(orber_tc:enum(false, "Name", ["E1", "E2", "E3"]))),
+ ?line ?match(code(orber_tc:enum("Id", 42, ["E1", "E2", "E3"]))),
+ ?line ?match(code(orber_tc:enum("Id", "Name", ["E1", false, "E3"]))),
+ ok.
+
+%%-----------------------------------------------------------------
+%% Test Case: string
+%% Description:
+%%-----------------------------------------------------------------
+string(doc) -> [];
+string(suite) -> [];
+string(_) ->
+ ?line true = orber_tc:check_tc(orber_tc:string(0)),
+ ?line true = orber_tc:check_tc(orber_tc:string(1)),
+ ?line false = orber_tc:check_tc(orber_tc:string("wrong")),
+ ?line code(orber_tc:string(0)),
+ ?line code(orber_tc:string(1)),
+ ?line ?match(code(orber_tc:string(-1))),
+ ?line ?match(code(orber_tc:string(?ULONGMAX+1))),
+ ?line ?match(code(orber_tc:string("wrong"))),
+ ok.
+
+%%-----------------------------------------------------------------
+%% Test Case: wstring
+%% Description:
+%%-----------------------------------------------------------------
+wstring(doc) -> [];
+wstring(suite) -> [];
+wstring(_) ->
+ ?line true = orber_tc:check_tc(orber_tc:wstring(0)),
+ ?line true = orber_tc:check_tc(orber_tc:wstring(1)),
+ ?line false = orber_tc:check_tc(orber_tc:wstring("wrong")),
+ ?line code(orber_tc:wstring(0)),
+ ?line code(orber_tc:wstring(1)),
+ ?line ?match(code(orber_tc:wstring(-1))),
+ ?line ?match(code(orber_tc:wstring(?ULONGMAX+1))),
+ ?line ?match(code(orber_tc:wstring(false))),
+ ok.
+
+%%-----------------------------------------------------------------
+%% Test Case: sequence
+%% Description:
+%%-----------------------------------------------------------------
+sequence(doc) -> [];
+sequence(suite) -> [];
+sequence(_) ->
+ ?line true = orber_tc:check_tc(orber_tc:sequence(orber_tc:struct("Id", "Name", ?ELIST), 0)),
+ ?line code(orber_tc:sequence(orber_tc:struct("Id", "Name", ?ELIST), 0)),
+ ok.
+
+%%-----------------------------------------------------------------
+%% Test Case: array
+%% Description:
+%%-----------------------------------------------------------------
+array(doc) -> [];
+array(suite) -> [];
+array(_) ->
+ ?line true = orber_tc:check_tc(orber_tc:array(orber_tc:struct("Id", "Name", ?ELIST), 1)),
+ ?line code(orber_tc:array(orber_tc:struct("Id", "Name", ?ELIST), 1)),
+ ok.
+
+%%-----------------------------------------------------------------
+%% Test Case: alias
+%% Description:
+%%-----------------------------------------------------------------
+alias(doc) -> [];
+alias(suite) -> [];
+alias(_) ->
+ ?line true = orber_tc:check_tc(orber_tc:alias("Id", "Name", orber_tc:struct("Id", "Name", ?ELIST))),
+ ?line false = orber_tc:check_tc(orber_tc:alias(false, "Name", orber_tc:struct("Id", "Name", ?ELIST))),
+ ?line false = orber_tc:check_tc(orber_tc:alias("Id", 42, orber_tc:struct("Id", "Name", ?ELIST))),
+ ?line false = orber_tc:check_tc(orber_tc:alias("Id", "Name", "wrong")),
+ ?line code(orber_tc:alias("Id", "Name", orber_tc:struct("Id", "Name", ?ELIST))),
+ ?line ?match(code(orber_tc:alias("Id", "Name", orber_tc:struct("Id", "Name", ?VELIST)))),
+ ok.
+
+%%-----------------------------------------------------------------
+%% Test Case: exception
+%% Description:
+%%-----------------------------------------------------------------
+exception(doc) -> [];
+exception(suite) -> [];
+exception(_) ->
+ ?line true = orber_tc:check_tc(orber_tc:exception("Id", "Name", ?ELIST)),
+ ?line false = orber_tc:check_tc(orber_tc:exception(42, "Name", ?ELIST)),
+ ?line false = orber_tc:check_tc(orber_tc:exception("Id", false, ?ELIST)),
+ ?line false = orber_tc:check_tc(orber_tc:exception("Id", "Name", "wrong")),
+ ?line code(orber_tc:exception("Id", "Name", ?ELIST)),
+ ?line ?match(code(orber_tc:exception(42, "Name", ?ELIST))),
+ ?line ?match(code(orber_tc:exception("Id", false, ?ELIST))),
+ ?line ?match(code(orber_tc:exception("Id", "Name", "wrong"))),
+
+ ok.
+
+%%-----------------------------------------------------------------
+%% Test Case: fixed
+%% Description:
+%%-----------------------------------------------------------------
+fixed(doc) -> [];
+fixed(suite) -> [];
+fixed(_) ->
+ ?line true = orber_tc:check_tc(orber_tc:fixed(25, 2)),
+ ?line code(orber_tc:fixed(25, 2)),
+ ok.
+
+%%-----------------------------------------------------------------
+%% Test Case: value
+%% Description:
+%%-----------------------------------------------------------------
+value(doc) -> [];
+value(suite) -> [];
+value(_) ->
+ ?line true = orber_tc:check_tc(orber_tc:value("Id", "Name", 42,
+ orber_tc:fixed(25, 2), ?VELIST)),
+ ?line false = orber_tc:check_tc(orber_tc:value(42, "Name", 42,
+ orber_tc:fixed(25, 2), ?VELIST)),
+ ?line false = orber_tc:check_tc(orber_tc:value("Id", 42, 42,
+ orber_tc:fixed(25, 2), ?VELIST)),
+ ?line false = orber_tc:check_tc(orber_tc:value("Id", "Name", "wrong",
+ orber_tc:fixed(25, 2), ?VELIST)),
+ ?line false = orber_tc:check_tc(orber_tc:value("Id", "Name", "42",
+ orber_tc:fixed(25, 2), ?VELIST)),
+ ?line false = orber_tc:check_tc(orber_tc:value("Id", "Name", "42",
+ ?VELIST, ?VELIST)),
+ ?line false = orber_tc:check_tc(orber_tc:value("Id", "Name", "42",
+ orber_tc:fixed(25, 2), false)),
+
+ ?line code(orber_tc:value("Id", "Name", 42, orber_tc:long(), ?VELIST)),
+ ok.
+
+%%-----------------------------------------------------------------
+%% Test Case: value_box
+%% Description:
+%%-----------------------------------------------------------------
+value_box(doc) -> [];
+value_box(suite) -> [];
+value_box(_) ->
+ ?line true = orber_tc:check_tc(orber_tc:value_box("Id", "Name",
+ orber_tc:fixed(25, 2))),
+ ?line false = orber_tc:check_tc(orber_tc:value_box(42, "Name",
+ orber_tc:fixed(25, 2))),
+ ?line false = orber_tc:check_tc(orber_tc:value_box("Id", 42,
+ orber_tc:fixed(25, 2))),
+ ?line false = orber_tc:check_tc(orber_tc:value_box("Id", "Name", "wrong")),
+ ?line code(orber_tc:value_box("Id", "Name", orber_tc:long())),
+ ?line ?match(code(orber_tc:value_box(42, "Name", orber_tc:short()))),
+ ?line ?match(code(orber_tc:value_box("Id", 42, orber_tc:char()))),
+ ?line ?match(code(orber_tc:value_box("Id", "Name", false))),
+ ok.
+
+%%-----------------------------------------------------------------
+%% Test Case: native
+%% Description:
+%%-----------------------------------------------------------------
+native(doc) -> [];
+native(suite) -> [];
+native(_) ->
+ ?line true = orber_tc:check_tc(orber_tc:native("Id", "Name")),
+ ?line false = orber_tc:check_tc(orber_tc:native(42, "Name")),
+ ?line false = orber_tc:check_tc(orber_tc:native("Id", 42)),
+ ?line code(orber_tc:native("Id", "Name")),
+ ?line ?match(code(orber_tc:native(42, "Name"))),
+ ?line ?match(code(orber_tc:native("Id", 42))),
+ ok.
+
+%%-----------------------------------------------------------------
+%% Test Case: abstract_interface
+%% Description:
+%%-----------------------------------------------------------------
+abstract_interface(doc) -> [];
+abstract_interface(suite) -> [];
+abstract_interface(_) ->
+ ?line true = orber_tc:check_tc(orber_tc:abstract_interface("RepId", "Name")),
+ ?line false = orber_tc:check_tc(orber_tc:abstract_interface(false, "Name")),
+ ?line false = orber_tc:check_tc(orber_tc:abstract_interface("RepId", 42)),
+ ?line code(orber_tc:abstract_interface("RepId", "Name")),
+ ?line ?match(code(orber_tc:abstract_interface(42, "Name"))),
+ ?line ?match(code(orber_tc:abstract_interface("Id", 42))),
+ ok.
+
+
+
+%%-----------------------------------------------------------------
+%% Test Case: indirection
+%% Description:
+%%-----------------------------------------------------------------
+indirection(doc) -> [];
+indirection(suite) -> [];
+indirection(_) ->
+ ?line true = orber_tc:check_tc({'none', 42}),
+ ok.
+
+%%-----------------------------------------------------------------
+%% Test Case: get_tc
+%% Description:
+%%-----------------------------------------------------------------
+get_tc(doc) -> [];
+get_tc(suite) -> [];
+get_tc(_) ->
+ TC = 'CosNaming_Binding':tc(),
+ ?line TC = orber_tc:get_tc({'CosNaming_Binding', 42}),
+ ?line ?match(orber_tc:get_tc({'none', 42})),
+ ok.
+
+%%-----------------------------------------------------------------
+%% MISC Operations
+%%-----------------------------------------------------------------
+code(Value) ->
+ cdr_encode:enc_type({1,2}, tk_TypeCode, Value).
diff --git a/lib/orber/vsn.mk b/lib/orber/vsn.mk
index 8ccdc9792c..c265db188f 100644
--- a/lib/orber/vsn.mk
+++ b/lib/orber/vsn.mk
@@ -1,12 +1,3 @@
-ORBER_VSN = 3.6.14
+ORBER_VSN = 3.6.19
-TICKETS = OTP-8201
-
-TICKETS_3.6.13 = OTP-7987
-
-TICKETS_3.6.12 = OTP-7906
-
-TICKETS_3.6.11 = OTP-7837
-
-TICKETS_3.6.10 = OTP-7595
diff --git a/lib/os_mon/doc/src/notes.xml b/lib/os_mon/doc/src/notes.xml
index 1a8551f57d..1062b07dfd 100644
--- a/lib/os_mon/doc/src/notes.xml
+++ b/lib/os_mon/doc/src/notes.xml
@@ -4,7 +4,7 @@
<chapter>
<header>
<copyright>
- <year>2004</year><year>2009</year>
+ <year>2004</year><year>2010</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
@@ -13,12 +13,12 @@
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>OS_Mon Release Notes</title>
@@ -30,6 +30,22 @@
</header>
<p>This document describes the changes made to the OS_Mon application.</p>
+<section><title>Os_Mon 2.2.5</title>
+
+ <section><title>Improvements and New Features</title>
+ <list>
+ <item>
+ <p>
+ Cleanups suggested by tidier and modernization of types
+ and specs.</p>
+ <p>
+ Own Id: OTP-8455</p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
<section><title>Os_Mon 2.2.4</title>
<section><title>Fixed Bugs and Malfunctions</title>
diff --git a/lib/os_mon/src/cpu_sup.erl b/lib/os_mon/src/cpu_sup.erl
index 742e20b1fa..e414e2c10b 100644
--- a/lib/os_mon/src/cpu_sup.erl
+++ b/lib/os_mon/src/cpu_sup.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(cpu_sup).
@@ -65,15 +65,10 @@
%% Contract specifications
%%----------------------------------------------------------------------
--type(util_cpus() :: 'all' | integer() | [integer()]).
--type(util_state() ::
- 'user' |
- 'nice_user' |
- 'kernel' |
- 'wait' |
- 'idle').
--type(util_value() :: {util_state(), float()} | float()).
--type(util_desc() :: {util_cpus(), util_value(), util_value(), []}).
+-type util_cpus() :: 'all' | integer() | [integer()].
+-type util_state() :: 'user' | 'nice_user' | 'kernel' | 'wait' | 'idle'.
+-type util_value() :: {util_state(), float()} | float().
+-type util_desc() :: {util_cpus(), util_value(), util_value(), []}.
%%----------------------------------------------------------------------
%% Exported functions
@@ -88,28 +83,28 @@ start_link() ->
stop() ->
gen_server:call(cpu_sup, ?quit, infinity).
--spec(nprocs/0 :: () -> integer() | {'error', any()}).
+-spec nprocs() -> integer() | {'error', any()}.
nprocs() ->
os_mon:call(cpu_sup, ?nprocs, infinity).
--spec(avg1/0 :: () -> integer() | {'error', any()}).
+-spec avg1() -> integer() | {'error', any()}.
avg1() ->
os_mon:call(cpu_sup, ?avg1, infinity).
--spec(avg5/0 :: () -> integer() | {'error', any()}).
+-spec avg5() -> integer() | {'error', any()}.
avg5() ->
os_mon:call(cpu_sup, ?avg5, infinity).
--spec(avg15/0 :: () -> integer() | {'error', any()}).
+-spec avg15() -> integer() | {'error', any()}.
avg15() ->
os_mon:call(cpu_sup, ?avg15, infinity).
--spec(util/1 :: ([ 'detailed' | 'per_cpu']) ->
- util_desc() | [util_desc()] | {'error', any()}).
+-spec util(['detailed' | 'per_cpu']) ->
+ util_desc() | [util_desc()] | {'error', any()}.
util(Args) when is_list (Args) ->
% Get arguments
@@ -126,7 +121,7 @@ util(Args) when is_list (Args) ->
util(_) ->
erlang:error(badarg).
--spec(util/0 :: () -> float()).
+-spec util() -> float().
util() ->
case util([]) of
diff --git a/lib/os_mon/test/Makefile b/lib/os_mon/test/Makefile
new file mode 100644
index 0000000000..c87285e38b
--- /dev/null
+++ b/lib/os_mon/test/Makefile
@@ -0,0 +1,92 @@
+#
+# %CopyrightBegin%
+#
+# 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%
+#
+include $(ERL_TOP)/make/target.mk
+
+include $(ERL_TOP)/make/$(TARGET)/otp.mk
+
+# ----------------------------------------------------
+# Target Specs
+# ----------------------------------------------------
+
+MODULES= \
+ os_mon_SUITE \
+ disksup_SUITE \
+ memsup_SUITE \
+ cpu_sup_SUITE \
+ os_mon_mib_SUITE \
+ os_sup_SUITE \
+ os_mon_conf
+
+EBIN = .
+
+HRL_FILES=
+
+ERL_FILES= $(MODULES:%=%.erl)
+
+TARGET_FILES = $(MODULES:%=$(EBIN)/%.$(EMULATOR))
+
+SOURCE = $(ERL_FILES) $(HRL_FILES)
+
+EMAKEFILE=Emakefile
+
+# ----------------------------------------------------
+# Release directory specification
+# ----------------------------------------------------
+RELSYSDIR = $(RELEASE_PATH)/os_mon_test
+
+# ----------------------------------------------------
+# FLAGS
+# ----------------------------------------------------
+ERL_MAKE_FLAGS +=
+ERL_COMPILE_FLAGS += -I$(ERL_TOP)/lib/test_server/include \
+ -I$(ERL_TOP)/lib/snmp/include
+
+# ----------------------------------------------------
+# Targets
+# ----------------------------------------------------
+
+make_emakefile:
+ $(ERL_TOP)/make/make_emakefile $(ERL_COMPILE_FLAGS) -o$(EBIN) $(MODULES)\
+ > $(EMAKEFILE)
+
+tests debug opt: make_emakefile
+ erl $(ERL_MAKE_FLAGS) -make
+
+clean:
+ rm -f $(EMAKEFILE)
+ rm -f $(TARGET_FILES)
+ rm -f core *~
+
+docs:
+
+
+# ----------------------------------------------------
+# Release Target
+# ----------------------------------------------------
+include $(ERL_TOP)/make/otp_release_targets.mk
+
+release_spec:
+
+release_tests_spec: make_emakefile
+ $(INSTALL_DIR) $(RELSYSDIR)
+ $(INSTALL_DATA) os_mon.spec $(EMAKEFILE) $(SOURCE) $(RELSYSDIR)
+
+## tar chf - *_SUITE_data | (cd $(RELSYSDIR); tar xf -)
+
+release_docs_spec:
diff --git a/lib/os_mon/test/cpu_sup_SUITE.erl b/lib/os_mon/test/cpu_sup_SUITE.erl
new file mode 100644
index 0000000000..45f9d981d1
--- /dev/null
+++ b/lib/os_mon/test/cpu_sup_SUITE.erl
@@ -0,0 +1,282 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 2002-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(cpu_sup_SUITE).
+-include("test_server.hrl").
+
+%% Test server specific exports
+-export([all/1]).
+-export([init_per_suite/1, end_per_suite/1]).
+-export([init_per_testcase/2, end_per_testcase/2]).
+
+%% Test cases
+-export([load_api/1]).
+-export([util_api/1, util_values/1]).
+-export([port/1]).
+-export([terminate/1, unavailable/1, restart/1]).
+
+%% Default timetrap timeout (set in init_per_testcase)
+-define(default_timeout, ?t:minutes(1)).
+
+init_per_suite(Config) when is_list(Config) ->
+ ?line ok = application:start(os_mon),
+ Config.
+
+end_per_suite(Config) when is_list(Config) ->
+ ?line ok = application:stop(os_mon),
+ Config.
+
+init_per_testcase(_Case, Config) ->
+ Dog = ?t:timetrap(?default_timeout),
+ [{watchdog, Dog} | Config].
+
+end_per_testcase(_Case, Config) ->
+ Dog = ?config(watchdog, Config),
+ ?t:timetrap_cancel(Dog),
+ ok.
+
+all(suite) ->
+ case ?t:os_type() of
+ {unix, sunos} ->
+ [load_api, util_api, util_values, port,
+ {conf, terminate, [unavailable], restart}];
+ {unix, linux} ->
+ [load_api, util_api, util_values, port,
+ {conf, terminate, [unavailable], restart}];
+ {unix, _OSname} ->
+ [load_api];
+ _OS ->
+ [unavailable]
+ end.
+
+load_api(suite) ->
+ [];
+load_api(doc) ->
+ ["Test of load API functions"];
+load_api(Config) when is_list(Config) ->
+
+ %% nprocs()
+ ?line N = cpu_sup:nprocs(),
+ ?line true = is_integer(N),
+ ?line true = N>0,
+
+ %% avg1()
+ ?line Load1 = cpu_sup:avg1(),
+ ?line true = is_integer(Load1),
+ ?line true = Load1>0,
+
+ %% avg5()
+ ?line Load5 = cpu_sup:avg5(),
+ ?line true = is_integer(Load5),
+ ?line true = Load5>0,
+
+ %% avg15()
+ ?line Load15 = cpu_sup:avg15(),
+ ?line true = is_integer(Load15),
+ ?line true = Load15>0,
+
+ ok.
+
+util_api(suite) ->
+ [];
+util_api(doc) ->
+ ["Test of utilization API functions"];
+util_api(Config) when is_list(Config) ->
+ %% Some useful funs when testing util/1
+ BusyP = fun({user, _Share}) -> true;
+ ({nice_user, _Share}) -> true;
+ ({kernel, _Share}) -> true;
+ ({hard_irq, _Share}) -> true;
+ ({soft_irq, _Share}) -> true;
+ (_) -> false
+ end,
+ NonBusyP = fun({wait, _Share}) -> true;
+ ({idle, _Share}) -> true;
+ ({steal, _Share}) -> true;
+ (_) -> false
+ end,
+ Sum = fun({_Tag, X}, Acc) -> Acc+X end,
+
+ %% util()
+ ?line Util1 = cpu_sup:util(),
+ ?line true = is_number(Util1),
+ ?line true = Util1>0,
+ ?line Util2 = cpu_sup:util(),
+ ?line true = is_number(Util2),
+ ?line true = Util2>0,
+
+ %% util([])
+ ?line {all, Busy1, NonBusy1, []} = cpu_sup:util([]),
+ ?line 100.00 = Busy1 + NonBusy1,
+
+ %% util([detailed])
+ ?line {Cpus2, Busy2, NonBusy2, []} = cpu_sup:util([detailed]),
+ ?line true = lists:all(fun(X) -> is_integer(X) end, Cpus2),
+ ?line true = lists:all(BusyP, Busy2),
+ ?line true = lists:all(NonBusyP, NonBusy2),
+ ?line 100.00 = lists:foldl(Sum,0,Busy2)+lists:foldl(Sum,0,NonBusy2),
+
+ %% util([per_cpu])
+ ?line [{Cpu3, Busy3, NonBusy3, []}|_] = cpu_sup:util([per_cpu]),
+ ?line true = is_integer(Cpu3),
+ ?line 100.00 = Busy3 + NonBusy3,
+
+ %% util([detailed, per_cpu])
+ ?line [{Cpu4, Busy4, NonBusy4, []}|_] =
+ cpu_sup:util([detailed, per_cpu]),
+ ?line true = is_integer(Cpu4),
+ ?line true = lists:all(BusyP, Busy2),
+ ?line true = lists:all(NonBusyP, NonBusy2),
+ ?line 100.00 = lists:foldl(Sum,0,Busy4)+lists:foldl(Sum,0,NonBusy4),
+
+ %% bad util/1 calls
+ ?line {'EXIT',{badarg,_}} = (catch cpu_sup:util(detailed)),
+ ?line {'EXIT',{badarg,_}} = (catch cpu_sup:util([detialed])),
+
+ ok.
+
+-define(SPIN_TIME, 1000).
+
+util_values(suite) ->
+ [];
+util_values(doc) ->
+ ["Test utilization values"];
+util_values(Config) when is_list(Config) ->
+
+ Tester = self(),
+ Ref = make_ref(),
+ Loop = fun (L) -> L(L) end,
+ Spinner = fun () ->
+ Looper = spawn_link(fun () -> Loop(Loop) end),
+ receive after ?SPIN_TIME -> ok end,
+ unlink(Looper),
+ exit(Looper, kill),
+ Tester ! Ref
+ end,
+
+ ?line cpu_sup:util(),
+
+ ?line spawn_link(Spinner),
+ ?line receive Ref -> ok end,
+ ?line HighUtil1 = cpu_sup:util(),
+
+ ?line receive after ?SPIN_TIME -> ok end,
+ ?line LowUtil1 = cpu_sup:util(),
+
+ ?line spawn_link(Spinner),
+ ?line receive Ref -> ok end,
+ ?line HighUtil2 = cpu_sup:util(),
+
+ ?line receive after ?SPIN_TIME -> ok end,
+ ?line LowUtil2 = cpu_sup:util(),
+
+ Utils = [{high1,HighUtil1}, {low1,LowUtil1},
+ {high2,HighUtil2}, {low2,LowUtil2}],
+ ?t:format("Utils: ~p~n", [Utils]),
+
+ ?line false = LowUtil1 > HighUtil1,
+ ?line false = LowUtil1 > HighUtil2,
+ ?line false = LowUtil2 > HighUtil1,
+ ?line false = LowUtil2 > HighUtil2,
+
+ ok.
+
+
+% Outdated
+% The portprogram is now restarted if killed, and not by os_mon...
+
+port(suite) ->
+ [];
+port(doc) ->
+ ["Test that cpu_sup handles a terminating port program"];
+port(Config) when is_list(Config) ->
+ case cpu_sup_os_pid() of
+ {ok, PidStr} ->
+ %% Monitor cpu_sup
+ ?line MonRef = erlang:monitor(process, cpu_sup),
+ ?line N1 = cpu_sup:nprocs(),
+ ?line true = N1>0,
+
+ %% Kill the port program
+ case os:cmd("kill -9 " ++ PidStr) of
+ [] ->
+ %% cpu_sup should not terminate
+ receive
+ {'DOWN', MonRef, _, _, Reason} ->
+ ?line ?t:fail({unexpected_exit_reason, Reason})
+ after 3000 ->
+ ok
+ end,
+
+ %% Give cpu_sup time to restart cpu_sup port
+ ?t:sleep(?t:seconds(3)),
+ ?line N2 = cpu_sup:nprocs(),
+ ?line true = N2>0,
+
+ erlang:demonitor(MonRef),
+ ok;
+
+ Line ->
+ erlang:demonitor(MonRef),
+ {skip, {not_killed, Line}}
+ end;
+ _ ->
+ {skip, os_pid_not_found }
+ end.
+
+terminate(suite) ->
+ [];
+terminate(Config) when is_list(Config) ->
+ ?line ok = application:set_env(os_mon, start_cpu_sup, false),
+ ?line ok = supervisor:terminate_child(os_mon_sup, cpu_sup),
+ ok.
+
+unavailable(suite) ->
+ [];
+unavailable(doc) ->
+ ["Test correct behaviour when service is unavailable"];
+unavailable(Config) when is_list(Config) ->
+
+ %% Make sure all API functions return their dummy values
+ ?line 0 = cpu_sup:nprocs(),
+ ?line 0 = cpu_sup:avg1(),
+ ?line 0 = cpu_sup:avg5(),
+ ?line 0 = cpu_sup:avg15(),
+ ?line 0 = cpu_sup:util(),
+ ?line {all,0,0,[]} = cpu_sup:util([]),
+ ?line {all,0,0,[]} = cpu_sup:util([detailed]),
+ ?line {all,0,0,[]} = cpu_sup:util([per_cpu]),
+ ?line {all,0,0,[]} = cpu_sup:util([detailed,per_cpu]),
+
+ ok.
+
+restart(suite) ->
+ [];
+restart(Config) when is_list(Config) ->
+ ?line ok = application:set_env(os_mon, start_cpu_sup, true),
+ ?line {ok, _Pid} = supervisor:restart_child(os_mon_sup, cpu_sup),
+ ok.
+
+%% Aux
+
+cpu_sup_os_pid() ->
+ Str = os:cmd("ps -e | grep '[c]pu_sup'"),
+ case io_lib:fread("~s", Str) of
+ {ok, [Pid], _Rest} -> {ok, Pid};
+ _ -> {error, pid_not_found}
+ end.
diff --git a/lib/os_mon/test/disksup_SUITE.erl b/lib/os_mon/test/disksup_SUITE.erl
new file mode 100644
index 0000000000..987d631c36
--- /dev/null
+++ b/lib/os_mon/test/disksup_SUITE.erl
@@ -0,0 +1,426 @@
+%%
+%% %CopyrightBegin%
+%%
+%% 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
+%% 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(disksup_SUITE).
+-include("test_server.hrl").
+
+%% Test server specific exports
+-export([all/1]).
+-export([init_per_suite/1, end_per_suite/1]).
+-export([init_per_testcase/2, end_per_testcase/2]).
+
+%% Test cases
+-export([api/1, config/1, alarm/1]).
+-export([port/1]).
+-export([terminate/1, unavailable/1, restart/1]).
+-export([otp_5910/1]).
+
+%% Default timetrap timeout (set in init_per_testcase)
+-define(default_timeout, ?t:minutes(1)).
+
+init_per_suite(Config) when is_list(Config) ->
+ ?line ok = application:start(os_mon),
+ Config.
+
+end_per_suite(Config) when is_list(Config) ->
+ ?line ok = application:stop(os_mon),
+ Config.
+
+init_per_testcase(_Case, Config) ->
+ Dog = ?t:timetrap(?default_timeout),
+ [{watchdog,Dog} | Config].
+
+end_per_testcase(_Case, Config) ->
+ Dog = ?config(watchdog, Config),
+ ?t:timetrap_cancel(Dog),
+ ok.
+
+all(suite) ->
+ Bugs = [otp_5910],
+ case ?t:os_type() of
+ {unix, sunos} ->
+ [api, config, alarm, port,
+ {conf, terminate, [unavailable], restart}] ++ Bugs;
+ {unix, _OSname} ->
+ [api, alarm] ++ Bugs;
+ {win32, _OSname} ->
+ [api, alarm] ++ Bugs;
+ _OS ->
+ [unavailable]
+ end.
+
+api(suite) ->
+ [];
+api(doc) ->
+ ["Test of API functions"];
+api(Config) when is_list(Config) ->
+
+ %% get_disk_data()
+ ?line [{Id, KByte, Capacity}|_] = disksup:get_disk_data(),
+ ?line true = io_lib:printable_list(Id),
+ ?line true = is_integer(KByte),
+ ?line true = is_integer(Capacity),
+ ?line true = KByte>0,
+ ?line true = Capacity>0,
+
+ %% get_check_interval()
+ ?line 1800000 = disksup:get_check_interval(),
+
+ %% set_check_interval(Minutes)
+ ?line ok = disksup:set_check_interval(20),
+ ?line 1200000 = disksup:get_check_interval(),
+ ?line {'EXIT',{badarg,_}} = (catch disksup:set_check_interval(0.5)),
+ ?line 1200000 = disksup:get_check_interval(),
+ ?line ok = disksup:set_check_interval(30),
+
+ %% get_almost_full_threshold()
+ ?line 80 = disksup:get_almost_full_threshold(),
+
+ %% set_almost_full_threshold(Float)
+ ?line ok = disksup:set_almost_full_threshold(0.90),
+ ?line 90 = disksup:get_almost_full_threshold(),
+ ?line {'EXIT',{badarg,_}} =
+ (catch disksup:set_almost_full_threshold(-0.5)),
+ ?line 90 = disksup:get_almost_full_threshold(),
+ ?line ok = disksup:set_almost_full_threshold(0.80),
+
+ ok.
+
+config(suite) ->
+ [];
+config(doc) ->
+ ["Test configuration"];
+config(Config) when is_list(Config) ->
+
+ %% Change configuration parameters and make sure change is reflected
+ %% when disksup is restarted
+ ?line ok =
+ application:set_env(os_mon, disk_space_check_interval, 29),
+ ?line ok =
+ application:set_env(os_mon, disk_almost_full_threshold, 0.81),
+
+ ?line ok = supervisor:terminate_child(os_mon_sup, disksup),
+ ?line {ok, _Child1} = supervisor:restart_child(os_mon_sup, disksup),
+
+ ?line 1740000 = disksup:get_check_interval(),
+ ?line 81 = disksup:get_almost_full_threshold(),
+
+ %% Also try this with bad parameter values, should be ignored
+ ?line ok =
+ application:set_env(os_mon, disk_space_check_interval, 0.5),
+ ?line ok =
+ application:set_env(os_mon, disk_almost_full_threshold, -0.81),
+
+ ?line ok = supervisor:terminate_child(os_mon_sup, disksup),
+ ?line {ok, _Child2} = supervisor:restart_child(os_mon_sup, disksup),
+
+ ?line 1800000 = disksup:get_check_interval(),
+ ?line 80 = disksup:get_almost_full_threshold(),
+
+ %% Reset configuration parameters
+ ?line ok =
+ application:set_env(os_mon, disk_space_check_interval, 30),
+ ?line ok =
+ application:set_env(os_mon, disk_almost_full_threshold, 0.80),
+
+ ok.
+
+%%----------------------------------------------------------------------
+%% NOTE: The test case is a bit weak as it will fail if the disk usage
+%% changes too much during its course, or if there are timing problems
+%% with the alarm_handler receiving the alarms too late
+%%----------------------------------------------------------------------
+alarm(suite) ->
+ [];
+alarm(doc) ->
+ ["Test that alarms are set and cleared"];
+alarm(Config) when is_list(Config) ->
+
+ %% Find out how many disks exceed the threshold
+ %% and make sure the corresponding number of alarms is set
+ ?line Threshold1 = disksup:get_almost_full_threshold(), % 80
+ ?line Data1 = disksup:get_disk_data(),
+ ?line Over1 = over_threshold(Data1, Threshold1),
+ ?line Alarms1 = get_alarms(),
+ if
+ Over1==length(Alarms1) ->
+ ?line true;
+ true ->
+ dump_info(),
+ ?line ?t:fail({bad_alarms, Threshold1, Data1, Alarms1})
+ end,
+
+ %% Try to find a disk with space usage below Threshold1,
+ %% lower the threshold accordingly and make sure new alarms are set
+ Fun1 = fun({_Id, _Kbyte, Capacity}) ->
+ if
+ Capacity>0, Capacity<Threshold1 -> true;
+ true -> false
+ end
+ end,
+ ?line case until(Fun1, Data1) of
+ {_, _, Cap1} ->
+ Threshold2 = Cap1-1,
+ ?line ok =
+ disksup:set_almost_full_threshold(Threshold2/100),
+ ?line disksup ! timeout, % force a disk check
+ ?line Data2 = disksup:get_disk_data(),
+ ?line Over2 = over_threshold(Data2, Threshold2),
+ ?line Alarms2 = get_alarms(),
+ if
+ Over2==length(Alarms2), Over2>Over1 ->
+ ?line true;
+ true ->
+ dump_info(),
+ ?line ?t:fail({bad_alarms, Threshold2, Data2, Alarms2})
+ end;
+ false ->
+ ?line ignore
+ end,
+
+ %% Find out the highest space usage among all disks
+ %% and try to raise the threshold above this value,
+ %% make sure all alarms are cleared
+ Fun2 = fun({_Id, _Kbyte, Capacity}, MaxAcc) ->
+ if
+ Capacity>MaxAcc -> Capacity;
+ true -> MaxAcc
+ end
+ end,
+ ?line case lists:foldl(Fun2, 0, Data1) of
+ Max when Max<100 ->
+ Threshold3 = Max+1,
+ ?line ok =
+ disksup:set_almost_full_threshold(Threshold3/100),
+ ?line disksup ! timeout, % force a disk check
+ ?line Data3 = disksup:get_disk_data(),
+ ?line Over3 = over_threshold(Data3, Threshold3),
+ ?line Alarms3 = get_alarms(),
+ if
+ Over3==0, length(Alarms3)==0 ->
+ ?line ok;
+ true ->
+ dump_info(),
+ ?line ?t:fail({bad_alarms, Threshold3, Data3, Alarms3})
+ end;
+ 100 ->
+ ?line ignore
+ end,
+
+ %% Reset threshold
+ ?line ok = disksup:set_almost_full_threshold(Threshold1/100),
+
+ ok.
+
+over_threshold(Data, Threshold) ->
+ Data2 = remove_duplicated_disks(lists:keysort(1, Data)),
+ lists:foldl(fun({_Id, _Kbyte, Cap}, N) when Cap>=Threshold ->
+ N+1;
+ (_DiskData, N) ->
+ N
+ end,
+ 0,
+ Data2).
+
+%% On some platforms (for example MontaVista) data for one disk can be
+%% "duplicated":
+%% Linux ppb 2.4.20_mvl31-pcore680 #1 Sun Feb 1 23:12:56 PST 2004 ppc unknown
+%%
+%% MontaVista(R) Linux(R) Professional Edition 3.1
+%%
+%% [ppb:~]> /bin/df -lk
+%% Filesystem 1k-blocks Used Available Use% Mounted on
+%% rootfs 8066141 3023763 4961717 38% /
+%% /dev/root 8066141 3023763 4961717 38% /
+%% tmpfs 192892 0 192892 0% /dev/shm
+%%
+%% disksup:
+%% [{"/",8066141,38}, {"/",8066141,38}, {"/dev/shm",192892,0}]
+%%
+%% disksup will only set ONE alarm for "/".
+%% Therefore the list of disk data must be sorted and duplicated disk
+%% tuples removed before calculating how many alarms should be set, or
+%% the testcase will fail erroneously.
+remove_duplicated_disks([{Id, _, _}, {Id, Kbyte, Cap}|T]) ->
+ remove_duplicated_disks([{Id, Kbyte, Cap}|T]);
+remove_duplicated_disks([H|T]) ->
+ [H|remove_duplicated_disks(T)];
+remove_duplicated_disks([]) ->
+ [].
+
+get_alarms() ->
+ lists:filter(fun({{disk_almost_full, _Disk},_}) -> true;
+ (_) -> false
+ end,
+ alarm_handler:get_alarms()).
+
+until(Fun, [H|T]) ->
+ case Fun(H) of
+ true -> H;
+ false ->
+ until(Fun, T)
+ end;
+until(_Fun, []) ->
+ false.
+
+port(suite) ->
+ [];
+port(doc) ->
+ ["Test that disksup handles a terminating port program"];
+port(Config) when is_list(Config) ->
+ ?line Str = os:cmd("ps -ef | grep '[d]isksup'"),
+ case io_lib:fread("~s ~s", Str) of
+ {ok, [_Uid,Pid], _Rest} ->
+
+ %% Monitor disksup
+ ?line MonRef = erlang:monitor(process, disksup),
+ ?line [{_Disk1,Kbyte1,_Cap1}|_] = disksup:get_disk_data(),
+ ?line true = Kbyte1>0,
+
+ %% Kill the port program
+ case os:cmd("kill -9 " ++ Pid) of
+ [] ->
+
+ %% disksup should now terminate
+ receive
+ {'DOWN', MonRef, _, _, {port_died, _Reason}} ->
+ ok;
+ {'DOWN', MonRef, _, _, Reason} ->
+ ?line ?t:fail({unexpected_exit_reason, Reason})
+ after
+ 3000 ->
+ ?line ?t:fail({still_alive, Str})
+ end,
+
+ %% Give os_mon_sup time to restart disksup
+ ?t:sleep(?t:seconds(3)),
+ ?line [{_Disk2,Kbyte2,_Cap2}|_] =
+ disksup:get_disk_data(),
+ ?line true = Kbyte2>0,
+
+ ok;
+
+ Line ->
+ erlang:demonitor(MonRef),
+ {skip, {not_killed, Line}}
+ end;
+ _ ->
+ {skip, {os_pid_not_found, Str}}
+ end.
+
+terminate(suite) ->
+ [];
+terminate(Config) when is_list(Config) ->
+ ?line ok = application:set_env(os_mon, start_disksup, false),
+ ?line ok = supervisor:terminate_child(os_mon_sup, disksup),
+ ok.
+
+unavailable(suite) ->
+ [];
+unavailable(doc) ->
+ ["Test correct behaviour when service is unavailable"];
+unavailable(Config) when is_list(Config) ->
+
+ %% Make sure all API functions return their dummy values
+ ?line [{"none",0,0}] = disksup:get_disk_data(),
+ ?line 1800000 = disksup:get_check_interval(),
+ ?line ok = disksup:set_check_interval(5),
+ ?line 80 = disksup:get_almost_full_threshold(),
+ ?line ok = disksup:set_almost_full_threshold(0.9),
+
+ ok.
+
+restart(suite) ->
+ [];
+restart(Config) when is_list(Config) ->
+ ?line ok = application:set_env(os_mon, start_disksup, true),
+ ?line {ok, _Pid} = supervisor:restart_child(os_mon_sup, disksup),
+ ok.
+
+otp_5910(suite) ->
+ [];
+otp_5910(doc) ->
+ ["Test that alarms are cleared if disksup crashes or "
+ "if OS_Mon is stopped"];
+otp_5910(Config) when is_list(Config) ->
+
+ %% Make sure disksup sets at least one alarm
+ ?line Data = disksup:get_disk_data(),
+ ?line Threshold0 = disksup:get_almost_full_threshold(),
+ ?line Threshold = case over_threshold(Data, Threshold0) of
+ 0 ->
+ [{_Id,_Kbyte,Cap}|_] = Data,
+ ?line ok = disksup:set_almost_full_threshold((Cap-1)/100),
+ Cap-1;
+ _N ->
+ Threshold0
+ end,
+ ?line ok = application:set_env(os_mon,
+ disk_almost_full_threshold,
+ Threshold/100),
+ ?line disksup ! timeout, % force a disk check
+ ?line Data2 = disksup:get_disk_data(),
+ ?line Over = over_threshold(Data2, Threshold),
+ ?line Alarms = get_alarms(),
+ if
+ Over==0 ->
+ ?line ?t:fail({threshold_too_low, Data2, Threshold});
+ Over==length(Alarms) ->
+ ok;
+ true ->
+ dump_info(),
+ ?line ?t:fail({bad_alarms, Threshold, Data2, Alarms})
+ end,
+
+ %% Kill disksup
+ exit(whereis(disksup), faked_disksup_crash),
+
+ %% Wait a little to make sure disksup has been restarted,
+ %% then make sure the alarms are set once, but not twice
+ ?t:sleep(?t:seconds(1)),
+ ?line Data3 = disksup:get_disk_data(),
+ ?line Alarms2 = get_alarms(),
+ if
+ length(Alarms2)==length(Alarms) ->
+ ok;
+ true ->
+ dump_info(),
+ ?line ?t:fail({bad_alarms, Threshold, Data3, Alarms,Alarms2})
+ end,
+
+ %% Stop OS_Mon and make sure all disksup alarms are cleared
+ ?line ok = application:stop(os_mon),
+ ?t:sleep(?t:seconds(1)),
+ ?line Alarms3 = get_alarms(),
+ if
+ length(Alarms3)==0 ->
+ ok;
+ true ->
+ ?line ?t:fail({alarms_not_cleared, Alarms3})
+ end,
+
+ %% Reset threshold and restart OS_Mon
+ ?line ok = application:set_env(os_mon,
+ disksup_almost_full_threshold, 0.8),
+ ?line ok = disksup:set_almost_full_threshold(0.8),
+ ?line ok = application:start(os_mon),
+
+ ok.
+
+dump_info() ->
+ io:format("Status: ~p~n", [sys:get_status(disksup)]).
diff --git a/lib/os_mon/test/memsup_SUITE.erl b/lib/os_mon/test/memsup_SUITE.erl
new file mode 100644
index 0000000000..01a7f6c7f2
--- /dev/null
+++ b/lib/os_mon/test/memsup_SUITE.erl
@@ -0,0 +1,782 @@
+%%
+%% %CopyrightBegin%
+%%
+%% 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
+%% 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(memsup_SUITE).
+-include("test_server.hrl").
+
+%% Test server specific exports
+-export([all/1]).
+-export([init_per_suite/1, end_per_suite/1]).
+-export([init_per_testcase/2, end_per_testcase/2]).
+
+%% Test cases
+-export([api/1, alarm1/1, alarm2/1, process/1]).
+-export([config/1, timeout/1, unavailable/1, port/1]).
+-export([otp_5910/1]).
+
+%% Default timetrap timeout (set in init_per_testcase)
+-define(default_timeout, ?t:minutes(1)).
+
+init_per_suite(Config) when is_list(Config) ->
+ ?line ok = application:start(os_mon),
+ Config.
+
+end_per_suite(Config) when is_list(Config) ->
+ ?line ok = application:stop(os_mon),
+ Config.
+
+init_per_testcase(_Case, Config) ->
+ Dog = ?t:timetrap(?default_timeout),
+ [{watchdog,Dog} | Config].
+
+end_per_testcase(_Case, Config) ->
+ Dog = ?config(watchdog, Config),
+ ?t:timetrap_cancel(Dog),
+ Config.
+
+all(suite) ->
+ All = case ?t:os_type() of
+ {unix, sunos} ->
+ [api, alarm1, alarm2, process,
+ config, timeout, unavailable, port];
+ {unix, linux} ->
+ [api, alarm1, alarm2, process, timeout];
+ _OS ->
+ [api, alarm1, alarm2, process]
+ end,
+ Bugs = [otp_5910],
+ All ++ Bugs.
+
+api(suite) ->
+ [];
+api(doc) ->
+ ["Test of API functions"];
+api(Config) when is_list(Config) ->
+
+ %% get_memory_data()
+ ?line RegMemData = memsup:get_memory_data(),
+ case RegMemData of
+ {TotMem, AllBytes, {Pid, PidBytes}} when is_integer(TotMem),
+ is_integer(AllBytes),
+ is_pid(Pid),
+ is_integer(PidBytes) ->
+ ok;
+ {0, 0, _WorstPid} ->
+ ?line ?t:fail(first_data_collection_failed);
+ _ ->
+ ?line ?t:fail({bad_return, RegMemData})
+ end,
+
+ %% get_system_memory_data()
+ ?line ExtMemData = memsup:get_system_memory_data(),
+ Tags = [ total_memory,
+ free_memory,
+ system_total_memory,
+ largest_free,
+ number_of_free,
+ free_swap,
+ total_swap,
+ cached_memory,
+ buffered_memory,
+ shared_memory],
+
+ ?line true = lists:all(fun({Tag,Value}) when is_atom(Tag),
+ is_integer(Value) ->
+ lists:member(Tag, Tags);
+ (_) ->
+ false
+ end,
+ ExtMemData),
+
+ %% get_os_wordsize()
+ ?line ok = case memsup:get_os_wordsize() of
+ 32 -> ok;
+ 64 -> ok;
+ unsupported_os -> ok;
+ _ -> error
+ end,
+
+ %% get_check_interval()
+ ?line 60000 = memsup:get_check_interval(),
+
+ %% set_check_interval(Minutes)
+ ?line ok = memsup:set_check_interval(2),
+ ?line 120000 = memsup:get_check_interval(),
+ ?line {'EXIT',{badarg,_}} =
+ (catch memsup:set_check_interval(0.2)),
+ ?line 120000 = memsup:get_check_interval(),
+ ?line ok = memsup:set_check_interval(1),
+
+ %% get_procmem_high_watermark()
+ ?line 5 = memsup:get_procmem_high_watermark(),
+
+ %% set_procmem_high_watermark()
+ ?line ok = memsup:set_procmem_high_watermark(0.1),
+ ?line 10 = memsup:get_procmem_high_watermark(),
+ ?line {'EXIT',{badarg,_}} =
+ (catch memsup:set_procmem_high_watermark(-0.1)),
+ ?line 10 = memsup:get_procmem_high_watermark(),
+ ?line ok = memsup:set_procmem_high_watermark(0.05),
+
+ %% get_sysmem_high_watermark()
+ ?line 80 = memsup:get_sysmem_high_watermark(),
+
+ %% set_sysmem_high_watermark()
+ ?line ok = memsup:set_sysmem_high_watermark(0.9),
+ ?line 90 = memsup:get_sysmem_high_watermark(),
+ ?line {'EXIT',{badarg,_}} =
+ (catch memsup:set_sysmem_high_watermark(-0.9)),
+ ?line 90 = memsup:get_sysmem_high_watermark(),
+ ?line ok = memsup:set_sysmem_high_watermark(0.8),
+
+ %% get|set_helper_timeout
+ ?line 30 = memsup:get_helper_timeout(),
+ ?line ok = memsup:set_helper_timeout(29),
+ ?line 29 = memsup:get_helper_timeout(),
+ ?line {'EXIT',{badarg,_}} = (catch memsup:set_helper_timeout(31.0)),
+ ?line 29 = memsup:get_helper_timeout(),
+ ok.
+
+%%----------------------------------------------------------------------
+%% NOTE: The test case is a bit weak as it will fail if the memory
+%% usage changes too much during its course.
+%%----------------------------------------------------------------------
+alarm1(suite) ->
+ [];
+alarm1(doc) ->
+ ["Test alarms when memsup_system_only==false"];
+alarm1(Config) when is_list(Config) ->
+
+ %% If system memory usage is too high, the testcase cannot
+ %% be run correctly
+ ?line {Total, Alloc, {_Pid,_PidAlloc}} = memsup:get_memory_data(),
+ io:format("alarm1: Total: ~p, Alloc: ~p~n", [Total, Alloc]),
+ ?line SysUsage = Alloc/Total,
+ if
+ SysUsage>0.99 ->
+ {skip, sys_mem_too_high};
+ true ->
+ alarm1(Config, SysUsage)
+ end.
+
+alarm1(_Config, SysUsage) ->
+ %% Set a long memory check interval, we will force memory checks
+ %% instead
+ ?line ok = memsup:set_check_interval(60),
+
+ %% Check thresholds
+ ?line SysThreshold = (memsup:get_sysmem_high_watermark()/100),
+ ?line ProcThreshold = (memsup:get_procmem_high_watermark()/100),
+
+ %% Check if a system alarm already should be set or not
+ SysP = if
+ SysUsage>SysThreshold -> true;
+ SysUsage=<SysThreshold -> false
+ end,
+
+ %% If system memory is higher than threshold, make sure the system
+ %% alarm is set. Otherwise, make sure it is not set
+ case alarm_set(system_memory_high_watermark) of
+ {true, []} when SysP ->
+ ok;
+ false when not SysP ->
+ ok;
+ _ ->
+ ?line ?t:fail({sys_alarm, SysUsage, SysThreshold})
+ end,
+
+ %% Lower/raise the threshold to clear/set the alarm
+ NewSysThreshold = if
+ SysP ->
+ Value = 1.1*SysUsage,
+ if
+ Value > 0.99 -> 0.99;
+ true -> Value
+ end;
+ not SysP -> 0.9*SysUsage
+ end,
+
+ ?line ok = memsup:set_sysmem_high_watermark(NewSysThreshold),
+
+ %% Initiate and wait for a new data collection
+ ?line ok = force_collection(),
+
+ %% Make sure the alarm is cleared/set
+ ?t:sleep(?t:seconds(5)),
+ case alarm_set(system_memory_high_watermark) of
+ {true, []} when not SysP ->
+ ok;
+ false when SysP ->
+ ok;
+ _ ->
+ ?line ?t:fail({sys_alarm, SysUsage, NewSysThreshold})
+ end,
+
+ %% Reset the threshold to set/clear the alarm again
+ ?line ok = memsup:set_sysmem_high_watermark(SysThreshold),
+ ?line ok = force_collection(),
+ ?t:sleep(?t:seconds(1)),
+ case alarm_set(system_memory_high_watermark) of
+ {true, []} when SysP ->
+ ok;
+ false when not SysP ->
+ ok;
+ _ ->
+ ?line ?t:fail({sys_alarm, SysUsage, SysThreshold})
+ end,
+
+ %% Check memory usage
+ ?line {Total2, _, {WorstPid, PidAlloc}} = memsup:get_memory_data(),
+
+ %% Check if a process alarm already should be set or not
+ PidUsage = PidAlloc/Total2,
+ ProcP = if
+ PidUsage>ProcThreshold -> true;
+ PidUsage=<ProcThreshold -> false
+ end,
+
+ %% Make sure the process alarm is set/not set accordingly
+ case alarm_set(process_memory_high_watermark) of
+ {true, WorstPid} when ProcP ->
+ ok;
+ false when not ProcP ->
+ ok;
+ {true, BadPid1} when ProcP ->
+ ?line ?t:fail({proc_alarm, WorstPid, BadPid1});
+ _ ->
+ ?line ?t:fail({proc_alarm, PidUsage, ProcThreshold})
+ end,
+
+ %% Lower/raise the threshold to clear/set the alarm
+ NewProcThreshold = if
+ ProcP -> 1.1*PidUsage;
+ not ProcP -> 0.9*PidUsage
+ end,
+ ?line ok = memsup:set_procmem_high_watermark(NewProcThreshold),
+ ?line ok = force_collection(),
+ ?t:sleep(?t:seconds(1)),
+ case alarm_set(process_memory_high_watermark) of
+ {true, WorstPid} when not ProcP ->
+ ok;
+ false when ProcP ->
+ ok;
+ {true, BadPid2} when not ProcP ->
+ ?line test_server:fail({proc_alarm, WorstPid, BadPid2});
+ _ ->
+ ?line ?t:fail({proc_alarm, PidUsage, ProcThreshold})
+ end,
+
+ %% Reset the threshold to clear/set the alarm
+ ?line ok = memsup:set_procmem_high_watermark(ProcThreshold),
+ ?line ok = force_collection(),
+ ?t:sleep(?t:seconds(1)),
+ case alarm_set(process_memory_high_watermark) of
+ {true, WorstPid} when ProcP ->
+ ok;
+ false when not ProcP ->
+ ok;
+ {true, BadPid3} when ProcP ->
+ ?line test_server:fail({proc_alarm, WorstPid, BadPid3});
+ _ ->
+ ?line ?t:fail({proc_alarm, PidUsage, ProcThreshold})
+ end,
+
+ %% Reset memory check interval
+ ?line ok = memsup:set_check_interval(1),
+ ok.
+
+alarm2(suite) ->
+ [];
+alarm2(doc) ->
+ ["Test alarms when memsup_system_only==true"];
+alarm2(Config) when is_list(Config) ->
+
+ %% If system memory usage is too high, the testcase cannot
+ %% be run correctly
+ ?line {Total, Alloc, {_Pid,_PidAlloc}} = memsup:get_memory_data(),
+ ?line SysUsage = Alloc/Total,
+ if
+ SysUsage>0.99 ->
+ {skip, sys_mem_too_high};
+ true ->
+ alarm2(Config, SysUsage)
+ end.
+
+alarm2(_Config, _SysUsage) ->
+
+ %% Change memsup_system_only and restart memsup
+ ?line ok = application:set_env(os_mon, memsup_system_only, true),
+ ?line ok = supervisor:terminate_child(os_mon_sup, memsup),
+ ?line {ok, _Memsup1} = supervisor:restart_child(os_mon_sup, memsup),
+
+ %% Set a long memory check interval, we will force memory checks
+ %% instead
+ ?line ok = memsup:set_check_interval(60),
+
+ %% Check data and thresholds
+ ?line {Total, Alloc, undefined} = memsup:get_memory_data(),
+ ?line SysThreshold = (memsup:get_sysmem_high_watermark()/100),
+ ?line true = is_integer(memsup:get_procmem_high_watermark()),
+
+ %% Check if a system alarm already should be set or not
+ ?line SysUsage = Alloc/Total,
+ SysP = if
+ SysUsage>SysThreshold -> true;
+ SysUsage=<SysThreshold -> false
+ end,
+
+ %% If system memory is higher than threshold, make sure the system
+ %% alarm is set. Otherwise, make sure it is not set
+ case alarm_set(system_memory_high_watermark) of
+ {true, []} when SysP ->
+ ok;
+ false when not SysP ->
+ ok;
+ _ ->
+ ?line ?t:fail({sys_alarm, SysUsage, SysThreshold})
+ end,
+
+ %% Lower/raise the threshold to clear/set the alarm
+ NewSysThreshold = if
+ SysP ->
+ Value = 1.1*SysUsage,
+ if
+ Value > 0.99 -> 0.99;
+ true -> Value
+ end;
+ not SysP -> 0.9*SysUsage
+ end,
+
+ ?line ok = memsup:set_sysmem_high_watermark(NewSysThreshold),
+
+ %% Initiate and wait for a new data collection
+ ?line ok = force_collection(),
+
+ %% Make sure the alarm is cleared/set
+ ?t:sleep(?t:seconds(1)),
+ case alarm_set(system_memory_high_watermark) of
+ {true, []} when not SysP ->
+ ok;
+ false when SysP ->
+ ok;
+ _ ->
+ ?line ?t:fail({sys_alarm, SysUsage, NewSysThreshold})
+ end,
+
+ %% Reset the threshold to set/clear the alarm again
+ ?line ok = memsup:set_sysmem_high_watermark(SysThreshold),
+ ?line ok = force_collection(),
+ ?t:sleep(?t:seconds(1)),
+ case alarm_set(system_memory_high_watermark) of
+ {true, []} when SysP ->
+ ok;
+ false when not SysP ->
+ ok;
+ _ ->
+ ?line ?t:fail({sys_alarm, SysUsage, SysThreshold})
+ end,
+
+ %% Reset memsup_system_only and restart memsup
+ %% (memory check interval is then automatically reset)
+ ?line ok = application:set_env(os_mon, memsup_system_only, false),
+ ?line ok = supervisor:terminate_child(os_mon_sup, memsup),
+ ?line {ok, _Memsup2} = supervisor:restart_child(os_mon_sup, memsup),
+
+ ok.
+
+alarm_set(Alarm) ->
+ alarm_set(Alarm, alarm_handler:get_alarms()).
+alarm_set(Alarm, [{Alarm,Data}|_]) ->
+ {true,Data};
+alarm_set(Alarm, [_|T]) ->
+ alarm_set(Alarm, T);
+alarm_set(_Alarm, []) ->
+ false.
+
+process(suite) ->
+ [];
+process(doc) ->
+ ["Make sure memsup discovers a process grown very large"];
+process(Config) when is_list(Config) ->
+
+ %% Set a long memory check interval, we will force memory checks
+ %% instead
+ ?line ok = memsup:set_check_interval(60),
+
+ %% Collect data
+ MemData = memsup:get_memory_data(),
+ io:format("process: memsup:get_memory_data() = ~p~n", [MemData]),
+ ?line {_Total,_Free,{_,Bytes}} = MemData,
+
+ %% Start a new process larger than Worst
+ ?line WorsePid = spawn(fun() -> new_hog(Bytes) end),
+ ?t:sleep(?t:seconds(1)),
+
+ %% Initiate and wait for a new data collection
+ ?line ok = force_collection(),
+
+ %% Check that get_memory_data() returns updated result
+ ?line case memsup:get_memory_data() of
+ {_, _, {WorsePid, _MoreBytes}} ->
+ ok;
+ {_, _, BadWorst} ->
+ ?line ?t:fail({worst_pid, BadWorst})
+ end,
+
+ %% Reset memory check interval
+ ?line exit(WorsePid, done),
+ ?line ok = memsup:set_check_interval(1),
+ ok.
+
+new_hog(Bytes) ->
+ WordSize = erlang:system_info(wordsize),
+ N = (Bytes+200) div WordSize div 2,
+ List = lists:duplicate(N, a),
+ new_hog_1(List).
+
+new_hog_1(List) ->
+ receive
+ _Any -> exit(List)
+ end.
+
+config(suite) ->
+ [];
+config(doc) ->
+ ["Test configuration"];
+config(Config) when is_list(Config) ->
+
+ %% Change configuration parameters and make sure change is reflected
+ %% when memsup is restarted
+ ?line ok = application:set_env(os_mon, memory_check_interval, 2),
+ ?line ok =
+ application:set_env(os_mon, system_memory_high_watermark, 0.9),
+ ?line ok =
+ application:set_env(os_mon, process_memory_high_watermark, 0.1),
+ ?line ok = application:set_env(os_mon, memsup_helper_timeout, 35),
+ ?line ok = application:set_env(os_mon, memsup_system_only, true),
+
+ ?line ok = supervisor:terminate_child(os_mon_sup, memsup),
+ ?line {ok, _Child1} = supervisor:restart_child(os_mon_sup, memsup),
+
+ ?line 120000 = memsup:get_check_interval(),
+ ?line 90 = memsup:get_sysmem_high_watermark(),
+ ?line 10 = memsup:get_procmem_high_watermark(),
+ ?line 35 = memsup:get_helper_timeout(),
+
+ %% Also try this with bad parameter values, should be ignored
+ ?line ok = application:set_env(os_mon, memory_check_interval, 0.2),
+ ?line ok =
+ application:set_env(os_mon, system_memory_high_watermark, -0.9),
+ ?line ok =
+ application:set_env(os_mon, process_memory_high_watermark,-0.1),
+ ?line ok = application:set_env(os_mon, memsup_helper_timeout, 0.35),
+ ?line ok = application:set_env(os_mon, memsup_system_only, arne),
+
+ ?line ok = supervisor:terminate_child(os_mon_sup, memsup),
+ ?line {ok, _Child2} = supervisor:restart_child(os_mon_sup, memsup),
+
+ ?line 60000 = memsup:get_check_interval(),
+ ?line 80 = memsup:get_sysmem_high_watermark(),
+ ?line 5 = memsup:get_procmem_high_watermark(),
+ ?line 30 = memsup:get_helper_timeout(),
+
+ %% Reset configuration parameters
+ ?line ok = application:set_env(os_mon, memory_check_interval, 1),
+ ?line ok =
+ application:set_env(os_mon, system_memory_high_watermark, 0.8),
+ ?line ok =
+ application:set_env(os_mon, process_memory_high_watermark,0.05),
+ ?line ok = application:set_env(os_mon, memsup_helper_timeout, 30),
+ ?line ok = application:set_env(os_mon, memsup_system_only, false),
+
+ ok.
+
+unavailable(suite) ->
+ [];
+unavailable(doc) ->
+ ["Test correct behaviour when service is unavailable"];
+unavailable(Config) when is_list(Config) ->
+
+ %% Close memsup
+ ?line ok = application:set_env(os_mon, start_memsup, false),
+ ?line ok = supervisor:terminate_child(os_mon_sup, memsup),
+
+ %% Make sure all API functions return their dummy values
+ ?line {0,0,{_Pid,0}} = memsup:get_memory_data(),
+ ?line ok = application:set_env(os_mon, memsup_system_only, true),
+ ?line {0,0,undefined} = memsup:get_memory_data(),
+ ?line ok = application:set_env(os_mon, memsup_system_only, false),
+ ?line [] = memsup:get_system_memory_data(),
+ ?line 0 = memsup:get_os_wordsize(),
+ ?line 60000 = memsup:get_check_interval(),
+ ?line ok = memsup:set_check_interval(2),
+ ?line 5 = memsup:get_procmem_high_watermark(),
+ ?line ok = memsup:set_procmem_high_watermark(0.10),
+ ?line 80 = memsup:get_sysmem_high_watermark(),
+ ?line ok = memsup:set_sysmem_high_watermark(0.90),
+ ?line 30 = memsup:get_helper_timeout(),
+ ?line ok = memsup:set_helper_timeout(35),
+
+ %% Start memsup again,
+ ?line ok = application:set_env(os_mon, start_memsup, true),
+ ?line {ok, _Child} = supervisor:restart_child(os_mon_sup, memsup),
+
+ ok.
+
+timeout(suite) ->
+ [];
+timeout(doc) ->
+ ["Test stability of memsup when data collection times out"];
+timeout(Config) when is_list(Config) ->
+
+ %% Set a long memory check interval and memsup_helper timeout,
+ %% we will force memory checks instead and fake timeouts
+ ?line ok = memsup:set_check_interval(60),
+ ?line ok = memsup:set_helper_timeout(3600),
+
+ %% Provoke a timeout during memory collection
+ ?line memsup ! time_to_collect,
+ ?line memsup ! reg_collection_timeout,
+
+ %% Not much we can check though, except that memsup is still running
+ ?line {_,_,_} = memsup:get_memory_data(),
+
+ %% Provoke a timeout during extensive memory collection
+ %% We fake a gen_server:call/2 to be able to send a timeout message
+ %% while the request is being handled
+
+ %% Linux should be handled the same way as solaris.
+
+% TimeoutMsg = case ?t:os_type() of
+% {unix, sunos} -> ext_collection_timeout;
+% {unix, linux} -> reg_collection_timeout
+% end,
+
+ TimeoutMsg = ext_collection_timeout,
+
+ ?line Pid = whereis(memsup),
+ ?line Mref = erlang:monitor(process, Pid),
+ ?line Pid ! {'$gen_call', {self(), Mref}, get_system_memory_data},
+ ?line Pid ! TimeoutMsg,
+ receive
+ {Mref, []} ->
+ erlang:demonitor(Mref),
+ ?line ok;
+ {Mref, Res} ->
+ erlang:demonitor(Mref),
+ ?line ?t:fail({unexpected_result, Res});
+ {'DOWN', Mref, _, _, _} ->
+ ?line ?t:fail(no_result)
+ end,
+
+ %% Reset memory check interval and memsup_helper timeout
+ ?line ok = memsup:set_check_interval(1),
+ ?line ok = memsup:set_helper_timeout(30),
+ ?line memsup ! time_to_collect,
+
+ ?line [_|_] = memsup:get_system_memory_data(),
+
+ ok.
+
+port(suite) ->
+ [];
+port(doc) ->
+ ["Test that memsup handles a terminating port program"];
+port(Config) when is_list(Config) ->
+ ?line Str = os:cmd("ps -e | grep '[m]emsup'"),
+ case io_lib:fread("~s", Str) of
+ {ok, [Pid], _Rest} ->
+
+ %% Monitor memsup
+ ?line MonRef = erlang:monitor(process, memsup),
+ ?line {Total1,_Alloc1,_Worst1} = memsup:get_memory_data(),
+ ?line true = Total1>0,
+
+ %% Kill the port program
+ case os:cmd("kill -9 " ++ Pid) of
+ [] ->
+
+ %% memsup should now terminate
+ receive
+ {'DOWN', MonRef, _, _, {port_died, _Reason}} ->
+ ok;
+ {'DOWN', MonRef, _, _, Reason} ->
+ ?line ?t:fail({unexpected_exit_reason, Reason})
+ after
+ 3000 ->
+ ?line ?t:fail(still_alive)
+ end,
+
+ %% Give os_mon_sup time to restart memsup
+ ?t:sleep(?t:seconds(3)),
+ ?line {Total2,_Alloc2,_Worst2} =
+ memsup:get_memory_data(),
+ ?line true = Total2>0,
+
+ ok;
+
+ Line ->
+ erlang:demonitor(MonRef),
+ {skip, {not_killed, Line}}
+ end;
+ _ ->
+ {skip, {os_pid_not_found, Str}}
+ end.
+
+otp_5910(suite) ->
+ [];
+otp_5910(doc) ->
+ ["Test that alarms are cleared and not set twice"];
+otp_5910(Config) when is_list(Config) ->
+ Alarms =
+ [system_memory_high_watermark, process_memory_high_watermark],
+
+ %% Make sure memsup sets both alarms
+ ?line ok = application:set_env(os_mon, memory_check_interval, 60),
+ ?line ok = memsup:set_check_interval(60),
+ ?line SysThreshold = (memsup:get_sysmem_high_watermark()/100),
+ ?line ProcThreshold = (memsup:get_procmem_high_watermark()/100),
+
+ MemData = memsup:get_memory_data(),
+
+ io:format("otp_5910: memsup:get_memory_data() = ~p~n", [MemData]),
+ ?line {Total, Alloc, {_Pid, _Bytes}} = MemData,
+ ?line Pid = spawn_opt(fun() ->
+ receive
+ die -> ok
+ end
+ end, [{min_heap_size, 1000}]),
+ %% Create a process guaranteed to live, be constant and
+ %% break memsup process limit
+ ?line {memory, Bytes} = erlang:process_info(Pid,memory),
+ ?line SysUsage = Alloc/Total,
+ ?line ProcUsage = Bytes/Total,
+
+ if
+ SysUsage>SysThreshold ->
+ ok;
+ SysUsage=<SysThreshold ->
+ ?line ok = application:set_env(os_mon,
+ sys_mem_high_watermark,
+ 0.5 * SysUsage),
+ ?line ok = memsup:set_sysmem_high_watermark(0.5 * SysUsage)
+ end,
+ if
+ ProcUsage>ProcThreshold ->
+ ok;
+ ProcUsage=<ProcThreshold ->
+ ?line ok = application:set_env(os_mon,
+ proc_mem_high_watermark,
+ 0.5 * ProcUsage),
+ ?line ok = memsup:set_procmem_high_watermark(0.5 *ProcUsage)
+ end,
+ ?line ok = force_collection(),
+ ?t:sleep(?t:seconds(1)),
+ lists:foreach(fun(AlarmId) ->
+ case alarm_set(AlarmId) of
+ {true, _} -> ok;
+ false ->
+ ?line ?t:fail({alarm_not_set,
+ AlarmId})
+ end
+ end,
+ Alarms),
+
+ %% Kill guaranteed process...
+ Pid ! die,
+ %% Kill memsup
+ exit(whereis(memsup), faked_memsup_crash),
+ %% Wait a little to make sure memsup has been restarted,
+ %% then make sure the alarms are set once, but not twice
+ ?t:sleep(?t:seconds(1)),
+ ?line MemUsage = memsup:get_memory_data(),
+ SetAlarms = alarm_handler:get_alarms(),
+ case lists:foldl(fun(system_memory_high_watermark, {S, P}) ->
+ {S+1, P};
+ (process_memory_high_watermark, {S, P}) ->
+ {S, P+1};
+ (_AlarmId, Acc0) ->
+ Acc0
+ end,
+ {0, 0},
+ SetAlarms) of
+ {0, 0} ->
+ ok;
+ _ ->
+ ?line ?t:fail({bad_number_of_alarms, SetAlarms, MemUsage})
+ end,
+
+ %% Stop OS_Mon and make sure all memsup alarms are cleared
+ ?line ok = application:stop(os_mon),
+ ?t:sleep(?t:seconds(1)),
+ lists:foreach(fun(AlarmId) ->
+ case alarm_set(AlarmId) of
+ false -> ok;
+ {true, _} ->
+ ?line ?t:fail({alarm_is_set, AlarmId})
+ end
+ end,
+ Alarms),
+
+ %% Reset configuration and restart OS_Mon
+ ?line ok = application:set_env(os_mon,memory_check_interval,1),
+ ?line ok = application:set_env(os_mon,sys_mem_high_watermark,0.8),
+ ?line ok = application:set_env(os_mon,proc_mem_high_watermark,0.05),
+ ?line ok = application:start(os_mon),
+
+ ok.
+
+%%----------------------------------------------------------------------
+%% Auxiliary
+%%----------------------------------------------------------------------
+
+force_collection() ->
+ erlang:trace(whereis(memsup), true, ['receive']),
+ memsup ! time_to_collect,
+ TimerRef = erlang:send_after(5000, self(), timeout),
+ force_collection(TimerRef).
+
+force_collection(TimerRef) ->
+ receive
+ {trace, _Pid, 'receive', {collected_sys, _Sys}} ->
+ erlang:cancel_timer(TimerRef),
+ erlang:trace(whereis(memsup), false, ['receive']),
+ flush(),
+ ok;
+ {trace, _Pid, 'receive', reg_collection_timeout} ->
+ erlang:cancel_timer(TimerRef),
+ erlang:trace(whereis(memsup), false, ['receive']),
+ flush(),
+ collection_timeout;
+ timout ->
+ erlang:trace(whereis(memsup), false, ['receive']),
+ flush(),
+ timeout;
+ _Msg ->
+ force_collection(TimerRef)
+ end.
+
+flush() ->
+ receive
+ {trace, _, _, _} ->
+ flush();
+ timeout ->
+ flush()
+ after 0 ->
+ ok
+ end.
diff --git a/lib/os_mon/test/os_mon.spec b/lib/os_mon/test/os_mon.spec
new file mode 100644
index 0000000000..bdae523795
--- /dev/null
+++ b/lib/os_mon/test/os_mon.spec
@@ -0,0 +1 @@
+{topcase, {dir, "../os_mon_test"}}.
diff --git a/lib/os_mon/test/os_mon_SUITE.erl b/lib/os_mon/test/os_mon_SUITE.erl
new file mode 100644
index 0000000000..ce52271ff8
--- /dev/null
+++ b/lib/os_mon/test/os_mon_SUITE.erl
@@ -0,0 +1,89 @@
+%%
+%% %CopyrightBegin%
+%%
+%% 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(os_mon_SUITE).
+-include("test_server.hrl").
+
+%% Test server specific exports
+-export([all/1]).
+-export([init_per_testcase/2, fin_per_testcase/2]).
+
+%% Test cases
+-export([app_file/1, config/1]).
+
+%% Default timetrap timeout (set in init_per_testcase)
+-define(default_timeout, ?t:minutes(1)).
+
+init_per_testcase(_Case, Config) ->
+ Dog = test_server:timetrap(?default_timeout),
+ [{watchdog, Dog}|Config].
+
+fin_per_testcase(_Case, Config) ->
+ Dog = ?config(watchdog, Config),
+ test_server:timetrap_cancel(Dog),
+ ok.
+
+all(suite) ->
+ case ?t:os_type() of
+ {unix, sunos} -> [app_file, config];
+ _OS -> [app_file]
+ end.
+
+app_file(suite) ->
+ [];
+app_file(doc) ->
+ ["Testing .app file"];
+app_file(Config) when is_list(Config) ->
+ ?line ok = test_server:app_test(os_mon),
+ ok.
+
+config(suite) ->
+ [];
+config(doc) ->
+ ["Test OS_Mon configuration"];
+config(Config) when is_list(Config) ->
+
+ IsReg = fun(Name) -> is_pid(whereis(Name)) end,
+ IsNotReg = fun(Name) -> undefined == whereis(Name) end,
+
+ ?line ok = application:start(os_mon),
+ ?line true = lists:all(IsReg, [cpu_sup, disksup, memsup]),
+ ?line ok = application:stop(os_mon),
+
+ ?line ok = application:set_env(os_mon, start_cpu_sup, false),
+ ?line ok = application:start(os_mon),
+ ?line true = lists:all(IsReg, [disksup, memsup]),
+ ?line true = IsNotReg(cpu_sup),
+ ?line ok = application:stop(os_mon),
+ ?line ok = application:set_env(os_mon, start_cpu_sup, true),
+
+ ?line ok = application:set_env(os_mon, start_disksup, false),
+ ?line ok = application:start(os_mon),
+ ?line true = lists:all(IsReg, [cpu_sup, memsup]),
+ ?line true = IsNotReg(disksup),
+ ?line ok = application:stop(os_mon),
+ ?line ok = application:set_env(os_mon, start_disksup, true),
+
+ ?line ok = application:set_env(os_mon, start_memsup, false),
+ ?line ok = application:start(os_mon),
+ ?line true = lists:all(IsReg, [cpu_sup, disksup]),
+ ?line true = IsNotReg(memsup),
+ ?line ok = application:stop(os_mon),
+ ?line ok = application:set_env(os_mon, start_memsup, true),
+
+ ok.
diff --git a/lib/os_mon/test/os_mon_conf.erl b/lib/os_mon/test/os_mon_conf.erl
new file mode 100644
index 0000000000..5c1fa43047
--- /dev/null
+++ b/lib/os_mon/test/os_mon_conf.erl
@@ -0,0 +1,28 @@
+%%
+%% %CopyrightBegin%
+%%
+%% 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
+%% 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(os_mon_conf).
+-export([init/1,fin/1]).
+
+init(Conf) ->
+ RetVal = application:start(os_mon,temporary),
+ [{os_mon,RetVal}|Conf].
+
+fin(Conf) ->
+ application:stop(os_mon),
+ lists:keydelete(os_mon,1,Conf).
diff --git a/lib/os_mon/test/os_mon_mib_SUITE.erl b/lib/os_mon/test/os_mon_mib_SUITE.erl
new file mode 100644
index 0000000000..a1d463030a
--- /dev/null
+++ b/lib/os_mon/test/os_mon_mib_SUITE.erl
@@ -0,0 +1,746 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 2004-2010. All Rights Reserved.
+%%
+%% The contents of this file are subject to the Erlang Public License,
+%% Version 1.1, (the "License"); you may not use this file except in
+%% compliance with the License. You should have received a copy of the
+%% Erlang Public License along with this software. If not, it can be
+%% retrieved online at http://www.erlang.org/.
+%%
+%% Software distributed under the License is distributed on an "AS IS"
+%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+%% the License for the specific language governing rights and limitations
+%% under the License.
+%%
+%% %CopyrightEnd%
+%%
+-module(os_mon_mib_SUITE).
+
+%-define(STANDALONE,1).
+
+-ifdef(STANDALONE).
+-define(line,erlang:display({line,?LINE}),).
+-define(config(A,B), config(A,B)).
+-else.
+-include("test_server.hrl").
+-include_lib("os_mon/include/OTP-OS-MON-MIB.hrl").
+-include_lib("snmp/include/snmp_types.hrl").
+-endif.
+
+% Test server specific exports
+-export([all/1, init_per_suite/1, end_per_suite/1,
+ init_per_testcase/2, end_per_testcase/2]).
+
+
+% Test cases must be exported.
+-export([update_load_table/1]).
+
+-export([get_mem_sys_mark/1, get_mem_proc_mark/1, get_disk_threshold/1,
+ get_load_table/1, get_next_load_table/1, get_disk_table/1,
+ get_next_disk_table/1, real_snmp_request/1, load_unload/1]).
+
+-export([sys_tot_mem/1, sys_used_mem/1, large_erl_process/1,
+ large_erl_process_mem/1, cpu_load/1, cpu_load5/1, cpu_load15/1,
+ os_wordsize/1, sys_tot_mem64/1, sys_used_mem64/1,
+ large_erl_process_mem64/1, disk_descr/1, disk_kbytes/1,
+ disk_capacity/1]).
+
+-export([tickets/1]).
+-export([otp_6351/1, otp_7441/1]).
+
+-define(TRAP_UDP, 5000).
+-define(AGENT_UDP, 4000).
+-define(CONF_FILE_VER, [v2]).
+-define(SYS_NAME, "Test os_mon_mibs").
+-define(MAX_MSG_SIZE, 484).
+-define(ENGINE_ID, "mgrEngine").
+-define(MGR_PORT, 5001).
+
+%%---------------------------------------------------------------------
+-ifdef(STANDALONE).
+-export([run/0]).
+run() ->
+ catch init_per_suite([]),
+ Ret = (catch update_load_table([])),
+ catch end_per_suite([]),
+ Ret.
+-else.
+
+init_per_testcase(_Case, Config) when is_list(Config) ->
+ Dog = test_server:timetrap(test_server:minutes(6)),
+ [{watchdog, Dog}|Config].
+
+end_per_testcase(_Case, Config) when is_list(Config) ->
+ Dog = ?config(watchdog, Config),
+ test_server:timetrap_cancel(Dog),
+ Config.
+
+all(doc) ->
+ ["Test os_mon mibs and provided instrumentation functions."];
+
+all(suite) ->
+ [load_unload, get_mem_sys_mark, get_mem_proc_mark,
+ get_disk_threshold, get_load_table, get_next_load_table,
+ get_disk_table, get_next_disk_table, real_snmp_request,
+ update_load_table, tickets].
+
+tickets(suite) ->
+ [otp_6351, otp_7441].
+
+-endif.
+%%---------------------------------------------------------------------
+%%--------------------------------------------------------------------
+%% Function: init_per_suite(Config) -> Config
+%% Config - [tuple()]
+%% A list of key/value pairs, holding the test case configuration.
+%% Description: Initiation 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) ->
+ ?line application:start(sasl),
+ ?line application:start(mnesia),
+ ?line application:start(os_mon),
+
+ %% Create initial configuration data for the snmp application
+ ?line PrivDir = ?config(priv_dir, Config),
+ ?line ConfDir = filename:join(PrivDir, "conf"),
+ ?line DbDir = filename:join(PrivDir,"db"),
+ ?line MgrDir = filename:join(PrivDir,"mgr"),
+
+ ?line file:make_dir(ConfDir),
+ ?line file:make_dir(DbDir),
+ ?line file:make_dir(MgrDir),
+
+ {ok, HostName} = inet:gethostname(),
+ {ok, Addr} = inet:getaddr(HostName, inet),
+
+ ?line snmp_config:write_agent_snmp_files(ConfDir, ?CONF_FILE_VER,
+ tuple_to_list(Addr), ?TRAP_UDP,
+ tuple_to_list(Addr),
+ ?AGENT_UDP, ?SYS_NAME),
+
+ ?line snmp_config:write_manager_snmp_files(MgrDir, tuple_to_list(Addr),
+ ?MGR_PORT, ?MAX_MSG_SIZE,
+ ?ENGINE_ID, [], [], []),
+
+ %% To make sure application:set_env is not overwritten by any
+ %% app-file settings.
+ ?line ok = application:load(snmp),
+
+ ?line application:set_env(snmp, agent, [{db_dir, DbDir},
+ {config, [{dir, ConfDir}]},
+ {agent_type, master},
+ {agent_verbosity, trace},
+ {net_if, [{verbosity, trace}]}]),
+ ?line application:set_env(snmp, manager, [{config, [{dir, MgrDir},
+ {db_dir, MgrDir},
+ {verbosity, trace}]},
+ {server, [{verbosity, trace}]},
+ {net_if, [{verbosity, trace}]},
+ {versions, [v1, v2, v3]}]),
+ application:start(snmp),
+
+ %% Load the mibs that should be tested
+ otp_mib:load(snmp_master_agent),
+ os_mon_mib:load(snmp_master_agent),
+
+ [{agent_ip, Addr}| 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) ->
+ PrivDir = ?config(priv_dir, Config),
+ ConfDir = filename:join(PrivDir,"conf"),
+ DbDir = filename:join(PrivDir,"db"),
+ MgrDir = filename:join(PrivDir, "mgr"),
+
+ %% Uload mibs
+ snmpa:unload_mibs(snmp_master_agent,["OTP-OS-MON-MIB"]),
+ otp_mib:unload(snmp_master_agent),
+
+ %% Clean up
+ application:stop(snmp),
+ application:stop(mnesia),
+ application:stop(os_mon),
+
+ del_dir(ConfDir),
+ del_dir(DbDir),
+ (catch del_dir(MgrDir)),
+ ok.
+
+%%---------------------------------------------------------------------
+%% Test cases
+%%---------------------------------------------------------------------
+load_unload(doc) ->
+ ["Test to unload and the reload the OTP.mib "];
+load_unload(suite) -> [];
+load_unload(Config) when list(Config) ->
+ ?line os_mon_mib:unload(snmp_master_agent),
+ ?line os_mon_mib:load(snmp_master_agent),
+ ok.
+%%---------------------------------------------------------------------
+
+update_load_table(doc) ->
+ ["check os_mon_mib:update_load_table error handling"];
+update_load_table(suite) ->
+ [];
+update_load_table(Config) when is_list(Config) ->
+ ?line Node = start_node(),
+ ?line ok = rpc:call(Node,application,start,[sasl]),
+ ?line ok = rpc:call(Node,application,start,[os_mon]),
+ ?line ok = os_mon_mib:update_load_table(),
+ ?line rpc:call(Node,application,stop,[os_mon]),
+ ?line ok = os_mon_mib:update_load_table(),
+ ?line stop_node(Node),
+ ok.
+
+otp_6351(doc) ->
+ ["like update_load_table, when memsup_system_only==true"];
+otp_6351(suite) ->
+ [];
+otp_6351(Config) when is_list(Config) ->
+ ?line Node = start_node(),
+ ?line ok = rpc:call(Node,application,start,[sasl]),
+ ?line ok = rpc:call(Node,application,load,[os_mon]),
+ ?line ok = rpc:call(Node,application,set_env,
+ [os_mon,memsup_system_only,true]),
+ ?line ok = rpc:call(Node,application,start,[os_mon]),
+ ?line Res = rpc:call(Node,os_mon_mib,get_load,[Node]),
+ if
+ is_tuple(Res), element(1, Res)==loadTable ->
+ ?line ok;
+ true ->
+ ?line ?t:fail(Res)
+ end,
+ ?line rpc:call(Node,application,stop,[os_mon]),
+ ?line stop_node(Node),
+ ok.
+
+
+
+
+%%---------------------------------------------------------------------
+get_mem_sys_mark(doc) ->
+ ["Simulates a get call to test the instrumentation function "
+ "for the loadMemorySystemWatermark variable."];
+get_mem_sys_mark(suite) ->
+ [];
+get_mem_sys_mark(Config) when is_list(Config) ->
+ case os_mon_mib:mem_sys_mark(get) of
+ {value, SysMark} when is_integer(SysMark) ->
+ ok;
+ _ ->
+ ?line test_server:fail(sys_mark_value_not_integer)
+ end.
+%%---------------------------------------------------------------------
+get_mem_proc_mark(doc) ->
+ ["Simulates a get call to test the instrumentation function "
+ "for the loadMemoryErlProcWatermark variable."];
+get_mem_proc_mark(suite) ->
+ [];
+get_mem_proc_mark(Config) when is_list(Config) ->
+ case os_mon_mib:mem_proc_mark(get) of
+ {value, ProcMark} when is_integer(ProcMark) ->
+ ok;
+ _ ->
+ ?line test_server:fail(proc_mark_value_not_integer)
+ end.
+%%---------------------------------------------------------------------
+get_disk_threshold(doc) ->
+ ["Simulates a get call to test the instrumentation function "
+ "for the diskAlmostFullThreshold variable."];
+get_disk_threshold(suite) ->
+ [];
+get_disk_threshold(Config) when is_list(Config) ->
+ case os_mon_mib:disk_threshold(get) of
+ {value, ProcMark} when is_integer(ProcMark) ->
+ ok;
+ _ ->
+ ?line test_server:fail(disk_threshold_value_not_integer)
+ end.
+%%---------------------------------------------------------------------
+
+%%% Note that when we have a string key, as in loadTable, the
+%%% instrumentation will deal with the [length(String), String]. We
+%%% have to know about this, when short cutting SNMP and calling
+%%% instrumentation functions directly as done in most test cases in
+%%% this test suite
+
+get_load_table(doc) ->
+ ["Simulates get calls to test the instrumentation function "
+ "for the loadTable"];
+get_load_table(suite) ->
+ [];
+get_load_table(Config) when is_list(Config) ->
+
+ NodeStr = atom_to_list(node()),
+ NodeLen = length(NodeStr),
+
+ {_, _, {Pid, _}} = memsup:get_memory_data(),
+ PidStr = lists:flatten(io_lib:format("~w", [Pid])),
+ ?line [{value, NodeStr},{value, PidStr}] =
+ os_mon_mib:load_table(get, [NodeLen | NodeStr],
+ [?loadErlNodeName, ?loadLargestErlProcess]),
+
+ ?line Values = os_mon_mib:load_table(get, [NodeLen | NodeStr] ,
+ [?loadSystemTotalMemory,
+ ?loadSystemUsedMemory,
+ ?loadLargestErlProcessUsedMemory,
+ ?loadCpuLoad,
+ ?loadCpuLoad5,
+ ?loadCpuLoad15,
+ ?loadOsWordsize,
+ ?loadSystemTotalMemory64,
+ ?loadSystemUsedMemory64,
+ ?loadLargestErlProcessUsedMemory64]),
+
+ IsInt = fun({value, Val}) when is_integer(Val) ->
+ true;
+ (_) ->
+ false
+ end,
+
+ NewValues = lists:filter(IsInt, Values),
+
+ case length(NewValues) of
+ 10 ->
+ ok;
+ _ ->
+ ?line test_server:fail(value_not_integer)
+ end,
+
+ ?line [{noValue,noSuchInstance}, {noValue,noSuchInstance},
+ {noValue,noSuchInstance}, {noValue,noSuchInstance},
+ {noValue,noSuchInstance}, {noValue,noSuchInstance},
+ {noValue,noSuchInstance}, {noValue,noSuchInstance},
+ {noValue,noSuchInstance}, {noValue,noSuchInstance},
+ {noValue,noSuchInstance}, {noValue,noSuchInstance}] =
+ os_mon_mib:load_table(get, [3, 102, 111, 111],
+ [?loadErlNodeName,
+ ?loadSystemTotalMemory,
+ ?loadSystemUsedMemory,
+ ?loadLargestErlProcess,
+ ?loadLargestErlProcessUsedMemory,
+ ?loadCpuLoad,
+ ?loadCpuLoad5,
+ ?loadCpuLoad15,
+ ?loadOsWordsize,
+ ?loadSystemTotalMemory64,
+ ?loadSystemUsedMemory64,
+ ?loadLargestErlProcessUsedMemory64]),
+
+ ok.
+%%---------------------------------------------------------------------
+get_next_load_table(doc) ->
+ ["Simulates get_next calls to test the instrumentation function "
+ "for the loadTable"];
+get_next_load_table(suite) ->
+ [ sys_tot_mem,
+ sys_used_mem,
+ large_erl_process,
+ large_erl_process_mem,
+ cpu_load,
+ cpu_load5,
+ cpu_load15,
+ os_wordsize,
+ sys_tot_mem64,
+ sys_used_mem64,
+ large_erl_process_mem64].
+
+sys_tot_mem(doc) ->
+ [];
+sys_tot_mem(suite) ->
+ [];
+sys_tot_mem(Config) when is_list(Config) ->
+ ?line [{[?loadSystemTotalMemory, Len | NodeStr], Mem}] =
+ os_mon_mib:load_table(get_next, [], [?loadSystemTotalMemory]),
+ ?line Len = length(NodeStr),
+ ?line true = lists:member(list_to_atom(NodeStr), [node() | nodes()]),
+
+ case Mem of
+ Mem when is_integer(Mem) ->
+ ok;
+ _ ->
+ ?line test_server:fail(sys_tot_mem_value_not_integer)
+ end.
+
+sys_used_mem(doc) ->
+ [];
+sys_used_mem(suite) -> [];
+sys_used_mem(Config) when is_list(Config) ->
+ ?line [{[?loadSystemUsedMemory, Len | NodeStr], Mem}] =
+ os_mon_mib:load_table(get_next,[], [?loadSystemUsedMemory]),
+ ?line Len = length(NodeStr),
+ ?line true = lists:member(list_to_atom(NodeStr), [node() | nodes()]),
+
+ case Mem of
+ Mem when is_integer(Mem) ->
+ ok;
+ _ ->
+ ?line test_server:fail(sys_used_mem_value_not_integer)
+ end.
+
+large_erl_process(doc) ->
+ [];
+large_erl_process(suite) ->
+ [];
+large_erl_process(Config) when is_list(Config) ->
+ {_, _, {Pid, _}} = memsup:get_memory_data(),
+ PidStr = lists:flatten(io_lib:format("~w", [Pid])),
+ ?line [{[?loadLargestErlProcess, Len | NodeStr], PidStr}] =
+ os_mon_mib:load_table(get_next,[], [?loadLargestErlProcess]),
+ ?line Len = length(NodeStr),
+ ?line true = lists:member(list_to_atom(NodeStr), [node() | nodes()]),
+ ok.
+
+large_erl_process_mem(doc) ->
+ [];
+large_erl_process_mem(suite) ->
+ [];
+large_erl_process_mem(Config) when is_list(Config) ->
+
+ ?line [{[?loadLargestErlProcessUsedMemory, Len | NodeStr], Mem}] =
+ os_mon_mib:load_table(get_next,[],
+ [?loadLargestErlProcessUsedMemory]),
+ ?line Len = length(NodeStr),
+ ?line true = lists:member(list_to_atom(NodeStr), [node() | nodes()]),
+
+ case Mem of
+ Mem when is_integer(Mem) ->
+ ok;
+ _ ->
+ ?line test_server:fail(erl_pid_mem_value_not_integer)
+ end.
+
+cpu_load(doc) ->
+ [];
+cpu_load(suite) ->
+ [];
+cpu_load(Config) when list(Config) ->
+ ?line [{[?loadCpuLoad, Len | NodeStr], Load}] =
+ os_mon_mib:load_table(get_next,[], [?loadCpuLoad]),
+ ?line Len = length(NodeStr),
+ ?line true = lists:member(list_to_atom(NodeStr), [node() | nodes()]),
+
+ case Load of
+ Load when is_integer(Load) ->
+ ok;
+ _ ->
+ ?line test_server:fail(cpu_load_value_not_integer)
+ end.
+
+cpu_load5(doc) ->
+ [];
+cpu_load5(suite) ->
+ [];
+cpu_load5(Config) when is_list(Config) ->
+ ?line [{[?loadCpuLoad5, Len | NodeStr], Load}] =
+ os_mon_mib:load_table(get_next,[], [?loadCpuLoad5]),
+ ?line Len = length(NodeStr),
+ ?line true = lists:member(list_to_atom(NodeStr), [node() | nodes()]),
+
+ case Load of
+ Load when is_integer(Load) ->
+ ok;
+ _ ->
+ ?line test_server:fail(cpu_load5_value_not_integer)
+ end.
+
+cpu_load15(doc) ->
+ [];
+cpu_load15(suite) ->
+ [];
+cpu_load15(Config) when is_list(Config) ->
+ ?line [{[?loadCpuLoad15, Len | NodeStr], Load}] =
+ os_mon_mib:load_table(get_next,[], [?loadCpuLoad15]),
+ ?line Len = length(NodeStr),
+ ?line true = lists:member(list_to_atom(NodeStr), [node() | nodes()]),
+
+ case Load of
+ Load when is_integer(Load) ->
+ ok;
+ _ ->
+ ?line test_server:fail(cpu_load15_value_not_integer)
+ end.
+
+os_wordsize(doc) ->
+ [];
+os_wordsize(suite) ->
+ [];
+os_wordsize(Config) when is_list(Config) ->
+ ?line [{[?loadOsWordsize, Len | NodeStr], Wordsize}] =
+ os_mon_mib:load_table(get_next,[], [?loadOsWordsize]),
+ ?line Len = length(NodeStr),
+ ?line true = lists:member(list_to_atom(NodeStr), [node() | nodes()]),
+
+ case Wordsize of
+ Wordsize when is_integer(Wordsize) ->
+ ok;
+ _ ->
+ ?line test_server:fail(os_wordsize_value_not_integer)
+ end.
+
+sys_tot_mem64(doc) ->
+ [];
+sys_tot_mem64(suite) ->
+ [];
+sys_tot_mem64(Config) when is_list(Config) ->
+ ?line [{[?loadSystemTotalMemory64, Len | NodeStr], Mem}] =
+ os_mon_mib:load_table(get_next, [], [?loadSystemTotalMemory64]),
+ ?line Len = length(NodeStr),
+ ?line true = lists:member(list_to_atom(NodeStr), [node() | nodes()]),
+
+ case Mem of
+ Mem when is_integer(Mem) ->
+ ok;
+ _ ->
+ ?line test_server:fail(sys_tot_mem_value_not_integer)
+ end.
+
+sys_used_mem64(doc) ->
+ [];
+sys_used_mem64(suite) -> [];
+sys_used_mem64(Config) when is_list(Config) ->
+ ?line [{[?loadSystemUsedMemory64, Len | NodeStr], Mem}] =
+ os_mon_mib:load_table(get_next,[], [?loadSystemUsedMemory64]),
+ ?line Len = length(NodeStr),
+ ?line true = lists:member(list_to_atom(NodeStr), [node() | nodes()]),
+
+ case Mem of
+ Mem when is_integer(Mem) ->
+ ok;
+ _ ->
+ ?line test_server:fail(sys_used_mem_value_not_integer)
+ end.
+
+large_erl_process_mem64(doc) ->
+ [];
+large_erl_process_mem64(suite) ->
+ [];
+large_erl_process_mem64(Config) when is_list(Config) ->
+
+ ?line [{[?loadLargestErlProcessUsedMemory64, Len | NodeStr], Mem}] =
+ os_mon_mib:load_table(get_next,[],
+ [?loadLargestErlProcessUsedMemory64]),
+ ?line Len = length(NodeStr),
+ ?line true = lists:member(list_to_atom(NodeStr), [node() | nodes()]),
+
+ case Mem of
+ Mem when is_integer(Mem) ->
+ ok;
+ _ ->
+ ?line test_server:fail(erl_pid_mem_value_not_integer)
+ end.
+%%---------------------------------------------------------------------
+get_disk_table(doc) ->
+ ["Simulates get calls to test the instrumentation function "
+ "for the diskTable."];
+get_disk_table(suite) ->
+ [];
+get_disk_table(Config) when is_list(Config) ->
+
+ DiskData = disksup:get_disk_data(),
+ DiskDataLen = length(DiskData),
+
+ if
+ DiskDataLen > 0 ->
+ ?line [{value, Value}] =
+ os_mon_mib:disk_table(get, [1,1], [?diskDescr]),
+
+ case is_list(Value) of
+ true ->
+ ok;
+ false ->
+ ?line test_server:fail(value_not_a_string)
+ end,
+
+ ?line Values = os_mon_mib:disk_table(get, [1,1],
+ [?diskId,
+ ?diskKBytes,
+ ?diskCapacity]),
+
+ IsInt = fun({value, Val}) when is_integer(Val) ->
+ true;
+ (_) ->
+ false
+ end,
+
+ NewValues = lists:filter(IsInt, Values),
+
+ case length(NewValues) of
+ 3 ->
+ ok;
+ _ ->
+ ?line test_server:fail(value_not_integer)
+ end
+ end,
+
+ ?line [{noValue,noSuchInstance}, {noValue,noSuchInstance},
+ {noValue,noSuchInstance}, {noValue,noSuchInstance}] =
+ os_mon_mib:disk_table(get, [1, DiskDataLen + 1], [?diskId,
+ ?diskDescr,
+ ?diskKBytes,
+ ?diskCapacity]),
+
+ ok.
+
+%%---------------------------------------------------------------------
+get_next_disk_table(doc) ->
+ ["Simulates get_next calls to test the instrumentation function "
+ "for the diskTable."];
+get_next_disk_table(suite) ->
+ [disk_descr, disk_kbytes, disk_capacity].
+
+disk_descr(doc) ->
+ [];
+disk_descr(suite) ->
+ [];
+disk_descr(Config) when is_list(Config) ->
+ ?line [{[?diskDescr, 1,1], Descr}] =
+ os_mon_mib:disk_table(get_next, [], [?diskDescr]),
+
+ case Descr of
+ Descr when is_list(Descr) ->
+ ok;
+ _ ->
+ ?line test_server:fail(disk_descr_value_not_a_string)
+ end.
+
+disk_kbytes(doc) ->
+ [];
+disk_kbytes(suite) -> [];
+disk_kbytes(Config) when is_list(Config) ->
+ ?line [{[?diskKBytes, 1,1], Kbytes}] =
+ os_mon_mib:disk_table(get_next,[], [?diskKBytes]),
+
+ case Kbytes of
+ Kbytes when is_integer(Kbytes) ->
+ ok;
+ _ ->
+ ?line test_server:fail(disk_kbytes_value_not_integer)
+ end.
+
+
+disk_capacity(doc) ->
+ [];
+disk_capacity(suite) -> [];
+disk_capacity(Config) when is_list(Config) ->
+ ?line [{[?diskCapacity, 1,1], Capacity}] =
+ os_mon_mib:disk_table(get_next,[], [?diskCapacity]),
+
+ case Capacity of
+ Capacity when is_integer(Capacity) ->
+ ok;
+ _ ->
+ ?line test_server:fail(disk_capacity_value_not_integer)
+ end.
+
+%%---------------------------------------------------------------------
+real_snmp_request(doc) ->
+ ["Starts an snmp manager and sends a real snmp-reques. i.e. "
+ "sends a udp message on the correct format."];
+real_snmp_request(suite) -> [];
+real_snmp_request(Config) when list(Config) ->
+ Agent_ip = ?config(agent_ip, Config),
+
+ ?line ok = snmpm:register_user(os_mon_mib_test, snmpm_user_default, []),
+ ?line ok = snmpm:register_agent(os_mon_mib_test, Agent_ip, ?AGENT_UDP),
+
+ NodStr = atom_to_list(node()),
+ Len = length(NodStr),
+ {_, _, {Pid, _}} = memsup:get_memory_data(),
+ PidStr = lists:flatten(io_lib:format("~w", [Pid])),
+ io:format("FOO: ~p~n", [PidStr]),
+ ?line ok = snmp_get(Agent_ip,
+ [?loadEntry ++
+ [?loadLargestErlProcess, Len | NodStr]],
+ PidStr),
+ ?line ok = snmp_get_next(Agent_ip,
+ [?loadEntry ++
+ [?loadSystemUsedMemory, Len | NodStr]],
+ ?loadEntry ++ [?loadSystemUsedMemory + 1, Len
+ | NodStr], PidStr),
+ ?line ok = snmp_set(Agent_ip, [?loadEntry ++
+ [?loadLargestErlProcess, Len | NodStr]],
+ s, "<0.101.0>"),
+ ok.
+
+otp_7441(doc) ->
+ ["Starts an snmp manager and requests total memory. Was previously
+ integer32 which was errornous on 64 bit machines."];
+otp_7441(suite) ->
+ [];
+otp_7441(Config) when is_list(Config) ->
+ Agent_ip = ?config(agent_ip, Config),
+
+
+ NodStr = atom_to_list(node()),
+ Len = length(NodStr),
+ Oids = [Oid|_] = [?loadEntry ++ [?loadSystemTotalMemory, Len | NodStr]],
+ ?line { ok, {noError,0,[#varbind{oid = Oid, variabletype = 'Unsigned32'}]}, _} =
+ snmpm:g(os_mon_mib_test, Agent_ip, ?AGENT_UDP, Oids),
+
+ ok.
+
+%%---------------------------------------------------------------------
+%% Internal functions
+%%---------------------------------------------------------------------
+-ifdef(STANDALONE).
+config(priv_dir,_) ->
+ "/tmp".
+
+start_node() ->
+ Host = hd(tl(string:tokens(atom_to_list(node()),"@"))),
+ {ok,Node} = slave:start(Host,testnisse),
+ net_adm:ping(testnisse),
+ Node.
+
+
+stop_node(Node) ->
+ rpc:call(Node,erlang,halt,[]).
+-else.
+start_node() ->
+ ?line Pa = filename:dirname(code:which(?MODULE)),
+ ?line {ok,Node} = test_server:start_node(testnisse, slave,
+ [{args, " -pa " ++ Pa}]),
+ Node.
+
+stop_node(Node) ->
+ test_server:stop_node(Node).
+
+-endif.
+
+del_dir(Dir) ->
+ io:format("Deleting: ~s~n",[Dir]),
+ {ok, Files} = file:list_dir(Dir),
+ FullPathFiles = lists:map(fun(File) -> filename:join(Dir, File) end,
+ Files),
+ lists:foreach({file, delete}, FullPathFiles),
+ file:del_dir(Dir).
+
+%%---------------------------------------------------------------------
+snmp_get(Agent_ip, Oids = [Oid |_], Result) ->
+ ?line {ok,{noError,0,[#varbind{oid = Oid,
+ variabletype = 'OCTET STRING',
+ value = Result}]}, _} =
+ snmpm:g(os_mon_mib_test, Agent_ip, ?AGENT_UDP, Oids),
+ ok.
+
+snmp_get_next(Agent_ip, Oids, NextOid, Result) ->
+ ?line {ok,{noError,0,[#varbind{oid = NextOid,
+ variabletype = 'OCTET STRING',
+ value = Result}]},_} =
+ snmpm:gn(os_mon_mib_test, Agent_ip, ?AGENT_UDP, Oids),
+ ok.
+
+snmp_set(Agent_ip, Oid, ValuType, Value) ->
+ ?line {ok, {notWritable, _, _}, _} =
+ snmpm:s(os_mon_mib_test,Agent_ip,?AGENT_UDP,[{Oid, ValuType, Value}]),
+ ok.
diff --git a/lib/os_mon/test/os_sup_SUITE.erl b/lib/os_mon/test/os_sup_SUITE.erl
new file mode 100644
index 0000000000..25041f968d
--- /dev/null
+++ b/lib/os_mon/test/os_sup_SUITE.erl
@@ -0,0 +1,189 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 2006-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(os_sup_SUITE).
+-include("test_server.hrl").
+
+%% Test server specific exports
+-export([all/1]).
+-export([init_per_suite/1, end_per_suite/1]).
+-export([init_per_testcase/2, end_per_testcase/2]).
+
+%% Test cases
+-export([message/1]).
+-export([config/1, port/1]).
+
+%% Default timetrap timeout (set in init_per_testcase)
+-define(default_timeout, ?t:minutes(1)).
+
+-define(TAG, test_tag).
+-define(MFA, {?MODULE, test_mfa, [?TAG]}).
+
+-export([test_mfa/2]).
+
+init_per_suite(Config) when is_list(Config) ->
+ spawn(fun() -> message_receptor() end),
+ ?line application:load(os_mon),
+ ?line ok = application:set_env(os_mon, start_os_sup, true),
+ ?line ok = application:set_env(os_mon, os_sup_mfa, ?MFA),
+ ?line ok = application:set_env(os_mon, os_sup_enable, false),
+ ?line ok = application:start(os_mon),
+ Config.
+
+end_per_suite(Config) when is_list(Config) ->
+ ?line application:stop(os_mon),
+ ?line ok = application:set_env(os_mon, start_os_sup, false),
+ MFA = {os_sup, error_report, [std_error]},
+ ?line ok = application:set_env(os_mon, os_sup_mfa, MFA),
+ ?line ok = application:set_env(os_mon, os_sup_enable, true),
+ ?line exit(whereis(message_receptor), done),
+ Config.
+
+init_per_testcase(_Case, Config) ->
+ Dog = ?t:timetrap(?default_timeout),
+ [{watchdog,Dog} | Config].
+
+end_per_testcase(_Case, Config) ->
+ Dog = ?config(watchdog, Config),
+ ?t:timetrap_cancel(Dog),
+ ok.
+
+all(suite) ->
+ case ?t:os_type() of
+ {unix, sunos} ->
+ [message, config, port];
+ {win32, _OSname} ->
+ [message];
+ OS ->
+ Str = io_lib:format("os_sup not available for ~p", [OS]),
+ {skip, lists:flatten(Str)}
+ end.
+
+message(suite) ->
+ [];
+message(doc) ->
+ ["Test OS message handling"];
+message(Config) when is_list(Config) ->
+
+ %% Fake an OS message
+ Data = "10H11386278426HSystem4HTest5HError5HTesto",
+ ?line os_sup_server ! {faked_port, {data, Data}},
+
+ %% Check with message_receptor that it has been received
+ ?t:sleep(?t:seconds(1)),
+ Msg =
+ case ?t:os_type() of
+ {unix, sunos} ->
+ {?TAG, Data};
+ {win32, _} ->
+ {?TAG,{{1138,627842,0},"System","Test","Error","Testo"}}
+ end,
+ ?line message_receptor ! {check, self(), Msg},
+ receive
+ {result, true} ->
+ ok;
+ {result, Rec} ->
+ ?t:fail({no_message, Rec})
+ end,
+
+ ok.
+
+config(suite) ->
+ [];
+config(doc) ->
+ ["Test configuration"];
+config(Config) when is_list(Config) ->
+
+ %% os_sup_enable==true and os_sup_own/os_sup_syslogconf cannot
+ %% be tested as test_server is not running is root
+
+ %% os_sup_mfa is already tested, sort of (in init_per_suite)
+
+ %% os_sup_errortag should be tested, however
+
+ ok.
+
+port(suite) ->
+ [];
+port(doc) ->
+ ["Test that os_sup handles a terminating port program"];
+port(Config) when is_list(Config) ->
+ ?line Str = os:cmd("ps -e | grep '[f]errule'"),
+ case io_lib:fread("~s", Str) of
+ {ok, [Pid], _Rest} ->
+
+ %% Monitor os_sup_server
+ ?line MonRef = erlang:monitor(process, os_sup_server),
+
+ %% Kill the port program
+ case os:cmd("kill -9 " ++ Pid) of
+ [] ->
+
+ %% os_sup_server should now terminate
+ receive
+ {'DOWN', MonRef, _, _, {port_died, _Reason}} ->
+ ok;
+ {'DOWN', MonRef, _, _, Reason} ->
+ ?line ?t:fail({unexpected_exit_reason, Reason})
+ after
+ 3000 ->
+ ?line ?t:fail(still_alive)
+ end,
+
+ %% Give os_mon_sup time to restart os_sup
+ ?t:sleep(?t:seconds(3)),
+ ?line true = is_pid(whereis(os_sup_server)),
+
+ ok;
+
+ Line ->
+ erlang:demonitor(MonRef),
+ {skip, {not_killed, Line}}
+ end;
+ _ ->
+ {skip, {os_pid_not_found}}
+ end.
+
+%%----------------------------------------------------------------------
+%% Auxiliary
+%%----------------------------------------------------------------------
+
+test_mfa(Message, Tag) ->
+ message_receptor ! {Tag, Message}.
+
+message_receptor() ->
+ register(message_receptor, self()),
+ message_receptor([]).
+
+message_receptor(Received) ->
+ receive
+ %% Check if a certain message has been received
+ {check, From, Msg} ->
+ case lists:member(Msg, Received) of
+ true ->
+ From ! {result, true},
+ message_receptor(lists:delete(Msg, Received));
+ false ->
+ From ! {result, Received},
+ message_receptor(Received)
+ end;
+
+ %% Save all other messages
+ Msg ->
+ message_receptor([Msg|Received])
+ end.
diff --git a/lib/os_mon/vsn.mk b/lib/os_mon/vsn.mk
index d9f56416bf..ecc47e70d8 100644
--- a/lib/os_mon/vsn.mk
+++ b/lib/os_mon/vsn.mk
@@ -1 +1 @@
-OS_MON_VSN = 2.2.4
+OS_MON_VSN = 2.2.5
diff --git a/lib/parsetools/doc/src/leex.xml b/lib/parsetools/doc/src/leex.xml
index c113b586df..12abfd244f 100644
--- a/lib/parsetools/doc/src/leex.xml
+++ b/lib/parsetools/doc/src/leex.xml
@@ -281,7 +281,7 @@ NAME = VALUE</code>
&lt;Regexp> : &lt;Erlang code>.</code>
<p>The &lt;Regexp> must occur at the start of a line and not
- include any blanks; use <c>\\t</c> and <c>\\s</c> to include TAB
+ include any blanks; use <c>\t</c> and <c>\s</c> to include TAB
and SPACE characters in the regular expression. If &lt;Regexp>
matches then the corresponding &lt;Erlang code> is evaluated to
generate a token. With the Erlang code the following predefined
@@ -344,7 +344,7 @@ D = [0-9]
{D}+ :
{token,{integer,TokenLine,list_to_integer(TokenChars)}}.
-{D}+\\.{D}+((E|e)(\\+|\\-)?{D}+)? :
+{D}+\.{D}+((E|e)(\+|\-)?{D}+)? :
{token,{float,TokenLine,list_to_float(TokenChars)}}.</code>
<p>The Erlang code in the "Erlang code." section is written into
@@ -367,7 +367,7 @@ D = [0-9]
<tag><c>c</c></tag>
<item><p>Matches the non-metacharacter c.</p>
</item>
- <tag><c>\\c</c></tag>
+ <tag><c>\c</c></tag>
<item><p>Matches the escape sequence or literal character c.</p>
</item>
<tag><c>.</c></tag>
@@ -410,33 +410,33 @@ D = [0-9]
<p>The escape sequences allowed are the same as for Erlang strings:</p>
<taglist>
- <tag><c>\\b</c></tag>
+ <tag><c>\b</c></tag>
<item><p>Backspace.</p></item>
- <tag><c>\\f</c></tag>
+ <tag><c>\f</c></tag>
<item><p>Form feed.</p></item>
- <tag><c>\\n</c></tag>
+ <tag><c>\n</c></tag>
<item><p>Newline (line feed).</p></item>
- <tag><c>\\r</c></tag>
+ <tag><c>\r</c></tag>
<item><p>Carriage return.</p></item>
- <tag><c>\\t</c></tag>
+ <tag><c>\t</c></tag>
<item><p>Tab.</p></item>
- <tag><c>\\e</c></tag>
+ <tag><c>\e</c></tag>
<item><p>Escape.</p></item>
- <tag><c>\\v</c></tag>
+ <tag><c>\v</c></tag>
<item><p>Vertical tab.</p></item>
- <tag><c>\\s</c></tag>
+ <tag><c>\s</c></tag>
<item><p>Space.</p></item>
- <tag><c>\\d</c></tag>
+ <tag><c>\d</c></tag>
<item><p>Delete.</p></item>
- <tag><c>\\ddd</c></tag>
+ <tag><c>\ddd</c></tag>
<item><p>The octal value <c>ddd</c>.</p></item>
- <tag><c>\\xhh</c></tag>
+ <tag><c>\xhh</c></tag>
<item><p>The hexadecimal value <c>hh</c>.</p></item>
- <tag><c>\\x{h...}</c></tag>
+ <tag><c>\x{h...}</c></tag>
<item><p>The hexadecimal value <c>h...</c>.</p></item>
- <tag><c>\\c</c></tag>
- <item><p>Any other character literally, for example <c>\\\\</c> for
- backslash, <c>\\"</c> for <c>"</c>.</p>
+ <tag><c>\c</c></tag>
+ <item><p>Any other character literally, for example <c>\\</c> for
+ backslash, <c>\"</c> for <c>"</c>.</p>
</item>
</taglist>
@@ -446,7 +446,7 @@ Atoms [a-z][0-9a-zA-Z_]*
Variables [A-Z_][0-9a-zA-Z_]*
-Floats (\\+|-)?[0-9]+\\.[0-9]+((E|e)(\\+|-)?[0-9]+)?</code>
+Floats (\+|-)?[0-9]+\.[0-9]+((E|e)(\+|-)?[0-9]+)?</code>
<note><p>Anchoring a regular expression with <c>^</c> and <c>$</c>
is not implemented in the current version of Leex and just
diff --git a/lib/parsetools/doc/src/notes.xml b/lib/parsetools/doc/src/notes.xml
index 2947517717..8a6f2c2714 100644
--- a/lib/parsetools/doc/src/notes.xml
+++ b/lib/parsetools/doc/src/notes.xml
@@ -4,7 +4,7 @@
<chapter>
<header>
<copyright>
- <year>1997</year><year>2009</year>
+ <year>1997</year><year>2010</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
@@ -13,12 +13,12 @@
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>Parsetools Release Notes</title>
@@ -30,6 +30,22 @@
</header>
<p>This document describes the changes made to the Parsetools application.</p>
+<section><title>Parsetools 2.0.2</title>
+
+ <section><title>Improvements and New Features</title>
+ <list>
+ <item>
+ <p>
+ Cleanups suggested by tidier and modernization of types
+ and specs.</p>
+ <p>
+ Own Id: OTP-8455</p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
<section><title>Parsetools 2.0.1</title>
<section><title>Improvements and New Features</title>
diff --git a/lib/parsetools/include/yeccpre.hrl b/lib/parsetools/include/yeccpre.hrl
index 2ffa13d6a7..33a103d95f 100644
--- a/lib/parsetools/include/yeccpre.hrl
+++ b/lib/parsetools/include/yeccpre.hrl
@@ -1,52 +1,51 @@
%%
%% %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
%% 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%
%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% The parser generator will insert appropriate declarations before this line.%
--type(yecc_ret() :: {'error', _} | {'ok', _}).
+-type yecc_ret() :: {'error', _} | {'ok', _}.
-spec parse(Tokens :: list()) -> yecc_ret().
parse(Tokens) ->
yeccpars0(Tokens, {no_func, no_line}, 0, [], []).
--spec(parse_and_scan/1 ::
- ({function() | {atom(), atom()}, [_]} | {atom(), atom(), [_]}) ->
- yecc_ret()).
+-spec parse_and_scan({function() | {atom(), atom()}, [_]} | {atom(), atom(), [_]}) ->
+ yecc_ret().
parse_and_scan({F, A}) -> % Fun or {M, F}
yeccpars0([], {{F, A}, no_line}, 0, [], []);
parse_and_scan({M, F, A}) ->
yeccpars0([], {{{M, F}, A}, no_line}, 0, [], []).
--spec(format_error/1 :: (any()) -> [char() | list()]).
+-spec format_error(any()) -> [char() | list()].
format_error(Message) ->
case io_lib:deep_char_list(Message) of
- true ->
- Message;
- _ ->
- io_lib:write(Message)
+ true ->
+ Message;
+ _ ->
+ io_lib:write(Message)
end.
-% To be used in grammar files to throw an error message to the parser
-% toplevel. Doesn't have to be exported!
--compile({nowarn_unused_function, return_error/2}).
--spec(return_error/2 :: (integer(), any()) -> no_return()).
+%% To be used in grammar files to throw an error message to the parser
+%% toplevel. Doesn't have to be exported!
+-compile({nowarn_unused_function,{return_error,2}}).
+-spec return_error(integer(), any()) -> no_return().
return_error(Line, Message) ->
throw({error, {Line, ?MODULE, Message}}).
@@ -85,7 +84,7 @@ yeccpars1([Token | Tokens], Tzr, State, States, Vstack) ->
yeccpars1([], {{F, A},_Line}, State, States, Vstack) ->
case apply(F, A) of
{ok, Tokens, Endline} ->
- yeccpars1(Tokens, {{F, A}, Endline}, State, States, Vstack);
+ yeccpars1(Tokens, {{F, A}, Endline}, State, States, Vstack);
{eof, Endline} ->
yeccpars1([], {no_func, Endline}, State, States, Vstack);
{error, Descriptor, _Endline} ->
@@ -118,7 +117,7 @@ yeccpars1(State1, State, States, Vstack, Token0, [], {no_func, Line}) ->
yeccpars2(State, '$end', [State1 | States], [Token0 | Vstack],
yecc_end(Line), [], {no_func, Line}).
-% For internal use only.
+%% For internal use only.
yecc_end({Line,_Column}) ->
{'$end', Line};
yecc_end(Line) ->
diff --git a/lib/parsetools/src/yecc.erl b/lib/parsetools/src/yecc.erl
index f4d76f471d..b8b2b2308c 100644
--- a/lib/parsetools/src/yecc.erl
+++ b/lib/parsetools/src/yecc.erl
@@ -1,19 +1,19 @@
%%
%% %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
%% 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%
%%
%% Yacc like LALR-1 parser generator for Erlang.
@@ -30,8 +30,8 @@
-import(lists, [append/1, append/2, concat/1, delete/2, filter/2,
flatmap/2, foldl/3, foldr/3, foreach/2, keydelete/3,
- keysearch/3, keysort/2, last/1, map/2, member/2,
- reverse/1, sort/1, usort/1]).
+ keysort/2, last/1, map/2, member/2, reverse/1,
+ sort/1, usort/1]).
-include("erl_compile.hrl").
-include("ms_transform.hrl").
@@ -297,18 +297,18 @@ options(Options0, [Key | Keys], L) when is_list(Options0) ->
false ->
Options0
end,
- V = case keysearch(Key, 1, Options) of
- {value, {Key, Filename0}} when Key =:= includefile;
- Key =:= parserfile ->
+ V = case lists:keyfind(Key, 1, Options) of
+ {Key, Filename0} when Key =:= includefile;
+ Key =:= parserfile ->
case is_filename(Filename0) of
no ->
badarg;
Filename ->
{ok, [{Key, Filename}]}
end;
- {value, {Key, Bool}} when Bool =:= true; Bool =:= false ->
- {ok, [{Key, Bool}]};
- {value, {Key, _}} ->
+ {Key, Bool} = KB when is_boolean(Bool) ->
+ {ok, [KB]};
+ {Key, _} ->
badarg;
false ->
{ok, [{Key, default_option(Key)}]}
@@ -348,8 +348,7 @@ atom_option(verbose) -> {verbose, true};
atom_option(Key) -> Key.
is_filename(T) ->
- try filename:flatten(T) of
- Filename -> Filename
+ try filename:flatten(T)
catch error: _ -> no
end.
@@ -366,8 +365,8 @@ shorten_filename(Name0) ->
start(Infilex, Options) ->
Infile = assure_extension(Infilex, ".yrl"),
- {value, {_, Outfilex0}} = keysearch(parserfile, 1, Options),
- {value, {_, Includefilex}} = keysearch(includefile, 1, Options),
+ {_, Outfilex0} = lists:keyfind(parserfile, 1, Options),
+ {_, Includefilex} = lists:keyfind(includefile, 1, Options),
Outfilex = case Outfilex0 of
[] -> filename:rootname(Infilex, ".yrl");
_ -> Outfilex0
@@ -715,14 +714,14 @@ names(Symbols) ->
map(fun(Symbol) -> Symbol#symbol.name end, Symbols).
symbol_line(Name, St) ->
- {value, #symbol{line = Line}} = symbol_search(Name, St#yecc.all_symbols),
+ #symbol{line = Line} = symbol_find(Name, St#yecc.all_symbols),
Line.
symbol_member(Symbol, Symbols) ->
- symbol_search(Symbol#symbol.name, Symbols) =/= false.
+ symbol_find(Symbol#symbol.name, Symbols) =/= false.
-symbol_search(Name, Symbols) ->
- keysearch(Name, #symbol.name, Symbols).
+symbol_find(Name, Symbols) ->
+ lists:keyfind(Name, #symbol.name, Symbols).
states_and_goto_table(St0) ->
St1 = create_symbol_table(St0),
@@ -876,8 +875,8 @@ add_warnings(SymNames, W0, St0) ->
check_rhs([#symbol{name = '$empty'}], St) ->
St;
check_rhs(Rhs, St0) ->
- case symbol_search('$empty', Rhs) of
- {value, #symbol{line = Line}} ->
+ case symbol_find('$empty', Rhs) of
+ #symbol{line = Line} ->
add_error(Line, illegal_empty, St0);
false ->
foldl(fun(Sym, St) ->
@@ -1096,10 +1095,10 @@ compute_states2([{Sym,Seed} | Seeds], N, Try, CurrState, StateTab, Tables) ->
compute_states2(Seeds, N, Try, CurrState, StateTab, Tables);
{merge, M, NewCurrent} ->
%% io:fwrite(<<"Merging with state ~w\n">>, [M]),
- Try1 = case keysearch(M, 1, Try) of
+ Try1 = case lists:keyfind(M, 1, Try) of
false ->
[{M, NewCurrent} | Try];
- {value, {_, OldCurrent}} ->
+ {_, OldCurrent} ->
case ordsets:is_subset(NewCurrent, OldCurrent) of
true ->
Try;
diff --git a/lib/parsetools/src/yeccparser.erl b/lib/parsetools/src/yeccparser.erl
index 80a6bbce0e..415547b4ce 100644
--- a/lib/parsetools/src/yeccparser.erl
+++ b/lib/parsetools/src/yeccparser.erl
@@ -16,53 +16,52 @@ line_of(Token) ->
-file("/clearcase/otp/erts/lib/parsetools/include/yeccpre.hrl", 0).
%%
%% %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
%% 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%
%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% The parser generator will insert appropriate declarations before this line.%
--type(yecc_ret() :: {'error', _} | {'ok', _}).
+-type yecc_ret() :: {'error', _} | {'ok', _}.
--spec(parse/1 :: (_) -> yecc_ret()).
+-spec parse(_) -> yecc_ret().
parse(Tokens) ->
yeccpars0(Tokens, false).
--spec(parse_and_scan/1 ::
- ({function() | {atom(), atom()}, [_]} | {atom(), atom(), [_]}) ->
- yecc_ret()).
+-spec parse_and_scan({function() | {atom(), atom()}, [_]} | {atom(), atom(), [_]}) ->
+ yecc_ret().
parse_and_scan({F, A}) -> % Fun or {M, F}
yeccpars0([], {F, A});
parse_and_scan({M, F, A}) ->
yeccpars0([], {{M, F}, A}).
--spec(format_error/1 :: (any()) -> [char() | list()]).
+-spec format_error(any()) -> [char() | list()].
format_error(Message) ->
case io_lib:deep_char_list(Message) of
- true ->
- Message;
- _ ->
- io_lib:write(Message)
+ true ->
+ Message;
+ _ ->
+ io_lib:write(Message)
end.
-% To be used in grammar files to throw an error message to the parser
-% toplevel. Doesn't have to be exported!
+%% To be used in grammar files to throw an error message to the parser
+%% toplevel. Doesn't have to be exported!
-compile({nowarn_unused_function,{return_error,2}}).
--spec(return_error/2 :: (integer(), any()) -> no_return()).
+-spec return_error(integer(), any()) -> no_return().
return_error(Line, Message) ->
throw({error, {Line, ?MODULE, Message}}).
@@ -101,7 +100,7 @@ yeccpars1([Token | Tokens], Tokenizer, State, States, Vstack) ->
yeccpars1([], {F, A}, State, States, Vstack) ->
case apply(F, A) of
{ok, Tokens, _Endline} ->
- yeccpars1(Tokens, {F, A}, State, States, Vstack);
+ yeccpars1(Tokens, {F, A}, State, States, Vstack);
{eof, _Endline} ->
yeccpars1([], false, State, States, Vstack);
{error, Descriptor, _Endline} ->
@@ -123,7 +122,7 @@ yeccpars1(State1, State, States, Vstack, Stack1, [Token | Tokens],
yeccpars1(State1, State, States, Vstack, Stack1, [], {F, A}) ->
case apply(F, A) of
{ok, Tokens, _Endline} ->
- yeccpars1(State1, State, States, Vstack, Stack1, Tokens, {F, A});
+ yeccpars1(State1, State, States, Vstack, Stack1, Tokens, {F, A});
{eof, _Endline} ->
yeccpars1(State1, State, States, Vstack, Stack1, [], false);
{error, Descriptor, _Endline} ->
diff --git a/lib/parsetools/test/Makefile b/lib/parsetools/test/Makefile
new file mode 100644
index 0000000000..19354b87b2
--- /dev/null
+++ b/lib/parsetools/test/Makefile
@@ -0,0 +1,78 @@
+#
+# %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%
+#
+include $(ERL_TOP)/make/target.mk
+include $(ERL_TOP)/make/$(TARGET)/otp.mk
+
+MODULES = \
+ leex_SUITE \
+ yecc_SUITE
+
+ERL_FILES= $(MODULES:%=%.erl)
+
+TARGET_FILES= $(MODULES:%=$(EBIN)/%.$(EMULATOR))
+INSTALL_PROGS= $(TARGET_FILES)
+
+EMAKEFILE=Emakefile
+
+# ----------------------------------------------------
+# Release directory specification
+# ----------------------------------------------------
+RELSYSDIR = $(RELEASE_PATH)/parsetools_test
+
+# ----------------------------------------------------
+# FLAGS
+# ----------------------------------------------------
+ERL_MAKE_FLAGS +=
+ERL_COMPILE_FLAGS += -I$(ERL_TOP)/lib/test_server/include
+
+EBIN = .
+
+# ----------------------------------------------------
+# Targets
+# ----------------------------------------------------
+.PHONY: make_emakefile
+
+make_emakefile:
+ $(ERL_TOP)/make/make_emakefile $(ERL_COMPILE_FLAGS) -o$(EBIN) $(MODULES)\
+ > $(EMAKEFILE)
+
+tests debug opt: make_emakefile
+ erl $(ERL_MAKE_FLAGS) -make
+
+clean:
+ rm -f $(EMAKEFILE)
+ rm -f $(TARGET_FILES)
+ rm -f core
+
+docs:
+
+# ----------------------------------------------------
+# Release Target
+# ----------------------------------------------------
+include $(ERL_TOP)/make/otp_release_targets.mk
+
+release_spec: opt
+
+release_tests_spec: make_emakefile
+ $(INSTALL_DIR) $(RELSYSDIR)
+ $(INSTALL_DATA) parsetools.spec $(EMAKEFILE) $(ERL_FILES) $(RELSYSDIR)
+ chmod -f -R u+w $(RELSYSDIR)
+ # @tar cf - *_SUITE_data | (cd $(RELSYSDIR); tar xf -)
+
+release_docs_spec:
diff --git a/lib/parsetools/test/leex_SUITE.erl b/lib/parsetools/test/leex_SUITE.erl
new file mode 100644
index 0000000000..069f780b5e
--- /dev/null
+++ b/lib/parsetools/test/leex_SUITE.erl
@@ -0,0 +1,909 @@
+%%
+%% %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(leex_SUITE).
+
+%-define(debug, true).
+
+-include_lib("stdlib/include/erl_compile.hrl").
+-include_lib("kernel/include/file.hrl").
+
+-ifdef(debug).
+-define(line, put(line, ?LINE), ).
+-define(config(X,Y), foo).
+-define(datadir, "leex_SUITE_data").
+-define(privdir, "leex_SUITE_priv").
+-define(t, test_server).
+-else.
+-include("test_server.hrl").
+-define(datadir, ?config(data_dir, Config)).
+-define(privdir, ?config(priv_dir, Config)).
+-endif.
+
+-export([all/1, init_per_testcase/2, fin_per_testcase/2]).
+
+-export([checks/1,
+ file/1, compile/1, syntax/1,
+ examples/1,
+ pt/1, man/1, ex/1, ex2/1, not_yet/1]).
+
+% Default timetrap timeout (set in init_per_testcase).
+-define(default_timeout, ?t:minutes(1)).
+
+init_per_testcase(_Case, Config) ->
+ ?line Dog = ?t:timetrap(?default_timeout),
+ [{watchdog, Dog} | Config].
+
+fin_per_testcase(_Case, Config) ->
+ Dog = ?config(watchdog, Config),
+ test_server:timetrap_cancel(Dog),
+ ok.
+
+all(suite) -> [checks, examples].
+
+checks(suite) ->
+ [file, compile, syntax].
+
+file(doc) ->
+ "Bad files and options.";
+file(suite) -> [];
+file(Config) when is_list(Config) ->
+ Dir = ?privdir,
+ Ret = [return, {report, false}],
+ ?line {error,[{_,[{none,leex,{file_error,_}}]}],[]} =
+ leex:file("not_a_file", Ret),
+ ?line {error,[{_,[{none,leex,{file_error,_}}]}],[]} =
+ leex:file("not_a_file", [{return,true}]),
+ ?line {error,[{_,[{none,leex,{file_error,_}}]}],[]} =
+ leex:file("not_a_file", [{report,false},return_errors]),
+ ?line error = leex:file("not_a_file"),
+ ?line error = leex:file("not_a_file", [{return,false},report]),
+ ?line error = leex:file("not_a_file", [return_warnings,{report,false}]),
+
+ Filename = filename:join(Dir, "file.xrl"),
+ file:delete(Filename),
+
+ ?line {'EXIT', {badarg, _}} = (catch leex:file({foo})),
+ ?line {'EXIT', {badarg, _}} =
+ (catch leex:file(Filename, {parserfile,{foo}})),
+ ?line {'EXIT', {badarg, _}} =
+ (catch leex:file(Filename, {includefile,{foo}})),
+
+ ?line {'EXIT', {badarg, _}} = (catch leex:file(Filename, no_option)),
+ ?line {'EXIT', {badarg, _}} =
+ (catch leex:file(Filename, [return | report])),
+ ?line {'EXIT', {badarg, _}} =
+ (catch leex:file(Filename, {return,foo})),
+ ?line {'EXIT', {badarg, _}} =
+ (catch leex:file(Filename, includefile)),
+
+ Mini = <<"Definitions.\n"
+ "D = [0-9]\n"
+ "Rules.\n"
+ "{L}+ : {token,{word,TokenLine,TokenChars}}.\n"
+ "Erlang code.\n">>,
+ ?line ok = file:write_file(Filename, Mini),
+ ?line {error,[{_,[{none,leex,{file_error,_}}]}],[]} =
+ leex:file(Filename, [{scannerfile,"//"} | Ret]),
+ ?line {error,[{_,[{none,leex,{file_error,_}}]}],[]} =
+ leex:file(Filename, [{includefile,"//"} | Ret]),
+ ?line {error,[{_,[{none,leex,{file_error,_}}]}],[]} =
+ leex:file(Filename, [{includefile,"/ /"} | Ret]),
+
+ LeexPre = filename:join(Dir, "leexinc.hrl"),
+ ?line ok = file:write_file(LeexPre, <<"syntax error.\n">>),
+ PreErrors = run_test(Config, Mini, LeexPre),
+ ?line {errors,
+ [{1,_,["syntax error before: ","error"]},
+ {3,_,undefined_module}],
+ []} =
+ extract(LeexPre, PreErrors),
+ file:delete(LeexPre),
+
+ Ret2 = [return, report_errors, report_warnings, verbose],
+ Scannerfile = filename:join(Dir, "file.erl"),
+ ?line ok = file:write_file(Scannerfile, <<"nothing">>),
+ ?line unwritable(Scannerfile),
+ ?line {error,[{_,[{none,leex,{file_error,_}}]}],[]} =
+ leex:file(Filename, Ret2),
+ ?line writable(Scannerfile),
+ file:delete(Scannerfile),
+
+ Dotfile = filename:join(Dir, "file.dot"),
+ ?line ok = file:write_file(Dotfile, <<"nothing">>),
+ ?line unwritable(Dotfile),
+ ?line {error,[{_,[{none,leex,{file_error,_}}]}],[]} =
+ leex:file(Filename, [dfa_graph | Ret2]),
+ ?line writable(Dotfile),
+ file:delete(Dotfile),
+
+ file:delete(Filename),
+ ok.
+
+compile(doc) ->
+ "Check of compile/3.";
+compile(suite) -> [];
+compile(Config) when is_list(Config) ->
+ Dir = ?privdir,
+ Filename = filename:join(Dir, "file.xrl"),
+ Scannerfile = filename:join(Dir, "file.erl"),
+ Mini = <<"Definitions.\n"
+ "D = [0-9]\n"
+ "Rules.\n"
+ "{L}+ : {token,{word,TokenLine,TokenChars}}.\n"
+ "Erlang code.\n">>,
+ ?line ok = file:write_file(Filename, Mini),
+ ?line error = leex:compile(Filename, "//", #options{}),
+ ?line ok = leex:compile(Filename, Scannerfile, #options{}),
+ file:delete(Scannerfile),
+ file:delete(Filename),
+ ok.
+
+syntax(doc) ->
+ "Syntax checks.";
+syntax(suite) -> [];
+syntax(Config) when is_list(Config) ->
+ Dir = ?privdir,
+ Filename = filename:join(Dir, "file.xrl"),
+ Ret = [return, {report, true}],
+ ?line ok = file:write_file(Filename,
+ <<"Definitions.\n"
+ "D = [0-9]\n"
+ "%% comment\n"
+ "Rules.\n"
+ "{L}+ : {token,{word,TokenLine,TokenChars}}.\n
+ ">>),
+ ?line {error,[{_,[{7,leex,missing_code}]}],[]} = leex:file(Filename, Ret),
+ ?line ok = file:write_file(Filename,
+ <<"Definitions.\n"
+ "D = [0-9]\n"
+ "Rules.\n"
+ "{L}+ : \n">>),
+ ?line {error,[{_,[{5,leex,missing_code}]}],[]} = leex:file(Filename, Ret),
+ ?line ok = file:write_file(Filename,
+ <<"Definitions.\n"
+ "D = [0-9]\n"
+ "Rules.\n"
+ "[] :">>),
+ ?line {error,[{_,[{4,leex,{regexp,_}}]}],[]} =
+ leex:file(Filename, Ret),
+ ?line ok = file:write_file(Filename,
+ <<"Definitions.\n"
+ "D = [0-9]\n"
+ "Rules.\n"
+ "{L}+ : .\n"
+ "[] : ">>),
+ ?line {error,[{_,[{5,leex,{regexp,_}}]}],[]} =
+ leex:file(Filename, Ret),
+ ?line ok = file:write_file(Filename,
+ <<"Definitions.\n"
+ "D = [0-9]\n"
+ "Rules.\n"
+ "[] : .\n">>),
+ ?line {error,[{_,[{4,leex,{regexp,_}}]}],[]} =
+ leex:file(Filename, Ret),
+ ?line ok = file:write_file(Filename,
+ <<"Definitions.\n"
+ "D = [0-9]\n"
+ "Rules.\n"
+ "{L}+ ">>),
+ ?line {error,[{_,[{5,leex,bad_rule}]}],[]} =
+ leex:file(Filename, Ret),
+ ?line ok = file:write_file(Filename,
+ <<"Definitions.\n"
+ "D = [0-9]\n"
+ "Rules.\n"
+ "{L}+ ; ">>),
+ ?line {error,[{_,[{4,leex,bad_rule}]}],[]} =
+ leex:file(Filename, Ret),
+ ?line ok = file:write_file(Filename,
+ <<"Definitions.\n"
+ "D = [0-9]\n"
+ "Rules.\n"
+ "[] : '99\n">>),
+ ?line {error,[{_,[{4,erl_scan,_}]}],[]} = leex:file(Filename, Ret),
+ ?line ok = file:write_file(Filename,
+ <<"Definitions.\n"
+ "D = [0-9]\n"
+ "Rules.\n">>),
+ ?line {error,[{_,[{3,leex,empty_rules}]}],[]} = leex:file(Filename, Ret),
+ ?line ok = file:write_file(Filename,
+ <<"Definitions.\n"
+ "D = [0-9]\n"
+ "Rules.\n"
+ "Erlang code.\n">>),
+ ?line {error,[{_,[{4,leex,empty_rules}]}],[]} = leex:file(Filename, Ret),
+ ?line ok = file:write_file(Filename,
+ <<"Definitions.\n"
+ "D = [0-9]\n">>),
+ ?line {error,[{_,[{2,leex,missing_rules}]}],[]} = leex:file(Filename, Ret),
+ ?line ok = file:write_file(Filename,
+ <<"Definitions.\n"
+ "D = [0-9]\n"
+ "Erlang code.\n">>),
+ ?line {error,[{_,[{3,leex,missing_rules}]}],[]} = leex:file(Filename, Ret),
+ ?line ok = file:write_file(Filename,
+ <<"">>),
+ %% This is a weird line:
+ ?line {error,[{_,[{0,leex,missing_defs}]}],[]} = leex:file(Filename, Ret),
+ ?line ok = file:write_file(Filename,
+ <<"Rules.\n">>),
+ ?line {error,[{_,[{1,leex,missing_defs}]}],[]} = leex:file(Filename, Ret),
+
+ %% Check that correct line number is used in messages.
+ ErlFile = filename:join(Dir, "file.erl"),
+ Ret1 = [{scannerfile,ErlFile}|Ret],
+ ?line ok = file:write_file(Filename,
+ <<"Definitions.\n"
+ "D = [0-9]\n"
+ "Rules.\n"
+ "{L}+ : {token,\n"
+ " {word,TokenLine,TokenChars,\n"
+ " DDDD}}.\n" % unbound
+ "Erlang code.\n"
+ "an error.\n">>), % syntax error
+ ?line {ok, _, []} = leex:file(Filename, Ret1),
+ ?line {error,
+ [{_,[{8,_,["syntax error before: ","error"]}]},
+ {_,[{6,_,{unbound_var,'DDDD'}}]}],
+ []} =
+ compile:file(ErlFile, [basic_validation, return]),
+
+ %% Ignored characters
+ ?line ok = file:write_file(Filename,
+ <<"Definitions. D = [0-9]\n"
+ "Rules. [a-z] : .\n"
+ "1 : skip_token.\n"
+ "Erlang code. f() -> a.\n">>),
+ ?line {ok,_,[{_,
+ [{1,leex,ignored_characters},
+ {2,leex,ignored_characters},
+ {4,leex,ignored_characters}]}]} =
+ leex:file(Filename, Ret),
+
+ ?line ok = file:write_file(Filename,
+ <<"Definitions.\n"
+ "D = [0-9]\n"
+ "Rules.\n"
+ "{L}+\\ : token.\n">>),
+ ?line {error,[{_,[{4,leex,{regexp,{unterminated,"\\"}}}]}],[]} =
+ leex:file(Filename, Ret),
+ ?line ok = file:write_file(Filename,
+ <<"Definitions.\n"
+ "D = [0-9]\n"
+ "Rules.\n"
+ "{L}+\\x : token.\n">>),
+ ?line {error,[{_,[{4,leex,{regexp,{illegal_char,"\\x"}}}]}],[]} =
+ leex:file(Filename, Ret),
+ ?line ok = file:write_file(Filename,
+ <<"Definitions.\n"
+ "D = [0-9]\n"
+ "Rules.\n"
+ "{L}+\\x{ : token.\n">>),
+ ?line {error,[{_,[{4,leex,{regexp,{unterminated,"\\x{"}}}]}],[]} =
+ leex:file(Filename, Ret),
+ ?line ok = file:write_file(Filename,
+ <<"Definitions.\n"
+ "D = [0-9]\n"
+ "Rules.\n"
+ "[^ab : token.\n">>),
+ ?line {error,[{_,[{4,leex,{regexp,{unterminated,"["}}}]}],[]} =
+ leex:file(Filename, Ret),
+ ?line ok = file:write_file(Filename,
+ <<"Definitions.\n"
+ "D = [0-9]\n"
+ "Rules.\n"
+ "(a : token.\n">>),
+ ?line {error,[{_,[{4,leex,{regexp,{unterminated,"("}}}]}],[]} =
+ leex:file(Filename, Ret),
+ ?line ok = file:write_file(Filename,
+ <<"Definitions.\n"
+ "D = [0-9]\n"
+ "Rules.\n"
+ "[b-a] : token.\n">>),
+ ?line {error,[{_,[{4,leex,{regexp,{char_class,"b-a"}}}]}],[]} =
+ leex:file(Filename, Ret),
+
+ ?line ok = file:write_file(Filename,
+ <<"Definitions.\n"
+ "D = [0-9]\n"
+ "Rules.\n"
+ "\\x{333333333333333333333333} : token.\n">>),
+ ?line {error,[{_,[{4,leex,{regexp,
+ {illegal_char,
+ "\\x{333333333333333333333333}"}}}]}],[]} =
+ leex:file(Filename, Ret),
+ ok.
+
+examples(suite) ->
+ [pt,man,ex,ex2,not_yet].
+
+pt(doc) ->
+ "Pushing back characters.";
+pt(suite) -> [];
+pt(Config) when is_list(Config) ->
+ %% Needs more testing...
+ Ts = [{pt_1,
+ <<"Definitions.\n"
+ "D = [0-9]\n"
+ "L = [a-z]\n"
+
+ "Rules.\n"
+ "{L}+ : {token,{word,TokenLine,TokenChars}}.\n"
+ "abc{D}+ : {skip_token,\"sture\" ++ string:substr(TokenChars, 4)}.\n"
+ "{D}+ : {token,{integer,TokenLine,list_to_integer(TokenChars)}}.\n"
+ "\\s : .\n"
+ "\\r\\n : {end_token,{crlf,TokenLine}}.\n"
+
+ "Erlang code.\n"
+ "-export([t/0]).\n"
+ "t() ->
+ {ok,[{word,1,\"sture\"},{integer,1,123}],1} =
+ string(\"abc123\"), ok. ">>,
+ default,
+ ok}],
+
+ ?line run(Config, Ts),
+ ok.
+
+man(doc) ->
+ "Examples from the manpage.";
+man(suite) -> [];
+man(Config) when is_list(Config) ->
+ Ts = [{man_1,
+ <<"Definitions.\n"
+ "Rules.\n"
+ "[a-z][0-9a-zA-Z_]* :\n"
+ " {token,{atom,TokenLine,list_to_atom(TokenChars)}}.\n"
+ "[A-Z_][0-9a-zA-Z_]* :\n"
+ " {token,{var,TokenLine,list_to_atom(TokenChars)}}.\n"
+ "(\\+|-)?[0-9]+\\.[0-9]+((E|e)(\\+|-)?[0-9]+)? : \n"
+ " {token,{float,TokenLine,list_to_float(TokenChars)}}.\n"
+ "\\s : skip_token.\n"
+ "Erlang code.\n"
+ "-export([t/0]).\n"
+ "t() ->\n"
+ " {ok,[{float,1,3.14},{atom,1,atom},{var,1,'V314'}],1} =\n"
+ " string(\"3.14atom V314\"),\n"
+ " ok.\n">>,
+ default,
+ ok},
+
+ {man_2,
+ <<"Definitions.\n"
+ "D = [0-9]\n"
+ "Rules.\n"
+ "{D}+ :\n"
+ " {token,{integer,TokenLine,list_to_integer(TokenChars)}}.\n"
+ "{D}+\\.{D}+((E|e)(\\+|\\-)?{D}+)? :\n"
+ " {token,{float,TokenLine,list_to_float(TokenChars)}}.\n"
+ "\\s : skip_token.\n"
+ "Erlang code.\n"
+ "-export([t/0]).\n"
+ "t() ->\n"
+ " {ok,[{float,1,3.14},{integer,1,314}],1} = \n"
+ " string(\"3.14 314\"),\n"
+ " ok.\n">>,
+ default,
+ ok}],
+
+ ?line run(Config, Ts),
+ ok.
+
+ex(doc) ->
+ "Examples.";
+ex(suite) -> [];
+ex(Config) when is_list(Config) ->
+ Ts = [{ex_1,
+ <<"Definitions.\n"
+ "D = [0-543-705-982]\n"
+ "Rules.\n"
+ "{D}+ :\n"
+ " {token,{integer,TokenLine,list_to_integer(TokenChars)}}.\n"
+ "[^235]+ :\n"
+ " {token,{list_to_atom(TokenChars),TokenLine}}.\n"
+ "Erlang code.\n"
+ "-export([t/0]).\n"
+ "t() ->\n"
+ " {ok,[{integer,1,12},{' c\\na',1},{integer,2,34},{b789a,2}],2} =\n"
+ " string(\"12 c\\na34b789a\"),\n"
+ " ok.\n">>,
+ default,
+ ok},
+
+ {ex_2,
+ <<"Definitions.\n"
+ "L = [a-z]\n"
+ "D = [0-9]\n"
+ "Rules.\n"
+ "{L}+ : {token,chars}.\n"
+ "zyx{D}+ : {token,zyx}.\n"
+ "\\s : skip_token.\n"
+ "Erlang code.\n"
+ "-export([t/0]).\n"
+ "t() ->\n"
+ " {ok,[chars,zyx],1} = string(\"abcdef zyx123\"),\n"
+ " ok.\n">>,
+ default,
+ ok},
+
+ {ex_3,
+ <<"Definitions.\n"
+ "NL = [\\n]\n"
+ "Rules.\n"
+ "{NL}* : {token,newlines}.\n"
+ "Erlang code.\n"
+ "-export([t/0]).\n"
+ "t() ->\n"
+ " {ok,[],1} = string(\"\"), ok.\n">>, % string("a") would loop...
+ default,
+ ok},
+
+ {ex_4,
+ <<"Definitions.\n"
+ "SP1 = [\\n-\\s]\n"
+ "SP0 = [\\000-\\n]\n"
+ "Rules.\n"
+ "{SP0}+ : {token,{small,TokenChars}}.\n"
+ "{SP1}+ : {token,{big,TokenChars}}.\n"
+ "Erlang code.\n"
+ "-export([t/0]).\n"
+ "t() ->\n"
+ " string(\"\\x00\\n\\s\\n\\n\"),\n"
+ " ok.\n">>,
+ default,
+ ok},
+
+ {ex_5,
+ <<"Definitions.\n"
+ "L = [a-z]\n"
+ "W = [\\s\\b\\n\\r\\t\\e\\v\\d\\f]\n"
+ "Rules.\n"
+ "\\[{L}+(,{L}+)*\\] : {token,{list,TokenChars}}.\n"
+ "\"{L}+\" : {token,{string,TokenChars}}.\n"
+ "\\$. : {token,{char,TokenChars}}.\n"
+ "{W}+ : {token,{white,TokenChars}}.\n"
+ "ff\\f+ : {token,{form,TokenChars}}.\n"
+ "\\$\\^+\\\\+ : {token,{other,TokenChars}}.\n"
+ "Erlang code.\n"
+ "-export([t/0]).\n"
+ "t() ->\n"
+ " {ok,[{white,\"\\b\\f\"}],1} = string(\"\\b\\f\"),\n"
+ " {ok,[{form,\"ff\\f\"}],1} = string(\"ff\\f\"),\n"
+ " {ok,[{string,\"\\\"foo\\\"\"}],1} = string(\"\\\"foo\\\"\"),\n"
+ " {ok,[{char,\"$.\"}],1} = string(\"$\\.\"),\n"
+ " {ok,[{list,\"[a,b,c]\"}],1} = string(\"[a,b,c]\"),\n"
+ " {ok,[{other,\"$^\\\\\"}],1} = string(\"$^\\\\\"),\n"
+ " ok.\n">>,
+ default,
+ ok},
+
+ {ex_6,
+ <<"Definitions.\n"
+ "L = [a-z]\n"
+ "Rules.\n"
+ "L}+ : {token,{TokenChars,#r.f}}.\n"
+ "Erlang code.\n"
+ "-record(r, {f}).\n"
+ "-export([t/0]).\n"
+ "t() ->\n"
+ " string(\"abc\"),\n"
+ " ok.\n">>,
+ default,
+ ok},
+
+ {ex_7, %% Assumes regexp can handle \x
+ <<"Definitions.\n"
+ "H1 = \\x11\\x{ab}\n"
+ "H2 = [\\x{30}\\x{ac}]\n"
+ "Rules.\n"
+ "{H1}{H2}+ : {token,{hex,TokenChars}}.\n"
+ "Erlang code.\n"
+ "-export([t/0]).\n"
+ "t() ->\n"
+ " {ok,[{hex,[17,171,48,172]}],1} =\n"
+ " string(\"\\x{11}\\xab0\\xac\"),\n"
+ " ok.\n">>,
+ default,
+ ok}],
+
+ ?line run(Config, Ts),
+ ok.
+
+ex2(doc) ->
+ "More examples.";
+ex2(suite) -> [];
+ex2(Config) when is_list(Config) ->
+ Xrl =
+ <<"
+%%% File : erlang_scan.xrl
+%%% Author : Robert Virding
+%%% Purpose : Tkoen definitions for Erlang.
+
+Definitions.
+O = [0-7]
+D = [0-9]
+H = [0-9a-fA-F]
+U = [A-Z]
+L = [a-z]
+A = ({U}|{L}|{D}|_|@)
+WS = ([\\000-\\s]|%.*)
+
+Rules.
+{D}+\\.{D}+((E|e)(\\+|\\-)?{D}+)? :
+ {token,{float,TokenLine,list_to_float(TokenChars)}}.
+{D}+#{H}+ : base(TokenLine, TokenChars).
+{D}+ : {token,{integer,TokenLine,list_to_integer(TokenChars)}}.
+{L}{A}* : Atom = list_to_atom(TokenChars),
+ {token,case reserved_word(Atom) of
+ true -> {Atom,TokenLine};
+ false -> {atom,TokenLine,Atom}
+ end}.
+'(\\\\\\^.|\\\\.|[^'])*' :
+ %% Strip quotes.
+ S = lists:sublist(TokenChars, 2, TokenLen - 2),
+ case catch list_to_atom(string_gen(S)) of
+ {'EXIT',_} -> {error,\"illegal atom \" ++ TokenChars};
+ Atom -> {token,{atom,TokenLine,Atom}}
+ end.
+({U}|_){A}* : {token,{var,TokenLine,list_to_atom(TokenChars)}}.
+\"(\\\\\\^.|\\\\.|[^\"])*\" :
+ %% Strip quotes.
+ S = lists:sublist(TokenChars, 2, TokenLen - 2),
+ {token,{string,TokenLine,string_gen(S)}}.
+\\$(\\\\{O}{O}{O}|\\\\\\^.|\\\\.|.) :
+ {token,{char,TokenLine,cc_convert(TokenChars)}}.
+-> : {token,{'->',TokenLine}}.
+:- : {token,{':-',TokenLine}}.
+\\|\\| : {token,{'||',TokenLine}}.
+<- : {token,{'<-',TokenLine}}.
+\\+\\+ : {token,{'++',TokenLine}}.
+-- : {token,{'--',TokenLine}}.
+=/= : {token,{'=/=',TokenLine}}.
+== : {token,{'==',TokenLine}}.
+=:= : {token,{'=:=',TokenLine}}.
+/= : {token,{'/=',TokenLine}}.
+>= : {token,{'>=',TokenLine}}.
+=< : {token,{'=<',TokenLine}}.
+<= : {token,{'<=',TokenLine}}.
+<< : {token,{'<<',TokenLine}}.
+>> : {token,{'>>',TokenLine}}.
+:: : {token,{'::',TokenLine}}.
+[]()[}{|!?/;:,.*+#<>=-] :
+ {token,{list_to_atom(TokenChars),TokenLine}}.
+\\.{WS} : {end_token,{dot,TokenLine}}.
+{WS}+ : skip_token.
+
+Erlang code.
+
+-export([reserved_word/1]).
+
+%% reserved_word(Atom) -> Bool
+%% return 'true' if Atom is an Erlang reserved word, else 'false'.
+
+reserved_word('after') -> true;
+reserved_word('begin') -> true;
+reserved_word('case') -> true;
+reserved_word('try') -> true;
+reserved_word('cond') -> true;
+reserved_word('catch') -> true;
+reserved_word('andalso') -> true;
+reserved_word('orelse') -> true;
+reserved_word('end') -> true;
+reserved_word('fun') -> true;
+reserved_word('if') -> true;
+reserved_word('let') -> true;
+reserved_word('of') -> true;
+reserved_word('query') -> true;
+reserved_word('receive') -> true;
+reserved_word('when') -> true;
+reserved_word('bnot') -> true;
+reserved_word('not') -> true;
+reserved_word('div') -> true;
+reserved_word('rem') -> true;
+reserved_word('band') -> true;
+reserved_word('and') -> true;
+reserved_word('bor') -> true;
+reserved_word('bxor') -> true;
+reserved_word('bsl') -> true;
+reserved_word('bsr') -> true;
+reserved_word('or') -> true;
+reserved_word('xor') -> true;
+reserved_word('spec') -> true;
+reserved_word(_) -> false.
+
+base(L, Cs) ->
+ H = string:chr(Cs, $#),
+ case list_to_integer(string:substr(Cs, 1, H-1)) of
+ B when B > 16 -> {error,\"illegal base\"};
+ B ->
+ case base(string:substr(Cs, H+1), B, 0) of
+ error -> {error,\"illegal based number\"};
+ N -> {token,{integer,L,N}}
+ end
+ end.
+
+base([C|Cs], Base, SoFar) when C >= $0, C =< $9, C < Base + $0 ->
+ Next = SoFar * Base + (C - $0),
+ base(Cs, Base, Next);
+base([C|Cs], Base, SoFar) when C >= $a, C =< $f, C < Base + $a - 10 ->
+ Next = SoFar * Base + (C - $a + 10),
+ base(Cs, Base, Next);
+base([C|Cs], Base, SoFar) when C >= $A, C =< $F, C < Base + $A - 10 ->
+ Next = SoFar * Base + (C - $A + 10),
+ base(Cs, Base, Next);
+base([_|_], _, _) -> error; %Unknown character
+base([], _, N) -> N.
+
+cc_convert([$$,$\\\\|Cs]) ->
+ hd(string_escape(Cs));
+cc_convert([$$,C]) -> C.
+
+string_gen([$\\\\|Cs]) ->
+ string_escape(Cs);
+string_gen([C|Cs]) ->
+ [C|string_gen(Cs)];
+string_gen([]) -> [].
+
+string_escape([O1,O2,O3|S]) when
+ O1 >= $0, O1 =< $7, O2 >= $0, O2 =< $7, O3 >= $0, O3 =< $7 ->
+ [(O1*8 + O2)*8 + O3 - 73*$0|string_gen(S)];
+string_escape([$^,C|Cs]) ->
+ [C band 31|string_gen(Cs)];
+string_escape([C|Cs]) when C >= $\\000, C =< $\\s ->
+ string_gen(Cs);
+string_escape([C|Cs]) ->
+ [escape_char(C)|string_gen(Cs)].
+
+escape_char($n) -> $\\n; %\\n = LF
+escape_char($r) -> $\\r; %\\r = CR
+escape_char($t) -> $\\t; %\\t = TAB
+escape_char($v) -> $\\v; %\\v = VT
+escape_char($b) -> $\\b; %\\b = BS
+escape_char($f) -> $\\f; %\\f = FF
+escape_char($e) -> $\\e; %\\e = ESC
+escape_char($s) -> $\\s; %\\s = SPC
+escape_char($d) -> $\\d; %\\d = DEL
+escape_char(C) -> C.
+ ">>,
+ Dir = ?privdir,
+ XrlFile = filename:join(Dir, "erlang_scan.xrl"),
+ ?line ok = file:write_file(XrlFile, Xrl),
+ ErlFile = filename:join(Dir, "erlang_scan.erl"),
+ ?line {ok, _} = leex:file(XrlFile, []),
+ ?line {ok, _} = compile:file(ErlFile, [{outdir,Dir}]),
+ code:purge(erlang_scan),
+ AbsFile = filename:rootname(ErlFile, ".erl"),
+ code:load_abs(AbsFile, erlang_scan),
+
+ F = fun(Cont, Chars, Location) ->
+ erlang_scan:tokens(Cont, Chars, Location)
+ end,
+ F1 = fun(Cont, Chars, Location) ->
+ erlang_scan:token(Cont, Chars, Location)
+ end,
+ fun() ->
+ S = "ab cd. ",
+ {ok, Ts, 1} = scan_tokens_1(S, F, 1),
+ {ok, Ts, 1} = scan_token_1(S, F1, 1),
+ {ok, Ts, 1} = scan_tokens(S, F, 1),
+ {ok, Ts, 1} = erlang_scan:string(S, 1)
+ end(),
+ fun() ->
+ S = "'ab\n cd'. ",
+ {ok, Ts, 2} = scan_tokens_1(S, F, 1),
+ {ok, Ts, 2} = scan_token_1(S, F1, 1),
+ {ok, Ts, 2} = scan_tokens(S, F, 1),
+ {ok, Ts, 2} = erlang_scan:string(S, 1)
+ end(),
+ fun() ->
+ S = "99. ",
+ {ok, Ts, 1} = scan_tokens_1(S, F, 1),
+ {ok, Ts, 1} = scan_token_1(S, F1, 1),
+ {ok, Ts, 1} = scan_tokens(S, F, 1),
+ {ok, Ts, 1} = erlang_scan:string(S, 1)
+ end(),
+ {ok,[{integer,1,99},{dot,1}],1} = erlang_scan:string("99. "),
+ fun() ->
+ Atom = "'" ++ lists:duplicate(1000,$a) ++ "'",
+ S = Atom ++ ". ",
+ Reason = "illegal atom " ++ Atom,
+ Err = {error,{1,erlang_scan,{user,Reason}},1},
+ {done,Err,[]} = scan_tokens_1(S, F, 1),
+ {done,Err,[]} = scan_token_1(S, F1, 1),
+ {done,Err,[]} = scan_tokens(S, F, 1),
+ Err = erlang_scan:string(S, 1)
+ end(),
+ fun() ->
+ S = "\x{aaa}. ",
+ Err = {error,{1,erlang_scan,{illegal,[2730]}},1},
+ {done,Err,[]} = scan_tokens_1(S, F, 1),
+ {done,Err,[_]} = scan_token_1(S, F1, 1), % Note: Rest non-empty
+ {done,Err,[]} = scan_tokens(S, F, 1),
+ Err = erlang_scan:string(S, 1)
+ end(),
+ fun() ->
+ S = "\x{aaa} + 1. 34",
+ Err = {error,{1,erlang_scan,{illegal,[2730]}},1},
+ {done,Err,[]} = scan_tokens_1(S, F, 1),
+ {done,Err,[_]} = scan_token_1(S, F1, 1), % Note: Rest non-empty
+ {done,Err,"34"} = scan_tokens(S, F, 1),
+ Err = erlang_scan:string(S, 1)
+ end(),
+ fun() ->
+ S = "\x{aaa} \x{bbb}. 34",
+ Err = {error,{1,erlang_scan,{illegal,[2730]}},1},
+ {done,Err,[]} = scan_tokens_1(S, F, 1),
+ {done,Err,[_]} = scan_token_1(S, F1, 1), % Note: Rest non-empty
+ {done,Err,"34"} = scan_tokens(S, F, 1),
+ Err = erlang_scan:string(S, 1)
+ end(),
+ fun() ->
+ S = "\x{aaa} 18#34. 34",
+ Err = {error,{1,erlang_scan,{illegal,[2730]}},1},
+ {done,Err,[]} = scan_tokens_1(S, F, 1),
+ {done,Err,[_]} = scan_token_1(S, F1, 1), % Note: Rest non-empty
+ {done,Err,"34"} = scan_tokens(S, F, 1),
+ Err = erlang_scan:string(S, 1)
+ end(),
+ fun() ->
+ S = "\x{aaa}"++eof,
+ Err = {error,{1,erlang_scan,{illegal,[2730]}},1},
+ {done,Err,eof} = scan_tokens_1(S, F, 1),
+ {done,Err,[_]} = scan_token_1(S, F1, 1), % Note: Rest non-empty
+ {done,Err,eof} = scan_tokens(S, F, 1),
+ Err = erlang_scan:string(S, 1)
+ end(),
+ ok.
+
+scan_tokens(String, Fun, Location) ->
+ scan_tokens(String, Fun, Location, []).
+
+scan_tokens(String, Fun, Location, Rs) ->
+ case Fun([], String, Location) of
+ {done, {error,_,_}, _} = Error ->
+ Error;
+ {done, {ok,Ts,End}, ""} ->
+ {ok, lists:append(lists:reverse([Ts|Rs])), End};
+ {done, {ok,Ts,End}, Rest} ->
+ scan_tokens(Rest, Fun, End, [Ts|Rs])
+ end.
+
+scan_tokens_1(String, Fun, Location) ->
+ scan_tokens_1({more, []}, String, Fun, Location, []).
+
+scan_tokens_1({done, {error, _, _}, _}=Error, _Cs, _Fun, _Location, _Rs) ->
+ Error;
+scan_tokens_1({done, {ok,Ts,End}, ""}, "", _Fun, _Location, Rs) ->
+ {ok,lists:append(lists:reverse([Ts|Rs])),End};
+scan_tokens_1({done, {ok,Ts,End}, Rest}, Cs, Fun, _Location, Rs) ->
+ scan_tokens_1({more,[]}, Rest++Cs, Fun, End, [Ts|Rs]);
+scan_tokens_1({more, Cont}, [C | Cs], Fun, Loc, Rs) ->
+ R = Fun(Cont, [C], Loc),
+ scan_tokens_1(R, Cs, Fun, Loc, Rs);
+scan_tokens_1({more, Cont}, eof, Fun, Loc, Rs) ->
+ R = Fun(Cont, eof, Loc),
+ scan_tokens_1(R, eof, Fun, Loc, Rs).
+
+scan_token_1(String, Fun, Location) ->
+ scan_token_1({more, []}, String, Fun, Location, []).
+
+scan_token_1({done, {error, _, _}, _}=Error, _Cs, _Fun, _Location, _Rs) ->
+ Error;
+scan_token_1({done, {ok,Ts,End}, ""}, "", _Fun, _Location, Rs) ->
+ {ok,lists:reverse([Ts|Rs]),End};
+scan_token_1({done, {ok,Ts,End}, Rest}, Cs, Fun, _Location, Rs) ->
+ scan_token_1({more,[]}, Rest++Cs, Fun, End, [Ts|Rs]);
+scan_token_1({more, Cont}, [C | Cs], Fun, Loc, Rs) ->
+ R = Fun(Cont, [C], Loc),
+ scan_token_1(R, Cs, Fun, Loc, Rs).
+
+%% End of ex2
+
+not_yet(doc) ->
+ "Not yet implemented.";
+not_yet(suite) -> [];
+not_yet(Config) when is_list(Config) ->
+ Dir = ?privdir,
+ Filename = filename:join(Dir, "file.xrl"),
+ Ret = [return, {report, true}],
+ ?line ok = file:write_file(Filename,
+ <<"Definitions.\n"
+ "Rules.\n"
+ "$ : .\n"
+ "Erlang code.\n">>),
+ ?line {error,[{_,[{3,leex,{regexp,_}}]}],[]} =
+ leex:file(Filename, Ret),
+ ?line ok = file:write_file(Filename,
+ <<"Definitions.\n"
+ "Rules.\n"
+ "^ : .\n"
+ "Erlang code.\n">>),
+ ?line {error,[{_,[{3,leex,{regexp,_}}]}],[]} =
+ leex:file(Filename, Ret),
+
+ ok.
+
+unwritable(Fname) ->
+ {ok, Info} = file:read_file_info(Fname),
+ Mode = Info#file_info.mode - 8#00200,
+ ok = file:write_file_info(Fname, Info#file_info{mode = Mode}).
+
+writable(Fname) ->
+ {ok, Info} = file:read_file_info(Fname),
+ Mode = Info#file_info.mode bor 8#00200,
+ ok = file:write_file_info(Fname, Info#file_info{mode = Mode}).
+
+run(Config, Tests) ->
+ F = fun({N,P,Pre,E}) ->
+ case catch run_test(Config, P, Pre) of
+ E ->
+ ok;
+ Bad ->
+ ?t:format("~nTest ~p failed. Expected~n ~p~n"
+ "but got~n ~p~n", [N, E, Bad]),
+ fail()
+ end
+ end,
+ lists:foreach(F, Tests).
+
+run_test(Config, Def, Pre) ->
+ %% io:format("testing ~s~n", [binary_to_list(Def)]),
+ DefFile = 'leex_test.xrl',
+ Filename = 'leex_test.erl',
+ DataDir = ?privdir,
+ XrlFile = filename:join(DataDir, DefFile),
+ ErlFile = filename:join(DataDir, Filename),
+ Opts = [return, warn_unused_vars,{outdir,DataDir}],
+ ok = file:write_file(XrlFile, Def),
+ LOpts = [return, {report, false} |
+ case Pre of
+ default ->
+ [];
+ _ ->
+ [{includefile,Pre}]
+ end],
+ XOpts = [verbose, dfa_graph], % just to get some code coverage...
+ LRet = leex:file(XrlFile, XOpts ++ LOpts),
+ case LRet of
+ {ok, _Outfile, _LWs} ->
+ CRet = compile:file(ErlFile, Opts),
+ case CRet of
+ {ok, _M, _Ws} ->
+ AbsFile = filename:rootname(ErlFile, ".erl"),
+ Mod = leex_test,
+ code:purge(Mod),
+ code:load_abs(AbsFile, Mod),
+ Mod:t();
+ %% warnings(ErlFile, Ws);
+ {error, [{ErlFile,Es}], []} -> {error, Es, []};
+ {error, [{ErlFile,Es}], [{ErlFile,Ws}]} -> {error, Es, Ws};
+ Error -> Error
+ end;
+ {error, [{XrlFile,LEs}], []} -> {error, LEs, []};
+ {error, [{XrlFile,LEs}], [{XrlFile,LWs}]} -> {error, LEs, LWs};
+ LError -> LError
+ end.
+
+extract(File, {error, Es, Ws}) ->
+ {errors, extract(File, Es), extract(File, Ws)};
+extract(File, Ts) ->
+ lists:append([T || {F, T} <- Ts, F =:= File]).
+
+fail() ->
+ ?t:fail().
diff --git a/lib/parsetools/test/parsetools.spec b/lib/parsetools/test/parsetools.spec
new file mode 100644
index 0000000000..5b34633378
--- /dev/null
+++ b/lib/parsetools/test/parsetools.spec
@@ -0,0 +1 @@
+{topcase, {dir, "../parsetools_test"}}.
diff --git a/lib/parsetools/test/yecc_SUITE.erl b/lib/parsetools/test/yecc_SUITE.erl
new file mode 100644
index 0000000000..b5da414f7b
--- /dev/null
+++ b/lib/parsetools/test/yecc_SUITE.erl
@@ -0,0 +1,1795 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 2005-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(yecc_SUITE).
+
+%-define(debug, true).
+
+-include_lib("stdlib/include/erl_compile.hrl").
+
+-ifdef(debug).
+-define(line, put(line, ?LINE), ).
+-define(config(X,Y), foo).
+-define(datadir, "yecc_SUITE_data").
+-define(privdir, "yecc_SUITE_priv").
+-define(t, test_server).
+-else.
+-include("test_server.hrl").
+-define(datadir, ?config(data_dir, Config)).
+-define(privdir, ?config(priv_dir, Config)).
+-endif.
+
+-export([all/1, init_per_testcase/2, fin_per_testcase/2]).
+
+-export([app_test/1,
+ checks/1,
+ file/1, syntax/1, compile/1, rules/1, expect/1,
+ conflicts/1,
+ examples/1,
+ empty/1, prec/1, yeccpre/1, lalr/1, old_yecc/1,
+ other_examples/1,
+ bugs/1,
+ otp_5369/1, otp_6362/1, otp_7945/1,
+ improvements/1,
+ otp_7292/1, otp_7969/1]).
+
+% Default timetrap timeout (set in init_per_testcase).
+-define(default_timeout, ?t:minutes(1)).
+
+init_per_testcase(_Case, Config) ->
+ ?line Dog = ?t:timetrap(?default_timeout),
+ [{watchdog, Dog} | Config].
+
+fin_per_testcase(_Case, Config) ->
+ Dog = ?config(watchdog, Config),
+ test_server:timetrap_cancel(Dog),
+ ok.
+
+all(suite) -> [app_test, checks, examples, bugs, improvements].
+
+app_test(doc) ->
+ ["Tests the applications consistency."];
+app_test(suite) ->
+ [];
+app_test(Config) when is_list(Config) ->
+ ?line ok=?t:app_test(parsetools),
+ ok.
+
+checks(suite) ->
+ [file, syntax, compile, rules, expect, conflicts].
+
+file(doc) ->
+ "Bad files and options.";
+file(suite) -> [];
+file(Config) when is_list(Config) ->
+ Dir = ?privdir,
+ Ret = [return, {report, false}],
+ ?line {error,[{_,[{none,yecc,{file_error,_}}]}],[]} =
+ yecc:file("not_a_file", Ret),
+ ?line {error,[{_,[{none,yecc,{file_error,_}}]}],[]} =
+ yecc:file("not_a_file", [{return,true}]),
+ ?line {error,[{_,[{none,yecc,{file_error,_}}]}],[]} =
+ yecc:file("not_a_file", [{report,false},return_errors]),
+ ?line error = yecc:file("not_a_file"),
+ ?line error = yecc:file("not_a_file", [{return,false},report]),
+ ?line error = yecc:file("not_a_file", [return_warnings,{report,false}]),
+ Filename = filename:join(Dir, "file.yrl"),
+ file:delete(Filename),
+
+ ?line {'EXIT', {badarg, _}} = (catch yecc:file({foo})),
+ ?line {'EXIT', {badarg, _}} =
+ (catch yecc:file(Filename, {parserfile,{foo}})),
+ ?line {'EXIT', {badarg, _}} =
+ (catch yecc:file(Filename, {includefile,{foo}})),
+
+ ?line {'EXIT', {badarg, _}} = (catch yecc:file(Filename, no_option)),
+ ?line {'EXIT', {badarg, _}} =
+ (catch yecc:file(Filename, [return | report])),
+ ?line {'EXIT', {badarg, _}} =
+ (catch yecc:file(Filename, {return,foo})),
+ ?line {'EXIT', {badarg, _}} =
+ (catch yecc:file(Filename, includefile)),
+
+ Mini = <<"Nonterminals nt.
+ Terminals t.
+ Rootsymbol nt.
+ nt -> t.">>,
+ ?line ok = file:write_file(Filename, Mini),
+ ?line {error,[{_,[{none,yecc,{file_error,_}}]}],[]} =
+ yecc:file(Filename, [{parserfile,"//"} | Ret]),
+
+ ?line {error,[{_,[{none,yecc,{file_error,_}}]}],[]} =
+ yecc:file(Filename, [{includefile,"//"} | Ret]),
+ ?line {error,[{_,[{none,yecc,{file_error,_}}]}],[]} =
+ yecc:file(Filename, [{includefile,"/ /"} | Ret]),
+
+ YeccPre = filename:join(Dir, "yeccpre.hrl"),
+ ?line ok = file:write_file(YeccPre, <<"syntax error. ">>),
+ PreErrors1 = run_test(Config, Mini, YeccPre),
+ ?line {errors,[_],[]} = extract(YeccPre, PreErrors1),
+ ?line ok = file:write_file(YeccPre, my_yeccpre()),
+ ?line {'EXIT', {undef,_}} = (catch run_test(Config, Mini, YeccPre)),
+
+ MiniCode = <<"
+ Nonterminals nt.
+ Terminals t.
+ Rootsymbol nt.
+ nt -> t.
+ Erlang code.
+ ">>,
+ ?line {'EXIT', {undef,_}} = (catch run_test(Config, MiniCode, YeccPre)),
+
+ file:delete(YeccPre),
+ file:delete(Filename),
+
+ ok.
+
+syntax(doc) ->
+ "Syntax checks.";
+syntax(suite) -> [];
+syntax(Config) when is_list(Config) ->
+ Dir = ?privdir,
+ %% Report errors. Very simple test of format_error/1.
+ Ret = [return, {report, true}],
+ Filename = filename:join(Dir, "file.yrl"),
+ Parserfile1 = filename:join(Dir, "a file"),
+
+ ?line ok = file:write_file(Filename, <<"">>),
+ ?line {error,[{_,[{none,yecc,no_grammar_rules},
+ {none,yecc,nonterminals_missing},
+ {none,yecc,rootsymbol_missing},
+ {none,yecc,terminals_missing}]}],[]} =
+ yecc:file(Filename, Ret),
+
+ ?line ok = file:write_file(Filename, <<"Nonterminals">>),
+ ?line {error,[{_,[{_,yecc,{error,yeccparser,_}}]}],[]} =
+ yecc:file(Filename, Ret),
+
+ ?line ok = file:write_file(Filename, <<"Nonterminals nt.">>),
+ ?line {error,[{_,[{none,yecc,no_grammar_rules},
+ {none,yecc,rootsymbol_missing},
+ {none,yecc,terminals_missing}]}],[]} =
+ yecc:file(Filename, Ret),
+
+ ?line ok = file:write_file(Filename, <<"Nonterminals nt. Terminals t.">>),
+ ?line {error,[{_,[{none,yecc,no_grammar_rules},
+ {none,yecc,rootsymbol_missing}]}],[]} =
+ yecc:file(Filename, Ret),
+
+ %% Nonterminals and terminals not disjoint.
+ ?line ok = file:write_file(Filename,
+ <<"Nonterminals nt 't t'. Terminals t 't t'. Rootsymbol nt.">>),
+ ?line {error,[{_,[{1,yecc,{symbol_terminal_and_nonterminal,'t t'}},
+ {none,yecc,no_grammar_rules}]}],
+ []} = yecc:file(Filename, Ret),
+
+ %% Rootsymbol is not a nonterminal.
+ ?line ok = file:write_file(Filename,
+ <<"Nonterminals nt. Terminals t.
+ Rootsymbol t. nt -> t.">>),
+ ?line {error,[{_,[{2,yecc,{bad_rootsymbol,t}}]}],[]} =
+ yecc:file(Filename, Ret),
+
+ %% Rootsymbol is not a nonterminal.
+ ?line ok = file:write_file(Filename,
+ <<"Nonterminals nt. Terminals t.
+ Rootsymbol t. nt -> t.">>),
+ ?line {error,[{_,[{2,yecc,{bad_rootsymbol,t}}]}],[]} =
+ yecc:file(Filename, Ret),
+
+ %% Endsymbol is a nonterminal.
+ ?line ok = file:write_file(Filename,
+ <<"Nonterminals nt. Terminals t. Rootsymbol nt.
+ Endsymbol nt.
+ nt -> t.">>),
+ ?line {error,[{_,[{2,yecc,{endsymbol_is_nonterminal,nt}}]}],[]} =
+ yecc:file(Filename, Ret),
+
+ %% Endsymbol is a terminal.
+ ?line ok = file:write_file(Filename,
+ <<"Nonterminals nt. Terminals t. Rootsymbol nt.
+ Endsymbol t.
+ nt -> t.">>),
+ ?line {error,[{_,[{2,yecc,{endsymbol_is_terminal,t}}]}],[]} =
+ yecc:file(Filename, Ret),
+
+ %% No grammar rules.
+ ?line ok = file:write_file(Filename,
+ <<"Nonterminals nt. Terminals t. Rootsymbol nt. Endsymbol e.">>),
+ ?line {error,[{_,[{none,yecc,no_grammar_rules}]}],[]} =
+ yecc:file(Filename, Ret),
+
+ %% Bad declaration.
+ ?line ok = file:write_file(Filename,
+ <<"Nonterminals nt. Terminals t. Rootsymbol nt. Endsymbol e.
+ nt -> t. e e.">>),
+ ?line {ok,_,[{_,[{2,yecc,bad_declaration}]}]} =
+ yecc:file(Filename, Ret),
+
+ %% Bad declaration.
+ ?line ok = file:write_file(Filename,
+ <<"Nonterminals nt. Terminals t.
+ Rootsymbol nt nt. Rootsymbol nt. Endsymbol e.
+ nt -> t.">>),
+ ?line {ok,_,[{_,[{2,yecc,bad_declaration}]}]} =
+ yecc:file(Filename, Ret),
+
+ %% Syntax error found by yeccparser.
+ ?line ok = file:write_file(Filename,
+ <<"Nonterminals nt. Terminals t. Rootsymbol nt. Endsymbol e.
+ a - a.">>),
+ ?line {error,[{_,[{2,yecc,{error,_yeccparser,_}}]}],[]} =
+ yecc:file(Filename, Ret),
+
+ %% Syntax error: unknown nonterminal.
+ ?line ok = file:write_file(Filename,
+ <<"Nonterminals nt. Terminals t. Rootsymbol nt. Endsymbol e.
+ 'unknown ' -> t.">>),
+ ?line {error,[{_,[{2,yecc,{undefined_nonterminal,'unknown '}}]}],[]} =
+ yecc:file(Filename, Ret),
+
+ %% Undefined rhs symbols. Note quotes in output.
+ ?line ok = file:write_file(Filename,
+ <<"Nonterminals Nonterminals nt.
+ Terminals t Terminals.
+ Rootsymbol nt.
+ Endsymbol e.
+ nt -> Nonterminals.
+ Nonterminals -> Terminals receive foo 45
+ '17' 'a b'.">>),
+ ?line {error,[{_,[{6,yecc,{undefined_symbol,45}},
+ {6,yecc,{undefined_symbol,foo}},
+ {6,yecc,{undefined_symbol,'receive'}},
+ {7,yecc,{undefined_symbol,'17'}},
+ {7,yecc,{undefined_symbol,'a b'}}]}],[]} =
+ yecc:file(Filename, Ret),
+
+ %% '$empty' used early, before Terminals. OK.
+ ?line ok = file:write_file(Filename,
+ <<"Nonterminals nt.
+ nt -> '$empty'.
+ Terminals t.
+ Rootsymbol nt.
+ Endsymbol e.">>),
+ ?line {ok,_,[{_,[{3,yecc,{unused_terminal,t}}]}]} =
+ yecc:file(Filename, Ret),
+
+ %% Illegal use of '$empty'.
+ ?line ok = file:write_file(Filename,
+ <<"Nonterminals nt nt2.
+ Terminals t.
+ Rootsymbol nt.
+ Endsymbol e.
+ nt -> t.
+ nt2 -> t '$empty'.">>),
+ ?line {error,[{_,[{6,yecc,illegal_empty}]}],[]} =
+ yecc:file(Filename, Ret),
+
+ ParserFile3 = [{parserfile, Parserfile1}],
+
+ %% Bad Erlang expression in action. Changed in OTP-7224.
+ ?line ok = file:write_file(Filename,
+ <<"Nonterminals nt.
+ Terminals t.
+ Rootsymbol nt.
+ Endsymbol e.
+ nt -> t : a bad code.">>),
+ ?line {ok, _, []} = yecc:file(Filename, ParserFile3 ++ Ret),
+
+ SzYeccPre = yeccpre_size(),
+ %% Note: checking the line numbers. Changes when yeccpre.hrl changes.
+ fun() ->
+ ?line {error,[{_,[{5,_,["syntax error before: ","bad"]}]},
+ {_,[{L1,_,{undefined_function,{yeccpars2_2_,1}}},
+ {L2,_,{bad_inline,{yeccpars2_2_,1}}}]}],
+ []} = compile:file(Parserfile1, [basic_validation,return]),
+ ?line L1 = 24 + SzYeccPre,
+ ?line L2 = 31 + SzYeccPre
+ end(),
+
+ %% Bad macro in action. OTP-7224.
+ ?line ok = file:write_file(Filename,
+ <<"Nonterminals nt.
+ Terminals t.
+ Rootsymbol nt.
+ Endsymbol e.
+ nt -> t : ?F(3).">>),
+ ?line {ok, _, []} = yecc:file(Filename, ParserFile3 ++ Ret),
+ %% Note: checking the line numbers. Changes when yeccpre.hrl changes.
+ fun() ->
+ ?line {error,[{_,[{5,_,{undefined,'F',1}}]},
+ {_,[{L1,_,{undefined_function,{yeccpars2_2_,1}}},
+ {L2,_,{bad_inline,{yeccpars2_2_,1}}}]}],
+ []} = compile:file(Parserfile1, [basic_validation,return]),
+ ?line L1 = 24 + SzYeccPre,
+ ?line L2 = 31 + SzYeccPre
+ end(),
+
+ %% Check line numbers. OTP-7224.
+ ?line ok = file:write_file(Filename,
+ <<"Terminals t.
+ Nonterminals nt.
+ Rootsymbol nt.
+ Endsymbol e.
+ nt -> t : ?F(3).
+ Erlang code.
+ -define(F(X), X).
+ t() ->
+ bad().">>),
+ ?line {ok, _, []} = yecc:file(Filename, ParserFile3 ++ Ret),
+ ?line {error,[{_,[{9,_,{undefined_function,{bad,0}}}]}],
+ [{_,[{8,_,{unused_function,{t,0}}}]}]}
+ = compile:file(Parserfile1, [basic_validation, return]),
+
+ %% Terminals defined before nonterminals. (One of many checks...)
+ %% Used to give an error message, but now allowed.
+ ?line ok = file:write_file(Filename,
+ <<"Terminals t.
+ Nonterminals nt.
+ Rootsymbol nt.
+ Endsymbol e.
+ nt -> t.
+ Erlang code.">>),
+ ?line {ok, _, []} = yecc:file(Filename, Ret),
+
+ %% Precedence with swapped arguments. Bad declaration.
+ ?line ok = file:write_file(Filename,
+ <<"Nonterminals nt.
+ Terminals t.
+ Rootsymbol nt.
+ Endsymbol e.
+ nt -> t.
+ Right t.
+ Left nt 100.">>),
+ ?line {ok,_,[{_,[{6,yecc,bad_declaration},{7,yecc,bad_declaration}]}]} =
+ yecc:file(Filename, Ret),
+
+ %% Precedence with unknown operator.
+ ?line ok = file:write_file(Filename,
+ <<"Nonterminals nt.
+ Terminals t.
+ Rootsymbol nt.
+ Endsymbol e.
+ nt -> t.
+ Unary 100 '-'.">>),
+ ?line {error,[{_,[{6,yecc,{precedence_op_is_unknown,'-'}}]}],[]} =
+ yecc:file(Filename, Ret),
+
+ %% Precedence with endsymbol operator.
+ ?line ok = file:write_file(Filename,
+ <<"Nonterminals nt.
+ Terminals t.
+ Rootsymbol nt.
+ Endsymbol e.
+ nt -> t.
+ Unary 100 e.">>),
+ ?line {error,[{_,[{6,yecc,{precedence_op_is_endsymbol,e}}]}],[]} =
+ yecc:file(Filename, Ret),
+
+ %% Duplicated precedence.
+ ?line ok = file:write_file(Filename, <<"
+ Nonterminals nt.
+ Terminals t '+'.
+ Rootsymbol nt.
+ nt -> t '+' nt.
+ Left 100 '+'.
+ Right 200 t.
+ Left 200 '+'.
+ Left 200 '+'.
+ Right 200 t.">>),
+ ?line {error,[{_,[{8,yecc,{duplicate_precedence,'+'}},
+ {9,yecc,{duplicate_precedence,'+'}},
+ {10,yecc,{duplicate_precedence,t}}]}],
+ []} = yecc:file(Filename, Ret),
+
+ %% Duplicated nonterminal.
+ ?line ok = file:write_file(Filename,
+ <<"Nonterminals 'n t' 'n t'. Terminals t.
+ Rootsymbol 'n t'. 'n t' -> t.">>),
+ ?line {ok, _, [{_,[{1,yecc,{duplicate_nonterminal,'n t'}}]}]} =
+ yecc:file(Filename, Ret),
+ ?line {ok, _, [{_,[{1,yecc,{duplicate_nonterminal,'n t'}}]}]} =
+ yecc:file(Filename, [return_warnings, {report, false}]),
+ ?line {ok, _} = yecc:file(Filename),
+ ?line {ok, _} =
+ yecc:file(Filename, [{report,false}, {return_warnings,false}]),
+
+ %% Duplicated terminal.
+ ?line ok = file:write_file(Filename,
+ <<"Nonterminals nt. Terminals 't t' 't t'.
+ Rootsymbol nt. nt -> 't t'.">>),
+ ?line {ok, _, [{_,[{1,yecc,{duplicate_terminal,'t t'}}]}]} =
+ yecc:file(Filename, Ret),
+
+ %% Two Nonterminals declarations.
+ ?line ok = file:write_file(Filename,
+ <<"Nonterminals nt. Terminals t.
+ Nonterminals nt2.
+ Rootsymbol nt2. nt -> t. nt2 -> nt.">>),
+ ?line {error,[{_,[{2,yecc,{duplicate_declaration,'Nonterminals'}}]}],
+ []} = yecc:file(Filename, Ret),
+
+ %% Three Terminals declarations.
+ ?line ok = file:write_file(Filename,
+ <<"Nonterminals nt. Terminals t.
+ Terminals t1.
+ Terminals t1.
+ Rootsymbol nt. nt -> t t1.">>),
+ ?line {error,[{_,[{2,yecc,{duplicate_declaration,'Terminals'}},
+ {3,yecc,{duplicate_declaration,'Terminals'}}]}],
+ []} = yecc:file(Filename, Ret),
+
+ %% Two root symbols.
+ ?line ok = file:write_file(Filename,
+ <<"Nonterminals nt. Terminals t. Rootsymbol t.
+ Rootsymbol nt. nt -> t.">>),
+ ?line {error,[{_,[{2,yecc,{duplicate_declaration,'Rootsymbol'}}]}],[]} =
+ yecc:file(Filename, Ret),
+
+ %% Two end symbols.
+ ?line ok = file:write_file(Filename,
+ <<"Nonterminals nt. Terminals t. Rootsymbol t.
+ Endsymbol e.
+ Endsymbol e. nt -> t.">>),
+ ?line {error,[{_,[{3,yecc,{duplicate_declaration,'Endsymbol'}}]}],[]} =
+ yecc:file(Filename, Ret),
+
+ %% Two end symbols.
+ ?line ok = file:write_file(Filename,
+ <<"Nonterminals nt. Terminals t. Rootsymbol t.
+ Expect 1.
+ Expect 0.
+ Endsymbol e. nt -> t.">>),
+ ?line {error,[{_,[{3,yecc,{duplicate_declaration,'Expect'}}]}],[]} =
+ yecc:file(Filename, Ret),
+
+ %% Some words should not be used.
+ ?line ok = file:write_file(Filename, <<"
+ Terminals '$empty' '$end'.
+ Nonterminals '$undefined'.
+ Rootsymbol '$undefined'.
+ Endsymbol '$end'.
+ '$undefined' -> '$empty'.
+ ">>),
+ ?line {error,[{_,[{2,yecc,{reserved,'$empty'}},
+ {2,yecc,{reserved,'$end'}},
+ {3,yecc,{reserved,'$undefined'}},
+ {5,yecc,{endsymbol_is_terminal,'$end'}}]}],[]} =
+ yecc:file(Filename, Ret),
+
+ %% Undefined pseudo variable.
+ ?line ok = file:write_file(Filename,<<"
+ Nonterminals nt.
+ Terminals t.
+ Rootsymbol nt.
+ nt -> t : '$2'.
+ ">>),
+ ?line {error,[{_,[{5,yecc,{undefined_pseudo_variable,'$2'}}]}],[]} =
+ yecc:file(Filename, Ret),
+
+ %% Space in module name.
+ ?line ok = file:write_file(Filename, <<"
+ Nonterminals list.
+ Terminals element.
+ Rootsymbol list.
+
+ list -> element : {single, '$1'}.
+ list -> list element : {pair, '$1', '$2'}.
+
+ Erlang code.
+
+ -export([t/0]).
+
+ t() ->
+ L = [{element, 1}, {element, 2}, {element, 3}],
+ {ok,_} = parse(L),
+ ok.
+ ">>),
+
+ Parserfile2 = filename:join(Dir, "a \"file\""),
+ %% The parser (yeccgramm.yrl) allows many symbol names...
+ ?line ok = file:write_file(Filename, <<"
+ Nonterminals Nonterminals Rootsymbol ':' '->'.
+ Terminals Terminals.
+ Rootsymbol Rootsymbol.
+ Endsymbol e.
+ Rootsymbol -> Nonterminals ':' '->'.
+ Nonterminals -> Terminals.
+ ':' -> '->'.
+ '->' -> Terminals.
+ ">>),
+ ?line {ok, _} = yecc:file(Filename, [{parserfile, Parserfile1}]),
+ ?line {ok, _} = yecc:file(Filename, [{parserfile, Parserfile1},time]),
+ ?line {ok,[]} = compile:file(Parserfile1, [basic_validation]),
+
+ Quotes = <<"
+ Nonterminals
+ tail try 17 42 Unused ' unused ' '42' 'fnutt\\'' receive.
+
+ Terminals
+ ']' '|' ',' '\"hi\"' 'there\\'' 'you\\'' ACCEPT.
+
+ Rootsymbol 17.
+
+ Endsymbol '$end'.
+
+ 17 -> try : '$1':more([\"hi \\\" there\", '.', 3.14, % $3 , % '$1' is a module
+ -104, ' ', ' a', '->', $a, $\t]), '$1'.
+
+ try -> tail 'you\\'' 'fnutt\\''.
+
+ 'fnutt\\'' -> 'you\\'' ACCEPT.
+
+ '42' -> tail.
+
+ tail -> ']' :
+ (fun(Strange) -> foo end)(apa).
+ tail -> '|' try ']' :
+ (fun(Strange) -> foo;
+ (_) -> 'when' % warning
+ end)('ap a', foo),
+ %% This line intentionally left blank.
+ R = #rec{},
+ A = R#rec.a,
+ <<\"hi\">> = <<\"hi\">>,
+ there.
+ tail -> ',' try tail : {cons,line('$2'),'$2','$3'}.
+
+
+ Erlang code.
+
+ -export([t/0]).
+
+ -record(rec, {a}).
+
+ just(Some, Code) ->
+ true.
+
+ more(Code) ->
+ io:format(\"~p~n\", [Code]), true.
+
+ line(_) ->
+ 17.
+
+ t() ->
+ ok. % compiled successfully...
+
+ ">>,
+
+ ?line ok = file:write_file(Filename, Quotes),
+ ?line {ok,_,[{_,
+ [{3,yecc,{unused_nonterminal,42}},
+ {3,yecc,{unused_nonterminal,' unused '}},
+ {3,yecc,{unused_nonterminal,'42'}},
+ {3,yecc,{unused_nonterminal,'Unused'}},
+ {3,yecc,{unused_nonterminal,'receive'}},
+ {6,yecc,{unused_terminal,'"hi"'}},
+ {6,yecc,{unused_terminal,'there\''}}]}]} =
+ yecc:file(Filename, Ret),
+
+ Ts = [{quotes, Quotes, default, ok}],
+ ?line run(Config, Ts),
+
+ %% Non-terminal has no rules, but is unused.
+ ?line ok = file:write_file(Filename,<<"
+ Nonterminals nt bad.
+ Terminals t.
+ Rootsymbol nt.
+
+ nt -> t : something.
+ ">>),
+ ?line {ok,_,[{_,[{2,yecc,{unused_nonterminal,bad}}]}]} =
+ yecc:file(Filename, Ret),
+
+ %% Non-terminal has no rules and is used.
+ ?line ok = file:write_file(Filename,<<"
+ Nonterminals nt bad.
+ Terminals t.
+ Rootsymbol nt.
+
+ nt -> t bad : something.
+ ">>),
+ ?line {error,[{_,[{2,yecc,{missing_syntax_rule,bad}}]}],[]} =
+ yecc:file(Filename, Ret),
+
+ %% Warning in Erlang code. With and without file attributes.
+ ?line ok = file:write_file(Filename,<<"
+ Nonterminals nt.
+ Terminals t.
+ Rootsymbol nt.
+
+ nt -> t : t(17).
+
+ Erlang code.
+
+ t(A) ->
+ b.
+ ">>),
+ ?line {ok, _, []} =
+ yecc:file(Filename, [file_attributes | Ret]),
+ Opts = [basic_validation, return],
+ Erlfile = filename:join(Dir, "file.erl"),
+ ?line {ok,[],[{_,[{10,_,_}]}]} = compile:file(Erlfile, Opts),
+ ?line {ok, _, []} =
+ yecc:file(Filename, [{file_attributes,false} | Ret]),
+ ?line {ok,[],[{_,[{4,_,_}]}]} = compile:file(Erlfile, Opts),
+
+ file:delete(Parserfile1 ++ ".erl"),
+ file:delete(Parserfile2 ++ ".erl"),
+ file:delete(Filename),
+
+ ok.
+
+compile(doc) ->
+ "Check of compile/3.";
+compile(suite) -> [];
+compile(Config) when is_list(Config) ->
+ Dir = ?privdir,
+ Filename = filename:join(Dir, "file.yrl"),
+ Parserfile = filename:join(Dir, "file.erl"),
+ ?line ok = file:write_file(Filename,
+ <<"Nonterminals nt.
+ Terminals t.
+ Rootsymbol nt.
+ nt -> t.">>),
+ ?line error = yecc:compile(Filename, "//", #options{}),
+ ?line ok = yecc:compile(Filename, Parserfile, #options{}),
+ file:delete(Parserfile),
+ file:delete(Filename),
+ ok.
+
+rules(doc) ->
+ "Check of rules.";
+rules(suite) -> [];
+rules(Config) when is_list(Config) ->
+ Dir = ?privdir,
+ Ret = [return, {report, false}],
+ Filename = filename:join(Dir, "file.yrl"),
+
+ ?line ok = file:write_file(Filename,
+ <<"Nonterminals nt. Terminals t. Rootsymbol nt.
+ nt -> t. nt -> t.">>),
+ ?line {error,[{_,[{none,yecc,{conflict,_}}]}],
+ [{_,[{none,yecc,{conflicts,0,1}}]}]} =
+ yecc:file(Filename, [return, report]),
+
+ ?line ok = file:write_file(Filename, <<"
+ Nonterminals A B E.
+ Terminals c d f x y.
+ Rootsymbol A.
+
+ A -> B c d.
+ A -> E c f.
+ B -> x y.
+ E -> x y.
+ ">>),
+ ?line {error,[{_,[{none,yecc,{conflict,_}}]}],
+ [{_,[{none,yecc,{conflicts,0,1}}]}]} =
+ yecc:file(Filename, Ret),
+
+ ?line ok = file:write_file(Filename,<<"
+ Terminals t.
+ Nonterminals nt.
+ Rootsymbol nt.
+ nt -> '$empty' : '$1'.
+ nt -> t.
+ ">>),
+ ?line {error,[{_,[{5,yecc,{undefined_pseudo_variable,'$1'}}]}],[]} =
+ yecc:file(Filename, Ret),
+
+ ?line ok = file:write_file(Filename,<<"
+ Terminals t.
+ Nonterminals nt.
+ Rootsymbol nt.
+ nt -> '$empty' : '$0'.
+ nt -> t.
+ ">>),
+ ?line {error,[{_,[{5,yecc,{undefined_pseudo_variable,'$0'}}]}],[]} =
+ yecc:file(Filename, Ret),
+
+ file:delete(Filename),
+
+ %% No precedences.
+ Ts = [{rules_1,<<"
+ Nonterminals exp.
+ Terminals number '*' '+' '(' ')'.
+ Rootsymbol exp.
+
+ exp -> exp '+' exp : {plus,'$1','$3'}.
+ exp -> exp '*' exp : {times,'$1','$3'}.
+ exp -> number : element(2, '$1').
+ exp -> '(' exp ')' : '$2'.
+
+ Erlang code.
+
+ -export([t/0]).
+
+ t() ->
+ {ok, {times, 1, {plus, 3, 5}}} =
+ parse([{number,1}, {'*',2}, {number,3},
+ {'+',4}, {number,5}]),
+ ok.
+ ">>,
+ default,
+ ok}],
+ ?line run(Config, Ts),
+ ok.
+
+examples(suite) ->
+ [empty, prec, yeccpre, lalr, old_yecc, other_examples].
+
+expect(doc) ->
+ "Check of expect.";
+expect(suite) -> [];
+expect(Config) when is_list(Config) ->
+ Dir = ?privdir,
+ Ret = [return, {report, true}],
+ Filename = filename:join(Dir, "file.yrl"),
+
+ ?line ok = file:write_file(Filename, <<"
+ Nonterminals e.
+ Terminals i t else.
+ Rootsymbol e.
+ Expect a.
+
+ e -> i e t e.
+ e -> i e t e else e.
+ ">>),
+ ?line {error,[{_,[{5,yecc,{bad_expect,a}}]}],[]} =
+ yecc:file(Filename, Ret),
+
+ ?line ok = file:write_file(Filename, <<"
+ Nonterminals e.
+ Terminals i t else.
+ Rootsymbol e.
+ Expect 1.
+
+ e -> i e t e.
+ e -> i e t e else e.
+ ">>),
+ ?line {ok, _, []} = yecc:file(Filename, Ret),
+
+ ?line ok = file:write_file(Filename, <<"
+ Nonterminals e.
+ Terminals i t else.
+ Rootsymbol e.
+ Expect 2.
+
+ e -> i e t e.
+ e -> i e t e else e.
+ ">>),
+ ?line {ok, _, [{_,[{none,yecc,{conflicts,1,0}}]}]} =
+ yecc:file(Filename, Ret),
+
+ ?line ok = file:write_file(Filename, <<"
+ Nonterminals e.
+ Terminals i t else.
+ Rootsymbol e.
+ Expect -2.
+
+ e -> i e t e.
+ e -> i e t e else e.
+ ">>),
+ ?line {error,[{_,[{5,yecc,{error,_yeccparser,_}}]}],[]} =
+ yecc:file(Filename, Ret),
+
+ %% States N. An undocumented declaration used for testing.
+ ?line ok = file:write_file(Filename, <<"
+ Nonterminals nt.
+ Terminals t.
+ Rootsymbol nt.
+ States 100.
+ nt -> t.">>),
+ ?line {ok,_,[{_, [{none,yecc,{n_states,100,3}}]}]} =
+ yecc:file(Filename, Ret),
+
+ ?line ok = file:write_file(Filename, <<"
+ Nonterminals nt.
+ Terminals t.
+ Rootsymbol nt.
+ States bad.
+ nt -> t.">>),
+ ?line {error,[{_,[{5,yecc,{bad_states,bad}}]}],[]} =
+ yecc:file(Filename, Ret),
+
+ file:delete(Filename),
+ ok.
+
+conflicts(doc) ->
+ "Shift/reduce and reduce/reduce conflicts.";
+conflicts(suite) -> [];
+conflicts(Config) when is_list(Config) ->
+ Dir = ?privdir,
+ Ret = [return, {report, true}],
+ Filename = filename:join(Dir, "file.yrl"),
+
+ ?line ok = file:write_file(Filename, <<"
+ Nonterminals S List Tuple Elements Element.
+ Terminals '{' '}' '[' ']' ',' nil e.
+ Rootsymbol S.
+
+ S -> '$empty' : empty.
+ S -> List : '$1'.
+
+ List -> '$empty' : [].
+ List -> nil : [].
+ List -> '[' Tuple ']' : {list, '$2'}.
+
+ Tuple -> '$empty' : {}.
+ Tuple -> '{' '}' : {}.
+ Tuple -> '{' Elements '}' : {tuple, '$2'}.
+
+ Elements -> '$empty' : none.
+ Elements -> Elements ',' Element : {elements, '$3', '$1'}.
+ Elements -> Element : '$1'.
+
+ Element -> List : '$1'.
+ Element -> Tuple : '$1'.
+ Element -> e : '$1'.
+ ">>),
+ ?line {error,[{_,_}],[{_,[{none,yecc,{conflicts,1,5}}]}]} =
+ yecc:file(Filename, Ret),
+
+ %% Can easily be resolved (but don't do it!).
+ ?line ok = file:write_file(Filename, <<"
+ Nonterminals S List Tuple Elements Element.
+ Terminals '{' '}' '[' ']' ',' nil e.
+ Rootsymbol S.
+
+ Right 100 List.
+
+ S -> '$empty' : empty.
+ S -> List : '$1'.
+
+ List -> '$empty' : [].
+ List -> nil : [].
+ List -> '[' Tuple ']' : {list, '$2'}.
+
+ Tuple -> '$empty' : {}.
+ Tuple -> '{' '}' : {}.
+ Tuple -> '{' Elements '}' : {tuple, '$2'}.
+
+ Elements -> '$empty' : none.
+ Elements -> Elements ',' Element : {elements, '$3', '$1'}.
+ Elements -> Element : '$1'.
+
+ Element -> List : '$1'.
+ Element -> Tuple : '$1'.
+ Element -> e : '$1'.
+ ">>),
+ ?line {ok, _, []} =
+ yecc:file(Filename, Ret),
+
+ file:delete(Filename),
+ ok.
+
+empty(doc) ->
+ "'$empty'.";
+empty(suite) -> [];
+empty(Config) when is_list(Config) ->
+ Ts = [{empty_1, <<"
+ Nonterminals nt.
+ Terminals t.
+ Rootsymbol nt.
+ Endsymbol e.
+ nt -> '$empty': nothing.
+ nt -> t : something.
+
+ Erlang code.
+
+ -export([t/0]).
+
+ t() ->
+ {ok, nothing} = parse([{e,2}]),
+ {ok, something} = parse([{t,1},{e,2}]),
+ ok.">>,
+ default,
+ ok},
+ {empty_2, <<"
+ %% There used to be a bug when it came to the left
+ %% corners. In this example rule 2 is a prefix of rule 1
+ %% such that the rule 2 generates $empty but rule 1 does
+ %% not. The old buggy code seemingly worked well too.
+ Nonterminals top A B C D.
+ Terminals t.
+ Rootsymbol top.
+
+ top -> A B C D : {'$1','$2','$3','$4'}.
+ top -> A B C : {'$1','$2','$3'}.
+
+ A -> '$empty' : e.
+ B -> '$empty' : e.
+ C -> '$empty' : e.
+
+ D -> t : t.
+
+ Erlang code.
+
+ -export([t/0]).
+
+ t() ->
+ {ok,{e,e,e,t}} = parse([{t, 1}]),
+ {ok,{e,e,e}} = parse([]),
+ ok.
+ ">>,
+ default,
+ ok}],
+ ?line run(Config, Ts),
+ ok.
+
+prec(doc) ->
+ "Precedence.";
+prec(suite) -> [];
+prec(Config) when is_list(Config) ->
+ Dir = ?privdir,
+ Ret = [return, {report, false}],
+ Filename = filename:join(Dir, "file.yrl"),
+
+ %% Don't know what 'Unary' actually means, but this is how it has
+ %% always worked...
+ ?line ok = file:write_file(Filename, <<"
+ Nonterminals E.
+ Terminals '*' '+' '=' integer.
+ Rootsymbol E.
+
+ E -> E '=' E : {op, '=', '$1', '$3'}.
+ E -> E '*' E : {op, '*', '$1', '$3'}.
+ E -> E '+' E : {op, '+', '$1', '$3'}.
+ E -> integer : '$1'.
+
+ Unary 100 '='.
+ Left 200 '+'.
+ Left 400 '*'.
+ ">>),
+ ?line {error,[{_,[{none,yecc,{conflict,_}}]}],
+ [{_,[{none,yecc,{conflicts,1,0}}]}]} =
+ yecc:file(Filename, Ret),
+
+ Ts = [{prec_1, <<"
+ Nonterminals E Expr Uminus.
+ Terminals '=' '+' '*' '-' '(' ')' integer var dot.
+ Rootsymbol Expr.
+
+ Expr -> E dot : '$1'.
+ E -> var '=' E : {match, line_of('$1'), '$1', '$3'}.
+ E -> E '+' E : {op, line_of('$1'), '+', '$1', '$3'}.
+ E -> E '-' E : {op, line_of('$1'), '-', '$1', '$3'}.
+ E -> E '*' E : {op, line_of('$1'), '*', '$1', '$3'}.
+ E -> Uminus : '$1'.
+ E -> '(' E ')' : '$2'.
+ E -> integer : '$1'.
+
+ Uminus -> '-' E : {op, line_of('$1'), '-', '$2'}.
+
+ Right 200 '='.
+ Left 300 '+'.
+ Left 300 '-'.
+ Left 400 '*'.
+ Unary 500 Uminus.
+
+ Erlang code.
+
+ -export([t/0, t/1]).
+
+ line_of(Token) ->
+ element(2, Token).
+
+ t() ->
+ {ok, -56} = t(\"A = (4 + 3) * - 8. \"),
+ {ok, 28} = t(\"A = 4 + B=3 * 8. \"),
+ {ok, 28} = t(\"4 - 3 * - 8. \"),
+ {ok, -20} = t(\"4 - 3 * 8. \"),
+ {ok, 2} = t(\"1 - - 1.\"),
+ ok.
+
+ t(S) ->
+ case erl_scan:string(S) of
+ {ok, Tokens, _Line} ->
+ case parse(Tokens) of
+ {ok, Expr} ->
+ case catch erl_eval:expr(Expr, []) of
+ {value, Value, _Bs} ->
+ {ok, Value};
+ {'EXIT', Reason} ->
+ {error, Reason}
+ end;
+ Error ->
+ Error
+ end;
+ Error ->
+ Error
+ end.
+ ">>,
+ default,
+ ok},
+
+ {prec_2, <<"
+ Nonterminals E uminus.
+ Terminals '*' '-' integer.
+ Rootsymbol E.
+
+ E -> E '-' E : {op, '-', '$1', '$3'}.
+ E -> E '*' E : {op, '*', '$1', '$3'}.
+ E -> uminus: '$1'.
+ E -> integer : '$1'.
+
+ uminus -> '-' E : {op, '-', '$2'}.
+
+ Left 200 '-'.
+ Left 400 '*'.
+ Unary 500 uminus.
+
+ Erlang code.
+
+ -export([t/0]).
+
+ t() ->
+ %% This used to be parsed -(4 * 3), but that has been corrected:
+ {ok,{op,'*',{op,'-',{integer,1,4}},{integer,3,12}}} =
+ parse([{'-',0},{integer,1,4},{'*',2},{integer,3,12}]),
+
+ {ok,{op,'-',{op,'-',{integer,1,4}},{integer,3,12}}} =
+ parse([{'-',0},{integer,1,4},{'-',2},{integer,3,12}]),
+ {ok,{op,'*',{op,'-',{op,'-',{integer,2,4}}},{integer,4,12}}} =
+ parse([{'-',0},{'-',1},{integer,2,4},{'*',3},{integer,4,12}]),
+ {ok,{op,'-',{integer,1,4},{op,'-',{integer,4,12}}}} =
+ parse([{integer,1,4},{'-',2},{'-',3},{integer,4,12}]),
+ ok.
+ ">>,
+ default,
+ ok},
+ {prec_3, <<"
+ Nonterminals nt.
+ Terminals '(' ')' t op.
+ Rootsymbol nt.
+
+ Nonassoc 100 op.
+
+ nt -> nt op nt : {'$2', '$1', '$3'}.
+ nt -> '(' nt ')' : '$2'.
+ nt -> t : '$1'.
+
+ Erlang code.
+
+ -export([t/0]).
+
+ t() ->
+ {error,{4,yecc_test,[\"syntax error before: \",\"op\"]}} =
+ parse([{t,1},{op,2},{t,3},{op,4},{t,5}]),
+ {ok,{{op,2},{t,1},{{op,5},{t,4},{t,6}}}} =
+ parse([{t,1},{op,2},{'(',3},{t,4},{op,5},{t,6},{')',7}]),
+ ok.
+ ">>,
+ default,
+ ok},
+
+ {prec_4, <<"
+ Nonterminals E.
+ Terminals '-' '+' '=' id.
+ Rootsymbol E.
+
+ E -> E '=' E : {op, '=', '$1', '$3'}.
+ E -> E '+' E : {op, '+', '$1', '$3'}.
+ E -> '-' E : {op, '-', '$2'}.
+ E -> id : '$1'.
+
+ Nonassoc 100 '='.
+ Right 200 '+' '-'.
+
+ Erlang code.
+
+ -export([t/0]).
+
+ t() ->
+ {ok,{op,'=',{id,1},{op,'-',{op,'+',{id,4},{id,6}}}}} =
+ parse([{id,1},{'=',2},{'-',3},{id,4},{'+',5},{id,6}]),
+ ok.
+
+ ">>,
+ default,
+ ok}],
+
+ ?line run(Config, Ts),
+ ok.
+
+yeccpre(doc) ->
+ "Errors etc. in actions, handled by yeccpre. parse_and_scan.";
+yeccpre(suite) -> [];
+yeccpre(Config) when is_list(Config) ->
+ Ts = [{error_1, <<"
+ Nonterminals list.
+ Terminals element e.
+ Rootsymbol list.
+
+ list -> element : {single, '$1'}.
+ list -> list element : throw(error).
+ list -> e : return_error(element(2, '$1'), bad_element).
+
+ Erlang code.
+
+ -export([t/0]).
+
+ t() ->
+ error = (catch parse([{element,1},{element,2}])),
+ {error, {2, _, Mess}} = parse([{element,1},{e,2}]),
+ ok.
+ ">>,
+ default,
+ ok},
+
+ {error_2, <<"
+ Nonterminals list.
+ Terminals element.
+ Rootsymbol list.
+
+ list -> element.
+
+ Erlang code.
+
+ -export([t/0, scan/1]).
+
+ scan(How) ->
+ case How of
+ thrown -> throw(thrown);
+ error -> erlang:error(error);
+ exit -> exit(exit)
+ end.
+
+ t() ->
+ try parse_and_scan({yecc_test, scan, [thrown]})
+ catch throw: thrown ->
+ ok
+ end,
+ try parse_and_scan({yecc_test, scan, [error]})
+ catch error: error ->
+ ok
+ end,
+ try parse_and_scan({{yecc_test, scan}, [exit]})
+ catch exit: exit ->
+ ok
+ end,
+ try parse_and_scan({fun scan/1, [thrown]})
+ catch throw: thrown ->
+ ok
+ end,
+ ok.
+ ">>,
+ default,
+ ok}],
+
+ ?line run(Config, Ts),
+ ok.
+
+lalr(doc) ->
+ "Examples of grammars that are LALR(1) but not SLR(1).";
+lalr(suite) -> [];
+lalr(Config) when is_list(Config) ->
+ Ts = [{lalr_1, <<"
+ %% http://inst.cs.berkeley.edu/~cs164/lectures/slide14a.pdf
+ %% http://pages.cpsc.ucalgary.ca/~robin/class/411/LR.1.html
+ %% b d . c. Shift or reduce?
+ Nonterminals S A.
+ Terminals a b c d.
+ Rootsymbol S.
+ S -> A a : {r1,'$1','$2'}.
+ S -> b A c : {r2,'$1','$2','$3'}.
+ S -> d c : {r3,'$1','$2'}.
+ S -> b d a : {r4,'$1','$2','$3'}.
+
+ A -> d : {r5,'$1'}.
+
+ Erlang code.
+
+ -export([t/0]).
+
+ t() ->
+ %% Reduce!
+ {ok,{r2,{b,1},{r5,{d,2}},{c,3}}} = parse([{b,1},{d,2},{c,3}]),
+ ok.
+ ">>,
+ default,
+ ok},
+ {lalr_2, <<"
+ %% http://www.cs.pitt.edu/~mock/cs2210/lectures/lecture5.pdf
+ Nonterminals S L R.
+ Terminals '*' id '='.
+ Rootsymbol S.
+ S -> L '=' R : {r1,'$1','$3'}.
+ S -> R : {r2,'$1'}.
+
+ L -> '*' R : {r3,'$2'}.
+ L -> id : {r4,'$1'}.
+
+ R -> L : {r5,'$1'}.
+
+ Erlang code.
+
+ -export([t/0]).
+
+ t() ->
+ {ok,{r1,{r3,{r5,{r4,{id,1}}}},{r5,{r4,{id,3}}}}} =
+ parse([{'*',0},{id,1},{'=',2},{id,3}]),
+ ok.
+ ">>,
+ default,
+ ok}],
+ ?line run(Config, Ts),
+ ok.
+
+old_yecc(doc) ->
+ "The old interface yecc:yecc/2,3,4.";
+old_yecc(suite) -> [];
+old_yecc(Config) when is_list(Config) ->
+ Dir = ?privdir,
+ Filename = filename:join(Dir, "file.yrl"),
+ Parserfile = filename:join(Dir, "file.erl"),
+ Mini = <<"Nonterminals nt.
+ Terminals t.
+ Rootsymbol nt.
+ nt -> t.">>,
+ ?line ok = file:write_file(Filename, Mini),
+ ?line {_, _} = yecc:yecc(Filename, Parserfile),
+ ?line {_, _} = yecc:yecc(Filename, Parserfile, true),
+ ?line {_, _} = yecc:yecc(Filename, Parserfile, true),
+ TE = process_flag(trap_exit, true),
+ ?line {'EXIT', error} =
+ (catch yecc:yecc(Filename, Parserfile, false, Parserfile)),
+ _ = process_flag(trap_exit, TE),
+ ok.
+
+other_examples(doc) ->
+ "Misc examples.";
+other_examples(suite) -> [];
+other_examples(Config) when is_list(Config) ->
+ Ts = [{empty, <<"
+ %% G1 from the 1974 article.
+
+ Nonterminals LIST ELEMENT.
+ Terminals ',' a b.
+ Rootsymbol LIST.
+
+ LIST -> LIST ',' ELEMENT : {'$1', '$3'}.
+ LIST -> ELEMENT : '$1'.
+
+ ELEMENT -> a : '$1'.
+ ELEMENT -> b : '$1'.
+
+ Erlang code.
+
+ -export([t/0]).
+
+ t() ->
+ L = [{a, 1}, {',', 2}, {b, 3}],
+ {ok,{{a,1},{b,3}}} = parse(L),
+ ok.
+ ">>,
+ default,
+ ok}],
+ ?line run(Config, Ts),
+ ok.
+
+bugs(suite) ->
+ [otp_5369, otp_6362, otp_7945].
+
+otp_5369(doc) ->
+ "OTP-5369. A bug in parse_and_scan reported on erlang questions.";
+otp_5369(suite) -> [];
+otp_5369(Config) when is_list(Config) ->
+ Ts = [{otp_5369,<<"
+ Nonterminals list.
+ Terminals element.
+ Rootsymbol list.
+
+ list -> element : {single, '$1'}.
+ list -> list element : {pair, '$1', '$2'}.
+
+ Erlang code.
+
+ -export([t/0, scan/1]).
+
+ scan(Lexer) ->
+ Lexer ! {scan, self()},
+ receive
+ {ok, Lexer, [Token], Position} ->
+ {ok, [Token], Position};
+ {eof, Lexer, Position} ->
+ {eof, Position}
+ end.
+
+ make_scanner(L) ->
+ spawn_link(fun() ->
+ loop(L)
+ end).
+
+ loop([]) ->
+ receive
+ {scan, Pid} ->
+ Pid ! {eof, self(), 1000}
+ end;
+ loop([Token = {_, P}|T]) ->
+ receive
+ {scan, Pid} ->
+ Pid ! {ok, self(), [Token], P},
+ loop(T)
+ end.
+
+ t(L) ->
+ case parse_and_scan({yecc_test, scan, [make_scanner(L)]}) of
+ {ok, _Result} ->
+ ok;
+ {error, {_LineNumber, Module, Message}} ->
+ _M = apply(Module, format_error, [Message]),
+ not_ok
+ end.
+
+ t() ->
+ not_ok = t([]), %% This test has been added afterwards.
+ %% OTP-5369 did not fix this bug!
+ L = [{element, 1},
+ {element, 2},
+ {element, 3}],
+ t(L).
+ ">>,
+ default,
+ ok}],
+ ?line run(Config, Ts),
+ ok.
+
+otp_6362(doc) ->
+ "OTP-6362. A precedence declaration bug reported on erlang questions.";
+otp_6362(suite) -> [];
+otp_6362(Config) when is_list(Config) ->
+ Ts = [{otp_6362_1,<<"
+ Nonterminals cmp compare expr.
+ Terminals 'string' '>' '='.
+ Rootsymbol compare.
+ Nonassoc 250 cmp.
+ compare -> expr cmp expr : {cmp, '$2', '$1', '$3'}.
+ compare -> expr : {cmp, '==', '$1', {string, \"TRUE\"}}.
+ cmp -> '>' '=' : '>='.
+ cmp -> '>' : '>'.
+ expr -> 'string' : '$1'.
+
+ Erlang code.
+
+ -export([t/0]).
+
+ t() ->
+ {ok,{cmp,'>',{string,1},{string,3}}} =
+ parse([{string,1}, {'>', 2}, {string,3}]),
+ ok.
+ ">>,
+ default,
+ ok}],
+ ?line run(Config, Ts),
+
+ Dir = ?privdir,
+ %% Report errors. Very simple test of format_error/1.
+ Ret = [return, {report, true}],
+ Filename = filename:join(Dir, "file.yrl"),
+
+ %% An error introduced due to this ticket. Terminals can be
+ %% assigned conflicting precedences, which cannot be resolved.
+ ?line ok = file:write_file(Filename,<<"
+ Nonterminals cmp compare expr fopp.
+ Terminals string '>' '='.
+ Rootsymbol compare.
+ Nonassoc 250 cmp.
+ Left 300 '>'.
+
+ compare -> expr cmp expr : {cmp, '$2', '$1', '$3'}.
+ compare -> expr fopp expr : {cmp, '$2', '$1', '$3'}.
+ compare -> expr '=' expr : '$1'.
+ compare -> expr : {cmp, '==', '$1', {string, foo}}.
+ cmp -> '>' '=' : '>='.
+ cmp -> '>' : '>'.
+ expr -> string : '$1'.
+
+ fopp -> '>' '=' : '>='.
+ fopp -> '>' : '>'.">>),
+
+ Ret = [return, {report, true}],
+ ?line {error,[{_,[{none,yecc,{conflict,_}}]}],[]} =
+ yecc:file(Filename, Ret),
+ file:delete(Filename),
+ ok.
+
+my_yeccpre() ->
+ %% Version 1.1.
+ <<"parse(Tokens) ->
+ yeccpars0(Tokens, false).
+
+ parse_and_scan({F, A}) -> % Fun or {M, F}
+ yeccpars0([], {F, A});
+ parse_and_scan({M, F, A}) ->
+ yeccpars0([], {{M, F}, A}).
+
+ format_error(Message) ->
+ case io_lib:deep_char_list(Message) of
+ true ->
+ Message;
+ _ ->
+ io_lib:write(Message)
+ end.
+
+ % To be used in grammar files to throw an error message to the parser
+ % toplevel. Doesn't have to be exported!
+ -compile({nowarn_unused_function,{return_error,2}}).
+ return_error(Line, Message) ->
+ throw({error, {Line, yecc_test, Message}}).
+
+ yeccpars0(Tokens, MFA) ->
+ try yeccpars1(Tokens, MFA, 0, [], [])
+ catch
+ throw: {error, {_Line, yecc_test, _M}} = Error ->
+ Error % probably from return_error/1
+ end.
+
+ % Don't change yeccpars1/6 too much, it is called recursively by yeccpars2/8!
+ yeccpars1([Token | Tokens], Tokenizer, State, States, Vstack) ->
+ yeccpars2(State, element(1, Token), States, Vstack, Token, Tokens,
+ Tokenizer);
+ yeccpars1([], {F, A}, State, States, Vstack) ->
+ case apply(F, A) of
+ {ok, Tokens, _Endline} ->
+ yeccpars1(Tokens, {F, A}, State, States, Vstack);
+ {eof, _Endline} ->
+ yeccpars1([], false, State, States, Vstack);
+ {error, Descriptor, _Endline} ->
+ {error, Descriptor}
+ end;
+ yeccpars1([], false, State, States, Vstack) ->
+ yeccpars2(State, '$end', States, Vstack, {'$end', 999999}, [], false).
+
+ % For internal use only.
+ yeccerror(Token) ->
+ {error,
+ {element(2, Token), yecc_test,
+ [\"syntax error before: \", yecctoken2string(Token)]}}.
+
+ yecctoken2string({atom, _, A}) -> io_lib:write(A);
+ yecctoken2string({integer,_,N}) -> io_lib:write(N);
+ yecctoken2string({float,_,F}) -> io_lib:write(F);
+ yecctoken2string({char,_,C}) -> io_lib:write_char(C);
+ yecctoken2string({var,_,V}) -> io_lib:format('~s', [V]);
+ yecctoken2string({string,_,S}) -> io_lib:write_string(S);
+ yecctoken2string({reserved_symbol, _, A}) -> io_lib:format('~w', [A]);
+ yecctoken2string({_Cat, _, Val}) -> io_lib:format('~w', [Val]);
+ yecctoken2string({'dot', _}) -> io_lib:format('~w', ['.']);
+ yecctoken2string({'$end', _}) ->
+ [];
+ yecctoken2string({Other, _}) when is_atom(Other) ->
+ io_lib:format('~w', [Other]);
+ yecctoken2string(Other) ->
+ io_lib:write(Other).
+">>.
+
+otp_7945(doc) ->
+ "OTP-7945. A bug introduced in R13A.";
+otp_7945(suite) -> [];
+otp_7945(Config) when is_list(Config) ->
+ ?line {error,_} = erl_parse:parse([{atom,3,foo},{'.',2,9,9}]),
+ ok.
+
+improvements(suite) ->
+ [otp_7292, otp_7969].
+
+otp_7292(doc) ->
+ "OTP-7292. Header declarations for edoc.";
+otp_7292(suite) -> [];
+otp_7292(Config) when is_list(Config) ->
+ Dir = ?privdir,
+ Filename = filename:join(Dir, "file.yrl"),
+ Parserfile1 = filename:join(Dir, "a file"),
+
+ Contents = <<"Nonterminals nt.
+ Terminals t.
+ Rootsymbol nt.
+ Endsymbol e.
+ nt -> t : a bad code.
+
+ Header \"%% copyright bla bla bla\"
+ \"%% @private\" \"%% foo\"
+ \"%% @author X.Y.\".
+
+ Erlang code.
+
+ %% @private
+ %% etc.
+
+ foo() ->
+ bar. ">>,
+
+ %% Check that correct line number is used in messages.
+ ?line ok = file:write_file(Filename, Contents),
+ ParserFile3 = [{parserfile, Parserfile1}],
+ Ret = [return, {report, true}],
+ ?line {ok, _, []} = yecc:file(Filename, ParserFile3 ++ Ret),
+
+ %% Note: checking the line numbers. Changes when yeccpre.hrl changes.
+ fun() ->
+ SzYeccPre = yeccpre_size(),
+ ?line {error,
+ [{_,[{5,_,["syntax error before: ","bad"]}]},
+ {_,[{L1,_,{undefined_function,{yeccpars2_2_,1}}},
+ {L2,_,{bad_inline,{yeccpars2_2_,1}}}]}],
+ [{_,[{16,_,{unused_function,{foo,0}}}]}]} =
+ compile:file(Parserfile1, [basic_validation, return]),
+ ?line L1 = 34 + SzYeccPre,
+ ?line L2 = 41 + SzYeccPre
+ end(),
+
+ YeccPre = filename:join(Dir, "yeccpre.hrl"),
+ ?line ok = file:write_file(YeccPre,
+ [<<"-export([parse/1, parse_and_scan/1, format_error/1]).\n">>,
+ yeccpre_v1_2()]),
+ Inc = [{includefile,YeccPre}],
+ ?line {ok, _, []} = yecc:file(Filename, ParserFile3 ++ Inc ++ Ret),
+ fun() ->
+ SzYeccPre = yeccpre_size(YeccPre),
+ ?line {error,
+ [{_,[{5,_,["syntax error before: ","bad"]}]},
+ {_,[{L1,_,{undefined_function,{yeccpars2_2_,1}}},
+ {L2,_,{bad_inline,{yeccpars2_2_,1}}}]}],
+ [{_,[{16,_,{unused_function,{foo,0}}}]}]} =
+ compile:file(Parserfile1, [basic_validation, return]),
+ ?line L1 = 33 + SzYeccPre,
+ ?line L2 = 40 + SzYeccPre
+ end(),
+
+ file:delete(YeccPre),
+ file:delete(Parserfile1 ++ ".erl"),
+ file:delete(Filename),
+
+ ok.
+
+yeccpre_v1_2() ->
+ <<"
+parse(Tokens) ->
+ yeccpars0(Tokens, false).
+
+parse_and_scan({F, A}) -> % Fun or {M, F}
+ yeccpars0([], {F, A});
+parse_and_scan({M, F, A}) ->
+ yeccpars0([], {{M, F}, A}).
+
+format_error(Message) ->
+ case io_lib:deep_char_list(Message) of
+ true ->
+ Message;
+ _ ->
+ io_lib:write(Message)
+ end.
+
+-define(CODE_VERSION, \"1.2\").
+
+yeccpars0(Tokens, MFA) ->
+ try yeccpars1(Tokens, MFA, 0, [], [])
+ catch
+ error: Error ->
+ Stacktrace = erlang:get_stacktrace(),
+ try yecc_error_type(Error, Stacktrace) of
+ {syntax_error, Token} ->
+ yeccerror(Token);
+ {missing_in_goto_table=Tag, State} ->
+ Desc = {State, Tag},
+ erlang:raise(error, {yecc_bug, ?CODE_VERSION, Desc},
+ Stacktrace);
+ {missing_in_goto_table=Tag, Symbol, State} ->
+ Desc = {Symbol, State, Tag},
+ erlang:raise(error, {yecc_bug, ?CODE_VERSION, Desc},
+ Stacktrace)
+ catch _:_ -> erlang:raise(error, Error, Stacktrace)
+ end;
+ throw: {error, {_Line, ?MODULE, _M}} = Error ->
+ Error % probably from return_error/2
+ end.
+
+yecc_error_type(function_clause, [{?MODULE,F,[_,_,_,_,Token,_,_]} | _]) ->
+ \"yeccpars2\" ++ _ = atom_to_list(F),
+ {syntax_error, Token};
+yecc_error_type({case_clause,{State}}, [{?MODULE,yeccpars2,_}|_]) ->
+ %% Inlined goto-function
+ {missing_in_goto_table, State};
+yecc_error_type(function_clause, [{?MODULE,F,[State]}|_]) ->
+ \"yeccgoto_\" ++ SymbolL = atom_to_list(F),
+ {ok,[{atom,_,Symbol}]} = erl_scan:string(SymbolL),
+ {missing_in_goto_table, Symbol, State}.
+
+yeccpars1([Token | Tokens], Tokenizer, State, States, Vstack) ->
+ yeccpars2(State, element(1, Token), States, Vstack, Token, Tokens,
+ Tokenizer);
+yeccpars1([], {F, A}, State, States, Vstack) ->
+ case apply(F, A) of
+ {ok, Tokens, _Endline} ->
+ yeccpars1(Tokens, {F, A}, State, States, Vstack);
+ {eof, _Endline} ->
+ yeccpars1([], false, State, States, Vstack);
+ {error, Descriptor, _Endline} ->
+ {error, Descriptor}
+ end;
+yeccpars1([], false, State, States, Vstack) ->
+ yeccpars2(State, '$end', States, Vstack, {'$end', 999999}, [], false).
+
+yeccpars1(State1, State, States, Vstack, Stack1, [Token | Tokens],
+ Tokenizer) ->
+ yeccpars2(State, element(1, Token), [State1 | States],
+ [Stack1 | Vstack], Token, Tokens, Tokenizer);
+yeccpars1(State1, State, States, Vstack, Stack1, [], {F, A}) ->
+ case apply(F, A) of
+ {ok, Tokens, _Endline} ->
+ yeccpars1(State1, State, States, Vstack, Stack1, Tokens, {F, A});
+ {eof, _Endline} ->
+ yeccpars1(State1, State, States, Vstack, Stack1, [], false);
+ {error, Descriptor, _Endline} ->
+ {error, Descriptor}
+ end;
+yeccpars1(State1, State, States, Vstack, Stack1, [], false) ->
+ yeccpars2(State, '$end', [State1 | States], [Stack1 | Vstack],
+ {'$end', 999999}, [], false).
+
+yeccerror(Token) ->
+ {error,
+ {element(2, Token), ?MODULE,
+ [\"syntax error before: \", yecctoken2string(Token)]}}.
+
+yecctoken2string({atom, _, A}) -> io_lib:write(A);
+yecctoken2string({integer,_,N}) -> io_lib:write(N);
+yecctoken2string({float,_,F}) -> io_lib:write(F);
+yecctoken2string({char,_,C}) -> io_lib:write_char(C);
+yecctoken2string({var,_,V}) -> io_lib:format('~s', [V]);
+yecctoken2string({string,_,S}) -> io_lib:write_string(S);
+yecctoken2string({reserved_symbol, _, A}) -> io_lib:format('~w', [A]);
+yecctoken2string({_Cat, _, Val}) -> io_lib:format('~w', [Val]);
+yecctoken2string({'dot', _}) -> io_lib:format('~w', ['.']);
+yecctoken2string({'$end', _}) ->
+ [];
+yecctoken2string({Other, _}) when is_atom(Other) ->
+ io_lib:format('~w', [Other]);
+yecctoken2string(Other) ->
+ io_lib:write(Other).
+">>.
+
+run(Config, Tests) ->
+ F = fun({N,P,Pre,E}) ->
+ case catch run_test(Config, P, Pre) of
+ E ->
+ ok;
+ Bad ->
+ ?t:format("~nTest ~p failed. Expected~n ~p~n"
+ "but got~n ~p~n", [N, E, Bad]),
+ fail()
+ end
+ end,
+ lists:foreach(F, Tests).
+
+otp_7969(doc) ->
+ "OTP-7969. Interface to the I/O protocol..";
+otp_7969(suite) -> [];
+otp_7969(Config) when is_list(Config) ->
+ ?line {ok,Ts1,_} =
+ erl_scan:string("'foo\nbar'", {1,1}, [text]),
+ ?line {error,{2,_,["syntax error before: ",[]]}} = erl_parse:parse(Ts1),
+
+ ?line {ok,Ts1_1,_} = erl_scan:string("'foo\nbar'", 1, [text]),
+ ?line {error,{2,_,["syntax error before: ",[]]}} = erl_parse:parse(Ts1_1),
+
+ ?line {ok,Ts2,_EndLocation} =
+ erl_scan:string("'foo\nbar'", {1,1}, []),
+ %% Can't do better than report possibly wrong line:
+ ?line {error,{1,_,["syntax error before: ",[]]}} = erl_parse:parse(Ts2),
+
+ ?line {ok, Ts11, _}=R1 = erl_scan:string("f() -> a."),
+ ?line F1 = fun() -> {ok,Ts11 ++ [{'$end',2}],2} end,
+ ?line{ok,{function,1,f,0,[{clause,1,[],[],[{atom,1,a}]}]}} =
+ erl_parse:parse_and_scan({F1, []}),
+ ?line F2 = fun() -> erl_scan:string("f() -> ,") end,
+ ?line {error,{1,erl_parse,_}} = erl_parse:parse_and_scan({F2, []}),
+ ?line F3 = fun() -> case erase(foo) of
+ bar ->
+ {ok,[{'$end',2}],3};
+ undefined ->
+ put(foo,bar), R1
+ end
+ end,
+ ?line {ok,{function,1,f,0,[{clause,1,[],[],[{atom,1,a}]}]}} =
+ erl_parse:parse_and_scan({F3,[]}),
+ F4 = fun() -> {error, {1, ?MODULE, bad}, 2} end,
+ ?line {error, {1,?MODULE,bad}} = erl_parse:parse_and_scan({F4, []}),
+ F5 = fun() -> {eof, 3} end,
+ ?line {error,{3,erl_parse,_}} = erl_parse:parse_and_scan({F5, []}),
+ ?line {error,{999999,erl_parse,_}} = erl_parse:parse([]),
+ ?line {ok, Ts21, EL} = erl_scan:string("f() -> a; g() -> b. ", {1,1}),
+ ?line F6 = fun() -> {ok, Ts21, EL} end,
+ ?line {error,{{1,11},erl_parse,_}} = erl_parse:parse_and_scan({F6, []}),
+ ok.
+
+yeccpre_size() ->
+ yeccpre_size(default_yeccpre()).
+
+yeccpre_size(File) ->
+ n_lines(File).
+
+default_yeccpre() ->
+ filename:join([code:lib_dir(parsetools),"include","yeccpre.hrl"]).
+
+n_lines(File) ->
+ {ok, Bin} = file:read_file(File),
+ length([C || C=$\n <- binary_to_list(Bin)]).
+
+run_test(Config, Def, Pre) ->
+ %% io:format("testing ~s~n", [binary_to_list(Def)]),
+ DefFile = 'yecc_test.yrl',
+ Filename = 'yecc_test.erl',
+ DataDir = ?privdir,
+ YrlFile = filename:join(DataDir, DefFile),
+ ErlFile = filename:join(DataDir, Filename),
+ Opts = [return, warn_unused_vars,{outdir,DataDir}],
+ ok = file:write_file(YrlFile, Def),
+ YOpts = [return, {report, false} |
+ case Pre of
+ default ->
+ [];
+ _ ->
+ [{includefile,Pre}]
+ end],
+ P0 = pps(),
+ YRet = yecc:file(YrlFile, [verbose | YOpts]),
+ case {pps(), YRet} of
+ {P0, {ok, _Outfile, _YWs}} ->
+ case compile:file(ErlFile, Opts) of
+ {ok, _M, _Ws} ->
+ AbsFile = filename:rootname(ErlFile, ".erl"),
+ Mod = yecc_test,
+ code:purge(Mod),
+ code:load_abs(AbsFile, Mod),
+ Mod:t();
+ %% warnings(ErlFile, Ws);
+ {error, [{ErlFile,Es}], []} -> {error, Es, []};
+ {error, [{ErlFile,Es}], [{ErlFile,Ws}]} -> {error, Es, Ws};
+ Error -> Error
+ end;
+ {P0, {error, [{YrlFile,YEs}], []}} -> {error, YEs, []};
+ {P0, {error, [{YrlFile,YEs}], [{YrlFile,YWs}]}} -> {error, YEs, YWs};
+ {P0, YError} -> YError;
+ {P, _} ->
+ io:format("failure, got ~p~n, expected ~p\n", [P, P0]),
+ fail()
+ end.
+
+extract(File, {error, Es, Ws}) ->
+ {errors, extract(File, Es), extract(File, Ws)};
+extract(File, Ts) ->
+ lists:append([T || {F, T} <- Ts, F =:= File]).
+
+pps() ->
+ {port_list(), process_list()}.
+
+port_list() ->
+ [{P,safe_second_element(erlang:port_info(P, name))} || P <- erlang:ports()].
+
+process_list() ->
+ [{P,process_info(P, registered_name),
+ safe_second_element(process_info(P, initial_call))} ||
+ P <- processes(), is_process_alive(P)].
+
+safe_second_element({_,Info}) -> Info;
+safe_second_element(Other) -> Other.
+
+fail() ->
+ ?t:fail().
diff --git a/lib/parsetools/vsn.mk b/lib/parsetools/vsn.mk
index e3db40c193..b1354e89d8 100644
--- a/lib/parsetools/vsn.mk
+++ b/lib/parsetools/vsn.mk
@@ -1 +1 @@
-PARSETOOLS_VSN = 2.0.1
+PARSETOOLS_VSN = 2.0.2
diff --git a/lib/percept/doc/src/Makefile b/lib/percept/doc/src/Makefile
index c841d17c01..f0d43c5a01 100644
--- a/lib/percept/doc/src/Makefile
+++ b/lib/percept/doc/src/Makefile
@@ -1,19 +1,19 @@
#
# %CopyrightBegin%
-#
-# Copyright Ericsson AB 2007-2009. All Rights Reserved.
-#
+#
+# Copyright Ericsson AB 2007-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%
#
@@ -153,10 +153,10 @@ gifs: $(GIF_FILES:%=$(HTMLDIR)/%)
xml: $(MODULE_XML_FILES)
$(PERCEPT_XML_FILES):
- docb_gen $(PERCEPT_DIR)/$(@:%.xml=%.erl)
+ escript $(DOCGEN)/priv/bin/xml_from_edoc.escript $(PERCEPT_DIR)/$(@:%.xml=%.erl)
$(RUNTIME_TOOLS_XML_FILES):
- docb_gen $(RUNTIME_TOOLS_DIR)/$(@:%.xml=%.erl)
+ escript $(DOCGEN)/priv/bin/xml_from_edoc.escript $(RUNTIME_TOOLS_DIR)/$(@:%.xml=%.erl)
info:
@echo "XML_PART_FILES: $(XML_PART_FILES)"
diff --git a/lib/percept/doc/src/notes.xml b/lib/percept/doc/src/notes.xml
index 4d54275e30..c310a0e598 100644
--- a/lib/percept/doc/src/notes.xml
+++ b/lib/percept/doc/src/notes.xml
@@ -32,6 +32,60 @@
</header>
<p>This document describes the changes made to the Percept application.</p>
+<section><title>Percept 0.8.4</title>
+
+ <section><title>Fixed Bugs and Malfunctions</title>
+ <list>
+ <item>
+ <p>
+ Fix egd_render transparent to use float constants.</p>
+ <p>
+ The render engine has float guards to enhance beam code
+ generation. However, the default case used integers which
+ caused the engine to crash. This is now fixed.</p>
+ <p>
+ Own Id: OTP-8425</p>
+ </item>
+ </list>
+ </section>
+
+
+ <section><title>Improvements and New Features</title>
+ <list>
+ <item>
+ <p>The documentation is now possible to build in an open
+ source environment after a number of bugs are fixed and
+ some features are added in the documentation build
+ process. </p>
+ <p>- The arity calculation is updated.</p>
+ <p>- The module prefix used in the function names for
+ bif's are removed in the generated links so the links
+ will look like
+ "http://www.erlang.org/doc/man/erlang.html#append_element-2"
+ instead of
+ "http://www.erlang.org/doc/man/erlang.html#erlang:append_element-2".</p>
+ <p>- Enhanced the menu positioning in the html
+ documentation when a new page is loaded.</p>
+ <p>- A number of corrections in the generation of man
+ pages (thanks to Sergei Golovan)</p>
+ <p>- The legal notice is taken from the xml book file so
+ OTP's build process can be used for non OTP
+ applications.</p>
+ <p>
+ Own Id: OTP-8343</p>
+ </item>
+ <item>
+ <p>
+ Cleanups suggested by tidier and modernization of types
+ and specs.</p>
+ <p>
+ Own Id: OTP-8455</p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
<section><title>Percept 0.8.3</title>
<section><title>Improvements and New Features</title>
diff --git a/lib/percept/src/egd.erl b/lib/percept/src/egd.erl
index 4becfef19b..4fb5b6c46a 100644
--- a/lib/percept/src/egd.erl
+++ b/lib/percept/src/egd.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%
%%
@@ -46,10 +46,10 @@
%% @type color()
%% @type render_option() = {render_engine, opaque} | {render_engine, alpha}
--type(egd_image() :: pid()).
--type(point() :: {non_neg_integer(), non_neg_integer()}).
--type(render_option() :: {'render_engine', 'opaque'} | {'render_engine', 'alpha'}).
--type(color() :: {float(), float(), float(), float()}).
+-type egd_image() :: pid().
+-type point() :: {non_neg_integer(), non_neg_integer()}.
+-type render_option() :: {'render_engine', 'opaque'} | {'render_engine', 'alpha'}.
+-type color() :: {float(), float(), float(), float()}.
%%==========================================================================
%%
@@ -60,7 +60,7 @@
%% @spec create(integer(), integer()) -> egd_image()
%% @doc Creates an image area and returns its reference.
--spec(create/2 :: (Width :: integer(), Height :: integer()) -> egd_image()).
+-spec create(Width :: integer(), Height :: integer()) -> egd_image().
create(Width,Height) ->
spawn_link(fun() -> init(trunc(Width),trunc(Height)) end).
@@ -69,16 +69,17 @@ create(Width,Height) ->
%% @spec destroy(egd_image()) -> ok
%% @doc Destroys the image.
--spec(destroy/1 :: (Image :: egd_image()) -> ok).
+-spec destroy(Image :: egd_image()) -> ok.
destroy(Image) ->
cast(Image, destroy),
ok.
-%% @spec render(egd_image()) -> binary()
+%% @spec render(egd_image()) -> binary()
%% @equiv render(Image, png, [{render_engine, opaque}])
+-spec render(Image :: egd_image()) -> binary().
render(Image) ->
render(Image, png, [{render_engine, opaque}]).
@@ -94,10 +95,10 @@ render(Image, Type) ->
%% binary can either be a raw bitmap with rgb tripplets or a binary in png
%% format.
--spec(render/3 :: (
+-spec render(
Image :: egd_image(),
Type :: 'png' | 'raw_bitmap' | 'eps',
- Options :: [render_option()]) -> binary()).
+ Options :: [render_option()]) -> binary().
render(Image, Type, Options) ->
{render_engine, RenderType} = proplists:lookup(render_engine, Options),
@@ -116,11 +117,11 @@ information(Pid) ->
%% @spec line(egd_image(), point(), point(), color()) -> ok
%% @doc Creates a line object from P1 to P2 in the image.
--spec(line/4 :: (
+-spec line(
Image :: egd_image(),
P1 :: point(),
P2 :: point(),
- Color :: color()) -> 'ok').
+ Color :: color()) -> 'ok'.
line(Image, P1, P2, Color) ->
cast(Image, {line, P1, P2, Color}),
@@ -128,13 +129,12 @@ 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()).
+-spec color(Value :: {byte(), byte(), byte()} | {byte(), byte(), byte(), byte()} | atom()) ->
+ color().
color(Color) ->
egd_primitives:color(Color).
diff --git a/lib/percept/src/egd.hrl b/lib/percept/src/egd.hrl
index 274986db65..2e8f5ebc50 100644
--- a/lib/percept/src/egd.hrl
+++ b/lib/percept/src/egd.hrl
@@ -1,24 +1,24 @@
%%
%% %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%
--type(rgba_float() :: {float(), float(), float(), float()}).
--type(rgba_byte() :: {byte(), byte(), byte(), byte()}).
--type(rgb() :: {byte(), byte(), byte()}).
+-type rgba_float() :: {float(), float(), float(), float()}.
+-type rgba_byte() :: {byte(), byte(), byte(), byte()}.
+-type rgb() :: {byte(), byte(), byte()}.
-record(image_object, {
type,
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..7fd1072ab1 100644
--- a/lib/percept/src/egd_render.erl
+++ b/lib/percept/src/egd_render.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%
%%
@@ -29,22 +29,22 @@
-include("egd.hrl").
-define('DummyC',0).
-binary(Image) -> binary(Image, opaque).
+binary(Image) ->
+ binary(Image, opaque).
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.
W = Image#image.width,
Bg = Image#image.background,
Os = Image#image.objects,
- erlang:list_to_binary(lists:map(fun
- (Y) -> scanline(Y, Os, {0,0,W - 1, Bg}, Type)
- end, lists:seq(1, Height)));
+ erlang:list_to_binary([scanline(Y, Os, {0,0,W - 1, Bg}, Type)
+ || Y <- lists:seq(1, Height)]);
Np ->
Pids = start_workers(Np, Type),
Handler = handle_workers(Height, Pids),
@@ -54,7 +54,9 @@ parallel_binary(Image = #image{ height = Height },Type) ->
Res
end.
-start_workers(Np, Type) -> start_workers(Np, Type, []).
+start_workers(Np, Type) ->
+ start_workers(Np, Type, []).
+
start_workers( 0, _, Pids) -> Pids;
start_workers(Np, Type, Pids) when Np > 0 ->
start_workers(Np - 1, Type, [spawn_link(fun() -> worker(Type) end)|Pids]).
@@ -90,7 +92,9 @@ init_workers(Image, Handler, [Pid|Pids]) ->
Handler ! {Pid, scan_complete},
init_workers(Image, Handler, Pids).
-handle_workers(H, Pids) -> spawn_link(fun() -> handle_workers(H, H, length(Pids)) end).
+handle_workers(H, Pids) ->
+ spawn_link(fun() -> handle_workers(H, H, length(Pids)) end).
+
handle_workers(_, 0, _) -> ok;
handle_workers(H, Hi, Np) when H > 0 ->
N = trunc(Hi/(2*Np)),
@@ -110,7 +114,9 @@ finish_workers([Pid|Pids]) ->
Pid ! {self(), done},
finish_workers(Pids).
-receive_binaries(H) -> receive_binaries(H, []).
+receive_binaries(H) ->
+ receive_binaries(H, []).
+
receive_binaries(0, Bins) -> erlang:list_to_binary(Bins);
receive_binaries(H, Bins) when H > 0 ->
receive
@@ -118,29 +124,16 @@ receive_binaries(H, Bins) when H > 0 ->
receive_binaries(H - 1, [Bin|Bins])
end.
-
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).
@@ -191,22 +184,16 @@ color(Trans,Layers,Type,OldC) ->
color([],_) -> {0.0,0.0,0.0,0.0};
color([{_,C}|_],opaque) -> C;
-color(Layers,alpha) -> color1({0,0,0,0},Layers).
+color(Layers,alpha) -> color1({0.0,0.0,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 +203,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 +219,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 +227,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 +249,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 +263,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 +319,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 +544,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 +553,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 +656,4 @@ eps_header(W,H) ->
eps_footer() ->
"%%EOF\n".
+
diff --git a/lib/percept/src/percept.erl b/lib/percept/src/percept.erl
index af1a920efd..f5e0f7e469 100644
--- a/lib/percept/src/percept.erl
+++ b/lib/percept/src/percept.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2007-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 2007-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%
%%
@@ -50,7 +50,7 @@
%% @type percept_option() = procs | ports | exclusive
--type(percept_option() :: 'procs' | 'ports' | 'exclusive' | 'scheduler').
+-type percept_option() :: 'procs' | 'ports' | 'exclusive' | 'scheduler'.
%%==========================================================================
%%
@@ -85,8 +85,8 @@ stop(_State) ->
%% profiling
--spec(profile/1 :: (Filename :: string()) ->
- {'ok', port()} | {'already_started', port()}).
+-spec profile(Filename :: file:filename()) ->
+ {'ok', port()} | {'already_started', port()}.
profile(Filename) ->
percept_profile:start(Filename, [procs]).
@@ -94,10 +94,9 @@ profile(Filename) ->
%% @spec profile(Filename::string(), [percept_option()]) -> {ok, Port} | {already_started, Port}
%% @see percept_profile
--spec(profile/2 :: (
- Filename :: string(),
- Options :: [percept_option()]) ->
- {'ok', port()} | {'already_started', port()}).
+-spec profile(Filename :: file:filename(),
+ Options :: [percept_option()]) ->
+ {'ok', port()} | {'already_started', port()}.
profile(Filename, Options) ->
percept_profile:start(Filename, Options).
@@ -105,16 +104,15 @@ profile(Filename, Options) ->
%% @spec profile(Filename::string(), MFA::mfa(), [percept_option()]) -> ok | {already_started, Port} | {error, not_started}
%% @see percept_profile
--spec(profile/3 :: (
- Filename :: string(),
- Entry :: {atom(), atom(), list()},
- Options :: [percept_option()]) ->
- 'ok' | {'already_started', port()} | {'error', 'not_started'}).
+-spec profile(Filename :: file:filename(),
+ Entry :: {atom(), atom(), list()},
+ Options :: [percept_option()]) ->
+ 'ok' | {'already_started', port()} | {'error', 'not_started'}.
profile(Filename, MFA, Options) ->
percept_profile:start(Filename, MFA, Options).
--spec(stop_profile/0 :: () -> 'ok' | {'error', 'not_started'}).
+-spec stop_profile() -> 'ok' | {'error', 'not_started'}.
%% @spec stop_profile() -> ok | {'error', 'not_started'}
%% @see percept_profile
@@ -125,8 +123,8 @@ stop_profile() ->
%% @spec analyze(string()) -> ok | {error, Reason}
%% @doc Analyze file.
--spec(analyze/1 :: (Filename :: string()) ->
- 'ok' | {'error', any()}).
+-spec analyze(Filename :: file:filename()) ->
+ 'ok' | {'error', any()}.
analyze(Filename) ->
case percept_db:start() of
@@ -142,9 +140,8 @@ analyze(Filename) ->
%% Reason = term()
%% @doc Starts webserver.
--spec(start_webserver/0 :: () ->
- {'started', string(), pos_integer()} |
- {'error', any()}).
+-spec start_webserver() ->
+ {'started', string(), pos_integer()} | {'error', any()}.
start_webserver() ->
start_webserver(0).
@@ -156,9 +153,8 @@ start_webserver() ->
%% @doc Starts webserver. If port number is 0, an available port number will
%% be assigned by inets.
--spec(start_webserver/1 :: (Port :: non_neg_integer()) ->
- {'started', string(), pos_integer()} |
- {'error', any()}).
+-spec start_webserver(Port :: non_neg_integer()) ->
+ {'started', string(), pos_integer()} | {'error', any()}.
start_webserver(Port) when is_integer(Port) ->
application:load(percept),
@@ -255,20 +251,20 @@ trace_parser(Trace, {Count, Pid}) ->
find_service_pid_from_port([], _) ->
undefined;
find_service_pid_from_port([{_, Pid, Options} | Services], Port) ->
- case lists:keysearch(port, 1, Options) of
+ case lists:keyfind(port, 1, Options) of
false ->
find_service_pid_from_port(Services, Port);
- {value, {port, Port}} ->
+ {port, Port} ->
Pid
end.
find_service_port_from_pid([], _) ->
undefined;
find_service_port_from_pid([{_, Pid, Options} | _], Pid) ->
- case lists:keysearch(port, 1, Options) of
+ case lists:keyfind(port, 1, Options) of
false ->
undefined;
- {value, {port, Port}} ->
+ {port, Port} ->
Port
end;
find_service_port_from_pid([{_, _, _} | Services], Pid) ->
diff --git a/lib/percept/src/percept.hrl b/lib/percept/src/percept.hrl
index a9afceb6d1..36b6f63a4d 100644
--- a/lib/percept/src/percept.hrl
+++ b/lib/percept/src/percept.hrl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2007-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 2007-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%
%%
@@ -23,10 +23,10 @@
%%% Type definitions %%%
%%% ------------------- %%%
--type(timestamp() :: {non_neg_integer(), non_neg_integer(), non_neg_integer()}).
--type(true_mfa() :: {atom(), atom(), byte() | list()}).
--type(state() :: 'active' | 'inactive').
--type(scheduler_id() :: {'scheduler_id', non_neg_integer()}).
+-type timestamp() :: {non_neg_integer(), non_neg_integer(), non_neg_integer()}.
+-type true_mfa() :: {atom(), atom(), byte() | list()}.
+-type state() :: 'active' | 'inactive'.
+-type scheduler_id() :: {'scheduler_id', non_neg_integer()}.
%%% ------------------- %%%
%%% Records %%%
@@ -40,8 +40,7 @@
runnable_count = 0 %:: non_neg_integer()
}).
--record(
- information, {
+-record(information, {
id ,%:: pid() | port(),
name = undefined ,%:: atom() | string() | 'undefined',
entry = undefined ,%:: true_mfa() | 'undefined',
diff --git a/lib/percept/src/percept_db.erl b/lib/percept/src/percept_db.erl
index dc85fa3510..edb0d79a29 100644
--- a/lib/percept/src/percept_db.erl
+++ b/lib/percept/src/percept_db.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2007-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 2007-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%
%%
@@ -72,7 +72,7 @@
%% Pid = pid()
%% @doc Starts or restarts the percept database.
--spec(start/0 :: () -> {'started', pid()} | {'restarted', pid()}).
+-spec start() -> {'started', pid()} | {'restarted', pid()}.
start() ->
case erlang:whereis(percept_db) of
@@ -92,7 +92,7 @@ start() ->
%% Pid = pid()
%% @doc Stops the percept database.
--spec(stop/0 :: () -> 'not_started' | {'stopped', pid()}).
+-spec stop() -> 'not_started' | {'stopped', pid()}.
stop() ->
case erlang:whereis(percept_db) of
@@ -392,23 +392,14 @@ consolidate_runnability_loop(Key) ->
consolidate_runnability_loop(ets:next(pdb_activity, Key)).
list_all_ts() ->
- ATs = [ Act#activity.timestamp ||
- Act <- select_query({activity, []})],
- STs = [ Act#activity.timestamp ||
- Act <- select_query({scheduler, []})],
+ ATs = [Act#activity.timestamp || Act <- select_query({activity, []})],
+ STs = [Act#activity.timestamp || Act <- select_query({scheduler, []})],
ITs = lists:flatten([
[I#information.start,
I#information.stop] ||
I <- select_query({information, all})]),
- % Filter out all undefined (non ts)
- TsList = lists:filter(
- fun(Element) ->
- case Element of
- {_,_,_} -> true;
- _ -> false
- end
- end, ATs ++ STs ++ ITs),
- TsList.
+ %% Filter out all undefined (non ts)
+ [Elem || Elem = {_,_,_} <- ATs ++ STs ++ ITs].
%% get_runnable_count(Type, State) -> RunnableCount
%% In:
diff --git a/lib/percept/src/percept_html.erl b/lib/percept/src/percept_html.erl
index ffce7a98fa..7e0ea45783 100644
--- a/lib/percept/src/percept_html.erl
+++ b/lib/percept/src/percept_html.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2007-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 2007-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(percept_html).
@@ -172,12 +172,12 @@ div_tag_graph() ->
width:40px;
height:40px;\"></div></div>".
--spec(url_graph/5 :: (
+-spec url_graph(
Widht :: non_neg_integer(),
Height :: non_neg_integer(),
Min :: float(),
Max :: float(),
- Pids :: [pid()]) -> string()).
+ Pids :: [pid()]) -> string().
url_graph(W, H, Min, Max, []) ->
"/cgi-bin/percept_graph/graph?range_min=" ++ term2html(float(Min))
@@ -508,10 +508,7 @@ cl_deltas([A,B|Ls], Out) -> cl_deltas([B|Ls], [B - A | Out]).
join_strings(Strings) ->
lists:flatten(Strings).
--spec(join_strings_with/2 :: (
- Strings :: [string()],
- Separator :: string()) ->
- string()).
+-spec join_strings_with(Strings :: [string()], Separator :: string()) -> string().
join_strings_with([S1, S2 | R], S) ->
join_strings_with([join_strings_with(S1,S2,S) | R], S);
@@ -522,7 +519,7 @@ join_strings_with(S1, S2, S) ->
%%% Generic erlang2html
--spec(html_table/1 :: (Rows :: [[string() | {'td' | 'th', string()}]]) -> string()).
+-spec html_table(Rows :: [[string() | {'td' | 'th', string()}]]) -> string().
html_table(Rows) -> "<table>" ++ html_table_row(Rows) ++ "</table>".
@@ -539,7 +536,7 @@ html_table_data([Data|Row]) -> "<td>" ++ Data ++ "</td>" ++ html_table_dat
--spec(table_line/1 :: (Table :: [any()]) -> string()).
+-spec table_line(Table :: [any()]) -> string().
table_line(List) -> table_line(List, ["<tr>"]).
table_line([], Out) -> lists:flatten(lists:reverse(["</tr>\n"|Out]));
@@ -548,16 +545,12 @@ table_line([Element | Elements], Out) when is_list(Element) ->
table_line([Element | Elements], Out) ->
table_line(Elements, ["<td>" ++ term2html(Element) ++ "</td>"|Out]).
--spec(term2html/1 :: (any()) -> string()).
+-spec term2html(any()) -> string().
term2html(Term) when is_float(Term) -> lists:flatten(io_lib:format("~.4f", [Term]));
term2html(Term) -> lists:flatten(io_lib:format("~p", [Term])).
--spec(mfa2html/1 :: (MFA :: {
- atom(),
- atom(),
- list() | integer()}) ->
- string()).
+-spec mfa2html(MFA :: {atom(), atom(), list() | integer()}) -> string().
mfa2html({Module, Function, Arguments}) when is_list(Arguments) ->
lists:flatten(io_lib:format("~p:~p/~p", [Module, Function, length(Arguments)]));
@@ -566,7 +559,7 @@ mfa2html({Module, Function, Arity}) when is_integer(Arity) ->
mfa2html(_) ->
"undefined".
--spec(pid2html/1 :: (Pid :: pid() | port()) -> string()).
+-spec pid2html(Pid :: pid() | port()) -> string().
pid2html(Pid) when is_pid(Pid) ->
PidString = term2html(Pid),
@@ -577,14 +570,14 @@ pid2html(Pid) when is_port(Pid) ->
pid2html(_) ->
"undefined".
--spec(image_string/1 :: (Request :: string()) -> string()).
+-spec image_string(Request :: string()) -> string().
image_string(Request) ->
"<img border=0 src=\"/cgi-bin/percept_graph/" ++
Request ++
" \">".
--spec(image_string/2 :: (atom() | string(), list()) -> string()).
+-spec image_string(atom() | string(), list()) -> string().
image_string(Request, Options) when is_atom(Request), is_list(Options) ->
image_string(image_string_head(erlang:atom_to_list(Request), Options, []));
@@ -610,13 +603,13 @@ image_string_tail(Request, [{Type, Value} | Opts], Out) ->
%%% percept conversions
--spec(pid2value/1 :: (Pid :: pid()) -> string()).
+-spec pid2value(Pid :: pid()) -> string().
pid2value(Pid) ->
String = lists:flatten(io_lib:format("~p", [Pid])),
lists:sublist(String, 2, erlang:length(String)-2).
--spec(value2pid/1 :: (Value :: string()) -> pid()).
+-spec value2pid(Value :: string()) -> pid().
value2pid(Value) ->
String = lists:flatten("<" ++ Value ++ ">"),
@@ -625,10 +618,8 @@ value2pid(Value) ->
%%% get value
--spec(get_option_value/2 :: (
- Option :: string(),
- Options :: [{string(),any()}]) ->
- {'error', any()} | bool() | pid() | [pid()] | number()).
+-spec get_option_value(Option :: string(), Options :: [{string(),any()}]) ->
+ {'error', any()} | boolean() | pid() | [pid()] | number().
get_option_value(Option, Options) ->
case catch get_option_value0(Option, Options) of
@@ -662,8 +653,7 @@ get_default_option_value(Option) ->
_ -> {error, {undefined_default_option, Option}}
end.
--spec(get_number_value/1 :: (Value :: string()) ->
- number() | {'error', 'illegal_number'}).
+-spec get_number_value(string()) -> number() | {'error', 'illegal_number'}.
get_number_value(Value) ->
% Try float
@@ -710,7 +700,7 @@ menu() ->
<li><a href=/cgi-bin/percept_html/page>overview</a></li>
</ul></div>\n".
--spec(error_msg/1 :: (Error :: string()) -> string()).
+-spec error_msg(Error :: string()) -> string().
error_msg(Error) ->
"<table width=300>
diff --git a/lib/percept/test/egd_SUITE.erl b/lib/percept/test/egd_SUITE.erl
index 603ad628d3..fde02b47d5 100644
--- a/lib/percept/test/egd_SUITE.erl
+++ b/lib/percept/test/egd_SUITE.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2007-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 2007-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%
%%
@@ -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
@@ -142,10 +143,50 @@ image_shape(Config) when is_list(Config) ->
?line ok = bitmap_point_has_color(Bitmap, {W,H}, Pt2, Fgc),
?line ok = bitmap_point_has_color(Bitmap, {W,H}, Pt1, Fgc),
+ ?line <<_/binary>> = egd:render(Im, raw_bitmap, [{render_engine, alpha}]),
+
?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),
+
+ ?line <<_/binary>> = egd_render:binary(Im2, alpha),
+
+ erase(image_size),
+ ok.
+
+
+
+
image_font(suite) ->
[];
image_font(doc) ->
diff --git a/lib/percept/vsn.mk b/lib/percept/vsn.mk
index ef5a20f028..443d25c78f 100644
--- a/lib/percept/vsn.mk
+++ b/lib/percept/vsn.mk
@@ -1 +1 @@
-PERCEPT_VSN = 0.8.3
+PERCEPT_VSN = 0.8.4
diff --git a/lib/public_key/asn1/Makefile b/lib/public_key/asn1/Makefile
index fbea701be9..94abec083c 100644
--- a/lib/public_key/asn1/Makefile
+++ b/lib/public_key/asn1/Makefile
@@ -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%
#
@@ -40,7 +40,7 @@ RELSYSDIR = $(RELEASE_PATH)/lib/public_key-$(VSN)
ASN_TOP = OTP-PUB-KEY
ASN_MODULES = PKIX1Explicit88 PKIX1Implicit88 PKIX1Algorithms88 \
- PKIXAttributeCertificate OTP-PKIX
+ PKIXAttributeCertificate PKCS-1 PKCS-3 OTP-PKIX
ASN_ASNS = $(ASN_MODULES:%=%.asn1)
ASN_ERLS = $(ASN_TOP).erl
ASN_HRLS = $(ASN_TOP).hrl
@@ -110,4 +110,6 @@ OTP-PUB-KEY.asn1db: PKIX1Algorithms88.asn1 \
PKIX1Explicit88.asn1 \
PKIX1Implicit88.asn1 \
PKIXAttributeCertificate.asn1 \
+ PKCS-1.asn1\
+ PKCS-3.asn1\
OTP-PKIX.asn1
diff --git a/lib/public_key/asn1/OTP-PUB-KEY.set.asn b/lib/public_key/asn1/OTP-PUB-KEY.set.asn
index 2f9ccd6b0e..5c76d13115 100644
--- a/lib/public_key/asn1/OTP-PUB-KEY.set.asn
+++ b/lib/public_key/asn1/OTP-PUB-KEY.set.asn
@@ -4,4 +4,5 @@ PKIX1Implicit88.asn1
PKIXAttributeCertificate.asn1
PKIX1Algorithms88.asn1
PKCS-1.asn1
+PKCS-3.asn1
DSS.asn1
diff --git a/lib/public_key/asn1/PKCS-3.asn1 b/lib/public_key/asn1/PKCS-3.asn1
new file mode 100644
index 0000000000..64180b3a85
--- /dev/null
+++ b/lib/public_key/asn1/PKCS-3.asn1
@@ -0,0 +1,21 @@
+PKCS-3 {
+ iso(1) member-body(2) us(840) rsadsi(113549)
+ pkcs(1) 3
+}
+
+DEFINITIONS EXPLICIT TAGS ::=
+
+BEGIN
+
+pkcs-3 OBJECT IDENTIFIER ::=
+ { iso(1) member-body(2) us(840) rsadsi(113549)
+ pkcs(1) 3 }
+
+dhKeyAgreement OBJECT IDENTIFIER ::= { pkcs-3 1 }
+
+DHParameter ::= SEQUENCE {
+ prime INTEGER, -- p
+ base INTEGER, -- g
+ privateValueLength INTEGER OPTIONAL }
+
+END \ No newline at end of file
diff --git a/lib/public_key/doc/src/Makefile b/lib/public_key/doc/src/Makefile
index 08d1396cca..298c28a740 100644
--- a/lib/public_key/doc/src/Makefile
+++ b/lib/public_key/doc/src/Makefile
@@ -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%
#
@@ -56,6 +56,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 = note.gif
# ----------------------------------------------------
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/public_key/doc/src/notes.xml b/lib/public_key/doc/src/notes.xml
index 822f8bdb66..33a424f432 100644
--- a/lib/public_key/doc/src/notes.xml
+++ b/lib/public_key/doc/src/notes.xml
@@ -33,7 +33,43 @@
<rev>A</rev>
<file>notes.xml</file>
</header>
+<section><title>Public_Key 0.6</title>
+
+<section><title>Improvements and New Features</title>
+<list>
+ <item>
+ <p>
+ Support for Diffie-Hellman. ssl-3.11 requires
+ public_key-0.6.</p>
+ <p>
+ Own Id: OTP-7046</p>
+ </item>
+ <item>
+ <p>
+ Moved extended key usage test for ssl values to ssl.</p>
+ <p>
+ Own Id: OTP-8553 Aux Id: seq11541, OTP-8554 </p>
+ </item>
+</list>
+</section>
+
+</section>
+
+<section><title>Public_Key 0.5</title>
+
+ <section><title>Improvements and New Features</title>
+ <list>
+ <item>
+ <p>Added <c>public_key:pkix_transform/2</c> to enable
+ ssl to send CA list during Certificate Request.</p>
+ <p><c>NOTE</c>: SSL (new_ssl) requires public_key-0.5.
+ ssl usage.</p>
+ <p>Own Id: OTP-8372</p>
+ </item>
+ </list>
+ </section>
+</section>
<section><title>Public_Key 0.4</title>
diff --git a/lib/public_key/src/pubkey_cert.erl b/lib/public_key/src/pubkey_cert.erl
index 0ccc74799c..8f7dfa8352 100644
--- a/lib/public_key/src/pubkey_cert.erl
+++ b/lib/public_key/src/pubkey_cert.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%
%%
@@ -455,24 +455,6 @@ validate_extensions([#'Extension'{extnID = ?'id-ce-keyUsage',
AccErr)
end;
-validate_extensions([#'Extension'{extnID = ?'id-ce-extKeyUsage',
- extnValue = KeyUse,
- critical = true} | Rest],
- #path_validation_state{} = ValidationState,
- ExistBasicCon, SelfSigned, UnknownExtensions, Verify,
- AccErr0) ->
- case is_valid_extkey_usage(KeyUse) of
- true ->
- validate_extensions(Rest, ValidationState, ExistBasicCon,
- SelfSigned, UnknownExtensions,
- Verify, AccErr0);
- false ->
- AccErr =
- not_valid({bad_cert, invalid_ext_key_usage}, Verify, AccErr0),
- validate_extensions(Rest, ValidationState, ExistBasicCon,
- SelfSigned, UnknownExtensions, Verify, AccErr)
- end;
-
validate_extensions([#'Extension'{extnID = ?'id-ce-subjectAltName',
extnValue = Names} | Rest],
ValidationState, ExistBasicCon,
@@ -590,13 +572,6 @@ validate_extensions([Extension | Rest], ValidationState,
is_valid_key_usage(KeyUse, Use) ->
lists:member(Use, KeyUse).
-is_valid_extkey_usage(?'id-kp-clientAuth') ->
- true;
-is_valid_extkey_usage(?'id-kp-serverAuth') ->
- true;
-is_valid_extkey_usage(_) ->
- false.
-
validate_subject_alt_names([]) ->
true;
validate_subject_alt_names([AltName | Rest]) ->
diff --git a/lib/public_key/src/pubkey_cert_records.erl b/lib/public_key/src/pubkey_cert_records.erl
index 36b7c47a9c..c7d4080adb 100644
--- a/lib/public_key/src/pubkey_cert_records.erl
+++ b/lib/public_key/src/pubkey_cert_records.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%
%%
@@ -23,7 +23,7 @@
-include("public_key.hrl").
--export([decode_cert/2, encode_cert/1, encode_tbs_cert/1]).
+-export([decode_cert/2, encode_cert/1, encode_tbs_cert/1, transform/2]).
-export([old_decode_cert/2, old_encode_cert/1]). %% Debugging and testing new code.
diff --git a/lib/public_key/src/pubkey_crypto.erl b/lib/public_key/src/pubkey_crypto.erl
index fe4e97fcc5..4ab655e977 100644
--- a/lib/public_key/src/pubkey_crypto.erl
+++ b/lib/public_key/src/pubkey_crypto.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%
%%
@@ -26,7 +26,7 @@
-export([encrypt_public/3, decrypt_private/3,
encrypt_private/3, decrypt_public/3,
- sign/2, sign/3, verify/5]).
+ sign/2, sign/3, verify/5, gen_key/2]).
-define(UINT32(X), X:32/unsigned-big-integer).
@@ -44,10 +44,14 @@
%%
%% Description: Public key encrypts PlainText.
%%--------------------------------------------------------------------
-encrypt_public(PlainText, #'RSAPublicKey'{modulus=N,publicExponent=E},Padding) ->
- crypto:rsa_public_encrypt(PlainText, [crypto:mpint(E),crypto:mpint(N)],Padding);
-encrypt_public(PlainText, #'RSAPrivateKey'{modulus=N,publicExponent=E},Padding) ->
- crypto:rsa_public_encrypt(PlainText, [crypto:mpint(E),crypto:mpint(N)],Padding).
+encrypt_public(PlainText, #'RSAPublicKey'{modulus=N,publicExponent=E},
+ Padding) ->
+ crypto:rsa_public_encrypt(PlainText, [crypto:mpint(E),crypto:mpint(N)],
+ Padding);
+encrypt_public(PlainText, #'RSAPrivateKey'{modulus=N,publicExponent=E},
+ Padding) ->
+ crypto:rsa_public_encrypt(PlainText, [crypto:mpint(E),crypto:mpint(N)],
+ Padding).
encrypt_private(PlainText, #'RSAPrivateKey'{modulus = N,
publicExponent = E,
@@ -67,15 +71,20 @@ encrypt_private(PlainText, #'RSAPrivateKey'{modulus = N,
%% Description: Uses private key to decrypt public key encrypted data.
%%--------------------------------------------------------------------
decrypt_private(CipherText,
- #'RSAPrivateKey'{modulus = N,publicExponent = E,privateExponent = D},
+ #'RSAPrivateKey'{modulus = N,publicExponent = E,
+ privateExponent = D},
Padding) ->
crypto:rsa_private_decrypt(CipherText,
- [crypto:mpint(E), crypto:mpint(N),crypto:mpint(D)],
- Padding).
-decrypt_public(CipherText, #'RSAPublicKey'{modulus = N, publicExponent = E}, Padding) ->
- crypto:rsa_public_decrypt(CipherText,[crypto:mpint(E), crypto:mpint(N)], Padding);
-decrypt_public(CipherText, #'RSAPrivateKey'{modulus = N, publicExponent = E}, Padding) ->
- crypto:rsa_public_decrypt(CipherText,[crypto:mpint(E), crypto:mpint(N)], Padding).
+ [crypto:mpint(E), crypto:mpint(N),
+ crypto:mpint(D)], Padding).
+decrypt_public(CipherText, #'RSAPublicKey'{modulus = N, publicExponent = E},
+ Padding) ->
+ crypto:rsa_public_decrypt(CipherText,[crypto:mpint(E), crypto:mpint(N)],
+ Padding);
+decrypt_public(CipherText, #'RSAPrivateKey'{modulus = N, publicExponent = E},
+ Padding) ->
+ crypto:rsa_public_decrypt(CipherText,[crypto:mpint(E), crypto:mpint(N)],
+ Padding).
%%--------------------------------------------------------------------
%% Function: sign(PlainText, Key) ->
@@ -125,10 +134,24 @@ verify(sha, PlainText, Signature, Key, #'Dss-Parms'{p = P, q = Q, g = G}) ->
[crypto:mpint(P), crypto:mpint(Q),
crypto:mpint(G), crypto:mpint(Key)]).
+
+%%--------------------------------------------------------------------
+%% Function: gen_key(Type, Params) ->
+%% Type = diffie_hellman
+%% Params = [P,G] | [Y, P, G]
+%% Description: Generates keys.
+%% -----------------------------------------------------------------
+gen_key(diffie_hellman, [Y, P, G]) ->
+ crypto:dh_generate_key(crypto:mpint(Y), [crypto:mpint(P),
+ crypto:mpint(G)]);
+gen_key(diffie_hellman, [P, G]) ->
+ crypto:dh_generate_key([crypto:mpint(P), crypto:mpint(G)]).
+
+%%% TODO: Support rsa, dss key_gen
+
%%--------------------------------------------------------------------
%%% Internal functions
%%--------------------------------------------------------------------
-
sized_binary(Binary) when is_binary(Binary) ->
Size = size(Binary),
<<?UINT32(Size), Binary/binary>>;
diff --git a/lib/public_key/src/pubkey_pem.erl b/lib/public_key/src/pubkey_pem.erl
index abd46fa00e..9fc17b6f73 100644
--- a/lib/public_key/src/pubkey_pem.erl
+++ b/lib/public_key/src/pubkey_pem.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%
%%
@@ -155,7 +155,7 @@ unhex(S) ->
unhex(S, []).
unhex("", Acc) ->
- lists:reverse(Acc);
+ list_to_binary(lists:reverse(Acc));
unhex([D1, D2 | Rest], Acc) ->
unhex(Rest, [erlang:list_to_integer([D1, D2], 16) | Acc]).
diff --git a/lib/public_key/src/public_key.appup.src b/lib/public_key/src/public_key.appup.src
index 8d33482f11..46e5ecca33 100644
--- a/lib/public_key/src/public_key.appup.src
+++ b/lib/public_key/src/public_key.appup.src
@@ -1,6 +1,40 @@
%% -*- erlang -*-
{"%VSN%",
[
+ {"0.5",
+ [
+ {update, public_key, soft, soft_purge, soft_purge, []},
+ {update, pubkey_crypto, soft, soft_purge, soft_purge, []},
+ {update, pubkey_pem, soft, soft_purge, soft_purge, []},
+ {update, pubkey_cert, soft, soft_purge, soft_purge, []}
+ ]
+ },
+ {"0.4",
+ [
+ {update, public_key, soft, soft_purge, soft_purge, []},
+ {update, pubkey_cert_records, soft, soft_purge, soft_purge, []},
+ {update, pubkey_crypto, soft, soft_purge, soft_purge, []},
+ {update, pubkey_pem, soft, soft_purge, soft_purge, []},
+ {update, pubkey_cert, soft, soft_purge, soft_purge, []}
+ ]
+ }
],
[
+ {"0.5",
+ [
+ {update, public_key, soft, soft_purge, soft_purge, []},
+ {update, pubkey_crypto, soft, soft_purge, soft_purge, []},
+ {update, pubkey_pem, soft, soft_purge, soft_purge, []},
+ {update, pubkey_cert, soft, soft_purge, soft_purge, []}
+ ]
+ },
+ {"0.4",
+ [
+ {update, public_key, soft, soft_purge, soft_purge, []},
+ {update, pubkey_cert_records, soft, soft_purge, soft_purge, []},
+ {update, pubkey_crypto, soft, soft_purge, soft_purge, []},
+ {update, pubkey_pem, soft, soft_purge, soft_purge, []},
+ {update, pubkey_cert, soft, soft_purge, soft_purge, []}
+ ]
+ }
]}.
diff --git a/lib/public_key/src/public_key.erl b/lib/public_key/src/public_key.erl
index b0b0b7a832..157e76bb21 100644
--- a/lib/public_key/src/public_key.erl
+++ b/lib/public_key/src/public_key.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%
%%
@@ -23,14 +23,13 @@
-include("public_key.hrl").
--export([decode_private_key/1, decode_private_key/2,
+-export([decode_private_key/1, decode_private_key/2, decode_dhparams/1,
decrypt_private/2, decrypt_private/3, encrypt_public/2,
encrypt_public/3, decrypt_public/2, decrypt_public/3,
- encrypt_private/2, encrypt_private/3,
- sign/2, sign/3,
+ encrypt_private/2, encrypt_private/3, gen_key/1, sign/2, sign/3,
verify_signature/3, verify_signature/4, verify_signature/5,
- pem_to_der/1, pem_to_der/2,
- pkix_decode_cert/2, pkix_encode_cert/1,
+ pem_to_der/1, pem_to_der/2, der_to_pem/2,
+ pkix_decode_cert/2, pkix_encode_cert/1, pkix_transform/2,
pkix_is_self_signed/1, pkix_is_fixed_dh_cert/1,
pkix_issuer_id/2,
pkix_is_issuer/2, pkix_normalize_general_name/1,
@@ -62,6 +61,21 @@ decode_private_key(KeyInfo = {dsa_private_key, _, _}, Password) ->
DerEncoded = pubkey_pem:decode_key(KeyInfo, Password),
'OTP-PUB-KEY':decode('DSAPrivateKey', DerEncoded).
+
+%%--------------------------------------------------------------------
+%% Function: decode_dhparams(DhParamInfo) ->
+%% {ok, DhParams} | {error, Reason}
+%%
+%% DhParamsInfo = {Type, der_bin(), ChipherInfo} - as returned from
+%% pem_to_der/[1,2] for DH parameters.
+%% Type = dh_params
+%% ChipherInfo = opaque() | no_encryption
+%%
+%% Description: Decodes an asn1 der encoded DH parameters.
+%%--------------------------------------------------------------------
+decode_dhparams({dh_params, DerEncoded, not_encrypted}) ->
+ 'OTP-PUB-KEY':decode('DHParameter', DerEncoded).
+
%%--------------------------------------------------------------------
%% Function: decrypt_private(CipherText, Key) ->
%% decrypt_private(CipherText, Key, Options) -> PlainTex
@@ -109,6 +123,18 @@ encrypt_private(PlainText, Key, Options) ->
pubkey_crypto:encrypt_private(PlainText, Key, Padding).
%%--------------------------------------------------------------------
+%% Function: gen_key(Params) -> Keys
+%%
+%% Params = #'DomainParameters'{} - Currently only supported option
+%% Keys = {PublicDHKey = integer(), PrivateDHKey = integer()}
+%%
+%% Description: Generates keys. Currently supports Diffie-Hellman keys.
+%%--------------------------------------------------------------------
+gen_key(#'DHParameter'{prime = P, base = G}) when is_integer(P),
+ is_integer(G) ->
+ pubkey_crypto:gen_key(diffie_hellman, [P, G]).
+
+%%--------------------------------------------------------------------
%% Function: pem_to_der(CertSource) ->
%% pem_to_der(CertSource, Password) -> {ok, [Entry]} |
%% {error, Reason}
@@ -116,7 +142,6 @@ encrypt_private(PlainText, Key, Options) ->
%% CertSource = File | CertData
%% CertData = binary()
%% File = path()
-%% Password = string()
%% Entry = {entry_type(), der_bin(), ChipherInfo}
%% ChipherInfo = opague() | no_encryption
%% der_bin() = binary()
@@ -127,7 +152,9 @@ encrypt_private(PlainText, Key, Options) ->
%% entries as asn1 der encoded entities. Currently supported entry
%% types are certificates, certificate requests, rsa private keys and
%% dsa private keys. In the case of a key entry ChipherInfo will be
-%% used by decode_private_key/2 if the key is protected by a password.
+%% private keys and Diffie Hellam parameters .In the case of a key
+%% entry ChipherInfo will be used by decode_private_key/2 if the key
+%% is protected by a password.
%%--------------------------------------------------------------------
pem_to_der(CertSource) ->
pem_to_der(CertSource, no_passwd).
@@ -137,6 +164,9 @@ pem_to_der(File, Password) when is_list(File) ->
pem_to_der(PemBin, Password) when is_binary(PemBin) ->
pubkey_pem:decode(PemBin, Password).
+der_to_pem(File, TypeDerList) ->
+ pubkey_pem:write_file(File, TypeDerList).
+
%%--------------------------------------------------------------------
%% Function: pkix_decode_cert(BerCert, Type) -> {ok, Cert} | {error, Reason}
%%
@@ -162,6 +192,20 @@ pkix_encode_cert(Cert) ->
pubkey_cert_records:encode_cert(Cert).
%%--------------------------------------------------------------------
+%% Function: pkix_transform(CertPart, Op) -> TransformedCertPart
+%%
+%% CertPart = pkix part data
+%% Op = encode | decode
+%%
+%% Description: Transform parts of a pkix certificate between 'plain' format
+%% and the internal 'otp' format, see pkix_decode_cert/2.
+%% Decode transforms from 'plain' to 'otp' and encode from 'otp' to 'plain'
+%% format.
+%%--------------------------------------------------------------------
+pkix_transform(CertPart, Op) ->
+ pubkey_cert_records:transform(CertPart, Op).
+
+%%--------------------------------------------------------------------
%% Function: pkix_path_validation(TrustedCert, CertChain, Options) ->
%% {ok, {{algorithm(), public_key(), public_key_params()} policy_tree()}} |
%% {error, Reason}
@@ -274,9 +318,10 @@ sign(Msg, #'RSAPrivateKey'{} = Key) when is_binary(Msg) ->
sign(Msg, #'DSAPrivateKey'{} = Key) when is_binary(Msg) ->
pubkey_crypto:sign(Msg, Key);
-sign(#'OTPTBSCertificate'{signature = SigAlg} = TBSCert, Key) ->
+sign(#'OTPTBSCertificate'{signature = #'SignatureAlgorithm'{algorithm = Alg}
+ = SigAlg} = TBSCert, Key) ->
Msg = pubkey_cert_records:encode_tbs_cert(TBSCert),
- DigestType = pubkey_cert:digest_type(SigAlg),
+ DigestType = pubkey_cert:digest_type(Alg),
Signature = pubkey_crypto:sign(DigestType, Msg, Key),
Cert = #'OTPCertificate'{tbsCertificate= TBSCert,
signatureAlgorithm = SigAlg,
diff --git a/lib/public_key/test/Makefile b/lib/public_key/test/Makefile
index 2a4687677c..c7215020c7 100644
--- a/lib/public_key/test/Makefile
+++ b/lib/public_key/test/Makefile
@@ -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%
#
@@ -21,7 +21,7 @@ include $(ERL_TOP)/make/target.mk
include $(ERL_TOP)/make/$(TARGET)/otp.mk
-INCLUDES= -I. -I$(ERL_TOP)/lib/test_server/include/ -I ../include \
+INCLUDES= -I. -I ../include
# ----------------------------------------------------
# Target Specs
diff --git a/lib/public_key/test/public_key_SUITE.erl b/lib/public_key/test/public_key_SUITE.erl
index 93ae6e6eda..8cc36e490d 100644
--- a/lib/public_key/test/public_key_SUITE.erl
+++ b/lib/public_key/test/public_key_SUITE.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%
%%
@@ -23,8 +23,9 @@
%% Note: This directive should only be used in test suites.
-compile(export_all).
--include("test_server.hrl").
--include("test_server_line.hrl").
+-include_lib("test_server/include/test_server.hrl").
+-include_lib("test_server/include/test_server_line.hrl").
+
-include("public_key.hrl").
-define(TIMEOUT, 120000). % 2 min
diff --git a/lib/public_key/vsn.mk b/lib/public_key/vsn.mk
index 64f0203915..da1465d538 100644
--- a/lib/public_key/vsn.mk
+++ b/lib/public_key/vsn.mk
@@ -1,6 +1,8 @@
-PUBLIC_KEY_VSN = 0.4
-
-TICKETS = OTP-8250
+PUBLIC_KEY_VSN = 0.6
+TICKETS = OTP-7046 \
+ OTP-8553
+#TICKETS_o.5 = OTP-8372
+#TICKETS_0.4 = OTP-8250
#TICKETS_0.3 = OTP-8100 OTP-8142
#TICKETS_0.2 = OTP-7860
#TICKETS_0.1 = OTP-7637 \ No newline at end of file
diff --git a/lib/reltool/doc/src/Makefile b/lib/reltool/doc/src/Makefile
index 2c634bdf6c..8bc1488f77 100644
--- a/lib/reltool/doc/src/Makefile
+++ b/lib/reltool/doc/src/Makefile
@@ -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%
include $(ERL_TOP)/make/target.mk
@@ -39,6 +39,10 @@ include files.mk
# ----------------------------------------------------
+XML_FILES = \
+ $(BOOK_FILES) $(XML_APPLICATION_FILES) $(XML_REF3_FILES) \
+ $(XML_PART_FILES) $(XML_CHAPTER_FILES)
+
HTML_FILES = $(XML_APPLICATION_FILES:%.xml=$(HTMLDIR)/%.html) \
$(XML_PART_FILES:%.xml=$(HTMLDIR)/%.html)
@@ -46,10 +50,6 @@ INFO_FILE = ../../info
MAN3_FILES = $(XML_REF3_FILES:%.xml=$(MAN3DIR)/%.3)
-XML_FILES = \
- $(BOOK_FILES) $(XML_CHAPTER_FILES) \
- $(XML_PART_FILES) $(XML_REF3_FILES) $(XML_APPLICATION_FILES)
-
HTML_REF_MAN_FILE = $(HTMLDIR)/index.html
TOP_PDF_FILE = $(PDFDIR)/$(APPLICATION)-$(VSN).pdf
@@ -72,15 +72,20 @@ $(TOP_PDF_FILE): $(XML_FILES)
pdf: $(TOP_PDF_FILE)
-html: gifs $(HTML_REF_MAN_FILE)
+html:images $(HTML_REF_MAN_FILE)
man: $(MAN3_FILES)
-gifs: $(GIF_FILES:%=$(HTMLDIR)/%)
+images: $(IMAGE_FILES:%=$(HTMLDIR)/%)
debug opt:
clean clean_docs:
+ for file in $(XML_FILES); do \
+ if [ -f $$file\src ]; then \
+ rm -f $$file; \
+ fi \
+ done
rm -rf $(HTMLDIR)/*
rm -f $(MAN3DIR)/*
rm -f $(TOP_PDF_FILE) $(TOP_PDF_FILE:%.pdf=%.fo)
@@ -95,8 +100,7 @@ release_docs_spec: docs
$(INSTALL_DIR) $(RELSYSDIR)/doc/pdf
$(INSTALL_DATA) $(TOP_PDF_FILE) $(RELSYSDIR)/doc/pdf
$(INSTALL_DIR) $(RELSYSDIR)/doc/html
- $(INSTALL_DATA) $(HTMLDIR)/* \
- $(RELSYSDIR)/doc/html
+ $(INSTALL_DATA) $(HTMLDIR)/* $(RELSYSDIR)/doc/html
$(INSTALL_DATA) $(INFO_FILE) $(RELSYSDIR)
$(INSTALL_DIR) $(RELEASE_PATH)/man/man3
$(INSTALL_DATA) $(MAN3DIR)/* $(RELEASE_PATH)/man/man3
diff --git a/lib/reltool/doc/src/book.gif b/lib/reltool/doc/src/book.gif
deleted file mode 100644
index 94b3868792..0000000000
--- a/lib/reltool/doc/src/book.gif
+++ /dev/null
Binary files differ
diff --git a/lib/reltool/doc/src/fascicules.xml b/lib/reltool/doc/src/fascicules.xml
deleted file mode 100644
index a57808974e..0000000000
--- a/lib/reltool/doc/src/fascicules.xml
+++ /dev/null
@@ -1,17 +0,0 @@
-<?xml version="1.0" encoding="latin1" ?>
-<!DOCTYPE fascicules SYSTEM "fascicules.dtd">
-
-<fascicules>
- <fascicule file="part" href="part_frame.html" entry="no">
- User's Guide
- </fascicule>
- <fascicule file="ref_man" href="ref_man_frame.html" entry="yes">
- Reference Manual
- </fascicule>
- <fascicule file="part_notes" href="part_notes_frame.html" entry="no">
- Release Notes
- </fascicule>
- <fascicule file="" href="../../../../doc/print.html" entry="no">
- Off-Print
- </fascicule>
-</fascicules>
diff --git a/lib/reltool/doc/src/files.mk b/lib/reltool/doc/src/files.mk
index b2dc06411d..07b52f4934 100644
--- a/lib/reltool/doc/src/files.mk
+++ b/lib/reltool/doc/src/files.mk
@@ -1,20 +1,20 @@
#-*-makefile-*- ; force emacs to enter makefile-mode
#
# %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%
XML_APPLICATION_FILES = \
@@ -24,8 +24,7 @@ XML_REF3_FILES = \
reltool.xml
XML_PART_FILES = \
- part.xml \
- part_notes.xml
+ part.xml
XML_CHAPTER_FILES = \
reltool_intro.xml \
@@ -35,11 +34,5 @@ XML_CHAPTER_FILES = \
BOOK_FILES = book.xml
-GIF_FILES = \
- book.gif \
- note.gif \
- notes.gif \
- ref_man.gif \
- user_guide.gif \
- warning.gif
+IMAGE_FILES =
diff --git a/lib/reltool/doc/src/note.gif b/lib/reltool/doc/src/note.gif
deleted file mode 100644
index 6fffe30419..0000000000
--- a/lib/reltool/doc/src/note.gif
+++ /dev/null
Binary files differ
diff --git a/lib/reltool/doc/src/notes.gif b/lib/reltool/doc/src/notes.gif
deleted file mode 100644
index e000cca26a..0000000000
--- a/lib/reltool/doc/src/notes.gif
+++ /dev/null
Binary files differ
diff --git a/lib/reltool/doc/src/notes.xml b/lib/reltool/doc/src/notes.xml
index 293793e900..524d728901 100644
--- a/lib/reltool/doc/src/notes.xml
+++ b/lib/reltool/doc/src/notes.xml
@@ -38,6 +38,21 @@
section is the version number of Reltool.</p>
+ <section><title>Reltool 0.5.3</title>
+
+ <section><title>Improvements and New Features</title>
+ <list>
+ <item>
+ <p>
+ Removed spurious documentation files.</p>
+ <p>
+ Own Id: OTP-8057</p>
+ </item>
+ </list>
+ </section>
+
+ </section>
+
<section><title>Reltool 0.5.2</title>
<section><title>Improvements and New Features</title>
diff --git a/lib/reltool/doc/src/part_notes.xml b/lib/reltool/doc/src/part_notes.xml
deleted file mode 100644
index 5a2aeecce6..0000000000
--- a/lib/reltool/doc/src/part_notes.xml
+++ /dev/null
@@ -1,41 +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>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>Reltool Release Notes</title>
- <prepared>H&aring;kan Mattsson</prepared>
- <docno></docno>
- <date></date>
- <rev>%VSN%</rev>
- </header>
- <description>
- <p><c>Reltool</c> is a release management tool. It analyses a given
- Erlang/OTP installation and determines various dependencies
- between applications. The <c>graphical</c> frontend depicts the
- dependencies and enables interactive customization of a
- target system. The backend provides a <c>batch</c> interface
- for generation of customized target systems.</p>
- </description>
- <xi:include href="notes.xml"/>
-</part>
diff --git a/lib/reltool/doc/src/ref_man.gif b/lib/reltool/doc/src/ref_man.gif
deleted file mode 100644
index b13c4efd53..0000000000
--- a/lib/reltool/doc/src/ref_man.gif
+++ /dev/null
Binary files differ
diff --git a/lib/reltool/doc/src/reltool_examples.xml b/lib/reltool/doc/src/reltool_examples.xml
index 3d087862e6..d6db246f6c 100644
--- a/lib/reltool/doc/src/reltool_examples.xml
+++ b/lib/reltool/doc/src/reltool_examples.xml
@@ -45,7 +45,8 @@
its server can be obtained with <c>reltool:get_server/1</c></p>
<pre>
-Erlang R13B02 (erts-5.7.3) [source] [64-bit] [smp:4:4] [rq:4] [async-threads:0] [kernel-poll:false]
+Erlang R13B02 (erts-5.7.3) [source] [64-bit] [smp:4:4] [rq:4]
+ [async-threads:0] [kernel-poll:false]
Eshell V5.7.3 (abort with ^G)
1&gt; {ok, Win} = reltool:start([]).
@@ -72,10 +73,13 @@ ok
<title>Inspecting the configuration</title>
<pre>
-Erlang R13B02 (erts-5.7.3) [source] [64-bit] [smp:4:4] [rq:4] [async-threads:0] [kernel-poll:false]
+Erlang R13B02 (erts-5.7.3) [source] [64-bit] [smp:4:4] [rq:4]
+ [async-threads:0] [kernel-poll:false]
Eshell V5.7.3 (abort with ^G)
-1&gt; Config = {sys, [{escript, "examples/display_args", [{incl_cond, include}]},
+1&gt; Config = {sys, [{escript,
+ "examples/display_args",
+ [{incl_cond, include}]},
{app, inets, [{incl_cond, include}]},
{app, mnesia, [{incl_cond, exclude}]},
{app, ssl, [{incl_cond, exclude}]},
@@ -244,7 +248,8 @@ Eshell V5.7.3 (abort with ^G)
<title>Generate release and script files</title>
<pre>
5&gt; {ok, Server} = reltool:start_server([{config, {sys, [{boot_rel, "NAME"},
- {rel, "NAME", "VSN", [kernel, stdlib, sasl]}]}}]).
+ {rel, "NAME", "VSN",
+ [kernel, stdlib, sasl]}]}}]).
{ok,&lt;0.1288.0&gt;}
6&gt; reltool:get_config(Server).
{ok,{sys,[{boot_rel,"NAME"},
@@ -297,10 +302,13 @@ ok
<section>
<title>Create a target system</title>
<pre>
-Erlang R13B02 (erts-5.7.3) [source] [64-bit] [smp:4:4] [rq:4] [async-threads:0] [kernel-poll:false]
+Erlang R13B02 (erts-5.7.3) [source] [64-bit] [smp:4:4] [rq:4]
+ [async-threads:0] [kernel-poll:false]
Eshell V5.7.3 (abort with ^G)
-1&gt; Config = {sys, [{escript, "examples/display_args", [{incl_cond, include}]},
+1&gt; Config = {sys, [{escript,
+ "examples/display_args",
+ [{incl_cond, include}]},
{app, inets, [{incl_cond, include}]},
{app, mnesia, [{incl_cond, exclude}]},
{app, ssl, [{incl_cond, exclude}]},
@@ -320,11 +328,11 @@ Eshell V5.7.3 (abort with ^G)
[{write_file,"start_erl.data","5.7.3 1.0"},
{create_dir,"1.0",
[{write_file,"start_clean.rel",
- [37,37,32,114,101,108,32,103,101,110,101,114,97,116|...]},
+ [37,37,32,114,101,108,32,103,101,110,101|...]},
{write_file,"start_clean.script",
- [37,37,32,115,99,114,105,112,116,32,103,101,110|...]},
+ [37,37,32,115,99,114,105,112,116,32|...]},
{write_file,"start_clean.boot",
- &lt;&lt;131,104,3,100,0,6,115,99,114,105,112,116,...&gt;&gt;},
+ &lt;&lt;131,104,3,100,0,6,115,99,114,...&gt;&gt;},
{write_file,"start_sasl.rel",
[37,37,32,114,101,108,32,103,101,110,101|...]},
{write_file,"start_sasl.script",
@@ -409,11 +417,13 @@ Eshell V5.7.3 (abort with ^G)
{copy_file,...},
{...}|...]},
{create_dir,"src",
- [{copy_file,[...]},{copy_file,...},{...}|...]}]}]},
+ [{copy_file,[...]},
+ {copy_file,...},{...}|...]}]}]},
{archive,"crypto-1.6.1.ez",[],
[{create_dir,"crypto-1.6.1",
[{create_dir,"ebin",
- [{copy_file,[...]},{copy_file,...},{...}|...]},
+ [{copy_file,[...]},
+ {copy_file,...},{...}|...]},
{create_dir,"src",[{copy_file,...},{...}|...]}]}]},
{create_dir,"crypto-1.6.1",
[{create_dir,"priv",
diff --git a/lib/reltool/doc/src/user_guide.gif b/lib/reltool/doc/src/user_guide.gif
deleted file mode 100644
index e6275a803d..0000000000
--- a/lib/reltool/doc/src/user_guide.gif
+++ /dev/null
Binary files differ
diff --git a/lib/reltool/doc/src/warning.gif b/lib/reltool/doc/src/warning.gif
deleted file mode 100644
index 96af52360e..0000000000
--- a/lib/reltool/doc/src/warning.gif
+++ /dev/null
Binary files differ
diff --git a/lib/reltool/src/reltool_target.erl b/lib/reltool/src/reltool_target.erl
index 895fc6702b..6d85a98d9f 100644
--- a/lib/reltool/src/reltool_target.erl
+++ b/lib/reltool/src/reltool_target.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(reltool_target).
@@ -966,9 +966,9 @@ do_eval_spec({create_dir, Dir, Files}, OrigSourceDir, SourceDir, TargetDir) ->
TargetDir2 = filename:join([TargetDir, Dir]),
reltool_utils:create_dir(TargetDir2),
do_eval_spec(Files, OrigSourceDir, SourceDir2, TargetDir2);
-do_eval_spec({create_dir, NewDir, OldDir, Files}, OrigSourceDir, _SourceDir, TargetDir) ->
+do_eval_spec({create_dir, Dir, OldDir, Files}, OrigSourceDir, _SourceDir, TargetDir) ->
SourceDir2 = filename:join([OrigSourceDir, OldDir]),
- TargetDir2 = filename:join([TargetDir, NewDir]),
+ TargetDir2 = filename:join([TargetDir, Dir]),
reltool_utils:create_dir(TargetDir2),
do_eval_spec(Files, SourceDir2, SourceDir2, TargetDir2);
do_eval_spec({archive, Archive, Options, Files}, OrigSourceDir, SourceDir, TargetDir) ->
@@ -992,9 +992,9 @@ do_eval_spec({copy_file, File}, _OrigSourceDir, SourceDir, TargetDir) ->
SourceFile = filename:join([SourceDir, File]),
TargetFile = filename:join([TargetDir, File]),
reltool_utils:copy_file(SourceFile, TargetFile);
-do_eval_spec({copy_file, NewFile, OldFile}, OrigSourceDir, _SourceDir, TargetDir) ->
+do_eval_spec({copy_file, File, OldFile}, OrigSourceDir, _SourceDir, TargetDir) ->
SourceFile = filename:join([OrigSourceDir, OldFile]),
- TargetFile = filename:join([TargetDir, NewFile]),
+ TargetFile = filename:join([TargetDir, File]),
reltool_utils:copy_file(SourceFile, TargetFile);
do_eval_spec({write_file, File, IoList}, _OrigSourceDir, _SourceDir, TargetDir) ->
TargetFile = filename:join([TargetDir, File]),
@@ -1014,8 +1014,8 @@ cleanup_spec({create_dir, Dir, Files}, TargetDir) ->
TargetDir2 = filename:join([TargetDir, Dir]),
cleanup_spec(Files, TargetDir2),
file:del_dir(TargetDir2);
-cleanup_spec({create_dir, NewDir, _OldDir, Files}, TargetDir) ->
- TargetDir2 = filename:join([TargetDir, NewDir]),
+cleanup_spec({create_dir, Dir, _OldDir, Files}, TargetDir) ->
+ TargetDir2 = filename:join([TargetDir, Dir]),
cleanup_spec(Files, TargetDir2),
file:del_dir(TargetDir2);
cleanup_spec({archive, Archive, _Options, Files}, TargetDir) ->
@@ -1125,6 +1125,8 @@ match(String, [#regexp{source = _, compiled = MP} | Regexps]) ->
end.
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%% Old style installation
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
install(RelName, TargetDir) ->
try
@@ -1220,7 +1222,6 @@ subst_var([C| Rest], Vars, Result, VarAcc) ->
subst_var(Rest, Vars, Result, [C| VarAcc]);
subst_var([], Vars, Result, VarAcc) ->
subst([], Vars, [VarAcc ++ [$% | Result]]).
-
start_scripts() ->
["erl", "start", "start_erl"].
diff --git a/lib/reltool/test/Makefile b/lib/reltool/test/Makefile
new file mode 100644
index 0000000000..00d2add3e5
--- /dev/null
+++ b/lib/reltool/test/Makefile
@@ -0,0 +1,82 @@
+#
+# %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%
+
+include $(ERL_TOP)/make/target.mk
+include $(ERL_TOP)/make/$(TARGET)/otp.mk
+
+# ----------------------------------------------------
+# Target Specs
+# ----------------------------------------------------
+
+MODULES= \
+ rtt \
+ reltool_wx_SUITE \
+ reltool_server_SUITE \
+ reltool_test_lib
+
+
+ERL_FILES= $(MODULES:%=%.erl)
+
+HRL_FILES= reltool_test_lib.hrl
+
+TARGET_FILES= \
+ $(MODULES:%=$(EBIN)/%.$(EMULATOR))
+
+INSTALL_PROGS= $(TARGET_FILES)
+
+# ----------------------------------------------------
+# Release directory specification
+# ----------------------------------------------------
+RELSYSDIR = $(RELEASE_PATH)/reltool_test
+
+# ----------------------------------------------------
+# FLAGS
+# ----------------------------------------------------
+#ERL_COMPILE_FLAGS +=
+
+EBIN = .
+
+# ----------------------------------------------------
+# Targets
+# ----------------------------------------------------
+
+tests debug opt: $(TARGET_FILES)
+
+clean:
+ rm -f $(TARGET_FILES)
+ rm -f core
+
+docs:
+
+# ----------------------------------------------------
+# Release Target
+# ----------------------------------------------------
+include $(ERL_TOP)/make/otp_release_targets.mk
+
+release_spec: opt
+
+release_tests_spec: opt
+ $(INSTALL_DIR) $(RELSYSDIR)
+ $(INSTALL_DATA) reltool.spec $(ERL_FILES) $(HRL_FILES) $(RELSYSDIR)
+ $(INSTALL_PROGRAM) rtt $(INSTALL_PROGS) $(RELSYSDIR)
+# chmod -f -R u+w $(RELSYSDIR)
+# @tar cf - *_SUITE_data | (cd $(RELSYSDIR); tar xf -)
+
+release_docs_spec:
+
+
diff --git a/lib/reltool/test/README b/lib/reltool/test/README
new file mode 100644
index 0000000000..031bd2c961
--- /dev/null
+++ b/lib/reltool/test/README
@@ -0,0 +1,30 @@
+
+Testing and running reltool tests.
+
+Testing gui api/applications can be hard, but we can at least
+test that wxerlang behaves as we expected, i.e. that the api
+is consistent and that it don't crash.
+
+The tests are structured as they are because we want you to
+be able to run them in three different ways.
+ - direct via an erlang shell
+ - via common_test application
+ - via erlang/OTP inhouse ts tool.
+
+To run all the tests compile them and on unix
+run ./rtt to create an erlang terminal.
+
+Invoke rtt:t(). in the erlang shell to run all regression tests.
+If you want to specific tests invoke rtt:t(Module)
+or rtt:t(Module, TestCase).
+
+To run all tests including the ones that require manual intervention run.
+rtt:t(all, [{user,true}]).
+
+To see every test_case window use
+rtt:t(all, [{user,step}]).
+This requires that you manually close each window to step to the
+next test_case.
+
+If you want to run specific test_cases use:
+rtt:t({Module,TestCase}, [{user,step}]).
diff --git a/lib/reltool/test/reltool.spec b/lib/reltool/test/reltool.spec
new file mode 100644
index 0000000000..252232e09d
--- /dev/null
+++ b/lib/reltool/test/reltool.spec
@@ -0,0 +1,2 @@
+{topcase, {dir, "../reltool_test"}}.
+
diff --git a/lib/reltool/test/reltool_server_SUITE.erl b/lib/reltool/test/reltool_server_SUITE.erl
new file mode 100644
index 0000000000..cf951191a0
--- /dev/null
+++ b/lib/reltool/test/reltool_server_SUITE.erl
@@ -0,0 +1,494 @@
+%%
+%% %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(reltool_server_SUITE).
+
+-export([all/0, init_per_suite/1, end_per_suite/1,
+ init_per_testcase/2, fin_per_testcase/2, end_per_testcase/2]).
+
+-compile(export_all).
+
+-include("reltool_test_lib.hrl").
+
+-define(NODE_NAME, '__RELTOOL__TEMPORARY_TEST__NODE__').
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%% Initialization functions.
+
+init_per_suite(Config) ->
+ reltool_test_lib:init_per_suite(Config).
+
+end_per_suite(Config) ->
+ reltool_test_lib:end_per_suite(Config).
+
+init_per_testcase(Func,Config) ->
+ reltool_test_lib:init_per_testcase(Func,Config).
+end_per_testcase(Func,Config) ->
+ reltool_test_lib:end_per_testcase(Func,Config).
+fin_per_testcase(Func,Config) -> %% For test_server
+ reltool_test_lib:end_per_testcase(Func,Config).
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%% SUITE specification
+
+all() ->
+ all(suite).
+all(suite) ->
+ [
+ start_server,
+ set_config,
+ create_release,
+ create_script,
+ create_target,
+ create_embedded,
+ create_standalone,
+ create_old_target
+ ].
+
+%% The test cases
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%% Start a server process and check that it does not crash
+
+start_server(TestInfo) when is_atom(TestInfo) ->
+ reltool_test_lib:tc_info(TestInfo);
+start_server(_Config) ->
+ {ok, Pid} = ?msym({ok, _}, reltool:start_server([])),
+ Libs = lists:sort(erl_libs()),
+ StrippedDefault =
+ case Libs of
+ [] -> {sys, []};
+ _ -> {sys, [{lib_dirs, Libs}]}
+ end,
+ ?m({ok, StrippedDefault}, reltool:get_config(Pid)),
+ ?m(ok, reltool:stop(Pid)),
+ ok.
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%% Start a server process and check that it does not crash
+
+set_config(TestInfo) when is_atom(TestInfo) ->
+ reltool_test_lib:tc_info(TestInfo);
+set_config(_Config) ->
+ Libs = lists:sort(erl_libs()),
+ Default =
+ {sys,
+ [
+ {mod_cond, all},
+ {incl_cond, derived},
+ {root_dir, code:root_dir()},
+ {lib_dirs, Libs}
+ ]},
+ {ok, Pid} = ?msym({ok, _}, reltool:start_server([{config, Default}])),
+ StrippedDefault =
+ case Libs of
+ [] -> {sys, []};
+ _ -> {sys, [{lib_dirs, Libs}]}
+ end,
+ ?m({ok, StrippedDefault}, reltool:get_config(Pid)),
+
+ ?m(ok, reltool:stop(Pid)),
+ ok.
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%% Generate releases
+
+create_release(TestInfo) when is_atom(TestInfo) ->
+ reltool_test_lib:tc_info(TestInfo);
+create_release(_Config) ->
+ %% Configure the server
+ RelName = "Just testing...",
+ RelVsn = "1.0",
+ Config =
+ {sys,
+ [
+ {lib_dirs, []},
+ {boot_rel, RelName},
+ {rel, RelName, RelVsn, [kernel, stdlib]}
+ ]},
+ %% Generate release
+ ErtsVsn = erlang:system_info(version),
+ Apps = application:loaded_applications(),
+ {value, {_, _, KernelVsn}} = lists:keysearch(kernel, 1, Apps),
+ {value, {_, _, StdlibVsn}} = lists:keysearch(stdlib, 1, Apps),
+ Rel = {release, {RelName, RelVsn},
+ {erts, ErtsVsn},
+ [{kernel, KernelVsn},
+ {stdlib, StdlibVsn}]},
+ ?m({ok, Rel}, reltool:get_rel([{config, Config}], RelName)),
+ ok.
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%% Generate boot scripts
+
+create_script(TestInfo) when is_atom(TestInfo) ->
+ reltool_test_lib:tc_info(TestInfo);
+create_script(_Config) ->
+ %% Configure the server
+ RelName = "Just testing",
+ RelVsn = "1.0",
+ Config =
+ {sys,
+ [
+ {lib_dirs, []},
+ {boot_rel, RelName},
+ {rel, RelName, RelVsn, [stdlib, kernel]}
+ ]},
+ {ok, Pid} = ?msym({ok, _}, reltool:start_server([{config, Config}])),
+
+ %% Generate release file
+ ErtsVsn = erlang:system_info(version),
+ Apps = application:loaded_applications(),
+ {value, {_, _, KernelVsn}} = lists:keysearch(kernel, 1, Apps),
+ {value, {_, _, StdlibVsn}} = lists:keysearch(stdlib, 1, Apps),
+ Rel = {release,
+ {RelName, RelVsn},
+ {erts, ErtsVsn},
+ [{stdlib, StdlibVsn}, {kernel, KernelVsn}]},
+ ?m({ok, Rel}, reltool:get_rel(Pid, RelName)),
+ RelFile = RelName ++ ".rel",
+ ?m(ok, file:write_file(RelFile, io_lib:format("~p.\n", [Rel]))),
+
+ %% Generate script file
+ ?m(ok, systools:make_script(RelName, [])),
+ ScriptFile = RelName ++ ".script",
+ {ok, [OrigScript]} = ?msym({ok, [_]}, file:consult(ScriptFile)),
+ {ok, Script} = ?msym({ok, _}, reltool:get_script(Pid, RelName)),
+ %% OrigScript2 = sort_script(OrigScript),
+ %% Script2 = sort_script(Script),
+ %% ?m(OrigScript2, Script2),
+
+ ?m(equal, diff_script(OrigScript, Script)),
+
+ %% Stop server
+ ?m(ok, reltool:stop(Pid)),
+ ok.
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%% Generate target system
+
+create_target(TestInfo) when is_atom(TestInfo) ->
+ reltool_test_lib:tc_info(TestInfo);
+create_target(_Config) ->
+ %% Configure the server
+ RelName1 = "Just testing",
+ RelName2 = "Just testing with SASL",
+ RelVsn = "1.0",
+ Config =
+ {sys,
+ [
+ {root_dir, code:root_dir()},
+ {lib_dirs, []},
+ {boot_rel, RelName2},
+ {rel, RelName1, RelVsn, [stdlib, kernel]},
+ {rel, RelName2, RelVsn, [sasl, stdlib, kernel]},
+ {app, sasl, [{incl_cond, include}]}
+ ]},
+
+ %% Generate target file
+ TargetDir = "reltool_target_dir_development",
+ ?m(ok, reltool_utils:recursive_delete(TargetDir)),
+ ?m(ok, file:make_dir(TargetDir)),
+ ?m(ok, reltool:create_target([{config, Config}], TargetDir)),
+
+ Erl = filename:join([TargetDir, "bin", "erl"]),
+ {ok, Node} = ?msym({ok, _}, start_node(?NODE_NAME, Erl)),
+ ?msym(ok, stop_node(Node)),
+
+ ok.
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%% Generate embedded target system
+
+create_embedded(TestInfo) when is_atom(TestInfo) ->
+ reltool_test_lib:tc_info(TestInfo);
+create_embedded(_Config) ->
+ %% Configure the server
+ RelName1 = "Just testing",
+ RelName2 = "Just testing with SASL",
+ RelVsn = "1.0",
+ Config =
+ {sys,
+ [
+ {lib_dirs, []},
+ {profile, embedded},
+ {boot_rel, RelName2},
+ {rel, RelName1, RelVsn, [stdlib, kernel]},
+ {rel, RelName2, RelVsn, [sasl, stdlib, kernel]},
+ {app, sasl, [{incl_cond, include}]}
+ ]},
+
+ %% Generate target file
+ TargetDir = "reltool_target_dir_embedded",
+ ?m(ok, reltool_utils:recursive_delete(TargetDir)),
+ ?m(ok, file:make_dir(TargetDir)),
+ ?m(ok, reltool:create_target([{config, Config}], TargetDir)),
+
+ Erl = filename:join([TargetDir, "bin", "erl"]),
+ {ok, Node} = ?msym({ok, _}, start_node(?NODE_NAME, Erl)),
+ ?msym(ok, stop_node(Node)),
+
+ ok.
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%% Generate standalone system
+
+create_standalone(TestInfo) when is_atom(TestInfo) ->
+ reltool_test_lib:tc_info(TestInfo);
+create_standalone(_Config) ->
+ %% Configure the server
+ ExDir = code:lib_dir(reltool, examples),
+ EscriptName = "display_args",
+ Escript = filename:join([ExDir, EscriptName]),
+ Config =
+ {sys,
+ [
+ {lib_dirs, []},
+ {escript, Escript, [{incl_cond, include}]},
+ {profile, standalone}
+ ]},
+
+ %% Generate target file
+ TargetDir = "reltool_target_dir_standalone",
+ ?m(ok, reltool_utils:recursive_delete(TargetDir)),
+ ?m(ok, file:make_dir(TargetDir)),
+ ?m(ok, reltool:create_target([{config, Config}], TargetDir)),
+
+ BinDir = filename:join([TargetDir, "bin"]),
+ Erl = filename:join([BinDir, "erl"]),
+ {ok, Node} = ?msym({ok, _}, start_node(?NODE_NAME, Erl)),
+ RootDir = ?ignore(rpc:call(Node, code, root_dir, [])),
+ ?msym(ok, stop_node(Node)),
+
+ Expected = iolist_to_binary(["Root dir: ", RootDir, "\n"
+ "Script args: [\"-arg1\",\"arg2\",\"arg3\"]\n",
+ "Smp: false\n",
+ "ExitCode:0"]),
+ io:format("Expected: ~s\n", [Expected]),
+ ?m(Expected, run(BinDir, EscriptName ++ " -arg1 arg2 arg3")),
+
+ ok.
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%% Generate old type of target system
+
+create_old_target(TestInfo) when is_atom(TestInfo) ->
+ reltool_test_lib:tc_info(TestInfo);
+create_old_target(_Config) ->
+ %% Configure the server
+ RelName1 = "Just testing",
+ RelName2 = "Just testing with SASL",
+ RelVsn = "1.0",
+ Config =
+ {sys,
+ [
+ {lib_dirs, []},
+ {boot_rel, RelName2},
+ {rel, RelName1, RelVsn, [stdlib, kernel]},
+ {rel, RelName2, RelVsn, [sasl, stdlib, kernel]},
+ {relocatable, false}, % Implies explicit old style installation
+ {app, sasl, [{incl_cond, include}]}
+ ]},
+
+ %% Generate target file
+ TargetDir = "reltool_target_dir_old",
+ ?m(ok, reltool_utils:recursive_delete(TargetDir)),
+ ?m(ok, file:make_dir(TargetDir)),
+ ?m(ok, reltool:create_target([{config, Config}], TargetDir)),
+
+ %% io:format("Will fail on Windows (should patch erl.ini)\n", []),
+ ?m(ok, reltool:install(RelName2, TargetDir)),
+
+ Erl = filename:join([TargetDir, "bin", "erl"]),
+ {ok, Node} = ?msym({ok, _}, start_node(?NODE_NAME, Erl)),
+ ?msym(ok, stop_node(Node)),
+
+ ok.
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%% Library functions
+
+erl_libs() ->
+ case os:getenv("ERL_LIBS") of
+ false -> [];
+ LibStr -> string:tokens(LibStr, ":;")
+ end.
+
+diff_script(Script, Script) ->
+ equal;
+diff_script({script, Rel, Commands1}, {script, Rel, Commands2}) ->
+ diff_cmds(Commands1, Commands2);
+diff_script({script, Rel1, _}, {script, Rel2, _}) ->
+ {error, {Rel1, Rel2}}.
+
+diff_cmds([Cmd | Commands1], [Cmd | Commands2]) ->
+ diff_cmds(Commands1, Commands2);
+diff_cmds([Cmd1 | _Commands1], [Cmd2 | _Commands2]) ->
+ {diff, {expected, Cmd1}, {actual, Cmd2}};
+diff_cmds([], []) ->
+ equal.
+
+os_cmd(Cmd) when is_list(Cmd) ->
+ %% Call the plain os:cmd with an echo command appended to print command status
+ %% io:format("os:cmd(~p).\n", [Cmd]),
+ case os:cmd(Cmd++";echo \"#$?\"") of
+ %% There is (as far as I can tell) only one thing that will match this
+ %% and that is too silly to ever be used, but...
+ []->
+ {99, []};
+ Return->
+ %% Find the position of the status code wich is last in the string
+ %% prepended with #
+ case string:rchr(Return, $#) of
+
+ %% This happens only if the sh command pipe is somehow interrupted
+ 0->
+ {98, Return};
+
+ Position->
+ Result = string:left(Return,Position - 1),
+ Status = string:substr(Return,Position + 1, length(Return) - Position - 1),
+ {list_to_integer(Status), Result}
+ end
+ end.
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%% Node handling
+
+start_node(Name, ErlPath) ->
+ FullName = full_node_name(Name),
+ CmdLine = mk_node_cmdline(Name, ErlPath),
+ io:format("Starting node ~p: ~s~n", [FullName, CmdLine]),
+ case open_port({spawn, CmdLine}, []) of
+ Port when is_port(Port) ->
+ unlink(Port),
+ erlang:port_close(Port),
+ case ping_node(FullName, 50) of
+ ok -> {ok, FullName};
+ Other -> exit({failed_to_start_node, FullName, Other})
+ end;
+ Error ->
+ exit({failed_to_start_node, FullName, Error})
+ end.
+
+stop_node(Node) ->
+ monitor_node(Node, true),
+ spawn(Node, fun () -> halt() end),
+ receive {nodedown, Node} -> ok end.
+
+mk_node_cmdline(Name) ->
+ Prog = case catch init:get_argument(progname) of
+ {ok,[[P]]} -> P;
+ _ -> exit(no_progname_argument_found)
+ end,
+ mk_node_cmdline(Name, Prog).
+
+mk_node_cmdline(Name, Prog) ->
+ Static = "-detached -noinput",
+ Pa = filename:dirname(code:which(?MODULE)),
+ NameSw = case net_kernel:longnames() of
+ false -> "-sname ";
+ true -> "-name ";
+ _ -> exit(not_distributed_node)
+ end,
+ {ok, Pwd} = file:get_cwd(),
+ NameStr = atom_to_list(Name),
+ Prog ++ " "
+ ++ Static ++ " "
+ ++ NameSw ++ " " ++ NameStr ++ " "
+ ++ "-pa " ++ Pa ++ " "
+ ++ "-env ERL_CRASH_DUMP " ++ Pwd ++ "/erl_crash_dump." ++ NameStr ++ " "
+ ++ "-setcookie " ++ atom_to_list(erlang:get_cookie()).
+
+full_node_name(PreName) ->
+ HostSuffix = lists:dropwhile(fun ($@) -> false; (_) -> true end,
+ atom_to_list(node())),
+ list_to_atom(atom_to_list(PreName) ++ HostSuffix).
+
+ping_node(_Node, 0) ->
+ {error, net_adm};
+ping_node(Node, N) when is_integer(N), N > 0 ->
+ case catch net_adm:ping(Node) of
+ pong ->
+ wait_for_process(Node, code_server, 50);
+ _ ->
+ timer:sleep(1000),
+ ping_node(Node, N-1)
+ end.
+
+wait_for_process(_Node, Name, 0) ->
+ {error, Name};
+wait_for_process(Node, Name, N) when is_integer(N), N > 0 ->
+ case rpc:call(Node, erlang, whereis, [Name]) of
+ undefined ->
+ timer:sleep(1000),
+ wait_for_process(Node, Name, N-1);
+ {badrpc, _} = Reason ->
+ erlang:error({Reason, Node});
+ Pid when is_pid(Pid) ->
+ ok
+ end.
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%% Run escript
+
+run(Dir, Cmd0) ->
+ Cmd = case os:type() of
+ {win32,_} -> filename:nativename(Dir) ++ "\\" ++ Cmd0;
+ _ -> Cmd0
+ end,
+ do_run(Dir, Cmd).
+
+run(Dir, Opts, Cmd0) ->
+ Cmd = case os:type() of
+ {win32,_} -> Opts ++ " " ++ filename:nativename(Dir) ++ "\\" ++ Cmd0;
+ _ -> Opts ++ " " ++ Dir ++ "/" ++ Cmd0
+ end,
+ do_run(Dir, Cmd).
+
+do_run(Dir, Cmd) ->
+ io:format("Run: ~p\n", [Cmd]),
+ Env = [{"PATH",Dir++":"++os:getenv("PATH")}],
+ Port = open_port({spawn,Cmd}, [exit_status,eof,in,{env,Env}]),
+ Res = get_data(Port, []),
+ receive
+ {Port,{exit_status,ExitCode}} ->
+ iolist_to_binary([Res,"ExitCode:"++integer_to_list(ExitCode)])
+ end.
+
+get_data(Port, SoFar) ->
+ receive
+ {Port,{data,Bytes}} ->
+ get_data(Port, [SoFar|Bytes]);
+ {Port,eof} ->
+ erlang:port_close(Port),
+ SoFar
+ end.
+
+expected_output([data_dir|T], Data) ->
+ Slash = case os:type() of
+ {win32,_} -> "\\";
+ _ -> "/"
+ end,
+ [filename:nativename(Data)++Slash|expected_output(T, Data)];
+expected_output([H|T], Data) ->
+ [H|expected_output(T, Data)];
+expected_output([], _) ->
+ [];
+expected_output(Bin, _) when is_binary(Bin) ->
+ Bin.
diff --git a/lib/reltool/test/reltool_test_lib.erl b/lib/reltool/test/reltool_test_lib.erl
new file mode 100644
index 0000000000..25978294ee
--- /dev/null
+++ b/lib/reltool/test/reltool_test_lib.erl
@@ -0,0 +1,329 @@
+%%
+%% %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(reltool_test_lib).
+-compile(export_all).
+
+-include("reltool_test_lib.hrl").
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+init_per_suite(Config) when is_list(Config)->
+ incr_timetrap(Config, 5).
+
+end_per_suite(Config) when is_list(Config)->
+ ok.
+
+incr_timetrap(Config, Times) ->
+ Key = tc_timeout,
+ KeyPos = 1,
+ NewTime =
+ case lists:keysearch(Key, KeyPos, Config) of
+ {value, {Key, OldTime}} ->
+ (timer:minutes(1) + OldTime) * Times;
+ false ->
+ timer:minutes(1) * Times
+ end,
+ lists:keystore(Key, KeyPos, Config, {Key, NewTime}).
+
+set_kill_timer(Config) ->
+ case init:get_argument(reltool_test_timeout) of
+ {ok, _} ->
+ Config;
+ _ ->
+ Time =
+ case lookup_config(tc_timeout, Config) of
+ [] ->
+ timer:minutes(5);
+ ConfigTime when is_integer(ConfigTime) ->
+ ConfigTime
+ end,
+ WatchDog = test_server:timetrap(Time),
+ [{kill_timer, WatchDog} | Config]
+ end.
+
+reset_kill_timer(Config) ->
+ DogKiller =
+ case get(reltool_test_server) of
+ true ->
+ fun(P) when is_pid(P) -> P ! stop;
+ (_) -> ok
+ end;
+ _ ->
+ fun(Ref) -> test_server:timetrap_cancel(Ref) end
+ end,
+ case lists:keysearch(kill_timer, 1, Config) of
+ {value, {kill_timer, WatchDog}} ->
+ DogKiller(WatchDog),
+ lists:keydelete(kill_timer, 1, Config);
+ _ ->
+ Config
+ end.
+
+lookup_config(Key,Config) ->
+ case lists:keysearch(Key, 1, Config) of
+ {value,{Key,Val}} ->
+ Val;
+ _ ->
+ []
+ end.
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+wx_init_per_suite(Config) ->
+ {_Pid, Ref} =
+ spawn_monitor(fun() ->
+ %% Avoid test case crash if wx master process dies
+ process_flag(trap_exit, true),
+ try
+ case os:type() of
+ {unix,darwin} ->
+ exit({skipped, "Can not test on MacOSX"});
+ {unix, _} ->
+ io:format("DISPLAY ~s~n", [os:getenv("DISPLAY")]),
+ case proplists:get_value(xserver, Config, none) of
+ none -> ignore;
+ Server -> os:putenv("DISPLAY", Server)
+ end;
+ _ ->
+ ignore
+ end,
+ wx:new(),
+ wx:destroy()
+ catch
+ error:undef ->
+ exit({skipped, "No wx compiled for this platform"});
+ _:Reason ->
+ exit({skipped, lists:flatten(io_lib:format("Start wx failed: ~p", [Reason]))})
+ end,
+ exit(normal)
+ end),
+ receive
+ {'DOWN', Ref, _, _, normal} ->
+ init_per_suite(Config);
+ {'DOWN', Ref, _, _, {skipped, _} = Skipped} ->
+ Skipped;
+ {'DOWN', Ref, _, _, Reason} ->
+ exit({wx_init_per_suite, Reason})
+ after timer:minutes(1) ->
+ exit({wx_init_per_suite, timeout})
+ end.
+
+wx_end_per_suite(Config) ->
+ end_per_suite(Config).
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+init_per_testcase(_Func, Config) when is_list(Config) ->
+ set_kill_timer(Config),
+ global:register_name(reltool_global_logger, group_leader()),
+ Config.
+
+end_per_testcase(_Func, Config) when is_list(Config) ->
+ global:unregister_name(reltool_global_logger),
+ reset_kill_timer(Config),
+ Config.
+
+%% Backwards compatible with test_server
+tc_info(suite) -> [];
+tc_info(doc) -> "".
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+%% Use ?log(Format, Args) as wrapper
+log(Format, Args, LongFile, Line) ->
+ File = filename:basename(LongFile),
+ Format2 = lists:concat([File, "(", Line, ")", ": ", Format]),
+ log(Format2, Args).
+
+log(Format, Args) ->
+ case global:whereis_name(reltool_global_logger) of
+ undefined ->
+ io:format(user, Format, Args);
+ Pid ->
+ io:format(Pid, Format, Args)
+ end.
+
+verbose(Format, Args, File, Line) ->
+ Arg = reltool_test_verbose,
+ case get(Arg) of
+ false ->
+ ok;
+ true ->
+ log(Format, Args, File, Line);
+ undefined ->
+ case init:get_argument(Arg) of
+ {ok, List} when is_list(List) ->
+ case lists:last(List) of
+ ["true"] ->
+ put(Arg, true),
+ log(Format, Args, File, Line);
+ _ ->
+ put(Arg, false),
+ ok
+ end;
+ _ ->
+ put(Arg, false),
+ ok
+ end
+ end.
+
+error(Format, Args, File, Line) ->
+ global:send(reltool_global_logger, {failed, File, Line}),
+ Fail = {filename:basename(File),Line,Args},
+ case global:whereis_name(reltool_test_case_sup) of
+ undefined -> ignore;
+ Pid -> Pid ! Fail
+ %% global:send(reltool_test_case_sup, Fail),
+ end,
+ log("<ERROR>~n" ++ Format, Args, File, Line).
+
+
+pick_msg() ->
+ receive
+ Message -> Message
+ after 4000 -> timeout
+ end.
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%% Utility functions
+
+user_available(Config) ->
+ false /= proplists:get_value(user, Config, false).
+
+
+wx_destroy(Frame, Config) ->
+ case proplists:get_value(user, Config, false) of
+ false ->
+ timer:sleep(100),
+ ?m(ok, wxFrame:destroy(Frame)),
+ ?m(ok, wx:destroy());
+ true ->
+ timer:sleep(500),
+ ?m(ok, wxFrame:destroy(Frame)),
+ ?m(ok, wx:destroy());
+ step -> %% Wait for user to close window
+ ?m(ok, wxEvtHandler:connect(Frame, close_window, [{skip,true}])),
+ wait_for_close()
+ end.
+
+wait_for_close() ->
+ receive
+ #wx{event=#wxClose{}} ->
+ ?log("Got close~n",[]),
+ ?m(ok, wx:destroy());
+ #wx{obj=Obj, event=Event} ->
+ try
+ Name = wxTopLevelWindow:getTitle(Obj),
+ ?log("~p Event: ~p~n", [Name, Event])
+ catch _:_ ->
+ ?log("Event: ~p~n", [Event])
+ end,
+ wait_for_close();
+ Other ->
+ ?log("Unexpected: ~p~n", [Other]),
+ wait_for_close()
+ end.
+
+
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%% A small test server, which can be run standalone in a shell
+
+run_test(Test = {_,_},Config) ->
+ run_test([Test],Config);
+run_test([{Module, TC} | Rest], Config) ->
+ log("\n\n=== Eval test suite: ~w ===~n", [Module]),
+ case catch Module:init_per_suite(Config) of
+ {skipped, Reason} ->
+ log("Test suite skipped: ~s~n", [Reason]),
+ [{skipped, Reason}];
+ NewConfig when is_list(NewConfig) ->
+ Res =
+ if
+ TC =:= all ->
+ [do_run_test(Module, Test, NewConfig) || Test <- Module:all()];
+ is_list(TC) ->
+ [do_run_test(Module, Test, NewConfig) || Test <- TC];
+ true ->
+ [do_run_test(Module, TC, NewConfig)]
+ end,
+ Module:end_per_suite(NewConfig),
+ Res ++ run_test(Rest, NewConfig);
+ Error ->
+ ?error("Test suite skipped: ~w~n", [Error]),
+ [{skipped, Error}]
+ end;
+run_test([], _Config) ->
+ [].
+
+do_run_test(Module, all, Config) ->
+ All = [{Module, Test} || Test <- Module:all()],
+ run_test(All, Config);
+do_run_test(Module, TestCase, Config) ->
+ log("Eval test case: ~w~n", [{Module, TestCase}]),
+ Sec = timer:seconds(1) * 1000,
+ {T, Res} =
+ timer:tc(?MODULE, eval_test_case, [Module, TestCase, Config]),
+ log("Tested ~w in ~w sec~n", [TestCase, T div Sec]),
+ {T div Sec, Res}.
+
+eval_test_case(Mod, Fun, Config) ->
+ flush(),
+ global:register_name(reltool_test_case_sup, self()),
+ Flag = process_flag(trap_exit, true),
+ Pid = spawn_link(?MODULE, test_case_evaluator, [Mod, Fun, [Config]]),
+ R = wait_for_evaluator(Pid, Mod, Fun, Config),
+ global:unregister_name(reltool_test_case_sup),
+ process_flag(trap_exit, Flag),
+ R.
+
+test_case_evaluator(Mod, Fun, [Config]) ->
+ NewConfig = Mod:init_per_testcase(Fun, Config),
+ R = apply(Mod, Fun, [NewConfig]),
+ Mod:fin_per_testcase(Fun, NewConfig),
+ exit({test_case_ok, R}).
+
+wait_for_evaluator(Pid, Mod, Fun, Config) ->
+ receive
+ {'EXIT', Pid, {test_case_ok, _PidRes}} ->
+ Errors = flush(),
+ Res =
+ case Errors of
+ [] -> ok;
+ Errors -> failed
+ end,
+ {Res, {Mod, Fun}, Errors};
+ {'EXIT', Pid, {skipped, Reason}} ->
+ log("<WARNING> Test case ~w skipped, because ~p~n",
+ [{Mod, Fun}, Reason]),
+ Mod:fin_per_testcase(Fun, Config),
+ {skip, {Mod, Fun}, Reason};
+ {'EXIT', Pid, Reason} ->
+ log("<ERROR> Eval process ~w exited, because\n\t~p~n",
+ [{Mod, Fun}, Reason]),
+ Mod:fin_per_testcase(Fun, Config),
+ {crash, {Mod, Fun}, Reason}
+ end.
+
+flush() ->
+ receive Msg -> [Msg | flush()]
+ after 0 -> []
+ end.
+
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
diff --git a/lib/reltool/test/reltool_test_lib.hrl b/lib/reltool/test/reltool_test_lib.hrl
new file mode 100644
index 0000000000..93134144ea
--- /dev/null
+++ b/lib/reltool/test/reltool_test_lib.hrl
@@ -0,0 +1,91 @@
+%%
+%% %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%
+
+-include_lib("wx/include/wx.hrl").
+
+-define(log(Format,Args), reltool_test_lib:log(Format,Args,?FILE,?LINE)).
+-define(warning(Format,Args), ?log("<WARNING>\n " ++ Format,Args)).
+-define(error(Format,Args), reltool_test_lib:error(Format,Args,?FILE,?LINE)).
+-define(verbose(Format,Args), reltool_test_lib:verbose(Format,Args,?FILE,?LINE)).
+
+-define(fatal(Format,Args),
+ ?error(Format, Args),
+ exit({test_case_fatal, Format, Args, ?FILE, ?LINE})).
+
+-define(skip(Format,Args),
+ ?warning(Format, Args),
+ exit({skipped, ?flat_format(Format, Args)})).
+
+-define(ignore(Expr),
+ fun() ->
+ AcTuAlReS = (catch (Expr)),
+ ?verbose("ok: ~p\n",[AcTuAlReS]),
+ AcTuAlReS
+ end()).
+
+-define(msym(ExpectedRes, Expr),
+ fun() ->
+ AcTuAlReS = (catch (Expr)),
+ case AcTuAlReS of
+ ExpectedRes ->
+ ?verbose("ok: ~p\n",[AcTuAlReS]),
+ AcTuAlReS;
+ _ ->
+ reltool_test_lib:error("Not matching actual result was:\n ~p \nExpected ~s\n",
+ [AcTuAlReS, ??ExpectedRes],
+ ?FILE, ?LINE),
+ AcTuAlReS
+ end
+ end()).
+
+-define(m(ExpectedRes, Expr),
+ fun() ->
+ AcTuAlReS = (catch (Expr)),
+ case AcTuAlReS of
+ ExpectedRes ->
+ ?verbose("ok: ~p\n",[AcTuAlReS]),
+ AcTuAlReS;
+ _ ->
+ reltool_test_lib:error("Not matching actual result was:\n\t~p \nExpected:\n\t~p\n",
+ [AcTuAlReS, ExpectedRes],
+ ?FILE, ?LINE),
+ AcTuAlReS
+ end
+ end()).
+
+-define(m_receive(ExpectedMsg),
+ ?m(ExpectedMsg,reltool_test_lib:pick_msg())).
+
+-define(m_multi_receive(ExpectedMsgs),
+ fun() ->
+ TmPeXpCtEdMsGs = lists:sort(ExpectedMsgs),
+ AcTuAlReS =
+ lists:sort(lists:map(fun(_) ->
+ reltool_test_lib:pick_msg()
+ end, TmPeXpCtEdMsGs)),
+ case AcTuAlReS of
+ TmPeXpCtEdMsGs ->
+ ?verbose("ok: ~p\n",[AcTuAlReS]),
+ AcTuAlReS;
+ _ ->
+ reltool_test_lib:error("Not matching actual result was:\n ~p \nExpected ~p\n",
+ [AcTuAlReS, ExpectedMsgs],
+ ?FILE, ?LINE),
+ AcTuAlReS
+ end
+ end()).
diff --git a/lib/reltool/test/reltool_wx_SUITE.erl b/lib/reltool/test/reltool_wx_SUITE.erl
new file mode 100644
index 0000000000..2e2b355e07
--- /dev/null
+++ b/lib/reltool/test/reltool_wx_SUITE.erl
@@ -0,0 +1,62 @@
+%%
+%% %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(reltool_wx_SUITE).
+
+-export([all/0, init_per_suite/1, end_per_suite/1,
+ init_per_testcase/2, fin_per_testcase/2, end_per_testcase/2]).
+
+-compile(export_all).
+
+-include("reltool_test_lib.hrl").
+
+%% Initialization functions.
+init_per_suite(Config) ->
+ reltool_test_lib:wx_init_per_suite(Config).
+
+end_per_suite(Config) ->
+ reltool_test_lib:wx_end_per_suite(Config).
+
+init_per_testcase(Func,Config) ->
+ reltool_test_lib:init_per_testcase(Func,Config).
+end_per_testcase(Func,Config) ->
+ reltool_test_lib:end_per_testcase(Func,Config).
+fin_per_testcase(Func,Config) -> %% For test_server
+ reltool_test_lib:end_per_testcase(Func,Config).
+
+%% SUITE specification
+all() ->
+ all(suite).
+all(suite) ->
+ [
+ start_all_windows
+ ].
+
+%% The test cases
+
+%% Display all windows and see if something crashes
+start_all_windows(TestInfo) when is_atom(TestInfo) ->
+ reltool_test_lib:tc_info(TestInfo);
+start_all_windows(_Config) ->
+ {ok, SysPid} = ?msym({ok, _}, reltool:start([{trap_exit, false}])),
+ {ok, AppPid} = ?msym({ok, _}, reltool_sys_win:open_app(SysPid, stdlib)),
+ ?msym({ok, _}, reltool_app_win:open_mod(AppPid, escript)),
+ timer:sleep(timer:seconds(10)),
+ ?m(ok, reltool:stop(SysPid)),
+
+ ok.
diff --git a/lib/reltool/test/rtt b/lib/reltool/test/rtt
new file mode 100755
index 0000000000..2411195338
--- /dev/null
+++ b/lib/reltool/test/rtt
@@ -0,0 +1,55 @@
+#! /bin/sh -f
+# %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%
+
+# Usage: rtt [-cerl] <args to erlang startup script>
+
+emu=erl
+while [ $# -gt 0 ]; do
+ case "$1" in
+ "-cerl")
+ shift
+ emu=cerl
+ ;;
+ *)
+ break
+ ;;
+ esac
+done
+
+log=test_log_$$
+latest=test_log_latest
+args=${1+"$@"}
+
+erlcmd="$emu -sname test_server -smp -pa ../../reltool/ebin $p $args -reltool_test_verbose true -reltool_test_timeout"
+
+echo "Give the following command in order to see the outcome:"
+echo ""
+echo " less $log"
+
+rm "$latest" 2>/dev/null
+ln -s "$log" "$latest"
+touch "$log"
+
+ostype=`uname -s`
+if [ "$ostype" = "SunOS" ] ; then
+ /usr/openwin/bin/xterm -T "Testing reltool" -l -lf "$log" -e $erlcmd &
+else
+ xterm -T "Testing reltool" -e script -f -c "$erlcmd" "$log" &
+fi
+
+tail -f "$log" | egrep 'Eval|<ERROR>|NYI'
diff --git a/lib/reltool/test/rtt.erl b/lib/reltool/test/rtt.erl
new file mode 100644
index 0000000000..6755b8400f
--- /dev/null
+++ b/lib/reltool/test/rtt.erl
@@ -0,0 +1,154 @@
+%%
+%% %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(rtt).
+-compile(export_all).
+
+%% Modules or suites can be shortcuts, for example server expands to reltool_server_SUITE.
+%%
+%% t(Tests) run reltool testcases.
+%% Tests can be module, {module, test_case} or [module|{module,test_case}]
+
+t() ->
+ t(read_test_case()).
+t(Test) ->
+ t(Test, []).
+
+t(Mod, TC) when is_atom(Mod), is_atom(TC) ->
+ t({Mod,TC}, []);
+t(all, Config) when is_list(Config) ->
+ Fs = filelib:wildcard("reltool_*_SUITE.erl"),
+ t([list_to_atom(filename:rootname(File)) || File <- Fs], Config);
+t(Test,Config) when is_list(Config) ->
+ Tests = resolve(Test),
+ write_test_case(Test),
+ Res = reltool_test_lib:run_test(Tests, Config),
+ append_test_case_info(Test, Res).
+
+user() ->
+ user(read_test_case()).
+user(Mod) ->
+ t(Mod, [{user,step}]).
+user(Mod,Tc) when is_atom(Tc) ->
+ t({Mod,Tc}, [{user,step}]).
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%% Resolves the name of test suites and test cases
+%% according to the alias definitions. Single atoms
+%% are assumed to be the name of a test suite.
+
+resolve(Suite0) when is_atom(Suite0) ->
+ case alias(Suite0) of
+ Suite when is_atom(Suite) ->
+ {Suite, all};
+ {Suite, Case} ->
+ {Suite, Case}
+ end;
+resolve({Suite0, Case}) when is_atom(Suite0), is_atom(Case) ->
+ case alias(Suite0) of
+ Suite when is_atom(Suite) ->
+ {Suite, Case};
+ {Suite, Case2} ->
+ {Suite, Case2}
+ end;
+resolve(List) when is_list(List) ->
+ [resolve(Case) || Case <- List].
+
+alias(Suite) when is_atom(Suite) ->
+ Str = atom_to_list(Suite),
+ case {Str, lists:reverse(Str)} of
+ {"reltool" ++ _, "ETIUS" ++ _} ->
+ Suite;
+ _ ->
+ list_to_atom("reltool_" ++ Str ++ "_SUITE")
+ end.
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+config_fname() ->
+ "reltool_test_case_config".
+
+%% Read default config file
+read_config() ->
+ Fname = config_fname(),
+ reltool_test_lib:log("Consulting file ~s...~n", [Fname]),
+ case file:consult(Fname) of
+ {ok, Config} ->
+ reltool_test_lib:log("Read config ~w~n", [Config]),
+ Config;
+ _Error ->
+ Config = reltool_test_lib:default_config(),
+ reltool_test_lib:log("<>WARNING<> Using default config: ~w~n", [Config]),
+ Config
+ end.
+
+%% Write new default config file
+write_config(Config) when is_list(Config) ->
+ Fname = config_fname(),
+ {ok, Fd} = file:open(Fname, write),
+ write_list(Fd, Config),
+ file:close(Fd).
+
+write_list(Fd, [H | T]) ->
+ ok = io:format(Fd, "~p.~n",[H]),
+ write_list(Fd, T);
+write_list(_, []) ->
+ ok.
+
+test_case_fname() ->
+ "reltool_test_case_info".
+
+%% Read name of test case
+read_test_case() ->
+ Fname = test_case_fname(),
+ case file:open(Fname, [read]) of
+ {ok, Fd} ->
+ Res = io:read(Fd, []),
+ file:close(Fd),
+ case Res of
+ {ok, TestCase} ->
+ reltool_test_lib:log("Using test case ~w from file ~s~n",
+ [TestCase, Fname]),
+ TestCase;
+ {error, _} ->
+ default_test_case(Fname)
+ end;
+ {error, _} ->
+ default_test_case(Fname)
+ end.
+
+default_test_case(Fname) ->
+ TestCase = all,
+ reltool_test_lib:log("<>WARNING<> Cannot read file ~s, "
+ "using default test case: ~w~n",
+ [Fname, TestCase]),
+ TestCase.
+
+write_test_case(TestCase) ->
+ Fname = test_case_fname(),
+ {ok, Fd} = file:open(Fname, write),
+ ok = io:format(Fd, "~p.~n",[TestCase]),
+ file:close(Fd).
+
+append_test_case_info(TestCase, TestCaseInfo) ->
+ Fname = test_case_fname(),
+ {ok, Fd} = file:open(Fname, [read, write]),
+ ok = io:format(Fd, "~p.~n",[TestCase]),
+ ok = io:format(Fd, "~p.~n",[TestCaseInfo]),
+ file:close(Fd),
+ TestCaseInfo.
diff --git a/lib/reltool/vsn.mk b/lib/reltool/vsn.mk
index d5ca40619c..118827a449 100644
--- a/lib/reltool/vsn.mk
+++ b/lib/reltool/vsn.mk
@@ -1,24 +1,7 @@
-# This is an -*-makefile-*- file.
-# %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%
+RELTOOL_VSN = 0.5.3
-RELTOOL_VSN = 0.5.2
-
-TICKETS = OTP-8254
+TICKETS = OTP-8057
+TICKETS_0_5_2 = OTP-8254
TICKETS_0_5_1 = OTP-8199
TICKETS_0_5 = OTP-7949
TICKETS_0_2_2 = OTP-7999
diff --git a/lib/runtime_tools/c_src/Makefile.in b/lib/runtime_tools/c_src/Makefile.in
index 05b5598e51..840de39f07 100644
--- a/lib/runtime_tools/c_src/Makefile.in
+++ b/lib/runtime_tools/c_src/Makefile.in
@@ -1,23 +1,24 @@
#
# %CopyrightBegin%
-#
-# Copyright Ericsson AB 1999-2009. All Rights Reserved.
-#
+#
+# Copyright Ericsson AB 1999-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%
#
include $(ERL_TOP)/make/target.mk
include $(ERL_TOP)/make/$(TARGET)/otp.mk
+include $(ERL_TOP)/make/$(TARGET)/otp_ded.mk
# ----------------------------------------------------
# Application version
@@ -30,20 +31,14 @@ VSN=$(RUNTIME_TOOLS_VSN)
# reasonable defaults, if something different is needed it should
# be set for that system only.
# ----------------------------------------------------
-CC = @CC@
-CFLAGS = @DED_CFLAGS@
-LD = @DED_LD@
+CC = $(DED_CC)
+CFLAGS = $(DED_CFLAGS)
+LD = $(DED_LD)
SHELL = /bin/sh
-LIBS = @LIBS@
-LDFLAGS += @DED_LDFLAGS@
-ERLANG_OSTYPE = @ERLANG_OSTYPE@
-
-SYSINCLUDE = -I$(ERL_TOP)/erts/emulator/beam \
- -I$(ERL_TOP)/erts/emulator/sys/$(ERLANG_OSTYPE) \
- -I$(ERL_TOP)/erts/include/internal \
- -I$(ERL_TOP)/erts/include/internal/$(ERLANG_OSTYPE) \
- -I$(ERL_TOP)/erts/include \
- -I$(ERL_TOP)/erts/include/$(ERLANG_OSTYPE)
+LIBS = $(DED_LIBS)
+LDFLAGS += $(DED_LDFLAGS)
+
+SYSINCLUDE = $(DED_SYS_INCLUDE)
ifeq ($(findstring vxworks,$(TARGET)),vxworks)
SYSINCLUDE += -I$(ERL_TOP)/erts/etc/vxworks
endif
diff --git a/lib/runtime_tools/doc/src/notes.xml b/lib/runtime_tools/doc/src/notes.xml
index 3262e4819b..9eb13727c7 100644
--- a/lib/runtime_tools/doc/src/notes.xml
+++ b/lib/runtime_tools/doc/src/notes.xml
@@ -4,7 +4,7 @@
<chapter>
<header>
<copyright>
- <year>2004</year><year>2009</year>
+ <year>2004</year><year>2010</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
@@ -13,12 +13,12 @@
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>Runtime_Tools Release Notes</title>
@@ -31,6 +31,76 @@
<p>This document describes the changes made to the Runtime_Tools
application.</p>
+<section><title>Runtime_Tools 1.8.3</title>
+
+ <section><title>Improvements and New Features</title>
+ <list>
+ <item>
+ <p>Cross compilation improvements and other build system
+ improvements.</p>
+ <p>Most notable:</p> <list><item> Lots of cross
+ compilation improvements. The old cross compilation
+ support was more or less non-existing as well as broken.
+ Please, note that the cross compilation support should
+ still be considered as experimental. Also note that old
+ cross compilation configurations cannot be used without
+ modifications. For more information on cross compiling
+ Erlang/OTP see the <c>$ERL_TOP/INSTALL-CROSS.md</c> file.
+ </item><item> Support for staged install using <url
+ href="http://www.gnu.org/prep/standards/html_node/DESTDIR.html">DESTDIR</url>.
+ The old broken <c>INSTALL_PREFIX</c> has also been fixed.
+ For more information see the <c>$ERL_TOP/INSTALL.md</c>
+ file. </item><item> Documentation of the <c>release</c>
+ target of the top <c>Makefile</c>. For more information
+ see the <c>$ERL_TOP/INSTALL.md</c> file. </item><item>
+ <c>make install</c> now by default creates relative
+ symbolic links instead of absolute ones. For more
+ information see the <c>$ERL_TOP/INSTALL.md</c> file.
+ </item><item> <c>$ERL_TOP/configure --help=recursive</c>
+ now works and prints help for all applications with
+ <c>configure</c> scripts. </item><item> Doing <c>make
+ install</c>, or <c>make release</c> directly after
+ <c>make all</c> no longer triggers miscellaneous
+ rebuilds. </item><item> Existing bootstrap system is now
+ used when doing <c>make install</c>, or <c>make
+ release</c> without a preceding <c>make all</c>.
+ </item><item> The <c>crypto</c> and <c>ssl</c>
+ applications use the same runtime library path when
+ dynamically linking against <c>libssl.so</c> and
+ <c>libcrypto.so</c>. The runtime library search path has
+ also been extended. </item><item> The <c>configure</c>
+ scripts of <c>erl_interface</c> and <c>odbc</c> now
+ search for thread libraries and thread library quirks the
+ same way as <c>erts</c> do. </item><item> The
+ <c>configure</c> script of the <c>odbc</c> application
+ now also looks for odbc libraries in <c>lib64</c> and
+ <c>lib/64</c> directories when building on a 64-bit
+ system. </item><item> The <c>config.h.in</c> file in the
+ <c>erl_interface</c> application is now automatically
+ generated in instead of statically updated which reduces
+ the risk of <c>configure</c> tests without any effect.
+ </item></list>
+ <p>(Thanks to Henrik Riomar for suggestions and
+ testing)</p>
+ <p>(Thanks to Winston Smith for the AVR32-Linux cross
+ configuration and testing)</p>
+ <p>
+ *** POTENTIAL INCOMPATIBILITY ***</p>
+ <p>
+ Own Id: OTP-8323</p>
+ </item>
+ <item>
+ <p>
+ Cleanups suggested by tidier and modernization of types
+ and specs.</p>
+ <p>
+ Own Id: OTP-8455</p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
<section><title>Runtime_Tools 1.8.2</title>
<section><title>Improvements and New Features</title>
diff --git a/lib/runtime_tools/src/percept_profile.erl b/lib/runtime_tools/src/percept_profile.erl
index b333dee0cf..cdc7a0fca1 100644
--- a/lib/runtime_tools/src/percept_profile.erl
+++ b/lib/runtime_tools/src/percept_profile.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%
%%
@@ -41,7 +41,7 @@
%% @type percept_option() = procs | ports | exclusive
--type(percept_option() :: 'procs' | 'ports' | 'exclusive' | 'scheduler').
+-type percept_option() :: 'procs' | 'ports' | 'exclusive' | 'scheduler'.
%%==========================================================================
%%
@@ -52,8 +52,8 @@
%% @spec start(Filename::string()) -> {ok, Port} | {already_started, Port}
%% @equiv start(Filename, [procs])
--spec(start/1 :: (Filename :: string()) ->
- {'ok', port()} | {'already_started', port()}).
+-spec start(Filename :: file:filename()) ->
+ {'ok', port()} | {'already_started', port()}.
start(Filename) ->
profile_to_file(Filename, [procs]).
@@ -64,10 +64,9 @@ start(Filename) ->
%% All events are stored in the file given by Filename.
%% An explicit call to stop/0 is needed to stop profiling.
--spec(start/2 :: (
- Filename :: string(),
- Options :: [percept_option()]) ->
- {'ok', port()} | {'already_started', port()}).
+-spec start(Filename :: file:filename(),
+ Options :: [percept_option()]) ->
+ {'ok', port()} | {'already_started', port()}.
start(Filename, Options) ->
profile_to_file(Filename, Options).
@@ -79,11 +78,10 @@ start(Filename, Options) ->
%% No explicit call to stop/0 is needed, the profiling stops when
%% the entry function returns.
--spec(start/3 :: (
- Filename :: string(),
- Entry :: {atom(), atom(), list()},
- Options :: [percept_option()]) ->
- 'ok' | {'already_started', port()} | {'error', 'not_started'}).
+-spec start(Filename :: file:filename(),
+ Entry :: {atom(), atom(), list()},
+ Options :: [percept_option()]) ->
+ 'ok' | {'already_started', port()} | {'error', 'not_started'}.
start(Filename, {Module, Function, Args}, Options) ->
case whereis(percept_port) of
@@ -107,11 +105,11 @@ deliver_all_trace() ->
receive {Tracer, ok} -> ok end,
erlang:trace(Tracee, false, [procs]),
ok.
--spec(stop/0 :: () -> 'ok' | {'error', 'not_started'}).
%% @spec stop() -> ok | {'error', 'not_started'}
%% @doc Stops profiling.
+-spec stop() -> 'ok' | {'error', 'not_started'}.
stop() ->
erlang:system_profile(undefined, [runnable_ports, runnable_procs]),
@@ -192,5 +190,4 @@ parse_profile_options([Opt|Opts], {TOpts, POpts}) ->
});
_ ->
parse_profile_options(Opts, {TOpts, POpts})
-
end.
diff --git a/lib/runtime_tools/test/Makefile b/lib/runtime_tools/test/Makefile
new file mode 100644
index 0000000000..873d395277
--- /dev/null
+++ b/lib/runtime_tools/test/Makefile
@@ -0,0 +1,65 @@
+#
+include $(ERL_TOP)/make/target.mk
+include $(ERL_TOP)/make/$(TARGET)/otp.mk
+
+MODULES = \
+ runtime_tools_SUITE \
+ inviso_testmodule1_foo \
+ inviso_SUITE \
+ dbg_SUITE \
+ erts_alloc_config_SUITE
+
+ERL_FILES= $(MODULES:%=%.erl)
+
+TARGET_FILES= $(MODULES:%=$(EBIN)/%.$(EMULATOR))
+INSTALL_PROGS= $(TARGET_FILES)
+
+EMAKEFILE=Emakefile
+
+# ----------------------------------------------------
+# Release directory specification
+# ----------------------------------------------------
+RELSYSDIR = $(RELEASE_PATH)/runtime_tools_test
+
+# ----------------------------------------------------
+# FLAGS
+# ----------------------------------------------------
+
+ERL_MAKE_FLAGS +=
+ERL_COMPILE_FLAGS += -I$(ERL_TOP)/lib/test_server/include
+
+EBIN = .
+
+# ----------------------------------------------------
+# Targets
+# ----------------------------------------------------
+
+make_emakefile:
+ $(ERL_TOP)/make/make_emakefile $(ERL_COMPILE_FLAGS) -o$(EBIN) $(MODULES)\
+ > $(EMAKEFILE)
+
+tests debug opt: make_emakefile
+ erl $(ERL_MAKE_FLAGS) -make
+
+clean:
+ rm -f $(EMAKEFILE)
+ rm -f $(TARGET_FILES)
+ rm -f core
+
+docs:
+
+# ----------------------------------------------------
+# Release Target
+# ----------------------------------------------------
+include $(ERL_TOP)/make/otp_release_targets.mk
+
+release_spec: opt
+
+release_tests_spec: make_emakefile
+ $(INSTALL_DIR) $(RELSYSDIR)
+ $(INSTALL_DATA) runtime_tools.spec $(ERL_FILES) $(RELSYSDIR)
+ $(INSTALL_DATA) $(EMAKEFILE) runtime_tools.cover $(RELSYSDIR)
+ chmod -f -R u+w $(RELSYSDIR)
+ @tar cf - *_SUITE_data | (cd $(RELSYSDIR); tar xf -)
+
+release_docs_spec:
diff --git a/lib/runtime_tools/test/dbg_SUITE.erl b/lib/runtime_tools/test/dbg_SUITE.erl
new file mode 100644
index 0000000000..ff96af5e86
--- /dev/null
+++ b/lib/runtime_tools/test/dbg_SUITE.erl
@@ -0,0 +1,901 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 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_SUITE).
+
+%% Test functions
+-export([all/1, big/1, tiny/1, simple/1, message/1, distributed/1,
+ ip_port/1, file_port/1, file_port2/1, file_port_schedfix/1,
+ ip_port_busy/1, wrap_port/1, wrap_port_time/1,
+ with_seq_trace/1, dead_suspend/1, local_trace/1,
+ saved_patterns/1]).
+-export([init_per_testcase/2, fin_per_testcase/2]).
+-export([tracee1/1, tracee2/1]).
+-export([dummy/0, exported/1]).
+
+-include("test_server.hrl").
+-define(default_timeout, ?t:minutes(1)).
+
+init_per_testcase(_Case, Config) ->
+ ?line Dog=test_server:timetrap(?default_timeout),
+ [{watchdog, Dog}|Config].
+fin_per_testcase(_Case, Config) ->
+ Dog=?config(watchdog, Config),
+ test_server:timetrap_cancel(Dog),
+ ok.
+
+all(suite) -> [big, tiny, simple, message, distributed,
+ ip_port, file_port, file_port2, file_port_schedfix,
+ ip_port_busy, wrap_port, wrap_port_time,
+ with_seq_trace, dead_suspend, local_trace, saved_patterns].
+
+big(suite) -> [];
+big(doc) -> ["Rudimentary interface test"];
+big(Config) when is_list(Config) ->
+ ?line {ok,OldCurDir} = file:get_cwd(),
+ Datadir=?config(data_dir, Config),
+ Privdir=?config(priv_dir, Config),
+ ?line ok=file:set_cwd(Privdir),
+ try
+ %% make sure dbg is stopped (and returns correctly)
+ ?line ok = dbg:stop(),
+
+ %% compile test module and make sure it is loaded.
+ ?line {ok,Mod} = compile:file(Datadir++"/dbg_test",[trace]),
+ ?line code:purge(dbg_test),
+ ?line {module, Mod}=code:load_file(dbg_test),
+
+ %% run/debug a named test function.
+ ?line Pid = spawn_link(dbg_test, loop, [Config]),
+ ?line true = register(dbg_test_loop, Pid),
+ ?line {ok,_} = dbg:tracer(),
+ ?line {ok,[{matched, _node, 1}]} = dbg:p(dbg_test_loop, [m,p,c]),
+ ?line ok = dbg:c(dbg_test, test, [Config]),
+ ?line ok = dbg:i(),
+ ?line dbg_test_loop ! {dbg_test, stop},
+ unregister(dbg_test_loop),
+ ?line ok = dbg:stop(),
+
+ %% run/debug a Pid.
+ ?line Pid2=spawn_link(dbg_test,loop,[Config]),
+ ?line {ok,_} = dbg:tracer(),
+ ?line {ok,[{matched, _node, 1}]} = dbg:p(Pid2,[s,r,p]),
+ ?line ok = dbg:c(dbg_test, test, [Config]),
+ ?line ok = dbg:i(),
+ ?line Pid2 ! {dbg_test, stop},
+
+ ?line ok=file:set_cwd(OldCurDir)
+ after
+ ?line dbg:stop()
+ end,
+ ok.
+
+
+tiny(suite) -> [];
+tiny(doc) -> ["Rudimentary interface test"];
+tiny(Config) when is_list(Config) ->
+ ?line {ok,OldCurDir} = file:get_cwd(),
+ Datadir=?config(data_dir, Config),
+ Privdir=?config(priv_dir, Config),
+ ?line ok=file:set_cwd(Privdir),
+ try
+ %% compile test module and make sure it is loaded.
+ ?line {ok, Mod} = compile:file(Datadir++"/dbg_test",[trace]),
+ ?line code:purge(dbg_test),
+ ?line {module, Mod}=code:load_file(dbg_test),
+
+ ?line Pid=spawn_link(dbg_test,loop,[Config]),
+ if
+ is_pid(Pid) ->
+ ?line dbg:tracer(),
+ ?line {ok,[{matched, _node, 1}]} = dbg:p(Pid,[s,r,m,p,c]),
+ ?line ok = dbg:c(dbg_test,test,[Config]),
+ ?line ok = dbg:i(),
+ ?line Pid ! {dbg_test, stop};
+ true ->
+ ?line ok=file:set_cwd(OldCurDir),
+ ?t:fail("Could not spawn external test process.~n"),
+ failure
+ end
+ after
+ ?line ok = dbg:stop(),
+ ?line ok = file:set_cwd(OldCurDir)
+ end,
+ ok.
+
+simple(suite) ->
+ [];
+simple(doc) ->
+ ["Simple interface test with own handler"];
+simple(Config) when is_list(Config) ->
+ try
+ ?line start(),
+ ?line dbg:p(self(),call),
+ ?line dbg:tp(dbg,ltp,[]),
+ ?line dbg:ltp(),
+ ?line stop(),
+ ?line S = self(),
+ ?line [{trace,S,call,{dbg,ltp,[]}}] = flush()
+ after
+ ?line dbg:stop()
+ end,
+ ok.
+
+message(suite) ->
+ [];
+message(doc) ->
+ ["Simple interface test with pam code that appends a message"];
+message(Config) when is_list(Config) ->
+ ?line {ok, _} = start(),
+ try
+ ?line {ok, [{matched, _node, 1}]} = dbg:p(self(),call),
+ ?line {ok, X} = dbg:tp(dbg,ltp,[{'_',[],[{message, {self}}]}]),
+ ?line {value, {saved, Saved}} = lists:keysearch(saved, 1, X),
+ ?line {ok, Y} = dbg:tp(dbg,ln,Saved),
+ ?line {value, {saved, Saved}} = lists:keysearch(saved, 1, Y),
+ ?line ok = dbg:ltp(),
+ ?line ok = dbg:ln()
+ after
+ ?line stop()
+ end,
+ ?line S = self(),
+ ?line [{trace,S,call,{dbg,ltp,[]},S},
+ {trace,S,call,{dbg,ln,[]},S}] = flush(),
+ ok.
+
+distributed(suite) ->
+ [];
+distributed(doc) ->
+ ["Simple test of distributed tracing"];
+distributed(Config) when is_list(Config) ->
+ ?line {ok, _} = start(),
+ ?line Node = start_slave(),
+ try
+ ?line RexPid = rpc:call(Node, erlang, whereis, [rex]),
+ ?line RexPidList = pid_to_list(RexPid),
+ ?line {ok, Node} = dbg:n(Node),
+ ?line {ok, X} = dbg:p(all,call),
+ ?line {value, {matched, Node, _}} = lists:keysearch(Node, 2, X),
+ ?line {ok, Y} = dbg:p(RexPidList, s),
+ ?line {value, {matched, Node, 1}} = lists:keysearch(Node, 2, Y),
+ ?line {ok, Z} = dbg:tp(dbg,ltp,[]),
+ ?line {value, {matched, Node, 1}} = lists:keysearch(Node, 2, Z),
+ ?line dbg:cn(Node),
+ ?line dbg:tp(dbg,ln,[]),
+ ?line ok = rpc:call(Node, dbg, ltp, []),
+ ?line ok = rpc:call(Node, dbg, ln, []),
+ ?line ok = dbg:ln(),
+ ?line S = self(),
+ ?line {TraceSend, TraceCall} =
+ lists:partition(fun ({trace,RP,send,_,_}) when RP =:= RexPid -> true;
+ (_) -> false end,
+ flush()),
+ ?line [_|_] = TraceSend,
+ ?line [{trace,Pid,call,{dbg,ltp,[]}},
+ {trace,S,call,{dbg,ln,[]}}] = TraceCall,
+ ?line Node = node(Pid),
+ %%
+ ?line stop()
+ after
+ ?line stop_slave(Node),
+ ?line stop()
+ end,
+ ok.
+
+
+local_trace(suite) ->
+ [];
+local_trace(doc) ->
+ ["Tests tracing of local function calls."];
+local_trace(Config) when is_list(Config) ->
+ ?line {ok, _} = start(),
+ try
+ ?line S = self(),
+ ?line %% Split "<X.Y.Z>" into {X, Y, Z}
+ ?line "<"++L1 = L = pid_to_list(S),
+ ?line NoDot = fun ($.) -> false; (_) -> true end,
+ ?line {LX,"."++L2} = lists:splitwith(NoDot, L1),
+ ?line {LY,"."++L3} = lists:splitwith(NoDot, L2),
+ ?line ">"++L4 = lists:reverse(L3),
+ ?line LZ = lists:reverse(L4),
+ ?line X = 0 = list_to_integer(LX),
+ ?line Y = list_to_integer(LY),
+ ?line Z = list_to_integer(LZ),
+ ?line XYZ = {X, Y, Z},
+ ?line io:format("Self = ~w = ~w~n", [S,XYZ]),
+ ?line {ok, [{matched, _node, 1}]} = dbg:p(S,call),
+ ?line {ok, [{matched, _node, 1}]} = dbg:p(XYZ,call),
+ if Z =:= 0 ->
+ ?line {ok, [{matched, _node, 1}]} = dbg:p(Y,call);
+ true -> ok
+ end,
+ ?line {ok, [{matched, _node, 1}]} = dbg:p(L,call),
+ ?line {ok, _} = dbg:tpl(?MODULE,not_exported,[]),
+ ?line 4 = not_exported(2),
+ ?line [{trace,S,call,{?MODULE,not_exported,[2]}}] = flush(),
+ ?line {ok, _} = dbg:tp(?MODULE,exported,[]),
+ ?line 4 = ?MODULE:exported(2),
+ ?line [{trace,S,call,{?MODULE,exported,[2]}},
+ {trace,S,call,{?MODULE,not_exported,[2]}}] = flush(),
+ ?line {ok, _} = dbg:ctpl(?MODULE),
+ ?line 4 = ?MODULE:exported(2),
+ ?line [{trace,S,call,{?MODULE,exported,[2]}}] = flush(),
+ ?line {ok, _} = dbg:tpl(?MODULE,not_exported,[]),
+ ?line {ok, _} = dbg:ctp(?MODULE),
+ ?line 4 = ?MODULE:exported(2),
+ ?line [] = flush(),
+ ?line {ok, _} = dbg:tpl(?MODULE,not_exported,x),
+ ?line catch ?MODULE:exported(x),
+ ?line [{trace,S,call,{dbg_SUITE,not_exported,[x]}},
+ {trace,S,exception_from,
+ {dbg_SUITE,not_exported,1},
+ {error,badarith}}] = flush()
+ after
+ ?line stop()
+ end,
+ ok.
+
+saved_patterns(suite) ->
+ [];
+saved_patterns(doc) ->
+ ["Tests saving of match_spec's."];
+saved_patterns(Config) when is_list(Config) ->
+ ?line dbg:stop(),
+ ?line {ok,[{saved,1}]} =
+ dbg:tp(dbg,ctp,1,[{'_',[],[{message, blahonga}]}]),
+ ?line {ok,[{saved,2}]} =
+ dbg:tp(dbg,ctp,1,[{['_'],[],[{message, blahonga}]}]),
+ ?line Privdir=?config(priv_dir, Config),
+ ?line file:make_dir(Privdir),
+ ?line File = filename:join([Privdir, "blahonga.ms"]),
+ ?line dbg:wtp(File),
+ ?line dbg:stop(),
+ ?line dbg:ctp('_','_','_'),
+ ?line {ok, _} = start(),
+ try
+ ?line dbg:rtp(File),
+ ?line {ok,[{matched,_node,1},{saved,1}]} = dbg:tp(dbg,ltp,0,1),
+ ?line {ok, [{matched, _node, 1}]} = dbg:p(self(),call),
+ ?line dbg:ltp(),
+ ?line S = self(),
+ ?line [{trace,S,call,{dbg,ltp,[]},blahonga}] = flush()
+ after
+ ?line stop()
+ end,
+ ok.
+
+
+
+not_exported(N) ->
+ N * 2.
+
+exported(N) ->
+ not_exported(N).
+
+ip_port(suite) ->
+ [];
+ip_port(doc) ->
+ ["Test tracing to IP port"];
+ip_port(Config) when is_list(Config) ->
+ ?line stop(),
+ ?line Port = dbg:trace_port(ip, 0),
+ ?line {ok, _} = dbg:tracer(port, Port),
+ try
+ ?line {ok, [{matched, _node, 1}]} = dbg:p(self(),call),
+ ?line {ok, X} = dbg:tp(dbg, ltp,[{'_',[],[{message, {self}}]}]),
+ ?line {value, {saved, _Saved}} = lists:keysearch(saved, 1, X),
+ ?line {ok, Y} = dbg:tp(dbg, ln, [{'_',[],[{message, hej}]}]),
+ ?line {value, {saved, _}} = lists:keysearch(saved, 1, Y),
+ ?line ok = dbg:ltp(),
+ ?line ok = dbg:ln(),
+ ?line {ok, IpPort} = dbg:trace_port_control(get_listen_port),
+ ?line io:format("IpPort = ~p~n", [IpPort]),
+ ?line dbg:trace_client(ip, IpPort, {fun myhandler/2, self()}),
+ ?line S = self(),
+ ?line [{trace,S,call,{dbg,ltp,[]},S},
+ {trace,S,call,{dbg,ln,[]},hej}] = flush()
+ after
+ ?line stop()
+ end,
+ ok.
+
+
+
+ip_port_busy(suite) ->
+ [];
+ip_port_busy(doc) ->
+ ["Test that the dbg server does not hang if the tracer don't start ",
+ "(OTP-3592)"];
+ip_port_busy(Config) when is_list(Config) ->
+ ?line stop(),
+ ?line Tracer = dbg:trace_port(ip, 4745),
+ ?line Port = Tracer(),
+ ?line {error, Reason} = dbg:tracer(port, Tracer),
+ try
+ ?line io:format("Error reason = ~p~n", [Reason]),
+ ?line true = port_close(Port)
+ after
+ ?line dbg:stop()
+ end,
+ ?line ok.
+
+
+
+file_port(suite) ->
+ [];
+file_port(doc) ->
+ ["Test tracing to file port (simple)"];
+file_port(Config) when is_list(Config) ->
+ ?line stop(),
+ ?line {A,B,C} = erlang:now(),
+ ?line FTMP = atom_to_list(?MODULE) ++ integer_to_list(A) ++ "-" ++
+ integer_to_list(B) ++ "-" ++ integer_to_list(C),
+ ?line FName = filename:join([?config(data_dir, Config), FTMP]),
+ ?line Port = dbg:trace_port(file, FName),
+ ?line {ok, _} = dbg:tracer(port, Port),
+ try
+ ?line {ok, [{matched, _node, 1}]} = dbg:p(self(),call),
+ ?line {ok, X} = dbg:tp(dbg, ltp,[{'_',[],[{message, {self}}]}]),
+ ?line {value, {saved, _Saved}} = lists:keysearch(saved, 1, X),
+ ?line {ok, Y} = dbg:tp(dbg, ln, [{'_',[],[{message, hej}]}]),
+ ?line {value, {saved, _}} = lists:keysearch(saved, 1, Y),
+ ?line ok = dbg:ltp(),
+ ?line ok = dbg:ln(),
+ ?line stop(),
+ ?line dbg:trace_client(file, FName, {fun myhandler/2, self()}),
+ ?line S = self(),
+ ?line [{trace,S,call,{dbg,ltp,[]},S},
+ {trace,S,call,{dbg,ln,[]},hej},
+ end_of_trace] = flush()
+ after
+ ?line stop(),
+ ?line file:delete(FName)
+ end,
+ ok.
+
+file_port2(suite) ->
+ [];
+file_port2(doc) ->
+ ["Test tracing to file port with 'follow_file'"];
+file_port2(Config) when is_list(Config) ->
+ case os:type() of
+ vxworks ->
+ {skipped, "VxWorks NFS cache ruins it all."};
+ _ ->
+ ?line stop(),
+ ?line {A,B,C} = erlang:now(),
+ ?line FTMP = atom_to_list(?MODULE) ++ integer_to_list(A) ++
+ "-" ++ integer_to_list(B) ++ "-" ++ integer_to_list(C),
+ ?line FName = filename:join([?config(data_dir, Config), FTMP]),
+ %% Ok, lets try with flush and follow_file, not a chance on VxWorks
+ %% with NFS caching...
+ ?line Port2 = dbg:trace_port(file, FName),
+ ?line {ok, _} = dbg:tracer(port, Port2),
+ try
+ ?line {ok, [{matched, _node, 1}]} = dbg:p(self(),call),
+ ?line {ok, _} = dbg:tp(dbg, ltp,[{'_',[],[{message, {self}}]}]),
+ ?line {ok, _} = dbg:tp(dbg, ln, [{'_',[],[{message, hej}]}]),
+ ?line ok = dbg:ltp(),
+ ?line ok = dbg:flush_trace_port(),
+ ?line dbg:trace_client(follow_file, FName,
+ {fun myhandler/2, self()}),
+ ?line S = self(),
+ ?line [{trace,S,call,{dbg,ltp,[]},S}] = flush(),
+ ?line ok = dbg:ln(),
+ ?line ok = dbg:flush_trace_port(),
+ ?line receive after 1000 -> ok end, %% Polls every second...
+ ?line [{trace,S,call,{dbg,ln,[]},hej}] = flush(),
+ ?line stop(),
+ ?line [] = flush()
+ after
+ ?line stop(),
+ ?line file:delete(FName)
+ end,
+ ok
+ end.
+
+file_port_schedfix(suite) ->
+ [];
+file_port_schedfix(doc) ->
+ ["Test that the scheduling timestamp fix for trace flag 'running' works."];
+file_port_schedfix(Config) when is_list(Config) ->
+ ?line case (catch erlang:system_info(smp_support)) of
+ true ->
+ {skip, "No schedule fix on SMP"};
+ _ ->
+ try
+ file_port_schedfix1(Config)
+ after
+ dbg:stop()
+ end
+ end.
+file_port_schedfix1(Config) when is_list(Config) ->
+ ?line stop(),
+ ?line {A,B,C} = erlang:now(),
+ ?line FTMP = atom_to_list(?MODULE) ++ integer_to_list(A) ++
+ "-" ++ integer_to_list(B) ++ "-" ++ integer_to_list(C),
+ ?line FName = filename:join([?config(data_dir, Config), FTMP]),
+ %%
+ ?line Port = dbg:trace_port(file, {FName, wrap, ".wraplog", 8*1024, 4}),
+ ?line {ok, _} = dbg:tracer(port, Port),
+ ?line {ok,[{matched,_node,0}]} = dbg:p(new,[running,procs,send,timestamp]),
+ %%
+ %% Generate the trace data
+ %%
+ %% This starts 3 processes that sends a message to each other in a ring,
+ %% 4 laps. Prior to sending the message to the next in the ring, each
+ %% process send 8 messages to itself, just to generate some trace data,
+ %% and to lower the possibility that the trace log wraps just after
+ %% a schedule out message (which would not burden any process and hence
+ %% not show up in the result)
+ %%
+ %% The wrap file trace is used because it burns a lot of time when the
+ %% driver swaps files, a lot more than the regular file trace. The test
+ %% case is dimensioned so that the log fills two files and just starts
+ %% on the third (out of four wrap files). This gives two file swaps,
+ %% and there are three processes, so one process will NOT be burdened.
+ %% The criterion for trace success is then that the max process
+ %% execution time must not be more than twice the min process
+ %% execution time. Wallclock. A normal result is about 10 times more
+ %% without schedule in - schedule out compensation (OTP-3938).
+ %%
+ ?line ok = token_volleyball(3, 4, 8),
+ %%
+ ?line {ok,[{matched,_,_}]} = dbg:p(all, [clear]),
+ ?line stop(),
+ % Some debug code to run on all platforms, for finding the fault on genny
+ % Dont touch please /PaN
+ ?line io:format("Trace dump by PaN BEGIN~n"),
+ ?line dbg:trace_client(file,{FName, wrap, ".wraplog"},{fun(end_of_trace,Pid)-> Pid ! done; (Mesg,Pid) -> io:format("~w~n",[Mesg]),Pid end,self()}),
+ receive done -> ok end,
+ ?line io:format("Trace dump by PaN END~n"),
+ %%
+ %% Get the trace result
+ %%
+ ?line Tag = make_ref(),
+ ?line dbg:trace_client(file, {FName, wrap, ".wraplog"},
+ {fun schedstat_handler/2, {self(), Tag, []}}),
+ ?line Result =
+ receive
+ {Tag, D} ->
+ lists:map(
+ fun({Pid, {A1, B1, C1}}) ->
+ {Pid, C1/1000000 + B1 + A1*1000000}
+ end,
+ D)
+ end,
+ ?line ok = io:format("Result=~p", [Result]),
+% erlang:display({?MODULE, ?LINE, Result}),
+ %%
+ %% Analyze the result
+ %%
+ ?line {Min, Max} =
+ lists:foldl(
+ fun({_Pid, M}, {Mi, Ma}) ->
+ {if M < Mi -> M; true -> Mi end,
+ if M > Ma -> M; true -> Ma end}
+ end,
+ {void, 0},
+ Result),
+ % More PaN debug
+ ?line io:format("Min = ~f, Max = ~f~n",[Min,Max]),
+ %%
+ %% Cleanup
+ %%
+ ?line ToBeDeleted = filelib:wildcard(FName++"*"++".wraplog"),
+ ?line lists:map({file, delete}, ToBeDeleted),
+% io:format("ToBeDeleted=~p", [ToBeDeleted]),
+ %%
+ %% Present the result
+ %%
+ P = (Max / Min - 1) * 100,
+ BottomLine = lists:flatten(io_lib:format("~.2f %", [P])),
+ if P > 100 ->
+ Reason = {BottomLine, '>', "100%"},
+ erlang:display({file_port_schedfix, fail, Reason}),
+ test_server:fail(Reason);
+ true ->
+ {comment, BottomLine}
+ end.
+
+wrap_port(suite) ->
+ [];
+wrap_port(doc) ->
+ ["Test tracing to wrapping file port"];
+wrap_port(Config) when is_list(Config) ->
+ ?line Self = self(),
+ ?line stop(),
+ ?line {A,B,C} = erlang:now(),
+ ?line FTMP = atom_to_list(?MODULE) ++ integer_to_list(A) ++ "-" ++
+ integer_to_list(B) ++ "-" ++ integer_to_list(C) ++ "-",
+ ?line FName = filename:join([?config(data_dir, Config), FTMP]),
+ ?line FNameWildcard = FName++"*"++".trace",
+ %% WrapSize=0 and WrapCnt=11 will force the trace to wrap after
+ %% every trace message, and to contain only the last 10 entries
+ %% after trace stop since the last file will be empty waiting
+ %% for its first trace message.
+ ?line WrapSize = 0,
+ ?line WrapCnt = 11,
+ ?line WrapFilesSpec = {FName, wrap, ".trace", WrapSize, WrapCnt},
+ ?line wrap_port_init(WrapFilesSpec),
+ %% The number of iterations, N, is tested to place wrap the log,
+ %% giving a gap in the filename sequence at index 3.
+ %% This should be a difficult case for
+ %% the trace_client file sorting functionality.
+ N = 7,
+ ?line lists:foreach(
+ fun(Cnt) ->
+ ?MODULE:tracee1(Cnt),
+ ?MODULE:tracee2(Cnt)
+ end,
+ lists:seq(1, N)),
+ ?line stop(),
+ try
+ ?line Files1 = filelib:wildcard(FNameWildcard),
+ ?line io:format("~p~n", [Files1]),
+ ?line Tc1 = dbg:trace_client(file, WrapFilesSpec,
+ {fun myhandler/2, {wait_for_go,Self}}),
+ ?line Tref1 = erlang:monitor(process, Tc1),
+ Tc1 ! {go,Self},
+ ?line [{'DOWN',Tref1,_,_,normal},
+ end_of_trace
+ |Result] = lists:reverse(flush()),
+ ?line M = N - (WrapCnt-1) div 2,
+ ?line M = wrap_port_result(Result, Self, N),
+ %%
+ %% Start a new wrap log with the same name to verify that
+ %% all files are cleared at wrap log start. Only produce
+ %% two trace messages to also place the gap at index 3,
+ %% so the trace log will be misinterpreted.
+ %%
+ ?line wrap_port_init(WrapFilesSpec),
+ ?line Files2 = filelib:wildcard(FNameWildcard),
+ ?line io:format("~p~n", [Files2]),
+ ?line -1 = ?MODULE:tracee1(-1),
+ ?line -1 = ?MODULE:tracee2(-1),
+ ?line stop(),
+ ?line Files = filelib:wildcard(FNameWildcard),
+ ?line io:format("~p~n", [Files]),
+ ?line Tc2 = dbg:trace_client(file, WrapFilesSpec,
+ {fun myhandler/2, {wait_for_go,Self}}),
+ ?line Tref2 = erlang:monitor(process, Tc2),
+ Tc2 ! {go,Self},
+ ?line [{trace,Self,call,{?MODULE,tracee1,[-1]},Self},
+ {trace,Self,call,{?MODULE,tracee2,[-1]},hej},
+ end_of_trace,
+ {'DOWN',Tref2,_,_,normal}] = flush(),
+ %%
+ ?line lists:map(fun(F) -> file:delete(F) end, Files)
+ after
+ ?line stop()
+ end,
+ ok.
+
+wrap_port_init(WrapFilesSpec) ->
+ ?line Port = dbg:trace_port(file, WrapFilesSpec),
+ ?line {ok, _} = dbg:tracer(port, Port),
+ ?line {ok, [{matched, _node, 1}]} = dbg:p(self(),call),
+ ?line {ok, X} = dbg:tp(?MODULE, tracee1,[{'_',[],[{message, {self}}]}]),
+ ?line {value, {saved, _Saved}} = lists:keysearch(saved, 1, X),
+ ?line {ok, Y} = dbg:tp(?MODULE, tracee2, [{'_',[],[{message, hej}]}]),
+ ?line {value, {saved, _}} = lists:keysearch(saved, 1, Y),
+ ok.
+
+tracee1(X) ->
+ X.
+
+tracee2(X) ->
+ X.
+
+wrap_port_result([], _S, M) ->
+ M;
+wrap_port_result([{trace, S, call, {?MODULE, tracee2, [M]}, hej},
+ {trace, S, call, {?MODULE, tracee1, [M]}, S} | Tail],
+ S,
+ M) ->
+ wrap_port_result(Tail, S, M-1).
+
+
+wrap_port_time(suite) ->
+ [];
+wrap_port_time(doc) ->
+ ["Test tracing to time limited wrapping file port"];
+wrap_port_time(Config) when is_list(Config) ->
+ ?line stop(),
+ ?line {A,B,C} = erlang:now(),
+ ?line FTMP = atom_to_list(?MODULE) ++ integer_to_list(A) ++ "-" ++
+ integer_to_list(B) ++ "-" ++ integer_to_list(C) ++ "-",
+ ?line FName = filename:join([?config(data_dir, Config), FTMP]),
+ %% WrapTime=2 and WrapCnt=4 will force the trace to wrap after
+ %% every 2 seconds, and to contain between 3*2 and 4*2 seconds
+ %% of trace entries.
+ ?line WrapFilesSpec = {FName, wrap, ".trace", {time, 2000}, 4},
+ ?line Port = dbg:trace_port(file, WrapFilesSpec),
+ ?line {ok, _} = dbg:tracer(port, Port),
+ try
+ ?line {ok, [{matched, _node, 1}]} = dbg:p(self(),call),
+ ?line {ok, X} = dbg:tp(?MODULE, tracee1,[{'_',[],[{message, {self}}]}]),
+ ?line {value, {saved, _Saved1}} = lists:keysearch(saved, 1, X),
+ ?line {ok, Y} = dbg:tp(?MODULE, tracee2, [{'_',[],[{message, hej}]}]),
+ ?line {value, {saved, _Saved2}} = lists:keysearch(saved, 1, Y),
+ %% The delays in the iterations places two trace messages in each
+ %% trace file, but the last which is empty waiting for its first
+ %% trace message. The number of iterations is chosen so that
+ %% one trace file has been wasted, and therefore the first pair
+ %% of trace messages.
+ ?line lists:foreach(
+ fun(Cnt) ->
+ receive after 1000 -> ok end,
+ ?MODULE:tracee1(Cnt),
+ ?MODULE:tracee2(Cnt),
+ receive after 1100 -> ok end
+ end,
+ lists:seq(1, 4)),
+ ?line stop(),
+ ?line Files = filelib:wildcard(FName ++ "*" ++ ".trace"),
+ ?line io:format("~p~n", [Files]),
+ ?line dbg:trace_client(file, WrapFilesSpec, {fun myhandler/2, self()}),
+ ?line S = self(),
+ ?line [{trace, S, call, {?MODULE, tracee1, [2]}, S},
+ {trace, S, call, {?MODULE, tracee2, [2]}, hej},
+ {trace, S, call, {?MODULE, tracee1, [3]}, S},
+ {trace, S, call, {?MODULE, tracee2, [3]}, hej},
+ {trace, S, call, {?MODULE, tracee1, [4]}, S},
+ {trace, S, call, {?MODULE, tracee2, [4]}, hej},
+ end_of_trace] = flush(),
+ ?line lists:map(fun(F) -> file:delete(F) end, Files)
+ after
+ ?line stop()
+ end,
+ ok.
+
+with_seq_trace(suite) ->
+ [];
+with_seq_trace(doc) ->
+ ["Test ordinary tracing combined with seq_trace"];
+with_seq_trace(Config) when is_list(Config) ->
+ try
+ ?line {ok, Server} = start(),
+ ?line {ok, Tracer} = dbg:get_tracer(),
+ ?line {ok, X} = dbg:tp(dbg, get_tracer, [{[],[],
+ [{set_seq_token, send, true}]}]),
+ ?line {value, {saved, _}} = lists:keysearch(saved, 1, X),
+ ?line {ok, [{matched, _node, 1}]} = dbg:p(self(),call),
+ ?line seq_trace:set_system_tracer(Tracer),
+ ?line dbg:get_tracer(),
+ receive
+ after 1 ->
+ ok
+ end,
+ ?line S = self(),
+ ?line ThisNode = node(),
+ ?line [{trace,S,call,{dbg,get_tracer,[]}},
+ {seq_trace,0,{send,_,S,Server,{S,{get_tracer,ThisNode}}}},
+ {seq_trace,0,{send,_,Server,S,{dbg,{ok,Tracer}}}}] =
+ flush()
+ after
+ ?line stop()
+ end,
+ ok.
+
+dead_suspend(suite) ->
+ [];
+dead_suspend(doc) ->
+ ["Test that trace messages concerning a now dead process does "
+ "not crash dbg."];
+
+dead_suspend(Config) when is_list(Config) ->
+ ?line start(),
+ try
+ survived = run_dead_suspend()
+ after
+ ?line stop()
+ end.
+
+run_dead_suspend() ->
+ dbg:p(new, call),
+ dbg:tp(?MODULE, dummy, []),
+ spawn(?MODULE, dummy, []),
+ spawn(?MODULE, dummy, []),
+ spawn(?MODULE, dummy, []),
+ spawn(?MODULE, dummy, []),
+ spawn(?MODULE, dummy, []),
+ receive after 1000 -> ok end,
+ case whereis(dbg) of
+ undefined ->
+ died;
+ _ ->
+ survived
+ end.
+
+dummy() ->
+ ok.
+
+
+%%
+%% Support functions
+%%
+
+start_slave() ->
+ {A, B, C} = now(),
+ Name = "asdkxlkmd" ++ integer_to_list(A+B+C),
+ {ok, Node} = test_server:start_node(Name,slave,[]),
+ ok = wait_node(Node, 15),
+ Node.
+
+stop_slave(Node) ->
+ test_server:stop_node(Node).
+
+wait_node(_,0) ->
+ no;
+wait_node(Node, N) ->
+ case net_adm:ping(Node) of
+ pong ->
+ ok;
+ pang ->
+ receive
+ after 1000 ->
+ ok
+ end,
+ wait_node(Node, N - 1)
+ end.
+
+myhandler(Message, {wait_for_go,Pid}) ->
+ receive
+ {go,Pid} ->
+ myhandler(Message, Pid)
+ end;
+myhandler(Message, Relay) ->
+ Relay ! Message,
+ case Message of
+ end_of_trace ->
+ ok;
+ _ ->
+ Relay
+ end.
+
+flush() ->
+ flush([]).
+flush(Acc) ->
+ receive
+ X ->
+ flush(Acc ++ [X])
+ after 1000 ->
+ Acc
+ end.
+
+start() ->
+ stop(),
+ dbg:tracer(process, {fun myhandler/2, self()}).
+
+stop() ->
+ dbg:stop().
+
+
+
+schedstat_handler(TraceMsg, {Parent, Tag, Data} = State) ->
+ case TraceMsg of
+ {trace_ts, Pid, in, _, Ts} ->
+ NewData =
+ case lists:keysearch(Pid, 1, Data) of
+ {value, {Pid, Acc}} ->
+ [{Pid, Acc, Ts} | lists:keydelete(Pid, 1, Data)];
+ false ->
+ [{Pid, {0, 0, 0}, Ts} | Data];
+ Other ->
+ exit(Parent, {?MODULE, ?LINE, Other}),
+ erlang:display({?MODULE, ?LINE, Other}),
+ Data
+ end,
+ {Parent, Tag, NewData};
+ {trace_ts, Pid, out, _, {A3, B3, C3}} ->
+ NewData =
+ case lists:keysearch(Pid, 1, Data) of
+ {value, {Pid, {A1, B1, C1}, {A2, B2, C2}}} ->
+ [{Pid, {A3-A2+A1, B3-B2+B1, C3-C2+C1}} |
+ lists:keydelete(Pid, 1, Data)];
+ Other ->
+ exit(Parent, {?MODULE, ?LINE, Other}),
+ erlang:display({?MODULE, ?LINE, Other}),
+ Data
+ end,
+ {Parent, Tag, NewData};
+ {trace_ts, Pid, exit, normal, {A3, B3, C3}} ->
+ NewData =
+ case lists:keysearch(Pid, 1, Data) of
+ {value, {Pid, {A1, B1, C1}, {A2, B2, C2}}} ->
+ [{Pid, {A3-A2+A1, B3-B2+B1, C3-C2+C1}} |
+ lists:keydelete(Pid, 1, Data)];
+ {value, {Pid, _Acc}} ->
+ Data;
+ false ->
+ [{Pid, {0, 0, 0}} | Data];
+ Other ->
+ exit(Parent, {?MODULE, ?LINE, Other}),
+ erlang:display({?MODULE, ?LINE, Other}),
+ Data
+ end,
+ {Parent, Tag, NewData};
+ {trace_ts, _Pid, send, _Msg, _OtherPid, _Ts} ->
+ State;
+ end_of_trace ->
+ Parent ! {Tag, Data},
+ State
+ end.
+
+
+
+pass_token(Token, Next, Loops) ->
+ receive
+ {Token, 1} = Msg ->
+ sendloop(Loops),
+ Next ! Msg;
+ {Token, _Cnt} = Msg->
+ sendloop(Loops),
+ Next ! Msg,
+ pass_token(Token, Next, Loops)
+ end.
+
+pass_token(Token, Final, Cnt, Loops) ->
+ receive
+ {Token, start, Next} ->
+ sendloop(Loops),
+ Msg = {Token, Cnt},
+ Next ! Msg,
+ pass_token(Token, Final, Next, Cnt, Loops)
+ end.
+
+pass_token(Token, Final, Next, Cnt, Loops) ->
+ receive
+ {Token, 1} ->
+ sendloop(Loops),
+ Msg = {Token, done},
+ Final ! Msg;
+ {Token, Cnt} ->
+ sendloop(Loops),
+ NextCnt = Cnt-1,
+ Msg = {Token, NextCnt},
+ Next ! Msg,
+ pass_token(Token, Final, Next, NextCnt, Loops)
+ end.
+
+sendloop(Loops) ->
+ sendloop(make_ref(), Loops).
+
+sendloop(_Tag, 0) ->
+ ok;
+sendloop(Tag, Loops) ->
+ self() ! {Tag, Loops},
+ receive {Tag, Loops} -> ok end,
+ sendloop(Tag, Loops-1).
+
+token_volleyball(N, Cnt, Loops)
+ when is_integer(N), N >= 1, is_integer(Cnt), Cnt >= 1,
+ is_integer(Loops), Loops >= 0 ->
+ Self = self(),
+ Token = make_ref(),
+ Last = spawn_link(fun() -> pass_token(Token, Self, Cnt, Loops) end),
+ First = token_volleyball(Token, Last, N-1, Loops),
+ Last ! {Token, start, First},
+ receive {Token, done} -> ok end.
+
+token_volleyball(Token, Next, 1, Loops) ->
+ spawn_link(fun() -> pass_token(Token, Next, Loops) end);
+token_volleyball(Token, Next, N, Loops) ->
+ Pid = spawn_link(fun() -> pass_token(Token, Next, Loops) end),
+ token_volleyball(Token, Pid, N-1, Loops).
diff --git a/lib/runtime_tools/test/dbg_SUITE_data/dbg_test.erl b/lib/runtime_tools/test/dbg_SUITE_data/dbg_test.erl
new file mode 100644
index 0000000000..2edbf6f99a
--- /dev/null
+++ b/lib/runtime_tools/test/dbg_SUITE_data/dbg_test.erl
@@ -0,0 +1,87 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 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%
+%%
+%%%----------------------------------------------------------------------
+%%% Purpose : A priority queue.
+%%%----------------------------------------------------------------------
+%%% This module implements a priority queue as defined in
+%%% "Priority Queues and the STL" by Mark Nelson in Dr.Dobb's Journal, Jan 1996
+%%% see http://web2.airmail.net/markn/articles/pq_stl/priority.htm for more
+%%% information. (A heap implementation is planned aswell)
+%%%----------------------------------------------------------------------
+%%% The items of the queue is kept priority sorted, and because of that,
+%%% a push() operation costs more than a pop() operation (wich only
+%%% needs to return the top item of the queue(read: list)).
+%%%----------------------------------------------------------------------
+%%% The priority queue can be deceptively nice to use when creating for
+%%% example a Huffman coding tree.
+%%% See http://web2.airmail.net/markn/articles/pq_stl/priority.htm or
+%%% Dr.Dobb's Journal Jan, 96 for more information on this.
+%%%----------------------------------------------------------------------
+
+%%% Used here strictly as something for dbg_SUITE to run.
+
+-module(dbg_test).
+-export([test/1, loop/1]).
+-export([new/0, push/3, pop/1]).
+
+loop(Config) ->
+ test(Config),
+ receive
+ {dbg_test, stop} ->
+ ok;
+ Other ->
+ loop(Config)
+ end,
+ ok.
+
+test(Config) ->
+ Q1=new(),
+ Q2=push(Q1, "monkey", 3),
+ Q3=push(Q2, "banana", 4),
+ Q4=push(Q3, "jungle", 2),
+ Q5=push(Q4, "world", 5),
+ Q6=push(Q5, "universe",6),
+ Q7=push(Q6, "peanut", 1),
+% io:format("~p~n",[Q7]),
+ {Itm, Q8}=pop(Q7),
+ ok.
+
+%% Returns a new priority queue.
+new() ->
+ [].
+
+%% Pushes a new item with a set priority into the queue.
+push(Queue, Itm, Pri) ->
+ insert(Queue, Itm, Pri, []).
+
+%% Pops the item with the highest priority out of the queue.
+pop([{Itm, Pri}|Queue]) ->
+ {Itm, Queue}.
+
+%% --- -- -
+%% Support functions.
+insert([], Itm, Pri, NewQ) ->
+ lists:flatten([lists:reverse(NewQ)|[{Itm, Pri}]]);
+% Itm>QItm>NewQ>Queue
+insert([{QItm,QPri}|Queue], Itm, Pri, NewQ) when Pri>QPri->
+ A = [{Itm, Pri}|[{QItm, QPri}]],
+ lists:flatten([[A|NewQ]|Queue]);
+insert([QItm|Rest], Itm, Pri, NewQ) ->
+ insert(Rest, Itm, Pri, [QItm|NewQ]).
+%% --- -- -
diff --git a/lib/runtime_tools/test/dbg_SUITE_data/exref_td.erl b/lib/runtime_tools/test/dbg_SUITE_data/exref_td.erl
new file mode 100644
index 0000000000..85faf620aa
--- /dev/null
+++ b/lib/runtime_tools/test/dbg_SUITE_data/exref_td.erl
@@ -0,0 +1,50 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 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(exref_td).
+
+-export([a/1,b/1,c/1,d/1,e/1,my_analyse/1]).
+
+a("edcba") ->
+ true;
+a(_) ->
+ lists:reverse("abcde").
+
+b(_) ->
+ a(nil).
+
+c(_) ->
+ nonexistentmodule:f().
+
+d(_) ->
+ lists:nonexistentfunction().
+
+e(_) ->
+ [a(x),b(x),c(x)].
+
+localfuncnotcalled() ->
+ true.
+
+localfunccalledbyf(A) ->
+ A.
+
+f() ->
+ lists:filter(fun localfunccalledbyf/1,"aaabba"),
+ F = fun localfuncnotcalled/0.
+
+my_analyse(Graph) -> ok.
diff --git a/lib/runtime_tools/test/erts_alloc_config_SUITE.erl b/lib/runtime_tools/test/erts_alloc_config_SUITE.erl
new file mode 100644
index 0000000000..32483dbe73
--- /dev/null
+++ b/lib/runtime_tools/test/erts_alloc_config_SUITE.erl
@@ -0,0 +1,206 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 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(erts_alloc_config_SUITE).
+
+%-define(line_trace, 1).
+
+-include("test_server.hrl").
+
+%-compile(export_all).
+-export([all/1, init_per_testcase/2, fin_per_testcase/2]).
+
+%% Testcases
+-export([basic/1]).
+
+%% internal export
+-export([make_basic_config/1]).
+
+-define(DEFAULT_TIMEOUT, ?t:minutes(2)).
+
+all(doc) -> [];
+all(suite) -> [basic].
+
+init_per_testcase(Case, Config) when is_list(Config) ->
+ [{testcase, Case},
+ {watchdog, ?t:timetrap(?DEFAULT_TIMEOUT)},
+ {erl_flags_env, save_env()} | Config].
+
+fin_per_testcase(_Case, Config) when is_list(Config) ->
+ ?t:timetrap_cancel(?config(watchdog, Config)),
+ restore_env(?config(erl_flags_env, Config)),
+ ok.
+
+%%%
+%%% The test cases ------------------------------------------------------------
+%%%
+
+basic(doc) -> [];
+basic(suite) -> [];
+basic(Config) when is_list(Config) ->
+ ?line ErtsAllocConfig = privfile("generated", Config),
+
+ SbctMod = " +MBsbct 1024 +MHsbct 4096",
+
+ %% Make sure we have enabled allocators
+ ZFlgs = case os:getenv("ERL_ZFLAGS") of
+ FlgString when is_list(FlgString) ->
+ FlgString;
+ _ ->
+ ""
+ end ++ " +Mea max +Mea config",
+
+ ?line os:putenv("ERL_ZFLAGS", ZFlgs ++ SbctMod),
+
+ ?line {ok, Node1} = start_node(Config),
+ ?line ok = rpc:call(Node1, ?MODULE, make_basic_config, [ErtsAllocConfig]),
+ ?line stop_node(Node1),
+
+ ?line display_file(ErtsAllocConfig),
+
+ ?line ManualConfig = privfile("manual", Config),
+ ?line {ok, IOD} = file:open(ManualConfig, [write]),
+ ?line io:format(IOD, "~s", ["+MBsbct 2048"]),
+ ?line file:close(IOD),
+ ?line display_file(ManualConfig),
+
+ ?line os:putenv("ERL_ZFLAGS", ZFlgs),
+
+ ?line {ok, Node2} = start_node(Config,
+ "-args_file " ++ ErtsAllocConfig
+ ++ " -args_file " ++ ManualConfig),
+
+ ?line {_, _, _, Cfg} = rpc:call(Node2, erlang, system_info, [allocator]),
+
+ ?line stop_node(Node2),
+
+ ?line {value,{binary_alloc, BCfg}} = lists:keysearch(binary_alloc, 1, Cfg),
+ ?line {value,{sbct, 2097152}} = lists:keysearch(sbct, 1, BCfg),
+ ?line {value,{eheap_alloc, HCfg}} = lists:keysearch(eheap_alloc, 1, Cfg),
+ ?line {value,{sbct, 4194304}} = lists:keysearch(sbct, 1, HCfg),
+
+ ?line ok.
+
+make_basic_config(ErtsAllocConfig) ->
+ %% Save some different scenarios
+ Tester = self(),
+ SSBegun = make_ref(),
+ SSDone = make_ref(),
+ SSFun = fun (F) ->
+ receive
+ SSDone ->
+ ok = erts_alloc_config:save_scenario(),
+ Tester ! SSDone
+ after 500 ->
+ ok = erts_alloc_config:save_scenario(),
+ F(F)
+ end
+ end,
+ SS = spawn_link(fun () ->
+ ok = erts_alloc_config:save_scenario(),
+ Tester ! SSBegun,
+ SSFun(SSFun)
+ end),
+ receive SSBegun -> ok end,
+ Ref = make_ref(),
+ Tab = ets:new(?MODULE, [bag, public]),
+ Ps = lists:map(
+ fun (_) ->
+ spawn_link(
+ fun () ->
+ ets:insert(Tab,
+ {self(),
+ lists:seq(1, 1000)}),
+ receive after 1000 -> ok end,
+ Tester ! {Ref, self()}
+ end)
+ end,
+ lists:seq(1, 10000)),
+ lists:foreach(fun (P) -> receive {Ref, P} -> ok end end, Ps),
+ ets:delete(Tab),
+ SS ! SSDone,
+ receive SSDone -> ok end,
+
+ ok = erts_alloc_config:make_config(ErtsAllocConfig).
+
+
+
+%%
+%% Utils ----------------------------------------------------------------------
+%%
+
+display_file(FileName) ->
+ ?t:format("filename: ~s~n", [FileName]),
+ {ok, Bin} = file:read_file(FileName),
+ io:format("~s", [binary_to_list(Bin)]),
+ ?t:format("eof: ~s~n", [FileName]),
+ ok.
+
+mk_name(Config) when is_list(Config) ->
+ {A, B, C} = now(),
+ list_to_atom(atom_to_list(?MODULE)
+ ++ "-" ++ atom_to_list(?config(testcase, Config))
+ ++ "-" ++ integer_to_list(A)
+ ++ "-" ++ integer_to_list(B)
+ ++ "-" ++ integer_to_list(C)).
+
+start_node(Config) ->
+ start_node(Config, "").
+
+start_node(Config, Args) ->
+ ?line Pa = filename:dirname(code:which(?MODULE)),
+ ?line ?t:start_node(mk_name(Config),
+ slave,
+ [{args, "-pa " ++ Pa ++ " " ++ Args}]).
+
+stop_node(Node) ->
+ ?line true = ?t:stop_node(Node).
+
+privfile(Name, Config) ->
+ filename:join([?config(priv_dir, Config),
+ atom_to_list(?config(testcase, Config)) ++ "." ++ Name]).
+
+save_env() ->
+ {erl_flags,
+ os:getenv("ERL_AFLAGS"),
+ os:getenv("ERL_FLAGS"),
+ os:getenv("ERL_"++erlang:system_info(otp_release)++"_FLAGS"),
+ os:getenv("ERL_ZFLAGS")}.
+
+restore_env(EVar, false) when is_list(EVar) ->
+ restore_env(EVar, "");
+restore_env(EVar, "") when is_list(EVar) ->
+ case os:getenv(EVar) of
+ false -> ok;
+ "" -> ok;
+ " " -> ok;
+ _ -> os:putenv(EVar, " ")
+ end;
+restore_env(EVar, Value) when is_list(EVar), is_list(Value) ->
+ case os:getenv(EVar) of
+ Value -> ok;
+ _ -> os:putenv(EVar, Value)
+ end.
+
+restore_env({erl_flags, AFlgs, Flgs, RFlgs, ZFlgs}) ->
+ restore_env("ERL_AFLAGS", AFlgs),
+ restore_env("ERL_FLAGS", Flgs),
+ restore_env("ERL_"++erlang:system_info(otp_release)++"_FLAGS", RFlgs),
+ restore_env("ERL_ZFLAGS", ZFlgs),
+ ok.
diff --git a/lib/runtime_tools/test/inviso_SUITE.erl b/lib/runtime_tools/test/inviso_SUITE.erl
new file mode 100644
index 0000000000..1c5c887b62
--- /dev/null
+++ b/lib/runtime_tools/test/inviso_SUITE.erl
@@ -0,0 +1,2840 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 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%
+%%
+%% Description:
+%% Test suite for inviso (basic parts, i.e not inviso tools). Note that
+%% inviso basic parts have modules in both the runtime_tools and
+%% inviso applications.
+%%
+%% Authors:
+%% Ann-Marie L�f, [email protected]
+%% Lennart �hman, [email protected]
+%% -----------------------------------------------------------------------------
+
+-module(inviso_SUITE).
+-compile(export_all).
+
+-include("test_server.hrl").
+-include_lib("kernel/include/file.hrl").
+
+-define(l,?line).
+
+all(suite) ->
+ [
+ basic_dist_trace_1,
+ basic_dist_trace_2,
+ basic_dist_trace_3,
+ basic_dist_trace_ti_1,
+ basic_dist_trace_ti_2,
+ basic_dist_trace_ti_3,
+ suspend_dist_trace_ti_1,
+ suspend_dist_trace_ti_2,
+ meta_cleanfunc_dist_1,
+ basic_handlerfun_dist_1,
+ delete_log_dist_1,
+ autostart_dist_1,
+ autostart_dist_2,
+ autostart_dist_3,
+ running_alone_dist_1,
+ running_alone_dist_2,
+ running_alone_dist_3,
+ running_alone_dist_4,
+ running_alone_dist_5,
+ overload_dist_1,
+ overload_dist_2,
+ overload_dist_3,
+ overload_dist_4,
+ overload_dist_5,
+ subscribe_dist_1,
+ lfm_trace_dist_1,
+ lfm_trace_ti_dist_2,
+ handle_logfile_sort_wrapset,
+ fetch_log_dist_trace_1,
+ fetch_log_dist_trace_2,
+ fetch_log_dist_trace_3,
+ fetch_log_dist_error_1,
+ fetch_log_dist_error_2,
+ expand_regexp_dist_1,
+ only_loaded_dist_1
+ ].
+
+
+init_per_suite(Config) ->
+ %% No never know who skrewed up this node before this suite! :-)
+ erlang:trace_pattern({'_','_','_'},[],[local]),
+ erlang:trace_pattern({'_','_','_'},[],[global]),
+ erlang:trace(all,false,[all]),
+
+ ?l ok=application:start(runtime_tools),
+ Config.
+
+end_per_suite(_Config) ->
+ ?l ok=application:stop(runtime_tools).
+
+
+%% For each distributed testcase, we need two other distributed nodes to run the
+%% runtime components on. Since they are freshly started every time there is no
+%% need to clean them up first.
+init_per_testcase(_Case,Config) ->
+ ?l TH=test_server:timetrap(100000),
+ ?l {ok,Node1}=test_server:start_node(inviso1,peer,[]),
+ ?l {ok,Node2}=test_server:start_node(inviso2,peer,[]),
+ ?l SuiteDir=filename:dirname(code:which(?MODULE)),
+
+ %% Otherwise peer nodes will not find this module!
+ ?l true=rpc:call(Node1,code,add_patha,[SuiteDir]),
+ ?l true=rpc:call(Node2,code,add_patha,[SuiteDir]),
+
+ ?l start_side_effect_logger(node()),
+ ?l start_side_effect_logger(Node1),
+ ?l start_side_effect_logger(Node2),
+
+
+ %% SPECIAL FOR MY PRIVATE TEST ENVIROMENT
+% ?l rpc:call(Node1,code,add_patha,["/clearcase/otp/tools/runtime_tools/ebin"]),
+% ?l rpc:call(Node1,code,add_patha,["/clearcase/otp/tools/inviso/ebin"]),
+% ?l rpc:call(Node2,code,add_patha,["/clearcase/otp/tools/runtime_tools/ebin"]),
+% ?l rpc:call(Node2,code,add_patha,["/clearcase/otp/tools/inviso/ebin"]),
+
+% %% SPECIAL FOR MY PRIVATE TEST ENVIROMENT, windows.
+% ?l rpc:call(Node1,code,add_patha,["Z:/DATA/PROJECTS/inviso_project/runtime_tools/ebin"]),
+% ?l rpc:call(Node1,code,add_patha,["Z:/DATA/PROJECTS/inviso_project/inviso/ebin"]),
+% ?l rpc:call(Node2,code,add_patha,["Z:/DATA/PROJECTS/inviso_project/runtime_tools/ebin"]),
+% ?l rpc:call(Node2,code,add_patha,["Z:/DATA/PROJECTS/inviso_project/inviso/ebin"]),
+
+ ?l ok=rpc:call(Node1,application,start,[runtime_tools]),
+ ?l ok=rpc:call(Node2,application,start,[runtime_tools]),
+ ?l timer:sleep(100), % Problem with autostarted runtime.
+ %% The following is a test that the inviso_rt processes which are autostarted
+ %% are now gone.
+
+ ?l ok=poll(rpc,call,[Node1,erlang,whereis,[inviso_rt]],undefined,20),
+ ?l ok=poll(rpc,call,[Node2,erlang,whereis,[inviso_rt]],undefined,20),
+
+% ?l ok=poll(rpc,call,[Node1,supervisor,which_children,[runtime_tools_sup]],[],20),
+% ?l ok=poll(rpc,call,[Node2,supervisor,which_children,[runtime_tools_sup]],[],20),
+ NewConfig1=insert_remotenode_config(inviso1,Node1,Config),
+ NewConfig2=insert_remotenode_config(inviso2,Node2,NewConfig1),
+ insert_timetraphandle_config(TH,NewConfig2).
+%% -----------------------------------------------------------------------------
+
+fin_per_testcase(Case,Config) ->
+ ?l test_server:stop_node(get_remotenode_config(inviso1,Config)),
+ ?l test_server:stop_node(get_remotenode_config(inviso2,Config)),
+
+ case whereis(inviso_c) of
+ undefined -> % Should not exist.
+ true;
+ Pid when is_pid(Pid) -> % But if it exists...
+ exit(Pid,kill), % Remove it!
+ io:format("Had to kill the control component in fin_per_testcase,~p.~n",[Case])
+ end,
+ case whereis(inviso_rt) of
+ undefined -> % Should not exist.
+ true;
+ Pid2 when is_pid(Pid2) -> % But if it exists...
+ exit(Pid2,kill), % Remove it!
+ io:format("Had to kill local runtime component in fin_per_testcase,~p.~n",[Case])
+ end,
+ ?l process_killer([inviso_test_proc,
+ inviso_tab_proc,
+ inviso_collector_proc,
+ global_inviso_test_proc]),
+ ?l test_server:timetrap_cancel(get_timetraphandle_config(Config)),
+
+ NewConfig1=remove_remotenode_config(inviso1,Config),
+ NewConfig2=remove_remotenode_config(inviso2,NewConfig1),
+ remove_timetraphandle_config(NewConfig2).
+%% -----------------------------------------------------------------------------
+
+%% ==============================================================================
+%% Testcases.
+%% ==============================================================================
+
+%% TEST CASE: Basic, distributed, trace only.
+basic_dist_trace_1(suite) -> [];
+basic_dist_trace_1(doc) ->
+ ["Basic case, start of distributed tracing, using only trac."];
+basic_dist_trace_1(Config) when is_list(Config) ->
+ RemoteNodes=get_remotenodes_config(Config),
+ Nodes=[node()|RemoteNodes],
+ PrivDir=filename:join(?config(priv_dir,Config),""),
+ TracerDataList=lists:map(fun(N)->{N,{file,filename:join([PrivDir,
+ "tf1_"++
+ atom_to_list(N)
+ ])}} end,
+ Nodes),
+ start_and_init_tracing2(Nodes,[],TracerDataList,{ok,[{trace_log,ok}]}),
+ activate_local_tracing(Nodes),
+ deactivate_local_tracing(Nodes),
+ stop_tracing(Nodes),
+ stop(Nodes),
+ ok.
+%% -----------------------------------------------------------------------------
+
+
+%% TEST CASE: Basic, distributed, activate global tracing for functions in modules
+%% pointed out using a regexp. No tracing will be done.
+basic_dist_trace_2(suite) -> [];
+basic_dist_trace_2(doc) ->
+ [""];
+basic_dist_trace_2(Config) when is_list(Config) ->
+ RemoteNodes=get_remotenodes_config(Config),
+ Nodes=[node()|RemoteNodes],
+ PrivDir=filename:join(?config(priv_dir,Config),""),
+ TracerDataList=lists:map(fun(N)->{N,{file,filename:join([PrivDir,
+ "tf1a_"++
+ atom_to_list(N)
+ ])}} end,
+ Nodes),
+ start_and_init_tracing2(Nodes,[],TracerDataList,{ok,[{trace_log,ok}]}),
+ Funcs1=activate_global_tracing_regexp(Nodes),
+ deactivate_global_tracing_regexp(Nodes,Funcs1),
+ stop_tracing(Nodes),
+ stop(Nodes),
+ ok.
+%% -----------------------------------------------------------------------------
+
+%% TEST CASE: Basic, distributed, activate global tracing for functions in modules
+%% pointed out using a dir-regexp. No tracing will be done.
+basic_dist_trace_3(suite) -> [];
+basic_dist_trace_3(doc) ->
+ [""];
+basic_dist_trace_3(Config) when is_list(Config) ->
+ RemoteNodes=get_remotenodes_config(Config),
+ Nodes=[node()|RemoteNodes],
+ PrivDir=filename:join(?config(priv_dir,Config),""),
+ TracerDataList=lists:map(fun(N)->{N,{file,filename:join([PrivDir,
+ "tf1b_"++
+ atom_to_list(N)
+ ])}} end,
+ Nodes),
+ start_and_init_tracing2(Nodes,[],TracerDataList,{ok,[{trace_log,ok}]}),
+ Funcs1=activate_global_tracing_regexp_dir(Nodes),
+ deactivate_global_tracing_regexp_dir(Nodes,Funcs1),
+ stop_tracing(Nodes),
+ stop(Nodes),
+ ok.
+%% -----------------------------------------------------------------------------
+
+%% TEST CASE: Basic, distributed, trace and ti.
+basic_dist_trace_ti_1(suite) -> [];
+basic_dist_trace_ti_1(doc) ->
+ [""];
+basic_dist_trace_ti_1(Config) when is_list(Config) ->
+ RemoteNodes=get_remotenodes_config(Config),
+ Nodes=[node()|RemoteNodes],
+ PrivDir=filename:join(?config(priv_dir,Config),""),
+ TracerDataFun=
+ fun(N)->{N,[{trace,{file,filename:join([PrivDir,"tf2_"++atom_to_list(N)])}},
+ {ti,{file,filename:join([PrivDir,"tf2_"++atom_to_list(N)++".ti"])}}]}
+ end,
+ TracerDataList=lists:map(TracerDataFun,Nodes),
+ start_and_init_tracing2(Nodes,[],TracerDataList,{ok,[{trace_log,ok},{ti_log,ok}]}),
+ activate_local_tracing(Nodes),
+ activate_meta_tracing(Nodes),
+ ?l true=(is_pid(whereis(inviso_rt))),
+ ?l true=(is_pid(whereis(inviso_rt_meta))),
+ deactivate_meta_tracing(Nodes),
+ deactivate_local_tracing(Nodes),
+ stop_tracing(Nodes),
+ ?l true=(is_pid(whereis(inviso_rt))), % Shall still be running.
+ ?l ok=poll(erlang,whereis,[inviso_rt_meta],undefined,3),
+ stop(Nodes),
+ timer:sleep(200), % Give it time to terminate.
+ ?l ok=poll(erlang,whereis,[inviso_rt],undefined,3),% Shall be gone now.
+ ?l undefined=whereis(inviso_rt_meta), % Still gone.
+ ok.
+%% -----------------------------------------------------------------------------
+
+%% Test CASE: Testing that the tpm_tracer functionality works. That is appending
+%% {tracer,Tracer} to a meta match spec.
+basic_dist_trace_ti_2(suite) -> [];
+basic_dist_trace_ti_2(doc) ->
+ [""];
+basic_dist_trace_ti_2(Config) when is_list(Config) ->
+ case erlang:system_info(version) of
+ "5.4"++_ -> % Perhaps not perfect, but work now :-)
+ {skip,"Old emulator"};
+ _ ->
+ basic_dist_trace_ti_2_do(Config)
+ end.
+
+basic_dist_trace_ti_2_do(Config) ->
+ RemoteNodes=get_remotenodes_config(Config),
+ Nodes=[node()|RemoteNodes],
+ PrivDir=filename:join(?config(priv_dir,Config),""),
+ TracerDataFun=
+ fun(N)->{N,[{trace,{file,filename:join([PrivDir,"tf3_"++atom_to_list(N)])}},
+ {ti,{file,filename:join([PrivDir,"tf3_"++atom_to_list(N)++".ti"])}}]}
+ end,
+ TracerDataList=lists:map(TracerDataFun,Nodes),
+ start_and_init_tracing2(Nodes,[],TracerDataList,{ok,[{trace_log,ok},{ti_log,ok}]}),
+ activate_deactivate_meta_tracing_tracer(Nodes),
+ stop_tracing(Nodes),
+ stop(Nodes),
+ ok.
+%% -----------------------------------------------------------------------------
+
+%% TEST CASE: Basic, distributed, trace and ti, where we try to use ctp_all to
+%% check that all global and local patterns are removed but that meta patterns
+%% remain.
+%% This test also checks that if the meta tracer is terminated an error value
+%% is generated when trying to do meta tracing at that node.
+basic_dist_trace_ti_3(suite) -> [];
+basic_dist_trace_ti_3(doc) ->
+ [""];
+basic_dist_trace_ti_3(Config) when is_list(Config) ->
+ RemoteNodes=get_remotenodes_config(Config),
+ Nodes=[node()|RemoteNodes],
+ PrivDir=filename:join(?config(priv_dir,Config),""),
+ TracerDataFun=
+ fun(N)->{N,[{trace,{file,filename:join([PrivDir,"tf4_"++atom_to_list(N)])}},
+ {ti,{file,filename:join([PrivDir,"tf4_"++atom_to_list(N)++".ti"])}}]}
+ end,
+ TracerDataList=lists:map(TracerDataFun,Nodes),
+ start_and_init_tracing2(Nodes,[],TracerDataList,{ok,[{trace_log,ok},{ti_log,ok}]}),
+ activate_local_tracing(Nodes),
+ activate_global_tracing(Nodes),
+ activate_meta_tracing(Nodes),
+ ?l true=(is_pid(whereis(inviso_rt))),
+ ?l true=(is_pid(whereis(inviso_rt_meta))),
+ ?l {ok,NodeResults1}=inviso:ctp_all(Nodes), % Removes local and global patterns.
+ ?l true=check_noderesults(Nodes,ok,NodeResults1),
+ ?l true=check_on_nodes(Nodes,erlang,trace_info,[{code,which,1},traced],{traced,false}),
+ ?l true=check_on_nodes(Nodes,erlang,trace_info,[{code,get_path,0},traced],{traced,false}),
+ %% But meta patters shall remain.
+ ?l true=check_on_nodes(Nodes,
+ erlang,
+ trace_info,
+ [{lists,module_info,0},meta_match_spec],
+ fun({meta_match_spec,L})when length(L)>0 ->true end),
+ ?l true=check_on_nodes(Nodes,
+ erlang,
+ trace_info,
+ [{lists,module_info,0},meta],
+ fun({meta,P})when is_pid(P) ->
+ P=rpc:call(node(P),erlang,whereis,[inviso_rt_meta]),
+ true
+ end),
+ %% Now kill the meta tracer somewhere and try to activate meta tracing.
+ ?l [ANode|_]=Nodes,
+ ?l AMetaPid=rpc:call(ANode,erlang,whereis,[inviso_rt_meta]),
+ ?l rpc:call(ANode,erlang,exit,[AMetaPid,kill]),
+ ?l {ok,NodeResults2}=inviso:tpm(Nodes,math,pi,0,[],void),
+ ?l {value,{ANode,{error,_}}}=lists:keysearch(ANode,1,NodeResults2),
+
+ ?l stop_tracing(Nodes),
+ ?l stop(Nodes),
+ ok.
+%% -----------------------------------------------------------------------------
+
+%% -----------------------------------------------------------------------------
+%% Test cases for SUSPEND
+%% -----------------------------------------------------------------------------
+
+%% TEST CASE: In this test case a trace with ti is started. Trace flags are set,
+%% trace patterns are set and meta trace patterns. We then check that the trace
+%% flags and the meta patterns are removed when tracing suspended.
+%% The suspension is cancelled and we check that it is possible to reactivate
+%% tracing by setting the process flags and meta patterns again.
+suspend_dist_trace_ti_1(suite) -> [];
+suspend_dist_trace_ti_1(doc) ->
+ [""];
+suspend_dist_trace_ti_1(Config) when is_list(Config) ->
+ ?l RemoteNodes=get_remotenodes_config(Config),
+ ?l Nodes=[node()|RemoteNodes],
+ ?l PrivDir=filename:join(?config(priv_dir,Config),""),
+ ?l TracerDataFun=
+ fun(N)->{N,[{trace,{file,filename:join([PrivDir,"tf_suspend1_"++atom_to_list(N)])}},
+ {ti,{file,filename:join([PrivDir,"tf_suspend1_"++atom_to_list(N)++".ti"])}}]}
+ end,
+ ?l TracerDataList=lists:map(TracerDataFun,Nodes),
+ start_and_init_tracing2(Nodes,[],TracerDataList,{ok,[{trace_log,ok},{ti_log,ok}]}),
+ activate_local_tracing(Nodes),
+ activate_meta_tracing(Nodes),
+ ?l true=(is_pid(whereis(inviso_rt))),
+ ?l true=(is_pid(whereis(inviso_rt_meta))),
+ %% Set some trace flags on some newly started test procs.
+ activate_traceflags(Nodes),
+
+ %% Now suspend the tracing on all nodes. That shall result in the removal
+ %% of trace flags and meta trace patterns, but not local trace patterns.
+ ?l {ok,NodeResults1}=inviso:suspend(Nodes,test),
+ ?l true=check_noderesults(Nodes,ok,NodeResults1),
+ %% Trace flags gone?
+ ?l TestProcs=lists:map(fun(N)->rpc:call(N,erlang,whereis,[inviso_test_proc]) end,Nodes),
+ ?l lists:foreach(fun(P)->
+ {flags,[]}=
+ rpc:call(node(P),erlang,trace_info,[P,flags])
+ end,
+ TestProcs),
+ %% Meta patterns shall be gone too, but local functions still there.
+ ?l lists:foreach(fun(N)->
+ {meta,false}=
+ rpc:call(N,
+ erlang,
+ trace_info,
+ [{math,module_info,1},meta]),
+ {traced,local}=
+ rpc:call(N,
+ erlang,
+ trace_info,
+ [{code,which,1},traced])
+ end,
+ Nodes),
+
+ %% Try to activate trace flags, trace patterns and meta tracing while
+ %% suspended. Should not succeed of course!
+ ?l ThisNode=node(),
+ ?l {ok,[{ThisNode,{error,suspended}}]}=
+ inviso:tf([ThisNode],inviso_test_proc,[call]),
+ ?l {ok,[{ThisNode,{error,suspended}}]}=
+ inviso:tpl([ThisNode],math,module_info,1,[]),
+ ?l {ok,[{ThisNode,{error,suspended}}]}=
+ inviso:init_tpm([ThisNode],
+ math,
+ module_info,
+ 1,
+ {?MODULE,tpm_init_func2}, % Does not exist on purpose.
+ {?MODULE,tpm_call_func2}, % Does not exist on purpose.
+ {?MODULE,tpm_return_func2}, % Does not exist on purpose.
+ {?MODULE,tpm_remove_func2}), % Does not exist on purpose.
+
+ %% Now we want to cancel suspension and see that we can reactivate tracing.
+ ?l {ok,NodeResults2}=inviso:cancel_suspension(Nodes),
+ ?l true=check_noderesults(Nodes,ok,NodeResults2),
+
+ ?l {ok,NodeResults3}=
+ inviso:init_tpm(math,
+ module_info,
+ 1,
+ {?MODULE,tpm_init_func2}, % Does not exist on purpose.
+ {?MODULE,tpm_call_func2}, % Does not exist on purpose.
+ {?MODULE,tpm_return_func2}, % Does not exist on purpose.
+ {?MODULE,tpm_remove_func2}), % Does not exist on purpose.
+ ?l true=check_noderesults(Nodes,ok,NodeResults3),
+ ?l {ok,NodeResults5}=
+ inviso:tpm_ms(math,module_info,1,ms1,[{'_',[],[{return_trace}]}]),
+ ?l true=check_noderesults(Nodes,{ok,1},NodeResults5),
+ ?l true=check_on_nodes(Nodes,
+ erlang,
+ trace_info,
+ [{math,module_info,1},meta_match_spec],
+ {meta_match_spec,[{'_',[],[{return_trace}]}]}),
+ ?l {ok,NodeResults6}=inviso:tf(Nodes,inviso_test_proc,[call]),
+ ?l true=check_noderesults(Nodes,{ok,[1]},NodeResults6),
+
+ %deactivate_meta_tracing(Nodes),
+ %deactivate_local_tracing(Nodes),
+ stop_tracing(Nodes),
+ ?l true=(is_pid(whereis(inviso_rt))), % Shall still be running.
+ ?l ok=poll(erlang,whereis,[inviso_rt_meta],undefined,3),
+ stop(Nodes),
+ ?l timer:sleep(200), % Give it time to terminate.
+ ?l ok=poll(erlang,whereis,[inviso_rt],undefined,3),% Shall be gone now.
+ ?l undefined=whereis(inviso_rt_meta), % Still gone.
+ ok.
+%% -----------------------------------------------------------------------------
+
+%% TEST CASE: In this test case a trace with ti is started. Trace flags are set,
+%% trace patterns are set and meta trace patterns. We then suspend tracing at
+%% all nodes, then stop tracing which shall be allowed. We then try to initiate
+%% tracing again which shall not be possible.
+suspend_dist_trace_ti_2(suite) -> [];
+suspend_dist_trace_ti_2(doc) ->
+ [""];
+suspend_dist_trace_ti_2(Config) when is_list(Config) ->
+ ?l RemoteNodes=get_remotenodes_config(Config),
+ ?l Nodes=[node()|RemoteNodes],
+ ?l PrivDir=filename:join(?config(priv_dir,Config),""),
+ ?l TracerDataFun=
+ fun(N)->{N,[{trace,{file,filename:join([PrivDir,"tf_suspend2_"++atom_to_list(N)])}},
+ {ti,{file,filename:join([PrivDir,"tf_suspend2_"++atom_to_list(N)++".ti"])}}]}
+ end,
+ ?l TracerDataList=lists:map(TracerDataFun,Nodes),
+ start_and_init_tracing2(Nodes,[],TracerDataList,{ok,[{trace_log,ok},{ti_log,ok}]}),
+ activate_local_tracing(Nodes),
+ activate_meta_tracing(Nodes),
+ ?l true=(is_pid(whereis(inviso_rt))),
+ ?l true=(is_pid(whereis(inviso_rt_meta))),
+ %% Set some trace flags on some newly started test procs.
+ activate_traceflags(Nodes),
+
+ %% Now suspend the tracing on all nodes. That shall result in the removal
+ %% of trace flags and meta trace patterns, but not local trace patterns.
+ ?l {ok,NodeResults1}=inviso:suspend(Nodes,test),
+ ?l true=check_noderesults(Nodes,ok,NodeResults1),
+
+ %% Now stop tracing.
+ ?l {ok,NodeResults3}=inviso:stop_tracing(Nodes),
+ ?l true=check_noderesults(Nodes,{ok,idle},NodeResults3),
+ %% Now try to initiate tracing again.
+ ThisNode=node(),
+ ?l {ok,[{ThisNode,{error,suspended}}]}=
+ inviso:init_tracing([ThisNode],
+ [{trace,{file,filename:join([PrivDir,"tf_suspend3_"++
+ atom_to_list(ThisNode)])}},
+ {ti,{file,{filename:join([PrivDir,"tf_suspend3_"++
+ atom_to_list(ThisNode)])}}}]),
+
+ %% Cancel the suspension and initiate tracing again.
+ ?l {ok,NodeResults2}=inviso:cancel_suspension(Nodes),
+ ?l true=check_noderesults(Nodes,ok,NodeResults2),
+ ?l TracerDataFun2=
+ fun(N)->{N,[{trace,{file,filename:join([PrivDir,"tf_suspend4_"++atom_to_list(N)])}},
+ {ti,{file,filename:join([PrivDir,"tf_suspend4_"++atom_to_list(N)++".ti"])}}]}
+ end,
+ ?l TracerDataList2=lists:map(TracerDataFun2,Nodes),
+ ?l {ok,NodeResults4}=inviso:init_tracing(TracerDataList2),
+ ?l true=check_noderesults(Nodes,{ok,[{trace_log,ok},{ti_log,ok}]},NodeResults4),
+ stop_tracing(Nodes),
+ ?l true=(is_pid(whereis(inviso_rt))), % Shall still be running.
+ stop(Nodes),
+ ?l timer:sleep(200), % Give it time to terminate.
+ ?l ok=poll(erlang,whereis,[inviso_rt],undefined,3),% Shall be gone now.
+ ok.
+%% -----------------------------------------------------------------------------
+
+
+
+%% TEST CASE: This test case tests that the clean function removes (prosumed)
+%% expired data from the internal public-loopdata structure in the inviso_rt_meta
+%% process.
+meta_cleanfunc_dist_1(Config) when is_list(Config) ->
+ RemoteNodes=get_remotenodes_config(Config),
+ Nodes=[node()|RemoteNodes],
+ PrivDir=filename:join(?config(priv_dir,Config),""),
+ TracerDataFun=
+ fun(N)->{N,[{trace,{file,filename:join([PrivDir,"mcf1_"++atom_to_list(N)])}},
+ {ti,{file,filename:join([PrivDir,"mcf1_"++atom_to_list(N)++".ti"])}}]}
+ end,
+ TracerDataList=lists:map(TracerDataFun,Nodes),
+ start_and_init_tracing2(Nodes,[],TracerDataList,{ok,[{trace_log,ok},{ti_log,ok}]}),
+ %% Now initialize meta tracing, but the call_func is a bit "fixed".
+ ?l {ok,NodeResults1}=
+ inviso:tpm(Nodes,math,module_info,1,[],
+ {?MODULE,meta_cleanfunc_initfunc_1},
+ {?MODULE,meta_cleanfunc_callfunc_1},
+ void,void),
+ ?l true=check_noderesults(Nodes,{ok,1},NodeResults1),
+ %% Nothing in the "our" part of the public loop data.
+ ?l true=check_on_nodes(Nodes,
+ inviso_rt_meta,get_state,[inviso_rt_meta],
+ fun({ok,_LD,{{_,[]},_}})->true end),
+ ?l lists:foreach(fun(N)->rpc:call(N,math,module_info,[exports]) end,Nodes),
+ %% Check that it has been added to the public loopdata structure.
+ ?l true=check_on_nodes(Nodes,
+ ?MODULE,poll,[inviso_rt_meta,
+ get_state,
+ [inviso_rt_meta],
+ fun({ok,_LD,{{_,[{meta_cleanfunc_test1,_Now}]},_}})->
+ true;
+ (_)->false
+ end,
+ 20],
+ ok),
+ %% While we wait for 60 seconds to pass, we test a few other things.
+ ?l {ok,NodeResults2}=
+ inviso:tpm(Nodes,?MODULE,slowfunction2,0,[{'_',[],[{return_trace}]}],
+ {?MODULE,meta_cleanfunc_initfunc_2},
+ {?MODULE,meta_cleanfunc_callfunc_2},
+ {?MODULE,meta_cleanfunc_returnfunc_2},
+ void),
+ ?l true=check_noderesults(Nodes,{ok,1},NodeResults2),
+ ?l lists:foreach(fun(N)->rpc:call(N,?MODULE,slowfunction,[]) end,Nodes),
+ %% Believe it or not but slowfunction is still running, in its own process,
+ %% we are therefore free now to examine the meta tracer.
+ ?l true=check_on_nodes(Nodes,
+ ?MODULE,poll,[inviso_rt_meta,
+ get_state,
+ [inviso_rt_meta],
+ fun({ok,_LD,{{[],Tuples},_}})->
+ {value,_}=
+ lists:keysearch(meta_cleanfunc_test2,
+ 1,
+ Tuples),
+ {value,_}=
+ lists:keysearch(meta_cleanfunc_test1,
+ 1,
+ Tuples),
+ true;
+ (_)->
+ false
+ end,
+ 20],
+ ok),
+ %% Now we wait for slowfunction to return and that the meta_cleanfunc_test2
+ %% to be removed from public loopdata strucuture.
+ ?l timer:sleep(10000),
+ %% The only thing remaining should be the meta_cleanfunc_test1 which will not
+ %% go away for less than that the clean functionality removes it.
+ ?l true=check_on_nodes(Nodes,
+ ?MODULE,poll,[inviso_rt_meta,
+ get_state,
+ [inviso_rt_meta],
+ fun({ok,_LD,{{_,[{meta_cleanfunc_test1,_Now}]},_}})->
+ true;
+ (_)->
+ false
+ end,
+ 20],
+ ok),
+ %% Wait for the clean function to clean meta_cleanfunc_test1 away.
+ ?l timer:sleep(51000), % Shall be gone after 5 seconds.
+ ?l true=check_on_nodes(Nodes,
+ ?MODULE,poll,[inviso_rt_meta,
+ get_state,
+ [inviso_rt_meta],
+ fun({ok,_LD,{{_,[]},_}})->true;
+ (_)->false
+ end,
+ 20],
+ ok),
+ stop_tracing(Nodes),
+ stop(Nodes),
+ ok.
+
+%% This function acts as tpm initialization function when we are going to test
+%% that the clean function works. Note that we here assume standard public loop
+%% datastructure.
+meta_cleanfunc_initfunc_1(_M,_F,_Arity,{E1,_E2}) ->
+ {ok,{E1,[]},void}.
+%% Function that is supposed to be called when the meta traced function is
+%% called.
+meta_cleanfunc_callfunc_1(_Pid,_Args,{{E1,E2},Global}) ->
+ {ok,{{E1,[{meta_cleanfunc_test1,now()}|E2]},Global},void}.
+
+meta_cleanfunc_initfunc_2(_M,_F,_Arity,PublLD) ->
+ {ok,PublLD,void}.
+meta_cleanfunc_callfunc_2(_Pid,_Args,{{E1,E2},Global}) ->
+ {ok,{{E1,[{meta_cleanfunc_test2,now()}|E2]},Global},void}.
+meta_cleanfunc_returnfunc_2(_Pid,_,{{E1,E2},Global}) ->
+ {value,_}=lists:keysearch(meta_cleanfunc_test2,1,E2),
+ {ok,{{E1,lists:keydelete(meta_cleanfunc_test2,1,E2)},Global},void}.
+
+slowfunction() ->
+ spawn(?MODULE,slowfunction1,[]).
+slowfunction1() ->
+ slowfunction2(). % Meta trace on this function call.
+slowfunction2() ->
+ timer:sleep(2000),
+ true.
+%% -----------------------------------------------------------------------------
+
+%% TEST CASE: Testing that a runtime component can be started instructing it
+%% to use a handler fun. Checks that the handler fun is called if a trace
+%% message comes in.
+basic_handlerfun_dist_1(suite) -> [];
+basic_handlerfun_dist_1(doc) ->
+ [""];
+basic_handlerfun_dist_1(Config) when is_list(Config) ->
+ RemoteNodes=get_remotenodes_config(Config),
+ Nodes=[node()|RemoteNodes],
+ ?l lists:foreach(fun(N)->rpc:call(N,ets,insert,[inviso_sideeffect_tab,{bhf1,0}]) end,
+ Nodes),
+ TracerDataFun=
+ fun(N)->{N,{fun basic_handlerfun_dist_1_fun/2,inviso_sideeffect_tab}} end,
+ TracerDataList=lists:map(TracerDataFun,Nodes),
+ start_and_init_tracing2(Nodes,[],TracerDataList,{ok,[{trace_log,ok}]}),
+ activate_local_tracing(Nodes),
+ activate_traceflags(Nodes),
+ ?l lists:foreach(fun(N)->[{bhf1,0}]=
+ rpc:call(N,ets,lookup,[inviso_sideeffect_tab,bhf1])
+ end,
+ Nodes),
+ ?l inviso_test_proc ! {apply,code,which,[lists]},
+ ok=poll(ets,lookup,[inviso_sideeffect_tab,bhf1],[{bhf1,1}],20),
+ deactivate_traceflags(Nodes),
+ deactivate_local_tracing(Nodes),
+ stop_tracing(Nodes),
+ timer:sleep(100),
+ ?l [{bhf1,1}]=ets:lookup(inviso_sideeffect_tab,bhf1),
+ stop(Nodes),
+ ok.
+
+%% Function used as handler fun for testcase above.
+basic_handlerfun_dist_1_fun(_Msg,TId) ->
+ ets:update_counter(TId,bhf1,1),
+ TId.
+%% -----------------------------------------------------------------------------
+
+%% TEST CASE: Here we test that delete_log removes the files at the involved
+%% runtime nodes. In this case we test that we remove logs according to last
+%% used tracer data.
+delete_log_dist_1(suite) -> [];
+delete_log_dist_1(doc) -> [""];
+delete_log_dist_1(Config) when is_list(Config) ->
+ RemoteNodes=get_remotenodes_config(Config),
+ Nodes=[node()|RemoteNodes],
+ PrivDir=filename:join(?config(priv_dir,Config),""),
+ TracerDataFun=
+ fun(N)->{N,[{trace,{file,filename:join([PrivDir,"dl1_"++atom_to_list(N)])}},
+ {ti,{file,filename:join([PrivDir,"dl1_"++atom_to_list(N)++".ti"])}}]}
+ end,
+ TracerDataList=lists:map(TracerDataFun,Nodes),
+ start_and_init_tracing2(Nodes,[],TracerDataList,{ok,[{trace_log,ok},{ti_log,ok}]}),
+ ?l Files=lists:map(fun({N,TD})->
+ ?l {value,{_,{_,TraceFile}}}=lists:keysearch(trace,1,TD),
+ ?l {value,{_,{_,TiFile}}}=lists:keysearch(ti,1,TD),
+ ?l {N,{TraceFile,TiFile}}
+ end,
+ TracerDataList),
+ io:format("The Files is:~w~n",[Files]),
+ ?l {ok,NodeResults1}=inviso:delete_log(Nodes), % Should not work!
+ ?l true=check_noderesults(Nodes,{error,tracing},NodeResults1),
+ stop_tracing(Nodes),
+ %% Files still here.
+ ?l lists:foreach(fun({N,{F1,F2}})->
+ ?l {ok,_}=rpc:call(N,file,read_file_info,[F1]),
+ ?l {ok,_}=rpc:call(N,file,read_file_info,[F2])
+ end,
+ Files),
+ ?l {ok,NodeResults2}=inviso:delete_log(Nodes),
+ ?l true=check_noderesults(Nodes,
+ fun({_N,{ok,LogInfos}})->
+ ?l {value,{_,[{ok,_FName1}]}}=
+ lists:keysearch(trace_log,1,LogInfos),
+ ?l {value,{_,[{ok,_FName2}]}}=
+ lists:keysearch(ti_log,1,LogInfos),
+ true
+ end,
+ NodeResults2),
+ %% The files shall be gone now.
+ ?l lists:foreach(fun({N,{F1,F2}})->
+ ?l {error,enoent}=rpc:call(N,file,read_file_info,[F1]),
+ ?l {error,enoent}=rpc:call(N,file,read_file_info,[F2])
+ end,
+ Files),
+ stop(Nodes),
+ ok.
+%% -----------------------------------------------------------------------------
+
+
+%% TEST CASE: Test of the autostart behaviour of the runtime component.
+%% Here we test that a runtime component is started according to the autostart.conf
+%% file. Note that the repeat parameter is set to 2.
+autostart_dist_1(suite) -> [];
+autostart_dist_1(doc) ->
+ [""];
+autostart_dist_1(Config) when is_list(Config) ->
+ RemoteNodes=get_remotenodes_config(Config),
+ PrivDir=filename:join(?config(priv_dir,Config),""),
+ AutoConfFile=filename:join(PrivDir,"autostart1.conf"),
+ [RNode|_]=RemoteNodes,
+ ?l ok=rpc:call(RNode,application,stop,[runtime_tools]),
+ ?l ok=rpc:call(RNode,application,set_env,[runtime_tools,
+ inviso_autostart_conf,
+ AutoConfFile]),
+ ?l {ok,FD}=file:open(AutoConfFile,[write]),
+ ?l ok=io:format(FD,"~w.~n~w.~n",[{repeat,2},{tag,c_ref}]),
+ ?l file:close(FD),
+ ?l ok=rpc:call(RNode,application,start,[runtime_tools]),
+ timer:sleep(1000),
+ ?l P1=rpc:call(RNode,erlang,whereis,[inviso_rt]),
+ ?l true=is_pid(P1),
+ ?l rpc:call(RNode,erlang,exit,[P1,kill]),
+ ?l ok=rpc:call(RNode,application,stop,[runtime_tools]),
+ ?l ok=rpc:call(RNode,application,start,[runtime_tools]),
+ timer:sleep(1000),
+ ?l P2=rpc:call(RNode,erlang,whereis,[inviso_rt]),
+ ?l true=is_pid(P2),
+ ?l rpc:call(RNode,erlang,exit,[P2,kill]),
+ ?l ok=rpc:call(RNode,application,stop,[runtime_tools]),
+ ?l ok=rpc:call(RNode,application,start,[runtime_tools]),
+ timer:sleep(1000),
+ ?l undefined=rpc:call(RNode,erlang,whereis,[inviso_rt]),
+ ok.
+%% -----------------------------------------------------------------------------
+
+%% TEST CASE: Test of autostart. Here we focus on that an autostarted
+%% runtime component actually follows the trace case command file and
+%% initiates tracing.
+autostart_dist_2(suite) -> [];
+autostart_dist_2(doc) ->
+ [""];
+autostart_dist_2(Config) when is_list(Config) ->
+ RemoteNodes=get_remotenodes_config(Config),
+ PrivDir=filename:join(?config(priv_dir,Config),""),
+ AutoConfFile=filename:join(PrivDir,"autostart2.conf"),
+ [RNode|_]=RemoteNodes,
+ ?l ok=rpc:call(RNode,application,stop,[runtime_tools]),
+ ?l ok=rpc:call(RNode,application,set_env,[runtime_tools,
+ inviso_autostart_conf,
+ AutoConfFile]),
+ ?l CmdFileName=filename:join(PrivDir,"autostart_cmd_as1"),
+ ?l {ok,FD}=file:open(CmdFileName,[write]),
+ ?l ok=io:format(FD,
+ "inviso:tpl(Nodes,M,F,Arity,[]).~n"
+ "inviso:tf(Nodes,inviso_test_proc,[call]).~n",
+ []),
+ ?l file:close(FD),
+ ?l TraceFileName=filename:join([PrivDir,"as1_"++atom_to_list(RNode)]),
+ ?l TiFileName=filename:join([PrivDir,"as1_"++atom_to_list(RNode)++".ti"]),
+ ?l inviso_as_lib:setup_autostart(RNode,
+ 2,
+ [],
+ [{trace,{file,TraceFileName}},
+ {ti,{file,TiFileName}}],
+ [[CmdFileName]],
+ [{'M',code},{'F',which},{'Arity',1}],
+ [{{inviso,tpl,5},{inviso_rt,tpl,{erlang,tl}}},
+ {{inviso,tf,3},{inviso_rt,tf,{erlang,tl}}}]),
+ ?l TestP=spawn(RNode,?MODULE,test_proc_init,[]),
+ ?l ok=rpc:call(RNode,application,start,[runtime_tools]),
+ ?l timer:sleep(1000),
+ ?l {ok,_}=file:read_file_info(TraceFileName),
+ ?l {ok,_}=file:read_file_info(TiFileName),
+ ?l true=is_pid(P=rpc:call(RNode,erlang,whereis,[inviso_rt])),
+ ?l ok=poll(rpc,call,[RNode,erlang,trace_info,[{code,which,1},traced]],{traced,local},10),
+ ?l {flags,[call]}=rpc:call(RNode,erlang,trace_info,[TestP,flags]),
+ ?l rpc:call(RNode,erlang,exit,[P,kill]),
+ ok.
+%% -----------------------------------------------------------------------------
+
+%% TEST CASE: Here we test that an autostarted runtime component with a dependency
+%% to a specific control component tries to connect to that control component
+%% during its start-up.
+autostart_dist_3(suite) -> [];
+autostart_dist_3(doc) ->
+ [""];
+autostart_dist_3(Config) when is_list(Config) ->
+ RemoteNodes=get_remotenodes_config(Config),
+ PrivDir=filename:join(?config(priv_dir,Config),""),
+ AutoConfFile=filename:join(PrivDir,"autostart3.conf"),
+ [RNode|_]=RemoteNodes,
+ ?l ok=rpc:call(RNode,application,stop,[runtime_tools]),
+ ?l ok=rpc:call(RNode,application,set_env,[runtime_tools,
+ inviso_autostart_conf,
+ AutoConfFile]),
+ ?l {ok,FD}=file:open(AutoConfFile,[write]),
+ ?l ok=io:format(FD,"~w.~n~w.~n~w.~n",
+ [{options,[{dependency,{infinity,node()}}]},{repeat,2},{tag,c_ref}]),
+ ?l file:close(FD),
+ %% Now start inviso at this node here for the runtime to connect.
+ ?l {ok,_Pid}=inviso:start(),
+ ?l ok=poll(erlang,whereis,[inviso_c],fun(P) when is_pid(P)->true;(_)->false end,10),
+ %% Make the runtime component start.
+ ?l ok=rpc:call(RNode,application,start,[runtime_tools]),
+ ?l ok=poll(rpc,call,[RNode,erlang,whereis,[inviso_rt]],
+ fun(P) when is_pid(P)->true;(_)->false end,10),
+ %% Check that the runtime component started.
+ ?l ok=poll(inviso,get_status,[[RNode]],{ok,[{RNode,{ok,{new,running}}}]},20),
+% ?l {ok,[{RNode,{ok,{new,running}}}]}=inviso:get_status([RNode]),
+ stop([RNode]),
+ ok.
+%% -----------------------------------------------------------------------------
+
+
+
+%% TEST CASE: Test of the dependency mechanism in the runtime component.
+%% Default behaviour is dependency=infinity, i.e the runtime components remains.
+%% We also test here that we can reconnect to the runtime.
+running_alone_dist_1(suite) -> [];
+running_alone_dist_1(doc) ->
+ [""];
+running_alone_dist_1(Config) when is_list(Config) ->
+ ?l {ok,_Pid1}=inviso:start(), % Start a control component.
+ RemoteNodes=get_remotenodes_config(Config),
+ Nodes=[node()|RemoteNodes],
+ ?l {ok,NodeResults1}=inviso:add_nodes(Nodes,a_ref,[]),
+ ?l true=check_noderesults(Nodes,{ok,new},NodeResults1),
+ ?l shutdown=inviso:stop(), % Stop the control component!
+ ?l undefined=whereis(inviso_c),
+ timer:sleep(3000), % How long shall we wait? :-)
+ ?l lists:foreach(fun(N)->true=is_pid(rpc:call(N,erlang,whereis,[inviso_rt])) end,
+ Nodes),
+ ?l {ok,_Pid2}=inviso:start(),
+ ?l {ok,NodeResults2}=inviso:add_nodes(Nodes,b_ref,[]),
+ ?l true=check_noderesults(Nodes,{ok,{adopted,new,running,a_ref}},NodeResults2),
+ stop(Nodes),
+ ok.
+%% -----------------------------------------------------------------------------
+
+%% TEST CASE: Test of the dependency mechanism in the runtime component.
+%% Test that the runtime components terminates after the specified 5000 ms.
+running_alone_dist_2(suite) -> [];
+running_alone_dist_2(doc) ->
+ [""];
+running_alone_dist_2(Config) when is_list(Config) ->
+ ?l {ok,_Pid1}=inviso:start(), % Start a control component.
+ RemoteNodes=get_remotenodes_config(Config),
+ Nodes=[node()|RemoteNodes],
+ ?l {ok,NodeResults1}=inviso:add_nodes(Nodes,a_ref,[{dependency,5000}]),
+ ?l true=check_noderesults(Nodes,{ok,new},NodeResults1),
+ ?l shutdown=inviso:stop(), % Stop the control component!
+ ?l undefined=whereis(inviso_c),
+ timer:sleep(2000),
+ ?l lists:foreach(fun(N)->true=is_pid(rpc:call(N,erlang,whereis,[inviso_rt])) end,
+ Nodes),
+ timer:sleep(4000), % Now they shall be dead!
+ ?l lists:foreach(fun(N)->undefined=rpc:call(N,erlang,whereis,[inviso_rt]) end,
+ Nodes),
+ ok.
+%% -----------------------------------------------------------------------------
+
+%% TEST CASE: Test of the dependency mechanism in the runtime component.
+%% Test that the runtime components terminates after the specified 5000 ms.
+running_alone_dist_3(suite) -> [];
+running_alone_dist_3(doc) ->
+ [""];
+running_alone_dist_3(Config) when is_list(Config) ->
+ ?l {ok,_Pid1}=inviso:start(), % Start a control component.
+ RemoteNodes=get_remotenodes_config(Config),
+ Nodes=[node()|RemoteNodes],
+ ?l {ok,NodeResults1}=inviso:add_nodes(Nodes,a_ref,[{dependency,1000}]),
+ ?l true=check_noderesults(Nodes,{ok,new},NodeResults1),
+ ?l {ok,NodeResults2}=inviso:change_options(Nodes,[{dependency,5000}]),
+ ?l true=check_noderesults(Nodes,ok,NodeResults2),
+ ?l shutdown=inviso:stop(), % Stop the control component!
+ ?l undefined=whereis(inviso_c),
+ timer:sleep(3000),
+ ?l lists:foreach(fun(N)->true=is_pid(rpc:call(N,erlang,whereis,[inviso_rt])) end,
+ Nodes),
+ timer:sleep(3000), % Now they shall be dead!
+ ?l lists:foreach(fun(N)->undefined=rpc:call(N,erlang,whereis,[inviso_rt]) end,
+ Nodes),
+ ok.
+%% -----------------------------------------------------------------------------
+
+%% TEST CASE: Test of the dependency mechanism in the runtime component.
+%% Test that the runtime components terminates after the specified 5000 ms,
+%% like we did in running_alone_dist_2. But now we also start tracing and checks
+%% that all inviso processes actually disappears when the time-out is reached.
+running_alone_dist_4(suite) -> [];
+running_alone_dist_4(doc) ->
+ [""];
+running_alone_dist_4(Config) when is_list(Config) ->
+ RemoteNodes=get_remotenodes_config(Config),
+ Nodes=[node()|RemoteNodes],
+ %% Start some tracing!
+ PrivDir=filename:join(?config(priv_dir,Config),""),
+ TracerDataFun=
+ fun(N)->{N,[{trace,{file,filename:join([PrivDir,"tf_ra4"++atom_to_list(N)])}},
+ {ti,{file,filename:join([PrivDir,"tf_ra4_"++atom_to_list(N)++".ti"])}}]}
+ end,
+ TracerDataList=lists:map(TracerDataFun,Nodes),
+ start_and_init_tracing2(Nodes,
+ [{dependency,5000}],
+ TracerDataList,
+ {ok,[{trace_log,ok},{ti_log,ok}]}),
+
+ ?l lists:foreach(fun(N)->true=is_pid(rpc:call(N,erlang,whereis,[inviso_rt])) end,
+ Nodes),
+ ?l lists:foreach(fun(N)->true=is_pid(rpc:call(N,erlang,whereis,[inviso_rt_meta])) end,
+ Nodes),
+ %% Stop control component and wait for the runtimes to terminate after
+ %% running alone timer has expired.
+ ?l shutdown=inviso:stop(), % Stop the control component!
+ ?l undefined=whereis(inviso_c),
+ timer:sleep(2000),
+ ?l lists:foreach(fun(N)->true=is_pid(rpc:call(N,erlang,whereis,[inviso_rt])) end,
+ Nodes),
+ ?l lists:foreach(fun(N)->true=is_pid(rpc:call(N,erlang,whereis,[inviso_rt_meta])) end,
+ Nodes),
+ timer:sleep(4000), % Now they shall be dead!
+ ?l lists:foreach(fun(N)->undefined=rpc:call(N,erlang,whereis,[inviso_rt]) end,
+ Nodes),
+ ?l lists:foreach(fun(N)->undefined=rpc:call(N,erlang,whereis,[inviso_rt_meta]) end,
+ Nodes),
+ ok.
+%% -----------------------------------------------------------------------------
+
+%% TEST CASE: Test of the dependency mechanism in the runtime component.
+%% Test that the runtime components terminates imeediately when the control
+%% component is stopped. Check that all processes are gone.
+running_alone_dist_5(suite) -> [];
+running_alone_dist_5(doc) ->
+ [""];
+running_alone_dist_5(Config) when is_list(Config) ->
+ RemoteNodes=get_remotenodes_config(Config),
+ Nodes=[node()|RemoteNodes],
+ %% Start some tracing!
+ PrivDir=filename:join(?config(priv_dir,Config),""),
+ TracerDataFun=
+ fun(N)->{N,[{trace,{file,filename:join([PrivDir,"tf_ra5"++atom_to_list(N)])}},
+ {ti,{file,filename:join([PrivDir,"tf_ra5_"++atom_to_list(N)++".ti"])}}]}
+ end,
+ TracerDataList=lists:map(TracerDataFun,Nodes),
+ start_and_init_tracing2(Nodes,
+ [{dependency,0}],
+ TracerDataList,
+ {ok,[{trace_log,ok},{ti_log,ok}]}),
+
+ ?l lists:foreach(fun(N)->true=is_pid(rpc:call(N,erlang,whereis,[inviso_rt])) end,
+ Nodes),
+ ?l lists:foreach(fun(N)->true=is_pid(rpc:call(N,erlang,whereis,[inviso_rt_meta])) end,
+ Nodes),
+ %% Stop control component and check that all runtime component processes have
+ %% terminate more or less immediately afterwards, since dependency==0.
+ ?l shutdown=inviso:stop(), % Stop the control component!
+ timer:sleep(100),
+ ?l undefined=whereis(inviso_c),
+ timer:sleep(500),
+ ?l lists:foreach(fun(N)->undefined=rpc:call(N,erlang,whereis,[inviso_rt]) end,
+ Nodes),
+ ?l lists:foreach(fun(N)->undefined=rpc:call(N,erlang,whereis,[inviso_rt_meta]) end,
+ Nodes),
+ ok.
+%% -----------------------------------------------------------------------------
+
+%% TEST CASE: Test of the overload protection mechanism. The mechanism checks
+%% for overload using the callback approximately at the interval specified.
+%% Check that it does not start protection until start of tracing.
+overload_dist_1(suite) -> [];
+overload_dist_1(doc) ->
+ [""];
+overload_dist_1(Config) when is_list(Config) ->
+ ?l {ok,_Pid1}=inviso:start(), % Start a control component.
+ RemoteNodes=get_remotenodes_config(Config),
+ Nodes=[node()|RemoteNodes],
+ ?l lists:foreach(fun(N)->true=rpc:call(N,ets,insert,[inviso_sideeffect_tab,{ovl1,0}]) end,
+ Nodes), % Initiate the counter.
+ ?l {ok,NodeResults1}=inviso:add_nodes(Nodes,
+ a_ref,
+ [{overload,{{?MODULE,overload1},500}}]),
+ ?l true=check_noderesults(Nodes,{ok,new},NodeResults1),
+ timer:sleep(1000), % Give the loadcheck time to perform.
+ ?l [{_,0}]=ets:lookup(inviso_sideeffect_tab,ovl1), % Nothing should have happened.
+
+ %% Overload check shall not start until we start tracing.
+ PrivDir=filename:join(?config(priv_dir,Config),""),
+ TracerDataList=lists:map(fun(N)->{N,[{trace,
+ {file,filename:join([PrivDir,
+ "tf_ovl1."++atom_to_list(N)
+ ])}}]}
+ end,
+ Nodes),
+ ?l {ok,NodeResults2}=inviso:init_tracing(TracerDataList),
+ ?l true=check_noderesults(Nodes,{ok,[{trace_log,ok}]},NodeResults2),
+ timer:sleep(1500), % Give the loadcheck time to perform.
+ ?l [{_,N}]=ets:lookup(inviso_sideeffect_tab,ovl1),
+ ?l true=(N>=2), % After 1,5 seconds, at least 2 checks.
+
+ %% Now change options and remove overload checking!
+ ?l {ok,NodeResults3}=inviso:change_options(Nodes,[overload]),
+ ?l true=check_noderesults(Nodes,ok,NodeResults3),
+ ?l [{_,N2}]=ets:lookup(inviso_sideeffect_tab,ovl1),
+ timer:sleep(1000),
+ ?l [{_,N2}]=ets:lookup(inviso_sideeffect_tab,ovl1), % No more loadchecks!
+
+ stop_tracing(Nodes),
+ stop(Nodes),
+ ok.
+%% -----------------------------------------------------------------------------
+
+%% TEST CASE: Test of the overload protection mechanism. In this case we focus
+%% in that the init and remove functions are carried out at change_options and
+%% when starting and stoping the runtime component.
+overload_dist_2(suite) -> [];
+overload_dist_2(doc) ->
+ [""];
+overload_dist_2(Config) when is_list(Config) ->
+ ?l {ok,_Pid1}=inviso:start(), % Start a control component.
+ RemoteNodes=get_remotenodes_config(Config),
+ Nodes=[node()|RemoteNodes],
+ ?l {ok,NodeResults1}=inviso:add_nodes(Nodes,
+ a_ref,
+ [{overload,{{?MODULE,overload2},
+ 500,
+ {?MODULE,overload2i,[]},
+ {?MODULE,overload2r,[]}}}]),
+ ?l true=check_noderesults(Nodes,{ok,new},NodeResults1),
+ ?l [{_,0}]=ets:lookup(inviso_sideeffect_tab,ovl2),
+
+ PrivDir=filename:join(?config(priv_dir,Config),""),
+ TracerDataList=lists:map(fun(N)->{N,[{trace,
+ {file,filename:join([PrivDir,
+ "tf_ovl2."++atom_to_list(N)
+ ])}}]}
+ end,
+ Nodes),
+ ?l {ok,NodeResults2}=inviso:init_tracing(TracerDataList),
+ ?l true=check_noderesults(Nodes,{ok,[{trace_log,ok}]},NodeResults2),
+ timer:sleep(1500), % Give the loadcheck time to perform.
+ ?l [{_,N}]=ets:lookup(inviso_sideeffect_tab,ovl2),
+ io:format("� is:~p~n",[N]),
+ ?l true=(N>=2), % After 1,5 seconds, at least 2 checks.
+ ?l {ok,NodeResults3}=inviso:change_options(Nodes,[{overload,{{?MODULE,overload3},
+ 500,
+ {?MODULE,overload3i,[]},
+ {?MODULE,overload3r,[]}}}]),
+ ?l true=check_noderesults(Nodes,ok,NodeResults3),
+ ?l []=ets:lookup(inviso_sideeffect_tab,ovl2),
+ timer:sleep(1500),
+ ?l [{_,N2}]=ets:lookup(inviso_sideeffect_tab,ovl3),
+ ?l true=(N2>=2), % After 1,5 seconds, at least 2 checks.
+ stop_tracing(Nodes),
+ ?l []=ets:lookup(inviso_sideeffect_tab,ovl3r), % Remove function shall not be called.
+ ?l [{_,N3}]=ets:lookup(inviso_sideeffect_tab,ovl3),
+ timer:sleep(1000), % Check that overloadchecking has stopped.
+ ?l [{_,N3}]=ets:lookup(inviso_sideeffect_tab,ovl3),
+ stop(Nodes),
+ ?l ok=poll(ets,lookup,[inviso_sideeffect_tab,ovl3r],[{ovl3r,done}],20),
+ ok.
+%% -----------------------------------------------------------------------------
+
+%% TEST CASE: Test of the overload protections mechanism. Here we focus on testing
+%% that if overload is reached tracing is really suspended.
+overload_dist_3(suite) -> [];
+overload_dist_3(doc) ->
+ [""];
+overload_dist_3(Config) when is_list(Config) ->
+ RemoteNodes=get_remotenodes_config(Config),
+ Nodes=[node()|RemoteNodes],
+ PrivDir=filename:join(?config(priv_dir,Config),""),
+ TracerDataList=
+ lists:map(fun(N)->{N,[{trace,{file,filename:join([PrivDir,
+ "tf_ovl3."++atom_to_list(N)])}},
+ {ti,{file,filename:join([PrivDir,
+ "tf_ovl3_ti."++atom_to_list(N)])}}]}
+ end,
+ Nodes),
+ ?l lists:foreach(fun(N)->
+ true=rpc:call(N,ets,insert,[inviso_sideeffect_tab,{ovl4,0}])
+ end,
+ Nodes),
+ start_and_init_tracing2(Nodes,
+ [{overload,{{?MODULE,overload4},500}}],
+ TracerDataList,
+ {ok,[{trace_log,ok},{ti_log,ok}]}),
+ activate_local_tracing(Nodes),
+ activate_meta_tracing(Nodes),
+ activate_traceflags(Nodes),
+ timer:sleep(600),
+ ?l [{_,N1}]=ets:lookup(inviso_sideeffect_tab,ovl4),
+ ?l true=(N1>=1), % Overload check has been done!
+ ?l Node=node(),
+ ?l {ok,[{Node,{ok,{tracing,running}}}]}=inviso:get_status([node()]),
+ ?l true=ets:insert(inviso_sideeffect_tab,{ovl4_suspend,true}),
+ timer:sleep(600),
+ ?l {ok,[{Node,{ok,{tracing,{suspended,test}}}}]}=inviso:get_status([node()]),
+ ?l [{_,N2}]=ets:lookup(inviso_sideeffect_tab,ovl4),
+ ?l {flags,[]}=erlang:trace_info(whereis(inviso_test_proc),flags),
+ ?l {meta,false}=erlang:trace_info({lists,module_info,0},meta),
+ ?l {traced,local}=erlang:trace_info({code,which,1},traced),
+ ?l true=(is_pid(whereis(inviso_rt_meta))),
+ ?l true=ets:delete(inviso_sideeffect_tab,ovl4_suspend),
+ timer:sleep(600),
+ ?l [{_,N2}]=ets:lookup(inviso_sideeffect_tab,ovl4), % No checking while suspended!
+ ?l {ok,[{Node,ok}]}=inviso:cancel_suspension([node()]),
+ ?l {ok,NodeResults1}=inviso:get_status(Nodes),
+ ?l true=check_noderesults(Nodes,{ok,{tracing,running}},NodeResults1),
+ timer:sleep(600),
+ ?l [{_,N3}]=ets:lookup(inviso_sideeffect_tab,ovl4),
+ ?l true=(N3>N2),
+ ?l deactivate_local_tracing(Nodes),
+ ?l stop_tracing(Nodes),
+ ?l stop(Nodes),
+ ok.
+%% -----------------------------------------------------------------------------
+
+%% TEST CASE. Test that the overload mechanism is triggered by to the runtime
+%% component incomming messages, and nothing else.
+overload_dist_4(suite) -> [];
+overload_dist_4(doc) ->
+ [""];
+overload_dist_4(Config) when is_list(Config) ->
+ ?l {ok,_Pid1}=inviso:start(), % Start a control component.
+ RemoteNodes=get_remotenodes_config(Config),
+ Nodes=[node()|RemoteNodes],
+ ?l {ok,NodeResults1}=inviso:add_nodes(Nodes,
+ a_ref,
+ [{overload,{{?MODULE,overload5},
+ infinity,
+ {?MODULE,overload5i,[]},
+ {?MODULE,overload5r,[]}}}]),
+ ?l true=check_noderesults(Nodes,{ok,new},NodeResults1),
+ ?l [{_,0}]=ets:lookup(inviso_sideeffect_tab,ovl5),
+
+ PrivDir=filename:join(?config(priv_dir,Config),""),
+ TracerDataList=lists:map(fun(N)->{N,[{trace,
+ {file,filename:join([PrivDir,
+ "tf_ovl4."++atom_to_list(N)
+ ])}}]}
+ end,
+ Nodes),
+ ?l {ok,NodeResults2}=inviso:init_tracing(TracerDataList),
+ ?l true=check_noderesults(Nodes,{ok,[{trace_log,ok}]},NodeResults2),
+ timer:sleep(2000), % Give the loadcheck time to perform.
+ ?l [{_,N}]=ets:lookup(inviso_sideeffect_tab,ovl5),
+ ?l true=(N==0), % And nothing shall have happend!
+ %% Now we send a message to the inviso_rt, then the load check function
+ %% shall be called.
+ ?l whereis(inviso_rt) ! test_of_loadcheck,
+ timer:sleep(200), % Make sure the inviso_rt gets scheduled.
+ ?l [{_,1}]=ets:lookup(inviso_sideeffect_tab,ovl5),
+ stop_tracing(Nodes),
+ ?l []=ets:lookup(inviso_sideeffect_tab,ovl5r), % Remove function shall not be called.
+ ?l [{_,N3}]=ets:lookup(inviso_sideeffect_tab,ovl5),
+ ?l whereis(inviso_rt) ! test_of_loadcheck,
+ timer:sleep(1000), % Check that overloadchecking has stopped.
+ ?l [{_,N3}]=ets:lookup(inviso_sideeffect_tab,ovl5),
+ stop(Nodes),
+ ?l ok=poll(ets,lookup,[inviso_sideeffect_tab,ovl5r],[{ovl5r,done}],20),
+ ok.
+%% -----------------------------------------------------------------------------
+
+%% TEST CASE. Test that the overload mechanism correctly calculates remaining time
+%% to next load check if a message comes into the runtime component "interupting"
+%% the waiting for loadcheck timeout. (Loadcheck timeout is implemented as an after
+%% in the receive).
+overload_dist_5(suite) -> [];
+overload_dist_5(doc) ->
+ [""];
+overload_dist_5(Config) when is_list(Config) ->
+ ?l {ok,_Pid1}=inviso:start(), % Start a control component.
+ RemoteNodes=get_remotenodes_config(Config),
+ Nodes=[node()|RemoteNodes],
+ ?l lists:foreach(fun(N)->true=rpc:call(N,ets,insert,[inviso_sideeffect_tab,{ovl6,0}]) end,
+ Nodes), % Initiate the counter.
+ ?l {ok,NodeResults1}=inviso:add_nodes(Nodes,
+ a_ref,
+ [{overload,{{?MODULE,overload6},1000}}]),
+ ?l true=check_noderesults(Nodes,{ok,new},NodeResults1),
+ %% Overload check shall not start until we start tracing.
+ PrivDir=filename:join(?config(priv_dir,Config),""),
+ TracerDataList=lists:map(fun(N)->{N,[{trace,
+ {file,filename:join([PrivDir,
+ "tf_ovl5."++atom_to_list(N)
+ ])}}]}
+ end,
+ Nodes),
+ ?l {ok,NodeResults2}=inviso:init_tracing(TracerDataList),
+ ?l true=check_noderesults(Nodes,{ok,[{trace_log,ok}]},NodeResults2),
+ ?l ok=poll(ets,lookup,[inviso_sideeffect_tab,ovl6],[{ovl6,2}],25),
+ %% Now we know that exactly 2 checks have been made. Try to Distract the runtime :-)
+ ?l inviso_rt:state(whereis(inviso_rt)), % Make it have to receive a message.
+ timer:sleep(500),
+ ?l [{_,2}]=ets:lookup(inviso_sideeffect_tab,ovl6), % Should still be 2.
+ timer:sleep(600),
+ ?l [{_,3}]=ets:lookup(inviso_sideeffect_tab,ovl6), % We expect yet one check.
+ timer:sleep(1100),
+ ?l [{_,4}]=ets:lookup(inviso_sideeffect_tab,ovl6),
+
+ stop_tracing(Nodes),
+ stop(Nodes),
+ ok.
+%% -----------------------------------------------------------------------------
+
+
+%% TEST CASE: Test of the subscription mechanism.
+subscribe_dist_1(Config) when is_list(Config) ->
+ RemoteNodes=get_remotenodes_config(Config),
+ Nodes=[node()|RemoteNodes],
+ PrivDir=filename:join(?config(priv_dir,Config),""),
+ Pid=spawn(?MODULE,inviso_msg_collector,[]),
+ CtrlPid=whereis(inviso_c),
+
+ ?l {ok,_Pid}=inviso:start(), % Start a control component.
+ ?l ok=inviso:subscribe(Pid),
+ ?l {ok,NodeResults1}=inviso:add_nodes(Nodes,a_ref,[]),
+ ?l true=check_noderesults(Nodes,{ok,new},NodeResults1),
+ ?l {ok,NodeResults2}=inviso:get_status(Nodes),
+ ?l true=check_noderesults(Nodes,{ok,{new,running}},NodeResults2),
+ check_msg_collector(Nodes,
+ fun({inviso_event,CP,_,{connected,N,{_Tag,{idle,running}}}})
+ when CP==CtrlPid ->
+ {true,N};
+ (_) ->
+ false
+ end,
+ 13),
+ TracerDataList=lists:map(fun(N)->{N,{file,
+ filename:join([PrivDir,
+ "tf_sub1"++atom_to_list(N)])}}
+ end,
+ Nodes),
+ ?l {ok,NodeResults3}=inviso:init_tracing(TracerDataList),
+ ?l true=check_noderesults(Nodes,{ok,[{trace_log,ok}]},NodeResults3),
+ check_msg_collector(Nodes,
+ fun({inviso_event,CP,_,{state_change,N,{tracing,running}}})
+ when CP==CtrlPid ->
+ {true,N};
+ (_) ->
+ false
+ end,
+ 13),
+ ?l {ok,NodeResults4}=inviso:suspend(Nodes,test),
+ ?l true=check_noderesults(Nodes,ok,NodeResults4),
+ check_msg_collector(Nodes,
+ fun({inviso_event,CP,_,{state_change,N,{tracing,{suspended,test}}}})
+ when CP==CtrlPid ->
+ {true,N};
+ (_) ->
+ false
+ end,
+ 13),
+ ?l [RNode|_]=RemoteNodes,
+ ?l RInvisoPid=rpc:call(RNode,erlang,whereis,[inviso_rt]),
+ ?l rpc:call(RNode,erlang,exit,[RInvisoPid,kill]),
+ check_msg_collector([RNode],
+ fun({inviso_event,CP,_,{disconnected,N,_Info}})
+ when CP==CtrlPid ->
+ {true,N};
+ (_) ->
+ false
+ end,
+ 11),
+
+ ?l {ok,_NodeResults5}=inviso:stop_tracing(Nodes),
+ ?l {ok,_NodeResults6}=inviso:stop_nodes(Nodes),
+ ?l shutdown=inviso:stop(),
+ ok.
+%% -----------------------------------------------------------------------------
+
+
+%% TEST CASE: fetch_log test of single straight trace_log file in distributed
+%% environment.
+fetch_log_dist_trace_1(suite) -> [];
+fetch_log_dist_trace_1(doc) ->
+ ["fetch_log test of single straight trace_log file in distributed"
+ "environment."];
+fetch_log_dist_trace_1(Config) when is_list(Config) ->
+ RemoteNodes=get_remotenodes_config(Config),
+ Nodes=[node()|RemoteNodes],
+ PrivDir=filename:join(?config(priv_dir,Config),""),
+ TracerDataList=lists:map(fun(N)->{N,[{trace,{file,filename:join([PrivDir,
+ "testfile1."++
+ atom_to_list(N)
+ ])}}]} end,
+ Nodes),
+ start_and_init_tracing2(Nodes,[],TracerDataList,{ok,[{trace_log,ok}]}),
+
+ %% Put some output in the logs.
+ ?l inviso:tp(Nodes,math,module_info,0,[]),
+ ?l inviso:tf(Nodes,all,[call]),
+ ?l lists:foreach(fun(N)->rpc:call(N,math,module_info,[]) end,Nodes),
+
+ stop_tracing(Nodes),
+ {H,M,S}=time(),
+ FetchToDir=filename:join([PrivDir,
+ "fetch_log_test1_"++integer_to_list(H)++"_"++
+ integer_to_list(M)++"_"++integer_to_list(S)]),
+ ?l ok=file:make_dir(FetchToDir),
+ ?l {ok,NodeResults}=inviso:fetch_log(RemoteNodes,FetchToDir,"p1"),
+ io:format("~p~n",[NodeResults]),
+ ?l true=check_noderesults(RemoteNodes,
+ fun({N,{complete,[{trace_log,[{ok,File}]},{ti_log,[]}]}}) ->
+ ?l File="p1testfile1."++atom_to_list(N),
+ true;
+ (_)->
+ false
+ end,
+ NodeResults),
+ ?l ON=filename:join(PrivDir,"testfile1."),
+ ?l FN=filename:join(FetchToDir,"p1testfile1."),
+ ?l lists:foreach(fun(N)->
+ {ok,#file_info{size=Size}}=
+ file:read_file_info(ON++atom_to_list(N)),
+ {ok,#file_info{size=Size}}=
+ file:read_file_info(FN++atom_to_list(N))
+ end,
+ RemoteNodes),
+ %% Now we wish to see that we get an incomplete if we try to fetch to a
+ %% directory that does not exist.
+ ?l FetchToErrorDir=filename:join([PrivDir,nonexistingingdir]),
+ ?l {ok,NodeResults2}=inviso:fetch_log(RemoteNodes,FetchToErrorDir,"p1"),
+ ?l io:format("NodeResults2:~w~n",[NodeResults2]),
+ ?l true=check_noderesults(RemoteNodes,
+ fun({_,{incomplete,_}}) ->
+ true;
+ (_)->
+ false
+ end,
+ NodeResults2),
+ stop(Nodes),
+ ok.
+%% -----------------------------------------------------------------------------
+
+fetch_log_dist_trace_2(suite) -> [];
+fetch_log_dist_trace_2(doc) ->
+ [""];
+fetch_log_dist_trace_2(Config) ->
+ RemoteNodes=get_remotenodes_config(Config),
+ Nodes=[node()|RemoteNodes],
+ PrivDir=filename:join(?config(priv_dir,Config),""),
+
+ {H,M,S}=time(),
+ ?l Name="wrap"++integer_to_list(H)++"_"++integer_to_list(M)++"_"++integer_to_list(S),
+ ?l BaseName=filename:join(PrivDir,Name),
+ Fun=fun(N)->{N,[{trace,{file,{BaseName++atom_to_list(N),wrap,".log",512,2}}},
+ {ti,{file,BaseName++"_ti_"++atom_to_list(N)++".ti"}}]}
+ end,
+ ?l TracerDataList=lists:map(Fun,Nodes),
+ start_and_init_tracing2(Nodes,[],TracerDataList,{ok,[{trace_log,ok},{ti_log,ok}]}),
+ fill_and_reach_two_wrapfiles(PrivDir,"^"++Name,Nodes),
+
+ stop_tracing(Nodes),
+ FetchToDir=filename:join([PrivDir,
+ "fetch_log_test2_"++integer_to_list(H)++"_"++
+ integer_to_list(M)++"_"++integer_to_list(S)]),
+ ?l ok=file:make_dir(FetchToDir),
+ ?l {ok,NodeResults}=inviso:fetch_log(RemoteNodes,FetchToDir,"p1"),
+ io:format("~p~n",[NodeResults]),
+ CheckFun=fun({N,{complete,[{trace_log,FileResults1},{ti_log,[{ok,TiFile}]}]}}) ->
+ Fun2=fun({ok,File}) ->
+ {match,1,_}=
+ regexp:first_match(File,
+ "^"++"p1"++Name++atom_to_list(N)),
+ true;
+ (_) ->
+ false
+ end,
+ ?l true=lists:all(Fun2,FileResults1),
+ ?l TiFile="p1"++Name++"_ti_"++atom_to_list(N)++".ti",
+ true;
+ (_)->
+ false
+ end,
+ ?l true=check_noderesults(RemoteNodes,CheckFun,NodeResults),
+ stop(Nodes),
+ ok.
+%% -----------------------------------------------------------------------------
+
+fetch_log_dist_trace_3(suite) -> [];
+fetch_log_dist_trace_3(doc) ->
+ [""];
+fetch_log_dist_trace_3(Config) ->
+ RemoteNodes=get_remotenodes_config(Config),
+ Nodes=[node()|RemoteNodes],
+ PrivDir=filename:join(?config(priv_dir,Config),""),
+
+ {H,M,S}=time(),
+ ?l Name="wrap2_"++integer_to_list(H)++"_"++integer_to_list(M)++"_"++integer_to_list(S),
+ ?l BaseName=filename:join(PrivDir,Name),
+ Fun=fun(N)->{N,[{trace,{file,{BaseName++atom_to_list(N),wrap,".log",512,2}}},
+ {ti,{file,BaseName++"_ti_"++atom_to_list(N)++".ti"}}]}
+ end,
+ ?l TracerDataList=lists:map(Fun,Nodes),
+ start_and_init_tracing2(Nodes,[],TracerDataList,{ok,[{trace_log,ok},{ti_log,ok}]}),
+ fill_and_reach_two_wrapfiles(PrivDir,"^"++Name,Nodes),
+
+ stop_tracing(Nodes),
+ FetchToDir=filename:join([PrivDir,
+ "fetch_log_test3_"++integer_to_list(H)++"_"++
+ integer_to_list(M)++"_"++integer_to_list(S)]),
+ ?l ok=file:make_dir(FetchToDir),
+ ?l {ok,NodeResults1}=inviso:list_logs(Nodes),
+ CheckFun=fun({N,{ok,[{trace_log,PrivDir2,[F1,F2]},{ti_log,PrivDir2,[F3]}]}})->
+ PrivDir2=PrivDir,
+ RegExp="^"++Name++atom_to_list(N)++"[0-9]+"++"\.log",
+ {match,1,_}=regexp:first_match(F1,RegExp),
+ {match,1,_}=regexp:first_match(F2,RegExp),
+ F3=Name++"_ti_"++atom_to_list(N)++".ti",
+ true;
+ (_) ->
+ false
+ end,
+ ?l true=check_noderesults(Nodes,CheckFun,NodeResults1),
+ ?l NodeFileSpecList=lists:map(fun({N,{ok,L}})->{N,L} end,
+ lists:keydelete(node(),1,NodeResults1)),
+ ?l {ok,NodeResults2}=inviso:fetch_log(NodeFileSpecList,FetchToDir,"p1"),
+io:format("~p~n",[NodeResults2]),
+ CheckFun2=fun({N,{complete,[{trace_log,FileResults1},{ti_log,[{ok,TiFile}]}]}}) ->
+ Fun2=fun({ok,File}) ->
+ {match,1,_}=
+ regexp:first_match(File,
+ "^"++"p1"++Name++atom_to_list(N)),
+ true;
+ (_) ->
+ false
+ end,
+ ?l true=lists:all(Fun2,FileResults1),
+ ?l TiFile="p1"++Name++"_ti_"++atom_to_list(N)++".ti",
+ true;
+ (_)->
+ false
+ end,
+ ?l true=check_noderesults(RemoteNodes,CheckFun2,NodeResults2),
+ stop(Nodes),
+ ok.
+%% -----------------------------------------------------------------------------
+
+fetch_log_dist_error_1(suite) -> [];
+fetch_log_dist_error_1(doc) ->
+ [""];
+fetch_log_dist_error_1(Config) when is_list(Config) ->
+ RemoteNodes=get_remotenodes_config(Config),
+ Nodes=[node()|RemoteNodes],
+ ?l {ok,_Pid}=inviso:start(), % Start a control component.
+ ?l {ok,NodeResults1}=inviso:add_nodes(Nodes,a_ref),
+ ?l true=check_noderesults(Nodes,{ok,new},NodeResults1),
+ ?l {ok,NodeResults2}=inviso:fetch_log(RemoteNodes,"foo","bar"),
+io:format("~p~n",[NodeResults2]),
+ ?l true=check_noderesults(RemoteNodes,
+ fun({_N,{error,no_tracerdata}})->true;
+ (_)->false
+ end,
+ NodeResults2),
+ stop(Nodes),
+ ok.
+%% -----------------------------------------------------------------------------
+
+fetch_log_dist_error_2(suite) -> [];
+fetch_log_dist_error_2(doc) ->
+ [""];
+fetch_log_dist_error_2(Config) when is_list(Config) ->
+ RemoteNodes=get_remotenodes_config(Config),
+ Nodes=[node()|RemoteNodes],
+ PrivDir=filename:join(?config(priv_dir,Config),""),
+ ?l {ok,_Pid}=inviso:start(), % Start a control component.
+ ?l {ok,NodeResults1}=inviso:add_nodes(Nodes,a_ref),
+ ?l true=check_noderesults(Nodes,{ok,new},NodeResults1),
+ ?l NodeLogList=lists:map(fun(N)->{N,[{trace_log,
+ PrivDir,
+ ["f1,fil","f2.fil"]},
+ {ti_log,
+ PrivDir,
+ ["f.ti"]}]}
+ end,
+ RemoteNodes),
+ ?l {ok,NodeResults2}=inviso:fetch_log(NodeLogList,"foo","bar"),
+ io:format("~p~n",[NodeResults2]),
+ ?l true=check_noderesults(RemoteNodes,
+ fun({_N,{incomplete,_}}) ->
+ true;
+ (_) ->
+ false
+ end,
+ NodeResults2),
+ ?l NodeTracerData=lists:map(fun(N)->{N,
+ [{trace,{file,filename:join(PrivDir,"foo")}},
+ {ti,{file,filename:join(PrivDir,"bar.ti")}}]}
+ end,
+ RemoteNodes),
+ {ok,NodeResults3}=inviso:fetch_log(NodeTracerData,"foo","bar"),
+ io:format("~p~n",[NodeResults3]),
+%% This should work this way. Now it says complete [], which is not entirely
+%% incorrect. But to follow the sematics of when fetching named files should
+%% say incomplete.
+%% Must do some rework to make that work. No real danger leaving it this way
+%% for now.
+% ?l true=check_noderesults(RemoteNodes,
+% fun({_N,{incomplete,_}}) ->
+% true;
+% (_) ->
+% false
+% end,
+% NodeResults3),
+ stop(Nodes),
+ ok.
+%% -----------------------------------------------------------------------------
+
+%% TEST CASE: This case tests that the log file merger merges files in the
+%% correct order, based on the timestamps.
+lfm_trace_dist_1(suite) -> [];
+lfm_trace_dist_1(doc) ->
+ [""];
+lfm_trace_dist_1(Config) when is_list(Config) ->
+ RemoteNodes=get_remotenodes_config(Config),
+ Nodes=[node()|RemoteNodes],
+ [RNode1,RNode2|_]=RemoteNodes,
+ PrivDir=filename:join(?config(priv_dir,Config),""),
+ TracerDataList=
+ lists:map(fun(N)->{N,{file,filename:join([PrivDir,"lfm1_"++atom_to_list(N)])}} end,
+ Nodes),
+ start_and_init_tracing2(Nodes,[],TracerDataList,{ok,[{trace_log,ok}]}),
+ activate_local_tracing(Nodes),
+ activate_traceflags(Nodes),
+
+ {inviso_test_proc,RNode2} ! {apply,code,which,[lists]},
+ timer:sleep(300),
+ {inviso_test_proc,RNode1} ! {apply,code,which,[lists]},
+ timer:sleep(300),
+ {inviso_test_proc,RNode1} ! {apply,code,which,[lists]},
+ timer:sleep(300),
+ inviso_test_proc ! {apply,code,which,[lists]},
+ timer:sleep(300),
+ {inviso_test_proc,RNode2} ! {apply,code,which,[lists]},
+ timer:sleep(300),
+ inviso_test_proc ! {apply,code,which,[lists]},
+
+ deactivate_traceflags(Nodes),
+ deactivate_local_tracing(Nodes),
+ stop_tracing(Nodes),
+ stop(Nodes),
+
+ DestFile=filename:join(PrivDir,"lfm1_out.txt"),
+ ?l {ok,6}=
+ inviso_lfm:merge([{node(),
+ [{trace_log,
+ [filename:join(PrivDir,"lfm1_"++atom_to_list(node()))]}]},
+ {RNode1,
+ [{trace_log,
+ [filename:join(PrivDir,"lfm1_"++atom_to_list(RNode1))]}]},
+ {RNode2,
+ [{trace_log,
+ [filename:join(PrivDir,"lfm1_"++atom_to_list(RNode2))]}]}],
+ DestFile),
+ ?l {ok,FD}=file:open(DestFile,[read]),
+ ?l S1=io:get_line(FD,""),
+ ?l true=lists:prefix(atom_to_list(RNode2),S1),
+ ?l S2=io:get_line(FD,""),
+ ?l true=lists:prefix(atom_to_list(RNode1),S2),
+ ?l S3=io:get_line(FD,""),
+ ?l true=lists:prefix(atom_to_list(RNode1),S3),
+ ?l S4=io:get_line(FD,""),
+ ?l true=lists:prefix(atom_to_list(node()),S4),
+ ?l S5=io:get_line(FD,""),
+ ?l true=lists:prefix(atom_to_list(RNode2),S5),
+ ?l S6=io:get_line(FD,""),
+ ?l true=lists:prefix(atom_to_list(node()),S6),
+ ?l file:close(FD),
+ ok.
+%% -----------------------------------------------------------------------------
+
+%% TEST CASE: Testing to the full extent that pid-mappings work with both
+%% local and global registration. Also checks that pidmappings can be removed
+%% and that consequently the mappings in the resulting merged file stops.
+lfm_trace_ti_dist_2(suite) -> [];
+lfm_trace_ti_dist_2(doc) ->
+ [""];
+lfm_trace_ti_dist_2(Config) when is_list(Config) ->
+ RemoteNodes=get_remotenodes_config(Config),
+ Nodes=[node()|RemoteNodes],
+ [RNode1,RNode2|_]=RemoteNodes,
+ PrivDir=filename:join(?config(priv_dir,Config),""),
+ TracerDataList=
+ lists:map(fun(N)->{N,[{trace,{file,filename:join(PrivDir,"lfm2_"++atom_to_list(N))}},
+ {ti,{file,filename:join(PrivDir,"lfm2_ti_"++atom_to_list(N))}}]}
+ end,
+ Nodes),
+ start_and_init_tracing2(Nodes,[],TracerDataList,{ok,[{trace_log,ok},{ti_log,ok}]}),
+ activate_local_tracing(Nodes),
+ activate_meta_tracing(Nodes),
+ activate_traceflags(Nodes),
+
+ {inviso_test_proc,RNode2} ! {apply,code,which,[lists]},
+ timer:sleep(300),
+ {inviso_test_proc,RNode1} ! {apply,code,which,[lists]},
+ timer:sleep(300),
+ {inviso_test_proc,RNode1} ! {apply,code,which,[lists]},
+ timer:sleep(300),
+ inviso_test_proc ! {apply,code,which,[lists]},
+ timer:sleep(300),
+
+ P2=spawn(RNode2,?MODULE,test_proc_loop,[]),
+ P1=spawn(RNode1,?MODULE,test_proc_loop,[]),
+ P0=spawn_link(?MODULE,test_proc_loop,[]),
+ ThisNode=node(),
+ ?l {ok,[{ThisNode,{ok,[1]}}]}=inviso:tf([node()],P0,[call,timestamp]),
+ ?l {ok,[{RNode1,{ok,[1]}}]}=inviso:tf([RNode1],P1,[call,timestamp]),
+ ?l {ok,[{RNode2,{ok,[1]}}]}=inviso:tf([RNode2],P2,[call,timestamp]),
+ P2 ! {apply,code,which,[lists]},
+ timer:sleep(300),
+ P1 ! {apply,code,which,[lists]},
+ timer:sleep(300),
+ P0 ! {apply,code,which,[lists]},
+ timer:sleep(300),
+
+ P3=spawn(RNode2,?MODULE,test_proc_loop,[]),
+ ?l yes=global:register_name(inviso_test_proc_globalname,P3),
+ ?l {ok,[{RNode2,{ok,[1]}}]}=inviso:tf([RNode2],P3,[call,timestamp]),
+ timer:sleep(300),
+ P3 ! {apply,code,which,[lists]},
+ timer:sleep(300),
+
+ P4=rpc:call(RNode1,erlang,whereis,[inviso_test_proc]),
+ ?l true=rpc:call(RNode1,erlang,unregister,[inviso_test_proc]),
+ timer:sleep(300),
+ P4 ! {apply,code,which,[lists]},
+ timer:sleep(300),
+
+ ?l true=rpc:call(RNode1,erlang,register,[inviso_test_proc,P4]),
+
+ ?l global:unregister_name(inviso_test_proc_globalname),
+ timer:sleep(300),
+ ?l P3 ! {apply,code,which,[lists]},
+ timer:sleep(300),
+
+ deactivate_traceflags(Nodes),
+ deactivate_local_tracing(Nodes),
+ stop_tracing(Nodes),
+ stop(Nodes),
+
+ DestFile=filename:join(PrivDir,"lfm2_out.txt"),
+ ?l {ok,10}=
+ inviso_lfm:merge([
+ {node(),
+ [{trace_log,
+ [filename:join(PrivDir,"lfm2_"++atom_to_list(node()))]},
+ {ti_log,
+ [filename:join(PrivDir,"lfm2_ti_"++atom_to_list(node()))]}]},
+ {RNode1,
+ [{trace_log,
+ [filename:join(PrivDir,"lfm2_"++atom_to_list(RNode1))]},
+ {ti_log,
+ [filename:join(PrivDir,"lfm2_ti_"++atom_to_list(RNode1))]}]},
+ {RNode2,
+ [{trace_log,
+ [filename:join(PrivDir,"lfm2_"++atom_to_list(RNode2))]},
+ {ti_log,
+ [filename:join(PrivDir,"lfm2_ti_"++atom_to_list(RNode2))]}]}
+ ],
+ DestFile),
+ ?l {ok,FD}=file:open(DestFile,[read]),
+ ?l S1=io:get_line(FD,""),
+io:format("S1 is:~p~n",[S1]),
+ ?l true=lists:prefix(atom_to_list(RNode2)++" [inviso_test_proc",S1),
+ ?l S2=io:get_line(FD,""),
+ ?l true=lists:prefix(atom_to_list(RNode1)++" [inviso_test_proc",S2),
+ ?l S3=io:get_line(FD,""),
+ ?l true=lists:prefix(atom_to_list(RNode1)++" [inviso_test_proc",S3),
+ ?l S4=io:get_line(FD,""),
+ ?l true=lists:prefix(atom_to_list(node())++" [inviso_test_proc",S4),
+ ?l S5=io:get_line(FD,""),
+ ?l true=lists:prefix(atom_to_list(RNode2)++" []",S5),
+ ?l S6=io:get_line(FD,""),
+ ?l true=lists:prefix(atom_to_list(RNode1)++" []",S6),
+ ?l S7=io:get_line(FD,""),
+ ?l true=lists:prefix(atom_to_list(node())++" []",S7),
+ ?l S8=io:get_line(FD,""),
+ ?l true=lists:prefix(atom_to_list(RNode2)++" [{global,inviso_test_proc_globalname}]",S8),
+ ?l S9=io:get_line(FD,""),
+ ?l true=lists:prefix(atom_to_list(RNode1)++" []",S9),
+ ?l S10=io:get_line(FD,""),
+ ?l true=lists:prefix(atom_to_list(RNode2)++" []",S10),
+ ?l file:close(FD),
+ ok.
+%% -----------------------------------------------------------------------------
+
+%% TEST CASE: This tests that the wrapset sorter works.
+handle_logfile_sort_wrapset(suite) -> [];
+handle_logfile_sort_wrapset(doc) ->
+ [""];
+handle_logfile_sort_wrapset(Config) when is_list(Config) ->
+ File0="prefix10.fil",
+ File1="prefix11.fil",
+ File2="prefix12.fil",
+ File3="prefix13.fil",
+ ?l [File0,File1,File2,File3]=
+ inviso_lfm_tpfreader:handle_logfile_sort_wrapset([File2,File1,File0,File3]),
+ File5="prefix15.fil",
+ ?l [File5,File0,File1,File2,File3]=
+ inviso_lfm_tpfreader:handle_logfile_sort_wrapset([File2,File5,File1,File0,File3]),
+ ok.
+%% -----------------------------------------------------------------------------
+
+%% TEST CASE: This case tests that the regexp mechanism in the inviso_rt_lib can
+%% find modules using regexps and that its only_loaded mechanism works.
+%% This test case can not be run when using cover because cover will make the
+%% modules no longer loaded from the path containing "runtime_tools".
+expand_regexp_dist_1(suite) -> [];
+expand_regexp_dist_1(doc) ->
+ [""];
+expand_regexp_dist_1(Config) when is_list(Config) ->
+ case ?t:is_cover() of
+ true ->
+ {skip,"Cover is running"};
+ false ->
+ expand_regexp_dist_1_nocover(Config)
+ end.
+
+expand_regexp_dist_1_nocover(Config) ->
+ RemoteNodes=get_remotenodes_config(Config),
+ Nodes=[node()|RemoteNodes],
+ [RNode1|_]=RemoteNodes,
+ ?l NodeResults1=inviso_rt_lib:expand_regexp(Nodes,"^inviso_rt.*",[]),
+ ?l L1=length(Nodes),
+ ?l L1=length(NodeResults1),
+ ?l true=lists:all(fun({_,Mods})->
+ ?l 3=length(Mods),
+ ?l true=lists:member(inviso_rt,Mods),
+ ?l true=lists:member(inviso_rt_lib,Mods),
+ ?l true=lists:member(inviso_rt_meta,Mods),
+ true;
+ (_) ->
+ false
+ end,
+ NodeResults1),
+ %% Check the dir-option. In the following inviso_tool_lib shall not be found.
+ ?l NodeResults2=inviso_rt_lib:expand_regexp(Nodes,"runtime_tools","invi.*lib.*",[]),
+?l io:format("NodeResults2:~w~n",[NodeResults2]),
+ ?l L1=length(NodeResults2), % Same number of nodes replying.
+ ?l true=lists:all(fun({_,Mods})->
+ 2=length(Mods),
+ true=lists:member(inviso_as_lib,Mods),
+ true=lists:member(inviso_rt_lib,Mods),
+ true;
+ (_) ->
+ false
+ end,
+ NodeResults2),
+ ?l [{RNode1,[]}]=
+ inviso_rt_lib:expand_regexp([RNode1],"^inviso_testmodule1.*",[only_loaded]),
+ ?l [{RNode1,[inviso_testmodule1_foo]}]=
+ inviso_rt_lib:expand_regexp([RNode1],"^inviso_testmodule1.*",[]),
+ ok.
+%% -----------------------------------------------------------------------------
+
+
+only_loaded_dist_1(suite) -> [];
+only_loaded_dist_1(doc) ->
+ [""];
+only_loaded_dist_1(Config) when is_list(Config) ->
+ RemoteNodes=get_remotenodes_config(Config),
+ Nodes=[node()|RemoteNodes],
+ [RNode1|_]=RemoteNodes,
+ PrivDir=filename:join(?config(priv_dir,Config),""),
+ TracerDataList=
+ lists:map(fun(N)->{N,[{trace,{file,filename:join(PrivDir,"ol_1_"++atom_to_list(N))}}]}
+ end,
+ Nodes),
+ start_and_init_tracing2(Nodes,[],TracerDataList,{ok,[{trace_log,ok}]}),
+ ?l false=rpc:call(RNode1,erlang,module_loaded,[inviso_testmodule1_foo]),
+ ?l {ok,[{RNode1,{ok,[0]}}]}=
+ inviso:tpl([RNode1],inviso_testmodule1_foo,'_','_',[],[only_loaded]),
+ ?l false=rpc:call(RNode1,erlang,module_loaded,[inviso_testmodule1_foo]),
+ ?l {ok,[{RNode1,{ok,[3]}}]}=
+ inviso:tpl([RNode1],inviso_testmodule1_foo,'_','_',[],[]),
+ stop_tracing(Nodes),
+ stop(Nodes),
+ ok.
+
+
+%% ==============================================================================
+%% Common functions setting up inviso.
+%% ==============================================================================
+
+%% Starts controlcomponent and adds runtime components on the nodes specified.
+%% Also initiates tracing on the nodes.
+start_and_init_tracing1(Nodes,Options,TracerData,Reply) when is_list(Nodes) ->
+ ?l {ok,_Pid}=inviso:start(), % Start a control component.
+ ?l {ok,NodeResults1}=inviso:add_nodes(Nodes,a_ref,Options),
+ io:format("~p~n",[NodeResults1]),
+ ?l true=check_noderesults(Nodes,{ok,new},NodeResults1),
+ ?l {ok,NodeResults2}=inviso:get_status(Nodes),
+ ?l true=check_noderesults(Nodes,{ok,{new,running}},NodeResults2),
+ ?l {ok,NodeResults3}=inviso:init_tracing(Nodes,TracerData),
+ ?l true=check_noderesults(Nodes,Reply,NodeResults3),
+ ok.
+start_and_init_tracing2(Nodes,Options,TracerDataList,Reply) ->
+ ?l {ok,_Pid}=inviso:start(), % Start a control component.
+ ?l {ok,NodeResults1}=inviso:add_nodes(Nodes,a_ref,Options),
+ io:format("~p~n",[NodeResults1]),
+ ?l true=check_noderesults(Nodes,{ok,new},NodeResults1),
+ ?l {ok,NodeResults2}=inviso:get_status(Nodes),
+ ?l true=check_noderesults(Nodes,{ok,{new,running}},NodeResults2),
+ ?l {ok,NodeResults4}=inviso:get_tracerdata(Nodes),
+ ?l true=check_noderesults(Nodes,{ok,no_tracerdata},NodeResults4),
+ ?l {ok,NodeResults3}=inviso:init_tracing(TracerDataList),
+ io:format("Tracerdatalist:~p~n",[TracerDataList]),
+ ?l true=check_noderesults(Nodes,Reply,NodeResults3),
+
+ ?l Fun1=fun({N,{ok,TD}}) when is_list(TD)->
+ ?l {value,{trace,Trace}}=lists:keysearch(trace,1,TD),
+ ?l {value,{N,TD2}}=lists:keysearch(N,1,TracerDataList),
+ ?l true=lists:member({trace,Trace},TD2),
+ %% Check that the trace file really exists.
+ ?l case Trace of % Trace={file,FilePortParameters}
+ {file,FileName1} when is_list(FileName1) ->
+ ?l {ok,_}=rpc:call(N,file,read_file_info,[FileName1]);
+ _ -> % This should be extended with more cases.
+ true
+ end,
+ ?l case lists:keysearch(ti,1,TD2) of
+ {value,{_,Ti}} -> % Ok, we have ti too.
+ ?l {value,{_,Ti}}=lists:keysearch(ti,1,TD),
+ ?l FileName2=element(2,Ti),
+ ?l {ok,_}=rpc:call(N,file,read_file_info,[FileName2]),
+ true;
+ false -> % No ti, we are done now.
+ true
+ end;
+ ({N,{ok,{file,FileName}}}) ->
+ ?l {value,{N,{file,FileName}}}=lists:keysearch(N,1,TracerDataList),
+ ?l {ok,_}=rpc:call(N,file,read_file_info,[FileName]),
+ true;
+ ({N,{ok,LogTD}}) -> % The case using a fun.
+ ?l {value,{N,LogTD}}=lists:keysearch(N,1,TracerDataList),
+ true
+ end,
+ ?l {ok,NodeResults5}=inviso:get_tracerdata(Nodes),
+ ?l true=check_noderesults(Nodes,Fun1,NodeResults5),
+ ok.
+%% ------------------------------------------------------------------------------
+
+%% Stops tracing on Nodes.
+stop_tracing(Nodes) when is_list(Nodes) ->
+ ?l {ok,NodeResults1}=inviso:stop_tracing(Nodes),
+ ?l true=check_noderesults(Nodes,{ok,idle},NodeResults1),
+ ?l {ok,NodeResults2}=inviso:get_status(Nodes),
+ ?l true=check_noderesults(Nodes,{ok,{idle,running}},NodeResults2),
+ %% The implementation says that the meta tracer shall be stopped when
+ %% tracing is stopped. Check that.
+ ?l lists:foreach(fun(N)->
+ ok=poll(erlang,whereis,[inviso_rt_meta],undefined,20)
+ end,
+ Nodes).
+%% ------------------------------------------------------------------------------
+
+%% Stops the runtime components on Nodes and stops the control component at this
+%% Erlang node.
+stop(Nodes) when is_list(Nodes) ->
+ ?l true=check_on_nodes(Nodes,erlang,whereis,[inviso_rt],fun(P) when is_pid(P)->true end),
+ ?l {ok,NodeResults}=inviso:stop_nodes(Nodes),
+ ?l true=check_noderesults(Nodes,ok,NodeResults),
+ ?l true=check_on_nodes(Nodes,erlang,whereis,[inviso_rt],fun(undefined)->true end),
+ ?l true=is_pid(whereis(inviso_c)),
+ ?l shutdown=inviso:stop(),
+ ?l ok=poll(erlang,whereis,[inviso_c],undefined,20).
+%% ------------------------------------------------------------------------------
+
+%% Help function activating local tracing.
+activate_local_tracing(Nodes) when is_list(Nodes) ->
+ ?l true=check_on_nodes(Nodes,
+ erlang,
+ trace_info,
+ [{code,which,1},traced],
+ {traced,false}),
+ ?l {ok,NodeResults}=inviso:tpl(Nodes,code,which,1,[]),
+ ?l true=check_noderesults(Nodes,fun({_,{ok,[1]}})->true end,NodeResults),
+ ?l true=check_on_nodes(Nodes,
+ erlang,
+ trace_info,
+ [{code,which,1},traced],
+ {traced,local}).
+%% ------------------------------------------------------------------------------
+
+%% Help function activating global tracing.
+activate_global_tracing(Nodes) when is_list(Nodes) ->
+ ?l true=check_on_nodes(Nodes,
+ erlang,
+ trace_info,
+ [{code,get_path,0},traced],
+ {traced,false}),
+ ?l {ok,NodeResults}=inviso:tp(Nodes,code,get_path,0,[]),
+ ?l true=check_noderesults(Nodes,fun({_,{ok,[1]}})->true end,NodeResults),
+ ?l true=check_on_nodes(Nodes,
+ erlang,
+ trace_info,
+ [{code,get_path,0},traced],
+ {traced,global}).
+%% ------------------------------------------------------------------------------
+
+
+%% Help function activating local tracing and using a regexp to point out modules.
+%% Returns the structure of modules and functions that were activated. Must be used
+%% when deactivating.
+activate_global_tracing_regexp(Nodes) when is_list(Nodes) ->
+ %% First find out which modules will be effected.
+ ?l Mods1=inviso_rt_lib:expand_regexp("application.*",[]),
+ ?l true=(length(Mods1)>1), % Should find more than one module!
+ ?l Funcs1=lists:foldl(fun(M,Acc)->[{M,M:module_info(exports)}|Acc] end,[],Mods1),
+ %% Check that these functions are not traced.
+ io:format("Modules:~w~n",[Mods1]),
+ ?l {ok,NodeResults}=inviso:tp(Nodes,"application.*",'_','_',[],[]),
+ io:format("Here 2~w~n",[NodeResults]),
+ ?l N=lists:foldl(fun({_,L1},A1)->lists:foldl(fun(_,A2)->A2+1 end,A1,L1) end,0,Funcs1),
+ ?l true=check_noderesults(Nodes,fun({_,{ok,L}})-> N==lists:sum(L) end,NodeResults),
+ io:format("Here 3~n",[]),
+ %% Check again!
+ ?l lists:foreach(fun({M,Funcs})->
+ lists:foreach(fun({F,Arity})->
+ true=check_on_nodes(Nodes,
+ erlang,
+ trace_info,
+ [{M,F,Arity},traced],
+ {traced,global})
+ end,
+ Funcs)
+ end,
+ Funcs1),
+ Funcs1.
+%% ------------------------------------------------------------------------------
+
+%% Help function as above but uses the dir feature as well.
+activate_global_tracing_regexp_dir(Nodes) when is_list(Nodes) ->
+ %% First find out which modules will be effected.
+ ?l Mods1=inviso_rt_lib:expand_regexp(".*kernel.*","application.*",[]),
+ ?l true=(length(Mods1)>1), % Should find more than one module!
+ ?l Funcs1=lists:foldl(fun(M,Acc)->[{M,M:module_info(exports)}|Acc] end,[],Mods1),
+ %% Check that these functions are not traced.
+ io:format("Modules:~w~n",[Mods1]),
+ ?l {ok,NodeResults}=inviso:tp(Nodes,{".*kernel.*","application.*"},'_','_',[],[]),
+ io:format("Here 2~w~n",[NodeResults]),
+ ?l N=lists:foldl(fun({_,L1},A1)->lists:foldl(fun(_,A2)->A2+1 end,A1,L1) end,0,Funcs1),
+ ?l true=check_noderesults(Nodes,fun({_,{ok,L}})-> N==lists:sum(L) end,NodeResults),
+ io:format("Here 3~n",[]),
+ %% Check again!
+ ?l lists:foreach(fun({M,Funcs})->
+ lists:foreach(fun({F,Arity})->
+ true=check_on_nodes(Nodes,
+ erlang,
+ trace_info,
+ [{M,F,Arity},traced],
+ {traced,global})
+ end,
+ Funcs)
+ end,
+ Funcs1),
+ Funcs1.
+%% ------------------------------------------------------------------------------
+
+deactivate_local_tracing(Nodes) when is_list(Nodes) ->
+ ?l true=check_on_nodes(Nodes,
+ erlang,
+ trace_info,
+ [{code,which,1},traced],
+ {traced,local}),
+ ?l {ok,NodeResults}=inviso:ctpl(Nodes,code,'_','_'),
+ ?l true=check_noderesults(Nodes,fun({_,{ok,[N]}})when is_integer(N)->true end,NodeResults),
+ ?l true=check_on_nodes(Nodes,
+ erlang,
+ trace_info,
+ [{code,which,1},traced],
+ {traced,false}).
+%% ------------------------------------------------------------------------------
+
+deactivate_global_tracing(Nodes) when is_list(Nodes) ->
+ ?l true=check_on_nodes(Nodes,
+ erlang,
+ trace_info,
+ [{code,get_path,0},traced],
+ {traced,global}),
+ ?l {ok,NodeResults}=inviso:ctp(Nodes,code,'_','_'),
+ ?l true=check_noderesults(Nodes,fun({_,{ok,[N]}})when is_integer(N)->true end,NodeResults),
+ ?l true=check_on_nodes(Nodes,
+ erlang,
+ trace_info,
+ [{code,get_path,0},traced],
+ {traced,false}).
+%% ------------------------------------------------------------------------------
+
+
+%% Function deactivating the functions activated by activate_global_tracing_regexp/1.
+deactivate_global_tracing_regexp(Nodes,Funcs1) ->
+ ?l lists:foreach(fun({M,Funcs})->
+ lists:foreach(fun({F,Arity})->
+ true=check_on_nodes(Nodes,
+ erlang,
+ trace_info,
+ [{M,F,Arity},traced],
+ {traced,global})
+ end,
+ Funcs)
+ end,
+ Funcs1),
+ ?l {ok,NodeResults}=inviso:ctp(Nodes,"application.*",'_','_'),
+ ?l N=lists:foldl(fun({_,L1},A1)->lists:foldl(fun(_,A2)->A2+1 end,A1,L1) end,0,Funcs1),
+ io:format("Noderesult from deactivate;~w~n",[NodeResults]),
+ ?l true=check_noderesults(Nodes,fun({_,{ok,L}})-> N==lists:sum(L) end,NodeResults),
+ ?l lists:foreach(fun({M,Funcs})->
+ lists:foreach(fun({F,Arity})->
+ true=check_on_nodes(Nodes,
+ erlang,
+ trace_info,
+ [{M,F,Arity},traced],
+ {traced,false})
+ end,
+ Funcs)
+ end,
+ Funcs1).
+%% ------------------------------------------------------------------------------
+
+%% Function deactivating the functions activated by activate_global_tracing_regexp_dir/1.
+deactivate_global_tracing_regexp_dir(Nodes,Funcs1) ->
+ ?l lists:foreach(fun({M,Funcs})->
+ lists:foreach(fun({F,Arity})->
+ true=check_on_nodes(Nodes,
+ erlang,
+ trace_info,
+ [{M,F,Arity},traced],
+ {traced,global})
+ end,
+ Funcs)
+ end,
+ Funcs1),
+ ?l {ok,NodeResults}=inviso:ctp(Nodes,{".*kernel.*","application.*"},'_','_'),
+ ?l N=lists:foldl(fun({_,L1},A1)->lists:foldl(fun(_,A2)->A2+1 end,A1,L1) end,0,Funcs1),
+ io:format("Noderesult from deactivate;~w~n",[NodeResults]),
+ ?l true=check_noderesults(Nodes,fun({_,{ok,L}})-> N==lists:sum(L) end,NodeResults),
+ ?l lists:foreach(fun({M,Funcs})->
+ lists:foreach(fun({F,Arity})->
+ true=check_on_nodes(Nodes,
+ erlang,
+ trace_info,
+ [{M,F,Arity},traced],
+ {traced,false})
+ end,
+ Funcs)
+ end,
+ Funcs1).
+%% ------------------------------------------------------------------------------
+
+%% Help function which starts the inviso_test_proc on all nodes and then sets
+%% the call flag on that process.
+activate_traceflags(Nodes) ->
+ ?l lists:foreach(fun(N)->spawn(N,?MODULE,test_proc_init,[]) end,Nodes),
+ ?l lists:foreach(fun(N)->
+ P=rpc:call(N,erlang,whereis,[inviso_test_proc]),
+ {flags,[]}=rpc:call(N,erlang,trace_info,[P,flags])
+ end,
+ Nodes),
+ ?l {ok,NodeResults}=inviso:tf(Nodes,inviso_test_proc,[call,timestamp]),
+ ?l true=check_noderesults(Nodes,{ok,[1]},NodeResults),
+ ?l lists:foreach(fun(N)->
+ P=rpc:call(N,erlang,whereis,[inviso_test_proc]),
+ {flags,Flags}=rpc:call(N,erlang,trace_info,[P,flags]),
+ true=lists:member(call,Flags),
+ true=lists:member(timestamp,Flags)
+ end,
+ Nodes),
+ %% Now try a globally registered process.
+ ?l [ANode|_]=Nodes,
+ ?l GPid=spawn(ANode,?MODULE,global_test_proc_init,[]),
+ ?l ok=poll(global,whereis_name,[global_inviso_test_proc],
+ fun(P) when is_pid(P)->true;(_)->false end,
+ 10),
+ ?l {ok,NodeResults2}=
+ inviso:tf(Nodes,{global,global_inviso_test_proc},[call,timestamp]),
+ ?l true=check_noderesults(Nodes,
+ fun({N,{ok,[1]}}) when N==ANode->true;
+ ({_,{ok,[0]}})->true;
+ (_)->false
+ end,
+ NodeResults2),
+ ?l {flags,Flags2}=rpc:call(ANode,erlang,trace_info,[GPid,flags]),
+ ?l 2=length(Flags2),
+ ?l true=lists:member(call,Flags2),
+ ?l true=lists:member(timestamp,Flags2),
+ true.
+%% ------------------------------------------------------------------------------
+
+deactivate_traceflags(Nodes) ->
+ ?l lists:foreach(fun(N)->
+ P=rpc:call(N,erlang,whereis,[inviso_test_proc]),
+ {flags,Flags}=rpc:call(N,erlang,trace_info,[P,flags]),
+ true=lists:member(call,Flags),
+ true=lists:member(timestamp,Flags)
+ end,
+ Nodes),
+ ?l {ok,NodeResults}=inviso:ctf(Nodes,inviso_test_proc,[call,timestamp]),
+ ?l true=check_noderesults(Nodes,{ok,[1]},NodeResults),
+ ?l lists:foreach(fun(N)->
+ P=rpc:call(N,erlang,whereis,[inviso_test_proc]),
+ {flags,[]}=rpc:call(N,erlang,trace_info,[P,flags])
+ end,
+ Nodes),
+ ?l GPid=global:whereis_name(global_inviso_test_proc),
+ ?l ANode=node(GPid),
+ ?l {flags,Flags2}=rpc:call(ANode,erlang,trace_info,[GPid,flags]),
+ ?l 2=length(Flags2),
+ ?l {ok,NodeResults2}=inviso:ctf(Nodes,{global,global_inviso_test_proc},[call,timestamp]),
+ ?l true=check_noderesults(Nodes,
+ fun({N,{ok,[1]}}) when N==ANode->true;
+ ({_,{ok,[0]}})->true;
+ (_)->false
+ end,
+ NodeResults2).
+%% ------------------------------------------------------------------------------
+
+
+activate_meta_tracing(Nodes) ->
+ ?l {ok,NodeResults1}=inviso:tpm_localnames(),
+ ?l true=check_noderesults(Nodes,{{ok,1},{ok,1}},NodeResults1),
+ ?l lists:foreach(fun(N)->P=rpc:call(N,erlang,whereis,[inviso_rt_meta]),
+ {meta,P}=rpc:call(N,erlang,trace_info,[{erlang,register,2},meta])
+ end,
+ Nodes),
+ ?l lists:foreach(fun(N)->P=rpc:call(N,erlang,whereis,[inviso_rt_meta]),
+ {meta,P}=rpc:call(N,erlang,trace_info,[{erlang,unregister,1},meta])
+ end,
+ Nodes),
+ ?l {ok,NodeResults2}=inviso:tpm_globalnames(),
+ ?l true=check_noderesults(Nodes,{{ok,1},{ok,1}},NodeResults2),
+ ?l lists:foreach(fun(N)->P=rpc:call(N,erlang,whereis,[inviso_rt_meta]),
+ {meta,P}=rpc:call(N,
+ erlang,
+ trace_info,
+ [{global,handle_call,3},meta])
+ end,
+ Nodes),
+ ?l lists:foreach(fun(N)->P=rpc:call(N,erlang,whereis,[inviso_rt_meta]),
+ {meta,P}=rpc:call(N,
+ erlang,
+ trace_info,
+ [{global,delete_global_name,2},meta])
+ end,
+ Nodes),
+
+ ?l lists:foreach(fun(N)->true=rpc:call(N,
+ ets,
+ insert,
+ [inviso_sideeffect_tab,{tpm_init_func1,0}]),
+ true=rpc:call(N,
+ ets,
+ insert,
+ [inviso_sideeffect_tab,{tpm_call_func1,0}]),
+ true=rpc:call(N,
+ ets,
+ insert,
+ [inviso_sideeffect_tab,{tpm_return_func1,0}])
+ end,
+ Nodes),
+ ?l {ok,NodeResults3}=
+ inviso:init_tpm(lists,
+ module_info,
+ 0,
+ {?MODULE,tpm_init_func1},
+ {?MODULE,tpm_call_func1},
+ {?MODULE,tpm_return_func1},
+ {?MODULE,tpm_remove_func1}),
+ ?l true=check_noderesults(Nodes,ok,NodeResults3),
+ ?l [{_,1}]=ets:lookup(inviso_sideeffect_tab,tpm_init_func1),
+ ?l {ok,NodeResults3a}=
+ inviso:init_tpm(lists,
+ module_info,
+ 0,
+ {?MODULE,tpm_init_func1},
+ {?MODULE,tpm_call_func1},
+ {?MODULE,tpm_return_func1},
+ {?MODULE,tpm_remove_func1}),
+ ?l true=check_noderesults(Nodes,{error,already_initiated},NodeResults3a),
+% %% Try more forbidden things. Wildcards not allowed in meta tracing!
+% ?l {ok,NodeResults3b}=inviso:tpm(Nodes,lists,'_',0,[{'_',[],[{return_trace}]}]),
+% io:format("The noderesults3b is:~w~n",[NodeResults3b]),
+% ?l true=check_noderesults(Nodes,{error,bad_mfa},NodeResults3b),
+ ?l {ok,NodeResults3c}=inviso:tpm(Nodes,lists,module_info,0,[{'_',[],[{return_trace}]}]),
+ ?l true=check_noderesults(Nodes,{ok,1},NodeResults3c),
+ ?l lists:foreach(fun(N)->P=rpc:call(N,erlang,whereis,[inviso_rt_meta]),
+ {meta,P}=rpc:call(N,erlang,trace_info,[{lists,module_info,0},meta])
+ end,
+ Nodes),
+ ?l lists:foreach(fun(N)->rpc:call(N,lists,module_info,[]) end,Nodes),
+ ?l ok=poll(ets,lookup,[inviso_sideeffect_tab,tpm_call_func1],[{tpm_call_func1,1}],20),
+ ?l ok=poll(ets,lookup,[inviso_sideeffect_tab,tpm_return_func1],[{tpm_return_func1,1}],20),
+ ?l lists:foreach(fun(N)->rpc:call(N,lists,module_info,[]) end,Nodes),
+ ?l ok=poll(ets,lookup,[inviso_sideeffect_tab,tpm_call_func1],[{tpm_call_func1,2}],20),
+ ?l ok=poll(ets,lookup,[inviso_sideeffect_tab,tpm_return_func1],[{tpm_return_func1,2}],20),
+
+ ?l {ok,NodeResults4}=
+ inviso:init_tpm(math,
+ module_info,
+ 1,
+ {?MODULE,tpm_init_func2}, % Does not exist on purpose.
+ {?MODULE,tpm_call_func2}, % Does not exist on purpose.
+ {?MODULE,tpm_return_func2}, % Does not exist on purpose.
+ {?MODULE,tpm_remove_func2}), % Does not exist on purpose.
+ ?l true=check_noderesults(Nodes,ok,NodeResults4),
+ ?l {ok,NodeResults5}=
+ inviso:tpm_ms(math,module_info,1,ms1,[{'_',[],[{return_trace}]}]),
+ ?l true=check_noderesults(Nodes,{ok,1},NodeResults5),
+ ?l lists:foreach(fun(N)->{meta_match_spec,[{'_',[],[{return_trace}]}]}=
+ rpc:call(N,erlang,trace_info,[{math,module_info,1},
+ meta_match_spec])
+ end,
+ Nodes),
+
+ ?l {ok,NodeResults6}=inviso:tpm_ms(math,module_info,1,ms2,[{[exports],[],[]}]),
+ ?l true=check_noderesults(Nodes,{ok,1},NodeResults6),
+ ?l lists:foreach(fun(N)->{meta_match_spec,[{[exports],[],[]},{'_',[],[{return_trace}]}]}=
+ rpc:call(N,erlang,trace_info,[{math,module_info,1},
+ meta_match_spec])
+ end,
+ Nodes),
+ ?l {ok,NodeResults7}=inviso:tpm_ms(math,module_info,1,ms3,[{[attributes],[],[]}]),
+ ?l true=check_noderesults(Nodes,{ok,1},NodeResults7),
+ ?l lists:foreach(fun(N)->{meta_match_spec,[{[attributes],[],[]},
+ {[exports],[],[]},
+ {'_',[],[{return_trace}]}]}=
+ rpc:call(N,erlang,trace_info,[{math,module_info,1},
+ meta_match_spec])
+ end,
+ Nodes),
+ ?l {ok,NodeResults8}=inviso:ctpm_ms(math,module_info,1,ms2),
+ ?l true=check_noderesults(Nodes,ok,NodeResults8),
+ ?l lists:foreach(fun(N)->{meta_match_spec,[{[attributes],[],[]},
+ {'_',[],[{return_trace}]}]}=
+ rpc:call(N,erlang,trace_info,[{math,module_info,1},
+ meta_match_spec])
+ end,
+ Nodes),
+ ?l io:format("whereis:~w~n",[lists:map(fun(N)->rpc:call(N,erlang,whereis,[inviso_rt_meta]) end,Nodes)]),
+ ?l {ok,NodeResults8}=inviso:ctpm_ms(math,module_info,1,ms3),
+ ?l io:format("whereis:~w~n",[lists:map(fun(N)->rpc:call(N,erlang,whereis,[inviso_rt_meta]) end,Nodes)]),
+ ?l {ok,NodeResults8}=inviso:ctpm_ms(math,module_info,1,ms1),
+ ?l lists:foreach(fun(N)->{meta_match_spec,false}=
+ rpc:call(N,erlang,trace_info,[{math,module_info,1},
+ meta_match_spec])
+ end,
+ Nodes),
+
+ %% Now try to do this with exception tracing instead.
+ %% Reset the side effect tables.
+ ?l lists:foreach(fun(N)->true=rpc:call(N,
+ ets,
+ insert,
+ [inviso_sideeffect_tab,{tpm_init_func1,0}]),
+ true=rpc:call(N,
+ ets,
+ insert,
+ [inviso_sideeffect_tab,{tpm_call_func1,0}]),
+ true=rpc:call(N,
+ ets,
+ insert,
+ [inviso_sideeffect_tab,{tpm_return_func1,0}])
+ end,
+ Nodes),
+ ?l {ok,NodeResults9}=
+ inviso:init_tpm(?MODULE,
+ failing_function,
+ 1,
+ {?MODULE,tpm_init_func1},
+ {?MODULE,tpm_call_func1},
+ {?MODULE,tpm_return_func1},
+ {?MODULE,tpm_remove_func1}),
+ ?l true=check_noderesults(Nodes,ok,NodeResults9),
+ ?l [{_,1}]=ets:lookup(inviso_sideeffect_tab,tpm_init_func1),
+ ?l {ok,NodeResults10}=inviso:tpm(Nodes,?MODULE,failing_function,1,[{'_',[],[{exception_trace}]}]),
+ ?l true=check_noderesults(Nodes,{ok,1},NodeResults10),
+ ?l lists:foreach(fun(N)->P=rpc:call(N,erlang,whereis,[inviso_rt_meta]),
+ {meta,P}=rpc:call(N,erlang,trace_info,[{?MODULE,failing_function,1},meta])
+ end,
+ Nodes),
+ ?l lists:foreach(fun(N)->rpc:call(N,?MODULE,failing_function,[nofailure]) end,Nodes),
+ ?l ok=poll(ets,lookup,[inviso_sideeffect_tab,tpm_call_func1],[{tpm_call_func1,1}],20),
+ ?l ok=poll(ets,lookup,[inviso_sideeffect_tab,tpm_return_func1],[{tpm_return_func1,1}],20),
+ ?l lists:foreach(fun(N)->rpc:call(N,?MODULE,failing_function,[failure]) end,Nodes),
+ ?l ok=poll(ets,lookup,[inviso_sideeffect_tab,tpm_call_func1],[{tpm_call_func1,2}],20),
+ ?l ok=poll(ets,lookup,[inviso_sideeffect_tab,tpm_return_func1],[{tpm_return_func1,3}],20),
+
+ ok.
+%% ------------------------------------------------------------------------------
+
+%% This function is for testing that appending the tracer to a trace action term
+%% works.
+activate_deactivate_meta_tracing_tracer(Nodes) ->
+ ?l {ok,NodeResults}=
+ inviso:tpm_tracer(Nodes,lists,module_info,0,[{'_',[],[{trace,[all],[call]}]}],void),
+ ?l true=check_noderesults(Nodes,{ok,1},NodeResults),
+ ?l lists:foreach(fun(N)->P=rpc:call(N,erlang,whereis,[inviso_rt_meta]),
+ {meta,P}=rpc:call(N,erlang,trace_info,[{lists,module_info,0},meta]),
+ {meta_match_spec,[{'_',[],[{trace,[all],Enable}]}]}=
+ rpc:call(N,erlang,trace_info,[{lists,module_info,0},
+ meta_match_spec]),
+ true=list_search(Enable,fun({{tracer,P}}) when is_port(P)->true;
+ (_) -> false
+ end)
+ end,
+ Nodes),
+ ?l {ok,NodeResults2}=
+ inviso:ctpm(Nodes,lists,module_info,0),
+ ?l true=check_noderesults(Nodes,ok,NodeResults2),
+ ?l lists:foreach(fun(N)->{meta,false}=
+ rpc:call(N,erlang,trace_info,[{lists,module_info,0},meta])
+ end,
+ Nodes),
+ ok.
+%% ------------------------------------------------------------------------------
+
+deactivate_meta_tracing(Nodes) ->
+ ?l lists:foreach(fun(N)->{meta,P}=
+ rpc:call(N,erlang,trace_info,[{erlang,register,2},meta]),
+ true=is_pid(P)
+ end,
+ Nodes),
+ ?l lists:foreach(fun(N)->{meta,P}=
+ rpc:call(N,erlang,trace_info,[{erlang,unregister,1},meta]),
+ true=is_pid(P)
+ end,
+ Nodes),
+ ?l {ok,NodeResults1}=inviso:ctpm_localnames(),
+ ?l lists:foreach(fun(N)->{meta,false}=
+ rpc:call(N,erlang,trace_info,[{erlang,register,2},meta]) end,
+ Nodes),
+ ?l lists:foreach(fun(N)->{meta,false}=
+ rpc:call(N,erlang,trace_info,[{erlang,unregister,1},meta])
+ end,
+ Nodes),
+ ?l true=check_noderesults(Nodes,{ok,ok},NodeResults1),
+
+ ?l lists:foreach(fun(N)->P=rpc:call(N,erlang,whereis,[inviso_rt_meta]),
+ {meta,P}=rpc:call(N,
+ erlang,
+ trace_info,
+ [{global,handle_call,3},meta])
+ end,
+ Nodes),
+ ?l lists:foreach(fun(N)->P=rpc:call(N,erlang,whereis,[inviso_rt_meta]),
+ {meta,P}=rpc:call(N,
+ erlang,
+ trace_info,
+ [{global,delete_global_name,2},meta])
+ end,
+ Nodes),
+ ?l {ok,NodeResults1b}=inviso:ctpm_globalnames(),
+ ?l true=check_noderesults(Nodes,{ok,ok},NodeResults1b),
+ ?l lists:foreach(fun(N)->
+ {meta,false}=rpc:call(N,
+ erlang,
+ trace_info,
+ [{global,handle_call,3},meta])
+ end,
+ Nodes),
+ ?l lists:foreach(fun(N)->
+ {meta,false}=rpc:call(N,
+ erlang,
+ trace_info,
+ [{global,delete_global_name,2},meta])
+ end,
+ Nodes),
+
+ ?l lists:foreach(fun(N)->{meta,P}=
+ rpc:call(N,erlang,trace_info,[{lists,module_info,0},meta]),
+ true=is_pid(P)
+ end,
+ Nodes),
+ ?l {ok,NodeResults2}=inviso:ctpm(lists,module_info,0),
+ ?l true=check_noderesults(Nodes,ok,NodeResults2),
+ ?l lists:foreach(fun(N)->{meta,false}=
+ rpc:call(N,erlang,trace_info,[{lists,module_info,0},meta]) end,
+ Nodes),
+ ?l [{_,0}]=ets:lookup(inviso_sideeffect_tab,tpm_init_func1),
+ ?l {ok,NodeResults3}=inviso:ctpm(math,module_info,1),
+ ?l true=check_noderesults(Nodes,ok,NodeResults3),
+ ok.
+%% ------------------------------------------------------------------------------
+
+%% Functions acting as callbacks for testing the meta tracing mechanisms.
+tpm_init_func1(_M,_F,_Arity,PublLD) ->
+ ets:update_counter(inviso_sideeffect_tab,tpm_init_func1,1),
+ {ok,PublLD,void}.
+tpm_call_func1(_Pid,{call,_Args,_TS},PublLD) ->
+ ets:update_counter(inviso_sideeffect_tab,tpm_call_func1,1),
+ {ok,PublLD,void}.
+tpm_return_func1(_Pid,{return_from,_ReturnVal,_TS},PublLD) ->
+ ets:update_counter(inviso_sideeffect_tab,tpm_return_func1,1),
+ {ok,PublLD,void};
+tpm_return_func1(_Pid,{exception_from,_ReturnVal,_TS},PublLD) ->
+ ets:update_counter(inviso_sideeffect_tab,tpm_return_func1,1),
+ ets:update_counter(inviso_sideeffect_tab,tpm_return_func1,1),
+ {ok,PublLD,void}.
+tpm_remove_func1(_M,_F,_Arity,PublLD) ->
+ ets:update_counter(inviso_sideeffect_tab,tpm_init_func1,-1),
+ {ok,PublLD}.
+%% ------------------------------------------------------------------------------
+
+
+%% Help function which traces on a function and makes function calls until there
+%% are two files in the wrap-set.
+fill_and_reach_two_wrapfiles(PrivDir,RegExp,Nodes) ->
+ ?l lists:foreach(fun(N)->spawn(N,?MODULE,test_proc_init,[]) end,Nodes),
+ ?l {ok,NodeResults1}=inviso:tpl(Nodes,?MODULE,test_function,0,[]),
+ ?l true=check_noderesults(Nodes,{ok,[1]},NodeResults1),
+ ?l {ok,NodeResults2}=inviso:tf(Nodes,inviso_test_proc,[call]),
+ ?l true=check_noderesults(Nodes,{ok,[1]},NodeResults2),
+ fill_and_reach_two_wrapfiles_2(PrivDir,RegExp,Nodes),
+ ?l {ok,NodeResults3}=inviso:ctf(Nodes,inviso_test_proc,[call]),
+ ?l true=check_noderesults(Nodes,{ok,[1]},NodeResults3),
+ ?l {ok,NodeResults4}=inviso:ctpl(Nodes,?MODULE,test_function,0),
+ ?l true=check_noderesults(Nodes,{ok,[1]},NodeResults4),
+ ok.
+
+fill_and_reach_two_wrapfiles_2(PrivDir,RegExp,[Node|Rest]) ->
+ ?l ok=rpc:call(Node,?MODULE,fill_and_reach_two_wrapfiles_3,[PrivDir,RegExp]),
+ fill_and_reach_two_wrapfiles_2(PrivDir,RegExp,Rest);
+fill_and_reach_two_wrapfiles_2(_,_,[]) ->
+ ok.
+
+fill_and_reach_two_wrapfiles_3(Dir,RegExp) ->
+ ok=send_to_test_proc({apply,?MODULE,test_function,[]},
+ fun reach_two_wraps_stopfun/1,
+ {Dir,RegExp++atom_to_list(node())},
+ 100).
+
+%% Help function intended to be used as fun in a send_to_test_proc/4 call.
+%% The function lists the content of Dir and looks for occurancies of String.
+%% If two files containing the string String are found, 'done' is returned.
+%% Otherwise 'continue'.
+reach_two_wraps_stopfun({Dir,RegExp}) ->
+ case file:list_dir(Dir) of
+ {ok,FileNames} ->
+ case how_many_files_regexp(FileNames,RegExp,0) of
+ {ok,2} ->
+ done;
+ _ ->
+ continue
+ end;
+ {error,_Reason} ->
+ error
+ end.
+%% ------------------------------------------------------------------------------
+
+%% ------------------------------------------------------------------------------
+%% Help function for the overload tests. These functions are used as callbacks.
+%% ------------------------------------------------------------------------------
+
+overload1(_) ->
+ ets:update_counter(inviso_sideeffect_tab,ovl1,1),
+ ok.
+%% This function is used when timeout occurs inside the runtime component.
+%% That is it is time to check for overload.
+overload2({timeout,overload2i_data}) ->
+ ets:update_counter(inviso_sideeffect_tab,ovl2,1),
+ ok.
+overload2i() ->
+ ets:insert(inviso_sideeffect_tab,{ovl2,0}),
+ {ok,overload2i_data}.
+overload2r(overload2i_data) ->
+ ets:delete(inviso_sideeffect_tab,ovl2).
+
+%% This function is used when timeout occurs inside the runtime component.
+%% That is it is time to check for overload.
+overload3({timeout,overload3i_data}) ->
+ ets:update_counter(inviso_sideeffect_tab,ovl3,1),
+ ok;
+overload3(_) -> % Must handle garbage too.
+ ignore.
+overload3i() ->
+ ets:insert(inviso_sideeffect_tab,{ovl3,0}),
+ {ok,overload3i_data}.
+overload3r(overload3i_data) ->
+ ets:insert(inviso_sideeffect_tab,{ovl3r,done}),
+ ets:delete(inviso_sideeffect_tab,ovl3).
+
+overload4(_) ->
+ case ets:lookup(inviso_sideeffect_tab,ovl4_suspend) of
+ [] -> % We are supposed to be running.
+ ets:update_counter(inviso_sideeffect_tab,ovl4,1),
+ ok;
+ [_] ->
+ {suspend,test}
+ end.
+
+%% This function is used when overload check is done by icomming message.
+overload5({msg,{test_of_loadcheck,overload5i_data}}) ->
+ ets:update_counter(inviso_sideeffect_tab,ovl5,1),
+ ok;
+overload5(_) ->
+ ignore.
+overload5i() ->
+ ets:insert(inviso_sideeffect_tab,{ovl5,0}),
+ {ok,overload5i_data}.
+overload5r(overload5i_data) ->
+ ets:delete(inviso_sideeffect_tab,ovl5),
+ ets:insert(inviso_sideeffect_tab,{ovl5r,done});
+overload5r(X) ->
+ erlang:display({'***',overload5r,X}).
+
+overload6(_) ->
+ ets:update_counter(inviso_sideeffect_tab,ovl6,1),
+ ok.
+%% ------------------------------------------------------------------------------
+
+%% ------------------------------------------------------------------------------
+%% Help function for the subscription tests. These function implements a collector
+%% process which will subscribe to inviso_events from the control component.
+%% ------------------------------------------------------------------------------
+
+%% Function which can be used to check if an inviso_event has arrived. The function
+%% takes a fun which tests the messages.
+check_msg_collector([],_,_) ->
+ true;
+check_msg_collector(_,_,0) ->
+ false;
+check_msg_collector(Nodes,Fun,T) ->
+ Ref=make_ref(),
+ inviso_collector_proc ! {fetch_message,self(),Ref,Fun},
+ receive
+ {inviso,Ref,{true,Node}} ->
+ check_msg_collector(lists:delete(Node,Nodes),Fun,T-1);
+ {inviso,Ref,false} ->
+ timer:sleep(100),
+ check_msg_collector(Nodes,Fun,T-1)
+ end.
+
+%% Spawn on this function to get a subscriber.
+inviso_msg_collector() ->
+ register(inviso_collector_proc,self()),
+ inviso_msg_collector_loop([]).
+
+inviso_msg_collector_loop(Msgs) ->
+ receive
+ {fetch_message,From,Ref,Fun} ->
+ {NewMsgs,Reply}=inviso_msg_collector_selector(Msgs,Fun,[]),
+ From ! {inviso,Ref,Reply},
+ inviso_msg_collector_loop(NewMsgs);
+ Msg ->
+ inviso_msg_collector_loop([Msg|Msgs])
+ end.
+
+inviso_msg_collector_selector([M|Rest],Fun,Accum) ->
+ case Fun(M) of
+ {true,X} ->
+ {Rest++Accum,{true,X}};
+ _ ->
+ inviso_msg_collector_selector(Rest,Fun,[M|Accum])
+ end;
+inviso_msg_collector_selector([],_,Accum) ->
+ {Accum,false}.
+%% ------------------------------------------------------------------------------
+
+
+%% ==============================================================================
+%% Help functions
+%% ==============================================================================
+
+list_search([E|Rest],Fun) ->
+ case Fun(E) of
+ true ->
+ true;
+ false ->
+ list_search(Rest,Fun)
+ end;
+list_search([],_Fun) ->
+ false.
+%% ------------------------------------------------------------------------------
+
+%% Help function checking that there is a Result for each node in Nodes.
+%% Returns 'true' if successful.
+check_noderesults(Nodes,Fun,[{Node,Result}|Rest]) when is_function(Fun) ->
+ case Fun({Node,Result}) of
+ true ->
+ case lists:member(Node,Nodes) of
+ true ->
+ check_noderesults(lists:delete(Node,Nodes),Fun,Rest);
+ false -> % Not good.
+ unknown_node_in_returnvalue
+ end;
+ _ ->
+ illegal_result
+ end;
+check_noderesults(Nodes,Result,[{Node,Result}|Rest]) ->
+ case lists:member(Node,Nodes) of
+ true ->
+ check_noderesults(lists:delete(Node,Nodes),Result,Rest);
+ false -> % Not good.
+ unknown_node_in_returnvalue
+ end;
+check_noderesults([],_,[]) ->
+ true;
+check_noderesults(X,Y,Z) ->
+ io:format("Bad arguments to check noderesults:~w~n~w~n~w~n",[X,Y,Z]),
+ false.
+%% ------------------------------------------------------------------------------
+
+%% Help function doing rpc on all nodes in Nodes calling M:F. Returns 'true' if
+%% successful.
+check_on_nodes([Node|Rest],M,F,Args,Result) when Node==node() ->
+ if
+ is_function(Result) ->
+ ?l true=Result(apply(M,F,Args));
+ true ->
+ ?l Result=apply(M,F,Args)
+ end,
+ check_on_nodes(Rest,M,F,Args,Result);
+check_on_nodes([Node|Rest],M,F,Args,Result) ->
+ if
+ is_function(Result) ->
+ ?l true=Result(rpc:call(Node,M,F,Args));
+ true ->
+ ?l Result=rpc:call(Node,M,F,Args)
+ end,
+ check_on_nodes(Rest,M,F,Args,Result);
+check_on_nodes([],_,_,_,_) ->
+ true.
+%% ------------------------------------------------------------------------------
+
+%% Help function which given a list of files searches through it and returns
+%% how many satisfies the RegExp.
+%% Returns {ok,N}.
+how_many_files_regexp([],_,N) ->
+ {ok,N};
+how_many_files_regexp([FName|Rest],RegExp,N) ->
+ case regexp:first_match(FName,RegExp) of
+ {match,1,_} ->
+ how_many_files_regexp(Rest,RegExp,N+1);
+ nomatch ->
+ how_many_files_regexp(Rest,RegExp,N);
+ {error,Reason} ->
+ test_server:fail(Reason)
+ end.
+%% ------------------------------------------------------------------------------
+
+%% Help function killing a bunch of registered processes.
+process_killer([RegName|Rest]) ->
+ case whereis(RegName) of
+ undefined ->
+ case global:whereis_name(RegName) of
+ undefined ->
+ process_killer(Rest);
+ P when is_pid(P) ->
+ if
+ node()==node(P) ->
+ exit(P,kill);
+ true ->
+ true
+ end,
+ process_killer(Rest)
+ end;
+ P when is_pid(P) ->
+ exit(P,kill),
+ process_killer(Rest)
+ end;
+process_killer([]) ->
+ true.
+%% ------------------------------------------------------------------------------
+
+%% Help function which waits for a function call to become Result. This is useful
+%% if what we are waiting for can happend independantly of indications we have
+%% access to.
+poll(_,_,_,_,0) ->
+ error;
+poll(M,F,Args,Result,Times) ->
+ try apply(M,F,Args) of
+ What when is_function(Result) ->
+ case Result(What) of
+ true ->
+ ok;
+ _ ->
+ timer:sleep(100),
+ poll(M,F,Args,Result,Times-1)
+ end;
+ Result ->
+ ok;
+ _ ->
+ timer:sleep(100),
+ poll(M,F,Args,Result,Times-1)
+ catch
+ error:Reason ->
+ io:format("Apply in suite-function poll/5 failed, ~w~n",[Reason]),
+ timer:sleep(100),
+ poll(M,F,Args,Result,Times-1)
+ end.
+%% ------------------------------------------------------------------------------
+
+insert_remotenode_config(Name,Node,Config) ->
+ [{remotenode,{Name,Node}}|Config].
+%% ------------------------------------------------------------------------------
+
+insert_timetraphandle_config(Handle,Config) ->
+ [{timetraphandle,Handle}|Config].
+%% ------------------------------------------------------------------------------
+
+get_remotenode_config(Name, [{remotenode, {Name, Node}}| _Cs]) ->
+ Node;
+get_remotenode_config(Name, [_ | Cs]) ->
+ get_remotenode_config(Name, Cs);
+get_remotenode_config(Name, []) ->
+ exit({no_remotenode, Name}).
+
+%% ------------------------------------------------------------------------------
+
+get_timetraphandle_config(Config) ->
+ {value,{_,Handle}}=lists:keysearch(timetraphandle,1,Config),
+ Handle.
+%% ------------------------------------------------------------------------------
+
+get_remotenodes_config([{remotenode,{_Name,Node}}|Config]) ->
+ [Node|get_remotenodes_config(Config)];
+get_remotenodes_config([_|Config]) ->
+ get_remotenodes_config(Config);
+get_remotenodes_config([]) ->
+ [].
+%% ------------------------------------------------------------------------------
+
+remove_remotenode_config(Name, [{remotenode, {Name, _}} | Cs]) ->
+ Cs;
+remove_remotenode_config(Name, [C | Cs]) ->
+ [C | remove_remotenode_config(Name, Cs)];
+remove_remotenode_config(_Name, []) ->
+ [].
+
+%% ------------------------------------------------------------------------------
+
+remove_timetraphandle_config(Config) ->
+ lists:keydelete(timetraphandle,1,Config).
+%% ------------------------------------------------------------------------------
+
+%% This function can be meta traced in order to check that exception_trace works.
+%% Must be exported.
+failing_function(nofailure) ->
+ true;
+failing_function(failure) ->
+ exit(failure).
+%% ------------------------------------------------------------------------------
+
+%% ==============================================================================
+%% Code for a test process which can be started.
+%% ==============================================================================
+
+test_proc_init() ->
+ register(inviso_test_proc,self()),
+ test_proc_loop().
+
+test_proc_loop() ->
+ receive
+ {apply,M,F,Args} ->
+ apply(M,F,Args),
+ test_proc_loop();
+ X ->
+ io:format("Got ~w~n",[X]),
+ test_proc_loop()
+ end.
+
+global_test_proc_init() ->
+ global:register_name(global_inviso_test_proc,self()),
+ test_proc_loop().
+%% ------------------------------------------------------------------------------
+
+send_to_test_proc(_,_,_,0) ->
+ error;
+send_to_test_proc(Msg,Fun,FunArg,N) ->
+ inviso_test_proc ! Msg,
+ case Fun(FunArg) of
+ done ->
+ ok;
+ error ->
+ test_server:fail(send_to_test_proc);
+ _ ->
+ send_to_test_proc(Msg,Fun,FunArg,N-1)
+ end.
+%% ------------------------------------------------------------------------------
+
+
+%% This function is here to be traced on by the inviso_test_proc. Must be exported.
+test_function() ->
+ 1+1.
+%% ------------------------------------------------------------------------------
+
+
+%% ==============================================================================
+%% Code for a test side effect table process.
+%% ==============================================================================
+
+%% The side effect logger is a process owning a public ETS table. The idea is that
+%% various callback functions can write in the table when called. In that way
+%% correct calling of the call-backs can be verified.
+start_side_effect_logger(Node) ->
+ ?l true=is_pid(spawn(Node,?MODULE,side_effect_logger_proc,[])),
+ ?l ok=poll(rpc,call,[Node,ets,lookup,[inviso_sideeffect_tab,foo]],[],20).
+
+%% This one must be exported.
+side_effect_logger_proc() ->
+ register(inviso_tab_proc,self()), % So we can kill it later.
+ ets:new(inviso_sideeffect_tab,[public,named_table]),
+ side_effect_logger_proc_2().
+
+side_effect_logger_proc_2() ->
+ receive
+ _X -> % This process is not expecting anything!
+ side_effect_logger_proc_2()
+ end.
+%% ------------------------------------------------------------------------------
diff --git a/lib/runtime_tools/test/inviso_testmodule1_foo.erl b/lib/runtime_tools/test/inviso_testmodule1_foo.erl
new file mode 100644
index 0000000000..a7a22cad39
--- /dev/null
+++ b/lib/runtime_tools/test/inviso_testmodule1_foo.erl
@@ -0,0 +1,9 @@
+-module(inviso_testmodule1_foo).
+
+-compile(export_all).
+
+%% The purpose of this module is simply to have a module that is
+%% guaranteed not loaded.
+
+foo() ->
+ true.
diff --git a/lib/runtime_tools/test/runtime_tools.cover b/lib/runtime_tools/test/runtime_tools.cover
new file mode 100644
index 0000000000..2d62ebe6ac
--- /dev/null
+++ b/lib/runtime_tools/test/runtime_tools.cover
@@ -0,0 +1 @@
+{exclude,[observer_backend]}.
diff --git a/lib/runtime_tools/test/runtime_tools.spec b/lib/runtime_tools/test/runtime_tools.spec
new file mode 100644
index 0000000000..a60a533ce2
--- /dev/null
+++ b/lib/runtime_tools/test/runtime_tools.spec
@@ -0,0 +1 @@
+{topcase, {dir, "../runtime_tools_test"}}.
diff --git a/lib/runtime_tools/test/runtime_tools_SUITE.erl b/lib/runtime_tools/test/runtime_tools_SUITE.erl
new file mode 100644
index 0000000000..84e255e126
--- /dev/null
+++ b/lib/runtime_tools/test/runtime_tools_SUITE.erl
@@ -0,0 +1,50 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 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(runtime_tools_SUITE).
+-include("test_server.hrl").
+
+%% Test server specific exports
+-export([all/1]).
+-export([init_per_testcase/2, end_per_testcase/2]).
+
+%% Test cases
+-export([app_file/1]).
+
+%% Default timetrap timeout (set in init_per_testcase)
+-define(default_timeout, ?t:minutes(1)).
+
+init_per_testcase(_Case, Config) ->
+ Dog = test_server:timetrap(?default_timeout),
+ [{watchdog, Dog} | Config].
+
+end_per_testcase(_Case, Config) ->
+ Dog = ?config(watchdog, Config),
+ ?t:timetrap_cancel(Dog),
+ ok.
+
+all(suite) ->
+ [app_file].
+
+app_file(suite) ->
+ [];
+app_file(doc) ->
+ ["Testing .app file"];
+app_file(Config) when is_list(Config) ->
+ ?line ok = ?t:app_test(runtime_tools),
+ ok.
diff --git a/lib/runtime_tools/vsn.mk b/lib/runtime_tools/vsn.mk
index 591f3e1ac4..4bbdef19de 100644
--- a/lib/runtime_tools/vsn.mk
+++ b/lib/runtime_tools/vsn.mk
@@ -1 +1 @@
-RUNTIME_TOOLS_VSN = 1.8.2
+RUNTIME_TOOLS_VSN = 1.8.3
diff --git a/lib/sasl/doc/src/notes.xml b/lib/sasl/doc/src/notes.xml
index 15387c1232..e528af2522 100644
--- a/lib/sasl/doc/src/notes.xml
+++ b/lib/sasl/doc/src/notes.xml
@@ -4,7 +4,7 @@
<chapter>
<header>
<copyright>
- <year>2004</year><year>2009</year>
+ <year>2004</year><year>2010</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
@@ -13,12 +13,12 @@
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>SASL Release Notes</title>
@@ -30,6 +30,86 @@
</header>
<p>This document describes the changes made to the SASL application.</p>
+<section><title>SASL 2.1.9.2</title>
+
+ <section><title>Fixed Bugs and Malfunctions</title>
+ <list>
+ <item>
+ <p>In R13B04 sys:get_status was modified to invoke
+ format_status/2 in the callback module if the module
+ exports that function. This resulted in a change to the
+ term returned from calling sys:get_status on the
+ supervisor module, since supervisor is a gen_server and
+ gen_server exports format_status. The sasl
+ release_handler_1 module had a dependency on the
+ pre-R13B04 term returned by sys:get_status when invoked
+ on a supervisor, so the R13B04 change broke that
+ dependency.</p>
+ <p>This problem has been fixed by change
+ release_handler_1 to handle both the pre-R13B04 and
+ R13B04 terms that sys:get_status can return from a
+ supervisor.</p>
+ <p>
+ Own Id: OTP-8619 Aux Id: seq11570 </p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
+<section><title>SASL 2.1.9.1</title>
+
+ <section><title>Improvements and New Features</title>
+ <list>
+ <item>
+ <p>Use an infinity timeout in all calls to
+ <c>gen_server:call()</c> in the <c>sasl</c>
+ application.</p>
+ <p>
+ Own Id: OTP-8506 Aux Id: seq11509 </p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
+<section><title>SASL 2.1.9</title>
+
+ <section><title>Improvements and New Features</title>
+ <list>
+ <item>
+ <p>
+ The <c>re:grep/1</c> function now uses the '<c>re</c>'
+ module instead of the deprecated '<c>regexp</c>' module.
+ There are new functions <c>rb:filter/1</c> and
+ <c>rb:filter/2</c> for easier filtering of reports.
+ (Thanks to Alvaro Videla.)</p>
+ <p>
+ Own Id: OTP-8443</p>
+ </item>
+ <item>
+ <p>
+ There is new function <c>sasl_report:format_report/3</c>
+ that works like the existing
+ <c>sasl_report:write_report/3</c> function except that it
+ returns a formatted string. Note that there is currently
+ no documentation for the <c>sasl_report</c> module.
+ (Thanks to Jay Nelson.)</p>
+ <p>
+ Own Id: OTP-8445</p>
+ </item>
+ <item>
+ <p>
+ Cleanups suggested by tidier and modernization of types
+ and specs.</p>
+ <p>
+ Own Id: OTP-8455</p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
<section><title>SASL 2.1.8</title>
<section><title>Improvements and New Features</title>
diff --git a/lib/sasl/doc/src/rb.xml b/lib/sasl/doc/src/rb.xml
index 5b49a7bced..f35ceb5777 100644
--- a/lib/sasl/doc/src/rb.xml
+++ b/lib/sasl/doc/src/rb.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>2010</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/.
+ The 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.
+ 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>rb</title>
@@ -43,20 +41,70 @@
</description>
<funcs>
<func>
+ <name>filter(Filters)</name>
+ <name>filter(Filters, Dates)</name>
+ <fsummary>Filter reports and displays them on the screen</fsummary>
+ <type>
+ <v>Filters = [filter()]</v>
+ <v>filter() = {Key, Value} | {Key, Value, no} | {Key, RegExp, re} | {Key, RegExp, re, no}</v>
+ <v>Key = term()</v>
+ <v>Value = term()</v>
+ <v>RegExp = string() | {string, Options} | mp(), {mp(), Options}</v>
+ <v>Dates = {DateFrom, DateTo} | {DateFrom, from} | {DateTo, to}</v>
+ <v>DateFrom = DateTo = {date(), time()}</v>
+ <v>date() and time() are the same type as in the <c>calendar</c> module</v>
+ </type>
+ <desc>
+ <p>This function displays the reports that match the provided filters.</p>
+ <p>
+ When a filter includes the <c>no</c> atom it will exclude the reports that match
+ that filter.
+ </p>
+ <p>
+ The reports are matched using the <c>proplists</c> module. The report must be a proplist
+ to be matched against any of the <c>filters()</c>.
+ </p>
+ <p>
+ If the filter is of the form <c>{Key, RegExp, re}</c> the report must contain an element with
+ <c>key = Key</c> and <c>Value</c> must match the RegExp regular expression.
+ </p>
+ <p>
+ If the Dates parameter is provided, then the reports are filtered according to the date
+ when they occurred. If Dates is of the form <c>{DateFrom, from}</c> then reports that occurred
+ after DateFrom are displayed.
+ </p>
+ <p>
+ If Dates is of the form <c>{DateTo, to}</c> then reports that occurred before DateTo
+ are displayed.
+ </p>
+ <p>
+ If two Dates are provided, then reports that occurred between those dates are returned.
+ </p>
+ <p>
+ If you only want to filter only by dates, then you can provide the empty list as the Filters
+ parameter.
+ </p>
+ <p>
+ See <c>rb:grep/1</c> for more information on the RegExp parameter.
+ </p>
+ </desc>
+ </func>
+ <func>
<name>grep(RegExp)</name>
<fsummary>Search the reports for a regular expression</fsummary>
<type>
- <v>RegExp = string()</v>
+ <v>RegExp = string() | {string, Options} | mp(), {mp(), Options}</v>
</type>
<desc>
<p>All reports containing the regular expression <c>RegExp</c>
are printed.
</p>
- <p><c>RegExp</c> is a string containing the regular
- expression. Refer to the module <c>regexp</c> in the STDLIB
- reference manual
- for a definition of valid regular expressions. They are
- essentially the same as the UNIX command <c>egrep</c>.
+ <p><c>RegExp</c> can be a string containing the regular
+ expression; a tuple with the string and the options for
+ compilation; a compiled regular expression; a compiled
+ regular expression and the options for running it.
+ Refer to the module <c>re</c> and specially the function <c>re:run/3</c>
+ for a definition of valid regular expressions and options.
</p>
</desc>
</func>
diff --git a/lib/sasl/src/overload.erl b/lib/sasl/src/overload.erl
index 3a9a51e8bf..5a4782efff 100644
--- a/lib/sasl/src/overload.erl
+++ b/lib/sasl/src/overload.erl
@@ -1,19 +1,19 @@
%%
%% %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
%% 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(overload).
@@ -71,7 +71,7 @@ init([]) ->
%% establish a call.
%% Returns: accept | reject
%%-----------------------------------------------------------------
-request() -> gen_server:call(overload, request).
+request() -> call(request).
%%-----------------------------------------------------------------
%% Func: set_config_data/2
@@ -82,13 +82,19 @@ request() -> gen_server:call(overload, request).
%% documented at all.
%%-----------------------------------------------------------------
set_config_data(MaxIntensity, Weight) ->
- gen_server:call(overload, {set_config_data, MaxIntensity, Weight}).
+ call({set_config_data, MaxIntensity, Weight}).
%%-----------------------------------------------------------------
%% Func: get_overload_info/0
%% Returns: A list of tagged items: TotalIntensity, AcceptIntensity,
%% MaxIntensity, Weight, TotalRequests, AcceptedRequests.
%%-----------------------------------------------------------------
-get_overload_info() -> gen_server:call(overload, get_overload_info).
+get_overload_info() -> call(get_overload_info).
+
+%%-----------------------------------------------------------------
+%% call(Request) -> Term
+%%-----------------------------------------------------------------
+call(Req) ->
+ gen_server:call(overload, Req, infinity).
%%%-----------------------------------------------------------------
%%% Callback functions from gen_server
diff --git a/lib/sasl/src/rb.erl b/lib/sasl/src/rb.erl
index 00d86285e5..38e486b7a7 100644
--- a/lib/sasl/src/rb.erl
+++ b/lib/sasl/src/rb.erl
@@ -1,19 +1,19 @@
%%
%% %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
%% 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(rb).
@@ -22,7 +22,7 @@
%% External exports
-export([start/0, start/1, stop/0, rescan/0, rescan/1]).
--export([list/0, list/1, show/0, show/1, grep/1, start_log/1, stop_log/0]).
+-export([list/0, list/1, show/0, show/1, grep/1, filter/1, filter/2, start_log/1, stop_log/0]).
-export([h/0, help/0]).
%% Internal exports
@@ -53,29 +53,35 @@ start_link(Options) ->
gen_server:start_link({local, rb_server}, rb, Options, []).
stop() ->
- gen_server:call(rb_server, stop),
+ call(stop),
supervisor:delete_child(sasl_sup, rb_server).
rescan() -> rescan([]).
rescan(Options) ->
- gen_server:call(rb_server, {rescan, Options}, infinity).
+ call({rescan, Options}).
list() -> list(all).
-list(Type) -> gen_server:call(rb_server, {list, Type}, infinity).
+list(Type) -> call({list, Type}).
show() ->
- gen_server:call(rb_server, show, infinity).
+ call(show).
show(Number) when is_integer(Number) ->
- gen_server:call(rb_server, {show_number, Number}, infinity);
+ call({show_number, Number});
show(Type) when is_atom(Type) ->
- gen_server:call(rb_server, {show_type, Type}, infinity).
+ call({show_type, Type}).
+
+grep(RegExp) -> call({grep, RegExp}).
-grep(RegExp) -> gen_server:call(rb_server, {grep, RegExp}, infinity).
+filter(Filters) when is_list(Filters) ->
+ call({filter, Filters}).
-start_log(FileName) -> gen_server:call(rb_server, {start_log, FileName}).
+filter(Filters, FDates) when is_list(Filters) andalso is_tuple(FDates) ->
+ call({filter, {Filters, FDates}}).
-stop_log() -> gen_server:call(rb_server, stop_log).
+start_log(FileName) -> call({start_log, FileName}).
+
+stop_log() -> call(stop_log).
h() -> help().
help() ->
@@ -90,7 +96,17 @@ help() ->
io:format("rb:list(Type) - list all reports of type Type~n"),
io:format(" currently supported types are:~n"),
print_types(),
- io:format("rb:grep(RegExp) - print reports containing RegExp~n"),
+ io:format("rb:grep(RegExp) - print reports containing RegExp.~n"),
+ io:format(" RegExp must be a valid argument for ~n"),
+ io:format(" the function re:run/2 or re:run/3.~n"),
+ io:format("rb:filter(Filters) - print reports matching Filters.~n"),
+ io:format(" reports must be proplists.~n"),
+ io:format(" Filters is a list of tuples of the following form:~n"),
+ print_filters(),
+ io:format("rb:filter(Filters, Dates) -~n"),
+ io:format(" same as rb:filter/1 but accepts date ranges to filter reports.~n"),
+ io:format(" Dates must be of the following form:~n"),
+ print_dates(),
io:format("rb:rescan() - rescans the report directory with same~n"),
io:format(" options.~n"),
io:format("rb:rescan(Options) - rescans the report directory with new~n"),
@@ -106,6 +122,13 @@ help() ->
%%-----------------------------------------------------------------
%% Internal functions.
%%-----------------------------------------------------------------
+
+%%-----------------------------------------------------------------
+%% call(Request) -> Term
+%%-----------------------------------------------------------------
+call(Req) ->
+ gen_server:call(rb_server, Req, infinity).
+
%%-----------------------------------------------------------------
%% MAKE SURE THESE TWO FUNCTIONS ARE UPDATED!
%%-----------------------------------------------------------------
@@ -133,7 +156,26 @@ print_types() ->
io:format(" - progress~n"),
io:format(" - error~n").
-
+print_filters() ->
+ io:format(" - {Key, Value}~n"),
+ io:format(" includes report containing {Key, Value}~n"),
+ io:format(" - {Key, Value, no}~n"),
+ io:format(" excludes report containing {Key, Value}~n"),
+ io:format(" - {Key, RegExp, re}~n"),
+ io:format(" RegExp must be a valid argument for ~n"),
+ io:format(" the function re:run/2 or re:run/3.~n"),
+ io:format(" - {Key, RegExp, re, no}~n"),
+ io:format(" excludes report containing {Key, RegExp}~n").
+
+print_dates() ->
+ io:format(" - {StartDate, EndDate}~n"),
+ io:format(" StartDate = EndDate = {{Y-M-D},{H,M,S}} ~n"),
+ io:format(" prints the reports with date between StartDate and EndDate~n"),
+ io:format(" - {StartDate, from}~n"),
+ io:format(" prints the reports with date greater than StartDate~n"),
+ io:format(" - {EndDate, to}~n"),
+ io:format(" prints the reports with date lesser than StartDate~n").
+
init(Options) ->
process_flag(priority, low),
process_flag(trap_exit, true),
@@ -190,8 +232,22 @@ handle_call(show, _From, State) ->
{reply, ok, State#state{device = NewDevice}};
handle_call({grep, RegExp}, _From, State) ->
#state{dir = Dir, data = Data, device = Device, abort = Abort, log = Log} = State,
- NewDevice = print_grep_reports(Dir, Data, RegExp, Device, Abort, Log),
- {reply, ok, State#state{device = NewDevice}}.
+ try print_grep_reports(Dir, Data, RegExp, Device, Abort, Log) of
+ NewDevice ->
+ {reply, ok, State#state{device = NewDevice}}
+ catch
+ error:Error ->
+ {reply, {error, Error}, State}
+ end;
+handle_call({filter, Filters}, _From, State) ->
+ #state{dir = Dir, data = Data, device = Device, abort = Abort, log = Log} = State,
+ try filter_all_reports(Dir, Data, Filters, Device, Abort, Log) of
+ NewDevice ->
+ {reply, ok, State#state{device = NewDevice}}
+ catch
+ error:Error ->
+ {reply, {error, Error}, State}
+ end.
terminate(_Reason, #state{device = Device}) ->
close_device(Device).
@@ -415,7 +471,7 @@ read_report(Fd) ->
Ref = make_ref(),
case (catch {Ref,binary_to_term(Bin)}) of
{'EXIT',_} ->
- {error, "Inclomplete erlang term in log"};
+ {error, "Incomplete erlang term in log"};
{Ref,Term} ->
{ok, Term}
end
@@ -622,21 +678,178 @@ check_rep(Fd, FilePosition, Device, RegExp, Number, Abort, Log) ->
case read_rep_msg(Fd, FilePosition) of
{Date, Msg} ->
MsgStr = lists:flatten(io_lib:format("~p",[Msg])),
- case regexp:match(MsgStr, RegExp) of
- {match, _, _} ->
+ case run_re(MsgStr, RegExp) of
+ match ->
io:format("Found match in report number ~w~n", [Number]),
case catch rb_format_supp:print(Date, Msg, Device) of
{'EXIT', _} ->
handle_bad_form(Date, Msg, Device, Abort, Log);
_ ->
{proceed,Device}
- end;
+ end;
+ _ ->
+ {proceed,Device}
+ end;
+ _ ->
+ io:format("rb: Cannot read from file~n"),
+ {proceed,Device}
+ end.
+
+run_re(Subject, {Regexp, Options}) ->
+ run_re(Subject, Regexp, Options);
+run_re(Subject, Regexp) ->
+ run_re(Subject, Regexp, []).
+
+run_re(Subject, Regexp, Options) ->
+ case re:run(Subject, Regexp, Options) of
+ nomatch ->
+ nomatch;
+ _ ->
+ match
+ end.
+
+filter_all_reports(_Dir, [], _Filters, Device, _Abort, _Log) ->
+ Device;
+filter_all_reports(Dir, Data, Filters, Device, Abort, Log) ->
+ {Next,Device1} = filter_report(Dir, Data, Filters, element(1, hd(Data)),
+ Device, Abort, Log),
+ if Next == abort ->
+ Device1;
+ true ->
+ filter_all_reports(Dir, tl(Data), Filters, Device1, Abort, Log)
+ end.
+
+filter_report(Dir, Data, Filters, Number, Device, Abort, Log) ->
+ case find_report(Data, Number) of
+ {Fname, FilePosition} ->
+ FileName = lists:concat([Dir, Fname]),
+ case file:open(FileName, [read]) of
+ {ok, Fd} ->
+ filter_rep(Filters, Fd, FilePosition, Device, Abort, Log);
+ _ ->
+ io:format("rb: can't open file ~p~n", [Fname]),
+ {proceed,Device}
+ end;
+ no_report ->
+ {proceed,Device}
+ end.
+
+filter_rep({Filters, FDates}, Fd, FilePosition, Device, Abort, Log) ->
+ RepMsg = read_rep_msg(Fd, FilePosition),
+ case RepMsg of
+ {_DateStr, {Date, _Msg}} ->
+ case compare_dates(Date, FDates) of
+ true ->
+ print_filter_report(RepMsg, Filters, Device, Abort, Log);
_ ->
{proceed,Device}
end;
_ ->
io:format("rb: Cannot read from file~n"),
{proceed,Device}
+ end;
+filter_rep(Filters, Fd, FilePosition, Device, Abort, Log) ->
+ RepMsg = read_rep_msg(Fd, FilePosition),
+ case RepMsg of
+ {Date, Msg} ->
+ print_filter_report({Date, Msg}, Filters, Device, Abort, Log);
+ _ ->
+ io:format("rb: Cannot read from file~n"),
+ {proceed,Device}
+ end.
+
+filter_report([], _Msg) ->
+ true;
+filter_report([{Key, Value}|T], Msg) ->
+ case proplists:get_value(Key, Msg) of
+ Value ->
+ filter_report(T, Msg);
+ _ ->
+ false
+ end;
+filter_report([{Key, Value, no}|T], Msg) ->
+ case proplists:get_value(Key, Msg) of
+ Value ->
+ false;
+ _ ->
+ filter_report(T, Msg)
+ end;
+filter_report([{Key, RegExp, re}|T], Msg) ->
+ case proplists:get_value(Key, Msg) of
+ undefined ->
+ false;
+ Value ->
+ Subject = lists:flatten(io_lib:format("~p",[Value])),
+ case run_re(Subject, RegExp) of
+ match ->
+ filter_report(T, Msg);
+ _ -> false
+ end
+ end;
+filter_report([{Key, RegExp, re, no}|T], Msg) ->
+ case proplists:get_value(Key, Msg) of
+ undefined ->
+ false;
+ Value ->
+ Subject = lists:flatten(io_lib:format("~p",[Value])),
+ case run_re(Subject, RegExp) of
+ match -> false;
+ _ -> filter_report(T, Msg)
+ end
+ end.
+
+get_compare_dates(Date, CompareDate) ->
+ case application:get_env(sasl, utc_log) of
+ {ok, true} ->
+ {local_time_to_universal_time(Date),
+ local_time_to_universal_time(CompareDate)};
+ _ ->
+ {Date, CompareDate}
+ end.
+get_compare_dates(Date, From, To) ->
+ case application:get_env(sasl, utc_log) of
+ {ok, true} ->
+ {local_time_to_universal_time(Date),
+ local_time_to_universal_time(From),
+ local_time_to_universal_time(To)};
+ _ ->
+ {Date, From, To}
+ end.
+
+compare_dates(Date, {CompareDate, from}) ->
+ {Date2, DateFrom} = get_compare_dates(Date, CompareDate),
+ calendar:datetime_to_gregorian_seconds(Date2) >=
+ calendar:datetime_to_gregorian_seconds(DateFrom);
+compare_dates(Date, {CompareDate, to}) ->
+ {Date2, DateTo} = get_compare_dates(Date, CompareDate),
+ calendar:datetime_to_gregorian_seconds(Date2) =<
+ calendar:datetime_to_gregorian_seconds(DateTo);
+compare_dates(Date, {From, To}) ->
+ {Date2, DateFrom, DateTo} = get_compare_dates(Date, From, To),
+ calendar:datetime_to_gregorian_seconds(Date2) >=
+ calendar:datetime_to_gregorian_seconds(DateFrom)
+ andalso
+ calendar:datetime_to_gregorian_seconds(Date2) =<
+ calendar:datetime_to_gregorian_seconds(DateTo).
+
+print_filter_report({Date, Msg}, Filters, Device, Abort, Log) ->
+ {_D, M} = Msg,
+ {_, _, M2} = M,
+ case M2 of
+ {_, _, Report} ->
+ case filter_report(Filters, Report) of
+ true ->
+ case catch rb_format_supp:print(Date, Msg, Device) of
+ {'EXIT', _} ->
+ handle_bad_form(Date, Msg, Device, Abort, Log);
+ _ ->
+ {proceed,Device}
+ end;
+ _ ->
+ {proceed, Device}
+ end;
+ _ ->
+ {proceed,Device}
end.
read_rep(Fd, FilePosition, Device, Abort, Log) ->
diff --git a/lib/sasl/src/release_handler.erl b/lib/sasl/src/release_handler.erl
index 42c3d9dd4b..4c43277848 100644
--- a/lib/sasl/src/release_handler.erl
+++ b/lib/sasl/src/release_handler.erl
@@ -1,19 +1,19 @@
%%
%% %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
%% 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(release_handler).
@@ -144,7 +144,7 @@ start_link() ->
%% exit_reason()
%%-----------------------------------------------------------------
unpack_release(ReleaseName) ->
- gen_server:call(release_handler, {unpack_release, ReleaseName}, infinity).
+ call({unpack_release, ReleaseName}).
%%-----------------------------------------------------------------
%% Purpose: Checks the relup script for the specified version.
@@ -157,7 +157,7 @@ unpack_release(ReleaseName) ->
%% exit_reason()
%%-----------------------------------------------------------------
check_install_release(Vsn) ->
- gen_server:call(release_handler, {check_install_release, Vsn}, infinity).
+ call({check_install_release, Vsn}).
%%-----------------------------------------------------------------
@@ -172,16 +172,13 @@ check_install_release(Vsn) ->
%% exit_reason()
%%-----------------------------------------------------------------
install_release(Vsn) ->
- gen_server:call(release_handler,
- {install_release, Vsn, restart, []},
- infinity).
+ call({install_release, Vsn, restart, []}).
+
install_release(Vsn, Opt) ->
case check_install_options(Opt, restart, []) of
{ok, ErrorAction, InstallOpt} ->
- gen_server:call(release_handler,
- {install_release, Vsn, ErrorAction, InstallOpt},
- infinity);
+ call({install_release, Vsn, ErrorAction, InstallOpt});
Error ->
Error
end.
@@ -222,13 +219,13 @@ check_timeout(_Else) -> false.
%% exit_reason()
%%-----------------------------------------------------------------
make_permanent(Vsn) ->
- gen_server:call(release_handler, {make_permanent, Vsn}, infinity).
+ call({make_permanent, Vsn}).
%%-----------------------------------------------------------------
%% Purpose: Reboots the system from an old release.
%%-----------------------------------------------------------------
reboot_old_release(Vsn) ->
- gen_server:call(release_handler, {reboot_old_release, Vsn}, infinity).
+ call({reboot_old_release, Vsn}).
%%-----------------------------------------------------------------
%% Purpose: Deletes all files and directories used by the release
@@ -238,7 +235,7 @@ reboot_old_release(Vsn) ->
%% Reason = {permanent, Vsn} |
%%-----------------------------------------------------------------
remove_release(Vsn) ->
- gen_server:call(release_handler, {remove_release, Vsn}, infinity).
+ call({remove_release, Vsn}).
%%-----------------------------------------------------------------
%% Args: RelFile = string()
@@ -257,7 +254,7 @@ remove_release(Vsn) ->
%% Returns: ok | {error, Reason}
%%-----------------------------------------------------------------
set_unpacked(RelFile, LibDirs) ->
- gen_server:call(release_handler, {set_unpacked, RelFile, LibDirs}).
+ call({set_unpacked, RelFile, LibDirs}).
%%-----------------------------------------------------------------
%% Args: Vsn = string()
@@ -267,7 +264,7 @@ set_unpacked(RelFile, LibDirs) ->
%% Returns: ok | {error, Reason}
%%-----------------------------------------------------------------
set_removed(Vsn) ->
- gen_server:call(release_handler, {set_removed, Vsn}).
+ call({set_removed, Vsn}).
%%-----------------------------------------------------------------
%% Purpose: Makes it possible to install the start.boot,
@@ -278,14 +275,14 @@ set_removed(Vsn) ->
%% Returns: ok | {error, {no_such_release, Vsn}}
%%-----------------------------------------------------------------
install_file(Vsn, File) when is_list(File) ->
- gen_server:call(release_handler, {install_file, File, Vsn}).
+ call({install_file, File, Vsn}).
%%-----------------------------------------------------------------
%% Returns: [{Name, Vsn, [LibName], Status}]
%% Status = unpacked | current | permanent | old
%%-----------------------------------------------------------------
which_releases() ->
- gen_server:call(release_handler, which_releases).
+ call(which_releases).
%%-----------------------------------------------------------------
%% check_script(Script, LibDirs) -> ok | {error, Reason}
@@ -468,11 +465,11 @@ read_appspec(App, Dir) ->
throw(Reason)
end.
-
-
-
-
-
+%%-----------------------------------------------------------------
+%% call(Request) -> Term
+%%-----------------------------------------------------------------
+call(Req) ->
+ gen_server:call(release_handler, Req, infinity).
%%-----------------------------------------------------------------
diff --git a/lib/sasl/src/release_handler_1.erl b/lib/sasl/src/release_handler_1.erl
index e3e3caba99..9c0edf4e99 100644
--- a/lib/sasl/src/release_handler_1.erl
+++ b/lib/sasl/src/release_handler_1.erl
@@ -1,19 +1,19 @@
%%
%% %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
%% 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(release_handler_1).
@@ -554,7 +554,13 @@ get_supervisor_module(SupPid) ->
get_supervisor_module1(SupPid) ->
{status, _Pid, {module, _Mod},
[_PDict, _SysState, _Parent, _Dbg, Misc]} = sys:get_status(SupPid),
- [_Name, State, _Type, _Time] = Misc,
+ %% supervisor Misc field changed at R13B04, handle old and new variants here
+ State = case Misc of
+ [_Name, State1, _Type, _Time] ->
+ State1;
+ [_Header, _Data, {data, [{"State", State2}]}] ->
+ State2
+ end,
%% Cannot use #supervisor_state{module = Module} = State.
{ok, element(#supervisor_state.module, State)}.
diff --git a/lib/sasl/src/sasl.app.src b/lib/sasl/src/sasl.app.src
index cfe4b81ab6..8c814cfaf5 100644
--- a/lib/sasl/src/sasl.app.src
+++ b/lib/sasl/src/sasl.app.src
@@ -1,19 +1,19 @@
%%
%% %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
%% 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%
%%
{application, sasl,
@@ -32,6 +32,8 @@
sasl_report,
sasl_report_tty_h,
sasl_report_file_h,
+ si,
+ si_sasl_supp,
systools,
systools_make,
systools_rc,
diff --git a/lib/sasl/src/sasl.erl b/lib/sasl/src/sasl.erl
index 979d80159e..d1babaffff 100644
--- a/lib/sasl/src/sasl.erl
+++ b/lib/sasl/src/sasl.erl
@@ -1,19 +1,19 @@
%%
%% %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
%% 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(sasl).
@@ -126,13 +126,13 @@ type(_) -> all.
add_error_logger_mf(undefined) -> ok;
add_error_logger_mf({Dir, MaxB, MaxF}) ->
error_logger:add_report_handler(
- log_mf_h, log_mf_h:init(Dir, MaxB, MaxF, {sasl, pred})).
+ log_mf_h, log_mf_h:init(Dir, MaxB, MaxF, fun pred/1)).
delete_error_logger_mf(undefined) -> ok;
delete_error_logger_mf(_) ->
error_logger:delete_report_handler(log_mf_h).
-pred({_Type, GL, _Msg}) when node(GL) /= node() -> false;
+pred({_Type, GL, _Msg}) when node(GL) =/= node() -> false;
pred(_) -> true.
%%%-----------------------------------------------------------------
diff --git a/lib/sasl/src/sasl_report.erl b/lib/sasl/src/sasl_report.erl
index bad3a75151..c3e6fede15 100644
--- a/lib/sasl/src/sasl_report.erl
+++ b/lib/sasl/src/sasl_report.erl
@@ -1,40 +1,46 @@
%%
%% %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
%% 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(sasl_report).
--export([write_report/3]).
+-export([write_report/3, format_report/3]).
-write_report(Fd, What, {Time, {error_report, _GL, {Pid, Type, Report}}}) ->
+format_report(Fd, What, Report) ->
+ io_report(io_lib, Fd, What, Report).
+
+write_report(Fd, What, Report) ->
+ io_report(io, Fd, What, Report).
+
+io_report(IO, Fd, What, {Time, {error_report, _GL, {Pid, Type, Report}}}) ->
case is_my_error_report(What, Type) of
true ->
Head = write_head(Type, Time, Pid),
- write_report2(Fd, Head, Type, Report);
+ write_report2(IO, Fd, Head, Type, Report);
_ -> true
end;
-write_report(Fd, What, {Time, {info_report, _GL, {Pid, Type, Report}}}) ->
+io_report(IO, Fd, What, {Time, {info_report, _GL, {Pid, Type, Report}}}) ->
case is_my_info_report(What, Type) of
true ->
Head = write_head(Type, Time, Pid),
- write_report2(Fd, Head, Type, Report);
+ write_report2(IO, Fd, Head, Type, Report);
_ -> true
end;
-write_report(_Fd, _, _) ->
+io_report(_IO, _Fd, _, _) ->
false.
is_my_error_report(all, Type) -> is_my_error_report(Type);
@@ -50,20 +56,26 @@ is_my_info_report(_, _Type) -> false.
is_my_info_report(progress) -> true;
is_my_info_report(_) -> false.
-write_report2(Fd, Head, supervisor_report, Report) ->
+write_report2(IO, Fd, Head, supervisor_report, Report) ->
Name = sup_get(supervisor, Report),
Context = sup_get(errorContext, Report),
Reason = sup_get(reason, Report),
Offender = sup_get(offender, Report),
- io:format(Fd, Head ++ " Supervisor: ~p~n Context: ~p~n Reason: "
- "~80.18p~n Offender: ~80.18p~n~n",
- [Name,Context,Reason,Offender]);
-write_report2(Fd, Head, progress, Report) ->
+ FmtString = " Supervisor: ~p~n Context: ~p~n Reason: "
+ "~80.18p~n Offender: ~80.18p~n~n",
+ write_report_action(IO, Fd, Head ++ FmtString,
+ [Name,Context,Reason,Offender]);
+write_report2(IO, Fd, Head, progress, Report) ->
Format = format_key_val(Report),
- io:format(Fd, Head ++ "~s", [Format]);
-write_report2(Fd, Head, crash_report, Report) ->
+ write_report_action(IO, Fd, Head ++ "~s", [Format]);
+write_report2(IO, Fd, Head, crash_report, Report) ->
Format = proc_lib:format(Report),
- io:format(Fd, Head ++ "~s", [Format]).
+ write_report_action(IO, Fd, Head ++ "~s", [Format]).
+
+write_report_action(io, Fd, Format, Args) ->
+ io:format(Fd, Format, Args);
+write_report_action(io_lib, _Fd, Format, Args) ->
+ io_lib:format(Format, Args).
format_key_val([{Tag,Data}|Rep]) ->
io_lib:format(" ~16w: ~p~n",[Tag,Data]) ++ format_key_val(Rep);
diff --git a/lib/sasl/src/si_sasl_supp.erl b/lib/sasl/src/si_sasl_supp.erl
index 52dbed2e00..9c96d11c28 100644
--- a/lib/sasl/src/si_sasl_supp.erl
+++ b/lib/sasl/src/si_sasl_supp.erl
@@ -1,19 +1,19 @@
%%
%% %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
%% 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(si_sasl_supp).
@@ -57,13 +57,13 @@
h() -> print_help().
help() -> print_help().
-si_exec(Fun, Args) -> gen_server:call(si_server, {si_exec, Fun, Args}).
+si_exec(Fun, Args) -> call({si_exec, Fun, Args}).
start_log(FileName) ->
- gen_server:call(si_server, {start_log, FileName}).
+ call({start_log, FileName}).
stop_log() ->
- gen_server:call(si_server, stop_log).
+ call(stop_log).
abbrevs() ->
io:format("~p", [process_abbrevs()]).
@@ -123,7 +123,7 @@ start_link(_Options) ->
gen_server:start_link({local, si_server}, si_sasl_supp, [], []).
stop() ->
- gen_server:call(si_server, stop),
+ call(stop),
supervisor:delete_child(sasl_sup, si_server).
@@ -208,6 +208,12 @@ open_log_file(FileName) ->
%% 3. Code
%%--------------------------------------------------
+%%-----------------------------------------------------------------
+%% call(Request) -> Term
+%%-----------------------------------------------------------------
+call(Req) ->
+ gen_server:call(si_server, Req, infinity).
+
%%--------------------------------------------------
%% Makes a Pid of almost anything.
%% Returns: Pid|{error, Reason}
diff --git a/lib/sasl/vsn.mk b/lib/sasl/vsn.mk
index f1f50f7d20..d01a9bc4f1 100644
--- a/lib/sasl/vsn.mk
+++ b/lib/sasl/vsn.mk
@@ -1 +1 @@
-SASL_VSN = 2.1.8
+SASL_VSN = 2.1.9.2
diff --git a/lib/snmp/doc/src/Makefile b/lib/snmp/doc/src/Makefile
index e1e3c7f41a..e8d9efb148 100644
--- a/lib/snmp/doc/src/Makefile
+++ b/lib/snmp/doc/src/Makefile
@@ -247,9 +247,9 @@ release_docs_spec: docs
$(INSTALL_DIR) $(RELEASE_PATH)/man/man3
$(INSTALL_DATA) $(MAN3DIR)/* $(RELEASE_PATH)/man/man3
$(INSTALL_DIR) $(RELEASE_PATH)/man/man6
- $(INSTALL_DATA) $(MAN3DIR)/* $(RELEASE_PATH)/man/man6
+ $(INSTALL_DATA) $(MAN6DIR)/* $(RELEASE_PATH)/man/man6
$(INSTALL_DIR) $(RELEASE_PATH)/man/man7
- $(INSTALL_DATA) $(MAN3DIR)/* $(RELEASE_PATH)/man/man7
+ $(INSTALL_DATA) $(MAN7DIR)/* $(RELEASE_PATH)/man/man7
else
diff --git a/lib/snmp/doc/src/notes.xml b/lib/snmp/doc/src/notes.xml
index 96a444227d..1f675605f8 100644
--- a/lib/snmp/doc/src/notes.xml
+++ b/lib/snmp/doc/src/notes.xml
@@ -1,10 +1,10 @@
-<?xml version="1.0" encoding="latin1" ?>
+<?xml version="1.0" encoding="iso-8859-1" ?>
<!DOCTYPE chapter SYSTEM "chapter.dtd">
<chapter>
<header>
<copyright>
- <year>1996</year><year>2009</year>
+ <year>1996</year><year>2012</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
@@ -33,6 +33,488 @@
</header>
<section>
+ <title>SNMP Development Toolkit 4.17.4</title>
+
+ <p>Version 4.17.4 supports code replacement in runtime from/to
+ version 4.17.3, 4.17.2, 4.17.1, 4.17, 4.16.2, 4.16.1 and 4.16.</p>
+
+ <section>
+ <title>Improvements and new features</title>
+ <p>-</p>
+
+ <!--
+ <list type="bulleted">
+ <item>
+ <p>[agent] DoS attack using GET-BULK with large value of
+ MaxRepetitions.
+ A preventive method has been implementing by simply
+ limit the number of varbinds that can be included in
+ a Get-BULK response message. This is specified by the
+ new config option,
+ <seealso marker="snmp_app#agent_gb_max_vbs">gb_max_vbs</seealso>.
+ </p>
+ <p>Own Id: OTP-9700</p>
+ </item>
+
+ </list>
+ -->
+
+ </section>
+
+ <section>
+ <title>Reported Fixed Bugs and Malfunctions</title>
+ <!--
+ <p>-</p>
+ -->
+
+ <list type="bulleted">
+ <item>
+ <p>[agent] Simultaneous
+ <seealso marker="snmpa#backup">snmpa:backup/1,2</seealso>
+ calls can interfere.
+ The master agent did not check if a backup was already in
+ progress when a backup request was accepted. </p>
+ <p>Own Id: OTP-9884</p>
+ <p>Aux Id: Seq 11995</p>
+ </item>
+
+ <item>
+ <p>[agent] When sending an error message (reply) regarding
+ <c>snmpUnknownPDUHandlers</c>, the agent used the wrong OID. </p>
+ <p>Own Id: OTP-9747</p>
+ </item>
+
+ </list>
+
+ </section>
+
+ <section>
+ <title>Incompatibilities</title>
+ <p>-</p>
+ </section>
+
+ </section> <!-- 4.17.4 -->
+
+
+ <section>
+ <title>SNMP Development Toolkit 4.17.3</title>
+
+ <p>Version 4.17.3 supports code replacement in runtime from/to
+ version 4.17.2, 4.17.1, 4.17, 4.16.2, 4.16.1 and 4.16.</p>
+
+ <section>
+ <title>Improvements and new features</title>
+ <!--
+ <p>-</p>
+ -->
+
+ <list type="bulleted">
+ <item>
+ <p>[agent] DoS attack using GET-BULK with large value of
+ MaxRepetitions.
+ A preventive method has been implementing by simply
+ limit the number of varbinds that can be included in
+ a Get-BULK response message. This is specified by the
+ new config option,
+ <seealso marker="snmp_app#agent_gb_max_vbs">gb_max_vbs</seealso>.
+ </p>
+ <p>Own Id: OTP-9700</p>
+ </item>
+
+ <item>
+ <p>[agent] Mib server cache gclimit update function incorrectly calls
+ age update function.
+ The gclimit update function,
+ <seealso marker="snmpa#update_mibs_cache_gclimit">update_mibs_cache_gclimit/1</seealso>,
+ <em>incorrectly</em> called the age update function,
+ <seealso marker="snmpa#update_mibs_cache_age">update_mibs_cache_age/2</seealso>. </p>
+ <p>Johan Claesson</p>
+ <p>Own Id: OTP-9868</p>
+ </item>
+
+ </list>
+
+ </section>
+
+ <section>
+ <title>Reported Fixed Bugs and Malfunctions</title>
+ <p>-</p>
+
+ <!--
+ <list type="bulleted">
+ <item>
+ <p>[agent] Originating discovery problems. </p>
+ <p>Invalid state variable update during second stage of
+ discovery causes master agent crash. </p>
+ <p>Also the net_if process failed to activate socket
+ ({active, once}) after first discovery response was sent. </p>
+ <p>Own Id: OTP-8044</p>
+ <p>Aux Id: Seq 11295</p>
+ </item>
+
+ </list>
+ -->
+
+ </section>
+
+ <section>
+ <title>Incompatibilities</title>
+ <p>-</p>
+ </section>
+
+ </section> <!-- 4.17.3 -->
+
+
+ <section>
+ <title>SNMP Development Toolkit 4.17.2</title>
+
+ <p>Version 4.17.2 supports code replacement in runtime from/to
+ version 4.17.1, 4.17, 4.16.2, 4.16.1 and 4.16.</p>
+
+ <section>
+ <title>Improvements and new features</title>
+ <!--
+ <p>-</p>
+ -->
+
+ <list type="bulleted">
+ <item>
+ <p>[manager] It is now possible to provide an "override" value
+ for community when issuing SNMP requests (see the
+ <seealso marker="snmpm#sync_get">sync_get</seealso>,
+ <seealso marker="snmpm#async_get">async_get</seealso>,
+ <seealso marker="snmpm#sync_get_next">sync_get_next</seealso>,
+ <seealso marker="snmpm#async_get_next">async_get_next</seealso>,
+ <seealso marker="snmpm#sync_set">sync_set</seealso>,
+ <seealso marker="snmpm#async_set">async_set</seealso>,
+ <seealso marker="snmpm#sync_get_bulk">sync_get_bulk</seealso> and
+ <seealso marker="snmpm#async_get_bulk">async_get_bulk</seealso>
+ for more info). By "override" means that any community value
+ configured when the agent was registered, is overridden by
+ this value for <em>this</em> request. </p>
+ <p>Own Id: OTP-9236</p>
+ </item>
+
+ </list>
+
+ </section>
+
+ <section>
+ <title>Reported Fixed Bugs and Malfunctions</title>
+ <p>-</p>
+
+ <!--
+ <list type="bulleted">
+ <item>
+ <p>[agent] Originating discovery problems. </p>
+ <p>Invalid state variable update during second stage of
+ discovery causes master agent crash. </p>
+ <p>Also the net_if process failed to activate socket
+ ({active, once}) after first discovery response was sent. </p>
+ <p>Own Id: OTP-8044</p>
+ <p>Aux Id: Seq 11295</p>
+ </item>
+
+ </list>
+ -->
+
+ </section>
+
+ <section>
+ <title>Incompatibilities</title>
+ <p>-</p>
+ </section>
+
+ </section> <!-- 4.17.2 -->
+
+
+ <section>
+ <title>SNMP Development Toolkit 4.17.1</title>
+ <p>Version 4.17.1 supports code replacement in runtime from/to
+ version 4.17, 4.16.2, 4.16.1, 4.16, 4.15, 4.14 and 4.13.5.</p>
+
+ <section>
+ <title>Improvements and new features</title>
+ <p>-</p>
+ </section>
+
+ <section>
+ <title>Reported Fixed Bugs and Malfunctions</title>
+ <list type="bulleted">
+ <item>
+ <p>When the function FilterMod:accept_recv/2
+ returned false the SNMP agent stopped collecting messages from UDP.</p>
+ <p>Own Id: OTP-8761</p>
+ </item>
+ </list>
+ </section>
+
+ <section>
+ <title>Incompatibilities</title>
+ <p>-</p>
+ </section>
+ </section> <!-- 4.17.1 -->
+
+
+ <section>
+ <title>SNMP Development Toolkit 4.17</title>
+ <p>Version 4.17 supports code replacement in runtime from/to
+ version 4.16.2, 4.16.1, 4.16, 4.15, 4.14 and 4.13.5.</p>
+
+ <section>
+ <title>Improvements and new features</title>
+ <!--
+ <p>-</p>
+ -->
+ <list type="bulleted">
+ <item>
+ <p>[agent] Added very basic support for multiple SNMPv3
+ EngineIDs in a single agent. See
+ <seealso marker="snmpa#send_notification">send_notification/7</seealso>,
+ <seealso marker="snmpa_mpd#process_packet">process_packet/7</seealso>,
+ <seealso marker="snmpa_mpd#generate_response_msg">generate_response_msg/6</seealso> or
+ <seealso marker="snmpa_mpd#generate_msg">generate_msg/6</seealso>
+ for more info. </p>
+
+ <p>Own Id: OTP-8478</p>
+ </item>
+
+ </list>
+
+ </section>
+
+ <section>
+ <title>Reported Fixed Bugs and Malfunctions</title>
+ <p>-</p>
+
+ <!--
+ <list type="bulleted">
+ <item>
+ <p>The config utility
+ (<seealso marker="snmp#config">snmp:config/0</seealso>)
+ generated a default notify.conf
+ with a bad name for the starndard trap entry (was "stadard trap",
+ but should have been "standard trap"). This has been corrected. </p>
+ <p>Kenji Rikitake</p>
+ <p>Own Id: OTP-8433</p>
+ </item>
+
+ </list>
+ -->
+
+ </section>
+
+ <section>
+ <title>Incompatibilities</title>
+ <p>-</p>
+ </section>
+ </section> <!-- 4.17 -->
+
+
+ <section>
+ <title>SNMP Development Toolkit 4.16.2</title>
+ <p>Version 4.16.2 supports code replacement in runtime from/to
+ version 4.16.1, 4.16, 4.15, 4.14 and 4.13.5.</p>
+
+ <section>
+ <title>Improvements and new features</title>
+ <!--
+ <p>-</p>
+ -->
+ <list type="bulleted">
+ <item>
+ <p>[compiler] The SMI specifies that a table row OID should be
+ named: { &lt;tableIdentifier&gt; "1" }. </p>
+ <p>A new option has been introduced,
+ <seealso marker="snmpc#compiler_opts">relaxed_row_name_assign_check</seealso>,
+ that allows for a more liberal numbering scheme</p>
+ <p>Own Id: OTP-8574</p>
+ </item>
+
+ <item>
+ <p>[agent|manager] Changes to make snmp (forward) compatible with
+ the new version of the crypto application (released in R14).
+ As of R14, crypto is implemented using NIFs. Also,
+ the API is more strict. </p>
+ <p>Own Id: OTP-8594</p>
+ </item>
+
+ <item>
+ <p>Auto [agent] Changed default value for the MIB server cache.
+ GC is now on by default. </p>
+ <p>Own Id: OTP-8648</p>
+ </item>
+
+ </list>
+
+ </section>
+
+ <section>
+ <title>Reported Fixed Bugs and Malfunctions</title>
+ <!--
+ <p>-</p>
+ -->
+
+ <list type="bulleted">
+ <item>
+ <p>Encode/decode of Counter64 values larger than
+ 16#7fffffffffffffff (9223372036854775807) failed. </p>
+ <p>Own Id: OTP-8563</p>
+ </item>
+
+ <item>
+ <p>[compiler] Fails to compile non-contiguous BITS. </p>
+ <p>Per Hedeland</p>
+ <p>Own Id: OTP-8595</p>
+ </item>
+
+ <item>
+ <p>[manager] Raise condition causing the manager server process to
+ crash. Unregistering an agent while traffic (set/get-operations)
+ is ongoing could cause a crash in the manager server process
+ (raise condition). </p>
+ <p>Own Id: OTP-8646</p>
+ <p>Aux Id: Seq 11585</p>
+ </item>
+
+ </list>
+
+ </section>
+
+ <section>
+ <title>Incompatibilities</title>
+ <p>-</p>
+ </section>
+ </section> <!-- 4.16.2 -->
+
+
+ <section>
+ <title>SNMP Development Toolkit 4.16.1</title>
+ <p>Version 4.16.1 supports code replacement in runtime from/to
+ version 4.16, 4.15, 4.14 and 4.13.5.</p>
+
+ <section>
+ <title>Improvements and new features</title>
+ <p>-</p>
+ <!--
+ <list type="bulleted">
+ <item>
+ <p>[agent|manager] Entries in the audit trail log can now be
+ augmented by a sequence number. </p>
+ <p>This is enabled by the <c>seqno</c> option, which is part of the
+ <seealso marker="snmp_config#audit_trail_log">Audit Trail Log</seealso>
+ config option. </p>
+ <p>See the
+ <seealso marker="snmp_app#configuration_params">reference manual</seealso>
+ or the
+ <seealso marker="snmp_config#configuration_params">Configuring the application</seealso>
+ chapter of the User's Guide for further info. </p>
+
+ <p>Own Id: OTP-8395</p>
+ </item>
+
+ </list>
+ -->
+
+ </section>
+
+ <section>
+ <title>Reported Fixed Bugs and Malfunctions</title>
+ <!--
+ <p>-</p>
+ -->
+
+ <list type="bulleted">
+ <item>
+ <p>[manager] Fixed an upgrade/downgrade problem. </p>
+ <p>Upgrade/downgrade from/to 4.13.5 did not work for the net-if
+ process. This has now been fixed. </p>
+ <p>Own Id: OTP-8481</p>
+ </item>
+
+ <item>
+ <p>[agent] A minor mnesia related performance improvement. </p>
+ <p>Own Id: OTP-8480</p>
+ </item>
+
+ </list>
+
+ </section>
+
+ <section>
+ <title>Incompatibilities</title>
+ <p>-</p>
+ </section>
+ </section> <!-- 4.16.1 -->
+
+
+ <section>
+ <title>SNMP Development Toolkit 4.16</title>
+ <p>Version 4.16 supports code replacement in runtime from/to
+ version 4.15, 4.14 and 4.13.5.</p>
+
+ <section>
+ <title>Improvements and new features</title>
+ <!--
+ <p>-</p>
+ -->
+ <list type="bulleted">
+ <item>
+ <p>[agent|manager] Entries in the audit trail log can now be
+ augmented by a sequence number. </p>
+ <p>This is enabled by the <c>seqno</c> option, which is part of the
+ <seealso marker="snmp_config#audit_trail_log">Audit Trail Log</seealso>
+ config option. </p>
+ <p>See the
+ <seealso marker="snmp_app#configuration_params">reference manual</seealso>
+ or the
+ <seealso marker="snmp_config#configuration_params">Configuring the application</seealso>
+ chapter of the User's Guide for further info. </p>
+
+ <p>Own Id: OTP-8395</p>
+ </item>
+
+ </list>
+
+ </section>
+
+ <section>
+ <title>Reported Fixed Bugs and Malfunctions</title>
+ <!--
+ <p>-</p>
+ -->
+
+ <list type="bulleted">
+ <item>
+ <p>[manager] Registration of agents using the config file,
+ <seealso marker="snmp_manager_config_files#agents">agents.conf</seealso>,
+ does not work. This has now been corrected. </p>
+ <p>Per Hedeland</p>
+ <p>Own Id: OTP-8442</p>
+ </item>
+
+ <item>
+ <p>The config utility
+ (<seealso marker="snmp#config">snmp:config/0</seealso>)
+ generated a default notify.conf
+ with a bad name for the starndard trap entry (was "stadard trap",
+ but should have been "standard trap"). This has been corrected. </p>
+ <p>Kenji Rikitake</p>
+ <p>Own Id: OTP-8433</p>
+ </item>
+
+ </list>
+
+ </section>
+
+ <section>
+ <title>Incompatibilities</title>
+ <p>-</p>
+ </section>
+ </section> <!-- 4.16 -->
+
+
+ <section>
<title>SNMP Development Toolkit 4.15</title>
<p>Version 4.15 supports code replacement in runtime from/to
diff --git a/lib/snmp/doc/src/notes_history.xml b/lib/snmp/doc/src/notes_history.xml
index 8739400773..934df87866 100644
--- a/lib/snmp/doc/src/notes_history.xml
+++ b/lib/snmp/doc/src/notes_history.xml
@@ -4,7 +4,7 @@
<chapter>
<header>
<copyright>
- <year>2004</year><year>2009</year>
+ <year>2004</year><year>2010</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
@@ -13,12 +13,12 @@
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>SNMP Release Notes history</title>
@@ -1732,7 +1732,7 @@
version 4.1. </p>
<p>When performing a downgrade, make sure the verbosity of the
manager server process is silence, or else the process will crash
- (due to a bug in version 4.0.4) and be restarted by it's
+ (due to a bug in version 4.0.4) and be restarted by its
supervisor.</p>
<section>
@@ -1773,7 +1773,7 @@
version 4.0.4. </p>
<p>When performing a downgrade, make sure the verbosity of the
manager server process is silence, or else the process will crash
- (due to a bug in version 4.0.4) and be restarted by it's
+ (due to a bug in version 4.0.4) and be restarted by its
supervisor.</p>
<section>
@@ -1827,8 +1827,8 @@
</item>
<item>
<p>[manager] The server process contained a bug that caused it
- to crash, if it received an exit message from it's gct (GC timer)
- process and it's verbosity was <em>log</em> or higher. </p>
+ to crash, if it received an exit message from its gct (GC timer)
+ process and its verbosity was <em>log</em> or higher. </p>
<p>This also effects the application downgrade. </p>
<p>Own Id: OTP-5306</p>
</item>
diff --git a/lib/snmp/doc/src/snmp_app.xml b/lib/snmp/doc/src/snmp_app.xml
index 460f0b8018..f6abe783b3 100644
--- a/lib/snmp/doc/src/snmp_app.xml
+++ b/lib/snmp/doc/src/snmp_app.xml
@@ -1,10 +1,10 @@
-<?xml version="1.0" encoding="latin1" ?>
+<?xml version="1.0" encoding="iso-8859-1" ?>
<!DOCTYPE appref SYSTEM "appref.dtd">
<appref>
<header>
<copyright>
- <year>1997</year><year>2009</year>
+ <year>1997</year><year>2011</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
@@ -13,12 +13,12 @@
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>snmp</title>
@@ -78,10 +78,18 @@
].
</pre>
- <p>Each snmp component has it's own set of configuration parameters,
- even though some of the types are common to both components. </p>
- <!-- Also in snmp_config.xml -->
+ <!--
+ ********************************************************
+
+ The info below is also found in the snmp_config.xml file
+
+ ********************************************************
+ -->
+
+
+ <p>Each snmp component has its own set of configuration parameters,
+ even though some of the types are common to both components. </p>
<pre>
snmp_components_config() -> [snmp_component_config()]
@@ -92,6 +100,7 @@
{agent_verbosity, verbosity()} |
{discovery, agent_discovery()} |
{versions, versions()} |
+ {gb_max_vbs, gb_max_vbs()} |
{priority, priority()} |
{multi_threaded, multi_threaded()} |
{db_dir, db_dir()} |
@@ -122,8 +131,10 @@
{def_user_data, def_user_data()}
</pre>
+ <marker id="agent_opts_and_types"></marker>
<p>Agent specific config options and types:</p>
<taglist>
+ <marker id="agent_type"></marker>
<tag><c><![CDATA[agent_type() = master | sub <optional>]]></c></tag>
<item>
<p>If <c>master</c>, one master agent is
@@ -131,6 +142,7 @@
<p>Default is <c>master</c>.</p>
</item>
+ <marker id="agent_disco"></marker>
<tag><c><![CDATA[agent_discovery() = [agent_discovery_opt()] <optional>]]></c></tag>
<item>
<p><c>agent_discovery_opt() =
@@ -143,6 +155,7 @@
<p>For defaults see the options in <c>agent_discovery_opt()</c>.</p>
</item>
+ <marker id="agent_term_disco_opts"></marker>
<tag><c><![CDATA[agent_terminating_discovery_opts() = [agent_terminating_discovery_opt()] <optional>]]></c></tag>
<item>
<p><c>agent_terminating_discovery_opt() =
@@ -160,6 +173,7 @@
</list>
</item>
+ <marker id="agent_orig_disco_opts"></marker>
<tag><c><![CDATA[agent_originating_discovery_opts() = [agent_originating_discovery_opt()] <optional>]]></c></tag>
<item>
<p><c>agent_originating_discovery_opt() =
@@ -173,6 +187,7 @@
</list>
</item>
+ <marker id="agent_mt"></marker>
<tag><c><![CDATA[multi_threaded() = bool() <optional>]]></c></tag>
<item>
<p>If <c>true</c>, the agent is multi-threaded, with one
@@ -180,11 +195,21 @@
<p>Default is <c>false</c>.</p>
</item>
+ <marker id="agent_data_dir"></marker>
<tag><c><![CDATA[db_dir() = string() <mandatory>]]></c></tag>
<item>
<p>Defines where the SNMP agent internal db files are stored.</p>
</item>
+ <marker id="agent_gb_max_vbs"></marker>
+ <tag><c><![CDATA[gb_max_vbs() = pos_integer() | infinity <optional>]]></c></tag>
+ <item>
+ <p>Defines the maximum number of varbinds allowed
+ in a Get-BULK response.</p>
+ <p>Default is <c>1000</c>.</p>
+ </item>
+
+ <marker id="agent_local_db"></marker>
<tag><c><![CDATA[local_db() = [local_db_opt()] <optional>]]></c></tag>
<item>
<p><c>local_db_opt() = {repair, agent_repair()} | {auto_save, agent_auto_save()} | {verbosity, verbosity()}</c></p>
@@ -192,6 +217,7 @@
<p>For defaults see the options in <c>local_db_opt()</c>.</p>
</item>
+ <marker id="agent_ldb_repair"></marker>
<tag><c><![CDATA[agent_repair() = false | true | force <optional>]]></c></tag>
<item>
<p>When starting snmpa_local_db it always tries to open an
@@ -202,6 +228,7 @@
<p>Default is <c>true</c>.</p>
</item>
+ <marker id="agent_ldb_auto_save"></marker>
<tag><c><![CDATA[agent_auto_save() = integer() | infinity <optional>]]></c></tag>
<item>
<p>The auto save interval. The table is flushed to disk
@@ -209,6 +236,7 @@
<p>Default is <c>5000</c>.</p>
</item>
+ <marker id="agent_net_if"></marker>
<tag><c><![CDATA[agent_net_if() = [agent_net_if_opt()] <optional>]]></c></tag>
<item>
<p><c>agent_net_if_opt() = {module, agent_net_if_module()} | {verbosity, verbosity()} | {options, agent_net_if_options()}</c></p>
@@ -217,6 +245,7 @@
<p>For defaults see the options in <c>agent_net_if_opt()</c>.</p>
</item>
+ <marker id="agent_ni_module"></marker>
<tag><c><![CDATA[agent_net_if_module() = atom() <optional>]]></c></tag>
<item>
<p>Module which handles the network interface part for the
@@ -225,6 +254,7 @@
<p>Default is <c>snmpa_net_if</c>.</p>
</item>
+ <marker id="agent_ni_opts"></marker>
<tag><c><![CDATA[agent_net_if_options() = [agent_net_if_option()] <optional>]]></c></tag>
<item>
<p><c>agent_net_if_option() = {bind_to, bind_to()} |
@@ -239,12 +269,14 @@
<p>For defaults see the options in <c>agent_net_if_option()</c>.</p>
</item>
+ <marker id="agent_ni_req_limit"></marker>
<tag><c><![CDATA[req_limit() = integer() | infinity <optional>]]></c></tag>
<item>
<p>Max number of simultaneous requests handled by the agent.</p>
<p>Default is <c>infinity</c>.</p>
</item>
+ <marker id="agent_ni_filter_opts"></marker>
<tag><c><![CDATA[agent_net_if_filter_options() = [agent_net_if_filter_option()] <optional>]]></c></tag>
<item>
<p><c>agent_net_if_filter_option() = {module, agent_net_if_filter_module()}</c></p>
@@ -255,6 +287,7 @@
<c>agent_net_if_filter_option()</c>.</p>
</item>
+ <marker id="agent_ni_filter_module"></marker>
<tag><c><![CDATA[agent_net_if_filter_module() = atom() <optional>]]></c></tag>
<item>
<p>Module which handles the network interface filter part for the
@@ -263,6 +296,7 @@
<p>Default is <c>snmpa_net_if_filter</c>.</p>
</item>
+ <marker id="agent_mibs"></marker>
<tag><c><![CDATA[agent_mibs() = [string()] <optional>]]></c></tag>
<item>
<p>Specifies a list of MIBs (including path) that defines which MIBs
@@ -277,6 +311,7 @@
<p>Default is <c>[]</c>.</p>
</item>
+ <marker id="agent_mib_storage"></marker>
<tag><c><![CDATA[mib_storage() = ets | {ets, Dir} | {ets, Dir, Action} | dets | {dets, Dir} | {dets, Dir, Action} | mnesia | {mnesia, Nodes} | {mnesia, Nodes, Action} <optional>]]></c></tag>
<item>
<p>Specifies how info retrieved from the mibs will be stored.</p>
@@ -302,6 +337,7 @@
mnesia/dets table already exist.</p>
</item>
+ <marker id="agent_mib_server"></marker>
<tag><c><![CDATA[mib_server() = [mib_server_opt()] <optional>]]></c></tag>
<item>
<p><c>mib_server_opt() = {mibentry_override, mibentry_override()} | {trapentry_override, trapentry_override()} | {verbosity, verbosity()} | {cache, mibs_cache()}</c></p>
@@ -309,6 +345,7 @@
<p>For defaults see the options in <c>mib_server_opt()</c>.</p>
</item>
+ <marker id="agent_ms_meo"></marker>
<tag><c><![CDATA[mibentry_override() = bool() <optional>]]></c></tag>
<item>
<p>If this value is false, then when loading a mib each mib-
@@ -318,6 +355,7 @@
<p>Default is <c>false</c>.</p>
</item>
+ <marker id="agent_ms_teo"></marker>
<tag><c><![CDATA[trapentry_override() = bool() <optional>]]></c></tag>
<item>
<p>If this value is false, then when loading a mib each trap
@@ -327,6 +365,7 @@
<p>Default is <c>false</c>.</p>
</item>
+ <marker id="agent_ms_cache"></marker>
<tag><c><![CDATA[mibs_cache() = bool() | mibs_cache_opts() <optional>]]></c></tag>
<item>
<p>Shall the agent utilize the mib server lookup cache or not.</p>
@@ -334,6 +373,7 @@
default values apply).</p>
</item>
+ <marker id="agent_ms_cache_opts"></marker>
<tag><c><![CDATA[mibs_cache_opts() = [mibs_cache_opt()] <optional>]]></c></tag>
<item>
<p><c>mibs_cache_opt() = {autogc, mibs_cache_autogc()} | {gclimit, mibs_cache_gclimit()} | {age, mibs_cache_age()}</c></p>
@@ -341,14 +381,16 @@
<p>For defaults see the options in <c>mibs_cache_opt()</c>.</p>
</item>
+ <marker id="agent_ms_cache_autogc"></marker>
<tag><c><![CDATA[mibs_cache_autogc() = bool() <optional>]]></c></tag>
<item>
<p>Defines if the mib server shall perform cache gc automatically or
leave it to the user (see
<seealso marker="snmpa#gc_mibs_cache">gc_mibs_cache/0,1,2,3</seealso>). </p>
- <p>Default is <c>false</c>.</p>
+ <p>Default is <c>true</c>.</p>
</item>
+ <marker id="agent_ms_cache_age"></marker>
<tag><c><![CDATA[mibs_cache_age() = integer() > 0 <optional>]]></c></tag>
<item>
<p>Defines how old the entries in the cache will be allowed before
@@ -358,6 +400,7 @@
<p>Default is <c>10 timutes</c>.</p>
</item>
+ <marker id="agent_ms_cache_gclimit"></marker>
<tag><c><![CDATA[mibs_cache_gclimit() = integer() > 0 | infinity <optional>]]></c></tag>
<item>
<p>When performing a GC, this is the max number of cache entries
@@ -368,6 +411,7 @@
<p>Default is <c>100</c>.</p>
</item>
+ <marker id="agent_error_report_mod"></marker>
<tag><c><![CDATA[error_report_mod() = atom() <optional>]]></c></tag>
<item>
<p>Defines an error report module, implementing the
@@ -377,6 +421,7 @@
<p>Default is <c>snmpa_error_logger</c>.</p>
</item>
+ <marker id="agent_symbolic_store"></marker>
<tag><c>symbolic_store() = [symbolic_store_opt()]</c></tag>
<item>
<p><c>symbolic_store_opt() = {verbosity, verbosity()}</c></p>
@@ -384,23 +429,29 @@
<p>For defaults see the options in <c>symbolic_store_opt()</c>.</p>
</item>
+ <marker id="agent_target_cache"></marker>
<tag><c>target_cache() = [target_cache_opt()]</c></tag>
<item>
<p><c>target_cache_opt() = {verbosity, verbosity()}</c></p>
<p>Defines options specific for the SNMP agent target cache. </p>
<p>For defaults see the options in <c>target_cache_opt()</c>.</p>
</item>
+
+ <marker id="agent_config"></marker>
<tag><c><![CDATA[agent_config() = [agent_config_opt()] <mandatory>]]></c></tag>
<item>
<p><c>agent_config_opt() = {dir, agent_config_dir()} | {force_load, force_load()} | {verbosity, verbosity()}</c></p>
<p>Defines specific config related options for the SNMP agent. </p>
<p>For defaults see the options in <c>agent_config_opt()</c>.</p>
</item>
+
+ <marker id="agent_config_dir"></marker>
<tag><c><![CDATA[agent_config_dir = dir() <mandatory>]]></c></tag>
<item>
<p>Defines where the SNMP agent configuration files are stored.</p>
</item>
+ <marker id="agent_force_load"></marker>
<tag><c><![CDATA[force_load() = bool() <optional>]]></c></tag>
<item>
<p>If <c>true</c> the configuration files are re-read
@@ -412,14 +463,18 @@
</item>
</taglist>
+ <marker id="manager_opts_and_types"></marker>
<p>Manager specific config options and types:</p>
<taglist>
+ <marker id="manager_server"></marker>
<tag><c><![CDATA[server() = [server_opt()] <optional>]]></c></tag>
<item>
<p><c>server_opt() = {timeout, server_timeout()} | {verbosity, verbosity()}</c></p>
<p>Specifies the options for the manager server process.</p>
<p>Default is <c>silence</c>.</p>
</item>
+
+ <marker id="manager_server_timeout"></marker>
<tag><c><![CDATA[server_timeout() = integer() <optional>]]></c></tag>
<item>
<p>Asynchroneous request cleanup time. For every requests,
@@ -440,6 +495,7 @@
<p>Default is <c>30000</c>.</p>
</item>
+ <marker id="manager_config"></marker>
<tag><c><![CDATA[manager_config() = [manager_config_opt()] <mandatory>]]></c></tag>
<item>
<p><c>manager_config_opt() = {dir, manager_config_dir()} | {db_dir, manager_db_dir()} | {db_init_error, db_init_error()} | {repair, manager_repair()} | {auto_save, manager_auto_save()} | {verbosity, verbosity()}</c></p>
@@ -447,16 +503,19 @@
<p>For defaults see the options in <c>manager_config_opt()</c>.</p>
</item>
+ <marker id="manager_config_dir"></marker>
<tag><c><![CDATA[manager_config_dir = dir() <mandatory>]]></c></tag>
<item>
<p>Defines where the SNMP manager configuration files are stored.</p>
</item>
+ <marker id="manager_config_db_dir"></marker>
<tag><c><![CDATA[manager_db_dir = dir() <mandatory>]]></c></tag>
<item>
<p>Defines where the SNMP manager store persistent data.</p>
</item>
+ <marker id="manager_config_repair"></marker>
<tag><c><![CDATA[manager_repair() = false | true | force <optional>]]></c></tag>
<item>
<p>Defines the repair option for the persistent database (if
@@ -464,6 +523,7 @@
<p>Default is <c>true</c>.</p>
</item>
+ <marker id="manager_config_auto_save"></marker>
<tag><c><![CDATA[manager_auto_save() = integer() | infinity <optional>]]></c></tag>
<item>
<p>The auto save interval. The table is flushed to disk
@@ -471,6 +531,7 @@
<p>Default is <c>5000</c>.</p>
</item>
+ <marker id="manager_irb"></marker>
<tag><c><![CDATA[manager_irb() = auto | user | {user, integer()} <optional>]]></c></tag>
<item>
<p>This option defines how the manager will handle the sending of
@@ -500,6 +561,7 @@
<p>Default is <c>auto</c>.</p>
</item>
+ <marker id="manager_mibs"></marker>
<tag><c><![CDATA[manager_mibs() = [string()] <optional>]]></c></tag>
<item>
<p>Specifies a list of MIBs (including path) and defines which MIBs
@@ -507,6 +569,7 @@
<p>Default is <c>[]</c>.</p>
</item>
+ <marker id="manager_net_if"></marker>
<tag><c><![CDATA[manager_net_if() = [manager_net_if_opt()] <optional>]]></c></tag>
<item>
<p><c>manager_net_if_opt() = {module, manager_net_if_module()} |
@@ -517,6 +580,7 @@
<p>For defaults see the options in <c>manager_net_if_opt()</c>.</p>
</item>
+ <marker id="manager_ni_opts"></marker>
<tag><c><![CDATA[manager_net_if_options() = [manager_net_if_option()] <optional>]]></c></tag>
<item>
<p><c>manager_net_if_option() = {bind_to, bind_to()} |
@@ -530,6 +594,7 @@
<p>For defaults see the options in <c>manager_net_if_option()</c>.</p>
</item>
+ <marker id="manager_ni_module"></marker>
<tag><c><![CDATA[manager_net_if_module() = atom() <optional>]]></c></tag>
<item>
<p>Module which handles the network interface part for the
@@ -538,6 +603,7 @@
<p>Default is <c>snmpm_net_if</c>.</p>
</item>
+ <marker id="manager_ni_filter_opts"></marker>
<tag><c><![CDATA[manager_net_if_filter_options() = [manager_net_if_filter_option()] <optional>]]></c></tag>
<item>
<p><c>manager_net_if_filter_option() = {module, manager_net_if_filter_module()}</c></p>
@@ -548,6 +614,7 @@
<c>manager_net_if_filter_option()</c>.</p>
</item>
+ <marker id="manager_ni_filter_module"></marker>
<tag><c><![CDATA[manager_net_if_filter_module() = atom() <optional>]]></c></tag>
<item>
<p>Module which handles the network interface filter part for the
@@ -556,6 +623,7 @@
<p>Default is <c>snmpm_net_if_filter</c>.</p>
</item>
+ <marker id="manager_def_user_module"></marker>
<tag><c><![CDATA[def_user_module() = atom() <optional>]]></c></tag>
<item>
<p>The module implementing the default user. See the
@@ -563,6 +631,7 @@
<p>Default is <c>snmpm_user_default</c>.</p>
</item>
+ <marker id="manager_def_user_data"></marker>
<tag><c><![CDATA[def_user_data() = term() <optional>]]></c></tag>
<item>
<p>Data for the default user. Passed to the user module when
@@ -571,8 +640,10 @@
</item>
</taglist>
+ <marker id="common_types"></marker>
<p>Common config types:</p>
<taglist>
+ <marker id="restart_type"></marker>
<tag><c>restart_type() = permanent | transient | temporary</c></tag>
<item>
<p>See <seealso marker="stdlib:supervisor#child_spec">supervisor</seealso>
@@ -580,6 +651,8 @@
<p>Default is <c>permanent</c> for the agent and <c>transient</c>
for the manager.</p>
</item>
+
+ <marker id="db_init_error"></marker>
<tag><c>db_init_error() = terminate | create</c></tag>
<item>
<p>Defines what to do if the agent or manager is unable to open an
@@ -588,23 +661,31 @@
agent/manager will remove the faulty file(s) and create new ones.</p>
<p>Default is <c>terminate</c>.</p>
</item>
+
+ <marker id="prio"></marker>
<tag><c><![CDATA[priority() = atom() <optional>]]></c></tag>
<item>
<p>Defines the Erlang priority for all SNMP processes.</p>
<p>Default is <c>normal</c>.</p>
</item>
+
+ <marker id="versions"></marker>
<tag><c><![CDATA[versions() = [version()] <optional>]]></c></tag>
<item>
<p><c>version() = v1 | v2 | v3</c></p>
<p>Which SNMP versions shall be accepted/used.</p>
<p>Default is <c>[v1,v2,v3]</c>.</p>
</item>
+
+ <marker id="verbosity"></marker>
<tag><c><![CDATA[verbosity() = silence | info | log | debug | trace <optional>]]></c></tag>
<item>
<p>Verbosity for a SNMP process. This specifies now much debug info
is printed.</p>
<p>Default is <c>silence</c>.</p>
</item>
+
+ <marker id="bind_to"></marker>
<tag><c><![CDATA[bind_to() = bool() <optional>]]></c></tag>
<item>
<p>If <c>true</c>, net_if binds to the IP address.
@@ -612,6 +693,8 @@
where it is running. </p>
<p>Default is <c>false</c>.</p>
</item>
+
+ <marker id="no_reuse"></marker>
<tag><c><![CDATA[no_reuse() = bool() <optional>]]></c></tag>
<item>
<p>If <c>true</c>, net_if does not specify that the IP
@@ -619,22 +702,30 @@
the address is set to reusable. </p>
<p>Default is <c>false</c>.</p>
</item>
+
+ <marker id="recbuf"></marker>
<tag><c><![CDATA[recbuf() = integer() <optional>]]></c></tag>
<item>
<p>Receive buffer size. </p>
<p>Default value is defined by <c>gen_udp</c>.</p>
</item>
+
+ <marker id="sndbuf"></marker>
<tag><c><![CDATA[sndbuf() = integer() <optional>]]></c></tag>
<item>
<p>Send buffer size. </p>
<p>Default value is defined by <c>gen_udp</c>.</p>
</item>
+
+ <marker id="note_store"></marker>
<tag><c><![CDATA[note_store() = [note_store_opt()] <optional>]]></c></tag>
<item>
<p><c>note_store_opt() = {timeout, note_store_timeout()} | {verbosity, verbosity()}</c></p>
<p>Specifies the start-up verbosity for the SNMP note store.</p>
<p>For defaults see the options in <c>note_store_opt()</c>.</p>
</item>
+
+ <marker id="ns_timeout"></marker>
<tag><c><![CDATA[note_store_timeout() = integer() <optional>]]></c></tag>
<item>
<p>Note cleanup time. When storing a note in the note store,
@@ -642,16 +733,21 @@
process performs a GC to remove the expired note's. Time in
milli-seconds.</p>
<p>Default is <c>30000</c>.</p>
+
</item>
+
+ <marker id="audit_trail_log"></marker>
<tag><c><![CDATA[audit_trail_log() = [audit_trail_log_opt()] <optional>]]></c></tag>
<item>
- <p><c>audit_trail_log_opt() = {type, atl_type()} | {dir, atl_dir()} | {size, atl_size()} | {repair, atl_repair()}</c></p>
+ <p><c>audit_trail_log_opt() = {type, atl_type()} | {dir, atl_dir()} | {size, atl_size()} | {repair, atl_repair()} | {seqno, atl_seqno()}</c></p>
<p>If present, this option specifies the options for the
audit trail logging. The <c>disk_log</c> module is used
to maintain a wrap log. If present, the <c>dir</c> and
<c>size</c> options are mandatory.</p>
<p>If not present, audit trail logging is not used.</p>
</item>
+
+ <marker id="atl_type"></marker>
<tag><c><![CDATA[atl_type() = read | write | read_write <optional>]]></c></tag>
<item>
<p>Specifies what type of an audit trail log should be used.
@@ -672,12 +768,16 @@
</list>
<p>Default is <c>read_write</c>.</p>
</item>
+
+ <marker id="atl_dir"></marker>
<tag><c><![CDATA[atl_dir = dir() <mandatory>]]></c></tag>
<item>
<p>Specifies where the audit trail log should be stored.</p>
<p>If <c>audit_trail_log</c> specifies that logging should take
place, this parameter <em>must</em> be defined.</p>
</item>
+
+ <marker id="atl_size"></marker>
<tag><c><![CDATA[atl_size() = {integer(), integer()} <mandatory>]]></c></tag>
<item>
<p>Specifies the size of the audit
@@ -685,17 +785,28 @@
<p>If <c>audit_trail_log</c> specifies that logging should
take place, this parameter <em>must</em> be defined.</p>
</item>
+
+ <marker id="atl_repair"></marker>
<tag><c><![CDATA[atl_repair() = true | false | truncate | snmp_repair <optional>]]></c></tag>
<item>
<p>Specifies if and how the audit trail log shall be repaired
when opened. Unless this parameter has the value <c>snmp_repair</c>
it is sent to <c>disk_log</c>. If, on the other hand, the value is
- <c>snmp_repair</c>, snmp attempts to handle certain faults on it's
+ <c>snmp_repair</c>, snmp attempts to handle certain faults on its
own. And even if it cannot repair the file, it does not truncate it
directly, but instead <em>moves it aside</em> for later off-line
analysis.</p>
<p>Default is <c>true</c>.</p>
</item>
+
+ <marker id="atl_seqno"></marker>
+ <tag><c><![CDATA[atl_seqno() = true | false <optional>]]></c></tag>
+ <item>
+ <p>Specifies if the audit trail log entries will be (sequence)
+ numbered or not. The range of the sequence numbers are according
+ to RFC 5424, i.e. 1 through 2147483647. </p>
+ <p>Default is <c>false</c>.</p>
+ </item>
</taglist>
</section>
diff --git a/lib/snmp/doc/src/snmp_config.xml b/lib/snmp/doc/src/snmp_config.xml
index 073cdde308..ab66a11387 100644
--- a/lib/snmp/doc/src/snmp_config.xml
+++ b/lib/snmp/doc/src/snmp_config.xml
@@ -1,10 +1,10 @@
-<?xml version="1.0" encoding="latin1" ?>
+<?xml version="1.0" encoding="iso-8859-1" ?>
<!DOCTYPE chapter SYSTEM "chapter.dtd">
<chapter>
<header>
<copyright>
- <year>1997</year><year>2009</year>
+ <year>1997</year><year>2011</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
@@ -13,12 +13,12 @@
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>Running the application</title>
@@ -40,6 +40,7 @@
<item>starting the application (agent and/or manager)</item>
<item>debugging the application (agent and/or manager)</item>
</list>
+
<p>Refer also to the chapter(s)
<seealso marker="snmp_agent_config_files">Definition of Agent Configuration Files</seealso> and
<seealso marker="snmp_manager_config_files">Definition of Manager Configuration Files</seealso> which contains more detailed information
@@ -73,13 +74,20 @@
</item>
</list>
+
+ <!--
+ *****************************************************
+
+ The info below is also found in the snmp_app.xml file
+
+ *****************************************************
+ -->
+
<p>The agent and manager uses (application) configuration parameters to
find out where these directories are located. The parameters should be
defined in an Erlang system configuration file. The following
configuration parameters are defined for the SNMP application:</p>
- <!-- Also in snmp_app.xml -->
-
<pre>
agent_options() = [agent_option()]
agent_option() = {restart_type, restart_type()} |
@@ -87,6 +95,7 @@
{agent_verbosity, verbosity()} |
{versions, versions()} |
{discovery, agent_discovery()} |
+ {gb_max_vbs, gb_max_vbs()} |
{priority, priority()} |
{multi_threaded, multi_threaded()} |
{db_dir, db_dir()} |
@@ -117,8 +126,10 @@
{def_user_data, def_user_data()}
</pre>
+ <marker id="agent_opts_and_types"></marker>
<p>Agent specific config options and types:</p>
<taglist>
+ <marker id="agent_type"></marker>
<tag><c><![CDATA[agent_type() = master | sub <optional>]]></c></tag>
<item>
<p>If <c>master</c>, one master agent is
@@ -126,6 +137,7 @@
<p>Default is <c>master</c>.</p>
</item>
+ <marker id="agent_disco"></marker>
<tag><c><![CDATA[agent_discovery() = [agent_discovery_opt()] <optional>]]></c></tag>
<item>
<p><c>agent_discovery_opt() =
@@ -138,6 +150,7 @@
<p>For defaults see the options in <c>agent_discovery_opt()</c>.</p>
</item>
+ <marker id="agent_term_disco_opts"></marker>
<tag><c><![CDATA[agent_terminating_discovery_opts() = [agent_terminating_discovery_opt()] <optional>]]></c></tag>
<item>
<p><c>agent_terminating_discovery_opt() =
@@ -155,6 +168,7 @@
</list>
</item>
+ <marker id="agent_orig_disco_opts"></marker>
<tag><c><![CDATA[agent_originating_discovery_opts() = [agent_originating_discovery_opt()] <optional>]]></c></tag>
<item>
<p><c>agent_originating_discovery_opt() =
@@ -168,6 +182,7 @@
</list>
</item>
+ <marker id="agent_mt"></marker>
<tag><c><![CDATA[multi_threaded() = bool() <optional>]]></c></tag>
<item>
<p>If <c>true</c>, the agent is multi-threaded, with one
@@ -175,11 +190,21 @@
<p>Default is <c>false</c>.</p>
</item>
+ <marker id="agent_data_dir"></marker>
<tag><c><![CDATA[db_dir() = string() <mandatory>]]></c></tag>
<item>
<p>Defines where the SNMP agent internal db files are stored.</p>
</item>
+ <marker id="agent_gb_max_vbs"></marker>
+ <tag><c><![CDATA[gb_max_vbs() = pos_integer() | infinity <optional>]]></c></tag>
+ <item>
+ <p>Defines the maximum number of varbinds allowed
+ in a Get-BULK response.</p>
+ <p>Default is <c>1000</c>.</p>
+ </item>
+
+ <marker id="agent_local_db"></marker>
<tag><c><![CDATA[local_db() = [local_db_opt()] <optional>]]></c></tag>
<item>
<p><c>local_db_opt() = {repair, agent_repair()} | {auto_save, agent_auto_save()} | {verbosity, verbosity()}</c></p>
@@ -187,6 +212,7 @@
<p>For defaults see the options in <c>local_db_opt()</c>.</p>
</item>
+ <marker id="agent_ldb_repair"></marker>
<tag><c><![CDATA[agent_repair() = false | true | force <optional>]]></c></tag>
<item>
<p>When starting snmpa_local_db it always tries to open an
@@ -197,6 +223,7 @@
<p>Default is <c>true</c>.</p>
</item>
+ <marker id="agent_ldb_auto_save"></marker>
<tag><c><![CDATA[agent_auto_save() = integer() | infinity <optional>]]></c></tag>
<item>
<p>The auto save interval. The table is flushed to disk
@@ -204,6 +231,7 @@
<p>Default is <c>5000</c>.</p>
</item>
+ <marker id="agent_net_if"></marker>
<tag><c><![CDATA[agent_net_if() = [agent_net_if_opt()] <optional>]]></c></tag>
<item>
<p><c>agent_net_if_option() = {module, agent_net_if_module()} |
@@ -214,6 +242,7 @@
<p>For defaults see the options in <c>agent_net_if_opt()</c>.</p>
</item>
+ <marker id="agent_ni_module"></marker>
<tag><c><![CDATA[agent_net_if_module() = atom() <optional>]]></c></tag>
<item>
<p>Module which handles the network interface part for the
@@ -222,6 +251,7 @@
<p>Default is <c>snmpa_net_if</c>.</p>
</item>
+ <marker id="agent_ni_opts"></marker>
<tag><c><![CDATA[agent_net_if_options() = [agent_net_if_option()] <optional>]]></c></tag>
<item>
<p><c>agent_net_if_option() = {bind_to, bind_to()} |
@@ -236,6 +266,14 @@
<p>For defaults see the options in <c>agent_net_if_option()</c>.</p>
</item>
+ <marker id="agent_ni_req_limit"></marker>
+ <tag><c><![CDATA[req_limit() = integer() | infinity <optional>]]></c></tag>
+ <item>
+ <p>Max number of simultaneous requests handled by the agent.</p>
+ <p>Default is <c>infinity</c>.</p>
+ </item>
+
+ <marker id="agent_ni_filter_opts"></marker>
<tag><c><![CDATA[agent_net_if_filter_options() = [agent_net_if_filter_option()] <optional>]]></c></tag>
<item>
<p><c><![CDATA[agent_net_if_filter_option() = {module, agent_net_if_filter_module()}]]></c></p>
@@ -245,6 +283,7 @@
<p>For defaults see the options in <c>agent_net_if_filter_option()</c>.</p>
</item>
+ <marker id="agent_ni_filter_module"></marker>
<tag><c><![CDATA[agent_net_if_filter_module() = atom() <optional>]]></c></tag>
<item>
<p>Module which handles the network interface filter part for the
@@ -254,12 +293,7 @@
<p>Default is <c>snmpa_net_if_filter</c>.</p>
</item>
- <tag><c><![CDATA[req_limit() = integer() | infinity <optional>]]></c></tag>
- <item>
- <p>Max number of simultaneous requests handled by the agent.</p>
- <p>Default is <c>infinity</c>.</p>
- </item>
-
+ <marker id="agent_mibs"></marker>
<tag><c><![CDATA[agent_mibs() = [string()] <optional>]]></c></tag>
<item>
<p>Specifies a list of MIBs (including path) that defines which MIBs
@@ -274,6 +308,7 @@
<p>Default is <c>[]</c>.</p>
</item>
+ <marker id="agent_mib_storage"></marker>
<tag><c><![CDATA[mib_storage() = ets | {ets, Dir} | {ets, Dir, Action} | dets | {dets, Dir} | {dets, Dir, Action} | mnesia | {mnesia, Nodes} | {mnesia, Nodes, Action} <optional>]]></c></tag>
<item>
<p>Specifies how info retrieved from the mibs will be stored.</p>
@@ -299,6 +334,7 @@
mnesia/dets table already exist.</p>
</item>
+ <marker id="agent_mib_server"></marker>
<tag><c><![CDATA[mib_server() = [mib_server_opt()] <optional>]]></c></tag>
<item>
<p><c>mib_server_opt() = {mibentry_override, mibentry_override()} | {trapentry_override, trapentry_override()} | {verbosity, verbosity()} | {cache, mibs_cache()}</c></p>
@@ -306,6 +342,7 @@
<p>For defaults see the options in <c>mib_server_opt()</c>.</p>
</item>
+ <marker id="agent_ms_meo"></marker>
<tag><c><![CDATA[mibentry_override() = bool() <optional>]]></c></tag>
<item>
<p>If this value is false, then when loading a mib each mib-
@@ -315,6 +352,7 @@
<p>Default is <c>false</c>.</p>
</item>
+ <marker id="agent_ms_teo"></marker>
<tag><c><![CDATA[trapentry_override() = bool() <optional>]]></c></tag>
<item>
<p>If this value is false, then when loading a mib each trap
@@ -324,6 +362,7 @@
<p>Default is <c>false</c>.</p>
</item>
+ <marker id="agent_ms_cache"></marker>
<tag><c><![CDATA[mibs_cache() = bool() | mibs_cache_opts() <optional>]]></c></tag>
<item>
<p>Shall the agent utilize the mib server lookup cache or not.</p>
@@ -331,6 +370,7 @@
default values apply).</p>
</item>
+ <marker id="agent_ms_cache_opts"></marker>
<tag><c><![CDATA[mibs_cache_opts() = [mibs_cache_opt()] <optional>]]></c></tag>
<item>
<p><c>mibs_cache_opt() = {autogc, mibs_cache_autogc()} | {gclimit, mibs_cache_gclimit()} | {age, mibs_cache_age()}</c></p>
@@ -338,14 +378,16 @@
<p>For defaults see the options in <c>mibs_cache_opt()</c>.</p>
</item>
+ <marker id="agent_ms_cache_autogc"></marker>
<tag><c><![CDATA[mibs_cache_autogc() = bool() <optional>]]></c></tag>
<item>
<p>Defines if the mib server shall perform cache gc automatically or
leave it to the user (see
<seealso marker="snmpa#gc_mibs_cache">gc_mibs_cache/0,1,2,3</seealso>). </p>
- <p>Default is <c>false</c>.</p>
+ <p>Default is <c>true</c>.</p>
</item>
+ <marker id="agent_ms_cache_age"></marker>
<tag><c><![CDATA[mibs_cache_age() = integer() > 0 <optional>]]></c></tag>
<item>
<p>Defines how old the entries in the cache will be allowed before
@@ -355,6 +397,7 @@
<p>Default is <c>10 timutes</c>.</p>
</item>
+ <marker id="agent_ms_cache_gclimit"></marker>
<tag><c><![CDATA[mibs_cache_gclimit() = integer() > 0 | infinity <optional>]]></c></tag>
<item>
<p>When performing a GC, this is the max number of cache entries
@@ -365,6 +408,7 @@
<p>Default is <c>100</c>.</p>
</item>
+ <marker id="agent_error_report_mod"></marker>
<tag><c><![CDATA[error_report_mod() = atom() <optional>]]></c></tag>
<item>
<p>Defines an error report module, implementing the
@@ -374,6 +418,7 @@
<p>Default is <c>snmpa_error_logger</c>.</p>
</item>
+ <marker id="agent_symbolic_store"></marker>
<tag><c>symbolic_store() = [symbolic_store_opt()]</c></tag>
<item>
<p><c>symbolic_store_opt() = {verbosity, verbosity()}</c></p>
@@ -381,12 +426,15 @@
<p>For defaults see the options in <c>symbolic_store_opt()</c>.</p>
</item>
+ <marker id="agent_target_cache"></marker>
<tag><c>target_cache() = [target_cache_opt()]</c></tag>
<item>
<p><c>target_cache_opt() = {verbosity, verbosity()}</c></p>
<p>Defines options specific for the SNMP agent target cache. </p>
<p>For defaults see the options in <c>target_cache_opt()</c>.</p>
</item>
+
+ <marker id="agent_config"></marker>
<tag><c><![CDATA[agent_config() = [agent_config_opt()] <mandatory>]]></c></tag>
<item>
<p><c>agent_config_opt() = {dir, agent_config_dir()} | {force_load, force_load()} | {verbosity, verbosity()}</c></p>
@@ -394,11 +442,13 @@
<p>For defaults see the options in <c>agent_config_opt()</c>.</p>
</item>
+ <marker id="agent_config_dir"></marker>
<tag><c><![CDATA[agent_config_dir = dir() <mandatory>]]></c></tag>
<item>
<p>Defines where the SNMP agent configuration files are stored.</p>
</item>
+ <marker id="agent_force_load"></marker>
<tag><c><![CDATA[force_load() = bool() <optional>]]></c></tag>
<item>
<p>If <c>true</c> the configuration files are re-read
@@ -410,14 +460,18 @@
</item>
</taglist>
+ <marker id="manager_opts_and_types"></marker>
<p>Manager specific config options and types:</p>
<taglist>
+ <marker id="manager_server"></marker>
<tag><c><![CDATA[server() = [server_opt()] <optional>]]></c></tag>
<item>
<p><c>server_opt() = {timeout, server_timeout()} | {verbosity, verbosity()}</c></p>
<p>Specifies the options for the manager server process.</p>
<p>Default is <c>silence</c>.</p>
</item>
+
+ <marker id="manager_server_timeout"></marker>
<tag><c><![CDATA[server_timeout() = integer() <optional>]]></c></tag>
<item>
<p>Asynchroneous request cleanup time. For every requests,
@@ -438,6 +492,7 @@
<p>Default is <c>30000</c>.</p>
</item>
+ <marker id="manager_config"></marker>
<tag><c><![CDATA[manager_config() = [manager_config_opt()] <mandatory>]]></c></tag>
<item>
<p><c>manager_config_opt() = {dir, manager_config_dir()} | {db_dir, manager_db_dir()} | {db_init_error, db_init_error()} | {repair, manager_repair()} | {auto_save, manager_auto_save()} | {verbosity, verbosity()}</c></p>
@@ -445,16 +500,19 @@
<p>For defaults see the options in <c>manager_config_opt()</c>.</p>
</item>
+ <marker id="manager_config_dir"></marker>
<tag><c><![CDATA[manager_config_dir = dir() <mandatory>]]></c></tag>
<item>
<p>Defines where the SNMP manager configuration files are stored.</p>
</item>
+ <marker id="manager_config_db_dir"></marker>
<tag><c><![CDATA[manager_db_dir = dir() <mandatory>]]></c></tag>
<item>
<p>Defines where the SNMP manager store persistent data.</p>
</item>
+ <marker id="manager_config_repair"></marker>
<tag><c><![CDATA[manager_repair() = false | true | force <optional>]]></c></tag>
<item>
<p>Defines the repair option for the persistent database (if
@@ -462,6 +520,7 @@
<p>Default is <c>true</c>.</p>
</item>
+ <marker id="manager_config_auto_save"></marker>
<tag><c><![CDATA[manager_auto_save() = integer() | infinity <optional>]]></c></tag>
<item>
<p>The auto save interval. The table is flushed to disk
@@ -469,6 +528,7 @@
<p>Default is <c>5000</c>.</p>
</item>
+ <marker id="manager_irb"></marker>
<tag><c><![CDATA[manager_irb() = auto | user | {user, integer()} <optional>]]></c></tag>
<item>
<p>This option defines how the manager will handle the sending of
@@ -498,6 +558,7 @@
<p>Default is <c>auto</c>.</p>
</item>
+ <marker id="manager_mibs"></marker>
<tag><c><![CDATA[manager_mibs() = [string()] <optional>]]></c></tag>
<item>
<p>Specifies a list of MIBs (including path) and defines which MIBs
@@ -505,6 +566,7 @@
<p>Default is <c>[]</c>.</p>
</item>
+ <marker id="manager_net_if"></marker>
<tag><c><![CDATA[manager_net_if() = [manager_net_if_opt()] <optional>]]></c></tag>
<item>
<p><c>manager_net_if_opt() = {module, manager_net_if_module()} |
@@ -515,6 +577,7 @@
<p>For defaults see the options in <c>manager_net_if_opt()</c>.</p>
</item>
+ <marker id="manager_ni_opts"></marker>
<tag><c><![CDATA[manager_net_if_options() = [manager_net_if_option()] <optional>]]></c></tag>
<item>
<p><c>manager_net_if_option() = {bind_to, bind_to()} |
@@ -528,6 +591,7 @@
<p>For defaults see the options in <c>manager_net_if_option()</c>.</p>
</item>
+ <marker id="manager_ni_module"></marker>
<tag><c><![CDATA[manager_net_if_module() = atom() <optional>]]></c></tag>
<item>
<p>Module which handles the network interface part for the
@@ -536,6 +600,7 @@
<p>Default is <c>snmpm_net_if</c>.</p>
</item>
+ <marker id="manager_ni_filter_opts"></marker>
<tag><c><![CDATA[manager_net_if_filter_options() = [manager_net_if_filter_option()] <optional>]]></c></tag>
<item>
<p><c>manager_net_if_filter_option() = {module, manager_net_if_filter_module()}</c></p>
@@ -546,6 +611,7 @@
<c>manager_net_if_filter_option()</c>.</p>
</item>
+ <marker id="manager_ni_filter_module"></marker>
<tag><c><![CDATA[manager_net_if_filter_module() = atom() <optional>]]></c></tag>
<item>
<p>Module which handles the network interface filter part for the
@@ -554,6 +620,7 @@
<p>Default is <c>snmpm_net_if_filter</c>.</p>
</item>
+ <marker id="manager_def_user_module"></marker>
<tag><c><![CDATA[def_user_module() = atom() <optional>]]></c></tag>
<item>
<p>The module implementing the default user. See the
@@ -561,6 +628,7 @@
<p>Default is <c>snmpm_user_default</c>.</p>
</item>
+ <marker id="manager_def_user_data"></marker>
<tag><c><![CDATA[def_user_data() = term() <optional>]]></c></tag>
<item>
<p>Data for the default user. Passed to the user when calling
@@ -569,8 +637,10 @@
</item>
</taglist>
+ <marker id="common_types"></marker>
<p>Common config types:</p>
<taglist>
+ <marker id="restart_type"></marker>
<tag><c>restart_type() = permanent | transient | temporary</c></tag>
<item>
<p>See <seealso marker="stdlib:supervisor#child_spec">supervisor</seealso>
@@ -579,6 +649,7 @@
for the manager.</p>
</item>
+ <marker id="db_init_error"></marker>
<tag><c>db_init_error() = terminate | create</c></tag>
<item>
<p>Defines what to do if the agent is unable to open an
@@ -588,12 +659,14 @@
<p>Default is <c>terminate</c>.</p>
</item>
+ <marker id="prio"></marker>
<tag><c><![CDATA[priority() = atom() <optional>]]></c></tag>
<item>
<p>Defines the Erlang priority for all SNMP processes.</p>
<p>Default is <c>normal</c>.</p>
</item>
+ <marker id="versions"></marker>
<tag><c><![CDATA[versions() = [version()] <optional>]]></c></tag>
<item>
<p><c>version() = v1 | v2 | v3</c></p>
@@ -601,6 +674,7 @@
<p>Default is <c>[v1,v2,v3]</c>.</p>
</item>
+ <marker id="verbosity"></marker>
<tag><c><![CDATA[verbosity() = silence | info | log | debug | trace <optional>]]></c></tag>
<item>
<p>Verbosity for a SNMP process. This specifies now much debug info
@@ -608,6 +682,7 @@
<p>Default is <c>silence</c>.</p>
</item>
+ <marker id="bind_to"></marker>
<tag><c><![CDATA[bind_to() = bool() <optional>]]></c></tag>
<item>
<p>If <c>true</c>, net_if binds to the IP address.
@@ -616,6 +691,7 @@
<p>Default is <c>false</c>.</p>
</item>
+ <marker id="no_reuse"></marker>
<tag><c><![CDATA[no_reuse() = bool() <optional>]]></c></tag>
<item>
<p>If <c>true</c>, net_if does not specify that the IP
@@ -624,17 +700,21 @@
<p>Default is <c>false</c>.</p>
</item>
+ <marker id="recbuf"></marker>
<tag><c><![CDATA[recbuf() = integer() <optional>]]></c></tag>
<item>
<p>Receive buffer size. </p>
<p>Default value is defined by <c>gen_udp</c>.</p>
</item>
+
+ <marker id="sndbuf"></marker>
<tag><c><![CDATA[sndbuf() = integer() <optional>]]></c></tag>
<item>
<p>Send buffer size. </p>
<p>Default value is defined by <c>gen_udp</c>.</p>
</item>
+ <marker id="note_store"></marker>
<tag><c><![CDATA[note_store() = [note_store_opt()] <optional>]]></c></tag>
<item>
<p><c>note_store_opt() = {timeout, note_store_timeout()} | {verbosity, verbosity()}</c></p>
@@ -642,6 +722,7 @@
<p>For defaults see the options in <c>note_store_opt()</c>.</p>
</item>
+ <marker id="ns_timeout"></marker>
<tag><c><![CDATA[note_store_timeout() = integer() <optional>]]></c></tag>
<item>
<p>Note cleanup time. When storing a note in the note store,
@@ -651,9 +732,10 @@
<p>Default is <c>30000</c>.</p>
</item>
+ <marker id="audit_trail_log"></marker>
<tag><c><![CDATA[audit_trail_log() [audit_trail_log_opt()] <optional>]]></c></tag>
<item>
- <p><c>audit_trail_log_opt() = {type, atl_type()} | {dir, atl_dir()} | {size, atl_size()} | {repair, atl_repair()}</c></p>
+ <p><c>audit_trail_log_opt() = {type, atl_type()} | {dir, atl_dir()} | {size, atl_size()} | {repair, atl_repair()} | {seqno, atl_seqno()}</c></p>
<p>If present, this option specifies the options for the
<em>audit trail logging</em>. The <c>disk_log</c> module is used
to maintain a wrap log. If present, the <c>dir</c> and
@@ -661,6 +743,7 @@
<p>If not present, audit trail logging is not used.</p>
</item>
+ <marker id="atl_type"></marker>
<tag><c><![CDATA[atl_type() = read | write | read_write <optional>]]></c></tag>
<item>
<p>Specifies what type of an audit trail log should be used.
@@ -682,6 +765,7 @@
<p>Default is <c>read_write</c>.</p>
</item>
+ <marker id="atl_dir"></marker>
<tag><c><![CDATA[atl_dir = dir() <mandatory>]]></c></tag>
<item>
<p>Specifies where the audit trail log should be stored.</p>
@@ -689,6 +773,7 @@
place, this parameter <em>must</em> be defined.</p>
</item>
+ <marker id="atl_size"></marker>
<tag><c><![CDATA[atl_size() = {integer(), integer()} <mandatory>]]></c></tag>
<item>
<p>Specifies the size of the audit
@@ -697,17 +782,27 @@
take place, this parameter <em>must</em> be defined.</p>
</item>
+ <marker id="atl_repair"></marker>
<tag><c><![CDATA[atl_repair() = true | false | truncate | snmp_repair <optional>]]></c></tag>
<item>
<p>Specifies if and how the audit trail log shall be repaired
when opened. Unless this parameter has the value <c>snmp_repair</c>
it is sent to <c>disk_log</c>. If, on the other hand, the value is
- <c>snmp_repair</c>, snmp attempts to handle certain faults on it's
+ <c>snmp_repair</c>, snmp attempts to handle certain faults on its
own. And even if it cannot repair the file, it does not truncate it
directly, but instead <em>moves it aside</em> for later off-line
analysis.</p>
<p>Default is <c>true</c>.</p>
</item>
+
+ <marker id="atl_seqno"></marker>
+ <tag><c><![CDATA[atl_seqno() = true | false <optional>]]></c></tag>
+ <item>
+ <p>Specifies if the audit trail log entries will be (sequence)
+ numbered or not. The range of the sequence numbers are according
+ to RFC 5424, i.e. 1 through 2147483647. </p>
+ <p>Default is <c>false</c>.</p>
+ </item>
</taglist>
</section>
diff --git a/lib/snmp/doc/src/snmpa.xml b/lib/snmp/doc/src/snmpa.xml
index b3661ae9b0..3bc2063f4e 100644
--- a/lib/snmp/doc/src/snmpa.xml
+++ b/lib/snmp/doc/src/snmpa.xml
@@ -1,10 +1,10 @@
-<?xml version="1.0" encoding="latin1" ?>
+<?xml version="1.0" encoding="iso-8859-1" ?>
<!DOCTYPE erlref SYSTEM "erlref.dtd">
<erlref>
<header>
<copyright>
- <year>2004</year><year>2009</year>
+ <year>2004</year><year>2012</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
@@ -13,12 +13,12 @@
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>snmpa</title>
@@ -198,12 +198,18 @@ notification_delivery_info() = #snmpa_notification_delivery_info{}
<type>
<v>BackupDir = string()</v>
<v>Agent = pid() | atom()</v>
+ <v>Reason = backup_in_progress | term()</v>
</type>
<desc>
<p>Backup persistent/permanent data handled by the agent
(such as local-db, mib-data and vacm). </p>
<p>Data stored by mnesia is not handled. </p>
<p>BackupDir cannot be identical to DbDir. </p>
+ <p>Simultaneous backup calls are <em>not</em> allowed.
+ That is, two different processes cannot simultaneously
+ successfully call this function. One of them will be first,
+ and succeed. The second will fail with the error reason
+ <c>backup_in_progress</c>. </p>
<marker id="info"></marker>
</desc>
@@ -217,13 +223,13 @@ notification_delivery_info() = #snmpa_notification_delivery_info{}
</type>
<desc>
<p>Returns a list (a dictionary) containing information about
- the agent. Information includes loaded MIBs, registered
- sub-agents, some information about the memory allocation. </p>
- <p>As of version 4.4 the format of the info has been changed.
- To convert the info to the old format, call the
- <seealso marker="#old_info_format">old_info_format</seealso>
- function. </p>
-
+ the agent. Information includes loaded MIBs, registered
+ sub-agents, some information about the memory allocation. </p>
+ <p>As of version 4.4 the format of the info has been changed.
+ To convert the info to the old format, call the
+ <seealso marker="#old_info_format">old_info_format</seealso>
+ function. </p>
+
<marker id="old_info_format"></marker>
</desc>
</func>
@@ -648,6 +654,20 @@ notification_delivery_info() = #snmpa_notification_delivery_info{}
<desc>
<p>Disable the mib server cache. </p>
+ <marker id="which_mibs_cache_size"></marker>
+ </desc>
+ </func>
+
+ <func>
+ <name>which_mibs_cache_size() -> void()</name>
+ <name>which_mibs_cache_size(Agent) -> void()</name>
+ <fsummary>The size of the mib server cache</fsummary>
+ <type>
+ <v>Agent = pid() | atom()</v>
+ </type>
+ <desc>
+ <p>Retreive the size of the mib server cache. </p>
+
<marker id="gc_mibs_cache"></marker>
</desc>
</func>
@@ -867,6 +887,7 @@ snmp_agent:register_subagent(SA1,[1,2,3], SA2).
<name>send_notification(Agent, Notification, Receiver, Varbinds)</name>
<name>send_notification(Agent, Notification, Receiver, NotifyName, Varbinds)</name>
<name>send_notification(Agent, Notification, Receiver, NotifyName, ContextName, Varbinds) -> void() </name>
+ <name>send_notification(Agent, Notification, Receiver, NotifyName, ContextName, Varbinds, LocalEngineID) -> void() </name>
<fsummary>Send a notification</fsummary>
<type>
<v>Agent = pid() | atom()</v>
@@ -888,6 +909,7 @@ snmp_agent:register_subagent(SA1,[1,2,3], SA2).
<v>OID = oid()</v>
<v>Value = term()</v>
<v>RowIndex = [int()]</v>
+ <v>LocalEngineID = string()</v>
</type>
<desc>
<p>Sends the notification <c>Notification</c> to the
@@ -1027,6 +1049,7 @@ snmp_agent:register_subagent(SA1,[1,2,3], SA2).
<item><c>{?sysLocation_instance, "upstairs"}</c> (provided
that the generated <c>.hrl</c> file is included)</item>
</list>
+
<p>If a variable in the notification is a table element, the
<c>RowIndex</c> for the element must be given in the
<c>Varbinds</c> list. In this case, the OBJECT IDENTIFIER sent
@@ -1034,15 +1057,27 @@ snmp_agent:register_subagent(SA1,[1,2,3], SA2).
element. This OBJECT IDENTIFIER could be used in a get
operation later.
</p>
+
<p>This function is asynchronous, and does not return any
information. If an error occurs, <c>user_err/2</c> of the error
report module is called and the notification is discarded.
</p>
+ <note>
+ <p>Note that the use of the LocalEngineID argument is only intended
+ for special cases, if the agent is to "emulate" multiple EngineIDs!
+ By default, the agent uses the value of <c>SnmpEngineID</c>
+ (see SNMP-FRAMEWORK-MIB). </p>
+ </note>
+
+<!--
<marker id="send_trap"></marker>
+-->
+ <marker id="discovery"></marker>
</desc>
</func>
+<!--
<func>
<name>send_trap(Agent,Trap,Community)</name>
<name>send_trap(Agent,Trap,Community,Varbinds) -> void()</name>
@@ -1114,6 +1149,7 @@ snmp_agent:register_subagent(SA1,[1,2,3], SA2).
<marker id="discovery"></marker>
</desc>
</func>
+-->
<func>
<name>discovery(TargetName, Notification) -> {ok, ManagerEngineID} | {error, Reason}</name>
diff --git a/lib/snmp/doc/src/snmpa_conf.xml b/lib/snmp/doc/src/snmpa_conf.xml
index f383394b7a..d873574c6e 100644
--- a/lib/snmp/doc/src/snmpa_conf.xml
+++ b/lib/snmp/doc/src/snmpa_conf.xml
@@ -4,7 +4,7 @@
<erlref>
<header>
<copyright>
- <year>2006</year><year>2009</year>
+ <year>2006</year><year>2010</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
@@ -13,12 +13,12 @@
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>snmpa_conf</title>
diff --git a/lib/snmp/doc/src/snmpa_mpd.xml b/lib/snmp/doc/src/snmpa_mpd.xml
index ea5bde8956..202e6b5661 100644
--- a/lib/snmp/doc/src/snmpa_mpd.xml
+++ b/lib/snmp/doc/src/snmpa_mpd.xml
@@ -4,7 +4,7 @@
<erlref>
<header>
<copyright>
- <year>1999</year><year>2009</year>
+ <year>1999</year><year>2010</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
@@ -13,12 +13,12 @@
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>snmpa_mpd</title>
@@ -63,15 +63,19 @@
</func>
<func>
- <name>process_packet(Packet, TDomain, TAddress, State) -> {ok, Vsn, Pdu, PduMS, ACMData} | {discarded, Reason} | {discovery, DiscoPacket}</name>
+ <name>process_packet(Packet, TDomain, TAddress, State, NoteStore, Log) -> {ok, Vsn, Pdu, PduMS, ACMData} | {discarded, Reason} | {discovery, DiscoPacket}</name>
+ <name>process_packet(Packet, TDomain, TAddress, LocalEngineID, State, NoteStore, Log) -> {ok, Vsn, Pdu, PduMS, ACMData} | {discarded, Reason} | {discovery, DiscoPacket}</name>
<fsummary>Process a packet received from the network</fsummary>
<type>
<v>Packet = binary()</v>
<v>TDomain = snmpUDPDomain</v>
<v>TAddress = {Ip, Udp}</v>
+ <v>LocalEngineID = string()</v>
<v>Ip = {integer(), integer(), integer(), integer()}</v>
<v>Udp = integer()</v>
<v>State = mpd_state()</v>
+ <v>NoteStore = pid()</v>
+ <v>Log = snmp_log()</v>
<v>Vsn = 'version-1' | 'version-2' | 'version-3'</v>
<v>Pdu = #pdu</v>
<v>PduMs = integer()</v>
@@ -84,18 +88,27 @@
decryption as necessary. The return values should be passed the
agent.</p>
+ <note>
+ <p>Note that the use of the LocalEngineID argument is only intended
+ for special cases, if the agent is to "emulate" multiple EngineIDs!
+ By default, the agent uses the value of <c>SnmpEngineID</c>
+ (see SNMP-FRAMEWORK-MIB). </p>
+ </note>
+
<marker id="generate_response_msg"></marker>
</desc>
</func>
<func>
- <name>generate_response_msg(Vsn, RePdu, Type, ACMData) -> {ok, Packet} | {discarded, Reason}</name>
+ <name>generate_response_msg(Vsn, RePdu, Type, ACMData, Log) -> {ok, Packet} | {discarded, Reason}</name>
+ <name>generate_response_msg(Vsn, RePdu, Type, ACMData, LocalEngineID, Log) -> {ok, Packet} | {discarded, Reason}</name>
<fsummary>Generate a response packet to be sent to the network</fsummary>
<type>
<v>Vsn = 'version-1' | 'version-2' | 'version-3'</v>
<v>RePdu = #pdu</v>
<v>Type = atom()</v>
<v>ACMData = acm_data()</v>
+ <v>LocalEngineID = string()</v>
<v>Packet = binary()</v>
</type>
<desc>
@@ -103,17 +116,27 @@
network. <c>Type</c> is the <c>#pdu.type</c> of the original
request.</p>
+ <note>
+ <p>Note that the use of the LocalEngineID argument is only intended
+ for special cases, if the agent is to "emulate" multiple EngineIDs!
+ By default, the agent uses the value of <c>SnmpEngineID</c>
+ (see SNMP-FRAMEWORK-MIB). </p>
+ </note>
+
<marker id="generate_msg"></marker>
</desc>
</func>
<func>
- <name>generate_msg(Vsn, Pdu, MsgData, To) -> {ok, PacketsAndAddresses} | {discarded, Reason}</name>
+ <name>generate_msg(Vsn, NoteStore, Pdu, MsgData, To) -> {ok, PacketsAndAddresses} | {discarded, Reason}</name>
+ <name>generate_msg(Vsn, NoteStore, Pdu, MsgData, LocalEngineID, To) -> {ok, PacketsAndAddresses} | {discarded, Reason}</name>
<fsummary>Generate a request message to be sent to the network</fsummary>
<type>
<v>Vsn = 'version-1' | 'version-2' | 'version-3'</v>
+ <v>NoteStore = pid()</v>
<v>Pdu = #pdu</v>
<v>MsgData = msg_data()</v>
+ <v>LocalEngineID = string()</v>
<v>To = [dest_addrs()]</v>
<v>PacketsAndAddresses = [{TDomain, TAddress, Packet}]</v>
<v>TDomain = snmpUDPDomain</v>
@@ -136,6 +159,13 @@
also received from the requests mentioned above.
</p>
+ <note>
+ <p>Note that the use of the LocalEngineID argument is only intended
+ for special cases, if the agent is to "emulate" multiple EngineIDs!
+ By default, the agent uses the value of <c>SnmpEngineID</c>
+ (see SNMP-FRAMEWORK-MIB). </p>
+ </note>
+
<marker id="discarded_pdu"></marker>
</desc>
</func>
diff --git a/lib/snmp/doc/src/snmpa_network_interface_filter.xml b/lib/snmp/doc/src/snmpa_network_interface_filter.xml
index d625fd3e4a..10419517dd 100644
--- a/lib/snmp/doc/src/snmpa_network_interface_filter.xml
+++ b/lib/snmp/doc/src/snmpa_network_interface_filter.xml
@@ -4,7 +4,7 @@
<erlref>
<header>
<copyright>
- <year>2007</year><year>2009</year>
+ <year>2007</year><year>2010</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
@@ -13,12 +13,12 @@
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>snmpa_network_interface_filter</title>
@@ -153,7 +153,7 @@ pdu_type() = 'get-request' | 'get-next-request' | 'get-response' | 'set-request'
<p>For the message to be discarded all together, the function
<em>must</em> return <em>false</em>. </p>
<p>Note that it is possible for this function to filter out targets
- (but <em>not</em> add it's own) by returning an updated
+ (but <em>not</em> add its own) by returning an updated
<c>Targets</c> list (<c>NewTargets</c>). </p>
</desc>
</func>
diff --git a/lib/snmp/doc/src/snmpc.xml b/lib/snmp/doc/src/snmpc.xml
index 48d63d6c91..fbd0950c69 100644
--- a/lib/snmp/doc/src/snmpc.xml
+++ b/lib/snmp/doc/src/snmpc.xml
@@ -4,7 +4,7 @@
<erlref>
<header>
<copyright>
- <year>2004</year><year>2009</year>
+ <year>2004</year><year>2010</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
@@ -13,12 +13,12 @@
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>snmpc</title>
@@ -47,9 +47,10 @@
<type>
<v>File = string()</v>
<v>Options = [opt()]</v>
- <v>opt() = db() | deprecated() | description() | reference() | group_check() | i() | il() | imports() | module() | module_identity() | outdir() | no_defs() | verbosity() | warnings()</v>
+ <v>opt() = db() | relaxed_row_name_assign_check() | deprecated() | description() | reference() | group_check() | i() | il() | imports() | module() | module_identity() | outdir() | no_defs() | verbosity() | warnings()</v>
<v>db() = {db, volatile|persistent|mnesia}</v>
<v>deprecated() = {deprecated, bool()}</v>
+ <v>relaxed_row_name_assign_check() = relaxed_row_name_assign_check</v>
<v>description() = description</v>
<v>reference() = reference</v>
<v>group_check() = {group_check, bool()}</v>
@@ -71,75 +72,104 @@
compiled file <c>BinFileName</c> is called
<c><![CDATA[<File>.bin]]></c>. </p>
<list type="bulleted">
- <item>The option <c>db</c> specifies which database should
- be used for the default instrumentation. Default is
- <c>volatile</c>.
+ <item>
+ <p>The option <c>db</c> specifies which database should
+ be used for the default instrumentation. </p>
+ <p>Default is <c>volatile</c>. </p>
+ </item>
+ <item>
+ <p>The option <c>deprecated</c> specifies if a deprecated
+ definition should be kept or not. If the option is
+ false the MIB compiler will ignore all deprecated
+ definitions. </p>
+ <p>Default is <c>true</c>. </p>
</item>
- <item>The option <c>deprecated</c> specifies if a deprecated
- definition should be kept or not. If the option is
- false the MIB compiler will ignore all deprecated
- definitions. Default is <c>true</c>.
+ <item>
+ <p>The option <c>relaxed_row_name_assign_check</c>, if present,
+ specifies that the row name assign check shall not be done
+ strictly according to the SMI (which allows only the value 1).
+ With this option, all values greater than zero is allowed
+ (>= 1). This means that the error will be converted to a
+ warning. </p>
+ <p>By default it is not included, but if this option is present
+ it will be. </p>
</item>
- <item>The option <c>description</c> specifies if the text
- of the DESCRIPTION field will be included or not. By default
- it is not included, but if this option is present it will
- be.
+ <item>
+ <p>The option <c>description</c> specifies if the text
+ of the DESCRIPTION field will be included or not. </p>
+ <p>By default it is not included, but if this option is
+ present it will be. </p>
</item>
- <item>The option <c>reference</c> specifies if the text
- of the REFERENCE field, when found in a table definition,
- will be included or not. By default
- it is not included, but if this option is present it will
- be. The reference text will be placed in the allocList field
- of the mib-entry record (#me{}) for the table.
+ <item>
+ <p>The option <c>reference</c> specifies if the text
+ of the REFERENCE field, when found in a table definition,
+ will be included or not. </p>
+ <p>By default it is not included, but if this option is present
+ it will be. The reference text will be placed in the allocList
+ field of the mib-entry record (#me{}) for the table. </p>
</item>
- <item>The option <c>group_check</c> specifies whether the
- mib compiler should check the OBJECT-GROUP macro and
- the NOTIFICATION-GROUP macro for correctness or not.
- Default is <c>true</c>.
+ <item>
+ <p>The option <c>group_check</c> specifies whether the
+ mib compiler should check the OBJECT-GROUP macro and
+ the NOTIFICATION-GROUP macro for correctness or not. </p>
+ <p>Default is <c>true</c>. </p>
</item>
- <item>The option <c>i</c> specifies the path to search for
- imported (compiled) MIB files. The directories should be
- strings with a trailing directory delimiter. Default is
- <c>["./"]</c>.
+ <item>
+ <p>The option <c>i</c> specifies the path to search for
+ imported (compiled) MIB files. The directories should be
+ strings with a trailing directory delimiter. </p>
+ <p>Default is <c>["./"]</c>. </p>
</item>
- <item>The option <c>il</c> (include_lib) also specifies a
- list of directories to search for imported MIBs. It
- assumes that the first element in the directory name
- corresponds to an OTP application. The compiler will find
- the current installed version. For example, the value
- ["snmp/mibs/"] will be replaced by ["snmp-3.1.1/mibs/"]
- (or what the current version may be in the system). The
- current directory and the <c><![CDATA[<snmp-home>/priv/mibs/]]></c>
- are always listed last in the include path.
+ <item>
+ <p>The option <c>il</c> (include_lib) also specifies a
+ list of directories to search for imported MIBs. It
+ assumes that the first element in the directory name
+ corresponds to an OTP application. The compiler will find
+ the current installed version. For example, the value
+ ["snmp/mibs/"] will be replaced by ["snmp-3.1.1/mibs/"]
+ (or what the current version may be in the system). The
+ current directory and the
+ <c><![CDATA[<snmp-home>/priv/mibs/]]></c>
+ are always listed last in the include path. </p>
</item>
- <item>The option <c>imports</c>, if present, specifies that the
- IMPORT statement of the MIB shall be included in the compiled mib.
+ <item>
+ <p>The option <c>imports</c>, if present, specifies that
+ the IMPORT statement of the MIB shall be included in the
+ compiled mib. </p>
</item>
- <item>The option <c>module</c>, if present, specifies the
- name of a module which implements all instrumentation
- functions for the MIB. The name of all instrumentation
- functions must be the same as the corresponding managed
- object it implements.
+ <item>
+ <p>The option <c>module</c>, if present, specifies the
+ name of a module which implements all instrumentation
+ functions for the MIB. </p>
+ <p>The name of all instrumentation
+ functions must be the same as the corresponding managed
+ object it implements. </p>
</item>
- <item>The option <c>module_identity</c>, if present, specifies
- that the info part of the MODULE-IDENTITY statement of the MIB
- shall be included in the compiled mib.
+ <item>
+ <p>The option <c>module_identity</c>, if present, specifies
+ that the info part of the MODULE-IDENTITY statement of the MIB
+ shall be included in the compiled mib. </p>
</item>
- <item>The option <c>no_defs</c>, if present, specifies
- that if a managed object does not have an instrumentation
- function, the default instrumentation function should NOT
- be used, instead this is reported as an error, and the
- compilation aborts.
+ <item>
+ <p>The option <c>no_defs</c>, if present, specifies
+ that if a managed object does not have an instrumentation
+ function, the default instrumentation function should NOT
+ be used, instead this is reported as an error, and the
+ compilation aborts. </p>
</item>
- <item>The option <c>verbosity</c> specifies the verbosity of
- the SNMP mib compiler. I.e. if warning, info, log, debug
- and trace messages shall be shown. Default is <c>silence</c>.
- Note that if the option <c>warnings</c> is <c>true</c> and the
- option <c>verbosity</c> is <c>silence</c>, warning messages will
- still be shown.
+ <item>
+ <p>The option <c>verbosity</c> specifies the verbosity of
+ the SNMP mib compiler. I.e. if warning, info, log, debug
+ and trace messages shall be shown. </p>
+ <p>Default is <c>silence</c>. </p>
+ <p>Note that if the option <c>warnings</c> is <c>true</c> and the
+ option <c>verbosity</c> is <c>silence</c>, warning messages will
+ still be shown. </p>
</item>
- <item>The option <c>warnings</c> specifies whether warning
- messages should be shown. Default is <c>true</c>.
+ <item>
+ <p>The option <c>warnings</c> specifies whether warning
+ messages should be shown. </p>
+ <p>Default is <c>true</c>. </p>
</item>
</list>
<p>The MIB compiler understands both SMIv1 and SMIv2 MIBs. It
diff --git a/lib/snmp/doc/src/snmpm.xml b/lib/snmp/doc/src/snmpm.xml
index 9e7ac75daf..8f631363dc 100644
--- a/lib/snmp/doc/src/snmpm.xml
+++ b/lib/snmp/doc/src/snmpm.xml
@@ -1,10 +1,10 @@
-<?xml version="1.0" encoding="latin1" ?>
+<?xml version="1.0" encoding="iso-8859-1" ?>
<!DOCTYPE erlref SYSTEM "erlref.dtd">
<erlref>
<header>
<copyright>
- <year>2004</year><year>2009</year>
+ <year>2004</year><year>2011</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
@@ -13,12 +13,12 @@
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>snmpm</title>
@@ -488,15 +488,17 @@ priv_key = [integer()] (length is 16 if priv = usmDESPrivProtocol | usmAesCfb1
<func>
<name>sync_get(UserId, TargetName, Oids) -> {ok, SnmpReply, Remaining} | {error, Reason}</name>
- <name>sync_get(UserId, TargetName, ContextName, Oids) -> {ok, SnmpReply, Remaining} | {error, Reason}</name>
+ <name>sync_get(UserId, TargetName, CC, Oids) -> {ok, SnmpReply, Remaining} | {error, Reason}</name>
<name>sync_get(UserId, TargetName, Oids, Timeout) -> {ok, SnmpReply, Remaining} | {error, Reason}</name>
- <name>sync_get(UserId, TargetName, ContextName, Oids, Timeout) -> {ok, SnmpReply, Remaining} | {error, Reason}</name>
- <name>sync_get(UserId, TargetName, ContextName, Oids, Timeout, ExtraInfo) -> {ok, SnmpReply, Remaining} | {error, Reason}</name>
+ <name>sync_get(UserId, TargetName, CC, Oids, Timeout) -> {ok, SnmpReply, Remaining} | {error, Reason}</name>
+ <name>sync_get(UserId, TargetName, CC, Oids, Timeout, ExtraInfo) -> {ok, SnmpReply, Remaining} | {error, Reason}</name>
<fsummary>Synchronous <c>get-request</c></fsummary>
<type>
<v>UserId = term()</v>
<v>TargetName = target_name()</v>
- <v>ContextName = string()</v>
+ <v>CC = context_name() | {community, community()} | {context_name(), community()}</v>
+ <v>context_name() = string()</v>
+ <v>community() = string()</v>
<v>Oids = [oid()]</v>
<v>Timeout = integer()</v>
<v>ExtraInfo = term()</v>
@@ -512,19 +514,23 @@ priv_key = [integer()] (length is 16 if priv = usmDESPrivProtocol | usmAesCfb1
</type>
<desc>
<p>Synchronous <c>get-request</c>. </p>
+ <p>When the <c>CC</c> argument is the tuple
+ <c>{_, Community}</c>, the <c>Community</c> part will
+ override the previously configured community for this agent
+ (represented by <c>TargetName</c>). </p>
<p><c>Remaining</c> is the remaining time of the given or
- default timeout time.</p>
+ default timeout time.</p>
<p>When <em>Reason</em> is <em>{send_failed, ...}</em> it means that
- the net_if process failed to send the message. This could happen
- because of any number of reasons, i.e. encoding error. <em>R</em>
- is the actual reason in this case. </p>
- <p><c>ExtraInfo</c> is an opaque data structure passed on to
- the net-if process. The net-if process included in this
- application makes no use of this info, so the only use for it
- in such a configuration (when using the built in net-if) would
- be tracing.</p>
- <p>For <c>SnmpInfo</c>, see the user callback function
- <seealso marker="snmpm_user#handle_report">handle_report</seealso>.</p>
+ the net_if process failed to send the message. This could happen
+ because of any number of reasons, i.e. encoding error. <em>R</em>
+ is the actual reason in this case. </p>
+ <p><c>ExtraInfo</c> is an opaque data structure passed on to
+ the net-if process. The net-if process included in this
+ application makes no use of this info, so the only use for it
+ in such a configuration (when using the built in net-if) would
+ be tracing.</p>
+ <p>For <c>SnmpInfo</c>, see the user callback function
+ <seealso marker="snmpm_user#handle_report">handle_report</seealso>.</p>
<marker id="async_get"></marker>
</desc>
@@ -532,15 +538,17 @@ priv_key = [integer()] (length is 16 if priv = usmDESPrivProtocol | usmAesCfb1
<func>
<name>async_get(UserId, TargetName, Oids) -> {ok, ReqId} | {error, Reason}</name>
- <name>async_get(UserId, TargetName, ContextName, Oids) -> {ok, ReqId} | {error, Reason}</name>
+ <name>async_get(UserId, TargetName, CC, Oids) -> {ok, ReqId} | {error, Reason}</name>
<name>async_get(UserId, TargetName, Oids, Expire) -> {ok, ReqId} | {error, Reason}</name>
- <name>async_get(UserId, TargetName, ContextName, Oids, Expire) -> {ok, ReqId} | {error, Reason}</name>
- <name>async_get(UserId, TargetName, ContextName, Oids, Expire, ExtraInfo) -> {ok, ReqId} | {error, Reason}</name>
+ <name>async_get(UserId, TargetName, CC, Oids, Expire) -> {ok, ReqId} | {error, Reason}</name>
+ <name>async_get(UserId, TargetName, CC, Oids, Expire, ExtraInfo) -> {ok, ReqId} | {error, Reason}</name>
<fsummary>Asynchronous <c>get-request</c></fsummary>
<type>
<v>UserId = term()</v>
<v>TargetName = target_name()</v>
- <v>ContextName = string()</v>
+ <v>CC = context_name() | {community, community()} | {context_name(), community()}</v>
+ <v>context_name() = string()</v>
+ <v>community() = string()</v>
<v>Oids = [oid()]</v>
<v>Expire = integer()</v>
<v>ExtraInfo = term()</v>
@@ -550,31 +558,37 @@ priv_key = [integer()] (length is 16 if priv = usmDESPrivProtocol | usmAesCfb1
<desc>
<p>Asynchronous <c>get-request</c>.</p>
<p>The reply, if it arrives, will be delivered to the user
- through a call to the snmpm_user callback function
- <c>handle_pdu</c>.</p>
- <p>The <c>Expire</c> time indicates for how long the request is
- valid (after which the manager is free to delete it).</p>
- <p><c>ExtraInfo</c> is an opaque data structure passed on to
- the net-if process. The net-if process included in this
- application makes no use of this info, so the only use for it
- in such a configuration (when using the built in net-if) would
- be tracing.</p>
-
+ through a call to the snmpm_user callback function
+ <c>handle_pdu</c>.</p>
+ <p>When the <c>CC</c> argument is the tuple
+ <c>{_, Community}</c>, the <c>Community</c> part will
+ override the previously configured community for this agent
+ (represented by <c>TargetName</c>). </p>
+ <p>The <c>Expire</c> time indicates for how long the request is
+ valid (after which the manager is free to delete it).</p>
+ <p><c>ExtraInfo</c> is an opaque data structure passed on to
+ the net-if process. The net-if process included in this
+ application makes no use of this info, so the only use for it
+ in such a configuration (when using the built in net-if) would
+ be tracing.</p>
+
<marker id="sync_get_next"></marker>
</desc>
</func>
<func>
<name>sync_get_next(UserId, TargetName, Oids) -> {ok, SnmpReply, Remaining} | {error, Reason}</name>
- <name>sync_get_next(UserId, TargetName, ContextName, Oids) -> {ok, SnmpReply, Remaining} | {error, Reason}</name>
+ <name>sync_get_next(UserId, TargetName, CC, Oids) -> {ok, SnmpReply, Remaining} | {error, Reason}</name>
<name>sync_get_next(UserId, TargetName, Oids, Timeout) -> {ok, SnmpReply, Remaining} | {error, Reason}</name>
- <name>sync_get_next(UserId, TargetName, ContextName, Oids, Timeout) -> {ok, SnmpReply, Remaining} | {error, Reason}</name>
- <name>sync_get_next(UserId, TargetName, ContextName, Oids, Timeout, ExtraInfo) -> {ok, SnmpReply, Remaining} | {error, Reason}</name>
+ <name>sync_get_next(UserId, TargetName, CC, Oids, Timeout) -> {ok, SnmpReply, Remaining} | {error, Reason}</name>
+ <name>sync_get_next(UserId, TargetName, CC, Oids, Timeout, ExtraInfo) -> {ok, SnmpReply, Remaining} | {error, Reason}</name>
<fsummary>Synchronous <c>get-next-request</c></fsummary>
<type>
<v>UserId = term()</v>
<v>TargetName = target_name()</v>
- <v>ContextName = string()</v>
+ <v>CC = context_name() | {community, community()} | {context_name(), community()}</v>
+ <v>context_name() = string()</v>
+ <v>community() = string()</v>
<v>Oids = [oid()]</v>
<v>Timeout = integer()</v>
<v>ExtraInfo = term()</v>
@@ -585,16 +599,20 @@ priv_key = [integer()] (length is 16 if priv = usmDESPrivProtocol | usmAesCfb1
</type>
<desc>
<p>Synchronous <c>get-next-request</c>. </p>
- <p><c>Remaining</c> time of the given or default timeout time.</p>
- <p>When <em>Reason</em> is <em>{send_failed, ...}</em> it means that
- the net_if process failed to send the message. This could happen
- because of any number of reasons, i.e. encoding error. <em>R</em>
- is the actual reason in this case. </p>
- <p><c>ExtraInfo</c> is an opaque data structure passed on to
- the net-if process. The net-if process included in this
- application makes no use of this info, so the only use for it
- in such a configuration (when using the built in net-if) would
- be tracing.</p>
+ <p>When the <c>CC</c> argument is the tuple
+ <c>{_, Community}</c>, the <c>Community</c> part will
+ override the previously configured community for this agent
+ (represented by <c>TargetName</c>). </p>
+ <p><c>Remaining</c> time of the given or default timeout time.</p>
+ <p>When <em>Reason</em> is <em>{send_failed, ...}</em> it means that
+ the net_if process failed to send the message. This could happen
+ because of any number of reasons, i.e. encoding error. <em>R</em>
+ is the actual reason in this case. </p>
+ <p><c>ExtraInfo</c> is an opaque data structure passed on to
+ the net-if process. The net-if process included in this
+ application makes no use of this info, so the only use for it
+ in such a configuration (when using the built in net-if) would
+ be tracing.</p>
<marker id="async_get_next"></marker>
</desc>
@@ -602,15 +620,17 @@ priv_key = [integer()] (length is 16 if priv = usmDESPrivProtocol | usmAesCfb1
<func>
<name>async_get_next(UserId, TargetName, Oids) -> {ok, ReqId} | {error, Reason}</name>
- <name>async_get_next(UserId, TargetName, ContextName, Oids) -> {ok, ReqId} | {error, Reason}</name>
+ <name>async_get_next(UserId, TargetName, CC, Oids) -> {ok, ReqId} | {error, Reason}</name>
<name>async_get_next(UserId, TargetName, Oids, Expire) -> {ok, ReqId} | {error, Reason}</name>
- <name>async_get_next(UserId, TargetName, ContextName, Oids, Expire) -> {ok, ReqId} | {error, Reason}</name>
- <name>async_get_next(UserId, TargetName, ContextName, Oids, Expire, ExtraInfo) -> {ok, ReqId} | {error, Reason}</name>
+ <name>async_get_next(UserId, TargetName, CC, Oids, Expire) -> {ok, ReqId} | {error, Reason}</name>
+ <name>async_get_next(UserId, TargetName, CC, Oids, Expire, ExtraInfo) -> {ok, ReqId} | {error, Reason}</name>
<fsummary>Asynchronous <c>get-next-request</c></fsummary>
<type>
<v>UserId = term()</v>
<v>TargetName = target_name()</v>
- <v>ContextName = string()</v>
+ <v>CC = context_name() | {community, community()} | {context_name(), community()}</v>
+ <v>context_name() = string()</v>
+ <v>community() = string()</v>
<v>Oids = [oid()]</v>
<v>Expire = integer()</v>
<v>ExtraInfo = term()</v>
@@ -620,9 +640,13 @@ priv_key = [integer()] (length is 16 if priv = usmDESPrivProtocol | usmAesCfb1
<desc>
<p>Asynchronous <c>get-next-request</c>. </p>
<p>The reply will be delivered to the user through a call
- to the snmpm_user callback function <c>handle_pdu</c>.</p>
- <p>The <c>Expire</c> time indicates for how long the request is
- valid (after which the manager is free to delete it).</p>
+ to the snmpm_user callback function <c>handle_pdu</c>.</p>
+ <p>When the <c>CC</c> argument is the tuple
+ <c>{_, Community}</c>, the <c>Community</c> part will
+ override the previously configured community for this agent
+ (represented by <c>TargetName</c>). </p>
+ <p>The <c>Expire</c> time indicates for how long the request is
+ valid (after which the manager is free to delete it).</p>
<marker id="sync_set"></marker>
</desc>
@@ -630,15 +654,17 @@ priv_key = [integer()] (length is 16 if priv = usmDESPrivProtocol | usmAesCfb1
<func>
<name>sync_set(UserId, TargetName, VarsAndVals) -> {ok, SnmpReply, Remaining} | {error, Reason}</name>
- <name>sync_set(UserId, TargetName, ContextName, VarsAndVals) -> {ok, SnmpReply, Remaining} | {error, Reason}</name>
+ <name>sync_set(UserId, TargetName, CC, VarsAndVals) -> {ok, SnmpReply, Remaining} | {error, Reason}</name>
<name>sync_set(UserId, TargetName, VarsAndVals, Timeout) -> {ok, SnmpReply, Remaining} | {error, Reason}</name>
- <name>sync_set(UserId, TargetName, ContextName, VarsAndVals, Timeout) -> {ok, SnmpReply, Remaining} | {error, Reason}</name>
- <name>sync_set(UserId, TargetName, ContextName, VarsAndVals, Timeout, ExtraInfo) -> {ok, SnmpReply, Remaining} | {error, Reason}</name>
+ <name>sync_set(UserId, TargetName, CC, VarsAndVals, Timeout) -> {ok, SnmpReply, Remaining} | {error, Reason}</name>
+ <name>sync_set(UserId, TargetName, CC, VarsAndVals, Timeout, ExtraInfo) -> {ok, SnmpReply, Remaining} | {error, Reason}</name>
<fsummary>Synchronous <c>set-request</c></fsummary>
<type>
<v>UserId = term()</v>
<v>TargetName = target_name()</v>
- <v>ContextName = string()</v>
+ <v>CC = context_name() | {community, community()} | {context_name(), community()}</v>
+ <v>context_name() = string()</v>
+ <v>community() = string()</v>
<v>VarsAndVals = vars_and_vals()</v>
<v>Timeout = integer()</v>
<v>ExtraInfo = term()</v>
@@ -649,18 +675,22 @@ priv_key = [integer()] (length is 16 if priv = usmDESPrivProtocol | usmAesCfb1
</type>
<desc>
<p>Synchronous <c>set-request</c>. </p>
- <p><c>Remaining</c> time of the given or default timeout time.</p>
- <p>When <em>Reason</em> is <em>{send_failed, ...}</em> it means that
- the net_if process failed to send the message. This could happen
- because of any number of reasons, i.e. encoding error. <em>R</em>
- is the actual reason in this case. </p>
- <p>When <em>var_and_val()</em> is <em>{oid(), value()}</em>, the
- manager makes an educated guess based on the loaded mibs. </p>
- <p><c>ExtraInfo</c> is an opaque data structure passed on to
- the net-if process. The net-if process included in this
- application makes no use of this info, so the only use for it
- in such a configuration (when using the built in net-if) would
- be tracing.</p>
+ <p>When the <c>CC</c> argument is the tuple
+ <c>{_, Community}</c>, the <c>Community</c> part will
+ override the previously configured community for this agent
+ (represented by <c>TargetName</c>). </p>
+ <p><c>Remaining</c> time of the given or default timeout time.</p>
+ <p>When <em>Reason</em> is <em>{send_failed, ...}</em> it means that
+ the net_if process failed to send the message. This could happen
+ because of any number of reasons, i.e. encoding error. <em>R</em>
+ is the actual reason in this case. </p>
+ <p>When <em>var_and_val()</em> is <em>{oid(), value()}</em>, the
+ manager makes an educated guess based on the loaded mibs. </p>
+ <p><c>ExtraInfo</c> is an opaque data structure passed on to
+ the net-if process. The net-if process included in this
+ application makes no use of this info, so the only use for it
+ in such a configuration (when using the built in net-if) would
+ be tracing.</p>
<marker id="async_set"></marker>
</desc>
@@ -668,16 +698,19 @@ priv_key = [integer()] (length is 16 if priv = usmDESPrivProtocol | usmAesCfb1
<func>
<name>async_set(UserId, TargetName, VarsAndVals) -> {ok, ReqId} | {error, Reason}</name>
- <name>async_set(UserId, TargetName, ContextName, VarsAndVals) -> {ok, ReqId} | {error, Reason}</name>
+ <name>async_set(UserId, TargetName, CC, VarsAndVals) -> {ok, ReqId} | {error, Reason}</name>
<name>async_set(UserId, TargetName, VarsAndVals, Expire) -> {ok, ReqId} | {error, Reason}</name>
- <name>async_set(UserId, TargetName, ContextName, VarsAndVals, Expire) -> {ok, ReqId} | {error, Reason}</name>
- <name>async_set(UserId, TargetName, ContextName, VarsAndVals, Expire, ExtraInfo) -> {ok, ReqId} | {error, Reason}</name>
+ <name>async_set(UserId, TargetName, CC, VarsAndVals, Expire) -> {ok, ReqId} | {error, Reason}</name>
+ <name>async_set(UserId, TargetName, CC, VarsAndVals, Expire, ExtraInfo) -> {ok, ReqId} | {error, Reason}</name>
<fsummary>Asynchronous <c>set-request</c></fsummary>
<type>
<v>UserId = term()</v>
<v>TargetName = target_name()</v>
<v>VarsAndVals = vars_and_vals()</v>
- <v>Expire = integer()</v>
+ <v>CC = context_name() | {community, community()} | {context_name(), community()}</v>
+ <v>context_name() = string()</v>
+ <v>community() = string()</v>
+ <v>Expire = integer()</v>
<v>ExtraInfo = term()</v>
<v>ReqId = term()</v>
<v>Reason = term()</v>
@@ -685,16 +718,20 @@ priv_key = [integer()] (length is 16 if priv = usmDESPrivProtocol | usmAesCfb1
<desc>
<p>Asynchronous <c>set-request</c>. </p>
<p>The reply will be delivered to the user through a call
- to the snmpm_user callback function <c>handle_pdu</c>.</p>
- <p>The <c>Expire</c> time indicates for how long the request is
- valid (after which the manager is free to delete it).</p>
- <p>When <em>var_and_val()</em> is <em>{oid(), value()}</em>, the
- manager makes an educated guess based on the loaded mibs. </p>
- <p><c>ExtraInfo</c> is an opaque data structure passed on to
- the net-if process. The net-if process included in this
- application makes no use of this info, so the only use for it
- in such a configuration (when using the built in net-if) would
- be tracing.</p>
+ to the snmpm_user callback function <c>handle_pdu</c>.</p>
+ <p>When the <c>CC</c> argument is the tuple
+ <c>{_, Community}</c>, the <c>Community</c> part will
+ override the previously configured community for this agent
+ (represented by <c>TargetName</c>). </p>
+ <p>The <c>Expire</c> time indicates for how long the request is
+ valid (after which the manager is free to delete it).</p>
+ <p>When <em>var_and_val()</em> is <em>{oid(), value()}</em>, the
+ manager makes an educated guess based on the loaded mibs. </p>
+ <p><c>ExtraInfo</c> is an opaque data structure passed on to
+ the net-if process. The net-if process included in this
+ application makes no use of this info, so the only use for it
+ in such a configuration (when using the built in net-if) would
+ be tracing.</p>
<marker id="sync_get_bulk"></marker>
</desc>
@@ -702,17 +739,19 @@ priv_key = [integer()] (length is 16 if priv = usmDESPrivProtocol | usmAesCfb1
<func>
<name>sync_get_bulk(UserId, TragetName, NonRep, MaxRep, Oids) -> {ok, SnmpReply, Remaining} | {error, Reason}</name>
- <name>sync_get_bulk(UserId, TragetName, NonRep, MaxRep, ContextName, Oids) -> {ok, SnmpReply, Remaining} | {error, Reason}</name>
+ <name>sync_get_bulk(UserId, TragetName, NonRep, MaxRep, CC, Oids) -> {ok, SnmpReply, Remaining} | {error, Reason}</name>
<name>sync_get_bulk(UserId, TragetName, NonRep, MaxRep, Oids, Timeout) -> {ok, SnmpReply, Remaining} | {error, Reason}</name>
- <name>sync_get_bulk(UserId, TragetName, NonRep, MaxRep, ContextName, Oids, Timeout) -> {ok, SnmpReply, Remaining} | {error, Reason}</name>
- <name>sync_get_bulk(UserId, TragetName, NonRep, MaxRep, ContextName, Oids, Timeout, ExtraInfo) -> {ok, SnmpReply, Remaining} | {error, Reason}</name>
+ <name>sync_get_bulk(UserId, TragetName, NonRep, MaxRep, CC, Oids, Timeout) -> {ok, SnmpReply, Remaining} | {error, Reason}</name>
+ <name>sync_get_bulk(UserId, TragetName, NonRep, MaxRep, CC, Oids, Timeout, ExtraInfo) -> {ok, SnmpReply, Remaining} | {error, Reason}</name>
<fsummary>Synchronous <c>get-bulk-request</c></fsummary>
<type>
<v>UserId = term()</v>
<v>TargetName = target_name()</v>
<v>NonRep = integer()</v>
<v>MaxRep = integer()</v>
- <v>ContextName = string()</v>
+ <v>CC = context_name() | {community, community()} | {context_name(), community()}</v>
+ <v>context_name() = string()</v>
+ <v>community() = string()</v>
<v>Oids = [oid()]</v>
<v>Timeout = integer()</v>
<v>ExtraInfo = term()</v>
@@ -722,34 +761,40 @@ priv_key = [integer()] (length is 16 if priv = usmDESPrivProtocol | usmAesCfb1
</type>
<desc>
<p>Synchronous <c>get-bulk-request</c> (See RFC1905).</p>
+ <p>When the <c>CC</c> argument is the tuple
+ <c>{_, Community}</c>, the <c>Community</c> part will
+ override the previously configured community for this agent
+ (represented by <c>TargetName</c>). </p>
<p><c>Remaining</c> time of the given or default timeout time.</p>
- <p>When <em>Reason</em> is <em>{send_failed, ...}</em> it means that
- the net_if process failed to send the message. This could happen
- because of any number of reasons, i.e. encoding error. <em>R</em>
- is the actual reason in this case. </p>
- <p><c>ExtraInfo</c> is an opaque data structure passed on to
- the net-if process. The net-if process included in this
- application makes no use of this info, so the only use for it
- in such a configuration (when using the built in net-if) would
- be tracing.</p>
-
+ <p>When <em>Reason</em> is <em>{send_failed, ...}</em> it means that
+ the net_if process failed to send the message. This could happen
+ because of any number of reasons, i.e. encoding error. <em>R</em>
+ is the actual reason in this case. </p>
+ <p><c>ExtraInfo</c> is an opaque data structure passed on to
+ the net-if process. The net-if process included in this
+ application makes no use of this info, so the only use for it
+ in such a configuration (when using the built in net-if) would
+ be tracing.</p>
+
<marker id="async_get_bulk"></marker>
</desc>
</func>
<func>
<name>async_get_bulk(UserId, TargetName, NonRep, MaxRep, Oids) -> {ok, ReqId} | {error, Reason}</name>
- <name>async_get_bulk(UserId, TargetName, NonRep, MaxRep, ContextName, Oids) -> {ok, ReqId} | {error, Reason}</name>
+ <name>async_get_bulk(UserId, TargetName, NonRep, MaxRep, CC, Oids) -> {ok, ReqId} | {error, Reason}</name>
<name>async_get_bulk(UserId, TargetName, NonRep, MaxRep, Oids, Expire) -> {ok, ReqId} | {error, Reason}</name>
- <name>async_get_bulk(UserId, TargetName, NonRep, MaxRep, ContextName, Oids, Expire) -> {ok, ReqId} | {error, Reason}</name>
- <name>async_get_bulk(UserId, TargetName, NonRep, MaxRep, ContextName, Oids, Expire, ExtraInfo) -> {ok, ReqId} | {error, Reason}</name>
+ <name>async_get_bulk(UserId, TargetName, NonRep, MaxRep, CC, Oids, Expire) -> {ok, ReqId} | {error, Reason}</name>
+ <name>async_get_bulk(UserId, TargetName, NonRep, MaxRep, CC, Oids, Expire, ExtraInfo) -> {ok, ReqId} | {error, Reason}</name>
<fsummary>Asynchronous <c>get-bulk-request</c></fsummary>
<type>
<v>UserId = term()</v>
<v>TargetName = target_name()</v>
<v>NonRep = integer()</v>
<v>MaxRep = integer()</v>
- <v>ContextName = string()</v>
+ <v>CC = context_name() | {community, community()} | {context_name(), community()}</v>
+ <v>context_name() = string()</v>
+ <v>community() = string()</v>
<v>Oids = [oid()]</v>
<v>Expire = integer()</v>
<v>ExtraInfo = term()</v>
@@ -759,9 +804,13 @@ priv_key = [integer()] (length is 16 if priv = usmDESPrivProtocol | usmAesCfb1
<desc>
<p>Asynchronous <c>get-bulk-request</c> (See RFC1905).</p>
<p>The reply will be delivered to the user through a call
- to the snmpm_user callback function <c>handle_pdu</c>.</p>
+ to the snmpm_user callback function <c>handle_pdu</c>.</p>
+ <p>When the <c>CC</c> argument is the tuple
+ <c>{_, Community}</c>, the <c>Community</c> part will
+ override the previously configured community for this agent
+ (represented by <c>TargetName</c>). </p>
<p>The <c>Expire</c> time indicates for how long the request is
- valid (after which the manager is free to delete it).</p>
+ valid (after which the manager is free to delete it).</p>
<marker id="cancel_async_request"></marker>
</desc>
@@ -920,7 +969,7 @@ priv_key = [integer()] (length is 16 if priv = usmDESPrivProtocol | usmAesCfb1
<v>Oids = [oid()]</v>
</type>
<desc>
- <p>Transform a alias-name to it's oid.</p>
+ <p>Transform a alias-name to its oid.</p>
<p>Note that an alias-name is only unique within the mib, so
when loading several mib's into a manager, there might be
several instances of the same aliasname.</p>
@@ -938,7 +987,7 @@ priv_key = [integer()] (length is 16 if priv = usmDESPrivProtocol | usmAesCfb1
<v>Reason = term()</v>
</type>
<desc>
- <p>Transform a oid to it's aliasname.</p>
+ <p>Transform a oid to its aliasname.</p>
<marker id="oid_to_type"></marker>
</desc>
diff --git a/lib/snmp/src/agent/depend.mk b/lib/snmp/src/agent/depend.mk
index bc39e1fa35..078ef15821 100644
--- a/lib/snmp/src/agent/depend.mk
+++ b/lib/snmp/src/agent/depend.mk
@@ -52,6 +52,7 @@ $(EBIN)/snmpa_acm.$(EMULATOR): \
$(EBIN)/snmpa_agent.$(EMULATOR): \
snmpa_agent.erl \
+ snmpa_internal.hrl \
../misc/snmp_debug.hrl \
../misc/snmp_verbosity.hrl \
../../include/snmp_types.hrl
@@ -136,6 +137,7 @@ $(EBIN)/snmpa_set_lib.$(EMULATOR): \
$(EBIN)/snmpa_supervisor.$(EMULATOR): \
snmpa_supervisor.erl \
+ snmpa_internal.hrl \
../misc/snmp_debug.hrl \
../misc/snmp_verbosity.hrl
diff --git a/lib/snmp/src/agent/snmp_target_mib.erl b/lib/snmp/src/agent/snmp_target_mib.erl
index a3ac67b533..d5c4ec2578 100644
--- a/lib/snmp/src/agent/snmp_target_mib.erl
+++ b/lib/snmp/src/agent/snmp_target_mib.erl
@@ -42,8 +42,14 @@
%% Column not accessible via SNMP - needed when the agent sends informs
-define(snmpTargetAddrEngineId, 10).
%% Extra comlumns for the augmented table snmpTargetAddrExtTable
--define(snmpTargetAddrTMask, 11).
--define(snmpTargetAddrMMS, 12).
+-define(snmpTargetAddrTMask, 11).
+-define(snmpTargetAddrMMS, 12).
+
+-ifdef(snmp_extended_verbosity).
+-define(vt(F,A), ?vtrace(F, A)).
+-else.
+-define(vt(_F, _A), ok).
+-endif.
%%-----------------------------------------------------------------
@@ -410,10 +416,16 @@ get_target_addrs() ->
get_target_addrs(Key, {Tab, _} = TabDb, Acc) ->
+ ?vt("get_target_addrs -> entry with"
+ "~n Key: ~p", [Key]),
case table_next(Tab, Key) of
endOfTable ->
+ ?vt("get_target_addrs -> endOfTable when"
+ "~n Acc: ~p", [Acc]),
Acc;
NextKey ->
+ ?vt("get_target_addrs -> next ok: "
+ "~n NextKey: ~p", [NextKey]),
case get_target_addr(TabDb, NextKey) of
{ok, Targ} ->
get_target_addrs(NextKey, TabDb, [Targ| Acc]);
diff --git a/lib/snmp/src/agent/snmpa.erl b/lib/snmp/src/agent/snmpa.erl
index 79493bd892..5ff0883be3 100644
--- a/lib/snmp/src/agent/snmpa.erl
+++ b/lib/snmp/src/agent/snmpa.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2004-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 2004-2012. All Rights Reserved.
+%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
-%%
+%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
-%%
+%%
%% %CopyrightEnd%
%%
-module(snmpa).
@@ -47,6 +47,7 @@
mib_of/1, mib_of/2,
me_of/1, me_of/2,
invalidate_mibs_cache/0, invalidate_mibs_cache/1,
+ which_mibs_cache_size/0, which_mibs_cache_size/1,
enable_mibs_cache/0, enable_mibs_cache/1,
disable_mibs_cache/0, disable_mibs_cache/1,
gc_mibs_cache/0, gc_mibs_cache/1, gc_mibs_cache/2, gc_mibs_cache/3,
@@ -60,7 +61,7 @@
register_subagent/3, unregister_subagent/2,
send_notification/3, send_notification/4, send_notification/5,
- send_notification/6,
+ send_notification/6, send_notification/7,
send_trap/3, send_trap/4,
discovery/2, discovery/3, discovery/4, discovery/5, discovery/6,
@@ -83,6 +84,7 @@
%% Audit Trail Log functions
-export([log_to_txt/2, log_to_txt/3, log_to_txt/4,
log_to_txt/5, log_to_txt/6, log_to_txt/7,
+ log_info/0,
change_log_size/1,
get_log_type/0, get_log_type/1,
change_log_type/1, change_log_type/2,
@@ -301,6 +303,13 @@ invalidate_mibs_cache(Agent) ->
snmpa_agent:invalidate_mibs_cache(Agent).
+which_mibs_cache_size() ->
+ which_mibs_cache_size(snmp_master_agent).
+
+which_mibs_cache_size(Agent) ->
+ snmpa_agent:which_mibs_cache_size(Agent).
+
+
enable_mibs_cache() ->
enable_mibs_cache(snmp_master_agent).
@@ -354,7 +363,7 @@ update_mibs_cache_age(Agent, Age) ->
update_mibs_cache_gclimit(GcLimit) ->
- update_mibs_cache_age(snmp_master_agent, GcLimit).
+ update_mibs_cache_gclimit(snmp_master_agent, GcLimit).
update_mibs_cache_gclimit(Agent, GcLimit) ->
snmpa_agent:update_mibs_cache_gclimit(Agent, GcLimit).
@@ -414,14 +423,23 @@ send_notification(Agent, Notification, Recv, Varbinds) ->
send_notification(Agent, Notification, Recv, NotifyName, Varbinds) ->
send_notification(Agent, Notification, Recv, NotifyName, "", Varbinds).
-send_notification(Agent, Notification, Recv,
- NotifyName, ContextName, Varbinds)
+send_notification(Agent, Notification, Recv, NotifyName,
+ ContextName, Varbinds)
when (is_list(NotifyName) andalso
is_list(ContextName) andalso
is_list(Varbinds)) ->
snmpa_agent:send_trap(Agent, Notification, NotifyName,
ContextName, Recv, Varbinds).
+send_notification(Agent, Notification, Recv,
+ NotifyName, ContextName, Varbinds, LocalEngineID)
+ when (is_list(NotifyName) andalso
+ is_list(ContextName) andalso
+ is_list(Varbinds) andalso
+ is_list(LocalEngineID)) ->
+ snmpa_agent:send_trap(Agent, Notification, NotifyName,
+ ContextName, Recv, Varbinds, LocalEngineID).
+
%% Kept for backwards compatibility
send_trap(Agent, Trap, Community) ->
send_notification(Agent, Trap, no_receiver, Community, "", []).
@@ -535,6 +553,7 @@ get_agent_caps() ->
%%%-----------------------------------------------------------------
%%% Audit Trail Log functions
%%%-----------------------------------------------------------------
+
log_to_txt(LogDir, Mibs) ->
OutFile = "snmpa_log.txt",
LogName = ?audit_trail_log_name,
@@ -555,6 +574,11 @@ log_to_txt(LogDir, Mibs, OutFile, LogName, LogFile, Start, Stop) ->
snmp:log_to_txt(LogDir, Mibs, OutFile, LogName, LogFile, Start, Stop).
+log_info() ->
+ LogName = ?audit_trail_log_name,
+ snmp_log:info(LogName).
+
+
change_log_size(NewSize) ->
LogName = ?audit_trail_log_name, % The old (agent) default
snmp:change_log_size(LogName, NewSize).
diff --git a/lib/snmp/src/agent/snmpa_agent.erl b/lib/snmp/src/agent/snmpa_agent.erl
index 508a1da514..e3178aacc6 100644
--- a/lib/snmp/src/agent/snmpa_agent.erl
+++ b/lib/snmp/src/agent/snmpa_agent.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 1996-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 1996-2012. All Rights Reserved.
+%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
-%%
+%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
-%%
+%%
%% %CopyrightEnd%
%%
-module(snmpa_agent).
@@ -30,7 +30,7 @@
-export([subagent_set/2,
load_mibs/2, unload_mibs/2, which_mibs/1, whereis_mib/2, info/1,
register_subagent/3, unregister_subagent/2,
- send_trap/6,
+ send_trap/6, send_trap/7,
register_notification_filter/5,
unregister_notification_filter/2,
which_notification_filter/1,
@@ -48,6 +48,7 @@
get/2, get/3, get_next/2, get_next/3]).
-export([mib_of/1, mib_of/2, me_of/1, me_of/2,
invalidate_mibs_cache/1,
+ which_mibs_cache_size/1,
enable_mibs_cache/1, disable_mibs_cache/1,
gc_mibs_cache/1, gc_mibs_cache/2, gc_mibs_cache/3,
enable_mibs_cache_autogc/1, disable_mibs_cache_autogc/1,
@@ -58,12 +59,16 @@
-export([get_log_type/1, set_log_type/2]).
-export([get_request_limit/1, set_request_limit/2]).
-export([invalidate_ca_cache/0]).
+-export([increment_counter/3]).
-export([restart_worker/1, restart_set_worker/1]).
%% Internal exports
-export([init/1, handle_call/3, handle_cast/2, handle_info/2,
terminate/2, code_change/3, tr_var/2, tr_varbind/1,
- handle_pdu/7, worker/2, worker_loop/1, do_send_trap/6]).
+ handle_pdu/8, worker/2, worker_loop/1, do_send_trap/7]).
+%% <BACKWARD-COMPAT>
+-export([handle_pdu/7]).
+%% </BACKWARD-COMPAT>
-ifndef(default_verbosity).
-define(default_verbosity,silence).
@@ -79,7 +84,6 @@
-define(DISCO_TERMINATING_TRIGGER_USERNAME, "").
-
-ifdef(snmp_debug).
-define(GS_START_LINK3(Prio, Parent, Ref, Opts),
gen_server:start_link(?MODULE, [Prio, Parent, Ref, Opts],
@@ -95,13 +99,48 @@
gen_server:start_link({local, Name}, ?MODULE,
[Prio, Parent, Ref, Opts],[])).
-endif.
-
+
+%% Increment this whenever a change is made to the worker interface
+-define(WORKER_INTERFACE_VERSION, 1).
+
+%% -- Utility macros for creating worker commands --
+-define(mk_pdu_wreq(Vsn, Pdu, PduMS, ACMData, Address, GbMaxVBs, Extra),
+ #wrequest{cmd = handle_pdu,
+ info = [{vsn, Vsn},
+ {pdu, Pdu},
+ {pdu_ms, PduMS},
+ {acm_data, ACMData},
+ {addr, Address},
+ {gb_max_vbs, GbMaxVBs},
+ {extra, Extra}]}).
+-define(mk_send_trap_wreq(TrapRec, NotifyName, ContextName,
+ Recv, Vbs, LocalEngineID),
+ #wrequest{cmd = send_trap,
+ info = [{trap_rec, TrapRec},
+ {notify_name, NotifyName},
+ {context_name, ContextName},
+ {receiver, Recv},
+ {varbinds, Vbs},
+ {local_engine_id, LocalEngineID}]}).
+-define(mk_terminate_wreq(), #wrequest{cmd = terminate, info = []}).
+-define(mk_verbosity_wreq(V), #wrequest{cmd = verbosity,
+ info = [{verbosity, V}]}).
+
-record(notification_filter, {id, mod, data}).
-record(disco,
{from, rec, sender, target, engine_id,
sec_level, ctx, ivbs, stage, handler, extra}).
+%% This record is used when sending requests to the worker processes
+-record(wrequest,
+ {
+ version = ?WORKER_INTERFACE_VERSION,
+ cmd,
+ info
+ }
+ ).
+
%%-----------------------------------------------------------------
%% The agent is multi-threaded, i.e. each request is handled
@@ -134,7 +173,8 @@
net_if_mod,
backup,
disco,
- mibs_cache_request}).
+ mibs_cache_request,
+ gb_max_vbs}).
%%%-----------------------------------------------------------------
@@ -244,6 +284,10 @@ disable_mibs_cache(Agent) ->
call(Agent, {mibs_cache_request, disable_cache}).
+which_mibs_cache_size(Agent) ->
+ call(Agent, {mibs_cache_request, cache_size}).
+
+
enable_mibs_cache_autogc(Agent) ->
call(Agent, {mibs_cache_request, enable_autogc}).
@@ -259,6 +303,29 @@ update_mibs_cache_age(Agent, Age) ->
call(Agent, {mibs_cache_request, {update_age, Age}}).
+increment_counter(Counter, Initial, Max) ->
+ %% This is to make sure no one else increments our counter
+ Key = {Counter, self()},
+
+ %% Counter data
+ Position = 2,
+ Increment = 1,
+ Threshold = Max,
+ SetValue = Initial,
+ UpdateOp = {Position, Increment, Threshold, SetValue},
+
+ %% And now for the actual increment
+ Tab = snmp_agent_table,
+ case (catch ets:update_counter(Tab, Key, UpdateOp)) of
+ {'EXIT', {badarg, _}} ->
+ %% Oups, first time
+ ets:insert(Tab, {Key, Initial}),
+ Initial;
+ Next when is_integer(Next) ->
+ Next
+ end.
+
+
init([Prio, Parent, Ref, Options]) ->
?d("init -> entry with"
"~n Prio: ~p"
@@ -295,6 +362,8 @@ do_init(Prio, Parent, Ref, Options) ->
MultiT = get_multi_threaded(Options),
Vsns = get_versions(Options),
+ GbMaxVbs = get_gb_max_vbs(Options),
+
NS = start_note_store(Prio, Ref, Options),
{Type, NetIfPid, NetIfMod} =
start_net_if(Parent, Prio, Ref, Vsns, NS, Options),
@@ -313,7 +382,8 @@ do_init(Prio, Parent, Ref, Options) ->
ref = Ref,
vsns = Vsns,
note_store = NS,
- net_if_mod = NetIfMod}}.
+ net_if_mod = NetIfMod,
+ gb_max_vbs = GbMaxVbs}}.
start_note_store(Prio, Ref, Options) ->
@@ -375,7 +445,8 @@ start_net_if(Parent, _Prio, _Ref, _Vsns, _NoteStore, _Options)
start_mib_server(Prio, Ref, Mibs, Options) ->
?vdebug("start_mib_server -> with Prio: ~p", [Prio]),
MibStorage = get_mib_storage(Options),
- MibsOpts = [{mib_storage, MibStorage}|get_option(mib_server, Options, [])],
+ MibsOpts = [{mib_storage, MibStorage} |
+ get_option(mib_server, Options, [])],
?vtrace("start_mib_server -> "
"~n Mibs: ~p"
@@ -500,14 +571,15 @@ which_notification_filter(Agent) ->
send_trap(Agent, Trap, NotifyName, CtxName, Recv, Varbinds) ->
?d("send_trap -> entry with"
- "~n self(): ~p"
- "~n Agent: ~p [~p]"
- "~n Trap: ~p"
- "~n NotifyName: ~p"
- "~n CtxName: ~p"
- "~n Recv: ~p"
- "~n Varbinds: ~p",
- [self(), Agent, wis(Agent), Trap, NotifyName, CtxName, Recv, Varbinds]),
+ "~n self(): ~p"
+ "~n Agent: ~p [~p]"
+ "~n Trap: ~p"
+ "~n NotifyName: ~p"
+ "~n CtxName: ~p"
+ "~n Recv: ~p"
+ "~n Varbinds: ~p",
+ [self(), Agent, wis(Agent),
+ Trap, NotifyName, CtxName, Recv, Varbinds]),
Msg = {send_trap, Trap, NotifyName, CtxName, Recv, Varbinds},
case (wis(Agent) =:= self()) of
false ->
@@ -516,6 +588,27 @@ send_trap(Agent, Trap, NotifyName, CtxName, Recv, Varbinds) ->
Agent ! Msg
end.
+send_trap(Agent, Trap, NotifyName, CtxName, Recv, Varbinds, LocalEngineID) ->
+ ?d("send_trap -> entry with"
+ "~n self(): ~p"
+ "~n Agent: ~p [~p]"
+ "~n Trap: ~p"
+ "~n NotifyName: ~p"
+ "~n CtxName: ~p"
+ "~n Recv: ~p"
+ "~n Varbinds: ~p"
+ "~n LocalEngineID: ~p",
+ [self(), Agent, wis(Agent),
+ Trap, NotifyName, CtxName, Recv, Varbinds, LocalEngineID]),
+ Msg =
+ {send_trap, Trap, NotifyName, CtxName, Recv, Varbinds, LocalEngineID},
+ case (wis(Agent) =:= self()) of
+ false ->
+ call(Agent, Msg);
+ true ->
+ Agent ! Msg
+ end.
+
%% -- Discovery functions --
@@ -602,6 +695,7 @@ wis(Pid) when is_pid(Pid) ->
wis(Atom) when is_atom(Atom) ->
whereis(Atom).
+
forward_trap(Agent, TrapRecord, NotifyName, CtxName, Recv, Varbinds) ->
Agent ! {forward_trap, TrapRecord, NotifyName, CtxName, Recv, Varbinds}.
@@ -682,7 +776,8 @@ handle_info({snmp_pdu, Vsn, Pdu, PduMS, ACMData, Address, Extra}, S) ->
?vdebug("handle_info(snmp_pdu) -> entry with"
"~n Vsn: ~p"
"~n Pdu: ~p"
- "~n Address: ~p", [Vsn, Pdu, Address]),
+ "~n Address: ~p"
+ "~n Extra: ~p", [Vsn, Pdu, Address, Extra]),
NewS = handle_snmp_pdu(is_valid_pdu_type(Pdu#pdu.type),
Vsn, Pdu, PduMS, ACMData, Address, Extra, S),
@@ -695,14 +790,15 @@ handle_info(worker_available, S) ->
handle_info({send_trap, Trap, NotifyName, ContextName, Recv, Varbinds}, S) ->
?vlog("[handle_info] send trap request:"
- "~n Trap: ~p"
- "~n NotifyName: ~p"
- "~n ContextName: ~p"
- "~n Recv: ~p"
- "~n Varbinds: ~p",
- [Trap,NotifyName,ContextName,Recv,Varbinds]),
+ "~n Trap: ~p"
+ "~n NotifyName: ~p"
+ "~n ContextName: ~p"
+ "~n Recv: ~p"
+ "~n Varbinds: ~p",
+ [Trap, NotifyName, ContextName, Recv, Varbinds]),
+ LocalEngineID = ?DEFAULT_LOCAL_ENGINE_ID,
case catch handle_send_trap(S, Trap, NotifyName, ContextName,
- Recv, Varbinds) of
+ Recv, Varbinds, LocalEngineID) of
{ok, NewS} ->
{noreply, NewS};
{'EXIT', R} ->
@@ -712,17 +808,39 @@ handle_info({send_trap, Trap, NotifyName, ContextName, Recv, Varbinds}, S) ->
{noreply, S}
end;
-handle_info({forward_trap, TrapRecord, NotifyName, ContextName,
- Recv, Varbinds},S) ->
+handle_info({send_trap, Trap, NotifyName, ContextName, Recv, Varbinds,
+ LocalEngineID}, S) ->
+ ?vlog("[handle_info] send trap request:"
+ "~n Trap: ~p"
+ "~n NotifyName: ~p"
+ "~n ContextName: ~p"
+ "~n Recv: ~p"
+ "~n Varbinds: ~p"
+ "~n LocalEngineID: ~p",
+ [Trap, NotifyName, ContextName, Recv, Varbinds, LocalEngineID]),
+ case catch handle_send_trap(S, Trap, NotifyName, ContextName,
+ Recv, Varbinds, LocalEngineID) of
+ {ok, NewS} ->
+ {noreply, NewS};
+ {'EXIT', R} ->
+ ?vinfo("Trap not sent:~n ~p", [R]),
+ {noreply, S};
+ _ ->
+ {noreply, S}
+ end;
+
+handle_info({forward_trap, TrapRecord, NotifyName, ContextName,
+ Recv, Varbinds}, S) ->
?vlog("[handle_info] forward trap request:"
- "~n TrapRecord: ~p"
- "~n NotifyName: ~p"
- "~n ContextName: ~p"
- "~n Recv: ~p"
- "~n Varbinds: ~p",
- [TrapRecord,NotifyName,ContextName,Recv,Varbinds]),
+ "~n TrapRecord: ~p"
+ "~n NotifyName: ~p"
+ "~n ContextName: ~p"
+ "~n Recv: ~p"
+ "~n Varbinds: ~p",
+ [TrapRecord, NotifyName, ContextName, Recv, Varbinds]),
+ LocalEngineID = ?DEFAULT_LOCAL_ENGINE_ID,
case (catch maybe_send_trap(S, TrapRecord, NotifyName, ContextName,
- Recv, Varbinds)) of
+ Recv, Varbinds, LocalEngineID)) of
{ok, NewS} ->
{noreply, NewS};
{'EXIT', R} ->
@@ -832,17 +950,52 @@ handle_call(restart_set_worker, _From, #state{set_worker = Pid} = S) ->
ok
end,
{reply, ok, S};
+
handle_call({send_trap, Trap, NotifyName, ContextName, Recv, Varbinds},
_From, S) ->
?vlog("[handle_call] send trap request:"
- "~n Trap: ~p"
- "~n NotifyName: ~p"
- "~n ContextName: ~p"
- "~n Recv: ~p"
- "~n Varbinds: ~p",
- [Trap,NotifyName,ContextName,Recv,Varbinds]),
+ "~n Trap: ~p"
+ "~n NotifyName: ~p"
+ "~n ContextName: ~p"
+ "~n Recv: ~p"
+ "~n Varbinds: ~p",
+ [Trap, NotifyName, ContextName, Recv, Varbinds]),
+ LocalEngineID =
+ case S#state.type of
+ master_agent ->
+ ?DEFAULT_LOCAL_ENGINE_ID;
+ _ ->
+ %% subagent -
+ %% we don't need this, eventually the trap sent request
+ %% will reach the master-agent and then it will look up
+ %% the proper engine id.
+ ignore
+ end,
+ case (catch handle_send_trap(S, Trap, NotifyName, ContextName,
+ Recv, Varbinds, LocalEngineID)) of
+ {ok, NewS} ->
+ {reply, ok, NewS};
+ {'EXIT', Reason} ->
+ ?vinfo("Trap not sent:~n ~p", [Reason]),
+ {reply, {error, {send_failed, Reason}}, S};
+ _ ->
+ ?vinfo("Trap not sent", []),
+ {reply, {error, send_failed}, S}
+ end;
+
+handle_call({send_trap, Trap, NotifyName,
+ ContextName, Recv, Varbinds, LocalEngineID},
+ _From, S) ->
+ ?vlog("[handle_call] send trap request:"
+ "~n Trap: ~p"
+ "~n NotifyName: ~p"
+ "~n ContextName: ~p"
+ "~n Recv: ~p"
+ "~n Varbinds: ~p"
+ "~n LocalEngineID: ~p",
+ [Trap, NotifyName, ContextName, Recv, Varbinds, LocalEngineID]),
case (catch handle_send_trap(S, Trap, NotifyName, ContextName,
- Recv, Varbinds)) of
+ Recv, Varbinds, LocalEngineID)) of
{ok, NewS} ->
{reply, ok, NewS};
{'EXIT', Reason} ->
@@ -852,8 +1005,10 @@ handle_call({send_trap, Trap, NotifyName, ContextName, Recv, Varbinds},
?vinfo("Trap not sent", []),
{reply, {error, send_failed}, S}
end;
+
handle_call({discovery,
- TargetName, Notification, ContextName, Vbs, DiscoHandler, ExtraInfo},
+ TargetName, Notification, ContextName, Vbs, DiscoHandler,
+ ExtraInfo},
From,
#state{disco = undefined} = S) ->
?vlog("[handle_call] initiate discovery process:"
@@ -893,7 +1048,7 @@ handle_call({subagent_get_next, MibView, Varbinds, PduData}, _From, S) ->
"~n PduData: ~p",
[MibView,Varbinds,PduData]),
put_pdu_data(PduData),
- {reply, do_get_next(MibView, Varbinds), S};
+ {reply, do_get_next(MibView, Varbinds, infinity), S};
handle_call({subagent_set, Arguments, PduData}, _From, S) ->
?vlog("[handle_call] subagent set:"
"~n Arguments: ~p"
@@ -934,7 +1089,7 @@ handle_call({get_next, Vars, Context}, _From, S) ->
?vdebug("Varbinds: ~p",[Varbinds]),
MibView = snmpa_acm:get_root_mib_view(),
Reply =
- case do_get_next(MibView, Varbinds) of
+ case do_get_next(MibView, Varbinds, infinity) of
{noError, 0, NewVarbinds} ->
Vbs = lists:keysort(#varbind.org_index, NewVarbinds),
[{Oid,Val} || #varbind{oid = Oid, value = Val} <- Vbs];
@@ -1035,7 +1190,8 @@ handle_call(info, _From, S) ->
handle_call(get_net_if, _From, S) ->
{reply, get(net_if), S};
-handle_call({backup, BackupDir}, From, S) ->
+%% Only accept a backup request if there is none already in progress
+handle_call({backup, BackupDir}, From, #state{backup = undefined} = S) ->
?vlog("backup: ~p", [BackupDir]),
Pid = self(),
V = get(verbosity),
@@ -1052,7 +1208,11 @@ handle_call({backup, BackupDir}, From, S) ->
end),
?vtrace("backup server: ~p", [BackupServer]),
{noreply, S#state{backup = {BackupServer, From}}};
-
+
+handle_call({backup, _BackupDir}, From, #state{backup = Backup} = S) ->
+ ?vinfo("backup already in progress: ~p", [Backup]),
+ {reply, {error, backup_in_progress}, S};
+
handle_call(dump_mibs, _From, S) ->
Reply = snmpa_mib:dump(get(mibserver)),
{reply, Reply, S};
@@ -1130,15 +1290,15 @@ handle_call(Req, _From, S) ->
Reply = {error, {unknown, Req}},
{reply, Reply, S}.
-handle_cast({verbosity,Verbosity}, S) ->
- ?vlog("verbosity: ~p -> ~p",[get(verbosity),Verbosity]),
+handle_cast({verbosity, Verbosity}, S) ->
+ ?vlog("verbosity: ~p -> ~p",[get(verbosity), Verbosity]),
put(verbosity,snmp_verbosity:validate(Verbosity)),
case S#state.worker of
- Pid when is_pid(Pid) -> Pid ! {verbosity,Verbosity};
+ Pid when is_pid(Pid) -> Pid ! ?mk_verbosity_wreq(Verbosity);
_ -> ok
end,
case S#state.set_worker of
- Pid2 when is_pid(Pid2) -> Pid2 ! {verbosity,Verbosity};
+ Pid2 when is_pid(Pid2) -> Pid2 ! ?mk_verbosity_wreq(Verbosity);
_ -> ok
end,
{noreply, S};
@@ -1195,6 +1355,8 @@ handle_mibs_cache_request(MibServer, Req) ->
snmpa_mib:gc_cache(MibServer, Age);
{gc_cache, Age, GcLimit} ->
snmpa_mib:gc_cache(MibServer, Age, GcLimit);
+ cache_size ->
+ snmpa_mib:which_cache_size(MibServer);
enable_cache ->
snmpa_mib:enable_cache(MibServer);
disable_cache ->
@@ -1223,79 +1385,90 @@ handle_mibs_cache_request(MibServer, Req) ->
%% Downgrade
%%
-code_change({down, _Vsn}, S, downgrade_to_pre_4_13) ->
- S1 = workers_restart(S),
- case S1#state.disco of
- undefined ->
- ok;
- #disco{from = From,
- sender = Sender,
- stage = Stage} ->
- gen_server:reply(From, {error, {upgrade, Stage, Sender}}),
- exit(Sender, kill)
- end,
+code_change({down, _Vsn}, S1, downgrade_to_pre_4_17_3) ->
+ #state{type = Type,
+ parent = Parent,
+ worker = Worker,
+ worker_state = WorkerState,
+ set_worker = SetWorker,
+ multi_threaded = MT,
+ ref = Ref,
+ vsns = Vsns,
+ nfilters = NF,
+ note_store = NoteStore,
+ mib_server = MS,
+ net_if = NetIf,
+ net_if_mod = NetIfMod,
+ backup = Backup,
+ disco = Disco,
+ mibs_cache_request = MCR} = S1,
S2 = {state,
- S1#state.type,
- S1#state.parent,
- S1#state.worker,
- S1#state.worker_state,
- S1#state.set_worker,
- S1#state.multi_threaded,
- S1#state.ref,
- S1#state.vsns,
- S1#state.nfilters,
- S1#state.note_store,
- S1#state.mib_server,
- S1#state.net_if,
- S1#state.net_if_mod,
- S1#state.backup,
- S1#state.disco},
+ type = Type,
+ parent = Parent,
+ worker = Worker,
+ worker_state = WorkerState,
+ set_worker = SetWorker,
+ multi_threaded = MT,
+ ref = Ref,
+ vsns = Vsns,
+ nfilters = NF,
+ note_store = NoteStore,
+ mib_server = MS,
+ net_if = NetIf,
+ net_if_mod = NetIfMod,
+ backup = Backup,
+ disco = Disco,
+ mibs_cache_request = MCR},
{ok, S2};
%% Upgrade
%%
-code_change(_Vsn, S, upgrade_from_pre_4_13) ->
+code_change(_Vsn, S1, upgrade_from_pre_4_17_3) ->
{state,
- Type,
- Parent,
- Worker,
- WorkerState,
- SetWorker,
- MultiThreaded,
- Ref,
- Vsns,
- NFilters = [],
- NoteStore,
- MibServer, %% Currently unused
- NetIf, %% Currently unused
- NetIfMod,
- Backup} = S,
- S1 = #state{type = Type,
- parent = Parent,
- worker = Worker,
- worker_state = WorkerState,
- set_worker = SetWorker,
- multi_threaded = MultiThreaded,
- ref = Ref,
- vsns = Vsns,
- nfilters = NFilters,
- note_store = NoteStore,
- mib_server = MibServer,
- net_if = NetIf,
- net_if_mod = NetIfMod,
- backup = Backup},
- S2 = workers_restart(S1),
+ type = Type,
+ parent = Parent,
+ worker = Worker,
+ worker_state = WorkerState,
+ set_worker = SetWorker,
+ multi_threaded = MT,
+ ref = Ref,
+ vsns = Vsns,
+ nfilters = NF,
+ note_store = NoteStore,
+ mib_server = MS,
+ net_if = NetIf,
+ net_if_mod = NetIfMod,
+ backup = Backup,
+ disco = Disco,
+ mibs_cache_request = MCR} = S1,
+ S2 = #state{type = Type,
+ parent = Parent,
+ worker = Worker,
+ worker_state = WorkerState,
+ set_worker = SetWorker,
+ multi_threaded = MT,
+ ref = Ref,
+ vsns = Vsns,
+ nfilters = NF,
+ note_store = NoteStore,
+ mib_server = MS,
+ net_if = NetIf,
+ net_if_mod = NetIfMod,
+ backup = Backup,
+ disco = Disco,
+ mibs_cache_request = MCR,
+ gb_max_vbs = ?DEFAULT_GB_MAX_VBS},
{ok, S2};
code_change(_Vsn, S, _Extra) ->
{ok, S}.
-workers_restart(#state{worker = W, set_worker = SW} = S) ->
- Worker = worker_restart(W),
- SetWorker = set_worker_restart(SW),
- S#state{worker = Worker,
- set_worker = SetWorker}.
+%% workers_restart(#state{worker = W, set_worker = SW} = S) ->
+%% Worker = worker_restart(W),
+%% SetWorker = set_worker_restart(SW),
+%% S#state{worker = Worker,
+%% set_worker = SetWorker}.
%%-----------------------------------------------------------------
@@ -1321,11 +1494,11 @@ set_worker_start() ->
worker_start(Dict) ->
proc_lib:spawn_link(?MODULE, worker, [self(), Dict]).
-worker_stop(Pid) ->
- worker_stop(Pid, infinity).
+%% worker_stop(Pid) ->
+%% worker_stop(Pid, infinity).
worker_stop(Pid, Timeout) when is_pid(Pid) ->
- Pid ! terminate,
+ Pid ! ?mk_terminate_wreq(),
receive
{'EXIT', Pid, normal} ->
ok
@@ -1336,17 +1509,17 @@ worker_stop(Pid, Timeout) when is_pid(Pid) ->
worker_stop(_, _) ->
ok.
-set_worker_restart(Pid) ->
- worker_restart(Pid, [{master, self()} | get()]).
+%% set_worker_restart(Pid) ->
+%% worker_restart(Pid, [{master, self()} | get()]).
-worker_restart(Pid) ->
- worker_restart(Pid, get()).
+%% worker_restart(Pid) ->
+%% worker_restart(Pid, get()).
-worker_restart(Pid, Dict) when is_pid(Pid) ->
- worker_stop(Pid),
- worker_start(Dict);
-worker_restart(Any, _Dict) ->
- Any.
+%% worker_restart(Pid, Dict) when is_pid(Pid) ->
+%% worker_stop(Pid),
+%% worker_start(Dict);
+%% worker_restart(Any, _Dict) ->
+%% Any.
%%-----------------------------------------------------------------
@@ -1459,22 +1632,27 @@ invalidate_ca_cache() ->
%%
%%-----------------------------------------------------------------
-spawn_thread(Vsn, Pdu, PduMS, ACMData, Address, Extra) ->
+%% This functions spawns a temporary worker process,
+%% that evaluates one request and then silently exits.
+spawn_thread(Vsn, Pdu, PduMS, ACMData, Address, GbMaxVBs, Extra) ->
Dict = get(),
- Args = [Vsn, Pdu, PduMS, ACMData, Address, Extra, Dict],
+ Args = [Vsn, Pdu, PduMS, ACMData, Address, GbMaxVBs, Extra, Dict],
proc_lib:spawn_link(?MODULE, handle_pdu, Args).
-spawn_trap_thread(TrapRec, NotifyName, ContextName, Recv, V) ->
+spawn_trap_thread(TrapRec, NotifyName, ContextName, Recv, Vbs,
+ LocalEngineID) ->
Dict = get(),
proc_lib:spawn_link(?MODULE, do_send_trap,
- [TrapRec, NotifyName, ContextName, Recv, V, Dict]).
+ [TrapRec, NotifyName, ContextName,
+ Recv, Vbs, LocalEngineID, Dict]).
-do_send_trap(TrapRec, NotifyName, ContextName, Recv, V, Dict) ->
+do_send_trap(TrapRec, NotifyName, ContextName, Recv, Vbs,
+ LocalEngineID, Dict) ->
lists:foreach(fun({Key, Val}) -> put(Key, Val) end, Dict),
- put(sname,trap_sender_short_name(get(sname))),
+ put(sname, trap_sender_short_name(get(sname))),
?vlog("starting",[]),
- snmpa_trap:send_trap(TrapRec, NotifyName, ContextName, Recv, V,
- get(net_if)).
+ snmpa_trap:send_trap(TrapRec, NotifyName, ContextName, Recv, Vbs,
+ LocalEngineID, get(net_if)).
worker(Master, Dict) ->
lists:foreach(fun({Key, Val}) -> put(Key, Val) end, Dict),
@@ -1483,40 +1661,119 @@ worker(Master, Dict) ->
worker_loop(Master).
worker_loop(Master) ->
- receive
- {Vsn, Pdu, PduMS, ACMData, Address, Extra} ->
- ?vtrace("worker_loop -> received request", []),
- handle_pdu(Vsn, Pdu, PduMS, ACMData, Address, Extra),
- Master ! worker_available;
-
- %% Old style message
- {MibView, Vsn, Pdu, PduMS, ACMData, AgentData, Extra} ->
- ?vtrace("worker_loop -> received (old) request", []),
- do_handle_pdu(MibView, Vsn, Pdu, PduMS, ACMData, AgentData, Extra),
- Master ! worker_available;
-
- {TrapRec, NotifyName, ContextName, Recv, V} -> % We don't trap exits!
- ?vtrace("worker_loop -> send trap:"
- "~n ~p", [TrapRec]),
- snmpa_trap:send_trap(TrapRec, NotifyName,
- ContextName, Recv, V, get(net_if)),
- Master ! worker_available;
-
- {verbosity, Verbosity} ->
- put(verbosity,snmp_verbosity:validate(Verbosity));
-
- terminate ->
- exit(normal);
-
- _X ->
- %% ignore
- ok
-
- after 30000 ->
- %% This is to assure that the worker process leaves a
- %% possibly old version of this module.
- ok
- end,
+ Res =
+ receive
+ #wrequest{cmd = handle_pdu,
+ info = Info} = Req ->
+ ?vtrace("worker_loop -> received handle_pdu request with"
+ "~n Info: ~p", [Info]),
+ Vsn = proplists:get_value(vsn, Info),
+ Pdu = proplists:get_value(pdu, Info),
+ PduMS = proplists:get_value(pdu_ms, Info),
+ ACMData = proplists:get_value(acm_data, Info),
+ Address = proplists:get_value(addr, Info),
+ GbMaxVBs = proplists:get_value(gb_max_vbs, Info),
+ Extra = proplists:get_value(extra, Info),
+ HandlePduRes =
+ try
+ begin
+ handle_pdu2(Vsn, Pdu, PduMS, ACMData, Address,
+ GbMaxVBs, Extra)
+ end
+ catch
+ T:E ->
+ exit({worker_crash, Req, T, E,
+ erlang:get_stacktrace()})
+ end,
+ Master ! worker_available,
+ HandlePduRes; % For debugging...
+
+
+ #wrequest{cmd = send_trap,
+ info = Info} = Req ->
+ ?vtrace("worker_loop -> received send_trap request with"
+ "~n Info: ~p", [Info]),
+ TrapRec = proplists:get_value(trap_rec, Info),
+ NotifyName = proplists:get_value(notify_name, Info),
+ ContextName = proplists:get_value(context_name, Info),
+ Recv = proplists:get_value(receiver, Info),
+ Vbs = proplists:get_value(varbinds, Info),
+ LocalEngineID = proplists:get_value(local_engine_id, Info),
+ SendTrapRes =
+ try
+ begin
+ snmpa_trap:send_trap(TrapRec, NotifyName,
+ ContextName, Recv, Vbs,
+ LocalEngineID,
+ get(net_if))
+ end
+ catch
+ T:E ->
+ exit({worker_crash, Req, T, E,
+ erlang:get_stacktrace()})
+ end,
+ Master ! worker_available,
+ SendTrapRes; % For debugging...
+
+
+ #wrequest{cmd = verbosity,
+ info = Info} ->
+ Verbosity = proplists:get_value(verbosity, Info),
+ put(verbosity, snmp_verbosity:validate(Verbosity));
+
+
+ #wrequest{cmd = terminate} ->
+ ?vtrace("worker_loop -> received terminate request", []),
+ exit(normal);
+
+
+ %% *************************************************************
+ %%
+ %% Kept for backward compatibillity reasons
+ %%
+ %% *************************************************************
+
+ {Vsn, Pdu, PduMS, ACMData, Address, Extra} ->
+ ?vtrace("worker_loop -> received request", []),
+ handle_pdu2(Vsn, Pdu, PduMS, ACMData, Address,
+ ?DEFAULT_GB_MAX_VBS, Extra),
+ Master ! worker_available;
+
+ %% We don't trap exits!
+ {TrapRec, NotifyName, ContextName, Recv, Vbs} ->
+ ?vtrace("worker_loop -> send trap:"
+ "~n ~p", [TrapRec]),
+ snmpa_trap:send_trap(TrapRec, NotifyName,
+ ContextName, Recv, Vbs, get(net_if)),
+ Master ! worker_available;
+
+ %% We don't trap exits!
+ {send_trap,
+ TrapRec, NotifyName, ContextName, Recv, Vbs, LocalEngineID} ->
+ ?vtrace("worker_loop -> send trap:"
+ "~n ~p", [TrapRec]),
+ snmpa_trap:send_trap(TrapRec, NotifyName,
+ ContextName, Recv, Vbs, LocalEngineID,
+ get(net_if)),
+ Master ! worker_available;
+
+ {verbosity, Verbosity} ->
+ put(verbosity, snmp_verbosity:validate(Verbosity));
+
+ terminate ->
+ exit(normal);
+
+ _X ->
+ %% ignore
+ ignore_unknown
+
+ after 30000 ->
+ %% This is to assure that the worker process leaves a
+ %% possibly old version of this module.
+ ok
+ end,
+ ?vtrace("worker_loop -> wrap with"
+ "~n ~p", [Res]),
?MODULE:worker_loop(Master).
@@ -1524,42 +1781,52 @@ worker_loop(Master) ->
%%-----------------------------------------------------------------
handle_snmp_pdu(true, Vsn, Pdu, PduMS, ACMData, Address, Extra,
- #state{multi_threaded = false} = S) ->
+ #state{multi_threaded = false,
+ gb_max_vbs = GbMaxVBs} = S) ->
?vtrace("handle_snmp_pdu -> single-thread agent",[]),
- handle_pdu(Vsn, Pdu, PduMS, ACMData, Address, Extra),
+ handle_pdu2(Vsn, Pdu, PduMS, ACMData, Address, GbMaxVBs, Extra),
S;
handle_snmp_pdu(true, Vsn, #pdu{type = 'set-request'} = Pdu, PduMS,
ACMData, Address, Extra,
#state{set_worker = Worker} = S) ->
?vtrace("handle_snmp_pdu -> multi-thread agent: "
"send set-request to main worker",[]),
- Worker ! {Vsn, Pdu, PduMS, ACMData, Address, Extra},
+ WRequest = ?mk_pdu_wreq(Vsn, Pdu, PduMS, ACMData, Address, infinity, Extra),
+ Worker ! WRequest,
S#state{worker_state = busy};
handle_snmp_pdu(true, Vsn, Pdu, PduMS,
ACMData, Address, Extra,
- #state{worker_state = busy} = S) ->
+ #state{worker_state = busy,
+ gb_max_vbs = GbMaxVBs} = S) ->
?vtrace("handle_snmp_pdu -> multi-thread agent: "
"main worker busy - create new worker",[]),
- spawn_thread(Vsn, Pdu, PduMS, ACMData, Address, Extra),
+ spawn_thread(Vsn, Pdu, PduMS, ACMData, Address, GbMaxVBs, Extra),
S;
handle_snmp_pdu(true, Vsn, Pdu, PduMS, ACMData, Address, Extra,
- #state{worker = Worker} = S) ->
+ #state{worker = Worker,
+ gb_max_vbs = GbMaxVBs} = S) ->
?vtrace("handle_snmp_pdu -> multi-thread agent: "
"send to main worker",[]),
- Worker ! {Vsn, Pdu, PduMS, ACMData, Address, Extra},
+ WRequest = ?mk_pdu_wreq(Vsn, Pdu, PduMS, ACMData, Address, GbMaxVBs, Extra),
+ Worker ! WRequest,
S#state{worker_state = busy};
handle_snmp_pdu(_, _Vsn, _Pdu, _PduMS, _ACMData, _Address, _Extra, S) ->
S.
%% Called via the spawn_thread function
+%% <BACKWARD-COMPAT>
handle_pdu(Vsn, Pdu, PduMS, ACMData, Address, Extra, Dict) ->
+ handle_pdu(Vsn, Pdu, PduMS, ACMData, Address, ?DEFAULT_GB_MAX_VBS, Extra,
+ Dict).
+%% </BACKWARD-COMPAT>
+handle_pdu(Vsn, Pdu, PduMS, ACMData, Address, GbMaxVBs, Extra, Dict) ->
lists:foreach(fun({Key, Val}) -> put(Key, Val) end, Dict),
put(sname, pdu_handler_short_name(get(sname))),
?vlog("new worker starting",[]),
- handle_pdu(Vsn, Pdu, PduMS, ACMData, Address, Extra).
+ handle_pdu2(Vsn, Pdu, PduMS, ACMData, Address, GbMaxVBs, Extra).
-handle_pdu(Vsn, Pdu, PduMS, ACMData, Address, Extra) ->
+handle_pdu2(Vsn, Pdu, PduMS, ACMData, Address, GbMaxVBs, Extra) ->
%% OTP-3324
AuthMod = get(auth_module),
case AuthMod:init_check_access(Pdu, ACMData) of
@@ -1568,7 +1835,8 @@ handle_pdu(Vsn, Pdu, PduMS, ACMData, Address, Extra) ->
"~n MibView: ~p"
"~n ContextName: ~p", [MibView, ContextName]),
AgentData = cheat(ACMData, Address, ContextName),
- do_handle_pdu(MibView, Vsn, Pdu, PduMS, ACMData, AgentData, Extra);
+ do_handle_pdu(MibView, Vsn, Pdu, PduMS, ACMData, AgentData,
+ GbMaxVBs, Extra);
{error, Reason} ->
?vlog("handle_pdu -> error:"
"~n Reason: ~p", [Reason]),
@@ -1582,16 +1850,19 @@ handle_pdu(Vsn, Pdu, PduMS, ACMData, Address, Extra) ->
end.
do_handle_pdu(MibView, Vsn, Pdu, PduMS,
- ACMData, {Community, Address, ContextName}, Extra) ->
+ ACMData, {Community, Address, ContextName},
+ GbMaxVBs, Extra) ->
put(net_if_data, Extra),
+
RePdu = process_msg(MibView, Vsn, Pdu, PduMS, Community,
- Address, ContextName),
+ Address, ContextName, GbMaxVBs),
?vtrace("do_handle_pdu -> processed:"
"~n RePdu: ~p", [RePdu]),
- get(net_if) ! {snmp_response, Vsn, RePdu,
- RePdu#pdu.type, ACMData, Address, Extra}.
+ NetIf = get(net_if),
+ NetIf ! {snmp_response, Vsn, RePdu,
+ RePdu#pdu.type, ACMData, Address, Extra}.
handle_acm_error(Vsn, Reason, Pdu, ACMData, Address, Extra) ->
@@ -1648,13 +1919,15 @@ handle_acm_error(Vsn, Reason, Pdu, ACMData, Address, Extra) ->
end.
-handle_send_trap(S, TrapName, NotifyName, ContextName, Recv, Varbinds) ->
+handle_send_trap(S, TrapName, NotifyName, ContextName, Recv, Varbinds,
+ LocalEngineID) ->
?vtrace("handle_send_trap -> entry with"
- "~n S#state.type: ~p"
- "~n TrapName: ~p"
- "~n NotifyName: ~p"
- "~n ContextName: ~p",
- [S#state.type, TrapName, NotifyName, ContextName]),
+ "~n S#state.type: ~p"
+ "~n TrapName: ~p"
+ "~n NotifyName: ~p"
+ "~n ContextName: ~p"
+ "~n LocalEngineID: ~p",
+ [S#state.type, TrapName, NotifyName, ContextName, LocalEngineID]),
case snmpa_trap:construct_trap(TrapName, Varbinds) of
{ok, TrapRecord, VarList} ->
?vtrace("handle_send_trap -> construction complete: "
@@ -1671,7 +1944,8 @@ handle_send_trap(S, TrapName, NotifyName, ContextName, Recv, Varbinds) ->
?vtrace("handle_send_trap -> "
"[master] handle send trap",[]),
maybe_send_trap(S, TrapRecord, NotifyName,
- ContextName, Recv, VarList)
+ ContextName, Recv, VarList,
+ LocalEngineID)
end;
error ->
error
@@ -1708,7 +1982,8 @@ maybe_forward_trap(#state{parent = Parent, nfilters = NFs} = S,
maybe_send_trap(#state{nfilters = NFs} = S,
- TrapRec, NotifyName, ContextName, Recv, Varbinds) ->
+ TrapRec, NotifyName, ContextName, Recv, Varbinds,
+ LocalEngineID) ->
?vtrace("maybe_send_trap -> entry with"
"~n NFs: ~p", [NFs]),
case filter_notification(NFs, [], TrapRec) of
@@ -1725,39 +2000,45 @@ maybe_send_trap(#state{nfilters = NFs} = S,
?vtrace("maybe_send_trap -> send trap:"
"~n ~p", [TrapRec2]),
do_handle_send_trap(S, TrapRec2,
- NotifyName, ContextName, Recv, Varbinds);
+ NotifyName, ContextName, Recv, Varbinds,
+ LocalEngineID);
{send, Removed, TrapRec2} ->
?vtrace("maybe_send_trap -> send trap:"
"~n ~p", [TrapRec2]),
NFs2 = del_notification_filter(Removed, NFs),
do_handle_send_trap(S#state{nfilters = NFs2}, TrapRec2,
- NotifyName, ContextName, Recv, Varbinds)
+ NotifyName, ContextName, Recv, Varbinds,
+ LocalEngineID)
end.
-do_handle_send_trap(S, TrapRec, NotifyName, ContextName, Recv, Varbinds) ->
- V = snmpa_trap:try_initialise_vars(get(mibserver), Varbinds),
+do_handle_send_trap(S, TrapRec, NotifyName, ContextName, Recv, Varbinds,
+ LocalEngineID) ->
+ Vbs = snmpa_trap:try_initialise_vars(get(mibserver), Varbinds),
case S#state.type of
subagent ->
forward_trap(S#state.parent, TrapRec, NotifyName, ContextName,
- Recv, V),
+ Recv, Vbs),
{ok, S};
master_agent when S#state.multi_threaded =:= false ->
?vtrace("do_handle_send_trap -> send trap:"
"~n ~p", [TrapRec]),
snmpa_trap:send_trap(TrapRec, NotifyName, ContextName,
- Recv, V, get(net_if)),
+ Recv, Vbs, LocalEngineID, get(net_if)),
{ok, S};
master_agent when S#state.worker_state =:= busy ->
%% Main worker busy => create new worker
?vtrace("do_handle_send_trap -> main worker busy: "
"spawn a trap sender", []),
- spawn_trap_thread(TrapRec, NotifyName, ContextName, Recv, V),
+ spawn_trap_thread(TrapRec, NotifyName, ContextName, Recv, Vbs,
+ LocalEngineID),
{ok, S};
master_agent ->
%% Send to main worker
?vtrace("do_handle_send_trap -> send to main worker",[]),
- S#state.worker ! {TrapRec, NotifyName, ContextName, Recv, V},
+ S#state.worker ! ?mk_send_trap_wreq(TrapRec, NotifyName,
+ ContextName, Recv, Vbs,
+ LocalEngineID),
{ok, S#state{worker_state = busy}}
end.
@@ -2094,17 +2375,18 @@ handle_mib_of(MibServer, Oid) ->
%% Func: process_msg/7
%% Returns: RePdu
%%-----------------------------------------------------------------
-process_msg(MibView, Vsn, Pdu, PduMS, Community, {Ip, Udp}, ContextName) ->
+process_msg(MibView, Vsn, Pdu, PduMS, Community, {Ip, Udp}, ContextName,
+ GbMaxVBs) ->
#pdu{request_id = ReqId} = Pdu,
put(snmp_address, {tuple_to_list(Ip), Udp}),
put(snmp_request_id, ReqId),
put(snmp_community, Community),
put(snmp_context, ContextName),
?vtrace("process ~p",[Pdu#pdu.type]),
- process_pdu(Pdu, PduMS, Vsn, MibView).
+ process_pdu(Pdu, PduMS, Vsn, MibView, GbMaxVBs).
process_pdu(#pdu{type='get-request', request_id = ReqId, varbinds=Vbs},
- _PduMS, Vsn, MibView) ->
+ _PduMS, Vsn, MibView, _GbMaxVBs) ->
?vtrace("get ~p",[ReqId]),
Res = get_err(do_get(MibView, Vbs, false)),
?vtrace("get result: "
@@ -2125,12 +2407,12 @@ process_pdu(#pdu{type='get-request', request_id = ReqId, varbinds=Vbs},
make_response_pdu(ReqId, ErrStatus, ErrIndex, Vbs, ResponseVarbinds);
process_pdu(#pdu{type = 'get-next-request', request_id = ReqId, varbinds = Vbs},
- _PduMS, Vsn, MibView) ->
+ _PduMS, Vsn, MibView, _GbMaxVBs) ->
?vtrace("process get-next-request -> entry with"
"~n ReqId: ~p"
"~n Vbs: ~p"
"~n MibView: ~p",[ReqId, Vbs, MibView]),
- Res = get_err(do_get_next(MibView, Vbs)),
+ Res = get_err(do_get_next(MibView, Vbs, infinity)),
?vtrace("get-next result: "
"~n ~p",[Res]),
{ErrStatus, ErrIndex, ResVarbinds} =
@@ -2147,11 +2429,15 @@ process_pdu(#pdu{type = 'get-next-request', request_id = ReqId, varbinds = Vbs},
"~n ~p",[ResponseVarbinds]),
make_response_pdu(ReqId, ErrStatus, ErrIndex, Vbs, ResponseVarbinds);
-process_pdu(#pdu{type = 'get-bulk-request',request_id = ReqId,varbinds = Vbs,
- error_status = NonRepeaters, error_index = MaxRepetitions},
- PduMS, _Vsn, MibView)->
+process_pdu(#pdu{type = 'get-bulk-request',
+ request_id = ReqId,
+ varbinds = Vbs,
+ error_status = NonRepeaters,
+ error_index = MaxRepetitions},
+ PduMS, _Vsn, MibView, GbMaxVBs) ->
{ErrStatus, ErrIndex, ResponseVarbinds} =
- get_err(do_get_bulk(MibView,NonRepeaters,MaxRepetitions,PduMS,Vbs)),
+ get_err(do_get_bulk(MibView, NonRepeaters, MaxRepetitions, PduMS, Vbs,
+ GbMaxVBs)),
?vtrace("get-bulk final result: "
"~n Error status: ~p"
"~n Error index: ~p"
@@ -2160,7 +2446,7 @@ process_pdu(#pdu{type = 'get-bulk-request',request_id = ReqId,varbinds = Vbs,
make_response_pdu(ReqId, ErrStatus, ErrIndex, Vbs, ResponseVarbinds);
process_pdu(#pdu{type = 'set-request', request_id = ReqId, varbinds = Vbs},
- _PduMS, Vsn, MibView)->
+ _PduMS, Vsn, MibView, _GbMaxVbs)->
Res = do_set(MibView, Vbs),
?vtrace("set result: "
"~n ~p",[Res]),
@@ -2217,7 +2503,8 @@ validate_next_v1_2([Vb | _Vbs], _MibView, _Res)
{noSuchName, Vb#varbind.org_index};
validate_next_v1_2([Vb | Vbs], MibView, Res)
when Vb#varbind.variabletype =:= 'Counter64' ->
- case validate_next_v1(do_get_next(MibView, [mk_next_oid(Vb)]), MibView) of
+ case validate_next_v1(
+ do_get_next(MibView, [mk_next_oid(Vb)], infinity), MibView) of
{noError, 0, [NVb]} ->
validate_next_v1_2(Vbs, MibView, [NVb | Res]);
{Error, Index, _OrgVb} ->
@@ -2690,59 +2977,97 @@ validate_tab_res(_TooMany, [], Mfa, _Res, I) ->
%% that this really matters, since many nexts across the same
%% subagent must be considered to be very rare.
%%-----------------------------------------------------------------
-do_get_next(MibView, UnsortedVarbinds) ->
- SortedVarbinds = oid_sort_varbindlist(UnsortedVarbinds),
- next_loop_varbinds([], SortedVarbinds, MibView, [], []).
-oid_sort_varbindlist(Vbs) ->
+%% It may be a bit agressive to check this already,
+%% but since it is a security measure, it makes sense.
+do_get_next(_MibView, UnsortedVarbinds, GbMaxVBs)
+ when (is_integer(GbMaxVBs) andalso (length(UnsortedVarbinds) > GbMaxVBs)) ->
+ {tooBig, 0, []}; % What is the correct index in this case?
+do_get_next(MibView, UnsortedVBs, GbMaxVBs) ->
+ ?vt("do_get_next -> entry when"
+ "~n MibView: ~p"
+ "~n UnsortedVBs: ~p", [MibView, UnsortedVBs]),
+ SortedVBs = oid_sort_vbs(UnsortedVBs),
+ ?vt("do_get_next -> "
+ "~n SortedVBs: ~p", [SortedVBs]),
+ next_loop_varbinds([], SortedVBs, MibView, [], [], GbMaxVBs).
+
+oid_sort_vbs(Vbs) ->
lists:keysort(#varbind.oid, Vbs).
+next_loop_varbinds(_, Vbs, _MibView, Res, _LAVb, GbMaxVBs)
+ when (is_integer(GbMaxVBs) andalso
+ ((length(Vbs) + length(Res)) > GbMaxVBs)) ->
+ {tooBig, 0, []}; % What is the correct index in this case?
+
%% LAVb is Last Accessible Vb
-next_loop_varbinds([], [Vb | Vbs], MibView, Res, LAVb) ->
+next_loop_varbinds([], [Vb | Vbs], MibView, Res, LAVb, GbMaxVBs) ->
?vt("next_loop_varbinds -> entry when"
"~n Vb: ~p"
"~n MibView: ~p", [Vb, MibView]),
case varbind_next(Vb, MibView) of
endOfMibView ->
+ ?vt("next_loop_varbind -> endOfMibView", []),
RVb = if LAVb =:= [] -> Vb;
true -> LAVb
end,
NewVb = RVb#varbind{variabletype = 'NULL', value = endOfMibView},
- next_loop_varbinds([], Vbs, MibView, [NewVb | Res], []);
+ next_loop_varbinds([], Vbs, MibView, [NewVb | Res], [], GbMaxVBs);
+
{variable, ME, VarOid} when ((ME#me.access =/= 'not-accessible') andalso
(ME#me.access =/= 'write-only') andalso
(ME#me.access =/= 'accessible-for-notify')) ->
+ ?vt("next_loop_varbind -> variable: "
+ "~n ME: ~p"
+ "~n VarOid: ~p", [ME, VarOid]),
case try_get_instance(Vb, ME) of
{value, noValue, _NoSuchSomething} ->
+ ?vt("next_loop_varbind -> noValue", []),
%% Try next one
- NewVb = Vb#varbind{oid = VarOid, value = 'NULL'},
- next_loop_varbinds([], [NewVb | Vbs], MibView, Res, []);
+ NewVb = Vb#varbind{oid = VarOid,
+ value = 'NULL'},
+ next_loop_varbinds([], [NewVb | Vbs], MibView, Res, [],
+ GbMaxVBs);
{value, Type, Value} ->
- NewVb = Vb#varbind{oid = VarOid, variabletype = Type,
- value = Value},
- next_loop_varbinds([], Vbs, MibView, [NewVb | Res], []);
+ ?vt("next_loop_varbind -> value"
+ "~n Type: ~p"
+ "~n Value: ~p", [Type, Value]),
+ NewVb = Vb#varbind{oid = VarOid,
+ variabletype = Type,
+ value = Value},
+ next_loop_varbinds([], Vbs, MibView, [NewVb | Res], [],
+ GbMaxVBs);
{error, ErrorStatus} ->
?vdebug("next loop varbinds:"
"~n ErrorStatus: ~p",[ErrorStatus]),
{ErrorStatus, Vb#varbind.org_index, []}
end;
{variable, _ME, VarOid} ->
+ ?vt("next_loop_varbind -> variable: "
+ "~n VarOid: ~p", [VarOid]),
RVb = if LAVb =:= [] -> Vb;
true -> LAVb
end,
NewVb = Vb#varbind{oid = VarOid, value = 'NULL'},
- next_loop_varbinds([], [NewVb | Vbs], MibView, Res, RVb);
+ next_loop_varbinds([], [NewVb | Vbs], MibView, Res, RVb, GbMaxVBs);
{table, TableOid, TableRestOid, ME} ->
+ ?vt("next_loop_varbind -> table: "
+ "~n TableOid: ~p"
+ "~n TableRestOid: ~p"
+ "~n ME: ~p", [TableOid, TableRestOid, ME]),
next_loop_varbinds({table, TableOid, ME,
[{tab_oid(TableRestOid), Vb}]},
- Vbs, MibView, Res, []);
+ Vbs, MibView, Res, [], GbMaxVBs);
{subagent, SubAgentPid, SAOid} ->
+ ?vt("next_loop_varbind -> subagent: "
+ "~n SubAgentPid: ~p"
+ "~n SAOid: ~p", [SubAgentPid, SAOid]),
NewVb = Vb#varbind{variabletype = 'NULL', value = 'NULL'},
next_loop_varbinds({subagent, SubAgentPid, SAOid, [NewVb]},
- Vbs, MibView, Res, [])
+ Vbs, MibView, Res, [], GbMaxVBs)
end;
next_loop_varbinds({table, TableOid, ME, TabOids},
- [Vb | Vbs], MibView, Res, _LAVb) ->
+ [Vb | Vbs], MibView, Res, _LAVb, GbMaxVBs) ->
?vt("next_loop_varbinds(table) -> entry with"
"~n TableOid: ~p"
"~n Vb: ~p", [TableOid, Vb]),
@@ -2750,13 +3075,14 @@ next_loop_varbinds({table, TableOid, ME, TabOids},
{table, TableOid, TableRestOid, _ME} ->
next_loop_varbinds({table, TableOid, ME,
[{tab_oid(TableRestOid), Vb} | TabOids]},
- Vbs, MibView, Res, []);
+ Vbs, MibView, Res, [], GbMaxVBs);
_ ->
case get_next_table(ME, TableOid, TabOids, MibView) of
{ok, TabRes, TabEndOfTabVbs} ->
NewVbs = lists:append(TabEndOfTabVbs, [Vb | Vbs]),
NewRes = lists:append(TabRes, Res),
- next_loop_varbinds([], NewVbs, MibView, NewRes, []);
+ next_loop_varbinds([], NewVbs, MibView, NewRes, [],
+ GbMaxVBs);
{ErrorStatus, OrgIndex} ->
?vdebug("next loop varbinds: next varbind"
"~n ErrorStatus: ~p"
@@ -2766,7 +3092,7 @@ next_loop_varbinds({table, TableOid, ME, TabOids},
end
end;
next_loop_varbinds({table, TableOid, ME, TabOids},
- [], MibView, Res, _LAVb) ->
+ [], MibView, Res, _LAVb, GbMaxVBs) ->
?vt("next_loop_varbinds(table) -> entry with"
"~n TableOid: ~p", [TableOid]),
case get_next_table(ME, TableOid, TabOids, MibView) of
@@ -2775,7 +3101,8 @@ next_loop_varbinds({table, TableOid, ME, TabOids},
"~n TabRes: ~p"
"~n TabEndOfTabVbs: ~p", [TabRes, TabEndOfTabVbs]),
NewRes = lists:append(TabRes, Res),
- next_loop_varbinds([], TabEndOfTabVbs, MibView, NewRes, []);
+ next_loop_varbinds([], TabEndOfTabVbs, MibView, NewRes, [],
+ GbMaxVBs);
{ErrorStatus, OrgIndex} ->
?vdebug("next loop varbinds: next table"
"~n ErrorStatus: ~p"
@@ -2784,7 +3111,7 @@ next_loop_varbinds({table, TableOid, ME, TabOids},
{ErrorStatus, OrgIndex, []}
end;
next_loop_varbinds({subagent, SAPid, SAOid, SAVbs},
- [Vb | Vbs], MibView, Res, _LAVb) ->
+ [Vb | Vbs], MibView, Res, _LAVb, GbMaxVBs) ->
?vt("next_loop_varbinds(subagent) -> entry with"
"~n SAPid: ~p"
"~n SAOid: ~p"
@@ -2793,13 +3120,14 @@ next_loop_varbinds({subagent, SAPid, SAOid, SAVbs},
{subagent, _SubAgentPid, SAOid} ->
next_loop_varbinds({subagent, SAPid, SAOid,
[Vb | SAVbs]},
- Vbs, MibView, Res, []);
+ Vbs, MibView, Res, [], GbMaxVBs);
_ ->
case get_next_sa(SAPid, SAOid, SAVbs, MibView) of
{ok, SARes, SAEndOfMibViewVbs} ->
NewVbs = lists:append(SAEndOfMibViewVbs, [Vb | Vbs]),
NewRes = lists:append(SARes, Res),
- next_loop_varbinds([], NewVbs, MibView, NewRes, []);
+ next_loop_varbinds([], NewVbs, MibView, NewRes, [],
+ GbMaxVBs);
{noSuchName, OrgIndex} ->
%% v1 reply, treat this Vb as endOfMibView, and try again
%% for the others.
@@ -2812,12 +3140,14 @@ next_loop_varbinds({subagent, SAPid, SAOid, SAVbs},
case lists:delete(EVb, SAVbs) of
[] ->
next_loop_varbinds([], [EndOfVb, Vb | Vbs],
- MibView, Res, []);
+ MibView, Res, [],
+ GbMaxVBs);
TryAgainVbs ->
next_loop_varbinds({subagent, SAPid, SAOid,
TryAgainVbs},
[EndOfVb, Vb | Vbs],
- MibView, Res, [])
+ MibView, Res, [],
+ GbMaxVBs)
end;
false ->
%% bad index from subagent
@@ -2833,14 +3163,15 @@ next_loop_varbinds({subagent, SAPid, SAOid, SAVbs},
end
end;
next_loop_varbinds({subagent, SAPid, SAOid, SAVbs},
- [], MibView, Res, _LAVb) ->
+ [], MibView, Res, _LAVb, GbMaxVBs) ->
?vt("next_loop_varbinds(subagent) -> entry with"
"~n SAPid: ~p"
"~n SAOid: ~p", [SAPid, SAOid]),
case get_next_sa(SAPid, SAOid, SAVbs, MibView) of
{ok, SARes, SAEndOfMibViewVbs} ->
NewRes = lists:append(SARes, Res),
- next_loop_varbinds([], SAEndOfMibViewVbs, MibView, NewRes, []);
+ next_loop_varbinds([], SAEndOfMibViewVbs, MibView, NewRes, [],
+ GbMaxVBs);
{noSuchName, OrgIndex} ->
%% v1 reply, treat this Vb as endOfMibView, and try again for
%% the others.
@@ -2851,11 +3182,13 @@ next_loop_varbinds({subagent, SAPid, SAOid, SAVbs},
value = {endOfMibView, NextOid}},
case lists:delete(EVb, SAVbs) of
[] ->
- next_loop_varbinds([], [EndOfVb], MibView, Res, []);
+ next_loop_varbinds([], [EndOfVb], MibView, Res, [],
+ GbMaxVBs);
TryAgainVbs ->
next_loop_varbinds({subagent, SAPid, SAOid,
TryAgainVbs},
- [EndOfVb], MibView, Res, [])
+ [EndOfVb], MibView, Res, [],
+ GbMaxVBs)
end;
false ->
%% bad index from subagent
@@ -2868,12 +3201,15 @@ next_loop_varbinds({subagent, SAPid, SAOid, SAVbs},
[ErrorStatus,OrgIndex]),
{ErrorStatus, OrgIndex, []}
end;
-next_loop_varbinds([], [], _MibView, Res, _LAVb) ->
+next_loop_varbinds([], [], _MibView, Res, _LAVb, _GbMaxVBs) ->
?vt("next_loop_varbinds -> entry when done", []),
{noError, 0, Res}.
try_get_instance(_Vb, #me{mfa = {M, F, A}, asn1_type = ASN1Type}) ->
- ?vtrace("try get instance from <~p,~p,~p>",[M,F,A]),
+ ?vtrace("try_get_instance -> entry with"
+ "~n M: ~p"
+ "~n F: ~p"
+ "~n A: ~p", [M,F,A]),
Result = (catch dbg_apply(M, F, [get | A])),
% mib shall return {value, <a-nice-value-within-range>} |
% {noValue, noSuchName} (v1) |
@@ -2884,6 +3220,7 @@ try_get_instance(_Vb, #me{mfa = {M, F, A}, asn1_type = ASN1Type}) ->
tab_oid([]) -> [0];
tab_oid(X) -> X.
+
%%-----------------------------------------------------------------
%% Perform a next, using the varbinds Oid if value is simple
%% value. If value is {endOf<something>, NextOid}, use NextOid.
@@ -3130,22 +3467,30 @@ next_oid(Oid) ->
%%%-----------------------------------------------------------------
%%% 5. GET-BULK REQUEST
+%%%
+%%% In order to prevent excesses in reply sizes there are two
+%%% preventive methods in place. One is to check that the encode
+%%% size does not exceed Max PDU size (this is mentioned in the
+%%% standard). The other is a simple VBs limit. That is, the
+%%% resulting response cannot contain more then this number of VBs.
%%%-----------------------------------------------------------------
-do_get_bulk(MibView, NonRepeaters, MaxRepetitions, PduMS, Varbinds) ->
- ?vtrace("do get bulk: start with"
+
+do_get_bulk(MibView, NonRepeaters, MaxRepetitions, PduMS, Varbinds, GbMaxVBs) ->
+ ?vtrace("do_get_bulk -> entry with"
"~n MibView: ~p"
"~n NonRepeaters: ~p"
"~n MaxRepetitions: ~p"
"~n PduMS: ~p"
- "~n Varbinds: ~p",
- [MibView, NonRepeaters, MaxRepetitions, PduMS, Varbinds]),
+ "~n Varbinds: ~p"
+ "~n GbMaxVBs: ~p",
+ [MibView, NonRepeaters, MaxRepetitions, PduMS, Varbinds, GbMaxVBs]),
{NonRepVbs, RestVbs} = split_vbs(NonRepeaters, Varbinds, []),
- ?vt("do get bulk -> split: "
+ ?vt("do_get_bulk -> split: "
"~n NonRepVbs: ~p"
"~n RestVbs: ~p", [NonRepVbs, RestVbs]),
- case do_get_next(MibView, NonRepVbs) of
- {noError, 0, UResNonRepVbs} ->
- ?vt("do get bulk -> next: "
+ case do_get_next(MibView, NonRepVbs, GbMaxVBs) of
+ {noError, 0, UResNonRepVbs} ->
+ ?vt("do_get_bulk -> next noError: "
"~n UResNonRepVbs: ~p", [UResNonRepVbs]),
ResNonRepVbs = lists:keysort(#varbind.org_index, UResNonRepVbs),
%% Decode the first varbinds, produce a reversed list of
@@ -3155,11 +3500,12 @@ do_get_bulk(MibView, NonRepeaters, MaxRepetitions, PduMS, Varbinds) ->
user_err("failed encoding varbind ~w:~n~p", [Idx, Reason]),
{genErr, Idx, []};
{SizeLeft, Res} when is_integer(SizeLeft) and is_list(Res) ->
- ?vtrace("do get bulk -> encoded: "
+ ?vtrace("do_get_bulk -> encoded: "
"~n SizeLeft: ~p"
"~n Res: ~w", [SizeLeft, Res]),
case (catch do_get_rep(SizeLeft, MibView, MaxRepetitions,
- RestVbs, Res)) of
+ RestVbs, Res,
+ length(UResNonRepVbs), GbMaxVBs)) of
{error, Idx, Reason} ->
user_err("failed encoding varbind ~w:~n~p",
[Idx, Reason]),
@@ -3168,6 +3514,10 @@ do_get_bulk(MibView, NonRepeaters, MaxRepetitions, PduMS, Varbinds) ->
?vtrace("do get bulk -> Res: "
"~n ~w", [Res]),
{noError, 0, conv_res(Res)};
+ {noError, 0, Data} = OK ->
+ ?vtrace("do get bulk -> OK: "
+ "~n length(Data): ~w", [length(Data)]),
+ OK;
Else ->
?vtrace("do get bulk -> Else: "
"~n ~w", [Else]),
@@ -3176,6 +3526,7 @@ do_get_bulk(MibView, NonRepeaters, MaxRepetitions, PduMS, Varbinds) ->
Res when is_list(Res) ->
{noError, 0, conv_res(Res)}
end;
+
{ErrorStatus, Index, _} ->
?vdebug("do get bulk: "
"~n ErrorStatus: ~p"
@@ -3225,11 +3576,12 @@ enc_vbs(SizeLeft, Vbs) ->
end,
lists:foldl(Fun, {SizeLeft, []}, Vbs).
-do_get_rep(Sz, MibView, MaxRepetitions, Varbinds, Res)
+do_get_rep(Sz, MibView, MaxRepetitions, Varbinds, Res, GbNumVBs, GbMaxVBs)
when MaxRepetitions >= 0 ->
- do_get_rep(Sz, MibView, 0, MaxRepetitions, Varbinds, Res);
-do_get_rep(Sz, MibView, _MaxRepetitions, Varbinds, Res) ->
- do_get_rep(Sz, MibView, 0, 0, Varbinds, Res).
+ do_get_rep(Sz, MibView, 0, MaxRepetitions, Varbinds, Res,
+ GbNumVBs, GbMaxVBs);
+do_get_rep(Sz, MibView, _MaxRepetitions, Varbinds, Res, GbNumVBs, GbMaxVBs) ->
+ do_get_rep(Sz, MibView, 0, 0, Varbinds, Res, GbNumVBs, GbMaxVBs).
conv_res(ResVarbinds) ->
conv_res(ResVarbinds, []).
@@ -3238,22 +3590,30 @@ conv_res([VbListOfBytes | T], Bytes) ->
conv_res([], Bytes) ->
Bytes.
-do_get_rep(_Sz, _MibView, Max, Max, _, Res) ->
+%% The only other value, then a positive integer, is infinity.
+do_get_rep(_Sz, _MibView, Count, Max, _, _Res, GbNumVBs, GbMaxVBs)
+ when (is_integer(GbMaxVBs) andalso (GbNumVBs > GbMaxVBs)) ->
+ ?vinfo("Max Get-BULK VBs limit (~w) exceeded (~w) when:"
+ "~n Count: ~p"
+ "~n Max: ~p", [GbMaxVBs, GbNumVBs, Count, Max]),
+ {tooBig, 0, []};
+do_get_rep(_Sz, _MibView, Max, Max, _, Res, _GbNumVBs, _GbMaxVBs) ->
?vt("do_get_rep -> done when: "
"~n Res: ~p", [Res]),
{noError, 0, conv_res(Res)};
-do_get_rep(Sz, MibView, Count, Max, Varbinds, Res) ->
+do_get_rep(Sz, MibView, Count, Max, Varbinds, Res, GbNumVBs, GbMaxVBs) ->
?vt("do_get_rep -> entry when: "
"~n Sz: ~p"
"~n Count: ~p"
"~n Res: ~w", [Sz, Count, Res]),
- case try_get_bulk(Sz, MibView, Varbinds) of
+ case try_get_bulk(Sz, MibView, Varbinds, GbMaxVBs) of
{noError, NextVarbinds, SizeLeft, Res2} ->
?vt("do_get_rep -> noError: "
"~n SizeLeft: ~p"
"~n Res2: ~p", [SizeLeft, Res2]),
do_get_rep(SizeLeft, MibView, Count+1, Max, NextVarbinds,
- Res2 ++ Res);
+ Res2 ++ Res,
+ GbNumVBs + length(Varbinds), GbMaxVBs);
{endOfMibView, _NextVarbinds, _SizeLeft, Res2} ->
?vt("do_get_rep -> endOfMibView: "
"~n Res2: ~p", [Res2]),
@@ -3265,22 +3625,29 @@ do_get_rep(Sz, MibView, Count, Max, Varbinds, Res) ->
{ErrorStatus, Index, []}
end.
-try_get_bulk(Sz, MibView, Varbinds) ->
+org_index_sort_vbs(Vbs) ->
+ lists:keysort(#varbind.org_index, Vbs).
+
+try_get_bulk(Sz, MibView, Varbinds, GbMaxVBs) ->
?vt("try_get_bulk -> entry with"
- "~n Sz: ~w", [Sz]),
- case do_get_next(MibView, Varbinds) of
+ "~n Sz: ~w"
+ "~n MibView: ~w"
+ "~n Varbinds: ~w", [Sz, MibView, Varbinds]),
+ case do_get_next(MibView, Varbinds, GbMaxVBs) of
{noError, 0, UNextVarbinds} ->
- ?vt("try_get_bulk -> noError", []),
- NextVarbinds = lists:keysort(#varbind.org_index, UNextVarbinds),
+ ?vt("try_get_bulk -> noError: "
+ "~n UNextVarbinds: ~p", [UNextVarbinds]),
+ NextVarbinds = org_index_sort_vbs(UNextVarbinds),
case (catch enc_vbs(Sz, NextVarbinds)) of
{error, Idx, Reason} ->
user_err("failed encoding varbind ~w:~n~p", [Idx, Reason]),
- ?vtrace("try_get_bulk -> error: "
+ ?vtrace("try_get_bulk -> encode error: "
"~n Idx: ~p"
"~n Reason: ~p", [Idx, Reason]),
{genErr, Idx};
- {SizeLeft, Res} when is_integer(SizeLeft) andalso is_list(Res) ->
- ?vt("try get bulk -> "
+ {SizeLeft, Res} when is_integer(SizeLeft) andalso
+ is_list(Res) ->
+ ?vt("try get bulk -> encode ok: "
"~n SizeLeft: ~w"
"~n Res: ~w", [SizeLeft, Res]),
{check_end_of_mibview(NextVarbinds),
@@ -3291,9 +3658,9 @@ try_get_bulk(Sz, MibView, Varbinds) ->
{endOfMibView, [], 0, Res}
end;
{ErrorStatus, Index, _} ->
- ?vt("try get bulk: "
+ ?vt("try_get_bulk -> error: "
"~n ErrorStatus: ~p"
- "~n Index: ~p",[ErrorStatus, Index]),
+ "~n Index: ~p", [ErrorStatus, Index]),
{ErrorStatus, Index}
end.
@@ -3434,9 +3801,8 @@ get_err({ErrC, ErrI, Vbs}) ->
{get_err_i(ErrC), ErrI, Vbs}.
get_err_i(noError) -> noError;
-get_err_i(S) ->
- ?vtrace("convert '~p' to 'genErr'",[S]),
- genErr.
+get_err_i(tooBig) -> tooBig; % OTP-9700
+get_err_i(ES) -> ?vtrace("convert ErrorStatus '~p' to 'genErr'", [ES]), genErr.
v2err_to_v1err(noError) -> noError;
v2err_to_v1err(noAccess) -> noSuchName;
@@ -3925,6 +4291,9 @@ get_multi_threaded(Opts) ->
get_versions(Opts) ->
get_option(versions, Opts, [v1,v2,v3]).
+get_gb_max_vbs(Opts) ->
+ get_option(gb_max_vbs, Opts, infinity).
+
get_note_store_opt(Opts) ->
get_option(note_store, Opts, []).
diff --git a/lib/snmp/src/agent/snmpa_general_db.erl b/lib/snmp/src/agent/snmpa_general_db.erl
index 795c353a9e..a06604c9cf 100644
--- a/lib/snmp/src/agent/snmpa_general_db.erl
+++ b/lib/snmp/src/agent/snmpa_general_db.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2000-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 2000-2010. All Rights Reserved.
+%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
-%%
+%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
-%%
+%%
%% %CopyrightEnd%
%%
-module(snmpa_general_db).
@@ -114,14 +114,7 @@ ets_open(Name, Dir, clear, Type) ->
mnesia_open({table_exist,Name},_Nodes,_RecName,_Attr,_Type,clear) ->
?vtrace("[mnesia] database ~p already exists; clear content",[Name]),
- Pattern = '_',
- F = fun() ->
- Recs = mnesia:match_object(Name,Pattern,read),
- lists:foreach(fun(Rec) ->
- mnesia:delete_object(Name,Rec,write)
- end, Recs),
- Recs
- end,
+ F = fun() -> mnesia:clear_table(Name) end,
case mnesia:transaction(F) of
{aborted,Reason} ->
exit({aborted,Reason});
diff --git a/lib/snmp/src/agent/snmpa_internal.hrl b/lib/snmp/src/agent/snmpa_internal.hrl
index a33a6809dc..671a3e4aaf 100644
--- a/lib/snmp/src/agent/snmpa_internal.hrl
+++ b/lib/snmp/src/agent/snmpa_internal.hrl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2006-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 2006-2011. All Rights Reserved.
+%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
-%%
+%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
-%%
+%%
%% %CopyrightEnd%
%%
@@ -22,6 +22,17 @@
-include_lib("snmp/src/app/snmp_internal.hrl").
+-define(DEFAULT_LOCAL_ENGINE_ID, snmp_framework_mib:get_engine_id()).
+
+%% -- Max number of VBs in a Get-BULK response --
+%% (( The default value, 1000, is *way* more ))
+%% (( then there is room for in a normal pdu ))
+%% (( (unless the max pdu size has been ))
+%% (( cranked way up), so this value should ))
+%% (( suffice as "infinity" without actually ))
+%% (( causing memory issues for the VM ... ))
+-define(DEFAULT_GB_MAX_VBS, 1000).
+
-define(snmpa_info(F, A), ?snmp_info("agent", F, A)).
-define(snmpa_warning(F, A), ?snmp_warning("agent", F, A)).
-define(snmpa_error(F, A), ?snmp_error("agent", F, A)).
diff --git a/lib/snmp/src/agent/snmpa_local_db.erl b/lib/snmp/src/agent/snmpa_local_db.erl
index d9d6e633de..0babc74d16 100644
--- a/lib/snmp/src/agent/snmpa_local_db.erl
+++ b/lib/snmp/src/agent/snmpa_local_db.erl
@@ -486,7 +486,11 @@ handle_call({match, Name, Db, Pattern}, _From, State) ->
L1 = match(Db, Name, Pattern, State),
{reply, lists:delete([undef], L1), State};
-handle_call({backup, BackupDir}, From, #state{dets = Dets} = State) ->
+%% This check (that there is no backup already in progress) is also
+%% done in the master agent process, but just in case a user issues
+%% a backup call to this process directly, we add a similar check here.
+handle_call({backup, BackupDir}, From,
+ #state{backup = undefined, dets = Dets} = State) ->
?vlog("backup: ~p",[BackupDir]),
Pid = self(),
V = get(verbosity),
@@ -511,6 +515,10 @@ handle_call({backup, BackupDir}, From, #state{dets = Dets} = State) ->
{reply, Error, State}
end;
+handle_call({backup, _BackupDir}, From, #state{backup = Backup} = S) ->
+ ?vinfo("backup already in progress: ~p", [Backup]),
+ {reply, {error, backup_in_progress}, S};
+
handle_call(dump, _From, #state{dets = Dets} = State) ->
?vlog("dump",[]),
dets_sync(Dets),
diff --git a/lib/snmp/src/agent/snmpa_mib.erl b/lib/snmp/src/agent/snmpa_mib.erl
index 370989d0be..574467d38f 100644
--- a/lib/snmp/src/agent/snmpa_mib.erl
+++ b/lib/snmp/src/agent/snmpa_mib.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 1996-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 1996-2012. All Rights Reserved.
+%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
-%%
+%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
-%%
+%%
%% %CopyrightEnd%
%%
-module(snmpa_mib).
@@ -55,7 +55,7 @@
-define(NO_CACHE, no_mibs_cache).
-define(DEFAULT_CACHE_USAGE, true).
-define(CACHE_GC_TICKTIME, timer:minutes(1)).
--define(DEFAULT_CACHE_AUTOGC, false).
+-define(DEFAULT_CACHE_AUTOGC, true).
-define(DEFAULT_CACHE_GCLIMIT, 100).
-define(DEFAULT_CACHE_AGE, timer:minutes(10)).
-define(CACHE_GC_TRIGGER, cache_gc_trigger).
@@ -552,8 +552,12 @@ handle_call({dump, File}, _From, #state{data = Data} = State) ->
Reply = snmpa_mib_data:dump(Data, File),
{reply, Reply, State};
-handle_call({backup, BackupDir}, From, #state{data = Data} = State) ->
- ?vlog("backup to ~s",[BackupDir]),
+%% This check (that there is no backup already in progress) is also
+%% done in the master agent process, but just in case a user issues
+%% a backup call to this process directly, we add a similar check here.
+handle_call({backup, BackupDir}, From,
+ #state{backup = undefined, data = Data} = State) ->
+ ?vlog("backup to ~s", [BackupDir]),
Pid = self(),
V = get(verbosity),
case file:read_file_info(BackupDir) of
@@ -576,6 +580,10 @@ handle_call({backup, BackupDir}, From, #state{data = Data} = State) ->
{reply, Error, State}
end;
+handle_call({backup, _BackupDir}, From, #state{backup = Backup} = S) ->
+ ?vinfo("backup already in progress: ~p", [Backup]),
+ {reply, {error, backup_in_progress}, S};
+
handle_call(stop, _From, State) ->
?vlog("stop",[]),
{stop, normal, ok, State};
diff --git a/lib/snmp/src/agent/snmpa_mib_lib.erl b/lib/snmp/src/agent/snmpa_mib_lib.erl
index 441228b9ee..ae94aca6d8 100644
--- a/lib/snmp/src/agent/snmpa_mib_lib.erl
+++ b/lib/snmp/src/agent/snmpa_mib_lib.erl
@@ -60,23 +60,23 @@ table_del_row({Tab, Db} = TabDb, Key) ->
get_table(NameDb, FOI) ->
(catch get_table(NameDb, FOI, [], [])).
-get_table(NameDb, FOI, Oid, Acc) ->
- case table_next(NameDb, Oid) of
+get_table(NameDb, FOI, Key, Acc) ->
+ case table_next(NameDb, Key) of
endOfTable ->
?vdebug("end of table",[]),
{ok, lists:reverse(Acc)};
- Oid ->
+ Key ->
%% Crap, circular ref
- ?vinfo("cyclic reference: ~w -> ~w", [Oid,Oid]),
- throw({error, {cyclic_db_reference, Oid, Acc}});
- NextOid ->
- ?vtrace("get row for oid ~w", [NextOid]),
- case table_get_row(NameDb, NextOid, FOI) of
+ ?vinfo("cyclic reference: ~w -> ~w", [Key, Key]),
+ throw({error, {cyclic_db_reference, Key, Acc}});
+ NextKey ->
+ ?vtrace("get row for key ~w", [NextKey]),
+ case table_get_row(NameDb, NextKey, FOI) of
undefined ->
- throw({error, {invalid_rowindex, NextOid, Acc}});
+ throw({error, {invalid_rowindex, NextKey, Acc}});
Row ->
?vtrace("row: ~w", [Row]),
- get_table(NameDb, FOI, NextOid, [{NextOid, Row}|Acc])
+ get_table(NameDb, FOI, NextKey, [{NextKey, Row}|Acc])
end
end.
diff --git a/lib/snmp/src/agent/snmpa_mpd.erl b/lib/snmp/src/agent/snmpa_mpd.erl
index 2e09286b87..e9d6cdeaa8 100644
--- a/lib/snmp/src/agent/snmpa_mpd.erl
+++ b/lib/snmp/src/agent/snmpa_mpd.erl
@@ -1,27 +1,28 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 1997-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 1997-2012. All Rights Reserved.
+%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
-%%
+%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
-%%
+%%
%% %CopyrightEnd%
%%
-module(snmpa_mpd).
-export([init/1, reset/0, inc/1, counters/0,
discarded_pdu/1,
- process_packet/6,
- generate_response_msg/5, generate_msg/5,
+ process_packet/6, process_packet/7,
+ generate_response_msg/5, generate_response_msg/6,
+ generate_msg/5, generate_msg/6,
generate_discovery_msg/4,
process_taddrs/1,
generate_req_id/0]).
@@ -34,6 +35,7 @@
-define(VMODULE,"MPD").
-include("snmp_verbosity.hrl").
+-include("snmpa_internal.hrl").
-define(empty_msg_size, 24).
@@ -120,6 +122,12 @@ reset() ->
%% section 4.2.1 in rfc2272)
%%-----------------------------------------------------------------
process_packet(Packet, TDomain, TAddress, State, NoteStore, Log) ->
+ LocalEngineID = ?DEFAULT_LOCAL_ENGINE_ID,
+ process_packet(Packet, TDomain, TAddress, LocalEngineID,
+ State, NoteStore, Log).
+
+process_packet(Packet, TDomain, TAddress, LocalEngineID,
+ State, NoteStore, Log) ->
inc(snmpInPkts),
case catch snmp_pdus:dec_message_only(binary_to_list(Packet)) of
@@ -127,15 +135,17 @@ process_packet(Packet, TDomain, TAddress, State, NoteStore, Log) ->
when State#state.v1 =:= true ->
?vlog("v1, community: ~s", [Community]),
HS = ?empty_msg_size + length(Community),
- v1_v2c_proc('version-1', NoteStore, Community, TDomain, TAddress,
- Data, HS, Log, Packet);
+ v1_v2c_proc('version-1', NoteStore, Community,
+ TDomain, TAddress,
+ LocalEngineID, Data, HS, Log, Packet);
#message{version = 'version-2', vsn_hdr = Community, data = Data}
when State#state.v2c =:= true ->
?vlog("v2c, community: ~s", [Community]),
HS = ?empty_msg_size + length(Community),
- v1_v2c_proc('version-2', NoteStore, Community, TDomain, TAddress,
- Data, HS, Log, Packet);
+ v1_v2c_proc('version-2', NoteStore, Community,
+ TDomain, TAddress,
+ LocalEngineID, Data, HS, Log, Packet);
#message{version = 'version-3', vsn_hdr = V3Hdr, data = Data}
when State#state.v3 =:= true ->
@@ -143,7 +153,9 @@ process_packet(Packet, TDomain, TAddress, State, NoteStore, Log) ->
[V3Hdr#v3_hdr.msgID,
V3Hdr#v3_hdr.msgFlags,
V3Hdr#v3_hdr.msgSecurityModel]),
- v3_proc(NoteStore, Packet, TDomain, TAddress, V3Hdr, Data, Log);
+ v3_proc(NoteStore, Packet,
+ TDomain, TAddress,
+ LocalEngineID, V3Hdr, Data, Log);
{'EXIT', {bad_version, Vsn}} ->
?vtrace("exit: bad version: ~p",[Vsn]),
@@ -170,10 +182,11 @@ discarded_pdu(Variable) -> inc(Variable).
%%-----------------------------------------------------------------
%% Handles a Community based message (v1 or v2c).
%%-----------------------------------------------------------------
-v1_v2c_proc(Vsn, NoteStore, Community, snmpUDPDomain, {Ip, Udp},
+v1_v2c_proc(Vsn, NoteStore, Community, snmpUDPDomain,
+ {Ip, Udp}, LocalEngineID,
Data, HS, Log, Packet) ->
TAddress = tuple_to_list(Ip) ++ [Udp div 256, Udp rem 256],
- AgentMS = snmp_framework_mib:get_engine_max_message_size(),
+ AgentMS = get_engine_max_message_size(LocalEngineID),
MgrMS = snmp_community_mib:get_target_addr_ext_mms(?snmpUDPDomain,
TAddress),
PduMS = case MgrMS of
@@ -220,10 +233,10 @@ v1_v2c_proc(Vsn, NoteStore, Community, snmpUDPDomain, {Ip, Udp},
{discarded, trap_pdu}
end;
v1_v2c_proc(_Vsn, _NoteStore, _Community, snmpUDPDomain, TAddress,
- _Data, _HS, _Log, _Packet) ->
+ _LocalEngineID, _Data, _HS, _Log, _Packet) ->
{discarded, {badarg, TAddress}};
v1_v2c_proc(_Vsn, _NoteStore, _Community, TDomain, _TAddress,
- _Data, _HS, _Log, _Packet) ->
+ _LocalEngineID, _Data, _HS, _Log, _Packet) ->
{discarded, {badarg, TDomain}}.
sec_model('version-1') -> ?SEC_V1;
@@ -234,15 +247,19 @@ sec_model('version-2') -> ?SEC_V2C.
%% Handles a SNMPv3 Message, following the procedures in rfc2272,
%% section 4.2 and 7.2
%%-----------------------------------------------------------------
-v3_proc(NoteStore, Packet, _TDomain, _TAddress, V3Hdr, Data, Log) ->
- case (catch v3_proc(NoteStore, Packet, V3Hdr, Data, Log)) of
+v3_proc(NoteStore, Packet, _TDomain, _TAddress, LocalEngineID,
+ V3Hdr, Data, Log) ->
+ case (catch v3_proc(NoteStore, Packet, LocalEngineID, V3Hdr, Data, Log)) of
{'EXIT', Reason} ->
exit(Reason);
Result ->
Result
end.
-v3_proc(NoteStore, Packet, V3Hdr, Data, Log) ->
+v3_proc(NoteStore, Packet, LocalEngineID, V3Hdr, Data, Log) ->
+ ?vtrace("v3_proc -> entry with"
+ "~n LocalEngineID: ~p",
+ [LocalEngineID]),
%% 7.2.3
#v3_hdr{msgID = MsgID,
msgMaxSize = MMS,
@@ -250,7 +267,7 @@ v3_proc(NoteStore, Packet, V3Hdr, Data, Log) ->
msgSecurityModel = MsgSecurityModel,
msgSecurityParameters = SecParams,
hdr_size = HdrSize} = V3Hdr,
- ?vdebug("v3_proc -> version 3 message header:"
+ ?vdebug("v3_proc -> version 3 message header [7.2.3]:"
"~n msgID = ~p"
"~n msgMaxSize = ~p"
"~n msgFlags = ~p"
@@ -263,17 +280,19 @@ v3_proc(NoteStore, Packet, V3Hdr, Data, Log) ->
SecLevel = check_sec_level(MsgFlags),
IsReportable = snmp_misc:is_reportable(MsgFlags),
%% 7.2.6
- ?vtrace("v3_proc -> "
+ ?vtrace("v3_proc -> [7.2.6]"
"~n SecModule = ~p"
"~n SecLevel = ~p"
"~n IsReportable = ~p",
- [SecModule,SecLevel,IsReportable]),
+ [SecModule, SecLevel, IsReportable]),
SecRes = (catch SecModule:process_incoming_msg(Packet, Data,
- SecParams, SecLevel)),
+ SecParams, SecLevel,
+ LocalEngineID)),
?vtrace("v3_proc -> message processing result: "
"~n SecRes: ~p", [SecRes]),
{SecEngineID, SecName, ScopedPDUBytes, SecData, DiscoOrPlain} =
- check_sec_module_result(SecRes, V3Hdr, Data, IsReportable, Log),
+ check_sec_module_result(SecRes, V3Hdr, Data,
+ LocalEngineID, IsReportable, Log),
?vtrace("v3_proc -> "
"~n DiscoOrPlain: ~w"
"~n SecEngineID: ~w"
@@ -311,7 +330,7 @@ v3_proc(NoteStore, Packet, V3Hdr, Data, Log) ->
Log(PDU#pdu.type, Packet)
end,
%% Make sure a get_bulk doesn't get too big.
- AgentMS = snmp_framework_mib:get_engine_max_message_size(),
+ AgentMS = get_engine_max_message_size(LocalEngineID),
%% PduMMS is supposed to be the maximum total length of the response
%% PDU we can send. From the MMS, we need to subtract everything before
%% the PDU, i.e. Message and ScopedPDU.
@@ -415,8 +434,8 @@ v3_proc(NoteStore, Packet, V3Hdr, Data, Log) ->
throw({discarded, received_v2_trap});
Type ->
%% 7.2.13
- SnmpEngineID = snmp_framework_mib:get_engine_id(),
- ?vtrace("v3_proc -> SnmpEngineID = ~w", [SnmpEngineID]),
+ SnmpEngineID = LocalEngineID,
+ ?vtrace("v3_proc -> 7.2.13", []),
case SecEngineID of
SnmpEngineID when (DiscoOrPlain =:= discovery) ->
%% This is a discovery step 2 message!
@@ -429,6 +448,7 @@ v3_proc(NoteStore, Packet, V3Hdr, Data, Log) ->
ContextName,
SecData,
PDU,
+ LocalEngineID,
Log);
SnmpEngineID when (DiscoOrPlain =:= plain) ->
@@ -443,18 +463,14 @@ v3_proc(NoteStore, Packet, V3Hdr, Data, Log) ->
_ ->
%% 4.2.2.1.2
NIsReportable = snmp_misc:is_reportable_pdu(Type),
- Val = inc(snmpUnknownPDUHandlers),
- ErrorInfo = {#varbind{oid = ?snmpUnknownPDUHandlers,
- variabletype = 'Counter32',
- value = Val},
- SecName,
- [{securityLevel, SecLevel},
- {contextEngineID, ContextEngineID},
- {contextName, ContextName}]},
+ ErrorInfo =
+ snmpUnknownPDUHandlers_ei(SecName, SecLevel,
+ ContextEngineID,
+ ContextName),
case generate_v3_report_msg(MsgID,
MsgSecurityModel,
- Data, ErrorInfo,
- Log) of
+ Data, LocalEngineID,
+ ErrorInfo, Log) of
{ok, Report} when NIsReportable =:= true ->
{discarded, snmpUnknownPDUHandlers, Report};
_ ->
@@ -473,6 +489,7 @@ v3_proc(NoteStore, Packet, V3Hdr, Data, Log) ->
ContextName,
SecData,
PDU,
+ LocalEngineID,
Log);
_ ->
@@ -480,6 +497,21 @@ v3_proc(NoteStore, Packet, V3Hdr, Data, Log) ->
end
end.
+make_error_info(Variable, Oid, SecName, Opts) ->
+ Val = inc(Variable),
+ VB = #varbind{oid = Oid,
+ variabletype = 'Counter32',
+ value = Val},
+ {VB, SecName, Opts}.
+
+snmpUnknownPDUHandlers_ei(SecName, SecLevel,
+ ContextEngineID, ContextName) ->
+ Opts = [{securityLevel, SecLevel},
+ {contextEngineID, ContextEngineID},
+ {contextName, ContextName}],
+ make_error_info(snmpUnknownPDUHandlers,
+ ?snmpUnknownPDUHandlers_instance,
+ SecName, Opts).
get_security_module(?SEC_USM) ->
snmpa_usm;
@@ -501,7 +533,7 @@ check_sec_level(Unknown) ->
inc(snmpInvalidMsgs),
throw({discarded, snmpInvalidMsgs}).
-check_sec_module_result(Res, V3Hdr, Data, IsReportable, Log) ->
+check_sec_module_result(Res, V3Hdr, Data, LocalEngineID, IsReportable, Log) ->
case Res of
{ok, X} ->
X;
@@ -516,7 +548,7 @@ check_sec_module_result(Res, V3Hdr, Data, IsReportable, Log) ->
#v3_hdr{msgID = MsgID, msgSecurityModel = MsgSecModel} = V3Hdr,
Pdu = get_scoped_pdu(Data),
case generate_v3_report_msg(MsgID, MsgSecModel, Pdu,
- ErrorInfo, Log) of
+ LocalEngineID, ErrorInfo, Log) of
{ok, Report} ->
throw({discarded, {securityError, Reason}, Report});
{discarded, _SomeOtherReason} ->
@@ -545,8 +577,15 @@ get_scoped_pdu(D) ->
generate_response_msg(Vsn, RePdu, Type, ACMData, Log) ->
generate_response_msg(Vsn, RePdu, Type, ACMData, Log, 1).
+generate_response_msg(Vsn, RePdu, Type, ACMData, Log, N) when is_integer(N) ->
+ LocalEngineID = ?DEFAULT_LOCAL_ENGINE_ID,
+ generate_response_msg(Vsn, RePdu, Type, ACMData, LocalEngineID, Log, N);
+generate_response_msg(Vsn, RePdu, Type, ACMData, LocalEngineID, Log) ->
+ generate_response_msg(Vsn, RePdu, Type, ACMData, LocalEngineID, Log, 1).
+
generate_response_msg(Vsn, RePdu, Type,
{community, _SecModel, Community, _IpUdp},
+ LocalEngineID,
Log, _) ->
case catch snmp_pdus:enc_pdu(RePdu) of
{'EXIT', Reason} ->
@@ -555,8 +594,9 @@ generate_response_msg(Vsn, RePdu, Type,
[RePdu, Community, Reason]),
{discarded, Reason};
PduBytes ->
- Message = #message{version = Vsn, vsn_hdr = Community,
- data = PduBytes},
+ Message = #message{version = Vsn,
+ vsn_hdr = Community,
+ data = PduBytes},
case catch list_to_binary(
snmp_pdus:enc_message_only(Message)) of
{'EXIT', Reason} ->
@@ -565,7 +605,7 @@ generate_response_msg(Vsn, RePdu, Type,
[RePdu, Community, Reason]),
{discarded, Reason};
Packet ->
- MMS = snmp_framework_mib:get_engine_max_message_size(),
+ MMS = get_engine_max_message_size(LocalEngineID),
case size(Packet) of
Len when Len =< MMS ->
Log(Type, Packet),
@@ -584,6 +624,7 @@ generate_response_msg(Vsn, RePdu, Type,
generate_response_msg(Vsn, RePdu, Type,
{v3, MsgID, MsgSecurityModel, SecName, SecLevel,
ContextEngineID, ContextName, SecData},
+ LocalEngineID,
Log, N) ->
%% rfc2272: 7.1 steps 6-8
ScopedPDU = #scopedPdu{contextEngineID = ContextEngineID,
@@ -596,7 +637,7 @@ generate_response_msg(Vsn, RePdu, Type,
[RePdu, ContextName, Reason]),
{discarded, Reason};
ScopedPDUBytes ->
- AgentMS = snmp_framework_mib:get_engine_max_message_size(),
+ AgentMS = get_engine_max_message_size(LocalEngineID),
V3Hdr = #v3_hdr{msgID = MsgID,
msgMaxSize = AgentMS,
msgFlags = snmp_misc:mk_msg_flags(Type, SecLevel),
@@ -611,13 +652,14 @@ generate_response_msg(Vsn, RePdu, Type,
?SEC_USM ->
snmpa_usm
end,
- SecEngineID = snmp_framework_mib:get_engine_id(),
+ SecEngineID = LocalEngineID,
?vtrace("generate_response_msg -> SecEngineID: ~w", [SecEngineID]),
case (catch SecModule:generate_outgoing_msg(Message,
SecEngineID,
SecName,
SecData,
- SecLevel)) of
+ SecLevel,
+ LocalEngineID)) of
{'EXIT', Reason} ->
config_err("~p (message: ~p)", [Reason, Message]),
{discarded, Reason};
@@ -668,12 +710,14 @@ generate_response_msg(Vsn, RePdu, Type,
SecName, SecLevel,
ContextEngineID,
ContextName,
- SecData}, Log, N+1)
+ SecData},
+ LocalEngineID, Log, N+1)
end
end
end.
-generate_v3_report_msg(MsgID, MsgSecurityModel, Data, ErrorInfo, Log) ->
+generate_v3_report_msg(MsgID, MsgSecurityModel, Data, LocalEngineID,
+ ErrorInfo, Log) ->
{Varbind, SecName, Opts} = ErrorInfo,
ReqId =
if
@@ -689,7 +733,7 @@ generate_v3_report_msg(MsgID, MsgSecurityModel, Data, ErrorInfo, Log) ->
error_index = 0,
varbinds = [Varbind]},
SecLevel = snmp_misc:get_option(securityLevel, Opts, 0),
- SnmpEngineID = snmp_framework_mib:get_engine_id(),
+ SnmpEngineID = LocalEngineID,
ContextEngineID =
snmp_misc:get_option(contextEngineID, Opts, SnmpEngineID),
ContextName = snmp_misc:get_option(contextName, Opts, ""),
@@ -697,7 +741,8 @@ generate_v3_report_msg(MsgID, MsgSecurityModel, Data, ErrorInfo, Log) ->
generate_response_msg('version-3', Pdu, report,
{v3, MsgID, MsgSecurityModel, SecName, SecLevel,
- ContextEngineID, ContextName, SecData}, Log).
+ ContextEngineID, ContextName, SecData},
+ LocalEngineID, Log).
%% req_id(#scopedPdu{data = #pdu{request_id = ReqId}}) ->
%% ?vtrace("Report ReqId: ~p",[ReqId]),
@@ -719,7 +764,8 @@ generate_discovery1_report_msg(MsgID, MsgSecurityModel,
SecName, SecLevel,
ContextEngineID, ContextName,
{SecData, Oid, Value},
- #pdu{request_id = ReqId}, Log) ->
+ #pdu{request_id = ReqId},
+ LocalEngineID, Log) ->
?vtrace("generate_discovery1_report_msg -> entry with"
"~n ReqId: ~p"
"~n Value: ~p", [ReqId, Value]),
@@ -734,7 +780,8 @@ generate_discovery1_report_msg(MsgID, MsgSecurityModel,
varbinds = [Varbind]},
case generate_response_msg('version-3', PduOut, report,
{v3, MsgID, MsgSecurityModel, SecName, SecLevel,
- ContextEngineID, ContextName, SecData}, Log) of
+ ContextEngineID, ContextName, SecData},
+ LocalEngineID, Log) of
{ok, Packet} ->
{discovery, Packet};
Error ->
@@ -745,7 +792,8 @@ generate_discovery1_report_msg(MsgID, MsgSecurityModel,
generate_discovery2_report_msg(MsgID, MsgSecurityModel,
SecName, SecLevel,
ContextEngineID, ContextName,
- SecData, #pdu{request_id = ReqId}, Log) ->
+ SecData, #pdu{request_id = ReqId},
+ LocalEngineID, Log) ->
?vtrace("generate_discovery2_report_msg -> entry with"
"~n ReqId: ~p", [ReqId]),
SecModule = get_security_module(MsgSecurityModel),
@@ -757,7 +805,8 @@ generate_discovery2_report_msg(MsgID, MsgSecurityModel,
varbinds = [Vb]},
case generate_response_msg('version-3', PduOut, report,
{v3, MsgID, MsgSecurityModel, SecName, SecLevel,
- ContextEngineID, ContextName, SecData}, Log) of
+ ContextEngineID, ContextName, SecData},
+ LocalEngineID, Log) of
{ok, Packet} ->
{discovery, Packet};
Error ->
@@ -816,7 +865,11 @@ set_vb_null([]) ->
%% Executed when a message that isn't a response is generated, i.e.
%% a trap or an inform.
%%-----------------------------------------------------------------
-generate_msg(Vsn, _NoteStore, Pdu, {community, Community}, To) ->
+generate_msg(Vsn, NoteStore, Pdu, ACMData, To) ->
+ LocalEngineID = ?DEFAULT_LOCAL_ENGINE_ID,
+ generate_msg(Vsn, NoteStore, Pdu, ACMData, LocalEngineID, To).
+
+generate_msg(Vsn, _NoteStore, Pdu, {community, Community}, LocalEngineID, To) ->
Message = #message{version = Vsn, vsn_hdr = Community, data = Pdu},
case catch list_to_binary(snmp_pdus:enc_message(Message)) of
{'EXIT', Reason} ->
@@ -825,7 +878,7 @@ generate_msg(Vsn, _NoteStore, Pdu, {community, Community}, To) ->
[Pdu, Community, Reason]),
{discarded, Reason};
Packet ->
- AgentMax = snmp_framework_mib:get_engine_max_message_size(),
+ AgentMax = get_engine_max_message_size(LocalEngineID),
case size(Packet) of
Len when Len =< AgentMax ->
{ok, mk_v1_v2_packet_list(To, Packet, Len, Pdu)};
@@ -838,9 +891,9 @@ generate_msg(Vsn, _NoteStore, Pdu, {community, Community}, To) ->
end
end;
generate_msg('version-3', NoteStore, Pdu,
- {v3, ContextEngineID, ContextName}, To) ->
- %% rfc2272: 7.1.6
- ScopedPDU = #scopedPdu{contextEngineID = ContextEngineID,
+ {v3, ContextEngineID, ContextName}, LocalEngineID, To) ->
+ %% rfc2272: 7.1 step 6
+ ScopedPDU = #scopedPdu{contextEngineID = LocalEngineID,
contextName = ContextName,
data = Pdu},
case (catch snmp_pdus:enc_scoped_pdu(ScopedPDU)) of
@@ -851,7 +904,8 @@ generate_msg('version-3', NoteStore, Pdu,
{discarded, Reason};
ScopedPDUBytes ->
{ok, mk_v3_packet_list(NoteStore, To, ScopedPDUBytes, Pdu,
- ContextEngineID, ContextName)}
+ ContextEngineID, ContextName,
+ LocalEngineID)}
end.
@@ -1094,17 +1148,21 @@ mk_msg_flags(PduType, SecLevel) ->
mk_v3_packet_entry(NoteStore, Domain, Addr,
{SecModel, SecName, SecLevel, TargetAddrName},
- ScopedPDUBytes, Pdu, ContextEngineID, ContextName) ->
- %% 7.1.7
- ?vtrace("mk_v3_packet_entry -> entry - 7.1.7", []),
- MsgID = generate_msg_id(),
- PduType = Pdu#pdu.type,
- MsgFlags = mk_msg_flags(PduType, SecLevel),
+ ScopedPDUBytes, Pdu, _ContextEngineID, ContextName,
+ LocalEngineID) ->
+ %% rfc2272 7.1 step 77
+ ?vtrace("mk_v3_packet_entry -> entry - RFC2272-7.1:7", []),
+ MsgVersion = 'version-3', % 7.1:7a
+ MsgID = generate_msg_id(), % 7.1:7b
+ MaxMsgSz = get_max_message_size(), % 7.1:7c
+ PduType = Pdu#pdu.type,
+ MsgFlags = mk_msg_flags(PduType, SecLevel), % 7.1:7d
+ MsgSecModel = SecModel, % 7.1:7e
V3Hdr = #v3_hdr{msgID = MsgID,
- msgMaxSize = get_max_message_size(),
+ msgMaxSize = MaxMsgSz,
msgFlags = MsgFlags,
- msgSecurityModel = SecModel},
- Message = #message{version = 'version-3',
+ msgSecurityModel = MsgSecModel},
+ Message = #message{version = MsgVersion,
vsn_hdr = V3Hdr,
data = ScopedPDUBytes},
SecModule =
@@ -1113,12 +1171,21 @@ mk_v3_packet_entry(NoteStore, Domain, Addr,
snmpa_usm
end,
+ %%
+ %% 7.1:8 - If the PDU is from the Response Class or the Internal Class
+ %% securityEngineID = snmpEngineID (local/source)
+ %% 7.1:9 - If the PDU is from the Unconfirmed Class
+ %% securityEngineID = snmpEngineID (local/source)
+ %% else
+ %% securityEngineID = targetEngineID (remote/destination)
+ %%
+
%% 7.1.9a
?vtrace("mk_v3_packet_entry -> sec engine id - 7.1.9a", []),
SecEngineID =
case PduType of
'snmpv2-trap' ->
- snmp_framework_mib:get_engine_id();
+ LocalEngineID;
_ ->
%% This is the implementation dependent target engine id
%% procedure.
@@ -1141,8 +1208,9 @@ mk_v3_packet_entry(NoteStore, Domain, Addr,
?vdebug("mk_v3_packet_entry -> secEngineID: ~p", [SecEngineID]),
%% 7.1.9b
- case catch SecModule:generate_outgoing_msg(Message, SecEngineID,
- SecName, [], SecLevel) of
+ case (catch SecModule:generate_outgoing_msg(Message, SecEngineID,
+ SecName, [], SecLevel,
+ LocalEngineID)) of
{'EXIT', Reason} ->
config_err("~p (message: ~p)", [Reason, Message]),
skip;
@@ -1169,7 +1237,7 @@ mk_v3_packet_entry(NoteStore, Domain, Addr,
sec_model = SecModel,
sec_name = SecName,
sec_level = SecLevel,
- ctx_engine_id = ContextEngineID,
+ ctx_engine_id = LocalEngineID,
ctx_name = ContextName,
disco = false,
req_id = Pdu#pdu.request_id},
@@ -1180,15 +1248,16 @@ mk_v3_packet_entry(NoteStore, Domain, Addr,
mk_v3_packet_list(NoteStore, To,
- ScopedPDUBytes, Pdu, ContextEngineID, ContextName) ->
+ ScopedPDUBytes, Pdu, ContextEngineID, ContextName,
+ LocalEngineID) ->
mk_v3_packet_list(NoteStore, To,
ScopedPDUBytes, Pdu,
- ContextEngineID, ContextName, []).
+ ContextEngineID, ContextName, LocalEngineID, []).
mk_v3_packet_list(_, [],
_ScopedPDUBytes, _Pdu,
_ContextEngineID, _ContextName,
- Acc) ->
+ _LocalEngineID, Acc) ->
lists:reverse(Acc);
%% This clause is for backward compatibillity reasons
@@ -1196,20 +1265,21 @@ mk_v3_packet_list(_, [],
mk_v3_packet_list(NoteStore,
[{{?snmpUDPDomain, [A,B,C,D,U1,U2]}, SecData} | T],
ScopedPDUBytes, Pdu, ContextEngineID, ContextName,
- Acc) ->
+ LocalEngineID, Acc) ->
case mk_v3_packet_entry(NoteStore,
snmpUDPDomain, {{A,B,C,D}, U1 bsl 8 + U2}, SecData,
ScopedPDUBytes, Pdu,
- ContextEngineID, ContextName) of
+ ContextEngineID, ContextName, LocalEngineID) of
skip ->
mk_v3_packet_list(NoteStore, T,
ScopedPDUBytes, Pdu,
- ContextEngineID, ContextName,
+ ContextEngineID, ContextName, LocalEngineID,
Acc);
{ok, Entry} ->
mk_v3_packet_list(NoteStore, T,
ScopedPDUBytes, Pdu,
- ContextEngineID, ContextName, [Entry | Acc])
+ ContextEngineID, ContextName, LocalEngineID,
+ [Entry | Acc])
end;
%% This is the new clause
@@ -1218,11 +1288,11 @@ mk_v3_packet_list(NoteStore,
mk_v3_packet_list(NoteStore,
[{{Domain, Addr}, SecData} | T],
ScopedPDUBytes, Pdu, ContextEngineID, ContextName,
- Acc) ->
+ LocalEngineID, Acc) ->
case mk_v3_packet_entry(NoteStore,
Domain, Addr, SecData,
ScopedPDUBytes, Pdu,
- ContextEngineID, ContextName) of
+ ContextEngineID, ContextName, LocalEngineID) of
skip ->
mk_v3_packet_list(NoteStore, T,
ScopedPDUBytes, Pdu,
@@ -1230,7 +1300,8 @@ mk_v3_packet_list(NoteStore,
{ok, Entry} ->
mk_v3_packet_list(NoteStore, T,
ScopedPDUBytes, Pdu,
- ContextEngineID, ContextName, [Entry | Acc])
+ ContextEngineID, ContextName,
+ LocalEngineID, [Entry | Acc])
end.
@@ -1253,6 +1324,9 @@ gen(Id) ->
get_target_engine_id(TargetAddrName) ->
snmp_target_mib:get_target_engine_id(TargetAddrName).
+get_engine_max_message_size(_LocalEngineID) ->
+ snmp_framework_mib:get_engine_max_message_size().
+
sec_module(?SEC_USM) ->
snmpa_usm.
diff --git a/lib/snmp/src/agent/snmpa_net_if.erl b/lib/snmp/src/agent/snmpa_net_if.erl
index d703e5ac55..97a7a63dee 100644
--- a/lib/snmp/src/agent/snmpa_net_if.erl
+++ b/lib/snmp/src/agent/snmpa_net_if.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2004-2009. All Rights Reserved.
+%% Copyright Ericsson AB 2004-2010. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
@@ -55,6 +55,9 @@
-define(DEFAULT_FILTER_MODULE, snmpa_net_if_filter).
-define(DEFAULT_FILTER_OPTS, [{module, ?DEFAULT_FILTER_MODULE}]).
+-define(ATL_SEQNO_INITIAL, 1).
+-define(ATL_SEQNO_MAX, 2147483647).
+
%%%-----------------------------------------------------------------
%%% This module implements the default Network Interface part
@@ -194,24 +197,43 @@ do_init(Prio, NoteStore, MasterAgent, Parent, Opts) ->
{error, {udp_open, UDPPort, Reason}}
end.
+
create_log() ->
case ets:lookup(snmp_agent_table, audit_trail_log) of
[] ->
{undefined, []};
[{audit_trail_log, AtlOpts}] ->
- ?vtrace("AtlOpts: ~p",[AtlOpts]),
+ ?vtrace("AtlOpts: ~p", [AtlOpts]),
Type = get_atl_type(AtlOpts),
Dir = get_atl_dir(AtlOpts),
Size = get_atl_size(AtlOpts),
Repair = get_atl_repair(AtlOpts),
Name = ?audit_trail_log_name,
File = filename:absname(?audit_trail_log_file, Dir),
- case snmp_log:create(Name, File, Size, Repair, true) of
- {ok, Log} ->
- ?vdebug("log created: ~w",[Log]),
- {Log, Type};
- {error, Reason} ->
- throw({error, {create_log, Reason}})
+ case get_atl_seqno(AtlOpts) of
+ true ->
+ Initial = ?ATL_SEQNO_INITIAL,
+ Max = ?ATL_SEQNO_MAX,
+ Module = snmpa_agent,
+ Function = increment_counter,
+ Args = [atl_seqno, Initial, Max],
+ SeqNoGen = {Module, Function, Args},
+ case snmp_log:create(Name, File,
+ SeqNoGen, Size, Repair, true) of
+ {ok, Log} ->
+ ?vdebug("log created: ~w", [Log]),
+ {Log, Type};
+ {error, Reason} ->
+ throw({error, {create_log, Reason}})
+ end;
+ _ ->
+ case snmp_log:create(Name, File, Size, Repair, true) of
+ {ok, Log} ->
+ ?vdebug("log created: ~w", [Log]),
+ {Log, Type};
+ {error, Reason} ->
+ throw({error, {create_log, Reason}})
+ end
end
end.
@@ -456,12 +478,13 @@ update_req_counter_outgoing(#state{limit = Limit, rcnt = RCnt} = S,
S#state{rcnt = NewRCnt}.
-maybe_handle_recv(#state{filter = FilterMod} = S,
+maybe_handle_recv(#state{usock = Sock, filter = FilterMod} = S,
Ip, Port, Packet) ->
case (catch FilterMod:accept_recv(Ip, Port)) of
false ->
%% Drop the received packet
inc(netIfMsgInDrops),
+ active_once(Sock),
S;
_ ->
handle_recv(S, Ip, Port, Packet)
@@ -918,61 +941,29 @@ system_continue(_Parent, _Dbg, S) ->
loop(S).
system_terminate(Reason, _Parent, _Dbg, #state{log = Log}) ->
+ ?vlog("system-terminate -> entry with"
+ "~n Reason: ~p", [Reason]),
do_close_log(Log),
exit(Reason).
-system_code_change(OldState, _Module, _OldVsn, upgrade_from_pre_4_10) ->
- {state,
- parent = Parent,
- note_store = NS,
- master_agent = MA,
- usock = Sock,
- usock_opts = SockOpts,
- mpd_state = MpdState,
- log = Log,
- reqs = Reqs,
- debug = Dbg,
- limit = Limit,
- rcnt = RCNT} = OldState,
- NewState = #state{parent = Parent,
- note_store = NS,
- master_agent = MA,
- usock = Sock,
- usock_opts = SockOpts,
- mpd_state = MpdState,
- log = Log,
- reqs = Reqs,
- debug = Dbg,
- limit = Limit,
- rcnt = RCNT,
- filter = create_filter(?DEFAULT_FILTER_OPTS)},
+system_code_change(OldState, _Module, _OldVsn, downgrade_to_pre_4_16) ->
+ {OldLog, Type} = OldState#state.log,
+ NewLog = snmp_log:downgrade(OldLog),
+ NewState = OldState#state{log = {NewLog, Type}},
{ok, NewState};
-system_code_change(OldState, _Module, _OldVsn, downgrade_to_pre_4_10) ->
- #state{parent = Parent,
- note_store = NS,
- master_agent = MA,
- usock = Sock,
- usock_opts = SockOpts,
- mpd_state = MpdState,
- log = Log,
- reqs = Reqs,
- debug = Dbg,
- limit = Limit,
- rcnt = RCNT} = OldState,
- NewState =
- {state,
- parent = Parent,
- note_store = NS,
- master_agent = MA,
- usock = Sock,
- usock_opts = SockOpts,
- mpd_state = MpdState,
- log = Log,
- reqs = Reqs,
- debug = Dbg,
- limit = Limit,
- rcnt = RCNT},
+
+system_code_change(OldState, _Module, _OldVsn, upgrade_from_pre_4_16) ->
+ Initial = ?ATL_SEQNO_INITIAL,
+ Max = ?ATL_SEQNO_MAX,
+ Module = snmpa_agent,
+ Function = increment_counter,
+ Args = [atl_seqno, Initial, Max],
+ SeqNoGen = {Module, Function, Args},
+ {OldLog, Type} = OldState#state.log,
+ NewLog = snmp_log:upgrade(OldLog, SeqNoGen),
+ NewState = OldState#state{log = {NewLog, Type}},
{ok, NewState};
+
system_code_change(S, _Module, _OldVsn, _Extra) ->
{ok, S}.
@@ -1111,6 +1102,9 @@ get_atl_size(Opts) ->
get_atl_repair(Opts) ->
snmp_misc:get_option(repair, Opts, true).
+get_atl_seqno(Opts) ->
+ snmp_misc:get_option(seqno, Opts, false).
+
get_verbosity(Opts) ->
snmp_misc:get_option(verbosity, Opts, ?default_verbosity).
diff --git a/lib/snmp/src/agent/snmpa_supervisor.erl b/lib/snmp/src/agent/snmpa_supervisor.erl
index 5ef5914e18..7a9c214e0d 100644
--- a/lib/snmp/src/agent/snmpa_supervisor.erl
+++ b/lib/snmp/src/agent/snmpa_supervisor.erl
@@ -176,8 +176,8 @@ init([AgentType, Opts]) ->
"~n AgentType: ~p"
"~n Opts: ~p", [AgentType, Opts]),
- put(sname, asup),
- put(verbosity,get_verbosity(Opts)),
+ put(sname, asup),
+ put(verbosity, get_verbosity(Opts)),
?vlog("starting",[]),
@@ -203,7 +203,12 @@ init([AgentType, Opts]) ->
Vsns = get_opt(versions, Opts, [v1,v2,v3]),
?vdebug("[agent table] store versions: ~p",[Vsns]),
ets:insert(snmp_agent_table, {versions, Vsns}),
-
+
+ %% -- Max number of VBs in a Get-BULK response --
+ GbMaxVBs = get_gb_max_vbs(Opts),
+ ?vdebug("[agent table] Get-BULK max VBs: ~p", [GbMaxVBs]),
+ ets:insert(snmp_agent_table, {gb_max_vbs, GbMaxVBs}),
+
%% -- DB-directory --
DbDir = get_opt(db_dir, Opts),
?vdebug("[agent table] store db_dir: ~n ~p",[DbDir]),
@@ -377,7 +382,8 @@ init([AgentType, Opts]) ->
{versions, Vsns},
{net_if, NiOpts},
{mib_server, MibsOpts},
- {note_store, NsOpts}|
+ {note_store, NsOpts},
+ {gb_max_vbs, GbMaxVBs} |
get_opt(master_agent_options, Opts, [])],
AgentSpec =
@@ -542,6 +548,32 @@ get_verbosity(Opts) ->
get_agent_type(Opts) ->
get_opt(agent_type, Opts, master).
+
+%% We validate this option! This should really be done for all
+%% options, but it is beyond the scope of this ticket, OTP-9700.
+
+get_gb_max_vbs(Opts) ->
+ Validate =
+ fun(GbMaxVBs)
+ when ((is_integer(GbMaxVBs) andalso (GbMaxVBs > 0)) orelse
+ (GbMaxVBs =:= infinity)) ->
+ ok;
+ (_) ->
+ error
+ end,
+ get_option(gb_max_vbs, ?DEFAULT_GB_MAX_VBS, Validate, Opts).
+
+get_option(Key, Default, Validate, Opts)
+ when is_list(Opts) andalso is_function(Validate) ->
+ Value = get_opt(Key, Opts, Default),
+ case Validate(Value) of
+ ok ->
+ Value;
+ error ->
+ exit({bad_option, Key, Value})
+ end.
+
+
get_opt(Key, Opts) ->
snmp_misc:get_option(Key, Opts).
diff --git a/lib/snmp/src/agent/snmpa_trap.erl b/lib/snmp/src/agent/snmpa_trap.erl
index b1096b1135..3b31c8d909 100644
--- a/lib/snmp/src/agent/snmpa_trap.erl
+++ b/lib/snmp/src/agent/snmpa_trap.erl
@@ -1,19 +1,19 @@
%%
%% %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
%% 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(snmpa_trap).
@@ -23,14 +23,18 @@
%%%-----------------------------------------------------------------
%% External exports
-export([construct_trap/2,
- try_initialise_vars/2, send_trap/6]).
+ try_initialise_vars/2,
+ send_trap/6, send_trap/7]).
-export([send_discovery/5]).
%% Internal exports
--export([init_v2_inform/9, init_v3_inform/9, send_inform/6]).
+-export([init_v2_inform/9,
+ init_v3_inform/9, init_v3_inform/10,
+ send_inform/6]).
-export([init_discovery_inform/12, send_discovery_inform/5]).
-include("snmp_types.hrl").
+-include("snmpa_internal.hrl").
-include("SNMPv2-MIB.hrl").
-include("SNMPv2-TM.hrl").
-include("SNMPv2-TC.hrl").
@@ -331,13 +335,36 @@ make_varbind_list(Varbinds) ->
%% SnmpTargetAddrTable (using the Tag).
%%-----------------------------------------------------------------
send_trap(TrapRec, NotifyName, ContextName, Recv, Vbs, NetIf) ->
- (catch do_send_trap(TrapRec, NotifyName, ContextName, Recv, Vbs, NetIf)).
+ LocalEngineID = ?DEFAULT_LOCAL_ENGINE_ID,
+ send_trap(TrapRec, NotifyName, ContextName, Recv, Vbs,
+ LocalEngineID, NetIf).
+
+%% The agent normally does not care about the result,
+%% but since it can be usefull when debugging, add
+%% some info when we fail to send the trap(s).
+send_trap(TrapRec, NotifyName, ContextName, Recv, Vbs, LocalEngineID, NetIf) ->
+ try
+ begin
+ do_send_trap(TrapRec, NotifyName, ContextName, Recv, Vbs,
+ LocalEngineID, NetIf)
+ end
+ catch
+ T:E ->
+ Info = [{args, [TrapRec, NotifyName, ContextName,
+ Recv, Vbs, LocalEngineID, NetIf]},
+ {tag, T},
+ {err, E},
+ {stacktrace, erlang:get_stacktrace()}],
+ {error, {failed_sending_trap, Info}}
+ end.
+
-do_send_trap(TrapRec, NotifyName, ContextName, Recv, Vbs, NetIf) ->
+do_send_trap(TrapRec, NotifyName, ContextName, Recv, Vbs,
+ LocalEngineID, NetIf) ->
VarbindList = make_varbind_list(Vbs),
Dests = find_dests(NotifyName),
send_trap_pdus(Dests, ContextName, {TrapRec, VarbindList}, [], [], [],
- Recv, NetIf).
+ Recv, LocalEngineID, NetIf).
send_discovery(TargetName, Record, ContextName, Vbs, NetIf) ->
case find_dest(TargetName) of
@@ -619,7 +646,9 @@ send_discovery_inform(Parent, Timeout, Retry, Msg, NetIf) ->
%%-----------------------------------------------------------------
send_trap_pdus([{DestAddr, TargetName, {MpModel, SecModel, SecName, SecLevel},
Type} | T],
- ContextName,{TrapRec, Vbs}, V1Res, V2Res, V3Res, Recv, NetIf) ->
+ ContextName,
+ {TrapRec, Vbs}, V1Res, V2Res, V3Res, Recv,
+ LocalEngineID, NetIf) ->
?vdebug("send trap pdus: "
"~n Destination address: ~p"
"~n Target name: ~p"
@@ -634,7 +663,7 @@ send_trap_pdus([{DestAddr, TargetName, {MpModel, SecModel, SecName, SecLevel},
case check_all_varbinds(TrapRec, Vbs, MibView) of
true when MpModel =:= ?MP_V1 ->
?vtrace("send_trap_pdus -> v1 mp model",[]),
- ContextEngineId = snmp_framework_mib:get_engine_id(),
+ ContextEngineId = LocalEngineID,
case snmp_community_mib:vacm2community({SecName,
ContextEngineId,
ContextName},
@@ -644,16 +673,18 @@ send_trap_pdus([{DestAddr, TargetName, {MpModel, SecModel, SecName, SecLevel},
[element(2, DestAddr)]),
send_trap_pdus(T, ContextName, {TrapRec, Vbs},
[{DestAddr, Community} | V1Res],
- V2Res, V3Res, Recv, NetIf);
+ V2Res, V3Res, Recv,
+ LocalEngineID, NetIf);
undefined ->
?vdebug("No community found for v1 dest: ~p",
[element(2, DestAddr)]),
send_trap_pdus(T, ContextName, {TrapRec, Vbs},
- V1Res, V2Res, V3Res, Recv, NetIf)
+ V1Res, V2Res, V3Res, Recv,
+ LocalEngineID, NetIf)
end;
true when MpModel =:= ?MP_V2C ->
?vtrace("send_trap_pdus -> v2c mp model",[]),
- ContextEngineId = snmp_framework_mib:get_engine_id(),
+ ContextEngineId = LocalEngineID,
case snmp_community_mib:vacm2community({SecName,
ContextEngineId,
ContextName},
@@ -664,12 +695,13 @@ send_trap_pdus([{DestAddr, TargetName, {MpModel, SecModel, SecName, SecLevel},
send_trap_pdus(T, ContextName, {TrapRec, Vbs},
V1Res,
[{DestAddr, Community, Type}|V2Res],
- V3Res, Recv, NetIf);
+ V3Res, Recv, LocalEngineID, NetIf);
undefined ->
?vdebug("No community found for v2c dest: ~p",
[element(2, DestAddr)]),
send_trap_pdus(T, ContextName, {TrapRec, Vbs},
- V1Res, V2Res, V3Res, Recv, NetIf)
+ V1Res, V2Res, V3Res, Recv,
+ LocalEngineID, NetIf)
end;
true when MpModel =:= ?MP_V3 ->
?vtrace("send_trap_pdus -> v3 mp model",[]),
@@ -678,18 +710,20 @@ send_trap_pdus([{DestAddr, TargetName, {MpModel, SecModel, SecName, SecLevel},
send_trap_pdus(T, ContextName, {TrapRec, Vbs},
V1Res, V2Res,
[{DestAddr, MsgData, Type} | V3Res],
- Recv, NetIf);
+ Recv, LocalEngineID, NetIf);
true ->
?vlog("bad MpModel ~p for dest ~p",
[MpModel, element(2, DestAddr)]),
send_trap_pdus(T, ContextName, {TrapRec, Vbs},
- V1Res, V2Res, V3Res, Recv, NetIf);
+ V1Res, V2Res, V3Res, Recv,
+ LocalEngineID, NetIf);
_ ->
?vlog("no access for dest: "
"~n ~p in target ~p",
[element(2, DestAddr), TargetName]),
send_trap_pdus(T, ContextName, {TrapRec, Vbs},
- V1Res, V2Res, V3Res, Recv, NetIf)
+ V1Res, V2Res, V3Res, Recv,
+ LocalEngineID, NetIf)
end;
{discarded, Reason} ->
?vlog("mib view error ~p for"
@@ -697,10 +731,10 @@ send_trap_pdus([{DestAddr, TargetName, {MpModel, SecModel, SecName, SecLevel},
"~n SecName: ~w",
[Reason, element(2, DestAddr), SecName]),
send_trap_pdus(T, ContextName, {TrapRec, Vbs},
- V1Res, V2Res, V3Res, Recv, NetIf)
+ V1Res, V2Res, V3Res, Recv, LocalEngineID, NetIf)
end;
send_trap_pdus([], ContextName, {TrapRec, Vbs}, V1Res, V2Res, V3Res,
- Recv, NetIf) ->
+ Recv, LocalEngineID, NetIf) ->
SysUpTime = snmp_standard_mib:sys_up_time(),
?vdebug("send trap pdus with sysUpTime ~p", [SysUpTime]),
InformRecvs = get_inform_recvs(V2Res ++ V3Res),
@@ -708,7 +742,8 @@ send_trap_pdus([], ContextName, {TrapRec, Vbs}, V1Res, V2Res, V3Res,
deliver_recv(Recv, snmp_targets, InformTargets),
send_v1_trap(TrapRec, V1Res, Vbs, NetIf, SysUpTime),
send_v2_trap(TrapRec, V2Res, Vbs, Recv, NetIf, SysUpTime),
- send_v3_trap(TrapRec, V3Res, Vbs, Recv, NetIf, SysUpTime, ContextName).
+ send_v3_trap(TrapRec, V3Res, Vbs, Recv, LocalEngineID, NetIf,
+ SysUpTime, ContextName).
send_v1_trap(_TrapRec, [], _Vbs, _NetIf, _SysUpTime) ->
ok;
@@ -762,21 +797,25 @@ send_v2_trap(TrapRec, V2Res, Vbs, Recv, NetIf, SysUpTime) ->
do_send_v2_trap(TrapRecvs, IVbs, NetIf),
do_send_v2_inform(InformRecvs, IVbs, Recv, NetIf).
-send_v3_trap(_TrapRec, [], _Vbs, _Recv, _NetIf, _SysUpTime, _ContextName) ->
+send_v3_trap(_TrapRec, [], _Vbs, _Recv, _LocalEngineID,
+ _NetIf, _SysUpTime, _ContextName) ->
ok;
-send_v3_trap(TrapRec, V3Res, Vbs, Recv, NetIf, SysUpTime, ContextName) ->
+send_v3_trap(TrapRec, V3Res, Vbs, Recv, LocalEngineID,
+ NetIf, SysUpTime, ContextName) ->
?vdebug("prepare to send v3 trap",[]),
{_Oid, IVbs} = mk_v2_trap(TrapRec, Vbs, SysUpTime), % v2 refers to SMIv2;
- TrapRecvs = get_trap_recvs(V3Res), % same SMI for v3
+ TrapRecvs = get_trap_recvs(V3Res), % same SMI for v3
InformRecvs = get_inform_recvs(V3Res),
do_send_v3_trap(TrapRecvs, ContextName, IVbs, NetIf),
- do_send_v3_inform(InformRecvs, ContextName, IVbs, Recv, NetIf).
+ do_send_v3_inform(InformRecvs, ContextName, IVbs, Recv,
+ LocalEngineID, NetIf).
mk_v2_trap(#notification{oid = Oid}, Vbs, SysUpTime) ->
?vtrace("make v2 notification '~p'",[Oid]),
mk_v2_notif(Oid, Vbs, SysUpTime);
-mk_v2_trap(#trap{enterpriseoid = Enter, specificcode = Spec}, Vbs, SysUpTime) ->
+mk_v2_trap(#trap{enterpriseoid = Enter, specificcode = Spec},
+ Vbs, SysUpTime) ->
%% Use alg. in rfc1908 to map a v1 trap to a v2 trap
?vtrace("make v2 trap for '~p' with ~p",[Enter,Spec]),
{Oid,Enterp} =
@@ -845,16 +884,16 @@ do_send_v3_trap(Recvs, ContextName, Vbs, NetIf) ->
end, Recvs),
ok.
-do_send_v3_inform([], _ContextName, _Vbs, _Recv, _NetIf) ->
+do_send_v3_inform([], _ContextName, _Vbs, _Recv, _LocalEngineID, _NetIf) ->
ok;
-do_send_v3_inform(Recvs, ContextName, Vbs, Recv, NetIf) ->
+do_send_v3_inform(Recvs, ContextName, Vbs, Recv, LocalEngineID, NetIf) ->
lists:foreach(
fun({Addr, MsgData, Timeout, Retry}) ->
?vtrace("~n start inform sender to send v3 inform to ~p",
[Addr]),
proc_lib:spawn_link(?MODULE, init_v3_inform,
[{Addr, MsgData}, Timeout, Retry, Vbs,
- Recv, NetIf, ContextName,
+ Recv, LocalEngineID, NetIf, ContextName,
get(verbosity), get(sname)])
end,
Recvs).
@@ -874,7 +913,13 @@ init_v2_inform(Addr, Timeout, Retry, Vbs, Recv, NetIf, Community,V,S) ->
%% New process
-init_v3_inform(Addr, Timeout, Retry, Vbs, Recv, NetIf, ContextName,V,S) ->
+init_v3_inform(Addr, Timeout, Retry, Vbs, Recv, NetIf, ContextName, V, S) ->
+ LocalEngineID = ?DEFAULT_LOCAL_ENGINE_ID,
+ init_v3_inform(Addr, Timeout, Retry, Vbs, Recv, LocalEngineID,
+ NetIf, ContextName, V, S).
+
+init_v3_inform(Addr, Timeout, Retry, Vbs, Recv, LocalEngineID,
+ NetIf, ContextName, V, S) ->
%% Make a new Inform for each recipient; they need unique
%% request-ids!
put(verbosity,V),
@@ -882,7 +927,7 @@ init_v3_inform(Addr, Timeout, Retry, Vbs, Recv, NetIf, ContextName,V,S) ->
?vdebug("~n starting with timeout = ~p and retry = ~p",
[Timeout,Retry]),
InformPdu = make_v2_notif_pdu(Vbs, 'inform-request'), % Yes, v2
- ContextEngineId = snmp_framework_mib:get_engine_id(),
+ ContextEngineId = LocalEngineID,
Msg = {send_pdu_req, 'version-3', InformPdu,
{v3, ContextEngineId, ContextName}, [Addr], self()},
?MODULE:send_inform(Addr, Timeout*10, Retry, Msg, Recv, NetIf).
diff --git a/lib/snmp/src/agent/snmpa_usm.erl b/lib/snmp/src/agent/snmpa_usm.erl
index a8c395534f..ae584bb3c1 100644
--- a/lib/snmp/src/agent/snmpa_usm.erl
+++ b/lib/snmp/src/agent/snmpa_usm.erl
@@ -1,26 +1,26 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 1999-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 1999-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(snmpa_usm).
-export([
- process_incoming_msg/4,
- generate_outgoing_msg/5,
+ process_incoming_msg/4, process_incoming_msg/5,
+ generate_outgoing_msg/5, generate_outgoing_msg/6,
generate_discovery_msg/4, generate_discovery_msg/5,
current_statsNotInTimeWindows_vb/0
]).
@@ -33,6 +33,7 @@
-define(VMODULE,"A-USM").
-include("snmp_verbosity.hrl").
+-include("snmpa_internal.hrl").
%%-----------------------------------------------------------------
@@ -58,7 +59,11 @@
%%-----------------------------------------------------------------
process_incoming_msg(Packet, Data, SecParams, SecLevel) ->
- TermDiscoEnabled = is_terminating_discovery_enabled(),
+ LocalEngineID = ?DEFAULT_LOCAL_ENGINE_ID,
+ process_incoming_msg(Packet, Data, SecParams, SecLevel, LocalEngineID).
+
+process_incoming_msg(Packet, Data, SecParams, SecLevel, LocalEngineID) ->
+ TermDiscoEnabled = is_terminating_discovery_enabled(),
TermTriggerUsername = terminating_trigger_username(),
%% 3.2.1
?vtrace("process_incoming_msg -> check security parms: 3.2.1",[]),
@@ -124,7 +129,7 @@ process_incoming_msg(Packet, Data, SecParams, SecLevel) ->
"~n ~p",[UsmUser]),
DiscoOrPlain = authenticate_incoming(Packet,
UsmSecParams, UsmUser,
- SecLevel),
+ SecLevel, LocalEngineID),
%% 3.2.8
?vtrace("process_incoming_msg -> "
"decrypt scoped data: 3.2.8",[]),
@@ -166,7 +171,8 @@ process_discovery_msg(MsgAuthEngineID, Data, SecLevel) ->
end.
-authenticate_incoming(Packet, UsmSecParams, UsmUser, SecLevel) ->
+authenticate_incoming(Packet, UsmSecParams, UsmUser, SecLevel,
+ LocalEngineID) ->
%% 3.2.6
?vtrace("authenticate_incoming -> 3.2.6", []),
AuthProtocol = element(?usmUserAuthProtocol, UsmUser),
@@ -190,7 +196,8 @@ authenticate_incoming(Packet, UsmSecParams, UsmUser, SecLevel) ->
SecName,
MsgAuthEngineID,
MsgAuthEngineBoots,
- MsgAuthEngineTime) of
+ MsgAuthEngineTime,
+ LocalEngineID) of
discovery ->
discovery;
true ->
@@ -205,15 +212,15 @@ authenticate_incoming(Packet, UsmSecParams, UsmUser, SecLevel) ->
plain
end.
-authoritative(SecName, MsgAuthEngineBoots, MsgAuthEngineTime) ->
+authoritative(SecName, MsgAuthEngineBoots, MsgAuthEngineTime, LocalEngineID) ->
?vtrace("authoritative -> entry with"
"~n SecName: ~p"
"~n MsgAuthEngineBoots: ~p"
"~n MsgAuthEngineTime: ~p",
[SecName, MsgAuthEngineBoots, MsgAuthEngineTime]),
- SnmpEngineBoots = snmp_framework_mib:get_engine_boots(),
+ SnmpEngineBoots = get_local_engine_boots(LocalEngineID),
?vtrace("authoritative -> SnmpEngineBoots: ~p", [SnmpEngineBoots]),
- SnmpEngineTime = snmp_framework_mib:get_engine_time(),
+ SnmpEngineTime = get_local_engine_time(LocalEngineID),
?vtrace("authoritative -> SnmpEngineTime: ~p", [SnmpEngineTime]),
InTimeWindow =
if
@@ -320,11 +327,12 @@ non_authoritative(SecName,
end.
-is_auth(?usmNoAuthProtocol, _, _, _, SecName, _, _, _) -> % 3.2.5
+is_auth(?usmNoAuthProtocol, _, _, _, SecName, _, _, _, _) -> % 3.2.5
error(usmStatsUnsupportedSecLevels,
?usmStatsUnsupportedSecLevels_instance, SecName); % OTP-5464
is_auth(AuthProtocol, AuthKey, AuthParams, Packet, SecName,
- MsgAuthEngineID, MsgAuthEngineBoots, MsgAuthEngineTime) ->
+ MsgAuthEngineID, MsgAuthEngineBoots, MsgAuthEngineTime,
+ LocalEngineID) ->
TermDiscoEnabled = is_terminating_discovery_enabled(),
TermDiscoStage2 = terminating_discovery_stage2(),
IsAuth = auth_in(AuthProtocol, AuthKey, AuthParams, Packet),
@@ -334,7 +342,7 @@ is_auth(AuthProtocol, AuthKey, AuthParams, Packet, SecName,
%% 3.2.7
?vtrace("is_auth -> "
"retrieve EngineBoots and EngineTime: 3.2.7",[]),
- SnmpEngineID = snmp_framework_mib:get_engine_id(),
+ SnmpEngineID = LocalEngineID,
?vtrace("is_auth -> SnmpEngineID: ~p", [SnmpEngineID]),
case MsgAuthEngineID of
SnmpEngineID when ((MsgAuthEngineBoots =:= 0) andalso
@@ -351,12 +359,14 @@ is_auth(AuthProtocol, AuthKey, AuthParams, Packet, SecName,
%% This will *always* result in the manager *not*
%% beeing in timewindow
authoritative(SecName,
- MsgAuthEngineBoots, MsgAuthEngineTime);
+ MsgAuthEngineBoots, MsgAuthEngineTime,
+ LocalEngineID);
SnmpEngineID -> %% 3.2.7a
?vtrace("is_auth -> we are authoritative: 3.2.7a", []),
authoritative(SecName,
- MsgAuthEngineBoots, MsgAuthEngineTime);
+ MsgAuthEngineBoots, MsgAuthEngineTime,
+ LocalEngineID);
_ -> %% 3.2.7b - we're non-authoritative
?vtrace("is_auth -> we are non-authoritative: 3.2.7b",[]),
@@ -396,7 +406,9 @@ try_decrypt(?usmDESPrivProtocol,
case (catch des_decrypt(PrivKey, UsmSecParams, EncryptedPDU)) of
{ok, DecryptedData} ->
DecryptedData;
- _ ->
+ Error ->
+ ?vlog("try_decrypt -> failed DES decrypt"
+ "~n Error: ~p", [Error]),
error(usmStatsDecryptionErrors,
?usmStatsDecryptionErrors_instance, % OTP-5464
SecName)
@@ -406,7 +418,9 @@ try_decrypt(?usmAesCfb128Protocol,
case (catch aes_decrypt(PrivKey, UsmSecParams, EncryptedPDU)) of
{ok, DecryptedData} ->
DecryptedData;
- _ ->
+ Error ->
+ ?vlog("try_decrypt -> failed AES decrypt"
+ "~n Error: ~p", [Error]),
error(usmStatsDecryptionErrors,
?usmStatsDecryptionErrors_instance, % OTP-5464
SecName)
@@ -414,12 +428,19 @@ try_decrypt(?usmAesCfb128Protocol,
generate_outgoing_msg(Message, SecEngineID, SecName, SecData, SecLevel) ->
+ LocalEngineID = ?DEFAULT_LOCAL_ENGINE_ID,
+ generate_outgoing_msg(Message, SecEngineID, SecName, SecData, SecLevel,
+ LocalEngineID).
+
+generate_outgoing_msg(Message, SecEngineID, SecName, SecData, SecLevel,
+ LocalEngineID) ->
%% 3.1.1
?vtrace("generate_outgoing_msg -> [3.1.1] entry with"
- "~n SecEngineID: ~p"
- "~n SecName: ~p"
- "~n SecLevel: ~w",
- [SecEngineID, SecName, SecLevel]),
+ "~n SecEngineID: ~p"
+ "~n SecName: ~p"
+ "~n SecLevel: ~w"
+ "~n LocalEngineID: ~p",
+ [SecEngineID, SecName, SecLevel, LocalEngineID]),
{UserName, AuthProtocol, PrivProtocol, AuthKey, PrivKey} =
case SecData of
[] -> % 3.1.1b
@@ -435,7 +456,7 @@ generate_outgoing_msg(Message, SecEngineID, SecName, SecData, SecLevel) ->
element(?usmUserPrivKey, User)};
{_, Name,_,_,_,_,_,_,_,_,_,_,_, RowStatus,_,_} ->
?vdebug("generate_outgoing_msg -> "
- "found user ~p with wrong row status: ~p",
+ "found not active user ~p: ~p",
[Name, RowStatus]),
error(unknownSecurityName);
_ ->
@@ -456,7 +477,7 @@ generate_outgoing_msg(Message, SecEngineID, SecName, SecData, SecLevel) ->
ScopedPduBytes = Message#message.data,
{ScopedPduData, MsgPrivParams} =
encrypt(ScopedPduBytes, PrivProtocol, PrivKey, SecLevel),
- SnmpEngineID = snmp_framework_mib:get_engine_id(),
+ SnmpEngineID = LocalEngineID,
?vtrace("generate_outgoing_msg -> SnmpEngineID: ~p [3.1.6]",
[SnmpEngineID]),
%% 3.1.6
@@ -470,8 +491,8 @@ generate_outgoing_msg(Message, SecEngineID, SecName, SecData, SecLevel) ->
{get_engine_boots(SecEngineID),
get_engine_time(SecEngineID)};
_ ->
- {snmp_framework_mib:get_engine_boots(),
- snmp_framework_mib:get_engine_time()}
+ {get_local_engine_boots(SnmpEngineID),
+ get_local_engine_time(SnmpEngineID)}
end,
%% 3.1.5 - 3.1.7
?vtrace("generate_outgoing_msg -> [3.1.5 - 3.1.7]",[]),
@@ -556,11 +577,15 @@ encrypt(Data, PrivProtocol, PrivKey, SecLevel) ->
?vtrace("encrypt -> 3.1.4a",[]),
case (catch try_encrypt(PrivProtocol, PrivKey, Data)) of
{ok, ScopedPduData, MsgPrivParams} ->
- ?vtrace("encrypt -> encode tag",[]),
+ ?vtrace("encrypt -> encrypted - now encode tag",[]),
{snmp_pdus:enc_oct_str_tag(ScopedPduData), MsgPrivParams};
{error, Reason} ->
+ ?vtrace("encrypt -> error: "
+ "~n Reason: ~p", [Reason]),
error(Reason);
- _Error ->
+ Error ->
+ ?vtrace("encrypt -> other: "
+ "~n Error: ~p", [Error]),
error(encryptionError)
end
end.
@@ -673,6 +698,19 @@ current_statsNotInTimeWindows_vb() ->
value = get_counter(usmStatsNotInTimeWindows)}.
+
+%%-----------------------------------------------------------------
+%% Future profing...
+%%-----------------------------------------------------------------
+
+get_local_engine_boots(_LocalEngineID) ->
+ snmp_framework_mib:get_engine_boots().
+
+get_local_engine_time(_LocalEngineID) ->
+ snmp_framework_mib:get_engine_time().
+
+
+
%%-----------------------------------------------------------------
%% We cache the local values of all non-auth engines we know.
%% Keep the values in the snmp_agent_table.
diff --git a/lib/snmp/src/agent/snmpa_vacm.erl b/lib/snmp/src/agent/snmpa_vacm.erl
index 2eacea4301..d17ed73ab7 100644
--- a/lib/snmp/src/agent/snmpa_vacm.erl
+++ b/lib/snmp/src/agent/snmpa_vacm.erl
@@ -62,6 +62,13 @@ get_mib_view(ViewType, SecModel, SecName, SecLevel, ContextName) ->
%% Follows the procedure in rfc2275
auth(ViewType, SecModel, SecName, SecLevel, ContextName) ->
+ ?vtrace("auth -> entry with"
+ "~n ViewType: ~p"
+ "~n SecModel: ~p"
+ "~n SecName: ~p"
+ "~n SecLevel: ~p"
+ "~n ContextName: ~p",
+ [ViewType, SecModel, SecName, SecLevel, ContextName]),
% 3.2.1 - Check that the context is known to us
?vdebug("check that the context (~p) is known to us",[ContextName]),
case snmp_view_based_acm_mib:vacmContextTable(get, ContextName,
@@ -74,7 +81,7 @@ auth(ViewType, SecModel, SecName, SecLevel, ContextName) ->
end,
% 3.2.2 - Check that the SecModel and SecName is valid
?vdebug("check that SecModel (~p) and SecName (~p) is valid",
- [SecModel,SecName]),
+ [SecModel, SecName]),
GroupName =
case snmp_view_based_acm_mib:get(vacmSecurityToGroupTable,
[SecModel, length(SecName) | SecName],
@@ -111,6 +118,8 @@ check_auth(Res) -> {ok, Res}.
%% key in the table >= ViewIndex.
%%-----------------------------------------------------------------
get_mib_view(ViewName) ->
+ ?vtrace("get_mib_view -> entry with"
+ "~n ViewName: ~p", [ViewName]),
ViewKey = [length(ViewName) | ViewName],
case snmp_view_based_acm_mib:table_next(vacmViewTreeFamilyTable,
ViewKey) of
@@ -202,6 +211,13 @@ backup(BackupDir) ->
%% Ret: {ok, ViewName} | {error, Reason}
get_view_name(ViewType, GroupName, ContextName, SecModel, SecLevel) ->
+ ?vtrace("get_view_name -> entry with"
+ "~n ViewType: ~p"
+ "~n GroupName: ~p"
+ "~n ContextName: ~p"
+ "~n SecModel: ~p"
+ "~n SecLevel: ~p",
+ [ViewType, GroupName, ContextName, SecModel, SecLevel]),
GroupKey = [length(GroupName) | GroupName],
case get_access_row(GroupKey, ContextName, SecModel, SecLevel) of
undefined ->
diff --git a/lib/snmp/src/app/snmp.appup.src b/lib/snmp/src/app/snmp.appup.src
index 3abce3d759..17eef2c504 100644
--- a/lib/snmp/src/app/snmp.appup.src
+++ b/lib/snmp/src/app/snmp.appup.src
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1999-2009. All Rights Reserved.
+%% Copyright Ericsson AB 1999-2012. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
@@ -22,25 +22,133 @@
%% ----- U p g r a d e -------------------------------------------------------
[
- {"4.14",
+ {"4.17.3",
[
- {load_module, snmpm_user, soft_purge, soft_purge, []},
- {load_module, snmpm_user_default, soft_purge, soft_purge, [snmpm_user]},
- {update, snmpm_server, soft, soft_purge, soft_purge,
- [snmpm_user_default]}
+ {load_module, snmpa_mpd, soft_purge, soft_purge, []},
+ {update, snmpa_local_db, soft, soft_purge, soft_purge, []},
+ {update, snmpa_mib, soft, soft_purge, soft_purge, []},
+ {update, snmpa_agent, soft, soft_purge, soft_purge, []}
+ ]
+ },
+ {"4.17.2",
+ [
+ {load_module, snmpa, soft_purge, soft_purge, []},
+ {load_module, snmpa_mpd, soft_purge, soft_purge, []},
+ {load_module, snmp_target_mib, soft_purge, soft_purge, [snmpa_mib_lib]},
+ {load_module, snmpa_mib_lib, soft_purge, soft_purge, []},
+ {load_module, snmpa_trap, soft_purge, soft_purge, []},
+ {load_module, snmpa_vacm, soft_purge, soft_purge, []},
+ {update, snmpa_supervisor, soft, soft_purge, soft_purge, []},
+ {update, snmpa_local_db, soft, soft_purge, soft_purge, []},
+ {update, snmpa_mib, soft, soft_purge, soft_purge, []},
+ {update, snmpa_agent, soft, soft_purge, soft_purge, []}
+ ]
+ },
+ {"4.17.1",
+ [
+ {load_module, snmpa, soft_purge, soft_purge, []},
+ {load_module, snmpa_mpd, soft_purge, soft_purge, []},
+ {load_module, snmp_target_mib, soft_purge, soft_purge, [snmpa_mib_lib]},
+ {load_module, snmpa_mib_lib, soft_purge, soft_purge, []},
+ {load_module, snmpa_trap, soft_purge, soft_purge, []},
+ {load_module, snmpa_vacm, soft_purge, soft_purge, []},
+ {update, snmpa_supervisor, soft, soft_purge, soft_purge, []},
+ {update, snmpa_local_db, soft, soft_purge, soft_purge, []},
+ {update, snmpa_mib, soft, soft_purge, soft_purge, []},
+ {update, snmpa_agent, soft, soft_purge, soft_purge, []},
+ {load_module, snmpm, soft_purge, soft_purge, [snmpm_server]},
+ {update, snmpm_server, soft, soft_purge, soft_purge, []}
+ ]
+ },
+ {"4.17",
+ [
+ {load_module, snmpa, soft_purge, soft_purge, []},
+ {load_module, snmpa_mpd, soft_purge, soft_purge, []},
+ {load_module, snmp_target_mib, soft_purge, soft_purge, [snmpa_mib_lib]},
+ {load_module, snmpa_mib_lib, soft_purge, soft_purge, []},
+ {load_module, snmpa_trap, soft_purge, soft_purge, []},
+ {load_module, snmpa_vacm, soft_purge, soft_purge, []},
+ {load_module, snmpa_net_if, soft_purge, soft_purge, []},
+ {load_module, snmpm, soft_purge, soft_purge, [snmpm_server]},
+ {update, snmpm_server, soft, soft_purge, soft_purge, []},
+ {update, snmpa_supervisor, soft, soft_purge, soft_purge, []},
+ {update, snmpa_local_db, soft, soft_purge, soft_purge, []},
+ {update, snmpa_mib, soft, soft_purge, soft_purge, []},
+ {update, snmpa_agent, soft, soft_purge, soft_purge, []}
]
},
- {"4.13.5",
+ {"4.16.2",
[
- {load_module, snmpm_user, soft_purge, soft_purge, []},
- {load_module, snmpm_user_default, soft_purge, soft_purge, [snmpm_user]},
- {load_module, snmpa_mib_data, soft_purge, soft_purge, []},
- {update, snmpa_agent, soft, soft_purge, soft_purge, []},
- {update, snmpa_net_if, soft, soft_purge, soft_purge, []},
- {update, snmpm_config, soft, soft_purge, soft_purge, []},
- {update, snmpm_server, soft, soft_purge, soft_purge, [snmpm_user_default]},
- {add_module, snmpm_net_if_filter},
- {add_module, snmpm_network_interface_filter}
+ {load_module, snmp_target_mib, soft_purge, soft_purge, [snmpa_mib_lib]},
+ {load_module, snmpa_mib_lib, soft_purge, soft_purge, []},
+ {load_module, snmpa_trap, soft_purge, soft_purge, []},
+ {load_module, snmpa_vacm, soft_purge, soft_purge, []},
+
+ {load_module, snmp_log, soft_purge, soft_purge, []},
+ {load_module, snmpa, soft_purge, soft_purge, [snmpa_agent]},
+ {load_module, snmpa_mpd, soft_purge, soft_purge, [snmpa_usm]},
+ {load_module, snmpa_usm, soft_purge, soft_purge, []},
+ {update, snmpa_supervisor, soft, soft_purge, soft_purge, []},
+ {update, snmpa_local_db, soft, soft_purge, soft_purge, []},
+ {update, snmpa_mib, soft, soft_purge, soft_purge, []},
+ {update, snmpa_agent, soft, soft_purge, soft_purge, []},
+ {load_module, snmpa_net_if, soft_purge, soft_purge, []},
+
+ {load_module, snmpm, soft_purge, soft_purge, [snmpm_server]},
+ {load_module, snmpm_mpd, soft_purge, soft_purge, []},
+ {update, snmpm_server, soft, soft_purge, soft_purge, []}
+ ]
+ },
+ {"4.16.1",
+ [
+ {load_module, snmp_target_mib, soft_purge, soft_purge, [snmpa_mib_lib]},
+ {load_module, snmpa_mib_lib, soft_purge, soft_purge, []},
+ {load_module, snmpa_trap, soft_purge, soft_purge, []},
+ {load_module, snmpa_vacm, soft_purge, soft_purge, []},
+
+ {load_module, snmp_log, soft_purge, soft_purge, []},
+ {load_module, snmp_pdus, soft_purge, soft_purge, []},
+ {load_module, snmp_usm, soft_purge, soft_purge, []},
+
+ {load_module, snmpa, soft_purge, soft_purge, [snmpa_agent]},
+ {load_module, snmpa_mpd, soft_purge, soft_purge, [snmpa_usm]},
+ {load_module, snmpa_usm, soft_purge, soft_purge, [snmp_usm]},
+ {update, snmpa_local_db, soft, soft_purge, soft_purge, []},
+ {update, snmpa_mib, soft, soft_purge, soft_purge, []},
+ {update, snmpa_supervisor, soft, soft_purge, soft_purge, []},
+ {update, snmpa_agent, soft, soft_purge, soft_purge, [snmpa_mib]},
+ {load_module, snmpa_net_if, soft_purge, soft_purge, []},
+
+ {load_module, snmpm, soft_purge, soft_purge, [snmpm_server]},
+ {load_module, snmpm_mpd, soft_purge, soft_purge, []},
+ {update, snmpm_server, soft, soft_purge, soft_purge, []}
+ ]
+ },
+ {"4.16",
+ [
+ {load_module, snmp_target_mib, soft_purge, soft_purge, [snmpa_mib_lib]},
+ {load_module, snmpa_mib_lib, soft_purge, soft_purge, []},
+ {load_module, snmpa_trap, soft_purge, soft_purge, []},
+ {load_module, snmpa_vacm, soft_purge, soft_purge, []},
+
+ {load_module, snmp_log, soft_purge, soft_purge, []},
+ {load_module, snmp_pdus, soft_purge, soft_purge, []},
+ {load_module, snmp_usm, soft_purge, soft_purge, []},
+
+ {load_module, snmpa, soft_purge, soft_purge, [snmpa_agent]},
+ {load_module, snmpa_general_db, soft_purge, soft_purge, []},
+ {load_module, snmpa_mpd, soft_purge, soft_purge, [snmpa_usm]},
+ {load_module, snmpa_usm, soft_purge, soft_purge, [snmp_usm]},
+ {update, snmpa_local_db, soft, soft_purge, soft_purge, []},
+ {update, snmpa_mib, soft, soft_purge, soft_purge, []},
+ {update, snmpa_supervisor, soft, soft_purge, soft_purge, []},
+ {update, snmpa_agent, soft, soft_purge, soft_purge, [snmpa_mib]},
+ {load_module, snmpa_net_if, soft_purge, soft_purge, []},
+
+ {load_module, snmpm, soft_purge, soft_purge, [snmpm_server]},
+ {load_module, snmpm_mpd, soft_purge, soft_purge, []},
+ {update, snmpm_net_if, soft, soft_purge, soft_purge, []},
+ {update, snmpm_server, soft, soft_purge, soft_purge, []}
]
}
],
@@ -48,24 +156,134 @@
%% ------D o w n g r a d e ---------------------------------------------------
[
- {"4.14",
+ {"4.17.3",
[
- {load_module, snmpm_user, soft_purge, soft_purge, []},
- {load_module, snmpm_user_default, soft_purge, soft_purge, [snmpm_user]},
- {update, snmpm_server, soft, soft_purge, soft_purge, [snmpm_user_default]}
+ {load_module, snmpa_mpd, soft_purge, soft_purge, []},
+ {update, snmpa_local_db, soft, soft_purge, soft_purge, []},
+ {update, snmpa_mib, soft, soft_purge, soft_purge, []},
+ {update, snmpa_agent, soft, soft_purge, soft_purge, []}
+ ]
+ },
+ {"4.17.2",
+ [
+ {load_module, snmpa, soft_purge, soft_purge, []},
+ {load_module, snmpa_mpd, soft_purge, soft_purge, []},
+ {load_module, snmp_target_mib, soft_purge, soft_purge, [snmpa_mib_lib]},
+ {load_module, snmpa_mib_lib, soft_purge, soft_purge, []},
+ {load_module, snmpa_trap, soft_purge, soft_purge, []},
+ {load_module, snmpa_vacm, soft_purge, soft_purge, []},
+ {update, snmpa_supervisor, soft, soft_purge, soft_purge, []},
+ {update, snmpa_local_db, soft, soft_purge, soft_purge, []},
+ {update, snmpa_mib, soft, soft_purge, soft_purge, []},
+ {update, snmpa_agent, soft, soft_purge, soft_purge, []}
+ ]
+ },
+ {"4.17.1",
+ [
+ {load_module, snmpa, soft_purge, soft_purge, []},
+ {load_module, snmpa_mpd, soft_purge, soft_purge, []},
+ {load_module, snmp_target_mib, soft_purge, soft_purge, [snmpa_mib_lib]},
+ {load_module, snmpa_mib_lib, soft_purge, soft_purge, []},
+ {load_module, snmpa_trap, soft_purge, soft_purge, []},
+ {load_module, snmpa_vacm, soft_purge, soft_purge, []},
+ {update, snmpa_supervisor, soft, soft_purge, soft_purge, []},
+ {update, snmpa_local_db, soft, soft_purge, soft_purge, []},
+ {update, snmpa_mib, soft, soft_purge, soft_purge, []},
+ {update, snmpa_agent, soft, soft_purge, soft_purge, []},
+ {load_module, snmpm, soft_purge, soft_purge, [snmpm_server]},
+ {update, snmpm_server, soft, soft_purge, soft_purge, []}
+ ]
+ },
+ {"4.17",
+ [
+ {load_module, snmpa, soft_purge, soft_purge, []},
+ {load_module, snmpa_mpd, soft_purge, soft_purge, []},
+ {load_module, snmp_target_mib, soft_purge, soft_purge, [snmpa_mib_lib]},
+ {load_module, snmpa_mib_lib, soft_purge, soft_purge, []},
+ {load_module, snmpa_trap, soft_purge, soft_purge, []},
+ {load_module, snmpa_vacm, soft_purge, soft_purge, []},
+ {update, snmpa_supervisor, soft, soft_purge, soft_purge, []},
+ {update, snmpa_local_db, soft, soft_purge, soft_purge, []},
+ {update, snmpa_mib, soft, soft_purge, soft_purge, []},
+ {update, snmpa_agent, soft, soft_purge, soft_purge, []},
+ {load_module, snmpa_net_if, soft_purge, soft_purge, []},
+ {load_module, snmpm, soft_purge, soft_purge, [snmpm_server]},
+ {update, snmpm_server, soft, soft_purge, soft_purge, []}
+ ]
+ },
+ {"4.16.2",
+ [
+ {load_module, snmp_target_mib, soft_purge, soft_purge, [snmpa_mib_lib]},
+ {load_module, snmpa_mib_lib, soft_purge, soft_purge, []},
+ {load_module, snmpa_trap, soft_purge, soft_purge, []},
+ {load_module, snmpa_vacm, soft_purge, soft_purge, []},
+
+ {load_module, snmp_log, soft_purge, soft_purge, []},
+
+ {load_module, snmpa, soft_purge, soft_purge, [snmpa_agent]},
+ {load_module, snmpa_mpd, soft_purge, soft_purge, [snmpa_usm]},
+ {load_module, snmpa_usm, soft_purge, soft_purge, []},
+ {update, snmpa_supervisor, soft, soft_purge, soft_purge, []},
+ {update, snmpa_local_db, soft, soft_purge, soft_purge, []},
+ {update, snmpa_mib, soft, soft_purge, soft_purge, []},
+ {update, snmpa_agent, soft, soft_purge, soft_purge, []},
+ {load_module, snmpa_net_if, soft_purge, soft_purge, []},
+
+ {load_module, snmpm, soft_purge, soft_purge, [snmpm_server]},
+ {load_module, snmpm_mpd, soft_purge, soft_purge, []},
+ {update, snmpm_server, soft, soft_purge, soft_purge, []}
+ ]
+ },
+ {"4.16.1",
+ [
+ {load_module, snmp_target_mib, soft_purge, soft_purge, [snmpa_mib_lib]},
+ {load_module, snmpa_mib_lib, soft_purge, soft_purge, []},
+ {load_module, snmpa_trap, soft_purge, soft_purge, []},
+ {load_module, snmpa_vacm, soft_purge, soft_purge, []},
+
+ {load_module, snmp_log, soft_purge, soft_purge, []},
+ {load_module, snmp_pdus, soft_purge, soft_purge, []},
+ {load_module, snmp_usm, soft_purge, soft_purge, []},
+
+ {load_module, snmpa, soft_purge, soft_purge, [snmpa_agent]},
+ {load_module, snmpa_mpd, soft_purge, soft_purge, [snmpa_usm]},
+ {load_module, snmpa_usm, soft_purge, soft_purge, [snmp_usm]},
+ {update, snmpa_local_db, soft, soft_purge, soft_purge, []},
+ {update, snmpa_mib, soft, soft_purge, soft_purge, []},
+ {update, snmpa_supervisor, soft, soft_purge, soft_purge, []},
+ {update, snmpa_agent, soft, soft_purge, soft_purge, [snmpa_mib]},
+ {load_module, snmpa_net_if, soft_purge, soft_purge, []},
+
+ {load_module, snmpm, soft_purge, soft_purge, [snmpm_server]},
+ {load_module, snmpm_mpd, soft_purge, soft_purge, []},
+ {update, snmpm_server, soft, soft_purge, soft_purge, []}
]
},
- {"4.13.5",
+ {"4.16",
[
- {load_module, snmpm_user, soft_purge, soft_purge, []},
- {load_module, snmpm_user_default, soft_purge, soft_purge, [snmpm_user]},
- {load_module, snmpa_mib_data, soft_purge, soft_purge, []},
- {update, snmpa_agent, soft, soft_purge, soft_purge, []},
- {update, snmpa_net_if, soft, soft_purge, soft_purge, []},
- {update, snmpm_config, soft, soft_purge, soft_purge, []},
- {update, snmpm_server, soft, soft_purge, soft_purge, [snmpm_user_default]},
- {remove, {snmpm_net_if_filter, soft_purge, brutal_purge}},
- {remove, {snmpm_network_interface_filter, soft_purge, brutal_purge}}
+ {load_module, snmp_target_mib, soft_purge, soft_purge, [snmpa_mib_lib]},
+ {load_module, snmpa_mib_lib, soft_purge, soft_purge, []},
+ {load_module, snmpa_trap, soft_purge, soft_purge, []},
+ {load_module, snmpa_vacm, soft_purge, soft_purge, []},
+
+ {load_module, snmp_log, soft_purge, soft_purge, []},
+ {load_module, snmp_pdus, soft_purge, soft_purge, []},
+ {load_module, snmp_usm, soft_purge, soft_purge, []},
+
+ {load_module, snmpa, soft_purge, soft_purge, [snmpa_agent]},
+ {load_module, snmpa_general_db, soft_purge, soft_purge, []},
+ {load_module, snmpa_mpd, soft_purge, soft_purge, [snmpa_usm]},
+ {load_module, snmpa_usm, soft_purge, soft_purge, [snmp_usm]},
+ {update, snmpa_local_db, soft, soft_purge, soft_purge, []},
+ {update, snmpa_mib, soft, soft_purge, soft_purge, []},
+ {update, snmpa_supervisor, soft, soft_purge, soft_purge, []},
+ {update, snmpa_agent, soft, soft_purge, soft_purge, [snmpa_mib]},
+ {load_module, snmpa_net_if, soft_purge, soft_purge, []},
+
+ {load_module, snmpm, soft_purge, soft_purge, [snmpm_server]},
+ {load_module, snmpm_mpd, soft_purge, soft_purge, []},
+ {update, snmpm_net_if, soft, soft_purge, soft_purge, []},
+ {update, snmpm_server, soft, soft_purge, soft_purge, []}
]
}
]
diff --git a/lib/snmp/src/compile/snmpc.erl b/lib/snmp/src/compile/snmpc.erl
index 8a1f15d4a4..a7f2cdc2bc 100644
--- a/lib/snmp/src/compile/snmpc.erl
+++ b/lib/snmp/src/compile/snmpc.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(snmpc).
@@ -34,6 +34,7 @@
-include("snmpc.hrl").
-include("snmpc_lib.hrl").
+-record(dldata, {deprecated, relaxed_row_name_assign_check}).
look_at(Mib) ->
io:format("~p ~n", [snmpc_lib:look_at(Mib)]).
@@ -114,6 +115,7 @@ compile(FileName) ->
%% module_identity
%% {module, string()}
%% no_defs
+%% relaxed_row_name_assign_check
%% (hidden) {verbosity, trace|debug|log|info|silence} silence
%% (hidden) version
%% (hidden) options
@@ -201,6 +203,8 @@ get_options([imports|Opts], Formats, Args) ->
get_options(Opts, ["~n imports"|Formats], Args);
get_options([module_identity|Opts], Formats, Args) ->
get_options(Opts, ["~n module_identity"|Formats], Args);
+get_options([relaxed_row_name_assign_check|Opts], Formats, Args) ->
+ get_options(Opts, ["~n relaxed_row_name_assign_check"|Formats], Args);
get_options([_|Opts], Formats, Args) ->
get_options(Opts, Formats, Args).
@@ -284,6 +288,8 @@ check_options([imports| T]) ->
check_options(T);
check_options([module_identity| T]) ->
check_options(T);
+check_options([relaxed_row_name_assign_check| T]) ->
+ check_options(T);
check_options([{module, M} | T]) when is_atom(M) ->
check_options(T);
check_options([no_defs| T]) ->
@@ -309,6 +315,9 @@ get_description(Options) ->
get_reference(Options) ->
get_bool_option(reference, Options).
+get_relaxed_row_name_assign_check(Options) ->
+ lists:member(relaxed_row_name_assign_check, Options).
+
get_bool_option(Option, Options) ->
case lists:member(Option, Options) of
false ->
@@ -406,8 +415,12 @@ compile_parsed_data(#pdata{mib_name = MibName,
defs = Definitions}) ->
snmpc_lib:import(Imports),
update_imports(Imports),
- Deprecated = get_deprecated(get(options)),
- definitions_loop(Definitions, Deprecated),
+ Opts = get(options),
+ Deprecated = get_deprecated(Opts),
+ RelChk = get_relaxed_row_name_assign_check(Opts),
+ Data = #dldata{deprecated = Deprecated,
+ relaxed_row_name_assign_check = RelChk},
+ definitions_loop(Definitions, Data),
MibName.
update_imports(Imports) ->
@@ -436,21 +449,21 @@ update_status(Name, Status) ->
%% A deprecated object
definitions_loop([{#mc_object_type{name = ObjName, status = deprecated},
Line}|T],
- false) ->
+ #dldata{deprecated = false} = Data) ->
%% May be implemented but the compiler chooses not to.
?vinfo2("object_type ~w is deprecated => ignored", [ObjName], Line),
update_status(ObjName, deprecated),
- definitions_loop(T, false);
+ definitions_loop(T, Data);
%% A obsolete object
definitions_loop([{#mc_object_type{name = ObjName, status = obsolete},
Line}|T],
- Deprecated) ->
+ Data) ->
?vlog2("object_type ~w is obsolete => ignored", [ObjName], Line),
%% No need to implement a obsolete object
update_status(ObjName, obsolete),
ensure_macro_imported('OBJECT-TYPE', Line),
- definitions_loop(T, Deprecated);
+ definitions_loop(T, Data);
%% Defining a table
definitions_loop([{#mc_object_type{name = NameOfTable,
@@ -475,7 +488,7 @@ definitions_loop([{#mc_object_type{name = NameOfTable,
{#mc_sequence{name = SeqName,
fields = FieldList},
Sline}|ColsEtc],
- Deprecated) ->
+ Data) ->
?vlog("defloop -> "
"[object_type(sequence_of),object_type(type,[1]),sequence]:"
"~n NameOfTable: ~p"
@@ -529,7 +542,89 @@ definitions_loop([{#mc_object_type{name = NameOfTable,
TableME#me{assocList=[{table_info,
TableInfo} | make_reference(Ref)]} |
ColMEs]),
- definitions_loop(RestObjs, Deprecated);
+ definitions_loop(RestObjs, Data);
+
+definitions_loop([{#mc_object_type{name = NameOfTable,
+ syntax = {{sequence_of, SeqName}, _},
+ max_access = Taccess,
+ kind = Kind,
+ status = Tstatus,
+ description = Desc1,
+ units = Tunits,
+ reference = Ref,
+ name_assign = Tindex},
+ Tline},
+ {#mc_object_type{name = NameOfEntry,
+ syntax = {{type, SeqName}, TEline},
+ max_access = 'not-accessible',
+ kind = {table_entry, IndexingInfo},
+ status = Estatus,
+ description = Desc2,
+ units = Eunits,
+ name_assign = {NameOfTable,[Idx]} = BadOID},
+ Eline},
+ {#mc_sequence{name = SeqName,
+ fields = FieldList},
+ Sline}|ColsEtc],
+ #dldata{relaxed_row_name_assign_check = true} = Data)
+ when is_integer(Idx) andalso (Idx > 1) ->
+ ?vlog("defloop -> "
+ "[object_type(sequence_of),object_type(type,[~w]),sequence]:"
+ "~n NameOfTable: ~p"
+ "~n SeqName: ~p"
+ "~n Taccess: ~p"
+ "~n Kind: ~p"
+ "~n Tstatus: ~p"
+ "~n Tindex: ~p"
+ "~n Tunits: ~p"
+ "~n Tline: ~p"
+ "~n NameOfEntry: ~p"
+ "~n TEline: ~p"
+ "~n IndexingInfo: ~p"
+ "~n Estatus: ~p"
+ "~n Eunits: ~p"
+ "~n Ref: ~p"
+ "~n Eline: ~p"
+ "~n FieldList: ~p"
+ "~n Sline: ~p",
+ [Idx,
+ NameOfTable,SeqName,Taccess,Kind,Tstatus,
+ Tindex,Tunits,Tline,
+ NameOfEntry,TEline,IndexingInfo,Estatus,Eunits,Ref,Eline,
+ FieldList,Sline]),
+ update_status(NameOfTable, Tstatus),
+ update_status(NameOfEntry, Estatus),
+ update_status(SeqName, undefined),
+ ensure_macro_imported('OBJECT-TYPE', Tline),
+ ?vwarning2("Bad TableEntry OID definition (~w)",
+ [BadOID], Eline),
+ test_table(NameOfTable,Taccess,Kind,Tindex,Tline),
+ {Tfather,Tsubindex} = Tindex,
+ snmpc_lib:register_oid(Tline,NameOfTable,Tfather,Tsubindex),
+ Description1 = make_description(Desc1),
+ TableME = #me{aliasname = NameOfTable,
+ entrytype = table,
+ access = 'not-accessible',
+ description = Description1,
+ units = Tunits},
+ snmpc_lib:register_oid(TEline,NameOfEntry,NameOfTable,[Idx]),
+ Description2 = make_description(Desc2),
+ TableEntryME = #me{aliasname = NameOfEntry,
+ entrytype = table_entry,
+ assocList = [{table_entry_with_sequence, SeqName}],
+ access = 'not-accessible',
+ description = Description2,
+ units = Eunits},
+ {ColMEs, RestObjs} =
+ define_cols(ColsEtc, 1, FieldList, NameOfEntry, NameOfTable, []),
+ TableInfo = snmpc_lib:make_table_info(Eline, NameOfTable,
+ IndexingInfo, ColMEs),
+ snmpc_lib:add_cdata(#cdata.mes,
+ [TableEntryME,
+ TableME#me{assocList=[{table_info,
+ TableInfo} | make_reference(Ref)]} |
+ ColMEs]),
+ definitions_loop(RestObjs, Data);
definitions_loop([{#mc_object_type{name = NameOfTable,
syntax = {{sequence_of, SeqName},_},
@@ -550,7 +645,7 @@ definitions_loop([{#mc_object_type{name = NameOfTable,
name_assign = BadOID}, Eline},
{#mc_sequence{name = SeqName,
fields = FieldList}, Sline}|ColsEtc],
- Deprecated) ->
+ Data) ->
?vlog("defloop -> "
"[object_type(sequence_of),object_type(type),sequence(fieldList)]:"
"~n NameOfTable: ~p"
@@ -605,13 +700,13 @@ definitions_loop([{#mc_object_type{name = NameOfTable,
TableME#me{assocList=[{table_info,
TableInfo} | make_reference(Ref)]} |
ColMEs]),
- definitions_loop(RestObjs, Deprecated);
+ definitions_loop(RestObjs, Data);
definitions_loop([{#mc_new_type{name = NewTypeName,
macro = Macro,
syntax = OldType,
display_hint = DisplayHint},Line}|T],
- Deprecated) ->
+ Data) ->
?vlog2("defloop -> new_type:"
"~n Macro: ~p"
"~n NewTypeName: ~p"
@@ -632,7 +727,7 @@ definitions_loop([{#mc_new_type{name = NewTypeName,
imported = false,
display_hint = DisplayHint}])
end,
- definitions_loop(T, Deprecated);
+ definitions_loop(T, Data);
%% Plain variable
definitions_loop([{#mc_object_type{name = NewVarName,
@@ -643,7 +738,7 @@ definitions_loop([{#mc_object_type{name = NewVarName,
description = Desc1,
units = Units,
name_assign = {Parent,SubIndex}},Line} |T],
- Deprecated) ->
+ Data) ->
?vlog2("defloop -> object_type (variable):"
"~n NewVarName: ~p"
"~n Type: ~p"
@@ -672,7 +767,7 @@ definitions_loop([{#mc_object_type{name = NewVarName,
VI = snmpc_lib:make_variable_info(NewME2),
snmpc_lib:add_cdata(#cdata.mes,
[NewME2#me{assocList = [{variable_info, VI}]}]),
- definitions_loop(T, Deprecated);
+ definitions_loop(T, Data);
definitions_loop([{#mc_module_identity{name = NewVarName,
last_updated = LU,
@@ -682,7 +777,7 @@ definitions_loop([{#mc_module_identity{name = NewVarName,
revisions = Revs0,
name_assign = {Parent, SubIndex}},
Line}|T],
- Deprecated) ->
+ Data) ->
?vlog2("defloop -> module-identity: "
"~n NewVarName: ~p"
"~n LU: ~p"
@@ -706,13 +801,13 @@ definitions_loop([{#mc_module_identity{name = NewVarName,
snmpc_lib:add_cdata(
#cdata.mes,
[snmpc_lib:makeInternalNode2(false, NewVarName)]),
- definitions_loop(T, Deprecated);
+ definitions_loop(T, Data);
definitions_loop([{#mc_internal{name = NewVarName,
macro = Macro,
parent = Parent,
sub_index = SubIndex},Line}|T],
- Deprecated) ->
+ Data) ->
?vlog2("defloop -> internal:"
"~n NewVarName: ~p"
"~n Macro: ~p"
@@ -724,7 +819,7 @@ definitions_loop([{#mc_internal{name = NewVarName,
snmpc_lib:add_cdata(
#cdata.mes,
[snmpc_lib:makeInternalNode2(false, NewVarName)]),
- definitions_loop(T, Deprecated);
+ definitions_loop(T, Data);
%% A trap message
definitions_loop([{#mc_trap{name = TrapName,
@@ -732,7 +827,7 @@ definitions_loop([{#mc_trap{name = TrapName,
vars = Variables,
description = Desc1,
num = SpecificCode}, Line}|T],
- Deprecated) ->
+ Data) ->
?vlog2("defloop -> trap:"
"~n TrapName: ~p"
"~n EnterPrise: ~p"
@@ -755,7 +850,7 @@ definitions_loop([{#mc_trap{name = TrapName,
lists:foreach(fun(Trap2) -> snmpc_lib:check_trap(Trap2, Trap, Line) end,
CDATA#cdata.traps),
snmpc_lib:add_cdata(#cdata.traps, [Trap]),
- definitions_loop(T, Deprecated);
+ definitions_loop(T, Data);
definitions_loop([{#mc_object_type{name = NameOfEntry,
syntax = Type,
@@ -763,7 +858,7 @@ definitions_loop([{#mc_object_type{name = NameOfEntry,
kind = {table_entry, Index},
status = Estatus,
name_assign = SubIndex},Eline}|T],
- Deprecated) ->
+ Data) ->
?vlog("defloop -> object_type (table_entry):"
"~n NameOfEntry: ~p"
"~n Type: ~p"
@@ -777,7 +872,7 @@ definitions_loop([{#mc_object_type{name = NameOfEntry,
update_status(NameOfEntry, Estatus),
snmpc_lib:print_error("Misplaced TableEntry definition (~w)",
[NameOfEntry], Eline),
- definitions_loop(T, Deprecated);
+ definitions_loop(T, Data);
definitions_loop([{#mc_notification{name = TrapName,
status = deprecated}, Line}|T],
@@ -790,19 +885,19 @@ definitions_loop([{#mc_notification{name = TrapName,
definitions_loop([{#mc_notification{name = TrapName,
status = obsolete}, Line}|T],
- Deprecated) ->
+ Data) ->
?vlog2("defloop -> notification ~w is obsolete => ignored",
[TrapName], Line),
update_status(TrapName, obsolete),
ensure_macro_imported('NOTIFICATION-TYPE', Line),
- definitions_loop(T, Deprecated);
+ definitions_loop(T, Data);
definitions_loop([{#mc_notification{name = TrapName,
vars = Variables,
status = Status,
description = Desc,
name_assign = {Parent, SubIndex}},Line}|T],
- Deprecated) ->
+ Data) ->
?vlog2("defloop -> notification:"
"~n TrapName: ~p"
"~n Variables: ~p"
@@ -824,13 +919,13 @@ definitions_loop([{#mc_notification{name = TrapName,
oidobjects = Variables},
snmpc_lib:check_notification(Notif, Line, CDATA#cdata.traps),
snmpc_lib:add_cdata(#cdata.traps, [Notif]),
- definitions_loop(T, Deprecated);
+ definitions_loop(T, Data);
-definitions_loop([{#mc_module_compliance{name = Name},Line}|T], Deprecated) ->
+definitions_loop([{#mc_module_compliance{name = Name},Line}|T], Data) ->
?vlog2("defloop -> module_compliance:"
"~n Name: ~p", [Name], Line),
ensure_macro_imported('MODULE-COMPLIANCE', Line),
- definitions_loop(T, Deprecated);
+ definitions_loop(T, Data);
definitions_loop([{#mc_object_group{name = Name,
objects = GroupObjects,
@@ -838,7 +933,7 @@ definitions_loop([{#mc_object_group{name = Name,
description = Desc,
reference = Ref,
name_assign = {Parent,SubIndex}}, Line}|T],
- Deprecated) ->
+ Data) ->
?vlog2("defloop -> object_group ~p:"
"~n GroupObjects: ~p"
"~n Status: ~p"
@@ -873,7 +968,7 @@ definitions_loop([{#mc_object_group{name = Name,
{objects, GroupObjects}]},
snmpc_lib:add_cdata(#cdata.mes, [NewME]),
- definitions_loop(T, Deprecated);
+ definitions_loop(T, Data);
definitions_loop([{#mc_notification_group{name = Name,
objects = GroupObjects,
@@ -882,7 +977,7 @@ definitions_loop([{#mc_notification_group{name = Name,
reference = Ref,
name_assign = {Parent,SubIndex}},
Line}
- |T], Deprecated) ->
+ |T], Data) ->
?vlog2("defloop -> notification_group ~p:"
"~n GroupObjects: ~p"
"~n Status: ~p"
@@ -918,13 +1013,13 @@ definitions_loop([{#mc_notification_group{name = Name,
{objects, GroupObjects}]},
snmpc_lib:add_cdata(#cdata.mes, [NewME]),
- definitions_loop(T, Deprecated);
+ definitions_loop(T, Data);
definitions_loop([{#mc_object_type{name = NameOfTable,
syntax = {{sequence_of, SeqName},_},
status = Tstatus},Tline},
Entry, Seq|T],
- Deprecated) ->
+ Data) ->
?vlog("defloop -> object_type (sequence_of): "
"~n NameOfTable: ~p"
"~n SeqName: ~p"
@@ -956,12 +1051,12 @@ definitions_loop([{#mc_object_type{name = NameOfTable,
"Invalid TableEntry '~p' (check STATUS, Sequence name, Oid)",
[safe_elem(1,safe_elem(2,Entry))],Tline)
end,
- definitions_loop(T, Deprecated);
+ definitions_loop(T, Data);
definitions_loop([{#mc_object_type{name = NameOfTable,
syntax = {{sequence_of, SeqName},_},
status = Tstatus},Tline}|T],
- Deprecated) ->
+ Data) ->
?vlog("defloop -> object_type (sequence_of):"
"~n object_type: ~p"
"~n sequence_of: ~p"
@@ -969,24 +1064,24 @@ definitions_loop([{#mc_object_type{name = NameOfTable,
update_status(NameOfTable, Tstatus),
snmpc_lib:print_error("Invalid statements following table ~p.",
[NameOfTable],Tline),
- definitions_loop(T, Deprecated);
+ definitions_loop(T, Data);
definitions_loop([{#mc_sequence{name = SeqName,
fields = _FieldList},Line}|T],
- Deprecated) ->
+ Data) ->
?vwarning2("Unexpected SEQUENCE ~w => ignoring", [SeqName], Line),
- definitions_loop(T, Deprecated);
+ definitions_loop(T, Data);
-definitions_loop([{Obj,Line}|T], Deprecated) ->
+definitions_loop([{Obj,Line}|T], Data) ->
?vinfo2("defloop -> unknown error"
"~n Obj: ~p", [Obj], Line),
snmpc_lib:print_error("Unknown Error in MIB. "
"Can't describe the error better than this: ~999p ignored."
" Please send a trouble report to [email protected].",
[Obj], Line),
- definitions_loop(T, Deprecated);
+ definitions_loop(T, Data);
-definitions_loop([], _Deprecated) ->
+definitions_loop([], _Data) ->
?vlog("defloop -> done", []),
ok.
diff --git a/lib/snmp/src/compile/snmpc_lib.erl b/lib/snmp/src/compile/snmpc_lib.erl
index b7e84e7d6b..4e5bc69f81 100644
--- a/lib/snmp/src/compile/snmpc_lib.erl
+++ b/lib/snmp/src/compile/snmpc_lib.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%
%%
@@ -125,7 +125,8 @@ test_kibbles(Kibbles,Line) ->
test_kibbles2([],_,_) ->
ok;
-test_kibbles2([{_KibbleName,BitNo}|Ks],BitNo,Line) ->
+test_kibbles2([{_KibbleName,BitNo}|Ks],ExpectBitNo,Line)
+ when BitNo >= ExpectBitNo ->
test_kibbles2(Ks,BitNo+1,Line);
test_kibbles2([{_KibbleName,BitNo}|_Ks],ExpectBitNo,Line) ->
print_error("Expected kibble no ~p but got ~p.",[ExpectBitNo,BitNo],Line).
diff --git a/lib/snmp/src/manager/snmpm.erl b/lib/snmp/src/manager/snmpm.erl
index 141addf440..7e801ebc40 100644
--- a/lib/snmp/src/manager/snmpm.erl
+++ b/lib/snmp/src/manager/snmpm.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2004-2009. All Rights Reserved.
+%% Copyright Ericsson AB 2004-2011. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
@@ -471,150 +471,70 @@ which_usm_users(EngineID) when is_list(EngineID) ->
%%
sync_get(UserId, TargetName, Oids) ->
-%% p("sync_get -> entry with"
-%% "~n UserId: ~p"
-%% "~n TargetName: ~p"
-%% "~n Oids: ~p", [UserId, TargetName, Oids]),
sync_get(UserId, TargetName, ?DEFAULT_CONTEXT, Oids).
-sync_get(UserId, TargetName, Context, Oids) when is_list(Oids) ->
-%% p("sync_get -> entry with"
-%% "~n UserId: ~p"
-%% "~n TargetName: ~p"
-%% "~n Context: ~p"
-%% "~n Oids: ~p", [UserId, TargetName, Context, Oids]),
- snmpm_server:sync_get(UserId, TargetName, Context, Oids);
-
+sync_get(UserId, TargetName, {community, Community}, Oids)
+ when is_list(Oids) ->
+ CC = {?DEFAULT_CONTEXT, Community},
+ snmpm_server:sync_get(UserId, TargetName, CC, Oids);
+sync_get(UserId, TargetName, CC, Oids) when is_list(Oids) ->
+ snmpm_server:sync_get(UserId, TargetName, CC, Oids);
sync_get(UserId, TargetName, Oids, Timeout) when is_integer(Timeout) ->
-%% p("sync_get -> entry with"
-%% "~n UserId: ~p"
-%% "~n TargetName: ~p"
-%% "~n Oids: ~p"
-%% "~n Timeout: ~p", [UserId, TargetName, Oids, Timeout]),
sync_get(UserId, TargetName, ?DEFAULT_CONTEXT, Oids, Timeout).
-sync_get(UserId, TargetName, Context, Oids, Timeout) ->
-%% p("sync_get -> entry with"
-%% "~n UserId: ~p"
-%% "~n TargetName: ~p"
-%% "~n Context: ~p"
-%% "~n Oids: ~p"
-%% "~n Timeout: ~p", [UserId, TargetName, Context, Oids, Timeout]),
- snmpm_server:sync_get(UserId, TargetName, Context, Oids, Timeout).
+sync_get(UserId, TargetName, {community, Community}, Oids, Timeout) ->
+ CC = {?DEFAULT_CONTEXT, Community},
+ snmpm_server:sync_get(UserId, TargetName, CC, Oids, Timeout);
+sync_get(UserId, TargetName, CC, Oids, Timeout) ->
+ snmpm_server:sync_get(UserId, TargetName, CC, Oids, Timeout).
-sync_get(UserId, TargetName, Context, Oids, Timeout, ExtraInfo) ->
-%% p("sync_get -> entry with"
-%% "~n UserId: ~p"
-%% "~n TargetName: ~p"
-%% "~n Context: ~p"
-%% "~n Oids: ~p"
-%% "~n Timeout: ~p"
-%% "~n ExtraInfo: ~p",
-%% [UserId, TargetName, Context, Oids, Timeout, ExtraInfo]),
- snmpm_server:sync_get(UserId, TargetName, Context, Oids, Timeout,
- ExtraInfo).
+sync_get(UserId, TargetName, {community, Community},
+ Oids, Timeout, ExtraInfo) ->
+ CC = {?DEFAULT_CONTEXT, Community},
+ snmpm_server:sync_get(UserId, TargetName, CC, Oids, Timeout, ExtraInfo);
+sync_get(UserId, TargetName, CC, Oids, Timeout, ExtraInfo) ->
+ snmpm_server:sync_get(UserId, TargetName, CC, Oids, Timeout, ExtraInfo).
g(UserId, Addr, Oids) ->
-%% p("g -> entry with"
-%% "~n UserId: ~p"
-%% "~n Addr: ~p"
-%% "~n Oids: ~p", [UserId, Addr, Oids]),
g(UserId, Addr, ?DEFAULT_AGENT_PORT, Oids).
-g(UserId, Addr, CtxName, Oids) when is_list(CtxName) andalso is_list(Oids) ->
-%% p("g -> entry with"
-%% "~n UserId: ~p"
-%% "~n Addr: ~p"
-%% "~n CtxName: ~p"
-%% "~n Oids: ~p", [UserId, Addr, CtxName, Oids]),
- g(UserId, Addr, ?DEFAULT_AGENT_PORT, CtxName, Oids);
-
g(UserId, Addr, Port, Oids) when is_integer(Port) andalso is_list(Oids) ->
-%% p("g -> entry with"
-%% "~n UserId: ~p"
-%% "~n Addr: ~p"
-%% "~n Port: ~p"
-%% "~n Oids: ~p", [UserId, Addr, Port, Oids]),
g(UserId, Addr, Port, ?DEFAULT_CONTEXT, Oids);
-
-g(UserId, Addr, Oids, Timeout)
- when is_list(Oids) andalso is_integer(Timeout) ->
-%% p("g -> entry with"
-%% "~n UserId: ~p"
-%% "~n Addr: ~p"
-%% "~n Oids: ~p"
-%% "~n Timeout: ~p", [UserId, Addr, Oids, Timeout]),
+g(UserId, Addr, CC, Oids) when is_list(Oids) ->
+ g(UserId, Addr, ?DEFAULT_AGENT_PORT, CC, Oids);
+g(UserId, Addr, Oids, Timeout) when is_integer(Timeout) ->
g(UserId, Addr, ?DEFAULT_AGENT_PORT, Oids, Timeout).
-g(UserId, Addr, Port, CtxName, Oids)
- when is_integer(Port) andalso is_list(CtxName) andalso is_list(Oids) ->
-%% p("g -> entry with"
-%% "~n UserId: ~p"
-%% "~n Addr: ~p"
-%% "~n Port: ~p"
-%% "~n Context: ~p"
-%% "~n Oids: ~p", [UserId, Addr, Port, CtxName, Oids]),
+g(UserId, Addr, Port, CC, Oids)
+ when is_integer(Port) andalso is_list(Oids) ->
case target_name(Addr, Port) of
{ok, TargetName} ->
-%% p("g -> TargetName: ~p", [TargetName]),
- sync_get(UserId, TargetName, CtxName, Oids);
+ sync_get(UserId, TargetName, CC, Oids);
Error ->
Error
end;
g(UserId, Addr, Port, Oids, Timeout)
when is_integer(Port) andalso is_list(Oids) andalso is_integer(Timeout) ->
-%% p("g -> entry with"
-%% "~n UserId: ~p"
-%% "~n Addr: ~p"
-%% "~n Oids: ~p"
-%% "~n Timeout: ~p",
-%% [UserId, Addr, Oids, Timeout]),
g(UserId, Addr, Port, ?DEFAULT_CONTEXT, Oids, Timeout);
-g(UserId, Addr, CtxName, Oids, Timeout)
- when is_list(CtxName) andalso is_list(Oids) andalso is_integer(Timeout) ->
-%% p("g -> entry with"
-%% "~n UserId: ~p"
-%% "~n Addr: ~p"
-%% "~n CtxName: ~p"
-%% "~n Oids: ~p"
-%% "~n Timeout: ~p",
-%% [UserId, Addr, CtxName, Oids, Timeout]),
- g(UserId, Addr, ?DEFAULT_AGENT_PORT, CtxName, Oids, Timeout).
-
-g(UserId, Addr, Port, CtxName, Oids, Timeout) ->
-%% p("g -> entry with"
-%% "~n UserId: ~p"
-%% "~n Addr: ~p"
-%% "~n Port: ~p"
-%% "~n CtxName: ~p"
-%% "~n Oids: ~p"
-%% "~n Timeout: ~p",
-%% [UserId, Addr, Port, CtxName, Oids, Timeout]),
+g(UserId, Addr, CC, Oids, Timeout)
+ when is_list(Oids) andalso is_integer(Timeout) ->
+ g(UserId, Addr, ?DEFAULT_AGENT_PORT, CC, Oids, Timeout).
+
+g(UserId, Addr, Port, CC, Oids, Timeout) ->
case target_name(Addr, Port) of
{ok, TargetName} ->
-%% p("g -> TargetName: ~p", [TargetName]),
- sync_get(UserId, TargetName, CtxName, Oids, Timeout);
+ sync_get(UserId, TargetName, CC, Oids, Timeout);
Error ->
Error
end.
-g(UserId, Addr, Port, CtxName, Oids, Timeout, ExtraInfo) ->
-%% p("g -> entry with"
-%% "~n UserId: ~p"
-%% "~n Addr: ~p"
-%% "~n Port: ~p"
-%% "~n CtxName: ~p"
-%% "~n Oids: ~p"
-%% "~n Timeout: ~p"
-%% "~n ExtraInfo: ~p",
-%% [UserId, Addr, Port, CtxName, Oids, Timeout, ExtraInfo]),
+g(UserId, Addr, Port, CC, Oids, Timeout, ExtraInfo) ->
case target_name(Addr, Port) of
{ok, TargetName} ->
-%% p("g -> TargetName: ~p", [TargetName]),
- sync_get(UserId, TargetName, CtxName, Oids, Timeout, ExtraInfo);
+ sync_get(UserId, TargetName, CC, Oids, Timeout, ExtraInfo);
Error ->
Error
end.
@@ -630,18 +550,27 @@ g(UserId, Addr, Port, CtxName, Oids, Timeout, ExtraInfo) ->
async_get(UserId, TargetName, Oids) ->
async_get(UserId, TargetName, ?DEFAULT_CONTEXT, Oids).
-async_get(UserId, TargetName, Context, Oids) when is_list(Oids) ->
- snmpm_server:async_get(UserId, TargetName, Context, Oids);
-
+async_get(UserId, TargetName, {community, Community}, Oids)
+ when is_list(Oids) ->
+ CC = {?DEFAULT_CONTEXT, Community},
+ snmpm_server:async_get(UserId, TargetName, CC, Oids);
+async_get(UserId, TargetName, CC, Oids) when is_list(Oids) ->
+ snmpm_server:async_get(UserId, TargetName, CC, Oids);
async_get(UserId, TargetName, Oids, Expire) when is_integer(Expire) ->
async_get(UserId, TargetName, ?DEFAULT_CONTEXT, Oids, Expire).
-async_get(UserId, TargetName, Context, Oids, Expire) ->
- snmpm_server:async_get(UserId, TargetName, Context, Oids, Expire).
+async_get(UserId, TargetName, {community, Community}, Oids, Expire) ->
+ CC = {?DEFAULT_CONTEXT, Community},
+ snmpm_server:async_get(UserId, TargetName, CC, Oids, Expire);
+async_get(UserId, TargetName, CC, Oids, Expire) ->
+ snmpm_server:async_get(UserId, TargetName, CC, Oids, Expire).
-async_get(UserId, TargetName, Context, Oids, Expire, ExtraInfo) ->
- snmpm_server:async_get(UserId, TargetName, Context, Oids, Expire,
- ExtraInfo).
+async_get(UserId, TargetName, {community, Community},
+ Oids, Expire, ExtraInfo) ->
+ CC = {?DEFAULT_CONTEXT, Community},
+ snmpm_server:async_get(UserId, TargetName, CC, Oids, Expire, ExtraInfo);
+async_get(UserId, TargetName, CC, Oids, Expire, ExtraInfo) ->
+ snmpm_server:async_get(UserId, TargetName, CC, Oids, Expire, ExtraInfo).
ag(UserId, Addr, Oids) ->
@@ -649,18 +578,17 @@ ag(UserId, Addr, Oids) ->
ag(UserId, Addr, Port, Oids) when is_integer(Port) andalso is_list(Oids) ->
ag(UserId, Addr, Port, ?DEFAULT_CONTEXT, Oids);
-
-ag(UserId, Addr, CtxName, Oids) when is_list(CtxName) andalso is_list(Oids) ->
- ag(UserId, Addr, ?DEFAULT_AGENT_PORT, CtxName, Oids);
-
ag(UserId, Addr, Oids, Expire) when is_list(Oids) andalso is_integer(Expire) ->
- ag(UserId, Addr, ?DEFAULT_AGENT_PORT, ?DEFAULT_CONTEXT, Oids, Expire).
+ ag(UserId, Addr, ?DEFAULT_AGENT_PORT, ?DEFAULT_CONTEXT, Oids, Expire);
+ag(UserId, Addr, CC, Oids) when is_list(Oids) ->
+ ag(UserId, Addr, ?DEFAULT_AGENT_PORT, CC, Oids).
+
-ag(UserId, Addr, Port, CtxName, Oids)
- when is_integer(Port) andalso is_list(CtxName) andalso is_list(Oids) ->
+ag(UserId, Addr, Port, CC, Oids)
+ when is_integer(Port) andalso is_list(Oids) ->
case target_name(Addr, Port) of
{ok, TargetName} ->
- async_get(UserId, TargetName, CtxName, Oids);
+ async_get(UserId, TargetName, CC, Oids);
Error ->
Error
end;
@@ -668,23 +596,22 @@ ag(UserId, Addr, Port, CtxName, Oids)
ag(UserId, Addr, Port, Oids, Expire)
when is_integer(Port) andalso is_list(Oids) andalso is_integer(Expire) ->
ag(UserId, Addr, Port, ?DEFAULT_CONTEXT, Oids, Expire);
+ag(UserId, Addr, CC, Oids, Expire)
+ when is_list(Oids) andalso is_integer(Expire) ->
+ ag(UserId, Addr, ?DEFAULT_AGENT_PORT, CC, Oids, Expire).
-ag(UserId, Addr, CtxName, Oids, Expire)
- when is_list(CtxName) andalso is_list(Oids) andalso is_integer(Expire) ->
- ag(UserId, Addr, ?DEFAULT_AGENT_PORT, CtxName, Oids, Expire).
-
-ag(UserId, Addr, Port, CtxName, Oids, Expire) ->
+ag(UserId, Addr, Port, CC, Oids, Expire) ->
case target_name(Addr, Port) of
{ok, TargetName} ->
- async_get(UserId, TargetName, CtxName, Oids, Expire);
+ async_get(UserId, TargetName, CC, Oids, Expire);
Error ->
Error
end.
-ag(UserId, Addr, Port, CtxName, Oids, Expire, ExtraInfo) ->
+ag(UserId, Addr, Port, CC, Oids, Expire, ExtraInfo) ->
case target_name(Addr, Port) of
{ok, TargetName} ->
- async_get(UserId, TargetName, CtxName, Oids, Expire, ExtraInfo);
+ async_get(UserId, TargetName, CC, Oids, Expire, ExtraInfo);
Error ->
Error
end.
@@ -697,63 +624,74 @@ ag(UserId, Addr, Port, CtxName, Oids, Expire, ExtraInfo) ->
sync_get_next(UserId, TargetName, Oids) ->
sync_get_next(UserId, TargetName, ?DEFAULT_CONTEXT, Oids).
-sync_get_next(UserId, TargetName, Context, Oids)
- when is_list(Context) andalso is_list(Oids) ->
- snmpm_server:sync_get_next(UserId, TargetName, Context, Oids);
-
+sync_get_next(UserId, TargetName, {community, Community}, Oids)
+ when is_list(Oids) ->
+ CC = {?DEFAULT_CONTEXT, Community},
+ snmpm_server:sync_get_next(UserId, TargetName, CC, Oids);
+sync_get_next(UserId, TargetName, CC, Oids)
+ when is_list(Oids) ->
+ snmpm_server:sync_get_next(UserId, TargetName, CC, Oids);
sync_get_next(UserId, TargetName, Oids, Timeout)
- when is_list(Oids) andalso is_integer(Timeout) ->
+ when is_integer(Timeout) ->
sync_get_next(UserId, TargetName, ?DEFAULT_CONTEXT, Oids, Timeout).
-sync_get_next(UserId, TargetName, Context, Oids, Timeout) ->
- snmpm_server:sync_get_next(UserId, TargetName, Context, Oids, Timeout).
-sync_get_next(UserId, TargetName, Context, Oids, Timeout, ExtraInfo) ->
- snmpm_server:sync_get_next(UserId, TargetName, Context, Oids, Timeout,
+sync_get_next(UserId, TargetName, {community, Community}, Oids, Timeout) ->
+ CC = {?DEFAULT_CONTEXT, Community},
+ snmpm_server:sync_get_next(UserId, TargetName, CC, Oids, Timeout);
+sync_get_next(UserId, TargetName, CC, Oids, Timeout) ->
+ snmpm_server:sync_get_next(UserId, TargetName, CC, Oids, Timeout).
+
+sync_get_next(UserId, TargetName, {community, Community},
+ Oids, Timeout, ExtraInfo) ->
+ CC = {?DEFAULT_CONTEXT, Community},
+ snmpm_server:sync_get_next(UserId, TargetName, CC, Oids, Timeout,
+ ExtraInfo);
+sync_get_next(UserId, TargetName, CC, Oids, Timeout, ExtraInfo) ->
+ snmpm_server:sync_get_next(UserId, TargetName, CC, Oids, Timeout,
ExtraInfo).
gn(UserId, Addr, Oids) ->
gn(UserId, Addr, ?DEFAULT_AGENT_PORT, Oids).
-gn(UserId, Addr, CtxName, Oids) when is_list(CtxName) andalso is_list(Oids) ->
- gn(UserId, Addr, ?DEFAULT_AGENT_PORT, CtxName, Oids);
-
-gn(UserId, Addr, Port, Oids) when is_integer(Port) andalso is_list(Oids) ->
- gn(UserId, Addr, Port, ?DEFAULT_CONTEXT, Oids);
-
gn(UserId, Addr, Oids, Timeout)
when is_list(Oids) andalso is_integer(Timeout) ->
- gn(UserId, Addr, ?DEFAULT_AGENT_PORT, Oids, Timeout).
+ gn(UserId, Addr, ?DEFAULT_AGENT_PORT, Oids, Timeout);
+gn(UserId, Addr, Port, Oids)
+ when is_integer(Port) andalso is_list(Oids) ->
+ gn(UserId, Addr, Port, ?DEFAULT_CONTEXT, Oids);
+gn(UserId, Addr, CC, Oids)
+ when is_list(Oids) ->
+ gn(UserId, Addr, ?DEFAULT_AGENT_PORT, CC, Oids).
-gn(UserId, Addr, Port, CtxName, Oids)
- when is_integer(Port) andalso is_list(CtxName) andalso is_list(Oids) ->
+gn(UserId, Addr, Port, Oids, Timeout)
+ when is_integer(Port) andalso is_list(Oids) andalso is_integer(Timeout) ->
+ gn(UserId, Addr, Port, ?DEFAULT_CONTEXT, Oids, Timeout);
+gn(UserId, Addr, Port, CC, Oids)
+ when is_integer(Port) andalso is_list(Oids) ->
case target_name(Addr, Port) of
{ok, TargetName} ->
- sync_get_next(UserId, TargetName, CtxName, Oids);
+ sync_get_next(UserId, TargetName, CC, Oids);
Error ->
Error
end;
-
-gn(UserId, Addr, Port, Oids, Timeout)
- when is_integer(Port) andalso is_list(Oids) andalso is_integer(Timeout) ->
- gn(UserId, Addr, Port, ?DEFAULT_CONTEXT, Oids, Timeout);
-gn(UserId, Addr, CtxName, Oids, Timeout)
- when is_list(CtxName) andalso is_list(Oids) andalso is_integer(Timeout) ->
- gn(UserId, Addr, ?DEFAULT_AGENT_PORT, CtxName, Oids, Timeout).
+gn(UserId, Addr, CC, Oids, Timeout)
+ when is_list(Oids) andalso is_integer(Timeout) ->
+ gn(UserId, Addr, ?DEFAULT_AGENT_PORT, CC, Oids, Timeout).
-gn(UserId, Addr, Port, CtxName, Oids, Timeout) ->
+gn(UserId, Addr, Port, CC, Oids, Timeout) ->
case target_name(Addr, Port) of
{ok, TargetName} ->
- sync_get_next(UserId, TargetName, CtxName, Oids, Timeout);
+ sync_get_next(UserId, TargetName, CC, Oids, Timeout);
Error ->
Error
end.
-gn(UserId, Addr, Port, CtxName, Oids, Timeout, ExtraInfo) ->
+gn(UserId, Addr, Port, CC, Oids, Timeout, ExtraInfo) ->
case target_name(Addr, Port) of
{ok, TargetName} ->
- sync_get_next(UserId, TargetName, CtxName, Oids, Timeout, ExtraInfo);
+ sync_get_next(UserId, TargetName, CC, Oids, Timeout, ExtraInfo);
Error ->
Error
end.
@@ -766,63 +704,72 @@ gn(UserId, Addr, Port, CtxName, Oids, Timeout, ExtraInfo) ->
async_get_next(UserId, TargetName, Oids) ->
async_get_next(UserId, TargetName, ?DEFAULT_CONTEXT, Oids).
-async_get_next(UserId, TargetName, Context, Oids)
- when is_list(Context) andalso is_list(Oids) ->
- snmpm_server:async_get_next(UserId, TargetName, Context, Oids);
-
+async_get_next(UserId, TargetName, {community, Community}, Oids)
+ when is_list(Oids) ->
+ CC = {?DEFAULT_CONTEXT, Community},
+ snmpm_server:async_get_next(UserId, TargetName, CC, Oids);
+async_get_next(UserId, TargetName, CC, Oids)
+ when is_list(Oids) ->
+ snmpm_server:async_get_next(UserId, TargetName, CC, Oids);
async_get_next(UserId, TargetName, Oids, Timeout)
- when is_list(Oids) andalso is_integer(Timeout) ->
+ when is_integer(Timeout) ->
async_get_next(UserId, TargetName, ?DEFAULT_CONTEXT, Oids, Timeout).
-async_get_next(UserId, TargetName, Context, Oids, Timeout) ->
- snmpm_server:async_get_next(UserId, TargetName, Context, Oids, Timeout).
-
-async_get_next(UserId, TargetName, Context, Oids, Timeout, ExtraInfo) ->
- snmpm_server:async_get_next(UserId, TargetName, Context, Oids, Timeout,
+async_get_next(UserId, TargetName, {community, Community}, Oids, Timeout) ->
+ CC = {?DEFAULT_CONTEXT, Community},
+ snmpm_server:async_get_next(UserId, TargetName, CC, Oids, Timeout);
+async_get_next(UserId, TargetName, CC, Oids, Timeout) ->
+ snmpm_server:async_get_next(UserId, TargetName, CC, Oids, Timeout).
+
+async_get_next(UserId, TargetName, {community, Community},
+ Oids, Timeout, ExtraInfo) ->
+ CC = {?DEFAULT_CONTEXT, Community},
+ snmpm_server:async_get_next(UserId, TargetName, CC, Oids, Timeout,
+ ExtraInfo);
+async_get_next(UserId, TargetName, CC, Oids, Timeout, ExtraInfo) ->
+ snmpm_server:async_get_next(UserId, TargetName, CC, Oids, Timeout,
ExtraInfo).
agn(UserId, Addr, Oids) ->
agn(UserId, Addr, ?DEFAULT_AGENT_PORT, Oids).
-agn(UserId, Addr, CtxName, Oids) when is_list(CtxName) andalso is_list(Oids) ->
- agn(UserId, Addr, ?DEFAULT_AGENT_PORT, CtxName, Oids);
-
-agn(UserId, Addr, Port, Oids) when is_integer(Port) andalso is_list(Oids) ->
- agn(UserId, Addr, Port, ?DEFAULT_CONTEXT, Oids);
-
agn(UserId, Addr, Oids, Expire)
when is_list(Oids) andalso is_integer(Expire) ->
- agn(UserId, Addr, ?DEFAULT_AGENT_PORT, Oids, Expire).
+ agn(UserId, Addr, ?DEFAULT_AGENT_PORT, Oids, Expire);
+agn(UserId, Addr, Port, Oids)
+ when is_integer(Port) andalso is_list(Oids) ->
+ agn(UserId, Addr, Port, ?DEFAULT_CONTEXT, Oids);
+agn(UserId, Addr, CC, Oids)
+ when is_list(Oids) ->
+ agn(UserId, Addr, ?DEFAULT_AGENT_PORT, CC, Oids).
-agn(UserId, Addr, Port, CtxName, Oids)
- when is_integer(Port) andalso is_list(CtxName) andalso is_list(Oids) ->
+agn(UserId, Addr, Port, Oids, Expire)
+ when is_integer(Port) andalso is_integer(Expire) ->
+ agn(UserId, Addr, Port, ?DEFAULT_CONTEXT, Oids, Expire);
+agn(UserId, Addr, CC, Oids, Expire)
+ when is_integer(Expire) ->
+ agn(UserId, Addr, ?DEFAULT_AGENT_PORT, CC, Oids, Expire);
+agn(UserId, Addr, Port, CC, Oids)
+ when is_integer(Port) andalso is_list(Oids) ->
case target_name(Addr, Port) of
{ok, TargetName} ->
- async_get_next(UserId, TargetName, CtxName, Oids);
+ async_get_next(UserId, TargetName, CC, Oids);
Error ->
Error
- end;
-
-agn(UserId, Addr, Port, Oids, Expire)
- when is_integer(Port) andalso is_list(Oids) andalso is_integer(Expire) ->
- agn(UserId, Addr, Port, ?DEFAULT_CONTEXT, Oids, Expire);
-agn(UserId, Addr, CtxName, Oids, Expire)
- when is_list(CtxName) andalso is_list(CtxName) andalso is_integer(Expire) ->
- agn(UserId, Addr, ?DEFAULT_AGENT_PORT, CtxName, Oids, Expire).
+ end.
-agn(UserId, Addr, Port, CtxName, Oids, Expire) ->
+agn(UserId, Addr, Port, CC, Oids, Expire) ->
case target_name(Addr, Port) of
{ok, TargetName} ->
- async_get_next(UserId, TargetName, CtxName, Oids, Expire);
+ async_get_next(UserId, TargetName, CC, Oids, Expire);
Error ->
Error
end.
-agn(UserId, Addr, Port, CtxName, Oids, Expire, ExtraInfo) ->
+agn(UserId, Addr, Port, CC, Oids, Expire, ExtraInfo) ->
case target_name(Addr, Port) of
{ok, TargetName} ->
- async_get_next(UserId, TargetName, CtxName, Oids, Expire,
- ExtraInfo);
+ async_get_next(UserId, TargetName, CC, Oids, Expire, ExtraInfo);
Error ->
Error
end.
@@ -835,19 +782,30 @@ agn(UserId, Addr, Port, CtxName, Oids, Expire, ExtraInfo) ->
sync_set(UserId, TargetName, VarsAndVals) ->
sync_set(UserId, TargetName, ?DEFAULT_CONTEXT, VarsAndVals).
-sync_set(UserId, TargetName, Context, VarsAndVals)
- when is_list(Context) andalso is_list(VarsAndVals) ->
- snmpm_server:sync_set(UserId, TargetName, Context, VarsAndVals);
-
sync_set(UserId, TargetName, VarsAndVals, Timeout)
when is_list(VarsAndVals) andalso is_integer(Timeout) ->
- sync_set(UserId, TargetName, ?DEFAULT_CONTEXT, VarsAndVals, Timeout).
-
-sync_set(UserId, TargetName, Context, VarsAndVals, Timeout) ->
- snmpm_server:sync_set(UserId, TargetName, Context, VarsAndVals, Timeout).
-
-sync_set(UserId, TargetName, Context, VarsAndVals, Timeout, ExtraInfo) ->
- snmpm_server:sync_set(UserId, TargetName, Context, VarsAndVals, Timeout,
+ sync_set(UserId, TargetName, ?DEFAULT_CONTEXT, VarsAndVals, Timeout);
+sync_set(UserId, TargetName, {community, Community}, VarsAndVals)
+ when is_list(VarsAndVals) ->
+ CC = {?DEFAULT_CONTEXT, Community},
+ snmpm_server:sync_set(UserId, TargetName, CC, VarsAndVals);
+sync_set(UserId, TargetName, CC, VarsAndVals)
+ when is_list(VarsAndVals) ->
+ snmpm_server:sync_set(UserId, TargetName, CC, VarsAndVals).
+
+sync_set(UserId, TargetName, {community, Community}, VarsAndVals, Timeout) ->
+ CC = {?DEFAULT_CONTEXT, Community},
+ snmpm_server:sync_set(UserId, TargetName, CC, VarsAndVals, Timeout);
+sync_set(UserId, TargetName, CC, VarsAndVals, Timeout) ->
+ snmpm_server:sync_set(UserId, TargetName, CC, VarsAndVals, Timeout).
+
+sync_set(UserId, TargetName, {community, Community},
+ VarsAndVals, Timeout, ExtraInfo) ->
+ CC = {?DEFAULT_CONTEXT, Community},
+ snmpm_server:sync_set(UserId, TargetName, CC, VarsAndVals, Timeout,
+ ExtraInfo);
+sync_set(UserId, TargetName, CC, VarsAndVals, Timeout, ExtraInfo) ->
+ snmpm_server:sync_set(UserId, TargetName, CC, VarsAndVals, Timeout,
ExtraInfo).
@@ -857,50 +815,43 @@ s(UserId, Addr, VarsAndVals) ->
s(UserId, Addr, Port, VarsAndVals)
when is_integer(Port) andalso is_list(VarsAndVals) ->
s(UserId, Addr, Port, ?DEFAULT_CONTEXT, VarsAndVals);
-
-s(UserId, Addr, CtxName, VarsAndVals)
- when is_list(CtxName) andalso is_list(VarsAndVals) ->
- s(UserId, Addr, ?DEFAULT_AGENT_PORT, CtxName, VarsAndVals);
-
s(UserId, Addr, VarsAndVals, Timeout)
when is_list(VarsAndVals) andalso is_integer(Timeout) ->
- s(UserId, Addr, ?DEFAULT_AGENT_PORT, VarsAndVals, Timeout).
+ s(UserId, Addr, ?DEFAULT_AGENT_PORT, VarsAndVals, Timeout);
+s(UserId, Addr, CC, VarsAndVals)
+ when is_list(VarsAndVals) ->
+ s(UserId, Addr, ?DEFAULT_AGENT_PORT, CC, VarsAndVals).
-s(UserId, Addr, Port, CtxName, VarsAndVals)
- when is_integer(Port) andalso
- is_list(CtxName) andalso
- is_list(VarsAndVals) ->
- case target_name(Addr, Port) of
- {ok, TargetName} ->
- sync_set(UserId, TargetName, CtxName, VarsAndVals);
- Error ->
- Error
- end;
s(UserId, Addr, Port, VarsAndVals, Timeout)
when is_integer(Port) andalso
is_list(VarsAndVals) andalso
is_integer(Timeout) ->
s(UserId, Addr, Port, ?DEFAULT_CONTEXT, VarsAndVals, Timeout);
+s(UserId, Addr, Port, CC, VarsAndVals)
+ when is_integer(Port) andalso is_list(VarsAndVals) ->
+ case target_name(Addr, Port) of
+ {ok, TargetName} ->
+ sync_set(UserId, TargetName, CC, VarsAndVals);
+ Error ->
+ Error
+ end;
+s(UserId, Addr, CC, VarsAndVals, Timeout)
+ when is_list(VarsAndVals) andalso is_integer(Timeout) ->
+ s(UserId, Addr, ?DEFAULT_AGENT_PORT, CC, VarsAndVals, Timeout).
-s(UserId, Addr, CtxName, VarsAndVals, Timeout)
- when is_list(CtxName) andalso
- is_list(VarsAndVals) andalso
- is_integer(Timeout) ->
- s(UserId, Addr, ?DEFAULT_AGENT_PORT, CtxName, VarsAndVals, Timeout).
-
-s(UserId, Addr, Port, CtxName, VarsAndVals, Timeout) ->
+s(UserId, Addr, Port, CC, VarsAndVals, Timeout) ->
case target_name(Addr, Port) of
{ok, TargetName} ->
- sync_set(UserId, TargetName, CtxName, VarsAndVals, Timeout);
+ sync_set(UserId, TargetName, CC, VarsAndVals, Timeout);
Error ->
Error
end.
-s(UserId, Addr, Port, CtxName, VarsAndVals, Timeout, ExtraInfo) ->
+s(UserId, Addr, Port, CC, VarsAndVals, Timeout, ExtraInfo) ->
case target_name(Addr, Port) of
{ok, TargetName} ->
- sync_set(UserId, TargetName, CtxName, VarsAndVals, Timeout, ExtraInfo);
+ sync_set(UserId, TargetName, CC, VarsAndVals, Timeout, ExtraInfo);
Error ->
Error
end.
@@ -913,72 +864,76 @@ s(UserId, Addr, Port, CtxName, VarsAndVals, Timeout, ExtraInfo) ->
async_set(UserId, TargetName, VarsAndVals) ->
async_set(UserId, TargetName, ?DEFAULT_CONTEXT, VarsAndVals).
-async_set(UserId, TargetName, Context, VarsAndVals)
- when is_list(Context) andalso is_list(VarsAndVals) ->
- snmpm_server:async_set(UserId, TargetName, Context, VarsAndVals);
-
async_set(UserId, TargetName, VarsAndVals, Expire)
when is_list(VarsAndVals) andalso is_integer(Expire) ->
- async_set(UserId, TargetName, ?DEFAULT_CONTEXT, VarsAndVals, Expire).
-
-async_set(UserId, TargetName, Context, VarsAndVals, Expire) ->
- snmpm_server:async_set(UserId, TargetName, Context, VarsAndVals, Expire).
-
-async_set(UserId, TargetName, Context, VarsAndVals, Expire, ExtraInfo) ->
- snmpm_server:async_set(UserId, TargetName, Context, VarsAndVals, Expire,
+ async_set(UserId, TargetName, ?DEFAULT_CONTEXT, VarsAndVals, Expire);
+async_set(UserId, TargetName, {community, Community}, VarsAndVals)
+ when is_list(VarsAndVals) ->
+ CC = {?DEFAULT_CONTEXT, Community},
+ snmpm_server:async_set(UserId, TargetName, CC, VarsAndVals);
+async_set(UserId, TargetName, CC, VarsAndVals)
+ when is_list(VarsAndVals) ->
+ snmpm_server:async_set(UserId, TargetName, CC, VarsAndVals).
+
+async_set(UserId, TargetName, {community, Community}, VarsAndVals, Expire) ->
+ CC = {?DEFAULT_CONTEXT, Community},
+ snmpm_server:async_set(UserId, TargetName, CC, VarsAndVals, Expire);
+async_set(UserId, TargetName, CC, VarsAndVals, Expire) ->
+ snmpm_server:async_set(UserId, TargetName, CC, VarsAndVals, Expire).
+
+async_set(UserId, TargetName, {community, Community},
+ VarsAndVals, Expire, ExtraInfo) ->
+ CC = {?DEFAULT_CONTEXT, Community},
+ snmpm_server:async_set(UserId, TargetName, CC, VarsAndVals, Expire,
+ ExtraInfo);
+async_set(UserId, TargetName, CC, VarsAndVals, Expire, ExtraInfo) ->
+ snmpm_server:async_set(UserId, TargetName, CC, VarsAndVals, Expire,
ExtraInfo).
as(UserId, Addr, VarsAndVals) ->
as(UserId, Addr, ?DEFAULT_AGENT_PORT, VarsAndVals).
+as(UserId, Addr, VarsAndVals, Expire)
+ when is_list(VarsAndVals) andalso is_integer(Expire) ->
+ as(UserId, Addr, ?DEFAULT_AGENT_PORT, VarsAndVals, Expire);
as(UserId, Addr, Port, VarsAndVals)
when is_integer(Port) andalso is_list(VarsAndVals) ->
as(UserId, Addr, Port, ?DEFAULT_CONTEXT, VarsAndVals);
+as(UserId, Addr, CC, VarsAndVals)
+ when is_list(VarsAndVals) ->
+ as(UserId, Addr, ?DEFAULT_AGENT_PORT, CC, VarsAndVals).
-as(UserId, Addr, CtxName, VarsAndVals)
- when is_list(CtxName) andalso is_list(VarsAndVals) ->
- as(UserId, Addr, ?DEFAULT_AGENT_PORT, CtxName, VarsAndVals);
-
-as(UserId, Addr, VarsAndVals, Expire)
- when is_list(VarsAndVals) andalso is_integer(Expire) ->
- as(UserId, Addr, ?DEFAULT_AGENT_PORT, VarsAndVals, Expire).
-as(UserId, Addr, Port, CtxName, VarsAndVals)
+as(UserId, Addr, Port, VarsAndVals, Expire)
when is_integer(Port) andalso
- is_list(CtxName) andalso
- is_list(VarsAndVals) ->
+ is_list(VarsAndVals) andalso
+ is_integer(Expire) ->
+ as(UserId, Addr, Port, ?DEFAULT_CONTEXT, VarsAndVals, Expire);
+as(UserId, Addr, Port, CC, VarsAndVals)
+ when is_integer(Port) andalso is_list(VarsAndVals) ->
case target_name(Addr, Port) of
{ok, TargetName} ->
- async_set(UserId, TargetName, CtxName, VarsAndVals);
+ async_set(UserId, TargetName, CC, VarsAndVals);
Error ->
Error
end;
-
-as(UserId, Addr, Port, VarsAndVals, Expire)
- when is_integer(Port) andalso
- is_list(VarsAndVals) andalso
- is_integer(Expire) ->
- as(UserId, Addr, Port, ?DEFAULT_CONTEXT, VarsAndVals, Expire);
-
-as(UserId, Addr, CtxName, VarsAndVals, Expire)
- when is_list(CtxName) andalso
- is_list(VarsAndVals) andalso
- is_integer(Expire) ->
- as(UserId, Addr, ?DEFAULT_AGENT_PORT, CtxName, VarsAndVals, Expire).
+as(UserId, Addr, CC, VarsAndVals, Expire)
+ when is_list(VarsAndVals) andalso is_integer(Expire) ->
+ as(UserId, Addr, ?DEFAULT_AGENT_PORT, CC, VarsAndVals, Expire).
-as(UserId, Addr, Port, CtxName, VarsAndVals, Expire) ->
+as(UserId, Addr, Port, CC, VarsAndVals, Expire) ->
case target_name(Addr, Port) of
{ok, TargetName} ->
- async_set(UserId, TargetName, CtxName, VarsAndVals, Expire);
+ async_set(UserId, TargetName, CC, VarsAndVals, Expire);
Error ->
Error
end.
-as(UserId, Addr, Port, CtxName, VarsAndVals, Expire, ExtraInfo) ->
+as(UserId, Addr, Port, CC, VarsAndVals, Expire, ExtraInfo) ->
case target_name(Addr, Port) of
{ok, TargetName} ->
- async_set(UserId, TargetName, CtxName, VarsAndVals, Expire, ExtraInfo);
+ async_set(UserId, TargetName, CC, VarsAndVals, Expire, ExtraInfo);
Error ->
Error
end.
@@ -992,101 +947,111 @@ as(UserId, Addr, Port, CtxName, VarsAndVals, Expire, ExtraInfo) ->
sync_get_bulk(UserId, TargetName, NonRep, MaxRep, Oids) ->
sync_get_bulk(UserId, TargetName, NonRep, MaxRep, ?DEFAULT_CONTEXT, Oids).
-sync_get_bulk(UserId, TargetName, NonRep, MaxRep, Context, Oids)
+sync_get_bulk(UserId, TargetName, NonRep, MaxRep, Oids, Timeout)
+ when is_integer(NonRep) andalso
+ is_integer(MaxRep) andalso
+ is_list(Oids) andalso
+ is_integer(Timeout) ->
+ sync_get_bulk(UserId, TargetName, NonRep, MaxRep,
+ ?DEFAULT_CONTEXT, Oids, Timeout);
+sync_get_bulk(UserId, TargetName,
+ NonRep, MaxRep, {community, Community}, Oids)
when is_integer(NonRep) andalso
is_integer(MaxRep) andalso
- is_list(Context) andalso
is_list(Oids) ->
+ CC = {?DEFAULT_CONTEXT, Community},
snmpm_server:sync_get_bulk(UserId, TargetName,
NonRep, MaxRep,
- Context, Oids);
-
-sync_get_bulk(UserId, TargetName, NonRep, MaxRep, Oids, Timeout)
+ CC, Oids);
+sync_get_bulk(UserId, TargetName, NonRep, MaxRep, CC, Oids)
when is_integer(NonRep) andalso
is_integer(MaxRep) andalso
- is_list(Oids) andalso
- is_integer(Timeout) ->
- sync_get_bulk(UserId, TargetName, NonRep, MaxRep,
- ?DEFAULT_CONTEXT, Oids, Timeout).
+ is_list(Oids) ->
+ snmpm_server:sync_get_bulk(UserId, TargetName,
+ NonRep, MaxRep,
+ CC, Oids).
-sync_get_bulk(UserId, TargetName, NonRep, MaxRep, Context, Oids, Timeout) ->
- snmpm_server:sync_get_bulk(UserId, TargetName, NonRep, MaxRep,
- Context, Oids, Timeout).
+sync_get_bulk(UserId, TargetName,
+ NonRep, MaxRep, {community, Community}, Oids, Timeout) ->
+ CC = {?DEFAULT_CONTEXT, Community},
+ snmpm_server:sync_get_bulk(UserId, TargetName,
+ NonRep, MaxRep, CC, Oids, Timeout);
+sync_get_bulk(UserId, TargetName, NonRep, MaxRep, CC, Oids, Timeout) ->
+ snmpm_server:sync_get_bulk(UserId, TargetName,
+ NonRep, MaxRep, CC, Oids, Timeout).
-sync_get_bulk(UserId, TargetName, NonRep, MaxRep, Context, Oids, Timeout,
+sync_get_bulk(UserId, TargetName,
+ NonRep, MaxRep, {community, Community},
+ Oids, Timeout, ExtraInfo) ->
+ CC = {?DEFAULT_CONTEXT, Community},
+ snmpm_server:sync_get_bulk(UserId, TargetName,
+ NonRep, MaxRep, CC, Oids, Timeout, ExtraInfo);
+sync_get_bulk(UserId, TargetName, NonRep, MaxRep, CC, Oids, Timeout,
ExtraInfo) ->
- snmpm_server:sync_get_bulk(UserId, TargetName, NonRep, MaxRep,
- Context, Oids, Timeout, ExtraInfo).
+ snmpm_server:sync_get_bulk(UserId, TargetName,
+ NonRep, MaxRep, CC, Oids, Timeout, ExtraInfo).
gb(UserId, Addr, NonRep, MaxRep, Oids) ->
gb(UserId, Addr, ?DEFAULT_AGENT_PORT, NonRep, MaxRep, Oids).
+gb(UserId, Addr, NonRep, MaxRep, Oids, Timeout)
+ when is_integer(NonRep) andalso
+ is_integer(MaxRep) andalso
+ is_list(Oids) andalso
+ is_integer(Timeout) ->
+ gb(UserId, Addr, ?DEFAULT_AGENT_PORT, NonRep, MaxRep, Oids, Timeout);
gb(UserId, Addr, Port, NonRep, MaxRep, Oids)
when is_integer(Port) andalso
is_integer(NonRep) andalso
is_integer(MaxRep) andalso
is_list(Oids) ->
gb(UserId, Addr, Port, NonRep, MaxRep, ?DEFAULT_CONTEXT, Oids);
-
-gb(UserId, Addr, NonRep, MaxRep, CtxName, Oids)
+gb(UserId, Addr, NonRep, MaxRep, CC, Oids)
when is_integer(NonRep) andalso
is_integer(MaxRep) andalso
- is_list(CtxName) andalso
is_list(Oids) ->
- gb(UserId, Addr, ?DEFAULT_AGENT_PORT, NonRep, MaxRep, CtxName, Oids);
+ gb(UserId, Addr, ?DEFAULT_AGENT_PORT, NonRep, MaxRep, CC, Oids).
-gb(UserId, Addr, NonRep, MaxRep, Oids, Timeout)
+gb(UserId, Addr, Port, NonRep, MaxRep, Oids, Timeout)
+ when is_integer(Port) andalso
+ is_integer(NonRep) andalso
+ is_integer(MaxRep) andalso
+ is_list(Oids) andalso
+ is_integer(Timeout) ->
+ gb(UserId, Addr, Port, NonRep, MaxRep, ?DEFAULT_CONTEXT, Oids, Timeout);
+gb(UserId, Addr, NonRep, MaxRep, CC, Oids, Timeout)
when is_integer(NonRep) andalso
is_integer(MaxRep) andalso
is_list(Oids) andalso
is_integer(Timeout) ->
- gb(UserId, Addr, ?DEFAULT_AGENT_PORT, NonRep, MaxRep, Oids, Timeout).
-
-gb(UserId, Addr, Port, NonRep, MaxRep, CtxName, Oids)
+ gb(UserId, Addr, ?DEFAULT_AGENT_PORT, NonRep, MaxRep, CC, Oids, Timeout);
+gb(UserId, Addr, Port, NonRep, MaxRep, CC, Oids)
when is_integer(Port) andalso
is_integer(NonRep) andalso
is_integer(MaxRep) andalso
- is_list(CtxName) andalso
is_list(Oids) ->
case target_name(Addr, Port) of
{ok, TargetName} ->
- sync_get_bulk(UserId, TargetName, NonRep, MaxRep, CtxName, Oids);
+ sync_get_bulk(UserId, TargetName, NonRep, MaxRep, CC, Oids);
Error ->
Error
- end;
-
-gb(UserId, Addr, Port, NonRep, MaxRep, Oids, Timeout)
- when is_integer(Port) andalso
- is_integer(NonRep) andalso
- is_integer(MaxRep) andalso
- is_list(Oids) andalso
- is_integer(Timeout) ->
- gb(UserId, Addr, Port, NonRep, MaxRep, ?DEFAULT_CONTEXT, Oids, Timeout);
-
-gb(UserId, Addr, NonRep, MaxRep, CtxName, Oids, Timeout)
- when is_integer(NonRep) andalso
- is_integer(MaxRep) andalso
- is_list(CtxName) andalso
- is_list(Oids) andalso
- is_integer(Timeout) ->
- gb(UserId, Addr, ?DEFAULT_AGENT_PORT, NonRep, MaxRep, CtxName, Oids,
- Timeout).
+ end.
-gb(UserId, Addr, Port, NonRep, MaxRep, CtxName, Oids, Timeout) ->
+gb(UserId, Addr, Port, NonRep, MaxRep, CC, Oids, Timeout) ->
case target_name(Addr, Port) of
{ok, TargetName} ->
sync_get_bulk(UserId, TargetName,
- NonRep, MaxRep, CtxName, Oids, Timeout);
+ NonRep, MaxRep, CC, Oids, Timeout);
Error ->
Error
end.
-gb(UserId, Addr, Port, NonRep, MaxRep, CtxName, Oids, Timeout, ExtraInfo) ->
+gb(UserId, Addr, Port, NonRep, MaxRep, CC, Oids, Timeout, ExtraInfo) ->
case target_name(Addr, Port) of
{ok, TargetName} ->
sync_get_bulk(UserId, TargetName,
- NonRep, MaxRep, CtxName, Oids, Timeout, ExtraInfo);
+ NonRep, MaxRep, CC, Oids, Timeout, ExtraInfo);
Error ->
Error
end.
@@ -1099,102 +1064,110 @@ gb(UserId, Addr, Port, NonRep, MaxRep, CtxName, Oids, Timeout, ExtraInfo) ->
async_get_bulk(UserId, TargetName, NonRep, MaxRep, Oids) ->
async_get_bulk(UserId, TargetName, NonRep, MaxRep, ?DEFAULT_CONTEXT, Oids).
-async_get_bulk(UserId, TargetName, NonRep, MaxRep, Context, Oids)
- when is_integer(NonRep) andalso
- is_integer(MaxRep) andalso
- is_list(Context) andalso
- is_list(Oids) ->
- snmpm_server:async_get_bulk(UserId, TargetName,
- NonRep, MaxRep, Context, Oids);
-
async_get_bulk(UserId, TargetName, NonRep, MaxRep, Oids, Expire)
when is_integer(NonRep) andalso
is_integer(MaxRep) andalso
is_list(Oids) andalso
is_integer(Expire) ->
async_get_bulk(UserId, TargetName,
- NonRep, MaxRep, ?DEFAULT_CONTEXT, Oids, Expire).
+ NonRep, MaxRep, ?DEFAULT_CONTEXT, Oids, Expire);
+async_get_bulk(UserId, TargetName,
+ NonRep, MaxRep, {community, Community}, Oids)
+ when is_integer(NonRep) andalso
+ is_integer(MaxRep) andalso
+ is_list(Oids) ->
+ CC = {?DEFAULT_CONTEXT, Community},
+ snmpm_server:async_get_bulk(UserId, TargetName,
+ NonRep, MaxRep, CC, Oids);
+async_get_bulk(UserId, TargetName, NonRep, MaxRep, CC, Oids)
+ when is_integer(NonRep) andalso
+ is_integer(MaxRep) andalso
+ is_list(Oids) ->
+ snmpm_server:async_get_bulk(UserId, TargetName,
+ NonRep, MaxRep, CC, Oids).
-async_get_bulk(UserId, TargetName, NonRep, MaxRep, Context, Oids, Expire) ->
+async_get_bulk(UserId, TargetName, NonRep, MaxRep, {community, Community},
+ Oids, Expire) ->
+ CC = {?DEFAULT_CONTEXT, Community},
snmpm_server:async_get_bulk(UserId, TargetName,
- NonRep, MaxRep, Context, Oids, Expire).
+ NonRep, MaxRep, CC, Oids, Expire);
+async_get_bulk(UserId, TargetName, NonRep, MaxRep, CC, Oids, Expire) ->
+ snmpm_server:async_get_bulk(UserId, TargetName,
+ NonRep, MaxRep, CC, Oids, Expire).
-async_get_bulk(UserId, TargetName, NonRep, MaxRep, Context, Oids, Expire,
+async_get_bulk(UserId, TargetName,
+ NonRep, MaxRep, {community, Community},
+ Oids, Expire, ExtraInfo) ->
+ CC = {?DEFAULT_CONTEXT, Community},
+ snmpm_server:async_get_bulk(UserId, TargetName,
+ NonRep, MaxRep, CC, Oids, Expire, ExtraInfo);
+async_get_bulk(UserId, TargetName, NonRep, MaxRep, CC, Oids, Expire,
ExtraInfo) ->
snmpm_server:async_get_bulk(UserId, TargetName,
- NonRep, MaxRep,
- Context, Oids, Expire, ExtraInfo).
+ NonRep, MaxRep, CC, Oids, Expire, ExtraInfo).
agb(UserId, Addr, NonRep, MaxRep, Oids) ->
agb(UserId, Addr, ?DEFAULT_AGENT_PORT, NonRep, MaxRep, Oids).
+agb(UserId, Addr, NonRep, MaxRep, Oids, Expire)
+ when is_integer(NonRep) andalso
+ is_integer(MaxRep) andalso
+ is_list(Oids) andalso
+ is_integer(Expire) ->
+ agb(UserId, Addr, ?DEFAULT_AGENT_PORT, NonRep, MaxRep, Oids, Expire);
agb(UserId, Addr, Port, NonRep, MaxRep, Oids)
when is_integer(Port) andalso
is_integer(NonRep) andalso
is_integer(MaxRep) andalso
is_list(Oids) ->
agb(UserId, Addr, Port, NonRep, MaxRep, ?DEFAULT_CONTEXT, Oids);
-
-agb(UserId, Addr, NonRep, MaxRep, CtxName, Oids)
+agb(UserId, Addr, NonRep, MaxRep, CC, Oids)
when is_integer(NonRep) andalso
is_integer(MaxRep) andalso
- is_list(CtxName) andalso
is_list(Oids) ->
- agb(UserId, Addr, ?DEFAULT_AGENT_PORT, NonRep, MaxRep, CtxName, Oids);
+ agb(UserId, Addr, ?DEFAULT_AGENT_PORT, NonRep, MaxRep, CC, Oids).
-agb(UserId, Addr, NonRep, MaxRep, Oids, Expire)
+agb(UserId, Addr, Port, NonRep, MaxRep, Oids, Expire)
+ when is_integer(Port) andalso
+ is_integer(NonRep) andalso
+ is_integer(MaxRep) andalso
+ is_list(Oids) andalso
+ is_integer(Expire) ->
+ agb(UserId, Addr, Port, NonRep, MaxRep, ?DEFAULT_CONTEXT, Oids, Expire);
+agb(UserId, Addr, NonRep, MaxRep, CC, Oids, Expire)
when is_integer(NonRep) andalso
is_integer(MaxRep) andalso
is_list(Oids) andalso
is_integer(Expire) ->
- agb(UserId, Addr, ?DEFAULT_AGENT_PORT, NonRep, MaxRep, Oids, Expire).
-
-agb(UserId, Addr, Port, NonRep, MaxRep, CtxName, Oids)
+ agb(UserId, Addr, ?DEFAULT_AGENT_PORT, NonRep, MaxRep, CC, Oids);
+agb(UserId, Addr, Port, NonRep, MaxRep, CC, Oids)
when is_integer(Port) andalso
is_integer(NonRep) andalso
is_integer(MaxRep),
- is_list(CtxName) andalso
is_list(Oids) ->
case target_name(Addr, Port) of
{ok, TargetName} ->
async_get_bulk(UserId, TargetName,
- NonRep, MaxRep, CtxName, Oids);
+ NonRep, MaxRep, CC, Oids);
Error ->
Error
- end;
-
-agb(UserId, Addr, Port, NonRep, MaxRep, Oids, Expire)
- when is_integer(Port) andalso
- is_integer(NonRep) andalso
- is_integer(MaxRep) andalso
- is_list(Oids) andalso
- is_integer(Expire) ->
- agb(UserId, Addr, Port, NonRep, MaxRep, ?DEFAULT_CONTEXT, Oids, Expire);
-
-agb(UserId, Addr, NonRep, MaxRep, CtxName, Oids, Expire)
- when is_integer(NonRep) andalso
- is_integer(MaxRep) andalso
- is_list(CtxName) andalso
- is_list(Oids) andalso
- is_integer(Expire) ->
- agb(UserId, Addr, ?DEFAULT_AGENT_PORT, NonRep, MaxRep, CtxName, Oids).
+ end.
-agb(UserId, Addr, Port, NonRep, MaxRep, CtxName, Oids, Expire) ->
+agb(UserId, Addr, Port, NonRep, MaxRep, CC, Oids, Expire) ->
case target_name(Addr, Port) of
{ok, TargetName} ->
async_get_bulk(UserId, TargetName,
- NonRep, MaxRep, CtxName, Oids, Expire);
+ NonRep, MaxRep, CC, Oids, Expire);
Error ->
Error
end.
-agb(UserId, Addr, Port, NonRep, MaxRep, CtxName, Oids, Expire, ExtraInfo) ->
+agb(UserId, Addr, Port, NonRep, MaxRep, CC, Oids, Expire, ExtraInfo) ->
case target_name(Addr, Port) of
{ok, TargetName} ->
async_get_bulk(UserId, TargetName,
- NonRep, MaxRep, CtxName, Oids, Expire,
- ExtraInfo);
+ NonRep, MaxRep, CC, Oids, Expire, ExtraInfo);
Error ->
Error
end.
diff --git a/lib/snmp/src/manager/snmpm_config.erl b/lib/snmp/src/manager/snmpm_config.erl
index 1a5400bf8e..b976e8f568 100644
--- a/lib/snmp/src/manager/snmpm_config.erl
+++ b/lib/snmp/src/manager/snmpm_config.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2004-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 2004-2010. All Rights Reserved.
+%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
-%%
+%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
-%%
+%%
%% %CopyrightEnd%
%%
%% -------------------------------------------------------------------------
@@ -63,6 +63,7 @@
cre_counter/2,
incr_counter/2,
+ increment_counter/3, increment_counter/4,
cre_stats_counter/2,
maybe_cre_stats_counter/2,
@@ -792,6 +793,34 @@ incr_counter(Counter, Incr, Wrap) ->
end.
+%% <ATL Sequence Number>
+increment_counter(Counter, Initial, Max) ->
+ Increment = 1,
+ increment_counter(Counter, Initial, Increment, Max).
+
+increment_counter(Counter, Initial, Increment, Max) ->
+ %% This is to make sure no one else increments our counter
+ Key = {Counter, self()},
+
+ %% Counter data
+ Position = 2,
+ Threshold = Max,
+ SetValue = Initial,
+ UpdateOp = {Position, Increment, Threshold, SetValue},
+
+ %% And now for the actual increment
+ Tab = snmpm_counter_table,
+ case (catch ets:update_counter(Tab, Key, UpdateOp)) of
+ {'EXIT', {badarg, _}} ->
+ %% Oups, first time
+ ets:insert(Tab, {Key, Initial}),
+ Initial;
+ Next when is_integer(Next) ->
+ Next
+ end.
+%% </ATL Sequence Number>
+
+
maybe_cre_stats_counter(Counter, Initial) ->
case ets:lookup(snmpm_stats_table, Counter) of
[_] ->
@@ -1013,14 +1042,16 @@ do_init(Opts) ->
AuditTrailLogOpts ->
?vtrace("ATL options: ~p", [AuditTrailLogOpts]),
ets:insert(snmpm_config_table, {audit_trail_log, true}),
- LogDir = get_atl_dir(AuditTrailLogOpts),
- LogType = get_atl_type(AuditTrailLogOpts),
- LogSize = get_atl_size(AuditTrailLogOpts),
- LogRep = get_atl_repair(AuditTrailLogOpts),
+ LogDir = get_atl_dir(AuditTrailLogOpts),
+ LogType = get_atl_type(AuditTrailLogOpts),
+ LogSize = get_atl_size(AuditTrailLogOpts),
+ LogRep = get_atl_repair(AuditTrailLogOpts),
+ LogSeqNo = get_atl_seqno(AuditTrailLogOpts),
ets:insert(snmpm_config_table, {audit_trail_log_dir, LogDir}),
ets:insert(snmpm_config_table, {audit_trail_log_type, LogType}),
ets:insert(snmpm_config_table, {audit_trail_log_size, LogSize}),
- ets:insert(snmpm_config_table, {audit_trail_log_repair, LogRep})
+ ets:insert(snmpm_config_table, {audit_trail_log_repair, LogRep}),
+ ets:insert(snmpm_config_table, {audit_trail_log_seqno, LogSeqNo})
end,
%% -- System default agent config --
@@ -1398,6 +1429,9 @@ verify_audit_trail_log_opts([{size, Size}|Opts]) ->
verify_audit_trail_log_opts([{repair, Repair}|Opts]) ->
verify_log_repair(Repair),
verify_audit_trail_log_opts(Opts);
+verify_audit_trail_log_opts([{seqno, SeqNo}|Opts]) ->
+ verify_log_seqno(SeqNo),
+ verify_audit_trail_log_opts(Opts);
verify_audit_trail_log_opts([Opt|_Opts]) ->
error({invalid_audit_trail_log_option, Opt}).
@@ -1440,6 +1474,11 @@ verify_log_repair(truncate) -> ok;
verify_log_repair(Repair) ->
error({invalid_audit_trail_log_repair, Repair}).
+verify_log_seqno(true) -> ok;
+verify_log_seqno(false) -> ok;
+verify_log_seqno(SeqNo) ->
+ error({invalid_audit_trail_log_seqno, SeqNo}).
+
verify_module(_, Mod) when is_atom(Mod) ->
ok;
@@ -1618,7 +1657,8 @@ verify_agent({UserId,
{ok, Addr} ->
snmp_conf:check_integer(Port, {gt, 0}),
Conf =
- [{address, Addr},
+ [{reg_type, target_name},
+ {address, Addr},
{port, Port},
{community, Comm},
{engine_id, EngineId},
@@ -3040,6 +3080,9 @@ get_atl_size(Opts) ->
get_atl_repair(Opts) ->
get_opt(repair, Opts, truncate).
+get_atl_seqno(Opts) ->
+ get_opt(seqno, Opts, false).
+
%%----------------------------------------------------------------------
diff --git a/lib/snmp/src/manager/snmpm_mpd.erl b/lib/snmp/src/manager/snmpm_mpd.erl
index d76ad20051..7712370d28 100644
--- a/lib/snmp/src/manager/snmpm_mpd.erl
+++ b/lib/snmp/src/manager/snmpm_mpd.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2004-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 2004-2010. All Rights Reserved.
+%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
-%%
+%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
-%%
+%%
%% %CopyrightEnd%
%%
@@ -257,11 +257,11 @@ process_v3_msg(NoteStore, Msg, Hdr, Data, Addr, Port, Log) ->
end,
?vlog("7.2.7"
- "~n ContextEngineID: \"~s\" "
+ "~n ContextEngineID: ~p "
"~n context: \"~s\" ",
[CtxEngineID, CtxName]),
if
- SecLevel == 3 -> % encrypted message - log decrypted pdu
+ SecLevel =:= 3 -> % encrypted message - log decrypted pdu
Log({Hdr, ScopedPDUBytes});
true -> % otherwise, log binary
Log(Msg)
@@ -338,7 +338,8 @@ process_v3_msg(NoteStore, Msg, Hdr, Data, Addr, Port, Log) ->
SnmpEngineID = get_engine_id(),
case SecEngineID of
SnmpEngineID -> % 7.2.13.b
- ?vtrace("valid securityEngineID: ~p", [SecEngineID]),
+ ?vtrace("7.2.13d - valid securityEngineID: ~p",
+ [SecEngineID]),
%% 4.2.2.1.1 - we don't handle proxys yet => we only
%% handle CtxEngineID to ourselves
%% Check that we actually know of an agent with this
@@ -353,7 +354,9 @@ process_v3_msg(NoteStore, Msg, Hdr, Data, Addr, Port, Log) ->
{MsgID, MsgSecModel, SecName, SecLevel,
CtxEngineID, CtxName, SecData},
{ok, 'version-3', PDU, PduMMS, ACMData};
- _ ->
+ UnknownEngineID ->
+ ?vtrace("4.2.2.1.2 - UnknownEngineId: ~p",
+ [UnknownEngineID]),
%% 4.2.2.1.2
NIsReportable = snmp_misc:is_reportable_pdu(Type),
Val = inc(snmpUnknownPDUHandlers),
@@ -377,7 +380,8 @@ process_v3_msg(NoteStore, Msg, Hdr, Data, Addr, Port, Log) ->
end
end;
_ -> % 7.2.13.a
- ?vinfo("invalid securityEngineID: ~p",[SecEngineID]),
+ ?vinfo("7.2.13a - invalid securityEngineID: ~p",
+ [SecEngineID]),
discard({badSecurityEngineID, SecEngineID})
end;
diff --git a/lib/snmp/src/manager/snmpm_net_if.erl b/lib/snmp/src/manager/snmpm_net_if.erl
index 14d39933dc..07156dacd9 100644
--- a/lib/snmp/src/manager/snmpm_net_if.erl
+++ b/lib/snmp/src/manager/snmpm_net_if.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2004-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 2004-2010. All Rights Reserved.
+%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
-%%
+%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
-%%
+%%
%% %CopyrightEnd%
%%
@@ -81,6 +81,9 @@
-define(IRGC_TIMEOUT, timer:minutes(5)).
+-define(ATL_SEQNO_INITIAL, 1).
+-define(ATL_SEQNO_MAX, 2147483647).
+
%%%-------------------------------------------------------------------
%%% API
@@ -297,11 +300,29 @@ do_init_log(true) ->
{ok, Repair} = snmpm_config:system_info(audit_trail_log_repair),
Name = ?audit_trail_log_name,
File = filename:absname(?audit_trail_log_file, Dir),
- case snmp_log:create(Name, File, Size, Repair, true) of
- {ok, Log} ->
- {Log, Type};
- {error, Reason} ->
- throw({error, {failed_create_audit_log, Reason}})
+ case snmpm_config:system_info(audit_trail_log_seqno) of
+ {ok, true} ->
+ Initial = ?ATL_SEQNO_INITIAL,
+ Max = ?ATL_SEQNO_MAX,
+ Module = snmpm_config,
+ Function = increment_counter,
+ Args = [atl_seqno, Initial, Max],
+ SeqNoGen = {Module, Function, Args},
+ case snmp_log:create(Name, File,
+ SeqNoGen, Size, Repair, true) of
+ {ok, Log} ->
+ ?vdebug("log created: ~w", [Log]),
+ {Log, Type};
+ {error, Reason} ->
+ throw({error, {failed_create_audit_log, Reason}})
+ end;
+ _ ->
+ case snmp_log:create(Name, File, Size, Repair, true) of
+ {ok, Log} ->
+ {Log, Type};
+ {error, Reason} ->
+ throw({error, {failed_create_audit_log, Reason}})
+ end
end.
@@ -420,7 +441,7 @@ handle_info(Info, State) ->
%% Returns: any (ignored by gen_server)
%%--------------------------------------------------------------------
terminate(Reason, #state{log = Log, irgc = IrGcRef}) ->
- ?vdebug("terminate: ~p",[Reason]),
+ ?vdebug("terminate: ~p", [Reason]),
irgc_stop(IrGcRef),
%% Close logs
do_close_log(Log),
@@ -441,35 +462,59 @@ do_close_log(_) ->
%% Returns: {ok, NewState}
%%----------------------------------------------------------------------
-code_change({down, _Vsn}, OldState, downgrade_to_pre45) ->
- ?d("code_change(down) -> entry", []),
- #state{server = Server,
- note_store = NoteStore,
- sock = Sock,
- mpd_state = MpdState,
- log = Log,
- irgc = IrGcRef} = OldState,
- irgc_stop(IrGcRef),
- (catch ets:delete(snmpm_inform_request_table)),
- State = {state, Server, NoteStore, Sock, MpdState, Log},
+code_change({down, _Vsn}, OldState, downgrade_to_pre_4_14) ->
+ ?d("code_change(down, downgrade_to_pre_4_14) -> entry with"
+ "~n OldState: ~p", [OldState]),
+ #state{server = Server,
+ note_store = NoteStore,
+ sock = Sock,
+ mpd_state = MpdState,
+ log = {OldLog, Type},
+ irb = IRB,
+ irgc = IRGC} = OldState,
+ NewLog = snmp_log:downgrade(OldLog),
+ State =
+ {state, Server, NoteStore, Sock, MpdState, {NewLog, Type}, IRB, IRGC},
+ {ok, State};
+
+code_change({down, _Vsn}, OldState, downgrade_to_pre_4_16) ->
+ ?d("code_change(down, downgrade_to_pre_4_16) -> entry with"
+ "~n OldState: ~p", [OldState]),
+ {OldLog, Type} = OldState#state.log,
+ NewLog = snmp_log:downgrade(OldLog),
+ State = OldState#state{log = {NewLog, Type}},
{ok, State};
% upgrade
-code_change(_Vsn, OldState, upgrade_from_pre45) ->
- ?d("code_change(up) -> entry", []),
- {state, Server, NoteStore, Sock, MpdState, Log} = OldState,
- State = #state{server = Server,
- note_store = NoteStore,
- sock = Sock,
- mpd_state = MpdState,
- log = Log,
- irb = auto,
- irgc = undefined},
- ets:new(snmpm_inform_request_table,
- [set, protected, named_table, {keypos, 1}]),
+code_change(_Vsn, OldState, upgrade_from_pre_4_14) ->
+ ?d("code_change(up, upgrade_from_pre_4_14) -> entry with"
+ "~n OldState: ~p", [OldState]),
+ {state, Server, NoteStore, Sock, MpdState, {OldLog, Type}, IRB, IRGC} =
+ OldState,
+ NewLog = snmp_log:upgrade(OldLog),
+ State = #state{server = Server,
+ note_store = NoteStore,
+ sock = Sock,
+ mpd_state = MpdState,
+ log = {NewLog, Type},
+ irb = IRB,
+ irgc = IRGC,
+ filter = ?DEFAULT_FILTER_MODULE},
+ {ok, State};
+
+code_change(_Vsn, OldState, upgrade_from_pre_4_16) ->
+ ?d("code_change(up, upgrade_from_pre_4_16) -> entry with"
+ "~n OldState: ~p", [OldState]),
+ {OldLog, Type} = OldState#state.log,
+ NewLog = snmp_log:upgrade(OldLog),
+ State = OldState#state{log = {NewLog, Type}},
{ok, State};
code_change(_Vsn, State, _Extra) ->
+ ?d("code_change -> entry with"
+ "~n Vsn: ~p"
+ "~n State: ~p"
+ "~n Extra: ~p", [_Vsn, State, _Extra]),
{ok, State}.
diff --git a/lib/snmp/src/manager/snmpm_server.erl b/lib/snmp/src/manager/snmpm_server.erl
index 30aacc0ec3..1349a64172 100644
--- a/lib/snmp/src/manager/snmpm_server.erl
+++ b/lib/snmp/src/manager/snmpm_server.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2004-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 2004-2011. All Rights Reserved.
+%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
-%%
+%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
-%%
+%%
%% %CopyrightEnd%
%%
@@ -192,153 +192,142 @@ unregister_user(UserId) ->
%% -- [sync] get --
-sync_get(UserId, TargetName, CtxName, Oids) ->
- sync_get(UserId, TargetName, CtxName, Oids,
- ?SYNC_GET_TIMEOUT).
+sync_get(UserId, TargetName, CC, Oids) ->
+ sync_get(UserId, TargetName, CC, Oids, ?SYNC_GET_TIMEOUT).
-sync_get(UserId, TargetName, CtxName, Oids, Timeout) ->
- sync_get(UserId, TargetName, CtxName, Oids, Timeout, ?EXTRA_INFO).
+sync_get(UserId, TargetName, CC, Oids, Timeout) ->
+ sync_get(UserId, TargetName, CC, Oids, Timeout, ?EXTRA_INFO).
-sync_get(UserId, TargetName, CtxName, Oids, Timeout, ExtraInfo)
+sync_get(UserId, TargetName, CC, Oids, Timeout, ExtraInfo)
when is_list(TargetName) andalso
- is_list(CtxName) andalso
is_list(Oids) andalso
is_integer(Timeout) ->
- call({sync_get, self(), UserId, TargetName, CtxName, Oids, Timeout, ExtraInfo}).
+ call({sync_get, self(), UserId, TargetName, CC, Oids, Timeout, ExtraInfo}).
%% -- [async] get --
-async_get(UserId, TargetName, CtxName, Oids) ->
- async_get(UserId, TargetName, CtxName, Oids,
- ?DEFAULT_ASYNC_EXPIRE, ?EXTRA_INFO).
+async_get(UserId, TargetName, CC, Oids) ->
+ async_get(UserId, TargetName, CC, Oids, ?DEFAULT_ASYNC_EXPIRE, ?EXTRA_INFO).
-async_get(UserId, TargetName, CtxName, Oids, Expire) ->
- async_get(UserId, TargetName, CtxName, Oids, Expire, ?EXTRA_INFO).
+async_get(UserId, TargetName, CC, Oids, Expire) ->
+ async_get(UserId, TargetName, CC, Oids, Expire, ?EXTRA_INFO).
-async_get(UserId, TargetName, CtxName, Oids, Expire, ExtraInfo)
+async_get(UserId, TargetName, CC, Oids, Expire, ExtraInfo)
when (is_list(TargetName) andalso
- is_list(CtxName) andalso
is_list(Oids) andalso
is_integer(Expire) andalso (Expire >= 0)) ->
- call({async_get, self(), UserId, TargetName, CtxName, Oids, Expire,
- ExtraInfo}).
+ call({async_get, self(), UserId, TargetName, CC, Oids, Expire, ExtraInfo}).
%% -- [sync] get-next --
-sync_get_next(UserId, TargetName, CtxName, Oids) ->
- sync_get_next(UserId, TargetName, CtxName, Oids, ?SYNC_GET_TIMEOUT,
+sync_get_next(UserId, TargetName, CC, Oids) ->
+ sync_get_next(UserId, TargetName, CC, Oids, ?SYNC_GET_TIMEOUT,
?EXTRA_INFO).
-sync_get_next(UserId, TargetName, CtxName, Oids, Timeout) ->
- sync_get_next(UserId, TargetName, CtxName, Oids, Timeout, ?EXTRA_INFO).
+sync_get_next(UserId, TargetName, CC, Oids, Timeout) ->
+ sync_get_next(UserId, TargetName, CC, Oids, Timeout, ?EXTRA_INFO).
-sync_get_next(UserId, TargetName, CtxName, Oids, Timeout, ExtraInfo)
+sync_get_next(UserId, TargetName, CC, Oids, Timeout, ExtraInfo)
when is_list(TargetName) andalso
- is_list(CtxName) andalso
is_list(Oids) andalso
is_integer(Timeout) ->
- call({sync_get_next, self(), UserId, TargetName, CtxName, Oids, Timeout,
+ call({sync_get_next, self(), UserId, TargetName, CC, Oids, Timeout,
ExtraInfo}).
%% -- [async] get-next --
-async_get_next(UserId, TargetName, CtxName, Oids) ->
- async_get_next(UserId, TargetName, CtxName, Oids,
+async_get_next(UserId, TargetName, CC, Oids) ->
+ async_get_next(UserId, TargetName, CC, Oids,
?DEFAULT_ASYNC_EXPIRE, ?EXTRA_INFO).
-async_get_next(UserId, TargetName, CtxName, Oids, Expire) ->
- async_get_next(UserId, TargetName, CtxName, Oids, Expire, ?EXTRA_INFO).
+async_get_next(UserId, TargetName, CC, Oids, Expire) ->
+ async_get_next(UserId, TargetName, CC, Oids, Expire, ?EXTRA_INFO).
-async_get_next(UserId, TargetName, CtxName, Oids, Expire, ExtraInfo)
+async_get_next(UserId, TargetName, CC, Oids, Expire, ExtraInfo)
when (is_list(TargetName) andalso
- is_list(CtxName) andalso
is_list(Oids) andalso
is_integer(Expire) andalso (Expire >= 0)) ->
- call({async_get_next, self(), UserId, TargetName, CtxName, Oids,
+ call({async_get_next, self(), UserId, TargetName, CC, Oids,
Expire, ExtraInfo}).
%% -- [sync] get-bulk --
-sync_get_bulk(UserId, TargetName, NonRep, MaxRep, CtxName, Oids) ->
+sync_get_bulk(UserId, TargetName, NonRep, MaxRep, CC, Oids) ->
sync_get_bulk(UserId, TargetName,
- NonRep, MaxRep, CtxName, Oids,
+ NonRep, MaxRep, CC, Oids,
?SYNC_GET_TIMEOUT, ?EXTRA_INFO).
-sync_get_bulk(UserId, TargetName, NonRep, MaxRep, CtxName, Oids, Timeout) ->
+sync_get_bulk(UserId, TargetName, NonRep, MaxRep, CC, Oids, Timeout) ->
sync_get_bulk(UserId, TargetName,
- NonRep, MaxRep, CtxName, Oids,
+ NonRep, MaxRep, CC, Oids,
Timeout, ?EXTRA_INFO).
-sync_get_bulk(UserId, TargetName, NonRep, MaxRep, CtxName, Oids, Timeout,
+sync_get_bulk(UserId, TargetName, NonRep, MaxRep, CC, Oids, Timeout,
ExtraInfo)
when is_list(TargetName) andalso
is_integer(NonRep) andalso
is_integer(MaxRep) andalso
- is_list(CtxName) andalso
is_list(Oids) andalso
is_integer(Timeout) ->
call({sync_get_bulk, self(), UserId, TargetName,
- NonRep, MaxRep, CtxName, Oids, Timeout, ExtraInfo}).
+ NonRep, MaxRep, CC, Oids, Timeout, ExtraInfo}).
%% -- [async] get-bulk --
-async_get_bulk(UserId, TargetName, NonRep, MaxRep, CtxName, Oids) ->
+async_get_bulk(UserId, TargetName, NonRep, MaxRep, CC, Oids) ->
async_get_bulk(UserId, TargetName,
- NonRep, MaxRep, CtxName, Oids,
+ NonRep, MaxRep, CC, Oids,
?DEFAULT_ASYNC_EXPIRE, ?EXTRA_INFO).
-async_get_bulk(UserId, TargetName, NonRep, MaxRep, CtxName, Oids, Expire) ->
+async_get_bulk(UserId, TargetName, NonRep, MaxRep, CC, Oids, Expire) ->
async_get_bulk(UserId, TargetName,
- NonRep, MaxRep, CtxName, Oids,
+ NonRep, MaxRep, CC, Oids,
Expire, ?EXTRA_INFO).
-async_get_bulk(UserId, TargetName, NonRep, MaxRep, CtxName, Oids, Expire,
+async_get_bulk(UserId, TargetName, NonRep, MaxRep, CC, Oids, Expire,
ExtraInfo)
when is_list(TargetName) andalso
is_integer(NonRep) andalso
is_integer(MaxRep) andalso
- is_list(CtxName) andalso
is_list(Oids) andalso
is_integer(Expire) ->
call({async_get_bulk, self(), UserId, TargetName,
- NonRep, MaxRep, CtxName, Oids, Expire, ExtraInfo}).
+ NonRep, MaxRep, CC, Oids, Expire, ExtraInfo}).
%% -- [sync] set --
%% VarsAndValues is: {PlainOid, o|s|i, Value} (unknown mibs) | {Oid, Value}
-sync_set(UserId, TargetName, CtxName, VarsAndVals) ->
- sync_set(UserId, TargetName, CtxName, VarsAndVals,
+sync_set(UserId, TargetName, CC, VarsAndVals) ->
+ sync_set(UserId, TargetName, CC, VarsAndVals,
?SYNC_SET_TIMEOUT, ?EXTRA_INFO).
-sync_set(UserId, TargetName, CtxName, VarsAndVals, Timeout) ->
- sync_set(UserId, TargetName, CtxName, VarsAndVals,
+sync_set(UserId, TargetName, CC, VarsAndVals, Timeout) ->
+ sync_set(UserId, TargetName, CC, VarsAndVals,
Timeout, ?EXTRA_INFO).
-sync_set(UserId, TargetName, CtxName, VarsAndVals, Timeout, ExtraInfo)
+sync_set(UserId, TargetName, CC, VarsAndVals, Timeout, ExtraInfo)
when is_list(TargetName) andalso
- is_list(CtxName) andalso
is_list(VarsAndVals) andalso
is_integer(Timeout) ->
call({sync_set, self(), UserId, TargetName,
- CtxName, VarsAndVals, Timeout, ExtraInfo}).
+ CC, VarsAndVals, Timeout, ExtraInfo}).
%% -- [async] set --
-async_set(UserId, TargetName, CtxName, VarsAndVals) ->
- async_set(UserId, TargetName, CtxName, VarsAndVals,
+async_set(UserId, TargetName, CC, VarsAndVals) ->
+ async_set(UserId, TargetName, CC, VarsAndVals,
?DEFAULT_ASYNC_EXPIRE, ?EXTRA_INFO).
-async_set(UserId, TargetName, CtxName, VarsAndVals, Expire) ->
- async_set(UserId, TargetName, CtxName, VarsAndVals,
+async_set(UserId, TargetName, CC, VarsAndVals, Expire) ->
+ async_set(UserId, TargetName, CC, VarsAndVals,
Expire, ?EXTRA_INFO).
-async_set(UserId, TargetName, CtxName, VarsAndVals, Expire, ExtraInfo)
+async_set(UserId, TargetName, CC, VarsAndVals, Expire, ExtraInfo)
when (is_list(TargetName) andalso
- is_list(CtxName) andalso
is_list(VarsAndVals) andalso
is_integer(Expire) andalso (Expire >= 0)) ->
call({async_set, self(), UserId, TargetName,
- CtxName, VarsAndVals, Expire, ExtraInfo}).
+ CC, VarsAndVals, Expire, ExtraInfo}).
cancel_async_request(UserId, ReqId) ->
@@ -571,11 +560,11 @@ handle_call({unregister_user, UserId}, _From, State) ->
%% We will reply to this request later, when the reply comes in from the
%% agent, or when the timeout hits (unless we get an error now).
-handle_call({sync_get, Pid, UserId, TargetName, CtxName, Oids, Timeout, ExtraInfo},
+handle_call({sync_get, Pid, UserId, TargetName, CC, Oids, Timeout, ExtraInfo},
From, State) ->
- ?vlog("received sync_get [~p] request", [CtxName]),
+ ?vlog("received sync_get [~p] request", [CC]),
case (catch handle_sync_get(Pid,
- UserId, TargetName, CtxName, Oids,
+ UserId, TargetName, CC, Oids,
Timeout, ExtraInfo, From, State)) of
ok ->
{noreply, State};
@@ -584,10 +573,10 @@ handle_call({sync_get, Pid, UserId, TargetName, CtxName, Oids, Timeout, ExtraInf
end;
-handle_call({sync_get_next, Pid, UserId, TargetName, CtxName, Oids, Timeout, ExtraInfo}, From, State) ->
- ?vlog("received sync_get_next [~p] request", [CtxName]),
+handle_call({sync_get_next, Pid, UserId, TargetName, CC, Oids, Timeout, ExtraInfo}, From, State) ->
+ ?vlog("received sync_get_next [~p] request", [CC]),
case (catch handle_sync_get_next(Pid,
- UserId, TargetName, CtxName, Oids,
+ UserId, TargetName, CC, Oids,
Timeout, ExtraInfo, From, State)) of
ok ->
{noreply, State};
@@ -598,11 +587,11 @@ handle_call({sync_get_next, Pid, UserId, TargetName, CtxName, Oids, Timeout, Ext
%% Check agent version? This op not in v1
handle_call({sync_get_bulk, Pid, UserId, TargetName,
- NonRep, MaxRep, CtxName, Oids, Timeout, ExtraInfo},
+ NonRep, MaxRep, CC, Oids, Timeout, ExtraInfo},
From, State) ->
- ?vlog("received sync_get_bulk [~p] request", [CtxName]),
+ ?vlog("received sync_get_bulk [~p] request", [CC]),
case (catch handle_sync_get_bulk(Pid,
- UserId, TargetName, CtxName,
+ UserId, TargetName, CC,
NonRep, MaxRep, Oids,
Timeout, ExtraInfo, From, State)) of
ok ->
@@ -613,11 +602,11 @@ handle_call({sync_get_bulk, Pid, UserId, TargetName,
handle_call({sync_set, Pid, UserId, TargetName,
- CtxName, VarsAndVals, Timeout, ExtraInfo},
+ CC, VarsAndVals, Timeout, ExtraInfo},
From, State) ->
- ?vlog("received sync_set [~p] request", [CtxName]),
+ ?vlog("received sync_set [~p] request", [CC]),
case (catch handle_sync_set(Pid,
- UserId, TargetName, CtxName, VarsAndVals,
+ UserId, TargetName, CC, VarsAndVals,
Timeout, ExtraInfo, From, State)) of
ok ->
{noreply, State};
@@ -627,40 +616,40 @@ handle_call({sync_set, Pid, UserId, TargetName,
handle_call({async_get, Pid, UserId, TargetName,
- CtxName, Oids, Expire, ExtraInfo},
+ CC, Oids, Expire, ExtraInfo},
_From, State) ->
- ?vlog("received async_get [~p] request", [CtxName]),
- Reply = (catch handle_async_get(Pid, UserId, TargetName, CtxName, Oids,
+ ?vlog("received async_get [~p] request", [CC]),
+ Reply = (catch handle_async_get(Pid, UserId, TargetName, CC, Oids,
Expire, ExtraInfo, State)),
{reply, Reply, State};
handle_call({async_get_next, Pid, UserId, TargetName,
- CtxName, Oids, Expire, ExtraInfo},
+ CC, Oids, Expire, ExtraInfo},
_From, State) ->
- ?vlog("received async_get_next [~p] request", [CtxName]),
- Reply = (catch handle_async_get_next(Pid, UserId, TargetName, CtxName,
+ ?vlog("received async_get_next [~p] request", [CC]),
+ Reply = (catch handle_async_get_next(Pid, UserId, TargetName, CC,
Oids, Expire, ExtraInfo, State)),
{reply, Reply, State};
%% Check agent version? This op not in v1
handle_call({async_get_bulk, Pid, UserId, TargetName,
- NonRep, MaxRep, CtxName, Oids, Expire, ExtraInfo},
+ NonRep, MaxRep, CC, Oids, Expire, ExtraInfo},
_From, State) ->
- ?vlog("received async_get_bulk [~p] request", [CtxName]),
+ ?vlog("received async_get_bulk [~p] request", [CC]),
Reply = (catch handle_async_get_bulk(Pid,
- UserId, TargetName, CtxName,
+ UserId, TargetName, CC,
NonRep, MaxRep, Oids,
Expire, ExtraInfo, State)),
{reply, Reply, State};
handle_call({async_set, Pid, UserId, TargetName,
- CtxName, VarsAndVals, Expire, ExtraInfo},
+ CC, VarsAndVals, Expire, ExtraInfo},
_From, State) ->
- ?vlog("received async_set [~p] request", [CtxName]),
- Reply = (catch handle_async_set(Pid, UserId, TargetName, CtxName,
+ ?vlog("received async_set [~p] request", [CC]),
+ Reply = (catch handle_async_set(Pid, UserId, TargetName, CC,
VarsAndVals, Expire, ExtraInfo, State)),
{reply, Reply, State};
@@ -899,18 +888,18 @@ terminate(Reason, #state{gct = GCT}) ->
%%
%%----------------------------------------------------------------------
-handle_sync_get(Pid, UserId, TargetName, CtxName, Oids, Timeout, ExtraInfo,
+handle_sync_get(Pid, UserId, TargetName, CC, Oids, Timeout, ExtraInfo,
From, State) ->
?vtrace("handle_sync_get -> entry with"
"~n Pid: ~p"
"~n UserId: ~p"
"~n TargetName: ~p"
- "~n CtxName: ~p"
+ "~n CC: ~p"
"~n Oids: ~p"
"~n Timeout: ~p"
"~n From: ~p",
- [Pid, UserId, TargetName, CtxName, Oids, Timeout, From]),
- case agent_data(TargetName, CtxName) of
+ [Pid, UserId, TargetName, CC, Oids, Timeout, From]),
+ case agent_data(TargetName, CC) of
{ok, RegType, Addr, Port, Vsn, MsgData} ->
?vtrace("handle_sync_get -> send a ~p message", [Vsn]),
ReqId = send_get_request(Oids, Vsn, MsgData, Addr, Port,
@@ -941,18 +930,18 @@ handle_sync_get(Pid, UserId, TargetName, CtxName, Oids, Timeout, ExtraInfo,
end.
-handle_sync_get_next(Pid, UserId, TargetName, CtxName, Oids, Timeout,
+handle_sync_get_next(Pid, UserId, TargetName, CC, Oids, Timeout,
ExtraInfo, From, State) ->
?vtrace("handle_sync_get_next -> entry with"
"~n Pid: ~p"
"~n UserId: ~p"
"~n TargetName: ~p"
- "~n CtxName: ~p"
+ "~n CC: ~p"
"~n Oids: ~p"
"~n Timeout: ~p"
"~n From: ~p",
- [Pid, UserId, TargetName, CtxName, Oids, Timeout, From]),
- case agent_data(TargetName, CtxName) of
+ [Pid, UserId, TargetName, CC, Oids, Timeout, From]),
+ case agent_data(TargetName, CC) of
{ok, RegType, Addr, Port, Vsn, MsgData} ->
?vtrace("handle_sync_get_next -> send a ~p message", [Vsn]),
ReqId = send_get_next_request(Oids, Vsn, MsgData,
@@ -984,22 +973,22 @@ handle_sync_get_next(Pid, UserId, TargetName, CtxName, Oids, Timeout,
end.
-handle_sync_get_bulk(Pid, UserId, TargetName, CtxName,
+handle_sync_get_bulk(Pid, UserId, TargetName, CC,
NonRep, MaxRep, Oids, Timeout,
ExtraInfo, From, State) ->
?vtrace("handle_sync_get_bulk -> entry with"
"~n Pid: ~p"
"~n UserId: ~p"
"~n TargetName: ~p"
- "~n CtxName: ~p"
+ "~n CC: ~p"
"~n NonRep: ~p"
"~n MaxRep: ~p"
"~n Oids: ~p"
"~n Timeout: ~p"
"~n From: ~p",
- [Pid, UserId, TargetName, CtxName, NonRep, MaxRep, Oids,
+ [Pid, UserId, TargetName, CC, NonRep, MaxRep, Oids,
Timeout, From]),
- case agent_data(TargetName, CtxName) of
+ case agent_data(TargetName, CC) of
{ok, RegType, Addr, Port, Vsn, MsgData} ->
?vtrace("handle_sync_get_bulk -> send a ~p message", [Vsn]),
ReqId = send_get_bulk_request(Oids, Vsn, MsgData, Addr, Port,
@@ -1031,18 +1020,18 @@ handle_sync_get_bulk(Pid, UserId, TargetName, CtxName,
end.
-handle_sync_set(Pid, UserId, TargetName, CtxName, VarsAndVals, Timeout,
+handle_sync_set(Pid, UserId, TargetName, CC, VarsAndVals, Timeout,
ExtraInfo, From, State) ->
?vtrace("handle_sync_set -> entry with"
"~n Pid: ~p"
"~n UserId: ~p"
"~n TargetName: ~p"
- "~n CtxName: ~p"
+ "~n CC: ~p"
"~n VarsAndVals: ~p"
"~n Timeout: ~p"
"~n From: ~p",
- [Pid, UserId, TargetName, CtxName, VarsAndVals, Timeout, From]),
- case agent_data(TargetName, CtxName) of
+ [Pid, UserId, TargetName, CC, VarsAndVals, Timeout, From]),
+ case agent_data(TargetName, CC) of
{ok, RegType, Addr, Port, Vsn, MsgData} ->
?vtrace("handle_sync_set -> send a ~p message", [Vsn]),
ReqId = send_set_request(VarsAndVals, Vsn, MsgData,
@@ -1074,17 +1063,17 @@ handle_sync_set(Pid, UserId, TargetName, CtxName, VarsAndVals, Timeout,
end.
-handle_async_get(Pid, UserId, TargetName, CtxName, Oids, Expire, ExtraInfo,
+handle_async_get(Pid, UserId, TargetName, CC, Oids, Expire, ExtraInfo,
State) ->
?vtrace("handle_async_get -> entry with"
"~n Pid: ~p"
"~n UserId: ~p"
"~n TargetName: ~p"
- "~n CtxName: ~p"
+ "~n CC: ~p"
"~n Oids: ~p"
"~n Expire: ~p",
- [Pid, UserId, TargetName, CtxName, Oids, Expire]),
- case agent_data(TargetName, CtxName) of
+ [Pid, UserId, TargetName, CC, Oids, Expire]),
+ case agent_data(TargetName, CC) of
{ok, RegType, Addr, Port, Vsn, MsgData} ->
?vtrace("handle_async_get -> send a ~p message", [Vsn]),
ReqId = send_get_request(Oids, Vsn, MsgData, Addr, Port,
@@ -1112,17 +1101,17 @@ handle_async_get(Pid, UserId, TargetName, CtxName, Oids, Expire, ExtraInfo,
end.
-handle_async_get_next(Pid, UserId, TargetName, CtxName, Oids, Expire,
+handle_async_get_next(Pid, UserId, TargetName, CC, Oids, Expire,
ExtraInfo, State) ->
?vtrace("handle_async_get_next -> entry with"
"~n Pid: ~p"
"~n UserId: ~p"
"~n TargetName: ~p"
- "~n CtxName: ~p"
+ "~n CC: ~p"
"~n Oids: ~p"
"~n Expire: ~p",
- [Pid, UserId, TargetName, CtxName, Oids, Expire]),
- case agent_data(TargetName, CtxName) of
+ [Pid, UserId, TargetName, CC, Oids, Expire]),
+ case agent_data(TargetName, CC) of
{ok, RegType, Addr, Port, Vsn, MsgData} ->
?vtrace("handle_async_get_next -> send a ~p message", [Vsn]),
ReqId = send_get_next_request(Oids, Vsn, MsgData,
@@ -1150,20 +1139,20 @@ handle_async_get_next(Pid, UserId, TargetName, CtxName, Oids, Expire,
end.
-handle_async_get_bulk(Pid, UserId, TargetName, CtxName,
+handle_async_get_bulk(Pid, UserId, TargetName, CC,
NonRep, MaxRep, Oids, Expire,
ExtraInfo, State) ->
?vtrace("handle_async_get_bulk -> entry with"
"~n Pid: ~p"
"~n UserId: ~p"
"~n TargetName: ~p"
- "~n CtxName: ~p"
+ "~n CC: ~p"
"~n NonRep: ~p"
"~n MaxRep: ~p"
"~n Oids: ~p"
"~n Expire: ~p",
- [Pid, UserId, TargetName, CtxName, NonRep, MaxRep, Oids, Expire]),
- case agent_data(TargetName, CtxName) of
+ [Pid, UserId, TargetName, CC, NonRep, MaxRep, Oids, Expire]),
+ case agent_data(TargetName, CC) of
{ok, RegType, Addr, Port, Vsn, MsgData} ->
?vtrace("handle_async_get_bulk -> send a ~p message", [Vsn]),
ReqId = send_get_bulk_request(Oids, Vsn, MsgData, Addr, Port,
@@ -1190,17 +1179,17 @@ handle_async_get_bulk(Pid, UserId, TargetName, CtxName,
end.
-handle_async_set(Pid, UserId, TargetName, CtxName, VarsAndVals, Expire,
+handle_async_set(Pid, UserId, TargetName, CC, VarsAndVals, Expire,
ExtraInfo, State) ->
?vtrace("handle_async_set -> entry with"
"~n Pid: ~p"
"~n UserId: ~p"
"~n TargetName: ~p"
- "~n CtxName: ~p"
+ "~n CC: ~p"
"~n VarsAndVals: ~p"
"~n Expire: ~p",
- [Pid, UserId, TargetName, CtxName, VarsAndVals, Expire]),
- case agent_data(TargetName, CtxName) of
+ [Pid, UserId, TargetName, CC, VarsAndVals, Expire]),
+ case agent_data(TargetName, CC) of
{ok, RegType, Addr, Port, Vsn, MsgData} ->
?vtrace("handle_async_set -> send a ~p message", [Vsn]),
ReqId = send_set_request(VarsAndVals, Vsn, MsgData,
@@ -2798,22 +2787,24 @@ request_id() ->
%%----------------------------------------------------------------------
+agent_data(TargetName, {CtxName, Community}) ->
+ agent_data(TargetName, CtxName, [{community, Community}]);
agent_data(TargetName, CtxName) ->
agent_data(TargetName, CtxName, []).
agent_data(TargetName, CtxName, Config) ->
case snmpm_config:agent_info(TargetName, all) of
{ok, Info} ->
- {value, {_, Version}} = lists:keysearch(version, 1, Info),
+ Version = agent_data_item(version, Info),
MsgData =
case Version of
v3 ->
DefSecModel = agent_data_item(sec_model, Info),
DefSecName = agent_data_item(sec_name, Info),
DefSecLevel = agent_data_item(sec_level, Info),
-
+
EngineId = agent_data_item(engine_id, Info),
-
+
SecModel = agent_data_item(sec_model,
Config,
DefSecModel),
@@ -2829,7 +2820,7 @@ agent_data(TargetName, CtxName, Config) ->
_ ->
DefComm = agent_data_item(community, Info),
DefSecModel = agent_data_item(sec_model, Info),
-
+
Comm = agent_data_item(community,
Config,
DefComm),
@@ -2848,8 +2839,12 @@ agent_data(TargetName, CtxName, Config) ->
end.
agent_data_item(Item, Info) ->
- {value, {_, Val}} = lists:keysearch(Item, 1, Info),
- Val.
+ case lists:keysearch(Item, 1, Info) of
+ {value, {_, Val}} ->
+ Val;
+ false ->
+ throw({error, {not_found, Item, Info}})
+ end.
agent_data_item(Item, Info, Default) ->
case lists:keysearch(Item, 1, Info) of
diff --git a/lib/snmp/src/misc/snmp_config.erl b/lib/snmp/src/misc/snmp_config.erl
index ad41eaf160..c066680160 100644
--- a/lib/snmp/src/misc/snmp_config.erl
+++ b/lib/snmp/src/misc/snmp_config.erl
@@ -1,19 +1,19 @@
%%
%% %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
%% 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%
%%
@@ -327,10 +327,15 @@ config_agent_sys() ->
ATLRepair = ask("23f. Audit trail log repair "
"(true/false/truncate/snmp_repair)?", "true",
fun verify_atl_repair/1),
+ ATLSeqNo = ask("23g. Audit trail log "
+ "sequence-numbering (true/false)?",
+ "false",
+ fun verify_atl_seqno/1),
[{audit_trail_log, [{type, ATLType},
{dir, ATLDir},
{size, ATLSize},
- {repair, ATLRepair}]}];
+ {repair, ATLRepair},
+ {seqno, ATLSeqNo}]}];
no ->
[]
end,
@@ -400,8 +405,39 @@ config_agent_sys() ->
NetIf = [{module, NetIfMod},
{verbosity, NetIfVerb},
{options, NetIfOpts}],
+ TermDiscoEnable = ask("26a. Allow terminating discovery "
+ "(true/false)?", "true",
+ fun verify_bool/1),
+ TermDiscoConf =
+ case TermDiscoEnable of
+ true ->
+ TermDiscoStage2 =
+ ask("26b. Second stage behaviour "
+ "(discovery/plain)?", "discovery",
+ fun verify_term_disco_behaviour/1),
+ TermDiscoTrigger =
+ ask("26c. Trigger username "
+ "(default/a string)?", "default",
+ fun verify_term_disco_trigger_username/1),
+ [{enable, TermDiscoEnable},
+ {stage2, TermDiscoStage2},
+ {trigger_username, TermDiscoTrigger}];
+ false ->
+ [{enable, TermDiscoEnable},
+ {stage2, discovery},
+ {trigger_username, ""}]
+ end,
+ OrigDiscoEnable = ask("27a. Allow originating discovery "
+ "(true/false)?", "true",
+ fun verify_bool/1),
+ OrigDiscoConf =
+ [{enable, OrigDiscoEnable}],
+ DiscoveryConfig =
+ [{terminating, TermDiscoConf},
+ {originating, OrigDiscoConf}],
[{agent_type, master},
{agent_verbosity, MasterAgentVerb},
+ {discovery, DiscoveryConfig},
{config, [{dir, ConfigDir},
{force_load, ForceLoad},
{verbosity, ConfigVerb}]},
@@ -644,23 +680,31 @@ config_manager_sys() ->
"(y/n)?",
"n", fun verify_yes_or_no/1) of
yes ->
- ATLDir = ask("19b. Where to store the "
+ ATLType = ask("19b. Audit trail log type "
+ "(write/read_write)?",
+ "read_write", fun verify_atl_type/1),
+ ATLDir = ask("19c. Where to store the "
"audit trail log?",
DefDir, fun verify_dir/1),
- ATLMaxFiles = ask("19c. Max number of files?",
+ ATLMaxFiles = ask("19d. Max number of files?",
"10",
fun verify_pos_integer/1),
- ATLMaxBytes = ask("19d. Max size (in bytes) "
+ ATLMaxBytes = ask("19e. Max size (in bytes) "
"of each file?",
"10240",
fun verify_pos_integer/1),
ATLSize = {ATLMaxBytes, ATLMaxFiles},
- ATLRepair = ask("19e. Audit trail log repair "
+ ATLRepair = ask("19f. Audit trail log repair "
"(true/false/truncate/snmp_repair)?", "true",
fun verify_atl_repair/1),
- [{audit_trail_log, [{dir, ATLDir},
+ ATLSeqNo = ask("19g. Audit trail log sequence-numbering "
+ "(true/false)?", "false",
+ fun verify_atl_seqno/1),
+ [{audit_trail_log, [{type, ATLType},
+ {dir, ATLDir},
{size, ATLSize},
- {repair, ATLRepair}]}];
+ {repair, ATLRepair},
+ {seqno, ATLSeqNo}]}];
no ->
[]
end,
@@ -1180,6 +1224,13 @@ verify_atl_repair("snmp_repair") ->
verify_atl_repair(R) ->
{error, "invalid audit trail log repair: " ++ R}.
+verify_atl_seqno("true") ->
+ {ok, true};
+verify_atl_seqno("false") ->
+ {ok, false};
+verify_atl_seqno(SN) ->
+ {error, "invalid audit trail log seqno: " ++ SN}.
+
verify_pos_integer(I0) ->
case (catch list_to_integer(I0)) of
@@ -1237,6 +1288,18 @@ verify_irb_user(TO) ->
end.
+verify_term_disco_behaviour("discovery") ->
+ {ok, discovery};
+verify_term_disco_behaviour("plain") ->
+ {ok, plain};
+verify_term_disco_behaviour(B) ->
+ {error, "invalid terminating discovery behaviour: " ++ B}.
+
+verify_term_disco_trigger_username("default") ->
+ {ok, ""};
+verify_term_disco_trigger_username(Trigger) ->
+ {ok, Trigger}.
+
verify_user_id(UserId) when is_list(UserId) ->
case (catch list_to_atom(UserId)) of
@@ -1743,7 +1806,7 @@ write_agent_snmp_notify_conf(Dir, NotifyType) ->
"%% {\"standard inform\", \"std_inform\", inform}.\n"
"%%\n\n",
Hdr = header() ++ Comment,
- Conf = [{"stadard_trap", "std_trap", NotifyType}],
+ Conf = [{"standard trap", "std_trap", NotifyType}],
write_agent_notify_config(Dir, Hdr, Conf).
write_agent_notify_config(Dir, Hdr, Conf) ->
@@ -2096,6 +2159,10 @@ write_sys_config_file_agent_opt(Fid, {audit_trail_log, Opts}) ->
ok = io:format(Fid, " {audit_trail_log, [", []),
write_sys_config_file_agent_atl_opts(Fid, Opts),
ok = io:format(Fid, "}", []);
+write_sys_config_file_agent_opt(Fid, {discovery, Opts}) ->
+ ok = io:format(Fid, " {discovery, [", []),
+ write_sys_config_file_agent_disco_opts(Fid, Opts),
+ ok = io:format(Fid, "}", []);
write_sys_config_file_agent_opt(Fid, {net_if, Opts}) ->
ok = io:format(Fid, " {net_if, ~w}", [Opts]);
write_sys_config_file_agent_opt(Fid, {mib_server, Opts}) ->
@@ -2139,7 +2206,58 @@ write_sys_config_file_agent_atl_opt(Fid, {type, Type}) ->
write_sys_config_file_agent_atl_opt(Fid, {size, Size}) ->
ok = io:format(Fid, "{size, ~w}", [Size]);
write_sys_config_file_agent_atl_opt(Fid, {repair, Rep}) ->
- ok = io:format(Fid, "{repair, ~w}", [Rep]).
+ ok = io:format(Fid, "{repair, ~w}", [Rep]);
+write_sys_config_file_agent_atl_opt(Fid, {seqno, SeqNo}) ->
+ ok = io:format(Fid, "{seqno, ~w}", [SeqNo]).
+
+
+%% These options are allways there
+write_sys_config_file_agent_disco_opts(Fid, [Opt]) ->
+ write_sys_config_file_agent_disco_opt(Fid, Opt),
+ ok = io:format(Fid, "]", []),
+ ok;
+write_sys_config_file_agent_disco_opts(Fid, [Opt|Opts]) ->
+ write_sys_config_file_agent_disco_opt(Fid, Opt),
+ ok = io:format(Fid, ", ", []),
+ write_sys_config_file_agent_disco_opts(Fid, Opts).
+
+write_sys_config_file_agent_disco_opt(Fid, {terminating, Opts}) ->
+ ok = io:format(Fid, "{terminating, [", []),
+ write_sys_config_file_agent_term_disco_opts(Fid, Opts),
+ ok = io:format(Fid, "}", []);
+write_sys_config_file_agent_disco_opt(Fid, {originating, Opts}) ->
+ ok = io:format(Fid, "{originating, [", []),
+ write_sys_config_file_agent_orig_disco_opts(Fid, Opts),
+ ok = io:format(Fid, "}", []).
+
+write_sys_config_file_agent_term_disco_opts(Fid, [Opt]) ->
+ write_sys_config_file_agent_term_disco_opt(Fid, Opt),
+ ok = io:format(Fid, "]", []),
+ ok;
+write_sys_config_file_agent_term_disco_opts(Fid, [Opt|Opts]) ->
+ write_sys_config_file_agent_term_disco_opt(Fid, Opt),
+ ok = io:format(Fid, ", ", []),
+ write_sys_config_file_agent_term_disco_opts(Fid, Opts).
+
+write_sys_config_file_agent_term_disco_opt(Fid, {enable, Enable}) ->
+ ok = io:format(Fid, "{enable, ~w}", [Enable]);
+write_sys_config_file_agent_term_disco_opt(Fid, {stage2, Stage2}) ->
+ ok = io:format(Fid, "{stage2, ~w}", [Stage2]);
+write_sys_config_file_agent_term_disco_opt(Fid, {trigger_username, Trigger}) ->
+ ok = io:format(Fid, "{trigger_username, \"~s\"}", [Trigger]).
+
+write_sys_config_file_agent_orig_disco_opts(Fid, [Opt]) ->
+ write_sys_config_file_agent_orig_disco_opt(Fid, Opt),
+ ok = io:format(Fid, "]", []),
+ ok;
+write_sys_config_file_agent_orig_disco_opts(Fid, [Opt|Opts]) ->
+ write_sys_config_file_agent_orig_disco_opt(Fid, Opt),
+ ok = io:format(Fid, ", ", []),
+ write_sys_config_file_agent_orig_disco_opts(Fid, Opts).
+
+write_sys_config_file_agent_orig_disco_opt(Fid, {enable, Enable}) ->
+ ok = io:format(Fid, "{enable, ~w}", [Enable]).
+
write_sys_config_file_manager_opts(Fid, [Opt]) ->
diff --git a/lib/snmp/src/misc/snmp_log.erl b/lib/snmp/src/misc/snmp_log.erl
index c3932ccc08..f9aa911817 100644
--- a/lib/snmp/src/misc/snmp_log.erl
+++ b/lib/snmp/src/misc/snmp_log.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%
%%
@@ -21,12 +21,19 @@
-export([
- create/4, create/5,
+ create/4, create/5, create/6,
change_size/2, close/1, sync/1, info/1,
log/4,
log_to_txt/5, log_to_txt/6, log_to_txt/7,
log_to_io/4, log_to_io/5, log_to_io/6
]).
+-export([
+ upgrade/1, upgrade/2,
+ downgrade/1
+ ]).
+-export([
+ validate/1, validate/2
+ ]).
-define(SNMP_USE_V3, true).
@@ -38,45 +45,105 @@
-define(LOG_FORMAT, internal).
-define(LOG_TYPE, wrap).
+-record(snmp_log, {id, seqno}).
+
%% --------------------------------------------------------------------
%% Exported functions
%% --------------------------------------------------------------------
+upgrade(Log) when is_record(Log, snmp_log) ->
+ Log;
+upgrade(Log) ->
+ upgrade(Log, disabled).
+
+upgrade(Log, _SeqNoGen) when is_record(Log, snmp_log) ->
+ Log;
+upgrade(Log, {M, F, A} = SeqNoGen)
+ when (is_atom(M) andalso is_atom(F) andalso is_list(A)) ->
+ #snmp_log{id = Log, seqno = SeqNoGen};
+upgrade(Log, SeqNoGen)
+ when is_function(SeqNoGen, 0) ->
+ #snmp_log{id = Log, seqno = SeqNoGen};
+upgrade(Log, disabled = SeqNoGen) ->
+ #snmp_log{id = Log, seqno = SeqNoGen}.
+
+downgrade(#snmp_log{id = Log}) ->
+ Log;
+downgrade(Log) ->
+ Log.
+
%% -- create ---
create(Name, File, Size, Repair) ->
- create(Name, File, Size, Repair, false).
-
-create(Name, File, Size, Repair, Notify) ->
+ create(Name, File, disabled, Size, Repair, false).
+
+create(Name, File, Size, Repair, Notify)
+ when (((Repair =:= true) orelse
+ (Repair =:= false) orelse
+ (Repair =:= truncate) orelse
+ (Repair =:= snmp_repair)) andalso
+ ((Notify =:= true) orelse
+ (Notify =:= false))) ->
+ create(Name, File, disabled, Size, Repair, Notify);
+create(Name, File, SeqNoGen, Size, Repair) ->
+ create(Name, File, SeqNoGen, Size, Repair, false).
+
+create(Name, File, SeqNoGen, Size, Repair, Notify)
+ when (((Repair =:= true) orelse
+ (Repair =:= false) orelse
+ (Repair =:= truncate) orelse
+ (Repair =:= snmp_repair)) andalso
+ ((Notify =:= true) orelse
+ (Notify =:= false))) ->
?vtrace("create -> entry with"
- "~n Name: ~p"
- "~n File: ~p"
- "~n Size: ~p"
- "~n Repair: ~p"
- "~n Notify: ~p", [Name, File, Size, Repair, Notify]),
- log_open(Name, File, Size, Repair, Notify).
+ "~n Name: ~p"
+ "~n File: ~p"
+ "~n SeqNoGen: ~p"
+ "~n Size: ~p"
+ "~n Repair: ~p"
+ "~n Notify: ~p", [Name, File, SeqNoGen, Size, Repair, Notify]),
+ log_open(Name, File, SeqNoGen, Size, Repair, Notify);
+create(Name, File, SeqNoGen, Size, Repair, Notify) ->
+ {error, {bad_args, Name, File, SeqNoGen, Size, Repair, Notify}}.
+
%% -- close ---
-close(Log) ->
+close(#snmp_log{id = Log}) ->
?vtrace("close -> entry with"
"~n Log: ~p", [Log]),
+ do_close(Log);
+close(Log) ->
+ do_close(Log).
+
+do_close(Log) ->
disk_log:close(Log).
%% -- close ---
+sync(#snmp_log{id = Log}) ->
+ do_sync(Log);
sync(Log) ->
+ do_sync(Log).
+
+do_sync(Log) ->
?vtrace("sync -> entry with"
"~n Log: ~p", [Log]),
disk_log:sync(Log).
+
%% -- info ---
+info(#snmp_log{id = Log}) ->
+ do_info(Log);
info(Log) ->
+ do_info(Log).
+
+do_info(Log) ->
case disk_log:info(Log) of
Info when is_list(Info) ->
Items = [no_current_bytes, no_current_items,
@@ -97,6 +164,138 @@ info_filter([Item|Items], Info, Acc) ->
end.
+%% -- validate --
+
+%% This function is used to "validate" a log.
+%% At present this means making sure all entries
+%% are in the proper order, and if sequence numbering
+%% is used that no entries are missing.
+%% It is intended to be used for testing.
+
+validate(Log) ->
+ validate(Log, false).
+
+validate(#snmp_log{id = Log}, SeqNoReq) ->
+ validate(Log, SeqNoReq);
+validate(Log, SeqNoReq)
+ when ((SeqNoReq =:= true) orelse (SeqNoReq =:= false)) ->
+ Validator =
+ fun({Timestamp, SeqNo, _Packet, _Addr, _Port}, {PrevTS, PrevSN}) ->
+ ?vtrace("validating log entry when"
+ "~n Timestamp: ~p"
+ "~n SeqNo: ~p"
+ "~n PrevTS: ~p"
+ "~n PrevSN: ~p",
+ [Timestamp, SeqNo, PrevTS, PrevSN]),
+ validate_timestamp(PrevTS, Timestamp),
+ validate_seqno(PrevSN, SeqNo),
+ {Timestamp, SeqNo};
+
+ ({Timestamp, _Packet, _Addr, _Port}, {PrevTS, _PrevSN}) when SeqNoReq =:= true ->
+ ?vtrace("validating log entry when"
+ "~n Timestamp: ~p"
+ "~n PrevTS: ~p",
+ [Timestamp, PrevTS]),
+ throw({error, {missing_seqno, Timestamp}});
+
+ ({Timestamp, _Packet, _Addr, _Port}, {PrevTS, PrevSN}) ->
+ ?vtrace("validating log entry when"
+ "~n Timestamp: ~p"
+ "~n PrevTS: ~p",
+ [Timestamp, PrevTS]),
+ validate_timestamp(PrevTS, Timestamp),
+ {Timestamp, PrevSN};
+
+ (E, Acc) ->
+ ?vtrace("validating bad log entry when"
+ "~n E: ~p"
+ "~n Acc: ~p",
+ [E, Acc]),
+ throw({error, {bad_entry, E, Acc}})
+ end,
+ try
+ begin
+ validate_loop(disk_log:chunk(Log, start),
+ Log, Validator, first, first)
+ end
+ catch
+ throw:Error ->
+ Error
+ end.
+
+%% We shall check that TS2 >= TS1
+validate_timestamp(first, _TS2) ->
+ ok;
+validate_timestamp({LT1, UT1} = TS1, {LT2, UT2} = TS2) ->
+ LT1_Secs = calendar:datetime_to_gregorian_seconds(LT1),
+ UT1_Secs = calendar:datetime_to_gregorian_seconds(UT1),
+ LT2_Secs = calendar:datetime_to_gregorian_seconds(LT2),
+ UT2_Secs = calendar:datetime_to_gregorian_seconds(UT2),
+ case ((LT2_Secs >= LT1_Secs) andalso (UT2_Secs >= UT1_Secs)) of
+ true ->
+ ok;
+ false ->
+ throw({error, {invalid_timestamp, TS1, TS2}})
+ end;
+validate_timestamp(TS1, TS2) ->
+ throw({error, {bad_timestamp, TS1, TS2}}).
+
+
+%% The usual case when SN2 = SN1 + 1
+validate_seqno(first, SN2)
+ when is_integer(SN2) >= 1 ->
+ ok;
+
+%% The usual case when SN2 = SN1 + 1
+validate_seqno(SN1, SN2)
+ when is_integer(SN1) andalso is_integer(SN2) andalso
+ (SN2 =:= (SN1 + 1)) andalso (SN1 >= 1) ->
+ ok;
+
+%% The case when we have a wrap
+validate_seqno(SN1, SN2)
+ when is_integer(SN1) andalso is_integer(SN2) andalso
+ (SN2 < SN1) andalso (SN2 >= 1) ->
+ ok;
+
+%% And everything else must be an error...
+validate_seqno(SN1, SN2) ->
+ throw({error, {bad_seqno, SN1, SN2}}).
+
+validate_loop(eof, _Log, _Validatior, _PrevTS, _PrevSN) ->
+ ok;
+validate_loop({error, _} = Error, _Log, _Validator, _PrevTS, _PrevSN) ->
+ Error;
+validate_loop({corrupt_log_file, _} = Reason,
+ _Log, _Validator, _PrevTS, _PrevSN) ->
+ {error, Reason};
+validate_loop({Cont, Terms}, Log, Validator, PrevTS, PrevSN) ->
+ ?vtrace("validate_loop -> entry with"
+ "~n Terms: ~p"
+ "~n PrevTS: ~p"
+ "~n PrevSN: ~p", [Terms, PrevTS, PrevSN]),
+ {NextTS, NextSN} = lists:foldl(Validator, {PrevTS, PrevSN}, Terms),
+ ?vtrace("validate_loop -> "
+ "~n NextTS: ~p"
+ "~n NextSN: ~p", [NextTS, NextSN]),
+ validate_loop(disk_log:chunk(Log, Cont), Log, Validator, NextTS, NextSN);
+validate_loop({Cont, Terms, BadBytes}, Log, Validator, PrevTS, PrevSN) ->
+ ?vtrace("validate_loop -> entry with"
+ "~n Terms: ~p"
+ "~n BadBytes: ~p"
+ "~n PrevTS: ~p"
+ "~n PrevSN: ~p", [Terms, BadBytes, PrevTS, PrevSN]),
+ error_logger:error_msg("Skipping ~w bytes while validating ~p~n~n",
+ [BadBytes, Log]),
+ {NextTS, NextSN} = lists:foldl(Validator, {PrevTS, PrevSN}, Terms),
+ ?vtrace("validate_loop -> "
+ "~n NextTS: ~p"
+ "~n NextSN: ~p", [NextTS, NextSN]),
+ validate_loop(disk_log:chunk(Log, Cont), Log, Validator, NextTS, NextSN);
+validate_loop(Error, _Log, _Write, _PrevTS, _PrevSN) ->
+ Error.
+
+
%% -- log ---
%%-----------------------------------------------------------------
@@ -109,19 +308,53 @@ info_filter([Item|Items], Info, Acc) ->
%%-----------------------------------------------------------------
-log(Log, Packet, Addr, Port) ->
+log(#snmp_log{id = Log, seqno = SeqNo}, Packet, Addr, Port) ->
?vtrace("log -> entry with"
"~n Log: ~p"
"~n Addr: ~p"
"~n Port: ~p", [Log, Addr, Port]),
- Entry = {timestamp(), Packet, Addr, Port},
- disk_log:alog(Log, Entry).
+ Entry = make_entry(SeqNo, Packet, Addr, Port),
+%% io:format("log -> "
+%% "~n Entry: ~p"
+%% "~n Info: ~p"
+%% "~n", [Entry, disk_log:info(Log)]),
+ Res = disk_log:alog(Log, Entry),
+%% io:format("log -> "
+%% "~n Res: ~p"
+%% "~n Info: ~p"
+%% "~n", [Res, disk_log:info(Log)]),
+ %% disk_log:sync(Log),
+ Res.
+
+
+
+make_entry(SeqNoGen, Packet, Addr, Port) ->
+ try next_seqno(SeqNoGen) of
+ disabled ->
+ {timestamp(), Packet, Addr, Port};
+ {ok, NextSeqNo} ->
+ {timestamp(), NextSeqNo, Packet, Addr, Port}
+ catch
+ _:_ ->
+ {timestamp(), Packet, Addr, Port}
+ end.
+next_seqno({M, F, A}) ->
+ {ok, apply(M, F, A)};
+next_seqno(F) when is_function(F) ->
+ {ok, F()};
+next_seqno(_) ->
+ disabled.
%% -- change_size ---
+change_size(#snmp_log{id = Log}, NewSize) ->
+ do_change_size(Log, NewSize);
change_size(Log, NewSize) ->
+ do_change_size(Log, NewSize).
+
+do_change_size(Log, NewSize) ->
?vtrace("change_size -> entry with"
"~n Log: ~p"
"~n NewSize: ~p", [Log, NewSize]),
@@ -171,6 +404,23 @@ log_to_io(Log, FileName, Dir, Mibs, Start, Stop)
log_convert(Log, File, Converter).
+%% -- log_to_plain ---
+
+%% log_to_plain(Log, FileName, Dir) ->
+%% log_to_plain(Log, FileName, Dir, null, null).
+
+%% log_to_plain(Log, FileName, Dir, Start) ->
+%% log_to_plain(Log, FileName, Dir, Start, null).
+
+%% log_to_plain(Log, FileName, Dir, Start, Stop)
+%% when is_list(Mibs) ->
+%% File = filename:join(Dir, FileName),
+%% Converter = fun(L) ->
+%% do_log_to_plain(L, Start, Stop)
+%% end,
+%% log_convert(Log, File, Converter).
+
+
%% --------------------------------------------------------------------
%% Internal functions
%% --------------------------------------------------------------------
@@ -178,7 +428,12 @@ log_to_io(Log, FileName, Dir, Mibs, Start, Stop)
%% -- log_convert ---
+log_convert(#snmp_log{id = Log}, File, Converter) ->
+ do_log_convert(Log, File, Converter);
log_convert(Log, File, Converter) ->
+ do_log_convert(Log, File, Converter).
+
+do_log_convert(Log, File, Converter) ->
%% First check if the caller process has already opened the
%% log, because if we close an already open log we will cause
%% a runtime error.
@@ -274,86 +529,151 @@ loop({Cont, Terms, BadBytes}, Log, Write) ->
loop(Error, _Log, _Write) ->
Error.
-format_msg({TimeStamp, {V3Hdr, ScopedPdu}, {Addr, Port}},
- Mib, Start, Stop) ->
- format_msg({TimeStamp, {V3Hdr, ScopedPdu}, Addr, Port},
- Mib, Start, Stop);
-format_msg({TimeStamp, {V3Hdr, ScopedPdu}, Addr, Port},
- Mib, Start, Stop) ->
-% io:format("format_msg -> entry with"
-% "~n TimeStamp: ~p"
-% "~n Start: ~p"
-% "~n Stop: ~p", [TimeStamp, Start, Stop]),
- case timestamp_filter(TimeStamp, Start, Stop) of
- true ->
- case (catch snmp_pdus:dec_scoped_pdu(ScopedPdu)) of
- ScopedPDU when is_record(ScopedPDU, scopedPdu) ->
- Msg = #message{version = 'version-3',
- vsn_hdr = V3Hdr,
- data = ScopedPDU},
- f(ts2str(TimeStamp), Msg, Addr, Port, Mib);
- {'EXIT', Reason} ->
- format_tab("** error in log file at ~s from ~p:~w ~p\n\n",
- [ts2str(TimeStamp), ip(Addr), Port, Reason])
- end;
- false ->
- ignore
- end;
-format_msg({TimeStamp, Packet, {Addr, Port}}, Mib, Start, Stop) ->
- format_msg({TimeStamp, Packet, Addr, Port}, Mib, Start, Stop);
-format_msg({TimeStamp, Packet, Addr, Port}, Mib, Start, Stop) ->
+
+format_msg(Entry, Mib, Start, Stop) ->
+ TimeStamp = element(1, Entry),
case timestamp_filter(TimeStamp, Start, Stop) of
true ->
- case (catch snmp_pdus:dec_message(binary_to_list(Packet))) of
- Msg when is_record(Msg, message) ->
- f(ts2str(TimeStamp), Msg, Addr, Port, Mib);
- {'EXIT', Reason} ->
- format_tab("** error in log file ~p\n\n", [Reason])
- end;
- false ->
- ignore
- end;
-format_msg(_, _Mib, _Start, _Stop) ->
+ do_format_msg(Entry, Mib);
+ false ->
+ ignore
+ end.
+
+%% This is an old-style entry, that never had the sequence-number
+do_format_msg({Timestamp, Packet, {Addr, Port}}, Mib) ->
+ do_format_msg(Timestamp, Packet, Addr, Port, Mib);
+
+%% This is the format without sequence-number
+do_format_msg({Timestamp, Packet, Addr, Port}, Mib) ->
+ do_format_msg(Timestamp, Packet, Addr, Port, Mib);
+
+%% This is the format with sequence-number
+do_format_msg({Timestamp, SeqNo, Packet, Addr, Port}, Mib) ->
+ do_format_msg(Timestamp, SeqNo, Packet, Addr, Port, Mib);
+
+%% This is crap...
+do_format_msg(_, _) ->
format_tab("** unknown entry in log file\n\n", []).
-f(TimeStamp, #message{version = Vsn, vsn_hdr = VsnHdr, data = Data},
+do_format_msg(TimeStamp, {V3Hdr, ScopedPdu}, Addr, Port, Mib) ->
+ case (catch snmp_pdus:dec_scoped_pdu(ScopedPdu)) of
+ ScopedPDU when is_record(ScopedPDU, scopedPdu) ->
+ Msg = #message{version = 'version-3',
+ vsn_hdr = V3Hdr,
+ data = ScopedPDU},
+ f(ts2str(TimeStamp), "", Msg, Addr, Port, Mib);
+ {'EXIT', Reason} ->
+ format_tab("** error in log file at ~s from ~p:~w ~p\n\n",
+ [ts2str(TimeStamp), ip(Addr), Port, Reason])
+ end;
+do_format_msg(TimeStamp, Packet, Addr, Port, Mib) ->
+ case (catch snmp_pdus:dec_message(binary_to_list(Packet))) of
+ Msg when is_record(Msg, message) ->
+ f(ts2str(TimeStamp), "", Msg, Addr, Port, Mib);
+ {'EXIT', Reason} ->
+ format_tab("** error in log file ~p\n\n", [Reason])
+ end.
+
+do_format_msg(TimeStamp, SeqNo, {V3Hdr, ScopedPdu}, Addr, Port, Mib) ->
+ case (catch snmp_pdus:dec_scoped_pdu(ScopedPdu)) of
+ ScopedPDU when is_record(ScopedPDU, scopedPdu) ->
+ Msg = #message{version = 'version-3',
+ vsn_hdr = V3Hdr,
+ data = ScopedPDU},
+ f(ts2str(TimeStamp), sn2str(SeqNo), Msg, Addr, Port, Mib);
+ {'EXIT', Reason} ->
+ format_tab("** error in log file at ~s from ~p:~w ~p\n\n",
+ [ts2str(TimeStamp), sn2str(SeqNo),
+ ip(Addr), Port, Reason])
+ end;
+do_format_msg(TimeStamp, SeqNo, Packet, Addr, Port, Mib) ->
+ case (catch snmp_pdus:dec_message(binary_to_list(Packet))) of
+ Msg when is_record(Msg, message) ->
+ f(ts2str(TimeStamp), sn2str(SeqNo), Msg, Addr, Port, Mib);
+ {'EXIT', Reason} ->
+ format_tab("** error in log file ~s from ~p:~w ~p\n\n",
+ [ts2str(TimeStamp), sn2str(SeqNo),
+ ip(Addr), Port, Reason])
+ end.
+
+
+%% format_msg({TimeStamp, {V3Hdr, ScopedPdu}, {Addr, Port}},
+%% Mib, Start, Stop) ->
+%% format_msg({TimeStamp, {V3Hdr, ScopedPdu}, Addr, Port},
+%% Mib, Start, Stop);
+%% format_msg({TimeStamp, {V3Hdr, ScopedPdu}, Addr, Port},
+%% Mib, Start, Stop) ->
+%% case timestamp_filter(TimeStamp, Start, Stop) of
+%% true ->
+%% case (catch snmp_pdus:dec_scoped_pdu(ScopedPdu)) of
+%% ScopedPDU when record(ScopedPDU, scopedPdu) ->
+%% Msg = #message{version = 'version-3',
+%% vsn_hdr = V3Hdr,
+%% data = ScopedPDU},
+%% f(ts2str(TimeStamp), Msg, Addr, Port, Mib);
+%% {'EXIT', Reason} ->
+%% format_tab("** error in log file at ~s from ~p:~w ~p\n\n",
+%% [ts2str(TimeStamp), ip(Addr), Port, Reason])
+%% end;
+%% false ->
+%% ignore
+%% end;
+%% format_msg({TimeStamp, Packet, {Addr, Port}}, Mib, Start, Stop) ->
+%% format_msg({TimeStamp, Packet, Addr, Port}, Mib, Start, Stop);
+%% format_msg({TimeStamp, Packet, Addr, Port}, Mib, Start, Stop) ->
+%% case timestamp_filter(TimeStamp, Start, Stop) of
+%% true ->
+%% case (catch snmp_pdus:dec_message(binary_to_list(Packet))) of
+%% Msg when record(Msg, message) ->
+%% f(ts2str(TimeStamp), Msg, Addr, Port, Mib);
+%% {'EXIT', Reason} ->
+%% format_tab("** error in log file ~p\n\n", [Reason])
+%% end;
+%% false ->
+%% ignore
+%% end;
+%% format_msg(_, _Mib, _Start, _Stop) ->
+%% format_tab("** unknown entry in log file\n\n", []).
+
+f(TimeStamp, SeqNo,
+ #message{version = Vsn, vsn_hdr = VsnHdr, data = Data},
Addr, Port, Mib) ->
Str = format_pdu(Data, Mib),
HdrStr = format_header(Vsn, VsnHdr),
case get_type(Data) of
trappdu ->
- f_trap(TimeStamp, Vsn, HdrStr, Str, Addr, Port);
+ f_trap(TimeStamp, SeqNo, Vsn, HdrStr, Str, Addr, Port);
'snmpv2-trap' ->
- f_trap(TimeStamp, Vsn, HdrStr, Str, Addr, Port);
+ f_trap(TimeStamp, SeqNo, Vsn, HdrStr, Str, Addr, Port);
'inform-request' ->
- f_inform(TimeStamp, Vsn, HdrStr, Str, Addr, Port);
+ f_inform(TimeStamp, SeqNo, Vsn, HdrStr, Str, Addr, Port);
'get-response' ->
- f_response(TimeStamp, Vsn, HdrStr, Str, Addr, Port);
+ f_response(TimeStamp, SeqNo, Vsn, HdrStr, Str, Addr, Port);
report ->
- f_report(TimeStamp, Vsn, HdrStr, Str, Addr, Port);
+ f_report(TimeStamp, SeqNo, Vsn, HdrStr, Str, Addr, Port);
_ ->
- f_request(TimeStamp, Vsn, HdrStr, Str, Addr, Port)
+ f_request(TimeStamp, SeqNo, Vsn, HdrStr, Str, Addr, Port)
end.
-f_request(TimeStamp, Vsn, HdrStr, Str, Addr, Port) ->
- format_tab("request ~s:~w - ~s [~s] ~w\n~s",
- [ip(Addr), Port, HdrStr, TimeStamp, Vsn, Str]).
+f_request(TimeStamp, SeqNo, Vsn, HdrStr, Str, Addr, Port) ->
+ format_tab("request ~s:~w - ~s [~s]~s ~w\n~s",
+ [ip(Addr), Port, HdrStr, TimeStamp, SeqNo, Vsn, Str]).
-f_response(TimeStamp, Vsn, HdrStr, Str, Addr, Port) ->
- format_tab("response ~s:~w - ~s [~s] ~w\n~s",
- [ip(Addr), Port, HdrStr, TimeStamp, Vsn, Str]).
+f_response(TimeStamp, SeqNo, Vsn, HdrStr, Str, Addr, Port) ->
+ format_tab("response ~s:~w - ~s [~s]~s ~w\n~s",
+ [ip(Addr), Port, HdrStr, TimeStamp, SeqNo, Vsn, Str]).
-f_report(TimeStamp, Vsn, HdrStr, Str, Addr, Port) ->
- format_tab("report ~s:~w - ~s [~s] ~w\n~s",
- [ip(Addr), Port, HdrStr, TimeStamp, Vsn, Str]).
+f_report(TimeStamp, SeqNo, Vsn, HdrStr, Str, Addr, Port) ->
+ format_tab("report ~s:~w - ~s [~s]~s ~w\n~s",
+ [ip(Addr), Port, HdrStr, TimeStamp, SeqNo, Vsn, Str]).
-f_trap(TimeStamp, Vsn, HdrStr, Str, Addr, Port) ->
- format_tab("trap ~s:~w - ~s [~s] ~w\n~s",
- [ip(Addr), Port, HdrStr, TimeStamp, Vsn, Str]).
+f_trap(TimeStamp, SeqNo, Vsn, HdrStr, Str, Addr, Port) ->
+ format_tab("trap ~s:~w - ~s [~s]~s ~w\n~s",
+ [ip(Addr), Port, HdrStr, TimeStamp, SeqNo, Vsn, Str]).
-f_inform(TimeStamp, Vsn, HdrStr, Str, Addr, Port) ->
- format_tab("inform ~s:~w - ~s [~s] ~w\n~s",
- [ip(Addr), Port, HdrStr, TimeStamp, Vsn, Str]).
+f_inform(TimeStamp, SeqNo, Vsn, HdrStr, Str, Addr, Port) ->
+ format_tab("inform ~s:~w - ~s [~s]~s ~w\n~s",
+ [ip(Addr), Port, HdrStr, TimeStamp, SeqNo, Vsn, Str]).
%% Convert a timestamp 2-tupple to a printable string
@@ -363,6 +683,13 @@ ts2str({Local,Universal}) ->
ts2str(_) ->
"".
+%% Convert a sequence number integer to a printable string
+%%
+sn2str(SeqNo) when is_integer(SeqNo) ->
+ " [" ++ integer_to_list(SeqNo) ++ "]";
+sn2str(_) ->
+ "".
+
%% Convert a datetime 2-tupple to a printable string
%%
dat2str({{Y,M,D},{H,Min,S}}) ->
@@ -457,19 +784,31 @@ ip({A,B,C,D}) ->
%% Various utility functions
%% -------------------------------------------------------------------
-log_open(Name, File, Size, Repair, Notify) ->
+log_open(Name, File, {M, F, A} = SeqNoGen, Size, Repair, Notify)
+ when (is_atom(M) andalso is_atom(F) andalso is_list(A)) ->
+ log_open2(Name, File, SeqNoGen, Size, Repair, Notify);
+log_open(Name, File, SeqNoGen, Size, Repair, Notify)
+ when is_function(SeqNoGen, 0) ->
+ log_open2(Name, File, SeqNoGen, Size, Repair, Notify);
+log_open(Name, File, disabled = SeqNoGen, Size, Repair, Notify) ->
+ log_open2(Name, File, SeqNoGen, Size, Repair, Notify);
+log_open(_, _File, BadSeqNoGen, _Size, _Repair, _Notify) ->
+ {error, {bad_seqno, BadSeqNoGen}}.
+
+log_open2(Name, File, SeqNoGen, Size, Repair, Notify) ->
case do_log_open(Name, File, Size, Repair, Notify) of
{ok, Log} ->
- {ok, Log};
+ {ok, #snmp_log{id = Log, seqno = SeqNoGen}};
{repaired, Log, Rec, Bad} ->
?vlog("log_open -> repaired: "
"~n Rec: ~p"
"~n Bad: ~p", [Rec, Bad]),
- {ok, Log};
+ {ok, #snmp_log{id = Log, seqno = SeqNoGen}};
Error ->
Error
end.
+
%% We need to make sure we do not end up in an infinit loop
%% Take the number of files of the wrap log and add 2 (for
%% the index and size files).
diff --git a/lib/snmp/src/misc/snmp_pdus.erl b/lib/snmp/src/misc/snmp_pdus.erl
index 6c80fc3876..dc8900c8cd 100644
--- a/lib/snmp/src/misc/snmp_pdus.erl
+++ b/lib/snmp/src/misc/snmp_pdus.erl
@@ -1,19 +1,19 @@
%%
%% %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
%% 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%
%%
@@ -38,7 +38,10 @@
dec_usm_security_parameters/1,
strip_encrypted_scoped_pdu_data/1,
octet_str_to_bits/1, bits_to_str/1,
- get_encoded_length/1]).
+ get_encoded_length/1,
+ enc_value/2, dec_value/1]).
+
+%% -compile(export_all).
%% Returns the number of octets required to encode Length.
get_encoded_length(Length) ->
@@ -290,12 +293,18 @@ dec_value([68 | Bytes]) ->
{Value, Rest} = dec_oct_str_notag(Bytes),
{{'Opaque', Value}, Rest};
dec_value([70 | Bytes]) ->
+ %% Counter64 is an unsigned 64 but is actually encoded as
+ %% a signed integer 64.
{Value, Rest} = dec_integer_notag(Bytes),
- if Value >= 0, Value =< 18446744073709551615 ->
- {{'Counter64', Value}, Rest};
- true ->
- exit({error, {bad_counter64, Value}})
- end;
+ Value2 =
+ if
+ (Value >= 0) andalso (Value < 16#8000000000000000) ->
+ Value;
+ (Value < 0) ->
+ 18446744073709551615 + Value + 1;
+ true ->
+ exit({error, {bad_counter64, Value}}) end,
+ {{'Counter64', Value2}, Rest};
dec_value([128,0|T]) ->
{{'NULL', noSuchObject}, T};
dec_value([129,0|T]) ->
@@ -633,6 +642,21 @@ enc_value(_Type, endOfMibView) ->
[130,0];
enc_value('NULL', _Val) ->
[5,0];
+enc_value('Counter64', Val) ->
+ Val2 =
+ if
+ Val > 16#ffffffffffffffff ->
+ exit({error, {bad_counter64, Val}});
+ Val >= 16#8000000000000000 ->
+ (Val band 16#7fffffffffffffff) - 16#8000000000000000;
+ Val >= 0 ->
+ Val;
+ true ->
+ exit({error, {bad_counter64, Val}})
+ end,
+ Bytes2 = enc_integer_notag(Val2),
+ Len2 = elength(length(Bytes2)),
+ lists:append([70 | Len2],Bytes2);
enc_value(Type, Val) ->
Bytes2 = enc_integer_notag(Val),
Len2 = elength(length(Bytes2)),
@@ -643,10 +667,7 @@ enc_val_tag('Counter32',Val) when (Val >= 0) andalso (Val =< 4294967295) ->
enc_val_tag('Unsigned32', Val) when (Val >= 0) andalso (Val =< 4294967295) ->
66;
enc_val_tag('TimeTicks', Val) when (Val >= 0) andalso (Val =< 4294967295) ->
- 67;
-enc_val_tag('Counter64', Val) when ((Val >= 0) andalso
- (Val =< 18446744073709551615)) ->
- 70.
+ 67.
%%----------------------------------------------------------------------
diff --git a/lib/snmp/src/misc/snmp_usm.erl b/lib/snmp/src/misc/snmp_usm.erl
index 6d216e65d6..3508f9e1c2 100644
--- a/lib/snmp/src/misc/snmp_usm.erl
+++ b/lib/snmp/src/misc/snmp_usm.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2004-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 2004-2010. All Rights Reserved.
+%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
-%%
+%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
-%%
+%%
%% %CopyrightEnd%
%%
@@ -198,7 +198,7 @@ des_encrypt(PrivKey, Data, SaltFun) ->
[A,B,C,D,E,F,G,H | PreIV] = PrivKey,
DesKey = [A,B,C,D,E,F,G,H],
Salt = SaltFun(),
- IV = snmp_misc:str_xor(PreIV, Salt),
+ IV = list_to_binary(snmp_misc:str_xor(PreIV, Salt)),
TailLen = (8 - (length(Data) rem 8)) rem 8,
Tail = mk_tail(TailLen),
EncData = crypto:des_cbc_encrypt(DesKey, IV, [Data,Tail]),
@@ -206,29 +206,41 @@ des_encrypt(PrivKey, Data, SaltFun) ->
des_decrypt(PrivKey, MsgPrivParams, EncData)
when length(MsgPrivParams) =:= 8 ->
+ ?vtrace("des_decrypt -> entry with"
+ "~n PrivKey: ~p"
+ "~n MsgPrivParams: ~p"
+ "~n EncData: ~p", [PrivKey, MsgPrivParams, EncData]),
[A,B,C,D,E,F,G,H | PreIV] = PrivKey,
DesKey = [A,B,C,D,E,F,G,H],
Salt = MsgPrivParams,
- IV = snmp_misc:str_xor(PreIV, Salt),
+ IV = list_to_binary(snmp_misc:str_xor(PreIV, Salt)),
%% Whatabout errors here??? E.g. not a mulitple of 8!
Data = binary_to_list(crypto:des_cbc_decrypt(DesKey, IV, EncData)),
Data2 = snmp_pdus:strip_encrypted_scoped_pdu_data(Data),
- {ok, Data2}.
+ {ok, Data2};
+des_decrypt(PrivKey, BadMsgPrivParams, EncData) ->
+ ?vtrace("des_decrypt -> entry when bad MsgPrivParams"
+ "~n PrivKey: ~p"
+ "~n BadMsgPrivParams: ~p"
+ "~n EncData: ~p",
+ [PrivKey, BadMsgPrivParams, EncData]),
+ throw({error, {bad_msgPrivParams, PrivKey, BadMsgPrivParams, EncData}}).
+
aes_encrypt(PrivKey, Data, SaltFun) ->
AesKey = PrivKey,
Salt = SaltFun(),
EngineBoots = snmp_framework_mib:get_engine_boots(),
EngineTime = snmp_framework_mib:get_engine_time(),
- IV = [?i32(EngineBoots), ?i32(EngineTime) | Salt],
+ IV = list_to_binary([?i32(EngineBoots), ?i32(EngineTime) | Salt]),
EncData = crypto:aes_cfb_128_encrypt(AesKey, IV, Data),
{ok, binary_to_list(EncData), Salt}.
aes_decrypt(PrivKey, MsgPrivParams, EncData, EngineBoots, EngineTime)
- when length(MsgPrivParams) == 8 ->
+ when length(MsgPrivParams) =:= 8 ->
AesKey = PrivKey,
Salt = MsgPrivParams,
- IV = [?i32(EngineBoots), ?i32(EngineTime) | Salt],
+ IV = list_to_binary([?i32(EngineBoots), ?i32(EngineTime) | Salt]),
%% Whatabout errors here??? E.g. not a mulitple of 8!
Data = binary_to_list(crypto:aes_cfb_128_decrypt(AesKey, IV, EncData)),
Data2 = snmp_pdus:strip_encrypted_scoped_pdu_data(Data),
diff --git a/lib/snmp/test/modules.mk b/lib/snmp/test/modules.mk
index ff848cad1b..6a0c3e9481 100644
--- a/lib/snmp/test/modules.mk
+++ b/lib/snmp/test/modules.mk
@@ -1,20 +1,20 @@
#-*-makefile-*- ; force emacs to enter makefile-mode
# %CopyrightBegin%
-#
-# Copyright Ericsson AB 2004-2009. All Rights Reserved.
-#
+#
+# Copyright Ericsson AB 2004-2010. All Rights Reserved.
+#
# The contents of this file are subject to the Erlang Public License,
# Version 1.1, (the "License"); you may not use this file except in
# compliance with the License. You should have received a copy of the
# Erlang Public License along with this software. If not, it can be
# retrieved online at http://www.erlang.org/.
-#
+#
# Software distributed under the License is distributed on an "AS IS"
# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
# the License for the specific language governing rights and limitations
# under the License.
-#
+#
# %CopyrightEnd%
SUITE_MODULES = \
@@ -57,6 +57,10 @@ MODULES = \
HRL_FILES = snmp_test_lib.hrl
+# These are MIBs that aure used by the compiler test-suite.
+COMPILER_MIB_FILES = \
+ OTP8574-MIB
+
MIB_FILES = \
OLD-SNMPEA-MIB.mib \
OLD-SNMPEA-MIB-v2.mib \
diff --git a/lib/snmp/test/snmp_agent_test.erl b/lib/snmp/test/snmp_agent_test.erl
index 53b35058e1..1676812e56 100644
--- a/lib/snmp/test/snmp_agent_test.erl
+++ b/lib/snmp/test/snmp_agent_test.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2003-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 2003-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%
%%
@@ -32,6 +32,8 @@
-include("snmp_test_lib.hrl").
-define(SNMP_USE_V3, true).
-include_lib("snmp/include/snmp_types.hrl").
+-include_lib("snmp/src/agent/snmpa_atl.hrl").
+
%% -include_lib("snmp/include/SNMP-COMMUNITY-MIB.hrl").
%% -include_lib("snmp/include/SNMP-VIEW-BASED-ACM-MIB.hrl").
%% -include_lib("snmp/include/SNMP-USER-BASED-SM-MIB.hrl").
@@ -84,16 +86,24 @@
all(suite) ->
- {req,
- [
- mnesia,
- distribution,
- {local_slave_nodes, 2},
- {time, 360}
- ],
- [{conf, init_all, cases(), finish_all}]}.
+ Reqs = [mnesia, distribution, {local_slave_nodes, 2}, {time, 360}],
+ Conf1 = [{conf, init_all, cases(), finish_all}],
+ Conf2 = [tickets2],
+ {req, Reqs, Conf1 ++ Conf2}.
+init_per_testcase(otp8395 = Case, Config) when is_list(Config) ->
+ ?DBG("init_per_testcase -> entry with"
+ "~n Case: ~p"
+ "~n Config: ~p", [Case, Config]),
+ Config2 = init_per_testcase2(Case, init_suite(Config)),
+ otp8395({init, Config2});
+init_per_testcase(otp9884 = Case, Config) when is_list(Config) ->
+ ?DBG("init_per_testcase -> entry with"
+ "~n Case: ~p"
+ "~n Config: ~p", [Case, Config]),
+ Config2 = init_per_testcase2(Case, init_suite(Config)),
+ otp9884({init, Config2});
init_per_testcase(otp_7157_test = _Case, Config) when is_list(Config) ->
?DBG("init_per_testcase -> entry with"
"~n Case: ~p"
@@ -119,6 +129,10 @@ init_per_testcase(_Case, Config) when is_list(Config) ->
Dog = ?WD_START(?MINS(6)),
[{watchdog, Dog}|Config].
+fin_per_testcase(otp8395, Config) when is_list(Config) ->
+ otp8395({fin, Config});
+fin_per_testcase(otp9884, Config) when is_list(Config) ->
+ otp9884({fin, Config});
fin_per_testcase(_Case, Config) when is_list(Config) ->
?DBG("fin_per_testcase -> entry with"
"~n Case: ~p"
@@ -127,6 +141,97 @@ fin_per_testcase(_Case, Config) when is_list(Config) ->
?WD_STOP(Dog),
Config.
+
+init_suite(Config) ->
+ ?DBG("init_suite -> entry with"
+ "~n Config: ~p", [Config]),
+
+ %% Suite root dir for test suite
+ PrivDir = ?config(priv_dir, Config),
+
+ %% Create top-directory for this sub-suite
+ SuiteTopDir = filename:join([PrivDir, ?MODULE]),
+ case file:make_dir(SuiteTopDir) of
+ ok ->
+ ok;
+ {error, eexist} ->
+ %% This can happen since this is not really a
+ %% suite-init function.
+ ok;
+ {error, Reason} ->
+ ?FAIL({failed_creating_suite_top_dir, SuiteTopDir, Reason})
+ end,
+
+
+ %% --
+ %% Fix config (data-dir is not correct):
+ %%
+
+ Config1 = fix_data_dir(Config),
+ %% Config1 = Config,
+
+ %% Mib-dirs
+ MibDir = ?config(data_dir, Config1),
+ StdMibDir = filename:join([code:priv_dir(snmp), "mibs"]),
+
+ Config2 = [{suite_top_dir, SuiteTopDir},
+ {mib_dir, MibDir},
+ {std_mib_dir, StdMibDir} | Config1],
+
+ ?DBG("init_suite -> done when"
+ "~n Config2: ~p", [Config2]),
+ Config2.
+
+%% end_per_suite(Config) ->
+end_suite(Config) ->
+ Config.
+
+fix_data_dir(Config) ->
+ DataDir0 = ?config(data_dir, Config),
+ DataDir1 = filename:split(filename:absname(DataDir0)),
+ [_|DataDir2] = lists:reverse(DataDir1),
+ DataDir = filename:join(lists:reverse(DataDir2) ++ [?snmp_test_data]),
+ Config1 = lists:keydelete(data_dir, 1, Config),
+ [{data_dir, DataDir} | Config1].
+
+
+init_per_testcase2(Case, Config) ->
+ SuiteToDir = ?config(suite_top_dir, Config),
+
+ %% Create top-directory for this test-case
+ CaseTopDir = filename:join([SuiteToDir, Case]),
+ ok = file:make_dir(CaseTopDir),
+
+ %% Create agent top-dir(s)
+ AgentTopDir = filename:join([CaseTopDir, agent]),
+ ok = file:make_dir(AgentTopDir),
+ AgentConfDir = filename:join([AgentTopDir, config]),
+ ok = file:make_dir(AgentConfDir),
+ AgentDbDir = filename:join([AgentTopDir, db]),
+ ok = file:make_dir(AgentDbDir),
+ AgentLogDir = filename:join([AgentTopDir, log]),
+ ok = file:make_dir(AgentLogDir),
+
+ %% Create sub-agent top-dir(s)
+ SubAgentTopDir = filename:join([CaseTopDir, sub_agent]),
+ ok = file:make_dir(SubAgentTopDir),
+
+ %% Create manager top-dir(s)
+ ManagerTopDir = filename:join([CaseTopDir, manager]),
+ ok = file:make_dir(ManagerTopDir),
+
+ [{case_top_dir, CaseTopDir},
+ {agent_top_dir, AgentTopDir},
+ {agent_conf_dir, AgentConfDir},
+ {agent_db_dir, AgentDbDir},
+ {agent_log_dir, AgentLogDir},
+ {sub_agent_top_dir, SubAgentTopDir},
+ {manager_top_dir, ManagerTopDir} | Config].
+
+fin_per_testcase2(_Case, Config) ->
+ Config.
+
+
cases() ->
case ?OSTYPE() of
vxworks ->
@@ -138,7 +243,7 @@ cases() ->
test_v1_v2,
test_multi_threaded,
mib_storage,
- tickets
+ tickets1
];
_Else ->
[
@@ -149,7 +254,7 @@ cases() ->
test_v3,
test_multi_threaded,
mib_storage,
- tickets
+ tickets1
]
end.
@@ -949,7 +1054,7 @@ v1_cases() ->
sparse_table,
cnt_64,
opaque,
-
+
change_target_addr_config
].
@@ -1103,7 +1208,10 @@ test_multi_threaded(suite) ->
{req, [], {conf, init_mt, mt_cases(), finish_mt}}.
mt_cases() ->
- [multi_threaded, mt_trap].
+ [
+ multi_threaded,
+ mt_trap
+ ].
init_mt(Config) when is_list(Config) ->
SaNode = ?config(snmp_sa, Config),
@@ -1880,7 +1988,8 @@ inform_i(Config) ->
?P1("unload TestTrap & TestTrapv2..."),
?line unload_master("TestTrap"),
- ?line unload_master("TestTrapv2").
+ ?line unload_master("TestTrapv2"),
+ ok.
v3_inform_i(X) ->
%% <CONDITIONAL-SKIP>
@@ -2926,8 +3035,9 @@ mt_trap_test(MA) ->
?DBG("mt_trap_test(01) -> issue testTrapv22 (standard trap)", []),
snmpa:send_trap(MA, testTrapv22, "standard trap"),
?DBG("mt_trap_test(02) -> await v2trap", []),
- ?line expect(1, v2trap, [{[sysUpTime, 0], any},
- {[snmpTrapOID, 0], ?system ++ [0,1]}]),
+ ?line expect(mt_trap_test_1, v2trap,
+ [{[sysUpTime, 0], any},
+ {[snmpTrapOID, 0], ?system ++ [0,1]}]),
?DBG("mt_trap_test(03) -> issue mtTrap (standard trap)", []),
snmpa:send_trap(MA, mtTrap, "standard trap"),
@@ -2935,28 +3045,22 @@ mt_trap_test(MA) ->
?DBG("mt_trap_test(04) -> multi pid: ~p. Now request sysUpTime...", [Pid]),
g([[sysUpTime,0]]),
- %% Previously (before OTP-6784) this was done at 09 below
- %% when the test1:multiStr was actually executed by the
- %% worker-process, but as of 4.9.4, this is now executed
- %% my the master_agent-process...
- ?DBG("mt_trap_test(05) -> send continue to multi-pid", []),
- Pid ! continue,
-
?DBG("mt_trap_test(06) -> await sysUpTime", []),
- ?line expect(2, [{[sysUpTime,0], any}]),
+ ?line expect(mt_trap_test_2, [{[sysUpTime,0], any}]),
?DBG("mt_trap_test(07) -> issue testTrapv22 (standard trap)", []),
snmpa:send_trap(MA, testTrapv22, "standard trap"),
?DBG("mt_trap_test(08) -> await v2trap", []),
- ?line expect(3, v2trap, [{[sysUpTime, 0], any},
- {[snmpTrapOID, 0], ?system ++ [0,1]}]),
+ ?line expect(mt_trap_test_3, v2trap,
+ [{[sysUpTime, 0], any},
+ {[snmpTrapOID, 0], ?system ++ [0,1]}]),
- %% ?DBG("mt_trap_test(09) -> send continue to multi-pid", []),
- %% Pid ! continue,
+ ?DBG("mt_trap_test(09) -> send continue to multi-pid", []),
+ Pid ! continue,
?DBG("mt_trap_test(10) -> await v2trap", []),
- ?line expect(4, v2trap, [{[sysUpTime, 0], any},
- {[snmpTrapOID, 0], ?testTrap ++ [2]},
- {[multiStr,0], "ok"}]),
+ ?line expect(mt_trap_test_4, v2trap, [{[sysUpTime, 0], any},
+ {[snmpTrapOID, 0], ?testTrap ++ [2]},
+ {[multiStr,0], "ok"}]),
?DBG("mt_trap_test(11) -> done", []),
ok.
@@ -3349,7 +3453,7 @@ do_mul_set_err() ->
?line ?v1_2(expect(2, noSuchName, 1, any),
expect(2, [{[friendsEntry, [2,3]], noSuchInstance}])),
g([NewKeyc4]),
- ?line ?v1_2(expect(3, noSuchName, 1, any),
+ ?line ?v1_2(expect(3, noSuchName, 1, any),
expect(3, [{NewKeyc4, noSuchInstance}])).
%% Req. SA-MIB
@@ -3360,10 +3464,10 @@ sa_mib() ->
?line expect(2, [{[sa, [1,0]], "sa_test"}]).
ma_trap1(MA) ->
- snmpa:send_trap(MA, testTrap2, "standard trap"),
+ ok = snmpa:send_trap(MA, testTrap2, "standard trap"),
?line expect(1, trap, [system], 6, 1, [{[system, [4,0]],
"{mbj,eklas}@erlang.ericsson.se"}]),
- snmpa:send_trap(MA, testTrap1, "standard trap"),
+ ok = snmpa:send_trap(MA, testTrap1, "standard trap"),
?line expect(2, trap, [1,2,3] , 1, 0, [{[system, [4,0]],
"{mbj,eklas}@erlang.ericsson.se"}]).
@@ -3412,7 +3516,8 @@ ma_v2_trap1(MA) ->
?DBG("ma_v2_traps -> send standard trap: testTrapv21",[]),
snmpa:send_trap(MA, testTrapv21, "standard trap"),
?line expect(2, v2trap, [{[sysUpTime, 0], any},
- {[snmpTrapOID, 0], ?snmp ++ [1]}]).
+ {[snmpTrapOID, 0], ?snmp ++ [1]}]),
+ ok.
ma_v2_trap2(MA) ->
snmpa:send_trap(MA,testTrapv22,"standard trap",[{sysContact,"pelle"}]),
@@ -3420,7 +3525,7 @@ ma_v2_trap2(MA) ->
{[snmpTrapOID, 0], ?system ++ [0,1]},
{[system, [4,0]], "pelle"}]).
-%% Note: This test case takes a while... actually a couple of minutes.
+%% Note: This test case takes a while... actually a couple of minutes.
ma_v2_inform1(MA) ->
?DBG("ma_v2_inform1 -> entry with"
"~n MA = ~p => "
@@ -5071,12 +5176,21 @@ reported_bugs_3(suite) ->
%% These are (ticket) test cases where the initiation has to be done
%% individually.
-tickets(suite) ->
+tickets1(suite) ->
[
otp_4394,
otp_7157
].
+
+tickets2(suite) ->
+ [
+ otp8395,
+ otp9884
+ ].
+
+
+
%%-----------------------------------------------------------------
%% Ticket: OTP-1128
%% Slogan: Bug in handling of createAndWait set-requests.
@@ -5153,7 +5267,35 @@ otp_1131_2(X) -> ?P(otp_1131_2), otp_1131(X).
otp_1131_3(X) ->
%% <CONDITIONAL-SKIP>
- Skippable = [{unix, [darwin]}],
+ %% This is intended to catch Montavista Linux 4.0/ppc (2.6.5)
+ %% Montavista Linux looks like a Debian distro (/etc/issue)
+ LinuxVersionVerify =
+ fun() ->
+ case os:cmd("uname -m") of
+ "ppc" ++ _ ->
+ case file:read_file_info("/etc/issue") of
+ {ok, _} ->
+ case os:cmd("grep -i montavista /etc/issue") of
+ Info when (is_list(Info) andalso
+ (length(Info) > 0)) ->
+ case os:version() of
+ {2, 6, 10} ->
+ true;
+ _ ->
+ false
+ end;
+ _ -> % Maybe plain Debian or Ubuntu
+ false
+ end;
+ _ ->
+ %% Not a Debian based distro
+ false
+ end;
+ _ ->
+ false
+ end
+ end,
+ Skippable = [{unix, [darwin, {linux, LinuxVersionVerify}]}],
Condition = fun() -> ?OS_BASED_SKIP(Skippable) end,
?NON_PC_TC_MAYBE_SKIP(X, Condition),
%% </CONDITIONAL-SKIP>
@@ -5624,10 +5766,9 @@ otp_4394_test1() ->
otp_7157(suite) ->
- {req, [], {conf,
- init_otp_7157,
- [otp_7157_test],
- finish_otp_7157}}.
+ Reqs = [],
+ Conf = [{conf, init_otp_7157, [otp_7157_test], finish_otp_7157}],
+ {req, Reqs, Conf}.
init_otp_7157(Config) when is_list(Config) ->
%% <CONDITIONAL-SKIP>
@@ -5691,6 +5832,525 @@ otp_7157_test1(MA) ->
%%-----------------------------------------------------------------
+%% Extra test cases
+%% These cases are started in the new way
+%%-----------------------------------------------------------------
+
+otp8395({init, Config}) when is_list(Config) ->
+ ?DBG("otp8395(init) -> entry with"
+ "~n Config: ~p", [Config]),
+
+ %% --
+ %% Start nodes
+ %%
+
+ {ok, AgentNode} = start_node(agent),
+ %% {ok, SubAgentNode} = start_node(sub_agent),
+ {ok, ManagerNode} = start_node(manager),
+
+ %% --
+ %% Mnesia init
+ %%
+
+ AgentDbDir = ?config(agent_db_dir, Config),
+ AgentMnesiaDir = filename:join([AgentDbDir, "mnesia"]),
+ mnesia_init(AgentNode, AgentMnesiaDir),
+
+ %% SubAgentDir = ?config(sub_agent_dir, Config),
+ %% SubAgentMnesiaDir = filename:join([SubAgentDir, "mnesia"]),
+ %% mnesia_init(SubAgentNode, SubAgentMnesiaDir),
+
+ %% ok = mnesia_create_schema(AgentNode, [AgentNode, SubAgentNode]),
+ %% ok = mnesia:create_schema([AgentNode, SubAgentNode]),
+ mnesia_create_schema(AgentNode, [AgentNode]),
+
+ mnesia_start(AgentNode),
+ %% mnesia_start(SubAgentNode),
+
+ %% --
+ %% Host & IP
+ %%
+
+ AgentHost = ?HOSTNAME(AgentNode),
+ %% SubAgentHost = ?HPSTNAME(SubAgentNode),
+ ManagerHost = ?HOSTNAME(ManagerNode),
+
+ Host = snmp_test_lib:hostname(),
+ Ip = ?LOCALHOST(),
+ {ok, AgentIP0} = snmp_misc:ip(AgentHost),
+ AgentIP = tuple_to_list(AgentIP0),
+ %% {ok, SubAgentIP0} = snmp_misc:ip(SubAgentHost),
+ %% SubAgentIP = tuple_to_list(SubAgentIP0),
+ {ok, ManagerIP0} = snmp_misc:ip(ManagerHost),
+ ManagerIP = tuple_to_list(ManagerIP0),
+
+
+ %% --
+ %% Write agent config
+ %%
+
+ Vsns = [v1],
+ AgentConfDir = ?config(agent_conf_dir, Config),
+ ManagerConfDir = ?config(manager_top_dir, Config),
+ snmp_agent_test_lib:config(Vsns,
+ ManagerConfDir, AgentConfDir,
+ ManagerIP, AgentIP),
+
+
+ %% --
+ %% Start the agent
+ %%
+
+ Config2 = start_agent([{host, Host},
+ {ip, Ip},
+ {agent_node, AgentNode},
+ {agent_host, AgentHost},
+ {agent_ip, AgentIP},
+ %% {sub_agent_node, SubAgentNode},
+ %% {sub_agent_host, SubAgentHost},
+ %% {sub_agent_ip, SubAgentIP},
+ {manager_node, ManagerNode},
+ {manager_host, ManagerHost},
+ {manager_ip, ManagerIP}|Config]),
+
+ %% --
+ %% Create watchdog
+ %%
+
+ Dog = ?WD_START(?MINS(1)),
+
+ [{watchdog, Dog} | Config2];
+
+otp8395({fin, Config}) when is_list(Config) ->
+ ?DBG("otp8395(fin) -> entry with"
+ "~n Config: ~p", [Config]),
+
+ AgentNode = ?config(agent_node, Config),
+ ManagerNode = ?config(manager_node, Config),
+
+ %% -
+ %% Stop agent (this is the nice way to do it,
+ %% so logs and files can be closed in the proper way).
+ %%
+
+ AgentSup = ?config(agent_sup, Config),
+ ?DBG("otp8395(fin) -> stop (stand-alone) agent: ~p", [AgentSup]),
+ stop_stdalone_agent(AgentSup),
+
+ %% -
+ %% Stop mnesia
+ %%
+ ?DBG("otp8395(fin) -> stop mnesia", []),
+ mnesia_stop(AgentNode),
+
+
+ %% -
+ %% Stop the agent node
+ %%
+
+ ?DBG("otp8395(fin) -> stop agent node", []),
+ stop_node(AgentNode),
+
+
+ %% SubAgentNode = ?config(sub_agent_node, Config),
+ %% stop_node(SubAgentNode),
+
+
+ %% -
+ %% Stop the manager node
+ %%
+
+ ?DBG("otp8395(fin) -> stop manager node", []),
+ stop_node(ManagerNode),
+
+ Dog = ?config(watchdog, Config),
+ ?WD_STOP(Dog),
+ lists:keydelete(watchdog, 1, Config);
+
+otp8395(doc) ->
+ "OTP-8395 - ATL with sequence numbering. ";
+
+otp8395(Config) when is_list(Config) ->
+ ?DBG("otp8395 -> entry with"
+ "~n Config: ~p", [Config]),
+
+ ?SLEEP(1000),
+
+ %% This is just to dirty trick for the ***old*** test-code
+ put(mgr_node, ?config(manager_node, Config)),
+ put(mgr_dir, ?config(manager_top_dir, Config)),
+ put(mib_dir, ?config(mib_dir, Config)),
+ put(vsn, v1),
+ put(master_host, ?config(agent_host, Config)),
+ try_test(simple_standard_test),
+
+ ?SLEEP(1000),
+ AgentNode = ?config(agent_node, Config),
+ AgentLogDir = ?config(agent_log_dir, Config),
+ OutFile = filename:join([AgentLogDir, "otp8395.txt"]),
+ {ok, LogInfo} = rpc:call(AgentNode, snmpa, log_info, []),
+ ?DBG("otp8395 -> LogInfo: ~p", [LogInfo]),
+
+ %% SyncRes = rpc:call(AgentNode, snmp, log_sync, [?audit_trail_log_name]),
+ %% ?DBG("otp8395 -> SyncRes: ~p", [SyncRes]),
+
+ ok = agent_log_validation(AgentNode),
+ LTTRes =
+ rpc:call(AgentNode, snmpa, log_to_txt, [AgentLogDir, [], OutFile]),
+ ?DBG("otp8395 -> LTTRes: ~p", [LTTRes]),
+
+ ?SLEEP(1000),
+ ?DBG("otp8395 -> done", []),
+ ok.
+
+
+%%-----------------------------------------------------------------
+
+otp9884({init, Config}) when is_list(Config) ->
+ ?DBG("otp9884(init) -> entry with"
+ "~n Config: ~p", [Config]),
+
+ %% --
+ %% Start nodes
+ %%
+
+ {ok, AgentNode} = start_node(agent),
+
+ %% We don't use a manager in this test but the (common) config
+ %% function takes an argument that is derived from this
+ {ok, ManagerNode} = start_node(manager),
+
+ %% --
+ %% Mnesia init
+ %%
+
+ AgentDbDir = ?config(agent_db_dir, Config),
+ AgentMnesiaDir = filename:join([AgentDbDir, "mnesia"]),
+ mnesia_init(AgentNode, AgentMnesiaDir),
+
+ mnesia_create_schema(AgentNode, [AgentNode]),
+
+ mnesia_start(AgentNode),
+
+ %% --
+ %% Host & IP
+ %%
+
+ AgentHost = ?HOSTNAME(AgentNode),
+ ManagerHost = ?HOSTNAME(ManagerNode),
+
+ Host = snmp_test_lib:hostname(),
+ Ip = ?LOCALHOST(),
+ {ok, AgentIP0} = snmp_misc:ip(AgentHost),
+ AgentIP = tuple_to_list(AgentIP0),
+ {ok, ManagerIP0} = snmp_misc:ip(ManagerHost),
+ ManagerIP = tuple_to_list(ManagerIP0),
+
+
+ %% --
+ %% Write agent config
+ %%
+
+ Vsns = [v1],
+ ManagerConfDir = ?config(manager_top_dir, Config),
+ AgentConfDir = ?config(agent_conf_dir, Config),
+ AgentTopDir = ?config(agent_top_dir, Config),
+ AgentBkpDir1 = filename:join([AgentTopDir, backup1]),
+ AgentBkpDir2 = filename:join([AgentTopDir, backup2]),
+ ok = file:make_dir(AgentBkpDir1),
+ ok = file:make_dir(AgentBkpDir2),
+ AgentBkpDirs = [AgentBkpDir1, AgentBkpDir2],
+ snmp_agent_test_lib:config(Vsns,
+ ManagerConfDir, AgentConfDir,
+ ManagerIP, AgentIP),
+
+
+ %% --
+ %% Start the agent
+ %%
+
+ Config2 = start_agent([{host, Host},
+ {ip, Ip},
+ {agent_node, AgentNode},
+ {agent_host, AgentHost},
+ {agent_ip, AgentIP},
+ {agent_backup_dirs, AgentBkpDirs}|Config]),
+
+ %% --
+ %% Create watchdog
+ %%
+
+ Dog = ?WD_START(?MINS(1)),
+
+ [{watchdog, Dog} | Config2];
+
+otp9884({fin, Config}) when is_list(Config) ->
+ ?DBG("otp9884(fin) -> entry with"
+ "~n Config: ~p", [Config]),
+
+ AgentNode = ?config(agent_node, Config),
+ ManagerNode = ?config(manager_node, Config),
+
+ %% -
+ %% Stop agent (this is the nice way to do it,
+ %% so logs and files can be closed in the proper way).
+ %%
+
+ AgentSup = ?config(agent_sup, Config),
+ ?DBG("otp9884(fin) -> stop (stand-alone) agent: ~p", [AgentSup]),
+ stop_stdalone_agent(AgentSup),
+
+ %% -
+ %% Stop mnesia
+ %%
+ ?DBG("otp9884(fin) -> stop mnesia", []),
+ mnesia_stop(AgentNode),
+
+
+ %% -
+ %% Stop the agent node
+ %%
+
+ ?DBG("otp9884(fin) -> stop agent node", []),
+ stop_node(AgentNode),
+
+
+ %% SubAgentNode = ?config(sub_agent_node, Config),
+ %% stop_node(SubAgentNode),
+
+
+ %% -
+ %% Stop the manager node
+ %%
+
+ ?DBG("otp9884(fin) -> stop manager node", []),
+ stop_node(ManagerNode),
+
+ Dog = ?config(watchdog, Config),
+ ?WD_STOP(Dog),
+ lists:keydelete(watchdog, 1, Config);
+
+otp9884(doc) ->
+ "OTP-9884 - Simlutaneous backup call should not work. ";
+
+otp9884(Config) when is_list(Config) ->
+ ?DBG("otp9884 -> entry with"
+ "~n Config: ~p", [Config]),
+
+ AgentNode = ?config(agent_node, Config),
+ [AgentBkpDir1, AgentBkpDir2] = ?config(agent_backup_dirs, Config),
+ Self = self(),
+ timer:apply_after(1000,
+ ?MODULE, otp9884_backup, [AgentNode, Self, first, AgentBkpDir1]),
+ timer:apply_after(1000,
+ ?MODULE, otp9884_backup, [AgentNode, Self, second, AgentBkpDir2]),
+ otp9884_await_backup_completion(undefined, undefined),
+
+ ?DBG("otp9884 -> done", []),
+ ok.
+
+
+otp9884_backup(Node, Pid, Tag, Dir) ->
+ io:format("[~w] call backup function~n", [Tag]),
+ Res = rpc:call(Node, snmpa, backup, [Dir]),
+ io:format("[~w] backup result: ~p~n", [Tag, Res]),
+ Pid ! {otp9884_backup_complete, Tag, Res}.
+
+otp9884_await_backup_completion(ok, Second)
+ when ((Second =/= ok) andalso (Second =/= undefined)) ->
+ io:format("otp9884_await_backup_completion -> "
+ "first backup succeed and second failed (~p)~n", [Second]),
+ ok;
+otp9884_await_backup_completion(First, ok)
+ when ((First =/= ok) andalso (First =/= undefined)) ->
+ io:format("otp9884_await_backup_completion -> "
+ "second backup succeed and first failed (~p)~n", [First]),
+ ok;
+otp9884_await_backup_completion(First, Second)
+ when (((First =:= undefined) andalso (Second =:= undefined))
+ orelse
+ ((First =:= undefined) andalso (Second =/= undefined))
+ orelse
+ ((First =/= undefined) andalso (Second =:= undefined))) ->
+ io:format("otp9884_await_backup_completion -> await complete messages~n", []),
+ receive
+ {otp9884_backup_complete, first, Res} ->
+ io:format("otp9884_await_backup_completion -> "
+ "received complete message for first: ~p~n", [Res]),
+ otp9884_await_backup_completion(Res, Second);
+ {otp9884_backup_complete, second, Res} ->
+ io:format("otp9884_await_backup_completion -> "
+ "received complete message for second: ~p~n", [Res]),
+ otp9884_await_backup_completion(First, Res)
+ after 10000 ->
+ %% we have waited long enough
+ throw({error, {timeout, First, Second}})
+ end;
+otp9884_await_backup_completion(First, Second) ->
+ throw({error, {bad_completion, First, Second}}).
+
+
+%%-----------------------------------------------------------------
+
+agent_log_validation(Node) ->
+ rpc:call(Node, ?MODULE, agent_log_validation, []).
+
+agent_log_validation() ->
+ put(sname, otp8308),
+ put(verbosity, trace),
+ snmp_log:validate(?audit_trail_log_name, true).
+
+mnesia_init(Node, Dir) ->
+ rpc:call(Node, ?MODULE, mnesia_init, [Dir]).
+
+mnesia_init(Dir) ->
+ ok = application:load(mnesia),
+ application_controller:set_env(mnesia, dir, Dir).
+
+mnesia_create_schema(Node, Nodes) ->
+ rpc:call(Node, mnesia, create_schema, [Nodes]).
+
+mnesia_start(Node) ->
+ rpc:call(Node, application, start, [mnesia]).
+
+mnesia_start() ->
+ application:start(mnesia).
+
+mnesia_stop(Node) ->
+ rpc:call(Node, application, stop, [mnesia]).
+
+mnesia_stop() ->
+ application:start(mnesia).
+
+
+start_agent(Config) ->
+ start_agent(Config, []).
+
+start_agent(Config, Opts) ->
+
+ %% Directories
+ ConfDir = ?config(agent_conf_dir, Config),
+ DbDir = ?config(agent_db_dir, Config),
+ LogDir = ?config(agent_log_dir, Config),
+
+ Vsns = [v1],
+
+ AgentConfig = process_agent_options(ConfDir, DbDir, LogDir, Vsns, Opts),
+
+ %% Nodes
+ AgentNode = ?config(agent_node, Config),
+ %% ManagerNode = ?config(manager_node, Config),
+
+ process_flag(trap_exit,true),
+
+ AgentTopSup = start_stdalone_agent(AgentNode, AgentConfig),
+
+ [{agent_sup, AgentTopSup} | Config].
+
+
+process_agent_options(ConfDir, DbDir, LogDir, Vsns, Opts) ->
+ Defaults =
+ [{agent_type, master},
+ {agent_verbosity, trace},
+ {priority, normal},
+ {versions, Vsns},
+ {db_dir, DbDir},
+ {mib_storage, ets},
+ {local_db, [{repair, true},
+ {auto_save, 5000},
+ {verbosity, log}]},
+ {error_report_module, snmpa_error_logger},
+ {config, [{dir, ConfDir},
+ {force_load, true},
+ {verbosity, trace}]},
+ {multi_threaded, true},
+ {mib_server, [{mibentry_override, false},
+ {trapentry_override, false},
+ {verbosity, info}]},
+ {target_cache, [{verbosity,info}]},
+ {symbolic_store, [{verbosity,log}]},
+ {note_store, [{timeout,30000}, {verbosity,log}]},
+ {net_if, [{module, snmpa_net_if},
+ {verbosity, trace},
+ {options, [{bind_to, false},
+ {no_reuse, false},
+ {req_limit, infinity}]}]},
+ {audit_trail_log, [{type, read_write},
+ {dir, LogDir},
+ {size, {10240,20}},
+ {repair, true},
+ {seqno, true}]}],
+
+ process_options(Defaults, Opts).
+
+process_options(Defaults, _Opts) ->
+ %% process_options(Defaults, Opts, []).
+ Defaults.
+
+%% process_options([], _Opts, Acc) ->
+%% lists:reverse(Acc);
+%% process_options([{Key, DefaultValue}|Defaults], Opts, Acc) ->
+%% case lists:keysearch(Key, 1, Opts) of
+%% {value, {Key, Value}} when is_list->
+
+
+snmp_app_env_init(Node, Entity, Conf) ->
+ rpc:call(Node, snmp_app_env_init, [Entity, Conf]).
+
+snmp_app_env_init(Entity, Conf) ->
+ application:unload(snmp),
+ application:load(snmp),
+ application:set_env(snmp, Entity, Conf).
+
+start_stdalone_agent(Node, Config) ->
+ rpc:call(Node, ?MODULE, start_stdalone_agent, [Config]).
+
+start_stdalone_agent(Config) ->
+ case snmpa_supervisor:start_link(normal, Config) of
+ {ok, AgentTopSup} ->
+ unlink(AgentTopSup),
+ AgentTopSup;
+ {error, {already_started, AgentTopSup}} ->
+ AgentTopSup
+ end.
+
+stop_stdalone_agent(Pid) when (node(Pid) =/= node()) ->
+ MRef = erlang:monitor(process, Pid),
+ rpc:call(node(Pid), ?MODULE, stop_stdalone_agent, [Pid]),
+ receive
+ {'DOWN', MRef, process, Pid, Info} ->
+ ?DBG("received expected DOWN message "
+ "regarding snmp agent supervisor: "
+ "~n Info: ~p", [Info]),
+ ok
+ after 5000 ->
+ ?DBG("no DOWN message "
+ "regarding snmp agent supervisor within time", []),
+ ok
+ end;
+stop_stdalone_agent(Pid) ->
+ ?DBG("attempting to terminate agent top-supervisor: ~p", [Pid]),
+ nkill(Pid, kill).
+
+
+nkill(Pid, Reason) ->
+ nkill(Pid, Reason, 10).
+
+nkill(Pid, Reason, N) when N > 0 ->
+ case (catch erlang:process_info(Pid)) of
+ Info when is_list(Info) ->
+ ?DBG("Info for process to kill: "
+ "~n Info: ~p", [Info]),
+ exit(Pid, Reason),
+ ?SLEEP(1000),
+ nkill(Pid, Reason, N-1);
+ _ ->
+ ?DBG("No process info => already dead?", []),
+ ok
+ end.
+
+
+%%-----------------------------------------------------------------
%% Slogan: info test
%%-----------------------------------------------------------------
@@ -5784,12 +6444,15 @@ verify_old_info([Key|Keys], Info) ->
is(S) -> [length(S) | S].
try_test(Func) ->
+ ?P2("try test ~w...", [Func]),
snmp_agent_test_lib:try_test(?MODULE, Func).
try_test(Func, A) ->
+ ?P2("try test ~w...", [Func]),
snmp_agent_test_lib:try_test(?MODULE, Func, A).
try_test(Func, A, Opts) ->
+ ?P2("try test ~w...", [Func]),
snmp_agent_test_lib:try_test(?MODULE, Func, A, Opts).
diff --git a/lib/snmp/test/snmp_agent_test_lib.erl b/lib/snmp/test/snmp_agent_test_lib.erl
index 31b375efa9..084b3ee8da 100644
--- a/lib/snmp/test/snmp_agent_test_lib.erl
+++ b/lib/snmp/test/snmp_agent_test_lib.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2005-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 2005-2011. All Rights Reserved.
+%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
-%%
+%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
-%%
+%%
%% %CopyrightEnd%
%%
@@ -296,7 +296,12 @@ call(N,M,F,A) ->
?DBG("call -> done:"
"~n Ret: ~p"
"~n Zed: ~p", [Ret, Zed]),
- Ret
+ case Ret of
+ {error, Reason} ->
+ exit(Reason);
+ OK ->
+ OK
+ end
end.
wait(From, Env, M, F, A) ->
@@ -421,7 +426,7 @@ start_agent(Config, Vsns, Opts) ->
?LOG("start_agent -> entry (~p) with"
"~n Config: ~p"
"~n Vsns: ~p"
- "~n Opts: ~p",[node(), Config, Vsns, Opts]),
+ "~n Opts: ~p", [node(), Config, Vsns, Opts]),
?line AgentDir = ?config(agent_dir, Config),
?line SaNode = ?config(snmp_sa, Config),
@@ -724,17 +729,13 @@ expect(Id, A, B, C, D, E) ->
expect2(Id, Fun).
expect2(Id, F) ->
- io:format("~w:expect2 -> entry with"
- "~n Id: ~w"
- "~n", [?MODULE, Id]),
+ io:format("EXPECT for ~w~n", [Id]),
case F() of
{error, Reason} ->
- {error, Id, Reason};
+ io:format("EXPECT failed for ~w: ~n~p~n", [Id, Reason]),
+ throw({error, {expect, Id, Reason}});
Else ->
- io:format("~w:expect2 -> "
- "~n Id: ~w"
- "~n Else: ~p"
- "~n", [?MODULE, Id, Else]),
+ io:format("EXPECT result for ~w: ~n~p~n", [Id, Else]),
Else
end.
@@ -769,21 +770,15 @@ do_expect(Expect) when is_atom(Expect) ->
do_expect({any_pdu, To})
when is_integer(To) orelse (To =:= infinity) ->
- io:format("~w:do_expect(any_pdu) -> entry with"
- "~n To: ~w"
- "~n", [?MODULE, To]),
+ io:format("EXPECT any PDU~n", []),
receive_pdu(To);
do_expect({any_trap, To}) ->
- io:format("~w:do_expect(any_trap) -> entry with"
- "~n To: ~w"
- "~n", [?MODULE, To]),
+ io:format("EXPECT any TRAP within ~w~n", [To]),
receive_trap(To);
do_expect({timeout, To}) ->
- io:format("~w:do_expect(timeout) -> entry with"
- "~n To: ~w"
- "~n", [?MODULE, To]),
+ io:format("EXPECT nothing within ~w~n", [To]),
receive
X ->
{error, {unexpected, X}}
@@ -794,13 +789,16 @@ do_expect({timeout, To}) ->
do_expect({Err, To})
when is_atom(Err) andalso (is_integer(To) orelse (To =:= infinity)) ->
+ io:format("EXPECT error ~w within ~w~n", [Err, To]),
do_expect({{error, Err}, To});
do_expect({error, Err}) when is_atom(Err) ->
Check = fun(_, R) -> R end,
+ io:format("EXPECT error ~w~n", [Err]),
do_expect2(Check, any, Err, any, any, get_timeout());
do_expect({{error, Err}, To}) ->
Check = fun(_, R) -> R end,
+ io:format("EXPECT error ~w within ~w~n", [Err, To]),
do_expect2(Check, any, Err, any, any, To);
%% exp_varbinds() -> [exp_varbind()]
@@ -810,16 +808,25 @@ do_expect({{error, Err}, To}) ->
%% ExpVBs -> exp_varbinds() | {VbsCondition, exp_varbinds()}
do_expect(ExpVBs) ->
Check = fun(_, R) -> R end,
+ io:format("EXPECT 'get-response'"
+ "~n with"
+ "~n Varbinds: ~p~n", [ExpVBs]),
do_expect2(Check, 'get-response', noError, 0, ExpVBs, get_timeout()).
do_expect(v2trap, ExpVBs) ->
Check = fun(_, R) -> R end,
+ io:format("EXPECT 'snmpv2-trap'"
+ "~n with"
+ "~n Varbinds: ~p~n", [ExpVBs]),
do_expect2(Check, 'snmpv2-trap', noError, 0, ExpVBs, get_timeout());
do_expect(report, ExpVBs) ->
Check = fun(_, R) -> R end,
+ io:format("EXPECT 'report'"
+ "~n with"
+ "~n Varbinds: ~p~n", [ExpVBs]),
do_expect2(Check, 'report', noError, 0, ExpVBs, get_timeout());
@@ -827,16 +834,13 @@ do_expect(inform, ExpVBs) ->
do_expect({inform, true}, ExpVBs);
do_expect({inform, false}, ExpVBs) ->
- io:format("~w:do_expect(inform, false) -> entry with"
- "~n ExpVBs: ~p"
- "~n", [?MODULE, ExpVBs]),
Check = fun(_, R) -> R end,
+ io:format("EXPECT 'inform-request' (false)"
+ "~n with"
+ "~n Varbinds: ~p~n", [ExpVBs]),
do_expect2(Check, 'inform-request', noError, 0, ExpVBs, get_timeout());
do_expect({inform, true}, ExpVBs) ->
- io:format("~w:do_expect(inform, true) -> entry with"
- "~n ExpVBs: ~p"
- "~n", [?MODULE, ExpVBs]),
Check =
fun(PDU, ok) ->
RespPDU = PDU#pdu{type = 'get-response',
@@ -847,6 +851,9 @@ do_expect({inform, true}, ExpVBs) ->
(_, Err) ->
Err
end,
+ io:format("EXPECT 'inform-request' (true)"
+ "~n with"
+ "~n Varbinds: ~p~n", [ExpVBs]),
do_expect2(Check, 'inform-request', noError, 0, ExpVBs, get_timeout());
do_expect({inform, {error, EStat, EIdx}}, ExpVBs)
@@ -861,6 +868,11 @@ do_expect({inform, {error, EStat, EIdx}}, ExpVBs)
(_, Err) ->
Err
end,
+ io:format("EXPECT 'inform-request' (error)"
+ "~n with"
+ "~n Error Status: ~p"
+ "~n Error Index: ~p"
+ "~n Varbinds: ~p~n", [EStat, EIdx, ExpVBs]),
do_expect2(Check, 'inform-request', noError, 0, ExpVBs, get_timeout()).
@@ -871,6 +883,12 @@ do_expect(Err, Idx, ExpVBs, To)
when is_atom(Err) andalso
(is_integer(Idx) orelse is_list(Idx) orelse (Idx == any)) ->
Check = fun(_, R) -> R end,
+ io:format("EXPECT 'get-response'"
+ "~n with"
+ "~n Error: ~p"
+ "~n Index: ~p"
+ "~n Varbinds: ~p"
+ "~n within ~w~n", [Err, Idx, ExpVBs, To]),
do_expect2(Check, 'get-response', Err, Idx, ExpVBs, To).
@@ -878,15 +896,13 @@ do_expect(Type, Enterp, Generic, Specific, ExpVBs) ->
do_expect(Type, Enterp, Generic, Specific, ExpVBs, 3500).
do_expect(trap, Enterp, Generic, Specific, ExpVBs, To) ->
- io:format("~w:do_expect(trap) -> entry with"
- "~n Enterp: ~w"
- "~n Generic: ~w"
- "~n Specific: ~w"
- "~n ExpVBs: ~w"
- "~n To: ~w"
- "~nwhen"
- "~n Time: ~w"
- "~n", [?MODULE, Enterp, Generic, Specific, ExpVBs, To, t()]),
+ io:format("EXPECT trap"
+ "~n with"
+ "~n Enterp: ~w"
+ "~n Generic: ~w"
+ "~n Specific: ~w"
+ "~n Varbinds: ~w"
+ "~n within ~w~n", [Enterp, Generic, Specific, ExpVBs, To]),
PureE = purify_oid(Enterp),
case receive_trap(To) of
#trappdu{enterprise = PureE,
@@ -916,49 +932,51 @@ do_expect2(Check, Type, Err, Idx, ExpVBs, To)
(is_list(ExpVBs) orelse (ExpVBs =:= any)) andalso
(is_integer(To) orelse (To =:= infinity)) ->
- io:format("~w:do_expect2 -> entry with"
- "~n Type: ~w"
- "~n Err: ~w"
- "~n Idx: ~w"
- "~n ExpVBs: ~w"
- "~n To: ~w"
- "~nwhen"
- "~n Time: ~w"
- "~n", [?MODULE, Type, Err, Idx, ExpVBs, To, t()]),
-
case receive_pdu(To) of
#pdu{type = Type,
error_status = Err,
error_index = Idx} when ExpVBs =:= any ->
+ io:format("EXPECT received expected pdu (1)~n", []),
ok;
#pdu{type = Type,
request_id = ReqId,
error_status = Err2,
error_index = Idx} when ExpVBs =:= any ->
+ io:format("EXPECT received expected pdu with "
+ "unexpected error status (2): "
+ "~n Error Status: ~p~n", [Err2]),
{error, {unexpected_error_status, Err, Err2, ReqId}};
#pdu{error_status = Err} when (Type =:= any) andalso
(Idx =:= any) andalso
(ExpVBs =:= any) ->
+ io:format("EXPECT received expected pdu (3)~n", []),
ok;
#pdu{request_id = ReqId,
error_status = Err2} when (Type =:= any) andalso
(Idx =:= any) andalso
(ExpVBs =:= any) ->
+ io:format("EXPECT received expected pdu with "
+ "unexpected error status (4): "
+ "~n Error Status: ~p~n", [Err2]),
{error, {unexpected_error_status, Err, Err2, ReqId}};
#pdu{type = Type,
error_status = Err} when (Idx =:= any) andalso
(ExpVBs =:= any) ->
+ io:format("EXPECT received expected pdu (5)~n", []),
ok;
#pdu{type = Type,
request_id = ReqId,
error_status = Err2} when (Idx =:= any) andalso
(ExpVBs =:= any) ->
+ io:format("EXPECT received expected pdu with "
+ "unexpected error status (6): "
+ "~n Error Status: ~p~n", [Err2]),
{error, {unexpected_error_status, Err, Err2, ReqId}};
#pdu{type = Type,
@@ -967,8 +985,13 @@ do_expect2(Check, Type, Err, Idx, ExpVBs, To)
error_index = EI} when is_list(Idx) andalso (ExpVBs =:= any) ->
case lists:member(EI, Idx) of
true ->
+ io:format("EXPECT received expected pdu with "
+ "expected error index (7)~n", []),
ok;
false ->
+ io:format("EXPECT received expected pdu with "
+ "unexpected error index (8): "
+ "~n Error Index: ~p~n", [EI]),
{error, {unexpected_error_index, EI, Idx, ReqId}}
end;
@@ -978,8 +1001,15 @@ do_expect2(Check, Type, Err, Idx, ExpVBs, To)
error_index = EI} when is_list(Idx) andalso (ExpVBs =:= any) ->
case lists:member(EI, Idx) of
true ->
+ io:format("EXPECT received expected pdu with "
+ "unexpected error status (9): "
+ "~n Error Status: ~p~n", [Err2]),
{error, {unexpected_error_status, Err, Err2, ReqId}};
false ->
+ io:format("EXPECT received expected pdu with "
+ "unexpected error (10): "
+ "~n Error Status: ~p"
+ "~n Error index: ~p~n", [Err2, EI]),
{error, {unexpected_error, {Err, Idx}, {Err2, EI}, ReqId}}
end;
@@ -987,6 +1017,12 @@ do_expect2(Check, Type, Err, Idx, ExpVBs, To)
request_id = ReqId,
error_status = Err2,
error_index = Idx2} when ExpVBs =:= any ->
+ io:format("EXPECT received unexpected pdu with (11) "
+ "~n Type: ~p"
+ "~n ReqId: ~p"
+ "~n Errot status: ~p"
+ "~n Error index: ~p"
+ "~n", [Type2, ReqId, Err2, Idx2]),
{error,
{unexpected_pdu,
{Type, Err, Idx}, {Type2, Err2, Idx2}, ReqId}};
@@ -995,11 +1031,26 @@ do_expect2(Check, Type, Err, Idx, ExpVBs, To)
error_status = Err,
error_index = Idx,
varbinds = VBs} = PDU ->
+ io:format("EXPECT received pdu (12): "
+ "~n [exp] Type: ~p"
+ "~n [exp] Error Status: ~p"
+ "~n [exp] Error Index: ~p"
+ "~n VBs: ~p"
+ "~nwhen"
+ "~n ExpVBs: ~p"
+ "~n", [Type, Err, Idx, VBs, ExpVBs]),
Check(PDU, check_vbs(purify_oids(ExpVBs), VBs));
#pdu{type = Type,
error_status = Err,
varbinds = VBs} = PDU when Idx =:= any ->
+ io:format("EXPECT received pdu (13): "
+ "~n [exp] Type: ~p"
+ "~n [exp] Error Status: ~p"
+ "~n VBs: ~p"
+ "~nwhen"
+ "~n ExpVBs: ~p"
+ "~n", [Type, Err, VBs, ExpVBs]),
Check(PDU, check_vbs(purify_oids(ExpVBs), VBs));
#pdu{type = Type,
@@ -1007,6 +1058,15 @@ do_expect2(Check, Type, Err, Idx, ExpVBs, To)
error_status = Err,
error_index = EI,
varbinds = VBs} = PDU when is_list(Idx) ->
+ io:format("EXPECT received pdu (14): "
+ "~n [exp] Type: ~p"
+ "~n ReqId: ~p"
+ "~n [exp] Error Status: ~p"
+ "~n [exp] Error Index: ~p"
+ "~n VBs: ~p"
+ "~nwhen"
+ "~n ExpVBs: ~p"
+ "~n", [Type, ReqId, Err, EI, VBs, ExpVBs]),
PureVBs = purify_oids(ExpVBs),
case lists:member(EI, Idx) of
true ->
@@ -1020,6 +1080,13 @@ do_expect2(Check, Type, Err, Idx, ExpVBs, To)
error_status = Err2,
error_index = Idx2,
varbinds = VBs2} ->
+ io:format("EXPECT received unexpected pdu with (15) "
+ "~n Type: ~p"
+ "~n ReqId: ~p"
+ "~n Errot status: ~p"
+ "~n Error index: ~p"
+ "~n Varbinds: ~p"
+ "~n", [Type2, ReqId, Err2, Idx2, VBs2]),
{error,
{unexpected_pdu,
{Type, Err, Idx, purify_oids(ExpVBs)},
@@ -1027,6 +1094,9 @@ do_expect2(Check, Type, Err, Idx, ExpVBs, To)
ReqId}};
Error ->
+ io:format("EXPECT received error (16): "
+ "~n Error: ~p"
+ "~n", [Error]),
Error
end.
@@ -1311,10 +1381,12 @@ rewrite_target_addr_conf(Dir, NewPort) ->
"~n NewPort: ~p", [NewPort]),
TAFile = filename:join(Dir, "target_addr.conf"),
case file:read_file_info(TAFile) of
- {ok, _} -> ok;
- {error, R} -> ?ERR("failure reading file info of "
- "target address config file: ~p",[R]),
- ok
+ {ok, _} ->
+ ok;
+ {error, R} ->
+ ?ERR("failure reading file info of "
+ "target address config file: ~p",[R]),
+ ok
end,
?line [TrapAddr|Addrs] =
@@ -1335,8 +1407,9 @@ rewrite_target_addr_conf(Dir, NewPort) ->
rewrite_target_addr_conf_check(O) ->
{ok,O}.
-rewrite_target_addr_conf2(NewPort,{Name,Ip,_Port,Timeout,Retry,
- "std_trap",EngineId}) ->
+rewrite_target_addr_conf2(NewPort,
+ {Name, Ip, _Port, Timeout, Retry,
+ "std_trap", EngineId}) ->
?LOG("rewrite_target_addr_conf2 -> entry with std_trap",[]),
{Name,Ip,NewPort,Timeout,Retry,"std_trap",EngineId};
rewrite_target_addr_conf2(_NewPort,O) ->
@@ -1463,7 +1536,7 @@ rpc(Node, F, A) ->
%%
%%
%% t() ->
-%% {A,B,C} = erlang:now(),
+%% {A,B,C} = os:timestamp(),
%% A*1000000000+B*1000+(C div 1000).
%%
%%
@@ -1475,6 +1548,6 @@ rpc(Node, F, A) ->
%% Time in milli seconds
-t() ->
- {A,B,C} = erlang:now(),
- A*1000000000+B*1000+(C div 1000).
+%% t() ->
+%% {A,B,C} = os:timestamp(),
+%% A*1000000000+B*1000+(C div 1000).
diff --git a/lib/snmp/test/snmp_compiler_test.erl b/lib/snmp/test/snmp_compiler_test.erl
index 9a9127a130..ad77b01362 100644
--- a/lib/snmp/test/snmp_compiler_test.erl
+++ b/lib/snmp/test/snmp_compiler_test.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2003-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 2003-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%
%%
@@ -46,7 +46,9 @@
module_identity/1,
tickets/1,
- otp_6150/1
+ otp_6150/1,
+ otp_8574/1,
+ otp_8595/1
]).
@@ -56,6 +58,7 @@
-export([
]).
+
%%----------------------------------------------------------------------
%% Macros
%%----------------------------------------------------------------------
@@ -98,7 +101,9 @@ all(suite) ->
tickets(suite) ->
[
- otp_6150
+ otp_6150,
+ otp_8574,
+ otp_8595
].
@@ -178,6 +183,54 @@ otp_6150(Config) when is_list(Config) ->
ok.
+otp_8574(suite) ->
+ [];
+otp_8574(Config) when is_list(Config) ->
+ put(tname,otp_8574),
+ p("starting with Config: ~p~n", [Config]),
+
+ Dir = ?config(comp_dir, Config),
+ MibDir = ?config(mib_dir, Config),
+ MibFile = join(MibDir, "OTP8574-MIB.mib"),
+
+ p("ensure compile fail without relaxed assign check"),
+ case snmpc:compile(MibFile, [{group_check, false}, {outdir, Dir}]) of
+ {error, compilation_failed} ->
+ p("with relaxed assign check MIB compiles with warning"),
+ case snmpc:compile(MibFile, [{group_check, false},
+ {outdir, Dir},
+ relaxed_row_name_assign_check]) of
+ {ok, _Mib} ->
+ ok;
+ {error, Reason} ->
+ p("unexpected compile failure: "
+ "~n Reason: ~p", [Reason]),
+ exit({unexpected_compile_failure, Reason})
+ end;
+
+ {ok, _} ->
+ p("unexpected compile success"),
+ exit(unexpected_compile_success)
+ end.
+
+
+otp_8595(suite) ->
+ [];
+otp_8595(Config) when is_list(Config) ->
+ put(tname,otp_8595),
+ p("starting with Config: ~p~n", [Config]),
+
+ Dir = ?config(comp_dir, Config),
+ MibDir = ?config(mib_dir, Config),
+ MibFile = join(MibDir, "OTP8595-MIB.mib"),
+ ?line {ok, Mib} =
+ snmpc:compile(MibFile, [{outdir, Dir},
+ {verbosity, trace},
+ {group_check, false}]),
+ io:format("otp_8595 -> Mib: ~n~p~n", [Mib]),
+ ok.
+
+
%%======================================================================
%% Internal functions
%%======================================================================
@@ -373,6 +426,9 @@ join(A,B) ->
%% p(F) ->
%% p(F, []).
+p(F) ->
+ p(F, []).
+
p(F, A) ->
p(get(tname), F, A).
diff --git a/lib/snmp/test/snmp_log_test.erl b/lib/snmp/test/snmp_log_test.erl
index b4694fd9ab..91bdc3e849 100644
--- a/lib/snmp/test/snmp_log_test.erl
+++ b/lib/snmp/test/snmp_log_test.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2003-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 2003-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%
%%
@@ -45,20 +45,30 @@
all/1,
open_and_close/1,
open_write_and_close/1,
+ open_write_and_close1/1,
+ open_write_and_close2/1,
+ open_write_and_close3/1,
+ open_write_and_close4/1,
+ log_to_io/1,
log_to_io1/1,
log_to_io2/1,
+ log_to_txt/1,
log_to_txt1/1,
- log_to_txt2/1
+ log_to_txt2/1,
+ log_to_txt3/1
]).
+
%%----------------------------------------------------------------------
%% Internal exports
%%----------------------------------------------------------------------
-export([
log_writer_main/5,
- log_reader_main/1
+ log_reader_main/1,
+ next_seqno/2
]).
+
%%----------------------------------------------------------------------
%% Macros
%%----------------------------------------------------------------------
@@ -102,10 +112,32 @@ all(suite) ->
[
open_and_close,
open_write_and_close,
+ log_to_io,
+ log_to_txt
+ ].
+
+
+open_write_and_close(suite) ->
+ [
+ open_write_and_close1,
+ open_write_and_close2,
+ open_write_and_close3,
+ open_write_and_close4
+ ].
+
+
+log_to_io(suite) ->
+ [
log_to_io1,
- log_to_io2,
+ log_to_io2
+ ].
+
+
+log_to_txt(suite) ->
+ [
log_to_txt1,
- log_to_txt2
+ log_to_txt2,
+ log_to_txt3
].
@@ -132,24 +164,129 @@ open_and_close(Config) when is_list(Config) ->
%%======================================================================
-open_write_and_close(suite) -> [];
-open_write_and_close(Config) when is_list(Config) ->
- p(open_write_and_close),
- put(sname,open_write_and_close),
+open_write_and_close1(suite) ->
+ [];
+open_write_and_close1(doc) ->
+ "Open a plain (no sequence-numbering) log file";
+open_write_and_close1(Config) when is_list(Config) ->
+ p(open_write_and_close1),
+ put(sname,open_write_and_close1),
+ put(verbosity,trace),
+ ?DBG("open_write_and_close1 -> start", []),
+
+ SeqNoGen = none,
+ ?line ok = open_write_and_close(SeqNoGen, Config),
+
+ ?DBG("open_write_and_close1 -> done", []),
+ ok.
+
+
+%%======================================================================
+
+open_write_and_close2(suite) ->
+ [];
+open_write_and_close2(doc) ->
+ "Open a log file with sequence-numbering explicitly disabled";
+open_write_and_close2(Config) when is_list(Config) ->
+ p(open_write_and_close2),
+ put(sname,open_write_and_close2),
+ put(verbosity,trace),
+ ?DBG("open_write_and_close2 -> start", []),
+
+ SeqNoGen = disabled,
+ ?line ok = open_write_and_close(SeqNoGen, Config),
+
+ ?DBG("open_write_and_close2 -> done", []),
+ ok.
+
+
+%%======================================================================
+
+open_write_and_close3(suite) ->
+ [];
+open_write_and_close3(doc) ->
+ "Open a log file with sequence-numbering using MFA";
+open_write_and_close3(Config) when is_list(Config) ->
+ p(open_write_and_close3),
+ put(sname,open_write_and_close3),
+ put(verbosity,trace),
+ ?DBG("open_write_and_close2 -> start", []),
+
+ seqno_init(),
+ SeqNoGen = {?MODULE, next_seqno, [10, 100]},
+ ?line ok = open_write_and_close(SeqNoGen, Config),
+ seqno_finish(),
+
+ ?DBG("open_write_and_close2 -> done", []),
+ ok.
+
+
+%%======================================================================
+
+open_write_and_close4(suite) ->
+ [];
+open_write_and_close4(doc) ->
+ "Open a log file with sequence-numbering using fun";
+open_write_and_close4(Config) when is_list(Config) ->
+ p(open_write_and_close4),
+ put(sname,open_write_and_close4),
put(verbosity,trace),
- ?DBG("open_write_and_close -> start", []),
+ ?DBG("open_write_and_close2 -> start", []),
+
+ seqno_init(),
+ SeqNoGen = fun() -> next_seqno(10, 100) end,
+ ?line ok = open_write_and_close(SeqNoGen, Config),
+ seqno_finish(),
+
+ ?DBG("open_write_and_close2 -> done", []),
+ ok.
+
+
+%%======================================================================
+
+seqno_init() ->
+ ets:new(snmp_log_test_seqno_tab, [named_table, set, protected]).
+
+seqno_finish() ->
+ ets:delete(snmp_log_test_seqno_tab).
+
+next_seqno(Initial, Max) ->
+ Key = seqno,
+ Position = 2,
+ Increment = 1,
+ Threshold = Max,
+ SetValue = Initial,
+ UpdateOp = {Position, Increment, Threshold, SetValue},
+ Tab = snmp_log_test_seqno_tab,
+ case (catch ets:update_counter(Tab, Key, UpdateOp)) of
+ {'EXIT', {badarg, _}} ->
+ ets:insert(Tab, {seqno, Initial}),
+ Initial;
+ Next when is_integer(Next) ->
+ Next
+ end.
+
+open_write_and_close(SeqNoGen, Config) ->
+ ?DBG("open_write_and_close1 -> start", []),
Dir = ?config(log_dir, Config),
Name = "snmp_test",
File = join(Dir, "snmp_test.log"),
Size = {1024, 10},
Repair = true,
?DBG("open_write_and_close -> create log", []),
- ?line {ok, Log} = snmp_log:create(Name, File, Size, Repair),
+
+ ?line {ok, Log} =
+ case SeqNoGen of
+ none ->
+ snmp_log:create(Name, File, Size, Repair);
+ _ ->
+ snmp_log:create(Name, File, SeqNoGen, Size, Repair)
+ end,
Vsn = 'version-2',
Community = "all-rights",
- ?DBG("open_write_and_close -> create messages to log", []),
+ ?DBG("open_write_and_close1 -> create messages to log", []),
%% A request
?line Req = get_next_request(Vsn, Community, [1,1], 1, 235779012),
@@ -162,7 +299,7 @@ open_write_and_close(Config) when is_list(Config) ->
Msgs = lists:flatten(lists:duplicate(1002,[Req,Rep])),
%% And now log them:
- ?DBG("open_write_and_close -> log ~p messages, ~p bytes",
+ ?DBG("open_write_and_close1 -> log ~p messages, ~p bytes",
[length(Msgs), size(list_to_binary(Msgs))]),
Addr = ?LOCALHOST(),
Port = 162,
@@ -172,11 +309,11 @@ open_write_and_close(Config) when is_list(Config) ->
lists:foreach(Logger, Msgs),
check_notify(),
- ?DBG("open_write_and_close -> display info", []),
+ ?DBG("open_write_and_close1 -> display info", []),
?line {ok, Info} = snmp_log:info(Log),
display_info(Info),
- ?DBG("open_write_and_close -> close log", []),
+ ?DBG("open_write_and_close1 -> close log", []),
?line ok = snmp_log:close(Log),
?DBG("open_write_and_close -> done", []),
@@ -308,18 +445,58 @@ log_to_txt1(Config) when is_list(Config) ->
put(sname,l2t1),
put(verbosity,trace),
?DBG("log_to_txt1 -> start", []),
+
+ Name = "snmp_test_l2t1",
+ SeqNoGen = disabled,
+ ?line ok = log_to_txt(Name, SeqNoGen, Config),
+
+ ?DBG("log_to_txt1 -> done", []),
+ ok.
+
+
+
+%%======================================================================
+
+log_to_txt2(suite) -> [];
+log_to_txt2(Config) when is_list(Config) ->
+ p(log_to_txt2),
+ put(sname,l2t2),
+ put(verbosity,trace),
+ ?DBG("log_to_txt2 -> start", []),
+
+ Name = "snmp_test_l2t2",
+ seqno_init(),
+ SeqNoGen = {?MODULE, next_seqno, [1, 100]},
+ ?line ok = log_to_txt(Name, SeqNoGen, Config),
+ seqno_finish(),
+
+ ?DBG("log_to_txt2 -> done", []),
+ ok.
+
+
+
+%%======================================================================
+
+log_to_txt(Name, SeqNoGen, Config) when is_list(Config) ->
+ ?DBG("log_to_txt -> entry", []),
Dir = ?config(log_dir, Config),
- Name = "snmp_test_l2t1",
- File = join(Dir, "snmp_test_l2t1.log"),
+ File = join(Dir, Name ++ ".log"),
Size = {10240, 10},
Repair = true,
- ?DBG("log_to_txt1 -> create log", []),
- ?line {ok, Log} = snmp_log:create(Name, File, Size, Repair),
- ?DBG("log_to_txt1 -> create messages to log", []),
+ ?DBG("log_to_txt -> create log", []),
+ ?line {ok, Log} =
+ case SeqNoGen of
+ none ->
+ snmp_log:create(Name, File, Size, Repair);
+ _ ->
+ snmp_log:create(Name, File, SeqNoGen, Size, Repair)
+ end,
+
+ ?DBG("log_to_txt -> create messages to log", []),
Msgs = messages(),
- ?DBG("log_to_txt1 -> create logger funs", []),
+ ?DBG("log_to_txt -> create logger funs", []),
Addr = ?LOCALHOST(),
Port = 162,
Logger = fun(Packet) ->
@@ -332,42 +509,42 @@ log_to_txt1(Config) when is_list(Config) ->
end,
To = lists:duplicate(20, 5000),
- ?DBG("log_to_txt1 -> log the messages", []),
+ ?DBG("log_to_txt -> log the messages", []),
Start = calendar:local_time(),
lists:foreach(BatchLogger, To),
Stop = calendar:local_time(),
- ?DBG("log_to_txt1 -> display info", []),
+ ?DBG("log_to_txt -> display info", []),
?line {ok, Info} = snmp_log:info(Log),
display_info(Info),
Out1 = join(Dir, "snmp_text-1.txt"),
- ?DBG("log_to_txt1 -> do the convert to a text file when"
+ ?DBG("log_to_txt -> do the convert to a text file when"
"~n Out1: ~p", [Out1]),
?line ok = snmp:log_to_txt(Dir, [], Out1, Log, File),
?line {ok, #file_info{size = Size1}} = file:read_file_info(Out1),
- ?DBG("log_to_txt1 -> text file size: ~p", [Size1]),
+ ?DBG("log_to_txt -> text file size: ~p", [Size1]),
validate_size(Size1),
Out2 = join(Dir, "snmp_text-2.txt"),
- ?DBG("log_to_txt1 -> do the convert to a text file when"
+ ?DBG("log_to_txt -> do the convert to a text file when"
"~n Start: ~p"
"~n Stop: ~p"
"~n Out2: ~p", [Start, Stop, Out2]),
?line ok = snmp:log_to_txt(Dir, [], Out2, Log, File, Start, Stop),
?line {ok, #file_info{size = Size2}} = file:read_file_info(Out2),
- ?DBG("log_to_txt1 -> text file size: ~p", [Size2]),
+ ?DBG("log_to_txt -> text file size: ~p", [Size2]),
validate_size(Size2, {le, Size1}),
%% Calculate new start / stop times...
GStart = calendar:datetime_to_gregorian_seconds(Start),
- ?DBG("log_to_txt1 -> GStart: ~p", [GStart]),
+ ?DBG("log_to_txt -> GStart: ~p", [GStart]),
GStop = calendar:datetime_to_gregorian_seconds(Stop),
- ?DBG("log_to_txt1 -> GStop: ~p", [GStop]),
+ ?DBG("log_to_txt -> GStop: ~p", [GStop]),
Diff4 = (GStop - GStart) div 4,
- ?DBG("log_to_txt1 -> Diff4: ~p", [Diff4]),
+ ?DBG("log_to_txt -> Diff4: ~p", [Diff4]),
GStart2 = GStart + Diff4,
GStop2 = GStop - Diff4,
if
@@ -381,20 +558,20 @@ log_to_txt1(Config) when is_list(Config) ->
Stop2 = calendar:gregorian_seconds_to_datetime(GStop2),
Out3 = join(Dir, "snmp_text-3.txt"),
- ?DBG("log_to_txt1 -> do the convert to a text file when"
+ ?DBG("log_to_txt -> do the convert to a text file when"
"~n Start2: ~p"
"~n Stop2: ~p"
"~n Out3: ~p", [Start2, Stop2, Out3]),
?line ok = snmp:log_to_txt(Dir, [], Out3, Log, File, Start2, Stop2),
?line {ok, #file_info{size = Size3}} = file:read_file_info(Out3),
- ?DBG("log_to_txt1 -> text file size: ~p", [Size3]),
+ ?DBG("log_to_txt -> text file size: ~p", [Size3]),
validate_size(Size3, {l, Size1}),
- ?DBG("log_to_txt1 -> close log", []),
+ ?DBG("log_to_txt -> close log", []),
?line ok = snmp_log:close(Log),
- ?DBG("log_to_txt1 -> done", []),
+ ?DBG("log_to_txt -> done", []),
ok.
@@ -405,19 +582,21 @@ log_to_txt1(Config) when is_list(Config) ->
%%
%% Test: ts:run(snmp, snmp_log_test, log_to_txt2, [batch]).
-log_to_txt2(suite) -> [];
-log_to_txt2(doc) -> "Log to txt file from a different process than which "
- "opened and wrote the log";
-log_to_txt2(Config) when is_list(Config) ->
+log_to_txt3(suite) ->
+ [];
+log_to_txt3(doc) ->
+ "Log to txt file from a different process than which "
+ "opened and wrote the log";
+log_to_txt3(Config) when is_list(Config) ->
process_flag(trap_exit, true),
- p(log_to_txt2),
- put(sname,l2t2),
+ p(log_to_txt3),
+ put(sname,l2t3),
put(verbosity,trace),
- ?DBG("log_to_txt2 -> start", []),
+ ?DBG("log_to_txt3 -> start", []),
Dir = ?config(log_dir, Config),
- Name = "snmp_test_l2t2",
- LogFile = join(Dir, "snmp_test_l2t2.log"),
- TxtFile = join(Dir, "snmp_test_l2t2.txt"),
+ Name = "snmp_test_l2t3",
+ LogFile = join(Dir, "snmp_test_l2t3.log"),
+ TxtFile = join(Dir, "snmp_test_l2t3.txt"),
Meg = 1024*1024,
Size = {10*Meg, 10},
Repair = true,
@@ -425,22 +604,22 @@ log_to_txt2(Config) when is_list(Config) ->
StdMibDir = filename:join(code:priv_dir(snmp), "mibs") ++ "/",
Mibs = [join(StdMibDir, "SNMPv2-MIB")],
- ?DBG("log_to_txt2 -> create log writer process", []),
+ ?DBG("log_to_txt3 -> create log writer process", []),
?line {ok, Log, Logger} = log_writer_start(Name, LogFile, Size, Repair),
- ?DBG("log_to_txt2 -> create log reader process", []),
+ ?DBG("log_to_txt3 -> create log reader process", []),
?line {ok, Reader} = log_reader_start(),
- ?DBG("log_to_txt2 -> wait some time", []),
+ ?DBG("log_to_txt3 -> wait some time", []),
?SLEEP(5000),
- ?DBG("log_to_txt2 -> display log info", []),
+ ?DBG("log_to_txt3 -> display log info", []),
?line log_writer_info(Logger),
- ?DBG("log_to_txt2 -> instruct the log writer to sleep some", []),
+ ?DBG("log_to_txt3 -> instruct the log writer to sleep some", []),
?line ok = log_writer_sleep(Logger, 5000),
- ?DBG("log_to_txt2 -> instruct the log reader to log to txt", []),
+ ?DBG("log_to_txt3 -> instruct the log reader to log to txt", []),
Res =
log_reader_log_to(Reader,
fun() ->
@@ -457,25 +636,25 @@ log_to_txt2(Config) when is_list(Config) ->
case Res of
{ok, Info} ->
- ?DBG("log_to_txt2 -> ~n Info: ~p", [Info]),
+ ?DBG("log_to_txt3 -> ~n Info: ~p", [Info]),
?line {ok, #file_info{size = FileSize}} =
file:read_file_info(TxtFile),
- ?DBG("log_to_txt2 -> text file size: ~p", [FileSize]),
+ ?DBG("log_to_txt3 -> text file size: ~p", [FileSize]),
validate_size(FileSize);
{Error, Info} ->
- ?DBG("log_to_txt2 -> log to txt failed: "
+ ?DBG("log_to_txt3 -> log to txt failed: "
"~n Error: ~p"
"~n Info: ~p", [Error, Info]),
?line ?FAIL({log_lo_txt_failed, Error, Info})
end,
- ?DBG("log_to_txt2 -> instruct the log writer to stop", []),
+ ?DBG("log_to_txt3 -> instruct the log writer to stop", []),
?line log_writer_stop(Logger),
- ?DBG("log_to_txt2 -> instruct the log reader to stop", []),
+ ?DBG("log_to_txt3 -> instruct the log reader to stop", []),
?line log_reader_stop(Reader),
- ?DBG("log_to_txt2 -> done", []),
+ ?DBG("log_to_txt3 -> done", []),
ok.
diff --git a/lib/snmp/test/snmp_manager_config_test.erl b/lib/snmp/test/snmp_manager_config_test.erl
index 51325996e6..d5dc1387f7 100644
--- a/lib/snmp/test/snmp_manager_config_test.erl
+++ b/lib/snmp/test/snmp_manager_config_test.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2004-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 2004-2010. All Rights Reserved.
+%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
-%%
+%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
-%%
+%%
%% %CopyrightEnd%
%%
@@ -86,7 +86,12 @@
stats_create_and_increment/1,
tickets/1,
- otp_7219/1
+ otp_7219/1,
+ otp_8395/1,
+ otp_8395_1/1,
+ otp_8395_2/1,
+ otp_8395_3/1,
+ otp_8395_4/1
]).
@@ -1439,10 +1444,9 @@ start_with_invalid_usm_conf_file1(Conf) when is_list(Conf) ->
p("[test 54] write usm config file with invalid auth-key (4)"),
Usm54 = setelement(4, Usm51, "[1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,kalle]"),
write_usm_conf(ConfDir, [Usm54]),
- %% ?line ok = crypto:start(), %% Varf�r k�r den redan?
- ?line crypto:start(), %% Make sure it's started...
+ ?line maybe_start_crypto(), %% Make sure it's started...
?line {error, Reason54} = config_start(Opts),
- ?line ok = crypto:stop(),
+ ?line ok = maybe_stop_crypto(),
p("start failed (as expected): ~p", [Reason54]),
?line {failed_check, _, _, _, {invalid_auth_key, _}} = Reason54,
await_config_not_running(),
@@ -1487,21 +1491,35 @@ start_with_invalid_usm_conf_file1(Conf) when is_list(Conf) ->
p("[test 59] write usm config file with invalid auth-key (9)"),
Usm59 = setelement(4, Usm57, "[1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9,ka]"),
write_usm_conf(ConfDir, [Usm59]),
- ?line ok = crypto:start(),
+ ?line ok = maybe_start_crypto(),
?line {error, Reason59} = config_start(Opts),
- ?line ok = crypto:stop(),
+ ?line ok = maybe_stop_crypto(),
p("start failed (as expected): ~p", [Reason59]),
?line {failed_check, _, _, _, {invalid_auth_key, _}} = Reason59,
await_config_not_running(),
%% --
- p("[test 5A] write usm config file with valid auth-key when crypto not started (10)"),
- Usm5A = setelement(4, Usm57, "[1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9,0]"),
- write_usm_conf(ConfDir, [Usm5A]),
- ?line {error, Reason5A} = config_start(Opts),
- p("start failed (as expected): ~p", [Reason5A]),
- ?line {failed_check, _, _, _, {unsupported_crypto, _}} = Reason5A,
- await_config_not_running(),
+ %% <CRYPTO-MODIFICATIONS>
+ %% The crypto application do no longer need to be started
+ %% explicitly (all of it is as of R14 implemented with NIFs).
+ case (catch crypto:version()) of
+ {'EXIT', {undef, _}} ->
+ p("[test 5A] write usm config file with valid auth-key "
+ "when crypto not started (10)"),
+ Usm5A = setelement(4,
+ Usm57,
+ "[1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9,0]"),
+ write_usm_conf(ConfDir, [Usm5A]),
+ ?line {error, Reason5A} = config_start(Opts),
+ p("start failed (as expected): ~p", [Reason5A]),
+ ?line {failed_check, _, _, _, {unsupported_crypto, _}} = Reason5A,
+ await_config_not_running();
+ _ ->
+ %% This function is only present in version 2.0 or greater.
+ %% The crypto app no longer needs to be explicitly started
+ ok
+ end,
+ %% </CRYPTO-MODIFICATIONS>
%% --
p("[test 61] write usm config file with invalid priv-protocol (1)"),
@@ -1561,9 +1579,9 @@ start_with_invalid_usm_conf_file1(Conf) when is_list(Conf) ->
p("[test 74] write usm config file with invalid priv-key (4)"),
Usm74 = setelement(6, Usm71, "[1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,kalle]"),
write_usm_conf(ConfDir, [Usm74]),
- ?line ok = crypto:start(),
+ ?line ok = maybe_start_crypto(),
?line {error, Reason74} = config_start(Opts),
- ?line ok = crypto:stop(),
+ ?line ok = maybe_stop_crypto(),
p("start failed (as expected): ~p", [Reason74]),
?line {failed_check, _, _, _, {invalid_priv_key, _}} = Reason74,
await_config_not_running(),
@@ -1587,15 +1605,27 @@ start_with_invalid_usm_conf_file1(Conf) when is_list(Conf) ->
await_config_not_running(),
%% --
- p("[test 77] write usm config file with valid priv-key when crypto not started (7)"),
- Usm77 = setelement(6, Usm71, "[1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6]"),
- write_usm_conf(ConfDir, [Usm77]),
- ?line {error, Reason77} = config_start(Opts),
- p("start failed (as expected): ~p", [Reason77]),
- ?line {failed_check, _, _, _, {unsupported_crypto, _}} = Reason77,
- await_config_not_running(),
+ %% <CRYPTO-MODIFICATIONS>
+ %% The crypto application do no longer need to be started
+ %% explicitly (all of it is as of R14 implemented with NIFs).
+ case (catch crypto:version()) of
+ {'EXIT', {undef, _}} ->
+ p("[test 77] write usm config file with valid priv-key "
+ "when crypto not started (7)"),
+ Usm77 = setelement(6, Usm71, "[1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6]"),
+ write_usm_conf(ConfDir, [Usm77]),
+ ?line {error, Reason77} = config_start(Opts),
+ p("start failed (as expected): ~p", [Reason77]),
+ ?line {failed_check, _, _, _, {unsupported_crypto, _}} = Reason77,
+ await_config_not_running();
+ _ ->
+ %% This function is only present in version 2.0 or greater.
+ %% The crypto app no longer needs to be explicitly started
+ ok
+ end,
+ %% </CRYPTO-MODIFICATIONS>
- %% --
+ %% --
p("[test 78] write usm config file with invalid usm (1)"),
write_usm_conf2(ConfDir, "{\"bmkEngine\", \"swiusmcf\"}."),
?line {error, Reason81} = config_start(Opts),
@@ -2295,7 +2325,8 @@ loop(N, _, F) when (N > 0) andalso is_function(F) ->
tickets(suite) ->
[
- otp_7219
+ otp_7219,
+ otp_8395
].
@@ -2347,6 +2378,170 @@ otp_7219(Config) when is_list(Config) ->
ok.
+
+otp_8395(suite) ->
+ [
+ otp_8395_1,
+ otp_8395_2,
+ otp_8395_3,
+ otp_8395_4
+ ].
+
+otp_8395_1(suite) -> [];
+otp_8395_1(doc) ->
+ "OTP-8395(1)";
+otp_8395_1(Conf) when is_list(Conf) ->
+ put(tname, otp_8395_1),
+ p("start"),
+ process_flag(trap_exit, true),
+ otp8395(Conf, false, ok),
+ ok.
+
+otp_8395_2(suite) -> [];
+otp_8395_2(doc) ->
+ "OTP-8395(2)";
+otp_8395_2(Conf) when is_list(Conf) ->
+ put(tname, otp_8395_2),
+ p("start"),
+ process_flag(trap_exit, true),
+ otp8395(Conf, true, ok),
+ ok.
+
+otp_8395_3(suite) -> [];
+otp_8395_3(doc) ->
+ "OTP-8395(3)";
+otp_8395_3(Conf) when is_list(Conf) ->
+ put(tname, otp_8395_3),
+ p("start"),
+ process_flag(trap_exit, true),
+ otp8395(Conf, gurka, error),
+ ok.
+
+otp8395(Conf, SeqNoVal, Expect) ->
+ ConfDir = ?config(manager_conf_dir, Conf),
+ DbDir = ?config(manager_db_dir, Conf),
+ LogDir = ?config(manager_log_dir, Conf),
+ StdMibDir = filename:join(code:priv_dir(snmp), "mibs") ++ "/",
+
+ write_manager_conf(ConfDir),
+
+ %% Third set of options (no versions):
+ p("all options"),
+ NetIfOpts = [{module, snmpm_net_if},
+ {verbosity, trace},
+ {options, [{recbuf, 30000},
+ {bind_to, false},
+ {no_reuse, false}]}],
+ ServerOpts = [{timeout, 10000}, {verbosity, trace}],
+ NoteStoreOpts = [{timeout, 20000}, {verbosity, trace}],
+ ConfigOpts = [{dir, ConfDir}, {verbosity, trace}, {db_dir, DbDir}],
+ Mibs = [join(StdMibDir, "SNMP-NOTIFICATION-MIB"),
+ join(StdMibDir, "SNMP-USER-BASED-SM-MIB")],
+ Prio = normal,
+ ATL = [{type, read_write},
+ {dir, LogDir},
+ {size, {10,10240}},
+ {repair, true},
+ {seqno, SeqNoVal}],
+ Vsns = [v1,v2,v3],
+ Opts = [{config, ConfigOpts},
+ {net_if, NetIfOpts},
+ {server, ServerOpts},
+ {note_store, NoteStoreOpts},
+ {audit_trail_log, ATL},
+ {priority, Prio},
+ {mibs, Mibs},
+ {versions, Vsns}],
+
+ case config_start(Opts) of
+ {ok, _Pid} when (Expect =:= ok) ->
+ ?line ok = config_stop(),
+ ok;
+ {ok, _Pid} when (Expect =/= ok) ->
+ config_stop(),
+ exit({unexpected_started_config, SeqNoVal});
+ _Error when (Expect =/= ok) ->
+ ok;
+ Error when (Expect =:= ok) ->
+ exit({unexpected_failed_starting_config, SeqNoVal, Error})
+ end,
+ p("done"),
+ ok.
+
+
+otp_8395_4(suite) -> [];
+otp_8395_4(doc) ->
+ "OTP-8395(4)";
+otp_8395_4(Conf) when is_list(Conf) ->
+ put(tname, otp_8395_4),
+ p("start"),
+ process_flag(trap_exit, true),
+
+ snmp:print_version_info(),
+
+ ConfDir = ?config(manager_conf_dir, Conf),
+ DbDir = ?config(manager_db_dir, Conf),
+ LogDir = ?config(manager_log_dir, Conf),
+ StdMibDir = filename:join(code:priv_dir(snmp), "mibs") ++ "/",
+
+ write_manager_conf(ConfDir),
+
+ %% Third set of options (no versions):
+ p("all options"),
+ NetIfOpts = [{module, snmpm_net_if},
+ {verbosity, trace},
+ {options, [{recbuf, 30000},
+ {bind_to, false},
+ {no_reuse, false}]}],
+ ServerOpts = [{timeout, 10000}, {verbosity, trace}],
+ NoteStoreOpts = [{timeout, 20000}, {verbosity, trace}],
+ ConfigOpts = [{dir, ConfDir}, {verbosity, trace}, {db_dir, DbDir}],
+ Mibs = [join(StdMibDir, "SNMP-NOTIFICATION-MIB"),
+ join(StdMibDir, "SNMP-USER-BASED-SM-MIB")],
+ Prio = normal,
+ ATL = [{type, read_write},
+ {dir, LogDir},
+ {size, {10,10240}},
+ {repair, true},
+ {seqno, true}],
+ Vsns = [v1,v2,v3],
+ Opts = [{config, ConfigOpts},
+ {net_if, NetIfOpts},
+ {server, ServerOpts},
+ {note_store, NoteStoreOpts},
+ {audit_trail_log, ATL},
+ {priority, Prio},
+ {mibs, Mibs},
+ {versions, Vsns}],
+
+ ?line {ok, _Pid} = config_start(Opts),
+
+ Counter = otp_8395_4,
+ Initial = 10,
+ Increment = 2,
+ Max = 20,
+
+ %% At this call the counter does *not* exist. The call creates
+ %% it with the initial value!
+
+ Val1 = Initial,
+ Val1 = otp8395_incr_counter(Counter, Initial, Increment, Max),
+
+ %% Now it exist, make sure another call does the expected increment
+
+ Val2 = Initial + Increment,
+ Val2 = otp8395_incr_counter(Counter, Initial, Increment, Max),
+
+ ?line ok = config_stop(),
+
+ p("done"),
+ ok.
+
+
+otp8395_incr_counter(Counter, Initial, Increment, Max) ->
+ snmpm_config:increment_counter(Counter, Initial, Increment, Max).
+
+
%%======================================================================
%% Internal functions
%%======================================================================
@@ -2506,6 +2701,27 @@ write_conf_file(Dir, File, Str) ->
file:close(Fd).
+maybe_start_crypto() ->
+ case (catch crypto:version()) of
+ {'EXIT', {undef, _}} ->
+ %% This is the version of crypto before the NIFs...
+ ?CRYPTO_START();
+ _ ->
+ %% No need to start this version of crypto..
+ ok
+ end.
+
+maybe_stop_crypto() ->
+ case (catch crypto:version()) of
+ {'EXIT', {undef, _}} ->
+ %% This is the version of crypto before the NIFs...
+ crypto:stop();
+ _ ->
+ %% There is nothing to stop in this version of crypto..
+ ok
+ end.
+
+
%% ------
str(X) ->
diff --git a/lib/snmp/test/snmp_manager_test.erl b/lib/snmp/test/snmp_manager_test.erl
index 31cc095349..cef96417dc 100644
--- a/lib/snmp/test/snmp_manager_test.erl
+++ b/lib/snmp/test/snmp_manager_test.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2003-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 2003-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%
%%
@@ -111,7 +111,9 @@
tickets/1,
otp8015/1,
- otp8015_1/1
+ otp8015_1/1,
+ otp8395/1,
+ otp8395_1/1
]).
@@ -240,18 +242,22 @@ init_per_testcase3(Case, Config) ->
simple_async_set2,
simple_sync_get_bulk2,
simple_async_get_bulk2,
- misc_async2
+ misc_async2,
+ otp8395_1
],
- Cases = [
- trap1,
- trap2,
- inform1,
- inform2,
- inform3,
- inform4,
- inform_swarm,
- report
- ] ++ OldApiCases ++ NewApiCases,
+ Cases =
+ [
+ trap1,
+ trap2,
+ inform1,
+ inform2,
+ inform3,
+ inform4,
+ inform_swarm,
+ report
+ ] ++
+ OldApiCases ++
+ NewApiCases,
case lists:member(Case, Cases) of
true ->
NoAutoInformCases = [inform1, inform2, inform3, inform_swarm],
@@ -265,6 +271,8 @@ init_per_testcase3(Case, Config) ->
{agent_verbosity, info},
{agent_net_if_verbosity, info}],
Verb ++ Config;
+ Case =:= otp8395_1 ->
+ [{manager_atl_seqno, true} | Config];
true ->
Config
end,
@@ -315,18 +323,22 @@ fin_per_testcase2(Case, Config) ->
simple_async_set2,
simple_sync_get_bulk2,
simple_async_get_bulk2,
- misc_async2
+ misc_async2,
+ otp8395_1
],
- Cases = [
- trap1,
- trap2,
- inform1,
- inform2,
- inform3,
- inform4,
- inform_swarm,
- report
- ] ++ OldApiCases ++ NewApiCases,
+ Cases =
+ [
+ trap1,
+ trap2,
+ inform1,
+ inform2,
+ inform3,
+ inform4,
+ inform_swarm,
+ report
+ ] ++
+ OldApiCases ++
+ NewApiCases,
case lists:member(Case, Cases) of
true ->
Conf1 = case lists:member(Case, NewApiCases) of
@@ -446,7 +458,8 @@ event_tests(suite) ->
tickets(suite) ->
[
- otp8015
+ otp8015,
+ otp8395
].
otp8015(suite) ->
@@ -454,6 +467,11 @@ otp8015(suite) ->
otp8015_1
].
+otp8395(suite) ->
+ [
+ otp8395_1
+ ].
+
%%======================================================================
%% Test functions
@@ -777,6 +795,35 @@ notify_started02(suite) -> [];
notify_started02(Config) when is_list(Config) ->
process_flag(trap_exit, true),
put(tname,ns02),
+
+ %% <CONDITIONAL-SKIP>
+ %% The point of this is to catch machines running
+ %% SLES9 (2.6.5)
+ LinuxVersionVerify =
+ fun() ->
+ case os:cmd("uname -m") of
+ "i686" ++ _ ->
+%% io:format("found an i686 machine, "
+%% "now check version~n", []),
+ case os:version() of
+ {2, 6, Rev} when Rev >= 16 ->
+ true;
+ {2, Min, _} when Min > 6 ->
+ true;
+ {Maj, _, _} when Maj > 2 ->
+ true;
+ _ ->
+ false
+ end;
+ _ ->
+ true
+ end
+ end,
+ Skippable = [{unix, [{linux, LinuxVersionVerify}]}],
+ Condition = fun() -> ?OS_BASED_SKIP(Skippable) end,
+ ?NON_PC_TC_MAYBE_SKIP(Config, Condition),
+ %% </CONDITIONAL-SKIP>
+
p("starting with Config: ~n~p", [Config]),
ConfDir = ?config(manager_conf_dir, Config),
@@ -1372,6 +1419,9 @@ simple_sync_get2(suite) -> [];
simple_sync_get2(Config) when is_list(Config) ->
process_flag(trap_exit, true),
put(tname, ssg2),
+ do_simple_get(Config).
+
+do_simple_get(Config) ->
p("starting with Config: ~p~n", [Config]),
Node = ?config(manager_node, Config),
@@ -1386,7 +1436,7 @@ simple_sync_get2(Config) when is_list(Config) ->
Oids2 = [[sysObjectID, 0], [sysDescr, 0], [sysUpTime, 0]],
?line ok = do_simple_get(Node, TargetName, Oids2),
ok.
-
+
do_simple_get(Node, TargetName, Oids) ->
?line {ok, Reply, Rem} = mgr_user_sync_get(Node, TargetName, Oids),
@@ -4438,6 +4488,16 @@ otp8015_1(Config) when is_list(Config) ->
%%======================================================================
+
+otp8395_1(doc) -> ["OTP-8395:1 - simple get with ATL sequence numbering."];
+otp8395_1(suite) -> [];
+otp8395_1(Config) when is_list(Config) ->
+ process_flag(trap_exit, true),
+ put(tname, otp8395_1),
+ do_simple_get(Config).
+
+
+%%======================================================================
%% async snmp utility functions
%%======================================================================
@@ -5063,12 +5123,15 @@ start_manager(Node, Vsns, Conf0, Opts) ->
ServerVerbosity = get_opt(manager_server_verbosity, Conf0, trace),
NetIfVerbosity = get_opt(manager_net_if_verbosity, Conf0, trace),
+ AtlSeqNo = get_opt(manager_atl_seqno, Conf0, false),
+
Env = [{versions, Vsns},
{inform_request_behaviour, IRB},
{audit_trail_log, [{type, read_write},
{dir, AtlDir},
{size, {10240, 10}},
- {repair, true}]},
+ {repair, true},
+ {seqno, AtlSeqNo}]},
{config, [{dir, ConfDir},
{db_dir, DbDir},
{verbosity, ConfigVerbosity}]},
diff --git a/lib/snmp/test/snmp_manager_user_test.erl b/lib/snmp/test/snmp_manager_user_test.erl
index 24ed3b0b73..0f47d70873 100644
--- a/lib/snmp/test/snmp_manager_user_test.erl
+++ b/lib/snmp/test/snmp_manager_user_test.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2004-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 2004-2010. All Rights Reserved.
+%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
-%%
+%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
-%%
+%%
%% %CopyrightEnd%
%%
@@ -822,10 +822,39 @@ register_monitor_and_crash3(doc) ->
"Start a single user process, "
"register-monitor one user and register one user, "
"crash the single user process.";
-register_monitor_and_crash3(Conf) when is_list(Conf) ->
+register_monitor_and_crash3(Conf) when is_list(Conf) ->
+ process_flag(trap_exit, true),
put(tname,rlac3),
+
+ %% <CONDITIONAL-SKIP>
+ %% The point of this is to catch machines running
+ %% SLES9 (2.6.5)
+ LinuxVersionVerify =
+ fun() ->
+ case os:cmd("uname -m") of
+ "i686" ++ _ ->
+%% io:format("found an i686 machine, "
+%% "now check version~n", []),
+ case os:version() of
+ {2, 6, Rev} when Rev >= 16 ->
+ true;
+ {2, Min, _} when Min > 6 ->
+ true;
+ {Maj, _, _} when Maj > 2 ->
+ true;
+ _ ->
+ false
+ end;
+ _ ->
+ true
+ end
+ end,
+ Skippable = [{unix, [{linux, LinuxVersionVerify}]}],
+ Condition = fun() -> ?OS_BASED_SKIP(Skippable) end,
+ ?NON_PC_TC_MAYBE_SKIP(Conf, Condition),
+ %% </CONDITIONAL-SKIP>
+
p("start"),
- process_flag(trap_exit, true),
ConfDir = ?config(manager_conf_dir, Conf),
DbDir = ?config(manager_db_dir, Conf),
diff --git a/lib/snmp/test/snmp_pdus_test.erl b/lib/snmp/test/snmp_pdus_test.erl
index d5add50f52..6dc5b779aa 100644
--- a/lib/snmp/test/snmp_pdus_test.erl
+++ b/lib/snmp/test/snmp_pdus_test.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2003-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 2003-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%
%%
@@ -37,6 +37,7 @@
all/1,
tickets/1,
otp7575/1,
+ otp8563/1,
init_per_testcase/2, fin_per_testcase/2
]).
@@ -66,6 +67,7 @@ init_per_testcase(_Case, Config) when is_list(Config) ->
fin_per_testcase(_Case, Config) when is_list(Config) ->
Config.
+
%%======================================================================
%% Test case definitions
%%======================================================================
@@ -76,7 +78,8 @@ all(suite) ->
tickets(suite) ->
[
- otp7575
+ otp7575,
+ otp8563
].
@@ -118,6 +121,55 @@ otp7575(Config) when is_list(Config) ->
ok.
+otp8563(suite) -> [];
+otp8563(doc) -> ["OTP-8563"];
+otp8563(Config) when is_list(Config) ->
+ Val1 = 16#7fffffffffffffff,
+ io:format("try encode and decode ~w~n", [Val1]),
+ Enc1 = snmp_pdus:enc_value('Counter64', Val1),
+ {{'Counter64', Val1}, []} = snmp_pdus:dec_value(Enc1),
+
+ Val2 = Val1 + 1,
+ io:format("try encode and decode ~w~n", [Val2]),
+ Enc2 = snmp_pdus:enc_value('Counter64', Val2),
+ {{'Counter64', Val2}, []} = snmp_pdus:dec_value(Enc2),
+
+ Val3 = Val2 + 1,
+ io:format("try encode and decode ~w~n", [Val3]),
+ Enc3 = snmp_pdus:enc_value('Counter64', Val3),
+ {{'Counter64', Val3}, []} = snmp_pdus:dec_value(Enc3),
+
+ Val4 = 16#fffffffffffffffe,
+ io:format("try encode and decode ~w~n", [Val4]),
+ Enc4 = snmp_pdus:enc_value('Counter64', Val4),
+ {{'Counter64', Val4}, []} = snmp_pdus:dec_value(Enc4),
+
+ Val5 = Val4 + 1,
+ io:format("try encode and decode ~w~n", [Val5]),
+ Enc5 = snmp_pdus:enc_value('Counter64', Val5),
+ {{'Counter64', Val5}, []} = snmp_pdus:dec_value(Enc5),
+
+ Val6 = 16#ffffffffffffffff + 1,
+ io:format("try and fail to encode ~w~n", [Val6]),
+ case (catch snmp_pdus:enc_value('Counter64', Val6)) of
+ {'EXIT', {error, {bad_counter64, Val6}}} ->
+ ok;
+ Unexpected6 ->
+ exit({unexpected_encode_result, Unexpected6, Val6})
+ end,
+
+ Val7 = -1,
+ io:format("try and fail to encode ~w~n", [Val7]),
+ case (catch snmp_pdus:enc_value('Counter64', Val7)) of
+ {'EXIT', {error, {bad_counter64, Val7}}} ->
+ ok;
+ Unexpected7 ->
+ exit({unexpected_encode_result, Unexpected7, Val7})
+ end,
+
+ ok.
+
+
%%======================================================================
%% Internal functions
%%======================================================================
diff --git a/lib/snmp/test/snmp_test_data/OLD-SNMPEA-MIB.mib b/lib/snmp/test/snmp_test_data/OLD-SNMPEA-MIB.mib
index dd90d0ab50..2ba1a6fd67 100644
--- a/lib/snmp/test/snmp_test_data/OLD-SNMPEA-MIB.mib
+++ b/lib/snmp/test/snmp_test_data/OLD-SNMPEA-MIB.mib
@@ -12,18 +12,12 @@ OLD-SNMPEA-MIB DEFINITIONS ::= BEGIN
;
-- MODULE-IDENTITY
--- LAST-UPDATED "9709220900Z"
--- ORGANIZATION "ETX/DN/S"
--- CONTACT-INFO
--- " Martin Bj�rklund
---
--- Postal: ERICSSON SOFTWARE TECHNOLOGY AB
--- ERLANG SYSTEMS
--- Box 1214
--- S-164 28 KISTA, SWEDEN
---
--- Tel: +46 8 719 20 89
--- E-mail: [email protected]"
+-- LAST-UPDATED "1004200000Z"
+-- ORGANIZATION "Erlang/OTP"
+-- CONTACT-INFO ""
+-- DESCRIPTION
+-- "Header cleanup."
+-- REVISION "1004200000Z"
-- DESCRIPTION
-- "This MIB module defines MIB objects for the SNMPEA
-- component in OTP."
diff --git a/lib/snmp/test/snmp_test_data/OTP8574-MIB.mib b/lib/snmp/test/snmp_test_data/OTP8574-MIB.mib
new file mode 100644
index 0000000000..b5e5ed1848
--- /dev/null
+++ b/lib/snmp/test/snmp_test_data/OTP8574-MIB.mib
@@ -0,0 +1,77 @@
+OTP8574-MIB DEFINITIONS ::= BEGIN
+
+IMPORTS
+ MODULE-IDENTITY, OBJECT-TYPE, enterprises, IpAddress FROM SNMPv2-SMI
+ RowStatus FROM SNMPv2-TC
+ ;
+
+otp8574MIB MODULE-IDENTITY
+ LAST-UPDATED "1004200000Z"
+ ORGANIZATION "Erlang/OTP"
+ CONTACT-INFO "www.erlang.org"
+ DESCRIPTION "The MIB module is used for testing a compiler feature"
+ ::= { otpSnmp 1 }
+
+ericsson OBJECT IDENTIFIER ::= { enterprises 193 }
+otp OBJECT IDENTIFIER ::= { ericsson 19 }
+otpApplications OBJECT IDENTIFIER ::= { otp 3 }
+otpSnmp OBJECT IDENTIFIER ::= { otpApplications 3 }
+
+testMIBObjects OBJECT IDENTIFIER ::= { otp8574MIB 1 }
+
+testMIBObjectGroup OBJECT IDENTIFIER ::= { testMIBObjects 1 }
+
+example-Table OBJECT-TYPE
+ SYNTAX SEQUENCE OF ExampleEntry
+ MAX-ACCESS not-accessible
+ STATUS current
+ DESCRIPTION "An example table"
+ ::= { testMIBObjectGroup 1 }
+
+example-Entry OBJECT-TYPE
+ SYNTAX ExampleEntry
+ MAX-ACCESS not-accessible
+ STATUS current
+ DESCRIPTION "Example table entry"
+ INDEX { exampleIndex }
+ ::= { example-Table 5 }
+
+ExampleEntry ::= SEQUENCE {
+ exampleIndex INTEGER,
+ exampleColumn OCTET STRING,
+ exampleNotAccessible OCTET STRING,
+ exampleRowStatus RowStatus
+}
+
+exampleIndex OBJECT-TYPE
+ SYNTAX INTEGER (1..100)
+ MAX-ACCESS read-write
+ STATUS current
+ DESCRIPTION "The index for this entry."
+ ::= { example-Entry 1 }
+
+exampleColumn OBJECT-TYPE
+ SYNTAX OCTET STRING
+ MAX-ACCESS read-write
+ STATUS current
+ DESCRIPTION
+ "Example table column"
+ ::= { example-Entry 2 }
+
+exampleNotAccessible OBJECT-TYPE
+ SYNTAX OCTET STRING
+ MAX-ACCESS not-accessible
+ STATUS current
+ DESCRIPTION
+ "Example table column"
+ ::= { example-Entry 3 }
+
+exampleRowStatus OBJECT-TYPE
+ SYNTAX RowStatus
+ MAX-ACCESS read-write
+ STATUS current
+ DESCRIPTION
+ "Example table RowStatus"
+ ::= { example-Entry 4 }
+
+END
diff --git a/lib/snmp/test/snmp_test_data/OTP8595-MIB.mib b/lib/snmp/test/snmp_test_data/OTP8595-MIB.mib
new file mode 100644
index 0000000000..23245bce37
--- /dev/null
+++ b/lib/snmp/test/snmp_test_data/OTP8595-MIB.mib
@@ -0,0 +1,45 @@
+OTP8595-MIB DEFINITIONS ::= BEGIN
+
+IMPORTS
+ MODULE-IDENTITY, OBJECT-TYPE, snmpModules, mib-2
+ FROM SNMPv2-SMI
+ DisplayString, TestAndIncr, TimeStamp, RowStatus, TruthValue,
+ TEXTUAL-CONVENTION
+ FROM SNMPv2-TC
+ MODULE-COMPLIANCE, OBJECT-GROUP, NOTIFICATION-GROUP
+ FROM SNMPv2-CONF
+ sysLocation, sysContact
+ FROM SNMPv2-MIB
+ ;
+
+otp8595MIB MODULE-IDENTITY
+ LAST-UPDATED "1004210000Z"
+ ORGANIZATION ""
+ CONTACT-INFO
+ ""
+ DESCRIPTION
+ "Test mib for OTP-8595"
+ ::= { snmpModules 1 }
+
+
+test OBJECT IDENTIFIER ::= { mib-2 15 }
+
+bits1 OBJECT-TYPE
+ SYNTAX BITS {
+ b0(0),
+ b1(1),
+ b2(2),
+ -- The following are extensions to the original set of
+ -- labels. The extensions start at an octet boundary.
+ -- So for bits 3 - 7, one MUST set them to zero on send
+ -- and one MUST ignore them on receipt.
+ b8(8),
+ b9(9)
+ }
+ MAX-ACCESS read-write
+ STATUS current
+ DESCRIPTION
+ ""
+ ::= { test 1 }
+
+END
diff --git a/lib/snmp/test/snmp_test_lib.erl b/lib/snmp/test/snmp_test_lib.erl
index 2586b66a13..54839d989b 100644
--- a/lib/snmp/test/snmp_test_lib.erl
+++ b/lib/snmp/test/snmp_test_lib.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2002-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 2002-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%
%%
@@ -172,7 +172,17 @@ os_based_skip(Skippable) when is_list(Skippable) ->
{value, {OsFam, OsName}} ->
true;
{value, {OsFam, OsNames}} when is_list(OsNames) ->
- lists:member(OsName, OsNames);
+ case lists:member(OsName, OsNames) of
+ true ->
+ true;
+ false ->
+ case lists:keymember(OsName, 1, OsNames) of
+ {value, {OsName, Check}} when is_function(Check) ->
+ Check();
+ _ ->
+ false
+ end
+ end;
_ ->
false
end
diff --git a/lib/snmp/test/snmp_test_mgr.erl b/lib/snmp/test/snmp_test_mgr.erl
index 085dc8600f..84bdc6b04f 100644
--- a/lib/snmp/test/snmp_test_mgr.erl
+++ b/lib/snmp/test/snmp_test_mgr.erl
@@ -1,19 +1,19 @@
%%
%% %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
%% 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%
%%
diff --git a/lib/snmp/test/snmp_test_mgr_misc.erl b/lib/snmp/test/snmp_test_mgr_misc.erl
index e6220f9241..ef1ba0b948 100644
--- a/lib/snmp/test/snmp_test_mgr_misc.erl
+++ b/lib/snmp/test/snmp_test_mgr_misc.erl
@@ -1,19 +1,19 @@
%%
%% %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
%% 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%
%%
@@ -101,8 +101,8 @@ init_packet(Parent, SnmpMgr,
init_debug(Dbg) when is_atom(Dbg) ->
put(debug,Dbg),
- put(verbosity,silence);
- %% put(verbosity,trace);
+ %% put(verbosity, silence);
+ put(verbosity, trace);
init_debug(DbgOptions) when is_list(DbgOptions) ->
case lists:keysearch(debug, 1, DbgOptions) of
{value, {_, Dbg}} when is_atom(Dbg) ->
diff --git a/lib/snmp/vsn.mk b/lib/snmp/vsn.mk
index e7a93f026d..54e80de84e 100644
--- a/lib/snmp/vsn.mk
+++ b/lib/snmp/vsn.mk
@@ -1,169 +1,65 @@
#-*-makefile-*- ; force emacs to enter makefile-mode
# %CopyrightBegin%
-#
-# Copyright Ericsson AB 1997-2009. All Rights Reserved.
-#
+#
+# Copyright Ericsson AB 1997-2012. All Rights Reserved.
+#
# The contents of this file are subject to the Erlang Public License,
# Version 1.1, (the "License"); you may not use this file except in
# compliance with the License. You should have received a copy of the
# Erlang Public License along with this software. If not, it can be
# retrieved online at http://www.erlang.org/.
-#
+#
# Software distributed under the License is distributed on an "AS IS"
# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
# the License for the specific language governing rights and limitations
# under the License.
-#
+#
# %CopyrightEnd%
-SNMP_VSN = 4.15
+SNMP_VSN = 4.17.4
PRE_VSN =
APP_VSN = "snmp-$(SNMP_VSN)$(PRE_VSN)"
-TICKETS = OTP-8229 OTP-8249
+TICKETS = OTP-9884 OTP-9747
-TICKETS_4_14 = OTP-8223 OTP-8228 OTP-8237
+TICKETS_4_17_3 = OTP-9700 OTP-9868
-TICKETS_4_13_5 = OTP-8116 OTP-8120 OTP-8181 OTP-8182
+TICKETS_4_17_2 = OTP-9236
-TICKETS_4_13_4 = OTP-8044 OTP-8062 OTP-8098
+TICKETS_4_17_1 = OTP-8761
-TICKETS_4_13_3 = OTP-8015 OTP-8020
+TICKETS_4_17 = OTP-8478
-TICKETS_4_13_2 = OTP-7961 OTP-7977 OTP-7983 OTP-7989
+TICKETS_4_16_2 = \
+ OTP-8563 \
+ OTP-8574 \
+ OTP-8594 \
+ OTP-8595 \
+ OTP-8646 \
+ OTP-8648
-TICKETS_4_13_1 = OTP-7902
+TICKETS_4_16_1 = \
+ OTP-8480 \
+ OTP-8481
-TICKETS_4_13 = OTP-7571 OTP-7735 OTP-7836 OTP-7851
+TICKETS_4_16 = \
+ OTP-8395 \
+ OTP-8433 \
+ OTP-8442
-TICKETS_4_12_2 = OTP-7868
+TICKETS_4_15 = \
+ OTP-8229 \
+ OTP-8249
-TICKETS_4_12_1 = OTP-7695 OTP-7698
+TICKETS_4_14 = \
+ OTP-8223 \
+ OTP-8228 \
+ OTP-8237
-TICKETS_4_12 = OTP-7346 OTP-7525
-
-TICKETS_4_11_2 = OTP-7570 OTP-7575
-
-TICKETS_4_11_1 = OTP-7390 OTP-7412 OTP-7426 OTP-7432
-
-TICKETS_4_11 = OTP-7201 OTP-7287 OTP-7319 OTP-7369 OTP-7371 OTP-7377 OTP-7381
-
-TICKETS_4_10_3 = OTP-7219
-
-TICKETS_4_10_2 = OTP-7152 OTP-7153 OTP-7157 OTP-7158 OTP-7159 OTP-7160
-
-TICKETS_4_10_1 = OTP-7083 OTP-7109 OTP-7110 OTP-7119 OTP-7121 OTP-7123
-
-TICKETS_4_10 = OTP-6649 OTP-6841 OTP-6898 OTP-6945
-
-TICKETS_4_9_6 = OTP-6840 OTP-6843
-
-TICKETS_4_9_5 = OTP-6805 OTP-6815
-
-TICKETS_4_9_4 = OTP-6784 OTP-6771
-
-TICKETS_4_9_3 = OTP-6605 OTP-6712 OTP-6713
-
-TICKETS_4_9_2 = OTP-6571
-
-TICKETS_4_9_1 = OTP-6566 OTP-6569
-
-TICKETS_4_9 = \
- OTP-6317 \
- OTP-6318 \
- OTP-6383 \
- OTP-6487 \
- OTP-6515 \
- OTP-6518 \
- OTP-6529 \
- OTP-6532 \
- OTP-6533 \
- OTP-6540
-
-TICKETS_4_8_4 = OTP-6408
-
-TICKETS_4_8_3 = OTP-6337 OTP-6340
-
-TICKETS_4_8_2 = OTP-6214 OTP-6247 OTP-6293
-
-TICKETS_4_8_1 = OTP-6176 OTP-6177
-
-TICKETS_4_8 = OTP-6137 OTP-6149 OTP-6150 OTP-6164
-
-TICKETS_4_7_4 = \
- OTP-6042 \
- OTP-6044 \
- OTP-6049 \
- OTP-6062 \
- OTP-6068 \
- OTP-6074 \
- OTP-6077 \
- OTP-6081
-
-TICKETS_4_7_3 = \
- OTP-6031 \
- OTP-6032
-
-TICKETS_4_7_2 = \
- OTP-5992 \
- OTP-6024
-
-TICKETS_4_7_1 = \
- OTP-5963 \
- OTP-5968 \
- OTP-5969
-
-TICKETS_4_7 = \
- OTP-5870 \
- OTP-5934 \
- OTP-5935 \
- OTP-5937
-
-TICKETS_4_6_1 = \
- OTP-5834 \
- OTP-5838
-
-TICKETS_4_6 = \
- OTP-5763 \
- OTP-5771 \
- OTP-5787 \
- OTP-5797 \
- OTP-5829
-
-TICKETS_4_5 = \
- OTP-5581 \
- OTP-5726 \
- OTP-5727 \
- OTP-5732 \
- OTP-5733 \
- OTP-5740 \
- OTP-5742
-
-TICKETS_4_4_1 = \
- OTP-5719 \
- OTP-5720
-
-TICKETS_4_4 = \
- OTP-5666 \
- OTP-5668 \
- OTP-5669 \
- OTP-5675 \
- OTP-5676 \
- OTP-5678 \
- OTP-5703
-
-TICKETS_4_3 = \
- OTP-5636 \
- OTP-5637 \
- OTP-5490
-
-TICKETS_4_2 = \
- OTP-5574 \
- OTP-5578 \
- OTP-5579 \
- OTP-5580 \
- OTP-5590 \
- OTP-5591 \
- OTP-5592
+TICKETS_4_13_5 = \
+ OTP-8116 \
+ OTP-8120 \
+ OTP-8181 \
+ OTP-8182
diff --git a/lib/ssh/doc/src/Makefile b/lib/ssh/doc/src/Makefile
index d2907a39d7..c4d8d9901c 100644
--- a/lib/ssh/doc/src/Makefile
+++ b/lib/ssh/doc/src/Makefile
@@ -1,19 +1,19 @@
#
# %CopyrightBegin%
-#
-# Copyright Ericsson AB 2004-2009. All Rights Reserved.
-#
+#
+# Copyright Ericsson AB 2004-2010. All Rights Reserved.
+#
# The contents of this file are subject to the Erlang Public License,
# Version 1.1, (the "License"); you may not use this file except in
# compliance with the License. You should have received a copy of the
# Erlang Public License along with this software. If not, it can be
# retrieved online at http://www.erlang.org/.
-#
+#
# Software distributed under the License is distributed on an "AS IS"
# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
# the License for the specific language governing rights and limitations
# under the License.
-#
+#
# %CopyrightEnd%
#
@@ -53,11 +53,14 @@ 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
+XML_FILES = $(BOOK_FILES) $(XML_APPLICATION_FILES) $(XML_REF3_FILES) \
+ $(XML_PART_FILES) $(XML_CHAPTER_FILES)
+
# ----------------------------------------------------
HTML_FILES = $(XML_APPLICATION_FILES:%.xml=$(HTMLDIR)/%.html) \
@@ -70,8 +73,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..9a08c72c93 100644
--- a/lib/ssh/doc/src/notes.xml
+++ b/lib/ssh/doc/src/notes.xml
@@ -4,7 +4,7 @@
<chapter>
<header>
<copyright>
- <year>2004</year><year>2009</year>
+ <year>2004</year><year>2010</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
@@ -29,6 +29,156 @@
<file>notes.xml</file>
</header>
+ <section><title>Ssh 1.1.13</title>
+
+ <section><title>Fixed Bugs and Malfunctions</title>
+ <list>
+ <item>
+ <p>
+ The fix regarding OTP-8863 was not included in the previous
+ version as stated.</p>
+ <p>
+ Own Id: OTP-8908</p>
+ </item>
+ </list>
+ </section>
+
+ </section>
+
+ <section><title>Ssh 1.1.12</title>
+
+ <section><title>Fixed Bugs and Malfunctions</title>
+ <list>
+ <item>
+ <p>
+ The processes ssh_subsystem_sup and one ssh_channel_sup
+ was not terminated when a connection was closed.</p>
+ <p>
+ Own Id: OTP-8807</p>
+ </item>
+ <item>
+ <p>
+ The ssh_system_sup did not catch noproc and shutdown
+ messages.</p>
+ <p>
+ Own Id: OTP-8863</p>
+ </item>
+ <item>
+ <p>
+ In some cases a crash report was generated when a
+ connection was closing down. This was caused by a race
+ condition between two processes.</p>
+ <p>
+ Own Id: OTP-8881 Aux Id: seq11656, seq11648 </p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
+<section><title>Ssh 1.1.11</title>
+
+ <section><title>Fixed Bugs and Malfunctions</title>
+ <list>
+ <item>
+ <p>
+ SSH in some cases generated a crash report when a channel
+ was closed in a normal way.</p>
+ <p>
+ Own Id: OTP-8735 Aux Id: seq11615</p>
+ </item>
+ </list>
+ </section>
+
+ </section>
+
+ <section><title>Ssh 1.1.10</title>
+
+ <section><title>Fixed Bugs and Malfunctions</title>
+ <list>
+ <item>
+ <p>
+ SSH in some cases terminated channels with reason
+ normal when it should have been shutdown.</p>
+ <p>
+ Own Id: OTP-8714 Aux Id:</p>
+ </item>
+ </list>
+ </section>
+
+ </section>
+
+ <section><title>Ssh 1.1.9</title>
+
+ <section><title>Fixed Bugs and Malfunctions</title>
+ <list>
+ <item>
+ <p>The function ssh:connect/4 was not exported.</p>
+ <p>Own Id: OTP-8550 Aux Id:</p>
+ </item>
+ <item>
+ <p>Aligned error message with used version (SSH_FX_FAILURE vs
+ SSH_FX_NOT_A_DIRECTORY, the latter introduced in version 6).</p>
+ <p>
+ *** POTENTIAL INCOMPATIBILITY ***</p>
+ <p>Own Id: OTP-8644 Aux Id: seq11574</p>
+ </item>
+ <item>
+ <p>Resolved race condition when another connection is started
+ before a channel is opened in the first connection.</p>
+ <p>Own Id: OTP-8645 Aux Id: seq11577</p>
+ </item>
+ </list>
+ </section>
+
+ <section><title>Improvements and New Features</title>
+ <list>
+ <item>
+ <p>The configuration parameter ip_v6_disabled is now available,
+ which makes it possible for the user to alter the IP version
+ SSH shall use.</p>
+ <p>
+ *** POTENTIAL INCOMPATIBILITY ***</p>
+ <p>Own Id: OTP-8535 Aux Id:</p>
+ </item>
+ <item>
+ <p>The ssh_connection:send operation now accepts infinity as timeout.</p>
+ <p>Own Id: OTP-8534 Aux Id:</p>
+ </item>
+ <item>
+ <p>The connection handler now include stack traces when a channel
+ message is not handled correctly.</p>
+ <p>Own Id: OTP-8524 Aux Id:</p>
+ </item>
+ </list>
+ </section>
+
+ </section>
+
+ <section><title>Ssh 1.1.8</title>
+
+ <section><title>Fixed Bugs and Malfunctions</title>
+ <list>
+ <item>
+ <p>
+ In some cases SSH ceased to collect more data from the transport layer.</p>
+ <p>
+ Own Id: OTP-8401 Aux Id: seq11479</p>
+ </item>
+ </list>
+ </section>
+
+ <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 +731,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..1b47a12021 100644
--- a/lib/ssh/doc/src/part_notes.xml
+++ b/lib/ssh/doc/src/part_notes.xml
@@ -4,7 +4,7 @@
<part xmlns:xi="http://www.w3.org/2001/XInclude">
<header>
<copyright>
- <year>2004</year><year>2009</year>
+ <year>2004</year><year>2010</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
@@ -13,12 +13,12 @@
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>SSH Release Notes</title>
@@ -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/doc/src/ssh.xml b/lib/ssh/doc/src/ssh.xml
index aca5c9cdc4..71e6b2cd3d 100644
--- a/lib/ssh/doc/src/ssh.xml
+++ b/lib/ssh/doc/src/ssh.xml
@@ -4,7 +4,7 @@
<erlref>
<header>
<copyright>
- <year>2004</year><year>2009</year>
+ <year>2004</year><year>2010</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
@@ -13,12 +13,12 @@
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>ssh</title>
@@ -159,6 +159,9 @@
<item>
<p>Allow an existing file-descriptor to be used
(simply passed on to the transport protocol).</p></item>
+ <tag><c><![CDATA[{ip_v6_disabled, boolean()}]]></c></tag>
+ <item>
+ <p>Determines if SSH shall use IPv6 or not.</p></item>
</taglist>
</desc>
</func>
@@ -198,8 +201,8 @@
<item>
Provides specifications for handling of subsystems. The
"sftp" subsystem-spec can be retrieved by calling
- ssh_sftd:subsystem_spec/1. If the subsystems option in not present
- the value of <c>[ssh_sftd:subsystem_spec([])]</c> will be used.
+ ssh_sftpd:subsystem_spec/1. If the subsystems option in not present
+ the value of <c>[ssh_sftpd:subsystem_spec([])]</c> will be used.
It is of course possible to set the option to the empty list
if you do not want the daemon to run any subsystems at all.
</item>
@@ -252,6 +255,10 @@
<item>
<p>Allow an existing file-descriptor to be used
(simply passed on to the transport protocol).</p></item>
+ <tag><c><![CDATA[{ip_v6_disabled, boolean()}]]></c></tag>
+ <item>
+ <p>Determines if SSH shall use IPv6 or not (only used when
+ HostAddress is set to any).</p></item>
</taglist>
</desc>
</func>
diff --git a/lib/ssh/examples/ssh_sample_cli.erl b/lib/ssh/examples/ssh_sample_cli.erl
index 2505c1b759..6f3092e567 100644
--- a/lib/ssh/examples/ssh_sample_cli.erl
+++ b/lib/ssh/examples/ssh_sample_cli.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2005-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 2005-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%
%%
@@ -30,19 +30,15 @@
%% our command functions
-export([cli_prime/1, cli_primes/1, cli_gcd/2, cli_lcm/2,
cli_factors/1, cli_exit/0, cli_rho/1, cli_help/0,
- cli_crash/0, cli_users/0, cli_self/0,
- cli_user/0, cli_host/0]).
-
-%% imports
--import(lists, [reverse/1, reverse/2, seq/2, prefix/2]).
--import(math, [sqrt/1]).
-
+ cli_crash/0, cli_self/0, cli_user/0, cli_host/0]).
listen(Port) ->
listen(Port, []).
listen(Port, Options) ->
- ssh_cli:listen(fun(U, H) -> start_our_shell(U, H) end, Port, Options).
+ crypto:start(),
+ ssh:start(),
+ ssh:daemon(any, Port, [{shell, fun(U, H) -> start_our_shell(U, H) end} | Options]).
%% our_routines
our_routines() ->
@@ -56,7 +52,6 @@ our_routines() ->
{"prime", cli_prime, "<int> check for primality"},
{"primes", cli_primes, "<int> print all primes up to <int>"},
{"rho", cli_rho, "<int> prime factors using rho's alg."},
- {"who", cli_users, " lists users"},
{"user", cli_user, " print name of user"},
{"host", cli_host, " print host addr"},
{"self", cli_self, " print my pid"}
@@ -85,11 +80,11 @@ our_routines() ->
common_prefix([C | R1], [C | R2], Acc) ->
common_prefix(R1, R2, [C | Acc]);
common_prefix(_, _, Acc) ->
- reverse(Acc).
+ lists:reverse(Acc).
%% longest prefix in a list, given a prefix
longest_prefix(List, Prefix) ->
- case [A || {A, _, _} <- List, prefix(Prefix, A)] of
+ case [A || {A, _, _} <- List, lists:prefix(Prefix, A)] of
[] ->
{none, List};
[S | Rest] ->
@@ -112,7 +107,7 @@ longest_prefix(List, Prefix) ->
expand([$ | _]) ->
{no, "", []};
expand(RevBefore) ->
- Before = reverse(RevBefore),
+ Before = lists:reverse(RevBefore),
case longest_prefix(our_routines(), Before) of
{prefix, P, [_]} ->
{yes, P ++ " ", []};
@@ -139,22 +134,27 @@ start_our_shell(User, Peer) ->
%%% an ordinary Read-Eval-Print-loop
our_shell_loop() ->
% Read
- Line = io:get_line({format, "CLI> ", []}),
+ Line = io:get_line("CLI> "),
% Eval
Result = eval_cli(Line),
% Print
io:format("---> ~p\n", [Result]),
case Result of
- done -> exit(normal);
- crash -> 1 / 0;
- _ -> our_shell_loop()
+ done ->
+ exit(normal);
+ crash ->
+ 1 / 0;
+ _ ->
+ our_shell_loop()
end.
%%% translate a command to a function
command_to_function(Command) ->
case lists:keysearch(Command, 1, our_routines()) of
- {value, {_, Proc, _}} -> Proc;
- false -> unknown_cli
+ {value, {_, Proc, _}} ->
+ Proc;
+ false ->
+ unknown_cli
end.
%%% evaluate a command line
@@ -209,14 +209,6 @@ cli_user() ->
cli_host() ->
get(peer_name).
-cli_users() ->
- case ssh_userauth:get_auth_users() of
- {ok, UsersPids} ->
- UsersPids; % [U || {U, _} <- UsersPids];
- E ->
- E
- end.
-
cli_self() ->
self().
@@ -243,7 +235,7 @@ cli_help() ->
%% a quite simple Sieve of Erastothenes (not tail-recursive, though)
primes(Size) ->
- era(sqrt(Size), seq(2,Size)).
+ era(math:sqrt(Size), lists:seq(2,Size)).
era(Max, [H|T]) when H =< Max ->
[H | era(Max, sieve([H|T], H))];
@@ -267,7 +259,7 @@ next_prime(Primes, P) ->
next_prime1(Primes, P) ->
P1 = P + 2,
- case divides(Primes, trunc(sqrt(P1)), P1) of
+ case divides(Primes, trunc(math:sqrt(P1)), P1) of
false -> P1;
true -> next_prime1(Primes, P1)
end.
@@ -282,7 +274,7 @@ divides([_ | R], Nsqrt, N) ->
divides(R, Nsqrt, N).
is_prime(P) ->
- lists:all(fun(A) -> P rem A =/= 0 end, primes(trunc(sqrt(P)))).
+ lists:all(fun(A) -> P rem A =/= 0 end, primes(trunc(math:sqrt(P)))).
%% Normal gcd, Euclid
gcd(R, Q) when abs(Q) < abs(R) -> gcd1(Q,R);
@@ -300,17 +292,17 @@ lcm(R, Q) ->
%%% Prime factors of a number (na�ve implementation)
factors(N) ->
- Nsqrt = trunc(sqrt(N)),
+ Nsqrt = trunc(math:sqrt(N)),
factors([], N, 2, Nsqrt, []).
factors(_Primes, N, Prime, Nsqrt, Factors) when Prime > Nsqrt ->
- reverse(Factors, [N]);
+ lists:reverse(Factors, [N]);
factors(Primes, N, Prime, Nsqrt, Factors) ->
case N rem Prime of
0 ->
%%io:format("factor ------- ~p\n", [Prime]),
N1 = N div Prime,
- factors(Primes, N1, Prime, trunc(sqrt(N1)), [Prime|Factors]);
+ factors(Primes, N1, Prime, trunc(math:sqrt(N1)), [Prime|Factors]);
_ ->
Primes1 = Primes ++ [Prime],
Prime1 = next_prime(Primes1, Prime),
diff --git a/lib/ssh/src/ssh.appup.src b/lib/ssh/src/ssh.appup.src
index 3bf772b42b..160e336873 100644
--- a/lib/ssh/src/ssh.appup.src
+++ b/lib/ssh/src/ssh.appup.src
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2004-2009. All Rights Reserved.
+%% Copyright Ericsson AB 2004-2010. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
@@ -19,6 +19,12 @@
{"%VSN%",
[
+ {"1.1.12", [{load_module, ssh_system_sup, soft_purge, soft_purge, []}]},
+ {"1.1.11", [{restart_application, ssh}]},
+ {"1.1.10", [{restart_application, ssh}]},
+ {"1.1.9", [{restart_application, ssh}]},
+ {"1.1.8", [{restart_application, ssh}]},
+ {"1.1.7", [{restart_application, ssh}]},
{"1.1.6", [{restart_application, ssh}]},
{"1.1.5", [{restart_application, ssh}]},
{"1.1.4", [{restart_application, ssh}]},
@@ -26,6 +32,12 @@
{"1.1.2", [{restart_application, ssh}]}
],
[
+ {"1.1.12", [{load_module, ssh_system_sup, soft_purge, soft_purge, []}]},
+ {"1.1.11", [{restart_application, ssh}]},
+ {"1.1.10", [{restart_application, ssh}]},
+ {"1.1.9", [{restart_application, ssh}]},
+ {"1.1.8", [{restart_application, ssh}]},
+ {"1.1.7", [{restart_application, ssh}]},
{"1.1.6", [{restart_application, ssh}]},
{"1.1.5", [{restart_application, ssh}]},
{"1.1.4", [{restart_application, ssh}]},
diff --git a/lib/ssh/src/ssh.erl b/lib/ssh/src/ssh.erl
index f9a986a8b6..994c77436a 100644
--- a/lib/ssh/src/ssh.erl
+++ b/lib/ssh/src/ssh.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2004-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 2004-2010. All Rights Reserved.
+%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
-%%
+%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
-%%
+%%
%% %CopyrightEnd%
%%
@@ -24,7 +24,7 @@
-include("ssh.hrl").
-include("ssh_connect.hrl").
--export([start/0, start/1, stop/0, connect/3, close/1, connection_info/2,
+-export([start/0, start/1, stop/0, connect/3, connect/4, close/1, connection_info/2,
channel_info/3,
daemon/1, daemon/2, daemon/3,
stop_listener/1, stop_listener/2, stop_daemon/1, stop_daemon/2,
@@ -330,10 +330,10 @@ handle_options([{nodelay, _} = Opt | Rest], SockOpts, Opts) ->
handle_options([Opt | Rest], SockOpts, Opts) ->
handle_options(Rest, SockOpts, [Opt | Opts]).
+%% Has IPv6 been disabled?
inetopt(true) ->
- inet6;
-
+ inet;
inetopt(false) ->
- inet.
+ inet6.
diff --git a/lib/ssh/src/ssh_acceptor.erl b/lib/ssh/src/ssh_acceptor.erl
index d19fee14e1..9060626ab3 100644
--- a/lib/ssh/src/ssh_acceptor.erl
+++ b/lib/ssh/src/ssh_acceptor.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%
%%
@@ -79,11 +79,11 @@ acceptor_loop(Callback, Port, Address, Opts, ListenSocket, AcceptTimeout) ->
handle_connection(Callback, Address, Port, Options, Socket) ->
SystemSup = ssh_system_sup:system_supervisor(Address, Port),
- ssh_system_sup:start_subsystem(SystemSup, Options),
+ {ok, SubSysSup} = ssh_system_sup:start_subsystem(SystemSup, Options),
ConnectionSup = ssh_system_sup:connection_supervisor(SystemSup),
{ok, Pid} =
ssh_connection_controler:start_manager_child(ConnectionSup,
- [server, Socket, Options]),
+ [server, Socket, Options, SubSysSup]),
Callback:controlling_process(Socket, Pid),
SshOpts = proplists:get_value(ssh_opts, Options),
Pid ! {start_connection, server, [Address, Port, Socket, SshOpts]}.
diff --git a/lib/ssh/src/ssh_channel.erl b/lib/ssh/src/ssh_channel.erl
index 3d67065ee1..dcb2d69290 100644
--- a/lib/ssh/src/ssh_channel.erl
+++ b/lib/ssh/src/ssh_channel.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%
%%
@@ -238,9 +238,19 @@ handle_info(Msg, #state{cm = ConnectionManager, channel_cb = Module,
{noreply, State#state{channel_state = ChannelState}};
{ok, ChannelState, Timeout} ->
{noreply, State#state{channel_state = ChannelState}, Timeout};
+ {stop, Reason, ChannelState} when is_atom(Reason)->
+ {stop, Reason, State#state{close_sent = true,
+ channel_state = ChannelState}};
{stop, ChannelId, ChannelState} ->
- ssh_connection:close(ConnectionManager, ChannelId),
- {stop, normal, State#state{close_sent = true,
+ Reason =
+ case Msg of
+ {'EXIT', _Pid, shutdown} ->
+ shutdown;
+ _ ->
+ normal
+ end,
+ (catch ssh_connection:close(ConnectionManager, ChannelId)),
+ {stop, Reason, State#state{close_sent = true,
channel_state = ChannelState}}
end.
diff --git a/lib/ssh/src/ssh_cli.erl b/lib/ssh/src/ssh_cli.erl
index 964f35121a..57ba87bd42 100644
--- a/lib/ssh/src/ssh_cli.erl
+++ b/lib/ssh/src/ssh_cli.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2005-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 2005-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%
%%
@@ -419,16 +419,14 @@ start_shell(ConnectionManager, State) ->
Shell = State#state.shell,
ShellFun = case is_function(Shell) of
true ->
+ {ok, User} =
+ ssh_userreg:lookup_user(ConnectionManager),
case erlang:fun_info(Shell, arity) of
{arity, 1} ->
- {ok, User} =
- ssh_userreg:lookup_user(ConnectionManager),
fun() -> Shell(User) end;
{arity, 2} ->
- {ok, User} =
- ssh_userreg:lookup_user(ConnectionManager),
{ok, PeerAddr} =
- ssh_cm:get_peer_addr(ConnectionManager),
+ ssh_connection_manager:peer_addr(ConnectionManager),
fun() -> Shell(User, PeerAddr) end;
_ ->
Shell
@@ -441,10 +439,28 @@ start_shell(ConnectionManager, State) ->
State#state{group = Group, buf = empty_buf()}.
start_shell(_ConnectionManager, Cmd, #state{exec={M, F, A}} = State) ->
- Group = group:start(self(), {M, F, A++[Cmd]}, [{echo,false}]),
+ Group = group:start(self(), {M, F, A++[Cmd]}, [{echo, false}]),
+ State#state{group = Group, buf = empty_buf()};
+start_shell(ConnectionManager, Cmd, #state{exec=Shell} = State) when is_function(Shell) ->
+ {ok, User} =
+ ssh_userreg:lookup_user(ConnectionManager),
+ ShellFun =
+ case erlang:fun_info(Shell, arity) of
+ {arity, 1} ->
+ fun() -> Shell(Cmd) end;
+ {arity, 2} ->
+ fun() -> Shell(Cmd, User) end;
+ {arity, 3} ->
+ {ok, PeerAddr} =
+ ssh_connection_manager:peer_addr(ConnectionManager),
+ fun() -> Shell(Cmd, User, PeerAddr) end;
+ _ ->
+ Shell
+ end,
+ Echo = get_echo(State#state.pty),
+ Group = group:start(self(), ShellFun, [{echo,Echo}]),
State#state{group = Group, buf = empty_buf()}.
-
% Pty can be undefined if the client never sets any pty options before
% starting the shell.
get_echo(undefined) ->
diff --git a/lib/ssh/src/ssh_connect.hrl b/lib/ssh/src/ssh_connect.hrl
index a5a4e42cd8..34d4ff8fc1 100755
--- a/lib/ssh/src/ssh_connect.hrl
+++ b/lib/ssh/src/ssh_connect.hrl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2005-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 2005-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%
%%
@@ -260,5 +260,6 @@
address,
port,
options,
- exec
+ exec,
+ sub_system_supervisor
}).
diff --git a/lib/ssh/src/ssh_connection.erl b/lib/ssh/src/ssh_connection.erl
index 0aaf1c18d2..7b9e9185bf 100644
--- a/lib/ssh/src/ssh_connection.erl
+++ b/lib/ssh/src/ssh_connection.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%
%%
@@ -123,6 +123,8 @@ send(ConnectionManager, ChannelId, Data) ->
send(ConnectionManager, ChannelId, 0, Data, infinity).
send(ConnectionManager, ChannelId, Data, TimeOut) when is_integer(TimeOut) ->
send(ConnectionManager, ChannelId, 0, Data, TimeOut);
+send(ConnectionManager, ChannelId, Data, infinity) ->
+ send(ConnectionManager, ChannelId, 0, Data, infinity);
send(ConnectionManager, ChannelId, Type, Data) ->
send(ConnectionManager, ChannelId, Type, Data, infinity).
send(ConnectionManager, ChannelId, Type, Data, TimeOut) ->
@@ -944,13 +946,12 @@ encode_ip(Addr) when is_list(Addr) ->
end
end.
-start_channel(Address, Port, Cb, Id, Args) ->
- start_channel(Address, Port, Cb, Id, Args, undefined).
+start_channel(Cb, Id, Args, SubSysSup) ->
+ start_channel(Cb, Id, Args, SubSysSup, undefined).
-start_channel(Address, Port, Cb, Id, Args, Exec) ->
+start_channel(Cb, Id, Args, SubSysSup, Exec) ->
ChildSpec = child_spec(Cb, Id, Args, Exec),
- SystemSup = ssh_system_sup:system_supervisor(Address, Port),
- ChannelSup = ssh_system_sup:channel_supervisor(SystemSup),
+ ChannelSup =ssh_subsystem_sup:channel_supervisor(SubSysSup),
ssh_channel_sup:start_child(ChannelSup, ChildSpec).
%%--------------------------------------------------------------------
@@ -1015,18 +1016,19 @@ start_cli(#connection{address = Address, port = Port, cli_spec = {Fun, [Shell]},
{ok, Pid}
end;
-start_cli(#connection{address = Address, port = Port,
- cli_spec = {CbModule, Args}, exec = Exec}, ChannelId) ->
- start_channel(Address, Port, CbModule, ChannelId, Args, Exec).
+start_cli(#connection{cli_spec = {CbModule, Args}, exec = Exec,
+ sub_system_supervisor = SubSysSup}, ChannelId) ->
+ start_channel(CbModule, ChannelId, Args, SubSysSup, Exec).
start_subsytem(BinName, #connection{address = Address, port = Port,
- options = Options},
+ options = Options,
+ sub_system_supervisor = SubSysSup},
#channel{local_id = ChannelId, remote_id = RemoteChannelId},
ReplyMsg) ->
Name = binary_to_list(BinName),
case check_subsystem(Name, Options) of
{Callback, Opts} when is_atom(Callback), Callback =/= none ->
- start_channel(Address, Port, Callback, ChannelId, Opts);
+ start_channel(Callback, ChannelId, Opts, SubSysSup);
{Other, _} when Other =/= none ->
handle_backwards_compatibility(Other, self(),
ChannelId, RemoteChannelId,
diff --git a/lib/ssh/src/ssh_connection_controler.erl b/lib/ssh/src/ssh_connection_controler.erl
index 7960eb11c6..ca3e62dc83 100644
--- a/lib/ssh/src/ssh_connection_controler.erl
+++ b/lib/ssh/src/ssh_connection_controler.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%
%%
%%--------------------------------------------------------------------
@@ -99,8 +99,8 @@ terminate(_Reason, #state{}) ->
handle_call({handler, Pid, [Role, Socket, Opts]}, _From, State) ->
{ok, Handler} = ssh_connection_handler:start_link(Role, Pid, Socket, Opts),
{reply, {ok, Handler}, State#state{handler = Handler}};
-handle_call({manager, [server = Role, Socket, Opts]}, _From, State) ->
- {ok, Manager} = ssh_connection_manager:start_link([Role, Socket, Opts]),
+handle_call({manager, [server = Role, Socket, Opts, SubSysSup]}, _From, State) ->
+ {ok, Manager} = ssh_connection_manager:start_link([Role, Socket, Opts, SubSysSup]),
{reply, {ok, Manager}, State#state{manager = Manager}};
handle_call({manager, [client = Role | Opts]}, _From, State) ->
{ok, Manager} = ssh_connection_manager:start_link([Role, Opts]),
@@ -126,8 +126,8 @@ handle_cast(_, State) ->
%% handle_info(ssh_connected, State) ->
%% {stop, normal, State};
%% Servant termination.
-handle_info({'EXIT', _Pid, normal}, State) ->
- {stop, normal, State}.
+handle_info({'EXIT', _Pid, Reason}, State) ->
+ {stop, Reason, State}.
%%-----------------------------------------------------------------
%% Func: code_change/3
diff --git a/lib/ssh/src/ssh_connection_handler.erl b/lib/ssh/src/ssh_connection_handler.erl
index 5240b4b4c5..926d4fddce 100644
--- a/lib/ssh/src/ssh_connection_handler.erl
+++ b/lib/ssh/src/ssh_connection_handler.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%
%%
%%
@@ -530,6 +530,7 @@ handle_info({Protocol, Socket, Data}, Statename,
case size(EncData0) + size(Data) >= max(8, BlockSize) of
true ->
{Ssh, SshPacketLen, DecData, EncData} =
+
ssh_transport:decrypt_first_block(<<EncData0/binary,
Data/binary>>, Ssh0),
case SshPacketLen > ?SSH_MAX_PACKET_SIZE of
@@ -704,11 +705,19 @@ generate_event(<<?BYTE(Byte), _/binary>> = Msg, StateName,
Byte == ?SSH_MSG_CHANNEL_REQUEST;
Byte == ?SSH_MSG_CHANNEL_SUCCESS;
Byte == ?SSH_MSG_CHANNEL_FAILURE ->
- ssh_connection_manager:event(Pid, Msg),
- State = generate_event_new_state(State0, EncData),
- next_packet(State),
- {next_state, StateName, State};
+ try
+ ssh_connection_manager:event(Pid, Msg),
+ State = generate_event_new_state(State0, EncData),
+ next_packet(State),
+ {next_state, StateName, State}
+ catch
+ exit:{noproc, _Reason} ->
+ Report = io_lib:format("~p Connection Handler terminated: ~p~n",
+ [self(), Pid]),
+ error_logger:info_report(Report),
+ {stop, normal, State0}
+ end;
generate_event(Msg, StateName, State0, EncData) ->
Event = ssh_bits:decode(Msg),
State = generate_event_new_state(State0, EncData),
@@ -737,7 +746,8 @@ next_packet(#state{decoded_data_buffer = <<>>,
State) when Buff =/= <<>> andalso size(Buff) >= 8 ->
%% More data from the next packet has been received
%% Fake a socket-recive message so that the data will be processed
- self() ! {Protocol, Socket, <<>>} ,
+ inet:setopts(Socket, [{active, once}]),
+ self() ! {Protocol, Socket, <<>>},
State;
next_packet(#state{socket = Socket} = State) ->
diff --git a/lib/ssh/src/ssh_connection_manager.erl b/lib/ssh/src/ssh_connection_manager.erl
index 3863005e74..6bf89224cf 100644
--- a/lib/ssh/src/ssh_connection_manager.erl
+++ b/lib/ssh/src/ssh_connection_manager.erl
@@ -1,7 +1,7 @@
%%
%% %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
@@ -146,6 +146,8 @@ adjust_window(ConnectionManager, Channel, Bytes) ->
close(ConnectionManager, ChannelId) ->
try call(ConnectionManager, {close, ChannelId}) of
ok ->
+ ok;
+ {error,normal} ->
ok
catch
exit:{noproc, _} ->
@@ -155,6 +157,8 @@ close(ConnectionManager, ChannelId) ->
stop(ConnectionManager) ->
try call(ConnectionManager, stop) of
ok ->
+ ok;
+ {error,normal} ->
ok
catch
exit:{noproc, _} ->
@@ -178,7 +182,7 @@ send_eof(ConnectionManager, ChannelId) ->
%% {stop, Reason}
%% Description: Initiates the server
%%--------------------------------------------------------------------
-init([server, _Socket, Opts]) ->
+init([server, _Socket, Opts, SubSysSup]) ->
process_flag(trap_exit, true),
ssh_bits:install_messages(ssh_connection:messages()),
Cache = ssh_channel:cache_create(),
@@ -187,7 +191,8 @@ init([server, _Socket, Opts]) ->
channel_id_seed = 0,
port_bindings = [],
requests = [],
- channel_pids = []},
+ channel_pids = [],
+ sub_system_supervisor = SubSysSup},
opts = Opts,
connected = false}};
@@ -272,18 +277,18 @@ handle_call({ssh_msg, Pid, Msg}, From,
{stop, normal, State#state{connection_state = Connection}}
catch
exit:{noproc, Reason} ->
- Report = io_lib:format("Connection probably terminated:~n~p~n~p~n",
- [ConnectionMsg, Reason]),
+ Report = io_lib:format("Connection probably terminated:~n~p~n~p~n~p~n",
+ [ConnectionMsg, Reason, erlang:get_stacktrace()]),
error_logger:info_report(Report),
{noreply, State};
error:Error ->
- Report = io_lib:format("Connection message returned:~n~p~n~p~n",
- [ConnectionMsg, Error]),
+ Report = io_lib:format("Connection message returned:~n~p~n~p~n~p~n",
+ [ConnectionMsg, Error, erlang:get_stacktrace()]),
error_logger:info_report(Report),
{noreply, State};
exit:Exit ->
- Report = io_lib:format("Connection message returned:~n~p~n~p~n",
- [ConnectionMsg, Exit]),
+ Report = io_lib:format("Connection message returned:~n~p~n~p~n~p~n",
+ [ConnectionMsg, Exit, erlang:get_stacktrace()]),
error_logger:info_report(Report),
{noreply, State}
end;
@@ -400,7 +405,7 @@ handle_call({close, ChannelId}, _,
end;
handle_call(stop, _, #state{role = _client,
- client = ChannelPid,
+ client = _ChannelPid,
connection = Pid} = State) ->
DisconnectMsg =
#ssh_msg_disconnect{code = ?SSH_DISCONNECT_BY_APPLICATION,
@@ -555,13 +560,18 @@ handle_info({'EXIT', _, _}, State) ->
%% The return value is ignored.
%%--------------------------------------------------------------------
terminate(Reason, #state{connection_state =
- #connection{requests = Requests},
+ #connection{requests = Requests,
+ sub_system_supervisor = SubSysSup},
opts = Opts}) ->
SSHOpts = proplists:get_value(ssh_opts, Opts),
disconnect_fun(Reason, SSHOpts),
(catch lists:foreach(fun({_, From}) ->
gen_server:reply(From, {error, connection_closed})
end, Requests)),
+ Address = proplists:get_value(address, Opts),
+ Port = proplists:get_value(port, Opts),
+ SystemSup = ssh_system_sup:system_supervisor(Address, Port),
+ ssh_system_sup:stop_subsystem(SystemSup, SubSysSup),
ok.
%%--------------------------------------------------------------------
@@ -592,7 +602,9 @@ call(Pid, Msg, Timeout) ->
Result
catch
exit:{timeout, _} ->
- {error, timeout}
+ {error, timeout};
+ exit:{normal, _} ->
+ {error, normal}
end.
cast(Pid, Msg) ->
diff --git a/lib/ssh/src/ssh_sftpd.erl b/lib/ssh/src/ssh_sftpd.erl
index 10b8ede1e4..da91817fd7 100644
--- a/lib/ssh/src/ssh_sftpd.erl
+++ b/lib/ssh/src/ssh_sftpd.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2005-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 2005-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%
%%
@@ -242,7 +242,8 @@ handle_op(?SSH_FXP_REALPATH, ReqId,
end;
handle_op(?SSH_FXP_OPENDIR, ReqId,
<<?UINT32(RLen), RPath:RLen/binary>>,
- State0 = #state{file_handler = FileMod, file_state = FS0}) ->
+ State0 = #state{xf = #ssh_xfer{vsn = Vsn},
+ file_handler = FileMod, file_state = FS0}) ->
RelPath = binary_to_list(RPath),
AbsPath = relate_file_name(RelPath, State0),
@@ -250,10 +251,14 @@ handle_op(?SSH_FXP_OPENDIR, ReqId,
{IsDir, FS1} = FileMod:is_dir(AbsPath, FS0),
State1 = State0#state{file_state = FS1},
case IsDir of
- false ->
+ false when Vsn > 5 ->
ssh_xfer:xf_send_status(XF, ReqId, ?SSH_FX_NOT_A_DIRECTORY,
"Not a directory"),
State1;
+ false ->
+ ssh_xfer:xf_send_status(XF, ReqId, ?SSH_FX_FAILURE,
+ "Not a directory"),
+ State1;
true ->
add_handle(State1, XF, ReqId, directory, {RelPath,unread})
end;
diff --git a/lib/ssh/src/ssh_system_sup.erl b/lib/ssh/src/ssh_system_sup.erl
index 477f60f993..d1003e12f2 100644
--- a/lib/ssh/src/ssh_system_sup.erl
+++ b/lib/ssh/src/ssh_system_sup.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2008-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
@@ -33,7 +33,8 @@
stop_system/2, system_supervisor/2,
subsystem_supervisor/1, channel_supervisor/1,
connection_supervisor/1,
- acceptor_supervisor/1, start_subsystem/2, restart_subsystem/2, restart_acceptor/2]).
+ acceptor_supervisor/1, start_subsystem/2, restart_subsystem/2,
+ restart_acceptor/2, stop_subsystem/2]).
%% Supervisor callback
-export([init/1]).
@@ -83,6 +84,23 @@ start_subsystem(SystemSup, Options) ->
Spec = ssh_subsystem_child_spec(Options),
supervisor:start_child(SystemSup, Spec).
+stop_subsystem(SystemSup, SubSys) ->
+ case catch lists:keyfind(SubSys, 2, supervisor:which_children(SystemSup)) of
+ false ->
+ {error, not_found};
+ {Id, _, _, _} ->
+ spawn(fun() -> supervisor:terminate_child(SystemSup, Id),
+ supervisor:delete_child(SystemSup, Id) end),
+ ok;
+ {'EXIT', {noproc, _}} ->
+ %% Already terminated; probably shutting down.
+ ok;
+ {'EXIT', {shutdown, _}} ->
+ %% Already shutting down.
+ ok
+ end.
+
+
restart_subsystem(Address, Port) ->
SysSupName = make_name(Address, Port),
SubSysName = id(ssh_subsystem_sup, Address, Port),
diff --git a/lib/ssh/vsn.mk b/lib/ssh/vsn.mk
index 016fb30c69..a053318120 100644
--- a/lib/ssh/vsn.mk
+++ b/lib/ssh/vsn.mk
@@ -1,9 +1,28 @@
#-*-makefile-*- ; force emacs to enter makefile-mode
-SSH_VSN = 1.1.7
+SSH_VSN = 1.1.12
APP_VSN = "ssh-$(SSH_VSN)"
-TICKETS = OTP-8121 \
+TICKETS = OTP-8908
+
+TICKETS_1.1.12 = OTP-8807 \
+ OTP-8881
+
+TICKETS_1.1.11 = OTP-8735
+
+TICKETS_1.1.10 = OTP-8714
+
+TICKETS_1.1.9 = OTP-8524 \
+ OTP-8534 \
+ OTP-8535 \
+ OTP-8550 \
+ OTP-8644 \
+ OTP-8645
+
+TICKETS_1.1.8 = OTP-8356 \
+ OTP-8401
+
+TICKETS_1.1.7 = OTP-8121 \
OTP-8277 \
OTP-8278 \
OTP-8201
diff --git a/lib/ssl/c_src/Makefile.in b/lib/ssl/c_src/Makefile.in
index bd1b2f9375..49a209f2eb 100644
--- a/lib/ssl/c_src/Makefile.in
+++ b/lib/ssl/c_src/Makefile.in
@@ -1,19 +1,19 @@
#
# %CopyrightBegin%
-#
-# Copyright Ericsson AB 1999-2009. All Rights Reserved.
-#
+#
+# Copyright Ericsson AB 1999-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%
#
@@ -106,6 +106,7 @@ SSL_MAKEFILE =
endif
CC_R_FLAG=@CFLAG_RUNTIME_LIBRARY_PATH@
+
ifeq ($(findstring @,$(CC_R_FLAG)),@)
# Old erts configure used which hasn't replaced @CFLAG_RUNTIME_LIBRARY_PATH@;
# we try our best here instead...
@@ -127,6 +128,12 @@ else
CC_R_OPT = $(CC_R_FLAG)$(SSL_LIBDIR)
endif
+SSL_CC_RUNTIME_LIBRARY_PATH=@SSL_CC_RUNTIME_LIBRARY_PATH@
+# Sigh...
+ifeq ($(findstring @,$(SSL_CC_RUNTIME_LIBRARY_PATH)),@)
+SSL_CC_RUNTIME_LIBRARY_PATH = $(CC_R_OPT)
+endif
+
SSL_LINK_LIB=-L$(SSL_LIBDIR) -lssl -lcrypto
else
# not dynamic crypto lib (default from R11B-5)
@@ -134,6 +141,7 @@ NEED_KERBEROS=@SSL_LINK_WITH_KERBEROS@
NEED_ZLIB=@SSL_LINK_WITH_ZLIB@
SSL_MAKEFILE =
CC_R_OPT =
+SSL_CC_RUNTIME_LIBRARY_PATH=
SSL_LINK_LIB = $(SSL_LIBDIR)/libssl.a $(SSL_LIBDIR)/libcrypto.a
ifeq ($(NEED_KERBEROS),yes)
SSL_LINK_LIB += @STATIC_KERBEROS_LIBS@
@@ -163,11 +171,11 @@ $(OBJDIR)/%$(obj): %.c
# Unix
$(BINDIR)/ssl_esock: $(OBJS)
- $(CC) $(CC_R_OPT) $(PLAIN_CFLAGS) $(LDFLAGS) -o $@ $^ $(LIBS) $(SSL_LINK_LIB)
+ $(CC) $(PLAIN_CFLAGS) $(LDFLAGS) -o $@ $^ $(LIBS) $(SSL_CC_RUNTIME_LIBRARY_PATH) $(SSL_LINK_LIB)
# Win32/Cygwin
$(BINDIR)/ssl_esock.exe: $(OBJS)
- $(LD) -L$(SSL_LIBDIR) -o $@ $^ -lwsock32 -llibeay32 -lssleay32
+ $(LD) $(SSL_CC_RUNTIME_LIBRARY_PATH) -L$(SSL_LIBDIR) -o $@ $^ -lwsock32 -llibeay32 -lssleay32
# Unix only, and only when linking statically
$(SSL_MAKEFILE):
diff --git a/lib/ssl/doc/src/Makefile b/lib/ssl/doc/src/Makefile
index 54d274ef83..fa263d28ab 100644
--- a/lib/ssl/doc/src/Makefile
+++ b/lib/ssl/doc/src/Makefile
@@ -1,19 +1,19 @@
#
# %CopyrightBegin%
-#
-# Copyright Ericsson AB 1999-2009. All Rights Reserved.
-#
+#
+# Copyright Ericsson AB 1999-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%
#
@@ -52,6 +52,9 @@ XML_CHAPTER_FILES = \
BOOK_FILES = book.xml
+XML_FILES = $(BOOK_FILES) $(XML_APPLICATION_FILES) $(XML_REF3_FILES) $(XML_REF6_FILES) \
+ $(XML_PART_FILES) $(XML_CHAPTER_FILES)
+
GIF_FILES = warning.gif
PS_FILES =
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..08868a1b3c 100644
--- a/lib/ssl/doc/src/new_ssl.xml
+++ b/lib/ssl/doc/src/new_ssl.xml
@@ -60,10 +60,9 @@
very crippled as the control of the ssl-socket was deep
down in openssl making it hard if not impossible to
support all inet options, ipv6 and upgrade of a tcp
- connection to a ssl connection. The alfa version has a
+ connection to a ssl connection. This version has a
few limitations that will be removed before the ssl-4.0
- release. Main differences and limitations in the alfa are
- listed below.</p>
+ release. Main differences and limitations are listed below.</p>
<list type="bulleted">
<item>New ssl requires the crypto
@@ -85,8 +84,6 @@
<item>New API functions are
ssl:shutdown/2, ssl:cipher_suites/[0,1] and
ssl:versions/0</item>
- <item>Diffie-Hellman keyexchange is
- not supported yet.</item>
<item>CRL and policy certificate
extensions are not supported yet. </item>
<item>Supported SSL/TLS-versions are SSL-3.0 and TLS-1.0 </item>
@@ -119,8 +116,8 @@
{fail_if_no_peer_cert, boolean()}
{depth, integer()} |
{certfile, path()} | {keyfile, path()} | {password, string()} |
- {cacertfile, path()} | {ciphers, ciphers()} | {ssl_imp, ssl_imp()}
- | {reuse_sessions, boolean()} | {reuse_session, fun()}
+ {cacertfile, path()} | {dhfile, path()} | {ciphers, ciphers()} |
+ {ssl_imp, ssl_imp()} | {reuse_sessions, boolean()} | {reuse_session, fun()}
</c></p>
<p><c>transportoption() = {CallbackModule, DataTag, ClosedTag}
@@ -263,6 +260,12 @@ end
CA certificates (trusted certificates used for verifying a peer
certificate). May be omitted if you do not want to verify
the peer.</item>
+
+ <tag>{dhfile, path()}</tag>
+ <item>Path to file containing PEM encoded Diffie Hellman parameters,
+ for the server to use if a cipher suite using Diffie Hellman key exchange
+ is negotiated. If not specified hardcode parameters will be used.
+ </item>
<tag>{ciphers, ciphers()}</tag>
<item>The function <c>ciphers_suites/0</c> can
@@ -437,30 +440,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>
@@ -505,6 +495,19 @@ end
</func>
<func>
+ <name>renegotiate(Socket) -> ok | {error, Reason}</name>
+ <fsummary> Initiates a new handshake.</fsummary>
+ <type>
+ <v>Socket = sslsocket()</v>
+ </type>
+ <desc><p>Initiates a new handshake. A notable return value is
+ <c>{error, renegotiation_rejected}</c> indicating that the peer
+ refused to go through with the renegotiation but the connection
+ is still active using the previously negotiated session.</p>
+ </desc>
+ </func>
+
+ <func>
<name>send(Socket, Data) -> ok | {error, Reason}</name>
<fsummary>Write data to a socket.</fsummary>
<type>
diff --git a/lib/ssl/doc/src/notes.xml b/lib/ssl/doc/src/notes.xml
index 14dfe616ba..9d13427677 100644
--- a/lib/ssl/doc/src/notes.xml
+++ b/lib/ssl/doc/src/notes.xml
@@ -4,7 +4,7 @@
<chapter>
<header>
<copyright>
- <year>1999</year><year>2009</year>
+ <year>1999</year><year>2010</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
@@ -13,12 +13,12 @@
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>SSL Release Notes</title>
@@ -30,6 +30,124 @@
</header>
<p>This document describes the changes made to the SSL application.
</p>
+<section><title>SSL 3.11</title>
+
+ <section><title>Fixed Bugs and Malfunctions</title>
+ <list>
+ <item>
+ <p>
+ Fixes handling of the option fail_if_no_peer_cert and
+ some undocumented options. Thanks to Rory Byrne.</p>
+ <p>
+ Own Id: OTP-8557</p>
+ </item>
+ </list>
+ </section>
+
+ <section><title>Improvements and New Features</title>
+ <list>
+ <item>
+ <p>
+ Support for Diffie-Hellman. ssl-3.11 requires
+ public_key-0.6.</p>
+ <p>
+ Own Id: OTP-7046</p>
+ </item>
+ <item>
+ <p>
+ New ssl now properly handles ssl renegotiation, and
+ initiates a renegotiation if ssl/ltls-sequence numbers
+ comes close to the max value. However RFC-5746 is not yet
+ supported, but will be in an upcoming release.</p>
+ <p>
+ Own Id: OTP-8517</p>
+ </item>
+ <item>
+ <p>
+ When gen_tcp is configured with the {packet,http} option,
+ it automatically switches to expect HTTP Headers after a
+ HTTP Request/Response line has been received. This update
+ fixes ssl to behave in the same way. Thanks to Rory
+ Byrne.</p>
+ <p>
+ Own Id: OTP-8545</p>
+ </item>
+ <item>
+ <p>
+ Ssl now correctly verifies the extended_key_usage
+ extension and also allows the user to verify application
+ specific extensions by supplying an appropriate fun.</p>
+ <p>
+ Own Id: OTP-8554 Aux Id: OTP-8553 </p>
+ </item>
+ <item>
+ <p>
+ Fixed ssl:transport_accept/2 to return properly when
+ socket is closed. Thanks to Rory Byrne.</p>
+ <p>
+ Own Id: OTP-8560</p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
+<section><title>SSL 3.10.9</title>
+
+ <section><title>Fixed Bugs and Malfunctions</title>
+ <list>
+ <item>
+ <p>
+ Fixed a crash in the certificate certification part.</p>
+ <p>
+ Own Id: OTP-8510 Aux Id: seq11525 </p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
+<section><title>SSL 3.10.8</title>
+
+ <section><title>Fixed Bugs and Malfunctions</title>
+ <list>
+ <item>
+ <p><c>ssl:send/2</c> ignored packet option, fix provided
+ by YAMASHINA Hio.</p>
+ <p>Fixed a file cache bug which caused problems when the
+ same file was used for both cert and cacert.</p>
+ <p>Allow <c>ssl:listen/2</c> to be called with option
+ {ssl_imp, old}.</p>
+ <p> Fixed ssl:setopts(Socket, binary) which didn't work
+ for 'new' ssl.</p>.
+ <p>
+ Own Id: OTP-8441</p>
+ </item>
+ <item>
+ <p>
+ Do a controlled shutdown if a non ssl packet arrives as
+ the first packet.</p>
+ <p>
+ Own Id: OTP-8459 Aux Id: seq11505 </p>
+ </item>
+ </list>
+ </section>
+
+
+ <section><title>Improvements and New Features</title>
+ <list>
+ <item>
+ <p>Fixed session reuse (in new_ssl), thanks Wil Tan.</p>
+ <p>Send CA list during Certificate Request (in new_ssl) ,
+ thanks Wil Tan.</p> <p><c>NOTE</c>: SSL (new_ssl)
+ requires public_key-0.5.</p>
+ <p>
+ Own Id: OTP-8372</p>
+ </item>
+ </list>
+ </section>
+
+</section>
<section><title>SSL 3.10.7</title>
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/ssl/src/ssl.appup.src b/lib/ssl/src/ssl.appup.src
index 755c3b51b5..e8ae6846aa 100644
--- a/lib/ssl/src/ssl.appup.src
+++ b/lib/ssl/src/ssl.appup.src
@@ -7,7 +7,10 @@
{"3.10.3", [{restart_application, ssl}]},
{"3.10.4", [{restart_application, ssl}]},
{"3.10.5", [{restart_application, ssl}]},
- {"3.10.6", [{restart_application, ssl}]}
+ {"3.10.6", [{restart_application, ssl}]},
+ {"3.10.7", [{restart_application, ssl}]},
+ {"3.10.8", [{restart_application, ssl}]},
+ {"3.10.9", [{restart_application, ssl}]}
],
[
{"3.10", [{restart_application, ssl}]},
@@ -16,6 +19,8 @@
{"3.10.3", [{restart_application, ssl}]},
{"3.10.4", [{restart_application, ssl}]},
{"3.10.5", [{restart_application, ssl}]},
- {"3.10.6", [{restart_application, ssl}]}
+ {"3.10.6", [{restart_application, ssl}]},
+ {"3.10.8", [{restart_application, ssl}]},
+ {"3.10.9", [{restart_application, ssl}]}
]}.
diff --git a/lib/ssl/src/ssl.erl b/lib/ssl/src/ssl.erl
index 1222fe97fd..3cd4c7fdbd 100644
--- a/lib/ssl/src/ssl.erl
+++ b/lib/ssl/src/ssl.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 1999-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 1999-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%
%%
@@ -29,13 +29,15 @@
connect/3, connect/2, connect/4, connection_info/1,
controlling_process/2, listen/2, pid/1, peername/1, recv/2, recv/3,
send/2, getopts/2, setopts/2, seed/1, sockname/1, peercert/1,
- peercert/2, version/0, versions/0, session_info/1, format_error/1]).
+ peercert/2, version/0, versions/0, session_info/1, format_error/1,
+ renegotiate/1]).
%% Should be deprecated as soon as old ssl is removed
%%-deprecated({pid, 1, next_major_release}).
-include("ssl_int.hrl").
-include("ssl_internal.hrl").
+-include("ssl_record.hrl").
-record(config, {ssl, %% SSL parameters
inet_user, %% User set inet options
@@ -129,7 +131,8 @@ listen(Port, Options0) ->
%% so that new and old ssl can be run by the same
%% code, however the option will be ignored by old ssl
%% that hardcodes reuseaddr to true in its portprogram.
- Options = proplists:delete(reuseaddr, Options0),
+ Options1 = proplists:delete(reuseaddr, Options0),
+ Options = proplists:delete(ssl_imp, Options1),
old_listen(Port, Options);
Value ->
{error, {eoptions, {ssl_imp, Value}}}
@@ -150,18 +153,23 @@ transport_accept(#sslsocket{pid = {ListenSocket, #config{cb=CbInfo, ssl=SslOpts}
%% and options should be inherited.
EmOptions = emulated_options(),
{ok, InetValues} = inet:getopts(ListenSocket, EmOptions),
- {CbModule,_,_} = CbInfo,
- {ok, Socket} = CbModule:accept(ListenSocket, Timeout),
- inet:setopts(Socket, internal_inet_values()),
- {ok, Port} = inet:port(Socket),
- case ssl_connection_sup:start_child([server, "localhost", Port, Socket,
- {SslOpts, socket_options(InetValues)}, self(),
- CbInfo]) of
- {ok, Pid} ->
- CbModule:controlling_process(Socket, Pid),
- {ok, SslSocket#sslsocket{pid = Pid}};
- {error, Reason} ->
- {error, Reason}
+ ok = inet:setopts(ListenSocket, internal_inet_values()),
+ {CbModule,_,_} = CbInfo,
+ case CbModule:accept(ListenSocket, Timeout) of
+ {ok, Socket} ->
+ ok = inet:setopts(ListenSocket, InetValues),
+ {ok, Port} = inet:port(Socket),
+ ConnArgs = [server, "localhost", Port, Socket,
+ {SslOpts, socket_options(InetValues)}, self(), CbInfo],
+ case ssl_connection_sup:start_child(ConnArgs) of
+ {ok, Pid} ->
+ CbModule:controlling_process(Socket, Pid),
+ {ok, SslSocket#sslsocket{pid = Pid}};
+ {error, Reason} ->
+ {error, Reason}
+ end;
+ {error, Reason} ->
+ {error, Reason}
end;
transport_accept(#sslsocket{} = ListenSocket, Timeout) ->
@@ -366,8 +374,10 @@ getopts(#sslsocket{} = Socket, Options) ->
%%
%% Description:
%%--------------------------------------------------------------------
-setopts(#sslsocket{fd = new_ssl, pid = Pid}, Options) when is_pid(Pid) ->
- ssl_connection:set_opts(Pid, Options);
+setopts(#sslsocket{fd = new_ssl, pid = Pid}, Opts0) when is_pid(Pid) ->
+ Opts = proplists:expand([{binary, [{mode, binary}]},
+ {list, [{mode, list}]}], Opts0),
+ ssl_connection:set_opts(Pid, Opts);
setopts(#sslsocket{fd = new_ssl, pid = {ListenSocket, _}}, OptTags) ->
inet:setopts(ListenSocket, OptTags);
setopts(#sslsocket{} = Socket, Options) ->
@@ -433,6 +443,10 @@ versions() ->
AvailableVsns = ?DEFAULT_SUPPORTED_VERSIONS,
[{ssl_app, ?VSN}, {supported, SupportedVsns}, {available, AvailableVsns}].
+
+renegotiate(#sslsocket{pid = Pid, fd = new_ssl}) ->
+ ssl_connection:renegotiation(Pid).
+
%%%--------------------------------------------------------------
%%% Internal functions
%%%--------------------------------------------------------------------
@@ -506,6 +520,9 @@ handle_options(Opts0, Role) ->
end
end,
+ UserFailIfNoPeerCert = validate_option(fail_if_no_peer_cert,
+ proplists:get_value(fail_if_no_peer_cert, Opts, false)),
+
{Verify, FailIfNoPeerCert, CaCertDefault} =
%% Handle 0, 1, 2 for backwards compatibility
case proplists:get_value(verify, Opts, verify_none) of
@@ -518,9 +535,7 @@ handle_options(Opts0, Role) ->
verify_none ->
{verify_none, false, ca_cert_default(verify_none, Role)};
verify_peer ->
- {verify_peer, proplists:get_value(fail_if_no_peer_cert,
- Opts, false),
- ca_cert_default(verify_peer, Role)};
+ {verify_peer, UserFailIfNoPeerCert, ca_cert_default(verify_peer, Role)};
Value ->
throw({error, {eoptions, {verify, Value}}})
end,
@@ -531,28 +546,31 @@ handle_options(Opts0, Role) ->
versions = handle_option(versions, Opts, []),
verify = validate_option(verify, Verify),
verify_fun = handle_option(verify_fun, Opts, VerifyFun),
- fail_if_no_peer_cert = validate_option(fail_if_no_peer_cert,
- FailIfNoPeerCert),
+ fail_if_no_peer_cert = FailIfNoPeerCert,
verify_client_once = handle_option(verify_client_once, Opts, false),
+ validate_extensions_fun = handle_option(validate_extensions_fun, Opts, undefined),
depth = handle_option(depth, Opts, 1),
certfile = CertFile,
keyfile = handle_option(keyfile, Opts, CertFile),
key = handle_option(key, Opts, undefined),
password = handle_option(password, Opts, ""),
cacertfile = handle_option(cacertfile, Opts, CaCertDefault),
+ dhfile = handle_option(dhfile, Opts, undefined),
ciphers = handle_option(ciphers, Opts, []),
%% Server side option
reuse_session = handle_option(reuse_session, Opts, ReuseSessionFun),
reuse_sessions = handle_option(reuse_sessions, Opts, true),
+ renegotiate_at = handle_option(renegotiate_at, Opts, ?DEFAULT_RENEGOTIATE_AT),
debug = handle_option(debug, Opts, [])
},
CbInfo = proplists:get_value(cb_info, Opts, {gen_tcp, tcp, tcp_closed}),
- SslOptions = [versions, verify, verify_fun,
+ SslOptions = [versions, verify, verify_fun, validate_extensions_fun,
+ fail_if_no_peer_cert, verify_client_once,
depth, certfile, keyfile,
- key, password, cacertfile, ciphers,
+ key, password, cacertfile, dhfile, ciphers,
debug, reuse_session, reuse_sessions, ssl_imp,
- cd_info],
+ cb_info, renegotiate_at],
SockOpts = lists:foldl(fun(Key, PropList) ->
proplists:delete(Key, PropList)
@@ -582,6 +600,9 @@ validate_option(fail_if_no_peer_cert, Value)
validate_option(verify_client_once, Value)
when Value == true; Value == false ->
Value;
+
+validate_option(validate_extensions_fun, Value) when Value == undefined; is_function(Value) ->
+ Value;
validate_option(depth, Value) when is_integer(Value),
Value >= 0, Value =< 255->
Value;
@@ -602,11 +623,17 @@ validate_option(cacertfile, undefined) ->
"";
validate_option(cacertfile, Value) when is_list(Value), Value =/= "" ->
Value;
+validate_option(dhfile, undefined = Value) ->
+ Value;
+validate_option(dhfile, Value) when is_list(Value), Value =/= "" ->
+ Value;
validate_option(ciphers, Value) when is_list(Value) ->
Version = ssl_record:highest_protocol_version([]),
try cipher_suites(Version, Value)
catch
exit:_ ->
+ throw({error, {eoptions, {ciphers, Value}}});
+ error:_->
throw({error, {eoptions, {ciphers, Value}}})
end;
validate_option(reuse_session, Value) when is_function(Value) ->
@@ -614,6 +641,9 @@ validate_option(reuse_session, Value) when is_function(Value) ->
validate_option(reuse_sessions, Value) when Value == true;
Value == false ->
Value;
+validate_option(renegotiate_at, Value) when is_integer(Value) ->
+ min(Value, ?DEFAULT_RENEGOTIATE_AT);
+
validate_option(debug, Value) when is_list(Value); Value == true ->
Value;
validate_option(Opt, Value) ->
@@ -625,7 +655,7 @@ validate_versions([Version | Rest], Versions) when Version == 'tlsv1.1';
Version == tlsv1;
Version == sslv3 ->
validate_versions(Rest, Versions);
-validate_versions(Ver, Versions) ->
+validate_versions([Ver| _], Versions) ->
throw({error, {eoptions, {Ver, {versions, Versions}}}}).
validate_inet_option(mode, Value)
@@ -829,6 +859,11 @@ version() ->
Vsns
end,
{ok, {SSLVsn, CompVsn, LibVsn}}.
+
+min(N,M) when N < M ->
+ N;
+min(_, M) ->
+ M.
%% Only used to remove exit messages from old ssl
%% First is a nonsense clause to provide some
diff --git a/lib/ssl/src/ssl_broker.erl b/lib/ssl/src/ssl_broker.erl
index 178fb5fcb9..7ef88baf2b 100644
--- a/lib/ssl/src/ssl_broker.erl
+++ b/lib/ssl/src/ssl_broker.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 1999-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 1999-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%
%%
@@ -333,9 +333,9 @@ init([Client, Type]) ->
debug1(Debug, Type, "in start, client = ~w", [Client]),
{ok, #st{brokertype = Type, server = Server, client = Client,
collector = Client, debug = Debug}};
- true ->
- {stop, no_ssl_server}
- end.
+ true ->
+ {stop, no_ssl_server}
+ end.
%%
diff --git a/lib/ssl/src/ssl_certificate.erl b/lib/ssl/src/ssl_certificate.erl
index d97b61a5ce..686e90a70c 100644
--- a/lib/ssl/src/ssl_certificate.erl
+++ b/lib/ssl/src/ssl_certificate.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2007-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 2007-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%
%%
@@ -29,10 +29,12 @@
-include("ssl_alert.hrl").
-include("ssl_internal.hrl").
-include("ssl_debug.hrl").
+-include_lib("public_key/include/public_key.hrl").
-export([trusted_cert_and_path/3,
certificate_chain/2,
- file_to_certificats/1]).
+ file_to_certificats/1,
+ validate_extensions/6]).
%%====================================================================
%% Internal application API
@@ -87,6 +89,30 @@ file_to_certificats(File) ->
{ok, List} = ssl_manager:cache_pem_file(File),
[Bin || {cert, Bin, not_encrypted} <- List].
+
+%% Validates ssl/tls specific extensions
+validate_extensions([], ValidationState, UnknownExtensions, _, AccErr, _) ->
+ {UnknownExtensions, ValidationState, AccErr};
+
+validate_extensions([#'Extension'{extnID = ?'id-ce-extKeyUsage',
+ extnValue = KeyUse,
+ critical = true} | Rest],
+ ValidationState, UnknownExtensions, Verify, AccErr0, Role) ->
+ case is_valid_extkey_usage(KeyUse, Role) of
+ true ->
+ validate_extensions(Rest, ValidationState, UnknownExtensions,
+ Verify, AccErr0, Role);
+ false ->
+ AccErr =
+ not_valid_extension({bad_cert, invalid_ext_key_usage}, Verify, AccErr0),
+ validate_extensions(Rest, ValidationState, UnknownExtensions, Verify, AccErr, Role)
+ end;
+
+validate_extensions([Extension | Rest], ValidationState, UnknownExtensions,
+ Verify, AccErr, Role) ->
+ validate_extensions(Rest, ValidationState, [Extension | UnknownExtensions],
+ Verify, AccErr, Role).
+
%%--------------------------------------------------------------------
%%% Internal functions
%%--------------------------------------------------------------------
@@ -154,3 +180,18 @@ not_valid(Alert, true, _) ->
throw(Alert);
not_valid(_, false, {ErlCert, Path}) ->
{ErlCert, Path, [{bad_cert, unknown_ca}]}.
+
+is_valid_extkey_usage(KeyUse, client) ->
+ %% Client wants to verify server
+ is_valid_key_usage(KeyUse,?'id-kp-serverAuth');
+is_valid_extkey_usage(KeyUse, server) ->
+ %% Server wants to verify client
+ is_valid_key_usage(KeyUse, ?'id-kp-clientAuth').
+
+is_valid_key_usage(KeyUse, Use) ->
+ lists:member(Use, KeyUse).
+
+not_valid_extension(Error, true, _) ->
+ throw(Error);
+not_valid_extension(Error, false, AccErrors) ->
+ [Error | AccErrors].
diff --git a/lib/ssl/src/ssl_certificate_db.erl b/lib/ssl/src/ssl_certificate_db.erl
index decc6c9fea..b8c3c6f6b7 100644
--- a/lib/ssl/src/ssl_certificate_db.erl
+++ b/lib/ssl/src/ssl_certificate_db.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2007-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 2007-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%
%%
@@ -27,7 +27,7 @@
-export([create/0, remove/1, add_trusted_certs/3,
remove_trusted_certs/2, lookup_trusted_cert/3, issuer_candidate/1,
- cache_pem_file/3]).
+ lookup_cached_certs/1, cache_pem_file/3]).
%%====================================================================
%% Internal application API
@@ -74,6 +74,9 @@ lookup_trusted_cert(Ref, SerialNumber, Issuer) ->
{ok, Certs}
end.
+lookup_cached_certs(File) ->
+ ets:lookup(certificate_db_name(), {file, File}).
+
%%--------------------------------------------------------------------
%% Function: add_trusted_certs(Pid, File, Db) -> {ok, Ref}
%% Pid = pid()
@@ -90,7 +93,7 @@ add_trusted_certs(Pid, File, [CertsDb, FileToRefDb, PidToFileDb]) ->
undefined ->
NewRef = make_ref(),
add_certs_from_file(File, NewRef, CertsDb),
- insert(File, NewRef, 1, FileToRefDb),
+ insert(File, NewRef, 1, FileToRefDb),
NewRef;
[OldRef] ->
ref_count(File,FileToRefDb,1),
@@ -104,14 +107,11 @@ add_trusted_certs(Pid, File, [CertsDb, FileToRefDb, PidToFileDb]) ->
%%
%% Description: Cache file as binary in DB
%%--------------------------------------------------------------------
-cache_pem_file(Pid, File, [_CertsDb, FileToRefDb, PidToFileDb]) ->
- try ref_count(File, FileToRefDb,1)
- catch _:_ ->
- {ok, Content} = public_key:pem_to_der(File),
- insert(File,Content,1,FileToRefDb)
- end,
+cache_pem_file(Pid, File, [CertsDb, _FileToRefDb, PidToFileDb]) ->
+ Res = {ok, Content} = public_key:pem_to_der(File),
+ insert({file, File}, Content, CertsDb),
insert(Pid, File, PidToFileDb),
- {ok, FileToRefDb}.
+ Res.
%%--------------------------------------------------------------------
%% Function: remove_trusted_certs(Pid, Db) -> _
@@ -123,15 +123,16 @@ remove_trusted_certs(Pid, [CertsDb, FileToRefDb, PidToFileDb]) ->
Files = lookup(Pid, PidToFileDb),
delete(Pid, PidToFileDb),
Clear = fun(File) ->
- case ref_count(File, FileToRefDb, -1) of
- 0 ->
- case lookup(File, FileToRefDb) of
- [Ref] when is_reference(Ref) ->
- remove_certs(Ref, CertsDb);
- _ -> ok
- end,
- delete(File, FileToRefDb);
- _ ->
+ delete({file,File}, CertsDb),
+ try
+ 0 = ref_count(File, FileToRefDb, -1),
+ case lookup(File, FileToRefDb) of
+ [Ref] when is_reference(Ref) ->
+ remove_certs(Ref, CertsDb);
+ _ -> ok
+ end,
+ delete(File, FileToRefDb)
+ catch _:_ ->
ok
end
end,
@@ -158,6 +159,8 @@ issuer_candidate(no_candidate) ->
case ets:first(Db) of
'$end_of_table' ->
no_more_candidates;
+ {file, _} = Key ->
+ issuer_candidate(Key);
Key ->
[Cert] = lookup(Key, Db),
{Key, Cert}
@@ -168,6 +171,8 @@ issuer_candidate(PrevCandidateKey) ->
case ets:next(Db, PrevCandidateKey) of
'$end_of_table' ->
no_more_candidates;
+ {file, _} = Key ->
+ issuer_candidate(Key);
Key ->
[Cert] = lookup(Key, Db),
{Key, Cert}
@@ -189,7 +194,7 @@ ref_count(Key, Db,N) ->
ets:update_counter(Db,Key,N).
delete(Key, Db) ->
- true = ets:delete(Db, Key).
+ _ = ets:delete(Db, Key).
lookup(Key, Db) ->
case ets:lookup(Db, Key) of
diff --git a/lib/ssl/src/ssl_connection.erl b/lib/ssl/src/ssl_connection.erl
index 178c055cdf..8ff001b172 100644
--- a/lib/ssl/src/ssl_connection.erl
+++ b/lib/ssl/src/ssl_connection.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2007-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 2007-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%
%%
@@ -41,15 +41,14 @@
%% Internal application API
-export([send/2, send/3, recv/3, connect/7, accept/6, close/1, shutdown/2,
new_user/2, get_opts/2, set_opts/2, info/1, session_info/1,
- peer_certificate/1,
- sockname/1, peername/1]).
+ peer_certificate/1, sockname/1, peername/1, renegotiation/1]).
%% Called by ssl_connection_sup
-export([start_link/7]).
%% gen_fsm callbacks
--export([init/1, hello/2, certify/2, cipher/2, connection/2, connection/3, abbreviated/2,
- handle_event/3,
+-export([init/1, hello/2, certify/2, cipher/2, connection/2,
+ abbreviated/2, handle_event/3,
handle_sync_event/4, handle_info/3, terminate/3, code_change/4]).
-record(state, {
@@ -78,17 +77,25 @@
client_certificate_requested = false,
key_algorithm, % atom as defined by cipher_suite
public_key_info, % PKIX: {Algorithm, PublicKey, PublicKeyParams}
- private_key, % PKIX: 'RSAPrivateKey'
- diffie_hellman_params, %
+ private_key, % PKIX: #'RSAPrivateKey'{}
+ diffie_hellman_params, % PKIX: #'DHParameter'{} relevant for server side
+ diffie_hellman_keys, % {PublicKey, PrivateKey}
premaster_secret, %
cert_db_ref, % ets_table()
from, % term(), where to reply
bytes_to_read, % integer(), # bytes to read in passive mode
user_data_buffer, % binary()
%% tls_buffer, % Keeps a lookahead one packet if available
- log_alert % boolan()
+ log_alert, % boolean()
+ renegotiation, % {boolean(), From | internal | peer}
+ recv_during_renegotiation, %boolean()
+ send_queue % queue()
}).
+-define(DEFAULT_DIFFIE_HELLMAN_PARAMS,
+ #'DHParameter'{prime = ?DEFAULT_DIFFIE_HELLMAN_PRIME,
+ base = ?DEFAULT_DIFFIE_HELLMAN_GENERATOR}).
+
%%====================================================================
%% Internal application API
%%====================================================================
@@ -99,15 +106,15 @@
%% Description:
%%--------------------------------------------------------------------
send(Pid, Data) ->
- sync_send_event(Pid, {application_data, erlang:iolist_to_binary(Data)}, infinity).
+ sync_send_all_state_event(Pid, {application_data, erlang:iolist_to_binary(Data)}, infinity).
send(Pid, Data, Timeout) ->
- sync_send_event(Pid, {application_data, erlang:iolist_to_binary(Data)}, Timeout).
+ sync_send_all_state_event(Pid, {application_data, erlang:iolist_to_binary(Data)}, Timeout).
%%--------------------------------------------------------------------
%% Function:
%%
%% Description:
%%--------------------------------------------------------------------
-recv(Pid, Length, Timeout) -> % TODO: Prio with renegotiate?
+recv(Pid, Length, Timeout) ->
sync_send_all_state_event(Pid, {recv, Length}, Timeout).
%%--------------------------------------------------------------------
%% Function:
@@ -209,6 +216,14 @@ session_info(ConnectionPid) ->
peer_certificate(ConnectionPid) ->
sync_send_all_state_event(ConnectionPid, peer_certificate).
+%%--------------------------------------------------------------------
+%% Function:
+%%
+%% Description:
+%%--------------------------------------------------------------------
+renegotiation(ConnectionPid) ->
+ sync_send_all_state_event(ConnectionPid, renegotiate).
+
%%====================================================================
%% ssl_connection_sup API
%%====================================================================
@@ -224,7 +239,6 @@ start_link(Role, Host, Port, Socket, Options, User, CbInfo) ->
gen_fsm:start_link(?MODULE, [Role, Host, Port, Socket, Options,
User, CbInfo], []).
-
%%====================================================================
%% gen_fsm callbacks
%%====================================================================
@@ -243,12 +257,13 @@ init([Role, Host, Port, Socket, {SSLOpts, _} = Options,
Hashes0 = ssl_handshake:init_hashes(),
try ssl_init(SSLOpts, Role) of
- {ok, Ref, CacheRef, OwnCert, Key} ->
+ {ok, Ref, CacheRef, OwnCert, Key, DHParams} ->
State = State0#state{tls_handshake_hashes = Hashes0,
own_cert = OwnCert,
cert_db_ref = Ref,
session_cache = CacheRef,
- private_key = Key},
+ private_key = Key,
+ diffie_hellman_params = DHParams},
{ok, hello, State}
catch
throw:Error ->
@@ -261,18 +276,20 @@ init([Role, Host, Port, Socket, {SSLOpts, _} = Options,
%% {next_state, NextStateName,
%% NextState, Timeout} |
%% {stop, Reason, NewState}
-%% Description:There should be one instance of this function for each possible
-%% state name. Whenever a gen_fsm receives an event sent using
-%% gen_fsm:send_event/2, the instance of this function with the same name as
-%% the current state name StateName is called to handle the event. It is also
-%% called if a timeout occurs.
+%%
+%% Description:There should be one instance of this function for each
+%% possible state name. Whenever a gen_fsm receives an event sent
+%% using gen_fsm:send_event/2, the instance of this function with the
+%% same name as the current state name StateName is called to handle
+%% the event. It is also called if a timeout occurs.
%%--------------------------------------------------------------------
hello(socket_control, #state{host = Host, port = Port, role = client,
ssl_options = SslOpts,
transport_cb = Transport, socket = Socket,
connection_states = ConnectionStates}
= State0) ->
- Hello = ssl_handshake:client_hello(Host, Port, ConnectionStates, SslOpts),
+ Hello = ssl_handshake:client_hello(Host, Port,
+ ConnectionStates, SslOpts),
Version = Hello#client_hello.client_version,
Hashes0 = ssl_handshake:init_hashes(),
{BinMsg, CS2, Hashes1} =
@@ -289,7 +306,7 @@ hello(socket_control, #state{host = Host, port = Port, role = client,
hello(socket_control, #state{role = server} = State) ->
{next_state, hello, next_record(State)};
-hello(hello, #state{role = client} = State) ->
+hello(#hello_request{}, #state{role = client} = State) ->
{next_state, hello, State};
hello(#server_hello{cipher_suite = CipherSuite,
@@ -301,13 +318,14 @@ hello(#server_hello{cipher_suite = CipherSuite,
host = Host, port = Port,
session_cache = Cache,
session_cache_cb = CacheCb} = State0) ->
+
{Version, NewId, ConnectionStates1} =
ssl_handshake:hello(Hello, ConnectionStates0),
{KeyAlgorithm, _, _, _} =
ssl_cipher:suite_definition(CipherSuite),
- PremasterSecret = make_premaster_secret(ReqVersion),
+ PremasterSecret = make_premaster_secret(ReqVersion, KeyAlgorithm),
State = State0#state{key_algorithm = KeyAlgorithm,
negotiated_version = Version,
@@ -358,47 +376,45 @@ hello(Hello = #client_hello{client_version = ClientVersion},
abbreviated(socket_control, #state{role = server} = State) ->
{next_state, abbreviated, State};
-abbreviated(hello, State) ->
+abbreviated(#hello_request{}, State) ->
{next_state, certify, State};
abbreviated(Finished = #finished{},
#state{role = server,
negotiated_version = Version,
tls_handshake_hashes = Hashes,
- session = #session{master_secret = MasterSecret},
- from = From} = State) ->
+ session = #session{master_secret = MasterSecret}} =
+ State0) ->
case ssl_handshake:verify_connection(Version, Finished, client,
MasterSecret, Hashes) of
verified ->
- gen_fsm:reply(From, connected),
- {next_state, connection, next_record_if_active(State)};
- #alert{} = Alert ->
- handle_own_alert(Alert, Version, abbreviated, State),
- {stop, normal, State}
+ State = ack_connection(State0),
+ next_state_connection(State);
+ #alert{} = Alert ->
+ handle_own_alert(Alert, Version, abbreviated, State0),
+ {stop, normal, State0}
end;
abbreviated(Finished = #finished{},
#state{role = client, tls_handshake_hashes = Hashes0,
session = #session{master_secret = MasterSecret},
- from = From,
- negotiated_version = Version} = State) ->
+ negotiated_version = Version} = State0) ->
case ssl_handshake:verify_connection(Version, Finished, server,
MasterSecret, Hashes0) of
verified ->
- {ConnectionStates, Hashes} = finalize_client_handshake(State),
- gen_fsm:reply(From, connected),
- {next_state, connection,
- next_record_if_active(State#state{tls_handshake_hashes = Hashes,
- connection_states =
- ConnectionStates})};
+ {ConnectionStates, Hashes} = finalize_client_handshake(State0),
+ State = ack_connection(State0),
+ next_state_connection(State#state{tls_handshake_hashes = Hashes,
+ connection_states =
+ ConnectionStates});
#alert{} = Alert ->
- handle_own_alert(Alert, Version, abbreviated, State),
- {stop, normal, State}
+ handle_own_alert(Alert, Version, abbreviated, State0),
+ {stop, normal, State0}
end.
certify(socket_control, #state{role = server} = State) ->
{next_state, certify, State};
-certify(hello, State) ->
+certify(#hello_request{}, State) ->
{next_state, certify, State};
certify(#certificate{asn1_certificates = []},
@@ -415,52 +431,71 @@ certify(#certificate{asn1_certificates = []},
ssl_options = #ssl_options{verify = verify_peer,
fail_if_no_peer_cert = false}} =
State) ->
- {next_state, certify, next_record(State#state{client_certificate_requested = false})};
+ {next_state, certify,
+ next_record(State#state{client_certificate_requested = false})};
certify(#certificate{} = Cert,
- #state{session = Session,
- negotiated_version = Version,
+ #state{negotiated_version = Version,
+ role = Role,
cert_db_ref = CertDbRef,
- ssl_options = Opts} = State0) ->
+ ssl_options = Opts} = State) ->
case ssl_handshake:certify(Cert, CertDbRef, Opts#ssl_options.depth,
Opts#ssl_options.verify,
- Opts#ssl_options.verify_fun) of
+ Opts#ssl_options.verify_fun,
+ Opts#ssl_options.validate_extensions_fun, Role) of
{PeerCert, PublicKeyInfo} ->
- State = State0#state{session =
- Session#session{peer_certificate = PeerCert},
- public_key_info = PublicKeyInfo,
- client_certificate_requested = false
- },
- {next_state, certify, next_record(State)};
+ handle_peer_cert(PeerCert, PublicKeyInfo,
+ State#state{client_certificate_requested = false});
#alert{} = Alert ->
- handle_own_alert(Alert, Version, certify_certificate, State0),
- {stop, normal, State0}
+ handle_own_alert(Alert, Version, certify_certificate, State),
+ {stop, normal, State}
end;
certify(#server_key_exchange{} = KeyExchangeMsg,
- #state{role = client,
- key_algorithm = Alg} = State)
- when Alg == dhe_dss; Alg == dhe_rsa; Alg == dh_anon; Alg == krb5 ->
- NewState = handle_server_key(KeyExchangeMsg, State),
- {next_state, certify, NewState};
+ #state{role = client, negotiated_version = Version,
+ key_algorithm = Alg} = State0)
+ when Alg == dhe_dss; Alg == dhe_rsa ->%%Not imp:Alg == dh_anon;Alg == krb5 ->
+ case handle_server_key(KeyExchangeMsg, State0) of
+ #state{} = State ->
+ {next_state, certify, next_record(State)};
+ #alert{} = Alert ->
+ handle_own_alert(Alert, Version, certify_server_keyexchange,
+ State0),
+ {stop, normal, State0}
+ end;
certify(#server_key_exchange{},
State = #state{role = client, negotiated_version = Version,
key_algorithm = Alg})
- when Alg == rsa; Alg == dh_dss; Alg == dh_rsa ->
+ when Alg == rsa; Alg == dh_dss; Alg == dh_rsa ->
Alert = ?ALERT_REC(?FATAL, ?UNEXPECTED_MESSAGE),
handle_own_alert(Alert, Version, certify_server_key_exchange, State),
{stop, normal, State};
-certify(KeyExchangeMsg = #server_key_exchange{}, State =
- #state{role = server}) ->
- NewState = handle_clinet_key(KeyExchangeMsg, State),
- {next_state, cipher, NewState};
-
certify(#certificate_request{}, State) ->
NewState = State#state{client_certificate_requested = true},
{next_state, certify, next_record(NewState)};
+
+%% Master secret was determined with help of server-key exchange msg
+certify(#server_hello_done{},
+ #state{session = #session{master_secret = MasterSecret} = Session,
+ connection_states = ConnectionStates0,
+ negotiated_version = Version,
+ premaster_secret = undefined,
+ role = client} = State0) ->
+ case ssl_handshake:master_secret(Version, Session,
+ ConnectionStates0, client) of
+ {MasterSecret, ConnectionStates1} ->
+ State = State0#state{connection_states = ConnectionStates1},
+ client_certify_and_key_exchange(State);
+ #alert{} = Alert ->
+ handle_own_alert(Alert, Version,
+ certify_server_hello_done, State0),
+ {stop, normal, State0}
+ end;
+
+%% Master secret is calculated from premaster_secret
certify(#server_hello_done{},
#state{session = Session0,
connection_states = ConnectionStates0,
@@ -487,7 +522,8 @@ certify(#client_key_exchange{},
negotiated_version = Version}) ->
%% We expect a certificate here
Alert = ?ALERT_REC(?FATAL, ?UNEXPECTED_MESSAGE),
- handle_own_alert(Alert, Version, certify_server_waiting_certificate, State),
+ handle_own_alert(Alert, Version,
+ certify_server_waiting_certificate, State),
{stop, normal, State};
@@ -517,11 +553,41 @@ certify(#client_key_exchange{exchange_keys
handle_own_alert(Alert, Version, certify_client_key_exchange,
State0),
{stop, normal, State0}
+ end;
+
+certify(#client_key_exchange{exchange_keys = #client_diffie_hellman_public{
+ dh_public = ClientPublicDhKey}},
+ #state{negotiated_version = Version,
+ diffie_hellman_params = #'DHParameter'{prime = P,
+ base = G},
+ diffie_hellman_keys = {_, ServerDhPrivateKey},
+ role = Role,
+ session = Session,
+ connection_states = ConnectionStates0} = State0) ->
+
+ PMpint = crypto:mpint(P),
+ GMpint = crypto:mpint(G),
+ PremasterSecret = crypto:dh_compute_key(mpint_binary(ClientPublicDhKey),
+ ServerDhPrivateKey,
+ [PMpint, GMpint]),
+
+ case ssl_handshake:master_secret(Version, PremasterSecret,
+ ConnectionStates0, Role) of
+ {MasterSecret, ConnectionStates} ->
+ State = State0#state{session =
+ Session#session{master_secret
+ = MasterSecret},
+ connection_states = ConnectionStates},
+ {next_state, cipher, next_record(State)};
+ #alert{} = Alert ->
+ handle_own_alert(Alert, Version,
+ certify_client_key_exchange, State0),
+ {stop, normal, State0}
end.
cipher(socket_control, #state{role = server} = State) ->
{next_state, cipher, State};
-cipher(hello, State) ->
+cipher(#hello_request{}, State) ->
{next_state, cipher, State};
cipher(#certificate_verify{signature = Signature},
@@ -543,43 +609,41 @@ cipher(#certificate_verify{signature = Signature},
end;
cipher(#finished{} = Finished,
- State = #state{from = From,
- negotiated_version = Version,
- host = Host,
- port = Port,
- role = Role,
- session = #session{master_secret = MasterSecret}
- = Session0,
- tls_handshake_hashes = Hashes}) ->
-
+ #state{negotiated_version = Version,
+ host = Host,
+ port = Port,
+ role = Role,
+ session = #session{master_secret = MasterSecret}
+ = Session0,
+ tls_handshake_hashes = Hashes} = State0) ->
+
case ssl_handshake:verify_connection(Version, Finished,
opposite_role(Role),
MasterSecret, Hashes) of
verified ->
- gen_fsm:reply(From, connected),
+ State = ack_connection(State0),
Session = register_session(Role, Host, Port, Session0),
case Role of
client ->
- {next_state, connection,
- next_record_if_active(State#state{session = Session})};
+ next_state_connection(State#state{session = Session});
server ->
{NewConnectionStates, NewHashes} =
finalize_server_handshake(State#state{
session = Session}),
- NewState =
- State#state{connection_states = NewConnectionStates,
- session = Session,
- tls_handshake_hashes = NewHashes},
- {next_state, connection, next_record_if_active(NewState)}
+ next_state_connection(State#state{connection_states =
+ NewConnectionStates,
+ session = Session,
+ tls_handshake_hashes =
+ NewHashes})
end;
#alert{} = Alert ->
- handle_own_alert(Alert, Version, cipher, State),
- {stop, normal, State}
+ handle_own_alert(Alert, Version, cipher, State0),
+ {stop, normal, State0}
end.
connection(socket_control, #state{role = server} = State) ->
{next_state, connection, State};
-connection(hello, State = #state{host = Host, port = Port,
+connection(#hello_request{}, State = #state{host = Host, port = Port,
socket = Socket,
ssl_options = SslOpts,
negotiated_version = Version,
@@ -592,36 +656,11 @@ connection(hello, State = #state{host = Host, port = Port,
{BinMsg, ConnectionStates1, Hashes1} =
encode_handshake(Hello, Version, ConnectionStates0, Hashes0),
Transport:send(Socket, BinMsg),
- {next_state, hello, State#state{connection_states = ConnectionStates1,
- tls_handshake_hashes = Hashes1}}.
-
-%%--------------------------------------------------------------------
-%% Function:
-%% state_name(Event, From, State) -> {next_state, NextStateName, NextState} |
-%% {next_state, NextStateName,
-%% NextState, Timeout} |
-%% {reply, Reply, NextStateName, NextState}|
-%% {reply, Reply, NextStateName,
-%% NextState, Timeout} |
-%% {stop, Reason, NewState}|
-%% {stop, Reason, Reply, NewState}
-%% Description: There should be one instance of this function for each
-%% possible state name. Whenever a gen_fsm receives an event sent using
-%% gen_fsm:sync_send_event/2,3, the instance of this function with the same
-%% name as the current state name StateName is called to handle the event.
-%%--------------------------------------------------------------------
-connection({application_data, Data}, _From,
- State = #state{socket = Socket,
- negotiated_version = Version,
- transport_cb = Transport,
- connection_states = ConnectionStates0}) ->
- %% We should look into having a worker process to do this to
- %% parallize send and receive decoding and not block the receiver
- %% if sending is overloading the socket.
- {Msgs, ConnectionStates1} = encode_data(Data, Version, ConnectionStates0),
- Result = Transport:send(Socket, Msgs),
- {reply, Result,
- connection, State#state{connection_states = ConnectionStates1}}.
+ {next_state, hello, next_record(State#state{connection_states =
+ ConnectionStates1,
+ tls_handshake_hashes = Hashes1})};
+connection(#client_hello{} = Hello, #state{role = server} = State) ->
+ hello(Hello, State).
%%--------------------------------------------------------------------
%% Function:
@@ -636,22 +675,37 @@ connection({application_data, Data}, _From,
%%--------------------------------------------------------------------
handle_event(#ssl_tls{type = ?HANDSHAKE, fragment = Data},
StateName,
- State = #state{key_algorithm = KeyAlg,
- tls_handshake_buffer = Buf0,
- negotiated_version = Version}) ->
+ State0 = #state{key_algorithm = KeyAlg,
+ tls_handshake_buffer = Buf0,
+ negotiated_version = Version}) ->
Handle =
- fun({Packet, Raw}, {next_state, SName, AS=#state{tls_handshake_hashes=Hs0}}) ->
+ fun({#hello_request{} = Packet, _}, {next_state, connection = SName, State}) ->
+ %% This message should not be included in handshake
+ %% message hashes. Starts new handshake (renegotiation)
+ Hs0 = ssl_handshake:init_hashes(),
+ ?MODULE:SName(Packet, State#state{tls_handshake_hashes=Hs0,
+ renegotiation = {true, peer}});
+ ({#hello_request{} = Packet, _}, {next_state, SName, State}) ->
+ %% This message should not be included in handshake
+ %% message hashes. Already in negotiation so it will be ignored!
+ ?MODULE:SName(Packet, State);
+ ({#client_hello{} = Packet, Raw}, {next_state, connection = SName, State}) ->
+ Hs0 = ssl_handshake:init_hashes(),
Hs1 = ssl_handshake:update_hashes(Hs0, Raw),
- ?MODULE:SName(Packet, AS#state{tls_handshake_hashes=Hs1});
+ ?MODULE:SName(Packet, State#state{tls_handshake_hashes=Hs1,
+ renegotiation = {true, peer}});
+ ({Packet, Raw}, {next_state, SName, State = #state{tls_handshake_hashes=Hs0}}) ->
+ Hs1 = ssl_handshake:update_hashes(Hs0, Raw),
+ ?MODULE:SName(Packet, State#state{tls_handshake_hashes=Hs1});
(_, StopState) -> StopState
end,
try
{Packets, Buf} = ssl_handshake:get_tls_handshake(Data,Buf0, KeyAlg,Version),
- Start = {next_state, StateName, State#state{tls_handshake_buffer = Buf}},
+ Start = {next_state, StateName, State0#state{tls_handshake_buffer = Buf}},
lists:foldl(Handle, Start, Packets)
catch throw:#alert{} = Alert ->
- handle_own_alert(Alert, Version, StateName, State),
- {stop, normal, State}
+ handle_own_alert(Alert, Version, StateName, State0),
+ {stop, normal, State0}
end;
handle_event(#ssl_tls{type = ?APPLICATION_DATA, fragment = Data},
@@ -680,7 +734,8 @@ handle_event(#ssl_tls{type = ?ALERT, fragment = Data}, StateName, State) ->
{next_state, StateName, State};
handle_event(#alert{level = ?FATAL} = Alert, connection,
- #state{from = From, user_application = {_Mon, Pid}, log_alert = Log,
+ #state{from = From, user_application = {_Mon, Pid},
+ log_alert = Log,
host = Host, port = Port, session = Session,
role = Role, socket_options = Opts} = State) ->
invalidate_session(Role, Host, Port, Session),
@@ -706,11 +761,21 @@ handle_event(#alert{level = ?WARNING, description = ?CLOSE_NOTIFY} = Alert,
_, #state{from = From, role = Role} = State) ->
alert_user(From, Alert, Role),
{stop, normal, State};
-handle_event(#alert{level = ?WARNING} = Alert, StateName,
+
+handle_event(#alert{level = ?WARNING, description = ?NO_RENEGOTIATION} = Alert, StateName,
+ #state{log_alert = Log, renegotiation = {true, internal}} = State) ->
+ log_alert(Log, StateName, Alert),
+ {stop, normal, State};
+
+handle_event(#alert{level = ?WARNING, description = ?NO_RENEGOTIATION} = Alert, StateName,
+ #state{log_alert = Log, renegotiation = {true, From}} = State) ->
+ log_alert(Log, StateName, Alert),
+ gen_fsm:reply(From, {error, renegotiation_rejected}),
+ {next_state, connection, next_record(State)};
+
+handle_event(#alert{level = ?WARNING, description = ?USER_CANCELED} = Alert, StateName,
#state{log_alert = Log} = State) ->
log_alert(Log, StateName, Alert),
-%%TODO: Could be user_canceled or no_negotiation should the latter be
- %% treated as fatal?!
{next_state, StateName, next_record(State)}.
%%--------------------------------------------------------------------
@@ -728,6 +793,43 @@ handle_event(#alert{level = ?WARNING} = Alert, StateName,
%% gen_fsm:sync_send_all_state_event/2,3, this function is called to handle
%% the event.
%%--------------------------------------------------------------------
+handle_sync_event({application_data, Data0}, From, connection,
+ #state{socket = Socket,
+ negotiated_version = Version,
+ transport_cb = Transport,
+ connection_states = ConnectionStates0,
+ send_queue = SendQueue,
+ socket_options = SockOpts,
+ ssl_options = #ssl_options{renegotiate_at = RenegotiateAt}}
+ = State) ->
+ %% We should look into having a worker process to do this to
+ %% parallize send and receive decoding and not block the receiver
+ %% if sending is overloading the socket.
+ try
+ Data = encode_packet(Data0, SockOpts),
+ case encode_data(Data, Version, ConnectionStates0, RenegotiateAt) of
+ {Msgs, [], ConnectionStates} ->
+ Result = Transport:send(Socket, Msgs),
+ {reply, Result,
+ connection, State#state{connection_states = ConnectionStates}};
+ {Msgs, RestData, ConnectionStates} ->
+ if
+ Msgs =/= [] ->
+ Transport:send(Socket, Msgs);
+ true ->
+ ok
+ end,
+ renegotiate(State#state{connection_states = ConnectionStates,
+ send_queue = queue:in_r({From, RestData}, SendQueue),
+ renegotiation = {true, internal}})
+ end
+ catch throw:Error ->
+ {reply, Error, connection, State}
+ end;
+handle_sync_event({application_data, Data}, From, StateName,
+ #state{send_queue = Queue} = State) ->
+ %% In renegotiation priorities handshake, send data when handshake is finished
+ {next_state, StateName, State#state{send_queue = queue:in({From, Data}, Queue)}};
handle_sync_event(started, From, StateName, State) ->
{next_state, StateName, State#state{from = From}};
@@ -744,23 +846,14 @@ handle_sync_event({shutdown, How}, From, StateName,
{stop, normal, Error, State#state{from = From}}
end;
-%% TODO: men vad g�r next_record om det �r t.ex. renegotiate? kanske
-%% inte bra... t�l att t�nkas p�!
-handle_sync_event({recv, N}, From, StateName,
- State0 = #state{user_data_buffer = Buffer}) ->
- State1 = State0#state{bytes_to_read = N, from = From},
- case Buffer of
- <<>> ->
- State = next_record(State1),
- {next_state, StateName, State};
- _ ->
- case application_data(<<>>, State1) of
- Stop = {stop, _, _} ->
- Stop;
- State ->
- {next_state, StateName, State}
- end
- end;
+handle_sync_event({recv, N}, From, connection = StateName, State0) ->
+ passive_receive(State0#state{bytes_to_read = N, from = From}, StateName);
+
+%% Doing renegotiate wait with handling request until renegotiate is
+%% finished. Will be handled by next_state_connection/1.
+handle_sync_event({recv, N}, From, StateName, State) ->
+ {next_state, StateName, State#state{bytes_to_read = N, from = From,
+ recv_during_renegotiation = true}};
handle_sync_event({new_user, User}, _From, StateName,
State =#state{user_application = {OldMon, _}}) ->
@@ -808,6 +901,12 @@ handle_sync_event({set_opts, Opts0}, _From, StateName,
end
end;
+handle_sync_event(renegotiate, From, connection, State) ->
+ renegotiate(State#state{renegotiation = {true, From}});
+
+handle_sync_event(renegotiate, _, StateName, State) ->
+ {reply, {error, already_renegotiating}, StateName, State};
+
handle_sync_event(info, _, StateName,
#state{negotiated_version = Version,
session = #session{cipher_suite = Suite}} = State) ->
@@ -828,7 +927,6 @@ handle_sync_event(peer_certificate, _, StateName,
= State) ->
{reply, {ok, Cert}, StateName, State}.
-
%%--------------------------------------------------------------------
%% Function:
%% handle_info(Info,StateName,State)-> {next_state, NextStateName, NextState}|
@@ -857,34 +955,6 @@ handle_info({Protocol, _, Data}, StateName, State =
{stop, normal, State}
end;
-%% %% This is the code for {packet,ssl} removed because it was slower
-%% %% than handling it in erlang.
-%% handle_info(Data = #ssl_tls{}, StateName,
-%% State = #state{tls_buffer = Buffer,
-%% socket = Socket,
-%% connection_states = ConnectionStates0}) ->
-%% case Buffer of
-%% buffer ->
-%% {next_state, StateName, State#state{tls_buffer = [Data]}};
-%% continue ->
-%% inet:setopts(Socket, [{active,once}]),
-%% {Plain, ConnectionStates} =
-%% ssl_record:decode_cipher_text(Data, ConnectionStates0),
-%% gen_fsm:send_all_state_event(self(), Plain),
-%% {next_state, StateName,
-%% State#state{tls_buffer = buffer,
-%% connection_states = ConnectionStates}};
-%% List when is_list(List) ->
-%% {next_state, StateName,
-%% State#state{tls_buffer = Buffer ++ [Data]}}
-%% end;
-
-%% handle_info(CloseMsg = {_, Socket}, StateName0,
-%% #state{socket = Socket,tls_buffer = [Msg]} = State0) ->
-%% %% Hmm we have a ssl_tls msg buffered, handle that first
-%% %% and it proberbly is a close alert
-%% {next_state, StateName0, State0#state{tls_buffer=[Msg,{ssl_close,CloseMsg}]}};
-
handle_info({CloseTag, Socket}, _StateName,
#state{socket = Socket, close_tag = CloseTag,
negotiated_version = Version, host = Host,
@@ -918,17 +988,23 @@ handle_info(A, StateName, State) ->
%% necessary cleaning up. When it returns, the gen_fsm terminates with
%% Reason. The return value is ignored.
%%--------------------------------------------------------------------
-terminate(_Reason, connection, _S=#state{negotiated_version = Version,
+terminate(_Reason, connection, #state{negotiated_version = Version,
connection_states = ConnectionStates,
transport_cb = Transport,
- socket = Socket}) ->
+ socket = Socket, send_queue = SendQueue,
+ renegotiation = Renegotiate}) ->
+ notify_senders(SendQueue),
+ notify_renegotiater(Renegotiate),
{BinAlert, _} = encode_alert(?ALERT_REC(?WARNING,?CLOSE_NOTIFY),
Version, ConnectionStates),
Transport:send(Socket, BinAlert),
Transport:close(Socket);
-terminate(_Reason, _StateName, _S=#state{transport_cb = Transport, socket = Socket}) ->
- Transport:close(Socket),
- ok.
+terminate(_Reason, _StateName, #state{transport_cb = Transport,
+ socket = Socket, send_queue = SendQueue,
+ renegotiation = Renegotiate}) ->
+ notify_senders(SendQueue),
+ notify_renegotiater(Renegotiate),
+ Transport:close(Socket).
%%--------------------------------------------------------------------
%% Function:
@@ -963,8 +1039,8 @@ ssl_init(SslOpts, Role) ->
PrivateKey =
init_private_key(SslOpts#ssl_options.key, SslOpts#ssl_options.keyfile,
SslOpts#ssl_options.password, Role),
- ?DBG_TERM(PrivateKey),
- {ok, CertDbRef, CacheRef, OwnCert, PrivateKey}.
+ DHParams = init_diffie_hellman(SslOpts#ssl_options.dhfile, Role),
+ {ok, CertDbRef, CacheRef, OwnCert, PrivateKey, DHParams}.
init_certificates(#ssl_options{cacertfile = CACertFile,
certfile = CertFile}, Role) ->
@@ -972,8 +1048,14 @@ init_certificates(#ssl_options{cacertfile = CACertFile,
case ssl_manager:connection_init(CACertFile, Role) of
{ok, CertDbRef, CacheRef} ->
init_certificates(CertDbRef, CacheRef, CertFile, Role);
+ {error, {badmatch, _Error}} ->
+ Report = io_lib:format("SSL: Error ~p Initializing: ~p ~n",
+ [_Error, CACertFile]),
+ error_logger:error_report(Report),
+ throw(ecacertfile);
{error, _Error} ->
- Report = io_lib:format("SSL: Error ~p ~n",[_Error]),
+ Report = io_lib:format("SSL: Error ~p Initializing: ~p ~n",
+ [_Error, CACertFile]),
error_logger:error_report(Report),
throw(ecacertfile)
end.
@@ -990,12 +1072,20 @@ init_certificates(CertDbRef, CacheRef, CertFile, server) ->
try
[OwnCert] = ssl_certificate:file_to_certificats(CertFile),
{ok, CertDbRef, CacheRef, OwnCert}
- catch _E:_R ->
- Report = io_lib:format("SSL: ~p: ~p:~p ~p~n",
- [?LINE, _E,_R, erlang:get_stacktrace()]),
- error_logger:error_report(Report),
- throw(ecertfile)
- end.
+ catch
+ _E:{badmatch, _R={error,_}} ->
+ Report = io_lib:format("SSL: ~p: ~p:~p ~s~n ~p~n",
+ [?LINE, _E,_R, CertFile,
+ erlang:get_stacktrace()]),
+ error_logger:error_report(Report),
+ throw(ecertfile);
+ _E:_R ->
+ Report = io_lib:format("SSL: ~p: ~p:~p ~s~n ~p~n",
+ [?LINE, _E,_R, CertFile,
+ erlang:get_stacktrace()]),
+ error_logger:error_report(Report),
+ throw(ecertfile)
+ end.
init_private_key(undefined, "", _Password, client) ->
undefined;
@@ -1003,42 +1093,50 @@ init_private_key(undefined, KeyFile, Password, _) ->
try
{ok, List} = ssl_manager:cache_pem_file(KeyFile),
[Der] = [Der || Der = {PKey, _ , _} <- List,
- PKey =:= rsa_private_key orelse PKey =:= dsa_private_key],
+ PKey =:= rsa_private_key orelse
+ PKey =:= dsa_private_key],
{ok, Decoded} = public_key:decode_private_key(Der,Password),
Decoded
- catch _E:_R ->
- Report = io_lib:format("SSL: ~p: ~p:~p ~p~n",
- [?LINE, _E,_R, erlang:get_stacktrace()]),
+ catch
+ _E:{badmatch, _R={error,_}} ->
+ Report = io_lib:format("SSL: ~p: ~p:~p ~s~n ~p~n",
+ [?LINE, _E,_R, KeyFile,
+ erlang:get_stacktrace()]),
+ error_logger:error_report(Report),
+ throw(ekeyfile);
+ _E:_R ->
+ Report = io_lib:format("SSL: ~p: ~p:~p ~s~n ~p~n",
+ [?LINE, _E,_R, KeyFile,
+ erlang:get_stacktrace()]),
error_logger:error_report(Report),
throw(ekeyfile)
end;
init_private_key(PrivateKey, _, _,_) ->
PrivateKey.
-send_event(FsmPid, Event) ->
- gen_fsm:send_event(FsmPid, Event).
-
-sync_send_event(FsmPid, Event, Timeout) ->
- try gen_fsm:sync_send_event(FsmPid, Event, Timeout) of
- Reply ->
- Reply
- catch
- exit:{noproc, _} ->
- {error, closed};
- exit:{timeout, _} ->
- {error, timeout};
- exit:{normal, _} ->
- {error, closed}
+init_diffie_hellman(_, client) ->
+ undefined;
+init_diffie_hellman(undefined, _) ->
+ ?DEFAULT_DIFFIE_HELLMAN_PARAMS;
+init_diffie_hellman(DHParamFile, server) ->
+ {ok, List} = ssl_manager:cache_pem_file(DHParamFile),
+ case [Der || Der = {dh_params, _ , _} <- List] of
+ [Der] ->
+ {ok, Decoded} = public_key:decode_dhparams(Der),
+ Decoded;
+ [] ->
+ ?DEFAULT_DIFFIE_HELLMAN_PARAMS
end.
+send_event(FsmPid, Event) ->
+ gen_fsm:send_event(FsmPid, Event).
send_all_state_event(FsmPid, Event) ->
gen_fsm:send_all_state_event(FsmPid, Event).
sync_send_all_state_event(FsmPid, Event) ->
- sync_send_all_state_event(FsmPid, Event, ?DEFAULT_TIMEOUT
-).
+ sync_send_all_state_event(FsmPid, Event, ?DEFAULT_TIMEOUT).
sync_send_all_state_event(FsmPid, Event, Timeout) ->
try gen_fsm:sync_send_all_state_event(FsmPid, Event, Timeout)
@@ -1055,6 +1153,16 @@ sync_send_all_state_event(FsmPid, Event, Timeout) ->
alert_event(Alert) ->
send_all_state_event(self(), Alert).
+%% We do currently not support cipher suites that use fixed DH.
+%% If we want to implement that we should add a code
+%% here to extract DH parameters form cert.
+handle_peer_cert(PeerCert, PublicKeyInfo,
+ #state{session = Session} = State0) ->
+ State = State0#state{session =
+ Session#session{peer_certificate = PeerCert},
+ public_key_info = PublicKeyInfo},
+ {next_state, certify, next_record(State)}.
+
certify_client(#state{client_certificate_requested = true, role = client,
connection_states = ConnectionStates0,
transport_cb = Transport,
@@ -1088,9 +1196,8 @@ verify_client_cert(#state{client_certificate_requested = true, role = client,
ignore -> %% No key or cert or fixed_diffie_hellman
State;
Verified ->
- SigAlg = ssl_handshake:sig_alg(KeyAlg),
{BinVerified, ConnectionStates1, Hashes1} =
- encode_handshake(Verified, SigAlg, Version,
+ encode_handshake(Verified, KeyAlg, Version,
ConnectionStates0, Hashes0),
Transport:send(Socket, BinVerified),
State#state{connection_states = ConnectionStates1,
@@ -1115,13 +1222,14 @@ do_server_hello(Type, #state{negotiated_version = Version,
case ssl_handshake:master_secret(Version, Session,
ConnectionStates0, server) of
{_, ConnectionStates1} ->
- {ConnectionStates, Hashes} =
- finished(State#state{connection_states =
- ConnectionStates1}),
- {next_state, abbreviated,
- next_record(State#state{connection_states =
- ConnectionStates,
- tls_handshake_hashes = Hashes})};
+ State1 = State#state{connection_states=ConnectionStates1,
+ session = Session},
+ {ConnectionStates, Hashes} =
+ finalize_server_handshake(State1),
+ Resumed = State1#state{connection_states =
+ ConnectionStates,
+ tls_handshake_hashes = Hashes},
+ {next_state, abbreviated, next_record(Resumed)};
#alert{} = Alert ->
handle_own_alert(Alert, Version, hello, State),
{stop, normal, State}
@@ -1230,14 +1338,15 @@ key_exchange(#state{role = server, key_algorithm = Algo} = State)
Algo == dh_rsa ->
State;
-key_exchange(#state{role = server, key_algorithm = rsa_export} = State) ->
+%key_exchange(#state{role = server, key_algorithm = rsa_export} = State) ->
%% TODO when the public key in the server certificate is
%% less than or equal to 512 bits in length dont send key_exchange
%% but do it otherwise
- State;
+% State;
key_exchange(#state{role = server, key_algorithm = Algo,
diffie_hellman_params = Params,
+ private_key = PrivateKey,
connection_states = ConnectionStates0,
negotiated_version = Version,
tls_handshake_hashes = Hashes0,
@@ -1248,26 +1357,28 @@ key_exchange(#state{role = server, key_algorithm = Algo,
Algo == dhe_dss_export;
Algo == dhe_rsa;
Algo == dhe_rsa_export ->
- Msg = ssl_handshake:key_exchange(server, Params),
- {BinMsg, ConnectionStates1, Hashes1} =
- encode_handshake(Msg, Version, ConnectionStates0, Hashes0),
- Transport:send(Socket, BinMsg),
- State#state{connection_states = ConnectionStates1,
- tls_handshake_hashes = Hashes1};
-key_exchange(#state{role = server, key_algorithm = dh_anon,
- connection_states = ConnectionStates0,
- negotiated_version = Version,
- tls_handshake_hashes = Hashes0,
- socket = Socket,
- transport_cb = Transport
- } = State) ->
- Msg = ssl_handshake:key_exchange(server, anonymous),
- {BinMsg, ConnectionStates1, Hashes1} =
+ Keys = public_key:gen_key(Params),
+ ConnectionState =
+ ssl_record:pending_connection_state(ConnectionStates0, read),
+ SecParams = ConnectionState#connection_state.security_parameters,
+ #security_parameters{client_random = ClientRandom,
+ server_random = ServerRandom} = SecParams,
+ Msg = ssl_handshake:key_exchange(server, {dh, Keys, Params,
+ Algo, ClientRandom,
+ ServerRandom,
+ PrivateKey}),
+ {BinMsg, ConnectionStates, Hashes1} =
encode_handshake(Msg, Version, ConnectionStates0, Hashes0),
Transport:send(Socket, BinMsg),
- State#state{connection_states = ConnectionStates1,
+ State#state{connection_states = ConnectionStates,
+ diffie_hellman_keys = Keys,
tls_handshake_hashes = Hashes1};
+
+
+%% key_algorithm = dh_anon is not supported. Should be by default disabled
+%% if support is implemented and then we need a key_exchange clause for it
+%% here.
key_exchange(#state{role = client,
connection_states = ConnectionStates0,
@@ -1287,17 +1398,33 @@ key_exchange(#state{role = client,
key_exchange(#state{role = client,
connection_states = ConnectionStates0,
key_algorithm = Algorithm,
- public_key_info = PublicKeyInfo,
negotiated_version = Version,
- diffie_hellman_params = Params,
- own_cert = Cert,
+ diffie_hellman_keys = {DhPubKey, _},
socket = Socket, transport_cb = Transport,
tls_handshake_hashes = Hashes0} = State)
when Algorithm == dhe_dss;
Algorithm == dhe_dss_export;
Algorithm == dhe_rsa;
Algorithm == dhe_rsa_export ->
- Msg = dh_key_exchange(Cert, Params, PublicKeyInfo),
+ Msg = ssl_handshake:key_exchange(client, {dh, DhPubKey}),
+ {BinMsg, ConnectionStates1, Hashes1} =
+ encode_handshake(Msg, Version, ConnectionStates0, Hashes0),
+ Transport:send(Socket, BinMsg),
+ State#state{connection_states = ConnectionStates1,
+ tls_handshake_hashes = Hashes1};
+
+key_exchange(#state{role = client,
+ connection_states = ConnectionStates0,
+ key_algorithm = Algorithm,
+ negotiated_version = Version,
+ client_certificate_requested = ClientCertReq,
+ own_cert = OwnCert,
+ diffie_hellman_keys = DhKeys,
+ socket = Socket, transport_cb = Transport,
+ tls_handshake_hashes = Hashes0} = State)
+ when Algorithm == dh_dss;
+ Algorithm == dh_rsa ->
+ Msg = dh_key_exchange(OwnCert, DhKeys, ClientCertReq),
{BinMsg, ConnectionStates1, Hashes1} =
encode_handshake(Msg, Version, ConnectionStates0, Hashes0),
Transport:send(Socket, BinMsg),
@@ -1312,17 +1439,19 @@ rsa_key_exchange(PremasterSecret, PublicKeyInfo = {Algorithm, _, _})
ssl_handshake:key_exchange(client,
{premaster_secret, PremasterSecret,
PublicKeyInfo});
-
rsa_key_exchange(_, _) ->
throw (?ALERT_REC(?FATAL,?HANDSHAKE_FAILURE)).
-dh_key_exchange(OwnCert, Params, PublicKeyInfo) ->
+dh_key_exchange(OwnCert, DhKeys, true) ->
case public_key:pkix_is_fixed_dh_cert(OwnCert) of
true ->
ssl_handshake:key_exchange(client, fixed_diffie_hellman);
false ->
- ssl_handshake:key_exchange(client, {dh, Params, PublicKeyInfo})
- end.
+ {DhPubKey, _} = DhKeys,
+ ssl_handshake:key_exchange(client, {dh, DhPubKey})
+ end;
+dh_key_exchange(_, {DhPubKey, _}, false) ->
+ ssl_handshake:key_exchange(client, {dh, DhPubKey}).
request_client_cert(#state{ssl_options = #ssl_options{verify = verify_peer},
connection_states = ConnectionStates0,
@@ -1356,7 +1485,8 @@ finalize_client_handshake(#state{connection_states = ConnectionStates0}
finalize_server_handshake(State) ->
ConnectionStates0 = cipher_protocol(State),
ConnectionStates =
- ssl_record:activate_pending_connection_state(ConnectionStates0, write),
+ ssl_record:activate_pending_connection_state(ConnectionStates0,
+ write),
finished(State#state{connection_states = ConnectionStates}).
cipher_protocol(#state{connection_states = ConnectionStates,
@@ -1364,7 +1494,8 @@ cipher_protocol(#state{connection_states = ConnectionStates,
negotiated_version = Version,
transport_cb = Transport}) ->
{BinChangeCipher, NewConnectionStates} =
- encode_change_cipher(#change_cipher_spec{}, Version, ConnectionStates),
+ encode_change_cipher(#change_cipher_spec{},
+ Version, ConnectionStates),
Transport:send(Socket, BinChangeCipher),
NewConnectionStates.
@@ -1380,10 +1511,66 @@ finished(#state{role = Role, socket = Socket, negotiated_version = Version,
Transport:send(Socket, BinFinished),
{NewConnectionStates, NewHashes}.
-handle_server_key(_KeyExchangeMsg, State) ->
- State.
-handle_clinet_key(_KeyExchangeMsg, State) ->
- State.
+handle_server_key(
+ #server_key_exchange{params =
+ #server_dh_params{dh_p = P,
+ dh_g = G,
+ dh_y = ServerPublicDhKey},
+ signed_params = Signed},
+ #state{session = Session, negotiated_version = Version, role = Role,
+ public_key_info = PubKeyInfo,
+ key_algorithm = KeyAlgo,
+ connection_states = ConnectionStates0} = State) ->
+
+ PLen = size(P),
+ GLen = size(G),
+ YLen = size(ServerPublicDhKey),
+
+ ConnectionState =
+ ssl_record:pending_connection_state(ConnectionStates0, read),
+ SecParams = ConnectionState#connection_state.security_parameters,
+ #security_parameters{client_random = ClientRandom,
+ server_random = ServerRandom} = SecParams,
+ Hash = ssl_handshake:server_key_exchange_hash(KeyAlgo,
+ <<ClientRandom/binary,
+ ServerRandom/binary,
+ ?UINT16(PLen), P/binary,
+ ?UINT16(GLen), G/binary,
+ ?UINT16(YLen),
+ ServerPublicDhKey/binary>>),
+
+ case verify_dh_params(Signed, Hash, PubKeyInfo) of
+ true ->
+ PMpint = mpint_binary(P),
+ GMpint = mpint_binary(G),
+ Keys = {_, ClientDhPrivateKey} =
+ crypto:dh_generate_key([PMpint,GMpint]),
+ PremasterSecret =
+ crypto:dh_compute_key(mpint_binary(ServerPublicDhKey),
+ ClientDhPrivateKey, [PMpint, GMpint]),
+ case ssl_handshake:master_secret(Version, PremasterSecret,
+ ConnectionStates0, Role) of
+ {MasterSecret, ConnectionStates} ->
+ State#state{diffie_hellman_keys = Keys,
+ session =
+ Session#session{master_secret
+ = MasterSecret},
+ connection_states = ConnectionStates};
+ #alert{} = Alert ->
+ Alert
+ end;
+ false ->
+ ?ALERT_REC(?FATAL,?HANDSHAKE_FAILURE)
+ end.
+
+verify_dh_params(Signed, Hash, {?rsaEncryption, PubKey, _PubKeyparams}) ->
+ case public_key:decrypt_public(Signed, PubKey,
+ [{rsa_pad, rsa_pkcs1_padding}]) of
+ Hash ->
+ true;
+ _ ->
+ false
+ end.
encode_alert(#alert{} = Alert, Version, ConnectionStates) ->
?DBG_TERM(Alert),
@@ -1405,8 +1592,23 @@ encode_handshake(HandshakeRec, SigAlg, Version, ConnectionStates0, Hashes0) ->
ssl_record:encode_handshake(Frag, Version, ConnectionStates0),
{E, ConnectionStates1, Hashes1}.
-encode_data(Data, Version, ConnectionStates) ->
- ssl_record:encode_data(Data, Version, ConnectionStates).
+encode_packet(Data, #socket_options{packet=Packet}) ->
+ case Packet of
+ 1 -> encode_size_packet(Data, 8, (1 bsl 8) - 1);
+ 2 -> encode_size_packet(Data, 16, (1 bsl 16) - 1);
+ 4 -> encode_size_packet(Data, 32, (1 bsl 32) - 1);
+ _ -> Data
+ end.
+
+encode_size_packet(Bin, Size, Max) ->
+ Len = byte_size(Bin),
+ case Len > Max of
+ true -> throw({error, {badarg, {packet_to_large, Len, Max}}});
+ false -> <<Len:Size, Bin/binary>>
+ end.
+
+encode_data(Data, Version, ConnectionStates, RenegotiateAt) ->
+ ssl_record:encode_data(Data, Version, ConnectionStates, RenegotiateAt).
decode_alerts(Bin) ->
decode_alerts(Bin, []).
@@ -1417,6 +1619,20 @@ decode_alerts(<<?BYTE(Level), ?BYTE(Description), Rest/binary>>, Acc) ->
decode_alerts(<<>>, Acc) ->
lists:reverse(Acc, []).
+passive_receive(State0 = #state{user_data_buffer = Buffer}, StateName) ->
+ case Buffer of
+ <<>> ->
+ State = next_record(State0),
+ {next_state, StateName, State};
+ _ ->
+ case application_data(<<>>, State0) of
+ Stop = {stop, _, _} ->
+ Stop;
+ State ->
+ {next_state, StateName, State}
+ end
+ end.
+
application_data(Data, #state{user_application = {_Mon, Pid},
socket_options = SOpts,
bytes_to_read = BytesToRead,
@@ -1467,19 +1683,49 @@ get_data(#socket_options{active=Active, packet=Raw}, BytesToRead, Buffer)
end;
get_data(#socket_options{packet=Type, packet_size=Size}, _, Buffer) ->
PacketOpts = [{packet_size, Size}],
- case erlang:decode_packet(Type, Buffer, PacketOpts) of
+ case decode_packet(Type, Buffer, PacketOpts) of
{more, _} ->
{ok, <<>>, Buffer};
Decoded ->
Decoded
end.
-deliver_app_data(SO = #socket_options{active=once}, Data, Pid, From) ->
- send_or_reply(once, Pid, From, format_reply(SO, Data)),
- SO#socket_options{active=false};
-deliver_app_data(SO= #socket_options{active=Active}, Data, Pid, From) ->
- send_or_reply(Active, Pid, From, format_reply(SO, Data)),
- SO.
+decode_packet({http, headers}, Buffer, PacketOpts) ->
+ decode_packet(httph, Buffer, PacketOpts);
+decode_packet({http_bin, headers}, Buffer, PacketOpts) ->
+ decode_packet(httph_bin, Buffer, PacketOpts);
+decode_packet(Type, Buffer, PacketOpts) ->
+ erlang:decode_packet(Type, Buffer, PacketOpts).
+
+%% Just like with gen_tcp sockets, an ssl socket that has been configured with
+%% {packet, http} (or {packet, http_bin}) will automatically switch to expect
+%% HTTP headers after it sees a HTTP Request or HTTP Response line. We
+%% represent the current state as follows:
+%% #socket_options.packet =:= http: Expect a HTTP Request/Response line
+%% #socket_options.packet =:= {http, headers}: Expect HTTP Headers
+%% Note that if the user has explicitly configured the socket to expect
+%% HTTP headers using the {packet, httph} option, we don't do any automatic
+%% switching of states.
+deliver_app_data(SOpts = #socket_options{active=Active, packet=Type},
+ Data, Pid, From) ->
+ send_or_reply(Active, Pid, From, format_reply(SOpts, Data)),
+ SO = case Data of
+ {P, _, _, _} when ((P =:= http_request) or (P =:= http_response)),
+ ((Type =:= http) or (Type =:= http_bin)) ->
+ SOpts#socket_options{packet={Type, headers}};
+ http_eoh when tuple_size(Type) =:= 2 ->
+ % End of headers - expect another Request/Response line
+ {Type1, headers} = Type,
+ SOpts#socket_options{packet=Type1};
+ _ ->
+ SOpts
+ end,
+ case Active of
+ once ->
+ SO#socket_options{active=false};
+ _ ->
+ SO
+ end.
format_reply(#socket_options{active=false, mode=Mode, header=Header}, Data) ->
{ok, format_reply(Mode, Header, Data)};
@@ -1520,34 +1766,6 @@ opposite_role(server) ->
send_user(Pid, Msg) ->
Pid ! Msg.
-%% %% This is the code for {packet,ssl} removed because it was slower
-%% %% than handling it in erlang.
-%% next_record(#state{socket = Socket,
-%% tls_buffer = [Msg|Rest],
-%% connection_states = ConnectionStates0} = State) ->
-%% Buffer =
-%% case Rest of
-%% [] ->
-%% inet:setopts(Socket, [{active,once}]),
-%% buffer;
-%% _ -> Rest
-%% end,
-%% case Msg of
-%% #ssl_tls{} ->
-%% {Plain, ConnectionStates} =
-%% ssl_record:decode_cipher_text(Msg, ConnectionStates0),
-%% gen_fsm:send_all_state_event(self(), Plain),
-%% State#state{tls_buffer=Buffer, connection_states = ConnectionStates};
-%% {ssl_close, Msg} ->
-%% self() ! Msg,
-%% State#state{tls_buffer=Buffer}
-%% end;
-%% next_record(#state{socket = Socket, tls_buffer = undefined} = State) ->
-%% inet:setopts(Socket, [{active,once}]),
-%% State#state{tls_buffer=continue};
-%% next_record(State) ->
-%% State#state{tls_buffer=continue}.
-
next_record(#state{tls_cipher_texts = [], socket = Socket} = State) ->
inet:setopts(Socket, [{active,once}]),
State;
@@ -1557,13 +1775,57 @@ next_record(#state{tls_cipher_texts = [CT | Rest],
gen_fsm:send_all_state_event(self(), Plain),
State#state{tls_cipher_texts = Rest, connection_states = ConnStates}.
+
next_record_if_active(State =
#state{socket_options =
#socket_options{active = false}}) ->
State;
+
next_record_if_active(State) ->
next_record(State).
+next_state_connection(#state{send_queue = Queue0,
+ negotiated_version = Version,
+ socket = Socket,
+ transport_cb = Transport,
+ connection_states = ConnectionStates0,
+ ssl_options = #ssl_options{renegotiate_at = RenegotiateAt}
+ } = State) ->
+ %% Send queued up data
+ case queue:out(Queue0) of
+ {{value, {From, Data}}, Queue} ->
+ case encode_data(Data, Version, ConnectionStates0, RenegotiateAt) of
+ {Msgs, [], ConnectionStates} ->
+ Result = Transport:send(Socket, Msgs),
+ gen_fsm:reply(From, Result),
+ next_state_connection(State#state{connection_states = ConnectionStates,
+ send_queue = Queue});
+ %% This is unlikely to happen. User configuration of the
+ %% undocumented test option renegotiation_at can make it more likely.
+ {Msgs, RestData, ConnectionStates} ->
+ if
+ Msgs =/= [] ->
+ Transport:send(Socket, Msgs);
+ true ->
+ ok
+ end,
+ renegotiate(State#state{connection_states = ConnectionStates,
+ send_queue = queue:in_r({From, RestData}, Queue),
+ renegotiation = {true, internal}})
+ end;
+ {empty, Queue0} ->
+ next_state_is_connection(State)
+ end.
+
+next_state_is_connection(State =
+ #state{recv_during_renegotiation = true, socket_options =
+ #socket_options{active = false}}) ->
+ passive_receive(State#state{recv_during_renegotiation = false}, connection);
+
+next_state_is_connection(State) ->
+ {next_state, connection, next_record_if_active(State)}.
+
+
register_session(_, _, _, #session{is_resumable = true} = Session) ->
Session; %% Already registered
register_session(client, Host, Port, Session0) ->
@@ -1613,7 +1875,10 @@ initial_state(Role, Host, Port, Socket, {SSLOptions, SocketOptions}, User,
bytes_to_read = 0,
user_data_buffer = <<>>,
log_alert = true,
- session_cache_cb = SessionCacheCb
+ session_cache_cb = SessionCacheCb,
+ renegotiation = {false, first},
+ recv_during_renegotiation = false,
+ send_queue = queue:new()
}.
sslsocket(Pid) ->
@@ -1628,8 +1893,12 @@ get_socket_opts(Socket, [mode | Tags], SockOpts, Acc) ->
get_socket_opts(Socket, Tags, SockOpts,
[{mode, SockOpts#socket_options.mode} | Acc]);
get_socket_opts(Socket, [packet | Tags], SockOpts, Acc) ->
- get_socket_opts(Socket, Tags, SockOpts,
- [{packet, SockOpts#socket_options.packet} | Acc]);
+ case SockOpts#socket_options.packet of
+ {Type, headers} ->
+ get_socket_opts(Socket, Tags, SockOpts, [{packet, Type} | Acc]);
+ Type ->
+ get_socket_opts(Socket, Tags, SockOpts, [{packet, Type} | Acc])
+ end;
get_socket_opts(Socket, [header | Tags], SockOpts, Acc) ->
get_socket_opts(Socket, Tags, SockOpts,
[{header, SockOpts#socket_options.header} | Acc]);
@@ -1651,7 +1920,8 @@ set_socket_opts(Socket, [], SockOpts, Other) ->
inet:setopts(Socket, Other),
SockOpts;
set_socket_opts(Socket, [{mode, Mode}| Opts], SockOpts, Other) ->
- set_socket_opts(Socket, Opts, SockOpts#socket_options{mode = Mode}, Other);
+ set_socket_opts(Socket, Opts,
+ SockOpts#socket_options{mode = Mode}, Other);
set_socket_opts(Socket, [{packet, Packet}| Opts], SockOpts, Other) ->
set_socket_opts(Socket, Opts,
SockOpts#socket_options{packet = Packet}, Other);
@@ -1693,12 +1963,68 @@ handle_own_alert(Alert, Version, StateName,
role = Role,
connection_states = ConnectionStates,
log_alert = Log}) ->
- {BinMsg, _} =
- encode_alert(Alert, Version, ConnectionStates),
- Transport:send(Socket, BinMsg),
- log_alert(Log, StateName, Alert),
- alert_user(User, Alert, Role).
-
-make_premaster_secret({MajVer, MinVer}) ->
+ try %% Try to tell the other side
+ {BinMsg, _} =
+ encode_alert(Alert, Version, ConnectionStates),
+ Transport:send(Socket, BinMsg)
+ catch _:_ -> %% Can crash if we are in a uninitialized state
+ ignore
+ end,
+ try %% Try to tell the local user
+ log_alert(Log, StateName, Alert),
+ alert_user(User, Alert, Role)
+ catch _:_ ->
+ ok
+ end.
+make_premaster_secret({MajVer, MinVer}, Alg) when Alg == rsa;
+ Alg == dh_dss;
+ Alg == dh_rsa ->
Rand = crypto:rand_bytes(?NUM_OF_PREMASTERSECRET_BYTES-2),
- <<?BYTE(MajVer), ?BYTE(MinVer), Rand/binary>>.
+ <<?BYTE(MajVer), ?BYTE(MinVer), Rand/binary>>;
+make_premaster_secret(_, _) ->
+ undefined.
+
+mpint_binary(Binary) ->
+ Size = byte_size(Binary),
+ <<?UINT32(Size), Binary/binary>>.
+
+
+ack_connection(#state{renegotiation = {true, Initiater}} = State)
+ when Initiater == internal;
+ Initiater == peer ->
+ State#state{renegotiation = undefined};
+ack_connection(#state{renegotiation = {true, From}} = State) ->
+ gen_fsm:reply(From, ok),
+ State#state{renegotiation = undefined};
+ack_connection(#state{renegotiation = {false, first}, from = From} = State) ->
+ gen_fsm:reply(From, connected),
+ State#state{renegotiation = undefined}.
+
+renegotiate(#state{role = client} = State) ->
+ %% Handle same way as if server requested
+ %% the renegotiation
+ Hs0 = ssl_handshake:init_hashes(),
+ connection(#hello_request{}, State#state{tls_handshake_hashes = Hs0});
+renegotiate(#state{role = server,
+ socket = Socket,
+ transport_cb = Transport,
+ negotiated_version = Version,
+ connection_states = ConnectionStates0} = State) ->
+ HelloRequest = ssl_handshake:hello_request(),
+ Frag = ssl_handshake:encode_handshake(HelloRequest, Version, undefined),
+ Hs0 = ssl_handshake:init_hashes(),
+ {BinMsg, ConnectionStates} =
+ ssl_record:encode_handshake(Frag, Version, ConnectionStates0),
+ Transport:send(Socket, BinMsg),
+ {next_state, hello, next_record(State#state{connection_states =
+ ConnectionStates,
+ tls_handshake_hashes = Hs0})}.
+notify_senders(SendQueue) ->
+ lists:foreach(fun({From, _}) ->
+ gen_fsm:reply(From, {error, closed})
+ end, queue:to_list(SendQueue)).
+
+notify_renegotiater({true, From}) when not is_atom(From) ->
+ gen_fsm:reply(From, {error, closed});
+notify_renegotiater(_) ->
+ ok.
diff --git a/lib/ssl/src/ssl_handshake.erl b/lib/ssl/src/ssl_handshake.erl
index 829e0c2ba6..9f5ac7106a 100644
--- a/lib/ssl/src/ssl_handshake.erl
+++ b/lib/ssl/src/ssl_handshake.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2007-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 2007-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%
%%
@@ -31,11 +31,11 @@
-include("ssl_debug.hrl").
-include_lib("public_key/include/public_key.hrl").
--export([master_secret/4, client_hello/4, server_hello/3, hello/2,
- certify/5, certificate/3,
+-export([master_secret/4, client_hello/4, server_hello/3, hello/2,
+ hello_request/0, certify/7, certificate/3,
client_certificate_verify/6,
certificate_verify/6, certificate_request/2,
- key_exchange/2, finished/4,
+ key_exchange/2, server_key_exchange_hash/2, finished/4,
verify_connection/5,
get_tls_handshake/4,
server_hello_done/0, sig_alg/1,
@@ -97,6 +97,15 @@ server_hello(SessionId, Version, ConnectionStates) ->
}.
%%--------------------------------------------------------------------
+%% Function: hello_request() -> #hello_request{}
+%%
+%% Description: Creates a hello request message sent by server to
+%% trigger renegotiation.
+%%--------------------------------------------------------------------
+hello_request() ->
+ #hello_request{}.
+
+%%--------------------------------------------------------------------
%% Function: hello(Hello, Info) ->
%% {Version, Id, NewConnectionStates} |
%% #alert{}
@@ -152,10 +161,25 @@ hello(#client_hello{client_version = ClientVersion, random = Random} = Hello,
%% Description: Handles a certificate handshake message
%%--------------------------------------------------------------------
certify(#certificate{asn1_certificates = ASN1Certs}, CertDbRef,
- MaxPathLen, Verify, VerifyFun) ->
+ MaxPathLen, Verify, VerifyFun, ValidateFun, Role) ->
[PeerCert | _] = ASN1Certs,
VerifyBool = verify_bool(Verify),
-
+
+ ValidateExtensionFun =
+ case ValidateFun of
+ undefined ->
+ fun(Extensions, ValidationState, Verify0, AccError) ->
+ ssl_certificate:validate_extensions(Extensions, ValidationState,
+ [], Verify0, AccError, Role)
+ end;
+ Fun ->
+ fun(Extensions, ValidationState, Verify0, AccError) ->
+ {NewExtensions, NewValidationState, NewAccError}
+ = ssl_certificate:validate_extensions(Extensions, ValidationState,
+ [], Verify0, AccError, Role),
+ Fun(NewExtensions, NewValidationState, Verify0, NewAccError)
+ end
+ end,
try
%% Allow missing root_cert and check that with VerifyFun
ssl_certificate:trusted_cert_and_path(ASN1Certs, CertDbRef, false) of
@@ -165,6 +189,8 @@ certify(#certificate{asn1_certificates = ASN1Certs}, CertDbRef,
[{max_path_length,
MaxPathLen},
{verify, VerifyBool},
+ {validate_extensions_fun,
+ ValidateExtensionFun},
{acc_errors,
VerifyErrors}]),
case Result of
@@ -248,8 +274,10 @@ client_certificate_verify(OwnCert, MasterSecret, Version, Algorithm,
%% Description: Checks that the certificate_verify message is valid.
%%--------------------------------------------------------------------
certificate_verify(Signature, {_, PublicKey, _}, Version,
- MasterSecret, Algorithm, {_, Hashes0})
- when Algorithm =:= rsa; Algorithm =:= dh_rsa; Algorithm =:= dhe_rsa ->
+ MasterSecret, Algorithm, {_, Hashes0})
+ when Algorithm == rsa;
+ Algorithm == dh_rsa;
+ Algorithm == dhe_rsa ->
Hashes = calc_certificate_verify(Version, MasterSecret,
Algorithm, Hashes0),
case public_key:decrypt_public(Signature, PublicKey,
@@ -296,30 +324,32 @@ key_exchange(client, fixed_diffie_hellman) ->
#client_diffie_hellman_public{
dh_public = <<>>
}};
-key_exchange(client, {dh, PublicKey}) ->
- Len = byte_size(PublicKey),
+key_exchange(client, {dh, <<?UINT32(Len), PublicKey:Len/binary>>}) ->
#client_key_exchange{
- exchange_keys = #client_diffie_hellman_public{
- dh_public = <<?UINT16(Len), PublicKey/binary>>}
+ exchange_keys = #client_diffie_hellman_public{
+ dh_public = PublicKey}
};
-%% key_exchange(server, {{?'dhpublicnumber', _PublicKey,
-%% #'DomainParameters'{p = P, g = G, y = Y},
-%% SignAlgorithm, ClientRandom, ServerRandom}}) ->
-%% ServerDHParams = #server_dh_params{dh_p = P, dh_g = G, dh_y = Y},
-%% PLen = byte_size(P),
-%% GLen = byte_size(G),
-%% YLen = byte_size(Y),
-%% Hash = server_key_exchange_hash(SignAlgorithm, <<ClientRandom/binary,
-%% ServerRandom/binary,
-%% ?UINT16(PLen), P/binary,
-%% ?UINT16(GLen), G/binary,
-%% ?UINT16(YLen), Y/binary>>),
-%% Signed = digitally_signed(Hash, PrivateKey),
-%% #server_key_exchange{
-%% params = ServerDHParams,
-%% signed_params = Signed
-%% };
+key_exchange(server, {dh, {<<?UINT32(_), PublicKey/binary>>, _},
+ #'DHParameter'{prime = P, base = G},
+ KeyAlgo, ClientRandom, ServerRandom, PrivateKey}) ->
+ <<?UINT32(_), PBin/binary>> = crypto:mpint(P),
+ <<?UINT32(_), GBin/binary>> = crypto:mpint(G),
+ PLen = byte_size(PBin),
+ GLen = byte_size(GBin),
+ YLen = byte_size(PublicKey),
+ ServerDHParams = #server_dh_params{dh_p = PBin,
+ dh_g = GBin, dh_y = PublicKey},
+
+ Hash =
+ server_key_exchange_hash(KeyAlgo, <<ClientRandom/binary,
+ ServerRandom/binary,
+ ?UINT16(PLen), PBin/binary,
+ ?UINT16(GLen), GBin/binary,
+ ?UINT16(YLen), PublicKey/binary>>),
+ Signed = digitally_signed(Hash, PrivateKey),
+ #server_key_exchange{params = ServerDHParams,
+ signed_params = Signed};
key_exchange(_, _) ->
%%TODO : Real imp
#server_key_exchange{}.
@@ -417,7 +447,8 @@ server_hello_done() ->
%%
%% encode a handshake packet to binary
%%--------------------------------------------------------------------
-encode_handshake(Package, Version, SigAlg) ->
+encode_handshake(Package, Version, KeyAlg) ->
+ SigAlg = sig_alg(KeyAlg),
{MsgType, Bin} = enc_hs(Package, Version, SigAlg),
Len = byte_size(Bin),
[MsgType, ?uint24(Len), Bin].
@@ -437,32 +468,16 @@ get_tls_handshake(Data, Buffer, KeyAlg, Version) ->
get_tls_handshake_aux(list_to_binary([Buffer, Data]),
KeyAlg, Version, []).
-get_tls_handshake_aux(<<?BYTE(Type), ?UINT24(Length), Body:Length/binary,Rest/binary>>,
- KeyAlg, Version, Acc) ->
+get_tls_handshake_aux(<<?BYTE(Type), ?UINT24(Length),
+ Body:Length/binary,Rest/binary>>, KeyAlg,
+ Version, Acc) ->
Raw = <<?BYTE(Type), ?UINT24(Length), Body/binary>>,
- H = dec_hs(Type, Body, KeyAlg, Version),
+ H = dec_hs(Type, Body, key_exchange_alg(KeyAlg), Version),
get_tls_handshake_aux(Rest, KeyAlg, Version, [{H,Raw} | Acc]);
get_tls_handshake_aux(Data, _KeyAlg, _Version, Acc) ->
{lists:reverse(Acc), Data}.
%%--------------------------------------------------------------------
-%% Function: sig_alg(atom()) -> integer()
-%%
-%% Description: Convert from key exchange as atom to signature
-%% algorithm as a ?SIGNATURE_... constant
-%%--------------------------------------------------------------------
-
-sig_alg(dh_anon) ->
- ?SIGNATURE_ANONYMOUS;
-sig_alg(Alg) when Alg == dhe_rsa; Alg == rsa; Alg == dh_rsa ->
- ?SIGNATURE_RSA;
-sig_alg(Alg) when Alg == dh_dss; Alg == dhe_dss ->
- ?SIGNATURE_DSA;
-sig_alg(_) ->
- ?NULL.
-
-
-%%--------------------------------------------------------------------
%%% Internal functions
%%--------------------------------------------------------------------
verify_bool(verify_peer) ->
@@ -649,8 +664,8 @@ dec_hs(?SERVER_HELLO, <<?BYTE(Major), ?BYTE(Minor), Random:32/binary,
dec_hs(?CERTIFICATE, <<?UINT24(ACLen), ASN1Certs:ACLen/binary>>, _, _) ->
#certificate{asn1_certificates = certs_to_list(ASN1Certs)};
dec_hs(?SERVER_KEY_EXCHANGE, <<?UINT16(ModLen), Mod:ModLen/binary,
- ?UINT16(ExpLen), Exp:ExpLen/binary,
- Sig/binary>>,
+ ?UINT16(ExpLen), Exp:ExpLen/binary,
+ ?UINT16(_), Sig/binary>>,
?KEY_EXCHANGE_RSA, _) ->
#server_key_exchange{params = #server_rsa_params{rsa_modulus = Mod,
rsa_exponent = Exp},
@@ -658,9 +673,10 @@ dec_hs(?SERVER_KEY_EXCHANGE, <<?UINT16(ModLen), Mod:ModLen/binary,
dec_hs(?SERVER_KEY_EXCHANGE, <<?UINT16(PLen), P:PLen/binary,
?UINT16(GLen), G:GLen/binary,
?UINT16(YLen), Y:YLen/binary,
- Sig/binary>>,
+ ?UINT16(_), Sig/binary>>,
?KEY_EXCHANGE_DIFFIE_HELLMAN, _) ->
- #server_key_exchange{params = #server_dh_params{dh_p = P,dh_g = G, dh_y = Y},
+ #server_key_exchange{params = #server_dh_params{dh_p = P,dh_g = G,
+ dh_y = Y},
signed_params = Sig};
dec_hs(?CERTIFICATE_REQUEST,
<<?BYTE(CertTypesLen), CertTypes:CertTypesLen/binary,
@@ -672,18 +688,20 @@ dec_hs(?SERVER_HELLO_DONE, <<>>, _, _) ->
#server_hello_done{};
dec_hs(?CERTIFICATE_VERIFY,<<?UINT16(_), Signature/binary>>, _, _)->
#certificate_verify{signature = Signature};
-dec_hs(?CLIENT_KEY_EXCHANGE, PKEPMS, rsa, {3, 0}) ->
+dec_hs(?CLIENT_KEY_EXCHANGE, PKEPMS, ?KEY_EXCHANGE_RSA, {3, 0}) ->
PreSecret = #encrypted_premaster_secret{premaster_secret = PKEPMS},
#client_key_exchange{exchange_keys = PreSecret};
-dec_hs(?CLIENT_KEY_EXCHANGE, <<?UINT16(_), PKEPMS/binary>>, rsa, _) ->
+dec_hs(?CLIENT_KEY_EXCHANGE, <<?UINT16(_), PKEPMS/binary>>,
+ ?KEY_EXCHANGE_RSA, _) ->
PreSecret = #encrypted_premaster_secret{premaster_secret = PKEPMS},
#client_key_exchange{exchange_keys = PreSecret};
dec_hs(?CLIENT_KEY_EXCHANGE, <<>>, ?KEY_EXCHANGE_DIFFIE_HELLMAN, _) ->
%% TODO: Should check whether the cert already contains a suitable DH-key (7.4.7.2)
throw(?ALERT_REC(?FATAL, implicit_public_value_encoding));
-dec_hs(?CLIENT_KEY_EXCHANGE, <<?UINT16(DH_YCLen), DH_YC:DH_YCLen/binary>>,
+dec_hs(?CLIENT_KEY_EXCHANGE, <<?UINT16(DH_YLen), DH_Y:DH_YLen/binary>>,
?KEY_EXCHANGE_DIFFIE_HELLMAN, _) ->
- #client_diffie_hellman_public{dh_public = DH_YC};
+ #client_key_exchange{exchange_keys =
+ #client_diffie_hellman_public{dh_public = DH_Y}};
dec_hs(?FINISHED, VerifyData, _, _) ->
#finished{verify_data = VerifyData};
dec_hs(_, _, _, _) ->
@@ -756,12 +774,13 @@ enc_hs(#certificate{asn1_certificates = ASN1CertList}, _Version, _) ->
{?CERTIFICATE, <<?UINT24(ACLen), ASN1Certs:ACLen/binary>>};
enc_hs(#server_key_exchange{params = #server_rsa_params{rsa_modulus = Mod,
rsa_exponent = Exp},
- signed_params = SignedParams}, _Version, _) ->
+ signed_params = SignedParams}, _Version, _) ->
ModLen = byte_size(Mod),
ExpLen = byte_size(Exp),
- {?SERVER_KEY_EXCHANGE, <<?UINT16(ModLen), Mod/binary,
+ SignedLen = byte_size(SignedParams),
+ {?SERVER_KEY_EXCHANGE, <<?UINT16(ModLen),Mod/binary,
?UINT16(ExpLen), Exp/binary,
- SignedParams/binary>>
+ ?UINT16(SignedLen), SignedParams/binary>>
};
enc_hs(#server_key_exchange{params = #server_dh_params{
dh_p = P, dh_g = G, dh_y = Y},
@@ -769,10 +788,11 @@ enc_hs(#server_key_exchange{params = #server_dh_params{
PLen = byte_size(P),
GLen = byte_size(G),
YLen = byte_size(Y),
- {?SERVER_KEY_EXCHANGE, <<?UINT16(PLen), P:PLen/binary,
- ?UINT16(GLen), G:GLen/binary,
- ?UINT16(YLen), Y:YLen/binary,
- SignedParams/binary>>
+ SignedLen = byte_size(SignedParams),
+ {?SERVER_KEY_EXCHANGE, <<?UINT16(PLen), P/binary,
+ ?UINT16(GLen), G/binary,
+ ?UINT16(YLen), Y/binary,
+ ?UINT16(SignedLen), SignedParams/binary>>
};
enc_hs(#certificate_request{certificate_types = CertTypes,
certificate_authorities = CertAuths},
@@ -860,9 +880,31 @@ certificate_types(_) ->
%% a RSA_FIXED_DH or DSS_FIXED_DH
<<?BYTE(?RSA_SIGN)>>.
-certificate_authorities(_) ->
- %%TODO Make list of know CA:s
- <<>>.
+certificate_authorities(CertDbRef) ->
+ Authorities = certificate_authorities_from_db(CertDbRef),
+ Enc = fun(#'OTPCertificate'{tbsCertificate=TBSCert}) ->
+ OTPSubj = TBSCert#'OTPTBSCertificate'.subject,
+ Subj = public_key:pkix_transform(OTPSubj, encode),
+ {ok, DNEncoded} = 'OTP-PUB-KEY':encode('Name', Subj),
+ DNEncodedBin = iolist_to_binary(DNEncoded),
+ DNEncodedLen = byte_size(DNEncodedBin),
+ <<?UINT16(DNEncodedLen), DNEncodedBin/binary>>
+ end,
+ list_to_binary([Enc(Cert) || {_, Cert} <- Authorities]).
+
+certificate_authorities_from_db(CertDbRef) ->
+ certificate_authorities_from_db(CertDbRef, no_candidate, []).
+
+certificate_authorities_from_db(CertDbRef, PrevKey, Acc) ->
+ case ssl_certificate_db:issuer_candidate(PrevKey) of
+ no_more_candidates ->
+ lists:reverse(Acc);
+ {{CertDbRef, _, _} = Key, Cert} ->
+ certificate_authorities_from_db(CertDbRef, Key, [Cert|Acc]);
+ {Key, _Cert} ->
+ %% skip certs not from this ssl connection
+ certificate_authorities_from_db(CertDbRef, Key, Acc)
+ end.
digitally_signed(Hashes, #'RSAPrivateKey'{} = Key) ->
public_key:encrypt_private(Hashes, Key,
@@ -905,13 +947,40 @@ calc_certificate_verify({3, N}, _, Algorithm, Hashes)
when N == 1; N == 2 ->
ssl_tls1:certificate_verify(Algorithm, Hashes).
-%% server_key_exchange_hash(Algorithm, Value) when Algorithm == rsa;
-%% Algorithm == dh_rsa;
-%% Algorithm == dhe_rsa ->
-%% MD5 = crypto:md5_final(Value),
-%% SHA = crypto:sha_final(Value),
-%% <<MD5/binary, SHA/binary>>;
+server_key_exchange_hash(Algorithm, Value) when Algorithm == rsa;
+ Algorithm == dh_rsa;
+ Algorithm == dhe_rsa ->
+ MD5Context = crypto:md5_init(),
+ NewMD5Context = crypto:md5_update(MD5Context, Value),
+ MD5 = crypto:md5_final(NewMD5Context),
+
+ SHAContext = crypto:sha_init(),
+ NewSHAContext = crypto:sha_update(SHAContext, Value),
+ SHA = crypto:sha_final(NewSHAContext),
+
+ <<MD5/binary, SHA/binary>>;
+
+server_key_exchange_hash(Algorithm, Value) when Algorithm == dh_dss;
+ Algorithm == dhe_dss ->
-%% server_key_exchange_hash(Algorithm, Value) when Algorithm == dh_dss;
-%% Algorithm == dhe_dss ->
-%% crypto:sha_final(Value).
+ SHAContext = crypto:sha_init(),
+ NewSHAContext = crypto:sha_update(SHAContext, Value),
+ crypto:sha_final(NewSHAContext).
+
+
+sig_alg(dh_anon) ->
+ ?SIGNATURE_ANONYMOUS;
+sig_alg(Alg) when Alg == dhe_rsa; Alg == rsa; Alg == dh_rsa ->
+ ?SIGNATURE_RSA;
+sig_alg(Alg) when Alg == dh_dss; Alg == dhe_dss ->
+ ?SIGNATURE_DSA;
+sig_alg(_) ->
+ ?NULL.
+
+key_exchange_alg(rsa) ->
+ ?KEY_EXCHANGE_RSA;
+key_exchange_alg(Alg) when Alg == dhe_rsa; Alg == dhe_dss;
+ Alg == dh_dss; Alg == dh_rsa; Alg == dh_anon ->
+ ?KEY_EXCHANGE_DIFFIE_HELLMAN;
+key_exchange_alg(_) ->
+ ?NULL.
diff --git a/lib/ssl/src/ssl_handshake.hrl b/lib/ssl/src/ssl_handshake.hrl
index b2bdfa0934..889d39f2af 100644
--- a/lib/ssl/src/ssl_handshake.hrl
+++ b/lib/ssl/src/ssl_handshake.hrl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2007-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 2007-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%
%%
@@ -38,7 +38,8 @@
-define(NUM_OF_SESSION_ID_BYTES, 32). % TSL 1.1 & SSL 3
-define(NUM_OF_PREMASTERSECRET_BYTES, 48).
-
+-define(DEFAULT_DIFFIE_HELLMAN_GENERATOR, 2).
+-define(DEFAULT_DIFFIE_HELLMAN_PRIME, 16#FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD129024E088A67CC74020BBEA63B139B22514A08798E3404DDEF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7EDEE386BFB5A899FA5AE9F24117C4B1FE649286651ECE65381FFFFFFFFFFFFFFFF).
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%% Handsake protocol - RFC 4346 section 7.4
diff --git a/lib/ssl/src/ssl_internal.hrl b/lib/ssl/src/ssl_internal.hrl
index 23a5c93452..8d19abfe1e 100644
--- a/lib/ssl/src/ssl_internal.hrl
+++ b/lib/ssl/src/ssl_internal.hrl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2007-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 2007-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%
%%
@@ -57,12 +57,15 @@
verify_fun, % fun(CertVerifyErrors) -> boolean()
fail_if_no_peer_cert, % boolean()
verify_client_once, % boolean()
+ %% fun(Extensions, State, Verify, AccError) -> {Extensions, State, AccError}
+ validate_extensions_fun,
depth, % integer()
certfile, % file()
keyfile, % file()
key, %
password, %
cacertfile, % file()
+ dhfile, % file()
ciphers, %
%% Local policy for the server if it want's to reuse the session
%% or not. Defaluts to allways returning true.
@@ -71,6 +74,7 @@
%% If false sessions will never be reused, if true they
%% will be reused if possible.
reuse_sessions, % boolean()
+ renegotiate_at,
debug %
}).
diff --git a/lib/ssl/src/ssl_manager.erl b/lib/ssl/src/ssl_manager.erl
index 6b83c2ea46..0151426d43 100644
--- a/lib/ssl/src/ssl_manager.erl
+++ b/lib/ssl/src/ssl_manager.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2007-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 2007-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%
%%
@@ -74,13 +74,11 @@ connection_init(TrustedcertsFile, Role) ->
call({connection_init, TrustedcertsFile, Role}).
cache_pem_file(File) ->
- case ets:lookup(ssl_file_to_ref,File) of
- [{_,_,Content}] ->
+ case ssl_certificate_db:lookup_cached_certs(File) of
+ [{_,Content}] ->
{ok, Content};
[] ->
- {ok, Db} = call({cache_pem, File}),
- [{_,_,Content}] = ets:lookup(Db,File),
- {ok, Content}
+ call({cache_pem, File})
end.
%%--------------------------------------------------------------------
@@ -170,13 +168,14 @@ handle_call({{connection_init, TrustedcertsFile, _Role}, Pid}, _From,
session_cache = Cache} = State) ->
erlang:monitor(process, Pid),
Result =
- case (catch ssl_certificate_db:add_trusted_certs(Pid,
- TrustedcertsFile,
- Db)) of
- {ok, Ref} ->
- {ok, Ref, Cache};
- Error ->
- {error, Error}
+ try
+ {ok, Ref} = ssl_certificate_db:add_trusted_certs(Pid, TrustedcertsFile, Db),
+ {ok, Ref, Cache}
+ catch
+ _:{badmatch, Error} ->
+ {error, Error};
+ _E:_R ->
+ {error, {_R,erlang:get_stacktrace()}}
end,
{reply, Result, State};
@@ -198,7 +197,9 @@ handle_call({{cache_pem, File},Pid}, _, State = #state{certificate_db = Db}) ->
try ssl_certificate_db:cache_pem_file(Pid,File,Db) of
Result ->
{reply, Result, State}
- catch _:Reason ->
+ catch _:{badmatch, Reason} ->
+ {reply, Reason, State};
+ _:Reason ->
{reply, {error, Reason}, State}
end;
diff --git a/lib/ssl/src/ssl_record.erl b/lib/ssl/src/ssl_record.erl
index 37a3d1b639..da48f049f6 100644
--- a/lib/ssl/src/ssl_record.erl
+++ b/lib/ssl/src/ssl_record.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2007-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 2007-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%
%%
@@ -45,7 +45,7 @@
%% Encoding records
-export([encode_handshake/3, encode_alert_record/3,
- encode_change_cipher_spec/2, encode_data/3]).
+ encode_change_cipher_spec/2, encode_data/4]).
%% Decoding
-export([decode_cipher_text/2]).
@@ -474,19 +474,31 @@ split_bin(Bin, ChunkSize, Acc) ->
lists:reverse(Acc, [Bin])
end.
-encode_data(Frag, Version, ConnectionStates)
+encode_data(Frag, Version, ConnectionStates, RenegotiateAt)
when byte_size(Frag) < (?MAX_PLAIN_TEXT_LENGTH - 2048) ->
- encode_plain_text(?APPLICATION_DATA,Version,Frag,ConnectionStates);
-encode_data(Frag, Version, ConnectionStates) ->
+ case encode_plain_text(?APPLICATION_DATA,Version,Frag,ConnectionStates, RenegotiateAt) of
+ {renegotiate, Data} ->
+ {[], Data, ConnectionStates};
+ {Msg, CS} ->
+ {Msg, [], CS}
+ end;
+
+encode_data(Frag, Version, ConnectionStates, RenegotiateAt) when is_binary(Frag) ->
Data = split_bin(Frag, ?MAX_PLAIN_TEXT_LENGTH - 2048),
- {CS1, Acc} =
- lists:foldl(fun(B, {CS0, Acc}) ->
- {ET, CS1} =
- encode_plain_text(?APPLICATION_DATA,
- Version, B, CS0),
- {CS1, [ET | Acc]}
- end, {ConnectionStates, []}, Data),
- {lists:reverse(Acc), CS1}.
+ encode_data(Data, Version, ConnectionStates, RenegotiateAt);
+
+encode_data(Data, Version, ConnectionStates0, RenegotiateAt) when is_list(Data) ->
+ {ConnectionStates, EncodedMsg, NotEncdedData} =
+ lists:foldl(fun(B, {CS0, Encoded, Rest}) ->
+ case encode_plain_text(?APPLICATION_DATA,
+ Version, B, CS0, RenegotiateAt) of
+ {renegotiate, NotEnc} ->
+ {CS0, Encoded, [NotEnc | Rest]};
+ {Enc, CS1} ->
+ {CS1, [Enc | Encoded], Rest}
+ end
+ end, {ConnectionStates0, [], []}, Data),
+ {lists:reverse(EncodedMsg), lists:reverse(NotEncdedData), ConnectionStates}.
encode_handshake(Frag, Version, ConnectionStates) ->
encode_plain_text(?HANDSHAKE, Version, Frag, ConnectionStates).
@@ -499,6 +511,16 @@ encode_alert_record(#alert{level = Level, description = Description},
encode_change_cipher_spec(Version, ConnectionStates) ->
encode_plain_text(?CHANGE_CIPHER_SPEC, Version, <<1:8>>, ConnectionStates).
+encode_plain_text(Type, Version, Data, ConnectionStates, RenegotiateAt) ->
+ #connection_states{current_write =
+ #connection_state{sequence_number = Num}} = ConnectionStates,
+ case renegotiate(Num, RenegotiateAt) of
+ false ->
+ encode_plain_text(Type, Version, Data, ConnectionStates);
+ true ->
+ {renegotiate, Data}
+ end.
+
encode_plain_text(Type, Version, Data, ConnectionStates) ->
#connection_states{current_write=#connection_state{
compression_state=CompS0,
@@ -511,6 +533,11 @@ encode_plain_text(Type, Version, Data, ConnectionStates) ->
CTBin = encode_tls_cipher_text(Type, Version, CipherText),
{CTBin, ConnectionStates#connection_states{current_write = CS2}}.
+renegotiate(N, M) when N < M->
+ false;
+renegotiate(_,_) ->
+ true.
+
encode_tls_cipher_text(Type, {MajVer, MinVer}, Fragment) ->
Length = erlang:iolist_size(Fragment),
[<<?BYTE(Type), ?BYTE(MajVer), ?BYTE(MinVer), ?UINT16(Length)>>, Fragment].
@@ -529,9 +556,6 @@ cipher(Type, Version, Fragment, CS0) ->
CS2 = CS1#connection_state{cipher_state=CipherS1},
{Ciphered, CS2}.
-decipher(TLS=#ssl_tls{type = ?CHANGE_CIPHER_SPEC}, CS) ->
- %% These are never encrypted
- {TLS, CS};
decipher(TLS=#ssl_tls{type=Type, version=Version, fragment=Fragment}, CS0) ->
SP = CS0#connection_state.security_parameters,
BCA = SP#security_parameters.bulk_cipher_algorithm, % eller Cipher?
diff --git a/lib/ssl/src/ssl_record.hrl b/lib/ssl/src/ssl_record.hrl
index 7370e0f0b3..362b7039d4 100644
--- a/lib/ssl/src/ssl_record.hrl
+++ b/lib/ssl/src/ssl_record.hrl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2007-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 2007-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%
%%
@@ -63,6 +63,13 @@
sequence_number
}).
+-define(MAX_SEQENCE_NUMBER, 18446744073709552000). %% math:pow(2, 64) - 1 = 1.8446744073709552e19
+%% Sequence numbers can not wrap so when max is about to be reached we should renegotiate.
+%% We will renegotiate a little before so that there will be sequence numbers left
+%% for the rehandshake and a little data.
+-define(MARGIN, 100).
+-define(DEFAULT_RENEGOTIATE_AT, ?MAX_SEQENCE_NUMBER - ?MARGIN).
+
%% ConnectionEnd
-define(SERVER, 0).
-define(CLIENT, 1).
diff --git a/lib/ssl/src/ssl_ssl3.erl b/lib/ssl/src/ssl_ssl3.erl
index ab29ac64df..df809ce275 100644
--- a/lib/ssl/src/ssl_ssl3.erl
+++ b/lib/ssl/src/ssl_ssl3.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2007-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 2007-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%
%%
@@ -182,13 +182,13 @@ setup_keys(export, MasterSecret, ServerRandom, ClientRandom,
suites() ->
[
%% TODO: uncomment when supported
- %% ?TLS_DHE_RSA_WITH_AES_256_CBC_SHA,
+ ?TLS_DHE_RSA_WITH_AES_256_CBC_SHA,
%% ?TLS_DHE_DSS_WITH_AES_256_CBC_SHA,
- %% TODO: Funkar inte, borde: ?TLS_RSA_WITH_AES_256_CBC_SHA,
- %% ?TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA,
+ ?TLS_RSA_WITH_AES_256_CBC_SHA,
+ ?TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA,
%% ?TLS_DHE_DSS_WITH_3DES_EDE_CBC_SHA,
?TLS_RSA_WITH_3DES_EDE_CBC_SHA,
- %% ?TLS_DHE_RSA_WITH_AES_128_CBC_SHA,
+ ?TLS_DHE_RSA_WITH_AES_128_CBC_SHA,
%% ?TLS_DHE_DSS_WITH_AES_128_CBC_SHA,
?TLS_RSA_WITH_AES_128_CBC_SHA,
%%?TLS_DHE_DSS_WITH_RC4_128_SHA, TODO: Support this?
diff --git a/lib/ssl/src/ssl_tls1.erl b/lib/ssl/src/ssl_tls1.erl
index e0013c48ac..ce9a135168 100644
--- a/lib/ssl/src/ssl_tls1.erl
+++ b/lib/ssl/src/ssl_tls1.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2007-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 2007-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%
%%
@@ -136,13 +136,13 @@ mac_hash(Method, Mac_write_secret, Seq_num, Type, {Major, Minor},
suites() ->
[
%% TODO: uncomment when supported
- %% ?TLS_DHE_RSA_WITH_AES_256_CBC_SHA,
- %% ?TLS_DHE_DSS_WITH_AES_256_CBC_SHA,
- %% TODO: Funkar inte, borde: ?TLS_RSA_WITH_AES_256_CBC_SHA,
- %% ?TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA,
+ ?TLS_DHE_RSA_WITH_AES_256_CBC_SHA,
+ %%?TLS_DHE_DSS_WITH_AES_256_CBC_SHA,
+ ?TLS_RSA_WITH_AES_256_CBC_SHA,
+ ?TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA,
%% ?TLS_DHE_DSS_WITH_3DES_EDE_CBC_SHA,
?TLS_RSA_WITH_3DES_EDE_CBC_SHA,
- %% ?TLS_DHE_RSA_WITH_AES_128_CBC_SHA,
+ ?TLS_DHE_RSA_WITH_AES_128_CBC_SHA,
%% ?TLS_DHE_DSS_WITH_AES_128_CBC_SHA,
?TLS_RSA_WITH_AES_128_CBC_SHA,
%%?TLS_DHE_DSS_WITH_RC4_128_SHA, TODO: Support this?
diff --git a/lib/ssl/test/Makefile b/lib/ssl/test/Makefile
new file mode 100644
index 0000000000..bd86120c98
--- /dev/null
+++ b/lib/ssl/test/Makefile
@@ -0,0 +1,137 @@
+#
+# %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%
+#
+
+#
+
+# SSL test suite Makefile
+#
+include $(ERL_TOP)/make/target.mk
+include $(ERL_TOP)/make/$(TARGET)/otp.mk
+
+# ----------------------------------------------------
+# Application version
+# ----------------------------------------------------
+include ../vsn.mk
+VSN=$(GS_VSN)
+
+# ----------------------------------------------------
+# Target Specs
+# ----------------------------------------------------
+
+MODULES = \
+ ssl_test_lib \
+ ssl_basic_SUITE \
+ ssl_packet_SUITE \
+ ssl_payload_SUITE \
+ ssl_to_openssl_SUITE \
+ ssl_test_MACHINE \
+ old_ssl_active_SUITE \
+ old_ssl_active_once_SUITE \
+ old_ssl_passive_SUITE \
+ old_ssl_verify_SUITE \
+ old_ssl_peer_cert_SUITE \
+ old_ssl_misc_SUITE \
+ old_ssl_protocol_SUITE \
+ old_transport_accept_SUITE \
+ old_ssl_dist_SUITE \
+ make_certs
+
+
+ERL_FILES = $(MODULES:%=%.erl)
+
+HRL_FILES = ssl_test_MACHINE.hrl
+
+HRL_FILES_SRC = \
+ ssl_pkix.hrl \
+ ssl_alert.hrl \
+ ssl_handshake.hrl
+
+HRL_FILES_INC = \
+ OTP-PKIX.hrl
+
+HRL_FILES_NEEDED_IN_TEST = \
+ $(HRL_FILES_SRC:%=../src/%) \
+ $(HRL_FILES_INC:%=../include/%)
+
+TARGET_FILES = $(MODULES:%=$(EBIN)/%.$(EMULATOR))
+
+INCLUDES = -I. -I$(ERL_TOP)/lib/test_server/include/
+
+DATADIRS = ssl_basic_SUITE_data
+
+EMAKEFILE=Emakefile
+MAKE_EMAKE = $(wildcard $(ERL_TOP)/make/make_emakefile)
+
+COVER_FILE = ssl.cover
+
+# ----------------------------------------------------
+# Release directory specification
+# ----------------------------------------------------
+RELSYSDIR = $(RELEASE_PATH)/ssl_test
+
+# ----------------------------------------------------
+# FLAGS
+# The path to the test_server ebin dir is needed when
+# running the target "targets".
+# ----------------------------------------------------
+ERL_COMPILE_FLAGS += -pa ../../../internal_tools/test_server/ebin \
+ $(INCLUDES)
+
+# ----------------------------------------------------
+# Targets
+# ----------------------------------------------------
+
+tests debug opt: $(BUILDTARGET)
+
+targets: $(TARGET_FILES)
+
+.PHONY: emakebuild
+
+emakebuild: $(EMAKEFILE)
+
+$(EMAKEFILE):
+ $(MAKE_EMAKE) $(ERL_COMPILE_FLAGS) -o$(EBIN) '*_SUITE_make' | grep -v Warning > $(EMAKEFILE)
+ $(MAKE_EMAKE) $(ERL_COMPILE_FLAGS) -o$(EBIN) $(MODULES) | grep -v Warning >> $(EMAKEFILE)
+
+clean:
+ rm -f $(EMAKEFILE)
+ rm -f $(TARGET_FILES)
+ rm -f core *~
+
+docs:
+
+# ----------------------------------------------------
+# Release Target
+# ----------------------------------------------------
+include $(ERL_TOP)/make/otp_release_targets.mk
+
+release_spec: opt
+
+release_tests_spec: opt
+ $(INSTALL_DIR) $(RELSYSDIR)
+ $(INSTALL_DATA) $(ERL_FILES) $(HRL_FILES) $(HRL_FILES_NEEDED_IN_TEST) $(COVER_FILE) $(RELSYSDIR)
+ $(INSTALL_DATA) ssl.spec $(RELSYSDIR)
+ chmod -f -R u+w $(RELSYSDIR)
+ @tar cf - *_SUITE_data | (cd $(RELSYSDIR); tar xf -)
+
+release_docs_spec:
+
+# Dependencies
+
+$(TARGET_FILES): $(HRL_FILES)
diff --git a/lib/ssl/test/make_certs.erl b/lib/ssl/test/make_certs.erl
new file mode 100644
index 0000000000..0cdf33c3e2
--- /dev/null
+++ b/lib/ssl/test/make_certs.erl
@@ -0,0 +1,288 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 2007-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(make_certs).
+
+-export([all/2]).
+
+-record(dn, {commonName,
+ organizationalUnitName = "Erlang OTP",
+ organizationName = "Ericsson AB",
+ localityName = "Stockholm",
+ countryName = "SE",
+ emailAddress = "[email protected]"}).
+
+all(DataDir, PrivDir) ->
+ OpenSSLCmd = "openssl",
+ create_rnd(DataDir, PrivDir), % For all requests
+ rootCA(PrivDir, OpenSSLCmd, "erlangCA"),
+ intermediateCA(PrivDir, OpenSSLCmd, "otpCA", "erlangCA"),
+ endusers(PrivDir, OpenSSLCmd, "otpCA", ["client", "server"]),
+ collect_certs(PrivDir, ["erlangCA", "otpCA"], ["client", "server"]),
+ %% Create keycert files
+ SDir = filename:join([PrivDir, "server"]),
+ SC = filename:join([SDir, "cert.pem"]),
+ SK = filename:join([SDir, "key.pem"]),
+ SKC = filename:join([SDir, "keycert.pem"]),
+ append_files([SK, SC], SKC),
+ CDir = filename:join([PrivDir, "client"]),
+ CC = filename:join([CDir, "cert.pem"]),
+ CK = filename:join([CDir, "key.pem"]),
+ CKC = filename:join([CDir, "keycert.pem"]),
+ append_files([CK, CC], CKC),
+ remove_rnd(PrivDir).
+
+append_files(FileNames, ResultFileName) ->
+ {ok, ResultFile} = file:open(ResultFileName, [write]),
+ do_append_files(FileNames, ResultFile).
+
+do_append_files([], RF) ->
+ ok = file:close(RF);
+do_append_files([F|Fs], RF) ->
+ {ok, Data} = file:read_file(F),
+ ok = file:write(RF, Data),
+ do_append_files(Fs, RF).
+
+rootCA(Root, OpenSSLCmd, Name) ->
+ create_ca_dir(Root, Name, ca_cnf(Name)),
+ DN = #dn{commonName = Name},
+ create_self_signed_cert(Root, OpenSSLCmd, Name, req_cnf(DN)),
+ ok.
+
+intermediateCA(Root, OpenSSLCmd, CA, ParentCA) ->
+ CA = "otpCA",
+ create_ca_dir(Root, CA, ca_cnf(CA)),
+ CARoot = filename:join([Root, CA]),
+ DN = #dn{commonName = CA},
+ CnfFile = filename:join([CARoot, "req.cnf"]),
+ file:write_file(CnfFile, req_cnf(DN)),
+ KeyFile = filename:join([CARoot, "private", "key.pem"]),
+ ReqFile = filename:join([CARoot, "req.pem"]),
+ create_req(Root, OpenSSLCmd, CnfFile, KeyFile, ReqFile),
+ CertFile = filename:join([CARoot, "cert.pem"]),
+ sign_req(Root, OpenSSLCmd, ParentCA, "ca_cert", ReqFile, CertFile).
+
+endusers(Root, OpenSSLCmd, CA, Users) ->
+ lists:foreach(fun(User) -> enduser(Root, OpenSSLCmd, CA, User) end, Users).
+
+enduser(Root, OpenSSLCmd, CA, User) ->
+ UsrRoot = filename:join([Root, User]),
+ file:make_dir(UsrRoot),
+ CnfFile = filename:join([UsrRoot, "req.cnf"]),
+ DN = #dn{commonName = User},
+ file:write_file(CnfFile, req_cnf(DN)),
+ KeyFile = filename:join([UsrRoot, "key.pem"]),
+ ReqFile = filename:join([UsrRoot, "req.pem"]),
+ create_req(Root, OpenSSLCmd, CnfFile, KeyFile, ReqFile),
+ CertFile = filename:join([UsrRoot, "cert.pem"]),
+ sign_req(Root, OpenSSLCmd, CA, "user_cert", ReqFile, CertFile).
+
+collect_certs(Root, CAs, Users) ->
+ Bins = lists:foldr(
+ fun(CA, Acc) ->
+ File = filename:join([Root, CA, "cert.pem"]),
+ {ok, Bin} = file:read_file(File),
+ [Bin, "\n" | Acc]
+ end, [], CAs),
+ lists:foreach(
+ fun(User) ->
+ File = filename:join([Root, User, "cacerts.pem"]),
+ file:write_file(File, Bins)
+ end, Users).
+
+create_self_signed_cert(Root, OpenSSLCmd, CAName, Cnf) ->
+ CARoot = filename:join([Root, CAName]),
+ CnfFile = filename:join([CARoot, "req.cnf"]),
+ file:write_file(CnfFile, Cnf),
+ KeyFile = filename:join([CARoot, "private", "key.pem"]),
+ CertFile = filename:join([CARoot, "cert.pem"]),
+ Cmd = [OpenSSLCmd, " req"
+ " -new"
+ " -x509"
+ " -config ", CnfFile,
+ " -keyout ", KeyFile,
+ " -out ", CertFile],
+ Env = [{"ROOTDIR", Root}],
+ cmd(Cmd, Env).
+
+create_ca_dir(Root, CAName, Cnf) ->
+ CARoot = filename:join([Root, CAName]),
+ file:make_dir(CARoot),
+ create_dirs(CARoot, ["certs", "crl", "newcerts", "private"]),
+ create_rnd(Root, filename:join([CAName, "private"])),
+ create_files(CARoot, [{"serial", "01\n"},
+ {"index.txt", ""},
+ {"ca.cnf", Cnf}]).
+
+create_req(Root, OpenSSLCmd, CnfFile, KeyFile, ReqFile) ->
+ Cmd = [OpenSSLCmd, " req"
+ " -new"
+ " -config ", CnfFile,
+ " -keyout ", KeyFile,
+ " -out ", ReqFile],
+ Env = [{"ROOTDIR", Root}],
+ cmd(Cmd, Env).
+
+sign_req(Root, OpenSSLCmd, CA, CertType, ReqFile, CertFile) ->
+ CACnfFile = filename:join([Root, CA, "ca.cnf"]),
+ Cmd = [OpenSSLCmd, " ca"
+ " -batch"
+ " -notext"
+ " -config ", CACnfFile,
+ " -extensions ", CertType,
+ " -in ", ReqFile,
+ " -out ", CertFile],
+ Env = [{"ROOTDIR", Root}],
+ cmd(Cmd, Env).
+
+%%
+%% Misc
+%%
+
+create_dirs(Root, Dirs) ->
+ lists:foreach(fun(Dir) ->
+ file:make_dir(filename:join([Root, Dir])) end,
+ Dirs).
+
+create_files(Root, NameContents) ->
+ lists:foreach(
+ fun({Name, Contents}) ->
+ file:write_file(filename:join([Root, Name]), Contents) end,
+ NameContents).
+
+create_rnd(FromDir, ToDir) ->
+ From = filename:join([FromDir, "RAND"]),
+ To = filename:join([ToDir, "RAND"]),
+ file:copy(From, To).
+
+remove_rnd(Dir) ->
+ File = filename:join([Dir, "RAND"]),
+ file:delete(File).
+
+cmd(Cmd, Env) ->
+ FCmd = lists:flatten(Cmd),
+ Port = open_port({spawn, FCmd}, [stream, eof, exit_status, stderr_to_stdout,
+ {env, Env}]),
+ eval_cmd(Port).
+
+eval_cmd(Port) ->
+ receive
+ {Port, {data, _}} ->
+ eval_cmd(Port);
+ {Port, eof} ->
+ ok
+ end,
+ receive
+ {Port, {exit_status, Status}} when Status /= 0 ->
+ %% io:fwrite("exit status: ~w~n", [Status]),
+ exit({eval_cmd, Status})
+ after 0 ->
+ ok
+ end.
+
+%%
+%% Contents of configuration files
+%%
+
+req_cnf(DN) ->
+ ["# Purpose: Configuration for requests (end users and CAs)."
+ "\n"
+ "ROOTDIR = $ENV::ROOTDIR\n"
+ "\n"
+
+ "[req]\n"
+ "input_password = secret\n"
+ "output_password = secret\n"
+ "default_bits = 1024\n"
+ "RANDFILE = $ROOTDIR/RAND\n"
+ "encrypt_key = no\n"
+ "default_md = sha1\n"
+ "#string_mask = pkix\n"
+ "x509_extensions = ca_ext\n"
+ "prompt = no\n"
+ "distinguished_name= name\n"
+ "\n"
+
+ "[name]\n"
+ "commonName = ", DN#dn.commonName, "\n"
+ "organizationalUnitName = ", DN#dn.organizationalUnitName, "\n"
+ "organizationName = ", DN#dn.organizationName, "\n"
+ "localityName = ", DN#dn.localityName, "\n"
+ "countryName = ", DN#dn.countryName, "\n"
+ "emailAddress = ", DN#dn.emailAddress, "\n"
+ "\n"
+
+ "[ca_ext]\n"
+ "basicConstraints = critical, CA:true\n"
+ "keyUsage = cRLSign, keyCertSign\n"
+ "subjectKeyIdentifier = hash\n"
+ "subjectAltName = email:copy\n"].
+
+
+ca_cnf(CA) ->
+ ["# Purpose: Configuration for CAs.\n"
+ "\n"
+ "ROOTDIR = $ENV::ROOTDIR\n"
+ "default_ca = ca\n"
+ "\n"
+
+ "[ca]\n"
+ "dir = $ROOTDIR/", CA, "\n"
+ "certs = $dir/certs\n"
+ "crl_dir = $dir/crl\n"
+ "database = $dir/index.txt\n"
+ "new_certs_dir = $dir/newcerts\n"
+ "certificate = $dir/cert.pem\n"
+ "serial = $dir/serial\n"
+ "crl = $dir/crl.pem\n"
+ "private_key = $dir/private/key.pem\n"
+ "RANDFILE = $dir/private/RAND\n"
+ "\n"
+ "x509_extensions = user_cert\n"
+ "default_days = 3600\n"
+ "default_md = sha1\n"
+ "preserve = no\n"
+ "policy = policy_match\n"
+ "\n"
+
+ "[policy_match]\n"
+ "commonName = supplied\n"
+ "organizationalUnitName = optional\n"
+ "organizationName = match\n"
+ "countryName = match\n"
+ "localityName = match\n"
+ "emailAddress = supplied\n"
+ "\n"
+
+ "[user_cert]\n"
+ "basicConstraints = CA:false\n"
+ "keyUsage = nonRepudiation, digitalSignature, keyEncipherment\n"
+ "subjectKeyIdentifier = hash\n"
+ "authorityKeyIdentifier = keyid,issuer:always\n"
+ "subjectAltName = email:copy\n"
+ "issuerAltName = issuer:copy\n"
+ "\n"
+
+ "[ca_cert]\n"
+ "basicConstraints = critical,CA:true\n"
+ "keyUsage = cRLSign, keyCertSign\n"
+ "subjectKeyIdentifier = hash\n"
+ "authorityKeyIdentifier = keyid:always,issuer:always\n"
+ "subjectAltName = email:copy\n"
+ "issuerAltName = issuer:copy\n"].
diff --git a/lib/ssl/test/old_ssl_active_SUITE.erl b/lib/ssl/test/old_ssl_active_SUITE.erl
new file mode 100644
index 0000000000..010596f351
--- /dev/null
+++ b/lib/ssl/test/old_ssl_active_SUITE.erl
@@ -0,0 +1,387 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 1999-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(old_ssl_active_SUITE).
+
+-export([all/1,
+ init_per_testcase/2,
+ fin_per_testcase/2,
+ config/1,
+ finish/1,
+ cinit_return_chkclose/1,
+ sinit_return_chkclose/1,
+ cinit_big_return_chkclose/1,
+ sinit_big_return_chkclose/1,
+ cinit_big_echo_chkclose/1,
+ cinit_huge_echo_chkclose/1,
+ sinit_big_echo_chkclose/1,
+ cinit_few_echo_chkclose/1,
+ cinit_many_echo_chkclose/1,
+ cinit_cnocert/1
+ ]).
+
+-import(ssl_test_MACHINE, [mk_ssl_cert_opts/1, test_one_listener/7,
+ test_server_only/6]).
+
+-include("test_server.hrl").
+-include("ssl_test_MACHINE.hrl").
+
+-define(MANYCONNS, ssl_test_MACHINE:many_conns()).
+
+init_per_testcase(_Case, Config) ->
+ WatchDog = ssl_test_lib:timetrap(?DEFAULT_TIMEOUT),
+ [{watchdog, WatchDog}| Config].
+
+fin_per_testcase(_Case, Config) ->
+ WatchDog = ?config(watchdog, Config),
+ test_server:timetrap_cancel(WatchDog).
+
+all(doc) ->
+ "Test of ssl.erl interface in active mode.";
+all(suite) ->
+ {conf,
+ config,
+ [cinit_return_chkclose,
+ sinit_return_chkclose,
+ cinit_big_return_chkclose,
+ sinit_big_return_chkclose,
+ cinit_big_echo_chkclose,
+ cinit_huge_echo_chkclose,
+ sinit_big_echo_chkclose,
+ cinit_few_echo_chkclose,
+ cinit_many_echo_chkclose,
+ cinit_cnocert],
+ finish}.
+
+config(doc) ->
+ "Want to se what Config contains, and record the number of available "
+ "file descriptors";
+config(suite) ->
+ [];
+config(Config) ->
+ io:format("Config: ~p~n", [Config]),
+ case os:type() of
+ {unix, _} ->
+ ?line io:format("Max fd value: ~s", [os:cmd("ulimit -n")]);
+ _ ->
+ ok
+ end,
+ %% XXX Also record: Erlang/SSL version, version of OpenSSL,
+ %% operating system, version of OTP, Erts, kernel and stdlib.
+
+ %% Check if SSL exists. If this case fails, all other cases are skipped
+ case ssl:start() of
+ ok -> ssl:stop();
+ {error, {already_started, _}} -> ssl:stop();
+ Error -> ?t:fail({failed_starting_ssl,Error})
+ end,
+ Config.
+
+finish(doc) ->
+ "This test case has no mission other than closing the conf case";
+finish(suite) ->
+ [];
+finish(Config) ->
+ Config.
+
+cinit_return_chkclose(doc) ->
+ "Client sends 1000 bytes to server, that receives them, sends them "
+ "back, and closes. Client waits for close. Both have certs.";
+cinit_return_chkclose(suite) ->
+ [];
+cinit_return_chkclose(Config) when list(Config) ->
+ process_flag(trap_exit, true),
+ DataSize = 1000, LPort = 3456,
+ Timeout = 40000, NConns = 1,
+
+ ?line {ok, {CsslOpts, SsslOpts}} = mk_ssl_cert_opts(Config),
+ ?line {ok, Host} = inet:gethostname(),
+
+ LCmds = [{sockopts, [{backlog, NConns}]},
+ {sslopts, SsslOpts},
+ {listen, LPort},
+ wait_sync,
+ lclose],
+ ACmds = [{timeout, Timeout},
+ accept,
+ {recv, DataSize}, {send, DataSize},
+ close],
+ CCmds = [{timeout, Timeout},
+ {sslopts, CsslOpts},
+ {connect, {Host, LPort}},
+ {send, DataSize}, {recv, DataSize},
+ await_close],
+ ?line test_one_listener(NConns, LCmds, ACmds, CCmds, Timeout, ?MODULE,
+ Config).
+
+sinit_return_chkclose(doc) ->
+ "Server sends 1000 bytes to client, that receives them, sends them "
+ "back, and closes. Server waits for close. Both have certs.";
+sinit_return_chkclose(suite) ->
+ [];
+sinit_return_chkclose(Config) when list(Config) ->
+ process_flag(trap_exit, true),
+ DataSize = 1000, LPort = 3456,
+ Timeout = 40000, NConns = 1,
+
+ ?line {ok, {CsslOpts, SsslOpts}} = mk_ssl_cert_opts(Config),
+ ?line {ok, Host} = inet:gethostname(),
+
+ LCmds = [{sockopts, [{backlog, NConns}]},
+ {sslopts, [{ssl_imp, old}|SsslOpts]},
+ {listen, LPort},
+ wait_sync,
+ lclose],
+ ACmds = [{timeout, Timeout},
+ accept,
+ {send, DataSize}, {recv, DataSize},
+ await_close],
+ CCmds = [{timeout, Timeout},
+ {sslopts, [{ssl_imp, old}|CsslOpts]},
+ {connect, {Host, LPort}},
+ {recv, DataSize}, {send, DataSize},
+ close],
+
+ ?line test_one_listener(NConns, LCmds, ACmds, CCmds, Timeout, ?MODULE,
+ Config).
+
+cinit_big_return_chkclose(doc) ->
+ "Client sends 50000 bytes to server, that receives them, sends them "
+ "back, and closes. Client waits for close. Both have certs.";
+cinit_big_return_chkclose(suite) ->
+ [];
+cinit_big_return_chkclose(Config) when list(Config) ->
+ process_flag(trap_exit, true),
+ DataSize = 50000, LPort = 3456,
+ Timeout = 40000, NConns = 1,
+
+ ?line {ok, {CsslOpts, SsslOpts}} = mk_ssl_cert_opts(Config),
+ ?line {ok, Host} = inet:gethostname(),
+
+ LCmds = [{sockopts, [{backlog, NConns}]},
+ {sslopts, SsslOpts},
+ {listen, LPort},
+ wait_sync,
+ lclose],
+ ACmds = [{timeout, Timeout},
+ accept,
+ {recv, DataSize}, {send, DataSize},
+ close],
+ CCmds = [{timeout, Timeout},
+ {sslopts, CsslOpts},
+ {connect, {Host, LPort}},
+ {send, DataSize}, {recv, DataSize},
+ await_close],
+ ?line test_one_listener(NConns, LCmds, ACmds, CCmds, Timeout, ?MODULE,
+ Config).
+
+sinit_big_return_chkclose(doc) ->
+ "Server sends 50000 bytes to client, that receives them, sends them "
+ "back, and closes. Server waits for close. Both have certs.";
+sinit_big_return_chkclose(suite) ->
+ [];
+sinit_big_return_chkclose(Config) when list(Config) ->
+ process_flag(trap_exit, true),
+ DataSize = 50000, LPort = 3456,
+ Timeout = 40000, NConns = 1,
+
+ ?line {ok, {CsslOpts, SsslOpts}} = mk_ssl_cert_opts(Config),
+ ?line {ok, Host} = inet:gethostname(),
+
+ LCmds = [{sockopts, [{backlog, NConns}]},
+ {sslopts, SsslOpts},
+ {listen, LPort},
+ wait_sync,
+ lclose],
+ ACmds = [{timeout, Timeout},
+ accept,
+ {send, DataSize}, {recv, DataSize},
+ await_close],
+ CCmds = [{timeout, Timeout},
+ {sslopts, CsslOpts},
+ {connect, {Host, LPort}},
+ {recv, DataSize}, {send, DataSize},
+ close],
+
+ ?line test_one_listener(NConns, LCmds, ACmds, CCmds, Timeout, ?MODULE,
+ Config).
+
+cinit_big_echo_chkclose(doc) ->
+ "Client sends 50000 bytes to server, that echoes them back "
+ "and closes. Client waits for close. Both have certs.";
+cinit_big_echo_chkclose(suite) ->
+ [];
+cinit_big_echo_chkclose(Config) when list(Config) ->
+ process_flag(trap_exit, true),
+ DataSize = 50000, LPort = 3456,
+ Timeout = 40000, NConns = 1,
+
+ ?line {ok, {CsslOpts, SsslOpts}} = mk_ssl_cert_opts(Config),
+ ?line {ok, Host} = inet:gethostname(),
+
+ LCmds = [{sockopts, [{backlog, NConns}]},
+ {sslopts, SsslOpts},
+ {listen, LPort},
+ wait_sync,
+ lclose],
+ ACmds = [{timeout, Timeout},
+ accept,
+ {echo, DataSize},
+ close],
+ CCmds = [{timeout, Timeout},
+ {sslopts, CsslOpts},
+ {connect, {Host, LPort}},
+ {send, DataSize}, {recv, DataSize},
+ await_close],
+ ?line test_one_listener(NConns, LCmds, ACmds, CCmds, Timeout, ?MODULE,
+ Config).
+
+cinit_huge_echo_chkclose(doc) ->
+ "Client sends 500000 bytes to server, that echoes them back "
+ "and closes. Client waits for close. Both have certs.";
+cinit_huge_echo_chkclose(suite) ->
+ [];
+cinit_huge_echo_chkclose(Config) when list(Config) ->
+ process_flag(trap_exit, true),
+ DataSize = 500000, LPort = 3456,
+ Timeout = 40000, NConns = 1,
+
+ ?line {ok, {CsslOpts, SsslOpts}} = mk_ssl_cert_opts(Config),
+ ?line {ok, Host} = inet:gethostname(),
+
+ LCmds = [{sockopts, [{backlog, NConns}]},
+ {sslopts, SsslOpts},
+ {listen, LPort},
+ wait_sync,
+ lclose],
+ ACmds = [{timeout, Timeout},
+ accept,
+ {echo, DataSize},
+ close],
+ CCmds = [{timeout, Timeout},
+ {sslopts, CsslOpts},
+ {connect, {Host, LPort}},
+ {send, DataSize}, {recv, DataSize},
+ await_close],
+ ?line test_one_listener(NConns, LCmds, ACmds, CCmds, Timeout, ?MODULE,
+ Config).
+
+sinit_big_echo_chkclose(doc) ->
+ "Server sends 50000 bytes to client, that echoes them back "
+ "and closes. Server waits for close. Both have certs.";
+sinit_big_echo_chkclose(suite) ->
+ [];
+sinit_big_echo_chkclose(Config) when list(Config) ->
+ process_flag(trap_exit, true),
+ DataSize = 50000, LPort = 3456,
+ Timeout = 40000, NConns = 1,
+
+ ?line {ok, {CsslOpts, SsslOpts}} = mk_ssl_cert_opts(Config),
+ ?line {ok, Host} = inet:gethostname(),
+
+ LCmds = [{sockopts, [{backlog, NConns}]},
+ {sslopts, SsslOpts},
+ {listen, LPort},
+ wait_sync,
+ lclose],
+ ACmds = [{timeout, Timeout},
+ accept,
+ {send, DataSize}, {recv, DataSize},
+ await_close],
+ CCmds = [{timeout, Timeout},
+ {sslopts, CsslOpts},
+ {connect, {Host, LPort}},
+ {echo, DataSize},
+ close],
+
+ ?line test_one_listener(NConns, LCmds, ACmds, CCmds, Timeout, ?MODULE,
+ Config).
+
+
+%% This case is repeated several times.
+
+cinit_few_echo_chkclose(X) -> cinit_many_echo_chkclose(X, 7).
+
+cinit_many_echo_chkclose(X) -> cinit_many_echo_chkclose(X, ?MANYCONNS).
+
+cinit_many_echo_chkclose(doc, _NConns) ->
+ "N client sends 10000 bytes to server, that echoes them back "
+ "and closes. Clients wait for close. All have certs.";
+cinit_many_echo_chkclose(suite, _NConns) ->
+ [];
+cinit_many_echo_chkclose(Config, NConns) when list(Config) ->
+ process_flag(trap_exit, true),
+ DataSize = 10000, LPort = 3456,
+ Timeout = 80000,
+
+ io:format("~w connections", [NConns]),
+
+ ?line {ok, {CsslOpts, SsslOpts}} = mk_ssl_cert_opts(Config),
+ ?line {ok, Host} = inet:gethostname(),
+
+ LCmds = [{sockopts, [{backlog, NConns}]},
+ {sslopts, SsslOpts},
+ {listen, LPort},
+ wait_sync,
+ lclose],
+ ACmds = [{timeout, Timeout},
+ accept,
+ {echo, DataSize},
+ close],
+ CCmds = [{timeout, Timeout},
+ {sslopts, CsslOpts},
+ {connect, {Host, LPort}},
+ {send, DataSize}, {recv, DataSize},
+ await_close],
+ ?line test_one_listener(NConns, LCmds, ACmds, CCmds, Timeout, ?MODULE,
+ Config).
+
+
+cinit_cnocert(doc) ->
+ "Client sends 1000 bytes to server, that receives them, sends them "
+ "back, and closes. Client waits for close. Client has no cert, "
+ "but server has.";
+cinit_cnocert(suite) ->
+ [];
+cinit_cnocert(Config) when list(Config) ->
+ process_flag(trap_exit, true),
+ DataSize = 1000, LPort = 3457,
+ Timeout = 40000, NConns = 1,
+
+ ?line {ok, {_CsslOpts, SsslOpts}} = mk_ssl_cert_opts(Config),
+ ?line {ok, Host} = inet:gethostname(),
+
+ LCmds = [{sockopts, [{backlog, NConns}]},
+ {sslopts, SsslOpts},
+ {listen, LPort},
+ wait_sync,
+ lclose],
+ ACmds = [{timeout, Timeout},
+ accept,
+ {recv, DataSize}, {send, DataSize},
+ close],
+ CCmds = [{timeout, Timeout},
+ {connect, {Host, LPort}},
+ {send, DataSize}, {recv, DataSize},
+ await_close],
+ ?line test_one_listener(NConns, LCmds, ACmds, CCmds, Timeout, ?MODULE,
+ Config).
+
+
diff --git a/lib/ssl/test/old_ssl_active_once_SUITE.erl b/lib/ssl/test/old_ssl_active_once_SUITE.erl
new file mode 100644
index 0000000000..6224b17aa7
--- /dev/null
+++ b/lib/ssl/test/old_ssl_active_once_SUITE.erl
@@ -0,0 +1,409 @@
+%%
+%% %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(old_ssl_active_once_SUITE).
+
+-export([all/1,
+ init_per_testcase/2,
+ fin_per_testcase/2,
+ config/1,
+ finish/1,
+ server_accept_timeout/1,
+ cinit_return_chkclose/1,
+ sinit_return_chkclose/1,
+ cinit_big_return_chkclose/1,
+ sinit_big_return_chkclose/1,
+ cinit_big_echo_chkclose/1,
+ cinit_huge_echo_chkclose/1,
+ sinit_big_echo_chkclose/1,
+ cinit_few_echo_chkclose/1,
+ cinit_many_echo_chkclose/1,
+ cinit_cnocert/1
+ ]).
+
+-import(ssl_test_MACHINE, [mk_ssl_cert_opts/1, test_one_listener/7,
+ test_server_only/6]).
+-include("test_server.hrl").
+-include("ssl_test_MACHINE.hrl").
+
+-define(MANYCONNS, ssl_test_MACHINE:many_conns()).
+
+init_per_testcase(_Case, Config) ->
+ WatchDog = ssl_test_lib:timetrap(?DEFAULT_TIMEOUT),
+ [{watchdog, WatchDog}| Config].
+
+fin_per_testcase(_Case, Config) ->
+ WatchDog = ?config(watchdog, Config),
+ test_server:timetrap_cancel(WatchDog).
+
+all(doc) ->
+ "Test of ssl.erl interface in passive mode.";
+all(suite) ->
+ {conf,
+ config,
+ [server_accept_timeout,
+ cinit_return_chkclose,
+ sinit_return_chkclose,
+ cinit_big_return_chkclose,
+ sinit_big_return_chkclose,
+ cinit_big_echo_chkclose,
+ cinit_huge_echo_chkclose,
+ sinit_big_echo_chkclose,
+ cinit_few_echo_chkclose,
+ cinit_many_echo_chkclose,
+ cinit_cnocert],
+ finish}.
+
+config(doc) ->
+ "Want to se what Config contains.";
+config(suite) ->
+ [];
+config(Config) ->
+ io:format("Config: ~p~n", [Config]),
+
+ %% Check if SSL exists. If this case fails, all other cases are skipped
+ case ssl:start() of
+ ok -> ssl:stop();
+ {error, {already_started, _}} -> ssl:stop();
+ Error -> ?t:fail({failed_starting_ssl,Error})
+ end,
+ Config.
+
+finish(doc) ->
+ "This test case has no mission other than closing the conf case";
+finish(suite) ->
+ [];
+finish(Config) ->
+ Config.
+
+server_accept_timeout(doc) ->
+ "Server has one pending accept with timeout. Checks that return "
+ "value is {error, timeout}.";
+server_accept_timeout(suite) ->
+ [];
+server_accept_timeout(Config) when list(Config) ->
+ process_flag(trap_exit, true),
+ LPort = 3456,
+ Timeout = 40000, NConns = 1,
+ AccTimeout = 3000,
+
+ ?line {ok, {_, SsslOpts}} = mk_ssl_cert_opts(Config),
+
+ LCmds = [{sockopts, [{backlog, NConns}, {active, once}]},
+ {sslopts, SsslOpts},
+ {listen, LPort},
+ wait_sync,
+ lclose],
+ ACmds = [{timeout, AccTimeout},
+ accept_timeout],
+ ?line test_server_only(NConns, LCmds, ACmds, Timeout, ?MODULE,
+ Config).
+
+cinit_return_chkclose(doc) ->
+ "Client sends 1000 bytes to server, that receives them, sends them "
+ "back, and closes. Client waits for close. Both have certs.";
+cinit_return_chkclose(suite) ->
+ [];
+cinit_return_chkclose(Config) when list(Config) ->
+ process_flag(trap_exit, true),
+ DataSize = 1000, LPort = 3456,
+ Timeout = 40000, NConns = 1,
+
+ ?line {ok, {CsslOpts, SsslOpts}} = mk_ssl_cert_opts(Config),
+ ?line {ok, Host} = inet:gethostname(),
+
+ LCmds = [{sockopts, [{backlog, NConns}, {active, once}]},
+ {sslopts, SsslOpts},
+ {listen, LPort},
+ wait_sync,
+ lclose],
+ ACmds = [{timeout, Timeout},
+ accept,
+ {recv, DataSize}, {send, DataSize},
+ close],
+ CCmds = [{timeout, Timeout},
+ {sockopts, [{active, once}]},
+ {sslopts, CsslOpts},
+ {connect, {Host, LPort}},
+ {send, DataSize}, {recv, DataSize},
+ await_close],
+ ?line test_one_listener(NConns, LCmds, ACmds, CCmds, Timeout, ?MODULE,
+ Config).
+
+sinit_return_chkclose(doc) ->
+ "Server sends 1000 bytes to client, that receives them, sends them "
+ "back, and closes. Server waits for close. Both have certs.";
+sinit_return_chkclose(suite) ->
+ [];
+sinit_return_chkclose(Config) when list(Config) ->
+ process_flag(trap_exit, true),
+ DataSize = 1000, LPort = 3456,
+ Timeout = 40000, NConns = 1,
+
+ ?line {ok, {CsslOpts, SsslOpts}} = mk_ssl_cert_opts(Config),
+ ?line {ok, Host} = inet:gethostname(),
+
+ LCmds = [{sockopts, [{backlog, NConns}, {active, once}]},
+ {sslopts, SsslOpts},
+ {listen, LPort},
+ wait_sync,
+ lclose],
+ ACmds = [{timeout, Timeout},
+ accept,
+ {send, DataSize}, {recv, DataSize},
+ await_close],
+ CCmds = [{timeout, Timeout},
+ {sockopts, [{active, once}]},
+ {sslopts, CsslOpts},
+ {connect, {Host, LPort}},
+ {recv, DataSize}, {send, DataSize},
+ close],
+
+ ?line test_one_listener(NConns, LCmds, ACmds, CCmds, Timeout, ?MODULE,
+ Config).
+
+cinit_big_return_chkclose(doc) ->
+ "Client sends 50000 bytes to server, that receives them, sends them "
+ "back, and closes. Client waits for close. Both have certs.";
+cinit_big_return_chkclose(suite) ->
+ [];
+cinit_big_return_chkclose(Config) when list(Config) ->
+ process_flag(trap_exit, true),
+ DataSize = 50000, LPort = 3456,
+ Timeout = 40000, NConns = 1,
+
+ ?line {ok, {CsslOpts, SsslOpts}} = mk_ssl_cert_opts(Config),
+ ?line {ok, Host} = inet:gethostname(),
+
+ %% Set {active, false} so that accept is passive to begin with.
+ LCmds = [{sockopts, [{backlog, NConns}, {active, false}]},
+ {sslopts, SsslOpts},
+ {listen, LPort},
+ wait_sync,
+ lclose],
+ ACmds = [{timeout, Timeout},
+ accept,
+ {sockopts, [{active, once}]}, % {active, once} here.
+ {recv, DataSize}, {send, DataSize},
+ close],
+ CCmds = [{timeout, Timeout},
+ {sockopts, [{active, once}]},
+ {sslopts, CsslOpts},
+ {connect, {Host, LPort}},
+ {send, DataSize}, {recv, DataSize},
+ await_close],
+ ?line test_one_listener(NConns, LCmds, ACmds, CCmds, Timeout, ?MODULE,
+ Config).
+
+sinit_big_return_chkclose(doc) ->
+ "Server sends 50000 bytes to client, that receives them, sends them "
+ "back, and closes. Server waits for close. Both have certs.";
+sinit_big_return_chkclose(suite) ->
+ [];
+sinit_big_return_chkclose(Config) when list(Config) ->
+ process_flag(trap_exit, true),
+ DataSize = 50000, LPort = 3456,
+ Timeout = 40000, NConns = 1,
+
+ ?line {ok, {CsslOpts, SsslOpts}} = mk_ssl_cert_opts(Config),
+ ?line {ok, Host} = inet:gethostname(),
+
+ LCmds = [{sockopts, [{backlog, NConns}, {active, once}]},
+ {sslopts, SsslOpts},
+ {listen, LPort},
+ wait_sync,
+ lclose],
+ ACmds = [{timeout, Timeout},
+ accept,
+ {send, DataSize}, {recv, DataSize},
+ await_close],
+ CCmds = [{timeout, Timeout},
+ {sockopts, [{active, once}]},
+ {sslopts, CsslOpts},
+ {connect, {Host, LPort}},
+ {recv, DataSize}, {send, DataSize},
+ close],
+
+ ?line test_one_listener(NConns, LCmds, ACmds, CCmds, Timeout, ?MODULE,
+ Config).
+
+cinit_big_echo_chkclose(doc) ->
+ "Client sends 50000 bytes to server, that echoes them back "
+ "and closes. Client waits for close. Both have certs.";
+cinit_big_echo_chkclose(suite) ->
+ [];
+cinit_big_echo_chkclose(Config) when list(Config) ->
+ process_flag(trap_exit, true),
+ DataSize = 50000, LPort = 3456,
+ Timeout = 40000, NConns = 1,
+
+ ?line {ok, {CsslOpts, SsslOpts}} = mk_ssl_cert_opts(Config),
+ ?line {ok, Host} = inet:gethostname(),
+
+ LCmds = [{sockopts, [{backlog, NConns}, {active, once}]},
+ {sslopts, SsslOpts},
+ {listen, LPort},
+ wait_sync,
+ lclose],
+ ACmds = [{timeout, Timeout},
+ accept,
+ {echo, DataSize},
+ close],
+ CCmds = [{timeout, Timeout},
+ {sockopts, [{active, once}]},
+ {sslopts, CsslOpts},
+ {connect, {Host, LPort}},
+ {send, DataSize}, {recv, DataSize},
+ await_close],
+ ?line test_one_listener(NConns, LCmds, ACmds, CCmds, Timeout, ?MODULE,
+ Config).
+
+cinit_huge_echo_chkclose(doc) ->
+ "Client sends 500000 bytes to server, that echoes them back "
+ "and closes. Client waits for close. Both have certs.";
+cinit_huge_echo_chkclose(suite) ->
+ [];
+cinit_huge_echo_chkclose(Config) when list(Config) ->
+ process_flag(trap_exit, true),
+ DataSize = 500000, LPort = 3456,
+ Timeout = 40000, NConns = 1,
+
+ ?line {ok, {CsslOpts, SsslOpts}} = mk_ssl_cert_opts(Config),
+ ?line {ok, Host} = inet:gethostname(),
+
+ LCmds = [{sockopts, [{backlog, NConns}, {active, once}]},
+ {sslopts, SsslOpts},
+ {listen, LPort},
+ wait_sync,
+ lclose],
+ ACmds = [{timeout, Timeout},
+ accept,
+ {echo, DataSize},
+ close],
+ CCmds = [{timeout, Timeout},
+ {sockopts, [{active, once}]},
+ {sslopts, CsslOpts},
+ {connect, {Host, LPort}},
+ {send, DataSize}, {recv, DataSize},
+ await_close],
+ ?line test_one_listener(NConns, LCmds, ACmds, CCmds, Timeout, ?MODULE,
+ Config).
+
+sinit_big_echo_chkclose(doc) ->
+ "Server sends 50000 bytes to client, that echoes them back "
+ "and closes. Server waits for close. Both have certs.";
+sinit_big_echo_chkclose(suite) ->
+ [];
+sinit_big_echo_chkclose(Config) when list(Config) ->
+ process_flag(trap_exit, true),
+ DataSize = 50000, LPort = 3456,
+ Timeout = 40000, NConns = 1,
+
+ ?line {ok, {CsslOpts, SsslOpts}} = mk_ssl_cert_opts(Config),
+ ?line {ok, Host} = inet:gethostname(),
+
+ LCmds = [{sockopts, [{backlog, NConns}, {active, once}]},
+ {sslopts, SsslOpts},
+ {listen, LPort},
+ wait_sync,
+ lclose],
+ ACmds = [{timeout, Timeout},
+ accept,
+ {send, DataSize}, {recv, DataSize},
+ await_close],
+ CCmds = [{timeout, Timeout},
+ {sockopts, [{active, once}]},
+ {sslopts, CsslOpts},
+ {connect, {Host, LPort}},
+ {echo, DataSize},
+ close],
+
+ ?line test_one_listener(NConns, LCmds, ACmds, CCmds, Timeout, ?MODULE,
+ Config).
+
+cinit_few_echo_chkclose(X) -> cinit_many_echo_chkclose(X, 7).
+
+cinit_many_echo_chkclose(X) -> cinit_many_echo_chkclose(X, ?MANYCONNS).
+
+cinit_many_echo_chkclose(doc, _NConns) ->
+ "client send 10000 bytes to server, that echoes them back "
+ "and closes. Clients wait for close. All have certs.";
+cinit_many_echo_chkclose(suite, _NConns) ->
+ [];
+cinit_many_echo_chkclose(Config, NConns) when list(Config) ->
+ process_flag(trap_exit, true),
+ DataSize = 10000, LPort = 3456,
+ Timeout = 80000,
+
+ io:format("~w connections", [NConns]),
+
+ ?line {ok, {CsslOpts, SsslOpts}} = mk_ssl_cert_opts(Config),
+ ?line {ok, Host} = inet:gethostname(),
+
+ LCmds = [{sockopts, [{backlog, NConns}, {active, once}]},
+ {sslopts, SsslOpts},
+ {listen, LPort},
+ wait_sync,
+ lclose],
+ ACmds = [{timeout, Timeout},
+ accept,
+ {echo, DataSize},
+ close],
+ CCmds = [{timeout, Timeout},
+ {sockopts, [{active, once}]},
+ {sslopts, CsslOpts},
+ {connect, {Host, LPort}},
+ {send, DataSize}, {recv, DataSize},
+ await_close],
+ ?line test_one_listener(NConns, LCmds, ACmds, CCmds, Timeout, ?MODULE,
+ Config).
+
+cinit_cnocert(doc) ->
+ "Client sends 1000 bytes to server, that receives them, sends them "
+ "back, and closes. Client waits for close. Client has no cert, "
+ "but server has.";
+cinit_cnocert(suite) ->
+ [];
+cinit_cnocert(Config) when list(Config) ->
+ process_flag(trap_exit, true),
+ DataSize = 1000, LPort = 3457,
+ Timeout = 40000, NConns = 1,
+
+ ?line {ok, {_CsslOpts, SsslOpts}} = mk_ssl_cert_opts(Config),
+ ?line {ok, Host} = inet:gethostname(),
+
+ LCmds = [{sockopts, [{backlog, NConns}, {active, once}]},
+ {sslopts, SsslOpts},
+ {listen, LPort},
+ wait_sync,
+ lclose],
+ ACmds = [{timeout, Timeout},
+ accept,
+ {recv, DataSize}, {send, DataSize},
+ close],
+ CCmds = [{timeout, Timeout},
+ {sockopts, [{active, once}]},
+ {connect, {Host, LPort}},
+ {send, DataSize}, {recv, DataSize},
+ await_close],
+ ?line test_one_listener(NConns, LCmds, ACmds, CCmds, Timeout, ?MODULE,
+ Config).
+
+
diff --git a/lib/ssl/test/old_ssl_dist_SUITE.erl b/lib/ssl/test/old_ssl_dist_SUITE.erl
new file mode 100644
index 0000000000..56209c3530
--- /dev/null
+++ b/lib/ssl/test/old_ssl_dist_SUITE.erl
@@ -0,0 +1,595 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 2007-2009. All Rights Reserved.
+%%
+%% The contents of this file are subject to the Erlang Public License,
+%% Version 1.1, (the "License"); you may not use this file except in
+%% compliance with the License. You should have received a copy of the
+%% Erlang Public License along with this software. If not, it can be
+%% retrieved online at http://www.erlang.org/.
+%%
+%% Software distributed under the License is distributed on an "AS IS"
+%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+%% the License for the specific language governing rights and limitations
+%% under the License.
+%%
+%% %CopyrightEnd%
+%%
+
+%%
+
+
+%%%-------------------------------------------------------------------
+%%% File : ssl_dist_SUITE.erl
+%%% Author : Rickard Green
+%%% Description : Test that the Erlang distribution works over ssl.
+%%%
+%%% Created : 15 Nov 2007 by Rickard Green
+%%%-------------------------------------------------------------------
+-module(old_ssl_dist_SUITE).
+
+-include("test_server.hrl").
+
+-define(DEFAULT_TIMETRAP_SECS, 240).
+
+-define(AWAIT_SLL_NODE_UP_TIMEOUT, 30000).
+
+-export([all/1]).
+-export([init_per_suite/1,
+ end_per_suite/1,
+ init_per_testcase/2,
+ fin_per_testcase/2]).
+-export([cnct2tstsrvr/1]).
+
+-export([basic/1]).
+
+-record(node_handle, {connection_handler, socket, name, nodename}).
+
+all(doc) ->
+ [];
+all(suite) ->
+ [basic].
+
+init_per_suite(Config) ->
+ add_ssl_opts_config(Config).
+
+end_per_suite(Config) ->
+ Config.
+
+init_per_testcase(Case, Config) when list(Config) ->
+ Dog = ?t:timetrap(?t:seconds(?DEFAULT_TIMETRAP_SECS)),
+ [{watchdog, Dog},{testcase, Case}|Config].
+
+fin_per_testcase(_Case, Config) when list(Config) ->
+ Dog = ?config(watchdog, Config),
+ ?t:timetrap_cancel(Dog),
+ ok.
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%% %%
+%% Testcases %%
+%% %%
+
+basic(doc) ->
+ ["Test that two nodes can connect via ssl distribution"];
+basic(suite) ->
+ [];
+basic(Config) when is_list(Config) ->
+ ?line NH1 = start_ssl_node(Config),
+ ?line Node1 = NH1#node_handle.nodename,
+ ?line NH2 = start_ssl_node(Config),
+ ?line Node2 = NH2#node_handle.nodename,
+
+ ?line pong = apply_on_ssl_node(NH1, fun () -> net_adm:ping(Node2) end),
+
+ ?line [Node2] = apply_on_ssl_node(NH1, fun () -> nodes() end),
+ ?line [Node1] = apply_on_ssl_node(NH2, fun () -> nodes() end),
+
+ %% The test_server node has the same cookie as the ssl nodes
+ %% but it should not be able to communicate with the ssl nodes
+ %% via the erlang distribution.
+ ?line pang = net_adm:ping(Node1),
+ ?line pang = net_adm:ping(Node2),
+
+
+ %%
+ %% Check that we are able to communicate over the erlang
+ %% distribution between the ssl nodes.
+ %%
+ ?line Ref = make_ref(),
+ ?line spawn(fun () ->
+ apply_on_ssl_node(
+ NH1,
+ fun () ->
+ tstsrvr_format("Hi from ~p!~n",
+ [node()]),
+ send_to_tstcntrl({Ref, self()}),
+ receive
+ {From, ping} ->
+ From ! {self(), pong}
+ end
+ end)
+ end),
+ ?line receive
+ {Ref, SslPid} ->
+ ?line ok = apply_on_ssl_node(
+ NH2,
+ fun () ->
+ tstsrvr_format("Hi from ~p!~n",
+ [node()]),
+ SslPid ! {self(), ping},
+ receive
+ {SslPid, pong} ->
+ ok
+ end
+ end)
+ end,
+
+ ?line stop_ssl_node(NH1),
+ ?line stop_ssl_node(NH2),
+ ?line success(Config).
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%% %%
+%% Internal functions %%
+%% %%
+
+%%
+%% ssl_node side api
+%%
+
+tstsrvr_format(Fmt, ArgList) ->
+ send_to_tstsrvr({format, Fmt, ArgList}).
+
+send_to_tstcntrl(Message) ->
+ send_to_tstsrvr({message, Message}).
+
+
+%%
+%% test_server side api
+%%
+
+apply_on_ssl_node(Node, M, F, A) when atom(M), atom(F), list(A) ->
+ Ref = make_ref(),
+ send_to_ssl_node(Node, {apply, self(), Ref, M, F, A}),
+ receive
+ {Ref, Result} ->
+ Result
+ end.
+
+apply_on_ssl_node(Node, Fun) when is_function(Fun, 0) ->
+ Ref = make_ref(),
+ send_to_ssl_node(Node, {apply, self(), Ref, Fun}),
+ receive
+ {Ref, Result} ->
+ Result
+ end.
+
+stop_ssl_node(#node_handle{connection_handler = Handler,
+ socket = Socket,
+ name = Name}) ->
+ ?t:format("Trying to stop ssl node ~s.~n", [Name]),
+ Mon = erlang:monitor(process, Handler),
+ unlink(Handler),
+ case gen_tcp:send(Socket, term_to_binary(stop)) of
+ ok ->
+ receive
+ {'DOWN', Mon, process, Handler, Reason} ->
+ case Reason of
+ normal -> ok;
+ _ -> exit(Reason)
+ end
+ end;
+ Error ->
+ erlang:demonitor(Mon, [flush]),
+ exit(Error)
+ end.
+
+start_ssl_node(Config) ->
+ start_ssl_node(Config, "").
+
+start_ssl_node(Config, XArgs) ->
+ Name = mk_node_name(Config),
+ SSL = ?config(ssl_opts, Config),
+ SSLDistOpts = setup_dist_opts(Name, ?config(priv_dir, Config)),
+ start_ssl_node_raw(Name, SSL ++ " " ++ SSLDistOpts ++ XArgs).
+
+start_ssl_node_raw(Name, Args) ->
+ {ok, LSock} = gen_tcp:listen(0,
+ [binary, {packet, 4}, {active, false}]),
+ {ok, ListenPort} = inet:port(LSock),
+ CmdLine = mk_node_cmdline(ListenPort, Name, Args),
+ ?t:format("Attempting to start ssl node ~s: ~s~n", [Name, CmdLine]),
+ case open_port({spawn, CmdLine}, []) of
+ Port when port(Port) ->
+ unlink(Port),
+ erlang:port_close(Port),
+ case await_ssl_node_up(Name, LSock) of
+ #node_handle{} = NodeHandle ->
+ ?t:format("Ssl node ~s started.~n", [Name]),
+ NodeName = list_to_atom(Name ++ "@" ++ host_name()),
+ NodeHandle#node_handle{nodename = NodeName};
+ Error ->
+ exit({failed_to_start_node, Name, Error})
+ end;
+ Error ->
+ exit({failed_to_start_node, Name, Error})
+ end.
+
+%%
+%% command line creation
+%%
+
+host_name() ->
+ [$@ | Host] = lists:dropwhile(fun ($@) -> false; (_) -> true end,
+ atom_to_list(node())),
+ Host.
+
+mk_node_name(Config) ->
+ {A, B, C} = erlang:now(),
+ Case = ?config(testcase, Config),
+ atom_to_list(?MODULE)
+ ++ "_"
+ ++ atom_to_list(Case)
+ ++ "_"
+ ++ integer_to_list(A)
+ ++ "-"
+ ++ integer_to_list(B)
+ ++ "-"
+ ++ integer_to_list(C).
+
+mk_node_cmdline(ListenPort, Name, Args) ->
+ Static = "-detached -noinput",
+ Pa = filename:dirname(code:which(?MODULE)),
+ Prog = case catch init:get_argument(progname) of
+ {ok,[[P]]} -> P;
+ _ -> exit(no_progname_argument_found)
+ end,
+ NameSw = case net_kernel:longnames() of
+ false -> "-sname ";
+ _ -> "-name "
+ end,
+ {ok, Pwd} = file:get_cwd(),
+ Prog ++ " "
+ ++ Static ++ " "
+ ++ NameSw ++ " " ++ Name ++ " "
+ ++ "-pa " ++ Pa ++ " "
+ ++ "-run " ++ atom_to_list(?MODULE) ++ " cnct2tstsrvr "
+ ++ host_name() ++ " "
+ ++ integer_to_list(ListenPort) ++ " "
+ ++ Args ++ " "
+ ++ "-env ERL_CRASH_DUMP " ++ Pwd ++ "/erl_crash_dump." ++ Name ++ " "
+ ++ "-setcookie " ++ atom_to_list(erlang:get_cookie()).
+
+%%
+%% Connection handler test_server side
+%%
+
+await_ssl_node_up(Name, LSock) ->
+ case gen_tcp:accept(LSock, ?AWAIT_SLL_NODE_UP_TIMEOUT) of
+ timeout ->
+ gen_tcp:close(LSock),
+ ?t:format("Timeout waiting for ssl node ~s to come up~n",
+ [Name]),
+ timeout;
+ {ok, Socket} ->
+ gen_tcp:close(LSock),
+ case gen_tcp:recv(Socket, 0) of
+ {ok, Bin} ->
+ check_ssl_node_up(Socket, Name, Bin);
+ {error, closed} ->
+ gen_tcp:close(Socket),
+ exit({lost_connection_with_ssl_node_before_up, Name})
+ end;
+ {error, Error} ->
+ gen_tcp:close(LSock),
+ exit({accept_failed, Error})
+ end.
+
+check_ssl_node_up(Socket, Name, Bin) ->
+ case catch binary_to_term(Bin) of
+ {'EXIT', _} ->
+ gen_tcp:close(Socket),
+ exit({bad_data_received_from_ssl_node, Name, Bin});
+ {ssl_node_up, NodeName} ->
+ case list_to_atom(Name++"@"++host_name()) of
+ NodeName ->
+ Parent = self(),
+ Go = make_ref(),
+ %% Spawn connection handler on test server side
+ Pid = spawn_link(
+ fun () ->
+ receive Go -> ok end,
+ tstsrvr_con_loop(Name, Socket, Parent)
+ end),
+ ok = gen_tcp:controlling_process(Socket, Pid),
+ Pid ! Go,
+ #node_handle{connection_handler = Pid,
+ socket = Socket,
+ name = Name};
+ _ ->
+ exit({unexpected_ssl_node_connected, NodeName})
+ end;
+ Msg ->
+ exit({unexpected_msg_instead_of_ssl_node_up, Name, Msg})
+ end.
+
+send_to_ssl_node(#node_handle{connection_handler = Hndlr}, Term) ->
+ Hndlr ! {relay_to_ssl_node, term_to_binary(Term)},
+ ok.
+
+tstsrvr_con_loop(Name, Socket, Parent) ->
+ inet:setopts(Socket,[{active,once}]),
+ receive
+ {relay_to_ssl_node, Data} when is_binary(Data) ->
+ case gen_tcp:send(Socket, Data) of
+ ok ->
+ ok;
+ _Error ->
+ gen_tcp:close(Socket),
+ exit({failed_to_relay_data_to_ssl_node, Name, Data})
+ end;
+ {tcp, Socket, Bin} ->
+ case catch binary_to_term(Bin) of
+ {'EXIT', _} ->
+ gen_tcp:close(Socket),
+ exit({bad_data_received_from_ssl_node, Name, Bin});
+ {format, FmtStr, ArgList} ->
+ ?t:format(FmtStr, ArgList);
+ {message, Msg} ->
+ Parent ! Msg;
+ {apply_res, To, Ref, Res} ->
+ To ! {Ref, Res};
+ bye ->
+ ?t:format("Ssl node ~s stopped.~n", [Name]),
+ gen_tcp:close(Socket),
+ exit(normal);
+ Unknown ->
+ exit({unexpected_message_from_ssl_node, Name, Unknown})
+ end;
+ {tcp_closed, Socket} ->
+ gen_tcp:close(Socket),
+ exit({lost_connection_with_ssl_node, Name})
+ end,
+ tstsrvr_con_loop(Name, Socket, Parent).
+
+%%
+%% Connection handler ssl_node side
+%%
+
+% cnct2tstsrvr() is called via command line arg -run ...
+cnct2tstsrvr([Host, Port]) when list(Host), list(Port) ->
+ %% Spawn connection handler on ssl node side
+ ConnHandler
+ = spawn(fun () ->
+ case catch gen_tcp:connect(Host,
+ list_to_integer(Port),
+ [binary,
+ {packet, 4},
+ {active, false}]) of
+ {ok, Socket} ->
+ notify_ssl_node_up(Socket),
+ ets:new(test_server_info,
+ [set,
+ public,
+ named_table,
+ {keypos, 1}]),
+ ets:insert(test_server_info,
+ {test_server_handler, self()}),
+ ssl_node_con_loop(Socket);
+ _Error ->
+ halt("Failed to connect to test server")
+ end
+ end),
+ spawn(fun () ->
+ Mon = erlang:monitor(process, ConnHandler),
+ receive
+ {'DOWN', Mon, process, ConnHandler, Reason} ->
+ receive after 1000 -> ok end,
+ halt("test server connection handler terminated: "
+ ++
+ lists:flatten(io_lib:format("~p", [Reason])))
+ end
+ end).
+
+notify_ssl_node_up(Socket) ->
+ case catch gen_tcp:send(Socket,
+ term_to_binary({ssl_node_up, node()})) of
+ ok -> ok;
+ _ -> halt("Failed to notify test server that I'm up")
+ end.
+
+send_to_tstsrvr(Term) ->
+ case catch ets:lookup_element(test_server_info, test_server_handler, 2) of
+ Hndlr when pid(Hndlr) ->
+ Hndlr ! {relay_to_test_server, term_to_binary(Term)}, ok;
+ _ ->
+ receive after 200 -> ok end,
+ send_to_tstsrvr(Term)
+ end.
+
+ssl_node_con_loop(Socket) ->
+ inet:setopts(Socket,[{active,once}]),
+ receive
+ {relay_to_test_server, Data} when is_binary(Data) ->
+ case gen_tcp:send(Socket, Data) of
+ ok ->
+ ok;
+ _Error ->
+ gen_tcp:close(Socket),
+ halt("Failed to relay data to test server")
+ end;
+ {tcp, Socket, Bin} ->
+ case catch binary_to_term(Bin) of
+ {'EXIT', _} ->
+ gen_tcp:close(Socket),
+ halt("test server sent me bad data");
+ {apply, From, Ref, M, F, A} ->
+ spawn_link(
+ fun () ->
+ send_to_tstsrvr({apply_res,
+ From,
+ Ref,
+ (catch apply(M, F, A))})
+ end);
+ {apply, From, Ref, Fun} ->
+ spawn_link(fun () ->
+ send_to_tstsrvr({apply_res,
+ From,
+ Ref,
+ (catch Fun())})
+ end);
+ stop ->
+ gen_tcp:send(Socket, term_to_binary(bye)),
+ gen_tcp:close(Socket),
+ init:stop(),
+ receive after infinity -> ok end;
+ _Unknown ->
+ halt("test server sent me an unexpected message")
+ end;
+ {tcp_closed, Socket} ->
+ halt("Lost connection to test server")
+ end,
+ ssl_node_con_loop(Socket).
+
+%%
+%% Setup ssl dist info
+%%
+
+rand_bin(N) ->
+ rand_bin(N, []).
+
+rand_bin(0, Acc) ->
+ Acc;
+rand_bin(N, Acc) ->
+ rand_bin(N-1, [random:uniform(256)-1|Acc]).
+
+make_randfile(Dir) ->
+ {ok, IoDev} = file:open(filename:join([Dir, "RAND"]), [write]),
+ {A, B, C} = erlang:now(),
+ random:seed(A, B, C),
+ ok = file:write(IoDev, rand_bin(1024)),
+ file:close(IoDev).
+
+append_files(FileNames, ResultFileName) ->
+ {ok, ResultFile} = file:open(ResultFileName, [write]),
+ do_append_files(FileNames, ResultFile).
+
+do_append_files([], RF) ->
+ ok = file:close(RF);
+do_append_files([F|Fs], RF) ->
+ {ok, Data} = file:read_file(F),
+ ok = file:write(RF, Data),
+ do_append_files(Fs, RF).
+
+setup_dist_opts(Name, PrivDir) ->
+ NodeDir = filename:join([PrivDir, Name]),
+ RGenDir = filename:join([NodeDir, "rand_gen"]),
+ ok = file:make_dir(NodeDir),
+ ok = file:make_dir(RGenDir),
+ make_randfile(RGenDir),
+ make_certs:all(RGenDir, NodeDir),
+ SDir = filename:join([NodeDir, "server"]),
+ SC = filename:join([SDir, "cert.pem"]),
+ SK = filename:join([SDir, "key.pem"]),
+ SKC = filename:join([SDir, "keycert.pem"]),
+ append_files([SK, SC], SKC),
+ CDir = filename:join([NodeDir, "client"]),
+ CC = filename:join([CDir, "cert.pem"]),
+ CK = filename:join([CDir, "key.pem"]),
+ CKC = filename:join([CDir, "keycert.pem"]),
+ append_files([CK, CC], CKC),
+ "-proto_dist inet_ssl "
+ ++ "-ssl_dist_opt server_certfile " ++ SKC ++ " "
+ ++ "-ssl_dist_opt client_certfile " ++ CKC ++ " "
+.% ++ "-ssl_dist_opt verify 1 depth 1".
+
+%%
+%% Start scripts etc...
+%%
+
+add_ssl_opts_config(Config) ->
+ %%
+ %% Start with boot scripts if on an installed system; otherwise,
+ %% just point out ssl ebin with -pa.
+ %%
+ try
+ Dir = ?config(priv_dir, Config),
+ LibDir = code:lib_dir(),
+ Apps = application:which_applications(),
+ {value, {stdlib, _, STDL_VSN}} = lists:keysearch(stdlib, 1, Apps),
+ {value, {kernel, _, KRNL_VSN}} = lists:keysearch(kernel, 1, Apps),
+ StdlDir = filename:join([LibDir, "stdlib-" ++ STDL_VSN]),
+ KrnlDir = filename:join([LibDir, "kernel-" ++ KRNL_VSN]),
+ {ok, _} = file:read_file_info(StdlDir),
+ {ok, _} = file:read_file_info(KrnlDir),
+ SSL_VSN = case lists:keysearch(ssl, 1, Apps) of
+ {value, {ssl, _, VSN}} ->
+ VSN;
+ _ ->
+ application:start(ssl),
+ try
+ {value,
+ {ssl,
+ _,
+ VSN}} = lists:keysearch(ssl,
+ 1,
+ application:which_applications()),
+ VSN
+ after
+ application:stop(ssl)
+ end
+ end,
+ SslDir = filename:join([LibDir, "ssl-" ++ SSL_VSN]),
+ {ok, _} = file:read_file_info(SslDir),
+ %% We are using an installed otp system, create the boot script.
+ Script = filename:join(Dir, atom_to_list(?MODULE)),
+ {ok, RelFile} = file:open(Script ++ ".rel", [write]),
+ io:format(RelFile,
+ "{release, ~n"
+ " {\"SSL distribution test release\", \"~s\"},~n"
+ " {erts, \"~s\"},~n"
+ " [{kernel, \"~s\"},~n"
+ " {stdlib, \"~s\"},~n"
+ " {ssl, \"~s\"}]}.~n",
+ [case catch erlang:system_info(otp_release) of
+ {'EXIT', _} -> "R11B";
+ Rel -> Rel
+ end,
+ erlang:system_info(version),
+ KRNL_VSN,
+ STDL_VSN,
+ SSL_VSN]),
+ ok = file:close(RelFile),
+ ok = systools:make_script(Script, []),
+ [{ssl_opts, "-boot " ++ Script} | Config]
+ catch
+ _:_ ->
+ [{ssl_opts, "-pa " ++ filename:dirname(code:which(ssl))}
+ | add_comment_config(
+ "Bootscript wasn't used since the test wasn't run on an "
+ "installed OTP system.",
+ Config)]
+ end.
+
+%%
+%% Add common comments to config
+%%
+
+add_comment_config(Comment, []) ->
+ [{comment, Comment}];
+add_comment_config(Comment, [{comment, OldComment} | Cs]) ->
+ [{comment, Comment ++ " " ++ OldComment} | Cs];
+add_comment_config(Comment, [C|Cs]) ->
+ [C|add_comment_config(Comment, Cs)].
+
+%%
+%% Call when test case success
+%%
+
+success(Config) ->
+ case lists:keysearch(comment, 1, Config) of
+ {value, {comment, _} = Res} -> Res;
+ _ -> ok
+ end.
diff --git a/lib/ssl/test/old_ssl_misc_SUITE.erl b/lib/ssl/test/old_ssl_misc_SUITE.erl
new file mode 100644
index 0000000000..55d1b71025
--- /dev/null
+++ b/lib/ssl/test/old_ssl_misc_SUITE.erl
@@ -0,0 +1,105 @@
+%%
+%% %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(old_ssl_misc_SUITE).
+
+-export([all/1,
+ init_per_testcase/2,
+ fin_per_testcase/2,
+ config/1,
+ finish/1,
+ seed/1,
+ app/1
+ ]).
+
+-import(ssl_test_MACHINE, [mk_ssl_cert_opts/1, test_one_listener/7,
+ test_server_only/6]).
+-include("test_server.hrl").
+-include("ssl_test_MACHINE.hrl").
+
+-define(MANYCONNS, 5).
+
+init_per_testcase(_Case, Config) ->
+ WatchDog = ssl_test_lib:timetrap(?DEFAULT_TIMEOUT),
+ [{watchdog, WatchDog}| Config].
+
+fin_per_testcase(_Case, Config) ->
+ WatchDog = ?config(watchdog, Config),
+ test_server:timetrap_cancel(WatchDog).
+
+all(doc) ->
+ "Test of misc in ssl.erl interface.";
+all(suite) ->
+ {conf,
+ config,
+ [seed, app],
+ finish
+ }.
+
+config(doc) ->
+ "Want to se what Config contains.";
+config(suite) ->
+ [];
+config(Config) ->
+ io:format("Config: ~p~n", [Config]),
+
+ %% Check if SSL exists. If this case fails, all other cases are skipped
+ case ssl:start() of
+ ok -> ssl:stop();
+ {error, {already_started, _}} -> ssl:stop();
+ Error -> ?t:fail({failed_starting_ssl,Error})
+ end,
+ Config.
+
+finish(doc) ->
+ "This test case has no mission other than closing the conf case";
+finish(suite) ->
+ [];
+finish(Config) ->
+ Config.
+
+seed(doc) ->
+ "Test that ssl:seed/1 works.";
+seed(suite) ->
+ [];
+seed(Config) when list(Config) ->
+ process_flag(trap_exit, true),
+ LPort = 3456,
+ Timeout = 40000, NConns = 1,
+
+ ?line {ok, {_, SsslOpts}} = mk_ssl_cert_opts(Config),
+
+ LCmds = [{seed, "tjosan"},
+ {sockopts, [{backlog, NConns}, {active, once}]},
+ {sslopts, SsslOpts},
+ {listen, LPort},
+ wait_sync,
+ lclose],
+ ?line test_server_only(NConns, LCmds, [], Timeout, ?MODULE,
+ Config).
+
+app(doc) ->
+ "Test that the ssl app file is ok";
+app(suite) ->
+ [];
+app(Config) when list(Config) ->
+ ?line ok = test_server:app_test(ssl).
+
+
diff --git a/lib/ssl/test/old_ssl_passive_SUITE.erl b/lib/ssl/test/old_ssl_passive_SUITE.erl
new file mode 100644
index 0000000000..4cb8c1f0cd
--- /dev/null
+++ b/lib/ssl/test/old_ssl_passive_SUITE.erl
@@ -0,0 +1,374 @@
+%%
+%% %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(old_ssl_passive_SUITE).
+
+-export([all/1,
+ init_per_testcase/2,
+ fin_per_testcase/2,
+ config/1,
+ finish/1,
+ server_accept_timeout/1,
+ cinit_return_chkclose/1,
+ sinit_return_chkclose/1,
+ cinit_big_return_chkclose/1,
+ sinit_big_return_chkclose/1,
+ cinit_big_echo_chkclose/1,
+ sinit_big_echo_chkclose/1,
+ cinit_few_echo_chkclose/1,
+ cinit_many_echo_chkclose/1,
+ cinit_cnocert/1
+ ]).
+
+-import(ssl_test_MACHINE, [mk_ssl_cert_opts/1, test_one_listener/7,
+ test_server_only/6]).
+
+-include("test_server.hrl").
+-include("ssl_test_MACHINE.hrl").
+
+-define(MANYCONNS, ssl_test_MACHINE:many_conns()).
+
+init_per_testcase(_Case, Config) ->
+ WatchDog = ssl_test_lib:timetrap(?DEFAULT_TIMEOUT),
+ [{watchdog, WatchDog}| Config].
+
+fin_per_testcase(_Case, Config) ->
+ WatchDog = ?config(watchdog, Config),
+ test_server:timetrap_cancel(WatchDog).
+
+all(doc) ->
+ "Test of ssl.erl interface in passive mode.";
+all(suite) ->
+ {conf,
+ config,
+ [server_accept_timeout,
+ cinit_return_chkclose,
+ sinit_return_chkclose,
+ cinit_big_return_chkclose,
+ sinit_big_return_chkclose,
+ cinit_big_echo_chkclose,
+ sinit_big_echo_chkclose,
+ cinit_few_echo_chkclose,
+ cinit_many_echo_chkclose,
+ cinit_cnocert],
+ finish}.
+
+config(doc) ->
+ "Want to se what Config contains.";
+config(suite) ->
+ [];
+config(Config) ->
+ io:format("Config: ~p~n", [Config]),
+
+ %% Check if SSL exists. If this case fails, all other cases are skipped
+ case ssl:start() of
+ ok -> ssl:stop();
+ {error, {already_started, _}} -> ssl:stop();
+ Error -> ?t:fail({failed_starting_ssl,Error})
+ end,
+ Config.
+
+finish(doc) ->
+ "This test case has no mission other than closing the conf case";
+finish(suite) ->
+ [];
+finish(Config) ->
+ Config.
+
+server_accept_timeout(doc) ->
+ "Server has one pending accept with timeout. Checks that return "
+ "value is {error, timeout}.";
+server_accept_timeout(suite) ->
+ [];
+server_accept_timeout(Config) when list(Config) ->
+ process_flag(trap_exit, true),
+ LPort = 3456,
+ Timeout = 40000, NConns = 1,
+ AccTimeout = 3000,
+
+ ?line {ok, {_, SsslOpts}} = mk_ssl_cert_opts(Config),
+
+ LCmds = [{sockopts, [{backlog, NConns}, {active, false}]},
+ {sslopts, SsslOpts},
+ {listen, LPort},
+ wait_sync,
+ lclose],
+ ACmds = [{timeout, AccTimeout},
+ accept_timeout],
+ ?line test_server_only(NConns, LCmds, ACmds, Timeout, ?MODULE, Config).
+
+cinit_return_chkclose(doc) ->
+ "Client sends 1000 bytes to server, that receives them, sends them "
+ "back, and closes. Client waits for close. Both have certs.";
+cinit_return_chkclose(suite) ->
+ [];
+cinit_return_chkclose(Config) when list(Config) ->
+ process_flag(trap_exit, true),
+ DataSize = 1000, LPort = 3456,
+ Timeout = 40000, NConns = 1,
+
+ ?line {ok, {CsslOpts, SsslOpts}} = mk_ssl_cert_opts(Config),
+ ?line {ok, Host} = inet:gethostname(),
+
+ LCmds = [{sockopts, [{backlog, NConns}, {active, false}]},
+ {sslopts, SsslOpts},
+ {listen, LPort},
+ wait_sync,
+ lclose],
+ ACmds = [{timeout, Timeout},
+ accept,
+ {recv, DataSize}, {send, DataSize},
+ close],
+ CCmds = [{timeout, Timeout},
+ {sockopts, [{active, false}]},
+ {sslopts, CsslOpts},
+ {connect, {Host, LPort}},
+ {send, DataSize}, {recv, DataSize},
+ await_close],
+ ?line test_one_listener(NConns, LCmds, ACmds, CCmds, Timeout, ?MODULE,
+ Config).
+
+sinit_return_chkclose(doc) ->
+ "Server sends 1000 bytes to client, that receives them, sends them "
+ "back, and closes. Server waits for close. Both have certs.";
+sinit_return_chkclose(suite) ->
+ [];
+sinit_return_chkclose(Config) when list(Config) ->
+ process_flag(trap_exit, true),
+ DataSize = 1000, LPort = 3456,
+ Timeout = 40000, NConns = 1,
+
+ ?line {ok, {CsslOpts, SsslOpts}} = mk_ssl_cert_opts(Config),
+ ?line {ok, Host} = inet:gethostname(),
+
+ LCmds = [{sockopts, [{backlog, NConns}, {active, false}]},
+ {sslopts, SsslOpts},
+ {listen, LPort},
+ wait_sync,
+ lclose],
+ ACmds = [{timeout, Timeout},
+ accept,
+ {send, DataSize}, {recv, DataSize},
+ await_close],
+ CCmds = [{timeout, Timeout},
+ {sockopts, [{active, false}]},
+ {sslopts, CsslOpts},
+ {connect, {Host, LPort}},
+ {recv, DataSize}, {send, DataSize},
+ close],
+
+ ?line test_one_listener(NConns, LCmds, ACmds, CCmds, Timeout, ?MODULE,
+ Config).
+
+cinit_big_return_chkclose(doc) ->
+ "Client sends 50000 bytes to server, that receives them, sends them "
+ "back, and closes. Client waits for close. Both have certs.";
+cinit_big_return_chkclose(suite) ->
+ [];
+cinit_big_return_chkclose(Config) when list(Config) ->
+ process_flag(trap_exit, true),
+ DataSize = 50000, LPort = 3456,
+ Timeout = 40000, NConns = 1,
+
+ ?line {ok, {CsslOpts, SsslOpts}} = mk_ssl_cert_opts(Config),
+ ?line {ok, Host} = inet:gethostname(),
+
+ LCmds = [{sockopts, [{backlog, NConns}, {active, false}]},
+ {sslopts, SsslOpts},
+ {listen, LPort},
+ wait_sync,
+ lclose],
+ ACmds = [{timeout, Timeout},
+ accept,
+ {recv, DataSize}, {send, DataSize},
+ close],
+ CCmds = [{timeout, Timeout},
+ {sockopts, [{active, false}]},
+ {sslopts, CsslOpts},
+ {connect, {Host, LPort}},
+ {send, DataSize}, {recv, DataSize},
+ await_close],
+ ?line test_one_listener(NConns, LCmds, ACmds, CCmds, Timeout, ?MODULE,
+ Config).
+
+sinit_big_return_chkclose(doc) ->
+ "Server sends 50000 bytes to client, that receives them, sends them "
+ "back, and closes. Server waits for close. Both have certs.";
+sinit_big_return_chkclose(suite) ->
+ [];
+sinit_big_return_chkclose(Config) when list(Config) ->
+ process_flag(trap_exit, true),
+ DataSize = 50000, LPort = 3456,
+ Timeout = 40000, NConns = 1,
+
+ ?line {ok, {CsslOpts, SsslOpts}} = mk_ssl_cert_opts(Config),
+ ?line {ok, Host} = inet:gethostname(),
+
+ LCmds = [{sockopts, [{backlog, NConns}, {active, false}]},
+ {sslopts, SsslOpts},
+ {listen, LPort},
+ wait_sync,
+ lclose],
+ ACmds = [{timeout, Timeout},
+ accept,
+ {send, DataSize}, {recv, DataSize},
+ await_close],
+ CCmds = [{timeout, Timeout},
+ {sockopts, [{active, false}]},
+ {sslopts, CsslOpts},
+ {connect, {Host, LPort}},
+ {recv, DataSize}, {send, DataSize},
+ close],
+
+ ?line test_one_listener(NConns, LCmds, ACmds, CCmds, Timeout, ?MODULE,
+ Config).
+
+cinit_big_echo_chkclose(doc) ->
+ "Client sends 50000 bytes to server, that echoes them back "
+ "and closes. Client waits for close. Both have certs.";
+cinit_big_echo_chkclose(suite) ->
+ [];
+cinit_big_echo_chkclose(Config) when list(Config) ->
+ process_flag(trap_exit, true),
+ DataSize = 50000, LPort = 3456,
+ Timeout = 40000, NConns = 1,
+
+ ?line {ok, {CsslOpts, SsslOpts}} = mk_ssl_cert_opts(Config),
+ ?line {ok, Host} = inet:gethostname(),
+
+ LCmds = [{sockopts, [{backlog, NConns}, {active, false}]},
+ {sslopts, SsslOpts},
+ {listen, LPort},
+ wait_sync,
+ lclose],
+ ACmds = [{timeout, Timeout},
+ accept,
+ {echo, DataSize},
+ close],
+ CCmds = [{timeout, Timeout},
+ {sockopts, [{active, false}]},
+ {sslopts, CsslOpts},
+ {connect, {Host, LPort}},
+ {send, DataSize}, {recv, DataSize},
+ await_close],
+ ?line test_one_listener(NConns, LCmds, ACmds, CCmds, Timeout, ?MODULE,
+ Config).
+
+sinit_big_echo_chkclose(doc) ->
+ "Server sends 50000 bytes to client, that echoes them back "
+ "and closes. Server waits for close. Both have certs.";
+sinit_big_echo_chkclose(suite) ->
+ [];
+sinit_big_echo_chkclose(Config) when list(Config) ->
+ process_flag(trap_exit, true),
+ DataSize = 50000, LPort = 3456,
+ Timeout = 40000, NConns = 1,
+
+ ?line {ok, {CsslOpts, SsslOpts}} = mk_ssl_cert_opts(Config),
+ ?line {ok, Host} = inet:gethostname(),
+
+ LCmds = [{sockopts, [{backlog, NConns}, {active, false}]},
+ {sslopts, SsslOpts},
+ {listen, LPort},
+ wait_sync,
+ lclose],
+ ACmds = [{timeout, Timeout},
+ accept,
+ {send, DataSize}, {recv, DataSize},
+ await_close],
+ CCmds = [{timeout, Timeout},
+ {sockopts, [{active, false}]},
+ {sslopts, CsslOpts},
+ {connect, {Host, LPort}},
+ {echo, DataSize},
+ close],
+
+ ?line test_one_listener(NConns, LCmds, ACmds, CCmds, Timeout, ?MODULE,
+ Config).
+
+
+cinit_few_echo_chkclose(X) -> cinit_many_echo_chkclose(X, 7).
+
+cinit_many_echo_chkclose(X) -> cinit_many_echo_chkclose(X, ?MANYCONNS).
+
+cinit_many_echo_chkclose(doc, _NConns) ->
+ "clients send 10000 bytes to server, that echoes them back "
+ "and closes. Clients wait for close. All have certs.";
+cinit_many_echo_chkclose(suite, _NConns) ->
+ [];
+cinit_many_echo_chkclose(Config, NConns) when list(Config) ->
+ process_flag(trap_exit, true),
+ DataSize = 10000, LPort = 3456,
+ Timeout = 80000,
+
+ io:format("~w connections", [NConns]),
+
+ ?line {ok, {CsslOpts, SsslOpts}} = mk_ssl_cert_opts(Config),
+ ?line {ok, Host} = inet:gethostname(),
+
+ LCmds = [{sockopts, [{backlog, NConns}, {active, false}]},
+ {sslopts, SsslOpts},
+ {listen, LPort},
+ wait_sync,
+ lclose],
+ ACmds = [{timeout, Timeout},
+ accept,
+ {echo, DataSize},
+ close],
+ CCmds = [{timeout, Timeout},
+ {sockopts, [{active, false}]},
+ {sslopts, CsslOpts},
+ {connect, {Host, LPort}},
+ {send, DataSize}, {recv, DataSize},
+ await_close],
+ ?line test_one_listener(NConns, LCmds, ACmds, CCmds, Timeout, ?MODULE,
+ Config).
+
+cinit_cnocert(doc) ->
+ "Client sends 1000 bytes to server, that receives them, sends them "
+ "back, and closes. Client waits for close. Client has no cert, "
+ "but server has.";
+cinit_cnocert(suite) ->
+ [];
+cinit_cnocert(Config) when list(Config) ->
+ process_flag(trap_exit, true),
+ DataSize = 1000, LPort = 3457,
+ Timeout = 40000, NConns = 1,
+
+ ?line {ok, {_CsslOpts, SsslOpts}} = mk_ssl_cert_opts(Config),
+ ?line {ok, Host} = inet:gethostname(),
+
+ LCmds = [{sockopts, [{backlog, NConns}, {active, false}]},
+ {sslopts, SsslOpts},
+ {listen, LPort},
+ wait_sync,
+ lclose],
+ ACmds = [{timeout, Timeout},
+ accept,
+ {recv, DataSize}, {send, DataSize},
+ close],
+ CCmds = [{timeout, Timeout},
+ {sockopts, [{active, false}]},
+ {connect, {Host, LPort}},
+ {send, DataSize}, {recv, DataSize},
+ await_close],
+ ?line test_one_listener(NConns, LCmds, ACmds, CCmds, Timeout, ?MODULE,
+ Config).
+
diff --git a/lib/ssl/test/old_ssl_peer_cert_SUITE.erl b/lib/ssl/test/old_ssl_peer_cert_SUITE.erl
new file mode 100644
index 0000000000..f0b8db2607
--- /dev/null
+++ b/lib/ssl/test/old_ssl_peer_cert_SUITE.erl
@@ -0,0 +1,180 @@
+%%
+%% %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(old_ssl_peer_cert_SUITE).
+
+-export([all/1,
+ init_per_testcase/2,
+ fin_per_testcase/2,
+ config/1,
+ finish/1,
+ cinit_plain/1,
+ cinit_both_verify/1,
+ cinit_cnocert/1
+ ]).
+
+-import(ssl_test_MACHINE, [mk_ssl_cert_opts/1, test_one_listener/7,
+ test_server_only/6]).
+-include("test_server.hrl").
+-include("ssl_test_MACHINE.hrl").
+
+
+init_per_testcase(_Case, Config) ->
+ WatchDog = ssl_test_lib:timetrap(?DEFAULT_TIMEOUT),
+ [{watchdog, WatchDog}| Config].
+
+fin_per_testcase(_Case, Config) ->
+ WatchDog = ?config(watchdog, Config),
+ test_server:timetrap_cancel(WatchDog).
+
+all(doc) ->
+ "Test of ssl verification and peer certificate retrieval.";
+all(suite) ->
+ {conf,
+ config,
+ [cinit_plain,
+ cinit_both_verify,
+ cinit_cnocert],
+ finish}.
+
+config(doc) ->
+ "Want to se what Config contains.";
+config(suite) ->
+ [];
+config(Config) ->
+ io:format("Config: ~p~n", [Config]),
+
+ %% Check if SSL exists. If this case fails, all other cases are skipped
+ case ssl:start() of
+ ok -> ssl:stop();
+ {error, {already_started, _}} -> ssl:stop();
+ Error -> ?t:fail({failed_starting_ssl,Error})
+ end,
+ Config.
+
+finish(doc) ->
+ "This test case has no mission other than closing the conf case";
+finish(suite) ->
+ [];
+finish(Config) ->
+ Config.
+
+cinit_plain(doc) ->
+ "Server closes after accept, Client waits for close. Both have certs "
+ "but both use the defaults for verify and depth, but still tries "
+ "to retreive each others certificates.";
+cinit_plain(suite) ->
+ [];
+cinit_plain(Config) when list(Config) ->
+ process_flag(trap_exit, true),
+ DataSize = 1000, LPort = 3456,
+ Timeout = 40000, NConns = 1,
+
+ ?line {ok, {CsslOpts, SsslOpts}} = mk_ssl_cert_opts(Config),
+
+ ?line {ok, Host} = inet:gethostname(),
+
+ LCmds = [{sockopts, [{backlog, NConns}]},
+ {sslopts, SsslOpts},
+ {listen, LPort},
+ wait_sync,
+ lclose],
+ ACmds = [{timeout, Timeout},
+ accept,
+ nopeercert,
+ {recv, DataSize},
+ close],
+ CCmds = [{timeout, Timeout},
+ {sslopts, CsslOpts},
+ {connect, {Host, LPort}},
+ peercert,
+ {send, DataSize},
+ await_close],
+ ?line test_one_listener(NConns, LCmds, ACmds, CCmds, Timeout,
+ ?MODULE, Config).
+
+cinit_both_verify(doc) ->
+ "Server closes after accept, Client waits for close. Both have certs "
+ "and both verify each other.";
+cinit_both_verify(suite) ->
+ [];
+cinit_both_verify(Config) when list(Config) ->
+ process_flag(trap_exit, true),
+ DataSize = 1000, LPort = 3456,
+ Timeout = 40000, NConns = 1,
+
+ ?line {ok, {CsslOpts0, SsslOpts0}} = mk_ssl_cert_opts(Config),
+ ?line CsslOpts = [{verify, 2}, {depth, 2} | CsslOpts0],
+ ?line SsslOpts = [{verify, 2}, {depth, 3} | SsslOpts0],
+
+ ?line {ok, Host} = inet:gethostname(),
+
+ LCmds = [{sockopts, [{backlog, NConns}]},
+ {sslopts, SsslOpts},
+ {listen, LPort},
+ wait_sync,
+ lclose],
+ ACmds = [{timeout, Timeout},
+ accept,
+ peercert,
+ {recv, DataSize},
+ close],
+ CCmds = [{timeout, Timeout},
+ {sslopts, CsslOpts},
+ {connect, {Host, LPort}},
+ peercert,
+ {send, DataSize},
+ await_close],
+ ?line test_one_listener(NConns, LCmds, ACmds, CCmds, Timeout,
+ ?MODULE, Config).
+
+cinit_cnocert(doc) ->
+ "Client has no cert. Nor the client, nor the server is verifying its "
+ "peer. Server closes, client waits for close.";
+cinit_cnocert(suite) ->
+ [];
+cinit_cnocert(Config) when list(Config) ->
+ process_flag(trap_exit, true),
+ DataSize = 1000, LPort = 3457,
+ Timeout = 40000, NConns = 1,
+
+ ?line {ok, {_, SsslOpts0}} = mk_ssl_cert_opts(Config),
+ ?line SsslOpts = [{verify, 0}, {depth, 2} | SsslOpts0],
+
+ ?line {ok, Host} = inet:gethostname(),
+
+ LCmds = [{sockopts, [{backlog, NConns}]},
+ {sslopts, SsslOpts},
+ {listen, LPort},
+ wait_sync,
+ lclose],
+ ACmds = [{timeout, Timeout},
+ accept,
+ {recv, DataSize},
+ close],
+ CCmds = [{timeout, Timeout},
+ {connect, {Host, LPort}},
+ peercert,
+ {send, DataSize},
+ await_close],
+ ?line test_one_listener(NConns, LCmds, ACmds, CCmds, Timeout,
+ ?MODULE, Config).
+
+
diff --git a/lib/ssl/test/old_ssl_protocol_SUITE.erl b/lib/ssl/test/old_ssl_protocol_SUITE.erl
new file mode 100644
index 0000000000..7bde5d6749
--- /dev/null
+++ b/lib/ssl/test/old_ssl_protocol_SUITE.erl
@@ -0,0 +1,169 @@
+%%
+%% %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%
+%%
+
+%%
+-module(old_ssl_protocol_SUITE).
+
+-export([all/1, init_per_testcase/2, fin_per_testcase/2, config/1,
+ finish/1, sslv2/1, sslv3/1, tlsv1/1, sslv2_sslv3/1,
+ sslv2_tlsv1/1, sslv3_tlsv1/1, sslv2_sslv3_tlsv1/1]).
+
+-import(ssl_test_MACHINE, [mk_ssl_cert_opts/1, test_one_listener/7,
+ test_server_only/6]).
+-include("test_server.hrl").
+-include("ssl_test_MACHINE.hrl").
+
+
+init_per_testcase(_Case, Config) ->
+ WatchDog = test_server:timetrap(?DEFAULT_TIMEOUT),
+ [{watchdog, WatchDog}| Config].
+
+fin_per_testcase(_Case, Config) ->
+ WatchDog = ?config(watchdog, Config),
+ test_server:timetrap_cancel(WatchDog).
+
+all(doc) ->
+ "Test of configuration protocol_version.";
+all(suite) ->
+ {conf,
+ config,
+ [sslv2, sslv3, tlsv1, sslv2_sslv3, sslv2_tlsv1, sslv3_tlsv1,
+ sslv2_sslv3_tlsv1],
+ finish}.
+
+config(doc) ->
+ "Want to se what Config contains.";
+config(suite) ->
+ [];
+config(Config) ->
+ io:format("Config: ~p~n", [Config]),
+
+ %% Check if SSL exists. If this case fails, all other cases are skipped
+ case ssl:start() of
+ ok -> ssl:stop();
+ {error, {already_started, _}} -> ssl:stop();
+ Error -> ?t:fail({failed_starting_ssl,Error})
+ end,
+ Config.
+
+finish(doc) ->
+ "This test case has no other purpose than closing the conf case.";
+finish(suite) ->
+ [];
+finish(Config) ->
+ Config.
+
+%%%%%
+
+sslv2(doc) ->
+ "Client has no cert. Nor the client, nor the server is verifying its "
+ "peer. Server closes, client waits for close. "
+ "Client and server choose SSLv2.";
+sslv2(suite) ->
+ [];
+sslv2(Config) when list(Config) ->
+ do_run_test(Config, [sslv2]).
+
+sslv3(doc) ->
+ "Client has no cert. Nor the client, nor the server is verifying its "
+ "peer. Server closes, client waits for close. "
+ "Client and server choose SSLv3.";
+sslv3(suite) ->
+ [];
+sslv3(Config) when list(Config) ->
+ do_run_test(Config, [sslv3]).
+
+tlsv1(doc) ->
+ "Client has no cert. Nor the client, nor the server is verifying its "
+ "peer. Server closes, client waits for close. "
+ "Client and server choose TLSv1.";
+tlsv1(suite) ->
+ [];
+tlsv1(Config) when list(Config) ->
+ do_run_test(Config, [tlsv1]).
+
+sslv2_sslv3(doc) ->
+ "Client has no cert. Nor the client, nor the server is verifying its "
+ "peer. Server closes, client waits for close. "
+ "Client and server choose between SSLv2 and SSLv3.";
+sslv2_sslv3(suite) ->
+ [];
+sslv2_sslv3(Config) when list(Config) ->
+ do_run_test(Config, [sslv2, sslv3]).
+
+sslv2_tlsv1(doc) ->
+ "Client has no cert. Nor the client, nor the server is verifying its "
+ "peer. Server closes, client waits for close. "
+ "Client and server choose between SSLv2 and TLSv1.";
+sslv2_tlsv1(suite) ->
+ [];
+sslv2_tlsv1(Config) when list(Config) ->
+ do_run_test(Config, [sslv2, tlsv1]).
+
+sslv3_tlsv1(doc) ->
+ "Client has no cert. Nor the client, nor the server is verifying its "
+ "peer. Server closes, client waits for close. "
+ "Client and server choose between SSLv3 and TLSv1.";
+sslv3_tlsv1(suite) ->
+ [];
+sslv3_tlsv1(Config) when list(Config) ->
+ do_run_test(Config, [sslv3, tlsv1]).
+
+sslv2_sslv3_tlsv1(doc) ->
+ "Client has no cert. Nor the client, nor the server is verifying its "
+ "peer. Server closes, client waits for close. "
+ "Client and server choose between SSLv2, SSLv3, and TLSv1.";
+sslv2_sslv3_tlsv1(suite) ->
+ [];
+sslv2_sslv3_tlsv1(Config) when list(Config) ->
+ do_run_test(Config, [sslv2, sslv3, tlsv1]).
+
+%%%%
+
+do_run_test(Config0, Protocols) ->
+ process_flag(trap_exit, true),
+ LPort = 3456,
+ Timeout = 40000, NConns = 1,
+ DataSize = 10,
+
+ ?line {ok, {_, SsslOpts0}} = mk_ssl_cert_opts(Config0),
+ ?line SsslOpts = [{verify, 0}, {depth, 2} | SsslOpts0],
+
+ ?line {ok, Host} = inet:gethostname(),
+
+ LCmds = [{sockopts, [{backlog, NConns}]},
+ {sslopts, SsslOpts},
+ {listen, LPort},
+ wait_sync,
+ lclose],
+ ACmds = [{timeout, Timeout},
+ accept,
+ connection_info,
+ {recv, DataSize},
+ close],
+ CCmds = [{timeout, Timeout},
+ {connect, {Host, LPort}},
+ connection_info,
+ {send, DataSize},
+ await_close],
+ Config1 = [{env, [{protocol_version, Protocols}]} | Config0],
+ ?line test_one_listener(NConns, LCmds, ACmds, CCmds, Timeout,
+ ?MODULE, Config1).
+
+
diff --git a/lib/ssl/test/old_ssl_verify_SUITE.erl b/lib/ssl/test/old_ssl_verify_SUITE.erl
new file mode 100644
index 0000000000..5db964526f
--- /dev/null
+++ b/lib/ssl/test/old_ssl_verify_SUITE.erl
@@ -0,0 +1,141 @@
+%%
+%% %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(old_ssl_verify_SUITE).
+
+-export([all/1,
+ init_per_testcase/2,
+ fin_per_testcase/2,
+ config/1,
+ finish/1,
+ cinit_both_verify/1,
+ cinit_cnocert/1
+ ]).
+
+-import(ssl_test_MACHINE, [mk_ssl_cert_opts/1, test_one_listener/7,
+ test_server_only/6]).
+-include("test_server.hrl").
+-include("ssl_test_MACHINE.hrl").
+
+
+init_per_testcase(_Case, Config) ->
+ WatchDog = ssl_test_lib:timetrap(?DEFAULT_TIMEOUT),
+ [{watchdog, WatchDog}| Config].
+
+fin_per_testcase(_Case, Config) ->
+ WatchDog = ?config(watchdog, Config),
+ test_server:timetrap_cancel(WatchDog).
+
+all(doc) ->
+ "Test of ssl.erl interface in active mode.";
+all(suite) ->
+ {conf,
+ config,
+ [cinit_both_verify,
+ cinit_cnocert],
+ finish}.
+
+config(doc) ->
+ "Want to se what Config contains.";
+config(suite) ->
+ [];
+config(Config) ->
+ io:format("Config: ~p~n", [Config]),
+
+ %% Check if SSL exists. If this case fails, all other cases are skipped
+ case ssl:start() of
+ ok -> ssl:stop();
+ {error, {already_started, _}} -> ssl:stop();
+ Error -> ?t:fail({failed_starting_ssl,Error})
+ end,
+ Config.
+
+finish(doc) ->
+ "This test case has no mission other than closing the conf case";
+finish(suite) ->
+ [];
+finish(Config) ->
+ Config.
+
+cinit_both_verify(doc) ->
+ "Server closes after accept, Client waits for close. Both have certs "
+ "and both verify each other.";
+cinit_both_verify(suite) ->
+ [];
+cinit_both_verify(Config) when list(Config) ->
+ process_flag(trap_exit, true),
+ DataSize = 1000, LPort = 3456,
+ Timeout = 40000, NConns = 1,
+
+ ?line {ok, {CsslOpts0, SsslOpts0}} = mk_ssl_cert_opts(Config),
+ ?line CsslOpts = [{verify, 2}, {depth, 2} | CsslOpts0],
+ ?line SsslOpts = [{verify, 2}, {depth, 3} | SsslOpts0],
+
+ ?line {ok, Host} = inet:gethostname(),
+
+ LCmds = [{sockopts, [{backlog, NConns}]},
+ {sslopts, SsslOpts},
+ {listen, LPort},
+ wait_sync,
+ lclose],
+ ACmds = [{timeout, Timeout},
+ accept,
+ {recv, DataSize},
+ close],
+ CCmds = [{timeout, Timeout},
+ {sslopts, CsslOpts},
+ {connect, {Host, LPort}},
+ {send, DataSize},
+ await_close],
+ ?line test_one_listener(NConns, LCmds, ACmds, CCmds, Timeout,
+ ?MODULE, Config).
+
+cinit_cnocert(doc) ->
+ "Client has no cert. Nor the client, nor the server is verifying its "
+ "peer. Server closes, client waits for close.";
+cinit_cnocert(suite) ->
+ [];
+cinit_cnocert(Config) when list(Config) ->
+ process_flag(trap_exit, true),
+ DataSize = 1000, LPort = 3457,
+ Timeout = 40000, NConns = 1,
+
+ ?line {ok, {_, SsslOpts0}} = mk_ssl_cert_opts(Config),
+ ?line SsslOpts = [{verify, 0}, {depth, 2} | SsslOpts0],
+
+ ?line {ok, Host} = inet:gethostname(),
+
+ LCmds = [{sockopts, [{backlog, NConns}]},
+ {sslopts, SsslOpts},
+ {listen, LPort},
+ wait_sync,
+ lclose],
+ ACmds = [{timeout, Timeout},
+ accept,
+ {recv, DataSize},
+ close],
+ CCmds = [{timeout, Timeout},
+ {connect, {Host, LPort}},
+ {send, DataSize},
+ await_close],
+ ?line test_one_listener(NConns, LCmds, ACmds, CCmds, Timeout,
+ ?MODULE, Config).
+
+
diff --git a/lib/ssl/test/old_transport_accept_SUITE.erl b/lib/ssl/test/old_transport_accept_SUITE.erl
new file mode 100644
index 0000000000..4bb09cee19
--- /dev/null
+++ b/lib/ssl/test/old_transport_accept_SUITE.erl
@@ -0,0 +1,238 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 2007-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(old_transport_accept_SUITE).
+-include("test_server.hrl").
+-include("test_server_line.hrl").
+
+%% Default timetrap timeout (set in init_per_testcase).
+-define(default_timeout, ?t:minutes(1)).
+-define(application, ssh).
+
+-export([all/1,
+ init_per_testcase/2,
+ fin_per_testcase/2,
+ config/1,
+ echo_once/1,
+ echo_twice/1,
+ close_before_ssl_accept/1,
+ server/5,
+ tolerant_server/5,
+ client/5
+ ]).
+
+init_per_testcase(_Case, Config) ->
+ WatchDog = ssl_test_lib:timetrap(?default_timeout),
+ [{watchdog, WatchDog}, {protomod, gen_tcp}, {serialize_accept, true}|
+ Config].
+
+fin_per_testcase(_Case, Config) ->
+ WatchDog = ?config(watchdog, Config),
+ test_server:timetrap_cancel(WatchDog).
+
+all(doc) ->
+ "Test transport_accept and ssl_accept";
+all(suite) ->
+ [config, echo_once, echo_twice, close_before_ssl_accept].
+
+config(doc) ->
+ "Want to se what Config contains.";
+config(suite) ->
+ [];
+config(Config) ->
+ io:format("Config: ~p~n", [Config]),
+ ok.
+
+echo_once(doc) ->
+ "Client sends 256 bytes to server, that receives them, sends them "
+ "back, and closes. Client waits for close. Both have certs.";
+echo_once(suite) ->
+ [];
+echo_once(Config) when list(Config) ->
+ process_flag(trap_exit, true),
+ LPort = 3456,
+ {ok, Host} = inet:gethostname(),
+ {ok, {COpts, SOpts}} = ssl_test_MACHINE:mk_ssl_cert_opts(Config),
+ N = 1,
+ Msg = lists:seq(0, 255),
+ Self = self(),
+ Params = "-pa " ++ filename:dirname(code:which(?MODULE)),
+ Node = start_node(server, Params),
+ CNode = start_node(client, Params),
+ Server = spawn_link(Node, ?MODULE, server, [Self, LPort, SOpts, Msg, N]),
+ Client = spawn_link(Node, ?MODULE, client, [Host, LPort, COpts, Msg, N]),
+ ok = receive
+ {Server, listening} ->
+ Client ! {Server, listening},
+ ok;
+ E ->
+ io:format("bad receive (1) ~p\n", [E]),
+ E
+ end,
+ receive
+ {Server, done} ->
+ ok
+ end,
+ test_server:stop_node(Node),
+ test_server:stop_node(CNode).
+
+close_before_ssl_accept(doc) ->
+ "Client sends 256 bytes to server, that receives them, sends them "
+ "back, and closes. Client waits for close. Both have certs.";
+close_before_ssl_accept(suite) ->
+ [];
+close_before_ssl_accept(Config) when list(Config) ->
+ process_flag(trap_exit, true),
+ LPort = 3456,
+ {ok, Host} = inet:gethostname(),
+ {ok, {COpts, SOpts}} = ssl_test_MACHINE:mk_ssl_cert_opts(Config),
+ Msg = lists:seq(0, 255),
+ Self = self(),
+ Params = "-pa " ++ filename:dirname(code:which(?MODULE)),
+ Node = start_node(server, Params),
+ CNode = start_node(client, Params),
+ Server = spawn_link(Node, ?MODULE, tolerant_server,
+ [Self, LPort, SOpts, Msg, 2]),
+ Client = spawn_link(Node, ?MODULE, client,
+ [Host, LPort, COpts, Msg, 1]),
+ ok = receive
+ {Server, listening} ->
+ {ok, S} = gen_tcp:connect(Host, LPort, []),
+ gen_tcp:close(S),
+ Client ! {Server, listening},
+ ok;
+ E ->
+ io:format("bad receive (1) ~p\n", [E]),
+ E
+ end,
+ receive
+ {Server, done} ->
+ ok
+ end,
+ test_server:stop_node(Node),
+ test_server:stop_node(CNode).
+
+client(Host, LPort, COpts, Msg, N) ->
+ ok = receive
+ {_Server, listening} ->
+ ok;
+ E ->
+ io:format("bad receive (2) ~p\n", [E]),
+ E
+ end,
+ Opts = COpts ++ [{packet, raw}, {active, false}],
+ app(),
+ lists:foreach(fun(_) ->
+ {ok, S} = ssl:connect(Host, LPort, Opts),
+ ssl:send(S, Msg),
+ {ok, Msg} = ssl:recv(S, length(Msg)),
+ ssl:close(S)
+ end, lists:seq(1, N)).
+
+echo_twice(doc) ->
+ "Two clients sends 256 bytes to server, that receives them, sends them "
+ "back, and closes. Client waits for close. Both have certs.";
+echo_twice(suite) ->
+ [];
+echo_twice(Config) when list(Config) ->
+ process_flag(trap_exit, true),
+ LPort = 3456,
+ {ok, Host} = inet:gethostname(),
+ {ok, {COpts, SOpts}} = ssl_test_MACHINE:mk_ssl_cert_opts(Config),
+ N = 2,
+ Msg = lists:seq(0, 255),
+ Self = self(),
+ Params = "-pa " ++ filename:dirname(code:which(?MODULE)),
+ Node = start_node(server, Params),
+ CNode = start_node(client, Params),
+ Server = spawn_link(Node, ?MODULE, server,
+ [Self, LPort, SOpts, Msg, N]),
+ Client = spawn_link(Node, ?MODULE, client,
+ [Host, LPort, COpts, Msg, N]),
+ ok = receive
+ {Server, listening} ->
+ Client ! {Server, listening},
+ ok;
+ E ->
+ io:format("bad receive (3) ~p\n", [E]),
+ E
+ end,
+ receive
+ {Server, done} ->
+ ok
+ end,
+ test_server:stop_node(Node),
+ test_server:stop_node(CNode).
+
+server(Client, Port, SOpts, Msg, N) ->
+ app(),
+ process_flag(trap_exit, true),
+ Opts = SOpts ++ [{packet, raw}, {active, false}],
+ {ok, LSock} = ssl:listen(Port, Opts),
+ Client ! {self(), listening},
+ server_loop(Client, LSock, Msg, N).
+
+server_loop(Client, _, _, 0) ->
+ Client ! {self(), done};
+server_loop(Client, LSock, Msg, N) ->
+ {ok, S} = ssl:transport_accept(LSock),
+ ok = ssl:ssl_accept(S),
+ %% P = ssl:controlling_process(S, Proxy),
+ {ok, Msg} = ssl:recv(S, length(Msg)),
+ ok = ssl:send(S, Msg),
+ ok = ssl:close(S),
+ server_loop(Client, LSock, Msg, N-1).
+
+tolerant_server(Client, Port, SOpts, Msg, N) ->
+ app(),
+ process_flag(trap_exit, true),
+ Opts = SOpts ++ [{packet, raw}, {active, false}],
+ {ok, LSock} = ssl:listen(Port, Opts),
+ Client ! {self(), listening},
+ tolerant_server_loop(Client, LSock, Msg, N).
+
+tolerant_server_loop(Client, _, _, 0) ->
+ Client ! {self(), done};
+tolerant_server_loop(Client, LSock, Msg, N) ->
+ {ok, S} = ssl:transport_accept(LSock),
+ case ssl:ssl_accept(S) of
+ ok ->
+ %% P = ssl:controlling_process(S, Proxy),
+ {ok, Msg} = ssl:recv(S, length(Msg)),
+ ok = ssl:send(S, Msg),
+ ok = ssl:close(S);
+ E ->
+ io:format("ssl_accept error: ~p\n", [E])
+ end,
+ tolerant_server_loop(Client, LSock, Msg, N-1).
+
+app() ->
+ case application:get_application(ssl) of
+ undefined ->
+ application:start(ssl);
+ _ ->
+ ok
+ end.
+
+start_node(Kind, Params) ->
+ S = atom_to_list(?MODULE)++"_" ++ atom_to_list(Kind),
+ {ok, Node} = test_server:start_node(list_to_atom(S), slave, [{args, Params}]),
+ Node.
+
diff --git a/lib/ssl/test/ssl.cover b/lib/ssl/test/ssl.cover
new file mode 100644
index 0000000000..138bf96b9d
--- /dev/null
+++ b/lib/ssl/test/ssl.cover
@@ -0,0 +1,7 @@
+{exclude, [ssl_pkix_oid,
+ 'PKIX1Algorithms88',
+ 'PKIX1Explicit88',
+ 'PKIX1Implicit88',
+ 'PKIXAttributeCertificate',
+ 'SSL-PKIX']}.
+
diff --git a/lib/ssl/test/ssl.spec b/lib/ssl/test/ssl.spec
new file mode 100644
index 0000000000..6ef4fb73db
--- /dev/null
+++ b/lib/ssl/test/ssl.spec
@@ -0,0 +1 @@
+{topcase, {dir, "../ssl_test"}}.
diff --git a/lib/ssl/test/ssl_basic_SUITE.erl b/lib/ssl/test/ssl_basic_SUITE.erl
new file mode 100644
index 0000000000..7f33efd7e1
--- /dev/null
+++ b/lib/ssl/test/ssl_basic_SUITE.erl
@@ -0,0 +1,2538 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 2007-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(ssl_basic_SUITE).
+
+%% Note: This directive should only be used in test suites.
+-compile(export_all).
+
+-include("test_server.hrl").
+-include("test_server_line.hrl").
+-include_lib("public_key/include/public_key.hrl").
+
+-define('24H_in_sec', 86400).
+-define(TIMEOUT, 60000).
+-define(EXPIRE, 10).
+-define(SLEEP, 500).
+
+
+-behaviour(ssl_session_cache_api).
+
+%% For the session cache tests
+-export([init/0, terminate/1, lookup/2, update/3,
+ delete/2, foldl/3, select_session/2]).
+
+%% 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(),
+ ssl:start(),
+ Result =
+ (catch make_certs:all(?config(data_dir, Config),
+ ?config(priv_dir, Config))),
+ test_server:format("Make certs ~p~n", [Result]),
+ ssl_test_lib:cert_options(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) ->
+ ssl:stop(),
+ 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(session_cache_process_list, Config) ->
+ init_customized_session_cache(Config);
+
+init_per_testcase(session_cache_process_mnesia, Config) ->
+ mnesia:start(),
+ init_customized_session_cache(Config);
+
+init_per_testcase(reuse_session_expired, Config0) ->
+ Config = lists:keydelete(watchdog, 1, Config0),
+ Dog = ssl_test_lib:timetrap(?EXPIRE * 1000 * 5),
+ ssl:stop(),
+ application:load(ssl),
+ application:set_env(ssl, session_lifetime, ?EXPIRE),
+ ssl:start(),
+ [{watchdog, Dog} | Config];
+
+init_per_testcase(_TestCase, Config0) ->
+ Config = lists:keydelete(watchdog, 1, Config0),
+ Dog = test_server:timetrap(?TIMEOUT),
+ [{watchdog, Dog} | Config].
+
+init_customized_session_cache(Config0) ->
+ Config = lists:keydelete(watchdog, 1, Config0),
+ Dog = test_server:timetrap(?TIMEOUT),
+ ssl:stop(),
+ application:load(ssl),
+ application:set_env(ssl, session_cb, ?MODULE),
+ ssl:start(),
+ [{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(session_cache_process_list, Config) ->
+ application:unset_env(ssl, session_cb),
+ end_per_testcase(default_action, Config);
+end_per_testcase(session_cache_process_mnesia, Config) ->
+ application:unset_env(ssl, session_cb),
+ mnesia:stop(),
+ end_per_testcase(default_action, Config);
+end_per_testcase(reuse_session_expired, Config) ->
+ application:unset_env(ssl, session_lifetime),
+ end_per_testcase(default_action, Config);
+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 the basic ssl functionality"];
+
+all(suite) ->
+ [app, connection_info, controlling_process, controller_dies,
+ peercert, connect_dist,
+ peername, sockname, socket_options, misc_ssl_options, versions, cipher_suites,
+ upgrade, upgrade_with_timeout, tcp_connect,
+ ipv6, ekeyfile, ecertfile, ecacertfile, eoptions, shutdown,
+ shutdown_write, shutdown_both, shutdown_error, ciphers,
+ send_close, close_transport_accept, dh_params,
+ server_verify_peer_passive,
+ server_verify_peer_active, server_verify_peer_active_once,
+ server_verify_none_passive, server_verify_none_active,
+ server_verify_none_active_once, server_verify_no_cacerts,
+ server_require_peer_cert_ok, server_require_peer_cert_fail,
+ server_verify_client_once_passive,
+ server_verify_client_once_active,
+ server_verify_client_once_active_once,
+ client_verify_none_passive,
+ client_verify_none_active, client_verify_none_active_once
+ %%, session_cache_process_list, session_cache_process_mnesia
+ ,reuse_session, reuse_session_expired, server_does_not_want_to_reuse_session,
+ client_renegotiate, server_renegotiate,
+ client_no_wrap_sequence_number, server_no_wrap_sequence_number,
+ extended_key_usage, validate_extensions_fun
+ ].
+
+%% Test cases starts here.
+%%--------------------------------------------------------------------
+app(doc) ->
+ "Test that the ssl app file is ok";
+app(suite) ->
+ [];
+app(Config) when is_list(Config) ->
+ ok = test_server:app_test(ssl).
+
+connection_info(doc) ->
+ ["Test the API function ssl:connection_info/1"];
+connection_info(suite) ->
+ [];
+connection_info(Config) when is_list(Config) ->
+ ClientOpts = ?config(client_opts, Config),
+ ServerOpts = ?config(server_opts, Config),
+ {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
+ Server = ssl_test_lib:start_server([{node, ServerNode}, {port, 0},
+ {from, self()},
+ {mfa, {?MODULE, connection_info_result, []}},
+ {options, ServerOpts}]),
+
+ Port = ssl_test_lib:inet_port(Server),
+ Client = ssl_test_lib:start_client([{node, ClientNode}, {port, Port},
+ {host, Hostname},
+ {from, self()},
+ {mfa, {?MODULE, connection_info_result, []}},
+ {options,
+ [{ciphers,[{rsa,rc4_128,sha,no_export}]} |
+ ClientOpts]}]),
+
+ test_server:format("Testcase ~p, Client ~p Server ~p ~n",
+ [self(), Client, Server]),
+
+ Version =
+ ssl_record:protocol_version(ssl_record:highest_protocol_version([])),
+
+ ServerMsg = ClientMsg = {ok, {Version, {rsa,rc4_128,sha,no_export}}},
+
+ ssl_test_lib:check_result(Server, ServerMsg, Client, ClientMsg),
+
+ ssl_test_lib:close(Server),
+ ssl_test_lib:close(Client).
+
+connection_info_result(Socket) ->
+ ssl:connection_info(Socket).
+
+%%--------------------------------------------------------------------
+
+controlling_process(doc) ->
+ ["Test API function controlling_process/2"];
+
+controlling_process(suite) ->
+ [];
+
+controlling_process(Config) when is_list(Config) ->
+ ClientOpts = ?config(client_opts, Config),
+ ServerOpts = ?config(server_opts, Config),
+ {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
+ ClientMsg = "Hello server",
+ ServerMsg = "Hello client",
+
+ Server = ssl_test_lib:start_server([{node, ServerNode}, {port, 0},
+ {from, self()},
+ {mfa, {?MODULE,
+ controlling_process_result, [self(),
+ ServerMsg]}},
+ {options, ServerOpts}]),
+ Port = ssl_test_lib:inet_port(Server),
+ Client = ssl_test_lib:start_client([{node, ClientNode}, {port, Port},
+ {host, Hostname},
+ {from, self()},
+ {mfa, {?MODULE,
+ controlling_process_result, [self(),
+ ClientMsg]}},
+ {options, ClientOpts}]),
+
+ test_server:format("Testcase ~p, Client ~p Server ~p ~n",
+ [self(), Client, Server]),
+
+ receive
+ {ssl, _, ServerMsg} ->
+ receive
+ {ssl, _, ClientMsg} ->
+ ok
+ end;
+ {ssl, _, ClientMsg} ->
+ receive
+ {ssl, _, ServerMsg} ->
+ ok
+ end;
+ Unexpected ->
+ test_server:fail(Unexpected)
+ end,
+
+ ssl_test_lib:close(Server),
+ ssl_test_lib:close(Client).
+
+controlling_process_result(Socket, Pid, Msg) ->
+ ok = ssl:controlling_process(Socket, Pid),
+ %% Make sure other side has evaluated controlling_process
+ %% before message is sent
+ test_server:sleep(?SLEEP),
+ ssl:send(Socket, Msg),
+ no_result_msg.
+
+
+controller_dies(doc) ->
+ ["Test that the socket is closed after controlling process dies"];
+controller_dies(suite) -> [];
+controller_dies(Config) when is_list(Config) ->
+ ClientOpts = ?config(client_opts, Config),
+ ServerOpts = ?config(server_opts, Config),
+ {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
+ ClientMsg = "Hello server",
+ ServerMsg = "Hello client",
+
+ Server = ssl_test_lib:start_server([{node, ServerNode}, {port, 0},
+ {from, self()},
+ {mfa, {?MODULE,
+ controller_dies_result, [self(),
+ ServerMsg]}},
+ {options, ServerOpts}]),
+ Port = ssl_test_lib:inet_port(Server),
+ Client = ssl_test_lib:start_client([{node, ClientNode}, {port, Port},
+ {host, Hostname},
+ {from, self()},
+ {mfa, {?MODULE,
+ controller_dies_result, [self(),
+ ClientMsg]}},
+ {options, ClientOpts}]),
+
+ test_server:format("Testcase ~p, Client ~p Server ~p ~n", [self(), Client, Server]),
+ test_server:sleep(?SLEEP), %% so that they are connected
+
+ process_flag(trap_exit, true),
+
+ %% Test that clients die
+ exit(Client, killed),
+ get_close(Client, ?LINE),
+
+ %% Test that clients die when process disappear
+ Server ! listen,
+ Tester = self(),
+ Connect = fun(Pid) ->
+ {ok, Socket} = ssl:connect(Hostname, Port,
+ [{reuseaddr,true},{ssl_imp,new}]),
+ Pid ! {self(), connected, Socket},
+ receive die_nice -> normal end
+ end,
+ Client2 = spawn_link(fun() -> Connect(Tester) end),
+ receive {Client2, connected, _Socket} -> Client2 ! die_nice end,
+
+ get_close(Client2, ?LINE),
+
+ %% Test that clients die when the controlling process have changed
+ Server ! listen,
+
+ Client3 = spawn_link(fun() -> Connect(Tester) end),
+ Controller = spawn_link(fun() -> receive die_nice -> normal end end),
+ receive
+ {Client3, connected, Socket} ->
+ ok = ssl:controlling_process(Socket, Controller),
+ Client3 ! die_nice
+ end,
+
+ test_server:format("Wating on exit ~p~n",[Client3]),
+ receive {'EXIT', Client3, normal} -> ok end,
+
+ receive %% Client3 is dead but that doesn't matter, socket should not be closed.
+ Unexpected ->
+ test_server:format("Unexpected ~p~n",[Unexpected]),
+ test_server:fail({line, ?LINE-1})
+ after 1000 ->
+ ok
+ end,
+ Controller ! die_nice,
+ get_close(Controller, ?LINE),
+
+ %% Test that servers die
+ Server ! listen,
+ LastClient = ssl_test_lib:start_client([{node, ClientNode}, {port, Port},
+ {host, Hostname},
+ {from, self()},
+ {mfa, {?MODULE,
+ controller_dies_result, [self(),
+ ClientMsg]}},
+ {options, [{reuseaddr,true}|ClientOpts]}]),
+ test_server:sleep(?SLEEP), %% so that they are connected
+
+ exit(Server, killed),
+ get_close(Server, ?LINE),
+ process_flag(trap_exit, false),
+ ssl_test_lib:close(LastClient).
+
+controller_dies_result(_Socket, _Pid, _Msg) ->
+ receive Result -> Result end.
+
+get_close(Pid, Where) ->
+ receive
+ {'EXIT', Pid, _Reason} ->
+ receive
+ {_, {ssl_closed, Socket}} ->
+ test_server:format("Socket closed ~p~n",[Socket]);
+ Unexpected ->
+ test_server:format("Unexpected ~p~n",[Unexpected]),
+ test_server:fail({line, ?LINE-1})
+ after 5000 ->
+ test_server:fail({timeout, {line, ?LINE, Where}})
+ end;
+ Unexpected ->
+ test_server:format("Unexpected ~p~n",[Unexpected]),
+ test_server:fail({line, ?LINE-1})
+ after 5000 ->
+ test_server:fail({timeout, {line, ?LINE, Where}})
+ end.
+
+%%--------------------------------------------------------------------
+peercert(doc) ->
+ [""];
+
+peercert(suite) ->
+ [];
+
+peercert(Config) when is_list(Config) ->
+ ClientOpts = ?config(client_opts, Config),
+ ServerOpts = ?config(server_opts, Config),
+ {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
+
+ Server = ssl_test_lib:start_server([{node, ClientNode}, {port, 0},
+ {from, self()},
+ {mfa, {?MODULE, peercert_result, []}},
+ {options, ServerOpts}]),
+ Port = ssl_test_lib:inet_port(Server),
+ Client = ssl_test_lib:start_client([{node, ServerNode}, {port, Port},
+ {host, Hostname},
+ {from, self()},
+ {mfa, {?MODULE, peercert_result, []}},
+ {options, ClientOpts}]),
+
+ CertFile = proplists:get_value(certfile, ServerOpts),
+ {ok, [{cert, BinCert, _}]} = public_key:pem_to_der(CertFile),
+ {ok, ErlCert} = public_key:pkix_decode_cert(BinCert, otp),
+
+ ServerMsg = {{error, no_peercert}, {error, no_peercert}},
+ ClientMsg = {{ok, BinCert}, {ok, ErlCert}},
+
+ test_server:format("Testcase ~p, Client ~p Server ~p ~n",
+ [self(), Client, Server]),
+
+ ssl_test_lib:check_result(Server, ServerMsg, Client, ClientMsg),
+
+ ssl_test_lib:close(Server),
+ ssl_test_lib:close(Client).
+
+peercert_result(Socket) ->
+ Result1 = ssl:peercert(Socket),
+ Result2 = ssl:peercert(Socket, [ssl]),
+ {Result1, Result2}.
+
+%%--------------------------------------------------------------------
+connect_dist(doc) ->
+ ["Test a simple connect as is used by distribution"];
+
+connect_dist(suite) ->
+ [];
+
+connect_dist(Config) when is_list(Config) ->
+ ClientOpts0 = ?config(client_kc_opts, Config),
+ ClientOpts = [{ssl_imp, new},{active, false}, {packet,4}|ClientOpts0],
+ ServerOpts0 = ?config(server_kc_opts, Config),
+ ServerOpts = [{ssl_imp, new},{active, false}, {packet,4}|ServerOpts0],
+
+ {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
+
+ Server = ssl_test_lib:start_server([{node, ServerNode}, {port, 0},
+ {from, self()},
+ {mfa, {?MODULE, connect_dist_s, []}},
+ {options, ServerOpts}]),
+ Port = ssl_test_lib:inet_port(Server),
+ Client = ssl_test_lib:start_client([{node, ClientNode}, {port, Port},
+ {host, Hostname},
+ {from, self()},
+ {mfa, {?MODULE, connect_dist_c, []}},
+ {options, ClientOpts}]),
+
+ ssl_test_lib:check_result(Server, ok, Client, ok),
+
+ ssl_test_lib:close(Server),
+ ssl_test_lib:close(Client).
+
+connect_dist_s(S) ->
+ Msg = term_to_binary({erlang,term}),
+ ok = ssl:send(S, Msg).
+
+connect_dist_c(S) ->
+ Test = binary_to_list(term_to_binary({erlang,term})),
+ {ok, Test} = ssl:recv(S, 0, 10000),
+ ok.
+
+
+%%--------------------------------------------------------------------
+peername(doc) ->
+ ["Test API function peername/1"];
+
+peername(suite) ->
+ [];
+
+peername(Config) when is_list(Config) ->
+ ClientOpts = ?config(client_opts, Config),
+ ServerOpts = ?config(server_opts, Config),
+ {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
+ Server = ssl_test_lib:start_server([{node, ServerNode}, {port, 0},
+ {from, self()},
+ {mfa, {?MODULE, peername_result, []}},
+ {options, ServerOpts}]),
+ Port = ssl_test_lib:inet_port(Server),
+ Client = ssl_test_lib:start_client([{node, ClientNode}, {port, Port},
+ {host, Hostname},
+ {from, self()},
+ {mfa, {?MODULE, peername_result, []}},
+ {options, [{port, 0} | ClientOpts]}]),
+
+ ClientPort = ssl_test_lib:inet_port(Client),
+ ServerIp = ssl_test_lib:node_to_hostip(ServerNode),
+ ClientIp = ssl_test_lib:node_to_hostip(ClientNode),
+ ServerMsg = {ok, {ClientIp, ClientPort}},
+ ClientMsg = {ok, {ServerIp, Port}},
+
+ test_server:format("Testcase ~p, Client ~p Server ~p ~n",
+ [self(), Client, Server]),
+
+ ssl_test_lib:check_result(Server, ServerMsg, Client, ClientMsg),
+
+ ssl_test_lib:close(Server),
+ ssl_test_lib:close(Client).
+
+peername_result(S) ->
+ ssl:peername(S).
+
+%%--------------------------------------------------------------------
+sockname(doc) ->
+ ["Test API function sockname/1"];
+
+sockname(suite) ->
+ [];
+
+sockname(Config) when is_list(Config) ->
+ ClientOpts = ?config(client_opts, Config),
+ ServerOpts = ?config(server_opts, Config),
+ {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
+ Server = ssl_test_lib:start_server([{node, ServerNode}, {port, 0},
+ {from, self()},
+ {mfa, {?MODULE, sockname_result, []}},
+ {options, ServerOpts}]),
+ Port = ssl_test_lib:inet_port(Server),
+ Client = ssl_test_lib:start_client([{node, ClientNode}, {port, Port},
+ {host, Hostname},
+ {from, self()},
+ {mfa, {?MODULE, sockname_result, []}},
+ {options, [{port, 0} | ClientOpts]}]),
+
+ ClientPort = ssl_test_lib:inet_port(Client),
+ ServerIp = ssl_test_lib:node_to_hostip(ServerNode),
+ ClientIp = ssl_test_lib:node_to_hostip(ClientNode),
+ ServerMsg = {ok, {ServerIp, Port}},
+ ClientMsg = {ok, {ClientIp, ClientPort}},
+
+ test_server:format("Testcase ~p, Client ~p Server ~p ~n",
+ [self(), Client, Server]),
+
+ ssl_test_lib:check_result(Server, ServerMsg, Client, ClientMsg),
+
+ ssl_test_lib:close(Server),
+ ssl_test_lib:close(Client).
+
+sockname_result(S) ->
+ ssl:sockname(S).
+
+%%--------------------------------------------------------------------
+cipher_suites(doc) ->
+ ["Test API function cipher_suites/0"];
+
+cipher_suites(suite) ->
+ [];
+
+cipher_suites(Config) when is_list(Config) ->
+ MandatoryCipherSuite = {rsa,'3des_ede_cbc',sha,no_export},
+ [_|_] = Suites = ssl:cipher_suites(),
+ true = lists:member(MandatoryCipherSuite, Suites).
+%%--------------------------------------------------------------------
+socket_options(doc) ->
+ ["Test API function getopts/2 and setopts/2"];
+
+socket_options(suite) ->
+ [];
+
+socket_options(Config) when is_list(Config) ->
+ ClientOpts = ?config(client_opts, Config),
+ ServerOpts = ?config(server_opts, Config),
+ {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
+ Values = [{mode, list}, {packet, 0}, {header, 0},
+ {active, true}],
+ %% Shall be the reverse order of Values!
+ Options = [active, header, packet, mode],
+
+ NewValues = [{mode, binary}, {active, once}],
+ %% Shall be the reverse order of NewValues!
+ NewOptions = [active, mode],
+
+ Server = ssl_test_lib:start_server([{node, ServerNode}, {port, 0},
+ {from, self()},
+ {mfa, {?MODULE, socket_options_result,
+ [Options, Values, NewOptions, NewValues]}},
+ {options, ServerOpts}]),
+ Port = ssl_test_lib:inet_port(Server),
+ Client = ssl_test_lib:start_client([{node, ClientNode}, {port, Port},
+ {host, Hostname},
+ {from, self()},
+ {mfa, {?MODULE, socket_options_result,
+ [Options, Values, NewOptions, NewValues]}},
+ {options, ClientOpts}]),
+
+ ssl_test_lib:check_result(Server, ok, Client, ok),
+
+ ssl_test_lib:close(Server),
+ ssl_test_lib:close(Client).
+
+socket_options_result(Socket, Options, DefaultValues, NewOptions, NewValues) ->
+ %% Test get/set emulated opts
+ {ok, DefaultValues} = ssl:getopts(Socket, Options),
+ ssl:setopts(Socket, NewValues),
+ {ok, NewValues} = ssl:getopts(Socket, NewOptions),
+ %% Test get/set inet opts
+ {ok,[{nodelay,false}]} = ssl:getopts(Socket, [nodelay]),
+ ok.
+
+%%--------------------------------------------------------------------
+misc_ssl_options(doc) ->
+ ["Test what happens when we give valid options"];
+
+misc_ssl_options(suite) ->
+ [];
+
+misc_ssl_options(Config) when is_list(Config) ->
+ ClientOpts = ?config(client_opts, Config),
+ ServerOpts = ?config(server_opts, Config),
+ {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
+
+ %% Chek that ssl options not tested elsewhere are filtered away e.i. not passed to inet.
+ TestOpts = [{depth, 1},
+ {key, undefined},
+ {password, []},
+ {reuse_session, fun(_,_,_,_) -> true end},
+ {debug, []},
+ {cb_info, {gen_tcp, tcp, tcp_closed}}],
+
+ Server =
+ ssl_test_lib:start_server([{node, ServerNode}, {port, 0},
+ {from, self()},
+ {mfa, {?MODULE, send_recv_result_active, []}},
+ {options, TestOpts ++ ServerOpts}]),
+ Port = ssl_test_lib:inet_port(Server),
+ Client =
+ ssl_test_lib:start_client([{node, ClientNode}, {port, Port},
+ {host, Hostname},
+ {from, self()},
+ {mfa, {?MODULE, send_recv_result_active, []}},
+ {options, TestOpts ++ ClientOpts}]),
+
+ test_server:format("Testcase ~p, Client ~p Server ~p ~n",
+ [self(), Client, Server]),
+
+ ssl_test_lib:check_result(Server, ok, Client, ok),
+ ssl_test_lib:close(Server),
+ ssl_test_lib:close(Client).
+
+%%--------------------------------------------------------------------
+versions(doc) ->
+ ["Test API function versions/0"];
+
+versions(suite) ->
+ [];
+
+versions(Config) when is_list(Config) ->
+ [_|_] = Versions = ssl:versions(),
+ test_server:format("~p~n", [Versions]).
+
+%%--------------------------------------------------------------------
+send_recv(doc) ->
+ [""];
+
+send_recv(suite) ->
+ [];
+
+send_recv(Config) when is_list(Config) ->
+ ClientOpts = ?config(client_opts, Config),
+ ServerOpts = ?config(server_opts, Config),
+ {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
+ Server =
+ ssl_test_lib:start_server([{node, ServerNode}, {port, 0},
+ {from, self()},
+ {mfa, {?MODULE, send_recv_result, []}},
+ {options, [{active, false} | ServerOpts]}]),
+ Port = ssl_test_lib:inet_port(Server),
+ Client =
+ ssl_test_lib:start_client([{node, ClientNode}, {port, Port},
+ {host, Hostname},
+ {from, self()},
+ {mfa, {?MODULE, send_recv_result, []}},
+ {options, [{active, false} | ClientOpts]}]),
+
+ test_server:format("Testcase ~p, Client ~p Server ~p ~n",
+ [self(), Client, Server]),
+
+ ssl_test_lib:check_result(Server, ok, Client, ok),
+
+ ssl_test_lib:close(Server),
+ ssl_test_lib:close(Client).
+
+send_close(doc) ->
+ [""];
+
+send_close(suite) ->
+ [];
+
+send_close(Config) when is_list(Config) ->
+ ClientOpts = ?config(client_opts, Config),
+ ServerOpts = ?config(server_opts, Config),
+ {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
+ Server =
+ ssl_test_lib:start_server([{node, ServerNode}, {port, 0},
+ {from, self()},
+ {mfa, {?MODULE, send_recv_result, []}},
+ {options, [{active, false} | ServerOpts]}]),
+ Port = ssl_test_lib:inet_port(Server),
+ {ok, TcpS} = rpc:call(ClientNode, gen_tcp, connect,
+ [Hostname,Port,[binary, {active, false}, {reuseaddr, true}]]),
+ {ok, SslS} = rpc:call(ClientNode, ssl, connect,
+ [TcpS,[{active, false}|ClientOpts]]),
+
+ test_server:format("Testcase ~p, Client ~p Server ~p ~n",
+ [self(), self(), Server]),
+ ok = ssl:send(SslS, "Hello world"),
+ {ok,<<"Hello world">>} = ssl:recv(SslS, 11),
+ gen_tcp:close(TcpS),
+ {error, _} = ssl:send(SslS, "Hello world"),
+ ssl_test_lib:close(Server).
+
+%%--------------------------------------------------------------------
+close_transport_accept(doc) ->
+ ["Tests closing ssl socket when waiting on ssl:transport_accept/1"];
+
+close_transport_accept(suite) ->
+ [];
+
+close_transport_accept(Config) when is_list(Config) ->
+ ServerOpts = ?config(server_opts, Config),
+ {_ClientNode, ServerNode, _Hostname} = ssl_test_lib:run_where(Config),
+
+ Port = 0,
+ Opts = [{active, false} | ServerOpts],
+ {ok, ListenSocket} = rpc:call(ServerNode, ssl, listen, [Port, Opts]),
+ spawn_link(fun() ->
+ test_server:sleep(?SLEEP),
+ rpc:call(ServerNode, ssl, close, [ListenSocket])
+ end),
+ case rpc:call(ServerNode, ssl, transport_accept, [ListenSocket]) of
+ {error, closed} ->
+ ok;
+ Other ->
+ exit({?LINE, Other})
+ end.
+
+%%--------------------------------------------------------------------
+dh_params(doc) ->
+ ["Test to specify DH-params file in server."];
+
+dh_params(suite) ->
+ [];
+
+dh_params(Config) when is_list(Config) ->
+ ClientOpts = ?config(client_opts, Config),
+ ServerOpts = ?config(server_opts, Config),
+ DataDir = ?config(data_dir, Config),
+ DHParamFile = filename:join(DataDir, "dHParam.pem"),
+
+ {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
+
+ Server = ssl_test_lib:start_server([{node, ServerNode}, {port, 0},
+ {from, self()},
+ {mfa, {?MODULE, send_recv_result_active, []}},
+ {options, [{dhfile, DHParamFile} | ServerOpts]}]),
+ Port = ssl_test_lib:inet_port(Server),
+ Client = ssl_test_lib:start_client([{node, ClientNode}, {port, Port},
+ {host, Hostname},
+ {from, self()},
+ {mfa, {?MODULE, send_recv_result_active, []}},
+ {options,
+ [{ciphers,[{dhe_rsa,aes_256_cbc,sha,ignore}]} |
+ ClientOpts]}]),
+
+ ssl_test_lib:check_result(Server, ok, Client, ok),
+
+ ssl_test_lib:close(Server),
+ ssl_test_lib:close(Client).
+
+%%--------------------------------------------------------------------
+upgrade(doc) ->
+ ["Test that you can upgrade an tcp connection to an ssl connection"];
+
+upgrade(suite) ->
+ [];
+
+upgrade(Config) when is_list(Config) ->
+ ClientOpts = ?config(client_opts, Config),
+ ServerOpts = ?config(server_opts, Config),
+ {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
+ TcpOpts = [binary, {reuseaddr, true}],
+
+ Server = ssl_test_lib:start_upgrade_server([{node, ServerNode}, {port, 0},
+ {from, self()},
+ {mfa, {?MODULE,
+ upgrade_result, []}},
+ {tcp_options, TcpOpts},
+ {ssl_options, ServerOpts}]),
+ Port = ssl_test_lib:inet_port(Server),
+ Client = ssl_test_lib:start_upgrade_client([{node, ClientNode},
+ {port, Port},
+ {host, Hostname},
+ {from, self()},
+ {mfa, {?MODULE, upgrade_result, []}},
+ {tcp_options, TcpOpts},
+ {ssl_options, ClientOpts}]),
+
+ test_server:format("Testcase ~p, Client ~p Server ~p ~n",
+ [self(), Client, Server]),
+
+ ssl_test_lib:check_result(Server, ok, Client, ok),
+
+ ssl_test_lib:close(Server),
+ ssl_test_lib:close(Client).
+
+upgrade_result(Socket) ->
+ ok = ssl:send(Socket, "Hello world"),
+ %% Make sure binary is inherited from tcp socket and that we do
+ %% not get the list default!
+ receive
+ {ssl, _, <<"Hello world">>} ->
+ ok
+ end.
+
+%%--------------------------------------------------------------------
+upgrade_with_timeout(doc) ->
+ ["Test ssl_accept/3"];
+
+upgrade_with_timeout(suite) ->
+ [];
+
+upgrade_with_timeout(Config) when is_list(Config) ->
+ ClientOpts = ?config(client_opts, Config),
+ ServerOpts = ?config(server_opts, Config),
+ {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
+ TcpOpts = [binary, {reuseaddr, true}],
+
+ Server = ssl_test_lib:start_upgrade_server([{node, ServerNode}, {port, 0},
+ {from, self()},
+ {timeout, 5000},
+ {mfa, {?MODULE,
+ upgrade_result, []}},
+ {tcp_options, TcpOpts},
+ {ssl_options, ServerOpts}]),
+ Port = ssl_test_lib:inet_port(Server),
+ Client = ssl_test_lib:start_upgrade_client([{node, ClientNode},
+ {port, Port},
+ {host, Hostname},
+ {from, self()},
+ {mfa, {?MODULE, upgrade_result, []}},
+ {tcp_options, TcpOpts},
+ {ssl_options, ClientOpts}]),
+
+ test_server:format("Testcase ~p, Client ~p Server ~p ~n",
+ [self(), Client, Server]),
+
+ ssl_test_lib:check_result(Server, ok, Client, ok),
+
+ ssl_test_lib:close(Server),
+ ssl_test_lib:close(Client).
+
+%%--------------------------------------------------------------------
+tcp_connect(doc) ->
+ ["Test what happens when a tcp tries to connect, i,e. a bad (ssl) packet is sent first"];
+
+tcp_connect(suite) ->
+ [];
+
+tcp_connect(Config) when is_list(Config) ->
+ ServerOpts = ?config(server_opts, Config),
+ {_, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
+ TcpOpts = [binary, {reuseaddr, true}],
+
+ Server = ssl_test_lib:start_upgrade_server([{node, ServerNode}, {port, 0},
+ {from, self()},
+ {timeout, 5000},
+ {mfa, {?MODULE, dummy, []}},
+ {tcp_options, TcpOpts},
+ {ssl_options, ServerOpts}]),
+ Port = ssl_test_lib:inet_port(Server),
+
+ {ok, Socket} = gen_tcp:connect(Hostname, Port, [binary, {packet, 0}]),
+ test_server:format("Testcase ~p connected to Server ~p ~n", [self(), Server]),
+ gen_tcp:send(Socket, "<SOME GARBLED NON SSL MESSAGE>"),
+
+ receive
+ {tcp_closed, Socket} ->
+ receive
+ {Server, {error, Error}} ->
+ test_server:format("Error ~p", [Error])
+ end
+ end,
+ ssl_test_lib:close(Server).
+
+
+dummy(_Socket) ->
+ %% Should not happen as the ssl connection will not be established
+ %% due to fatal handshake failiure
+ exit(kill).
+
+%%--------------------------------------------------------------------
+ipv6(doc) ->
+ ["Test ipv6."];
+ipv6(suite) ->
+ [];
+ipv6(Config) when is_list(Config) ->
+ {ok, Hostname0} = inet:gethostname(),
+
+ case lists:member(list_to_atom(Hostname0), ?config(ipv6_hosts, Config)) of
+ true ->
+ ClientOpts = ?config(client_opts, Config),
+ ServerOpts = ?config(server_opts, Config),
+ {ClientNode, ServerNode, Hostname} =
+ ssl_test_lib:run_where(Config, ipv6),
+ Server = ssl_test_lib:start_server([{node, ServerNode},
+ {port, 0}, {from, self()},
+ {mfa, {?MODULE, send_recv_result, []}},
+ {options,
+ [inet6, {active, false} | ServerOpts]}]),
+ Port = ssl_test_lib:inet_port(Server),
+ Client = ssl_test_lib:start_client([{node, ClientNode},
+ {port, Port}, {host, Hostname},
+ {from, self()},
+ {mfa, {?MODULE, send_recv_result, []}},
+ {options,
+ [inet6, {active, false} | ClientOpts]}]),
+
+ test_server:format("Testcase ~p, Client ~p Server ~p ~n",
+ [self(), Client, Server]),
+
+ ssl_test_lib:check_result(Server, ok, Client, ok),
+
+ ssl_test_lib:close(Server),
+ ssl_test_lib:close(Client);
+ false ->
+ {skip, "Host does not support IPv6"}
+ end.
+
+%%--------------------------------------------------------------------
+
+ekeyfile(doc) ->
+ ["Test what happens with an invalid key file"];
+
+ekeyfile(suite) ->
+ [];
+
+ekeyfile(Config) when is_list(Config) ->
+ ClientOpts = ?config(client_opts, Config),
+ BadOpts = ?config(server_bad_key, Config),
+ {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
+
+ Server =
+ ssl_test_lib:start_server_error([{node, ServerNode}, {port, 0},
+ {from, self()},
+ {options, BadOpts}]),
+
+ Port = ssl_test_lib:inet_port(Server),
+
+ Client =
+ ssl_test_lib:start_client_error([{node, ClientNode},
+ {port, Port}, {host, Hostname},
+ {from, self()}, {options, ClientOpts}]),
+
+ ssl_test_lib:check_result(Server, {error, ekeyfile}, Client,
+ {error, closed}).
+
+%%--------------------------------------------------------------------
+
+ecertfile(doc) ->
+ ["Test what happens with an invalid cert file"];
+
+ecertfile(suite) ->
+ [];
+
+ecertfile(Config) when is_list(Config) ->
+ ClientOpts = ?config(client_opts, Config),
+ ServerBadOpts = ?config(server_bad_cert, Config),
+ {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
+
+ Server =
+ ssl_test_lib:start_server_error([{node, ServerNode}, {port, 0},
+ {from, self()},
+ {options, ServerBadOpts}]),
+
+ Port = ssl_test_lib:inet_port(Server),
+
+ Client =
+ ssl_test_lib:start_client_error([{node, ClientNode},
+ {port, Port}, {host, Hostname},
+ {from, self()},
+ {options, ClientOpts}]),
+
+ ssl_test_lib:check_result(Server, {error, ecertfile}, Client,
+ {error, closed}).
+
+
+%%--------------------------------------------------------------------
+ecacertfile(doc) ->
+ ["Test what happens with an invalid cacert file"];
+
+ecacertfile(suite) ->
+ [];
+
+ecacertfile(Config) when is_list(Config) ->
+ ClientOpts = [{reuseaddr, true}|?config(client_opts, Config)],
+ ServerBadOpts = [{reuseaddr, true}|?config(server_bad_ca, Config)],
+ {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
+
+ Server0 =
+ ssl_test_lib:start_server_error([{node, ServerNode},
+ {port, 0}, {from, self()},
+ {options, ServerBadOpts}]),
+
+ Port0 = ssl_test_lib:inet_port(Server0),
+
+
+ Client0 =
+ ssl_test_lib:start_client_error([{node, ClientNode},
+ {port, Port0}, {host, Hostname},
+ {from, self()},
+ {options, ClientOpts}]),
+
+ ssl_test_lib:check_result(Server0, {error, ecacertfile},
+ Client0, {error, closed}),
+
+ File0 = proplists:get_value(cacertfile, ServerBadOpts),
+ File = File0 ++ "do_not_exit.pem",
+ ServerBadOpts1 = [{cacertfile, File}|proplists:delete(cacertfile, ServerBadOpts)],
+
+ Server1 =
+ ssl_test_lib:start_server_error([{node, ServerNode},
+ {port, 0}, {from, self()},
+ {options, ServerBadOpts1}]),
+
+ Port1 = ssl_test_lib:inet_port(Server1),
+
+ Client1 =
+ ssl_test_lib:start_client_error([{node, ClientNode},
+ {port, Port1}, {host, Hostname},
+ {from, self()},
+ {options, ClientOpts}]),
+
+ ssl_test_lib:check_result(Server1, {error, ecacertfile},
+ Client1, {error, closed}),
+ ok.
+
+
+
+%%--------------------------------------------------------------------
+eoptions(doc) ->
+ ["Test what happens when we give invalid options"];
+
+eoptions(suite) ->
+ [];
+
+eoptions(Config) when is_list(Config) ->
+ ClientOpts = ?config(client_opts, Config),
+ ServerOpts = ?config(server_opts, Config),
+ {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
+
+ Check = fun(Client, Server, {versions, [sslv2, sslv3]} = Option) ->
+ ssl_test_lib:check_result(Server,
+ {error, {eoptions, {sslv2, Option}}},
+ Client,
+ {error, {eoptions, {sslv2, Option}}});
+ (Client, Server, Option) ->
+ ssl_test_lib:check_result(Server,
+ {error, {eoptions, Option}},
+ Client,
+ {error, {eoptions, Option}})
+ end,
+
+ TestOpts = [{versions, [sslv2, sslv3]},
+ {ssl_imp, cool},
+ {verify, 4},
+ {verify_fun, function},
+ {fail_if_no_peer_cert, 0},
+ {verify_client_once, 1},
+ {validate_extensions_fun, function},
+ {depth, four},
+ {certfile, 'cert.pem'},
+ {keyfile,'key.pem' },
+ {password, foo},
+ {cacertfile, ""},
+ {dhfile,'dh.pem' },
+ {ciphers, [{foo, bar, sha, ignore}]},
+ {reuse_session, foo},
+ {reuse_sessions, 0},
+ {renegotiate_at, "10"},
+ {debug, 1},
+ {mode, depech},
+ {packet, 8.0},
+ {packet_size, "2"},
+ {header, a},
+ {active, trice},
+ {key, 'key.pem' }],
+
+ [begin
+ Server =
+ ssl_test_lib:start_server_error([{node, ServerNode}, {port, 0},
+ {from, self()},
+ {options, [TestOpt | ServerOpts]}]),
+ %% Will never reach a point where port is used.
+ Client =
+ ssl_test_lib:start_client_error([{node, ClientNode}, {port, 0},
+ {host, Hostname}, {from, self()},
+ {options, [TestOpt | ClientOpts]}]),
+ Check(Client, Server, TestOpt),
+ ok
+ end || TestOpt <- TestOpts],
+ ok.
+
+%%--------------------------------------------------------------------
+shutdown(doc) ->
+ [""];
+
+shutdown(suite) ->
+ [];
+
+shutdown(Config) when is_list(Config) ->
+ ClientOpts = ?config(client_opts, Config),
+ ServerOpts = ?config(server_opts, Config),
+ {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
+ Server = ssl_test_lib:start_server([{node, ServerNode}, {port, 0},
+ {from, self()},
+ {mfa, {?MODULE, shutdown_result, [server]}},
+ {options, [{exit_on_close, false},
+ {active, false} | ServerOpts]}]),
+ Port = ssl_test_lib:inet_port(Server),
+ Client = ssl_test_lib:start_client([{node, ClientNode}, {port, Port},
+ {host, Hostname},
+ {from, self()},
+ {mfa,
+ {?MODULE, shutdown_result, [client]}},
+ {options,
+ [{exit_on_close, false},
+ {active, false} | ClientOpts]}]),
+
+ ssl_test_lib:check_result(Server, ok, Client, ok),
+
+ ssl_test_lib:close(Server),
+ ssl_test_lib:close(Client).
+
+shutdown_result(Socket, server) ->
+ ssl:send(Socket, "Hej"),
+ ssl:shutdown(Socket, write),
+ {ok, "Hej hopp"} = ssl:recv(Socket, 8),
+ ok;
+
+shutdown_result(Socket, client) ->
+ {ok, "Hej"} = ssl:recv(Socket, 3),
+ ssl:send(Socket, "Hej hopp"),
+ ssl:shutdown(Socket, write),
+ ok.
+
+%%--------------------------------------------------------------------
+shutdown_write(doc) ->
+ [""];
+
+shutdown_write(suite) ->
+ [];
+
+shutdown_write(Config) when is_list(Config) ->
+ ClientOpts = ?config(client_opts, Config),
+ ServerOpts = ?config(server_opts, Config),
+ {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
+ Server = ssl_test_lib:start_server([{node, ServerNode}, {port, 0},
+ {from, self()},
+ {mfa, {?MODULE, shutdown_write_result, [server]}},
+ {options, [{active, false} | ServerOpts]}]),
+ Port = ssl_test_lib:inet_port(Server),
+ Client = ssl_test_lib:start_client([{node, ClientNode}, {port, Port},
+ {host, Hostname},
+ {from, self()},
+ {mfa, {?MODULE, shutdown_write_result, [client]}},
+ {options, [{active, false} | ClientOpts]}]),
+
+ ssl_test_lib:check_result(Server, ok, Client, {error, closed}).
+
+shutdown_write_result(Socket, server) ->
+ test_server:sleep(?SLEEP),
+ ssl:shutdown(Socket, write);
+shutdown_write_result(Socket, client) ->
+ ssl:recv(Socket, 0).
+
+%%--------------------------------------------------------------------
+shutdown_both(doc) ->
+ [""];
+
+shutdown_both(suite) ->
+ [];
+
+shutdown_both(Config) when is_list(Config) ->
+ ClientOpts = ?config(client_opts, Config),
+ ServerOpts = ?config(server_opts, Config),
+ {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
+ Server = ssl_test_lib:start_server([{node, ServerNode}, {port, 0},
+ {from, self()},
+ {mfa, {?MODULE, shutdown_both_result, [server]}},
+ {options, [{active, false} | ServerOpts]}]),
+ Port = ssl_test_lib:inet_port(Server),
+ Client = ssl_test_lib:start_client([{node, ClientNode}, {port, Port},
+ {host, Hostname},
+ {from, self()},
+ {mfa, {?MODULE, shutdown_both_result, [client]}},
+ {options, [{active, false} | ClientOpts]}]),
+
+ ssl_test_lib:check_result(Server, ok, Client, {error, closed}).
+
+shutdown_both_result(Socket, server) ->
+ test_server:sleep(?SLEEP),
+ ssl:shutdown(Socket, read_write);
+shutdown_both_result(Socket, client) ->
+ ssl:recv(Socket, 0).
+
+%%--------------------------------------------------------------------
+shutdown_error(doc) ->
+ [""];
+
+shutdown_error(suite) ->
+ [];
+
+shutdown_error(Config) when is_list(Config) ->
+ ServerOpts = ?config(server_opts, Config),
+ Port = ssl_test_lib:inet_port(node()),
+ {ok, Listen} = ssl:listen(Port, ServerOpts),
+ {error, enotconn} = ssl:shutdown(Listen, read_write),
+ ok = ssl:close(Listen),
+ {error, closed} = ssl:shutdown(Listen, read_write).
+
+%%--------------------------------------------------------------------
+ciphers(doc) ->
+ [""];
+
+ciphers(suite) ->
+ [];
+
+ciphers(Config) when is_list(Config) ->
+ Version =
+ ssl_record:protocol_version(ssl_record:highest_protocol_version([])),
+
+ Ciphers = ssl:cipher_suites(),
+ Result = lists:map(fun(Cipher) ->
+ cipher(Cipher, Version, Config) end,
+ Ciphers),
+ case lists:flatten(Result) of
+ [] ->
+ ok;
+ Error ->
+ test_server:format("Cipher suite errors: ~p~n", [Error]),
+ test_server:fail(cipher_suite_failed_see_test_case_log)
+ end.
+
+cipher(CipherSuite, Version, Config) ->
+ process_flag(trap_exit, true),
+ test_server:format("Testing CipherSuite ~p~n", [CipherSuite]),
+ ClientOpts = ?config(client_opts, Config),
+ ServerOpts = ?config(server_opts, Config),
+ {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
+ Server = ssl_test_lib:start_server([{node, ServerNode}, {port, 0},
+ {from, self()},
+ {mfa, {?MODULE, connection_info_result, []}},
+ {options, ServerOpts}]),
+ Port = ssl_test_lib:inet_port(Server),
+ Client = ssl_test_lib:start_client([{node, ClientNode}, {port, Port},
+ {host, Hostname},
+ {from, self()},
+ {mfa, {?MODULE, connection_info_result, []}},
+ {options,
+ [{ciphers,[CipherSuite]} |
+ ClientOpts]}]),
+
+ ServerMsg = ClientMsg = {ok, {Version, CipherSuite}},
+
+ Result = ssl_test_lib:wait_for_result(Server, ServerMsg,
+ Client, ClientMsg),
+ ssl_test_lib:close(Server),
+ receive
+ {'EXIT', Server, normal} ->
+ ok
+ end,
+ ssl_test_lib:close(Client),
+ receive
+ {'EXIT', Client, normal} ->
+ ok
+ end,
+ process_flag(trap_exit, false),
+ case Result of
+ ok ->
+ [];
+ Error ->
+ [{CipherSuite, Error}]
+ end.
+
+%%--------------------------------------------------------------------
+reuse_session(doc) ->
+ ["Test reuse of sessions (short handshake)"];
+
+reuse_session(suite) ->
+ [];
+
+reuse_session(Config) when is_list(Config) ->
+ process_flag(trap_exit, true),
+ ClientOpts = ?config(client_opts, Config),
+ ServerOpts = ?config(server_opts, Config),
+ {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
+
+ Server =
+ ssl_test_lib:start_server([{node, ServerNode}, {port, 0},
+ {from, self()},
+ {mfa, {?MODULE, session_info_result, []}},
+ {options, ServerOpts}]),
+ Port = ssl_test_lib:inet_port(Server),
+ Client0 =
+ ssl_test_lib:start_client([{node, ClientNode},
+ {port, Port}, {host, Hostname},
+ {mfa, {ssl_test_lib, no_result, []}},
+ {from, self()}, {options, ClientOpts}]),
+ SessionInfo =
+ receive
+ {Server, Info} ->
+ Info
+ end,
+
+ Server ! listen,
+
+ %% Make sure session is registered
+ test_server:sleep(?SLEEP),
+
+ Client1 =
+ ssl_test_lib:start_client([{node, ClientNode},
+ {port, Port}, {host, Hostname},
+ {mfa, {?MODULE, session_info_result, []}},
+ {from, self()}, {options, ClientOpts}]),
+ receive
+ {Client1, SessionInfo} ->
+ ok;
+ {Client1, Other} ->
+ test_server:format("Expected: ~p, Unexpected: ~p~n",
+ [SessionInfo, Other]),
+ test_server:fail(session_not_reused)
+ end,
+
+ Server ! listen,
+
+ Client2 =
+ ssl_test_lib:start_client([{node, ClientNode},
+ {port, Port}, {host, Hostname},
+ {mfa, {?MODULE, session_info_result, []}},
+ {from, self()}, {options, [{reuse_sessions, false}
+ | ClientOpts]}]),
+ receive
+ {Client2, SessionInfo} ->
+ test_server:fail(
+ session_reused_when_session_reuse_disabled_by_client);
+ {Client2, _} ->
+ ok
+ end,
+
+ ssl_test_lib:close(Server),
+ ssl_test_lib:close(Client0),
+ ssl_test_lib:close(Client1),
+ ssl_test_lib:close(Client2),
+
+
+ Server1 =
+ ssl_test_lib:start_server([{node, ServerNode}, {port, 0},
+ {from, self()},
+ {mfa, {?MODULE, session_info_result, []}},
+ {options, [{reuse_sessions, false} | ServerOpts]}]),
+
+ Port1 = ssl_test_lib:inet_port(Server1),
+ Client3 =
+ ssl_test_lib:start_client([{node, ClientNode},
+ {port, Port1}, {host, Hostname},
+ {mfa, {?MODULE, session_info_result, []}},
+ {from, self()}, {options, ClientOpts}]),
+
+ SessionInfo1 =
+ receive
+ {Server1, Info1} ->
+ Info1
+ end,
+
+ Server1 ! listen,
+
+ %% Make sure session is registered
+ test_server:sleep(?SLEEP),
+
+ Client4 =
+ ssl_test_lib:start_client([{node, ClientNode},
+ {port, Port1}, {host, Hostname},
+ {mfa, {?MODULE, session_info_result, []}},
+ {from, self()}, {options, ClientOpts}]),
+
+ receive
+ {Client4, SessionInfo1} ->
+ test_server:fail(
+ session_reused_when_session_reuse_disabled_by_server);
+ {Client4, _Other} ->
+ ok
+ end,
+
+ ssl_test_lib:close(Server1),
+ ssl_test_lib:close(Client3),
+ ssl_test_lib:close(Client4),
+ process_flag(trap_exit, false).
+
+
+session_info_result(Socket) ->
+ ssl:session_info(Socket).
+
+%%--------------------------------------------------------------------
+reuse_session_expired(doc) ->
+ ["Test sessions is not reused when it has expired"];
+
+reuse_session_expired(suite) ->
+ [];
+
+reuse_session_expired(Config) when is_list(Config) ->
+ process_flag(trap_exit, true),
+ ClientOpts = ?config(client_opts, Config),
+ ServerOpts = ?config(server_opts, Config),
+ {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
+
+ Server =
+ ssl_test_lib:start_server([{node, ServerNode}, {port, 0},
+ {from, self()},
+ {mfa, {?MODULE, session_info_result, []}},
+ {options, ServerOpts}]),
+ Port = ssl_test_lib:inet_port(Server),
+ Client0 =
+ ssl_test_lib:start_client([{node, ClientNode},
+ {port, Port}, {host, Hostname},
+ {mfa, {ssl_test_lib, no_result, []}},
+ {from, self()}, {options, ClientOpts}]),
+ SessionInfo =
+ receive
+ {Server, Info} ->
+ Info
+ end,
+
+ Server ! listen,
+
+ %% Make sure session is registered
+ test_server:sleep(?SLEEP),
+
+ Client1 =
+ ssl_test_lib:start_client([{node, ClientNode},
+ {port, Port}, {host, Hostname},
+ {mfa, {?MODULE, session_info_result, []}},
+ {from, self()}, {options, ClientOpts}]),
+ receive
+ {Client1, SessionInfo} ->
+ ok;
+ {Client1, Other} ->
+ test_server:format("Expected: ~p, Unexpected: ~p~n",
+ [SessionInfo, Other]),
+ test_server:fail(session_not_reused)
+ end,
+
+ Server ! listen,
+
+ %% Make sure session is unregistered due to expiration
+ test_server:sleep((?EXPIRE+1) * 1000),
+
+ Client2 =
+ ssl_test_lib:start_client([{node, ClientNode},
+ {port, Port}, {host, Hostname},
+ {mfa, {?MODULE, session_info_result, []}},
+ {from, self()}, {options, ClientOpts}]),
+ receive
+ {Client2, SessionInfo} ->
+ test_server:fail(session_reused_when_session_expired);
+ {Client2, _} ->
+ ok
+ end,
+
+ ssl_test_lib:close(Server),
+ ssl_test_lib:close(Client0),
+ ssl_test_lib:close(Client1),
+ ssl_test_lib:close(Client2),
+ process_flag(trap_exit, false).
+%%--------------------------------------------------------------------
+server_does_not_want_to_reuse_session(doc) ->
+ ["Test reuse of sessions (short handshake)"];
+
+server_does_not_want_to_reuse_session(suite) ->
+ [];
+
+server_does_not_want_to_reuse_session(Config) when is_list(Config) ->
+ ClientOpts = ?config(client_opts, Config),
+ ServerOpts = ?config(server_opts, Config),
+ {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
+
+ Server =
+ ssl_test_lib:start_server([{node, ServerNode}, {port, 0},
+ {from, self()},
+ {mfa, {?MODULE, session_info_result, []}},
+ {options, [{reuse_session, fun(_,_,_,_) ->
+ false
+ end} |
+ ServerOpts]}]),
+ Port = ssl_test_lib:inet_port(Server),
+ Client0 =
+ ssl_test_lib:start_client([{node, ClientNode},
+ {port, Port}, {host, Hostname},
+ {mfa, {ssl_test_lib, no_result, []}},
+ {from, self()}, {options, ClientOpts}]),
+ SessionInfo =
+ receive
+ {Server, Info} ->
+ Info
+ end,
+
+ Server ! listen,
+
+ %% Make sure session is registered
+ test_server:sleep(?SLEEP),
+
+ Client1 =
+ ssl_test_lib:start_client([{node, ClientNode},
+ {port, Port}, {host, Hostname},
+ {mfa, {?MODULE, session_info_result, []}},
+ {from, self()}, {options, ClientOpts}]),
+ receive
+ {Client1, SessionInfo} ->
+ test_server:fail(session_reused_when_server_does_not_want_to);
+ {Client1, _Other} ->
+ ok
+ end,
+
+ ssl_test_lib:close(Server),
+ ssl_test_lib:close(Client0),
+ ssl_test_lib:close(Client1),
+ process_flag(trap_exit, false).
+
+%%--------------------------------------------------------------------
+
+server_verify_peer_passive(doc) ->
+ ["Test server option verify_peer"];
+
+server_verify_peer_passive(suite) ->
+ [];
+
+server_verify_peer_passive(Config) when is_list(Config) ->
+ ClientOpts = ?config(client_verification_opts, Config),
+ ServerOpts = ?config(server_verification_opts, Config),
+ {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
+ Server = ssl_test_lib:start_server([{node, ServerNode}, {port, 0},
+ {from, self()},
+ {mfa, {?MODULE, send_recv_result, []}},
+ {options, [{active, false}, {verify, verify_peer}
+ | ServerOpts]}]),
+ Port = ssl_test_lib:inet_port(Server),
+ Client = ssl_test_lib:start_client([{node, ClientNode}, {port, Port},
+ {host, Hostname},
+ {from, self()},
+ {mfa, {?MODULE, send_recv_result, []}},
+ {options, [{active, false} | ClientOpts]}]),
+
+ ssl_test_lib:check_result(Server, ok, Client, ok),
+ ssl_test_lib:close(Server),
+ ssl_test_lib:close(Client).
+
+%%--------------------------------------------------------------------
+
+server_verify_peer_active(doc) ->
+ ["Test server option verify_peer"];
+
+server_verify_peer_active(suite) ->
+ [];
+
+server_verify_peer_active(Config) when is_list(Config) ->
+ ClientOpts = ?config(client_verification_opts, Config),
+ ServerOpts = ?config(server_verification_opts, Config),
+ {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
+ Server = ssl_test_lib:start_server([{node, ServerNode}, {port, 0},
+ {from, self()},
+ {mfa, {?MODULE, send_recv_result_active, []}},
+ {options, [{active, true}, {verify, verify_peer}
+ | ServerOpts]}]),
+ Port = ssl_test_lib:inet_port(Server),
+ Client = ssl_test_lib:start_client([{node, ClientNode}, {port, Port},
+ {host, Hostname},
+ {from, self()},
+ {mfa, {?MODULE, send_recv_result_active, []}},
+ {options, [{active, true} | ClientOpts]}]),
+
+ ssl_test_lib:check_result(Server, ok, Client, ok),
+ ssl_test_lib:close(Server),
+ ssl_test_lib:close(Client).
+
+%%--------------------------------------------------------------------
+server_verify_peer_active_once(doc) ->
+ ["Test server option verify_peer"];
+
+server_verify_peer_active_once(suite) ->
+ [];
+
+server_verify_peer_active_once(Config) when is_list(Config) ->
+ ClientOpts = ?config(client_verification_opts, Config),
+ ServerOpts = ?config(server_verification_opts, Config),
+ {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
+ Server = ssl_test_lib:start_server([{node, ServerNode}, {port, 0},
+ {from, self()},
+ {mfa, {?MODULE, send_recv_result_active_once, []}},
+ {options, [{active, once}, {verify, verify_peer}
+ | ServerOpts]}]),
+ Port = ssl_test_lib:inet_port(Server),
+ Client = ssl_test_lib:start_client([{node, ClientNode}, {port, Port},
+ {host, Hostname},
+ {from, self()},
+ {mfa, {?MODULE, send_recv_result_active_once, []}},
+ {options, [{active, once} | ClientOpts]}]),
+
+ ssl_test_lib:check_result(Server, ok, Client, ok),
+ ssl_test_lib:close(Server),
+ ssl_test_lib:close(Client).
+
+%%--------------------------------------------------------------------
+
+server_verify_none_passive(doc) ->
+ ["Test server option verify_none"];
+
+server_verify_none_passive(suite) ->
+ [];
+
+server_verify_none_passive(Config) when is_list(Config) ->
+ ClientOpts = ?config(client_opts, Config),
+ ServerOpts = ?config(server_opts, Config),
+ {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
+ Server = ssl_test_lib:start_server([{node, ServerNode}, {port, 0},
+ {from, self()},
+ {mfa, {?MODULE, send_recv_result, []}},
+ {options, [{active, false}, {verify, verify_none}
+ | ServerOpts]}]),
+ Port = ssl_test_lib:inet_port(Server),
+ Client = ssl_test_lib:start_client([{node, ClientNode}, {port, Port},
+ {host, Hostname},
+ {from, self()},
+ {mfa, {?MODULE, send_recv_result, []}},
+ {options, [{active, false} | ClientOpts]}]),
+
+ ssl_test_lib:check_result(Server, ok, Client, ok),
+ ssl_test_lib:close(Server),
+ ssl_test_lib:close(Client).
+
+%%--------------------------------------------------------------------
+
+server_verify_none_active(doc) ->
+ ["Test server option verify_none"];
+
+server_verify_none_active(suite) ->
+ [];
+
+server_verify_none_active(Config) when is_list(Config) ->
+ ClientOpts = ?config(client_opts, Config),
+ ServerOpts = ?config(server_opts, Config),
+ {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
+ Server = ssl_test_lib:start_server([{node, ServerNode}, {port, 0},
+ {from, self()},
+ {mfa, {?MODULE, send_recv_result_active, []}},
+ {options, [{active, true}, {verify, verify_none} |
+ ServerOpts]}]),
+ Port = ssl_test_lib:inet_port(Server),
+ Client = ssl_test_lib:start_client([{node, ClientNode}, {port, Port},
+ {host, Hostname},
+ {from, self()},
+ {mfa, {?MODULE, send_recv_result_active, []}},
+ {options, [{active, true} | ClientOpts]}]),
+
+ ssl_test_lib:check_result(Server, ok, Client, ok),
+ ssl_test_lib:close(Server),
+ ssl_test_lib:close(Client).
+
+%%--------------------------------------------------------------------
+server_verify_none_active_once(doc) ->
+ ["Test server option verify_none"];
+
+server_verify_none_active_once(suite) ->
+ [];
+
+server_verify_none_active_once(Config) when is_list(Config) ->
+ ClientOpts = ?config(client_opts, Config),
+ ServerOpts = ?config(server_opts, Config),
+ {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
+ Server = ssl_test_lib:start_server([{node, ServerNode}, {port, 0},
+ {from, self()},
+ {mfa, {?MODULE, send_recv_result_active_once, []}},
+ {options, [{active, once}, {verify, verify_none}
+ | ServerOpts]}]),
+ Port = ssl_test_lib:inet_port(Server),
+ Client = ssl_test_lib:start_client([{node, ClientNode}, {port, Port},
+ {host, Hostname},
+ {from, self()},
+ {mfa, {?MODULE, send_recv_result_active_once, []}},
+ {options, [{active, once} | ClientOpts]}]),
+
+ ssl_test_lib:check_result(Server, ok, Client, ok),
+ ssl_test_lib:close(Server),
+ ssl_test_lib:close(Client).
+%%--------------------------------------------------------------------
+
+server_verify_client_once_passive(doc) ->
+ ["Test server option verify_client_once"];
+
+server_verify_client_once_passive(suite) ->
+ [];
+
+server_verify_client_once_passive(Config) when is_list(Config) ->
+ ClientOpts = ?config(client_opts, Config),
+ ServerOpts = ?config(server_verification_opts, Config),
+ {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
+ Server = ssl_test_lib:start_server([{node, ServerNode}, {port, 0},
+ {from, self()},
+ {mfa, {?MODULE, send_recv_result, []}},
+ {options, [{active, false}, {verify, verify_peer},
+ {verify_client_once, true}
+ | ServerOpts]}]),
+ Port = ssl_test_lib:inet_port(Server),
+ Client0 = ssl_test_lib:start_client([{node, ClientNode}, {port, Port},
+ {host, Hostname},
+ {from, self()},
+ {mfa, {?MODULE, send_recv_result, []}},
+ {options, [{active, false} | ClientOpts]}]),
+
+ ssl_test_lib:check_result(Server, ok, Client0, ok),
+ ssl_test_lib:close(Client0),
+ Server ! listen,
+ Client1 = ssl_test_lib:start_client([{node, ClientNode}, {port, Port},
+ {host, Hostname},
+ {from, self()},
+ {mfa, {?MODULE, result_ok, []}},
+ {options, [{active, false} | ClientOpts]}]),
+
+ ssl_test_lib:check_result(Client1, ok),
+ ssl_test_lib:close(Server),
+ ssl_test_lib:close(Client1).
+
+%%--------------------------------------------------------------------
+
+server_verify_client_once_active(doc) ->
+ ["Test server option verify_client_once"];
+
+server_verify_client_once_active(suite) ->
+ [];
+
+server_verify_client_once_active(Config) when is_list(Config) ->
+ ClientOpts = ?config(client_opts, Config),
+ ServerOpts = ?config(server_verification_opts, Config),
+ {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
+ Server = ssl_test_lib:start_server([{node, ServerNode}, {port, 0},
+ {from, self()},
+ {mfa, {?MODULE, send_recv_result_active, []}},
+ {options, [{active, once}, {verify, verify_peer},
+ {verify_client_once, true}
+ | ServerOpts]}]),
+ Port = ssl_test_lib:inet_port(Server),
+ Client0 = ssl_test_lib:start_client([{node, ClientNode}, {port, Port},
+ {host, Hostname},
+ {from, self()},
+ {mfa, {?MODULE, send_recv_result_active, []}},
+ {options, [{active, true} | ClientOpts]}]),
+
+ ssl_test_lib:check_result(Server, ok, Client0, ok),
+ ssl_test_lib:close(Client0),
+ Server ! listen,
+ Client1 = ssl_test_lib:start_client([{node, ClientNode}, {port, Port},
+ {host, Hostname},
+ {from, self()},
+ {mfa, {?MODULE, result_ok, []}},
+ {options, [{active, true} | ClientOpts]}]),
+
+ ssl_test_lib:check_result(Client1, ok),
+ ssl_test_lib:close(Server),
+ ssl_test_lib:close(Client1).
+
+
+%%--------------------------------------------------------------------
+
+server_verify_client_once_active_once(doc) ->
+ ["Test server option verify_client_once"];
+
+server_verify_client_once_active_once(suite) ->
+ [];
+
+server_verify_client_once_active_once(Config) when is_list(Config) ->
+ ClientOpts = ?config(client_opts, Config),
+ ServerOpts = ?config(server_verification_opts, Config),
+ {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
+ Server = ssl_test_lib:start_server([{node, ServerNode}, {port, 0},
+ {from, self()},
+ {mfa, {?MODULE, send_recv_result_active_once, []}},
+ {options, [{active, once}, {verify, verify_peer},
+ {verify_client_once, true}
+ | ServerOpts]}]),
+ Port = ssl_test_lib:inet_port(Server),
+ Client0 = ssl_test_lib:start_client([{node, ClientNode}, {port, Port},
+ {host, Hostname},
+ {from, self()},
+ {mfa, {?MODULE, send_recv_result_active_once, []}},
+ {options, [{active, once} | ClientOpts]}]),
+
+ ssl_test_lib:check_result(Server, ok, Client0, ok),
+ ssl_test_lib:close(Client0),
+ Server ! listen,
+
+ Client1 = ssl_test_lib:start_client([{node, ClientNode}, {port, Port},
+ {host, Hostname},
+ {from, self()},
+ {mfa, {?MODULE, result_ok, []}},
+ {options, [{active, once} | ClientOpts]}]),
+
+ ssl_test_lib:check_result(Client1, ok),
+ ssl_test_lib:close(Server),
+ ssl_test_lib:close(Client1).
+
+%%--------------------------------------------------------------------
+
+server_verify_no_cacerts(doc) ->
+ ["Test server must have cacerts if it wants to verify client"];
+
+server_verify_no_cacerts(suite) ->
+ [];
+
+server_verify_no_cacerts(Config) when is_list(Config) ->
+ ServerOpts = ServerOpts = ?config(server_opts, Config),
+ {_, ServerNode, _} = ssl_test_lib:run_where(Config),
+ Server = ssl_test_lib:start_server_error([{node, ServerNode}, {port, 0},
+ {from, self()},
+ {options, [{verify, verify_peer}
+ | ServerOpts]}]),
+
+ ssl_test_lib:check_result(Server, {error, {eoptions, {cacertfile, ""}}}).
+
+%%--------------------------------------------------------------------
+
+server_require_peer_cert_ok(doc) ->
+ ["Test server option fail_if_no_peer_cert when peer sends cert"];
+
+server_require_peer_cert_ok(suite) ->
+ [];
+
+server_require_peer_cert_ok(Config) when is_list(Config) ->
+ ServerOpts = [{verify, verify_peer}, {fail_if_no_peer_cert, true}
+ | ?config(server_verification_opts, Config)],
+ ClientOpts = ?config(client_verification_opts, Config),
+ {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
+
+ Server = ssl_test_lib:start_server([{node, ServerNode}, {port, 0},
+ {from, self()},
+ {mfa, {?MODULE, send_recv_result, []}},
+ {options, [{active, false} | ServerOpts]}]),
+ Port = ssl_test_lib:inet_port(Server),
+ Client = ssl_test_lib:start_client([{node, ClientNode}, {port, Port},
+ {host, Hostname},
+ {from, self()},
+ {mfa, {?MODULE, send_recv_result, []}},
+ {options, [{active, false} | ClientOpts]}]),
+
+ ssl_test_lib:check_result(Server, ok, Client, ok),
+ ssl_test_lib:close(Server),
+ ssl_test_lib:close(Client).
+
+%%--------------------------------------------------------------------
+
+server_require_peer_cert_fail(doc) ->
+ ["Test server option fail_if_no_peer_cert when peer doesn't send cert"];
+
+server_require_peer_cert_fail(suite) ->
+ [];
+
+server_require_peer_cert_fail(Config) when is_list(Config) ->
+ ServerOpts = [{verify, verify_peer}, {fail_if_no_peer_cert, true}
+ | ?config(server_verification_opts, Config)],
+ BadClientOpts = ?config(client_opts, Config),
+ {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
+
+ Server = ssl_test_lib:start_server_error([{node, ServerNode}, {port, 0},
+ {from, self()},
+ {mfa, {?MODULE, no_result, []}},
+ {options, [{active, false} | ServerOpts]}]),
+
+ Port = ssl_test_lib:inet_port(Server),
+
+ Client = ssl_test_lib:start_client_error([{node, ClientNode}, {port, Port},
+ {host, Hostname},
+ {from, self()},
+ {mfa, {?MODULE, no_result, []}},
+ {options, [{active, false} | BadClientOpts]}]),
+
+ ssl_test_lib:check_result(Server, {error, esslaccept},
+ Client, {error, esslconnect}),
+ ssl_test_lib:close(Server),
+ ssl_test_lib:close(Client).
+
+%%--------------------------------------------------------------------
+
+client_verify_none_passive(doc) ->
+ ["Test client option verify_none"];
+
+client_verify_none_passive(suite) ->
+ [];
+
+client_verify_none_passive(Config) when is_list(Config) ->
+ ClientOpts = ?config(client_opts, Config),
+ ServerOpts = ?config(server_opts, Config),
+ {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
+ Server = ssl_test_lib:start_server([{node, ServerNode}, {port, 0},
+ {from, self()},
+ {mfa, {?MODULE, send_recv_result, []}},
+ {options, [{active, false}
+ | ServerOpts]}]),
+ Port = ssl_test_lib:inet_port(Server),
+
+ Client = ssl_test_lib:start_client([{node, ClientNode}, {port, Port},
+ {host, Hostname},
+ {from, self()},
+ {mfa, {?MODULE, send_recv_result, []}},
+ {options, [{active, false},
+ {verify, verify_none}
+ | ClientOpts]}]),
+
+ ssl_test_lib:check_result(Server, ok, Client, ok),
+ ssl_test_lib:close(Server),
+ ssl_test_lib:close(Client).
+
+%%--------------------------------------------------------------------
+
+client_verify_none_active(doc) ->
+ ["Test client option verify_none"];
+
+client_verify_none_active(suite) ->
+ [];
+
+client_verify_none_active(Config) when is_list(Config) ->
+ ClientOpts = ?config(client_opts, Config),
+ ServerOpts = ?config(server_opts, Config),
+ {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
+ Server = ssl_test_lib:start_server([{node, ServerNode}, {port, 0},
+ {from, self()},
+ {mfa, {?MODULE,
+ send_recv_result_active, []}},
+ {options, [{active, true}
+ | ServerOpts]}]),
+ Port = ssl_test_lib:inet_port(Server),
+ Client = ssl_test_lib:start_client([{node, ClientNode}, {port, Port},
+ {host, Hostname},
+ {from, self()},
+ {mfa, {?MODULE,
+ send_recv_result_active, []}},
+ {options, [{active, true},
+ {verify, verify_none}
+ | ClientOpts]}]),
+
+ ssl_test_lib:check_result(Server, ok, Client, ok),
+ ssl_test_lib:close(Server),
+ ssl_test_lib:close(Client).
+
+%%--------------------------------------------------------------------
+client_verify_none_active_once(doc) ->
+ ["Test client option verify_none"];
+
+client_verify_none_active_once(suite) ->
+ [];
+
+client_verify_none_active_once(Config) when is_list(Config) ->
+ ClientOpts = ?config(client_opts, Config),
+ ServerOpts = ?config(server_opts, Config),
+
+ {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
+ Server = ssl_test_lib:start_server([{node, ServerNode}, {port, 0},
+ {from, self()},
+ {mfa, {?MODULE, send_recv_result_active_once, []}},
+ {options, [{active, once} | ServerOpts]}]),
+ Port = ssl_test_lib:inet_port(Server),
+ %% TODO: send message to test process to make sure
+ %% verifyfun has beeen run as it has the same behavior as
+ %% the default fun
+ VerifyFun = fun([{bad_cert, unknown_ca}]) ->
+ true;
+ (_) ->
+ false
+ end,
+ Client = ssl_test_lib:start_client([{node, ClientNode}, {port, Port},
+ {host, Hostname},
+ {from, self()},
+ {mfa, {?MODULE,
+ send_recv_result_active_once,
+ []}},
+ {options, [{active, once},
+ {verify, verify_none},
+ {verify_fun, VerifyFun}
+ | ClientOpts]}]),
+
+ ssl_test_lib:check_result(Server, ok, Client, ok),
+ ssl_test_lib:close(Server),
+ ssl_test_lib:close(Client).
+
+
+
+%%--------------------------------------------------------------------
+client_renegotiate(doc) ->
+ ["Test ssl:renegotiate/1 on client."];
+
+client_renegotiate(suite) ->
+ [];
+
+client_renegotiate(Config) when is_list(Config) ->
+ process_flag(trap_exit, true),
+ ServerOpts = ?config(server_opts, Config),
+ ClientOpts = ?config(client_opts, Config),
+
+ {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
+
+ Data = "From erlang to erlang",
+
+ Server =
+ ssl_test_lib:start_server([{node, ServerNode}, {port, 0},
+ {from, self()},
+ {mfa, {?MODULE, erlang_ssl_receive, [Data]}},
+ {options, ServerOpts}]),
+ Port = ssl_test_lib:inet_port(Server),
+
+ Client = ssl_test_lib:start_client([{node, ClientNode}, {port, Port},
+ {host, Hostname},
+ {from, self()},
+ {mfa, {?MODULE,
+ renegotiate, [Data]}},
+ {options, [{reuse_sessions, false} | ClientOpts]}]),
+
+ ssl_test_lib:check_result(Client, ok, Server, ok),
+
+ ssl_test_lib:close(Server),
+ ssl_test_lib:close(Client),
+ process_flag(trap_exit, false),
+ ok.
+%%--------------------------------------------------------------------
+server_renegotiate(doc) ->
+ ["Test ssl:renegotiate/1 on server."];
+
+server_renegotiate(suite) ->
+ [];
+
+server_renegotiate(Config) when is_list(Config) ->
+ process_flag(trap_exit, true),
+ ServerOpts = ?config(server_opts, Config),
+ ClientOpts = ?config(client_opts, Config),
+
+ {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
+
+ Data = "From erlang to erlang",
+
+ Server = ssl_test_lib:start_server([{node, ServerNode}, {port, 0},
+ {from, self()},
+ {mfa, {?MODULE,
+ renegotiate, [Data]}},
+ {options, ServerOpts}]),
+ Port = ssl_test_lib:inet_port(Server),
+
+ Client = ssl_test_lib:start_client([{node, ClientNode}, {port, Port},
+ {host, Hostname},
+ {from, self()},
+ {mfa, {?MODULE, erlang_ssl_receive, [Data]}},
+ {options, [{reuse_sessions, false} | ClientOpts]}]),
+
+ ssl_test_lib:check_result(Server, ok, Client, ok),
+ ssl_test_lib:close(Server),
+ ssl_test_lib:close(Client),
+ ok.
+
+%%--------------------------------------------------------------------
+client_no_wrap_sequence_number(doc) ->
+ ["Test that erlang client will renegotiate session when",
+ "max sequence number celing is about to be reached. Although"
+ "in the testcase we use the test option renegotiate_at"
+ " to lower treashold substantially."];
+
+client_no_wrap_sequence_number(suite) ->
+ [];
+
+client_no_wrap_sequence_number(Config) when is_list(Config) ->
+ process_flag(trap_exit, true),
+ ServerOpts = ?config(server_opts, Config),
+ ClientOpts = ?config(client_opts, Config),
+
+ {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
+
+ ErlData = "From erlang to erlang",
+ N = 10,
+
+ Server =
+ ssl_test_lib:start_server([{node, ServerNode}, {port, 0},
+ {from, self()},
+ {mfa, {ssl_test_lib, no_result, []}},
+ {options, ServerOpts}]),
+ Port = ssl_test_lib:inet_port(Server),
+
+ Client = ssl_test_lib:start_client([{node, ClientNode}, {port, Port},
+ {host, Hostname},
+ {from, self()},
+ {mfa, {ssl_test_lib,
+ trigger_renegotiate, [[ErlData, N+2]]}},
+ {options, [{reuse_sessions, false},
+ {renegotiate_at, N} | ClientOpts]}]),
+
+ ssl_test_lib:check_result(Client, ok),
+
+ ssl_test_lib:close(Server),
+ ssl_test_lib:close(Client),
+ process_flag(trap_exit, false),
+ ok.
+%%--------------------------------------------------------------------
+server_no_wrap_sequence_number(doc) ->
+ ["Test that erlang server will renegotiate session when",
+ "max sequence number celing is about to be reached. Although"
+ "in the testcase we use the test option renegotiate_at"
+ " to lower treashold substantially."];
+
+server_no_wrap_sequence_number(suite) ->
+ [];
+
+server_no_wrap_sequence_number(Config) when is_list(Config) ->
+ process_flag(trap_exit, true),
+ ServerOpts = ?config(server_opts, Config),
+ ClientOpts = ?config(client_opts, Config),
+
+ {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
+
+ Data = "From erlang to erlang",
+ N = 10,
+
+ Server = ssl_test_lib:start_server([{node, ServerNode}, {port, 0},
+ {from, self()},
+ {mfa, {ssl_test_lib,
+ trigger_renegotiate, [[Data, N+2]]}},
+ {options, [{renegotiate_at, N} | ServerOpts]}]),
+ Port = ssl_test_lib:inet_port(Server),
+
+ Client = ssl_test_lib:start_client([{node, ClientNode}, {port, Port},
+ {host, Hostname},
+ {from, self()},
+ {mfa, {ssl_test_lib, no_result, []}},
+ {options, [{reuse_sessions, false} | ClientOpts]}]),
+
+ ssl_test_lib:check_result(Server, ok),
+ ssl_test_lib:close(Server),
+ ssl_test_lib:close(Client),
+ ok.
+
+%%--------------------------------------------------------------------
+extended_key_usage(doc) ->
+ ["Test cert that has a critical extended_key_usage extension"];
+
+extended_key_usage(suite) ->
+ [];
+
+extended_key_usage(Config) when is_list(Config) ->
+ ClientOpts = ?config(client_opts, Config),
+ ServerOpts = ?config(server_opts, Config),
+ PrivDir = ?config(priv_dir, Config),
+
+ CertFile = proplists:get_value(certfile, ServerOpts),
+ KeyFile = proplists:get_value(keyfile, ServerOpts),
+ NewCertFile = filename:join(PrivDir, "cert.pem"),
+
+ {ok, [{cert, DerCert, _}]} = public_key:pem_to_der(CertFile),
+
+ {ok, [KeyInfo]} = public_key:pem_to_der(KeyFile),
+
+ {ok, Key} = public_key:decode_private_key(KeyInfo),
+
+ {ok, OTPCert} = public_key:pkix_decode_cert(DerCert, otp),
+
+ ExtKeyUsageExt = {'Extension', ?'id-ce-extKeyUsage', true, [?'id-kp-serverAuth']},
+
+ OTPTbsCert = OTPCert#'OTPCertificate'.tbsCertificate,
+
+ Extensions = OTPTbsCert#'OTPTBSCertificate'.extensions,
+
+ NewOTPTbsCert = OTPTbsCert#'OTPTBSCertificate'{extensions = [ExtKeyUsageExt |Extensions]},
+
+ NewDerCert = public_key:sign(NewOTPTbsCert, Key),
+
+ public_key:der_to_pem(NewCertFile, [{cert, NewDerCert}]),
+
+ NewServerOpts = [{certfile, NewCertFile} | proplists:delete(certfile, ServerOpts)],
+
+ {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
+
+ Server = ssl_test_lib:start_server([{node, ServerNode}, {port, 0},
+ {from, self()},
+ {mfa, {?MODULE, send_recv_result_active, []}},
+ {options, NewServerOpts}]),
+ Port = ssl_test_lib:inet_port(Server),
+ Client = ssl_test_lib:start_client([{node, ClientNode}, {port, Port},
+ {host, Hostname},
+ {from, self()},
+ {mfa, {?MODULE, send_recv_result_active, []}},
+ {options, ClientOpts}]),
+
+ ssl_test_lib:check_result(Server, ok, Client, ok),
+
+ ssl_test_lib:close(Server),
+ ssl_test_lib:close(Client).
+
+%%--------------------------------------------------------------------
+validate_extensions_fun(doc) ->
+ ["Test that it is possible to specify a validate_extensions_fun"];
+
+validate_extensions_fun(suite) ->
+ [];
+
+validate_extensions_fun(Config) when is_list(Config) ->
+ ClientOpts = ?config(client_verification_opts, Config),
+ ServerOpts = ?config(server_verification_opts, Config),
+
+ Fun = fun(Extensions, State, _, AccError) ->
+ {Extensions, State, AccError}
+ end,
+
+ {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
+
+ Server = ssl_test_lib:start_server([{node, ServerNode}, {port, 0},
+ {from, self()},
+ {mfa, {?MODULE, send_recv_result_active, []}},
+ {options, [{validate_extensions_fun, Fun},
+ {verify, verify_peer} | ServerOpts]}]),
+ Port = ssl_test_lib:inet_port(Server),
+
+ Client = ssl_test_lib:start_client([{node, ClientNode}, {port, Port},
+ {host, Hostname},
+ {from, self()},
+ {mfa, {?MODULE, send_recv_result_active, []}},
+ {options,[{validate_extensions_fun, Fun} | ClientOpts]}]),
+
+ ssl_test_lib:check_result(Server, ok, Client, ok),
+
+ ssl_test_lib:close(Server),
+ ssl_test_lib:close(Client).
+
+%%--------------------------------------------------------------------
+%%% Internal functions
+%%--------------------------------------------------------------------
+send_recv_result(Socket) ->
+ ssl:send(Socket, "Hello world"),
+ {ok,"Hello world"} = ssl:recv(Socket, 11),
+ ok.
+
+send_recv_result_active(Socket) ->
+ ssl:send(Socket, "Hello world"),
+ receive
+ {ssl, Socket, "Hello world"} ->
+ ok
+ end.
+
+send_recv_result_active_once(Socket) ->
+ ssl:send(Socket, "Hello world"),
+ receive
+ {ssl, Socket, "Hello world"} ->
+ ok
+ end.
+
+result_ok(_Socket) ->
+ ok.
+
+renegotiate(Socket, Data) ->
+ test_server:format("Renegotiating ~n", []),
+ Result = ssl:renegotiate(Socket),
+ test_server:format("Result ~p~n", [Result]),
+ ssl:send(Socket, Data),
+ case Result of
+ ok ->
+ ok;
+ %% It is not an error in erlang ssl
+ %% if peer rejects renegotiation.
+ %% Connection will stay up
+ {error, renegotiation_rejected} ->
+ ok;
+ Other ->
+ Other
+ end.
+
+session_cache_process_list(doc) ->
+ ["Test reuse of sessions (short handshake)"];
+
+session_cache_process_list(suite) ->
+ [];
+session_cache_process_list(Config) when is_list(Config) ->
+ session_cache_process(list,Config).
+
+session_cache_process_mnesia(doc) ->
+ ["Test reuse of sessions (short handshake)"];
+
+session_cache_process_mnesia(suite) ->
+ [];
+session_cache_process_mnesia(Config) when is_list(Config) ->
+ session_cache_process(mnesia,Config).
+
+session_cache_process(Type,Config) when is_list(Config) ->
+ process_flag(trap_exit, true),
+ setup_session_cb(Type),
+
+ ClientOpts = ?config(client_opts, Config),
+ ServerOpts = ?config(server_opts, Config),
+ {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
+
+ Server =
+ ssl_test_lib:start_server([{node, ServerNode}, {port, 0},
+ {from, self()},
+ {mfa, {?MODULE, session_info_result, []}},
+ {options,
+ [{session_cache_cb, ?MODULE}|
+ ServerOpts]}]),
+ Port = ssl_test_lib:inet_port(Server),
+ Client0 =
+ ssl_test_lib:start_client([{node, ClientNode},
+ {port, Port}, {host, Hostname},
+ {mfa, {ssl_test_lib, no_result, []}},
+ {from, self()}, {options, ClientOpts}]),
+ SessionInfo =
+ receive
+ {Server, Info} ->
+ Info
+ end,
+
+ Server ! listen,
+
+ %% Make sure session is registered
+ test_server:sleep(?SLEEP),
+
+ Client1 =
+ ssl_test_lib:start_client([{node, ClientNode},
+ {port, Port}, {host, Hostname},
+ {mfa, {?MODULE, session_info_result, []}},
+ {from, self()}, {options, ClientOpts}]),
+ receive
+ {Client1, SessionInfo} ->
+ ok;
+ {Client1, Other} ->
+ test_server:format("Expected: ~p, Unexpected: ~p~n",
+ [SessionInfo, Other]),
+ test_server:fail(session_not_reused)
+ end,
+
+ ssl_test_lib:close(Server),
+ ssl_test_lib:close(Client0),
+ ssl_test_lib:close(Client1),
+
+ Server1 =
+ ssl_test_lib:start_server([{node, ServerNode}, {port, 0},
+ {from, self()},
+ {mfa, {?MODULE, session_info_result, []}},
+ {options,
+ [{reuse_sessions, false} | ServerOpts]}]),
+ Port1 = ssl_test_lib:inet_port(Server1),
+
+ Client3 =
+ ssl_test_lib:start_client([{node, ClientNode},
+ {port, Port1}, {host, Hostname},
+ {mfa, {?MODULE, session_info_result, []}},
+ {from, self()}, {options, ClientOpts}]),
+
+ SessionInfo1 =
+ receive
+ {Server1, Info1} ->
+ Info1
+ end,
+
+ Server1 ! listen,
+
+ %% Make sure session is registered
+ test_server:sleep(?SLEEP),
+
+ Client4 =
+ ssl_test_lib:start_client([{node, ClientNode},
+ {port, Port1}, {host, Hostname},
+ {mfa, {?MODULE, session_info_result, []}},
+ {from, self()}, {options, ClientOpts}]),
+
+ receive
+ {Client4, SessionInfo1} ->
+ test_server:fail(
+ session_reused_when_session_reuse_disabled_by_server);
+ {Client4, _Other} ->
+ ok
+ end,
+
+ ssl_test_lib:close(Server1),
+ ssl_test_lib:close(Client3),
+ ssl_test_lib:close(Client4),
+ process_flag(trap_exit, false).
+
+setup_session_cb(Type) ->
+ ssl_test = ets:new(ssl_test,[named_table, set,public]),
+ ets:insert(ssl_test, {type,Type}).
+
+session_cb() ->
+ [{type,Type}] = ets:lookup(ssl_test, type),
+ Type.
+
+init() ->
+ io:format("~p~n",[?LINE]),
+ case session_cb() of
+ list ->
+ spawn(fun() -> session_loop([]) end);
+ mnesia ->
+ mnesia:start(),
+ {atomic,ok} = mnesia:create_table(sess_cache, [])
+ end.
+
+terminate(Cache) ->
+ io:format("~p~n",[?LINE]),
+ case session_cb() of
+ list ->
+ Cache ! terminate;
+ mnesia ->
+ {atomic,ok} = mnesia:delete_table(sess_cache, [])
+ end.
+
+lookup(Cache, Key) ->
+ io:format("~p~n",[?LINE]),
+ case session_cb() of
+ list ->
+ Cache ! {self(), lookup, Key},
+ receive {Cache, Res} -> Res end;
+ mnesia ->
+ case mnesia:transaction(fun() ->
+ mnesia:read(sess_cache,
+ Key, read)
+ end) of
+ {atomic, [Session]} -> Session;
+ _ -> undefined
+ end
+ end.
+
+update(Cache, Key, Value) ->
+ io:format("~p~n",[?LINE]),
+ case session_cb() of
+ list ->
+ Cache ! {update, Key, Value};
+ mnesia ->
+ {atomic, ok} =
+ mnesia:transaction(fun() ->
+ mnesia:write(sess_cache,
+ Key, Value)
+ end)
+ end.
+
+delete(Cache, Key) ->
+ io:format("~p~n",[?LINE]),
+ case session_cb() of
+ list ->
+ Cache ! {delete, Key};
+ mnesia ->
+ {atomic, ok} =
+ mnesia:transaction(fun() ->
+ mnesia:delete(sess_cache, Key)
+ end)
+ end.
+
+foldl(Fun, Acc, Cache) ->
+ io:format("~p~n",[?LINE]),
+ case session_cb() of
+ list ->
+ Cache ! {self(),foldl,Fun,Acc},
+ receive {Cache, Res} -> Res end;
+ mnesia ->
+ Foldl = fun() ->
+ mnesia:foldl(Fun, Acc, sess_cache)
+ end,
+ {atomic, Res} = mnesia:transaction(Foldl),
+ Res
+ end.
+
+select_session(Cache, PartialKey) ->
+ io:format("~p~n",[?LINE]),
+ case session_cb() of
+ list ->
+ Cache ! {self(),select_session, PartialKey},
+ receive {Cache, Res} -> Res end;
+ mnesia ->
+ Sel = fun() ->
+ mnesia:select(Cache,
+ [{{{PartialKey,'$1'}, '$2'},
+ [],['$$']}])
+ end,
+ {atomic, Res} = mnesia:transaction(Sel),
+ Res
+ end.
+
+session_loop(Sess) ->
+ receive
+ terminate ->
+ ok;
+ {Pid, lookup, Key} ->
+ case lists:keysearch(Key,1,Sess) of
+ {value, {Key,Value}} ->
+ Pid ! {self(), Value};
+ _ ->
+ Pid ! {self(), undefined}
+ end,
+ session_loop(Sess);
+ {update, Key, Value} ->
+ session_loop([{Key,Value}|Sess]);
+ {delete, Key} ->
+ session_loop(lists:keydelete(Key,1,Sess));
+ {Pid,foldl,Fun,Acc} ->
+ Res = lists:foldl(Fun, Acc,Sess),
+ Pid ! {self(), Res},
+ session_loop(Sess);
+ {Pid,select_session,PKey} ->
+ Sel = fun({{Head, _},Session}, Acc) when Head =:= PKey ->
+ [Session|Acc];
+ (_,Acc) ->
+ Acc
+ end,
+ Pid ! {self(), lists:foldl(Sel, [], Sess)},
+ session_loop(Sess)
+ end.
+
+erlang_ssl_receive(Socket, Data) ->
+ receive
+ {ssl, Socket, Data} ->
+ io:format("Received ~p~n",[Data]),
+ ok;
+ Other ->
+ test_server:fail({unexpected_message, Other})
+ after ?SLEEP * 3 ->
+ test_server:fail({did_not_get, Data})
+ end.
+
diff --git a/lib/ssl/test/ssl_basic_SUITE_data/RAND b/lib/ssl/test/ssl_basic_SUITE_data/RAND
new file mode 100644
index 0000000000..70997bd01f
--- /dev/null
+++ b/lib/ssl/test/ssl_basic_SUITE_data/RAND
Binary files differ
diff --git a/lib/ssl/test/ssl_basic_SUITE_data/dHParam.pem b/lib/ssl/test/ssl_basic_SUITE_data/dHParam.pem
new file mode 100644
index 0000000000..feb581da30
--- /dev/null
+++ b/lib/ssl/test/ssl_basic_SUITE_data/dHParam.pem
@@ -0,0 +1,5 @@
+-----BEGIN DH PARAMETERS-----
+MIGHAoGBAMY5VmCZ22ZEy/KO8kjt94PH7ZtSG0Z0zitlMlvd4VsNkDzXsVeu+wkH
+FGDC3h3vgv6iwXGCbmrSOVk/FPZbzLhwZ8aLnkUFOBbOvVvb1JptQwOt8mf+eScG
+M2gGBktheQV5Nf1IrzOctG7VGt+neiqb/Y86uYCcDdL+M8++0qnLAgEC
+-----END DH PARAMETERS-----
diff --git a/lib/ssl/test/ssl_packet_SUITE.erl b/lib/ssl/test/ssl_packet_SUITE.erl
new file mode 100644
index 0000000000..1bcb9a657b
--- /dev/null
+++ b/lib/ssl/test/ssl_packet_SUITE.erl
@@ -0,0 +1,1746 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 2008-2010. All Rights Reserved.
+%%
+%% The contents of this file are subject to the Erlang Public License,
+%% Version 1.1, (the "License"); you may not use this file except in
+%% compliance with the License. You should have received a copy of the
+%% Erlang Public License along with this software. If not, it can be
+%% retrieved online at http://www.erlang.org/.
+%%
+%% Software distributed under the License is distributed on an "AS IS"
+%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+%% the License for the specific language governing rights and limitations
+%% under the License.
+%%
+%% %CopyrightEnd%
+%%
+
+%%
+-module(ssl_packet_SUITE).
+
+%% Note: This directive should only be used in test suites.
+-compile(export_all).
+
+-include("test_server.hrl").
+
+-define(BYTE(X), X:8/unsigned-big-integer).
+-define(UINT16(X), X:16/unsigned-big-integer).
+-define(UINT24(X), X:24/unsigned-big-integer).
+-define(UINT32(X), X:32/unsigned-big-integer).
+-define(UINT64(X), X:64/unsigned-big-integer).
+-define(STRING(X), ?UINT32((size(X))), (X)/binary).
+
+-define(byte(X), << ?BYTE(X) >> ).
+-define(uint16(X), << ?UINT16(X) >> ).
+-define(uint24(X), << ?UINT24(X) >> ).
+-define(uint32(X), << ?UINT32(X) >> ).
+-define(uint64(X), << ?UINT64(X) >> ).
+-define(TIMEOUT, 120000).
+
+-define(MANY, 1000).
+-define(SOME, 50).
+
+
+%% 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(),
+ ssl:start(),
+ Result =
+ (catch make_certs:all(?config(data_dir, Config),
+ ?config(priv_dir, Config))),
+ test_server:format("Make certs ~p~n", [Result]),
+ ssl_test_lib:cert_options(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) ->
+ ssl:stop(),
+ 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 = ssl_test_lib: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 that erlang:decode_packet/3 seems to be handled correctly."
+ "We only use the most basic packet types in our tests as testing of"
+ "the packet types are for inet to verify"
+ ];
+
+all(suite) ->
+ [packet_raw_passive_many_small,
+ packet_0_passive_many_small, packet_1_passive_many_small,
+ packet_2_passive_many_small, packet_4_passive_many_small,
+ packet_raw_passive_some_big, packet_0_passive_some_big,
+ packet_1_passive_some_big,
+ packet_2_passive_some_big, packet_4_passive_some_big,
+ packet_raw_active_once_many_small,
+ packet_0_active_once_many_small, packet_1_active_once_many_small,
+ packet_2_active_once_many_small, packet_4_active_once_many_small,
+ packet_raw_active_once_some_big,
+ packet_0_active_once_some_big, packet_1_active_once_some_big,
+ packet_2_active_once_some_big, packet_4_active_once_some_big,
+ packet_raw_active_many_small, packet_0_active_many_small,
+ packet_1_active_many_small,
+ packet_2_active_many_small, packet_4_active_many_small,
+ packet_raw_active_some_big, packet_0_active_some_big,
+ packet_1_active_some_big, packet_2_active_some_big,
+ packet_4_active_some_big,
+ packet_send_to_large,
+ packet_wait_passive, packet_wait_active,
+ packet_baddata_passive, packet_baddata_active,
+ packet_size_passive, packet_size_active,
+ packet_erl_decode,
+ packet_http_decode,
+ packet_http_bin_decode_multi
+ ].
+
+%% Test cases starts here.
+%%--------------------------------------------------------------------
+packet_raw_passive_many_small(doc) ->
+ ["Test packet option {packet, raw} in passive mode."];
+
+packet_raw_passive_many_small(suite) ->
+ [];
+
+packet_raw_passive_many_small(Config) when is_list(Config) ->
+ ClientOpts = ?config(client_opts, Config),
+ ServerOpts = ?config(server_opts, Config),
+ {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
+
+ Data = "Packet option is {packet, raw}",
+
+ Server = ssl_test_lib:start_server([{node, ClientNode}, {port, 0},
+ {from, self()},
+ {mfa, {?MODULE, send_raw ,[Data, ?MANY]}},
+ {options, ServerOpts}]),
+ Port = ssl_test_lib:inet_port(Server),
+ Client = ssl_test_lib:start_client([{node, ServerNode}, {port, Port},
+ {host, Hostname},
+ {from, self()},
+ {mfa, {?MODULE, passive_raw, [Data, ?MANY]}},
+ {options,
+ [{active, false},
+ {packet, raw} |
+ ClientOpts]}]),
+
+ ssl_test_lib:check_result(Client, ok),
+
+ ssl_test_lib:close(Server),
+ ssl_test_lib:close(Client).
+
+%%--------------------------------------------------------------------
+
+packet_raw_passive_some_big(doc) ->
+ ["Test packet option {packet, raw} in passive mode."];
+
+packet_raw_passive_some_big(suite) ->
+ [];
+
+packet_raw_passive_some_big(Config) when is_list(Config) ->
+ ClientOpts = ?config(client_opts, Config),
+ ServerOpts = ?config(server_opts, Config),
+ {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
+
+ Data = lists:append(lists:duplicate(100, "1234567890")),
+
+ Server = ssl_test_lib:start_server([{node, ClientNode}, {port, 0},
+ {from, self()},
+ {mfa, {?MODULE, send_raw ,[Data, ?SOME]}},
+ {options, ServerOpts}]),
+ Port = ssl_test_lib:inet_port(Server),
+ Client = ssl_test_lib:start_client([{node, ServerNode}, {port, Port},
+ {host, Hostname},
+ {from, self()},
+ {mfa, {?MODULE, passive_raw, [Data, ?SOME]}},
+ {options,
+ [{active, false},
+ {packet, raw} |
+ ClientOpts]}]),
+
+ ssl_test_lib:check_result(Client, ok),
+
+ ssl_test_lib:close(Server),
+ ssl_test_lib:close(Client).
+
+%%--------------------------------------------------------------------
+packet_0_passive_many_small(doc) ->
+ ["Test packet option {packet, 0} in passive mode."];
+
+packet_0_passive_many_small(suite) ->
+ [];
+
+packet_0_passive_many_small(Config) when is_list(Config) ->
+ ClientOpts = ?config(client_opts, Config),
+ ServerOpts = ?config(server_opts, Config),
+ {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
+
+ Data = "Packet option is {packet, 0}, equivalent to packet raw.",
+
+ Server = ssl_test_lib:start_server([{node, ClientNode}, {port, 0},
+ {from, self()},
+ {mfa, {?MODULE, send_raw ,[Data, ?MANY]}},
+ {options, ServerOpts}]),
+ Port = ssl_test_lib:inet_port(Server),
+ Client = ssl_test_lib:start_client([{node, ServerNode}, {port, Port},
+ {host, Hostname},
+ {from, self()},
+ {mfa, {?MODULE, passive_raw, [Data, ?MANY]}},
+ {options, [{active, false},
+ {packet, 0} |
+ ClientOpts]}]),
+
+ ssl_test_lib:check_result(Client, ok),
+
+ ssl_test_lib:close(Server),
+ ssl_test_lib:close(Client).
+
+%%--------------------------------------------------------------------
+packet_0_passive_some_big(doc) ->
+ ["Test packet option {packet, 0} in passive mode."];
+
+packet_0_passive_some_big(suite) ->
+ [];
+
+packet_0_passive_some_big(Config) when is_list(Config) ->
+ ClientOpts = ?config(client_opts, Config),
+ ServerOpts = ?config(server_opts, Config),
+ {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
+
+ Data = lists:append(lists:duplicate(100, "1234567890")),
+
+ Server = ssl_test_lib:start_server([{node, ClientNode}, {port, 0},
+ {from, self()},
+ {mfa, {?MODULE, send_raw ,[Data, ?SOME]}},
+ {options, ServerOpts}]),
+ Port = ssl_test_lib:inet_port(Server),
+ Client = ssl_test_lib:start_client([{node, ServerNode}, {port, Port},
+ {host, Hostname},
+ {from, self()},
+ {mfa, {?MODULE, passive_raw, [Data, ?SOME]}},
+ {options, [{active, false},
+ {packet, 0} |
+ ClientOpts]}]),
+
+ ssl_test_lib:check_result(Client, ok),
+
+ ssl_test_lib:close(Server),
+ ssl_test_lib:close(Client).
+
+%%--------------------------------------------------------------------
+packet_1_passive_many_small(doc) ->
+ ["Test packet option {packet, 1} in passive mode."];
+
+packet_1_passive_many_small(suite) ->
+ [];
+
+packet_1_passive_many_small(Config) when is_list(Config) ->
+ ClientOpts = ?config(client_opts, Config),
+ ServerOpts = ?config(server_opts, Config),
+ {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
+
+ Data = "Packet option is {packet, 1}",
+
+ Server = ssl_test_lib:start_server([{node, ClientNode}, {port, 0},
+ {from, self()},
+ {mfa, {?MODULE, send, [Data, ?MANY]}},
+ {options, [{packet, 1}|ServerOpts]}]),
+ Port = ssl_test_lib:inet_port(Server),
+ Client = ssl_test_lib:start_client([{node, ServerNode}, {port, Port},
+ {host, Hostname},
+ {from, self()},
+ {mfa, {?MODULE, passive_recv_packet,
+ [Data, ?MANY]}},
+ {options, [{active, false},
+ {packet, 1} |
+ ClientOpts]}]),
+
+ ssl_test_lib:check_result(Client, ok),
+
+ ssl_test_lib:close(Server),
+ ssl_test_lib:close(Client).
+
+%%--------------------------------------------------------------------
+packet_1_passive_some_big(doc) ->
+ ["Test packet option {packet, 1} in passive mode."];
+
+packet_1_passive_some_big(suite) ->
+ [];
+
+packet_1_passive_some_big(Config) when is_list(Config) ->
+ ClientOpts = ?config(client_opts, Config),
+ ServerOpts = ?config(server_opts, Config),
+ {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
+
+ Data = lists:append(lists:duplicate(255, "1")),
+
+ Server = ssl_test_lib:start_server([{node, ClientNode}, {port, 0},
+ {from, self()},
+ {mfa, {?MODULE, send, [Data, ?SOME]}},
+ {options, [{packet, 1}|ServerOpts]}]),
+ Port = ssl_test_lib:inet_port(Server),
+ Client = ssl_test_lib:start_client([{node, ServerNode}, {port, Port},
+ {host, Hostname},
+ {from, self()},
+ {mfa, {?MODULE, passive_recv_packet,
+ [Data, ?SOME]}},
+ {options, [{active, false},
+ {packet, 1} |
+ ClientOpts]}]),
+
+ ssl_test_lib:check_result(Client, ok),
+
+ ssl_test_lib:close(Server),
+ ssl_test_lib:close(Client).
+
+%%--------------------------------------------------------------------
+packet_2_passive_many_small(doc) ->
+ ["Test packet option {packet, 2} in passive mode"];
+
+packet_2_passive_many_small(suite) ->
+ [];
+
+packet_2_passive_many_small(Config) when is_list(Config) ->
+ ClientOpts = ?config(client_opts, Config),
+ ServerOpts = ?config(server_opts, Config),
+ {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
+
+ Data = "Packet option is {packet, 2}",
+
+ Server = ssl_test_lib:start_server([{node, ClientNode}, {port, 0},
+ {from, self()},
+ {mfa, {?MODULE, send, [Data, ?MANY]}},
+ {options, [{packet, 2}|ServerOpts]}]),
+ Port = ssl_test_lib:inet_port(Server),
+ Client = ssl_test_lib:start_client([{node, ServerNode}, {port, Port},
+ {host, Hostname},
+ {from, self()},
+ {mfa, {?MODULE, passive_recv_packet,
+ [Data, ?MANY]}},
+ {options, [{active, false},
+ {packet, 2} |
+ ClientOpts]}]),
+
+ ssl_test_lib:check_result(Client, ok),
+
+ ssl_test_lib:close(Server),
+ ssl_test_lib:close(Client).
+
+%%--------------------------------------------------------------------
+packet_2_passive_some_big(doc) ->
+ ["Test packet option {packet, 2} in passive mode"];
+
+packet_2_passive_some_big(suite) ->
+ [];
+
+packet_2_passive_some_big(Config) when is_list(Config) ->
+ ClientOpts = ?config(client_opts, Config),
+ ServerOpts = ?config(server_opts, Config),
+ {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
+
+ Data = lists:append(lists:duplicate(100, "1234567890")),
+
+ Server = ssl_test_lib:start_server([{node, ClientNode}, {port, 0},
+ {from, self()},
+ {mfa, {?MODULE, send, [Data, ?SOME]}},
+ {options, [{packet, 2}|ServerOpts]}]),
+ Port = ssl_test_lib:inet_port(Server),
+ Client = ssl_test_lib:start_client([{node, ServerNode}, {port, Port},
+ {host, Hostname},
+ {from, self()},
+ {mfa, {?MODULE, passive_recv_packet,
+ [Data, ?SOME]}},
+ {options, [{active, false},
+ {packet, 2} |
+ ClientOpts]}]),
+
+ ssl_test_lib:check_result(Client, ok),
+
+ ssl_test_lib:close(Server),
+ ssl_test_lib:close(Client).
+
+%%--------------------------------------------------------------------
+packet_4_passive_many_small(doc) ->
+ ["Test packet option {packet, 4} in passive mode"];
+
+packet_4_passive_many_small(suite) ->
+ [];
+
+packet_4_passive_many_small(Config) when is_list(Config) ->
+ ClientOpts = ?config(client_opts, Config),
+ ServerOpts = ?config(server_opts, Config),
+ {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
+
+ Data = "Packet option is {packet, 4}",
+
+ Server = ssl_test_lib:start_server([{node, ClientNode}, {port, 0},
+ {from, self()},
+ {mfa,
+ {?MODULE, send, [Data, ?MANY]}},
+ {options, [{packet, 4}|ServerOpts]}]),
+ Port = ssl_test_lib:inet_port(Server),
+ Client = ssl_test_lib:start_client([{node, ServerNode}, {port, Port},
+ {host, Hostname},
+ {from, self()},
+ {mfa, {?MODULE, passive_recv_packet,
+ [Data, ?MANY]}},
+ {options, [{active, false},
+ {packet, 4} |
+ ClientOpts]}]),
+
+ ssl_test_lib:check_result(Client, ok),
+
+ ssl_test_lib:close(Server),
+ ssl_test_lib:close(Client).
+
+%%--------------------------------------------------------------------
+packet_4_passive_some_big(doc) ->
+ ["Test packet option {packet, 4} in passive mode"];
+
+packet_4_passive_some_big(suite) ->
+ [];
+
+packet_4_passive_some_big(Config) when is_list(Config) ->
+ ClientOpts = ?config(client_opts, Config),
+ ServerOpts = ?config(server_opts, Config),
+ {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
+
+ Data = lists:append(lists:duplicate(100, "1234567890")),
+
+ Server = ssl_test_lib:start_server([{node, ClientNode}, {port, 0},
+ {from, self()},
+ {mfa, {?MODULE, send, [Data, ?SOME]}},
+ {options, [{packet, 4}|ServerOpts]}]),
+ Port = ssl_test_lib:inet_port(Server),
+ Client = ssl_test_lib:start_client([{node, ServerNode}, {port, Port},
+ {host, Hostname},
+ {from, self()},
+ {mfa, {?MODULE, passive_recv_packet,
+ [Data, ?SOME]}},
+ {options, [{active, false},
+ {packet, 4} |
+ ClientOpts]}]),
+
+ ssl_test_lib:check_result(Client, ok),
+
+ ssl_test_lib:close(Server),
+ ssl_test_lib:close(Client).
+
+
+%%--------------------------------------------------------------------
+packet_raw_active_once_many_small(doc) ->
+ ["Test packet option {packet, raw} in active once mode."];
+
+packet_raw_active_once_many_small(suite) ->
+ [];
+
+packet_raw_active_once_many_small(Config) when is_list(Config) ->
+ ClientOpts = ?config(client_opts, Config),
+ ServerOpts = ?config(server_opts, Config),
+ {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
+
+ Data = "Packet option is {packet, raw}",
+
+ Server = ssl_test_lib:start_server([{node, ClientNode}, {port, 0},
+ {from, self()},
+ {mfa, {?MODULE, send_raw ,[Data, ?MANY]}},
+ {options, ServerOpts}]),
+ Port = ssl_test_lib:inet_port(Server),
+ Client = ssl_test_lib:start_client([{node, ServerNode}, {port, Port},
+ {host, Hostname},
+ {from, self()},
+ {mfa, {?MODULE, active_once_raw, [Data, ?MANY]}},
+ {options, [{active, once},
+ {packet, raw} |
+ ClientOpts]}]),
+
+ ssl_test_lib:check_result(Client, ok),
+
+ ssl_test_lib:close(Server),
+ ssl_test_lib:close(Client).
+
+%%--------------------------------------------------------------------
+packet_raw_active_once_some_big(doc) ->
+ ["Test packet option {packet, raw} in active once mode."];
+
+packet_raw_active_once_some_big(suite) ->
+ [];
+
+packet_raw_active_once_some_big(Config) when is_list(Config) ->
+ ClientOpts = ?config(client_opts, Config),
+ ServerOpts = ?config(server_opts, Config),
+ {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
+
+ Data = lists:append(lists:duplicate(100, "1234567890")),
+
+ Server = ssl_test_lib:start_server([{node, ClientNode}, {port, 0},
+ {from, self()},
+ {mfa, {?MODULE, send_raw ,[Data, ?SOME]}},
+ {options, ServerOpts}]),
+ Port = ssl_test_lib:inet_port(Server),
+ Client = ssl_test_lib:start_client([{node, ServerNode}, {port, Port},
+ {host, Hostname},
+ {from, self()},
+ {mfa, {?MODULE, active_once_raw, [Data, ?SOME]}},
+ {options, [{active, once},
+ {packet, raw} |
+ ClientOpts]}]),
+
+ ssl_test_lib:check_result(Client, ok),
+
+ ssl_test_lib:close(Server),
+ ssl_test_lib:close(Client).
+
+%%--------------------------------------------------------------------
+packet_0_active_once_many_small(doc) ->
+ ["Test packet option {packet, 0} in active once mode."];
+
+packet_0_active_once_many_small(suite) ->
+ [];
+
+packet_0_active_once_many_small(Config) when is_list(Config) ->
+ ClientOpts = ?config(client_opts, Config),
+ ServerOpts = ?config(server_opts, Config),
+ {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
+
+ Data = "Packet option is {packet, 0}",
+
+ Server = ssl_test_lib:start_server([{node, ClientNode}, {port, 0},
+ {from, self()},
+ {mfa, {?MODULE, send_raw ,[Data, ?MANY]}},
+ {options, ServerOpts}]),
+ Port = ssl_test_lib:inet_port(Server),
+ Client = ssl_test_lib:start_client([{node, ServerNode}, {port, Port},
+ {host, Hostname},
+ {from, self()},
+ {mfa,
+ {?MODULE, active_once_raw,
+ [Data, ?MANY]}},
+ {options, [{active, once},
+ {packet, 0} |
+ ClientOpts]}]),
+
+ ssl_test_lib:check_result(Client, ok),
+
+ ssl_test_lib:close(Server),
+ ssl_test_lib:close(Client).
+
+
+%%--------------------------------------------------------------------
+packet_0_active_once_some_big(doc) ->
+ ["Test packet option {packet, 0} in active once mode."];
+
+packet_0_active_once_some_big(suite) ->
+ [];
+
+packet_0_active_once_some_big(Config) when is_list(Config) ->
+ ClientOpts = ?config(client_opts, Config),
+ ServerOpts = ?config(server_opts, Config),
+ {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
+
+ Data = lists:append(lists:duplicate(100, "1234567890")),
+
+ Server = ssl_test_lib:start_server([{node, ClientNode}, {port, 0},
+ {from, self()},
+ {mfa, {?MODULE, send_raw ,
+ [Data, ?SOME]}},
+ {options, ServerOpts}]),
+ Port = ssl_test_lib:inet_port(Server),
+ Client = ssl_test_lib:start_client([{node, ServerNode}, {port, Port},
+ {host, Hostname},
+ {from, self()},
+ {mfa,
+ {?MODULE, active_once_raw,
+ [Data, ?SOME]}},
+ {options, [{active, once},
+ {packet, 0} |
+ ClientOpts]}]),
+
+ ssl_test_lib:check_result(Client, ok),
+
+ ssl_test_lib:close(Server),
+ ssl_test_lib:close(Client).
+
+%%--------------------------------------------------------------------
+packet_1_active_once_many_small(doc) ->
+ ["Test packet option {packet, 1} in active once mode."];
+
+packet_1_active_once_many_small(suite) ->
+ [];
+
+packet_1_active_once_many_small(Config) when is_list(Config) ->
+ ClientOpts = ?config(client_opts, Config),
+ ServerOpts = ?config(server_opts, Config),
+ {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
+
+ Data = "Packet option is {packet, 1}",
+
+ Server = ssl_test_lib:start_server([{node, ClientNode}, {port, 0},
+ {from, self()},
+ {mfa, {?MODULE, send, [Data, ?MANY]}},
+ {options, [{packet, 1}|ServerOpts]}]),
+ Port = ssl_test_lib:inet_port(Server),
+ Client = ssl_test_lib:start_client([{node, ServerNode}, {port, Port},
+ {host, Hostname},
+ {from, self()},
+ {mfa,
+ {?MODULE,
+ active_once_packet,
+ [Data, ?MANY]}},
+ {options, [{active, once},
+ {packet, 1} |
+ ClientOpts]}]),
+
+ ssl_test_lib:check_result(Client, ok),
+
+ ssl_test_lib:close(Server),
+ ssl_test_lib:close(Client).
+
+%%--------------------------------------------------------------------
+packet_1_active_once_some_big(doc) ->
+ ["Test packet option {packet, 1} in active once mode."];
+
+packet_1_active_once_some_big(suite) ->
+ [];
+
+packet_1_active_once_some_big(Config) when is_list(Config) ->
+ ClientOpts = ?config(client_opts, Config),
+ ServerOpts = ?config(server_opts, Config),
+ {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
+
+ Data = lists:append(lists:duplicate(255, "1")),
+
+ Server = ssl_test_lib:start_server([{node, ClientNode}, {port, 0},
+ {from, self()},
+ {mfa, {?MODULE, send, [Data, ?SOME]}},
+ {options, [{packet, 1}|ServerOpts]}]),
+ Port = ssl_test_lib:inet_port(Server),
+ Client = ssl_test_lib:start_client([{node, ServerNode}, {port, Port},
+ {host, Hostname},
+ {from, self()},
+ {mfa,
+ {?MODULE,
+ active_once_packet,
+ [Data, ?SOME]}},
+ {options, [{active, once},
+ {packet, 1} |
+ ClientOpts]}]),
+
+ ssl_test_lib:check_result(Client, ok),
+
+ ssl_test_lib:close(Server),
+ ssl_test_lib:close(Client).
+
+%%--------------------------------------------------------------------
+packet_2_active_once_many_small(doc) ->
+ ["Test packet option {packet, 2} in active once mode"];
+
+packet_2_active_once_many_small(suite) ->
+ [];
+
+packet_2_active_once_many_small(Config) when is_list(Config) ->
+ ClientOpts = ?config(client_opts, Config),
+ ServerOpts = ?config(server_opts, Config),
+ {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
+
+ Data = "Packet option is {packet, 2}",
+
+ Server = ssl_test_lib:start_server([{node, ClientNode}, {port, 0},
+ {from, self()},
+ {mfa, {?MODULE, send, [Data, ?MANY]}},
+ {options, [{packet, 2}|ServerOpts]}]),
+ Port = ssl_test_lib:inet_port(Server),
+ Client = ssl_test_lib:start_client([{node, ServerNode}, {port, Port},
+ {host, Hostname},
+ {from, self()},
+ {mfa,
+ {?MODULE,
+ active_once_packet,
+ [Data, ?MANY]}},
+ {options, [{active, once},
+ {packet, 2} |
+ ClientOpts]}]),
+
+ ssl_test_lib:check_result(Client, ok),
+
+ ssl_test_lib:close(Server),
+ ssl_test_lib:close(Client).
+
+
+%%--------------------------------------------------------------------
+packet_2_active_once_some_big(doc) ->
+ ["Test packet option {packet, 2} in active once mode"];
+
+packet_2_active_once_some_big(suite) ->
+ [];
+
+packet_2_active_once_some_big(Config) when is_list(Config) ->
+ ClientOpts = ?config(client_opts, Config),
+ ServerOpts = ?config(server_opts, Config),
+ {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
+
+ Data = lists:append(lists:duplicate(100, "1234567890")),
+
+ Server = ssl_test_lib:start_server([{node, ClientNode}, {port, 0},
+ {from, self()},
+ {mfa, {?MODULE, send, [Data, ?SOME]}},
+ {options, [{packet, 2}|ServerOpts]}]),
+ Port = ssl_test_lib:inet_port(Server),
+ Client = ssl_test_lib:start_client([{node, ServerNode}, {port, Port},
+ {host, Hostname},
+ {from, self()},
+ {mfa,
+ {?MODULE,
+ active_once_packet,
+ [Data, ?SOME]}},
+ {options, [{active, once},
+ {packet, 2} |
+ ClientOpts]}]),
+
+ ssl_test_lib:check_result(Client, ok),
+
+ ssl_test_lib:close(Server),
+ ssl_test_lib:close(Client).
+
+%%--------------------------------------------------------------------
+packet_4_active_once_many_small(doc) ->
+ ["Test packet option {packet, 4} in active once mode"];
+
+packet_4_active_once_many_small(suite) ->
+ [];
+
+packet_4_active_once_many_small(Config) when is_list(Config) ->
+ ClientOpts = ?config(client_opts, Config),
+ ServerOpts = ?config(server_opts, Config),
+ {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
+
+ Data = "Packet option is {packet, 4}",
+
+ Server = ssl_test_lib:start_server([{node, ClientNode}, {port, 0},
+ {from, self()},
+ {mfa, {?MODULE, send, [Data, ?MANY]}},
+ {options, [{packet, 4}|ServerOpts]}]),
+ Port = ssl_test_lib:inet_port(Server),
+ Client = ssl_test_lib:start_client([{node, ServerNode}, {port, Port},
+ {host, Hostname},
+ {from, self()},
+ {mfa,
+ {?MODULE,
+ active_once_packet,
+ [Data, ?MANY]}},
+ {options, [{active, once},
+ {packet, 4} |
+ ClientOpts]}]),
+
+ ssl_test_lib:check_result(Client, ok),
+
+ ssl_test_lib:close(Server),
+ ssl_test_lib:close(Client).
+
+%%--------------------------------------------------------------------
+packet_4_active_once_some_big(doc) ->
+ ["Test packet option {packet, 4} in active once mode"];
+
+packet_4_active_once_some_big(suite) ->
+ [];
+
+packet_4_active_once_some_big(Config) when is_list(Config) ->
+ ClientOpts = ?config(client_opts, Config),
+ ServerOpts = ?config(server_opts, Config),
+ {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
+
+ Data = lists:append(lists:duplicate(100, "1234567890")),
+
+ Server = ssl_test_lib:start_server([{node, ClientNode}, {port, 0},
+ {from, self()},
+ {mfa, {?MODULE, send, [Data, ?SOME]}},
+ {options, [{packet, 4}|ServerOpts]}]),
+ Port = ssl_test_lib:inet_port(Server),
+ Client = ssl_test_lib:start_client([{node, ServerNode}, {port, Port},
+ {host, Hostname},
+ {from, self()},
+ {mfa,
+ {?MODULE,
+ active_once_packet,
+ [Data, ?SOME]}},
+ {options, [{active, once},
+ {packet, 4} |
+ ClientOpts]}]),
+
+ ssl_test_lib:check_result(Client, ok),
+
+ ssl_test_lib:close(Server),
+ ssl_test_lib:close(Client).
+
+%%--------------------------------------------------------------------
+packet_raw_active_many_small(doc) ->
+ ["Test packet option {packet, raw} in active mode."];
+
+packet_raw_active_many_small(suite) ->
+ [];
+
+packet_raw_active_many_small(Config) when is_list(Config) ->
+ ClientOpts = ?config(client_opts, Config),
+ ServerOpts = ?config(server_opts, Config),
+ {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
+
+ Data = "Packet option is {packet, raw}",
+
+ Server = ssl_test_lib:start_server([{node, ClientNode}, {port, 0},
+ {from, self()},
+ {mfa, {?MODULE, send_raw ,[Data, ?MANY]}},
+ {options, ServerOpts}]),
+ Port = ssl_test_lib:inet_port(Server),
+ Client = ssl_test_lib:start_client([{node, ServerNode}, {port, Port},
+ {host, Hostname},
+ {from, self()},
+ {mfa, {?MODULE, active_raw,
+ [Data, ?MANY]}},
+ {options, [{active, true},
+ {packet, raw} |
+ ClientOpts]}]),
+
+ ssl_test_lib:check_result(Client, ok),
+
+ ssl_test_lib:close(Server),
+ ssl_test_lib:close(Client).
+
+
+%%--------------------------------------------------------------------
+packet_raw_active_some_big(doc) ->
+ ["Test packet option {packet, raw} in active mode."];
+
+packet_raw_active_some_big(suite) ->
+ [];
+
+packet_raw_active_some_big(Config) when is_list(Config) ->
+ ClientOpts = ?config(client_opts, Config),
+ ServerOpts = ?config(server_opts, Config),
+ {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
+
+ Data = lists:append(lists:duplicate(100, "1234567890")),
+
+ Server = ssl_test_lib:start_server([{node, ClientNode}, {port, 0},
+ {from, self()},
+ {mfa, {?MODULE, send_raw ,[Data, ?SOME]}},
+ {options, ServerOpts}]),
+ Port = ssl_test_lib:inet_port(Server),
+ Client = ssl_test_lib:start_client([{node, ServerNode}, {port, Port},
+ {host, Hostname},
+ {from, self()},
+ {mfa, {?MODULE, active_raw, [Data, ?SOME]}},
+ {options, [{active, true},
+ {packet, raw} |
+ ClientOpts]}]),
+
+ ssl_test_lib:check_result(Client, ok),
+
+ ssl_test_lib:close(Server),
+ ssl_test_lib:close(Client).
+
+%%--------------------------------------------------------------------
+packet_0_active_many_small(doc) ->
+ ["Test packet option {packet, 0} in active mode."];
+
+packet_0_active_many_small(suite) ->
+ [];
+
+packet_0_active_many_small(Config) when is_list(Config) ->
+ ClientOpts = ?config(client_opts, Config),
+ ServerOpts = ?config(server_opts, Config),
+ {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
+
+ Data = "Packet option is {packet, 0}",
+
+ Server = ssl_test_lib:start_server([{node, ClientNode}, {port, 0},
+ {from, self()},
+ {mfa, {?MODULE, send_raw ,[Data, ?MANY]}},
+ {options, ServerOpts}]),
+ Port = ssl_test_lib:inet_port(Server),
+ Client = ssl_test_lib:start_client([{node, ServerNode}, {port, Port},
+ {host, Hostname},
+ {from, self()},
+ {mfa,
+ {?MODULE, active_raw,
+ [Data, ?MANY]}},
+ {options, [{active, true},
+ {packet, 0} |
+ ClientOpts]}]),
+
+ ssl_test_lib:check_result(Client, ok),
+
+ ssl_test_lib:close(Server),
+ ssl_test_lib:close(Client).
+
+%%--------------------------------------------------------------------
+packet_0_active_some_big(doc) ->
+ ["Test packet option {packet, 0} in active mode."];
+
+packet_0_active_some_big(suite) ->
+ [];
+
+packet_0_active_some_big(Config) when is_list(Config) ->
+ ClientOpts = ?config(client_opts, Config),
+ ServerOpts = ?config(server_opts, Config),
+ {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
+
+ Data = lists:append(lists:duplicate(100, "1234567890")),
+
+ Server = ssl_test_lib:start_server([{node, ClientNode}, {port, 0},
+ {from, self()},
+ {mfa, {?MODULE, send_raw ,[Data, ?SOME]}},
+ {options, ServerOpts}]),
+ Port = ssl_test_lib:inet_port(Server),
+ Client = ssl_test_lib:start_client([{node, ServerNode}, {port, Port},
+ {host, Hostname},
+ {from, self()},
+ {mfa,
+ {?MODULE, active_raw,
+ [Data, ?SOME]}},
+ {options, [{active, true},
+ {packet, 0} |
+ ClientOpts]}]),
+
+ ssl_test_lib:check_result(Client, ok),
+
+ ssl_test_lib:close(Server),
+ ssl_test_lib:close(Client).
+
+
+%%--------------------------------------------------------------------
+packet_1_active_many_small(doc) ->
+ ["Test packet option {packet, 1} in active mode."];
+
+packet_1_active_many_small(suite) ->
+ [];
+
+packet_1_active_many_small(Config) when is_list(Config) ->
+ ClientOpts = ?config(client_opts, Config),
+ ServerOpts = ?config(server_opts, Config),
+ {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
+
+ Data = "Packet option is {packet, 1}",
+
+ Server = ssl_test_lib:start_server([{node, ClientNode}, {port, 0},
+ {from, self()},
+ {mfa, {?MODULE, send, [Data, ?MANY]}},
+ {options, [{packet, 1}|ServerOpts]}]),
+ Port = ssl_test_lib:inet_port(Server),
+ Client = ssl_test_lib:start_client([{node, ServerNode}, {port, Port},
+ {host, Hostname},
+ {from, self()},
+ {mfa,
+ {?MODULE,
+ active_packet, [Data, ?MANY]}},
+ {options, [{active, true},
+ {packet, 1} |
+ ClientOpts]}]),
+
+ ssl_test_lib:check_result(Client, ok),
+
+ ssl_test_lib:close(Server),
+ ssl_test_lib:close(Client).
+
+%%--------------------------------------------------------------------
+packet_1_active_some_big(doc) ->
+ ["Test packet option {packet, 1} in active mode."];
+
+packet_1_active_some_big(suite) ->
+ [];
+
+packet_1_active_some_big(Config) when is_list(Config) ->
+ ClientOpts = ?config(client_opts, Config),
+ ServerOpts = ?config(server_opts, Config),
+ {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
+
+ Data = lists:append(lists:duplicate(255, "1")),
+
+ Server = ssl_test_lib:start_server([{node, ClientNode}, {port, 0},
+ {from, self()},
+ {mfa, {?MODULE, send, [Data, ?SOME]}},
+ {options, [{packet, 1}|ServerOpts]}]),
+ Port = ssl_test_lib:inet_port(Server),
+ Client = ssl_test_lib:start_client([{node, ServerNode}, {port, Port},
+ {host, Hostname},
+ {from, self()},
+ {mfa,
+ {?MODULE,
+ active_packet, [Data, ?SOME]}},
+ {options, [{active, true},
+ {packet, 1} |
+ ClientOpts]}]),
+
+ ssl_test_lib:check_result(Client, ok),
+
+ ssl_test_lib:close(Server),
+ ssl_test_lib:close(Client).
+
+%%--------------------------------------------------------------------
+packet_2_active_many_small(doc) ->
+ ["Test packet option {packet, 2} in active mode"];
+
+packet_2_active_many_small(suite) ->
+ [];
+
+packet_2_active_many_small(Config) when is_list(Config) ->
+ ClientOpts = ?config(client_opts, Config),
+ ServerOpts = ?config(server_opts, Config),
+ {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
+
+ Data = "Packet option is {packet, 2}",
+
+ Server = ssl_test_lib:start_server([{node, ClientNode}, {port, 0},
+ {from, self()},
+ {mfa, {?MODULE, send, [Data, ?MANY]}},
+ {options, [{packet, 2}|ServerOpts]}]),
+ Port = ssl_test_lib:inet_port(Server),
+ Client = ssl_test_lib:start_client([{node, ServerNode}, {port, Port},
+ {host, Hostname},
+ {from, self()},
+ {mfa,
+ {?MODULE,
+ active_packet, [Data, ?MANY]}},
+ {options, [{active, true},
+ {packet, 2} |
+ ClientOpts]}]),
+
+ ssl_test_lib:check_result(Client, ok),
+
+ ssl_test_lib:close(Server),
+ ssl_test_lib:close(Client).
+
+%%--------------------------------------------------------------------
+packet_2_active_some_big(doc) ->
+ ["Test packet option {packet, 2} in active mode"];
+
+packet_2_active_some_big(suite) ->
+ [];
+
+packet_2_active_some_big(Config) when is_list(Config) ->
+ ClientOpts = ?config(client_opts, Config),
+ ServerOpts = ?config(server_opts, Config),
+ {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
+
+ Data = lists:append(lists:duplicate(100, "1234567890")),
+
+ Server = ssl_test_lib:start_server([{node, ClientNode}, {port, 0},
+ {from, self()},
+ {mfa, {?MODULE, send, [Data, ?SOME]}},
+ {options, [{packet, 2}|ServerOpts]}]),
+ Port = ssl_test_lib:inet_port(Server),
+ Client = ssl_test_lib:start_client([{node, ServerNode}, {port, Port},
+ {host, Hostname},
+ {from, self()},
+ {mfa,
+ {?MODULE,
+ active_packet, [Data, ?SOME]}},
+ {options, [{active, true},
+ {packet, 2} |
+ ClientOpts]}]),
+
+ ssl_test_lib:check_result(Client, ok),
+
+ ssl_test_lib:close(Server),
+ ssl_test_lib:close(Client).
+
+%%--------------------------------------------------------------------
+packet_4_active_many_small(doc) ->
+ ["Test packet option {packet, 4} in active mode"];
+
+packet_4_active_many_small(suite) ->
+ [];
+
+packet_4_active_many_small(Config) when is_list(Config) ->
+ ClientOpts = ?config(client_opts, Config),
+ ServerOpts = ?config(server_opts, Config),
+ {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
+
+ Data = "Packet option is {packet, 4}",
+
+ Server = ssl_test_lib:start_server([{node, ClientNode}, {port, 0},
+ {from, self()},
+ {mfa, {?MODULE, send, [Data, ?MANY]}},
+ {options, [{packet, 4}|ServerOpts]}]),
+ Port = ssl_test_lib:inet_port(Server),
+ Client = ssl_test_lib:start_client([{node, ServerNode}, {port, Port},
+ {host, Hostname},
+ {from, self()},
+ {mfa,
+ {?MODULE,
+ active_packet, [Data, ?MANY]}},
+ {options, [{active, true},
+ {packet, 4} |
+ ClientOpts]}]),
+
+ ssl_test_lib:check_result(Client, ok),
+
+ ssl_test_lib:close(Server),
+ ssl_test_lib:close(Client).
+
+
+%%--------------------------------------------------------------------
+packet_4_active_some_big(doc) ->
+ ["Test packet option {packet, 4} in active mode"];
+
+packet_4_active_some_big(suite) ->
+ [];
+
+packet_4_active_some_big(Config) when is_list(Config) ->
+ ClientOpts = ?config(client_opts, Config),
+ ServerOpts = ?config(server_opts, Config),
+ {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
+
+ Data = lists:append(lists:duplicate(100, "1234567890")),
+
+ Server = ssl_test_lib:start_server([{node, ClientNode}, {port, 0},
+ {from, self()},
+ {mfa, {?MODULE, send, [Data, ?SOME]}},
+ {options, [{packet, 4} | ServerOpts]}]),
+ Port = ssl_test_lib:inet_port(Server),
+ Client = ssl_test_lib:start_client([{node, ServerNode}, {port, Port},
+ {host, Hostname},
+ {from, self()},
+ {mfa,
+ {?MODULE,
+ active_packet, [Data, ?SOME]}},
+ {options, [{active, true},
+ {packet, 4} |
+ ClientOpts]}]),
+
+ ssl_test_lib:check_result(Client, ok),
+
+ ssl_test_lib:close(Server),
+ ssl_test_lib:close(Client).
+
+
+%%--------------------------------------------------------------------
+packet_send_to_large(doc) ->
+ ["Test setting the packet option {packet, 2} on the send side"];
+
+packet_send_to_large(suite) -> [];
+
+packet_send_to_large(Config) when is_list(Config) ->
+ ClientOpts = ?config(client_opts, Config),
+ ServerOpts = ?config(server_opts, Config),
+ {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
+
+ Data = lists:append(lists:duplicate(30, "1234567890")),
+
+ Server = ssl_test_lib:start_server([{node, ClientNode}, {port, 0},
+ {from, self()},
+ {mfa, {?MODULE, send, [Data, 1]}},
+ {options, [{packet, 1}| ServerOpts]}]),
+ Port = ssl_test_lib:inet_port(Server),
+ Client = ssl_test_lib:start_client([{node, ServerNode}, {port, Port},
+ {host, Hostname},
+ {from, self()},
+ {mfa, {?MODULE, active_packet, [Data, 1]}},
+ {options, [{active, true} | ClientOpts]}]),
+
+ ssl_test_lib:check_result(Server, {error, {badarg, {packet_to_large, 300, 255}}}),
+
+ ssl_test_lib:close(Server),
+ ssl_test_lib:close(Client).
+
+
+
+
+
+%%--------------------------------------------------------------------
+packet_wait_active(doc) ->
+ ["Test waiting when complete packages have not arrived"];
+
+packet_wait_active(suite) ->
+ [];
+
+packet_wait_active(Config) when is_list(Config) ->
+ ClientOpts = ?config(client_opts, Config),
+ ServerOpts = ?config(server_opts, Config),
+ {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
+
+ Data = list_to_binary(lists:duplicate(100, "1234567890")),
+
+ Server = ssl_test_lib:start_server([{node, ClientNode}, {port, 0},
+ {from, self()},
+ {mfa, {?MODULE, send_incomplete ,[Data, ?SOME]}},
+ {options, ServerOpts}]),
+ Port = ssl_test_lib:inet_port(Server),
+ Client = ssl_test_lib:start_client([{node, ServerNode}, {port, Port},
+ {host, Hostname},
+ {from, self()},
+ {mfa,
+ {?MODULE, active_packet,
+ [binary_to_list(Data), ?SOME]}},
+ {options, [{active, true},
+ {packet, 4} |
+ ClientOpts]}]),
+
+ ssl_test_lib:check_result(Client, ok),
+
+ ssl_test_lib:close(Server),
+ ssl_test_lib:close(Client).
+
+
+%%--------------------------------------------------------------------
+packet_wait_passive(doc) ->
+ ["Test waiting when complete packages have not arrived"];
+
+packet_wait_passive(suite) ->
+ [];
+
+packet_wait_passive(Config) when is_list(Config) ->
+ ClientOpts = ?config(client_opts, Config),
+ ServerOpts = ?config(server_opts, Config),
+ {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
+
+ Data = list_to_binary(lists:duplicate(100, "1234567890")),
+
+ Server = ssl_test_lib:start_server([{node, ClientNode}, {port, 0},
+ {from, self()},
+ {mfa, {?MODULE, send_incomplete ,[Data, ?SOME]}},
+ {options, ServerOpts}]),
+ Port = ssl_test_lib:inet_port(Server),
+ Client = ssl_test_lib:start_client([{node, ServerNode}, {port, Port},
+ {host, Hostname},
+ {from, self()},
+ {mfa, {?MODULE, passive_recv_packet,
+ [binary_to_list(Data), ?SOME]}},
+ {options, [{active, false},
+ {packet, 4} |
+ ClientOpts]}]),
+
+ ssl_test_lib:check_result(Client, ok),
+
+ ssl_test_lib:close(Server),
+ ssl_test_lib:close(Client).
+%%--------------------------------------------------------------------
+packet_baddata_active(doc) ->
+ ["Test that if a bad packet arrives error msg is sent and socket is closed"];
+packet_baddata_active(suite) ->
+ [];
+
+packet_baddata_active(Config) when is_list(Config) ->
+ ClientOpts = ?config(client_opts, Config),
+ ServerOpts = ?config(server_opts, Config),
+ {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
+
+ Data = list_to_binary(lists:duplicate(100, "1234567890")),
+
+ Server = ssl_test_lib:start_server([{node, ClientNode}, {port, 0},
+ {from, self()},
+ {mfa, {?MODULE, send_incomplete ,[Data, 1]}},
+ {options, ServerOpts}]),
+ Port = ssl_test_lib:inet_port(Server),
+ Client = ssl_test_lib:start_client([{node, ServerNode}, {port, Port},
+ {host, Hostname},
+ {from, self()},
+ {mfa, {?MODULE, active_packet, [Data, 1]}},
+ {options, [{active, true},
+ {packet, cdr} |
+ ClientOpts]}]),
+ receive
+ {Client, {other, {ssl_error, _Socket, {invalid_packet, _}},{error,closed},1}} -> ok;
+ Unexpected ->
+ test_server:fail({unexpected, Unexpected})
+ end,
+
+
+ ssl_test_lib:close(Server),
+ ssl_test_lib:close(Client).
+%%--------------------------------------------------------------------
+packet_baddata_passive(doc) ->
+ ["Test that if a bad packet arrives error msg is sent and socket is closed"];
+
+packet_baddata_passive(suite) ->
+ [];
+
+packet_baddata_passive(Config) when is_list(Config) ->
+ ClientOpts = ?config(client_opts, Config),
+ ServerOpts = ?config(server_opts, Config),
+ {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
+
+ Data = list_to_binary(lists:duplicate(100, "1234567890")),
+
+ Server = ssl_test_lib:start_server([{node, ClientNode}, {port, 0},
+ {from, self()},
+ {mfa, {?MODULE, send_incomplete ,[Data, 1]}},
+ {options, ServerOpts}]),
+ Port = ssl_test_lib:inet_port(Server),
+ Client = ssl_test_lib:start_client([{node, ServerNode}, {port, Port},
+ {host, Hostname},
+ {from, self()},
+ {mfa, {?MODULE, passive_recv_packet,
+ [Data, 1]}},
+ {options, [{active, false},
+ {packet, cdr} |
+ ClientOpts]}]),
+
+ receive
+ {Client, {other, {error, {invalid_packet, _}},{error,closed}, 1}} -> ok;
+ Unexpected ->
+ test_server:fail({unexpected, Unexpected})
+ end,
+
+ ssl_test_lib:close(Server),
+ ssl_test_lib:close(Client).
+%%--------------------------------------------------------------------
+packet_size_active(doc) ->
+ ["Test that if a packet of size larger than packet_size arrives error msg is sent and socket is closed"];
+packet_size_active(suite) ->
+ [];
+
+packet_size_active(Config) when is_list(Config) ->
+ ClientOpts = ?config(client_opts, Config),
+ ServerOpts = ?config(server_opts, Config),
+ {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
+
+ Data = list_to_binary(lists:duplicate(100, "1234567890")),
+
+ Server = ssl_test_lib:start_server([{node, ClientNode}, {port, 0},
+ {from, self()},
+ {mfa, {?MODULE, send_incomplete ,[Data, 1]}},
+ {options, ServerOpts}]),
+ Port = ssl_test_lib:inet_port(Server),
+ Client = ssl_test_lib:start_client([{node, ServerNode}, {port, Port},
+ {host, Hostname},
+ {from, self()},
+ {mfa, {?MODULE, active_packet, [Data, 1]}},
+ {options, [{active, true},
+ {packet, 4}, {packet_size, 10} |
+ ClientOpts]}]),
+ receive
+ {Client, {other, {ssl_error, _Socket, {invalid_packet, _}},{error,closed},1}} -> ok;
+ Unexpected ->
+ test_server:fail({unexpected, Unexpected})
+ end,
+
+ ssl_test_lib:close(Server),
+ ssl_test_lib:close(Client).
+%%--------------------------------------------------------------------
+packet_size_passive(doc) ->
+ ["Test that if a packet of size larger than packet_size arrives error msg is sent and socket is closed"];
+packet_size_passive(suite) ->
+ [];
+
+packet_size_passive(Config) when is_list(Config) ->
+ ClientOpts = ?config(client_opts, Config),
+ ServerOpts = ?config(server_opts, Config),
+ {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
+
+ Data = list_to_binary(lists:duplicate(100, "1234567890")),
+
+ Server = ssl_test_lib:start_server([{node, ClientNode}, {port, 0},
+ {from, self()},
+ {mfa, {?MODULE, send_incomplete ,[Data, 1]}},
+ {options, ServerOpts}]),
+ Port = ssl_test_lib:inet_port(Server),
+ Client = ssl_test_lib:start_client([{node, ServerNode}, {port, Port},
+ {host, Hostname},
+ {from, self()},
+ {mfa, {?MODULE, passive_recv_packet, [Data, 1]}},
+ {options, [{active, false},
+ {packet, 4}, {packet_size, 30} |
+ ClientOpts]}]),
+ receive
+ {Client, {other, {error, {invalid_packet, _}},{error,closed},1}} -> ok;
+ Unexpected ->
+ test_server:fail({unexpected, Unexpected})
+ end,
+
+ ssl_test_lib:close(Server),
+ ssl_test_lib:close(Client).
+
+%%--------------------------------------------------------------------
+packet_erl_decode(doc) ->
+ ["Test that packets of sent to erlang:decode_packet works, i.e. currently"
+ "asn1 | cdr | sunrm | fcgi | tpkt | line | http | http_bin"
+ ];
+packet_erl_decode(suite) ->
+ [];
+
+packet_erl_decode(Config) when is_list(Config) ->
+ ClientOpts = ?config(client_opts, Config),
+ ServerOpts = ?config(server_opts, Config),
+ {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
+
+ %% A valid cdr packet
+ Data = <<71,73,79,80,1,2,2,1,0,0,0,41,0,0,0,0,0,0,0,0,0,0,0,1,78,
+ 69,79,0,0,0,0,2,0,10,0,0,0,0,0,0,0,0,0,18,0,0,0,0,0,0,0,4,49>>,
+
+ Server = ssl_test_lib:start_server([{node, ClientNode}, {port, 0},
+ {from, self()},
+ {mfa, {?MODULE, server_packet_decode ,[Data]}},
+ {options, [{active, true}, binary, {packet, cdr}|ServerOpts]}]),
+
+ Port = ssl_test_lib:inet_port(Server),
+ Client = ssl_test_lib:start_client([{node, ServerNode}, {port, Port},
+ {host, Hostname},
+ {from, self()},
+ {mfa, {?MODULE, client_packet_decode, [Data]}},
+ {options, [{active, true}, binary | ClientOpts]}]),
+
+ ssl_test_lib:check_result(Server, ok, Client, ok),
+
+ ssl_test_lib:close(Server),
+ ssl_test_lib:close(Client).
+
+
+server_packet_decode(Socket, CDR) ->
+ receive
+ {ssl, Socket, CDR} -> ok;
+ Other1 -> exit({?LINE, Other1})
+ end,
+ ok = ssl:send(Socket, CDR),
+ receive
+ {ssl, Socket, CDR} -> ok;
+ Other2 -> exit({?LINE, Other2})
+ end,
+ ok = ssl:send(Socket, CDR),
+ ok.
+
+client_packet_decode(Socket, CDR) ->
+ <<P1:10/binary, P2/binary>> = CDR,
+ ok = ssl:send(Socket, P1),
+ ok = ssl:send(Socket, P2),
+ receive
+ {ssl, Socket, CDR} -> ok;
+ Other1 -> exit({?LINE, Other1})
+ end,
+ ssl:setopts(Socket, [{packet, cdr}]),
+ ok = ssl:send(Socket, CDR),
+ receive
+ {ssl, Socket, CDR} -> ok;
+ Other2 -> exit({?LINE, Other2})
+ end,
+ ok.
+
+%%--------------------------------------------------------------------
+packet_http_decode(doc) ->
+ ["Test setting the packet option {packet, http}"];
+packet_http_decode(suite) ->
+ [];
+
+packet_http_decode(Config) when is_list(Config) ->
+ ClientOpts = ?config(client_opts, Config),
+ ServerOpts = ?config(server_opts, Config),
+ {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
+
+ Request = "GET / HTTP/1.1\r\n"
+ "host: www.example.com\r\n"
+ "user-agent: HttpTester\r\n"
+ "\r\n",
+ Response = "HTTP/1.1 200 OK\r\n"
+ "\r\n"
+ "Hello!",
+
+ Server = ssl_test_lib:start_server([{node, ClientNode}, {port, 0},
+ {from, self()},
+ {mfa, {?MODULE, server_http_decode, [Response]}},
+ {options, [{active, true}, binary, {packet, http} |
+ ServerOpts]}]),
+
+ Port = ssl_test_lib:inet_port(Server),
+ Client = ssl_test_lib:start_client([{node, ServerNode}, {port, Port},
+ {host, Hostname},
+ {from, self()},
+ {mfa, {?MODULE, client_http_decode, [Request]}},
+ {options, [{active, true}, binary, {packet, http} |
+ ClientOpts]}]),
+
+ ssl_test_lib:check_result(Server, ok, Client, ok),
+
+ ssl_test_lib:close(Server),
+ ssl_test_lib:close(Client).
+
+
+server_http_decode(Socket, HttpResponse) ->
+ assert_packet_opt(Socket, http),
+ receive
+ {ssl, Socket, {http_request, 'GET', _, {1,1}}} -> ok;
+ Other1 -> exit({?LINE, Other1})
+ end,
+ assert_packet_opt(Socket, http),
+ receive
+ {ssl, Socket, {http_header, _, 'Host', _, "www.example.com"}} -> ok;
+ Other2 -> exit({?LINE, Other2})
+ end,
+ assert_packet_opt(Socket, http),
+ receive
+ {ssl, Socket, {http_header, _, 'User-Agent', _, "HttpTester"}} -> ok;
+ Other3 -> exit({?LINE, Other3})
+ end,
+ assert_packet_opt(Socket, http),
+ receive
+ {ssl, Socket, http_eoh} -> ok;
+ Other4 -> exit({?LINE, Other4})
+ end,
+ assert_packet_opt(Socket, http),
+ ok = ssl:send(Socket, HttpResponse),
+ ok.
+
+client_http_decode(Socket, HttpRequest) ->
+ ok = ssl:send(Socket, HttpRequest),
+ receive
+ {ssl, Socket, {http_response, {1,1}, 200, "OK"}} -> ok;
+ Other1 -> exit({?LINE, Other1})
+ end,
+ receive
+ {ssl, Socket, http_eoh} -> ok;
+ Other2 -> exit({?LINE, Other2})
+ end,
+ ok = ssl:setopts(Socket, [{packet, 0}]),
+ receive
+ {ssl, Socket, <<"Hello!">>} -> ok;
+ Other3 -> exit({?LINE, Other3})
+ end,
+ ok.
+
+%%--------------------------------------------------------------------
+packet_http_bin_decode_multi(doc) ->
+ ["Test setting the packet option {packet, http_bin} with multiple requests"];
+packet_http_bin_decode_multi(suite) ->
+ [];
+
+packet_http_bin_decode_multi(Config) when is_list(Config) ->
+ ClientOpts = ?config(client_opts, Config),
+ ServerOpts = ?config(server_opts, Config),
+ {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
+
+ Request = <<"GET / HTTP/1.1\r\n"
+ "host: www.example.com\r\n"
+ "user-agent: HttpTester\r\n"
+ "\r\n">>,
+ Response = <<"HTTP/1.1 200 OK\r\n"
+ "\r\n"
+ "Hello!">>,
+ NumMsgs = 3,
+
+ Server = ssl_test_lib:start_server([{node, ClientNode}, {port, 0},
+ {from, self()},
+ {mfa, {?MODULE, server_http_bin_decode, [Response, NumMsgs]}},
+ {options, [{active, true}, binary, {packet, http_bin} |
+ ServerOpts]}]),
+
+ Port = ssl_test_lib:inet_port(Server),
+ Client = ssl_test_lib:start_client([{node, ServerNode}, {port, Port},
+ {host, Hostname},
+ {from, self()},
+ {mfa, {?MODULE, client_http_bin_decode, [Request, NumMsgs]}},
+ {options, [{active, true}, binary, {packet, http_bin} |
+ ClientOpts]}]),
+
+ ssl_test_lib:check_result(Server, ok, Client, ok),
+
+ ssl_test_lib:close(Server),
+ ssl_test_lib:close(Client).
+
+
+server_http_bin_decode(Socket, HttpResponse, Count) when Count > 0 ->
+ assert_packet_opt(Socket, http_bin),
+ receive
+ {ssl, Socket, {http_request, 'GET', _, {1,1}}} -> ok;
+ Other1 -> exit({?LINE, Other1})
+ end,
+ assert_packet_opt(Socket, http_bin),
+ receive
+ {ssl, Socket, {http_header, _, 'Host', _, <<"www.example.com">>}} -> ok;
+ Other2 -> exit({?LINE, Other2})
+ end,
+ assert_packet_opt(Socket, http_bin),
+ receive
+ {ssl, Socket, {http_header, _, 'User-Agent', _, <<"HttpTester">>}} -> ok;
+ Other3 -> exit({?LINE, Other3})
+ end,
+ assert_packet_opt(Socket, http_bin),
+ receive
+ {ssl, Socket, http_eoh} -> ok;
+ Other4 -> exit({?LINE, Other4})
+ end,
+ assert_packet_opt(Socket, http_bin),
+ ok = ssl:send(Socket, HttpResponse),
+ server_http_bin_decode(Socket, HttpResponse, Count - 1);
+server_http_bin_decode(_, _, _) ->
+ ok.
+
+client_http_bin_decode(Socket, HttpRequest, Count) when Count > 0 ->
+ ok = ssl:send(Socket, HttpRequest),
+ receive
+ {ssl, Socket, {http_response, {1,1}, 200, <<"OK">>}} -> ok;
+ Other1 -> exit({?LINE, Other1})
+ end,
+ receive
+ {ssl, Socket, http_eoh} -> ok;
+ Other2 -> exit({?LINE, Other2})
+ end,
+ ok = ssl:setopts(Socket, [{packet, 0}]),
+ receive
+ {ssl, Socket, <<"Hello!">>} -> ok;
+ Other3 -> exit({?LINE, Other3})
+ end,
+ ok = ssl:setopts(Socket, [{packet, http_bin}]),
+ client_http_bin_decode(Socket, HttpRequest, Count - 1);
+client_http_bin_decode(_, _, _) ->
+ ok.
+
+%%--------------------------------------------------------------------
+%% Internal functions
+
+send_raw(_,_, 0) ->
+ no_result_msg;
+send_raw(Socket, Data, N) ->
+ ssl:send(Socket, Data),
+ send_raw(Socket, Data, N-1).
+
+passive_raw(_, _, 0) ->
+ ok;
+passive_raw(Socket, Data, N) ->
+ Length = length(Data),
+ {ok, Data} = ssl:recv(Socket, Length),
+ passive_raw(Socket, Data, N-1).
+
+passive_recv_packet(_, _, 0) ->
+ ok;
+passive_recv_packet(Socket, Data, N) ->
+ case ssl:recv(Socket, 0) of
+ {ok, Data} ->
+ passive_recv_packet(Socket, Data, N-1);
+ Other ->
+ {other, Other, ssl:session_info(Socket), N}
+ end.
+
+send(_,_, 0) ->
+ no_result_msg;
+send(Socket, Data, N) ->
+ case ssl:send(Socket, [Data]) of
+ ok ->
+ send(Socket, Data, N-1);
+ Other ->
+ Other
+ end.
+
+send_incomplete(Socket, Data, N) ->
+ send_incomplete(Socket, Data, N, <<>>).
+send_incomplete(Socket, _Data, 0, Prev) ->
+ ssl:send(Socket, Prev),
+ no_result_msg;
+send_incomplete(Socket, Data, N, Prev) ->
+ Length = size(Data),
+ <<Part1:42/binary, Rest/binary>> = Data,
+ ssl:send(Socket, [Prev, ?uint32(Length), Part1]),
+ send_incomplete(Socket, Data, N-1, Rest).
+
+active_once_raw(Socket, Data, N) ->
+ active_once_raw(Socket, Data, N, []).
+
+active_once_raw(_, _, 0, _) ->
+ ok;
+active_once_raw(Socket, Data, N, Acc) ->
+ receive
+ {ssl, Socket, Data} ->
+ ssl:setopts(Socket, [{active, once}]),
+ active_once_raw(Socket, Data, N-1, []);
+ {ssl, Socket, Other} ->
+ case Acc ++ Other of
+ Data ->
+ ssl:setopts(Socket, [{active, once}]),
+ active_once_raw(Socket, Data, N-1, []);
+ NewAcc ->
+ ssl:setopts(Socket, [{active, once}]),
+ active_once_raw(Socket, Data, N, NewAcc)
+ end
+ end.
+
+active_once_packet(_,_, 0) ->
+ ok;
+active_once_packet(Socket, Data, N) ->
+ receive
+ {ssl, Socket, Data} ->
+ ok
+ end,
+ ssl:setopts(Socket, [{active, once}]),
+ active_once_packet(Socket, Data, N-1).
+
+active_raw(Socket, Data, N) ->
+ active_raw(Socket, Data, N, []).
+
+active_raw(_, _, 0, _) ->
+ ok;
+active_raw(Socket, Data, N, Acc) ->
+ receive
+ {ssl, Socket, Data} ->
+ active_raw(Socket, Data, N-1, []);
+ {ssl, Socket, Other} ->
+ case Acc ++ Other of
+ Data ->
+ active_raw(Socket, Data, N-1, []);
+ NewAcc ->
+ active_raw(Socket, Data, NewAcc)
+ end
+ end.
+
+active_packet(_, _, 0) ->
+ ok;
+active_packet(Socket, Data, N) ->
+ receive
+ {ssl, Socket, Data} ->
+ active_packet(Socket, Data, N -1);
+ Other ->
+ {other, Other, ssl:session_info(Socket),N}
+ end.
+
+assert_packet_opt(Socket, Type) ->
+ {ok, [{packet, Type}]} = ssl:getopts(Socket, [packet]).
diff --git a/lib/ssl/test/ssl_payload_SUITE.erl b/lib/ssl/test/ssl_payload_SUITE.erl
new file mode 100644
index 0000000000..a0aa92bdf2
--- /dev/null
+++ b/lib/ssl/test/ssl_payload_SUITE.erl
@@ -0,0 +1,726 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 2008-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(ssl_payload_SUITE).
+
+%% Note: This directive should only be used in test suites.
+-compile(export_all).
+
+-include("test_server.hrl").
+
+-define(TIMEOUT, 600000).
+
+%% 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(),
+ ssl:start(),
+ make_certs:all(?config(data_dir, Config), ?config(priv_dir, Config)),
+ ssl_test_lib:cert_options(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) ->
+ ssl:stop(),
+ 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 = ssl_test_lib: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 payload over ssl in all socket modes, active, active_once,"
+ "and passive mode."];
+
+all(suite) ->
+ [server_echos_passive_small, server_echos_active_once_small,
+ server_echos_active_small,
+ client_echos_passive_small, client_echos_active_once_small,
+ client_echos_active_small,
+ server_echos_passive_big, server_echos_active_once_big,
+ server_echos_active_big,
+ client_echos_passive_big, client_echos_active_once_big,
+ client_echos_active_big,
+ server_echos_passive_huge, server_echos_active_once_huge,
+ server_echos_active_huge,
+ client_echos_passive_huge, client_echos_active_once_huge,
+ client_echos_active_huge
+ ].
+
+%% Test cases starts here.
+%%--------------------------------------------------------------------
+server_echos_passive_small(doc) ->
+ ["Client sends 1000 bytes in passive mode to server, that receives them, "
+ "sends them back, and closes."];
+
+server_echos_passive_small(suite) ->
+ [];
+
+server_echos_passive_small(Config) when is_list(Config) ->
+ ClientOpts = ?config(client_opts, Config),
+ ServerOpts = ?config(server_opts, Config),
+ {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
+
+ Str = "1234567890",
+
+ server_echos_passive(Str, 1000, ClientOpts, ServerOpts,
+ ClientNode, ServerNode, Hostname).
+
+%%--------------------------------------------------------------------
+
+server_echos_active_once_small(doc) ->
+ ["Client sends 1000 bytes in active once mode to server, that receives "
+ " them, sends them back, and closes."];
+
+server_echos_active_once_small(suite) ->
+ [];
+
+server_echos_active_once_small(Config) when is_list(Config) ->
+ ClientOpts = ?config(client_opts, Config),
+ ServerOpts = ?config(server_opts, Config),
+ {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
+
+ Str = "1234567890",
+
+ server_echos_active_once(Str, 1000, ClientOpts, ServerOpts,
+ ClientNode, ServerNode, Hostname).
+
+%%--------------------------------------------------------------------
+
+server_echos_active_small(doc) ->
+ ["Client sends 1000 bytes in active mode to server, that receives them, "
+ "sends them back, and closes."];
+
+server_echos_active_small(suite) ->
+ [];
+
+server_echos_active_small(Config) when is_list(Config) ->
+ ClientOpts = ?config(client_opts, Config),
+ ServerOpts = ?config(server_opts, Config),
+ {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
+
+ Str = "1234567890",
+
+ server_echos_active(Str, 1000, ClientOpts, ServerOpts,
+ ClientNode, ServerNode, Hostname).
+
+%%--------------------------------------------------------------------
+client_echos_passive_small(doc) ->
+ ["Server sends 1000 bytes in passive mode to client, that receives them, "
+ "sends them back, and closes."];
+
+client_echos_passive_small(suite) ->
+ [];
+
+client_echos_passive_small(Config) when is_list(Config) ->
+ ClientOpts = ?config(client_opts, Config),
+ ServerOpts = ?config(server_opts, Config),
+ {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
+
+ Str = "1234567890",
+
+ client_echos_passive(Str, 1000, ClientOpts, ServerOpts, ClientNode,
+ ServerNode, Hostname).
+
+%%--------------------------------------------------------------------
+client_echos_active_once_small(doc) ->
+ ["Server sends 1000 bytes in active once mode to client, that receives "
+ "them, sends them back, and closes."];
+
+client_echos_active_once_small(suite) ->
+ [];
+
+client_echos_active_once_small(Config) when is_list(Config) ->
+ ClientOpts = ?config(client_opts, Config),
+ ServerOpts = ?config(server_opts, Config),
+ {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
+
+ Str = "1234567890",
+
+ client_echos_active_once(Str, 1000, ClientOpts, ServerOpts, ClientNode,
+ ServerNode, Hostname).
+
+%%--------------------------------------------------------------------
+client_echos_active_small(doc) ->
+ ["Server sends 1000 bytes in active mode to client, that receives them, "
+ "sends them back, and closes."];
+
+client_echos_active_small(suite) ->
+ [];
+
+client_echos_active_small(Config) when is_list(Config) ->
+ ClientOpts = ?config(client_opts, Config),
+ ServerOpts = ?config(server_opts, Config),
+ {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
+
+ Str = "1234567890",
+
+ client_echos_active(Str, 1000, ClientOpts, ServerOpts, ClientNode,
+ ServerNode, Hostname).
+
+
+%%--------------------------------------------------------------------
+server_echos_passive_big(doc) ->
+ ["Client sends 50000 bytes to server in passive mode, that receives them, "
+ "sends them back, and closes."];
+
+server_echos_passive_big(suite) ->
+ [];
+
+server_echos_passive_big(Config) when is_list(Config) ->
+ ClientOpts = ?config(client_opts, Config),
+ ServerOpts = ?config(server_opts, Config),
+ {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
+
+ Str = "1234567890",
+
+ server_echos_passive(Str, 50000, ClientOpts, ServerOpts, ClientNode,
+ ServerNode, Hostname).
+
+%%--------------------------------------------------------------------
+
+server_echos_active_once_big(doc) ->
+ ["Client sends 50000 bytes to server in active once mode, that receives "
+ "them, sends them back, and closes."];
+
+server_echos_active_once_big(suite) ->
+ [];
+
+server_echos_active_once_big(Config) when is_list(Config) ->
+ ClientOpts = ?config(client_opts, Config),
+ ServerOpts = ?config(server_opts, Config),
+ {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
+
+ Str = "1234567890",
+
+ server_echos_active_once(Str, 50000, ClientOpts, ServerOpts, ClientNode,
+ ServerNode, Hostname).
+
+%%--------------------------------------------------------------------
+
+server_echos_active_big(doc) ->
+ ["Client sends 50000 bytes to server in active once mode, that receives "
+ " them, sends them back, and closes."];
+
+server_echos_active_big(suite) ->
+ [];
+
+server_echos_active_big(Config) when is_list(Config) ->
+ ClientOpts = ?config(client_opts, Config),
+ ServerOpts = ?config(server_opts, Config),
+ {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
+
+ Str = "1234567890",
+
+ server_echos_active(Str, 50000, ClientOpts, ServerOpts, ClientNode,
+ ServerNode, Hostname).
+
+%%--------------------------------------------------------------------
+client_echos_passive_big(doc) ->
+ ["Server sends 50000 bytes to client in passive mode, that receives them, "
+ "sends them back, and closes."];
+
+client_echos_passive_big(suite) ->
+ [];
+
+client_echos_passive_big(Config) when is_list(Config) ->
+ ClientOpts = ?config(client_opts, Config),
+ ServerOpts = ?config(server_opts, Config),
+ {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
+
+ Str = "1234567890",
+
+ client_echos_passive(Str, 50000, ClientOpts, ServerOpts, ClientNode,
+ ServerNode, Hostname).
+
+%%--------------------------------------------------------------------
+client_echos_active_once_big(doc) ->
+ ["Server sends 50000 bytes to client in active once mode, that receives"
+ " them, sends them back, and closes."];
+
+client_echos_active_once_big(suite) ->
+ [];
+
+client_echos_active_once_big(Config) when is_list(Config) ->
+ ClientOpts = ?config(client_opts, Config),
+ ServerOpts = ?config(server_opts, Config),
+ {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
+
+ Str = "1234567890",
+
+ client_echos_active_once(Str, 50000, ClientOpts, ServerOpts, ClientNode,
+ ServerNode, Hostname).
+
+%%--------------------------------------------------------------------
+client_echos_active_big(doc) ->
+ ["Server sends 50000 bytes to client in active mode, that receives them, "
+ "sends them back, and closes."];
+
+client_echos_active_big(suite) ->
+ [];
+
+client_echos_active_big(Config) when is_list(Config) ->
+ ClientOpts = ?config(client_opts, Config),
+ ServerOpts = ?config(server_opts, Config),
+ {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
+
+ Str = "1234567890",
+
+ client_echos_active(Str, 50000, ClientOpts, ServerOpts, ClientNode,
+ ServerNode, Hostname).
+
+%%--------------------------------------------------------------------
+server_echos_passive_huge(doc) ->
+ ["Client sends 500000 bytes to server in passive mode, that receives "
+ " them, sends them back, and closes."];
+
+server_echos_passive_huge(suite) ->
+ [];
+
+server_echos_passive_huge(Config) when is_list(Config) ->
+ ClientOpts = ?config(client_opts, Config),
+ ServerOpts = ?config(server_opts, Config),
+ {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
+
+ Str = "1234567890",
+
+ server_echos_passive(Str, 500000, ClientOpts, ServerOpts, ClientNode,
+ ServerNode, Hostname).
+
+%%--------------------------------------------------------------------
+server_echos_active_once_huge(doc) ->
+ ["Client sends 500000 bytes to server in active once mode, that receives "
+ "them, sends them back, and closes."];
+
+server_echos_active_once_huge(suite) ->
+ [];
+
+server_echos_active_once_huge(Config) when is_list(Config) ->
+ ClientOpts = ?config(client_opts, Config),
+ ServerOpts = ?config(server_opts, Config),
+ {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
+
+ Str = "1234567890",
+
+ server_echos_active_once(Str, 500000, ClientOpts, ServerOpts, ClientNode,
+ ServerNode, Hostname).
+
+%%--------------------------------------------------------------------
+server_echos_active_huge(doc) ->
+ ["Client sends 500000 bytes to server in active mode, that receives them, "
+ "sends them back, and closes."];
+
+server_echos_active_huge(suite) ->
+ [];
+
+server_echos_active_huge(Config) when is_list(Config) ->
+ ClientOpts = ?config(client_opts, Config),
+ ServerOpts = ?config(server_opts, Config),
+ {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
+
+ Str = "1234567890",
+
+ server_echos_active(Str, 500000, ClientOpts, ServerOpts, ClientNode,
+ ServerNode, Hostname).
+
+%%--------------------------------------------------------------------
+client_echos_passive_huge(doc) ->
+ ["Server sends 500000 bytes to client in passive mode, that receives "
+ "them, sends them back, and closes."];
+
+client_echos_passive_huge(suite) ->
+ [];
+
+client_echos_passive_huge(Config) when is_list(Config) ->
+ ClientOpts = ?config(client_opts, Config),
+ ServerOpts = ?config(server_opts, Config),
+ {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
+
+ Str = "1234567890",
+ client_echos_passive(Str, 500000, ClientOpts, ServerOpts, ClientNode,
+ ServerNode, Hostname).
+
+%%--------------------------------------------------------------------
+client_echos_active_once_huge(doc) ->
+ ["Server sends 500000 bytes to client in active once mode, that receives "
+ "them, sends them back, and closes."];
+
+client_echos_active_once_huge(suite) ->
+ [];
+
+client_echos_active_once_huge(Config) when is_list(Config) ->
+ ClientOpts = ?config(client_opts, Config),
+ ServerOpts = ?config(server_opts, Config),
+ {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
+
+ Str = "1234567890",
+ client_echos_active_once(Str, 500000, ClientOpts, ServerOpts, ClientNode,
+ ServerNode, Hostname).
+
+%%--------------------------------------------------------------------
+client_echos_active_huge(doc) ->
+ ["Server sends 500000 bytes to client in active mode, that receives them, "
+ "sends them back, and closes."];
+
+client_echos_active_huge(suite) ->
+ [];
+
+client_echos_active_huge(Config) when is_list(Config) ->
+ ClientOpts = ?config(client_opts, Config),
+ ServerOpts = ?config(server_opts, Config),
+ {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
+
+ Str = "1234567890",
+ client_echos_active(Str, 500000, ClientOpts, ServerOpts, ClientNode,
+ ServerNode, Hostname).
+
+%%--------------------------------------------------------------------
+
+server_echos_passive(Data, Length, ClientOpts, ServerOpts,
+ ClientNode, ServerNode, Hostname) ->
+ Server = ssl_test_lib:start_server([{node, ServerNode}, {port, 0},
+ {from, self()},
+ {mfa,
+ {?MODULE, echoer,
+ [Data, Length]}},
+ {options,
+ [{active, false},{mode, binary}
+ | ServerOpts]}]),
+ Port = ssl_test_lib:inet_port(Server),
+ Client = ssl_test_lib:start_client([{node, ClientNode}, {port, Port},
+ {host, Hostname},
+ {from, self()},
+ {mfa,
+ {?MODULE, sender,
+ [Data,
+ Length]}},
+ {options,
+ [{active, false}, {mode, binary} |
+ ClientOpts]}]),
+ ssl_test_lib:check_result(Server, ok, Client, ok),
+
+ ssl_test_lib:close(Server),
+ ssl_test_lib:close(Client).
+
+
+server_echos_active_once(Data, Length, ClientOpts, ServerOpts, ClientNode,
+ ServerNode, Hostname) ->
+ Server = ssl_test_lib:start_server([{node, ServerNode}, {port, 0},
+ {from, self()},
+ {mfa,
+ {?MODULE, echoer_once,
+ [Data, Length]}},
+ {options, [{active, once},
+ {mode, binary}|
+ ServerOpts]}]),
+ Port = ssl_test_lib:inet_port(Server),
+ Client = ssl_test_lib:start_client([{node, ClientNode}, {port, Port},
+ {host, Hostname},
+ {from, self()},
+ {mfa,
+ {?MODULE, sender_once,
+ [Data, Length]}},
+ {options, [{active, once},
+ {mode, binary} |
+ ClientOpts]}]),
+ ssl_test_lib:check_result(Server, ok, Client, ok),
+
+ ssl_test_lib:close(Server),
+ ssl_test_lib:close(Client).
+
+
+server_echos_active(Data, Length, ClientOpts, ServerOpts,
+ ClientNode, ServerNode, Hostname) ->
+ Server = ssl_test_lib:start_server([{node, ServerNode}, {port, 0},
+ {from, self()},
+ {mfa,
+ {?MODULE, echoer_active,
+ [Data, Length]}},
+ {options,
+ [{active, true},
+ {mode, binary} | ServerOpts]}]),
+ Port = ssl_test_lib:inet_port(Server),
+ Client = ssl_test_lib:start_client([{node, ClientNode}, {port, Port},
+ {host, Hostname},
+ {from, self()},
+ {mfa,
+ {?MODULE, sender_active,
+ [Data,
+ Length]}},
+ {options,
+ [{active, true}, {mode, binary}
+ | ClientOpts]}]),
+ ssl_test_lib:check_result(Server, ok, Client, ok),
+
+ ssl_test_lib:close(Server),
+ ssl_test_lib:close(Client).
+
+client_echos_passive(Data, Length, ClientOpts, ServerOpts,
+ ClientNode, ServerNode, Hostname) ->
+ Server = ssl_test_lib:start_server([{node, ServerNode}, {port, 0},
+ {from, self()},
+ {mfa,
+ {?MODULE, sender,
+ [Data, Length]}},
+ {options,
+ [{active, false}, {mode, binary} |
+ ServerOpts]}]),
+ Port = ssl_test_lib:inet_port(Server),
+ Client = ssl_test_lib:start_client([{node, ClientNode}, {port, Port},
+ {host, Hostname},
+ {from, self()},
+ {mfa,
+ {?MODULE, echoer,
+ [Data,
+ Length]}},
+ {options,
+ [{active, false}, {mode, binary}
+ | ClientOpts]}]),
+ ssl_test_lib:check_result(Server, ok, Client, ok),
+
+ ssl_test_lib:close(Server),
+ ssl_test_lib:close(Client).
+
+client_echos_active_once(Data, Length,
+ ClientOpts, ServerOpts, ClientNode, ServerNode,
+ Hostname) ->
+ Server = ssl_test_lib:start_server([{node, ServerNode}, {port, 0},
+ {from, self()},
+ {mfa,
+ {?MODULE, sender_once,
+ [Data, Length]}},
+ {options, [{active, once},
+ {mode, binary} |
+ ServerOpts]}]),
+ Port = ssl_test_lib:inet_port(Server),
+ Client = ssl_test_lib:start_client([{node, ClientNode}, {port, Port},
+ {host, Hostname},
+ {from, self()},
+ {mfa,
+ {?MODULE, echoer_once,
+ [Data,
+ Length]}},
+ {options,[{active, once},
+ {mode, binary}
+ | ClientOpts]}]),
+ ssl_test_lib:check_result(Server, ok, Client, ok),
+
+ ssl_test_lib:close(Server),
+ ssl_test_lib:close(Client).
+
+client_echos_active(Data, Length, ClientOpts, ServerOpts, ClientNode,
+ ServerNode,
+ Hostname) ->
+ Server = ssl_test_lib:start_server([{node, ServerNode}, {port, 0},
+ {from, self()},
+ {mfa,
+ {?MODULE, sender_active,
+ [Data, Length]}},
+ {options, [{active, true},
+ {mode, binary}
+ | ServerOpts]}]),
+ Port = ssl_test_lib:inet_port(Server),
+ Client = ssl_test_lib:start_client([{node, ClientNode}, {port, Port},
+ {host, Hostname},
+ {from, self()},
+ {mfa,
+ {?MODULE, echoer_active,
+ [Data,
+ Length]}},
+ {options, [{active, true},
+ {mode, binary}
+ | ClientOpts]}]),
+ ssl_test_lib:check_result(Server, ok, Client, ok),
+
+ ssl_test_lib:close(Server),
+ ssl_test_lib:close(Client).
+
+send(_, _, _, 0,_) ->
+ ok;
+send(Socket, Data, Size, Repeate,F) ->
+ NewData = lists:duplicate(Size div 10, Data),
+ ssl:send(Socket, NewData),
+ F(),
+ send(Socket, Data, Size, Repeate - 1,F).
+
+sender(Socket, Data, Size) ->
+ ok = send(Socket, Data, Size, 100, fun() -> do_recv(Socket, Data, Size, <<>>, false) end),
+ test_server:format("Sender recv: ~p~n", [ssl:getopts(Socket, [active])]),
+ ok.
+
+sender_once(Socket, Data, Size) ->
+ send(Socket, Data, Size, 100,
+ fun() -> do_active_once(Socket, Data, Size, <<>>, false) end),
+ test_server:format("Sender active once: ~p~n",
+ [ssl:getopts(Socket, [active])]),
+ ok.
+
+sender_active(Socket, Data, Size) ->
+ F = fun() -> do_active(Socket, Data, Size, <<>>, false) end,
+ send(Socket, Data, Size, 100, F),
+ test_server:format("Sender active: ~p~n", [ssl:getopts(Socket, [active])]),
+ ok.
+
+echoer(Socket, Data, Size) ->
+ test_server:format("Echoer recv: ~p~n", [ssl:getopts(Socket, [active])]),
+ echo(fun() -> do_recv(Socket, Data, Size, <<>>, true) end, 100).
+
+echoer_once(Socket, Data, Size) ->
+ test_server:format("Echoer active once: ~p ~n",
+ [ssl:getopts(Socket, [active])]),
+ echo(fun() -> do_active_once(Socket, Data, Size, <<>>, true) end, 100).
+
+echoer_active(Socket, Data, Size) ->
+ test_server:format("Echoer active: ~p~n", [ssl:getopts(Socket, [active])]),
+ echo(fun() -> do_active(Socket, Data, Size, <<>>, true) end, 100).
+
+echo(_Fun, 0) -> ok;
+echo(Fun, N) ->
+ Fun(),
+ echo(Fun, N-1).
+
+
+do_recv(_Socket, _Data, 0, _Acc, true) ->
+ ok;
+do_recv(_Socket, Data, 0, Acc, false) ->
+ Data = lists:sublist(binary_to_list(Acc), 10);
+
+do_recv(Socket, Data, Size, Acc, Echo) ->
+ {ok, NewData} = ssl:recv(Socket, 0),
+ NewSize = size(NewData),
+ case Echo of
+ true ->
+ ssl:send(Socket, NewData),
+ NewSize = size(NewData),
+ do_recv(Socket, Data, Size - NewSize, [], Echo);
+ false ->
+ case size(Acc) < 10 of
+ true ->
+ do_recv(Socket, Data, Size - NewSize,
+ <<Acc/binary, NewData/binary>>, Echo);
+ false ->
+ do_recv(Socket, Data, Size - NewSize, Acc, Echo)
+ end
+ end.
+
+do_active_once(_Socket, _Data, 0, _Acc, true) ->
+ ok;
+do_active_once(_Socket, Data, 0, Acc, false) ->
+ Data = lists:sublist(binary_to_list(Acc), 10);
+
+do_active_once(Socket, Data, Size, Acc, Echo) ->
+ receive
+ {ssl, Socket, NewData} ->
+ NewSize = size(NewData),
+ case Echo of
+ true ->
+ ssl:send(Socket, NewData),
+ ssl:setopts(Socket, [{active, once}]),
+ do_active_once(Socket, Data, Size - NewSize, [], Echo);
+ false ->
+ case size(Acc) < 10 of
+ true ->
+ ssl:setopts(Socket, [{active, once}]),
+ do_active_once(Socket, Data, Size - NewSize,
+ <<Acc/binary, NewData/binary>>,
+ Echo);
+ false ->
+ ssl:setopts(Socket, [{active, once}]),
+ do_active_once(Socket, Data,
+ Size - NewSize, Acc, Echo)
+ end
+ end
+ end.
+
+do_active(_Socket, _Data, 0, _Acc, true) ->
+ ok;
+do_active(_Socket, Data, 0, Acc, false) ->
+ Data = lists:sublist(binary_to_list(Acc), 10);
+
+do_active(Socket, Data, Size, Acc, Echo) ->
+ receive
+ {ssl, Socket, NewData} ->
+ NewSize = size(NewData),
+ case Echo of
+ true ->
+ ssl:send(Socket, NewData),
+ do_active(Socket, Data, Size - NewSize, [], Echo);
+ false ->
+ case size(Acc) < 10 of
+ true ->
+ do_active(Socket, Data, Size - NewSize,
+ <<Acc/binary, NewData/binary>>,
+ Echo);
+ false ->
+ do_active(Socket, Data,
+ Size - NewSize, Acc, Echo)
+ end
+ end
+ end.
diff --git a/lib/ssl/test/ssl_test_MACHINE.erl b/lib/ssl/test/ssl_test_MACHINE.erl
new file mode 100644
index 0000000000..e75f7079ed
--- /dev/null
+++ b/lib/ssl/test/ssl_test_MACHINE.erl
@@ -0,0 +1,935 @@
+%%
+%% %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(ssl_test_MACHINE).
+
+-export([many_conns/0, mk_ssl_cert_opts/1, test_one_listener/7,
+ test_server_only/6]).
+
+-export([process_init/3, do_start/1]).
+
+
+-include("test_server.hrl").
+-include("ssl_test_MACHINE.hrl").
+
+-define(WAIT_TIMEOUT, 10000).
+-define(CLOSE_WAIT, 1000).
+
+%%
+%% many_conns() -> ManyConnections
+%%
+%% Choose a suitable number of "many connections" depending on platform
+%% and current limit for file descriptors.
+%%
+many_conns() ->
+ case os:type() of
+ {unix,_} -> many_conns_1();
+ _ -> 10
+ end.
+
+many_conns_1() ->
+ N0 = os:cmd("ulimit -n"),
+ N1 = lists:reverse(N0),
+ N2 = lists:dropwhile(fun($\r) -> true;
+ ($\n) -> true;
+ (_) -> false
+ end, N1),
+ N = list_to_integer(lists:reverse(N2)),
+ lists:min([(N - 10) div 2, 501]).
+
+%%
+%% mk_ssl_cert_opts(Config) -> {ok, {COpts, SOpts}}
+%%
+%%
+mk_ssl_cert_opts(_Config) ->
+ Dir = filename:join([code:lib_dir(ssl), "examples", "certs", "etc"]),
+ COpts = [{cacertfile, filename:join([Dir, "client", "cacerts.pem"])},
+ {certfile, filename:join([Dir, "client", "cert.pem"])},
+ {keyfile, filename:join([Dir, "client", "key.pem"])}],
+ SOpts = [{cacertfile, filename:join([Dir, "server", "cacerts.pem"])},
+ {certfile, filename:join([Dir, "server", "cert.pem"])},
+ {keyfile, filename:join([Dir, "server", "key.pem"])}],
+ {ok, {COpts, SOpts}}.
+
+%%
+%% Cmds:
+%% {protomod, gen_tcp | ssl} default = ssl
+%% {serialize_accept, true | false} default = false
+%% {timeout, Timeout}
+%% {sockopts, Opts}
+%% {sslopts, Opts}
+%% {protocols, Protocols} [sslv2|sslv3|tlsv1]
+%% {listen, Port}
+%% {lsock, LSock} listen socket for acceptor
+%% peercert
+%% accept
+%% {connect, {Host, Port}}
+%% {recv, N}
+%% {send, N}
+%% {echo, N} async echo back
+%% close close connection socket
+%% {close, Time} wait time and then close socket
+%% lclose close listen socket
+%% await_close wait for close
+%% wait_sync listener's wait for sync from parent
+%% connection_info
+%% {exit, Reason} exit
+%%
+%%
+%% We cannot have more than `backlog' acceptors at the same time.
+%%
+
+
+%%
+%% test_one_listener(NConns, LCmds, ACmds, CCmds, Timeout, Suite, Config)
+%%
+%% Creates one client and one server node, and runs one listener on
+%% the server node (according to LCmds), and creates NConns acceptors
+%% on the server node, and the same number of connectors on the client
+%% node. The acceptors and and connectors execute according to ACmds
+%% and CCmds, respectively.
+%%
+%% It is a good idea to have the backlog size in LCmds set to
+%% be at least as large as NConns.
+%%
+test_one_listener(NConns, LCmds0, ACmds0, CCmds0, Timeout, Suite, Config) ->
+ ProtoMod = get_protomod(Config),
+ SerializeAccept = get_serialize_accept(Config),
+ ?line {ok, {CNode, SNode}} = start_client_server_nodes(Suite),
+ case ProtoMod of
+ ssl ->
+ ?line ok = start_ssl([CNode, SNode], Config);
+ gen_tcp ->
+ ok
+ end,
+ LCmds = [{protomod, ProtoMod}| LCmds0],
+ ACmds = [{protomod, ProtoMod}, {serialize_accept, SerializeAccept}|
+ ACmds0],
+ CCmds = [{protomod, ProtoMod}| CCmds0],
+
+ ?line {ok, Listener} = start_process(SNode, self(), LCmds, listener),
+ ?line {ok, LSock} = wait_lsock(Listener, ?WAIT_TIMEOUT),
+ ?line {ok, Accs0} = start_processes(NConns, SNode, self(),
+ [{lsock, LSock}| ACmds], acceptor),
+ Accs = case ProtoMod of
+ gen_tcp ->
+ [Acc1| Accs1] = Accs0,
+ Acc1 ! {continue_accept, self()},
+ Accs1;
+ ssl ->
+ Accs0
+ end,
+ ?line {ok, Conns} = start_processes(NConns, CNode, self(),
+ CCmds, connector),
+ ?line case wait_ack(Accs, Accs0 ++ Conns, Timeout) of
+ ok ->
+ ?line sync([Listener]),
+ ?line wait_ack([], [Listener], ?WAIT_TIMEOUT);
+ {error, Reason} ->
+ ?line stop_node(SNode),
+ ?line stop_node(CNode),
+ exit(Reason)
+ end,
+ ?line stop_node(SNode),
+ ?line stop_node(CNode),
+ ok.
+
+%%
+%% test_server_only(NConns, LCmds, ACmds, Timeout, Suite, Config)
+%%
+%% Creates only one server node, and runs one listener on
+%% the server node (according to LCmds), and creates NConns acceptors
+%% on the server node. The acceptors execute according to ACmds.
+%% There are no connectors.
+%%
+test_server_only(NConns, LCmds0, ACmds0, Timeout, Suite, Config) ->
+ ProtoMod = get_protomod(Config),
+ ?line {ok, SNode} = start_server_node(Suite),
+ case ProtoMod of
+ ssl ->
+ ?line ok = start_ssl([SNode], Config);
+ gen_tcp ->
+ ok
+ end,
+ LCmds = [{protomod, ProtoMod}| LCmds0],
+ ACmds = [{protomod, ProtoMod}| ACmds0],
+ ?line {ok, Listener} = start_process(SNode, self(), LCmds, listener),
+ ?line {ok, LSock} = wait_lsock(Listener, ?WAIT_TIMEOUT),
+ ?line {ok, Accs0} = start_processes(NConns, SNode, self(),
+ [{lsock, LSock}| ACmds], acceptor),
+ Accs = case ProtoMod of
+ gen_tcp ->
+ [Acc1| Accs1] = Accs0,
+ Acc1 ! {continue_accept, self()},
+ Accs1;
+ ssl ->
+ Accs0
+ end,
+ ?line case wait_ack(Accs, Accs0, Timeout) of
+ ok ->
+ ?line sync([Listener]),
+ ?line wait_ack([], [Listener], ?WAIT_TIMEOUT);
+ {error, Reason} ->
+ ?line stop_node(SNode),
+ exit(Reason)
+ end,
+ ?line stop_node(SNode),
+ ok.
+
+%%
+%% start_client_server_nodes(Suite) -> {ok, {CNode, SNode}}
+%%
+start_client_server_nodes(Suite) ->
+ {ok, CNode} = start_client_node(Suite),
+ {ok, SNode} = start_server_node(Suite),
+ {ok, {CNode, SNode}}.
+
+start_client_node(Suite) ->
+ start_node(lists:concat([Suite, "_client"])).
+
+start_server_node(Suite) ->
+ start_node(lists:concat([Suite, "_server"])).
+
+%%
+%% start_ssl(Nodes, Config)
+%%
+start_ssl(Nodes, Config) ->
+ Env0 = lists:flatten([Env00 || {env, Env00} <- Config]),
+ Env1 = case os:getenv("SSL_DEBUG") of
+ false ->
+ [];
+ _ ->
+ Dir = ?config(priv_dir, Config),
+ [{debug, true}, {debugdir, Dir}]
+ end,
+ Env = Env0 ++ Env1,
+ lists:foreach(
+ fun(Node) -> rpc:call(Node, ?MODULE, do_start, [Env]) end, Nodes),
+ ok.
+
+do_start(Env) ->
+ application:load(ssl),
+ lists:foreach(
+ fun({Par, Val}) -> application:set_env(ssl, Par, Val) end, Env),
+ application:start(ssl),
+ application:start(crypto).
+
+%%
+%% start_node(Name) -> {ok, Node}
+%% start_node(Name, ExtraParams) -> {ok, Node}
+%%
+start_node(Name) ->
+ start_node(Name, []).
+start_node(Name, ExtraParams) ->
+ Params = "-pa " ++ filename:dirname(code:which(?MODULE)) ++ " " ++
+ ExtraParams,
+ test_server:start_node(Name, slave, [{args, Params}]).
+
+stop_node(Node) ->
+ test_server:stop_node(Node).
+
+%%
+%% start_processes(N, Node, Parent, Cmds, Type) -> {ok, Pids}
+%%
+start_processes(M, Node, Parent, Cmds, Type) ->
+ start_processes1(0, M, Node, Parent, Cmds, Type, []).
+start_processes1(M, M, _, _, _, _, Pids) ->
+ {ok, lists:reverse(Pids)};
+start_processes1(N, M, Node, Parent, Cmds, Type, Pids) ->
+ {ok, Pid} = start_process(Node, Parent, Cmds, {Type, N + 1}),
+ start_processes1(N + 1, M, Node, Parent, Cmds, Type, [Pid| Pids]).
+
+%%
+%% start_process(Node, Parent, Cmds, Type) -> {ok, Pid}
+%%
+start_process(Node, Parent, Cmds0, Type) ->
+ Cmds = case os:type() of
+ {win32, _} ->
+ lists:map(fun(close) -> {close, ?CLOSE_WAIT};
+ (Term) -> Term end, Cmds0);
+ _ ->
+ Cmds0
+ end,
+ Pid = spawn_link(Node, ?MODULE, process_init, [Parent, Cmds, Type]),
+ {ok, Pid}.
+
+process_init(Parent, Cmds, Type) ->
+ ?debug("#### ~w start~n", [{Type, self()}]),
+ pre_main_loop(Cmds, #st{parent = Parent, type = Type}).
+
+%%
+%% pre_main_loop
+%%
+pre_main_loop([], St) ->
+ ?debug("#### ~w end~n", [{St#st.type, self()}]),
+ main_loop([], St);
+pre_main_loop(Cmds, St) ->
+ ?debug("#### ~w -> ~w~n",
+ [{St#st.type, self(), St#st.sock, St#st.port,
+ St#st.peer, St#st.active}, hd(Cmds)]),
+ main_loop(Cmds, St).
+
+%%
+%% main_loop(Cmds, St)
+%%
+main_loop([{protomod, ProtoMod}| Cmds], St) ->
+ pre_main_loop(Cmds, St#st{protomod = ProtoMod});
+
+main_loop([{serialize_accept, Bool}| Cmds], St) ->
+ pre_main_loop(Cmds, St#st{serialize_accept = Bool});
+
+main_loop([{sockopts, Opts}| Cmds], St) ->
+ pre_main_loop(Cmds, St#st{sockopts = Opts});
+
+main_loop([{sslopts, Opts}| Cmds], St) ->
+ pre_main_loop(Cmds, St#st{sslopts = Opts});
+
+main_loop([{protocols, Protocols}| Cmds], St) ->
+ pre_main_loop(Cmds, St#st{protocols = Protocols});
+
+main_loop([{timeout, T}| Cmds], St) ->
+ pre_main_loop(Cmds, St#st{timeout = T});
+
+main_loop([{lsock, LSock}| Cmds], St) ->
+ pre_main_loop(Cmds, St#st{lsock = LSock});
+
+main_loop([{seed, Data}| Cmds], St) ->
+ case ssl:seed("tjosan") of
+ ok ->
+ pre_main_loop(Cmds, St);
+ {error, Reason} ->
+ ?error("#### ~w(~w) in seed: error: ~w~n",
+ [St#st.type, self(), Reason]),
+ exit(Reason)
+ end;
+
+main_loop([{listen, Port}| Cmds], St) ->
+ case listen(St, Port) of
+ {ok, LSock} ->
+ ack_lsock(St#st.parent, LSock),
+ NSt = get_active(St#st{port = Port, sock = LSock, lsock = LSock}),
+ pre_main_loop(Cmds, St);
+ {error, Reason} ->
+ ?error("#### ~w(~w) in listen: error: ~w~n",
+ [St#st.type, self(), Reason]),
+ exit(Reason)
+ end;
+
+main_loop([accept| Cmds], St) ->
+ case St#st.serialize_accept of
+ true ->
+ Parent = St#st.parent,
+ receive
+ {continue_accept, Parent} ->
+ ok
+ end;
+ false ->
+ ok
+ end,
+ case accept(St) of
+ {ok, Sock, Port, Peer} ->
+ case St#st.serialize_accept of
+ true ->
+ St#st.parent ! {one_accept_done, self()};
+ false ->
+ ok
+ end,
+ NSt = get_active(St#st{sock = Sock, port = Port, peer = Peer}),
+ pre_main_loop(Cmds, NSt);
+ {error, Reason} ->
+ ?error("#### ~w(~w) in accept: error: ~w~n",
+ [St#st.type, self(), Reason]),
+ exit(Reason)
+ end;
+
+main_loop([accept_timeout| Cmds], St) ->
+ case accept(St) of
+ {error, timeout} ->
+ pre_main_loop(Cmds, St);
+ {error, Reason} ->
+ ?error("#### ~w(~w) in accept_timeout: error: ~w~n",
+ [St#st.type, self(), Reason]),
+ exit(Reason)
+ end;
+
+
+main_loop([{connect, {Host, Port}}| Cmds], St) ->
+ case connect(St, Host, Port) of
+ {ok, Sock, LPort, Peer} ->
+ NSt = get_active(St#st{sock = Sock, port = LPort, peer = Peer}),
+ pre_main_loop(Cmds, NSt);
+ {error, Reason} ->
+ ?error("#### ~w(~w) in connect: error: ~w~n",
+ [St#st.type, self(), Reason]),
+ exit(Reason)
+ end;
+
+main_loop([connection_info| Cmds], St) ->
+ case connection_info(St) of
+ {ok, ProtoInfo} ->
+ io:fwrite("Got connection_info:~n~p~n", [ProtoInfo]),
+ pre_main_loop(Cmds, St);
+ {error, Reason} ->
+ ?error("#### ~w(~w) in connection_info: error: ~w~n",
+ [St#st.type, self(), Reason]),
+ exit(Reason)
+ end;
+
+main_loop([peercert| Cmds], St) ->
+ case peercert(St) of
+ {ok, Cert} ->
+ io:fwrite("Got cert:~n~p~n", [Cert]),
+ pre_main_loop(Cmds, St);
+ {error, Reason} ->
+ ?error("#### ~w(~w) in peercert: error: ~w~n",
+ [St#st.type, self(), Reason]),
+ exit(Reason)
+ end;
+
+main_loop([nopeercert| Cmds], St) ->
+ case peercert(St) of
+ {error, Reason} ->
+ io:fwrite("Got no cert as expected. reason:~n~p~n", [Reason]),
+ pre_main_loop(Cmds, St);
+ {ok, Cert} ->
+ ?error("#### ~w(~w) in peercert: error: got cert: ~p~n",
+ [St#st.type, self(), Cert]),
+ exit(peercert)
+ end;
+
+main_loop([{recv, N}| Cmds], St) ->
+ recv_loop([{recv, N}| Cmds], fun recv/1, St); % Returns to main_loop/2.
+
+main_loop([{send, N}| Cmds], St) ->
+ Msg = mk_msg(N),
+ case send(St, Msg) of
+ ok ->
+ pre_main_loop(Cmds, St);
+ {error, Reason} ->
+ ?error("#### ~w(~w) in send: error: ~w~n",
+ [St#st.type, self(), Reason]),
+ exit(Reason)
+ end;
+
+main_loop([{echo, N}| Cmds], St) ->
+ recv_loop([{echo, N}| Cmds], fun echo/1, St); % Returns to main_loop/2.
+
+main_loop([{close, WaitTime}| Cmds], St) ->
+ wait(WaitTime),
+ pre_main_loop([close| Cmds], St);
+
+main_loop([close| Cmds], St) ->
+ case close(St) of
+ ok ->
+ pre_main_loop(Cmds, St#st{sock = nil});
+ {error, Reason} ->
+ ?error("#### ~w(~w) in close: error: ~w~n",
+ [St#st.type, self(), Reason]),
+ exit(Reason)
+ end;
+
+main_loop([lclose| Cmds], St) ->
+ case lclose(St) of
+ ok ->
+ pre_main_loop(Cmds, St#st{lsock = nil});
+ {error, Reason} ->
+ ?error("#### ~w(~w) in lclose: error: ~w~n",
+ [St#st.type, self(), Reason]),
+ exit(Reason)
+ end;
+
+main_loop([await_close| Cmds], St) ->
+ case await_close(St) of
+ ok ->
+ pre_main_loop(Cmds, St#st{sock = nil});
+ {error, Reason} ->
+ ?error("#### ~w(~w) in await_close: error: ~w~n",
+ [St#st.type, self(), Reason]),
+ exit(Reason)
+ end;
+
+main_loop([wait_sync| Cmds], St) ->
+ wait_sync(St),
+ pre_main_loop(Cmds, St);
+
+main_loop({exit, Reason}, _St) ->
+ exit(Reason);
+
+main_loop([], _St) ->
+ ok.
+
+%%
+%% recv_loop(Cmds, F, St)
+%%
+%% F = recv/1 | echo/1
+%%
+recv_loop([{_Tag, 0}| Cmds], _, St) ->
+ pre_main_loop(Cmds, St);
+recv_loop([{_Tag, N}| _Cmds], _, St) when N < 0 ->
+ ?error("#### ~w(~w) in recv_loop: error: too much: ~w~n",
+ [St#st.type, self(), N]),
+ exit(toomuch); % XXX or {error, Reason}?
+recv_loop([{Tag, N}| Cmds], F, St) ->
+ case F(St) of
+ {ok, Len} ->
+ NSt = St#st{active = new_active(St#st.active)},
+ if
+ Len == N ->
+ pre_main_loop(Cmds, NSt);
+ true ->
+ ?debug("#### ~w -> ~w~n",
+ [{NSt#st.type, self(), NSt#st.sock, NSt#st.port,
+ NSt#st.peer, NSt#st.active}, {Tag, N - Len}]),
+ recv_loop([{Tag, N - Len}| Cmds], F, NSt)
+ end;
+ {error, Reason} ->
+ ?error("#### ~w(~w) in recv_loop: error: ~w, ~w bytes remain~n",
+ [St#st.type, self(), Reason, N]),
+ exit(Reason)
+ end.
+
+new_active(once) ->
+ false;
+new_active(A) ->
+ A.
+
+get_active(St) ->
+ A = case proplists:get_value(active, St#st.sockopts, undefined) of
+ undefined ->
+ Mod = case St#st.protomod of
+ ssl ->
+ ssl;
+ gen_tcp ->
+ inet
+ end,
+ {ok, [{active, Ax}]} = Mod:getopts(St#st.sock, [active]),
+ Ax;
+ Ay ->
+ Ay
+ end,
+ ?debug("#### ~w(~w) get_active: ~p\n", [St#st.type, self(), A]),
+ St#st{active = A}.
+
+
+%%
+%% SOCKET FUNCTIONS
+%%
+
+%%
+%% ssl
+%%
+
+%%
+%% listen(St, LPort) -> {ok, LSock} | {error, Reason}
+%%
+listen(St, LPort) ->
+ case St#st.protomod of
+ ssl ->
+ ssl:listen(LPort, St#st.sockopts ++ St#st.sslopts);
+ gen_tcp ->
+ gen_tcp:listen(LPort, St#st.sockopts)
+ end.
+
+%%
+%% accept(St) -> {ok, Sock} | {error, Reason}
+%%
+accept(St) ->
+ case St#st.protomod of
+ ssl ->
+ case ssl:transport_accept(St#st.lsock, St#st.timeout) of
+ {ok, Sock} ->
+ case ssl:ssl_accept(Sock, St#st.timeout) of
+ ok ->
+ {ok, Port} = ssl:sockname(Sock),
+ {ok, Peer} = ssl:peername(Sock),
+ {ok, Sock, Port, Peer};
+ Other ->
+ Other
+ end;
+ Other ->
+ Other
+ end;
+ gen_tcp ->
+ case gen_tcp:accept(St#st.lsock, St#st.timeout) of
+ {ok, Sock} ->
+ {ok, Port} = inet:port(Sock),
+ {ok, Peer} = inet:peername(Sock),
+ {ok, Sock, Port, Peer};
+ Other ->
+ Other
+ end
+ end.
+
+%%
+%% connect(St, Host, Port) -> {ok, Sock} | {error, Reason}
+%%
+connect(St, Host, Port) ->
+
+ case St#st.protomod of
+ ssl ->
+ case ssl:connect(Host, Port, St#st.sockopts ++ St#st.sslopts,
+ St#st.timeout) of
+ {ok, Sock} ->
+ {ok, LPort} = ssl:sockname(Sock),
+ {ok, Peer} = ssl:peername(Sock),
+ {ok, Sock, LPort, Peer};
+ Other ->
+ Other
+ end;
+ gen_tcp ->
+ case gen_tcp:connect(Host, Port, St#st.sockopts, St#st.timeout) of
+ {ok, Sock} ->
+ {ok, LPort} = inet:port(Sock),
+ {ok, Peer} = inet:peername(Sock),
+ {ok, Sock, LPort, Peer};
+ Other ->
+ Other
+ end
+ end.
+
+%%
+%% peercert(St) -> {ok, Cert} | {error, Reason}
+%%
+peercert(St) ->
+ case St#st.protomod of
+ ssl ->
+ ssl:peercert(St#st.sock, [ssl]);
+ gen_tcp ->
+ {ok, <<>>}
+ end.
+
+%%
+%% connection_info(St) -> {ok, ProtoInfo} | {error, Reason}
+%%
+connection_info(St) ->
+ case St#st.protomod of
+ ssl ->
+ case ssl:connection_info(St#st.sock) of
+ Res = {ok, {Proto, _}} ->
+ case St#st.protocols of
+ [] ->
+ Res;
+ Protocols ->
+ case lists:member(Proto, Protocols) of
+ true ->
+ Res;
+ false ->
+ {error, Proto}
+ end
+ end;
+ Error ->
+ Error
+ end;
+ gen_tcp ->
+ {ok, <<>>}
+ end.
+
+%%
+%% close(St) -> ok | {error, Reason}
+%%
+
+close(St) ->
+ Mod = St#st.protomod,
+ case St#st.sock of
+ nil ->
+ ok;
+ _ ->
+ Mod:close(St#st.sock)
+ end.
+
+%%
+%% lclose(St) -> ok | {error, Reason}
+%%
+lclose(St) ->
+ Mod = St#st.protomod,
+ case St#st.lsock of
+ nil ->
+ ok;
+ _ ->
+ Mod:close(St#st.lsock)
+ end.
+
+%%
+%% recv(St) = {ok, Len} | {error, Reason}
+%%
+recv(St) ->
+ case do_recv(St) of
+ {ok, Msg} ->
+ {ok, length(Msg)};
+ {error, Reason} ->
+ {error, Reason}
+ end.
+
+do_recv(St) when St#st.active == false ->
+ %% First check that we do *not* have any ssl/gen_tcp messages in the
+ %% message queue, then call the receive function.
+ Sock = St#st.sock,
+ case St#st.protomod of
+ ssl ->
+ receive
+ M = {ssl, Sock, _Msg} ->
+ {error, {unexpected_messagex, M}};
+ M = {ssl_closed, Sock} ->
+ {error, {unexpected_message, M}};
+ M = {ssl_error, Sock, _Reason} ->
+ {error, {unexpected_message, M}}
+ after 0 ->
+ ssl:recv(St#st.sock, 0, St#st.timeout)
+ end;
+ gen_tcp ->
+ receive
+ M = {tcp, Sock, _Msg} ->
+ {error, {unexpected_message, M}};
+ M = {tcp_closed, Sock} ->
+ {error, {unexpected_message, M}};
+ M = {tcp_error, Sock, _Reason} ->
+ {error, {unexpected_message, M}}
+ after 0 ->
+ gen_tcp:recv(St#st.sock, 0, St#st.timeout)
+ end
+ end;
+do_recv(St) ->
+ Sock = St#st.sock,
+ Timeout = St#st.timeout,
+ case St#st.protomod of
+ ssl ->
+ receive
+ {ssl, Sock, Msg} ->
+ {ok, Msg};
+ {ssl_closed, Sock} ->
+ {error, closed};
+ {ssl_error, Sock, Reason} ->
+ {error, Reason}
+ after Timeout ->
+ {error, timeout}
+ end;
+ gen_tcp ->
+ receive
+ {tcp, Sock, Msg} ->
+ {ok, Msg};
+ {tcp_closed, Sock} ->
+ {error, closed};
+ {tcp_error, Sock, Reason} ->
+ {error, Reason}
+ after Timeout ->
+ {error, timeout}
+ end
+ end.
+
+%%
+%% echo(St) = {ok, Len} | {error, Reason}
+%%
+echo(St) ->
+ Sock = St#st.sock,
+ case do_recv(St) of
+ {ok, Msg} ->
+ Mod = St#st.protomod,
+ case Mod:send(Sock, Msg) of
+ ok ->
+ {ok, length(Msg)};
+ {error, Reason} ->
+ {error, Reason}
+ end;
+ {error, Reason} ->
+ {error, Reason}
+ end.
+
+%%
+%% send(St, Msg) -> ok | {error, Reason}
+%%
+send(St, Msg) ->
+ Mod = St#st.protomod,
+ Mod:send(St#st.sock, Msg).
+
+%%
+%% await_close(St) -> ok | {error, Reason}
+%%
+await_close(St) when St#st.active == false ->
+ %% First check that we do *not* have any ssl/gen_tcp messages in the
+ %% message queue, then call the receive function.
+ Sock = St#st.sock,
+ Res = case St#st.protomod of
+ ssl ->
+ receive
+ M = {ssl, Sock, _Msg0} ->
+ {error, {unexpected_message, M}};
+ M = {ssl_closed, Sock} ->
+ {error, {unexpected_message, M}};
+ M = {ssl_error, Sock, _Reason} ->
+ {error, {unexpected_message, M}}
+ after 0 ->
+ ok
+ end;
+ gen_tcp ->
+ receive
+ M = {tcp, Sock, _Msg0} ->
+ {error, {unexpected_message, M}};
+ M = {tcp_closed, Sock} ->
+ {error, {unexpected_message, M}};
+ M = {tcp_error, Sock, _Reason} ->
+ {error, {unexpected_message, M}}
+ after 0 ->
+ ok
+ end
+ end,
+ case Res of
+ ok ->
+ Mod = St#st.protomod,
+ case Mod:recv(St#st.sock, 0, St#st.timeout) of
+ {ok, _Msg} ->
+ {error, toomuch};
+ {error, _} ->
+ ok
+ end;
+ _ ->
+ Res
+ end;
+await_close(St) ->
+ Sock = St#st.sock,
+ Timeout = St#st.timeout,
+ case St#st.protomod of
+ ssl ->
+ receive
+ {ssl, Sock, _Msg} ->
+ {error, toomuch};
+ {ssl_closed, Sock} ->
+ ok;
+ {ssl_error, Sock, Reason} ->
+ {error, Reason}
+ after Timeout ->
+ {error, timeout}
+ end;
+ gen_tcp ->
+ receive
+ {tcp, Sock, _Msg} ->
+ {error, toomuch};
+ {tcp_closed, Sock} ->
+ ok;
+ {tcp_error, Sock, Reason} ->
+ {error, Reason}
+ after Timeout ->
+ {error, timeout}
+ end
+ end.
+
+
+%%
+%% HELP FUNCTIONS
+%%
+
+wait_ack(_, [], _) ->
+ ok;
+wait_ack(AccPids0, Pids, Timeout) ->
+ ?debug("#### CONTROLLER: waiting for ~w~n", [Pids]),
+ receive
+ {one_accept_done, Pid} ->
+ case lists:delete(Pid, AccPids0) of
+ [] ->
+ wait_ack([], Pids, Timeout);
+ [AccPid| AccPids1] ->
+ AccPid ! {continue_accept, self()},
+ wait_ack(AccPids1, Pids, Timeout)
+ end;
+ {'EXIT', Pid, normal} ->
+ wait_ack(AccPids0, lists:delete(Pid, Pids), Timeout);
+ {'EXIT', Pid, Reason} ->
+ ?error("#### CONTROLLER got abnormal exit: ~w, ~w~n",
+ [Pid, Reason]),
+ {error, Reason}
+ after Timeout ->
+ ?error("#### CONTROLLER exiting because of timeout = ~w~n",
+ [Timeout]),
+ {error, Timeout}
+ end.
+
+
+%%
+%% ack_lsock(Pid, LSock)
+%%
+ack_lsock(Pid, LSock) ->
+ Pid ! {lsock, self(), LSock}.
+
+wait_lsock(Pid, Timeout) ->
+ receive
+ {lsock, Pid, LSock} ->
+ {ok, LSock}
+ after Timeout ->
+ exit(timeout)
+ end.
+
+%%
+%% sync(Pids)
+%%
+sync(Pids) ->
+ lists:foreach(fun (Pid) -> Pid ! {self(), sync} end, Pids).
+
+%%
+%% wait_sync(St)
+%%
+wait_sync(St) ->
+ Pid = St#st.parent,
+ receive
+ {Pid, sync} ->
+ ok
+ end.
+
+%%
+%% wait(Time)
+%%
+wait(Time) ->
+ receive
+ after Time ->
+ ok
+ end.
+
+%%
+%% mk_msg(Size)
+%%
+mk_msg(Size) ->
+ mk_msg(0, Size, []).
+
+mk_msg(_, 0, Acc) ->
+ Acc;
+mk_msg(Pos, Size, Acc) ->
+ C = (((Pos + Size) rem 256) - 1) band 255,
+ mk_msg(Pos, Size - 1, [C| Acc]).
+
+%%
+%% get_protomod(Config)
+%%
+get_protomod(Config) ->
+ case lists:keysearch(protomod, 1, Config) of
+ {value, {_, ProtoMod}} ->
+ ProtoMod;
+ false ->
+ ssl
+ end.
+
+%%
+%% get_serialize_accept(Config)
+%%
+get_serialize_accept(Config) ->
+ case lists:keysearch(serialize_accept, 1, Config) of
+ {value, {_, Val}} ->
+ Val;
+ false ->
+ false
+ end.
+
diff --git a/lib/ssl/test/ssl_test_MACHINE.hrl b/lib/ssl/test/ssl_test_MACHINE.hrl
new file mode 100644
index 0000000000..e78b33f505
--- /dev/null
+++ b/lib/ssl/test/ssl_test_MACHINE.hrl
@@ -0,0 +1,39 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 2003-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%
+%%
+
+-record(st, {protomod = ssl,
+ serialize_accept = false,
+ parent = nil,
+ type = nil,
+ active = nil,
+ port = 0,
+ peer = nil,
+ lsock = nil,
+ sock = nil,
+ timeout = infinity,
+ sockopts = [],
+ sslopts = [],
+ protocols = []}).
+
+%%-define(debug(X, Y), io:format(X, Y)).
+-define(debug(X, Y), ok).
+-define(error(X, Y), io:format(X, Y)).
+
+-define(DEFAULT_TIMEOUT, 240000).
+
diff --git a/lib/ssl/test/ssl_test_lib.erl b/lib/ssl/test/ssl_test_lib.erl
new file mode 100644
index 0000000000..00c5350ad0
--- /dev/null
+++ b/lib/ssl/test/ssl_test_lib.erl
@@ -0,0 +1,496 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 2008-2010. All Rights Reserved.
+%%
+%% The contents of this file are subject to the Erlang Public License,
+%% Version 1.1, (the "License"); you may not use this file except in
+%% compliance with the License. You should have received a copy of the
+%% Erlang Public License along with this software. If not, it can be
+%% retrieved online at http://www.erlang.org/.
+%%
+%% Software distributed under the License is distributed on an "AS IS"
+%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+%% the License for the specific language governing rights and limitations
+%% under the License.
+%%
+%% %CopyrightEnd%
+%%
+
+%%
+-module(ssl_test_lib).
+
+-include("test_server.hrl").
+-include("test_server_line.hrl").
+
+%% Note: This directive should only be used in test suites.
+-compile(export_all).
+
+-record(sslsocket, { fd = nil, pid = nil}).
+
+timetrap(Time) ->
+ Mul = try
+ test_server:timetrap_scale_factor()
+ catch _:_ -> 1 end,
+ test_server:timetrap(1000+Time*Mul).
+
+%% For now always run locally
+run_where(_) ->
+ ClientNode = node(),
+ ServerNode = node(),
+ {ok, Host} = rpc:call(ServerNode, inet, gethostname, []),
+ {ClientNode, ServerNode, Host}.
+
+run_where(_, ipv6) ->
+ ClientNode = node(),
+ ServerNode = node(),
+ {ok, Host} = rpc:call(ServerNode, inet, gethostname, []),
+ {ClientNode, ServerNode, Host}.
+
+node_to_hostip(Node) ->
+ [_ , Host] = string:tokens(atom_to_list(Node), "@"),
+ {ok, Address} = inet:getaddr(Host, inet),
+ Address.
+
+start_server(Args) ->
+ Result = spawn_link(?MODULE, run_server, [Args]),
+ receive
+ {listen, up} ->
+ Result
+ end.
+
+run_server(Opts) ->
+ Node = proplists:get_value(node, Opts),
+ Port = proplists:get_value(port, Opts),
+ Options = proplists:get_value(options, Opts),
+ Pid = proplists:get_value(from, Opts),
+ test_server:format("ssl:listen(~p, ~p)~n", [Port, Options]),
+ {ok, ListenSocket} = rpc:call(Node, ssl, listen, [Port, Options]),
+ Pid ! {listen, up},
+ send_selected_port(Pid, Port, ListenSocket),
+ run_server(ListenSocket, Opts).
+
+run_server(ListenSocket, Opts) ->
+ AcceptSocket = connect(ListenSocket, Opts),
+ Node = proplists:get_value(node, Opts),
+ Pid = proplists:get_value(from, Opts),
+ {Module, Function, Args} = proplists:get_value(mfa, Opts),
+ test_server:format("Server: apply(~p,~p,~p)~n",
+ [Module, Function, [AcceptSocket | Args]]),
+ case rpc:call(Node, Module, Function, [AcceptSocket | Args]) of
+ no_result_msg ->
+ ok;
+ Msg ->
+ test_server:format("Msg: ~p ~n", [Msg]),
+ Pid ! {self(), Msg}
+ end,
+ receive
+ listen ->
+ run_server(ListenSocket, Opts);
+ close ->
+ ok = rpc:call(Node, ssl, close, [AcceptSocket])
+ end.
+
+%%% To enable to test with s_client -reconnect
+connect(ListenSocket, Opts) ->
+ Node = proplists:get_value(node, Opts),
+ ReconnectTimes = proplists:get_value(reconnect_times, Opts, 0),
+ AcceptSocket = connect(ListenSocket, Node, 1 + ReconnectTimes, dummy),
+ case ReconnectTimes of
+ 0 ->
+ AcceptSocket;
+ _ ->
+ remove_close_msg(ReconnectTimes),
+ AcceptSocket
+ end.
+
+connect(_, _, 0, AcceptSocket) ->
+ AcceptSocket;
+connect(ListenSocket, Node, N, _) ->
+ test_server:format("ssl:transport_accept(~p)~n", [ListenSocket]),
+ {ok, AcceptSocket} = rpc:call(Node, ssl, transport_accept,
+ [ListenSocket]),
+ test_server:format("ssl:ssl_accept(~p)~n", [AcceptSocket]),
+ ok = rpc:call(Node, ssl, ssl_accept, [AcceptSocket]),
+ connect(ListenSocket, Node, N-1, AcceptSocket).
+
+remove_close_msg(0) ->
+ ok;
+remove_close_msg(ReconnectTimes) ->
+ receive
+ {ssl_closed, _} ->
+ remove_close_msg(ReconnectTimes -1)
+ end.
+
+
+start_client(Args) ->
+ Result = spawn_link(?MODULE, run_client, [Args]),
+ receive
+ connected ->
+ Result
+ end.
+
+run_client(Opts) ->
+ Node = proplists:get_value(node, Opts),
+ Host = proplists:get_value(host, Opts),
+ Port = proplists:get_value(port, Opts),
+ Pid = proplists:get_value(from, Opts),
+ Options = proplists:get_value(options, Opts),
+ test_server:format("ssl:connect(~p, ~p, ~p)~n", [Host, Port, Options]),
+ case rpc:call(Node, ssl, connect, [Host, Port, Options]) of
+ {ok, Socket} ->
+ Pid ! connected,
+ test_server:format("Client: connected~n", []),
+ %% In specail cases we want to know the client port, it will
+ %% be indicated by sending {port, 0} in options list!
+ send_selected_port(Pid, proplists:get_value(port, Options), Socket),
+ {Module, Function, Args} = proplists:get_value(mfa, Opts),
+ test_server:format("Client: apply(~p,~p,~p)~n",
+ [Module, Function, [Socket | Args]]),
+ case rpc:call(Node, Module, Function, [Socket | Args]) of
+ no_result_msg ->
+ ok;
+ Msg ->
+ Pid ! {self(), Msg}
+ end,
+ receive
+ close ->
+ ok = rpc:call(Node, ssl, close, [Socket])
+ end;
+ {error, Reason} ->
+ test_server:format("Client: connection failed: ~p ~n", [Reason]),
+ Pid ! {self(), {error, Reason}}
+ end.
+
+close(Pid) ->
+ Pid ! close.
+
+check_result(Server, ServerMsg, Client, ClientMsg) ->
+ receive
+ {Server, ServerMsg} ->
+ receive
+ {Client, ClientMsg} ->
+ ok;
+ Unexpected ->
+ Reason = {{expected, {Client, ClientMsg}},
+ {got, Unexpected}},
+ test_server:fail(Reason)
+ end;
+ {Client, ClientMsg} ->
+ receive
+ {Server, ServerMsg} ->
+ ok;
+ Unexpected ->
+ Reason = {{expected, {Server, ClientMsg}},
+ {got, Unexpected}},
+ test_server:fail(Reason)
+ end;
+ {Port, {data,Debug}} when is_port(Port) ->
+ io:format("openssl ~s~n",[Debug]),
+ check_result(Server, ServerMsg, Client, ClientMsg);
+
+ Unexpected ->
+ Reason = {{expected, {Client, ClientMsg}},
+ {expected, {Server, ServerMsg}}, {got, Unexpected}},
+ test_server:fail(Reason)
+ end.
+
+check_result(Pid, Msg) ->
+ receive
+ {Pid, Msg} ->
+ ok;
+ {Port, {data,Debug}} when is_port(Port) ->
+ io:format("openssl ~s~n",[Debug]),
+ check_result(Pid,Msg);
+ Unexpected ->
+ Reason = {{expected, {Pid, Msg}},
+ {got, Unexpected}},
+ test_server:fail(Reason)
+ end.
+
+check_result_ignore_renegotiation_reject(Pid, Msg) ->
+ receive
+ {Pid, fail_session_fatal_alert_during_renegotiation} ->
+ test_server:comment("Server rejected old renegotiation"),
+ ok;
+ {ssl_error, _, esslconnect} ->
+ test_server:comment("Server rejected old renegotiation"),
+ ok;
+ {Pid, Msg} ->
+ ok;
+ {Port, {data,Debug}} when is_port(Port) ->
+ io:format("openssl ~s~n",[Debug]),
+ check_result(Pid,Msg);
+ Unexpected ->
+ Reason = {{expected, {Pid, Msg}},
+ {got, Unexpected}},
+ test_server:fail(Reason)
+ end.
+
+
+wait_for_result(Server, ServerMsg, Client, ClientMsg) ->
+ receive
+ {Server, ServerMsg} ->
+ receive
+ {Client, ClientMsg} ->
+ ok;
+ Unexpected ->
+ Unexpected
+ end;
+ {Client, ClientMsg} ->
+ receive
+ {Server, ServerMsg} ->
+ ok;
+ Unexpected ->
+ Unexpected
+ end;
+ {Port, {data,Debug}} when is_port(Port) ->
+ io:format("openssl ~s~n",[Debug]),
+ wait_for_result(Server, ServerMsg, Client, ClientMsg);
+ Unexpected ->
+ Unexpected
+ end.
+
+
+wait_for_result(Pid, Msg) ->
+ receive
+ {Pid, Msg} ->
+ ok;
+ {Port, {data,Debug}} when is_port(Port) ->
+ io:format("openssl ~s~n",[Debug]),
+ wait_for_result(Pid,Msg);
+ Unexpected ->
+ Unexpected
+ end.
+
+cert_options(Config) ->
+ ClientCaCertFile = filename:join([?config(priv_dir, Config),
+ "client", "cacerts.pem"]),
+ ClientCertFile = filename:join([?config(priv_dir, Config),
+ "client", "cert.pem"]),
+ ServerCaCertFile = filename:join([?config(priv_dir, Config),
+ "server", "cacerts.pem"]),
+ ServerCertFile = filename:join([?config(priv_dir, Config),
+ "server", "cert.pem"]),
+ ServerKeyFile = filename:join([?config(priv_dir, Config),
+ "server", "key.pem"]),
+ ClientKeyFile = filename:join([?config(priv_dir, Config),
+ "client", "key.pem"]),
+ ServerKeyCertFile = filename:join([?config(priv_dir, Config),
+ "server", "keycert.pem"]),
+ ClientKeyCertFile = filename:join([?config(priv_dir, Config),
+ "client", "keycert.pem"]),
+
+ BadCaCertFile = filename:join([?config(priv_dir, Config),
+ "badcacert.pem"]),
+ BadCertFile = filename:join([?config(priv_dir, Config),
+ "badcert.pem"]),
+ BadKeyFile = filename:join([?config(priv_dir, Config),
+ "badkey.pem"]),
+ [{client_opts, [{ssl_imp, new},{reuseaddr, true}]},
+ {client_verification_opts, [{cacertfile, ClientCaCertFile},
+ {certfile, ClientCertFile},
+ {keyfile, ClientKeyFile},
+ {ssl_imp, new}]},
+ {server_opts, [{ssl_imp, new},{reuseaddr, true},
+ {certfile, ServerCertFile}, {keyfile, ServerKeyFile}]},
+ {server_verification_opts, [{ssl_imp, new},{reuseaddr, true},
+ {cacertfile, ServerCaCertFile},
+ {certfile, ServerCertFile}, {keyfile, ServerKeyFile}]},
+ {client_kc_opts, [{certfile, ClientKeyCertFile}, {ssl_imp, new}]},
+ {server_kc_opts, [{ssl_imp, new},{reuseaddr, true},
+ {certfile, ServerKeyCertFile}]},
+ {client_bad_ca, [{cacertfile, BadCaCertFile},
+ {certfile, ClientCertFile},
+ {keyfile, ClientKeyFile},
+ {ssl_imp, new}]},
+ {client_bad_cert, [{cacertfile, ClientCaCertFile},
+ {certfile, BadCertFile},
+ {keyfile, ClientKeyFile},
+ {ssl_imp, new}]},
+ {server_bad_ca, [{ssl_imp, new},{cacertfile, BadCaCertFile},
+ {certfile, ServerCertFile},
+ {keyfile, ServerKeyFile}]},
+ {server_bad_cert, [{ssl_imp, new},{cacertfile, ServerCaCertFile},
+ {certfile, BadCertFile}, {keyfile, ServerKeyFile}]},
+ {server_bad_key, [{ssl_imp, new},{cacertfile, ServerCaCertFile},
+ {certfile, ServerCertFile}, {keyfile, BadKeyFile}]}
+ | Config].
+
+
+start_upgrade_server(Args) ->
+ Result = spawn_link(?MODULE, run_upgrade_server, [Args]),
+ receive
+ {listen, up} ->
+ Result
+ end.
+
+run_upgrade_server(Opts) ->
+ Node = proplists:get_value(node, Opts),
+ Port = proplists:get_value(port, Opts),
+ TimeOut = proplists:get_value(timeout, Opts, infinity),
+ TcpOptions = proplists:get_value(tcp_options, Opts),
+ SslOptions = proplists:get_value(ssl_options, Opts),
+ Pid = proplists:get_value(from, Opts),
+
+ test_server:format("gen_tcp:listen(~p, ~p)~n", [Port, TcpOptions]),
+ {ok, ListenSocket} = rpc:call(Node, gen_tcp, listen, [Port, TcpOptions]),
+ Pid ! {listen, up},
+ send_selected_port(Pid, Port, ListenSocket),
+ test_server:format("gen_tcp:accept(~p)~n", [ListenSocket]),
+ {ok, AcceptSocket} = rpc:call(Node, gen_tcp, accept, [ListenSocket]),
+
+ try
+ {ok, SslAcceptSocket} = case TimeOut of
+ infinity ->
+ test_server:format("ssl:ssl_accept(~p, ~p)~n",
+ [AcceptSocket, SslOptions]),
+ rpc:call(Node, ssl, ssl_accept,
+ [AcceptSocket, SslOptions]);
+ _ ->
+ test_server:format("ssl:ssl_accept(~p, ~p, ~p)~n",
+ [AcceptSocket, SslOptions, TimeOut]),
+ rpc:call(Node, ssl, ssl_accept,
+ [AcceptSocket, SslOptions, TimeOut])
+ end,
+ {Module, Function, Args} = proplists:get_value(mfa, Opts),
+ Msg = rpc:call(Node, Module, Function, [SslAcceptSocket | Args]),
+ Pid ! {self(), Msg},
+ receive
+ close ->
+ ok = rpc:call(Node, ssl, close, [SslAcceptSocket])
+ end
+ catch error:{badmatch, Error} ->
+ Pid ! {self(), Error}
+ end.
+
+start_upgrade_client(Args) ->
+ spawn_link(?MODULE, run_upgrade_client, [Args]).
+
+run_upgrade_client(Opts) ->
+ Node = proplists:get_value(node, Opts),
+ Host = proplists:get_value(host, Opts),
+ Port = proplists:get_value(port, Opts),
+ Pid = proplists:get_value(from, Opts),
+ TcpOptions = proplists:get_value(tcp_options, Opts),
+ SslOptions = proplists:get_value(ssl_options, Opts),
+
+ test_server:format("gen_tcp:connect(~p, ~p, ~p)~n",
+ [Host, Port, TcpOptions]),
+ {ok, Socket} = rpc:call(Node, gen_tcp, connect, [Host, Port, TcpOptions]),
+
+ send_selected_port(Pid, Port, Socket),
+
+ test_server:format("ssl:connect(~p, ~p)~n", [Socket, SslOptions]),
+ {ok, SslSocket} = rpc:call(Node, ssl, connect, [Socket, SslOptions]),
+
+ {Module, Function, Args} = proplists:get_value(mfa, Opts),
+ test_server:format("apply(~p, ~p, ~p)~n",
+ [Module, Function, [SslSocket | Args]]),
+ Msg = rpc:call(Node, Module, Function, [SslSocket | Args]),
+ Pid ! {self(), Msg},
+ receive
+ close ->
+ ok = rpc:call(Node, ssl, close, [SslSocket])
+ end.
+
+start_server_error(Args) ->
+ Result = spawn_link(?MODULE, run_server_error, [Args]),
+ receive
+ {listen, up} ->
+ Result
+ end.
+
+run_server_error(Opts) ->
+ Node = proplists:get_value(node, Opts),
+ Port = proplists:get_value(port, Opts),
+ Options = proplists:get_value(options, Opts),
+ Pid = proplists:get_value(from, Opts),
+ test_server:format("ssl:listen(~p, ~p)~n", [Port, Options]),
+ case rpc:call(Node, ssl, listen, [Port, Options]) of
+ {ok, ListenSocket} ->
+ %% To make sure error_client will
+ %% get {error, closed} and not {error, connection_refused}
+ Pid ! {listen, up},
+ send_selected_port(Pid, Port, ListenSocket),
+ test_server:format("ssl:transport_accept(~p)~n", [ListenSocket]),
+ case rpc:call(Node, ssl, transport_accept, [ListenSocket]) of
+ {error, _} = Error ->
+ Pid ! {self(), Error};
+ {ok, AcceptSocket} ->
+ test_server:format("ssl:ssl_accept(~p)~n", [AcceptSocket]),
+ Error = rpc:call(Node, ssl, ssl_accept, [AcceptSocket]),
+ Pid ! {self(), Error}
+ end;
+ Error ->
+ %% Not really true but as this is an error test
+ %% this is what we want.
+ Pid ! {listen, up},
+ Pid ! {self(), Error}
+ end.
+
+start_client_error(Args) ->
+ spawn_link(?MODULE, run_client_error, [Args]).
+
+run_client_error(Opts) ->
+ Node = proplists:get_value(node, Opts),
+ Host = proplists:get_value(host, Opts),
+ Port = proplists:get_value(port, Opts),
+ Pid = proplists:get_value(from, Opts),
+ Options = proplists:get_value(options, Opts),
+ test_server:format("ssl:connect(~p, ~p, ~p)~n", [Host, Port, Options]),
+ Error = rpc:call(Node, ssl, connect, [Host, Port, Options]),
+ Pid ! {self(), Error}.
+
+inet_port(Pid) when is_pid(Pid)->
+ receive
+ {Pid, {port, Port}} ->
+ Port
+ end;
+
+inet_port(Node) ->
+ {Port, Socket} = do_inet_port(Node),
+ rpc:call(Node, gen_tcp, close, [Socket]),
+ Port.
+
+do_inet_port(Node) ->
+ {ok, Socket} = rpc:call(Node, gen_tcp, listen, [0, [{reuseaddr, true}]]),
+ {ok, Port} = rpc:call(Node, inet, port, [Socket]),
+ {Port, Socket}.
+
+no_result(_) ->
+ no_result_msg.
+
+trigger_renegotiate(Socket, [ErlData, N]) ->
+ [{session_id, Id} | _ ] = ssl:session_info(Socket),
+ trigger_renegotiate(Socket, ErlData, N, Id).
+
+trigger_renegotiate(Socket, _, 0, Id) ->
+ test_server:sleep(1000),
+ case ssl:session_info(Socket) of
+ [{session_id, Id} | _ ] ->
+ fail_session_not_renegotiated;
+ %% Tests that uses this function will not reuse
+ %% sessions so if we get a new session id the
+ %% renegotiation has succeeded.
+ [{session_id, _} | _ ] ->
+ ok;
+ {error, closed} ->
+ fail_session_fatal_alert_during_renegotiation;
+ {error, timeout} ->
+ fail_timeout
+ end;
+
+trigger_renegotiate(Socket, ErlData, N, Id) ->
+ ssl:send(Socket, ErlData),
+ trigger_renegotiate(Socket, ErlData, N-1, Id).
+
+
+send_selected_port(Pid, 0, #sslsocket{} = Socket) ->
+ {ok, {_, NewPort}} = ssl:sockname(Socket),
+ Pid ! {self(), {port, NewPort}};
+send_selected_port(Pid, 0, Socket) ->
+ {ok, {_, NewPort}} = inet:sockname(Socket),
+ Pid ! {self(), {port, NewPort}};
+send_selected_port(_,_,_) ->
+ ok.
diff --git a/lib/ssl/test/ssl_to_openssl_SUITE.erl b/lib/ssl/test/ssl_to_openssl_SUITE.erl
new file mode 100644
index 0000000000..cbf0447bf0
--- /dev/null
+++ b/lib/ssl/test/ssl_to_openssl_SUITE.erl
@@ -0,0 +1,1070 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 2008-2010. All Rights Reserved.
+%%
+%% The contents of this file are subject to the Erlang Public License,
+%% Version 1.1, (the "License"); you may not use this file except in
+%% compliance with the License. You should have received a copy of the
+%% Erlang Public License along with this software. If not, it can be
+%% retrieved online at http://www.erlang.org/.
+%%
+%% Software distributed under the License is distributed on an "AS IS"
+%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+%% the License for the specific language governing rights and limitations
+%% under the License.
+%%
+%% %CopyrightEnd%
+%%
+
+%%
+
+-module(ssl_to_openssl_SUITE).
+
+%% Note: This directive should only be used in test suites.
+-compile(export_all).
+
+-include("test_server.hrl").
+-include("test_server_line.hrl").
+-include("ssl_pkix.hrl").
+
+-define(TIMEOUT, 120000).
+-define(SLEEP, 1000).
+-define(OPENSSL_RENEGOTIATE, "r\n").
+-define(OPENSSL_QUIT, "Q\n").
+-define(OPENSSL_GARBAGE, "P\n").
+
+%% 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) ->
+ case os:find_executable("openssl") of
+ false ->
+ {skip, "Openssl not found"};
+ _ ->
+ crypto:start(),
+ ssl:start(),
+ Result =
+ (catch make_certs:all(?config(data_dir, Config),
+ ?config(priv_dir, Config))),
+ test_server:format("Make certs ~p~n", [Result]),
+ ssl_test_lib:cert_options(Config)
+ end.
+
+%%--------------------------------------------------------------------
+%% Function: end_per_suite(Config) -> _
+%% Config - [tuple()]
+%% A list of key/value pairs, holding the test case configuration.
+%% Description: Cleanup after the whole suite
+%%--------------------------------------------------------------------
+end_per_suite(_Config) ->
+ ssl:stop(),
+ 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 = ssl_test_lib: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 erlangs ssl against openssl"];
+
+all(suite) ->
+ [erlang_client_openssl_server,
+ erlang_server_openssl_client,
+ erlang_server_openssl_client_reuse_session,
+ erlang_client_openssl_server_renegotiate,
+ erlang_client_openssl_server_no_wrap_sequence_number,
+ erlang_server_openssl_client_no_wrap_sequence_number,
+ erlang_client_openssl_server_no_server_ca_cert,
+ ssl3_erlang_client_openssl_server,
+ ssl3_erlang_server_openssl_client,
+ ssl3_erlang_client_openssl_server_client_cert,
+ ssl3_erlang_server_openssl_client_client_cert,
+ ssl3_erlang_server_erlang_client_client_cert,
+ tls1_erlang_client_openssl_server,
+ tls1_erlang_server_openssl_client,
+ tls1_erlang_client_openssl_server_client_cert,
+ tls1_erlang_server_openssl_client_client_cert,
+ tls1_erlang_server_erlang_client_client_cert,
+ ciphers,
+ erlang_client_bad_openssl_server
+ ].
+
+%% Test cases starts here.
+%%--------------------------------------------------------------------
+
+erlang_client_openssl_server(doc) ->
+ ["Test erlang client with openssl server"];
+erlang_client_openssl_server(suite) ->
+ [];
+erlang_client_openssl_server(Config) when is_list(Config) ->
+ process_flag(trap_exit, true),
+ ServerOpts = ?config(server_opts, Config),
+ ClientOpts = ?config(client_opts, Config),
+
+ {ClientNode, _, Hostname} = ssl_test_lib:run_where(Config),
+
+ Data = "From openssl to erlang",
+
+ Port = ssl_test_lib:inet_port(node()),
+ CertFile = proplists:get_value(certfile, ServerOpts),
+ KeyFile = proplists:get_value(keyfile, ServerOpts),
+
+ Cmd = "openssl s_server -accept " ++ integer_to_list(Port) ++
+ " -cert " ++ CertFile ++ " -key " ++ KeyFile,
+
+ test_server:format("openssl cmd: ~p~n", [Cmd]),
+
+ OpensslPort = open_port({spawn, Cmd}, [stderr_to_stdout]),
+
+ wait_for_openssl_server(),
+
+ Client = ssl_test_lib:start_client([{node, ClientNode}, {port, Port},
+ {host, Hostname},
+ {from, self()},
+ {mfa, {?MODULE,
+ erlang_ssl_receive, [Data]}},
+ {options, ClientOpts}]),
+ port_command(OpensslPort, Data),
+
+ ssl_test_lib:check_result(Client, ok),
+
+ %% Clean close down! Server needs to be closed first !!
+ close_port(OpensslPort),
+
+ ssl_test_lib:close(Client),
+ process_flag(trap_exit, false),
+ ok.
+
+
+%%--------------------------------------------------------------------
+erlang_server_openssl_client(doc) ->
+ ["Test erlang server with openssl client"];
+erlang_server_openssl_client(suite) ->
+ [];
+erlang_server_openssl_client(Config) when is_list(Config) ->
+ process_flag(trap_exit, true),
+ ServerOpts = ?config(server_opts, Config),
+
+ {_, ServerNode, _} = ssl_test_lib:run_where(Config),
+
+ Data = "From openssl to erlang",
+
+ Server = ssl_test_lib:start_server([{node, ServerNode}, {port, 0},
+ {from, self()},
+ {mfa, {?MODULE, erlang_ssl_receive, [Data]}},
+ {options, ServerOpts}]),
+ Port = ssl_test_lib:inet_port(Server),
+
+ Cmd = "openssl s_client -port " ++ integer_to_list(Port) ++
+ " -host localhost",
+
+ test_server:format("openssl cmd: ~p~n", [Cmd]),
+
+ OpenSslPort = open_port({spawn, Cmd}, [stderr_to_stdout]),
+ port_command(OpenSslPort, Data),
+
+ ssl_test_lib:check_result(Server, ok),
+
+ ssl_test_lib:close(Server),
+
+ close_port(OpenSslPort),
+ process_flag(trap_exit, false),
+ ok.
+
+%%--------------------------------------------------------------------
+
+erlang_server_openssl_client_reuse_session(doc) ->
+ ["Test erlang server with openssl client that reconnects with the"
+ "same session id, to test reusing of sessions."];
+erlang_server_openssl_client_reuse_session(suite) ->
+ [];
+erlang_server_openssl_client_reuse_session(Config) when is_list(Config) ->
+ process_flag(trap_exit, true),
+ ServerOpts = ?config(server_opts, Config),
+
+ {_, ServerNode, _} = ssl_test_lib:run_where(Config),
+
+ Data = "From openssl to erlang",
+
+ Server = ssl_test_lib:start_server([{node, ServerNode}, {port, 0},
+ {from, self()},
+ {mfa, {?MODULE, erlang_ssl_receive, [Data]}},
+ {reconnect_times, 5},
+ {options, ServerOpts}]),
+ Port = ssl_test_lib:inet_port(Server),
+
+ Cmd = "openssl s_client -port " ++ integer_to_list(Port) ++
+ " -host localhost -reconnect",
+
+ test_server:format("openssl cmd: ~p~n", [Cmd]),
+
+ OpenSslPort = open_port({spawn, Cmd}, [stderr_to_stdout]),
+
+ port_command(OpenSslPort, Data),
+
+ ssl_test_lib:check_result(Server, ok),
+
+ ssl_test_lib:close(Server),
+
+ close_port(OpenSslPort),
+ process_flag(trap_exit, false),
+ ok.
+
+%%--------------------------------------------------------------------
+
+erlang_client_openssl_server_renegotiate(doc) ->
+ ["Test erlang client when openssl server issuses a renegotiate"];
+erlang_client_openssl_server_renegotiate(suite) ->
+ [];
+erlang_client_openssl_server_renegotiate(Config) when is_list(Config) ->
+ process_flag(trap_exit, true),
+ ServerOpts = ?config(server_opts, Config),
+ ClientOpts = ?config(client_opts, Config),
+
+ {ClientNode, _, Hostname} = ssl_test_lib:run_where(Config),
+
+ ErlData = "From erlang to openssl",
+ OpenSslData = "From openssl to erlang",
+
+ Port = ssl_test_lib:inet_port(node()),
+ CertFile = proplists:get_value(certfile, ServerOpts),
+ KeyFile = proplists:get_value(keyfile, ServerOpts),
+
+ Cmd = "openssl s_server -accept " ++ integer_to_list(Port) ++
+ " -cert " ++ CertFile ++ " -key " ++ KeyFile ++ " -msg",
+
+ test_server:format("openssl cmd: ~p~n", [Cmd]),
+
+ OpensslPort = open_port({spawn, Cmd}, [stderr_to_stdout]),
+
+ wait_for_openssl_server(),
+
+ Client = ssl_test_lib:start_client([{node, ClientNode}, {port, Port},
+ {host, Hostname},
+ {from, self()},
+ {mfa, {?MODULE,
+ delayed_send, [[ErlData, OpenSslData]]}},
+ {options, ClientOpts}]),
+
+ port_command(OpensslPort, ?OPENSSL_RENEGOTIATE),
+ test_server:sleep(?SLEEP),
+ port_command(OpensslPort, OpenSslData),
+
+ %%ssl_test_lib:check_result(Client, ok),
+ %% Currently allow test case to not fail
+ %% if server requires secure renegotiation from RFC-5746
+ %% This should be removed as soon as we have implemented it.
+ ssl_test_lib:check_result_ignore_renegotiation_reject(Client, ok),
+
+ %% Clean close down! Server needs to be closed first !!
+ close_port(OpensslPort),
+
+ ssl_test_lib:close(Client),
+ process_flag(trap_exit, false),
+ ok.
+
+%%--------------------------------------------------------------------
+
+erlang_client_openssl_server_no_wrap_sequence_number(doc) ->
+ ["Test that erlang client will renegotiate session when",
+ "max sequence number celing is about to be reached. Although"
+ "in the testcase we use the test option renegotiate_at"
+ " to lower treashold substantially."];
+erlang_client_openssl_server_no_wrap_sequence_number(suite) ->
+ [];
+erlang_client_openssl_server_no_wrap_sequence_number(Config) when is_list(Config) ->
+ process_flag(trap_exit, true),
+ ServerOpts = ?config(server_opts, Config),
+ ClientOpts = ?config(client_opts, Config),
+
+ {ClientNode, _, Hostname} = ssl_test_lib:run_where(Config),
+
+ ErlData = "From erlang to openssl\n",
+ N = 10,
+
+ Port = ssl_test_lib:inet_port(node()),
+ CertFile = proplists:get_value(certfile, ServerOpts),
+ KeyFile = proplists:get_value(keyfile, ServerOpts),
+
+ Cmd = "openssl s_server -accept " ++ integer_to_list(Port) ++
+ " -cert " ++ CertFile ++ " -key " ++ KeyFile ++ " -msg",
+
+ test_server:format("openssl cmd: ~p~n", [Cmd]),
+
+ OpensslPort = open_port({spawn, Cmd}, [stderr_to_stdout]),
+
+ wait_for_openssl_server(),
+
+ Client = ssl_test_lib:start_client([{node, ClientNode}, {port, Port},
+ {host, Hostname},
+ {from, self()},
+ {mfa, {ssl_test_lib,
+ trigger_renegotiate, [[ErlData, N+2]]}},
+ {options, [{reuse_sessions, false},
+ {renegotiate_at, N} | ClientOpts]}]),
+
+ %%ssl_test_lib:check_result(Client, ok),
+ %% Currently allow test case to not fail
+ %% if server requires secure renegotiation from RFC-5746
+ %% This should be removed as soon as we have implemented it.
+ ssl_test_lib:check_result_ignore_renegotiation_reject(Client, ok),
+
+ %% Clean close down! Server needs to be closed first !!
+ close_port(OpensslPort),
+
+ ssl_test_lib:close(Client),
+ process_flag(trap_exit, false),
+ ok.
+%%--------------------------------------------------------------------
+erlang_server_openssl_client_no_wrap_sequence_number(doc) ->
+ ["Test that erlang client will renegotiate session when",
+ "max sequence number celing is about to be reached. Although"
+ "in the testcase we use the test option renegotiate_at"
+ " to lower treashold substantially."];
+
+erlang_server_openssl_client_no_wrap_sequence_number(suite) ->
+ [];
+erlang_server_openssl_client_no_wrap_sequence_number(Config) when is_list(Config) ->
+ process_flag(trap_exit, true),
+ ServerOpts = ?config(server_opts, Config),
+
+ {_, ServerNode, _} = ssl_test_lib:run_where(Config),
+
+ Data = "From openssl to erlang",
+
+ N = 10,
+
+ Server = ssl_test_lib:start_server([{node, ServerNode}, {port, 0},
+ {from, self()},
+ {mfa, {ssl_test_lib,
+ trigger_renegotiate, [[Data, N+2]]}},
+ {options, [{renegotiate_at, N} | ServerOpts]}]),
+ Port = ssl_test_lib:inet_port(Server),
+
+ Cmd = "openssl s_client -port " ++ integer_to_list(Port) ++
+ " -host localhost -msg",
+
+ test_server:format("openssl cmd: ~p~n", [Cmd]),
+
+ OpenSslPort = open_port({spawn, Cmd}, [stderr_to_stdout]),
+
+ port_command(OpenSslPort, Data),
+
+ ssl_test_lib:check_result(Server, ok),
+
+ ssl_test_lib:close(Server),
+
+ close_port(OpenSslPort),
+ process_flag(trap_exit, false),
+ ok.
+%%--------------------------------------------------------------------
+
+erlang_client_openssl_server_no_server_ca_cert(doc) ->
+ ["Test erlang client when openssl server sends a cert chain not"
+ "including the ca cert. Explicitly test this even if it is"
+ "implicitly tested eleswhere."];
+erlang_client_openssl_server_no_server_ca_cert(suite) ->
+ [];
+erlang_client_openssl_server_no_server_ca_cert(Config) when is_list(Config) ->
+ process_flag(trap_exit, true),
+ ServerOpts = ?config(server_opts, Config),
+ ClientOpts = ?config(client_opts, Config),
+
+ {ClientNode, _, Hostname} = ssl_test_lib:run_where(Config),
+
+ Data = "From openssl to erlang",
+
+ Port = ssl_test_lib:inet_port(node()),
+ CertFile = proplists:get_value(certfile, ServerOpts),
+ KeyFile = proplists:get_value(keyfile, ServerOpts),
+
+ Cmd = "openssl s_server -accept " ++ integer_to_list(Port) ++
+ " -cert " ++ CertFile ++ " -key " ++ KeyFile ++ " -msg",
+
+ test_server:format("openssl cmd: ~p~n", [Cmd]),
+
+ OpensslPort = open_port({spawn, Cmd}, [stderr_to_stdout]),
+
+ wait_for_openssl_server(),
+
+ Client = ssl_test_lib:start_client([{node, ClientNode}, {port, Port},
+ {host, Hostname},
+ {from, self()},
+ {mfa, {?MODULE,
+ erlang_ssl_receive, [Data]}},
+ {options, ClientOpts}]),
+
+ port_command(OpensslPort, Data),
+
+ ssl_test_lib:check_result(Client, ok),
+
+ %% Clean close down! Server needs to be closed first !!
+ close_port(OpensslPort),
+
+ ssl_test_lib:close(Client),
+ process_flag(trap_exit, false),
+ ok.
+
+%%--------------------------------------------------------------------
+ssl3_erlang_client_openssl_server(doc) ->
+ ["Test erlang client with openssl server"];
+ssl3_erlang_client_openssl_server(suite) ->
+ [];
+ssl3_erlang_client_openssl_server(Config) when is_list(Config) ->
+ ServerOpts = ?config(server_opts, Config),
+ ClientOpts = ?config(client_opts, Config),
+
+ {ClientNode, _, Hostname} = ssl_test_lib:run_where(Config),
+
+ Port = ssl_test_lib:inet_port(node()),
+ CertFile = proplists:get_value(certfile, ServerOpts),
+ KeyFile = proplists:get_value(keyfile, ServerOpts),
+
+ Cmd = "openssl s_server -accept " ++ integer_to_list(Port) ++
+ " -cert " ++ CertFile ++ " -key " ++ KeyFile ++ " -ssl3",
+
+ test_server:format("openssl cmd: ~p~n", [Cmd]),
+
+ OpensslPort = open_port({spawn, Cmd}, [stderr_to_stdout]),
+
+ wait_for_openssl_server(),
+
+ Client = ssl_test_lib:start_client([{node, ClientNode}, {port, Port},
+ {host, Hostname},
+ {from, self()},
+ {mfa, {?MODULE,
+ connection_info, [sslv3]}},
+ {options,
+ [{versions, [sslv3]} | ClientOpts]}]),
+ ssl_test_lib:check_result(Client, ok),
+
+ ssl_test_lib:close(Client),
+ %% Clean close down!
+ close_port(OpensslPort),
+ test_server:sleep(?SLEEP),
+ ok.
+
+%%--------------------------------------------------------------------
+
+ssl3_erlang_server_openssl_client(doc) ->
+ ["Test erlang server with openssl client"];
+ssl3_erlang_server_openssl_client(suite) ->
+ [];
+ssl3_erlang_server_openssl_client(Config) when is_list(Config) ->
+ ServerOpts = ?config(server_opts, Config),
+
+ {_, ServerNode, _} = ssl_test_lib:run_where(Config),
+
+ Server = ssl_test_lib:start_server([{node, ServerNode}, {port, 0},
+ {from, self()},
+ {mfa,
+ {?MODULE, connection_info, [sslv3]}},
+ {options,
+ [{versions, [sslv3]} | ServerOpts]}]),
+ Port = ssl_test_lib:inet_port(Server),
+
+ Cmd = "openssl s_client -port " ++ integer_to_list(Port) ++
+ " -host localhost -ssl3",
+
+ test_server:format("openssl cmd: ~p~n", [Cmd]),
+
+ OpenSslPort = open_port({spawn, Cmd}, [stderr_to_stdout]),
+
+ ssl_test_lib:check_result(Server, ok),
+
+ close_port(OpenSslPort), %% openssl server first
+ ssl_test_lib:close(Server),
+ test_server:sleep(?SLEEP),
+ ok.
+
+%%--------------------------------------------------------------------
+ssl3_erlang_client_openssl_server_client_cert(doc) ->
+ ["Test erlang client with openssl server when client sends cert"];
+ssl3_erlang_client_openssl_server_client_cert(suite) ->
+ [];
+ssl3_erlang_client_openssl_server_client_cert(Config) when is_list(Config) ->
+ process_flag(trap_exit, true),
+ ServerOpts = ?config(server_verification_opts, Config),
+ ClientOpts = ?config(client_verification_opts, Config),
+
+ {ClientNode, _, Hostname} = ssl_test_lib:run_where(Config),
+
+ Data = "From openssl to erlang",
+
+ Port = ssl_test_lib:inet_port(node()),
+ CertFile = proplists:get_value(certfile, ServerOpts),
+ CaCertFile = proplists:get_value(cacertfile, ServerOpts),
+ KeyFile = proplists:get_value(keyfile, ServerOpts),
+
+ Cmd = "openssl s_server -accept " ++ integer_to_list(Port) ++
+ " -cert " ++ CertFile ++ " -CAfile " ++ CaCertFile
+ ++ " -key " ++ KeyFile ++ " -Verify 2 -ssl3",
+
+ test_server:format("openssl cmd: ~p~n", [Cmd]),
+
+ OpensslPort = open_port({spawn, Cmd}, [stderr_to_stdout]),
+
+ wait_for_openssl_server(),
+
+ Client = ssl_test_lib:start_client([{node, ClientNode}, {port, Port},
+ {host, Hostname},
+ {from, self()},
+ {mfa, {?MODULE,
+ erlang_ssl_receive, [Data]}},
+ {options, ClientOpts}]),
+ port_command(OpensslPort, Data),
+
+ ssl_test_lib:check_result(Client, ok),
+
+ %% Clean close down!
+ close_port(OpensslPort),
+ ssl_test_lib:close(Client),
+ process_flag(trap_exit, false),
+ ok.
+
+%%--------------------------------------------------------------------
+
+ssl3_erlang_server_openssl_client_client_cert(doc) ->
+ ["Test erlang server with openssl client when client sends cert"];
+ssl3_erlang_server_openssl_client_client_cert(suite) ->
+ [];
+ssl3_erlang_server_openssl_client_client_cert(Config) when is_list(Config) ->
+ process_flag(trap_exit, true),
+ ServerOpts = ?config(server_verification_opts, Config),
+ ClientOpts = ?config(client_verification_opts, Config),
+
+ {_, ServerNode, _} = ssl_test_lib:run_where(Config),
+
+ Data = "From openssl to erlang",
+
+ Server = ssl_test_lib:start_server([{node, ServerNode}, {port, 0},
+ {from, self()},
+ {mfa, {?MODULE,
+ erlang_ssl_receive, [Data]}},
+ {options,
+ [{verify , verify_peer}
+ | ServerOpts]}]),
+ Port = ssl_test_lib:inet_port(Server),
+
+ CaCertFile = proplists:get_value(cacertfile, ClientOpts),
+ CertFile = proplists:get_value(certfile, ClientOpts),
+ KeyFile = proplists:get_value(keyfile, ClientOpts),
+
+ Cmd = "openssl s_client -cert " ++ CertFile ++ " -CAfile " ++ CaCertFile
+ ++ " -key " ++ KeyFile ++ " -port " ++ integer_to_list(Port) ++
+ " -host localhost -ssl3",
+
+ test_server:format("openssl cmd: ~p~n", [Cmd]),
+
+ OpenSslPort = open_port({spawn, Cmd}, [stderr_to_stdout]),
+ port_command(OpenSslPort, Data),
+
+ ssl_test_lib:check_result(Server, ok),
+
+ close_port(OpenSslPort), %% openssl server first
+ ssl_test_lib:close(Server),
+ %% Clean close down!
+ process_flag(trap_exit, false),
+ ok.
+
+
+%%--------------------------------------------------------------------
+
+ssl3_erlang_server_erlang_client_client_cert(doc) ->
+ ["Test erlang server with erlang client when client sends cert"];
+ssl3_erlang_server_erlang_client_client_cert(suite) ->
+ [];
+ssl3_erlang_server_erlang_client_client_cert(Config) when is_list(Config) ->
+ process_flag(trap_exit, true),
+ ServerOpts = ?config(server_verification_opts, Config),
+ ClientOpts = ?config(client_verification_opts, Config),
+
+ {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
+
+ Data = "From erlang to erlang",
+
+ Server = ssl_test_lib:start_server([{node, ServerNode}, {port, 0},
+ {from, self()},
+ {mfa, {?MODULE,
+ erlang_ssl_receive, [Data]}},
+ {options,
+ [{verify , verify_peer}
+ | ServerOpts]}]),
+ Port = ssl_test_lib:inet_port(Server),
+
+ Client = ssl_test_lib:start_client([{node, ClientNode}, {port, Port},
+ {host, Hostname},
+ {from, self()},
+ {mfa, {ssl, send, [Data]}},
+ {options,
+ [{versions, [sslv3]} | ClientOpts]}]),
+
+ ssl_test_lib:check_result(Server, ok, Client, ok),
+
+ ssl_test_lib:close(Server),
+ ssl_test_lib:close(Client),
+ process_flag(trap_exit, false),
+ ok.
+
+%%--------------------------------------------------------------------
+
+tls1_erlang_client_openssl_server(doc) ->
+ ["Test erlang client with openssl server"];
+tls1_erlang_client_openssl_server(suite) ->
+ [];
+tls1_erlang_client_openssl_server(Config) when is_list(Config) ->
+ process_flag(trap_exit, true),
+ ServerOpts = ?config(server_opts, Config),
+ ClientOpts = ?config(client_opts, Config),
+
+
+ test_server:format("Server Opts", [ServerOpts]),
+
+ {ClientNode, _, Hostname} = ssl_test_lib:run_where(Config),
+
+ Port = ssl_test_lib:inet_port(node()),
+ CertFile = proplists:get_value(certfile, ServerOpts),
+ KeyFile = proplists:get_value(keyfile, ServerOpts),
+
+ Cmd = "openssl s_server -accept " ++ integer_to_list(Port) ++
+ " -cert " ++ CertFile ++ " -key " ++ KeyFile ++ " -tls1",
+
+ test_server:format("openssl cmd: ~p~n", [Cmd]),
+
+ OpensslPort = open_port({spawn, Cmd}, [stderr_to_stdout]),
+
+ wait_for_openssl_server(),
+
+ Client = ssl_test_lib:start_client([{node, ClientNode}, {port, Port},
+ {host, Hostname},
+ {from, self()},
+ {mfa, {?MODULE,
+ connection_info, [tlsv1]}},
+ {options,
+ [{versions, [tlsv1]} | ClientOpts]}]),
+
+ ssl_test_lib:check_result(Client, ok),
+
+ ssl_test_lib:close(Client),
+ %% Clean close down!
+ close_port(OpensslPort),
+ process_flag(trap_exit, false),
+ ok.
+
+%%--------------------------------------------------------------------
+
+tls1_erlang_server_openssl_client(doc) ->
+ ["Test erlang server with openssl client"];
+tls1_erlang_server_openssl_client(suite) ->
+ [];
+tls1_erlang_server_openssl_client(Config) when is_list(Config) ->
+ process_flag(trap_exit, true),
+ ServerOpts = ?config(server_opts, Config),
+
+ {_, ServerNode, _} = ssl_test_lib:run_where(Config),
+
+ Server = ssl_test_lib:start_server([{node, ServerNode}, {port, 0},
+ {from, self()},
+ {mfa,
+ {?MODULE, connection_info, [tlsv1]}},
+ {options,
+ [{versions, [tlsv1]} | ServerOpts]}]),
+ Port = ssl_test_lib:inet_port(Server),
+
+ Cmd = "openssl s_client -port " ++ integer_to_list(Port) ++
+ " -host localhost -tls1",
+
+ test_server:format("openssl cmd: ~p~n", [Cmd]),
+
+ OpenSslPort = open_port({spawn, Cmd}, [stderr_to_stdout]),
+
+ ssl_test_lib:check_result(Server, ok),
+
+ %% Clean close down!
+ close_port(OpenSslPort),
+ ssl_test_lib:close(Server),
+ process_flag(trap_exit, false),
+ ok.
+
+%%--------------------------------------------------------------------
+
+tls1_erlang_client_openssl_server_client_cert(doc) ->
+ ["Test erlang client with openssl server when client sends cert"];
+tls1_erlang_client_openssl_server_client_cert(suite) ->
+ [];
+tls1_erlang_client_openssl_server_client_cert(Config) when is_list(Config) ->
+ process_flag(trap_exit, true),
+ ServerOpts = ?config(server_verification_opts, Config),
+ ClientOpts = ?config(client_verification_opts, Config),
+
+ {ClientNode, _, Hostname} = ssl_test_lib:run_where(Config),
+
+ Data = "From openssl to erlang",
+
+ Port = ssl_test_lib:inet_port(node()),
+ CaCertFile = proplists:get_value(cacertfile, ServerOpts),
+ CertFile = proplists:get_value(certfile, ServerOpts),
+ KeyFile = proplists:get_value(keyfile, ServerOpts),
+
+ Cmd = "openssl s_server -accept " ++ integer_to_list(Port) ++
+ " -cert " ++ CertFile ++ " -CAfile " ++ CaCertFile
+ ++ " -key " ++ KeyFile ++ " -Verify 2 -tls1",
+
+ test_server:format("openssl cmd: ~p~n", [Cmd]),
+
+ OpensslPort = open_port({spawn, Cmd}, [stderr_to_stdout]),
+
+ wait_for_openssl_server(),
+
+ Client = ssl_test_lib:start_client([{node, ClientNode}, {port, Port},
+ {host, Hostname},
+ {from, self()},
+ {mfa, {?MODULE,
+ erlang_ssl_receive, [Data]}},
+ {options, ClientOpts}]),
+ port_command(OpensslPort, Data),
+
+ ssl_test_lib:check_result(Client, ok),
+
+ %% Clean close down!
+ close_port(OpensslPort),
+ ssl_test_lib:close(Client),
+ process_flag(trap_exit, false),
+ ok.
+
+%%--------------------------------------------------------------------
+
+tls1_erlang_server_openssl_client_client_cert(doc) ->
+ ["Test erlang server with openssl client when client sends cert"];
+tls1_erlang_server_openssl_client_client_cert(suite) ->
+ [];
+tls1_erlang_server_openssl_client_client_cert(Config) when is_list(Config) ->
+ process_flag(trap_exit, true),
+ ServerOpts = ?config(server_verification_opts, Config),
+ ClientOpts = ?config(client_verification_opts, Config),
+
+ {_, ServerNode, _} = ssl_test_lib:run_where(Config),
+
+ Data = "From openssl to erlang",
+
+ Server = ssl_test_lib:start_server([{node, ServerNode}, {port, 0},
+ {from, self()},
+ {mfa, {?MODULE,
+ erlang_ssl_receive, [Data]}},
+ {options,
+ [{verify , verify_peer}
+ | ServerOpts]}]),
+ Port = ssl_test_lib:inet_port(Server),
+
+ CaCertFile = proplists:get_value(cacertfile, ClientOpts),
+ CertFile = proplists:get_value(certfile, ClientOpts),
+ KeyFile = proplists:get_value(keyfile, ClientOpts),
+
+ Cmd = "openssl s_client -cert " ++ CertFile ++ " -CAfile " ++ CaCertFile
+ ++ " -key " ++ KeyFile ++ " -port " ++ integer_to_list(Port) ++
+ " -host localhost -tls1",
+
+ test_server:format("openssl cmd: ~p~n", [Cmd]),
+
+ OpenSslPort = open_port({spawn, Cmd}, [stderr_to_stdout]),
+ port_command(OpenSslPort, Data),
+
+ ssl_test_lib:check_result(Server, ok),
+
+ %% Clean close down!
+ close_port(OpenSslPort),
+ ssl_test_lib:close(Server),
+ process_flag(trap_exit, false),
+ ok.
+
+%%--------------------------------------------------------------------
+tls1_erlang_server_erlang_client_client_cert(doc) ->
+ ["Test erlang server with erlang client when client sends cert"];
+tls1_erlang_server_erlang_client_client_cert(suite) ->
+ [];
+tls1_erlang_server_erlang_client_client_cert(Config) when is_list(Config) ->
+ process_flag(trap_exit, true),
+ ServerOpts = ?config(server_verification_opts, Config),
+ ClientOpts = ?config(client_verification_opts, Config),
+
+ {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
+
+ Data = "From erlang to erlang",
+
+ Server = ssl_test_lib:start_server([{node, ServerNode}, {port, 0},
+ {from, self()},
+ {mfa, {?MODULE,
+ erlang_ssl_receive, [Data]}},
+ {options,
+ [{verify , verify_peer}
+ | ServerOpts]}]),
+ Port = ssl_test_lib:inet_port(Server),
+
+ Client = ssl_test_lib:start_client([{node, ClientNode}, {port, Port},
+ {host, Hostname},
+ {from, self()},
+ {mfa, {ssl, send, [Data]}},
+ {options,
+ [{versions, [tlsv1]} | ClientOpts]}]),
+
+ ssl_test_lib:check_result(Server, ok, Client, ok),
+
+ ssl_test_lib:close(Server),
+ %% Clean close down!
+ process_flag(trap_exit, false),
+ ok.
+%%--------------------------------------------------------------------
+
+ciphers(doc) ->
+ [""];
+
+ciphers(suite) ->
+ [];
+
+ciphers(Config) when is_list(Config) ->
+ Version =
+ ssl_record:protocol_version(ssl_record:highest_protocol_version([])),
+
+ Ciphers = ssl:cipher_suites(),
+ Result = lists:map(fun(Cipher) ->
+ cipher(Cipher, Version, Config) end,
+ Ciphers),
+ case lists:flatten(Result) of
+ [] ->
+ ok;
+ Error ->
+ test_server:format("Cipher suite errors: ~p~n", [Error]),
+ test_server:fail(cipher_suite_failed_see_test_case_log)
+ end.
+
+cipher(CipherSuite, Version, Config) ->
+ process_flag(trap_exit, true),
+ test_server:format("Testing CipherSuite ~p~n", [CipherSuite]),
+ ClientOpts = ?config(client_opts, Config),
+ ServerOpts = ?config(server_opts, Config),
+ {ClientNode, _ServerNode, Hostname} = ssl_test_lib:run_where(Config),
+
+ Port = ssl_test_lib:inet_port(node()),
+ CertFile = proplists:get_value(certfile, ServerOpts),
+ KeyFile = proplists:get_value(keyfile, ServerOpts),
+
+ Cmd = "openssl s_server -accept " ++ integer_to_list(Port) ++
+ " -cert " ++ CertFile ++ " -key " ++ KeyFile ++ "",
+
+ test_server:format("openssl cmd: ~p~n", [Cmd]),
+
+ OpenSslPort = open_port({spawn, Cmd}, [stderr_to_stdout]),
+
+ wait_for_openssl_server(),
+
+ Client = ssl_test_lib:start_client([{node, ClientNode}, {port, Port},
+ {host, Hostname},
+ {from, self()},
+ {mfa, {?MODULE, connection_info_result, []}},
+ {options,
+ [{ciphers,[CipherSuite]} |
+ ClientOpts]}]),
+
+ ClientMsg = {ok, {Version, CipherSuite}},
+
+ Result = ssl_test_lib:wait_for_result(Client, ClientMsg),
+
+ close_port(OpenSslPort),
+ %% Clean close down!
+ ssl_test_lib:close(Client),
+ receive
+ {'EXIT', Client, normal} ->
+ ok
+ end,
+
+ Return = case Result of
+ ok ->
+ [];
+ Error ->
+ [{CipherSuite, Error}]
+ end,
+ process_flag(trap_exit, false),
+ Return.
+
+%%--------------------------------------------------------------------
+erlang_client_bad_openssl_server(doc) ->
+ [""];
+erlang_client_bad_openssl_server(suite) ->
+ [];
+erlang_client_bad_openssl_server(Config) when is_list(Config) ->
+ process_flag(trap_exit, true),
+ ServerOpts = ?config(server_verification_opts, Config),
+ ClientOpts = ?config(client_verification_opts, Config),
+
+ {ClientNode, _, Hostname} = ssl_test_lib:run_where(Config),
+
+ Port = ssl_test_lib:inet_port(node()),
+ CertFile = proplists:get_value(certfile, ServerOpts),
+ KeyFile = proplists:get_value(keyfile, ServerOpts),
+
+ Cmd = "openssl s_server -accept " ++ integer_to_list(Port) ++
+ " -cert " ++ CertFile ++ " -key " ++ KeyFile ++ "",
+
+ test_server:format("openssl cmd: ~p~n", [Cmd]),
+
+ OpensslPort = open_port({spawn, Cmd}, [stderr_to_stdout]),
+
+ wait_for_openssl_server(),
+
+ Client = ssl_test_lib:start_client([{node, ClientNode}, {port, Port},
+ {host, Hostname},
+ {from, self()},
+ {mfa, {?MODULE, server_sent_garbage, []}},
+ {options,
+ [{versions, [tlsv1]} | ClientOpts]}]),
+
+ %% Send garbage
+ port_command(OpensslPort, ?OPENSSL_GARBAGE),
+
+ test_server:sleep(?SLEEP),
+
+ Client ! server_sent_garbage,
+
+ ssl_test_lib:check_result(Client, true),
+
+ ssl_test_lib:close(Client),
+ %% Clean close down!
+ close_port(OpensslPort),
+ process_flag(trap_exit, false),
+ ok.
+%%--------------------------------------------------------------------
+
+erlang_ssl_receive(Socket, Data) ->
+ test_server:format("Connection info: ~p~n",
+ [ssl:connection_info(Socket)]),
+ receive
+ {ssl, Socket, Data} ->
+ io:format("Received ~p~n",[Data]),
+ %% open_ssl server sometimes hangs waiting in blocking read
+ ssl:send(Socket, "Got it"),
+ ok;
+ {Port, {data,Debug}} when is_port(Port) ->
+ io:format("openssl ~s~n",[Debug]),
+ erlang_ssl_receive(Socket,Data);
+ Other ->
+ test_server:fail({unexpected_message, Other})
+ after 4000 ->
+ test_server:fail({did_not_get, Data})
+ end.
+
+connection_info(Socket, Version) ->
+ case ssl:connection_info(Socket) of
+ {ok, {Version, _} = Info} ->
+ test_server:format("Connection info: ~p~n", [Info]),
+ ok;
+ {ok, {OtherVersion, _}} ->
+ {wrong_version, OtherVersion}
+ end.
+
+connection_info_result(Socket) ->
+ ssl:connection_info(Socket).
+
+
+delayed_send(Socket, [ErlData, OpenSslData]) ->
+ test_server:sleep(?SLEEP),
+ ssl:send(Socket, ErlData),
+ erlang_ssl_receive(Socket, OpenSslData).
+
+close_port(Port) ->
+ port_command(Port, ?OPENSSL_QUIT),
+ %%catch port_command(Port, "quit\n"),
+ close_loop(Port, 500, false).
+
+close_loop(Port, Time, SentClose) ->
+ receive
+ {Port, {data,Debug}} when is_port(Port) ->
+ io:format("openssl ~s~n",[Debug]),
+ close_loop(Port, Time, SentClose);
+ {ssl,_,Msg} ->
+ io:format("ssl Msg ~s~n",[Msg]),
+ close_loop(Port, Time, SentClose);
+ {Port, closed} ->
+ io:format("Port Closed~n",[]),
+ ok;
+ {'EXIT', Port, Reason} ->
+ io:format("Port Closed ~p~n",[Reason]),
+ ok;
+ Msg ->
+ io:format("Port Msg ~p~n",[Msg]),
+ close_loop(Port, Time, SentClose)
+ after Time ->
+ case SentClose of
+ false ->
+ io:format("Closing port ~n",[]),
+ catch erlang:port_close(Port),
+ close_loop(Port, Time, true);
+ true ->
+ io:format("Timeout~n",[])
+ end
+ end.
+
+
+server_sent_garbage(Socket) ->
+ receive
+ server_sent_garbage ->
+ {error, closed} == ssl:send(Socket, "data")
+ end.
+
+wait_for_openssl_server() ->
+ receive
+ {Port, {data, Debug}} when is_port(Port) ->
+ io:format("openssl ~s~n",[Debug]),
+ %% openssl has started make sure
+ %% it will be in accept. Parsing
+ %% output is too error prone. (Even
+ %% more so than sleep!)
+ test_server:sleep(?SLEEP)
+ end.
+
diff --git a/lib/ssl/vsn.mk b/lib/ssl/vsn.mk
index 603c419653..a8966d46d7 100644
--- a/lib/ssl/vsn.mk
+++ b/lib/ssl/vsn.mk
@@ -1,25 +1,16 @@
-#
-# %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%
-#
-
-SSL_VSN = 3.10.7
-
-TICKETS = OTP-8260 OTP-8218 OTP-8250
+SSL_VSN = 3.11
+
+TICKETS = OTP-8517 \
+ OTP-7046 \
+ OTP-8557 \
+ OTP-8560 \
+ OTP-8545 \
+ OTP-8554
+
+#TICKETS_3.10.9 = OTP-8510
+
+#TICKETS_3.10.8 = OTP-8372 OTP-8441 OTP-8459
+#TICKETS_3.10.7 = OTP-8260 OTP-8218 OTP-8250
#TICKETS_3.10.6 = OTP-8275
diff --git a/lib/stdlib/doc/src/beam_lib.xml b/lib/stdlib/doc/src/beam_lib.xml
index f2a9c2a671..b9286f1402 100644
--- a/lib/stdlib/doc/src/beam_lib.xml
+++ b/lib/stdlib/doc/src/beam_lib.xml
@@ -4,7 +4,7 @@
<erlref>
<header>
<copyright>
- <year>2000</year><year>2009</year>
+ <year>2000</year><year>2010</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
@@ -13,12 +13,12 @@
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>beam_lib</title>
@@ -70,82 +70,88 @@
using <seealso marker="#strip/1">strip/1</seealso>,
<seealso marker="#strip_files/1">strip_files/1</seealso> and/or
<seealso marker="#strip_release/1">strip_release/1</seealso>.</p>
- <p><em>Reconstructing source code</em></p>
- <p>Here is an example of how to reconstruct source code from
- the debug information in a BEAM file <c>Beam</c>:</p>
- <code type="none">
+ <section>
+ <title>Reconstructing source code</title>
+ <p>Here is an example of how to reconstruct source code from
+ the debug information in a BEAM file <c>Beam</c>:</p>
+ <code type="none">
{ok,{_,[{abstract_code,{_,AC}}]}} = beam_lib:chunks(Beam,[abstract_code]).
io:fwrite("~s~n", [erl_prettypr:format(erl_syntax:form_list(AC))]).</code>
- <p><em>Encrypted debug information</em></p>
- <p>The debug information can be encrypted in order to keep
- the source code secret, but still being able to use tools such as
- Xref or Debugger. </p>
- <p>To use encrypted debug information, a key must be provided to
- the compiler and <c>beam_lib</c>. The key is given as a string and
- it is recommended that it contains at least 32 characters and
- that both upper and lower case letters as well as digits and
- special characters are used.</p>
- <p></p>
- <p>The default type -- and currently the only type -- of crypto
- algorithm is <c>des3_cbc</c>, three rounds of DES. The key string
- will be scrambled using <c>erlang:md5/1</c> to generate
- the actual keys used for <c>des3_cbc</c>.</p>
- <note>
- <p>As far as we know by the time of writing, it is
- infeasible to break <c>des3_cbc</c> encryption without any
- knowledge of the key. Therefore, as long as the key is kept
- safe and is unguessable, the encrypted debug information
- <em>should</em> be safe from intruders.</p>
- </note>
- <p>There are two ways to provide the key:</p>
- <list type="ordered">
- <item>
- <p>Use the compiler option <c>{debug_info,Key}</c>, see
- <seealso marker="compiler:compile#debug_info_key">compile(3)</seealso>,
- and the function
- <seealso marker="#crypto_key_fun/1">crypto_key_fun/1</seealso>
- to register a fun which returns the key whenever
- <c>beam_lib</c> needs to decrypt the debug information.</p>
- <p>If no such fun is registered, <c>beam_lib</c> will instead
- search for a <c>.erlang.crypt</c> file, see below.</p>
- </item>
- <item>
- <p>Store the key in a text file named <c>.erlang.crypt</c>.</p>
- <p>In this case, the compiler option <c>encrypt_debug_info</c>
- can be used, see
- <seealso marker="compiler:compile#encrypt_debug_info">compile(3)</seealso>.</p>
- </item>
- </list>
- <p><em>.erlang.crypt</em></p>
- <p><c>beam_lib</c> searches for <c>.erlang.crypt</c> in the current
- directory and then the home directory for the current user. If
- the file is found and contains a key, <c>beam_lib</c> will
- implicitly create a crypto key fun and register it.</p>
- <p>The <c>.erlang.crypt</c> file should contain a single list of
- tuples:</p>
- <code type="none">
+ </section>
+ <section>
+ <title>Encrypted debug information</title>
+ <p>The debug information can be encrypted in order to keep
+ the source code secret, but still being able to use tools such as
+ Xref or Debugger. </p>
+ <p>To use encrypted debug information, a key must be provided to
+ the compiler and <c>beam_lib</c>. The key is given as a string and
+ it is recommended that it contains at least 32 characters and
+ that both upper and lower case letters as well as digits and
+ special characters are used.</p>
+ <p></p>
+ <p>The default type -- and currently the only type -- of crypto
+ algorithm is <c>des3_cbc</c>, three rounds of DES. The key string
+ will be scrambled using <c>erlang:md5/1</c> to generate
+ the actual keys used for <c>des3_cbc</c>.</p>
+ <note>
+ <p>As far as we know by the time of writing, it is
+ infeasible to break <c>des3_cbc</c> encryption without any
+ knowledge of the key. Therefore, as long as the key is kept
+ safe and is unguessable, the encrypted debug information
+ <em>should</em> be safe from intruders.</p>
+ </note>
+ <p>There are two ways to provide the key:</p>
+ <list type="ordered">
+ <item>
+ <p>Use the compiler option <c>{debug_info,Key}</c>, see
+ <seealso marker="compiler:compile#debug_info_key">compile(3)</seealso>,
+ and the function
+ <seealso marker="#crypto_key_fun/1">crypto_key_fun/1</seealso>
+ to register a fun which returns the key whenever
+ <c>beam_lib</c> needs to decrypt the debug information.</p>
+ <p>If no such fun is registered, <c>beam_lib</c> will instead
+ search for a <c>.erlang.crypt</c> file, see below.</p>
+ </item>
+ <item>
+ <p>Store the key in a text file named <c>.erlang.crypt</c>.</p>
+ <p>In this case, the compiler option <c>encrypt_debug_info</c>
+ can be used, see
+ <seealso marker="compiler:compile#encrypt_debug_info">compile(3)</seealso>.</p>
+ </item>
+ </list>
+ </section>
+ <section>
+ <title>.erlang.crypt</title>
+ <p><c>beam_lib</c> searches for <c>.erlang.crypt</c> in the current
+ directory and then the home directory for the current user. If
+ the file is found and contains a key, <c>beam_lib</c> will
+ implicitly create a crypto key fun and register it.</p>
+ <p>The <c>.erlang.crypt</c> file should contain a single list of
+ tuples:</p>
+ <code type="none">
{debug_info, Mode, Module, Key}</code>
- <p><c>Mode</c> is the type of crypto algorithm; currently, the only
- allowed value thus is <c>des3_cbc</c>. <c>Module</c> is either an
- atom, in which case <c>Key</c> will only be used for the module
- <c>Module</c>, or <c>[]</c>, in which case <c>Key</c> will be
- used for all modules. <c>Key</c> is the non-empty key string.</p>
- <p>The <c>Key</c> in the first tuple where both <c>Mode</c> and
- <c>Module</c> matches will be used.</p>
- <p>Here is an example of an <c>.erlang.crypt</c> file that returns
- the same key for all modules:</p>
- <code type="none"><![CDATA[
+ <p><c>Mode</c> is the type of crypto algorithm; currently, the only
+ allowed value thus is <c>des3_cbc</c>. <c>Module</c> is either an
+ atom, in which case <c>Key</c> will only be used for the module
+ <c>Module</c>, or <c>[]</c>, in which case <c>Key</c> will be
+ used for all modules. <c>Key</c> is the non-empty key string.</p>
+ <p>The <c>Key</c> in the first tuple where both <c>Mode</c> and
+ <c>Module</c> matches will be used.</p>
+ <p>Here is an example of an <c>.erlang.crypt</c> file that returns
+ the same key for all modules:</p>
+ <code type="none"><![CDATA[
[{debug_info, des3_cbc, [], "%>7}|pc/DM6Cga*68$Mw]L#&_Gejr]G^"}].]]></code>
- <p>And here is a slightly more complicated example of an
- <c>.erlang.crypt</c> which provides one key for the module
- <c>t</c>, and another key for all other modules:</p>
- <code type="none"><![CDATA[
+ <p>And here is a slightly more complicated example of an
+ <c>.erlang.crypt</c> which provides one key for the module
+ <c>t</c>, and another key for all other modules:</p>
+ <code type="none"><![CDATA[
[{debug_info, des3_cbc, t, "My KEY"},
{debug_info, des3_cbc, [], "%>7}|pc/DM6Cga*68$Mw]L#&_Gejr]G^"}].]]></code>
- <note>
- <p>Do not use any of the keys in these examples. Use your own
- keys.</p>
- </note>
+ <note>
+ <p>Do not use any of the keys in these examples. Use your own
+ keys.</p>
+ </note>
+ </section>
</section>
<section>
diff --git a/lib/stdlib/doc/src/epp.xml b/lib/stdlib/doc/src/epp.xml
index 455d9dc124..e6b48b270a 100644
--- a/lib/stdlib/doc/src/epp.xml
+++ b/lib/stdlib/doc/src/epp.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>2010</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/.
+ The 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.
+ 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>epp</title>
@@ -112,7 +110,7 @@
<p>A string which describes the error is obtained with the following call:
</p>
<code type="none">
-apply(Module, format_error, ErrorDescriptor) </code>
+ Module:format_error(ErrorDescriptor) </code>
</section>
<section>
diff --git a/lib/stdlib/doc/src/erl_lint.xml b/lib/stdlib/doc/src/erl_lint.xml
index e339f484cc..6a7d37765c 100644
--- a/lib/stdlib/doc/src/erl_lint.xml
+++ b/lib/stdlib/doc/src/erl_lint.xml
@@ -4,7 +4,7 @@
<erlref>
<header>
<copyright>
- <year>1996</year><year>2009</year>
+ <year>1996</year><year>2010</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
@@ -13,12 +13,12 @@
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>erl_lint</title>
@@ -147,7 +147,7 @@
<p>A string which describes the error is obtained with the following call:
</p>
<code type="none">
-apply(Module, format_error, ErrorDescriptor) </code>
+ Module:format_error(ErrorDescriptor) </code>
</section>
<section>
diff --git a/lib/stdlib/doc/src/erl_parse.xml b/lib/stdlib/doc/src/erl_parse.xml
index 739fde7a40..ae8a8afd5c 100644
--- a/lib/stdlib/doc/src/erl_parse.xml
+++ b/lib/stdlib/doc/src/erl_parse.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>2010</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/.
+ The 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.
+ 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>erl_parse</title>
@@ -188,7 +186,7 @@
<p>A string which describes the error is obtained with the following call:
</p>
<code type="none">
-apply(Module, format_error, ErrorDescriptor) </code>
+ Module:format_error(ErrorDescriptor) </code>
</section>
<section>
diff --git a/lib/stdlib/doc/src/file_sorter.xml b/lib/stdlib/doc/src/file_sorter.xml
index b3f4da294c..ccb32659a0 100644
--- a/lib/stdlib/doc/src/file_sorter.xml
+++ b/lib/stdlib/doc/src/file_sorter.xml
@@ -4,7 +4,7 @@
<erlref>
<header>
<copyright>
- <year>2001</year><year>2009</year>
+ <year>2001</year><year>2010</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
@@ -13,12 +13,12 @@
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>file_sorter</title>
@@ -83,13 +83,15 @@
An ordering function is antisymmetric, transitive and total.
<c>Fun(A,&nbsp;B)</c> should return <c>true</c> if <c>A</c>
comes before <c>B</c> in the ordering, <c>false</c> otherwise.
+ An example of a typical ordering function is less than or equal
+ to, <c>=&lt;/2</c>.
Using an ordering function will slow down the sort
considerably. The <c>keysort</c>, <c>keymerge</c> and
<c>keycheck</c> functions do not accept ordering functions.
</item>
<item><c>{unique, bool()}</c>. When sorting or merging files,
- only the first of a sequence of terms that compare equal is
- output if this option is set to <c>true</c>. The default
+ only the first of a sequence of terms that compare equal (<c>==</c>)
+ is output if this option is set to <c>true</c>. The default
value is <c>false</c> which implies that all terms that
compare equal are output. When checking files for
sortedness, a check that no pair of consecutive terms
@@ -301,7 +303,7 @@ Value = Term</pre>
<desc>
<p>Sorts tuples on files. The sort is performed on the
element(s) mentioned in <c>KeyPos</c>. If two tuples
- compare equal on one element, next element according to
+ compare equal (<c>==</c>) on one element, next element according to
<c>KeyPos</c> is compared. The sort is stable.
</p>
<p><c>keysort(N, FileName)</c> is equivalent to
diff --git a/lib/stdlib/doc/src/filename.xml b/lib/stdlib/doc/src/filename.xml
index 3a6c5e0b60..0cf82fa48b 100644
--- a/lib/stdlib/doc/src/filename.xml
+++ b/lib/stdlib/doc/src/filename.xml
@@ -37,7 +37,7 @@
is meant all strings that can be used to denote a file. They can
be short relative names like <c>foo.erl</c>, very long absolute
name which include a drive designator and directory names like
- <c>D:\\usr/local\\bin\\erl/lib\\tools\\foo.erl</c>, or any variations
+ <c>D:\usr/local\bin\erl/lib\tools\foo.erl</c>, or any variations
in between.</p>
<p>In Windows, all functions return file names with forward slashes
only, even if the arguments contain back slashes. Use
@@ -173,7 +173,7 @@ name() = string() | atom() | DeepList
14> <input>filename:dirname("kalle.erl").</input>
"."
-5> <input>filename:dirname("\\\\usr\\\\src/kalle.erl").</input> % Windows
+5> <input>filename:dirname("\\usr\\src/kalle.erl").</input> % Windows
"/usr/src"</pre>
</desc>
</func>
@@ -228,7 +228,7 @@ name() = string() | atom() | DeepList
18> <input>filename:join(["a/b///c/"]).</input>
"a/b/c"
-6> <input>filename:join(["B:a\\\\b///c/"]).</input> % Windows
+6> <input>filename:join(["B:a\\b///c/"]).</input> % Windows
"b:a/b/c"</pre>
</desc>
</func>
@@ -259,7 +259,7 @@ name() = string() | atom() | DeepList
"/usr/local/bin"
7> <input>filename:nativename("/usr/local/bin/").</input> % Windows
-"\\\\usr\\\\local\\\\bin"</pre>
+"\\usr\\local\\bin"</pre>
</desc>
</func>
<func>
@@ -329,7 +329,7 @@ name() = string() | atom() | DeepList
["/","usr","local","bin"]
25> <input>filename:split("foo/bar").</input>
["foo","bar"]
-26> <input>filename:split("a:\\\\msdev\\\\include").</input>
+26> <input>filename:split("a:\\msdev\\include").</input>
["a:/","msdev","include"]</pre>
</desc>
</func>
diff --git a/lib/stdlib/doc/src/gb_sets.xml b/lib/stdlib/doc/src/gb_sets.xml
index accec623b9..60d8bcbfa3 100644
--- a/lib/stdlib/doc/src/gb_sets.xml
+++ b/lib/stdlib/doc/src/gb_sets.xml
@@ -4,7 +4,7 @@
<erlref>
<header>
<copyright>
- <year>2001</year><year>2009</year>
+ <year>2001</year><year>2010</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
@@ -13,12 +13,12 @@
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>gb_sets</title>
@@ -34,6 +34,8 @@
General Balanced Trees. This can be much more efficient than
using ordered lists, for larger sets, but depends on the
application.</p>
+ <p>This module considers two elements as different if and only if
+ they do not compare equal (<c>==</c>).</p>
</description>
<section>
diff --git a/lib/stdlib/doc/src/gb_trees.xml b/lib/stdlib/doc/src/gb_trees.xml
index 2bf18138c0..94f40c28bd 100644
--- a/lib/stdlib/doc/src/gb_trees.xml
+++ b/lib/stdlib/doc/src/gb_trees.xml
@@ -4,7 +4,7 @@
<erlref>
<header>
<copyright>
- <year>2001</year><year>2009</year>
+ <year>2001</year><year>2010</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
@@ -13,12 +13,12 @@
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>gb_trees</title>
@@ -34,6 +34,8 @@
Balanced Trees. These have no storage overhead compared to
unbalanced binary trees, and their performance is in general
better than AVL trees.</p>
+ <p>This module considers two keys as different if and only if
+ they do not compare equal (<c>==</c>).</p>
</description>
<section>
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/io.xml b/lib/stdlib/doc/src/io.xml
index c075f11792..efbb1fc078 100644
--- a/lib/stdlib/doc/src/io.xml
+++ b/lib/stdlib/doc/src/io.xml
@@ -4,7 +4,7 @@
<erlref>
<header>
<copyright>
- <year>1996</year><year>2009</year>
+ <year>1996</year><year>2010</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
@@ -13,12 +13,12 @@
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>io</title>
@@ -1003,7 +1003,8 @@ enter><input>bar.</input>
<title>Standard Error</title>
<p>In certain situations, especially when the standard output is redirected, access to an io_server() specific for error messages might be convenient. The io_device 'standard_error' can be used to direct output to whatever the current operating system considers a suitable device for error output. Example on a Unix-like operating system:</p>
<pre>
-$ <input>erl -noshell -noinput -eval 'io:format(standard_error,"Error: ~s~n",["error 11"]),init:stop().' > /dev/null</input>
+$ <input>erl -noshell -noinput -eval 'io:format(standard_error,"Error: ~s~n",["error 11"]),'\</input>
+<input>'init:stop().' > /dev/null</input>
Error: error 11</pre>
@@ -1020,7 +1021,7 @@ Error: error 11</pre>
<p>A string which describes the error is obtained with the following
call:</p>
<code type="none">
-apply(Module, format_error, ErrorDescriptor)</code>
+Module:format_error(ErrorDescriptor)</code>
</section>
</erlref>
diff --git a/lib/stdlib/doc/src/io_protocol.xml b/lib/stdlib/doc/src/io_protocol.xml
index 1b75114031..201787f7b5 100644
--- a/lib/stdlib/doc/src/io_protocol.xml
+++ b/lib/stdlib/doc/src/io_protocol.xml
@@ -546,7 +546,7 @@ request({get_chars, Encoding, _Prompt, N}, State) -&gt;
get_until(Encoding, ?MODULE, until_enough, [N], State);
request({get_line, Encoding, _Prompt}, State) -&gt;
%% To simplify the code, get_line is implemented using get_until
- get_until(Encoding, ?MODULE, until_newline, [$\\n], State);
+ get_until(Encoding, ?MODULE, until_newline, [$\n], State);
</code>
<p>Here we have cheated a little by more or less only implementing
diff --git a/lib/stdlib/doc/src/lists.xml b/lib/stdlib/doc/src/lists.xml
index 39fc05420d..855a7e0244 100644
--- a/lib/stdlib/doc/src/lists.xml
+++ b/lib/stdlib/doc/src/lists.xml
@@ -4,7 +4,7 @@
<erlref>
<header>
<copyright>
- <year>1996</year><year>2009</year>
+ <year>1996</year><year>2010</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
@@ -13,12 +13,12 @@
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>lists</title>
@@ -30,15 +30,16 @@
<module>lists</module>
<modulesummary>List Processing Functions</modulesummary>
<description>
- <p>This module contains functions for list processing. The functions
- are organized in two groups: those in the first group perform a
- particular operation on one or more lists, whereas those in the
- second group are higher-order functions, using a fun as argument
- to perform an operation on one list.</p>
+ <p>This module contains functions for list processing.</p>
+
<p>Unless otherwise stated, all functions assume that position
numbering starts at 1. That is, the first element of a list is at
position 1.</p>
+ <p>Two terms <c>T1</c> and <c>T2</c> compare equal if
+ <c>T1&nbsp;==&nbsp;T2</c> evaluates to <c>true</c>. They match
+ if <c>T1&nbsp;=:=&nbsp;T2</c> evaluates to <c>true</c>.</p>
+
<p>Whenever an <marker
id="ordering_function"></marker><em>ordering function</em>
<c>F</c> is expected as argument, it is assumed that the
diff --git a/lib/stdlib/doc/src/notes.xml b/lib/stdlib/doc/src/notes.xml
index f7128b641d..c55eafc8b8 100644
--- a/lib/stdlib/doc/src/notes.xml
+++ b/lib/stdlib/doc/src/notes.xml
@@ -4,7 +4,7 @@
<chapter>
<header>
<copyright>
- <year>2004</year><year>2009</year>
+ <year>2004</year><year>2010</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
@@ -13,12 +13,12 @@
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>STDLIB Release Notes</title>
@@ -30,6 +30,170 @@
</header>
<p>This document describes the changes made to the STDLIB application.</p>
+<section><title>STDLIB 1.16.5</title>
+
+ <section><title>Fixed Bugs and Malfunctions</title>
+ <list>
+ <item>
+ <p>
+ Because of a race condition, using filelib:ensure_dir/1
+ from multiple processes to create the same path or parts
+ of the same directory structure, filelib:ensure_dir/1
+ could return a meaningless {error,eexist}. That race
+ condition has been eliminated, and {error,eexist} will
+ now be returned only if there exists a regular file,
+ device file, or some other non-directory file with the
+ same name. (Thanks to Tuncer Ayaz.)</p>
+ <p>
+ Own Id: OTP-8389</p>
+ </item>
+ <item>
+ <p>A number of bugs concerning re and unicode are
+ corrected:</p>
+ <p>re:compile no longer looses unicode option, which also
+ fixes bug in re:split.</p>
+ <p>re:replace now handles unicode charlist replacement
+ argument</p>
+ <p>re:replace now handles unicode RE charlist argument
+ correctly</p>
+ <p>re:replace now handles binary unicode output correctly
+ when nothing is replaced.</p>
+ <p>Most code, testcases and error isolation done by Rory
+ Byrne.</p>
+ <p>
+ Own Id: OTP-8394</p>
+ </item>
+ <item>
+ <p>
+ The loading of native code was not properly atomic in the
+ SMP emulator, which could cause crashes. Also a per-MFA
+ information table for the native code has now been
+ protected with a lock since it turns that it could be
+ accessed concurrently in the SMP emulator. (Thanks to
+ Mikael Pettersson.)</p>
+ <p>
+ Own Id: OTP-8397</p>
+ </item>
+ <item>
+ <p>
+ user.erl (used in oldshell) is updated to handle unicode
+ in prompt strings (io:get_line/{1,2}). io_lib is also
+ updated to format prompts with the 't' modifier (i.e. ~ts
+ instead of ~s).</p>
+ <p>
+ Own Id: OTP-8418 Aux Id: OTP-8393 </p>
+ </item>
+ <item>
+ <p>
+ The re module: A regular expression with an option change
+ at the start of a pattern that had top-level alternatives
+ could cause overwriting and/or a crash. (Thanks to
+ Michael Santos.)</p>
+ <p>
+ Own Id: OTP-8438</p>
+ </item>
+ </list>
+ </section>
+
+
+ <section><title>Improvements and New Features</title>
+ <list>
+ <item>
+ <p>
+ The ability for the gen_server and gen_fsm callback
+ modules to format their own state for display under the
+ sys:get_status/1,2 calls has been restored and
+ documented. (Thanks to Steve Vinoski.)</p>
+ <p>
+ Own Id: OTP-8324</p>
+ </item>
+ <item>
+ <p>
+ c:nc/{1,2} used to assume that the beam file was created
+ in the same directory as the source code and failed to
+ load the code if it was not. Corrected to look for the
+ beam file in the current directory or in the directory
+ specified by the <c>{outdir,Dir}</c> option. (Thanks to
+ Alex Suraci.)</p>
+ <p>
+ Own Id: OTP-8337</p>
+ </item>
+ <item>
+ <p>The documentation is now possible to build in an open
+ source environment after a number of bugs are fixed and
+ some features are added in the documentation build
+ process. </p>
+ <p>- The arity calculation is updated.</p>
+ <p>- The module prefix used in the function names for
+ bif's are removed in the generated links so the links
+ will look like
+ "http://www.erlang.org/doc/man/erlang.html#append_element-2"
+ instead of
+ "http://www.erlang.org/doc/man/erlang.html#erlang:append_element-2".</p>
+ <p>- Enhanced the menu positioning in the html
+ documentation when a new page is loaded.</p>
+ <p>- A number of corrections in the generation of man
+ pages (thanks to Sergei Golovan)</p>
+ <p>- The legal notice is taken from the xml book file so
+ OTP's build process can be used for non OTP
+ applications.</p>
+ <p>
+ Own Id: OTP-8343</p>
+ </item>
+ <item>
+ <p>
+ Shell tab completion now works for quoted module and
+ function names. (Thanks to Ulf Wiger.)</p>
+ <p>
+ Own Id: OTP-8383</p>
+ </item>
+ <item>
+ <p>
+ Explicit top directories in archive files are now
+ optional.</p>
+ <p>
+ For example, if an archive (app-vsn.ez) just contains an
+ app-vsn/ebin/mod.beam file, the file info for the app-vsn
+ and app-vsn/ebin directories are faked using the file
+ info from the archive file as origin. The virtual
+ direcories can also be listed. For short, the top
+ directories are virtual if they does not exist.</p>
+ <p>
+ Own Id: OTP-8387</p>
+ </item>
+ <item>
+ <p>Macros overloading has been implemented. (Thanks to
+ Christopher Faulet.)</p>
+ <p>
+ Own Id: OTP-8388</p>
+ </item>
+ <item>
+ <p>The new function <c>shell:prompt_func/1</c> and the
+ new application configuration parameter
+ <c>shell_prompt_func</c> can be used for customizing the
+ Erlang shell prompt.</p>
+ <p>
+ Own Id: OTP-8393</p>
+ </item>
+ <item>
+ <p>
+ Improved handling of typed records in escripts</p>
+ <p>
+ Own Id: OTP-8434</p>
+ </item>
+ <item>
+ <p>
+ Added supervisor:count_children/1 to count the number of
+ children being managed without the memory impact of
+ which_children/1. (Thanks to Jay Nelson.)</p>
+ <p>
+ Own Id: OTP-8436</p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
<section><title>STDLIB 1.16.4</title>
<section><title>Improvements and New Features</title>
diff --git a/lib/stdlib/doc/src/proplists.xml b/lib/stdlib/doc/src/proplists.xml
index a218dcf1fe..9f1c5b24ad 100644
--- a/lib/stdlib/doc/src/proplists.xml
+++ b/lib/stdlib/doc/src/proplists.xml
@@ -4,7 +4,7 @@
<erlref>
<header>
<copyright>
- <year>2002</year><year>2009</year>
+ <year>2002</year><year>2010</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
@@ -13,12 +13,12 @@
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>proplists</title>
@@ -44,6 +44,9 @@
such as options passed to a function where a user may specify options
overriding the default settings, object properties, annotations,
etc.</p>
+ <p>Two keys are considered equal if they match (<c>=:=</c>). In other
+ words, numbers are compared literally rather than by value, so that,
+ for instance, <c>1</c> and <c>1.0</c> are different keys.</p>
</description>
<funcs>
<func>
diff --git a/lib/stdlib/doc/src/re.xml b/lib/stdlib/doc/src/re.xml
index 41dce7f2a7..4d2a0e0995 100644
--- a/lib/stdlib/doc/src/re.xml
+++ b/lib/stdlib/doc/src/re.xml
@@ -56,10 +56,10 @@
<note>
<p>The Erlang literal syntax for strings give special
- meaning to the &quot;\\&quot; (backslash) character. To literally write
+ meaning to the &quot;\&quot; (backslash) character. To literally write
a regular expression or a replacement string containing a
backslash in your code or in the shell, two backslashes have to be written:
- &quot;\\\\&quot;.</p>
+ &quot;\\&quot;.</p>
</note>
@@ -163,9 +163,9 @@ This option makes it possible to include comments inside complicated patterns. N
</taglist>
</item>
<tag><c>bsr_anycrlf</c></tag>
- <item>Specifies specifically that \\R is to match only the cr, lf or crlf sequences, not the Unicode specific newline characters.</item>
+ <item>Specifies specifically that \R is to match only the cr, lf or crlf sequences, not the Unicode specific newline characters.</item>
<tag><c>bsr_unicode</c></tag>
- <item>Specifies specifically that \\R is to match all the Unicode newline characters (including crlf etc, the default).</item>
+ <item>Specifies specifically that \R is to match all the Unicode newline characters (including crlf etc, the default).</item>
</taglist>
</desc>
</func>
@@ -384,9 +384,9 @@ This option makes it possible to include comments inside complicated patterns. N
</taglist>
</item>
<tag><c>bsr_anycrlf</c></tag>
- <item>Specifies specifically that \\R is to match only the cr, lf or crlf sequences, not the Unicode specific newline characters.(overrides compilation option)</item>
+ <item>Specifies specifically that \R is to match only the cr, lf or crlf sequences, not the Unicode specific newline characters.(overrides compilation option)</item>
<tag><c>bsr_unicode</c></tag>
- <item>Specifies specifically that \\R is to match all the Unicode newline characters (including crlf etc, the default).(overrides compilation option)</item>
+ <item>Specifies specifically that \R is to match all the Unicode newline characters (including crlf etc, the default).(overrides compilation option)</item>
<tag><c>{capture, ValueSpec}</c>/<c>{capture, ValueSpec, Type}</c></tag>
<item>
@@ -471,9 +471,9 @@ This option makes it possible to include comments inside complicated patterns. N
<tag><c>index</c></tag>
<item>Return captured substrings as pairs of byte indexes into the subject string and length of the matching string in the subject (as if the subject string was flattened with <c>iolist_to_binary/1</c> or <c>unicode:characters_to_binary/2</c> prior to matching). Note that the <c>unicode</c> option results in <em>byte-oriented</em> indexes in a (possibly imagined) <em>UTF-8 encoded</em> binary. A byte index tuple <c>{0,2}</c> might therefore represent one or two characters when <c>unicode</c> is in effect. This might seem contra-intuitive, but has been deemed the most effective and useful way to way to do it. To return lists instead might result in simpler code if that is desired. This return type is the default.</item>
<tag><c>list</c></tag>
- <item>Return matching substrings as lists of characters (Erlang <c>string()</c>'s). It the <c>unicode</c> option is used in combination with the \\C sequence in the regular expression, a captured subpattern can contain bytes that has is not valid UTF-8 (\\C matches bytes regardless of character encoding). In that case the <c>list</c> capturing may result in the same types of tuples that <c>unicode:characters_to_list/2</c> can return, namely three-tuples with the tag <c>incomplete</c> or <c>error</c>, the successfully converted characters and the invalid UTF-8 tail of the conversion as a binary. The best strategy is to avoid using the\\C sequence when capturing lists.</item>
+ <item>Return matching substrings as lists of characters (Erlang <c>string()</c>'s). It the <c>unicode</c> option is used in combination with the \C sequence in the regular expression, a captured subpattern can contain bytes that has is not valid UTF-8 (\C matches bytes regardless of character encoding). In that case the <c>list</c> capturing may result in the same types of tuples that <c>unicode:characters_to_list/2</c> can return, namely three-tuples with the tag <c>incomplete</c> or <c>error</c>, the successfully converted characters and the invalid UTF-8 tail of the conversion as a binary. The best strategy is to avoid using the \C sequence when capturing lists.</item>
<tag><c>binary</c></tag>
- <item>Return matching substrings as binaries. If the <c>unicode</c> option is used, these binaries is in UTF-8. If the \\C sequence is used together with <c>unicode</c> the binaries may be invalid UTF-8.</item>
+ <item>Return matching substrings as binaries. If the <c>unicode</c> option is used, these binaries is in UTF-8. If the \C sequence is used together with <c>unicode</c> the binaries may be invalid UTF-8.</item>
</taglist>
</item>
</taglist>
@@ -544,20 +544,20 @@ This option makes it possible to include comments inside complicated patterns. N
<p>The replacement string can contain the special character
<c>&amp;</c>, which inserts the whole matching expression in the
- result, and the special sequence <c>\\</c>N (where N is an
+ result, and the special sequence <c>\</c>N (where N is an
integer &gt; 0), resulting in the subexpression number N will be
inserted in the result. If no subexpression with that number is
generated by the regular expression, nothing is inserted.</p>
- <p>To insert an <c>&amp;</c> or <c>\\</c> in the result, precede it
- with a <c>\\</c>. Note that Erlang already gives a special
- meaning to <c>\\</c> in literal strings, why a single <c>\\</c>
- has to be written as <c>"\\\\"</c> and therefore a double <c>\\</c>
- as <c>"\\\\\\\\"</c>. Example:</p>
+ <p>To insert an <c>&amp;</c> or <c>\</c> in the result, precede it
+ with a <c>\</c>. Note that Erlang already gives a special
+ meaning to <c>\</c> in literal strings, why a single <c>\</c>
+ has to be written as <c>"\\"</c> and therefore a double <c>\</c>
+ as <c>"\\\\"</c>. Example:</p>
<code> re:replace("abcd","c","[&amp;]",[{return,list}]).</code>
<p>gives</p>
<code> "ab[c]d"</code>
<p>while</p>
- <code> re:replace("abcd","c","[\\\&amp;]",[{return,list}]).</code>
+ <code> re:replace("abcd","c","[\\&amp;]",[{return,list}]).</code>
<p>gives</p>
<code> "ab[&amp;]d"</code>
<p>As with <c>re:run/3</c>, compilation errors raise the <c>badarg</c>
@@ -592,7 +592,7 @@ This option makes it possible to include comments inside complicated patterns. N
<v>NLSpec = cr | crlf | lf | anycrlf | any </v>
<v>SplitList = [ RetData ] | [ GroupedRetData ]</v>
<v>GroupedRetData = [ RetData ]</v>
- <v>RetData = iodata() charlist() | binary() | list()</v>
+ <v>RetData = iodata() | charlist() | binary() | list()</v>
</type>
<desc>
<p>This function splits the input into parts by finding tokens
@@ -852,19 +852,19 @@ example, the pattern:</p>
<p> (*CR)a.b</p>
</quote>
-<p>changes the convention to CR. That pattern matches "a\\nb" because LF is no
+<p>changes the convention to CR. That pattern matches "a\nb" because LF is no
longer a newline. Note that these special settings, which are not
Perl-compatible, are recognized only at the very start of a pattern, and that
they must be in upper case. If more than one of them is present, the last one
is used.</p>
-<p>The newline convention does not affect what the \\R escape sequence matches. By
+<p>The newline convention does not affect what the \R escape sequence matches. By
default, this is any Unicode newline sequence, for Perl compatibility. However,
-this can be changed; see the description of \\R in the section entitled
+this can be changed; see the description of \R in the section entitled
"Newline sequences"
-below. A change of \\R setting can be combined with a change of newline
+below. A change of \R setting can be combined with a change of newline
convention.</p>
</section>
@@ -897,7 +897,7 @@ recognized within square brackets. Outside square brackets, the metacharacters
are as follows:</p>
<taglist>
- <tag>\\</tag> <item>general escape character with several uses</item>
+ <tag>\</tag> <item>general escape character with several uses</item>
<tag>^</tag> <item>assert start of string (or line, in multiline mode)</item>
<tag>$</tag> <item>assert end of string (or line, in multiline mode)</item>
<tag>.</tag> <item>match any character except newline (by default)</item>
@@ -918,7 +918,7 @@ are as follows:</p>
a character class the only metacharacters are:</p>
<taglist>
- <tag>\\</tag> <item>general escape character</item>
+ <tag>\</tag> <item>general escape character</item>
<tag>^</tag> <item>negate the class, but only if the first character</item>
<tag>-</tag> <item>indicates character range</item>
<tag>[</tag> <item>POSIX character class (only if followed by POSIX
@@ -939,11 +939,11 @@ non-alphanumeric character, it takes away any special meaning that character
may have. This use of backslash as an escape character applies both inside and
outside character classes.</p>
-<p>For example, if you want to match a * character, you write \\* in the pattern.
+<p>For example, if you want to match a * character, you write \* in the pattern.
This escaping action applies whether or not the following character would
otherwise be interpreted as a metacharacter, so it is always safe to precede a
non-alphanumeric with backslash to specify that it stands for itself. In
-particular, if you want to match a backslash, you write \\\\.</p>
+particular, if you want to match a backslash, you write \\.</p>
<p>If a pattern is compiled with the <c>extended</c> option, whitespace in the
pattern (other than in a character class) and characters between a # outside
@@ -951,18 +951,18 @@ a character class and the next newline are ignored. An escaping backslash can
be used to include a whitespace or # character as part of the pattern.</p>
<p>If you want to remove the special meaning from a sequence of characters, you
-can do so by putting them between \\Q and \\E. This is different from Perl in
-that $ and @ are handled as literals in \\Q...\\E sequences in PCRE, whereas in
+can do so by putting them between \Q and \E. This is different from Perl in
+that $ and @ are handled as literals in \Q...\E sequences in PCRE, whereas in
Perl, $ and @ cause variable interpolation. Note the following examples:</p>
<code type="none">
Pattern PCRE matches Perl matches
- \\Qabc$xyz\\E abc$xyz abc followed by the contents of $xyz
- \\Qabc\\$xyz\\E abc\\$xyz abc\\$xyz
- \\Qabc\\E\\$\\Qxyz\\E abc$xyz abc$xyz</code>
+ \Qabc$xyz\E abc$xyz abc followed by the contents of $xyz
+ \Qabc\$xyz\E abc\$xyz abc\$xyz
+ \Qabc\E\$\Qxyz\E abc$xyz abc$xyz</code>
-<p>The \\Q...\\E sequence is recognized both inside and outside character classes.</p>
+<p>The \Q...\E sequence is recognized both inside and outside character classes.</p>
<p><em>Non-printing characters</em></p>
@@ -975,41 +975,41 @@ use one of the following escape sequences than the binary character it
represents:</p>
<taglist>
- <tag>\\a</tag> <item>alarm, that is, the BEL character (hex 07)</item>
- <tag>\\cx</tag> <item>"control-x", where x is any character</item>
- <tag>\\e </tag> <item>escape (hex 1B)</item>
- <tag>\\f</tag> <item>formfeed (hex 0C)</item>
- <tag>\\n</tag> <item>linefeed (hex 0A)</item>
- <tag>\\r</tag> <item>carriage return (hex 0D)</item>
- <tag>\\t </tag> <item>tab (hex 09)</item>
- <tag>\\ddd</tag> <item>character with octal code ddd, or backreference</item>
- <tag>\\xhh </tag> <item>character with hex code hh</item>
- <tag>\\x{hhh..}</tag> <item>character with hex code hhh..</item>
+ <tag>\a</tag> <item>alarm, that is, the BEL character (hex 07)</item>
+ <tag>\cx</tag> <item>"control-x", where x is any character</item>
+ <tag>\e </tag> <item>escape (hex 1B)</item>
+ <tag>\f</tag> <item>formfeed (hex 0C)</item>
+ <tag>\n</tag> <item>linefeed (hex 0A)</item>
+ <tag>\r</tag> <item>carriage return (hex 0D)</item>
+ <tag>\t </tag> <item>tab (hex 09)</item>
+ <tag>\ddd</tag> <item>character with octal code ddd, or backreference</item>
+ <tag>\xhh </tag> <item>character with hex code hh</item>
+ <tag>\x{hhh..}</tag> <item>character with hex code hhh..</item>
</taglist>
-<p>The precise effect of \\cx is as follows: if x is a lower case letter, it
+<p>The precise effect of \cx is as follows: if x is a lower case letter, it
is converted to upper case. Then bit 6 of the character (hex 40) is inverted.
-Thus \\cz becomes hex 1A, but \\c{ becomes hex 3B, while \\c; becomes hex
+Thus \cz becomes hex 1A, but \c{ becomes hex 3B, while \c; becomes hex
7B.</p>
-<p>After \\x, from zero to two hexadecimal digits are read (letters can be in
-upper or lower case). Any number of hexadecimal digits may appear between \\x{
+<p>After \x, from zero to two hexadecimal digits are read (letters can be in
+upper or lower case). Any number of hexadecimal digits may appear between \x{
and }, but the value of the character code must be less than 256 in non-UTF-8
mode, and less than 2**31 in UTF-8 mode. That is, the maximum value in
hexadecimal is 7FFFFFFF. Note that this is bigger than the largest Unicode code
point, which is 10FFFF.</p>
-<p>If characters other than hexadecimal digits appear between \\x{ and }, or if
+<p>If characters other than hexadecimal digits appear between \x{ and }, or if
there is no terminating }, this form of escape is not recognized. Instead, the
-initial \\x will be interpreted as a basic hexadecimal escape, with no
+initial \x will be interpreted as a basic hexadecimal escape, with no
following digits, giving a character whose value is zero.</p>
<p>Characters whose value is less than 256 can be defined by either of the two
-syntaxes for \\x. There is no difference in the way they are handled. For
-example, \\xdc is exactly the same as \\x{dc}.</p>
+syntaxes for \x. There is no difference in the way they are handled. For
+example, \xdc is exactly the same as \x{dc}.</p>
-<p>After \\0 up to two further octal digits are read. If there are fewer than two
-digits, just those that are present are used. Thus the sequence \\0\\x\\07
+<p>After \0 up to two further octal digits are read. If there are fewer than two
+digits, just those that are present are used. Thus the sequence \0\x\07
specifies two binary zeros followed by a BEL character (code value 7). Make
sure you supply two digits after the initial zero if the pattern character that
follows is itself an octal digit.</p>
@@ -1027,32 +1027,32 @@ have not been that many capturing subpatterns, PCRE re-reads up to three octal
digits following the backslash, and uses them to generate a data character. Any
subsequent digits stand for themselves.
The value of a
-character specified in octal must be less than \\400.
+character specified in octal must be less than \400.
In non-UTF-8 mode, the value of a
-character specified in octal must be less than \\400. In UTF-8 mode, values up
-to \\777 are permitted.
+character specified in octal must be less than \400. In UTF-8 mode, values up
+to \777 are permitted.
For example:</p>
<taglist>
- <tag>\\040</tag> <item>is another way of writing a space</item>
+ <tag>\040</tag> <item>is another way of writing a space</item>
- <tag>\\40</tag> <item>is the same, provided there are fewer than 40
+ <tag>\40</tag> <item>is the same, provided there are fewer than 40
previous capturing subpatterns</item>
- <tag>\\7</tag> <item>is always a back reference</item>
+ <tag>\7</tag> <item>is always a back reference</item>
- <tag>\\11</tag> <item> might be a back reference, or another way of
+ <tag>\11</tag> <item> might be a back reference, or another way of
writing a tab</item>
- <tag>\\011</tag> <item>is always a tab</item>
- <tag>\\0113</tag> <item>is a tab followed by the character "3"</item>
+ <tag>\011</tag> <item>is always a tab</item>
+ <tag>\0113</tag> <item>is a tab followed by the character "3"</item>
- <tag>\\113</tag> <item>might be a back reference, otherwise the
+ <tag>\113</tag> <item>might be a back reference, otherwise the
character with octal code 113</item>
- <tag>\\377</tag> <item>might be a back reference, otherwise
+ <tag>\377</tag> <item>might be a back reference, otherwise
the byte consisting entirely of 1 bits</item>
- <tag>\\81</tag> <item>is either a back reference, or a binary zero
+ <tag>\81</tag> <item>is either a back reference, or a binary zero
followed by the two characters "8" and "1"</item>
</taglist>
@@ -1062,16 +1062,16 @@ read.</p>
<p>All the sequences that define a single character value can be used
both inside and outside character classes. In addition, inside a
-character class, the sequence \\b is interpreted as the backspace
-character (hex 08), and the sequences \\R and \\X are interpreted as
+character class, the sequence \b is interpreted as the backspace
+character (hex 08), and the sequences \R and \X are interpreted as
the characters "R" and "X", respectively. Outside a character class,
these sequences have different meanings (see below).</p>
<p><em>Absolute and relative back references</em></p>
-<p>The sequence \\g followed by an unsigned or a negative number,
+<p>The sequence \g followed by an unsigned or a negative number,
optionally enclosed in braces, is an absolute or relative back
-reference. A named back reference can be coded as \\g{name}. Back
+reference. A named back reference can be coded as \g{name}. Back
references are discussed later, following the discussion of
parenthesized subpatterns.</p>
@@ -1081,16 +1081,16 @@ parenthesized subpatterns.</p>
following are always recognized:</p>
<taglist>
- <tag>\\d</tag> <item>any decimal digit</item>
- <tag>\\D</tag> <item>any character that is not a decimal digit</item>
- <tag>\\h</tag> <item>any horizontal whitespace character</item>
- <tag>\\H</tag> <item>any character that is not a horizontal whitespace character</item>
- <tag>\\s</tag> <item>any whitespace character</item>
- <tag>\\S</tag> <item>any character that is not a whitespace character</item>
- <tag>\\v</tag> <item>any vertical whitespace character</item>
- <tag>\\V</tag> <item>any character that is not a vertical whitespace character</item>
- <tag>\\w</tag> <item>any "word" character</item>
- <tag>\\W</tag> <item>any "non-word" character</item>
+ <tag>\d</tag> <item>any decimal digit</item>
+ <tag>\D</tag> <item>any character that is not a decimal digit</item>
+ <tag>\h</tag> <item>any horizontal whitespace character</item>
+ <tag>\H</tag> <item>any character that is not a horizontal whitespace character</item>
+ <tag>\s</tag> <item>any whitespace character</item>
+ <tag>\S</tag> <item>any character that is not a whitespace character</item>
+ <tag>\v</tag> <item>any vertical whitespace character</item>
+ <tag>\V</tag> <item>any character that is not a vertical whitespace character</item>
+ <tag>\w</tag> <item>any "word" character</item>
+ <tag>\W</tag> <item>any "non-word" character</item>
</taglist>
<p>Each pair of escape sequences partitions the complete set of characters into
@@ -1101,19 +1101,19 @@ classes. They each match one character of the appropriate type. If the current
matching point is at the end of the subject string, all of them fail, since
there is no character to match.</p>
-<p>For compatibility with Perl, \\s does not match the VT character (code 11).
-This makes it different from the POSIX "space" class. The \\s characters
+<p>For compatibility with Perl, \s does not match the VT character (code 11).
+This makes it different from the POSIX "space" class. The \s characters
are HT (9), LF (10), FF (12), CR (13), and space (32). If "use locale;" is
-included in a Perl script, \\s may match the VT character. In PCRE, it never
+included in a Perl script, \s may match the VT character. In PCRE, it never
does.</p>
-<p>In UTF-8 mode, characters with values greater than 128 never match \\d, \\s, or
-\\w, and always match \\D, \\S, and \\W. This is true even when Unicode
+<p>In UTF-8 mode, characters with values greater than 128 never match \d, \s, or
+\w, and always match \D, \S, and \W. This is true even when Unicode
character property support is available. These sequences retain their original
meanings from before UTF-8 support was available, mainly for efficiency
reasons.</p>
-<p>The sequences \\h, \\H, \\v, and \\V are Perl 5.10 features. In contrast to the
+<p>The sequences \h, \H, \v, and \V are Perl 5.10 features. In contrast to the
other sequences, these do match certain high-valued codepoints in UTF-8 mode.
The horizontal space characters are:</p>
@@ -1157,11 +1157,11 @@ low-valued character tables, which are always ISO-8859-1.</p>
<p><em>Newline sequences</em></p>
-<p>Outside a character class, by default, the escape sequence \\R matches any
-Unicode newline sequence. This is a Perl 5.10 feature. In non-UTF-8 mode \\R is
+<p>Outside a character class, by default, the escape sequence \R matches any
+Unicode newline sequence. This is a Perl 5.10 feature. In non-UTF-8 mode \R is
equivalent to the following:</p>
-<quote><p> (?&gt;\\r\\n|\\n|\\x0b|\\f|\\r|\\x85)</p></quote>
+<quote><p> (?&gt;\r\n|\n|\x0b|\f|\r|\x85)</p></quote>
<p>This is an example of an "atomic group", details of which are given below.</p>
@@ -1177,7 +1177,7 @@ Unicode character property support is not needed for these characters to be
recognized.</p>
-<p>It is possible to restrict \\R to match only CR, LF, or CRLF (instead of the
+<p>It is possible to restrict \R to match only CR, LF, or CRLF (instead of the
complete set of Unicode line endings) by setting the option <c>bsr_anycrlf</c>
either at compile time or when the pattern is matched. (BSR is an abbreviation
for "backslash R".) This can be made the default when PCRE is built; if this is
@@ -1197,7 +1197,7 @@ newline convention, for example, a pattern can start with:</p>
<p> (*ANY)(*BSR_ANYCRLF)</p>
-<p>Inside a character class, \\R matches the letter "R".</p>
+<p>Inside a character class, \R matches the letter "R".</p>
<p><em>Unicode character properties</em></p>
@@ -1208,22 +1208,22 @@ When not in UTF-8 mode, these sequences are of course limited to testing
characters whose codepoints are less than 256, but they do work in this mode.
The extra escape sequences are:</p>
-<p> \\p{<em>xx</em>} a character with the <em>xx</em> property
- \\P{<em>xx</em>} a character without the <em>xx</em> property
- \\X an extended Unicode sequence</p>
+<p> \p{<em>xx</em>} a character with the <em>xx</em> property
+ \P{<em>xx</em>} a character without the <em>xx</em> property
+ \X an extended Unicode sequence</p>
<p>The property names represented by <em>xx</em> above are limited to the Unicode
script names, the general category properties, and "Any", which matches any
character (including newline). Other properties such as "InMusicalSymbols" are
-not currently supported by PCRE. Note that \\P{Any} does not match any
+not currently supported by PCRE. Note that \P{Any} does not match any
characters, so always causes a match failure.</p>
<p>Sets of Unicode characters are defined as belonging to certain scripts. A
character from one of these sets can be matched using a script name. For
example:</p>
-<p> \\p{Greek}
- \\P{Han}</p>
+<p> \p{Greek}
+ \P{Han}</p>
<p>Those that are not part of an identified script are lumped together as
"Common". The current list of scripts is:</p>
@@ -1300,15 +1300,15 @@ example:</p>
<p>Each character has exactly one general category property, specified by a
two-letter abbreviation. For compatibility with Perl, negation can be specified
by including a circumflex between the opening brace and the property name. For
-example, \\p{^Lu} is the same as \\P{Lu}.</p>
+example, \p{^Lu} is the same as \P{Lu}.</p>
-<p>If only one letter is specified with \\p or \\P, it includes all the general
+<p>If only one letter is specified with \p or \P, it includes all the general
category properties that start with that letter. In this case, in the absence
of negation, the curly brackets in the escape sequence are optional; these two
examples have the same effect:</p>
-<list><item>\\p{L}</item>
- <item>\\pL</item></list>
+<list><item>\p{L}</item>
+ <item>\pL</item></list>
<p>The following general category property codes are supported:</p>
@@ -1382,7 +1382,7 @@ cannot be tested by PCRE, unless UTF-8 validity checking has been turned off
<em>pcreapi</em>
page).</p>
-<p>The long synonyms for these properties that Perl supports (such as \\p{Letter})
+<p>The long synonyms for these properties that Perl supports (such as \p{Letter})
are not supported by PCRE, nor is it permitted to prefix any of these
properties with "Is".</p>
@@ -1391,12 +1391,12 @@ Instead, this property is assumed for any code point that is not in the
Unicode table.</p>
<p>Specifying caseless matching does not affect these escape sequences. For
-example, \\p{Lu} always matches only upper case letters.</p>
+example, \p{Lu} always matches only upper case letters.</p>
-<p>The \\X escape matches any number of Unicode characters that form an extended
-Unicode sequence. \\X is equivalent to</p>
+<p>The \X escape matches any number of Unicode characters that form an extended
+Unicode sequence. \X is equivalent to</p>
-<quote><p> (?&gt;\\PM\\pM*)</p></quote>
+<quote><p> (?&gt;\PM\pM*)</p></quote>
<p>That is, it matches a character without the "mark" property, followed by zero
or more characters with the "mark" property, and treats the sequence as an
@@ -1404,20 +1404,20 @@ atomic group
(see below).
Characters with the "mark" property are typically accents that affect the
preceding character. None of them have codepoints less than 256, so in
-non-UTF-8 mode \\X matches any one character.</p>
+non-UTF-8 mode \X matches any one character.</p>
<p>Matching characters by Unicode property is not fast, because PCRE has to search
a structure that contains data for over fifteen thousand characters. That is
-why the traditional escape sequences such as \\d and \\w do not use Unicode
+why the traditional escape sequences such as \d and \w do not use Unicode
properties in PCRE.</p>
<p><em>Resetting the match start</em></p>
-<p>The escape sequence \\K, which is a Perl 5.10 feature, causes any previously
+<p>The escape sequence \K, which is a Perl 5.10 feature, causes any previously
matched characters not to be included in the final matched sequence. For
example, the pattern:</p>
-<quote><p> foo\\Kbar</p></quote>
+<quote><p> foo\Kbar</p></quote>
<p>matches "foobar", but reports that it has matched "bar". This feature is
similar to a lookbehind assertion
@@ -1426,12 +1426,12 @@ similar to a lookbehind assertion
(described below).
However, in this case, the part of the subject before the real match does not
-have to be of fixed length, as lookbehind assertions do. The use of \\K does
+have to be of fixed length, as lookbehind assertions do. The use of \K does
not interfere with the setting of
captured substrings.
For example, when the pattern</p>
-<quote><p> (foo)\\Kbar</p></quote>
+<quote><p> (foo)\Kbar</p></quote>
<p>matches "foobar", the first substring is still set to "foo".</p>
@@ -1444,50 +1444,50 @@ string. The use of subpatterns for more complicated assertions is
described below. The backslashed assertions are:</p>
<taglist>
- <tag>\\b</tag> <item>matches at a word boundary</item>
- <tag>\\B</tag> <item>matches when not at a word boundary</item>
- <tag>\\A</tag> <item>matches at the start of the subject</item>
- <tag>\\Z</tag> <item>matches at the end of the subject
+ <tag>\b</tag> <item>matches at a word boundary</item>
+ <tag>\B</tag> <item>matches when not at a word boundary</item>
+ <tag>\A</tag> <item>matches at the start of the subject</item>
+ <tag>\Z</tag> <item>matches at the end of the subject
also matches before a newline at the end of
the subject</item>
- <tag>\\z</tag> <item>matches only at the end of the subject</item>
- <tag>\\G</tag> <item>matches at the first matching position in the
+ <tag>\z</tag> <item>matches only at the end of the subject</item>
+ <tag>\G</tag> <item>matches at the first matching position in the
subject</item>
</taglist>
-<p>These assertions may not appear in character classes (but note that \\b has a
+<p>These assertions may not appear in character classes (but note that \b has a
different meaning, namely the backspace character, inside a character class).</p>
<p>A word boundary is a position in the subject string where the current character
-and the previous character do not both match \\w or \\W (i.e. one matches
-\\w and the other matches \\W), or the start or end of the string if the
-first or last character matches \\w, respectively.</p>
+and the previous character do not both match \w or \W (i.e. one matches
+\w and the other matches \W), or the start or end of the string if the
+first or last character matches \w, respectively.</p>
-<p>The \\A, \\Z, and \\z assertions differ from the traditional circumflex and
+<p>The \A, \Z, and \z assertions differ from the traditional circumflex and
dollar (described in the next section) in that they only ever match at the very
start and end of the subject string, whatever options are set. Thus, they are
independent of multiline mode. These three assertions are not affected by the
<c>notbol</c> or <c>noteol</c> options, which affect only the behaviour of the
circumflex and dollar metacharacters. However, if the <em>startoffset</em>
argument of <c>re:run/3</c> is non-zero, indicating that matching is to start
-at a point other than the beginning of the subject, \\A can never match. The
-difference between \\Z and \\z is that \\Z matches before a newline at the end
-of the string as well as at the very end, whereas \\z matches only at the end.</p>
+at a point other than the beginning of the subject, \A can never match. The
+difference between \Z and \z is that \Z matches before a newline at the end
+of the string as well as at the very end, whereas \z matches only at the end.</p>
-<p>The \\G assertion is true only when the current matching position is at the
+<p>The \G assertion is true only when the current matching position is at the
start point of the match, as specified by the <em>startoffset</em> argument of
-<c>re:run/3</c>. It differs from \\A when the value of <em>startoffset</em> is
+<c>re:run/3</c>. It differs from \A when the value of <em>startoffset</em> is
non-zero. By calling <c>re:run/3</c> multiple times with appropriate
arguments, you can mimic Perl's /g option, and it is in this kind of
-implementation where \\G can be useful.</p>
+implementation where \G can be useful.</p>
-<p>Note, however, that PCRE's interpretation of \\G, as the start of the current
+<p>Note, however, that PCRE's interpretation of \G, as the start of the current
match, is subtly different from Perl's, which defines it as the end of the
previous match. In Perl, these can be different when the previously matched
string was empty. Because PCRE does just one match at a time, it cannot
reproduce this behaviour.</p>
-<p>If all the alternatives of a pattern begin with \\G, the expression is anchored
+<p>If all the alternatives of a pattern begin with \G, the expression is anchored
to the starting match position, and the "anchored" flag is set in the compiled
regular expression.</p>
@@ -1519,7 +1519,7 @@ character class.</p>
<p>The meaning of dollar can be changed so that it matches only at the
very end of the string, by setting the <c>dollar_endonly</c> option at
-compile time. This does not affect the \\Z assertion.</p>
+compile time. This does not affect the \Z assertion.</p>
<p>The meanings of the circumflex and dollar characters are changed if the
<c>multiline</c> option is set. When this is the case, a circumflex matches
@@ -1530,16 +1530,16 @@ matches before any newlines in the string, as well as at the very end, when
sequence CRLF, isolated CR and LF characters do not indicate newlines.</p>
<p>For example, the pattern /^abc$/ matches the subject string
-"def\\nabc" (where \\n represents a newline) in multiline mode, but
+"def\nabc" (where \n represents a newline) in multiline mode, but
not otherwise. Consequently, patterns that are anchored in single line
mode because all branches start with ^ are not anchored in multiline
mode, and a match for circumflex is possible when the
<em>startoffset</em> argument of <c>re:run/3</c> is non-zero. The
<c>dollar_endonly</c> option is ignored if <c>multiline</c> is set.</p>
-<p>Note that the sequences \\A, \\Z, and \\z can be used to match the start and
+<p>Note that the sequences \A, \Z, and \z can be used to match the start and
end of the subject in both modes, and if all branches of a pattern start with
-\\A it is always anchored, whether or not <c>multiline</c> is set.</p>
+\A it is always anchored, whether or not <c>multiline</c> is set.</p>
</section>
@@ -1574,14 +1574,14 @@ involve newlines. Dot has no special meaning in a character class.</p>
<section><marker id="sect6"></marker><title>Matching a single byte</title>
-<p>Outside a character class, the escape sequence \\C matches any one byte, both
+<p>Outside a character class, the escape sequence \C matches any one byte, both
in and out of UTF-8 mode. Unlike a dot, it always matches any line-ending
characters. The feature is provided in Perl in order to match individual bytes
in UTF-8 mode. Because it breaks up UTF-8 characters into individual bytes,
what remains in the string may be a malformed UTF-8 string. For this reason,
-the \\C escape sequence is best avoided.</p>
+the \C escape sequence is best avoided.</p>
-<p>PCRE does not allow \\C to appear in lookbehind assertions (described below),
+<p>PCRE does not allow \C to appear in lookbehind assertions (described below),
because in UTF-8 mode this would make it impossible to calculate the length of
the lookbehind.</p>
@@ -1615,7 +1615,7 @@ string, and therefore it fails if the current pointer is at the end of the
string.</p>
<p>In UTF-8 mode, characters with values greater than 255 can be included in a
-class as a literal string of bytes, or by using the \\x{ escaping mechanism.</p>
+class as a literal string of bytes, or by using the \x{ escaping mechanism.</p>
<p>When caseless matching is set, any letters in a class represent both their
upper case and lower case versions, so for example, a caseless [aeiou] matches
@@ -1648,32 +1648,32 @@ character of a range. A pattern such as [W-]46] is interpreted as a
class of two characters ("W" and "-") followed by a literal string
"46]", so it would match "W46]" or "-46]". However, if the "]" is
escaped with a backslash it is interpreted as the end of range, so
-[W-\\]46] is interpreted as a class containing a range followed by two
+[W-\]46] is interpreted as a class containing a range followed by two
other characters. The octal or hexadecimal representation of "]" can
also be used to end a range.</p>
<p>Ranges operate in the collating sequence of character values. They can also be
-used for characters specified numerically, for example [\\000-\\037].
+used for characters specified numerically, for example [\000-\037].
In UTF-8
mode, ranges can include characters whose values are greater than 255, for
-example [\\x{100}-\\x{2ff}].
+example [\x{100}-\x{2ff}].
</p>
<p>If a range that includes letters is used when caseless matching is set, it
matches the letters in either case. For example, [W-c] is equivalent to
-[][\\\\^_`wxyzabc], matched caselessly
+[][\\^_`wxyzabc], matched caselessly
, and in non-UTF-8 mode, if character
-tables for a French locale are in use, [\\xc8-\\xcb] matches accented E
+tables for a French locale are in use, [\xc8-\xcb] matches accented E
characters in both cases. In UTF-8 mode, PCRE supports the concept of case for
characters with values greater than 128 only when it is compiled with Unicode
property support.</p>
-<p>The character types \\d, \\D, \\p, \\P, \\s, \\S, \\w, and \\W may
+<p>The character types \d, \D, \p, \P, \s, \S, \w, and \W may
also appear in a character class, and add the characters that they
-match to the class. For example, [\\dABCDEF] matches any hexadecimal
+match to the class. For example, [\dABCDEF] matches any hexadecimal
digit. A circumflex can conveniently be used with the upper case
character types to specify a more restricted set of characters than
-the matching lower case type. For example, the class [^\\W_] matches
+the matching lower case type. For example, the class [^\W_] matches
any letter or digit, but not underscore.</p>
<p>The only metacharacters that are recognized in character classes
@@ -1702,20 +1702,20 @@ are</p>
<tag>ascii</tag> <item>character codes 0 - 127</item>
<tag>blank</tag> <item>space or tab only</item>
<tag>cntrl</tag> <item>control characters</item>
- <tag>digit</tag> <item>decimal digits (same as \\d)</item>
+ <tag>digit</tag> <item>decimal digits (same as \d)</item>
<tag>graph</tag> <item>printing characters, excluding space</item>
<tag>lower</tag> <item>lower case letters</item>
<tag>print</tag> <item>printing characters, including space</item>
<tag>punct</tag> <item>printing characters, excluding letters and digits</item>
- <tag>space</tag> <item>whitespace (not quite the same as \\s)</item>
+ <tag>space</tag> <item>whitespace (not quite the same as \s)</item>
<tag>upper</tag> <item>upper case letters</item>
- <tag>word</tag> <item>"word" characters (same as \\w)</item>
+ <tag>word</tag> <item>"word" characters (same as \w)</item>
<tag>xdigit</tag> <item>hexadecimal digits</item>
</taglist>
<p>The "space" characters are HT (9), LF (10), VT (11), FF (12), CR (13), and
space (32). Notice that this list includes the VT character (code 11). This
-makes "space" different to \\s, which does not include VT (for Perl
+makes "space" different to \s, which does not include VT (for Perl
compatibility).</p>
<p>The name "word" is a Perl extension, and "blank" is a GNU extension
@@ -1936,7 +1936,7 @@ match. Suppose you want to match the name of a weekday, either as a 3-letter
abbreviation or as the full name, and in both cases you want to extract the
abbreviation. This pattern (ignoring the line breaks) does the job:</p>
-<code type="none">
+<code type="none">
(?&lt;DN&gt;Mon|Fri|Sun)(?:day)?|
(?&lt;DN&gt;Tue)(?:sday)?|
(?&lt;DN&gt;Wed)(?:nesday)?|
@@ -1972,12 +1972,12 @@ following items:</p>
<list>
<item>a literal data character</item>
<item>the dot metacharacter</item>
- <item>the \\C escape sequence</item>
- <item>the \\X escape sequence
+ <item>the \C escape sequence</item>
+ <item>the \X escape sequence
(in UTF-8 mode with Unicode properties)
</item>
- <item>the \\R escape sequence</item>
- <item>an escape such as \\d that matches a single character</item>
+ <item>the \R escape sequence</item>
+ <item>an escape such as \d that matches a single character</item>
<item>a character class</item>
<item>a back reference (see next section)</item>
<item>a parenthesized subpattern (unless it is an assertion)</item>
@@ -1999,7 +1999,7 @@ quantifier specifies an exact number of required matches. Thus</p>
<p>matches at least 3 successive vowels, but may match many more, while</p>
-<quote><p> \\d{8}</p></quote>
+<quote><p> \d{8}</p></quote>
<p>matches exactly 8 digits. An opening curly bracket that appears in a position
where a quantifier is not allowed, or one that does not match the syntax of a
@@ -2007,9 +2007,9 @@ quantifier, is taken as a literal character. For example, {,6} is not a
quantifier, but a literal string of four characters.</p>
<p>In UTF-8 mode, quantifiers apply to UTF-8 characters rather than to individual
-bytes. Thus, for example, \\x{100}{2} matches two UTF-8 characters, each of
+bytes. Thus, for example, \x{100}{2} matches two UTF-8 characters, each of
which is represented by a two-byte sequence. Similarly, when Unicode property
-support is available, \\X{3} matches three Unicode extended sequences, each of
+support is available, \X{3} matches three Unicode extended sequences, each of
which may be several bytes long (and they may be of different lengths).</p>
<p>The quantifier {0} is permitted, causing the expression to behave as if the
@@ -2042,7 +2042,7 @@ is in trying to match comments in C programs. These appear between /* and */
and within the comment, individual * and / characters may appear. An attempt to
match C comments by applying the pattern</p>
-<quote><p> /\\*.*\\*/</p></quote>
+<quote><p> /\*.*\*/</p></quote>
<p>to the string</p>
@@ -2055,14 +2055,14 @@ item.</p>
greedy, and instead matches the minimum number of times possible, so the
pattern</p>
-<quote><p> /\\*.*?\\*/</p></quote>
+<quote><p> /\*.*?\*/</p></quote>
<p>does the right thing with the C comments. The meaning of the various
quantifiers is not otherwise changed, just the preferred number of matches.
Do not confuse this use of question mark with its use as a quantifier in its
own right. Because it has two uses, it can sometimes appear doubled, as in</p>
-<quote><p> \\d??\\d</p></quote>
+<quote><p> \d??\d</p></quote>
<p>which matches one digit by preference, but can match two if that is the only
way the rest of the pattern matches.</p>
@@ -2081,7 +2081,7 @@ to Perl's /s) is set, thus allowing the dot to match newlines, the pattern is
implicitly anchored, because whatever follows will be tried against every
character position in the subject string, so there is no point in retrying the
overall match at any position after the first. PCRE normally treats such a
-pattern as though it were preceded by \\A.</p>
+pattern as though it were preceded by \A.</p>
<p>In cases where it is known that the subject string contains no newlines, it is
worth setting <c>dotall</c> in order to obtain this optimization, or
@@ -2092,7 +2092,7 @@ is inside capturing parentheses that are the subject of a backreference
elsewhere in the pattern, a match at the start may fail where a later one
succeeds. Consider, for example:</p>
-<quote><p> (.*)abc\\1</p></quote>
+<quote><p> (.*)abc\1</p></quote>
<p>If the subject is "xyz123abc123" the match point is the fourth character. For
this reason, such a pattern is not implicitly anchored.</p>
@@ -2100,7 +2100,7 @@ this reason, such a pattern is not implicitly anchored.</p>
<p>When a capturing subpattern is repeated, the value captured is the substring
that matched the final iteration. For example, after</p>
-<quote><p> (tweedle[dume]{3}\\s*)+</p></quote>
+<quote><p> (tweedle[dume]{3}\s*)+</p></quote>
<p>has matched "tweedledum tweedledee" the value of the captured substring is
"tweedledee". However, if there are nested capturing subpatterns, the
@@ -2123,12 +2123,12 @@ pattern to match. Sometimes it is useful to prevent this, either to change the
nature of the match, or to cause it fail earlier than it otherwise might, when
the author of the pattern knows there is no point in carrying on.</p>
-<p>Consider, for example, the pattern \\d+foo when applied to the subject line</p>
+<p>Consider, for example, the pattern \d+foo when applied to the subject line</p>
<quote><p> 123456bar</p></quote>
<p>After matching all 6 digits and then failing to match "foo", the normal
-action of the matcher is to try again with only 5 digits matching the \\d+
+action of the matcher is to try again with only 5 digits matching the \d+
item, and then with 4, and so on, before ultimately failing. "Atomic grouping"
(a term taken from Jeffrey Friedl's book) provides the means for specifying
that once a subpattern has matched, it is not to be re-evaluated in this way.</p>
@@ -2137,7 +2137,7 @@ that once a subpattern has matched, it is not to be re-evaluated in this way.</p
immediately on failing to match "foo" the first time. The notation is a kind of
special parenthesis, starting with (?&gt; as in this example:</p>
-<quote><p> (?&gt;\\d+)foo</p></quote>
+<quote><p> (?&gt;\d+)foo</p></quote>
<p>This kind of parenthesis "locks up" the part of the pattern it contains once
it has matched, and a failure further into the pattern is prevented from
@@ -2150,9 +2150,9 @@ the current point in the subject string.</p>
<p>Atomic grouping subpatterns are not capturing subpatterns. Simple cases such as
the above example can be thought of as a maximizing repeat that must swallow
-everything it can. So, while both \\d+ and \\d+? are prepared to adjust the
+everything it can. So, while both \d+ and \d+? are prepared to adjust the
number of digits they match in order to make the rest of the pattern match,
-(?&gt;\\d+) can only match an entire sequence of digits.</p>
+(?&gt;\d+) can only match an entire sequence of digits.</p>
<p>Atomic groups in general can of course contain arbitrarily complicated
subpatterns, and can be nested. However, when the subpattern for an atomic
@@ -2161,7 +2161,7 @@ notation, called a "possessive quantifier" can be used. This consists of an
additional + character following a quantifier. Using this notation, the
previous example can be rewritten as</p>
-<quote><p> \\d++foo</p></quote>
+<quote><p> \d++foo</p></quote>
<p>Note that a possessive quantifier can be used with an entire group, for
example:</p>
@@ -2189,7 +2189,7 @@ be repeated an unlimited number of times, the use of an atomic group is the
only way to avoid some failing matches taking a very long time indeed. The
pattern</p>
-<quote><p> (\\D+|&lt;\\d+&gt;)*[!?]</p></quote>
+<quote><p> (\D+|&lt;\d+&gt;)*[!?]</p></quote>
<p>matches an unlimited number of substrings that either consist of non-digits, or
digits enclosed in &lt;&gt;, followed by either ! or ?. When it matches, it runs
@@ -2198,7 +2198,7 @@ quickly. However, if it is applied to</p>
<quote><p> aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa</p></quote>
<p>it takes a long time before reporting failure. This is because the string can
-be divided between the internal \\D+ repeat and the external * repeat in a
+be divided between the internal \D+ repeat and the external * repeat in a
large number of ways, and all have to be tried. (The example uses [!?] rather
than a single character at the end, because both PCRE and Perl have an
optimization that allows for fast failure when a single character is used. They
@@ -2206,7 +2206,7 @@ remember the last single character that is required for a match, and fail early
if it is not present in the string.) If the pattern is changed so that it uses
an atomic group, like this:</p>
-<quote><p> ((?&gt;\\D+)|&lt;\\d+&gt;)*[!?]</p></quote>
+<quote><p> ((?&gt;\D+)|&lt;\d+&gt;)*[!?]</p></quote>
<p>sequences of non-digits cannot be broken, and failure happens quickly.</p>
@@ -2229,22 +2229,22 @@ in an earlier iteration.</p>
<p>It is not possible to have a numerical "forward back reference" to
a subpattern whose number is 10 or more using this syntax because a
-sequence such as \\50 is interpreted as a character defined in
+sequence such as \50 is interpreted as a character defined in
octal. See the subsection entitled "Non-printing characters" above for
further details of the handling of digits following a backslash. There
is no such problem when named parentheses are used. A back reference
to any subpattern is possible using named parentheses (see below).</p>
<p>Another way of avoiding the ambiguity inherent in the use of digits
-following a backslash is to use the \\g escape sequence, which is a
+following a backslash is to use the \g escape sequence, which is a
feature introduced in Perl 5.10. This escape must be followed by an
unsigned number or a negative number, optionally enclosed in
braces. These examples are all identical:</p>
<list>
- <item>(ring), \\1</item>
- <item>(ring), \\g1</item>
- <item>(ring), \\g{1}</item>
+ <item>(ring), \1</item>
+ <item>(ring), \g1</item>
+ <item>(ring), \g{1}</item>
</list>
<p>An unsigned number specifies an absolute reference without the
@@ -2252,11 +2252,11 @@ ambiguity that is present in the older syntax. It is also useful when
literal digits follow the reference. A negative number is a relative
reference. Consider this example:</p>
-<quote><p> (abc(def)ghi)\\g{-1}</p></quote>
+<quote><p> (abc(def)ghi)\g{-1}</p></quote>
-<p>The sequence \\g{-1} is a reference to the most recently started capturing
-subpattern before \\g, that is, is it equivalent to \\2. Similarly, \\g{-2}
-would be equivalent to \\1. The use of relative references can be helpful in
+<p>The sequence \g{-1} is a reference to the most recently started capturing
+subpattern before \g, that is, is it equivalent to \2. Similarly, \g{-2}
+would be equivalent to \1. The use of relative references can be helpful in
long patterns, and also in patterns that are created by joining together
fragments that contain references within themselves.</p>
@@ -2265,29 +2265,29 @@ subpattern in the current subject string, rather than anything
matching the subpattern itself (see "Subpatterns as subroutines" below
for a way of doing that). So the pattern</p>
-<quote><p> (sens|respons)e and \\1ibility</p></quote>
+<quote><p> (sens|respons)e and \1ibility</p></quote>
<p>matches "sense and sensibility" and "response and responsibility", but not
"sense and responsibility". If caseful matching is in force at the time of the
back reference, the case of letters is relevant. For example,</p>
-<quote><p> ((?i)rah)\\s+\\1</p></quote>
+<quote><p> ((?i)rah)\s+\1</p></quote>
<p>matches "rah rah" and "RAH RAH", but not "RAH rah", even though the original
capturing subpattern is matched caselessly.</p>
<p>There are several different ways of writing back references to named
-subpatterns. The .NET syntax \\k{name} and the Perl syntax \\k&lt;name&gt; or
-\\k'name' are supported, as is the Python syntax (?P=name). Perl 5.10's unified
-back reference syntax, in which \\g can be used for both numeric and named
+subpatterns. The .NET syntax \k{name} and the Perl syntax \k&lt;name&gt; or
+\k'name' are supported, as is the Python syntax (?P=name). Perl 5.10's unified
+back reference syntax, in which \g can be used for both numeric and named
references, is also supported. We could rewrite the above example in any of
the following ways:</p>
<list>
- <item>(?&lt;p1&gt;(?i)rah)\\s+\\k&lt;p1&gt;</item>
- <item>(?'p1'(?i)rah)\\s+\\k{p1}</item>
- <item>(?P&lt;p1&gt;(?i)rah)\\s+(?P=p1)</item>
- <item>(?&lt;p1&gt;(?i)rah)\\s+\\g{p1}</item>
+ <item>(?&lt;p1&gt;(?i)rah)\s+\k&lt;p1&gt;</item>
+ <item>(?'p1'(?i)rah)\s+\k{p1}</item>
+ <item>(?P&lt;p1&gt;(?i)rah)\s+(?P=p1)</item>
+ <item>(?&lt;p1&gt;(?i)rah)\s+\g{p1}</item>
</list>
<p>A subpattern that is referenced by name may appear in the pattern before or
@@ -2297,7 +2297,7 @@ after the reference.</p>
subpattern has not actually been used in a particular match, any back
references to it always fail. For example, the pattern</p>
-<quote><p> (a|(bc))\\2</p></quote>
+<quote><p> (a|(bc))\2</p></quote>
<p>always fails if it starts to match "a" rather than "bc". Because
there may be many capturing parentheses in a pattern, all digits
@@ -2308,11 +2308,11 @@ some delimiter must be used to terminate the back reference. If the
empty comment (see "Comments" below) can be used.</p>
<p>A back reference that occurs inside the parentheses to which it refers fails
-when the subpattern is first used, so, for example, (a\\1) never matches.
+when the subpattern is first used, so, for example, (a\1) never matches.
However, such references can be useful inside repeated subpatterns. For
example, the pattern</p>
-<quote><p> (a|b\\1)+</p></quote>
+<quote><p> (a|b\1)+</p></quote>
<p>matches any number of "a"s and also "aba", "ababbaa" etc. At each iteration of
the subpattern, the back reference matches the character string corresponding
@@ -2327,7 +2327,7 @@ minimum of zero.</p>
<p>An assertion is a test on the characters following or preceding the current
matching point that does not actually consume any characters. The simple
-assertions coded as \\b, \\B, \\A, \\G, \\Z, \\z, ^ and $ are described
+assertions coded as \b, \B, \A, \G, \Z, \z, ^ and $ are described
above.</p>
@@ -2348,7 +2348,7 @@ because it does not make sense for negative assertions.</p>
<p>Lookahead assertions start with (?= for positive assertions and (?! for
negative assertions. For example,</p>
-<quote><p> \\w+(?=;)</p></quote>
+<quote><p> \w+(?=;)</p></quote>
<p>matches a word followed by a semicolon, but does not include the semicolon in
the match, and</p>
@@ -2400,7 +2400,7 @@ lengths, but it is acceptable if rewritten to use two top-level branches:</p>
<quote><p> (?&lt;=abc|abde)</p></quote>
-<p>In some cases, the Perl 5.10 escape sequence \\K (see above) can be
+<p>In some cases, the Perl 5.10 escape sequence \K (see above) can be
used instead of a lookbehind assertion; this is not restricted to a
fixed-length.</p>
@@ -2409,9 +2409,9 @@ temporarily move the current position back by the fixed length and then try to
match. If there are insufficient characters before the current position, the
assertion fails.</p>
-<p>PCRE does not allow the \\C escape (which matches a single byte in UTF-8 mode)
+<p>PCRE does not allow the \C escape (which matches a single byte in UTF-8 mode)
to appear in lookbehind assertions, because it makes it impossible to calculate
-the length of the lookbehind. The \\X and \\R escapes, which can match
+the length of the lookbehind. The \X and \R escapes, which can match
different numbers of bytes, are also not permitted.</p>
<p>Possessive quantifiers can be used in conjunction with lookbehind assertions to
@@ -2443,7 +2443,7 @@ approach makes a significant difference to the processing time.</p>
<p>Several assertions (of any sort) may occur in succession. For example,</p>
-<quote><p> (?&lt;=\\d{3})(?&lt;!999)foo</p></quote>
+<quote><p> (?&lt;=\d{3})(?&lt;!999)foo</p></quote>
<p>matches "foo" preceded by three digits that are not "999". Notice
that each of the assertions is applied independently at the same point
@@ -2454,7 +2454,7 @@ three characters are not "999". This pattern does <em>not</em> match
the last three of which are not "999". For example, it doesn't match
"123abcfoo". A pattern to do that is</p>
-<quote><p> (?&lt;=\\d{3}...)(?&lt;!999)foo</p></quote>
+<quote><p> (?&lt;=\d{3}...)(?&lt;!999)foo</p></quote>
<p>This time the first assertion looks at the preceding six
characters, checking that the first three are digits, and then the
@@ -2468,7 +2468,7 @@ second assertion checks that the preceding three characters are not
<p>matches an occurrence of "baz" that is preceded by "bar" which in
turn is not preceded by "foo", while</p>
-<quote><p> (?&lt;=\\d{3}(?!999)...)foo</p></quote>
+<quote><p> (?&lt;=\d{3}(?!999)...)foo</p></quote>
<p>is another pattern that matches "foo" preceded by three digits and any three
characters that are not "999".</p>
@@ -2510,7 +2510,7 @@ refer to subsequent groups with constructs such as (?(+2).</p>
whitespace to make it more readable (assume the <c>extended</c>
option) and to divide it into three parts for ease of discussion:</p>
-<quote><p> ( \\( )? [^()]+ (?(1) \\) )</p></quote>
+<quote><p> ( \( )? [^()]+ (?(1) \) )</p></quote>
<p>The first part matches an optional opening parenthesis, and if that
character is present, sets it as the first captured substring. The second part
@@ -2525,7 +2525,7 @@ non-parentheses, optionally enclosed in parentheses.</p>
<p>If you were embedding this pattern in a larger one, you could use a relative
reference:</p>
-<quote><p> ...other stuff... ( \\( )? [^()]+ (?(-1) \\) ) ...</p></quote>
+<quote><p> ...other stuff... ( \( )? [^()]+ (?(-1) \) ) ...</p></quote>
<p>This makes the fragment independent of the parentheses in the larger pattern.</p>
@@ -2543,7 +2543,7 @@ consist entirely of digits is not recommended.</p>
<p>Rewriting the above example to use a named subpattern gives this:</p>
-<quote><p> (?&lt;OPEN&gt; \\( )? [^()]+ (?(&lt;OPEN&gt;) \\) )</p></quote>
+<quote><p> (?&lt;OPEN&gt; \( )? [^()]+ (?(&lt;OPEN&gt;) \) )</p></quote>
<p><em>Checking for pattern recursion</em></p>
@@ -2571,8 +2571,8 @@ point in the pattern; the idea of DEFINE is that it can be used to define
is described below.) For example, a pattern to match an IPv4 address could be
written like this (ignore whitespace and line breaks):</p>
-<quote><p> (?(DEFINE) (?&lt;byte&gt; 2[0-4]\\d | 25[0-5] | 1\\d\\d | [1-9]?\\d) )
- \\b (?&amp;byte) (\\.(?&amp;byte)){3} \\b</p></quote>
+<quote><p> (?(DEFINE) (?&lt;byte&gt; 2[0-4]\d | 25[0-5] | 1\d\d | [1-9]?\d) )
+ \b (?&amp;byte) (\.(?&amp;byte)){3} \b</p></quote>
<p>The first part of the pattern is a DEFINE group inside which a another group
named "byte" is defined. This matches an individual component of an IPv4
@@ -2590,9 +2590,9 @@ assertion. This may be a positive or negative lookahead or lookbehind
assertion. Consider this pattern, again containing non-significant
whitespace, and with the two alternatives on the second line:</p>
-<code type="none">
+<code type="none">
(?(?=[^a-z]*[a-z])
- \\d{2}-[a-z]{3}-\\d{2} | \\d{2}-\\d{2}-\\d{2} )</code>
+ \d{2}-[a-z]{3}-\d{2} | \d{2}-\d{2}-\d{2} )</code>
<p>The condition is a positive lookahead assertion that matches an optional
sequence of non-letters followed by a letter. In other words, it tests for the
@@ -2631,7 +2631,7 @@ can refer to the expression itself. A Perl pattern using code
interpolation to solve the parentheses problem can be created like
this:</p>
-<quote><p> $re = qr{\\( (?: (?&gt;[^()]+) | (?p{$re}) )* \\)}x;</p></quote>
+<quote><p> $re = qr{\( (?: (?&gt;[^()]+) | (?p{$re}) )* \)}x;</p></quote>
<p>The (?p{...}) item interpolates Perl code at run time, and in this
case refers recursively to the pattern in which it appears.</p>
@@ -2657,7 +2657,7 @@ failure.</p>
<p>This PCRE pattern solves the nested parentheses problem (assume the
<c>extended</c> option is set so that whitespace is ignored):</p>
-<quote><p> \\( ( (?&gt;[^()]+) | (?R) )* \\)</p></quote>
+<quote><p> \( ( (?&gt;[^()]+) | (?R) )* \)</p></quote>
<p>First it matches an opening parenthesis. Then it matches any number
of substrings which can either be a sequence of non-parentheses, or a
@@ -2667,7 +2667,7 @@ parenthesized substring). Finally there is a closing parenthesis.</p>
<p>If this were part of a larger pattern, you would not want to
recurse the entire pattern, so instead you could use this:</p>
-<quote><p> ( \\( ( (?&gt;[^()]+) | (?1) )* \\) )</p></quote>
+<quote><p> ( \( ( (?&gt;[^()]+) | (?1) )* \) )</p></quote>
<p>We have put the pattern into parentheses, and caused the recursion
to refer to them instead of the whole pattern.</p>
@@ -2691,7 +2691,7 @@ Perl syntax for this is (?&amp;name); PCRE's earlier syntax
(?P&gt;name) is also supported. We could rewrite the above example as
follows:</p>
-<quote><p> (?&lt;pn&gt; \\( ( (?&gt;[^()]+) | (?&amp;pn) )* \\) )</p></quote>
+<quote><p> (?&lt;pn&gt; \( ( (?&gt;[^()]+) | (?&amp;pn) )* \) )</p></quote>
<p>If there is more than one subpattern with the same name, the earliest one is
used.</p>
@@ -2727,7 +2727,7 @@ If the pattern above is matched against</p>
on at the top level. If additional parentheses are added, giving</p>
<code type="none">
- \\( ( ( (?&gt;[^()]+) | (?R) )* ) \\)
+ \( ( ( (?&gt;[^()]+) | (?R) )* ) \)
^ ^
^ ^</code>
@@ -2747,7 +2747,7 @@ brackets, allowing for arbitrary nesting. Only digits are allowed in
nested brackets (that is, when recursing), whereas any characters are
permitted at the outer level.</p>
-<quote><p> &lt; (?: (?(R) \\d++ | [^&lt;&gt;]*+) | (?R)) * &gt;</p></quote>
+<quote><p> &lt; (?: (?(R) \d++ | [^&lt;&gt;]*+) | (?R)) * &gt;</p></quote>
<p>In this pattern, (?(R) is the start of a conditional subpattern,
with two different alternatives for the recursive and non-recursive
@@ -2771,7 +2771,7 @@ relative, as in these examples:</p>
<p>An earlier example pointed out that the pattern</p>
-<quote><p> (sens|respons)e and \\1ibility</p></quote>
+<quote><p> (sens|respons)e and \1ibility</p></quote>
<p>matches "sense and sensibility" and "response and responsibility", but not
"sense and responsibility". If instead the pattern</p>
diff --git a/lib/stdlib/doc/src/regexp.xml b/lib/stdlib/doc/src/regexp.xml
index 8da636e4ad..8c4191c88f 100644
--- a/lib/stdlib/doc/src/regexp.xml
+++ b/lib/stdlib/doc/src/regexp.xml
@@ -132,7 +132,7 @@
<v>RepCount = integer()</v>
</type>
<desc>
- <p>Substitutes the first occurrence of a substring matching <c>RegExp</c> in <c>String</c> with the string <c>New</c>. A <c><![CDATA[&]]></c> in the string <c>New</c> is replaced by the matched substring of <c>String</c>. <c><![CDATA[\\&]]></c> puts a literal <c><![CDATA[&]]></c> into the replacement string. It returns as follows:</p>
+ <p>Substitutes the first occurrence of a substring matching <c>RegExp</c> in <c>String</c> with the string <c>New</c>. A <c><![CDATA[&]]></c> in the string <c>New</c> is replaced by the matched substring of <c>String</c>. <c><![CDATA[\&]]></c> puts a literal <c><![CDATA[&]]></c> into the replacement string. It returns as follows:</p>
<taglist>
<tag><c>{ok,NewString,RepCount}</c></tag>
<item>
@@ -286,7 +286,7 @@
<item>
<p>matches the non-metacharacter <c>c</c>.</p>
</item>
- <tag>\\c</tag>
+ <tag>\c</tag>
<item>
<p>matches the escape sequence or literal character <c>c</c>.</p>
</item>
@@ -341,74 +341,74 @@
<p>The escape sequences allowed are the same as for Erlang
strings:</p>
<taglist>
- <tag><c>\\b</c></tag>
+ <tag><c>\b</c></tag>
<item>
<p>backspace</p>
</item>
- <tag><c>\\f</c></tag>
+ <tag><c>\f</c></tag>
<item>
<p>form feed </p>
</item>
- <tag><c>\</c></tag>
+ <tag><c>\n</c></tag>
<item>
<p>newline (line feed) </p>
</item>
- <tag><c>\\r</c></tag>
+ <tag><c>\r</c></tag>
<item>
<p>carriage return </p>
</item>
- <tag><c>\\t</c></tag>
+ <tag><c>\t</c></tag>
<item>
<p>tab </p>
</item>
- <tag><c>\\e</c></tag>
+ <tag><c>\e</c></tag>
<item>
<p>escape </p>
</item>
- <tag><c>\\v</c></tag>
+ <tag><c>\v</c></tag>
<item>
<p>vertical tab </p>
</item>
- <tag><c>\\s</c></tag>
+ <tag><c>\s</c></tag>
<item>
<p>space </p>
</item>
- <tag><c>\\d</c></tag>
+ <tag><c>\d</c></tag>
<item>
<p>delete </p>
</item>
- <tag><c>\\ddd</c></tag>
+ <tag><c>\ddd</c></tag>
<item>
<p>the octal value ddd </p>
</item>
- <tag><c>\\xhh</c></tag>
+ <tag><c>\xhh</c></tag>
<item>
<p>The hexadecimal value <c>hh</c>.</p>
</item>
- <tag><c>\\x{h...}</c></tag>
+ <tag><c>\x{h...}</c></tag>
<item>
<p>The hexadecimal value <c>h...</c>.</p>
</item>
- <tag><c>\\c</c></tag>
+ <tag><c>\c</c></tag>
<item>
- <p>any other character literally, for example <c>\\\\</c> for backslash,
- <c>\\"</c> for ")</p>
+ <p>any other character literally, for example <c>\\</c> for backslash,
+ <c>\"</c> for ")</p>
</item>
</taglist>
<p>To make these functions easier to use, in combination with the
function <c>io:get_line</c> which terminates the input line with
a new line, the <c>$</c> characters also matches a string ending
- with <c>"...\ "</c>. The following examples
+ with <c>"...\n"</c>. The following examples
define Erlang data types:</p>
<pre>
Atoms [a-z][0-9a-zA-Z_]*
Variables [A-Z_][0-9a-zA-Z_]*
-Floats (\\+|-)?[0-9]+\\.[0-9]+((E|e)(\\+|-)?[0-9]+)?</pre>
- <p>Regular expressions are written as Erlang strings when used with the functions in this module. This means that any <c>\\</c> or <c>"</c> characters in a regular expression
- string must be written with <c>\\</c> as they are also escape characters for the string. For example, the regular expression string for Erlang floats is:
- <c>"(\\\\+|-)?[0-9]+\\\\.[0-9]+((E|e)(\\\\+|-)?[0-9]+)?"</c>.</p>
+Floats (\+|-)?[0-9]+\.[0-9]+((E|e)(\+|-)?[0-9]+)?</pre>
+ <p>Regular expressions are written as Erlang strings when used with the functions in this module. This means that any <c>\</c> or <c>"</c> characters in a regular expression
+ string must be written with <c>\</c> as they are also escape characters for the string. For example, the regular expression string for Erlang floats is:
+ <c>"(\\+|-)?[0-9]+\\.[0-9]+((E|e)(\\+|-)?[0-9]+)?"</c>.</p>
<p>It is not really necessary to have the escape sequences as part of the regular expression syntax as they can always be generated directly in the string. They are included for completeness and can they can also be useful when generating regular expressions, or when they are entered other than with Erlang strings.</p>
</section>
</erlref>
diff --git a/lib/stdlib/doc/src/shell.xml b/lib/stdlib/doc/src/shell.xml
index 24b845fee9..73cc1b33bd 100644
--- a/lib/stdlib/doc/src/shell.xml
+++ b/lib/stdlib/doc/src/shell.xml
@@ -4,7 +4,7 @@
<erlref>
<header>
<copyright>
- <year>1996</year><year>2009</year>
+ <year>1996</year><year>2010</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
@@ -13,12 +13,12 @@
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>shell</title>
@@ -333,10 +333,12 @@ undefined
&lt;0.57.0>
27> <input>get(aa).</input>
hello
-28> <input>io:format("hello hello\ ").</input>
-hello hello ok
+28> <input>io:format("hello hello\n").</input>
+hello hello
+ok
29> <input>e(28).</input>
-hello hello ok
+hello hello
+ok
30> <input>v(28).</input>
ok
31> <input>c(ex).</input>
@@ -737,6 +739,28 @@ loop(N) ->
returns <c>{error,Reason}</c>.</item>
</list>
</section>
+
+ <section>
+ <title>Prompting</title>
+ <p>The default shell prompt function displays the name of the node
+ (if the node can be part of a distributed system) and the
+ current command number. The user can customize the prompt
+ function by calling
+ <c>shell:prompt_func/1</c> or by setting the application
+ configuration parameter <c>shell_prompt_func</c> for the
+ application STDLIB.</p>
+ <p>A customized prompt function is stated as a tuple
+ <c>{Mod,&nbsp;Func}</c>. The function is called as
+ <c>Mod:Func(L)</c>, where <c>L</c> is a list of key-value pairs
+ created by the shell. Currently there is only one pair:
+ <c>{history, N}</c>, where N is the current command number. The
+ function should return a list of characters or an atom. This
+ constraint is due to the Erlang I/O-protocol. Unicode characters
+ beyond codepoint 255 are allowed in the list. Note
+ that in restricted mode the call <c>Mod:Func(L)</c> must be
+ allowed or the default shell prompt function will be called.</p>
+ </section>
+
<funcs>
<func>
<name>history(N) -> integer()</name>
@@ -780,6 +804,19 @@ loop(N) ->
</desc>
</func>
<func>
+ <name>prompt_func(PromptFunc) -> prompt_func()</name>
+ <fsummary>Sets the shell prompt</fsummary>
+ <type>
+ <v>PromptFunc = prompt_func()</v>
+ <v>prompt_func() = default | {Mod, Func}</v>
+ <v>Mod = Func = atom()</v>
+ </type>
+ <desc>
+ <p>Sets the shell prompt function to <c>PromptFunc</c>. The
+ previous prompt function is returned.</p>
+ </desc>
+ </func>
+ <func>
<name>start_restricted(Module) -> ok | {error, Reason}</name>
<fsummary>Exits a normal shell and starts a restricted shell.</fsummary>
<type>
diff --git a/lib/stdlib/doc/src/sofs.xml b/lib/stdlib/doc/src/sofs.xml
index ac434ec5b7..8c8ae51262 100644
--- a/lib/stdlib/doc/src/sofs.xml
+++ b/lib/stdlib/doc/src/sofs.xml
@@ -4,7 +4,7 @@
<erlref>
<header>
<copyright>
- <year>2001</year><year>2009</year>
+ <year>2001</year><year>2010</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
@@ -13,12 +13,12 @@
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>sofs</title>
@@ -311,7 +311,7 @@
applying Fun to the type of the given set), and that Fun does
nothing but selecting, duplicating or rearranging parts of the
elements. Specifying a SetFun as an integer I is equivalent to
- specifying <c>{external, fun(X)&nbsp;-> element(I,&nbsp;X)}</c>,
+ specifying <c>{external, fun(X)&nbsp;-> element(I,&nbsp;X)&nbsp;end}</c>,
but is to be preferred since it makes it possible to handle this
case even more efficiently. Examples of SetFuns:</p>
<pre>
@@ -336,6 +336,7 @@ fun(S) -> sofs:partition(1, S) end
<c>badarg</c>, <c>bad_function</c>, or <c>type_mismatch</c>
message when given badly formed arguments or sets the types of
which are not compatible.</p>
+ <p>When comparing external sets the operator <c>==/2</c> is used.</p>
<p><em>Types</em></p>
<pre>
anyset() = -&nbsp;an unordered, ordered or atomic set&nbsp;-
@@ -1108,7 +1109,13 @@ type() = -&nbsp;a type&nbsp;- </pre>
<desc>
<p>Returns <c>true</c> if the AnySet1 and AnySet2
are <seealso marker="#equal">equal</seealso>, <c>false</c>
- otherwise.</p>
+ otherwise. This example shows that <c>==/2</c> is used when
+ comparing sets for equality:</p>
+ <pre>
+1> <input>S1 = sofs:set([1.0]),</input>
+<input>S2 = sofs:set([1]),</input>
+<input>sofs:is_equal(S1, S2).</input>
+true</pre>
</desc>
</func>
<func>
diff --git a/lib/stdlib/doc/src/stdlib_app.xml b/lib/stdlib/doc/src/stdlib_app.xml
index da046b8a8d..a615c1bf88 100644
--- a/lib/stdlib/doc/src/stdlib_app.xml
+++ b/lib/stdlib/doc/src/stdlib_app.xml
@@ -4,23 +4,21 @@
<appref>
<header>
<copyright>
- <year>2005</year>
- <year>2007</year>
- <holder>Ericsson AB, All Rights Reserved</holder>
+ <year>2005</year><year>2010</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/.
+ The 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.
+ 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>STDLIB</title>
@@ -63,6 +61,16 @@
<p>This parameter can be used to determine how many
commands are saved by the Erlang shell.</p>
</item>
+ <tag><c>shell_prompt_func = {Mod, Func} | default</c></tag>
+ <item>
+ <p>where</p>
+ <list type="bulleted">
+ <item><c>Mod = atom()</c></item>
+ <item><c>Func = atom()</c></item>
+ </list>
+ <p>This parameter can be used to set a customized
+ Erlang shell prompt function.</p>
+ </item>
<tag><c>shell_saved_results = integer() >= 0</c></tag>
<item>
<p>This parameter can be used to determine how many
diff --git a/lib/stdlib/doc/src/string.xml b/lib/stdlib/doc/src/string.xml
index 7ee38e496d..de1b99a2d5 100644
--- a/lib/stdlib/doc/src/string.xml
+++ b/lib/stdlib/doc/src/string.xml
@@ -117,9 +117,9 @@
from) Chars.</p>
<p>For example:</p>
<code type="none">
-> string:span("\\t abcdef", " \\t").
+> string:span("\t abcdef", " \t").
5
-> string:cspan("\\t abcdef", " \\t").
+> string:cspan("\t abcdef", " \t").
0 </code>
</desc>
</func>
diff --git a/lib/stdlib/doc/src/supervisor.xml b/lib/stdlib/doc/src/supervisor.xml
index adf9d24eae..c696434d49 100644
--- a/lib/stdlib/doc/src/supervisor.xml
+++ b/lib/stdlib/doc/src/supervisor.xml
@@ -4,7 +4,7 @@
<erlref>
<header>
<copyright>
- <year>1996</year><year>2009</year>
+ <year>1996</year><year>2010</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
@@ -13,12 +13,12 @@
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>supervisor</title>
@@ -402,9 +402,12 @@ child_spec() = {Id,StartFunc,Restart,Shutdown,Type,Modules}
<v>&nbsp;Module = atom()</v>
</type>
<desc>
- <p>Returns a list with information about all child
+ <p>Returns a newly created list with information about all child
specifications and child processes belonging to
the supervisor <c>SupRef</c>.</p>
+ <p>Note that calling this function when supervising a large
+ number of children under low memory conditions can cause an
+ out of memory exception.</p>
<p>See <c>start_child/2</c> for a description of <c>SupRef</c>.</p>
<p>The information given for each child specification/process
is:</p>
@@ -428,6 +431,39 @@ child_spec() = {Id,StartFunc,Restart,Shutdown,Type,Modules}
</desc>
</func>
<func>
+ <name>count_children(SupRef) -> PropListOfCounts</name>
+ <fsummary>Return counts for the number of childspecs, active children, supervisors and workers.</fsummary>
+ <type>
+ <v>SupRef = Name | {Name,Node} | {global,Name} | pid()</v>
+ <v>&nbsp;Name = Node = atom()</v>
+ <v>PropListOfCounts = [{specs, ChildSpecCount}, {active, ActiveProcessCount}, {supervisors, ChildSupervisorCount}, {workers, ChildWorkerCount}]</v>
+ </type>
+ <desc>
+ <p>Returns a property list (see <c>proplists</c>) containing the
+ counts for each of the following elements of the supervisor's
+ child specifications and managed processes:</p>
+ <list type="bulleted">
+ <item>
+ <p><c>specs</c> - the total count of children, dead or alive.</p>
+ </item>
+ <item>
+ <p><c>active</c> - the count of all actively running child processes
+ managed by this supervisor.</p>
+ </item>
+ <item>
+ <p><c>supervisors</c> - the count of all children marked as
+ child_type = supervisor in the spec list, whether or not the
+ child process is still alive.</p>
+ </item>
+ <item>
+ <p><c>workers</c> - the count of all children marked as
+ child_type = worker in the spec list, whether or not the child
+ process is still alive.</p>
+ </item>
+ </list>
+ </desc>
+ </func>
+ <func>
<name>check_childspecs([ChildSpec]) -> Result</name>
<fsummary>Check if children specifications are syntactically correct.</fsummary>
<type>
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/doc/src/unicode.xml b/lib/stdlib/doc/src/unicode.xml
index b3aad51591..60edd8ade9 100644
--- a/lib/stdlib/doc/src/unicode.xml
+++ b/lib/stdlib/doc/src/unicode.xml
@@ -51,7 +51,9 @@ charlist() = [unicode_char() | unicode_binary() | charlist()]
a unicode_binary is allowed as the tail of the list</code>
<code type="none">
-external_unicode_binary() = binary() with characters coded in a user specified Unicode encoding other than UTF-8 (UTF-16 or UTF-32)
+external_unicode_binary() = binary()
+ with characters coded in a user specified Unicode encoding other
+ than UTF-8 (UTF-16 or UTF-32)
external_chardata() = external_charlist() | external_unicode_binary()
diff --git a/lib/stdlib/doc/src/unicode_usage.xml b/lib/stdlib/doc/src/unicode_usage.xml
index 06347b3aae..c5bf10b63d 100644
--- a/lib/stdlib/doc/src/unicode_usage.xml
+++ b/lib/stdlib/doc/src/unicode_usage.xml
@@ -76,7 +76,8 @@ charlist() = [unicode_char() | unicode_binary() | charlist()]
a unicode_binary is allowed as the tail of the list</code>
<p>The module <c>unicode</c> in stdlib even supports similar mixes with binaries containing other encodings than UTF-8, but that is a special case to allow for conversions to and from external data:</p>
<code type="none">
-external_unicode_binary() = binary() with characters coded in a user specified Unicode encoding other than UTF-8 (UTF-16 or UTF-32)
+external_unicode_binary() = binary() with characters coded in a user specified Unicode
+ encoding other than UTF-8 (UTF-16 or UTF-32)
external_chardata() = external_charlist() | external_unicode_binary()
@@ -93,7 +94,8 @@ external_charlist() = [unicode_char() | external_unicode_binary() | external_cha
<code>
&lt;&lt;Ch/utf8,_/binary&gt;&gt; = Bin1,
&lt;&lt;Ch/utf16-little,_/binary&gt;&gt; = Bin2,
-Bin3 = &lt;&lt;$H/utf32-little, $e/utf32-little, $l/utf32-little, $l/utf32-little, $o/utf32-little&gt;&gt;,</code>
+Bin3 = &lt;&lt;$H/utf32-little, $e/utf32-little, $l/utf32-little, $l/utf32-little,
+ $o/utf32-little&gt;&gt;,</code>
<p>For convenience, literal strings can be encoded with a Unicode encoding in binaries using the following (or similar) syntax:</p>
<code>
Bin4 = &lt;&lt;"Hello"/utf16&gt;&gt;,</code>
diff --git a/lib/stdlib/doc/src/win32reg.xml b/lib/stdlib/doc/src/win32reg.xml
index d8055047b0..28960cd098 100644
--- a/lib/stdlib/doc/src/win32reg.xml
+++ b/lib/stdlib/doc/src/win32reg.xml
@@ -48,7 +48,7 @@
<p>Paths to keys are left to right, with sub-keys to the right and backslash
between keys. (Remember that backslashes must be doubled in Erlang strings.)
Case is preserved but not significant.
- Example: <c>"\\\\hkey_local_machine\\\\software\\\\Ericsson\\\\Erlang\\\\5.0"</c> is the key
+ Example: <c>"\\hkey_local_machine\\software\\Ericsson\\Erlang\\5.0"</c> is the key
for the installation data for the latest Erlang release.</p>
<p>There are six entry points in the Windows registry, top level keys. They can be
abbreviated in the <c>win32reg</c> module as:</p>
@@ -66,7 +66,7 @@ current_config HKEY_CURRENT_CONFIG
hkcc HKEY_CURRENT_CONFIG
dyn_data HKEY_DYN_DATA
hkdd HKEY_DYN_DATA</pre>
- <p>The key above could be written as <c>"\\\\hklm\\\\software\\\\ericsson\\\\erlang\\\\5.0"</c>.</p>
+ <p>The key above could be written as <c>"\\hklm\\software\\ericsson\\erlang\\5.0"</c>.</p>
<p>The <c>win32reg</c> module uses a current key. It works much like the
current directory. From the current key, values can be fetched, sub-keys
can be listed, and so on.</p>
@@ -96,7 +96,7 @@ hkdd HKEY_DYN_DATA</pre>
<desc>
<p>Changes the current key to another key. Works like cd.
The key can be specified as a relative path or as an
- absolute path, starting with \\.</p>
+ absolute path, starting with \.</p>
</desc>
</func>
<func>
diff --git a/lib/stdlib/src/Makefile b/lib/stdlib/src/Makefile
index 68708d6b02..237818c08b 100644
--- a/lib/stdlib/src/Makefile
+++ b/lib/stdlib/src/Makefile
@@ -1,19 +1,19 @@
#
# %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
# 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%
#
@@ -146,6 +146,9 @@ APPUP_TARGET= $(EBIN)/$(APPUP_FILE)
# FLAGS
# ----------------------------------------------------
+ifeq ($(NATIVE_LIBS_ENABLED),yes)
+ERL_COMPILE_FLAGS += +native
+endif
ERL_COMPILE_FLAGS += -I../include -I../../kernel/include
# ----------------------------------------------------
@@ -173,8 +176,8 @@ $(BOOTSTRAP_COMPILER)/ebin/erl_parse.beam: erl_parse.yrl
$(ERLC) -o $(BOOTSTRAP_COMPILER)/egen erl_parse.yrl
$(ERLC) -o $(BOOTSTRAP_COMPILER)/ebin $(BOOTSTRAP_COMPILER)/egen/erl_parse.erl
-#$(BOOTSTRAP_COMPILER)/ebin/erl_lint.beam: erl_lint.erl
-# $(ERLC) -o $(BOOTSTRAP_COMPILER)/ebin erl_lint.erl
+$(BOOTSTRAP_TOP)/lib/stdlib/egen/erl_parse.erl: erl_parse.yrl
+ $(ERLC) $(YRL_FLAGS) -o$(BOOTSTRAP_TOP)/lib/stdlib/egen erl_parse.yrl
$(BOOTSTRAP_COMPILER)/ebin/%.beam: %.erl
$(ERLC) -o $(BOOTSTRAP_COMPILER)/ebin $<
diff --git a/lib/stdlib/src/array.erl b/lib/stdlib/src/array.erl
index 295eeac221..83576c9fd3 100644
--- a/lib/stdlib/src/array.erl
+++ b/lib/stdlib/src/array.erl
@@ -741,11 +741,17 @@ set_get_test_() ->
?_assert(array:get(0, set(0, 42, set(0, 17, new()))) =:= 42),
- ?_assert(array:get(0, reset(0, new())) =:= undefined),
- ?_assert(array:get(0, reset(0, set(0, 17, new()))) =:= undefined),
- ?_assert(array:get(0, reset(0, new({default,42}))) =:= 42),
- ?_assert(array:get(0, reset(0, set(0, 17, new({default,42}))))
- =:= 42)
+ ?_assertError(badarg, array:get(0, reset(11, new([{size,10}])))),
+ ?_assertError(badarg, array:get(0, reset(-1, new([{size,10}])))),
+ ?_assert(array:get(0, reset(0, new())) =:= undefined),
+ ?_assert(array:get(0, reset(0, set(0, 17, new()))) =:= undefined),
+ ?_assert(array:get(0, reset(9, set(9, 17, new()))) =:= undefined),
+ ?_assert(array:get(0, reset(11, set(11, 17, new()))) =:= undefined),
+ ?_assert(array:get(0, reset(11, set(12, 17, new()))) =:= undefined),
+ ?_assert(array:get(0, reset(1, set(12, 17, new()))) =:= undefined),
+ ?_assert(array:get(0, reset(11, new())) =:= undefined),
+ ?_assert(array:get(0, reset(0, set(0, 17, new({default,42})))) =:= 42),
+ ?_assert(array:get(0, reset(0, new({default,42}))) =:= 42)
].
-endif.
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/dets_v8.erl b/lib/stdlib/src/dets_v8.erl
index b24df02882..1f9f84cd27 100644
--- a/lib/stdlib/src/dets_v8.erl
+++ b/lib/stdlib/src/dets_v8.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2001-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 2001-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(dets_v8).
@@ -1053,14 +1053,14 @@ wl([{_Seq, {insert, Object}} | Cs], Type, _Del, Lookup, _I, _Objs)
wl(Cs, Type, delete, Lookup, 1, [{Object,-1}]);
wl([{_Seq, {insert, Object}} | Cs], Type, Del, Lookup, _I, Objs) ->
NObjs =
- case lists:keysearch(Object, 1, Objs) of
- {value, {_, 0}} ->
+ case lists:keyfind(Object, 1, Objs) of
+ {_, 0} ->
lists:keyreplace(Object, 1, Objs, {Object,-1});
- {value, {_, _C}} when Type =:= bag -> % C =:= 1; C =:= -1
+ {_, _C} when Type =:= bag -> % C =:= 1; C =:= -1
Objs;
- {value, {_, C}} when C < 0 -> % when Type =:= duplicate_bag
+ {_, C} when C < 0 -> % when Type =:= duplicate_bag
lists:keyreplace(Object, 1, Objs, {Object,C-1});
- {value, {_, C}} -> % when C > 0, Type =:= duplicate_bag
+ {_, C} -> % when C > 0, Type =:= duplicate_bag
lists:keyreplace(Object, 1, Objs, {Object,C+1});
false when Del =:= delete ->
[{Object, -1} | Objs];
@@ -1258,8 +1258,8 @@ eval_slot(Head, TrySize, Pos, WLs, L, LU) ->
find_key(Head, Pos, NextPos, Size, Term, Key, WLs, L, LU).
find_key(Head, Pos, NextPos, Size, Term, Key, WLs, L, LU) ->
- case lists:keysearch(Key, 1, WLs) of
- {value, {_, {Delete, LookUp, Objects}} = WL} ->
+ case lists:keyfind(Key, 1, WLs) of
+ {_, {Delete, LookUp, Objects}} = WL ->
NWLs = lists:delete(WL, WLs),
{NewObjects, NL, LUK} = eval_object(Size, Term, Delete, LookUp,
Objects, Head, Pos, L, []),
@@ -1297,30 +1297,30 @@ eval_key(Key, Delete, LookUp, Objects, Head, Pos, WLs, L, LU, LUK) ->
%% All objects in Objects have the key Key.
eval_object(Size, Term, Delete, LookUp, Objects, Head, Pos, L, LU) ->
Type = Head#head.type,
- case lists:keysearch(Term, 1, Objects) of
- {value, {_Object, N}} when N =:= 0 ->
+ case lists:keyfind(Term, 1, Objects) of
+ {_Object, N} when N =:= 0 ->
L1 = [{delete,Pos,Size} | L],
{Objects, L1, LU};
- {value, {_Object, N}} when N < 0, Type =:= set ->
+ {_Object, N} when N < 0, Type =:= set ->
L1 = [{old,Pos} | L],
wl_lookup(LookUp, Objects, Term, L1, LU);
- {value, {Object, _N}} when Type =:= bag -> % when N =:= 1; N =:= -1
+ {Object, _N} when Type =:= bag -> % when N =:= 1; N =:= -1
L1 = [{old,Pos} | L],
Objects1 = lists:keydelete(Object, 1, Objects),
wl_lookup(LookUp, Objects1, Term, L1, LU);
- {value, {Object, N}} when N < 0, Type =:= duplicate_bag ->
+ {Object, N} when N < 0, Type =:= duplicate_bag ->
L1 = [{old,Pos} | L],
Objects1 = lists:keyreplace(Object, 1, Objects, {Object,N+1}),
wl_lookup(LookUp, Objects1, Term, L1, LU);
- {value, {_Object, N}} when N > 0, Type =:= duplicate_bag ->
+ {_Object, N} when N > 0, Type =:= duplicate_bag ->
L1 = [{old,Pos} | L],
wl_lookup(LookUp, Objects, Term, L1, LU);
false when Type =:= set, Delete =:= delete ->
- case lists:keysearch(-1, 2, Objects) of
+ case lists:keyfind(-1, 2, Objects) of
false -> % no inserted object, perhaps deleted objects
L1 = [{delete,Pos,Size} | L],
{[], L1, LU};
- {value, {Term2,-1}} ->
+ {Term2, -1} ->
Bin2 = term_to_binary(Term2),
NSize = byte_size(Bin2),
Overwrite =
diff --git a/lib/stdlib/src/edlin.erl b/lib/stdlib/src/edlin.erl
index 31a653bda0..6cb441dbed 100644
--- a/lib/stdlib/src/edlin.erl
+++ b/lib/stdlib/src/edlin.erl
@@ -1,19 +1,19 @@
%%
%% %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
%% 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(edlin).
@@ -30,8 +30,6 @@
-import(lists, [reverse/1, reverse/2]).
-%-import([nthtail/2, keysearch/3, prefix/2]).
-
-export([over_word/3]).
@@ -281,12 +279,32 @@ do_op(_, Bef, Aft, Rs) ->
%% Step over word/non-word characters pushing the stepped over ones on
%% the stack.
-over_word([C|Cs], Stack, N) ->
+
+over_word(Cs, Stack, N) ->
+ L = length([1 || $\' <- Cs]),
+ case L rem 2 of
+ 0 ->
+ over_word1(Cs, Stack, N);
+ 1 ->
+ until_quote(Cs, Stack, N)
+ end.
+
+until_quote([$\'|Cs], Stack, N) ->
+ {Cs, [$\'|Stack], N+1};
+until_quote([C|Cs], Stack, N) ->
+ until_quote(Cs, [C|Stack], N+1).
+
+over_word1([$\'=C|Cs], Stack, N) ->
+ until_quote(Cs, [C|Stack], N+1);
+over_word1(Cs, Stack, N) ->
+ over_word2(Cs, Stack, N).
+
+over_word2([C|Cs], Stack, N) ->
case word_char(C) of
- true -> over_word(Cs, [C|Stack], N+1);
+ true -> over_word2(Cs, [C|Stack], N+1);
false -> {[C|Cs],Stack,N}
end;
-over_word([], Stack, N) when is_integer(N) ->
+over_word2([], Stack, N) when is_integer(N) ->
{[],Stack,N}.
over_non_word([C|Cs], Stack, N) ->
@@ -456,8 +474,8 @@ prompt({line,Pbs,_,_}) ->
%% case erlang:module_loaded(Mod) of
%% true ->
%% L = apply(Mod, module_info, []),
-%% case keysearch(exports, 1, L) of
-%% {value, {_, Exports}} ->
+%% case lists:keyfind(exports, 1, L) of
+%% {_, Exports} ->
%% match(FuncPrefix, Exports, "(");
%% _ ->
%% no
@@ -473,7 +491,7 @@ prompt({line,Pbs,_,_}) ->
%% print_matches(Matches),
%% no;
%% {partial, Str} ->
-%% case nthtail(length(Prefix), Str) of
+%% case lists:nthtail(length(Prefix), Str) of
%% [] ->
%% print_matches(Matches),
%% {yes, []};
@@ -481,7 +499,7 @@ prompt({line,Pbs,_,_}) ->
%% {yes, Remain}
%% end;
%% {complete, Str} ->
-%% {yes, nthtail(length(Prefix), Str) ++ Extra};
+%% {yes, lists:nthtail(length(Prefix), Str) ++ Extra};
%% no ->
%% no
%% end.
diff --git a/lib/stdlib/src/edlin_expand.erl b/lib/stdlib/src/edlin_expand.erl
index 7ed76a6b09..516c0aa30b 100644
--- a/lib/stdlib/src/edlin_expand.erl
+++ b/lib/stdlib/src/edlin_expand.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2005-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 2005-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(edlin_expand).
@@ -46,23 +46,38 @@ expand_module_name(Prefix) ->
match(Prefix, code:all_loaded(), ":").
expand_function_name(ModStr, FuncPrefix) ->
- Mod = list_to_atom(ModStr),
- case erlang:module_loaded(Mod) of
- true ->
- L = Mod:module_info(),
- case lists:keyfind(exports, 1, L) of
- {_, Exports} ->
- match(FuncPrefix, Exports, "(");
- _ ->
- {no, [], []}
- end;
- false ->
+ case to_atom(ModStr) of
+ {ok, Mod} ->
+ case erlang:module_loaded(Mod) of
+ true ->
+ L = Mod:module_info(),
+ case lists:keyfind(exports, 1, L) of
+ {_, Exports} ->
+ match(FuncPrefix, Exports, "(");
+ _ ->
+ {no, [], []}
+ end;
+ false ->
+ {no, [], []}
+ end;
+ error ->
{no, [], []}
end.
+%% if it's a quoted atom, atom_to_list/1 will do the wrong thing.
+to_atom(Str) ->
+ case erl_scan:string(Str) of
+ {ok, [{atom,_,A}], _} ->
+ {ok, A};
+ _ ->
+ error
+ end.
+
match(Prefix, Alts, Extra) ->
Len = length(Prefix),
- Matches = [{S, A} || {H, A} <- Alts, prefix(Prefix, S=atom_to_list(H))],
+ Matches = lists:sort(
+ [{S, A} || {H, A} <- Alts,
+ prefix(Prefix, S=hd(io_lib:fwrite("~w",[H])))]),
case longest_common_head([N || {N, _} <- Matches]) of
{partial, []} ->
{no, [], Matches}; % format_matches(Matches)};
diff --git a/lib/stdlib/src/epp.erl b/lib/stdlib/src/epp.erl
index 8b702c005b..424aed3d2e 100644
--- a/lib/stdlib/src/epp.erl
+++ b/lib/stdlib/src/epp.erl
@@ -1,19 +1,19 @@
%%
%% %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
%% 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(epp).
@@ -111,18 +111,24 @@ format_error({bad,W}) ->
io_lib:format("badly formed '~s'", [W]);
format_error({call,What}) ->
io_lib:format("illegal macro call '~s'",[What]);
-format_error({undefined,M}) ->
- io_lib:format("undefined macro '~w'", [M]);
+format_error({undefined,M,none}) ->
+ io_lib:format("undefined macro '~s'", [M]);
+format_error({undefined,M,A}) ->
+ io_lib:format("undefined macro '~s/~p'", [M,A]);
format_error({depth,What}) ->
io_lib:format("~s too deep",[What]);
format_error({mismatch,M}) ->
- io_lib:format("argument mismatch for macro '~w'", [M]);
+ io_lib:format("argument mismatch for macro '~s'", [M]);
format_error({arg_error,M}) ->
- io_lib:format("badly formed argument for macro '~w'", [M]);
+ io_lib:format("badly formed argument for macro '~s'", [M]);
format_error({redefine,M}) ->
- io_lib:format("redefining macro '~w'", [M]);
-format_error({circular,M}) ->
- io_lib:format("circular macro '~w'", [M]);
+ io_lib:format("redefining macro '~s'", [M]);
+format_error({redefine_predef,M}) ->
+ io_lib:format("redefining predefined macro '~s'", [M]);
+format_error({circular,M,none}) ->
+ io_lib:format("circular macro '~s'", [M]);
+format_error({circular,M,A}) ->
+ io_lib:format("circular macro '~s/~p'", [M,A]);
format_error({include,W,F}) ->
io_lib:format("can't find include ~s \"~s\"", [W,F]);
format_error({illegal,How,What}) ->
@@ -258,18 +264,23 @@ user_predef([{M,Val,redefine}|Pdm], Ms) when is_atom(M) ->
user_predef(Pdm, dict:store({atom,M}, {none,Exp}, Ms));
user_predef([{M,Val}|Pdm], Ms) when is_atom(M) ->
case dict:find({atom,M}, Ms) of
- {ok,_Def} ->
+ {ok,_Defs} when is_list(_Defs) -> %% User defined macros
{error,{redefine,M}};
+ {ok,_Def} -> %% Predefined macros
+ {error,{redefine_predef,M}};
error ->
Exp = erl_parse:tokens(erl_parse:abstract(Val)),
- user_predef(Pdm, dict:store({atom,M}, {none,Exp}, Ms))
+ user_predef(Pdm, dict:store({atom,M}, [{none, {none,Exp}}], Ms))
end;
user_predef([M|Pdm], Ms) when is_atom(M) ->
case dict:find({atom,M}, Ms) of
- {ok,_Def} ->
+ {ok,_Defs} when is_list(_Defs) -> %% User defined macros
{error,{redefine,M}};
+ {ok,_Def} -> %% Predefined macros
+ {error,{redefine_predef,M}};
error ->
- user_predef(Pdm, dict:store({atom,M}, {none,[{atom,1,true}]}, Ms))
+ user_predef(Pdm,
+ dict:store({atom,M}, [{none, {none,[{atom,1,true}]}}], Ms))
end;
user_predef([Md|_Pdm], _Ms) -> {error,{bad,Md}};
user_predef([], Ms) -> {ok,Ms}.
@@ -476,57 +487,56 @@ scan_extends(_Ts, _As, Ms) -> Ms.
%% scan_define(Tokens, DefineToken, From, EppState)
-scan_define([{'(',_Lp},{atom,_Lm,M}=Mac,{',',_Lc}|Toks], _Def, From, St) ->
+scan_define([{'(',_Lp},{Type,_Lm,M}=Mac,{',',_Lc}|Toks], _Def, From, St)
+ when Type =:= atom; Type =:= var ->
case dict:find({atom,M}, St#epp.macs) of
- {ok,_OldDef} ->
- epp_reply(From, {error,{loc(Mac),epp,{redefine,M}}}),
- wait_req_scan(St);
- error ->
- scan_define_cont(From, St,
- {atom, M},
- {none,macro_expansion(Toks)})
- end;
-scan_define([{'(',_Lp},{atom,_Lm,M}=Mac,{'(',_Lc}|Toks], Def, From, St) ->
- case dict:find({atom,M}, St#epp.macs) of
- {ok,_Def} ->
- epp_reply(From, {error,{loc(Mac),epp,{redefine,M}}}),
- wait_req_scan(St);
- error ->
- case catch macro_pars(Toks, []) of
- {ok, {As, Me}} ->
- scan_define_cont(From, St,
- {atom, M},
- {As, Me});
- _ ->
- epp_reply(From, {error,{loc(Def),epp,{bad,define}}}),
- wait_req_scan(St)
- end
- end;
-scan_define([{'(',_Lp},{var,_Lm,M}=Mac,{',',_Lc}|Toks], _Def, From, St) ->
- case dict:find({atom,M}, St#epp.macs) of
- {ok,_OldDef} ->
- epp_reply(From, {error,{loc(Mac),epp,{redefine,M}}}),
- wait_req_scan(St);
- error ->
- scan_define_cont(From, St,
- {atom, M},
- {none,macro_expansion(Toks)})
+ {ok, Defs} when is_list(Defs) ->
+ %% User defined macros: can be overloaded
+ case proplists:is_defined(none, Defs) of
+ true ->
+ epp_reply(From, {error,{loc(Mac),epp,{redefine,M}}}),
+ wait_req_scan(St);
+ false ->
+ scan_define_cont(From, St,
+ {atom, M},
+ {none, {none,macro_expansion(Toks)}})
+ end;
+ {ok, _PreDef} ->
+ %% Predefined macros: cannot be overloaded
+ epp_reply(From, {error,{loc(Mac),epp,{redefine_predef,M}}}),
+ wait_req_scan(St);
+ error ->
+ scan_define_cont(From, St,
+ {atom, M},
+ {none, {none,macro_expansion(Toks)}})
end;
-scan_define([{'(',_Lp},{var,_Lm,M}=Mac,{'(',_Lc}|Toks], Def, From, St) ->
- case dict:find({atom,M}, St#epp.macs) of
- {ok,_Def} ->
- epp_reply(From, {error,{loc(Mac),epp,{redefine,M}}}),
- wait_req_scan(St);
- error ->
- case catch macro_pars(Toks, []) of
- {ok, {As, Me}} ->
- scan_define_cont(From, St,
- {atom, M},
- {As, Me});
- _ ->
- epp_reply(From, {error,{loc(Def),epp,{bad,define}}}),
- wait_req_scan(St)
- end
+scan_define([{'(',_Lp},{Type,_Lm,M}=Mac,{'(',_Lc}|Toks], Def, From, St)
+ when Type =:= atom; Type =:= var ->
+ case catch macro_pars(Toks, []) of
+ {ok, {As,Me}} ->
+ Len = length(As),
+ case dict:find({atom,M}, St#epp.macs) of
+ {ok, Defs} when is_list(Defs) ->
+ %% User defined macros: can be overloaded
+ case proplists:is_defined(Len, Defs) of
+ true ->
+ epp_reply(From,{error,{loc(Mac),epp,{redefine,M}}}),
+ wait_req_scan(St);
+ false ->
+ scan_define_cont(From, St, {atom, M},
+ {Len, {As, Me}})
+ end;
+ {ok, _PreDef} ->
+ %% Predefined macros: cannot be overloaded
+ %% (There are currently no predefined F(...) macros.)
+ epp_reply(From, {error,{loc(Mac),epp,{redefine_predef,M}}}),
+ wait_req_scan(St);
+ error ->
+ scan_define_cont(From, St, {atom, M}, {Len, {As, Me}})
+ end;
+ _ ->
+ epp_reply(From, {error,{loc(Def),epp,{bad,define}}}),
+ wait_req_scan(St)
end;
scan_define(_Toks, Def, From, St) ->
epp_reply(From, {error,{loc(Def),epp,{bad,define}}}),
@@ -541,13 +551,17 @@ scan_define(_Toks, Def, From, St) ->
%%% the information from St#epp.uses is traversed, and if a circularity
%%% is detected, an error message is thrown.
-scan_define_cont(F, St, M, Def) ->
- Ms = dict:store(M, Def, St#epp.macs),
- U = dict:store(M, macro_uses(Def), St#epp.uses),
- scan_toks(F, St#epp{uses=U, macs=Ms}).
+scan_define_cont(F, St, M, {Arity, Def}) ->
+ Ms = dict:append_list(M, [{Arity, Def}], St#epp.macs),
+ try dict:append_list(M, [{Arity, macro_uses(Def)}], St#epp.uses) of
+ U ->
+ scan_toks(F, St#epp{uses=U, macs=Ms})
+ catch
+ {error, Line, Reason} ->
+ epp_reply(F, {error,{Line,epp,Reason}}),
+ wait_req_scan(St)
+ end.
-macro_uses(undefined) ->
- undefined;
macro_uses({_Args, Tokens}) ->
Uses0 = macro_ref(Tokens),
lists:usort(Uses0).
@@ -556,31 +570,25 @@ macro_ref([]) ->
[];
macro_ref([{'?', _}, {'?', _} | Rest]) ->
macro_ref(Rest);
-macro_ref([{'?', _}, {atom, _, A} | Rest]) ->
- [{atom, A} | macro_ref(Rest)];
-macro_ref([{'?', _}, {var, _, A} | Rest]) ->
- [{atom, A} | macro_ref(Rest)];
+macro_ref([{'?', _}, {atom, Lm, A} | Rest]) ->
+ Arity = count_args(Rest, Lm, A),
+ [{{atom, A}, Arity} | macro_ref(Rest)];
+macro_ref([{'?', _}, {var, Lm, A} | Rest]) ->
+ Arity = count_args(Rest, Lm, A),
+ [{{atom, A}, Arity} | macro_ref(Rest)];
macro_ref([_Token | Rest]) ->
macro_ref(Rest).
-all_macro_uses(D0) ->
- L = dict:to_list(D0),
- D = dict:new(),
- add_macro_uses(L, D).
-
-add_macro_uses([], D) ->
- D;
-add_macro_uses([{Key, Def} | Rest], D0) ->
- add_macro_uses(Rest, dict:store(Key, macro_uses(Def), D0)).
-
%% scan_undef(Tokens, UndefToken, From, EppState)
scan_undef([{'(',_Llp},{atom,_Lm,M},{')',_Lrp},{dot,_Ld}], _Undef, From, St) ->
- scan_toks(From, St#epp{macs=dict:erase({atom,M}, St#epp.macs),
- uses=all_macro_uses(St#epp.macs)});
+ Macs = dict:erase({atom,M}, St#epp.macs),
+ Uses = dict:erase({atom,M}, St#epp.uses),
+ scan_toks(From, St#epp{macs=Macs, uses=Uses});
scan_undef([{'(',_Llp},{var,_Lm,M},{')',_Lrp},{dot,_Ld}], _Undef, From,St) ->
- scan_toks(From, St#epp{macs=dict:erase({atom,M}, St#epp.macs),
- uses=all_macro_uses(St#epp.macs)});
+ Macs = dict:erase({atom,M}, St#epp.macs),
+ Uses = dict:erase({atom,M}, St#epp.uses),
+ scan_toks(From, St#epp{macs=Macs, uses=Uses});
scan_undef(_Toks, Undef, From, St) ->
epp_reply(From, {error,{loc(Undef),epp,{bad,undef}}}),
wait_req_scan(St).
@@ -819,42 +827,57 @@ expand_macros(Type, MacT, M, Toks, Ms0) ->
%% (Type will always be 'atom')
{Ms, U} = Ms0,
Lm = loc(MacT),
- check_uses([{Type,M}], [], U, Lm),
Tinfo = element(2, MacT),
- case dict:find({Type,M}, Ms) of
+ case expand_macro1(Type, Lm, M, Toks, Ms) of
{ok,{none,Exp}} ->
- expand_macros(expand_macro(Exp, Tinfo, Toks, dict:new()), Ms0);
+ check_uses([{{Type,M}, none}], [], U, Lm),
+ Toks1 = expand_macros(expand_macro(Exp, Tinfo, [], dict:new()), Ms0),
+ expand_macros(Toks1++Toks, Ms0);
{ok,{As,Exp}} ->
+ check_uses([{{Type,M}, length(As)}], [], U, Lm),
{Bs,Toks1} = bind_args(Toks, Lm, M, As, dict:new()),
- %%io:format("Bound arguments to macro ~w (~w)~n", [M,Bs]),
- expand_macros(expand_macro(Exp, Tinfo, Toks1, Bs), Ms0);
- {ok,undefined} ->
- throw({error,Lm,{undefined,M}});
- error ->
- throw({error,Lm,{undefined,M}})
+ expand_macros(expand_macro(Exp, Tinfo, Toks1, Bs), Ms0)
+ end.
+
+expand_macro1(Type, Lm, M, Toks, Ms) ->
+ Arity = count_args(Toks, Lm, M),
+ case dict:find({Type,M}, Ms) of
+ error -> %% macro not found
+ throw({error,Lm,{undefined,M,Arity}});
+ {ok, undefined} -> %% Predefined macro without definition
+ throw({error,Lm,{undefined,M,Arity}});
+ {ok, [{none, Def}]} ->
+ {ok, Def};
+ {ok, Defs} when is_list(Defs) ->
+ case proplists:get_value(Arity, Defs) of
+ undefined ->
+ throw({error,Lm,{mismatch,M}});
+ Def ->
+ {ok, Def}
+ end;
+ {ok, PreDef} -> %% Predefined macro
+ {ok, PreDef}
end.
-check_uses(undefined, _Anc, _U, _Lm) ->
- ok;
check_uses([], _Anc, _U, _Lm) ->
ok;
check_uses([M|Rest], Anc, U, Lm) ->
case lists:member(M, Anc) of
true ->
- {_, Name} = M,
- throw({error,Lm,{circular,Name}});
+ {{_, Name},Arity} = M,
+ throw({error,Lm,{circular,Name,Arity}});
false ->
L = get_macro_uses(M, U),
check_uses(L, [M|Anc], U, Lm),
check_uses(Rest, Anc, U, Lm)
end.
-
-get_macro_uses(M, U) ->
+
+get_macro_uses({M,Arity}, U) ->
case dict:find(M, U) of
error ->
[];
{ok, L} ->
- L
+ proplists:get_value(Arity, L, proplists:get_value(none, L, []))
end.
%% Macro expansion
@@ -882,7 +905,7 @@ expand_macros([T|Ts], Ms) ->
expand_macros([], _Ms) -> [].
%% bind_args(Tokens, MacroLocation, MacroName, ArgumentVars, Bindings)
-%% Collect the arguments to a macro call and check for correct number.
+%% Collect the arguments to a macro call.
bind_args([{'(',_Llp},{')',_Lrp}|Toks], _Lm, _M, [], Bs) ->
{Bs,Toks};
@@ -890,7 +913,7 @@ bind_args([{'(',_Llp}|Toks0], Lm, M, [A|As], Bs) ->
{Arg,Toks1} = macro_arg(Toks0, [], []),
macro_args(Toks1, Lm, M, As, store_arg(Lm, M, A, Arg, Bs));
bind_args(_Toks, Lm, M, _As, _Bs) ->
- throw({error,Lm,{mismatch,M}}).
+ throw({error,Lm,{mismatch,M}}). % Cannot happen.
macro_args([{')',_Lrp}|Toks], _Lm, _M, [], Bs) ->
{Bs,Toks};
@@ -898,15 +921,39 @@ macro_args([{',',_Lc}|Toks0], Lm, M, [A|As], Bs) ->
{Arg,Toks1} = macro_arg(Toks0, [], []),
macro_args(Toks1, Lm, M, As, store_arg(Lm, M, A, Arg, Bs));
macro_args([], Lm, M, _As, _Bs) ->
- throw({error,Lm,{arg_error,M}});
+ throw({error,Lm,{arg_error,M}}); % Cannot happen.
macro_args(_Toks, Lm, M, _As, _Bs) ->
- throw({error,Lm,{mismatch,M}}).
+ throw({error,Lm,{mismatch,M}}). % Cannot happen.
store_arg(L, M, _A, [], _Bs) ->
throw({error,L,{mismatch,M}});
store_arg(_L, _M, A, Arg, Bs) ->
dict:store(A, Arg, Bs).
+%% count_args(Tokens, MacroLine, MacroName)
+%% Count the number of arguments in a macro call.
+count_args([{'(', _Llp},{')',_Lrp}|_Toks], _Lm, _M) ->
+ 0;
+count_args([{'(', _Llp},{',',_Lc}|_Toks], Lm, M) ->
+ throw({error,Lm,{arg_error,M}});
+count_args([{'(',_Llp}|Toks0], Lm, M) ->
+ {_Arg,Toks1} = macro_arg(Toks0, [], []),
+ count_args(Toks1, Lm, M, 1);
+count_args(_Toks, _Lm, _M) ->
+ none.
+
+count_args([{')',_Lrp}|_Toks], _Lm, _M, NbArgs) ->
+ NbArgs;
+count_args([{',',_Lc},{')',_Lrp}|_Toks], Lm, M, _NbArgs) ->
+ throw({error,Lm,{arg_error,M}});
+count_args([{',',_Lc}|Toks0], Lm, M, NbArgs) ->
+ {_Arg,Toks1} = macro_arg(Toks0, [], []),
+ count_args(Toks1, Lm, M, NbArgs+1);
+count_args([], Lm, M, _NbArgs) ->
+ throw({error,Lm,{arg_error,M}});
+count_args(_Toks, Lm, M, _NbArgs) ->
+ throw({error,Lm,{mismatch,M}}). % Cannot happen.
+
%% macro_arg([Tok], [ClosePar], [ArgTok]) -> {[ArgTok],[RestTok]}.
%% Collect argument tokens until we hit a ',' or a ')'. We know a
%% enough about syntax to recognise "open parentheses" and keep
diff --git a/lib/stdlib/src/erl_lint.erl b/lib/stdlib/src/erl_lint.erl
index 156d68554e..91f7641af7 100644
--- a/lib/stdlib/src/erl_lint.erl
+++ b/lib/stdlib/src/erl_lint.erl
@@ -1,20 +1,20 @@
%% -*- erlang-indent-level: 4 -*-
%%
%% %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
%% 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%
%%
%% Do necessary checking of Erlang code.
@@ -78,7 +78,7 @@ value_option(Flag, Default, On, OnVal, Off, OffVal, Opts) ->
calls = dict:new(), %Who calls who
imported = [], %Actually imported functions
used_records=sets:new() :: set(), %Used record definitions
- used_types = sets:new() :: set() %Used type definitions
+ used_types = dict:new() :: dict() %Used type definitions
}).
%% Define the lint state record.
@@ -277,6 +277,8 @@ format_error({conflicting_behaviours,{Name,Arity},B,FirstL,FirstB}) ->
format_error({undefined_behaviour_func, {Func,Arity}, Behaviour}) ->
io_lib:format("undefined callback function ~w/~w (behaviour '~w')",
[Func,Arity,Behaviour]);
+format_error({undefined_behaviour_func, {Func,Arity,_Spec}, Behaviour}) ->
+ format_error({undefined_behaviour_func, {Func,Arity}, Behaviour});
format_error({undefined_behaviour,Behaviour}) ->
io_lib:format("behaviour ~w undefined", [Behaviour]);
format_error({undefined_behaviour_callbacks,Behaviour}) ->
@@ -288,7 +290,7 @@ format_error({ill_defined_behaviour_callbacks,Behaviour}) ->
%% --- types and specs ---
format_error({singleton_typevar, Name}) ->
io_lib:format("type variable ~w is only used once (is unbound)", [Name]);
-format_error({type_ref, {TypeName, Arity}}) ->
+format_error({undefined_type, {TypeName, Arity}}) ->
io_lib:format("type ~w~s undefined", [TypeName, gen_type_paren(Arity)]);
format_error({unused_type, {TypeName, Arity}}) ->
io_lib:format("type ~w~s is unused", [TypeName, gen_type_paren(Arity)]);
@@ -757,10 +759,11 @@ post_traversal_check(Forms, St0) ->
St7 = check_bif_clashes(Forms, St6),
St8 = check_specs_without_function(St7),
St9 = check_functions_without_spec(Forms, St8),
- StA = check_unused_types(Forms, St9),
- StB = check_untyped_records(Forms, StA),
- StC = check_on_load(StB),
- check_unused_records(Forms, StC).
+ StA = check_undefined_types(St9),
+ StB = check_unused_types(Forms, StA),
+ StC = check_untyped_records(Forms, StB),
+ StD = check_on_load(StC),
+ check_unused_records(Forms, StD).
%% check_behaviour(State0) -> State
%% Check that the behaviour attribute is valid.
@@ -786,13 +789,20 @@ behaviour_callbacks(Line, B, St0) ->
Funcs when is_list(Funcs) ->
All = all(fun({FuncName, Arity}) ->
is_atom(FuncName) andalso is_integer(Arity);
+ ({FuncName, Arity, Spec}) ->
+ is_atom(FuncName) andalso is_integer(Arity)
+ andalso is_list(Spec);
(_Other) ->
false
end,
Funcs),
+ MaybeRemoveSpec = fun({_F,_A}=FA) -> FA;
+ ({F,A,_S}) -> {F,A};
+ (Other) -> Other
+ end,
if
All =:= true ->
- {Funcs, St0};
+ {[MaybeRemoveSpec(F) || F <- Funcs], St0};
true ->
St1 = add_warning(Line,
{ill_defined_behaviour_callbacks,B},
@@ -970,6 +980,16 @@ check_undefined_functions(#lint{called=Called0,defined=Def0}=St0) ->
add_error(L, {undefined_function,NA}, St)
end, St0, Undef).
+%% check_undefined_types(State0) -> State
+
+check_undefined_types(#lint{usage=Usage,types=Def}=St0) ->
+ Used = Usage#usage.used_types,
+ UTAs = dict:fetch_keys(Used),
+ Undef = [{TA,dict:fetch(TA, Used)} || TA <- UTAs, not dict:is_key(TA, Def)],
+ foldl(fun ({TA,L}, St) ->
+ add_error(L, {undefined_type,TA}, St)
+ end, St0, Undef).
+
%% check_bif_clashes(Forms, State0) -> State
check_bif_clashes(Forms, St0) ->
@@ -1427,20 +1447,11 @@ is_pattern_expr_1({tuple,_Line,Es}) ->
all(fun is_pattern_expr/1, Es);
is_pattern_expr_1({nil,_Line}) -> true;
is_pattern_expr_1({cons,_Line,H,T}) ->
- case is_pattern_expr_1(H) of
- true -> is_pattern_expr_1(T);
- false -> false
- end;
+ is_pattern_expr_1(H) andalso is_pattern_expr_1(T);
is_pattern_expr_1({op,_Line,Op,A}) ->
- case erl_internal:arith_op(Op, 1) of
- true -> is_pattern_expr_1(A);
- false -> false
- end;
+ erl_internal:arith_op(Op, 1) andalso is_pattern_expr_1(A);
is_pattern_expr_1({op,_Line,Op,A1,A2}) ->
- case erl_internal:arith_op(Op, 2) of
- true -> all(fun is_pattern_expr/1, [A1,A2]);
- false -> false
- end;
+ erl_internal:arith_op(Op, 2) andalso all(fun is_pattern_expr/1, [A1,A2]);
is_pattern_expr_1(_Other) -> false.
%% pattern_bin([Element], VarTable, Old, BinVarTable, State) ->
@@ -1817,28 +1828,17 @@ is_gexpr({bin,_L,Fs}, RDs) ->
end, Fs);
is_gexpr({call,_L,{atom,_Lf,F},As}, RDs) ->
A = length(As),
- case erl_internal:guard_bif(F, A) of
- true -> is_gexpr_list(As, RDs);
- false -> false
- end;
+ erl_internal:guard_bif(F, A) andalso is_gexpr_list(As, RDs);
is_gexpr({call,_L,{remote,_Lr,{atom,_Lm,erlang},{atom,_Lf,F}},As}, RDs) ->
A = length(As),
- case erl_internal:guard_bif(F, A) orelse is_gexpr_op(F, A) of
- true -> is_gexpr_list(As, RDs);
- false -> false
- end;
+ (erl_internal:guard_bif(F, A) orelse is_gexpr_op(F, A))
+ andalso is_gexpr_list(As, RDs);
is_gexpr({call,L,{tuple,Lt,[{atom,Lm,erlang},{atom,Lf,F}]},As}, RDs) ->
is_gexpr({call,L,{remote,Lt,{atom,Lm,erlang},{atom,Lf,F}},As}, RDs);
is_gexpr({op,_L,Op,A}, RDs) ->
- case is_gexpr_op(Op, 1) of
- true -> is_gexpr(A, RDs);
- false -> false
- end;
+ is_gexpr_op(Op, 1) andalso is_gexpr(A, RDs);
is_gexpr({op,_L,Op,A1,A2}, RDs) ->
- case is_gexpr_op(Op, 2) of
- true -> is_gexpr_list([A1,A2], RDs);
- false -> false
- end;
+ is_gexpr_op(Op, 2) andalso is_gexpr_list([A1,A2], RDs);
is_gexpr(_Other, _RDs) -> false.
is_gexpr_op('andalso', 2) -> true;
@@ -2388,7 +2388,7 @@ check_type(Types, St) ->
{SeenVars, St1} = check_type(Types, dict:new(), St),
dict:fold(fun(Var, {seen_once, Line}, AccSt) ->
case atom_to_list(Var) of
- [$_|_] -> AccSt;
+ "_"++_ -> AccSt;
_ -> add_error(Line, {singleton_typevar, Var}, AccSt)
end;
(_Var, seen_multiple, AccSt) ->
@@ -2400,7 +2400,7 @@ check_type({ann_type, _L, [_Var, Type]}, SeenVars, St) ->
check_type({paren_type, _L, [Type]}, SeenVars, St) ->
check_type(Type, SeenVars, St);
check_type({remote_type, L, [{atom, _, Mod}, {atom, _, Name}, Args]},
- SeenVars, St = #lint{module=CurrentMod}) ->
+ SeenVars, #lint{module=CurrentMod} = St) ->
St1 =
case (dict:is_key({Name, length(Args)}, default_types())
orelse is_var_arity_type(Name)) of
@@ -2463,21 +2463,15 @@ check_type({type, _L, product, Args}, SeenVars, St) ->
lists:foldl(fun(T, {AccSeenVars, AccSt}) ->
check_type(T, AccSeenVars, AccSt)
end, {SeenVars, St}, Args);
-check_type({type, La, TypeName, Args}, SeenVars,
- St = #lint{types=Defs, usage=Usage}) ->
+check_type({type, La, TypeName, Args}, SeenVars, #lint{usage=Usage} = St) ->
Arity = length(Args),
- St1 =
- case dict:is_key({TypeName, Arity}, Defs) of
- true ->
- UsedTypes1 = Usage#usage.used_types,
- UsedTypes2 = sets:add_element({TypeName, Arity}, UsedTypes1),
- St#lint{usage=Usage#usage{used_types=UsedTypes2}};
- false ->
- case is_var_arity_type(TypeName) of
- true -> St;
- false -> add_error(La, {type_ref, {TypeName, Arity}}, St)
- end
- end,
+ St1 = case is_var_arity_type(TypeName) of
+ true -> St;
+ false ->
+ OldUsed = Usage#usage.used_types,
+ UsedTypes = dict:store({TypeName, Arity}, La, OldUsed),
+ St#lint{usage=Usage#usage{used_types=UsedTypes}}
+ end,
check_type({type, -1, product, Args}, SeenVars, St1).
check_record_types(Line, Name, Fields, SeenVars, St) ->
@@ -2636,7 +2630,7 @@ check_specs([FunType|Left], Arity, St0) ->
check_specs([], _Arity, St) ->
St.
-check_specs_without_function(St = #lint{module=Mod, defined=Funcs}) ->
+check_specs_without_function(#lint{module=Mod,defined=Funcs,specs=Specs}=St) ->
Fun = fun({M, F, A} = MFA, Line, AccSt) when M =:= Mod ->
case gb_sets:is_element({F, A}, Funcs) of
true -> AccSt;
@@ -2644,7 +2638,7 @@ check_specs_without_function(St = #lint{module=Mod, defined=Funcs}) ->
end;
({_M, _F, _A}, _Line, AccSt) -> AccSt
end,
- dict:fold(Fun, St, St#lint.specs).
+ dict:fold(Fun, St, Specs).
%% This generates warnings for functions without specs; if the user has
%% specified both options, we do not generate the same warnings twice.
@@ -2688,7 +2682,7 @@ check_unused_types(Forms, St = #lint{usage=Usage, types=Types}) ->
(Type, FileLine, AccSt) ->
case loc(FileLine) of
{FirstFile, _} ->
- case sets:is_element(Type, UsedTypes) of
+ case dict:is_key(Type, UsedTypes) of
true -> AccSt;
false ->
add_warning(FileLine,
@@ -3009,7 +3003,7 @@ check_old_unused_vars(Vt, Vt0, St0) ->
unused_vars(Vt, Vt0, _St0) ->
U0 = orddict:filter(fun (V, {_State,unused,_Ls}) ->
case atom_to_list(V) of
- [$_|_] -> false;
+ "_"++_ -> false;
_ -> true
end;
(_V, _How) -> false
diff --git a/lib/stdlib/src/escript.erl b/lib/stdlib/src/escript.erl
index 697a69b801..5958a58d7c 100644
--- a/lib/stdlib/src/escript.erl
+++ b/lib/stdlib/src/escript.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2007-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 2007-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(escript).
@@ -63,7 +63,7 @@ script_name() ->
%% string()).
foldl(Fun, Acc0, File) when is_function(Fun, 4) ->
case parse_file(File, false) of
- {text, _, Forms, _Mode} when is_list(Forms) ->
+ {text, _, Forms, _HasRecs, _Mode} when is_list(Forms) ->
GetInfo = fun() -> file:read_file_info(File) end,
GetBin =
fun() ->
@@ -80,7 +80,7 @@ foldl(Fun, Acc0, File) when is_function(Fun, 4) ->
throw:Reason ->
{error, Reason}
end;
- {beam, _, BeamBin, _Mode} when is_binary(BeamBin) ->
+ {beam, _, BeamBin, _HasRecs, _Mode} when is_binary(BeamBin) ->
GetInfo = fun() -> file:read_file_info(File) end,
GetBin = fun() -> BeamBin end,
try
@@ -89,7 +89,7 @@ foldl(Fun, Acc0, File) when is_function(Fun, 4) ->
throw:Reason ->
{error, Reason}
end;
- {archive, _, ArchiveBin, _Mode} when is_binary(ArchiveBin) ->
+ {archive, _, ArchiveBin, _HasRecs, _Mode} when is_binary(ArchiveBin) ->
ZipFun =
fun({Name, GetInfo, GetBin}, A) ->
A2 = Fun(Name, GetInfo, GetBin, A),
@@ -139,7 +139,8 @@ start(EscriptOptions) ->
parse_and_run(File, Args, Options) ->
CheckOnly = lists:member("s", Options),
- {Source, Module, FormsOrBin, Mode} = parse_file(File, CheckOnly),
+ {Source, Module, FormsOrBin, HasRecs, Mode} =
+ parse_file(File, CheckOnly),
Mode2 =
case lists:member("d", Options) of
true ->
@@ -159,7 +160,7 @@ parse_and_run(File, Args, Options) ->
is_list(FormsOrBin) ->
case Mode2 of
interpret ->
- interpret(FormsOrBin, File, Args);
+ interpret(FormsOrBin, HasRecs, File, Args);
compile ->
case compile:forms(FormsOrBin, [report]) of
{ok, Module, BeamBin} ->
@@ -180,7 +181,8 @@ parse_and_run(File, Args, Options) ->
is_binary(FormsOrBin) ->
case Source of
archive ->
- case code:set_primary_archive(File, FormsOrBin) of
+ {ok, FileInfo} = file:read_file_info(File),
+ case code:set_primary_archive(File, FormsOrBin, FileInfo) of
ok when CheckOnly ->
case code:load_file(Module) of
{module, _} ->
@@ -245,7 +247,8 @@ parse_file(File, CheckOnly) ->
#state{mode = Mode,
source = Source,
module = Module,
- forms_or_bin = FormsOrBin} =
+ forms_or_bin = FormsOrBin,
+ has_records = HasRecs} =
case ScriptType of
archive ->
%% Archive file
@@ -259,7 +262,7 @@ parse_file(File, CheckOnly) ->
%% Source code
parse_source(S, File, Fd, StartLine, HeaderSz, CheckOnly)
end,
- {Source, Module, FormsOrBin, Mode}.
+ {Source, Module, FormsOrBin, HasRecs, Mode}.
%% Skip header and make a heuristic guess about the script type
skip_header(P, LineNo) ->
@@ -420,8 +423,7 @@ check_source(S, CheckOnly) ->
case S of
#state{n_errors = Nerrs} when Nerrs =/= 0 ->
fatal("There were compilation errors.");
- #state{exports_main = ExpMain,
- has_records = HasRecs,
+ #state{exports_main = ExpMain,
forms_or_bin = [FileForm2, ModForm2 | Forms]} ->
%% Optionally add export of main/1
Forms2 =
@@ -432,36 +434,15 @@ check_source(S, CheckOnly) ->
Forms3 = [FileForm2, ModForm2 | Forms2],
case CheckOnly of
true ->
- %% Optionally expand records
- Forms4 =
- case HasRecs of
- false -> Forms3;
- true -> erl_expand_records:module(Forms3, [])
- end,
%% Strong validation and halt
- case compile:forms(Forms4, [report,strong_validation]) of
+ case compile:forms(Forms3, [report,strong_validation]) of
{ok,_} ->
my_halt(0);
_Other ->
fatal("There were compilation errors.")
end;
false ->
- %% Basic validation before execution
- case erl_lint:module(Forms3) of
- {ok,Ws} ->
- report_warnings(Ws);
- {error,Es,Ws} ->
- report_errors(Es),
- report_warnings(Ws),
- fatal("There were compilation errors.")
- end,
- %% Optionally expand records
- Forms4 =
- case HasRecs of
- false -> Forms3;
- true -> erl_expand_records:module(Forms3, [])
- end,
- S#state{forms_or_bin = Forms4}
+ S#state{forms_or_bin = Forms3}
end
end.
@@ -494,17 +475,9 @@ epp_parse_file2(Epp, S, Forms, Parsed) ->
case Parsed of
{ok, Form} ->
case Form of
- {attribute,Ln,record,{Record,Fields}} ->
- S2 = S#state{has_records = true},
- case epp:normalize_typed_record_fields(Fields) of
- {typed, NewFields} ->
- epp_parse_file(Epp, S2,
- [{attribute, Ln, record, {Record, NewFields}},
- {attribute, Ln, type,
- {{record, Record}, Fields, []}} | Forms]);
- not_typed ->
- epp_parse_file(Epp, S2, [Form | Forms])
- end;
+ {attribute,_,record, _} ->
+ S2 = S#state{has_records = true},
+ epp_parse_file(Epp, S2, [Form | Forms]);
{attribute,Ln,mode,NewMode} ->
S2 = S#state{mode = NewMode},
if
@@ -563,8 +536,23 @@ run(Module, Args) ->
fatal(format_exception(Class, Reason))
end.
-interpret(Forms, File, Args) ->
- Dict = parse_to_dict(Forms),
+interpret(Forms, HasRecs, File, Args) ->
+ %% Basic validation before execution
+ case erl_lint:module(Forms) of
+ {ok,Ws} ->
+ report_warnings(Ws);
+ {error,Es,Ws} ->
+ report_errors(Es),
+ report_warnings(Ws),
+ fatal("There were compilation errors.")
+ end,
+ %% Optionally expand records
+ Forms2 =
+ case HasRecs of
+ false -> Forms;
+ true -> erl_expand_records:module(Forms, [])
+ end,
+ Dict = parse_to_dict(Forms2),
ArgsA = erl_parse:abstract(Args, 0),
Call = {call,0,{atom,0,main},[ArgsA]},
try
diff --git a/lib/stdlib/src/file_sorter.erl b/lib/stdlib/src/file_sorter.erl
index de9e628e22..e21a0c88f3 100644
--- a/lib/stdlib/src/file_sorter.erl
+++ b/lib/stdlib/src/file_sorter.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2001-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 2001-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(file_sorter).
@@ -186,7 +186,7 @@ options(Option) ->
options([{format, Format} | L], Opts) when Format =:= binary;
Format =:= term;
is_function(Format),
- is_function(Format, 1) ->
+ is_function(Format, 1) ->
options(L, Opts#opts{format = Format});
options([{format, binary_term} | L], Opts) ->
options(L, Opts#opts{format = binary_term_fun()});
@@ -419,9 +419,9 @@ culprit_found(IFun, F, FNs, W, L, I, [_Size | BT]) ->
IFun(close),
check_files(FNs, W, [{F,I,binary_to_term(BT)} | L]).
-files(_I, L, _LSz, #w{seq = 1}=W, []) ->
+files(_I, L, _LSz, #w{seq = 1, out = Out}=W, []) ->
%% No temporary files created, everything in L.
- case W#w.out of
+ case Out of
Fun when is_function(Fun) ->
SL = internal_sort(L, W),
W1 = outfun(binterm_objects(SL, []), W),
@@ -462,8 +462,8 @@ fun_run(I, L, LSz, W, []) ->
{cont, NW, Objs} ->
fun_run(I, L, LSz, NW, Objs)
end;
-fun_run(I, L, LSz, W, Objs) when LSz < W#w.runsize ->
- {NI, NObjs, NL, NLSz} = fun_objs(Objs, L, LSz, W#w.runsize, I, W),
+fun_run(I, L, LSz, #w{runsize = Runsize}=W, Objs) when LSz < Runsize ->
+ {NI, NObjs, NL, NLSz} = fun_objs(Objs, L, LSz, Runsize, I, W),
fun_run(NI, NL, NLSz, W, NObjs);
fun_run(I, L, _LSz, W, Objs) ->
NW = write_run(L, W),
@@ -1201,11 +1201,11 @@ infun(W) ->
erlang:raise(Class, Reason, erlang:get_stacktrace())
end.
-outfun(A, W) when W#w.inout_value =/= no_value ->
+outfun(A, #w{inout_value = Val} = W) when Val =/= no_value ->
W1 = W#w{inout_value = no_value},
W2 = if
W1#w.fun_out ->
- outfun(W#w.inout_value, W1);
+ outfun(Val, W1);
true -> W1
end,
outfun(A, W2);
@@ -1372,19 +1372,19 @@ cleanup(W) ->
end,
lists:foreach(F, W1#w.temp).
-close_input(W) when is_function(W#w.in) ->
- catch (W#w.in)(close),
+close_input(#w{in = In}=W) when is_function(In) ->
+ catch In(close),
W#w{in = undefined};
close_input(#w{in = undefined}=W) ->
W.
-close_out(W) when is_function(W#w.out) ->
- catch (W#w.out)(close);
+close_out(#w{out = Out}) when is_function(Out) ->
+ catch Out(close);
close_out(_) ->
ok.
close_file(Fd, W) ->
- {value, {Fd, FileName}} = lists:keysearch(Fd, 1, W#w.temp),
+ {Fd, FileName} = lists:keyfind(Fd, 1, W#w.temp),
?DEBUG("closing ~p~n", [FileName]),
file:close(Fd),
W#w{temp = [FileName | lists:keydelete(Fd, 1, W#w.temp)]}.
diff --git a/lib/stdlib/src/filelib.erl b/lib/stdlib/src/filelib.erl
index d65588f0d1..74c5172137 100644
--- a/lib/stdlib/src/filelib.erl
+++ b/lib/stdlib/src/filelib.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(filelib).
@@ -228,7 +228,17 @@ ensure_dir(F) ->
ok;
false ->
ensure_dir(Dir),
- file:make_dir(Dir)
+ case file:make_dir(Dir) of
+ {error,eexist}=EExist ->
+ case do_is_dir(Dir, file) of
+ true ->
+ ok;
+ false ->
+ EExist
+ end;
+ Err ->
+ Err
+ end
end.
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/io_lib.erl b/lib/stdlib/src/io_lib.erl
index 2d3c86e4ea..26f6ec8931 100644
--- a/lib/stdlib/src/io_lib.erl
+++ b/lib/stdlib/src/io_lib.erl
@@ -1,19 +1,19 @@
%%
%% %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
%% 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%
%%
@@ -139,9 +139,9 @@ format_prompt({format,Format,Args}) ->
format_prompt(Format,Args);
format_prompt(Prompt)
when is_list(Prompt); is_atom(Prompt); is_binary(Prompt) ->
- format_prompt("~s", [Prompt]);
+ format_prompt("~ts", [Prompt]);
format_prompt(Prompt) ->
- format_prompt("~p", [Prompt]).
+ format_prompt("~tp", [Prompt]).
format_prompt(Format, Args) ->
case catch io_lib:format(Format, Args) 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/qlc.erl b/lib/stdlib/src/qlc.erl
index ef142e1c8a..6e48d95973 100644
--- a/lib/stdlib/src/qlc.erl
+++ b/lib/stdlib/src/qlc.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2004-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 2004-2010. All Rights Reserved.
+%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
-%%
+%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
-%%
+%%
%% %CopyrightEnd%
%%
-module(qlc).
@@ -528,122 +528,111 @@ options(Options0, [Key | Keys], L) when is_list(Options0) ->
false ->
Options0
end,
- V = case lists:keysearch(Key, 1, Options) of
- {value, {format_fun, U=undefined}} ->
+ V = case lists:keyfind(Key, 1, Options) of
+ {format_fun, U=undefined} ->
{ok, U};
- {value, {info_fun, U=undefined}} ->
+ {info_fun, U=undefined} ->
{ok, U};
- {value, {lookup_fun, U=undefined}} ->
+ {lookup_fun, U=undefined} ->
{ok, U};
- {value, {parent_fun, U=undefined}} ->
+ {parent_fun, U=undefined} ->
{ok, U};
- {value, {post_fun, U=undefined}} ->
+ {post_fun, U=undefined} ->
{ok, U};
- {value, {pre_fun, U=undefined}} ->
+ {pre_fun, U=undefined} ->
{ok, U};
- {value, {info_fun, Fun}} when is_function(Fun),
- is_function(Fun, 1) ->
+ {info_fun, Fun} when is_function(Fun), is_function(Fun, 1) ->
{ok, Fun};
- {value, {pre_fun, Fun}} when is_function(Fun),
- is_function(Fun, 1) ->
+ {pre_fun, Fun} when is_function(Fun), is_function(Fun, 1) ->
{ok, Fun};
- {value, {post_fun, Fun}} when is_function(Fun),
- is_function(Fun, 0) ->
+ {post_fun, Fun} when is_function(Fun), is_function(Fun, 0) ->
{ok, Fun};
- {value, {lookup_fun, Fun}} when is_function(Fun),
- is_function(Fun, 2) ->
+ {lookup_fun, Fun} when is_function(Fun), is_function(Fun, 2) ->
{ok, Fun};
- {value, {max_lookup, Max}} when is_integer(Max), Max >= 0 ->
+ {max_lookup, Max} when is_integer(Max), Max >= 0 ->
{ok, Max};
- {value, {max_lookup, infinity}} ->
+ {max_lookup, infinity} ->
{ok, -1};
- {value, {format_fun, Fun}} when is_function(Fun),
- is_function(Fun, 1) ->
+ {format_fun, Fun} when is_function(Fun), is_function(Fun, 1) ->
{ok, Fun};
- {value, {parent_fun, Fun}} when is_function(Fun),
- is_function(Fun, 0) ->
+ {parent_fun, Fun} when is_function(Fun), is_function(Fun, 0) ->
{ok, Fun};
- {value, {key_equality, KE='=='}}->
+ {key_equality, KE='=='} ->
{ok, KE};
- {value, {key_equality, KE='=:='}}->
+ {key_equality, KE='=:='} ->
{ok, KE};
- {value, {join, J=any}} ->
+ {join, J=any} ->
{ok, J};
- {value, {join, J=nested_loop}} ->
+ {join, J=nested_loop} ->
{ok, J};
- {value, {join, J=merge}} ->
+ {join, J=merge} ->
{ok, J};
- {value, {join, J=lookup}} ->
+ {join, J=lookup} ->
{ok, J};
- {value, {lookup, LookUp}} when LookUp;
- not LookUp;
- LookUp =:= any ->
+ {lookup, LookUp} when is_boolean(LookUp); LookUp =:= any ->
{ok, LookUp};
- {value, {max_list_size, Max}} when is_integer(Max), Max >= 0 ->
+ {max_list_size, Max} when is_integer(Max), Max >= 0 ->
{ok, Max};
- {value, {tmpdir_usage, TmpUsage}} when TmpUsage =:= allowed;
- TmpUsage =:= not_allowed;
- TmpUsage =:= info_msg;
- TmpUsage =:= warning_msg;
- TmpUsage =:= error_msg ->
+ {tmpdir_usage, TmpUsage} when TmpUsage =:= allowed;
+ TmpUsage =:= not_allowed;
+ TmpUsage =:= info_msg;
+ TmpUsage =:= warning_msg;
+ TmpUsage =:= error_msg ->
{ok, TmpUsage};
- {value, {unique, Unique}} when Unique; not Unique ->
+ {unique, Unique} when is_boolean(Unique) ->
{ok, Unique};
- {value, {cache, Cache}} when Cache; not Cache; Cache =:= list ->
+ {cache, Cache} when is_boolean(Cache); Cache =:= list ->
{ok, Cache};
- {value, {cache, ets}} ->
+ {cache, ets} ->
{ok, true};
- {value, {cache, no}} ->
+ {cache, no} ->
{ok, false};
- {value, {unique_all, UniqueAll}} when UniqueAll; not UniqueAll ->
+ {unique_all, UniqueAll} when is_boolean(UniqueAll) ->
{ok, UniqueAll};
- {value, {cache_all, CacheAll}} when CacheAll;
- not CacheAll;
- CacheAll =:= list ->
+ {cache_all, CacheAll} when is_boolean(CacheAll);
+ CacheAll =:= list ->
{ok, CacheAll};
- {value, {cache_all, ets}} ->
+ {cache_all, ets} ->
{ok, true};
- {value, {cache_all, no}} ->
+ {cache_all, no} ->
{ok, false};
- {value, {spawn_options, default}} ->
+ {spawn_options, default} ->
{ok, default};
- {value, {spawn_options, SpawnOptions}} ->
+ {spawn_options, SpawnOptions} ->
case is_proper_list(SpawnOptions) of
true ->
{ok, SpawnOptions};
false ->
badarg
end;
- {value, {flat, Flat}} when Flat; not Flat ->
+ {flat, Flat} when is_boolean(Flat) ->
{ok, Flat};
- {value, {format, Format}} when Format =:= string;
- Format =:= abstract_code;
- Format =:= debug ->
+ {format, Format} when Format =:= string;
+ Format =:= abstract_code;
+ Format =:= debug ->
{ok, Format};
- {value, {n_elements, NElements}} when NElements =:= infinity;
- is_integer(NElements),
- NElements > 0 ->
+ {n_elements, NElements} when NElements =:= infinity;
+ is_integer(NElements),
+ NElements > 0 ->
{ok, NElements};
- {value, {depth, Depth}} when Depth =:= infinity;
- is_integer(Depth), Depth >= 0 ->
+ {depth, Depth} when Depth =:= infinity;
+ is_integer(Depth), Depth >= 0 ->
{ok, Depth};
- {value, {order, Order}} when is_function(Order),
- is_function(Order, 2);
- (Order =:= ascending);
- (Order =:= descending) ->
+ {order, Order} when is_function(Order), is_function(Order, 2);
+ (Order =:= ascending);
+ (Order =:= descending) ->
{ok, Order};
- {value, {compressed, Comp}} when Comp ->
+ {compressed, Comp} when Comp ->
{ok, [compressed]};
- {value, {compressed, Comp}} when not Comp ->
+ {compressed, Comp} when not Comp ->
{ok, []};
- {value, {tmpdir, T}} ->
+ {tmpdir, T} ->
{ok, T};
- {value, {size, Size}} when is_integer(Size), Size > 0 ->
+ {size, Size} when is_integer(Size), Size > 0 ->
{ok, Size};
- {value, {no_files, NoFiles}} when is_integer(NoFiles),
- NoFiles > 1 ->
+ {no_files, NoFiles} when is_integer(NoFiles), NoFiles > 1 ->
{ok, NoFiles};
- {value, {Key, _}} ->
+ {Key, _} ->
badarg;
false ->
Default = default_option(Key),
@@ -1457,7 +1446,7 @@ prep_qlc_lc({qlc_v1, QFun, CodeF, Qdata0, QOpt}, Opt, GOpt, _H) ->
{?qual_data(QNum, GoI, SI, {gen, Prep}), ModGens}
end,
{Qdata, ModGens} = lists:mapfoldl(F, [], Qdata0),
- SomeLookUp = lists:keymember(true, 2, ModGens) =/= false,
+ SomeLookUp = lists:keymember(true, 2, ModGens),
check_lookup_option(Opt, SomeLookUp),
case ModGens of
[{_QNum, _LookUp, all, OnePrep}] ->
@@ -1503,7 +1492,7 @@ pos_fun('==', QOpt, QNum) ->
prep_gen(#qlc_table{lu_vals = LuV0, ms = MS0, trav_MS = TravMS,
info_fun = IF, lookup_fun = LU_fun,
- key_equality = KeyEquality}=LE0,
+ key_equality = KeyEquality}=LE0,
Prep0, PosFun0, {MS, Fs}, Opt) ->
PosFun = PosFun0(KeyEquality),
{LuV, {STag,SkipFils}} = find_const_positions(IF, LU_fun, PosFun, Opt),
@@ -1998,8 +1987,8 @@ no_cache_of_first_generator(Optz, 1) ->
Optz#optz{cache = false}.
maybe_sort(LE, QNum, DoSort, Opt) ->
- case lists:keysearch(QNum, 1, DoSort) of
- {value, {QNum, Col}} ->
+ case lists:keyfind(QNum, 1, DoSort) of
+ {QNum, Col} ->
#qlc_opt{tmpdir = TmpDir, tmpdir_usage = TmpUsage} = Opt,
SortOpts = [{tmpdir,Dir} || Dir <- [TmpDir], Dir =/= ""],
Sort = #qlc_sort{h = LE, keypos = {keysort, Col}, unique = false,
@@ -2025,7 +2014,7 @@ skip_lookup_filters(Qdata0, LU_SkipFs) ->
%% specification it must be applied _after_ the lookup join (the
%% filter must not be skipped!).
activate_join_lookup_filter(QNum, Qdata) ->
- {value, {_,GoI2,SI2,{gen,Prep2}}} = lists:keysearch(QNum, 1, Qdata),
+ {_,GoI2,SI2,{gen,Prep2}} = lists:keyfind(QNum, 1, Qdata),
Table2 = Prep2#prepared.qh,
NPrep2 = Prep2#prepared{qh = Table2#qlc_table{ms = no_match_spec}},
%% Table2#qlc_table.ms has been reset; the filter will be run.
@@ -2059,7 +2048,7 @@ opt_join(Join, JoinOption, Qdata, Opt, LU_SkipQuals) ->
opt_join_lu([{{_Q1,_C1,Q2,_C2}=J,[{lookup_join,_KEols,JKE,Skip0} | _]} | LJ],
Qdata, LU_SkipQuals) ->
- {value, {Q2,_,_,{gen,Prep2}}} = lists:keysearch(Q2, 1, Qdata),
+ {Q2,_,_,{gen,Prep2}} = lists:keyfind(Q2, 1, Qdata),
#qlc_table{ms = MS, key_equality = KE,
lookup_fun = LU_fun} = Prep2#prepared.qh,
%% If there is no filter to skip (the match spec was derived
@@ -2670,8 +2659,8 @@ sort_list_output(L) ->
%% Don't use the file_sorter unless it is known that objects will be
%% put on a temporary file (optimization).
sort_handle(H, ListFun, FileFun, SortOptions, Post, LocalPost, TmpUsageM) ->
- Size = case lists:keysearch(size, 1, SortOptions) of
- {value, {size, Size0}} -> Size0;
+ Size = case lists:keyfind(size, 1, SortOptions) of
+ {size, Size0} -> Size0;
false -> default_option(size)
end,
sort_cache(H, [], Size, {ListFun, FileFun, Post, LocalPost, TmpUsageM}).
@@ -2891,8 +2880,8 @@ ucache_recall(UTab, MTab, SeqNo) ->
Object = case ets:lookup(UTab, Hash) of
[{Hash, SeqNo, Object0}] -> Object0;
HashSeqObjects ->
- {value, {Hash, SeqNo, Object0}} =
- lists:keysearch(SeqNo, 2, HashSeqObjects),
+ {Hash, SeqNo, Object0} =
+ lists:keyfind(SeqNo, 2, HashSeqObjects),
Object0
end,
[Object | fun() -> ucache_recall(UTab, MTab, SeqNo + 1) end]
@@ -3403,8 +3392,8 @@ merge_join_id() ->
tmp_merge_file(MergeId) ->
TmpFiles = get(?MERGE_JOIN_FILE),
- case lists:keysearch(MergeId, 1, TmpFiles) of
- {value, {MergeId, Fd, FileName}} ->
+ case lists:keyfind(MergeId, 1, TmpFiles) of
+ {MergeId, Fd, FileName} ->
{Fd, FileName};
false ->
none
diff --git a/lib/stdlib/src/qlc_pt.erl b/lib/stdlib/src/qlc_pt.erl
index 2d7874d99f..24378a0698 100644
--- a/lib/stdlib/src/qlc_pt.erl
+++ b/lib/stdlib/src/qlc_pt.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2004-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 2004-2010. All Rights Reserved.
+%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
-%%
+%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
-%%
+%%
%% %CopyrightEnd%
%%
-module(qlc_pt).
@@ -845,8 +845,8 @@ join_handle(AP, L, [F, H, O, C], Constants) ->
join_handle_constants(QId, ExtraConstants) ->
IdNo = QId#qid.no,
- case lists:keysearch(IdNo, 1, ExtraConstants) of
- {value, {IdNo, ConstOps}} ->
+ case lists:keyfind(IdNo, 1, ExtraConstants) of
+ {IdNo, ConstOps} ->
ConstOps;
false ->
[]
@@ -1231,9 +1231,9 @@ lu_skip(ColConstants, FilterData, PatternFrame, PatternVars,
%% The filter can only be skipped if all constants
%% are looked up.
LookedUpConstants =
- case lists:keysearch(Column, 1, ColConstants) of
+ case lists:keyfind(Column, 1, ColConstants) of
false -> [];
- {value, {Column,LUCs}} -> LUCs
+ {Column, LUCs} -> LUCs
end,
%% Don't try to handle filters that compare several
%% values equal. See also frames_to_columns().
@@ -1279,8 +1279,8 @@ join_gens(Cs0, Qs, Skip) ->
join_gens2(lists:filter(fun(C) -> length(C) > 2 end, Cs), FD, Skip)}.
join_gens2(Cs0, FilterData, Skip) ->
- [{J, skip_tag(case lists:keysearch(J, 1, Skip) of
- {value, {J,FilL}} ->
+ [{J, skip_tag(case lists:keyfind(J, 1, Skip) of
+ {J, FilL} ->
FilL;
false ->
[]
@@ -1296,8 +1296,8 @@ skip_tag(FilList, FilterData) ->
end, FilList}.
skip_tag(Col, ColFils, FilterData) ->
- case lists:keysearch(Col, 1, ColFils) of
- {value, {Col, FilL}} ->
+ case lists:keyfind(Col, 1, ColFils) of
+ {Col, FilL} ->
Tag = if
length(FilterData) =:= length(FilL) ->
all;
@@ -1415,7 +1415,7 @@ sel_gf([], _N, _Deps, _RDs, _Gens, _Gens1) ->
sel_gf([{#qid{no = N}=Id,{fil,F}}=Fil | FData], N, Deps, RDs, Gens, Gens1) ->
case erl_lint:is_guard_test(F, RDs) of
true ->
- {value, {Id,GIds}} = lists:keysearch(Id, 1, Deps),
+ {Id,GIds} = lists:keyfind(Id, 1, Deps),
case length(GIds) =< 1 of
true ->
case generators_in_scope(GIds, Gens1) of
@@ -2572,8 +2572,8 @@ nos_pattern([P0 | Ps0], S0, PVs0) ->
{[P | Ps], S, PVs};
nos_pattern({var,L,V}, {LI,Vs0,UV,A,Sg}, PVs0) when V =/= '_' ->
{Name, Vs, PVs} =
- case lists:keysearch(V, 1, PVs0) of
- {value, {V,VN}} ->
+ case lists:keyfind(V, 1, PVs0) of
+ {V, VN} ->
_ = used_var(V, Vs0, UV),
{VN, Vs0, PVs0};
false ->
diff --git a/lib/stdlib/src/re.erl b/lib/stdlib/src/re.erl
index 5417ac02e5..296a6b3d23 100644
--- a/lib/stdlib/src/re.erl
+++ b/lib/stdlib/src/re.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%
%%
-module(re).
@@ -32,18 +32,7 @@ split(Subject,RE,Options) ->
try
{NewOpt,Convert,Unicode,Limit,Strip,Group} =
process_split_params(Options,iodata,false,-1,false,false),
- FlatSubject =
- case is_binary(Subject) of
- true ->
- Subject;
- false ->
- case Unicode of
- true ->
- unicode:characters_to_binary(Subject,unicode);
- false ->
- iolist_to_binary(Subject)
- end
- end,
+ FlatSubject = to_binary(Subject, Unicode),
case compile_split(RE,NewOpt) of
{error,_Err} ->
throw(badre);
@@ -217,19 +206,9 @@ replace(Subject,RE,Replacement,Options) ->
try
{NewOpt,Convert,Unicode} =
process_repl_params(Options,iodata,false),
- FlatSubject =
- case is_binary(Subject) of
- true ->
- Subject;
- false ->
- case Unicode of
- true ->
- unicode:characters_to_binary(Subject,unicode);
- false ->
- iolist_to_binary(Subject)
- end
- end,
- case do_replace(FlatSubject,Subject,RE,Replacement,NewOpt) of
+ FlatSubject = to_binary(Subject, Unicode),
+ FlatReplacement = to_binary(Replacement, Unicode),
+ case do_replace(FlatSubject,Subject,RE,FlatReplacement,NewOpt) of
{error,_Err} ->
throw(badre);
IoList ->
@@ -237,7 +216,12 @@ replace(Subject,RE,Replacement,Options) ->
iodata ->
IoList;
binary ->
- iolist_to_binary(IoList);
+ case Unicode of
+ false ->
+ iolist_to_binary(IoList);
+ true ->
+ unicode:characters_to_binary(IoList,unicode)
+ end;
list ->
case Unicode of
false ->
@@ -324,8 +308,7 @@ process_split_params([H|T],C,U,L,S,G) ->
{[H|NT],NC,NU,NL,NS,NG}.
apply_mlist(Subject,Replacement,Mlist) ->
- do_mlist(Subject,Subject,0,precomp_repl(iolist_to_binary(Replacement)),
- Mlist).
+ do_mlist(Subject,Subject,0,precomp_repl(Replacement), Mlist).
precomp_repl(<<>>) ->
@@ -545,7 +528,7 @@ process_uparams([],Type) ->
ucompile(RE,Options) ->
try
- re:compile(unicode:characters_to_binary(RE,unicode))
+ re:compile(unicode:characters_to_binary(RE,unicode),Options)
catch
error:AnyError ->
{'EXIT',{new_stacktrace,[{Mod,_,L}|Rest]}} =
@@ -618,18 +601,7 @@ grun(Subject,RE,{Options,NeedClean,OrigRE}) ->
grun2(Subject,RE,{Options,NeedClean}) ->
Unicode = check_for_unicode(RE,Options),
- FlatSubject =
- case is_binary(Subject) of
- true ->
- Subject;
- false ->
- case Unicode of
- true ->
- unicode:characters_to_binary(Subject,unicode);
- false ->
- iolist_to_binary(Subject)
- end
- end,
+ FlatSubject = to_binary(Subject, Unicode),
do_grun(FlatSubject,Subject,Unicode,RE,{Options,NeedClean}).
do_grun(FlatSubject,Subject,Unicode,RE,{Options0,NeedClean}) ->
@@ -749,3 +721,10 @@ runopt(global) ->
true;
runopt(_) ->
false.
+
+to_binary(Bin, _IsUnicode) when is_binary(Bin) ->
+ Bin;
+to_binary(Data, true) ->
+ unicode:characters_to_binary(Data,unicode);
+to_binary(Data, false) ->
+ iolist_to_binary(Data).
diff --git a/lib/stdlib/src/shell.erl b/lib/stdlib/src/shell.erl
index a8d31b4e6b..ebb221c151 100644
--- a/lib/stdlib/src/shell.erl
+++ b/lib/stdlib/src/shell.erl
@@ -1,19 +1,19 @@
%%
%% %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
%% 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(shell).
@@ -22,12 +22,14 @@
-export([whereis_evaluator/0, whereis_evaluator/1]).
-export([start_restricted/1, stop_restricted/0]).
-export([local_allowed/3, non_local_allowed/3]).
+-export([prompt_func/1]).
-define(LINEMAX, 30).
-define(CHAR_MAX, 60).
-define(DEF_HISTORY, 20).
-define(DEF_RESULTS, 20).
-define(DEF_CATCH_EXCEPTION, false).
+-define(DEF_PROMPT_FUNC, default).
-define(RECORDS, shell_records).
@@ -235,14 +237,15 @@ server(StartSync) ->
{History,Results} = check_and_get_history_and_results(),
server_loop(0, start_eval(Bs, RT, []), Bs, RT, [], History, Results).
-server_loop(N0, Eval_0, Bs0, RT, Ds0, History0, Results0) ->
+server_loop(N0, Eval_0, Bs00, RT, Ds00, History0, Results0) ->
N = N0 + 1,
- {Res, Eval0} = get_command(prompt(N), Eval_0, Bs0, RT, Ds0),
+ {Eval_1,Bs0,Ds0,Prompt} = prompt(N, Eval_0, Bs00, RT, Ds00),
+ {Res,Eval0} = get_command(Prompt, Eval_1, Bs0, RT, Ds0),
case Res of
{ok,Es0,_EndLine} ->
case expand_hist(Es0, N) of
{ok,Es} ->
- {V,Eval,Bs,Ds} = shell_cmd(Es, Eval0, Bs0, RT, Ds0),
+ {V,Eval,Bs,Ds} = shell_cmd(Es, Eval0, Bs0, RT, Ds0, cmd),
{History,Results} = check_and_get_history_and_results(),
add_cmd(N, Es, V),
HB1 = del_cmd(command, N - History, N - History0, false),
@@ -301,7 +304,42 @@ get_command1(Pid, Eval, Bs, RT, Ds) ->
get_command1(Pid, start_eval(Bs, RT, Ds), Bs, RT, Ds)
end.
-prompt(N) ->
+prompt(N, Eval0, Bs0, RT, Ds0) ->
+ case get_prompt_func() of
+ {M,F} ->
+ L = [{history,N}],
+ C = {call,1,{remote,1,{atom,1,M},{atom,1,F}},[{value,1,L}]},
+ {V,Eval,Bs,Ds} = shell_cmd([C], Eval0, Bs0, RT, Ds0, pmt),
+ {Eval,Bs,Ds,case V of
+ {pmt,Val} ->
+ Val;
+ _ ->
+ bad_prompt_func({M,F}),
+ default_prompt(N)
+ end};
+ default ->
+ {Eval0,Bs0,Ds0,default_prompt(N)}
+ end.
+
+get_prompt_func() ->
+ case application:get_env(stdlib, shell_prompt_func) of
+ {ok,{M,F}=PromptFunc} when is_atom(M), is_atom(F) ->
+ PromptFunc;
+ {ok,default=Default} ->
+ Default;
+ {ok,Term} ->
+ bad_prompt_func(Term),
+ default;
+ undefined ->
+ default
+ end.
+
+bad_prompt_func(M) ->
+ fwrite_severity(benign, <<"Bad prompt function: ~p">>, [M]).
+
+default_prompt(N) ->
+ %% Don't bother flattening the list irrespective of what the
+ %% I/O-protocol states.
case is_alive() of
true -> io_lib:format(<<"(~s)~w> ">>, [node(), N]);
false -> io_lib:format(<<"~w> ">>, [N])
@@ -461,14 +499,16 @@ has_bin(T, I) ->
has_bin(element(I, T)),
has_bin(T, I - 1).
-%% shell_cmd(Sequence, Evaluator, Bindings, RecordTable, Dictionary)
+%% shell_cmd(Sequence, Evaluator, Bindings, RecordTable, Dictionary, What)
%% shell_rep(Evaluator, Bindings, RecordTable, Dictionary) ->
%% {Value,Evaluator,Bindings,Dictionary}
%% Send a command to the evaluator and wait for the reply. Start a new
%% evaluator if necessary.
+%% What = pmt | cmd. When evaluating a prompt ('pmt') the evaluated value
+%% must not be displayed, and it has to be returned.
-shell_cmd(Es, Eval, Bs, RT, Ds) ->
- Eval ! {shell_cmd,self(),{eval,Es}},
+shell_cmd(Es, Eval, Bs, RT, Ds, W) ->
+ Eval ! {shell_cmd,self(),{eval,Es}, W},
shell_rep(Eval, Bs, RT, Ds).
shell_rep(Ev, Bs0, RT, Ds0) ->
@@ -559,26 +599,26 @@ evaluator(Shell, Bs, RT, Ds) ->
eval_loop(Shell, Bs0, RT) ->
receive
- {shell_cmd,Shell,{eval,Es}} ->
+ {shell_cmd,Shell,{eval,Es},W} ->
Ef = {value,
fun(MForFun, As) -> apply_fun(MForFun, As, Shell) end},
Lf = local_func_handler(Shell, RT, Ef),
- Bs = eval_exprs(Es, Shell, Bs0, RT, Lf, Ef),
+ Bs = eval_exprs(Es, Shell, Bs0, RT, Lf, Ef, W),
eval_loop(Shell, Bs, RT)
end.
restricted_eval_loop(Shell, Bs0, RT, RShMod) ->
receive
- {shell_cmd,Shell,{eval,Es}} ->
+ {shell_cmd,Shell,{eval,Es}, W} ->
{LFH,NLFH} = restrict_handlers(RShMod, Shell, RT),
put(restricted_expr_state, []),
- Bs = eval_exprs(Es, Shell, Bs0, RT, {eval,LFH}, {value,NLFH}),
+ Bs = eval_exprs(Es, Shell, Bs0, RT, {eval,LFH}, {value,NLFH}, W),
restricted_eval_loop(Shell, Bs, RT, RShMod)
end.
-eval_exprs(Es, Shell, Bs0, RT, Lf, Ef) ->
+eval_exprs(Es, Shell, Bs0, RT, Lf, Ef, W) ->
try
- {R,Bs2} = exprs(Es, Bs0, RT, Lf, Ef),
+ {R,Bs2} = exprs(Es, Bs0, RT, Lf, Ef, W),
Shell ! {shell_rep,self(),R},
Bs2
catch
@@ -614,10 +654,10 @@ do_catch(_Class, _Reason) ->
false
end.
-exprs(Es, Bs0, RT, Lf, Ef) ->
- exprs(Es, Bs0, RT, Lf, Ef, Bs0).
+exprs(Es, Bs0, RT, Lf, Ef, W) ->
+ exprs(Es, Bs0, RT, Lf, Ef, Bs0, W).
-exprs([E0|Es], Bs1, RT, Lf, Ef, Bs0) ->
+exprs([E0|Es], Bs1, RT, Lf, Ef, Bs0, W) ->
UsedRecords = used_record_defs(E0, RT),
RBs = record_bindings(UsedRecords, Bs1),
case check_command(prep_check([E0]), RBs) of
@@ -629,16 +669,20 @@ exprs([E0|Es], Bs1, RT, Lf, Ef, Bs0) ->
if
Es =:= [] ->
VS = pp(V0, 1, RT),
- io:requests([{put_chars, VS}, nl]),
+ [io:requests([{put_chars, VS}, nl]) || W =:= cmd],
%% Don't send the result back if it will be
%% discarded anyway.
- V = case result_will_be_saved() of
- true -> V0;
- false -> ignored
+ V = if
+ W =:= pmt ->
+ {W,V0};
+ true -> case result_will_be_saved() of
+ true -> V0;
+ false -> ignored
+ end
end,
{{value,V,Bs,get()},Bs};
true ->
- exprs(Es, Bs, RT, Lf, Ef, Bs0)
+ exprs(Es, Bs, RT, Lf, Ef, Bs0, W)
end;
{error,Error} ->
{{command_error,Error},Bs0}
@@ -1383,7 +1427,7 @@ pp(V, I, RT) ->
columns() ->
case io:columns() of
- {ok,N} -> N;
+ {ok,N} -> N;
_ -> 80
end.
@@ -1438,3 +1482,9 @@ results(L) when is_integer(L), L >= 0 ->
catch_exception(Bool) ->
set_env(stdlib, shell_catch_exception, Bool, ?DEF_CATCH_EXCEPTION).
+
+-type prompt_func() :: 'default' | {module(),atom()}.
+-spec prompt_func(prompt_func()) -> prompt_func().
+
+prompt_func(String) ->
+ set_env(stdlib, shell_prompt_func, String, ?DEF_PROMPT_FUNC).
diff --git a/lib/stdlib/src/shell_default.erl b/lib/stdlib/src/shell_default.erl
index 670f8cdb44..3fe359af0e 100644
--- a/lib/stdlib/src/shell_default.erl
+++ b/lib/stdlib/src/shell_default.erl
@@ -1,19 +1,19 @@
%%
%% %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
%% 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%
%%
@@ -45,6 +45,7 @@ help() ->
format("h() -- history\n"),
format("history(N) -- set how many previous commands to keep\n"),
format("results(N) -- set how many previous command results to keep\n"),
+ format("catch_exception(B) -- how exceptions are handled\n"),
format("v(N) -- use the value of query <N>\n"),
format("rd(R,D) -- define a record\n"),
format("rf() -- remove all record information\n"),
diff --git a/lib/stdlib/src/supervisor.erl b/lib/stdlib/src/supervisor.erl
index fb1303d1eb..22269a8d1b 100644
--- a/lib/stdlib/src/supervisor.erl
+++ b/lib/stdlib/src/supervisor.erl
@@ -1,19 +1,19 @@
%%
%% %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
%% 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(supervisor).
@@ -24,7 +24,7 @@
-export([start_link/2,start_link/3,
start_child/2, restart_child/2,
delete_child/2, terminate_child/2,
- which_children/1,
+ which_children/1, count_children/1,
check_childspecs/1]).
-export([behaviour_info/1]).
@@ -95,6 +95,9 @@ terminate_child(Supervisor, Name) ->
which_children(Supervisor) ->
call(Supervisor, which_children).
+count_children(Supervisor) ->
+ call(Supervisor, count_children).
+
call(Supervisor, Req) ->
gen_server:call(Supervisor, Req, infinity).
@@ -297,7 +300,49 @@ handle_call(which_children, _From, State) ->
{Name, Pid, ChildType, Mods}
end,
State#state.children),
- {reply, Resp, State}.
+ {reply, Resp, State};
+
+handle_call(count_children, _From, State) when ?is_simple(State) ->
+ [#child{child_type = CT}] = State#state.children,
+ {Active, Count} =
+ ?DICT:fold(fun(Pid, _Val, {Alive, Tot}) ->
+ if is_pid(Pid) -> {Alive+1, Tot +1};
+ true -> {Alive, Tot + 1} end
+ end, {0, 0}, State#state.dynamics),
+ Reply = case CT of
+ supervisor -> [{specs, 1}, {active, Active},
+ {supervisors, Count}, {workers, 0}];
+ worker -> [{specs, 1}, {active, Active},
+ {supervisors, 0}, {workers, Count}]
+ end,
+ {reply, Reply, State};
+
+handle_call(count_children, _From, State) ->
+
+ %% Specs and children are together on the children list...
+ {Specs, Active, Supers, Workers} =
+ lists:foldl(fun(Child, Counts) ->
+ count_child(Child, Counts)
+ end, {0,0,0,0}, State#state.children),
+
+ %% Reformat counts to a property list.
+ Reply = [{specs, Specs}, {active, Active},
+ {supervisors, Supers}, {workers, Workers}],
+ {reply, Reply, State}.
+
+
+count_child(#child{pid = Pid, child_type = worker},
+ {Specs, Active, Supers, Workers}) ->
+ case is_pid(Pid) andalso is_process_alive(Pid) of
+ true -> {Specs+1, Active+1, Supers, Workers+1};
+ false -> {Specs+1, Active, Supers, Workers+1}
+ end;
+count_child(#child{pid = Pid, child_type = supervisor},
+ {Specs, Active, Supers, Workers}) ->
+ case is_pid(Pid) andalso is_process_alive(Pid) of
+ true -> {Specs+1, Active+1, Supers+1, Workers};
+ false -> {Specs+1, Active, Supers+1, Workers}
+ end.
%%% Hopefully cause a function-clause as there is no API function
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/ExpandTestCaps.erl b/lib/stdlib/test/ExpandTestCaps.erl
new file mode 100644
index 0000000000..96c4115354
--- /dev/null
+++ b/lib/stdlib/test/ExpandTestCaps.erl
@@ -0,0 +1,32 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 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('ExpandTestCaps').
+
+-export([a_fun_name/1,
+ a_less_fun_name/1,
+ b_comes_after_a/1]).
+
+a_fun_name(X) ->
+ X.
+
+a_less_fun_name(X) ->
+ X.
+
+b_comes_after_a(X) ->
+ X.
diff --git a/lib/stdlib/test/ExpandTestCaps1.erl b/lib/stdlib/test/ExpandTestCaps1.erl
new file mode 100644
index 0000000000..09ee9f81c4
--- /dev/null
+++ b/lib/stdlib/test/ExpandTestCaps1.erl
@@ -0,0 +1,44 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 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('ExpandTestCaps1').
+
+-export([a_fun_name/1,
+ a_less_fun_name/1,
+ b_comes_after_a/1,
+ 'Quoted_fun_name'/0,
+ 'Quoted_fun_too'/0,
+ '#weird-fun-name'/0]).
+
+a_fun_name(X) ->
+ X.
+
+a_less_fun_name(X) ->
+ X.
+
+b_comes_after_a(X) ->
+ X.
+
+'Quoted_fun_name'() ->
+ whoopee.
+
+'Quoted_fun_too'() ->
+ too.
+
+'#weird-fun-name'() ->
+ weird.
diff --git a/lib/stdlib/test/Makefile b/lib/stdlib/test/Makefile
index 7a87eef5f3..9beac93eb8 100644
--- a/lib/stdlib/test/Makefile
+++ b/lib/stdlib/test/Makefile
@@ -18,6 +18,7 @@ MODULES= \
digraph_utils_SUITE \
dummy1_h \
dummy_h \
+ edlin_expand_SUITE \
epp_SUITE \
erl_eval_helper \
erl_eval_SUITE \
@@ -29,6 +30,10 @@ MODULES= \
escript_SUITE \
ets_SUITE \
ets_tough_SUITE \
+ expand_test \
+ expand_test1 \
+ ExpandTestCaps \
+ ExpandTestCaps1 \
filelib_SUITE \
file_sorter_SUITE \
filename_SUITE \
@@ -105,7 +110,7 @@ COVERFILE=stdlib.cover
make_emakefile:
$(ERL_TOP)/make/make_emakefile $(ERL_COMPILE_FLAGS) -o$(EBIN) $(MODULES) \
- >> $(EMAKEFILE)
+ > $(EMAKEFILE)
tests debug opt: make_emakefile
erl $(ERL_MAKE_FLAGS) -make
diff --git a/lib/stdlib/test/array_SUITE.erl b/lib/stdlib/test/array_SUITE.erl
index 7cfdcf6dfd..e7cfc65be1 100644
--- a/lib/stdlib/test/array_SUITE.erl
+++ b/lib/stdlib/test/array_SUITE.erl
@@ -384,11 +384,17 @@ set_get_test_() ->
?_assert(array:get(0, set(0, 42, set(0, 17, new()))) =:= 42),
- ?_assert(array:get(0, reset(0, new())) =:= undefined),
- ?_assert(array:get(0, reset(0, set(0, 17, new()))) =:= undefined),
- ?_assert(array:get(0, reset(0, new({default,42}))) =:= 42),
- ?_assert(array:get(0, reset(0, set(0, 17, new({default,42}))))
- =:= 42)
+ ?_assertError(badarg, array:get(0, reset(11, new([{size,10}])))),
+ ?_assertError(badarg, array:get(0, reset(-1, new([{size,10}])))),
+ ?_assert(array:get(0, reset(0, new())) =:= undefined),
+ ?_assert(array:get(0, reset(0, set(0, 17, new()))) =:= undefined),
+ ?_assert(array:get(0, reset(9, set(9, 17, new()))) =:= undefined),
+ ?_assert(array:get(0, reset(11, set(11, 17, new()))) =:= undefined),
+ ?_assert(array:get(0, reset(11, set(12, 17, new()))) =:= undefined),
+ ?_assert(array:get(0, reset(1, set(12, 17, new()))) =:= undefined),
+ ?_assert(array:get(0, reset(11, new())) =:= undefined),
+ ?_assert(array:get(0, reset(0, set(0, 17, new({default,42})))) =:= 42),
+ ?_assert(array:get(0, reset(0, new({default,42}))) =:= 42)
].
to_list_test_() ->
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/calendar_SUITE.erl b/lib/stdlib/test/calendar_SUITE.erl
index ea81bb99a9..10fb72c1b1 100644
--- a/lib/stdlib/test/calendar_SUITE.erl
+++ b/lib/stdlib/test/calendar_SUITE.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(calendar_SUITE).
@@ -48,7 +48,7 @@ gregorian_days(doc) ->
"At the same time valid_date is tested.";
gregorian_days(suite) ->
[];
-gregorian_days(Config) when list(Config) ->
+gregorian_days(Config) when is_list(Config) ->
?line Days = calendar:date_to_gregorian_days({?START_YEAR, 1, 1}),
?line MaxDays = calendar:date_to_gregorian_days({?END_YEAR, 1, 1}),
?line check_gregorian_days(Days, MaxDays).
@@ -60,7 +60,7 @@ gregorian_seconds(doc) ->
"every 2 days + 1 second.";
gregorian_seconds(suite) ->
[];
-gregorian_seconds(Config) when list(Config) ->
+gregorian_seconds(Config) when is_list(Config) ->
?line Secs = calendar:datetime_to_gregorian_seconds({{?START_YEAR, 1, 1},
{0, 0, 0}}),
?line MaxSecs = calendar:datetime_to_gregorian_seconds({{?END_YEAR, 1, 1},
@@ -72,7 +72,7 @@ day_of_the_week(doc) ->
"year ?START_YEAR up to ?END_YEAR.";
day_of_the_week(suite) ->
[];
-day_of_the_week(Config) when list(Config) ->
+day_of_the_week(Config) when is_list(Config) ->
?line Days = calendar:date_to_gregorian_days({?START_YEAR, 1, 1}),
?line MaxDays = calendar:date_to_gregorian_days({?END_YEAR, 1, 1}),
?line DayNumber = calendar:day_of_the_week({?START_YEAR, 1, 1}),
@@ -82,7 +82,7 @@ day_of_the_week_calibrate(doc) ->
"Tests that day_of_the_week for 1997-11-11 is Tuesday (2)";
day_of_the_week_calibrate(suite) ->
[];
-day_of_the_week_calibrate(Config) when list(Config) ->
+day_of_the_week_calibrate(Config) when is_list(Config) ->
?line 2 = calendar:day_of_the_week({1997, 11, 11}).
leap_years(doc) ->
@@ -90,7 +90,7 @@ leap_years(doc) ->
"year ?START_YEAR up to ?END_YEAR.";
leap_years(suite) ->
[];
-leap_years(Config) when list(Config) ->
+leap_years(Config) when is_list(Config) ->
?line check_leap_years(?START_YEAR, ?END_YEAR).
last_day_of_the_month(doc) ->
@@ -98,14 +98,14 @@ last_day_of_the_month(doc) ->
"year ?START_YEAR up to ?END_YEAR.";
last_day_of_the_month(suite) ->
[];
-last_day_of_the_month(Config) when list(Config) ->
+last_day_of_the_month(Config) when is_list(Config) ->
?line check_last_day_of_the_month({?START_YEAR, 1}, {?END_YEAR, 1}).
local_time_to_universal_time_dst(doc) ->
"Tests local_time_to_universal_time_dst for MET";
local_time_to_universal_time_dst(suite) ->
[];
-local_time_to_universal_time_dst(Config) when list(Config) ->
+local_time_to_universal_time_dst(Config) when is_list(Config) ->
case os:type() of
{unix,_} ->
case os:cmd("date '+%Z'") of
@@ -117,7 +117,7 @@ local_time_to_universal_time_dst(Config) when list(Config) ->
_ ->
local_time_to_universal_time_dst_x(Config)
end.
-local_time_to_universal_time_dst_x(Config) when list(Config) ->
+local_time_to_universal_time_dst_x(Config) when is_list(Config) ->
%% Assumes MET (UTC+1 / UTC+2(dst)
?line LtW = {{2003,01,15},{14,00,00}}, % Winter
?line UtW = {{2003,01,15},{13,00,00}}, %
diff --git a/lib/stdlib/test/edlin_expand_SUITE.erl b/lib/stdlib/test/edlin_expand_SUITE.erl
new file mode 100644
index 0000000000..613bfd000e
--- /dev/null
+++ b/lib/stdlib/test/edlin_expand_SUITE.erl
@@ -0,0 +1,156 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 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(edlin_expand_SUITE).
+-export([all/1]).
+
+-export([normal/1, quoted_fun/1, quoted_module/1, quoted_both/1]).
+
+-export([init_per_testcase/2, fin_per_testcase/2]).
+
+-include("test_server.hrl").
+
+% Default timetrap timeout (set in init_per_testcase).
+-define(default_timeout, ?t:minutes(1)).
+
+init_per_testcase(_Case, Config) ->
+ ?line Dog = ?t:timetrap(?default_timeout),
+ [{watchdog, Dog} | Config].
+fin_per_testcase(_Case, Config) ->
+ Dog = ?config(watchdog, Config),
+ test_server:timetrap_cancel(Dog),
+ ok.
+
+all(doc) ->
+ ["Test cases for edlin_expand."];
+all(suite) ->
+ [normal, quoted_fun, quoted_module, quoted_both].
+
+normal(doc) ->
+ [""];
+normal(suite) ->
+ [];
+normal(Config) when is_list(Config) ->
+ ?line {module,expand_test} = c:l(expand_test),
+ % These tests might fail if another module with the prefix "expand_" happens
+ % to also be loaded.
+ ?line {yes, "test:", []} = edlin_expand:expand(lists:reverse("expand_")),
+ ?line {no, [], []} = edlin_expand:expand(lists:reverse("expandXX_")),
+ ?line {no,[],
+ [{"a_fun_name",1},
+ {"a_less_fun_name",1},
+ {"b_comes_after_a",1},
+ {"module_info",0},
+ {"module_info",1}]} = edlin_expand:expand(lists:reverse("expand_test:")),
+ ?line {yes,[],[{"a_fun_name",1},
+ {"a_less_fun_name",1}]} = edlin_expand:expand(
+ lists:reverse("expand_test:a_")),
+ ok.
+
+quoted_fun(doc) ->
+ ["Normal module name, some function names using quoted atoms"];
+quoted_fun(suite) ->
+ [];
+quoted_fun(Config) when is_list(Config) ->
+ ?line {module,expand_test} = c:l(expand_test),
+ ?line {module,expand_test1} = c:l(expand_test1),
+ %% should be no colon after test this time
+ ?line {yes, "test", []} = edlin_expand:expand(lists:reverse("expand_")),
+ ?line {no, [], []} = edlin_expand:expand(lists:reverse("expandXX_")),
+ ?line {no,[],[{"'#weird-fun-name'",0},
+ {"'Quoted_fun_name'",0},
+ {"'Quoted_fun_too'",0},
+ {"a_fun_name",1},
+ {"a_less_fun_name",1},
+ {"b_comes_after_a",1},
+ {"module_info",0},
+ {"module_info",1}]} = edlin_expand:expand(
+ lists:reverse("expand_test1:")),
+ ?line {yes,"_",[]} = edlin_expand:expand(
+ lists:reverse("expand_test1:a")),
+ ?line {yes,[],[{"a_fun_name",1},
+ {"a_less_fun_name",1}]} = edlin_expand:expand(
+ lists:reverse("expand_test1:a_")),
+ ?line {yes,[],
+ [{"'#weird-fun-name'",0},
+ {"'Quoted_fun_name'",0},
+ {"'Quoted_fun_too'",0}]} = edlin_expand:expand(
+ lists:reverse("expand_test1:'")),
+ ?line {yes,"uoted_fun_",[]} = edlin_expand:expand(
+ lists:reverse("expand_test1:'Q")),
+ ?line {yes,[],
+ [{"'Quoted_fun_name'",0},
+ {"'Quoted_fun_too'",0}]} = edlin_expand:expand(
+ lists:reverse("expand_test1:'Quoted_fun_")),
+ ?line {yes,"weird-fun-name'(",[]} = edlin_expand:expand(
+ lists:reverse("expand_test1:'#")),
+ ok.
+
+quoted_module(doc) ->
+ [""];
+quoted_module(suite) ->
+ [];
+quoted_module(Config) when is_list(Config) ->
+ ?line {module,'ExpandTestCaps'} = c:l('ExpandTestCaps'),
+ ?line {yes, "Caps':", []} = edlin_expand:expand(lists:reverse("'ExpandTest")),
+ ?line {no,[],
+ [{"a_fun_name",1},
+ {"a_less_fun_name",1},
+ {"b_comes_after_a",1},
+ {"module_info",0},
+ {"module_info",1}]} = edlin_expand:expand(lists:reverse("'ExpandTestCaps':")),
+ ?line {yes,[],[{"a_fun_name",1},
+ {"a_less_fun_name",1}]} = edlin_expand:expand(
+ lists:reverse("'ExpandTestCaps':a_")),
+ ok.
+
+quoted_both(suite) ->
+ [];
+quoted_both(Config) when is_list(Config) ->
+ ?line {module,'ExpandTestCaps'} = c:l('ExpandTestCaps'),
+ ?line {module,'ExpandTestCaps1'} = c:l('ExpandTestCaps1'),
+ %% should be no colon (or quote) after test this time
+ ?line {yes, "Caps", []} = edlin_expand:expand(lists:reverse("'ExpandTest")),
+ ?line {no,[],[{"'#weird-fun-name'",0},
+ {"'Quoted_fun_name'",0},
+ {"'Quoted_fun_too'",0},
+ {"a_fun_name",1},
+ {"a_less_fun_name",1},
+ {"b_comes_after_a",1},
+ {"module_info",0},
+ {"module_info",1}]} = edlin_expand:expand(
+ lists:reverse("'ExpandTestCaps1':")),
+ ?line {yes,"_",[]} = edlin_expand:expand(
+ lists:reverse("'ExpandTestCaps1':a")),
+ ?line {yes,[],[{"a_fun_name",1},
+ {"a_less_fun_name",1}]} = edlin_expand:expand(
+ lists:reverse("'ExpandTestCaps1':a_")),
+ ?line {yes,[],
+ [{"'#weird-fun-name'",0},
+ {"'Quoted_fun_name'",0},
+ {"'Quoted_fun_too'",0}]} = edlin_expand:expand(
+ lists:reverse("'ExpandTestCaps1':'")),
+ ?line {yes,"uoted_fun_",[]} = edlin_expand:expand(
+ lists:reverse("'ExpandTestCaps1':'Q")),
+ ?line {yes,[],
+ [{"'Quoted_fun_name'",0},
+ {"'Quoted_fun_too'",0}]} = edlin_expand:expand(
+ lists:reverse("'ExpandTestCaps1':'Quoted_fun_")),
+ ?line {yes,"weird-fun-name'(",[]} = edlin_expand:expand(
+ lists:reverse("'ExpandTestCaps1':'#")),
+ ok.
diff --git a/lib/stdlib/test/epp_SUITE.erl b/lib/stdlib/test/epp_SUITE.erl
index 67e20fd2e1..9a3ae0baf5 100644
--- a/lib/stdlib/test/epp_SUITE.erl
+++ b/lib/stdlib/test/epp_SUITE.erl
@@ -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%
-module(epp_SUITE).
@@ -23,7 +23,7 @@
upcase_mac/1, upcase_mac_1/1, upcase_mac_2/1,
variable/1, variable_1/1, otp_4870/1, otp_4871/1, otp_5362/1,
pmod/1, not_circular/1, skip_header/1, otp_6277/1, otp_7702/1,
- otp_8130/1]).
+ otp_8130/1, overload_mac/1, otp_8388/1]).
-export([epp_parse_erl_form/2]).
@@ -61,8 +61,9 @@ fin_per_testcase(_, Config) ->
all(doc) ->
["Test cases for epp."];
all(suite) ->
- [rec_1, upcase_mac, predef_mac, variable, otp_4870, otp_4871, otp_5362,
- pmod, not_circular, skip_header, otp_6277, otp_7702, otp_8130].
+ [rec_1, upcase_mac, predef_mac, variable, otp_4870, otp_4871, otp_5362,
+ pmod, not_circular, skip_header, otp_6277, otp_7702, otp_8130,
+ overload_mac, otp_8388].
rec_1(doc) ->
["Recursive macros hang or crash epp (OTP-1398)."];
@@ -466,7 +467,7 @@ otp_6277(Config) when is_list(Config) ->
-define(ASSERT, ?MODULE).
?ASSERT().">>,
- [{error,{{4,16},epp,{undefined,'MODULE'}}}]}],
+ [{error,{{4,16},epp,{undefined,'MODULE', none}}}]}],
?line [] = check(Config, Ts),
ok.
@@ -673,7 +674,7 @@ otp_8130(Config) when is_list(Config) ->
{otp_8130_c7,
<<"\nt() -> ?A.\n">>,
- {errors,[{{2,9},epp,{undefined,'A'}}],[]}},
+ {errors,[{{2,9},epp,{undefined,'A', none}}],[]}},
{otp_8130_c8,
<<"\n-include_lib(\"$apa/foo.hrl\").\n">>,
@@ -683,7 +684,7 @@ otp_8130(Config) when is_list(Config) ->
{otp_8130_c9,
<<"-define(S, ?S).\n"
"t() -> ?S.\n">>,
- {errors,[{{2,9},epp,{circular,'S'}}],[]}},
+ {errors,[{{2,9},epp,{circular,'S', none}}],[]}},
{otp_8130_c10,
<<"\n-file.">>,
@@ -718,22 +719,22 @@ otp_8130(Config) when is_list(Config) ->
{otp_8130_c17,
<<"\n-define(A(B), B).\n"
"-define(A, 1).\n">>,
- {errors,[{{3,9},epp,{redefine,'A'}}],[]}},
+ []},
{otp_8130_c18,
<<"\n-define(A, 1).\n"
"-define(A(B), B).\n">>,
- {errors,[{{3,9},epp,{redefine,'A'}}],[]}},
+ []},
{otp_8130_c19,
<<"\n-define(a(B), B).\n"
"-define(a, 1).\n">>,
- {errors,[{{3,9},epp,{redefine,a}}],[]}},
+ []},
{otp_8130_c20,
<<"\n-define(a, 1).\n"
"-define(a(B), B).\n">>,
- {errors,[{{3,9},epp,{redefine,a}}],[]}},
+ []},
{otp_8130_c21,
<<"\n-define(A(B, B), B).\n">>,
@@ -745,7 +746,7 @@ otp_8130(Config) when is_list(Config) ->
{otp_8130_c23,
<<"\n-file(?b, 3).\n">>,
- {errors,[{{2,8},epp,{undefined,b}}],[]}},
+ {errors,[{{2,8},epp,{undefined,b, none}}],[]}},
{otp_8130_c24,
<<"\n-include(\"no such file.erl\").\n">>,
@@ -821,7 +822,8 @@ macs(Epp) ->
macro(Epp, N) ->
case lists:keyfind({atom,N}, 1, epp:macro_defs(Epp)) of
false -> false;
- {{atom,N},{_,V}} -> V
+ {{atom,N},{_,V}} -> V;
+ {{atom,N},Defs} -> lists:append([V || {_,{_,V}} <- Defs])
end.
ifdef(Config) ->
@@ -1030,6 +1032,113 @@ ifdef(Config) ->
],
?line [] = run(Config, Ts).
+
+
+overload_mac(doc) ->
+ ["Advanced test on overloading macros."];
+overload_mac(suite) ->
+ [];
+overload_mac(Config) when is_list(Config) ->
+ Cs = [
+ %% '-undef' removes all definitions of a macro
+ {overload_mac_c1,
+ <<"-define(A, a).\n"
+ "-define(A(X), X).\n"
+ "-undef(A).\n"
+ "t1() -> ?A.\n",
+ "t2() -> ?A(1).">>,
+ {errors,[{{4,9},epp,{undefined,'A', none}},
+ {{5,9},epp,{undefined,'A', 1}}],[]}},
+
+ %% cannot overload predefined macros
+ {overload_mac_c2,
+ <<"-define(MODULE(X), X).">>,
+ {errors,[{{1,9},epp,{redefine_predef,'MODULE'}}],[]}},
+
+ %% cannot overload macros with same arity
+ {overload_mac_c3,
+ <<"-define(A(X), X).\n"
+ "-define(A(Y), Y).">>,
+ {errors,[{{2,9},epp,{redefine,'A'}}],[]}},
+
+ {overload_mac_c4,
+ <<"-define(A, a).\n"
+ "-define(A(X,Y), {X,Y}).\n"
+ "a(X) -> X.\n"
+ "t() -> ?A(1).">>,
+ {errors,[{{4,9},epp,{mismatch,'A'}}],[]}}
+ ],
+ ?line [] = compile(Config, Cs),
+
+ Ts = [
+ {overload_mac_r1,
+ <<"-define(A, 1).\n"
+ "-define(A(X), X).\n"
+ "-define(A(X, Y), {X, Y}).\n"
+ "t() -> {?A, ?A(2), ?A(3, 4)}.">>,
+ {1, 2, {3, 4}}},
+
+ {overload_mac_r2,
+ <<"-define(A, 1).\n"
+ "-define(A(X), X).\n"
+ "t() -> ?A(?A).">>,
+ 1},
+
+ {overload_mac_r3,
+ <<"-define(A, ?B).\n"
+ "-define(B, a).\n"
+ "-define(B(X), {b,X}).\n"
+ "a(X) -> X.\n"
+ "t() -> ?A(1).">>,
+ 1}
+ ],
+ ?line [] = run(Config, Ts).
+
+
+otp_8388(doc) ->
+ ["OTP-8388. More tests on overloaded macros."];
+otp_8388(suite) ->
+ [];
+otp_8388(Config) when is_list(Config) ->
+ Dir = ?config(priv_dir, Config),
+ ?line File = filename:join(Dir, "otp_8388.erl"),
+ ?line ok = file:write_file(File, <<"-module(otp_8388)."
+ "-define(LINE, a).">>),
+ fun() ->
+ PreDefMacros = [{'LINE', a}],
+ ?line {error,{redefine_predef,'LINE'}} =
+ epp:open(File, [], PreDefMacros)
+ end(),
+
+ fun() ->
+ PreDefMacros = ['LINE'],
+ ?line {error,{redefine_predef,'LINE'}} =
+ epp:open(File, [], PreDefMacros)
+ end(),
+
+ Ts = [
+ {macro_1,
+ <<"-define(m(A), A).\n"
+ "t() -> ?m(,).\n">>,
+ {errors,[{{2,11},epp,{arg_error,m}}],[]}},
+ {macro_2,
+ <<"-define(m(A), A).\n"
+ "t() -> ?m(a,).\n">>,
+ {errors,[{{2,12},epp,{arg_error,m}}],[]}},
+ {macro_3,
+ <<"-define(LINE, a).\n">>,
+ {errors,[{{1,9},epp,{redefine_predef,'LINE'}}],[]}},
+ {macro_4,
+ <<"-define(A(B, C, D), {B,C,D}).\n"
+ "t() -> ?A(a,,3).\n">>,
+ {errors,[{{2,8},epp,{mismatch,'A'}}],[]}},
+ {macro_5,
+ <<"-define(Q, {?F0(), ?F1(,,4)}).\n">>,
+ {errors,[{{1,24},epp,{arg_error,'F1'}}],[]}}
+ ],
+ ?line [] = compile(Config, Ts),
+ ok.
+
check(Config, Tests) ->
eval_tests(Config, fun check_test/2, Tests).
diff --git a/lib/stdlib/test/erl_lint_SUITE.erl b/lib/stdlib/test/erl_lint_SUITE.erl
index bfbd7b3dc1..8581b496aa 100644
--- a/lib/stdlib/test/erl_lint_SUITE.erl
+++ b/lib/stdlib/test/erl_lint_SUITE.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 1999-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 1999-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(erl_lint_SUITE).
@@ -2597,7 +2597,7 @@ otp_8051(Config) when is_list(Config) ->
<<"-opaque foo() :: bar().
">>,
[],
- {error,[{1,erl_lint,{type_ref,{bar,0}}}],
+ {error,[{1,erl_lint,{undefined_type,{bar,0}}}],
[{1,erl_lint,{unused_type,{foo,0}}}]}}],
?line [] = run(Config, Ts),
ok.
diff --git a/lib/stdlib/test/ets_SUITE.erl b/lib/stdlib/test/ets_SUITE.erl
index 6016bc9bdc..13c87ca005 100644
--- a/lib/stdlib/test/ets_SUITE.erl
+++ b/lib/stdlib/test/ets_SUITE.erl
@@ -1,19 +1,19 @@
%%
%% %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
%% 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(ets_SUITE).
@@ -4530,10 +4530,16 @@ meta_wb(Config) when is_list(Config) ->
meta_wb_do(Opts) ->
%% Do random new/delete/rename of colliding named tables
- Names = [pioneer | colliding_names(pioneer)],
+ Names0 = [pioneer | colliding_names(pioneer)],
+
+ %% Remove any names that happen to exist as tables already
+ Names = lists:filter(fun(Name) -> ets:info(Name) == undefined end,
+ Names0),
Len = length(Names),
OpFuns = {fun meta_wb_new/4, fun meta_wb_delete/4, fun meta_wb_rename/4},
+ ?line true = (Len >= 3),
+
io:format("Colliding names = ~p\n",[Names]),
F = fun(0,_,_) -> ok;
(N,Tabs,Me) -> Name1 = lists:nth(random:uniform(Len),Names),
diff --git a/lib/stdlib/test/ets_tough_SUITE.erl b/lib/stdlib/test/ets_tough_SUITE.erl
index e3d44d00b9..4c8d941f13 100644
--- a/lib/stdlib/test/ets_tough_SUITE.erl
+++ b/lib/stdlib/test/ets_tough_SUITE.erl
@@ -1,19 +1,19 @@
%%
%% %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
%% 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(ets_tough_SUITE).
@@ -40,7 +40,7 @@ fin_per_testcase(_Func, Config) ->
ets:delete(?GLOBAL_PARAMS).
-ex1(Config) when list(Config) ->
+ex1(Config) when is_list(Config) ->
?line ets:new(?GLOBAL_PARAMS,[named_table,public]),
?line ets:insert(?GLOBAL_PARAMS,{a,set}),
?line ets:insert(?GLOBAL_PARAMS,{b,set}),
@@ -269,7 +269,7 @@ show_entries(Fd) ->
start(DbName) ->
case gen_server:start_link(ets_tough_SUITE,{DbName,no_dump_dir},[]) of
- {ok,Pid} when pid(Pid) ->
+ {ok,Pid} when is_pid(Pid) ->
{ok, Pid};
Other ->
Other
@@ -283,7 +283,7 @@ start(DbName) ->
start(DbName,DumpDir) ->
case gen_server:start_link(ets_tough_SUITE,
{DbName,{dump_dir,DumpDir}},[]) of
- {ok,Pid} when pid(Pid) ->
+ {ok,Pid} when is_pid(Pid) ->
{ok, Pid};
Other ->
Other
@@ -1075,7 +1075,7 @@ phys_read_len(Fd) ->
phys_read_entry(Fd,Len) ->
case io:get_chars(Fd,'',Len) of
- L when list(L), length(L) == Len ->
+ L when is_list(L), length(L) == Len ->
{ok,binary_to_term(list_to_binary(L))};
Other ->
{error,{read_term,Other}}
diff --git a/lib/stdlib/test/expand_test.erl b/lib/stdlib/test/expand_test.erl
new file mode 100644
index 0000000000..63e4bc3aa0
--- /dev/null
+++ b/lib/stdlib/test/expand_test.erl
@@ -0,0 +1,32 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 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(expand_test).
+
+-export([a_fun_name/1,
+ a_less_fun_name/1,
+ b_comes_after_a/1]).
+
+a_fun_name(X) ->
+ X.
+
+a_less_fun_name(X) ->
+ X.
+
+b_comes_after_a(X) ->
+ X.
diff --git a/lib/stdlib/test/expand_test1.erl b/lib/stdlib/test/expand_test1.erl
new file mode 100644
index 0000000000..11b6fec0f3
--- /dev/null
+++ b/lib/stdlib/test/expand_test1.erl
@@ -0,0 +1,44 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 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(expand_test1).
+
+-export([a_fun_name/1,
+ a_less_fun_name/1,
+ b_comes_after_a/1,
+ 'Quoted_fun_name'/0,
+ 'Quoted_fun_too'/0,
+ '#weird-fun-name'/0]).
+
+a_fun_name(X) ->
+ X.
+
+a_less_fun_name(X) ->
+ X.
+
+b_comes_after_a(X) ->
+ X.
+
+'Quoted_fun_name'() ->
+ whoopee.
+
+'Quoted_fun_too'() ->
+ too.
+
+'#weird-fun-name'() ->
+ weird.
diff --git a/lib/stdlib/test/filelib_SUITE.erl b/lib/stdlib/test/filelib_SUITE.erl
index c9c6054f7b..d54741051f 100644
--- a/lib/stdlib/test/filelib_SUITE.erl
+++ b/lib/stdlib/test/filelib_SUITE.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2005-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 2005-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%
%%
@@ -21,7 +21,7 @@
-export([all/1,init_per_testcase/2,fin_per_testcase/2,
wildcard_one/1,wildcard_two/1,wildcard_errors/1,
- fold_files/1,otp_5960/1]).
+ fold_files/1,otp_5960/1,ensure_dir_eexist/1]).
-import(lists, [foreach/2]).
@@ -38,7 +38,8 @@ fin_per_testcase(_Case, Config) ->
ok.
all(suite) ->
- [wildcard_one,wildcard_two,wildcard_errors,fold_files,otp_5960].
+ [wildcard_one,wildcard_two,wildcard_errors,fold_files,otp_5960,
+ ensure_dir_eexist].
wildcard_one(Config) when is_list(Config) ->
?line {ok,OldCwd} = file:get_cwd(),
@@ -223,7 +224,9 @@ otp_5960(Config) when is_list(Config) ->
?line Name1 = filename:join(Dir, name1),
?line Name2 = filename:join(Dir, name2),
?line ok = filelib:ensure_dir(Name1), % parent is created
+ ?line ok = filelib:ensure_dir(Name1), % repeating it should be OK
?line ok = filelib:ensure_dir(Name2), % parent already exists
+ ?line ok = filelib:ensure_dir(Name2), % repeating it should be OK
?line Name3 = filename:join(Name1, name3),
?line {ok, FileInfo} = file:read_file_info(Dir),
case os:type() of
@@ -239,3 +242,16 @@ otp_5960(Config) when is_list(Config) ->
?line ok = file:write_file_info(Dir, #file_info{mode=Mode}),
ok
end.
+
+ensure_dir_eexist(Config) when is_list(Config) ->
+ ?line PrivDir = ?config(priv_dir, Config),
+ ?line Dir = filename:join(PrivDir, ensure_dir_eexist),
+ ?line Name = filename:join(Dir, "same_name_as_file_and_dir"),
+ ?line ok = filelib:ensure_dir(Name),
+ ?line ok = file:write_file(Name, <<"some string\n">>),
+
+ %% There already is a file with the name of the directory
+ %% we want to create.
+ ?line NeedFile = filename:join(Name, "file"),
+ ?line {error, eexist} = filelib:ensure_dir(NeedFile),
+ ok.
diff --git a/lib/stdlib/test/fixtable_SUITE.erl b/lib/stdlib/test/fixtable_SUITE.erl
index 9f21308ad4..1940ee147e 100644
--- a/lib/stdlib/test/fixtable_SUITE.erl
+++ b/lib/stdlib/test/fixtable_SUITE.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 1999-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 1999-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%
%%
%%%----------------------------------------------------------------------
@@ -83,7 +83,7 @@ fixbag(doc) ->
"incorrect lookups"];
fixbag(suite) ->
[];
-fixbag(Config) when list(Config) ->
+fixbag(Config) when is_list(Config) ->
?line T = ets:new(x,[bag]),
?line ets:insert(T,{a,1}),
?line ets:insert(T,{a,2}),
@@ -101,7 +101,7 @@ insert_same_key(doc) ->
["Check correct behaviour if a key is deleted and reinserted during fixation."];
insert_same_key(suite) ->
[];
-insert_same_key(Config) when list(Config) ->
+insert_same_key(Config) when is_list(Config) ->
?line {ok,Dets1} = dets:open_file(?DETS_TMP1,
[{file, dets_filename(?DETS_TMP1,Config)}]),
?line Ets1 = ets:new(ets,[]),
@@ -180,7 +180,7 @@ owner_dies(doc) ->
["Check correct behaviour if the table owner dies."];
owner_dies(suite) ->
[];
-owner_dies(Config) when list(Config) ->
+owner_dies(Config) when is_list(Config) ->
?line P1 = start_commander(),
?line Ets1 = command(P1,{ets,new,[ets,[]]}),
?line command(P1,{ets,safe_fixtable,[Ets1,true]}),
@@ -236,7 +236,7 @@ other_process_closes(doc) ->
other_process_closes(suite) ->
[];
-other_process_closes(Config) when list(Config) ->
+other_process_closes(Config) when is_list(Config) ->
?line {ok,Dets} = dets:open_file(?DETS_TMP1,
[{file, dets_filename(tmp1,Config)}]),
?line P2 = start_commander(),
@@ -265,7 +265,7 @@ other_process_deletes(doc) ->
"deletes an ets table"];
other_process_deletes(suite) ->
[];
-other_process_deletes(Config) when list(Config) ->
+other_process_deletes(Config) when is_list(Config) ->
?line Ets = ets:new(ets,[public]),
?line P = start_commander(),
?line ets:safe_fixtable(Ets,true),
@@ -282,7 +282,7 @@ multiple_fixes(doc) ->
["Check that multiple safe_fixtable keeps the reference counter."];
multiple_fixes(suite) ->
[];
-multiple_fixes(Config) when list(Config) ->
+multiple_fixes(Config) when is_list(Config) ->
?line {ok,Dets} = dets:open_file(?DETS_TMP1,
[{file, dets_filename(?DETS_TMP1,Config)}]),
?line Ets = ets:new(ets,[]),
@@ -317,7 +317,7 @@ multiple_processes(doc) ->
"counted OK"];
multiple_processes(suite) ->
[];
-multiple_processes(Config) when list(Config) ->
+multiple_processes(Config) when is_list(Config) ->
?line {ok,Dets} = dets:open_file(?DETS_TMP1,[{file,
dets_filename(?DETS_TMP1,
Config)}]),
@@ -370,7 +370,7 @@ multiple_processes(Tab, Mod) ->
%%% Helpers
-dets_filename(Base, Config) when atom(Base) ->
+dets_filename(Base, Config) when is_atom(Base) ->
dets_filename(atom_to_list(Base) ++ ".dat", Config);
dets_filename(Basename, Config) ->
PrivDir = ?config(priv_dir,Config),
diff --git a/lib/stdlib/test/format_SUITE.erl b/lib/stdlib/test/format_SUITE.erl
index 2c415894f4..1c9e953003 100644
--- a/lib/stdlib/test/format_SUITE.erl
+++ b/lib/stdlib/test/format_SUITE.erl
@@ -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%
%%
-module(format_SUITE).
@@ -45,7 +45,7 @@ hang_1(doc) ->
["Bad args can hang (OTP-2400)"];
hang_1(suite) ->
[];
-hang_1(Config) when list(Config) ->
+hang_1(Config) when is_list(Config) ->
?line _ = (catch io:format(a, "", [])),
?line _ = (catch io:format({}, "", [])),
ok.
diff --git a/lib/stdlib/test/gen_event_SUITE.erl b/lib/stdlib/test/gen_event_SUITE.erl
index dc5ddebf53..8cbffaca56 100644
--- a/lib/stdlib/test/gen_event_SUITE.erl
+++ b/lib/stdlib/test/gen_event_SUITE.erl
@@ -1,19 +1,19 @@
%%
%% %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
%% 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(gen_event_SUITE).
@@ -33,7 +33,7 @@ all(suite) -> {req, [stdlib], [start, test_all, hibernate]}.
start(doc) -> [];
start(suite) -> [];
-start(Config) when list(Config) ->
+start(Config) when is_list(Config) ->
OldFl = process_flag(trap_exit, true),
?line {ok, Pid0} = gen_event:start(), %anonymous
@@ -175,7 +175,7 @@ test_all(suite) -> [add_handler, add_sup_handler, delete_handler,
add_handler(doc) -> [];
add_handler(suite) -> [];
-add_handler(Config) when list(Config) ->
+add_handler(Config) when is_list(Config) ->
?line {ok,_} = gen_event:start({local, my_dummy_handler}),
?line {error, my_error} =
gen_event:add_handler(my_dummy_handler, dummy_h, make_error),
@@ -196,7 +196,7 @@ add_handler(Config) when list(Config) ->
add_sup_handler(doc) -> [];
add_sup_handler(suite) -> [];
-add_sup_handler(Config) when list(Config) ->
+add_sup_handler(Config) when is_list(Config) ->
?line {ok,Pid} = gen_event:start({local, my_dummy_handler}),
?line {error, my_error} =
gen_event:add_sup_handler(my_dummy_handler, dummy_h, make_error),
@@ -238,7 +238,7 @@ add_sup_handler(Config) when list(Config) ->
delete_handler(doc) -> [];
delete_handler(suite) -> [];
-delete_handler(Config) when list(Config) ->
+delete_handler(Config) when is_list(Config) ->
?line {ok,_} = gen_event:start({local, my_dummy_handler}),
?line ok = gen_event:add_handler(my_dummy_handler, dummy_h, [self()]),
?line {error, module_not_found} =
@@ -270,7 +270,7 @@ delete_handler(Config) when list(Config) ->
swap_handler(doc) -> [];
swap_handler(suite) -> [];
-swap_handler(Config) when list(Config) ->
+swap_handler(Config) when is_list(Config) ->
?line {ok,_} = gen_event:start({local, my_dummy_handler}),
?line ok = gen_event:add_handler(my_dummy_handler, dummy_h, [self()]),
?line {error, non_existing} =
@@ -299,7 +299,7 @@ swap_handler(Config) when list(Config) ->
swap_sup_handler(doc) -> [];
swap_sup_handler(suite) -> [];
-swap_sup_handler(Config) when list(Config) ->
+swap_sup_handler(Config) when is_list(Config) ->
?line {ok,_} = gen_event:start({local, my_dummy_handler}),
?line ok = gen_event:add_sup_handler(my_dummy_handler, dummy_h, [self()]),
?line {error, non_existing} =
@@ -341,7 +341,7 @@ swap_sup_handler(Config) when list(Config) ->
notify(doc) -> [];
notify(suite) -> [];
-notify(Config) when list(Config) ->
+notify(Config) when is_list(Config) ->
?line {ok,_} = gen_event:start({local, my_dummy_handler}),
?line ok = gen_event:add_handler(my_dummy_handler, dummy_h, [self()]),
Event = {event, self()},
@@ -457,7 +457,7 @@ notify(Config) when list(Config) ->
sync_notify(doc) -> [];
sync_notify(suite) -> [];
-sync_notify(Config) when list(Config) ->
+sync_notify(Config) when is_list(Config) ->
?line {ok,_} = gen_event:start({local, my_dummy_handler}),
?line ok = gen_event:add_handler(my_dummy_handler, dummy_h, [self()]),
Event = {event, self()},
@@ -576,7 +576,7 @@ sync_notify(Config) when list(Config) ->
call(doc) -> [];
call(suite) -> [];
-call(Config) when list(Config) ->
+call(Config) when is_list(Config) ->
?line {ok,_} = gen_event:start({local, my_dummy_handler}),
?line ok = gen_event:add_handler(my_dummy_handler, dummy_h, [self()]),
?line ok = gen_event:add_handler(my_dummy_handler, {dummy_h, 1}, [self()]),
@@ -718,7 +718,7 @@ flush() ->
info(doc) -> [];
info(suite) -> [];
-info(Config) when list(Config) ->
+info(Config) when is_list(Config) ->
?line {ok,_} = gen_event:start({local, my_dummy_handler}),
?line ok = gen_event:add_handler(my_dummy_handler, dummy_h, [self()]),
Info = {info, self()},
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/stdlib/test/io_proto_SUITE.erl b/lib/stdlib/test/io_proto_SUITE.erl
index 46407193d7..93159fbd5b 100644
--- a/lib/stdlib/test/io_proto_SUITE.erl
+++ b/lib/stdlib/test/io_proto_SUITE.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(io_proto_SUITE).
@@ -23,7 +23,7 @@
-export([init_per_testcase/2, fin_per_testcase/2]).
-export([setopts_getopts/1,unicode_options/1,unicode_options_gen/1, binary_options/1, bc_with_r12/1,
- bc_with_r12_gl/1, read_modes_gl/1,bc_with_r12_ogl/1, read_modes_ogl/1, broken_unicode/1,eof_on_pipe/1]).
+ bc_with_r12_gl/1, read_modes_gl/1,bc_with_r12_ogl/1, read_modes_ogl/1, broken_unicode/1,eof_on_pipe/1,unicode_prompt/1]).
-export([io_server_proxy/1,start_io_server_proxy/0, proxy_getall/1, proxy_setnext/2, proxy_quit/1]).
@@ -31,6 +31,8 @@
-export([toerl_server/3,hold_the_line/3,answering_machine1/3,
answering_machine2/3]).
+-export([uprompt/1]).
+
%-define(without_test_server, true).
-ifdef(without_test_server).
@@ -43,14 +45,17 @@
-define(privdir(Conf), ?config(priv_dir, Conf)).
-endif.
-%-define(debug, true).
+-define(debug, true).
-ifdef(debug).
-define(format(S, A), io:format(S, A)).
-define(dbg(Data),io:format(standard_error, "DBG: ~p\r\n",[Data])).
+-define(RM_RF(Dir),begin io:format(standard_error, "Not Removed: ~p\r\n",[Dir]),
+ ok end).
-else.
-define(format(S, A), ok).
-define(dbg(Data),noop).
+-define(RM_RF(Dir),rm_rf(Dir)).
-endif.
@@ -79,7 +84,7 @@ all(doc) ->
all(suite) ->
[setopts_getopts, unicode_options, unicode_options_gen, binary_options, bc_with_r12,
bc_with_r12_gl,bc_with_r12_ogl, read_modes_gl, read_modes_ogl,
- broken_unicode,eof_on_pipe].
+ broken_unicode,eof_on_pipe,unicode_prompt].
-record(state, {
@@ -88,6 +93,48 @@ all(suite) ->
mode = list
}).
+uprompt(_L) ->
+ [1050,1072,1082,1074,1086,32,1077,32,85,110,105,99,111,100,101,32,63].
+
+unicode_prompt(suite) ->
+ [];
+unicode_prompt(doc) ->
+ ["Test that an Unicode prompt does not crash the shell"];
+unicode_prompt(Config) when is_list(Config) ->
+ ?line PA = filename:dirname(code:which(?MODULE)),
+ ?line rtnode([{putline,""},
+ {putline, "2."},
+ {getline, "2"},
+ {putline, "shell:prompt_func({io_proto_SUITE,uprompt})."},
+ {getline, "default"},
+ {putline, "io:get_line('')."},
+ {putline, "hej"},
+ {getline, "\"hej\\n\""},
+ {putline, "io:setopts([{binary,true}])."},
+ {getline, "ok"},
+ {putline, "io:get_line('')."},
+ {putline, "hej"},
+ {getline, "<<\"hej\\n\">>"}
+ ],[],[],"-pa "++ PA),
+ %% And one with oldshell
+ ?line rtnode([{putline,""},
+ {putline, "2."},
+ {getline_re, ".*2."},
+ {getline, "2"},
+ {putline, "shell:prompt_func({io_proto_SUITE,uprompt})."},
+ {getline_re, ".*default"},
+ {putline, "io:get_line('')."},
+ {putline, "hej"},
+ {getline_re, ".*\"hej\\\\n\""},
+ {putline, "io:setopts([{binary,true}])."},
+ {getline_re, ".*ok"},
+ {putline, "io:get_line('')."},
+ {putline, "hej"},
+ {getline_re, ".*<<\"hej\\\\n\">>"}
+ ],[],[],"-oldshell -pa "++PA),
+ ok.
+
+
setopts_getopts(suite) ->
[];
setopts_getopts(doc) ->
@@ -197,6 +244,15 @@ setopts_getopts(Config) when is_list(Config) ->
{getline_re, ".*<<\"hej\\\\n\">>"}
],[],[],"-oldshell"),
ok.
+
+
+get_lc_ctype() ->
+ case {os:type(),os:version()} of
+ {{unix,sunos},{5,N,_}} when N =< 8 ->
+ "iso_8859_1";
+ _ ->
+ "ISO-8859-1"
+ end.
unicode_options(suite) ->
[];
@@ -369,7 +425,7 @@ unicode_options(Config) when is_list(Config) ->
{getline,
binary_to_list(unicode:characters_to_binary(
[1024],unicode,utf8))}
- ],[],"LC_CTYPE=\"ISO-8859-1\"; export LC_CTYPE; "),
+ ],[],"LC_CTYPE=\""++get_lc_ctype()++"\"; export LC_CTYPE; "),
?line rtnode([{putline,""},
{putline, "2."},
{getline_re, ".*2."},
@@ -384,7 +440,7 @@ unicode_options(Config) when is_list(Config) ->
{getline_re,
".*"++binary_to_list(unicode:characters_to_binary(
[1024],unicode,utf8))}
- ],[],"LC_CTYPE=\"ISO-8859-1\"; export LC_CTYPE; ",
+ ],[],"LC_CTYPE=\""++get_lc_ctype()++"\"; export LC_CTYPE; ",
" -oldshell "),
ok.
@@ -974,7 +1030,7 @@ answering_machine1(OthNode,OthReg,Me) ->
{putline, TestDataUtf},
{getline_re, ".*Okej"}
- ],Me,"LC_CTYPE=\"ISO-8859-1\"; export LC_CTYPE; "),
+ ],Me,"LC_CTYPE=\""++get_lc_ctype()++"\"; export LC_CTYPE; "),
O = list_to_atom(OthReg),
O ! {self(),done},
ok.
@@ -1045,7 +1101,7 @@ answering_machine2(OthNode,OthReg,Me) ->
{putline, TestDataUtf},
{getline_re, ".*Okej"}
- ],Me,"LC_CTYPE=\"ISO-8859-1\"; export LC_CTYPE; "," -oldshell "),
+ ],Me,"LC_CTYPE=\""++get_lc_ctype()++"\"; export LC_CTYPE; "," -oldshell "),
O = list_to_atom(OthReg),
O ! {self(),done},
ok.
@@ -1087,7 +1143,9 @@ read_modes_gl_1(_Config,Machine) ->
[MyNodeList, "io_proto_suite", N2List]),
?line GL = receive X when is_pid(X) -> X end,
+ ?dbg({group_leader,X}),
%% get_line
+ ?line receive after 500 -> ok end, % Dont clash with the new shell...
?line "Hej\n" = io:get_line(GL,"Prompt\n"),
?line io:setopts(GL,[binary]),
?line io:format(GL,"Okej~n",[]),
@@ -1287,7 +1345,7 @@ rtnode(Commands,Nodename,ErlPrefix,Extra) ->
?line ok
end,
?line wait_for_runerl_server(SPid),
- ?line ok = rm_rf(Tempdir),
+ ?line ok = ?RM_RF(Tempdir),
?line ok = Res
end
end.
@@ -1308,7 +1366,7 @@ timeout(normal) ->
%% stop_noshell_node(Node) ->
%% test_server:stop_node(Node).
-
+-ifndef(debug).
rm_rf(Dir) ->
try
{ok,List} = file:list_dir(Dir),
@@ -1324,7 +1382,7 @@ rm_rf(Dir) ->
catch
_:Exception -> {error, {Exception,Dir}}
end.
-
+-endif.
get_and_put(_CPid,[],_) ->
ok;
@@ -1527,6 +1585,8 @@ start_runerl_node(RunErl,Erl,Tempdir,Nodename,Extra) ->
" "++Extra
end,
spawn(fun() ->
+ ?dbg(RunErl++" "++Tempdir++"/ "++Tempdir++" \""++
+ Erl++XArg++XXArg++"\""),
os:cmd(RunErl++" "++Tempdir++"/ "++Tempdir++" \""++
Erl++XArg++XXArg++"\"")
end).
diff --git a/lib/stdlib/test/ms_transform_SUITE.erl b/lib/stdlib/test/ms_transform_SUITE.erl
index cf0926b7fa..79a0a9af89 100644
--- a/lib/stdlib/test/ms_transform_SUITE.erl
+++ b/lib/stdlib/test/ms_transform_SUITE.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2003-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 2003-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(ms_transform_SUITE).
@@ -56,7 +56,7 @@ andalso_orelse(suite) ->
[];
andalso_orelse(doc) ->
["Tests that andalso and orelse are allowed in guards."];
-andalso_orelse(Config) when list(Config) ->
+andalso_orelse(Config) when is_list(Config) ->
?line setup(Config),
?line [{{'$1','$2'},
[{'and',{is_integer,'$1'},{'>',{'+','$1',5},'$2'}}],
@@ -93,7 +93,7 @@ bitsyntax(suite) ->
[];
bitsyntax(doc) ->
["Tests that bitsyntax works and does not work where appropriate"];
-bitsyntax(Config) when list(Config) ->
+bitsyntax(Config) when is_list(Config) ->
?line setup(Config),
?line [{'_',[],
[<<0,27,0,27>>]}] =
@@ -131,7 +131,7 @@ record_defaults(suite) ->
[];
record_defaults(doc) ->
["Tests that record defaults works"];
-record_defaults(Config) when list(Config) ->
+record_defaults(Config) when is_list(Config) ->
?line setup(Config),
?line [{{<<27>>,{a,5,'$1',hej,hej}},
[],
@@ -146,7 +146,7 @@ basic_ets(suite) ->
[];
basic_ets(doc) ->
["Tests basic ets:fun2ms"];
-basic_ets(Config) when list(Config) ->
+basic_ets(Config) when is_list(Config) ->
?line setup(Config),
?line [{{a,b},[],[true]}] = compile_and_run(
<<"ets:fun2ms(fun({a,b}) -> true end)">>),
@@ -167,7 +167,7 @@ basic_dbg(suite) ->
[];
basic_dbg(doc) ->
["Tests basic ets:fun2ms"];
-basic_dbg(Config) when list(Config) ->
+basic_dbg(Config) when is_list(Config) ->
?line setup(Config),
?line [{[a,b],[],[{message,banan},{return_trace}]}] =
compile_and_run(<<"dbg:fun2ms(fun([a,b]) -> message(banan), ",
@@ -186,7 +186,7 @@ from_shell(suite) ->
[];
from_shell(doc) ->
["Test calling of ets/dbg:fun2ms from the shell"];
-from_shell(Config) when list(Config) ->
+from_shell(Config) when is_list(Config) ->
?line setup(Config),
?line Fun = do_eval("fun({a,b}) -> true end"),
?line [{{a,b},[],[true]}] = apply(ets,fun2ms,[Fun]),
@@ -203,7 +203,7 @@ records(suite) ->
[];
records(doc) ->
["Tests expansion of records in fun2ms"];
-records(Config) when list(Config) ->
+records(Config) when is_list(Config) ->
?line setup(Config),
?line RD = <<"-record(t, {"
"t1 = [],"
@@ -253,7 +253,7 @@ record_index(suite) ->
[];
record_index(doc) ->
["Tests expansion of records in fun2ms, part 2"];
-record_index(Config) when list(Config) ->
+record_index(Config) when is_list(Config) ->
?line setup(Config),
?line RD = <<"-record(a,{a,b}).">>,
?line [{{2},[],[true]}] = compile_and_run(RD,
@@ -268,7 +268,7 @@ top_match(suite) ->
[];
top_match(doc) ->
["Tests matching on top level in head to give alias for object()"];
-top_match(Config) when list(Config) ->
+top_match(Config) when is_list(Config) ->
?line setup(Config),
?line RD = <<"-record(a,{a,b}).">>,
?line [{{a,3,'_'},[],['$_']}] =
@@ -295,7 +295,7 @@ multipass(suite) ->
[];
multipass(doc) ->
["Tests that multi-defined fields in records give errors."];
-multipass(Config) when list(Config) ->
+multipass(Config) when is_list(Config) ->
?line setup(Config),
?line RD = <<"-record(a,{a,b}).">>,
?line expect_failure(RD,<<"ets:fun2ms(fun(A) -> #a{a=2,a=3} end)">>),
@@ -319,7 +319,7 @@ old_guards(suite) ->
[];
old_guards(doc) ->
["Tests that old type tests in guards are translated"];
-old_guards(Config) when list(Config) ->
+old_guards(Config) when is_list(Config) ->
?line setup(Config),
Tests = [
{atom,is_atom},
@@ -382,7 +382,7 @@ autoimported(suite) ->
autoimported(doc) ->
["Tests use of autoimported bif's used like erlang:'+'(A,B) in guards"
" and body."];
-autoimported(Config) when list(Config) ->
+autoimported(Config) when is_list(Config) ->
?line setup(Config),
Allowed = [
{abs,1},
@@ -582,7 +582,7 @@ float_1_function(suite) ->
[];
float_1_function(doc) ->
["OTP-5297. The function float/1."];
-float_1_function(Config) when list(Config) ->
+float_1_function(Config) when is_list(Config) ->
?line setup(Config),
RunMS = fun(L, MS) ->
ets:match_spec_run(L, ets:match_spec_compile(MS))
diff --git a/lib/stdlib/test/queue_SUITE.erl b/lib/stdlib/test/queue_SUITE.erl
index ec3080baa0..2cd6b52311 100644
--- a/lib/stdlib/test/queue_SUITE.erl
+++ b/lib/stdlib/test/queue_SUITE.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 1999-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 1999-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(queue_SUITE).
@@ -45,7 +45,7 @@ do(doc) ->
[""];
do(suite) ->
[];
-do(Config) when list(Config) ->
+do(Config) when is_list(Config) ->
?line L = [{in, 1},
{in, 2},
{out, {value, 1}},
@@ -66,7 +66,7 @@ to_list(doc) ->
["OTP-2701"];
to_list(suite) ->
[];
-to_list(Config) when list(Config) ->
+to_list(Config) when is_list(Config) ->
?line E = queue:new(),
?line Q = do_queue(E, [{in, 1},
{in, 2},
@@ -104,7 +104,7 @@ io_test(doc) ->
"Test input and output";
io_test(suite) ->
[];
-io_test(Config) when list(Config) ->
+io_test(Config) when is_list(Config) ->
E = queue:new(),
do_io_test(E),
ok.
@@ -284,7 +284,7 @@ op_test(doc) ->
"Test operations on whole queues";
op_test(suite) ->
[];
-op_test(Config) when list(Config) ->
+op_test(Config) when is_list(Config) ->
do_op_test(fun id/1),
ok.
@@ -382,7 +382,7 @@ error(doc) ->
"Test queue errors";
error(suite) ->
[];
-error(Config) when list(Config) ->
+error(Config) when is_list(Config) ->
do_error(fun id/1, illegal_queue),
do_error(fun id/1, {[],illegal_queue}),
do_error(fun id/1, {illegal_queue,[17]}),
@@ -449,7 +449,7 @@ oops(doc) ->
"Test queue errors";
oops(suite) ->
[];
-oops(Config) when list(Config) ->
+oops(Config) when is_list(Config) ->
?line N = 3142,
?line Optab = optab(),
?line Seed0 = random:seed0(),
diff --git a/lib/stdlib/test/re_SUITE.erl b/lib/stdlib/test/re_SUITE.erl
index 98eb66d1fb..02683f9f1a 100644
--- a/lib/stdlib/test/re_SUITE.erl
+++ b/lib/stdlib/test/re_SUITE.erl
@@ -1,29 +1,29 @@
%%
%% %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%
%%
-module(re_SUITE).
--export([all/1, pcre/1,compile_options/1,run_options/1,combined_options/1,replace_autogen/1,global_capture/1,replace_return/1,split_autogen/1,split_options/1,split_specials/1,error_handling/1]).
+-export([all/1, pcre/1,compile_options/1,run_options/1,combined_options/1,replace_autogen/1,global_capture/1,replace_input_types/1,replace_return/1,split_autogen/1,split_options/1,split_specials/1,error_handling/1,pcre_cve_2008_2371/1]).
-include("test_server.hrl").
-include_lib("kernel/include/file.hrl").
-all(suite) -> [pcre,compile_options,run_options,combined_options,replace_autogen,global_capture,replace_return,split_autogen,split_options,split_specials,error_handling].
+all(suite) -> [pcre,compile_options,run_options,combined_options,replace_autogen,global_capture,replace_input_types,replace_return,split_autogen,split_options,split_specials,error_handling,pcre_cve_2008_2371].
pcre(doc) ->
["Run all applicable tests from the PCRE testsuites."];
@@ -268,7 +268,17 @@ global_capture(Config) when is_list(Config) ->
?line {match,[[{3,5},{5,3}],[{11,4},{12,3}]]} = re:run("ABC�bcdABCabcdA",".(?<FOO>bcd)",[global,{capture,all,index},unicode]),
?t:timetrap_cancel(Dog),
ok.
-
+
+replace_input_types(doc) ->
+ ["Tests replace with different input types"];
+replace_input_types(Config) when is_list(Config) ->
+ Dog = ?t:timetrap(?t:minutes(3)),
+ ?line <<"abcd">> = re:replace("abcd","Z","X",[{return,binary},unicode]),
+ ?line <<"abcd">> = re:replace("abcd","\x{400}","X",[{return,binary},unicode]),
+ ?line <<"a",208,128,"cd">> = re:replace(<<"abcd">>,"b","\x{400}",[{return,binary},unicode]),
+ ?t:timetrap_cancel(Dog),
+ ok.
+
replace_return(doc) ->
["Tests return options of replace together with global searching"];
replace_return(Config) when is_list(Config) ->
@@ -289,6 +299,10 @@ replace_return(Config) when is_list(Config) ->
?line <<"iXk">> = re:replace("abcdefghijk","(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)","\\9X",[{return,binary}]),
?line <<"jXk">> = re:replace("abcdefghijk","(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)","\\10X",[{return,binary}]),
?line <<"Xk">> = re:replace("abcdefghijk","(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)","\\11X",[{return,binary}]),
+ ?line "a\x{400}bcX" = re:replace("a\x{400}bcd","d","X",[global,{return,list},unicode]),
+ ?line <<"a",208,128,"bcX">> = re:replace("a\x{400}bcd","d","X",[global,{return,binary},unicode]),
+ ?line "a\x{400}bcd" = re:replace("a\x{400}bcd","Z","X",[global,{return,list},unicode]),
+ ?line <<"a",208,128,"bcd">> = re:replace("a\x{400}bcd","Z","X",[global,{return,binary},unicode]),
?t:timetrap_cancel(Dog),
ok.
@@ -524,3 +538,9 @@ error_handling(Config) when is_list(Config) ->
?t:timetrap_cancel(Dog),
ok.
+pcre_cve_2008_2371(doc) ->
+ "Fix as in http://vcs.pcre.org/viewvc?revision=360&view=revision";
+pcre_cve_2008_2371(Config) when is_list(Config) ->
+ %% Make sure it doesn't crash the emulator.
+ re:compile(<<"(?i)[\xc3\xa9\xc3\xbd]|[\xc3\xa9\xc3\xbdA]">>, [unicode]),
+ ok.
diff --git a/lib/stdlib/test/re_SUITE_data/mod_testoutput8 b/lib/stdlib/test/re_SUITE_data/mod_testoutput8
new file mode 100644
index 0000000000..b7e7b02d6c
--- /dev/null
+++ b/lib/stdlib/test/re_SUITE_data/mod_testoutput8
@@ -0,0 +1,877 @@
+/-- Do not use the \x{} construct except with patterns that have the --/
+/-- /8 option set, because PCRE doesn't recognize them as UTF-8 unless --/
+No match
+/-- that option is set. However, the latest Perls recognize them always. --/
+No match
+
+\x{100}ab/8
+ \x{100}ab
+ 0: \x{100}ab
+
+/a\x{100}*b/8
+ ab
+ 0: ab
+ a\x{100}b
+ 0: a\x{100}b
+ a\x{100}\x{100}b
+ 0: a\x{100}\x{100}b
+
+/a\x{100}+b/8
+ a\x{100}b
+ 0: a\x{100}b
+ a\x{100}\x{100}b
+ 0: a\x{100}\x{100}b
+ *** Failers
+No match
+ ab
+No match
+
+/\bX/8
+ Xoanon
+ 0: X
+ +Xoanon
+ 0: X
+ \x{300}Xoanon
+ 0: X
+ *** Failers
+No match
+ YXoanon
+No match
+
+/\BX/8
+ YXoanon
+ 0: X
+ *** Failers
+No match
+ Xoanon
+No match
+ +Xoanon
+No match
+ \x{300}Xoanon
+No match
+
+/X\b/8
+ X+oanon
+ 0: X
+ ZX\x{300}oanon
+ 0: X
+ FAX
+ 0: X
+ *** Failers
+No match
+ Xoanon
+No match
+
+/X\B/8
+ Xoanon
+ 0: X
+ *** Failers
+No match
+ X+oanon
+No match
+ ZX\x{300}oanon
+No match
+ FAX
+No match
+
+/[^a]/8
+ abcd
+ 0: b
+ a\x{100}
+ 0: \x{100}
+
+/^[abc\x{123}\x{400}-\x{402}]{2,3}\d/8
+ ab99
+ 0: ab9
+ \x{123}\x{123}45
+ 0: \x{123}\x{123}4
+ \x{400}\x{401}\x{402}6
+ 0: \x{400}\x{401}\x{402}6
+ *** Failers
+No match
+ d99
+No match
+ \x{123}\x{122}4
+No match
+ \x{400}\x{403}6
+No match
+ \x{400}\x{401}\x{402}\x{402}6
+No match
+
+/abc/8
+ �]
+Error -10
+ �
+Error -10
+ ���
+Error -10
+ ���\?
+No match
+
+/a.b/8
+ acb
+ 0: acb
+ a\x7fb
+ 0: a\x{7f}b
+ a\x{100}b
+ 0: a\x{100}b
+ *** Failers
+No match
+ a\nb
+No match
+
+/^[a\x{c0}]/8
+ *** Failers
+No match
+ \x{100}
+No match
+
+/(?<=aXb)cd/8
+ aXbcd
+ 0: cd
+
+/(?<=a\x{100}b)cd/8
+ a\x{100}bcd
+ 0: cd
+
+/(?<=a\x{100000}b)cd/8
+ a\x{100000}bcd
+ 0: cd
+
+/(?:\x{100}){3}b/8
+ \x{100}\x{100}\x{100}b
+ 0: \x{100}\x{100}\x{100}b
+ *** Failers
+No match
+ \x{100}\x{100}b
+No match
+
+/\x{ab}/8
+ \x{ab}
+ 0: \x{ab}
+ \xc2\xab
+ 0: \x{ab}
+ *** Failers
+No match
+ \x00{ab}
+No match
+
+/^[^a]{2}/8
+ \x{100}bc
+ 0: \x{100}b
+
+/^[^a]{2,}/8
+ \x{100}bcAa
+ 0: \x{100}bcA
+
+/^[^a]{2,}?/8
+ \x{100}bca
+ 0: \x{100}b
+
+/^[^a]{2}/8i
+ \x{100}bc
+ 0: \x{100}b
+
+/^[^a]{2,}/8i
+ \x{100}bcAa
+ 0: \x{100}bc
+
+/^[^a]{2,}?/8iU
+ \x{100}bca
+ 0: \x{100}bc
+
+/\x{100}{0,0}/8
+ abcd
+ 0:
+
+/\x{100}?/8
+ abcd
+ 0:
+ \x{100}\x{100}
+ 0: \x{100}
+
+/\x{100}{0,3}/8
+ \x{100}\x{100}
+ 0: \x{100}\x{100}
+ \x{100}\x{100}\x{100}\x{100}
+ 0: \x{100}\x{100}\x{100}
+
+/\x{100}*/8
+ abce
+ 0:
+ \x{100}\x{100}\x{100}\x{100}
+ 0: \x{100}\x{100}\x{100}\x{100}
+
+/\x{100}{1,1}/8
+ abcd\x{100}\x{100}\x{100}\x{100}
+ 0: \x{100}
+
+/\x{100}{1,3}/8
+ abcd\x{100}\x{100}\x{100}\x{100}
+ 0: \x{100}\x{100}\x{100}
+
+/\x{100}+/8
+ abcd\x{100}\x{100}\x{100}\x{100}
+ 0: \x{100}\x{100}\x{100}\x{100}
+
+/\x{100}{3}/8
+ abcd\x{100}\x{100}\x{100}XX
+ 0: \x{100}\x{100}\x{100}
+
+/\x{100}{3,5}/8
+ abcd\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}XX
+ 0: \x{100}\x{100}\x{100}\x{100}\x{100}
+
+/\x{100}{3,}/8
+ abcd\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}XX
+ 0: \x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}
+
+/(?<=a\x{100}{2}b)X/8
+ Xyyya\x{100}\x{100}bXzzz
+ 0: X
+
+/\D*/8
+ aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+ 0: aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+
+/\D*/8
+ \x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}
+ 0: \x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}
+
+/\D/8
+ 1X2
+ 0: X
+ 1\x{100}2
+ 0: \x{100}
+
+/>\S/8
+ > >X Y
+ 0: >X
+ > >\x{100} Y
+ 0: >\x{100}
+
+/\d/8
+ \x{100}3
+ 0: 3
+
+/\s/8
+ \x{100} X
+ 0:
+
+/\D+/8
+ 12abcd34
+ 0: abcd
+ *** Failers
+ 0: *** Failers
+ 1234
+No match
+
+/\d+/8
+ 12abcd34
+ 0: 12
+ *** Failers
+No match
+
+/\d{2,3}/8
+ 12abcd34
+ 0: 12
+ 1234abcd
+ 0: 123
+ *** Failers
+No match
+ 1.4
+No match
+
+/\S+/8
+ 12abcd34
+ 0: 12abcd34
+ *** Failers
+ 0: ***
+ \ \
+No match
+
+/>\s+</8
+ 12> <34
+ 0: > <
+ *** Failers
+No match
+
+/>\s{2,3}</8
+ ab> <cd
+ 0: > <
+ ab> <ce
+ 0: > <
+ *** Failers
+No match
+ ab> <cd
+No match
+
+/>\s{2,3}?</8
+ ab> <cd
+ 0: > <
+ ab> <ce
+ 0: > <
+ *** Failers
+No match
+ ab> <cd
+No match
+
+/\w+/8
+ 12 34
+ 0: 12
+ *** Failers
+ 0: Failers
+ +++=*!
+No match
+
+/\w{2,3}/8
+ ab cd
+ 0: ab
+ abcd ce
+ 0: abc
+ *** Failers
+ 0: Fai
+ a.b.c
+No match
+
+/\W+/8
+ 12====34
+ 0: ====
+ *** Failers
+ 0: ***
+ abcd
+No match
+
+/\W{2,3}/8
+ ab====cd
+ 0: ===
+ ab==cd
+ 0: ==
+ *** Failers
+ 0: ***
+ a.b.c
+No match
+
+/\W{2,3}?/8U
+ ab====cd
+ 0: ===
+ ab==cd
+ 0: ==
+ *** Failers
+ 0: ***
+ a.b.c
+No match
+
+/[\x{100}]/8
+ \x{100}
+ 0: \x{100}
+ Z\x{100}
+ 0: \x{100}
+ \x{100}Z
+ 0: \x{100}
+ *** Failers
+No match
+
+/[Z\x{100}]/8
+ Z\x{100}
+ 0: Z
+ \x{100}
+ 0: \x{100}
+ \x{100}Z
+ 0: \x{100}
+ *** Failers
+No match
+
+/[\x{100}\x{200}]/8
+ ab\x{100}cd
+ 0: \x{100}
+ ab\x{200}cd
+ 0: \x{200}
+ *** Failers
+No match
+
+/[\x{100}-\x{200}]/8
+ ab\x{100}cd
+ 0: \x{100}
+ ab\x{200}cd
+ 0: \x{200}
+ ab\x{111}cd
+ 0: \x{111}
+ *** Failers
+No match
+
+/[z-\x{200}]/8
+ ab\x{100}cd
+ 0: \x{100}
+ ab\x{200}cd
+ 0: \x{200}
+ ab\x{111}cd
+ 0: \x{111}
+ abzcd
+ 0: z
+ ab|cd
+ 0: |
+ *** Failers
+No match
+
+/[Q\x{100}\x{200}]/8
+ ab\x{100}cd
+ 0: \x{100}
+ ab\x{200}cd
+ 0: \x{200}
+ Q?
+ 0: Q
+ *** Failers
+No match
+
+/[Q\x{100}-\x{200}]/8
+ ab\x{100}cd
+ 0: \x{100}
+ ab\x{200}cd
+ 0: \x{200}
+ ab\x{111}cd
+ 0: \x{111}
+ Q?
+ 0: Q
+ *** Failers
+No match
+
+/[Qz-\x{200}]/8
+ ab\x{100}cd
+ 0: \x{100}
+ ab\x{200}cd
+ 0: \x{200}
+ ab\x{111}cd
+ 0: \x{111}
+ abzcd
+ 0: z
+ ab|cd
+ 0: |
+ Q?
+ 0: Q
+ *** Failers
+No match
+
+/[\x{100}\x{200}]{1,3}/8
+ ab\x{100}cd
+ 0: \x{100}
+ ab\x{200}cd
+ 0: \x{200}
+ ab\x{200}\x{100}\x{200}\x{100}cd
+ 0: \x{200}\x{100}\x{200}
+ *** Failers
+No match
+
+/[\x{100}\x{200}]{1,3}?/8U
+ ab\x{100}cd
+ 0: \x{100}
+ ab\x{200}cd
+ 0: \x{200}
+ ab\x{200}\x{100}\x{200}\x{100}cd
+ 0: \x{200}\x{100}\x{200}
+ *** Failers
+No match
+
+/[Q\x{100}\x{200}]{1,3}/8
+ ab\x{100}cd
+ 0: \x{100}
+ ab\x{200}cd
+ 0: \x{200}
+ ab\x{200}\x{100}\x{200}\x{100}cd
+ 0: \x{200}\x{100}\x{200}
+ *** Failers
+No match
+
+/[Q\x{100}\x{200}]{1,3}?/8U
+ ab\x{100}cd
+ 0: \x{100}
+ ab\x{200}cd
+ 0: \x{200}
+ ab\x{200}\x{100}\x{200}\x{100}cd
+ 0: \x{200}\x{100}\x{200}
+ *** Failers
+No match
+
+/(?<=[\x{100}\x{200}])X/8
+ abc\x{200}X
+ 0: X
+ abc\x{100}X
+ 0: X
+ *** Failers
+No match
+ X
+No match
+
+/(?<=[Q\x{100}\x{200}])X/8
+ abc\x{200}X
+ 0: X
+ abc\x{100}X
+ 0: X
+ abQX
+ 0: X
+ *** Failers
+No match
+ X
+No match
+
+/(?<=[\x{100}\x{200}]{3})X/8
+ abc\x{100}\x{200}\x{100}X
+ 0: X
+ *** Failers
+No match
+ abc\x{200}X
+No match
+ X
+No match
+
+/[^\x{100}\x{200}]X/8
+ AX
+ 0: AX
+ \x{150}X
+ 0: \x{150}X
+ \x{500}X
+ 0: \x{500}X
+ *** Failers
+No match
+ \x{100}X
+No match
+ \x{200}X
+No match
+
+/[^Q\x{100}\x{200}]X/8
+ AX
+ 0: AX
+ \x{150}X
+ 0: \x{150}X
+ \x{500}X
+ 0: \x{500}X
+ *** Failers
+No match
+ \x{100}X
+No match
+ \x{200}X
+No match
+ QX
+No match
+
+/[^\x{100}-\x{200}]X/8
+ AX
+ 0: AX
+ \x{500}X
+ 0: \x{500}X
+ *** Failers
+No match
+ \x{100}X
+No match
+ \x{150}X
+No match
+ \x{200}X
+No match
+
+/[z-\x{100}]/8i
+ z
+ 0: z
+ Z
+ 0: Z
+ \x{100}
+ 0: \x{100}
+ *** Failers
+No match
+ \x{102}
+No match
+ y
+No match
+
+/[\xFF]/
+ >\xff<
+ 0: \xff
+
+/[\xff]/8
+ >\x{ff}<
+ 0: \x{ff}
+
+/[^\xFF]/
+ XYZ
+ 0: X
+
+/[^\xff]/8
+ XYZ
+ 0: X
+ \x{123}
+ 0: \x{123}
+
+/^[ac]*b/8
+ xb
+No match
+
+/^[ac\x{100}]*b/8
+ xb
+No match
+
+/^[^x]*b/8i
+ xb
+No match
+
+/^[^x]*b/8
+ xb
+No match
+
+/^\d*b/8
+ xb
+No match
+
+/^\x{85}$/8i
+ \x{85}
+ 0: \x{85}
+
+/^abc./mgx8<any>
+ abc1 \x0aabc2 \x0babc3xx \x0cabc4 \x0dabc5xx \x0d\x0aabc6 \x{0085}abc7 \x{2028}abc8 \x{2029}abc9 JUNK
+ 0: abc1
+ 0: abc2
+ 0: abc3
+ 0: abc4
+ 0: abc5
+ 0: abc6
+ 0: abc7
+ 0: abc8
+ 0: abc9
+
+/abc.$/mgx8<any>
+ abc1\x0a abc2\x0b abc3\x0c abc4\x0d abc5\x0d\x0a abc6\x{0085} abc7\x{2028} abc8\x{2029} abc9
+ 0: abc1
+ 0: abc2
+ 0: abc3
+ 0: abc4
+ 0: abc5
+ 0: abc6
+ 0: abc7
+ 0: abc8
+ 0: abc9
+
+/^a\Rb/8<bsr_unicode>
+ a\nb
+ 0: a\x{0a}b
+ a\rb
+ 0: a\x{0d}b
+ a\r\nb
+ 0: a\x{0d}\x{0a}b
+ a\x0bb
+ 0: a\x{0b}b
+ a\x0cb
+ 0: a\x{0c}b
+ a\x{85}b
+ 0: a\x{85}b
+ a\x{2028}b
+ 0: a\x{2028}b
+ a\x{2029}b
+ 0: a\x{2029}b
+ ** Failers
+No match
+ a\n\rb
+No match
+
+/^a\R*b/8<bsr_unicode>
+ ab
+ 0: ab
+ a\nb
+ 0: a\x{0a}b
+ a\rb
+ 0: a\x{0d}b
+ a\r\nb
+ 0: a\x{0d}\x{0a}b
+ a\x0bb
+ 0: a\x{0b}b
+ a\x0c\x{2028}\x{2029}b
+ 0: a\x{0c}\x{2028}\x{2029}b
+ a\x{85}b
+ 0: a\x{85}b
+ a\n\rb
+ 0: a\x{0a}\x{0d}b
+ a\n\r\x{85}\x0cb
+ 0: a\x{0a}\x{0d}\x{85}\x{0c}b
+
+/^a\R+b/8<bsr_unicode>
+ a\nb
+ 0: a\x{0a}b
+ a\rb
+ 0: a\x{0d}b
+ a\r\nb
+ 0: a\x{0d}\x{0a}b
+ a\x0bb
+ 0: a\x{0b}b
+ a\x0c\x{2028}\x{2029}b
+ 0: a\x{0c}\x{2028}\x{2029}b
+ a\x{85}b
+ 0: a\x{85}b
+ a\n\rb
+ 0: a\x{0a}\x{0d}b
+ a\n\r\x{85}\x0cb
+ 0: a\x{0a}\x{0d}\x{85}\x{0c}b
+ ** Failers
+No match
+ ab
+No match
+
+/^a\R{1,3}b/8<bsr_unicode>
+ a\nb
+ 0: a\x{0a}b
+ a\n\rb
+ 0: a\x{0a}\x{0d}b
+ a\n\r\x{85}b
+ 0: a\x{0a}\x{0d}\x{85}b
+ a\r\n\r\nb
+ 0: a\x{0d}\x{0a}\x{0d}\x{0a}b
+ a\r\n\r\n\r\nb
+ 0: a\x{0d}\x{0a}\x{0d}\x{0a}\x{0d}\x{0a}b
+ a\n\r\n\rb
+ 0: a\x{0a}\x{0d}\x{0a}\x{0d}b
+ a\n\n\r\nb
+ 0: a\x{0a}\x{0a}\x{0d}\x{0a}b
+ ** Failers
+No match
+ a\n\n\n\rb
+No match
+ a\r
+No match
+
+/\h+\V?\v{3,4}/8
+ \x09\x20\x{a0}X\x0a\x0b\x0c\x0d\x0a
+ 0: \x{09} \x{a0}X\x{0a}\x{0b}\x{0c}\x{0d}
+
+/\V?\v{3,4}/8
+ \x20\x{a0}X\x0a\x0b\x0c\x0d\x0a
+ 0: X\x{0a}\x{0b}\x{0c}\x{0d}
+
+/\h+\V?\v{3,4}/8
+ >\x09\x20\x{a0}X\x0a\x0a\x0a<
+ 0: \x{09} \x{a0}X\x{0a}\x{0a}\x{0a}
+
+/\V?\v{3,4}/8
+ >\x09\x20\x{a0}X\x0a\x0a\x0a<
+ 0: X\x{0a}\x{0a}\x{0a}
+
+/\H\h\V\v/8
+ X X\x0a
+ 0: X X\x{0a}
+ X\x09X\x0b
+ 0: X\x{09}X\x{0b}
+ ** Failers
+No match
+ \x{a0} X\x0a
+No match
+
+/\H*\h+\V?\v{3,4}/8
+ \x09\x20\x{a0}X\x0a\x0b\x0c\x0d\x0a
+ 0: \x{09} \x{a0}X\x{0a}\x{0b}\x{0c}\x{0d}
+ \x09\x20\x{a0}\x0a\x0b\x0c\x0d\x0a
+ 0: \x{09} \x{a0}\x{0a}\x{0b}\x{0c}\x{0d}
+ \x09\x20\x{a0}\x0a\x0b\x0c
+ 0: \x{09} \x{a0}\x{0a}\x{0b}\x{0c}
+ ** Failers
+No match
+ \x09\x20\x{a0}\x0a\x0b
+No match
+
+/\H\h\V\v/8
+ \x{3001}\x{3000}\x{2030}\x{2028}
+ 0: \x{3001}\x{3000}\x{2030}\x{2028}
+ X\x{180e}X\x{85}
+ 0: X\x{180e}X\x{85}
+ ** Failers
+No match
+ \x{2009} X\x0a
+No match
+
+/\H*\h+\V?\v{3,4}/8
+ \x{1680}\x{180e}\x{2007}X\x{2028}\x{2029}\x0c\x0d\x0a
+ 0: \x{1680}\x{180e}\x{2007}X\x{2028}\x{2029}\x{0c}\x{0d}
+ \x09\x{205f}\x{a0}\x0a\x{2029}\x0c\x{2028}\x0a
+ 0: \x{09}\x{205f}\x{a0}\x{0a}\x{2029}\x{0c}\x{2028}
+ \x09\x20\x{202f}\x0a\x0b\x0c
+ 0: \x{09} \x{202f}\x{0a}\x{0b}\x{0c}
+ ** Failers
+No match
+ \x09\x{200a}\x{a0}\x{2028}\x0b
+No match
+
+/a\Rb/I8<bsr_anycrlf>
+Capturing subpattern count = 0
+Options: bsr_anycrlf utf8
+First char = 'a'
+Need char = 'b'
+ a\rb
+ 0: a\x{0d}b
+ a\nb
+ 0: a\x{0a}b
+ a\r\nb
+ 0: a\x{0d}\x{0a}b
+ ** Failers
+No match
+ a\x{85}b
+No match
+ a\x0bb
+No match
+
+/a\Rb/I8<bsr_unicode>
+Capturing subpattern count = 0
+Options: bsr_unicode utf8
+First char = 'a'
+Need char = 'b'
+ a\rb
+ 0: a\x{0d}b
+ a\nb
+ 0: a\x{0a}b
+ a\r\nb
+ 0: a\x{0d}\x{0a}b
+ a\x{85}b
+ 0: a\x{85}b
+ a\x0bb
+ 0: a\x{0b}b
+ ** Failers
+No match
+ a\x{85}b\<bsr_anycrlf>
+No match
+ a\x0bb\<bsr_anycrlf>
+No match
+
+/a\R?b/I8<bsr_anycrlf>
+Capturing subpattern count = 0
+Options: bsr_anycrlf utf8
+First char = 'a'
+Need char = 'b'
+ a\rb
+ 0: a\x{0d}b
+ a\nb
+ 0: a\x{0a}b
+ a\r\nb
+ 0: a\x{0d}\x{0a}b
+ ** Failers
+No match
+ a\x{85}b
+No match
+ a\x0bb
+No match
+
+/a\R?b/I8<bsr_unicode>
+Capturing subpattern count = 0
+Options: bsr_unicode utf8
+First char = 'a'
+Need char = 'b'
+ a\rb
+ 0: a\x{0d}b
+ a\nb
+ 0: a\x{0a}b
+ a\r\nb
+ 0: a\x{0d}\x{0a}b
+ a\x{85}b
+ 0: a\x{85}b
+ a\x0bb
+ 0: a\x{0b}b
+ ** Failers
+No match
+ a\x{85}b\<bsr_anycrlf>
+No match
+ a\x0bb\<bsr_anycrlf>
+No match
+
+/ End of testinput 8 /
diff --git a/lib/stdlib/test/re_testoutput1_replacement_test.erl b/lib/stdlib/test/re_testoutput1_replacement_test.erl
index b20db3f9c3..69cb140e0d 100644
--- a/lib/stdlib/test/re_testoutput1_replacement_test.erl
+++ b/lib/stdlib/test/re_testoutput1_replacement_test.erl
@@ -1,23 +1,24 @@
%%
%% %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%
%%
-module(re_testoutput1_replacement_test).
-compile(export_all).
+-compile(no_native).
-include("test_server.hrl").
%% This file is generated by running run_pcre_tests:gen_repl_test("re_SUITE_data/testoutput1")
run() ->
diff --git a/lib/stdlib/test/re_testoutput1_split_test.erl b/lib/stdlib/test/re_testoutput1_split_test.erl
index 7e2d3f79ec..e86a04b008 100644
--- a/lib/stdlib/test/re_testoutput1_split_test.erl
+++ b/lib/stdlib/test/re_testoutput1_split_test.erl
@@ -1,23 +1,24 @@
%%
%% %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%
%%
-module(re_testoutput1_split_test).
-compile(export_all).
+-compile(no_native).
-include("test_server.hrl").
%% This file is generated by running run_pcre_tests:gen_split_test("re_SUITE_data/testoutput1")
join([]) -> [];
diff --git a/lib/stdlib/test/run_pcre_tests.erl b/lib/stdlib/test/run_pcre_tests.erl
index 0ef3986918..78b4803fc8 100644
--- a/lib/stdlib/test/run_pcre_tests.erl
+++ b/lib/stdlib/test/run_pcre_tests.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%
%%
-module(run_pcre_tests).
@@ -25,7 +25,7 @@ test(RootDir) ->
erts_debug:set_internal_state(available_internal_state,true),
io:format("oldlimit: ~p~n",[ erts_debug:set_internal_state(re_loop_limit,10)]),
Testfiles0 = ["testoutput1", "testoutput2", "testoutput3", "testoutput4",
- "testoutput5", "testoutput6", "testoutput10"],
+ "testoutput5", "testoutput6","mod_testoutput8","testoutput10"],
Testfiles = [ filename:join([RootDir,FN]) || FN <- Testfiles0 ],
Res = [ begin io:format("~s~n",[X]), t(X) end || X <- Testfiles ],
io:format("limit was: ~p~n",[ erts_debug:set_internal_state(re_loop_limit,default)]),
@@ -42,12 +42,14 @@ t(OneFile,Num) ->
put(error_limit,Num),
put(skipped,0),
Res =
- [test(Structured,true,index),
- test(Structured,false,index),
- test(Structured,true,binary),
- test(Structured,false,binary),
- test(Structured,true,list),
- test(Structured,false,list)],
+ [test(Structured,true,index,false),
+ test(Structured,false,index,false),
+ test(Structured,true,index,true),
+ test(Structured,false,index,true),
+ test(Structured,true,binary,false),
+ test(Structured,false,binary,false),
+ test(Structured,true,list,false),
+ test(Structured,false,list,false)],
{lists:sum(Res),length(Structured)*6,get(skipped)}.
@@ -63,11 +65,21 @@ pick_exec_options([Opt|T]) ->
pick_exec_options([]) ->
{[],[]}.
-test([],_,_) ->
+test([],_,_,_) ->
0;
-test([{RE,Line,Options0,Tests}|T],PreCompile,XMode) ->
+test([{RE0,Line,Options0,Tests}|T],PreCompile,XMode,REAsList) ->
%io:format("."),
%case RE of <<>> -> io:format("Empty re:~w~n",[Line]); _ -> ok end,
+ Unicode = lists:member(unicode,Options0),
+ RE = case REAsList of
+ true ->
+ if
+ Unicode -> unicode:characters_to_list(RE0);
+ true -> binary_to_list(RE0)
+ end;
+ false ->
+ RE0
+ end,
{Options,ExecOptions} = pick_exec_options(Options0),
{Cres, Xopt} = case PreCompile of
true ->
@@ -80,7 +92,7 @@ test([{RE,Line,Options0,Tests}|T],PreCompile,XMode) ->
%erlang:display({testrun,RE,P,Tests,ExecOptions,Xopt,XMode}),
case (catch testrun(RE,P,Tests,ExecOptions,Xopt,XMode)) of
N when is_integer(N) ->
- N + test(T,PreCompile,XMode);
+ N + test(T,PreCompile,XMode,REAsList);
limit ->
io:format("Error limit reached.~n"),
1;
@@ -91,12 +103,12 @@ test([{RE,Line,Options0,Tests}|T],PreCompile,XMode) ->
_ ->
put(skipped,1)
end,
- test(T,PreCompile,XMode)
+ test(T,PreCompile,XMode,REAsList)
end;
{error,Err} ->
io:format("Compile error(~w): ~w~n",[Line,Err]),
case get(error_limit) of
- infinite -> 1 + test(T,PreCompile,XMode);
+ infinite -> 1 + test(T,PreCompile,XMode,REAsList);
X ->
case X-1 of
Y when Y =< 0 ->
@@ -104,7 +116,7 @@ test([{RE,Line,Options0,Tests}|T],PreCompile,XMode) ->
1;
Y ->
put(error_limit,Y),
- 1 + test(T,PreCompile,XMode)
+ 1 + test(T,PreCompile,XMode,REAsList)
end
end
end.
@@ -549,6 +561,8 @@ tr_option($N) ->
[no_auto_capture];
tr_option($8) ->
[unicode];
+tr_option($U) ->
+ [ungreedy];
tr_option($g) ->
[{exec_option,g}];
tr_option(_) ->
@@ -973,6 +987,7 @@ gen_split_test(OneFile) ->
{ok,F}= file:open(ErlFileName,[write]),
io:format(F,"-module(~s).~n",[ErlModule]),
io:format(F,"-compile(export_all).~n",[]),
+ io:format(F,"-compile(no_native).~n",[]),
io:format(F,"-include(\"test_server.hrl\").~n",[]),
%io:format(F,"-define(line,erlang:display(?LINE),).~n",[]),
io:format(F,"%% This file is generated by running ~w:gen_split_test(~p)~n",
@@ -1054,6 +1069,7 @@ gen_repl_test(OneFile) ->
{ok,F}= file:open(ErlFileName,[write]),
io:format(F,"-module(~s).~n",[ErlModule]),
io:format(F,"-compile(export_all).~n",[]),
+ io:format(F,"-compile(no_native).~n",[]),
io:format(F,"-include(\"test_server.hrl\").~n",[]),
io:format(F,"%% This file is generated by running ~w:gen_repl_test(~p)~n",
[?MODULE,OneFile]),
diff --git a/lib/stdlib/test/select_SUITE.erl b/lib/stdlib/test/select_SUITE.erl
index 54664fbb00..6900f1a8f5 100644
--- a/lib/stdlib/test/select_SUITE.erl
+++ b/lib/stdlib/test/select_SUITE.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2000-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 2000-2010. All Rights Reserved.
+%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
-%%
+%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
-%%
+%%
%% %CopyrightEnd%
%%
@@ -79,14 +79,14 @@ select_test(suite) ->
[];
select_test(doc) ->
["Tests select in numerous ways"];
-select_test(Config) when list(Config) ->
+select_test(Config) when is_list(Config) ->
do_test(Config).
return_values(suite) ->
[];
return_values(doc) ->
["Tests return values in specific situations for select/3 and select/1"];
-return_values(Config) when list(Config) ->
+return_values(Config) when is_list(Config) ->
do_return_values().
-endif.
@@ -279,7 +279,7 @@ cmp_ms_to_fun({Mod,Tab}, MS, Fun1, Fun2, ChunkSize) ->
MSRes = lists:sort(chunked_select(Mod,Tab,MS,ChunkSize)),
FunRes0 = table_foldl(Fun1,[],{Mod,Tab}),
FunRes = case Fun2 of
- F when function(F) ->
+ F when is_function(F) ->
FunRes1 = table_foldl(F,[],{Mod,Tab}),
lists:merge(FunRes0,FunRes1);
[] ->
diff --git a/lib/stdlib/test/shell_SUITE.erl b/lib/stdlib/test/shell_SUITE.erl
index 5827d5f332..588342d46a 100644
--- a/lib/stdlib/test/shell_SUITE.erl
+++ b/lib/stdlib/test/shell_SUITE.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2004-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 2004-2010. All Rights Reserved.
+%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
-%%
+%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
-%%
+%%
%% %CopyrightEnd%
%%
-module(shell_SUITE).
@@ -28,13 +28,14 @@
progex/1, progex_bit_syntax/1, progex_records/1,
progex_lc/1, progex_funs/1,
tickets/1, otp_5990/1, otp_6166/1, otp_6554/1, otp_6785/1,
- otp_7184/1, otp_7232/1]).
+ otp_7184/1, otp_7232/1, otp_8393/1]).
-export([restricted/1, start_restricted_from_shell/1,
start_restricted_on_command_line/1,restricted_local/1]).
%% Internal export.
--export([otp_5435_2/0]).
+-export([otp_5435_2/0, prompt1/1, prompt2/1, prompt3/1, prompt4/1,
+ prompt5/1]).
%%
%% Define to run outside of test server
@@ -2256,7 +2257,7 @@ progex_funs(Config) when is_list(Config) ->
ok.
tickets(suite) ->
- [otp_5990, otp_6166, otp_6554, otp_6785, otp_7184, otp_7232].
+ [otp_5990, otp_6166, otp_6554, otp_6785, otp_7184, otp_7232, otp_8393].
otp_5990(doc) ->
"OTP-5990. {erlang,is_record}.";
@@ -2598,6 +2599,93 @@ otp_7232(Config) when is_list(Config) ->
" end}])" = evaluate(Info, []),
ok.
+otp_8393(doc) ->
+ "OTP-8393. Prompt string.";
+otp_8393(suite) -> [];
+otp_8393(Config) when is_list(Config) ->
+ ?line _ = shell:prompt_func(default),
+ ?line "Bad prompt function: '> '" =
+ prompt_err(<<"shell:prompt_func('> ').">>),
+
+ ?line _ = shell:prompt_func(default),
+ ?line "exception error: bad argument in an arithmetic expression"++_ =
+ prompt_err(<<"shell:prompt_func({shell_SUITE,prompt4}).">>),
+
+ ?line _ = shell:prompt_func(default),
+ ?line "default.\n" =
+ t(<<"shell:prompt_func({shell_SUITE,prompt2}).">>),
+
+ ?line _ = shell:prompt_func(default),
+ ?line "default\nl.\n" =
+ t(<<"shell:prompt_func({shell_SUITE,prompt3}). l.">>),
+
+ %%
+ %% Although this tests that you can set a unicode prompt function
+ %% it does not really test that it does work with the io-servers.
+ %% That is instead tested in the io_proto_SUITE, which has
+ %% the right infrastructure in place for such tests. /PaN
+ %%
+ ?line _ = shell:prompt_func(default),
+ ?line "default\nl.\n" =
+ t(<<"shell:prompt_func({shell_SUITE,prompt5}). l.">>),
+
+ %% Restricted shell.
+ Contents = <<"-module(test_restricted_shell).
+ -export([local_allowed/3, non_local_allowed/3]).
+ local_allowed(_,_,State) ->
+ {false,State}.
+
+ non_local_allowed({shell,stop_restricted},[],State) ->
+ {true,State};
+ non_local_allowed({shell,prompt_func},[_L],State) ->
+ {true,State};
+ non_local_allowed({shell_SUITE,prompt1},[_L],State) ->
+ {true,State};
+ non_local_allowed(_,_,State) ->
+ {false,State}.
+ ">>,
+ ?line Test = filename:join(?config(priv_dir, Config),
+ "test_restricted_shell.erl"),
+ ?line ok = compile_file(Config, Test, Contents, []),
+ ?line _ = shell:prompt_func(default),
+ ?line "exception exit: restricted shell starts now" =
+ comm_err(<<"begin shell:start_restricted("
+ "test_restricted_shell) end.">>),
+ ?line "default.\n"++_ =
+ t(<<"shell:prompt_func({shell_SUITE,prompt1}).">>),
+ ?line "exception exit: restricted shell does not allow apple(" ++ _ =
+ comm_err(<<"apple(1).">>),
+ ?line "{shell_SUITE,prompt1}.\n" =
+ t(<<"shell:prompt_func(default).">>),
+ ?line "exception exit: restricted shell stopped"=
+ comm_err(<<"begin shell:stop_restricted() end.">>),
+ ?line undefined =
+ application:get_env(stdlib, restricted_shell),
+
+ ?line NR = shell:results(20),
+ ?line "default\n20.\n" =
+ t(<<"shell:prompt_func({shell_SUITE,prompt3}). results(0).">>),
+
+ ?line _ = shell:prompt_func(default),
+ ?line 0 = shell:results(NR),
+ ok.
+
+prompt1(_L) ->
+ "prompt> ".
+
+prompt2(_L) ->
+ {'EXIT', []}.
+
+prompt3(L) ->
+ N = proplists:get_value(history, L),
+ integer_to_list(N).
+
+prompt4(_L) ->
+ erlang:apply({erlang,'/'}, [1,0]).
+
+prompt5(_L) ->
+ [1050,1072,1082,1074,1086,32,1077,32,85,110,105,99,111,100,101,32,63].
+
-ifdef(not_used).
exit_term(B) ->
"** exception exit:" ++ Reply = t(B),
@@ -2627,7 +2715,16 @@ comm_err(B) ->
Reply = t(B),
S0 = string:left(Reply, string:chr(Reply, $\n)-1),
S1 = string:strip(S0, left, $*),
- S2 = string:strip(S1, both, $ ),
+ S2 = string:strip(S1, both, $ ),
+ S = string:strip(S2, both, $"),
+ string:strip(S, right, $.).
+
+prompt_err(B) ->
+ Reply = t(B),
+ S00 = string:sub_string(Reply, string:chr(Reply, $\n)+1),
+ S0 = string:left(S00, string:chr(S00, $\n)-1),
+ S1 = string:strip(S0, left, $*),
+ S2 = string:strip(S1, both, $ ),
S = string:strip(S2, both, $"),
string:strip(S, right, $.).
diff --git a/lib/stdlib/test/slave_SUITE.erl b/lib/stdlib/test/slave_SUITE.erl
index 3b737af64d..5c1282fe9b 100644
--- a/lib/stdlib/test/slave_SUITE.erl
+++ b/lib/stdlib/test/slave_SUITE.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(slave_SUITE).
@@ -31,7 +31,7 @@ all(suite) ->
[t_start_link, start_link_nodedown, t_start, errors].
t_start_link(suite) -> [];
-t_start_link(Config) when list(Config) ->
+t_start_link(Config) when is_list(Config) ->
?line Dog = test_server:timetrap(test_server:seconds(20)),
%% Define useful variables.
@@ -81,7 +81,7 @@ t_start_link(Config) when list(Config) ->
%% Test that slave:start_link() works when the master exits.
start_link_nodedown(suite) -> [];
-start_link_nodedown(Config) when list(Config) ->
+start_link_nodedown(Config) when is_list(Config) ->
?line Dog = test_server:timetrap(test_server:seconds(20)),
%% Define useful variables.
@@ -109,7 +109,7 @@ start_a_slave(ReplyTo, Host, Name) ->
%% Test slave:start().
t_start(suite) -> [];
-t_start(Config) when list(Config) ->
+t_start(Config) when is_list(Config) ->
?line Dog = test_server:timetrap(test_server:seconds(20)),
%% Define useful variables.
@@ -160,7 +160,7 @@ t_start(Config) when list(Config) ->
%% in slave is 32 seconds).
errors(suite) -> [];
-errors(Config) when list(Config) ->
+errors(Config) when is_list(Config) ->
?line Dog = test_server:timetrap(test_server:seconds(50)),
?line process_flag(trap_exit, true),
diff --git a/lib/stdlib/test/sofs_SUITE.erl b/lib/stdlib/test/sofs_SUITE.erl
index 0849e0f59c..d60cfc6895 100644
--- a/lib/stdlib/test/sofs_SUITE.erl
+++ b/lib/stdlib/test/sofs_SUITE.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2001-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 2001-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(sofs_SUITE).
@@ -115,7 +115,7 @@ sofs(suite) ->
from_term_1(suite) -> [];
from_term_1(doc) -> [""];
-from_term_1(Conf) when list(Conf) ->
+from_term_1(Conf) when is_list(Conf) ->
%% would go wrong: projection(1,from_term([{2,b},{1,a,b}])),
?line {'EXIT', {badarg, _}} = (catch from_term([], {atom,'_',atom})),
@@ -203,7 +203,7 @@ from_term_1(Conf) when list(Conf) ->
set_1(suite) -> [];
set_1(doc) -> [""];
-set_1(Conf) when list(Conf) ->
+set_1(Conf) when is_list(Conf) ->
%% set/1
?line {'EXIT', {badarg, _}} = (catch set(a)),
?line {'EXIT', {badarg, _}} = (catch set({a})),
@@ -235,7 +235,7 @@ set_1(Conf) when list(Conf) ->
from_sets_1(suite) -> [];
from_sets_1(doc) -> [""];
-from_sets_1(Conf) when list(Conf) ->
+from_sets_1(Conf) when is_list(Conf) ->
?line E = empty_set(),
%% unordered
@@ -272,7 +272,7 @@ from_sets_1(Conf) when list(Conf) ->
relation_1(suite) -> [];
relation_1(doc) -> [""];
-relation_1(Conf) when list(Conf) ->
+relation_1(Conf) when is_list(Conf) ->
%% relation/1
?line eval(relation([]), from_term([], [{atom,atom}])),
?line eval(from_term([{a}]), relation([{a}])),
@@ -305,7 +305,7 @@ relation_1(Conf) when list(Conf) ->
a_function_1(suite) -> [];
a_function_1(doc) -> [""];
-a_function_1(Conf) when list(Conf) ->
+a_function_1(Conf) when is_list(Conf) ->
%% a_function/1
?line eval(a_function([]), from_term([], [{atom,atom}])),
?line eval(a_function([{a,b},{a,b},{b,c}]), from_term([{a,b},{b,c}])),
@@ -352,7 +352,7 @@ a_function_1(Conf) when list(Conf) ->
family_1(suite) -> [];
family_1(doc) -> [""];
-family_1(Conf) when list(Conf) ->
+family_1(Conf) when is_list(Conf) ->
%% family/1
?line eval(family([]), from_term([],[{atom,[atom]}])),
?line {'EXIT', {badarg, _}} = (catch family(a)),
@@ -413,7 +413,7 @@ family_1(Conf) when list(Conf) ->
projection(suite) -> [];
projection(doc) -> [""];
-projection(Conf) when list(Conf) ->
+projection(Conf) when is_list(Conf) ->
?line E = empty_set(),
?line ER = relation([]),
@@ -535,7 +535,7 @@ projection(Conf) when list(Conf) ->
substitution(suite) -> [];
substitution(doc) -> [""];
-substitution(Conf) when list(Conf) ->
+substitution(Conf) when is_list(Conf) ->
?line E = empty_set(),
?line ER = relation([]),
@@ -633,7 +633,7 @@ substitution(Conf) when list(Conf) ->
restriction(suite) -> [];
restriction(doc) -> [""];
-restriction(Conf) when list(Conf) ->
+restriction(Conf) when is_list(Conf) ->
?line E = empty_set(),
?line ER = relation([], 2),
@@ -752,7 +752,7 @@ restriction(Conf) when list(Conf) ->
drestriction(suite) -> [];
drestriction(doc) -> [""];
-drestriction(Conf) when list(Conf) ->
+drestriction(Conf) when is_list(Conf) ->
?line E = empty_set(),
?line ER = relation([], 2),
@@ -869,7 +869,7 @@ drestriction(Conf) when list(Conf) ->
strict_relation_1(suite) -> [];
strict_relation_1(doc) -> [""];
-strict_relation_1(Conf) when list(Conf) ->
+strict_relation_1(Conf) when is_list(Conf) ->
?line E = empty_set(),
?line ER = relation([], 2),
?line eval(strict_relation(E), E),
@@ -890,7 +890,7 @@ strict_relation_1(Conf) when list(Conf) ->
extension(suite) -> [];
extension(doc) -> [""];
-extension(Conf) when list(Conf) ->
+extension(Conf) when is_list(Conf) ->
?line E = empty_set(),
?line ER = relation([], 2),
?line EF = family([]),
@@ -933,7 +933,7 @@ lextension(R, S, C) ->
weak_relation_1(suite) -> [];
weak_relation_1(doc) -> [""];
-weak_relation_1(Conf) when list(Conf) ->
+weak_relation_1(Conf) when is_list(Conf) ->
?line E = empty_set(),
?line ER = relation([], 2),
?line eval(weak_relation(E), E),
@@ -966,7 +966,7 @@ weak_relation_1(Conf) when list(Conf) ->
to_sets_1(suite) -> [];
to_sets_1(doc) -> [""];
-to_sets_1(Conf) when list(Conf) ->
+to_sets_1(Conf) when is_list(Conf) ->
?line {'EXIT', {badarg, _}} = (catch to_sets(from_term(a))),
?line {'EXIT', {function_clause, _}} = (catch to_sets(a)),
%% unordered
@@ -988,8 +988,8 @@ to_sets_1(Conf) when list(Conf) ->
specification(suite) -> [];
specification(doc) -> [""];
-specification(Conf) when list(Conf) ->
- Fun = {external, fun(I) when integer(I) -> true; (_) -> false end},
+specification(Conf) when is_list(Conf) ->
+ Fun = {external, fun(I) when is_integer(I) -> true; (_) -> false end},
?line [1,2,3] = to_external(specification(Fun, set([a,1,b,2,c,3]))),
Fun2 = fun(S) -> is_subset(S, set([1,3,5,7,9])) end,
@@ -1014,7 +1014,7 @@ specification(Conf) when list(Conf) ->
union_1(suite) -> [];
union_1(doc) -> [""];
-union_1(Conf) when list(Conf) ->
+union_1(Conf) when is_list(Conf) ->
?line E = empty_set(),
?line ER = relation([], 2),
?line {'EXIT', {badarg, _}} = (catch union(ER)),
@@ -1044,7 +1044,7 @@ union_1(Conf) when list(Conf) ->
intersection_1(suite) -> [];
intersection_1(doc) -> [""];
-intersection_1(Conf) when list(Conf) ->
+intersection_1(Conf) when is_list(Conf) ->
?line E = empty_set(),
?line {'EXIT', {badarg, _}} = (catch intersection(from_term([a,b]))),
?line {'EXIT', {badarg, _}} = (catch intersection(E)),
@@ -1068,7 +1068,7 @@ intersection_1(Conf) when list(Conf) ->
difference(suite) -> [];
difference(doc) -> [""];
-difference(Conf) when list(Conf) ->
+difference(Conf) when is_list(Conf) ->
?line E = empty_set(),
?line {'EXIT', {type_mismatch, _}} =
(catch difference(relation([{a,b}]), relation([{a,b,c}]))),
@@ -1089,7 +1089,7 @@ difference(Conf) when list(Conf) ->
symdiff(suite) -> [];
symdiff(doc) -> [""];
-symdiff(Conf) when list(Conf) ->
+symdiff(Conf) when is_list(Conf) ->
?line E = empty_set(),
?line {'EXIT', {type_mismatch, _}} =
(catch symdiff(relation([{a,b}]), relation([{a,b,c}]))),
@@ -1114,7 +1114,7 @@ symdiff(Conf) when list(Conf) ->
symmetric_partition(suite) -> [];
symmetric_partition(doc) -> [""];
-symmetric_partition(Conf) when list(Conf) ->
+symmetric_partition(Conf) when is_list(Conf) ->
?line E = set([]),
?line S1 = set([1,2,3,4]),
?line S2 = set([3,4,5,6]),
@@ -1148,7 +1148,7 @@ symmetric_partition(Conf) when list(Conf) ->
is_sofs_set_1(suite) -> [];
is_sofs_set_1(doc) -> [""];
-is_sofs_set_1(Conf) when list(Conf) ->
+is_sofs_set_1(Conf) when is_list(Conf) ->
?line E = empty_set(),
?line true = is_sofs_set(E),
?line true = is_sofs_set(from_term([a])),
@@ -1159,7 +1159,7 @@ is_sofs_set_1(Conf) when list(Conf) ->
is_set_1(suite) -> [];
is_set_1(doc) -> [""];
-is_set_1(Conf) when list(Conf) ->
+is_set_1(Conf) when is_list(Conf) ->
?line E = empty_set(),
?line true = is_set(E),
?line true = is_set(from_term([a])),
@@ -1177,7 +1177,7 @@ is_set_1(Conf) when list(Conf) ->
is_equal(suite) -> [];
is_equal(doc) -> [""];
-is_equal(Conf) when list(Conf) ->
+is_equal(Conf) when is_list(Conf) ->
?line E = empty_set(),
?line true = is_equal(E, E),
?line false = is_equal(from_term([a]), E),
@@ -1212,7 +1212,7 @@ is_equal(Conf) when list(Conf) ->
is_subset(suite) -> [];
is_subset(doc) -> [""];
-is_subset(Conf) when list(Conf) ->
+is_subset(Conf) when is_list(Conf) ->
?line E = empty_set(),
?line true = is_subset(E, E),
?line true = is_subset(set([a,c,e]), set([a,b,c,d,e])),
@@ -1230,7 +1230,7 @@ is_subset(Conf) when list(Conf) ->
is_a_function_1(suite) -> [];
is_a_function_1(doc) -> [""];
-is_a_function_1(Conf) when list(Conf) ->
+is_a_function_1(Conf) when is_list(Conf) ->
?line E = empty_set(),
?line ER = relation([], 2),
?line {'EXIT', {badarg, _}} = (catch is_a_function(set([a,b]))),
@@ -1254,7 +1254,7 @@ is_a_function_1(Conf) when list(Conf) ->
is_disjoint(suite) -> [];
is_disjoint(doc) -> [""];
-is_disjoint(Conf) when list(Conf) ->
+is_disjoint(Conf) when is_list(Conf) ->
?line E = empty_set(),
?line {'EXIT', {type_mismatch, _}} =
(catch is_disjoint(relation([{a,1}]), set([a,b]))),
@@ -1268,7 +1268,7 @@ is_disjoint(Conf) when list(Conf) ->
join(suite) -> [];
join(doc) -> [""];
-join(Conf) when list(Conf) ->
+join(Conf) when is_list(Conf) ->
?line E = empty_set(),
?line {'EXIT', {badarg, _}} = (catch join(relation([{a,1}]), 3, E, 5)),
@@ -1306,7 +1306,7 @@ join(Conf) when list(Conf) ->
canonical(suite) -> [];
canonical(doc) -> [""];
-canonical(Conf) when list(Conf) ->
+canonical(Conf) when is_list(Conf) ->
?line E = empty_set(),
?line {'EXIT', {badarg, _}} =
(catch canonical_relation(set([a,b]))),
@@ -1318,7 +1318,7 @@ canonical(Conf) when list(Conf) ->
relation_to_family_1(suite) -> [];
relation_to_family_1(doc) -> [""];
-relation_to_family_1(Conf) when list(Conf) ->
+relation_to_family_1(Conf) when is_list(Conf) ->
?line E = empty_set(),
?line EF = family([]),
?line eval(relation_to_family(E), E),
@@ -1333,7 +1333,7 @@ relation_to_family_1(Conf) when list(Conf) ->
domain_1(suite) -> [];
domain_1(doc) -> [""];
-domain_1(Conf) when list(Conf) ->
+domain_1(Conf) when is_list(Conf) ->
?line E = empty_set(),
?line ER = relation([]),
?line {'EXIT', {badarg, _}} = (catch domain(relation([],3))),
@@ -1355,7 +1355,7 @@ domain_1(Conf) when list(Conf) ->
range_1(suite) -> [];
range_1(doc) -> [""];
-range_1(Conf) when list(Conf) ->
+range_1(Conf) when is_list(Conf) ->
?line E = empty_set(),
?line ER = relation([]),
?line {'EXIT', {badarg, _}} = (catch range(relation([],3))),
@@ -1367,7 +1367,7 @@ range_1(Conf) when list(Conf) ->
inverse_1(suite) -> [];
inverse_1(doc) -> [""];
-inverse_1(Conf) when list(Conf) ->
+inverse_1(Conf) when is_list(Conf) ->
?line E = empty_set(),
?line ER = relation([]),
?line {'EXIT', {badarg, _}} = (catch inverse(relation([],3))),
@@ -1391,7 +1391,7 @@ inverse_1(Conf) when list(Conf) ->
converse_1(suite) -> [];
converse_1(doc) -> [""];
-converse_1(Conf) when list(Conf) ->
+converse_1(Conf) when is_list(Conf) ->
?line E = empty_set(),
?line ER = relation([]),
?line {'EXIT', {badarg, _}} = (catch converse(relation([],3))),
@@ -1407,7 +1407,7 @@ converse_1(Conf) when list(Conf) ->
no_elements_1(suite) -> [];
no_elements_1(doc) -> [""];
-no_elements_1(Conf) when list(Conf) ->
+no_elements_1(Conf) when is_list(Conf) ->
?line 0 = no_elements(empty_set()),
?line 0 = no_elements(set([])),
?line 1 = no_elements(from_term([a])),
@@ -1419,7 +1419,7 @@ no_elements_1(Conf) when list(Conf) ->
image(suite) -> [];
image(doc) -> [""];
-image(Conf) when list(Conf) ->
+image(Conf) when is_list(Conf) ->
?line E = empty_set(),
?line ER = relation([]),
?line eval(image(E, E), E),
@@ -1441,7 +1441,7 @@ image(Conf) when list(Conf) ->
inverse_image(suite) -> [];
inverse_image(doc) -> [""];
-inverse_image(Conf) when list(Conf) ->
+inverse_image(Conf) when is_list(Conf) ->
?line E = empty_set(),
?line ER = relation([]),
?line eval(inverse_image(E, E), E),
@@ -1468,7 +1468,7 @@ inverse_image(Conf) when list(Conf) ->
composite_1(suite) -> [];
composite_1(doc) -> [""];
-composite_1(Conf) when list(Conf) ->
+composite_1(Conf) when is_list(Conf) ->
?line E = empty_set(),
?line EF = a_function([]),
?line eval(composite(E, E), E),
@@ -1520,7 +1520,7 @@ composite_1(Conf) when list(Conf) ->
relative_product_1(suite) -> [];
relative_product_1(doc) -> [""];
-relative_product_1(Conf) when list(Conf) ->
+relative_product_1(Conf) when is_list(Conf) ->
?line E = empty_set(),
?line ER = relation([]),
?line eval(relative_product1(E, E), E),
@@ -1548,7 +1548,7 @@ relative_product_1(Conf) when list(Conf) ->
relative_product_2(suite) -> [];
relative_product_2(doc) -> [""];
-relative_product_2(Conf) when list(Conf) ->
+relative_product_2(Conf) when is_list(Conf) ->
?line E = empty_set(),
?line ER = relation([]),
@@ -1597,7 +1597,7 @@ relative_product_2(Conf) when list(Conf) ->
product_1(suite) -> [];
product_1(doc) -> [""];
-product_1(Conf) when list(Conf) ->
+product_1(Conf) when is_list(Conf) ->
?line E = empty_set(),
?line eval(product(E, E), E),
?line eval(product(relation([]), E), E),
@@ -1625,7 +1625,7 @@ product_1(Conf) when list(Conf) ->
partition_1(suite) -> [];
partition_1(doc) -> [""];
-partition_1(Conf) when list(Conf) ->
+partition_1(Conf) when is_list(Conf) ->
?line E = empty_set(),
?line ER = relation([]),
?line Id = fun(A) -> A end,
@@ -1671,7 +1671,7 @@ partition_1(Conf) when list(Conf) ->
partition_3(suite) -> [];
partition_3(doc) -> [""];
-partition_3(Conf) when list(Conf) ->
+partition_3(Conf) when is_list(Conf) ->
?line E = empty_set(),
?line ER = relation([]),
@@ -1818,7 +1818,7 @@ lpartition(F, S1, S2) ->
multiple_relative_product(suite) -> [];
multiple_relative_product(doc) -> [""];
-multiple_relative_product(Conf) when list(Conf) ->
+multiple_relative_product(Conf) when is_list(Conf) ->
?line E = empty_set(),
?line ER = relation([]),
?line T = relation([{a,1},{a,11},{b,2},{c,3},{c,33},{d,4}]),
@@ -1842,7 +1842,7 @@ multiple_relative_product(Conf) when list(Conf) ->
digraph(suite) -> [];
digraph(doc) -> [""];
-digraph(Conf) when list(Conf) ->
+digraph(Conf) when is_list(Conf) ->
?line T0 = ets:all(),
?line E = empty_set(),
?line R = relation([{a,b},{b,c},{c,d},{d,a}]),
@@ -1901,7 +1901,7 @@ digraph(Conf) when list(Conf) ->
constant_function(suite) -> [];
constant_function(doc) -> [""];
-constant_function(Conf) when list(Conf) ->
+constant_function(Conf) when is_list(Conf) ->
?line E = empty_set(),
?line C = from_term(3),
?line eval(constant_function(E, C), E),
@@ -1913,7 +1913,7 @@ constant_function(Conf) when list(Conf) ->
misc(suite) -> [];
misc(doc) -> [""];
-misc(Conf) when list(Conf) ->
+misc(Conf) when is_list(Conf) ->
% find "relational" part of relation:
?line S = relation([{a,b},{b,c},{b,d},{c,d}]),
Id = fun(A) -> A end,
@@ -1943,7 +1943,7 @@ sofs_family(suite) ->
family_specification(suite) -> [];
family_specification(doc) -> [""];
-family_specification(Conf) when list(Conf) ->
+family_specification(Conf) when is_list(Conf) ->
E = empty_set(),
%% internal
?line eval(family_specification({sofs, is_set}, E), E),
@@ -1963,7 +1963,7 @@ family_specification(Conf) when list(Conf) ->
(catch family_specification(Fun3, F3)),
%% external
- IsList = {external, fun(L) when list(L) -> true; (_) -> false end},
+ IsList = {external, fun(L) when is_list(L) -> true; (_) -> false end},
?line eval(family_specification(IsList, E), E),
?line eval(family_specification(IsList, F1), F1),
MF = {external, fun(L) -> lists:member(3, L) end},
@@ -1975,7 +1975,7 @@ family_specification(Conf) when list(Conf) ->
family_domain_1(suite) -> [];
family_domain_1(doc) -> [""];
-family_domain_1(Conf) when list(Conf) ->
+family_domain_1(Conf) when is_list(Conf) ->
?line E = empty_set(),
?line ER = from_term([{a,[]},{b,[]}],[{atom,[{atom,atom}]}]),
?line EF = from_term([{a,[]},{b,[]}],[{atom,[atom]}]),
@@ -2001,7 +2001,7 @@ family_domain_1(Conf) when list(Conf) ->
family_range_1(suite) -> [];
family_range_1(doc) -> [""];
-family_range_1(Conf) when list(Conf) ->
+family_range_1(Conf) when is_list(Conf) ->
?line E = empty_set(),
?line ER = from_term([{a,[]},{b,[]}],[{atom,[{atom,atom}]}]),
?line EF = from_term([{a,[]},{b,[]}],[{atom,[atom]}]),
@@ -2023,7 +2023,7 @@ family_range_1(Conf) when list(Conf) ->
family_to_relation_1(suite) -> [];
family_to_relation_1(doc) -> [""];
-family_to_relation_1(Conf) when list(Conf) ->
+family_to_relation_1(Conf) when is_list(Conf) ->
?line E = empty_set(),
?line ER = relation([]),
?line EF = family([]),
@@ -2037,7 +2037,7 @@ family_to_relation_1(Conf) when list(Conf) ->
union_of_family_1(suite) -> [];
union_of_family_1(doc) -> [""];
-union_of_family_1(Conf) when list(Conf) ->
+union_of_family_1(Conf) when is_list(Conf) ->
?line E = empty_set(),
?line EF = from_term([{a,[]},{b,[]}],[{atom,[atom]}]),
?line eval(union_of_family(E), E),
@@ -2052,7 +2052,7 @@ union_of_family_1(Conf) when list(Conf) ->
intersection_of_family_1(suite) -> [];
intersection_of_family_1(doc) -> [""];
-intersection_of_family_1(Conf) when list(Conf) ->
+intersection_of_family_1(Conf) when is_list(Conf) ->
?line EF = from_term([{a,[]},{b,[]}],[{atom,[atom]}]),
?line eval(intersection_of_family(EF), set([])),
?line FR = from_term([{a,[1,2,3]},{b,[2,3]},{c,[3,4,5]}]),
@@ -2066,7 +2066,7 @@ intersection_of_family_1(Conf) when list(Conf) ->
family_projection(suite) -> [];
family_projection(doc) -> [""];
-family_projection(Conf) when list(Conf) ->
+family_projection(Conf) when is_list(Conf) ->
SSType = [{atom,[[atom]]}],
SRType = [{atom,[{atom,atom}]}],
?line E = empty_set(),
@@ -2127,7 +2127,7 @@ family_projection(Conf) when list(Conf) ->
family_difference(suite) -> [];
family_difference(doc) -> [""];
-family_difference(Conf) when list(Conf) ->
+family_difference(Conf) when is_list(Conf) ->
?line E = empty_set(),
?line EF = family([]),
?line F9 = from_term([{b,[b,c]}]),
@@ -2164,7 +2164,7 @@ family_difference(Conf) when list(Conf) ->
family_intersection_1(suite) -> [];
family_intersection_1(doc) -> [""];
-family_intersection_1(Conf) when list(Conf) ->
+family_intersection_1(Conf) when is_list(Conf) ->
?line E = empty_set(),
?line EF = family([]),
?line ES = from_term([], [{atom,[[atom]]}]),
@@ -2184,7 +2184,7 @@ family_intersection_1(Conf) when list(Conf) ->
family_intersection_2(suite) -> [];
family_intersection_2(doc) -> [""];
-family_intersection_2(Conf) when list(Conf) ->
+family_intersection_2(Conf) when is_list(Conf) ->
?line E = empty_set(),
?line EF = family([]),
?line F1 = from_term([{a,[1,2]},{b,[4,5]},{c,[7,8]},{d,[10,11]}]),
@@ -2215,7 +2215,7 @@ family_intersection_2(Conf) when list(Conf) ->
family_union_1(suite) -> [];
family_union_1(doc) -> [""];
-family_union_1(Conf) when list(Conf) ->
+family_union_1(Conf) when is_list(Conf) ->
?line E = empty_set(),
?line EF = family([]),
?line ES = from_term([], [{atom,[[atom]]}]),
@@ -2230,7 +2230,7 @@ family_union_1(Conf) when list(Conf) ->
family_union_2(suite) -> [];
family_union_2(doc) -> [""];
-family_union_2(Conf) when list(Conf) ->
+family_union_2(Conf) when is_list(Conf) ->
?line E = empty_set(),
?line EF = family([]),
?line F1 = from_term([{a,[1,2]},{b,[4,5]},{c,[7,8]},{d,[10,11]}]),
@@ -2259,7 +2259,7 @@ family_union_2(Conf) when list(Conf) ->
partition_family(suite) -> [];
partition_family(doc) -> [""];
-partition_family(Conf) when list(Conf) ->
+partition_family(Conf) when is_list(Conf) ->
?line E = empty_set(),
%% set of ordered sets
diff --git a/lib/stdlib/test/supervisor_SUITE.erl b/lib/stdlib/test/supervisor_SUITE.erl
index b5d9ca44bf..039ea298c4 100644
--- a/lib/stdlib/test/supervisor_SUITE.erl
+++ b/lib/stdlib/test/supervisor_SUITE.erl
@@ -1,19 +1,19 @@
%%
%% %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
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
-%%
+%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
-%%
+%%
%% %CopyrightEnd%
%%
%% Description: Tests supervisor.erl
@@ -50,7 +50,7 @@
simple_one_for_one_extra/1]).
%% Misc tests
--export([child_unlink/1, tree/1]).
+-export([child_unlink/1, tree/1, count_children_memory/1]).
%-------------------------------------------------------------------------
@@ -60,7 +60,8 @@ all(suite) ->
child_adm_simple, extra_return, child_specs,
restart_one_for_one, restart_one_for_all,
restart_simple_one_for_one, restart_rest_for_one,
- normal_termination, abnormal_termination, child_unlink, tree]}.
+ normal_termination, abnormal_termination, child_unlink, tree,
+ count_children_memory]}.
start(InitResult) ->
@@ -72,6 +73,15 @@ init(fail) ->
init(InitResult) ->
InitResult.
+%% Respect proplist return of supervisor:count_children
+get_child_counts(Supervisor) ->
+ Counts = supervisor:count_children(Supervisor),
+ [proplists:get_value(specs, Counts),
+ proplists:get_value(active, Counts),
+ proplists:get_value(supervisors, Counts),
+ proplists:get_value(workers, Counts)].
+
+
%-------------------------------------------------------------------------
%
% Test cases starts here.
@@ -89,7 +99,7 @@ sup_start_normal(doc) ->
["Tests that the supervisor process starts correctly and that it "
"can be terminated gracefully."];
sup_start_normal(suite) -> [];
-sup_start_normal(Config) when list(Config) ->
+sup_start_normal(Config) when is_list(Config) ->
process_flag(trap_exit, true),
?line {ok, Pid} = start({ok, {{one_for_one, 2, 3600}, []}}),
?line exit(Pid, shutdown),
@@ -107,7 +117,7 @@ sup_start_normal(Config) when list(Config) ->
sup_start_ignore_init(doc) ->
["Tests what happens if init-callback returns ignore"];
sup_start_ignore_init(suite) -> [];
-sup_start_ignore_init(Config) when list(Config) ->
+sup_start_ignore_init(Config) when is_list(Config) ->
process_flag(trap_exit, true),
?line ignore = start(ignore),
@@ -127,7 +137,7 @@ sup_start_ignore_init(Config) when list(Config) ->
sup_start_ignore_child(doc) ->
["Tests what happens if init-callback returns ignore"];
sup_start_ignore_child(suite) -> [];
-sup_start_ignore_child(Config) when list(Config) ->
+sup_start_ignore_child(Config) when is_list(Config) ->
process_flag(trap_exit, true),
?line {ok, _Pid} = start({ok, {{one_for_one, 2, 3600}, []}}),
Child1 = {child1, {supervisor_1, start_child, [ignore]},
@@ -140,13 +150,15 @@ sup_start_ignore_child(Config) when list(Config) ->
?line [{child2, CPid2, worker, []},{child1, undefined, worker, []}]
= supervisor:which_children(sup_test),
+ ?line [2,1,0,2] = get_child_counts(sup_test),
+
ok.
%-------------------------------------------------------------------------
sup_start_error_return(doc) ->
["Tests what happens if init-callback returns a invalid value"];
sup_start_error_return(suite) -> [];
-sup_start_error_return(Config) when list(Config) ->
+sup_start_error_return(Config) when is_list(Config) ->
process_flag(trap_exit, true),
?line {error, Term} = start(invalid),
@@ -165,7 +177,7 @@ sup_start_error_return(Config) when list(Config) ->
sup_start_fail(doc) ->
["Tests what happens if init-callback fails"];
sup_start_fail(suite) -> [];
-sup_start_fail(Config) when list(Config) ->
+sup_start_fail(Config) when is_list(Config) ->
process_flag(trap_exit, true),
?line {error, Term} = start(fail),
@@ -192,7 +204,7 @@ sup_stop_infinity(doc) ->
"for children of type supervisor"];
sup_stop_infinity(suite) -> [];
-sup_stop_infinity(Config) when list(Config) ->
+sup_stop_infinity(Config) when is_list(Config) ->
process_flag(trap_exit, true),
?line {ok, Pid} = start({ok, {{one_for_one, 2, 3600}, []}}),
Child1 = {child1, {supervisor_1, start_child, []},
@@ -230,7 +242,7 @@ sup_stop_timeout(doc) ->
["See sup_stop/1 when Shutdown = 1000"];
sup_stop_timeout(suite) -> [];
-sup_stop_timeout(Config) when list(Config) ->
+sup_stop_timeout(Config) when is_list(Config) ->
process_flag(trap_exit, true),
?line {ok, Pid} = start({ok, {{one_for_one, 2, 3600}, []}}),
Child1 = {child1, {supervisor_1, start_child, []},
@@ -278,7 +290,7 @@ sup_stop_brutal_kill(doc) ->
["See sup_stop/1 when Shutdown = brutal_kill"];
sup_stop_brutal_kill(suite) -> [];
-sup_stop_brutal_kill(Config) when list(Config) ->
+sup_stop_brutal_kill(Config) when is_list(Config) ->
process_flag(trap_exit, true),
?line {ok, Pid} = start({ok, {{one_for_one, 2, 3600}, []}}),
Child1 = {child1, {supervisor_1, start_child, []},
@@ -327,7 +339,7 @@ extra_return(doc) ->
"and restart_child/2"];
extra_return(suite) -> [];
-extra_return(Config) when list(Config) ->
+extra_return(Config) when is_list(Config) ->
process_flag(trap_exit, true),
Child = {child1, {supervisor_1, start_child, [extra_return]},
permanent, 1000,
@@ -341,6 +353,8 @@ extra_return(Config) when list(Config) ->
?line {error, running} = supervisor:delete_child(sup_test, child1),
?line {error, running} = supervisor:restart_child(sup_test, child1),
?line [{child1, CPid, worker, []}] = supervisor:which_children(sup_test),
+ ?line [1,1,0,1] = get_child_counts(sup_test),
+
?line ok = supervisor:terminate_child(sup_test, child1),
receive
{'EXIT', CPid, shutdown} -> ok;
@@ -350,29 +364,39 @@ extra_return(Config) when list(Config) ->
?line test_server:fail(no_child_termination)
end,
?line [{child1,undefined,worker,[]}] = supervisor:which_children(sup_test),
+ ?line [1,0,0,1] = get_child_counts(sup_test),
+
?line {ok, CPid2,extra_return} =
supervisor:restart_child(sup_test, child1),
?line [{child1, CPid2, worker, []}] = supervisor:which_children(sup_test),
+ ?line [1,1,0,1] = get_child_counts(sup_test),
+
?line ok = supervisor:terminate_child(sup_test, child1),
?line ok = supervisor:terminate_child(sup_test, child1),
?line ok = supervisor:delete_child(sup_test, child1),
?line {error, not_found} = supervisor:restart_child(sup_test, child1),
?line [] = supervisor:which_children(sup_test),
+ ?line [0,0,0,0] = get_child_counts(sup_test),
+
?line {ok, CPid3, extra_return} = supervisor:start_child(sup_test, Child),
?line [{child1, CPid3, worker, []}] = supervisor:which_children(sup_test),
+ ?line [1,1,0,1] = get_child_counts(sup_test),
+
ok.
%-------------------------------------------------------------------------
child_adm(doc)->
["Test API functions start_child/2, terminate_child/2, delete_child/2 "
- "restart_child/2, which_children/1. Only correct childspecs are used, "
- "handling of incorrect childspecs is tested in child_specs/1"];
+ "restart_child/2, which_children/1, count_children/1. Only correct "
+ "childspecs are used, handling of incorrect childspecs is tested in "
+ "child_specs/1"];
child_adm(suite) -> [];
-child_adm(Config) when list(Config) ->
+child_adm(Config) when is_list(Config) ->
process_flag(trap_exit, true),
Child = {child1, {supervisor_1, start_child, []}, permanent, 1000,
worker, []},
?line {ok, _Pid} = start({ok, {{one_for_one, 2, 3600}, [Child]}}),
?line [{child1, CPid, worker, []}] = supervisor:which_children(sup_test),
+ ?line [1,1,0,1] = get_child_counts(sup_test),
link(CPid),
%% Start of an already runnig process
@@ -392,6 +416,7 @@ child_adm(Config) when list(Config) ->
?line test_server:fail(no_child_termination)
end,
?line [{child1,undefined,worker,[]}] = supervisor:which_children(sup_test),
+ ?line [1,0,0,1] = get_child_counts(sup_test),
%% Like deleting something that does not exist, it will succeed!
?line ok = supervisor:terminate_child(sup_test, child1),
@@ -402,6 +427,7 @@ child_adm(Config) when list(Config) ->
%% Restart
?line {ok, CPid2} = supervisor:restart_child(sup_test, child1),
?line [{child1, CPid2, worker, []}] = supervisor:which_children(sup_test),
+ ?line [1,1,0,1] = get_child_counts(sup_test),
?line {error, running} = supervisor:restart_child(sup_test, child1),
?line {error, not_found} = supervisor:restart_child(sup_test, child2),
@@ -414,15 +440,19 @@ child_adm(Config) when list(Config) ->
?line ok = supervisor:delete_child(sup_test, child1),
?line {error, not_found} = supervisor:restart_child(sup_test, child1),
?line [] = supervisor:which_children(sup_test),
+ ?line [0,0,0,0] = get_child_counts(sup_test),
%% Start
?line {'EXIT',{noproc,{gen_server,call, _}}} =
(catch supervisor:start_child(foo, Child)),
?line {ok, CPid3} = supervisor:start_child(sup_test, Child),
?line [{child1, CPid3, worker, []}] = supervisor:which_children(sup_test),
+ ?line [1,1,0,1] = get_child_counts(sup_test),
?line {'EXIT',{noproc,{gen_server,call,[foo,which_children,infinity]}}}
= (catch supervisor:which_children(foo)),
+ ?line {'EXIT',{noproc,{gen_server,call,[foo,count_children,infinity]}}}
+ = (catch supervisor:count_children(foo)),
ok.
%-------------------------------------------------------------------------
child_adm_simple(doc) ->
@@ -430,12 +460,13 @@ child_adm_simple(doc) ->
"restart_child/2 are not valid for a simple_one_for_one supervisor "
"check that the correct error message is returned."];
child_adm_simple(suite) -> [];
-child_adm_simple(Config) when list(Config) ->
+child_adm_simple(Config) when is_list(Config) ->
Child = {child, {supervisor_1, start_child, []}, permanent, 1000,
worker, []},
?line {ok, _Pid} = start({ok, {{simple_one_for_one, 2, 3600}, [Child]}}),
%% In simple_one_for_one all children are added dynamically
?line [] = supervisor:which_children(sup_test),
+ ?line [1,0,0,0] = get_child_counts(sup_test),
%% Start
?line {'EXIT',{noproc,{gen_server,call, _}}} =
@@ -443,12 +474,14 @@ child_adm_simple(Config) when list(Config) ->
?line {ok, CPid1} = supervisor:start_child(sup_test, []),
?line [{undefined, CPid1, worker, []}] =
supervisor:which_children(sup_test),
+ ?line [1,1,0,1] = get_child_counts(sup_test),
?line {ok, CPid2} = supervisor:start_child(sup_test, []),
?line Children = supervisor:which_children(sup_test),
?line 2 = length(Children),
?line true = lists:member({undefined, CPid2, worker, []}, Children),
?line true = lists:member({undefined, CPid1, worker, []}, Children),
+ ?line [1,2,0,2] = get_child_counts(sup_test),
%% Termination
?line {error, simple_one_for_one} =
@@ -467,7 +500,7 @@ child_adm_simple(Config) when list(Config) ->
child_specs(doc) ->
["Tests child specs, invalid formats should be rejected."];
child_specs(suite) -> [];
-child_specs(Config) when list(Config) ->
+child_specs(Config) when is_list(Config) ->
process_flag(trap_exit, true),
?line {ok, _Pid} = start({ok, {{one_for_one, 2, 3600}, []}}),
?line {error, _} = supervisor:start_child(sup_test, hej),
@@ -526,7 +559,7 @@ normal_termination(suite) ->
permanent_normal(doc) ->
["A permanent child should always be restarted"];
permanent_normal(suite) -> [];
-permanent_normal(Config) when list(Config) ->
+permanent_normal(Config) when is_list(Config) ->
?line {ok, _SupPid} = start({ok, {{one_for_one, 2, 3600}, []}}),
Child1 = {child1, {supervisor_1, start_child, []}, permanent, 1000,
worker, []},
@@ -541,14 +574,16 @@ permanent_normal(Config) when list(Config) ->
ok;
false ->
?line test_server:fail({permanent_child_not_restarted, Child1})
- end.
+ end,
+ ?line [1,1,0,1] = get_child_counts(sup_test),
+ ok.
%-------------------------------------------------------------------------
transient_normal(doc) ->
["A transient child should not be restarted if it exits with "
"reason normal"];
transient_normal(suite) -> [];
-transient_normal(Config) when list(Config) ->
+transient_normal(Config) when is_list(Config) ->
?line {ok, _SupPid} = start({ok, {{one_for_one, 2, 3600}, []}}),
Child1 = {child1, {supervisor_1, start_child, []}, transient, 1000,
worker, []},
@@ -558,13 +593,15 @@ transient_normal(Config) when list(Config) ->
CPid1 ! stop,
test_server:sleep(100),
- ?line [{child1,undefined,worker,[]}] = supervisor:which_children(sup_test).
+ ?line [{child1,undefined,worker,[]}] = supervisor:which_children(sup_test),
+ ?line [1,0,0,1] = get_child_counts(sup_test),
+ ok.
%-------------------------------------------------------------------------
temporary_normal(doc) ->
["A temporary process should never be restarted"];
temporary_normal(suite) -> [];
-temporary_normal(Config) when list(Config) ->
+temporary_normal(Config) when is_list(Config) ->
?line {ok, _SupPid} = start({ok, {{one_for_one, 2, 3600}, []}}),
Child1 = {child1, {supervisor_1, start_child, []}, temporary, 1000,
worker, []},
@@ -574,8 +611,10 @@ temporary_normal(Config) when list(Config) ->
CPid1 ! stop,
test_server:sleep(100),
- ?line [{child1,undefined,worker,[]}] = supervisor:which_children(sup_test).
+ ?line [{child1,undefined,worker,[]}] = supervisor:which_children(sup_test),
+ ?line [1,0,0,1] = get_child_counts(sup_test),
+ ok.
%-------------------------------------------------------------------------
abnormal_termination(doc) ->
["Testes the supervisors behaviour if a child dies with reason abnormal"];
@@ -586,7 +625,7 @@ abnormal_termination(suite) ->
permanent_abnormal(doc) ->
["A permanent child should always be restarted"];
permanent_abnormal(suite) -> [];
-permanent_abnormal(Config) when list(Config) ->
+permanent_abnormal(Config) when is_list(Config) ->
?line {ok, _SupPid} = start({ok, {{one_for_one, 2, 3600}, []}}),
Child1 = {child1, {supervisor_1, start_child, []}, permanent, 1000,
worker, []},
@@ -601,14 +640,16 @@ permanent_abnormal(Config) when list(Config) ->
ok;
false ->
?line test_server:fail({permanent_child_not_restarted, Child1})
- end.
+ end,
+ ?line [1,1,0,1] = get_child_counts(sup_test),
+ ok.
%-------------------------------------------------------------------------
transient_abnormal(doc) ->
["A transient child should be restarted if it exits with "
"reason abnormal"];
transient_abnormal(suite) -> [];
-transient_abnormal(Config) when list(Config) ->
+transient_abnormal(Config) when is_list(Config) ->
?line {ok, _SupPid} = start({ok, {{one_for_one, 2, 3600}, []}}),
Child1 = {child1, {supervisor_1, start_child, []}, transient, 1000,
worker, []},
@@ -624,14 +665,15 @@ transient_abnormal(Config) when list(Config) ->
ok;
false ->
?line test_server:fail({transient_child_not_restarted, Child1})
- end.
-
+ end,
+ ?line [1,1,0,1] = get_child_counts(sup_test),
+ ok.
%-------------------------------------------------------------------------
temporary_abnormal(doc) ->
["A temporary process should never be restarted"];
temporary_abnormal(suite) -> [];
-temporary_abnormal(Config) when list(Config) ->
+temporary_abnormal(Config) when is_list(Config) ->
?line {ok, _SupPid} = start({ok, {{one_for_one, 2, 3600}, []}}),
Child1 = {child1, {supervisor_1, start_child, []}, temporary, 1000,
worker, []},
@@ -641,8 +683,10 @@ temporary_abnormal(Config) when list(Config) ->
CPid1 ! die,
test_server:sleep(100),
- ?line [{child1,undefined,worker,[]}] = supervisor:which_children(sup_test).
+ ?line [{child1,undefined,worker,[]}] = supervisor:which_children(sup_test),
+ ?line [1,0,0,1] = get_child_counts(sup_test),
+ ok.
%-------------------------------------------------------------------------
restart_one_for_one(doc) ->
["Test that the one_for_one strategy works."];
@@ -653,7 +697,7 @@ restart_one_for_one(suite) -> [one_for_one, one_for_one_escalation].
one_for_one(doc) ->
["Test the one_for_one base case."];
one_for_one(suite) -> [];
-one_for_one(Config) when list(Config) ->
+one_for_one(Config) when is_list(Config) ->
process_flag(trap_exit, true),
Child1 = {child1, {supervisor_1, start_child, []}, permanent, 1000,
worker, []},
@@ -679,6 +723,7 @@ one_for_one(Config) when list(Config) ->
end;
true -> ?line test_server:fail({bad_child_list, Children})
end,
+ ?line [2,2,0,2] = get_child_counts(sup_test),
%% Test restart frequency property
CPid2 ! die,
@@ -697,7 +742,7 @@ one_for_one(Config) when list(Config) ->
one_for_one_escalation(doc) ->
["Test restart escalation on a one_for_one supervisor."];
one_for_one_escalation(suite) -> [];
-one_for_one_escalation(Config) when list(Config) ->
+one_for_one_escalation(Config) when is_list(Config) ->
process_flag(trap_exit, true),
Child1 = {child1, {supervisor_1, start_child, [error]},
permanent, 1000,
@@ -737,7 +782,7 @@ restart_one_for_all(suite) ->
one_for_all(doc) ->
["Test the one_for_all base case."];
one_for_all(suite) -> [];
-one_for_all(Config) when list(Config) ->
+one_for_all(Config) when is_list(Config) ->
process_flag(trap_exit, true),
Child1 = {child1, {supervisor_1, start_child, []}, permanent, 1000,
worker, []},
@@ -772,6 +817,8 @@ one_for_all(Config) when list(Config) ->
true -> ?line test_server:fail(bad_child);
false -> ok
end,
+ ?line [2,2,0,2] = get_child_counts(sup_test),
+
%%% Test restart frequency property
[{_, Pid3, _, _}|_] = supervisor:which_children(sup_test),
Pid3 ! die,
@@ -788,7 +835,7 @@ one_for_all(Config) when list(Config) ->
one_for_all_escalation(doc) ->
["Test restart escalation on a one_for_all supervisor."];
one_for_all_escalation(suite) -> [];
-one_for_all_escalation(Config) when list(Config) ->
+one_for_all_escalation(Config) when is_list(Config) ->
process_flag(trap_exit, true),
Child1 = {child1, {supervisor_1, start_child, []}, permanent, 1000,
worker, []},
@@ -830,7 +877,7 @@ restart_simple_one_for_one(suite) ->
simple_one_for_one(doc) ->
["Test the simple_one_for_one base case."];
simple_one_for_one(suite) -> [];
-simple_one_for_one(Config) when list(Config) ->
+simple_one_for_one(Config) when is_list(Config) ->
process_flag(trap_exit, true),
Child = {child, {supervisor_1, start_child, []}, permanent, 1000,
worker, []},
@@ -854,6 +901,8 @@ simple_one_for_one(Config) when list(Config) ->
end;
true -> ?line test_server:fail({bad_child_list, Children})
end,
+ ?line [1,2,0,2] = get_child_counts(sup_test),
+
%% Test restart frequency property
CPid2 ! die,
receive
@@ -872,7 +921,7 @@ simple_one_for_one_extra(doc) ->
["Tests automatic restart of children "
"who's start function return extra info."];
simple_one_for_one_extra(suite) -> [];
-simple_one_for_one_extra(Config) when list(Config) ->
+simple_one_for_one_extra(Config) when is_list(Config) ->
process_flag(trap_exit, true),
Child = {child, {supervisor_1, start_child, [extra_info]},
permanent, 1000, worker, []},
@@ -896,6 +945,8 @@ simple_one_for_one_extra(Config) when list(Config) ->
end;
true -> ?line test_server:fail({bad_child_list, Children})
end,
+ ?line [1,2,0,2] = get_child_counts(sup_test),
+
CPid2 ! die,
receive
{'EXIT', CPid2, _} -> ok
@@ -912,7 +963,7 @@ simple_one_for_one_extra(Config) when list(Config) ->
simple_one_for_one_escalation(doc) ->
["Test restart escalation on a simple_one_for_one supervisor."];
simple_one_for_one_escalation(suite) -> [];
-simple_one_for_one_escalation(Config) when list(Config) ->
+simple_one_for_one_escalation(Config) when is_list(Config) ->
process_flag(trap_exit, true),
Child = {child, {supervisor_1, start_child, []}, permanent, 1000,
worker, []},
@@ -947,7 +998,7 @@ restart_rest_for_one(suite) -> [rest_for_one, rest_for_one_escalation].
rest_for_one(doc) ->
["Test the rest_for_one base case."];
rest_for_one(suite) -> [];
-rest_for_one(Config) when list(Config) ->
+rest_for_one(Config) when is_list(Config) ->
process_flag(trap_exit, true),
Child1 = {child1, {supervisor_1, start_child, []}, permanent, 1000,
worker, []},
@@ -962,6 +1013,8 @@ rest_for_one(Config) when list(Config) ->
link(CPid2),
?line {ok, CPid3} = supervisor:start_child(sup_test, Child3),
link(CPid3),
+ ?line [3,3,0,3] = get_child_counts(sup_test),
+
CPid2 ! die,
receive
{'EXIT', CPid2, died} -> ok;
@@ -987,6 +1040,8 @@ rest_for_one(Config) when list(Config) ->
if length(Children) == 3 -> ok;
true -> ?line test_server:fail({bad_child_list, Children})
end,
+ ?line [3,3,0,3] = get_child_counts(sup_test),
+
%% Test that no old children is still alive
SCh = lists:map(fun({_,P,_,_}) -> P end, Children),
case lists:member(CPid1, SCh) of
@@ -1018,7 +1073,7 @@ rest_for_one(Config) when list(Config) ->
rest_for_one_escalation(doc) ->
["Test restart escalation on a rest_for_one supervisor."];
rest_for_one_escalation(suite) -> [];
-rest_for_one_escalation(Config) when list(Config) ->
+rest_for_one_escalation(Config) when is_list(Config) ->
process_flag(trap_exit, true),
Child1 = {child1, {supervisor_1, start_child, []}, permanent, 1000,
worker, []},
@@ -1052,7 +1107,7 @@ rest_for_one_escalation(Config) when list(Config) ->
child_unlink(doc)-> ["Test that the supervisor does not hang forever if "
"the child unliks and then is terminated by the supervisor."];
child_unlink(suite) -> [];
-child_unlink(Config) when list(Config) ->
+child_unlink(Config) when is_list(Config) ->
?line {ok, SupPid} = start({ok, {{one_for_one, 2, 3600}, []}}),
@@ -1081,7 +1136,7 @@ tree(doc) ->
["Test a basic supervison tree."];
tree(suite) ->
[];
-tree(Config) when list(Config) ->
+tree(Config) when is_list(Config) ->
process_flag(trap_exit, true),
Child1 = {child1, {supervisor_1, start_child, []},
@@ -1114,15 +1169,19 @@ tree(Config) when list(Config) ->
%% Child supervisors
?line {ok, Sup1} = supervisor:start_child(Pid, ChildSup1),
?line {ok, Sup2} = supervisor:start_child(Pid, ChildSup2),
+ ?line [2,2,2,0] = get_child_counts(Pid),
%% Workers
-
?line [{_, CPid2, _, _},{_, CPid1, _, _}] =
supervisor:which_children(Sup1),
+ ?line [2,2,0,2] = get_child_counts(Sup1),
+ ?line [0,0,0,0] = get_child_counts(Sup2),
%% Dynamic children
?line {ok, CPid3} = supervisor:start_child(Sup2, Child3),
?line {ok, CPid4} = supervisor:start_child(Sup2, Child4),
+ ?line [2,2,0,2] = get_child_counts(Sup1),
+ ?line [2,2,0,2] = get_child_counts(Sup2),
link(Sup1),
link(Sup2),
@@ -1144,9 +1203,11 @@ tree(Config) when list(Config) ->
?line [{_, CPid2, _, _},{_, CPid1, _, _}] =
supervisor:which_children(Sup1),
+ ?line [2,2,0,2] = get_child_counts(Sup1),
?line [{_, NewCPid4, _, _},{_, CPid3, _, _}] =
supervisor:which_children(Sup2),
+ ?line [2,2,0,2] = get_child_counts(Sup2),
link(NewCPid4),
@@ -1195,9 +1256,99 @@ tree(Config) when list(Config) ->
?line [{supchild2, NewSup2, _, _},{supchild1, NewSup1, _, _}] =
supervisor:which_children(Pid),
+ ?line [2,2,2,0] = get_child_counts(Pid),
?line [{child2, _, _, _},{child1, _, _, _}] =
supervisor:which_children(NewSup1),
+ ?line [2,2,0,2] = get_child_counts(NewSup1),
+
?line [] = supervisor:which_children(NewSup2),
+ ?line [0,0,0,0] = get_child_counts(NewSup2),
ok.
+%-------------------------------------------------------------------------
+count_children_allocator_test(MemoryState) ->
+ Allocators = [temp_alloc, eheap_alloc, binary_alloc, ets_alloc,
+ driver_alloc, sl_alloc, ll_alloc, fix_alloc, std_alloc,
+ sys_alloc],
+ MemoryStateList = element(4, MemoryState),
+ AllocTypes = [lists:keyfind(Alloc, 1, MemoryStateList)
+ || Alloc <- Allocators],
+ AllocStates = [lists:keyfind(e, 1, AllocValue)
+ || {_Type, AllocValue} <- AllocTypes],
+ lists:all(fun(State) -> State == {e, true} end, AllocStates).
+
+count_children_memory(doc) ->
+ ["Test that which_children eats memory, but count_children does not."];
+count_children_memory(suite) ->
+ MemoryState = erlang:system_info(allocator),
+ case count_children_allocator_test(MemoryState) of
+ true -> [];
+ false ->
+ {skip, "+Meamin used during test; erlang:memory/1 not available"}
+ end;
+count_children_memory(Config) when is_list(Config) ->
+ process_flag(trap_exit, true),
+ Child = {child, {supervisor_1, start_child, []}, temporary, 1000,
+ worker, []},
+ ?line {ok, _Pid} = start({ok, {{simple_one_for_one, 2, 3600}, [Child]}}),
+ [supervisor:start_child(sup_test, []) || _Ignore <- lists:seq(1,1000)],
+
+ garbage_collect(),
+ _Size1 = erlang:memory(processes_used),
+ Children = supervisor:which_children(sup_test),
+ _Size2 = erlang:memory(processes_used),
+ ChildCount = get_child_counts(sup_test),
+ Size3 = erlang:memory(processes_used),
+
+ [supervisor:start_child(sup_test, []) || _Ignore2 <- lists:seq(1,1000)],
+
+ garbage_collect(),
+ Children2 = supervisor:which_children(sup_test),
+ Size4 = erlang:memory(processes_used),
+ ChildCount2 = get_child_counts(sup_test),
+ Size5 = erlang:memory(processes_used),
+
+ garbage_collect(),
+ Children3 = supervisor:which_children(sup_test),
+ Size6 = erlang:memory(processes_used),
+ ChildCount3 = get_child_counts(sup_test),
+ Size7 = erlang:memory(processes_used),
+
+ ?line 1000 = length(Children),
+ ?line [1,1000,0,1000] = ChildCount,
+ ?line 2000 = length(Children2),
+ ?line [1,2000,0,2000] = ChildCount2,
+ ?line Children3 = Children2,
+ ?line ChildCount3 = ChildCount2,
+
+ %% count_children consumes memory using an accumulator function,
+ %% but the space can be reclaimed incrementally, whereas
+ %% which_children generates a return list.
+ case (Size5 =< Size4) of
+ true -> ok;
+ false ->
+ ?line test_server:fail({count_children, used_more_memory})
+ end,
+ case Size7 =< Size6 of
+ true -> ok;
+ false ->
+ ?line test_server:fail({count_children, used_more_memory})
+ end,
+
+ case Size4 > Size3 of
+ true -> ok;
+ false ->
+ ?line test_server:fail({which_children, used_no_memory})
+ end,
+ case Size6 > Size5 of
+ true -> ok;
+ false ->
+ ?line test_server:fail({which_children, used_no_memory})
+ end,
+
+ [exit(Pid, kill) || {undefined, Pid, worker, _Modules} <- Children3],
+ test_server:sleep(100),
+ ?line [1,0,0,0] = get_child_counts(sup_test),
+
+ ok.
diff --git a/lib/stdlib/test/tar_SUITE.erl b/lib/stdlib/test/tar_SUITE.erl
index af687ed2e1..7646f4c249 100644
--- a/lib/stdlib/test/tar_SUITE.erl
+++ b/lib/stdlib/test/tar_SUITE.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(tar_SUITE).
@@ -183,7 +183,7 @@ atomic(doc) ->
"and uncompressed archives."
"Also test the 'cooked' option."];
atomic(suite) -> [];
-atomic(Config) when list(Config) ->
+atomic(Config) when is_list(Config) ->
?line ok = file:set_cwd(?config(priv_dir, Config)),
?line DataFiles = data_files(),
?line Names = [Name || {Name,_,_} <- DataFiles],
@@ -369,7 +369,7 @@ try_bad(Name0, Reason, Config) ->
case catch erl_tar:format_error(Reason) of
{'EXIT', CrashReason} ->
test_server:fail({format_error, crashed, CrashReason});
- String when list(String) ->
+ String when is_list(String) ->
io:format("format_error(~p) -> ~s", [Reason, String]);
Other ->
test_server:fail({format_error, returned, Other})
@@ -413,7 +413,7 @@ try_error(M, F, A, Error) ->
case catch erl_tar:format_error(Error) of
{'EXIT', FReason} ->
test_server:fail({format_error, crashed, FReason});
- String when list(String) ->
+ String when is_list(String) ->
io:format("format_error(~p) -> ~s", [Error, String]);
Other ->
test_server:fail({format_error, returned, Other})
@@ -431,7 +431,7 @@ remove_prefix(_, Result) ->
extract_from_binary(doc) ->
"Test extracting a tar archive from a binary.";
-extract_from_binary(Config) when list(Config) ->
+extract_from_binary(Config) when is_list(Config) ->
?line DataDir = ?config(data_dir, Config),
?line PrivDir = ?config(priv_dir, Config),
?line Long = filename:join(DataDir, "no_fancy_stuff.tar"),
diff --git a/lib/stdlib/test/timer_SUITE.erl b/lib/stdlib/test/timer_SUITE.erl
index 86d8612b56..5f38c91c64 100644
--- a/lib/stdlib/test/timer_SUITE.erl
+++ b/lib/stdlib/test/timer_SUITE.erl
@@ -1,19 +1,19 @@
%%
%% %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
%% 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(timer_SUITE).
@@ -271,7 +271,7 @@ collect(N, {E,A,B}, I) ->
print_report ->
print_report({E,A,B,I}),
collect(N,{E,A,B}, I);
- {Pid, get_report} when pid(Pid) ->
+ {Pid, get_report} when is_pid(Pid) ->
Pid ! {report, {E, A, B, I}},
collect(N,{E,A,B}, I);
reset ->
diff --git a/lib/stdlib/test/unicode_SUITE.erl b/lib/stdlib/test/unicode_SUITE.erl
index 706445005c..141ac64606 100644
--- a/lib/stdlib/test/unicode_SUITE.erl
+++ b/lib/stdlib/test/unicode_SUITE.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%
%%
-module(unicode_SUITE).
@@ -276,7 +276,7 @@ ex_latin1(Config) when is_list(Config) ->
unicode:characters_to_list(make_unaligned(MissingLastByte),unicode),
?line DoubleSize16 = byte_size(DoubleUtf16),
- ?line DoubleUtf16_2 = erlang:concat_binary([DoubleUtf16,<<16#FFFFF/utf16-big>>]),
+ ?line DoubleUtf16_2 = list_to_binary([DoubleUtf16,<<16#FFFFF/utf16-big>>]),
?line DoubleSize16_2 = byte_size(DoubleUtf16_2),
?line AllBut1_16 = DoubleSize16 - 1,
?line AllBut2_16_2 = DoubleSize16_2 - 2,
@@ -884,15 +884,15 @@ utf8_to_list_bsyntax(<<C/utf8,R/binary>>) ->
list_to_utf8_bsyntax(List,unicode) ->
FList = flatx(List),
- erlang:concat_binary([ if
- is_binary(E) ->
- E;
- true ->
- <<E/utf8>>
- end || E <- FList ]);
+ list_to_binary([ if
+ is_binary(E) ->
+ E;
+ true ->
+ <<E/utf8>>
+ end || E <- FList ]);
list_to_utf8_bsyntax(List,latin1) ->
FList = flatb(List),
- erlang:concat_binary([ <<E/utf8>> || E <- FList ]).
+ list_to_binary([ <<E/utf8>> || E <- FList ]).
@@ -954,15 +954,15 @@ utf16_big_to_list_bsyntax(<<C/utf16-big,R/binary>>) ->
list_to_utf16_big_bsyntax(List,{utf16,big}) ->
FList = flatx(List),
- erlang:concat_binary([ if
- is_binary(E) ->
- E;
- true ->
- <<E/utf16-big>>
- end || E <- FList ]);
+ list_to_binary([ if
+ is_binary(E) ->
+ E;
+ true ->
+ <<E/utf16-big>>
+ end || E <- FList ]);
list_to_utf16_big_bsyntax(List,latin1) ->
FList = flatb(List),
- erlang:concat_binary([ <<E/utf16-big>> || E <- FList ]).
+ list_to_binary([ <<E/utf16-big>> || E <- FList ]).
utf16_little_to_list_bsyntax(<<>>) ->
@@ -972,15 +972,15 @@ utf16_little_to_list_bsyntax(<<C/utf16-little,R/binary>>) ->
list_to_utf16_little_bsyntax(List,{utf16,little}) ->
FList = flatx(List),
- erlang:concat_binary([ if
- is_binary(E) ->
- E;
- true ->
- <<E/utf16-little>>
- end || E <- FList ]);
+ list_to_binary([ if
+ is_binary(E) ->
+ E;
+ true ->
+ <<E/utf16-little>>
+ end || E <- FList ]);
list_to_utf16_little_bsyntax(List,latin1) ->
FList = flatb(List),
- erlang:concat_binary([ <<E/utf16-little>> || E <- FList ]).
+ list_to_binary([ <<E/utf16-little>> || E <- FList ]).
@@ -991,15 +991,15 @@ utf32_big_to_list_bsyntax(<<C/utf32-big,R/binary>>) ->
list_to_utf32_big_bsyntax(List,{utf32,big}) ->
FList = flatx(List),
- erlang:concat_binary([ if
- is_binary(E) ->
- E;
- true ->
- <<E/utf32-big>>
- end || E <- FList ]);
+ list_to_binary([ if
+ is_binary(E) ->
+ E;
+ true ->
+ <<E/utf32-big>>
+ end || E <- FList ]);
list_to_utf32_big_bsyntax(List,latin1) ->
FList = flatb(List),
- erlang:concat_binary([ <<E/utf32-big>> || E <- FList ]).
+ list_to_binary([ <<E/utf32-big>> || E <- FList ]).
utf32_little_to_list_bsyntax(<<>>) ->
@@ -1009,15 +1009,15 @@ utf32_little_to_list_bsyntax(<<C/utf32-little,R/binary>>) ->
list_to_utf32_little_bsyntax(List,{utf32,little}) ->
FList = flatx(List),
- erlang:concat_binary([ if
- is_binary(E) ->
- E;
- true ->
- <<E/utf32-little>>
- end || E <- FList ]);
+ list_to_binary([ if
+ is_binary(E) ->
+ E;
+ true ->
+ <<E/utf32-little>>
+ end || E <- FList ]);
list_to_utf32_little_bsyntax(List,latin1) ->
FList = flatb(List),
- erlang:concat_binary([ <<E/utf32-little>> || E <- FList ]).
+ list_to_binary([ <<E/utf32-little>> || E <- FList ]).
diff --git a/lib/stdlib/test/win32reg_SUITE.erl b/lib/stdlib/test/win32reg_SUITE.erl
index 3ad58eba03..c8cc82f61e 100644
--- a/lib/stdlib/test/win32reg_SUITE.erl
+++ b/lib/stdlib/test/win32reg_SUITE.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(win32reg_SUITE).
@@ -37,7 +37,7 @@ fini(Config) when is_list(Config) ->
Config.
long(doc) -> "Test long keys and entries (OTP-3446).";
-long(Config) when list(Config) ->
+long(Config) when is_list(Config) ->
?line Dog = test_server:timetrap(test_server:seconds(10)),
?line LongKey = "software\\" ++
@@ -61,7 +61,7 @@ long(Config) when list(Config) ->
?line test_server:timetrap_cancel(Dog),
ok.
-evil_write(Config) when list(Config) ->
+evil_write(Config) when is_list(Config) ->
?line Dog = test_server:timetrap(test_server:seconds(10)),
?line Key = "Software\\Ericsson\\Erlang",
diff --git a/lib/stdlib/test/zip_SUITE.erl b/lib/stdlib/test/zip_SUITE.erl
index 55cbd277ef..12ca655000 100644
--- a/lib/stdlib/test/zip_SUITE.erl
+++ b/lib/stdlib/test/zip_SUITE.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2006-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 2006-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(zip_SUITE).
@@ -181,7 +181,7 @@ atomic(doc) ->
["Test the 'atomic' operations: zip/unzip/list_dir, on archives."
"Also test the 'cooked' option."];
atomic(suite) -> [];
-atomic(Config) when list(Config) ->
+atomic(Config) when is_list(Config) ->
ok = file:set_cwd(?config(priv_dir, Config)),
DataFiles = data_files(),
Names = [Name || {Name,_,_} <- DataFiles],
@@ -209,7 +209,7 @@ openzip_api(doc) ->
["Test the openzip_open/2, openzip_get/1, openzip_get/2, openzip_close/1 "
"and openzip_list_dir/1 functions."];
openzip_api(suite) -> [];
-openzip_api(Config) when list(Config) ->
+openzip_api(Config) when is_list(Config) ->
ok = file:set_cwd(?config(priv_dir, Config)),
DataFiles = data_files(),
Names = [Name || {Name, _, _} <- DataFiles],
@@ -248,7 +248,7 @@ zip_api(doc) ->
["Test the zip_open/2, zip_get/1, zip_get/2, zip_close/1 "
"and zip_list_dir/1 functions."];
zip_api(suite) -> [];
-zip_api(Config) when list(Config) ->
+zip_api(Config) when is_list(Config) ->
ok = file:set_cwd(?config(priv_dir, Config)),
DataFiles = data_files(),
Names = [Name || {Name, _, _} <- DataFiles],
@@ -550,7 +550,7 @@ aliases(Config) when is_list(Config) ->
unzip_from_binary(doc) ->
["Test extracting a zip archive from a binary."];
-unzip_from_binary(Config) when list(Config) ->
+unzip_from_binary(Config) when is_list(Config) ->
DataDir = ?config(data_dir, Config),
PrivDir = ?config(priv_dir, Config),
ExtractDir = filename:join(PrivDir, "extract_from_binary"),
@@ -626,7 +626,7 @@ delete_all_in(Dir) ->
compress_control(doc) ->
["Test control of which files that should be compressed"];
compress_control(suite) -> [];
-compress_control(Config) when list(Config) ->
+compress_control(Config) when is_list(Config) ->
ok = file:set_cwd(?config(priv_dir, Config)),
Dir = "compress_control",
Files = [
diff --git a/lib/stdlib/vsn.mk b/lib/stdlib/vsn.mk
index c6e93a4b4b..75dc7dc62f 100644
--- a/lib/stdlib/vsn.mk
+++ b/lib/stdlib/vsn.mk
@@ -1,2 +1,2 @@
-STDLIB_VSN = 1.16.4
+STDLIB_VSN = 1.16.5
diff --git a/lib/syntax_tools/Makefile b/lib/syntax_tools/Makefile
index 08ede67209..37e84a80a5 100644
--- a/lib/syntax_tools/Makefile
+++ b/lib/syntax_tools/Makefile
@@ -58,10 +58,10 @@ include $(ERL_TOP)/make/otp_subdir.mk
version:
@echo "$(VSN)"
-docs:
- erl -noshell -pa "$(BINDIR)" -run edoc_run application "'$(APPNAME)'" '"."' '$(DOC_OPTS)' -s init stop
+# The overriding "docs" target have been removed so the default make rules work properly.
-edocs: docs
+edocs:
+ erl -noshell -pa "$(BINDIR)" -run edoc_run application "'$(APPNAME)'" '"."' '$(DOC_OPTS)' -s init stop
app_release: tar
diff --git a/lib/syntax_tools/doc/Makefile b/lib/syntax_tools/doc/Makefile
index 27f32988c8..6afd16f669 100644
--- a/lib/syntax_tools/doc/Makefile
+++ b/lib/syntax_tools/doc/Makefile
@@ -13,8 +13,6 @@
# Portions created by Ericsson are Copyright 1999, Ericsson Utvecklings
# AB. All Rights Reserved.''
#
-# $Id: Makefile,v 1.1.1.1 2004/10/04 13:56:14 richardc Exp $
-#
include $(ERL_TOP)/make/target.mk
include $(ERL_TOP)/make/$(TARGET)/otp.mk
diff --git a/lib/syntax_tools/doc/src/Makefile b/lib/syntax_tools/doc/src/Makefile
index 2065614251..291b3e3047 100644
--- a/lib/syntax_tools/doc/src/Makefile
+++ b/lib/syntax_tools/doc/src/Makefile
@@ -1,19 +1,19 @@
#
# %CopyrightBegin%
-#
-# Copyright Ericsson AB 2006-2009. All Rights Reserved.
-#
+#
+# Copyright Ericsson AB 2006-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%
#
include $(ERL_TOP)/make/target.mk
@@ -101,10 +101,10 @@ html: gifs $(HTML_REF_MAN_FILE)
man: $(MAN3_FILES)
$(XML_REF3_FILES):
- docb_gen $(SRC_DIR)/$(@:%.xml=%.erl)
+ escript $(DOCGEN)/priv/bin/xml_from_edoc.escript $(SRC_DIR)/$(@:%.xml=%.erl)
$(XML_CHAPTER_FILES):
- docb_gen -chapter -def vsn $(VSN) ../overview.edoc
+ escript $(DOCGEN)/priv/bin/xml_from_edoc.escript -def vsn $(VSN) -chapter ../overview.edoc
gifs: $(GIF_FILES:%=$(HTMLDIR)/%)
diff --git a/lib/syntax_tools/doc/src/notes.xml b/lib/syntax_tools/doc/src/notes.xml
index 8fe21c8859..a3b842b50b 100644
--- a/lib/syntax_tools/doc/src/notes.xml
+++ b/lib/syntax_tools/doc/src/notes.xml
@@ -4,7 +4,7 @@
<chapter>
<header>
<copyright>
- <year>2007</year><year>2009</year>
+ <year>2007</year><year>2010</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
@@ -13,12 +13,12 @@
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>Syntax_Tools Release Notes</title>
@@ -31,6 +31,37 @@
<p>This document describes the changes made to the Syntax_Tools
application.</p>
+<section><title>Syntax_Tools 1.6.5</title>
+
+ <section><title>Improvements and New Features</title>
+ <list>
+ <item>
+ <p>The documentation is now possible to build in an open
+ source environment after a number of bugs are fixed and
+ some features are added in the documentation build
+ process. </p>
+ <p>- The arity calculation is updated.</p>
+ <p>- The module prefix used in the function names for
+ bif's are removed in the generated links so the links
+ will look like
+ "http://www.erlang.org/doc/man/erlang.html#append_element-2"
+ instead of
+ "http://www.erlang.org/doc/man/erlang.html#erlang:append_element-2".</p>
+ <p>- Enhanced the menu positioning in the html
+ documentation when a new page is loaded.</p>
+ <p>- A number of corrections in the generation of man
+ pages (thanks to Sergei Golovan)</p>
+ <p>- The legal notice is taken from the xml book file so
+ OTP's build process can be used for non OTP
+ applications.</p>
+ <p>
+ Own Id: OTP-8343</p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
<section><title>Syntax_Tools 1.6.4</title>
<section><title>Improvements and New Features</title>
diff --git a/lib/syntax_tools/examples/Makefile b/lib/syntax_tools/examples/Makefile
index a52a52a50c..7cfe9185c2 100644
--- a/lib/syntax_tools/examples/Makefile
+++ b/lib/syntax_tools/examples/Makefile
@@ -13,8 +13,6 @@
# Portions created by Ericsson are Copyright 1999, Ericsson Utvecklings
# AB. All Rights Reserved.''
#
-# $Id$
-#
include $(ERL_TOP)/make/target.mk
include $(ERL_TOP)/make/$(TARGET)/otp.mk
diff --git a/lib/syntax_tools/src/Makefile b/lib/syntax_tools/src/Makefile
index 5ffe85c975..50369e633e 100644
--- a/lib/syntax_tools/src/Makefile
+++ b/lib/syntax_tools/src/Makefile
@@ -23,7 +23,10 @@ RELSYSDIR = $(RELEASE_PATH)/lib/syntax_tools-$(VSN)
EBIN = ../ebin
-ERL_COMPILE_FLAGS += +warn_unused_vars +nowarn_shadow_vars +warn_unused_import +warn_obsolete_guard
+ifeq ($(NATIVE_LIBS_ENABLED),yes)
+ERL_COMPILE_FLAGS += +native
+endif
+ERL_COMPILE_FLAGS += +warn_unused_vars +nowarn_shadow_vars +warn_unused_import +warn_missing_spec +warn_untyped_record
SOURCES=erl_syntax.erl erl_prettypr.erl erl_syntax_lib.erl \
erl_comment_scan.erl erl_recomment.erl erl_tidy.erl \
@@ -34,15 +37,15 @@ OBJECTS=$(SOURCES:%.erl=$(EBIN)/%.$(EMULATOR)) $(APP_TARGET) $(APPUP_TARGET)
APP_FILE= syntax_tools.app
APP_SRC= $(APP_FILE).src
APP_TARGET= $(EBIN)/$(APP_FILE)
-
+
APPUP_FILE= syntax_tools.appup
APPUP_SRC= $(APPUP_FILE).src
APPUP_TARGET= $(EBIN)/$(APPUP_FILE)
-
+
# ----------------------------------------------------
# Targets
# ----------------------------------------------------
-
+
debug opt: $(OBJECTS)
all: $(OBJECTS)
@@ -52,6 +55,8 @@ clean:
rm -f $(OBJECTS)
rm -f core *~
+docs:
+
distclean: clean
realclean: clean
@@ -62,10 +67,10 @@ $(EBIN)/%.$(EMULATOR):%.erl
# ----------------------------------------------------
# Special Build Targets
# ----------------------------------------------------
-
+
$(APP_TARGET): $(APP_SRC) ../vsn.mk
sed -e 's;%VSN%;$(VSN);' $< > $@
-
+
$(APPUP_TARGET): $(APPUP_SRC) ../vsn.mk
sed -e 's;%VSN%;$(VSN);' $< > $@
diff --git a/lib/syntax_tools/src/epp_dodger.erl b/lib/syntax_tools/src/epp_dodger.erl
index 7aef549574..6b0f2034f8 100644
--- a/lib/syntax_tools/src/epp_dodger.erl
+++ b/lib/syntax_tools/src/epp_dodger.erl
@@ -90,6 +90,9 @@
%% This is a so-called Erlang I/O ErrorInfo structure; see the {@link
%% //stdlib/io} module for details.
+-type errorinfo() :: term(). % {integer(), atom(), term()}.
+
+-type option() :: atom() | {atom(), term()}.
%% =====================================================================
%% @spec parse_file(File) -> {ok, Forms} | {error, errorinfo()}
@@ -98,6 +101,9 @@
%%
%% @equiv parse_file(File, [])
+-spec parse_file(file:filename()) ->
+ {'ok', erl_syntax:forms()} | {'error', errorinfo()}.
+
parse_file(File) ->
parse_file(File, []).
@@ -109,11 +115,11 @@ parse_file(File) ->
%% @doc Reads and parses a file. If successful, `{ok, Forms}'
%% is returned, where `Forms' is a list of abstract syntax
%% trees representing the "program forms" of the file (cf.
-%% `erl_syntax:is_form/1'). Otherwise, `{error,
-%% errorinfo()}' is returned, typically if the file could not be
-%% opened. Note that parse errors show up as error markers in the
-%% returned list of forms; they do not cause this function to fail or
-%% return `{error,errorinfo()}'.
+%% `erl_syntax:is_form/1'). Otherwise, `{error, errorinfo()}' is
+%% returned, typically if the file could not be opened. Note that
+%% parse errors show up as error markers in the returned list of
+%% forms; they do not cause this function to fail or return
+%% `{error, errorinfo()}'.
%%
%% Options:
%% <dl>
@@ -135,6 +141,9 @@ parse_file(File) ->
%% @see quick_parse_file/1
%% @see erl_syntax:is_form/1
+-spec parse_file(file:filename(), [option()]) ->
+ {'ok', erl_syntax:forms()} | {'error', errorinfo()}.
+
parse_file(File, Options) ->
parse_file(File, fun parse/3, Options).
@@ -144,6 +153,9 @@ parse_file(File, Options) ->
%%
%% @equiv quick_parse_file(File, [])
+-spec quick_parse_file(file:filename()) ->
+ {'ok', erl_syntax:forms()} | {'error', errorinfo()}.
+
quick_parse_file(File) ->
quick_parse_file(File, []).
@@ -167,6 +179,9 @@ quick_parse_file(File) ->
%% @see quick_parse/2
%% @see parse_file/2
+-spec quick_parse_file(file:filename(), [option()]) ->
+ {'ok', erl_syntax:forms()} | {'error', errorinfo()}.
+
quick_parse_file(File, Options) ->
parse_file(File, fun quick_parse/3, Options ++ [no_fail]).
@@ -185,6 +200,8 @@ parse_file(File, Parser, Options) ->
%% @spec parse(IODevice) -> {ok, Forms} | {error, errorinfo()}
%% @equiv parse(IODevice, 1)
+-spec parse(file:io_device()) -> {'ok', erl_syntax:forms()}.
+
parse(Dev) ->
parse(Dev, 1).
@@ -196,6 +213,8 @@ parse(Dev) ->
%% @equiv parse(IODevice, StartLine, [])
%% @see parse/1
+-spec parse(file:io_device(), integer()) -> {'ok', erl_syntax:forms()}.
+
parse(Dev, L) ->
parse(Dev, L, []).
@@ -216,12 +235,18 @@ parse(Dev, L) ->
%% @see parse_form/2
%% @see quick_parse/3
+-spec parse(file:io_device(), integer(), [option()]) ->
+ {'ok', erl_syntax:forms()}.
+
parse(Dev, L0, Options) ->
parse(Dev, L0, fun parse_form/3, Options).
%% @spec quick_parse(IODevice) -> {ok, Forms} | {error, errorinfo()}
%% @equiv quick_parse(IODevice, 1)
+-spec quick_parse(file:io_device()) ->
+ {'ok', erl_syntax:forms()}.
+
quick_parse(Dev) ->
quick_parse(Dev, 1).
@@ -234,6 +259,9 @@ quick_parse(Dev) ->
%% @equiv quick_parse(IODevice, StartLine, [])
%% @see quick_parse/1
+-spec quick_parse(file:io_device(), integer()) ->
+ {'ok', erl_syntax:forms()}.
+
quick_parse(Dev, L) ->
quick_parse(Dev, L, []).
@@ -252,6 +280,9 @@ quick_parse(Dev, L) ->
%% @see quick_parse_form/2
%% @see parse/3
+-spec quick_parse(file:io_device(), integer(), [option()]) ->
+ {'ok', erl_syntax:forms()}.
+
quick_parse(Dev, L0, Options) ->
parse(Dev, L0, fun quick_parse_form/3, Options).
@@ -284,6 +315,10 @@ parse(Dev, L0, Fs, Parser, Options) ->
%%
%% @see quick_parse_form/2
+-spec parse_form(file:io_device(), integer()) ->
+ {'ok', erl_syntax:forms(), integer()}
+ | {'eof', integer()} | {'error', errorinfo(), integer()}.
+
parse_form(Dev, L0) ->
parse_form(Dev, L0, []).
@@ -310,6 +345,10 @@ parse_form(Dev, L0) ->
%% @see parse_form/2
%% @see quick_parse_form/3
+-spec parse_form(file:io_device(), integer(), [option()]) ->
+ {'ok', erl_syntax:forms(), integer()}
+ | {'eof', integer()} | {'error', errorinfo(), integer()}.
+
parse_form(Dev, L0, Options) ->
parse_form(Dev, L0, fun normal_parser/2, Options).
@@ -326,6 +365,10 @@ parse_form(Dev, L0, Options) ->
%%
%% @see parse_form/2
+-spec quick_parse_form(file:io_device(), integer()) ->
+ {'ok', erl_syntax:forms(), integer()}
+ | {'eof', integer()} | {'error', errorinfo(), integer()}.
+
quick_parse_form(Dev, L0) ->
quick_parse_form(Dev, L0, []).
@@ -347,6 +390,10 @@ quick_parse_form(Dev, L0) ->
%% @see quick_parse_form/2
%% @see parse_form/3
+-spec quick_parse_form(file:io_device(), integer(), [option()]) ->
+ {'ok', erl_syntax:forms(), integer()}
+ | {'eof', integer()} | {'error', errorinfo(), integer()}.
+
quick_parse_form(Dev, L0, Options) ->
parse_form(Dev, L0, fun quick_parser/2, Options).
@@ -751,11 +798,13 @@ fix_define([{atom, L, ?pp_form}, {'(', _}, {')', _}, {'->', _},
fix_define(_Ts) ->
error.
-%% @spec (Tokens::[term()]) -> string()
+%% @spec tokens_to_string(Tokens::[term()]) -> string()
%%
%% @doc Generates a string corresponding to the given token sequence.
%% The string can be re-tokenized to yield the same token list again.
+-spec tokens_to_string([term()]) -> string().
+
tokens_to_string([{atom,_,A} | Ts]) ->
io_lib:write_atom(A) ++ " " ++ tokens_to_string(Ts);
tokens_to_string([{string, _, S} | Ts]) ->
@@ -764,21 +813,23 @@ tokens_to_string([{float, _, F} | Ts]) ->
float_to_list(F) ++ " " ++ tokens_to_string(Ts);
tokens_to_string([{integer, _, N} | Ts]) ->
integer_to_list(N) ++ " " ++ tokens_to_string(Ts);
-tokens_to_string([{var,_,A} | Ts]) ->
+tokens_to_string([{var, _, A} | Ts]) ->
atom_to_list(A) ++ " " ++ tokens_to_string(Ts);
-tokens_to_string([{dot,_} | Ts]) ->
+tokens_to_string([{dot, _} | Ts]) ->
".\n" ++ tokens_to_string(Ts);
-tokens_to_string([{A,_} | Ts]) ->
+tokens_to_string([{A, _} | Ts]) ->
atom_to_list(A) ++ " " ++ tokens_to_string(Ts);
tokens_to_string([]) ->
"".
-%% @spec (Descriptor::term()) -> string()
+%% @spec format_error(Descriptor::term()) -> string()
%% @hidden
%% @doc Callback function for formatting error descriptors. Not for
%% normal use.
+-spec format_error(term()) -> string().
+
format_error(macro_args) ->
errormsg("macro call missing end parenthesis");
format_error({unknown, Reason}) ->
diff --git a/lib/syntax_tools/src/erl_comment_scan.erl b/lib/syntax_tools/src/erl_comment_scan.erl
index df1449da4e..09ce21a428 100644
--- a/lib/syntax_tools/src/erl_comment_scan.erl
+++ b/lib/syntax_tools/src/erl_comment_scan.erl
@@ -14,8 +14,7 @@
%% Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
%% USA
%%
-%% $Id$
-%%
+%% =====================================================================
%% @copyright 1997-2006 Richard Carlsson
%% @author Richard Carlsson <[email protected]>
%% @end
@@ -29,6 +28,11 @@
%% =====================================================================
+
+-type comment() :: {integer(), integer(), integer(), [string()]}.
+-type commentLine() :: {integer(), integer(), integer(), string()}.
+
+%% =====================================================================
%% @spec file(FileName::file:filename()) -> [Comment]
%%
%% Comment = {Line, Column, Indentation, Text}
@@ -59,6 +63,8 @@
%% error occurred, where `Reason' is an atom corresponding to
%% a Posix error code; see the module {@link //kernel/file} for details.
+-spec file(file:filename()) -> [comment()].
+
file(Name) ->
Name1 = filename(Name),
case catch {ok, file:read_file(Name1)} of
@@ -80,7 +86,7 @@ file(Name) ->
%% =====================================================================
-%% string(string()) -> [Comment]
+%% @spec string(string()) -> [Comment]
%%
%% Comment = {Line, Column, Indentation, Text}
%% Line = integer()
@@ -94,6 +100,8 @@ file(Name) ->
%%
%% @see file/1
+-spec string(string()) -> [comment()].
+
string(Text) ->
lists:reverse(join_lines(scan_lines(Text))).
@@ -116,6 +124,8 @@ string(Text) ->
%% to (but not including) the line-terminating newline. For details on
%% `Line', `Column' and `Indent', see {@link file/1}.
+-spec scan_lines(string()) -> [commentLine()].
+
scan_lines(Text) ->
scan_lines(Text, 1, 0, 0, []).
@@ -231,6 +241,8 @@ scan_char([], _L, _Col, Ack) ->
%%
%% @see scan_lines/1
+-spec join_lines([commentLine()]) -> [comment()].
+
join_lines([{L, Col, Ind, Txt} | Lines]) ->
join_lines(Lines, [Txt], L, Col, Ind);
join_lines([]) ->
diff --git a/lib/syntax_tools/src/erl_prettypr.erl b/lib/syntax_tools/src/erl_prettypr.erl
index 8d2f4facea..606441bcf1 100644
--- a/lib/syntax_tools/src/erl_prettypr.erl
+++ b/lib/syntax_tools/src/erl_prettypr.erl
@@ -48,25 +48,30 @@
-define(NOUSER, undefined).
-define(NOHOOK, none).
--record(ctxt, {prec = 0,
- sub_indent = 2,
- break_indent = 4,
- clause = undefined,
- hook = ?NOHOOK,
- paper = ?PAPER,
- ribbon = ?RIBBON,
- user = ?NOUSER}).
+-type hook() :: 'none'
+ | fun((erl_syntax:syntaxTree(), _, _) -> prettypr:document()).
+-record(ctxt, {prec = 0 :: integer(),
+ sub_indent = 2 :: non_neg_integer(),
+ break_indent = 4 :: non_neg_integer(),
+ clause = undefined,
+ hook = ?NOHOOK :: hook(),
+ paper = ?PAPER :: integer(),
+ ribbon = ?RIBBON :: integer(),
+ user = ?NOUSER :: term()}).
+-type context() :: #ctxt{}.
%% =====================================================================
%% The following functions examine and modify contexts:
-%% @spec (context()) -> context()
+%% @spec (context()) -> integer()
%% @doc Returns the operator precedence field of the prettyprinter
%% context.
%%
%% @see set_ctxt_precedence/2
+-spec get_ctxt_precedence(context()) -> integer().
+
get_ctxt_precedence(Ctxt) ->
Ctxt#ctxt.prec.
@@ -78,6 +83,8 @@ get_ctxt_precedence(Ctxt) ->
%% @see //stdlib/erl_parse
%% @see get_ctxt_precedence/1
+-spec set_ctxt_precedence(context(), integer()) -> context().
+
set_ctxt_precedence(Ctxt, Prec) ->
set_prec(Ctxt, Prec).
@@ -91,6 +98,8 @@ reset_prec(Ctxt) ->
%% @doc Returns the paper widh field of the prettyprinter context.
%% @see set_ctxt_paperwidth/2
+-spec get_ctxt_paperwidth(context()) -> integer().
+
get_ctxt_paperwidth(Ctxt) ->
Ctxt#ctxt.paper.
@@ -104,6 +113,8 @@ get_ctxt_paperwidth(Ctxt) ->
%%
%% @see get_ctxt_paperwidth/1
+-spec set_ctxt_paperwidth(context(), integer()) -> context().
+
set_ctxt_paperwidth(Ctxt, W) ->
Ctxt#ctxt{paper = W}.
@@ -111,6 +122,8 @@ set_ctxt_paperwidth(Ctxt, W) ->
%% @doc Returns the line widh field of the prettyprinter context.
%% @see set_ctxt_linewidth/2
+-spec get_ctxt_linewidth(context()) -> integer().
+
get_ctxt_linewidth(Ctxt) ->
Ctxt#ctxt.ribbon.
@@ -124,6 +137,8 @@ get_ctxt_linewidth(Ctxt) ->
%%
%% @see get_ctxt_linewidth/1
+-spec set_ctxt_linewidth(context(), integer()) -> context().
+
set_ctxt_linewidth(Ctxt, W) ->
Ctxt#ctxt{ribbon = W}.
@@ -131,6 +146,8 @@ set_ctxt_linewidth(Ctxt, W) ->
%% @doc Returns the hook function field of the prettyprinter context.
%% @see set_ctxt_hook/2
+-spec get_ctxt_hook(context()) -> hook().
+
get_ctxt_hook(Ctxt) ->
Ctxt#ctxt.hook.
@@ -138,6 +155,8 @@ get_ctxt_hook(Ctxt) ->
%% @doc Updates the hook function field of the prettyprinter context.
%% @see get_ctxt_hook/1
+-spec set_ctxt_hook(context(), hook()) -> context().
+
set_ctxt_hook(Ctxt, Hook) ->
Ctxt#ctxt{hook = Hook}.
@@ -145,6 +164,8 @@ set_ctxt_hook(Ctxt, Hook) ->
%% @doc Returns the user data field of the prettyprinter context.
%% @see set_ctxt_user/2
+-spec get_ctxt_user(context()) -> term().
+
get_ctxt_user(Ctxt) ->
Ctxt#ctxt.user.
@@ -152,6 +173,8 @@ get_ctxt_user(Ctxt) ->
%% @doc Updates the user data field of the prettyprinter context.
%% @see get_ctxt_user/1
+-spec set_ctxt_user(context(), term()) -> context().
+
set_ctxt_user(Ctxt, X) ->
Ctxt#ctxt{user = X}.
@@ -160,6 +183,8 @@ set_ctxt_user(Ctxt, X) ->
%% @spec format(Tree::syntaxTree()) -> string()
%% @equiv format(Tree, [])
+-spec format(erl_syntax:syntaxTree()) -> string().
+
format(Node) ->
format(Node, []).
@@ -237,6 +262,8 @@ format(Node) ->
%% @see get_ctxt_user/1
%% @see set_ctxt_user/2
+-spec format(erl_syntax:syntaxTree(), [term()]) -> string().
+
format(Node, Options) ->
W = proplists:get_value(paper, Options, ?PAPER),
L = proplists:get_value(ribbon, Options, ?RIBBON),
@@ -247,6 +274,8 @@ format(Node, Options) ->
%% @spec best(Tree::syntaxTree()) -> empty | document()
%% @equiv best(Tree, [])
+-spec best(erl_syntax:syntaxTree()) -> 'empty' | prettypr:document().
+
best(Node) ->
best(Node, []).
@@ -266,6 +295,8 @@ best(Node) ->
%% @see format/2
%% @see prettypr:best/3
+-spec best(erl_syntax:syntaxTree(), [term()]) -> 'empty' | prettypr:document().
+
best(Node, Options) ->
W = proplists:get_value(paper, Options, ?PAPER),
L = proplists:get_value(ribbon, Options, ?RIBBON),
@@ -276,6 +307,8 @@ best(Node, Options) ->
%% @spec layout(Tree::syntaxTree()) -> document()
%% @equiv layout(Tree, [])
+-spec layout(erl_syntax:syntaxTree()) -> prettypr:document().
+
layout(Node) ->
layout(Node, []).
@@ -300,6 +333,8 @@ layout(Node) ->
%% @see format/2
%% @see layout/1
+-spec layout(erl_syntax:syntaxTree(), [term()]) -> prettypr:document().
+
layout(Node, Options) ->
lay(Node,
#ctxt{hook = proplists:get_value(hook, Options, ?NOHOOK),
@@ -593,7 +628,7 @@ lay_2(Node, Ctxt) ->
fun_expr ->
Ctxt1 = reset_prec(Ctxt),
D = lay_clauses(erl_syntax:fun_expr_clauses(Node),
- fun_expr, Ctxt1),
+ fun_expr, Ctxt1),
sep([follow(text("fun"), D, Ctxt1#ctxt.sub_indent),
text("end")]);
diff --git a/lib/syntax_tools/src/erl_recomment.erl b/lib/syntax_tools/src/erl_recomment.erl
index 62ec7da200..145bbc6f37 100644
--- a/lib/syntax_tools/src/erl_recomment.erl
+++ b/lib/syntax_tools/src/erl_recomment.erl
@@ -47,6 +47,9 @@
%% comments. Comments within function definitions or declarations
%% ("forms") are simply ignored.
+-spec quick_recomment_forms(erl_syntax:forms(), [erl_comment_scan:comment()]) ->
+ erl_syntax:syntaxTree().
+
quick_recomment_forms(Tree, Cs) ->
recomment_forms(Tree, Cs, false).
@@ -109,6 +112,9 @@ quick_recomment_forms(Tree, Cs) ->
%% @see recomment_tree/2
%% @see quick_recomment_forms/2
+-spec recomment_forms(erl_syntax:forms(), [erl_comment_scan:comment()]) ->
+ erl_syntax:syntaxTree().
+
recomment_forms(Tree, Cs) ->
recomment_forms(Tree, Cs, true).
@@ -209,7 +215,7 @@ comment_delta(Text) ->
%% the source file itself, but have been included by preprocessing. This
%% way, comments will not be inserted into such parts by mistake.
--record(filter, {file = undefined, line = 0}).
+-record(filter, {file = undefined, line = 0 :: integer()}).
filter_forms(Fs) ->
filter_forms(Fs, false, #filter{}).
@@ -330,6 +336,9 @@ check_file_attr_2(L) ->
%%
%% @see recomment_forms/2
+-spec recomment_tree(erl_syntax:syntaxTree(), [erl_comment_scan:comment()]) ->
+ {erl_syntax:syntaxTree(), [erl_comment_scan:comment()]}.
+
recomment_tree(Tree, Cs) ->
{Tree1, Cs1} = insert_comments(Cs, build_tree(Tree)),
{revert_tree(Tree1), Cs1}.
@@ -592,23 +601,23 @@ expand_comment(C) ->
%% syntax tree for any such tree that can have no subtrees, i.e., such
%% that `erl_syntax:is_leaf' yields `true'.
--record(leaf, {min = 0,
- max = 0,
- precomments = [],
- postcomments = [],
- value}).
-
--record(tree, {min = 0,
- max = 0,
- type,
- attrs,
- precomments = [],
- postcomments = [],
- subtrees = []}).
-
--record(list, {min = 0,
- max = 0,
- subtrees = []}).
+-record(leaf, {min = 0 :: integer(),
+ max = 0 :: integer(),
+ precomments = [] :: [erl_syntax:syntaxTree()],
+ postcomments = [] :: [erl_syntax:syntaxTree()],
+ value :: erl_syntax:syntaxTree()}).
+
+-record(tree, {min = 0 :: integer(),
+ max = 0 :: integer(),
+ type :: atom(),
+ attrs :: erl_syntax:syntaxTreeAttributes(),
+ precomments = [] :: [erl_syntax:syntaxTree()],
+ postcomments = [] :: [erl_syntax:syntaxTree()],
+ subtrees = [] :: [erl_syntax:syntaxTree()]}).
+
+-record(list, {min = 0 :: integer(),
+ max = 0 :: integer(),
+ subtrees = [] :: [erl_syntax:syntaxTree()]}).
leaf_node(Min, Max, Value) ->
#leaf{min = Min,
diff --git a/lib/syntax_tools/src/erl_syntax.erl b/lib/syntax_tools/src/erl_syntax.erl
index 6ceb3ddcaf..9a2967d550 100644
--- a/lib/syntax_tools/src/erl_syntax.erl
+++ b/lib/syntax_tools/src/erl_syntax.erl
@@ -343,8 +343,8 @@
%%
%% type(Com) = comment
--record(com, {pre = [],
- post = []}).
+-record(com, {pre = [] :: [syntaxTree()],
+ post = [] :: [syntaxTree()]}).
%% `attr' records store node attributes as an aggregate.
%%
@@ -357,9 +357,10 @@
%% where `Pos' `Ann' and `Comments' are the corresponding values of a
%% `tree' or `wrapper' record.
--record(attr, {pos = 0,
- ann = [],
- com = none}).
+-record(attr, {pos = 0 :: term(),
+ ann = [] :: [term()],
+ com = none :: 'none' | #com{}}).
+-type syntaxTreeAttributes() :: #attr{}.
%% `tree' records represent new-form syntax tree nodes.
%%
@@ -371,9 +372,9 @@
%%
%% is_tree(Tree) = true
--record(tree, {type,
+-record(tree, {type :: atom(),
attr = #attr{} :: #attr{},
- data}).
+ data :: term()}).
%% `wrapper' records are used for attaching new-form node information to
%% `erl_parse' trees.
@@ -386,10 +387,13 @@
%%
%% is_tree(Wrapper) = false
--record(wrapper, {type,
+-record(wrapper, {type :: atom(),
attr = #attr{} :: #attr{},
- tree}).
+ tree :: term()}).
+%% =====================================================================
+
+-type syntaxTree() :: #tree{} | #wrapper{} | tuple(). % XXX: refine
%% =====================================================================
%%
@@ -532,6 +536,8 @@
%% @see variable/1
%% @see warning_marker/1
+-spec type(syntaxTree()) -> atom().
+
type(#tree{type = T}) ->
T;
type(#wrapper{type = T}) ->
@@ -599,7 +605,7 @@ type(Node) ->
%% =====================================================================
-%% @spec is_leaf(Node::syntaxTree()) -> bool()
+%% @spec is_leaf(Node::syntaxTree()) -> boolean()
%%
%% @doc Returns <code>true</code> if <code>Node</code> is a leaf node,
%% otherwise <code>false</code>. The currently recognised leaf node
@@ -635,6 +641,8 @@ type(Node) ->
%% @see type/1
%% @see is_literal/1
+-spec is_leaf(syntaxTree()) -> boolean().
+
is_leaf(Node) ->
case type(Node) of
atom -> true;
@@ -657,7 +665,7 @@ is_leaf(Node) ->
%% =====================================================================
-%% @spec is_form(Node::syntaxTree()) -> bool()
+%% @spec is_form(Node::syntaxTree()) -> boolean()
%%
%% @doc Returns <code>true</code> if <code>Node</code> is a syntax tree
%% representing a so-called "source code form", otherwise
@@ -688,6 +696,8 @@ is_leaf(Node) ->
%% @see rule/2
%% @see warning_marker/1
+-spec is_form(syntaxTree()) -> boolean().
+
is_form(Node) ->
case type(Node) of
attribute -> true;
@@ -722,6 +732,8 @@ is_form(Node) ->
%% number *of the error descriptor*; this is all handled transparently
%% by `get_pos' and `set_pos'.
+-spec get_pos(syntaxTree()) -> term().
+
get_pos(#tree{attr = Attr}) ->
Attr#attr.pos;
get_pos(#wrapper{attr = Attr}) ->
@@ -745,6 +757,8 @@ get_pos(Node) ->
%% @see get_pos/1
%% @see copy_pos/2
+-spec set_pos(syntaxTree(), term()) -> syntaxTree().
+
set_pos(Node, Pos) ->
case Node of
#tree{attr = Attr} ->
@@ -771,6 +785,8 @@ set_pos(Node, Pos) ->
%% @see get_pos/1
%% @see set_pos/2
+-spec copy_pos(syntaxTree(), syntaxTree()) -> syntaxTree().
+
copy_pos(Source, Target) ->
set_pos(Target, get_pos(Source)).
@@ -818,6 +834,8 @@ set_com(Node, Com) ->
%% @see get_postcomments/1
%% @see get_attrs/1
+-spec get_precomments(syntaxTree()) -> [syntaxTree()].
+
get_precomments(#tree{attr = Attr}) -> get_precomments_1(Attr);
get_precomments(#wrapper{attr = Attr}) -> get_precomments_1(Attr);
get_precomments(_) -> [].
@@ -842,6 +860,8 @@ get_precomments_1(#attr{com = #com{pre = Cs}}) -> Cs.
%% @see remove_comments/1
%% @see join_comments/2
+-spec set_precomments(syntaxTree(), [syntaxTree()]) -> syntaxTree().
+
set_precomments(Node, Cs) ->
case Node of
#tree{attr = Attr} ->
@@ -875,6 +895,8 @@ set_precomments_1(#attr{com = Com} = Attr, Cs) ->
%% @see add_postcomments/2
%% @see join_comments/2
+-spec add_precomments([syntaxTree()], syntaxTree()) -> syntaxTree().
+
add_precomments(Cs, Node) ->
case Node of
#tree{attr = Attr} ->
@@ -916,6 +938,8 @@ add_precomments_1(Cs, #attr{com = Com} = Attr) ->
%% @see get_precomments/1
%% @see get_attrs/1
+-spec get_postcomments(syntaxTree()) -> [syntaxTree()].
+
get_postcomments(#tree{attr = Attr}) -> get_postcomments_1(Attr);
get_postcomments(#wrapper{attr = Attr}) -> get_postcomments_1(Attr);
get_postcomments(_) -> [].
@@ -940,6 +964,8 @@ get_postcomments_1(#attr{com = #com{post = Cs}}) -> Cs.
%% @see remove_comments/1
%% @see join_comments/2
+-spec set_postcomments(syntaxTree(), [syntaxTree()]) -> syntaxTree().
+
set_postcomments(Node, Cs) ->
case Node of
#tree{attr = Attr} ->
@@ -973,6 +999,8 @@ set_postcomments_1(#attr{com = Com} = Attr, Cs) ->
%% @see add_precomments/2
%% @see join_comments/2
+-spec add_postcomments([syntaxTree()], syntaxTree()) -> syntaxTree().
+
add_postcomments(Cs, Node) ->
case Node of
#tree{attr = Attr} ->
@@ -990,7 +1018,7 @@ add_postcomments_1(Cs, #attr{com = Com} = Attr) ->
%% =====================================================================
-%% @spec has_comments(Node::syntaxTree()) -> bool()
+%% @spec has_comments(Node::syntaxTree()) -> boolean()
%%
%% @doc Yields <code>false</code> if the node has no associated
%% comments, and <code>true</code> otherwise.
@@ -1003,6 +1031,8 @@ add_postcomments_1(Cs, #attr{com = Com} = Attr) ->
%% @see get_postcomments/1
%% @see remove_comments/1
+-spec has_comments(syntaxTree()) -> boolean().
+
has_comments(#tree{attr = Attr}) ->
case Attr#attr.com of
none -> false;
@@ -1030,6 +1060,8 @@ has_comments(_) -> false.
%% @see set_precomments/2
%% @see set_postcomments/2
+-spec remove_comments(syntaxTree()) -> syntaxTree().
+
remove_comments(Node) ->
case Node of
#tree{attr = Attr} ->
@@ -1059,6 +1091,8 @@ remove_comments(Node) ->
%% @see set_precomments/2
%% @see set_postcomments/2
+-spec copy_comments(syntaxTree(), syntaxTree()) -> syntaxTree().
+
copy_comments(Source, Target) ->
set_com(Target, get_com(Source)).
@@ -1081,6 +1115,8 @@ copy_comments(Source, Target) ->
%% @see add_precomments/2
%% @see add_postcomments/2
+-spec join_comments(syntaxTree(), syntaxTree()) -> syntaxTree().
+
join_comments(Source, Target) ->
add_postcomments(
get_postcomments(Source),
@@ -1097,6 +1133,8 @@ join_comments(Source, Target) ->
%% @see set_ann/2
%% @see get_attrs/1
+-spec get_ann(syntaxTree()) -> [term()].
+
get_ann(#tree{attr = Attr}) -> Attr#attr.ann;
get_ann(#wrapper{attr = Attr}) -> Attr#attr.ann;
get_ann(_) -> [].
@@ -1113,6 +1151,8 @@ get_ann(_) -> [].
%% @see add_ann/2
%% @see copy_ann/2
+-spec set_ann(syntaxTree(), [term()]) -> syntaxTree().
+
set_ann(Node, As) ->
case Node of
#tree{attr = Attr} ->
@@ -1138,6 +1178,8 @@ set_ann(Node, As) ->
%% @see get_ann/1
%% @see set_ann/2
+-spec add_ann(term(), syntaxTree()) -> syntaxTree().
+
add_ann(A, Node) ->
case Node of
#tree{attr = Attr} ->
@@ -1164,6 +1206,8 @@ add_ann(A, Node) ->
%% @see get_ann/1
%% @see set_ann/2
+-spec copy_ann(syntaxTree(), syntaxTree()) -> syntaxTree().
+
copy_ann(Source, Target) ->
set_ann(Target, get_ann(Source)).
@@ -1192,6 +1236,8 @@ copy_ann(Source, Target) ->
%% @see get_precomments/1
%% @see get_postcomments/1
+-spec get_attrs(syntaxTree()) -> syntaxTreeAttributes().
+
get_attrs(#tree{attr = Attr}) -> Attr;
get_attrs(#wrapper{attr = Attr}) -> Attr;
get_attrs(Node) -> #attr{pos = get_pos(Node),
@@ -1209,6 +1255,8 @@ get_attrs(Node) -> #attr{pos = get_pos(Node),
%% @see get_attrs/1
%% @see copy_attrs/2
+-spec set_attrs(syntaxTree(), syntaxTreeAttributes()) -> syntaxTree().
+
set_attrs(Node, Attr) ->
case Node of
#tree{} ->
@@ -1233,6 +1281,8 @@ set_attrs(Node, Attr) ->
%% @see get_attrs/1
%% @see set_attrs/2
+-spec copy_attrs(syntaxTree(), syntaxTree()) -> syntaxTree().
+
copy_attrs(S, T) ->
set_attrs(T, get_attrs(S)).
@@ -1241,6 +1291,8 @@ copy_attrs(S, T) ->
%% @spec comment(Strings) -> syntaxTree()
%% @equiv comment(none, Strings)
+-spec comment([string()]) -> syntaxTree().
+
comment(Strings) ->
comment(none, Strings).
@@ -1268,7 +1320,9 @@ comment(Strings) ->
%% @see comment/1
%% @see is_form/1
--record(comment, {pad, text}).
+-type padding() :: 'none' | integer().
+
+-record(comment, {pad :: padding(), text :: [string()]}).
%% type(Node) = comment
%% data(Node) = #comment{pad :: Padding, text :: Strings}
@@ -1276,6 +1330,8 @@ comment(Strings) ->
%% Padding = none | integer()
%% Strings = [string()]
+-spec comment(padding(), [string()]) -> syntaxTree().
+
comment(Pad, Strings) ->
tree(comment, #comment{pad = Pad, text = Strings}).
@@ -1287,6 +1343,8 @@ comment(Pad, Strings) ->
%%
%% @see comment/2
+-spec comment_text(syntaxTree()) -> [string()].
+
comment_text(Node) ->
(data(Node))#comment.text.
@@ -1300,6 +1358,8 @@ comment_text(Node) ->
%%
%% @see comment/2
+-spec comment_padding(syntaxTree()) -> padding().
+
comment_padding(Node) ->
(data(Node))#comment.pad.
@@ -1333,6 +1393,8 @@ comment_padding(Node) ->
%% Form = syntaxTree()
%% is_form(Form) = true
+-spec form_list([syntaxTree()]) -> syntaxTree().
+
form_list(Forms) ->
tree(form_list, Forms).
@@ -1344,6 +1406,8 @@ form_list(Forms) ->
%%
%% @see form_list/1
+-spec form_list_elements(syntaxTree()) -> [syntaxTree()].
+
form_list_elements(Node) ->
data(Node).
@@ -1358,6 +1422,8 @@ form_list_elements(Node) ->
%%
%% @see form_list/1
+-spec flatten_form_list(syntaxTree()) -> syntaxTree().
+
flatten_form_list(Node) ->
Fs = form_list_elements(Node),
Fs1 = lists:reverse(flatten_form_list_1(Fs, [])),
@@ -1389,6 +1455,8 @@ flatten_form_list_1([], As) ->
%% type(Node) = text
%% data(Node) = string()
+-spec text(string()) -> syntaxTree().
+
text(String) ->
tree(text, String).
@@ -1401,6 +1469,8 @@ text(String) ->
%%
%% @see text/1
+-spec text_string(syntaxTree()) -> string().
+
text_string(Node) ->
data(Node).
@@ -1432,6 +1502,8 @@ text_string(Node) ->
%%
%% Name = atom() \ '_'
+-spec variable(atom() | string()) -> syntaxTree().
+
variable(Name) when is_atom(Name) ->
tree(variable, Name);
variable(Name) ->
@@ -1450,6 +1522,8 @@ revert_variable(Node) ->
%%
%% @see variable/1
+-spec variable_name(syntaxTree()) -> atom().
+
variable_name(Node) ->
case unwrap(Node) of
{var, _, Name} ->
@@ -1466,6 +1540,8 @@ variable_name(Node) ->
%%
%% @see variable/1
+-spec variable_literal(syntaxTree()) -> string().
+
variable_literal(Node) ->
case unwrap(Node) of
{var, _, Name} ->
@@ -1491,6 +1567,8 @@ variable_literal(Node) ->
%%
%% {var, Pos, '_'}
+-spec underscore() -> syntaxTree().
+
underscore() ->
tree(underscore, []).
@@ -1518,6 +1596,8 @@ revert_underscore(Node) ->
%%
%% Value = integer()
+-spec integer(integer()) -> syntaxTree().
+
integer(Value) ->
tree(integer, Value).
@@ -1527,7 +1607,7 @@ revert_integer(Node) ->
%% =====================================================================
-%% @spec is_integer(Node::syntaxTree(), Value::integer()) -> bool()
+%% @spec is_integer(Node::syntaxTree(), Value::integer()) -> boolean()
%%
%% @doc Returns <code>true</code> if <code>Node</code> has type
%% <code>integer</code> and represents <code>Value</code>, otherwise
@@ -1535,6 +1615,8 @@ revert_integer(Node) ->
%%
%% @see integer/1
+-spec is_integer(syntaxTree(), integer()) -> boolean().
+
is_integer(Node, Value) ->
case unwrap(Node) of
{integer, _, Value} ->
@@ -1553,6 +1635,8 @@ is_integer(Node, Value) ->
%%
%% @see integer/1
+-spec integer_value(syntaxTree()) -> integer().
+
integer_value(Node) ->
case unwrap(Node) of
{integer, _, Value} ->
@@ -1570,6 +1654,8 @@ integer_value(Node) ->
%%
%% @see integer/1
+-spec integer_literal(syntaxTree()) -> string().
+
integer_literal(Node) ->
integer_to_list(integer_value(Node)).
@@ -1600,6 +1686,8 @@ integer_literal(Node) ->
%% overridden by the type conversion BIF of the same name, so always use
%% `make_float/1' for local calls.
+-spec float(float()) -> syntaxTree().
+
float(Value) ->
make_float(Value).
@@ -1620,6 +1708,8 @@ revert_float(Node) ->
%%
%% @see float/1
+-spec float_value(syntaxTree()) -> float().
+
float_value(Node) ->
case unwrap(Node) of
{float, _, Value} ->
@@ -1637,6 +1727,8 @@ float_value(Node) ->
%%
%% @see float/1
+-spec float_literal(syntaxTree()) -> string().
+
float_literal(Node) ->
float_to_list(float_value(Node)).
@@ -1667,6 +1759,8 @@ float_literal(Node) ->
%%
%% Code = integer()
+-spec char(char()) -> syntaxTree().
+
char(Char) ->
tree(char, Char).
@@ -1676,7 +1770,7 @@ revert_char(Node) ->
%% =====================================================================
-%% @spec is_char(Node::syntaxTree(), Value::char()) -> bool()
+%% @spec is_char(Node::syntaxTree(), Value::char()) -> boolean()
%%
%% @doc Returns <code>true</code> if <code>Node</code> has type
%% <code>char</code> and represents <code>Value</code>, otherwise
@@ -1684,6 +1778,8 @@ revert_char(Node) ->
%%
%% @see char/1
+-spec is_char(syntaxTree(), char()) -> boolean().
+
is_char(Node, Value) ->
case unwrap(Node) of
{char, _, Value} ->
@@ -1702,6 +1798,8 @@ is_char(Node, Value) ->
%%
%% @see char/1
+-spec char_value(syntaxTree()) -> char().
+
char_value(Node) ->
case unwrap(Node) of
{char, _, Char} ->
@@ -1719,6 +1817,8 @@ char_value(Node) ->
%%
%% @see char/1
+-spec char_literal(syntaxTree()) -> string().
+
char_literal(Node) ->
io_lib:write_char(char_value(Node)).
@@ -1749,6 +1849,8 @@ char_literal(Node) ->
%%
%% Chars = string()
+-spec string(string()) -> syntaxTree().
+
string(String) ->
tree(string, String).
@@ -1758,7 +1860,7 @@ revert_string(Node) ->
%% =====================================================================
-%% @spec is_string(Node::syntaxTree(), Value::string()) -> bool()
+%% @spec is_string(Node::syntaxTree(), Value::string()) -> boolean()
%%
%% @doc Returns <code>true</code> if <code>Node</code> has type
%% <code>string</code> and represents <code>Value</code>, otherwise
@@ -1766,6 +1868,8 @@ revert_string(Node) ->
%%
%% @see string/1
+-spec is_string(syntaxTree(), string()) -> boolean().
+
is_string(Node, Value) ->
case unwrap(Node) of
{string, _, Value} ->
@@ -1784,6 +1888,8 @@ is_string(Node, Value) ->
%%
%% @see string/1
+-spec string_value(syntaxTree()) -> string().
+
string_value(Node) ->
case unwrap(Node) of
{string, _, List} ->
@@ -1801,6 +1907,8 @@ string_value(Node) ->
%%
%% @see string/1
+-spec string_literal(syntaxTree()) -> string().
+
string_literal(Node) ->
io_lib:write_string(string_value(Node)).
@@ -1826,6 +1934,8 @@ string_literal(Node) ->
%%
%% Value = atom()
+-spec atom(atom() | string()) -> syntaxTree().
+
atom(Name) when is_atom(Name) ->
tree(atom, Name);
atom(Name) ->
@@ -1837,7 +1947,7 @@ revert_atom(Node) ->
%% =====================================================================
-%% @spec is_atom(Node::syntaxTree(), Value::atom()) -> bool()
+%% @spec is_atom(Node::syntaxTree(), Value::atom()) -> boolean()
%%
%% @doc Returns <code>true</code> if <code>Node</code> has type
%% <code>atom</code> and represents <code>Value</code>, otherwise
@@ -1845,6 +1955,8 @@ revert_atom(Node) ->
%%
%% @see atom/1
+-spec is_atom(syntaxTree(), atom()) -> boolean().
+
is_atom(Node, Value) ->
case unwrap(Node) of
{atom, _, Value} ->
@@ -1863,6 +1975,8 @@ is_atom(Node, Value) ->
%%
%% @see atom/1
+-spec atom_value(syntaxTree()) -> atom().
+
atom_value(Node) ->
case unwrap(Node) of
{atom, _, Name} ->
@@ -1879,6 +1993,8 @@ atom_value(Node) ->
%%
%% @see atom/1
+-spec atom_name(syntaxTree()) -> string().
+
atom_name(Node) ->
atom_to_list(atom_value(Node)).
@@ -1897,6 +2013,8 @@ atom_name(Node) ->
%% @see atom/1
%% @see string/1
+-spec atom_literal(syntaxTree()) -> string().
+
atom_literal(Node) ->
io_lib:write_atom(atom_value(Node)).
@@ -1925,6 +2043,8 @@ atom_literal(Node) ->
%%
%% Elements = [erl_parse()]
+-spec tuple([syntaxTree()]) -> syntaxTree().
+
tuple(List) ->
tree(tuple, List).
@@ -1941,6 +2061,8 @@ revert_tuple(Node) ->
%%
%% @see tuple/1
+-spec tuple_elements(syntaxTree()) -> [syntaxTree()].
+
tuple_elements(Node) ->
case unwrap(Node) of
{tuple, _, List} ->
@@ -1962,6 +2084,8 @@ tuple_elements(Node) ->
%% @see tuple/1
%% @see tuple_elements/1
+-spec tuple_size(syntaxTree()) -> non_neg_integer().
+
tuple_size(Node) ->
length(tuple_elements(Node)).
@@ -1970,6 +2094,8 @@ tuple_size(Node) ->
%% @spec list(List) -> syntaxTree()
%% @equiv list(List, none)
+-spec list([syntaxTree()]) -> syntaxTree().
+
list(List) ->
list(List, none).
@@ -2020,7 +2146,7 @@ list(List) ->
%% @see compact_list/1
%% @see get_attrs/1
--record(list, {prefix, suffix}).
+-record(list, {prefix :: [syntaxTree()], suffix :: 'none' | syntaxTree()}).
%% type(Node) = list
%% data(Node) = #list{prefix :: Elements, suffix :: Tail}
@@ -2038,9 +2164,11 @@ list(List) ->
%% <Suffix>]' where the form of <Suffix> can depend on the
%% structure of <Tail>; there is no fixed printed form.
+-spec list([syntaxTree()], 'none' | syntaxTree()) -> syntaxTree().
+
list([], none) ->
nil();
-list(Elements, Tail) when Elements /= [] ->
+list(Elements, Tail) when Elements =/= [] ->
tree(list, #list{prefix = Elements, suffix = Tail}).
revert_list(Node) ->
@@ -2073,6 +2201,8 @@ revert_list(Node) ->
%%
%% {nil, Pos}
+-spec nil() -> syntaxTree().
+
nil() ->
tree(nil).
@@ -2092,6 +2222,8 @@ revert_nil(Node) ->
%%
%% @see list/2
+-spec list_prefix(syntaxTree()) -> [syntaxTree()].
+
list_prefix(Node) ->
case unwrap(Node) of
{cons, _, Head, _} ->
@@ -2102,7 +2234,7 @@ list_prefix(Node) ->
%% =====================================================================
-%% @spec list_suffix(Node::syntaxTree()) -> none | syntaxTree()
+%% @spec list_suffix(Node::syntaxTree()) -> none | syntaxTree()
%%
%% @doc Returns the suffix subtree of a <code>list</code> node, if one
%% exists. If <code>Node</code> represents "<code>[<em>E1</em>, ...,
@@ -2121,6 +2253,8 @@ list_prefix(Node) ->
%% @see nil/0
%% @see compact_list/1
+-spec list_suffix(syntaxTree()) -> 'none' | syntaxTree().
+
list_suffix(Node) ->
case unwrap(Node) of
{cons, _, _, Tail} ->
@@ -2158,6 +2292,8 @@ list_suffix(Node) ->
%% @see list_head/1
%% @see list_tail/1
+-spec cons(syntaxTree(), syntaxTree()) -> syntaxTree().
+
cons(Head, Tail) ->
case type(Tail) of
list ->
@@ -2181,6 +2317,8 @@ cons(Head, Tail) ->
%% @see list_tail/1
%% @see cons/2
+-spec list_head(syntaxTree()) -> syntaxTree().
+
list_head(Node) ->
hd(list_prefix(Node)).
@@ -2202,6 +2340,8 @@ list_head(Node) ->
%% @see list_head/1
%% @see cons/2
+-spec list_tail(syntaxTree()) -> syntaxTree().
+
list_tail(Node) ->
Tail = list_suffix(Node),
case tl(list_prefix(Node)) of
@@ -2217,7 +2357,7 @@ list_tail(Node) ->
%% =====================================================================
-%% @spec is_list_skeleton(syntaxTree()) -> bool()
+%% @spec is_list_skeleton(syntaxTree()) -> boolean()
%%
%% @doc Returns <code>true</code> if <code>Node</code> has type
%% <code>list</code> or <code>nil</code>, otherwise <code>false</code>.
@@ -2225,6 +2365,8 @@ list_tail(Node) ->
%% @see list/2
%% @see nil/0
+-spec is_list_skeleton(syntaxTree()) -> boolean().
+
is_list_skeleton(Node) ->
case type(Node) of
list -> true;
@@ -2234,7 +2376,7 @@ is_list_skeleton(Node) ->
%% =====================================================================
-%% @spec is_proper_list(Node::syntaxTree()) -> bool()
+%% @spec is_proper_list(Node::syntaxTree()) -> boolean()
%%
%% @doc Returns <code>true</code> if <code>Node</code> represents a
%% proper list, and <code>false</code> otherwise. A proper list is a
@@ -2255,6 +2397,8 @@ is_list_skeleton(Node) ->
%%
%% @see list/2
+-spec is_proper_list(syntaxTree()) -> boolean().
+
is_proper_list(Node) ->
case type(Node) of
list ->
@@ -2284,6 +2428,8 @@ is_proper_list(Node) ->
%% @see list/2
%% @see is_proper_list/1
+-spec list_elements(syntaxTree()) -> [syntaxTree()].
+
list_elements(Node) ->
lists:reverse(list_elements(Node, [])).
@@ -2319,6 +2465,8 @@ list_elements(Node, As) ->
%% @see is_proper_list/1
%% @see list_elements/1
+-spec list_length(syntaxTree()) -> non_neg_integer().
+
list_length(Node) ->
list_length(Node, 0).
@@ -2354,6 +2502,8 @@ list_length(Node, A) ->
%% @see list/2
%% @see compact_list/1
+-spec normalize_list(syntaxTree()) -> syntaxTree().
+
normalize_list(Node) ->
case type(Node) of
list ->
@@ -2391,6 +2541,8 @@ normalize_list_1(Es, Tail) ->
%% @see list/2
%% @see normalize_list/1
+-spec compact_list(syntaxTree()) -> syntaxTree().
+
compact_list(Node) ->
case type(Node) of
list ->
@@ -2447,6 +2599,8 @@ compact_list(Node) ->
%% See `binary_field' for documentation on `erl_parse' binary
%% fields (or "elements").
+-spec binary([syntaxTree()]) -> syntaxTree().
+
binary(List) ->
tree(binary, List).
@@ -2464,6 +2618,8 @@ revert_binary(Node) ->
%% @see binary/1
%% @see binary_field/2
+-spec binary_fields(syntaxTree()) -> [syntaxTree()].
+
binary_fields(Node) ->
case unwrap(Node) of
{bin, _, List} ->
@@ -2477,6 +2633,8 @@ binary_fields(Node) ->
%% @spec binary_field(Body) -> syntaxTree()
%% @equiv binary_field(Body, [])
+-spec binary_field(syntaxTree()) -> syntaxTree().
+
binary_field(Body) ->
binary_field(Body, []).
@@ -2498,6 +2656,9 @@ binary_field(Body) ->
%% @see binary_field/2
%% @see size_qualifier/2
+-spec binary_field(syntaxTree(), 'none' | syntaxTree(), [syntaxTree()]) ->
+ syntaxTree().
+
binary_field(Body, none, Types) ->
binary_field(Body, Types);
binary_field(Body, Size, Types) ->
@@ -2521,13 +2682,13 @@ binary_field(Body, Size, Types) ->
%% @see binary_field_types/1
%% @see binary_field_size/1
--record(binary_field, {body, types}).
+-record(binary_field, {body :: syntaxTree(), types :: [syntaxTree()]}).
%% type(Node) = binary_field
%% data(Node) = #binary_field{body :: Body, types :: Types}
%%
%% Body = syntaxTree()
-%% Types = [Type]
+%% Types = [syntaxTree()]
%%
%% `erl_parse' representation:
%%
@@ -2538,6 +2699,8 @@ binary_field(Body, Size, Types) ->
%% TypeList = default | [Type] \ []
%% Type = atom() | {atom(), integer()}
+-spec binary_field(syntaxTree(), [syntaxTree()]) -> syntaxTree().
+
binary_field(Body, Types) ->
tree(binary_field, #binary_field{body = Body, types = Types}).
@@ -2569,6 +2732,8 @@ revert_binary_field(Node) ->
%%
%% @see binary_field/2
+-spec binary_field_body(syntaxTree()) -> syntaxTree().
+
binary_field_body(Node) ->
case unwrap(Node) of
{bin_element, _, Body, Size, _} ->
@@ -2592,6 +2757,8 @@ binary_field_body(Node) ->
%%
%% @see binary_field/2
+-spec binary_field_types(syntaxTree()) -> [syntaxTree()].
+
binary_field_types(Node) ->
case unwrap(Node) of
{bin_element, Pos, _, _, Types} ->
@@ -2620,6 +2787,8 @@ binary_field_types(Node) ->
%% @see binary_field/2
%% @see binary_field/3
+-spec binary_field_size(syntaxTree()) -> 'none' | syntaxTree().
+
binary_field_size(Node) ->
case unwrap(Node) of
{bin_element, _, _, Size, _} ->
@@ -2649,13 +2818,15 @@ binary_field_size(Node) ->
%% @see size_qualifier_body/1
%% @see size_qualifier_argument/1
--record(size_qualifier, {body, size}).
+-record(size_qualifier, {body :: syntaxTree(), size :: syntaxTree()}).
%% type(Node) = size_qualifier
%% data(Node) = #size_qualifier{body :: Body, size :: Size}
%%
%% Body = Size = syntaxTree()
+-spec size_qualifier(syntaxTree(), syntaxTree()) -> syntaxTree().
+
size_qualifier(Body, Size) ->
tree(size_qualifier,
#size_qualifier{body = Body, size = Size}).
@@ -2669,6 +2840,8 @@ size_qualifier(Body, Size) ->
%%
%% @see size_qualifier/2
+-spec size_qualifier_body(syntaxTree()) -> syntaxTree().
+
size_qualifier_body(Node) ->
(data(Node))#size_qualifier.body.
@@ -2681,6 +2854,8 @@ size_qualifier_body(Node) ->
%%
%% @see size_qualifier/2
+-spec size_qualifier_argument(syntaxTree()) -> syntaxTree().
+
size_qualifier_argument(Node) ->
(data(Node))#size_qualifier.size.
@@ -2714,6 +2889,8 @@ size_qualifier_argument(Node) ->
%% Note that there is no position information for the node
%% itself: `get_pos' and `set_pos' handle this as a special case.
+-spec error_marker(term()) -> syntaxTree().
+
error_marker(Error) ->
tree(error_marker, Error).
@@ -2731,6 +2908,8 @@ revert_error_marker(Node) ->
%%
%% @see error_marker/1
+-spec error_marker_info(syntaxTree()) -> term().
+
error_marker_info(Node) ->
case unwrap(Node) of
{error, Error} ->
@@ -2769,6 +2948,8 @@ error_marker_info(Node) ->
%% Note that there is no position information for the node
%% itself: `get_pos' and `set_pos' handle this as a special case.
+-spec warning_marker(term()) -> syntaxTree().
+
warning_marker(Warning) ->
tree(warning_marker, Warning).
@@ -2786,6 +2967,8 @@ revert_warning_marker(Node) ->
%%
%% @see warning_marker/1
+-spec warning_marker_info(syntaxTree()) -> term().
+
warning_marker_info(Node) ->
case unwrap(Node) of
{warning, Error} ->
@@ -2818,6 +3001,8 @@ warning_marker_info(Node) ->
%%
%% {eof, Pos}
+-spec eof_marker() -> syntaxTree().
+
eof_marker() ->
tree(eof_marker).
@@ -2830,6 +3015,8 @@ revert_eof_marker(Node) ->
%% @spec attribute(Name) -> syntaxTree()
%% @equiv attribute(Name, none)
+-spec attribute(syntaxTree()) -> syntaxTree().
+
attribute(Name) ->
attribute(Name, none).
@@ -2859,7 +3046,7 @@ attribute(Name) ->
%% @see text/1
%% @see is_form/1
--record(attribute, {name, args}).
+-record(attribute, {name :: syntaxTree(), args :: 'none' | [syntaxTree()]}).
%% type(Node) = attribute
%% data(Node) = #attribute{name :: Name, args :: Arguments}
@@ -2922,6 +3109,8 @@ attribute(Name) ->
%%
%% Representing `-Name(Term).'.
+-spec attribute(syntaxTree(), 'none' | [syntaxTree()]) -> syntaxTree().
+
attribute(Name, Args) ->
tree(attribute, #attribute{name = Name, args = Args}).
@@ -3049,6 +3238,8 @@ revert_module_name(A) ->
%%
%% @see attribute/1
+-spec attribute_name(syntaxTree()) -> syntaxTree().
+
attribute_name(Node) ->
case unwrap(Node) of
{attribute, Pos, Name, _} ->
@@ -3071,6 +3262,8 @@ attribute_name(Node) ->
%%
%% @see attribute/1
+-spec attribute_arguments(syntaxTree()) -> none | [syntaxTree()].
+
attribute_arguments(Node) ->
case unwrap(Node) of
{attribute, Pos, Name, Data} ->
@@ -3141,13 +3334,15 @@ attribute_arguments(Node) ->
%% @see arity_qualifier_body/1
%% @see arity_qualifier_argument/1
--record(arity_qualifier, {body, arity}).
+-record(arity_qualifier, {body :: syntaxTree(), arity :: syntaxTree()}).
%% type(Node) = arity_qualifier
%% data(Node) = #arity_qualifier{body :: Body, arity :: Arity}
%%
%% Body = Arity = syntaxTree()
+-spec arity_qualifier(syntaxTree(), syntaxTree()) -> syntaxTree().
+
arity_qualifier(Body, Arity) ->
tree(arity_qualifier,
#arity_qualifier{body = Body, arity = Arity}).
@@ -3161,6 +3356,8 @@ arity_qualifier(Body, Arity) ->
%%
%% @see arity_qualifier/2
+-spec arity_qualifier_body(syntaxTree()) -> syntaxTree().
+
arity_qualifier_body(Node) ->
(data(Node))#arity_qualifier.body.
@@ -3173,6 +3370,8 @@ arity_qualifier_body(Node) ->
%%
%% @see arity_qualifier/2
+-spec arity_qualifier_argument(syntaxTree()) -> syntaxTree().
+
arity_qualifier_argument(Node) ->
(data(Node))#arity_qualifier.arity.
@@ -3187,7 +3386,7 @@ arity_qualifier_argument(Node) ->
%% @see module_qualifier_argument/1
%% @see module_qualifier_body/1
--record(module_qualifier, {module, body}).
+-record(module_qualifier, {module :: syntaxTree(), body :: syntaxTree()}).
%% type(Node) = module_qualifier
%% data(Node) = #module_qualifier{module :: Module, body :: Body}
@@ -3200,6 +3399,8 @@ arity_qualifier_argument(Node) ->
%%
%% Module = Arg = erl_parse()
+-spec module_qualifier(syntaxTree(), syntaxTree()) -> syntaxTree().
+
module_qualifier(Module, Body) ->
tree(module_qualifier,
#module_qualifier{module = Module, body = Body}).
@@ -3219,6 +3420,8 @@ revert_module_qualifier(Node) ->
%%
%% @see module_qualifier/2
+-spec module_qualifier_argument(syntaxTree()) -> syntaxTree().
+
module_qualifier_argument(Node) ->
case unwrap(Node) of
{remote, _, Module, _} ->
@@ -3236,6 +3439,8 @@ module_qualifier_argument(Node) ->
%%
%% @see module_qualifier/2
+-spec module_qualifier_body(syntaxTree()) -> syntaxTree().
+
module_qualifier_body(Node) ->
case unwrap(Node) of
{remote, _, _, Body} ->
@@ -3267,6 +3472,8 @@ module_qualifier_body(Node) ->
%% represents a Mnemosyne query record field access ('record_access');
%% see type/1 for details.
+-spec qualified_name([syntaxTree()]) -> syntaxTree().
+
qualified_name(Segments) ->
tree(qualified_name, Segments).
@@ -3283,6 +3490,8 @@ revert_qualified_name(Node) ->
%%
%% @see qualified_name/1
+-spec qualified_name_segments(syntaxTree()) -> [syntaxTree()].
+
qualified_name_segments(Node) ->
case unwrap(Node) of
{record_field, _, _, _} = Node1 ->
@@ -3314,6 +3523,9 @@ qualified_name_segments(Node) ->
%% @see rule/2
-record(function, {name, clauses}).
+%% XXX: This one is problematic because there is a tuple with the same
+%% tag and size that comes from 'erl_parse'
+%% -record(function, {name :: syntaxTree(), clauses :: [syntaxTree()]}).
%% type(Node) = function
%% data(Node) = #function{name :: Name, clauses :: Clauses}
@@ -3340,6 +3552,8 @@ qualified_name_segments(Node) ->
%% the integer `Arity'; see `clause' for documentation on
%% `erl_parse' clauses.
+-spec function(syntaxTree(), [syntaxTree()]) -> syntaxTree().
+
function(Name, Clauses) ->
tree(function, #function{name = Name, clauses = Clauses}).
@@ -3363,6 +3577,8 @@ revert_function(Node) ->
%%
%% @see function/2
+-spec function_name(syntaxTree()) -> syntaxTree().
+
function_name(Node) ->
case unwrap(Node) of
{function, Pos, Name, _, _} ->
@@ -3380,6 +3596,8 @@ function_name(Node) ->
%%
%% @see function/2
+-spec function_clauses(syntaxTree()) -> [syntaxTree()].
+
function_clauses(Node) ->
case unwrap(Node) of
{function, _, _, _, Clauses} ->
@@ -3406,6 +3624,8 @@ function_clauses(Node) ->
%% @see clause/3
%% @see clause_patterns/1
+-spec function_arity(syntaxTree()) -> arity().
+
function_arity(Node) ->
%% Note that this never accesses the arity field of `erl_parse'
%% function nodes.
@@ -3416,6 +3636,10 @@ function_arity(Node) ->
%% @spec clause(Guard, Body) -> syntaxTree()
%% @equiv clause([], Guard, Body)
+-type guard() :: 'none' | syntaxTree() | [syntaxTree()] | [[syntaxTree()]].
+
+-spec clause(guard(), [syntaxTree()]) -> syntaxTree().
+
clause(Guard, Body) ->
clause([], Guard, Body).
@@ -3455,7 +3679,9 @@ clause(Guard, Body) ->
%% @see clause_guard/1
%% @see clause_body/1
--record(clause, {patterns, guard, body}).
+-record(clause, {patterns :: [syntaxTree()],
+ guard :: guard(),
+ body :: [syntaxTree()]}).
%% type(Node) = clause
%% data(Node) = #clause{patterns :: Patterns, guard :: Guard,
@@ -3482,6 +3708,8 @@ clause(Guard, Body) ->
%% versions, `Guard' was simply a list `[E1, ..., En]' of parse
%% trees, which is equivalent to the new form `[[E1, ..., En]]'.
+-spec clause([syntaxTree()], guard(), [syntaxTree()]) -> syntaxTree().
+
clause(Patterns, Guard, Body) ->
Guard1 = case Guard of
[] ->
@@ -3551,7 +3779,7 @@ fold_try_clause({clause, Pos, [P], Guard, Body}) ->
unfold_try_clauses(Cs) ->
[unfold_try_clause(C) || C <- Cs].
-unfold_try_clause({clause, Pos, [{tuple, _, [{atom,_,throw}, V, _]}],
+unfold_try_clause({clause, Pos, [{tuple, _, [{atom, _, throw}, V, _]}],
Guard, Body}) ->
{clause, Pos, [V], Guard, Body};
unfold_try_clause({clause, Pos, [{tuple, _, [C, V, _]}],
@@ -3567,6 +3795,8 @@ unfold_try_clause({clause, Pos, [{tuple, _, [C, V, _]}],
%%
%% @see clause/3
+-spec clause_patterns(syntaxTree()) -> [syntaxTree()].
+
clause_patterns(Node) ->
case unwrap(Node) of
{clause, _, Patterns, _, _} ->
@@ -3587,6 +3817,8 @@ clause_patterns(Node) ->
%%
%% @see clause/3
+-spec clause_guard(syntaxTree()) -> 'none' | syntaxTree().
+
clause_guard(Node) ->
case unwrap(Node) of
{clause, _, _, Guard, _} ->
@@ -3610,6 +3842,8 @@ clause_guard(Node) ->
%%
%% @see clause/3
+-spec clause_body(syntaxTree()) -> [syntaxTree()].
+
clause_body(Node) ->
case unwrap(Node) of
{clause, _, _, _, Body} ->
@@ -3632,6 +3866,8 @@ clause_body(Node) ->
%% type(Node) = disjunction
%% data(Node) = [syntaxTree()]
+-spec disjunction([syntaxTree()]) -> syntaxTree().
+
disjunction(Tests) ->
tree(disjunction, Tests).
@@ -3644,6 +3880,8 @@ disjunction(Tests) ->
%%
%% @see disjunction/1
+-spec disjunction_body(syntaxTree()) -> [syntaxTree()].
+
disjunction_body(Node) ->
data(Node).
@@ -3661,6 +3899,8 @@ disjunction_body(Node) ->
%% type(Node) = conjunction
%% data(Node) = [syntaxTree()]
+-spec conjunction([syntaxTree()]) -> syntaxTree().
+
conjunction(Tests) ->
tree(conjunction, Tests).
@@ -3673,6 +3913,8 @@ conjunction(Tests) ->
%%
%% @see conjunction/1
+-spec conjunction_body(syntaxTree()) -> [syntaxTree()].
+
conjunction_body(Node) ->
data(Node).
@@ -3694,6 +3936,8 @@ conjunction_body(Node) ->
%%
%% Expr = erl_parse()
+-spec catch_expr(syntaxTree()) -> syntaxTree().
+
catch_expr(Expr) ->
tree(catch_expr, Expr).
@@ -3710,6 +3954,8 @@ revert_catch_expr(Node) ->
%%
%% @see catch_expr/1
+-spec catch_expr_body(syntaxTree()) -> syntaxTree().
+
catch_expr_body(Node) ->
case unwrap(Node) of
{'catch', _, Expr} ->
@@ -3729,7 +3975,7 @@ catch_expr_body(Node) ->
%% @see match_expr_pattern/1
%% @see match_expr_body/1
--record(match_expr, {pattern, body}).
+-record(match_expr, {pattern :: syntaxTree(), body :: syntaxTree()}).
%% type(Node) = match_expr
%% data(Node) = #match_expr{pattern :: Pattern, body :: Body}
@@ -3742,6 +3988,8 @@ catch_expr_body(Node) ->
%%
%% Pattern = Body = erl_parse()
+-spec match_expr(syntaxTree(), syntaxTree()) -> syntaxTree().
+
match_expr(Pattern, Body) ->
tree(match_expr, #match_expr{pattern = Pattern, body = Body}).
@@ -3759,6 +4007,8 @@ revert_match_expr(Node) ->
%%
%% @see match_expr/2
+-spec match_expr_pattern(syntaxTree()) -> syntaxTree().
+
match_expr_pattern(Node) ->
case unwrap(Node) of
{match, _, Pattern, _} ->
@@ -3775,6 +4025,8 @@ match_expr_pattern(Node) ->
%%
%% @see match_expr/2
+-spec match_expr_body(syntaxTree()) -> syntaxTree().
+
match_expr_body(Node) ->
case unwrap(Node) of
{match, _, _, Body} ->
@@ -3802,6 +4054,8 @@ match_expr_body(Node) ->
%% type(Node) = operator
%% data(Node) = atom()
+-spec operator(atom() | string()) -> syntaxTree().
+
operator(Name) when is_atom(Name) ->
tree(operator, Name);
operator(Name) ->
@@ -3816,6 +4070,8 @@ operator(Name) ->
%%
%% @see operator/1
+-spec operator_name(syntaxTree()) -> atom().
+
operator_name(Node) ->
data(Node).
@@ -3829,6 +4085,8 @@ operator_name(Node) ->
%%
%% @see operator/1
+-spec operator_literal(syntaxTree()) -> string().
+
operator_literal(Node) ->
atom_to_list(operator_name(Node)).
@@ -3846,7 +4104,9 @@ operator_literal(Node) ->
%% @see infix_expr_operator/1
%% @see prefix_expr/2
--record(infix_expr, {operator, left, right}).
+-record(infix_expr, {operator :: syntaxTree(),
+ left :: syntaxTree(),
+ right :: syntaxTree()}).
%% type(Node) = infix_expr
%% data(Node) = #infix_expr{left :: Left, operator :: Operator,
@@ -3861,6 +4121,8 @@ operator_literal(Node) ->
%% Operator = atom()
%% Left = Right = erl_parse()
+-spec infix_expr(syntaxTree(), syntaxTree(), syntaxTree()) -> syntaxTree().
+
infix_expr(Left, Operator, Right) ->
tree(infix_expr, #infix_expr{operator = Operator, left = Left,
right = Right}).
@@ -3888,6 +4150,8 @@ revert_infix_expr(Node) ->
%%
%% @see infix_expr/3
+-spec infix_expr_left(syntaxTree()) -> syntaxTree().
+
infix_expr_left(Node) ->
case unwrap(Node) of
{op, _, _, Left, _} ->
@@ -3905,6 +4169,8 @@ infix_expr_left(Node) ->
%%
%% @see infix_expr/3
+-spec infix_expr_operator(syntaxTree()) -> syntaxTree().
+
infix_expr_operator(Node) ->
case unwrap(Node) of
{op, Pos, Operator, _, _} ->
@@ -3922,6 +4188,8 @@ infix_expr_operator(Node) ->
%%
%% @see infix_expr/3
+-spec infix_expr_right(syntaxTree()) -> syntaxTree().
+
infix_expr_right(Node) ->
case unwrap(Node) of
{op, _, _, _, Right} ->
@@ -3942,7 +4210,7 @@ infix_expr_right(Node) ->
%% @see prefix_expr_operator/1
%% @see infix_expr/3
--record(prefix_expr, {operator, argument}).
+-record(prefix_expr, {operator :: syntaxTree(), argument :: syntaxTree()}).
%% type(Node) = prefix_expr
%% data(Node) = #prefix_expr{operator :: Operator,
@@ -3957,6 +4225,8 @@ infix_expr_right(Node) ->
%% Operator = atom()
%% Argument = erl_parse()
+-spec prefix_expr(syntaxTree(), syntaxTree()) -> syntaxTree().
+
prefix_expr(Operator, Argument) ->
tree(prefix_expr, #prefix_expr{operator = Operator,
argument = Argument}).
@@ -3983,6 +4253,8 @@ revert_prefix_expr(Node) ->
%%
%% @see prefix_expr/2
+-spec prefix_expr_operator(syntaxTree()) -> syntaxTree().
+
prefix_expr_operator(Node) ->
case unwrap(Node) of
{op, Pos, Operator, _} ->
@@ -4000,6 +4272,8 @@ prefix_expr_operator(Node) ->
%%
%% @see prefix_expr/2
+-spec prefix_expr_argument(syntaxTree()) -> syntaxTree().
+
prefix_expr_argument(Node) ->
case unwrap(Node) of
{op, _, _, Argument} ->
@@ -4013,6 +4287,8 @@ prefix_expr_argument(Node) ->
%% @spec record_field(Name) -> syntaxTree()
%% @equiv record_field(Name, none)
+-spec record_field(syntaxTree()) -> syntaxTree().
+
record_field(Name) ->
record_field(Name, none).
@@ -4030,13 +4306,15 @@ record_field(Name) ->
%% @see record_field_value/1
%% @see record_expr/3
--record(record_field, {name, value}).
+-record(record_field, {name :: syntaxTree(), value :: 'none' | syntaxTree()}).
%% type(Node) = record_field
%% data(Node) = #record_field{name :: Name, value :: Value}
%%
%% Name = Value = syntaxTree()
+-spec record_field(syntaxTree(), 'none' | syntaxTree()) -> syntaxTree().
+
record_field(Name, Value) ->
tree(record_field, #record_field{name = Name, value = Value}).
@@ -4048,6 +4326,8 @@ record_field(Name, Value) ->
%%
%% @see record_field/2
+-spec record_field_name(syntaxTree()) -> syntaxTree().
+
record_field_name(Node) ->
(data(Node))#record_field.name.
@@ -4064,6 +4344,8 @@ record_field_name(Node) ->
%%
%% @see record_field/2
+-spec record_field_value(syntaxTree()) -> 'none' | syntaxTree().
+
record_field_value(Node) ->
(data(Node))#record_field.value.
@@ -4083,7 +4365,7 @@ record_field_value(Node) ->
%% @see record_index_expr_field/1
%% @see record_expr/3
--record(record_index_expr, {type, field}).
+-record(record_index_expr, {type :: syntaxTree(), field :: syntaxTree()}).
%% type(Node) = record_index_expr
%% data(Node) = #record_index_expr{type :: Type, field :: Field}
@@ -4097,6 +4379,8 @@ record_field_value(Node) ->
%% Type = atom()
%% Field = erl_parse()
+-spec record_index_expr(syntaxTree(), syntaxTree()) -> syntaxTree().
+
record_index_expr(Type, Field) ->
tree(record_index_expr, #record_index_expr{type = Type,
field = Field}).
@@ -4121,6 +4405,8 @@ revert_record_index_expr(Node) ->
%%
%% @see record_index_expr/2
+-spec record_index_expr_type(syntaxTree()) -> syntaxTree().
+
record_index_expr_type(Node) ->
case unwrap(Node) of
{record_index, Pos, Type, _} ->
@@ -4138,6 +4424,8 @@ record_index_expr_type(Node) ->
%%
%% @see record_index_expr/2
+-spec record_index_expr_field(syntaxTree()) -> syntaxTree().
+
record_index_expr_field(Node) ->
case unwrap(Node) of
{record_index, _, _, Field} ->
@@ -4151,6 +4439,8 @@ record_index_expr_field(Node) ->
%% @spec record_access(Argument, Field) -> syntaxTree()
%% @equiv record_access(Argument, none, Field)
+-spec record_access(syntaxTree(), syntaxTree()) -> syntaxTree().
+
record_access(Argument, Field) ->
record_access(Argument, none, Field).
@@ -4175,7 +4465,9 @@ record_access(Argument, Field) ->
%% @see record_expr/3
%% @see query_expr/1
--record(record_access, {argument, type, field}).
+-record(record_access, {argument :: syntaxTree(),
+ type :: 'none' | syntaxTree(),
+ field :: syntaxTree()}).
%% type(Node) = record_access
%% data(Node) = #record_access{argument :: Argument, type :: Type,
@@ -4192,6 +4484,9 @@ record_access(Argument, Field) ->
%% Argument = Field = erl_parse()
%% Type = atom()
+-spec record_access(syntaxTree(), 'none' | syntaxTree(), syntaxTree()) ->
+ syntaxTree().
+
record_access(Argument, Type, Field) ->
tree(record_access,#record_access{argument = Argument,
type = Type,
@@ -4223,6 +4518,8 @@ revert_record_access(Node) ->
%%
%% @see record_access/3
+-spec record_access_argument(syntaxTree()) -> syntaxTree().
+
record_access_argument(Node) ->
case unwrap(Node) of
{record_field, _, Argument, _} ->
@@ -4246,6 +4543,8 @@ record_access_argument(Node) ->
%%
%% @see record_access/3
+-spec record_access_type(syntaxTree()) -> 'none' | syntaxTree().
+
record_access_type(Node) ->
case unwrap(Node) of
{record_field, _, _, _} ->
@@ -4265,6 +4564,8 @@ record_access_type(Node) ->
%%
%% @see record_access/3
+-spec record_access_field(syntaxTree()) -> syntaxTree().
+
record_access_field(Node) ->
case unwrap(Node) of
{record_field, _, _, Field} ->
@@ -4280,6 +4581,8 @@ record_access_field(Node) ->
%% @spec record_expr(Type, Fields) -> syntaxTree()
%% @equiv record_expr(none, Type, Fields)
+-spec record_expr(syntaxTree(), [syntaxTree()]) -> syntaxTree().
+
record_expr(Type, Fields) ->
record_expr(none, Type, Fields).
@@ -4305,7 +4608,9 @@ record_expr(Type, Fields) ->
%% @see record_index_expr/2
%% @see record_access/3
--record(record_expr, {argument, type, fields}).
+-record(record_expr, {argument :: 'none' | syntaxTree(),
+ type :: syntaxTree(),
+ fields :: [syntaxTree()]}).
%% type(Node) = record_expr
%% data(Node) = #record_expr{argument :: Argument, type :: Type,
@@ -4327,6 +4632,9 @@ record_expr(Type, Fields) ->
%% | {record_field, Pos, Field}
%% Field = Value = erl_parse()
+-spec record_expr('none' | syntaxTree(), syntaxTree(), [syntaxTree()]) ->
+ syntaxTree().
+
record_expr(Argument, Type, Fields) ->
tree(record_expr, #record_expr{argument = Argument,
type = Type, fields = Fields}).
@@ -4363,6 +4671,8 @@ revert_record_expr(Node) ->
%%
%% @see record_expr/3
+-spec record_expr_argument(syntaxTree()) -> 'none' | syntaxTree().
+
record_expr_argument(Node) ->
case unwrap(Node) of
{record, _, _, _} ->
@@ -4381,6 +4691,8 @@ record_expr_argument(Node) ->
%%
%% @see record_expr/3
+-spec record_expr_type(syntaxTree()) -> syntaxTree().
+
record_expr_type(Node) ->
case unwrap(Node) of
{record, Pos, Type, _} ->
@@ -4400,6 +4712,8 @@ record_expr_type(Node) ->
%%
%% @see record_expr/3
+-spec record_expr_fields(syntaxTree()) -> [syntaxTree()].
+
record_expr_fields(Node) ->
case unwrap(Node) of
{record, _, _, Fields} ->
@@ -4427,6 +4741,9 @@ record_expr_fields(Node) ->
%% @see application/2
%% @see module_qualifier/2
+-spec application('none' | syntaxTree(), syntaxTree(), [syntaxTree()]) ->
+ syntaxTree().
+
application(none, Name, Arguments) ->
application(Name, Arguments);
application(Module, Name, Arguments) ->
@@ -4446,7 +4763,7 @@ application(Module, Name, Arguments) ->
%% @see application_arguments/1
%% @see application/3
--record(application, {operator, arguments}).
+-record(application, {operator :: syntaxTree(), arguments :: [syntaxTree()]}).
%% type(Node) = application
%% data(Node) = #application{operator :: Operator,
@@ -4462,6 +4779,8 @@ application(Module, Name, Arguments) ->
%% Operator = erl_parse()
%% Arguments = [erl_parse()]
+-spec application(syntaxTree(), [syntaxTree()]) -> syntaxTree().
+
application(Operator, Arguments) ->
tree(application, #application{operator = Operator,
arguments = Arguments}).
@@ -4486,6 +4805,8 @@ revert_application(Node) ->
%% @see application/2
%% @see module_qualifier/2
+-spec application_operator(syntaxTree()) -> syntaxTree().
+
application_operator(Node) ->
case unwrap(Node) of
{call, _, Operator, _} ->
@@ -4503,6 +4824,8 @@ application_operator(Node) ->
%%
%% @see application/2
+-spec application_arguments(syntaxTree()) -> [syntaxTree()].
+
application_arguments(Node) ->
case unwrap(Node) of
{call, _, _, Arguments} ->
@@ -4524,7 +4847,7 @@ application_arguments(Node) ->
%% @see list_comp_body/1
%% @see generator/2
--record(list_comp, {template, body}).
+-record(list_comp, {template :: syntaxTree(), body :: [syntaxTree()]}).
%% type(Node) = list_comp
%% data(Node) = #list_comp{template :: Template, body :: Body}
@@ -4539,6 +4862,8 @@ application_arguments(Node) ->
%% Template = erl_parse()
%% Body = [erl_parse()] \ []
+-spec list_comp(syntaxTree(), [syntaxTree()]) -> syntaxTree().
+
list_comp(Template, Body) ->
tree(list_comp, #list_comp{template = Template, body = Body}).
@@ -4556,6 +4881,8 @@ revert_list_comp(Node) ->
%%
%% @see list_comp/2
+-spec list_comp_template(syntaxTree()) -> syntaxTree().
+
list_comp_template(Node) ->
case unwrap(Node) of
{lc, _, Template, _} ->
@@ -4573,6 +4900,8 @@ list_comp_template(Node) ->
%%
%% @see list_comp/2
+-spec list_comp_body(syntaxTree()) -> [syntaxTree()].
+
list_comp_body(Node) ->
case unwrap(Node) of
{lc, _, _, Body} ->
@@ -4593,7 +4922,7 @@ list_comp_body(Node) ->
%% @see binary_comp_body/1
%% @see generator/2
--record(binary_comp, {template, body}).
+-record(binary_comp, {template :: syntaxTree(), body :: [syntaxTree()]}).
%% type(Node) = binary_comp
%% data(Node) = #binary_comp{template :: Template, body :: Body}
@@ -4608,6 +4937,8 @@ list_comp_body(Node) ->
%% Template = erl_parse()
%% Body = [erl_parse()] \ []
+-spec binary_comp(syntaxTree(), [syntaxTree()]) -> syntaxTree().
+
binary_comp(Template, Body) ->
tree(binary_comp, #binary_comp{template = Template, body = Body}).
@@ -4625,6 +4956,8 @@ revert_binary_comp(Node) ->
%%
%% @see binary_comp/2
+-spec binary_comp_template(syntaxTree()) -> syntaxTree().
+
binary_comp_template(Node) ->
case unwrap(Node) of
{bc, _, Template, _} ->
@@ -4642,6 +4975,8 @@ binary_comp_template(Node) ->
%%
%% @see binary_comp/2
+-spec binary_comp_body(syntaxTree()) -> [syntaxTree()].
+
binary_comp_body(Node) ->
case unwrap(Node) of
{bc, _, _, Body} ->
@@ -4670,6 +5005,8 @@ binary_comp_body(Node) ->
%%
%% Body = erl_parse()
+-spec query_expr(syntaxTree()) -> syntaxTree().
+
query_expr(Body) ->
tree(query_expr, Body).
@@ -4686,6 +5023,8 @@ revert_query_expr(Node) ->
%%
%% @see query_expr/1
+-spec query_expr_body(syntaxTree()) -> syntaxTree().
+
query_expr_body(Node) ->
case unwrap(Node) of
{'query', _, Body} ->
@@ -4715,7 +5054,7 @@ query_expr_body(Node) ->
%% @see is_form/1
%% @see function/2
--record(rule, {name, clauses}).
+-record(rule, {name :: syntaxTree(), clauses :: [syntaxTree()]}).
%% type(Node) = rule
%% data(Node) = #rule{name :: Name, clauses :: Clauses}
@@ -4738,6 +5077,8 @@ query_expr_body(Node) ->
%% the integer `Arity'; see `clause' for documentation on
%% `erl_parse' clauses.
+-spec rule(syntaxTree(), [syntaxTree()]) -> syntaxTree().
+
rule(Name, Clauses) ->
tree(rule, #rule{name = Name, clauses = Clauses}).
@@ -4761,6 +5102,8 @@ revert_rule(Node) ->
%%
%% @see rule/2
+-spec rule_name(syntaxTree()) -> syntaxTree().
+
rule_name(Node) ->
case unwrap(Node) of
{rule, Pos, Name, _, _} ->
@@ -4776,6 +5119,8 @@ rule_name(Node) ->
%%
%% @see rule/2
+-spec rule_clauses(syntaxTree()) -> [syntaxTree()].
+
rule_clauses(Node) ->
case unwrap(Node) of
{rule, _, _, _, Clauses} ->
@@ -4801,6 +5146,8 @@ rule_clauses(Node) ->
%% @see clause/3
%% @see clause_patterns/1
+-spec rule_arity(syntaxTree()) -> arity().
+
rule_arity(Node) ->
%% Note that this never accesses the arity field of
%% `erl_parse' rule nodes.
@@ -4819,7 +5166,7 @@ rule_arity(Node) ->
%% @see list_comp/2
%% @see binary_comp/2
--record(generator, {pattern, body}).
+-record(generator, {pattern :: syntaxTree(), body :: syntaxTree()}).
%% type(Node) = generator
%% data(Node) = #generator{pattern :: Pattern, body :: Body}
@@ -4832,6 +5179,8 @@ rule_arity(Node) ->
%%
%% Pattern = Body = erl_parse()
+-spec generator(syntaxTree(), syntaxTree()) -> syntaxTree().
+
generator(Pattern, Body) ->
tree(generator, #generator{pattern = Pattern, body = Body}).
@@ -4849,6 +5198,8 @@ revert_generator(Node) ->
%%
%% @see generator/2
+-spec generator_pattern(syntaxTree()) -> syntaxTree().
+
generator_pattern(Node) ->
case unwrap(Node) of
{generate, _, Pattern, _} ->
@@ -4865,6 +5216,8 @@ generator_pattern(Node) ->
%%
%% @see generator/2
+-spec generator_body(syntaxTree()) -> syntaxTree().
+
generator_body(Node) ->
case unwrap(Node) of
{generate, _, _, Body} ->
@@ -4886,7 +5239,7 @@ generator_body(Node) ->
%% @see list_comp/2
%% @see binary_comp/2
--record(binary_generator, {pattern, body}).
+-record(binary_generator, {pattern :: syntaxTree(), body :: syntaxTree()}).
%% type(Node) = binary_generator
%% data(Node) = #binary_generator{pattern :: Pattern, body :: Body}
@@ -4899,6 +5252,8 @@ generator_body(Node) ->
%%
%% Pattern = Body = erl_parse()
+-spec binary_generator(syntaxTree(), syntaxTree()) -> syntaxTree().
+
binary_generator(Pattern, Body) ->
tree(binary_generator, #binary_generator{pattern = Pattern, body = Body}).
@@ -4916,6 +5271,8 @@ revert_binary_generator(Node) ->
%%
%% @see binary_generator/2
+-spec binary_generator_pattern(syntaxTree()) -> syntaxTree().
+
binary_generator_pattern(Node) ->
case unwrap(Node) of
{b_generate, _, Pattern, _} ->
@@ -4932,6 +5289,8 @@ binary_generator_pattern(Node) ->
%%
%% @see binary_generator/2
+-spec binary_generator_body(syntaxTree()) -> syntaxTree().
+
binary_generator_body(Node) ->
case unwrap(Node) of
{b_generate, _, _, Body} ->
@@ -4940,6 +5299,7 @@ binary_generator_body(Node) ->
(data(Node1))#binary_generator.body
end.
+
%% =====================================================================
%% @spec block_expr(Body::[syntaxTree()]) -> syntaxTree()
%%
@@ -4960,6 +5320,8 @@ binary_generator_body(Node) ->
%%
%% Body = [erl_parse()] \ []
+-spec block_expr(Body::[syntaxTree()]) -> syntaxTree().
+
block_expr(Body) ->
tree(block_expr, Body).
@@ -4977,6 +5339,8 @@ revert_block_expr(Node) ->
%%
%% @see block_expr/1
+-spec block_expr_body(syntaxTree()) -> [syntaxTree()].
+
block_expr_body(Node) ->
case unwrap(Node) of
{block, _, Body} ->
@@ -5015,6 +5379,8 @@ block_expr_body(Node) ->
%%
%% See `clause' for documentation on `erl_parse' clauses.
+-spec if_expr([syntaxTree()]) -> syntaxTree().
+
if_expr(Clauses) ->
tree(if_expr, Clauses).
@@ -5032,6 +5398,8 @@ revert_if_expr(Node) ->
%%
%% @see if_expr/1
+-spec if_expr_clauses(syntaxTree()) -> [syntaxTree()].
+
if_expr_clauses(Node) ->
case unwrap(Node) of
{'if', _, Clauses} ->
@@ -5059,7 +5427,7 @@ if_expr_clauses(Node) ->
%% @see if_expr/1
%% @see cond_expr/1
--record(case_expr, {argument, clauses}).
+-record(case_expr, {argument :: syntaxTree(), clauses :: [syntaxTree()]}).
%% type(Node) = case_expr
%% data(Node) = #case_expr{argument :: Argument,
@@ -5078,6 +5446,8 @@ if_expr_clauses(Node) ->
%%
%% See `clause' for documentation on `erl_parse' clauses.
+-spec case_expr(syntaxTree(), [syntaxTree()]) -> syntaxTree().
+
case_expr(Argument, Clauses) ->
tree(case_expr, #case_expr{argument = Argument,
clauses = Clauses}).
@@ -5096,6 +5466,8 @@ revert_case_expr(Node) ->
%%
%% @see case_expr/2
+-spec case_expr_argument(syntaxTree()) -> syntaxTree().
+
case_expr_argument(Node) ->
case unwrap(Node) of
{'case', _, Argument, _} ->
@@ -5113,6 +5485,8 @@ case_expr_argument(Node) ->
%%
%% @see case_expr/2
+-spec case_expr_clauses(syntaxTree()) -> [syntaxTree()].
+
case_expr_clauses(Node) ->
case unwrap(Node) of
{'case', _, _, Clauses} ->
@@ -5151,6 +5525,8 @@ case_expr_clauses(Node) ->
%%
%% See `clause' for documentation on `erl_parse' clauses.
+-spec cond_expr([syntaxTree()]) -> syntaxTree().
+
cond_expr(Clauses) ->
tree(cond_expr, Clauses).
@@ -5168,6 +5544,8 @@ revert_cond_expr(Node) ->
%%
%% @see cond_expr/1
+-spec cond_expr_clauses(syntaxTree()) -> [syntaxTree()].
+
cond_expr_clauses(Node) ->
case unwrap(Node) of
{'cond', _, Clauses} ->
@@ -5181,6 +5559,8 @@ cond_expr_clauses(Node) ->
%% @spec receive_expr(Clauses) -> syntaxTree()
%% @equiv receive_expr(Clauses, none, [])
+-spec receive_expr([syntaxTree()]) -> syntaxTree().
+
receive_expr(Clauses) ->
receive_expr(Clauses, none, []).
@@ -5213,7 +5593,9 @@ receive_expr(Clauses) ->
%% @see clause/3
%% @see case_expr/2
--record(receive_expr, {clauses, timeout, action}).
+-record(receive_expr, {clauses :: [syntaxTree()],
+ timeout :: 'none' | syntaxTree(),
+ action :: [syntaxTree()]}).
%% type(Node) = receive_expr
%% data(Node) = #receive_expr{clauses :: Clauses,
@@ -5236,6 +5618,9 @@ receive_expr(Clauses) ->
%%
%% See `clause' for documentation on `erl_parse' clauses.
+-spec receive_expr([syntaxTree()], 'none' | syntaxTree(), [syntaxTree()]) ->
+ syntaxTree().
+
receive_expr(Clauses, Timeout, Action) ->
%% If `Timeout' is `none', we always replace the actual
%% `Action' argument with an empty list, since
@@ -5271,6 +5656,8 @@ revert_receive_expr(Node) ->
%%
%% @see receive_expr/3
+-spec receive_expr_clauses(syntaxTree()) -> [syntaxTree()].
+
receive_expr_clauses(Node) ->
case unwrap(Node) of
{'receive', _, Clauses} ->
@@ -5295,6 +5682,8 @@ receive_expr_clauses(Node) ->
%%
%% @see receive_expr/3
+-spec receive_expr_timeout(syntaxTree()) -> 'none' | syntaxTree().
+
receive_expr_timeout(Node) ->
case unwrap(Node) of
{'receive', _, _} ->
@@ -5316,6 +5705,8 @@ receive_expr_timeout(Node) ->
%%
%% @see receive_expr/3
+-spec receive_expr_action(syntaxTree()) -> [syntaxTree()].
+
receive_expr_action(Node) ->
case unwrap(Node) of
{'receive', _, _} ->
@@ -5332,6 +5723,8 @@ receive_expr_action(Node) ->
%% syntaxTree()
%% @equiv try_expr(Body, [], Handlers)
+-spec try_expr([syntaxTree()], [syntaxTree()]) -> syntaxTree().
+
try_expr(Body, Handlers) ->
try_expr(Body, [], Handlers).
@@ -5341,6 +5734,8 @@ try_expr(Body, Handlers) ->
%% Handlers::[syntaxTree()]) -> syntaxTree()
%% @equiv try_expr(Body, Clauses, Handlers, [])
+-spec try_expr([syntaxTree()], [syntaxTree()], [syntaxTree()]) -> syntaxTree().
+
try_expr(Body, Clauses, Handlers) ->
try_expr(Body, Clauses, Handlers, []).
@@ -5350,6 +5745,8 @@ try_expr(Body, Clauses, Handlers) ->
%% syntaxTree()
%% @equiv try_expr(Body, [], [], After)
+-spec try_after_expr([syntaxTree()], [syntaxTree()]) -> syntaxTree().
+
try_after_expr(Body, After) ->
try_expr(Body, [], [], After).
@@ -5391,7 +5788,10 @@ try_after_expr(Body, After) ->
%% @see class_qualifier/2
%% @see case_expr/2
--record(try_expr, {body, clauses, handlers, 'after'}).
+-record(try_expr, {body :: [syntaxTree()],
+ clauses :: [syntaxTree()],
+ handlers :: [syntaxTree()],
+ 'after' :: [syntaxTree()]}).
%% type(Node) = try_expr
%% data(Node) = #try_expr{body :: Body,
@@ -5414,6 +5814,9 @@ try_after_expr(Body, After) ->
%%
%% See `clause' for documentation on `erl_parse' clauses.
+-spec try_expr([syntaxTree()], [syntaxTree()],
+ [syntaxTree()], [syntaxTree()]) -> syntaxTree().
+
try_expr(Body, Clauses, Handlers, After) ->
tree(try_expr, #try_expr{body = Body,
clauses = Clauses,
@@ -5437,6 +5840,8 @@ revert_try_expr(Node) ->
%%
%% @see try_expr/4
+-spec try_expr_body(syntaxTree()) -> [syntaxTree()].
+
try_expr_body(Node) ->
case unwrap(Node) of
{'try', _, Body, _, _, _} ->
@@ -5456,6 +5861,8 @@ try_expr_body(Node) ->
%%
%% @see try_expr/4
+-spec try_expr_clauses(syntaxTree()) -> [syntaxTree()].
+
try_expr_clauses(Node) ->
case unwrap(Node) of
{'try', _, _, Clauses, _, _} ->
@@ -5473,6 +5880,8 @@ try_expr_clauses(Node) ->
%%
%% @see try_expr/4
+-spec try_expr_handlers(syntaxTree()) -> [syntaxTree()].
+
try_expr_handlers(Node) ->
case unwrap(Node) of
{'try', _, _, _, Handlers, _} ->
@@ -5490,6 +5899,8 @@ try_expr_handlers(Node) ->
%%
%% @see try_expr/4
+-spec try_expr_after(syntaxTree()) -> [syntaxTree()].
+
try_expr_after(Node) ->
case unwrap(Node) of
{'try', _, _, _, _, After} ->
@@ -5510,13 +5921,15 @@ try_expr_after(Node) ->
%% @see class_qualifier_body/1
%% @see try_expr/4
--record(class_qualifier, {class, body}).
+-record(class_qualifier, {class :: syntaxTree(), body :: syntaxTree()}).
%% type(Node) = class_qualifier
%% data(Node) = #class_qualifier{class :: Class, body :: Body}
%%
%% Class = Body = syntaxTree()
+-spec class_qualifier(syntaxTree(), syntaxTree()) -> syntaxTree().
+
class_qualifier(Class, Body) ->
tree(class_qualifier,
#class_qualifier{class = Class, body = Body}).
@@ -5530,6 +5943,8 @@ class_qualifier(Class, Body) ->
%%
%% @see class_qualifier/2
+-spec class_qualifier_argument(syntaxTree()) -> syntaxTree().
+
class_qualifier_argument(Node) ->
(data(Node))#class_qualifier.class.
@@ -5541,6 +5956,8 @@ class_qualifier_argument(Node) ->
%%
%% @see class_qualifier/2
+-spec class_qualifier_body(syntaxTree()) -> syntaxTree().
+
class_qualifier_body(Node) ->
(data(Node))#class_qualifier.body.
@@ -5559,6 +5976,8 @@ class_qualifier_body(Node) ->
%% @see implicit_fun/1
%% @see implicit_fun/3
+-spec implicit_fun(syntaxTree(), 'none' | syntaxTree()) -> syntaxTree().
+
implicit_fun(Name, none) ->
implicit_fun(Name);
implicit_fun(Name, Arity) ->
@@ -5580,6 +5999,9 @@ implicit_fun(Name, Arity) ->
%% @see implicit_fun/1
%% @see implicit_fun/2
+-spec implicit_fun('none' | syntaxTree(), syntaxTree(), syntaxTree()) ->
+ syntaxTree().
+
implicit_fun(none, Name, Arity) ->
implicit_fun(Name, Arity);
implicit_fun(Module, Name, Arity) ->
@@ -5610,7 +6032,9 @@ implicit_fun(Module, Name, Arity) ->
%%
%% Module = atom()
%% Name = atom()
-%% Arity = integer()
+%% Arity = arity()
+
+-spec implicit_fun(syntaxTree()) -> syntaxTree().
implicit_fun(Name) ->
tree(implicit_fun, Name).
@@ -5661,6 +6085,8 @@ revert_implicit_fun(Node) ->
%% @see arity_qualifier/2
%% @see module_qualifier/2
+-spec implicit_fun_name(syntaxTree()) -> syntaxTree().
+
implicit_fun_name(Node) ->
case unwrap(Node) of
{'fun', Pos, {function, Atom, Arity}} ->
@@ -5707,6 +6133,8 @@ implicit_fun_name(Node) ->
%%
%% See `clause' for documentation on `erl_parse' clauses.
+-spec fun_expr([syntaxTree()]) -> syntaxTree().
+
fun_expr(Clauses) ->
tree(fun_expr, Clauses).
@@ -5724,6 +6152,8 @@ revert_fun_expr(Node) ->
%%
%% @see fun_expr/1
+-spec fun_expr_clauses(syntaxTree()) -> [syntaxTree()].
+
fun_expr_clauses(Node) ->
case unwrap(Node) of
{'fun', _, {clauses, Clauses}} ->
@@ -5750,6 +6180,8 @@ fun_expr_clauses(Node) ->
%% @see clause/3
%% @see clause_patterns/1
+-spec fun_expr_arity(syntaxTree()) -> arity().
+
fun_expr_arity(Node) ->
length(clause_patterns(hd(fun_expr_clauses(Node)))).
@@ -5766,6 +6198,8 @@ fun_expr_arity(Node) ->
%% type(Node) = parentheses
%% data(Node) = syntaxTree()
+-spec parentheses(syntaxTree()) -> syntaxTree().
+
parentheses(Expr) ->
tree(parentheses, Expr).
@@ -5780,6 +6214,8 @@ revert_parentheses(Node) ->
%%
%% @see parentheses/1
+-spec parentheses_body(syntaxTree()) -> syntaxTree().
+
parentheses_body(Node) ->
data(Node).
@@ -5788,6 +6224,8 @@ parentheses_body(Node) ->
%% @spec macro(Name) -> syntaxTree()
%% @equiv macro(Name, none)
+-spec macro(syntaxTree()) -> syntaxTree().
+
macro(Name) ->
macro(Name, none).
@@ -5818,7 +6256,7 @@ macro(Name) ->
%% @see macro/1
%% @see text/1
--record(macro, {name, arguments}).
+-record(macro, {name :: syntaxTree(), arguments :: 'none' | [syntaxTree()]}).
%% type(Node) = macro
%% data(Node) = #macro{name :: Name, arguments :: Arguments}
@@ -5826,6 +6264,8 @@ macro(Name) ->
%% Name = syntaxTree()
%% Arguments = none | [syntaxTree()]
+-spec macro(syntaxTree(), 'none' | [syntaxTree()]) -> syntaxTree().
+
macro(Name, Arguments) ->
tree(macro, #macro{name = Name, arguments = Arguments}).
@@ -5837,6 +6277,8 @@ macro(Name, Arguments) ->
%%
%% @see macro/2
+-spec macro_name(syntaxTree()) -> syntaxTree().
+
macro_name(Node) ->
(data(Node))#macro.name.
@@ -5853,6 +6295,8 @@ macro_name(Node) ->
%%
%% @see macro/2
+-spec macro_arguments(syntaxTree()) -> 'none' | [syntaxTree()].
+
macro_arguments(Node) ->
(data(Node))#macro.arguments.
@@ -5871,6 +6315,8 @@ macro_arguments(Node) ->
%% @see concrete/1
%% @see is_literal/1
+-spec abstract(term()) -> syntaxTree().
+
abstract([H | T] = L) when is_integer(H) ->
case is_printable(L) of
true ->
@@ -5932,6 +6378,8 @@ abstract_tail(H, T) ->
%% @see is_literal/1
%% @see char/1
+-spec concrete(syntaxTree()) -> term().
+
concrete(Node) ->
case type(Node) of
atom ->
@@ -5978,7 +6426,7 @@ concrete_list([]) ->
%% =====================================================================
-%% @spec is_literal(Node::syntaxTree()) -> bool()
+%% @spec is_literal(Node::syntaxTree()) -> boolean()
%%
%% @doc Returns <code>true</code> if <code>Node</code> represents a
%% literal term, otherwise <code>false</code>. This function returns
@@ -5988,6 +6436,8 @@ concrete_list([]) ->
%% @see abstract/1
%% @see concrete/1
+-spec is_literal(syntaxTree()) -> boolean().
+
is_literal(T) ->
case type(T) of
atom ->
@@ -6031,6 +6481,8 @@ is_literal(T) ->
%% @see revert_forms/1
%% @see //stdlib/erl_parse
+-spec revert(syntaxTree()) -> syntaxTree().
+
revert(Node) ->
case is_tree(Node) of
false ->
@@ -6172,6 +6624,10 @@ revert_root(Node) ->
%% @see form_list/1
%% @see is_form/1
+-type forms() :: syntaxTree() | [syntaxTree()].
+
+%% -spec revert_forms(forms()) -> [erl_parse()].
+
revert_forms(L) when is_list(L) ->
revert_forms(form_list(L));
revert_forms(T) ->
@@ -6270,6 +6726,8 @@ revert_forms_1([]) ->
%% @see is_leaf/1
%% @see copy_attrs/2
+-spec subtrees(syntaxTree()) -> [[syntaxTree()]].
+
subtrees(T) ->
case is_leaf(T) of
true ->
@@ -6442,6 +6900,8 @@ subtrees(T) ->
%% @see copy_attrs/2
%% @see type/1
+-spec update_tree(syntaxTree(), [[syntaxTree()]]) -> syntaxTree().
+
update_tree(Node, Groups) ->
copy_attrs(Node, make_tree(type(Node), Groups)).
@@ -6471,6 +6931,8 @@ update_tree(Node, Groups) ->
%% @see is_leaf/1
%% @see copy_attrs/2
+-spec make_tree(atom(), [[syntaxTree()]]) -> syntaxTree().
+
make_tree(application, [[F], A]) -> application(F, A);
make_tree(arity_qualifier, [[N], [A]]) -> arity_qualifier(N, A);
make_tree(attribute, [[N]]) -> attribute(N);
@@ -6567,6 +7029,8 @@ make_tree(tuple, [E]) -> tuple(E).
%% @see type/1
%% @see get_ann/1
+-spec meta(syntaxTree()) -> syntaxTree().
+
meta(T) ->
%% First of all we check for metavariables:
case type(T) of
@@ -6693,6 +7157,8 @@ meta_call(F, As) ->
%% @spec tree(Type) -> syntaxTree()
%% @equiv tree(Type, [])
+-spec tree(atom()) -> syntaxTree().
+
tree(Type) ->
tree(Type, []).
@@ -6727,12 +7193,14 @@ tree(Type) ->
%% @see data/1
%% @see type/1
+-spec tree(atom(), term()) -> syntaxTree().
+
tree(Type, Data) ->
#tree{type = Type, data = Data}.
%% =====================================================================
-%% @spec is_tree(Tree::syntaxTree()) -> bool()
+%% @spec is_tree(Tree::syntaxTree()) -> boolean()
%%
%% @doc <em>For special purposes only</em>. Returns <code>true</code> if
%% <code>Tree</code> is an abstract syntax tree and <code>false</code>
@@ -6743,6 +7211,8 @@ tree(Type, Data) ->
%%
%% @see tree/2
+-spec is_tree(syntaxTree()) -> boolean().
+
is_tree(#tree{}) ->
true;
is_tree(_) ->
@@ -6759,6 +7229,8 @@ is_tree(_) ->
%%
%% @see tree/2
+-spec data(syntaxTree()) -> term().
+
data(#tree{data = D}) -> D;
data(T) -> erlang:error({badarg, T}).
@@ -6788,6 +7260,8 @@ data(T) -> erlang:error({badarg, T}).
%% trees. <em>Attaching a wrapper onto another wrapper structure is an
%% error</em>.</p>
+%%-spec wrap(erl_parse:parse_tree()) -> syntaxTree().
+
wrap(Node) ->
%% We assume that Node is an old-school `erl_parse' tree.
#wrapper{type = type(Node), attr = #attr{pos = get_pos(Node)},
@@ -6802,17 +7276,21 @@ wrap(Node) ->
%% <code>erl_parse</code> tree; otherwise it returns <code>Node</code>
%% itself.
+-spec unwrap(syntaxTree()) -> syntaxTree().
+
unwrap(#wrapper{tree = Node}) -> Node;
unwrap(Node) -> Node. % This could also be a new-form node.
%% =====================================================================
-%% @spec is_wrapper(Term::term()) -> bool()
+%% @spec is_wrapper(Term::term()) -> boolean()
%%
%% @doc Returns <code>true</code> if the argument is a wrapper
%% structure, otherwise <code>false</code>.
-ifndef(NO_UNUSED).
+-spec is_wrapper(term()) -> boolean().
+
is_wrapper(#wrapper{}) ->
true;
is_wrapper(_) ->
diff --git a/lib/syntax_tools/src/erl_syntax_lib.erl b/lib/syntax_tools/src/erl_syntax_lib.erl
index ccbf864c2a..5c4e074488 100644
--- a/lib/syntax_tools/src/erl_syntax_lib.erl
+++ b/lib/syntax_tools/src/erl_syntax_lib.erl
@@ -46,6 +46,9 @@
new_variable_names/2, new_variable_names/3, strip_comments/1,
to_comment/1, to_comment/2, to_comment/3, variables/1]).
+%% =====================================================================
+
+-type ordset(X) :: [X]. % XXX: TAKE ME OUT
%% =====================================================================
%% @spec map(Function, Tree::syntaxTree()) -> syntaxTree()
@@ -58,6 +61,9 @@
%%
%% @see map_subtrees/2
+-spec map(fun((erl_syntax:syntaxTree()) -> erl_syntax:syntaxTree()),
+ erl_syntax:syntaxTree()) -> erl_syntax:syntaxTree().
+
map(F, Tree) ->
case erl_syntax:subtrees(Tree) of
[] ->
@@ -81,6 +87,9 @@ map(F, Tree) ->
%%
%% @see map/2
+-spec map_subtrees(fun((erl_syntax:syntaxTree()) -> erl_syntax:syntaxTree()),
+ erl_syntax:syntaxTree()) -> erl_syntax:syntaxTree().
+
map_subtrees(F, Tree) ->
case erl_syntax:subtrees(Tree) of
[] ->
@@ -105,6 +114,9 @@ map_subtrees(F, Tree) ->
%% @see fold_subtrees/3
%% @see foldl_listlist/3
+-spec fold(fun((erl_syntax:syntaxTree(), term()) -> term()),
+ term(), erl_syntax:syntaxTree()) -> term().
+
fold(F, S, Tree) ->
case erl_syntax:subtrees(Tree) of
[] ->
@@ -137,6 +149,9 @@ fold_2(_, S, []) ->
%%
%% @see fold/3
+-spec fold_subtrees(fun((erl_syntax:syntaxTree(), term()) -> term()),
+ term(), erl_syntax:syntaxTree()) -> term().
+
fold_subtrees(F, S, Tree) ->
foldl_listlist(F, S, erl_syntax:subtrees(Tree)).
@@ -151,6 +166,9 @@ fold_subtrees(F, S, Tree) ->
%% @see fold/3
%% @see //stdlib/lists:foldl/3
+-spec foldl_listlist(fun((term(), term()) -> term()),
+ term(), [[term()]]) -> term().
+
foldl_listlist(F, S, [L | Ls]) ->
foldl_listlist(F, foldl(F, S, L), Ls);
foldl_listlist(_, S, []) ->
@@ -178,6 +196,9 @@ foldl(_, S, []) ->
%% @see map/2
%% @see fold/3
+-spec mapfold(fun((erl_syntax:syntaxTree(), term()) -> {erl_syntax:syntaxTree(), term()}),
+ term(), erl_syntax:syntaxTree()) -> {erl_syntax:syntaxTree(), term()}.
+
mapfold(F, S, Tree) ->
case erl_syntax:subtrees(Tree) of
[] ->
@@ -216,6 +237,11 @@ mapfold_2(_, S, []) ->
%%
%% @see mapfold/3
+-spec mapfold_subtrees(fun((erl_syntax:syntaxTree(), term()) ->
+ {erl_syntax:syntaxTree(), term()}),
+ term(), erl_syntax:syntaxTree()) ->
+ {erl_syntax:syntaxTree(), term()}.
+
mapfold_subtrees(F, S, Tree) ->
case erl_syntax:subtrees(Tree) of
[] ->
@@ -237,6 +263,9 @@ mapfold_subtrees(F, S, Tree) ->
%% The list of lists in the result has the same structure as the given
%% list of lists.
+-spec mapfoldl_listlist(fun((term(), term()) -> {term(), term()}),
+ term(), [[term()]]) -> {[[term()]], term()}.
+
mapfoldl_listlist(F, S, [L | Ls]) ->
{L1, S1} = mapfoldl(F, S, L),
{Ls1, S2} = mapfoldl_listlist(F, S1, Ls),
@@ -263,6 +292,8 @@ mapfoldl(_, S, []) ->
%%
%% @see //stdlib/sets
+-spec variables(erl_syntax:syntaxTree()) -> set().
+
variables(Tree) ->
variables(Tree, sets:new()).
@@ -316,6 +347,8 @@ default_variable_name(N) ->
%%
%% @see new_variable_name/2
+-spec new_variable_name(set()) -> atom().
+
new_variable_name(S) ->
new_variable_name(fun default_variable_name/1, S).
@@ -340,6 +373,8 @@ new_variable_name(S) ->
%% @see //stdlib/sets
%% @see //stdlib/random
+-spec new_variable_name(fun((integer()) -> atom()), set()) -> atom().
+
new_variable_name(F, S) ->
R = start_range(S),
new_variable_name(R, F, S).
@@ -388,6 +423,8 @@ generate(_Key, Range) ->
%%
%% @see new_variable_name/1
+-spec new_variable_names(integer(), set()) -> [atom()].
+
new_variable_names(N, S) ->
new_variable_names(N, fun default_variable_name/1, S).
@@ -402,6 +439,9 @@ new_variable_names(N, S) ->
%%
%% @see new_variable_name/2
+-spec new_variable_names(integer(), fun((integer()) -> atom()), set()) ->
+ [atom()].
+
new_variable_names(N, F, S) when is_integer(N) ->
R = start_range(S),
new_variable_names(N, [], R, F, S).
@@ -441,6 +481,9 @@ new_variable_names(0, Names, _, _, _) ->
%% @see annotate_bindings/1
%% @see //stdlib/ordsets
+-spec annotate_bindings(erl_syntax:syntaxTree(), ordset(atom())) ->
+ erl_syntax:syntaxTree().
+
annotate_bindings(Tree, Env) ->
{Tree1, _, _} = vann(Tree, Env),
Tree1.
@@ -457,6 +500,8 @@ annotate_bindings(Tree, Env) ->
%%
%% @see annotate_bindings/2
+-spec annotate_bindings(erl_syntax:syntaxTree()) -> erl_syntax:syntaxTree().
+
annotate_bindings(Tree) ->
As = erl_syntax:get_ann(Tree),
case lists:keyfind(env, 1, As) of
@@ -856,7 +901,7 @@ delete_binding_anns([]) ->
%% =====================================================================
-%% @spec is_fail_expr(Tree::syntaxTree()) -> bool()
+%% @spec is_fail_expr(Tree::syntaxTree()) -> boolean()
%%
%% @doc Returns `true' if `Tree' represents an
%% expression which never terminates normally. Note that the reverse
@@ -869,6 +914,8 @@ delete_binding_anns([]) ->
%% @see //erts/erlang:error/1
%% @see //erts/erlang:error/2
+-spec is_fail_expr(erl_syntax:syntaxTree()) -> boolean().
+
is_fail_expr(E) ->
case erl_syntax:type(E) of
application ->
@@ -1038,6 +1085,12 @@ is_fail_expr(E) ->
%% @see erl_syntax:error_marker_info/1
%% @see erl_syntax:warning_marker_info/1
+-type key() :: 'attributes' | 'errors' | 'exports' | 'functions' | 'imports'
+ | 'module' | 'records' | 'rules' | 'warnings'.
+-type info_pair() :: {key(), term()}.
+
+-spec analyze_forms(erl_syntax:forms()) -> [info_pair()].
+
analyze_forms(Forms) when is_list(Forms) ->
finfo_to_list(lists:foldl(fun collect_form/2, new_finfo(), Forms));
analyze_forms(Forms) ->
@@ -1204,6 +1257,8 @@ list_value(List) ->
%% @see erl_syntax:error_marker_info/1
%% @see erl_syntax:warning_marker_info/1
+-spec analyze_form(erl_syntax:syntaxTree()) -> {atom(), term()} | atom().
+
analyze_form(Node) ->
case erl_syntax:type(Node) of
attribute ->
@@ -1276,6 +1331,9 @@ analyze_form(Node) ->
%% @see analyze_record_attribute/1
%% @see analyze_wild_attribute/1
+-spec analyze_attribute(erl_syntax:syntaxTree()) ->
+ 'preprocessor' | {atom(), term()}. % XXX: underspecified
+
analyze_attribute(Node) ->
Name = erl_syntax:attribute_name(Node),
case erl_syntax:type(Name) of
@@ -1326,12 +1384,14 @@ analyze_attribute(_, Node) ->
%% containing the module name and a list of the parameter variable
%% names.
%%
-%% The evaluation throws `syntax_error' if
-%% `Node' does not represent a well-formed module
-%% attribute.
+%% The evaluation throws `syntax_error' if `Node' does not represent a
+%% well-formed module attribute.
%%
%% @see analyze_attribute/1
+-spec analyze_module_attribute(erl_syntax:syntaxTree()) ->
+ atom() | {atom(), [atom()]}.
+
analyze_module_attribute(Node) ->
case erl_syntax:type(Node) of
attribute ->
@@ -1370,12 +1430,16 @@ analyze_variable_list(Node) ->
%% attribute. We do not guarantee that each name occurs at most once in
%% the list. The order of listing is not defined.
%%
-%% The evaluation throws `syntax_error' if
-%% `Node' does not represent a well-formed export
-%% attribute.
+%% The evaluation throws `syntax_error' if `Node' does not represent a
+%% well-formed export attribute.
%%
%% @see analyze_attribute/1
+-type functionN() :: atom() | {atom(), arity()}.
+-type functionName() :: functionN() | {atom(), functionN()}.
+
+-spec analyze_export_attribute(erl_syntax:syntaxTree()) -> [functionName()].
+
analyze_export_attribute(Node) ->
case erl_syntax:type(Node) of
attribute ->
@@ -1416,6 +1480,8 @@ analyze_function_name_list(Node) ->
%% The evaluation throws `syntax_error' if
%% `Node' does not represent a well-formed function name.
+-spec analyze_function_name(erl_syntax:syntaxTree()) -> functionName().
+
analyze_function_name(Node) ->
case erl_syntax:type(Node) of
atom ->
@@ -1470,12 +1536,14 @@ append_arity(_A, Name) ->
%% that each name occurs at most once in `Names'. The order
%% of listing is not defined.
%%
-%% The evaluation throws `syntax_error' if
-%% `Node' does not represent a well-formed import
-%% attribute.
+%% The evaluation throws `syntax_error' if `Node' does not represent a
+%% well-formed import attribute.
%%
%% @see analyze_attribute/1
+-spec analyze_import_attribute(erl_syntax:syntaxTree()) ->
+ {atom(), [functionName()]} | atom().
+
analyze_import_attribute(Node) ->
case erl_syntax:type(Node) of
attribute ->
@@ -1498,19 +1566,19 @@ analyze_import_attribute(Node) ->
%% @spec analyze_wild_attribute(Node::syntaxTree()) -> {atom(), term()}
%%
%% @doc Returns the name and value of a "wild" attribute. The result is
-%% the pair `{Name, Value}', if `Node' represents
-%% "`-Name(Value)'".
+%% the pair `{Name, Value}', if `Node' represents "`-Name(Value)'".
%%
%% Note that no checking is done whether `Name' is a
%% reserved attribute name such as `module' or
%% `export': it is assumed that the attribute is "wild".
%%
-%% The evaluation throws `syntax_error' if
-%% `Node' does not represent a well-formed wild
-%% attribute.
+%% The evaluation throws `syntax_error' if `Node' does not represent a
+%% well-formed wild attribute.
%%
%% @see analyze_attribute/1
+-spec analyze_wild_attribute(erl_syntax:syntaxTree()) -> {atom(), term()}.
+
analyze_wild_attribute(Node) ->
case erl_syntax:type(Node) of
attribute ->
@@ -1559,6 +1627,10 @@ analyze_wild_attribute(Node) ->
%% @see analyze_attribute/1
%% @see analyze_record_field/1
+-type fields() :: [{atom(), 'none' | erl_syntax:syntaxTree()}].
+
+-spec analyze_record_attribute(erl_syntax:syntaxTree()) -> {atom(), fields()}.
+
analyze_record_attribute(Node) ->
case erl_syntax:type(Node) of
attribute ->
@@ -1629,6 +1701,11 @@ analyze_record_attribute_tuple(Node) ->
%% @see analyze_record_attribute/1
%% @see analyze_record_field/1
+-type info() :: {atom(), [{atom(), 'none' | erl_syntax:syntaxTree()}]}
+ | {atom(), atom()} | atom().
+
+-spec analyze_record_expr(erl_syntax:syntaxTree()) -> {atom(), info()} | atom().
+
analyze_record_expr(Node) ->
case erl_syntax:type(Node) of
record_expr ->
@@ -1700,6 +1777,9 @@ analyze_record_expr(Node) ->
%% @see analyze_record_attribute/1
%% @see analyze_record_expr/1
+-spec analyze_record_field(erl_syntax:syntaxTree()) ->
+ {atom(), 'none' | erl_syntax:syntaxTree()}.
+
analyze_record_field(Node) ->
case erl_syntax:type(Node) of
record_field ->
@@ -1730,6 +1810,8 @@ analyze_record_field(Node) ->
%%
%% @see analyze_attribute/1
+-spec analyze_file_attribute(erl_syntax:syntaxTree()) -> {string(), integer()}.
+
analyze_file_attribute(Node) ->
case erl_syntax:type(Node) of
attribute ->
@@ -1765,6 +1847,8 @@ analyze_file_attribute(Node) ->
%%
%% @see analyze_rule/1
+-spec analyze_function(erl_syntax:syntaxTree()) -> {atom(), arity()}.
+
analyze_function(Node) ->
case erl_syntax:type(Node) of
function ->
@@ -1794,6 +1878,8 @@ analyze_function(Node) ->
%%
%% @see analyze_function/1
+-spec analyze_rule(erl_syntax:syntaxTree()) -> {atom(), arity()}.
+
analyze_rule(Node) ->
case erl_syntax:type(Node) of
rule ->
@@ -1826,11 +1912,12 @@ analyze_rule(Node) ->
%%
%% @see analyze_function_name/1
+-spec analyze_implicit_fun(erl_syntax:syntaxTree()) -> functionName().
+
analyze_implicit_fun(Node) ->
case erl_syntax:type(Node) of
implicit_fun ->
- analyze_function_name(
- erl_syntax:implicit_fun_name(Node));
+ analyze_function_name(erl_syntax:implicit_fun_name(Node));
_ ->
throw(syntax_error)
end.
@@ -1851,12 +1938,15 @@ analyze_implicit_fun(Node) ->
%% function is not explicitly named (i.e., `F' is given by
%% some expression), only the arity `A' is returned.
%%
-%% The evaluation throws `syntax_error' if
-%% `Node' does not represent a well-formed application
-%% expression.
+%% The evaluation throws `syntax_error' if `Node' does not represent a
+%% well-formed application expression.
%%
%% @see analyze_function_name/1
+-type appFunName() :: {atom(), arity()} | {atom(), {atom(), arity()}}.
+
+-spec analyze_application(erl_syntax:syntaxTree()) -> appFunName() | arity().
+
analyze_application(Node) ->
case erl_syntax:type(Node) of
application ->
@@ -1897,6 +1987,11 @@ analyze_application(Node) ->
%%
%% @see analyze_function_name/1
+-type shortname() :: atom() | {atom(), arity()}.
+-type name() :: shortname() | {atom(), shortname()}.
+
+-spec function_name_expansions([name()]) -> [{shortname(), name()}].
+
function_name_expansions(Fs) ->
function_name_expansions(Fs, []).
@@ -1922,6 +2017,8 @@ function_name_expansions(A, Name, Ack) ->
%% Standalone comments in form lists are removed; any other standalone
%% comments are changed into null-comments (no text, no indentation).
+-spec strip_comments(erl_syntax:syntaxTree()) -> erl_syntax:syntaxTree().
+
strip_comments(Tree) ->
map(fun strip_comments_1/1, Tree).
@@ -1942,6 +2039,8 @@ strip_comments_1(T) ->
%% @spec to_comment(Tree) -> syntaxTree()
%% @equiv to_comment(Tree, "% ")
+-spec to_comment(erl_syntax:syntaxTree()) -> erl_syntax:syntaxTree().
+
to_comment(Tree) ->
to_comment(Tree, "% ").
@@ -1956,6 +2055,8 @@ to_comment(Tree) ->
%% @see to_comment/3
%% @see erl_prettypr:format/1
+-spec to_comment(erl_syntax:syntaxTree(), string()) -> erl_syntax:syntaxTree().
+
to_comment(Tree, Prefix) ->
F = fun (T) -> erl_prettypr:format(T) end,
to_comment(Tree, Prefix, F).
@@ -1985,6 +2086,10 @@ to_comment(Tree, Prefix) ->
%% @see to_comment/1
%% @see to_comment/2
+-spec to_comment(erl_syntax:syntaxTree(), string(),
+ fun((erl_syntax:syntaxTree()) -> string())) ->
+ erl_syntax:syntaxTree().
+
to_comment(Tree, Prefix, F) ->
erl_syntax:comment(split_lines(F(Tree), Prefix)).
@@ -1998,6 +2103,8 @@ to_comment(Tree, Prefix, F) ->
%% @see limit/3
%% @see erl_syntax:text/1
+-spec limit(erl_syntax:syntaxTree(), integer()) -> erl_syntax:syntaxTree().
+
limit(Tree, Depth) ->
limit(Tree, Depth, erl_syntax:text("...")).
@@ -2026,6 +2133,9 @@ limit(Tree, Depth) ->
%%
%% @see limit/2
+-spec limit(erl_syntax:syntaxTree(), integer(), erl_syntax:syntaxTree()) ->
+ erl_syntax:syntaxTree().
+
limit(_Tree, Depth, Node) when Depth < 0 ->
Node;
limit(Tree, Depth, Node) ->
diff --git a/lib/syntax_tools/src/erl_tidy.erl b/lib/syntax_tools/src/erl_tidy.erl
index e3b479008f..021ab18736 100644
--- a/lib/syntax_tools/src/erl_tidy.erl
+++ b/lib/syntax_tools/src/erl_tidy.erl
@@ -66,6 +66,7 @@ dir__defaults() ->
%% @equiv dir("")
-spec dir() -> 'ok'.
+
dir() ->
dir("").
@@ -74,6 +75,7 @@ dir() ->
%% @equiv dir(Dir, [])
-spec dir(file:filename()) -> 'ok'.
+
dir(Dir) ->
dir(Dir, []).
@@ -130,6 +132,7 @@ dir(Dir) ->
options :: options()}).
-spec dir(file:filename(), options()) -> 'ok'.
+
dir(Dir, Opts) ->
Opts1 = Opts ++ dir__defaults(),
Env = #dir{follow_links = proplists:get_bool(follow_links, Opts1),
@@ -212,6 +215,7 @@ default_printer() ->
%% @equiv file(Name, [])
-spec file(file:filename()) -> 'ok'.
+
file(Name) ->
file(Name, []).
@@ -275,6 +279,7 @@ file(Name) ->
%% @see module/2
-spec file(file:filename(), options()) -> 'ok'.
+
file(Name, Opts) ->
Parent = self(),
Child = spawn_link(fun () -> file_1(Parent, Name, Opts) end),
@@ -478,11 +483,12 @@ backup_file_1(Name, Opts) ->
throw(R)
end.
-
%% =====================================================================
%% @spec module(Forms) -> syntaxTree()
%% @equiv module(Forms, [])
+-spec module(erl_syntax:forms()) -> erl_syntax:syntaxTree().
+
module(Forms) ->
module(Forms, []).
@@ -609,6 +615,8 @@ module(Forms) ->
%%
%% </dl>
+-spec module(erl_syntax:forms(), [term()]) -> erl_syntax:syntaxTree().
+
module(Forms, Opts) when is_list(Forms) ->
module(erl_syntax:form_list(Forms), Opts);
module(Forms, Opts) ->
@@ -668,11 +676,8 @@ analyze_forms(Forms, File) ->
throw(R)
end.
-%% XXX: The following should be imported from erl_syntax_lib
--type key() :: atom().
--type info_pair() :: {key(), any()}.
+-spec get_module_name([erl_syntax_lib:info_pair()], string()) -> atom().
--spec get_module_name([info_pair()], string()) -> atom().
get_module_name(List, File) ->
case lists:keyfind(module, 1, List) of
{module, M} ->
@@ -691,7 +696,8 @@ get_module_attributes(List) ->
[]
end.
--spec get_module_exports([info_pair()]) -> [{atom(), byte()}].
+-spec get_module_exports([erl_syntax_lib:info_pair()]) -> [{atom(), arity()}].
+
get_module_exports(List) ->
case lists:keyfind(exports, 1, List) of
{exports, Es} ->
@@ -700,7 +706,8 @@ get_module_exports(List) ->
[]
end.
--spec get_module_imports([info_pair()]) -> [{atom(), atom()}].
+-spec get_module_imports([erl_syntax_lib:info_pair()]) -> [{atom(), atom()}].
+
get_module_imports(List) ->
case lists:keyfind(imports, 1, List) of
{imports, Is} ->
@@ -714,6 +721,7 @@ compile_attrs(As) ->
|| {compile, T} <- As]).
-spec flatten_imports([{atom(), [atom()]}]) -> [{atom(), atom()}].
+
flatten_imports(Is) ->
[{F, M} || {M, Fs} <- Is, F <- Fs].
@@ -736,7 +744,8 @@ check_imports(Is, Opts, File) ->
end.
-spec check_imports_1([{atom(), atom()}]) -> boolean().
-check_imports_1([{F1, M1}, {F2, M2} | _Is]) when F1 =:= F2, M1 =/= M2 ->
+
+check_imports_1([{F, M1}, {F, M2} | _Is]) when M1 =/= M2 ->
false;
check_imports_1([_ | Is]) ->
check_imports_1(Is);
@@ -1629,6 +1638,7 @@ rename_remote_call(F, St) ->
end.
-spec rename_remote_call_1(mfa()) -> {atom(), atom()} | 'false'.
+
rename_remote_call_1({dict, dict_to_list, 1}) -> {dict, to_list};
rename_remote_call_1({dict, list_to_dict, 1}) -> {dict, from_list};
rename_remote_call_1({erl_eval, arg_list, 2}) -> {erl_eval, expr_list};
@@ -1662,7 +1672,8 @@ rename_remote_call_1({string, index, 2}) -> {string, str};
rename_remote_call_1({unix, cmd, 1}) -> {os, cmd};
rename_remote_call_1(_) -> false.
--spec rewrite_guard_test(atom(), byte()) -> atom().
+-spec rewrite_guard_test(atom(), arity()) -> atom().
+
rewrite_guard_test(atom, 1) -> is_atom;
rewrite_guard_test(binary, 1) -> is_binary;
rewrite_guard_test(constant, 1) -> is_constant;
@@ -1680,7 +1691,8 @@ rewrite_guard_test(record, 2) -> is_record;
rewrite_guard_test(record, 3) -> is_record;
rewrite_guard_test(N, _A) -> N.
--spec reverse_guard_test(atom(), byte()) -> atom().
+-spec reverse_guard_test(atom(), arity()) -> atom().
+
reverse_guard_test(is_atom, 1) -> atom;
reverse_guard_test(is_binary, 1) -> binary;
reverse_guard_test(is_constant, 1) -> constant;
diff --git a/lib/syntax_tools/src/igor.erl b/lib/syntax_tools/src/igor.erl
index 9e7b784170..e92e9593b6 100644
--- a/lib/syntax_tools/src/igor.erl
+++ b/lib/syntax_tools/src/igor.erl
@@ -117,20 +117,23 @@
-define(record_name(R), {record, R}).
+%% =====================================================================
+
+-type ordset(X) :: [X]. % XXX: TAKE ME OUT
+
+%% =====================================================================
%% Data structure for module information
--record(module, {name, % = atom()
- vars = none, % = [atom()] | none
- functions, % = ordset({atom(), int()})
- exports, % = ordset({atom(), int()})
- % | ordset({{atom(), int()},
- % term()})
- aliases, % = ordset({{atom(), int()},
- % {atom(),
- % {atom(), int()}}})
- attributes, % = ordset({atom(), term()})
- records % = [{atom(), [{atom(), term()}]}]
+-record(module, {name :: atom(),
+ vars = none :: [atom()] | 'none',
+ functions :: ordset({atom(), arity()}),
+ exports :: ordset({atom(), arity()})
+ | ordset({{atom(), arity()}, term()}),
+ aliases :: ordset({{atom(), arity()},
+ {atom(), {atom(), arity()}}}),
+ attributes :: ordset({atom(), term()}),
+ records :: [{atom(), [{atom(), term()}]}]
}).
%% The default pretty-printing function.
@@ -138,6 +141,17 @@
default_printer(Tree, Options) ->
erl_prettypr:format(Tree, Options).
+%% =====================================================================
+
+-type option() :: atom() | {atom(), term()}.
+
+-type attribute() :: {atom(), term()}.
+-type moduleName() :: atom().
+-type functionName() :: {atom(), arity()}.
+-type functionPair() :: {functionName(), {moduleName(), functionName()}}.
+-type stubDescriptor() :: [{moduleName(), [functionPair()], [attribute()]}].
+
+-type notes() :: 'always' | 'yes' | 'no'.
%% =====================================================================
%% @spec parse_transform(Forms::[syntaxTree()], Options::[term()]) ->
@@ -169,6 +183,9 @@ default_printer(Tree, Options) ->
%% @see merge_files/4
%% @see //compiler/compile:file/2
+-spec parse_transform(erl_syntax:forms(), [option()]) ->
+ [erl_syntax:syntaxTree()].
+
parse_transform(Forms, Options) ->
M = get_module_info(Forms),
Name = M#module.name,
@@ -192,6 +209,8 @@ parse_transform(Forms, Options) ->
%% @spec merge(Name::atom(), Files::[filename()]) -> [filename()]
%% @equiv merge(Name, Files, [])
+-spec merge(atom(), [file:filename()]) -> [file:filename()].
+
merge(Name, Files) ->
merge(Name, Files, []).
@@ -251,7 +270,7 @@ merge(Name, Files) ->
%% <dd>Specifies the file name suffix to be used when a backup file
%% is created; the default value is `".bak"'.</dd>
%%
-%% <dt>`{backups, bool()}'</dt>
+%% <dt>`{backups, boolean()}'</dt>
%%
%% <dd>If the value is `true', existing files will be
%% renamed before new files are opened for writing. The new names
@@ -271,7 +290,7 @@ merge(Name, Files) ->
%% resulting source code is to be written. By default, this is the
%% same as the `Name' argument.</dd>
%%
-%% <dt>`{preprocess, bool()}'</dt>
+%% <dt>`{preprocess, boolean()}'</dt>
%%
%% <dd>If the value is `true', preprocessing will be done
%% when reading the source code. See `merge_files/4' for
@@ -294,7 +313,7 @@ merge(Name, Files) ->
%% stub module files are written. The default value is
%% `"stubs"'.</dd>
%%
-%% <dt>`{stubs, bool()}'</dt>
+%% <dt>`{stubs, boolean()}'</dt>
%%
%% <dd>If the value is `true', stub module files will be
%% automatically generated for all exported modules that do not have
@@ -324,6 +343,8 @@ merge(Name, Files) ->
{suffix, ?DEFAULT_SUFFIX},
{verbose, false}]).
+-spec merge(atom(), [file:filename()], [option()]) -> [file:filename()].
+
merge(Name, Files, Opts) ->
Opts1 = Opts ++ ?DEFAULT_MERGE_OPTS,
{Tree, Stubs} = merge_files(Name, Files, Opts1),
@@ -339,6 +360,9 @@ merge(Name, Files, Opts) ->
%% {syntaxTree(), [stubDescriptor()]}
%% @equiv merge_files(Name, [], Files, Options)
+-spec merge_files(atom(), [file:filename()], [option()]) ->
+ {erl_syntax:syntaxTree(), [stubDescriptor()]}.
+
merge_files(Name, Files, Options) ->
merge_files(Name, [], Files, Options).
@@ -380,7 +404,7 @@ merge_files(Name, Files, Options) ->
%%
%% Options:
%% <dl>
-%% <dt>`{comments, bool()}'</dt>
+%% <dt>`{comments, boolean()}'</dt>
%%
%% <dd>If the value is `true', source code comments in
%% the original files will be preserved in the output. The default
@@ -409,7 +433,7 @@ merge_files(Name, Files, Options) ->
%% Erlang preprocessor, if used (cf. the `preprocess'
%% option). The default value is the empty list.</dd>
%%
-%% <dt>`{preprocess, bool()}'</dt>
+%% <dt>`{preprocess, boolean()}'</dt>
%%
%% <dd>If the value is `false', Igor will read source
%% files without passing them through the Erlang preprocessor
@@ -438,6 +462,9 @@ merge_files(Name, Files, Options) ->
%% @see //stdlib/filename:find_src/2
%% @see epp_dodger
+-spec merge_files(atom(), erl_syntax:forms(), [file:filename()], [option()]) ->
+ {erl_syntax:syntaxTree(), [stubDescriptor()]}.
+
merge_files(_, _Trees, [], _) ->
report_error("no files to merge."),
exit(badarg);
@@ -512,7 +539,7 @@ merge_files(Name, Trees, Files, Opts) ->
%% `Sources' will be exported. The default value is the
%% empty list.</dd>
%%
-%% <dt>`{export_all, bool()}'</dt>
+%% <dt>`{export_all, boolean()}'</dt>
%%
%% <dd>If the value is `true', this is equivalent to
%% listing all of the input modules in the `export'
@@ -532,7 +559,7 @@ merge_files(Name, Trees, Files, Opts) ->
%% they will be handled as in the `comment' case. The
%% default value is `no'.</dd>
%%
-%% <dt>`{no_banner, bool()}'</dt>
+%% <dt>`{no_banner, boolean()}'</dt>
%%
%% <dd>If the value is `true', no banner comment will be
%% added at the top of the resulting module, even if the target
@@ -541,7 +568,7 @@ merge_files(Name, Trees, Files, Opts) ->
%% code is at the top of the output. The default value is
%% `false'.</dd>
%%
-%% <dt>`{no_headers, bool()}'</dt>
+%% <dt>`{no_headers, boolean()}'</dt>
%%
%% <dd>If the value is `true', no header comments will be
%% added to the resulting module at the beginning of each section of
@@ -550,7 +577,7 @@ merge_files(Name, Trees, Files, Opts) ->
%% normally added whenever more than two or more modules are
%% merged.</dd>
%%
-%% <dt>`{no_imports, bool()}'</dt>
+%% <dt>`{no_imports, boolean()}'</dt>
%%
%% <dd>If the value is `true', all
%% `-import(...)' declarations in the original code will
@@ -599,7 +626,7 @@ merge_files(Name, Trees, Files, Opts) ->
%% regarded as "static", regardless of the value of this option. By
%% default, all involved modules are assumed to be static.</dd>
%%
-%% <dt>`{tidy, bool()}'</dt>
+%% <dt>`{tidy, boolean()}'</dt>
%%
%% <dd>If the value is `true', the resulting code will be
%% processed using the `erl_tidy' module, which removes
@@ -607,7 +634,7 @@ merge_files(Name, Trees, Files, Opts) ->
%% `erl_tidy:module/2' for additional options.) The
%% default value is `true'.</dd>
%%
-%% <dt>`{verbose, bool()}'</dt>
+%% <dt>`{verbose, boolean()}'</dt>
%%
%% <dd>If the value is `true', progress messages will be
%% output while the program is running; the default value is
@@ -659,19 +686,22 @@ merge_files(Name, Trees, Files, Opts) ->
%% Data structure for merging environment.
--record(merge, {target, % = atom()
- sources, % = ordset(atom())
- export, % = ordset(atom())
- static, % = ordset(atom())
- safe, % = ordset(atom())
- preserved, % = bool()
- no_headers, % = bool()
- notes, % = bool()
- redirect, % = dict(atom(), atom())
- no_imports, % = ordset(atom())
- options % = [term()]
+-record(merge, {target :: atom(),
+ sources :: ordset(atom()),
+ export :: ordset(atom()),
+ static :: ordset(atom()),
+ safe :: ordset(atom()),
+ preserved :: boolean(),
+ no_headers :: boolean(),
+ notes :: notes(),
+ redirect :: dict(), % = dict(atom(), atom())
+ no_imports :: ordset(atom()),
+ options :: [option()]
}).
+-spec merge_sources(atom(), erl_syntax:forms(), [option()]) ->
+ {erl_syntax:syntaxTree(), [stubDescriptor()]}.
+
merge_sources(Name, Sources, Opts) ->
%% Prepare the options and the inputs.
Opts1 = Opts ++ [{export_all, false},
@@ -696,7 +726,7 @@ merge_sources(Name, Sources, Opts) ->
%% Data structure for keeping state during transformation.
--record(state, {export}).
+-record(state, {export :: set()}).
state__add_export(Name, Arity, S) ->
S#state{export = sets:add_element({Name, Arity},
@@ -981,7 +1011,7 @@ make_stubs(Modules, Renaming, Env) ->
make_stubs_1([M | Ms], Renaming, Env) ->
Name = M#module.name,
- if Name /= Env#merge.target ->
+ if Name =/= Env#merge.target ->
case ordsets:is_element(Name, Env#merge.export) of
true ->
[make_stub(M, Renaming(Name), Env)
@@ -1005,7 +1035,7 @@ make_stub(M, Map, Env) ->
%% Removing and/or out-commenting program forms. The returned form
%% sequence tree is not necessarily flat.
--record(filter, {records, file_attributes, attributes}).
+-record(filter, {records :: set(), file_attributes, attributes}).
filter_forms(Tree, Env) ->
Forms = erl_syntax:form_list_elements(
@@ -1098,8 +1128,7 @@ filter_form(F, S) ->
kill_form(F) ->
F1 = erl_syntax:set_precomments(F, []),
F2 = erl_syntax_lib:to_comment(F1, ?KILL_PREFIX),
- erl_syntax:set_precomments(F2,
- erl_syntax:get_precomments(F)).
+ erl_syntax:set_precomments(F2, erl_syntax:get_precomments(F)).
%% ---------------------------------------------------------------------
@@ -1138,8 +1167,7 @@ merge_namespaces(Modules, Env) ->
[] ->
ok;
Fs ->
- report_warning("interface functions renamed:\n\t~p.",
- [Fs])
+ report_warning("interface functions renamed:\n\t~p.", [Fs])
end,
{M4, Acc2} = merge_namespaces_1(M2, Acc1),
Ms = M3 ++ M4,
@@ -1550,20 +1578,20 @@ alias_expansions_2(Modules, Table) ->
%% Data structure for code transformation environment.
--record(code, {module, % = atom()
- target, % = atom()
- sources, % = ordset(atom())
- static, % = ordset(atom())
- safe, % = ordset(atom())
- preserved, % = bool()
- no_headers, % = bool()
- notes, % = bool()
+-record(code, {module :: atom(),
+ target :: atom(),
+ sources :: set(), % set(atom()),
+ static :: set(), % set(atom()),
+ safe :: set(), % set(atom()),
+ preserved :: boolean(),
+ no_headers :: boolean(),
+ notes :: notes(),
map, % = ({atom(), int()}) -> {atom(), int()}
renaming, % = (atom()) -> ({atom(), int()}) ->
% {atom(), int()}
- expand, % = dict({atom(), int()},
- % {atom(), {atom(), int()}})
- redirect % = dict(atom(), atom())
+ expand :: dict(), % = dict({atom(), int()},
+ % {atom(), {atom(), int()}})
+ redirect :: dict() % = dict(atom(), atom())
}).
%% `Trees' must be a list of syntax trees of type `form_list'. The
@@ -1657,8 +1685,8 @@ take_header_1([F | Fs], As) ->
section_header(Name, Tree, Env) ->
N = sets:size(Env#code.sources),
- if N > 1, Name /= Env#code.target, Env#code.notes /= no,
- Env#code.no_headers /= true ->
+ if N > 1, Name =/= Env#code.target, Env#code.notes =/= no,
+ Env#code.no_headers =/= true ->
Text = io_lib:fwrite("The following code stems "
"from module `~w'.", [Name]),
Header = comment([?COMMENT_BAR, "",
@@ -2292,11 +2320,11 @@ maybe_modified_1({value, Node1}, Node, Depth, Message, Notes) ->
%% Options:
%% <dl>
%% <dt>`{backup_suffix, string()}'</dt>
-%% <dt>`{backups, bool()}'</dt>
+%% <dt>`{backups, boolean()}'</dt>
%% <dt>`{printer, Function}'</dt>
%% <dt>`{stub_dir, filename()}'</dt>
%% <dt>`{suffix, string()}'</dt>
-%% <dt>`{verbose, bool()}'</dt>
+%% <dt>`{verbose, boolean()}'</dt>
%% </dl>
%%
%% See `merge/3' for details on these options.
@@ -2304,6 +2332,8 @@ maybe_modified_1({value, Node1}, Node, Depth, Message, Notes) ->
%% @see merge/3
%% @see merge_sources/3
+-spec create_stubs([stubDescriptor()], [option()]) -> [string()].
+
create_stubs(Stubs, Opts) ->
Opts1 = Opts ++ ?DEFAULT_MERGE_OPTS,
lists:foldl(fun (S, Fs) ->
@@ -2365,9 +2395,15 @@ stub_header(Name, Exports, Attrs) ->
%% =====================================================================
+
+-type renamings() :: [{atom(), atom()}].
+
+%% =====================================================================
%% @spec rename(Files::[filename()], Renamings) -> [string()]
%% @equiv rename(Files, Renamings, [])
+-spec rename([file:filename()], renamings()) -> [string()].
+
rename(Files, Renamings) ->
rename(Files, Renamings, []).
@@ -2408,35 +2444,35 @@ rename(Files, Renamings) ->
%% Options:
%% <dl>
%% <dt>`{backup_suffix, string()}'</dt>
-%% <dt>`{backups, bool()}'</dt>
+%% <dt>`{backups, boolean()}'</dt>
%% <dt>`{printer, Function}'</dt>
-%% <dt>`{stubs, bool()}'</dt>
+%% <dt>`{stubs, boolean()}'</dt>
%% <dt>`{suffix, string()}'</dt>
%% </dl>
%% See `merge/3' for details on these options.
%%
%% <dl>
-%% <dt>`{comments, bool()}'</dt>
-%% <dt>`{preprocess, bool()}'</dt>
+%% <dt>`{comments, boolean()}'</dt>
+%% <dt>`{preprocess, boolean()}'</dt>
%% </dl>
%% See `merge_files/4' for details on these options.
%%
%% <dl>
-%% <dt>`{no_banner, bool()}'</dt>
+%% <dt>`{no_banner, boolean()}'</dt>
%% </dl>
%% For the `rename' function, this option is
%% `true' by default. See `merge_sources/3' for
%% details.
%%
%% <dl>
-%% <dt>`{tidy, bool()}'</dt>
+%% <dt>`{tidy, boolean()}'</dt>
%% </dl>
%% For the `rename' function, this option is
%% `false' by default. See `merge_sources/3' for
%% details.
%%
%% <dl>
-%% <dt>`{no_headers, bool()}'</dt>
+%% <dt>`{no_headers, boolean()}'</dt>
%% <dt>`{stub_dir, filename()}'</dt>
%% </dl>
%% These options are preset by the `rename' function and
@@ -2448,6 +2484,8 @@ rename(Files, Renamings) ->
%% @see merge_sources/3
%% @see merge_files/4
+-spec rename([file:filename()], renamings(), [term()]) -> [string()].
+
rename(Files, Renamings, Opts) ->
Dict = case is_atom_map(Renamings) of
true ->
diff --git a/lib/syntax_tools/src/prettypr.erl b/lib/syntax_tools/src/prettypr.erl
index 4dd95a2b08..1868f63e54 100644
--- a/lib/syntax_tools/src/prettypr.erl
+++ b/lib/syntax_tools/src/prettypr.erl
@@ -50,29 +50,22 @@
%% ---------------------------------------------------------------------
-%% XXX: just an approximation
--type deep_string() :: [char() | [_]].
-
-%% XXX: poor man's document() until recursive data types are supported
--type doc() :: 'null'
- | {'text' | 'fit', _}
- | {'nest' | 'beside' | 'above' | 'union', _, _}
- | {'sep' | 'float', _, _, _}.
+-type deep_string() :: [char() | deep_string()].
%% Document structures fully implemented and available to the user:
-record(text, {s :: deep_string()}).
--record(nest, {n :: integer(), d :: doc()}).
--record(beside, {d1 :: doc(), d2 :: doc()}).
--record(above, {d1 :: doc(), d2 :: doc()}).
--record(sep, {ds :: [doc()], i = 0 :: integer(), p = false :: boolean()}).
+-record(nest, {n :: integer(), d :: document()}).
+-record(beside, {d1 :: document(), d2 :: document()}).
+-record(above, {d1 :: document(), d2 :: document()}).
+-record(sep, {ds :: [document()], i = 0 :: integer(),
+ p = false :: boolean()}).
%% Document structure which is not clear whether it is fully implemented:
--record(float, {d :: doc(), h :: integer(), v :: integer()}).
+-record(float, {d :: document(), h :: integer(), v :: integer()}).
%% Document structures not available to the user:
--record(union, {d1 :: doc(), d2 :: doc()}).
--record(fit, {d :: doc()}).
-
+-record(union, {d1 :: document(), d2 :: document()}).
+-record(fit, {d :: document()}).
%% ---------------------------------------------------------------------
%% A small warning for hackers: it's fairly easy to break this
@@ -637,43 +630,43 @@ flatrev([], As, []) ->
%% Contexts:
%%
%% #c_best_nest{w = integer(), r = integer(), i = integer()}
-%% #c_above_nest{d = doc(), i = integer(), c = ctxt()}
-%% #c_beside{d = doc(), c = ctxt()}
+%% #c_above_nest{d = document(), i = integer(), c = ctxt()}
+%% #c_beside{d = document(), c = ctxt()}
%% #c_text_beside{s = string(), c = ctxt()}
-%% #c_sep_nest{ds = [doc()], i = integer(), p = boolean(),
+%% #c_sep_nest{ds = [document()], i = integer(), p = boolean(),
%% c = ctxt()}
%% #c_best_nest_or{w = integer(), r = integer(), i = integer(),
-%% d = doc()}
+%% d = document()}
%% #c_fit{c = ctxt()}
--record(c_best_nest, {w, r, i}). %% best(w, r, nest(i, *))
+%% best(w, r, nest(i, *))
+-record(c_best_nest, {w :: integer(), r :: integer(), i :: integer()}).
--record(c_above_nest, {d, i = 0, c}). %% above(*, nest(i, d))
+%% above(*, nest(i, d))
+-record(c_above_nest, {d :: document(), i = 0 :: integer(), c :: ctxt()}).
--record(c_beside, {d, c}). %% beside(*, d)
+-record(c_beside, {d :: document(), c :: ctxt()}). %% beside(*, d)
--record(c_text_beside, {s, c}). %% beside(text(s), *)
+-record(c_text_beside, {s :: string(), c :: ctxt()}). %% beside(text(s), *)
%% p = false => sep([* | map(nest i, ds)])
%% p = true => par([* | map(nest i, ds)])
--record(c_sep_nest, {ds, i, p, c}).
+-record(c_sep_nest, {ds :: [document()], i :: integer(),
+ p :: boolean(), c :: ctxt()}).
--record(c_best_nest_or, {w, r, i, d}). %% nicest(
- %% best(w, r,
- %% nest(i, *)),
- %% best(w, r, d))
+%% nicest(best(w, r, nest(i, *)), best(w, r, d))
+-record(c_best_nest_or, {w :: integer(), r :: integer(),
+ i :: integer(), d :: document()}).
--record(c_fit, {c}). %% fit(*)
+-record(c_fit, {c :: ctxt()}). %% fit(*)
--record(c_float_beside, {d, h, v, c}). %% beside(
- %% float(d, h,
- %% v),
- %% *)
--record(c_float_above_nest, {d, h, v, i, c}). %% above(
- %% float(d, h,
- %% v),
- %% nest(i, *))
+%% beside(float(d, h, v), *)
+-record(c_float_beside, {d :: document(), h :: integer(),
+ v :: integer(), c :: ctxt()}).
+%% above(float(d, h, v), nest(i, *))
+-record(c_float_above_nest, {d :: document(), h :: integer(),
+ v :: integer(), i :: integer(), c :: ctxt()}).
%% Contexts introduced: In case:
%%
@@ -687,6 +680,11 @@ flatrev([], As, []) ->
%% c_float_beside float (c_beside)
%% c_float_above_nest float (c_above_nest)
+-type ctxt() :: #c_best_nest{} | #c_above_nest{}
+ | #c_beside{} | #c_text_beside{}
+ | #c_sep_nest{} | #c_best_nest_or{}
+ | #c_fit{} | #c_float_beside{} | #c_float_above_nest{}.
+
%% Entry point for the layout algorithm:
-spec best(document(), integer(), integer()) -> 'empty' | document().
diff --git a/lib/syntax_tools/vsn.mk b/lib/syntax_tools/vsn.mk
index 53c13440f3..2ba5eac582 100644
--- a/lib/syntax_tools/vsn.mk
+++ b/lib/syntax_tools/vsn.mk
@@ -1 +1 @@
-SYNTAX_TOOLS_VSN = 1.6.4
+SYNTAX_TOOLS_VSN = 1.6.5
diff --git a/lib/test_server/doc/src/Makefile b/lib/test_server/doc/src/Makefile
index e3c1b8ce92..c7ba415e5b 100644
--- a/lib/test_server/doc/src/Makefile
+++ b/lib/test_server/doc/src/Makefile
@@ -1,19 +1,19 @@
#
# %CopyrightBegin%
-#
-# Copyright Ericsson AB 2002-2009. All Rights Reserved.
-#
+#
+# Copyright Ericsson AB 2002-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%
#
@@ -60,6 +60,9 @@ XML_CHAPTER_FILES = \
BOOK_FILES = book.xml
+XML_FILES = $(BOOK_FILES) $(XML_APPLICATION_FILES) $(XML_REF3_FILES) $(XML_REF6_FILES) \
+ $(XML_PART_FILES) $(XML_CHAPTER_FILES)
+
GIF_FILES =
# ----------------------------------------------------
diff --git a/lib/test_server/doc/src/notes.xml b/lib/test_server/doc/src/notes.xml
index a71c18b5b7..b6e0a6cefa 100644
--- a/lib/test_server/doc/src/notes.xml
+++ b/lib/test_server/doc/src/notes.xml
@@ -4,7 +4,7 @@
<chapter>
<header>
<copyright>
- <year>2004</year><year>2009</year>
+ <year>2004</year><year>2010</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
@@ -13,12 +13,12 @@
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>APPLICATION Release Notes</title>
@@ -32,6 +32,59 @@
<file>notes.xml</file>
</header>
+<section><title>Test_Server 3.3.6</title>
+
+ <section><title>Fixed Bugs and Malfunctions</title>
+ <list>
+ <item>
+ <p>
+ The Test Server parse transform did not handle bit string
+ comprehensions. This has been fixed.</p>
+ <p>
+ Own Id: OTP-8458 Aux Id: OTP-8311 </p>
+ </item>
+ </list>
+ </section>
+
+
+ <section><title>Improvements and New Features</title>
+ <list>
+ <item>
+ <p>
+ The tc_status value in the Config list for a test case
+ that has failed because of a timetrap timeout, has
+ changed from {tc_status,timeout} to
+ {tc_status,timetrap_timeout}.</p>
+ <p>
+ Own Id: OTP-8302</p>
+ </item>
+ <item>
+ <p>The documentation is now possible to build in an open
+ source environment after a number of bugs are fixed and
+ some features are added in the documentation build
+ process. </p>
+ <p>- The arity calculation is updated.</p>
+ <p>- The module prefix used in the function names for
+ bif's are removed in the generated links so the links
+ will look like
+ "http://www.erlang.org/doc/man/erlang.html#append_element-2"
+ instead of
+ "http://www.erlang.org/doc/man/erlang.html#erlang:append_element-2".</p>
+ <p>- Enhanced the menu positioning in the html
+ documentation when a new page is loaded.</p>
+ <p>- A number of corrections in the generation of man
+ pages (thanks to Sergei Golovan)</p>
+ <p>- The legal notice is taken from the xml book file so
+ OTP's build process can be used for non OTP
+ applications.</p>
+ <p>
+ Own Id: OTP-8343</p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
<section><title>Test_Server 3.3.5</title>
<section><title>Fixed Bugs and Malfunctions</title>
diff --git a/lib/test_server/doc/src/test_server_ctrl.xml b/lib/test_server/doc/src/test_server_ctrl.xml
index 3d95813c14..0ed5f88544 100644
--- a/lib/test_server/doc/src/test_server_ctrl.xml
+++ b/lib/test_server/doc/src/test_server_ctrl.xml
@@ -24,7 +24,7 @@
</legalnotice>
<title>The Test Server Controller</title>
- <prepared>Siri Hansen</prepared>
+ <prepared>Siri Hansen, Peter Andersson</prepared>
<responsible></responsible>
<docno></docno>
<approved></approved>
@@ -582,7 +582,7 @@ Optional, if not given the test server controller node
<br></br>
<c>erl -noshell -s test_server_ctrl run_test KEY1 Value1 KEY2 Value2 ... -s erlang halt</c></p>
<p>Or make an alias (this is for unix/tcsh) <br></br>
-<c>alias erl_test 'erl -noshell -s test_server_ctrl run_test \\!* -s erlang halt'</c></p>
+<c>alias erl_test 'erl -noshell -s test_server_ctrl run_test \!* -s erlang halt'</c></p>
<p>And then use it like this <br></br>
<c>erl_test KEY1 Value1 KEY2 Value2 ...</c> <br></br>
</p>
@@ -649,8 +649,13 @@ Optional, if not given the test server controller node
<fsummary>Get subcases.</fsummary>
<type>
<v>Mod = atom()</v>
+ <d>Test suite name.</d>
<v>Func = atom()</v>
- <v>TestCaseList = [,SubCase]</v>
+ <d>Name of test case.</d>
+ <v>TestCaseList = [SubCase]</v>
+ <d>List of test cases.</d>
+ <v>SubCase = atom()</v>
+ <d>Name of a case.</d>
</type>
<desc>
<p>This function is called before a test case is started. The
@@ -660,36 +665,72 @@ Optional, if not given the test server controller node
</desc>
</func>
<func>
- <name>init_tc(Mod,Func,Args) -> {ok,Args}</name>
- <fsummary>Preparation for a test case.</fsummary>
+ <name>init_tc(Mod,Func,Args0) -> {ok,Args1} | {skip,ReasonToSkip} | {auto_skip,ReasonToSkip} | {fail,ReasonToFail}</name>
+ <fsummary>Preparation for a test case or configuration function.</fsummary>
<type>
<v>Mod = atom()</v>
+ <d>Test suite name.</d>
<v>Func = atom()</v>
- <v>Args = [tuple()]</v>
- <d>Normally Args = [Config]</d>
+ <d>Name of test case or configuration function.</d>
+ <v>Args0 = Args1 = [tuple()]</v>
+ <d>Normally Args = [Config]</d>
+ <v>ReasonToSkip = term()</v>
+ <d>Reason to skip the test case or configuration function.</d>
+ <v>ReasonToFail = term()</v>
+ <d>Reason to fail the test case or configuration function.</d>
</type>
<desc>
- <p>This function is called when a test case is started. It is
- called on the process executing the test case function
- (<c>Mod:Func</c>). Typical use of this function can be to alter
- the input parameters to the test case function (<c>Args</c>) or
- to set properties for the executing process.</p>
+ <p>This function is called before a test case or configuration
+ function starts. It is called on the process executing the function
+ <c>Mod:Func</c>. Typical use of this function can be to alter
+ the input parameters to the test case function (<c>Args</c>) or
+ to set properties for the executing process.</p>
+ <p>By returning <c>{skip,Reason}</c>, <c>Func</c> gets skipped.
+ <c>Func</c> also gets skipped if <c>{auto_skip,Reason}</c> is returned,
+ but then gets an auto skipped status (rather than user skipped).</p>
+ <p>To fail <c>Func</c> immediately instead of executing it, return
+ <c>{fail,ReasonToFail}.</c></p>
</desc>
</func>
<func>
- <name>end_tc(Mod,Func,Args) -> ok</name>
- <fsummary>Cleanup after a test case.</fsummary>
+ <name>end_tc(Mod,Func,Status) -> ok | {fail,ReasonToFail}</name>
+ <fsummary>Cleanup after a test case or configuration function.</fsummary>
<type>
<v>Mod = atom()</v>
+ <d>Test suite name.</d>
<v>Func = atom()</v>
+ <d>Name of test case or configuration function.</d>
+ <v>Status = {Result,Args} | {TCPid,Result,Args}</v>
+ <d>The status of the test case or configuration function.</d>
+ <v>ReasonToFail = term()</v>
+ <d>Reason to fail the test case or configuration function.</d>
+ <v>Result = ok | Skip | Fail</v>
+ <d>The final result of the test case or configuration function.</d>
+ <v>TCPid = pid()</v>
+ <d>Pid of the process executing Func</d>
+ <v>Skip = {skip,SkipReason}</v>
+ <v>SkipReason = term() | {failed,{Mod,init_per_testcase,term()}}</v>
+ <d>Reason why the function was skipped.</d>
+ <v>Fail = {error,term()} | {'EXIT',term()} | {timetrap_timeout,integer()} |
+ {testcase_aborted,term()} | testcase_aborted_or_killed |
+ {failed,term()} | {failed,{Mod,end_per_testcase,term()}}</v>
+ <d>Reason why the function failed.</d>
<v>Args = [tuple()]</v>
- <d>Normally Args = [Config]</d>
+ <d>Normally Args = [Config]</d>
</type>
<desc>
- <p>This function is called when a test case is completed. It is
- called on the process where the test case function
- (<c>Mod:Func</c>) was executed. Typical use of this function can
- be to clean up stuff done by <c>init_tc/3</c>.</p>
+ <p>This function is called when a test case, or a configuration function,
+ is finished. It is normally called on the process where the function
+ <c>Mod:Func</c> has been executing, but if not, the pid of the test
+ case process is passed with the <c>Status</c> argument.</p>
+ <p>Typical use of the <c>end_tc/3</c> function can be to clean up
+ after <c>init_tc/3</c>.</p>
+ <p>If <c>Func</c> is a test case, it is possible to analyse the value of
+ <c>Result</c> to verify that <c>init_per_testcase/2</c> and
+ <c>end_per_testcase/2</c> executed successfully.</p>
+ <p>It is possible with <c>end_tc/3</c> to fail an otherwise successful
+ test case, by returning <c>{fail,ReasonToFail}</c>. The test case <c>Func</c>
+ will be logged as failed with the provided term as reason.</p>
</desc>
</func>
<func>
@@ -700,37 +741,39 @@ Optional, if not given the test server controller node
<v>Data = term()</v>
</type>
<desc>
- <p>This function is called in order to keep the framework upto
- date about the progress of the test. This is useful e.g. if the
- framework implements a GUI where the progress information is
- constantly updated. The following can be reported:
- </p>
- <p><c>What = tests_start, Data = {Name,NumCases}</c> <br></br>
-<c>What = tests_done, Data = {Ok,Failed,Skipped}</c> <br></br>
-<c>What = tc_start, Data = {Mod,Func}</c> <br></br>
-<c>What = tc_done, Data = {Mod,Func,Result}</c></p>
+ <p>This function is called in order to keep the framework up-to-date with
+ the progress of the test. This is useful e.g. if the
+ framework implements a GUI where the progress information is
+ constantly updated. The following can be reported:
+ </p>
+ <p><c>What = tests_start, Data = {Name,NumCases}</c><br></br>
+ <c>What = tests_done, Data = {Ok,Failed,{UserSkipped,AutoSkipped}}</c><br></br>
+ <c>What = tc_start, Data = {Mod,Func}</c><br></br>
+ <c>What = tc_done, Data = {Mod,Func,Result}</c><br></br>
+ <c>What = tc_user_skip, Data = {Mod,Func,Comment}</c><br></br>
+ <c>What = tc_auto_skip, Data = {Mod,Func,Comment}</c></p>
</desc>
</func>
<func>
- <name>error_notification(Mod, Case, Args, Error) -> ok</name>
- <fsummary>Inform framework of crashing testcase.</fsummary>
+ <name>error_notification(Mod, Func, Args, Error) -> ok</name>
+ <fsummary>Inform framework of crashing testcase or configuration function.</fsummary>
<type>
<v>Mod = atom()</v>
<d>Test suite name.</d>
- <v>Case = atom()</v>
- <d>Name of test case function.</d>
+ <v>Func = atom()</v>
+ <d>Name of test case or configuration function.</d>
<v>Args = [tuple()]</v>
<d>Normally Args = [Config]</d>
<v>Error = {Reason,Location}</v>
<v>Reason = term()</v>
<d>Reason for termination.</d>
- <v>Location = unknown | [{Mod,Case,Line}]</v>
+ <v>Location = unknown | [{Mod,Func,Line}]</v>
<d>Last known position in Mod before termination.</d>
<v>Line = integer()</v>
<d>Line number in file Mod.erl.</d>
</type>
<desc>
- <p>This function is called as the result of testcase Mod:Case failing
+ <p>This function is called as the result of function <c>Mod:Func</c> failing
with Reason at Location. The function is intended mainly to aid
specific logging or error handling in the framework application. Note
that for Location to have relevant values (i.e. other than unknown),
diff --git a/lib/test_server/doc/src/write_framework_chapter.xml b/lib/test_server/doc/src/write_framework_chapter.xml
index 2fde67132e..8a20e9afec 100644
--- a/lib/test_server/doc/src/write_framework_chapter.xml
+++ b/lib/test_server/doc/src/write_framework_chapter.xml
@@ -103,7 +103,7 @@
<p>A typical command line may look like this <br></br>
<c>erl -noshell -s test_server_ctrl run_test KEY1 Value1 KEY2 Value2 ... -s erlang halt</c></p>
<p>Or make an alias (this is for unix/tcsh) <br></br>
-<c>alias erl_test 'erl -noshell -s test_server_ctrl run_test \\!* -s erlang halt'</c></p>
+<c>alias erl_test 'erl -noshell -s test_server_ctrl run_test \!* -s erlang halt'</c></p>
<p>And then use it like this <br></br>
<c>erl_test KEY1 Value1 KEY2 Value2 ...</c> <br></br>
</p>
diff --git a/lib/test_server/info b/lib/test_server/info
index 79ccc202d7..7a9ed6c700 100644
--- a/lib/test_server/info
+++ b/lib/test_server/info
@@ -1,2 +1,2 @@
-group: tools
+group: test Test Applications
short: The OTP Test Server
diff --git a/lib/test_server/src/Makefile b/lib/test_server/src/Makefile
index 2d7e5b28bc..d55a3a597d 100644
--- a/lib/test_server/src/Makefile
+++ b/lib/test_server/src/Makefile
@@ -1,19 +1,19 @@
#
# %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
# 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 @@ clean:
rm -f $(TARGET_FILES) $(TS_TARGET_FILES)
rm -f core
-doc:
+docs:
configure: configure.in
autoconf configure.in > configure
diff --git a/lib/test_server/src/test_server.erl b/lib/test_server/src/test_server.erl
index 99e24205ae..f918f47415 100644
--- a/lib/test_server/src/test_server.erl
+++ b/lib/test_server/src/test_server.erl
@@ -1,19 +1,19 @@
%%
%% %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
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
-%%
+%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
-%%
+%%
%% %CopyrightEnd%
%%
-module(test_server).
@@ -760,6 +760,10 @@ run_test_case_msgloop(Ref, Pid, CaptureStdout, Terminate, Comment) ->
spawn_fw_call(undefined,undefined,Pid,testcase_aborted_or_killed,
unknown,self(),Comment),
run_test_case_msgloop(Ref,Pid,CaptureStdout,Terminate,Comment);
+ {fw_error,{FwMod,FwFunc,FwError}} ->
+ spawn_fw_call(FwMod,FwFunc,Pid,{framework_error,FwError},
+ unknown,self(),Comment),
+ run_test_case_msgloop(Ref,Pid,CaptureStdout,Terminate,Comment);
_ ->
%% the testcase has terminated because of Reason (e.g. an exit
%% because a linked process failed)
@@ -859,6 +863,22 @@ spawn_fw_call(Mod,{end_per_testcase,Func},Pid,{timetrap_timeout,TVal}=Why,
"</font>"]}}
end,
spawn_link(FwCall);
+
+spawn_fw_call(FwMod,FwFunc,_Pid,{framework_error,FwError},_,SendTo,_Comment) ->
+ FwCall =
+ fun() ->
+ test_server_sup:framework_call(report, [framework_error,
+ {{FwMod,FwFunc},FwError}]),
+ Comment =
+ lists:flatten(
+ io_lib:format("<font color=\"red\">"
+ "WARNING! ~w:~w failed!</font>", [FwMod,FwFunc])),
+ %% finished, report back
+ SendTo ! {self(),fw_notify_done,
+ {died,{error,{FwMod,FwFunc,FwError}},{FwMod,FwFunc},[],Comment}}
+ end,
+ spawn_link(FwCall);
+
spawn_fw_call(Mod,Func,Pid,Error,Loc,SendTo,Comment) ->
FwCall =
fun() ->
diff --git a/lib/test_server/src/test_server_ctrl.erl b/lib/test_server/src/test_server_ctrl.erl
index 667d0cc051..4cb5863955 100644
--- a/lib/test_server/src/test_server_ctrl.erl
+++ b/lib/test_server/src/test_server_ctrl.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2002-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 2002-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(test_server_ctrl).
diff --git a/lib/test_server/src/test_server_line.erl b/lib/test_server/src/test_server_line.erl
index 26ef3a3040..848a9c23dd 100644
--- a/lib/test_server/src/test_server_line.erl
+++ b/lib/test_server/src/test_server_line.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2004-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 2004-2010. All Rights Reserved.
+%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
-%%
+%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
-%%
+%%
%% %CopyrightEnd%
%%
-module(test_server_line).
@@ -347,6 +347,10 @@ munge_expr({'fun',Line,{clauses,Clauses}}, Vars) ->
%% Only for Vsn=raw_abstract_v1
{MungedClauses,Vars2}=munge_clauses(Clauses, Vars, []),
{{'fun',Line,{clauses,MungedClauses}}, Vars2};
+munge_expr({bc,Line,Expr,LC}, Vars) ->
+ {MungedExpr, Vars2} = munge_expr(Expr, Vars),
+ {MungedLC, Vars3} = munge_lc(LC, Vars2, []),
+ {{bc,Line,MungedExpr,MungedLC}, Vars3};
munge_expr(Form, Vars) -> % var|char|integer|float|string|atom|nil|bin|eof
{Form, Vars}.
@@ -363,6 +367,9 @@ munge_exprs([], Vars, MungedExprs) ->
munge_lc([{generate,Line,Pattern,Expr}|LC], Vars, MungedLC) ->
{MungedExpr, Vars2} = munge_expr(Expr, Vars),
munge_lc(LC, Vars2, [{generate,Line,Pattern,MungedExpr}|MungedLC]);
+munge_lc([{b_generate,Line,Pattern,Expr}|LC], Vars, MungedLC) ->
+ {MungedExpr, Vars2} = munge_expr(Expr, Vars),
+ munge_lc(LC, Vars2, [{b_generate,Line,Pattern,MungedExpr}|MungedLC]);
munge_lc([Expr|LC], Vars, MungedLC) ->
{MungedExpr, Vars2} = munge_expr(Expr, Vars),
munge_lc(LC, Vars2, [MungedExpr|MungedLC]);
diff --git a/lib/test_server/src/test_server_sup.erl b/lib/test_server/src/test_server_sup.erl
index c665f185fd..89edb0f881 100644
--- a/lib/test_server/src/test_server_sup.erl
+++ b/lib/test_server/src/test_server_sup.erl
@@ -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%
%%
@@ -497,7 +497,18 @@ framework_call(Callback,Func,Args,DefaultReturn) ->
end,
case erlang:function_exported(Mod,Func,length(Args)) of
true ->
- apply(Mod,Func,Args);
+ EH = fun(Reason) -> exit({fw_error,{Mod,Func,Reason}}) end,
+ try apply(Mod,Func,Args) of
+ Result ->
+ Result
+ catch
+ exit:Why ->
+ EH(Why);
+ error:Why ->
+ EH({Why,erlang:get_stacktrace()});
+ throw:Why ->
+ EH(Why)
+ end;
false ->
DefaultReturn
end.
diff --git a/lib/test_server/test/Makefile b/lib/test_server/test/Makefile
new file mode 100644
index 0000000000..702d73f5af
--- /dev/null
+++ b/lib/test_server/test/Makefile
@@ -0,0 +1,95 @@
+#
+# %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= \
+ test_server_SUITE \
+ test_server_line_SUITE \
+ test_server_skip_SUITE \
+ test_server_conf01_SUITE \
+ test_server_conf02_SUITE \
+ test_server_parallel01_SUITE \
+ test_server_shuffle01_SUITE
+
+ERL_FILES= $(MODULES:%=%.erl)
+
+TARGET_FILES= $(MODULES:%=$(EBIN)/%.$(EMULATOR))
+INSTALL_PROGS= $(TARGET_FILES)
+
+EMAKEFILE=Emakefile
+COVERFILE=test_server.cover
+
+# ----------------------------------------------------
+# Release directory specification
+# ----------------------------------------------------
+RELSYSDIR = $(RELEASE_PATH)/test_server_test
+
+# ----------------------------------------------------
+# FLAGS
+# ----------------------------------------------------
+
+ERL_MAKE_FLAGS += -pa $(ERL_TOP)/lib/test_server/ebin
+ERL_COMPILE_FLAGS += -I$(ERL_TOP)/lib/test_server/include
+
+EBIN = .
+
+# ----------------------------------------------------
+# Targets
+# ----------------------------------------------------
+
+.PHONY: make_emakefile
+
+make_emakefile:
+ $(ERL_TOP)/make/make_emakefile $(ERL_COMPILE_FLAGS) -o$(EBIN) \
+ '*_SUITE_make' > $(EMAKEFILE)
+ $(ERL_TOP)/make/make_emakefile $(ERL_COMPILE_FLAGS) -o$(EBIN) $(MODULES)\
+ >> $(EMAKEFILE)
+
+tests debug opt: make_emakefile
+ cd ../src && $(MAKE) ../ebin/test_server_line.beam
+ erl $(ERL_MAKE_FLAGS) -make
+
+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: opt
+
+release_tests_spec: make_emakefile
+ $(INSTALL_DIR) $(RELSYSDIR)
+ $(INSTALL_DATA) $(EMAKEFILE) $(ERL_FILES) $(COVERFILE) $(RELSYSDIR)
+ $(INSTALL_PROGRAM) test_server.spec $(RELSYSDIR)
+ chmod -f -R u+w $(RELSYSDIR)
+ @tar cf - *_SUITE_data | (cd $(RELSYSDIR); tar xf -)
+
+release_docs_spec:
diff --git a/lib/test_server/test/test_server.cover b/lib/test_server/test/test_server.cover
new file mode 100644
index 0000000000..c2366db166
--- /dev/null
+++ b/lib/test_server/test/test_server.cover
@@ -0,0 +1,20 @@
+{exclude,[test_server,
+ test_server_ctrl,
+ ts_selftest]}.
+
+%% Using include list here because the test_server might not find
+%% lib_dir for test_server - and so it will not find which modules to
+%% compile.
+{include,[erl2html2,
+ test_server_node,
+ test_server_sup,
+ ts,
+ ts_autoconf_vxworks,
+ ts_autoconf_win32,
+ ts_erl_config,
+ ts_install,
+ ts_lib,
+ ts_make,
+ ts_run,
+ vxworks_client]}.
+
diff --git a/lib/test_server/test/test_server.spec b/lib/test_server/test/test_server.spec
new file mode 100644
index 0000000000..23b0b71963
--- /dev/null
+++ b/lib/test_server/test/test_server.spec
@@ -0,0 +1,2 @@
+{topcase, {dir, "../test_server_test"}}.
+{skip,{test_server_SUITE,skip_case7,"This case should be noted as `Skipped'"}}.
diff --git a/lib/test_server/test/test_server_SUITE.erl b/lib/test_server/test/test_server_SUITE.erl
new file mode 100644
index 0000000000..dfe1028d3a
--- /dev/null
+++ b/lib/test_server/test/test_server_SUITE.erl
@@ -0,0 +1,554 @@
+%%
+%% %CopyrightBegin%
+%%
+%% 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%
+%%
+
+%%%------------------------------------------------------------------
+%%% Test Server self test.
+%%%------------------------------------------------------------------
+-module(test_server_SUITE).
+-include_lib("test_server/include/test_server.hrl").
+-include_lib("test_server/include/test_server_line.hrl").
+-include_lib("kernel/include/file.hrl").
+-export([all/1]).
+
+-export([init_per_suite/1, end_per_suite/1]).
+-export([init_per_testcase/2, end_per_testcase/2, fin_per_testcase/2]).
+-export([config/1, comment/1, timetrap/1, timetrap_cancel/1, multiply_timetrap/1,
+ init_per_s/1, init_per_tc/1, end_per_tc/1,
+ timeconv/1, msgs/1, capture/1, timecall/1,
+ do_times/1, do_times_mfa/1, do_times_fun/1,
+ skip_cases/1, skip_case1/1, skip_case2/1, skip_case3/1,
+ skip_case4/1, skip_case5/1, skip_case6/1, skip_case7/1,
+ skip_case8/1, skip_case9/1, undefined_functions/1,
+ conf_init/1, check_new_conf/1, conf_cleanup/1,
+ check_old_conf/1, conf_init_fail/1, start_stop_node/1,
+ cleanup_nodes_init/1, check_survive_nodes/1, cleanup_nodes_fin/1,
+ commercial/1]).
+
+-export([dummy_function/0,dummy_function/1,doer/1]).
+
+all(doc) -> ["Test Server self test"];
+all(suite) ->
+ [config, comment, timetrap, timetrap_cancel, multiply_timetrap,
+ init_per_s, init_per_tc, end_per_tc,
+ timeconv, msgs, capture, timecall, do_times, skip_cases,
+ undefined_functions, commercial,
+ {conf, conf_init, [check_new_conf], conf_cleanup},
+ check_old_conf,
+ {conf, conf_init_fail,[conf_member_skip],conf_cleanup_skip},
+ start_stop_node,
+ {conf, cleanup_nodes_init,[check_survive_nodes],cleanup_nodes_fin},
+ config
+ ].
+
+
+init_per_suite(Config) ->
+ [{init_per_suite_var,ok}|Config].
+
+end_per_suite(_Config) ->
+ ok.
+
+init_per_testcase(Func, Config) when is_atom(Func), is_list(Config) ->
+ Dog = ?t:timetrap(?t:minutes(2)),
+ Config1 = [{watchdog, Dog}|Config],
+ case Func of
+ init_per_tc ->
+ [{strange_var, 1}|Config1];
+ skip_case8 ->
+ {skipped, "This case should be noted as `Skipped'"};
+ skip_case9 ->
+ {skip, "This case should be noted as `Skipped'"};
+ _ ->
+ Config1
+ end;
+init_per_testcase(Func, Config) ->
+ io:format("Func:~p",[Func]),
+ io:format("Config:~p",[Config]),
+ ?t:fail("Arguments to init_per_testcase not correct").
+
+end_per_testcase(Func, Config) when is_atom(Func), is_list(Config) ->
+ Dog=?config(watchdog, Config),
+ ?t:timetrap_cancel(Dog),
+ case Func of
+ end_per_tc -> io:format("CLEANUP => this test case is ok\n");
+ _Other -> ok
+ end;
+end_per_testcase(Func, Config) ->
+ io:format("Func:~p",[Func]),
+ io:format("Config:~p",[Config]),
+ ?t:fail("Arguments to end_per_testcase not correct").
+
+fin_per_testcase(Func, Config) ->
+ io:format("Func:~p",[Func]),
+ io:format("Config:~p",[Config]),
+ ?t:fail("fin_per_testcase/2 called, should have called end_per_testcase/2").
+
+
+config(suite) -> [];
+config(doc) -> ["Test that the Config variable is decent, ",
+ "and that the std config variables are correct ",
+ "(check that data/priv dir exists)."
+ "Also check that ?config macro works."];
+config(Config) when is_list(Config) ->
+ is_tuplelist(Config),
+ {value,{data_dir,Dd}}=lists:keysearch(data_dir,1,Config),
+ {value,{priv_dir,Dp}}=lists:keysearch(priv_dir,1,Config),
+ true=is_dir(Dd),
+ {ok, _Bin}=file:read_file(filename:join(Dd, "dummy_file")),
+ true=is_dir(Dp),
+
+ Dd = ?config(data_dir,Config),
+ Dp = ?config(priv_dir,Config),
+ ok;
+config(_Config) ->
+ ?t:fail("Config variable is not a list.").
+
+is_tuplelist([]) ->
+ true;
+is_tuplelist([{_A,_B}|Rest]) ->
+ is_tuplelist(Rest);
+is_tuplelist(_) ->
+ false.
+
+is_dir(Dir) ->
+ case file:read_file_info(Dir) of
+ {ok, #file_info{type=directory}} ->
+ true;
+ _ ->
+ false
+ end.
+
+comment(suite) -> [];
+comment(doc) -> ["Print a comment in the HTML log"];
+comment(Config) when is_list(Config) ->
+ ?t:comment("This comment should not occur in the HTML log because a later"
+ " comment shall overwrite it"),
+ ?t:comment("This comment is printed with the comment/1 function."
+ " It should occur in the HTML log").
+
+
+
+timetrap(suite) -> [];
+timetrap(doc) -> ["Test that timetrap works."];
+timetrap(Config) when is_list(Config) ->
+ TrapAfter = 3000,
+ Dog=?t:timetrap(TrapAfter),
+ process_flag(trap_exit, true),
+ TimeOut = TrapAfter * test_server:timetrap_scale_factor() + 1000,
+ receive
+ {'EXIT', Dog, {timetrap_timeout, _, _}} ->
+ ok;
+ {'EXIT', _OtherPid, {timetrap_timeout, _, _}} ->
+ ?t:fail("EXIT signal from wrong process")
+ after
+ TimeOut ->
+ ?t:fail("Timetrap is not working.")
+ end,
+ ?t:timetrap_cancel(Dog),
+ ok.
+
+
+timetrap_cancel(suite) -> [];
+timetrap_cancel(doc) -> ["Test that timetrap_cancel works."];
+timetrap_cancel(Config) when is_list(Config) ->
+ Dog=?t:timetrap(1000),
+ receive
+ after
+ 500 ->
+ ok
+ end,
+ ?t:timetrap_cancel(Dog),
+ receive
+ after 1000 ->
+ ok
+ end,
+ ok.
+
+multiply_timetrap(suite) -> [];
+multiply_timetrap(doc) -> ["Test multiply timetrap"];
+multiply_timetrap(Config) when is_list(Config) ->
+ %% This simulates the call to test_server_ctrl:multiply_timetraps/1:
+ put(test_server_multiply_timetraps,2),
+
+ Dog = ?t:timetrap(500),
+ timer:sleep(800),
+ ?t:timetrap_cancel(Dog),
+
+ %% Reset
+ put(test_server_multiply_timetraps,1),
+ ok.
+
+
+init_per_s(suite) -> [];
+init_per_s(doc) -> ["Test that a Config that is altered in ",
+ "init_per_suite gets through to the testcases."];
+init_per_s(Config) ->
+ %% Check that the config var sent from init_per_suite
+ %% really exists.
+ {value, {init_per_suite_var, ok}} =
+ lists:keysearch(init_per_suite_var,1,Config),
+
+ %% Check that the other variables still exist.
+ {value,{data_dir,_Dd}}=lists:keysearch(data_dir,1,Config),
+ {value,{priv_dir,_Dp}}=lists:keysearch(priv_dir,1,Config),
+ ok.
+
+init_per_tc(suite) -> [];
+init_per_tc(doc) -> ["Test that a Config that is altered in ",
+ "init_per_testcase gets through to the ",
+ "actual testcase."];
+init_per_tc(Config) ->
+ %% Check that the config var sent from init_per_testcase
+ %% really exists.
+ {value, {strange_var, 1}} = lists:keysearch(strange_var,1,Config),
+
+ %% Check that the other variables still exist.
+ {value,{data_dir,_Dd}}=lists:keysearch(data_dir,1,Config),
+ {value,{priv_dir,_Dp}}=lists:keysearch(priv_dir,1,Config),
+ ok.
+
+end_per_tc(suite) -> [];
+end_per_tc(doc) -> ["Test that end_per_testcase/2 is called even if"
+ " test case fails"];
+end_per_tc(Config) when is_list(Config) ->
+ ?t:fail("This case should fail! Check that \"CLEANUP\" is"
+ " printed in the minor log file.").
+
+
+timeconv(suite) -> [];
+timeconv(doc) -> ["Test that the time unit conversion functions ",
+ "works."];
+timeconv(Config) when is_list(Config) ->
+ Val=2,
+ Secs=Val*1000,
+ Mins=Secs*60,
+ Hrs=Mins*60,
+ Secs=?t:seconds(2),
+ Mins=?t:minutes(2),
+ Hrs=?t:hours(2),
+ ok.
+
+
+msgs(suite) -> [];
+msgs(doc) -> ["Tests the messages_get function."];
+msgs(Config) when is_list(Config) ->
+ self() ! {hej, du},
+ self() ! {lite, "data"},
+ self() ! en_atom,
+ [{hej, du}, {lite, "data"}, en_atom] = ?t:messages_get(),
+ ok.
+
+capture(suite) -> [];
+capture(doc) -> ["Test that the capture functions work properly."];
+capture(Config) when is_list(Config) ->
+ String1="abcedfghjiklmnopqrstuvwxyz",
+ String2="0123456789",
+ ?t:capture_start(),
+ io:format(String1),
+ [String1]=?t:capture_get(),
+ io:format(String2),
+ [String2]=?t:capture_get(),
+ ?t:capture_stop(),
+ []=?t:capture_get(),
+ io:format(String2),
+ []=?t:capture_get(),
+ ok.
+
+timecall(suite) -> [];
+timecall(doc) -> ["Tests that timed calls work."];
+timecall(Config) when is_list(Config) ->
+ {_Time1, liten_apa_e_oxo_farlig} = ?t:timecall(?MODULE, dummy_function, []),
+ {Time2, jag_ar_en_gorilla} = ?t:timecall(?MODULE, dummy_function, [gorilla]),
+ DTime=round(Time2),
+ if
+ DTime<1 ->
+ ?t:fail("Timecall reported a too low time.");
+ DTime==1 ->
+ ok;
+ DTime>1 ->
+ ?t:fail("Timecall reported a too high time.")
+ end,
+ ok.
+
+dummy_function() ->
+ liten_apa_e_oxo_farlig.
+dummy_function(gorilla) ->
+ receive after 1000 -> ok end,
+ jag_ar_en_gorilla.
+
+
+do_times(suite) -> [do_times_mfa, do_times_fun];
+do_times(doc) -> ["Test the do_times function."].
+
+do_times_mfa(suite) -> [];
+do_times_mfa(doc) -> ["Test the do_times function with M,F,A given."];
+do_times_mfa(Config) when is_list(Config) ->
+ ?t:do_times(100, ?MODULE, doer, [self()]),
+ 100=length(?t:messages_get()),
+ ok.
+
+do_times_fun(suite) -> [];
+do_times_fun(doc) -> ["Test the do_times function with fun given."];
+do_times_fun(Config) when is_list(Config) ->
+ Self = self(),
+ ?t:do_times(100, fun() -> doer(Self) end),
+ 100=length(?t:messages_get()),
+ ok.
+
+doer(From) ->
+ From ! a,
+ ok.
+
+skip_cases(doc) -> ["Test all possible ways to skip a test case."];
+skip_cases(suite) -> [skip_case1, skip_case2, skip_case3, skip_case4,
+ skip_case5, skip_case6, skip_case7, skip_case8,
+ skip_case9].
+
+skip_case1(suite) -> [];
+skip_case1(doc) -> ["Test that you can return {skipped, Reason},"
+ " and that Reason is in the comment field in the HTML log"];
+skip_case1(Config) when is_list(Config) ->
+ %% If this comment shows, the case failed!!
+ ?t:comment("ERROR: This case should have been noted as `Skipped'"),
+ %% The Reason in {skipped, Reason} should overwrite a 'comment'
+ {skipped, "This case should be noted as `Skipped'"}.
+
+skip_case2(suite) -> [];
+skip_case2(doc) -> ["Test that you can return {skipped, Reason},"
+ " and that Reason is in the comment field in the HTML log"];
+skip_case2(Config) when is_list(Config) ->
+ %% If this comment shows, the case failed!!
+ ?t:comment("ERROR: This case should have been noted as `Skipped'"),
+ %% The Reason in {skipped, Reason} should overwrite a 'comment'
+ exit({skipped, "This case should be noted as `Skipped'"}).
+
+skip_case3(suite) -> [];
+skip_case3(doc) -> ["Test that you can return {skip, Reason},"
+ " and that Reason is in the comment field in the HTML log"];
+skip_case3(Config) when is_list(Config) ->
+ %% If this comment shows, the case failed!!
+ ?t:comment("ERROR: This case should have been noted as `Skipped'"),
+ %% The Reason in {skip, Reason} should overwrite a 'comment'
+ {skip, "This case should be noted as `Skipped'"}.
+
+skip_case4(suite) -> [];
+skip_case4(doc) -> ["Test that you can return {skip, Reason},"
+ " and that Reason is in the comment field in the HTML log"];
+skip_case4(Config) when is_list(Config) ->
+ %% If this comment shows, the case failed!!
+ ?t:comment("ERROR: This case should have been noted as `Skipped'"),
+ %% The Reason in {skip, Reason} should overwrite a 'comment'
+ exit({skip, "This case should be noted as `Skipped'"}).
+
+skip_case5(suite) -> {skipped, "This case should be noted as `Skipped'"};
+skip_case5(doc) -> ["Test that you can return {skipped, Reason}"
+ " from the specification clause"].
+
+skip_case6(suite) -> {skip, "This case should be noted as `Skipped'"};
+skip_case6(doc) -> ["Test that you can return {skip, Reason}"
+ " from the specification clause"].
+
+skip_case7(suite) -> [];
+skip_case7(doc) -> ["Test that skip works from a test specification file"];
+skip_case7(Config) when is_list(Config) ->
+ %% This case shall be skipped by adding
+ %% {skip, {test_server_SUITE, skip_case7, Reason}}.
+ %% to the test specification file.
+ ?t:fail("This case should have been Skipped by the .spec file").
+
+skip_case8(suite) -> [];
+skip_case8(doc) -> ["Test that {skipped, Reason} works from"
+ " init_per_testcase/2"];
+skip_case8(Config) when is_list(Config) ->
+ %% This case shall be skipped by adding a specific clause to
+ %% returning {skipped, Reason} from init_per_testcase/2 for this case.
+ ?t:fail("This case should have been Skipped by init_per_testcase/2").
+
+skip_case9(suite) -> [];
+skip_case9(doc) -> ["Test that {skip, Reason} works from a init_per_testcase/2"];
+skip_case9(Config) when is_list(Config) ->
+ %% This case shall be skipped by adding a specific clause to
+ %% returning {skip, Reason} from init_per_testcase/2 for this case.
+ ?t:fail("This case should have been Skipped by init_per_testcase/2").
+
+undefined_functions(suite) -> [];
+undefined_functions(doc) -> ["Check for calls to undefined functions in"
+ " test_server."
+ "Skip if cover is running"];
+undefined_functions(Config) when is_list(Config) ->
+ case whereis(cover_server) of
+ Pid when is_pid(Pid) ->
+ {skip,"Cover is running"};
+ undefined ->
+ undefined_functions()
+ end.
+
+undefined_functions() ->
+ TestServerDir = filename:dirname(code:which(test_server)),
+ Res = xref:d(TestServerDir),
+
+ {value,{unused,Unused}} = lists:keysearch(unused, 1, Res),
+ case Unused of
+ [] -> ok;
+ _ ->
+ lists:foreach(fun (MFA) ->
+ io:format("~s unused", [format_mfa(MFA)])
+ end, Unused)
+ end,
+
+ {value,{undefined,Undef0}} = lists:keysearch(undefined, 1, Res),
+ Undef = [U || U <- Undef0, not unresolved(U)],
+ case Undef of
+ [] -> ok;
+ _ ->
+ lists:foreach(fun ({MFA1,MFA2}) ->
+ io:format("~s calls undefined ~s",
+ [format_mfa(MFA1),format_mfa(MFA2)])
+ end, Undef),
+ ?t:fail({length(Undef),undefined_functions_in_otp})
+ end,
+ ok.
+
+unresolved({_,{_,'$F_EXPR',_}}) -> true;
+unresolved(_) -> false.
+
+format_mfa({M,F,A}) ->
+ lists:flatten(io_lib:format("~s:~s/~p", [M,F,A])).
+
+conf_init(doc) -> ["Test successful conf case: Change Config parameter"];
+conf_init(Config) when is_list(Config) ->
+ [{conf_init_var,1389}|Config].
+
+check_new_conf(suite) -> [];
+check_new_conf(doc) -> ["Check that Config parameter changed by"
+ " conf_init is used"];
+check_new_conf(Config) when is_list(Config) ->
+ 1389 = ?config(conf_init_var,Config),
+ ok.
+
+conf_cleanup(doc) -> ["Test successful conf case: Restore Config parameter"];
+conf_cleanup(Config) when is_list(Config) ->
+ lists:keydelete(conf_init_var,1,Config).
+
+check_old_conf(suite) -> [];
+check_old_conf(doc) -> ["Test that the restored Config is used after a"
+ " conf cleanup"];
+check_old_conf(Config) when is_list(Config) ->
+ undefined = ?config(conf_init_var,Config),
+ ok.
+
+conf_init_fail(doc) -> ["Test that config members are skipped if"
+ " conf init function fails."];
+conf_init_fail(Config) when is_list(Config) ->
+ ?t:fail("This case should fail! Check that conf_member_skip and"
+ " conf_cleanup_skip are skipped.").
+
+
+
+start_stop_node(suite) -> [];
+start_stop_node(doc) -> ["Test start and stop of slave and peer nodes"];
+start_stop_node(Config) when is_list(Config) ->
+ {ok,Node2} = ?t:start_node(node2,peer,[]),
+ {error, _} = ?t:start_node(node2,peer,[{fail_on_error,false}]),
+ true = lists:member(Node2,nodes()),
+
+ {ok,Node3} = ?t:start_node(node3,slave,[]),
+ {error, _} = ?t:start_node(node3,slave,[]),
+ true = lists:member(Node3,nodes()),
+
+ {ok,Node4} = ?t:start_node(node4,peer,[{wait,false}]),
+ case lists:member(Node4,nodes()) of
+ true ->
+ ?t:comment("WARNING: Node started with {wait,false}"
+ " is up faster than expected...");
+ false ->
+ wait_for_node(Node4,0),
+ true = lists:member(Node4,nodes())
+ end,
+
+ true = ?t:stop_node(Node2),
+ false = lists:member(Node2,nodes()),
+
+ true = ?t:stop_node(Node3),
+ false = lists:member(Node3,nodes()),
+
+ true = ?t:stop_node(Node4),
+ false = lists:member(Node4,nodes()),
+ timer:sleep(2000),
+ false = ?t:stop_node(Node4),
+
+ ok.
+
+
+wait_for_node(Node,Acc) ->
+ case net_adm:ping(Node) of
+ pang ->
+ timer:sleep(100),
+ wait_for_node(Node,Acc+100);
+ pong ->
+ Acc
+ end.
+
+cleanup_nodes_init(doc) -> ["Test that nodes are terminated when test case"
+ " is finished unless {cleanup,false} is given."];
+cleanup_nodes_init(Config) when is_list(Config) ->
+ {ok,DieSlave} = ?t:start_node(die_slave, slave, []),
+ {ok,SurviveSlave} = ?t:start_node(survive_slave, slave, [{cleanup,false}]),
+ {ok,DiePeer} = ?t:start_node(die_peer, peer, []),
+ {ok,SurvivePeer} = ?t:start_node(survive_peer, peer, [{cleanup,false}]),
+ [{die_slave,DieSlave},
+ {survive_slave,SurviveSlave},
+ {die_peer,DiePeer},
+ {survive_peer,SurvivePeer} | Config].
+
+
+
+check_survive_nodes(suite) -> [];
+check_survive_nodes(doc) -> ["Test that nodes with {cleanup,false} survived"];
+check_survive_nodes(Config) when is_list(Config) ->
+ timer:sleep(1000),
+ false = lists:member(?config(die_slave,Config),nodes()),
+ true = lists:member(?config(survive_slave,Config),nodes()),
+ false = lists:member(?config(die_peer,Config),nodes()),
+ true = lists:member(?config(survive_peer,Config),nodes()),
+ ok.
+
+
+cleanup_nodes_fin(doc) -> ["Test that nodes started with {cleanup,false}"
+ " can be stopped"];
+cleanup_nodes_fin(Config) when is_list(Config) ->
+ Slave = ?config(survive_slave,Config),
+ Peer = ?config(survive_peer,Config),
+
+ true = ?t:stop_node(Slave),
+ false = lists:member(Slave,nodes()),
+ true = ?t:stop_node(Peer),
+ false = lists:member(Peer,nodes()),
+
+ C1 = lists:keydelete(die_slave,1,Config),
+ C2 = lists:keydelete(survive_slave,1,C1),
+ C3 = lists:keydelete(die_peer,1,C2),
+ lists:keydelete(survive_peer,1,C3).
+
+commercial(Config) when is_list(Config) ->
+ case ?t:is_commercial() of
+ false -> {comment,"Open-source build"};
+ true -> {comment,"Commercial build"}
+ end.
+
+
diff --git a/lib/test_server/test/test_server_SUITE_data/dummy_file b/lib/test_server/test/test_server_SUITE_data/dummy_file
new file mode 100644
index 0000000000..65c88fbd75
--- /dev/null
+++ b/lib/test_server/test/test_server_SUITE_data/dummy_file
@@ -0,0 +1 @@
+Dummy file. \ No newline at end of file
diff --git a/lib/test_server/test/test_server_conf01_SUITE.erl b/lib/test_server/test/test_server_conf01_SUITE.erl
new file mode 100644
index 0000000000..a6d7dfe851
--- /dev/null
+++ b/lib/test_server/test/test_server_conf01_SUITE.erl
@@ -0,0 +1,187 @@
+%%
+%% %CopyrightBegin%
+%%
+%% 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%
+%%
+
+%%%------------------------------------------------------------------
+%%% Test Server self test.
+%%%------------------------------------------------------------------
+-module(test_server_conf01_SUITE).
+-include_lib("test_server/include/test_server.hrl").
+
+-compile(export_all).
+
+all(doc) -> ["Test simple conf case structure, with and without nested cases"];
+all(suite) ->
+ [
+ {conf, conf1_init, [conf1_tc1, conf1_tc2], conf1_end},
+
+ {conf, [], conf2_init, [conf2_tc1, conf2_tc2], conf2_end},
+
+ {conf, conf3_init, [conf3_tc1,
+
+ {conf, [], conf4_init, [conf4_tc1, conf4_tc2], conf4_end},
+
+ conf3_tc2], conf3_end},
+
+ conf5
+ ].
+
+%%---------- conf cases ----------
+
+conf1_init(Config) when is_list(Config) ->
+ [{cc1,conf1}|Config].
+conf1_end(_Config) ->
+ ok.
+
+conf2_init(Config) when is_list(Config) ->
+ [{cc2,conf2}|Config].
+conf2_end(_Config) ->
+ ok.
+
+conf3_init(Config) when is_list(Config) ->
+ [{cc3,conf3}|Config].
+conf3_end(_Config) ->
+ ok.
+
+conf4_init(Config) when is_list(Config) ->
+ [{cc4,conf4}|Config].
+conf4_end(_Config) ->
+ ok.
+
+conf5_init(Config) when is_list(Config) ->
+ [{cc5,conf5}|Config].
+conf5_end(_Config) ->
+ ok.
+
+conf6_init(Config) when is_list(Config) ->
+ [{cc6,conf6}|Config].
+conf6_end(_Config) ->
+ ok.
+
+
+conf5(suite) -> % test specification
+ [{conf, conf5_init, [conf5_tc1,
+
+ {conf, [], conf6_init, [conf6_tc1, conf6_tc2], conf6_end},
+
+ conf5_tc2], conf5_end}].
+
+
+%%---------- test cases ----------
+
+conf1_tc1(Config) when is_list(Config) ->
+ case ?config(data_dir,Config) of
+ undefined -> exit(no_data_dir);
+ _ -> ok
+ end,
+ conf1 = ?config(cc1,Config),
+ ok.
+conf1_tc2(Config) when is_list(Config) ->
+ case ?config(priv_dir,Config) of
+ undefined -> exit(no_priv_dir);
+ _ -> ok
+ end,
+ conf1 = ?config(cc1,Config),
+ ok.
+
+conf2_tc1(Config) when is_list(Config) ->
+ undefined = ?config(cc1,Config),
+ case ?config(data_dir,Config) of
+ undefined -> exit(no_data_dir);
+ _ -> ok
+ end,
+ conf2 = ?config(cc2,Config),
+ ok.
+conf2_tc2(Config) when is_list(Config) ->
+ case ?config(priv_dir,Config) of
+ undefined -> exit(no_priv_dir);
+ _ -> ok
+ end,
+ conf2 = ?config(cc2,Config),
+ ok.
+
+conf3_tc1(Config) when is_list(Config) ->
+ undefined = ?config(cc1,Config),
+ undefined = ?config(cc2,Config),
+ conf3 = ?config(cc3,Config),
+ ok.
+conf3_tc2(Config) when is_list(Config) ->
+ conf3 = ?config(cc3,Config),
+ undefined = ?config(cc4,Config),
+ ok.
+
+conf4_tc1(Config) when is_list(Config) ->
+ case ?config(data_dir,Config) of
+ undefined -> exit(no_data_dir);
+ _ -> ok
+ end,
+ undefined = ?config(cc1,Config),
+ undefined = ?config(cc2,Config),
+ conf3 = ?config(cc3,Config),
+ conf4 = ?config(cc4,Config),
+ ok.
+conf4_tc2(Config) when is_list(Config) ->
+ case ?config(priv_dir,Config) of
+ undefined -> exit(no_priv_dir);
+ _ -> ok
+ end,
+ conf3 = ?config(cc3,Config),
+ conf4 = ?config(cc4,Config),
+ ok.
+
+conf5_tc1(Config) when is_list(Config) ->
+ case ?config(data_dir,Config) of
+ undefined -> exit(no_data_dir);
+ _ -> ok
+ end,
+ undefined = ?config(cc1,Config),
+ undefined = ?config(cc2,Config),
+ undefined = ?config(cc3,Config),
+ undefined = ?config(cc4,Config),
+ conf5 = ?config(cc5,Config),
+ ok.
+conf5_tc2(Config) when is_list(Config) ->
+ case ?config(priv_dir,Config) of
+ undefined -> exit(no_priv_dir);
+ _ -> ok
+ end,
+ conf5 = ?config(cc5,Config),
+ undefined = ?config(cc6,Config),
+ ok.
+
+conf6_tc1(Config) when is_list(Config) ->
+ case ?config(data_dir,Config) of
+ undefined -> exit(no_data_dir);
+ _ -> ok
+ end,
+ undefined = ?config(cc1,Config),
+ undefined = ?config(cc2,Config),
+ undefined = ?config(cc3,Config),
+ undefined = ?config(cc4,Config),
+ conf5 = ?config(cc5,Config),
+ conf6 = ?config(cc6,Config),
+ ok.
+conf6_tc2(Config) when is_list(Config) ->
+ case ?config(priv_dir,Config) of
+ undefined -> exit(no_priv_dir);
+ _ -> ok
+ end,
+ conf5 = ?config(cc5,Config),
+ conf6 = ?config(cc6,Config),
+ ok.
+
diff --git a/lib/test_server/test/test_server_conf02_SUITE.erl b/lib/test_server/test/test_server_conf02_SUITE.erl
new file mode 100644
index 0000000000..deba4660c6
--- /dev/null
+++ b/lib/test_server/test/test_server_conf02_SUITE.erl
@@ -0,0 +1,294 @@
+%%
+%% %CopyrightBegin%
+%%
+%% 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%
+%%
+
+%%%------------------------------------------------------------------
+%%% Test Server self test.
+%%%------------------------------------------------------------------
+-module(test_server_conf02_SUITE).
+-include_lib("test_server/include/test_server.hrl").
+
+-compile(export_all).
+
+all(doc) -> ["Test simple conf case structure, with and without nested cases"];
+all(suite) ->
+ [
+ {conf, conf1_init, [conf1_tc1, conf1_tc2], conf1_end},
+
+ {conf, [], conf2_init, [conf2_tc1, conf2_tc2], conf2_end},
+
+ {conf, conf3_init, [conf3_tc1,
+
+ {conf, [], conf4_init, [conf4_tc1, conf4_tc2], conf4_end},
+
+ conf3_tc2], conf3_end},
+
+ conf5
+ ].
+
+
+%%---------- conf cases ----------
+
+init_per_suite(Config) ->
+ case ?config(data_dir,Config) of
+ undefined -> exit(no_data_dir);
+ _ -> ok
+ end,
+ [{suite,init}|Config].
+end_per_suite(Config) ->
+ case ?config(data_dir,Config) of
+ undefined -> exit(no_data_dir);
+ _ -> ok
+ end,
+ init = ?config(suite,Config),
+ ok.
+
+init_per_testcase(TC=conf1_tc1, Config) ->
+ init = ?config(suite,Config),
+ [{tc11,TC}|Config];
+init_per_testcase(TC=conf1_tc2, Config) ->
+ [{tc12,TC}|Config];
+init_per_testcase(TC=conf2_tc1, Config) ->
+ [{tc21,TC}|Config];
+init_per_testcase(TC=conf2_tc2, Config) ->
+ [{tc22,TC}|Config];
+init_per_testcase(TC=conf3_tc1, Config) ->
+ [{tc31,TC}|Config];
+init_per_testcase(TC=conf3_tc2, Config) ->
+ [{tc32,TC}|Config];
+init_per_testcase(TC=conf4_tc1, Config) ->
+ [{tc41,TC}|Config];
+init_per_testcase(TC=conf4_tc2, Config) ->
+ [{tc42,TC}|Config];
+init_per_testcase(TC=conf5_tc1, Config) ->
+ [{tc51,TC}|Config];
+init_per_testcase(TC=conf5_tc2, Config) ->
+ [{tc52,TC}|Config];
+init_per_testcase(TC=conf6_tc1, Config) ->
+ [{tc61,TC}|Config];
+init_per_testcase(TC=conf6_tc2, Config) ->
+ init = ?config(suite,Config),
+ [{tc62,TC}|Config].
+
+end_per_testcase(TC=conf1_tc1, Config) ->
+ init = ?config(suite,Config),
+ TC = ?config(tc11,Config),
+ ok;
+end_per_testcase(TC=conf1_tc2, Config) ->
+ TC = ?config(tc12,Config),
+ ok;
+end_per_testcase(TC=conf2_tc1, Config) ->
+ TC = ?config(tc21,Config),
+ ok;
+end_per_testcase(TC=conf2_tc2, Config) ->
+ TC = ?config(tc22,Config),
+ ok;
+end_per_testcase(TC=conf3_tc1, Config) ->
+ TC = ?config(tc31,Config),
+ ok;
+end_per_testcase(TC=conf3_tc2, Config) ->
+ TC = ?config(tc32,Config),
+ ok;
+end_per_testcase(TC=conf4_tc1, Config) ->
+ TC = ?config(tc41,Config),
+ ok;
+end_per_testcase(TC=conf4_tc2, Config) ->
+ TC = ?config(tc42,Config),
+ ok;
+end_per_testcase(TC=conf5_tc1, Config) ->
+ TC = ?config(tc51,Config),
+ ok;
+end_per_testcase(TC=conf5_tc2, Config) ->
+ TC = ?config(tc52,Config),
+ ok;
+end_per_testcase(TC=conf6_tc1, Config) ->
+ TC = ?config(tc61,Config),
+ ok;
+end_per_testcase(TC=conf6_tc2, Config) ->
+ init = ?config(suite,Config),
+ TC = ?config(tc62,Config),
+ ok.
+
+conf1_init(Config) when is_list(Config) ->
+ init = ?config(suite,Config),
+ [{cc1,conf1}|Config].
+conf1_end(_Config) ->
+ ok.
+
+conf2_init(Config) when is_list(Config) ->
+ [{cc2,conf2}|Config].
+conf2_end(_Config) ->
+ ok.
+
+conf3_init(Config) when is_list(Config) ->
+ [{cc3,conf3}|Config].
+conf3_end(_Config) ->
+ ok.
+
+conf4_init(Config) when is_list(Config) ->
+ [{cc4,conf4}|Config].
+conf4_end(_Config) ->
+ ok.
+
+conf5_init(Config) when is_list(Config) ->
+ [{cc5,conf5}|Config].
+conf5_end(_Config) ->
+ ok.
+
+conf6_init(Config) when is_list(Config) ->
+ init = ?config(suite,Config),
+ [{cc6,conf6}|Config].
+conf6_end(_Config) ->
+ ok.
+
+conf5(suite) -> % test specification
+ [{conf, conf5_init, [conf5_tc1,
+
+ {conf, [], conf6_init, [conf6_tc1, conf6_tc2], conf6_end},
+
+ conf5_tc2], conf5_end}].
+
+%%---------- test cases ----------
+
+conf1_tc1(Config) when is_list(Config) ->
+ case ?config(data_dir,Config) of
+ undefined -> exit(no_data_dir);
+ _ -> ok
+ end,
+ init = ?config(suite,Config),
+ conf1 = ?config(cc1,Config),
+ conf1_tc1 = ?config(tc11,Config),
+ ok.
+conf1_tc2(Config) when is_list(Config) ->
+ case ?config(priv_dir,Config) of
+ undefined -> exit(no_priv_dir);
+ _ -> ok
+ end,
+ init = ?config(suite,Config),
+ conf1 = ?config(cc1,Config),
+ conf1_tc2 = ?config(tc12,Config),
+ ok.
+
+conf2_tc1(Config) when is_list(Config) ->
+ init = ?config(suite,Config),
+ undefined = ?config(cc1,Config),
+ undefined = ?config(tc11,Config),
+ conf2 = ?config(cc2,Config),
+ conf2_tc1 = ?config(tc21,Config),
+ ok.
+conf2_tc2(Config) when is_list(Config) ->
+ init = ?config(suite,Config),
+ conf2 = ?config(cc2,Config),
+ undefined = ?config(tc21,Config),
+ conf2_tc2 = ?config(tc22,Config),
+ ok.
+
+conf3_tc1(Config) when is_list(Config) ->
+ init = ?config(suite,Config),
+ undefined = ?config(cc2,Config),
+ undefined = ?config(tc22,Config),
+ conf3 = ?config(cc3,Config),
+ conf3_tc1 = ?config(tc31,Config),
+ ok.
+conf3_tc2(Config) when is_list(Config) ->
+ init = ?config(suite,Config),
+ conf3 = ?config(cc3,Config),
+ undefined = ?config(cc4,Config),
+ undefined = ?config(tc31,Config),
+ undefined = ?config(tc41,Config),
+ conf3_tc2 = ?config(tc32,Config),
+ ok.
+
+conf4_tc1(Config) when is_list(Config) ->
+ init = ?config(suite,Config),
+ case ?config(data_dir,Config) of
+ undefined -> exit(no_data_dir);
+ _ -> ok
+ end,
+ undefined = ?config(cc1,Config),
+ undefined = ?config(cc2,Config),
+ conf3 = ?config(cc3,Config),
+ conf4 = ?config(cc4,Config),
+ undefined = ?config(tc32,Config),
+ conf4_tc1 = ?config(tc41,Config),
+ ok.
+conf4_tc2(Config) when is_list(Config) ->
+ init = ?config(suite,Config),
+ case ?config(priv_dir,Config) of
+ undefined -> exit(no_priv_dir);
+ _ -> ok
+ end,
+ conf3 = ?config(cc3,Config),
+ conf4 = ?config(cc4,Config),
+ undefined = ?config(tc41,Config),
+ conf4_tc2 = ?config(tc42,Config),
+ ok.
+
+conf5_tc1(Config) when is_list(Config) ->
+ init = ?config(suite,Config),
+ case ?config(data_dir,Config) of
+ undefined -> exit(no_data_dir);
+ _ -> ok
+ end,
+ undefined = ?config(cc1,Config),
+ undefined = ?config(cc2,Config),
+ undefined = ?config(cc3,Config),
+ undefined = ?config(cc4,Config),
+ conf5 = ?config(cc5,Config),
+ undefined = ?config(tc42,Config),
+ conf5_tc1 = ?config(tc51,Config),
+ ok.
+conf5_tc2(Config) when is_list(Config) ->
+ init = ?config(suite,Config),
+ case ?config(priv_dir,Config) of
+ undefined -> exit(no_priv_dir);
+ _ -> ok
+ end,
+ conf5 = ?config(cc5,Config),
+ undefined = ?config(cc6,Config),
+ undefined = ?config(tc51,Config),
+ undefined = ?config(tc62,Config),
+ conf5_tc2 = ?config(tc52,Config),
+ ok.
+
+conf6_tc1(Config) when is_list(Config) ->
+ init = ?config(suite,Config),
+ case ?config(data_dir,Config) of
+ undefined -> exit(no_data_dir);
+ _ -> ok
+ end,
+ undefined = ?config(cc1,Config),
+ undefined = ?config(cc2,Config),
+ undefined = ?config(cc3,Config),
+ undefined = ?config(cc4,Config),
+ conf5 = ?config(cc5,Config),
+ conf6 = ?config(cc6,Config),
+ undefined = ?config(tc52,Config),
+ conf6_tc1 = ?config(tc61,Config),
+ ok.
+conf6_tc2(Config) when is_list(Config) ->
+ init = ?config(suite,Config),
+ case ?config(priv_dir,Config) of
+ undefined -> exit(no_priv_dir);
+ _ -> ok
+ end,
+ conf5 = ?config(cc5,Config),
+ conf6 = ?config(cc6,Config),
+ undefined = ?config(tc61,Config),
+ conf6_tc2 = ?config(tc62,Config),
+ ok.
diff --git a/lib/test_server/test/test_server_line_SUITE.erl b/lib/test_server/test/test_server_line_SUITE.erl
new file mode 100644
index 0000000000..02897f164f
--- /dev/null
+++ b/lib/test_server/test/test_server_line_SUITE.erl
@@ -0,0 +1,122 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 2004-2010. All Rights Reserved.
+%%
+%% The contents of this file are subject to the Erlang Public License,
+%% Version 1.1, (the "License"); you may not use this file except in
+%% compliance with the License. You should have received a copy of the
+%% Erlang Public License along with this software. If not, it can be
+%% retrieved online at http://www.erlang.org/.
+%%
+%% Software distributed under the License is distributed on an "AS IS"
+%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+%% the License for the specific language governing rights and limitations
+%% under the License.
+%%
+%% %CopyrightEnd%
+%%
+
+%%%------------------------------------------------------------------
+%%% Test Server self test.
+%%%------------------------------------------------------------------
+-module(test_server_line_SUITE).
+-include_lib("test_server/include/test_server.hrl").
+
+-export([all/1]).
+-export([init_per_testcase/2, fin_per_testcase/2]).
+-export([parse_transform/1, lines/1]).
+
+all(doc) -> ["Test of parse transform for collection line numbers"];
+all(suite) -> [parse_transform,lines].
+
+
+init_per_testcase(_Case, Config) ->
+ ?line test_server_line:clear(),
+ Dog = ?t:timetrap(?t:minutes(2)),
+ [{watchdog, Dog}|Config].
+
+fin_per_testcase(_Case, Config) ->
+ ?line test_server_line:clear(),
+ Dog=?config(watchdog, Config),
+ ?t:timetrap_cancel(Dog),
+ ok.
+
+parse_transform(suite) -> [];
+parse_transform(doc) -> [];
+parse_transform(Config) when is_list(Config) ->
+ ?line DataDir = ?config(data_dir,Config),
+ code:add_pathz(DataDir),
+
+ ?line ok = parse_transform_test:excluded(),
+ ?line [] = test_server_line:get_lines(),
+
+ ?line test_server_line:clear(),
+ ?line ok = parse_transform_test:func(),
+
+ ?line [{parse_transform_test,func4,58},
+ {parse_transform_test,func,49},
+ {parse_transform_test,func3,56},
+ {parse_transform_test,func,39},
+ {parse_transform_test,func2,54},
+ {parse_transform_test,func,36},
+ {parse_transform_test,func1,52},
+ {parse_transform_test,func,35}] = test_server_line:get_lines(),
+
+ code:del_path(DataDir),
+ ok.
+
+lines(suite) -> [];
+lines(doc) -> ["Test parse transform for collection line numbers"];
+lines(Config) when is_list(Config) ->
+ ?line L0 = [{mod,func,1},{mod,func,2},{mod,func,3},
+ {m,f,4},{m,f,5},{m,f,6},
+ {mo,fu,7},{mo,fu,8},{mo,fu,9}],
+ ?line LL = string:copies(L0, 1000),
+ ?line T1 = erlang:now(),
+ ?line lists:foreach(fun ({M,F,L}) ->
+ test_server_line:'$test_server_line'(M, F, L)
+ end, LL),
+ ?line T2 = erlang:now(),
+ ?line Long = test_server_line:get_lines(),
+ ?line test_server_line:clear(),
+
+ ?line T3 = erlang:now(),
+ ?line lists:foreach(fun ({M,F,L}) ->
+ test_server_line:'$test_server_lineQ'(M, F, L)
+ end, LL),
+ ?line T4 = erlang:now(),
+ ?line LongQ = test_server_line:get_lines(),
+
+ ?line io:format("'$test_server_line': ~f~n'$test_server_lineQ': ~f~n",
+ [timer:now_diff(T2, T1)/1000, timer:now_diff(T4, T3)/1000]),
+ ?line io:format("'$test_server_line' result long:~p~n", [Long]),
+ ?line io:format("'$test_server_lineQ' result long:~p~n", [LongQ]),
+
+ if Long =:= LongQ ->
+ ?line ok;
+ true ->
+ ?line ?t:fail("The two methods did not produce same result for"
+ " long lists of lines")
+ end,
+
+ ?line test_server_line:clear(),
+ ?line lists:foreach(fun ({M,F,L}) ->
+ test_server_line:'$test_server_line'(M, F, L)
+ end, L0),
+ ?line Short = test_server_line:get_lines(),
+ ?line test_server_line:clear(),
+ ?line lists:foreach(fun ({M,F,L}) ->
+ test_server_line:'$test_server_lineQ'(M, F, L)
+ end, L0),
+ ?line ShortQ = test_server_line:get_lines(),
+
+ ?line io:format("'$test_server_line' result short:~p~n", [Short]),
+ ?line io:format("'$test_server_lineQ' result short:~p~n", [ShortQ]),
+
+ if Short =:= ShortQ ->
+ ?line ok;
+ true ->
+ ?line ?t:fail("The two methods did not produce same result for"
+ " shot lists of lines\n")
+ end.
diff --git a/lib/test_server/test/test_server_line_SUITE_data/Makefile.src b/lib/test_server/test/test_server_line_SUITE_data/Makefile.src
new file mode 100644
index 0000000000..a077648934
--- /dev/null
+++ b/lib/test_server/test/test_server_line_SUITE_data/Makefile.src
@@ -0,0 +1,6 @@
+EFLAGS=+debug_info -pa ../../test_server -I../../test_server
+
+all: parse_transform_test.@EMULATOR@
+
+parse_transform_test.@EMULATOR@: parse_transform_test.erl
+ erlc $(EFLAGS) parse_transform_test.erl
diff --git a/lib/test_server/test/test_server_line_SUITE_data/parse_transform_test.erl b/lib/test_server/test/test_server_line_SUITE_data/parse_transform_test.erl
new file mode 100644
index 0000000000..c3ee1b68cd
--- /dev/null
+++ b/lib/test_server/test/test_server_line_SUITE_data/parse_transform_test.erl
@@ -0,0 +1,59 @@
+%%
+%% %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(parse_transform_test).
+
+-include("test_server_line.hrl").
+-no_lines([{excluded,0}]).
+
+-export([excluded/0, func/0]).
+
+
+excluded() ->
+ line1,
+ line2,
+ ok.
+
+
+func() ->
+ hello,
+ func1(),
+ case func2() of
+ ok ->
+ helloagain,
+ case func3() of
+ ok ->
+ ok;
+ error ->
+ error
+ end;
+ error ->
+ error
+ end,
+ excluded(),
+ func4().
+
+func1() ->
+ ok.
+func2() ->
+ ok.
+func3() ->
+ error.
+func4() ->
+ ok.
+
diff --git a/lib/test_server/test/test_server_parallel01_SUITE.erl b/lib/test_server/test/test_server_parallel01_SUITE.erl
new file mode 100644
index 0000000000..0e7f329f89
--- /dev/null
+++ b/lib/test_server/test/test_server_parallel01_SUITE.erl
@@ -0,0 +1,518 @@
+%%
+%% %CopyrightBegin%
+%%
+%% 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%
+%%
+
+%%%------------------------------------------------------------------
+%%% Test Server self test.
+%%%------------------------------------------------------------------
+-module(test_server_parallel01_SUITE).
+-include_lib("test_server/include/test_server.hrl").
+
+-compile(export_all).
+
+%% -------------------------------------------------------------------
+%% Notes on parallel execution of test cases
+%% -------------------------------------------------------------------
+%%
+%% A group nested under a parallel group will start executing in
+%% parallel with previous (parallel) test cases (no matter what
+%% properties the nested group has). Test cases are however never
+%% executed in parallel with the start or end conf case of the same
+%% group! Because of this, the test_server_ctrl loop waits at
+%% the end conf of a group for all parallel cases to finish
+%% before the end conf case actually executes. This has the effect
+%% that it's only after a nested group has finished that any
+%% remaining parallel cases in the previous group get spawned (*).
+%% Example (all parallel cases):
+%%
+%% group1_init |---->
+%% group1_case1 | --------->
+%% group1_case2 | --------------------------------->
+%% group2_init | ---->
+%% group2_case1 | ------>
+%% group2_case2 | ---------->
+%% group2_end | --->
+%% group1_case3 (*)| ---->
+%% group1_case4 (*)| -->
+%% group1_end | --->
+%%
+
+all(doc) -> ["Test simple conf case structure, with and without nested cases"];
+all(suite) ->
+ [
+ {conf, [parallel], conf1_init, [conf1_tc1, conf1_tc2], conf1_end},
+
+ {conf, [parallel], conf2_init, [conf2_tc1, conf2_tc2], conf2_end},
+
+ {conf, [parallel], conf3_init, [conf3_tc1, conf3_tc1,
+
+ {conf, [],
+ conf4_init, [conf4_tc1, conf4_tc2], conf4_end},
+
+ conf3_tc2], conf3_end},
+
+ conf5,
+
+ {conf, [parallel], conf7_init, [conf7_tc1, conf7_tc1,
+
+ {conf, [parallel],
+ conf8_init, [conf8_tc1, conf8_tc2], conf8_end},
+
+ conf7_tc2], conf7_end}
+
+ ].
+
+
+%%---------- conf cases ----------
+
+init_per_suite(Config) ->
+ case ?config(data_dir,Config) of
+ undefined -> exit(no_data_dir);
+ _ -> ok
+ end,
+ [{suite,init}|Config].
+end_per_suite(Config) ->
+ case ?config(data_dir,Config) of
+ undefined -> exit(no_data_dir);
+ _ -> ok
+ end,
+ init = ?config(suite,Config),
+ ok.
+
+init_per_testcase(TC=conf1_tc1, Config) ->
+ init = ?config(suite,Config),
+ [{tc11,TC}|Config];
+init_per_testcase(TC=conf1_tc2, Config) ->
+ [{tc12,TC}|Config];
+init_per_testcase(TC=conf2_tc1, Config) ->
+ [{tc21,TC}|Config];
+init_per_testcase(TC=conf2_tc2, Config) ->
+ [{tc22,TC}|Config];
+init_per_testcase(TC=conf3_tc1, Config) ->
+ [{tc31,TC}|Config];
+init_per_testcase(TC=conf3_tc2, Config) ->
+ [{tc32,TC}|Config];
+init_per_testcase(TC=conf4_tc1, Config) ->
+ [{tc41,TC}|Config];
+init_per_testcase(TC=conf4_tc2, Config) ->
+ [{tc42,TC}|Config];
+init_per_testcase(TC=conf5_tc1, Config) ->
+ [{tc51,TC}|Config];
+init_per_testcase(TC=conf5_tc2, Config) ->
+ [{tc52,TC}|Config];
+init_per_testcase(TC=conf6_tc1, Config) ->
+ [{tc61,TC}|Config];
+init_per_testcase(TC=conf6_tc2, Config) ->
+ init = ?config(suite,Config),
+ [{tc62,TC}|Config];
+init_per_testcase(TC=conf7_tc1, Config) ->
+ [{tc71,TC}|Config];
+init_per_testcase(TC=conf7_tc2, Config) ->
+ [{tc72,TC}|Config];
+init_per_testcase(TC=conf8_tc1, Config) ->
+ [{tc81,TC}|Config];
+init_per_testcase(TC=conf8_tc2, Config) ->
+ init = ?config(suite,Config),
+ [{tc82,TC}|Config].
+
+end_per_testcase(TC=conf1_tc1, Config) ->
+ init = ?config(suite,Config),
+ TC = ?config(tc11,Config),
+ ok;
+end_per_testcase(TC=conf1_tc2, Config) ->
+ TC = ?config(tc12,Config),
+ ok;
+end_per_testcase(TC=conf2_tc1, Config) ->
+ TC = ?config(tc21,Config),
+ ok;
+end_per_testcase(TC=conf2_tc2, Config) ->
+ TC = ?config(tc22,Config),
+ ok;
+end_per_testcase(TC=conf3_tc1, Config) ->
+ TC = ?config(tc31,Config),
+ ok;
+end_per_testcase(TC=conf3_tc2, Config) ->
+ TC = ?config(tc32,Config),
+ ok;
+end_per_testcase(TC=conf4_tc1, Config) ->
+ TC = ?config(tc41,Config),
+ ok;
+end_per_testcase(TC=conf4_tc2, Config) ->
+ TC = ?config(tc42,Config),
+ ok;
+end_per_testcase(TC=conf5_tc1, Config) ->
+ TC = ?config(tc51,Config),
+ ok;
+end_per_testcase(TC=conf5_tc2, Config) ->
+ TC = ?config(tc52,Config),
+ ok;
+end_per_testcase(TC=conf6_tc1, Config) ->
+ TC = ?config(tc61,Config),
+ ok;
+end_per_testcase(TC=conf6_tc2, Config) ->
+ init = ?config(suite,Config),
+ TC = ?config(tc62,Config),
+ ok;
+end_per_testcase(TC=conf7_tc1, Config) ->
+ TC = ?config(tc71,Config),
+ ok;
+end_per_testcase(TC=conf7_tc2, Config) ->
+ TC = ?config(tc72,Config),
+ ok;
+end_per_testcase(TC=conf8_tc1, Config) ->
+ TC = ?config(tc81,Config),
+ ok;
+end_per_testcase(TC=conf8_tc2, Config) ->
+ init = ?config(suite,Config),
+ TC = ?config(tc82,Config),
+ ok.
+
+conf1_init(Config) when is_list(Config) ->
+ test_server:comment(io_lib:format("~p",[now()])),
+ [parallel] = ?config(tc_group_properties,Config),
+ init = ?config(suite,Config),
+ [{t0,now()},{cc1,conf1}|Config].
+conf1_end(Config) ->
+ %% check 2s & 3s < 4s
+ Ms = timer:now_diff(now(),?config(t0,Config)),
+ test_server:comment(io_lib:format("~p",[now()])),
+ if Ms > 3500000 -> exit({bad_parallel_exec,Ms});
+ Ms < 3000000 -> exit({bad_parallel_exec,Ms});
+ true -> ok
+ end.
+
+conf2_init(Config) when is_list(Config) ->
+ test_server:comment(io_lib:format("~p",[now()])),
+ [parallel] = ?config(tc_group_properties,Config),
+ [{t0,now()},{cc2,conf2}|Config].
+conf2_end(Config) ->
+ %% check 3s & 2s < 4s
+ Ms = timer:now_diff(now(),?config(t0,Config)),
+ test_server:comment(io_lib:format("~p",[now()])),
+ if Ms > 3500000 -> exit({bad_parallel_exec,Ms});
+ Ms < 3000000 -> exit({bad_parallel_exec,Ms});
+ true -> ok
+ end.
+
+conf3_init(Config) when is_list(Config) ->
+ test_server:comment(io_lib:format("~p",[now()])),
+ [parallel] = ?config(tc_group_properties,Config),
+ [{t0,now()},{cc3,conf3}|Config].
+conf3_end(Config) ->
+ %% check 6s & 6s & (2s & 3s) & 1s = ~6s
+ Ms = timer:now_diff(now(),?config(t0,Config)),
+ test_server:comment(io_lib:format("~p",[now()])),
+ if Ms > 6500000 -> exit({bad_parallel_exec,Ms});
+ Ms < 6000000 -> exit({bad_parallel_exec,Ms});
+ true -> ok
+ end.
+
+conf4_init(Config) when is_list(Config) ->
+ test_server:comment(io_lib:format("~p",[now()])),
+ [] = ?config(tc_group_properties,Config),
+ [{t0,now()},{cc4,conf4}|Config].
+conf4_end(Config) ->
+ %% check 2s & 3s >= 5s
+ Ms = timer:now_diff(now(),?config(t0,Config)),
+ test_server:comment(io_lib:format("~p",[now()])),
+ if Ms > 5500000 -> exit({bad_parallel_exec,Ms});
+ Ms < 5000000 -> exit({bad_parallel_exec,Ms});
+ true -> ok
+ end.
+
+conf5_init(Config) when is_list(Config) ->
+ test_server:comment(io_lib:format("~p",[now()])),
+ [] = ?config(tc_group_properties,Config),
+ [{t0,now()},{cc5,conf5}|Config].
+conf5_end(Config) ->
+ %% check 1s & 1s & (3s & 2s) & 1s = ~6s
+ Ms = timer:now_diff(now(),?config(t0,Config)),
+ test_server:comment(io_lib:format("~p",[now()])),
+ if Ms > 7000000 -> exit({bad_parallel_exec,Ms});
+ Ms < 6000000 -> exit({bad_parallel_exec,Ms});
+ true -> ok
+ end.
+
+conf6_init(Config) when is_list(Config) ->
+ test_server:comment(io_lib:format("~p",[now()])),
+ [parallel] = ?config(tc_group_properties,Config),
+ init = ?config(suite,Config),
+ [{t0,now()},{cc6,conf6}|Config].
+conf6_end(Config) ->
+ %% check 3s & 2s < 5s
+ Ms = timer:now_diff(now(),?config(t0,Config)),
+ test_server:comment(io_lib:format("~p",[now()])),
+ if Ms > 3500000 -> exit({bad_parallel_exec,Ms});
+ Ms < 3000000 -> exit({bad_parallel_exec,Ms});
+ true -> ok
+ end.
+
+conf5(suite) -> % test specification
+ [{conf, conf5_init, [conf5_tc1, conf5_tc1,
+
+ {conf, [parallel], conf6_init, [conf6_tc1, conf6_tc2], conf6_end},
+
+ conf5_tc2], conf5_end}].
+
+conf7_init(Config) when is_list(Config) ->
+ test_server:comment(io_lib:format("~p",[now()])),
+ [parallel] = ?config(tc_group_properties,Config),
+ [{t0,now()},{cc7,conf7}|Config].
+conf7_end(Config) ->
+ %% check 1s & 1s & (2s & 2s) & 1s = ~3s
+ Ms = timer:now_diff(now(),?config(t0,Config)),
+ test_server:comment(io_lib:format("~p",[now()])),
+ if Ms > 3500000 -> exit({bad_parallel_exec,Ms});
+ Ms < 3000000 -> exit({bad_parallel_exec,Ms});
+ true -> ok
+ end.
+
+conf8_init(Config) when is_list(Config) ->
+ test_server:comment(io_lib:format("~p",[now()])),
+ [parallel] = ?config(tc_group_properties,Config),
+ init = ?config(suite,Config),
+ [{t0,now()},{cc8,conf8}|Config].
+conf8_end(Config) ->
+ %% check 2s & 2s < 4s
+ Ms = timer:now_diff(now(),?config(t0,Config)),
+ test_server:comment(io_lib:format("~p",[now()])),
+ if Ms > 2500000 -> exit({bad_parallel_exec,Ms});
+ Ms < 2000000 -> exit({bad_parallel_exec,Ms});
+ true -> ok
+ end.
+
+
+%%---------- test cases ----------
+
+conf1_tc1(Config) when is_list(Config) ->
+ case ?config(data_dir,Config) of
+ undefined -> exit(no_data_dir);
+ _ -> ok
+ end,
+ init = ?config(suite,Config),
+ conf1 = ?config(cc1,Config),
+ conf1_tc1 = ?config(tc11,Config),
+ timer:sleep(2000),
+ test_server:comment(io_lib:format("~p",[now()])),
+ ok.
+conf1_tc2(Config) when is_list(Config) ->
+ case ?config(priv_dir,Config) of
+ undefined -> exit(no_priv_dir);
+ _ -> ok
+ end,
+ init = ?config(suite,Config),
+ conf1 = ?config(cc1,Config),
+ conf1_tc2 = ?config(tc12,Config),
+ timer:sleep(3000),
+ test_server:comment(io_lib:format("~p",[now()])),
+ ok.
+
+conf2_tc1(Config) when is_list(Config) ->
+ init = ?config(suite,Config),
+ undefined = ?config(cc1,Config),
+ undefined = ?config(tc11,Config),
+ conf2 = ?config(cc2,Config),
+ conf2_tc1 = ?config(tc21,Config),
+ timer:sleep(3000),
+ test_server:comment(io_lib:format("~p",[now()])),
+ ok.
+conf2_tc2(Config) when is_list(Config) ->
+ init = ?config(suite,Config),
+ conf2 = ?config(cc2,Config),
+ undefined = ?config(tc21,Config),
+ conf2_tc2 = ?config(tc22,Config),
+ timer:sleep(2000),
+ test_server:comment(io_lib:format("~p",[now()])),
+ ok.
+
+conf3_tc1(Config) when is_list(Config) ->
+ init = ?config(suite,Config),
+ undefined = ?config(cc2,Config),
+ undefined = ?config(tc22,Config),
+ conf3 = ?config(cc3,Config),
+ conf3_tc1 = ?config(tc31,Config),
+ timer:sleep(6000),
+ test_server:comment(io_lib:format("~p",[now()])),
+ ok.
+conf3_tc2(Config) when is_list(Config) ->
+ init = ?config(suite,Config),
+ conf3 = ?config(cc3,Config),
+ undefined = ?config(cc4,Config),
+ undefined = ?config(tc31,Config),
+ undefined = ?config(tc41,Config),
+ conf3_tc2 = ?config(tc32,Config),
+ timer:sleep(1000),
+ test_server:comment(io_lib:format("~p",[now()])),
+ ok.
+
+conf4_tc1(Config) when is_list(Config) ->
+ init = ?config(suite,Config),
+ case ?config(data_dir,Config) of
+ undefined -> exit(no_data_dir);
+ _ -> ok
+ end,
+ undefined = ?config(cc1,Config),
+ undefined = ?config(cc2,Config),
+ conf3 = ?config(cc3,Config),
+ conf4 = ?config(cc4,Config),
+ undefined = ?config(tc32,Config),
+ conf4_tc1 = ?config(tc41,Config),
+ timer:sleep(2000),
+ test_server:comment(io_lib:format("~p",[now()])),
+ ok.
+conf4_tc2(Config) when is_list(Config) ->
+ init = ?config(suite,Config),
+ case ?config(priv_dir,Config) of
+ undefined -> exit(no_priv_dir);
+ _ -> ok
+ end,
+ conf3 = ?config(cc3,Config),
+ conf4 = ?config(cc4,Config),
+ undefined = ?config(tc41,Config),
+ conf4_tc2 = ?config(tc42,Config),
+ timer:sleep(3000),
+ test_server:comment(io_lib:format("~p",[now()])),
+ ok.
+
+conf5_tc1(Config) when is_list(Config) ->
+ init = ?config(suite,Config),
+ case ?config(data_dir,Config) of
+ undefined -> exit(no_data_dir);
+ _ -> ok
+ end,
+ undefined = ?config(cc1,Config),
+ undefined = ?config(cc2,Config),
+ undefined = ?config(cc3,Config),
+ undefined = ?config(cc4,Config),
+ conf5 = ?config(cc5,Config),
+ undefined = ?config(tc42,Config),
+ conf5_tc1 = ?config(tc51,Config),
+ timer:sleep(1000),
+ test_server:comment(io_lib:format("~p",[now()])),
+ ok.
+conf5_tc2(Config) when is_list(Config) ->
+ init = ?config(suite,Config),
+ case ?config(priv_dir,Config) of
+ undefined -> exit(no_priv_dir);
+ _ -> ok
+ end,
+ conf5 = ?config(cc5,Config),
+ undefined = ?config(cc6,Config),
+ undefined = ?config(tc51,Config),
+ undefined = ?config(tc62,Config),
+ conf5_tc2 = ?config(tc52,Config),
+ timer:sleep(1000),
+ test_server:comment(io_lib:format("~p",[now()])),
+ ok.
+
+conf6_tc1(Config) when is_list(Config) ->
+ init = ?config(suite,Config),
+ case ?config(data_dir,Config) of
+ undefined -> exit(no_data_dir);
+ _ -> ok
+ end,
+ undefined = ?config(cc1,Config),
+ undefined = ?config(cc2,Config),
+ undefined = ?config(cc3,Config),
+ undefined = ?config(cc4,Config),
+ conf5 = ?config(cc5,Config),
+ conf6 = ?config(cc6,Config),
+ undefined = ?config(tc52,Config),
+ conf6_tc1 = ?config(tc61,Config),
+ timer:sleep(3000),
+ test_server:comment(io_lib:format("~p",[now()])),
+ ok.
+conf6_tc2(Config) when is_list(Config) ->
+ init = ?config(suite,Config),
+ case ?config(priv_dir,Config) of
+ undefined -> exit(no_priv_dir);
+ _ -> ok
+ end,
+ conf5 = ?config(cc5,Config),
+ conf6 = ?config(cc6,Config),
+ undefined = ?config(tc61,Config),
+ conf6_tc2 = ?config(tc62,Config),
+ timer:sleep(2000),
+ test_server:comment(io_lib:format("~p",[now()])),
+ ok.
+
+conf7_tc1(Config) when is_list(Config) ->
+ init = ?config(suite,Config),
+ case ?config(data_dir,Config) of
+ undefined -> exit(no_data_dir);
+ _ -> ok
+ end,
+ undefined = ?config(cc1,Config),
+ undefined = ?config(cc2,Config),
+ undefined = ?config(cc3,Config),
+ undefined = ?config(cc4,Config),
+ undefined = ?config(cc5,Config),
+ undefined = ?config(cc6,Config),
+ conf7 = ?config(cc7,Config),
+ undefined = ?config(tc62,Config),
+ conf7_tc1 = ?config(tc71,Config),
+ timer:sleep(1000),
+ test_server:comment(io_lib:format("~p",[now()])),
+ ok.
+conf7_tc2(Config) when is_list(Config) ->
+ init = ?config(suite,Config),
+ case ?config(priv_dir,Config) of
+ undefined -> exit(no_priv_dir);
+ _ -> ok
+ end,
+ conf7 = ?config(cc7,Config),
+ undefined = ?config(cc8,Config),
+ undefined = ?config(tc71,Config),
+ undefined = ?config(tc82,Config),
+ conf7_tc2 = ?config(tc72,Config),
+ timer:sleep(1000),
+ test_server:comment(io_lib:format("~p",[now()])),
+ ok.
+
+conf8_tc1(Config) when is_list(Config) ->
+ init = ?config(suite,Config),
+ case ?config(data_dir,Config) of
+ undefined -> exit(no_data_dir);
+ _ -> ok
+ end,
+ undefined = ?config(cc1,Config),
+ undefined = ?config(cc2,Config),
+ undefined = ?config(cc3,Config),
+ undefined = ?config(cc4,Config),
+ undefined = ?config(cc5,Config),
+ undefined = ?config(cc6,Config),
+ conf7 = ?config(cc7,Config),
+ conf8 = ?config(cc8,Config),
+ undefined = ?config(tc72,Config),
+ conf8_tc1 = ?config(tc81,Config),
+ timer:sleep(2000),
+ test_server:comment(io_lib:format("~p",[now()])),
+ ok.
+conf8_tc2(Config) when is_list(Config) ->
+ init = ?config(suite,Config),
+ case ?config(priv_dir,Config) of
+ undefined -> exit(no_priv_dir);
+ _ -> ok
+ end,
+ conf7 = ?config(cc7,Config),
+ conf8 = ?config(cc8,Config),
+ undefined = ?config(tc81,Config),
+ conf8_tc2 = ?config(tc82,Config),
+ timer:sleep(2000),
+ test_server:comment(io_lib:format("~p",[now()])),
+ ok.
diff --git a/lib/test_server/test/test_server_shuffle01_SUITE.erl b/lib/test_server/test/test_server_shuffle01_SUITE.erl
new file mode 100644
index 0000000000..7ad269501d
--- /dev/null
+++ b/lib/test_server/test/test_server_shuffle01_SUITE.erl
@@ -0,0 +1,471 @@
+%%
+%% %CopyrightBegin%
+%%
+%% 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%
+%%
+
+%%%------------------------------------------------------------------
+%%% Test Server self test.
+%%%------------------------------------------------------------------
+-module(test_server_shuffle01_SUITE).
+-include_lib("test_server/include/test_server.hrl").
+
+-compile(export_all).
+
+all(doc) -> ["Test simple conf case structure, with and without nested cases"];
+all(suite) ->
+ [
+ {conf, [shuffle], conf1_init, [conf1_tc1, conf1_tc2, conf1_tc3], conf1_end},
+
+ {conf, [{shuffle,{1,2,3}}], conf2_init, [conf2_tc1, conf2_tc2, conf2_tc3], conf2_end},
+
+ {conf, [shuffle], conf3_init, [conf3_tc1, conf3_tc2, conf3_tc3,
+
+ {conf, [], conf4_init,
+ [conf4_tc1, conf4_tc2], conf4_end}],
+ conf3_end},
+
+ conf5,
+
+ {conf, [shuffle,{repeat,5},parallel], conf7_init, [conf7_tc1,
+
+ {conf, [{shuffle,{3,2,1}},{repeat,3}],
+ conf8_init, [conf8_tc1, conf8_tc2, conf8_tc3],
+ conf8_end},
+
+ conf7_tc2, conf7_tc3], conf7_end}
+
+ ].
+
+
+%%---------- conf cases ----------
+
+init_per_suite(Config) ->
+ case ?config(data_dir,Config) of
+ undefined -> exit(no_data_dir);
+ _ -> ok
+ end,
+ [{suite,init}|Config].
+end_per_suite(Config) ->
+ case ?config(data_dir,Config) of
+ undefined -> exit(no_data_dir);
+ _ -> ok
+ end,
+ init = ?config(suite,Config),
+ ok.
+
+init_per_testcase(TC=conf1_tc1, Config) ->
+ init = ?config(suite,Config),
+ [{tc11,TC}|Config];
+init_per_testcase(TC=conf1_tc2, Config) ->
+ [{tc12,TC}|Config];
+init_per_testcase(TC=conf1_tc3, Config) ->
+ [{tc13,TC}|Config];
+init_per_testcase(TC=conf2_tc1, Config) ->
+ [{tc21,TC}|Config];
+init_per_testcase(TC=conf2_tc2, Config) ->
+ [{tc22,TC}|Config];
+init_per_testcase(TC=conf2_tc3, Config) ->
+ [{tc23,TC}|Config];
+init_per_testcase(TC=conf3_tc1, Config) ->
+ [{tc31,TC}|Config];
+init_per_testcase(TC=conf3_tc2, Config) ->
+ [{tc32,TC}|Config];
+init_per_testcase(TC=conf3_tc3, Config) ->
+ [{tc33,TC}|Config];
+init_per_testcase(TC=conf4_tc1, Config) ->
+ [{tc41,TC}|Config];
+init_per_testcase(TC=conf4_tc2, Config) ->
+ [{tc42,TC}|Config];
+init_per_testcase(TC=conf5_tc1, Config) ->
+ [{tc51,TC}|Config];
+init_per_testcase(TC=conf5_tc2, Config) ->
+ [{tc52,TC}|Config];
+init_per_testcase(TC=conf6_tc1, Config) ->
+ [{tc61,TC}|Config];
+init_per_testcase(TC=conf6_tc2, Config) ->
+ init = ?config(suite,Config),
+ [{tc62,TC}|Config];
+init_per_testcase(TC=conf6_tc3, Config) ->
+ [{tc63,TC}|Config];
+init_per_testcase(TC=conf7_tc1, Config) ->
+ [{tc71,TC}|Config];
+init_per_testcase(TC=conf7_tc2, Config) ->
+ [{tc72,TC}|Config];
+init_per_testcase(TC=conf7_tc3, Config) ->
+ [{tc73,TC}|Config];
+init_per_testcase(TC=conf8_tc1, Config) ->
+ [{tc81,TC}|Config];
+init_per_testcase(TC=conf8_tc2, Config) ->
+ init = ?config(suite,Config),
+ [{tc82,TC}|Config];
+init_per_testcase(TC=conf8_tc3, Config) ->
+ [{tc83,TC}|Config].
+
+end_per_testcase(TC=conf1_tc1, Config) ->
+ init = ?config(suite,Config),
+ TC = ?config(tc11,Config),
+ ok;
+end_per_testcase(TC=conf1_tc2, Config) ->
+ TC = ?config(tc12,Config),
+ ok;
+end_per_testcase(TC=conf1_tc3, Config) ->
+ TC = ?config(tc13,Config),
+ ok;
+end_per_testcase(TC=conf2_tc1, Config) ->
+ TC = ?config(tc21,Config),
+ ok;
+end_per_testcase(TC=conf2_tc2, Config) ->
+ TC = ?config(tc22,Config),
+ ok;
+end_per_testcase(TC=conf2_tc3, Config) ->
+ TC = ?config(tc23,Config),
+ ok;
+end_per_testcase(TC=conf3_tc1, Config) ->
+ TC = ?config(tc31,Config),
+ ok;
+end_per_testcase(TC=conf3_tc2, Config) ->
+ TC = ?config(tc32,Config),
+ ok;
+end_per_testcase(TC=conf3_tc3, Config) ->
+ TC = ?config(tc33,Config),
+ ok;
+end_per_testcase(TC=conf4_tc1, Config) ->
+ TC = ?config(tc41,Config),
+ ok;
+end_per_testcase(TC=conf4_tc2, Config) ->
+ TC = ?config(tc42,Config),
+ ok;
+end_per_testcase(TC=conf5_tc1, Config) ->
+ TC = ?config(tc51,Config),
+ ok;
+end_per_testcase(TC=conf5_tc2, Config) ->
+ TC = ?config(tc52,Config),
+ ok;
+end_per_testcase(TC=conf6_tc1, Config) ->
+ TC = ?config(tc61,Config),
+ ok;
+end_per_testcase(TC=conf6_tc2, Config) ->
+ init = ?config(suite,Config),
+ TC = ?config(tc62,Config),
+ ok;
+end_per_testcase(TC=conf6_tc3, Config) ->
+ TC = ?config(tc63,Config),
+ ok;
+end_per_testcase(TC=conf7_tc1, Config) ->
+ TC = ?config(tc71,Config),
+ ok;
+end_per_testcase(TC=conf7_tc2, Config) ->
+ TC = ?config(tc72,Config),
+ ok;
+end_per_testcase(TC=conf7_tc3, Config) ->
+ TC = ?config(tc73,Config),
+ ok;
+end_per_testcase(TC=conf8_tc1, Config) ->
+ TC = ?config(tc81,Config),
+ ok;
+end_per_testcase(TC=conf8_tc2, Config) ->
+ init = ?config(suite,Config),
+ TC = ?config(tc82,Config),
+ ok;
+end_per_testcase(TC=conf8_tc3, Config) ->
+ TC = ?config(tc83,Config),
+ ok.
+
+
+conf1_init(Config) when is_list(Config) ->
+ init = ?config(suite,Config),
+ [{shuffle,{_,_,_}}] = ?config(tc_group_properties,Config),
+ test_server:comment("Shuffle (random seed)"),
+ [{cc1,conf1}|Config].
+conf1_end(_Config) ->
+ ok.
+
+conf2_init(Config) when is_list(Config) ->
+ [{shuffle,{1,2,3}}] = ?config(tc_group_properties,Config),
+ test_server:comment("Shuffle (user seed)"),
+ [{cc2,conf2}|Config].
+conf2_end(_Config) ->
+ ok.
+
+conf3_init(Config) when is_list(Config) ->
+ [{shuffle,{_,_,_}}] = ?config(tc_group_properties,Config),
+ test_server:comment("Shuffle (random)"),
+ [{cc3,conf3}|Config].
+conf3_end(_Config) ->
+ ok.
+
+conf4_init(Config) when is_list(Config) ->
+ [] = ?config(tc_group_properties,Config),
+ test_server:comment("No shuffle"),
+ [{cc4,conf4}|Config].
+conf4_end(_Config) ->
+ ok.
+
+conf5_init(Config) when is_list(Config) ->
+ [] = ?config(tc_group_properties,Config),
+ test_server:comment("No shuffle"),
+ [{cc5,conf5}|Config].
+conf5_end(_Config) ->
+ ok.
+
+conf6_init(Config) when is_list(Config) ->
+ [{shuffle,{_,_,_}}] = ?config(tc_group_properties,Config),
+ test_server:comment("Shuffle (random)"),
+ init = ?config(suite,Config),
+ [{cc6,conf6}|Config].
+conf6_end(_Config) ->
+ ok.
+
+conf5(suite) -> % test specification
+ [{conf, conf5_init, [conf5_tc1,
+
+ {conf, [shuffle], conf6_init,
+ [conf6_tc1, conf6_tc2, conf6_tc3],
+ conf6_end},
+
+ conf5_tc2], conf5_end}].
+
+conf7_init(Config) when is_list(Config) ->
+ test_server:comment("Group 7, Shuffle (random seed)"),
+ case proplists:get_value(shuffle,?config(tc_group_properties,Config)) of
+ {_,_,_} -> ok
+ end,
+ [{cc7,conf7}|Config].
+conf7_end(_Config) ->
+ ok.
+
+conf8_init(Config) when is_list(Config) ->
+ test_server:comment("Group 8, Shuffle (user start seed)"),
+ case proplists:get_value(shuffle,?config(tc_group_properties,Config)) of
+ {_,_,_} -> ok
+ end,
+ init = ?config(suite,Config),
+ [{cc8,conf8}|Config].
+conf8_end(_Config) ->
+ ok.
+
+
+%%---------- test cases ----------
+
+conf1_tc1(Config) when is_list(Config) ->
+ test_server:comment("Case 1"),
+ case ?config(data_dir,Config) of
+ undefined -> exit(no_data_dir);
+ _ -> ok
+ end,
+ init = ?config(suite,Config),
+ conf1 = ?config(cc1,Config),
+ conf1_tc1 = ?config(tc11,Config),
+ ok.
+conf1_tc2(Config) when is_list(Config) ->
+ test_server:comment("Case 2"),
+ case ?config(priv_dir,Config) of
+ undefined -> exit(no_priv_dir);
+ _ -> ok
+ end,
+ init = ?config(suite,Config),
+ conf1 = ?config(cc1,Config),
+ conf1_tc2 = ?config(tc12,Config),
+ ok.
+conf1_tc3(suite) -> [];
+conf1_tc3(_Config) ->
+ test_server:comment("Case 3"),
+ ok.
+
+conf2_tc1(Config) when is_list(Config) ->
+ test_server:comment("Case 1"),
+ init = ?config(suite,Config),
+ undefined = ?config(cc1,Config),
+ conf2 = ?config(cc2,Config),
+ conf2_tc1 = ?config(tc21,Config),
+ ok.
+conf2_tc2(Config) when is_list(Config) ->
+ test_server:comment("Case 2"),
+ init = ?config(suite,Config),
+ conf2 = ?config(cc2,Config),
+ conf2_tc2 = ?config(tc22,Config),
+ ok.
+conf2_tc3(suite) -> [];
+conf2_tc3(_Config) ->
+ test_server:comment("Case 3"),
+ ok.
+
+conf3_tc1(Config) when is_list(Config) ->
+ test_server:comment("Case 1"),
+ init = ?config(suite,Config),
+ undefined = ?config(cc2,Config),
+ conf3 = ?config(cc3,Config),
+ conf3_tc1 = ?config(tc31,Config),
+ ok.
+conf3_tc2(Config) when is_list(Config) ->
+ test_server:comment("Case 2"),
+ init = ?config(suite,Config),
+ conf3 = ?config(cc3,Config),
+ undefined = ?config(cc4,Config),
+ conf3_tc2 = ?config(tc32,Config),
+ ok.
+conf3_tc3(suite) -> [];
+conf3_tc3(_Config) ->
+ test_server:comment("Case 3"),
+ ok.
+
+conf4_tc1(Config) when is_list(Config) ->
+ test_server:comment("Case 1"),
+ init = ?config(suite,Config),
+ case ?config(data_dir,Config) of
+ undefined -> exit(no_data_dir);
+ _ -> ok
+ end,
+ undefined = ?config(cc1,Config),
+ undefined = ?config(cc2,Config),
+ conf3 = ?config(cc3,Config),
+ conf4 = ?config(cc4,Config),
+ conf4_tc1 = ?config(tc41,Config),
+ ok.
+conf4_tc2(Config) when is_list(Config) ->
+ test_server:comment("Case 2"),
+ init = ?config(suite,Config),
+ case ?config(priv_dir,Config) of
+ undefined -> exit(no_priv_dir);
+ _ -> ok
+ end,
+ conf3 = ?config(cc3,Config),
+ conf4 = ?config(cc4,Config),
+ conf4_tc2 = ?config(tc42,Config),
+ ok.
+
+conf5_tc1(Config) when is_list(Config) ->
+ test_server:comment("Case 1"),
+ init = ?config(suite,Config),
+ case ?config(data_dir,Config) of
+ undefined -> exit(no_data_dir);
+ _ -> ok
+ end,
+ undefined = ?config(cc1,Config),
+ undefined = ?config(cc2,Config),
+ undefined = ?config(cc3,Config),
+ undefined = ?config(cc4,Config),
+ conf5 = ?config(cc5,Config),
+ conf5_tc1 = ?config(tc51,Config),
+ ok.
+conf5_tc2(Config) when is_list(Config) ->
+ test_server:comment("Case 2"),
+ init = ?config(suite,Config),
+ case ?config(priv_dir,Config) of
+ undefined -> exit(no_priv_dir);
+ _ -> ok
+ end,
+ conf5 = ?config(cc5,Config),
+ undefined = ?config(cc6,Config),
+ conf5_tc2 = ?config(tc52,Config),
+ ok.
+
+conf6_tc1(Config) when is_list(Config) ->
+ test_server:comment("Case 1"),
+ init = ?config(suite,Config),
+ case ?config(data_dir,Config) of
+ undefined -> exit(no_data_dir);
+ _ -> ok
+ end,
+ undefined = ?config(cc1,Config),
+ undefined = ?config(cc2,Config),
+ undefined = ?config(cc3,Config),
+ undefined = ?config(cc4,Config),
+ conf5 = ?config(cc5,Config),
+ conf6 = ?config(cc6,Config),
+ conf6_tc1 = ?config(tc61,Config),
+ ok.
+conf6_tc2(Config) when is_list(Config) ->
+ test_server:comment("Case 2"),
+ init = ?config(suite,Config),
+ case ?config(priv_dir,Config) of
+ undefined -> exit(no_priv_dir);
+ _ -> ok
+ end,
+ conf5 = ?config(cc5,Config),
+ conf6 = ?config(cc6,Config),
+ conf6_tc2 = ?config(tc62,Config),
+ ok.
+conf6_tc3(suite) -> [];
+conf6_tc3(_Config) ->
+ test_server:comment("Case 3"),
+ ok.
+
+conf7_tc1(Config) when is_list(Config) ->
+ test_server:comment("Case 1"),
+ init = ?config(suite,Config),
+ case ?config(data_dir,Config) of
+ undefined -> exit(no_data_dir);
+ _ -> ok
+ end,
+ undefined = ?config(cc1,Config),
+ undefined = ?config(cc2,Config),
+ undefined = ?config(cc3,Config),
+ undefined = ?config(cc4,Config),
+ undefined = ?config(cc5,Config),
+ undefined = ?config(cc6,Config),
+ conf7 = ?config(cc7,Config),
+ conf7_tc1 = ?config(tc71,Config),
+ ok.
+conf7_tc2(Config) when is_list(Config) ->
+ test_server:comment("Case 2"),
+ init = ?config(suite,Config),
+ case ?config(priv_dir,Config) of
+ undefined -> exit(no_priv_dir);
+ _ -> ok
+ end,
+ conf7 = ?config(cc7,Config),
+ undefined = ?config(cc8,Config),
+ conf7_tc2 = ?config(tc72,Config),
+ ok.
+conf7_tc3(suite) -> [];
+conf7_tc3(_Config) ->
+ test_server:comment("Case 3"),
+ ok.
+
+conf8_tc1(Config) when is_list(Config) ->
+ test_server:comment("Case 1"),
+ init = ?config(suite,Config),
+ case ?config(data_dir,Config) of
+ undefined -> exit(no_data_dir);
+ _ -> ok
+ end,
+ undefined = ?config(cc1,Config),
+ undefined = ?config(cc2,Config),
+ undefined = ?config(cc3,Config),
+ undefined = ?config(cc4,Config),
+ undefined = ?config(cc5,Config),
+ undefined = ?config(cc6,Config),
+ conf7 = ?config(cc7,Config),
+ conf8 = ?config(cc8,Config),
+ conf8_tc1 = ?config(tc81,Config),
+ ok.
+conf8_tc2(Config) when is_list(Config) ->
+ test_server:comment("Case 2"),
+ init = ?config(suite,Config),
+ case ?config(priv_dir,Config) of
+ undefined -> exit(no_priv_dir);
+ _ -> ok
+ end,
+ conf7 = ?config(cc7,Config),
+ conf8 = ?config(cc8,Config),
+ conf8_tc2 = ?config(tc82,Config),
+ ok.
+conf8_tc3(suite) -> [];
+conf8_tc3(_Config) ->
+ test_server:comment("Case 3"),
+ ok.
diff --git a/lib/test_server/test/test_server_skip_SUITE.erl b/lib/test_server/test/test_server_skip_SUITE.erl
new file mode 100644
index 0000000000..4037e1cc0e
--- /dev/null
+++ b/lib/test_server/test/test_server_skip_SUITE.erl
@@ -0,0 +1,43 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 2004-2010. All Rights Reserved.
+%%
+%% The contents of this file are subject to the Erlang Public License,
+%% Version 1.1, (the "License"); you may not use this file except in
+%% compliance with the License. You should have received a copy of the
+%% Erlang Public License along with this software. If not, it can be
+%% retrieved online at http://www.erlang.org/.
+%%
+%% Software distributed under the License is distributed on an "AS IS"
+%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+%% the License for the specific language governing rights and limitations
+%% under the License.
+%%
+%% %CopyrightEnd%
+%%
+-module(test_server_skip_SUITE).
+
+-export([all/1, init_per_suite/1, end_per_suite/1]).
+-export([dummy/1]).
+
+-include_lib("test_server/include/test_server.hrl").
+-include_lib("test_server/include/test_server_line.hrl").
+
+all(suite) ->
+ [dummy].
+
+init_per_suite(Config) when is_list(Config) ->
+ {skip,"Skipping init_per_suite - check that \'dummy\' and"
+ " \'end_per_suite\' are also skipped"}.
+
+dummy(suite) -> [];
+dummy(doc) -> ["This testcase should never be executed"];
+dummy(Config) when is_list(Config) ->
+ ?t:fail("This testcase should be executed since"
+ " init_per_suite/1 is skipped").
+
+end_per_suite(doc) -> ["This testcase should never be executed"];
+end_per_suite(Config) when is_list(Config) ->
+ ?t:fail("end_per_suite/1 should not be executed when"
+ " init_per_suite/1 is skipped").
diff --git a/lib/test_server/vsn.mk b/lib/test_server/vsn.mk
index 8e02fde8bc..e3aac682ec 100644
--- a/lib/test_server/vsn.mk
+++ b/lib/test_server/vsn.mk
@@ -1,2 +1,2 @@
-TEST_SERVER_VSN = 3.3.5
+TEST_SERVER_VSN = 3.3.6
diff --git a/lib/tools/doc/src/Makefile b/lib/tools/doc/src/Makefile
index bab607c4bd..433f123ae5 100644
--- a/lib/tools/doc/src/Makefile
+++ b/lib/tools/doc/src/Makefile
@@ -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%
#
include $(ERL_TOP)/make/target.mk
@@ -41,6 +41,7 @@ XML_REF3_FILES = \
eprof.xml \
fprof.xml \
cprof.xml \
+ lcnt.xml \
instrument.xml \
make.xml \
tags.xml \
@@ -53,6 +54,7 @@ XML_CHAPTER_FILES = \
cover_chapter.xml \
fprof_chapter.xml \
cprof_chapter.xml \
+ lcnt_chapter.xml \
erlang_mode_chapter.xml \
xref_chapter.xml \
notes.xml \
diff --git a/lib/tools/doc/src/erlang_mode.xml b/lib/tools/doc/src/erlang_mode.xml
index 72770898c2..912c442153 100644
--- a/lib/tools/doc/src/erlang_mode.xml
+++ b/lib/tools/doc/src/erlang_mode.xml
@@ -51,7 +51,7 @@
<list type="bulleted">
<item><em><c>TAB</c></em> (<c>erlang-indent-command</c>) -
Indents the current line of code. </item>
- <item><em><c>M-C-\\</c></em> (<c>indent-region</c>) - Indents all
+ <item><em><c>M-C-\</c></em> (<c>indent-region</c>) - Indents all
lines in the region. </item>
<item><em><c>M-l</c></em> (<c>indent-for-comment</c>) - Insert a
comment character to the right of the code on the line (if
diff --git a/lib/tools/doc/src/erlang_mode_chapter.xml b/lib/tools/doc/src/erlang_mode_chapter.xml
index cf043e3302..b22c6b1809 100644
--- a/lib/tools/doc/src/erlang_mode_chapter.xml
+++ b/lib/tools/doc/src/erlang_mode_chapter.xml
@@ -74,10 +74,10 @@
environment variable is set, Emacs will look for the
<c>.emacs</c> file in the directory indicated by the
<em>HOME</em> variable. If <em>HOME</em> is not set, Emacs
- will look for the <c>.emacs</c> file in <c>C:\\ </c>.</p>
+ will look for the <c>.emacs</c> file in <c>C:\ </c>.</p>
<p>Below is a complete example of what should be added to a user's
<c>.emacs</c> provided that OTP is installed in the directory
- <c><![CDATA[C:\\Program Files\\erl<Ver>]]></c>: </p>
+ <c><![CDATA[C:\Program Files\erl<Ver>]]></c>: </p>
<code type="none"><![CDATA[
(setq load-path (cons "C:/Program Files/erl<Ver>/lib/tools-<ToolsVer>/emacs"
load-path))
@@ -87,7 +87,7 @@
]]></code>
<note>
<p>In .emacs, the slash character "/" can be used as path
- separator. But if you decide to use the backslash character "\\",
+ separator. But if you decide to use the backslash character "\",
please not that you must use double backslashes, since they are
treated as escape characters by Emacs.</p>
</note>
diff --git a/lib/tools/doc/src/lcnt.xml b/lib/tools/doc/src/lcnt.xml
new file mode 100644
index 0000000000..3c55e4e422
--- /dev/null
+++ b/lib/tools/doc/src/lcnt.xml
@@ -0,0 +1,465 @@
+<?xml version="1.0" encoding="latin1" ?>
+<!DOCTYPE erlref SYSTEM "erlref.dtd">
+
+<erlref>
+ <header>
+ <copyright>
+ <year>2009</year>
+ <year>2010</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>lcnt</title>
+ <prepared>Björn-Egil Dahlberg</prepared>
+ <responsible>nobody</responsible>
+ <docno></docno>
+ <approved>nobody</approved>
+ <checked></checked>
+ <date>2009-11-26</date>
+ <rev>PA1</rev>
+ <file>lcnt.xml</file>
+ </header>
+ <module>lcnt</module>
+ <modulesummary>A runtime system Lock Profiling tool.</modulesummary>
+ <description>
+ <p>The <c>lcnt</c> module is used to profile the internal ethread locks in the
+ Erlang Runtime System. With <c>lcnt</c> enabled, Internal counters in the
+ runtime system are updated each time a lock is taken. The counters stores
+ information about the number of acquisition tries and the number of collisions
+ that has occurred during the acquisition tries. The counters also record the
+ waiting time a lock has caused for a blocked thread when a collision has occurred.
+ </p>
+ <p>
+ The data produced by the lock counters will give an estimate on how well
+ the runtime system will behave from a parallelizable view point for the
+ scenarios tested. This tool was mainly developed to help erlang runtime
+ developers iron out potential and generic bottlenecks.
+ </p>
+ <p>Locks in the emulator are named after what type of resource they protect and where
+ in the emulator they are initialized, those are lock 'classes'. Most of those
+ locks are also instantiated several times, and given unique identifiers, to increase
+ locking granularity. Typically an instantiated lock protects a disjunct set of
+ the resource, i.e ets-tables, processes or ports. In other cases it protects a
+ specific range of a resource, e.g. <c>pix_lock</c> which protects index to process
+ mappings, and is given a unique number within the class. A unique lock in <c>lcnt</c>
+ is referenced by a name (class) and an identifier, <c>{Name, Id}</c>.
+ </p>
+ <p>Some locks in the system are static and protects global resources, for example
+ <c>bif_timers</c> and the <c>run_queue</c> locks. Other locks are dynamic and not
+ necessarily long lived, for example process locks and ets-table locks. The
+ statistics data from short lived locks can be stored separately when the locks
+ are deleted. This behavior is by default turned off to save memory but can be
+ turned on via <c>lcnt:rt_opt({copy_save, true})</c>. The <c>lcnt:apply/1,2,3</c>
+ functions enables this behavior during profiling.
+ </p>
+ </description>
+ <funcs>
+
+ <func>
+ <name>start() -> {ok, Pid} | {error, {already_started, Pid}} </name>
+ <fsummary>Starts the lock profiler server.</fsummary>
+ <type>
+ <v>Pid = pid()</v>
+ </type>
+ <desc>
+ <p>Starts the lock profiler server. The server only act as a medium for the
+ user and performs filtering and printing of data collected by <c>lcnt:collect/1</c>.
+ </p>
+ </desc>
+ </func>
+
+ <func>
+ <name>stop() -> ok</name>
+ <fsummary>Stops the lock profiler server.</fsummary>
+ <desc>
+ <p>Stops the lock profiler server.</p>
+ </desc>
+ </func>
+
+ <func>
+ <name>collect() -> ok</name>
+ <fsummary>Same as <c>collect(node())</c>.</fsummary>
+ <desc><p>Same as <c>collect(node())</c>.</p></desc>
+ </func>
+
+ <func>
+ <name>collect(Node) -> ok</name>
+ <fsummary>Collects lock statistics from the runtime system.</fsummary>
+ <type>
+ <v>Node = node()</v>
+ </type>
+ <desc>
+ <p>Collects lock statistics from the runtime system. The function starts a
+ server if it is not already started. It then populates the server with lock
+ statistics. If the server held any lock statistics data before the collect then
+ that data is lost.
+ </p>
+ <note>
+ <p>
+ When collection occurs the runtime system transitions to a single thread,
+ blocking all other threads. No other tasks will be scheduled during this
+ operation. Depending on the size of the data this might take a long time
+ (several seconds) and cause timeouts in the system.
+ </p>
+ </note>
+ </desc>
+ </func>
+
+ <func>
+ <name>clear() -> ok</name>
+ <fsummary>Same as <c>clear(node())</c>.</fsummary>
+ <desc><p>Same as <c>clear(node())</c>.</p></desc>
+ </func>
+
+ <func>
+ <name>clear(Node) -> ok</name>
+ <fsummary>Clears the internal lock statistics from runtime system.</fsummary>
+ <type>
+ <v>Node = node()</v>
+ </type>
+ <desc>
+ <p>Clears the internal lock statistics from the runtime system. This does not clear the
+ data on the server only on runtime system. All counters for static locks are zeroed,
+ all dynamic locks currently alive are zeroed and all saved locks now destroyed are removed.
+ It also resets the duration timer.
+ </p>
+ </desc>
+ </func>
+ <func>
+ <name>conflicts() -> ok</name>
+ <fsummary>Same as <c>conflicts([])</c>.</fsummary>
+ <desc><p>Same as <c>conflicts([])</c>.</p></desc>
+ </func>
+ <func>
+ <name>conflicts([Option]) -> ok</name>
+ <fsummary>Prints a list of internal lock counters.</fsummary>
+ <type>
+ <v>Option = {sort, Sort} | {reverse, bool()} | {thresholds, [Thresholds]} | {print, [Print | {Print, integer()}]} | {max_locks, MaxLocks} | {combine, bool()}</v>
+ <v>Sort = name | id | type | tries | colls | ratio | time | entry</v>
+ <v>Thresholds = {tries, integer()} | {colls, integer()} | {time, integer()}</v>
+ <v>Print = name | id | type | entry | tries | colls | ratio | time | duration</v>
+ <v>MaxLocks = integer() | none</v>
+ </type>
+ <desc>
+ <p>Prints a list of internal locks and its statistics.</p>
+ <p>For option description, see <seealso marker="#inspect/2">lcnt:inspect/2</seealso>.</p>
+ </desc>
+ </func>
+
+ <func>
+ <name>locations() -> ok</name>
+ <fsummary>Same as <c>locations([])</c>.</fsummary>
+ <desc>
+ <p>Same as <c>locations([])</c>.</p>
+ </desc>
+ </func>
+ <func>
+ <name>locations([Option]) -> ok</name>
+ <fsummary>Prints a list of internal lock counters by source code locations.</fsummary>
+ <type>
+ <v>Option = {sort, Sort} | {thresholds, [Thresholds]} | {print, [Print | {Print, integer()}]} | {max_locks, MaxLocks} | {combine, bool()}</v>
+ <v>Sort = name | id | type | tries | colls | ratio | time | entry</v>
+ <v>Thresholds = {tries, integer()} | {colls, integer()} | {time, integer()}</v>
+ <v>Print = name | id | type | entry | tries | colls | ratio | time | duration</v>
+ <v>MaxLocks = integer() | none</v>
+ </type>
+ <desc>
+ <p>Prints a list of internal lock counters by source code locations.</p>
+ <p>For option description, see <seealso marker="#inspect/2">lcnt:inspect/2</seealso>.</p>
+ </desc>
+ </func>
+
+ <func>
+ <name>inspect(Lock) -> ok</name>
+ <fsummary>Same as <c>inspect(Lock, [])</c>.</fsummary>
+ <desc><p>Same as <c>inspect(Lock, [])</c>.</p></desc>
+ </func>
+ <func>
+ <name>inspect(Lock, [Option]) -> ok</name>
+ <fsummary>Prints a list of internal lock counters for a specific lock.</fsummary>
+ <type>
+ <v>Lock = Name | {Name, Id | [Id]}</v>
+ <v>Name = atom() | pid() | port()</v>
+ <v>Id = atom() | integer() | pid() | port()</v>
+ <v>Option = {sort, Sort} | {thresholds, [Thresholds]} | {print, [Print | {Print, integer()}]} | {max_locks, MaxLocks} | {combine, bool()} | {locations, bool()}</v>
+ <v>Sort = name | id | type | tries | colls | ratio | time</v>
+ <v>Thresholds = {tries, integer()} | {colls, integer()} | {time, integer()}</v>
+ <v>Print = name | id | type | entry | tries | colls | ratio | time | duration</v>
+ <v>MaxLocks = integer() | none</v>
+ </type>
+ <desc>
+ <p>Prints a list of internal lock counters for a specific lock.</p>
+ <p>Lock <c>Name</c> and <c>Id</c> for ports and processes are interchangeable with the use of <c>lcnt:swap_pid_keys/0</c> and is the reason why <c>pid()</c> and <c>port()</c> options can be used in both <c>Name</c> and <c>Id</c> space. Both pids and ports are special identifiers with stripped creation and can be recreated with <seealso marker="#pid/3">lcnt:pid/2,3</seealso> and <seealso marker="#port/2">lcnt:port/1,2</seealso>. </p>
+ <p>Option description:</p>
+ <taglist>
+ <tag><c>{combine, bool()}</c></tag>
+ <item>Combine the statistics from different instances of a lock class.
+ <br/>Default: <c>true</c>
+ </item>
+
+ <tag><c>{locations, bool()}</c></tag>
+ <item>Print the statistics by source file and line numbers.
+ <br/>Default: <c>false</c>
+ </item>
+
+ <tag><c>{max_locks, MaxLocks}</c></tag>
+ <item>Maximum number of locks printed or no limit with <c>none</c>.
+ <br/>Default: <c>20</c>
+ </item>
+
+ <tag><c>{print, PrintOptions}</c></tag>
+ <item>Printing options:
+ <taglist>
+ <tag><c>name</c></tag>
+ <item>Named lock or named set of locks (classes). The same name used for initializing the lock in the VM.</item>
+
+ <tag><c>id</c></tag>
+ <item>Internal id for set of locks, not always unique. This could be table name for ets tables (db_tab), port id for ports, integer identifiers for allocators, etc.</item>
+
+ <tag><c>type</c></tag>
+ <item>Type of lock: <c>rw_mutex</c>, <c>mutex</c>, <c>spinlock</c>, <c>rw_spinlock</c> or <c>proclock</c>.</item>
+
+ <tag><c>entry</c></tag>
+ <item>In combination with <c>{locations, true}</c> this option prints the lock operations source file and line number entry-points along with statistics for each entry. </item>
+
+ <tag><c>tries</c></tag>
+ <item>Number of acquisitions of this lock.</item>
+
+ <tag><c>colls</c></tag>
+ <item>Number of collisions when a thread tried to acquire this lock. This is when a trylock is EBUSY, a write try on read held rw_lock, a try read on write held rw_lock, a thread tries to lock an already locked lock. (Internal states supervises this).</item>
+
+ <tag><c>ratio</c></tag>
+ <item>The ratio between the number of collisions and the number of tries (acquisitions) in percentage.</item>
+
+ <tag><c>time</c></tag>
+ <item>Accumulated waiting time for this lock. This could be greater than actual wall clock time, it is accumulated for all threads. Trylock conflicts does not accumulate time.</item>
+
+ <tag><c>duration</c></tag>
+ <item>Percentage of accumulated waiting time of wall clock time. This percentage can be higher than 100% since accumulated time is from all threads.</item>
+ </taglist>
+ <br/>Default: <c>[name,id,tries,colls,ratio,time,duration]</c>
+ </item>
+
+ <tag><c>{reverse, bool()}</c></tag>
+ <item>Reverses the order of sorting.
+ <br/>Default: <c>false</c>
+ </item>
+
+ <tag><c>{sort, Sort}</c></tag>
+ <item>Column sorting orders.
+ <br/>Default: <c>time</c>
+ </item>
+
+ <tag><c>{thresholds, Thresholds}</c></tag>
+ <item>Filtering thresholds. Anything values above the threshold value are passed through.
+ <br/>Default: <c>[{tries, 0}, {colls, 0}, {time, 0}]</c>
+ </item>
+
+ </taglist>
+
+ </desc>
+ </func>
+
+ <func>
+ <name>information() -> ok</name>
+ <fsummary>Prints lcnt server state and generic information about collected lock statistics.</fsummary>
+ <desc>
+ <p>Prints lcnt server state and generic information about collected lock statistics.</p>
+ </desc>
+ </func>
+
+ <func>
+ <name>swap_pid_keys() -> ok</name>
+ <fsummary>Swaps places on <c>Name</c> and <c>Id</c> space for ports and processes.</fsummary>
+ <desc>
+ <p>Swaps places on <c>Name</c> and <c>Id</c> space for ports and processes.</p>
+ </desc>
+ </func>
+
+ <func>
+ <name>load(Filename) -> ok</name>
+ <fsummary>Restores previously saved data to the server.</fsummary>
+ <type>
+ <v>Filename = filename()</v>
+ </type>
+ <desc>
+ <p>Restores previously saved data to the server.</p>
+ </desc>
+ </func>
+
+ <func>
+ <name>save(Filename) -> ok</name>
+ <fsummary>Saves the collected data to file.</fsummary>
+ <type>
+ <v>Filename = filename()</v>
+ </type>
+ <desc>
+ <p>Saves the collected data to file.</p>
+ </desc>
+ </func>
+ </funcs>
+
+ <section>
+ <title>Convenience functions</title>
+ <p>The following functions are used for convenience.</p>
+ </section>
+ <funcs>
+ <func>
+ <name>apply(Fun) -> term()</name>
+ <fsummary>Same as <c>apply(Fun, [])</c>.</fsummary>
+ <desc>
+ <p>Same as <c>apply(Fun, [])</c>.</p>
+ </desc>
+ </func>
+ <func>
+ <name>apply(Fun, Args) -> term()</name>
+ <fsummary>Clears counters, applies function and collects the profiling results.</fsummary>
+ <type>
+ <v>Fun = fun()</v>
+ <v>Args = [term()]</v>
+ </type>
+ <desc>
+ <p> Clears the lock counters and then setups the instrumentation to save all destroyed locks.
+ After setup the fun is called, passing the elements in <c>Args</c> as arguments.
+ When the fun returns the statistics are immediately collected to the server. After the
+ collection the instrumentation is returned to its previous behavior.
+ The result of the applied fun is returned.
+ </p>
+ </desc>
+ </func>
+ <func>
+ <name>apply(Module, Function, Args) -> term()</name>
+ <fsummary>Clears counters, applies function and collects the profiling results.</fsummary>
+ <type>
+ <v>Module = atom()</v>
+ <v>Function = atom()</v>
+ <v>Args = [term()]</v>
+ </type>
+ <desc>
+ <p> Clears the lock counters and then setups the instrumentation to save all destroyed locks.
+ After setup the function is called, passing the elements in <c>Args</c> as arguments.
+ When the function returns the statistics are immediately collected to the server. After the
+ collection the instrumentation is returned to its previous behavior.
+ The result of the applied function is returned.
+ </p>
+ </desc>
+ </func>
+
+ <func>
+ <name>pid(Id, Serial) -> pid()</name>
+ <fsummary>Same as <c>pid(node(), Id, Serial)</c>.</fsummary>
+ <desc><p>Same as <c>pid(node(), Id, Serial)</c>.</p></desc>
+ </func>
+ <func>
+ <name>pid(Node, Id, Serial) -> pid()</name>
+ <fsummary>Creates a process id with creation 0.</fsummary>
+ <type>
+ <v>Node = node()</v>
+ <v>Id = integer()</v>
+ <v>Serial = integer()</v>
+ </type>
+ <desc>
+ <p>Creates a process id with creation 0. Example:</p>
+ </desc>
+ </func>
+
+ <func>
+ <name>port(Id) -> port()</name>
+ <fsummary>Same as <c>port(node(), Id)</c>.</fsummary>
+ <desc><p>Same as <c>port(node(), Id)</c>.</p></desc>
+ </func>
+ <func>
+ <name>port(Node, Id) -> port()</name>
+ <fsummary>Creates a port id with creation 0.</fsummary>
+ <type>
+ <v>Node = node()</v>
+ <v>Id = integer()</v>
+ </type>
+ <desc><p>Creates a port id with creation 0.</p></desc>
+ </func>
+
+ </funcs>
+
+ <section>
+ <title>Internal runtime lock counter controllers</title>
+ <p> The following functions control the behavior of the internal counters. </p>
+ </section>
+
+ <funcs>
+ <func>
+ <name>rt_collect() -> [lock_counter_data()]</name>
+ <fsummary>Same as <c>rt_collect(node())</c>.</fsummary>
+ <desc> <p>Same as <c>rt_collect(node())</c>.</p> </desc>
+ </func>
+ <func>
+ <name>rt_collect(Node) -> [lock_counter_data()]</name>
+ <fsummary>Returns a list of raw lock counter data.</fsummary>
+ <type>
+ <v>Node = node()</v>
+ </type>
+ <desc> <p>Returns a list of raw lock counter data.</p> </desc>
+ </func>
+
+ <func>
+ <name>rt_clear() -> ok</name>
+ <fsummary>Same as <c>rt_clear(node())</c>.</fsummary>
+ <desc> <p>Same as <c>rt_clear(node())</c>.</p> </desc>
+ </func>
+ <func>
+ <name>rt_clear(Node) -> ok</name>
+ <fsummary>Clears the internal counters.</fsummary>
+ <type>
+ <v>Node = node()</v>
+ </type>
+ <desc> <p>Clear the internal counters. Same as <c>lcnt:clear(Node)</c>.</p></desc>
+ </func>
+
+ <func>
+ <name>rt_opt({Type, bool()}) -> bool()</name>
+ <fsummary>Same as <c>rt_opt(node(), {Type, Opt})</c>.</fsummary>
+ <desc> <p>Same as <c>rt_opt(node(), {Type, Opt})</c>.</p> </desc>
+ </func>
+ <func>
+ <name>rt_opt(Node, {Type, bool()}) -> bool()</name>
+ <fsummary>Changes the lock counter behavior and returns the previous behaviour.</fsummary>
+ <type>
+ <v>Node = node()</v>
+ <v>Type = copy_save | process_locks</v>
+ </type>
+ <desc>
+ <p>Changes the lock counter behavior and returns the previous behaviour.</p>
+ <p>Option description:</p>
+ <taglist>
+ <tag><c>{copy_save, bool()}</c></tag>
+ <item>Enable statistics saving from destroyed locks by copying. This might consume a lot of memory.
+ <br/>Default: <c>false</c>
+ </item>
+
+ <tag><c>{process_locks, bool()}</c></tag>
+ <item>Profile process locks.
+ <br/>Default: <c>true</c>
+ </item>
+ </taglist>
+ </desc>
+ </func>
+ </funcs>
+
+ <section>
+ <title>See Also</title>
+ <p> <seealso marker="lcnt_chapter">LCNT User's Guide</seealso></p>
+ </section>
+</erlref>
diff --git a/lib/tools/doc/src/lcnt_chapter.xml b/lib/tools/doc/src/lcnt_chapter.xml
new file mode 100644
index 0000000000..8f44b23f59
--- /dev/null
+++ b/lib/tools/doc/src/lcnt_chapter.xml
@@ -0,0 +1,301 @@
+<?xml version="1.0" encoding="latin1" ?>
+<!DOCTYPE chapter SYSTEM "chapter.dtd">
+
+<chapter>
+ <header>
+ <copyright>
+ <year>2009</year><year>2010</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>lcnt - The Lock Profiler</title>
+ <prepared>Björn-Egil Dahlberg</prepared>
+ <responsible>nobody</responsible>
+ <docno></docno>
+ <approved>nobody</approved>
+ <checked>no</checked>
+ <date>2009-11-26</date>
+ <rev>PA1</rev>
+ <file>lcnt_chapter.xml</file>
+ </header>
+ <p>
+ Internally in the Erlang runtime system locks are used to protect resources from being updated from multiple threads in a fatal way. Locks are necessary
+ to ensure that the runtime system works properly but it also introduces a couple of limitations. Lock contention and locking overhead.
+ </p>
+ <p>
+ With lock contention we mean when one thread locks a resource and another thread, or threads, tries to acquire the same resource at the same time. The lock will deny
+ the other thread access to the resource and the thread will be blocked from continuing its execution. The second thread has to wait until the first thread has
+ completed its access to the resource and unlocked it. The <c>lcnt</c> tool measures these lock conflicts.
+ </p>
+ <p>
+ Locks has an inherent cost in execution time and memory space. It takes time initialize, destroy, aquiring or releasing locks. To decrease lock contention it
+ some times necessary to use finer grained locking strategies. This will usually also increase the locking overhead and hence there is a tradeoff
+ between lock contention and overhead. In general, lock contention increases with the number of threads running concurrently. The <c>lcnt</c> tool does not measure locking overhead.
+ </p>
+ <section>
+ <title> Enabling lock-counting </title>
+ <p>For investigation of locks in the emulator we use an internal tool called <c>lcnt</c> (short for lock-count). The VM needs to be compiled with this option enabled. To enable this, use:</p>
+
+ <pre>
+cd $ERL_TOP
+./configure --enable-lock-counter
+ </pre>
+
+ <p>
+ Another way to enable this alongside a normal VM is to compile it at emulator directory level, much like a debug build. To compile it this way do the following,
+ </p>
+ <pre>
+cd $ERL_TOP/erts/emulator
+make lcnt FLAVOR=smp
+ </pre>
+ <p> and then starting Erlang with,</p>
+ <pre>
+$ERL_TOP/bin/cerl -lcnt
+ </pre>
+ <p>To verify that you lock-counting enabled check that <c>[lock-counting]</c> appears in the status text when the VM is started.</p>
+ <pre>
+Erlang R13B03 (erts-5.7.4) [source] [64-bit] [smp:8:8] [rq:8] [async-threads:0] [hipe]
+ [kernel-poll:false] [lock-counting]
+ </pre>
+ </section>
+ <section>
+ <title>Getting started</title>
+ <p>Once you have a lock counting enabled VM the module <c>lcnt</c> can be used. The module is intended to be used from the current running nodes shell. To access remote nodes use <c>lcnt:clear(Node)</c> and <c>lcnt:collect(Node)</c>. </p>
+
+ <p>All locks are continuously monitored and its statistics updated. Use <c>lcnt:clear/0</c> to initially clear all counters before running any specific tests. This command will also reset the duration timer internally.</p>
+ <p>To retrieve lock statistics information use, <c>lcnt:collect/0,1</c>. The collect operation will start a <c>lcnt</c> server if it not already started. All collected data will be built into an erlang term and uploaded to the server and a duration time will also be uploaded. This duration is the time between <c>lcnt:clear/0,1</c> and <c>lcnt:collect/0,1</c>.</p>
+
+ <p>Once the data is collected to the server it can be filtered, sorted and printed in many different ways.</p>
+ <p>See the <seealso marker="lcnt">reference manual</seealso> for a description of each function.</p>
+ </section>
+ <section>
+ <title> Example of usage </title>
+ <p>From the Erlang shell:</p>
+ <pre>
+Erlang R13B03 (erts-5.7.4) [source] [smp:8:8] [rq:8] [async-threads:0] [hipe]
+ [kernel-poll:false] [lock-counting]
+1> lcnt:rt_opt({copy_save, true}).
+false
+2> lcnt:clear(), big:bang(1000), lcnt:collect().
+ok
+3> lcnt:conflicts().
+ lock id #tries #collisions collisions [%] time [us] duration [%]
+ ----- --- ------- ------------ --------------- ---------- -------------
+ alcu_allocator 50 4113692 158921 3.8632 215464 4.4962
+ pix_lock 256 4007140 4882 0.1218 12221 0.2550
+ run_queue 8 2287246 6949 0.3038 9825 0.2050
+ proc_main 1029 3115778 25755 0.8266 1199 0.0250
+ proc_msgq 1029 2467022 1910 0.0774 1048 0.0219
+ proc_status 1029 5708439 2435 0.0427 706 0.0147
+ message_pre_alloc_lock 8 2008569 134 0.0067 90 0.0019
+ timeofday 1 54065 8 0.0148 22 0.0005
+ gc_info 1 7071 7 0.0990 5 0.0001
+ok
+</pre>
+<p>
+ Another way to to profile a specific function is to use <c>lcnt:apply/3</c> or <c>lcnt:apply/1</c> which does <c>lcnt:clear/0</c> before the function and <c>lcnt:collect/0</c> after its invocation.
+ It also sets <c>copy_save</c> to <c>true</c> for the duration of the function call
+</p>
+<pre>
+Erlang R13B03 (erts-5.7.4) [source] [smp:8:8] [rq:8] [async-threads:0] [hipe]
+ [kernel-poll:false] [lock-counting]
+1> lcnt:apply(fun() -> big:bang(1000) end).
+4384.338
+2> lcnt:conflicts().
+ lock id #tries #collisions collisions [%] time [us] duration [%]
+ ----- --- ------- ------------ --------------- ---------- -------------
+ alcu_allocator 50 4117913 183091 4.4462 234232 5.1490
+ run_queue 8 2050398 3801 0.1854 6700 0.1473
+ pix_lock 256 4007080 4943 0.1234 2847 0.0626
+ proc_main 1028 3000178 28247 0.9415 1022 0.0225
+ proc_msgq 1028 2293677 1352 0.0589 545 0.0120
+ proc_status 1028 5258029 1744 0.0332 442 0.0097
+ message_pre_alloc_lock 8 2009322 147 0.0073 82 0.0018
+ timeofday 1 48616 9 0.0185 13 0.0003
+ gc_info 1 7455 12 0.1610 9 0.0002
+ok
+</pre>
+<p> The process locks are sorted after its class like all other locks. It is convenient to look at specific processes and ports as classes. We can do this by swapping class and class identifiers with <c>lcnt:swap_pid_keys/0</c>. </p>
+<pre>
+3> lcnt:swap_pid_keys().
+ok
+4> lcnt:conflicts([{print, [name, tries, ratio, time]}]).
+ lock #tries collisions [%] time [us]
+ ----- ------- --------------- ----------
+ alcu_allocator 4117913 4.4462 234232
+ run_queue 2050398 0.1854 6700
+ pix_lock 4007080 0.1234 2847
+ message_pre_alloc_lock 2009322 0.0073 82
+ &lt;[email protected]&gt; 13493 1.4452 41
+ &lt;[email protected]&gt; 13504 1.1404 36
+ &lt;[email protected]&gt; 13181 1.6235 35
+ &lt;[email protected]&gt; 13534 0.8202 22
+ &lt;[email protected]&gt; 8744 5.8326 22
+ &lt;[email protected]&gt; 13335 1.1174 19
+ &lt;[email protected]&gt; 13452 1.3678 19
+ &lt;[email protected]&gt; 13497 1.8745 18
+ &lt;[email protected]&gt; 11009 2.5343 18
+ &lt;[email protected]&gt; 13131 1.2566 16
+ &lt;[email protected]&gt; 13216 1.7327 15
+ &lt;[email protected]&gt; 13156 1.1098 15
+ &lt;[email protected]&gt; 13420 0.7303 14
+ &lt;[email protected]&gt; 13141 1.6437 14
+ &lt;[email protected]&gt; 13346 1.2064 13
+ &lt;[email protected]&gt; 13076 1.1701 13
+ok
+</pre>
+ </section>
+ <section>
+ <title> Example with Mnesia Transaction Benchmark </title>
+ <p>From the Erlang shell:</p>
+<pre>
+Erlang R13B03 (erts-5.7.4) [source] [smp:8:8] [rq:8] [async-threads:0] [hipe]
+ [kernel-poll:false] [lock-counting]
+
+Eshell V5.7.4 (abort with ^G)
+1> Conf=[{db_nodes, [node()]}, {driver_nodes, [node()]}, {replica_nodes, [node()]},
+ {n_drivers_per_node, 10}, {n_branches, 1000}, {n_accounts_per_branch, 10},
+ {replica_type, ram_copies}, {stop_after, 60000}, {reuse_history_id, true}].
+[{db_nodes,[nonode@nohost]},
+ {driver_nodes,[nonode@nohost]},
+ {replica_nodes,[nonode@nohost]},
+ {n_drivers_per_node,10},
+ {n_branches,1000},
+ {n_accounts_per_branch,10},
+ {replica_type,ram_copies},
+ {stop_after,60000},
+ {reuse_history_id,true}]
+2> mnesia_tpcb:init([{use_running_mnesia, false}|Conf]).
+ignore
+</pre>
+<p>Initial configuring of the benchmark is done. It is time to profile the actual benchmark and Mnesia</p>
+<pre>
+3> lcnt:apply(fun() -> {ok,{time, Tps,_,_,_,_}} = mnesia_tpcb:run([{use_running_mnesia,
+ true}|Conf]), Tps/60 end).
+12037.483333333334
+ok
+4> lcnt:swap_pid_keys().
+ok
+</pre>
+<p>The <c>id</c> header represents the number of unique identifiers under a class when the option <c>{combine, true}</c> is used (which is on by default). It will otherwise show the specific identifier.
+The <c>db_tab</c> listing shows 722287 unique locks, it is one for each ets-table created and Mnesia creates one for each transaction.
+</p>
+<pre>
+5> lcnt:conflicts().
+ lock id #tries #collisions collisions [%] time [us] duration [%]
+ ----- --- ------- ------------ --------------- ---------- -------------
+ alcu_allocator 50 56355118 732662 1.3001 2934747 4.8862
+ db_tab 722287 94513441 63203 0.0669 1958797 3.2613
+ timeofday 1 2701048 175854 6.5106 1746079 2.9071
+ pix_lock 256 24306168 163214 0.6715 918309 1.5289
+ run_queue 8 11813811 152637 1.2920 357040 0.5945
+ message_pre_alloc_lock 8 17671449 57203 0.3237 263043 0.4380
+ mnesia_locker 4 17477633 1618548 9.2607 97092 0.1617
+ mnesia_tm 4 9891408 463788 4.6888 86353 0.1438
+ gc_info 1 823460 628 0.0763 24826 0.0413
+ meta_main_tab_slot 16 41393400 7193 0.0174 11393 0.0190
+ &lt;[email protected]&gt; 4 4331412 333 0.0077 7148 0.0119
+ timer_wheel 1 203185 30 0.0148 3108 0.0052
+ &lt;[email protected]&gt; 4 4291098 210 0.0049 885 0.0015
+ &lt;[email protected]&gt; 4 4294702 288 0.0067 442 0.0007
+ &lt;[email protected]&gt; 4 4346066 235 0.0054 390 0.0006
+ &lt;[email protected]&gt; 4 4348159 287 0.0066 379 0.0006
+ &lt;[email protected]&gt; 4 4279309 290 0.0068 325 0.0005
+ &lt;[email protected]&gt; 4 4292190 302 0.0070 315 0.0005
+ &lt;[email protected]&gt; 4 4208858 265 0.0063 276 0.0005
+ &lt;[email protected]&gt; 4 4377502 267 0.0061 276 0.0005
+ok
+</pre>
+<p>The listing shows <c>mnesia_locker</c>, a process, has highly contended locks.</p>
+<pre>
+6> lcnt:inspect(mnesia_locker).
+ lock id #tries #collisions collisions [%] time [us] duration [%]
+ ----- --- ------- ------------ --------------- ---------- -------------
+ mnesia_locker proc_msgq 5449930 59374 1.0894 69781 0.1162
+ mnesia_locker proc_main 4462782 1487374 33.3284 14398 0.0240
+ mnesia_locker proc_status 7564921 71800 0.9491 12913 0.0215
+ mnesia_locker proc_link 0 0 0.0000 0 0.0000
+ok
+</pre>
+<p>Listing without class combiner.</p>
+
+<pre>
+7> lcnt:conflicts([{combine, false}, {print, [name, id, tries, ratio, time]}]).
+ lock id #tries collisions [%] time [us]
+ ----- --- ------- --------------- ----------
+ db_tab mnesia_transient_decision 722250 3.9463 1856852
+ timeofday undefined 2701048 6.5106 1746079
+ alcu_allocator ets_alloc 7490696 2.2737 692655
+ alcu_allocator ets_alloc 7081771 2.3294 664522
+ alcu_allocator ets_alloc 7047750 2.2520 658495
+ alcu_allocator ets_alloc 5883537 2.3177 610869
+ pix_lock 58 11011355 1.1924 564808
+ pix_lock 60 4426484 0.7120 262490
+ alcu_allocator ets_alloc 1897004 2.4248 219543
+ message_pre_alloc_lock undefined 4211267 0.3242 128299
+ run_queue 3 2801555 1.3003 116792
+ run_queue 2 2799988 1.2700 100091
+ run_queue 1 2966183 1.2712 78834
+ mnesia_locker proc_msgq 5449930 1.0894 69781
+ message_pre_alloc_lock undefined 3495672 0.3262 65773
+ message_pre_alloc_lock undefined 4189752 0.3174 58607
+ mnesia_tm proc_msgq 2094144 1.7184 56361
+ run_queue 4 2343585 1.3115 44300
+ db_tab branch 1446529 0.5229 38244
+ gc_info undefined 823460 0.0763 24826
+ok
+</pre>
+<p>
+In this scenario the lock that protects ets-table <c>mnesia_transient_decision</c> has spent most of its waiting for. That is 1.8 seconds in a test that run for 60 seconds. The time is also spread on eight different scheduler threads.
+</p>
+<pre>
+8> lcnt:inspect(db_tab, [{print, [name, id, tries, colls, ratio, duration]}]).
+ lock id #tries #collisions collisions [%] duration [%]
+ ----- --- ------- ------------ --------------- -------------
+ db_tab mnesia_transient_decision 722250 28502 3.9463 3.0916
+ db_tab branch 1446529 7564 0.5229 0.0637
+ db_tab account 1464500 8203 0.5601 0.0357
+ db_tab teller 1464529 8110 0.5538 0.0291
+ db_tab history 722250 3767 0.5216 0.0232
+ db_tab mnesia_stats 750332 7057 0.9405 0.0180
+ db_tab mnesia_trans_store 61 0 0.0000 0.0000
+ db_tab mnesia_trans_store 61 0 0.0000 0.0000
+ db_tab mnesia_trans_store 53 0 0.0000 0.0000
+ db_tab mnesia_trans_store 53 0 0.0000 0.0000
+ db_tab mnesia_trans_store 53 0 0.0000 0.0000
+ db_tab mnesia_trans_store 53 0 0.0000 0.0000
+ db_tab mnesia_trans_store 53 0 0.0000 0.0000
+ db_tab mnesia_trans_store 53 0 0.0000 0.0000
+ db_tab mnesia_trans_store 53 0 0.0000 0.0000
+ db_tab mnesia_trans_store 53 0 0.0000 0.0000
+ db_tab mnesia_trans_store 53 0 0.0000 0.0000
+ db_tab mnesia_trans_store 53 0 0.0000 0.0000
+ db_tab mnesia_trans_store 53 0 0.0000 0.0000
+ db_tab mnesia_trans_store 53 0 0.0000 0.0000
+ok
+</pre>
+
+ </section>
+ <section>
+ <title> Deciphering the output </title>
+ <p> Typically high <c>time</c> values are bad and this is often the thing to look for. However, one should also look for high lock acquisition frequencies (#tries) since locks generate overhead and because high frequency could become problematic if they begin to have conflicts even if it is not shown in a particular test. </p>
+ </section>
+
+ <section>
+ <title>See Also</title>
+ <p> <seealso marker="lcnt">LCNT Reference Manual</seealso></p>
+ </section>
+</chapter>
diff --git a/lib/tools/doc/src/notes.xml b/lib/tools/doc/src/notes.xml
index 59f600145e..e7d1ae150c 100644
--- a/lib/tools/doc/src/notes.xml
+++ b/lib/tools/doc/src/notes.xml
@@ -4,7 +4,7 @@
<chapter>
<header>
<copyright>
- <year>2004</year><year>2009</year>
+ <year>2004</year><year>2010</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
@@ -13,12 +13,12 @@
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>Tools Release Notes</title>
@@ -30,6 +30,55 @@
</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><title>Improvements and New Features</title>
+ <list>
+ <item>
+ <p>
+ Add lock profiling tool.</p>
+ <p>
+ The Lock profiling tool, lcnt, can make use of the
+ internal lock statistics when the runtime system is built
+ with this feature enabled.</p>
+ <p>
+ This provides a mechanism to examine potential lock
+ bottlenecks within the runtime itself.</p>
+ <p>
+ - Add erts_debug:lock_counters({copy_save, bool()}). This
+ option enables or disables statistics saving for
+ destroyed processes and ets-tables. Enabling this might
+ consume a lot of memory.</p>
+ <p>
+ - Add id-numbering for lock classes which is otherwise
+ undefined.</p>
+ <p>
+ Own Id: OTP-8424</p>
+ </item>
+ <item>
+ <p>
+ emacs: Moved code skeletons to a separate file and and
+ added a configurable variable to choose skeleton. Thanks
+ Dave Peticolas.</p>
+ <p>
+ Own Id: OTP-8446</p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
<section><title>Tools 2.6.5</title>
<section><title>Fixed Bugs and Malfunctions</title>
diff --git a/lib/tools/doc/src/notes_history.xml b/lib/tools/doc/src/notes_history.xml
index ef5ce1c03d..3791d5270a 100644
--- a/lib/tools/doc/src/notes_history.xml
+++ b/lib/tools/doc/src/notes_history.xml
@@ -4,23 +4,21 @@
<chapter>
<header>
<copyright>
- <year>2006</year>
- <year>2007</year>
- <holder>Ericsson AB, All Rights Reserved</holder>
+ <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.
-
- 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>Tools Release Notes</title>
@@ -63,7 +61,7 @@
<p>Own Id: OTP-5073</p>
</item>
<item>
- <p>Previous patch from open source messed up \\M-q so part of
+ <p>Previous patch from open source messed up \M-q so part of
that patch was backed out.</p>
<p>Own Id: OTP-5074</p>
</item>
diff --git a/lib/tools/doc/src/part.xml b/lib/tools/doc/src/part.xml
index 3e02086b80..bf9e1ebbec 100644
--- a/lib/tools/doc/src/part.xml
+++ b/lib/tools/doc/src/part.xml
@@ -4,7 +4,7 @@
<part xmlns:xi="http://www.w3.org/2001/XInclude">
<header>
<copyright>
- <year>1996</year><year>2009</year>
+ <year>1996</year><year>2010</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
@@ -13,12 +13,12 @@
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>Tools User's Guide</title>
@@ -55,6 +55,8 @@
<tag><em>instrument</em></tag>
<item>Utility functions for obtaining and analysing resource usage
in an instrumented Erlang runtime system.</item>
+ <tag><em>lcnt</em></tag>
+ <item>A lock profiling tool for the Erlang runtime system.</item>
<tag><em>make</em></tag>
<item>A make utility for Erlang similar to UNIX make.</item>
<tag><em>tags</em></tag>
@@ -69,6 +71,7 @@
<xi:include href="cprof_chapter.xml"/>
<xi:include href="erlang_mode_chapter.xml"/>
<xi:include href="fprof_chapter.xml"/>
+ <xi:include href="lcnt_chapter.xml"/>
<xi:include href="xref_chapter.xml"/>
</part>
diff --git a/lib/tools/doc/src/ref_man.xml b/lib/tools/doc/src/ref_man.xml
index aea74e3746..d4861af9f3 100644
--- a/lib/tools/doc/src/ref_man.xml
+++ b/lib/tools/doc/src/ref_man.xml
@@ -4,7 +4,7 @@
<application xmlns:xi="http://www.w3.org/2001/XInclude">
<header>
<copyright>
- <year>1996</year><year>2009</year>
+ <year>1996</year><year>2010</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
@@ -13,12 +13,12 @@
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>Tools Reference Manual</title>
@@ -51,9 +51,14 @@
Erlang programs. Uses trace to file to minimize runtime
performance impact, and displays time for calling and called
functions.</item>
+
<tag><em>instrument</em></tag>
<item>Utility functions for obtaining and analysing resource usage
in an instrumented Erlang runtime system.</item>
+
+ <tag><em>lcnt</em></tag>
+ <item>A lock profiling tool for the Erlang runtime system.</item>
+
<tag><em>make</em></tag>
<item>A make utility for Erlang similar to UNIX make.</item>
<tag><em>tags</em></tag>
@@ -70,6 +75,7 @@
<xi:include href="erlang_mode.xml"/>
<xi:include href="fprof.xml"/>
<xi:include href="instrument.xml"/>
+ <xi:include href="lcnt.xml"/>
<xi:include href="make.xml"/>
<xi:include href="tags.xml"/>
<xi:include href="xref.xml"/>
diff --git a/lib/tools/doc/src/xref.xml b/lib/tools/doc/src/xref.xml
index 6fff68fe9f..407a7392ad 100644
--- a/lib/tools/doc/src/xref.xml
+++ b/lib/tools/doc/src/xref.xml
@@ -1176,7 +1176,7 @@ Evaluates a predefined analysis.
<item>
<p><c>no_functions</c>. Functions in library modules and
the functions <c>module_info/0,1</c> are not counted by
- <c>info</c>. Assuming that <c>"Extra := _:module_info/\\"(0|1)\\" + LM"</c> has been evaluated, the
+ <c>info</c>. Assuming that <c>"Extra := _:module_info/\"(0|1)\" + LM"</c> has been evaluated, the
sum of the number of local and exported functions are:</p>
<list type="bulleted">
<item><c>"# (F - Extra)"</c> (info/1)</item>
diff --git a/lib/tools/emacs/erlang-skels-old.el b/lib/tools/emacs/erlang-skels-old.el
new file mode 100644
index 0000000000..b88d7bcc4b
--- /dev/null
+++ b/lib/tools/emacs/erlang-skels-old.el
@@ -0,0 +1,1267 @@
+;;
+;; %CopyrightBegin%
+;;
+;; Copyright Ericsson AB 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%
+;;;
+;;; Purpose: Provide Erlang code skeletons.
+;;; See 'erlang-skel-file' variable.
+
+(defvar erlang-tempo-tags nil
+ "Tempo tags for erlang mode")
+
+(defvar erlang-skel
+ '(("If" "if" erlang-skel-if)
+ ("Case" "case" erlang-skel-case)
+ ("Receive" "receive" erlang-skel-receive)
+ ("Receive After" "after" erlang-skel-receive-after)
+ ("Receive Loop" "loop" erlang-skel-receive-loop)
+ ("Module" "module" erlang-skel-module)
+ ("Author" "author" erlang-skel-author)
+ ()
+ ("Small Header" "small-header"
+ erlang-skel-small-header erlang-skel-header)
+ ("Normal Header" "normal-header"
+ erlang-skel-normal-header erlang-skel-header)
+ ("Large Header" "large-header"
+ erlang-skel-large-header erlang-skel-header)
+ ()
+ ("Small Server" "small-server"
+ erlang-skel-small-server erlang-skel-header)
+ ()
+ ("Application" "application"
+ erlang-skel-application erlang-skel-header)
+ ("Supervisor" "supervisor"
+ erlang-skel-supervisor erlang-skel-header)
+ ("supervisor_bridge" "supervisor-bridge"
+ erlang-skel-supervisor-bridge erlang-skel-header)
+ ("gen_server" "generic-server"
+ erlang-skel-generic-server erlang-skel-header)
+ ("gen_event" "gen-event"
+ erlang-skel-gen-event erlang-skel-header)
+ ("gen_fsm" "gen-fsm"
+ erlang-skel-gen-fsm erlang-skel-header)
+ ("Library module" "gen-lib"
+ erlang-skel-lib erlang-skel-header)
+ ("Corba callback" "gen-corba-cb"
+ erlang-skel-corba-callback erlang-skel-header)
+ ("Small Common Test suite" "ct-test-suite-s"
+ erlang-skel-ct-test-suite-s erlang-skel-header)
+ ("Large Common Test suite" "ct-test-suite-l"
+ erlang-skel-ct-test-suite-l erlang-skel-header)
+ ("Erlang TS test suite" "ts-test-suite"
+ erlang-skel-ts-test-suite erlang-skel-header)
+ )
+ "*Description of all skeleton templates.
+Both functions and menu entries will be created.
+
+Each entry in `erlang-skel' should be a list with three or four
+elements, or the empty list.
+
+The first element is the name which shows up in the menu. The second
+is the `tempo' identifier (The string \"erlang-\" will be added in
+front of it). The third is the skeleton descriptor, a variable
+containing `tempo' attributes as described in the function
+`tempo-define-template'. The optional fourth elements denotes a
+function which should be called when the menu is selected.
+
+Functions corresponding to every template will be created. The name
+of the function will be `tempo-template-erlang-X' where `X' is the
+tempo identifier as specified in the second argument of the elements
+in this list.
+
+A list with zero elements means that the a horizontal line should
+be placed in the menu.")
+
+;; In XEmacs `user-mail-address' returns "[email protected] (Foo Bar)" ARGH!
+;; What's wrong with that? RFC 822 says it's legal. [sverkerw]
+;; This needs to use the customized value. If that's not sane, things like
+;; add-log will lose anyhow. Avoid it if there _is_ a paren.
+(defvar erlang-skel-mail-address
+ (if (or (not user-mail-address) (string-match "(" user-mail-address))
+ (concat (user-login-name) "@"
+ (or (and (boundp 'mail-host-address)
+ mail-host-address)
+ (system-name)))
+ user-mail-address)
+ "Mail address of the user.")
+
+;; Expression templates:
+(defvar erlang-skel-case
+ '((erlang-skel-skip-blank) o >
+ "case " p " of" n> p "_ ->" n> p "ok" n> "end" p)
+ "*The skeleton of a `case' expression.
+Please see the function `tempo-define-template'.")
+
+(defvar erlang-skel-if
+ '((erlang-skel-skip-blank) o >
+ "if" n> p " ->" n> p "ok" n> "end" p)
+ "The skeleton of an `if' expression.
+Please see the function `tempo-define-template'.")
+
+(defvar erlang-skel-receive
+ '((erlang-skel-skip-blank) o >
+ "receive" n> p "_ ->" n> p "ok" n> "end" p)
+ "*The skeleton of a `receive' expression.
+Please see the function `tempo-define-template'.")
+
+(defvar erlang-skel-receive-after
+ '((erlang-skel-skip-blank) o >
+ "receive" n> p "_ ->" n> p "ok" n> "after " p "T ->" n>
+ p "ok" n> "end" p)
+ "*The skeleton of a `receive' expression with an `after' clause.
+Please see the function `tempo-define-template'.")
+
+(defvar erlang-skel-receive-loop
+ '(& o "loop(" p ") ->" n> "receive" n> p "_ ->" n>
+ "loop(" p ")" n> "end.")
+ "*The skeleton of a simple `receive' loop.
+Please see the function `tempo-define-template'.")
+
+
+;; Attribute templates
+
+(defvar erlang-skel-module
+ '(& "-module("
+ (erlang-add-quotes-if-needed (erlang-get-module-from-file-name))
+ ")." n)
+ "*The skeleton of a `module' attribute.
+Please see the function `tempo-define-template'.")
+
+(defvar erlang-skel-author
+ '(& "-author('" erlang-skel-mail-address "')." n)
+ "*The skeleton of a `author' attribute.
+Please see the function `tempo-define-template'.")
+
+(defvar erlang-skel-vc nil
+ "*The skeleton template to generate a version control attribute.
+The default is to insert nothing. Example of usage:
+
+ (setq erlang-skel-vc '(& \"-rcs(\\\"$\Id: $ \\\").\") n)
+
+Please see the function `tempo-define-template'.")
+
+(defvar erlang-skel-export
+ '(& "-export([" n> "])." n)
+ "*The skeleton of an `export' attribute.
+Please see the function `tempo-define-template'.")
+
+(defvar erlang-skel-import
+ '(& "%%-import(Module, [Function/Arity, ...])." n)
+ "*The skeleton of an `import' attribute.
+Please see the function `tempo-define-template'.")
+
+(defvar erlang-skel-compile nil
+ ;; '(& "%%-compile(export_all)." n)
+ "*The skeleton of a `compile' attribute.
+Please see the function `tempo-define-template'.")
+
+
+;; Comment templates.
+
+(defvar erlang-skel-date-function 'erlang-skel-dd-mmm-yyyy
+ "*Function which returns date string.
+Look in the module `time-stamp' for a battery of functions.")
+
+(defvar erlang-skel-copyright-comment '()
+ "*The template for a copyright line in the header, normally empty.
+This variable should be bound to a `tempo' template, for example:
+ '(& \"%%% Copyright (C) 2000, Yoyodyne, Inc.\" n)
+
+Please see the function `tempo-define-template'.")
+
+(defvar erlang-skel-created-comment
+ '(& "%%% Created : " (funcall erlang-skel-date-function) " by "
+ (user-full-name) " <" erlang-skel-mail-address ">" n)
+ "*The template for the \"Created:\" comment line.")
+
+(defvar erlang-skel-author-comment
+ '(& "%%% Author : " (user-full-name) " <" erlang-skel-mail-address ">" n)
+ "*The template for creating the \"Author:\" line in the header.
+Please see the function `tempo-define-template'.")
+
+(defvar erlang-skel-file-comment
+ '(& "%%% File : " (file-name-nondirectory buffer-file-name) n)
+"*The template for creating the \"Module:\" line in the header.
+Please see the function `tempo-define-template'.")
+
+(defvar erlang-skel-small-header
+ '(o (erlang-skel-include erlang-skel-module)
+ ;; erlang-skel-author)
+ n
+ (erlang-skel-include erlang-skel-compile
+ ;; erlang-skel-export
+ erlang-skel-vc))
+ "*The template of a small header without any comments.
+Please see the function `tempo-define-template'.")
+
+(defvar erlang-skel-normal-header
+ '(o (erlang-skel-include erlang-skel-copyright-comment
+ erlang-skel-file-comment
+ erlang-skel-author-comment)
+ "%%% Description : " p n
+ (erlang-skel-include erlang-skel-created-comment) n
+ (erlang-skel-include erlang-skel-small-header) n)
+ "*The template of a normal header.
+Please see the function `tempo-define-template'.")
+
+(defvar erlang-skel-large-header
+ '(o (erlang-skel-separator)
+ (erlang-skel-include erlang-skel-copyright-comment
+ erlang-skel-file-comment
+ erlang-skel-author-comment)
+ "%%% Description : " p n
+ "%%%" n
+ (erlang-skel-include erlang-skel-created-comment)
+ (erlang-skel-separator)
+ (erlang-skel-include erlang-skel-small-header) )
+ "*The template of a large header.
+Please see the function `tempo-define-template'.")
+
+
+;; Server templates.
+
+(defvar erlang-skel-small-server
+ '((erlang-skel-include erlang-skel-large-header)
+ "-export([start/0,init/1])." n n n
+ "start() ->" n> "spawn(" (erlang-get-module-from-file-name)
+ ", init, [self()])." n n
+ "init(From) ->" n>
+ "loop(From)." n n
+ "loop(From) ->" n>
+ "receive" n>
+ p "_ ->" n>
+ "loop(From)" n>
+ "end."
+ )
+ "*Template of a small server.
+Please see the function `tempo-define-template'.")
+
+;; Behaviour templates.
+
+(defvar erlang-skel-application
+ '((erlang-skel-include erlang-skel-large-header)
+ "-behaviour(application)." n n
+ "%% Application callbacks" n
+ "-export([start/2, stop/1])." n n
+ (erlang-skel-double-separator 2)
+ "%% Application callbacks" n
+ (erlang-skel-double-separator 2)
+ (erlang-skel-separator 2)
+ "%% Function: start(Type, StartArgs) -> {ok, Pid} |" n
+ "%% {ok, Pid, State} |" n
+ "%% {error, Reason}" n
+ "%% Description: This function is called whenever an application " n
+ "%% is started using application:start/1,2, and should start the processes" n
+ "%% of the application. If the application is structured according to the" n
+ "%% OTP design principles as a supervision tree, this means starting the" n
+ "%% top supervisor of the tree." n
+ (erlang-skel-separator 2)
+ "start(_Type, StartArgs) ->" n>
+ "case 'TopSupervisor':start_link(StartArgs) of" n>
+ "{ok, Pid} -> " n>
+ "{ok, Pid};" n>
+ "Error ->" n>
+ "Error" n>
+ "end." n
+ n
+ (erlang-skel-separator 2)
+ "%% Function: stop(State) -> void()" n
+ "%% Description: This function is called whenever an application" n
+ "%% has stopped. It is intended to be the opposite of Module:start/2 and" n
+ "%% should do any necessary cleaning up. The return value is ignored. "n
+ (erlang-skel-separator 2)
+ "stop(_State) ->" n>
+ "ok." n
+ n
+ (erlang-skel-double-separator 2)
+ "%% Internal functions" n
+ (erlang-skel-double-separator 2)
+ )
+ "*The template of an application behaviour.
+Please see the function `tempo-define-template'.")
+
+(defvar erlang-skel-supervisor
+ '((erlang-skel-include erlang-skel-large-header)
+ "-behaviour(supervisor)." n n
+
+ "%% API" n
+ "-export([start_link/0])." n n
+
+ "%% Supervisor callbacks" n
+ "-export([init/1])." n n
+
+ "-define(SERVER, ?MODULE)." n n
+
+ (erlang-skel-double-separator 2)
+ "%% API functions" n
+ (erlang-skel-double-separator 2)
+ (erlang-skel-separator 2)
+ "%% Function: start_link() -> {ok,Pid} | ignore | {error,Error}" n
+ "%% Description: Starts the supervisor" n
+ (erlang-skel-separator 2)
+ "start_link() ->" n>
+ "supervisor:start_link({local, ?SERVER}, ?MODULE, [])." n
+ n
+ (erlang-skel-double-separator 2)
+ "%% Supervisor callbacks" n
+ (erlang-skel-double-separator 2)
+ (erlang-skel-separator 2)
+ "%% Func: init(Args) -> {ok, {SupFlags, [ChildSpec]}} |" n
+ "%% ignore |" n
+ "%% {error, Reason}" n
+ "%% Description: Whenever a supervisor is started using "n
+ "%% supervisor:start_link/[2,3], this function is called by the new process "n
+ "%% to find out about restart strategy, maximum restart frequency and child "n
+ "%% specifications." n
+ (erlang-skel-separator 2)
+ "init([]) ->" n>
+ "AChild = {'AName',{'AModule',start_link,[]}," n>
+ "permanent,2000,worker,['AModule']}," n>
+ "{ok,{{one_for_all,0,1}, [AChild]}}." n
+ n
+ (erlang-skel-double-separator 2)
+ "%% Internal functions" n
+ (erlang-skel-double-separator 2)
+ )
+ "*The template of an supervisor behaviour.
+Please see the function `tempo-define-template'.")
+
+(defvar erlang-skel-supervisor-bridge
+ '((erlang-skel-include erlang-skel-large-header)
+ "-behaviour(supervisor_bridge)." n n
+
+ "%% API" n
+ "-export([start_link/0])." n n
+
+ "%% supervisor_bridge callbacks" n
+ "-export([init/1, terminate/2])." n n
+
+ "-define(SERVER, ?MODULE)." n n
+
+ "-record(state, {})." n n
+
+ (erlang-skel-double-separator 2)
+ "%% API" n
+ (erlang-skel-double-separator 2)
+ (erlang-skel-separator 2)
+ "%% Function: start_link() -> {ok,Pid} | ignore | {error,Error}" n
+ "%% Description: Starts the supervisor bridge" n
+ (erlang-skel-separator 2)
+ "start_link() ->" n>
+ "supervisor_bridge:start_link({local, ?SERVER}, ?MODULE, [])." n
+ n
+ (erlang-skel-double-separator 2)
+ "%% supervisor_bridge callbacks" n
+ (erlang-skel-double-separator 2)
+ (erlang-skel-separator 2)
+ "%% Funcion: init(Args) -> {ok, Pid, State} |" n
+ "%% ignore |" n
+ "%% {error, Reason} " n
+ "%% Description:Creates a supervisor_bridge process, linked to the calling" n
+ "%% process, which calls Module:init/1 to start the subsystem. To ensure a" n
+ "%% synchronized start-up procedure, this function does not return until" n
+ "%% Module:init/1 has returned. " n
+ (erlang-skel-separator 2)
+ "init([]) ->" n>
+ "case 'AModule':start_link() of" n>
+ "{ok, Pid} ->" n>
+ "{ok, Pid, #state{}};" n>
+ "Error ->" n>
+ "Error" n>
+ "end." n
+ n
+ (erlang-skel-separator 2)
+ "%% Func: terminate(Reason, State) -> void()" n
+ "%% Description:This function is called by the supervisor_bridge when it is"n
+ "%% about to terminate. It should be the opposite of Module:init/1 and stop"n
+ "%% the subsystem and do any necessary cleaning up.The return value is ignored."
+ (erlang-skel-separator 2)
+ "terminate(Reason, State) ->" n>
+ "'AModule':stop()," n>
+ "ok." n
+ n
+ (erlang-skel-double-separator 2)
+ "%% Internal functions" n
+ (erlang-skel-double-separator 2)
+ )
+ "*The template of an supervisor_bridge behaviour.
+Please see the function `tempo-define-template'.")
+
+(defvar erlang-skel-generic-server
+ '((erlang-skel-include erlang-skel-large-header)
+ "-behaviour(gen_server)." n n
+
+ "%% API" n
+ "-export([start_link/0])." n n
+
+ "%% gen_server callbacks" n
+ "-export([init/1, handle_call/3, handle_cast/2, "
+ "handle_info/2," n>
+ "terminate/2, code_change/3])." n n
+
+ "-record(state, {})." n n
+
+ (erlang-skel-double-separator 2)
+ "%% API" n
+ (erlang-skel-double-separator 2)
+ (erlang-skel-separator 2)
+ "%% Function: start_link() -> {ok,Pid} | ignore | {error,Error}" n
+ "%% Description: Starts the server" n
+ (erlang-skel-separator 2)
+ "start_link() ->" n>
+ "gen_server:start_link({local, ?SERVER}, ?MODULE, [], [])." n
+ n
+ (erlang-skel-double-separator 2)
+ "%% gen_server callbacks" n
+ (erlang-skel-double-separator 2)
+ n
+ (erlang-skel-separator 2)
+ "%% Function: init(Args) -> {ok, State} |" n
+ "%% {ok, State, Timeout} |" n
+ "%% ignore |" n
+ "%% {stop, Reason}" n
+ "%% Description: Initializes the server" n
+ (erlang-skel-separator 2)
+ "init([]) ->" n>
+ "{ok, #state{}}." n
+ n
+ (erlang-skel-separator 2)
+ "%% Function: "
+ "%% handle_call(Request, From, State) -> {reply, Reply, State} |" n
+ "%% {reply, Reply, State, Timeout} |" n
+ "%% {noreply, State} |" n
+ "%% {noreply, State, Timeout} |" n
+ "%% {stop, Reason, Reply, State} |" n
+ "%% {stop, Reason, State}" n
+ "%% Description: Handling call messages" n
+ (erlang-skel-separator 2)
+ "handle_call(_Request, _From, State) ->" n>
+ "Reply = ok," n>
+ "{reply, Reply, State}." n
+ n
+ (erlang-skel-separator 2)
+ "%% Function: handle_cast(Msg, State) -> {noreply, State} |" n
+ "%% {noreply, State, Timeout} |" n
+ "%% {stop, Reason, State}" n
+ "%% Description: Handling cast messages" n
+
+ (erlang-skel-separator 2)
+ "handle_cast(_Msg, State) ->" n>
+ "{noreply, State}." n
+ n
+ (erlang-skel-separator 2)
+ "%% Function: handle_info(Info, State) -> {noreply, State} |" n
+ "%% {noreply, State, Timeout} |" n
+ "%% {stop, Reason, State}" n
+ "%% Description: Handling all non call/cast messages" n
+ (erlang-skel-separator 2)
+ "handle_info(_Info, State) ->" n>
+ "{noreply, State}." n
+ n
+ (erlang-skel-separator 2)
+ "%% Function: terminate(Reason, State) -> void()" n
+ "%% Description: This function is called by a gen_server when it is about to"n
+ "%% terminate. It should be the opposite of Module:init/1 and do any necessary"n
+ "%% cleaning up. When it returns, the gen_server terminates with Reason." n
+ "%% The return value is ignored." n
+
+ (erlang-skel-separator 2)
+ "terminate(_Reason, _State) ->" n>
+ "ok." n
+ n
+ (erlang-skel-separator 2)
+ "%% Func: code_change(OldVsn, State, Extra) -> {ok, NewState}" n
+ "%% Description: Convert process state when code is changed" n
+ (erlang-skel-separator 2)
+ "code_change(_OldVsn, State, _Extra) ->" n>
+ "{ok, State}." n
+ n
+ (erlang-skel-separator 2)
+ "%%% Internal functions" n
+ (erlang-skel-separator 2)
+ )
+ "*The template of a generic server.
+Please see the function `tempo-define-template'.")
+
+(defvar erlang-skel-gen-event
+ '((erlang-skel-include erlang-skel-large-header)
+ "-behaviour(gen_event)." n
+
+ "%% API" n
+ "-export([start_link/0, add_handler/0])." n n
+
+ "%% gen_event callbacks" n
+ "-export([init/1, handle_event/2, handle_call/2, " n>
+ "handle_info/2, terminate/2, code_change/3])." n n
+
+ "-record(state, {})." n n
+
+ (erlang-skel-double-separator 2)
+ "%% gen_event callbacks" n
+ (erlang-skel-double-separator 2)
+ (erlang-skel-separator 2)
+ "%% Function: start_link() -> {ok,Pid} | {error,Error} " n
+ "%% Description: Creates an event manager." n
+ (erlang-skel-separator 2)
+ "start_link() ->" n>
+ "gen_event:start_link({local, ?SERVER}). " n
+ n
+ (erlang-skel-separator 2)
+ "%% Function: add_handler() -> ok | {'EXIT',Reason} | term()" n
+ "%% Description: Adds an event handler" n
+ (erlang-skel-separator 2)
+ "add_handler() ->" n>
+ "gen_event:add_handler(?SERVER, ?MODULE, [])." n
+ n
+ (erlang-skel-double-separator 2)
+ "%% gen_event callbacks" n
+ (erlang-skel-double-separator 2)
+ (erlang-skel-separator 2)
+ "%% Function: init(Args) -> {ok, State}" n
+ "%% Description: Whenever a new event handler is added to an event manager,"n
+ "%% this function is called to initialize the event handler." n
+ (erlang-skel-separator 2)
+ "init([]) ->" n>
+ "{ok, #state{}}." n
+ n
+ (erlang-skel-separator 2)
+ "%% Function: "n
+ "%% handle_event(Event, State) -> {ok, State} |" n
+ "%% {swap_handler, Args1, State1, Mod2, Args2} |"n
+ "%% remove_handler" n
+ "%% Description:Whenever an event manager receives an event sent using"n
+ "%% gen_event:notify/2 or gen_event:sync_notify/2, this function is called for"n
+ "%% each installed event handler to handle the event. "n
+ (erlang-skel-separator 2)
+ "handle_event(_Event, State) ->" n>
+ "{ok, State}." n
+ n
+ (erlang-skel-separator 2)
+ "%% Function: " n
+ "%% handle_call(Request, State) -> {ok, Reply, State} |" n
+ "%% {swap_handler, Reply, Args1, State1, "n
+ "%% Mod2, Args2} |" n
+ "%% {remove_handler, Reply}" n
+ "%% Description: Whenever an event manager receives a request sent using"n
+ "%% gen_event:call/3,4, this function is called for the specified event "n
+ "%% handler to handle the request."n
+ (erlang-skel-separator 2)
+ "handle_call(_Request, State) ->" n>
+ "Reply = ok," n>
+ "{ok, Reply, State}." n
+ n
+ (erlang-skel-separator 2)
+ "%% Function: " n
+ "%% handle_info(Info, State) -> {ok, State} |" n
+ "%% {swap_handler, Args1, State1, Mod2, Args2} |" n
+ "%% remove_handler" n
+ "%% Description: This function is called for each installed event handler when"n
+ "%% an event manager receives any other message than an event or a synchronous"n
+ "%% request (or a system message)."n
+ (erlang-skel-separator 2)
+ "handle_info(_Info, State) ->" n>
+ "{ok, State}." n
+ n
+ (erlang-skel-separator 2)
+ "%% Function: terminate(Reason, State) -> void()" n
+ "%% Description:Whenever an event handler is deleted from an event manager,"n
+ "%% this function is called. It should be the opposite of Module:init/1 and "n
+ "%% do any necessary cleaning up. " n
+ (erlang-skel-separator 2)
+ "terminate(_Reason, _State) ->" n>
+ "ok." n
+ n
+ (erlang-skel-separator 2)
+ "%% Function: code_change(OldVsn, State, Extra) -> {ok, NewState} " n
+ "%% Description: Convert process state when code is changed" n
+ (erlang-skel-separator 2)
+ "code_change(_OldVsn, State, _Extra) ->" n>
+ "{ok, State}." n
+ n
+ (erlang-skel-separator 2)
+ "%%% Internal functions" n
+ (erlang-skel-separator 2)
+ )
+ "*The template of a gen_event.
+Please see the function `tempo-define-template'.")
+
+(defvar erlang-skel-gen-fsm
+ '((erlang-skel-include erlang-skel-large-header)
+ "-behaviour(gen_fsm)." n n
+
+ "%% API" n
+ "-export([start_link/0])." n n
+
+ "%% gen_fsm callbacks" n
+ "-export([init/1, state_name/2, state_name/3, handle_event/3," n>
+ "handle_sync_event/4, handle_info/3, terminate/3, code_change/4])." n n
+
+ "-record(state, {})." n n
+
+ (erlang-skel-double-separator 2)
+ "%% API" n
+ (erlang-skel-double-separator 2)
+ (erlang-skel-separator 2)
+ "%% Function: start_link() -> ok,Pid} | ignore | {error,Error}" n
+ "%% Description:Creates a gen_fsm process which calls Module:init/1 to"n
+ "%% initialize. To ensure a synchronized start-up procedure, this function" n
+ "%% does not return until Module:init/1 has returned. " n
+ (erlang-skel-separator 2)
+ "start_link() ->" n>
+ "gen_fsm:start_link({local, ?SERVER}, ?MODULE, [], [])." n
+ n
+ (erlang-skel-double-separator 2)
+ "%% gen_fsm callbacks" n
+ (erlang-skel-double-separator 2)
+ (erlang-skel-separator 2)
+ "%% Function: init(Args) -> {ok, StateName, State} |" n
+ "%% {ok, StateName, State, Timeout} |" n
+ "%% ignore |" n
+ "%% {stop, StopReason} " n
+ "%% Description:Whenever a gen_fsm is started using gen_fsm:start/[3,4] or"n
+ "%% gen_fsm:start_link/3,4, this function is called by the new process to "n
+ "%% initialize. " n
+ (erlang-skel-separator 2)
+ "init([]) ->" n>
+ "{ok, state_name, #state{}}." n
+ n
+ (erlang-skel-separator 2)
+ "%% Function: "n
+ "%% state_name(Event, State) -> {next_state, NextStateName, NextState}|" n
+ "%% {next_state, NextStateName, " n
+ "%% NextState, Timeout} |" n
+ "%% {stop, Reason, NewState}" n
+ "%% Description:There should be one instance of this function for each possible"n
+ "%% state name. Whenever a gen_fsm receives an event sent using" n
+ "%% gen_fsm:send_event/2, the instance of this function with the same name as"n
+ "%% the current state name StateName is called to handle the event. It is also "n
+ "%% called if a timeout occurs. " n
+ (erlang-skel-separator 2)
+ "state_name(_Event, State) ->" n>
+ "{next_state, state_name, State}." n
+ n
+ (erlang-skel-separator 2)
+ "%% Function:" n
+ "%% state_name(Event, From, State) -> {next_state, NextStateName, NextState} |"n
+ "%% {next_state, NextStateName, " n
+ "%% NextState, Timeout} |" n
+ "%% {reply, Reply, NextStateName, NextState}|"n
+ "%% {reply, Reply, NextStateName, " n
+ "%% NextState, Timeout} |" n
+ "%% {stop, Reason, NewState}|" n
+ "%% {stop, Reason, Reply, NewState}" n
+ "%% Description: There should be one instance of this function for each" n
+ "%% possible state name. Whenever a gen_fsm receives an event sent using" n
+ "%% gen_fsm:sync_send_event/2,3, the instance of this function with the same"n
+ "%% name as the current state name StateName is called to handle the event." n
+ (erlang-skel-separator 2)
+ "state_name(_Event, _From, State) ->" n>
+ "Reply = ok," n>
+ "{reply, Reply, state_name, State}." n
+ n
+ (erlang-skel-separator 2)
+ "%% Function: " n
+ "%% handle_event(Event, StateName, State) -> {next_state, NextStateName, "n
+ "%% NextState} |" n
+ "%% {next_state, NextStateName, "n
+ "%% NextState, Timeout} |" n
+ "%% {stop, Reason, NewState}" n
+ "%% Description: Whenever a gen_fsm receives an event sent using"n
+ "%% gen_fsm:send_all_state_event/2, this function is called to handle"n
+ "%% the event." n
+ (erlang-skel-separator 2)
+ "handle_event(_Event, StateName, State) ->" n>
+ "{next_state, StateName, State}." n
+ n
+ (erlang-skel-separator 2)
+ "%% Function: " n
+ "%% handle_sync_event(Event, From, StateName, "n
+ "%% State) -> {next_state, NextStateName, NextState} |" n
+ "%% {next_state, NextStateName, NextState, " n
+ "%% Timeout} |" n
+ "%% {reply, Reply, NextStateName, NextState}|" n
+ "%% {reply, Reply, NextStateName, NextState, " n
+ "%% Timeout} |" n
+ "%% {stop, Reason, NewState} |" n
+ "%% {stop, Reason, Reply, NewState}" n
+ "%% Description: Whenever a gen_fsm receives an event sent using"n
+ "%% gen_fsm:sync_send_all_state_event/2,3, this function is called to handle"n
+ "%% the event."n
+ (erlang-skel-separator 2)
+ "handle_sync_event(Event, From, StateName, State) ->" n>
+ "Reply = ok," n>
+ "{reply, Reply, StateName, State}." n
+ n
+ (erlang-skel-separator 2)
+ "%% Function: " n
+ "%% handle_info(Info,StateName,State)-> {next_state, NextStateName, NextState}|" n
+ "%% {next_state, NextStateName, NextState, "n
+ "%% Timeout} |" n
+ "%% {stop, Reason, NewState}" n
+ "%% Description: This function is called by a gen_fsm when it receives any"n
+ "%% other message than a synchronous or asynchronous event"n
+ "%% (or a system message)." n
+ (erlang-skel-separator 2)
+ "handle_info(_Info, StateName, State) ->" n>
+ "{next_state, StateName, State}." n
+ n
+ (erlang-skel-separator 2)
+ "%% Function: terminate(Reason, StateName, State) -> void()" n
+ "%% Description:This function is called by a gen_fsm when it is about"n
+ "%% to terminate. It should be the opposite of Module:init/1 and do any"n
+ "%% necessary cleaning up. When it returns, the gen_fsm terminates with"n
+ "%% Reason. The return value is ignored." n
+ (erlang-skel-separator 2)
+ "terminate(_Reason, _StateName, _State) ->" n>
+ "ok." n
+ n
+ (erlang-skel-separator 2)
+ "%% Function:" n
+ "%% code_change(OldVsn, StateName, State, Extra) -> {ok, StateName, NewState}" n
+ "%% Description: Convert process state when code is changed" n
+ (erlang-skel-separator 2)
+ "code_change(_OldVsn, StateName, State, _Extra) ->" n>
+ "{ok, StateName, State}." n
+ n
+ (erlang-skel-separator 2)
+ "%%% Internal functions" n
+ (erlang-skel-separator 2)
+ )
+ "*The template of a gen_fsm.
+Please see the function `tempo-define-template'.")
+
+(defvar erlang-skel-lib
+ '((erlang-skel-include erlang-skel-large-header)
+
+ "%% API" n
+ "-export([])." n n
+
+ (erlang-skel-double-separator 2)
+ "%% API" n
+ (erlang-skel-double-separator 2)
+ (erlang-skel-separator 2)
+ "%% Function: " n
+ "%% Description:" n
+ (erlang-skel-separator 2)
+ n
+ (erlang-skel-double-separator 2)
+ "%% Internal functions" n
+ (erlang-skel-double-separator 2)
+ )
+ "*The template of a library module.
+Please see the function `tempo-define-template'.")
+
+(defvar erlang-skel-corba-callback
+ '((erlang-skel-include erlang-skel-large-header)
+ "%% Include files" n n
+
+ "%% API" n
+ "-export([])." n n
+
+ "%% Corba callbacks" n
+ "-export([init/1, terminate/2, code_change/3])." n n
+
+ "-record(state, {})." n n
+
+ (erlang-skel-double-separator 2)
+ "%% Corba callbacks" n
+ (erlang-skel-double-separator 2)
+ (erlang-skel-separator 2)
+ "%% Function: init(Args) -> {ok, State} |" n
+ "%% {ok, State, Timeout} |" n
+ "%% ignore |" n
+ "%% {stop, Reason}" n
+ "%% Description: Initializes the server" n
+ (erlang-skel-separator 2)
+ "init([]) ->" n>
+ "{ok, #state{}}." n
+ n
+ (erlang-skel-separator 2)
+ "%% Function: terminate(Reason, State) -> void()" n
+ "%% Description: Shutdown the server" n
+ (erlang-skel-separator 2)
+ "terminate(_Reason, _State) ->" n>
+ "ok." n
+ n
+ (erlang-skel-separator 2)
+ "%% Function: code_change(OldVsn, State, Extra) -> {ok, NewState} " n
+ "%% Description: Convert process state when code is changed" n
+ (erlang-skel-separator 2)
+ "code_change(_OldVsn, State, _Extra) ->" n>
+ "{ok, State}." n
+ n
+ (erlang-skel-double-separator 2)
+ "%% Internal functions" n
+ (erlang-skel-double-separator 2)
+ )
+ "*The template of a library module.
+Please see the function `tempo-define-template'.")
+
+(defvar erlang-skel-ts-test-suite
+ '((erlang-skel-include erlang-skel-large-header)
+ "%% Note: This directive should only be used in test suites." n
+ "-compile(export_all)." n n
+
+ "-include_lib(\"test_server/include/test_server.hrl\")." n n
+
+ (erlang-skel-separator 2)
+ "%% TEST SERVER CALLBACK FUNCTIONS" n
+ (erlang-skel-separator 2)
+ n
+ (erlang-skel-separator 2)
+ "%% Function: init_per_suite(Config0) -> Config1 | {skip,Reason}" n
+ "%%" n
+ "%% Config0 = Config1 = [tuple()]" n
+ "%% A list of key/value pairs, holding the test case configuration." n
+ "%% Reason = term()" n
+ "%% The reason for skipping the suite." n
+ "%%" n
+ "%% Description: Initialization before the suite." n
+ "%%" n
+ "%% Note: This function is free to add any key/value pairs to the Config" n
+ "%% variable, but should NOT alter/remove any existing entries." n
+ (erlang-skel-separator 2)
+ "init_per_suite(Config) ->" n >
+ "Config." n n
+
+ (erlang-skel-separator 2)
+ "%% Function: end_per_suite(Config) -> void()" n
+ "%%" n
+ "%% Config = [tuple()]" n
+ "%% A list of key/value pairs, holding the test case configuration." n
+ "%%" n
+ "%% Description: Cleanup after the suite." n
+ (erlang-skel-separator 2)
+ "end_per_suite(_Config) ->" n >
+ "ok." n n
+
+ (erlang-skel-separator 2)
+ "%% Function: init_per_testcase(TestCase, Config0) -> Config1 |" n
+ "%% {skip,Reason}" n
+ "%% TestCase = atom()" n
+ "%% Name of the test case that is about to run." n
+ "%% Config0 = Config1 = [tuple()]" n
+ "%% A list of key/value pairs, holding the test case configuration." n
+ "%% Reason = term()" n
+ "%% The reason for skipping the test case." n
+ "%%" n
+ "%% Description: Initialization before each test case." n
+ "%%" n
+ "%% Note: This function is free to add any key/value pairs to the Config" n
+ "%% variable, but should NOT alter/remove any existing entries." n
+ (erlang-skel-separator 2)
+ "init_per_testcase(_TestCase, Config) ->" n >
+ "Config." n n
+
+ (erlang-skel-separator 2)
+ "%% Function: end_per_testcase(TestCase, Config) -> void()" n
+ "%%" n
+ "%% TestCase = atom()" n
+ "%% Name of the test case that is finished." n
+ "%% Config = [tuple()]" n
+ "%% A list of key/value pairs, holding the test case configuration." n
+ "%%" n
+ "%% Description: Cleanup after each test case." n
+ (erlang-skel-separator 2)
+ "end_per_testcase(_TestCase, _Config) ->" n >
+ "ok."n n
+
+ (erlang-skel-separator 2)
+ "%% Function: all(Clause) -> Descr | Spec | {skip,Reason}" n
+ "%%" n
+ "%% Clause = doc | suite" n
+ "%% Indicates expected return value." n
+ "%% Descr = [string()] | []" n
+ "%% String that describes the test suite." n
+ "%% Spec = [TestCase]" n
+ "%% A test specification." n
+ "%% TestCase = ConfCase | atom()" n
+ "%% Configuration case, or the name of a test case function." n
+ "%% ConfCase = {conf,Init,Spec,End} |" n
+ "%% {conf,Properties,Init,Spec,End}" n
+ "%% Init = End = {Mod,Func} | Func" n
+ "%% Initialization and cleanup function." n
+ "%% Mod = Func = atom()" n
+ "%% Properties = [parallel | sequence | Shuffle | {RepeatType,N}]" n
+ "%% Execution properties of the test cases (may be combined)." n
+ "%% Shuffle = shuffle | {shuffle,Seed}" n
+ "%% To get cases executed in random order." n
+ "%% Seed = {integer(),integer(),integer()}" n
+ "%% RepeatType = repeat | repeat_until_all_ok | repeat_until_all_fail |" n
+ "%% repeat_until_any_ok | repeat_until_any_fail" n
+ "%% To get execution of cases repeated." n
+ "%% N = integer() | forever" n
+ "%% Reason = term()" n
+ "%% The reason for skipping the test suite." n
+ "%%" n
+ "%% Description: Returns a description of the test suite when" n
+ "%% Clause == doc, and a test specification (list" n
+ "%% of the conf and test cases in the suite) when" n
+ "%% Clause == suite." n
+ (erlang-skel-separator 2)
+ "all(doc) -> " n >
+ "[\"Describe the main purpose of this suite\"];" n n
+ "all(suite) -> " n >
+ "[a_test_case]." n n
+ n
+ (erlang-skel-separator 2)
+ "%% TEST CASES" n
+ (erlang-skel-separator 2)
+ n
+ (erlang-skel-separator 2)
+ "%% Function: TestCase(Arg) -> Descr | Spec | ok | exit() | {skip,Reason}" n
+ "%%" n
+ "%% Arg = doc | suite | Config" n
+ "%% Indicates expected behaviour and return value." n
+ "%% Config = [tuple()]" n
+ "%% A list of key/value pairs, holding the test case configuration." n
+ "%% Descr = [string()] | []" n
+ "%% String that describes the test case." n
+ "%% Spec = [tuple()] | []" n
+ "%% A test specification, see all/1." n
+ "%% Reason = term()" n
+ "%% The reason for skipping the test case." n
+ "%%" n
+ "%% Description: Test case function. Returns a description of the test" n
+ "%% case (doc), then returns a test specification (suite)," n
+ "%% or performs the actual test (Config)." n
+ (erlang-skel-separator 2)
+ "a_test_case(doc) -> " n >
+ "[\"Describe the main purpose of this test case\"];" n n
+ "a_test_case(suite) -> " n >
+ "[];" n n
+ "a_test_case(Config) when is_list(Config) -> " n >
+ "ok." n
+ )
+ "*The template of a library module.
+Please see the function `tempo-define-template'.")
+
+(defvar erlang-skel-ct-test-suite-l
+ '((erlang-skel-include erlang-skel-large-header)
+ "%% Note: This directive should only be used in test suites." n
+ "-compile(export_all)." n n
+
+ "-include_lib(\"common_test/include/ct.hrl\")." n n
+
+ (erlang-skel-separator 2)
+ "%% COMMON TEST CALLBACK FUNCTIONS" n
+ (erlang-skel-separator 2)
+ n
+ (erlang-skel-separator 2)
+ "%% Function: suite() -> Info" n
+ "%%" n
+ "%% Info = [tuple()]" n
+ "%% List of key/value pairs." n
+ "%%" n
+ "%% Description: Returns list of tuples to set default properties" n
+ "%% for the suite." n
+ "%%" n
+ "%% Note: The suite/0 function is only meant to be used to return" n
+ "%% default data values, not perform any other operations." n
+ (erlang-skel-separator 2)
+ "suite() ->" n >
+ "[{timetrap,{minutes,10}}]." n n
+
+ (erlang-skel-separator 2)
+ "%% Function: init_per_suite(Config0) ->" n
+ "%% Config1 | {skip,Reason} | {skip_and_save,Reason,Config1}" n
+ "%%" n
+ "%% Config0 = Config1 = [tuple()]" n
+ "%% A list of key/value pairs, holding the test case configuration." n
+ "%% Reason = term()" n
+ "%% The reason for skipping the suite." n
+ "%%" n
+ "%% Description: Initialization before the suite." n
+ "%%" n
+ "%% Note: This function is free to add any key/value pairs to the Config" n
+ "%% variable, but should NOT alter/remove any existing entries." n
+ (erlang-skel-separator 2)
+ "init_per_suite(Config) ->" n >
+ "Config." n n
+
+ (erlang-skel-separator 2)
+ "%% Function: end_per_suite(Config0) -> void() | {save_config,Config1}" n
+ "%%" n
+ "%% Config0 = Config1 = [tuple()]" n
+ "%% A list of key/value pairs, holding the test case configuration." n
+ "%%" n
+ "%% Description: Cleanup after the suite." n
+ (erlang-skel-separator 2)
+ "end_per_suite(_Config) ->" n >
+ "ok." n n
+
+ (erlang-skel-separator 2)
+ "%% Function: init_per_group(GroupName, Config0) ->" n
+ "%% Config1 | {skip,Reason} | {skip_and_save,Reason,Config1}" n
+ "%%" n
+ "%% GroupName = atom()" n
+ "%% Name of the test case group that is about to run." n
+ "%% Config0 = Config1 = [tuple()]" n
+ "%% A list of key/value pairs, holding configuration data for the group." n
+ "%% Reason = term()" n
+ "%% The reason for skipping all test cases and subgroups in the group." n
+ "%%" n
+ "%% Description: Initialization before each test case group." n
+ (erlang-skel-separator 2)
+ "init_per_group(_GroupName, Config) ->" n >
+ "Config." n n
+
+ (erlang-skel-separator 2)
+ "%% Function: end_per_group(GroupName, Config0) ->" n
+ "%% void() | {save_config,Config1}" n
+ "%%" n
+ "%% GroupName = atom()" n
+ "%% Name of the test case group that is finished." n
+ "%% Config0 = Config1 = [tuple()]" n
+ "%% A list of key/value pairs, holding configuration data for the group." n
+ "%%" n
+ "%% Description: Cleanup after each test case group." n
+ (erlang-skel-separator 2)
+ "end_per_group(_GroupName, _Config) ->" n >
+ "ok." n n
+
+ (erlang-skel-separator 2)
+ "%% Function: init_per_testcase(TestCase, Config0) ->" n
+ "%% Config1 | {skip,Reason} | {skip_and_save,Reason,Config1}" n
+ "%%" n
+ "%% TestCase = atom()" n
+ "%% Name of the test case that is about to run." n
+ "%% Config0 = Config1 = [tuple()]" n
+ "%% A list of key/value pairs, holding the test case configuration." n
+ "%% Reason = term()" n
+ "%% The reason for skipping the test case." n
+ "%%" n
+ "%% Description: Initialization before each test case." n
+ "%%" n
+ "%% Note: This function is free to add any key/value pairs to the Config" n
+ "%% variable, but should NOT alter/remove any existing entries." n
+ (erlang-skel-separator 2)
+ "init_per_testcase(_TestCase, Config) ->" n >
+ "Config." n n
+
+ (erlang-skel-separator 2)
+ "%% Function: end_per_testcase(TestCase, Config0) ->" n
+ "%% void() | {save_config,Config1} | {fail,Reason}" n
+ "%%" n
+ "%% TestCase = atom()" n
+ "%% Name of the test case that is finished." n
+ "%% Config0 = Config1 = [tuple()]" n
+ "%% A list of key/value pairs, holding the test case configuration." n
+ "%% Reason = term()" n
+ "%% The reason for failing the test case." n
+ "%%" n
+ "%% Description: Cleanup after each test case." n
+ (erlang-skel-separator 2)
+ "end_per_testcase(_TestCase, _Config) ->" n >
+ "ok." n n
+
+ (erlang-skel-separator 2)
+ "%% Function: groups() -> [Group]" n
+ "%%" n
+ "%% Group = {GroupName,Properties,GroupsAndTestCases}" n
+ "%% GroupName = atom()" n
+ "%% The name of the group." n
+ "%% Properties = [parallel | sequence | Shuffle | {RepeatType,N}]" n
+ "%% Group properties that may be combined." n
+ "%% GroupsAndTestCases = [Group | {group,GroupName} | TestCase]" n
+ "%% TestCase = atom()" n
+ "%% The name of a test case." n
+ "%% Shuffle = shuffle | {shuffle,Seed}" n
+ "%% To get cases executed in random order." n
+ "%% Seed = {integer(),integer(),integer()}" n
+ "%% RepeatType = repeat | repeat_until_all_ok | repeat_until_all_fail |" n
+ "%% repeat_until_any_ok | repeat_until_any_fail" n
+ "%% To get execution of cases repeated." n
+ "%% N = integer() | forever" n
+ "%%" n
+ "%% Description: Returns a list of test case group definitions." n
+ (erlang-skel-separator 2)
+ "groups() ->" n >
+ "[]." n n
+
+ (erlang-skel-separator 2)
+ "%% Function: all() -> GroupsAndTestCases | {skip,Reason}" n
+ "%%" n
+ "%% GroupsAndTestCases = [{group,GroupName} | TestCase]" n
+ "%% GroupName = atom()" n
+ "%% Name of a test case group." n
+ "%% TestCase = atom()" n
+ "%% Name of a test case." n
+ "%% Reason = term()" n
+ "%% The reason for skipping all groups and test cases." n
+ "%%" n
+ "%% Description: Returns the list of groups and test cases that" n
+ "%% are to be executed." n
+ (erlang-skel-separator 2)
+ "all() -> " n >
+ "[my_test_case]." n n
+
+ n
+ (erlang-skel-separator 2)
+ "%% TEST CASES" n
+ (erlang-skel-separator 2)
+ n
+
+ (erlang-skel-separator 2)
+ "%% Function: TestCase() -> Info" n
+ "%%" n
+ "%% Info = [tuple()]" n
+ "%% List of key/value pairs." n
+ "%%" n
+ "%% Description: Test case info function - returns list of tuples to set" n
+ "%% properties for the test case." n
+ "%%" n
+ "%% Note: This function is only meant to be used to return a list of" n
+ "%% values, not perform any other operations." n
+ (erlang-skel-separator 2)
+ "my_test_case() -> " n >
+ "[]." n n
+
+ (erlang-skel-separator 2)
+ "%% Function: TestCase(Config0) ->" n
+ "%% ok | exit() | {skip,Reason} | {comment,Comment} |" n
+ "%% {save_config,Config1} | {skip_and_save,Reason,Config1}" n
+ "%%" n
+ "%% Config0 = Config1 = [tuple()]" n
+ "%% A list of key/value pairs, holding the test case configuration." n
+ "%% Reason = term()" n
+ "%% The reason for skipping the test case." n
+ "%% Comment = term()" n
+ "%% A comment about the test case that will be printed in the html log." n
+ "%%" n
+ "%% Description: Test case function. (The name of it must be specified in" n
+ "%% the all/0 list or in a test case group for the test case" n
+ "%% to be executed)." n
+ (erlang-skel-separator 2)
+ "my_test_case(_Config) -> " n >
+ "ok." n
+ )
+ "*The template of a library module.
+Please see the function `tempo-define-template'.")
+
+(defvar erlang-skel-ct-test-suite-s
+ '((erlang-skel-include erlang-skel-large-header)
+ "-compile(export_all)." n n
+
+ "-include_lib(\"common_test/include/ct.hrl\")." n n
+
+ (erlang-skel-separator 2)
+ "%% Function: suite() -> Info" n
+ "%% Info = [tuple()]" n
+ (erlang-skel-separator 2)
+ "suite() ->" n >
+ "[{timetrap,{seconds,30}}]." n n
+
+ (erlang-skel-separator 2)
+ "%% Function: init_per_suite(Config0) ->" n
+ "%% Config1 | {skip,Reason} | {skip_and_save,Reason,Config1}" n
+ "%% Config0 = Config1 = [tuple()]" n
+ "%% Reason = term()" n
+ (erlang-skel-separator 2)
+ "init_per_suite(Config) ->" n >
+ "Config." n n
+
+ (erlang-skel-separator 2)
+ "%% Function: end_per_suite(Config0) -> void() | {save_config,Config1}" n
+ "%% Config0 = Config1 = [tuple()]" n
+ (erlang-skel-separator 2)
+ "end_per_suite(_Config) ->" n >
+ "ok." n n
+
+ (erlang-skel-separator 2)
+ "%% Function: init_per_group(GroupName, Config0) ->" n
+ "%% Config1 | {skip,Reason} | {skip_and_save,Reason,Config1}" n
+ "%% GroupName = atom()" n
+ "%% Config0 = Config1 = [tuple()]" n
+ "%% Reason = term()" n
+ (erlang-skel-separator 2)
+ "init_per_group(_GroupName, Config) ->" n >
+ "Config." n n
+
+ (erlang-skel-separator 2)
+ "%% Function: end_per_group(GroupName, Config0) ->" n
+ "%% void() | {save_config,Config1}" n
+ "%% GroupName = atom()" n
+ "%% Config0 = Config1 = [tuple()]" n
+ (erlang-skel-separator 2)
+ "end_per_group(_GroupName, _Config) ->" n >
+ "ok." n n
+
+ (erlang-skel-separator 2)
+ "%% Function: init_per_testcase(TestCase, Config0) ->" n
+ "%% Config1 | {skip,Reason} | {skip_and_save,Reason,Config1}" n
+ "%% TestCase = atom()" n
+ "%% Config0 = Config1 = [tuple()]" n
+ "%% Reason = term()" n
+ (erlang-skel-separator 2)
+ "init_per_testcase(_TestCase, Config) ->" n >
+ "Config." n n
+
+ (erlang-skel-separator 2)
+ "%% Function: end_per_testcase(TestCase, Config0) ->" n
+ "%% void() | {save_config,Config1} | {fail,Reason}" n
+ "%% TestCase = atom()" n
+ "%% Config0 = Config1 = [tuple()]" n
+ "%% Reason = term()" n
+ (erlang-skel-separator 2)
+ "end_per_testcase(_TestCase, _Config) ->" n >
+ "ok." n n
+
+ (erlang-skel-separator 2)
+ "%% Function: groups() -> [Group]" n
+ "%% Group = {GroupName,Properties,GroupsAndTestCases}" n
+ "%% GroupName = atom()" n
+ "%% Properties = [parallel | sequence | Shuffle | {RepeatType,N}]" n
+ "%% GroupsAndTestCases = [Group | {group,GroupName} | TestCase]" n
+ "%% TestCase = atom()" n
+ "%% Shuffle = shuffle | {shuffle,{integer(),integer(),integer()}}" n
+ "%% RepeatType = repeat | repeat_until_all_ok | repeat_until_all_fail |" n
+ "%% repeat_until_any_ok | repeat_until_any_fail" n
+ "%% N = integer() | forever" n
+ (erlang-skel-separator 2)
+ "groups() ->" n >
+ "[]." n n
+
+ (erlang-skel-separator 2)
+ "%% Function: all() -> GroupsAndTestCases | {skip,Reason}" n
+ "%% GroupsAndTestCases = [{group,GroupName} | TestCase]" n
+ "%% GroupName = atom()" n
+ "%% TestCase = atom()" n
+ "%% Reason = term()" n
+ (erlang-skel-separator 2)
+ "all() -> " n >
+ "[my_test_case]." n n
+
+ (erlang-skel-separator 2)
+ "%% Function: TestCase() -> Info" n
+ "%% Info = [tuple()]" n
+ (erlang-skel-separator 2)
+ "my_test_case() -> " n >
+ "[]." n n
+
+ (erlang-skel-separator 2)
+ "%% Function: TestCase(Config0) ->" n
+ "%% ok | exit() | {skip,Reason} | {comment,Comment} |" n
+ "%% {save_config,Config1} | {skip_and_save,Reason,Config1}" n
+ "%% Config0 = Config1 = [tuple()]" n
+ "%% Reason = term()" n
+ "%% Comment = term()" n
+ (erlang-skel-separator 2)
+ "my_test_case(_Config) -> " n >
+ "ok." n
+ )
+ "*The template of a library module.
+Please see the function `tempo-define-template'.")
diff --git a/lib/tools/emacs/erlang-skels.el b/lib/tools/emacs/erlang-skels.el
new file mode 100644
index 0000000000..355b223822
--- /dev/null
+++ b/lib/tools/emacs/erlang-skels.el
@@ -0,0 +1,1553 @@
+;;
+;; %CopyrightBegin%
+;;
+;; Copyright Ericsson AB 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%
+;;;
+;;; Purpose: Provide Erlang code skeletons.
+;;; See 'erlang-skel-file' variable.
+
+(defvar erlang-tempo-tags nil
+ "Tempo tags for erlang mode")
+
+(defvar erlang-skel
+ '(("If" "if" erlang-skel-if)
+ ("Case" "case" erlang-skel-case)
+ ("Receive" "receive" erlang-skel-receive)
+ ("Receive After" "after" erlang-skel-receive-after)
+ ("Receive Loop" "loop" erlang-skel-receive-loop)
+ ("Module" "module" erlang-skel-module)
+ ("Author" "author" erlang-skel-author)
+ ("Function" "function" erlang-skel-function)
+ ()
+ ("Small Header" "small-header"
+ erlang-skel-small-header erlang-skel-header)
+ ("Normal Header" "normal-header"
+ erlang-skel-normal-header erlang-skel-header)
+ ("Large Header" "large-header"
+ erlang-skel-large-header erlang-skel-header)
+ ()
+ ("Small Server" "small-server"
+ erlang-skel-small-server erlang-skel-header)
+ ()
+ ("Application" "application"
+ erlang-skel-application erlang-skel-header)
+ ("Supervisor" "supervisor"
+ erlang-skel-supervisor erlang-skel-header)
+ ("supervisor_bridge" "supervisor-bridge"
+ erlang-skel-supervisor-bridge erlang-skel-header)
+ ("gen_server" "generic-server"
+ erlang-skel-generic-server erlang-skel-header)
+ ("gen_event" "gen-event"
+ erlang-skel-gen-event erlang-skel-header)
+ ("gen_fsm" "gen-fsm"
+ erlang-skel-gen-fsm erlang-skel-header)
+ ("Library module" "gen-lib"
+ erlang-skel-lib erlang-skel-header)
+ ("Corba callback" "gen-corba-cb"
+ erlang-skel-corba-callback erlang-skel-header)
+ ("Small Common Test suite" "ct-test-suite-s"
+ erlang-skel-ct-test-suite-s erlang-skel-header)
+ ("Large Common Test suite" "ct-test-suite-l"
+ erlang-skel-ct-test-suite-l erlang-skel-header)
+ ("Erlang TS test suite" "ts-test-suite"
+ erlang-skel-ts-test-suite erlang-skel-header)
+ )
+ "*Description of all skeleton templates.
+Both functions and menu entries will be created.
+
+Each entry in `erlang-skel' should be a list with three or four
+elements, or the empty list.
+
+The first element is the name which shows up in the menu. The second
+is the `tempo' identifier (The string \"erlang-\" will be added in
+front of it). The third is the skeleton descriptor, a variable
+containing `tempo' attributes as described in the function
+`tempo-define-template'. The optional fourth elements denotes a
+function which should be called when the menu is selected.
+
+Functions corresponding to every template will be created. The name
+of the function will be `tempo-template-erlang-X' where `X' is the
+tempo identifier as specified in the second argument of the elements
+in this list.
+
+A list with zero elements means that the a horizontal line should
+be placed in the menu.")
+
+(defvar erlang-skel-use-separators t
+ "A boolean than determines whether the skeletons include horizontal
+separators.
+
+Should this variable be nil, the documentation for functions will not
+include separators of the form %%--...")
+
+;; In XEmacs `user-mail-address' returns "[email protected] (Foo Bar)" ARGH!
+;; What's wrong with that? RFC 822 says it's legal. [sverkerw]
+;; This needs to use the customized value. If that's not sane, things like
+;; add-log will lose anyhow. Avoid it if there _is_ a paren.
+(defvar erlang-skel-mail-address
+ (if (or (not user-mail-address) (string-match "(" user-mail-address))
+ (concat (user-login-name) "@"
+ (or (and (boundp 'mail-host-address)
+ mail-host-address)
+ (system-name)))
+ user-mail-address)
+ "Mail address of the user.")
+
+;; Expression templates:
+(defvar erlang-skel-case
+ '((erlang-skel-skip-blank) o >
+ "case " p " of" n> p "_ ->" n> p "ok" n> "end" p)
+ "*The skeleton of a `case' expression.
+Please see the function `tempo-define-template'.")
+
+(defvar erlang-skel-if
+ '((erlang-skel-skip-blank) o >
+ "if" n> p " ->" n> p "ok" n> "end" p)
+ "The skeleton of an `if' expression.
+Please see the function `tempo-define-template'.")
+
+(defvar erlang-skel-receive
+ '((erlang-skel-skip-blank) o >
+ "receive" n> p "_ ->" n> p "ok" n> "end" p)
+ "*The skeleton of a `receive' expression.
+Please see the function `tempo-define-template'.")
+
+(defvar erlang-skel-receive-after
+ '((erlang-skel-skip-blank) o >
+ "receive" n> p "_ ->" n> p "ok" n> "after " p "T ->" n>
+ p "ok" n> "end" p)
+ "*The skeleton of a `receive' expression with an `after' clause.
+Please see the function `tempo-define-template'.")
+
+(defvar erlang-skel-receive-loop
+ '(& o "loop(" p ") ->" n> "receive" n> p "_ ->" n>
+ "loop(" p ")" n> "end.")
+ "*The skeleton of a simple `receive' loop.
+Please see the function `tempo-define-template'.")
+
+
+(defvar erlang-skel-function
+ '((erlang-skel-separator-start 2)
+ "%% @doc" n
+ "%% @spec" n
+ (erlang-skel-separator-end 2))
+ "*The template of a function skeleton.
+Please see the function `tempo-define-template'.")
+
+
+;; Attribute templates
+
+(defvar erlang-skel-module
+ '(& "-module("
+ (erlang-add-quotes-if-needed (erlang-get-module-from-file-name))
+ ")." n)
+ "*The skeleton of a `module' attribute.
+Please see the function `tempo-define-template'.")
+
+(defvar erlang-skel-author
+ '(& "-author('" erlang-skel-mail-address "')." n)
+ "*The skeleton of a `author' attribute.
+Please see the function `tempo-define-template'.")
+
+(defvar erlang-skel-vc nil
+ "*The skeleton template to generate a version control attribute.
+The default is to insert nothing. Example of usage:
+
+ (setq erlang-skel-vc '(& \"-rcs(\\\"$\Id: $ \\\").\") n)
+
+Please see the function `tempo-define-template'.")
+
+(defvar erlang-skel-export
+ '(& "-export([" n> "])." n)
+ "*The skeleton of an `export' attribute.
+Please see the function `tempo-define-template'.")
+
+(defvar erlang-skel-import
+ '(& "%%-import(Module, [Function/Arity, ...])." n)
+ "*The skeleton of an `import' attribute.
+Please see the function `tempo-define-template'.")
+
+(defvar erlang-skel-compile nil
+ ;; '(& "%%-compile(export_all)." n)
+ "*The skeleton of a `compile' attribute.
+Please see the function `tempo-define-template'.")
+
+
+;; Comment templates.
+
+(defvar erlang-skel-date-function 'erlang-skel-dd-mmm-yyyy
+ "*Function which returns date string.
+Look in the module `time-stamp' for a battery of functions.")
+
+(defvar erlang-skel-copyright-comment
+ (if (boundp '*copyright-organization*)
+ '(& "%%% @copyright (C) " (format-time-string "%Y") ", "
+ *copyright-organization* n)
+ '(& "%%% @copyright (C) " (format-time-string "%Y") ", "
+ (user-full-name) n))
+ "*The template for a copyright line in the header, normally empty.
+This variable should be bound to a `tempo' template, for example:
+ '(& \"%%% Copyright (C) 2000, Yoyodyne, Inc.\" n)
+Please see the function `tempo-define-template'.")
+
+(defvar erlang-skel-created-comment
+ '(& "%%% Created : " (funcall erlang-skel-date-function) " by "
+ (user-full-name) " <" erlang-skel-mail-address ">" n)
+ "*The template for the \"Created:\" comment line.")
+
+(defvar erlang-skel-author-comment
+ '(& "%%% @author " (user-full-name) " <" erlang-skel-mail-address ">" n)
+ "*The template for creating the \"Author:\" line in the header.
+Please see the function `tempo-define-template'.")
+
+(defvar erlang-skel-small-header
+ '(o (erlang-skel-include erlang-skel-module)
+ n
+ (erlang-skel-include erlang-skel-compile erlang-skel-vc))
+ "*The template of a small header without any comments.
+Please see the function `tempo-define-template'.")
+
+(defvar erlang-skel-normal-header
+ '(o (erlang-skel-include erlang-skel-author-comment)
+ (erlang-skel-include erlang-skel-copyright-comment)
+ "%%% @doc" n
+ "%%%" p n
+ "%%% @end" n
+ (erlang-skel-include erlang-skel-created-comment) n
+ (erlang-skel-include erlang-skel-small-header) n)
+ "*The template of a normal header.
+Please see the function `tempo-define-template'.")
+
+(defvar erlang-skel-large-header
+ '(o (erlang-skel-separator)
+ (erlang-skel-include erlang-skel-author-comment)
+ (erlang-skel-include erlang-skel-copyright-comment)
+ "%%% @doc" n
+ "%%%" p n
+ "%%% @end" n
+ (erlang-skel-include erlang-skel-created-comment)
+ (erlang-skel-separator)
+ (erlang-skel-include erlang-skel-small-header) )
+ "*The template of a large header.
+Please see the function `tempo-define-template'.")
+
+
+ ;; Server templates.
+(defvar erlang-skel-small-server
+ '((erlang-skel-include erlang-skel-large-header)
+ "-export([start/0, init/1])." n n n
+ "start() ->" n> "spawn(" (erlang-get-module-from-file-name)
+ ", init, [self()])." n n
+ "init(From) ->" n>
+ "loop(From)." n n
+ "loop(From) ->" n>
+ "receive" n>
+ p "_ ->" n>
+ "loop(From)" n>
+ "end." n
+ )
+ "*Template of a small server.
+Please see the function `tempo-define-template'.")
+
+;; Behaviour templates.
+(defvar erlang-skel-application
+ '((erlang-skel-include erlang-skel-large-header)
+ "-behaviour(application)." n n
+ "%% Application callbacks" n
+ "-export([start/2, stop/1])." n n
+ (erlang-skel-double-separator-start 3)
+ "%%% Application callbacks" n
+ (erlang-skel-double-separator-end 3) n
+ (erlang-skel-separator-start 2)
+ "%% @private" n
+ "%% @doc" n
+ "%% This function is called whenever an application is started using" n
+ "%% application:start/[1,2], and should start the processes of the" n
+ "%% application. If the application is structured according to the OTP" n
+ "%% design principles as a supervision tree, this means starting the" n
+ "%% top supervisor of the tree." n
+ "%%" n
+ "%% @spec start(StartType, StartArgs) -> {ok, Pid} |" n
+ "%% {ok, Pid, State} |" n
+ "%% {error, Reason}" n
+ "%% StartType = normal | {takeover, Node} | {failover, Node}" n
+ "%% StartArgs = term()" n
+ (erlang-skel-separator-end 2)
+ "start(_StartType, _StartArgs) ->" n>
+ "case 'TopSupervisor':start_link() of" n>
+ "{ok, Pid} ->" n>
+ "{ok, Pid};" n>
+ "Error ->" n>
+ "Error" n>
+ "end." n
+ n
+ (erlang-skel-separator-start 2)
+ "%% @private" n
+ "%% @doc" n
+ "%% This function is called whenever an application has stopped. It" n
+ "%% is intended to be the opposite of Module:start/2 and should do" n
+ "%% any necessary cleaning up. The return value is ignored." n
+ "%%" n
+ "%% @spec stop(State) -> void()" n
+ (erlang-skel-separator-end 2)
+ "stop(_State) ->" n>
+ "ok." n
+ n
+ (erlang-skel-double-separator-start 3)
+ "%%% Internal functions" n
+ (erlang-skel-double-separator-end 3)
+ )
+ "*The template of an application behaviour.
+Please see the function `tempo-define-template'.")
+
+(defvar erlang-skel-supervisor
+ '((erlang-skel-include erlang-skel-large-header)
+ "-behaviour(supervisor)." n n
+
+ "%% API" n
+ "-export([start_link/0])." n n
+
+ "%% Supervisor callbacks" n
+ "-export([init/1])." n n
+
+ "-define(SERVER, ?MODULE)." n n
+
+ (erlang-skel-double-separator-start 3)
+ "%%% API functions" n
+ (erlang-skel-double-separator-end 3) n
+ (erlang-skel-separator-start 2)
+ "%% @doc" n
+ "%% Starts the supervisor" n
+ "%%" n
+ "%% @spec start_link() -> {ok, Pid} | ignore | {error, Error}" n
+ (erlang-skel-separator-end 2)
+ "start_link() ->" n>
+ "supervisor:start_link({local, ?SERVER}, ?MODULE, [])." n
+ n
+ (erlang-skel-double-separator-start 3)
+ "%%% Supervisor callbacks" n
+ (erlang-skel-double-separator-end 3) n
+ (erlang-skel-separator-start 2)
+ "%% @private" n
+ "%% @doc" n
+ "%% Whenever a supervisor is started using supervisor:start_link/[2,3]," n
+ "%% this function is called by the new process to find out about" n
+ "%% restart strategy, maximum restart frequency and child" n
+ "%% specifications." n
+ "%%" n
+ "%% @spec init(Args) -> {ok, {SupFlags, [ChildSpec]}} |" n
+ "%% ignore |" n
+ "%% {error, Reason}" n
+ (erlang-skel-separator-end 2)
+ "init([]) ->" n>
+ "RestartStrategy = one_for_one," n>
+ "MaxRestarts = 1000," n>
+ "MaxSecondsBetweenRestarts = 3600," n
+ "" n>
+ "SupFlags = {RestartStrategy, MaxRestarts, MaxSecondsBetweenRestarts}," n
+ "" n>
+ "Restart = permanent," n>
+ "Shutdown = 2000," n>
+ "Type = worker," n
+ "" n>
+ "AChild = {'AName', {'AModule', start_link, []}," n>
+ "Restart, Shutdown, Type, ['AModule']}," n
+ "" n>
+ "{ok, {SupFlags, [AChild]}}." n
+ n
+ (erlang-skel-double-separator-start 3)
+ "%%% Internal functions" n
+ (erlang-skel-double-separator-end 3)
+ )
+ "*The template of an supervisor behaviour.
+Please see the function `tempo-define-template'.")
+
+(defvar erlang-skel-supervisor-bridge
+ '((erlang-skel-include erlang-skel-large-header)
+ "-behaviour(supervisor_bridge)." n n
+
+ "%% API" n
+ "-export([start_link/0])." n n
+
+ "%% supervisor_bridge callbacks" n
+ "-export([init/1, terminate/2])." n n
+
+ "-define(SERVER, ?MODULE)." n n
+
+ "-record(state, {})." n n
+
+ (erlang-skel-double-separator-start 3)
+ "%%% API" n
+ (erlang-skel-double-separator-end 3) n
+ (erlang-skel-separator-start 2)
+ "%% @doc" n
+ "%% Starts the supervisor bridge" n
+ "%%" n
+ "%% @spec start_link() -> {ok, Pid} | ignore | {error, Error}" n
+ (erlang-skel-separator-end 2)
+ "start_link() ->" n>
+ "supervisor_bridge:start_link({local, ?SERVER}, ?MODULE, [])." n
+ n
+ (erlang-skel-double-separator-start 3)
+ "%%% supervisor_bridge callbacks" n
+ (erlang-skel-double-separator-end 3) n
+ (erlang-skel-separator-start 2)
+ "%% @private" n
+ "%% @doc" n
+ "%% Creates a supervisor_bridge process, linked to the calling process," n
+ "%% which calls Module:init/1 to start the subsystem. To ensure a" n
+ "%% synchronized start-up procedure, this function does not return" n
+ "%% until Module:init/1 has returned." n
+ "%%" n
+ "%% @spec init(Args) -> {ok, Pid, State} |" n
+ "%% ignore |" n
+ "%% {error, Reason}" n
+ (erlang-skel-separator-end 2)
+ "init([]) ->" n>
+ "case 'AModule':start_link() of" n>
+ "{ok, Pid} ->" n>
+ "{ok, Pid, #state{}};" n>
+ "Error ->" n>
+ "Error" n>
+ "end." n
+ n
+ (erlang-skel-separator-start 2)
+ "%% @private" n
+ "%% @doc" n
+ "%% This function is called by the supervisor_bridge when it is about" n
+ "%% to terminate. It should be the opposite of Module:init/1 and stop" n
+ "%% the subsystem and do any necessary cleaning up.The return value is" n
+ "%% ignored." n
+ "%%" n
+ "%% @spec terminate(Reason, State) -> void()" n
+ (erlang-skel-separator-end 2)
+ "terminate(Reason, State) ->" n>
+ "'AModule':stop()," n>
+ "ok." n
+ n
+ (erlang-skel-double-separator-start 3)
+ "%%% Internal functions" n
+ (erlang-skel-double-separator-end 3)
+ )
+ "*The template of an supervisor_bridge behaviour.
+Please see the function `tempo-define-template'.")
+
+(defvar erlang-skel-generic-server
+ '((erlang-skel-include erlang-skel-large-header)
+ "-behaviour(gen_server)." n n
+
+ "%% API" n
+ "-export([start_link/0])." n n
+
+ "%% gen_server callbacks" n
+ "-export([init/1, handle_call/3, handle_cast/2, "
+ "handle_info/2," n>
+ "terminate/2, code_change/3])." n n
+
+ "-define(SERVER, ?MODULE). " n n
+
+ "-record(state, {})." n n
+
+ (erlang-skel-double-separator-start 3)
+ "%%% API" n
+ (erlang-skel-double-separator-end 3) n
+ (erlang-skel-separator-start 2)
+ "%% @doc" n
+ "%% Starts the server" n
+ "%%" n
+ "%% @spec start_link() -> {ok, Pid} | ignore | {error, Error}" n
+ (erlang-skel-separator-end 2)
+ "start_link() ->" n>
+ "gen_server:start_link({local, ?SERVER}, ?MODULE, [], [])." n
+ n
+ (erlang-skel-double-separator-start 3)
+ "%%% gen_server callbacks" n
+ (erlang-skel-double-separator-end 3)
+ n
+ (erlang-skel-separator-start 2)
+ "%% @private" n
+ "%% @doc" n
+ "%% Initializes the server" n
+ "%%" n
+ "%% @spec init(Args) -> {ok, State} |" n
+ "%% {ok, State, Timeout} |" n
+ "%% ignore |" n
+ "%% {stop, Reason}" n
+ (erlang-skel-separator-end 2)
+ "init([]) ->" n>
+ "{ok, #state{}}." n
+ n
+ (erlang-skel-separator-start 2)
+ "%% @private" n
+ "%% @doc" n
+ "%% Handling call messages" n
+ "%%" n
+ "%% @spec handle_call(Request, From, State) ->" n
+ "%% {reply, Reply, State} |" n
+ "%% {reply, Reply, State, Timeout} |" n
+ "%% {noreply, State} |" n
+ "%% {noreply, State, Timeout} |" n
+ "%% {stop, Reason, Reply, State} |" n
+ "%% {stop, Reason, State}" n
+ (erlang-skel-separator-end 2)
+ "handle_call(_Request, _From, State) ->" n>
+ "Reply = ok," n>
+ "{reply, Reply, State}." n
+ n
+ (erlang-skel-separator-start 2)
+ "%% @private" n
+ "%% @doc" n
+ "%% Handling cast messages" n
+ "%%" n
+ "%% @spec handle_cast(Msg, State) -> {noreply, State} |" n
+ "%% {noreply, State, Timeout} |" n
+ "%% {stop, Reason, State}" n
+ (erlang-skel-separator-end 2)
+ "handle_cast(_Msg, State) ->" n>
+ "{noreply, State}." n
+ n
+ (erlang-skel-separator-start 2)
+ "%% @private" n
+ "%% @doc" n
+ "%% Handling all non call/cast messages" n
+ "%%" n
+ "%% @spec handle_info(Info, State) -> {noreply, State} |" n
+ "%% {noreply, State, Timeout} |" n
+ "%% {stop, Reason, State}" n
+ (erlang-skel-separator-end 2)
+ "handle_info(_Info, State) ->" n>
+ "{noreply, State}." n
+ n
+ (erlang-skel-separator-start 2)
+ "%% @private" n
+ "%% @doc" n
+ "%% This function is called by a gen_server when it is about to" n
+ "%% terminate. It should be the opposite of Module:init/1 and do any" n
+ "%% necessary cleaning up. When it returns, the gen_server terminates" n
+ "%% with Reason. The return value is ignored." n
+ "%%" n
+ "%% @spec terminate(Reason, State) -> void()" n
+ (erlang-skel-separator-end 2)
+ "terminate(_Reason, _State) ->" n>
+ "ok." n
+ n
+ (erlang-skel-separator-start 2)
+ "%% @private" n
+ "%% @doc" n
+ "%% Convert process state when code is changed" n
+ "%%" n
+ "%% @spec code_change(OldVsn, State, Extra) -> {ok, NewState}" n
+ (erlang-skel-separator-end 2)
+ "code_change(_OldVsn, State, _Extra) ->" n>
+ "{ok, State}." n
+ n
+ (erlang-skel-double-separator-start 3)
+ "%%% Internal functions" n
+ (erlang-skel-double-separator-end 3)
+ )
+ "*The template of a generic server.
+Please see the function `tempo-define-template'.")
+
+(defvar erlang-skel-gen-event
+ '((erlang-skel-include erlang-skel-large-header)
+ "-behaviour(gen_event)." n n
+
+ "%% API" n
+ "-export([start_link/0, add_handler/0])." n n
+
+ "%% gen_event callbacks" n
+ "-export([init/1, handle_event/2, handle_call/2, " n>
+ "handle_info/2, terminate/2, code_change/3])." n n
+
+ "-define(SERVER, ?MODULE). " n n
+
+ "-record(state, {})." n n
+
+ (erlang-skel-double-separator-start 3)
+ "%%% gen_event callbacks" n
+ (erlang-skel-double-separator-end 3) n
+ (erlang-skel-separator-start 2)
+ "%% @doc" n
+ "%% Creates an event manager" n
+ "%%" n
+ "%% @spec start_link() -> {ok, Pid} | {error, Error}" n
+ (erlang-skel-separator-end 2)
+ "start_link() ->" n>
+ "gen_event:start_link({local, ?SERVER})." n
+ n
+ (erlang-skel-separator-start 2)
+ "%% @doc" n
+ "%% Adds an event handler" n
+ "%%" n
+ "%% @spec add_handler() -> ok | {'EXIT', Reason} | term()" n
+ (erlang-skel-separator-end 2)
+ "add_handler() ->" n>
+ "gen_event:add_handler(?SERVER, ?MODULE, [])." n
+ n
+ (erlang-skel-double-separator-start 3)
+ "%%% gen_event callbacks" n
+ (erlang-skel-double-separator-end 3) n
+ (erlang-skel-separator-start 2)
+ "%% @private" n
+ "%% @doc" n
+ "%% Whenever a new event handler is added to an event manager," n
+ "%% this function is called to initialize the event handler." n
+ "%%" n
+ "%% @spec init(Args) -> {ok, State}" n
+ (erlang-skel-separator-end 2)
+ "init([]) ->" n>
+ "{ok, #state{}}." n
+ n
+ (erlang-skel-separator-start 2)
+ "%% @private" n
+ "%% @doc" n
+ "%% Whenever an event manager receives an event sent using" n
+ "%% gen_event:notify/2 or gen_event:sync_notify/2, this function is" n
+ "%% called for each installed event handler to handle the event." n
+ "%%" n
+ "%% @spec handle_event(Event, State) ->" n
+ "%% {ok, State} |" n
+ "%% {swap_handler, Args1, State1, Mod2, Args2} |"n
+ "%% remove_handler" n
+ (erlang-skel-separator-end 2)
+ "handle_event(_Event, State) ->" n>
+ "{ok, State}." n
+ n
+ (erlang-skel-separator-start 2)
+ "%% @private" n
+ "%% @doc" n
+ "%% Whenever an event manager receives a request sent using" n
+ "%% gen_event:call/3,4, this function is called for the specified" n
+ "%% event handler to handle the request." n
+ "%%" n
+ "%% @spec handle_call(Request, State) ->" n
+ "%% {ok, Reply, State} |" n
+ "%% {swap_handler, Reply, Args1, State1, Mod2, Args2} |" n
+ "%% {remove_handler, Reply}" n
+ (erlang-skel-separator-end 2)
+ "handle_call(_Request, State) ->" n>
+ "Reply = ok," n>
+ "{ok, Reply, State}." n
+ n
+ (erlang-skel-separator-start 2)
+ "%% @private" n
+ "%% @doc" n
+ "%% This function is called for each installed event handler when" n
+ "%% an event manager receives any other message than an event or a" n
+ "%% synchronous request (or a system message)." n
+ "%%" n
+ "%% @spec handle_info(Info, State) ->" n
+ "%% {ok, State} |" n
+ "%% {swap_handler, Args1, State1, Mod2, Args2} |" n
+ "%% remove_handler" n
+ (erlang-skel-separator-end 2)
+ "handle_info(_Info, State) ->" n>
+ "{ok, State}." n
+ n
+ (erlang-skel-separator-start 2)
+ "%% @private" n
+ "%% @doc" n
+ "%% Whenever an event handler is deleted from an event manager, this" n
+ "%% function is called. It should be the opposite of Module:init/1 and" n
+ "%% do any necessary cleaning up." n
+ "%%" n
+ "%% @spec terminate(Reason, State) -> void()" n
+ (erlang-skel-separator-end 2)
+ "terminate(_Reason, _State) ->" n>
+ "ok." n
+ n
+ (erlang-skel-separator-start 2)
+ "%% @private" n
+ "%% @doc" n
+ "%% Convert process state when code is changed" n
+ "%%" n
+ "%% @spec code_change(OldVsn, State, Extra) -> {ok, NewState}" n
+ (erlang-skel-separator-end 2)
+ "code_change(_OldVsn, State, _Extra) ->" n>
+ "{ok, State}." n
+ n
+ (erlang-skel-double-separator-start 3)
+ "%%% Internal functions" n
+ (erlang-skel-double-separator-end 3)
+ )
+ "*The template of a gen_event.
+Please see the function `tempo-define-template'.")
+
+(defvar erlang-skel-gen-fsm
+ '((erlang-skel-include erlang-skel-large-header)
+ "-behaviour(gen_fsm)." n n
+
+ "%% API" n
+ "-export([start_link/0])." n n
+
+ "%% gen_fsm callbacks" n
+ "-export([init/1, state_name/2, state_name/3, handle_event/3," n>
+ "handle_sync_event/4, handle_info/3, terminate/3, code_change/4])." n n
+
+ "-define(SERVER, ?MODULE)." n n
+
+ "-record(state, {})." n n
+
+ (erlang-skel-double-separator-start 3)
+ "%%% API" n
+ (erlang-skel-double-separator-end 3) n
+ (erlang-skel-separator-start 2)
+ "%% @doc" n
+ "%% Creates a gen_fsm process which calls Module:init/1 to" n
+ "%% initialize. To ensure a synchronized start-up procedure, this" n
+ "%% function does not return until Module:init/1 has returned." n
+ "%%" n
+ "%% @spec start_link() -> {ok, Pid} | ignore | {error, Error}" n
+ (erlang-skel-separator-end 2)
+ "start_link() ->" n>
+ "gen_fsm:start_link({local, ?SERVER}, ?MODULE, [], [])." n
+ n
+ (erlang-skel-double-separator-start 3)
+ "%%% gen_fsm callbacks" n
+ (erlang-skel-double-separator-end 3) n
+ (erlang-skel-separator-start 2)
+ "%% @private" n
+ "%% @doc" n
+ "%% Whenever a gen_fsm is started using gen_fsm:start/[3,4] or" n
+ "%% gen_fsm:start_link/[3,4], this function is called by the new" n
+ "%% process to initialize." n
+ "%%" n
+ "%% @spec init(Args) -> {ok, StateName, State} |" n
+ "%% {ok, StateName, State, Timeout} |" n
+ "%% ignore |" n
+ "%% {stop, StopReason}" n
+ (erlang-skel-separator-end 2)
+ "init([]) ->" n>
+ "{ok, state_name, #state{}}." n
+ n
+ (erlang-skel-separator-start 2)
+ "%% @private" n
+ "%% @doc" n
+ "%% There should be one instance of this function for each possible" n
+ "%% state name. Whenever a gen_fsm receives an event sent using" n
+ "%% gen_fsm:send_event/2, the instance of this function with the same" n
+ "%% name as the current state name StateName is called to handle" n
+ "%% the event. It is also called if a timeout occurs." n
+ "%%" n
+ "%% @spec state_name(Event, State) ->" n
+ "%% {next_state, NextStateName, NextState} |" n
+ "%% {next_state, NextStateName, NextState, Timeout} |" n
+ "%% {stop, Reason, NewState}" n
+ (erlang-skel-separator-end 2)
+ "state_name(_Event, State) ->" n>
+ "{next_state, state_name, State}." n
+ n
+ (erlang-skel-separator-start 2)
+ "%% @private" n
+ "%% @doc" n
+ "%% There should be one instance of this function for each possible" n
+ "%% state name. Whenever a gen_fsm receives an event sent using" n
+ "%% gen_fsm:sync_send_event/[2,3], the instance of this function with" n
+ "%% the same name as the current state name StateName is called to" n
+ "%% handle the event." n
+ "%%" n
+ "%% @spec state_name(Event, From, State) ->" n
+ "%% {next_state, NextStateName, NextState} |"n
+ "%% {next_state, NextStateName, NextState, Timeout} |" n
+ "%% {reply, Reply, NextStateName, NextState} |" n
+ "%% {reply, Reply, NextStateName, NextState, Timeout} |" n
+ "%% {stop, Reason, NewState} |" n
+ "%% {stop, Reason, Reply, NewState}" n
+ (erlang-skel-separator-end 2)
+ "state_name(_Event, _From, State) ->" n>
+ "Reply = ok," n>
+ "{reply, Reply, state_name, State}." n
+ n
+ (erlang-skel-separator-start 2)
+ "%% @private" n
+ "%% @doc" n
+ "%% Whenever a gen_fsm receives an event sent using" n
+ "%% gen_fsm:send_all_state_event/2, this function is called to handle" n
+ "%% the event." n
+ "%%" n
+ "%% @spec handle_event(Event, StateName, State) ->" n
+ "%% {next_state, NextStateName, NextState} |" n
+ "%% {next_state, NextStateName, NextState, Timeout} |" n
+ "%% {stop, Reason, NewState}" n
+ (erlang-skel-separator-end 2)
+ "handle_event(_Event, StateName, State) ->" n>
+ "{next_state, StateName, State}." n
+ n
+ (erlang-skel-separator-start 2)
+ "%% @private" n
+ "%% @doc" n
+ "%% Whenever a gen_fsm receives an event sent using" n
+ "%% gen_fsm:sync_send_all_state_event/[2,3], this function is called" n
+ "%% to handle the event." n
+ "%%" n
+ "%% @spec handle_sync_event(Event, From, StateName, State) ->" n
+ "%% {next_state, NextStateName, NextState} |" n
+ "%% {next_state, NextStateName, NextState, Timeout} |" n
+ "%% {reply, Reply, NextStateName, NextState} |" n
+ "%% {reply, Reply, NextStateName, NextState, Timeout} |" n
+ "%% {stop, Reason, NewState} |" n
+ "%% {stop, Reason, Reply, NewState}" n
+ (erlang-skel-separator-end 2)
+ "handle_sync_event(_Event, _From, StateName, State) ->" n>
+ "Reply = ok," n>
+ "{reply, Reply, StateName, State}." n
+ n
+ (erlang-skel-separator-start 2)
+ "%% @private" n
+ "%% @doc" n
+ "%% This function is called by a gen_fsm when it receives any" n
+ "%% message other than a synchronous or asynchronous event" n
+ "%% (or a system message)." n
+ "%%" n
+ "%% @spec handle_info(Info,StateName,State)->" n
+ "%% {next_state, NextStateName, NextState} |" n
+ "%% {next_state, NextStateName, NextState, Timeout} |" n
+ "%% {stop, Reason, NewState}" n
+ (erlang-skel-separator-end 2)
+ "handle_info(_Info, StateName, State) ->" n>
+ "{next_state, StateName, State}." n
+ n
+ (erlang-skel-separator-start 2)
+ "%% @private" n
+ "%% @doc" n
+ "%% This function is called by a gen_fsm when it is about to" n
+ "%% terminate. It should be the opposite of Module:init/1 and do any" n
+ "%% necessary cleaning up. When it returns, the gen_fsm terminates with" n
+ "%% Reason. The return value is ignored." n
+ "%%" n
+ "%% @spec terminate(Reason, StateName, State) -> void()" n
+ (erlang-skel-separator-end 2)
+ "terminate(_Reason, _StateName, _State) ->" n>
+ "ok." n
+ n
+ (erlang-skel-separator-start 2)
+ "%% @private" n
+ "%% @doc" n
+ "%% Convert process state when code is changed" n
+ "%%" n
+ "%% @spec code_change(OldVsn, StateName, State, Extra) ->" n
+ "%% {ok, StateName, NewState}" n
+ (erlang-skel-separator-end 2)
+ "code_change(_OldVsn, StateName, State, _Extra) ->" n>
+ "{ok, StateName, State}." n
+ n
+ (erlang-skel-double-separator-start 3)
+ "%%% Internal functions" n
+ (erlang-skel-double-separator-end 3)
+ )
+ "*The template of a gen_fsm.
+Please see the function `tempo-define-template'.")
+
+(defvar erlang-skel-lib
+ '((erlang-skel-include erlang-skel-large-header)
+
+ "%% API" n
+ "-export([])." n n
+
+ (erlang-skel-double-separator-start 3)
+ "%%% API" n
+ (erlang-skel-double-separator-end 3) n
+ (erlang-skel-separator-start 2)
+ "%% @doc" n
+ "%% @spec" n
+ (erlang-skel-separator-end 2)
+ n
+ (erlang-skel-double-separator-start 3)
+ "%%% Internal functions" n
+ (erlang-skel-double-separator-end 3)
+ )
+ "*The template of a library module.
+Please see the function `tempo-define-template'.")
+
+(defvar erlang-skel-corba-callback
+ '((erlang-skel-include erlang-skel-large-header)
+ "%% Include files" n n
+
+ "%% API" n
+ "-export([])." n n
+
+ "%% Corba callbacks" n
+ "-export([init/1, terminate/2, code_change/3])." n n
+
+ "-record(state, {})." n n
+
+ (erlang-skel-double-separator-start 3)
+ "%%% Corba callbacks" n
+ (erlang-skel-double-separator-end 3) n
+ (erlang-skel-separator-start 2)
+ "%% @private" n
+ "%% @doc" n
+ "%% Initializes the server" n
+ "%%" n
+ "%% @spec init(Args) -> {ok, State} |" n
+ "%% {ok, State, Timeout} |" n
+ "%% ignore |" n
+ "%% {stop, Reason}" n
+ (erlang-skel-separator-end 2)
+ "init([]) ->" n>
+ "{ok, #state{}}." n
+ n
+ (erlang-skel-separator-start 2)
+ "%% @private" n
+ "%% @doc" n
+ "%% Shutdown the server" n
+ "%%" n
+ "%% @spec terminate(Reason, State) -> void()" n
+ (erlang-skel-separator-end 2)
+ "terminate(_Reason, _State) ->" n>
+ "ok." n
+ n
+ (erlang-skel-separator-start 2)
+ "%% @private" n
+ "%% @doc" n
+ "%% Convert process state when code is changed" n
+ "%%" n
+ "%% @spec code_change(OldVsn, State, Extra) -> {ok, NewState}" n
+ (erlang-skel-separator-end 2)
+ "code_change(_OldVsn, State, _Extra) ->" n>
+ "{ok, State}." n
+ n
+ (erlang-skel-double-separator-start 3)
+ "%%% Internal functions" n
+ (erlang-skel-double-separator-end 3)
+ )
+ "*The template of a library module.
+Please see the function `tempo-define-template'.")
+
+(defvar erlang-skel-ts-test-suite
+ '((erlang-skel-include erlang-skel-large-header)
+ "%% Note: This directive should only be used in test suites." n
+ "-compile(export_all)." n n
+
+ "-include_lib(\"test_server/include/test_server.hrl\")." n n
+
+ (erlang-skel-separator-start 2)
+ "%% TEST SERVER CALLBACK FUNCTIONS" n
+ (erlang-skel-separator 2)
+ n
+ (erlang-skel-separator-start 2)
+ "%%" n
+ "%% @doc" n
+ "%% Initialization before the suite." n
+ "%%" n
+ "%% Config0 = Config1 = [tuple()]" n
+ "%% A list of key/value pairs, holding the test case configuration." n
+ "%% Reason = term()" n
+ "%% The reason for skipping the suite." n
+ "%%" n
+ "%% Note: This function is free to add any key/value pairs to the Config" n
+ "%% variable, but should NOT alter/remove any existing entries." n
+ "%%" n
+ "%% @spec init_per_suite(Config) -> Config" n
+ (erlang-skel-separator-end 2)
+ "init_per_suite(Config) ->" n >
+ "Config." n n
+
+ (erlang-skel-separator-start 2)
+ "%% @doc" n
+ "%% Cleanup after the suite." n
+ "%% Config - [tuple()]" n
+ "%% A list of key/value pairs, holding the test case configuration." n
+ "%%" n
+ "%% @spec end_per_suite(Config) -> _" n
+ (erlang-skel-separator-end 2)
+ "end_per_suite(_Config) ->" n >
+ "ok." n n
+
+ (erlang-skel-separator-start 2)
+ "%% @doc" n
+ "%% Initialization before each test case" n
+ "%%" n
+ "%% TestCase - atom()" n
+ "%% Name of the test case that is about to be run." n
+ "%% Config - [tuple()]" n
+ "%% A list of key/value pairs, holding the test case configuration." n
+ "%% Reason = term()" n
+ "%% The reason for skipping the test case." n
+ "%%" n
+ "%% Note: This function is free to add any key/value pairs to the Config" n
+ "%% variable, but should NOT alter/remove any existing entries." n
+ "%%" n
+ "%% @spec init_per_testcase(TestCase, Config) -> Config" n
+ (erlang-skel-separator-end 2)
+ "init_per_testcase(_TestCase, Config) ->" n >
+ "Config." n n
+
+ (erlang-skel-separator-start 2)
+ "%% @doc" n
+ "%% Cleanup after each test case" n
+ "%%" n
+ "%% TestCase = atom()" n
+ "%% Name of the test case that is finished." n
+ "%% Config = [tuple()]" n
+ "%% A list of key/value pairs, holding the test case configuration." n
+ "%%" n
+ "%% @spec end_per_testcase(TestCase, Config) -> _" n
+ (erlang-skel-separator-end 2)
+ "end_per_testcase(_TestCase, _Config) ->" n >
+ "ok."n n
+
+ (erlang-skel-separator-start 2)
+ "%% @doc" n
+ "%% Returns a description of the test suite when" n
+ "%% Clause == doc, and a test specification (list" n
+ "%% of the conf and test cases in the suite) when" n
+ "%% Clause == suite." n
+ "%% Returns a list of all test cases in this test suite" n
+ "%%" n
+ "%% Clause = doc | suite" n
+ "%% Indicates expected return value." n
+ "%% Descr = [string()] | []" n
+ "%% String that describes the test suite." n
+ "%% Spec = [TestCase]" n
+ "%% A test specification." n
+ "%% TestCase = ConfCase | atom()" n
+ "%% Configuration case, or the name of a test case function." n
+ "%% ConfCase = {conf,Init,Spec,End} |" n
+ "%% {conf,Properties,Init,Spec,End}" n
+ "%% Init = End = {Mod,Func} | Func" n
+ "%% Initialization and cleanup function." n
+ "%% Mod = Func = atom()" n
+ "%% Properties = [parallel | sequence | Shuffle | {RepeatType,N}]" n
+ "%% Execution properties of the test cases (may be combined)." n
+ "%% Shuffle = shuffle | {shuffle,Seed}" n
+ "%% To get cases executed in random order." n
+ "%% Seed = {integer(),integer(),integer()}" n
+ "%% RepeatType = repeat | repeat_until_all_ok | repeat_until_all_fail |" n
+ "%% repeat_until_any_ok | repeat_until_any_fail" n
+ "%% To get execution of cases repeated." n
+ "%% N = integer() | forever" n
+ "%% Reason = term()" n
+ "%% The reason for skipping the test suite." n
+ "%%" n
+ "%% @spec all(Clause) -> TestCases" n
+ (erlang-skel-separator-end 2)
+ "all(doc) ->" n >
+ "[\"Describe the main purpose of this suite\"];" n n
+ "all(suite) -> " n >
+ "[a_test_case]." n n
+ n
+ (erlang-skel-separator-start 2)
+ "%% TEST CASES" n
+ (erlang-skel-separator 2)
+ n
+ (erlang-skel-separator-start 2)
+ "%% @doc" n
+ "%% Test case function. Returns a description of the test" n
+ "%% case (doc), then returns a test specification (suite)," n
+ "%% or performs the actual test (Config)." n
+ "%%" n
+ "%% Arg = doc | suite | Config" n
+ "%% Indicates expected behaviour and return value." n
+ "%% Config = [tuple()]" n
+ "%% A list of key/value pairs, holding the test case configuration." n
+ "%% Descr = [string()] | []" n
+ "%% String that describes the test case." n
+ "%% Spec = [tuple()] | []" n
+ "%% A test specification, see all/1." n
+ "%% Reason = term()" n
+ "%% The reason for skipping the test case." n
+ "%%" n
+ "%% @spec TestCase(Arg) -> Descr | Spec | ok | exit() | {skip,Reason}" n
+
+ (erlang-skel-separator-end 2)
+ "a_test_case(doc) -> " n >
+ "[\"Describe the main purpose of this test case\"];" n n
+ "a_test_case(suite) -> " n >
+ "[];" n n
+ "a_test_case(Config) when is_list(Config) -> " n >
+ "ok." n
+ )
+ "*The template of a library module.
+Please see the function `tempo-define-template'.")
+
+(defvar erlang-skel-ct-test-suite-s
+ '((erlang-skel-include erlang-skel-large-header)
+ "-compile(export_all)." n n
+
+ "-include_lib(\"common_test/include/ct.hrl\")." n n
+
+ (erlang-skel-separator-start 2)
+ "%% @spec suite() -> Info" n
+ "%% Info = [tuple()]" n
+ (erlang-skel-separator-end 2)
+ "suite() ->" n >
+ "[{timetrap,{seconds,30}}]." n n
+
+ (erlang-skel-separator-start 2)
+ "%% @spec init_per_suite(Config0) ->" n
+ "%% Config1 | {skip,Reason} | {skip_and_save,Reason,Config1}" n
+ "%% Config0 = Config1 = [tuple()]" n
+ "%% Reason = term()" n
+ (erlang-skel-separator-end 2)
+ "init_per_suite(Config) ->" n >
+ "Config." n n
+
+ (erlang-skel-separator-start 2)
+ "%% @spec end_per_suite(Config0) -> void() | {save_config,Config1}" n
+ "%% Config0 = Config1 = [tuple()]" n
+ (erlang-skel-separator-end 2)
+ "end_per_suite(_Config) ->" n >
+ "ok." n n
+
+ (erlang-skel-separator-start 2)
+ "%% @spec init_per_group(GroupName, Config0) ->" n
+ "%% Config1 | {skip,Reason} | {skip_and_save,Reason,Config1}" n
+ "%% GroupName = atom()" n
+ "%% Config0 = Config1 = [tuple()]" n
+ "%% Reason = term()" n
+ (erlang-skel-separator-end 2)
+ "init_per_group(_GroupName, Config) ->" n >
+ "Config." n n
+
+ (erlang-skel-separator-start 2)
+ "%% @spec end_per_group(GroupName, Config0) ->" n
+ "%% void() | {save_config,Config1}" n
+ "%% GroupName = atom()" n
+ "%% Config0 = Config1 = [tuple()]" n
+ (erlang-skel-separator-end 2)
+ "end_per_group(_GroupName, _Config) ->" n >
+ "ok." n n
+
+ (erlang-skel-separator-start 2)
+ "%% @spec init_per_testcase(TestCase, Config0) ->" n
+ "%% Config1 | {skip,Reason} | {skip_and_save,Reason,Config1}" n
+ "%% TestCase = atom()" n
+ "%% Config0 = Config1 = [tuple()]" n
+ "%% Reason = term()" n
+ (erlang-skel-separator-end 2)
+ "init_per_testcase(_TestCase, Config) ->" n >
+ "Config." n n
+
+ (erlang-skel-separator-start 2)
+ "%% @spec end_per_testcase(TestCase, Config0) ->" n
+ "%% void() | {save_config,Config1} | {fail,Reason}" n
+ "%% TestCase = atom()" n
+ "%% Config0 = Config1 = [tuple()]" n
+ "%% Reason = term()" n
+ (erlang-skel-separator-end 2)
+ "end_per_testcase(_TestCase, _Config) ->" n >
+ "ok." n n
+
+ (erlang-skel-separator-start 2)
+ "%% @spec groups() -> [Group]" n
+ "%% Group = {GroupName,Properties,GroupsAndTestCases}" n
+ "%% GroupName = atom()" n
+ "%% Properties = [parallel | sequence | Shuffle | {RepeatType,N}]" n
+ "%% GroupsAndTestCases = [Group | {group,GroupName} | TestCase]" n
+ "%% TestCase = atom()" n
+ "%% Shuffle = shuffle | {shuffle,{integer(),integer(),integer()}}" n
+ "%% RepeatType = repeat | repeat_until_all_ok | repeat_until_all_fail |" n
+ "%% repeat_until_any_ok | repeat_until_any_fail" n
+ "%% N = integer() | forever" n
+ (erlang-skel-separator-end 2)
+ "groups() ->" n >
+ "[]." n n
+
+ (erlang-skel-separator-start 2)
+ "%% @spec all() -> GroupsAndTestCases | {skip,Reason}" n
+ "%% GroupsAndTestCases = [{group,GroupName} | TestCase]" n
+ "%% GroupName = atom()" n
+ "%% TestCase = atom()" n
+ "%% Reason = term()" n
+ (erlang-skel-separator-end 2)
+ "all() -> " n >
+ "[my_test_case]." n n
+
+ (erlang-skel-separator-start 2)
+ "%% @spec TestCase() -> Info" n
+ "%% Info = [tuple()]" n
+ (erlang-skel-separator-end 2)
+ "my_test_case() -> " n >
+ "[]." n n
+
+ (erlang-skel-separator-start 2)
+ "%% @spec TestCase(Config0) ->" n
+ "%% ok | exit() | {skip,Reason} | {comment,Comment} |" n
+ "%% {save_config,Config1} | {skip_and_save,Reason,Config1}" n
+ "%% Config0 = Config1 = [tuple()]" n
+ "%% Reason = term()" n
+ "%% Comment = term()" n
+ (erlang-skel-separator-end 2)
+ "my_test_case(_Config) -> " n >
+ "ok." n
+ )
+ "*The template of a library module.
+Please see the function `tempo-define-template'.")
+
+
+(defvar erlang-skel-ct-test-suite-l
+ '((erlang-skel-include erlang-skel-large-header)
+ "%% Note: This directive should only be used in test suites." n
+ "-compile(export_all)." n n
+
+ "-include_lib(\"common_test/include/ct.hrl\")." n n
+
+ (erlang-skel-separator-start 2)
+ "%% COMMON TEST CALLBACK FUNCTIONS" n
+ (erlang-skel-separator 2)
+ n
+ (erlang-skel-separator-start 2)
+ "%% @doc" n
+ "%% Returns list of tuples to set default properties" n
+ "%% for the suite." n
+ "%%" n
+ "%% Function: suite() -> Info" n
+ "%%" n
+ "%% Info = [tuple()]" n
+ "%% List of key/value pairs." n
+ "%%" n
+ "%% Note: The suite/0 function is only meant to be used to return" n
+ "%% default data values, not perform any other operations." n
+ "%%" n
+ "%% @spec suite() -> Info" n
+ (erlang-skel-separator-end 2)
+ "suite() ->" n >
+ "[{timetrap,{minutes,10}}]." n n
+
+ (erlang-skel-separator-start 2)
+ "%% @doc" n
+ "%% Initialization before the whole suite" n
+ "%%" n
+ "%% Config0 = Config1 = [tuple()]" n
+ "%% A list of key/value pairs, holding the test case configuration." n
+ "%% Reason = term()" n
+ "%% The reason for skipping the suite." n
+ "%%" n
+ "%% Note: This function is free to add any key/value pairs to the Config" n
+ "%% variable, but should NOT alter/remove any existing entries." n
+ "%%" n
+ "%% @spec init_per_suite(Config0) ->" n
+ "%% Config1 | {skip,Reason} | {skip_and_save,Reason,Config1}" n
+ (erlang-skel-separator-end 2)
+ "init_per_suite(Config) ->" n >
+ "Config." n n
+
+ (erlang-skel-separator-start 2)
+ "%% @doc" n
+ "%% Cleanup after the whole suite" n
+ "%%" n
+ "%% Config - [tuple()]" n
+ "%% A list of key/value pairs, holding the test case configuration." n
+ "%%" n
+ "%% @spec end_per_suite(Config) -> _" n
+ (erlang-skel-separator-end 2)
+ "end_per_suite(_Config) ->" n >
+ "ok." n n
+
+ (erlang-skel-separator-start 2)
+ "%% @doc" n
+ "%% Initialization before each test case group." n
+ "%%" n
+ "%% GroupName = atom()" n
+ "%% Name of the test case group that is about to run." n
+ "%% Config0 = Config1 = [tuple()]" n
+ "%% A list of key/value pairs, holding configuration data for the group." n
+ "%% Reason = term()" n
+ "%% The reason for skipping all test cases and subgroups in the group." n
+ "%%" n
+ "%% @spec init_per_group(GroupName, Config0) ->" n
+ "%% Config1 | {skip,Reason} | {skip_and_save,Reason,Config1}" n
+ (erlang-skel-separator-end 2)
+ "init_per_group(_GroupName, Config) ->" n >
+ "Config." n n
+
+ (erlang-skel-separator-start 2)
+ "%% @doc" n
+ "%% Cleanup after each test case group." n
+ "%%" n
+ "%% GroupName = atom()" n
+ "%% Name of the test case group that is finished." n
+ "%% Config0 = Config1 = [tuple()]" n
+ "%% A list of key/value pairs, holding configuration data for the group." n
+ "%%" n
+ "%% @spec end_per_group(GroupName, Config0) ->" n
+ "%% void() | {save_config,Config1}" n
+ (erlang-skel-separator-end 2)
+ "end_per_group(_GroupName, _Config) ->" n >
+ "ok." n n
+ (erlang-skel-separator-start 2)
+ "%% @doc" n
+ "%% Initialization before each test case" n
+ "%%" n
+ "%% TestCase - atom()" n
+ "%% Name of the test case that is about to be run." n
+ "%% Config0 = Config1 = [tuple()]" n
+ "%% A list of key/value pairs, holding the test case configuration." n
+ "%% Reason = term()" n
+ "%% The reason for skipping the test case." n
+ "%%" n
+ "%% Note: This function is free to add any key/value pairs to the Config" n
+ "%% variable, but should NOT alter/remove any existing entries." n
+ "%%" n
+ "%% @spec init_per_testcase(TestCase, Config0) ->" n
+ "%% Config1 | {skip,Reason} | {skip_and_save,Reason,Config1}" n
+ (erlang-skel-separator-end 2)
+ "init_per_testcase(_TestCase, Config) ->" n >
+ "Config." n n
+
+ (erlang-skel-separator-start 2)
+ "%% @doc" n
+ "%% Cleanup after each test case" n
+ "%%" n
+ "%% TestCase - atom()" n
+ "%% Name of the test case that is finished." n
+ "%% Config0 = Config1 = [tuple()]" n
+ "%% A list of key/value pairs, holding the test case configuration." n
+ "%%" n
+ "%% @spec end_per_testcase(TestCase, Config0) ->" n
+ "%% void() | {save_config,Config1} | {fail,Reason}" n
+ (erlang-skel-separator-end 2)
+ "end_per_testcase(_TestCase, _Config) ->" n >
+ "ok." n n
+
+ (erlang-skel-separator-start 2)
+ "%% @doc" n
+ "%% Returns a list of test case group definitions." n
+ "%%" n
+ "%% Group = {GroupName,Properties,GroupsAndTestCases}" n
+ "%% GroupName = atom()" n
+ "%% The name of the group." n
+ "%% Properties = [parallel | sequence | Shuffle | {RepeatType,N}]" n
+ "%% Group properties that may be combined." n
+ "%% GroupsAndTestCases = [Group | {group,GroupName} | TestCase]" n
+ "%% TestCase = atom()" n
+ "%% The name of a test case." n
+ "%% Shuffle = shuffle | {shuffle,Seed}" n
+ "%% To get cases executed in random order." n
+ "%% Seed = {integer(),integer(),integer()}" n
+ "%% RepeatType = repeat | repeat_until_all_ok | repeat_until_all_fail |" n
+ "%% repeat_until_any_ok | repeat_until_any_fail" n
+ "%% To get execution of cases repeated." n
+ "%% N = integer() | forever" n
+ "%%" n
+ "%% @spec: groups() -> [Group]" n
+ (erlang-skel-separator-end 2)
+ "groups() ->" n >
+ "[]." n n
+
+ (erlang-skel-separator-start 2)
+ "%% @doc" n
+ "%% Returns the list of groups and test cases that" n
+ "%% are to be executed." n
+ "%%" n
+ "%% GroupsAndTestCases = [{group,GroupName} | TestCase]" n
+ "%% GroupName = atom()" n
+ "%% Name of a test case group." n
+ "%% TestCase = atom()" n
+ "%% Name of a test case." n
+ "%% Reason = term()" n
+ "%% The reason for skipping all groups and test cases." n
+ "%%" n
+ "%% @spec all() -> GroupsAndTestCases | {skip,Reason}" n
+ (erlang-skel-separator-end 2)
+ "all() -> " n >
+ "[my_test_case]." n n
+
+ n
+ (erlang-skel-separator-start 2)
+ "%% TEST CASES" n
+ (erlang-skel-separator 2)
+ n
+
+ (erlang-skel-separator-start 2)
+ "%% @doc " n
+ "%% Test case info function - returns list of tuples to set" n
+ "%% properties for the test case." n
+ "%%" n
+ "%% Info = [tuple()]" n
+ "%% List of key/value pairs." n
+ "%%" n
+ "%% Note: This function is only meant to be used to return a list of" n
+ "%% values, not perform any other operations." n
+ "%%" n
+ "%% @spec TestCase() -> Info " n
+ (erlang-skel-separator-end 2)
+ "my_test_case() -> " n >
+ "[]." n n
+
+ (erlang-skel-separator 2)
+ "%% @doc Test case function. (The name of it must be specified in" n
+ "%% the all/0 list or in a test case group for the test case" n
+ "%% to be executed)." n
+ "%%" n
+ "%% Config0 = Config1 = [tuple()]" n
+ "%% A list of key/value pairs, holding the test case configuration." n
+ "%% Reason = term()" n
+ "%% The reason for skipping the test case." n
+ "%% Comment = term()" n
+ "%% A comment about the test case that will be printed in the html log." n
+ "%%" n
+ "%% @spec TestCase(Config0) ->" n
+ "%% ok | exit() | {skip,Reason} | {comment,Comment} |" n
+ "%% {save_config,Config1} | {skip_and_save,Reason,Config1}" n
+ (erlang-skel-separator-end 2)
+ "my_test_case(_Config) -> " n >
+ "ok." n
+
+ )
+ "*The template of a library module.
+ Please see the function `tempo-define-template'.")
+
+;; Skeleton code:
+
+;; This code is based on the package `tempo' which is part of modern
+;; Emacsen. (GNU Emacs 19.25 (?) and XEmacs 19.14.)
+
+(defun erlang-skel-init ()
+ "Generate the skeleton functions and menu items.
+The variable `erlang-skel' contains the name and descriptions of
+all skeletons.
+
+The skeleton routines are based on the `tempo' package. Should this
+package not be present, this function does nothing."
+ (interactive)
+ (condition-case nil
+ (require 'tempo)
+ (error t))
+ (if (featurep 'tempo)
+ (let ((skel erlang-skel)
+ (menu '()))
+ (while skel
+ (cond ((null (car skel))
+ (setq menu (cons nil menu)))
+ (t
+ (funcall (symbol-function 'tempo-define-template)
+ (concat "erlang-" (nth 1 (car skel)))
+ ;; The tempo template used contains an `include'
+ ;; function call only, hence changes to the
+ ;; variables describing the templates take effect
+ ;; immdiately.
+ (list (list 'erlang-skel-include (nth 2 (car skel))))
+ (nth 1 (car skel)))
+ (setq menu (cons (erlang-skel-make-menu-item
+ (car skel)) menu))))
+ (setq skel (cdr skel)))
+ (setq erlang-menu-skel-items
+ (list nil (list "Skeletons" (nreverse menu))))
+ (setq erlang-menu-items
+ (erlang-menu-add-above 'erlang-menu-skel-items
+ 'erlang-menu-version-items
+ erlang-menu-items))
+ (erlang-menu-init))))
+
+(defun erlang-skel-make-menu-item (skel)
+ (let ((func (intern (concat "tempo-template-erlang-" (nth 1 skel)))))
+ (cond ((null (nth 3 skel))
+ (list (car skel) func))
+ (t
+ (list (car skel)
+ (list 'lambda '()
+ '(interactive)
+ (list 'funcall
+ (list 'quote (nth 3 skel))
+ (list 'quote func))))))))
+
+;; Functions designed to be added to the skeleton menu.
+;; (Not normally used)
+(defun erlang-skel-insert (func)
+ "Insert skeleton generated by FUNC and goto first tempo mark."
+ (save-excursion (funcall func))
+ (funcall (symbol-function 'tempo-forward-mark)))
+
+(defun erlang-skel-header (func)
+ "Insert the header generated by FUNC at the beginning of the buffer."
+ (goto-char (point-min))
+ (save-excursion (funcall func))
+ (funcall (symbol-function 'tempo-forward-mark)))
+
+
+;; Functions used inside the skeleton descriptions.
+(defun erlang-skel-skip-blank ()
+ (skip-chars-backward " \t")
+ nil)
+
+(defun erlang-skel-include (&rest args)
+ "Include a template inside another template.
+
+Example of use, assuming that `erlang-skel-func' is defined:
+
+ (defvar foo-skeleton '(\"%%% New function:\"
+ (erlang-skel-include erlang-skel-func)))
+
+Technically, this function returns the `tempo' attribute`(l ...)' which
+can contain other `tempo' attributes. Please see the function
+`tempo-define-template' for a description of the `(l ...)' attribute."
+ (let ((res '())
+ entry)
+ (while args
+ (setq entry (car args))
+ (while entry
+ (setq res (cons (car entry) res))
+ (setq entry (cdr entry)))
+ (setq args (cdr args)))
+ (cons 'l (nreverse res))))
+
+(defun erlang-skel-separator (&optional percent)
+ "Return a comment separator."
+ (let ((percent (or percent 3)))
+ (concat (make-string percent ?%)
+ (make-string (- 70 percent) ?-)
+ "\n")))
+
+(defun erlang-skel-separator-start (&optional percent)
+ "Return a comment separator or an empty string if separators
+are configured off."
+ (if erlang-skel-use-separators
+ (erlang-skel-separator percent)
+ ""))
+
+(defun erlang-skel-separator-end (&optional percent)
+ "Return a comment separator to end a function comment block or an
+empty string if separators are configured off."
+ (if erlang-skel-use-separators
+ (concat "%% @end\n" (erlang-skel-separator percent))
+ ""))
+
+(defun erlang-skel-double-separator (&optional percent)
+ "Return a double line (equals sign) comment separator."
+ (let ((percent (or percent 3)))
+ (concat (make-string percent ?%)
+ (make-string (- 70 percent) ?=)
+ "\n")))
+
+(defun erlang-skel-double-separator-start (&optional percent)
+ "Return a double separator or a newline if separators are configured off."
+ (if erlang-skel-use-separators
+ (erlang-skel-double-separator percent)
+ "\n"))
+
+(defun erlang-skel-double-separator-end (&optional percent)
+ "Return a double separator or an empty string if separators are
+configured off."
+ (if erlang-skel-use-separators
+ (erlang-skel-double-separator percent)
+ ""))
+
+(defun erlang-skel-dd-mmm-yyyy ()
+ "Return the current date as a string in \"DD Mon YYYY\" form.
+The first character of DD is space if the value is less than 10."
+ (let ((date (current-time-string)))
+ (format "%2d %s %s"
+ (string-to-int (substring date 8 10))
+ (substring date 4 7)
+ (substring date -4))))
+
+;; Local variables:
+;; coding: iso-8859-1
+;; End:
+
+;;; erlang-skels.el ends here
diff --git a/lib/tools/emacs/erlang.el b/lib/tools/emacs/erlang.el
index f623e3a1ee..da586ee09a 100644
--- a/lib/tools/emacs/erlang.el
+++ b/lib/tools/emacs/erlang.el
@@ -1,19 +1,19 @@
;; erlang.el --- Major modes for editing and running Erlang
;; %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
;; 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%
;;
;; Copyright (C) 2004 Free Software Foundation, Inc.
@@ -72,7 +72,7 @@
;; Variables:
-(defconst erlang-version "2.6.1"
+(defconst erlang-version "2.7"
"The version number of Erlang mode.")
(defvar erlang-root-dir nil
@@ -895,1254 +895,16 @@ behaviour.")
(defconst inferior-erlang-use-cmm (boundp 'minor-mode-overriding-map-alist)
"Non-nil means use `compilation-minor-mode' in Erlang shell.")
-;; Tempo skeleton templates:
-
-(defvar erlang-tempo-tags nil
- "Tempo tags for erlang mode")
-
-(defvar erlang-skel
- '(("If" "if" erlang-skel-if)
- ("Case" "case" erlang-skel-case)
- ("Receive" "receive" erlang-skel-receive)
- ("Receive After" "after" erlang-skel-receive-after)
- ("Receive Loop" "loop" erlang-skel-receive-loop)
- ("Module" "module" erlang-skel-module)
- ("Author" "author" erlang-skel-author)
- ()
- ("Small Header" "small-header"
- erlang-skel-small-header erlang-skel-header)
- ("Normal Header" "normal-header"
- erlang-skel-normal-header erlang-skel-header)
- ("Large Header" "large-header"
- erlang-skel-large-header erlang-skel-header)
- ()
- ("Small Server" "small-server"
- erlang-skel-small-server erlang-skel-header)
- ()
- ("Application" "application"
- erlang-skel-application erlang-skel-header)
- ("Supervisor" "supervisor"
- erlang-skel-supervisor erlang-skel-header)
- ("supervisor_bridge" "supervisor-bridge"
- erlang-skel-supervisor-bridge erlang-skel-header)
- ("gen_server" "generic-server"
- erlang-skel-generic-server erlang-skel-header)
- ("gen_event" "gen-event"
- erlang-skel-gen-event erlang-skel-header)
- ("gen_fsm" "gen-fsm"
- erlang-skel-gen-fsm erlang-skel-header)
- ("Library module" "gen-lib"
- erlang-skel-lib erlang-skel-header)
- ("Corba callback" "gen-corba-cb"
- erlang-skel-corba-callback erlang-skel-header)
- ("Small Common Test suite" "ct-test-suite-s"
- erlang-skel-ct-test-suite-s erlang-skel-header)
- ("Large Common Test suite" "ct-test-suite-l"
- erlang-skel-ct-test-suite-l erlang-skel-header)
- ("Erlang TS test suite" "ts-test-suite"
- erlang-skel-ts-test-suite erlang-skel-header)
- )
- "*Description of all skeleton templates.
-Both functions and menu entries will be created.
-
-Each entry in `erlang-skel' should be a list with three or four
-elements, or the empty list.
-
-The first element is the name which shows up in the menu. The second
-is the `tempo' identifier (The string \"erlang-\" will be added in
-front of it). The third is the skeleton descriptor, a variable
-containing `tempo' attributes as described in the function
-`tempo-define-template'. The optional fourth elements denotes a
-function which should be called when the menu is selected.
-
-Functions corresponding to every template will be created. The name
-of the function will be `tempo-template-erlang-X' where `X' is the
-tempo identifier as specified in the second argument of the elements
-in this list.
-
-A list with zero elements means that the a horizontal line should
-be placed in the menu.")
-
-;; In XEmacs `user-mail-address' returns "[email protected] (Foo Bar)" ARGH!
-;; What's wrong with that? RFC 822 says it's legal. [sverkerw]
-;; This needs to use the customized value. If that's not sane, things like
-;; add-log will lose anyhow. Avoid it if there _is_ a paren.
-(defvar erlang-skel-mail-address
- (if (or (not user-mail-address) (string-match "(" user-mail-address))
- (concat (user-login-name) "@"
- (or (and (boundp 'mail-host-address)
- mail-host-address)
- (system-name)))
- user-mail-address)
- "Mail address of the user.")
-
-;; Expression templates:
-(defvar erlang-skel-case
- '((erlang-skel-skip-blank) o >
- "case " p " of" n> p "_ ->" n> p "ok" n> "end" p)
- "*The skeleton of a `case' expression.
-Please see the function `tempo-define-template'.")
-
-(defvar erlang-skel-if
- '((erlang-skel-skip-blank) o >
- "if" n> p " ->" n> p "ok" n> "end" p)
- "The skeleton of an `if' expression.
-Please see the function `tempo-define-template'.")
-
-(defvar erlang-skel-receive
- '((erlang-skel-skip-blank) o >
- "receive" n> p "_ ->" n> p "ok" n> "end" p)
- "*The skeleton of a `receive' expression.
-Please see the function `tempo-define-template'.")
-
-(defvar erlang-skel-receive-after
- '((erlang-skel-skip-blank) o >
- "receive" n> p "_ ->" n> p "ok" n> "after " p "T ->" n>
- p "ok" n> "end" p)
- "*The skeleton of a `receive' expression with an `after' clause.
-Please see the function `tempo-define-template'.")
-
-(defvar erlang-skel-receive-loop
- '(& o "loop(" p ") ->" n> "receive" n> p "_ ->" n>
- "loop(" p ")" n> "end.")
- "*The skeleton of a simple `receive' loop.
-Please see the function `tempo-define-template'.")
-
-
-;; Attribute templates
-
-(defvar erlang-skel-module
- '(& "-module("
- (erlang-add-quotes-if-needed (erlang-get-module-from-file-name))
- ")." n)
- "*The skeleton of a `module' attribute.
-Please see the function `tempo-define-template'.")
-
-(defvar erlang-skel-author
- '(& "-author('" erlang-skel-mail-address "')." n)
- "*The skeleton of a `author' attribute.
-Please see the function `tempo-define-template'.")
-
-(defvar erlang-skel-vc nil
- "*The skeleton template to generate a version control attribute.
-The default is to insert nothing. Example of usage:
-
- (setq erlang-skel-vc '(& \"-rcs(\\\"$\Id: $ \\\").\") n)
-
-Please see the function `tempo-define-template'.")
-
-(defvar erlang-skel-export
- '(& "-export([" n> "])." n)
- "*The skeleton of an `export' attribute.
-Please see the function `tempo-define-template'.")
-
-(defvar erlang-skel-import
- '(& "%%-import(Module, [Function/Arity, ...])." n)
- "*The skeleton of an `import' attribute.
-Please see the function `tempo-define-template'.")
-
-(defvar erlang-skel-compile nil
- ;; '(& "%%-compile(export_all)." n)
- "*The skeleton of a `compile' attribute.
-Please see the function `tempo-define-template'.")
-
-
-;; Comment templates.
-
-(defvar erlang-skel-date-function 'erlang-skel-dd-mmm-yyyy
- "*Function which returns date string.
-Look in the module `time-stamp' for a battery of functions.")
-
-(defvar erlang-skel-copyright-comment '()
- "*The template for a copyright line in the header, normally empty.
-This variable should be bound to a `tempo' template, for example:
- '(& \"%%% Copyright (C) 2000, Yoyodyne, Inc.\" n)
-
-Please see the function `tempo-define-template'.")
-
-(defvar erlang-skel-created-comment
- '(& "%%% Created : " (funcall erlang-skel-date-function) " by "
- (user-full-name) " <" erlang-skel-mail-address ">" n)
- "*The template for the \"Created:\" comment line.")
-
-(defvar erlang-skel-author-comment
- '(& "%%% Author : " (user-full-name) " <" erlang-skel-mail-address ">" n)
- "*The template for creating the \"Author:\" line in the header.
-Please see the function `tempo-define-template'.")
-
-(defvar erlang-skel-file-comment
- '(& "%%% File : " (file-name-nondirectory buffer-file-name) n)
-"*The template for creating the \"Module:\" line in the header.
-Please see the function `tempo-define-template'.")
-
-(defvar erlang-skel-small-header
- '(o (erlang-skel-include erlang-skel-module)
- ;; erlang-skel-author)
- n
- (erlang-skel-include erlang-skel-compile
- ;; erlang-skel-export
- erlang-skel-vc))
- "*The template of a small header without any comments.
-Please see the function `tempo-define-template'.")
-
-(defvar erlang-skel-normal-header
- '(o (erlang-skel-include erlang-skel-copyright-comment
- erlang-skel-file-comment
- erlang-skel-author-comment)
- "%%% Description : " p n
- (erlang-skel-include erlang-skel-created-comment) n
- (erlang-skel-include erlang-skel-small-header) n)
- "*The template of a normal header.
-Please see the function `tempo-define-template'.")
-
-(defvar erlang-skel-large-header
- '(o (erlang-skel-separator)
- (erlang-skel-include erlang-skel-copyright-comment
- erlang-skel-file-comment
- erlang-skel-author-comment)
- "%%% Description : " p n
- "%%%" n
- (erlang-skel-include erlang-skel-created-comment)
- (erlang-skel-separator)
- (erlang-skel-include erlang-skel-small-header) )
- "*The template of a large header.
-Please see the function `tempo-define-template'.")
-
-
-;; Server templates.
-
-(defvar erlang-skel-small-server
- '((erlang-skel-include erlang-skel-large-header)
- "-export([start/0,init/1])." n n n
- "start() ->" n> "spawn(" (erlang-get-module-from-file-name)
- ", init, [self()])." n n
- "init(From) ->" n>
- "loop(From)." n n
- "loop(From) ->" n>
- "receive" n>
- p "_ ->" n>
- "loop(From)" n>
- "end."
- )
- "*Template of a small server.
-Please see the function `tempo-define-template'.")
-
-;; Behaviour templates.
-
-(defvar erlang-skel-application
- '((erlang-skel-include erlang-skel-large-header)
- "-behaviour(application)." n n
- "%% Application callbacks" n
- "-export([start/2, stop/1])." n n
- (erlang-skel-double-separator 2)
- "%% Application callbacks" n
- (erlang-skel-double-separator 2)
- (erlang-skel-separator 2)
- "%% Function: start(Type, StartArgs) -> {ok, Pid} |" n
- "%% {ok, Pid, State} |" n
- "%% {error, Reason}" n
- "%% Description: This function is called whenever an application " n
- "%% is started using application:start/1,2, and should start the processes" n
- "%% of the application. If the application is structured according to the" n
- "%% OTP design principles as a supervision tree, this means starting the" n
- "%% top supervisor of the tree." n
- (erlang-skel-separator 2)
- "start(_Type, StartArgs) ->" n>
- "case 'TopSupervisor':start_link(StartArgs) of" n>
- "{ok, Pid} -> " n>
- "{ok, Pid};" n>
- "Error ->" n>
- "Error" n>
- "end." n
- n
- (erlang-skel-separator 2)
- "%% Function: stop(State) -> void()" n
- "%% Description: This function is called whenever an application" n
- "%% has stopped. It is intended to be the opposite of Module:start/2 and" n
- "%% should do any necessary cleaning up. The return value is ignored. "n
- (erlang-skel-separator 2)
- "stop(_State) ->" n>
- "ok." n
- n
- (erlang-skel-double-separator 2)
- "%% Internal functions" n
- (erlang-skel-double-separator 2)
- )
- "*The template of an application behaviour.
-Please see the function `tempo-define-template'.")
-
-(defvar erlang-skel-supervisor
- '((erlang-skel-include erlang-skel-large-header)
- "-behaviour(supervisor)." n n
-
- "%% API" n
- "-export([start_link/0])." n n
-
- "%% Supervisor callbacks" n
- "-export([init/1])." n n
-
- "-define(SERVER, ?MODULE)." n n
-
- (erlang-skel-double-separator 2)
- "%% API functions" n
- (erlang-skel-double-separator 2)
- (erlang-skel-separator 2)
- "%% Function: start_link() -> {ok,Pid} | ignore | {error,Error}" n
- "%% Description: Starts the supervisor" n
- (erlang-skel-separator 2)
- "start_link() ->" n>
- "supervisor:start_link({local, ?SERVER}, ?MODULE, [])." n
- n
- (erlang-skel-double-separator 2)
- "%% Supervisor callbacks" n
- (erlang-skel-double-separator 2)
- (erlang-skel-separator 2)
- "%% Func: init(Args) -> {ok, {SupFlags, [ChildSpec]}} |" n
- "%% ignore |" n
- "%% {error, Reason}" n
- "%% Description: Whenever a supervisor is started using "n
- "%% supervisor:start_link/[2,3], this function is called by the new process "n
- "%% to find out about restart strategy, maximum restart frequency and child "n
- "%% specifications." n
- (erlang-skel-separator 2)
- "init([]) ->" n>
- "AChild = {'AName',{'AModule',start_link,[]}," n>
- "permanent,2000,worker,['AModule']}," n>
- "{ok,{{one_for_all,0,1}, [AChild]}}." n
- n
- (erlang-skel-double-separator 2)
- "%% Internal functions" n
- (erlang-skel-double-separator 2)
- )
- "*The template of an supervisor behaviour.
-Please see the function `tempo-define-template'.")
-
-(defvar erlang-skel-supervisor-bridge
- '((erlang-skel-include erlang-skel-large-header)
- "-behaviour(supervisor_bridge)." n n
-
- "%% API" n
- "-export([start_link/0])." n n
-
- "%% supervisor_bridge callbacks" n
- "-export([init/1, terminate/2])." n n
-
- "-define(SERVER, ?MODULE)." n n
-
- "-record(state, {})." n n
-
- (erlang-skel-double-separator 2)
- "%% API" n
- (erlang-skel-double-separator 2)
- (erlang-skel-separator 2)
- "%% Function: start_link() -> {ok,Pid} | ignore | {error,Error}" n
- "%% Description: Starts the supervisor bridge" n
- (erlang-skel-separator 2)
- "start_link() ->" n>
- "supervisor_bridge:start_link({local, ?SERVER}, ?MODULE, [])." n
- n
- (erlang-skel-double-separator 2)
- "%% supervisor_bridge callbacks" n
- (erlang-skel-double-separator 2)
- (erlang-skel-separator 2)
- "%% Funcion: init(Args) -> {ok, Pid, State} |" n
- "%% ignore |" n
- "%% {error, Reason} " n
- "%% Description:Creates a supervisor_bridge process, linked to the calling" n
- "%% process, which calls Module:init/1 to start the subsystem. To ensure a" n
- "%% synchronized start-up procedure, this function does not return until" n
- "%% Module:init/1 has returned. " n
- (erlang-skel-separator 2)
- "init([]) ->" n>
- "case 'AModule':start_link() of" n>
- "{ok, Pid} ->" n>
- "{ok, Pid, #state{}};" n>
- "Error ->" n>
- "Error" n>
- "end." n
- n
- (erlang-skel-separator 2)
- "%% Func: terminate(Reason, State) -> void()" n
- "%% Description:This function is called by the supervisor_bridge when it is"n
- "%% about to terminate. It should be the opposite of Module:init/1 and stop"n
- "%% the subsystem and do any necessary cleaning up.The return value is ignored."
- (erlang-skel-separator 2)
- "terminate(Reason, State) ->" n>
- "'AModule':stop()," n>
- "ok." n
- n
- (erlang-skel-double-separator 2)
- "%% Internal functions" n
- (erlang-skel-double-separator 2)
- )
- "*The template of an supervisor_bridge behaviour.
-Please see the function `tempo-define-template'.")
-
-(defvar erlang-skel-generic-server
- '((erlang-skel-include erlang-skel-large-header)
- "-behaviour(gen_server)." n n
-
- "%% API" n
- "-export([start_link/0])." n n
-
- "%% gen_server callbacks" n
- "-export([init/1, handle_call/3, handle_cast/2, "
- "handle_info/2," n>
- "terminate/2, code_change/3])." n n
- "-record(state, {})." n n
-
- (erlang-skel-double-separator 2)
- "%% API" n
- (erlang-skel-double-separator 2)
- (erlang-skel-separator 2)
- "%% Function: start_link() -> {ok,Pid} | ignore | {error,Error}" n
- "%% Description: Starts the server" n
- (erlang-skel-separator 2)
- "start_link() ->" n>
- "gen_server:start_link({local, ?SERVER}, ?MODULE, [], [])." n
- n
- (erlang-skel-double-separator 2)
- "%% gen_server callbacks" n
- (erlang-skel-double-separator 2)
- n
- (erlang-skel-separator 2)
- "%% Function: init(Args) -> {ok, State} |" n
- "%% {ok, State, Timeout} |" n
- "%% ignore |" n
- "%% {stop, Reason}" n
- "%% Description: Initiates the server" n
- (erlang-skel-separator 2)
- "init([]) ->" n>
- "{ok, #state{}}." n
- n
- (erlang-skel-separator 2)
- "%% Function: "
- "%% handle_call(Request, From, State) -> {reply, Reply, State} |" n
- "%% {reply, Reply, State, Timeout} |" n
- "%% {noreply, State} |" n
- "%% {noreply, State, Timeout} |" n
- "%% {stop, Reason, Reply, State} |" n
- "%% {stop, Reason, State}" n
- "%% Description: Handling call messages" n
- (erlang-skel-separator 2)
- "handle_call(_Request, _From, State) ->" n>
- "Reply = ok," n>
- "{reply, Reply, State}." n
- n
- (erlang-skel-separator 2)
- "%% Function: handle_cast(Msg, State) -> {noreply, State} |" n
- "%% {noreply, State, Timeout} |" n
- "%% {stop, Reason, State}" n
- "%% Description: Handling cast messages" n
-
- (erlang-skel-separator 2)
- "handle_cast(_Msg, State) ->" n>
- "{noreply, State}." n
- n
- (erlang-skel-separator 2)
- "%% Function: handle_info(Info, State) -> {noreply, State} |" n
- "%% {noreply, State, Timeout} |" n
- "%% {stop, Reason, State}" n
- "%% Description: Handling all non call/cast messages" n
- (erlang-skel-separator 2)
- "handle_info(_Info, State) ->" n>
- "{noreply, State}." n
- n
- (erlang-skel-separator 2)
- "%% Function: terminate(Reason, State) -> void()" n
- "%% Description: This function is called by a gen_server when it is about to"n
- "%% terminate. It should be the opposite of Module:init/1 and do any necessary"n
- "%% cleaning up. When it returns, the gen_server terminates with Reason." n
- "%% The return value is ignored." n
-
- (erlang-skel-separator 2)
- "terminate(_Reason, _State) ->" n>
- "ok." n
- n
- (erlang-skel-separator 2)
- "%% Func: code_change(OldVsn, State, Extra) -> {ok, NewState}" n
- "%% Description: Convert process state when code is changed" n
- (erlang-skel-separator 2)
- "code_change(_OldVsn, State, _Extra) ->" n>
- "{ok, State}." n
- n
- (erlang-skel-separator 2)
- "%%% Internal functions" n
- (erlang-skel-separator 2)
- )
- "*The template of a generic server.
-Please see the function `tempo-define-template'.")
-
-(defvar erlang-skel-gen-event
- '((erlang-skel-include erlang-skel-large-header)
- "-behaviour(gen_event)." n
-
- "%% API" n
- "-export([start_link/0, add_handler/0])." n n
-
- "%% gen_event callbacks" n
- "-export([init/1, handle_event/2, handle_call/2, " n>
- "handle_info/2, terminate/2, code_change/3])." n n
-
- "-record(state, {})." n n
-
- (erlang-skel-double-separator 2)
- "%% gen_event callbacks" n
- (erlang-skel-double-separator 2)
- (erlang-skel-separator 2)
- "%% Function: start_link() -> {ok,Pid} | {error,Error} " n
- "%% Description: Creates an event manager." n
- (erlang-skel-separator 2)
- "start_link() ->" n>
- "gen_event:start_link({local, ?SERVER}). " n
- n
- (erlang-skel-separator 2)
- "%% Function: add_handler() -> ok | {'EXIT',Reason} | term()" n
- "%% Description: Adds an event handler" n
- (erlang-skel-separator 2)
- "add_handler() ->" n>
- "gen_event:add_handler(?SERVER, ?MODULE, [])." n
- n
- (erlang-skel-double-separator 2)
- "%% gen_event callbacks" n
- (erlang-skel-double-separator 2)
- (erlang-skel-separator 2)
- "%% Function: init(Args) -> {ok, State}" n
- "%% Description: Whenever a new event handler is added to an event manager,"n
- "%% this function is called to initialize the event handler." n
- (erlang-skel-separator 2)
- "init([]) ->" n>
- "{ok, #state{}}." n
- n
- (erlang-skel-separator 2)
- "%% Function: "n
- "%% handle_event(Event, State) -> {ok, State} |" n
- "%% {swap_handler, Args1, State1, Mod2, Args2} |"n
- "%% remove_handler" n
- "%% Description:Whenever an event manager receives an event sent using"n
- "%% gen_event:notify/2 or gen_event:sync_notify/2, this function is called for"n
- "%% each installed event handler to handle the event. "n
- (erlang-skel-separator 2)
- "handle_event(_Event, State) ->" n>
- "{ok, State}." n
- n
- (erlang-skel-separator 2)
- "%% Function: " n
- "%% handle_call(Request, State) -> {ok, Reply, State} |" n
- "%% {swap_handler, Reply, Args1, State1, "n
- "%% Mod2, Args2} |" n
- "%% {remove_handler, Reply}" n
- "%% Description: Whenever an event manager receives a request sent using"n
- "%% gen_event:call/3,4, this function is called for the specified event "n
- "%% handler to handle the request."n
- (erlang-skel-separator 2)
- "handle_call(_Request, State) ->" n>
- "Reply = ok," n>
- "{ok, Reply, State}." n
- n
- (erlang-skel-separator 2)
- "%% Function: " n
- "%% handle_info(Info, State) -> {ok, State} |" n
- "%% {swap_handler, Args1, State1, Mod2, Args2} |" n
- "%% remove_handler" n
- "%% Description: This function is called for each installed event handler when"n
- "%% an event manager receives any other message than an event or a synchronous"n
- "%% request (or a system message)."n
- (erlang-skel-separator 2)
- "handle_info(_Info, State) ->" n>
- "{ok, State}." n
- n
- (erlang-skel-separator 2)
- "%% Function: terminate(Reason, State) -> void()" n
- "%% Description:Whenever an event handler is deleted from an event manager,"n
- "%% this function is called. It should be the opposite of Module:init/1 and "n
- "%% do any necessary cleaning up. " n
- (erlang-skel-separator 2)
- "terminate(_Reason, _State) ->" n>
- "ok." n
- n
- (erlang-skel-separator 2)
- "%% Function: code_change(OldVsn, State, Extra) -> {ok, NewState} " n
- "%% Description: Convert process state when code is changed" n
- (erlang-skel-separator 2)
- "code_change(_OldVsn, State, _Extra) ->" n>
- "{ok, State}." n
- n
- (erlang-skel-separator 2)
- "%%% Internal functions" n
- (erlang-skel-separator 2)
- )
- "*The template of a gen_event.
-Please see the function `tempo-define-template'.")
-
-(defvar erlang-skel-gen-fsm
- '((erlang-skel-include erlang-skel-large-header)
- "-behaviour(gen_fsm)." n n
-
- "%% API" n
- "-export([start_link/0])." n n
-
- "%% gen_fsm callbacks" n
- "-export([init/1, state_name/2, state_name/3, handle_event/3," n>
- "handle_sync_event/4, handle_info/3, terminate/3, code_change/4])." n n
-
- "-record(state, {})." n n
-
- (erlang-skel-double-separator 2)
- "%% API" n
- (erlang-skel-double-separator 2)
- (erlang-skel-separator 2)
- "%% Function: start_link() -> ok,Pid} | ignore | {error,Error}" n
- "%% Description:Creates a gen_fsm process which calls Module:init/1 to"n
- "%% initialize. To ensure a synchronized start-up procedure, this function" n
- "%% does not return until Module:init/1 has returned. " n
- (erlang-skel-separator 2)
- "start_link() ->" n>
- "gen_fsm:start_link({local, ?SERVER}, ?MODULE, [], [])." n
- n
- (erlang-skel-double-separator 2)
- "%% gen_fsm callbacks" n
- (erlang-skel-double-separator 2)
- (erlang-skel-separator 2)
- "%% Function: init(Args) -> {ok, StateName, State} |" n
- "%% {ok, StateName, State, Timeout} |" n
- "%% ignore |" n
- "%% {stop, StopReason} " n
- "%% Description:Whenever a gen_fsm is started using gen_fsm:start/[3,4] or"n
- "%% gen_fsm:start_link/3,4, this function is called by the new process to "n
- "%% initialize. " n
- (erlang-skel-separator 2)
- "init([]) ->" n>
- "{ok, state_name, #state{}}." n
- n
- (erlang-skel-separator 2)
- "%% Function: "n
- "%% state_name(Event, State) -> {next_state, NextStateName, NextState}|" n
- "%% {next_state, NextStateName, " n
- "%% NextState, Timeout} |" n
- "%% {stop, Reason, NewState}" n
- "%% Description:There should be one instance of this function for each possible"n
- "%% state name. Whenever a gen_fsm receives an event sent using" n
- "%% gen_fsm:send_event/2, the instance of this function with the same name as"n
- "%% the current state name StateName is called to handle the event. It is also "n
- "%% called if a timeout occurs. " n
- (erlang-skel-separator 2)
- "state_name(_Event, State) ->" n>
- "{next_state, state_name, State}." n
- n
- (erlang-skel-separator 2)
- "%% Function:" n
- "%% state_name(Event, From, State) -> {next_state, NextStateName, NextState} |"n
- "%% {next_state, NextStateName, " n
- "%% NextState, Timeout} |" n
- "%% {reply, Reply, NextStateName, NextState}|"n
- "%% {reply, Reply, NextStateName, " n
- "%% NextState, Timeout} |" n
- "%% {stop, Reason, NewState}|" n
- "%% {stop, Reason, Reply, NewState}" n
- "%% Description: There should be one instance of this function for each" n
- "%% possible state name. Whenever a gen_fsm receives an event sent using" n
- "%% gen_fsm:sync_send_event/2,3, the instance of this function with the same"n
- "%% name as the current state name StateName is called to handle the event." n
- (erlang-skel-separator 2)
- "state_name(_Event, _From, State) ->" n>
- "Reply = ok," n>
- "{reply, Reply, state_name, State}." n
- n
- (erlang-skel-separator 2)
- "%% Function: " n
- "%% handle_event(Event, StateName, State) -> {next_state, NextStateName, "n
- "%% NextState} |" n
- "%% {next_state, NextStateName, "n
- "%% NextState, Timeout} |" n
- "%% {stop, Reason, NewState}" n
- "%% Description: Whenever a gen_fsm receives an event sent using"n
- "%% gen_fsm:send_all_state_event/2, this function is called to handle"n
- "%% the event." n
- (erlang-skel-separator 2)
- "handle_event(_Event, StateName, State) ->" n>
- "{next_state, StateName, State}." n
- n
- (erlang-skel-separator 2)
- "%% Function: " n
- "%% handle_sync_event(Event, From, StateName, "n
- "%% State) -> {next_state, NextStateName, NextState} |" n
- "%% {next_state, NextStateName, NextState, " n
- "%% Timeout} |" n
- "%% {reply, Reply, NextStateName, NextState}|" n
- "%% {reply, Reply, NextStateName, NextState, " n
- "%% Timeout} |" n
- "%% {stop, Reason, NewState} |" n
- "%% {stop, Reason, Reply, NewState}" n
- "%% Description: Whenever a gen_fsm receives an event sent using"n
- "%% gen_fsm:sync_send_all_state_event/2,3, this function is called to handle"n
- "%% the event."n
- (erlang-skel-separator 2)
- "handle_sync_event(Event, From, StateName, State) ->" n>
- "Reply = ok," n>
- "{reply, Reply, StateName, State}." n
- n
- (erlang-skel-separator 2)
- "%% Function: " n
- "%% handle_info(Info,StateName,State)-> {next_state, NextStateName, NextState}|" n
- "%% {next_state, NextStateName, NextState, "n
- "%% Timeout} |" n
- "%% {stop, Reason, NewState}" n
- "%% Description: This function is called by a gen_fsm when it receives any"n
- "%% other message than a synchronous or asynchronous event"n
- "%% (or a system message)." n
- (erlang-skel-separator 2)
- "handle_info(_Info, StateName, State) ->" n>
- "{next_state, StateName, State}." n
- n
- (erlang-skel-separator 2)
- "%% Function: terminate(Reason, StateName, State) -> void()" n
- "%% Description:This function is called by a gen_fsm when it is about"n
- "%% to terminate. It should be the opposite of Module:init/1 and do any"n
- "%% necessary cleaning up. When it returns, the gen_fsm terminates with"n
- "%% Reason. The return value is ignored." n
- (erlang-skel-separator 2)
- "terminate(_Reason, _StateName, _State) ->" n>
- "ok." n
- n
- (erlang-skel-separator 2)
- "%% Function:" n
- "%% code_change(OldVsn, StateName, State, Extra) -> {ok, StateName, NewState}" n
- "%% Description: Convert process state when code is changed" n
- (erlang-skel-separator 2)
- "code_change(_OldVsn, StateName, State, _Extra) ->" n>
- "{ok, StateName, State}." n
- n
- (erlang-skel-separator 2)
- "%%% Internal functions" n
- (erlang-skel-separator 2)
- )
- "*The template of a gen_fsm.
-Please see the function `tempo-define-template'.")
-
-(defvar erlang-skel-lib
- '((erlang-skel-include erlang-skel-large-header)
-
- "%% API" n
- "-export([])." n n
-
- (erlang-skel-double-separator 2)
- "%% API" n
- (erlang-skel-double-separator 2)
- (erlang-skel-separator 2)
- "%% Function: " n
- "%% Description:" n
- (erlang-skel-separator 2)
- n
- (erlang-skel-double-separator 2)
- "%% Internal functions" n
- (erlang-skel-double-separator 2)
- )
- "*The template of a library module.
-Please see the function `tempo-define-template'.")
-
-(defvar erlang-skel-corba-callback
- '((erlang-skel-include erlang-skel-large-header)
- "%% Include files" n n
-
- "%% API" n
- "-export([])." n n
+(defvar erlang-skel-file "erlang-skels"
+ "The type of erlang-skeletons that should be used, default
+ uses edoc type, for the old type, standard comments,
+ set \"erlang-skels-old\" in your .emacs and restart.
- "%% Corba callbacks" n
- "-export([init/1, terminate/2, code_change/3])." n n
+ Or define your own and set the variable to that file.")
- "-record(state, {})." n n
-
- (erlang-skel-double-separator 2)
- "%% Corba callbacks" n
- (erlang-skel-double-separator 2)
- (erlang-skel-separator 2)
- "%% Function: init(Args) -> {ok, State} |" n
- "%% {ok, State, Timeout} |" n
- "%% ignore |" n
- "%% {stop, Reason}" n
- "%% Description: Initiates the server" n
- (erlang-skel-separator 2)
- "init([]) ->" n>
- "{ok, #state{}}." n
- n
- (erlang-skel-separator 2)
- "%% Function: terminate(Reason, State) -> void()" n
- "%% Description: Shutdown the server" n
- (erlang-skel-separator 2)
- "terminate(_Reason, _State) ->" n>
- "ok." n
- n
- (erlang-skel-separator 2)
- "%% Function: code_change(OldVsn, State, Extra) -> {ok, NewState} " n
- "%% Description: Convert process state when code is changed" n
- (erlang-skel-separator 2)
- "code_change(_OldVsn, State, _Extra) ->" n>
- "{ok, State}." n
- n
- (erlang-skel-double-separator 2)
- "%% Internal functions" n
- (erlang-skel-double-separator 2)
- )
- "*The template of a library module.
-Please see the function `tempo-define-template'.")
-
-(defvar erlang-skel-ts-test-suite
- '((erlang-skel-include erlang-skel-large-header)
- "%% Note: This directive should only be used in test suites." n
- "-compile(export_all)." n n
-
- "-include(\"test_server.hrl\")." n n
-
- (erlang-skel-separator 2)
- "%% TEST SERVER CALLBACK FUNCTIONS" n
- (erlang-skel-separator 2)
- n
- (erlang-skel-separator 2)
- "%% Function: init_per_suite(Config0) -> Config1 | {skip,Reason}" n
- "%%" n
- "%% Config0 = Config1 = [tuple()]" n
- "%% A list of key/value pairs, holding the test case configuration." n
- "%% Reason = term()" n
- "%% The reason for skipping the suite." n
- "%%" n
- "%% Description: Initialization before the suite." n
- "%%" n
- "%% Note: This function is free to add any key/value pairs to the Config" n
- "%% variable, but should NOT alter/remove any existing entries." n
- (erlang-skel-separator 2)
- "init_per_suite(Config) ->" n >
- "Config." n n
-
- (erlang-skel-separator 2)
- "%% Function: end_per_suite(Config) -> void()" n
- "%%" n
- "%% Config = [tuple()]" n
- "%% A list of key/value pairs, holding the test case configuration." n
- "%%" n
- "%% Description: Cleanup after the suite." n
- (erlang-skel-separator 2)
- "end_per_suite(_Config) ->" n >
- "ok." n n
-
- (erlang-skel-separator 2)
- "%% Function: init_per_testcase(TestCase, Config0) -> Config1 |" n
- "%% {skip,Reason}" n
- "%% TestCase = atom()" n
- "%% Name of the test case that is about to run." n
- "%% Config0 = Config1 = [tuple()]" n
- "%% A list of key/value pairs, holding the test case configuration." n
- "%% Reason = term()" n
- "%% The reason for skipping the test case." n
- "%%" n
- "%% Description: Initialization before each test case." n
- "%%" n
- "%% Note: This function is free to add any key/value pairs to the Config" n
- "%% variable, but should NOT alter/remove any existing entries." n
- (erlang-skel-separator 2)
- "init_per_testcase(_TestCase, Config) ->" n >
- "Config." n n
-
- (erlang-skel-separator 2)
- "%% Function: end_per_testcase(TestCase, Config) -> void()" n
- "%%" n
- "%% TestCase = atom()" n
- "%% Name of the test case that is finished." n
- "%% Config = [tuple()]" n
- "%% A list of key/value pairs, holding the test case configuration." n
- "%%" n
- "%% Description: Cleanup after each test case." n
- (erlang-skel-separator 2)
- "end_per_testcase(_TestCase, _Config) ->" n >
- "ok."n n
-
- (erlang-skel-separator 2)
- "%% Function: all(Clause) -> Descr | Spec | {skip,Reason}" n
- "%%" n
- "%% Clause = doc | suite" n
- "%% Indicates expected return value." n
- "%% Descr = [string()] | []" n
- "%% String that describes the test suite." n
- "%% Spec = [TestCase]" n
- "%% A test specification." n
- "%% TestCase = ConfCase | atom()" n
- "%% Configuration case, or the name of a test case function." n
- "%% ConfCase = {conf,Init,Spec,End} |" n
- "%% {conf,Properties,Init,Spec,End}" n
- "%% Init = End = {Mod,Func} | Func" n
- "%% Initialization and cleanup function." n
- "%% Mod = Func = atom()" n
- "%% Properties = [parallel | sequence | Shuffle | {RepeatType,N}]" n
- "%% Execution properties of the test cases (may be combined)." n
- "%% Shuffle = shuffle | {shuffle,Seed}" n
- "%% To get cases executed in random order." n
- "%% Seed = {integer(),integer(),integer()}" n
- "%% RepeatType = repeat | repeat_until_all_ok | repeat_until_all_fail |" n
- "%% repeat_until_any_ok | repeat_until_any_fail" n
- "%% To get execution of cases repeated." n
- "%% N = integer() | forever" n
- "%% Reason = term()" n
- "%% The reason for skipping the test suite." n
- "%%" n
- "%% Description: Returns a description of the test suite when" n
- "%% Clause == doc, and a test specification (list" n
- "%% of the conf and test cases in the suite) when" n
- "%% Clause == suite." n
- (erlang-skel-separator 2)
- "all(doc) -> " n >
- "[\"Describe the main purpose of this suite\"];" n n
- "all(suite) -> " n >
- "[a_test_case]." n n
- n
- (erlang-skel-separator 2)
- "%% TEST CASES" n
- (erlang-skel-separator 2)
- n
- (erlang-skel-separator 2)
- "%% Function: TestCase(Arg) -> Descr | Spec | ok | exit() | {skip,Reason}" n
- "%%" n
- "%% Arg = doc | suite | Config" n
- "%% Indicates expected behaviour and return value." n
- "%% Config = [tuple()]" n
- "%% A list of key/value pairs, holding the test case configuration." n
- "%% Descr = [string()] | []" n
- "%% String that describes the test case." n
- "%% Spec = [tuple()] | []" n
- "%% A test specification, see all/1." n
- "%% Reason = term()" n
- "%% The reason for skipping the test case." n
- "%%" n
- "%% Description: Test case function. Returns a description of the test" n
- "%% case (doc), then returns a test specification (suite)," n
- "%% or performs the actual test (Config)." n
- (erlang-skel-separator 2)
- "a_test_case(doc) -> " n >
- "[\"Describe the main purpose of this test case\"];" n n
- "a_test_case(suite) -> " n >
- "[];" n n
- "a_test_case(Config) when is_list(Config) -> " n >
- "ok." n
- )
- "*The template of a library module.
-Please see the function `tempo-define-template'.")
-
-(defvar erlang-skel-ct-test-suite-l
- '((erlang-skel-include erlang-skel-large-header)
- "%% Note: This directive should only be used in test suites." n
- "-compile(export_all)." n n
-
- "-include(\"ct.hrl\")." n n
-
- (erlang-skel-separator 2)
- "%% COMMON TEST CALLBACK FUNCTIONS" n
- (erlang-skel-separator 2)
- n
- (erlang-skel-separator 2)
- "%% Function: suite() -> Info" n
- "%%" n
- "%% Info = [tuple()]" n
- "%% List of key/value pairs." n
- "%%" n
- "%% Description: Returns list of tuples to set default properties" n
- "%% for the suite." n
- "%%" n
- "%% Note: The suite/0 function is only meant to be used to return" n
- "%% default data values, not perform any other operations." n
- (erlang-skel-separator 2)
- "suite() ->" n >
- "[{timetrap,{minutes,10}}]." n n
-
- (erlang-skel-separator 2)
- "%% Function: init_per_suite(Config0) ->" n
- "%% Config1 | {skip,Reason} | {skip_and_save,Reason,Config1}" n
- "%%" n
- "%% Config0 = Config1 = [tuple()]" n
- "%% A list of key/value pairs, holding the test case configuration." n
- "%% Reason = term()" n
- "%% The reason for skipping the suite." n
- "%%" n
- "%% Description: Initialization before the suite." n
- "%%" n
- "%% Note: This function is free to add any key/value pairs to the Config" n
- "%% variable, but should NOT alter/remove any existing entries." n
- (erlang-skel-separator 2)
- "init_per_suite(Config) ->" n >
- "Config." n n
-
- (erlang-skel-separator 2)
- "%% Function: end_per_suite(Config0) -> void() | {save_config,Config1}" n
- "%%" n
- "%% Config0 = Config1 = [tuple()]" n
- "%% A list of key/value pairs, holding the test case configuration." n
- "%%" n
- "%% Description: Cleanup after the suite." n
- (erlang-skel-separator 2)
- "end_per_suite(_Config) ->" n >
- "ok." n n
-
- (erlang-skel-separator 2)
- "%% Function: init_per_group(GroupName, Config0) ->" n
- "%% Config1 | {skip,Reason} | {skip_and_save,Reason,Config1}" n
- "%%" n
- "%% GroupName = atom()" n
- "%% Name of the test case group that is about to run." n
- "%% Config0 = Config1 = [tuple()]" n
- "%% A list of key/value pairs, holding configuration data for the group." n
- "%% Reason = term()" n
- "%% The reason for skipping all test cases and subgroups in the group." n
- "%%" n
- "%% Description: Initialization before each test case group." n
- (erlang-skel-separator 2)
- "init_per_group(_GroupName, Config) ->" n >
- "Config." n n
-
- (erlang-skel-separator 2)
- "%% Function: end_per_group(GroupName, Config0) ->" n
- "%% void() | {save_config,Config1}" n
- "%%" n
- "%% GroupName = atom()" n
- "%% Name of the test case group that is finished." n
- "%% Config0 = Config1 = [tuple()]" n
- "%% A list of key/value pairs, holding configuration data for the group." n
- "%%" n
- "%% Description: Cleanup after each test case group." n
- (erlang-skel-separator 2)
- "end_per_group(_GroupName, _Config) ->" n >
- "ok." n n
-
- (erlang-skel-separator 2)
- "%% Function: init_per_testcase(TestCase, Config0) ->" n
- "%% Config1 | {skip,Reason} | {skip_and_save,Reason,Config1}" n
- "%%" n
- "%% TestCase = atom()" n
- "%% Name of the test case that is about to run." n
- "%% Config0 = Config1 = [tuple()]" n
- "%% A list of key/value pairs, holding the test case configuration." n
- "%% Reason = term()" n
- "%% The reason for skipping the test case." n
- "%%" n
- "%% Description: Initialization before each test case." n
- "%%" n
- "%% Note: This function is free to add any key/value pairs to the Config" n
- "%% variable, but should NOT alter/remove any existing entries." n
- (erlang-skel-separator 2)
- "init_per_testcase(_TestCase, Config) ->" n >
- "Config." n n
-
- (erlang-skel-separator 2)
- "%% Function: end_per_testcase(TestCase, Config0) ->" n
- "%% void() | {save_config,Config1} | {fail,Reason}" n
- "%%" n
- "%% TestCase = atom()" n
- "%% Name of the test case that is finished." n
- "%% Config0 = Config1 = [tuple()]" n
- "%% A list of key/value pairs, holding the test case configuration." n
- "%% Reason = term()" n
- "%% The reason for failing the test case." n
- "%%" n
- "%% Description: Cleanup after each test case." n
- (erlang-skel-separator 2)
- "end_per_testcase(_TestCase, _Config) ->" n >
- "ok." n n
-
- (erlang-skel-separator 2)
- "%% Function: groups() -> [Group]" n
- "%%" n
- "%% Group = {GroupName,Properties,GroupsAndTestCases}" n
- "%% GroupName = atom()" n
- "%% The name of the group." n
- "%% Properties = [parallel | sequence | Shuffle | {RepeatType,N}]" n
- "%% Group properties that may be combined." n
- "%% GroupsAndTestCases = [Group | {group,GroupName} | TestCase]" n
- "%% TestCase = atom()" n
- "%% The name of a test case." n
- "%% Shuffle = shuffle | {shuffle,Seed}" n
- "%% To get cases executed in random order." n
- "%% Seed = {integer(),integer(),integer()}" n
- "%% RepeatType = repeat | repeat_until_all_ok | repeat_until_all_fail |" n
- "%% repeat_until_any_ok | repeat_until_any_fail" n
- "%% To get execution of cases repeated." n
- "%% N = integer() | forever" n
- "%%" n
- "%% Description: Returns a list of test case group definitions." n
- (erlang-skel-separator 2)
- "groups() ->" n >
- "[]." n n
-
- (erlang-skel-separator 2)
- "%% Function: all() -> GroupsAndTestCases | {skip,Reason}" n
- "%%" n
- "%% GroupsAndTestCases = [{group,GroupName} | TestCase]" n
- "%% GroupName = atom()" n
- "%% Name of a test case group." n
- "%% TestCase = atom()" n
- "%% Name of a test case." n
- "%% Reason = term()" n
- "%% The reason for skipping all groups and test cases." n
- "%%" n
- "%% Description: Returns the list of groups and test cases that" n
- "%% are to be executed." n
- (erlang-skel-separator 2)
- "all() -> " n >
- "[my_test_case]." n n
-
- n
- (erlang-skel-separator 2)
- "%% TEST CASES" n
- (erlang-skel-separator 2)
- n
-
- (erlang-skel-separator 2)
- "%% Function: TestCase() -> Info" n
- "%%" n
- "%% Info = [tuple()]" n
- "%% List of key/value pairs." n
- "%%" n
- "%% Description: Test case info function - returns list of tuples to set" n
- "%% properties for the test case." n
- "%%" n
- "%% Note: This function is only meant to be used to return a list of" n
- "%% values, not perform any other operations." n
- (erlang-skel-separator 2)
- "my_test_case() -> " n >
- "[]." n n
-
- (erlang-skel-separator 2)
- "%% Function: TestCase(Config0) ->" n
- "%% ok | exit() | {skip,Reason} | {comment,Comment} |" n
- "%% {save_config,Config1} | {skip_and_save,Reason,Config1}" n
- "%%" n
- "%% Config0 = Config1 = [tuple()]" n
- "%% A list of key/value pairs, holding the test case configuration." n
- "%% Reason = term()" n
- "%% The reason for skipping the test case." n
- "%% Comment = term()" n
- "%% A comment about the test case that will be printed in the html log." n
- "%%" n
- "%% Description: Test case function. (The name of it must be specified in" n
- "%% the all/0 list or in a test case group for the test case" n
- "%% to be executed)." n
- (erlang-skel-separator 2)
- "my_test_case(_Config) -> " n >
- "ok." n
- )
- "*The template of a library module.
-Please see the function `tempo-define-template'.")
-
-(defvar erlang-skel-ct-test-suite-s
- '((erlang-skel-include erlang-skel-large-header)
- "-compile(export_all)." n n
-
- "-include(\"ct.hrl\")." n n
-
- (erlang-skel-separator 2)
- "%% Function: suite() -> Info" n
- "%% Info = [tuple()]" n
- (erlang-skel-separator 2)
- "suite() ->" n >
- "[{timetrap,{seconds,30}}]." n n
-
- (erlang-skel-separator 2)
- "%% Function: init_per_suite(Config0) ->" n
- "%% Config1 | {skip,Reason} | {skip_and_save,Reason,Config1}" n
- "%% Config0 = Config1 = [tuple()]" n
- "%% Reason = term()" n
- (erlang-skel-separator 2)
- "init_per_suite(Config) ->" n >
- "Config." n n
-
- (erlang-skel-separator 2)
- "%% Function: end_per_suite(Config0) -> void() | {save_config,Config1}" n
- "%% Config0 = Config1 = [tuple()]" n
- (erlang-skel-separator 2)
- "end_per_suite(_Config) ->" n >
- "ok." n n
-
- (erlang-skel-separator 2)
- "%% Function: init_per_group(GroupName, Config0) ->" n
- "%% Config1 | {skip,Reason} | {skip_and_save,Reason,Config1}" n
- "%% GroupName = atom()" n
- "%% Config0 = Config1 = [tuple()]" n
- "%% Reason = term()" n
- (erlang-skel-separator 2)
- "init_per_group(_GroupName, Config) ->" n >
- "Config." n n
-
- (erlang-skel-separator 2)
- "%% Function: end_per_group(GroupName, Config0) ->" n
- "%% void() | {save_config,Config1}" n
- "%% GroupName = atom()" n
- "%% Config0 = Config1 = [tuple()]" n
- (erlang-skel-separator 2)
- "end_per_group(_GroupName, _Config) ->" n >
- "ok." n n
-
- (erlang-skel-separator 2)
- "%% Function: init_per_testcase(TestCase, Config0) ->" n
- "%% Config1 | {skip,Reason} | {skip_and_save,Reason,Config1}" n
- "%% TestCase = atom()" n
- "%% Config0 = Config1 = [tuple()]" n
- "%% Reason = term()" n
- (erlang-skel-separator 2)
- "init_per_testcase(_TestCase, Config) ->" n >
- "Config." n n
-
- (erlang-skel-separator 2)
- "%% Function: end_per_testcase(TestCase, Config0) ->" n
- "%% void() | {save_config,Config1} | {fail,Reason}" n
- "%% TestCase = atom()" n
- "%% Config0 = Config1 = [tuple()]" n
- "%% Reason = term()" n
- (erlang-skel-separator 2)
- "end_per_testcase(_TestCase, _Config) ->" n >
- "ok." n n
-
- (erlang-skel-separator 2)
- "%% Function: groups() -> [Group]" n
- "%% Group = {GroupName,Properties,GroupsAndTestCases}" n
- "%% GroupName = atom()" n
- "%% Properties = [parallel | sequence | Shuffle | {RepeatType,N}]" n
- "%% GroupsAndTestCases = [Group | {group,GroupName} | TestCase]" n
- "%% TestCase = atom()" n
- "%% Shuffle = shuffle | {shuffle,{integer(),integer(),integer()}}" n
- "%% RepeatType = repeat | repeat_until_all_ok | repeat_until_all_fail |" n
- "%% repeat_until_any_ok | repeat_until_any_fail" n
- "%% N = integer() | forever" n
- (erlang-skel-separator 2)
- "groups() ->" n >
- "[]." n n
-
- (erlang-skel-separator 2)
- "%% Function: all() -> GroupsAndTestCases | {skip,Reason}" n
- "%% GroupsAndTestCases = [{group,GroupName} | TestCase]" n
- "%% GroupName = atom()" n
- "%% TestCase = atom()" n
- "%% Reason = term()" n
- (erlang-skel-separator 2)
- "all() -> " n >
- "[my_test_case]." n n
-
- (erlang-skel-separator 2)
- "%% Function: TestCase() -> Info" n
- "%% Info = [tuple()]" n
- (erlang-skel-separator 2)
- "my_test_case() -> " n >
- "[]." n n
-
- (erlang-skel-separator 2)
- "%% Function: TestCase(Config0) ->" n
- "%% ok | exit() | {skip,Reason} | {comment,Comment} |" n
- "%% {save_config,Config1} | {skip_and_save,Reason,Config1}" n
- "%% Config0 = Config1 = [tuple()]" n
- "%% Reason = term()" n
- "%% Comment = term()" n
- (erlang-skel-separator 2)
- "my_test_case(_Config) -> " n >
- "ok." n
- )
- "*The template of a library module.
-Please see the function `tempo-define-template'.")
+;; Tempo skeleton templates:
+(load erlang-skel-file)
;; Font-lock variables
@@ -3792,9 +2554,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 +2717,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 +2810,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 +2843,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 +3718,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/Makefile b/lib/tools/src/Makefile
index 81933cda14..360f4f8f29 100644
--- a/lib/tools/src/Makefile
+++ b/lib/tools/src/Makefile
@@ -1,19 +1,19 @@
#
# %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
# 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
@@ -34,11 +34,13 @@ RELSYSDIR = $(RELEASE_PATH)/lib/tools-$(VSN)
# Common Macros
# ----------------------------------------------------
-MODULES= cover \
+MODULES= \
+ cover \
cover_web \
eprof \
fprof \
cprof \
+ lcnt \
instrument \
make \
tags \
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/src/lcnt.erl b/lib/tools/src/lcnt.erl
new file mode 100644
index 0000000000..989a661b75
--- /dev/null
+++ b/lib/tools/src/lcnt.erl
@@ -0,0 +1,840 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 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(lcnt).
+-behaviour(gen_server).
+-author("Björn-Egil Dahlberg").
+
+%% gen_server callbacks
+-export([
+ init/1,
+ handle_call/3,
+ handle_cast/2,
+ handle_info/2,
+ terminate/2,
+ code_change/3
+ ]).
+
+%% start/stop
+-export([
+ start/0,
+ stop/0
+ ]).
+
+%% erts_debug:lock_counters api
+-export([
+ rt_collect/0,
+ rt_collect/1,
+ rt_clear/0,
+ rt_clear/1,
+ rt_opt/1,
+ rt_opt/2
+ ]).
+
+
+%% gen_server call api
+-export([
+ raw/0,
+ collect/0,
+ collect/1,
+ clear/0,
+ clear/1,
+ conflicts/0,
+ conflicts/1,
+ locations/0,
+ locations/1,
+ inspect/1,
+ inspect/2,
+ information/0,
+ swap_pid_keys/0,
+ % set options
+ set/1,
+ set/2,
+
+ load/1,
+ save/1
+ ]).
+
+%% convenience
+-export([
+ apply/3,
+ apply/2,
+ apply/1,
+ all_conflicts/0,
+ all_conflicts/1,
+ pid/2, pid/3,
+ port/1, port/2
+ ]).
+
+-define(version, "1.0").
+
+-record(state, {
+ locks = [],
+ duration = 0
+ }).
+
+
+-record(stats, {
+ file,
+ line,
+ tries,
+ colls,
+ time, % us
+ nt % #timings collected
+ }).
+
+-record(lock, {
+ name,
+ id,
+ type,
+ stats = []
+ }).
+
+-record(print, {
+ name,
+ id,
+ type,
+ entry,
+ tries,
+ colls,
+ cr, % collision ratio
+ time,
+ dtr % time duration ratio
+ }).
+
+
+
+%% -------------------------------------------------------------------- %%
+%%
+%% start/stop/init
+%%
+%% -------------------------------------------------------------------- %%
+
+start() -> gen_server:start({local, ?MODULE}, ?MODULE, [], []).
+stop() -> gen_server:cast(?MODULE, stop).
+init([]) -> {ok, #state{ locks = [], duration = 0 } }.
+
+%% -------------------------------------------------------------------- %%
+%%
+%% API erts_debug:lock_counters
+%%
+%% -------------------------------------------------------------------- %%
+
+rt_collect() ->
+ erts_debug:lock_counters(info).
+
+rt_collect(Node) ->
+ rpc:call(Node, erts_debug, lock_counters, [info]).
+
+rt_clear() ->
+ erts_debug:lock_counters(clear).
+
+rt_clear(Node) ->
+ rpc:call(Node, erts_debug, lock_counters, [clear]).
+
+rt_opt({Type, Opt}) ->
+ erts_debug:lock_counters({Type, Opt}).
+
+rt_opt(Node, {Type, Opt}) ->
+ rpc:call(Node, erts_debug, lock_counters, [{Type, Opt}]).
+
+%% -------------------------------------------------------------------- %%
+%%
+%% API implementation
+%%
+%% -------------------------------------------------------------------- %%
+
+clear() -> rt_clear().
+clear(Node) -> rt_clear(Node).
+collect() -> call({collect, rt_collect()}).
+collect(Node) -> call({collect, rt_collect(Node)}).
+
+locations() -> call({locations,[]}).
+locations(Opts) -> call({locations, Opts}).
+conflicts() -> call({conflicts, []}).
+conflicts(Opts) -> call({conflicts, Opts}).
+inspect(Lock) -> call({inspect, Lock, []}).
+inspect(Lock, Opts) -> call({inspect, Lock, Opts}).
+information() -> call(information).
+swap_pid_keys() -> call(swap_pid_keys).
+raw() -> call(raw).
+set(Option, Value) -> call({set, Option, Value}).
+set({Option, Value}) -> call({set, Option, Value}).
+save(Filename) -> call({save, Filename}).
+load(Filename) -> start(), call({load, Filename}).
+
+call(Msg) -> gen_server:call(?MODULE, Msg, infinity).
+
+%% -------------------------------------------------------------------- %%
+%%
+%% convenience implementation
+%%
+%% -------------------------------------------------------------------- %%
+
+apply(M,F,As) when is_atom(M), is_atom(F), is_list(As) ->
+ lcnt:start(),
+ Opt = lcnt:rt_opt({copy_save, true}),
+ lcnt:clear(),
+ Res = erlang:apply(M,F,As),
+ lcnt:collect(),
+ lcnt:rt_opt({copy_save, Opt}),
+ Res.
+
+apply(Fun) when is_function(Fun) ->
+ lcnt:apply(Fun, []).
+
+apply(Fun, As) when is_function(Fun) ->
+ lcnt:start(),
+ Opt = lcnt:rt_opt({copy_save, true}),
+ lcnt:clear(),
+ Res = erlang:apply(Fun, As),
+ lcnt:collect(),
+ lcnt:rt_opt({copy_save, Opt}),
+ Res.
+
+all_conflicts() -> all_conflicts(time).
+all_conflicts(Sort) ->
+ conflicts([{max_locks, none}, {thresholds, []},{combine,false}, {sort, Sort}, {reverse, true}]).
+
+pid(Id, Serial) -> pid(node(), Id, Serial).
+pid(Node, Id, Serial) when is_atom(Node) ->
+ Header = <<131,103,100>>,
+ String = atom_to_list(Node),
+ L = length(String),
+ binary_to_term(list_to_binary([Header, bytes16(L), String, bytes32(Id), bytes32(Serial),0])).
+
+port(Id) -> port(node(), Id).
+port(Node, Id ) when is_atom(Node) ->
+ Header = <<131,102,100>>,
+ String = atom_to_list(Node),
+ L = length(String),
+ binary_to_term(list_to_binary([Header, bytes16(L), String, bytes32(Id), 0])).
+
+%% -------------------------------------------------------------------- %%
+%%
+%% handle_call
+%%
+%% -------------------------------------------------------------------- %%
+
+% printing
+
+handle_call({conflicts, InOpts}, _From, #state{ locks = Locks } = State) when is_list(InOpts) ->
+ Default = [
+ {sort, time},
+ {reverse, false},
+ {print, [name,id,tries,colls,ratio,time,duration]},
+ {max_locks, 20},
+ {combine, true},
+ {thresholds, [{tries, 0}, {colls, 0}, {time, 0}] },
+ {locations, false}],
+
+ Opts = options(InOpts, Default),
+ Flocks = filter_locks_type(Locks, proplists:get_value(type, Opts)),
+ Combos = combine_classes(Flocks, proplists:get_value(combine, Opts)),
+ Printables = locks2print(Combos, State#state.duration),
+ Filtered = filter_print(Printables, Opts),
+
+ print_lock_information(Filtered, proplists:get_value(print, Opts)),
+
+ {reply, ok, State};
+
+handle_call(information, _From, State) ->
+ print_state_information(State),
+ {reply, ok, State};
+
+handle_call({locations, InOpts}, _From, #state{ locks = Locks } = State) when is_list(InOpts) ->
+ Default = [
+ {sort, time},
+ {reverse, false},
+ {print, [name,entry,tries,colls,ratio,time,duration]},
+ {max_locks, 20},
+ {combine, true},
+ {thresholds, [{tries, 0}, {colls, 0}, {time, 0}] },
+ {locations, true}],
+
+ Opts = options(InOpts, Default),
+ Printables = filter_print([#print{
+ name = string_names(Names),
+ entry = term2string("~p:~p", [Stats#stats.file, Stats#stats.line]),
+ colls = Stats#stats.colls,
+ tries = Stats#stats.tries,
+ cr = percent(Stats#stats.colls, Stats#stats.tries),
+ time = Stats#stats.time,
+ dtr = percent(Stats#stats.time, State#state.duration)
+ } || {Stats, Names} <- combine_locations(Locks) ], Opts),
+
+ print_lock_information(Printables, proplists:get_value(print, Opts)),
+
+ {reply, ok, State};
+
+handle_call({inspect, Lockname, InOpts}, _From, #state{ duration = Duration, locks = Locks } = State) when is_list(InOpts) ->
+ Default = [
+ {sort, time},
+ {reverse, false},
+ {print, [name,id,tries,colls,ratio,time,duration]},
+ {max_locks, 20},
+ {combine, false},
+ {thresholds, [] },
+ {locations, false}],
+
+ Opts = options(InOpts, Default),
+ Filtered = filter_locks(Locks, Lockname),
+ IDs = case {proplists:get_value(full_id, Opts), proplists:get_value(combine, Opts)} of
+ {true, true} -> locks_ids(Filtered);
+ _ -> []
+ end,
+ Combos = combine_classes(Filtered, proplists:get_value(combine, Opts)),
+ case proplists:get_value(locations, Opts) of
+ true ->
+ lists:foreach(fun
+ (#lock{ name = Name, id = Id, type = Type, stats = Stats }) ->
+ IdString = case proplists:get_value(full_id, Opts) of
+ true -> term2string(proplists:get_value(Name, IDs, Id));
+ _ -> term2string(Id)
+ end,
+ Combined = [CStats || {CStats,_} <- combine_locations(Stats)],
+ case Combined of
+ [] ->
+ ok;
+ _ ->
+ %io:format("Combined ~p~n", [Combined]),
+ print("lock: " ++ term2string(Name)),
+ print("id: " ++ IdString),
+ print("type: " ++ term2string(Type)),
+ Ps = stats2print(Combined, Duration),
+ Opts1 = options([{print, [entry, tries,colls,ratio,time,duration]},
+ {thresholds, [{tries, -1}, {colls, -1}, {time, -1}]}], Opts),
+ print_lock_information(filter_print(Ps, Opts1), proplists:get_value(print, Opts1))
+ end
+ % (#lock{ name = Name, id = Id}) ->
+ % io:format("Empty lock ~p ~p~n", [Name, Id])
+ end, Combos);
+ _ ->
+ Print1 = locks2print(Combos, Duration),
+ Print2 = filter_print(Print1, Opts),
+ print_lock_information(Print2, proplists:get_value(print, Opts))
+ end,
+ {reply, ok, State};
+
+handle_call(raw, _From, #state{ locks = Locks} = State)->
+ {reply, Locks, State};
+
+% collecting
+handle_call({collect, Data}, _From, State)->
+ {reply, ok, data2state(Data, State)};
+
+% manipulate
+handle_call(swap_pid_keys, _From, #state{ locks = Locks } = State)->
+ SwappedLocks = lists:map(fun
+ (L) when L#lock.name =:= port_lock; L#lock.type =:= proclock ->
+ L#lock{ id = L#lock.name, name = L#lock.id };
+ (L) ->
+ L
+ end, Locks),
+
+ {reply, ok, State#state{ locks = SwappedLocks}};
+
+% settings
+handle_call({set, data, Data}, _From, State)->
+ {reply, ok, data2state(Data, State)};
+
+handle_call({set, duration, Duration}, _From, State)->
+ {reply, ok, State#state{ duration = Duration}};
+
+% file operations
+handle_call({load, Filename}, _From, State) ->
+ case file:read_file(Filename) of
+ {ok, Binary} ->
+ case binary_to_term(Binary) of
+ {?version, Statelist} ->
+ {reply, ok, list2state(Statelist)};
+ {Version, _} ->
+ {reply, {error, {mismatch, Version, ?version}}, State}
+ end;
+ Error ->
+ {reply, {error, Error}, State}
+ end;
+
+handle_call({save, Filename}, _From, State) ->
+ Binary = term_to_binary({?version, state2list(State)}),
+ case file:write_file(Filename, Binary) of
+ ok ->
+ {reply, ok, State};
+ Error ->
+ {reply, {error, Error}, State}
+ end;
+
+
+handle_call(Command, _From, State) ->
+ {reply, {error, {undefined, Command}}, State}.
+
+%% -------------------------------------------------------------------- %%
+%%
+%% handle_cast
+%%
+%% -------------------------------------------------------------------- %%
+
+handle_cast(stop, State) ->
+ {stop, normal, State};
+handle_cast(_, State) ->
+ {noreply, State}.
+
+%% -------------------------------------------------------------------- %%
+%%
+%% handle_info
+%%
+%% -------------------------------------------------------------------- %%
+
+handle_info(_Info, State) ->
+ {noreply, State}.
+
+%% -------------------------------------------------------------------- %%
+%%
+%% termination
+%%
+%% -------------------------------------------------------------------- %%
+
+terminate(_Reason, _State) ->
+ ok.
+
+%% -------------------------------------------------------------------- %%
+%%
+%% code_change
+%%
+%% -------------------------------------------------------------------- %%
+
+code_change(_OldVsn, State, _Extra) ->
+ {ok, State}.
+
+%% -------------------------------------------------------------------- %%
+%%
+%% AUX
+%%
+%% -------------------------------------------------------------------- %%
+
+% summate
+
+summate_locks(Locks) -> summate_locks(Locks, #stats{ tries = 0, colls = 0, time = 0, nt = 0}).
+summate_locks([], Stats) -> Stats;
+summate_locks([L|Ls], #stats{ tries = Tries, colls = Colls, time = Time, nt = Nt}) ->
+ S = summate_stats(L#lock.stats),
+ summate_locks(Ls, #stats{ tries = Tries + S#stats.tries, colls = Colls + S#stats.colls, time = Time + S#stats.time, nt = Nt + S#stats.nt}).
+
+summate_stats(Stats) -> summate_stats(Stats, #stats{ tries = 0, colls = 0, time = 0, nt = 0}).
+summate_stats([], Stats) -> Stats;
+summate_stats([S|Ss], #stats{ tries = Tries, colls = Colls, time = Time, nt = Nt}) ->
+ summate_stats(Ss, #stats{ tries = Tries + S#stats.tries, colls = Colls + S#stats.colls, time = Time + S#stats.time, nt = Nt + S#stats.nt}).
+
+
+%% manipulators
+filter_locks_type(Locks, undefined) -> Locks;
+filter_locks_type(Locks, all) -> Locks;
+filter_locks_type(Locks, Types) when is_list(Types) ->
+ [ L || L <- Locks, lists:member(L#lock.type, Types)];
+filter_locks_type(Locks, Type) ->
+ [ L || L <- Locks, L#lock.type =:= Type].
+
+filter_locks(Locks, {Lockname, Ids}) when is_list(Ids) ->
+ [ L || L <- Locks, L#lock.name =:= Lockname, lists:member(L#lock.id, Ids)];
+filter_locks(Locks, {Lockname, Id}) ->
+ [ L || L <- Locks, L#lock.name =:= Lockname, L#lock.id =:= Id ];
+filter_locks(Locks, Lockname) ->
+ [ L || L <- Locks, L#lock.name =:= Lockname ].
+% order of processing
+% 2. cut thresholds
+% 3. sort locks
+% 4. max length of locks
+
+filter_print(PLs, Opts) ->
+ TLs = threshold_locks(PLs, proplists:get_value(thresholds, Opts, [])),
+ SLs = sort_locks(TLs, proplists:get_value(sort, Opts, time)),
+ CLs = cut_locks(SLs, proplists:get_value(max_locks, Opts, none)),
+ reverse_locks(CLs, proplists:get_value(reverse, Opts, false)).
+
+sort_locks(Locks, Type) -> lists:reverse(sort_locks0(Locks, Type)).
+sort_locks0(Locks, name) -> lists:keysort(#print.name, Locks);
+sort_locks0(Locks, id) -> lists:keysort(#print.id, Locks);
+sort_locks0(Locks, type) -> lists:keysort(#print.type, Locks);
+sort_locks0(Locks, tries) -> lists:keysort(#print.tries, Locks);
+sort_locks0(Locks, colls) -> lists:keysort(#print.colls, Locks);
+sort_locks0(Locks, ratio) -> lists:keysort(#print.cr, Locks);
+sort_locks0(Locks, time) -> lists:keysort(#print.time, Locks);
+sort_locks0(Locks, _) -> sort_locks0(Locks, time).
+
+% cut locks not above certain thresholds
+threshold_locks(Locks, Thresholds) ->
+ Tries = proplists:get_value(tries, Thresholds, -1),
+ Colls = proplists:get_value(colls, Thresholds, -1),
+ Time = proplists:get_value(time, Thresholds, -1),
+ [ L || L <- Locks, L#print.tries > Tries, L#print.colls > Colls, L#print.time > Time].
+
+cut_locks(Locks, N) when is_integer(N), N > 0 -> lists:sublist(Locks, N);
+cut_locks(Locks, _) -> Locks.
+
+%% reversal
+reverse_locks(Locks, true) -> lists:reverse(Locks);
+reverse_locks(Locks, _) -> Locks.
+
+
+%%
+string_names([]) -> "";
+string_names(Names) -> string_names(Names, []).
+string_names([Name], Strings) -> strings(lists:reverse([term2string(Name) | Strings]));
+string_names([Name|Names],Strings) -> string_names(Names, [term2string(Name) ++ ","|Strings]).
+
+%% combine_locations
+%% In:
+%% Locations :: [#lock{}] | [#stats{}]
+%% Out:
+%% [{{File,Line}, #stats{}, [Lockname]}]
+
+
+combine_locations(Locations) -> gb_trees:values(combine_locations(Locations, gb_trees:empty())).
+combine_locations([], Tree) -> Tree;
+combine_locations([S|_] = Stats, Tree) when is_record(S, stats) ->
+ combine_locations(Stats, undefined, Tree);
+combine_locations([#lock{ stats = Stats, name = Name}|Ls], Tree) ->
+ combine_locations(Ls, combine_locations(Stats, Name, Tree)).
+
+combine_locations([], _, Tree) -> Tree;
+combine_locations([S|Ss], Name, Tree) when is_record(S, stats)->
+ Key = {S#stats.file, S#stats.line},
+ Tree1 = case gb_trees:lookup(Key, Tree) of
+ none ->
+ gb_trees:insert(Key, {S, [Name]}, Tree);
+ {value, {C, Names}} ->
+ NewNames = case lists:member(Name, Names) of
+ true -> Names;
+ _ -> [Name | Names]
+ end,
+ gb_trees:update(Key, {
+ C#stats{
+ tries = C#stats.tries + S#stats.tries,
+ colls = C#stats.colls + S#stats.colls,
+ time = C#stats.time + S#stats.time,
+ nt = C#stats.nt + S#stats.nt
+ }, NewNames}, Tree)
+ end,
+ combine_locations(Ss, Name, Tree1).
+
+%% combines all statistics for a class (name) lock
+%% id's are translated to #id's.
+
+combine_classes(Locks, true) -> combine_classes1(Locks, gb_trees:empty());
+combine_classes(Locks, _) -> Locks.
+
+combine_classes1([], Tree) -> gb_trees:values(Tree);
+combine_classes1([L|Ls], Tree) ->
+ Key = L#lock.name,
+ case gb_trees:lookup(Key, Tree) of
+ none ->
+ combine_classes1(Ls, gb_trees:insert(Key, L#lock{ id = 1 }, Tree));
+ {value, C} ->
+ combine_classes1(Ls, gb_trees:update(Key, C#lock{
+ id = C#lock.id + 1,
+ stats = L#lock.stats ++ C#lock.stats
+ }, Tree))
+ end.
+
+locks_ids(Locks) -> locks_ids(Locks, []).
+locks_ids([], Out) -> Out;
+locks_ids([#lock{ name = Key } = L|Ls], Out) ->
+ case proplists:get_value(Key, Out) of
+ undefined ->
+ locks_ids(Ls, [{Key, [L#lock.id] } | Out]);
+ Ids ->
+ locks_ids(Ls, [{Key, [L#lock.id | Ids] } | proplists:delete(Key,Out)])
+ end.
+
+stats2print(Stats, Duration) ->
+ lists:map(fun
+ (S) ->
+ #print{
+ entry = term2string("~p:~p", [S#stats.file, S#stats.line]),
+ colls = S#stats.colls,
+ tries = S#stats.tries,
+ cr = percent(S#stats.colls, S#stats.tries),
+ time = S#stats.time,
+ dtr = percent(S#stats.time, Duration)
+ }
+ end, Stats).
+
+locks2print(Locks, Duration) ->
+ lists:map( fun
+ (L) ->
+ Tries = lists:sum([T || #stats{ tries = T} <- L#lock.stats]),
+ Colls = lists:sum([C || #stats{ colls = C} <- L#lock.stats]),
+ Time = lists:sum([T || #stats{ time = T} <- L#lock.stats]),
+ Cr = percent(Colls, Tries),
+ Dtr = percent(Time, Duration),
+ #print{
+ name = L#lock.name,
+ id = L#lock.id,
+ type = L#lock.type,
+ tries = Tries,
+ colls = Colls,
+ cr = Cr,
+ time = Time,
+ dtr = Dtr
+ }
+ end, Locks).
+
+%% state making
+
+data2state(Data, State) ->
+ Duration = time2us(proplists:get_value(duration, Data)),
+ Rawlocks = proplists:get_value(locks, Data),
+ Locks = locks2records(Rawlocks),
+ State#state{
+ duration = Duration,
+ locks = Locks
+ }.
+
+locks2records(Locks) -> locks2records(Locks, []).
+locks2records([], Out) -> Out;
+locks2records([{Name, Id, Type, Stats}|Locks], Out) ->
+ Lock = #lock{
+ name = Name,
+ id = clean_id_creation(Id),
+ type = Type,
+ stats = [ #stats{
+ file = File,
+ line = Line,
+ tries = Tries,
+ colls = Colls,
+ time = time2us({S, Ns}),
+ nt = N
+ } || {{File, Line}, {Tries, Colls, {S, Ns, N}}} <- Stats] },
+ locks2records(Locks, [Lock|Out]).
+
+clean_id_creation(Id) when is_pid(Id) ->
+ Bin = term_to_binary(Id),
+ <<H:3/binary, L:16, Node:L/binary, Ids:8/binary, _Creation/binary>> = Bin,
+ Bin2 = list_to_binary([H, bytes16(L), Node, Ids, 0]),
+ binary_to_term(Bin2);
+clean_id_creation(Id) when is_port(Id) ->
+ Bin = term_to_binary(Id),
+ <<H:3/binary, L:16, Node:L/binary, Ids:4/binary, _Creation/binary>> = Bin,
+ Bin2 = list_to_binary([H, bytes16(L), Node, Ids, 0]),
+ binary_to_term(Bin2);
+clean_id_creation(Id) ->
+ Id.
+
+%% serializer
+
+state_default(Field) -> proplists:get_value(Field, state2list(#state{})).
+
+state2list(State) ->
+ [_|Values] = tuple_to_list(State),
+ lists:zipwith(fun
+ (locks, Locks) -> {locks, [lock2list(Lock) || Lock <- Locks]};
+ (X, Y) -> {X,Y}
+ end, record_info(fields, state), Values).
+
+list2state(List) -> list2state(record_info(fields, state), List, [state]).
+list2state([], _, Out) -> list_to_tuple(lists:reverse(Out));
+list2state([locks|Fs], List, Out) ->
+ Locks = [ list2lock(Lock) || Lock <- proplists:get_value(locks, List, [])],
+ list2state(Fs, List, [Locks|Out]);
+list2state([F|Fs], List, Out) -> list2state(Fs, List, [proplists:get_value(F, List, state_default(F))|Out]).
+
+lock_default(Field) -> proplists:get_value(Field, lock2list(#lock{})).
+
+lock2list(Lock) ->
+ [_|Values] = tuple_to_list(Lock),
+ lists:zip(record_info(fields, lock), Values).
+
+list2lock(List) -> list2lock(record_info(fields, lock), List, [lock]).
+list2lock([], _, Out) -> list_to_tuple(lists:reverse(Out));
+list2lock([F|Fs], List, Out) -> list2lock(Fs, List, [proplists:get_value(F, List, lock_default(F))|Out]).
+
+%% printing
+
+%% print_lock_information
+%% In:
+%% Locks :: [#lock{}]
+%% Print :: [Type | {Type, integer()}]
+%%
+%% Out:
+%% ok
+
+auto_print_width(Locks, Print) ->
+ % iterate all lock entries to save all max length values
+ % these are records, so we do a little tuple <-> list smashing
+ R = lists:foldl(fun
+ (L, Max) ->
+ list_to_tuple(lists:reverse(lists:foldl(fun
+ ({print,print}, Out) -> [print|Out];
+ ({Str, Len}, Out) -> [erlang:min(erlang:max(length(s(Str))+1,Len),80)|Out]
+ end, [], lists:zip(tuple_to_list(L), tuple_to_list(Max)))))
+ end, #print{ id = 4, type = 5, entry = 5, name = 6, tries = 8, colls = 13, cr = 16, time = 11, dtr = 14 },
+ Locks),
+ % Setup the offsets for later pruning
+ Offsets = [
+ {id, R#print.id},
+ {name, R#print.name},
+ {type, R#print.type},
+ {entry, R#print.entry},
+ {tries, R#print.tries},
+ {colls, R#print.colls},
+ {ratio, R#print.cr},
+ {time, R#print.time},
+ {duration, R#print.dtr}],
+ % Prune offsets to only allow specified print options
+ lists:foldr(fun
+ ({Type, W}, Out) -> [{Type, W}|Out];
+ (Type, Out) -> [proplists:lookup(Type, Offsets)|Out]
+ end, [], Print).
+
+print_lock_information(Locks, Print) ->
+ % remake Print to autosize entries
+ AutoPrint = auto_print_width(Locks, Print),
+
+ print_header(AutoPrint),
+
+ lists:foreach(fun
+ (L) ->
+ print_lock(L, AutoPrint)
+ end, Locks),
+ ok.
+
+print_header(Opts) ->
+ Header = #print{
+ name = "lock",
+ id = "id",
+ type = "type",
+ entry = "location",
+ tries = "#tries",
+ colls = "#collisions",
+ cr = "collisions [%]",
+ time = "time [us]",
+ dtr = "duration [%]"
+ },
+ Divider = #print{
+ name = lists:duplicate(1 + length(Header#print.name), 45),
+ id = lists:duplicate(1 + length(Header#print.id), 45),
+ type = lists:duplicate(1 + length(Header#print.type), 45),
+ entry = lists:duplicate(1 + length(Header#print.entry), 45),
+ tries = lists:duplicate(1 + length(Header#print.tries), 45),
+ colls = lists:duplicate(1 + length(Header#print.colls), 45),
+ cr = lists:duplicate(1 + length(Header#print.cr), 45),
+ time = lists:duplicate(1 + length(Header#print.time), 45),
+ dtr = lists:duplicate(1 + length(Header#print.dtr), 45)
+ },
+ print_lock(Header, Opts),
+ print_lock(Divider, Opts),
+ ok.
+
+
+print_lock(L, Opts) -> print_lock(L, Opts, []).
+print_lock(_, [], Formats) -> print(strings(lists:reverse(Formats)));
+print_lock(L, [Opt|Opts], Formats) ->
+ case Opt of
+ id -> print_lock(L, Opts, [{space, 25, s(L#print.id) } | Formats]);
+ {id, W} -> print_lock(L, Opts, [{space, W, s(L#print.id) } | Formats]);
+ type -> print_lock(L, Opts, [{space, 18, s(L#print.type) } | Formats]);
+ {type, W} -> print_lock(L, Opts, [{space, W, s(L#print.type) } | Formats]);
+ entry -> print_lock(L, Opts, [{space, 30, s(L#print.entry)} | Formats]);
+ {entry, W} -> print_lock(L, Opts, [{space, W, s(L#print.entry)} | Formats]);
+ name -> print_lock(L, Opts, [{space, 22, s(L#print.name) } | Formats]);
+ {name, W} -> print_lock(L, Opts, [{space, W, s(L#print.name) } | Formats]);
+ tries -> print_lock(L, Opts, [{space, 12, s(L#print.tries)} | Formats]);
+ {tries, W} -> print_lock(L, Opts, [{space, W, s(L#print.tries)} | Formats]);
+ colls -> print_lock(L, Opts, [{space, 14, s(L#print.colls)} | Formats]);
+ {colls, W} -> print_lock(L, Opts, [{space, W, s(L#print.colls)} | Formats]);
+ ratio -> print_lock(L, Opts, [{space, 20, s(L#print.cr) } | Formats]);
+ {ratio, W} -> print_lock(L, Opts, [{space, W, s(L#print.cr) } | Formats]);
+ time -> print_lock(L, Opts, [{space, 15, s(L#print.time) } | Formats]);
+ {time, W} -> print_lock(L, Opts, [{space, W, s(L#print.time) } | Formats]);
+ duration -> print_lock(L, Opts, [{space, 20, s(L#print.dtr) } | Formats]);
+ {duration, W} -> print_lock(L, Opts, [{space, W, s(L#print.dtr) } | Formats]);
+ _ -> print_lock(L, Opts, Formats)
+ end.
+
+print_state_information(#state{ locks = Locks} = State) ->
+ Stats = summate_locks(Locks),
+ print("information:"),
+ print(kv("#locks", s(length(Locks)))),
+ print(kv("duration", s(State#state.duration) ++ " us" ++ " (" ++ s(State#state.duration/1000000) ++ " s)")),
+ print("\nsummated stats:"),
+ print(kv("#tries", s(Stats#stats.tries))),
+ print(kv("#colls", s(Stats#stats.colls))),
+ print(kv("wait time", s(Stats#stats.time) ++ " us" ++ " ( " ++ s(Stats#stats.time/1000000) ++ " s)")),
+ print(kv("percent of duration", s(Stats#stats.time/State#state.duration*100) ++ " %")),
+ ok.
+
+%% AUX
+
+time2us({S, Ns}) -> round(S*1000000 + Ns/1000).
+
+percent(_,0) -> 0.0;
+percent(T,N) -> T/N*100.
+
+options(Opts, Default) when is_list(Default) ->
+ options1(proplists:unfold(Opts), Default).
+options1([], Defaults) -> Defaults;
+options1([{Key, Value}|Opts], Defaults) ->
+ case proplists:get_value(Key, Defaults) of
+ undefined -> options1(Opts, [{Key, Value} | Defaults]);
+ _ -> options1(Opts, [{Key, Value} | proplists:delete(Key, Defaults)])
+ end.
+
+%%% AUX STRING FORMATTING
+
+print(String) -> io:format("~s~n", [String]).
+
+kv(Key, Value) -> kv(Key, Value, 20).
+kv(Key, Value, Offset) -> term2string(term2string("~~~ps : ~~s", [Offset]),[Key, Value]).
+
+s(T) when is_float(T) -> term2string("~.4f", [T]);
+s(T) when is_list(T) -> term2string("~s", [T]);
+s(T) -> term2string(T).
+
+strings(Strings) -> strings(Strings, []).
+strings([], Out) -> Out;
+strings([{space, N, S} | Ss], Out) -> strings(Ss, Out ++ term2string(term2string("~~~ps", [N]), [S]));
+strings([{format, Format, S} | Ss], Out) -> strings(Ss, Out ++ term2string(Format, [S]));
+strings([S|Ss], Out) -> strings(Ss, Out ++ term2string("~s", [S])).
+
+
+term2string({M,F,A}) when is_atom(M), is_atom(F), is_integer(A) -> term2string("~p:~p/~p", [M,F,A]);
+term2string(Term) when is_port(Term) ->
+ % ex #Port<6442.816>
+ <<_:3/binary, L:16, Node:L/binary, Ids:32, _/binary>> = term_to_binary(Term),
+ term2string("#Port<~s.~w>", [Node, Ids]);
+term2string(Term) when is_pid(Term) ->
+ % ex <0.80.0>
+ <<_:3/binary, L:16, Node:L/binary, Ids:32, Serial:32, _/binary>> = term_to_binary(Term),
+ term2string("<~s.~w.~w>", [Node, Ids, Serial]);
+term2string(Term) -> term2string("~w", [Term]).
+term2string(Format, Terms) -> lists:flatten(io_lib:format(Format, Terms)).
+
+%%% AUD id binary
+
+bytes16(Value) ->
+ B0 = Value band 255,
+ B1 = (Value bsr 8) band 255,
+ <<B1, B0>>.
+
+bytes32(Value) ->
+ B0 = Value band 255,
+ B1 = (Value bsr 8) band 255,
+ B2 = (Value bsr 16) band 255,
+ B3 = (Value bsr 24) band 255,
+ <<B3, B2, B1, B0>>.
diff --git a/lib/tools/src/xref_utils.erl b/lib/tools/src/xref_utils.erl
index aeb7bf9f1c..680b7e8aac 100644
--- a/lib/tools/src/xref_utils.erl
+++ b/lib/tools/src/xref_utils.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2000-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 2000-2010. All Rights Reserved.
+%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
-%%
+%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
-%%
+%%
%% %CopyrightEnd%
%%
-module(xref_utils).
@@ -453,7 +453,8 @@ find_beam(Module) when is_atom(Module) ->
non_existing ->
error({no_such_module, Module});
preloaded ->
- {_M, _Bin, File} = code:get_object_code(Module),
+ {Module, {_M, _Bin, File}} =
+ {Module, code:get_object_code(Module)},
{ok, File};
cover_compiled ->
error({cover_compiled, Module});
diff --git a/lib/tools/test/Makefile b/lib/tools/test/Makefile
new file mode 100644
index 0000000000..3a59be758a
--- /dev/null
+++ b/lib/tools/test/Makefile
@@ -0,0 +1,93 @@
+#
+# %CopyrightBegin%
+#
+# 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%
+#
+include $(ERL_TOP)/make/target.mk
+include $(ERL_TOP)/make/$(TARGET)/otp.mk
+
+MODULES = \
+ cover_SUITE \
+ eprof_SUITE \
+ emem_SUITE \
+ fprof_SUITE \
+ cprof_SUITE \
+ instrument_SUITE \
+ lcnt_SUITE \
+ make_SUITE \
+ tools_SUITE \
+ xref_SUITE \
+ ignore_cores
+
+ERL_FILES= $(MODULES:%=%.erl)
+
+TARGET_FILES= $(MODULES:%=$(EBIN)/%.$(EMULATOR))
+INSTALL_PROGS= $(TARGET_FILES)
+
+EMAKEFILE=Emakefile
+
+SPEC_FILES= tools.spec tools.spec.win
+
+# ----------------------------------------------------
+# Release directory specification
+# ----------------------------------------------------
+RELSYSDIR = $(RELEASE_PATH)/tools_test
+
+# ----------------------------------------------------
+# FLAGS
+# ----------------------------------------------------
+ERL_MAKE_FLAGS +=
+ERL_COMPILE_FLAGS += -I$(ERL_TOP)/lib/test_server/include \
+ -I$(ERL_TOP)/lib/percept/include
+
+EBIN = .
+
+# ----------------------------------------------------
+# Targets
+# ----------------------------------------------------
+.PHONY: make_emakefile
+
+make_emakefile:
+ $(ERL_TOP)/make/make_emakefile $(ERL_COMPILE_FLAGS) -o$(EBIN) $(MODULES)\
+ > $(EMAKEFILE)
+
+tests debug opt: make_emakefile
+ erl $(ERL_MAKE_FLAGS) -make
+
+clean:
+ rm -f $(EMAKEFILE)
+ rm -f $(TARGET_FILES)
+ rm -f core *~
+
+docs:
+
+
+# ----------------------------------------------------
+# Release Target
+# ----------------------------------------------------
+include $(ERL_TOP)/make/otp_release_targets.mk
+
+release_spec: opt
+
+release_tests_spec: make_emakefile
+ $(INSTALL_DIR) $(RELSYSDIR)
+ $(INSTALL_DATA) $(SPEC_FILES) $(EMAKEFILE) $(ERL_FILES) $(RELSYSDIR)
+ chmod -f -R u+w $(RELSYSDIR)
+ @tar cf - *_SUITE_data | (cd $(RELSYSDIR); tar xf -)
+
+release_docs_spec:
+
+
diff --git a/lib/tools/test/cover_SUITE.erl b/lib/tools/test/cover_SUITE.erl
new file mode 100644
index 0000000000..b9ccd62d0b
--- /dev/null
+++ b/lib/tools/test/cover_SUITE.erl
@@ -0,0 +1,1198 @@
+%%
+%% %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(cover_SUITE).
+
+-export([all/1]).
+-export([start/1, compile/1, analyse/1, misc/1, stop/1,
+ distribution/1, export_import/1,
+ otp_5031/1, eif/1, otp_5305/1, otp_5418/1, otp_6115/1, otp_7095/1,
+ otp_8188/1, otp_8270/1, otp_8273/1, otp_8340/1]).
+
+-include("test_server.hrl").
+
+%%----------------------------------------------------------------------
+%% The following directory structure is assumed:
+%% cwd __________________________________________
+%% | \ \ \ \ \ \ \
+%% a b cc d f d1 compile_beam_____ otp_6115
+%% | \ \ \ \ \ \ \
+%% e crypt v w x d f1 f2
+%% |
+%% y
+%%----------------------------------------------------------------------
+
+all(suite) ->
+ case whereis(cover_server) of
+ undefined ->
+ [start, compile, analyse, misc, stop, distribution,
+ export_import,
+ otp_5031, eif, otp_5305, otp_5418, otp_6115, otp_7095,
+ otp_8188, otp_8270, otp_8273, otp_8340];
+ _pid ->
+ {skip,"It looks like the test server is running cover. "
+ "Can't run cover test."}
+ end.
+
+start(suite) -> [];
+start(Config) when is_list(Config) ->
+ ?line ok = file:set_cwd(?config(data_dir, Config)),
+
+ ?line Files = lsfiles(),
+ ?line remove(files(Files, ".out")),
+
+ ?line {ok, Pid} = cover:start(),
+ ?line {error, {already_started, Pid}} = cover:start().
+
+compile(suite) -> [];
+compile(Config) when is_list(Config) ->
+ ?line ok = file:set_cwd(?config(data_dir, Config)),
+
+ ?line Result1 = cover:compile_directory(),
+ ?line SortedResult = lists:sort(Result1),
+ ?line {ok, CWD} = file:get_cwd(),
+ ?line Result2 = cover:compile_directory(CWD),
+ ?line SortedResult = lists:sort(Result2),
+ ?line [{error,_DFile},{ok,a},{ok,b},{ok,cc},{ok,f}] = SortedResult,
+ ?line [{ok,e}] = cover:compile_directory("d1"),
+ ?line {error,enoent} = cover:compile_directory("d2"),
+
+ ?line {ok,a} = cover:compile(a),
+ ?line {ok,b} = compile:file(b),
+ ?line code:purge(b),
+ ?line {module,b} = code:load_file(b),
+ ?line {ok,d} = cover:compile("d.erl", [{d,'AGE',42}]),
+ ?line {error,_BBFile} = cover:compile(bb),
+
+ ?line StdlibDir = code:lib_dir(stdlib),
+ ?line Lists = filename:join([StdlibDir, "src", "lists.erl"]),
+ ?line {error, Lists} = cover:compile(Lists),
+
+ %% For compiling beam: using dummy files v,w,x,y and z
+ ?line file:set_cwd("compile_beam"),
+ ?line {ok,_} = compile:file(v,[debug_info,report]),
+ ?line {ok,_} = compile:file(w,[debug_info,report]),
+ ?line {ok,_} = compile:file(x),
+ ?line {ok,_} = compile:file("d/y",[debug_info,{outdir,"d"},report]),
+ ?line Key = "A Krypto Key",
+ ?line {ok,_} = compile:file(crypt, [debug_info,{debug_info_key,Key},report]),
+ ?line {ok,v} = cover:compile_beam(v),
+ ?line {ok,w} = cover:compile_beam("w.beam"),
+ ?line {error,{encrypted_abstract_code,_}} =
+ cover:compile_beam("crypt.beam"),
+ ?line ok = beam_lib:crypto_key_fun(simple_crypto_fun(Key)),
+ ?line {ok,crypt} = cover:compile_beam("crypt.beam"),
+ ?line {error,{no_abstract_code,"./x.beam"}} = cover:compile_beam(x),
+ ?line {error,{already_cover_compiled,no_beam_found,a}}=cover:compile_beam(a),
+ ?line {error,non_existing} = cover:compile_beam(z),
+ ?line [{ok,y}] = cover:compile_beam_directory("d"),
+ ?line Result3 = lists:sort(cover:compile_beam_directory()),
+ ?line [{error,{no_abstract_code,_XBeam}},{ok,crypt},{ok,v},{ok,w}] = Result3,
+ ?line {error,enoent} = cover:compile_beam_directory("d2"),
+ ?line decompile([v,w,y]),
+ ?line Files = lsfiles(),
+ ?line remove(files(Files, ".beam")).
+
+simple_crypto_fun(Key) ->
+ fun(init) -> ok;
+ ({debug_info, des3_cbc, crypt, _}) -> Key
+ end.
+
+analyse(suite) -> [];
+analyse(Config) when is_list(Config) ->
+ ?line ok = file:set_cwd(?config(data_dir, Config)),
+
+ ?line done = a:start(5),
+
+ ?line {ok, {a,{17,2}}} = cover:analyse(a, coverage, module),
+ ?line {ok, [{{a,start,1},{6,0}},
+ {{a,stop,1},{0,1}},
+ {{a,pong,1},{1,0}},
+ {{a,loop,3},{5,1}},
+ {{a,trycatch,1},{4,0}},
+ {{a,exit_kalle,0},{1,0}}]} = cover:analyse(a, coverage, function),
+ ?line {ok, [{{a,start,1,1},{6,0}},
+ {{a,stop,1,1},{0,1}},
+ {{a,pong,1,1},{1,0}},
+ {{a,loop,3,1},{3,1}},
+ {{a,loop,3,2},{2,0}},
+ {{a,trycatch,1,1},{4,0}},
+ {{a,exit_kalle,0,1},{1,0}}]} = cover:analyse(a, coverage, clause),
+ ?line {ok, [{{a,9},{1,0}},
+ {{a,10},{1,0}},
+ {{a,11},{1,0}},
+ {{a,13},{1,0}},
+ {{a,14},{1,0}},
+ {{a,15},{1,0}},
+ {{a,21},{0,1}},
+ {{a,26},{1,0}},
+ {{a,31},{1,0}},
+ {{a,32},{1,0}},
+ {{a,34},{1,0}},
+ {{a,36},{0,1}},
+ {{a,39},{1,0}},
+ {{a,40},{1,0}},
+ {{a,44},{1,0}},
+ {{a,47},{1,0}},
+ {{a,49},{1,0}},
+ {{a,51},{1,0}},
+ {{a,55},{1,0}}]} = cover:analyse(a, coverage, line),
+
+ ?line {ok, {a,15}} = cover:analyse(a, calls, module),
+ ?line {ok, [{{a,start,1},1},
+ {{a,stop,1},0},
+ {{a,pong,1},5},
+ {{a,loop,3},6},
+ {{a,trycatch,1},2},
+ {{a,exit_kalle,0},1}]} = cover:analyse(a, calls, function),
+ ?line {ok, [{{a,start,1,1},1},
+ {{a,stop,1,1},0},
+ {{a,pong,1,1},5},
+ {{a,loop,3,1},5},
+ {{a,loop,3,2},1},
+ {{a,trycatch,1,1},2},
+ {{a,exit_kalle,0,1},1}]} = cover:analyse(a, calls, clause),
+ ?line {ok, [{{a,9},1},
+ {{a,10},1},
+ {{a,11},1},
+ {{a,13},1},
+ {{a,14},1},
+ {{a,15},1},
+ {{a,21},0},
+ {{a,26},5},
+ {{a,31},5},
+ {{a,32},5},
+ {{a,34},5},
+ {{a,36},0},
+ {{a,39},1},
+ {{a,40},1},
+ {{a,44},2},
+ {{a,47},1},
+ {{a,49},1},
+ {{a,51},2},
+ {{a,55},1}]} = cover:analyse(a, calls, line),
+
+ ?line {ok, [{{a,start,1},{6,0}},
+ {{a,stop,1},{0,1}},
+ {{a,pong,1},{1,0}},
+ {{a,loop,3},{5,1}},
+ {{a,trycatch,1},{4,0}},
+ {{a,exit_kalle,0},{1,0}}]} = cover:analyse(a),
+ ?line {ok, {a,{17,2}}} = cover:analyse(a, module),
+ ?line {ok, [{{a,start,1},1},
+ {{a,stop,1},0},
+ {{a,pong,1},5},
+ {{a,loop,3},6},
+ {{a,trycatch,1},2},
+ {{a,exit_kalle,0},1}]} = cover:analyse(a, calls),
+
+ ?line {ok, "a.COVER.out"} = cover:analyse_to_file(a),
+ ?line {ok, "e.COVER.out"} = cover:analyse_to_file(e),
+ ?line {ok, "a.COVER.html"} = cover:analyse_to_file(a,[html]),
+ ?line {ok, "e.COVER.html"} = cover:analyse_to_file(e,[html]),
+
+ %% analyse_to_file of file which is compiled from beam
+ ?line {ok,f} = compile:file(f,[debug_info]),
+ ?line code:purge(f),
+ ?line {module,f} = code:load_file(f),
+ ?line {ok,f} = cover:compile_beam(f),
+ ?line f:f2(),
+ ?line {ok, "f.COVER.out"} = cover:analyse_to_file(f),
+
+ %% Source code cannot be found by analyse_to_file
+ ?line {ok,v} = compile:file("compile_beam/v",[debug_info]),
+ ?line code:purge(v),
+ ?line {module,v} = code:load_file(v),
+ ?line {ok,v} = cover:compile_beam(v),
+ ?line {error,no_source_code_found} = cover:analyse_to_file(v),
+
+ ?line {error,{not_cover_compiled,b}} = cover:analyse(b),
+ ?line {error,{not_cover_compiled,g}} = cover:analyse(g),
+ ?line {error,{not_cover_compiled,b}} = cover:analyse_to_file(b),
+ ?line {error,{not_cover_compiled,g}} = cover:analyse_to_file(g).
+
+misc(suite) -> [];
+misc(Config) when is_list(Config) ->
+ ?line ok = file:set_cwd(?config(data_dir, Config)),
+
+ ?line [a,cc,crypt,d,e,f,v] = lists:sort(cover:modules()),
+
+ ?line {ok,cc} = compile:file(cc),
+ ?line code:purge(cc),
+ ?line {module,cc} = code:load_file(cc),
+ ?line [a,crypt,d,e,f,v] = lists:sort(cover:modules()),
+
+ ?line {file, _File} = cover:is_compiled(a),
+ ?line false = cover:is_compiled(b),
+ ?line false = cover:is_compiled(g),
+
+ ?line ok = cover:reset(a),
+ ?line {ok, {a,{0,19}}} = cover:analyse(a, module),
+ ?line ok = cover:reset().
+
+stop(suite) -> [];
+stop(Config) when is_list(Config) ->
+ ?line ok = file:set_cwd(?config(data_dir, Config)),
+
+ ?line cover_compiled = code:which(a),
+ ?line {ok,d} = compile:file(d, [{d,'AGE',42}]),
+ ?line code:purge(d),
+ ?line {module,d} = code:load_file(d),
+ ?line ok = cover:stop(),
+ ?line Beam = code:which(a),
+ ?line true = is_unloaded(Beam),
+
+ ?line Files = lsfiles(),
+ ?line remove(files(Files, ".out")),
+ ?line remove(files(Files, ".html")),
+ ?line remove(files(Files, ".beam")).
+
+distribution(suite) -> [];
+distribution(Config) when is_list(Config) ->
+ ?line DataDir = ?config(data_dir, Config),
+ ?line ok = file:set_cwd(DataDir),
+
+ ?line {ok,N1} = ?t:start_node(cover_SUITE_distribution1,slave,[]),
+ ?line {ok,N2} = ?t:start_node(cover_SUITE_distribution2,slave,[]),
+ ?line {ok,N3} = ?t:start_node(cover_SUITE_distribution3,slave,[]),
+
+ %% Check that an already compiled module is loaded on new nodes
+ ?line {ok,f} = cover:compile(f),
+ ?line {ok,[_,_,_]} = cover:start(nodes()),
+ ?line cover_compiled = code:which(f),
+ ?line cover_compiled = rpc:call(N1,code,which,[f]),
+ ?line cover_compiled = rpc:call(N2,code,which,[f]),
+ ?line cover_compiled = rpc:call(N3,code,which,[f]),
+
+ %% Check that a node cannot be started twice
+ ?line {ok,[]} = cover:start(N2),
+
+ %% Check that the current node (i.e. the main node) is not started with
+ %% start/1 and not stopped with stop/1
+ ?line {ok,[]} = cover:start(node()),
+ ?line ok = cover:stop(node()),
+ ?line true = is_pid(whereis(cover_server)),
+
+ %% Check that a new compiled module is loaded on all existing nodes
+ ?line compile:file("compile_beam/v",[debug_info]),
+ ?line {ok,v} = cover:compile_beam(v),
+ ?line cover_compiled = code:which(v),
+ ?line cover_compiled = rpc:call(N1,code,which,[v]),
+ ?line cover_compiled = rpc:call(N2,code,which,[v]),
+ ?line cover_compiled = rpc:call(N3,code,which,[v]),
+
+ %% this is lost when the node is killed
+ ?line rpc:call(N3,f,f2,[]),
+ ?line rpc:call(N3,erlang,halt,[]),
+
+ %% this should be visible in analyse
+ ?line rpc:call(N1,f,f1,[]),
+
+ %% Check that data is collected from remote node when stopped
+ ?line ok = cover:stop(N1),
+ ?line N1Beam = rpc:call(N1,code,which,[f]),
+ ?line true = is_unloaded(N1Beam),
+ ?line check_f_calls(1,0),
+
+ %% Call f:f1() again on another node and check that number of calls is
+ %% accumulated.
+ ?line f:f1(),
+ ?line check_f_calls(2,0),
+
+ %% Check that reset works on all nodes
+ ?line f:f1(),
+ ?line rpc:call(N2,f,f1,[]),
+ ?line ok = cover:reset(f),
+ ?line check_f_calls(0,0),
+
+ %% Check that data is collected from all nodes
+ ?line rpc:call(N2,f,f1,[]),
+ ?line f:f2(),
+ ?line check_f_calls(1,1),
+
+ %% Check that same data is not fetched again (i.e. that analyse does
+ %% reset on the remote node(s))
+ ?line check_f_calls(1,1),
+
+ %% Check that stop() unloads on all nodes
+ ?line ok = cover:stop(),
+ ?line LocalBeam = code:which(f),
+ ?line N2Beam = rpc:call(N2,code,which,[f]),
+ ?line true = is_unloaded(LocalBeam),
+ ?line true = is_unloaded(N2Beam),
+
+ %% Check that cover_server on remote node dies if main node dies
+ ?line {ok,[N1]} = cover:start(N1),
+ ?line true = is_pid(rpc:call(N1,erlang,whereis,[cover_server])),
+ ?line exit(whereis(cover_server),kill),
+ ?line timer:sleep(10),
+ ?line undefined = rpc:call(N1,erlang,whereis,[cover_server]),
+
+ %% Cleanup
+ ?line Files = lsfiles(),
+ ?line remove(files(Files, ".beam")),
+ ?line ?t:stop_node(N1),
+ ?line ?t:stop_node(N2).
+
+
+export_import(suite) -> [];
+export_import(Config) when is_list(Config) ->
+ ?line DataDir = ?config(data_dir, Config),
+ ?line ok = file:set_cwd(DataDir),
+
+ %% Export one module
+ ?line {ok,f} = cover:compile(f),
+ ?line f:f1(),
+ %% check that no info is written about where data comes from when no
+ %% files are imported
+ ?line ?t:capture_start(),
+ ?line check_f_calls(1,0),
+ ?line [] = ?t:capture_get(),
+ ?line ?t:capture_stop(),
+ ?line ok = cover:export("f_exported",f),
+ ?line check_f_calls(1,0),
+ ?line ok = cover:stop(),
+
+ %% Check that same data exists after import and that info is written about
+ %% data comming from imported file
+ ?line ok = cover:import("f_exported"),
+ ?line ?t:capture_start(),
+ ?line check_f_calls(1,0),
+ ?line [Text1] = ?t:capture_get(),
+ ?line "Analysis includes data from imported files"++_ = lists:flatten(Text1),
+ ?line ?t:capture_stop(),
+
+ %% Export all modules
+ ?line {ok,a} = cover:compile(a),
+ ?line ?t:capture_start(),
+ ?line ok = cover:export("all_exported"),
+ ?line [Text2] = ?t:capture_get(),
+ ?line "Export includes data from imported files"++_ = lists:flatten(Text2),
+ ?line ?t:capture_stop(),
+ ?line ok = cover:stop(),
+ ?line ok = cover:import("all_exported"),
+ ?line check_f_calls(1,0),
+
+ %% Check that data is reset when module is compiled again, and that
+ %% warning is written when data is deleted for imported module.
+ ?line ?t:capture_start(),
+ ?line {ok,f} = cover:compile(f),
+ ?line timer:sleep(10), % capture needs some time
+ ?line [Text3] = ?t:capture_get(),
+ ?line "WARNING: Deleting data for module f imported from" ++ _ =
+ lists:flatten(Text3),
+ ?line ?t:capture_stop(),
+ ?line check_f_calls(0,0),
+
+ %% Check that data is summed up when first compiled and then imported
+ %% The module which has been compiled (f) is loaded from the file
+ %% all_exported again (since it has been reset during cover compiling),
+ %% but the other module (a) is not loaded since it is already loaded
+ ?line f:f1(),
+ ?line f:f2(),
+ ?line ok = cover:import("f_exported"),
+ ?line ?t:capture_start(),
+ ?line ok = cover:import("all_exported"),
+ ?line [Text4] = ?t:capture_get(), % a is not loaded again
+ ?line "WARNING: Module a already imported from " ++ _ = lists:flatten(Text4),
+ ?line ?t:capture_stop(),
+ ?line check_f_calls(3,1),
+
+ %% Check that warning is written when same file is imported twice,
+ %% and that data is not imported again
+ ?line ?t:capture_start(),
+ ?line ok = cover:import("all_exported"),
+ ?line [Text5,Text6] = ?t:capture_get(),
+ ?line "WARNING: Module f already imported from " ++ _ = lists:flatten(Text5),
+ ?line "WARNING: Module a already imported from " ++ _ = lists:flatten(Text6),
+ ?line ?t:capture_stop(),
+ ?line check_f_calls(3,1),
+
+ %% Check that reset removes all data and that the file which has been
+ %% reset can be imported again with no warning
+ ?line cover:reset(f),
+ ?line check_f_calls(0,0),
+ ?line ?t:capture_start(),
+ ?line ok = cover:import("all_exported"),
+ ?line [Text7] = ?t:capture_get(), % warning only on mod a
+ ?line "WARNING: Module a already imported from " ++ _ = lists:flatten(Text7),
+ ?line ?t:capture_stop(),
+ ?line check_f_calls(1,0),
+
+ %% same as above - only reset all
+ ?line cover:reset(),
+ ?line check_f_calls(0,0),
+ ?line ?t:capture_start(),
+ ?line ok = cover:import("all_exported"),
+ ?line [] = ?t:capture_get(), % no warnings
+ ?line ?t:capture_stop(),
+ ?line check_f_calls(1,0),
+
+ %% Cleanup
+ ?line ok = cover:stop(),
+ ?line Files = lsfiles(),
+ ?line remove(["f_exported","all_exported"|files(Files, ".beam")]).
+
+
+otp_5031(suite) -> [];
+otp_5031(Config) when is_list(Config) ->
+
+ Dog = ?t:timetrap(?t:seconds(10)),
+
+ ?line {ok,N1} = ?t:start_node(cover_SUITE_distribution1,slave,[]),
+ ?line {ok,[N1]} = cover:start(N1),
+ ?line {error,not_main_node} = rpc:call(N1,cover,modules,[]),
+ ?line cover:stop(),
+
+ ?t:timetrap_cancel(Dog),
+ ok.
+
+eif(doc) ->
+ ["Test the \'Exclude Included Functions\' functionality"];
+eif(suite) ->
+ [];
+eif(Config) when is_list(Config) ->
+ ?line ok = file:set_cwd(filename:join(?config(data_dir, Config),
+ "included_functions")),
+ ?line {ok, cover_inc} = compile:file(cover_inc,[debug_info]),
+ ?line {ok, cover_inc} = cover:compile_beam(cover_inc),
+
+ %% This function will cause an included function to be executed.
+ %% The analysis should only show the lines that actually exist
+ %% in cover_inc.beam - not the ones from the included file.
+ ?line cover_inc:func(),
+ ?line {ok, [_, _]} = cover:analyse(cover_inc, line),
+ ?line cover:stop(),
+ ok.
+
+otp_5305(suite) -> [];
+otp_5305(Config) when is_list(Config) ->
+ ?line ok = file:set_cwd(?config(priv_dir, Config)),
+
+ File = "t.erl",
+ Test = <<"-module(t).
+ -export([t/0]).
+ -include_lib(\"stdlib/include/ms_transform.hrl\").
+ t() ->
+ ets:fun2ms(fun(X) -> X end).
+ ">>,
+ ?line ok = file:write_file(File, Test),
+ ?line {ok, t} = cover:compile(File),
+ ?line cover:stop(),
+ ?line ok = file:delete(File),
+
+ ok.
+
+otp_5418(suite) -> [];
+otp_5418(Config) when is_list(Config) ->
+ ?line ok = file:set_cwd(?config(priv_dir, Config)),
+
+ File = "t.erl",
+ Test = <<"-module(t).
+ ">>,
+ ?line ok = file:write_file(File, Test),
+ ?line {ok, t} = cover:compile(File),
+ ?line {ok,{t,{0,0}}} = cover:analyse(t, module),
+ ?line cover:stop(),
+ ?line ok = file:delete(File),
+
+ ok.
+
+otp_6115(suite) -> [];
+otp_6115(Config) when is_list(Config) ->
+ case erlang:system_info(heap_type) of
+ hybrid -> {skip,"Hybrid-heap emulator doesn't keep track of funs"};
+ _ -> otp_6115_1(Config)
+ end.
+
+otp_6115_1(Config) ->
+ ?line {ok, CWD} = file:get_cwd(),
+ ?line Dir = filename:join(?config(data_dir, Config), otp_6115),
+ ?line ok = file:set_cwd(Dir),
+ ?line {ok, f1} = compile:file(f1, [debug_info]),
+ ?line {ok, f2} = compile:file(f2, [debug_info]),
+
+ %% Cover compile f1, but not f2
+ ?line {ok, f1} = cover:compile(f1),
+
+ %% If f1 is cover compiled, a process P is started with a
+ %% reference to the fun created in start_fail/0, and cover:stop() is
+ %% called, then P should be killed.
+ %% This is because (the fun held by P) references the cover
+ %% compiled code which should be *unloaded* when cover:stop() is
+ %% called -- running cover compiled code when there is no cover
+ %% server and thus no ets tables to bump counters in, makes no
+ %% sense.
+ ?line Pid1 = f1:start_fail(),
+
+ %% If f1 is cover compiled, a process P is started with a
+ %% reference to the fun created in start_ok/0, and
+ %% cover:stop() is called, then P should survive.
+ %% This is because (the fun held by) P always references the current
+ %% version of the module, and is thus not affected by the cover
+ %% compiled version being unloaded.
+ ?line Pid2 = f1:start_ok(),
+
+ %% Now stop cover
+ ?line cover:stop(),
+
+ %% Ensure that f1 is loaded (and not cover compiled), that Pid1
+ %% is dead and Pid2 is alive, but with no reference to old code
+ case code:which(f1) of
+ Beam when is_list(Beam) ->
+ ok;
+ Other ->
+ ?line ?t:fail({"f1 is not reloaded", Other})
+ end,
+ case process_info(Pid1) of
+ undefined ->
+ ok;
+ _PI1 ->
+ RefToOldP = erlang:check_process_code(Pid1, f1),
+ ?line ?t:fail({"Pid1 still alive", RefToOldP})
+ end,
+ case process_info(Pid2) of
+ PI2 when is_list(PI2) ->
+ case erlang:check_process_code(Pid2, f2) of
+ false ->
+ ok;
+ true ->
+ ?line ?t:fail("Pid2 has ref to old code")
+ end;
+ undefined ->
+ ?line ?t:fail("Pid2 has died")
+ end,
+
+ ?line file:set_cwd(CWD),
+ ok.
+
+otp_7095(doc) ->
+ ["andalso/orelse"];
+otp_7095(suite) -> [];
+otp_7095(Config) when is_list(Config) ->
+ ?line ok = file:set_cwd(?config(priv_dir, Config)),
+
+ File = "t.erl",
+ Test = <<"-module(t).
+ -export([t/0]).
+ t() ->
+ t1(),
+ t2(),
+ t3(),
+ t4(),
+ t5(),
+ put(t6, 0),
+ 0 = t6(),
+ 1 = erase(t6),
+ t7(),
+ put(t8, 0),
+ {'EXIT',{{badarg,0},_}} = (catch t8()),
+ 1 = erase(t8),
+ t9(),
+ ok.
+
+ t1() ->
+ false % 20
+ andalso
+ true. % 22
+
+ t2() ->
+ true % 25
+ andalso
+ true. % 27
+
+ t3() ->
+ false % 30
+ orelse
+ true. % 32
+
+ t4() ->
+ true % 35
+ orelse
+ true. % 37
+
+ t5() ->
+ true % 40
+ andalso
+ true % 42
+ andalso
+ false. % 44
+
+ t6() ->
+ true andalso % 47
+ add_one(t6). % 48
+
+ t7() ->
+ true % 51
+ andalso
+ false % 53
+ andalso
+ not_ok. % 55
+
+ t8() ->
+ true % 58
+ andalso
+ true % 60
+ andalso
+ add_one(t8) % 62
+ andalso
+ false. % 64
+
+ t9() ->
+ if % 67
+ true ->
+ true % 69
+ andalso
+ false % 71
+ end
+ orelse
+ case ok of % 74
+ true ->
+ a; % 76
+ _ ->
+ true % 78
+ end.
+
+ add_one(T) ->
+ put(T, get(T) + 1). % 82
+ ">>,
+ ?line ok = file:write_file(File, Test),
+ ?line {ok, t} = cover:compile(File),
+ ?line ok = t:t(),
+ ?line {ok,[{{t,4},1},{{t,5},1},{{t,6},1},{{t,7},1},{{t,8},1},{{t,9},1},
+ {{t,10},1},{{t,11},1},{{t,12},1},{{t,13},1},{{t,14},1},
+ {{t,15},1},{{t,16},1},{{t,17},1},
+ {{t,20},1},{{t,22},0},
+ {{t,25},1},{{t,27},1},
+ {{t,30},1},{{t,32},1},
+ {{t,35},1},{{t,37},0},
+ {{t,40},1},{{t,42},1},{{t,44},1},
+ {{t,47},1},{{t,48},1},
+ {{t,51},1},{{t,53},1},{{t,55},0},
+ {{t,58},1},{{t,60},1},{{t,62},1},{{t,64},0},
+ {{t,67},1},{{t,69},1},{{t,71},1},{{t,74},1},
+ {{t,76},0},{{t,78},1},
+ {{t,82},2}]} = cover:analyse(t, calls, line),
+ ?line cover:stop(),
+ ?line ok = file:delete(File),
+
+ ok.
+
+otp_8270(doc) ->
+ ["OTP-8270. Bug."];
+otp_8270(suite) -> [];
+otp_8270(Config) when is_list(Config) ->
+ ?line DataDir = ?config(data_dir, Config),
+ ?line ok = file:set_cwd(DataDir),
+
+ ?line PrivDir = ?config(priv_dir, Config),
+
+ As = [{args," -pa " ++ PrivDir}],
+ ?line {ok,N1} = ?t:start_node(cover_n1,slave,As),
+ ?line {ok,N2} = ?t:start_node(cover_n2,slave,As),
+ ?line {ok,N3} = ?t:start_node(cover_n3,slave,As),
+
+ timer:sleep(500),
+ cover:start(nodes()),
+
+ Test = <<
+ "-module(m).\n"
+ "-compile(export_all).\n"
+ "t() -> t(0).\n"
+ "l() ->\n"
+ " catch ets:tab2list(cover_internal_data_table).\n"
+ "t(Sz) ->\n"
+ " case ets:info(cover_internal_data_table, size) of\n"
+ " Sz ->\n"
+ " m:t(Sz); % Not a local call! Newly loaded code is entered.\n"
+ " NSz ->\n"
+ " % error_logger:info_msg(\"~p: ~p ~p change~n L1 ~p~n\", \n"
+ " % [node(), Sz, NSz, l()]),\n"
+ " m:t(NSz)\n"
+ " end.\n">>,
+ ?line _File = c_mod(m, Test, Config),
+ Fun = fun m:t/0,
+ ?line Pid1 = spawn(Fun),
+ ?line Pid2 = spawn(N1, Fun),
+ ?line Pid3 = spawn(N2, Fun),
+ ?line Pid4 = spawn(N3, Fun),
+
+ ?line {ok, m} = cover:compile_beam(m),
+
+ timer:sleep(1000),
+
+ ?line Info = erlang:process_info(Pid1),
+ ?line N1_info = rpc:call(N1, erlang, process_info, [Pid2]),
+ ?line N2_info = rpc:call(N2, erlang, process_info, [Pid3]),
+ ?line N3_info = rpc:call(N3, erlang, process_info, [Pid4]),
+
+ ?line true = is_list(Info),
+ ?line {N1,true} = {N1,is_list(N1_info)},
+ ?line {N2,true} = {N2,is_list(N2_info)},
+ ?line {N3,true} = {N3,is_list(N3_info)},
+
+ ?line ?t:stop_node(N1),
+ ?line ?t:stop_node(N2),
+ ?line ?t:stop_node(N3),
+ ok.
+
+otp_8273(doc) ->
+ ["OTP-8270. Bug."];
+otp_8273(suite) -> [];
+otp_8273(Config) when is_list(Config) ->
+ Test = <<"-module(t).
+ -export([t/0]).
+ t() ->
+ foo = true andalso foo,
+ bar = false orelse bar,
+ ok.
+ ">>,
+ ?line File = cc_mod(t, Test, Config),
+ ?line ok = t:t(),
+ ?line cover:stop(),
+ ?line ok = file:delete(File),
+
+ ok.
+
+otp_8340(doc) ->
+ ["OTP-8340. Bug."];
+otp_8340(suite) -> [];
+otp_8340(Config) when is_list(Config) ->
+ ?line [{{t,1},1},{{t,2},1},{{t,4},1}] =
+ analyse_expr(<<"<< \n"
+ " <<3:2, \n"
+ " SeqId:62>> \n"
+ " || SeqId <- [64] >>">>, Config),
+
+ ok.
+
+otp_8188(doc) ->
+ ["Clauses on the same line."];
+otp_8188(suite) -> [];
+otp_8188(Config) when is_list(Config) ->
+ %% This example covers the bug report:
+ Test = <<"-module(t).
+ -export([test/1]).
+
+ -define(FOOBAR(X),
+ case X of
+ ok -> true;
+ _ -> false
+ end).
+
+ test(X)->
+ _Res =
+ ?FOOBAR(X).
+ ">>,
+ ?line File = cc_mod(t, Test, Config),
+ ?line false = t:test(nok),
+ ?line {ok,[{{t,11},1},{{t,12},1}]} = cover:analyse(t, calls, line),
+ ?line cover:stop(),
+ ?line ok = file:delete(File),
+
+ %% Bit string comprehensions are now traversed;
+ %% the handling of list comprehensions has been improved:
+ comprehension_8188(Config),
+
+ %% Variants of the reported bug:
+ bug_8188(Config),
+ ok.
+
+bug_8188(Cf) ->
+ ?line [{{t,1},1},{{t,2},1},{{t,3},1}] =
+ analyse_expr(<<"A = 3,\n" % 1
+ " case A of\n" % 1
+ " 2 -> two; 3 -> three end, A + 2">>, % 1
+ Cf),
+
+ ?line [{{t,1},1},
+ {{t,2},0},
+ {{t,3},1},
+ {{t,4},1},
+ {{t,5},1},
+ {{t,6},0},
+ {{t,7},1},
+ {{t,9},2}] =
+ analyse_expr(<<"case two() of\n" % 1
+ " 1 -> 2;\n" % 0
+ " _ -> begin 3 end\n" % 1
+ " +\n" % 1
+ " begin 4 end end, case two() of\n" % 1
+ " 1 -> a;\n" % 0
+ " 2 -> b; 3 -> c\n" % 1
+ " end.\n"
+ "two() -> 2">>, Cf), % 2
+
+ ?line [{{t,1},1}, {{t,2},1}, {{t,3},1},
+ {{t,4},1}, {{t,5},1}, {{t,6},0}] =
+ analyse_expr(<<" self() ! 1,\n"
+ " receive \n"
+ " X=1 -> a;\n"
+ " X=2 -> b end, case X of \n"
+ " 1 -> a;\n"
+ " 2 -> b\n"
+ " end">>, Cf),
+
+ T0 = <<"t1(X) ->\n "
+ "case X of\n"
+ " 1 -> A=a,B=A,B; % bump Li\n"
+ " 2 -> b; 3 -> case X of % 2 -> b shall bump Li\n"
+ " 3 -> a; % bump Li\n"
+ " 2 -> b end; 4 -> d end, case X of % Li\n"
+ " 1 -> a;\n"
+ " 2 -> b; 3 -> c;\n"
+ " 4 -> d\n"
+ " end">>,
+
+ T1 = [<<"a = t1(1). ">>,T0],
+ ?line [{{t,1},1}, {{t,2},1}, {{t,3},1}, {{t,4},0},
+ {{t,5},0}, {{t,6},1}, {{t,7},1}, {{t,8},0}, {{t,9},0}] =
+ analyse_expr(T1, Cf),
+
+ T2 = [<<"b = t1(2). ">>,T0],
+ ?line [{{t,1},1}, {{t,2},1}, {{t,3},0}, {{t,4},1},
+ {{t,5},0}, {{t,6},1}, {{t,7},0}, {{t,8},1}, {{t,9},0}] =
+ analyse_expr(T2, Cf),
+
+ T3 = [<<"c = t1(3). ">>,T0],
+ ?line [{{t,1},1}, {{t,2},1}, {{t,3},0}, {{t,4},1},
+ {{t,5},1}, {{t,6},1}, {{t,7},0}, {{t,8},1}, {{t,9},0}] =
+ analyse_expr(T3, Cf),
+
+ T4 = [<<"d = t1(4). ">>,T0],
+ ?line [{{t,1},1}, {{t,2},1}, {{t,3},0}, {{t,4},0},
+ {{t,5},0}, {{t,6},1}, {{t,7},0}, {{t,8},0}, {{t,9},1}] =
+ analyse_expr(T4, Cf),
+
+ ?line [{{t,1},1},{{t,2},1},{{t,3},1},{{t,4},1},{{t,5},1}] =
+ analyse_expr(
+ <<"2 = x3(1). "
+ "x3(X) ->\n"
+ " case X of \n"
+ " 1 -> case X of\n"
+ " 1 -> a, Y = 2;\n"
+ " 2 -> b, Y = 3 end, Y; 2 -> Y = 4 end, Y">>, Cf),
+
+ ?line [{{t,1},1},{{t,2},1},{{t,3},1},{{t,4},1}] =
+ analyse_expr(
+ <<"1 = x4(1). "
+ "x4(X) ->\n"
+ " case X of\n"
+ " 1 -> case X of\n"
+ " 1 -> Y = 1 end, case X of 1 -> Y = 1 end, Y end">>,
+ Cf),
+
+ T10 = <<"t1(X) ->\n"
+ "if\n"
+ " X =:= 1 -> a;\n"
+ " X =:= 2 -> b; X =:= 3 -> c end, case X of \n"
+ " 1 -> a;\n"
+ " 2 -> b; 3 -> c end, case X of\n"
+ " 1 -> a;\n"
+ " 2 -> b; 3 -> c\n"
+ " end">>,
+ T11 = [<<"a = t1(1). ">>,T10],
+ ?line [{{t,1},1}, {{t,2},1}, {{t,3},1}, {{t,4},1},
+ {{t,5},1}, {{t,6},1}, {{t,7},1}, {{t,8},0}] =
+ analyse_expr(T11, Cf),
+
+ T12 = [<<"b = t1(2). ">>,T10],
+ ?line [{{t,1},1}, {{t,2},1}, {{t,3},0}, {{t,4},1},
+ {{t,5},0}, {{t,6},1}, {{t,7},0}, {{t,8},1}] =
+ analyse_expr(T12, Cf),
+
+ T13 = [<<"c = t1(3). ">>,T10],
+ ?line [{{t,1},1}, {{t,2},1}, {{t,3},0}, {{t,4},1},
+ {{t,5},0}, {{t,6},1}, {{t,7},0}, {{t,8},1}] =
+ analyse_expr(T13, Cf),
+
+ T20 = <<"t1(X) ->\n"
+ "case X of\n"
+ " 1 -> a;\n"
+ " 2 -> b; 3 -> case X of\n"
+ " 1 -> a;\n"
+ " 2 -> b; 3 -> c end end, case X of\n"
+ " 1 -> a;\n"
+ " 2 -> b; 3 -> c\n"
+ " end">>,
+
+ T21 = [<<"a = t1(1). ">>,T20],
+ ?line [{{t,1},1}, {{t,2},1}, {{t,3},1}, {{t,4},0},
+ {{t,5},0}, {{t,6},1}, {{t,7},1}, {{t,8},0}] =
+ analyse_expr(T21, Cf),
+
+ T22 = [<<"b = t1(2). ">>,T20],
+ ?line [{{t,1},1}, {{t,2},1}, {{t,3},0}, {{t,4},1},
+ {{t,5},0}, {{t,6},1}, {{t,7},0}, {{t,8},1}] =
+ analyse_expr(T22, Cf),
+
+ T23 = [<<"c = t1(3). ">>,T20],
+ ?line [{{t,1},1}, {{t,2},1}, {{t,3},0}, {{t,4},1},
+ {{t,5},0}, {{t,6},1}, {{t,7},0}, {{t,8},1}] =
+ analyse_expr(T23, Cf),
+
+ T30 = <<
+ "t1(X) ->\n"
+ "case X of\n"
+ " 1 -> a;\n"
+ " 2 -> b; 3 -> case X of 1 -> a; 2 -> b; 3 -> c end end, case X of\n"
+ " 1 -> a;\n"
+ " 2 -> b; 3 -> c\n"
+ " end\n">>,
+
+ T31 = [<<"a = t1(1). ">>,T30],
+ ?line [{{t,1},1}, {{t,2},1}, {{t,3},1},
+ {{t,4},1}, {{t,5},1}, {{t,6},0}] =
+ analyse_expr(T31, Cf),
+
+ T32 = [<<"b = t1(2). ">>,T30],
+ ?line [{{t,1},1}, {{t,2},1}, {{t,3},0},
+ {{t,4},1}, {{t,5},0}, {{t,6},1}] =
+ analyse_expr(T32, Cf),
+
+ T33 = [<<"c = t1(3). ">>,T30],
+ ?line [{{t,1},1}, {{t,2},1}, {{t,3},0},
+ {{t,4},1}, {{t,5},0}, {{t,6},1}] =
+ analyse_expr(T33, Cf),
+
+ %% 'try' now traverses the body as a body...
+ ?line [{{t,1},1},{{t,2},1},{{t,3},1},{{t,4},0},{{t,6},1}] =
+ analyse_expr(<<"try \n"
+ " B = 2, \n"
+ " C = erlang:error(foo), \n"
+ " {B,C} \n"
+ "catch _:_ -> \n"
+ " foo \n"
+ "end">>, Cf),
+
+ %% receive after:
+ ?line [{{t,1},1},{{t,2},0},{{t,3},1}] =
+ analyse_expr(<<"receive \n"
+ " X=1 -> a; \n"
+ " X=2 -> b after begin 10 end -> X=3 end">>, Cf),
+ ?line [{{t,1},1},{{t,2},0},{{t,3},1}] =
+ analyse_expr(<<"receive \n"
+ " X=1 -> a; \n"
+ " X=2 -> b after 10 -> begin X=3 end end">>, Cf),
+ ok.
+
+comprehension_8188(Cf) ->
+ ?line [{{t,1},1}] =
+ analyse_expr(<<"[begin X end || X <- [1,2,3], X > 1]">>, Cf),
+ ?line [{{t,1},1},{{t,2},1}] =
+ analyse_expr(<<"[begin X end || \n"
+ " X <- [1,2,3], X > 1]">>, Cf),
+ ?line [{{t,1},1},{{t,2},1},{{t,3},3}] =
+ analyse_expr(<<"[begin X end || \n "
+ " X <- [1,2,3], \n "
+ " X > 1]">>, Cf),
+ ?line [{{t,1},1},{{t,3},1},{{t,4},3}] =
+ analyse_expr(<<"[begin X end || \n "
+ " X <- \n "
+ " [1,2,3], \n "
+ " X > 1]">>, Cf),
+ ?line [{{t,1},1},{{t,2},2}] =
+ analyse_expr(<<"[ \n "
+ " X || X <- [1,2,3], X > 1]">>, Cf),
+ ?line [{{t,1},1},{{t,2},2},{{t,3},3}] =
+ analyse_expr(<<"[ \n"
+ " X || X <- [1,2,3], \n"
+ " X > 1]">>, Cf),
+ ?line [{{t,1},1},{{t,2},1},{{t,3},2}] =
+ analyse_expr(<<"[ \n "
+ " X || X <- [1,2,3], X > 1, \n"
+ " X > 2]">>, Cf),
+
+ ?line [{{t,1},1},
+ {{t,3},2},
+ {{t,5},1},
+ {{t,7},1},
+ {{t,8},0},
+ {{t,12},3},
+ {{t,15},2},
+ {{t,17},2},
+ {{t,18},1}] =
+ analyse_expr(<<"[ \n" % 1
+ " begin\n"
+ " X * 2\n" % 2
+ " end ||\n"
+ " X <- [1,\n" % 1
+ " case two() of\n"
+ " 2 -> 2;\n" % 1
+ " _ -> two\n" % 0
+ " end,\n"
+ " 3],\n"
+ " begin\n"
+ " math:sqrt(X) > 1.0\n" % 3
+ " end,\n"
+ " begin\n"
+ " true\n" % 2
+ " end,\n"
+ " true]. \n" % 2
+ " two() -> 2">>, Cf), % 1
+
+ ?line [{{t,1},1},
+ {{t,2},2},
+ {{t,3},1},
+ {{t,5},1},
+ {{t,6},0},
+ {{t,9},3},
+ {{t,10},2},
+ {{t,11},2},
+ {{t,12},1}] =
+ analyse_expr(<<"[ \n"
+ " X * 2 || \n" % 2
+ " X <- [1,\n" % 1
+ " case two() of\n"
+ " 2 -> 2;\n" % 1
+ " _ -> two\n" % 0
+ " end,\n"
+ " 3],\n"
+ " math:sqrt(X) > 1.0,\n" % 3
+ " true,\n" % 2
+ " true]. \n" % 2
+ " two() -> 2">>, Cf), % 1
+
+ ?line [{{t,1},1},
+ {{t,2},2},
+ {{t,3},1},
+ {{t,4},1},
+ {{t,5},0},
+ {{t,8},1},
+ {{t,9},0},
+ {{t,12},3},
+ {{t,13},2},
+ {{t,14},2}] =
+ analyse_expr(<<"<< \n" % 1
+ " << (X*2) >> || \n" % 2
+ " <<X>> <= << (case two() of\n"
+ " 2 -> 1;\n" % 1
+ " _ -> 2\n" % 0
+ " end)/integer,\n"
+ " (case two() of \n"
+ " 2 -> 2;\n" % 1
+ " _ -> two\n" % 0
+ " end)/integer,\n"
+ " 3 >>, \n"
+ " math:sqrt(X) > 1.0,\n" % 3
+ " true >>.\n" % 2
+ "two() -> 2">>, Cf),
+
+ ?line [{{t,1},1},
+ {{t,2},4},
+ {{t,4},1},
+ {{t,6},1},
+ {{t,7},0},
+ {{t,10},3},
+ {{t,11},2},
+ {{t,12},4},
+ {{t,13},1}] =
+ analyse_expr(<<"<< \n" % 1
+ " << (2)\n" % 4
+ " :(8) >> || \n"
+ " <<X>> <= << 1,\n" % 1
+ " (case two() of \n"
+ " 2 -> 2;\n" % 1
+ " _ -> two\n" % 0
+ " end)/integer,\n"
+ " 3 >>, \n"
+ " math:sqrt(X) > 1.0,\n" % 3
+ " <<_>> <= << 1, 2 >>,\n" % 2
+ " true >>.\n" % 4
+ "two() -> 2">>, Cf), % 1
+
+ ok.
+
+%%--Auxiliary------------------------------------------------------------
+
+analyse_expr(Expr, Config) ->
+ Binary = [<<"-module(t). "
+ "-export([t/0]). "
+ "t() -> ">>, Expr, <<".\n">>],
+ File = cc_mod(t, Binary, Config),
+ t:t(),
+ {ok, Result} = cover:analyse(t, calls, line),
+ ok = file:delete(File),
+ Result.
+
+cc_mod(M, Binary, Config) ->
+ {ok, Dir} = file:get_cwd(),
+ PrivDir = ?config(priv_dir, Config),
+ ok = file:set_cwd(PrivDir),
+ File = atom_to_list(M) ++ ".erl",
+ try
+ ok = file:write_file(File, Binary),
+ {ok, M} = cover:compile(File),
+ filename:join(PrivDir, File)
+ after file:set_cwd(Dir)
+ end.
+
+c_mod(M, Binary, Config) ->
+ {ok, Dir} = file:get_cwd(),
+ PrivDir = ?config(priv_dir, Config),
+ ok = file:set_cwd(PrivDir),
+ File = atom_to_list(M) ++ ".erl",
+ try
+ ok = file:write_file(File, Binary),
+ {ok, M} = compile:file(File, [debug_info]),
+ code:purge(M),
+ AbsFile = filename:rootname(File, ".erl"),
+ code:load_abs(AbsFile, M),
+ filename:join(PrivDir, File)
+ after file:set_cwd(Dir)
+ end.
+
+lsfiles() ->
+ {ok, CWD} = file:get_cwd(),
+ lsfiles(CWD).
+
+lsfiles(Dir) ->
+ {ok, Files} = file:list_dir(Dir),
+ Files.
+
+files(Files, Ext) ->
+ lists:filter(fun(File) ->
+ case filename:extension(File) of
+ Ext -> true;
+ _ -> false
+ end
+ end,
+ Files).
+
+remove([File|Files]) ->
+ ok = file:delete(File),
+ remove(Files);
+remove([]) ->
+ ok.
+
+decompile([Mod|Mods]) ->
+ code:purge(Mod),
+ code:delete(Mod),
+ decompile(Mods);
+decompile([]) ->
+ ok.
+
+is_unloaded(What) ->
+ if
+ is_list(What) -> true;
+ What==non_existing -> true;
+ true -> false
+ end.
+
+check_f_calls(F1,F2) ->
+ {ok,[{{f,f1,0},F1},{{f,f2,0},F2}]} = cover:analyse(f,calls,function).
diff --git a/lib/tools/test/cover_SUITE_data/a.erl b/lib/tools/test/cover_SUITE_data/a.erl
new file mode 100644
index 0000000000..31119821cd
--- /dev/null
+++ b/lib/tools/test/cover_SUITE_data/a.erl
@@ -0,0 +1,55 @@
+-module(a).
+-export([start/1, stop/1]).
+-export([pong/1]).
+-export([loop/3,exit_kalle/0]).
+
+%% start(N) -> pid()
+%% N = integer()
+start(N) ->
+ Pong = b:start(),
+ spawn(?MODULE, loop, [self(), N, Pong]),
+ receive
+ done ->
+ {exit,kalle} = trycatch(fun ?MODULE:exit_kalle/0),
+ {throw,kalle} = trycatch(fun() -> throw(kalle) end),
+ done
+ end.
+
+%% stop(Ping) -> stop
+%% Ping = pid()
+stop(Ping) ->
+ Ping ! stop.
+
+%% pong(Ping) -> pong
+%% Ping = pid()
+pong(Ping) ->
+ Ping ! pong.
+
+%%--Internal functions------------------------------------------------
+
+loop(Starter, N, Pong) when N>0 ->
+ Pong ! {ping, self()},
+ receive
+ pong ->
+ loop(Starter, N-1, Pong);
+ stop ->
+ done
+ end;
+loop(Starter, 0, Pong) ->
+ Pong ! stop,
+ Starter ! done.
+
+
+trycatch(Fun) ->
+ try Fun()
+ catch
+ Throw ->
+ {throw,Throw};
+ exit:Reason ->
+ {exit,Reason}
+ after
+ cleanup
+ end.
+
+exit_kalle() ->
+ exit(kalle).
diff --git a/lib/tools/test/cover_SUITE_data/b.erl b/lib/tools/test/cover_SUITE_data/b.erl
new file mode 100644
index 0000000000..13f39b8cb9
--- /dev/null
+++ b/lib/tools/test/cover_SUITE_data/b.erl
@@ -0,0 +1,14 @@
+-module(b).
+-export([start/0, loop/0]).
+
+start() ->
+ spawn(?MODULE, loop, []).
+
+loop() ->
+ receive
+ {ping, Ping} ->
+ a:pong(Ping),
+ loop();
+ stop ->
+ done
+ end.
diff --git a/lib/tools/test/cover_SUITE_data/cc.erl b/lib/tools/test/cover_SUITE_data/cc.erl
new file mode 100644
index 0000000000..587bdbe493
--- /dev/null
+++ b/lib/tools/test/cover_SUITE_data/cc.erl
@@ -0,0 +1,88 @@
+-module(cc).
+-export([epp/1, epp/2, dbg/1, dbg/2, cvr/1, cvr/2]).
+-export([p/2, pp/2]).
+
+%% epp(Module) - Creates Module.epp which contains all forms of Module
+%% as obtained by using epp.
+%%
+%% dbg(Module) - Creates Module.dbg which contains all forms of Module
+%% as obtained by using beam_lib:chunks/2.
+%%
+%% cvr(Module) - Creates Module.cvr which contains all forms of Module
+%% as obtained by using cover:transform/3.
+%%
+
+epp(Module) ->
+ epp(Module, p).
+epp(Module, P) ->
+ File = atom_to_list(Module)++".erl",
+ {ok,Cwd} = file:get_cwd(),
+ {ok, Fd1} = epp:open(File, [Cwd], []),
+ {ok, Fd2} = file:open(atom_to_list(Module)++".epp", write),
+
+ epp(Fd1, Fd2, P),
+
+ epp:close(Fd1),
+ file:close(Fd2),
+ ok.
+
+epp(Fd1, Fd2, P) ->
+ case epp:parse_erl_form(Fd1) of
+ {ok, {attribute,Line,Attr,Data}} ->
+ epp(Fd1, Fd2, P);
+ {ok, Form} when P==p ->
+ io:format(Fd2, "~p.~n", [Form]),
+ epp(Fd1, Fd2, P);
+ {ok, Form} when P==pp ->
+ io:format(Fd2, "~p.~n", [erl_pp:form(Form)]),
+ epp(Fd1, Fd2, P);
+ {eof, Line} ->
+ ok
+ end.
+
+cvr(Module) ->
+ cvr(Module, p).
+cvr(Module, P) ->
+ case beam_lib:chunks(Module, [abstract_code]) of
+ {ok, {Module, [{abstract_code, no_abstract_code}]}} ->
+ {error, {no_debug_info,Module}};
+ {ok, {Module, [{abstract_code, {Vsn, Forms}}]}} ->
+ Vars = {vars,Module,Vsn, [],
+ undefined, undefined, undefined, undefined, undefined,
+ undefined,
+ false},
+ {ok, TForms, _Vars2} = cover:transform(Forms, [], Vars),
+ File = atom_to_list(Module)++".cvr",
+ apply(?MODULE, P, [File, TForms]);
+ Error ->
+ Error
+ end.
+
+dbg(Module) ->
+ dbg(Module, p).
+dbg(Module, P) ->
+ case beam_lib:chunks(Module, [abstract_code]) of
+ {ok, {Module, [{abstract_code, no_abstract_code}]}} ->
+ {error, {no_debug_info,Module}};
+ {ok, {Module, [{abstract_code, {Vsn, Forms}}]}} ->
+ File = atom_to_list(Module)++".dbg",
+ apply(?MODULE, P, [File, Forms]);
+ Error ->
+ Error
+ end.
+
+p(File, Forms) ->
+ {ok, Fd} = file:open(File, write),
+ lists:foreach(fun(Form) ->
+ io:format(Fd, "~p.~n", [Form])
+ end,
+ Forms),
+ file:close(Fd).
+
+pp(File, Forms) ->
+ {ok, Fd} = file:open(File, write),
+ lists:foreach(fun(Form) ->
+ io:format(Fd, "~s", [erl_pp:form(Form)])
+ end,
+ Forms),
+ file:close(Fd).
diff --git a/lib/tools/test/cover_SUITE_data/compile_beam/crypt.erl b/lib/tools/test/cover_SUITE_data/compile_beam/crypt.erl
new file mode 100644
index 0000000000..1596777edf
--- /dev/null
+++ b/lib/tools/test/cover_SUITE_data/compile_beam/crypt.erl
@@ -0,0 +1,6 @@
+-module(crypt).
+
+-export([f/0]).
+
+f() ->
+ ok.
diff --git a/lib/tools/test/cover_SUITE_data/compile_beam/d/y.erl b/lib/tools/test/cover_SUITE_data/compile_beam/d/y.erl
new file mode 100644
index 0000000000..14b9461410
--- /dev/null
+++ b/lib/tools/test/cover_SUITE_data/compile_beam/d/y.erl
@@ -0,0 +1,6 @@
+-module(y).
+
+-export([f/0]).
+
+f() ->
+ ok.
diff --git a/lib/tools/test/cover_SUITE_data/compile_beam/v.erl b/lib/tools/test/cover_SUITE_data/compile_beam/v.erl
new file mode 100644
index 0000000000..007957297a
--- /dev/null
+++ b/lib/tools/test/cover_SUITE_data/compile_beam/v.erl
@@ -0,0 +1,6 @@
+-module(v).
+
+-export([f/0]).
+
+f() ->
+ ok.
diff --git a/lib/tools/test/cover_SUITE_data/compile_beam/w.erl b/lib/tools/test/cover_SUITE_data/compile_beam/w.erl
new file mode 100644
index 0000000000..88ad606db8
--- /dev/null
+++ b/lib/tools/test/cover_SUITE_data/compile_beam/w.erl
@@ -0,0 +1,6 @@
+-module(w).
+
+-export([f/0]).
+
+f() ->
+ ok.
diff --git a/lib/tools/test/cover_SUITE_data/compile_beam/x.erl b/lib/tools/test/cover_SUITE_data/compile_beam/x.erl
new file mode 100644
index 0000000000..8953f6d05d
--- /dev/null
+++ b/lib/tools/test/cover_SUITE_data/compile_beam/x.erl
@@ -0,0 +1,6 @@
+-module(x).
+
+-export([f/0]).
+
+f() ->
+ ok.
diff --git a/lib/tools/test/cover_SUITE_data/d.erl b/lib/tools/test/cover_SUITE_data/d.erl
new file mode 100644
index 0000000000..696e27e49b
--- /dev/null
+++ b/lib/tools/test/cover_SUITE_data/d.erl
@@ -0,0 +1,156 @@
+-module(d).
+
+-export([start/0, stop/0]).
+-export([store/2, store/3, move/2,
+ location/1, who_are_at/1, who_are_older/1,
+ size/0]).
+-export([init/0]). % spawn
+
+-record(person, {name, age, location, moved=false}).
+
+%%%----------------------------------------------------------------------
+%%% User interface functions
+%%%----------------------------------------------------------------------
+
+%%% start() -> pid()
+start() ->
+ spawn(?MODULE, init, []).
+
+%%% stop()
+stop() ->
+ arne ! stop.
+
+%%% store(Name, Location) ->
+%%% store(Name, Age, Location) -> ok | {error,Reason}
+%%% Name = Location = atom()
+%%% Age = integer()
+%%% Reason = not_started | no_response | {internal_error,term()}
+store(Name, Location) ->
+ store(Name, ?AGE, Location).
+store(Name, Age, Location) when atom(Name), integer(Age), atom(Location) ->
+ send({store, Name, Age, Location}).
+
+%%% move(OldLocation, NewLocation) -> Names | {error,Reason}
+%%% OldLocation = NewLocation = atom()
+%%% Names = [Name]
+%%% Name = atom()
+%%% Reason = not_started | no_response | {internal_error,term()}
+move(OldLocation, NewLocation) ->
+ send({move, OldLocation, NewLocation}).
+
+%%% location(Name) -> Location | no_such_person | {error,Reason}
+%%% Name = atom()
+%%% Reason = not_started | no_response | {internal_error,term()}
+location(Name) when atom(Name) ->
+ send({location, Name}).
+
+%%% who_are_at(Location) -> Names | {error,Reason}
+%%% Location = atom()
+%%% Names = [Name]
+%%% Name = atom()
+%%% Reason = not_started | no_response | {internal_error,term()}
+who_are_at(Location) when atom(Location) ->
+ send({who_are_at, Location}).
+
+%%% who_are_older(Age) -> Names | {error,Reason}
+%%% Age = integer()
+%%% Names = [Name]
+%%% Name = atom()
+%%% Reason = not_started | no_response | {internal_error,term()}
+who_are_older(Age) when integer(Age) ->
+ send({who_are_older, Age}).
+
+%%% size() -> N | {error,Reason}
+%%% N = integer()
+%%% Reason = not_started | no_response | {internal_error,term()}
+size() ->
+ send(size).
+
+%%%----------------------------------------------------------------------
+%%% Main loop
+%%%----------------------------------------------------------------------
+send(Request) ->
+ Pid = whereis(arne),
+ if
+ Pid==undefined ->
+ {error, not_started};
+ true ->
+ send(Pid, Request)
+ end.
+send(Pid, Request) ->
+ Pid ! {request, self(), Request},
+ receive
+ {reply, Reply} ->
+ Reply
+ after
+ 1000 ->
+ {error, no_response}
+ end.
+
+init() ->
+ register(arne, self()),
+ loop([]).
+
+loop(Db) ->
+ receive
+ stop ->
+ true;
+ {request, From, Request} ->
+ case catch handle(Request, Db) of
+ {reply, Reply, NewDb} ->
+ From ! {reply, Reply},
+ loop(NewDb);
+ {'EXIT', Reason} ->
+ From ! {reply, {error, {internal_error, Reason}}},
+ loop(Db)
+ end
+ end.
+
+%%%----------------------------------------------------------------------
+%%% DB functionality
+%%%----------------------------------------------------------------------
+handle({store, Name, Age, Location}, Db) ->
+ {reply, ok, [#person{name=Name, age=Age, location=Location} | Db]};
+handle({move, OldLocation, NewLocation}, Db) ->
+ {Names, NewDb} = move(OldLocation, NewLocation, Db, [], []),
+ {reply, Names, NewDb};
+handle({location, Name}, Db) ->
+ case lists:keysearch(Name, #person.name, Db) of
+ {value, #person{location=Location}} when atom(Location) ->
+ {reply, Location, Db};
+ false ->
+ {reply, no_such_name, Db}
+ end;
+handle({who_are_at, Location}, Db) ->
+ Result = lists:foldl(fun(Person, Names) ->
+ case Person#person.location of
+ Location ->
+ [Person#person.name | Names];
+ _OtherLocation ->
+ Names
+ end
+ end,
+ [],
+ Db),
+ {reply, Result, Db};
+handle({who_are_older, Old}, Db) ->
+ Result = [Name || {person,Name,Age,Location} <- Db,
+ Age>Old],
+ {reply, Result, Db};
+handle(size, Db) ->
+ Result = count(Db, 0), {reply, Result, Db}.
+
+count([H|T], N) ->
+ count(T, N+1);
+count([], N) ->
+ N.
+
+move(OldLoc, NewLoc, [#person{location=OldLoc} = Person|T], Db, Names) ->
+ NewPerson = Person#person{location=NewLoc,
+ moved=true},
+ NewNames = [Person#person.name|Names],
+ move(OldLoc, NewLoc, T, [NewPerson|Db], NewNames);
+move(OldLoc, NewLoc, [Person|T], Db, Names) ->
+ move(OldLoc, NewLoc, T, [Person|Db], Names);
+move(OldLoc, NewLoc, [], Db, Names) ->
+ {lists:reverse(Names), lists:reverse(Db)}.
diff --git a/lib/tools/test/cover_SUITE_data/d1/e.erl b/lib/tools/test/cover_SUITE_data/d1/e.erl
new file mode 100644
index 0000000000..b4041d48e6
--- /dev/null
+++ b/lib/tools/test/cover_SUITE_data/d1/e.erl
@@ -0,0 +1,127 @@
+-module(e).
+-behaviour(gen_server).
+
+%% External exports
+-export([start_link/0]).
+-export([hello/0]).
+
+%% gen_server callbacks
+-export([init/1, handle_call/3, handle_cast/2, handle_info/2, terminate/2,
+ code_change/3]).
+
+-record(state, {}).
+
+%%%----------------------------------------------------------------------
+%%% API
+%%%----------------------------------------------------------------------
+start_link() ->
+ gen_server:start_link({local, myserver}, myserver, [], []).
+
+hello() ->
+ gen_server:call(myserver, hello).
+
+%%%----------------------------------------------------------------------
+%%% Callback functions from gen_server
+%%%----------------------------------------------------------------------
+
+%%----------------------------------------------------------------------
+%% Func: init/1
+%% Returns: {ok, State} |
+%% {ok, State, Timeout} |
+%% ignore |
+%% {stop, Reason}
+%%----------------------------------------------------------------------
+init([]) ->
+ {ok, #state{}}.
+
+%%----------------------------------------------------------------------
+%% Func: handle_call/3
+%% Returns: {reply, Reply, State} |
+%% {reply, Reply, State, Timeout} |
+%% {noreply, State} |
+%% {noreply, State, Timeout} |
+%% {stop, Reason, Reply, State} | (terminate/2 is called)
+%% {stop, Reason, State} (terminate/2 is called)
+%%----------------------------------------------------------------------
+handle_call(Request, From, State) ->
+ Reply = case Request of
+ char ->
+ $B;
+ integer ->
+ 17;
+ float ->
+ 32.76;
+ string ->
+ "hi there";
+ atom ->
+ hello;
+ block ->
+ begin
+ a,
+ b
+ end;
+ binary ->
+ <<1, 2, 3>>
+ end,
+ {reply, Reply, State}.
+
+%%----------------------------------------------------------------------
+%% Func: handle_cast/2
+%% Returns: {noreply, State} |
+%% {noreply, State, Timeout} |
+%% {stop, Reason, State} (terminate/2 is called)
+%%----------------------------------------------------------------------
+handle_cast(Msg, State) when atom(Msg) ->
+ {noreply, State};
+handle_cast(Msg, State) when binary(Msg) ->
+ {noreply, State};
+handle_cast(Msg, State) when not is_tuple(Msg), not is_list(Msg) ->
+ {noreply, State};
+handle_cast(Msg, State) when float(Msg) ->
+ {noreply, State};
+handle_cast(Msg, State) when function(Msg) ->
+ {noreply, State};
+handle_cast(Msg, State) when integer(Msg) ->
+ {noreply, State};
+handle_cast(Msg, State) when list(Msg) ->
+ {noreply, State};
+handle_cast(Msg, State) when number(Msg) ->
+ {noreply, State};
+handle_cast(Msg, State) when pid(Msg) ->
+ {noreply, State};
+handle_cast(Msg, State) when port(Msg) ->
+ {noreply, State};
+handle_cast(Msg, State) when reference(Msg) ->
+ {noreply, State};
+handle_cast(Msg, State) when tuple(Msg) ->
+ {noreply, State}.
+
+%%----------------------------------------------------------------------
+%% Func: handle_info/2
+%% Returns: {noreply, State} |
+%% {noreply, State, Timeout} |
+%% {stop, Reason, State} (terminate/2 is called)
+%%----------------------------------------------------------------------
+handle_info(Info, State) ->
+ {noreply, State}.
+
+%%----------------------------------------------------------------------
+%% Func: terminate/2
+%% Purpose: Shutdown the server
+%% Returns: any (ignored by gen_server)
+%%----------------------------------------------------------------------
+terminate(Reason, State) ->
+ ok.
+
+%%----------------------------------------------------------------------
+%% Func: code_change/3
+%% Purpose: Convert process state when code is changed
+%% Returns: {ok, NewState}
+%%----------------------------------------------------------------------
+code_change(OldVsn, State, Extra) ->
+ {ok, State}.
+
+%%%----------------------------------------------------------------------
+%%% Internal functions
+%%%----------------------------------------------------------------------
+
diff --git a/lib/tools/test/cover_SUITE_data/f.erl b/lib/tools/test/cover_SUITE_data/f.erl
new file mode 100644
index 0000000000..1ef8bbdb49
--- /dev/null
+++ b/lib/tools/test/cover_SUITE_data/f.erl
@@ -0,0 +1,10 @@
+-module(f).
+-export([f1/0,f2/0]).
+
+f1() ->
+ f1_line1,
+ f1_line2.
+
+f2() ->
+ f2_line1,
+ f2_line2.
diff --git a/lib/tools/test/cover_SUITE_data/included_functions/cover_inc.erl b/lib/tools/test/cover_SUITE_data/included_functions/cover_inc.erl
new file mode 100644
index 0000000000..fa8eebfd00
--- /dev/null
+++ b/lib/tools/test/cover_SUITE_data/included_functions/cover_inc.erl
@@ -0,0 +1,8 @@
+-module(cover_inc).
+-compile(export_all).
+-include("cover_inc.hrl").
+
+func() ->
+ func1(),
+ ok.
+
diff --git a/lib/tools/test/cover_SUITE_data/included_functions/cover_inc.hrl b/lib/tools/test/cover_SUITE_data/included_functions/cover_inc.hrl
new file mode 100644
index 0000000000..cbdfe601d1
--- /dev/null
+++ b/lib/tools/test/cover_SUITE_data/included_functions/cover_inc.hrl
@@ -0,0 +1,7 @@
+func1() ->
+ A = line_2_in_include_file,
+ erlang:display(A),
+ line_4_in_include_file.
+
+
+
diff --git a/lib/tools/test/cover_SUITE_data/otp_6115/f1.erl b/lib/tools/test/cover_SUITE_data/otp_6115/f1.erl
new file mode 100644
index 0000000000..b659e5d818
--- /dev/null
+++ b/lib/tools/test/cover_SUITE_data/otp_6115/f1.erl
@@ -0,0 +1,12 @@
+-module(f1).
+-export([start_fail/0, start_ok/0]).
+
+start_fail() ->
+ f2:start(fun() ->
+ io:format("this does not work\n",[])
+ end).
+
+start_ok() ->
+ f2:start(fun fun1/0).
+fun1() ->
+ io:format("this works\n",[]).
diff --git a/lib/tools/test/cover_SUITE_data/otp_6115/f2.erl b/lib/tools/test/cover_SUITE_data/otp_6115/f2.erl
new file mode 100644
index 0000000000..72a6a64c4d
--- /dev/null
+++ b/lib/tools/test/cover_SUITE_data/otp_6115/f2.erl
@@ -0,0 +1,13 @@
+-module(f2).
+-export([start/1]).
+
+start(Fun) ->
+ spawn(fun() ->
+ wait(Fun)
+ end).
+
+wait(Fun) ->
+ receive
+ go ->
+ Fun()
+ end.
diff --git a/lib/tools/test/cprof_SUITE.erl b/lib/tools/test/cprof_SUITE.erl
new file mode 100644
index 0000000000..e697cc1571
--- /dev/null
+++ b/lib/tools/test/cprof_SUITE.erl
@@ -0,0 +1,309 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 2002-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%
+%%
+
+%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%%%
+%%% Define to run outside of test server
+%%%
+%%% -define(STANDALONE,1).
+%%%
+%%%
+%%% Define for debug output
+%%%
+%%% -define(debug,1).
+
+-module(cprof_SUITE).
+
+%% Exported end user tests
+-export([basic_test/0, on_load_test/1, modules_test/1]).
+
+%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%% Test server related stuff
+%%
+
+-ifdef(STANDALONE).
+-define(config(A,B),config(A,B)).
+-export([config/2]).
+-else.
+-include("test_server.hrl").
+-endif.
+
+-ifdef(debug).
+-ifdef(STANDALONE).
+-define(line, erlang:display({?MODULE,?LINE}), ).
+-endif.
+-define(dbgformat(A,B),io:format(A,B)).
+-else.
+-ifdef(STANDALONE).
+-define(line, noop, ).
+-endif.
+-define(dbgformat(A,B),noop).
+-endif.
+
+-ifdef(STANDALONE).
+config(priv_dir, _) ->
+ ".";
+config(data_dir, _) ->
+ "cprof_SUITE_data".
+-else.
+%% When run in test server.
+-export([all/1, init_per_testcase/2, fin_per_testcase/2, not_run/1]).
+-export([basic/1, on_load/1, modules/1]).
+
+init_per_testcase(_Case, Config) ->
+ ?line Dog=test_server:timetrap(test_server:seconds(30)),
+ [{watchdog, Dog}|Config].
+
+fin_per_testcase(_Case, Config) ->
+ erlang:trace_pattern({'_','_','_'}, false, [local,meta,call_count]),
+ erlang:trace_pattern(on_load, false, [local,meta,call_count]),
+ erlang:trace(all, false, [all]),
+ Dog=?config(watchdog, Config),
+ test_server:timetrap_cancel(Dog),
+ ok.
+
+all(doc) ->
+ ["Test the cprof profiling tool."];
+all(suite) ->
+ case test_server:is_native(?MODULE) of
+ true -> [not_run];
+ false -> [basic, on_load, modules]
+%, on_and_off, info,
+% pause_and_restart, combo]
+ end.
+
+not_run(Config) when is_list(Config) ->
+ {skipped,"Native code"}.
+
+basic(suite) ->
+ [];
+basic(doc) ->
+ ["Tests basic profiling"];
+basic(Config) when is_list(Config) ->
+ basic_test().
+
+on_load(suite) ->
+ [];
+on_load(doc) ->
+ ["Tests profiling of unloaded module"];
+on_load(Config) when is_list(Config) ->
+ on_load_test(Config).
+
+modules(suite) ->
+ [];
+modules(doc) ->
+ ["Tests profiling of several modules"];
+modules(Config) when is_list(Config) ->
+ modules_test(Config).
+
+-endif. %-ifdef(STANDALONE). ... -else.
+
+%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%%% The Tests
+%%%
+
+basic_test() ->
+ ?line M = 1000,
+ %%
+ ?line M2 = M*2,
+ ?line M3 = M*3,
+ ?line M2__1 = M2 + 1,
+ ?line M3__1 = M3 + 1,
+ ?line N = cprof:stop(),
+ %%
+ ?line 2 = cprof:start(?MODULE, seq_r),
+ ?line 1 = cprof:start(?MODULE, seq, 3),
+ ?line L = seq(1, M, fun succ/1),
+ ?line Lr = seq_r(1, M, fun succ/1),
+ ?line L = lists:reverse(Lr),
+ %%
+ ?line io:format("~p~n~p~n~p~n",
+ [erlang:trace_info({?MODULE,sec_r,3}, all),
+ erlang:trace_info({?MODULE,sec_r,4}, all),
+ erlang:trace_info({?MODULE,sec,3}, all)]),
+ %%
+ ?line ModAna1 = {?MODULE,M2__1,[{{?MODULE,seq_r,4},M},
+ {{?MODULE,seq,3},M},
+ {{?MODULE,seq_r,3},1}]},
+ ?line ModAna1 = cprof:analyse(?MODULE,0),
+ ?line {M2__1, [ModAna1]} = cprof:analyse(),
+ ?line ModAna1 = cprof:analyse(?MODULE, 1),
+ ?line {M2__1, [ModAna1]} = cprof:analyse(1),
+ %%
+ ?line ModAna2 = {?MODULE,M2__1,[{{?MODULE,seq_r,4},M},
+ {{?MODULE,seq,3},M}]},
+ ?line ModAna2 = cprof:analyse(?MODULE, 2),
+ ?line {M2__1, [ModAna2]} = cprof:analyse(2),
+ %%
+ 2 = cprof:pause(?MODULE, seq_r),
+ ?line L = seq(1, M, fun succ/1),
+ ?line Lr = seq_r(1, M, fun succ/1),
+ %%
+ ?line ModAna3 = {?MODULE,M3__1,[{{?MODULE,seq,3},M2},
+ {{?MODULE,seq_r,4},M},
+ {{?MODULE,seq_r,3},1}]},
+ ?line ModAna3 = cprof:analyse(?MODULE),
+ %%
+ ?line N = cprof:pause(),
+ ?line L = seq(1, M, fun succ/1),
+ ?line Lr = seq_r(1, M, fun succ/1),
+ %%
+ ?line {M3__1, [ModAna3]} = cprof:analyse(),
+ %%
+ ?line N = cprof:restart(),
+ ?line L = seq(1, M, fun succ/1),
+ ?line Lr = seq_r(1, M, fun succ/1),
+ %%
+ ?line ModAna1 = cprof:analyse(?MODULE),
+ %%
+ ?line N = cprof:stop(),
+ ?line {?MODULE,0,[]} = cprof:analyse(?MODULE),
+ ?line {0,[]} = cprof:analyse(),
+ ok.
+
+%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+on_load_test(Config) ->
+ ?line Priv = ?config(priv_dir, Config),
+ ?line Data = ?config(data_dir, Config),
+ ?line File = filename:join(Data, "cprof_SUITE_test"),
+ ?line Module = cprof_SUITE_test,
+ ?line M = 1000,
+ %%
+ ?line M2 = M*2,
+ ?line M2__1 = M2 + 1,
+ ?line N1 = cprof:start(),
+
+ ?line {ok,Module} = c:c(File, [{outdir,Priv}]),
+
+ %% If this system is hipe-enabled, the loader may have called module_info/1
+ %% when Module was loaded above. Reset the call count to avoid seeing
+ %% the call in the analysis below.
+
+ ?line 1 = cprof:restart(Module, module_info, 1),
+
+ ?line L = Module:seq(1, M, fun succ/1),
+ ?line Lr = Module:seq_r(1, M, fun succ/1),
+ ?line Lr = lists:reverse(L),
+ ?line N2 = cprof:pause(),
+ ?line N3 = cprof:pause(Module),
+ ?line {Module,M2__1,[{{Module,seq_r,4},M},
+ {{Module,seq,3},M},
+ {{Module,seq_r,3},1}]} = cprof:analyse(Module),
+ ?line io:format("~p ~p ~p~n", [N1, N2, N3]),
+ ?line code:purge(Module),
+ ?line code:delete(Module),
+ ?line N4 = N2 - N3,
+ %%
+ ?line N4 = cprof:restart(),
+ ?line {ok,Module} = c:c(File, [{outdir,Priv}]),
+ ?line L = Module:seq(1, M, fun succ/1),
+ ?line Lr = Module:seq_r(1, M, fun succ/1),
+ ?line L = seq(1, M, fun succ/1),
+ ?line Lr = seq_r(1, M, fun succ/1),
+ ?line N2 = cprof:pause(),
+ ?line {Module,0,[]} = cprof:analyse(Module),
+ ?line M_1 = M - 1,
+ ?line M4__4 = M*4 - 4,
+ ?line M10_7 = M*10 - 7,
+ ?line {?MODULE,M10_7,[{{?MODULE,succ,1},M4__4},
+ {{?MODULE,seq_r,4},M},
+ {{?MODULE,seq,3},M},
+ {{?MODULE,'-on_load_test/1-fun-5-',1},M_1},
+ {{?MODULE,'-on_load_test/1-fun-4-',1},M_1},
+ {{?MODULE,'-on_load_test/1-fun-3-',1},M_1},
+ {{?MODULE,'-on_load_test/1-fun-2-',1},M_1},
+ {{?MODULE,seq_r,3},1}]}
+ = cprof:analyse(?MODULE),
+ ?line N2 = cprof:stop(),
+ ok.
+
+%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+modules_test(Config) ->
+ ?line Priv = ?config(priv_dir, Config),
+ ?line Data = ?config(data_dir, Config),
+ ?line File = filename:join(Data, "cprof_SUITE_test"),
+ ?line Module = cprof_SUITE_test,
+ ?line {ok,Module} = c:c(File, [{outdir,Priv}]),
+ ?line M = 10,
+ %%
+ ?line M2 = M*2,
+ ?line M2__1 = M2 + 1,
+ ?line erlang:yield(),
+ ?line N = cprof:start(),
+ ?line L = Module:seq(1, M, fun succ/1),
+ ?line Lr = Module:seq_r(1, M, fun succ/1),
+ ?line L = seq(1, M, fun succ/1),
+ ?line Lr = seq_r(1, M, fun succ/1),
+ ?line N = cprof:pause(),
+ ?line Lr = lists:reverse(L),
+ ?line M_1 = M - 1,
+ ?line M4_4 = M*4 - 4,
+ ?line M10_7 = M*10 - 7,
+ ?line M2__1 = M*2 + 1,
+ ?line {Tot,ModList} = cprof:analyse(),
+ ?line {value,{?MODULE,M10_7,[{{?MODULE,succ,1},M4_4},
+ {{?MODULE,seq_r,4},M},
+ {{?MODULE,seq,3},M},
+ {{?MODULE,'-modules_test/1-fun-3-',1},M_1},
+ {{?MODULE,'-modules_test/1-fun-2-',1},M_1},
+ {{?MODULE,'-modules_test/1-fun-1-',1},M_1},
+ {{?MODULE,'-modules_test/1-fun-0-',1},M_1},
+ {{?MODULE,seq_r,3},1}]}} =
+ lists:keysearch(?MODULE, 1, ModList),
+ ?line {value,{Module,M2__1,[{{Module,seq_r,4},M},
+ {{Module,seq,3},M},
+ {{Module,seq_r,3},1}]}} =
+ lists:keysearch(Module, 1, ModList),
+ ?line Tot = lists:foldl(fun ({_,C,_}, A) -> C+A end, 0, ModList),
+ ?line {cprof,_,Prof} = cprof:analyse(cprof),
+ ?line {value,{{cprof,pause,0},1}} =
+ lists:keysearch({cprof,pause,0}, 1, Prof),
+ ?line N = cprof:stop(),
+ ok.
+
+
+
+%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%% Local helpers
+
+
+
+%% Stack recursive seq
+seq(Stop, Stop, Succ) when is_function(Succ) ->
+ [Stop];
+seq(Start, Stop, Succ) when is_function(Succ) ->
+ [Start | seq(Succ(Start), Stop, Succ)].
+
+
+
+%% Tail recursive seq, result list is reversed
+seq_r(Start, Stop, Succ) when is_function(Succ) ->
+ seq_r(Start, Stop, Succ, []).
+
+seq_r(Stop, Stop, _, R) ->
+ [Stop | R];
+seq_r(Start, Stop, Succ, R) ->
+ seq_r(Succ(Start), Stop, Succ, [Start | R]).
+
+
+
+%% Successor
+succ(X) -> X+1.
diff --git a/lib/tools/test/cprof_SUITE_data/cprof_SUITE_test.erl b/lib/tools/test/cprof_SUITE_data/cprof_SUITE_test.erl
new file mode 100644
index 0000000000..02d8b027e5
--- /dev/null
+++ b/lib/tools/test/cprof_SUITE_data/cprof_SUITE_test.erl
@@ -0,0 +1,25 @@
+-module(cprof_SUITE_test).
+
+-export([seq/3, seq_r/3]).
+
+
+
+%% Stack recursive seq
+seq(Stop, Stop, Succ) when function(Succ) ->
+ [Stop];
+seq(Start, Stop, Succ) when function(Succ) ->
+ [Start | seq(Succ(Start), Stop, Succ)].
+
+
+
+%% Tail recursive seq, result list is reversed
+seq_r(Start, Stop, Succ) when function(Succ) ->
+ seq_r(Start, Stop, Succ, []).
+
+seq_r(Stop, Stop, _, R) ->
+ [Stop | R];
+seq_r(Start, Stop, Succ, R) ->
+ seq_r(Succ(Start), Stop, Succ, [Start | R]).
+
+
+
diff --git a/lib/tools/test/emem_SUITE.erl b/lib/tools/test/emem_SUITE.erl
new file mode 100644
index 0000000000..430fa86c6c
--- /dev/null
+++ b/lib/tools/test/emem_SUITE.erl
@@ -0,0 +1,713 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 2005-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(emem_SUITE).
+
+%%-define(line_trace, 1).
+
+-export([init_per_suite/1, end_per_suite/1,
+ receive_and_save_trace/2, send_trace/2]).
+
+
+-export([all/1, init_per_testcase/2, fin_per_testcase/2]).
+
+-export([live_node/1,
+ 'sparc_sunos5.8_32b_emt2.0'/1,
+ 'pc_win2000_32b_emt2.0'/1,
+ 'pc.smp_linux2.2.19pre17_32b_emt2.0'/1,
+ 'powerpc_darwin7.7.0_32b_emt2.0'/1,
+ 'alpha_osf1v5.1_64b_emt2.0'/1,
+ 'sparc_sunos5.8_64b_emt2.0'/1,
+ 'sparc_sunos5.8_32b_emt1.0'/1,
+ 'pc_win2000_32b_emt1.0'/1,
+ 'powerpc_darwin7.7.0_32b_emt1.0'/1,
+ 'alpha_osf1v5.1_64b_emt1.0'/1,
+ 'sparc_sunos5.8_64b_emt1.0'/1]).
+
+-include_lib("kernel/include/file.hrl").
+
+-include("test_server.hrl").
+
+-define(DEFAULT_TIMEOUT, ?t:minutes(5)).
+
+-define(EMEM_64_32_COMMENT,
+ "64 bit trace; this build of emem can only handle 32 bit traces").
+
+-record(emem_res, {nodename,
+ hostname,
+ pid,
+ start_time,
+ trace_version,
+ max_word_size,
+ word_size,
+ last_values,
+ maximum,
+ exit_code}).
+
+%%
+%%
+%% Exported suite functions
+%%
+%%
+
+all(doc) -> [];
+all(suite) ->
+ case is_debug_compiled() of
+ true -> {skipped, "Not run when debug compiled"};
+ false -> test_cases()
+ end.
+
+test_cases() ->
+ [live_node,
+ 'sparc_sunos5.8_32b_emt2.0',
+ 'pc_win2000_32b_emt2.0',
+ 'pc.smp_linux2.2.19pre17_32b_emt2.0',
+ 'powerpc_darwin7.7.0_32b_emt2.0',
+ 'alpha_osf1v5.1_64b_emt2.0',
+ 'sparc_sunos5.8_64b_emt2.0',
+ 'sparc_sunos5.8_32b_emt1.0',
+ 'pc_win2000_32b_emt1.0',
+ 'powerpc_darwin7.7.0_32b_emt1.0',
+ 'alpha_osf1v5.1_64b_emt1.0',
+ 'sparc_sunos5.8_64b_emt1.0'].
+
+init_per_testcase(Case, Config) when is_list(Config) ->
+ case maybe_skip(Config) of
+ {skip, _}=Skip -> Skip;
+ ok ->
+ Dog = ?t:timetrap(?DEFAULT_TIMEOUT),
+
+ %% Until emem is completely stable we run these tests in a working
+ %% directory with an ignore_core_files file which will make the
+ %% search for core files ignore cores generated by this suite.
+ ignore_cores:setup(?MODULE,
+ Case,
+ [{watchdog, Dog}, {testcase, Case} | Config])
+ end.
+
+fin_per_testcase(_Case, Config) when is_list(Config) ->
+ ignore_cores:restore(Config),
+ Dog = ?config(watchdog, Config),
+ ?t:timetrap_cancel(Dog),
+ ok.
+
+maybe_skip(Config) ->
+ DataDir = ?config(data_dir, Config),
+ case filelib:is_dir(DataDir) of
+ false ->
+ {skip, "No data directory"};
+ true ->
+ case ?config(emem, Config) of
+ undefined ->
+ {skip, "emem not found"};
+ _ ->
+ ok
+ end
+ end.
+
+init_per_suite(Config) when is_list(Config) ->
+ BinDir = filename:join([code:lib_dir(tools), "bin"]),
+ Target = erlang:system_info(system_architecture),
+ Res = (catch begin
+ case check_dir(filename:join([BinDir, Target])) of
+ not_found -> ok;
+ TDir ->
+ check_emem(TDir, purecov),
+ check_emem(TDir, purify),
+ check_emem(TDir, debug),
+ check_emem(TDir, opt)
+ end,
+ check_emem(BinDir, opt),
+ ""
+ end),
+ Res ++ ignore_cores:init(Config).
+
+end_per_suite(Config) when is_list(Config) ->
+ Config1 = lists:keydelete(emem, 1, Config),
+ Config2 = lists:keydelete(emem_comment, 1, Config1),
+ ignore_cores:fini(Config2).
+
+%%
+%%
+%% Test cases
+%%
+%%
+
+live_node(doc) -> [];
+live_node(suite) -> [];
+live_node(Config) when is_list(Config) ->
+ ?line {ok, EmuFlag, Port} = start_emem(Config),
+ ?line Nodename = mk_nodename(Config),
+ ?line {ok, Node} = start_node(Nodename, EmuFlag),
+ ?line NP = spawn(Node,
+ fun () ->
+ receive go -> ok end,
+ I = spawn(fun () -> ignorer end),
+ GC = fun () ->
+ GCP = fun (P) ->
+ garbage_collect(P)
+ end,
+ lists:foreach(GCP, processes())
+ end,
+ Seq = fun () -> I ! lists:seq(1, 1000000) end,
+ spawn_link(Seq),
+ B1 = <<0:10000000>>,
+ spawn_link(Seq),
+ B2 = <<0:10000000>>,
+ spawn_link(Seq),
+ B3 = <<0:10000000>>,
+ I ! {B1, B2, B3},
+ GC(),
+ GC(),
+ GC()
+ end),
+ ?line MRef = erlang:monitor(process, NP),
+ NP ! go,
+ ?line receive
+ {'DOWN', MRef, process, NP, Reason} ->
+ ?line spawn(Node, fun () -> halt(17) end),
+ ?line normal = Reason
+ end,
+ ?line Res = get_emem_result(Port),
+ ?line {ok, Hostname} = inet:gethostname(),
+ ?line ShortHostname = short_hostname(Hostname),
+ ?line {true, _} = has_prefix(Nodename, Res#emem_res.nodename),
+ ?line ShortHostname = short_hostname(Res#emem_res.hostname),
+ ?line Bits = case erlang:system_info(wordsize) of
+ 4 -> ?line "32 bits";
+ 8 -> ?line "64 bits"
+ end,
+ ?line Bits = Res#emem_res.word_size,
+ ?line "17" = Res#emem_res.exit_code,
+ ?line emem_comment(Config).
+
+'sparc_sunos5.8_32b_emt2.0'(doc) -> [];
+'sparc_sunos5.8_32b_emt2.0'(suite) -> [];
+'sparc_sunos5.8_32b_emt2.0'(Config) when is_list(Config) ->
+ ?line Res = run_emem_on_casefile(Config),
+ ?line "test_server" = Res#emem_res.nodename,
+ ?line "gorbag" = Res#emem_res.hostname,
+ ?line "17074" = Res#emem_res.pid,
+ ?line "2005-01-14 17:28:37.881980" = Res#emem_res.start_time,
+ ?line "2.0" = Res#emem_res.trace_version,
+ ?line "32 bits" = Res#emem_res.word_size,
+ ?line ["15",
+ "2665739", "8992", "548986", "16131", "539994",
+ "4334192", "1", "99", "15", "98",
+ "0", "0", "49", "0", "49"] = Res#emem_res.last_values,
+ ?line ["5972061", "9662",
+ "7987824", "5",
+ "2375680", "3"] = Res#emem_res.maximum,
+ ?line "0" = Res#emem_res.exit_code,
+ ?line emem_comment(Config).
+
+'pc_win2000_32b_emt2.0'(doc) -> [];
+'pc_win2000_32b_emt2.0'(suite) -> [];
+'pc_win2000_32b_emt2.0'(Config) when is_list(Config) ->
+ ?line Res = run_emem_on_casefile(Config),
+ ?line "test_server" = Res#emem_res.nodename,
+ ?line "E-788FCF5191B54" = Res#emem_res.hostname,
+ ?line "504" = Res#emem_res.pid,
+ ?line "2005-01-24 17:27:28.224000" = Res#emem_res.start_time,
+ ?line "2.0" = Res#emem_res.trace_version,
+ ?line "32 bits" = Res#emem_res.word_size,
+ ?line ["11",
+ "2932575", "8615", "641087", "68924", "632472"]
+ = Res#emem_res.last_values,
+ ?line ["5434206", "9285"] = Res#emem_res.maximum,
+ ?line "0" = Res#emem_res.exit_code,
+ ?line emem_comment(Config).
+
+'pc.smp_linux2.2.19pre17_32b_emt2.0'(doc) -> [];
+'pc.smp_linux2.2.19pre17_32b_emt2.0'(suite) -> [];
+'pc.smp_linux2.2.19pre17_32b_emt2.0'(Config) when is_list(Config) ->
+ ?line Res = run_emem_on_casefile(Config),
+ ?line "test_server" = Res#emem_res.nodename,
+ ?line "four-roses" = Res#emem_res.hostname,
+ ?line "20689" = Res#emem_res.pid,
+ ?line "2005-01-20 13:11:26.143077" = Res#emem_res.start_time,
+ ?line "2.0" = Res#emem_res.trace_version,
+ ?line "32 bits" = Res#emem_res.word_size,
+ ?line ["49",
+ "2901817", "9011", "521610", "10875", "512599",
+ "5392096", "2", "120", "10", "118",
+ "0", "0", "59", "0", "59"] = Res#emem_res.last_values,
+ ?line ["6182918", "9681",
+ "9062112", "6",
+ "2322432", "3"] = Res#emem_res.maximum,
+ ?line "0" = Res#emem_res.exit_code,
+ ?line emem_comment(Config).
+
+
+'powerpc_darwin7.7.0_32b_emt2.0'(doc) -> [];
+'powerpc_darwin7.7.0_32b_emt2.0'(suite) -> [];
+'powerpc_darwin7.7.0_32b_emt2.0'(Config) when is_list(Config) ->
+ ?line Res = run_emem_on_casefile(Config),
+ ?line "test_server" = Res#emem_res.nodename,
+ ?line "grima" = Res#emem_res.hostname,
+ ?line "13021" = Res#emem_res.pid,
+ ?line "2005-01-20 15:08:17.568668" = Res#emem_res.start_time,
+ ?line "2.0" = Res#emem_res.trace_version,
+ ?line "32 bits" = Res#emem_res.word_size,
+ ?line ["9",
+ "2784323", "8641", "531105", "15893", "522464"]
+ = Res#emem_res.last_values,
+ ?line ["6150376", "9311"] = Res#emem_res.maximum,
+ ?line "0" = Res#emem_res.exit_code,
+ ?line emem_comment(Config).
+
+'alpha_osf1v5.1_64b_emt2.0'(doc) -> [];
+'alpha_osf1v5.1_64b_emt2.0'(suite) -> [];
+'alpha_osf1v5.1_64b_emt2.0'(Config) when is_list(Config) ->
+ ?line Res = run_emem_on_casefile(Config),
+ ?line "test_server" = Res#emem_res.nodename,
+ ?line "thorin" = Res#emem_res.hostname,
+ ?line "224630" = Res#emem_res.pid,
+ ?line "2005-01-20 22:38:01.299632" = Res#emem_res.start_time,
+ ?line "2.0" = Res#emem_res.trace_version,
+ ?line "64 bits" = Res#emem_res.word_size,
+ ?line case Res#emem_res.max_word_size of
+ "32 bits" ->
+ ?line emem_comment(Config, ?EMEM_64_32_COMMENT);
+ "64 bits" ->
+ ?line ["22",
+ "6591992", "8625", "516785", "14805", "508160",
+ "11429184", "5", "127", "254", "122",
+ "0", "0", "61", "0", "61"] = Res#emem_res.last_values,
+ ?line ["7041775", "9295",
+ "11593024", "7",
+ "2097152", "3"] = Res#emem_res.maximum,
+ ?line "0" = Res#emem_res.exit_code,
+ ?line emem_comment(Config)
+ end.
+
+'sparc_sunos5.8_64b_emt2.0'(doc) -> [];
+'sparc_sunos5.8_64b_emt2.0'(suite) -> [];
+'sparc_sunos5.8_64b_emt2.0'(Config) when is_list(Config) ->
+ ?line Res = run_emem_on_casefile(Config),
+ ?line "test_server" = Res#emem_res.nodename,
+ ?line "gorbag" = Res#emem_res.hostname,
+ ?line "10907" = Res#emem_res.pid,
+ ?line "2005-01-20 13:48:34.677068" = Res#emem_res.start_time,
+ ?line "2.0" = Res#emem_res.trace_version,
+ ?line "64 bits" = Res#emem_res.word_size,
+ ?line case Res#emem_res.max_word_size of
+ "32 bits" ->
+ ?line emem_comment(Config, ?EMEM_64_32_COMMENT);
+ "64 bits" ->
+ ?line ["16",
+ "5032887", "8657", "530635", "14316", "521978",
+ "8627140", "5", "139", "19", "134",
+ "0", "0", "67", "0", "67"] = Res#emem_res.last_values,
+ ?line ["11695070", "9324",
+ "16360388", "10",
+ "4136960", "3"] = Res#emem_res.maximum,
+ ?line "0" = Res#emem_res.exit_code,
+ ?line emem_comment(Config)
+ end.
+
+'sparc_sunos5.8_32b_emt1.0'(doc) -> [];
+'sparc_sunos5.8_32b_emt1.0'(suite) -> [];
+'sparc_sunos5.8_32b_emt1.0'(Config) when is_list(Config) ->
+ ?line Res = run_emem_on_casefile(Config),
+ ?line "" = Res#emem_res.nodename,
+ ?line "" = Res#emem_res.hostname,
+ ?line "" = Res#emem_res.pid,
+ ?line "" = Res#emem_res.start_time,
+ ?line "1.0" = Res#emem_res.trace_version,
+ ?line "32 bits" = Res#emem_res.word_size,
+ ?line ["11",
+ "2558261", "8643", "560610", "15325", "551967"]
+ = Res#emem_res.last_values,
+ ?line ["2791121", "9317"] = Res#emem_res.maximum,
+ ?line "0" = Res#emem_res.exit_code,
+ ?line emem_comment(Config).
+
+'pc_win2000_32b_emt1.0'(doc) -> [];
+'pc_win2000_32b_emt1.0'(suite) -> [];
+'pc_win2000_32b_emt1.0'(Config) when is_list(Config) ->
+ ?line Res = run_emem_on_casefile(Config),
+ ?line "" = Res#emem_res.nodename,
+ ?line "" = Res#emem_res.hostname,
+ ?line "" = Res#emem_res.pid,
+ ?line "" = Res#emem_res.start_time,
+ ?line "1.0" = Res#emem_res.trace_version,
+ ?line "32 bits" = Res#emem_res.word_size,
+ ?line ["6",
+ "2965248", "8614", "640897", "68903", "632283"]
+ = Res#emem_res.last_values,
+ ?line ["3147090", "9283"] = Res#emem_res.maximum,
+ ?line "0" = Res#emem_res.exit_code,
+ ?line emem_comment(Config).
+
+
+'powerpc_darwin7.7.0_32b_emt1.0'(doc) -> [];
+'powerpc_darwin7.7.0_32b_emt1.0'(suite) -> [];
+'powerpc_darwin7.7.0_32b_emt1.0'(Config) when is_list(Config) ->
+ ?line Res = run_emem_on_casefile(Config),
+ ?line "" = Res#emem_res.nodename,
+ ?line "" = Res#emem_res.hostname,
+ ?line "" = Res#emem_res.pid,
+ ?line "" = Res#emem_res.start_time,
+ ?line "1.0" = Res#emem_res.trace_version,
+ ?line "32 bits" = Res#emem_res.word_size,
+ ?line ["8",
+ "2852991", "8608", "529662", "15875", "521054"]
+ = Res#emem_res.last_values,
+ ?line ["3173335", "9278"] = Res#emem_res.maximum,
+ ?line "0" = Res#emem_res.exit_code,
+ ?line emem_comment(Config).
+
+'alpha_osf1v5.1_64b_emt1.0'(doc) -> [];
+'alpha_osf1v5.1_64b_emt1.0'(suite) -> [];
+'alpha_osf1v5.1_64b_emt1.0'(Config) when is_list(Config) ->
+ ?line Res = run_emem_on_casefile(Config),
+ ?line "" = Res#emem_res.nodename,
+ ?line "" = Res#emem_res.hostname,
+ ?line "" = Res#emem_res.pid,
+ ?line "" = Res#emem_res.start_time,
+ ?line "1.0" = Res#emem_res.trace_version,
+ ?line "64 bits" = Res#emem_res.word_size,
+ ?line case Res#emem_res.max_word_size of
+ "32 bits" ->
+ ?line emem_comment(Config, ?EMEM_64_32_COMMENT);
+ "64 bits" ->
+ ?line ["22",
+ "6820094", "8612", "515518", "14812", "506906"]
+ = Res#emem_res.last_values,
+ ?line ["7292413", "9282"] = Res#emem_res.maximum,
+ ?line "0" = Res#emem_res.exit_code,
+ ?line emem_comment(Config)
+ end.
+
+'sparc_sunos5.8_64b_emt1.0'(doc) -> [];
+'sparc_sunos5.8_64b_emt1.0'(suite) -> [];
+'sparc_sunos5.8_64b_emt1.0'(Config) when is_list(Config) ->
+ ?line Res = run_emem_on_casefile(Config),
+ ?line "" = Res#emem_res.nodename,
+ ?line "" = Res#emem_res.hostname,
+ ?line "" = Res#emem_res.pid,
+ ?line "" = Res#emem_res.start_time,
+ ?line "1.0" = Res#emem_res.trace_version,
+ ?line "64 bits" = Res#emem_res.word_size,
+ ?line case Res#emem_res.max_word_size of
+ "32 bits" ->
+ ?line emem_comment(Config, ?EMEM_64_32_COMMENT);
+ "64 bits" ->
+ ?line ["15",
+ "4965746", "8234", "543940", "14443", "535706"]
+ = Res#emem_res.last_values,
+ ?line ["11697645", "8908"] = Res#emem_res.maximum,
+ ?line "0" = Res#emem_res.exit_code,
+ ?line emem_comment(Config)
+ end.
+
+%%
+%%
+%% Auxiliary functions
+%%
+%%
+
+receive_and_save_trace(PortNumber, FileName) when is_integer(PortNumber),
+ is_list(FileName) ->
+ {ok, F} = file:open(FileName, [write, compressed]),
+ {ok, LS} = gen_tcp:listen(PortNumber, [inet, {reuseaddr,true}, binary]),
+ {ok, S} = gen_tcp:accept(LS),
+ gen_tcp:close(LS),
+ receive_loop(S,F).
+
+receive_loop(Socket, File) ->
+ receive
+ {tcp, Socket, Data} ->
+ ok = file:write(File, Data),
+ receive_loop(Socket, File);
+ {tcp_closed, Socket} ->
+ file:close(File),
+ ok;
+ {tcp_error, Socket, Reason} ->
+ file:close(File),
+ {error, Reason}
+ end.
+
+send_trace({Host, PortNumber}, FileName) when is_list(Host),
+ is_integer(PortNumber),
+ is_list(FileName) ->
+ ?line {ok, F} = file:open(FileName, [read, compressed]),
+ ?line {ok, S} = gen_tcp:connect(Host, PortNumber, [inet,{packet, 0}]),
+ ?line send_loop(S, F);
+send_trace(EmuFlag, FileName) when is_list(EmuFlag),
+ is_list(FileName) ->
+ ?line ["+Mit", IpAddrStr, PortNoStr] = string:tokens(EmuFlag, " :"),
+ ?line send_trace({IpAddrStr, list_to_integer(PortNoStr)}, FileName).
+
+send_loop(Socket, File) ->
+ ?line case file:read(File, 128) of
+ {ok, Data} ->
+ ?line case gen_tcp:send(Socket, Data) of
+ ok -> ?line send_loop(Socket, File);
+ Error ->
+ ?line gen_tcp:close(Socket),
+ ?line file:close(File),
+ Error
+ end;
+ eof ->
+ ?line gen_tcp:close(Socket),
+ ?line file:close(File),
+ ?line ok;
+ Error ->
+ ?line gen_tcp:close(Socket),
+ ?line file:close(File),
+ ?line Error
+ end.
+
+check_emem(Dir, Type) when is_atom(Type) ->
+ ExeSuffix = case ?t:os_type() of
+ {win32, _} -> ".exe";
+ _ -> ""
+ end,
+ TypeSuffix = case Type of
+ opt -> "";
+ _ -> "." ++ atom_to_list(Type)
+ end,
+ Emem = "emem" ++ TypeSuffix ++ ExeSuffix,
+ case check_file(filename:join([Dir, Emem])) of
+ not_found -> ok;
+ File ->
+ Comment = case Type of
+ opt -> "";
+ _ -> "[emem " ++ atom_to_list(Type) ++ " compiled]"
+ end,
+ throw([{emem, File}, {emem_comment, Comment}])
+ end.
+
+check_dir(DirName) ->
+ case file:read_file_info(DirName) of
+ {ok, #file_info {type = directory, access = A}} when A == read;
+ A == read_write ->
+ DirName;
+ _ ->
+ not_found
+ end.
+
+check_file(FileName) ->
+ case file:read_file_info(FileName) of
+ {ok, #file_info {type = regular, access = A}} when A == read;
+ A == read_write ->
+ ?line FileName;
+ _ ->
+ ?line not_found
+ end.
+
+emem_comment(Config) when is_list(Config) ->
+ emem_comment(Config, "").
+
+emem_comment(Config, ExtraComment)
+ when is_list(Config), is_list(ExtraComment) ->
+ case {?config(emem_comment, Config), ExtraComment} of
+ {"", ""} -> ?line ok;
+ {"", XC} -> ?line {comment, XC};
+ {EmemC, ""} -> ?line {comment, EmemC};
+ {EmemC, XC} -> ?line {comment, EmemC ++ " " ++ XC}
+ end.
+
+run_emem_on_casefile(Config) ->
+ CaseName = atom_to_list(?config(testcase, Config)),
+ ?line File = filename:join([?config(data_dir, Config), CaseName ++ ".gz"]),
+ ?line case check_file(File) of
+ not_found ->
+ ?line ?t:fail({error, {filenotfound, File}});
+ _ ->
+ ?line ok
+ end,
+ ?line {ok, EmuFlag, Port} = start_emem(Config),
+ ?line Parent = self(),
+ ?line Ref = make_ref(),
+ ?line spawn_link(fun () ->
+ SRes = send_trace(EmuFlag, File),
+ Parent ! {Ref, SRes}
+ end),
+ ?line Res = get_emem_result(Port),
+ ?line receive
+ {Ref, ok} ->
+ ?line ok;
+ {Ref, SendError} ->
+ ?line ?t:format("Send result: ~p~n", [SendError])
+ end,
+ ?line Res.
+
+get_emem_result(Port) ->
+ ?line {Res, LV} = get_emem_result(Port, {#emem_res{}, []}),
+ ?line Res#emem_res{last_values = string:tokens(LV, " ")}.
+
+get_emem_result(Port, {_EmemRes, _LastValues} = Res) ->
+ ?line case get_emem_line(Port) of
+ eof ->
+ ?line Res;
+ Line ->
+ ?line get_emem_result(Port, parse_emem_line(Line, Res))
+ end.
+
+parse_emem_main_header_footer_line(Line, {ER, LV} = Res) ->
+
+ %% Header
+ ?line case has_prefix("> Nodename:", Line) of
+ {true, NN} ->
+ ?line throw({ER#emem_res{nodename = strip(NN)}, LV});
+ false -> ?line ok
+ end,
+ ?line case has_prefix("> Hostname:", Line) of
+ {true, HN} ->
+ ?line throw({ER#emem_res{hostname = strip(HN)}, LV});
+ false -> ?line ok
+ end,
+ ?line case has_prefix("> Pid:", Line) of
+ {true, P} ->
+ ?line throw({ER#emem_res{pid = strip(P)}, LV});
+ false -> ?line ok
+ end,
+ ?line case has_prefix("> Start time (UTC):", Line) of
+ {true, ST} ->
+ ?line throw({ER#emem_res{start_time = strip(ST)}, LV});
+ false -> ?line ok
+ end,
+ ?line case has_prefix("> Actual trace version:", Line) of
+ {true, TV} ->
+ ?line throw({ER#emem_res{trace_version = strip(TV)}, LV});
+ false -> ?line ok
+ end,
+ ?line case has_prefix("> Maximum trace word size:", Line) of
+ {true, MWS} ->
+ ?line throw({ER#emem_res{max_word_size = strip(MWS)}, LV});
+ false -> ?line ok
+ end,
+ ?line case has_prefix("> Actual trace word size:", Line) of
+ {true, WS} ->
+ ?line throw({ER#emem_res{word_size = strip(WS)}, LV});
+ false -> ?line ok
+ end,
+
+ %% Footer
+ ?line case has_prefix("> Maximum:", Line) of
+ {true, M} ->
+ ?line throw({ER#emem_res{maximum = string:tokens(M," ")}, LV});
+ false -> ?line ok
+ end,
+ ?line case has_prefix("> Emulator exited with code:", Line) of
+ {true, EC} ->
+ ?line throw({ER#emem_res{exit_code = strip(EC)}, LV});
+ false -> ?line ok
+ end,
+ ?line Res.
+
+parse_emem_header_line(_Line, {_ER, _LV} = Res) ->
+ ?line Res.
+
+parse_emem_value_line(Line, {EmemRes, _OldLastValues}) ->
+ ?line {EmemRes, Line}.
+
+parse_emem_line("", Res) ->
+ ?line Res;
+parse_emem_line(Line, Res) ->
+ ?line [Prefix | _] = Line,
+ case Prefix of
+ $> -> ?line catch parse_emem_main_header_footer_line(Line, Res);
+ $| -> ?line catch parse_emem_header_line(Line, Res);
+ _ -> ?line catch parse_emem_value_line(Line, Res)
+ end.
+
+start_emem(Config) when is_list(Config) ->
+ ?line Emem = ?config(emem, Config),
+ ?line Cd = case ignore_cores:dir(Config) of
+ false -> [];
+ Dir -> [{cd, Dir}]
+ end,
+ ?line case open_port({spawn, Emem ++ " -t -n -o -i 1"},
+ Cd ++ [{line, 1024}, eof]) of
+ Port when is_port(Port) -> ?line {ok, read_emu_flag(Port), Port};
+ Error -> ?line ?t:fail(Error)
+ end.
+
+read_emu_flag(Port) ->
+ ?line Line = case get_emem_line(Port) of
+ eof -> ?line ?t:fail(unexpected_end_of_file);
+ L -> ?line L
+ end,
+ ?line case has_prefix("> Emulator command line argument:", Line) of
+ {true, EmuFlag} -> EmuFlag;
+ false -> ?line read_emu_flag(Port)
+ end.
+
+get_emem_line(Port, Acc) ->
+ ?line receive
+ {Port, {data, {eol, Data}}} ->
+ ?line Res = case Acc of
+ [] -> ?line Data;
+ _ -> ?line lists:flatten([Acc|Data])
+ end,
+ ?line ?t:format("~s", [Res]),
+ ?line Res;
+ {Port, {data, {noeol, Data}}} ->
+ ?line get_emem_line(Port, [Acc|Data]);
+ {Port, eof} ->
+ ?line port_close(Port),
+ ?line eof
+ end.
+
+get_emem_line(Port) ->
+ ?line get_emem_line(Port, []).
+
+short_hostname([]) ->
+ [];
+short_hostname([$.|_]) ->
+ [];
+short_hostname([C|Cs]) ->
+ [C | short_hostname(Cs)].
+
+has_prefix([], List) when is_list(List) ->
+ {true, List};
+has_prefix([P|Xs], [P|Ys]) ->
+ has_prefix(Xs, Ys);
+has_prefix(_, _) ->
+ false.
+
+strip(Str) -> string:strip(Str).
+
+mk_nodename(Config) ->
+ {A, B, C} = now(),
+ atom_to_list(?MODULE)
+ ++ "-" ++ atom_to_list(?config(testcase, Config))
+ ++ "-" ++ integer_to_list(A*1000000000000 + B*1000000 + C).
+
+start_node(Name, Args) ->
+ ?line Pa = filename:dirname(code:which(?MODULE)),
+ ?line ?t:start_node(Name, peer, [{args, Args ++ " -pa " ++ Pa}]).
+
+% stop_node(Node) ->
+% ?t:stop_node(Node).
+
+is_debug_compiled() ->
+ is_debug_compiled(erlang:system_info(system_version)).
+
+is_debug_compiled([$d,$e,$b,$u,$g | _]) ->
+ true;
+is_debug_compiled([ _, _, _, _]) ->
+ false;
+is_debug_compiled([]) ->
+ false;
+is_debug_compiled([_|Rest]) ->
+ is_debug_compiled(Rest).
diff --git a/lib/tools/test/eprof_SUITE.erl b/lib/tools/test/eprof_SUITE.erl
new file mode 100644
index 0000000000..028fea8fe1
--- /dev/null
+++ b/lib/tools/test/eprof_SUITE.erl
@@ -0,0 +1,97 @@
+%%
+%% %CopyrightBegin%
+%%
+%% 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
+%% 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(eprof_SUITE).
+
+-include("test_server.hrl").
+
+-export([all/1,tiny/1,eed/1]).
+
+all(suite) -> [tiny,eed].
+
+
+tiny(suite) -> [];
+tiny(Config) when is_list(Config) ->
+ ?line ensure_eprof_stopped(),
+ ?line {ok, OldCurDir} = file:get_cwd(),
+ Datadir = ?config(data_dir, Config),
+ Privdir = ?config(priv_dir, Config),
+ ?line TTrap=?t:timetrap(60*1000),
+ % (Trace)Compile to priv_dir and make sure the correct version is loaded.
+ ?line {ok,eprof_suite_test} = compile:file(filename:join(Datadir,
+ "eprof_suite_test"),
+ [trace,{outdir, Privdir}]),
+ ?line ok = file:set_cwd(Privdir),
+ ?line code:purge(eprof_suite_test),
+ ?line {module,eprof_suite_test} = code:load_file(eprof_suite_test),
+ ?line {ok,_Pid} = eprof:start(),
+ ?line nothing_to_analyse = eprof:analyse(),
+ ?line nothing_to_analyse = eprof:total_analyse(),
+ ?line eprof:profile([], eprof_suite_test, test, [Config]),
+ ?line ok = eprof:analyse(),
+ ?line ok = eprof:total_analyse(),
+ ?line ok = eprof:log("eprof_SUITE_logfile"),
+ ?line stopped = eprof:stop(),
+ ?line ?t:timetrap_cancel(TTrap),
+ ?line ok = file:set_cwd(OldCurDir),
+ ok.
+
+eed(suite) -> [];
+eed(Config) when is_list(Config) ->
+ ?line ensure_eprof_stopped(),
+ ?line Datadir = ?config(data_dir, Config),
+ ?line Privdir = ?config(priv_dir, Config),
+ ?line TTrap=?t:timetrap(5*60*1000),
+
+ %% (Trace)Compile to priv_dir and make sure the correct version is loaded.
+ ?line code:purge(eed),
+ ?line {ok,eed} = c:c(filename:join(Datadir, "eed"), [trace,{outdir,Privdir}]),
+ ?line {ok,_Pid} = eprof:start(),
+ ?line Script = filename:join(Datadir, "ed.script"),
+ ?line ok = file:set_cwd(Datadir),
+ ?line {T1,_} = statistics(runtime),
+ ?line ok = eed:file(Script),
+ ?line ok = eed:file(Script),
+ ?line ok = eed:file(Script),
+ ?line ok = eed:file(Script),
+ ?line ok = eed:file(Script),
+ ?line ok = eed:file(Script),
+ ?line ok = eed:file(Script),
+ ?line ok = eed:file(Script),
+ ?line ok = eed:file(Script),
+ ?line ok = eed:file(Script),
+ ?line {T2,_} = statistics(runtime),
+ ?line {ok,ok} = eprof:profile([], eed, file, [Script]),
+ ?line {T3,_} = statistics(runtime),
+ ?line profiling_already_stopped = eprof:stop_profiling(),
+ ?line ok = eprof:analyse(),
+ ?line ok = eprof:total_analyse(),
+ ?line ok = eprof:log("eprof_SUITE_logfile"),
+ ?line stopped = eprof:stop(),
+ ?line ?t:timetrap_cancel(TTrap),
+ S = lists:flatten(io_lib:format("~p times slower", [10*(T3-T2)/(T2-T1)])),
+ {comment,S}.
+
+ensure_eprof_stopped() ->
+ Pid = whereis(eprof),
+ case whereis(eprof) of
+ undefined ->
+ ok;
+ Pid ->
+ ?line stopped=eprof:stop()
+ end.
diff --git a/lib/tools/test/eprof_SUITE_data/ed.script b/lib/tools/test/eprof_SUITE_data/ed.script
new file mode 100644
index 0000000000..94531a9e98
--- /dev/null
+++ b/lib/tools/test/eprof_SUITE_data/ed.script
@@ -0,0 +1,8 @@
+H
+r eed.erl
+g/^[a-z][a-zA-Z_]*\(/i\
+%%% -------------------------------------------------------------\
+%%% A stupid function header.\
+%%% -------------------------------------------------------------
+1,$p
+q
diff --git a/lib/tools/test/eprof_SUITE_data/eed.erl b/lib/tools/test/eprof_SUITE_data/eed.erl
new file mode 100644
index 0000000000..0175abdd0e
--- /dev/null
+++ b/lib/tools/test/eprof_SUITE_data/eed.erl
@@ -0,0 +1,815 @@
+%%%----------------------------------------------------------------------
+%%% File : eed.erl
+%%% Author : Bjorn Gustavsson <bjorn@strider>
+%%% Purpose : Unix `ed' look-alike.
+%%% Created : 24 Aug 1997 by Bjorn Gustavsson <bjorn@strider>
+%%%----------------------------------------------------------------------
+
+-module(eed).
+-author('bjorn@strider').
+
+-export([edit/0, edit/1, file/1, cmd_line/1]).
+
+-record(state, {dot = 0, % Line number of dot.
+ upto_dot = [], % Lines up to dot (reversed).
+ after_dot = [], % Lines after dot.
+ lines = 0, % Total number of lines.
+ print=false, % Print after command.
+ filename=[], % Current file.
+ pattern, % Current pattern.
+ in_global=false, % True if executing global command.
+ input=[], % Global input stream.
+ undo, % Last undo state.
+ marks=[], % List of marks.
+ modified=false, % Buffer is modified.
+ opts=[{prompt, ''}], % Options.
+ last_error, % The last error encountered.
+ input_fd % Input file descriptor.
+ }).
+
+-record(line, {contents, % Contents of line.
+ mark=false % Marked (for global prefix).
+ }).
+
+cmd_line([Script]) ->
+ file(Script),
+ halt().
+
+file(Script) ->
+ case file:open(Script, [read]) of
+ {ok,Fd} ->
+ loop(#state{input_fd=Fd}),
+ ok;
+ {error,E} ->
+ {error,E}
+ end.
+
+edit() ->
+ loop(#state{input_fd=group_leader()}).
+
+edit(Name) ->
+ loop(command([$e|Name], #state{input_fd=group_leader()})).
+
+loop(St0) ->
+ {ok, St1, Cmd} = get_line(St0),
+ case catch command(lib:nonl(Cmd), St1) of
+ {'EXIT', Reason} ->
+ %% XXX Should clear outstanding global command here.
+ loop(print_error({'EXIT', Reason}, St1));
+ quit ->
+ ok;
+ {error, Reason} ->
+ loop(print_error(Reason, St1));
+ St2 when record(St2, state) ->
+ loop(St2)
+ end.
+
+command(Cmd, St) ->
+ case parse_command(Cmd, St) of
+ quit ->
+ quit;
+ St1 when function(St1#state.print) ->
+ if
+ St1#state.dot /= 0 ->
+ print_current(St1);
+ true ->
+ ok
+ end,
+ St1#state{print=false};
+ St1 when record(St1, state) ->
+ St1
+ end.
+
+get_line(St) ->
+ Opts = St#state.opts,
+ {value, {prompt, Prompt}} = lists:keysearch(prompt, 1, Opts),
+ get_line(Prompt, St).
+
+get_line(Prompt, St) when St#state.input == [] ->
+ Line = get_line1(St#state.input_fd, Prompt, []),
+ {ok, St, Line};
+get_line(_, St) ->
+ get_input(St#state.input, St, []).
+
+get_input([eof], St, []) ->
+ {ok, St, eof};
+get_input([eof], St, Result) ->
+ {ok, St#state{input=[eof]}, lists:reverse(Result)};
+get_input([$\n|Rest], St, Result) ->
+ {ok, St#state{input=Rest}, lists:reverse(Result)};
+get_input([C|Rest], St, Result) ->
+ get_input(Rest, St, [C|Result]).
+
+get_line1(Io, Prompt, Result) ->
+ get_line2(Io, io:get_line(Io, Prompt), Result).
+
+get_line2(Io, eof, []) ->
+ eof;
+get_line2(Io, eof, Result) ->
+ lists:reverse(Result);
+get_line2(Io, [$\\, $\n], Result) ->
+ get_line1(Io, '', [$\n|Result]);
+get_line2(Io, [$\n], Result) ->
+ lists:reverse(Result, [$\n]);
+get_line2(Io, [C|Rest], Result) ->
+ get_line2(Io, Rest, [C|Result]).
+
+print_error(Reason, St0) ->
+ St1 = St0#state{last_error=Reason},
+ io:put_chars("?\n"),
+ case lists:member(help_always, St1#state.opts) of
+ true ->
+ help_command([], [], St1),
+ St1;
+ false ->
+ St1
+ end.
+
+format_error(bad_command) -> "unknown command";
+format_error(bad_filename) -> "illegal or missing filename";
+format_error(bad_file) -> "cannot open input file";
+format_error(bad_linenum) -> "line out of range";
+format_error(bad_delimiter) -> "illegal or missing delimiter";
+format_error(bad_undo) -> "nothing to undo";
+format_error(bad_mark) -> "mark not lower case ascii";
+format_error(bad_pattern) -> "invalid regular expression";
+format_error(buffer_modified) -> "warning: expecting `w'";
+format_error(nested_globals) -> "multiple globals not allowed";
+format_error(nomatch) -> "search string not found";
+format_error(missing_space) -> "no space after command";
+format_error(garbage_after_command) -> "illegal suffix";
+format_error(not_implemented) -> "not implemented yet";
+format_error({'EXIT', {Code, {Mod, Func, Args}}}) ->
+ lists:flatten(io_lib:format("aborted due to bug (~p)",
+ [{Code, {Mod, Func, length(Args)}}]));
+format_error(A) -> atom_to_list(A).
+
+
+
+%%% Parsing commands.
+
+parse_command(Cmd, St) ->
+ parse_command(Cmd, St, []).
+
+parse_command(Cmd, State, Nums) ->
+ case get_one(Cmd, State) of
+ {ok, Num, Rest, NewState} ->
+ parse_next_address(Rest, NewState, [Num|Nums]);
+ false ->
+ parse_command1(Cmd, State, Nums)
+ end.
+
+parse_next_address([$,|Rest], State, Nums) ->
+ parse_command(Rest, State, Nums);
+parse_next_address([$;|Rest], State, [Num|Nums]) ->
+ parse_command(Rest, move_to(Num, State), [Num|Nums]);
+parse_next_address(Rest, State, Nums) ->
+ parse_command1(Rest, State, Nums).
+
+parse_command1([Letter|Rest], State, Nums) ->
+ Cont = fun(Fun, NumLines, Def) ->
+ execute_command(Fun, NumLines, Def, State, Nums, Rest) end,
+ parse_cmd_char(Letter, Cont);
+parse_command1([], State, Nums) ->
+ execute_command(fun print_command/3, 1, next, State, Nums, []).
+
+get_one(Cmd, St) ->
+ case get_address(Cmd, St) of
+ {ok, Addr, Cmd1, St1} ->
+ get_one1(Cmd1, Addr, St1);
+ false ->
+ get_one1(Cmd, false, St)
+ end.
+
+get_one1([D|Rest], false, St) when $0 =< D, D =< $9 ->
+ get_one2(get_number([D|Rest]), 1, 0, St);
+get_one1([D|Rest], Sum, St) when $0 =< D, D =< $9 ->
+ get_one2(get_number([D|Rest]), 1, Sum, St);
+get_one1([$+, D|Rest], Sum, St) when $0 =< D, D =< $9 ->
+ get_one2(get_number([D|Rest]), 1, Sum, St);
+get_one1([$-, D|Rest], Sum, St) when $0 =< D, D =< $9 ->
+ get_one2(get_number([D|Rest]), -1, Sum, St);
+get_one1([$+|Rest], Sum, St) ->
+ get_one2({ok, 1, Rest}, 1, Sum, St);
+get_one1([$-|Rest], Sum, St) ->
+ get_one2({ok, 1, Rest}, -1, Sum, St);
+get_one1(Cmd, false, St) ->
+ false;
+get_one1(Cmd, Sum, St) ->
+ {ok, Sum, Cmd, St}.
+
+get_one2({ok, Number, Rest}, Mul, false, St) ->
+ get_one1(Rest, St#state.dot+Mul*Number, St);
+get_one2({ok, Number, Rest}, Mul, Sum, St) ->
+ get_one1(Rest, Sum+Mul*Number, St).
+
+get_number(Cmd) ->
+ get_number(Cmd, 0).
+
+get_number([D|Rest], Result) when $0 =< D, D =< $9 ->
+ get_number(Rest, Result*10+D-$0);
+get_number(Rest, Result) ->
+ {ok, Result, Rest}.
+
+get_address([$.|Rest], State) ->
+ {ok, State#state.dot, Rest, State};
+get_address([$$|Rest], State) ->
+ {ok, State#state.lines, Rest, State};
+get_address([$', Mark|Rest], St) when $a =< Mark, Mark =< $z ->
+ case lists:keysearch(Mark, 2, St#state.marks) of
+ {value, {Line, Mark}} ->
+ {ok, Line, Rest, St};
+ false ->
+ {ok, 0, Rest, St}
+ end;
+get_address([$'|Rest], State) ->
+ error(bad_mark);
+get_address([$/|Rest], State) ->
+ scan_forward($/, Rest, State);
+get_address([$?|Rest], State) ->
+ error(not_implemented);
+get_address(Cmd, St) ->
+ false.
+
+scan_forward(End, Patt0, State) ->
+ {ok, Rest, NewState} = get_pattern(End, Patt0, State),
+ Dot = NewState#state.dot,
+ After = NewState#state.after_dot,
+ scan_forward1(Dot+1, After, NewState, Rest).
+
+scan_forward1(Linenum, [Line|Rest], State, RestCmd) ->
+ case regexp:first_match(Line#line.contents, State#state.pattern) of
+ {match, _, _} ->
+ {ok, Linenum, RestCmd, State};
+ nomatch ->
+ scan_forward1(Linenum+1, Rest, State, RestCmd)
+ end;
+scan_forward1(_, [], State, RestCmd) ->
+ Dot = State#state.dot,
+ Upto = State#state.upto_dot,
+ case scan_forward2(Dot, Upto, State, RestCmd) of
+ false ->
+ error(bad_linenum);
+ Other ->
+ Other
+ end.
+
+scan_forward2(0, [], State, RestCmd) ->
+ false;
+scan_forward2(Linenum, [Line|Rest], State, RestCmd) ->
+ case scan_forward2(Linenum-1, Rest, State, RestCmd) of
+ false ->
+ case regexp:first_match(Line#line.contents, State#state.pattern) of
+ {match, _, _} ->
+ {ok, Linenum, RestCmd, State};
+ nomatch ->
+ false
+ end;
+ Other ->
+ Other
+ end.
+
+parse_cmd_char($S, Cont) -> Cont(fun quest_command/3, 0, none);
+parse_cmd_char($T, Cont) -> Cont(fun time_command/3, 0, none);
+parse_cmd_char($=, Cont) -> Cont(fun print_linenum/3, 1, last);
+parse_cmd_char($a, Cont) -> Cont(fun append_command/3, 1, dot);
+parse_cmd_char($c, Cont) -> Cont(fun change_command/3, 2, dot);
+parse_cmd_char($d, Cont) -> Cont(fun delete_command/3, 2, dot);
+parse_cmd_char($e, Cont) -> Cont(fun enter_command/3, 0, none);
+parse_cmd_char($E, Cont) -> Cont(fun enter_always_command/3, 0, none);
+parse_cmd_char($f, Cont) -> Cont(fun file_command/3, 0, none);
+parse_cmd_char($g, Cont) -> Cont(fun global_command/3, 2, all);
+parse_cmd_char($h, Cont) -> Cont(fun help_command/3, 0, none);
+parse_cmd_char($H, Cont) -> Cont(fun help_always_command/3, 0, none);
+parse_cmd_char($i, Cont) -> Cont(fun insert_command/3, 1, dot);
+parse_cmd_char($k, Cont) -> Cont(fun mark_command/3, 1, dot);
+parse_cmd_char($l, Cont) -> Cont(fun list_command/3, 2, dot);
+parse_cmd_char($m, Cont) -> Cont(fun move_command/3, 2, dot);
+parse_cmd_char($n, Cont) -> Cont(fun number_command/3, 2, dot);
+parse_cmd_char($p, Cont) -> Cont(fun print_command/3, 2, dot);
+parse_cmd_char($P, Cont) -> Cont(fun prompt_command/3, 0, none);
+parse_cmd_char($q, Cont) -> Cont(fun quit_command/3, 0, none);
+parse_cmd_char($Q, Cont) -> Cont(fun quit_always_command/3, 0, none);
+parse_cmd_char($r, Cont) -> Cont(fun read_command/3, 1, last);
+parse_cmd_char($s, Cont) -> Cont(fun subst_command/3, 2, dot);
+parse_cmd_char($t, Cont) -> Cont(fun transpose_command/3, 2, dot);
+parse_cmd_char($u, Cont) -> Cont(fun undo_command/3, 0, none);
+parse_cmd_char($v, Cont) -> Cont(fun vglobal_command/3, 2, all);
+parse_cmd_char($w, Cont) -> Cont(fun write_command/3, 2, all);
+parse_cmd_char(_, Cont) -> error(bad_command).
+
+execute_command(Fun, NumLines, Def, State, Nums, Rest) ->
+ Lines = check_lines(NumLines, Def, Nums, State),
+ Fun(Rest, Lines, State).
+
+check_lines(0, _, [], _State) ->
+ [];
+check_lines(1, dot, [], #state{dot=Dot}) ->
+ [Dot];
+check_lines(1, next, [], State) when State#state.dot < State#state.lines ->
+ [State#state.dot+1];
+check_lines(1, last, [], State) ->
+ [State#state.lines];
+check_lines(1, _, [Num|_], State) when 0 =< Num, Num =< State#state.lines ->
+ [Num];
+check_lines(2, dot, [], #state{dot=Dot}) ->
+ [Dot, Dot];
+check_lines(2, all, [], #state{lines=Lines}) ->
+ [1, Lines];
+check_lines(2, _, [Num], State) when 0 =< Num, Num =< State#state.lines ->
+ [Num, Num];
+check_lines(2, _, [Num2, Num1|_], State)
+when 0 =< Num1, Num1 =< Num2, Num2 =< State#state.lines ->
+ [Num1, Num2];
+check_lines(_, _, _, _) ->
+ error(bad_linenum).
+
+
+%%% Executing commands.
+
+%% ($)= - print line number
+
+print_linenum(Rest, [Line], State) ->
+ NewState = check_trailing_p(Rest, State),
+ io:format("~w\n", [Line]),
+ NewState.
+
+%% ? - print state (for debugging)
+
+quest_command([], [], State) ->
+ io:format("~p\n", [State]),
+ State.
+
+%% Tcmd - time command
+
+time_command(Cmd, [], St) ->
+ Fun = fun parse_command/2,
+ erlang:garbage_collect(),
+ {Elapsed, Val} = timer:tc(erlang, apply, [Fun, [Cmd, St]]),
+ io:format("Time used: ~p s~n", [Elapsed/1000000.0]),
+ case Val of
+ {error, Reason} ->
+ throw({error, Reason});
+ Other ->
+ Other
+ end.
+
+%% (.)a - append text
+
+append_command(Rest, [Line], St0) ->
+ St1 = save_for_undo(St0),
+ append(move_to(Line, check_trailing_p(Rest, St1))).
+
+append(St0) ->
+ {ok, St1, Line0} = get_line('', St0),
+ case Line0 of
+ eof ->
+ St1;
+ ".\n" ->
+ St1;
+ Line ->
+ append(insert_line(Line, St1))
+ end.
+
+%% (.,.)c
+
+change_command(Rest, Lines, St0) ->
+ St1 = delete_command(Rest, Lines, St0),
+ St2 = append_command([], [St1#state.dot-1], St1),
+ save_for_undo(St2, St0).
+
+%% (.,.)d - delete lines
+
+delete_command(Rest, [0, Last], St) ->
+ error(bad_linenum);
+delete_command(Rest, [First, Last], St0) ->
+ St1 = check_trailing_p(Rest, save_for_undo(St0)),
+ delete(Last-First+1, move_to(Last, St1)).
+
+delete(0, St) when St#state.dot == St#state.lines ->
+ St;
+delete(0, St) ->
+ next_line(St);
+delete(Left, St0) ->
+ St1 = delete_current_line(St0),
+ delete(Left-1, St1).
+
+%% e file - replace buffer with new file
+
+enter_command(Name, [], St) when St#state.modified == true ->
+ error(buffer_modified);
+enter_command(Name, [], St0) ->
+ enter_always_command(Name, [], St0).
+
+%% E file - replace buffer with new file
+
+enter_always_command(Name, [], St0) ->
+ St1 = read_command(Name, [0], #state{filename=St0#state.filename,
+ opts=St0#state.opts}),
+ St1#state{modified=false}.
+
+%% f file - print filename; set filename
+
+file_command([], [], St) ->
+ io:format("~s~n", [St#state.filename]),
+ St;
+file_command([$_|Name0], [], St) ->
+ Name = skip_blanks(Name0),
+ file_command([], [], St#state{filename=Name});
+file_command(_, _, _) ->
+ error(missing_space).
+
+%% (1,$)g/RE/commands - execute commands on all matching lines.
+%% (1,$)v/RE/commands - execute commands on all non-matching lines.
+
+global_command(Cmd, Lines, St) ->
+ check_global0(true, Cmd, Lines, St).
+
+vglobal_command(Cmd, Lines, St) ->
+ check_global0(false, Cmd, Lines, St).
+
+check_global0(_, _, _, St) when St#state.in_global == true ->
+ error(nested_globals);
+check_global0(Sense, [Sep|Pattern], Lines, St0) ->
+ {ok, Cmd, St1} = get_pattern(Sep, Pattern, St0),
+ St2 = mark(Sense, Lines, St1),
+ do_global_command(Cmd, St2#state{in_global=true}, 0).
+
+mark(Sense, [First, Last], St0) ->
+ St1 = move_to(Last, St0),
+ mark1(Sense, First-1, St1).
+
+mark1(Sense, First, St) when St#state.dot == First ->
+ St;
+mark1(Sense, First, St) ->
+ [Line|Prev] = St#state.upto_dot,
+ NewLine = case match(St) of
+ true -> Line#line{mark=Sense};
+ false -> Line#line{mark=not(Sense)}
+ end,
+ mark1(Sense, First, prev_line(St#state{upto_dot=[NewLine|Prev]})).
+
+do_global_command(Cmd, St0, Matches) ->
+ case find_mark(St0) of
+ {ok, St1} ->
+ St2 = St1#state{input=Cmd++[eof]},
+ {ok, St3, Cmd1} = get_line(St2),
+ St4 = command(Cmd1, St3),
+ %% XXX There might be several commands.
+ do_global_command(Cmd, St4, Matches+1);
+ false when Matches == 0 ->
+ error(nomatch);
+ false ->
+ St0#state{in_global=false, input=[]}
+ end.
+
+find_mark(State) ->
+ find_mark(State#state.lines, State).
+
+find_mark(0, _State) ->
+ false;
+find_mark(Limit, State) when State#state.dot == 0 ->
+ find_mark(Limit, next_line(State));
+find_mark(Limit, State) ->
+ case State#state.upto_dot of
+ [Line|Prev] when Line#line.mark == true ->
+ NewLine = Line#line{mark=false},
+ {ok, State#state{upto_dot=[NewLine|Prev]}};
+ _Other ->
+ find_mark(Limit-1, wrap_next_line(State))
+ end.
+
+%% h - print info about last error
+
+help_command([], [], St) ->
+ case St#state.last_error of
+ undefined ->
+ St;
+ Reason ->
+ io:put_chars(format_error(Reason)),
+ io:nl(),
+ St
+ end;
+help_command(_, _, _) ->
+ error(garbage_after_command).
+
+%% H - toggle automatic help mode on/off
+
+help_always_command([], [], St) ->
+ Opts = St#state.opts,
+ case lists:member(help_always, Opts) of
+ true ->
+ St#state{opts=Opts--[help_always]};
+ false ->
+ help_command([], [], St),
+ St#state{opts=[help_always|Opts]}
+ end.
+
+%% (.)i - insert text
+
+insert_command(Rest, [0], State) ->
+ error(bad_linenum);
+insert_command(Rest, [Line], State) ->
+ append_command(Rest, [Line-1], State).
+
+%% (.)kx - mark line
+
+mark_command(_, [0], St) ->
+ error(bad_linenum);
+mark_command([Mark|Rest], [Line], St) when $a =< Mark, Mark =< $z ->
+ error(not_implemented);
+mark_command(_, _, _) ->
+ error(bad_mark).
+
+%% (.,.)l - list lines
+
+list_command(Rest, Lines, St) ->
+ print([$l|Rest], Lines, St).
+
+%% (.,.)m - move lines
+
+move_command(Cmd, [First, Last], St) ->
+ error(not_implemented).
+
+%% (.,.)t - copy lines
+
+transpose_command(Cmd, [First, Last], St) ->
+ error(not_implemented).
+
+%% (.,.)n - print lines with line numbers
+
+number_command(Rest, Lines, St) ->
+ print([$n|Rest], Lines, St).
+
+%% (.,.)p - print lines
+
+print_command(Rest, Lines, St) ->
+ print([$p|Rest], Lines, St).
+
+%% P - toggle prompt
+
+prompt_command([], [], St) ->
+ Opts = St#state.opts,
+ case lists:keysearch(prompt, 1, Opts) of
+ {value, {prompt, ''}} ->
+ St#state{opts=[{prompt, '*'}|Opts]};
+ {value, Value} ->
+ St#state{opts=[{prompt, ''} | Opts--[Value]]}
+ end;
+prompt_command(_, _, _) ->
+ error(garbage_after_command).
+
+%% q - quit editor
+
+quit_command([], [], _) ->
+ quit;
+quit_command(_, _, _) ->
+ error(garbage_after_command).
+
+%% Q - quit editor
+
+quit_always_command([], [], _) ->
+ quit;
+quit_always_command(_, _, _) ->
+ error(garbage_after_command).
+
+%% ($)r file - read file
+
+read_command([], _, St) when St#state.filename == [] ->
+ error(bad_filename);
+read_command([], [After], St) ->
+ read(After, St#state.filename, St);
+read_command([$ |Name0], [After], St) when St#state.filename == [] ->
+ Name = skip_blanks(Name0),
+ read(After, Name, St#state{filename=Name});
+read_command([$ |Name0], [After], St) ->
+ Name = skip_blanks(Name0),
+ read(After, Name, St);
+read_command(_, _, _) ->
+ error(missing_space).
+
+read(After, Name, St0) ->
+ case file:read_file(Name) of
+ {ok, Bin} ->
+ Chars = size(Bin),
+ St1 = move_to(After, St0),
+ St2 = insert_line(binary_to_list(Bin), St1),
+ io:format("~w~n", [Chars]),
+ St2;
+ {error, _} ->
+ error(bad_file)
+ end.
+
+%% s/pattern/replacement/gp
+
+subst_command(_, [0, _], _) ->
+ error(bad_linenum);
+subst_command([$ |Cmd0], [First, Last], St0) ->
+ error(bad_delimiter);
+subst_command([$\n|Cmd0], [First, Last], St0) ->
+ error(bad_delimiter);
+subst_command([Sep|Cmd0], [First, Last], St0) ->
+ St1 = save_for_undo(St0),
+ {ok, Cmd1, St2} = get_pattern(Sep, Cmd0, St1),
+ {ok, Replacement, Cmd2} = get_replacement(Sep, Cmd1),
+ {ok, Sub, Cmd3} = subst_check_gflag(Cmd2),
+ St3 = check_trailing_p(Cmd3, St2),
+ subst_command(Last-First+1, Sub, Replacement, move_to(First-1, St3), nomatch);
+subst_command([], _, _) ->
+ error(bad_delimiter).
+
+subst_command(0, _, _, _, nomatch) ->
+ error(nomatch);
+subst_command(0, _, _, _, StLast) when record(StLast, state) ->
+ StLast;
+subst_command(Left, Sub, Repl, St0, LastMatch) ->
+ St1 = next_line(St0),
+ [Line|_] = St1#state.upto_dot,
+ case regexp:Sub(Line#line.contents, St1#state.pattern, Repl) of
+ {ok, _, 0} ->
+ subst_command(Left-1, Sub, Repl, St1, LastMatch);
+ {ok, NewContents, _} ->
+ %% XXX This doesn't work with marks.
+ St2 = delete_current_line(St1),
+ St3 = insert_line(NewContents, St2),
+ subst_command(Left-1, Sub, Repl, St3, St3)
+ end.
+
+subst_check_gflag([$g|Cmd]) -> {ok, gsub, Cmd};
+subst_check_gflag(Cmd) -> {ok, sub, Cmd}.
+
+%% u - undo
+
+undo_command([], [], St) when St#state.undo == undefined ->
+ error(bad_undo);
+undo_command([], [], #state{undo=Undo}) ->
+ Undo;
+undo_command(_, _, _) ->
+ error(garbage_after_command).
+
+%% (1,$)w - write buffer to file
+
+write_command(Cmd, [First, Last], St) ->
+ error(not_implemented).
+
+
+%%% Primitive buffer operations.
+
+print_current(St) ->
+ [Line|_] = St#state.upto_dot,
+ Printer = St#state.print,
+ Printer(Line#line.contents, St).
+
+delete_current_line(St) when St#state.dot == 0 ->
+ error(bad_linenum);
+delete_current_line(St) ->
+ Lines = St#state.lines,
+ [_|Prev] = St#state.upto_dot,
+ St#state{dot=St#state.dot-1, upto_dot=Prev, lines=Lines-1, modified=true}.
+
+insert_line(Line, State) ->
+ insert_line1(Line, State, []).
+
+insert_line1([$\n|Rest], State, Result) ->
+ NewState = insert_single_line(lists:reverse(Result, [$\n]), State),
+ insert_line1(Rest, NewState, []);
+insert_line1([C|Rest], State, Result) ->
+ insert_line1(Rest, State, [C|Result]);
+insert_line1([], State, []) ->
+ State;
+insert_line1([], State, Result) ->
+ insert_single_line(lists:reverse(Result, [$\n]), State).
+
+insert_single_line(Line0, State) ->
+ Line = #line{contents=Line0},
+ Dot = State#state.dot,
+ Before = State#state.upto_dot,
+ Lines = State#state.lines,
+ %% XXX Avoid updating the record every time.
+ State#state{dot=Dot+1, upto_dot=[Line|Before], lines=Lines+1, modified=true}.
+
+move_to(Line, State) when Line < State#state.dot ->
+ move_to(Line, prev_line(State));
+move_to(Line, State) when State#state.dot < Line ->
+ move_to(Line, next_line(State));
+move_to(Line, State) when Line == State#state.dot ->
+ State.
+
+prev_line(State) ->
+ Dot = State#state.dot,
+ Before = State#state.upto_dot,
+ After = State#state.after_dot,
+ State#state{dot=Dot-1, upto_dot=tl(Before), after_dot=[hd(Before)|After]}.
+
+next_line(State) ->
+ Dot = State#state.dot,
+ Before = State#state.upto_dot,
+ After = State#state.after_dot,
+ State#state{dot=Dot+1, upto_dot=[hd(After)|Before], after_dot=tl(After)}.
+
+wrap_next_line(State) when State#state.dot == State#state.lines ->
+ move_to(1, State);
+wrap_next_line(State) ->
+ next_line(State).
+
+
+%%% Utilities.
+
+get_pattern(End, Cmd, State) ->
+ get_pattern(End, Cmd, State, []).
+
+get_pattern(End, [End|Rest], State, []) when State#state.pattern /= undefined ->
+ {ok, Rest, State};
+get_pattern(End, [End|Rest], State, Result) ->
+ case regexp:parse(lists:reverse(Result)) of
+ {error, _} ->
+ error(bad_pattern);
+ {ok, Re} ->
+ {ok, Rest, State#state{pattern=Re}}
+ end;
+get_pattern(End, [C|Rest], State, Result) ->
+ get_pattern(End, Rest, State, [C|Result]);
+get_pattern(End, [], State, Result) ->
+ get_pattern(End, [End], State, Result).
+
+get_replacement(End, Cmd) ->
+ get_replacement(End, Cmd, []).
+
+get_replacement(End, [End|Rest], Result) ->
+ {ok, lists:reverse(Result), Rest};
+get_replacement(End, [$\\, $&|Rest], Result) ->
+ get_replacement(End, Rest, [$&, $\\|Result]);
+get_replacement(End, [$\\, C|Rest], Result) ->
+ get_replacement(End, Rest, [C|Result]);
+get_replacement(End, [C|Rest], Result) ->
+ get_replacement(End, Rest, [C|Result]);
+get_replacement(End, [], Result) ->
+ get_replacement(End, [End], Result).
+
+check_trailing_p([$l], St) ->
+ St#state{print=fun(Line, _) -> lister(Line, 0) end};
+check_trailing_p([$n], St) ->
+ St#state{print=fun numberer/2};
+check_trailing_p([$p], St) ->
+ St#state{print=fun(Line, _) -> io:put_chars(Line) end};
+check_trailing_p([], State) ->
+ State;
+check_trailing_p(Other, State) ->
+ error(garbage_after_command).
+
+error(Reason) ->
+ throw({error, Reason}).
+
+match(State) when State#state.dot == 0 ->
+ false;
+match(State) ->
+ [Line|_] = State#state.upto_dot,
+ Re = State#state.pattern,
+ case regexp:first_match(Line#line.contents, Re) of
+ {match, _, _} -> true;
+ nomatch -> false
+ end.
+
+skip_blanks([$ |Rest]) ->
+ skip_blanks(Rest);
+skip_blanks(Rest) ->
+ Rest.
+
+print(Rest, [Line], St0) when Line > 0 ->
+ St1 = check_trailing_p(Rest, St0),
+ print(Line, move_to(Line-1, St1));
+print(Rest, [First, Last], St0) when First > 0 ->
+ St1 = check_trailing_p(Rest, St0),
+ print(Last, move_to(First-1, St1)).
+
+print(Last, St) when St#state.dot == Last ->
+ St#state{print=false};
+print(Last, St0) ->
+ St1 = next_line(St0),
+ print_current(St1),
+ print(Last, St1).
+
+lister(Rest, 64) ->
+ io:put_chars("\\\n"),
+ lister(Rest, 0);
+lister([C|Rest], Num) ->
+ list_char(C),
+ lister(Rest, Num+1);
+lister([], _) ->
+ ok.
+
+list_char($\t) ->
+ io:put_chars("\\t");
+list_char($\n) ->
+ io:put_chars("$\n");
+list_char(C) ->
+ io:put_chars([C]).
+
+numberer(Line, St) ->
+ io:format("~w\t~s", [St#state.dot, Line]).
+
+save_for_undo(St) ->
+ St#state{undo=St#state{undo=undefined, print=false}}.
+
+save_for_undo(St, OldSt) ->
+ St#state{undo=OldSt#state{undo=undefined, print=false}}.
diff --git a/lib/tools/test/eprof_SUITE_data/eprof_suite_test.erl b/lib/tools/test/eprof_SUITE_data/eprof_suite_test.erl
new file mode 100644
index 0000000000..a88b6e21f2
--- /dev/null
+++ b/lib/tools/test/eprof_SUITE_data/eprof_suite_test.erl
@@ -0,0 +1,74 @@
+%% ``The contents of this file are subject to the Erlang Public License,
+%% Version 1.1, (the "License"); you may not use this file except in
+%% compliance with the License. You should have received a copy of the
+%% Erlang Public License along with this software. If not, it can be
+%% retrieved via the world wide web at http://www.erlang.org/.
+%%
+%% Software distributed under the License is distributed on an "AS IS"
+%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+%% the License for the specific language governing rights and limitations
+%% under the License.
+%%
+%% The Initial Developer of the Original Code is Ericsson Utvecklings AB.
+%% Portions created by Ericsson are Copyright 1999, Ericsson Utvecklings
+%% AB. All Rights Reserved.''
+%%
+%% $Id$
+%%
+%%%----------------------------------------------------------------------
+%%% Purpose : A priority queue.
+%%%----------------------------------------------------------------------
+%%% This module implements a priority queue as defined in
+%%% "Priority Queues and the STL" by Mark Nelson in Dr.Dobb's Journal, Jan 1996
+%%% see http://web2.airmail.net/markn/articles/pq_stl/priority.htm for more
+%%% information. (A heap implementation is planned aswell)
+%%%----------------------------------------------------------------------
+%%% The items of the queue is kept priority sorted, and because of that,
+%%% a push() operation costs more than a pop() operation (wich only
+%%% needs to return the top item of the queue(read: list)).
+%%%----------------------------------------------------------------------
+%%% The priority queue can be deceptively nice to use when creating for
+%%% example a Huffman coding tree.
+%%% See http://web2.airmail.net/markn/articles/pq_stl/priority.htm or
+%%% Dr.Dobb's Journal Jan, 96 for more information on this.
+%%%----------------------------------------------------------------------
+
+-module(eprof_suite_test).
+-export([test/1]).
+-export([new/0, push/3, pop/1]).
+
+test(Config) ->
+ Q1=new(),
+ Q2=push(Q1, "monkey", 3),
+ Q3=push(Q2, "banana", 4),
+ Q4=push(Q3, "jungle", 2),
+ Q5=push(Q4, "world", 5),
+ Q6=push(Q5, "universe",6),
+ Q7=push(Q6, "peanut", 1),
+% io:format("~p~n",[Q7]),
+ {Itm, Q8}=pop(Q7),
+ ok.
+
+%% Returns a new priority queue.
+new() ->
+ [].
+
+%% Pushes a new item with a set priority into the queue.
+push(Queue, Itm, Pri) ->
+ insert(Queue, Itm, Pri, []).
+
+%% Pops the item with the highest priority out of the queue.
+pop([{Itm, Pri}|Queue]) ->
+ {Itm, Queue}.
+
+%% --- -- -
+%% Support functions.
+insert([], Itm, Pri, NewQ) ->
+ lists:flatten([lists:reverse(NewQ)|[{Itm, Pri}]]);
+% Itm>QItm>NewQ>Queue
+insert([{QItm,QPri}|Queue], Itm, Pri, NewQ) when Pri>QPri->
+ A = [{Itm, Pri}|[{QItm, QPri}]],
+ lists:flatten([[A|NewQ]|Queue]);
+insert([QItm|Rest], Itm, Pri, NewQ) ->
+ insert(Rest, Itm, Pri, [QItm|NewQ]).
+%% --- -- -
diff --git a/lib/tools/test/fprof_SUITE.erl b/lib/tools/test/fprof_SUITE.erl
new file mode 100644
index 0000000000..e437007e76
--- /dev/null
+++ b/lib/tools/test/fprof_SUITE.erl
@@ -0,0 +1,1191 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 2001-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(fprof_SUITE).
+
+-include("test_server.hrl").
+
+%% Test server framework exports
+-export([all/1, not_run/1]).
+
+%% Test suites
+-export([stack_seq/1, tail_seq/1, create_file_slow/1, spawn_simple/1,
+ imm_tail_seq/1, imm_create_file_slow/1, imm_compile/1,
+ cpu_create_file_slow/1]).
+
+%% Other exports
+-export([create_file_slow/2]).
+
+
+%% Debug exports
+-export([parse/1, verify/2]).
+-export([spawn_simple_test/3]).
+
+
+-define(line_trace,true).
+
+%-define(debug,true).
+-ifdef(debug).
+-define(dbg(Str,Args), io:format(Str,Args)).
+-else.
+-define(dbg(Str,Args), ok).
+-endif.
+
+
+
+%%%---------------------------------------------------------------------
+%%% Test suites
+%%%---------------------------------------------------------------------
+
+
+
+all(doc) ->
+ ["Test the 'fprof' profiling tool."];
+all(suite) ->
+ case test_server:is_native(?MODULE) of
+ true ->
+ [not_run];
+ false ->
+ [stack_seq, tail_seq, create_file_slow, spawn_simple,
+ imm_tail_seq, imm_create_file_slow, imm_compile,
+ cpu_create_file_slow]
+ end.
+
+not_run(Config) when is_list(Config) ->
+ {skipped, "Native code"}.
+
+%%%---------------------------------------------------------------------
+
+stack_seq(doc) ->
+ ["Tests a stack recursive variant of lists:seq/3"];
+stack_seq(suite) ->
+ [];
+stack_seq(Config) when is_list(Config) ->
+ ?line Timetrap = ?t:timetrap(?t:seconds(20)),
+ ?line PrivDir = ?config(priv_dir, Config),
+ ?line TraceFile =
+ filename:join(PrivDir, ?MODULE_STRING"_stack_seq.trace"),
+ ?line AnalysisFile =
+ filename:join(PrivDir, ?MODULE_STRING"_stack_seq.analysis"),
+ ?line Start = 1,
+ ?line Stop = 1000,
+ ?line Succ = fun (X) -> X + 1 end,
+ ?line ok = fprof:stop(kill),
+ %%
+ ?line TS0 = erlang:now(),
+ ?line R0 = fprof:apply(fun seq/3, [Start, Stop, Succ], [{file, TraceFile}]),
+ ?line TS1 = erlang:now(),
+ ?line R = seq(Start, Stop, Succ),
+ ?line TS2 = erlang:now(),
+ ?line ok = fprof:profile(file, TraceFile),
+ ?line ok = fprof:analyse(),
+ ?line ok = fprof:analyse(dest, AnalysisFile),
+ ?line ok = fprof:stop(),
+ ?line R = R0,
+ %%
+ ?line {ok, [T, P]} = parse(AnalysisFile),
+ ?line io:format("~p~n~n~p~n", [P, ets:tab2list(T)]),
+ ?line ok = (catch verify(T, P)),
+ ?line Proc = pid_to_list(self()),
+ ?line case P of
+ [{analysis_options, _},
+ [{totals, _, Acc, _}],
+ [{Proc, _, undefined, _} | _]] ->
+ ok
+ end,
+ %%
+ ?line check_own_and_acc(TraceFile,AnalysisFile),
+ %%
+ ?line ets:delete(T),
+ ?line file:delete(TraceFile),
+ ?line file:delete(AnalysisFile),
+ ?line ?t:timetrap_cancel(Timetrap),
+ ?line Acc1 = ts_sub(TS1, TS0),
+ ?line Acc2 = ts_sub(TS2, TS1),
+ ?line io:format("ts:~w, fprof:~w, bare:~w.~n", [Acc, Acc1, Acc2]),
+ {comment, io_lib:format("~p times slower", [Acc1/Acc2])}.
+
+%%%---------------------------------------------------------------------
+
+tail_seq(doc) ->
+ ["Tests a tail recursive variant of lists:seq/3"];
+tail_seq(suite) ->
+ [];
+tail_seq(Config) when is_list(Config) ->
+ ?line Timetrap = ?t:timetrap(?t:seconds(10)),
+ ?line PrivDir = ?config(priv_dir, Config),
+ ?line TraceFile =
+ filename:join(PrivDir, ?MODULE_STRING"_tail_seq.trace"),
+ ?line AnalysisFile =
+ filename:join(PrivDir, ?MODULE_STRING"_tail_seq.analysis"),
+ ?line Start = 1,
+ ?line Stop = 1000,
+ ?line Succ = fun (X) -> X + 1 end,
+ ?line ok = fprof:stop(kill),
+ %%
+ ?line TS0 = erlang:now(),
+ ?line R = seq_r(Start, Stop, Succ),
+ ?line TS1 = erlang:now(),
+ %%
+ ?line R1 = fprof:apply(fun seq_r/3, [Start, Stop, Succ],
+ [{file, TraceFile}]),
+ ?line TS2 = erlang:now(),
+ ?line ok = fprof:profile([{file,TraceFile}]),
+ ?line ok = fprof:analyse(),
+ ?line ok = fprof:analyse(dest, AnalysisFile),
+ ?line ok = fprof:stop(),
+ ?line R = R1,
+ %%
+ ?line {ok, [T, P]} = parse(AnalysisFile),
+ ?line io:format("~p~n~n~p~n", [P, ets:tab2list(T)]),
+ ?line ok = verify(T, P),
+ ?line Proc = pid_to_list(self()),
+ ?line case P of
+ [{analysis_options, _},
+ [{totals, _, Acc, _}],
+ [{Proc, _, undefined, _} | _]] ->
+ ok
+ end,
+ %%
+ ?line check_own_and_acc(TraceFile,AnalysisFile),
+ %%
+ ?line ets:delete(T),
+ ?line file:delete(TraceFile),
+ ?line file:delete(AnalysisFile),
+ ?line ?t:timetrap_cancel(Timetrap),
+ ?line Acc1 = ts_sub(TS1, TS0),
+ ?line Acc2 = ts_sub(TS2, TS1),
+ ?line io:format("ts:~w, fprof:~w, bare:~w.~n", [Acc, Acc2, Acc1]),
+ {comment, io_lib:format("~p times slower", [Acc2/Acc1])}.
+
+%%%---------------------------------------------------------------------
+
+create_file_slow(doc) ->
+ ["Tests the create_file_slow benchmark"];
+create_file_slow(suite) ->
+ [];
+create_file_slow(Config) when is_list(Config) ->
+ ?line Timetrap = ?t:timetrap(?t:seconds(40)),
+ ?line PrivDir = ?config(priv_dir, Config),
+ ?line TraceFile =
+ filename:join(PrivDir, ?MODULE_STRING"_create_file_slow.trace"),
+ ?line AnalysisFile =
+ filename:join(PrivDir, ?MODULE_STRING"_create_file_slow.analysis"),
+ ?line DataFile =
+ filename:join(PrivDir, ?MODULE_STRING"_create_file_slow.data"),
+ ?line ok = fprof:stop(kill),
+ %%
+ ?line TS0 = erlang:now(),
+ ?line ok = create_file_slow(DataFile, 1024),
+ ?line TS1 = erlang:now(),
+ %%
+ ?line ok = file:delete(DataFile),
+ ?line TS2 = erlang:now(),
+ ?line ok = fprof:apply(?MODULE, create_file_slow, [DataFile, 1024],
+ [{file, TraceFile}]),
+ ?line TS3 = erlang:now(),
+ ?line ok = fprof:profile(file, TraceFile),
+ ?line ok = fprof:analyse(),
+ ?line ok = fprof:analyse(dest, AnalysisFile),
+ ?line ok = fprof:stop(),
+ %%
+ ?line {ok, [T, P]} = parse(AnalysisFile),
+ ?line io:format("~p~n~n~p~n", [P, ets:tab2list(T)]),
+ ?line ok = verify(T, P),
+ ?line Proc = pid_to_list(self()),
+ ?line case P of
+ [{analysis_options, _},
+ [{totals, _, Acc, _}],
+ [{Proc, _, undefined, _} | _]] ->
+ ok
+ end,
+ %%
+ ?line check_own_and_acc(TraceFile,AnalysisFile),
+ %%
+ ?line ets:delete(T),
+ ?line file:delete(DataFile),
+ ?line file:delete(TraceFile),
+ ?line file:delete(AnalysisFile),
+ ?line ?t:timetrap_cancel(Timetrap),
+ ?line Acc1 = ts_sub(TS1, TS0),
+ ?line Acc3 = ts_sub(TS3, TS2),
+ ?line io:format("ts:~w, fprof:~w, bare:~w.~n", [Acc, Acc3, Acc1]),
+ {comment, io_lib:format("~p times slower", [Acc3/Acc1])}.
+
+
+
+%%%---------------------------------------------------------------------
+
+spawn_simple(doc) ->
+ ["Tests process spawn"];
+spawn_simple(suite) ->
+ [];
+spawn_simple(Config) when is_list(Config) ->
+ ?line Timetrap = ?t:timetrap(?t:seconds(30)),
+ ?line PrivDir = ?config(priv_dir, Config),
+ ?line TraceFile =
+ filename:join(PrivDir, ?MODULE_STRING"_spawn_simple.trace"),
+ ?line AnalysisFile =
+ filename:join(PrivDir, ?MODULE_STRING"_spawn_simple.analysis"),
+ ?line Start = 1,
+ ?line Stop = 1000,
+ ?line Succ = fun (X) -> X + 1 end,
+ ?line ok = fprof:stop(kill),
+ %%
+ ?line TS0 = erlang:now(),
+ ?line {{_, R1}, {_, R2}} = spawn_simple_test(Start, Stop, Succ),
+ ?line TS1 = erlang:now(),
+ %%
+ ?line ok = fprof:trace(start, TraceFile),
+ ?line {{P1, R3}, {P2, R4}} = spawn_simple_test(Start, Stop, Succ),
+ ?line ok = fprof:trace(stop),
+ ?line TS2 = erlang:now(),
+ ?line ok = fprof:profile(file, TraceFile),
+ ?line ok = fprof:analyse(),
+ ?line ok = fprof:analyse(dest, AnalysisFile),
+ ?line ok = fprof:stop(),
+ ?line R1 = R3,
+ ?line R2 = R4,
+ %%
+ ?line {ok, [T, P]} = parse(AnalysisFile),
+ ?line io:format("~p~n~n~p~n", [P, ets:tab2list(T)]),
+ ?line ok = verify(T, P),
+ ?line Proc1 = pid_to_list(P1),
+ ?line Proc2 = pid_to_list(P2),
+ ?line Proc0 = pid_to_list(self()),
+ ?line io:format("~p~n ~p ~p ~p~n", [P, Proc0, Proc1, Proc2]),
+ ?line [{analysis_options, _}, [{totals, _, Acc, _}] | Procs] = P,
+ ?line [[{Proc0, _, undefined, _} | _]] =
+ lists:filter(fun ([Pt | _]) when element(1, Pt) == Proc0 -> true;
+ (_) -> false
+ end, Procs),
+ ?line [[{Proc1, _, undefined, _},
+ {spawned_by, Proc0},
+ {spawned_as, {erlang, apply, ["#Fun"++_, []]}},
+ {initial_calls, [{erlang, apply, 2},
+ {?MODULE, '-spawn_simple_test/3-fun-0-', 4}]}
+ | _]] =
+ lists:filter(fun ([Pt | _]) when element(1, Pt) == Proc1 -> true;
+ (_) -> false
+ end, Procs),
+ ?line [[{Proc2, _, undefined, _},
+ {spawned_by, Proc0},
+ {spawned_as, {erlang, apply, ["#Fun"++_, []]}},
+ {initial_calls, [{erlang, apply, 2},
+ {?MODULE, '-spawn_simple_test/3-fun-1-', 4}]}
+ | _]] =
+ lists:filter(fun ([Pt | _]) when element(1, Pt) == Proc2 -> true;
+ (_) -> false
+ end, Procs),
+ ?line 3 = length(Procs),
+ ?line R1 = lists:reverse(R2),
+ %%
+ ?line check_own_and_acc(TraceFile,AnalysisFile),
+ %%
+ ?line ets:delete(T),
+ ?line file:delete(TraceFile),
+ ?line file:delete(AnalysisFile),
+ ?line ?t:timetrap_cancel(Timetrap),
+ ?line Acc1 = ts_sub(TS1, TS0),
+ ?line Acc2 = ts_sub(TS2, TS1),
+ ?line io:format("ts:~w, fprof:~w, bare:~w.~n", [Acc, Acc2, Acc1]),
+ {comment, io_lib:format("~p times slower", [Acc2/Acc1])}.
+
+
+spawn_simple_test(Start, Stop, Succ) ->
+ Parent = self(),
+ Seq =
+ spawn_link(
+ fun () ->
+ Parent ! {self(), seq(Start, Stop, Succ)}
+ end),
+ SeqR =
+ spawn_link(
+ fun () ->
+ Parent ! {self(), seq_r(Start, Stop, Succ)}
+ end),
+ receive {Seq, SeqResult} ->
+ receive {SeqR, SeqRResult} ->
+ {{Seq, SeqResult}, {SeqR, SeqRResult}}
+ end
+ end.
+
+
+
+%%%---------------------------------------------------------------------
+
+imm_tail_seq(doc) ->
+ ["Tests a tail recursive variant of lists:seq/3 ",
+ "with immediate trace to profile"];
+imm_tail_seq(suite) ->
+ [];
+imm_tail_seq(Config) when is_list(Config) ->
+ ?line Timetrap = ?t:timetrap(?t:seconds(10)),
+ ?line PrivDir = ?config(priv_dir, Config),
+ ?line AnalysisFile =
+ filename:join(PrivDir, ?MODULE_STRING"_imm_tail_seq.analysis"),
+ ?line Start = 1,
+ ?line Stop = 1000,
+ ?line Succ = fun (X) -> X + 1 end,
+ ?line ok = fprof:stop(kill),
+ ?line catch eprof:stop(),
+ %%
+ ?line TS0 = erlang:now(),
+ ?line R0 = seq_r(Start, Stop, Succ),
+ ?line TS1 = erlang:now(),
+ %%
+ ?line profiling = eprof:start_profiling([self()]),
+ ?line TS2 = erlang:now(),
+ ?line R2 = seq_r(Start, Stop, Succ),
+ ?line TS3 = erlang:now(),
+ ?line profiling_stopped = eprof:stop_profiling(),
+ ?line R2 = R0,
+ %%
+ ?line eprof:analyse(),
+ ?line stopped = eprof:stop(),
+ %%
+ ?line {ok, Tracer} = fprof:profile(start),
+ ?line ok = fprof:trace([start, {tracer, Tracer}]),
+ ?line TS4 = erlang:now(),
+ ?line R4 = seq_r(Start, Stop, Succ),
+ ?line TS5 = erlang:now(),
+ ?line ok = fprof:trace(stop),
+ ?line ok = fprof:analyse(),
+ ?line ok = fprof:analyse(dest, AnalysisFile),
+ ?line ok = fprof:stop(),
+ ?line R4 = R0,
+ %%
+ ?line {ok, [T, P]} = parse(AnalysisFile),
+ ?line io:format("~p~n~n~p~n", [P, ets:tab2list(T)]),
+ ?line ok = verify(T, P),
+ ?line Proc = pid_to_list(self()),
+ ?line case P of
+ [{analysis_options, _},
+ [{totals, _, Acc, _}],
+ [{Proc, _, undefined, _} | _]] ->
+ ok
+ end,
+ %%
+ ?line ets:delete(T),
+ ?line file:delete(AnalysisFile),
+ ?line ?t:timetrap_cancel(Timetrap),
+ ?line Acc1 = ts_sub(TS1, TS0),
+ ?line Acc3 = ts_sub(TS3, TS2),
+ ?line Acc5 = ts_sub(TS5, TS4),
+ ?line io:format("~p (plain), ~p (eprof), ~p (fprof), ~p (cpu)~n",
+ [Acc1/1000, Acc3/1000, Acc5/1000, Acc/1000]),
+ {comment, io_lib:format("~p/~p (fprof/eprof) times slower",
+ [Acc5/Acc1, Acc3/Acc1])}.
+
+%%%---------------------------------------------------------------------
+
+imm_create_file_slow(doc) ->
+ ["Tests a tail recursive variant of lists:seq/3 ",
+ "with immediate trace to profile"];
+imm_create_file_slow(suite) ->
+ [];
+imm_create_file_slow(Config) when is_list(Config) ->
+ ?line Timetrap = ?t:timetrap(?t:seconds(60)),
+ ?line PrivDir = ?config(priv_dir, Config),
+ ?line DataFile =
+ filename:join(PrivDir, ?MODULE_STRING"_imm_create_file_slow.data"),
+ ?line AnalysisFile =
+ filename:join(PrivDir, ?MODULE_STRING"_imm_create_file_slow.analysis"),
+ ?line ok = fprof:stop(kill),
+ %%
+ ?line TS0 = erlang:now(),
+ ?line ok = create_file_slow(DataFile, 1024),
+ ?line TS1 = erlang:now(),
+ ?line ok = file:delete(DataFile),
+ %%
+ ?line {ok, Tracer} = fprof:profile(start),
+ ?line TS2 = erlang:now(),
+ ?line ok = fprof:apply(?MODULE, create_file_slow, [DataFile, 1024],
+ [{tracer, Tracer}, continue]),
+ ?line TS3 = erlang:now(),
+ ?line ok = fprof:profile(stop),
+ ?line ok = fprof:analyse(),
+ ?line ok = fprof:analyse(dest, AnalysisFile),
+ ?line ok = fprof:stop(),
+ %%
+ ?line {ok, [T, P]} = parse(AnalysisFile),
+ ?line io:format("~p~n~n~p~n", [P, ets:tab2list(T)]),
+ ?line ok = verify(T, P),
+ ?line Proc = pid_to_list(self()),
+ ?line case P of
+ [{analysis_options, _},
+ [{totals, _, Acc, _}],
+ [{Proc, _, undefined, _} | _]] ->
+ ok
+ end,
+ %%
+ ?line ets:delete(T),
+ ?line file:delete(DataFile),
+ ?line file:delete(AnalysisFile),
+ ?line ?t:timetrap_cancel(Timetrap),
+ ?line Acc1 = ts_sub(TS1, TS0),
+ ?line Acc3 = ts_sub(TS3, TS2),
+ ?line io:format("ts:~w, fprof:~w, bare:~w.~n", [Acc, Acc3, Acc1]),
+ {comment, io_lib:format("~p times slower", [Acc3/Acc1])}.
+
+%%%---------------------------------------------------------------------
+
+imm_compile(doc) ->
+ ["Tests to compile a small source file ",
+ "with immediate trace to profile"];
+imm_compile(suite) ->
+ [];
+imm_compile(Config) when is_list(Config) ->
+ ?line Timetrap = ?t:timetrap(?t:minutes(20)),
+ ?line DataDir = ?config(data_dir, Config),
+ ?line SourceFile = filename:join(DataDir, "foo.erl"),
+ ?line PrivDir = ?config(priv_dir, Config),
+ ?line AnalysisFile =
+ filename:join(PrivDir, ?MODULE_STRING"_imm_compile.analysis"),
+ ?line ok = fprof:stop(kill),
+ ?line catch eprof:stop(),
+ %%
+ ?line {ok, foo, _} = compile:file(SourceFile, [binary]),
+ ?line TS0 = erlang:now(),
+ ?line {ok, foo, _} = compile:file(SourceFile, [binary]),
+ ?line TS1 = erlang:now(),
+ %%
+ ?line profiling = eprof:start_profiling([self()]),
+ ?line TS2 = erlang:now(),
+ ?line {ok, foo, _} = compile:file(SourceFile, [binary]),
+ ?line TS3 = erlang:now(),
+ ?line profiling_stopped = eprof:stop_profiling(),
+ %%
+ ?line eprof:analyse(),
+ ?line stopped = eprof:stop(),
+ %%
+ ?line {ok, Tracer} = fprof:profile(start),
+ ?line ok = fprof:trace([start, {tracer, Tracer}]),
+ ?line TS4 = erlang:now(),
+ ?line {ok, foo, _} = compile:file(SourceFile, [binary]),
+ ?line TS5 = erlang:now(),
+ ?line ok = fprof:trace(stop),
+ %%
+ ?line io:format("Analysing...~n"),
+ ?line ok = fprof:analyse(dest, AnalysisFile),
+ ?line ok = fprof:stop(),
+ %%
+ ?line {ok, [T, P]} = parse(AnalysisFile),
+ ?line io:format("~p~n", [P]),
+ ?line Acc1 = ts_sub(TS1, TS0),
+ ?line Acc3 = ts_sub(TS3, TS2),
+ ?line Acc5 = ts_sub(TS5, TS4),
+ ?line io:format("Verifying...~n"),
+ ?line ok = verify(T, P),
+ ?line case P of
+ [{analysis_options, _},
+ [{totals, _, Acc, _}] | _] ->
+ ok
+ end,
+ %%
+ ?line ets:delete(T),
+ ?line file:delete(AnalysisFile),
+ ?line ?t:timetrap_cancel(Timetrap),
+ ?line io:format("~p (plain), ~p (eprof), ~p (fprof), ~p(cpu)~n",
+ [Acc1/1000, Acc3/1000, Acc5/1000, Acc/1000]),
+ {comment, io_lib:format("~p/~p (fprof/eprof) times slower",
+ [Acc5/Acc1, Acc3/Acc1])}.
+
+%%%---------------------------------------------------------------------
+
+cpu_create_file_slow(doc) ->
+ ["Tests the create_file_slow benchmark using cpu_time"];
+cpu_create_file_slow(suite) ->
+ [];
+cpu_create_file_slow(Config) when is_list(Config) ->
+ ?line Timetrap = ?t:timetrap(?t:seconds(40)),
+ ?line PrivDir = ?config(priv_dir, Config),
+ ?line TraceFile =
+ filename:join(PrivDir, ?MODULE_STRING"_cpu_create_file_slow.trace"),
+ ?line AnalysisFile =
+ filename:join(PrivDir, ?MODULE_STRING"_cpu_create_file_slow.analysis"),
+ ?line DataFile =
+ filename:join(PrivDir, ?MODULE_STRING"_cpu_create_file_slow.data"),
+ ?line ok = fprof:stop(kill),
+ %%
+ ?line TS0 = erlang:now(),
+ ?line Result = (catch fprof:apply(?MODULE, create_file_slow,
+ [DataFile, 1024],
+ [{file, TraceFile}, cpu_time])),
+ ?line TS1 = erlang:now(),
+ ?line TestResult =
+ case Result of
+ ok ->
+ ?line ok = fprof:profile(file, TraceFile),
+ ?line ok = fprof:analyse(),
+ ?line ok = fprof:analyse(dest, AnalysisFile),
+ ?line ok = fprof:stop(),
+ %%
+ ?line {ok, [T, P]} = parse(AnalysisFile),
+ ?line io:format("~p~n~n~p~n", [P, ets:tab2list(T)]),
+ ?line ok = verify(T, P),
+ ?line Proc = pid_to_list(self()),
+ ?line case P of
+ [{analysis_options, _},
+ [{totals, _, Acc, _}],
+ [{Proc, _, undefined, _} | _]] ->
+ ok
+ end,
+ %%
+ ?line check_own_and_acc(TraceFile,AnalysisFile),
+ %%
+ ?line ets:delete(T),
+ ?line file:delete(DataFile),
+ ?line file:delete(TraceFile),
+ ?line file:delete(AnalysisFile),
+ ?line Acc1 = ts_sub(TS1, TS0),
+ ?line io:format("cpu_ts:~w, fprof:~w~n", [Acc, Acc1]),
+ {comment, io_lib:format("~p% cpu utilization",
+ [100*Acc/Acc1])};
+ {'EXIT', not_supported} ->
+ case {os:type(), os:version()} of
+ {{unix, sunos}, {Major, Minor, _}}
+ when Major >= 5, Minor >= 7 ->
+ test_server:fail(Result);
+ _ ->
+ {skipped, "not_supported"}
+ end;
+ _ ->
+ test_server:fail(Result)
+ end,
+ ?line ?t:timetrap_cancel(Timetrap),
+ TestResult.
+
+
+
+%%%---------------------------------------------------------------------
+%%% Functions to test
+%%%---------------------------------------------------------------------
+
+
+
+%% Stack recursive seq
+seq(Stop, Stop, Succ) when is_function(Succ) ->
+ [Stop];
+seq(Start, Stop, Succ) when is_function(Succ) ->
+ [Start | seq(Succ(Start), Stop, Succ)].
+
+
+
+%% Tail recursive seq, result list is reversed
+seq_r(Start, Stop, Succ) when is_function(Succ) ->
+ seq_r(Start, Stop, Succ, []).
+
+seq_r(Stop, Stop, _, R) ->
+ [Stop | R];
+seq_r(Start, Stop, Succ, R) ->
+ seq_r(Succ(Start), Stop, Succ, [Start | R]).
+
+
+
+create_file_slow(Name, N) when is_integer(N), N >= 0 ->
+ {ok, FD} =
+ file:open(Name, [raw, write, delayed_write, binary]),
+ if N > 256 ->
+ ok = file:write(FD,
+ lists:map(fun (X) -> <<X:32/unsigned>> end,
+ lists:seq(0, 255))),
+ ok = create_file_slow(FD, 256, N);
+ true ->
+ ok = create_file_slow(FD, 0, N)
+ end,
+ ok = file:close(FD).
+
+create_file_slow(_FD, M, M) ->
+ ok;
+create_file_slow(FD, M, N) ->
+ ok = file:write(FD, <<M:32/unsigned>>),
+ create_file_slow(FD, M+1, N).
+
+
+
+%%%---------------------------------------------------------------------
+%%% Profile verification functions
+%%%---------------------------------------------------------------------
+
+
+
+verify(Tab, [{analysis_options, _},
+ [{totals, Cnt, Acc, Own} | _] | Processes]) ->
+ Processes_1 =
+ lists:map(
+ fun ([{Proc, Cnt_P, undefined, Own_P} | _]) ->
+ case sum_process(Tab, Proc) of
+ {Proc, Cnt_P, Acc_P, Own_P} = Clocks
+ when Acc_P >= Own_P ->
+ Clocks;
+ Weird ->
+ throw({error, [?MODULE, ?LINE, Weird]})
+ end
+ end,
+ Processes),
+ case lists:foldl(
+ fun ({_, Cnt_P2, Acc_P2, Own_P2},
+ {totals, Cnt_T, Acc_T, Own_T}) ->
+ {totals, Cnt_P2+Cnt_T, Acc_P2+Acc_T, Own_P2+Own_T}
+ end,
+ {totals, 0, 0, 0},
+ Processes_1) of
+ {totals, Cnt, Acc_T, Own} when Acc_T >= Acc ->
+ ok;
+ Weird ->
+ throw({error, [?MODULE, ?LINE, Weird]})
+ end.
+
+
+
+sum_process(Tab, Proc) ->
+ ets_select_fold(
+ Tab, [{{{Proc, '_'}, '_'}, [], ['$_']}], 100,
+ fun ({{P, MFA}, {Callers, {MFA, Cnt, Acc, Own}, Called}},
+ {P, Cnt_P, Acc_P, Own_P}) when P == Proc ->
+ ok = verify_callers(Tab, Proc, MFA, Callers),
+ ok = verify_called(Tab, Proc, MFA, Called),
+ {P, Cnt+Cnt_P, Acc+Acc_P, Own+Own_P};
+ (Weird, Clocks) ->
+ throw({error, [?MODULE, ?LINE, Weird, Clocks]})
+ end,
+ {Proc, 0, 0, 0}).
+
+verify_callers(_, _, _, []) ->
+ ok;
+verify_callers(Tab, Proc, MFA, [{Caller, Cnt, Acc, Own} | Tail]) ->
+ Id = {Proc, Caller},
+ case ets:lookup(Tab, Id) of
+ [{Id, {_, {Caller, _, _, _}, Called}}] ->
+ case lists:keysearch(MFA, 1, Called) of
+ {value, {MFA, Cnt, Acc, Own}} ->
+ verify_callers(Tab, Proc, MFA, Tail);
+ false ->
+ throw({error, [?MODULE, ?LINE, MFA, Id]})
+ end;
+ Weird ->
+ throw({error, [?MODULE, ?LINE, Weird]})
+ end.
+
+verify_called(_, _, _, []) ->
+ ok;
+verify_called(Tab, Proc, MFA, [{Called, Cnt, Acc, Own} | Tail]) ->
+ Id = {Proc, Called},
+ case ets:lookup(Tab, Id) of
+ [{Id, {Callers, {Called, _, _, _}, _}}] ->
+ case lists:keysearch(MFA, 1, Callers) of
+ {value, {MFA, Cnt, Acc, Own}} ->
+ verify_called(Tab, Proc, MFA, Tail);
+ false ->
+ throw({error, [?MODULE, ?LINE, MFA, Id]})
+ end;
+ Weird ->
+ throw({error, [?MODULE, ?LINE, Weird]})
+ end.
+
+
+
+%% Parse a analysis file and return an Ets table with all function entries,
+%% and a list of process entries. Checks the concistency of the function
+%% entries when they are read.
+parse(Filename) ->
+ case file:open(Filename, [read]) of
+ {ok, FD} ->
+ Result = parse_stream(FD),
+ file:close(FD),
+ Result;
+ Error ->
+ Error
+ end.
+
+parse_stream(FD) ->
+ Tab = ets:new(fprof_SUITE, []),
+ parse_stream(FD, Tab, [], void).
+
+parse_stream(FD, Tab, R, Proc) ->
+ case catch io:read(FD, '') of
+ {'EXIT', _} ->
+ {error, [?MODULE, ?LINE]};
+ {ok, Term} ->
+ case parse_term(Term) of
+ {ok, {analysis_options, _} = Term_1}
+ when Proc == void ->
+ parse_stream(FD, Tab, [Term_1 | R], analysis_options);
+ {ok, [{totals, _, _, _} | _] = Term_1}
+ when Proc == analysis_options ->
+ parse_stream(FD, Tab, [Term_1 | R], totals);
+ {ok, [{P, _, _, _} | _] = Term_1} ->
+ parse_stream(FD, Tab, [Term_1 | R], P);
+ {ok, {_Callers, {MFA, _, _, _}, _Called} = Term_1}
+ when Proc == totals; is_list(Proc) ->
+ ets:insert(Tab, {{Proc, MFA}, Term_1}),
+ parse_stream(FD, Tab, R, Proc);
+ {ok, Term_1} ->
+ {error, [?MODULE, ?LINE, Term_1]};
+ E ->
+ E
+ end;
+ eof ->
+ {ok, [Tab, lists:reverse(R)]};
+ Error ->
+ Error
+ end.
+
+parse_term({Callers, Func, Called})
+ when is_list(Callers), is_list(Called) ->
+ Callers_1 = lists:map(fun parse_clocks/1, Callers),
+ Func_1 = parse_clocks(Func),
+ Called_1 = lists:map(fun parse_clocks/1, Called),
+ Result = {Callers_1, Func_1, Called_1},
+ case chk_invariant(Result) of
+ ok ->
+ {ok, Result};
+ Error ->
+ Error
+ end;
+parse_term([{_, _, _, _} = Clocks | Tail]) ->
+ {ok, [parse_clocks(Clocks) | Tail]};
+parse_term(Term) ->
+ {ok, Term}.
+
+parse_clocks({MFA, Cnt, undefined, Own}) ->
+ {MFA, Cnt, undefined, round(Own*1000)};
+parse_clocks({MFA, Cnt, Acc, Own}) ->
+ {MFA, Cnt, round(Acc*1000), round(Own*1000)};
+parse_clocks(Clocks) ->
+ Clocks.
+
+
+
+chk_invariant({Callers, {MFA, Cnt, Acc, Own}, Called} = Term) ->
+ {_, Callers_Cnt, Callers_Acc, Callers_Own} = Callers_Sum = sum(Callers),
+% {_, Called_Cnt, Called_Acc, Called_Own} = Called_Sum = sum(Called),
+ case {MFA,
+ lists:keymember(suspend, 1, Callers),
+ lists:keymember(garbage_collect, 1, Callers),
+ Called} of
+ {suspend, false, _, []} ->
+ ok;
+ {suspend, _, _, _} = Weird ->
+ {error, [?MODULE, ?LINE, Weird, Term]};
+ {garbage_collect, false, false, []} ->
+ ok;
+ {garbage_collect, false, false, [{suspend, _, _, _}]} ->
+ ok;
+ {garbage_collect, _, _, _} = Weird ->
+ {error, [?MODULE, ?LINE, Weird, Term]};
+ {undefined, false, false, _}
+ when Callers == [], Cnt == 0, Acc == 0, Own == 0 ->
+ ok;
+ {undefined, _, _, _} = Weird ->
+ {error, [?MODULE, ?LINE, Weird, Term]};
+ {_, _, _, _} ->
+ case chk_self_call(Term) of
+ true when Callers_Cnt /= Cnt; Callers_Acc /= Acc;
+ Callers_Own /= Own ->
+ {error, [?MODULE, ?LINE, Callers_Sum, Term]};
+% true when Called_Acc + Own /= Acc ->
+% io:format("WARNING: ~p:~p, ~p, ~p.~n",
+% [?MODULE, ?LINE, Term, Called_Sum]),
+% {error, [?MODULE, ?LINE, Term, Called_Sum]};
+% ok;
+ true ->
+ ok;
+ false ->
+ {error, [?MODULE, ?LINE, Term]}
+ end
+ end.
+
+ts_sub({A, B, C}, {A0, B0, C0}) ->
+ ((A - A0)*1000000000000 + (B - B0))*1000000 + C - C0.
+
+sum(Funcs) ->
+ {sum, _Cnt, _Acc, _Own} =
+ lists:foldl(
+ fun ({_, C1, A1, O1}, {sum, C2, A2, O2}) ->
+ {sum, C1+C2, A1+A2, O1+O2}
+ end,
+ {sum, 0, 0, 0},
+ Funcs).
+
+chk_self_call({Callers, {MFA, _Cnt, _Acc, _Own}, Called}) ->
+ case lists:keysearch(MFA, 1, Callers) of
+ false ->
+ true;
+ {value, {MFA, C, 0, O}} ->
+ case lists:keysearch(MFA, 1, Called) of
+ false ->
+ false;
+ {value, {MFA, C, 0, O}} ->
+ true;
+ {value, _} ->
+ false
+ end;
+ {value, _} ->
+ false
+ end.
+
+
+
+%%%---------------------------------------------------------------------
+%%% Fairly generic support functions
+%%%---------------------------------------------------------------------
+
+
+ets_select_fold(Table, MatchSpec, Limit, Fun, Acc) ->
+ ets:safe_fixtable(Table, true),
+ ets_select_fold_1(ets:select(Table, MatchSpec, Limit), Fun, Acc).
+
+ets_select_fold_1('$end_of_table', _, Acc) ->
+ Acc;
+ets_select_fold_1({Matches, Continuation}, Fun, Acc) ->
+ ets_select_fold_1(ets:select(Continuation),
+ Fun,
+ lists:foldl(Fun, Acc, Matches)).
+
+
+
+% ets_select_foreach(Table, MatchSpec, Limit, Fun) ->
+% ets:safe_fixtable(Table, true),
+% ets_select_foreach_1(ets:select(Table, MatchSpec, Limit), Fun).
+
+% ets_select_foreach_1('$end_of_table', _) ->
+% ok;
+% ets_select_foreach_1({Matches, Continuation}, Fun) ->
+% lists:foreach(Fun, Matches),
+% ets_select_foreach_1(ets:select(Continuation), Fun).
+
+
+%%%---------------------------------------------------------------------
+%%% Simple smulation of fprof used for checking own and acc times for
+%%% each function.
+%%% The function 'undefined' is ignored
+%%%---------------------------------------------------------------------
+
+%% check_own_and_acc_traced(TraceFile, AnalysisFile) ->
+%% check_own_and_acc(TraceFile, AnalysisFile, fun handle_trace_traced/2).
+
+check_own_and_acc(TraceFile, AnalysisFile) ->
+ check_own_and_acc(TraceFile, AnalysisFile, fun handle_trace/2).
+
+check_own_and_acc(TraceFile, AnalysisFile, HandlerFun) ->
+ dbg:trace_client(file,TraceFile,{HandlerFun,{init,self()}}),
+ receive {result,Result} ->
+ compare(Result,get_own_and_acc_from_analysis(AnalysisFile))
+ end.
+
+%% handle_trace_traced(Trace, Msg) ->
+%% io:format("handle_trace_traced(~p, ~p).", [Trace, Msg]),
+%% handle_trace(Trace, Msg).
+
+handle_trace(Trace,{init,Parent}) ->
+ ?dbg("~p",[start]),
+ ets:new(fprof_verify_tab,[named_table]),
+ handle_trace(Trace,Parent);
+handle_trace({trace_ts,Pid,in,MFA,TS},P) ->
+ ?dbg("~p",[{{in,Pid,MFA},get(Pid)}]),
+ case get(Pid) of
+ [suspend|[suspend|_]=NewStack] ->
+ T = ts_sub(TS,get({Pid,last_ts})),
+ update_acc(Pid,NewStack,T),
+ put(Pid,NewStack);
+ [suspend|NewStack] = Stack ->
+ T = ts_sub(TS,get({Pid,last_ts})),
+ update_acc(Pid,Stack,T),
+ put(Pid,NewStack);
+ [] ->
+ put(Pid,[MFA]),
+ insert(Pid,MFA);
+ undefined ->
+ put(first_ts,TS),
+ put(Pid,[MFA]),
+ insert(Pid,MFA)
+ end,
+ put({Pid,last_ts},TS),
+ P;
+handle_trace({trace_ts,Pid,out,_MfaOrZero,TS},P) ->
+ ?dbg("~p",[{{out,Pid,_MfaOrZero},get(Pid)}]),
+ T = ts_sub(TS,get({Pid,last_ts})),
+ case get(Pid) of
+ [suspend|S] = Stack ->
+ update_acc(Pid,S,T),
+ put(Pid,[suspend|Stack]);
+ [MFA|_] = Stack ->
+ insert(Pid,suspend),
+ update_own(Pid,MFA,T),
+ update_acc(Pid,Stack,T),
+ put(Pid,[suspend|Stack]);
+ [] ->
+ insert(Pid,suspend),
+ put(Pid,[suspend])
+ end,
+ put({Pid,last_ts},TS),
+ P;
+handle_trace({trace_ts,Pid,call,MFA,{cp,Caller},TS},P) ->
+ ?dbg("~p",[{{call,Pid,MFA},get(Pid)}]),
+ T = ts_sub(TS,get({Pid,last_ts})),
+ case get(Pid) of
+ [MFA|_] = Stack ->
+ %% recursive
+ update_own(Pid,MFA,T),
+ update_acc(Pid,Stack,T);
+ [CallingMFA|_] = Stack when Caller==undefined ->
+ insert(Pid,MFA),
+ update_own(Pid,CallingMFA,T),
+ update_acc(Pid,Stack,T),
+ put(Pid,[MFA|Stack]);
+ [] when Caller==undefined ->
+ insert(Pid,MFA),
+ insert(Pid,MFA),
+ put(Pid,[MFA]);
+ Stack0 ->
+ Stack = [CallingMFA|_] = insert_caller(Caller,Stack0,[]),
+ insert(Pid,MFA),
+ insert(Pid,Caller),
+ update_own(Pid,CallingMFA,T),
+ update_acc(Pid,Stack,T),
+ put(Pid,[MFA|Stack])
+ end,
+ put({Pid,last_ts},TS),
+ P;
+handle_trace({trace_ts,Pid,return_to,MFA,TS},P) ->
+ ?dbg("~p",[{{return_to,Pid,MFA},get(Pid)}]),
+ T = ts_sub(TS,get({Pid,last_ts})),
+ case get(Pid) of
+ [MFA|_] = Stack ->
+ %% recursive
+ update_own(Pid,MFA,T),
+ update_acc(Pid,Stack,T),
+ put(Pid,Stack);
+ [ReturnFromMFA,MFA|RestOfStack] = Stack ->
+ update_own(Pid,ReturnFromMFA,T),
+ update_acc(Pid,Stack,T),
+ put(Pid,[MFA|RestOfStack]);
+ [ReturnFromMFA|RestOfStack] = Stack ->
+ update_own(Pid,ReturnFromMFA,T),
+ update_acc(Pid,Stack,T),
+ case find_return_to(MFA,RestOfStack) of
+ [] when MFA==undefined ->
+ put(Pid,[]);
+ [] ->
+ insert(Pid,MFA),
+ put(Pid,[MFA]);
+ NewStack ->
+ put(Pid,NewStack)
+ end
+ end,
+ put({Pid,last_ts},TS),
+ P;
+handle_trace({trace_ts,Pid,gc_start,_,TS},P) ->
+ ?dbg("~p",[{{gc_start,Pid},get(Pid)}]),
+ case get(Pid) of
+ [suspend|_] = Stack ->
+ T = ts_sub(TS,get({Pid,last_ts})),
+ insert(Pid,garbage_collect),
+ update_acc(Pid,Stack,T),
+ put(Pid,[garbage_collect|Stack]);
+ [CallingMFA|_] = Stack ->
+ T = ts_sub(TS,get({Pid,last_ts})),
+ insert(Pid,garbage_collect),
+ update_own(Pid,CallingMFA,T),
+ update_acc(Pid,Stack,T),
+ put(Pid,[garbage_collect|Stack]);
+ undefined ->
+ put(first_ts,TS),
+ put(Pid,[garbage_collect]),
+ insert(Pid,garbage_collect)
+ end,
+ put({Pid,last_ts},TS),
+ P;
+handle_trace({trace_ts,Pid,gc_end,_,TS},P) ->
+ ?dbg("~p",[{{gc_end,Pid},get(Pid)}]),
+ T = ts_sub(TS,get({Pid,last_ts})),
+ case get(Pid) of
+ [garbage_collect|RestOfStack] = Stack ->
+ update_own(Pid,garbage_collect,T),
+ update_acc(Pid,Stack,T),
+ put(Pid,RestOfStack)
+ end,
+ put({Pid,last_ts},TS),
+ P;
+handle_trace({trace_ts,Pid,spawn,NewPid,{M,F,Args},TS},P) ->
+ MFA = {M,F,length(Args)},
+ ?dbg("~p",[{{spawn,Pid,NewPid,MFA},get(Pid)}]),
+ T = ts_sub(TS,get({Pid,last_ts})),
+ put({NewPid,last_ts},TS),
+ put(NewPid,[suspend,MFA]),
+ insert(NewPid,suspend),
+ insert(NewPid,MFA),
+ case get(Pid) of
+ [SpawningMFA|_] = Stack ->
+ update_own(Pid,SpawningMFA,T),
+ update_acc(Pid,Stack,T)
+ end,
+ put({Pid,last_ts},TS),
+ P;
+handle_trace({trace_ts,Pid,exit,_Reason,TS},P) ->
+ ?dbg("~p",[{{exit,Pid,_Reason},get(Pid)}]),
+ T = ts_sub(TS,get({Pid,last_ts})),
+ case get(Pid) of
+ [DyingMFA|_] = Stack ->
+ update_own(Pid,DyingMFA,T),
+ update_acc(Pid,Stack,T),
+ put(Pid,[]);
+ [] ->
+ ok
+ end,
+ put({Pid,last_ts},TS),
+ P;
+handle_trace({trace_ts,_,Link,_,_},P)
+ when Link==link;
+ Link==unlink;
+ Link==getting_linked;
+ Link==getting_unlinked ->
+ P;
+handle_trace(end_of_trace,P) ->
+ ?dbg("~p",['end']),
+ Result = ets:tab2list(fprof_verify_tab),
+ {TotOwn,ProcOwns} = get_proc_owns(Result,[],0),
+ TotAcc = ts_sub(get_last_ts(),get(first_ts)),
+ P ! {result,[{totals,TotAcc,TotOwn}|ProcOwns]++Result},
+ P;
+handle_trace(Other,_P) ->
+ exit({unexpected,Other}).
+
+find_return_to(MFA,[MFA|_]=Stack) ->
+ Stack;
+find_return_to(MFA,[_|Stack]) ->
+ find_return_to(MFA,Stack);
+find_return_to(_MFA,[]) ->
+ [].
+
+insert_caller(MFA,[MFA|Rest],Result) ->
+ lists:reverse(Result)++[MFA|Rest];
+insert_caller(MFA,[Other|Rest],Result) ->
+ insert_caller(MFA,Rest,[Other|Result]);
+insert_caller(MFA,[],Result) ->
+ lists:reverse([MFA|Result]).
+
+insert(Pid,MFA) ->
+ case ets:member(fprof_verify_tab,{Pid,MFA}) of
+ false ->
+ ets:insert(fprof_verify_tab,{{Pid,MFA},0,0});
+ true ->
+ ok
+ end.
+
+update_own(Pid,MFA,T) ->
+ ets:update_counter(fprof_verify_tab,{Pid,MFA},{3,T}).
+
+update_acc(Pid,[MFA|Rest],T) ->
+ case lists:member(MFA,Rest) of
+ true ->
+ %% Only charge one time for recursive functions
+ ok;
+ false ->
+ ets:update_counter(fprof_verify_tab,{Pid,MFA},{2,T})
+ end,
+ update_acc(Pid,Rest,T);
+update_acc(_Pid,[],_T) ->
+ ok.
+
+
+get_last_ts() ->
+ get_last_ts(get(),{0,0,0}).
+get_last_ts([{{_,last_ts},TS}|Rest],Last) when TS>Last ->
+ get_last_ts(Rest,TS);
+get_last_ts([_|Rest],Last) ->
+ get_last_ts(Rest,Last);
+get_last_ts([],Last) ->
+ Last.
+
+get_proc_owns([{{Pid,_MFA},_Acc,Own}|Rest],Result,Sum) ->
+ NewResult =
+ case lists:keysearch(Pid,1,Result) of
+ {value,{Pid,undefined,PidOwn}} ->
+ lists:keyreplace(Pid,1,Result,{Pid,undefined,PidOwn+Own});
+ false ->
+ [{Pid,undefined,Own}|Result]
+ end,
+ get_proc_owns(Rest,NewResult,Sum+Own);
+get_proc_owns([],Result,Sum) ->
+ {Sum,Result}.
+
+
+compare([X|Rest],FprofResult) ->
+ FprofResult1 =
+ case lists:member(X,FprofResult) of
+ true ->
+ ?dbg("~p",[X]),
+ lists:delete(X,FprofResult);
+ false ->
+ case lists:keysearch(element(1,X),1,FprofResult) of
+ {value,Fprof} ->
+ put(compare_error,true),
+ io:format("Error: Different values\n"
+ "Fprof: ~p\n"
+ "Simulator: ~p",[Fprof,X]),
+ lists:delete(Fprof,FprofResult);
+ false ->
+ put(compare_error,true),
+ io:format("Error: Missing in fprof: ~p",[X]),
+ FprofResult
+ end
+ end,
+ compare(Rest,FprofResult1);
+compare([],Rest) ->
+ case {remove_undefined(Rest,[]),get(compare_error)} of
+ {[],undefined} -> ok;
+ {Error,_} ->
+ case Error of
+ [] -> ok;
+ _ -> io:format("\nMissing in simulator results:\n~p\n",[Error])
+ end,
+ ?t:fail({error,mismatch_between_simulator_and_fprof})
+ end.
+
+remove_undefined([{{_Pid,undefined},_,_}|Rest],Result) ->
+ remove_undefined(Rest,Result);
+remove_undefined([X|Rest],Result) ->
+ remove_undefined(Rest,[X|Result]);
+remove_undefined([],Result) ->
+ Result.
+
+get_own_and_acc_from_analysis(Log) ->
+ case file:consult(Log) of
+ {ok,[_Options,[{totals,_,TotAcc,TotOwn}]|Rest]} ->
+ get_own_and_acc(undefined,Rest,
+ [{totals,m1000(TotAcc),m1000(TotOwn)}]);
+ Error ->
+ exit({error,{cant_open,Log,Error}})
+ end.
+
+get_own_and_acc(_,[[{PidStr,_,Acc,Own}|_]|Rest],Result) ->
+ Pid = list_to_pid(PidStr),
+ get_own_and_acc(Pid,Rest,[{Pid,m1000(Acc),m1000(Own)}|Result]);
+get_own_and_acc(Pid,[{_Callers,{MFA,_,Acc,Own},_Called}|Rest],Result) ->
+ get_own_and_acc(Pid,Rest,[{{Pid,MFA},m1000(Acc),m1000(Own)}|Result]);
+get_own_and_acc(_,[],Result) ->
+ lists:reverse(Result).
+
+m1000(undefined) ->
+ undefined;
+m1000(X) ->
+ round(X*1000).
+
diff --git a/lib/tools/test/fprof_SUITE_data/foo.erl b/lib/tools/test/fprof_SUITE_data/foo.erl
new file mode 100644
index 0000000000..eaa8132b1e
--- /dev/null
+++ b/lib/tools/test/fprof_SUITE_data/foo.erl
@@ -0,0 +1,41 @@
+%% ``The contents of this file are subject to the Erlang Public License,
+%% Version 1.1, (the "License"); you may not use this file except in
+%% compliance with the License. You should have received a copy of the
+%% Erlang Public License along with this software. If not, it can be
+%% retrieved via the world wide web at http://www.erlang.org/.
+%%
+%% Software distributed under the License is distributed on an "AS IS"
+%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+%% the License for the specific language governing rights and limitations
+%% under the License.
+%%
+%% The Initial Developer of the Original Code is Ericsson Utvecklings AB.
+%% Portions created by Ericsson are Copyright 1999, Ericsson Utvecklings
+%% AB. All Rights Reserved.''
+%%
+%% $Id$
+%%
+-module(foo).
+
+-export([create_file_slow/2]).
+
+
+
+create_file_slow(Name, N) when integer(N), N >= 0 ->
+ {ok, FD} =
+ file:open(Name, [raw, write, delayed_write, binary]),
+ if N > 256 ->
+ ok = file:write(FD,
+ lists:map(fun (X) -> <<X:32/unsigned>> end,
+ lists:seq(0, 255))),
+ ok = create_file_slow(FD, 256, N);
+ true ->
+ ok = create_file_slow(FD, 0, N)
+ end,
+ ok = file:close(FD).
+
+create_file_slow(FD, M, M) ->
+ ok;
+create_file_slow(FD, M, N) ->
+ ok = file:write(FD, <<M:32/unsigned>>),
+ create_file_slow(FD, M+1, N).
diff --git a/lib/tools/test/ignore_cores.erl b/lib/tools/test/ignore_cores.erl
new file mode 120000
index 0000000000..8902a469ef
--- /dev/null
+++ b/lib/tools/test/ignore_cores.erl
@@ -0,0 +1 @@
+../../../erts/test/ignore_cores.erl \ No newline at end of file
diff --git a/lib/tools/test/instrument_SUITE.erl b/lib/tools/test/instrument_SUITE.erl
new file mode 100644
index 0000000000..da5930e015
--- /dev/null
+++ b/lib/tools/test/instrument_SUITE.erl
@@ -0,0 +1,129 @@
+%%
+%% %CopyrightBegin%
+%%
+%% 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%
+%%
+-module(instrument_SUITE).
+
+-export([all/1,init_per_testcase/2,fin_per_testcase/2]).
+
+-export(['+Mim true'/1, '+Mis true'/1]).
+
+-include("test_server.hrl").
+
+init_per_testcase(_Case, Config) ->
+ ?line Dog=?t:timetrap(10000),
+ [{watchdog, Dog}|Config].
+
+fin_per_testcase(_Case, Config) ->
+ Dog=?config(watchdog, Config),
+ ?t:timetrap_cancel(Dog),
+ ok.
+
+all(suite) -> ['+Mim true', '+Mis true'].
+
+'+Mim true'(doc) -> ["Check that memory data can be read and processed"];
+'+Mim true'(suite) -> [];
+'+Mim true'(Config) when is_list(Config) ->
+ ?line Node = start_slave("+Mim true"),
+ ?line MD = rpc:call(Node, instrument, memory_data, []),
+ ?line [{total,[{sizes,S1,S2,S3},{blocks,B1,B2,B3}]}]
+ = rpc:call(Node, instrument, memory_status, [total]),
+ ?line stop_slave(Node),
+ ?line true = S1 =< S2,
+ ?line true = S2 =< S3,
+ ?line true = B1 =< B2,
+ ?line true = B2 =< B3,
+ ?line MDS = instrument:sort(MD),
+ ?line {Low, High} = instrument:mem_limits(MDS),
+ ?line true = Low < High,
+ ?line {_, AL} = MDS,
+ ?line SumBlocks = instrument:sum_blocks(MD),
+ ?line case SumBlocks of
+ N when is_integer(N) ->
+ ?line N = lists:foldl(fun ({_,_,Size,_}, Sum) ->
+ Size+Sum
+ end,
+ 0,
+ AL),
+ ?line N =< S3;
+ Other ->
+ ?line ?t:fail(Other)
+ end,
+ ?line lists:foldl(
+ fun ({TDescr,Addr,Size,Proc}, MinAddr) ->
+ ?line true = TDescr /= invalid_type,
+ ?line true = is_integer(TDescr),
+ ?line true = is_integer(Addr),
+ ?line true = is_integer(Size),
+ ?line true = Addr >= MinAddr,
+ ?line case Proc of
+ {0, Number, Serial} ->
+ ?line true = is_integer(Number),
+ ?line true = is_integer(Serial);
+ undefined ->
+ ok;
+ BadProc ->
+ ?line ?t:fail({badproc, BadProc})
+ end,
+ ?line NextMinAddr = Addr+Size,
+ ?line true = NextMinAddr =< High,
+ ?line NextMinAddr
+ end,
+ Low,
+ AL),
+ ?line {_, DAL} = instrument:descr(MDS),
+ ?line lists:foreach(
+ fun ({TDescr,_,_,Proc}) ->
+ ?line true = TDescr /= invalid_type,
+ ?line true = is_atom(TDescr) orelse is_list(TDescr),
+ ?line true = is_pid(Proc) orelse Proc == undefined
+ end,
+ DAL),
+ ?line ASL = lists:map(fun ({_,A,S,_}) -> {A,S} end, AL),
+ ?line ASL = lists:map(fun ({_,A,S,_}) -> {A,S} end, DAL),
+ ?line instrument:holes(MDS),
+ ?line {comment,
+ "total status - sum of blocks = " ++ integer_to_list(S1-SumBlocks)}.
+
+'+Mis true'(doc) -> ["Check that memory data can be read and processed"];
+'+Mis true'(suite) -> [];
+'+Mis true'(Config) when is_list(Config) ->
+ ?line Node = start_slave("+Mis true"),
+ ?line [{total,[{sizes,S1,S2,S3},{blocks,B1,B2,B3}]}]
+ = rpc:call(Node, instrument, memory_status, [total]),
+ ?line true = S1 =< S2,
+ ?line true = S2 =< S3,
+ ?line true = B1 =< B2,
+ ?line true = B2 =< B3,
+ ?line true = is_list(rpc:call(Node,instrument,memory_status,[allocators])),
+ ?line true = is_list(rpc:call(Node,instrument,memory_status,[classes])),
+ ?line true = is_list(rpc:call(Node,instrument,memory_status,[types])),
+ ?line ok.
+
+start_slave(Args) ->
+ ?line {A, B, C} = now(),
+ ?line MicroSecs = A*1000000000000 + B*1000000 + C,
+ ?line Name = "instr_" ++ integer_to_list(MicroSecs),
+ ?line Pa = filename:dirname(code:which(?MODULE)),
+ ?line {ok, Node} = ?t:start_node(list_to_atom(Name),
+ slave,
+ [{args, "-pa " ++ Pa ++ " " ++ Args}]),
+ ?line Node.
+
+
+stop_slave(Node) ->
+ ?line true = ?t:stop_node(Node).
diff --git a/lib/tools/test/lcnt_SUITE.erl b/lib/tools/test/lcnt_SUITE.erl
new file mode 100644
index 0000000000..e6866f721d
--- /dev/null
+++ b/lib/tools/test/lcnt_SUITE.erl
@@ -0,0 +1,154 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 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(lcnt_SUITE).
+-include("test_server.hrl").
+
+%% Test server specific exports
+-export([all/1]).
+-export([init_per_suite/1, end_per_suite/1]).
+-export([init_per_testcase/2, end_per_testcase/2]).
+
+%% Test cases
+-export([
+ load_v1/1,
+ conflicts/1,
+ locations/1,
+ swap_keys/1
+ ]).
+
+%% Default timetrap timeout (set in init_per_testcase)
+-define(default_timeout, ?t:minutes(2)).
+
+init_per_suite(Config) when is_list(Config) ->
+ Config.
+
+end_per_suite(Config) when is_list(Config) ->
+ Config.
+
+init_per_testcase(_Case, Config) ->
+ Dog = ?t:timetrap(?default_timeout),
+ [{watchdog,Dog} | Config].
+
+end_per_testcase(_Case, Config) ->
+ Dog = ?config(watchdog, Config),
+ ?t:timetrap_cancel(Dog),
+ ok.
+
+all(suite) ->
+ % Test cases
+ [load_v1, conflicts, locations, swap_keys].
+
+%%----------------------------------------------------------------------
+%% Tests
+%%----------------------------------------------------------------------
+
+load_v1(suite) ->
+ [];
+load_v1(doc) ->
+ ["Load data from file."];
+load_v1(Config) when is_list(Config) ->
+ ?line {ok, _} = lcnt:start(),
+ ?line Path = ?config(data_dir, Config),
+ ?line File = filename:join([Path,"big_bang_40.lcnt"]),
+ ?line ok = lcnt:load(File),
+ ?line ok = lcnt:stop(),
+ ok.
+
+conflicts(suite) ->
+ [];
+conflicts(doc) ->
+ ["API: conflicts"];
+conflicts(Config) when is_list(Config) ->
+ ?line {ok, _} = lcnt:start(),
+ ?line Path = ?config(data_dir, Config),
+ ?line File = filename:join([Path,"big_bang_40.lcnt"]),
+ ?line ok = lcnt:load(File),
+ ?line ok = lcnt:conflicts(),
+ THs = [-1, 0, 100, 1000],
+ Print = [name , id , type , entry , tries , colls , ratio , time , duration],
+ Opts = [
+ [{sort, Sort}, {reverse, Rev}, {max_locks, ML}, {combine, Combine}, {thresholds, [TH]}, {print, [Print]}] ||
+ Sort <- [name , id , type , tries , colls , ratio , time , entry],
+ ML <- [none, 1 , 32, 4096],
+ Combine <- [true, false],
+ TH <- [{tries, Tries} || Tries <- THs] ++ [{colls, Colls} || Colls <- THs] ++ [{time, Time} || Time <- THs],
+ Rev <- [true, false]
+ ],
+ ?line ok = test_conflicts_opts(Opts),
+ ?line ok = lcnt:stop(),
+ ok.
+
+test_conflicts_opts([]) -> ok;
+test_conflicts_opts([Opt|Opts]) ->
+ ?line ok = lcnt:conflicts(Opt),
+ test_conflicts_opts(Opts).
+
+locations(suite) ->
+ [];
+locations(doc) ->
+ ["API: locations"];
+locations(Config) when is_list(Config) ->
+ ?line {ok, _} = lcnt:start(),
+ ?line Path = ?config(data_dir, Config),
+ ?line File = filename:join([Path,"big_bang_40.lcnt"]),
+ ?line ok = lcnt:load(File),
+ ?line ok = lcnt:locations(),
+ THs = [-1, 0, 100, 1000],
+ Print = [name , id , type , entry , tries , colls , ratio , time , duration],
+ Opts = [
+ [{full_id, Id}, {sort, Sort}, {max_locks, ML}, {combine, Combine}, {thresholds, [TH]}, {print, Print}] ||
+ Sort <- [name , id , type , tries , colls , ratio , time , entry],
+ ML <- [none, 1 , 64],
+ Combine <- [true, false],
+ TH <- [{tries, Tries} || Tries <- THs] ++ [{colls, Colls} || Colls <- THs] ++ [{time, Time} || Time <- THs],
+ Id <- [true, false]
+ ],
+ ?line ok = test_locations_opts(Opts),
+ ?line ok = lcnt:stop(),
+ ok.
+
+test_locations_opts([]) -> ok;
+test_locations_opts([Opt|Opts]) ->
+ ?line ok = lcnt:locations(Opt),
+ test_locations_opts(Opts).
+
+swap_keys(suite) ->
+ [];
+swap_keys(doc) ->
+ ["Test interchanging port/process id with class"];
+swap_keys(Config) when is_list(Config) ->
+ ?line {ok, _} = lcnt:start(),
+ ?line Path = ?config(data_dir, Config),
+ ?line File = filename:join([Path,"big_bang_40.lcnt"]),
+ ?line ok = lcnt:load(File),
+ ?line ok = lcnt:conflicts(),
+ ?line ok = lcnt:swap_pid_keys(),
+ ?line ok = lcnt:conflicts(),
+ ?line ok = lcnt:stop(),
+ ok.
+
+
+%%----------------------------------------------------------------------
+%% Auxiliary tests
+%%----------------------------------------------------------------------
+
+%%----------------------------------------------------------------------
+%% Auxiliary
+%%----------------------------------------------------------------------
diff --git a/lib/tools/test/lcnt_SUITE_data/big_bang_40.lcnt b/lib/tools/test/lcnt_SUITE_data/big_bang_40.lcnt
new file mode 100644
index 0000000000..6087f6f37e
--- /dev/null
+++ b/lib/tools/test/lcnt_SUITE_data/big_bang_40.lcnt
Binary files differ
diff --git a/lib/tools/test/make_SUITE.erl b/lib/tools/test/make_SUITE.erl
new file mode 100644
index 0000000000..72dccdb465
--- /dev/null
+++ b/lib/tools/test/make_SUITE.erl
@@ -0,0 +1,295 @@
+%%
+%% %CopyrightBegin%
+%%
+%% 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
+%% compliance with the License. You should have received a copy of the
+%% Erlang Public License along with this software. If not, it can be
+%% retrieved online at http://www.erlang.org/.
+%%
+%% Software distributed under the License is distributed on an "AS IS"
+%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+%% the License for the specific language governing rights and limitations
+%% under the License.
+%%
+%% %CopyrightEnd%
+%%
+-module(make_SUITE).
+
+-export([all/1, make_all/1, make_files/1]).
+-export([otp_6057_init/1,
+ otp_6057_a/1, otp_6057_b/1, otp_6057_c/1,
+ otp_6057_end/1]).
+
+-include("test_server.hrl").
+
+-include_lib("kernel/include/file.hrl").
+
+%% in ./make_SUITE_data there are test-files used by this
+%% test suite. There are 4 files named test1.erl ... test5.erl.
+%% The test files are attacked in various ways in order to put make on trial.
+%%
+%% Also, and Emakefile exists in ./make_SUITE_data. This file specifies
+%% that the file :"test5.erl" shall be compiled with the 'S' option,
+%% i.e. produce "test5.S" instead of "test5.<objext>"
+
+all(suite) -> [make_all, make_files,
+ {conf, otp_6057_init,
+ [otp_6057_a,otp_6057_b,otp_6057_c], otp_6057_end}].
+
+test_files() -> ["test1", "test2", "test3", "test4"].
+
+make_all(suite) -> [];
+make_all(Config) when is_list(Config) ->
+ ?line Current = prepare_data_dir(Config),
+ ?line up_to_date = make:all(),
+ ?line ok = ensure_exists(test_files()),
+ ?line ok = ensure_exists(["test5"],".S"), % Emakefile: [{test5,['S']}
+ ?line file:set_cwd(Current),
+ ?line ensure_no_messages(),
+ ok.
+
+make_files(suite) -> [];
+make_files(Config) when is_list(Config) ->
+ ?line Current = prepare_data_dir(Config),
+
+ %% Make files that exist.
+
+ ?line Files = [test1, test2],
+ ?line up_to_date = make:files(Files), % ok files
+ ?line ok = ensure_exists(Files),
+
+ ?line error = make:files([test1,test7]), % non existing file
+ ?line up_to_date = make:files([test1,test2],[debug_info]), % with option
+
+ ?line file:set_cwd(Current),
+ ?line ensure_no_messages(),
+ ok.
+
+
+%% Moves to the data directory of this suite, clean it from any object
+%% files (*.jam for a JAM emulator). Returns the previous directory.
+prepare_data_dir(Config) ->
+ ?line {ok, Current} = file:get_cwd(),
+ ?line {value, {data_dir, Dir}} = lists:keysearch(data_dir, 1, Config),
+ ?line file:set_cwd(Dir),
+ ?line {ok, Files} = file:list_dir("."),
+ ?line delete_obj(Files, code:objfile_extension()),
+ ?line ensure_no_messages(),
+ Current.
+
+delete_obj([File|Rest], ObjExt) ->
+ ?line case filename:extension(File) of
+ ObjExt -> file:delete(File);
+ ".S" -> file:delete(File);
+ _ -> ok
+ end,
+ ?line delete_obj(Rest, ObjExt);
+delete_obj([], _) ->
+ ok.
+
+
+
+%% Ensure that the given object files exists.
+ensure_exists(Names) ->
+ ensure_exists(Names, code:objfile_extension()).
+
+ensure_exists([Name|Rest], ObjExt) when is_atom(Name) ->
+ ensure_exists([atom_to_list(Name)|Rest], ObjExt);
+ensure_exists([Name|Rest], ObjExt) ->
+ case filelib:is_regular(Name++ObjExt) of
+ true ->
+ ensure_exists(Rest, ObjExt);
+ false ->
+ Name++ObjExt
+ end;
+ensure_exists([], _) ->
+ ok.
+
+otp_6057_init(Config) when is_list(Config) ->
+ ?line DataDir = ?config(data_dir, Config),
+ ?line PrivDir = ?config(priv_dir, Config),
+
+ %% Create the directories PrivDir/otp_6057/src1, /src2 and /ebin
+ Src1 = filename:join([PrivDir, otp_6057, src1]),
+ Src2 = filename:join([PrivDir, otp_6057, src2]),
+ Ebin = filename:join([PrivDir, otp_6057, ebin]),
+ ?line ok = file:make_dir(filename:join(PrivDir, otp_6057)),
+ ?line ok = file:make_dir(Src1),
+ ?line ok = file:make_dir(Src2),
+ ?line ok = file:make_dir(Ebin),
+
+ %% Copy test1.erl and test2.erl to src1, and test3.erl to src2
+ Test1orig = filename:join(DataDir, "test1.erl"),
+ Test2orig = filename:join(DataDir, "test2.erl"),
+ Test3orig = filename:join(DataDir, "test3.erl"),
+ Test1 = filename:join(Src1, "test1.erl"),
+ Test2 = filename:join(Src1, "test2.erl"),
+ Test3 = filename:join(Src2, "test3.erl"),
+ ?line {ok, _} = file:copy(Test1orig, Test1),
+ ?line {ok, _} = file:copy(Test2orig, Test2),
+ ?line {ok, _} = file:copy(Test3orig, Test3),
+
+ %% Create an Emakefile in src1
+ Emakefile = filename:join(Src1, "Emakefile"),
+ ?line {ok, Fd} = file:open(Emakefile, write),
+ ?line ok = io:write(Fd, {["test1.erl","test2","../src2/test3"],
+ [{outdir,"../ebin"}]}),
+ ?line ok = io:fwrite(Fd, ".~n", []),
+ ?line ok = file:close(Fd),
+
+ ?line ensure_no_messages(),
+ Config.
+
+otp_6057_a(suite) ->
+ [];
+otp_6057_a(doc) ->
+ ["Test that make:all/0 looks for object file in correct place"];
+otp_6057_a(Config) when is_list(Config) ->
+ ?line PrivDir = ?config(priv_dir, Config),
+
+ %% Go to src1, saving old CWD
+ ?line {ok, CWD} = file:get_cwd(),
+ Src1 = filename:join([PrivDir, otp_6057, src1]),
+ ?line ok = file:set_cwd(Src1),
+
+ %% Call make:all()
+ ?line up_to_date = make:all(),
+
+ %% Ensure that all beam files are created in the ebin directory
+ Ebin = filename:join([PrivDir, otp_6057, ebin]),
+ Test1 = filename:join(Ebin, test1),
+ Test2 = filename:join(Ebin, test2),
+ Test3 = filename:join(Ebin, test3),
+ case ensure_exists([Test1, Test2, Test3]) of
+ ok -> ok;
+ Missing ->
+ ?line ?t:fail({"missing beam file", Missing})
+ end,
+
+ %% Check creation date of test1.beam and make sure it is not
+ %% recompiled if make:all() is called again.
+ %% (Sleep a while, if the file is recompiled within a second then
+ %% mtime will be the same).
+ ?line {ok, FileInfo1} = file:read_file_info(Test1++".beam"),
+ Date1 = FileInfo1#file_info.mtime,
+ ?t:sleep(?t:seconds(2)),
+ ?line up_to_date = make:all(),
+ ?line {ok, FileInfo2} = file:read_file_info(Test1++".beam"),
+ case FileInfo2#file_info.mtime of
+ Date1 -> ok;
+ _Date2 ->
+ ?line ?t:fail({"recompiled beam file", Test1++".beam"})
+ end,
+
+ %% Remove the beam files
+ ?line ok =
+ ensure_removed([Test1++".beam",Test2++".beam",Test2++".beam"]),
+
+ %% Return to original CWD
+ ?line ok = file:set_cwd(CWD),
+
+ ?line ensure_no_messages(),
+ ok.
+
+otp_6057_b(suite) ->
+ [];
+otp_6057_b(doc) ->
+ ["Test that make:files/1 can handle a file in another directory"];
+otp_6057_b(Config) when is_list(Config) ->
+ ?line PrivDir = ?config(priv_dir, Config),
+
+ %% Go to src1, saving old CWD
+ ?line {ok, CWD} = file:get_cwd(),
+ Src1 = filename:join([PrivDir, otp_6057, src1]),
+ ?line ok = file:set_cwd(Src1),
+
+ %% Ensure there is no beam file already
+ Ebin = filename:join([PrivDir, otp_6057, ebin]),
+ Test3 = filename:join(Ebin, "test3"),
+ ?line ok = ensure_removed([Test3++".beam"]),
+
+ %% Call make:files/1
+ ?line up_to_date = make:files(["../src2/test3"]),
+
+ %% Ensure that the beam file is created in the ebin directory
+ case ensure_exists([Test3]) of
+ ok -> ok;
+ Missing ->
+ ?line ?t:fail({"missing beam file", Missing})
+ end,
+
+ %% Remove the beam file
+ ?line ok = ensure_removed([Test3++".beam"]),
+
+ %% Return to original CWD
+ ?line ok = file:set_cwd(CWD),
+
+ ?line ensure_no_messages(),
+ ok.
+
+otp_6057_c(suite) ->
+ [];
+otp_6057_c(doc) ->
+ ["Test that make:files/1 find options in Emakefile if a file is "
+ "given with the .erl extension there"];
+otp_6057_c(Config) when is_list(Config) ->
+ ?line PrivDir = ?config(priv_dir, Config),
+
+ %% Go to src1, saving old CWD
+ ?line {ok, CWD} = file:get_cwd(),
+ Src1 = filename:join([PrivDir, otp_6057, src1]),
+ ?line ok = file:set_cwd(Src1),
+
+ %% Ensure there are no beam files already
+ Ebin = filename:join([PrivDir, otp_6057, ebin]),
+ Test1 = filename:join(Ebin, "test1"),
+ Test2 = filename:join(Ebin, "test2"),
+ ?line ok = ensure_removed([Test1++".beam",Test2++".beam"]),
+
+ %% Call make:files/1
+ ?line up_to_date = make:files([test1, test2]),
+
+ %% Ensure that the beam files are created in the ebin directory
+ Ebin = filename:join([PrivDir, otp_6057, ebin]),
+ case ensure_exists([Test1, Test2]) of
+ ok -> ok;
+ Missing ->
+ ?line ?t:fail({"missing beam file", Missing})
+ end,
+
+ %% Remove the beam files
+ ?line ok = ensure_removed([Test1++".beam", Test2++".beam"]),
+
+ %% Return to original CWD
+ ?line ok = file:set_cwd(CWD),
+
+ ?line ensure_no_messages(),
+ ok.
+
+otp_6057_end(Config) when is_list(Config) ->
+ Config.
+
+ensure_removed([File|Files]) ->
+ file:delete(File),
+ ensure_removed(Files);
+ensure_removed([]) ->
+ ok.
+
+ensure_no_messages() ->
+ ensure_no_messages(0).
+
+ensure_no_messages(N) ->
+ receive
+ Any ->
+ io:format("Unexpected message: ~p", [Any]),
+ ensure_no_messages(N+1)
+ after 0 ->
+ case N of
+ 0 -> ok;
+ N -> ?t:fail()
+ end
+ end.
+
diff --git a/lib/tools/test/make_SUITE_data/Emakefile b/lib/tools/test/make_SUITE_data/Emakefile
new file mode 100644
index 0000000000..ae9abb3cbe
--- /dev/null
+++ b/lib/tools/test/make_SUITE_data/Emakefile
@@ -0,0 +1,20 @@
+%% ``The contents of this file are subject to the Erlang Public License,
+%% Version 1.1, (the "License"); you may not use this file except in
+%% compliance with the License. You should have received a copy of the
+%% Erlang Public License along with this software. If not, it can be
+%% retrieved via the world wide web at http://www.erlang.org/.
+%%
+%% Software distributed under the License is distributed on an "AS IS"
+%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+%% the License for the specific language governing rights and limitations
+%% under the License.
+%%
+%% The Initial Developer of the Original Code is Ericsson Utvecklings AB.
+%% Portions created by Ericsson are Copyright 1999, Ericsson Utvecklings
+%% AB. All Rights Reserved.''
+%%
+%% $Id$
+%%
+
+{test5,['S']}.
+'*'.
diff --git a/lib/tools/test/make_SUITE_data/test1.erl b/lib/tools/test/make_SUITE_data/test1.erl
new file mode 100644
index 0000000000..f4a133008e
--- /dev/null
+++ b/lib/tools/test/make_SUITE_data/test1.erl
@@ -0,0 +1,10 @@
+-module(test1).
+-copyright('Copyright (c) 1991-97 Ericsson Telecom AB').
+-vsn('$Revision: /main/release/2 $').
+-compile(export_all).
+
+f1() ->
+ true.
+
+f2() ->
+ true.
diff --git a/lib/tools/test/make_SUITE_data/test2.erl b/lib/tools/test/make_SUITE_data/test2.erl
new file mode 100644
index 0000000000..5845357c3e
--- /dev/null
+++ b/lib/tools/test/make_SUITE_data/test2.erl
@@ -0,0 +1,10 @@
+-module(test2).
+-copyright('Copyright (c) 1991-97 Ericsson Telecom AB').
+-vsn('$Revision: /main/release/2 $').
+-compile(export_all).
+
+f1() ->
+ true.
+
+f2() ->
+ true.
diff --git a/lib/tools/test/make_SUITE_data/test3.erl b/lib/tools/test/make_SUITE_data/test3.erl
new file mode 100644
index 0000000000..4339260ecb
--- /dev/null
+++ b/lib/tools/test/make_SUITE_data/test3.erl
@@ -0,0 +1,10 @@
+-module(test3).
+-copyright('Copyright (c) 1991-97 Ericsson Telecom AB').
+-vsn('$Revision: /main/release/2 $').
+-compile(export_all).
+
+f1() ->
+ true.
+
+f2() ->
+ true.
diff --git a/lib/tools/test/make_SUITE_data/test4.erl b/lib/tools/test/make_SUITE_data/test4.erl
new file mode 100644
index 0000000000..11b37123f1
--- /dev/null
+++ b/lib/tools/test/make_SUITE_data/test4.erl
@@ -0,0 +1,10 @@
+-module(test4).
+-copyright('Copyright (c) 1991-97 Ericsson Telecom AB').
+-vsn('$Revision: /main/release/2 $').
+-compile(export_all).
+
+f1() ->
+ true.
+
+f2() ->
+ true.
diff --git a/lib/tools/test/make_SUITE_data/test5.erl b/lib/tools/test/make_SUITE_data/test5.erl
new file mode 100644
index 0000000000..108ab8e494
--- /dev/null
+++ b/lib/tools/test/make_SUITE_data/test5.erl
@@ -0,0 +1,10 @@
+-module(test5).
+-copyright('Copyright (c) 1991-97 Ericsson Telecom AB').
+-vsn('$Revision: /main/release/1').
+-compile(export_all).
+
+f1() ->
+ true.
+
+f2() ->
+ true.
diff --git a/lib/tools/test/tools.spec b/lib/tools/test/tools.spec
new file mode 100644
index 0000000000..93d5930472
--- /dev/null
+++ b/lib/tools/test/tools.spec
@@ -0,0 +1 @@
+{topcase, {dir, "../tools_test"}}.
diff --git a/lib/tools/test/tools.spec.win b/lib/tools/test/tools.spec.win
new file mode 100644
index 0000000000..b43d542ff1
--- /dev/null
+++ b/lib/tools/test/tools.spec.win
@@ -0,0 +1,2 @@
+{topcase, {dir, "../tools_test"}}.
+{skip, {emem_SUITE, "Not on windows, yet. FIXME!!!"}}.
diff --git a/lib/tools/test/tools_SUITE.erl b/lib/tools/test/tools_SUITE.erl
new file mode 100644
index 0000000000..6b952f10ab
--- /dev/null
+++ b/lib/tools/test/tools_SUITE.erl
@@ -0,0 +1,56 @@
+%%
+%% %CopyrightBegin%
+%%
+%% 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(tools_SUITE).
+
+-include("test_server.hrl").
+
+%% Default timetrap timeout (set in init_per_testcase).
+-define(default_timeout, ?t:minutes(1)).
+-define(application, tools).
+
+%% Test server specific exports
+-export([all/1]).
+-export([init_per_testcase/2, fin_per_testcase/2]).
+
+%% Test cases must be exported.
+-export([app_test/1]).
+
+all(doc) ->
+ [];
+all(suite) ->
+ [app_test].
+
+init_per_testcase(_Case, Config) ->
+ ?line Dog=test_server:timetrap(?default_timeout),
+ [{watchdog, Dog}|Config].
+fin_per_testcase(_Case, Config) ->
+ Dog=?config(watchdog, Config),
+ test_server:timetrap_cancel(Dog),
+ ok.
+
+%%%
+%%% Test cases starts here.
+%%%
+
+app_test(doc) ->
+ ["Test that the .app file does not contain any `basic' errors"];
+app_test(suite) ->
+ [];
+app_test(Config) when is_list(Config) ->
+ ?line ?t:app_test(tools, tolerant).
diff --git a/lib/tools/test/xref_SUITE.erl b/lib/tools/test/xref_SUITE.erl
new file mode 100644
index 0000000000..b4684140ca
--- /dev/null
+++ b/lib/tools/test/xref_SUITE.erl
@@ -0,0 +1,2747 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 2000-2010. All Rights Reserved.
+%%
+%% The contents of this file are subject to the Erlang Public License,
+%% Version 1.1, (the "License"); you may not use this file except in
+%% compliance with the License. You should have received a copy of the
+%% Erlang Public License along with this software. If not, it can be
+%% retrieved online at http://www.erlang.org/.
+%%
+%% Software distributed under the License is distributed on an "AS IS"
+%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+%% the License for the specific language governing rights and limitations
+%% under the License.
+%%
+%% %CopyrightEnd%
+
+-module(xref_SUITE).
+
+%-define(debug, true).
+
+-ifdef(debug).
+-define(format(S, A), io:format(S, A)).
+-define(line, put(line, ?LINE), ).
+-define(config(X,Y), "./log_dir/").
+-define(t,test_server).
+-define(datadir, "xref_SUITE_data").
+-define(privdir, "xref_SUITE_priv").
+-define(copydir, "xref_SUITE_priv/datacopy").
+-else.
+-include("test_server.hrl").
+-define(format(S, A), ok).
+-define(datadir, ?config(data_dir, Conf)).
+-define(privdir, ?config(priv_dir, Conf)).
+-define(copydir, ?config(copy_dir, Conf)).
+-endif.
+
+-export([all/1, init/1, fini/1]).
+
+-export([xref/1,
+ addrem/1, convert/1, intergraph/1, lines/1, loops/1,
+ no_data/1, modules/1]).
+
+-export([files/1,
+ add/1, default/1, info/1, lib/1, read/1, read2/1, remove/1,
+ replace/1, update/1, deprecated/1, trycatch/1,
+ abstract_modules/1, fun_mfa/1, qlc/1]).
+
+-export([analyses/1,
+ analyze/1, basic/1, md/1, q/1, variables/1, unused_locals/1]).
+
+-export([misc/1,
+ format_error/1, otp_7423/1, otp_7831/1]).
+
+-import(lists, [append/2, flatten/1, keysearch/3, member/2, sort/1, usort/1]).
+
+-import(sofs, [converse/1, from_term/1, intersection/2, is_sofs_set/1,
+ range/1, relation_to_family/1, set/1, to_external/1,
+ union/2]).
+
+-export([init_per_testcase/2, fin_per_testcase/2]).
+
+%% Checks some info counters of a server and some relations that should hold.
+-export([check_count/1, check_state/1]).
+
+-include_lib("kernel/include/file.hrl").
+
+-include_lib("tools/src/xref.hrl").
+
+all(suite) ->
+ {conf, init, [xref, files, analyses, misc], fini}.
+
+init(Conf) when is_list(Conf) ->
+ DataDir = ?datadir,
+ PrivDir = ?privdir,
+ ?line CopyDir = fname(PrivDir, "datacopy"),
+ ?line TarFile = fname(PrivDir, "datacopy.tgz"),
+ ?line {ok, Tar} = erl_tar:open(TarFile, [write, compressed]),
+ ?line ok = erl_tar:add(Tar, DataDir, CopyDir, [compressed]),
+ ?line ok = erl_tar:close(Tar),
+ ?line ok = erl_tar:extract(TarFile, [compressed]),
+ ?line ok = file:delete(TarFile),
+ [{copy_dir, CopyDir} | Conf].
+
+fini(Conf) when is_list(Conf) ->
+ %% Nothing.
+ Conf.
+
+init_per_testcase(_Case, Config) ->
+ Dog=?t:timetrap(?t:minutes(2)),
+ [{watchdog, Dog}|Config].
+
+fin_per_testcase(_Case, _Config) ->
+ Dog=?config(watchdog, _Config),
+ test_server:timetrap_cancel(Dog),
+ ok.
+
+xref(suite) ->
+ [addrem, convert, intergraph, lines, loops, no_data, modules].
+
+%% Seems a bit short...
+addrem(suite) -> [];
+addrem(doc) -> ["Simple test of removing modules"];
+addrem(Conf) when is_list(Conf) ->
+ S0 = new(),
+
+ F1 = {m1,f1,1},
+ F2 = {m2,f1,2},
+
+ E1 = {F1,F2},
+ E2 = {F2,F1},
+
+ D1 = {F1,12},
+ DefAt_m1 = [D1],
+ X_m1 = [F1],
+ % L_m1 = [],
+ XC_m1 = [E1],
+ LC_m1 = [],
+ LCallAt_m1 = [],
+ XCallAt_m1 = [{E1,13}],
+ Info1 = #xref_mod{name = m1, app_name = [a1]},
+ ?line S1 = add_module(S0, Info1, DefAt_m1, X_m1, LCallAt_m1, XCallAt_m1,
+ XC_m1, LC_m1),
+
+ D2 = {F2,7},
+ DefAt_m2 = [D2],
+ X_m2 = [F2],
+ % L_m2 = [],
+ XC_m2 = [E2],
+ LC_m2 = [],
+ LCallAt_m2 = [],
+ XCallAt_m2 = [{E2,96}],
+ Info2 = #xref_mod{name = m2, app_name = [a2]},
+ ?line S2 = add_module(S1, Info2, DefAt_m2, X_m2, LCallAt_m2, XCallAt_m2,
+ XC_m2, LC_m2),
+
+ ?line S5 = set_up(S2),
+
+ ?line {ok, XMod1, S6} = remove_module(S5, m1),
+ ?line [a1] = XMod1#xref_mod.app_name,
+ ?line {ok, XMod2, S6a} = remove_module(S6, m2),
+ ?line [a2] = XMod2#xref_mod.app_name,
+ ?line S7 = set_up(S6a),
+
+ ?line AppInfo1 = #xref_app{name = a1, rel_name = [r1]},
+ ?line S9 = add_application(S7, AppInfo1),
+ ?line S10 = set_up(S9),
+ ?line AppInfo2 = #xref_app{name = a2, rel_name = [r1]},
+ ?line _S11 = add_application(S10, AppInfo2),
+ ok.
+
+convert(suite) -> [];
+convert(doc) -> ["Coercion of data"];
+convert(Conf) when is_list(Conf) ->
+ S0 = new(),
+
+ F1 = {m1,f1,1},
+ F6 = {m1,f2,6}, % X
+ F2 = {m2,f1,2},
+ F3 = {m2,f2,3}, % X
+ F7 = {m2,f3,7}, % X
+ F4 = {m3,f1,4}, % X
+ F5 = {m3,f2,5},
+
+ UF1 = {m1,f12,17},
+ UF2 = {m17,f17,177},
+
+ E1 = {F1,F3}, % X
+ E2 = {F6,F7}, % X
+ E3 = {F2,F6}, % X
+ E4 = {F1,F4}, % X
+ E5 = {F4,F5},
+ E6 = {F7,F4}, % X
+
+ UE1 = {F2,UF2}, % X
+ UE2 = {F5,UF1}, % X
+
+ D1 = {F1,12},
+ D6 = {F6,3},
+ DefAt_m1 = [D1,D6],
+ X_m1 = [F6],
+ % L_m1 = [F1],
+ XC_m1 = [E1,E2,E4],
+ LC_m1 = [],
+ LCallAt_m1 = [],
+ XCallAt_m1 = [{E1,13},{E2,17},{E4,7}],
+ Info1 = #xref_mod{name = m1, app_name = [a1]},
+ ?line S1 = add_module(S0, Info1, DefAt_m1, X_m1, LCallAt_m1, XCallAt_m1,
+ XC_m1, LC_m1),
+
+ D2 = {F2,7},
+ D3 = {F3,9},
+ D7 = {F7,19},
+ DefAt_m2 = [D2,D3,D7],
+ X_m2 = [F3,F7],
+ % L_m2 = [F2],
+ XC_m2 = [E3,E6,UE1],
+ LC_m2 = [],
+ LCallAt_m2 = [],
+ XCallAt_m2 = [{E3,96},{E6,12},{UE1,77}],
+ Info2 = #xref_mod{name = m2, app_name = [a2]},
+ ?line S2 = add_module(S1, Info2, DefAt_m2, X_m2, LCallAt_m2, XCallAt_m2,
+ XC_m2, LC_m2),
+
+ D4 = {F4,6},
+ D5 = {F5,97},
+ DefAt_m3 = [D4,D5],
+ X_m3 = [F4],
+ % L_m3 = [F5],
+ XC_m3 = [UE2],
+ LC_m3 = [E5],
+ LCallAt_m3 = [{E5,19}],
+ XCallAt_m3 = [{UE2,22}],
+ Info3 = #xref_mod{name = m3, app_name = [a3]},
+ ?line S3 = add_module(S2, Info3, DefAt_m3, X_m3, LCallAt_m3, XCallAt_m3,
+ XC_m3, LC_m3),
+
+ Info4 = #xref_mod{name = m4, app_name = [a2]},
+ ?line S4 = add_module(S3, Info4, [], [], [], [], [], []),
+
+ AppInfo1 = #xref_app{name = a1, rel_name = [r1]},
+ ?line S9 = add_application(S4, AppInfo1),
+ AppInfo2 = #xref_app{name = a2, rel_name = [r1]},
+ ?line S10 = add_application(S9, AppInfo2),
+ AppInfo3 = #xref_app{name = a3, rel_name = [r2]},
+ ?line S11 = add_application(S10, AppInfo3),
+
+ RelInfo1 = #xref_rel{name = r1},
+ ?line S12 = add_release(S11, RelInfo1),
+ RelInfo2 = #xref_rel{name = r2},
+ ?line S13 = add_release(S12, RelInfo2),
+
+ ?line S = set_up(S13),
+
+ ?line {ok, _} = eval("(Lin)(m1->m1:Mod) * m1->m1", type_error, S),
+ ?line {ok, _} = eval("(XXL)(Lin)(m1->m1:Mod) * m1->m1", type_error, S),
+
+ ?line AllDefAt = eval("(Lin) M", S),
+ ?line AllV = eval("(Fun) M", S),
+ ?line AllCallAt = eval("(XXL)(Lin) E", S),
+ ?line AllE = eval("E", S),
+
+ ?line AM = eval("AM", S),
+ ?line A = eval("A", S),
+ ?line R = eval("R", S),
+
+
+ % vertices
+ % general 1 step
+ ?line {ok, _} = eval("(Fun) (Lin) M", AllV, S),
+ ?line {ok, _} = eval("(Fun) (Lin) (Lin) M", AllV, S),
+ ?line {ok, _} = eval(f("(Fun) (Lin) ~p", [[F1, F3]]), [F1,F3], S),
+ ?line {ok, _} = eval(f("(Mod) ~p", [AllV]), [m1,m17,m2,m3], S),
+ ?line {ok, _} = eval(f("(Mod) ~p", [[F1,F3,F6]]), [m1,m2], S),
+ ?line {ok, _} = eval("(App) M", A, S),
+ ?line {ok, _} = eval(f("(App) ~p", [[m1,m2,m4]]), [a1,a2], S),
+ ?line {ok, _} = eval(f("(Rel) ~p", [A]), R, S),
+ ?line {ok, _} = eval(f("(Rel) ~p", [[a1,a2,a2]]), [r1], S),
+ % general 2 steps
+ ?line {ok, _} = eval("(Mod) (Lin) M", [m1,m17,m2,m3], S),
+ ?line {ok, _} = eval(f("(App) ~p", [AllV]), [a1,a2,a3], S),
+ ?line {ok, _} = eval("(Rel) M", R, S),
+ % general 4 steps
+ ?line {ok, _} = eval("(Rel) (Lin) M", [r1,r2], S),
+
+ % special 1 step
+ ?line {ok, _} = eval(f("(Lin) ~p", [AllV]), AllDefAt, S),
+ ?line {ok, _} = eval(f("(Lin) ~p", [[F1,F3]]), [{F1,12},{F3,9}], S),
+ ?line {ok, _} = eval("(Fun) M", AllV, S),
+ ?line {ok, _} = eval(f("(Fun) ~p", [[m1,m2]]), [F1,F2,F3,F6,F7,UF1], S),
+ ?line {ok, _} = eval(f("(Mod) ~p", [A]), AM, S),
+ ?line {ok, _} = eval(f("(Mod) ~p", [[a1,a2]]), [m1,m2,m4], S),
+ ?line {ok, _} = eval(f("(App) ~p", [R]), A, S),
+ ?line {ok, _} = eval(f("(App) ~p", [[r1]]), [a1,a2], S),
+ % special 2 steps
+ ?line {ok, _} = eval("(Lin) M", AllDefAt, S),
+ ?line AnalyzedV = eval("(Fun) AM", S),
+ ?line {ok, _} = eval(f("(Fun) ~p", [A]), AnalyzedV, S),
+ ?line {ok, _} = eval(f("(Mod) ~p", [R]), AM, S),
+ % special 4 steps
+ ?line AnalyzedAllDefAt = eval("(Lin) AM", S),
+ ?line {ok, _} = eval("(Lin) R", AnalyzedAllDefAt, S),
+
+ % edges
+ Ms = [{m1,m2},{m1,m3},{m2,m1},{m2,m3},{m3,m3}],
+ UMs = [{m2,m17},{m3,m1}],
+ AllMs = append(Ms, UMs),
+ As = [{a1,a2},{a1,a3},{a2,a1},{a2,a3},{a3,a3}],
+ Rs = [{r1,r1},{r1,r2},{r2,r2}],
+
+ % general 1 step
+ ?line {ok, _} = eval("(Fun) (Lin) E", AllE, S),
+ ?line {ok, _} = eval(f("(Fun)(Lin) ~p", [[E1, E6]]), [E1, E6], S),
+ ?line {ok, _} = eval("(Mod) E", AllMs, S),
+ ?line {ok, _} = eval(f("(Mod) ~p", [[E1, E6]]), [{m1,m2},{m2,m3}], S),
+ ?line {ok, _} = eval(f("(App) ~p", [As]), As, S),
+ ?line {ok, _} = eval("(App) [m1->m2,m2->m3]", [{a1,a2},{a2,a3}], S),
+ ?line {ok, _} = eval(f("(Rel) ~p", [As]), Rs, S),
+ ?line {ok, _} = eval("(Rel) a1->a2", [{r1,r1}], S),
+
+ % special 1 step
+ ?line {ok, _} = eval("(XXL) (Lin) (Fun) E", AllCallAt, S),
+ ?line {ok, _} = eval("(XXL) (XXL) (Lin) (Fun) E", AllCallAt, S),
+
+ ?line {ok, _} = eval(f("(XXL) (Lin) ~p", [[E1, E6]]),
+ [{{D1,D3},[13]}, {{D7,D4},[12]}], S),
+ ?line {ok, _} = eval(f("(Fun) ~p", [AllMs]), AllE, S),
+ ?line {ok, _} = eval("(Fun) [m1->m2,m2->m3]", [E1,E2,E6], S),
+ ?line {ok, _} = eval(f("(Mod) ~p", [As]), Ms, S),
+ ?line {ok, _} = eval("(Mod) [a1->a2,a2->a3]", [{m1,m2},{m2,m3}], S),
+ ?line {ok, _} = eval(f("(App) ~p", [Rs]), As, S),
+ ?line {ok, _} = eval("(App) r1->r1", [{a1,a2},{a2,a1}], S),
+ ok.
+
+intergraph(suite) -> [];
+intergraph(doc) -> ["Inter Call Graph"];
+intergraph(Conf) when is_list(Conf) ->
+ S0 = new(),
+
+ F1 = {m1,f1,1}, % X
+ F2 = {m1,f2,2}, % X
+ F3 = {m1,f3,3},
+ F4 = {m1,f4,4},
+ F5 = {m1,f5,5},
+
+ F6 = {m2,f1,6}, % X
+ F7 = {m2,f1,7},
+ F8 = {m2,f1,8},
+ F9 = {m2,f1,9},
+ F10 = {m2,f1,10},
+ F11 = {m2,f1,11},
+
+ % Note: E1 =:= E4!
+ E1 = {F2,F1},
+ E2 = {F2,F3},
+ E3 = {F3,F1},
+ E4 = {F2,F1}, % X
+ E5 = {F4,F2},
+ E6 = {F5,F4},
+ E7 = {F4,F5},
+
+ E8 = {F6,F7},
+ E9 = {F7,F8},
+ E10 = {F8,F1}, % X
+ E11 = {F6,F9},
+ E12 = {F6,F10},
+ E13 = {F9,F11},
+ E14 = {F10,F11},
+ E15 = {F11,F1}, % X
+
+ D1 = {F1,1},
+ D2 = {F2,2},
+ D3 = {F3,3},
+ D4 = {F4,4},
+ D5 = {F5,5},
+ DefAt_m1 = [D1,D2,D3,D4,D5],
+ X_m1 = [F1,F2],
+ % L_m1 = [F3,F4,F5],
+ XC_m1 = [E4],
+ LC_m1 = [E1,E2,E3,E5,E6,E7],
+ % Note: E1 and E4 together!
+ LCallAt_m1 = [{E1,1},{E2,2},{E3,3},{E5,5},{E6,6},{E7,7}],
+ XCallAt_m1 = [{E1,4}],
+ Info1 = #xref_mod{name = m1, app_name = [a1]},
+ ?line S1 = add_module(S0, Info1, DefAt_m1, X_m1, LCallAt_m1, XCallAt_m1,
+ XC_m1, LC_m1),
+
+ D6 = {F6,6},
+ D7 = {F7,7},
+ D8 = {F8,8},
+ D9 = {F9,9},
+ D10 = {F10,10},
+ D11 = {F11,11},
+ DefAt_m2 = [D6,D7,D8,D9,D10,D11],
+ X_m2 = [F6],
+ % L_m2 = [F7,F8,F9,F10,F11],
+ XC_m2 = [E10,E15],
+ LC_m2 = [E8,E9,E11,E12,E13,E14],
+ LCallAt_m2 = [{E8,8},{E9,9},{E11,11},{E12,12},{E13,13},{E14,14}],
+ XCallAt_m2 = [{E10,10},{E15,15}],
+ Info2 = #xref_mod{name = m2, app_name = [a2]},
+ ?line S2 = add_module(S1, Info2, DefAt_m2, X_m2, LCallAt_m2, XCallAt_m2,
+ XC_m2, LC_m2),
+
+ AppInfo1 = #xref_app{name = a1, rel_name = [r1]},
+ ?line S5 = add_application(S2, AppInfo1),
+ AppInfo2 = #xref_app{name = a2, rel_name = [r1]},
+ ?line S6 = add_application(S5, AppInfo2),
+
+ RelInfo = #xref_rel{name = r1},
+ ?line S7 = add_release(S6, RelInfo),
+
+ ?line S = set_up(S7),
+
+ ?line {ok, _} = eval("EE | m1", [E1,E5,E6,E7], S),
+ ?line {ok, _} = eval("EE | m2", [{F6,F1}], S),
+ ?line {ok, _} = eval("EE | m2 + EE | m2", [{F6,F1}], S),
+
+ ?line {ok, _} = eval("(Fun)(Lin)(E | m1)",
+ to_external(union(set(XC_m1), set(LC_m1))), S),
+ ?line {ok, _} = eval("(XXL)(ELin) (EE | m1)",
+ [{{D2,D1},[1,2,4]},{{D4,D2},[5]},{{D5,D4},[6]},{{D4,D5},[7]}],
+ S),
+ ?line {ok, _} = eval("(XXL)(ELin)(EE | m2)", [{{D6,D1},[8,11,12]}], S),
+ ?line {ok, _} = eval("(XXL)(ELin)(ELin)(EE | m2)",
+ [{{D6,D1},[8,11,12]}], S),
+
+ %% Combining graphs (equal or different):
+ ?line {ok, _} = eval("(XXL)(ELin)(EE | m2 + EE | m2)",
+ [{{D6,D1},[8,11,12]}], S),
+ ?line {ok, _} = eval("(XXL)(ELin)(EE | m2 * EE | m2)",
+ [{{D6,D1},[8,11,12]}], S),
+ ?line {ok, _} = eval("(XXL)(ELin)(EE | m2 - EE | m1)",
+ [{{D6,D1},[8,11,12]}], S),
+ ?line {ok, _} = eval("(XXL)(ELin)(EE | m2 - E | m2)",
+ [{{D6,D1},[8,11,12]}], S),
+ ?line {ok, _} = eval("(XXL)(ELin)(Fun)(ELin)(EE | m2)",
+ [{{D6,D1},[8,11,12]}], S),
+ ?line {ok, _} = eval("EE | m1 + E | m1", LC_m1, S),
+ ?line {ok, _} = eval(f("EE | ~p + E | ~p", [F2, F2]), [E1,E2], S),
+ %% [1,4] from 'calls' is a subset of [1,2,4] from Inter Call Graph:
+ ?line {ok, _} = eval(f("(XXL)(Lin) (E | ~p)", [F2]),
+ [{{D2,D1},[1,4]},{{D2,D3},[2]}], S),
+
+ ?line {ok, _} = eval(f("(XXL)(ELin) (EE | ~p)", [F2]),
+ [{{D2,D1},[1,2,4]}], S),
+ ?line {ok, _} = eval(f("(XXL)((ELin)(EE | ~p) + (Lin)(E | ~p))", [F2, F2]),
+ [{{D2,D1},[1,2,4]},{{D2,D3},[2]}], S),
+ ?line {ok, _} =
+ eval(f("(XXL)((ELin) ~p + (Lin) ~p)", [{F2, F1}, {F2, F1}]),
+ [{{D2,D1},[1,2,4]}], S),
+ ?line {ok, _} = eval(f("(Fun)(Lin) ~p", [{F2, F1}]), [E1], S),
+ %% The external call E4 is included in the reply:
+ ?line {ok, _} = eval("(XXL)(Lin)(LC | m1)",
+ [{{D2,D1},[1,4]},{{D2,D3},[2]},{{D3,D1},[3]},
+ {{D4,D2},[5]},{{D4,D5},[7]},{{D5,D4},[6]}], S),
+ %% The local call E1 is included in the reply:
+ ?line {ok, _} = eval("(XXL)(Lin)(XC | m1)", [{{D2,D1},[1,4]}], S),
+
+ ?line {ok, _} = eval(f("(LLin) (E | ~p || ~p) + (XLin) (E | ~p || ~p)",
+ [F2, F1, F2, F1]), [{E4,[1,4]}], S),
+
+ ?line {ok, _} = eval("# (ELin) E", 6, S),
+
+ ok.
+
+lines(suite) -> [];
+lines(doc) -> ["More test of Inter Call Graph, and regular expressions"];
+lines(Conf) when is_list(Conf) ->
+ S0 = new(),
+
+ F1 = {m1,f1,1}, % X
+ F2 = {m1,f2,2},
+ F3 = {m1,f3,3},
+ F4 = {m2,f4,4}, % X
+ F5 = {m1,f5,5}, % X
+ F6 = {m1,f6,6},
+
+ E1 = {F1,F2},
+ E2 = {F2,F1}, % X
+ E3 = {F3,F2},
+ E4 = {F1,F4}, % X
+ E5 = {F2,F4}, % X
+ E6 = {F5,F6},
+ E7 = {F6,F4}, % X
+
+ D1 = {F1,1},
+ D2 = {F2,2},
+ D3 = {F3,3},
+ D4 = {F4,4},
+ D5 = {F5,5},
+ D6 = {F6,6},
+
+ DefAt_m1 = [D1,D2,D3,D5,D6],
+ X_m1 = [F1,F5],
+ % L_m1 = [F2,F3,F6],
+ XC_m1 = [E4,E5,E7],
+ LC_m1 = [E1,E2,E3,E6],
+ LCallAt_m1 = [{E1,1},{E3,3},{E6,6}],
+ XCallAt_m1 = [{E2,2},{E4,4},{E5,5},{E7,7}],
+ Info1 = #xref_mod{name = m1, app_name = [a1]},
+ ?line S1 = add_module(S0, Info1, DefAt_m1, X_m1, LCallAt_m1, XCallAt_m1,
+ XC_m1, LC_m1),
+
+ DefAt_m2 = [D4],
+ X_m2 = [F4],
+ % L_m2 = [],
+ XC_m2 = [],
+ LC_m2 = [],
+ LCallAt_m2 = [],
+ XCallAt_m2 = [],
+ Info2 = #xref_mod{name = m2, app_name = [a2]},
+ ?line S2 = add_module(S1, Info2, DefAt_m2, X_m2, LCallAt_m2, XCallAt_m2,
+ XC_m2, LC_m2),
+
+ AppInfo1 = #xref_app{name = a1, rel_name = [r1]},
+ ?line S5 = add_application(S2, AppInfo1),
+ AppInfo2 = #xref_app{name = a2, rel_name = [r1]},
+ ?line S6 = add_application(S5, AppInfo2),
+
+ RelInfo = #xref_rel{name = r1},
+ ?line S7 = add_release(S6, RelInfo),
+
+ ?line S = set_up(S7),
+
+ ?line {ok, _} = eval("(XXL) (ELin) (EE | m1)",
+ [{{D1,D1},[1]},{{D1,D4},[1,4]},{{D3,D1},[3]},{{D3,D4},[3]},
+ {{D5,D4},[6]}], S),
+ ?line {ok, _} = eval("(XXL)(Lin) (E | m1)",
+ [{{D1,D2},[1]},{{D1,D4},[4]},{{D2,D1},[2]},
+ {{D2,D4},[5]},{{D3,D2},[3]},{{D5,D6},[6]},{{D6,D4},[7]}],
+ S),
+ ?line {ok, _} = eval("(E | m1) + (EE | m1)",
+ [E1,E2,E3,E4,E5,E6,E7,{F1,F1},{F3,F1},{F3,F4},{F5,F4}],
+ S),
+ ?line {ok, _} = eval("(Lin)(E | m1)",
+ [{E4,[4]},{E1,[1]},{E2,[2]},{E5,[5]},
+ {E3,[3]},{E7,[7]},{E6,[6]}], S),
+ ?line {ok, _} = eval("(ELin)(EE | m1)",
+ [{{F1,F1},[1]},{{F1,F4},[1,4]},{{F3,F1},[3]},{{F3,F4},[3]},
+ {{F5,F4},[6]}], S),
+ ?line {ok, _} = eval("(Lin)(E | m1) + (ELin)(EE | m1)",
+ [{E4,[1,4]},{E1,[1]},{E2,[2]},{E5,[5]},
+ {E3,[3]},{E7,[7]},{E6,[6]},
+ {{F1,F1},[1]},{{F3,F1},[3]},{{F3,F4},[3]},
+ {{F5,F4},[6]}], S),
+ ?line {ok, _} = eval("(Lin)(E | m1) - (ELin)(EE | m1)",
+ [{E1,[1]},{E2,[2]},{E5,[5]},
+ {E3,[3]},{E7,[7]},{E6,[6]}], S),
+ ?line {ok, _} = eval("(Lin)(E | m1) * (ELin)(EE | m1)",
+ [{E4,[4]}], S),
+ ?line {ok, _} = eval("(XXL)(Lin) (E | m1)",
+ [{{D1,D4},[4]},{{D1,D2},[1]},{{D2,D1},[2]},{{D2,D4},[5]},
+ {{D3,D2},[3]},{{D6,D4},[7]},{{D5,D6},[6]}], S),
+ ?line {ok, _} = eval("(XXL)(ELin) (EE | m1)",
+ [{{D1,D1},[1]},{{D1,D4},[1,4]},{{D3,D1},[3]},{{D3,D4},[3]},
+ {{D5,D4},[6]}], S),
+ ?line {ok, _} = eval("(XXL)(Lin)(Fun)(Lin) (E | m1)",
+ [{{D1,D4},[4]},{{D1,D2},[1]},{{D2,D1},[2]},{{D2,D4},[5]},
+ {{D3,D2},[3]},{{D6,D4},[7]},{{D5,D6},[6]}], S),
+ ?line {ok, _} = eval("(XXL)(ELin)(Fun)(ELin) (EE | m1)",
+ [{{D1,D1},[1]},{{D1,D4},[1,4]},{{D3,D1},[3]},{{D3,D4},[3]},
+ {{D5,D4},[6]}], S),
+
+ %% A few tests on regexp.
+ ?line {ok, _} = eval("\"(foo\":Mod", parse_error, S),
+ ?line {ok, _} = eval("_Foo:_/_", parse_error, S),
+ ?line {ok, _} = eval("\".*foo\"", parse_error, S),
+ ?line {ok, _} = eval("_:_/_:Lin", parse_error, S),
+ ?line {ok, _} = eval("_:_/_:Mod", parse_error, S),
+ ?line {ok, _} = eval("_:_/_:App", parse_error, S),
+ ?line {ok, _} = eval("_:_/_:Rel", parse_error, S),
+ ?line {ok, _} = eval("m2:_/4", [F4], S),
+ ?line {ok, _} = eval("m2:_/4:Fun", [F4], S),
+ ?line {ok, _} = eval("\"m.?\":\"f.*\"/\"6\"", [F6], S),
+ ?line {ok, _} = eval("_:_/6", [F6], S),
+ ?line {ok, _} = eval("m1:\"f1\"/_", [F1], S),
+ ?line {ok, _} = eval("\"m1\":f1/_", [F1], S),
+ ?line {ok, _} = eval("\"m1\":Mod", [m1], S),
+ ?line {ok, _} = eval("\"a1\":App", [a1], S),
+ ?line {ok, _} = eval("\"r1\":Rel", [r1], S),
+ ?line {ok, _} = eval("_:_/-1", [], S),
+
+ ok.
+
+loops(suite) -> [];
+loops(doc) -> ["More Inter Call Graph, loops and \"unusual\" cases"];
+loops(Conf) when is_list(Conf) ->
+ S0 = new(),
+
+ F1 = {m1,f1,1}, % X
+ F2 = {m1,f2,2},
+ F3 = {m1,f3,3}, % X
+ F4 = {m1,f4,4},
+ F5 = {m1,f5,5},
+ F6 = {m1,f1,6}, % X
+ F7 = {m1,f1,7},
+
+ E1 = {F1,F1}, % X
+ E2 = {F2,F2},
+ E3 = {F3,F4},
+ E4 = {F4,F5},
+ E5 = {F5,F3}, % X
+
+ D1 = {F1,1},
+ D2 = {F2,2},
+ D3 = {F3,3},
+ D4 = {F4,4},
+ D5 = {F5,5},
+ D6 = {F6,6},
+ D7 = {F7,7},
+ DefAt_m1 = [D1,D2,D3,D4,D5,D6,D7],
+ X_m1 = [F1,F3,F6],
+ % L_m1 = [F2,F4,F5],
+ XC_m1 = [],
+ LC_m1 = [E1,E2,E3,E4,E5],
+ LCallAt_m1 = [{E2,2},{E3,3},{E4,4}],
+ XCallAt_m1 = [{E1,1},{E5,5}],
+ Info1 = #xref_mod{name = m1, app_name = [a1]},
+ ?line S1 = add_module(S0, Info1, DefAt_m1, X_m1, LCallAt_m1, XCallAt_m1,
+ XC_m1, LC_m1),
+
+ ?line S = set_up(S1),
+
+ % Neither F6 nor F7 is included. Perhaps one should change that?
+ ?line {ok, _} = eval("EE | m1", [E1,E2,{F3,F3}], S),
+ ?line {ok, _} = eval(f("(XXL)(ELin) (EE | ~p)", [F3]), [{{D3,D3},[3]}], S),
+
+ ?line {ok, _} = eval("m1->m1 | m1->m1", type_error, S),
+ ?line {ok, _} = eval(f("~p | ~p", [F2, F1]), type_error, S),
+
+ ?line {ok, _} = eval(f("range (closure EE | ~p)", [F1]), [F1], S),
+ ?line {ok, _} = eval(f("domain (closure EE || ~p)", [F3]), [F3], S),
+
+ ?line {ok, _} = eval(f("domain (closure E || ~p)", [F3]), [F3,F4,F5], S),
+
+ ?line {ok, _} = eval("components E", [[F1],[F2],[F3,F4,F5]], S),
+ ?line {ok, _} = eval("components EE", [[F1],[F2],[F3]], S),
+
+ ok.
+
+no_data(suite) -> [];
+no_data(doc) -> ["Simple tests when there is no data"];
+no_data(Conf) when is_list(Conf) ->
+ S0 = new(),
+ ?line S1 = set_up(S0),
+ ?line {ok, _} = eval("M", [], S1),
+ ?line {ok, _} = eval("A", [], S1),
+ ?line {ok, _} = eval("R", [], S1),
+
+ ModInfo = #xref_mod{name = m, app_name = []},
+ ?line S2 = add_module(S1, ModInfo, [], [], [], [], [], []),
+ AppInfo = #xref_app{name = a, rel_name = []},
+ ?line S3 = add_application(S2, AppInfo),
+ RelInfo = #xref_rel{name = r, dir = ""},
+ ?line S4 = add_release(S3, RelInfo),
+ ?line S5 = set_up(S4),
+ ?line {ok, _} = eval("M", [m], S5),
+ ?line {ok, _} = eval("A", [a], S5),
+ ?line {ok, _} = eval("R", [r], S5),
+ ok.
+
+modules(suite) -> [];
+modules(doc) -> ["Modules mode"];
+modules(Conf) when is_list(Conf) ->
+ CopyDir = ?copydir,
+ Dir = fname(CopyDir, "rel2"),
+ X = fname(Dir, "x.erl"),
+ Y = fname(Dir, "y.erl"),
+ A1_1 = fname([Dir,"lib","app1-1.1"]),
+ A2 = fname([Dir,"lib","app2-1.1"]),
+ EB1_1 = fname(A1_1, "ebin"),
+ EB2 = fname(A2, "ebin"),
+ Xbeam = fname(EB2, "x.beam"),
+ Ybeam = fname(EB1_1, "y.beam"),
+
+ ?line {ok, x} = compile:file(X, [debug_info, {outdir,EB2}]),
+ ?line {ok, y} = compile:file(Y, [debug_info, {outdir,EB1_1}]),
+
+ ?line {ok, S0} = xref_base:new([{xref_mode, modules}]),
+ ?line {ok, release2, S1} =
+ xref_base:add_release(S0, Dir, [{name,release2}]),
+ ?line S = set_up(S1),
+ ?line {{error, _, {unavailable_analysis, undefined_function_calls}}, _} =
+ xref_base:analyze(S, undefined_function_calls),
+ ?line {{error, _, {unavailable_analysis, locals_not_used}}, _} =
+ xref_base:analyze(S, locals_not_used),
+ ?line {{error, _, {unavailable_analysis, {call, foo}}}, _} =
+ xref_base:analyze(S, {call, foo}),
+ ?line {{error, _, {unavailable_analysis, {use, foo}}}, _} =
+ xref_base:analyze(S, {use, foo}),
+ ?line analyze(undefined_functions, [{x,undef,0}], S),
+ ?line 5 = length(xref_base:info(S)),
+
+ %% More: all info, conversions.
+
+ ?line ok = file:delete(Xbeam),
+ ?line ok = file:delete(Ybeam),
+ ?line ok = xref_base:delete(S),
+ ok.
+
+files(suite) ->
+ [add, default, info, lib, read, read2, remove, replace, update,
+ deprecated, trycatch, abstract_modules, fun_mfa, qlc].
+
+add(suite) -> [];
+add(doc) -> ["Add modules, applications, releases, directories"];
+add(Conf) when is_list(Conf) ->
+ CopyDir = ?copydir,
+ Dir = fname(CopyDir, "rel2"),
+ UDir = fname([CopyDir,"dir","unreadable"]),
+ DDir = fname(CopyDir,"dir"),
+ UFile = fname([DDir, "dir","unreadable.beam"]),
+ X = fname(Dir, "x.erl"),
+ Y = fname(Dir, "y.erl"),
+ A1_1 = fname([Dir,"lib","app1-1.1"]),
+ A2 = fname([Dir,"lib","app2-1.1"]),
+ EB1_1 = fname(A1_1, "ebin"),
+ EB2 = fname(A2, "ebin"),
+ Xbeam = fname(EB2, "x.beam"),
+ Ybeam = fname(EB1_1, "y.beam"),
+
+ ?line {ok, x} = compile:file(X, [debug_info, {outdir,EB2}]),
+ ?line {ok, y} = compile:file(Y, [debug_info, {outdir,EB1_1}]),
+
+ ?line case os:type() of
+ {unix, _} ->
+ ?line make_udir(UDir),
+ ?line make_ufile(UFile);
+ _ ->
+ true
+ end,
+
+ ?line {error, _, {invalid_options,[not_an_option] }} =
+ xref_base:new([not_an_option]),
+ ?line {error, _, {invalid_options,[{verbose,not_a_value}] }} =
+ xref_base:new([{verbose,not_a_value}]),
+ ?line S = new(),
+ ?line {error, _, {invalid_options,[not_an_option]}} =
+ xref_base:set_up(S, [not_an_option]),
+ ?line {error, _, {invalid_options,[{builtins,true},not_an_option]}} =
+ xref_base:add_directory(S, foo, [{builtins,true},not_an_option]),
+ ?line {error, _, {invalid_options,[{builtins,not_a_value}]}} =
+ xref_base:add_directory(S, foo, [{builtins,not_a_value}]),
+ ?line {error, _, {invalid_filename,{foo,bar}}} =
+ xref_base:add_directory(S, {foo,bar}, []),
+ ?line {error, _, {invalid_options,[{builtins,true},not_an_option]}} =
+ xref_base:add_module(S, foo, [{builtins,true},not_an_option]),
+ ?line {error, _, {invalid_options,[{builtins,not_a_value}]}} =
+ xref_base:add_module(S, foo, [{builtins,not_a_value}]),
+ ?line {error, _, {invalid_filename,{foo,bar}}} =
+ xref_base:add_module(S, {foo,bar}, []),
+ ?line {error, _, {invalid_options,[{builtins,true},not_an_option]}} =
+ xref_base:add_application(S, foo, [{builtins,true},not_an_option]),
+ ?line {error, _, {invalid_options,[{builtins,not_a_value}]}} =
+ xref_base:add_application(S, foo, [{builtins,not_a_value}]),
+ ?line {error, _, {invalid_filename,{foo,bar}}} =
+ xref_base:add_application(S, {foo,bar}, []),
+ ?line {error, _, {invalid_options,[not_an_option]}} =
+ xref_base:add_release(S, foo, [not_an_option]),
+ ?line {error, _, {invalid_options,[{builtins,not_a_value}]}} =
+ xref_base:add_release(S, foo, [{builtins,not_a_value}]),
+ ?line {error, _, {invalid_filename,{foo,bar}}} =
+ xref_base:add_release(S, {foo,bar}, []),
+ ?line {ok, S1} =
+ xref_base:set_default(S, [{verbose,false}, {warnings, false}]),
+ ?line case os:type() of
+ {unix, _} ->
+ ?line {error, _, {file_error, _, _}} =
+ xref_base:add_release(S, UDir);
+ _ ->
+ true
+ end,
+ ?line {error, _, {file_error, _, _}} =
+ xref_base:add_release(S, fname(["/a/b/c/d/e/f","__foo"])),
+ ?line {ok, release2, S2} =
+ xref_base:add_release(S1, Dir, [{name,release2}]),
+ ?line {error, _, {module_clash, {x, _, _}}} =
+ xref_base:add_module(S2, Xbeam),
+ ?line {ok, S3} = xref_base:remove_release(S2, release2),
+ ?line {ok, rel2, S4} = xref_base:add_release(S3, Dir),
+ ?line {error, _, {release_clash, {rel2, _, _}}} =
+ xref_base:add_release(S4, Dir),
+ ?line {ok, S5} = xref_base:remove_release(S4, rel2),
+ %% One unreadable file and one JAM file found (no verification here):
+ ?line {ok, [], S6} = xref_base:add_directory(S5, fname(CopyDir,"dir"),
+ [{recurse,true}, {warnings,true}]),
+ ?line case os:type() of
+ {unix, _} ->
+ ?line {error, _, {file_error, _, _}} =
+ xref_base:add_directory(S6, UDir);
+ _ ->
+ true
+ end,
+ ?line {ok, app1, S7} = xref_base:add_application(S6, A1_1),
+ ?line {error, _, {application_clash, {app1, _, _}}} =
+ xref_base:add_application(S7, A1_1),
+ ?line {ok, S8} = xref_base:remove_application(S7, app1),
+ ?line ok = xref_base:delete(S8),
+ ?line ok = file:delete(Xbeam),
+ ?line ok = file:delete(Ybeam),
+ ?line case os:type() of
+ {unix, _} ->
+ ?line ok = file:del_dir(UDir),
+ ?line ok = file:delete(UFile);
+ _ ->
+ true
+ end,
+ ok.
+
+default(suite) -> [];
+default(doc) -> ["Default values of options"];
+default(Conf) when is_list(Conf) ->
+ S = new(),
+ ?line {error, _, {invalid_options,[not_an_option]}} =
+ xref_base:set_default(S, not_an_option, true),
+ ?line {error, _, {invalid_options,[{builtins, not_a_value}]}} =
+ xref_base:set_default(S, builtins, not_a_value),
+ ?line {error, _, {invalid_options,[not_an_option]}} =
+ xref_base:get_default(S, not_an_option),
+ ?line {error, _, {invalid_options,[not_an_option]}} =
+ xref_base:set_default(S, [not_an_option]),
+
+ ?line D = xref_base:get_default(S),
+ ?line [{builtins,false},{recurse,false},{verbose,false},{warnings,true}] =
+ D,
+
+ ?line ok = xref_base:delete(S),
+ ok.
+
+info(suite) -> [];
+info(doc) -> ["The info functions"];
+info(Conf) when is_list(Conf) ->
+ CopyDir = ?copydir,
+ Dir = fname(CopyDir,"rel2"),
+ LDir = fname(CopyDir,"lib_test"),
+ X = fname(Dir, "x.erl"),
+ Y = fname(Dir, "y.erl"),
+ A1_1 = fname([Dir,"lib","app1-1.1"]),
+ A2 = fname([Dir,"lib","app2-1.1"]),
+ EB1_1 = fname(A1_1, "ebin"),
+ EB2 = fname(A2, "ebin"),
+ Xbeam = fname(EB2, "x.beam"),
+ Ybeam = fname(EB1_1, "y.beam"),
+
+ ?line {ok, x} = compile:file(X, [debug_info, {outdir,EB2}]),
+ ?line {ok, y} = compile:file(Y, [debug_info, {outdir,EB1_1}]),
+
+ ?line {ok, _} = start(s),
+ ?line {error, _, {no_such_info, release}} = xref:info(s, release),
+ ?line {error, _, {no_such_info, release}} = xref:info(s, release, rel),
+ ?line {error, _, {no_such_module, mod}} = xref:info(s, modules, mod),
+ ?line {error, _, {no_such_application, app}} =
+ xref:info(s, applications, app),
+ ?line {error, _, {no_such_release, rel}} = xref:info(s, releases, rel),
+ ?line ok = xref:set_default(s, [{verbose,false}, {warnings, false}]),
+ ?line {ok, rel2} = xref:add_release(s, Dir),
+ ?line 9 = length(xref:info(s)),
+ ?line [{x,_}, {y, _}] = xref:info(s, modules),
+ ?line [{app1,_}, {app2, _}] = xref:info(s, applications),
+ ?line [{rel2,_}] = xref:info(s, releases),
+ ?line [] = xref:info(s, libraries),
+ ?line [{x,_}] = xref:info(s, modules, x),
+ ?line [{rel2,_}] = xref:info(s, releases, rel2),
+ ?line {error, _, {no_such_library, foo}} = xref:info(s, libraries, [foo]),
+
+ ?line {ok, lib1} =
+ compile:file(fname(LDir,lib1),[debug_info,{outdir,LDir}]),
+ ?line {ok, lib2} =
+ compile:file(fname(LDir,lib2),[debug_info,{outdir,LDir}]),
+ ?line ok = xref:set_library_path(s, [LDir], [{verbose,false}]),
+ ?line [{lib1,_}, {lib2, _}] = xref:info(s, libraries),
+ ?line [{lib1,_}, {lib2, _}] = xref:info(s, libraries, [lib1,lib2]),
+ ?line ok = file:delete(fname(LDir, "lib1.beam")),
+ ?line ok = file:delete(fname(LDir, "lib2.beam")),
+
+ ?line check_state(s),
+
+ ?line xref:stop(s),
+
+ ?line ok = file:delete(Xbeam),
+ ?line ok = file:delete(Ybeam),
+
+ ok.
+
+lib(suite) -> [];
+lib(doc) -> ["Library modules"];
+lib(Conf) when is_list(Conf) ->
+ CopyDir = ?copydir,
+ Dir = fname(CopyDir,"lib_test"),
+ UDir = fname([CopyDir,"dir","non_existent"]),
+
+ ?line {ok, lib1} = compile:file(fname(Dir,lib1),[debug_info,{outdir,Dir}]),
+ ?line {ok, lib2} = compile:file(fname(Dir,lib2),[debug_info,{outdir,Dir}]),
+ ?line {ok, lib3} = compile:file(fname(Dir,lib3),[debug_info,{outdir,Dir}]),
+ ?line {ok, t} = compile:file(fname(Dir,t),[debug_info,{outdir,Dir}]),
+
+ ?line {ok, _} = start(s),
+ ?line ok = xref:set_default(s, [{verbose,false}, {warnings, false}]),
+ ?line {ok, t} = xref:add_module(s, fname(Dir,"t.beam")),
+ ?line {error, _, {invalid_options,[not_an_option]}} =
+ xref:set_library_path(s, ["foo"], [not_an_option]),
+ ?line {error, _, {invalid_path,otp}} = xref:set_library_path(s,otp),
+ ?line {error, _, {invalid_path,[""]}} = xref:set_library_path(s,[""]),
+ ?line {error, _, {invalid_path,[[$a | $b]]}} =
+ xref:set_library_path(s,[[$a | $b]]),
+ ?line {error, _, {invalid_path,[otp]}} = xref:set_library_path(s,[otp]),
+ ?line {ok, []} = xref:get_library_path(s),
+ ?line ok = xref:set_library_path(s, [Dir], [{verbose,false}]),
+ ?line {ok, UnknownFunctions} = xref:q(s, "U"),
+ ?line [{lib1,unknown,0}, {lib2,local,0},
+ {lib2,unknown,0}, {unknown,unknown,0}]
+ = UnknownFunctions,
+ ?line {ok, [{lib2,f,0},{lib3,f,0}]} = xref:q(s, "DF"),
+ ?line {ok, []} = xref:q(s, "DF_1"),
+ ?line {ok, [{lib2,f,0}]} = xref:q(s, "DF_2"),
+ ?line {ok, [{lib2,f,0}]} = xref:q(s, "DF_3"),
+
+ ?line {ok, [unknown]} = xref:q(s, "UM"),
+ ?line {ok, UnknownDefAt} = xref:q(s, "(Lin)U"),
+ ?line [{{lib1,unknown,0},0},{{lib2,local,0},0}, {{lib2,unknown,0},0},
+ {{unknown,unknown,0},0}] = UnknownDefAt,
+ ?line {ok, LibFuns} = xref:q(s, "X * LM"),
+ ?line [{lib2,f,0},{lib3,f,0}] = LibFuns,
+ ?line {ok, LibMods} = xref:q(s, "LM"),
+ ?line [lib1,lib2,lib3] = LibMods,
+ ?line {ok, [{{lib2,f,0},0},{{lib3,f,0},0}]} = xref:q(s, "(Lin) (LM * X)"),
+ ?line {ok, [{{lib1,unknown,0},0}, {{lib2,f,0},0}, {{lib2,local,0},0},
+ {{lib2,unknown,0},0}, {{lib3,f,0},0}]} = xref:q(s,"(Lin)LM"),
+ ?line {ok,[lib1,lib2,lib3,t,unknown]} = xref:q(s,"M"),
+ ?line {ok,[{lib2,f,0},{lib3,f,0},{t,t,0}]} = xref:q(s,"X * M"),
+ ?line check_state(s),
+
+ ?line copy_file(fname(Dir, "lib1.erl"), fname(Dir,"lib1.beam")),
+ ?line ok = xref:set_library_path(s, [Dir]),
+ ?line {error, _, _} = xref:q(s, "U"),
+
+ %% OTP-3921. AM and LM not always disjoint.
+ ?line {ok, lib1} = compile:file(fname(Dir,lib1),[debug_info,{outdir,Dir}]),
+ ?line {ok, lib1} = xref:add_module(s, fname(Dir,"lib1.beam")),
+ ?line check_state(s),
+
+ ?line {error, _, {file_error, _, _}} = xref:set_library_path(s, [UDir]),
+
+ ?line xref:stop(s),
+ ?line ok = file:delete(fname(Dir, "lib1.beam")),
+ ?line ok = file:delete(fname(Dir, "lib2.beam")),
+ ?line ok = file:delete(fname(Dir, "lib3.beam")),
+ ?line ok = file:delete(fname(Dir, "t.beam")),
+
+ ?line {ok, cp} = compile:file(fname(Dir,cp),[debug_info,{outdir,Dir}]),
+ ?line {ok, _} = start(s),
+ ?line ok = xref:set_default(s, [{verbose,false}, {warnings, false}]),
+ ?line {ok, cp} = xref:add_module(s, fname(Dir,"cp.beam")),
+ ?line {ok, [{lists, sort, 1}]} = xref:q(s, "U"),
+ ?line ok = xref:set_library_path(s, code_path),
+ ?line {ok, []} = xref:q(s, "U"),
+ ?line check_state(s),
+ ?line xref:stop(s),
+ ?line ok = file:delete(fname(Dir, "cp.beam")),
+ ok.
+
+read(suite) -> [];
+read(doc) -> ["Data read from the Abstract Code"];
+read(Conf) when is_list(Conf) ->
+ CopyDir = ?copydir,
+ Dir = fname(CopyDir,"read"),
+ File = fname(Dir, "read"),
+ Beam = fname(Dir, "read.beam"),
+ ?line {ok, read} = compile:file(File, [debug_info,{outdir,Dir}]),
+ ?line do_read(File, abstract_v2),
+ ?line copy_file(fname(Dir, "read.beam.v1"), Beam),
+ ?line do_read(File, abstract_v1),
+ ?line ok = file:delete(Beam),
+ ok.
+
+do_read(File, Version) ->
+ ?line {ok, _} = start(s),
+ ?line ok = xref:set_default(s, [{verbose,false}, {warnings, false}]),
+ ?line {ok, read} = xref:add_module(s, File),
+
+ ?line {U, OK, OKB} = read_expected(Version),
+
+ %% {ok, UC} = xref:q(s, "(Lin) UC"),
+ %% RR = to_external(converse(family_to_relation(family(UC)))),
+ %% lists:foreach(fun(X) -> io:format("~w~n", [X]) end, RR),
+ Unres = to_external(relation_to_family(converse(from_term(U)))),
+ ?line {ok, Unres} = xref:q(s, "(Lin) UC"),
+
+ %% {ok, EE} = xref:q(s, "(Lin) (E - UC)"),
+ %% AA = to_external(converse(family_to_relation(family(EE)))),
+ %% lists:foreach(fun(X) -> io:format("~w~n", [X]) end, AA),
+ Calls = to_external(relation_to_family(converse(from_term(OK)))),
+ ?line {ok, Calls} = xref:q(s, "(Lin) (E - UC) "),
+
+ ?line ok = check_state(s),
+ ?line {ok, UM} = xref:q(s, "UM"),
+ ?line true = member('$M_EXPR', UM),
+
+ ?line {ok, X} = xref:q(s, "X"),
+ ?line true = member({read, module_info, 0}, X),
+ ?line false = member({foo, module_info, 0}, X),
+ ?line false = member({erlang, module_info, 0}, X),
+ ?line {ok, Unknowns} = xref:q(s, "U"),
+ ?line false = member({read, module_info, 0}, Unknowns),
+ ?line true = member({foo, module_info, 0}, Unknowns),
+ ?line true = member({erlang, module_info, 0}, Unknowns),
+ ?line {ok, LC} = xref:q(s, "LC"),
+ ?line true = member({{read,bi,0},{read,bi,0}}, LC),
+
+ ?line ok = xref:set_library_path(s, add_erts_code_path(fname(code:lib_dir(kernel),ebin))),
+ ?line io:format("~p~n",[(catch xref:get_library_path(s))]),
+ ?line {ok, X2} = xref:q(s, "X"),
+ ?line ok = check_state(s),
+ ?line true = member({read, module_info, 0}, X2),
+ ?line false = member({foo, module_info, 0}, X2),
+ ?line true = member({erlang, module_info, 0}, X2),
+ ?line {ok, Unknowns2} = xref:q(s, "U"),
+ ?line false = member({read, module_info, 0}, Unknowns2),
+ ?line true = member({foo, module_info, 0}, Unknowns2),
+ ?line false = member({erlang, module_info, 0}, Unknowns2),
+
+ ?line ok = xref:remove_module(s, read),
+ ?line {ok, read} = xref:add_module(s, File, [{builtins,true}]),
+
+ UnresB = to_external(relation_to_family(converse(from_term(U)))),
+ ?line {ok, UnresB} = xref:q(s, "(Lin) UC"),
+ CallsB = to_external(relation_to_family(converse(from_term(OKB)))),
+ ?line {ok, CallsB} = xref:q(s, "(Lin) (E - UC) "),
+ ?line ok = check_state(s),
+ ?line {ok, XU} = xref:q(s, "XU"),
+ ?line Erl = set([{erlang,length,1},{erlang,integer,1},
+ {erlang,binary_to_term,1}]),
+ ?line [{erlang,binary_to_term,1},{erlang,length,1}] =
+ to_external(intersection(set(XU), Erl)),
+ ?line xref:stop(s).
+
+%% What is expected when xref_SUITE_data/read/read.erl is added:
+read_expected(Version) ->
+ %% Line positions in xref_SUITE_data/read/read.erl:
+ POS1 = 28, POS2 = POS1+10, POS3 = POS2+6, POS4 = POS3+6, POS5 = POS4+10,
+ POS6 = POS5+5, POS7 = POS6+6, POS8 = POS7+6, POS9 = POS8+8,
+ POS10 = POS9+10, POS11 = POS10+7, POS12 = POS11+8, POS13 = POS12+10,
+ POS14 = POS13+18, % POS15 = POS14+23,
+
+ FF = {read,funfuns,0},
+ U = [{POS1+5,{FF,{dist,'$F_EXPR',0}}},
+ {POS1+8,{FF,{dist,'$F_EXPR',0}}},
+ {POS2+8,{{read,funfuns,0},{expr,'$F_EXPR',1}}},
+ {POS3+4,{FF,{expr,'$F_EXPR',2}}},
+ {POS4+2,{FF,{modul,'$F_EXPR',1}}},
+ {POS4+4,{FF,{spm,'$F_EXPR',1}}},
+ {POS4+6,{FF,{spm,'$F_EXPR',1}}},
+ {POS4+8,{FF,{spm,'$F_EXPR',1}}},
+ {POS5+1,{FF,{'$M_EXPR','$F_EXPR',0}}},
+ {POS5+2,{FF,{'$M_EXPR','$F_EXPR',0}}},
+ {POS5+3,{FF,{'$M_EXPR','$F_EXPR',0}}},
+ {POS6+1,{FF,{'$M_EXPR','$F_EXPR',0}}},
+ {POS6+2,{FF,{'$M_EXPR','$F_EXPR',0}}},
+ {POS6+4,{FF,{n,'$F_EXPR',-1}}},
+ {POS7+1,{FF,{'$M_EXPR',f,1}}},
+ {POS7+2,{FF,{'$M_EXPR',f,1}}},
+ {POS8+2,{FF,{hej,'$F_EXPR',1}}},
+ {POS8+3,{FF,{t,'$F_EXPR',1}}},
+ {POS8+5,{FF,{a,'$F_EXPR',1}}},
+ {POS8+7,{FF,{m,'$F_EXPR',1}}},
+ {POS9+1,{FF,{'$M_EXPR',f,1}}},
+ {POS9+3,{FF,{a,'$F_EXPR',1}}},
+ {POS10+1,{FF,{'$M_EXPR',foo,1}}},
+ {POS10+2,{FF,{'$M_EXPR','$F_EXPR',1}}},
+ {POS10+3,{FF,{'$M_EXPR','$F_EXPR',2}}},
+ {POS10+4,{FF,{'$M_EXPR','$F_EXPR',1}}},
+ {POS10+5,{FF,{'$M_EXPR',san,1}}},
+ {POS10+6,{FF,{'$M_EXPR','$F_EXPR',1}}},
+ {POS11+1,{FF,{'$M_EXPR','$F_EXPR',1}}},
+ {POS11+2,{FF,{'$M_EXPR','$F_EXPR',-1}}},
+ {POS11+3,{FF,{m,f,-1}}},
+ {POS11+4,{FF,{m,f,-1}}},
+ {POS11+5,{FF,{'$M_EXPR','$F_EXPR',1}}},
+ {POS11+6,{FF,{'$M_EXPR','$F_EXPR',1}}},
+ {POS12+1,{FF,{'$M_EXPR','$F_EXPR',-1}}},
+ {POS12+4,{FF,{'$M_EXPR','$F_EXPR',2}}},
+ {POS12+7,{FF,{'$M_EXPR','$F_EXPR',-1}}},
+ {POS12+8,{FF,{m4,f4,-1}}},
+ {POS13+2,{FF,{debug,'$F_EXPR',0}}},
+ {POS13+3,{FF,{'$M_EXPR','$F_EXPR',-1}}},
+ {POS14+8,{{read,bi,0},{'$M_EXPR','$F_EXPR',1}}}],
+
+ O1 = [{20,{{read,lc,0},{ets,new,0}}},
+ {21,{{read,lc,0},{ets,tab2list,1}}},
+ {POS1+1,{FF,{erlang,spawn,1}}},
+ {POS1+1,{FF,{mod17,fun17,0}}},
+ {POS1+2,{FF,{erlang,spawn,1}}},
+ {POS1+2,{FF,{read,local,0}}},
+ {POS1+3,{FF,{erlang,spawn,1}}},
+ {POS1+4,{FF,{dist,func,0}}},
+ {POS1+4,{FF,{erlang,spawn,1}}},
+ {POS1+5,{FF,{erlang,spawn,1}}},
+ {POS1+6,{FF,{erlang,spawn_link,1}}},
+ {POS1+6,{FF,{mod17,fun17,0}}},
+ {POS1+7,{FF,{dist,func,0}}},
+ {POS1+7,{FF,{erlang,spawn_link,1}}},
+ {POS1+8,{FF,{erlang,spawn_link,1}}},
+ {POS2+1,{FF,{d,f,0}}},
+ {POS2+1,{FF,{dist,func,2}}},
+ {POS2+1,{FF,{erlang,spawn,2}}},
+ {POS2+2,{FF,{dist,func,2}}},
+ {POS2+2,{FF,{erlang,spawn,2}}},
+ {POS2+2,{FF,{mod42,func,0}}},
+ {POS2+3,{FF,{d,f,0}}},
+ {POS2+3,{FF,{dist,func,2}}},
+ {POS2+3,{FF,{erlang,spawn_link,2}}},
+ {POS2+4,{FF,{dist,func,2}}},
+ {POS2+4,{FF,{erlang,spawn_link,2}}},
+ {POS2+4,{FF,{mod42,func,0}}},
+ {POS3+1,{FF,{dist,func,2}}},
+ {POS3+3,{FF,{dist,func,2}}},
+ {POS4+1,{FF,{erlang,spawn,4}}},
+ {POS4+1,{FF,{modul,function,0}}},
+ {POS4+2,{FF,{erlang,spawn,4}}},
+ {POS4+3,{FF,{dist,func,2}}},
+ {POS4+3,{FF,{erlang,spawn,4}}},
+ {POS4+3,{FF,{spm,spf,2}}},
+ {POS4+4,{FF,{dist,func,2}}},
+ {POS4+4,{FF,{erlang,spawn,4}}},
+ {POS4+5,{FF,{dist,func,2}}},
+ {POS4+5,{FF,{erlang,spawn_link,4}}},
+ {POS4+5,{FF,{spm,spf,2}}},
+ {POS4+6,{FF,{dist,func,2}}},
+ {POS4+6,{FF,{erlang,spawn_link,4}}},
+ {POS4+7,{FF,{erlang,spawn_opt,4}}},
+ {POS4+7,{FF,{read,bi,0}}},
+ {POS4+7,{FF,{spm,spf,2}}},
+ {POS4+8,{FF,{erlang,spawn_opt,4}}},
+ {POS4+8,{FF,{read,bi,0}}},
+ {POS5+1,{FF,{erlang,spawn,1}}},
+ {POS5+2,{FF,{erlang,spawn,1}}},
+ {POS5+3,{FF,{erlang,spawn_link,1}}},
+ {POS6+1,{FF,{erlang,spawn,2}}},
+ {POS6+2,{FF,{erlang,spawn_link,2}}},
+ {POS7+1,{FF,{erlang,spawn,4}}},
+ {POS7+2,{FF,{erlang,spawn_opt,4}}},
+ {POS8+1,{FF,{hej,san,1}}},
+ {POS8+4,{FF,{a,b,1}}},
+ {POS8+4,{FF,{erlang,apply,2}}},
+ {POS8+5,{FF,{erlang,apply,2}}},
+ {POS8+6,{FF,{erlang,apply,3}}},
+ {POS8+6,{FF,{m,f,1}}},
+ {POS8+7,{FF,{erlang,apply,3}}},
+ {POS9+1,{FF,{erlang,apply,3}}},
+ {POS9+1,{FF,{read,bi,0}}},
+ {POS9+2,{FF,{a,b,1}}},
+ {POS9+2,{FF,{erlang,apply,2}}},
+ {POS9+3,{FF,{erlang,apply,2}}},
+ {POS9+4,{FF,{erlang,apply,2}}},
+ {POS9+4,{FF,{erlang,not_a_function,1}}},
+ {POS9+5,{FF,{erlang,apply,3}}},
+ {POS9+5,{FF,{mod,func,2}}},
+ {POS9+6,{FF,{erlang,apply,1}}},
+ {POS9+7,{FF,{erlang,apply,2}}},
+ {POS9+7,{FF,{math,add3,1}}},
+ {POS9+8,{FF,{q,f,1}}},
+ {POS10+4,{FF,{erlang,apply,2}}},
+ {POS10+5,{FF,{mod1,fun1,1}}},
+ {POS11+1,{FF,{erlang,apply,3}}},
+ {POS11+2,{FF,{erlang,apply,3}}},
+ {POS11+3,{FF,{erlang,apply,3}}},
+ {POS11+4,{FF,{erlang,apply,3}}},
+ {POS11+6,{FF,{erlang,apply,2}}},
+ {POS12+1,{FF,{erlang,apply,2}}},
+ {POS12+4,{FF,{erlang,apply,2}}},
+ {POS12+5,{FF,{erlang,apply,3}}},
+ {POS12+5,{FF,{m3,f3,2}}},
+ {POS12+7,{FF,{erlang,apply,2}}},
+ {POS12+8,{FF,{erlang,apply,3}}},
+ {POS13+1,{FF,{dm,df,1}}},
+ {POS13+6,{{read,bi,0},{foo,module_info,0}}},
+ {POS13+7,{{read,bi,0},{read,module_info,0}}},
+ {POS13+9,{{read,bi,0},{t,foo,1}}},
+ {POS14+11,{{read,bi,0},{erlang,module_info,0}}},
+ {POS14+17,{{read,bi,0},{read,bi,0}}}],
+
+ OK = case Version of
+ abstract_v1 ->
+ [{POS8+3, {FF,{erlang,apply,3}}},
+ {POS10+1, {FF,{erlang,apply,3}}},
+ {POS10+6, {FF,{erlang,apply,3}}}]
+ ++
+ [{0,{FF,{read,'$F_EXPR',178}}},
+ {0,{FF,{modul,'$F_EXPR',179}}}]
+ ++ O1;
+ _ ->
+% [{POS15+2,{{read,bi,0},{foo,t,0}}},
+% {POS15+3,{{read,bi,0},{bar,t,0}}},
+% {POS15+6,{{read,bi,0},{read,local,0}}},
+% {POS15+8,{{read,bi,0},{foo,t,0}}},
+% {POS15+10,{{read,bi,0},{bar,t,0}}}] ++
+ [{16,{FF,{read,'$F_EXPR',178}}},
+ {17,{FF,{modul,'$F_EXPR',179}}}]
+ ++
+ O1
+ end,
+
+ %% When builtins =:= true:
+ OKB = [{POS13+1,{FF,{erts_debug,apply,4}}},
+ {POS13+2,{FF,{erts_debug,apply,4}}},
+ {POS13+3,{FF,{erts_debug,apply,4}}},
+ {POS1+3, {FF,{erlang,binary_to_term,1}}},
+ {POS3+1, {FF,{erlang,spawn,3}}},
+ {POS3+2, {FF,{erlang,spawn,3}}},
+ {POS3+3, {FF,{erlang,spawn_link,3}}},
+ {POS3+4, {FF,{erlang,spawn_link,3}}},
+ {POS6+4, {FF,{erlang,spawn,3}}},
+ {POS13+5, {{read,bi,0},{erlang,length,1}}},
+ {POS14+3, {{read,bi,0},{erlang,length,1}}}]
+ ++ OK,
+
+ {U, OK, OKB}.
+
+read2(suite) -> [];
+read2(doc) -> ["Data read from the Abstract Code (cont)"];
+read2(Conf) when is_list(Conf) ->
+ %% Handles the spawn_opt versions added in R9 (OTP-4180).
+ %% Expected augmentations: try/catch, cond.
+ CopyDir = ?copydir,
+ Dir = fname(CopyDir,"read"),
+ File = fname(Dir, "read2.erl"),
+ MFile = fname(Dir, "read2"),
+ Beam = fname(Dir, "read2.beam"),
+ Test = <<"-module(read2).
+ -compile(export_all).
+
+ f() ->
+ spawn_opt({read2,f}, % POS2
+ [f()]),
+ spawn_opt(fun() -> foo end, [link]),
+ spawn_opt(f(),
+ {read2,f}, [{min_heap_size,1000}]),
+ spawn_opt(f(),
+ fun() -> f() end, [flopp]),
+ spawn_opt(f(),
+ read2, f, [], []);
+ f() ->
+ %% Duplicated unresolved calls are ignored:
+ (f())(foo,bar),(f())(foo,bar). % POS1
+ ">>,
+ ?line ok = file:write_file(File, Test),
+ ?line {ok, read2} = compile:file(File, [debug_info,{outdir,Dir}]),
+
+ ?line {ok, _} = xref:start(s),
+ ?line {ok, read2} = xref:add_module(s, MFile),
+ ?line {U0, OK0} = read2_expected(),
+
+ U = to_external(relation_to_family(converse(from_term(U0)))),
+ OK = to_external(relation_to_family(converse(from_term(OK0)))),
+ ?line {ok, U2} = xref:q(s, "(Lin) UC"),
+ ?line {ok, OK2} = xref:q(s, "(Lin) (E - UC)"),
+ ?line true = U =:= U2,
+ ?line true = OK =:= OK2,
+ ?line ok = check_state(s),
+ ?line xref:stop(s),
+
+ ?line ok = file:delete(File),
+ ?line ok = file:delete(Beam),
+ ok.
+
+
+read2_expected() ->
+ POS1 = 16,
+ POS2 = 5,
+ FF = {read2,f,0},
+ U = [{POS1,{FF,{'$M_EXPR','$F_EXPR',2}}}],
+ OK = [{POS2,{FF,{erlang,spawn_opt,2}}},
+ {POS2,{FF,FF}},
+ {POS2+1,{FF,FF}},
+ {POS2+2,{FF,{erlang,spawn_opt,2}}},
+ {POS2+3,{FF,{erlang,spawn_opt,3}}},
+ {POS2+3,{FF,FF}},
+ {POS2+3,{FF,FF}},
+ {POS2+5,{FF,{erlang,spawn_opt,3}}},
+ {POS2+5,{FF,FF}},
+ {POS2+6,{FF,FF}},
+ {POS2+7,{FF,{erlang,spawn_opt,5}}},
+ {POS2+7,{FF,FF}},
+ {POS2+7,{FF,FF}},
+ {POS1,{FF,FF}}],
+ {U, OK}.
+
+remove(suite) -> [];
+remove(doc) -> ["Remove modules, applications, releases"];
+remove(Conf) when is_list(Conf) ->
+ S = new(),
+ ?line {error, _, {no_such_module, mod}} =
+ xref_base:remove_module(S, mod),
+ ?line {error, _, {no_such_application, app}} =
+ xref_base:remove_application(S, app),
+ ?line {error, _, {no_such_release, rel}} =
+ xref_base:remove_release(S, rel),
+ ?line ok = xref_base:delete(S),
+ ok.
+
+replace(suite) -> [];
+replace(doc) -> ["Replace modules, applications, releases"];
+replace(Conf) when is_list(Conf) ->
+ CopyDir = ?copydir,
+ Dir = fname(CopyDir,"rel2"),
+ X = fname(Dir, "x.erl"),
+ Y = fname(Dir, "y.erl"),
+ A1_0 = fname(Dir, fname("lib","app1-1.0")),
+ A1_1 = fname(Dir, fname("lib","app1-1.1")),
+ A2 = fname(Dir, fname("lib","app2-1.1")),
+ EB1_0 = fname(A1_0, "ebin"),
+ EB1_1 = fname(A1_1, "ebin"),
+ Xbeam = fname(EB1_1, "x.beam"),
+ Ybeam = fname(EB1_1, "y.beam"),
+
+ ?line {ok, x} = compile:file(X, [debug_info, {outdir,EB1_0}]),
+ ?line {ok, x} = compile:file(X, [debug_info, {outdir,EB1_1}]),
+ ?line {ok, y} = compile:file(Y, [debug_info, {outdir,EB1_1}]),
+
+ ?line {ok, _} = start(s),
+ ?line {ok, false} = xref:set_default(s, verbose, false),
+ ?line {ok, true} = xref:set_default(s, warnings, false),
+ ?line {ok, rel2} = xref:add_release(s, Dir, []),
+ ?line {error, _, _} = xref:replace_application(s, app1, "no_data"),
+ ?line {error, _, {no_such_application, app12}} =
+ xref:replace_application(s, app12, A1_0, []),
+ ?line {error, _, {invalid_filename,{foo,bar}}} =
+ xref:replace_application(s, app1, {foo,bar}, []),
+ ?line {error, _, {invalid_options,[not_an_option]}} =
+ xref:replace_application(s, foo, bar, [not_an_option]),
+ ?line {error, _, {invalid_options,[{builtins,not_a_value}]}} =
+ xref:replace_application(s, foo, bar, [{builtins,not_a_value}]),
+ ?line {ok, app1} =
+ xref:replace_application(s, app1, A1_0),
+ ?line [{_, AppInfo}] = xref:info(s, applications, app1),
+ ?line {value, {release, [rel2]}} = keysearch(release, 1, AppInfo),
+
+ ?line {error, _, {no_such_module, xx}} =
+ xref:replace_module(s, xx, Xbeam, []),
+ ?line {error, _, {invalid_options,[{builtins,true},not_an_option]}} =
+ xref:replace_module(s, foo, bar,[{builtins,true},not_an_option]),
+ ?line {error, _, {invalid_options,[{builtins,not_a_value}]}} =
+ xref:replace_module(s, foo, bar, [{builtins,not_a_value}]),
+ ?line {error, _, {invalid_filename,{foo,bar}}} =
+ xref:replace_module(s, x, {foo,bar}),
+ ?line {ok, x} = xref:replace_module(s, x, Xbeam),
+ ?line [{x, ModInfo}] = xref:info(s, modules, x),
+ ?line {value, {application, [app1]}} =
+ keysearch(application, 1, ModInfo),
+
+ ?line {ok, x} = compile:file(X, [no_debug_info, {outdir,EB1_1}]),
+ ?line {error, _, {no_debug_info, _}} = xref:replace_module(s, x, Xbeam),
+ ?line {error, _, {module_mismatch, x,y}} =
+ xref:replace_module(s, x, Ybeam),
+ ?line case os:type() of
+ {unix, _} ->
+ ?line hide_file(Ybeam),
+ ?line {error, _, {file_error, _, _}} =
+ xref:replace_module(s, x, Ybeam);
+ _ ->
+ true
+ end,
+ ?line ok = xref:remove_module(s, x),
+ ?line {error, _, {no_debug_info, _}} = xref:add_module(s, Xbeam),
+
+ %% "app2" is ignored, the old application name is kept
+ ?line {ok, app1} = xref:replace_application(s, app1, A2),
+
+ ?line xref:stop(s),
+ ?line ok = file:delete(fname(EB1_0, "x.beam")),
+ ?line ok = file:delete(Xbeam),
+ ?line ok = file:delete(Ybeam),
+ ok.
+
+update(suite) -> [];
+update(doc) -> ["The update() function"];
+update(Conf) when is_list(Conf) ->
+ CopyDir = ?copydir,
+ Dir = fname(CopyDir,"update"),
+ Source = fname(Dir, "x.erl"),
+ Beam = fname(Dir, "x.beam"),
+ ?line copy_file(fname(Dir, "x.erl.1"), Source),
+ ?line {ok, x} = compile:file(Source, [debug_info, {outdir,Dir}]),
+
+ ?line {ok, _} = start(s),
+ ?line ok = xref:set_default(s, [{verbose,false}, {warnings, false}]),
+ ?line {ok, [x]} = xref:add_directory(s, Dir, [{builtins,true}]),
+ ?line {error, _, {invalid_options,[not_an_option]}} =
+ xref:update(s, [not_an_option]),
+ ?line {ok, []} = xref:update(s),
+ ?line {ok, [{erlang,atom_to_list,1}]} = xref:q(s, "XU"),
+
+ ?line [{x, ModInfo}] = xref:info(s, modules, x),
+ ?line case keysearch(directory, 1, ModInfo) of
+ {value, {directory, Dir}} -> ok
+ end,
+
+ timer:sleep(2000), % make sure modification time has changed
+ ?line copy_file(fname(Dir, "x.erl.2"), Source),
+ ?line {ok, x} = compile:file(Source, [debug_info, {outdir,Dir}]),
+ ?line {ok, [x]} = xref:update(s, []),
+ ?line {ok, [{erlang,list_to_atom,1}]} = xref:q(s, "XU"),
+
+ timer:sleep(2000),
+ ?line {ok, x} = compile:file(Source, [no_debug_info,{outdir,Dir}]),
+ ?line {error, _, {no_debug_info, _}} = xref:update(s),
+
+ ?line xref:stop(s),
+ ?line ok = file:delete(Beam),
+ ?line ok = file:delete(Source),
+ ok.
+
+deprecated(suite) -> [];
+deprecated(doc) -> ["OTP-4695: Deprecated functions."];
+deprecated(Conf) when is_list(Conf) ->
+ Dir = ?copydir,
+ File = fname(Dir, "depr.erl"),
+ MFile_r9c = fname(Dir, "depr_r9c"),
+ MFile = fname(Dir, "depr"),
+ Beam = fname(Dir, "depr.beam"),
+ %% This file has been compiled to ?datadir/depr_r9c.beam
+ %% using the R9C compiler. From R10B and onwards the linter
+ %% checks the 'deprecated' attribute as well.
+% Test = <<"-module(depr).
+
+% -export([t/0,f/1,bar/2,f/2,g/3]).
+
+% -deprecated([{f,1}, % DF
+% {bar,2,eventually}]). % DF_3
+% -deprecated([{f,1,next_major_release}]). % DF_2 (again)
+% -deprecated([{frutt,0,next_version}]). % message...
+% -deprecated([{f,2,next_major_release}, % DF_2
+% {g,3,next_version}, % DF_1
+% {ignored,10,100}]). % message...
+% -deprecated([{does_not_exist,1}]). % message...
+
+% -deprecated(foo). % message...
+
+% t() ->
+% frutt(1),
+% g(1,2, 3),
+% ?MODULE:f(10).
+
+% f(A) ->
+% ?MODULE:f(A,A).
+
+% f(X, Y) ->
+% ?MODULE:g(X, Y, X).
+
+% g(F, G, H) ->
+% ?MODULE:bar(F, {G,H}).
+
+% bar(_, _) ->
+% true.
+
+% frutt(_) ->
+% frutt().
+
+% frutt() ->
+% true.
+% ">>,
+
+% ?line ok = file:write_file(File, Test),
+% ?line {ok, depr_r9c} = compile:file(File, [debug_info,{outdir,Dir}]),
+
+ ?line {ok, _} = xref:start(s),
+ ?line {ok, depr_r9c} = xref:add_module(s, MFile_r9c),
+ M9 = depr_r9c,
+ DF_1 = usort([{{M9,f,2},{M9,g,3}}]),
+ DF_2 = usort(DF_1++[{{M9,f,1},{M9,f,2}},{{M9,t,0},{M9,f,1}}]),
+ DF_3 = usort(DF_2++[{{M9,g,3},{M9,bar,2}}]),
+ DF = usort(DF_3++[{{M9,t,0},{M9,f,1}}]),
+
+ ?line {ok,DF} = xref:analyze(s, deprecated_function_calls),
+ ?line {ok,DF_1} =
+ xref:analyze(s, {deprecated_function_calls,next_version}),
+ ?line {ok,DF_2} =
+ xref:analyze(s, {deprecated_function_calls,next_major_release}),
+ ?line {ok,DF_3} =
+ xref:analyze(s, {deprecated_function_calls,eventually}),
+
+ D = to_external(range(from_term(DF))),
+ D_1 = to_external(range(from_term(DF_1))),
+ D_2 = to_external(range(from_term(DF_2))),
+ D_3 = to_external(range(from_term(DF_3))),
+
+ ?line {ok,D} = xref:analyze(s, deprecated_functions),
+ ?line {ok,D_1} =
+ xref:analyze(s, {deprecated_functions,next_version}),
+ ?line {ok,D_2} =
+ xref:analyze(s, {deprecated_functions,next_major_release}),
+ ?line {ok,D_3} =
+ xref:analyze(s, {deprecated_functions,eventually}),
+
+ ?line ok = check_state(s),
+ ?line xref:stop(s),
+
+ Test2= <<"-module(depr).
+
+ -export([t/0,f/1,bar/2,f/2,g/3]).
+
+ -deprecated([{'_','_',eventually}]). % DF_3
+ -deprecated([{f,'_',next_major_release}]). % DF_2
+ -deprecated([{g,'_',next_version}]). % DF_1
+ -deprecated([{bar,2}]). % DF
+
+ t() ->
+ g(1,2, 3),
+ ?MODULE:f(10).
+
+ f(A) ->
+ ?MODULE:f(A,A).
+
+ f(X, Y) ->
+ ?MODULE:g(X, Y, X).
+
+ g(F, G, H) ->
+ ?MODULE:bar(F, {G,H}).
+
+ bar(_, _) ->
+ ?MODULE:t().
+ ">>,
+
+ ?line ok = file:write_file(File, Test2),
+ ?line {ok, depr} = compile:file(File, [debug_info,{outdir,Dir}]),
+
+ ?line {ok, _} = xref:start(s),
+ ?line {ok, depr} = xref:add_module(s, MFile),
+
+ M = depr,
+ DFa_1 = usort([{{M,f,2},{M,g,3}}]),
+ DFa_2 = usort(DFa_1++[{{M,f,1},{M,f,2}},{{M,t,0},{M,f,1}}]),
+ DFa_3 = usort(DFa_2++[{{M,bar,2},{M,t,0}},{{M,g,3},{M,bar,2}}]),
+ DFa = DFa_3,
+
+ ?line {ok,DFa} = xref:analyze(s, deprecated_function_calls),
+ ?line {ok,DFa_1} =
+ xref:analyze(s, {deprecated_function_calls,next_version}),
+ ?line {ok,DFa_2} =
+ xref:analyze(s, {deprecated_function_calls,next_major_release}),
+ ?line {ok,DFa_3} =
+ xref:analyze(s, {deprecated_function_calls,eventually}),
+
+ ?line ok = check_state(s),
+ ?line xref:stop(s),
+
+ %% All of the module is deprecated.
+ Test3= <<"-module(depr).
+
+ -export([t/0,f/1,bar/2,f/2,g/3]).
+
+ -deprecated([{f,'_',next_major_release}]). % DF_2
+ -deprecated([{g,'_',next_version}]). % DF_1
+ -deprecated(module). % DF
+
+ t() ->
+ g(1,2, 3),
+ ?MODULE:f(10).
+
+ f(A) ->
+ ?MODULE:f(A,A).
+
+ f(X, Y) ->
+ ?MODULE:g(X, Y, X).
+
+ g(F, G, H) ->
+ ?MODULE:bar(F, {G,H}).
+
+ bar(_, _) ->
+ ?MODULE:t().
+ ">>,
+
+ ?line ok = file:write_file(File, Test3),
+ ?line {ok, depr} = compile:file(File, [debug_info,{outdir,Dir}]),
+
+ ?line {ok, _} = xref:start(s),
+ ?line {ok, depr} = xref:add_module(s, MFile),
+
+ DFb_1 = usort([{{M,f,2},{M,g,3}}]),
+ DFb_2 = usort(DFb_1++[{{M,f,1},{M,f,2}},{{M,t,0},{M,f,1}}]),
+ DFb_3 = DFb_2,
+ DFb = usort(DFb_2++[{{M,bar,2},{M,t,0}},{{M,g,3},{M,bar,2}}]),
+
+ ?line {ok,DFb} = xref:analyze(s, deprecated_function_calls),
+ ?line {ok,DFb_1} =
+ xref:analyze(s, {deprecated_function_calls,next_version}),
+ ?line {ok,DFb_2} =
+ xref:analyze(s, {deprecated_function_calls,next_major_release}),
+ ?line {ok,DFb_3} =
+ xref:analyze(s, {deprecated_function_calls,eventually}),
+
+ ?line ok = check_state(s),
+ ?line xref:stop(s),
+
+ ?line ok = file:delete(File),
+ ?line ok = file:delete(Beam),
+ ok.
+
+
+trycatch(suite) -> [];
+trycatch(doc) -> ["OTP-5152: try/catch, final (?) version."];
+trycatch(Conf) when is_list(Conf) ->
+ Dir = ?copydir,
+ File = fname(Dir, "trycatch.erl"),
+ MFile = fname(Dir, "trycatch"),
+ Beam = fname(Dir, "trycatch.beam"),
+ Test = <<"-module(trycatch).
+
+ -export([trycatch/0]).
+
+ trycatch() ->
+ try
+ foo:bar(),
+ bar:foo() of
+ 1 -> foo:foo();
+ 2 -> bar:bar()
+ catch
+ error:a -> err:e1();
+ error:b -> err:e2()
+ after
+ fini:shed()
+ end.
+ ">>,
+
+ ?line ok = file:write_file(File, Test),
+ ?line {ok, trycatch} = compile:file(File, [debug_info,{outdir,Dir}]),
+
+ ?line {ok, _} = xref:start(s),
+ ?line {ok, trycatch} = xref:add_module(s, MFile),
+ A = trycatch,
+ {ok,[{{{A,A,0},{bar,bar,0}},[10]},
+ {{{A,A,0},{bar,foo,0}},[8]},
+ {{{A,A,0},{err,e1,0}},[12]},
+ {{{A,A,0},{err,e2,0}},[13]},
+ {{{A,A,0},{fini,shed,0}},[15]},
+ {{{A,A,0},{foo,bar,0}},[7]},
+ {{{A,A,0},{foo,foo,0}},[9]}]} =
+ xref:q(s, "(Lin) (E | trycatch:trycatch/0)"),
+
+ ?line ok = check_state(s),
+ ?line xref:stop(s),
+
+ ?line ok = file:delete(File),
+ ?line ok = file:delete(Beam),
+ ok.
+
+
+abstract_modules(suite) -> [];
+abstract_modules(doc) -> ["OTP-5520: Abstract (parameterized) modules."];
+abstract_modules(Conf) when is_list(Conf) ->
+ Dir = ?copydir,
+ File = fname(Dir, "absmod.erl"),
+ MFile = fname(Dir, "absmod"),
+ Beam = fname(Dir, "absmod.beam"),
+ Test = <<"-module(param, [A, B]).
+
+ -export([args/1]).
+
+ args(C) ->
+ X = local(C),
+ Y = THIS:new(), % undef
+ Z = new(A, B),
+ {X, Y, Z}.
+
+ local(C) ->
+ module_info(C).
+ ">>,
+
+ ?line ok = file:write_file(File, Test),
+
+ %% The compiler will no longer allow us to have a mismatch between
+ %% the module name and the output file, so we must use a trick.
+ ?line {ok, param, BeamCode} = compile:file(File, [binary,debug_info]),
+ ?line ok = file:write_file(Beam, BeamCode),
+
+ ?line {ok, _} = xref:start(s),
+ ?line {ok, param} = xref:add_module(s, MFile, {warnings,false}),
+ A = param,
+ ?line {ok, [{{{A,args,1},{'$M_EXPR',new,0}},[7]},
+ {{{A,args,1},{A,local,1}},[6]},
+ {{{A,args,1},{A,new,2}},[8]},
+ {{{A,local,1},{A,module_info,1}},[12]},
+ {{{param,new,2},{param,instance,2}},[0]}]} =
+ xref:q(s, "(Lin) E"),
+ ?line {ok,[{param,args,1},
+ {param,instance,2},
+ {param,local,1},
+ {param,module_info,1},
+ {param,new,2}]} = xref:q(s, "F"),
+
+ ?line ok = check_state(s),
+ ?line xref:stop(s),
+
+ ?line {ok, _} = xref:start(s, {xref_mode, modules}),
+ ?line {ok, param} = xref:add_module(s, MFile),
+ ?line {ok,[{param,args,1},
+ {param,instance,2},
+ {param,new,2}]} = xref:q(s, "X"),
+ ?line ok = check_state(s),
+ ?line xref:stop(s),
+
+ ?line ok = file:delete(File),
+ ?line ok = file:delete(Beam),
+ ok.
+
+fun_mfa(suite) -> [];
+fun_mfa(doc) -> ["OTP-5653: fun M:F/A."];
+fun_mfa(Conf) when is_list(Conf) ->
+ Dir = ?copydir,
+ File = fname(Dir, "fun_mfa.erl"),
+ MFile = fname(Dir, "fun_mfa"),
+ Beam = fname(Dir, "fun_mfa.beam"),
+ Test = <<"-module(fun_mfa).
+
+ -export([t/0, t1/0, t2/0, t3/0]).
+
+ t() ->
+ F = fun ?MODULE:t/0,
+ (F)().
+
+ t1() ->
+ F = fun t/0,
+ (F)().
+
+ t2() ->
+ fun ?MODULE:t/0().
+
+ t3() ->
+ fun t3/0().
+ ">>,
+
+ ?line ok = file:write_file(File, Test),
+ A = fun_mfa,
+ ?line {ok, A} = compile:file(File, [debug_info,{outdir,Dir}]),
+ ?line {ok, _} = xref:start(s),
+ ?line {ok, A} = xref:add_module(s, MFile, {warnings,false}),
+ ?line {ok, [{{{A,t,0},{'$M_EXPR','$F_EXPR',0}},[7]},
+ {{{A,t,0},{A,t,0}},[6]},
+ {{{A,t1,0},{'$M_EXPR','$F_EXPR',0}},[11]},
+ {{{A,t1,0},{A,t,0}},[10]},
+ {{{A,t2,0},{A,t,0}},[14]},
+ {{{A,t3,0},{fun_mfa,t3,0}},[17]}]} =
+ xref:q(s, "(Lin) E"),
+
+ ?line ok = check_state(s),
+ ?line xref:stop(s),
+
+ ?line ok = file:delete(File),
+ ?line ok = file:delete(Beam),
+ ok.
+
+qlc(suite) -> [];
+qlc(doc) -> ["OTP-5195: A bug fix when using qlc:q/1,2."];
+qlc(Conf) when is_list(Conf) ->
+ Dir = ?copydir,
+ File = fname(Dir, "qlc.erl"),
+ MFile = fname(Dir, "qlc"),
+ Beam = fname(Dir, "qlc.beam"),
+ Test = <<"-module(qlc).
+
+ -include_lib(\"stdlib/include/qlc.hrl\").
+
+ -export([t/0]).
+
+ t() ->
+ dets:open_file(t, []),
+ dets:insert(t, [{1,a},{2,b},{3,c},{4,d}]),
+ MS = ets:fun2ms(fun({X,Y}) when (X > 1) or (X < 5) -> {Y}
+ end),
+ QH1 = dets:table(t, [{traverse, {select, MS}}]),
+ QH2 = qlc:q([{Y} || {X,Y} <- dets:table(t),
+ (X > 1) or (X < 5)]),
+ true = qlc:info(QH1) =:= qlc:info(QH2),
+ dets:close(t),
+ ok.
+ ">>,
+
+ ?line ok = file:write_file(File, Test),
+ A = qlc,
+ ?line {ok, A} = compile:file(File, [debug_info,{outdir,Dir}]),
+ ?line {ok, _} = xref:start(s),
+ ?line {ok, A} = xref:add_module(s, MFile, {warnings,false}),
+ ?line {ok, _} = xref:q(s, "(Lin) E"), % is can be loaded
+
+ ?line ok = check_state(s),
+ ?line xref:stop(s),
+
+ ?line ok = file:delete(File),
+ ?line ok = file:delete(Beam),
+ ok.
+
+
+analyses(suite) ->
+ [analyze, basic, md, q, variables, unused_locals].
+
+analyze(suite) -> [];
+analyze(doc) -> ["Simple analyses"];
+analyze(Conf) when is_list(Conf) ->
+ S0 = new(),
+ ?line {{error, _, {invalid_options,[not_an_option]}}, _} =
+ xref_base:analyze(S0, undefined_function_calls, [not_an_option]),
+ ?line {{error, _, {invalid_query,{q}}}, _} = xref_base:q(S0,{q}),
+ ?line {{error, _, {unknown_analysis,foo}}, _} = xref_base:analyze(S0, foo),
+ ?line {{error, _, {unknown_constant,"foo:bar/-1"}}, _} =
+ xref_base:analyze(S0, {use,{foo,bar,-1}}),
+
+ CopyDir = ?copydir,
+ Dir = fname(CopyDir,"rel2"),
+ X = fname(Dir, "x.erl"),
+ Y = fname(Dir, "y.erl"),
+ A1_1 = fname([Dir,"lib","app1-1.1"]),
+ A2 = fname([Dir,"lib","app2-1.1"]),
+ EB1_1 = fname(A1_1, "ebin"),
+ EB2 = fname(A2, "ebin"),
+ Xbeam = fname(EB2, "x.beam"),
+ Ybeam = fname(EB1_1, "y.beam"),
+
+ ?line {ok, x} = compile:file(X, [debug_info, {outdir,EB2}]),
+ ?line {ok, y} = compile:file(Y, [debug_info, {outdir,EB1_1}]),
+
+ ?line {ok, rel2, S1} = xref_base:add_release(S0, Dir, [{verbose,false}]),
+ ?line S = set_up(S1),
+
+ ?line {ok, _} =
+ analyze(undefined_function_calls, [{{x,xx,0},{x,undef,0}}], S),
+ ?line {ok, _} = analyze(undefined_functions, [{x,undef,0}], S),
+ ?line {ok, _} = analyze(locals_not_used, [{x,l,0},{x,l1,0}], S),
+ ?line {ok, _} = analyze(exports_not_used, [{x,xx,0},{y,t,0}], S),
+
+ ?line {ok, _} =
+ analyze(deprecated_function_calls, [{{y,t,0},{x,t,0}}], S),
+ ?line {ok, _} = analyze({deprecated_function_calls,next_version}, [], S),
+ ?line {ok, _} =
+ analyze({deprecated_function_calls,next_major_release}, [], S),
+ ?line {ok, _} = analyze({deprecated_function_calls,eventually},
+ [{{y,t,0},{x,t,0}}], S),
+ ?line {ok, _} = analyze(deprecated_functions, [{x,t,0}], S),
+ ?line {ok, _} = analyze({deprecated_functions,next_version}, [], S),
+ ?line {ok, _} =
+ analyze({deprecated_functions,next_major_release}, [], S),
+ ?line {ok, _} = analyze({deprecated_functions,eventually}, [{x,t,0}], S),
+
+ ?line {ok, _} = analyze({call, {x,xx,0}}, [{x,undef,0}], S),
+ ?line {ok, _} =
+ analyze({call, [{x,xx,0},{x,l,0}]}, [{x,l1,0},{x,undef,0}], S),
+ ?line {ok, _} = analyze({use, {x,l,0}}, [{x,l1,0}], S),
+ ?line {ok, _} =
+ analyze({use, [{x,l,0},{x,l1,0}]}, [{x,l,0},{x,l1,0}], S),
+
+ ?line {ok, _} = analyze({module_call, x}, [x], S),
+ ?line {ok, _} = analyze({module_call, [x,y]}, [x], S),
+ ?line {ok, _} = analyze({module_use, x}, [x,y], S),
+ ?line {ok, _} = analyze({module_use, [x,y]}, [x,y], S),
+
+ ?line {ok, _} = analyze({application_call, app1}, [app2], S),
+ ?line {ok, _} = analyze({application_call, [app1,app2]}, [app2], S),
+ ?line {ok, _} = analyze({application_use, app2}, [app1,app2], S),
+ ?line {ok, _} = analyze({application_use, [app1,app2]}, [app1,app2], S),
+
+ ?line ok = xref_base:delete(S),
+ ?line ok = file:delete(Xbeam),
+ ?line ok = file:delete(Ybeam),
+ ok.
+
+basic(suite) -> [];
+basic(doc) -> ["Use of operators"];
+basic(Conf) when is_list(Conf) ->
+ ?line S0 = new(),
+
+ F1 = {m1,f1,1},
+ F6 = {m1,f2,6}, % X
+ F2 = {m2,f1,2},
+ F3 = {m2,f2,3}, % X
+ F7 = {m2,f3,7}, % X
+ F4 = {m3,f1,4}, % X
+ F5 = {m3,f2,5},
+
+ UF1 = {m1,f12,17},
+ UF2 = {m17,f17,177},
+
+ E1 = {F1,F3}, % X
+ E2 = {F6,F7}, % X
+ E3 = {F2,F6}, % X
+ E4 = {F1,F4}, % X
+ E5 = {F4,F5},
+ E6 = {F7,F4}, % X
+ E7 = {F1,F6},
+
+ UE1 = {F2,UF2}, % X
+ UE2 = {F5,UF1}, % X
+
+ D1 = {F1,12},
+ D6 = {F6,3},
+ DefAt_m1 = [D1,D6],
+ X_m1 = [F6],
+ % L_m1 = [F1],
+ XC_m1 = [E1,E2,E4],
+ LC_m1 = [E7],
+ LCallAt_m1 = [{E7,12}],
+ XCallAt_m1 = [{E1,13},{E2,17},{E4,7}],
+ Info1 = #xref_mod{name = m1, app_name = [a1]},
+ ?line S1 = add_module(S0, Info1, DefAt_m1, X_m1, LCallAt_m1, XCallAt_m1,
+ XC_m1, LC_m1),
+
+ D2 = {F2,7},
+ D3 = {F3,9},
+ D7 = {F7,19},
+ DefAt_m2 = [D2,D3,D7],
+ X_m2 = [F3,F7],
+ % L_m2 = [F2],
+ XC_m2 = [E3,E6,UE1],
+ LC_m2 = [],
+ LCallAt_m2 = [],
+ XCallAt_m2 = [{E3,96},{E6,12},{UE1,77}],
+ Info2 = #xref_mod{name = m2, app_name = [a2]},
+ ?line S2 = add_module(S1, Info2, DefAt_m2, X_m2, LCallAt_m2, XCallAt_m2,
+ XC_m2, LC_m2),
+
+ D4 = {F4,6},
+ D5 = {F5,97},
+ DefAt_m3 = [D4,D5],
+ X_m3 = [F4],
+ % L_m3 = [F5],
+ XC_m3 = [UE2],
+ LC_m3 = [E5],
+ LCallAt_m3 = [{E5,19}],
+ XCallAt_m3 = [{UE2,22}],
+ Info3 = #xref_mod{name = m3, app_name = [a3]},
+ ?line S3 = add_module(S2, Info3, DefAt_m3, X_m3, LCallAt_m3, XCallAt_m3,
+ XC_m3, LC_m3),
+
+ Info4 = #xref_mod{name = m4, app_name = [a2]},
+ ?line S4 = add_module(S3, Info4, [], [], [], [], [], []),
+
+ AppInfo1 = #xref_app{name = a1, rel_name = [r1]},
+ ?line S9 = add_application(S4, AppInfo1),
+ AppInfo2 = #xref_app{name = a2, rel_name = [r1]},
+ ?line S10 = add_application(S9, AppInfo2),
+ AppInfo3 = #xref_app{name = a3, rel_name = [r2]},
+ ?line S11 = add_application(S10, AppInfo3),
+
+ RelInfo1 = #xref_rel{name = r1},
+ ?line S12 = add_release(S11, RelInfo1),
+ RelInfo2 = #xref_rel{name = r2},
+ ?line S13 = add_release(S12, RelInfo2),
+
+ ?line S = set_up(S13),
+
+ ?line {ok, _} = eval("[m1,m2] + m:f/1", unknown_constant, S),
+ ?line {ok, _} = eval("[m1, m2, m:f/1]", type_mismatch, S),
+
+ ?line {ok, _} = eval("[m1, m1->m2]", type_mismatch, S),
+ ?line {ok, _} = eval("components:f/1", unknown_constant, S),
+ ?line {ok, _} = eval("'of':f/1", unknown_constant, S),
+ ?line {ok, _} = eval("of:f/1", parse_error, S),
+ ?line {ok, _} = eval("components", unknown_constant, S),
+ ?line {ok, _} = eval("[components, of, closure]", parse_error, S),
+ ?line {ok, _} = eval("[components, 'of', closure]", unknown_constant, S),
+
+ ?line {ok, _} = eval("[a1->a2,m1->m2]", type_mismatch, S),
+ ?line {ok, _} = eval("a1->a2,m1->m2", parse_error, S),
+
+ ?line {ok, _} = eval("m1->a1", type_mismatch, S),
+ ?line {ok, _} = eval("[{m1,f1,1}] : App", parse_error, S),
+ ?line {ok, _} = eval("[{m1,f1,1}] : Fun", [F1], S),
+ ?line {ok, _} = eval("range X", type_error, S),
+ ?line {ok, _} = eval("domain X", type_error, S),
+ ?line {ok, _} = eval("range M", type_error, S),
+ ?line {ok, _} = eval("domain M", type_error, S),
+
+ % Misc.
+ ?line {ok, _} = eval("not_a_prefix_operator m1", parse_error, S),
+ ?line {ok, _} = eval(f("(Mod) ~p", [[F1,F6,F5]]), [m1,m3], S),
+ ?line {ok, _} = eval("(Lin) M - (Lin) m1",
+ [{F2,7},{F3,9},{F7,19},{F4,6},{F5,97},{UF2,0}], S),
+ ?line {ok, _} = eval(f("(Lin) M * (Lin) ~p", [[F1,F6]]),
+ [{F1,12},{F6,3}], S),
+
+ ?line {ok, _} = eval(f("X * ~p", [[F1, F2, F3, F4, F5]]), [F3, F4], S),
+ ?line {ok, _} = eval("X", [F6,F3,F7,F4], S),
+ ?line {ok, _} = eval("X * AM", [F6,F3,F7,F4], S),
+ ?line {ok, _} = eval("X * a2", [F3,F7], S),
+
+ ?line {ok, _} = eval("L * r1", [F1,F2], S),
+ ?line {ok, _} = eval("U", [UF1, UF2], S),
+ ?line {ok, _} = eval("U * AM", [UF1], S),
+ ?line {ok, _} = eval("U * UM", [UF2], S),
+ ?line {ok, _} = eval("XU * [m1, m2]", [F6,F3,F7,UF1], S),
+ ?line {ok, _} = eval("LU * [m3, m4]", [F5], S),
+ ?line {ok, _} = eval("UU", [F1,F2], S),
+
+ ?line {ok, _} = eval("XC | m1", [E1,E2,E4], S),
+ ?line {ok, _} = eval(f("XC | ~p", [F1]), [E1,E4], S),
+ ?line {ok, _} = eval(f("(XXL) (Lin) (XC | ~p)", [F1]),
+ [{{D1,D3},[13]},{{D1,D4},[7]}],S),
+ ?line {ok, _} = eval(f("XC | (~p + ~p)", [F1, F2]), [E1,E4,E3,UE1], S),
+ ?line {ok, _} = eval(f("(XXL) (Lin) (XC | ~p)", [F1]),
+ [{{D1,D3},[13]},{{D1,D4},[7]}], S),
+ ?line {ok, _} = eval("LC | m3", [E5], S),
+ ?line {ok, _} = eval(f("LC | ~p", [F1]), [E7], S),
+ ?line {ok, _} = eval(f("LC | (~p + ~p)", [F1, F4]), [E7, E5], S),
+ ?line {ok, _} = eval("E | m1", [E1,E2,E4,E7], S),
+ ?line {ok, _} = eval(f("E | ~p", [F1]), [E1,E7,E4], S),
+ ?line {ok, _} = eval(f("E | (~p + ~p)", [F1, F2]), [E1,E7,E4,E3,UE1], S),
+
+ ?line {ok, _} = eval("XC || m1", [E3,UE2], S),
+ ?line {ok, _} = eval(f("XC || ~p", [F6]), [E3], S),
+ ?line {ok, _} = eval(f("XC || (~p + ~p)", [F4, UF2]), [UE1,E4,E6], S),
+ ?line {ok, _} = eval("LC || m3", [E5], S),
+ ?line {ok, _} = eval(f("LC || ~p", [F1]), [], S),
+ ?line {ok, _} = eval(f("LC || ~p", [F6]), [E7], S),
+ ?line {ok, _} = eval(f("LC || (~p + ~p)", [F5, F6]), [E7,E5], S),
+ ?line {ok, _} = eval("E || m1", [E3,UE2,E7], S),
+ ?line {ok, _} = eval(f("E || ~p", [F6]), [E3,E7], S),
+ ?line {ok, _} = eval(f("E || (~p + ~p)", [F3,F4]), [E1,E4,E6], S),
+
+ ?line {ok, _} = eval(f("~p + ~p", [F1,F2]), [F1,F2], S),
+ ?line {ok, _} = eval(f("~p * ~p", [m1,[F1,F6,F2]]), [F1,F6], S),
+ ?line {ok, _} = eval(f("~p * ~p", [F1,F2]), [], S),
+
+ %% range, domain
+ ?line {ok, _} = eval("range (E || m1)", [F6,UF1], S),
+ ?line {ok, _} = eval("domain (E || m1)", [F1,F2,F5], S),
+ ?line {ok, _} = eval(f("E | domain ~p", [[E1, {F2,F4}]]),
+ [E1,E7,E4,E3,UE1], S),
+
+ %% components, condensation, use, call
+ ?line {ok, _} = eval("(Lin) components E", type_error, S),
+ ?line {ok, _} = eval("components (Lin) E", type_error, S),
+ ?line {ok, _} = eval("components V", type_error, S),
+ ?line {ok, _} = eval("components E + components E", type_error, S),
+
+ ?line {ok, _} = eval(f("range (closure E | ~p)", [[F1,F2]]),
+ [F6,F3,F7,F4,F5,UF1,UF2], S),
+ ?line {ok, _} =
+ eval(f("domain (closure E || ~p)", [[UF2,F7]]), [F1,F2,F6], S),
+ ?line {ok, _} = eval("components E", [], S),
+ ?line {ok, _} = eval("components (Mod) E", [[m1,m2,m3]], S),
+ ?line {ok, _} = eval("components closure (Mod) E", [[m1,m2,m3]], S),
+ ?line {ok, _} = eval("condensation (Mod) E",
+ [{[m1,m2,m3],[m1,m2,m3]},{[m1,m2,m3],[m17]}], S),
+ ?line {ok, _} = eval("condensation closure (Mod) E",
+ [{[m1,m2,m3],[m1,m2,m3]},{[m1,m2,m3],[m17]}], S),
+ ?line {ok, _} = eval("condensation closure closure closure (Mod) E",
+ [{[m1,m2,m3],[m1,m2,m3]},{[m1,m2,m3],[m17]}], S),
+ ?line {ok, _} = eval("weak condensation (Mod) E",
+ [{[m1,m2,m3],[m1,m2,m3]},{[m1,m2,m3],[m17]},{[m17],[m17]}], S),
+ ?line {ok, _} = eval("strict condensation (Mod) E",
+ [{[m1,m2,m3],[m17]}], S),
+ ?line {ok, _} = eval("range condensation (Mod) E",
+ [[m1,m2,m3],[m17]], S),
+ ?line {ok, _} = eval("domain condensation (Mod) E",
+ [[m1,m2,m3]], S),
+
+ %% |, ||, |||
+ ?line {ok, _} = eval("(Lin) E || V", type_error, S),
+ ?line {ok, _} = eval("E ||| (Lin) V", type_error, S),
+ ?line {ok, _} = eval("E ||| m1", [E7], S),
+ ?line {ok, _} = eval("closure E ||| m1", [E7,{F1,UF1},{F6,UF1}], S),
+ ?line {ok, _} = eval("closure E ||| [m1,m2]",
+ [{F1,UF1},{F2,F7},{F1,F7},{F6,UF1},{F2,UF1},{F7,UF1},E7,E1,E2,E3], S),
+ ?line {ok, _} = eval("AE | a1", [{a1,a1},{a1,a2},{a1,a3}], S),
+
+ %% path ('of')
+ ?line {ok, _} = eval("(Lin) {m1,m2} of E", type_error, S),
+ ?line {ok, _} = eval("{m1,m2} of (Lin) E", type_error, S),
+ ?line [m1,m2] = eval("{m1,m2} of {m1,m2}", S),
+ ?line {ok, _} = eval("{m1,m2} of m1", type_error, S),
+ ?line {ok, _} = eval("{a3,m1} of ME", type_mismatch, S),
+ ?line [m1,m1] = eval("{m1} of ME", S),
+ ?line [m1,m1] = eval("{m1} of closure closure ME", S),
+ ?line false = eval("{m17} of ME", S),
+ ?line [m2,m1,m2] = eval("{m2} : Mod of ME", S),
+ ?line [m1,m2,m17] = eval("{m1, m17} of ME", S),
+ ?line [m1,m2,m17] = eval("m1 -> m17 of ME", S),
+ ?line {ok, _} = eval("[m1->m17,m17->m1] of ME", type_error, S),
+ ?line case eval(f("~p of E", [{F1,F7,UF1}]), S) of
+ [F1,F6,F7,F4,F5,UF1] -> ok
+ end,
+ ?line [a2,a1,a2] = eval("{a2} of AE", S),
+
+ %% weak/strict
+ ?line {ok, _} = eval("weak {m1,m2}", [{m1,m1},{m1,m2},{m2,m2}], S),
+ ?line {ok, _} = eval("strict [{m1,m1},{m1,m2},{m2,m2}]", [{m1,m2}], S),
+ ?line {ok, _} = eval("range weak [{m1,m2}] : Mod", [m1,m2], S),
+ ?line {ok, _} = eval("domain strict [{m1,m1},{m1,m2},{m2,m2}]", [m1], S),
+
+ %% #, number of
+ ?line {ok, _} = eval("# [{r1,r2}] : Rel", 1, S),
+ ?line {ok, _} = eval("# [{a3,a1}] : App", 1, S),
+ ?line {ok, _} = eval("# AE", 7, S),
+ ?line {ok, _} = eval("# ME", 8, S),
+ ?line {ok, _} = eval("# AE + # ME", 15, S),
+ ?line {ok, _} = eval("# AE * # ME", 56, S),
+ ?line {ok, _} = eval("# AE - # ME", -1, S),
+ ?line {ok, _} = eval("# E", 9, S),
+ ?line {ok, _} = eval("# V", 9, S),
+ ?line {ok, _} = eval("# (Lin) E", 9, S),
+ ?line {ok, _} = eval("# (ELin) E", 7, S),
+ ?line {ok, _} = eval("# closure E", type_error, S),
+ ?line {ok, _} = eval("# weak {m1,m2}", 3, S),
+ ?line {ok, _} = eval("#strict condensation (Mod) E", 1, S),
+ ?line {ok, _} = eval("#components closure (Mod) E", 1, S),
+ ?line {ok, _} = eval("# range strict condensation (Mod) E", 1, S),
+ ok.
+
+md(suite) -> [];
+md(doc) -> ["The xref:m() and xref:d() functions"];
+md(Conf) when is_list(Conf) ->
+ CopyDir = ?copydir,
+ Dir = fname(CopyDir,"md"),
+ X = fname(Dir, "x__x.erl"),
+ Y = fname(Dir, "y__y.erl"),
+ Xbeam = fname(Dir, "x__x.beam"),
+ Ybeam = fname(Dir, "y__y.beam"),
+
+ ?line {error, _, {invalid_filename,{foo,bar}}} = xref:m({foo,bar}),
+ ?line {error, _, {invalid_filename,{foo,bar}}} = xref:d({foo,bar}),
+
+ ?line {ok, x__x} = compile:file(X, [debug_info, {outdir,Dir}]),
+ ?line {ok, y__y} = compile:file(Y, [debug_info, {outdir,Dir}]),
+
+ ?line {error, _, {no_such_module, foo_bar}} = xref:m(foo_bar),
+ ?line OldPath = code:get_path(),
+ ?line true = code:set_path([Dir | OldPath]),
+ ?line MInfo = xref:m(x__x),
+ ?line [{{x__x,t,1},{y__y,t,2}}] = info_tag(MInfo, undefined),
+ ?line [] = info_tag(MInfo, unused),
+ ?line [] = info_tag(MInfo, deprecated),
+ ?line DInfo = xref:d(Dir),
+ ?line [{{x__x,t,1},{y__y,t,2}}] = info_tag(DInfo, undefined),
+ ?line [{y__y,l,0},{y__y,l1,0}] = info_tag(DInfo, unused),
+ ?line [] = info_tag(MInfo, deprecated),
+
+ %% Switch from 'functions' mode to 'modules' mode.
+ ?line {ok, x__x} = compile:file(X, [no_debug_info, {outdir,Dir}]),
+ ?line {ok, y__y} = compile:file(Y, [no_debug_info, {outdir,Dir}]),
+ ?line MInfoMod = xref:m(x__x),
+ ?line [{y__y,t,2}] = info_tag(MInfoMod, undefined),
+ ?line [] = info_tag(MInfo, deprecated),
+ ?line DInfoMod = xref:d(Dir),
+ ?line [{y__y,t,2}] = info_tag(DInfoMod, undefined),
+ ?line [] = info_tag(MInfo, deprecated),
+
+ ?line true = code:set_path(OldPath),
+ ?line ok = file:delete(Xbeam),
+ ?line ok = file:delete(Ybeam),
+ ok.
+
+q(suite) -> [];
+q(doc) -> ["User queries"];
+q(Conf) when is_list(Conf) ->
+ ?line S0 = new(),
+ ?line {ok, _} = eval("'foo", parse_error, S0),
+ ?line {ok, _} = eval("TT = E, TT = V", variable_reassigned, S0),
+ ?line {ok, _} = eval("TT = E, TTT", unknown_variable, S0),
+ ?line {ok, S} = eval("TT := E", [], S0),
+ ?line {ok, S1} = eval("TT * TT * TT", [], S),
+ ?line {ok, _S2} = xref_base:forget(S1, 'TT'),
+ ok.
+
+variables(suite) -> [];
+variables(doc) -> ["Setting and getting values of query variables"];
+variables(Conf) when is_list(Conf) ->
+ ?line Sa = new(),
+ ?line {{error, _, {invalid_options,[not_an_option]}}, _} =
+ xref_base:variables(Sa, [not_an_option]),
+ ?line {error, _, {not_user_variable,foo}} = xref_base:forget(Sa, foo),
+ ?line Sa1 = set_up(Sa),
+ ?line {error, _, {not_user_variable,foo}} = xref_base:forget(Sa1, foo),
+ ?line ok = xref_base:delete(Sa1),
+
+ ?line S0 = new(),
+
+ F1 = {m1,f1,1},
+ F2 = {m2,f1,2},
+ Lib = {lib1,f1,1}, % undefined
+
+ E1 = {F1,F2},
+ E2 = {F2,F1},
+ E3 = {F1,Lib},
+
+ D1 = {F1,12},
+ DefAt_m1 = [D1],
+ X_m1 = [F1],
+ % L_m1 = [],
+ XC_m1 = [E1,E3],
+ LC_m1 = [],
+ LCallAt_m1 = [],
+ XCallAt_m1 = [{E1,13},{E3,17}],
+ Info1 = #xref_mod{name = m1, app_name = [a1]},
+ ?line S1 = add_module(S0, Info1, DefAt_m1, X_m1, LCallAt_m1, XCallAt_m1,
+ XC_m1, LC_m1),
+
+ D2 = {F2,7},
+ DefAt_m2 = [D2],
+ X_m2 = [F2],
+ % L_m2 = [],
+ XC_m2 = [E2],
+ LC_m2 = [],
+ LCallAt_m2 = [],
+ XCallAt_m2 = [{E2,96}],
+ Info2 = #xref_mod{name = m2, app_name = [a2]},
+ ?line S2 = add_module(S1, Info2, DefAt_m2, X_m2, LCallAt_m2, XCallAt_m2,
+ XC_m2, LC_m2),
+
+ ?line S = set_up(S2),
+
+ ?line eval("T1=E, T2=E*T1, T3 = T2*T2, T4=range T3, T5=T3|T4, T5",
+ [E1,E2,E3], S),
+ ?line eval("((E*E)*(E*E)) | (range ((E*E)*(E*E)))",
+ [E1,E2,E3], S),
+ ?line eval("T1=V*V,T2=T1*V,T3=V*V*V,T3",
+ [F1,F2,Lib], S),
+ ?line eval("T1=V*V, T2=V*V, T1*T2",
+ [F1,F2,Lib], S),
+
+ ?line {ok, S100} = eval("T0 := E", [E1, E2, E3], S),
+ ?line {ok, S101} = eval("T1 := E | m1", [E1, E3], S100),
+ ?line {ok, S102} = eval("T2 := E | m2", [E2], S101),
+ ?line {{ok, [{user, ['T0', 'T1', 'T2']}]}, _} = xref_base:variables(S102),
+ ?line {ok, S103} = xref_base:forget(S102, 'T0'),
+ ?line {{ok, [{user, ['T1', 'T2']}]}, S104} =
+ xref_base:variables(S103, [user]),
+ ?line {ok, S105} = xref_base:forget(S104),
+ ?line {{ok, [{user, []}]}, S106} = xref_base:variables(S105),
+ ?line {{ok, [{predefined,_}]}, S107_0} =
+ xref_base:variables(S106, [predefined]),
+
+ ?line {ok, S107_1} =
+ eval("TT := E, TT2 := V, TT1 := TT * TT", [E1,E2,E3], S107_0),
+ ?line {{ok, [{user, ['TT', 'TT1', 'TT2']}]}, _} =
+ xref_base:variables(S107_1),
+ ?line {ok, S107} = xref_base:forget(S107_1),
+
+ CopyDir = ?copydir,
+ ?line Dir = fname(CopyDir,"lib_test"),
+ Beam = fname(Dir, "lib1.beam"),
+
+ ?line copy_file(fname(Dir, "lib1.erl"), Beam),
+ ?line {ok, S108} =
+ xref_base:set_library_path(S107, [Dir], [{verbose,false}]),
+ ?line {{error, _, _}, _} = xref_base:variables(S108, [{verbose,false}]),
+ ?line {ok, S109} = xref_base:set_library_path(S108, [], [{verbose,false}]),
+
+ ?line Tabs = length(ets:all()),
+
+ ?line {ok, S110} = eval("Eplus := closure E, TT := Eplus",
+ 'closure()', S109),
+ ?line {{ok, [{user, ['Eplus','TT']}]}, S111} = xref_base:variables(S110),
+ ?line {ok, S112} = xref_base:forget(S111, ['TT','Eplus']),
+ ?line true = Tabs =:= length(ets:all()),
+
+ ?line {ok, NS0} = eval("Eplus := closure E", 'closure()', S112),
+ ?line {{ok, [{user, ['Eplus']}]}, NS} = xref_base:variables(NS0),
+ ?line ok = xref_base:delete(NS),
+ ?line true = Tabs =:= length(ets:all()),
+
+ ?line ok = file:delete(Beam),
+ ok.
+
+unused_locals(suite) -> [];
+unused_locals(doc) -> ["OTP-5071. Too many unused functions."];
+unused_locals(Conf) when is_list(Conf) ->
+ Dir = ?copydir,
+
+ File1 = fname(Dir, "a.erl"),
+ MFile1 = fname(Dir, "a"),
+ Beam1 = fname(Dir, "a.beam"),
+ Test1 = <<"-module(a).
+ -export([f/1, g/2]).
+
+ f(X) ->
+ Y = b:f(X),
+ Z = b:g(Y),
+ start(b, h, [Z]).
+
+ g(X, Y) ->
+ ok.
+
+ start(M, F, A) ->
+ spawn(M, F, A).
+ ">>,
+ ?line ok = file:write_file(File1, Test1),
+ ?line {ok, a} = compile:file(File1, [debug_info,{outdir,Dir}]),
+
+ File2 = fname(Dir, "b.erl"),
+ MFile2 = fname(Dir, "b"),
+ Beam2 = fname(Dir, "b.beam"),
+ Test2 = <<"-module(b).
+ -export([f/1, g/2]).
+
+ f(X) ->
+ io:write(\"~w\", [X]),
+ a:start(timer, sleep, [1000]).
+
+ g(X, Y) ->
+ apply(a, g, [X, Y]).
+ ">>,
+
+ ?line ok = file:write_file(File2, Test2),
+ ?line {ok, b} = compile:file(File2, [debug_info,{outdir,Dir}]),
+
+ ?line {ok, _} = xref:start(s),
+ ?line {ok, a} = xref:add_module(s, MFile1),
+ ?line {ok, b} = xref:add_module(s, MFile2),
+ ?line {ok, []} = xref:analyse(s, locals_not_used),
+ ?line ok = check_state(s),
+ ?line xref:stop(s),
+
+ ?line ok = file:delete(File1),
+ ?line ok = file:delete(Beam1),
+ ?line ok = file:delete(File2),
+ ?line ok = file:delete(Beam2),
+ ok.
+
+misc(suite) ->
+ [format_error, otp_7423, otp_7831].
+
+format_error(suite) -> [];
+format_error(doc) -> ["Format error messages"];
+format_error(Conf) when is_list(Conf) ->
+ ?line {ok, _Pid} = start(s),
+ ?line ok = xref:set_default(s, [{verbose,false}, {warnings, false}]),
+
+ %% Parse error messages.
+ ?line 'Invalid regular expression "add(": unterminated \`(\'\n'
+ = fatom(xref:q(s,'"add("')),
+ ?line 'Invalid operator foo\n' =
+ fatom(xref:q(s,'foo E')),
+ ?line 'Invalid wildcard variable \'_Var\' (only \'_\' is allowed)\n'
+ = fatom(xref:q(s,"module:function/_Var")),
+ ?line 'Missing type of regular expression ".*"\n'
+ = fatom(xref:q(s,'".*"')),
+ ?line 'Type does not match structure of constant: \'M\' : Fun\n'
+ = fatom(xref:q(s,"'M' : Fun")),
+ ?line 'Type does not match structure of constant: ".*" : Fun\n'
+ = fatom(xref:q(s,'".*" : Fun')),
+ ?line 'Type does not match structure of constant: [m:f/1, m1:f2/3] : App\n'
+ = fatom(xref:q(s,"[m:f/1,m1:f2/3] : App")),
+ ?line 'Parse error on line 1: syntax error before: \'-\'\n' =
+ fatom(xref:q(s,"E + -")),
+ ?line "Parse error on line 1: unterminated atom starting with 'foo'\n"
+ = flatten(xref:format_error(xref:q(s,"'foo"))),
+ ?line 'Parse error at end of string: syntax error before: \n' =
+ fatom(xref:q(s,"E +")),
+ ?line 'Parse error on line 1: syntax error before: \'Lin\'\n' =
+ fatom(xref:q(s,"Lin")),
+
+ %% Other messages
+ ?line 'Variable \'QQ\' used before set\n' =
+ fatom(xref:q(s,"QQ")),
+ ?line 'Unknown constant a\n' =
+ fatom(xref:q(s,"{a} of E")),
+
+ %% Testing xref_parser:t2s/1.
+ ?line 'Variable assigned more than once: E := E + E\n' =
+ fatom(xref:q(s,"E:=E + E")),
+ ?line 'Variable assigned more than once: E = E + E\n' =
+ fatom(xref:q(s,"E=E + E")),
+ ?line "Operator applied to argument(s) of different or invalid type(s): "
+ "E + V * V\n" =
+ flatten(xref:format_error(xref:q(s,"E + (V * V)"))),
+ ?line {error,xref_compiler,{type_error,"(V + V) * E"}} =
+ xref:q(s,"(V + V) * E"),
+ ?line "Type does not match structure of constant: [m:f/3 -> g:h/17] : "
+ "App\n" =
+ flatten(xref:format_error(xref:q(s,"[{{m,f,3},{g,h,17}}] : App"))),
+ ?line 'Type does not match structure of constant: [m -> f, g -> h] : Fun\n'
+ = fatom(xref:q(s,"[{m,f},g->h] : Fun")),
+ ?line 'Type does not match structure of constant: {m, n, o} : Fun\n' =
+ fatom(xref:q(s,"{m,n,o} : Fun")),
+ ?line {error,xref_compiler,{type_error,"range (Lin) V"}} =
+ xref:q(s,"range ((Lin) V)"),
+ ?line {error,xref_compiler,{type_error,"condensation range E"}} =
+ xref:q(s,"condensation (range E)"),
+ ?line {error,xref_compiler,{type_error,"condensation (# E + # V)"}} =
+ xref:q(s,"condensation (# E + # V)"),
+ ?line {error,xref_compiler,{type_error,"range (# E + # E)"}} =
+ xref:q(s,"range (#E + #E)"),
+ ?line {error,xref_compiler,{type_error,"range (# E)"}} =
+ xref:q(s,"range #E"), % Hm...
+ ?line {error,xref_compiler,{type_error,"E + # E"}} =
+ xref:q(s,"E + #E + #E"), % Hm...
+ ?line {error,xref_compiler,{type_error,"V * E || V | V"}} =
+ xref:q(s,"V * (E || V) | V"),
+ ?line {error,xref_compiler,{type_error,"E || (E | V)"}} =
+ xref:q(s,"V * E || (E | V)"),
+ ?line {error,xref_compiler,{type_error,"E * \"m\" : Mod"}} =
+ xref:q(s,'E * "m" : Mod'),
+ ?line {error,xref_compiler,{type_error,"E * (\"m\":f/_ + m:\"f\"/3)"}} =
+ xref:q(s,'E * ("m":f/_ + m:"f"/3)'),
+
+ ?line xref:stop(s),
+ ok.
+
+otp_7423(suite) -> [];
+otp_7423(doc) -> ["OTP-7423. Xref scanner bug."];
+otp_7423(Conf) when is_list(Conf) ->
+ ?line {ok, _Pid} = start(s),
+ S = "E | [compiler] : App || [{erlang,
+ size,
+ 1}] : Fun",
+ ?line {error,xref_compiler,{unknown_constant,"compiler"}} = xref:q(s,S),
+ ?line xref:stop(s),
+ ok.
+
+otp_7831(suite) -> [];
+otp_7831(doc) -> ["OTP-7831. Allow anonymous Xref processes."];
+otp_7831(Conf) when is_list(Conf) ->
+ ?line {ok, Pid1} = xref:start([]),
+ ?line xref:stop(Pid1),
+ ?line {ok, Pid2} = xref:start([{xref_mode, modules}]),
+ ?line xref:stop(Pid2),
+ ok.
+
+%%%
+%%% Utilities
+%%%
+
+copy_file(Src, Dest) ->
+ file:copy(Src, Dest).
+
+fname(N) ->
+ filename:join(N).
+
+fname(Dir, Basename) ->
+ filename:join(Dir, Basename).
+
+new() ->
+ ?line {ok, S} = xref_base:new(),
+ S.
+
+set_up(S) ->
+ ?line {ok, S1} = xref_base:set_up(S, [{verbose, false}]),
+ S1.
+
+eval(Query, E, S) ->
+ ?format("------------------------------~n", []),
+ ?format("Evaluating ~p~n", [Query]),
+ ?line {Answer, NewState} = xref_base:q(S, Query, [{verbose, false}]),
+ {Reply, Expected} =
+ case Answer of
+ {ok, R} when is_list(E) ->
+ {unsetify(R), sort(E)};
+ {ok, R} ->
+ {unsetify(R), E};
+ {error, _Module, Reason} ->
+ {element(1, Reason), E}
+ end,
+ if
+ Reply =:= Expected ->
+ ?format("As expected, got ~n~p~n", [Expected]),
+ {ok, NewState};
+ true ->
+ ?format("Expected ~n~p~nbut got ~n~p~n", [Expected, Reply]),
+ not_ok
+ end.
+
+analyze(Query, E, S) ->
+ ?format("------------------------------~n", []),
+ ?format("Evaluating ~p~n", [Query]),
+ ?line {{ok, L}, NewState} =
+ xref_base:analyze(S, Query, [{verbose, false}]),
+ case {unsetify(L), sort(E)} of
+ {X,X} ->
+ ?format("As was expected, got ~n~p~n", [X]),
+ {ok, NewState};
+ {_R,_X} ->
+ ?format("Expected ~n~p~nbut got ~n~p~n", [_X, _R]),
+ not_ok
+ end.
+
+unsetify(S) ->
+ case is_sofs_set(S) of
+ true -> to_external(S);
+ false -> S
+ end.
+
+%% Note: assumes S has been set up; the new state is not returned
+eval(Query, S) ->
+ ?line {{ok, Answer}, _NewState} =
+ xref_base:q(S, Query, [{verbose, false}]),
+ unsetify(Answer).
+
+add_module(S, XMod, DefAt, X, LCallAt, XCallAt, XC, LC) ->
+ Attr = {[], [], []},
+ Depr0 = {[], [], [], []},
+ DBad = [],
+ Depr = {Depr0,DBad},
+ Data = {DefAt, LCallAt, XCallAt, LC, XC, X, Attr, Depr},
+ Unres = [],
+ ?line {ok, _Module, _Bad, State} =
+ xref_base:do_add_module(S, XMod, Unres, Data),
+ State.
+
+add_application(S, XApp) ->
+ ?line xref_base:do_add_application(S, XApp).
+
+add_release(S, XRel) ->
+ ?line xref_base:do_add_release(S, XRel).
+
+remove_module(S, M) ->
+ ?line xref_base:do_remove_module(S, M).
+
+info_tag(Info, Tag) ->
+ {value, {_Tag, Value}} = lists:keysearch(Tag, 1, Info),
+ Value.
+
+make_ufile(FileName) ->
+ ?line ok = file:write_file(FileName, term_to_binary(foo)),
+ ?line hide_file(FileName).
+
+make_udir(Dir) ->
+ ?line ok = file:make_dir(Dir),
+ ?line hide_file(Dir).
+
+hide_file(FileName) ->
+ ?line {ok, FileInfo} = file:read_file_info(FileName),
+ ?line NewFileInfo = FileInfo#file_info{mode = 0},
+ ?line ok = file:write_file_info(FileName, NewFileInfo).
+
+%% Note that S has to be set up before calling this checking function.
+check_state(S) ->
+ ?line Info = xref:info(S),
+
+ ?line modules_mode_check(S, Info),
+ case info(Info, mode) of
+ modules ->
+ ok;
+ functions ->
+ functions_mode_check(S, Info)
+ end.
+
+%% The manual mentions some facts that should always hold.
+%% Here they are again.
+functions_mode_check(S, Info) ->
+ %% F = L + X,
+ ?line {ok, F} = xref:q(S, "F"),
+ ?line {ok, F} = xref:q(S, "L + X"),
+
+ %% V = X + L + B + U,
+ ?line {ok, V} = xref:q(S, "V"),
+ ?line {ok, V} = xref:q(S, "X + L + B + U"),
+
+ %% X, L, B and U are disjoint.
+ ?line {ok, []} =
+ xref:q(S, "X * L + X * B + X * U + L * B + L * U + B * U"),
+
+ %% V = UU + XU + LU,
+ ?line {ok, V} = xref:q(S, "UU + XU + LU"),
+
+ %% E = LC + XC
+ ?line {ok, E} = xref:q(S, "E"),
+ ?line {ok, E} = xref:q(S, "LC + XC"),
+
+ %% U subset of XU,
+ ?line {ok, []} = xref:q(S, "U - XU"),
+
+ %% LU = range LC
+ ?line {ok, []} = xref:q(S, "(LU - range LC) + (range LC - LU)"),
+
+ %% XU = range XC
+ ?line {ok, []} = xref:q(S, "(XU - range XC) + (range XC - XU)"),
+
+ %% LU subset F
+ ?line {ok, []} = xref:q(S, "LU - F"),
+
+ %% UU subset F
+ ?line {ok, []} = xref:q(S, "UU - F"),
+
+ %% ME = (Mod) E
+ ?line {ok, ME} = xref:q(S, "ME"),
+ ?line {ok, ME} = xref:q(S, "(Mod) E"),
+
+ %% AE = (App) E
+ ?line {ok, AE} = xref:q(S, "AE"),
+ ?line {ok, AE} = xref:q(S, "(App) E"),
+
+ %% RE = (Rel) E
+ ?line {ok, RE} = xref:q(S, "RE"),
+ ?line {ok, RE} = xref:q(S, "(Rel) E"),
+
+ %% (Mod) V subset of M
+ ?line {ok, []} = xref:q(S, "(Mod) V - M"),
+
+ %% range UC subset of U
+ ?line {ok, []} = xref:q(S, "range UC - U"),
+
+ %% Some checks on the numbers returned by the info functions.
+
+ ?line {Resolved, Unresolved} = info(Info, no_calls),
+ ?line AllCalls = Resolved + Unresolved,
+ ?line {ok, AllCalls} = xref:q(S, "# (XLin) E + # (LLin) E"),
+
+ ?line {Local, Exported} = info(Info, no_functions),
+ ?line LX = Local+Exported,
+ ?line {ok, LXs} = xref:q(S, 'Extra = _:module_info/"(0|1)" + LM,
+ # (F - Extra)'),
+ ?line true = LX =:= LXs,
+
+ ?line {LocalCalls, ExternalCalls, UnresCalls} =
+ info(Info, no_function_calls),
+ ?line LEU = LocalCalls + ExternalCalls + UnresCalls,
+ ?line {ok, LEU} = xref:q(S, "# LC + # XC"),
+
+ ?line InterFunctionCalls = info(Info, no_inter_function_calls),
+ ?line {ok, InterFunctionCalls} = xref:q(S, "# EE"),
+
+ %% And some more checks on counters...
+ ?line check_count(S),
+
+ %% ... and more
+ ?line {ok, []} = xref:q(S, "LM - X - U - B"),
+
+ ok.
+
+modules_mode_check(S, Info) ->
+ %% B subset of XU,
+ ?line {ok, []} = xref:q(S, "B - XU"),
+
+ %% M = AM + LM + UM
+ ?line {ok, M} = xref:q(S, "M"),
+ ?line {ok, M} = xref:q(S, "AM + LM + UM"),
+
+ %% DF is a subset of X U B, etc.
+ ?line {ok, []} = xref:q(S, "DF - X - B"),
+ ?line {ok, []} = xref:q(S, "DF_3 - DF"),
+ ?line {ok, []} = xref:q(S, "DF_2 - DF_3"),
+ ?line {ok, []} = xref:q(S, "DF_1 - DF_2"),
+
+ %% AM, LM and UM are disjoint.
+ ?line {ok, []} = xref:q(S, "AM * LM + AM * UM + LM * UM"),
+
+ %% (App) M subset of A
+ ?line {ok, []} = xref:q(S, "(App) M - A"),
+
+ ?line AM = info(Info, no_analyzed_modules),
+ ?line {ok, AM} = xref:q(S, "# AM"),
+
+ ?line A = info(Info, no_applications),
+ ?line {ok, A} = xref:q(S, "# A"),
+
+ ?line NoR = info(Info, no_releases),
+ ?line {ok, NoR} = xref:q(S, "# R"),
+
+ ok.
+
+%% Checks the counters of some of the overall and modules info functions.
+%% (Applications and releases are not checked.)
+check_count(S) ->
+ %%{ok, R} = xref:q(S, 'R'),
+ %% {ok, A} = xref:q(S, 'A'),
+ {ok, M} = xref:q(S, 'AM'),
+
+ {ok, _} = xref:q(S,
+ "Extra := _:module_info/\"(0|1)\" + LM"),
+
+ %% info/1:
+ {ok, NoR} = xref:q(S, '# R'),
+ {ok, NoA} = xref:q(S, '# A'),
+ {ok, NoM} = xref:q(S, '# AM'),
+ {ok, NoCalls} = xref:q(S, '# (XLin) E + # (LLin) E'),
+ {ok, NoFunCalls} = xref:q(S, '# E'),
+ {ok, NoXCalls} = xref:q(S, '# XC'),
+ {ok, NoLCalls} = xref:q(S, '# LC'),
+ {ok, NoLXCalls} = xref:q(S, '# (XC * LC)'),
+ NoAllCalls = NoXCalls + NoLCalls,
+ {ok, NoFun} = xref:q(S, '# (F - Extra)'),
+ {ok, NoICalls} = xref:q(S, '# EE'),
+
+ Info = xref:info(S),
+ NoR = info(Info, no_releases),
+ NoA = info(Info, no_applications),
+ NoM = info(Info, no_analyzed_modules),
+ {NoResolved, NoUC} = info(Info, no_calls),
+ NoCalls = NoResolved + NoUC,
+ {NoLocal, NoExternal, NoUnres} = info(Info, no_function_calls),
+ NoAllCalls = NoLocal + NoExternal + NoUnres,
+ NoAllCalls = NoFunCalls + NoLXCalls,
+ {NoLocalFuns, NoExportedFuns} = info(Info, no_functions),
+ NoFun = NoLocalFuns + NoExportedFuns,
+ NoICalls = info(Info, no_inter_function_calls),
+
+ %% per module
+ info_module(M, S),
+
+ ok.
+
+info_module([M | Ms], S) ->
+ {ok, NoCalls} = per_module("T = (E | ~p : Mod), # (XLin) T + # (LLin) T",
+ M, S),
+ {ok, NoFunCalls} = per_module("# (E | ~p : Mod)", M, S),
+ {ok, NoXCalls} = per_module("# (XC | ~p : Mod)", M, S),
+ {ok, NoLCalls} = per_module("# (LC | ~p : Mod)", M, S),
+ {ok, NoLXCalls} = per_module("# ((XC * LC) | ~p : Mod)", M, S),
+ NoAllCalls = NoXCalls + NoLCalls,
+ {ok, NoFun} = per_module("# (F * ~p : Mod - Extra)", M, S),
+ {ok, NoICalls} = per_module("# (EE | ~p : Mod)", M, S),
+
+ [{_M,Info}] = xref:info(S, modules, M),
+ {NoResolved, NoUC} = info(Info, no_calls),
+ NoCalls = NoResolved + NoUC,
+ {NoLocal, NoExternal, NoUnres} = info(Info, no_function_calls),
+ NoAllCalls = NoLocal + NoExternal + NoUnres,
+ NoAllCalls = NoFunCalls + NoLXCalls,
+ {NoLocalFuns, NoExportedFuns} = info(Info, no_functions),
+ NoFun = NoLocalFuns + NoExportedFuns,
+ NoICalls = info(Info, no_inter_function_calls),
+
+ info_module(Ms, S);
+info_module([], _S) ->
+ ok.
+
+per_module(Q, M, S) ->
+ xref:q(S, f(Q, [M])).
+
+info(Info, What) ->
+ {value, {What, Value}} = lists:keysearch(What, 1, Info),
+ Value.
+
+f(S, A) ->
+ flatten(io_lib:format(S, A)).
+
+fatom(R) ->
+ list_to_atom(flatten(xref:format_error(R))).
+
+start(Server) ->
+ ?line case xref:start(Server) of
+ {error, {already_started, _Pid}} ->
+ ?line xref:stop(Server),
+ ?line xref:start(Server);
+ R -> R
+ end.
+
+add_erts_code_path(KernelPath) ->
+ VersionDirs =
+ filelib:is_dir(
+ filename:join(
+ [code:lib_dir(),
+ lists:flatten(
+ ["kernel-",
+ [X ||
+ {kernel,_,X} <-
+ application_controller:which_applications()]])])),
+ case VersionDirs of
+ true ->
+ case code:lib_dir(erts) of
+ String when is_list(String) ->
+ [KernelPath, fname(String,"ebin")];
+ _Other1 ->
+ [KernelPath]
+ end;
+ false ->
+ % Clearcase?
+ PrelPath = filename:join([code:lib_dir(),"..","erts","preloaded"]),
+ case filelib:is_dir(PrelPath) of
+ true ->
+ [KernelPath, fname(PrelPath,"ebin")];
+ false ->
+ [KernelPath]
+ end
+ end.
+
+
diff --git a/lib/tools/test/xref_SUITE_data/depr_r9c.beam b/lib/tools/test/xref_SUITE_data/depr_r9c.beam
new file mode 100644
index 0000000000..82f0eef5a1
--- /dev/null
+++ b/lib/tools/test/xref_SUITE_data/depr_r9c.beam
Binary files differ
diff --git a/lib/tools/test/xref_SUITE_data/dir/dir/dummy b/lib/tools/test/xref_SUITE_data/dir/dir/dummy
new file mode 100644
index 0000000000..7f62a93220
--- /dev/null
+++ b/lib/tools/test/xref_SUITE_data/dir/dir/dummy
@@ -0,0 +1,2 @@
+This directory is not empty.
+Prevents winzip from removing the directory.
diff --git a/lib/tools/test/xref_SUITE_data/dir/jam/x.jam b/lib/tools/test/xref_SUITE_data/dir/jam/x.jam
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/lib/tools/test/xref_SUITE_data/dir/jam/x.jam
diff --git a/lib/tools/test/xref_SUITE_data/lib_test/cp.erl b/lib/tools/test/xref_SUITE_data/lib_test/cp.erl
new file mode 100644
index 0000000000..efe5d77854
--- /dev/null
+++ b/lib/tools/test/xref_SUITE_data/lib_test/cp.erl
@@ -0,0 +1,6 @@
+-module(cp).
+
+-export([t/0]).
+
+t() ->
+ lists:sort(a).
diff --git a/lib/tools/test/xref_SUITE_data/lib_test/lib1.erl b/lib/tools/test/xref_SUITE_data/lib_test/lib1.erl
new file mode 100644
index 0000000000..7d50fcb1af
--- /dev/null
+++ b/lib/tools/test/xref_SUITE_data/lib_test/lib1.erl
@@ -0,0 +1,6 @@
+-module(lib1).
+
+-export([f/0]).
+
+f() ->
+ true.
diff --git a/lib/tools/test/xref_SUITE_data/lib_test/lib2.erl b/lib/tools/test/xref_SUITE_data/lib_test/lib2.erl
new file mode 100644
index 0000000000..ca505dfd4f
--- /dev/null
+++ b/lib/tools/test/xref_SUITE_data/lib_test/lib2.erl
@@ -0,0 +1,14 @@
+-module(lib2).
+
+-export([f/0, g/0]).
+
+-deprecated({f,0,next_major_release}).
+
+f() ->
+ local().
+
+g() ->
+ true.
+
+local() ->
+ true.
diff --git a/lib/tools/test/xref_SUITE_data/lib_test/lib3.erl b/lib/tools/test/xref_SUITE_data/lib_test/lib3.erl
new file mode 100644
index 0000000000..8a900f8040
--- /dev/null
+++ b/lib/tools/test/xref_SUITE_data/lib_test/lib3.erl
@@ -0,0 +1,11 @@
+-module(lib3).
+
+-export([f/0, g/0]).
+
+-deprecated(module).
+
+f() ->
+ true.
+
+g() ->
+ true.
diff --git a/lib/tools/test/xref_SUITE_data/lib_test/t.erl b/lib/tools/test/xref_SUITE_data/lib_test/t.erl
new file mode 100644
index 0000000000..d2bd81110e
--- /dev/null
+++ b/lib/tools/test/xref_SUITE_data/lib_test/t.erl
@@ -0,0 +1,14 @@
+-module(t).
+
+-export([t/0]).
+
+t() ->
+ %% lib1: only unknown functions used
+ %% lib2: one known used, one unknown function used, one local used
+ %% lib3: one known function used
+ lib1:unknown(),
+ lib2:f(), %% known, g/0 not used
+ lib2:unknown(),
+ lib2:local(),
+ lib3:f(),
+ unknown:unknown().
diff --git a/lib/tools/test/xref_SUITE_data/md/x__x.erl b/lib/tools/test/xref_SUITE_data/md/x__x.erl
new file mode 100644
index 0000000000..83234e1d3f
--- /dev/null
+++ b/lib/tools/test/xref_SUITE_data/md/x__x.erl
@@ -0,0 +1,7 @@
+-module(x__x).
+
+-export([t/1]).
+
+t(A) ->
+ y__y:t(A),
+ y__y:t(A,A).
diff --git a/lib/tools/test/xref_SUITE_data/md/y__y.erl b/lib/tools/test/xref_SUITE_data/md/y__y.erl
new file mode 100644
index 0000000000..b2bb783fd8
--- /dev/null
+++ b/lib/tools/test/xref_SUITE_data/md/y__y.erl
@@ -0,0 +1,12 @@
+-module(y__y).
+
+-export([t/1]).
+
+t(A) ->
+ x__x:t(A).
+
+l() ->
+ l1().
+
+l1() ->
+ l().
diff --git a/lib/tools/test/xref_SUITE_data/read/read.beam.v1 b/lib/tools/test/xref_SUITE_data/read/read.beam.v1
new file mode 100644
index 0000000000..3b8e9c4c38
--- /dev/null
+++ b/lib/tools/test/xref_SUITE_data/read/read.beam.v1
Binary files differ
diff --git a/lib/tools/test/xref_SUITE_data/read/read.erl b/lib/tools/test/xref_SUITE_data/read/read.erl
new file mode 100644
index 0000000000..4a0cc280c3
--- /dev/null
+++ b/lib/tools/test/xref_SUITE_data/read/read.erl
@@ -0,0 +1,175 @@
+-module(read).
+
+-export([lc/0, funfuns/0, bi/0]).
+
+-xref({xx,ff,22}).
+-xref({{all,0},{no,0}}).
+-xref([{{all,0},{i,0}},{{all,0},{x2,5}}]).
+-xref([apa]).
+-xref({all,0}).
+-xref([{{{all},0},{no,0}},{{all,0},{m,x2,5}}]).
+-xref([{{a,14},{q,f,17}}]).
+-xref({{i,f,17},{g,18}}).
+-xref({{j,f,17},{i,g,18}}).
+
+-xref({{funfuns,0},{'$F_EXPR',177}}).
+-xref({{funfuns,0},{?MODULE,'$F_EXPR',178}}).
+-xref({{funfuns,0},{modul,'$F_EXPR',179}}).
+
+lc() ->
+ Tab = ets:new(),
+ [Mt||{_M,Mt} <- ets:tab2list(Tab)].
+
+funfuns() ->
+ A = variable,
+
+ %% Spawn...
+
+ %% Recognized. POS1=28.
+ spawn(fun() -> mod17:fun17() end),
+ spawn(fun local/0),
+ spawn(fun binary_to_term/1), % builtin, not collected
+ spawn({dist,func}),
+ spawn({dist,A}), % {dist,'$F_EXPR',0}
+ spawn_link(fun() -> mod17:fun17() end),
+ spawn_link({dist,func}),
+ spawn_link({dist,A}), % {dist,'$F_EXPR',0}
+
+ %% POS2=POS1+10
+ spawn({dist,func}(arg1,arg2), {d,f}),
+ spawn({dist,func}(arg1,arg2), fun() -> mod42:func() end),
+ spawn_link({dist,func}(arg1,arg2), {d,f}),
+ spawn_link({dist,func}(arg1,arg2), fun() -> mod42:func() end),
+
+ %% POS3=POS2+6
+ spawn(dist, func, [arg1,arg2]), % spawn/3 is builtin
+ spawn(expr, A, [arg1]), % {expr,'$F_EXPR',1}
+ spawn_link(dist, func, [arg1,arg2]), % spawn_link/3 is builtin
+ spawn_link(expr, A, [arg1,arg2]), % {expr,'$F_EXPR',2}
+
+ %% POS4=POS3+6
+ spawn(node, modul, function, []),
+ spawn(node, modul, A, [a]), % {modul,'$F_EXPR',1}
+ spawn({dist,func}(arg1,arg2), spm, spf, [a,b]),
+ spawn({dist,func}(arg1,arg2), spm, A, [a]), % {spm,'$F_EXPR',1}
+ spawn_link({dist,func}(arg1,arg2), spm, spf, [a,b]),
+ spawn_link({dist,func}(arg1,arg2), spm, A, [a]), % {spm,'$F_EXPR',1}
+ spawn_opt(spm, spf, [arg3, arg4], [opt1, bi()]),
+ spawn_opt(spm, A, [a], [opt1, bi()]), % {spm,'$F_EXPR',1}
+
+ %% Not recognized or invalid. POS5=POS4+10
+ spawn(A), % {'$M_EXPR','$F_EXPR',0}
+ spawn(17), % {'$M_EXPR','$F_EXPR',0}
+ spawn_link(A), % {'$M_EXPR','$F_EXPR',0}
+
+ %% POS6=POS5+5
+ spawn({a,b},[1008]), % {'$M_EXPR','$F_EXPR',0}
+ spawn_link({a,b},[1008]), % {'$M_EXPR','$F_EXPR',0}
+
+ spawn(n, A, A), % {n,'$F_EXPR',-1}
+
+ %% POS7=POS6+6
+ spawn(n, A,f,[1007]), % {'$M_EXPR',f,1}, spawn/3 is builtin
+ spawn_opt(A,f,[1007],[]), % {'$M_EXPR',f,1}
+
+ %% Apply...
+
+ %% Recognized. POS8=POS7+6
+ {hej,san}(1002),
+ {hej,A}(1002), % {hej,'$F_EXPR',1}
+ t:A(1003), % {t,'$F_EXPR',1}
+ apply({a,b},[1005]),
+ apply({a,A},[1005]), % {a,'$F_EXPR',1}
+ apply(m,f,[100011]),
+ apply(m,A,[100011]), % {m,'$F_EXPR',1}
+ %% POS9=POS8+8
+ apply(A, f, [bi()]), % {'$M_EXPR',f,1}
+ {erlang,apply}({a,b},[8888]),
+ {erlang,apply}({a,A},[8888]), % {a,'$F_EXPR',1}
+ {erlang,apply}({erlang,apply},[{erlang,not_a_function},[7777]]),
+ apply(erlang, apply, [erlang, apply, [mod, func, [atom77,tjohej]]]),
+ erlang:apply(foo), % not an apply, but an unknown function
+ apply(fun(X) -> math:add3(X) end, [7]),
+ (fun(X) -> q:f(X) end)(3008),
+
+ %% Not recognized or invalid. POS10=POS9+10
+ A:foo(1000), % {'$M_EXPR',foo,1}
+ A(17), % {'$M_EXPR','$F_EXPR',1}
+ A(17,[one,two]), % {'$M_EXPR','$F_EXPR',2}
+ apply(apa,[1001]), % {'$M_EXPR','$F_EXPR',1}
+ {mod1:fun1(hej),san}(1017), % {'$M_EXPR',san,1}
+ A:A(1004), % {'$M_EXPR','$F_EXPR',1}
+ %% POS11=POS10+7
+ apply(A,A,[1006]), % {'$M_EXPR','$F_EXPR',1}
+ apply(A,A,[1009 | 10010]), % {'$M_EXPR','$F_EXPR',-1}
+ apply(m,f,[10000 | 9999]), % {m,f,-1}
+ apply(m,f,a), % {m,f,-1}
+ 3(a), % {'$M_EXPR','$F_EXPR',1}
+ apply(3,[a]), % {'$M_EXPR','$F_EXPR',1}
+
+ %% POS12=POS11+8
+ apply(A, A), % number of arguments is not known, {'$M_EXPR','$F_EXPR',-1}
+ Args0 = [list],
+ Args = [a | Args0], % number of arguments is known
+ apply(A, Args), % {'$M_EXPR','$F_EXPR',2}
+ apply(m3, f3, Args), %
+ NotArgs = [is_not, a | list], % number of arguments is not known
+ apply(A, NotArgs), % {'$M_EXPR','$F_EXPR',-1}
+ apply(m4, f4, NotArgs), % {m4,f4,-1}
+
+ %% OTP Internal. POS13=POS12+10
+ erts_debug:apply(dm, df, [17], foobar),
+ erts_debug:apply(debug, A, [], A), % {debug,'$F_EXPR',0}
+ erts_debug:apply(A, A, A, A). % {'$M_EXPR','$F_EXPR',-1}
+
+bi() when length([]) > 17 ->
+ foo:module_info(),
+ module_info(),
+ A = tjo,
+ t:foo(A),
+ case true of
+ true when integer(1) ->
+ X = foo;
+ false ->
+ X = flopp
+ end,
+ X == A;
+bi() ->
+ %% POS14=POS13+18
+ Z = fun(Y) -> Y end,
+ case true of
+ true when length([a,b]) > 4 ->
+ F = fun(X) -> X end,
+ F(3);
+ false ->
+ F = 17,
+ F(3) % {'$M_EXPR','$F_EXPR',1}
+ end,
+ Z(apa),
+ erlang:module_info();
+bi() ->
+ Bin11 = <<1, 17, 42>>,
+ Bin12 = <<"abc">>,
+ false = (Bin11 == Bin12),
+ A = 1, B = 17,
+ Bin3 = <<A, B, (bi()):16>>,
+ <<D:16, E, F/binary>> = Bin3,
+ X = 9, <<(X+1):8>>,
+ _Fyy = <<X:4/little-signed-integer-unit:8>>,
+ D + E + F.
+%bi() ->
+% %% POS15=POS14+13
+% try
+% foo:t(),
+% bar:t()
+% of
+% {v,1} ->
+% local();
+% {v,2} ->
+% foo:t()
+% catch
+% {'EXIT',_} -> bar:t()
+% end.
+
+local() ->
+ true.
diff --git a/lib/tools/test/xref_SUITE_data/rel2/lib/app1-1.0/ebin/dummy b/lib/tools/test/xref_SUITE_data/rel2/lib/app1-1.0/ebin/dummy
new file mode 100644
index 0000000000..7f62a93220
--- /dev/null
+++ b/lib/tools/test/xref_SUITE_data/rel2/lib/app1-1.0/ebin/dummy
@@ -0,0 +1,2 @@
+This directory is not empty.
+Prevents winzip from removing the directory.
diff --git a/lib/tools/test/xref_SUITE_data/rel2/lib/app1-1.1/ebin/dummy b/lib/tools/test/xref_SUITE_data/rel2/lib/app1-1.1/ebin/dummy
new file mode 100644
index 0000000000..7f62a93220
--- /dev/null
+++ b/lib/tools/test/xref_SUITE_data/rel2/lib/app1-1.1/ebin/dummy
@@ -0,0 +1,2 @@
+This directory is not empty.
+Prevents winzip from removing the directory.
diff --git a/lib/tools/test/xref_SUITE_data/rel2/lib/app2-1.1/ebin/dummy b/lib/tools/test/xref_SUITE_data/rel2/lib/app2-1.1/ebin/dummy
new file mode 100644
index 0000000000..7f62a93220
--- /dev/null
+++ b/lib/tools/test/xref_SUITE_data/rel2/lib/app2-1.1/ebin/dummy
@@ -0,0 +1,2 @@
+This directory is not empty.
+Prevents winzip from removing the directory.
diff --git a/lib/tools/test/xref_SUITE_data/rel2/x.erl b/lib/tools/test/xref_SUITE_data/rel2/x.erl
new file mode 100644
index 0000000000..2125760776
--- /dev/null
+++ b/lib/tools/test/xref_SUITE_data/rel2/x.erl
@@ -0,0 +1,16 @@
+-module(x).
+
+-export([t/0, xx/0]).
+-deprecated({t,0,eventually}).
+
+t() ->
+ true.
+
+xx() ->
+ x:undef().
+
+l() ->
+ l1().
+
+l1() ->
+ l().
diff --git a/lib/tools/test/xref_SUITE_data/rel2/y.erl b/lib/tools/test/xref_SUITE_data/rel2/y.erl
new file mode 100644
index 0000000000..2a6e65e78f
--- /dev/null
+++ b/lib/tools/test/xref_SUITE_data/rel2/y.erl
@@ -0,0 +1,6 @@
+-module(y).
+
+-export([t/0]).
+
+t() ->
+ x:t().
diff --git a/lib/tools/test/xref_SUITE_data/update/x.erl.1 b/lib/tools/test/xref_SUITE_data/update/x.erl.1
new file mode 100644
index 0000000000..6af13329a2
--- /dev/null
+++ b/lib/tools/test/xref_SUITE_data/update/x.erl.1
@@ -0,0 +1,6 @@
+-module(x).
+
+-export([t/0]).
+
+t() ->
+ erlang:atom_to_list(tjohoo).
diff --git a/lib/tools/test/xref_SUITE_data/update/x.erl.2 b/lib/tools/test/xref_SUITE_data/update/x.erl.2
new file mode 100644
index 0000000000..e303a758d2
--- /dev/null
+++ b/lib/tools/test/xref_SUITE_data/update/x.erl.2
@@ -0,0 +1,6 @@
+-module(x).
+
+-export([t/0]).
+
+t() ->
+ erlang:list_to_atom("tjohoo").
diff --git a/lib/tools/vsn.mk b/lib/tools/vsn.mk
index 644e8b719b..faea408cc2 100644
--- a/lib/tools/vsn.mk
+++ b/lib/tools/vsn.mk
@@ -1,19 +1 @@
-# This is an -*-makefile-*- file.
-# %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%
-
-TOOLS_VSN = 2.6.5
+TOOLS_VSN = 2.6.5.1
diff --git a/lib/tv/vsn.mk b/lib/tv/vsn.mk
index be1981b755..9b8c1a68c7 100644
--- a/lib/tv/vsn.mk
+++ b/lib/tv/vsn.mk
@@ -1,20 +1 @@
-#
-# %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%
-#
-
TV_VSN = 2.1.4.4
diff --git a/lib/typer/src/typer_annotator.erl b/lib/typer/src/typer_annotator.erl
index 17eeeb6dfe..68a8f03a5c 100644
--- a/lib/typer/src/typer_annotator.erl
+++ b/lib/typer/src/typer_annotator.erl
@@ -1,20 +1,20 @@
%% -*- erlang-indent-level: 2 -*-
%%
%% %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%
%%
%%============================================================================
@@ -227,6 +227,8 @@ get_type({{M, F, A} = MFA, Range, Arg}, CodeServer, RecMap) ->
Sig = erl_types:t_fun(Arg, Range),
case dialyzer_contracts:check_contract(Contract, Sig) of
ok -> {{F, A}, {contract, Contract}};
+ {error, {extra_range, _, _}} ->
+ {{F, A}, {contract, Contract}};
{error, invalid_contract} ->
CString = dialyzer_contracts:contract_to_string(Contract),
SigString = dialyzer_utils:format_sig(Sig, RecMap),
@@ -235,7 +237,7 @@ get_type({{M, F, A} = MFA, Range, Arg}, CodeServer, RecMap) ->
"\t The contract is: " ++ CString ++ "\n" ++
"\t but the inferred signature is: ~s",
[M, F, A, SigString]));
- {error, Msg} ->
+ {error, Msg} when is_list(Msg) -> % Msg is a string()
typer:error(
io_lib:format("Error in contract of function ~w:~w/~w: ~s",
[M, F, A, Msg]))
diff --git a/lib/typer/vsn.mk b/lib/typer/vsn.mk
index 9558412375..285fa62da3 100644
--- a/lib/typer/vsn.mk
+++ b/lib/typer/vsn.mk
@@ -1 +1 @@
-TYPER_VSN = 0.1.7.3
+TYPER_VSN = 0.1.7.4
diff --git a/lib/webtool/doc/src/notes.xml b/lib/webtool/doc/src/notes.xml
index 644cf7f7a8..dc325b5b61 100644
--- a/lib/webtool/doc/src/notes.xml
+++ b/lib/webtool/doc/src/notes.xml
@@ -4,7 +4,7 @@
<chapter>
<header>
<copyright>
- <year>2004</year><year>2009</year>
+ <year>2004</year><year>2010</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
@@ -13,12 +13,12 @@
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>Webtool Release Notes</title>
@@ -31,6 +31,21 @@
<p>This document describes the changes made to the Webtool
application.</p>
+<section><title>WebTool 0.8.6</title>
+
+ <section><title>Improvements and New Features</title>
+ <list>
+ <item>
+ <p>
+ Misc updates</p>
+ <p>
+ Own Id: OTP-8456</p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
<section><title>WebTool 0.8.5</title>
<section><title>Improvements and New Features</title>
diff --git a/lib/webtool/doc/src/webtool_chapter.xml b/lib/webtool/doc/src/webtool_chapter.xml
index ceadce382d..f72a255b0a 100644
--- a/lib/webtool/doc/src/webtool_chapter.xml
+++ b/lib/webtool/doc/src/webtool_chapter.xml
@@ -212,16 +212,13 @@ http://Servername:Port/ErlScriptAlias/Mod/Func<?QueryString> ]]></code>
header("text/html").
header(MimeType) -&gt;
- "Content-type: " ++ MimeType ++ "\\r\
-\\r\
-".
+ "Content-type: " ++ MimeType ++ "\r\n\r\n".
html_header() -&gt;
"&lt;HTML&gt;
&lt;HEAD&gt;
&lt;TITLE&gt;Hello world Example &lt;/TITLE&gt;
- &lt;/HEAD&gt;\
-".
+ &lt;/HEAD&gt;\n".
helloworld_body()-&gt;
"&lt;BODY&gt;Hello World&lt;/BODY&gt;".
diff --git a/lib/webtool/vsn.mk b/lib/webtool/vsn.mk
index 8124b16816..712e3abbaf 100644
--- a/lib/webtool/vsn.mk
+++ b/lib/webtool/vsn.mk
@@ -1,2 +1 @@
-WEBTOOL_VSN=0.8.5
-
+WEBTOOL_VSN=0.8.6
diff --git a/lib/wx/api_gen/gen_util.erl b/lib/wx/api_gen/gen_util.erl
index d47fd579a5..859317bdef 100644
--- a/lib/wx/api_gen/gen_util.erl
+++ b/lib/wx/api_gen/gen_util.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%
%%
%% Some utilities
@@ -205,42 +205,65 @@ halt(Reason) ->
end.
erl_copyright() ->
+ StartYear = start_year(get(current_class)),
w("%%~n",[]),
w("%% %CopyrightBegin%~n",[]),
- w("%% ~n",[]),
- w("%% Copyright Ericsson AB 2008-2009. All Rights Reserved.~n",[]),
- w("%% ~n",[]),
+ w("%%~n",[]),
+ w("%% Copyright Ericsson AB ~p-2010. All Rights Reserved.~n",
+ [StartYear]),
+ w("%%~n",[]),
w("%% The contents of this file are subject to the Erlang Public License,~n",[]),
w("%% Version 1.1, (the \"License\"); you may not use this file except in~n",[]),
w("%% compliance with the License. You should have received a copy of the~n",[]),
w("%% Erlang Public License along with this software. If not, it can be~n",[]),
w("%% retrieved online at http://www.erlang.org/.~n",[]),
- w("%% ~n",[]),
+ w("%%~n",[]),
w("%% Software distributed under the License is distributed on an \"AS IS\"~n",[]),
w("%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See~n",[]),
w("%% the License for the specific language governing rights and limitations~n",[]),
w("%% under the License.~n",[]),
- w("%% ~n",[]),
+ w("%%~n",[]),
w("%% %CopyrightEnd%~n",[]).
c_copyright() ->
w("/*~n",[]),
w(" * %CopyrightBegin%~n",[]),
- w(" * ~n",[]),
- w(" * Copyright Ericsson AB 2008-2009. All Rights Reserved.~n",[]),
- w(" * ~n",[]),
+ w(" *~n",[]),
+ w(" * Copyright Ericsson AB 2008-2010. All Rights Reserved.~n",[]),
+ w(" *~n",[]),
w(" * The contents of this file are subject to the Erlang Public License,~n",[]),
w(" * Version 1.1, (the \"License\"); you may not use this file except in~n",[]),
w(" * compliance with the License. You should have received a copy of the~n",[]),
w(" * Erlang Public License along with this software. If not, it can be~n",[]),
w(" * retrieved online at http://www.erlang.org/.~n",[]),
- w(" * ~n",[]),
+ w(" *~n",[]),
w(" * Software distributed under the License is distributed on an \"AS IS\"~n",[]),
w(" * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See~n",[]),
w(" * the License for the specific language governing rights and limitations~n",[]),
w(" * under the License.~n",[]),
- w(" * ~n",[]),
+ w(" *~n",[]),
w(" * %CopyrightEnd% ~n",[]),
w("*/~n",[]).
-
+start_year("wxAuiManagerEvent") -> 2009;
+start_year("wxAuiNotebookEvent") -> 2009;
+start_year("wxChoicebook") -> 2009;
+start_year("wxGridCellBoolEditor") -> 2009;
+start_year("wxGridCellBoolRenderer") -> 2009;
+start_year("wxGridCellChoiceEditor") -> 2009;
+start_year("wxGridCellFloatEditor") -> 2009;
+start_year("wxGridCellFloatRenderer") -> 2009;
+start_year("wxGridCellNumberEditor") -> 2009;
+start_year("wxGridCellNumberRenderer") -> 2009;
+start_year("wxGridCellStringRenderer") -> 2009;
+start_year("wxGridCellTextEditor") -> 2009;
+start_year("wxHtmlLinkEvent") -> 2009;
+start_year("wxHtmlWindow") -> 2009;
+start_year("wxListbook") -> 2009;
+start_year("wxLogNull") -> 2009;
+start_year("wxSpinEvent") -> 2009;
+start_year("wxSplitterEvent") -> 2009;
+start_year("wxSplitterWindow") -> 2009;
+start_year("wxToolbook") -> 2009;
+start_year("wxTreebook") -> 2009;
+start_year(_) -> 2008.
diff --git a/lib/wx/api_gen/gl_gen_c.erl b/lib/wx/api_gen/gl_gen_c.erl
index 5c72499790..864ce8b1ac 100644
--- a/lib/wx/api_gen/gl_gen_c.erl
+++ b/lib/wx/api_gen/gl_gen_c.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%
%%
%%%-------------------------------------------------------------------
@@ -44,7 +44,7 @@ gen(GLFuncs, GLUFuncs) ->
%% Marshal funcs
open_write("../c_src/gen/gl_funcs.cpp"),
c_copyright(),
- w("/***** This file is generated do not edit ****/ ~n~n", []),
+ w("/***** This file is generated do not edit ****/~n~n", []),
w("#include <stdio.h>~n", []),
w("#include <string.h>~n", []),
w("#include \"../wxe_impl.h\"~n", []),
@@ -67,8 +67,8 @@ gen(GLFuncs, GLUFuncs) ->
" driver_send_term(WXE_DRV_PORT,caller,rt,8);~n"
" return ;~n }~n };~n~n", []),
- w(" switch(op) ~n{~n",[]),
- w(" case 5000: ~n wxe_tess_impl(bp, caller); ~n break;~n", []),
+ w(" switch(op)~n{~n",[]),
+ w(" case 5000:~n wxe_tess_impl(bp, caller);~n break;~n", []),
w(" case WXE_BIN_INCR:~n driver_binary_inc_refc(bins[0]->bin);~n break;~n",[]),
w(" case WXE_BIN_DECR:~n driver_binary_dec_refc(bins[0]->bin);~n break;~n",[]),
@@ -93,23 +93,23 @@ funcs(F) ->
func(#func{where=erl}) -> ok;
func(#func{id=Id,alt={has_vector,_,FuncName}}) ->
#func{name=Name,type=T,params=As} = get(FuncName),
- w("case ~p: { // ~s ~n", [Id,Name]),
+ w("case ~p: { // ~s~n", [Id,Name]),
put(bin_count,-1),
As1 = declare_vars(T, As),
As2 = decode_args(As1),
As3 = call_gl(Name,T,As2),
build_return_vals(T,As3),
free_args(),
- w("}; break; ~n", []);
+ w("}; break;~n", []);
func(#func{name=Name,id=Id,type=T,params=As,alt=_Alt}) ->
- w("case ~p: { // ~s ~n", [Id,Name]),
+ w("case ~p: { // ~s~n", [Id,Name]),
put(bin_count,-1),
As2 = decode_args(As),
declare_vars(T, As), %% Unusal order but it's c++
As3 = call_gl(Name,T,As2),
build_return_vals(T,As3),
free_args(),
- w("}; break; ~n", []).
+ w("}; break;~n", []).
declare_vars(void,Ps) ->
[declare_var(P) || P <- Ps];
@@ -183,7 +183,7 @@ decode_arg(P=#arg{name=Name,type=#type{name=T,base=string,single=list}},A0) ->
w(" int * ~sTotSize = (int *) bp; bp += 4;~n",[Name]),
%% w(" if(*~sLen > 256) *~sLen = 256;", []),
w(" ~s **~s;~n", [T,Name]),
- w(" ~s = (~s **) driver_alloc(sizeof(~s *) * *~sLen); ~n",[Name, T, T, Name]),
+ w(" ~s = (~s **) driver_alloc(sizeof(~s *) * *~sLen);~n",[Name, T, T, Name]),
store_free(Name),
w(" for(int i=0;i<*~sLen;i++) {~n", [Name]),
w(" ~s[i] = (~s *) bp; bp += 1+strlen(bp);};~n",[Name,T]),
@@ -353,7 +353,7 @@ build_return_vals(Type,As) ->
case Vars of
none -> ignore;
_ ->
- w(" driver_free(rt); ~n", [])
+ w(" driver_free(rt);~n", [])
end,
[w(" ~s~n", [Name]) || Name <- FreeList],
ok
@@ -492,7 +492,7 @@ build_ret(Name,_Q,T=#type{}) ->
gen_defines(GLFuncs,GLUFuncs) ->
open_write("../c_src/gen/gl_fdefs.h"),
c_copyright(),
- w("/***** This file is generated do not edit ****/ ~n~n", []),
+ w("/***** This file is generated do not edit ****/~n~n", []),
w("#ifdef WX_DEF_EXTS~n", []),
w("# define WXE_EXTERN~n", []),
w("#else~n# define WXE_EXTERN extern~n", []),
@@ -543,7 +543,7 @@ fdef_types(As) ->
gl_gen_init(Funcs) ->
open_write("../c_src/gen/gl_finit.h"),
c_copyright(),
- w("/***** This file is generated do not edit ****/ ~n~n", []),
+ w("/***** This file is generated do not edit ****/~n~n", []),
w("static struct {\n"
" const char * name;\n"
" const char * alt;\n"
@@ -557,7 +557,7 @@ gl_gen_init(Funcs) ->
glu_gen_init(Funcs) ->
open_write("../c_src/gen/glu_finit.h"),
c_copyright(),
- w("/***** This file is generated do not edit ****/ ~n~n", []),
+ w("/***** This file is generated do not edit ****/~n~n", []),
w("static struct {\n"
" const char * name;\n"
" const char * alt;\n"
diff --git a/lib/wx/api_gen/gl_gen_erl.erl b/lib/wx/api_gen/gl_gen_erl.erl
index 3e436100b6..07e4d6f783 100644
--- a/lib/wx/api_gen/gl_gen_erl.erl
+++ b/lib/wx/api_gen/gl_gen_erl.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%
%%
%%%-------------------------------------------------------------------
@@ -86,14 +86,14 @@ gl_api(Fs) ->
erl_copyright(),
w("~n%% OPENGL API~n~n", []),
w("%% This file is generated DO NOT EDIT~n~n", []),
- w("%% @doc Standard OpenGL api. ~n", []),
+ w("%% @doc Standard OpenGL api.~n", []),
w("%% See <a href=\"http://www.opengl.org/sdk/docs/man/\">www.opengl.org</a>~n",[]),
w("%%~n", []),
- w("%% Booleans are represented by integers 0 and 1. ~n~n", []),
+ w("%% Booleans are represented by integers 0 and 1.~n~n", []),
w("%% @type wx_mem(). see wx.erl on memory allocation functions~n", []),
w("%% @type enum(). An integer defined in gl.hrl~n", []),
w("%% @type offset(). An integer which is an offset in an array~n", []),
- w("%% @type clamp(). A float clamped between 0.0 - 1.0 ~n", []),
+ w("%% @type clamp(). A float clamped between 0.0 - 1.0~n", []),
w("-module(gl).~n~n",[]),
w("-compile(inline).~n", []),
@@ -106,7 +106,7 @@ gl_api(Fs) ->
ExportList = lists:map(Exp,Fs),
w("~n-export([~s]).~n~n", [args(fun(EF) -> EF end, ",", ExportList, 60)]),
- w("~n%% API ~n~n", []),
+ w("~n%% API~n~n", []),
[gen_funcs(F) || F <- Fs],
close(),
ok.
@@ -116,14 +116,14 @@ glu_api(Fs) ->
erl_copyright(),
w("~n%% OPENGL UTILITY API~n~n", []),
w("%% This file is generated DO NOT EDIT~n~n", []),
- w("%% @doc A part of the standard OpenGL Utility api. ~n", []),
+ w("%% @doc A part of the standard OpenGL Utility api.~n", []),
w("%% See <a href=\"http://www.opengl.org/sdk/docs/man/\">www.opengl.org</a>~n",[]),
w("%%~n", []),
- w("%% Booleans are represented by integers 0 and 1. ~n~n", []),
+ w("%% Booleans are represented by integers 0 and 1.~n~n", []),
w("%% @type wx_mem(). see wx.erl on memory allocation functions~n", []),
w("%% @type enum(). An integer defined in gl.hrl~n", []),
w("%% @type offset(). An integer which is an offset in an array~n", []),
- w("%% @type clamp(). A float clamped between 0.0 - 1.0 ~n~n", []),
+ w("%% @type clamp(). A float clamped between 0.0 - 1.0~n~n", []),
w("-module(glu).~n",[]),
w("-compile(inline).~n", []),
@@ -134,7 +134,7 @@ glu_api(Fs) ->
ExportList = ["tesselate/2" | lists:map(Exp,Fs)],
w("~n-export([~s]).~n~n", [args(fun(EF) -> EF end, ",", ExportList, 60)]),
- w("~n%% API ~n~n", []),
+ w("~n%% API~n~n", []),
w("%% @spec (Vec3, [Vec3]) -> {Triangles, VertexPos}~n",[]),
w("%% Vec3 = {float(),float(),float()}~n",[]),
@@ -143,8 +143,8 @@ glu_api(Fs) ->
w("%% @doc General purpose polygon triangulation.~n",[]),
w("%% The first argument is the normal and the second a list of~n"
"%% vertex positions. Returned is a list of indecies of the vertices~n"
- "%% and a binary (64bit native float) containing an array of ~n"
- "%% vertex positions, it starts with the vertices in Vs and ~n"
+ "%% and a binary (64bit native float) containing an array of~n"
+ "%% vertex positions, it starts with the vertices in Vs and~n"
"%% may contain newly created vertices in the end.~n", []),
w("tesselate({Nx,Ny,Nz}, Vs) ->~n",[]),
@@ -413,7 +413,7 @@ marshal_arg(#type{size=Sz,name=Type,single={tuple_list,TSz}},Name,A0) ->
marshal_arg(T=#type{}, Name, Align) ->
io:format("{\"~s\", {\"~s\", }}.~n", [get(current_func),lowercase(Name)]),
%%?error({unhandled_type, {Name,T}}).
- w(" Don't know how to marshal this type ~p ~p ~n", [T,Name]),
+ w(" Don't know how to marshal this type ~p ~p~n", [T,Name]),
align(8,Align,"").
% Make sure that it is aligned before adding it, and update alignment
@@ -581,7 +581,7 @@ gen_debug(GL, GLU) ->
open_write("../src/gen/gl_debug.hrl"),
erl_copyright(),
w("%% This file is generated DO NOT EDIT~n~n", []),
- w("gldebug_table() -> ~n[~n", []),
+ w("gldebug_table() ->~n[~n", []),
[printd(F,gl) || F <- GL],
[printd(F,glu) || F <- GLU],
w(" {-1, {mod, func, -1}}~n",[]),
diff --git a/lib/wx/api_gen/wx_gen.erl b/lib/wx/api_gen/wx_gen.erl
index 50dd2d6f51..2ed4476440 100644
--- a/lib/wx/api_gen/wx_gen.erl
+++ b/lib/wx/api_gen/wx_gen.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%
%%
%% Api wrapper generator
@@ -73,8 +73,7 @@ gen_xml() ->
-record(hs,{alias,skip,fs,fopt,ev,acc,info}).
init_defs(List0) ->
- List1 = to_lists(List0),
- lists:map(fun mangle_info/1, List1).
+ [mangle_info(L) || L <- to_lists(List0)].
mangle_info(E={enum,Type0,SkipStr}) ->
Type = case is_atom(Type0) of true -> atom_to_list(Type0); false -> Type0 end,
@@ -138,9 +137,9 @@ parse_defs([{class,Name,Parent,Info}|Rest], Acc0) ->
Defs0 = load_members(FileName, Name, gb_trees:empty(), Tab, Type, Info),
put(current_class, Name),
- Class0 = #class{name=name(Name,Info),parent=Parent,
+ Class0 = #class{name=name(Name,Info), parent=Parent,
doc=get_value(doc,Info#hs.info,undefined),
- file=FileName,options=Info#hs.info, id=next_id(class_id)},
+ file=FileName, options=Info#hs.info, id=next_id(class_id)},
ParseClass = fun(Member,{Class,Dfs}) ->
parse_class(Member,Tab,Dfs,Class,Info)
end,
@@ -161,12 +160,11 @@ parse_defs([], Acc) -> reverse(Acc).
meta_info(C=#class{name=CName,methods=Ms0}) ->
Ms = lists:append(Ms0),
- HaveConstructor =
- lists:keysearch(constructor, #method.method_type, Ms) =/= false,
+ HaveConstructor = lists:keymember(constructor, #method.method_type, Ms),
case lists:keysearch(destructor, #method.method_type, Ms) of
false when HaveConstructor ->
- Dest = #method{name="destroy",id=next_id(func_id),
- method_type=destructor, params=[this(CName)]},
+ Dest = #method{name = "destroy", id = next_id(func_id),
+ method_type = destructor, params = [this(CName)]},
C#class{methods = [[Dest]|Ms0]};
false ->
C#class{abstract = true};
@@ -451,9 +449,9 @@ find_erl_alias_name(MName,Ps,Fopts) ->
_ ->
Find = fun({all,AliasName},Acc) -> [AliasName|Acc];
({Var,AliasName},Acc) ->
- case lists:keysearch(Var, #param.name, Ps) of
- {value, _} -> [AliasName|Acc];
- _ -> Acc
+ case lists:keymember(Var, #param.name, Ps) of
+ true -> [AliasName|Acc];
+ false -> Acc
end
end,
case lists:foldl(Find, [], Aliases) of
@@ -699,10 +697,12 @@ parse_type2([N="wxArrayInt"|R],Info,Opts,T) ->
parse_type2(R,Info,Opts,T#type{name=N,base=int,single=array});
parse_type2([N="wxArrayDouble"|R],Info,Opts,T) ->
parse_type2(R,Info,Opts,T#type{name=N,base=double,single=array});
-parse_type2([N="wxTreeItemId"|R],Info,Opts,T) ->
- parse_type2(R,Info,Opts,T#type{name=N,base={ref,N}});
+parse_type2([N="wxTreeItemId"|R],Info,Opts,T) -> %% Use Pointer as Ids
+ parse_type2(R,Info,Opts,T#type{name=N,base=int64});
+parse_type2([N="wxTreeItemIdValue"|R],Info,Opts,T) -> %% Use Pointer as Ids
+ parse_type2(R,Info,Opts,T#type{name=N,base=int64});
parse_type2([N="wxArrayTreeItemIds"|R],Info,Opts,T) ->
- parse_type2(R,Info,Opts,T#type{name=N,base={ref,"wxTreeItemId"},single=array});
+ parse_type2(R,Info,Opts,T#type{name=N,base=int64,single=array});
parse_type2([N="wxTreeItemData"|R],Info,Opts,T) ->
parse_type2(R,Info,Opts,T#type{name="wxETreeItemData",base={term,N}});
parse_type2([N="wxClientData"|R],Info,Opts,T) ->
@@ -871,11 +871,14 @@ add_method2(M0=#method{name=Name,params=Ps0,type=T0},#class{name=CName,parent=Pa
end,
M1 = M0#method{defined_in=CName,
min_arity = length(Req),
- max_arity = length(Req) + if length(Opt) > 0 -> 1; true -> 0 end,
+ max_arity = length(Req) + case Opt of
+ [_ | _] -> 1;
+ _ -> 0
+ end,
type = Type,
method_type = IsStatic,
where = Where,
- id=next_id(func_id),
+ id = next_id(func_id),
pre_hook = get_opt(pre_hook, Name, length(Ps), Opts),
post_hook = get_opt(post_hook, Name, length(Ps), Opts),
doc = get_opt(doc, Name, length(Ps), Opts)
@@ -1035,10 +1038,10 @@ types_differ([list|R1], [opt_list|R2]) ->
types_differ([opt_list|R1], [list|R2]) ->
types_differ(R1,R2);
types_differ([C1|R1], [C2|R2]) when is_tuple(C1), is_tuple(C2) ->
- (size(C1) =/= size(C2)) orelse types_differ(R1,R2);
+ (tuple_size(C1) =/= tuple_size(C2)) orelse types_differ(R1,R2);
types_differ([C1|_R1], [_C2|_R2]) when is_tuple(C1) ->
true;
-types_differ([_C1|_R1], [C2|_R2]) when is_tuple(C2)->
+types_differ([_C1|_R1], [C2|_R2]) when is_tuple(C2) ->
true;
types_differ([_C1|R1], [_C2|R2]) -> %% More cases?
types_differ(R1,R2);
@@ -1082,6 +1085,7 @@ type_foot_print(#type{base=long}) -> int;
type_foot_print(#type{base=binary}) -> binary;
type_foot_print(#type{base={binary,_}}) -> binary;
type_foot_print(#type{base=int}) -> int;
+type_foot_print(#type{base=int64}) -> int;
type_foot_print(#type{base=bool}) -> bool;
%%type_foot_print(#type{base=datetime}) -> datetime;
type_foot_print(#type{base=float}) -> float;
@@ -1195,7 +1199,7 @@ name(Name0, #hs{alias=Alias}) ->
Name0;
"esaBrekciP" ++ _ -> %% Arrg uses base
Name0;
- "esaB" ++ Rest when hd(Name0) == $w ->
+ "esaB" ++ Rest when hd(Name0) =:= $w ->
%% Arrg Some decl uses base class directly
reverse(Rest);
_F ->
diff --git a/lib/wx/api_gen/wx_gen_cpp.erl b/lib/wx/api_gen/wx_gen_cpp.erl
index fd0bea04ae..9e9f8799c7 100644
--- a/lib/wx/api_gen/wx_gen_cpp.erl
+++ b/lib/wx/api_gen/wx_gen_cpp.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%
%%
%%%-------------------------------------------------------------------
@@ -38,7 +38,7 @@
gen(Defs) ->
open_write("../c_src/gen/wxe_derived_dest.h"),
c_copyright(),
- w("~n/***** This file is generated do not edit ****/ ~n~n", []),
+ w("~n/***** This file is generated do not edit ****/~n~n", []),
gen_derived_dest(Defs),
close(),
@@ -91,16 +91,16 @@ gen_derived_dest_2(C=#class{name=Class}) ->
case is_derived(C) of
true ->
?WTC("gen_derived_dest_2"),
- w("class E~s : public ~s { ~n",[Class,Class]),
+ w("class E~s : public ~s {~n",[Class,Class]),
case Class of
"wxGLCanvas" -> %% Special for cleaning up gl context
w(" public: ~~E~s() {deleteActiveGL(this);"
- "((WxeApp *)wxTheApp)->clearPtr(this);}; ~n", [Class]);
+ "((WxeApp *)wxTheApp)->clearPtr(this);};~n", [Class]);
_ ->
- w(" public: ~~E~s() {((WxeApp *)wxTheApp)->clearPtr(this);}; ~n", [Class])
+ w(" public: ~~E~s() {((WxeApp *)wxTheApp)->clearPtr(this);};~n", [Class])
end,
gen_constructors(C),
- w("}; ~n~n", []);
+ w("};~n~n", []);
false ->
ignore
end.
@@ -147,7 +147,7 @@ gen_type({merged, _, _T1,_, _, T2,_}, 2) ->
gen_type(T2,error).
gen_funcs(Defs) ->
- w("~n/***** This file is generated do not edit ****/ ~n~n"),
+ w("~n/***** This file is generated do not edit ****/~n~n"),
w("#include <wx/wx.h>~n"),
w("#include \"../wxe_impl.h\"~n"),
w("#include \"../wxe_events.h\"~n"),
@@ -156,21 +156,21 @@ gen_funcs(Defs) ->
w("#include \"wxe_derived_dest.h\"~n~n"),
w("void WxeApp::wxe_dispatch(wxeCommand& Ecmd)~n{~n"),
- w(" char * bp = Ecmd.buffer; ~n"),
+ w(" char * bp = Ecmd.buffer;~n"),
w(" wxeMemEnv *memenv = getMemEnv(Ecmd.port);~n"),
%% w(" wxMBConvUTF32 UTFconverter;~n"),
w(" wxeReturn rt = wxeReturn(WXE_DRV_PORT, Ecmd.caller, true);~n"),
- w(" try { ~n"),
- w(" switch (Ecmd.op) ~n{~n"),
-%% w(" case WXE_CREATE_PORT: ~n", []),
-%% w(" { newMemEnv(Ecmd.port); } break; ~n", []),
-%% w(" case WXE_REMOVE_PORT: ~n", []),
-%% w(" { destroyMemEnv(Ecmd.port); } break; ~n", []),
- w(" case DESTROY_OBJECT: { ~n"),
+ w(" try {~n"),
+ w(" switch (Ecmd.op)~n{~n"),
+%% w(" case WXE_CREATE_PORT:~n", []),
+%% w(" { newMemEnv(Ecmd.port); } break;~n", []),
+%% w(" case WXE_REMOVE_PORT:~n", []),
+%% w(" { destroyMemEnv(Ecmd.port); } break;~n", []),
+ w(" case DESTROY_OBJECT: {~n"),
w(" wxObject *This = (wxObject *) getPtr(bp,memenv); "),
w(" if(This) {"),
w(" ((WxeApp *) wxTheApp)->clearPtr((void *) This);~n"),
- w(" delete This; }~n } break; ~n"),
+ w(" delete This; }~n } break;~n"),
w(" case WXE_REGISTER_OBJECT: {~n"
" registerPid(bp, Ecmd.caller, memenv);~n"
" rt.addAtom(\"ok\");~n"
@@ -190,7 +190,7 @@ gen_funcs(Defs) ->
w(" }~n"),
w("} // switch~n"),
w(" rt.send();~n"),
- w("} catch (wxe_badarg badarg) { // try ~n"),
+ w("} catch (wxe_badarg badarg) { // try~n"),
w(" wxeReturn error = wxeReturn(WXE_DRV_PORT, Ecmd.caller, false);"),
w(" error.addAtom(\"_wxe_error_\");~n"),
w(" error.addInt((int) Ecmd.op);~n"),
@@ -199,7 +199,7 @@ gen_funcs(Defs) ->
w(" error.addTupleCount(2);~n"),
w(" error.addTupleCount(3);~n"),
w(" error.send();~n"),
- w("}} /* The End */ ~n"),
+ w("}} /* The End */~n"),
Res.
gen_class(C=#class{name=Name,methods=Ms,options=Opts}) ->
@@ -233,7 +233,7 @@ gen_method(_CName, M=#method{where=erl_no_opt}) -> M;
gen_method(CName, M=#method{where=taylormade, name=Name, id=Id}) ->
{ok, Bin} = file:read_file(filename:join([wx_extra, CName ++".c_src"])),
Str0 = binary_to_list(Bin),
- %% io:format("C++ Class ~p ~p ~n", [CName, Name]),
+ %% io:format("C++ Class ~p ~p~n", [CName, Name]),
{match, [Str1]} = re:run(Str0, "<<"++Name++"(.*)"++Name++">>",
[dotall, {capture, all_but_first, list}]),
@@ -244,13 +244,13 @@ gen_method(CName, M=#method{name=N,params=[Ps],method_type=destructor,id=MethodI
case hd(reverse(wx_gen_erl:parents(CName))) of
root ->
?WTC("gen_method"),
- w("case ~s: { // ~s::~s ~n", [wx_gen_erl:get_unique_name(MethodId),CName,N]),
+ w("case ~s: { // ~s::~s~n", [wx_gen_erl:get_unique_name(MethodId),CName,N]),
decode_arguments([Ps]),
w(" if(This) {", []),
w(" ((WxeApp *) wxTheApp)->clearPtr((void *) This);~n", []),
w(" delete This;}~n", []),
free_args(),
- w(" break; ~n}~n", []);
+ w(" break;~n}~n", []);
object -> %% Use default
ignore
end,
@@ -259,7 +259,7 @@ gen_method(CName, M=#method{name=N,params=Ps0,type=T,method_type=MT,id=MethodId
put(current_func, N),
put(bin_count,-1),
?WTC("gen_method"),
- w("case ~s: { // ~s::~s ~n", [wx_gen_erl:get_unique_name(MethodId),CName,N]),
+ w("case ~s: { // ~s::~s~n", [wx_gen_erl:get_unique_name(MethodId),CName,N]),
Ps1 = declare_variables(void, Ps0),
{Ps2,Align} = decode_arguments(Ps1),
Opts = [Opt || Opt = #param{def=Def,in=In,where=Where} <- Ps2,
@@ -276,7 +276,7 @@ gen_method(CName, M=#method{name=N,params=Ps0,type=T,method_type=MT,id=MethodId
end,
free_args(),
build_return_vals(T,Ps3),
- w(" break; ~n}~n", []),
+ w(" break;~n}~n", []),
erase(current_func),
M.
@@ -309,6 +309,8 @@ declare_type(N,false,_,#type{name="wxArrayTreeItemIds",ref=reference}) ->
w(" wxArrayTreeItemIds ~s;~n", [N]);
declare_type(N,false,_,#type{name="wxDateTime"}) ->
w(" wxDateTime ~s;~n", [N]);
+declare_type(N,false,_,#type{name=Type, base=int64, ref=reference}) ->
+ w(" ~s ~s;~n", [Type,N]);
declare_type(N,true,Def,#type{base=Base,single=true,name=Type,by_val=true})
when Base =:= int; Base =:= long; Base =:= float; Base =:= double; Base =:= bool ->
w(" ~s ~s=~s;~n", [Type,N,Def]);
@@ -351,9 +353,9 @@ declare_type(N,In,Def,T) ->
decode_options([], _Align) -> ok;
decode_options(Opts, Align) ->
align(Align, 64),
- w(" while( * (int*) bp) { switch (* (int*) bp) { ~n", []),
+ w(" while( * (int*) bp) { switch (* (int*) bp) {~n", []),
foldl(fun decode_opt/2, 1, Opts),
- w(" }}; ~n", []).
+ w(" }};~n", []).
decode_opt(#param{name=Name,type=Type}, N) ->
w(" case ~p: {bp += 4;~n", [N]),
@@ -478,9 +480,13 @@ decode_arg(N,#type{base={comp,_,List},single=true,name=Type,ref=Ref},Arg,A0) ->
{double, _} -> 0
end;
-decode_arg(N,#type{name=Class,base={ref,"wxTreeItemId"},single=true},Arg,A0) ->
- A = align(A0,32),
- wa(" ~s ",[Class],"~s = wxTreeItemId(getPtr(bp,memenv)); bp += 4;~n",[N],Arg),
+decode_arg(N,#type{name=Class="wxTreeItemId",single=true},Arg,A0) ->
+ A = align(A0,64),
+ wa(" ~s ",[Class],"~s = wxTreeItemId((void *) *(wxUint64 *) bp); bp += 8;~n",[N],Arg),
+ A;
+decode_arg(N,#type{name=Class="wxTreeItemIdValue",single=true},Arg,A0) ->
+ A = align(A0,64),
+ wa(" ~s ",[Class],"~s = (~s) * (wxUint64 *) bp; bp += 8;~n",[N,Class],Arg),
A;
decode_arg(N,#type{name="wxChar", single=S},Arg,A0)
when S =/= true ->
@@ -542,10 +548,10 @@ decode_arg(N,#type{name=Type,base=binary,mod=Mod0},Arg,A0) ->
Mod = mods([M || M <- Mod0]),
case Arg of
arg ->
- w(" ~s~s * ~s = (~s~s*) Ecmd.bin[~p]->base; ~n",
+ w(" ~s~s * ~s = (~s~s*) Ecmd.bin[~p]->base;~n",
[Mod,Type,N,Mod,Type, next_id(bin_count)]);
opt ->
- w(" ~s = (~s~s*) Ecmd.bin[~p]->base; ~n",
+ w(" ~s = (~s~s*) Ecmd.bin[~p]->base;~n",
[N,Mod,Type,next_id(bin_count)])
end,
A0;
@@ -555,10 +561,10 @@ decode_arg(N,#type{base={term,"wxTreeItemData"},mod=Mod0},Arg,A0) ->
BinCnt = next_id(bin_count),
case Arg of
arg ->
- w(" ~s~s * ~s = new ~s(Ecmd.bin[~p]->size, Ecmd.bin[~p]->base); ~n",
+ w(" ~s~s * ~s = new ~s(Ecmd.bin[~p]->size, Ecmd.bin[~p]->base);~n",
[Mod,Type,N,Type,BinCnt,BinCnt]);
opt ->
- w(" ~s = new ~s(Ecmd.bin[~p]->size, Ecmd.bin[~p]->base); ~n",
+ w(" ~s = new ~s(Ecmd.bin[~p]->size, Ecmd.bin[~p]->base);~n",
[N,Type,BinCnt,BinCnt])
end,
A0;
@@ -567,10 +573,10 @@ decode_arg(N,#type{name=Type,base={term,_},mod=Mod0},Arg,A0) ->
BinCnt = next_id(bin_count),
case Arg of
arg ->
- w(" ~s~s * ~s = new ~s(Ecmd.bin[~p]); ~n",
+ w(" ~s~s * ~s = new ~s(Ecmd.bin[~p]);~n",
[Mod,Type,N,Type,BinCnt]);
opt ->
- w(" ~s = new ~s(Ecmd.bin[~p]); ~n",
+ w(" ~s = new ~s(Ecmd.bin[~p]);~n",
[N,Type,BinCnt])
end,
A0;
@@ -786,7 +792,7 @@ virtual_dest(#class{methods=Ms, parent=Parent}) ->
"root" ->
false;
_ ->
- io:format("Error: ~p ~n",[Parent]),
+ io:format("Error: ~p~n",[Parent]),
erlang:error(no_parent)
end;
PClass ->
@@ -851,8 +857,10 @@ build_ret_types(Type,Ps) ->
build_ret(Name,_,#type{base={class,Class},single=true}) ->
w(" rt.addRef(getRef((void *)~s,memenv), \"~s\");~n",[Name,Class]);
-build_ret(Name,_,#type{base={ref,"wxTreeItemId"=Class},single=true}) ->
- w(" rt.addRef(getRef((void *)~s.m_pItem,memenv), \"~s\");~n",[Name,Class]);
+build_ret(Name,_,#type{name="wxTreeItemId",single=true}) ->
+ w(" rt.add((wxUIntPtr *) ~s.m_pItem);~n",[Name]);
+build_ret(Name,_,#type{name="wxTreeItemIdValue",single=true}) ->
+ w(" rt.add((wxUIntPtr *) ~s);~n",[Name]);
build_ret(Name,_,#type{base={term,_},single=true}) ->
w(" rt.addExt2Term(~s);~n", [Name]);
build_ret(Name,_,#type{base={binary,Size},single=true}) ->
@@ -897,7 +905,7 @@ build_ret(Name,_,#type{name=List,single=list,base={class,Class}}) ->
build_ret(Name,_,#type{name="wxArrayTreeItemIds"}) ->
w(" for(unsigned int i=0; i < ~s.GetCount(); i++) {~n", [Name]),
- w(" rt.addRef(getRef((void *)~s[i].m_pItem,memenv), \"wxTreeItemId\");}~n",[Name]),
+ w(" rt.add((wxUIntPtr *)~s[i].m_pItem);}~n",[Name]),
w(" rt.endList(~s.GetCount());~n",[Name]);
build_ret(Name,_,#type{base=float,single=true}) ->
@@ -1009,7 +1017,7 @@ gen_macros() ->
build_events() ->
open_write("../c_src/gen/wxe_events.cpp"),
c_copyright(),
- w("~n/***** This file is generated do not edit ****/ ~n~n"),
+ w("~n/***** This file is generated do not edit ****/~n~n"),
w("#include <wx/wx.h>~n"),
w("#include \"../wxe_impl.h\"~n~n"),
w("#include \"wxe_macros.h\"~n"),
@@ -1019,7 +1027,7 @@ build_events() ->
w("wxeEtype::wxeEtype(const char *name, int Id) {eName = name;cID = Id;}~n~n"),
w("WX_DECLARE_HASH_MAP(int, wxeEtype*, wxIntegerHash, wxIntegerEqual, wxeETmap );~n~n"),
- w("wxeETmap etmap; ~n~n"),
+ w("wxeETmap etmap;~n~n"),
w(
"int wxeEventTypeFromAtom(char *etype_atom) {
@@ -1046,16 +1054,16 @@ build_events() ->
close().
initEventTable(Evs) ->
- w("void initEventTable() ~n{~n"),
+ w("void initEventTable()~n{~n"),
w(" struct { ",[]),
- w("int ev_type; int class_id; const char * ev_name;} event_types[] = ~n {~n",[]),
+ w("int ev_type; int class_id; const char * ev_name;} event_types[] =~n {~n",[]),
lists:foreach(fun(Ev) -> init_event_classes(Ev) end,
[#class{id=0,event=[wxEVT_NULL]}|Evs]),
w(" {-1, 0, ""}~n };~n",[]),
w(" for(int i=0; event_types[i].ev_type != -1; i++) {~n",[]),
w(" if(NULL == etmap[event_types[i].ev_type]) {~n",[]),
- w(" etmap[event_types[i].ev_type] = ~n"
+ w(" etmap[event_types[i].ev_type] =~n"
" new wxeEtype(event_types[i].ev_name, event_types[i].class_id);~n"),
w(" } else {~n",[]),
w(" wxeEtype *prev = etmap[event_types[i].ev_type];~n"
@@ -1074,10 +1082,10 @@ init_event_classes(#class{event=ETs, id=Id}) ->
w(" {~w + wxEVT_USER_FIRST, ~w, ~p},~n",
[Cev, find_id(OtherClass), wx_gen_erl:event_type_name(Eev)]);
({Ev, {test_if, Test}}) ->
- w("#if ~s ~n", [Test]),
+ w("#if ~s~n", [Test]),
w(" {~w, ~w, ~p},~n",
[Ev, Id, wx_gen_erl:event_type_name(Ev)]),
- w("#endif ~n", []);
+ w("#endif~n", []);
(Ev) ->
w(" {~w, ~w, ~p},~n",
[Ev, Id, wx_gen_erl:event_type_name(Ev)])
@@ -1091,20 +1099,20 @@ find_id(OtherClass) ->
encode_events(Evs) ->
?WTC("encode_events"),
- w("void wxeEvtListener::forward(wxEvent& event) ~n"
- "{ ~n"
+ w("void wxeEvtListener::forward(wxEvent& event)~n"
+ "{~n"
"#ifdef DEBUG~n"
- " if(!sendevent(&event, port)) ~n"
+ " if(!sendevent(&event, port))~n"
" fprintf(stderr, \"Couldn't send event!\\r\\n\");~n"
"#else~n"
"sendevent(&event, port);~n"
"#endif~n"
"}~n~n"),
- w("int getRef(void* ptr, wxeMemEnv* memenv) ~n"
- "{ ~n"
+ w("int getRef(void* ptr, wxeMemEnv* memenv)~n"
+ "{~n"
" WxeApp * app = (WxeApp *) wxTheApp;~n"
" return app->getRef(ptr,memenv);~n"
- "} ~n~n"),
+ "}~n~n"),
w("bool sendevent(wxEvent *event, ErlDrvPort port)~n{~n"
" int send_res ;~n"
" char * evClass = NULL;~n"
diff --git a/lib/wx/api_gen/wx_gen_erl.erl b/lib/wx/api_gen/wx_gen_erl.erl
index 64c11baec1..d75442d307 100644
--- a/lib/wx/api_gen/wx_gen_erl.erl
+++ b/lib/wx/api_gen/wx_gen_erl.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%
%%
%%%-------------------------------------------------------------------
@@ -119,7 +119,7 @@ gen_class1(C=#class{name=Name,parent=Parent,methods=Ms,options=Opts}) ->
case [P || P <- Parents, P =/= root, P =/= object] of
[] -> ignore;
Ps ->
- w("%% <p>This class is derived (and can use functions) from: ~n", []),
+ w("%% <p>This class is derived (and can use functions) from:~n", []),
[w("%% <br />{@link ~s}~n", [P]) || P <- Ps],
w("%% </p>~n",[])
end,
@@ -302,7 +302,7 @@ gen_dest(#class{name=CName,abstract=Abs}, Ms) ->
gen_dest2(Class, Id) ->
w("%% @spec (This::~s()) -> ok~n", [Class]),
w("%% @doc Destroys this object, do not use object again~n", []),
- w("destroy(Obj=#wx_ref{type=Type}) -> ~n", []),
+ w("destroy(Obj=#wx_ref{type=Type}) ->~n", []),
w(" ?CLASS(Type,~s),~n",[Class]),
case Id of
object ->
@@ -317,7 +317,7 @@ gen_inherited([object], Done, Exported) -> {Done, Exported};
gen_inherited([Parent|Ps], Done0, Exported0) ->
#class{name=Class, methods=Ms} = get({class,Parent}),
case is_list(Exported0) of
- false -> w(" %% From ~s ~n", [Class]);
+ false -> w(" %% From ~s~n", [Class]);
true -> ignore
end,
{Done,Exported} = gen_inherited_ms(Ms, Class, Done0, gb_sets:empty(), Exported0),
@@ -575,6 +575,8 @@ guard_test(#param{name=Name,type=#type{single=Single}})
"is_list(" ++ erl_arg_name(Name) ++ ")";
guard_test(#param{name=N,type=#type{base=int}}) ->
"is_integer(" ++ erl_arg_name(N) ++ ")";
+guard_test(#param{name=N,type=#type{base=int64}}) ->
+ "is_integer(" ++ erl_arg_name(N) ++ ")";
guard_test(#param{name=N,type=#type{base=long}}) ->
"is_integer(" ++ erl_arg_name(N) ++ ")";
guard_test(#param{name=N,type=#type{base=float}}) ->
@@ -603,6 +605,7 @@ guard_test(#param{name=N,type=#type{base={comp,"wxColour",_Tup}}}) ->
"tuple_size(" ++ erl_arg_name(N) ++ ") =:= 3; tuple_size(" ++ erl_arg_name(N) ++ ") =:= 4";
guard_test(#param{name=N,type=#type{base={comp,_,Tup}}}) ->
Doc = fun({int,V}) -> "is_integer("++erl_arg_name(N)++V ++")";
+ ({int64,V}) -> "is_integer("++erl_arg_name(N)++V ++")";
({double,V}) -> "is_number("++erl_arg_name(N)++V ++")"
end,
args(Doc, ",", Tup);
@@ -670,7 +673,7 @@ gen_doc(Class, Cs = [#method{name=N, alias=A,method_type=MT}|_]) ->
[lowercase_all(Class),lowercase_all(Class),lowercase_all(N)])
end,
Name = case MT of constructor -> "new"; _ -> erl_func_name(N,A) end,
- w("%% <br /> Alternatives: ~n",[]),
+ w("%% <br /> Alternatives:~n",[]),
[gen_doc2(Name, Clause) || Clause <- Cs],
ok.
@@ -768,7 +771,9 @@ doc_arg_type3(#type{name="wxArrayString"}) -> "[string()]";
doc_arg_type3(#type{name="wxDateTime"}) -> "wx:datetime()";
doc_arg_type3(#type{name="wxArtClient"}) -> "string()";
doc_arg_type3(#type{base=int}) -> "integer()";
+doc_arg_type3(#type{base=int64}) -> "integer()";
doc_arg_type3(#type{base=long}) -> "integer()";
+doc_arg_type3(#type{name="wxTreeItemId"}) -> "wxTreeCtrl:treeItemId()";
doc_arg_type3(#type{base=bool}) -> "bool()";
doc_arg_type3(#type{base=float}) -> "float()";
doc_arg_type3(#type{base=double}) -> "float()";
@@ -851,7 +856,7 @@ doc_enum_desc([{Enum,Vs}|R]) ->
doc_enum_desc(R).
%% Misc functions prefixed with wx
-erl_func_name("wx" ++ Name, undefined) -> check_name(lowercase(Name));
+erl_func_name("wx" ++ Name, undefined) -> check_name(lowercase(Name));
erl_func_name(Name, undefined) -> check_name(lowercase(Name));
erl_func_name(_, Alias) -> check_name(lowercase(Alias)).
@@ -926,6 +931,8 @@ marshal_arg(#type{single=true,base=float}, Name, Align) ->
align(32, Align, Name ++ ":32/?F");
marshal_arg(#type{single=true,base=double}, Name, Align) ->
align(64, Align, Name ++ ":64/?F");
+marshal_arg(#type{single=true,base=int64}, Name, Align) ->
+ align(64, Align, Name ++ ":64/?UI");
marshal_arg(#type{single=true,base=int}, Name, Align) ->
align(32, Align, Name ++ ":32/?UI");
marshal_arg(#type{single=true,base={enum,_Enum}}, Name, Align) ->
@@ -1019,22 +1026,22 @@ enum_name(Name) ->
gen_enums_ints() ->
%% open_write("../include/wx.hrl"), opened in gen_event_recs
- w("~n%% Hardcoded Records ~n", []),
- w("-record(wxMouseState, {x, y, %% integer() ~n"
- " leftDown, middleDown, rightDown, %% bool() ~n"
+ w("~n%% Hardcoded Records~n", []),
+ w("-record(wxMouseState, {x, y, %% integer()~n"
+ " leftDown, middleDown, rightDown, %% bool()~n"
" controlDown, shiftDown, altDown, metaDown, cmdDown %% bool()~n"
" }).~n", []),
- w("-record(wxHtmlLinkInfo, { ~n"
- " href, target %% string() ~n"
+ w("-record(wxHtmlLinkInfo, {~n"
+ " href, target %% string()~n"
" }).~n", []),
- w("~n%% Hardcoded Defines ~n", []),
+ w("~n%% Hardcoded Defines~n", []),
Enums = [E || E = {{enum,_},#enum{as_atom=false}} <- get()],
w("-define(wxDefaultSize, {-1,-1}).~n", []),
w("-define(wxDefaultPosition, {-1,-1}).~n", []),
- w("~n%% Global Variables ~n", []),
+ w("~n%% Global Variables~n", []),
[w("-define(~s, wxe_util:get_const(~s)).~n", [Gvar, Gvar]) ||
{Gvar,_,_Id} <- get(gvars)],
- w("~n%% Enum and defines ~n", []),
+ w("~n%% Enum and defines~n", []),
foldl(fun({{enum,Type},Enum= #enum{as_atom=false}}, Done) ->
build_enum_ints(Type,Enum,Done);
(_,Done) -> Done
@@ -1044,9 +1051,9 @@ gen_enums_ints() ->
build_enum_ints(Type,#enum{vals=Vals},Done) ->
case Type of
[$@|_] -> ok; % anonymous
- {Class,[$@|_]} when Vals =/= [] -> w("% From class ~s ~n", [Class]);
- {Class,Enum} when Vals =/= [] -> w("% From ~s::~s ~n", [Class,Enum]);
- _ when Vals =/= [] -> w("% Type ~s ~n", [Type]);
+ {Class,[$@|_]} when Vals =/= [] -> w("% From class ~s~n", [Class]);
+ {Class,Enum} when Vals =/= [] -> w("% From ~s::~s~n", [Class,Enum]);
+ _ when Vals =/= [] -> w("% Type ~s~n", [Type]);
_ -> ok
end,
@@ -1089,7 +1096,7 @@ gen_event_recs() ->
erl_copyright(),
w("", []),
w("%% This file is generated DO NOT EDIT~n~n", []),
- w("%% All event messages are encapsulated in a wx record ~n"
+ w("%% All event messages are encapsulated in a wx record~n"
"%% they contain the widget id and a specialized event record.~n"
"%% Each event record may be sent for one or more event types.~n"
"%% The mapping to wxWidgets is one record per class.~n~n",[]),
@@ -1097,7 +1104,7 @@ gen_event_recs() ->
w("-record(wx, {id, %% Integer Identity of object.~n"
" obj, %% Object reference that was used in the connect call.~n"
" userData, %% User data specified in the connect call.~n"
- " event}).%% The event record ~n~n",[]),
+ " event}).%% The event record~n~n",[]),
w("%% Here comes the definitions of all event records.~n"
"%% they contain the event type and possible some extra information.~n~n",[]),
Types = [build_event_rec(C) || {_,C=#class{event=Evs}} <- get(), Evs =/= false],
@@ -1150,7 +1157,7 @@ build_event_rec(Class=#class{name=Name, event=Evs}) ->
%% false -> w("%% This event will be handled by other handlers~n",[])
%% end,
w("%% Callback event: {@link ~s}~n", [Name]),
- w("-record(~s, {type}). ~n~n", [Rec]);
+ w("-record(~s, {type}).~n~n", [Rec]);
false ->
w("%% @type ~s() = #~s{type=wxEventType(),~s}.~n",
[Rec,Rec,args(GetType,",",Attr)]),
@@ -1160,7 +1167,7 @@ build_event_rec(Class=#class{name=Name, event=Evs}) ->
%% false -> w("%% This event will be handled by other handlers~n",[])
%% end,
w("%% Callback event: {@link ~s}~n", [Name]),
- w("-record(~s,{type, ~s}). ~n~n", [Rec,args(GetName,",",Attr)])
+ w("-record(~s,{type, ~s}).~n~n", [Rec,args(GetName,",",Attr)])
end,
EvTypes.
@@ -1190,7 +1197,7 @@ gen_funcnames() ->
open_write("../src/gen/wxe_debug.hrl"),
erl_copyright(),
w("%% This file is generated DO NOT EDIT~n~n", []),
- w("wxdebug_table() -> ~n[~n", []),
+ w("wxdebug_table() ->~n[~n", []),
w(" {0, {wx, internal_batch_start, 0}},~n", []),
w(" {1, {wx, internal_batch_end, 0}},~n", []),
w(" {4, {wxObject, internal_destroy, 1}},~n", []),
diff --git a/lib/wx/api_gen/wxapi.conf b/lib/wx/api_gen/wxapi.conf
index df154f0125..4f7bbfedef 100644
--- a/lib/wx/api_gen/wxapi.conf
+++ b/lib/wx/api_gen/wxapi.conf
@@ -1,20 +1,20 @@
%% -*- erlang -*-
%%
%% %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%
%
%% Api defs file, defines the classes and members we want.
@@ -757,7 +757,7 @@
{'EditLabel',[{"textControlClass",nowhere}]},
'EnsureVisible',
{'FindItem',3},'GetColumn','GetColumnCount','GetColumnWidth','GetCountPerPage',
- %%'GetEditControl',
+ 'GetEditControl',
'GetImageList','GetItem','GetItemBackgroundColour',
'GetItemCount',{'GetItemData', [{return, {base,int}}]},
'GetItemFont','GetItemPosition','GetItemRect',
@@ -889,7 +889,12 @@
{enum, wxTreeItemIcon, "wxTreeItemIcon_"}.
-{class, wxTreeCtrl, wxControl, [],
+{class, wxTreeCtrl, wxControl,
+ [{doc,
+ "Note: The representation of treeItemId() have changed "
+ "from the original class implementation to be an semi-opaque type,"
+ "Equality between TreeItemId's can be tested and zero means that the TreeItem is invalid."
+ }],
['wxTreeCtrl','~wxTreeCtrl','AddRoot','AppendItem',
%% Not on Windows 'AssignButtonsImageList','GetButtonsImageList','SetButtonsImageList'
'AssignImageList','AssignStateImageList','Collapse','CollapseAndReset',
@@ -897,10 +902,10 @@
%'EndEditLabel',
'EnsureVisible','Expand','GetBoundingRect',
'GetChildrenCount','GetCount','GetEditControl',
- %'GetFirstChild',
+ {'GetFirstChild',[{"cookie", out}]}, {'GetNextChild',[{"cookie", [both]}]},
'GetFirstVisibleItem',{'GetImageList',0},'GetIndent',
'GetItemBackgroundColour','GetItemData','GetItemFont','GetItemImage',
- 'GetItemText','GetItemTextColour','GetLastChild', % 'GetNextChild',
+ 'GetItemText','GetItemTextColour','GetLastChild',
'GetNextSibling','GetNextVisible','GetItemParent',%'GetParent',
'GetPrevSibling','GetPrevVisible','GetRootItem',
'GetSelection',{'GetSelections', [{return, nowhere},{"val",out}]},
@@ -985,7 +990,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/Makefile.in b/lib/wx/c_src/Makefile.in
index 2f04b1dbf6..5a0b4ce8ef 100644
--- a/lib/wx/c_src/Makefile.in
+++ b/lib/wx/c_src/Makefile.in
@@ -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%
#
@@ -47,14 +47,11 @@ ERL_DIR = @ERLANG_ROOT_DIR@
ERL_INCS = -I$(ERL_DIR)/usr/include
else
-ERLANG_OSTYPE = @WXERL_SYS_TYPE@
-
-ERL_INCS= -I$(ERL_TOP)/erts/emulator/beam \
- -I$(ERL_TOP)/erts/emulator/sys/$(ERLANG_OSTYPE) \
- -I$(ERL_TOP)/erts/include/internal \
- -I$(ERL_TOP)/erts/include/internal/$(ERLANG_OSTYPE) \
- -I$(ERL_TOP)/erts/include \
- -I$(ERL_TOP)/erts/include/$(ERLANG_OSTYPE)
+
+include $(ERL_TOP)/make/target.mk
+include $(ERL_TOP)/make/$(TARGET)/otp_ded.mk
+
+ERL_INCS= $(DED_INCLUDES)
endif
diff --git a/lib/wx/c_src/gen/gl_fdefs.h b/lib/wx/c_src/gen/gl_fdefs.h
index 5fcd2d8e9b..f8851ddb83 100644
--- a/lib/wx/c_src/gen/gl_fdefs.h
+++ b/lib/wx/c_src/gen/gl_fdefs.h
@@ -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%
*/
/***** This file is generated do not edit ****/
diff --git a/lib/wx/c_src/gen/gl_finit.h b/lib/wx/c_src/gen/gl_finit.h
index dac74ca7b6..a22192d06a 100644
--- a/lib/wx/c_src/gen/gl_finit.h
+++ b/lib/wx/c_src/gen/gl_finit.h
@@ -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%
*/
/***** This file is generated do not edit ****/
diff --git a/lib/wx/c_src/gen/gl_funcs.cpp b/lib/wx/c_src/gen/gl_funcs.cpp
index 784731f02c..41a5524891 100644
--- a/lib/wx/c_src/gen/gl_funcs.cpp
+++ b/lib/wx/c_src/gen/gl_funcs.cpp
@@ -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%
*/
/***** This file is generated do not edit ****/
diff --git a/lib/wx/c_src/gen/glu_finit.h b/lib/wx/c_src/gen/glu_finit.h
index 7135c53243..2f0e2d15e4 100644
--- a/lib/wx/c_src/gen/glu_finit.h
+++ b/lib/wx/c_src/gen/glu_finit.h
@@ -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%
*/
/***** This file is generated do not edit ****/
diff --git a/lib/wx/c_src/gen/wxe_derived_dest.h b/lib/wx/c_src/gen/wxe_derived_dest.h
index ec56df7d4e..57b0faa2cb 100644
--- a/lib/wx/c_src/gen/wxe_derived_dest.h
+++ b/lib/wx/c_src/gen/wxe_derived_dest.h
@@ -1,235 +1,235 @@
/*
* %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%
*/
-/***** This file is generated do not edit ****/
+/***** This file is generated do not edit ****/
-class EwxWindow : public wxWindow {
- public: ~EwxWindow() {((WxeApp *)wxTheApp)->clearPtr(this);};
+class EwxWindow : public wxWindow {
+ public: ~EwxWindow() {((WxeApp *)wxTheApp)->clearPtr(this);};
EwxWindow(wxWindow * parent,wxWindowID id,const wxPoint& pos,const wxSize& size,long style) : wxWindow(parent,id,pos,size,style) {};
EwxWindow() : wxWindow() {};
-};
+};
-class EwxFrame : public wxFrame {
- public: ~EwxFrame() {((WxeApp *)wxTheApp)->clearPtr(this);};
+class EwxFrame : public wxFrame {
+ public: ~EwxFrame() {((WxeApp *)wxTheApp)->clearPtr(this);};
EwxFrame(wxWindow * parent,wxWindowID id,const wxString& title,const wxPoint& pos,const wxSize& size,long style) : wxFrame(parent,id,title,pos,size,style) {};
EwxFrame() : wxFrame() {};
-};
+};
-class EwxMiniFrame : public wxMiniFrame {
- public: ~EwxMiniFrame() {((WxeApp *)wxTheApp)->clearPtr(this);};
+class EwxMiniFrame : public wxMiniFrame {
+ public: ~EwxMiniFrame() {((WxeApp *)wxTheApp)->clearPtr(this);};
EwxMiniFrame(wxWindow * parent,wxWindowID id,const wxString& title,const wxPoint& pos,const wxSize& size,long style) : wxMiniFrame(parent,id,title,pos,size,style) {};
EwxMiniFrame() : wxMiniFrame() {};
-};
+};
-class EwxSplashScreen : public wxSplashScreen {
- public: ~EwxSplashScreen() {((WxeApp *)wxTheApp)->clearPtr(this);};
+class EwxSplashScreen : public wxSplashScreen {
+ public: ~EwxSplashScreen() {((WxeApp *)wxTheApp)->clearPtr(this);};
EwxSplashScreen(const wxBitmap& bitmap,long splashStyle,int milliseconds,wxWindow * parent,wxWindowID id,const wxPoint& pos,const wxSize& size,long style) : wxSplashScreen(bitmap,splashStyle,milliseconds,parent,id,pos,size,style) {};
EwxSplashScreen() : wxSplashScreen() {};
-};
+};
-class EwxPanel : public wxPanel {
- public: ~EwxPanel() {((WxeApp *)wxTheApp)->clearPtr(this);};
+class EwxPanel : public wxPanel {
+ public: ~EwxPanel() {((WxeApp *)wxTheApp)->clearPtr(this);};
EwxPanel(wxWindow * parent,int x,int y,int width,int height,long style) : wxPanel(parent,x,y,width,height,style) {};
EwxPanel(wxWindow * parent,wxWindowID winid,const wxPoint& pos,const wxSize& size,long style) : wxPanel(parent,winid,pos,size,style) {};
EwxPanel() : wxPanel() {};
-};
+};
-class EwxScrolledWindow : public wxScrolledWindow {
- public: ~EwxScrolledWindow() {((WxeApp *)wxTheApp)->clearPtr(this);};
+class EwxScrolledWindow : public wxScrolledWindow {
+ public: ~EwxScrolledWindow() {((WxeApp *)wxTheApp)->clearPtr(this);};
EwxScrolledWindow(wxWindow * parent,wxWindowID winid,const wxPoint& pos,const wxSize& size,long style) : wxScrolledWindow(parent,winid,pos,size,style) {};
EwxScrolledWindow() : wxScrolledWindow() {};
-};
+};
-class EwxSashWindow : public wxSashWindow {
- public: ~EwxSashWindow() {((WxeApp *)wxTheApp)->clearPtr(this);};
+class EwxSashWindow : public wxSashWindow {
+ public: ~EwxSashWindow() {((WxeApp *)wxTheApp)->clearPtr(this);};
EwxSashWindow(wxWindow * parent,wxWindowID id,const wxPoint& pos,const wxSize& size,long style) : wxSashWindow(parent,id,pos,size,style) {};
EwxSashWindow() : wxSashWindow() {};
-};
+};
-class EwxSashLayoutWindow : public wxSashLayoutWindow {
- public: ~EwxSashLayoutWindow() {((WxeApp *)wxTheApp)->clearPtr(this);};
+class EwxSashLayoutWindow : public wxSashLayoutWindow {
+ public: ~EwxSashLayoutWindow() {((WxeApp *)wxTheApp)->clearPtr(this);};
EwxSashLayoutWindow(wxWindow * parent,wxWindowID id,const wxPoint& pos,const wxSize& size,long style) : wxSashLayoutWindow(parent,id,pos,size,style) {};
EwxSashLayoutWindow() : wxSashLayoutWindow() {};
-};
+};
-class EwxGrid : public wxGrid {
- public: ~EwxGrid() {((WxeApp *)wxTheApp)->clearPtr(this);};
+class EwxGrid : public wxGrid {
+ public: ~EwxGrid() {((WxeApp *)wxTheApp)->clearPtr(this);};
EwxGrid(wxWindow * parent,int x,int y,int w,int h,long style) : wxGrid(parent,x,y,w,h,style) {};
EwxGrid(wxWindow * parent,wxWindowID id,const wxPoint& pos,const wxSize& size,long style) : wxGrid(parent,id,pos,size,style) {};
EwxGrid() : wxGrid() {};
-};
+};
-class EwxMirrorDC : public wxMirrorDC {
- public: ~EwxMirrorDC() {((WxeApp *)wxTheApp)->clearPtr(this);};
+class EwxMirrorDC : public wxMirrorDC {
+ public: ~EwxMirrorDC() {((WxeApp *)wxTheApp)->clearPtr(this);};
EwxMirrorDC(wxDC& dc,bool mirror) : wxMirrorDC(dc,mirror) {};
-};
+};
-class EwxScreenDC : public wxScreenDC {
- public: ~EwxScreenDC() {((WxeApp *)wxTheApp)->clearPtr(this);};
+class EwxScreenDC : public wxScreenDC {
+ public: ~EwxScreenDC() {((WxeApp *)wxTheApp)->clearPtr(this);};
EwxScreenDC() : wxScreenDC() {};
-};
+};
-class EwxPostScriptDC : public wxPostScriptDC {
- public: ~EwxPostScriptDC() {((WxeApp *)wxTheApp)->clearPtr(this);};
+class EwxPostScriptDC : public wxPostScriptDC {
+ public: ~EwxPostScriptDC() {((WxeApp *)wxTheApp)->clearPtr(this);};
EwxPostScriptDC(const wxPrintData& printData) : wxPostScriptDC(printData) {};
EwxPostScriptDC() : wxPostScriptDC() {};
-};
+};
-class EwxWindowDC : public wxWindowDC {
- public: ~EwxWindowDC() {((WxeApp *)wxTheApp)->clearPtr(this);};
+class EwxWindowDC : public wxWindowDC {
+ public: ~EwxWindowDC() {((WxeApp *)wxTheApp)->clearPtr(this);};
EwxWindowDC(wxWindow * win) : wxWindowDC(win) {};
EwxWindowDC() : wxWindowDC() {};
-};
+};
-class EwxClientDC : public wxClientDC {
- public: ~EwxClientDC() {((WxeApp *)wxTheApp)->clearPtr(this);};
+class EwxClientDC : public wxClientDC {
+ public: ~EwxClientDC() {((WxeApp *)wxTheApp)->clearPtr(this);};
EwxClientDC(wxWindow * win) : wxClientDC(win) {};
EwxClientDC() : wxClientDC() {};
-};
+};
-class EwxPaintDC : public wxPaintDC {
- public: ~EwxPaintDC() {((WxeApp *)wxTheApp)->clearPtr(this);};
+class EwxPaintDC : public wxPaintDC {
+ public: ~EwxPaintDC() {((WxeApp *)wxTheApp)->clearPtr(this);};
EwxPaintDC(wxWindow * win) : wxPaintDC(win) {};
EwxPaintDC() : wxPaintDC() {};
-};
+};
-class EwxMemoryDC : public wxMemoryDC {
- public: ~EwxMemoryDC() {((WxeApp *)wxTheApp)->clearPtr(this);};
+class EwxMemoryDC : public wxMemoryDC {
+ public: ~EwxMemoryDC() {((WxeApp *)wxTheApp)->clearPtr(this);};
EwxMemoryDC(wxDC * dc) : wxMemoryDC(dc) {};
EwxMemoryDC(wxBitmap& dc) : wxMemoryDC(dc) {};
EwxMemoryDC() : wxMemoryDC() {};
-};
+};
-class EwxBufferedDC : public wxBufferedDC {
- public: ~EwxBufferedDC() {((WxeApp *)wxTheApp)->clearPtr(this);};
+class EwxBufferedDC : public wxBufferedDC {
+ public: ~EwxBufferedDC() {((WxeApp *)wxTheApp)->clearPtr(this);};
EwxBufferedDC(wxDC * dc,const wxSize& area,int style) : wxBufferedDC(dc,area,style) {};
EwxBufferedDC(wxDC * dc,wxBitmap& buffer,int style) : wxBufferedDC(dc,buffer,style) {};
EwxBufferedDC() : wxBufferedDC() {};
-};
+};
-class EwxBufferedPaintDC : public wxBufferedPaintDC {
- public: ~EwxBufferedPaintDC() {((WxeApp *)wxTheApp)->clearPtr(this);};
+class EwxBufferedPaintDC : public wxBufferedPaintDC {
+ public: ~EwxBufferedPaintDC() {((WxeApp *)wxTheApp)->clearPtr(this);};
EwxBufferedPaintDC(wxWindow * window,wxBitmap& buffer,int style) : wxBufferedPaintDC(window,buffer,style) {};
EwxBufferedPaintDC(wxWindow * window,int style) : wxBufferedPaintDC(window,style) {};
-};
+};
-class EwxMenuBar : public wxMenuBar {
- public: ~EwxMenuBar() {((WxeApp *)wxTheApp)->clearPtr(this);};
+class EwxMenuBar : public wxMenuBar {
+ public: ~EwxMenuBar() {((WxeApp *)wxTheApp)->clearPtr(this);};
EwxMenuBar(long style) : wxMenuBar(style) {};
EwxMenuBar() : wxMenuBar() {};
-};
+};
-class EwxMenu : public wxMenu {
- public: ~EwxMenu() {((WxeApp *)wxTheApp)->clearPtr(this);};
+class EwxMenu : public wxMenu {
+ public: ~EwxMenu() {((WxeApp *)wxTheApp)->clearPtr(this);};
EwxMenu(const wxString& title,long style) : wxMenu(title,style) {};
EwxMenu(long style) : wxMenu(style) {};
-};
+};
-class EwxMenuItem : public wxMenuItem {
- public: ~EwxMenuItem() {((WxeApp *)wxTheApp)->clearPtr(this);};
+class EwxMenuItem : public wxMenuItem {
+ public: ~EwxMenuItem() {((WxeApp *)wxTheApp)->clearPtr(this);};
EwxMenuItem(wxMenu * parentMenu,int id,const wxString& text,const wxString& help,wxItemKind kind,wxMenu * subMenu) : wxMenuItem(parentMenu,id,text,help,kind,subMenu) {};
-};
+};
-class EwxStatusBar : public wxStatusBar {
- public: ~EwxStatusBar() {((WxeApp *)wxTheApp)->clearPtr(this);};
+class EwxStatusBar : public wxStatusBar {
+ public: ~EwxStatusBar() {((WxeApp *)wxTheApp)->clearPtr(this);};
EwxStatusBar(wxWindow * parent,wxWindowID winid,long style) : wxStatusBar(parent,winid,style) {};
EwxStatusBar() : wxStatusBar() {};
-};
+};
-class EwxBitmap : public wxBitmap {
- public: ~EwxBitmap() {((WxeApp *)wxTheApp)->clearPtr(this);};
+class EwxBitmap : public wxBitmap {
+ public: ~EwxBitmap() {((WxeApp *)wxTheApp)->clearPtr(this);};
EwxBitmap(const char * bits,int width,int height,int depth) : wxBitmap(bits,width,height,depth) {};
EwxBitmap(int width,int height,int depth) : wxBitmap(width,height,depth) {};
EwxBitmap(const wxString& filename,wxBitmapType type) : wxBitmap(filename,type) {};
EwxBitmap(const wxImage& image,int depth) : wxBitmap(image,depth) {};
EwxBitmap() : wxBitmap() {};
-};
+};
-class EwxIcon : public wxIcon {
- public: ~EwxIcon() {((WxeApp *)wxTheApp)->clearPtr(this);};
+class EwxIcon : public wxIcon {
+ public: ~EwxIcon() {((WxeApp *)wxTheApp)->clearPtr(this);};
EwxIcon(const wxString& filename,wxBitmapType type,int desiredWidth,int desiredHeight) : wxIcon(filename,type,desiredWidth,desiredHeight) {};
EwxIcon(const wxIconLocation& loc) : wxIcon(loc) {};
EwxIcon() : wxIcon() {};
-};
+};
-class EwxCursor : public wxCursor {
- public: ~EwxCursor() {((WxeApp *)wxTheApp)->clearPtr(this);};
+class EwxCursor : public wxCursor {
+ public: ~EwxCursor() {((WxeApp *)wxTheApp)->clearPtr(this);};
EwxCursor(const char * bits,int width,int height,int hotSpotX,int hotSpotY) : wxCursor(bits,width,height,hotSpotX,hotSpotY) {};
EwxCursor(int cursorId) : wxCursor(cursorId) {};
EwxCursor(const wxImage& image) : wxCursor(image) {};
EwxCursor() : wxCursor() {};
-};
+};
-class EwxMask : public wxMask {
- public: ~EwxMask() {((WxeApp *)wxTheApp)->clearPtr(this);};
+class EwxMask : public wxMask {
+ public: ~EwxMask() {((WxeApp *)wxTheApp)->clearPtr(this);};
EwxMask(const wxBitmap& bitmap,int paletteIndex) : wxMask(bitmap,paletteIndex) {};
EwxMask(const wxBitmap& bitmap,const wxColour& colour) : wxMask(bitmap,colour) {};
EwxMask(const wxBitmap& bitmap) : wxMask(bitmap) {};
EwxMask() : wxMask() {};
-};
+};
-class EwxImage : public wxImage {
- public: ~EwxImage() {((WxeApp *)wxTheApp)->clearPtr(this);};
+class EwxImage : public wxImage {
+ public: ~EwxImage() {((WxeApp *)wxTheApp)->clearPtr(this);};
EwxImage(int width,int height,unsigned char * data,unsigned char * alpha,bool static_data) : wxImage(width,height,data,alpha,static_data) {};
EwxImage(int width,int height,unsigned char * data,bool static_data) : wxImage(width,height,data,static_data) {};
EwxImage(int width,int height,bool clear) : wxImage(width,height,clear) {};
EwxImage(const wxString& name,const wxString& mimetype,int index) : wxImage(name,mimetype,index) {};
EwxImage(const wxString& name,long type,int index) : wxImage(name,type,index) {};
EwxImage() : wxImage() {};
-};
+};
-class EwxBrush : public wxBrush {
- public: ~EwxBrush() {((WxeApp *)wxTheApp)->clearPtr(this);};
+class EwxBrush : public wxBrush {
+ public: ~EwxBrush() {((WxeApp *)wxTheApp)->clearPtr(this);};
EwxBrush(const wxColour& colour,int style) : wxBrush(colour,style) {};
EwxBrush(const wxBitmap& stippleBitmap) : wxBrush(stippleBitmap) {};
EwxBrush() : wxBrush() {};
-};
+};
-class EwxPen : public wxPen {
- public: ~EwxPen() {((WxeApp *)wxTheApp)->clearPtr(this);};
+class EwxPen : public wxPen {
+ public: ~EwxPen() {((WxeApp *)wxTheApp)->clearPtr(this);};
EwxPen(const wxColour& colour,int width,int style) : wxPen(colour,width,style) {};
EwxPen() : wxPen() {};
-};
+};
-class EwxRegion : public wxRegion {
- public: ~EwxRegion() {((WxeApp *)wxTheApp)->clearPtr(this);};
+class EwxRegion : public wxRegion {
+ public: ~EwxRegion() {((WxeApp *)wxTheApp)->clearPtr(this);};
EwxRegion(wxCoord x,wxCoord y,wxCoord w,wxCoord h) : wxRegion(x,y,w,h) {};
EwxRegion(const wxPoint& topLeft,const wxPoint& bottomRight) : wxRegion(topLeft,bottomRight) {};
EwxRegion(const wxBitmap& bmp) : wxRegion(bmp) {};
EwxRegion(const wxRect& rect) : wxRegion(rect) {};
EwxRegion() : wxRegion() {};
-};
+};
-class EwxAcceleratorTable : public wxAcceleratorTable {
- public: ~EwxAcceleratorTable() {((WxeApp *)wxTheApp)->clearPtr(this);};
+class EwxAcceleratorTable : public wxAcceleratorTable {
+ public: ~EwxAcceleratorTable() {((WxeApp *)wxTheApp)->clearPtr(this);};
EwxAcceleratorTable(int n,const wxAcceleratorEntry * entries) : wxAcceleratorTable(n,entries) {};
EwxAcceleratorTable() : wxAcceleratorTable() {};
-};
+};
-class EwxCaret : public wxCaret {
- public: ~EwxCaret() {((WxeApp *)wxTheApp)->clearPtr(this);};
+class EwxCaret : public wxCaret {
+ public: ~EwxCaret() {((WxeApp *)wxTheApp)->clearPtr(this);};
EwxCaret(wxWindow * window,int width,int height) : wxCaret(window,width,height) {};
EwxCaret(wxWindow * window,const wxSize& size) : wxCaret(window,size) {};
-};
+};
-class EwxSizerItem : public wxSizerItem {
- public: ~EwxSizerItem() {((WxeApp *)wxTheApp)->clearPtr(this);};
+class EwxSizerItem : public wxSizerItem {
+ public: ~EwxSizerItem() {((WxeApp *)wxTheApp)->clearPtr(this);};
EwxSizerItem(int width,int height,int proportion,int flag,int border,wxObject * userData) : wxSizerItem(width,height,proportion,flag,border,userData) {};
EwxSizerItem(wxWindow * window,int proportion,int flag,int border,wxObject * userData) : wxSizerItem(window,proportion,flag,border,userData) {};
EwxSizerItem(wxSizer * window,int proportion,int flag,int border,wxObject * userData) : wxSizerItem(window,proportion,flag,border,userData) {};
@@ -237,483 +237,483 @@ class EwxSizerItem : public wxSizerItem {
EwxSizerItem(wxWindow * window,const wxSizerFlags& flags) : wxSizerItem(window,flags) {};
EwxSizerItem(wxSizer * window,const wxSizerFlags& flags) : wxSizerItem(window,flags) {};
EwxSizerItem() : wxSizerItem() {};
-};
+};
-class EwxBoxSizer : public wxBoxSizer {
- public: ~EwxBoxSizer() {((WxeApp *)wxTheApp)->clearPtr(this);};
+class EwxBoxSizer : public wxBoxSizer {
+ public: ~EwxBoxSizer() {((WxeApp *)wxTheApp)->clearPtr(this);};
EwxBoxSizer(int orient) : wxBoxSizer(orient) {};
-};
+};
-class EwxStaticBoxSizer : public wxStaticBoxSizer {
- public: ~EwxStaticBoxSizer() {((WxeApp *)wxTheApp)->clearPtr(this);};
+class EwxStaticBoxSizer : public wxStaticBoxSizer {
+ public: ~EwxStaticBoxSizer() {((WxeApp *)wxTheApp)->clearPtr(this);};
EwxStaticBoxSizer(int orient,wxWindow * win,const wxString& label) : wxStaticBoxSizer(orient,win,label) {};
EwxStaticBoxSizer(wxStaticBox * box,int orient) : wxStaticBoxSizer(box,orient) {};
-};
+};
-class EwxGridSizer : public wxGridSizer {
- public: ~EwxGridSizer() {((WxeApp *)wxTheApp)->clearPtr(this);};
+class EwxGridSizer : public wxGridSizer {
+ public: ~EwxGridSizer() {((WxeApp *)wxTheApp)->clearPtr(this);};
EwxGridSizer(int rows,int cols,int vgap,int hgap) : wxGridSizer(rows,cols,vgap,hgap) {};
EwxGridSizer(int cols,int vgap,int hgap) : wxGridSizer(cols,vgap,hgap) {};
-};
+};
-class EwxFlexGridSizer : public wxFlexGridSizer {
- public: ~EwxFlexGridSizer() {((WxeApp *)wxTheApp)->clearPtr(this);};
+class EwxFlexGridSizer : public wxFlexGridSizer {
+ public: ~EwxFlexGridSizer() {((WxeApp *)wxTheApp)->clearPtr(this);};
EwxFlexGridSizer(int rows,int cols,int vgap,int hgap) : wxFlexGridSizer(rows,cols,vgap,hgap) {};
EwxFlexGridSizer(int cols,int vgap,int hgap) : wxFlexGridSizer(cols,vgap,hgap) {};
-};
+};
-class EwxGridBagSizer : public wxGridBagSizer {
- public: ~EwxGridBagSizer() {((WxeApp *)wxTheApp)->clearPtr(this);};
+class EwxGridBagSizer : public wxGridBagSizer {
+ public: ~EwxGridBagSizer() {((WxeApp *)wxTheApp)->clearPtr(this);};
EwxGridBagSizer(int vgap,int hgap) : wxGridBagSizer(vgap,hgap) {};
-};
+};
-class EwxStdDialogButtonSizer : public wxStdDialogButtonSizer {
- public: ~EwxStdDialogButtonSizer() {((WxeApp *)wxTheApp)->clearPtr(this);};
+class EwxStdDialogButtonSizer : public wxStdDialogButtonSizer {
+ public: ~EwxStdDialogButtonSizer() {((WxeApp *)wxTheApp)->clearPtr(this);};
EwxStdDialogButtonSizer() : wxStdDialogButtonSizer() {};
-};
+};
-class EwxFont : public wxFont {
- public: ~EwxFont() {((WxeApp *)wxTheApp)->clearPtr(this);};
+class EwxFont : public wxFont {
+ public: ~EwxFont() {((WxeApp *)wxTheApp)->clearPtr(this);};
EwxFont(int size,int family,int style,int weight,bool underlined,const wxString& face,wxFontEncoding encoding) : wxFont(size,family,style,weight,underlined,face,encoding) {};
EwxFont(const wxString& fontname) : wxFont(fontname) {};
EwxFont() : wxFont() {};
-};
+};
-class EwxToolTip : public wxToolTip {
- public: ~EwxToolTip() {((WxeApp *)wxTheApp)->clearPtr(this);};
+class EwxToolTip : public wxToolTip {
+ public: ~EwxToolTip() {((WxeApp *)wxTheApp)->clearPtr(this);};
EwxToolTip(const wxString& tip) : wxToolTip(tip) {};
-};
+};
-class EwxButton : public wxButton {
- public: ~EwxButton() {((WxeApp *)wxTheApp)->clearPtr(this);};
+class EwxButton : public wxButton {
+ public: ~EwxButton() {((WxeApp *)wxTheApp)->clearPtr(this);};
EwxButton(wxWindow * parent,wxWindowID id,const wxString& label,const wxPoint& pos,const wxSize& size,long style,const wxValidator& validator) : wxButton(parent,id,label,pos,size,style,validator) {};
EwxButton() : wxButton() {};
-};
+};
-class EwxBitmapButton : public wxBitmapButton {
- public: ~EwxBitmapButton() {((WxeApp *)wxTheApp)->clearPtr(this);};
+class EwxBitmapButton : public wxBitmapButton {
+ public: ~EwxBitmapButton() {((WxeApp *)wxTheApp)->clearPtr(this);};
EwxBitmapButton(wxWindow * parent,wxWindowID id,const wxBitmap& bitmap,const wxPoint& pos,const wxSize& size,long style,const wxValidator& validator) : wxBitmapButton(parent,id,bitmap,pos,size,style,validator) {};
EwxBitmapButton() : wxBitmapButton() {};
-};
+};
-class EwxToggleButton : public wxToggleButton {
- public: ~EwxToggleButton() {((WxeApp *)wxTheApp)->clearPtr(this);};
+class EwxToggleButton : public wxToggleButton {
+ public: ~EwxToggleButton() {((WxeApp *)wxTheApp)->clearPtr(this);};
EwxToggleButton(wxWindow * parent,wxWindowID id,const wxString& label,const wxPoint& pos,const wxSize& size,long style,const wxValidator& validator) : wxToggleButton(parent,id,label,pos,size,style,validator) {};
EwxToggleButton() : wxToggleButton() {};
-};
+};
-class EwxCalendarCtrl : public wxCalendarCtrl {
- public: ~EwxCalendarCtrl() {((WxeApp *)wxTheApp)->clearPtr(this);};
+class EwxCalendarCtrl : public wxCalendarCtrl {
+ public: ~EwxCalendarCtrl() {((WxeApp *)wxTheApp)->clearPtr(this);};
EwxCalendarCtrl(wxWindow * parent,wxWindowID id,const wxDateTime& date,const wxPoint& pos,const wxSize& size,long style) : wxCalendarCtrl(parent,id,date,pos,size,style) {};
EwxCalendarCtrl() : wxCalendarCtrl() {};
-};
+};
-class EwxCheckBox : public wxCheckBox {
- public: ~EwxCheckBox() {((WxeApp *)wxTheApp)->clearPtr(this);};
+class EwxCheckBox : public wxCheckBox {
+ public: ~EwxCheckBox() {((WxeApp *)wxTheApp)->clearPtr(this);};
EwxCheckBox(wxWindow * parent,wxWindowID id,const wxString& label,const wxPoint& pos,const wxSize& size,long style,const wxValidator& validator) : wxCheckBox(parent,id,label,pos,size,style,validator) {};
EwxCheckBox() : wxCheckBox() {};
-};
+};
-class EwxCheckListBox : public wxCheckListBox {
- public: ~EwxCheckListBox() {((WxeApp *)wxTheApp)->clearPtr(this);};
+class EwxCheckListBox : public wxCheckListBox {
+ public: ~EwxCheckListBox() {((WxeApp *)wxTheApp)->clearPtr(this);};
EwxCheckListBox(wxWindow * parent,wxWindowID id,const wxPoint& pos,const wxSize& size,const wxArrayString& choices,long style,const wxValidator& validator) : wxCheckListBox(parent,id,pos,size,choices,style,validator) {};
EwxCheckListBox() : wxCheckListBox() {};
-};
+};
-class EwxChoice : public wxChoice {
- public: ~EwxChoice() {((WxeApp *)wxTheApp)->clearPtr(this);};
+class EwxChoice : public wxChoice {
+ public: ~EwxChoice() {((WxeApp *)wxTheApp)->clearPtr(this);};
EwxChoice(wxWindow * parent,wxWindowID id,const wxPoint& pos,const wxSize& size,const wxArrayString& choices,long style,const wxValidator& validator) : wxChoice(parent,id,pos,size,choices,style,validator) {};
EwxChoice() : wxChoice() {};
-};
+};
-class EwxComboBox : public wxComboBox {
- public: ~EwxComboBox() {((WxeApp *)wxTheApp)->clearPtr(this);};
+class EwxComboBox : public wxComboBox {
+ public: ~EwxComboBox() {((WxeApp *)wxTheApp)->clearPtr(this);};
EwxComboBox(wxWindow * parent,wxWindowID id,const wxString& value,const wxPoint& pos,const wxSize& size,const wxArrayString& choices,long style,const wxValidator& validator) : wxComboBox(parent,id,value,pos,size,choices,style,validator) {};
EwxComboBox() : wxComboBox() {};
-};
+};
-class EwxGauge : public wxGauge {
- public: ~EwxGauge() {((WxeApp *)wxTheApp)->clearPtr(this);};
+class EwxGauge : public wxGauge {
+ public: ~EwxGauge() {((WxeApp *)wxTheApp)->clearPtr(this);};
EwxGauge(wxWindow * parent,wxWindowID id,int range,const wxPoint& pos,const wxSize& size,long style,const wxValidator& validator) : wxGauge(parent,id,range,pos,size,style,validator) {};
EwxGauge() : wxGauge() {};
-};
+};
-class EwxGenericDirCtrl : public wxGenericDirCtrl {
- public: ~EwxGenericDirCtrl() {((WxeApp *)wxTheApp)->clearPtr(this);};
+class EwxGenericDirCtrl : public wxGenericDirCtrl {
+ public: ~EwxGenericDirCtrl() {((WxeApp *)wxTheApp)->clearPtr(this);};
EwxGenericDirCtrl(wxWindow * parent,const wxWindowID id,const wxString& dir,const wxPoint& pos,const wxSize& size,long style,const wxString& filter,int defaultFilter) : wxGenericDirCtrl(parent,id,dir,pos,size,style,filter,defaultFilter) {};
EwxGenericDirCtrl() : wxGenericDirCtrl() {};
-};
+};
-class EwxStaticBox : public wxStaticBox {
- public: ~EwxStaticBox() {((WxeApp *)wxTheApp)->clearPtr(this);};
+class EwxStaticBox : public wxStaticBox {
+ public: ~EwxStaticBox() {((WxeApp *)wxTheApp)->clearPtr(this);};
EwxStaticBox(wxWindow * parent,wxWindowID id,const wxString& label,const wxPoint& pos,const wxSize& size,long style) : wxStaticBox(parent,id,label,pos,size,style) {};
EwxStaticBox() : wxStaticBox() {};
-};
+};
-class EwxStaticLine : public wxStaticLine {
- public: ~EwxStaticLine() {((WxeApp *)wxTheApp)->clearPtr(this);};
+class EwxStaticLine : public wxStaticLine {
+ public: ~EwxStaticLine() {((WxeApp *)wxTheApp)->clearPtr(this);};
EwxStaticLine(wxWindow * parent,wxWindowID id,const wxPoint& pos,const wxSize& size,long style) : wxStaticLine(parent,id,pos,size,style) {};
EwxStaticLine() : wxStaticLine() {};
-};
+};
-class EwxListBox : public wxListBox {
- public: ~EwxListBox() {((WxeApp *)wxTheApp)->clearPtr(this);};
+class EwxListBox : public wxListBox {
+ public: ~EwxListBox() {((WxeApp *)wxTheApp)->clearPtr(this);};
EwxListBox(wxWindow * parent,wxWindowID id,const wxPoint& pos,const wxSize& size,const wxArrayString& choices,long style,const wxValidator& validator) : wxListBox(parent,id,pos,size,choices,style,validator) {};
EwxListBox() : wxListBox() {};
-};
+};
-class EwxListCtrl : public wxListCtrl {
- public: ~EwxListCtrl() {((WxeApp *)wxTheApp)->clearPtr(this);};
+class EwxListCtrl : public wxListCtrl {
+ public: ~EwxListCtrl() {((WxeApp *)wxTheApp)->clearPtr(this);};
EwxListCtrl(wxWindow * parent,wxWindowID winid,const wxPoint& pos,const wxSize& size,long style,const wxValidator& validator) : wxListCtrl(parent,winid,pos,size,style,validator) {};
EwxListCtrl() : wxListCtrl() {};
-};
+};
-class EwxListItem : public wxListItem {
- public: ~EwxListItem() {((WxeApp *)wxTheApp)->clearPtr(this);};
+class EwxListItem : public wxListItem {
+ public: ~EwxListItem() {((WxeApp *)wxTheApp)->clearPtr(this);};
EwxListItem(const wxListItem& item) : wxListItem(item) {};
EwxListItem() : wxListItem() {};
-};
+};
-class EwxImageList : public wxImageList {
- public: ~EwxImageList() {((WxeApp *)wxTheApp)->clearPtr(this);};
+class EwxImageList : public wxImageList {
+ public: ~EwxImageList() {((WxeApp *)wxTheApp)->clearPtr(this);};
EwxImageList(int width,int height,bool mask,int initialCount) : wxImageList(width,height,mask,initialCount) {};
EwxImageList() : wxImageList() {};
-};
+};
-class EwxTextCtrl : public wxTextCtrl {
- public: ~EwxTextCtrl() {((WxeApp *)wxTheApp)->clearPtr(this);};
+class EwxTextCtrl : public wxTextCtrl {
+ public: ~EwxTextCtrl() {((WxeApp *)wxTheApp)->clearPtr(this);};
EwxTextCtrl(wxWindow * parent,wxWindowID id,const wxString& value,const wxPoint& pos,const wxSize& size,long style,const wxValidator& validator) : wxTextCtrl(parent,id,value,pos,size,style,validator) {};
EwxTextCtrl() : wxTextCtrl() {};
-};
+};
-class EwxNotebook : public wxNotebook {
- public: ~EwxNotebook() {((WxeApp *)wxTheApp)->clearPtr(this);};
+class EwxNotebook : public wxNotebook {
+ public: ~EwxNotebook() {((WxeApp *)wxTheApp)->clearPtr(this);};
EwxNotebook(wxWindow * parent,wxWindowID winid,const wxPoint& pos,const wxSize& size,long style) : wxNotebook(parent,winid,pos,size,style) {};
EwxNotebook() : wxNotebook() {};
-};
+};
-class EwxChoicebook : public wxChoicebook {
- public: ~EwxChoicebook() {((WxeApp *)wxTheApp)->clearPtr(this);};
+class EwxChoicebook : public wxChoicebook {
+ public: ~EwxChoicebook() {((WxeApp *)wxTheApp)->clearPtr(this);};
EwxChoicebook(wxWindow * parent,wxWindowID id,const wxPoint& pos,const wxSize& size,long style) : wxChoicebook(parent,id,pos,size,style) {};
EwxChoicebook() : wxChoicebook() {};
-};
+};
-class EwxToolbook : public wxToolbook {
- public: ~EwxToolbook() {((WxeApp *)wxTheApp)->clearPtr(this);};
+class EwxToolbook : public wxToolbook {
+ public: ~EwxToolbook() {((WxeApp *)wxTheApp)->clearPtr(this);};
EwxToolbook(wxWindow * parent,wxWindowID id,const wxPoint& pos,const wxSize& size,long style) : wxToolbook(parent,id,pos,size,style) {};
EwxToolbook() : wxToolbook() {};
-};
+};
-class EwxListbook : public wxListbook {
- public: ~EwxListbook() {((WxeApp *)wxTheApp)->clearPtr(this);};
+class EwxListbook : public wxListbook {
+ public: ~EwxListbook() {((WxeApp *)wxTheApp)->clearPtr(this);};
EwxListbook(wxWindow * parent,wxWindowID id,const wxPoint& pos,const wxSize& size,long style) : wxListbook(parent,id,pos,size,style) {};
EwxListbook() : wxListbook() {};
-};
+};
-class EwxTreebook : public wxTreebook {
- public: ~EwxTreebook() {((WxeApp *)wxTheApp)->clearPtr(this);};
+class EwxTreebook : public wxTreebook {
+ public: ~EwxTreebook() {((WxeApp *)wxTheApp)->clearPtr(this);};
EwxTreebook(wxWindow * parent,wxWindowID id,const wxPoint& pos,const wxSize& size,long style) : wxTreebook(parent,id,pos,size,style) {};
EwxTreebook() : wxTreebook() {};
-};
+};
-class EwxTreeCtrl : public wxTreeCtrl {
- public: ~EwxTreeCtrl() {((WxeApp *)wxTheApp)->clearPtr(this);};
+class EwxTreeCtrl : public wxTreeCtrl {
+ public: ~EwxTreeCtrl() {((WxeApp *)wxTheApp)->clearPtr(this);};
EwxTreeCtrl(wxWindow * parent,wxWindowID id,const wxPoint& pos,const wxSize& size,long style,const wxValidator& validator) : wxTreeCtrl(parent,id,pos,size,style,validator) {};
EwxTreeCtrl() : wxTreeCtrl() {};
-};
+};
-class EwxScrollBar : public wxScrollBar {
- public: ~EwxScrollBar() {((WxeApp *)wxTheApp)->clearPtr(this);};
+class EwxScrollBar : public wxScrollBar {
+ public: ~EwxScrollBar() {((WxeApp *)wxTheApp)->clearPtr(this);};
EwxScrollBar(wxWindow * parent,wxWindowID id,const wxPoint& pos,const wxSize& size,long style,const wxValidator& validator) : wxScrollBar(parent,id,pos,size,style,validator) {};
EwxScrollBar() : wxScrollBar() {};
-};
+};
-class EwxSpinButton : public wxSpinButton {
- public: ~EwxSpinButton() {((WxeApp *)wxTheApp)->clearPtr(this);};
+class EwxSpinButton : public wxSpinButton {
+ public: ~EwxSpinButton() {((WxeApp *)wxTheApp)->clearPtr(this);};
EwxSpinButton(wxWindow * parent,wxWindowID id,const wxPoint& pos,const wxSize& size,long style) : wxSpinButton(parent,id,pos,size,style) {};
EwxSpinButton() : wxSpinButton() {};
-};
+};
-class EwxSpinCtrl : public wxSpinCtrl {
- public: ~EwxSpinCtrl() {((WxeApp *)wxTheApp)->clearPtr(this);};
+class EwxSpinCtrl : public wxSpinCtrl {
+ public: ~EwxSpinCtrl() {((WxeApp *)wxTheApp)->clearPtr(this);};
EwxSpinCtrl(wxWindow * parent,wxWindowID id,const wxString& value,const wxPoint& pos,const wxSize& size,long style,int min,int max,int initial) : wxSpinCtrl(parent,id,value,pos,size,style,min,max,initial) {};
EwxSpinCtrl() : wxSpinCtrl() {};
-};
+};
-class EwxStaticText : public wxStaticText {
- public: ~EwxStaticText() {((WxeApp *)wxTheApp)->clearPtr(this);};
+class EwxStaticText : public wxStaticText {
+ public: ~EwxStaticText() {((WxeApp *)wxTheApp)->clearPtr(this);};
EwxStaticText(wxWindow * parent,wxWindowID id,const wxString& label,const wxPoint& pos,const wxSize& size,long style) : wxStaticText(parent,id,label,pos,size,style) {};
EwxStaticText() : wxStaticText() {};
-};
+};
-class EwxStaticBitmap : public wxStaticBitmap {
- public: ~EwxStaticBitmap() {((WxeApp *)wxTheApp)->clearPtr(this);};
+class EwxStaticBitmap : public wxStaticBitmap {
+ public: ~EwxStaticBitmap() {((WxeApp *)wxTheApp)->clearPtr(this);};
EwxStaticBitmap(wxWindow * parent,wxWindowID id,const wxBitmap& label,const wxPoint& pos,const wxSize& size,long style) : wxStaticBitmap(parent,id,label,pos,size,style) {};
EwxStaticBitmap() : wxStaticBitmap() {};
-};
+};
-class EwxRadioBox : public wxRadioBox {
- public: ~EwxRadioBox() {((WxeApp *)wxTheApp)->clearPtr(this);};
+class EwxRadioBox : public wxRadioBox {
+ public: ~EwxRadioBox() {((WxeApp *)wxTheApp)->clearPtr(this);};
EwxRadioBox(wxWindow * parent,wxWindowID id,const wxString& title,const wxPoint& pos,const wxSize& size,const wxArrayString& choices,int majorDim,long style,const wxValidator& val) : wxRadioBox(parent,id,title,pos,size,choices,majorDim,style,val) {};
-};
+};
-class EwxRadioButton : public wxRadioButton {
- public: ~EwxRadioButton() {((WxeApp *)wxTheApp)->clearPtr(this);};
+class EwxRadioButton : public wxRadioButton {
+ public: ~EwxRadioButton() {((WxeApp *)wxTheApp)->clearPtr(this);};
EwxRadioButton(wxWindow * parent,wxWindowID id,const wxString& label,const wxPoint& pos,const wxSize& size,long style,const wxValidator& validator) : wxRadioButton(parent,id,label,pos,size,style,validator) {};
EwxRadioButton() : wxRadioButton() {};
-};
+};
-class EwxSlider : public wxSlider {
- public: ~EwxSlider() {((WxeApp *)wxTheApp)->clearPtr(this);};
+class EwxSlider : public wxSlider {
+ public: ~EwxSlider() {((WxeApp *)wxTheApp)->clearPtr(this);};
EwxSlider(wxWindow * parent,wxWindowID id,int value,int minValue,int maxValue,const wxPoint& pos,const wxSize& size,long style,const wxValidator& validator) : wxSlider(parent,id,value,minValue,maxValue,pos,size,style,validator) {};
EwxSlider() : wxSlider() {};
-};
+};
-class EwxDialog : public wxDialog {
- public: ~EwxDialog() {((WxeApp *)wxTheApp)->clearPtr(this);};
+class EwxDialog : public wxDialog {
+ public: ~EwxDialog() {((WxeApp *)wxTheApp)->clearPtr(this);};
EwxDialog(wxWindow * parent,wxWindowID id,const wxString& title,const wxPoint& pos,const wxSize& size,long style) : wxDialog(parent,id,title,pos,size,style) {};
EwxDialog() : wxDialog() {};
-};
+};
-class EwxColourDialog : public wxColourDialog {
- public: ~EwxColourDialog() {((WxeApp *)wxTheApp)->clearPtr(this);};
+class EwxColourDialog : public wxColourDialog {
+ public: ~EwxColourDialog() {((WxeApp *)wxTheApp)->clearPtr(this);};
EwxColourDialog(wxWindow * parent,wxColourData * data) : wxColourDialog(parent,data) {};
EwxColourDialog() : wxColourDialog() {};
-};
+};
-class EwxColourData : public wxColourData {
- public: ~EwxColourData() {((WxeApp *)wxTheApp)->clearPtr(this);};
+class EwxColourData : public wxColourData {
+ public: ~EwxColourData() {((WxeApp *)wxTheApp)->clearPtr(this);};
EwxColourData(const wxColourData& data) : wxColourData(data) {};
EwxColourData() : wxColourData() {};
-};
+};
-class EwxPalette : public wxPalette {
- public: ~EwxPalette() {((WxeApp *)wxTheApp)->clearPtr(this);};
+class EwxPalette : public wxPalette {
+ public: ~EwxPalette() {((WxeApp *)wxTheApp)->clearPtr(this);};
EwxPalette(int n,const unsigned char * red,const unsigned char * green,const unsigned char * blue) : wxPalette(n,red,green,blue) {};
EwxPalette() : wxPalette() {};
-};
+};
-class EwxDirDialog : public wxDirDialog {
- public: ~EwxDirDialog() {((WxeApp *)wxTheApp)->clearPtr(this);};
+class EwxDirDialog : public wxDirDialog {
+ public: ~EwxDirDialog() {((WxeApp *)wxTheApp)->clearPtr(this);};
EwxDirDialog(wxWindow * parent,const wxString& title,const wxString& defaultPath,long style,const wxPoint& pos,const wxSize& sz) : wxDirDialog(parent,title,defaultPath,style,pos,sz) {};
-};
+};
-class EwxFileDialog : public wxFileDialog {
- public: ~EwxFileDialog() {((WxeApp *)wxTheApp)->clearPtr(this);};
+class EwxFileDialog : public wxFileDialog {
+ public: ~EwxFileDialog() {((WxeApp *)wxTheApp)->clearPtr(this);};
EwxFileDialog(wxWindow * parent,const wxString& message,const wxString& defaultDir,const wxString& defaultFile,const wxString& wildCard,long style,const wxPoint& pos,const wxSize& sz) : wxFileDialog(parent,message,defaultDir,defaultFile,wildCard,style,pos,sz) {};
-};
+};
-class EwxFilePickerCtrl : public wxFilePickerCtrl {
- public: ~EwxFilePickerCtrl() {((WxeApp *)wxTheApp)->clearPtr(this);};
+class EwxFilePickerCtrl : public wxFilePickerCtrl {
+ public: ~EwxFilePickerCtrl() {((WxeApp *)wxTheApp)->clearPtr(this);};
EwxFilePickerCtrl(wxWindow * parent,wxWindowID id,const wxString& path,const wxString& message,const wxString& wildcard,const wxPoint& pos,const wxSize& size,long style,const wxValidator& validator) : wxFilePickerCtrl(parent,id,path,message,wildcard,pos,size,style,validator) {};
EwxFilePickerCtrl() : wxFilePickerCtrl() {};
-};
+};
-class EwxDirPickerCtrl : public wxDirPickerCtrl {
- public: ~EwxDirPickerCtrl() {((WxeApp *)wxTheApp)->clearPtr(this);};
+class EwxDirPickerCtrl : public wxDirPickerCtrl {
+ public: ~EwxDirPickerCtrl() {((WxeApp *)wxTheApp)->clearPtr(this);};
EwxDirPickerCtrl(wxWindow * parent,wxWindowID id,const wxString& path,const wxString& message,const wxPoint& pos,const wxSize& size,long style,const wxValidator& validator) : wxDirPickerCtrl(parent,id,path,message,pos,size,style,validator) {};
EwxDirPickerCtrl() : wxDirPickerCtrl() {};
-};
+};
-class EwxColourPickerCtrl : public wxColourPickerCtrl {
- public: ~EwxColourPickerCtrl() {((WxeApp *)wxTheApp)->clearPtr(this);};
+class EwxColourPickerCtrl : public wxColourPickerCtrl {
+ public: ~EwxColourPickerCtrl() {((WxeApp *)wxTheApp)->clearPtr(this);};
EwxColourPickerCtrl(wxWindow * parent,wxWindowID id,const wxColour& col,const wxPoint& pos,const wxSize& size,long style,const wxValidator& validator) : wxColourPickerCtrl(parent,id,col,pos,size,style,validator) {};
EwxColourPickerCtrl() : wxColourPickerCtrl() {};
-};
+};
-class EwxDatePickerCtrl : public wxDatePickerCtrl {
- public: ~EwxDatePickerCtrl() {((WxeApp *)wxTheApp)->clearPtr(this);};
+class EwxDatePickerCtrl : public wxDatePickerCtrl {
+ public: ~EwxDatePickerCtrl() {((WxeApp *)wxTheApp)->clearPtr(this);};
EwxDatePickerCtrl(wxWindow * parent,wxWindowID id,const wxDateTime& date,const wxPoint& pos,const wxSize& size,long style,const wxValidator& validator) : wxDatePickerCtrl(parent,id,date,pos,size,style,validator) {};
EwxDatePickerCtrl() : wxDatePickerCtrl() {};
-};
+};
-class EwxFontPickerCtrl : public wxFontPickerCtrl {
- public: ~EwxFontPickerCtrl() {((WxeApp *)wxTheApp)->clearPtr(this);};
+class EwxFontPickerCtrl : public wxFontPickerCtrl {
+ public: ~EwxFontPickerCtrl() {((WxeApp *)wxTheApp)->clearPtr(this);};
EwxFontPickerCtrl(wxWindow * parent,wxWindowID id,const wxFont& initial,const wxPoint& pos,const wxSize& size,long style,const wxValidator& validator) : wxFontPickerCtrl(parent,id,initial,pos,size,style,validator) {};
EwxFontPickerCtrl() : wxFontPickerCtrl() {};
-};
+};
-class EwxFindReplaceDialog : public wxFindReplaceDialog {
- public: ~EwxFindReplaceDialog() {((WxeApp *)wxTheApp)->clearPtr(this);};
+class EwxFindReplaceDialog : public wxFindReplaceDialog {
+ public: ~EwxFindReplaceDialog() {((WxeApp *)wxTheApp)->clearPtr(this);};
EwxFindReplaceDialog(wxWindow * parent,wxFindReplaceData * data,const wxString& title,int style) : wxFindReplaceDialog(parent,data,title,style) {};
EwxFindReplaceDialog() : wxFindReplaceDialog() {};
-};
+};
-class EwxFindReplaceData : public wxFindReplaceData {
- public: ~EwxFindReplaceData() {((WxeApp *)wxTheApp)->clearPtr(this);};
+class EwxFindReplaceData : public wxFindReplaceData {
+ public: ~EwxFindReplaceData() {((WxeApp *)wxTheApp)->clearPtr(this);};
EwxFindReplaceData(unsigned int flags) : wxFindReplaceData(flags) {};
EwxFindReplaceData() : wxFindReplaceData() {};
-};
+};
-class EwxMultiChoiceDialog : public wxMultiChoiceDialog {
- public: ~EwxMultiChoiceDialog() {((WxeApp *)wxTheApp)->clearPtr(this);};
+class EwxMultiChoiceDialog : public wxMultiChoiceDialog {
+ public: ~EwxMultiChoiceDialog() {((WxeApp *)wxTheApp)->clearPtr(this);};
EwxMultiChoiceDialog(wxWindow * parent,const wxString& message,const wxString& caption,const wxArrayString& choices,long style,const wxPoint& pos) : wxMultiChoiceDialog(parent,message,caption,choices,style,pos) {};
EwxMultiChoiceDialog() : wxMultiChoiceDialog() {};
-};
+};
-class EwxSingleChoiceDialog : public wxSingleChoiceDialog {
- public: ~EwxSingleChoiceDialog() {((WxeApp *)wxTheApp)->clearPtr(this);};
+class EwxSingleChoiceDialog : public wxSingleChoiceDialog {
+ public: ~EwxSingleChoiceDialog() {((WxeApp *)wxTheApp)->clearPtr(this);};
EwxSingleChoiceDialog(wxWindow * parent,const wxString& message,const wxString& caption,const wxArrayString& choices,char ** clientData,long style,const wxPoint& pos) : wxSingleChoiceDialog(parent,message,caption,choices,clientData,style,pos) {};
EwxSingleChoiceDialog() : wxSingleChoiceDialog() {};
-};
+};
-class EwxTextEntryDialog : public wxTextEntryDialog {
- public: ~EwxTextEntryDialog() {((WxeApp *)wxTheApp)->clearPtr(this);};
+class EwxTextEntryDialog : public wxTextEntryDialog {
+ public: ~EwxTextEntryDialog() {((WxeApp *)wxTheApp)->clearPtr(this);};
EwxTextEntryDialog(wxWindow * parent,const wxString& message,const wxString& caption,const wxString& value,long style,const wxPoint& pos) : wxTextEntryDialog(parent,message,caption,value,style,pos) {};
-};
+};
-class EwxPasswordEntryDialog : public wxPasswordEntryDialog {
- public: ~EwxPasswordEntryDialog() {((WxeApp *)wxTheApp)->clearPtr(this);};
+class EwxPasswordEntryDialog : public wxPasswordEntryDialog {
+ public: ~EwxPasswordEntryDialog() {((WxeApp *)wxTheApp)->clearPtr(this);};
EwxPasswordEntryDialog(wxWindow * parent,const wxString& message,const wxString& caption,const wxString& value,long style,const wxPoint& pos) : wxPasswordEntryDialog(parent,message,caption,value,style,pos) {};
-};
+};
-class EwxFontData : public wxFontData {
- public: ~EwxFontData() {((WxeApp *)wxTheApp)->clearPtr(this);};
+class EwxFontData : public wxFontData {
+ public: ~EwxFontData() {((WxeApp *)wxTheApp)->clearPtr(this);};
EwxFontData(const wxFontData& data) : wxFontData(data) {};
EwxFontData() : wxFontData() {};
-};
+};
-class EwxFontDialog : public wxFontDialog {
- public: ~EwxFontDialog() {((WxeApp *)wxTheApp)->clearPtr(this);};
+class EwxFontDialog : public wxFontDialog {
+ public: ~EwxFontDialog() {((WxeApp *)wxTheApp)->clearPtr(this);};
EwxFontDialog(wxWindow * parent,const wxFontData& data) : wxFontDialog(parent,data) {};
EwxFontDialog() : wxFontDialog() {};
-};
+};
-class EwxProgressDialog : public wxProgressDialog {
- public: ~EwxProgressDialog() {((WxeApp *)wxTheApp)->clearPtr(this);};
+class EwxProgressDialog : public wxProgressDialog {
+ public: ~EwxProgressDialog() {((WxeApp *)wxTheApp)->clearPtr(this);};
EwxProgressDialog(const wxString& title,const wxString& message,int maximum,wxWindow * parent,int style) : wxProgressDialog(title,message,maximum,parent,style) {};
-};
+};
-class EwxMessageDialog : public wxMessageDialog {
- public: ~EwxMessageDialog() {((WxeApp *)wxTheApp)->clearPtr(this);};
+class EwxMessageDialog : public wxMessageDialog {
+ public: ~EwxMessageDialog() {((WxeApp *)wxTheApp)->clearPtr(this);};
EwxMessageDialog(wxWindow * parent,const wxString& message,const wxString& caption,long style,const wxPoint& pos) : wxMessageDialog(parent,message,caption,style,pos) {};
-};
+};
-class EwxPageSetupDialog : public wxPageSetupDialog {
- public: ~EwxPageSetupDialog() {((WxeApp *)wxTheApp)->clearPtr(this);};
+class EwxPageSetupDialog : public wxPageSetupDialog {
+ public: ~EwxPageSetupDialog() {((WxeApp *)wxTheApp)->clearPtr(this);};
EwxPageSetupDialog(wxWindow * parent,wxPageSetupDialogData * data) : wxPageSetupDialog(parent,data) {};
-};
+};
-class EwxPageSetupDialogData : public wxPageSetupDialogData {
- public: ~EwxPageSetupDialogData() {((WxeApp *)wxTheApp)->clearPtr(this);};
+class EwxPageSetupDialogData : public wxPageSetupDialogData {
+ public: ~EwxPageSetupDialogData() {((WxeApp *)wxTheApp)->clearPtr(this);};
EwxPageSetupDialogData(const wxPrintData& printData) : wxPageSetupDialogData(printData) {};
EwxPageSetupDialogData(const wxPageSetupDialogData& printData) : wxPageSetupDialogData(printData) {};
EwxPageSetupDialogData() : wxPageSetupDialogData() {};
-};
+};
-class EwxPrintDialog : public wxPrintDialog {
- public: ~EwxPrintDialog() {((WxeApp *)wxTheApp)->clearPtr(this);};
+class EwxPrintDialog : public wxPrintDialog {
+ public: ~EwxPrintDialog() {((WxeApp *)wxTheApp)->clearPtr(this);};
EwxPrintDialog(wxWindow * parent,wxPrintDialogData * data) : wxPrintDialog(parent,data) {};
EwxPrintDialog(wxWindow * parent,wxPrintData * data) : wxPrintDialog(parent,data) {};
-};
+};
-class EwxPrintDialogData : public wxPrintDialogData {
- public: ~EwxPrintDialogData() {((WxeApp *)wxTheApp)->clearPtr(this);};
+class EwxPrintDialogData : public wxPrintDialogData {
+ public: ~EwxPrintDialogData() {((WxeApp *)wxTheApp)->clearPtr(this);};
EwxPrintDialogData(const wxPrintDialogData& dialogData) : wxPrintDialogData(dialogData) {};
EwxPrintDialogData(const wxPrintData& dialogData) : wxPrintDialogData(dialogData) {};
EwxPrintDialogData() : wxPrintDialogData() {};
-};
+};
-class EwxPrintData : public wxPrintData {
- public: ~EwxPrintData() {((WxeApp *)wxTheApp)->clearPtr(this);};
+class EwxPrintData : public wxPrintData {
+ public: ~EwxPrintData() {((WxeApp *)wxTheApp)->clearPtr(this);};
EwxPrintData(const wxPrintData& printData) : wxPrintData(printData) {};
EwxPrintData() : wxPrintData() {};
-};
+};
-class EwxPrintPreview : public wxPrintPreview {
- public: ~EwxPrintPreview() {((WxeApp *)wxTheApp)->clearPtr(this);};
+class EwxPrintPreview : public wxPrintPreview {
+ public: ~EwxPrintPreview() {((WxeApp *)wxTheApp)->clearPtr(this);};
EwxPrintPreview(wxPrintout * printout,wxPrintout * printoutForPrinting,wxPrintData * data) : wxPrintPreview(printout,printoutForPrinting,data) {};
EwxPrintPreview(wxPrintout * printout,wxPrintout * printoutForPrinting,wxPrintDialogData * data) : wxPrintPreview(printout,printoutForPrinting,data) {};
-};
+};
-class EwxPreviewFrame : public wxPreviewFrame {
- public: ~EwxPreviewFrame() {((WxeApp *)wxTheApp)->clearPtr(this);};
+class EwxPreviewFrame : public wxPreviewFrame {
+ public: ~EwxPreviewFrame() {((WxeApp *)wxTheApp)->clearPtr(this);};
EwxPreviewFrame(wxPrintPreview * preview,wxWindow * parent,const wxString& title,const wxPoint& pos,const wxSize& size,long style) : wxPreviewFrame(preview,parent,title,pos,size,style) {};
-};
+};
-class EwxPreviewControlBar : public wxPreviewControlBar {
- public: ~EwxPreviewControlBar() {((WxeApp *)wxTheApp)->clearPtr(this);};
+class EwxPreviewControlBar : public wxPreviewControlBar {
+ public: ~EwxPreviewControlBar() {((WxeApp *)wxTheApp)->clearPtr(this);};
EwxPreviewControlBar(wxPrintPreview * preview,long buttons,wxWindow * parent,const wxPoint& pos,const wxSize& size,long style) : wxPreviewControlBar(preview,buttons,parent,pos,size,style) {};
-};
+};
-class EwxPrinter : public wxPrinter {
- public: ~EwxPrinter() {((WxeApp *)wxTheApp)->clearPtr(this);};
+class EwxPrinter : public wxPrinter {
+ public: ~EwxPrinter() {((WxeApp *)wxTheApp)->clearPtr(this);};
EwxPrinter(wxPrintDialogData * data) : wxPrinter(data) {};
-};
+};
-class EwxXmlResource : public wxXmlResource {
- public: ~EwxXmlResource() {((WxeApp *)wxTheApp)->clearPtr(this);};
+class EwxXmlResource : public wxXmlResource {
+ public: ~EwxXmlResource() {((WxeApp *)wxTheApp)->clearPtr(this);};
EwxXmlResource(const wxString& filemask,int flags,const wxString& domain) : wxXmlResource(filemask,flags,domain) {};
EwxXmlResource(int flags,const wxString& domain) : wxXmlResource(flags,domain) {};
-};
+};
-class EwxHtmlEasyPrinting : public wxHtmlEasyPrinting {
- public: ~EwxHtmlEasyPrinting() {((WxeApp *)wxTheApp)->clearPtr(this);};
+class EwxHtmlEasyPrinting : public wxHtmlEasyPrinting {
+ public: ~EwxHtmlEasyPrinting() {((WxeApp *)wxTheApp)->clearPtr(this);};
EwxHtmlEasyPrinting(const wxString& name,wxWindow * parentWindow) : wxHtmlEasyPrinting(name,parentWindow) {};
-};
+};
-class EwxGLCanvas : public wxGLCanvas {
- public: ~EwxGLCanvas() {deleteActiveGL(this);((WxeApp *)wxTheApp)->clearPtr(this);};
+class EwxGLCanvas : public wxGLCanvas {
+ public: ~EwxGLCanvas() {deleteActiveGL(this);((WxeApp *)wxTheApp)->clearPtr(this);};
EwxGLCanvas(wxWindow * parent,const wxGLContext * shared,wxWindowID id,const wxPoint& pos,const wxSize& size,long style,const wxString& name,int * attribList,const wxPalette& palette) : wxGLCanvas(parent,shared,id,pos,size,style,name,attribList,palette) {};
EwxGLCanvas(wxWindow * parent,const wxGLCanvas * shared,wxWindowID id,const wxPoint& pos,const wxSize& size,long style,const wxString& name,int * attribList,const wxPalette& palette) : wxGLCanvas(parent,shared,id,pos,size,style,name,attribList,palette) {};
EwxGLCanvas(wxWindow * parent,wxWindowID id,const wxPoint& pos,const wxSize& size,long style,const wxString& name,int * attribList,const wxPalette& palette) : wxGLCanvas(parent,id,pos,size,style,name,attribList,palette) {};
-};
+};
-class EwxAuiManager : public wxAuiManager {
- public: ~EwxAuiManager() {((WxeApp *)wxTheApp)->clearPtr(this);};
+class EwxAuiManager : public wxAuiManager {
+ public: ~EwxAuiManager() {((WxeApp *)wxTheApp)->clearPtr(this);};
EwxAuiManager(wxWindow * managed_wnd,unsigned int flags) : wxAuiManager(managed_wnd,flags) {};
-};
+};
-class EwxAuiNotebook : public wxAuiNotebook {
- public: ~EwxAuiNotebook() {((WxeApp *)wxTheApp)->clearPtr(this);};
+class EwxAuiNotebook : public wxAuiNotebook {
+ public: ~EwxAuiNotebook() {((WxeApp *)wxTheApp)->clearPtr(this);};
EwxAuiNotebook(wxWindow * parent,wxWindowID id,const wxPoint& pos,const wxSize& size,long style) : wxAuiNotebook(parent,id,pos,size,style) {};
EwxAuiNotebook() : wxAuiNotebook() {};
-};
+};
-class EwxMDIParentFrame : public wxMDIParentFrame {
- public: ~EwxMDIParentFrame() {((WxeApp *)wxTheApp)->clearPtr(this);};
+class EwxMDIParentFrame : public wxMDIParentFrame {
+ public: ~EwxMDIParentFrame() {((WxeApp *)wxTheApp)->clearPtr(this);};
EwxMDIParentFrame(wxWindow * parent,wxWindowID id,const wxString& title,const wxPoint& pos,const wxSize& size,long style) : wxMDIParentFrame(parent,id,title,pos,size,style) {};
EwxMDIParentFrame() : wxMDIParentFrame() {};
-};
+};
-class EwxMDIChildFrame : public wxMDIChildFrame {
- public: ~EwxMDIChildFrame() {((WxeApp *)wxTheApp)->clearPtr(this);};
+class EwxMDIChildFrame : public wxMDIChildFrame {
+ public: ~EwxMDIChildFrame() {((WxeApp *)wxTheApp)->clearPtr(this);};
EwxMDIChildFrame(wxMDIParentFrame * parent,wxWindowID id,const wxString& title,const wxPoint& pos,const wxSize& size,long style) : wxMDIChildFrame(parent,id,title,pos,size,style) {};
EwxMDIChildFrame() : wxMDIChildFrame() {};
-};
+};
-class EwxMDIClientWindow : public wxMDIClientWindow {
- public: ~EwxMDIClientWindow() {((WxeApp *)wxTheApp)->clearPtr(this);};
+class EwxMDIClientWindow : public wxMDIClientWindow {
+ public: ~EwxMDIClientWindow() {((WxeApp *)wxTheApp)->clearPtr(this);};
EwxMDIClientWindow(wxMDIParentFrame * parent,long style) : wxMDIClientWindow(parent,style) {};
EwxMDIClientWindow() : wxMDIClientWindow() {};
-};
+};
-class EwxLayoutAlgorithm : public wxLayoutAlgorithm {
- public: ~EwxLayoutAlgorithm() {((WxeApp *)wxTheApp)->clearPtr(this);};
+class EwxLayoutAlgorithm : public wxLayoutAlgorithm {
+ public: ~EwxLayoutAlgorithm() {((WxeApp *)wxTheApp)->clearPtr(this);};
EwxLayoutAlgorithm() : wxLayoutAlgorithm() {};
-};
+};
-class EwxPrintout : public wxPrintout {
- public: ~EwxPrintout() {((WxeApp *)wxTheApp)->clearPtr(this);};
+class EwxPrintout : public wxPrintout {
+ public: ~EwxPrintout() {((WxeApp *)wxTheApp)->clearPtr(this);};
EwxPrintout(const wxString& title) : wxPrintout(title) {};
-};
+};
-class EwxClipboard : public wxClipboard {
- public: ~EwxClipboard() {((WxeApp *)wxTheApp)->clearPtr(this);};
+class EwxClipboard : public wxClipboard {
+ public: ~EwxClipboard() {((WxeApp *)wxTheApp)->clearPtr(this);};
EwxClipboard() : wxClipboard() {};
-};
+};
-class EwxSplitterWindow : public wxSplitterWindow {
- public: ~EwxSplitterWindow() {((WxeApp *)wxTheApp)->clearPtr(this);};
+class EwxSplitterWindow : public wxSplitterWindow {
+ public: ~EwxSplitterWindow() {((WxeApp *)wxTheApp)->clearPtr(this);};
EwxSplitterWindow(wxWindow * parent,wxWindowID id,const wxPoint& pos,const wxSize& size,long style) : wxSplitterWindow(parent,id,pos,size,style) {};
EwxSplitterWindow() : wxSplitterWindow() {};
-};
+};
-class EwxHtmlWindow : public wxHtmlWindow {
- public: ~EwxHtmlWindow() {((WxeApp *)wxTheApp)->clearPtr(this);};
+class EwxHtmlWindow : public wxHtmlWindow {
+ public: ~EwxHtmlWindow() {((WxeApp *)wxTheApp)->clearPtr(this);};
EwxHtmlWindow(wxWindow * parent,wxWindowID id,const wxPoint& pos,const wxSize& size,long style) : wxHtmlWindow(parent,id,pos,size,style) {};
EwxHtmlWindow() : wxHtmlWindow() {};
-};
+};
void WxeApp::delete_object(void *ptr, wxeRefData *refd) {
switch(refd->type) {
diff --git a/lib/wx/c_src/gen/wxe_events.cpp b/lib/wx/c_src/gen/wxe_events.cpp
index f15754a072..a6857442c9 100644
--- a/lib/wx/c_src/gen/wxe_events.cpp
+++ b/lib/wx/c_src/gen/wxe_events.cpp
@@ -1,23 +1,23 @@
/*
* %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%
*/
-/***** This file is generated do not edit ****/
+/***** This file is generated do not edit ****/
#include <wx/wx.h>
#include "../wxe_impl.h"
@@ -31,7 +31,7 @@ wxeEtype::wxeEtype(const char *name, int Id) {eName = name;cID = Id;}
WX_DECLARE_HASH_MAP(int, wxeEtype*, wxIntegerHash, wxIntegerEqual, wxeETmap );
-wxeETmap etmap;
+wxeETmap etmap;
int wxeEventTypeFromAtom(char *etype_atom) {
wxeETmap::iterator it;
@@ -48,9 +48,9 @@ int wxeEventTypeFromAtom(char *etype_atom) {
return -1;
}
-void initEventTable()
+void initEventTable()
{
- struct { int ev_type; int class_id; const char * ev_name;} event_types[] =
+ struct { int ev_type; int class_id; const char * ev_name;} event_types[] =
{
{wxEVT_NULL, 0, "null"},
{wxEVT_COMMAND_BUTTON_CLICKED, 163, "command_button_clicked"},
@@ -274,27 +274,27 @@ void initEventTable()
{wxEVT_COMMAND_AUINOTEBOOK_END_DRAG, 220, "command_auinotebook_end_drag"},
{wxEVT_COMMAND_AUINOTEBOOK_DRAG_MOTION, 220, "command_auinotebook_drag_motion"},
{wxEVT_COMMAND_AUINOTEBOOK_ALLOW_DND, 220, "command_auinotebook_allow_dnd"},
-#if wxCHECK_VERSION(2,8,5)
+#if wxCHECK_VERSION(2,8,5)
{wxEVT_COMMAND_AUINOTEBOOK_TAB_MIDDLE_DOWN, 220, "command_auinotebook_tab_middle_down"},
-#endif
-#if wxCHECK_VERSION(2,8,5)
+#endif
+#if wxCHECK_VERSION(2,8,5)
{wxEVT_COMMAND_AUINOTEBOOK_TAB_MIDDLE_UP, 220, "command_auinotebook_tab_middle_up"},
-#endif
-#if wxCHECK_VERSION(2,8,5)
+#endif
+#if wxCHECK_VERSION(2,8,5)
{wxEVT_COMMAND_AUINOTEBOOK_TAB_RIGHT_DOWN, 220, "command_auinotebook_tab_right_down"},
-#endif
-#if wxCHECK_VERSION(2,8,5)
+#endif
+#if wxCHECK_VERSION(2,8,5)
{wxEVT_COMMAND_AUINOTEBOOK_TAB_RIGHT_UP, 220, "command_auinotebook_tab_right_up"},
-#endif
-#if wxCHECK_VERSION(2,8,5)
+#endif
+#if wxCHECK_VERSION(2,8,5)
{wxEVT_COMMAND_AUINOTEBOOK_PAGE_CLOSED, 220, "command_auinotebook_page_closed"},
-#endif
-#if wxCHECK_VERSION(2,8,5)
+#endif
+#if wxCHECK_VERSION(2,8,5)
{wxEVT_COMMAND_AUINOTEBOOK_DRAG_DONE, 220, "command_auinotebook_drag_done"},
-#endif
-#if wxCHECK_VERSION(2,8,5)
+#endif
+#if wxCHECK_VERSION(2,8,5)
{wxEVT_COMMAND_AUINOTEBOOK_BG_DCLICK, 220, "command_auinotebook_bg_dclick"},
-#endif
+#endif
{wxEVT_AUI_PANE_BUTTON, 221, "aui_pane_button"},
{wxEVT_AUI_PANE_CLOSE, 221, "aui_pane_close"},
{wxEVT_AUI_PANE_MAXIMIZE, 221, "aui_pane_maximize"},
@@ -305,7 +305,7 @@ void initEventTable()
};
for(int i=0; event_types[i].ev_type != -1; i++) {
if(NULL == etmap[event_types[i].ev_type]) {
- etmap[event_types[i].ev_type] =
+ etmap[event_types[i].ev_type] =
new wxeEtype(event_types[i].ev_name, event_types[i].class_id);
} else {
wxeEtype *prev = etmap[event_types[i].ev_type];
@@ -319,21 +319,21 @@ void initEventTable()
}
}
-void wxeEvtListener::forward(wxEvent& event)
-{
+void wxeEvtListener::forward(wxEvent& event)
+{
#ifdef DEBUG
- if(!sendevent(&event, port))
+ if(!sendevent(&event, port))
fprintf(stderr, "Couldn't send event!\r\n");
#else
sendevent(&event, port);
#endif
}
-int getRef(void* ptr, wxeMemEnv* memenv)
-{
+int getRef(void* ptr, wxeMemEnv* memenv)
+{
WxeApp * app = (WxeApp *) wxTheApp;
return app->getRef(ptr,memenv);
-}
+}
bool sendevent(wxEvent *event, ErlDrvPort port)
{
@@ -740,8 +740,8 @@ case 208: {// wxTreeEvent
evClass = (char*)"wxTreeEvent";
rt.addAtom((char*)"wxTree");
rt.addAtom(Etype->eName);
- rt.addRef(getRef((void *)ev->GetItem().m_pItem,memenv), "wxTreeItemId");
- rt.addRef(getRef((void *)ev->GetOldItem().m_pItem,memenv), "wxTreeItemId");
+ rt.add((wxUIntPtr *) ev->GetItem().m_pItem);
+ rt.add((wxUIntPtr *) ev->GetOldItem().m_pItem);
rt.add(ev->GetPoint());
rt.addTupleCount(5);
break;
diff --git a/lib/wx/c_src/gen/wxe_funcs.cpp b/lib/wx/c_src/gen/wxe_funcs.cpp
index cb662fc91b..c8549d0716 100644
--- a/lib/wx/c_src/gen/wxe_funcs.cpp
+++ b/lib/wx/c_src/gen/wxe_funcs.cpp
@@ -1,23 +1,23 @@
/*
* %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%
*/
-/***** This file is generated do not edit ****/
+/***** This file is generated do not edit ****/
#include <wx/wx.h>
#include "../wxe_impl.h"
@@ -28,16 +28,16 @@
void WxeApp::wxe_dispatch(wxeCommand& Ecmd)
{
- char * bp = Ecmd.buffer;
+ char * bp = Ecmd.buffer;
wxeMemEnv *memenv = getMemEnv(Ecmd.port);
wxeReturn rt = wxeReturn(WXE_DRV_PORT, Ecmd.caller, true);
- try {
- switch (Ecmd.op)
+ try {
+ switch (Ecmd.op)
{
- case DESTROY_OBJECT: {
+ case DESTROY_OBJECT: {
wxObject *This = (wxObject *) getPtr(bp,memenv); if(This) { ((WxeApp *) wxTheApp)->clearPtr((void *) This);
delete This; }
- } break;
+ } break;
case WXE_REGISTER_OBJECT: {
registerPid(bp, Ecmd.caller, memenv);
rt.addAtom("ok");
@@ -110,19 +110,19 @@ case 101: { // wxEvtHandler::Disconnect
break;
}
-case wxWindow_new_0: { // wxWindow::wxWindow
+case wxWindow_new_0: { // wxWindow::wxWindow
wxWindow * Result = new EwxWindow();
newPtr((void *) Result, 0, memenv);
rt.addRef(getRef((void *)Result,memenv), "wxWindow");
- break;
+ break;
}
-case wxWindow_new_3: { // wxWindow::wxWindow
+case wxWindow_new_3: { // wxWindow::wxWindow
wxPoint pos= wxDefaultPosition;
wxSize size= wxDefaultSize;
long style=0;
wxWindow *parent = (wxWindow *) getPtr(bp,memenv); bp += 4;
int * id = (int *) bp; bp += 4;
- while( * (int*) bp) { switch (* (int*) bp) {
+ while( * (int*) bp) { switch (* (int*) bp) {
case 1: {bp += 4;
int * posX = (int *) bp; bp += 4;
int * posY = (int *) bp; bp += 4;
@@ -138,86 +138,86 @@ case wxWindow_new_3: { // wxWindow::wxWindow
case 3: {bp += 4;
style = (long)*(int *) bp; bp += 4;
} break;
- }};
+ }};
wxWindow * Result = new EwxWindow(parent,(wxWindowID) *id,pos,size,style);
newPtr((void *) Result, 0, memenv);
rt.addRef(getRef((void *)Result,memenv), "wxWindow");
- break;
+ break;
}
-case wxWindow_CacheBestSize: { // wxWindow::CacheBestSize
+case wxWindow_CacheBestSize: { // wxWindow::CacheBestSize
wxWindow *This = (wxWindow *) getPtr(bp,memenv); bp += 4;
int * sizeW = (int *) bp; bp += 4;
int * sizeH = (int *) bp; bp += 4;
wxSize size = wxSize(*sizeW,*sizeH);
if(!This) throw wxe_badarg(0);
This->CacheBestSize(size);
- break;
+ break;
}
-case wxWindow_CaptureMouse: { // wxWindow::CaptureMouse
+case wxWindow_CaptureMouse: { // wxWindow::CaptureMouse
wxWindow *This = (wxWindow *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
This->CaptureMouse();
- break;
+ break;
}
-case wxWindow_Center: { // wxWindow::Center
+case wxWindow_Center: { // wxWindow::Center
int dir=wxBOTH;
wxWindow *This = (wxWindow *) getPtr(bp,memenv); bp += 4;
bp += 4; /* Align */
- while( * (int*) bp) { switch (* (int*) bp) {
+ while( * (int*) bp) { switch (* (int*) bp) {
case 1: {bp += 4;
dir = (int)*(int *) bp; bp += 4;
} break;
- }};
+ }};
if(!This) throw wxe_badarg(0);
This->Center(dir);
- break;
+ break;
}
-case wxWindow_CenterOnParent: { // wxWindow::CenterOnParent
+case wxWindow_CenterOnParent: { // wxWindow::CenterOnParent
int dir=wxBOTH;
wxWindow *This = (wxWindow *) getPtr(bp,memenv); bp += 4;
bp += 4; /* Align */
- while( * (int*) bp) { switch (* (int*) bp) {
+ while( * (int*) bp) { switch (* (int*) bp) {
case 1: {bp += 4;
dir = (int)*(int *) bp; bp += 4;
} break;
- }};
+ }};
if(!This) throw wxe_badarg(0);
This->CenterOnParent(dir);
- break;
+ break;
}
-case wxWindow_Centre: { // wxWindow::Centre
+case wxWindow_Centre: { // wxWindow::Centre
int dir=wxBOTH;
wxWindow *This = (wxWindow *) getPtr(bp,memenv); bp += 4;
bp += 4; /* Align */
- while( * (int*) bp) { switch (* (int*) bp) {
+ while( * (int*) bp) { switch (* (int*) bp) {
case 1: {bp += 4;
dir = (int)*(int *) bp; bp += 4;
} break;
- }};
+ }};
if(!This) throw wxe_badarg(0);
This->Centre(dir);
- break;
+ break;
}
-case wxWindow_CentreOnParent: { // wxWindow::CentreOnParent
+case wxWindow_CentreOnParent: { // wxWindow::CentreOnParent
int dir=wxBOTH;
wxWindow *This = (wxWindow *) getPtr(bp,memenv); bp += 4;
bp += 4; /* Align */
- while( * (int*) bp) { switch (* (int*) bp) {
+ while( * (int*) bp) { switch (* (int*) bp) {
case 1: {bp += 4;
dir = (int)*(int *) bp; bp += 4;
} break;
- }};
+ }};
if(!This) throw wxe_badarg(0);
This->CentreOnParent(dir);
- break;
+ break;
}
-case wxWindow_ClearBackground: { // wxWindow::ClearBackground
+case wxWindow_ClearBackground: { // wxWindow::ClearBackground
wxWindow *This = (wxWindow *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
This->ClearBackground();
- break;
+ break;
}
-case wxWindow_ClientToScreen_2: { // wxWindow::ClientToScreen
+case wxWindow_ClientToScreen_2: { // wxWindow::ClientToScreen
wxWindow *This = (wxWindow *) getPtr(bp,memenv); bp += 4;
int * x = (int *) bp; bp += 4;
int * y = (int *) bp; bp += 4;
@@ -226,9 +226,9 @@ case wxWindow_ClientToScreen_2: { // wxWindow::ClientToScreen
rt.addInt(*x);
rt.addInt(*y);
rt.addTupleCount(2);
- break;
+ break;
}
-case wxWindow_ClientToScreen_1: { // wxWindow::ClientToScreen
+case wxWindow_ClientToScreen_1: { // wxWindow::ClientToScreen
wxWindow *This = (wxWindow *) getPtr(bp,memenv); bp += 4;
int * ptX = (int *) bp; bp += 4;
int * ptY = (int *) bp; bp += 4;
@@ -236,23 +236,23 @@ case wxWindow_ClientToScreen_1: { // wxWindow::ClientToScreen
if(!This) throw wxe_badarg(0);
wxPoint Result = This->ClientToScreen(pt);
rt.add(Result);
- break;
+ break;
}
-case wxWindow_Close: { // wxWindow::Close
+case wxWindow_Close: { // wxWindow::Close
bool force=false;
wxWindow *This = (wxWindow *) getPtr(bp,memenv); bp += 4;
bp += 4; /* Align */
- while( * (int*) bp) { switch (* (int*) bp) {
+ while( * (int*) bp) { switch (* (int*) bp) {
case 1: {bp += 4;
force = *(bool *) bp; bp += 4;
} break;
- }};
+ }};
if(!This) throw wxe_badarg(0);
bool Result = This->Close(force);
rt.addBool(Result);
- break;
+ break;
}
-case wxWindow_ConvertDialogToPixels: { // wxWindow::ConvertDialogToPixels
+case wxWindow_ConvertDialogToPixels: { // wxWindow::ConvertDialogToPixels
wxWindow *This = (wxWindow *) getPtr(bp,memenv); bp += 4;
int * szW = (int *) bp; bp += 4;
int * szH = (int *) bp; bp += 4;
@@ -260,9 +260,9 @@ case wxWindow_ConvertDialogToPixels: { // wxWindow::ConvertDialogToPixels
if(!This) throw wxe_badarg(0);
wxSize Result = This->ConvertDialogToPixels(sz);
rt.add(Result);
- break;
+ break;
}
-case wxWindow_ConvertPixelsToDialog: { // wxWindow::ConvertPixelsToDialog
+case wxWindow_ConvertPixelsToDialog: { // wxWindow::ConvertPixelsToDialog
wxWindow *This = (wxWindow *) getPtr(bp,memenv); bp += 4;
int * szW = (int *) bp; bp += 4;
int * szH = (int *) bp; bp += 4;
@@ -270,57 +270,57 @@ case wxWindow_ConvertPixelsToDialog: { // wxWindow::ConvertPixelsToDialog
if(!This) throw wxe_badarg(0);
wxSize Result = This->ConvertPixelsToDialog(sz);
rt.add(Result);
- break;
+ break;
}
-case wxWindow_Destroy: { // wxWindow::Destroy
+case wxWindow_Destroy: { // wxWindow::Destroy
wxWindow *This = (wxWindow *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
bool Result = This->Destroy();
rt.addBool(Result);
- break;
+ break;
}
-case wxWindow_DestroyChildren: { // wxWindow::DestroyChildren
+case wxWindow_DestroyChildren: { // wxWindow::DestroyChildren
wxWindow *This = (wxWindow *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
bool Result = This->DestroyChildren();
rt.addBool(Result);
- break;
+ break;
}
-case wxWindow_Disable: { // wxWindow::Disable
+case wxWindow_Disable: { // wxWindow::Disable
wxWindow *This = (wxWindow *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
bool Result = This->Disable();
rt.addBool(Result);
- break;
+ break;
}
-case wxWindow_Enable: { // wxWindow::Enable
+case wxWindow_Enable: { // wxWindow::Enable
bool enable=true;
wxWindow *This = (wxWindow *) getPtr(bp,memenv); bp += 4;
bp += 4; /* Align */
- while( * (int*) bp) { switch (* (int*) bp) {
+ while( * (int*) bp) { switch (* (int*) bp) {
case 1: {bp += 4;
enable = *(bool *) bp; bp += 4;
} break;
- }};
+ }};
if(!This) throw wxe_badarg(0);
bool Result = This->Enable(enable);
rt.addBool(Result);
- break;
+ break;
}
-case wxWindow_FindFocus: { // wxWindow::FindFocus
+case wxWindow_FindFocus: { // wxWindow::FindFocus
wxWindow * Result = (wxWindow*)wxWindow::FindFocus();
rt.addRef(getRef((void *)Result,memenv), "wxWindow");
- break;
+ break;
}
-case wxWindow_FindWindow_1_0: { // wxWindow::FindWindow
+case wxWindow_FindWindow_1_0: { // wxWindow::FindWindow
wxWindow *This = (wxWindow *) getPtr(bp,memenv); bp += 4;
int * winid = (int *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
wxWindow * Result = (wxWindow*)This->FindWindow((long) *winid);
rt.addRef(getRef((void *)Result,memenv), "wxWindow");
- break;
+ break;
}
-case wxWindow_FindWindow_1_1: { // wxWindow::FindWindow
+case wxWindow_FindWindow_1_1: { // wxWindow::FindWindow
wxWindow *This = (wxWindow *) getPtr(bp,memenv); bp += 4;
int * nameLen = (int *) bp; bp += 4;
wxString name = wxString(bp, wxConvUTF8);
@@ -328,122 +328,122 @@ case wxWindow_FindWindow_1_1: { // wxWindow::FindWindow
if(!This) throw wxe_badarg(0);
wxWindow * Result = (wxWindow*)This->FindWindow(name);
rt.addRef(getRef((void *)Result,memenv), "wxWindow");
- break;
+ break;
}
-case wxWindow_FindWindowById: { // wxWindow::FindWindowById
+case wxWindow_FindWindowById: { // wxWindow::FindWindowById
const wxWindow * parent=NULL;
int * winid = (int *) bp; bp += 4;
bp += 4; /* Align */
- while( * (int*) bp) { switch (* (int*) bp) {
+ while( * (int*) bp) { switch (* (int*) bp) {
case 1: {bp += 4;
parent = (wxWindow *) getPtr(bp,memenv); bp += 4;
} break;
- }};
+ }};
wxWindow * Result = (wxWindow*)wxWindow::FindWindowById((long) *winid,parent);
rt.addRef(getRef((void *)Result,memenv), "wxWindow");
- break;
+ break;
}
-case wxWindow_FindWindowByName: { // wxWindow::FindWindowByName
+case wxWindow_FindWindowByName: { // wxWindow::FindWindowByName
const wxWindow * parent=NULL;
int * nameLen = (int *) bp; bp += 4;
wxString name = wxString(bp, wxConvUTF8);
bp += *nameLen+((8-((4+ *nameLen) & 7)) & 7);
- while( * (int*) bp) { switch (* (int*) bp) {
+ while( * (int*) bp) { switch (* (int*) bp) {
case 1: {bp += 4;
parent = (wxWindow *) getPtr(bp,memenv); bp += 4;
} break;
- }};
+ }};
wxWindow * Result = (wxWindow*)wxWindow::FindWindowByName(name,parent);
rt.addRef(getRef((void *)Result,memenv), "wxWindow");
- break;
+ break;
}
-case wxWindow_FindWindowByLabel: { // wxWindow::FindWindowByLabel
+case wxWindow_FindWindowByLabel: { // wxWindow::FindWindowByLabel
const wxWindow * parent=NULL;
int * labelLen = (int *) bp; bp += 4;
wxString label = wxString(bp, wxConvUTF8);
bp += *labelLen+((8-((4+ *labelLen) & 7)) & 7);
- while( * (int*) bp) { switch (* (int*) bp) {
+ while( * (int*) bp) { switch (* (int*) bp) {
case 1: {bp += 4;
parent = (wxWindow *) getPtr(bp,memenv); bp += 4;
} break;
- }};
+ }};
wxWindow * Result = (wxWindow*)wxWindow::FindWindowByLabel(label,parent);
rt.addRef(getRef((void *)Result,memenv), "wxWindow");
- break;
+ break;
}
-case wxWindow_Fit: { // wxWindow::Fit
+case wxWindow_Fit: { // wxWindow::Fit
wxWindow *This = (wxWindow *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
This->Fit();
- break;
+ break;
}
-case wxWindow_FitInside: { // wxWindow::FitInside
+case wxWindow_FitInside: { // wxWindow::FitInside
wxWindow *This = (wxWindow *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
This->FitInside();
- break;
+ break;
}
-case wxWindow_Freeze: { // wxWindow::Freeze
+case wxWindow_Freeze: { // wxWindow::Freeze
wxWindow *This = (wxWindow *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
This->Freeze();
- break;
+ break;
}
-case wxWindow_GetAcceleratorTable: { // wxWindow::GetAcceleratorTable
+case wxWindow_GetAcceleratorTable: { // wxWindow::GetAcceleratorTable
wxWindow *This = (wxWindow *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
wxAcceleratorTable * Result = (wxAcceleratorTable*)This->GetAcceleratorTable();
rt.addRef(getRef((void *)Result,memenv), "wxAcceleratorTable");
- break;
+ break;
}
-case wxWindow_GetBackgroundColour: { // wxWindow::GetBackgroundColour
+case wxWindow_GetBackgroundColour: { // wxWindow::GetBackgroundColour
wxWindow *This = (wxWindow *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
wxColour Result = This->GetBackgroundColour();
rt.add(Result);
- break;
+ break;
}
-case wxWindow_GetBackgroundStyle: { // wxWindow::GetBackgroundStyle
+case wxWindow_GetBackgroundStyle: { // wxWindow::GetBackgroundStyle
wxWindow *This = (wxWindow *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
int Result = This->GetBackgroundStyle();
rt.addInt(Result);
- break;
+ break;
}
-case wxWindow_GetBestSize: { // wxWindow::GetBestSize
+case wxWindow_GetBestSize: { // wxWindow::GetBestSize
wxWindow *This = (wxWindow *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
wxSize Result = This->GetBestSize();
rt.add(Result);
- break;
+ break;
}
-case wxWindow_GetCaret: { // wxWindow::GetCaret
+case wxWindow_GetCaret: { // wxWindow::GetCaret
wxWindow *This = (wxWindow *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
wxCaret * Result = (wxCaret*)This->GetCaret();
rt.addRef(getRef((void *)Result,memenv), "wxCaret");
- break;
+ break;
}
-case wxWindow_GetCapture: { // wxWindow::GetCapture
+case wxWindow_GetCapture: { // wxWindow::GetCapture
wxWindow * Result = (wxWindow*)wxWindow::GetCapture();
rt.addRef(getRef((void *)Result,memenv), "wxWindow");
- break;
+ break;
}
-case wxWindow_GetCharHeight: { // wxWindow::GetCharHeight
+case wxWindow_GetCharHeight: { // wxWindow::GetCharHeight
wxWindow *This = (wxWindow *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
int Result = This->GetCharHeight();
rt.addInt(Result);
- break;
+ break;
}
-case wxWindow_GetCharWidth: { // wxWindow::GetCharWidth
+case wxWindow_GetCharWidth: { // wxWindow::GetCharWidth
wxWindow *This = (wxWindow *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
int Result = This->GetCharWidth();
rt.addInt(Result);
- break;
+ break;
}
-case wxWindow_GetChildren: { // wxWindow::GetChildren
+case wxWindow_GetChildren: { // wxWindow::GetChildren
wxWindow *This = (wxWindow *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
const wxWindowList Result = This->GetChildren();
@@ -452,194 +452,194 @@ case wxWindow_GetChildren: { // wxWindow::GetChildren
wxWindow * ResultTmp = *it;
rt.addRef(getRef((void *)ResultTmp,memenv), "wxWindow"); i++;}
rt.endList(Result.GetCount());
- break;
+ break;
}
-case wxWindow_GetClientSize: { // wxWindow::GetClientSize
+case wxWindow_GetClientSize: { // wxWindow::GetClientSize
wxWindow *This = (wxWindow *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
wxSize Result = This->GetClientSize();
rt.add(Result);
- break;
+ break;
}
-case wxWindow_GetContainingSizer: { // wxWindow::GetContainingSizer
+case wxWindow_GetContainingSizer: { // wxWindow::GetContainingSizer
wxWindow *This = (wxWindow *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
wxSizer * Result = (wxSizer*)This->GetContainingSizer();
rt.addRef(getRef((void *)Result,memenv), "wxSizer");
- break;
+ break;
}
-case wxWindow_GetCursor: { // wxWindow::GetCursor
+case wxWindow_GetCursor: { // wxWindow::GetCursor
wxWindow *This = (wxWindow *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
const wxCursor * Result = &This->GetCursor();
rt.addRef(getRef((void *)Result,memenv), "wxCursor");
- break;
+ break;
}
-case wxWindow_GetDropTarget: { // wxWindow::GetDropTarget
+case wxWindow_GetDropTarget: { // wxWindow::GetDropTarget
wxWindow *This = (wxWindow *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
wxDropTarget * Result = (wxDropTarget*)This->GetDropTarget();
rt.addRef(getRef((void *)Result,memenv), "wxDropTarget");
- break;
+ break;
}
-case wxWindow_GetEventHandler: { // wxWindow::GetEventHandler
+case wxWindow_GetEventHandler: { // wxWindow::GetEventHandler
wxWindow *This = (wxWindow *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
wxEvtHandler * Result = (wxEvtHandler*)This->GetEventHandler();
rt.addRef(getRef((void *)Result,memenv), "wxEvtHandler");
- break;
+ break;
}
-case wxWindow_GetExtraStyle: { // wxWindow::GetExtraStyle
+case wxWindow_GetExtraStyle: { // wxWindow::GetExtraStyle
wxWindow *This = (wxWindow *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
long Result = This->GetExtraStyle();
rt.addInt(Result);
- break;
+ break;
}
-case wxWindow_GetFont: { // wxWindow::GetFont
+case wxWindow_GetFont: { // wxWindow::GetFont
wxWindow *This = (wxWindow *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
wxFont * Result = new wxFont(This->GetFont()); newPtr((void *) Result,3, memenv);;
rt.addRef(getRef((void *)Result,memenv), "wxFont");
- break;
+ break;
}
-case wxWindow_GetForegroundColour: { // wxWindow::GetForegroundColour
+case wxWindow_GetForegroundColour: { // wxWindow::GetForegroundColour
wxWindow *This = (wxWindow *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
wxColour Result = This->GetForegroundColour();
rt.add(Result);
- break;
+ break;
}
-case wxWindow_GetGrandParent: { // wxWindow::GetGrandParent
+case wxWindow_GetGrandParent: { // wxWindow::GetGrandParent
wxWindow *This = (wxWindow *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
wxWindow * Result = (wxWindow*)This->GetGrandParent();
rt.addRef(getRef((void *)Result,memenv), "wxWindow");
- break;
+ break;
}
-case wxWindow_GetHandle: { // wxWindow::GetHandle
+case wxWindow_GetHandle: { // wxWindow::GetHandle
wxWindow *This = (wxWindow *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
wxUIntPtr * Result = (wxUIntPtr*)This->GetHandle();
rt.add(Result);
- break;
+ break;
}
-case wxWindow_GetHelpText: { // wxWindow::GetHelpText
+case wxWindow_GetHelpText: { // wxWindow::GetHelpText
wxWindow *This = (wxWindow *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
wxString Result = This->GetHelpText();
rt.add(Result);
- break;
+ break;
}
-case wxWindow_GetId: { // wxWindow::GetId
+case wxWindow_GetId: { // wxWindow::GetId
wxWindow *This = (wxWindow *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
wxWindowID Result = This->GetId();
rt.addInt(Result);
- break;
+ break;
}
-case wxWindow_GetLabel: { // wxWindow::GetLabel
+case wxWindow_GetLabel: { // wxWindow::GetLabel
wxWindow *This = (wxWindow *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
wxString Result = This->GetLabel();
rt.add(Result);
- break;
+ break;
}
-case wxWindow_GetMaxSize: { // wxWindow::GetMaxSize
+case wxWindow_GetMaxSize: { // wxWindow::GetMaxSize
wxWindow *This = (wxWindow *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
wxSize Result = This->GetMaxSize();
rt.add(Result);
- break;
+ break;
}
-case wxWindow_GetMinSize: { // wxWindow::GetMinSize
+case wxWindow_GetMinSize: { // wxWindow::GetMinSize
wxWindow *This = (wxWindow *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
wxSize Result = This->GetMinSize();
rt.add(Result);
- break;
+ break;
}
-case wxWindow_GetName: { // wxWindow::GetName
+case wxWindow_GetName: { // wxWindow::GetName
wxWindow *This = (wxWindow *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
wxString Result = This->GetName();
rt.add(Result);
- break;
+ break;
}
-case wxWindow_GetParent: { // wxWindow::GetParent
+case wxWindow_GetParent: { // wxWindow::GetParent
wxWindow *This = (wxWindow *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
wxWindow * Result = (wxWindow*)This->GetParent();
rt.addRef(getRef((void *)Result,memenv), "wxWindow");
- break;
+ break;
}
-case wxWindow_GetPosition: { // wxWindow::GetPosition
+case wxWindow_GetPosition: { // wxWindow::GetPosition
wxWindow *This = (wxWindow *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
wxPoint Result = This->GetPosition();
rt.add(Result);
- break;
+ break;
}
-case wxWindow_GetRect: { // wxWindow::GetRect
+case wxWindow_GetRect: { // wxWindow::GetRect
wxWindow *This = (wxWindow *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
wxRect Result = This->GetRect();
rt.add(Result);
- break;
+ break;
}
-case wxWindow_GetScreenPosition: { // wxWindow::GetScreenPosition
+case wxWindow_GetScreenPosition: { // wxWindow::GetScreenPosition
wxWindow *This = (wxWindow *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
wxPoint Result = This->GetScreenPosition();
rt.add(Result);
- break;
+ break;
}
-case wxWindow_GetScreenRect: { // wxWindow::GetScreenRect
+case wxWindow_GetScreenRect: { // wxWindow::GetScreenRect
wxWindow *This = (wxWindow *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
wxRect Result = This->GetScreenRect();
rt.add(Result);
- break;
+ break;
}
-case wxWindow_GetScrollPos: { // wxWindow::GetScrollPos
+case wxWindow_GetScrollPos: { // wxWindow::GetScrollPos
wxWindow *This = (wxWindow *) getPtr(bp,memenv); bp += 4;
int * orient = (int *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
int Result = This->GetScrollPos((int) *orient);
rt.addInt(Result);
- break;
+ break;
}
-case wxWindow_GetScrollRange: { // wxWindow::GetScrollRange
+case wxWindow_GetScrollRange: { // wxWindow::GetScrollRange
wxWindow *This = (wxWindow *) getPtr(bp,memenv); bp += 4;
int * orient = (int *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
int Result = This->GetScrollRange((int) *orient);
rt.addInt(Result);
- break;
+ break;
}
-case wxWindow_GetScrollThumb: { // wxWindow::GetScrollThumb
+case wxWindow_GetScrollThumb: { // wxWindow::GetScrollThumb
wxWindow *This = (wxWindow *) getPtr(bp,memenv); bp += 4;
int * orient = (int *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
int Result = This->GetScrollThumb((int) *orient);
rt.addInt(Result);
- break;
+ break;
}
-case wxWindow_GetSize: { // wxWindow::GetSize
+case wxWindow_GetSize: { // wxWindow::GetSize
wxWindow *This = (wxWindow *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
wxSize Result = This->GetSize();
rt.add(Result);
- break;
+ break;
}
-case wxWindow_GetSizer: { // wxWindow::GetSizer
+case wxWindow_GetSizer: { // wxWindow::GetSizer
wxWindow *This = (wxWindow *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
wxSizer * Result = (wxSizer*)This->GetSizer();
rt.addRef(getRef((void *)Result,memenv), "wxSizer");
- break;
+ break;
}
-case wxWindow_GetTextExtent: { // wxWindow::GetTextExtent
+case wxWindow_GetTextExtent: { // wxWindow::GetTextExtent
int x;
int y;
int descent;
@@ -649,11 +649,11 @@ case wxWindow_GetTextExtent: { // wxWindow::GetTextExtent
int * stringLen = (int *) bp; bp += 4;
wxString string = wxString(bp, wxConvUTF8);
bp += *stringLen+((8-((0+ *stringLen) & 7)) & 7);
- while( * (int*) bp) { switch (* (int*) bp) {
+ while( * (int*) bp) { switch (* (int*) bp) {
case 1: {bp += 4;
theFont = (wxFont *) getPtr(bp,memenv); bp += 4;
} break;
- }};
+ }};
if(!This) throw wxe_badarg(0);
This->GetTextExtent(string,&x,&y,&descent,&externalLeading,theFont);
rt.addInt(x);
@@ -661,107 +661,107 @@ theFont = (wxFont *) getPtr(bp,memenv); bp += 4;
rt.addInt(descent);
rt.addInt(externalLeading);
rt.addTupleCount(4);
- break;
+ break;
}
-case wxWindow_GetToolTip: { // wxWindow::GetToolTip
+case wxWindow_GetToolTip: { // wxWindow::GetToolTip
wxWindow *This = (wxWindow *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
wxToolTip * Result = (wxToolTip*)This->GetToolTip();
rt.addRef(getRef((void *)Result,memenv), "wxToolTip");
- break;
+ break;
}
-case wxWindow_GetUpdateRegion: { // wxWindow::GetUpdateRegion
+case wxWindow_GetUpdateRegion: { // wxWindow::GetUpdateRegion
wxWindow *This = (wxWindow *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
const wxRegion * Result = &This->GetUpdateRegion();
rt.addRef(getRef((void *)Result,memenv), "wxRegion");
- break;
+ break;
}
-case wxWindow_GetVirtualSize: { // wxWindow::GetVirtualSize
+case wxWindow_GetVirtualSize: { // wxWindow::GetVirtualSize
wxWindow *This = (wxWindow *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
wxSize Result = This->GetVirtualSize();
rt.add(Result);
- break;
+ break;
}
-case wxWindow_GetWindowStyleFlag: { // wxWindow::GetWindowStyleFlag
+case wxWindow_GetWindowStyleFlag: { // wxWindow::GetWindowStyleFlag
wxWindow *This = (wxWindow *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
long Result = This->GetWindowStyleFlag();
rt.addInt(Result);
- break;
+ break;
}
-case wxWindow_GetWindowVariant: { // wxWindow::GetWindowVariant
+case wxWindow_GetWindowVariant: { // wxWindow::GetWindowVariant
wxWindow *This = (wxWindow *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
int Result = This->GetWindowVariant();
rt.addInt(Result);
- break;
+ break;
}
-case wxWindow_HasCapture: { // wxWindow::HasCapture
+case wxWindow_HasCapture: { // wxWindow::HasCapture
wxWindow *This = (wxWindow *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
bool Result = This->HasCapture();
rt.addBool(Result);
- break;
+ break;
}
-case wxWindow_HasScrollbar: { // wxWindow::HasScrollbar
+case wxWindow_HasScrollbar: { // wxWindow::HasScrollbar
wxWindow *This = (wxWindow *) getPtr(bp,memenv); bp += 4;
int * orient = (int *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
bool Result = This->HasScrollbar((int) *orient);
rt.addBool(Result);
- break;
+ break;
}
-case wxWindow_HasTransparentBackground: { // wxWindow::HasTransparentBackground
+case wxWindow_HasTransparentBackground: { // wxWindow::HasTransparentBackground
wxWindow *This = (wxWindow *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
bool Result = This->HasTransparentBackground();
rt.addBool(Result);
- break;
+ break;
}
-case wxWindow_Hide: { // wxWindow::Hide
+case wxWindow_Hide: { // wxWindow::Hide
wxWindow *This = (wxWindow *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
bool Result = This->Hide();
rt.addBool(Result);
- break;
+ break;
}
-case wxWindow_InheritAttributes: { // wxWindow::InheritAttributes
+case wxWindow_InheritAttributes: { // wxWindow::InheritAttributes
wxWindow *This = (wxWindow *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
This->InheritAttributes();
- break;
+ break;
}
-case wxWindow_InitDialog: { // wxWindow::InitDialog
+case wxWindow_InitDialog: { // wxWindow::InitDialog
wxWindow *This = (wxWindow *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
This->InitDialog();
- break;
+ break;
}
-case wxWindow_InvalidateBestSize: { // wxWindow::InvalidateBestSize
+case wxWindow_InvalidateBestSize: { // wxWindow::InvalidateBestSize
wxWindow *This = (wxWindow *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
This->InvalidateBestSize();
- break;
+ break;
}
-case wxWindow_IsEnabled: { // wxWindow::IsEnabled
+case wxWindow_IsEnabled: { // wxWindow::IsEnabled
wxWindow *This = (wxWindow *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
bool Result = This->IsEnabled();
rt.addBool(Result);
- break;
+ break;
}
-case wxWindow_IsExposed_2: { // wxWindow::IsExposed
+case wxWindow_IsExposed_2: { // wxWindow::IsExposed
wxWindow *This = (wxWindow *) getPtr(bp,memenv); bp += 4;
int * x = (int *) bp; bp += 4;
int * y = (int *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
bool Result = This->IsExposed((int) *x,(int) *y);
rt.addBool(Result);
- break;
+ break;
}
-case wxWindow_IsExposed_4: { // wxWindow::IsExposed
+case wxWindow_IsExposed_4: { // wxWindow::IsExposed
wxWindow *This = (wxWindow *) getPtr(bp,memenv); bp += 4;
int * x = (int *) bp; bp += 4;
int * y = (int *) bp; bp += 4;
@@ -770,9 +770,9 @@ case wxWindow_IsExposed_4: { // wxWindow::IsExposed
if(!This) throw wxe_badarg(0);
bool Result = This->IsExposed((int) *x,(int) *y,(int) *w,(int) *h);
rt.addBool(Result);
- break;
+ break;
}
-case wxWindow_IsExposed_1_0: { // wxWindow::IsExposed
+case wxWindow_IsExposed_1_0: { // wxWindow::IsExposed
wxWindow *This = (wxWindow *) getPtr(bp,memenv); bp += 4;
int * ptX = (int *) bp; bp += 4;
int * ptY = (int *) bp; bp += 4;
@@ -780,9 +780,9 @@ case wxWindow_IsExposed_1_0: { // wxWindow::IsExposed
if(!This) throw wxe_badarg(0);
bool Result = This->IsExposed(pt);
rt.addBool(Result);
- break;
+ break;
}
-case wxWindow_IsExposed_1_1: { // wxWindow::IsExposed
+case wxWindow_IsExposed_1_1: { // wxWindow::IsExposed
wxWindow *This = (wxWindow *) getPtr(bp,memenv); bp += 4;
int * rectX = (int *) bp; bp += 4;
int * rectY = (int *) bp; bp += 4;
@@ -792,174 +792,174 @@ case wxWindow_IsExposed_1_1: { // wxWindow::IsExposed
if(!This) throw wxe_badarg(0);
bool Result = This->IsExposed(rect);
rt.addBool(Result);
- break;
+ break;
}
-case wxWindow_IsRetained: { // wxWindow::IsRetained
+case wxWindow_IsRetained: { // wxWindow::IsRetained
wxWindow *This = (wxWindow *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
bool Result = This->IsRetained();
rt.addBool(Result);
- break;
+ break;
}
-case wxWindow_IsShown: { // wxWindow::IsShown
+case wxWindow_IsShown: { // wxWindow::IsShown
wxWindow *This = (wxWindow *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
bool Result = This->IsShown();
rt.addBool(Result);
- break;
+ break;
}
-case wxWindow_IsTopLevel: { // wxWindow::IsTopLevel
+case wxWindow_IsTopLevel: { // wxWindow::IsTopLevel
wxWindow *This = (wxWindow *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
bool Result = This->IsTopLevel();
rt.addBool(Result);
- break;
+ break;
}
-case wxWindow_Layout: { // wxWindow::Layout
+case wxWindow_Layout: { // wxWindow::Layout
wxWindow *This = (wxWindow *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
bool Result = This->Layout();
rt.addBool(Result);
- break;
+ break;
}
-case wxWindow_LineDown: { // wxWindow::LineDown
+case wxWindow_LineDown: { // wxWindow::LineDown
wxWindow *This = (wxWindow *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
bool Result = This->LineDown();
rt.addBool(Result);
- break;
+ break;
}
-case wxWindow_LineUp: { // wxWindow::LineUp
+case wxWindow_LineUp: { // wxWindow::LineUp
wxWindow *This = (wxWindow *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
bool Result = This->LineUp();
rt.addBool(Result);
- break;
+ break;
}
-case wxWindow_Lower: { // wxWindow::Lower
+case wxWindow_Lower: { // wxWindow::Lower
wxWindow *This = (wxWindow *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
This->Lower();
- break;
+ break;
}
-case wxWindow_MakeModal: { // wxWindow::MakeModal
+case wxWindow_MakeModal: { // wxWindow::MakeModal
bool modal=true;
wxWindow *This = (wxWindow *) getPtr(bp,memenv); bp += 4;
bp += 4; /* Align */
- while( * (int*) bp) { switch (* (int*) bp) {
+ while( * (int*) bp) { switch (* (int*) bp) {
case 1: {bp += 4;
modal = *(bool *) bp; bp += 4;
} break;
- }};
+ }};
if(!This) throw wxe_badarg(0);
This->MakeModal(modal);
- break;
+ break;
}
-case wxWindow_Move_3: { // wxWindow::Move
+case wxWindow_Move_3: { // wxWindow::Move
int flags=wxSIZE_USE_EXISTING;
wxWindow *This = (wxWindow *) getPtr(bp,memenv); bp += 4;
int * x = (int *) bp; bp += 4;
int * y = (int *) bp; bp += 4;
bp += 4; /* Align */
- while( * (int*) bp) { switch (* (int*) bp) {
+ while( * (int*) bp) { switch (* (int*) bp) {
case 1: {bp += 4;
flags = (int)*(int *) bp; bp += 4;
} break;
- }};
+ }};
if(!This) throw wxe_badarg(0);
This->Move((int) *x,(int) *y,flags);
- break;
+ break;
}
-case wxWindow_Move_2: { // wxWindow::Move
+case wxWindow_Move_2: { // wxWindow::Move
int flags=wxSIZE_USE_EXISTING;
wxWindow *This = (wxWindow *) getPtr(bp,memenv); bp += 4;
int * ptX = (int *) bp; bp += 4;
int * ptY = (int *) bp; bp += 4;
wxPoint pt = wxPoint(*ptX,*ptY);
bp += 4; /* Align */
- while( * (int*) bp) { switch (* (int*) bp) {
+ while( * (int*) bp) { switch (* (int*) bp) {
case 1: {bp += 4;
flags = (int)*(int *) bp; bp += 4;
} break;
- }};
+ }};
if(!This) throw wxe_badarg(0);
This->Move(pt,flags);
- break;
+ break;
}
-case wxWindow_MoveAfterInTabOrder: { // wxWindow::MoveAfterInTabOrder
+case wxWindow_MoveAfterInTabOrder: { // wxWindow::MoveAfterInTabOrder
wxWindow *This = (wxWindow *) getPtr(bp,memenv); bp += 4;
wxWindow *win = (wxWindow *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
This->MoveAfterInTabOrder(win);
- break;
+ break;
}
-case wxWindow_MoveBeforeInTabOrder: { // wxWindow::MoveBeforeInTabOrder
+case wxWindow_MoveBeforeInTabOrder: { // wxWindow::MoveBeforeInTabOrder
wxWindow *This = (wxWindow *) getPtr(bp,memenv); bp += 4;
wxWindow *win = (wxWindow *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
This->MoveBeforeInTabOrder(win);
- break;
+ break;
}
-case wxWindow_Navigate: { // wxWindow::Navigate
+case wxWindow_Navigate: { // wxWindow::Navigate
int flags=wxNavigationKeyEvent::IsForward;
wxWindow *This = (wxWindow *) getPtr(bp,memenv); bp += 4;
bp += 4; /* Align */
- while( * (int*) bp) { switch (* (int*) bp) {
+ while( * (int*) bp) { switch (* (int*) bp) {
case 1: {bp += 4;
flags = (int)*(int *) bp; bp += 4;
} break;
- }};
+ }};
if(!This) throw wxe_badarg(0);
bool Result = This->Navigate(flags);
rt.addBool(Result);
- break;
+ break;
}
-case wxWindow_PageDown: { // wxWindow::PageDown
+case wxWindow_PageDown: { // wxWindow::PageDown
wxWindow *This = (wxWindow *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
bool Result = This->PageDown();
rt.addBool(Result);
- break;
+ break;
}
-case wxWindow_PageUp: { // wxWindow::PageUp
+case wxWindow_PageUp: { // wxWindow::PageUp
wxWindow *This = (wxWindow *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
bool Result = This->PageUp();
rt.addBool(Result);
- break;
+ break;
}
-case wxWindow_PopEventHandler: { // wxWindow::PopEventHandler
+case wxWindow_PopEventHandler: { // wxWindow::PopEventHandler
bool deleteHandler=false;
wxWindow *This = (wxWindow *) getPtr(bp,memenv); bp += 4;
bp += 4; /* Align */
- while( * (int*) bp) { switch (* (int*) bp) {
+ while( * (int*) bp) { switch (* (int*) bp) {
case 1: {bp += 4;
deleteHandler = *(bool *) bp; bp += 4;
} break;
- }};
+ }};
if(!This) throw wxe_badarg(0);
wxEvtHandler * Result = (wxEvtHandler*)This->PopEventHandler(deleteHandler);
rt.addRef(getRef((void *)Result,memenv), "wxEvtHandler");
- break;
+ break;
}
-case wxWindow_PopupMenu_2: { // wxWindow::PopupMenu
+case wxWindow_PopupMenu_2: { // wxWindow::PopupMenu
wxPoint pos= wxDefaultPosition;
wxWindow *This = (wxWindow *) getPtr(bp,memenv); bp += 4;
wxMenu *menu = (wxMenu *) getPtr(bp,memenv); bp += 4;
- while( * (int*) bp) { switch (* (int*) bp) {
+ while( * (int*) bp) { switch (* (int*) bp) {
case 1: {bp += 4;
int * posX = (int *) bp; bp += 4;
int * posY = (int *) bp; bp += 4;
pos = wxPoint(*posX,*posY);
bp += 4; /* Align */
} break;
- }};
+ }};
if(!This) throw wxe_badarg(0);
bool Result = This->PopupMenu(menu,pos);
rt.addBool(Result);
- break;
+ break;
}
-case wxWindow_PopupMenu_3: { // wxWindow::PopupMenu
+case wxWindow_PopupMenu_3: { // wxWindow::PopupMenu
wxWindow *This = (wxWindow *) getPtr(bp,memenv); bp += 4;
wxMenu *menu = (wxMenu *) getPtr(bp,memenv); bp += 4;
int * x = (int *) bp; bp += 4;
@@ -967,20 +967,20 @@ case wxWindow_PopupMenu_3: { // wxWindow::PopupMenu
if(!This) throw wxe_badarg(0);
bool Result = This->PopupMenu(menu,(int) *x,(int) *y);
rt.addBool(Result);
- break;
+ break;
}
-case wxWindow_Raise: { // wxWindow::Raise
+case wxWindow_Raise: { // wxWindow::Raise
wxWindow *This = (wxWindow *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
This->Raise();
- break;
+ break;
}
-case wxWindow_Refresh: { // wxWindow::Refresh
+case wxWindow_Refresh: { // wxWindow::Refresh
bool eraseBackground=true;
const wxRect *rect=(const wxRect *) NULL; wxRect rectTmp;
wxWindow *This = (wxWindow *) getPtr(bp,memenv); bp += 4;
bp += 4; /* Align */
- while( * (int*) bp) { switch (* (int*) bp) {
+ while( * (int*) bp) { switch (* (int*) bp) {
case 1: {bp += 4;
eraseBackground = *(bool *) bp; bp += 4;
} break;
@@ -992,12 +992,12 @@ case wxWindow_Refresh: { // wxWindow::Refresh
rectTmp = wxRect(*rectX,*rectY,*rectW,*rectH); rect = & rectTmp;
bp += 4; /* Align */
} break;
- }};
+ }};
if(!This) throw wxe_badarg(0);
This->Refresh(eraseBackground,rect);
- break;
+ break;
}
-case wxWindow_RefreshRect: { // wxWindow::RefreshRect
+case wxWindow_RefreshRect: { // wxWindow::RefreshRect
bool eraseBackground=true;
wxWindow *This = (wxWindow *) getPtr(bp,memenv); bp += 4;
int * rectX = (int *) bp; bp += 4;
@@ -1006,37 +1006,37 @@ case wxWindow_RefreshRect: { // wxWindow::RefreshRect
int * rectH = (int *) bp; bp += 4;
wxRect rect = wxRect(*rectX,*rectY,*rectW,*rectH);
bp += 4; /* Align */
- while( * (int*) bp) { switch (* (int*) bp) {
+ while( * (int*) bp) { switch (* (int*) bp) {
case 1: {bp += 4;
eraseBackground = *(bool *) bp; bp += 4;
} break;
- }};
+ }};
if(!This) throw wxe_badarg(0);
This->RefreshRect(rect,eraseBackground);
- break;
+ break;
}
-case wxWindow_ReleaseMouse: { // wxWindow::ReleaseMouse
+case wxWindow_ReleaseMouse: { // wxWindow::ReleaseMouse
wxWindow *This = (wxWindow *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
This->ReleaseMouse();
- break;
+ break;
}
-case wxWindow_RemoveChild: { // wxWindow::RemoveChild
+case wxWindow_RemoveChild: { // wxWindow::RemoveChild
wxWindow *This = (wxWindow *) getPtr(bp,memenv); bp += 4;
wxWindow *child = (wxWindow *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
This->RemoveChild(child);
- break;
+ break;
}
-case wxWindow_Reparent: { // wxWindow::Reparent
+case wxWindow_Reparent: { // wxWindow::Reparent
wxWindow *This = (wxWindow *) getPtr(bp,memenv); bp += 4;
wxWindow *newParent = (wxWindow *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
bool Result = This->Reparent(newParent);
rt.addBool(Result);
- break;
+ break;
}
-case wxWindow_ScreenToClient_2: { // wxWindow::ScreenToClient
+case wxWindow_ScreenToClient_2: { // wxWindow::ScreenToClient
int x;
int y;
wxWindow *This = (wxWindow *) getPtr(bp,memenv); bp += 4;
@@ -1045,9 +1045,9 @@ case wxWindow_ScreenToClient_2: { // wxWindow::ScreenToClient
rt.addInt(x);
rt.addInt(y);
rt.addTupleCount(2);
- break;
+ break;
}
-case wxWindow_ScreenToClient_1: { // wxWindow::ScreenToClient
+case wxWindow_ScreenToClient_1: { // wxWindow::ScreenToClient
wxWindow *This = (wxWindow *) getPtr(bp,memenv); bp += 4;
int * ptX = (int *) bp; bp += 4;
int * ptY = (int *) bp; bp += 4;
@@ -1055,31 +1055,31 @@ case wxWindow_ScreenToClient_1: { // wxWindow::ScreenToClient
if(!This) throw wxe_badarg(0);
wxPoint Result = This->ScreenToClient(pt);
rt.add(Result);
- break;
+ break;
}
-case wxWindow_ScrollLines: { // wxWindow::ScrollLines
+case wxWindow_ScrollLines: { // wxWindow::ScrollLines
wxWindow *This = (wxWindow *) getPtr(bp,memenv); bp += 4;
int * lines = (int *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
bool Result = This->ScrollLines((int) *lines);
rt.addBool(Result);
- break;
+ break;
}
-case wxWindow_ScrollPages: { // wxWindow::ScrollPages
+case wxWindow_ScrollPages: { // wxWindow::ScrollPages
wxWindow *This = (wxWindow *) getPtr(bp,memenv); bp += 4;
int * pages = (int *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
bool Result = This->ScrollPages((int) *pages);
rt.addBool(Result);
- break;
+ break;
}
-case wxWindow_ScrollWindow: { // wxWindow::ScrollWindow
+case wxWindow_ScrollWindow: { // wxWindow::ScrollWindow
const wxRect *rect=(wxRect *) NULL; wxRect rectTmp;
wxWindow *This = (wxWindow *) getPtr(bp,memenv); bp += 4;
int * dx = (int *) bp; bp += 4;
int * dy = (int *) bp; bp += 4;
bp += 4; /* Align */
- while( * (int*) bp) { switch (* (int*) bp) {
+ while( * (int*) bp) { switch (* (int*) bp) {
case 1: {bp += 4;
int * rectX = (int *) bp; bp += 4;
int * rectY = (int *) bp; bp += 4;
@@ -1088,26 +1088,26 @@ case wxWindow_ScrollWindow: { // wxWindow::ScrollWindow
rectTmp = wxRect(*rectX,*rectY,*rectW,*rectH); rect = & rectTmp;
bp += 4; /* Align */
} break;
- }};
+ }};
if(!This) throw wxe_badarg(0);
This->ScrollWindow((int) *dx,(int) *dy,rect);
- break;
+ break;
}
-case wxWindow_SetAcceleratorTable: { // wxWindow::SetAcceleratorTable
+case wxWindow_SetAcceleratorTable: { // wxWindow::SetAcceleratorTable
wxWindow *This = (wxWindow *) getPtr(bp,memenv); bp += 4;
wxAcceleratorTable *accel = (wxAcceleratorTable *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
This->SetAcceleratorTable(*accel);
- break;
+ break;
}
-case wxWindow_SetAutoLayout: { // wxWindow::SetAutoLayout
+case wxWindow_SetAutoLayout: { // wxWindow::SetAutoLayout
wxWindow *This = (wxWindow *) getPtr(bp,memenv); bp += 4;
bool * autoLayout = (bool *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
This->SetAutoLayout((bool) *autoLayout);
- break;
+ break;
}
-case wxWindow_SetBackgroundColour: { // wxWindow::SetBackgroundColour
+case wxWindow_SetBackgroundColour: { // wxWindow::SetBackgroundColour
wxWindow *This = (wxWindow *) getPtr(bp,memenv); bp += 4;
int * colourR = (int *) bp; bp += 4;
int * colourG = (int *) bp; bp += 4;
@@ -1117,41 +1117,41 @@ case wxWindow_SetBackgroundColour: { // wxWindow::SetBackgroundColour
if(!This) throw wxe_badarg(0);
bool Result = This->SetBackgroundColour(colour);
rt.addBool(Result);
- break;
+ break;
}
-case wxWindow_SetBackgroundStyle: { // wxWindow::SetBackgroundStyle
+case wxWindow_SetBackgroundStyle: { // wxWindow::SetBackgroundStyle
wxWindow *This = (wxWindow *) getPtr(bp,memenv); bp += 4;
wxBackgroundStyle style = *(wxBackgroundStyle *) bp; bp += 4;;
if(!This) throw wxe_badarg(0);
bool Result = This->SetBackgroundStyle((wxBackgroundStyle) style);
rt.addBool(Result);
- break;
+ break;
}
-case wxWindow_SetCaret: { // wxWindow::SetCaret
+case wxWindow_SetCaret: { // wxWindow::SetCaret
wxWindow *This = (wxWindow *) getPtr(bp,memenv); bp += 4;
wxCaret *caret = (wxCaret *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
This->SetCaret(caret);
- break;
+ break;
}
-case wxWindow_SetClientSize_2: { // wxWindow::SetClientSize
+case wxWindow_SetClientSize_2: { // wxWindow::SetClientSize
wxWindow *This = (wxWindow *) getPtr(bp,memenv); bp += 4;
int * width = (int *) bp; bp += 4;
int * height = (int *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
This->SetClientSize((int) *width,(int) *height);
- break;
+ break;
}
-case wxWindow_SetClientSize_1_0: { // wxWindow::SetClientSize
+case wxWindow_SetClientSize_1_0: { // wxWindow::SetClientSize
wxWindow *This = (wxWindow *) getPtr(bp,memenv); bp += 4;
int * sizeW = (int *) bp; bp += 4;
int * sizeH = (int *) bp; bp += 4;
wxSize size = wxSize(*sizeW,*sizeH);
if(!This) throw wxe_badarg(0);
This->SetClientSize(size);
- break;
+ break;
}
-case wxWindow_SetClientSize_1_1: { // wxWindow::SetClientSize
+case wxWindow_SetClientSize_1_1: { // wxWindow::SetClientSize
wxWindow *This = (wxWindow *) getPtr(bp,memenv); bp += 4;
int * rectX = (int *) bp; bp += 4;
int * rectY = (int *) bp; bp += 4;
@@ -1160,42 +1160,42 @@ case wxWindow_SetClientSize_1_1: { // wxWindow::SetClientSize
wxRect rect = wxRect(*rectX,*rectY,*rectW,*rectH);
if(!This) throw wxe_badarg(0);
This->SetClientSize(rect);
- break;
+ break;
}
-case wxWindow_SetContainingSizer: { // wxWindow::SetContainingSizer
+case wxWindow_SetContainingSizer: { // wxWindow::SetContainingSizer
wxWindow *This = (wxWindow *) getPtr(bp,memenv); bp += 4;
wxSizer *sizer = (wxSizer *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
This->SetContainingSizer(sizer);
- break;
+ break;
}
-case wxWindow_SetCursor: { // wxWindow::SetCursor
+case wxWindow_SetCursor: { // wxWindow::SetCursor
wxWindow *This = (wxWindow *) getPtr(bp,memenv); bp += 4;
wxCursor *cursor = (wxCursor *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
bool Result = This->SetCursor(*cursor);
rt.addBool(Result);
- break;
+ break;
}
-case wxWindow_SetMaxSize: { // wxWindow::SetMaxSize
+case wxWindow_SetMaxSize: { // wxWindow::SetMaxSize
wxWindow *This = (wxWindow *) getPtr(bp,memenv); bp += 4;
int * maxSizeW = (int *) bp; bp += 4;
int * maxSizeH = (int *) bp; bp += 4;
wxSize maxSize = wxSize(*maxSizeW,*maxSizeH);
if(!This) throw wxe_badarg(0);
This->SetMaxSize(maxSize);
- break;
+ break;
}
-case wxWindow_SetMinSize: { // wxWindow::SetMinSize
+case wxWindow_SetMinSize: { // wxWindow::SetMinSize
wxWindow *This = (wxWindow *) getPtr(bp,memenv); bp += 4;
int * minSizeW = (int *) bp; bp += 4;
int * minSizeH = (int *) bp; bp += 4;
wxSize minSize = wxSize(*minSizeW,*minSizeH);
if(!This) throw wxe_badarg(0);
This->SetMinSize(minSize);
- break;
+ break;
}
-case wxWindow_SetOwnBackgroundColour: { // wxWindow::SetOwnBackgroundColour
+case wxWindow_SetOwnBackgroundColour: { // wxWindow::SetOwnBackgroundColour
wxWindow *This = (wxWindow *) getPtr(bp,memenv); bp += 4;
int * colourR = (int *) bp; bp += 4;
int * colourG = (int *) bp; bp += 4;
@@ -1204,16 +1204,16 @@ case wxWindow_SetOwnBackgroundColour: { // wxWindow::SetOwnBackgroundColour
wxColour colour = wxColour(*colourR,*colourG,*colourB,*colourA);
if(!This) throw wxe_badarg(0);
This->SetOwnBackgroundColour(colour);
- break;
+ break;
}
-case wxWindow_SetOwnFont: { // wxWindow::SetOwnFont
+case wxWindow_SetOwnFont: { // wxWindow::SetOwnFont
wxWindow *This = (wxWindow *) getPtr(bp,memenv); bp += 4;
wxFont *font = (wxFont *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
This->SetOwnFont(*font);
- break;
+ break;
}
-case wxWindow_SetOwnForegroundColour: { // wxWindow::SetOwnForegroundColour
+case wxWindow_SetOwnForegroundColour: { // wxWindow::SetOwnForegroundColour
wxWindow *This = (wxWindow *) getPtr(bp,memenv); bp += 4;
int * colourR = (int *) bp; bp += 4;
int * colourG = (int *) bp; bp += 4;
@@ -1222,43 +1222,43 @@ case wxWindow_SetOwnForegroundColour: { // wxWindow::SetOwnForegroundColour
wxColour colour = wxColour(*colourR,*colourG,*colourB,*colourA);
if(!This) throw wxe_badarg(0);
This->SetOwnForegroundColour(colour);
- break;
+ break;
}
-case wxWindow_SetDropTarget: { // wxWindow::SetDropTarget
+case wxWindow_SetDropTarget: { // wxWindow::SetDropTarget
wxWindow *This = (wxWindow *) getPtr(bp,memenv); bp += 4;
wxDropTarget *dropTarget = (wxDropTarget *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
This->SetDropTarget(dropTarget);
- break;
+ break;
}
-case wxWindow_SetExtraStyle: { // wxWindow::SetExtraStyle
+case wxWindow_SetExtraStyle: { // wxWindow::SetExtraStyle
wxWindow *This = (wxWindow *) getPtr(bp,memenv); bp += 4;
int * exStyle = (int *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
This->SetExtraStyle((long) *exStyle);
- break;
+ break;
}
-case wxWindow_SetFocus: { // wxWindow::SetFocus
+case wxWindow_SetFocus: { // wxWindow::SetFocus
wxWindow *This = (wxWindow *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
This->SetFocus();
- break;
+ break;
}
-case wxWindow_SetFocusFromKbd: { // wxWindow::SetFocusFromKbd
+case wxWindow_SetFocusFromKbd: { // wxWindow::SetFocusFromKbd
wxWindow *This = (wxWindow *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
This->SetFocusFromKbd();
- break;
+ break;
}
-case wxWindow_SetFont: { // wxWindow::SetFont
+case wxWindow_SetFont: { // wxWindow::SetFont
wxWindow *This = (wxWindow *) getPtr(bp,memenv); bp += 4;
wxFont *font = (wxFont *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
bool Result = This->SetFont(*font);
rt.addBool(Result);
- break;
+ break;
}
-case wxWindow_SetForegroundColour: { // wxWindow::SetForegroundColour
+case wxWindow_SetForegroundColour: { // wxWindow::SetForegroundColour
wxWindow *This = (wxWindow *) getPtr(bp,memenv); bp += 4;
int * colourR = (int *) bp; bp += 4;
int * colourG = (int *) bp; bp += 4;
@@ -1268,50 +1268,50 @@ case wxWindow_SetForegroundColour: { // wxWindow::SetForegroundColour
if(!This) throw wxe_badarg(0);
bool Result = This->SetForegroundColour(colour);
rt.addBool(Result);
- break;
+ break;
}
-case wxWindow_SetHelpText: { // wxWindow::SetHelpText
+case wxWindow_SetHelpText: { // wxWindow::SetHelpText
wxWindow *This = (wxWindow *) getPtr(bp,memenv); bp += 4;
int * textLen = (int *) bp; bp += 4;
wxString text = wxString(bp, wxConvUTF8);
bp += *textLen+((8-((0+ *textLen) & 7)) & 7);
if(!This) throw wxe_badarg(0);
This->SetHelpText(text);
- break;
+ break;
}
-case wxWindow_SetId: { // wxWindow::SetId
+case wxWindow_SetId: { // wxWindow::SetId
wxWindow *This = (wxWindow *) getPtr(bp,memenv); bp += 4;
int * winid = (int *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
This->SetId((wxWindowID) *winid);
- break;
+ break;
}
-case wxWindow_SetLabel: { // wxWindow::SetLabel
+case wxWindow_SetLabel: { // wxWindow::SetLabel
wxWindow *This = (wxWindow *) getPtr(bp,memenv); bp += 4;
int * labelLen = (int *) bp; bp += 4;
wxString label = wxString(bp, wxConvUTF8);
bp += *labelLen+((8-((0+ *labelLen) & 7)) & 7);
if(!This) throw wxe_badarg(0);
This->SetLabel(label);
- break;
+ break;
}
-case wxWindow_SetName: { // wxWindow::SetName
+case wxWindow_SetName: { // wxWindow::SetName
wxWindow *This = (wxWindow *) getPtr(bp,memenv); bp += 4;
int * nameLen = (int *) bp; bp += 4;
wxString name = wxString(bp, wxConvUTF8);
bp += *nameLen+((8-((0+ *nameLen) & 7)) & 7);
if(!This) throw wxe_badarg(0);
This->SetName(name);
- break;
+ break;
}
-case wxWindow_SetPalette: { // wxWindow::SetPalette
+case wxWindow_SetPalette: { // wxWindow::SetPalette
wxWindow *This = (wxWindow *) getPtr(bp,memenv); bp += 4;
wxPalette *pal = (wxPalette *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
This->SetPalette(*pal);
- break;
+ break;
}
-case wxWindow_SetScrollbar: { // wxWindow::SetScrollbar
+case wxWindow_SetScrollbar: { // wxWindow::SetScrollbar
bool refresh=true;
wxWindow *This = (wxWindow *) getPtr(bp,memenv); bp += 4;
int * orient = (int *) bp; bp += 4;
@@ -1319,31 +1319,31 @@ case wxWindow_SetScrollbar: { // wxWindow::SetScrollbar
int * thumbVisible = (int *) bp; bp += 4;
int * range = (int *) bp; bp += 4;
bp += 4; /* Align */
- while( * (int*) bp) { switch (* (int*) bp) {
+ while( * (int*) bp) { switch (* (int*) bp) {
case 1: {bp += 4;
refresh = *(bool *) bp; bp += 4;
} break;
- }};
+ }};
if(!This) throw wxe_badarg(0);
This->SetScrollbar((int) *orient,(int) *pos,(int) *thumbVisible,(int) *range,refresh);
- break;
+ break;
}
-case wxWindow_SetScrollPos: { // wxWindow::SetScrollPos
+case wxWindow_SetScrollPos: { // wxWindow::SetScrollPos
bool refresh=true;
wxWindow *This = (wxWindow *) getPtr(bp,memenv); bp += 4;
int * orient = (int *) bp; bp += 4;
int * pos = (int *) bp; bp += 4;
bp += 4; /* Align */
- while( * (int*) bp) { switch (* (int*) bp) {
+ while( * (int*) bp) { switch (* (int*) bp) {
case 1: {bp += 4;
refresh = *(bool *) bp; bp += 4;
} break;
- }};
+ }};
if(!This) throw wxe_badarg(0);
This->SetScrollPos((int) *orient,(int) *pos,refresh);
- break;
+ break;
}
-case wxWindow_SetSize_5: { // wxWindow::SetSize
+case wxWindow_SetSize_5: { // wxWindow::SetSize
int sizeFlags=wxSIZE_AUTO;
wxWindow *This = (wxWindow *) getPtr(bp,memenv); bp += 4;
int * x = (int *) bp; bp += 4;
@@ -1351,33 +1351,33 @@ case wxWindow_SetSize_5: { // wxWindow::SetSize
int * width = (int *) bp; bp += 4;
int * height = (int *) bp; bp += 4;
bp += 4; /* Align */
- while( * (int*) bp) { switch (* (int*) bp) {
+ while( * (int*) bp) { switch (* (int*) bp) {
case 1: {bp += 4;
sizeFlags = (int)*(int *) bp; bp += 4;
} break;
- }};
+ }};
if(!This) throw wxe_badarg(0);
This->SetSize((int) *x,(int) *y,(int) *width,(int) *height,sizeFlags);
- break;
+ break;
}
-case wxWindow_SetSize_2_0: { // wxWindow::SetSize
+case wxWindow_SetSize_2_0: { // wxWindow::SetSize
wxWindow *This = (wxWindow *) getPtr(bp,memenv); bp += 4;
int * width = (int *) bp; bp += 4;
int * height = (int *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
This->SetSize((int) *width,(int) *height);
- break;
+ break;
}
-case wxWindow_SetSize_1: { // wxWindow::SetSize
+case wxWindow_SetSize_1: { // wxWindow::SetSize
wxWindow *This = (wxWindow *) getPtr(bp,memenv); bp += 4;
int * sizeW = (int *) bp; bp += 4;
int * sizeH = (int *) bp; bp += 4;
wxSize size = wxSize(*sizeW,*sizeH);
if(!This) throw wxe_badarg(0);
This->SetSize(size);
- break;
+ break;
}
-case wxWindow_SetSize_2_1: { // wxWindow::SetSize
+case wxWindow_SetSize_2_1: { // wxWindow::SetSize
int sizeFlags=wxSIZE_AUTO;
wxWindow *This = (wxWindow *) getPtr(bp,memenv); bp += 4;
int * rectX = (int *) bp; bp += 4;
@@ -1386,16 +1386,16 @@ case wxWindow_SetSize_2_1: { // wxWindow::SetSize
int * rectH = (int *) bp; bp += 4;
wxRect rect = wxRect(*rectX,*rectY,*rectW,*rectH);
bp += 4; /* Align */
- while( * (int*) bp) { switch (* (int*) bp) {
+ while( * (int*) bp) { switch (* (int*) bp) {
case 1: {bp += 4;
sizeFlags = (int)*(int *) bp; bp += 4;
} break;
- }};
+ }};
if(!This) throw wxe_badarg(0);
This->SetSize(rect,sizeFlags);
- break;
+ break;
}
-case wxWindow_SetSizeHints_3: { // wxWindow::SetSizeHints
+case wxWindow_SetSizeHints_3: { // wxWindow::SetSizeHints
int maxW=wxDefaultCoord;
int maxH=wxDefaultCoord;
int incW=wxDefaultCoord;
@@ -1404,7 +1404,7 @@ case wxWindow_SetSizeHints_3: { // wxWindow::SetSizeHints
int * minW = (int *) bp; bp += 4;
int * minH = (int *) bp; bp += 4;
bp += 4; /* Align */
- while( * (int*) bp) { switch (* (int*) bp) {
+ while( * (int*) bp) { switch (* (int*) bp) {
case 1: {bp += 4;
maxW = (int)*(int *) bp; bp += 4;
} break;
@@ -1417,12 +1417,12 @@ case wxWindow_SetSizeHints_3: { // wxWindow::SetSizeHints
case 4: {bp += 4;
incH = (int)*(int *) bp; bp += 4;
} break;
- }};
+ }};
if(!This) throw wxe_badarg(0);
This->SetSizeHints((int) *minW,(int) *minH,maxW,maxH,incW,incH);
- break;
+ break;
}
-case wxWindow_SetSizeHints_2: { // wxWindow::SetSizeHints
+case wxWindow_SetSizeHints_2: { // wxWindow::SetSizeHints
wxSize maxSize= wxDefaultSize;
wxSize incSize= wxDefaultSize;
wxWindow *This = (wxWindow *) getPtr(bp,memenv); bp += 4;
@@ -1430,7 +1430,7 @@ case wxWindow_SetSizeHints_2: { // wxWindow::SetSizeHints
int * minSizeH = (int *) bp; bp += 4;
wxSize minSize = wxSize(*minSizeW,*minSizeH);
bp += 4; /* Align */
- while( * (int*) bp) { switch (* (int*) bp) {
+ while( * (int*) bp) { switch (* (int*) bp) {
case 1: {bp += 4;
int * maxSizeW = (int *) bp; bp += 4;
int * maxSizeH = (int *) bp; bp += 4;
@@ -1443,371 +1443,371 @@ case wxWindow_SetSizeHints_2: { // wxWindow::SetSizeHints
incSize = wxSize(*incSizeW,*incSizeH);
bp += 4; /* Align */
} break;
- }};
+ }};
if(!This) throw wxe_badarg(0);
This->SetSizeHints(minSize,maxSize,incSize);
- break;
+ break;
}
-case wxWindow_SetSizer: { // wxWindow::SetSizer
+case wxWindow_SetSizer: { // wxWindow::SetSizer
bool deleteOld=true;
wxWindow *This = (wxWindow *) getPtr(bp,memenv); bp += 4;
wxSizer *sizer = (wxSizer *) getPtr(bp,memenv); bp += 4;
- while( * (int*) bp) { switch (* (int*) bp) {
+ while( * (int*) bp) { switch (* (int*) bp) {
case 1: {bp += 4;
deleteOld = *(bool *) bp; bp += 4;
} break;
- }};
+ }};
if(!This) throw wxe_badarg(0);
This->SetSizer(sizer,deleteOld);
- break;
+ break;
}
-case wxWindow_SetSizerAndFit: { // wxWindow::SetSizerAndFit
+case wxWindow_SetSizerAndFit: { // wxWindow::SetSizerAndFit
bool deleteOld=true;
wxWindow *This = (wxWindow *) getPtr(bp,memenv); bp += 4;
wxSizer *sizer = (wxSizer *) getPtr(bp,memenv); bp += 4;
- while( * (int*) bp) { switch (* (int*) bp) {
+ while( * (int*) bp) { switch (* (int*) bp) {
case 1: {bp += 4;
deleteOld = *(bool *) bp; bp += 4;
} break;
- }};
+ }};
if(!This) throw wxe_badarg(0);
This->SetSizerAndFit(sizer,deleteOld);
- break;
+ break;
}
-case wxWindow_SetThemeEnabled: { // wxWindow::SetThemeEnabled
+case wxWindow_SetThemeEnabled: { // wxWindow::SetThemeEnabled
wxWindow *This = (wxWindow *) getPtr(bp,memenv); bp += 4;
bool * enableTheme = (bool *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
This->SetThemeEnabled((bool) *enableTheme);
- break;
+ break;
}
-case wxWindow_SetToolTip_1_0: { // wxWindow::SetToolTip
+case wxWindow_SetToolTip_1_0: { // wxWindow::SetToolTip
wxWindow *This = (wxWindow *) getPtr(bp,memenv); bp += 4;
int * tipLen = (int *) bp; bp += 4;
wxString tip = wxString(bp, wxConvUTF8);
bp += *tipLen+((8-((0+ *tipLen) & 7)) & 7);
if(!This) throw wxe_badarg(0);
This->SetToolTip(tip);
- break;
+ break;
}
-case wxWindow_SetToolTip_1_1: { // wxWindow::SetToolTip
+case wxWindow_SetToolTip_1_1: { // wxWindow::SetToolTip
wxWindow *This = (wxWindow *) getPtr(bp,memenv); bp += 4;
wxToolTip *tip = (wxToolTip *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
This->SetToolTip(tip);
- break;
+ break;
}
-case wxWindow_SetVirtualSize_1: { // wxWindow::SetVirtualSize
+case wxWindow_SetVirtualSize_1: { // wxWindow::SetVirtualSize
wxWindow *This = (wxWindow *) getPtr(bp,memenv); bp += 4;
int * sizeW = (int *) bp; bp += 4;
int * sizeH = (int *) bp; bp += 4;
wxSize size = wxSize(*sizeW,*sizeH);
if(!This) throw wxe_badarg(0);
This->SetVirtualSize(size);
- break;
+ break;
}
-case wxWindow_SetVirtualSize_2: { // wxWindow::SetVirtualSize
+case wxWindow_SetVirtualSize_2: { // wxWindow::SetVirtualSize
wxWindow *This = (wxWindow *) getPtr(bp,memenv); bp += 4;
int * x = (int *) bp; bp += 4;
int * y = (int *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
This->SetVirtualSize((int) *x,(int) *y);
- break;
+ break;
}
-case wxWindow_SetVirtualSizeHints_3: { // wxWindow::SetVirtualSizeHints
+case wxWindow_SetVirtualSizeHints_3: { // wxWindow::SetVirtualSizeHints
int maxW=wxDefaultCoord;
int maxH=wxDefaultCoord;
wxWindow *This = (wxWindow *) getPtr(bp,memenv); bp += 4;
int * minW = (int *) bp; bp += 4;
int * minH = (int *) bp; bp += 4;
bp += 4; /* Align */
- while( * (int*) bp) { switch (* (int*) bp) {
+ while( * (int*) bp) { switch (* (int*) bp) {
case 1: {bp += 4;
maxW = (int)*(int *) bp; bp += 4;
} break;
case 2: {bp += 4;
maxH = (int)*(int *) bp; bp += 4;
} break;
- }};
+ }};
if(!This) throw wxe_badarg(0);
This->SetVirtualSizeHints((int) *minW,(int) *minH,maxW,maxH);
- break;
+ break;
}
-case wxWindow_SetVirtualSizeHints_2: { // wxWindow::SetVirtualSizeHints
+case wxWindow_SetVirtualSizeHints_2: { // wxWindow::SetVirtualSizeHints
wxSize maxSize= wxDefaultSize;
wxWindow *This = (wxWindow *) getPtr(bp,memenv); bp += 4;
int * minSizeW = (int *) bp; bp += 4;
int * minSizeH = (int *) bp; bp += 4;
wxSize minSize = wxSize(*minSizeW,*minSizeH);
bp += 4; /* Align */
- while( * (int*) bp) { switch (* (int*) bp) {
+ while( * (int*) bp) { switch (* (int*) bp) {
case 1: {bp += 4;
int * maxSizeW = (int *) bp; bp += 4;
int * maxSizeH = (int *) bp; bp += 4;
maxSize = wxSize(*maxSizeW,*maxSizeH);
bp += 4; /* Align */
} break;
- }};
+ }};
if(!This) throw wxe_badarg(0);
This->SetVirtualSizeHints(minSize,maxSize);
- break;
+ break;
}
-case wxWindow_SetWindowStyle: { // wxWindow::SetWindowStyle
+case wxWindow_SetWindowStyle: { // wxWindow::SetWindowStyle
wxWindow *This = (wxWindow *) getPtr(bp,memenv); bp += 4;
int * style = (int *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
This->SetWindowStyle((long) *style);
- break;
+ break;
}
-case wxWindow_SetWindowStyleFlag: { // wxWindow::SetWindowStyleFlag
+case wxWindow_SetWindowStyleFlag: { // wxWindow::SetWindowStyleFlag
wxWindow *This = (wxWindow *) getPtr(bp,memenv); bp += 4;
int * style = (int *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
This->SetWindowStyleFlag((long) *style);
- break;
+ break;
}
-case wxWindow_SetWindowVariant: { // wxWindow::SetWindowVariant
+case wxWindow_SetWindowVariant: { // wxWindow::SetWindowVariant
wxWindow *This = (wxWindow *) getPtr(bp,memenv); bp += 4;
wxWindowVariant variant = *(wxWindowVariant *) bp; bp += 4;;
if(!This) throw wxe_badarg(0);
This->SetWindowVariant((wxWindowVariant) variant);
- break;
+ break;
}
-case wxWindow_ShouldInheritColours: { // wxWindow::ShouldInheritColours
+case wxWindow_ShouldInheritColours: { // wxWindow::ShouldInheritColours
wxWindow *This = (wxWindow *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
bool Result = This->ShouldInheritColours();
rt.addBool(Result);
- break;
+ break;
}
-case wxWindow_Show: { // wxWindow::Show
+case wxWindow_Show: { // wxWindow::Show
bool show=true;
wxWindow *This = (wxWindow *) getPtr(bp,memenv); bp += 4;
bp += 4; /* Align */
- while( * (int*) bp) { switch (* (int*) bp) {
+ while( * (int*) bp) { switch (* (int*) bp) {
case 1: {bp += 4;
show = *(bool *) bp; bp += 4;
} break;
- }};
+ }};
if(!This) throw wxe_badarg(0);
bool Result = This->Show(show);
rt.addBool(Result);
- break;
+ break;
}
-case wxWindow_Thaw: { // wxWindow::Thaw
+case wxWindow_Thaw: { // wxWindow::Thaw
wxWindow *This = (wxWindow *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
This->Thaw();
- break;
+ break;
}
-case wxWindow_TransferDataFromWindow: { // wxWindow::TransferDataFromWindow
+case wxWindow_TransferDataFromWindow: { // wxWindow::TransferDataFromWindow
wxWindow *This = (wxWindow *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
bool Result = This->TransferDataFromWindow();
rt.addBool(Result);
- break;
+ break;
}
-case wxWindow_TransferDataToWindow: { // wxWindow::TransferDataToWindow
+case wxWindow_TransferDataToWindow: { // wxWindow::TransferDataToWindow
wxWindow *This = (wxWindow *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
bool Result = This->TransferDataToWindow();
rt.addBool(Result);
- break;
+ break;
}
-case wxWindow_Update: { // wxWindow::Update
+case wxWindow_Update: { // wxWindow::Update
wxWindow *This = (wxWindow *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
This->Update();
- break;
+ break;
}
-case wxWindow_UpdateWindowUI: { // wxWindow::UpdateWindowUI
+case wxWindow_UpdateWindowUI: { // wxWindow::UpdateWindowUI
long flags=wxUPDATE_UI_NONE;
wxWindow *This = (wxWindow *) getPtr(bp,memenv); bp += 4;
bp += 4; /* Align */
- while( * (int*) bp) { switch (* (int*) bp) {
+ while( * (int*) bp) { switch (* (int*) bp) {
case 1: {bp += 4;
flags = (long)*(int *) bp; bp += 4;
} break;
- }};
+ }};
if(!This) throw wxe_badarg(0);
This->UpdateWindowUI(flags);
- break;
+ break;
}
-case wxWindow_Validate: { // wxWindow::Validate
+case wxWindow_Validate: { // wxWindow::Validate
wxWindow *This = (wxWindow *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
bool Result = This->Validate();
rt.addBool(Result);
- break;
+ break;
}
-case wxWindow_WarpPointer: { // wxWindow::WarpPointer
+case wxWindow_WarpPointer: { // wxWindow::WarpPointer
wxWindow *This = (wxWindow *) getPtr(bp,memenv); bp += 4;
int * x = (int *) bp; bp += 4;
int * y = (int *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
This->WarpPointer((int) *x,(int) *y);
- break;
+ break;
}
-case wxTopLevelWindow_GetIcon: { // wxTopLevelWindow::GetIcon
+case wxTopLevelWindow_GetIcon: { // wxTopLevelWindow::GetIcon
wxTopLevelWindow *This = (wxTopLevelWindow *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
const wxIcon * Result = &This->GetIcon();
rt.addRef(getRef((void *)Result,memenv), "wxIcon");
- break;
+ break;
}
-case wxTopLevelWindow_GetIcons: { // wxTopLevelWindow::GetIcons
+case wxTopLevelWindow_GetIcons: { // wxTopLevelWindow::GetIcons
wxTopLevelWindow *This = (wxTopLevelWindow *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
const wxIconBundle * Result = &This->GetIcons();
rt.addRef(getRef((void *)Result,memenv), "wxIconBundle");
- break;
+ break;
}
-case wxTopLevelWindow_GetTitle: { // wxTopLevelWindow::GetTitle
+case wxTopLevelWindow_GetTitle: { // wxTopLevelWindow::GetTitle
wxTopLevelWindow *This = (wxTopLevelWindow *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
wxString Result = This->GetTitle();
rt.add(Result);
- break;
+ break;
}
-case wxTopLevelWindow_IsActive: { // wxTopLevelWindow::IsActive
+case wxTopLevelWindow_IsActive: { // wxTopLevelWindow::IsActive
wxTopLevelWindow *This = (wxTopLevelWindow *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
bool Result = This->IsActive();
rt.addBool(Result);
- break;
+ break;
}
-case wxTopLevelWindow_Iconize: { // wxTopLevelWindow::Iconize
+case wxTopLevelWindow_Iconize: { // wxTopLevelWindow::Iconize
bool iconize=true;
wxTopLevelWindow *This = (wxTopLevelWindow *) getPtr(bp,memenv); bp += 4;
bp += 4; /* Align */
- while( * (int*) bp) { switch (* (int*) bp) {
+ while( * (int*) bp) { switch (* (int*) bp) {
case 1: {bp += 4;
iconize = *(bool *) bp; bp += 4;
} break;
- }};
+ }};
if(!This) throw wxe_badarg(0);
This->Iconize(iconize);
- break;
+ break;
}
-case wxTopLevelWindow_IsFullScreen: { // wxTopLevelWindow::IsFullScreen
+case wxTopLevelWindow_IsFullScreen: { // wxTopLevelWindow::IsFullScreen
wxTopLevelWindow *This = (wxTopLevelWindow *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
bool Result = This->IsFullScreen();
rt.addBool(Result);
- break;
+ break;
}
-case wxTopLevelWindow_IsIconized: { // wxTopLevelWindow::IsIconized
+case wxTopLevelWindow_IsIconized: { // wxTopLevelWindow::IsIconized
wxTopLevelWindow *This = (wxTopLevelWindow *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
bool Result = This->IsIconized();
rt.addBool(Result);
- break;
+ break;
}
-case wxTopLevelWindow_IsMaximized: { // wxTopLevelWindow::IsMaximized
+case wxTopLevelWindow_IsMaximized: { // wxTopLevelWindow::IsMaximized
wxTopLevelWindow *This = (wxTopLevelWindow *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
bool Result = This->IsMaximized();
rt.addBool(Result);
- break;
+ break;
}
-case wxTopLevelWindow_Maximize: { // wxTopLevelWindow::Maximize
+case wxTopLevelWindow_Maximize: { // wxTopLevelWindow::Maximize
bool maximize=true;
wxTopLevelWindow *This = (wxTopLevelWindow *) getPtr(bp,memenv); bp += 4;
bp += 4; /* Align */
- while( * (int*) bp) { switch (* (int*) bp) {
+ while( * (int*) bp) { switch (* (int*) bp) {
case 1: {bp += 4;
maximize = *(bool *) bp; bp += 4;
} break;
- }};
+ }};
if(!This) throw wxe_badarg(0);
This->Maximize(maximize);
- break;
+ break;
}
-case wxTopLevelWindow_RequestUserAttention: { // wxTopLevelWindow::RequestUserAttention
+case wxTopLevelWindow_RequestUserAttention: { // wxTopLevelWindow::RequestUserAttention
int flags=wxUSER_ATTENTION_INFO;
wxTopLevelWindow *This = (wxTopLevelWindow *) getPtr(bp,memenv); bp += 4;
bp += 4; /* Align */
- while( * (int*) bp) { switch (* (int*) bp) {
+ while( * (int*) bp) { switch (* (int*) bp) {
case 1: {bp += 4;
flags = (int)*(int *) bp; bp += 4;
} break;
- }};
+ }};
if(!This) throw wxe_badarg(0);
This->RequestUserAttention(flags);
- break;
+ break;
}
-case wxTopLevelWindow_SetIcon: { // wxTopLevelWindow::SetIcon
+case wxTopLevelWindow_SetIcon: { // wxTopLevelWindow::SetIcon
wxTopLevelWindow *This = (wxTopLevelWindow *) getPtr(bp,memenv); bp += 4;
wxIcon *icon = (wxIcon *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
This->SetIcon(*icon);
- break;
+ break;
}
-case wxTopLevelWindow_SetIcons: { // wxTopLevelWindow::SetIcons
+case wxTopLevelWindow_SetIcons: { // wxTopLevelWindow::SetIcons
wxTopLevelWindow *This = (wxTopLevelWindow *) getPtr(bp,memenv); bp += 4;
wxIconBundle *icons = (wxIconBundle *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
This->SetIcons(*icons);
- break;
+ break;
}
-case wxTopLevelWindow_CenterOnScreen: { // wxTopLevelWindow::CenterOnScreen
+case wxTopLevelWindow_CenterOnScreen: { // wxTopLevelWindow::CenterOnScreen
int dir=wxBOTH;
wxTopLevelWindow *This = (wxTopLevelWindow *) getPtr(bp,memenv); bp += 4;
bp += 4; /* Align */
- while( * (int*) bp) { switch (* (int*) bp) {
+ while( * (int*) bp) { switch (* (int*) bp) {
case 1: {bp += 4;
dir = (int)*(int *) bp; bp += 4;
} break;
- }};
+ }};
if(!This) throw wxe_badarg(0);
This->CenterOnScreen(dir);
- break;
+ break;
}
-case wxTopLevelWindow_CentreOnScreen: { // wxTopLevelWindow::CentreOnScreen
+case wxTopLevelWindow_CentreOnScreen: { // wxTopLevelWindow::CentreOnScreen
int dir=wxBOTH;
wxTopLevelWindow *This = (wxTopLevelWindow *) getPtr(bp,memenv); bp += 4;
bp += 4; /* Align */
- while( * (int*) bp) { switch (* (int*) bp) {
+ while( * (int*) bp) { switch (* (int*) bp) {
case 1: {bp += 4;
dir = (int)*(int *) bp; bp += 4;
} break;
- }};
+ }};
if(!This) throw wxe_badarg(0);
This->CentreOnScreen(dir);
- break;
+ break;
}
-case wxTopLevelWindow_SetShape: { // wxTopLevelWindow::SetShape
+case wxTopLevelWindow_SetShape: { // wxTopLevelWindow::SetShape
wxTopLevelWindow *This = (wxTopLevelWindow *) getPtr(bp,memenv); bp += 4;
wxRegion *region = (wxRegion *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
bool Result = This->SetShape(*region);
rt.addBool(Result);
- break;
+ break;
}
-case wxTopLevelWindow_SetTitle: { // wxTopLevelWindow::SetTitle
+case wxTopLevelWindow_SetTitle: { // wxTopLevelWindow::SetTitle
wxTopLevelWindow *This = (wxTopLevelWindow *) getPtr(bp,memenv); bp += 4;
int * titleLen = (int *) bp; bp += 4;
wxString title = wxString(bp, wxConvUTF8);
bp += *titleLen+((8-((0+ *titleLen) & 7)) & 7);
if(!This) throw wxe_badarg(0);
This->SetTitle(title);
- break;
+ break;
}
-case wxTopLevelWindow_ShowFullScreen: { // wxTopLevelWindow::ShowFullScreen
+case wxTopLevelWindow_ShowFullScreen: { // wxTopLevelWindow::ShowFullScreen
long style=wxFULLSCREEN_ALL;
wxTopLevelWindow *This = (wxTopLevelWindow *) getPtr(bp,memenv); bp += 4;
bool * show = (bool *) bp; bp += 4;
- while( * (int*) bp) { switch (* (int*) bp) {
+ while( * (int*) bp) { switch (* (int*) bp) {
case 1: {bp += 4;
style = (long)*(int *) bp; bp += 4;
} break;
- }};
+ }};
if(!This) throw wxe_badarg(0);
bool Result = This->ShowFullScreen((bool) *show,style);
rt.addBool(Result);
- break;
+ break;
}
-case wxFrame_new_4: { // wxFrame::wxFrame
+case wxFrame_new_4: { // wxFrame::wxFrame
wxPoint pos= wxDefaultPosition;
wxSize size= wxDefaultSize;
long style=wxDEFAULT_FRAME_STYLE;
@@ -1816,7 +1816,7 @@ case wxFrame_new_4: { // wxFrame::wxFrame
int * titleLen = (int *) bp; bp += 4;
wxString title = wxString(bp, wxConvUTF8);
bp += *titleLen+((8-((4+ *titleLen) & 7)) & 7);
- while( * (int*) bp) { switch (* (int*) bp) {
+ while( * (int*) bp) { switch (* (int*) bp) {
case 1: {bp += 4;
int * posX = (int *) bp; bp += 4;
int * posY = (int *) bp; bp += 4;
@@ -1832,19 +1832,19 @@ case wxFrame_new_4: { // wxFrame::wxFrame
case 3: {bp += 4;
style = (long)*(int *) bp; bp += 4;
} break;
- }};
+ }};
wxFrame * Result = new EwxFrame(parent,(wxWindowID) *id,title,pos,size,style);
newPtr((void *) Result, 0, memenv);
rt.addRef(getRef((void *)Result,memenv), "wxFrame");
- break;
+ break;
}
-case wxFrame_new_0: { // wxFrame::wxFrame
+case wxFrame_new_0: { // wxFrame::wxFrame
wxFrame * Result = new EwxFrame();
newPtr((void *) Result, 0, memenv);
rt.addRef(getRef((void *)Result,memenv), "wxFrame");
- break;
+ break;
}
-case wxFrame_Create: { // wxFrame::Create
+case wxFrame_Create: { // wxFrame::Create
wxPoint pos= wxDefaultPosition;
wxSize size= wxDefaultSize;
long style=wxDEFAULT_FRAME_STYLE;
@@ -1854,7 +1854,7 @@ case wxFrame_Create: { // wxFrame::Create
int * titleLen = (int *) bp; bp += 4;
wxString title = wxString(bp, wxConvUTF8);
bp += *titleLen+((8-((0+ *titleLen) & 7)) & 7);
- while( * (int*) bp) { switch (* (int*) bp) {
+ while( * (int*) bp) { switch (* (int*) bp) {
case 1: {bp += 4;
int * posX = (int *) bp; bp += 4;
int * posY = (int *) bp; bp += 4;
@@ -1870,19 +1870,19 @@ case wxFrame_Create: { // wxFrame::Create
case 3: {bp += 4;
style = (long)*(int *) bp; bp += 4;
} break;
- }};
+ }};
if(!This) throw wxe_badarg(0);
bool Result = This->Create(parent,(wxWindowID) *id,title,pos,size,style);
rt.addBool(Result);
- break;
+ break;
}
-case wxFrame_CreateStatusBar: { // wxFrame::CreateStatusBar
+case wxFrame_CreateStatusBar: { // wxFrame::CreateStatusBar
int number=1;
long style=wxST_SIZEGRIP|wxFULL_REPAINT_ON_RESIZE;
wxWindowID id=0;
wxFrame *This = (wxFrame *) getPtr(bp,memenv); bp += 4;
bp += 4; /* Align */
- while( * (int*) bp) { switch (* (int*) bp) {
+ while( * (int*) bp) { switch (* (int*) bp) {
case 1: {bp += 4;
number = (int)*(int *) bp; bp += 4;
} break;
@@ -1892,137 +1892,137 @@ case wxFrame_CreateStatusBar: { // wxFrame::CreateStatusBar
case 3: {bp += 4;
id = (wxWindowID)*(int *) bp; bp += 4;
} break;
- }};
+ }};
if(!This) throw wxe_badarg(0);
wxStatusBar * Result = (wxStatusBar*)This->CreateStatusBar(number,style,id);
rt.addRef(getRef((void *)Result,memenv), "wxStatusBar");
- break;
+ break;
}
-case wxFrame_CreateToolBar: { // wxFrame::CreateToolBar
+case wxFrame_CreateToolBar: { // wxFrame::CreateToolBar
long style=-1;
wxWindowID id=-1;
wxFrame *This = (wxFrame *) getPtr(bp,memenv); bp += 4;
bp += 4; /* Align */
- while( * (int*) bp) { switch (* (int*) bp) {
+ while( * (int*) bp) { switch (* (int*) bp) {
case 1: {bp += 4;
style = (long)*(int *) bp; bp += 4;
} break;
case 2: {bp += 4;
id = (wxWindowID)*(int *) bp; bp += 4;
} break;
- }};
+ }};
if(!This) throw wxe_badarg(0);
wxToolBar * Result = (wxToolBar*)This->CreateToolBar(style,id);
rt.addRef(getRef((void *)Result,memenv), "wxToolBar");
- break;
+ break;
}
-case wxFrame_GetClientAreaOrigin: { // wxFrame::GetClientAreaOrigin
+case wxFrame_GetClientAreaOrigin: { // wxFrame::GetClientAreaOrigin
wxFrame *This = (wxFrame *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
wxPoint Result = This->GetClientAreaOrigin();
rt.add(Result);
- break;
+ break;
}
-case wxFrame_GetMenuBar: { // wxFrame::GetMenuBar
+case wxFrame_GetMenuBar: { // wxFrame::GetMenuBar
wxFrame *This = (wxFrame *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
wxMenuBar * Result = (wxMenuBar*)This->GetMenuBar();
rt.addRef(getRef((void *)Result,memenv), "wxMenuBar");
- break;
+ break;
}
-case wxFrame_GetStatusBar: { // wxFrame::GetStatusBar
+case wxFrame_GetStatusBar: { // wxFrame::GetStatusBar
wxFrame *This = (wxFrame *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
wxStatusBar * Result = (wxStatusBar*)This->GetStatusBar();
rt.addRef(getRef((void *)Result,memenv), "wxStatusBar");
- break;
+ break;
}
-case wxFrame_GetStatusBarPane: { // wxFrame::GetStatusBarPane
+case wxFrame_GetStatusBarPane: { // wxFrame::GetStatusBarPane
wxFrame *This = (wxFrame *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
int Result = This->GetStatusBarPane();
rt.addInt(Result);
- break;
+ break;
}
-case wxFrame_GetToolBar: { // wxFrame::GetToolBar
+case wxFrame_GetToolBar: { // wxFrame::GetToolBar
wxFrame *This = (wxFrame *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
wxToolBar * Result = (wxToolBar*)This->GetToolBar();
rt.addRef(getRef((void *)Result,memenv), "wxToolBar");
- break;
+ break;
}
-case wxFrame_ProcessCommand: { // wxFrame::ProcessCommand
+case wxFrame_ProcessCommand: { // wxFrame::ProcessCommand
wxFrame *This = (wxFrame *) getPtr(bp,memenv); bp += 4;
int * winid = (int *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
bool Result = This->ProcessCommand((int) *winid);
rt.addBool(Result);
- break;
+ break;
}
-case wxFrame_SendSizeEvent: { // wxFrame::SendSizeEvent
+case wxFrame_SendSizeEvent: { // wxFrame::SendSizeEvent
wxFrame *This = (wxFrame *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
This->SendSizeEvent();
- break;
+ break;
}
-case wxFrame_SetMenuBar: { // wxFrame::SetMenuBar
+case wxFrame_SetMenuBar: { // wxFrame::SetMenuBar
wxFrame *This = (wxFrame *) getPtr(bp,memenv); bp += 4;
wxMenuBar *menubar = (wxMenuBar *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
This->SetMenuBar(menubar);
- break;
+ break;
}
-case wxFrame_SetStatusBar: { // wxFrame::SetStatusBar
+case wxFrame_SetStatusBar: { // wxFrame::SetStatusBar
wxFrame *This = (wxFrame *) getPtr(bp,memenv); bp += 4;
wxStatusBar *statbar = (wxStatusBar *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
This->SetStatusBar(statbar);
- break;
+ break;
}
-case wxFrame_SetStatusBarPane: { // wxFrame::SetStatusBarPane
+case wxFrame_SetStatusBarPane: { // wxFrame::SetStatusBarPane
wxFrame *This = (wxFrame *) getPtr(bp,memenv); bp += 4;
int * n = (int *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
This->SetStatusBarPane((int) *n);
- break;
+ break;
}
-case wxFrame_SetStatusText: { // wxFrame::SetStatusText
+case wxFrame_SetStatusText: { // wxFrame::SetStatusText
int number=0;
wxFrame *This = (wxFrame *) getPtr(bp,memenv); bp += 4;
int * textLen = (int *) bp; bp += 4;
wxString text = wxString(bp, wxConvUTF8);
bp += *textLen+((8-((0+ *textLen) & 7)) & 7);
- while( * (int*) bp) { switch (* (int*) bp) {
+ while( * (int*) bp) { switch (* (int*) bp) {
case 1: {bp += 4;
number = (int)*(int *) bp; bp += 4;
} break;
- }};
+ }};
if(!This) throw wxe_badarg(0);
This->SetStatusText(text,number);
- break;
+ break;
}
-case wxFrame_SetStatusWidths: { // wxFrame::SetStatusWidths
+case wxFrame_SetStatusWidths: { // wxFrame::SetStatusWidths
wxFrame *This = (wxFrame *) getPtr(bp,memenv); bp += 4;
int * widths_fieldLen = (int *) bp; bp += 4;
int * widths_field = (int *) bp; bp += *widths_fieldLen*4+((0+ *widths_fieldLen)%2 )*4;
if(!This) throw wxe_badarg(0);
This->SetStatusWidths(*widths_fieldLen,widths_field);
- break;
+ break;
}
-case wxFrame_SetToolBar: { // wxFrame::SetToolBar
+case wxFrame_SetToolBar: { // wxFrame::SetToolBar
wxFrame *This = (wxFrame *) getPtr(bp,memenv); bp += 4;
wxToolBar *toolbar = (wxToolBar *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
This->SetToolBar(toolbar);
- break;
+ break;
}
-case wxMiniFrame_new_0: { // wxMiniFrame::wxMiniFrame
+case wxMiniFrame_new_0: { // wxMiniFrame::wxMiniFrame
wxMiniFrame * Result = new EwxMiniFrame();
newPtr((void *) Result, 0, memenv);
rt.addRef(getRef((void *)Result,memenv), "wxMiniFrame");
- break;
+ break;
}
-case wxMiniFrame_new_4: { // wxMiniFrame::wxMiniFrame
+case wxMiniFrame_new_4: { // wxMiniFrame::wxMiniFrame
wxPoint pos= wxDefaultPosition;
wxSize size= wxDefaultSize;
long style=wxCAPTION|wxRESIZE_BORDER;
@@ -2031,7 +2031,7 @@ case wxMiniFrame_new_4: { // wxMiniFrame::wxMiniFrame
int * titleLen = (int *) bp; bp += 4;
wxString title = wxString(bp, wxConvUTF8);
bp += *titleLen+((8-((4+ *titleLen) & 7)) & 7);
- while( * (int*) bp) { switch (* (int*) bp) {
+ while( * (int*) bp) { switch (* (int*) bp) {
case 1: {bp += 4;
int * posX = (int *) bp; bp += 4;
int * posY = (int *) bp; bp += 4;
@@ -2047,13 +2047,13 @@ case wxMiniFrame_new_4: { // wxMiniFrame::wxMiniFrame
case 3: {bp += 4;
style = (long)*(int *) bp; bp += 4;
} break;
- }};
+ }};
wxMiniFrame * Result = new EwxMiniFrame(parent,(wxWindowID) *id,title,pos,size,style);
newPtr((void *) Result, 0, memenv);
rt.addRef(getRef((void *)Result,memenv), "wxMiniFrame");
- break;
+ break;
}
-case wxMiniFrame_Create: { // wxMiniFrame::Create
+case wxMiniFrame_Create: { // wxMiniFrame::Create
wxPoint pos= wxDefaultPosition;
wxSize size= wxDefaultSize;
long style=wxCAPTION|wxRESIZE_BORDER;
@@ -2063,7 +2063,7 @@ case wxMiniFrame_Create: { // wxMiniFrame::Create
int * titleLen = (int *) bp; bp += 4;
wxString title = wxString(bp, wxConvUTF8);
bp += *titleLen+((8-((0+ *titleLen) & 7)) & 7);
- while( * (int*) bp) { switch (* (int*) bp) {
+ while( * (int*) bp) { switch (* (int*) bp) {
case 1: {bp += 4;
int * posX = (int *) bp; bp += 4;
int * posY = (int *) bp; bp += 4;
@@ -2079,19 +2079,19 @@ case wxMiniFrame_Create: { // wxMiniFrame::Create
case 3: {bp += 4;
style = (long)*(int *) bp; bp += 4;
} break;
- }};
+ }};
if(!This) throw wxe_badarg(0);
bool Result = This->Create(parent,(wxWindowID) *id,title,pos,size,style);
rt.addBool(Result);
- break;
+ break;
}
-case wxSplashScreen_new_0: { // wxSplashScreen::wxSplashScreen
+case wxSplashScreen_new_0: { // wxSplashScreen::wxSplashScreen
wxSplashScreen * Result = new EwxSplashScreen();
newPtr((void *) Result, 0, memenv);
rt.addRef(getRef((void *)Result,memenv), "wxSplashScreen");
- break;
+ break;
}
-case wxSplashScreen_new_6: { // wxSplashScreen::wxSplashScreen
+case wxSplashScreen_new_6: { // wxSplashScreen::wxSplashScreen
wxPoint pos= wxDefaultPosition;
wxSize size= wxDefaultSize;
long style=wxSIMPLE_BORDER|wxFRAME_NO_TASKBAR|wxSTAY_ON_TOP;
@@ -2101,7 +2101,7 @@ case wxSplashScreen_new_6: { // wxSplashScreen::wxSplashScreen
wxWindow *parent = (wxWindow *) getPtr(bp,memenv); bp += 4;
int * id = (int *) bp; bp += 4;
bp += 4; /* Align */
- while( * (int*) bp) { switch (* (int*) bp) {
+ while( * (int*) bp) { switch (* (int*) bp) {
case 1: {bp += 4;
int * posX = (int *) bp; bp += 4;
int * posY = (int *) bp; bp += 4;
@@ -2117,33 +2117,33 @@ case wxSplashScreen_new_6: { // wxSplashScreen::wxSplashScreen
case 3: {bp += 4;
style = (long)*(int *) bp; bp += 4;
} break;
- }};
+ }};
wxSplashScreen * Result = new EwxSplashScreen(*bitmap,(long) *splashStyle,(int) *milliseconds,parent,(wxWindowID) *id,pos,size,style);
newPtr((void *) Result, 0, memenv);
rt.addRef(getRef((void *)Result,memenv), "wxSplashScreen");
- break;
+ break;
}
-case wxSplashScreen_GetSplashStyle: { // wxSplashScreen::GetSplashStyle
+case wxSplashScreen_GetSplashStyle: { // wxSplashScreen::GetSplashStyle
wxSplashScreen *This = (wxSplashScreen *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
long Result = This->GetSplashStyle();
rt.addInt(Result);
- break;
+ break;
}
-case wxSplashScreen_GetTimeout: { // wxSplashScreen::GetTimeout
+case wxSplashScreen_GetTimeout: { // wxSplashScreen::GetTimeout
wxSplashScreen *This = (wxSplashScreen *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
int Result = This->GetTimeout();
rt.addInt(Result);
- break;
+ break;
}
-case wxPanel_new_0: { // wxPanel::wxPanel
+case wxPanel_new_0: { // wxPanel::wxPanel
wxPanel * Result = new EwxPanel();
newPtr((void *) Result, 0, memenv);
rt.addRef(getRef((void *)Result,memenv), "wxPanel");
- break;
+ break;
}
-case wxPanel_new_6: { // wxPanel::wxPanel
+case wxPanel_new_6: { // wxPanel::wxPanel
long style=wxTAB_TRAVERSAL|wxNO_BORDER;
wxWindow *parent = (wxWindow *) getPtr(bp,memenv); bp += 4;
int * x = (int *) bp; bp += 4;
@@ -2151,24 +2151,24 @@ case wxPanel_new_6: { // wxPanel::wxPanel
int * width = (int *) bp; bp += 4;
int * height = (int *) bp; bp += 4;
bp += 4; /* Align */
- while( * (int*) bp) { switch (* (int*) bp) {
+ while( * (int*) bp) { switch (* (int*) bp) {
case 1: {bp += 4;
style = (long)*(int *) bp; bp += 4;
} break;
- }};
+ }};
wxPanel * Result = new EwxPanel(parent,(int) *x,(int) *y,(int) *width,(int) *height,style);
newPtr((void *) Result, 0, memenv);
rt.addRef(getRef((void *)Result,memenv), "wxPanel");
- break;
+ break;
}
-case wxPanel_new_2: { // wxPanel::wxPanel
+case wxPanel_new_2: { // wxPanel::wxPanel
wxWindowID winid=wxID_ANY;
wxPoint pos= wxDefaultPosition;
wxSize size= wxDefaultSize;
long style=wxTAB_TRAVERSAL|wxNO_BORDER;
wxWindow *parent = (wxWindow *) getPtr(bp,memenv); bp += 4;
bp += 4; /* Align */
- while( * (int*) bp) { switch (* (int*) bp) {
+ while( * (int*) bp) { switch (* (int*) bp) {
case 1: {bp += 4;
winid = (wxWindowID)*(int *) bp; bp += 4;
} break;
@@ -2187,32 +2187,32 @@ case wxPanel_new_2: { // wxPanel::wxPanel
case 4: {bp += 4;
style = (long)*(int *) bp; bp += 4;
} break;
- }};
+ }};
wxPanel * Result = new EwxPanel(parent,winid,pos,size,style);
newPtr((void *) Result, 0, memenv);
rt.addRef(getRef((void *)Result,memenv), "wxPanel");
- break;
+ break;
}
-case wxPanel_InitDialog: { // wxPanel::InitDialog
+case wxPanel_InitDialog: { // wxPanel::InitDialog
wxPanel *This = (wxPanel *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
This->InitDialog();
- break;
+ break;
}
-case wxScrolledWindow_new_0: { // wxScrolledWindow::wxScrolledWindow
+case wxScrolledWindow_new_0: { // wxScrolledWindow::wxScrolledWindow
wxScrolledWindow * Result = new EwxScrolledWindow();
newPtr((void *) Result, 0, memenv);
rt.addRef(getRef((void *)Result,memenv), "wxScrolledWindow");
- break;
+ break;
}
-case wxScrolledWindow_new_2: { // wxScrolledWindow::wxScrolledWindow
+case wxScrolledWindow_new_2: { // wxScrolledWindow::wxScrolledWindow
wxWindowID winid=wxID_ANY;
wxPoint pos= wxDefaultPosition;
wxSize size= wxDefaultSize;
long style=(wxHSCROLL|wxVSCROLL);
wxWindow *parent = (wxWindow *) getPtr(bp,memenv); bp += 4;
bp += 4; /* Align */
- while( * (int*) bp) { switch (* (int*) bp) {
+ while( * (int*) bp) { switch (* (int*) bp) {
case 1: {bp += 4;
winid = (wxWindowID)*(int *) bp; bp += 4;
} break;
@@ -2231,13 +2231,13 @@ case wxScrolledWindow_new_2: { // wxScrolledWindow::wxScrolledWindow
case 4: {bp += 4;
style = (long)*(int *) bp; bp += 4;
} break;
- }};
+ }};
wxScrolledWindow * Result = new EwxScrolledWindow(parent,winid,pos,size,style);
newPtr((void *) Result, 0, memenv);
rt.addRef(getRef((void *)Result,memenv), "wxScrolledWindow");
- break;
+ break;
}
-case wxScrolledWindow_CalcScrolledPosition_4: { // wxScrolledWindow::CalcScrolledPosition
+case wxScrolledWindow_CalcScrolledPosition_4: { // wxScrolledWindow::CalcScrolledPosition
int xx;
int yy;
wxScrolledWindow *This = (wxScrolledWindow *) getPtr(bp,memenv); bp += 4;
@@ -2248,9 +2248,9 @@ case wxScrolledWindow_CalcScrolledPosition_4: { // wxScrolledWindow::CalcScrolle
rt.addInt(xx);
rt.addInt(yy);
rt.addTupleCount(2);
- break;
+ break;
}
-case wxScrolledWindow_CalcScrolledPosition_1: { // wxScrolledWindow::CalcScrolledPosition
+case wxScrolledWindow_CalcScrolledPosition_1: { // wxScrolledWindow::CalcScrolledPosition
wxScrolledWindow *This = (wxScrolledWindow *) getPtr(bp,memenv); bp += 4;
int * ptX = (int *) bp; bp += 4;
int * ptY = (int *) bp; bp += 4;
@@ -2258,9 +2258,9 @@ case wxScrolledWindow_CalcScrolledPosition_1: { // wxScrolledWindow::CalcScrolle
if(!This) throw wxe_badarg(0);
wxPoint Result = This->CalcScrolledPosition(pt);
rt.add(Result);
- break;
+ break;
}
-case wxScrolledWindow_CalcUnscrolledPosition_4: { // wxScrolledWindow::CalcUnscrolledPosition
+case wxScrolledWindow_CalcUnscrolledPosition_4: { // wxScrolledWindow::CalcUnscrolledPosition
int xx;
int yy;
wxScrolledWindow *This = (wxScrolledWindow *) getPtr(bp,memenv); bp += 4;
@@ -2271,9 +2271,9 @@ case wxScrolledWindow_CalcUnscrolledPosition_4: { // wxScrolledWindow::CalcUnscr
rt.addInt(xx);
rt.addInt(yy);
rt.addTupleCount(2);
- break;
+ break;
}
-case wxScrolledWindow_CalcUnscrolledPosition_1: { // wxScrolledWindow::CalcUnscrolledPosition
+case wxScrolledWindow_CalcUnscrolledPosition_1: { // wxScrolledWindow::CalcUnscrolledPosition
wxScrolledWindow *This = (wxScrolledWindow *) getPtr(bp,memenv); bp += 4;
int * ptX = (int *) bp; bp += 4;
int * ptY = (int *) bp; bp += 4;
@@ -2281,17 +2281,17 @@ case wxScrolledWindow_CalcUnscrolledPosition_1: { // wxScrolledWindow::CalcUnscr
if(!This) throw wxe_badarg(0);
wxPoint Result = This->CalcUnscrolledPosition(pt);
rt.add(Result);
- break;
+ break;
}
-case wxScrolledWindow_EnableScrolling: { // wxScrolledWindow::EnableScrolling
+case wxScrolledWindow_EnableScrolling: { // wxScrolledWindow::EnableScrolling
wxScrolledWindow *This = (wxScrolledWindow *) getPtr(bp,memenv); bp += 4;
bool * x_scrolling = (bool *) bp; bp += 4;
bool * y_scrolling = (bool *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
This->EnableScrolling((bool) *x_scrolling,(bool) *y_scrolling);
- break;
+ break;
}
-case wxScrolledWindow_GetScrollPixelsPerUnit: { // wxScrolledWindow::GetScrollPixelsPerUnit
+case wxScrolledWindow_GetScrollPixelsPerUnit: { // wxScrolledWindow::GetScrollPixelsPerUnit
int pixelsPerUnitX;
int pixelsPerUnitY;
wxScrolledWindow *This = (wxScrolledWindow *) getPtr(bp,memenv); bp += 4;
@@ -2300,9 +2300,9 @@ case wxScrolledWindow_GetScrollPixelsPerUnit: { // wxScrolledWindow::GetScrollPi
rt.addInt(pixelsPerUnitX);
rt.addInt(pixelsPerUnitY);
rt.addTupleCount(2);
- break;
+ break;
}
-case wxScrolledWindow_GetViewStart: { // wxScrolledWindow::GetViewStart
+case wxScrolledWindow_GetViewStart: { // wxScrolledWindow::GetViewStart
int x;
int y;
wxScrolledWindow *This = (wxScrolledWindow *) getPtr(bp,memenv); bp += 4;
@@ -2311,31 +2311,31 @@ case wxScrolledWindow_GetViewStart: { // wxScrolledWindow::GetViewStart
rt.addInt(x);
rt.addInt(y);
rt.addTupleCount(2);
- break;
+ break;
}
-case wxScrolledWindow_DoPrepareDC: { // wxScrolledWindow::DoPrepareDC
+case wxScrolledWindow_DoPrepareDC: { // wxScrolledWindow::DoPrepareDC
wxScrolledWindow *This = (wxScrolledWindow *) getPtr(bp,memenv); bp += 4;
wxDC *dc = (wxDC *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
This->DoPrepareDC(*dc);
- break;
+ break;
}
-case wxScrolledWindow_PrepareDC: { // wxScrolledWindow::PrepareDC
+case wxScrolledWindow_PrepareDC: { // wxScrolledWindow::PrepareDC
wxScrolledWindow *This = (wxScrolledWindow *) getPtr(bp,memenv); bp += 4;
wxDC *dc = (wxDC *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
This->PrepareDC(*dc);
- break;
+ break;
}
-case wxScrolledWindow_Scroll: { // wxScrolledWindow::Scroll
+case wxScrolledWindow_Scroll: { // wxScrolledWindow::Scroll
wxScrolledWindow *This = (wxScrolledWindow *) getPtr(bp,memenv); bp += 4;
int * x = (int *) bp; bp += 4;
int * y = (int *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
This->Scroll((int) *x,(int) *y);
- break;
+ break;
}
-case wxScrolledWindow_SetScrollbars: { // wxScrolledWindow::SetScrollbars
+case wxScrolledWindow_SetScrollbars: { // wxScrolledWindow::SetScrollbars
int xPos=0;
int yPos=0;
bool noRefresh=false;
@@ -2345,7 +2345,7 @@ case wxScrolledWindow_SetScrollbars: { // wxScrolledWindow::SetScrollbars
int * noUnitsX = (int *) bp; bp += 4;
int * noUnitsY = (int *) bp; bp += 4;
bp += 4; /* Align */
- while( * (int*) bp) { switch (* (int*) bp) {
+ while( * (int*) bp) { switch (* (int*) bp) {
case 1: {bp += 4;
xPos = (int)*(int *) bp; bp += 4;
} break;
@@ -2355,40 +2355,40 @@ case wxScrolledWindow_SetScrollbars: { // wxScrolledWindow::SetScrollbars
case 3: {bp += 4;
noRefresh = *(bool *) bp; bp += 4;
} break;
- }};
+ }};
if(!This) throw wxe_badarg(0);
This->SetScrollbars((int) *pixelsPerUnitX,(int) *pixelsPerUnitY,(int) *noUnitsX,(int) *noUnitsY,xPos,yPos,noRefresh);
- break;
+ break;
}
-case wxScrolledWindow_SetScrollRate: { // wxScrolledWindow::SetScrollRate
+case wxScrolledWindow_SetScrollRate: { // wxScrolledWindow::SetScrollRate
wxScrolledWindow *This = (wxScrolledWindow *) getPtr(bp,memenv); bp += 4;
int * xstep = (int *) bp; bp += 4;
int * ystep = (int *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
This->SetScrollRate((int) *xstep,(int) *ystep);
- break;
+ break;
}
-case wxScrolledWindow_SetTargetWindow: { // wxScrolledWindow::SetTargetWindow
+case wxScrolledWindow_SetTargetWindow: { // wxScrolledWindow::SetTargetWindow
wxScrolledWindow *This = (wxScrolledWindow *) getPtr(bp,memenv); bp += 4;
wxWindow *target = (wxWindow *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
This->SetTargetWindow(target);
- break;
+ break;
}
-case wxSashWindow_new_0: { // wxSashWindow::wxSashWindow
+case wxSashWindow_new_0: { // wxSashWindow::wxSashWindow
wxSashWindow * Result = new EwxSashWindow();
newPtr((void *) Result, 0, memenv);
rt.addRef(getRef((void *)Result,memenv), "wxSashWindow");
- break;
+ break;
}
-case wxSashWindow_new_2: { // wxSashWindow::wxSashWindow
+case wxSashWindow_new_2: { // wxSashWindow::wxSashWindow
wxWindowID id=wxID_ANY;
wxPoint pos= wxDefaultPosition;
wxSize size= wxDefaultSize;
long style=(0x0040|0x0080)|wxCLIP_CHILDREN;
wxWindow *parent = (wxWindow *) getPtr(bp,memenv); bp += 4;
bp += 4; /* Align */
- while( * (int*) bp) { switch (* (int*) bp) {
+ while( * (int*) bp) { switch (* (int*) bp) {
case 1: {bp += 4;
id = (wxWindowID)*(int *) bp; bp += 4;
} break;
@@ -2407,98 +2407,98 @@ case wxSashWindow_new_2: { // wxSashWindow::wxSashWindow
case 4: {bp += 4;
style = (long)*(int *) bp; bp += 4;
} break;
- }};
+ }};
wxSashWindow * Result = new EwxSashWindow(parent,id,pos,size,style);
newPtr((void *) Result, 0, memenv);
rt.addRef(getRef((void *)Result,memenv), "wxSashWindow");
- break;
+ break;
}
-case wxSashWindow_GetSashVisible: { // wxSashWindow::GetSashVisible
+case wxSashWindow_GetSashVisible: { // wxSashWindow::GetSashVisible
wxSashWindow *This = (wxSashWindow *) getPtr(bp,memenv); bp += 4;
wxSashEdgePosition edge = *(wxSashEdgePosition *) bp; bp += 4;;
if(!This) throw wxe_badarg(0);
bool Result = This->GetSashVisible((wxSashEdgePosition) edge);
rt.addBool(Result);
- break;
+ break;
}
-case wxSashWindow_GetMaximumSizeX: { // wxSashWindow::GetMaximumSizeX
+case wxSashWindow_GetMaximumSizeX: { // wxSashWindow::GetMaximumSizeX
wxSashWindow *This = (wxSashWindow *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
int Result = This->GetMaximumSizeX();
rt.addInt(Result);
- break;
+ break;
}
-case wxSashWindow_GetMaximumSizeY: { // wxSashWindow::GetMaximumSizeY
+case wxSashWindow_GetMaximumSizeY: { // wxSashWindow::GetMaximumSizeY
wxSashWindow *This = (wxSashWindow *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
int Result = This->GetMaximumSizeY();
rt.addInt(Result);
- break;
+ break;
}
-case wxSashWindow_GetMinimumSizeX: { // wxSashWindow::GetMinimumSizeX
+case wxSashWindow_GetMinimumSizeX: { // wxSashWindow::GetMinimumSizeX
wxSashWindow *This = (wxSashWindow *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
int Result = This->GetMinimumSizeX();
rt.addInt(Result);
- break;
+ break;
}
-case wxSashWindow_GetMinimumSizeY: { // wxSashWindow::GetMinimumSizeY
+case wxSashWindow_GetMinimumSizeY: { // wxSashWindow::GetMinimumSizeY
wxSashWindow *This = (wxSashWindow *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
int Result = This->GetMinimumSizeY();
rt.addInt(Result);
- break;
+ break;
}
-case wxSashWindow_SetMaximumSizeX: { // wxSashWindow::SetMaximumSizeX
+case wxSashWindow_SetMaximumSizeX: { // wxSashWindow::SetMaximumSizeX
wxSashWindow *This = (wxSashWindow *) getPtr(bp,memenv); bp += 4;
int * max = (int *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
This->SetMaximumSizeX((int) *max);
- break;
+ break;
}
-case wxSashWindow_SetMaximumSizeY: { // wxSashWindow::SetMaximumSizeY
+case wxSashWindow_SetMaximumSizeY: { // wxSashWindow::SetMaximumSizeY
wxSashWindow *This = (wxSashWindow *) getPtr(bp,memenv); bp += 4;
int * max = (int *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
This->SetMaximumSizeY((int) *max);
- break;
+ break;
}
-case wxSashWindow_SetMinimumSizeX: { // wxSashWindow::SetMinimumSizeX
+case wxSashWindow_SetMinimumSizeX: { // wxSashWindow::SetMinimumSizeX
wxSashWindow *This = (wxSashWindow *) getPtr(bp,memenv); bp += 4;
int * min = (int *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
This->SetMinimumSizeX((int) *min);
- break;
+ break;
}
-case wxSashWindow_SetMinimumSizeY: { // wxSashWindow::SetMinimumSizeY
+case wxSashWindow_SetMinimumSizeY: { // wxSashWindow::SetMinimumSizeY
wxSashWindow *This = (wxSashWindow *) getPtr(bp,memenv); bp += 4;
int * min = (int *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
This->SetMinimumSizeY((int) *min);
- break;
+ break;
}
-case wxSashWindow_SetSashVisible: { // wxSashWindow::SetSashVisible
+case wxSashWindow_SetSashVisible: { // wxSashWindow::SetSashVisible
wxSashWindow *This = (wxSashWindow *) getPtr(bp,memenv); bp += 4;
wxSashEdgePosition edge = *(wxSashEdgePosition *) bp; bp += 4;;
bool * sash = (bool *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
This->SetSashVisible((wxSashEdgePosition) edge,(bool) *sash);
- break;
+ break;
}
-case wxSashLayoutWindow_new_0: { // wxSashLayoutWindow::wxSashLayoutWindow
+case wxSashLayoutWindow_new_0: { // wxSashLayoutWindow::wxSashLayoutWindow
wxSashLayoutWindow * Result = new EwxSashLayoutWindow();
newPtr((void *) Result, 0, memenv);
rt.addRef(getRef((void *)Result,memenv), "wxSashLayoutWindow");
- break;
+ break;
}
-case wxSashLayoutWindow_new_2: { // wxSashLayoutWindow::wxSashLayoutWindow
+case wxSashLayoutWindow_new_2: { // wxSashLayoutWindow::wxSashLayoutWindow
wxWindowID id=wxID_ANY;
wxPoint pos= wxDefaultPosition;
wxSize size= wxDefaultSize;
long style=wxSW_3D|wxCLIP_CHILDREN;
wxWindow *parent = (wxWindow *) getPtr(bp,memenv); bp += 4;
bp += 4; /* Align */
- while( * (int*) bp) { switch (* (int*) bp) {
+ while( * (int*) bp) { switch (* (int*) bp) {
case 1: {bp += 4;
id = (wxWindowID)*(int *) bp; bp += 4;
} break;
@@ -2517,20 +2517,20 @@ case wxSashLayoutWindow_new_2: { // wxSashLayoutWindow::wxSashLayoutWindow
case 4: {bp += 4;
style = (long)*(int *) bp; bp += 4;
} break;
- }};
+ }};
wxSashLayoutWindow * Result = new EwxSashLayoutWindow(parent,id,pos,size,style);
newPtr((void *) Result, 0, memenv);
rt.addRef(getRef((void *)Result,memenv), "wxSashLayoutWindow");
- break;
+ break;
}
-case wxSashLayoutWindow_Create: { // wxSashLayoutWindow::Create
+case wxSashLayoutWindow_Create: { // wxSashLayoutWindow::Create
wxWindowID id=wxID_ANY;
wxPoint pos= wxDefaultPosition;
wxSize size= wxDefaultSize;
long style=wxSW_3D|wxCLIP_CHILDREN;
wxSashLayoutWindow *This = (wxSashLayoutWindow *) getPtr(bp,memenv); bp += 4;
wxWindow *parent = (wxWindow *) getPtr(bp,memenv); bp += 4;
- while( * (int*) bp) { switch (* (int*) bp) {
+ while( * (int*) bp) { switch (* (int*) bp) {
case 1: {bp += 4;
id = (wxWindowID)*(int *) bp; bp += 4;
} break;
@@ -2549,62 +2549,62 @@ case wxSashLayoutWindow_Create: { // wxSashLayoutWindow::Create
case 4: {bp += 4;
style = (long)*(int *) bp; bp += 4;
} break;
- }};
+ }};
if(!This) throw wxe_badarg(0);
bool Result = This->Create(parent,id,pos,size,style);
rt.addBool(Result);
- break;
+ break;
}
-case wxSashLayoutWindow_GetAlignment: { // wxSashLayoutWindow::GetAlignment
+case wxSashLayoutWindow_GetAlignment: { // wxSashLayoutWindow::GetAlignment
wxSashLayoutWindow *This = (wxSashLayoutWindow *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
int Result = This->GetAlignment();
rt.addInt(Result);
- break;
+ break;
}
-case wxSashLayoutWindow_GetOrientation: { // wxSashLayoutWindow::GetOrientation
+case wxSashLayoutWindow_GetOrientation: { // wxSashLayoutWindow::GetOrientation
wxSashLayoutWindow *This = (wxSashLayoutWindow *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
int Result = This->GetOrientation();
rt.addInt(Result);
- break;
+ break;
}
-case wxSashLayoutWindow_SetAlignment: { // wxSashLayoutWindow::SetAlignment
+case wxSashLayoutWindow_SetAlignment: { // wxSashLayoutWindow::SetAlignment
wxSashLayoutWindow *This = (wxSashLayoutWindow *) getPtr(bp,memenv); bp += 4;
wxLayoutAlignment align = *(wxLayoutAlignment *) bp; bp += 4;;
if(!This) throw wxe_badarg(0);
This->SetAlignment((wxLayoutAlignment) align);
- break;
+ break;
}
-case wxSashLayoutWindow_SetDefaultSize: { // wxSashLayoutWindow::SetDefaultSize
+case wxSashLayoutWindow_SetDefaultSize: { // wxSashLayoutWindow::SetDefaultSize
wxSashLayoutWindow *This = (wxSashLayoutWindow *) getPtr(bp,memenv); bp += 4;
int * sizeW = (int *) bp; bp += 4;
int * sizeH = (int *) bp; bp += 4;
wxSize size = wxSize(*sizeW,*sizeH);
if(!This) throw wxe_badarg(0);
This->SetDefaultSize(size);
- break;
+ break;
}
-case wxSashLayoutWindow_SetOrientation: { // wxSashLayoutWindow::SetOrientation
+case wxSashLayoutWindow_SetOrientation: { // wxSashLayoutWindow::SetOrientation
wxSashLayoutWindow *This = (wxSashLayoutWindow *) getPtr(bp,memenv); bp += 4;
wxLayoutOrientation orient = *(wxLayoutOrientation *) bp; bp += 4;;
if(!This) throw wxe_badarg(0);
This->SetOrientation((wxLayoutOrientation) orient);
- break;
+ break;
}
-case wxGrid_new_0: { // wxGrid::wxGrid
+case wxGrid_new_0: { // wxGrid::wxGrid
wxGrid * Result = new EwxGrid();
newPtr((void *) Result, 0, memenv);
rt.addRef(getRef((void *)Result,memenv), "wxGrid");
- break;
+ break;
}
-case wxGrid_new_3: { // wxGrid::wxGrid
+case wxGrid_new_3: { // wxGrid::wxGrid
wxPoint pos= wxDefaultPosition;
wxSize size= wxDefaultSize;
long style=wxWANTS_CHARS;
wxWindow *parent = (wxWindow *) getPtr(bp,memenv); bp += 4;
int * id = (int *) bp; bp += 4;
- while( * (int*) bp) { switch (* (int*) bp) {
+ while( * (int*) bp) { switch (* (int*) bp) {
case 1: {bp += 4;
int * posX = (int *) bp; bp += 4;
int * posY = (int *) bp; bp += 4;
@@ -2620,13 +2620,13 @@ case wxGrid_new_3: { // wxGrid::wxGrid
case 3: {bp += 4;
style = (long)*(int *) bp; bp += 4;
} break;
- }};
+ }};
wxGrid * Result = new EwxGrid(parent,(wxWindowID) *id,pos,size,style);
newPtr((void *) Result, 0, memenv);
rt.addRef(getRef((void *)Result,memenv), "wxGrid");
- break;
+ break;
}
-case wxGrid_new_4: { // wxGrid::wxGrid
+case wxGrid_new_4: { // wxGrid::wxGrid
int w=wxDefaultCoord;
int h=wxDefaultCoord;
long style=wxWANTS_CHARS;
@@ -2634,7 +2634,7 @@ case wxGrid_new_4: { // wxGrid::wxGrid
int * x = (int *) bp; bp += 4;
int * y = (int *) bp; bp += 4;
bp += 4; /* Align */
- while( * (int*) bp) { switch (* (int*) bp) {
+ while( * (int*) bp) { switch (* (int*) bp) {
case 1: {bp += 4;
w = (int)*(int *) bp; bp += 4;
} break;
@@ -2644,113 +2644,113 @@ case wxGrid_new_4: { // wxGrid::wxGrid
case 3: {bp += 4;
style = (long)*(int *) bp; bp += 4;
} break;
- }};
+ }};
wxGrid * Result = new EwxGrid(parent,(int) *x,(int) *y,w,h,style);
newPtr((void *) Result, 0, memenv);
rt.addRef(getRef((void *)Result,memenv), "wxGrid");
- break;
+ break;
}
-case wxGrid_AppendCols: { // wxGrid::AppendCols
+case wxGrid_AppendCols: { // wxGrid::AppendCols
int numCols=1;
bool updateLabels=true;
wxGrid *This = (wxGrid *) getPtr(bp,memenv); bp += 4;
bp += 4; /* Align */
- while( * (int*) bp) { switch (* (int*) bp) {
+ while( * (int*) bp) { switch (* (int*) bp) {
case 1: {bp += 4;
numCols = (int)*(int *) bp; bp += 4;
} break;
case 2: {bp += 4;
updateLabels = *(bool *) bp; bp += 4;
} break;
- }};
+ }};
if(!This) throw wxe_badarg(0);
bool Result = This->AppendCols(numCols,updateLabels);
rt.addBool(Result);
- break;
+ break;
}
-case wxGrid_AppendRows: { // wxGrid::AppendRows
+case wxGrid_AppendRows: { // wxGrid::AppendRows
int numRows=1;
bool updateLabels=true;
wxGrid *This = (wxGrid *) getPtr(bp,memenv); bp += 4;
bp += 4; /* Align */
- while( * (int*) bp) { switch (* (int*) bp) {
+ while( * (int*) bp) { switch (* (int*) bp) {
case 1: {bp += 4;
numRows = (int)*(int *) bp; bp += 4;
} break;
case 2: {bp += 4;
updateLabels = *(bool *) bp; bp += 4;
} break;
- }};
+ }};
if(!This) throw wxe_badarg(0);
bool Result = This->AppendRows(numRows,updateLabels);
rt.addBool(Result);
- break;
+ break;
}
-case wxGrid_AutoSize: { // wxGrid::AutoSize
+case wxGrid_AutoSize: { // wxGrid::AutoSize
wxGrid *This = (wxGrid *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
This->AutoSize();
- break;
+ break;
}
-case wxGrid_AutoSizeColumn: { // wxGrid::AutoSizeColumn
+case wxGrid_AutoSizeColumn: { // wxGrid::AutoSizeColumn
bool setAsMin=true;
wxGrid *This = (wxGrid *) getPtr(bp,memenv); bp += 4;
int * col = (int *) bp; bp += 4;
- while( * (int*) bp) { switch (* (int*) bp) {
+ while( * (int*) bp) { switch (* (int*) bp) {
case 1: {bp += 4;
setAsMin = *(bool *) bp; bp += 4;
} break;
- }};
+ }};
if(!This) throw wxe_badarg(0);
This->AutoSizeColumn((int) *col,setAsMin);
- break;
+ break;
}
-case wxGrid_AutoSizeColumns: { // wxGrid::AutoSizeColumns
+case wxGrid_AutoSizeColumns: { // wxGrid::AutoSizeColumns
bool setAsMin=true;
wxGrid *This = (wxGrid *) getPtr(bp,memenv); bp += 4;
bp += 4; /* Align */
- while( * (int*) bp) { switch (* (int*) bp) {
+ while( * (int*) bp) { switch (* (int*) bp) {
case 1: {bp += 4;
setAsMin = *(bool *) bp; bp += 4;
} break;
- }};
+ }};
if(!This) throw wxe_badarg(0);
This->AutoSizeColumns(setAsMin);
- break;
+ break;
}
-case wxGrid_AutoSizeRow: { // wxGrid::AutoSizeRow
+case wxGrid_AutoSizeRow: { // wxGrid::AutoSizeRow
bool setAsMin=true;
wxGrid *This = (wxGrid *) getPtr(bp,memenv); bp += 4;
int * row = (int *) bp; bp += 4;
- while( * (int*) bp) { switch (* (int*) bp) {
+ while( * (int*) bp) { switch (* (int*) bp) {
case 1: {bp += 4;
setAsMin = *(bool *) bp; bp += 4;
} break;
- }};
+ }};
if(!This) throw wxe_badarg(0);
This->AutoSizeRow((int) *row,setAsMin);
- break;
+ break;
}
-case wxGrid_AutoSizeRows: { // wxGrid::AutoSizeRows
+case wxGrid_AutoSizeRows: { // wxGrid::AutoSizeRows
bool setAsMin=true;
wxGrid *This = (wxGrid *) getPtr(bp,memenv); bp += 4;
bp += 4; /* Align */
- while( * (int*) bp) { switch (* (int*) bp) {
+ while( * (int*) bp) { switch (* (int*) bp) {
case 1: {bp += 4;
setAsMin = *(bool *) bp; bp += 4;
} break;
- }};
+ }};
if(!This) throw wxe_badarg(0);
This->AutoSizeRows(setAsMin);
- break;
+ break;
}
-case wxGrid_BeginBatch: { // wxGrid::BeginBatch
+case wxGrid_BeginBatch: { // wxGrid::BeginBatch
wxGrid *This = (wxGrid *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
This->BeginBatch();
- break;
+ break;
}
-case wxGrid_BlockToDeviceRect: { // wxGrid::BlockToDeviceRect
+case wxGrid_BlockToDeviceRect: { // wxGrid::BlockToDeviceRect
wxGrid *This = (wxGrid *) getPtr(bp,memenv); bp += 4;
int * topLeftR = (int *) bp; bp += 4;
int * topLeftC = (int *) bp; bp += 4;
@@ -2761,46 +2761,46 @@ case wxGrid_BlockToDeviceRect: { // wxGrid::BlockToDeviceRect
if(!This) throw wxe_badarg(0);
wxRect Result = This->BlockToDeviceRect(topLeft,bottomRight);
rt.add(Result);
- break;
+ break;
}
-case wxGrid_CanDragColSize: { // wxGrid::CanDragColSize
+case wxGrid_CanDragColSize: { // wxGrid::CanDragColSize
wxGrid *This = (wxGrid *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
bool Result = This->CanDragColSize();
rt.addBool(Result);
- break;
+ break;
}
-case wxGrid_CanDragRowSize: { // wxGrid::CanDragRowSize
+case wxGrid_CanDragRowSize: { // wxGrid::CanDragRowSize
wxGrid *This = (wxGrid *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
bool Result = This->CanDragRowSize();
rt.addBool(Result);
- break;
+ break;
}
-case wxGrid_CanDragGridSize: { // wxGrid::CanDragGridSize
+case wxGrid_CanDragGridSize: { // wxGrid::CanDragGridSize
wxGrid *This = (wxGrid *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
bool Result = This->CanDragGridSize();
rt.addBool(Result);
- break;
+ break;
}
-case wxGrid_CanEnableCellControl: { // wxGrid::CanEnableCellControl
+case wxGrid_CanEnableCellControl: { // wxGrid::CanEnableCellControl
wxGrid *This = (wxGrid *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
bool Result = This->CanEnableCellControl();
rt.addBool(Result);
- break;
+ break;
}
-case wxGrid_CellToRect_2: { // wxGrid::CellToRect
+case wxGrid_CellToRect_2: { // wxGrid::CellToRect
wxGrid *This = (wxGrid *) getPtr(bp,memenv); bp += 4;
int * row = (int *) bp; bp += 4;
int * col = (int *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
wxRect Result = This->CellToRect((int) *row,(int) *col);
rt.add(Result);
- break;
+ break;
}
-case wxGrid_CellToRect_1: { // wxGrid::CellToRect
+case wxGrid_CellToRect_1: { // wxGrid::CellToRect
wxGrid *This = (wxGrid *) getPtr(bp,memenv); bp += 4;
int * coordsR = (int *) bp; bp += 4;
int * coordsC = (int *) bp; bp += 4;
@@ -2808,43 +2808,43 @@ case wxGrid_CellToRect_1: { // wxGrid::CellToRect
if(!This) throw wxe_badarg(0);
wxRect Result = This->CellToRect(coords);
rt.add(Result);
- break;
+ break;
}
-case wxGrid_ClearGrid: { // wxGrid::ClearGrid
+case wxGrid_ClearGrid: { // wxGrid::ClearGrid
wxGrid *This = (wxGrid *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
This->ClearGrid();
- break;
+ break;
}
-case wxGrid_ClearSelection: { // wxGrid::ClearSelection
+case wxGrid_ClearSelection: { // wxGrid::ClearSelection
wxGrid *This = (wxGrid *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
This->ClearSelection();
- break;
+ break;
}
-case wxGrid_CreateGrid: { // wxGrid::CreateGrid
+case wxGrid_CreateGrid: { // wxGrid::CreateGrid
wxGrid::wxGridSelectionModes selmode=wxGrid::wxGridSelectCells;
wxGrid *This = (wxGrid *) getPtr(bp,memenv); bp += 4;
int * numRows = (int *) bp; bp += 4;
int * numCols = (int *) bp; bp += 4;
bp += 4; /* Align */
- while( * (int*) bp) { switch (* (int*) bp) {
+ while( * (int*) bp) { switch (* (int*) bp) {
case 1: {bp += 4;
selmode = *(wxGrid::wxGridSelectionModes *) bp; bp += 4;;
} break;
- }};
+ }};
if(!This) throw wxe_badarg(0);
bool Result = This->CreateGrid((int) *numRows,(int) *numCols,(wxGrid::wxGridSelectionModes) selmode);
rt.addBool(Result);
- break;
+ break;
}
-case wxGrid_DeleteCols: { // wxGrid::DeleteCols
+case wxGrid_DeleteCols: { // wxGrid::DeleteCols
int pos=0;
int numCols=1;
bool updateLabels=true;
wxGrid *This = (wxGrid *) getPtr(bp,memenv); bp += 4;
bp += 4; /* Align */
- while( * (int*) bp) { switch (* (int*) bp) {
+ while( * (int*) bp) { switch (* (int*) bp) {
case 1: {bp += 4;
pos = (int)*(int *) bp; bp += 4;
} break;
@@ -2854,19 +2854,19 @@ case wxGrid_DeleteCols: { // wxGrid::DeleteCols
case 3: {bp += 4;
updateLabels = *(bool *) bp; bp += 4;
} break;
- }};
+ }};
if(!This) throw wxe_badarg(0);
bool Result = This->DeleteCols(pos,numCols,updateLabels);
rt.addBool(Result);
- break;
+ break;
}
-case wxGrid_DeleteRows: { // wxGrid::DeleteRows
+case wxGrid_DeleteRows: { // wxGrid::DeleteRows
int pos=0;
int numRows=1;
bool updateLabels=true;
wxGrid *This = (wxGrid *) getPtr(bp,memenv); bp += 4;
bp += 4; /* Align */
- while( * (int*) bp) { switch (* (int*) bp) {
+ while( * (int*) bp) { switch (* (int*) bp) {
case 1: {bp += 4;
pos = (int)*(int *) bp; bp += 4;
} break;
@@ -2876,134 +2876,134 @@ case wxGrid_DeleteRows: { // wxGrid::DeleteRows
case 3: {bp += 4;
updateLabels = *(bool *) bp; bp += 4;
} break;
- }};
+ }};
if(!This) throw wxe_badarg(0);
bool Result = This->DeleteRows(pos,numRows,updateLabels);
rt.addBool(Result);
- break;
+ break;
}
-case wxGrid_DisableCellEditControl: { // wxGrid::DisableCellEditControl
+case wxGrid_DisableCellEditControl: { // wxGrid::DisableCellEditControl
wxGrid *This = (wxGrid *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
This->DisableCellEditControl();
- break;
+ break;
}
-case wxGrid_DisableDragColSize: { // wxGrid::DisableDragColSize
+case wxGrid_DisableDragColSize: { // wxGrid::DisableDragColSize
wxGrid *This = (wxGrid *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
This->DisableDragColSize();
- break;
+ break;
}
-case wxGrid_DisableDragGridSize: { // wxGrid::DisableDragGridSize
+case wxGrid_DisableDragGridSize: { // wxGrid::DisableDragGridSize
wxGrid *This = (wxGrid *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
This->DisableDragGridSize();
- break;
+ break;
}
-case wxGrid_DisableDragRowSize: { // wxGrid::DisableDragRowSize
+case wxGrid_DisableDragRowSize: { // wxGrid::DisableDragRowSize
wxGrid *This = (wxGrid *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
This->DisableDragRowSize();
- break;
+ break;
}
-case wxGrid_EnableCellEditControl: { // wxGrid::EnableCellEditControl
+case wxGrid_EnableCellEditControl: { // wxGrid::EnableCellEditControl
bool enable=true;
wxGrid *This = (wxGrid *) getPtr(bp,memenv); bp += 4;
bp += 4; /* Align */
- while( * (int*) bp) { switch (* (int*) bp) {
+ while( * (int*) bp) { switch (* (int*) bp) {
case 1: {bp += 4;
enable = *(bool *) bp; bp += 4;
} break;
- }};
+ }};
if(!This) throw wxe_badarg(0);
This->EnableCellEditControl(enable);
- break;
+ break;
}
-case wxGrid_EnableDragColSize: { // wxGrid::EnableDragColSize
+case wxGrid_EnableDragColSize: { // wxGrid::EnableDragColSize
bool enable=true;
wxGrid *This = (wxGrid *) getPtr(bp,memenv); bp += 4;
bp += 4; /* Align */
- while( * (int*) bp) { switch (* (int*) bp) {
+ while( * (int*) bp) { switch (* (int*) bp) {
case 1: {bp += 4;
enable = *(bool *) bp; bp += 4;
} break;
- }};
+ }};
if(!This) throw wxe_badarg(0);
This->EnableDragColSize(enable);
- break;
+ break;
}
-case wxGrid_EnableDragGridSize: { // wxGrid::EnableDragGridSize
+case wxGrid_EnableDragGridSize: { // wxGrid::EnableDragGridSize
bool enable=true;
wxGrid *This = (wxGrid *) getPtr(bp,memenv); bp += 4;
bp += 4; /* Align */
- while( * (int*) bp) { switch (* (int*) bp) {
+ while( * (int*) bp) { switch (* (int*) bp) {
case 1: {bp += 4;
enable = *(bool *) bp; bp += 4;
} break;
- }};
+ }};
if(!This) throw wxe_badarg(0);
This->EnableDragGridSize(enable);
- break;
+ break;
}
-case wxGrid_EnableDragRowSize: { // wxGrid::EnableDragRowSize
+case wxGrid_EnableDragRowSize: { // wxGrid::EnableDragRowSize
bool enable=true;
wxGrid *This = (wxGrid *) getPtr(bp,memenv); bp += 4;
bp += 4; /* Align */
- while( * (int*) bp) { switch (* (int*) bp) {
+ while( * (int*) bp) { switch (* (int*) bp) {
case 1: {bp += 4;
enable = *(bool *) bp; bp += 4;
} break;
- }};
+ }};
if(!This) throw wxe_badarg(0);
This->EnableDragRowSize(enable);
- break;
+ break;
}
-case wxGrid_EnableEditing: { // wxGrid::EnableEditing
+case wxGrid_EnableEditing: { // wxGrid::EnableEditing
wxGrid *This = (wxGrid *) getPtr(bp,memenv); bp += 4;
bool * edit = (bool *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
This->EnableEditing((bool) *edit);
- break;
+ break;
}
-case wxGrid_EnableGridLines: { // wxGrid::EnableGridLines
+case wxGrid_EnableGridLines: { // wxGrid::EnableGridLines
bool enable=true;
wxGrid *This = (wxGrid *) getPtr(bp,memenv); bp += 4;
bp += 4; /* Align */
- while( * (int*) bp) { switch (* (int*) bp) {
+ while( * (int*) bp) { switch (* (int*) bp) {
case 1: {bp += 4;
enable = *(bool *) bp; bp += 4;
} break;
- }};
+ }};
if(!This) throw wxe_badarg(0);
This->EnableGridLines(enable);
- break;
+ break;
}
-case wxGrid_EndBatch: { // wxGrid::EndBatch
+case wxGrid_EndBatch: { // wxGrid::EndBatch
wxGrid *This = (wxGrid *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
This->EndBatch();
- break;
+ break;
}
-case wxGrid_Fit: { // wxGrid::Fit
+case wxGrid_Fit: { // wxGrid::Fit
wxGrid *This = (wxGrid *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
This->Fit();
- break;
+ break;
}
-case wxGrid_ForceRefresh: { // wxGrid::ForceRefresh
+case wxGrid_ForceRefresh: { // wxGrid::ForceRefresh
wxGrid *This = (wxGrid *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
This->ForceRefresh();
- break;
+ break;
}
-case wxGrid_GetBatchCount: { // wxGrid::GetBatchCount
+case wxGrid_GetBatchCount: { // wxGrid::GetBatchCount
wxGrid *This = (wxGrid *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
int Result = This->GetBatchCount();
rt.addInt(Result);
- break;
+ break;
}
-case wxGrid_GetCellAlignment: { // wxGrid::GetCellAlignment
+case wxGrid_GetCellAlignment: { // wxGrid::GetCellAlignment
int horiz;
int vert;
wxGrid *This = (wxGrid *) getPtr(bp,memenv); bp += 4;
@@ -3014,63 +3014,63 @@ case wxGrid_GetCellAlignment: { // wxGrid::GetCellAlignment
rt.addInt(horiz);
rt.addInt(vert);
rt.addTupleCount(2);
- break;
+ break;
}
-case wxGrid_GetCellBackgroundColour: { // wxGrid::GetCellBackgroundColour
+case wxGrid_GetCellBackgroundColour: { // wxGrid::GetCellBackgroundColour
wxGrid *This = (wxGrid *) getPtr(bp,memenv); bp += 4;
int * row = (int *) bp; bp += 4;
int * col = (int *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
wxColour Result = This->GetCellBackgroundColour((int) *row,(int) *col);
rt.add(Result);
- break;
+ break;
}
-case wxGrid_GetCellEditor: { // wxGrid::GetCellEditor
+case wxGrid_GetCellEditor: { // wxGrid::GetCellEditor
wxGrid *This = (wxGrid *) getPtr(bp,memenv); bp += 4;
int * row = (int *) bp; bp += 4;
int * col = (int *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
wxGridCellEditor * Result = (wxGridCellEditor*)This->GetCellEditor((int) *row,(int) *col);
rt.addRef(getRef((void *)Result,memenv), "wxGridCellEditor");
- break;
+ break;
}
-case wxGrid_GetCellFont: { // wxGrid::GetCellFont
+case wxGrid_GetCellFont: { // wxGrid::GetCellFont
wxGrid *This = (wxGrid *) getPtr(bp,memenv); bp += 4;
int * row = (int *) bp; bp += 4;
int * col = (int *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
wxFont * Result = new wxFont(This->GetCellFont((int) *row,(int) *col)); newPtr((void *) Result,3, memenv);;
rt.addRef(getRef((void *)Result,memenv), "wxFont");
- break;
+ break;
}
-case wxGrid_GetCellRenderer: { // wxGrid::GetCellRenderer
+case wxGrid_GetCellRenderer: { // wxGrid::GetCellRenderer
wxGrid *This = (wxGrid *) getPtr(bp,memenv); bp += 4;
int * row = (int *) bp; bp += 4;
int * col = (int *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
wxGridCellRenderer * Result = (wxGridCellRenderer*)This->GetCellRenderer((int) *row,(int) *col);
rt.addRef(getRef((void *)Result,memenv), "wxGridCellRenderer");
- break;
+ break;
}
-case wxGrid_GetCellTextColour: { // wxGrid::GetCellTextColour
+case wxGrid_GetCellTextColour: { // wxGrid::GetCellTextColour
wxGrid *This = (wxGrid *) getPtr(bp,memenv); bp += 4;
int * row = (int *) bp; bp += 4;
int * col = (int *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
wxColour Result = This->GetCellTextColour((int) *row,(int) *col);
rt.add(Result);
- break;
+ break;
}
-case wxGrid_GetCellValue_2: { // wxGrid::GetCellValue
+case wxGrid_GetCellValue_2: { // wxGrid::GetCellValue
wxGrid *This = (wxGrid *) getPtr(bp,memenv); bp += 4;
int * row = (int *) bp; bp += 4;
int * col = (int *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
wxString Result = This->GetCellValue((int) *row,(int) *col);
rt.add(Result);
- break;
+ break;
}
-case wxGrid_GetCellValue_1: { // wxGrid::GetCellValue
+case wxGrid_GetCellValue_1: { // wxGrid::GetCellValue
wxGrid *This = (wxGrid *) getPtr(bp,memenv); bp += 4;
int * coordsR = (int *) bp; bp += 4;
int * coordsC = (int *) bp; bp += 4;
@@ -3078,9 +3078,9 @@ case wxGrid_GetCellValue_1: { // wxGrid::GetCellValue
if(!This) throw wxe_badarg(0);
wxString Result = This->GetCellValue(coords);
rt.add(Result);
- break;
+ break;
}
-case wxGrid_GetColLabelAlignment: { // wxGrid::GetColLabelAlignment
+case wxGrid_GetColLabelAlignment: { // wxGrid::GetColLabelAlignment
int horiz;
int vert;
wxGrid *This = (wxGrid *) getPtr(bp,memenv); bp += 4;
@@ -3089,31 +3089,31 @@ case wxGrid_GetColLabelAlignment: { // wxGrid::GetColLabelAlignment
rt.addInt(horiz);
rt.addInt(vert);
rt.addTupleCount(2);
- break;
+ break;
}
-case wxGrid_GetColLabelSize: { // wxGrid::GetColLabelSize
+case wxGrid_GetColLabelSize: { // wxGrid::GetColLabelSize
wxGrid *This = (wxGrid *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
int Result = This->GetColLabelSize();
rt.addInt(Result);
- break;
+ break;
}
-case wxGrid_GetColLabelValue: { // wxGrid::GetColLabelValue
+case wxGrid_GetColLabelValue: { // wxGrid::GetColLabelValue
wxGrid *This = (wxGrid *) getPtr(bp,memenv); bp += 4;
int * col = (int *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
wxString Result = This->GetColLabelValue((int) *col);
rt.add(Result);
- break;
+ break;
}
-case wxGrid_GetColMinimalAcceptableWidth: { // wxGrid::GetColMinimalAcceptableWidth
+case wxGrid_GetColMinimalAcceptableWidth: { // wxGrid::GetColMinimalAcceptableWidth
wxGrid *This = (wxGrid *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
int Result = This->GetColMinimalAcceptableWidth();
rt.addInt(Result);
- break;
+ break;
}
-case wxGrid_GetDefaultCellAlignment: { // wxGrid::GetDefaultCellAlignment
+case wxGrid_GetDefaultCellAlignment: { // wxGrid::GetDefaultCellAlignment
int horiz;
int vert;
wxGrid *This = (wxGrid *) getPtr(bp,memenv); bp += 4;
@@ -3122,60 +3122,60 @@ case wxGrid_GetDefaultCellAlignment: { // wxGrid::GetDefaultCellAlignment
rt.addInt(horiz);
rt.addInt(vert);
rt.addTupleCount(2);
- break;
+ break;
}
-case wxGrid_GetDefaultCellBackgroundColour: { // wxGrid::GetDefaultCellBackgroundColour
+case wxGrid_GetDefaultCellBackgroundColour: { // wxGrid::GetDefaultCellBackgroundColour
wxGrid *This = (wxGrid *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
wxColour Result = This->GetDefaultCellBackgroundColour();
rt.add(Result);
- break;
+ break;
}
-case wxGrid_GetDefaultCellFont: { // wxGrid::GetDefaultCellFont
+case wxGrid_GetDefaultCellFont: { // wxGrid::GetDefaultCellFont
wxGrid *This = (wxGrid *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
wxFont * Result = new wxFont(This->GetDefaultCellFont()); newPtr((void *) Result,3, memenv);;
rt.addRef(getRef((void *)Result,memenv), "wxFont");
- break;
+ break;
}
-case wxGrid_GetDefaultCellTextColour: { // wxGrid::GetDefaultCellTextColour
+case wxGrid_GetDefaultCellTextColour: { // wxGrid::GetDefaultCellTextColour
wxGrid *This = (wxGrid *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
wxColour Result = This->GetDefaultCellTextColour();
rt.add(Result);
- break;
+ break;
}
-case wxGrid_GetDefaultColLabelSize: { // wxGrid::GetDefaultColLabelSize
+case wxGrid_GetDefaultColLabelSize: { // wxGrid::GetDefaultColLabelSize
wxGrid *This = (wxGrid *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
int Result = This->GetDefaultColLabelSize();
rt.addInt(Result);
- break;
+ break;
}
-case wxGrid_GetDefaultColSize: { // wxGrid::GetDefaultColSize
+case wxGrid_GetDefaultColSize: { // wxGrid::GetDefaultColSize
wxGrid *This = (wxGrid *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
int Result = This->GetDefaultColSize();
rt.addInt(Result);
- break;
+ break;
}
-case wxGrid_GetDefaultEditor: { // wxGrid::GetDefaultEditor
+case wxGrid_GetDefaultEditor: { // wxGrid::GetDefaultEditor
wxGrid *This = (wxGrid *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
wxGridCellEditor * Result = (wxGridCellEditor*)This->GetDefaultEditor();
rt.addRef(getRef((void *)Result,memenv), "wxGridCellEditor");
- break;
+ break;
}
-case wxGrid_GetDefaultEditorForCell_2: { // wxGrid::GetDefaultEditorForCell
+case wxGrid_GetDefaultEditorForCell_2: { // wxGrid::GetDefaultEditorForCell
wxGrid *This = (wxGrid *) getPtr(bp,memenv); bp += 4;
int * row = (int *) bp; bp += 4;
int * col = (int *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
wxGridCellEditor * Result = (wxGridCellEditor*)This->GetDefaultEditorForCell((int) *row,(int) *col);
rt.addRef(getRef((void *)Result,memenv), "wxGridCellEditor");
- break;
+ break;
}
-case wxGrid_GetDefaultEditorForCell_1: { // wxGrid::GetDefaultEditorForCell
+case wxGrid_GetDefaultEditorForCell_1: { // wxGrid::GetDefaultEditorForCell
wxGrid *This = (wxGrid *) getPtr(bp,memenv); bp += 4;
int * cR = (int *) bp; bp += 4;
int * cC = (int *) bp; bp += 4;
@@ -3183,9 +3183,9 @@ case wxGrid_GetDefaultEditorForCell_1: { // wxGrid::GetDefaultEditorForCell
if(!This) throw wxe_badarg(0);
wxGridCellEditor * Result = (wxGridCellEditor*)This->GetDefaultEditorForCell(c);
rt.addRef(getRef((void *)Result,memenv), "wxGridCellEditor");
- break;
+ break;
}
-case wxGrid_GetDefaultEditorForType: { // wxGrid::GetDefaultEditorForType
+case wxGrid_GetDefaultEditorForType: { // wxGrid::GetDefaultEditorForType
wxGrid *This = (wxGrid *) getPtr(bp,memenv); bp += 4;
int * typeNameLen = (int *) bp; bp += 4;
wxString typeName = wxString(bp, wxConvUTF8);
@@ -3193,25 +3193,25 @@ case wxGrid_GetDefaultEditorForType: { // wxGrid::GetDefaultEditorForType
if(!This) throw wxe_badarg(0);
wxGridCellEditor * Result = (wxGridCellEditor*)This->GetDefaultEditorForType(typeName);
rt.addRef(getRef((void *)Result,memenv), "wxGridCellEditor");
- break;
+ break;
}
-case wxGrid_GetDefaultRenderer: { // wxGrid::GetDefaultRenderer
+case wxGrid_GetDefaultRenderer: { // wxGrid::GetDefaultRenderer
wxGrid *This = (wxGrid *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
wxGridCellRenderer * Result = (wxGridCellRenderer*)This->GetDefaultRenderer();
rt.addRef(getRef((void *)Result,memenv), "wxGridCellRenderer");
- break;
+ break;
}
-case wxGrid_GetDefaultRendererForCell: { // wxGrid::GetDefaultRendererForCell
+case wxGrid_GetDefaultRendererForCell: { // wxGrid::GetDefaultRendererForCell
wxGrid *This = (wxGrid *) getPtr(bp,memenv); bp += 4;
int * row = (int *) bp; bp += 4;
int * col = (int *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
wxGridCellRenderer * Result = (wxGridCellRenderer*)This->GetDefaultRendererForCell((int) *row,(int) *col);
rt.addRef(getRef((void *)Result,memenv), "wxGridCellRenderer");
- break;
+ break;
}
-case wxGrid_GetDefaultRendererForType: { // wxGrid::GetDefaultRendererForType
+case wxGrid_GetDefaultRendererForType: { // wxGrid::GetDefaultRendererForType
wxGrid *This = (wxGrid *) getPtr(bp,memenv); bp += 4;
int * typeNameLen = (int *) bp; bp += 4;
wxString typeName = wxString(bp, wxConvUTF8);
@@ -3219,102 +3219,102 @@ case wxGrid_GetDefaultRendererForType: { // wxGrid::GetDefaultRendererForType
if(!This) throw wxe_badarg(0);
wxGridCellRenderer * Result = (wxGridCellRenderer*)This->GetDefaultRendererForType(typeName);
rt.addRef(getRef((void *)Result,memenv), "wxGridCellRenderer");
- break;
+ break;
}
-case wxGrid_GetDefaultRowLabelSize: { // wxGrid::GetDefaultRowLabelSize
+case wxGrid_GetDefaultRowLabelSize: { // wxGrid::GetDefaultRowLabelSize
wxGrid *This = (wxGrid *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
int Result = This->GetDefaultRowLabelSize();
rt.addInt(Result);
- break;
+ break;
}
-case wxGrid_GetDefaultRowSize: { // wxGrid::GetDefaultRowSize
+case wxGrid_GetDefaultRowSize: { // wxGrid::GetDefaultRowSize
wxGrid *This = (wxGrid *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
int Result = This->GetDefaultRowSize();
rt.addInt(Result);
- break;
+ break;
}
-case wxGrid_GetGridCursorCol: { // wxGrid::GetGridCursorCol
+case wxGrid_GetGridCursorCol: { // wxGrid::GetGridCursorCol
wxGrid *This = (wxGrid *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
int Result = This->GetGridCursorCol();
rt.addInt(Result);
- break;
+ break;
}
-case wxGrid_GetGridCursorRow: { // wxGrid::GetGridCursorRow
+case wxGrid_GetGridCursorRow: { // wxGrid::GetGridCursorRow
wxGrid *This = (wxGrid *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
int Result = This->GetGridCursorRow();
rt.addInt(Result);
- break;
+ break;
}
-case wxGrid_GetGridLineColour: { // wxGrid::GetGridLineColour
+case wxGrid_GetGridLineColour: { // wxGrid::GetGridLineColour
wxGrid *This = (wxGrid *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
wxColour Result = This->GetGridLineColour();
rt.add(Result);
- break;
+ break;
}
-case wxGrid_GridLinesEnabled: { // wxGrid::GridLinesEnabled
+case wxGrid_GridLinesEnabled: { // wxGrid::GridLinesEnabled
wxGrid *This = (wxGrid *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
bool Result = This->GridLinesEnabled();
rt.addBool(Result);
- break;
+ break;
}
-case wxGrid_GetLabelBackgroundColour: { // wxGrid::GetLabelBackgroundColour
+case wxGrid_GetLabelBackgroundColour: { // wxGrid::GetLabelBackgroundColour
wxGrid *This = (wxGrid *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
wxColour Result = This->GetLabelBackgroundColour();
rt.add(Result);
- break;
+ break;
}
-case wxGrid_GetLabelFont: { // wxGrid::GetLabelFont
+case wxGrid_GetLabelFont: { // wxGrid::GetLabelFont
wxGrid *This = (wxGrid *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
wxFont * Result = new wxFont(This->GetLabelFont()); newPtr((void *) Result,3, memenv);;
rt.addRef(getRef((void *)Result,memenv), "wxFont");
- break;
+ break;
}
-case wxGrid_GetLabelTextColour: { // wxGrid::GetLabelTextColour
+case wxGrid_GetLabelTextColour: { // wxGrid::GetLabelTextColour
wxGrid *This = (wxGrid *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
wxColour Result = This->GetLabelTextColour();
rt.add(Result);
- break;
+ break;
}
-case wxGrid_GetNumberCols: { // wxGrid::GetNumberCols
+case wxGrid_GetNumberCols: { // wxGrid::GetNumberCols
wxGrid *This = (wxGrid *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
int Result = This->GetNumberCols();
rt.addInt(Result);
- break;
+ break;
}
-case wxGrid_GetNumberRows: { // wxGrid::GetNumberRows
+case wxGrid_GetNumberRows: { // wxGrid::GetNumberRows
wxGrid *This = (wxGrid *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
int Result = This->GetNumberRows();
rt.addInt(Result);
- break;
+ break;
}
-case wxGrid_GetOrCreateCellAttr: { // wxGrid::GetOrCreateCellAttr
+case wxGrid_GetOrCreateCellAttr: { // wxGrid::GetOrCreateCellAttr
wxGrid *This = (wxGrid *) getPtr(bp,memenv); bp += 4;
int * row = (int *) bp; bp += 4;
int * col = (int *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
wxGridCellAttr * Result = (wxGridCellAttr*)This->GetOrCreateCellAttr((int) *row,(int) *col);
rt.addRef(getRef((void *)Result,memenv), "wxGridCellAttr");
- break;
+ break;
}
-case wxGrid_GetRowMinimalAcceptableHeight: { // wxGrid::GetRowMinimalAcceptableHeight
+case wxGrid_GetRowMinimalAcceptableHeight: { // wxGrid::GetRowMinimalAcceptableHeight
wxGrid *This = (wxGrid *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
int Result = This->GetRowMinimalAcceptableHeight();
rt.addInt(Result);
- break;
+ break;
}
-case wxGrid_GetRowLabelAlignment: { // wxGrid::GetRowLabelAlignment
+case wxGrid_GetRowLabelAlignment: { // wxGrid::GetRowLabelAlignment
int horiz;
int vert;
wxGrid *This = (wxGrid *) getPtr(bp,memenv); bp += 4;
@@ -3323,46 +3323,46 @@ case wxGrid_GetRowLabelAlignment: { // wxGrid::GetRowLabelAlignment
rt.addInt(horiz);
rt.addInt(vert);
rt.addTupleCount(2);
- break;
+ break;
}
-case wxGrid_GetRowLabelSize: { // wxGrid::GetRowLabelSize
+case wxGrid_GetRowLabelSize: { // wxGrid::GetRowLabelSize
wxGrid *This = (wxGrid *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
int Result = This->GetRowLabelSize();
rt.addInt(Result);
- break;
+ break;
}
-case wxGrid_GetRowLabelValue: { // wxGrid::GetRowLabelValue
+case wxGrid_GetRowLabelValue: { // wxGrid::GetRowLabelValue
wxGrid *This = (wxGrid *) getPtr(bp,memenv); bp += 4;
int * row = (int *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
wxString Result = This->GetRowLabelValue((int) *row);
rt.add(Result);
- break;
+ break;
}
-case wxGrid_GetRowSize: { // wxGrid::GetRowSize
+case wxGrid_GetRowSize: { // wxGrid::GetRowSize
wxGrid *This = (wxGrid *) getPtr(bp,memenv); bp += 4;
int * row = (int *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
int Result = This->GetRowSize((int) *row);
rt.addInt(Result);
- break;
+ break;
}
-case wxGrid_GetScrollLineX: { // wxGrid::GetScrollLineX
+case wxGrid_GetScrollLineX: { // wxGrid::GetScrollLineX
wxGrid *This = (wxGrid *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
int Result = This->GetScrollLineX();
rt.addInt(Result);
- break;
+ break;
}
-case wxGrid_GetScrollLineY: { // wxGrid::GetScrollLineY
+case wxGrid_GetScrollLineY: { // wxGrid::GetScrollLineY
wxGrid *This = (wxGrid *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
int Result = This->GetScrollLineY();
rt.addInt(Result);
- break;
+ break;
}
-case wxGrid_GetSelectedCells: { // wxGrid::GetSelectedCells
+case wxGrid_GetSelectedCells: { // wxGrid::GetSelectedCells
wxGrid *This = (wxGrid *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
wxGridCellCoordsArray Result = This->GetSelectedCells();
@@ -3370,30 +3370,30 @@ case wxGrid_GetSelectedCells: { // wxGrid::GetSelectedCells
rt.add(Result[i]);
}
rt.endList(Result.GetCount());
- break;
+ break;
}
-case wxGrid_GetSelectedCols: { // wxGrid::GetSelectedCols
+case wxGrid_GetSelectedCols: { // wxGrid::GetSelectedCols
wxGrid *This = (wxGrid *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
wxArrayInt Result = This->GetSelectedCols();
rt.add(Result);
- break;
+ break;
}
-case wxGrid_GetSelectedRows: { // wxGrid::GetSelectedRows
+case wxGrid_GetSelectedRows: { // wxGrid::GetSelectedRows
wxGrid *This = (wxGrid *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
wxArrayInt Result = This->GetSelectedRows();
rt.add(Result);
- break;
+ break;
}
-case wxGrid_GetSelectionBackground: { // wxGrid::GetSelectionBackground
+case wxGrid_GetSelectionBackground: { // wxGrid::GetSelectionBackground
wxGrid *This = (wxGrid *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
wxColour Result = This->GetSelectionBackground();
rt.add(Result);
- break;
+ break;
}
-case wxGrid_GetSelectionBlockTopLeft: { // wxGrid::GetSelectionBlockTopLeft
+case wxGrid_GetSelectionBlockTopLeft: { // wxGrid::GetSelectionBlockTopLeft
wxGrid *This = (wxGrid *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
wxGridCellCoordsArray Result = This->GetSelectionBlockTopLeft();
@@ -3401,9 +3401,9 @@ case wxGrid_GetSelectionBlockTopLeft: { // wxGrid::GetSelectionBlockTopLeft
rt.add(Result[i]);
}
rt.endList(Result.GetCount());
- break;
+ break;
}
-case wxGrid_GetSelectionBlockBottomRight: { // wxGrid::GetSelectionBlockBottomRight
+case wxGrid_GetSelectionBlockBottomRight: { // wxGrid::GetSelectionBlockBottomRight
wxGrid *This = (wxGrid *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
wxGridCellCoordsArray Result = This->GetSelectionBlockBottomRight();
@@ -3411,63 +3411,63 @@ case wxGrid_GetSelectionBlockBottomRight: { // wxGrid::GetSelectionBlockBottomRi
rt.add(Result[i]);
}
rt.endList(Result.GetCount());
- break;
+ break;
}
-case wxGrid_GetSelectionForeground: { // wxGrid::GetSelectionForeground
+case wxGrid_GetSelectionForeground: { // wxGrid::GetSelectionForeground
wxGrid *This = (wxGrid *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
wxColour Result = This->GetSelectionForeground();
rt.add(Result);
- break;
+ break;
}
-case wxGrid_GetViewWidth: { // wxGrid::GetViewWidth
+case wxGrid_GetViewWidth: { // wxGrid::GetViewWidth
wxGrid *This = (wxGrid *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
int Result = This->GetViewWidth();
rt.addInt(Result);
- break;
+ break;
}
-case wxGrid_GetGridWindow: { // wxGrid::GetGridWindow
+case wxGrid_GetGridWindow: { // wxGrid::GetGridWindow
wxGrid *This = (wxGrid *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
wxWindow * Result = (wxWindow*)This->GetGridWindow();
rt.addRef(getRef((void *)Result,memenv), "wxWindow");
- break;
+ break;
}
-case wxGrid_GetGridRowLabelWindow: { // wxGrid::GetGridRowLabelWindow
+case wxGrid_GetGridRowLabelWindow: { // wxGrid::GetGridRowLabelWindow
wxGrid *This = (wxGrid *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
wxWindow * Result = (wxWindow*)This->GetGridRowLabelWindow();
rt.addRef(getRef((void *)Result,memenv), "wxWindow");
- break;
+ break;
}
-case wxGrid_GetGridColLabelWindow: { // wxGrid::GetGridColLabelWindow
+case wxGrid_GetGridColLabelWindow: { // wxGrid::GetGridColLabelWindow
wxGrid *This = (wxGrid *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
wxWindow * Result = (wxWindow*)This->GetGridColLabelWindow();
rt.addRef(getRef((void *)Result,memenv), "wxWindow");
- break;
+ break;
}
-case wxGrid_GetGridCornerLabelWindow: { // wxGrid::GetGridCornerLabelWindow
+case wxGrid_GetGridCornerLabelWindow: { // wxGrid::GetGridCornerLabelWindow
wxGrid *This = (wxGrid *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
wxWindow * Result = (wxWindow*)This->GetGridCornerLabelWindow();
rt.addRef(getRef((void *)Result,memenv), "wxWindow");
- break;
+ break;
}
-case wxGrid_HideCellEditControl: { // wxGrid::HideCellEditControl
+case wxGrid_HideCellEditControl: { // wxGrid::HideCellEditControl
wxGrid *This = (wxGrid *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
This->HideCellEditControl();
- break;
+ break;
}
-case wxGrid_InsertCols: { // wxGrid::InsertCols
+case wxGrid_InsertCols: { // wxGrid::InsertCols
int pos=0;
int numCols=1;
bool updateLabels=true;
wxGrid *This = (wxGrid *) getPtr(bp,memenv); bp += 4;
bp += 4; /* Align */
- while( * (int*) bp) { switch (* (int*) bp) {
+ while( * (int*) bp) { switch (* (int*) bp) {
case 1: {bp += 4;
pos = (int)*(int *) bp; bp += 4;
} break;
@@ -3477,19 +3477,19 @@ case wxGrid_InsertCols: { // wxGrid::InsertCols
case 3: {bp += 4;
updateLabels = *(bool *) bp; bp += 4;
} break;
- }};
+ }};
if(!This) throw wxe_badarg(0);
bool Result = This->InsertCols(pos,numCols,updateLabels);
rt.addBool(Result);
- break;
+ break;
}
-case wxGrid_InsertRows: { // wxGrid::InsertRows
+case wxGrid_InsertRows: { // wxGrid::InsertRows
int pos=0;
int numRows=1;
bool updateLabels=true;
wxGrid *This = (wxGrid *) getPtr(bp,memenv); bp += 4;
bp += 4; /* Align */
- while( * (int*) bp) { switch (* (int*) bp) {
+ while( * (int*) bp) { switch (* (int*) bp) {
case 1: {bp += 4;
pos = (int)*(int *) bp; bp += 4;
} break;
@@ -3499,43 +3499,43 @@ case wxGrid_InsertRows: { // wxGrid::InsertRows
case 3: {bp += 4;
updateLabels = *(bool *) bp; bp += 4;
} break;
- }};
+ }};
if(!This) throw wxe_badarg(0);
bool Result = This->InsertRows(pos,numRows,updateLabels);
rt.addBool(Result);
- break;
+ break;
}
-case wxGrid_IsCellEditControlEnabled: { // wxGrid::IsCellEditControlEnabled
+case wxGrid_IsCellEditControlEnabled: { // wxGrid::IsCellEditControlEnabled
wxGrid *This = (wxGrid *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
bool Result = This->IsCellEditControlEnabled();
rt.addBool(Result);
- break;
+ break;
}
-case wxGrid_IsCurrentCellReadOnly: { // wxGrid::IsCurrentCellReadOnly
+case wxGrid_IsCurrentCellReadOnly: { // wxGrid::IsCurrentCellReadOnly
wxGrid *This = (wxGrid *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
bool Result = This->IsCurrentCellReadOnly();
rt.addBool(Result);
- break;
+ break;
}
-case wxGrid_IsEditable: { // wxGrid::IsEditable
+case wxGrid_IsEditable: { // wxGrid::IsEditable
wxGrid *This = (wxGrid *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
bool Result = This->IsEditable();
rt.addBool(Result);
- break;
+ break;
}
-case wxGrid_IsInSelection_2: { // wxGrid::IsInSelection
+case wxGrid_IsInSelection_2: { // wxGrid::IsInSelection
wxGrid *This = (wxGrid *) getPtr(bp,memenv); bp += 4;
int * row = (int *) bp; bp += 4;
int * col = (int *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
bool Result = This->IsInSelection((int) *row,(int) *col);
rt.addBool(Result);
- break;
+ break;
}
-case wxGrid_IsInSelection_1: { // wxGrid::IsInSelection
+case wxGrid_IsInSelection_1: { // wxGrid::IsInSelection
wxGrid *This = (wxGrid *) getPtr(bp,memenv); bp += 4;
int * coordsR = (int *) bp; bp += 4;
int * coordsC = (int *) bp; bp += 4;
@@ -3543,153 +3543,153 @@ case wxGrid_IsInSelection_1: { // wxGrid::IsInSelection
if(!This) throw wxe_badarg(0);
bool Result = This->IsInSelection(coords);
rt.addBool(Result);
- break;
+ break;
}
-case wxGrid_IsReadOnly: { // wxGrid::IsReadOnly
+case wxGrid_IsReadOnly: { // wxGrid::IsReadOnly
wxGrid *This = (wxGrid *) getPtr(bp,memenv); bp += 4;
int * row = (int *) bp; bp += 4;
int * col = (int *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
bool Result = This->IsReadOnly((int) *row,(int) *col);
rt.addBool(Result);
- break;
+ break;
}
-case wxGrid_IsSelection: { // wxGrid::IsSelection
+case wxGrid_IsSelection: { // wxGrid::IsSelection
wxGrid *This = (wxGrid *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
bool Result = This->IsSelection();
rt.addBool(Result);
- break;
+ break;
}
-case wxGrid_IsVisible_3: { // wxGrid::IsVisible
+case wxGrid_IsVisible_3: { // wxGrid::IsVisible
bool wholeCellVisible=true;
wxGrid *This = (wxGrid *) getPtr(bp,memenv); bp += 4;
int * row = (int *) bp; bp += 4;
int * col = (int *) bp; bp += 4;
bp += 4; /* Align */
- while( * (int*) bp) { switch (* (int*) bp) {
+ while( * (int*) bp) { switch (* (int*) bp) {
case 1: {bp += 4;
wholeCellVisible = *(bool *) bp; bp += 4;
} break;
- }};
+ }};
if(!This) throw wxe_badarg(0);
bool Result = This->IsVisible((int) *row,(int) *col,wholeCellVisible);
rt.addBool(Result);
- break;
+ break;
}
-case wxGrid_IsVisible_2: { // wxGrid::IsVisible
+case wxGrid_IsVisible_2: { // wxGrid::IsVisible
bool wholeCellVisible=true;
wxGrid *This = (wxGrid *) getPtr(bp,memenv); bp += 4;
int * coordsR = (int *) bp; bp += 4;
int * coordsC = (int *) bp; bp += 4;
wxGridCellCoords coords = wxGridCellCoords(*coordsR,*coordsC);
bp += 4; /* Align */
- while( * (int*) bp) { switch (* (int*) bp) {
+ while( * (int*) bp) { switch (* (int*) bp) {
case 1: {bp += 4;
wholeCellVisible = *(bool *) bp; bp += 4;
} break;
- }};
+ }};
if(!This) throw wxe_badarg(0);
bool Result = This->IsVisible(coords,wholeCellVisible);
rt.addBool(Result);
- break;
+ break;
}
-case wxGrid_MakeCellVisible_2: { // wxGrid::MakeCellVisible
+case wxGrid_MakeCellVisible_2: { // wxGrid::MakeCellVisible
wxGrid *This = (wxGrid *) getPtr(bp,memenv); bp += 4;
int * row = (int *) bp; bp += 4;
int * col = (int *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
This->MakeCellVisible((int) *row,(int) *col);
- break;
+ break;
}
-case wxGrid_MakeCellVisible_1: { // wxGrid::MakeCellVisible
+case wxGrid_MakeCellVisible_1: { // wxGrid::MakeCellVisible
wxGrid *This = (wxGrid *) getPtr(bp,memenv); bp += 4;
int * coordsR = (int *) bp; bp += 4;
int * coordsC = (int *) bp; bp += 4;
wxGridCellCoords coords = wxGridCellCoords(*coordsR,*coordsC);
if(!This) throw wxe_badarg(0);
This->MakeCellVisible(coords);
- break;
+ break;
}
-case wxGrid_MoveCursorDown: { // wxGrid::MoveCursorDown
+case wxGrid_MoveCursorDown: { // wxGrid::MoveCursorDown
wxGrid *This = (wxGrid *) getPtr(bp,memenv); bp += 4;
bool * expandSelection = (bool *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
bool Result = This->MoveCursorDown((bool) *expandSelection);
rt.addBool(Result);
- break;
+ break;
}
-case wxGrid_MoveCursorLeft: { // wxGrid::MoveCursorLeft
+case wxGrid_MoveCursorLeft: { // wxGrid::MoveCursorLeft
wxGrid *This = (wxGrid *) getPtr(bp,memenv); bp += 4;
bool * expandSelection = (bool *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
bool Result = This->MoveCursorLeft((bool) *expandSelection);
rt.addBool(Result);
- break;
+ break;
}
-case wxGrid_MoveCursorRight: { // wxGrid::MoveCursorRight
+case wxGrid_MoveCursorRight: { // wxGrid::MoveCursorRight
wxGrid *This = (wxGrid *) getPtr(bp,memenv); bp += 4;
bool * expandSelection = (bool *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
bool Result = This->MoveCursorRight((bool) *expandSelection);
rt.addBool(Result);
- break;
+ break;
}
-case wxGrid_MoveCursorUp: { // wxGrid::MoveCursorUp
+case wxGrid_MoveCursorUp: { // wxGrid::MoveCursorUp
wxGrid *This = (wxGrid *) getPtr(bp,memenv); bp += 4;
bool * expandSelection = (bool *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
bool Result = This->MoveCursorUp((bool) *expandSelection);
rt.addBool(Result);
- break;
+ break;
}
-case wxGrid_MoveCursorDownBlock: { // wxGrid::MoveCursorDownBlock
+case wxGrid_MoveCursorDownBlock: { // wxGrid::MoveCursorDownBlock
wxGrid *This = (wxGrid *) getPtr(bp,memenv); bp += 4;
bool * expandSelection = (bool *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
bool Result = This->MoveCursorDownBlock((bool) *expandSelection);
rt.addBool(Result);
- break;
+ break;
}
-case wxGrid_MoveCursorLeftBlock: { // wxGrid::MoveCursorLeftBlock
+case wxGrid_MoveCursorLeftBlock: { // wxGrid::MoveCursorLeftBlock
wxGrid *This = (wxGrid *) getPtr(bp,memenv); bp += 4;
bool * expandSelection = (bool *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
bool Result = This->MoveCursorLeftBlock((bool) *expandSelection);
rt.addBool(Result);
- break;
+ break;
}
-case wxGrid_MoveCursorRightBlock: { // wxGrid::MoveCursorRightBlock
+case wxGrid_MoveCursorRightBlock: { // wxGrid::MoveCursorRightBlock
wxGrid *This = (wxGrid *) getPtr(bp,memenv); bp += 4;
bool * expandSelection = (bool *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
bool Result = This->MoveCursorRightBlock((bool) *expandSelection);
rt.addBool(Result);
- break;
+ break;
}
-case wxGrid_MoveCursorUpBlock: { // wxGrid::MoveCursorUpBlock
+case wxGrid_MoveCursorUpBlock: { // wxGrid::MoveCursorUpBlock
wxGrid *This = (wxGrid *) getPtr(bp,memenv); bp += 4;
bool * expandSelection = (bool *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
bool Result = This->MoveCursorUpBlock((bool) *expandSelection);
rt.addBool(Result);
- break;
+ break;
}
-case wxGrid_MovePageDown: { // wxGrid::MovePageDown
+case wxGrid_MovePageDown: { // wxGrid::MovePageDown
wxGrid *This = (wxGrid *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
bool Result = This->MovePageDown();
rt.addBool(Result);
- break;
+ break;
}
-case wxGrid_MovePageUp: { // wxGrid::MovePageUp
+case wxGrid_MovePageUp: { // wxGrid::MovePageUp
wxGrid *This = (wxGrid *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
bool Result = This->MovePageUp();
rt.addBool(Result);
- break;
+ break;
}
-case wxGrid_RegisterDataType: { // wxGrid::RegisterDataType
+case wxGrid_RegisterDataType: { // wxGrid::RegisterDataType
wxGrid *This = (wxGrid *) getPtr(bp,memenv); bp += 4;
int * typeNameLen = (int *) bp; bp += 4;
wxString typeName = wxString(bp, wxConvUTF8);
@@ -3698,21 +3698,21 @@ case wxGrid_RegisterDataType: { // wxGrid::RegisterDataType
wxGridCellEditor *editor = (wxGridCellEditor *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
This->RegisterDataType(typeName,renderer,editor);
- break;
+ break;
}
-case wxGrid_SaveEditControlValue: { // wxGrid::SaveEditControlValue
+case wxGrid_SaveEditControlValue: { // wxGrid::SaveEditControlValue
wxGrid *This = (wxGrid *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
This->SaveEditControlValue();
- break;
+ break;
}
-case wxGrid_SelectAll: { // wxGrid::SelectAll
+case wxGrid_SelectAll: { // wxGrid::SelectAll
wxGrid *This = (wxGrid *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
This->SelectAll();
- break;
+ break;
}
-case wxGrid_SelectBlock_5: { // wxGrid::SelectBlock
+case wxGrid_SelectBlock_5: { // wxGrid::SelectBlock
bool addToSelected=false;
wxGrid *This = (wxGrid *) getPtr(bp,memenv); bp += 4;
int * topRow = (int *) bp; bp += 4;
@@ -3720,16 +3720,16 @@ case wxGrid_SelectBlock_5: { // wxGrid::SelectBlock
int * bottomRow = (int *) bp; bp += 4;
int * rightCol = (int *) bp; bp += 4;
bp += 4; /* Align */
- while( * (int*) bp) { switch (* (int*) bp) {
+ while( * (int*) bp) { switch (* (int*) bp) {
case 1: {bp += 4;
addToSelected = *(bool *) bp; bp += 4;
} break;
- }};
+ }};
if(!This) throw wxe_badarg(0);
This->SelectBlock((int) *topRow,(int) *leftCol,(int) *bottomRow,(int) *rightCol,addToSelected);
- break;
+ break;
}
-case wxGrid_SelectBlock_3: { // wxGrid::SelectBlock
+case wxGrid_SelectBlock_3: { // wxGrid::SelectBlock
bool addToSelected=false;
wxGrid *This = (wxGrid *) getPtr(bp,memenv); bp += 4;
int * topLeftR = (int *) bp; bp += 4;
@@ -3739,42 +3739,42 @@ case wxGrid_SelectBlock_3: { // wxGrid::SelectBlock
int * bottomRightC = (int *) bp; bp += 4;
wxGridCellCoords bottomRight = wxGridCellCoords(*bottomRightR,*bottomRightC);
bp += 4; /* Align */
- while( * (int*) bp) { switch (* (int*) bp) {
+ while( * (int*) bp) { switch (* (int*) bp) {
case 1: {bp += 4;
addToSelected = *(bool *) bp; bp += 4;
} break;
- }};
+ }};
if(!This) throw wxe_badarg(0);
This->SelectBlock(topLeft,bottomRight,addToSelected);
- break;
+ break;
}
-case wxGrid_SelectCol: { // wxGrid::SelectCol
+case wxGrid_SelectCol: { // wxGrid::SelectCol
bool addToSelected=false;
wxGrid *This = (wxGrid *) getPtr(bp,memenv); bp += 4;
int * col = (int *) bp; bp += 4;
- while( * (int*) bp) { switch (* (int*) bp) {
+ while( * (int*) bp) { switch (* (int*) bp) {
case 1: {bp += 4;
addToSelected = *(bool *) bp; bp += 4;
} break;
- }};
+ }};
if(!This) throw wxe_badarg(0);
This->SelectCol((int) *col,addToSelected);
- break;
+ break;
}
-case wxGrid_SelectRow: { // wxGrid::SelectRow
+case wxGrid_SelectRow: { // wxGrid::SelectRow
bool addToSelected=false;
wxGrid *This = (wxGrid *) getPtr(bp,memenv); bp += 4;
int * row = (int *) bp; bp += 4;
- while( * (int*) bp) { switch (* (int*) bp) {
+ while( * (int*) bp) { switch (* (int*) bp) {
case 1: {bp += 4;
addToSelected = *(bool *) bp; bp += 4;
} break;
- }};
+ }};
if(!This) throw wxe_badarg(0);
This->SelectRow((int) *row,addToSelected);
- break;
+ break;
}
-case wxGrid_SetCellAlignment_4: { // wxGrid::SetCellAlignment
+case wxGrid_SetCellAlignment_4: { // wxGrid::SetCellAlignment
wxGrid *This = (wxGrid *) getPtr(bp,memenv); bp += 4;
int * row = (int *) bp; bp += 4;
int * col = (int *) bp; bp += 4;
@@ -3782,25 +3782,25 @@ case wxGrid_SetCellAlignment_4: { // wxGrid::SetCellAlignment
int * vert = (int *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
This->SetCellAlignment((int) *row,(int) *col,(int) *horiz,(int) *vert);
- break;
+ break;
}
-case wxGrid_SetCellAlignment_3: { // wxGrid::SetCellAlignment
+case wxGrid_SetCellAlignment_3: { // wxGrid::SetCellAlignment
wxGrid *This = (wxGrid *) getPtr(bp,memenv); bp += 4;
int * align = (int *) bp; bp += 4;
int * row = (int *) bp; bp += 4;
int * col = (int *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
This->SetCellAlignment((int) *align,(int) *row,(int) *col);
- break;
+ break;
}
-case wxGrid_SetCellAlignment_1: { // wxGrid::SetCellAlignment
+case wxGrid_SetCellAlignment_1: { // wxGrid::SetCellAlignment
wxGrid *This = (wxGrid *) getPtr(bp,memenv); bp += 4;
int * align = (int *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
This->SetCellAlignment((int) *align);
- break;
+ break;
}
-case wxGrid_SetCellBackgroundColour_3_0: { // wxGrid::SetCellBackgroundColour
+case wxGrid_SetCellBackgroundColour_3_0: { // wxGrid::SetCellBackgroundColour
wxGrid *This = (wxGrid *) getPtr(bp,memenv); bp += 4;
int * row = (int *) bp; bp += 4;
int * col = (int *) bp; bp += 4;
@@ -3811,9 +3811,9 @@ case wxGrid_SetCellBackgroundColour_3_0: { // wxGrid::SetCellBackgroundColour
wxColour val = wxColour(*valR,*valG,*valB,*valA);
if(!This) throw wxe_badarg(0);
This->SetCellBackgroundColour((int) *row,(int) *col,val);
- break;
+ break;
}
-case wxGrid_SetCellBackgroundColour_1: { // wxGrid::SetCellBackgroundColour
+case wxGrid_SetCellBackgroundColour_1: { // wxGrid::SetCellBackgroundColour
wxGrid *This = (wxGrid *) getPtr(bp,memenv); bp += 4;
int * colR = (int *) bp; bp += 4;
int * colG = (int *) bp; bp += 4;
@@ -3822,9 +3822,9 @@ case wxGrid_SetCellBackgroundColour_1: { // wxGrid::SetCellBackgroundColour
wxColour col = wxColour(*colR,*colG,*colB,*colA);
if(!This) throw wxe_badarg(0);
This->SetCellBackgroundColour(col);
- break;
+ break;
}
-case wxGrid_SetCellBackgroundColour_3_1: { // wxGrid::SetCellBackgroundColour
+case wxGrid_SetCellBackgroundColour_3_1: { // wxGrid::SetCellBackgroundColour
wxGrid *This = (wxGrid *) getPtr(bp,memenv); bp += 4;
int * colourR = (int *) bp; bp += 4;
int * colourG = (int *) bp; bp += 4;
@@ -3835,36 +3835,36 @@ case wxGrid_SetCellBackgroundColour_3_1: { // wxGrid::SetCellBackgroundColour
int * col = (int *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
This->SetCellBackgroundColour(colour,(int) *row,(int) *col);
- break;
+ break;
}
-case wxGrid_SetCellEditor: { // wxGrid::SetCellEditor
+case wxGrid_SetCellEditor: { // wxGrid::SetCellEditor
wxGrid *This = (wxGrid *) getPtr(bp,memenv); bp += 4;
int * row = (int *) bp; bp += 4;
int * col = (int *) bp; bp += 4;
wxGridCellEditor *editor = (wxGridCellEditor *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
This->SetCellEditor((int) *row,(int) *col,editor);
- break;
+ break;
}
-case wxGrid_SetCellFont: { // wxGrid::SetCellFont
+case wxGrid_SetCellFont: { // wxGrid::SetCellFont
wxGrid *This = (wxGrid *) getPtr(bp,memenv); bp += 4;
int * row = (int *) bp; bp += 4;
int * col = (int *) bp; bp += 4;
wxFont *val = (wxFont *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
This->SetCellFont((int) *row,(int) *col,*val);
- break;
+ break;
}
-case wxGrid_SetCellRenderer: { // wxGrid::SetCellRenderer
+case wxGrid_SetCellRenderer: { // wxGrid::SetCellRenderer
wxGrid *This = (wxGrid *) getPtr(bp,memenv); bp += 4;
int * row = (int *) bp; bp += 4;
int * col = (int *) bp; bp += 4;
wxGridCellRenderer *renderer = (wxGridCellRenderer *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
This->SetCellRenderer((int) *row,(int) *col,renderer);
- break;
+ break;
}
-case wxGrid_SetCellTextColour_3_0: { // wxGrid::SetCellTextColour
+case wxGrid_SetCellTextColour_3_0: { // wxGrid::SetCellTextColour
wxGrid *This = (wxGrid *) getPtr(bp,memenv); bp += 4;
int * row = (int *) bp; bp += 4;
int * col = (int *) bp; bp += 4;
@@ -3875,9 +3875,9 @@ case wxGrid_SetCellTextColour_3_0: { // wxGrid::SetCellTextColour
wxColour val = wxColour(*valR,*valG,*valB,*valA);
if(!This) throw wxe_badarg(0);
This->SetCellTextColour((int) *row,(int) *col,val);
- break;
+ break;
}
-case wxGrid_SetCellTextColour_3_1: { // wxGrid::SetCellTextColour
+case wxGrid_SetCellTextColour_3_1: { // wxGrid::SetCellTextColour
wxGrid *This = (wxGrid *) getPtr(bp,memenv); bp += 4;
int * valR = (int *) bp; bp += 4;
int * valG = (int *) bp; bp += 4;
@@ -3888,9 +3888,9 @@ case wxGrid_SetCellTextColour_3_1: { // wxGrid::SetCellTextColour
int * col = (int *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
This->SetCellTextColour(val,(int) *row,(int) *col);
- break;
+ break;
}
-case wxGrid_SetCellTextColour_1: { // wxGrid::SetCellTextColour
+case wxGrid_SetCellTextColour_1: { // wxGrid::SetCellTextColour
wxGrid *This = (wxGrid *) getPtr(bp,memenv); bp += 4;
int * colR = (int *) bp; bp += 4;
int * colG = (int *) bp; bp += 4;
@@ -3899,9 +3899,9 @@ case wxGrid_SetCellTextColour_1: { // wxGrid::SetCellTextColour
wxColour col = wxColour(*colR,*colG,*colB,*colA);
if(!This) throw wxe_badarg(0);
This->SetCellTextColour(col);
- break;
+ break;
}
-case wxGrid_SetCellValue_3_0: { // wxGrid::SetCellValue
+case wxGrid_SetCellValue_3_0: { // wxGrid::SetCellValue
wxGrid *This = (wxGrid *) getPtr(bp,memenv); bp += 4;
int * row = (int *) bp; bp += 4;
int * col = (int *) bp; bp += 4;
@@ -3910,9 +3910,9 @@ case wxGrid_SetCellValue_3_0: { // wxGrid::SetCellValue
bp += *sLen+((8-((0+ *sLen) & 7)) & 7);
if(!This) throw wxe_badarg(0);
This->SetCellValue((int) *row,(int) *col,s);
- break;
+ break;
}
-case wxGrid_SetCellValue_2: { // wxGrid::SetCellValue
+case wxGrid_SetCellValue_2: { // wxGrid::SetCellValue
wxGrid *This = (wxGrid *) getPtr(bp,memenv); bp += 4;
int * coordsR = (int *) bp; bp += 4;
int * coordsC = (int *) bp; bp += 4;
@@ -3922,9 +3922,9 @@ case wxGrid_SetCellValue_2: { // wxGrid::SetCellValue
bp += *sLen+((8-((0+ *sLen) & 7)) & 7);
if(!This) throw wxe_badarg(0);
This->SetCellValue(coords,s);
- break;
+ break;
}
-case wxGrid_SetCellValue_3_1: { // wxGrid::SetCellValue
+case wxGrid_SetCellValue_3_1: { // wxGrid::SetCellValue
wxGrid *This = (wxGrid *) getPtr(bp,memenv); bp += 4;
int * valLen = (int *) bp; bp += 4;
wxString val = wxString(bp, wxConvUTF8);
@@ -3933,48 +3933,48 @@ case wxGrid_SetCellValue_3_1: { // wxGrid::SetCellValue
int * col = (int *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
This->SetCellValue(val,(int) *row,(int) *col);
- break;
+ break;
}
-case wxGrid_SetColAttr: { // wxGrid::SetColAttr
+case wxGrid_SetColAttr: { // wxGrid::SetColAttr
wxGrid *This = (wxGrid *) getPtr(bp,memenv); bp += 4;
int * col = (int *) bp; bp += 4;
wxGridCellAttr *attr = (wxGridCellAttr *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
This->SetColAttr((int) *col,attr);
- break;
+ break;
}
-case wxGrid_SetColFormatBool: { // wxGrid::SetColFormatBool
+case wxGrid_SetColFormatBool: { // wxGrid::SetColFormatBool
wxGrid *This = (wxGrid *) getPtr(bp,memenv); bp += 4;
int * col = (int *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
This->SetColFormatBool((int) *col);
- break;
+ break;
}
-case wxGrid_SetColFormatNumber: { // wxGrid::SetColFormatNumber
+case wxGrid_SetColFormatNumber: { // wxGrid::SetColFormatNumber
wxGrid *This = (wxGrid *) getPtr(bp,memenv); bp += 4;
int * col = (int *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
This->SetColFormatNumber((int) *col);
- break;
+ break;
}
-case wxGrid_SetColFormatFloat: { // wxGrid::SetColFormatFloat
+case wxGrid_SetColFormatFloat: { // wxGrid::SetColFormatFloat
int width=-1;
int precision=-1;
wxGrid *This = (wxGrid *) getPtr(bp,memenv); bp += 4;
int * col = (int *) bp; bp += 4;
- while( * (int*) bp) { switch (* (int*) bp) {
+ while( * (int*) bp) { switch (* (int*) bp) {
case 1: {bp += 4;
width = (int)*(int *) bp; bp += 4;
} break;
case 2: {bp += 4;
precision = (int)*(int *) bp; bp += 4;
} break;
- }};
+ }};
if(!This) throw wxe_badarg(0);
This->SetColFormatFloat((int) *col,width,precision);
- break;
+ break;
}
-case wxGrid_SetColFormatCustom: { // wxGrid::SetColFormatCustom
+case wxGrid_SetColFormatCustom: { // wxGrid::SetColFormatCustom
wxGrid *This = (wxGrid *) getPtr(bp,memenv); bp += 4;
int * col = (int *) bp; bp += 4;
int * typeNameLen = (int *) bp; bp += 4;
@@ -3982,24 +3982,24 @@ case wxGrid_SetColFormatCustom: { // wxGrid::SetColFormatCustom
bp += *typeNameLen+((8-((4+ *typeNameLen) & 7)) & 7);
if(!This) throw wxe_badarg(0);
This->SetColFormatCustom((int) *col,typeName);
- break;
+ break;
}
-case wxGrid_SetColLabelAlignment: { // wxGrid::SetColLabelAlignment
+case wxGrid_SetColLabelAlignment: { // wxGrid::SetColLabelAlignment
wxGrid *This = (wxGrid *) getPtr(bp,memenv); bp += 4;
int * horiz = (int *) bp; bp += 4;
int * vert = (int *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
This->SetColLabelAlignment((int) *horiz,(int) *vert);
- break;
+ break;
}
-case wxGrid_SetColLabelSize: { // wxGrid::SetColLabelSize
+case wxGrid_SetColLabelSize: { // wxGrid::SetColLabelSize
wxGrid *This = (wxGrid *) getPtr(bp,memenv); bp += 4;
int * height = (int *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
This->SetColLabelSize((int) *height);
- break;
+ break;
}
-case wxGrid_SetColLabelValue: { // wxGrid::SetColLabelValue
+case wxGrid_SetColLabelValue: { // wxGrid::SetColLabelValue
wxGrid *This = (wxGrid *) getPtr(bp,memenv); bp += 4;
int * col = (int *) bp; bp += 4;
int * valLen = (int *) bp; bp += 4;
@@ -4007,40 +4007,40 @@ case wxGrid_SetColLabelValue: { // wxGrid::SetColLabelValue
bp += *valLen+((8-((4+ *valLen) & 7)) & 7);
if(!This) throw wxe_badarg(0);
This->SetColLabelValue((int) *col,val);
- break;
+ break;
}
-case wxGrid_SetColMinimalWidth: { // wxGrid::SetColMinimalWidth
+case wxGrid_SetColMinimalWidth: { // wxGrid::SetColMinimalWidth
wxGrid *This = (wxGrid *) getPtr(bp,memenv); bp += 4;
int * col = (int *) bp; bp += 4;
int * width = (int *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
This->SetColMinimalWidth((int) *col,(int) *width);
- break;
+ break;
}
-case wxGrid_SetColMinimalAcceptableWidth: { // wxGrid::SetColMinimalAcceptableWidth
+case wxGrid_SetColMinimalAcceptableWidth: { // wxGrid::SetColMinimalAcceptableWidth
wxGrid *This = (wxGrid *) getPtr(bp,memenv); bp += 4;
int * width = (int *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
This->SetColMinimalAcceptableWidth((int) *width);
- break;
+ break;
}
-case wxGrid_SetColSize: { // wxGrid::SetColSize
+case wxGrid_SetColSize: { // wxGrid::SetColSize
wxGrid *This = (wxGrid *) getPtr(bp,memenv); bp += 4;
int * col = (int *) bp; bp += 4;
int * width = (int *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
This->SetColSize((int) *col,(int) *width);
- break;
+ break;
}
-case wxGrid_SetDefaultCellAlignment: { // wxGrid::SetDefaultCellAlignment
+case wxGrid_SetDefaultCellAlignment: { // wxGrid::SetDefaultCellAlignment
wxGrid *This = (wxGrid *) getPtr(bp,memenv); bp += 4;
int * horiz = (int *) bp; bp += 4;
int * vert = (int *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
This->SetDefaultCellAlignment((int) *horiz,(int) *vert);
- break;
+ break;
}
-case wxGrid_SetDefaultCellBackgroundColour: { // wxGrid::SetDefaultCellBackgroundColour
+case wxGrid_SetDefaultCellBackgroundColour: { // wxGrid::SetDefaultCellBackgroundColour
wxGrid *This = (wxGrid *) getPtr(bp,memenv); bp += 4;
int * valR = (int *) bp; bp += 4;
int * valG = (int *) bp; bp += 4;
@@ -4049,16 +4049,16 @@ case wxGrid_SetDefaultCellBackgroundColour: { // wxGrid::SetDefaultCellBackgroun
wxColour val = wxColour(*valR,*valG,*valB,*valA);
if(!This) throw wxe_badarg(0);
This->SetDefaultCellBackgroundColour(val);
- break;
+ break;
}
-case wxGrid_SetDefaultCellFont: { // wxGrid::SetDefaultCellFont
+case wxGrid_SetDefaultCellFont: { // wxGrid::SetDefaultCellFont
wxGrid *This = (wxGrid *) getPtr(bp,memenv); bp += 4;
wxFont *val = (wxFont *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
This->SetDefaultCellFont(*val);
- break;
+ break;
}
-case wxGrid_SetDefaultCellTextColour: { // wxGrid::SetDefaultCellTextColour
+case wxGrid_SetDefaultCellTextColour: { // wxGrid::SetDefaultCellTextColour
wxGrid *This = (wxGrid *) getPtr(bp,memenv); bp += 4;
int * valR = (int *) bp; bp += 4;
int * valG = (int *) bp; bp += 4;
@@ -4067,57 +4067,57 @@ case wxGrid_SetDefaultCellTextColour: { // wxGrid::SetDefaultCellTextColour
wxColour val = wxColour(*valR,*valG,*valB,*valA);
if(!This) throw wxe_badarg(0);
This->SetDefaultCellTextColour(val);
- break;
+ break;
}
-case wxGrid_SetDefaultEditor: { // wxGrid::SetDefaultEditor
+case wxGrid_SetDefaultEditor: { // wxGrid::SetDefaultEditor
wxGrid *This = (wxGrid *) getPtr(bp,memenv); bp += 4;
wxGridCellEditor *editor = (wxGridCellEditor *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
This->SetDefaultEditor(editor);
- break;
+ break;
}
-case wxGrid_SetDefaultRenderer: { // wxGrid::SetDefaultRenderer
+case wxGrid_SetDefaultRenderer: { // wxGrid::SetDefaultRenderer
wxGrid *This = (wxGrid *) getPtr(bp,memenv); bp += 4;
wxGridCellRenderer *renderer = (wxGridCellRenderer *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
This->SetDefaultRenderer(renderer);
- break;
+ break;
}
-case wxGrid_SetDefaultColSize: { // wxGrid::SetDefaultColSize
+case wxGrid_SetDefaultColSize: { // wxGrid::SetDefaultColSize
bool resizeExistingCols=false;
wxGrid *This = (wxGrid *) getPtr(bp,memenv); bp += 4;
int * width = (int *) bp; bp += 4;
- while( * (int*) bp) { switch (* (int*) bp) {
+ while( * (int*) bp) { switch (* (int*) bp) {
case 1: {bp += 4;
resizeExistingCols = *(bool *) bp; bp += 4;
} break;
- }};
+ }};
if(!This) throw wxe_badarg(0);
This->SetDefaultColSize((int) *width,resizeExistingCols);
- break;
+ break;
}
-case wxGrid_SetDefaultRowSize: { // wxGrid::SetDefaultRowSize
+case wxGrid_SetDefaultRowSize: { // wxGrid::SetDefaultRowSize
bool resizeExistingRows=false;
wxGrid *This = (wxGrid *) getPtr(bp,memenv); bp += 4;
int * height = (int *) bp; bp += 4;
- while( * (int*) bp) { switch (* (int*) bp) {
+ while( * (int*) bp) { switch (* (int*) bp) {
case 1: {bp += 4;
resizeExistingRows = *(bool *) bp; bp += 4;
} break;
- }};
+ }};
if(!This) throw wxe_badarg(0);
This->SetDefaultRowSize((int) *height,resizeExistingRows);
- break;
+ break;
}
-case wxGrid_SetGridCursor: { // wxGrid::SetGridCursor
+case wxGrid_SetGridCursor: { // wxGrid::SetGridCursor
wxGrid *This = (wxGrid *) getPtr(bp,memenv); bp += 4;
int * row = (int *) bp; bp += 4;
int * col = (int *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
This->SetGridCursor((int) *row,(int) *col);
- break;
+ break;
}
-case wxGrid_SetGridLineColour: { // wxGrid::SetGridLineColour
+case wxGrid_SetGridLineColour: { // wxGrid::SetGridLineColour
wxGrid *This = (wxGrid *) getPtr(bp,memenv); bp += 4;
int * valR = (int *) bp; bp += 4;
int * valG = (int *) bp; bp += 4;
@@ -4126,9 +4126,9 @@ case wxGrid_SetGridLineColour: { // wxGrid::SetGridLineColour
wxColour val = wxColour(*valR,*valG,*valB,*valA);
if(!This) throw wxe_badarg(0);
This->SetGridLineColour(val);
- break;
+ break;
}
-case wxGrid_SetLabelBackgroundColour: { // wxGrid::SetLabelBackgroundColour
+case wxGrid_SetLabelBackgroundColour: { // wxGrid::SetLabelBackgroundColour
wxGrid *This = (wxGrid *) getPtr(bp,memenv); bp += 4;
int * valR = (int *) bp; bp += 4;
int * valG = (int *) bp; bp += 4;
@@ -4137,16 +4137,16 @@ case wxGrid_SetLabelBackgroundColour: { // wxGrid::SetLabelBackgroundColour
wxColour val = wxColour(*valR,*valG,*valB,*valA);
if(!This) throw wxe_badarg(0);
This->SetLabelBackgroundColour(val);
- break;
+ break;
}
-case wxGrid_SetLabelFont: { // wxGrid::SetLabelFont
+case wxGrid_SetLabelFont: { // wxGrid::SetLabelFont
wxGrid *This = (wxGrid *) getPtr(bp,memenv); bp += 4;
wxFont *val = (wxFont *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
This->SetLabelFont(*val);
- break;
+ break;
}
-case wxGrid_SetLabelTextColour: { // wxGrid::SetLabelTextColour
+case wxGrid_SetLabelTextColour: { // wxGrid::SetLabelTextColour
wxGrid *This = (wxGrid *) getPtr(bp,memenv); bp += 4;
int * valR = (int *) bp; bp += 4;
int * valG = (int *) bp; bp += 4;
@@ -4155,55 +4155,55 @@ case wxGrid_SetLabelTextColour: { // wxGrid::SetLabelTextColour
wxColour val = wxColour(*valR,*valG,*valB,*valA);
if(!This) throw wxe_badarg(0);
This->SetLabelTextColour(val);
- break;
+ break;
}
-case wxGrid_SetMargins: { // wxGrid::SetMargins
+case wxGrid_SetMargins: { // wxGrid::SetMargins
wxGrid *This = (wxGrid *) getPtr(bp,memenv); bp += 4;
int * extraWidth = (int *) bp; bp += 4;
int * extraHeight = (int *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
This->SetMargins((int) *extraWidth,(int) *extraHeight);
- break;
+ break;
}
-case wxGrid_SetReadOnly: { // wxGrid::SetReadOnly
+case wxGrid_SetReadOnly: { // wxGrid::SetReadOnly
bool isReadOnly=true;
wxGrid *This = (wxGrid *) getPtr(bp,memenv); bp += 4;
int * row = (int *) bp; bp += 4;
int * col = (int *) bp; bp += 4;
bp += 4; /* Align */
- while( * (int*) bp) { switch (* (int*) bp) {
+ while( * (int*) bp) { switch (* (int*) bp) {
case 1: {bp += 4;
isReadOnly = *(bool *) bp; bp += 4;
} break;
- }};
+ }};
if(!This) throw wxe_badarg(0);
This->SetReadOnly((int) *row,(int) *col,isReadOnly);
- break;
+ break;
}
-case wxGrid_SetRowAttr: { // wxGrid::SetRowAttr
+case wxGrid_SetRowAttr: { // wxGrid::SetRowAttr
wxGrid *This = (wxGrid *) getPtr(bp,memenv); bp += 4;
int * row = (int *) bp; bp += 4;
wxGridCellAttr *attr = (wxGridCellAttr *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
This->SetRowAttr((int) *row,attr);
- break;
+ break;
}
-case wxGrid_SetRowLabelAlignment: { // wxGrid::SetRowLabelAlignment
+case wxGrid_SetRowLabelAlignment: { // wxGrid::SetRowLabelAlignment
wxGrid *This = (wxGrid *) getPtr(bp,memenv); bp += 4;
int * horiz = (int *) bp; bp += 4;
int * vert = (int *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
This->SetRowLabelAlignment((int) *horiz,(int) *vert);
- break;
+ break;
}
-case wxGrid_SetRowLabelSize: { // wxGrid::SetRowLabelSize
+case wxGrid_SetRowLabelSize: { // wxGrid::SetRowLabelSize
wxGrid *This = (wxGrid *) getPtr(bp,memenv); bp += 4;
int * width = (int *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
This->SetRowLabelSize((int) *width);
- break;
+ break;
}
-case wxGrid_SetRowLabelValue: { // wxGrid::SetRowLabelValue
+case wxGrid_SetRowLabelValue: { // wxGrid::SetRowLabelValue
wxGrid *This = (wxGrid *) getPtr(bp,memenv); bp += 4;
int * row = (int *) bp; bp += 4;
int * valLen = (int *) bp; bp += 4;
@@ -4211,46 +4211,46 @@ case wxGrid_SetRowLabelValue: { // wxGrid::SetRowLabelValue
bp += *valLen+((8-((4+ *valLen) & 7)) & 7);
if(!This) throw wxe_badarg(0);
This->SetRowLabelValue((int) *row,val);
- break;
+ break;
}
-case wxGrid_SetRowMinimalHeight: { // wxGrid::SetRowMinimalHeight
+case wxGrid_SetRowMinimalHeight: { // wxGrid::SetRowMinimalHeight
wxGrid *This = (wxGrid *) getPtr(bp,memenv); bp += 4;
int * row = (int *) bp; bp += 4;
int * width = (int *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
This->SetRowMinimalHeight((int) *row,(int) *width);
- break;
+ break;
}
-case wxGrid_SetRowMinimalAcceptableHeight: { // wxGrid::SetRowMinimalAcceptableHeight
+case wxGrid_SetRowMinimalAcceptableHeight: { // wxGrid::SetRowMinimalAcceptableHeight
wxGrid *This = (wxGrid *) getPtr(bp,memenv); bp += 4;
int * width = (int *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
This->SetRowMinimalAcceptableHeight((int) *width);
- break;
+ break;
}
-case wxGrid_SetRowSize: { // wxGrid::SetRowSize
+case wxGrid_SetRowSize: { // wxGrid::SetRowSize
wxGrid *This = (wxGrid *) getPtr(bp,memenv); bp += 4;
int * row = (int *) bp; bp += 4;
int * height = (int *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
This->SetRowSize((int) *row,(int) *height);
- break;
+ break;
}
-case wxGrid_SetScrollLineX: { // wxGrid::SetScrollLineX
+case wxGrid_SetScrollLineX: { // wxGrid::SetScrollLineX
wxGrid *This = (wxGrid *) getPtr(bp,memenv); bp += 4;
int * x = (int *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
This->SetScrollLineX((int) *x);
- break;
+ break;
}
-case wxGrid_SetScrollLineY: { // wxGrid::SetScrollLineY
+case wxGrid_SetScrollLineY: { // wxGrid::SetScrollLineY
wxGrid *This = (wxGrid *) getPtr(bp,memenv); bp += 4;
int * y = (int *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
This->SetScrollLineY((int) *y);
- break;
+ break;
}
-case wxGrid_SetSelectionBackground: { // wxGrid::SetSelectionBackground
+case wxGrid_SetSelectionBackground: { // wxGrid::SetSelectionBackground
wxGrid *This = (wxGrid *) getPtr(bp,memenv); bp += 4;
int * cR = (int *) bp; bp += 4;
int * cG = (int *) bp; bp += 4;
@@ -4259,9 +4259,9 @@ case wxGrid_SetSelectionBackground: { // wxGrid::SetSelectionBackground
wxColour c = wxColour(*cR,*cG,*cB,*cA);
if(!This) throw wxe_badarg(0);
This->SetSelectionBackground(c);
- break;
+ break;
}
-case wxGrid_SetSelectionForeground: { // wxGrid::SetSelectionForeground
+case wxGrid_SetSelectionForeground: { // wxGrid::SetSelectionForeground
wxGrid *This = (wxGrid *) getPtr(bp,memenv); bp += 4;
int * cR = (int *) bp; bp += 4;
int * cG = (int *) bp; bp += 4;
@@ -4270,60 +4270,60 @@ case wxGrid_SetSelectionForeground: { // wxGrid::SetSelectionForeground
wxColour c = wxColour(*cR,*cG,*cB,*cA);
if(!This) throw wxe_badarg(0);
This->SetSelectionForeground(c);
- break;
+ break;
}
-case wxGrid_SetSelectionMode: { // wxGrid::SetSelectionMode
+case wxGrid_SetSelectionMode: { // wxGrid::SetSelectionMode
wxGrid *This = (wxGrid *) getPtr(bp,memenv); bp += 4;
wxGrid::wxGridSelectionModes selmode = *(wxGrid::wxGridSelectionModes *) bp; bp += 4;;
if(!This) throw wxe_badarg(0);
This->SetSelectionMode((wxGrid::wxGridSelectionModes) selmode);
- break;
+ break;
}
-case wxGrid_ShowCellEditControl: { // wxGrid::ShowCellEditControl
+case wxGrid_ShowCellEditControl: { // wxGrid::ShowCellEditControl
wxGrid *This = (wxGrid *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
This->ShowCellEditControl();
- break;
+ break;
}
-case wxGrid_XToCol: { // wxGrid::XToCol
+case wxGrid_XToCol: { // wxGrid::XToCol
bool clipToMinMax=false;
wxGrid *This = (wxGrid *) getPtr(bp,memenv); bp += 4;
int * x = (int *) bp; bp += 4;
- while( * (int*) bp) { switch (* (int*) bp) {
+ while( * (int*) bp) { switch (* (int*) bp) {
case 1: {bp += 4;
clipToMinMax = *(bool *) bp; bp += 4;
} break;
- }};
+ }};
if(!This) throw wxe_badarg(0);
int Result = This->XToCol((int) *x,clipToMinMax);
rt.addInt(Result);
- break;
+ break;
}
-case wxGrid_XToEdgeOfCol: { // wxGrid::XToEdgeOfCol
+case wxGrid_XToEdgeOfCol: { // wxGrid::XToEdgeOfCol
wxGrid *This = (wxGrid *) getPtr(bp,memenv); bp += 4;
int * x = (int *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
int Result = This->XToEdgeOfCol((int) *x);
rt.addInt(Result);
- break;
+ break;
}
-case wxGrid_YToEdgeOfRow: { // wxGrid::YToEdgeOfRow
+case wxGrid_YToEdgeOfRow: { // wxGrid::YToEdgeOfRow
wxGrid *This = (wxGrid *) getPtr(bp,memenv); bp += 4;
int * y = (int *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
int Result = This->YToEdgeOfRow((int) *y);
rt.addInt(Result);
- break;
+ break;
}
-case wxGrid_YToRow: { // wxGrid::YToRow
+case wxGrid_YToRow: { // wxGrid::YToRow
wxGrid *This = (wxGrid *) getPtr(bp,memenv); bp += 4;
int * y = (int *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
int Result = This->YToRow((int) *y);
rt.addInt(Result);
- break;
+ break;
}
-case wxGridCellRenderer_Draw: { // wxGridCellRenderer::Draw
+case wxGridCellRenderer_Draw: { // wxGridCellRenderer::Draw
wxGridCellRenderer *This = (wxGridCellRenderer *) getPtr(bp,memenv); bp += 4;
wxGrid *grid = (wxGrid *) getPtr(bp,memenv); bp += 4;
wxGridCellAttr *attr = (wxGridCellAttr *) getPtr(bp,memenv); bp += 4;
@@ -4338,9 +4338,9 @@ case wxGridCellRenderer_Draw: { // wxGridCellRenderer::Draw
bool * isSelected = (bool *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
This->Draw(*grid,*attr,*dc,rect,(int) *row,(int) *col,(bool) *isSelected);
- break;
+ break;
}
-case wxGridCellRenderer_GetBestSize: { // wxGridCellRenderer::GetBestSize
+case wxGridCellRenderer_GetBestSize: { // wxGridCellRenderer::GetBestSize
wxGridCellRenderer *This = (wxGridCellRenderer *) getPtr(bp,memenv); bp += 4;
wxGrid *grid = (wxGrid *) getPtr(bp,memenv); bp += 4;
wxGridCellAttr *attr = (wxGridCellAttr *) getPtr(bp,memenv); bp += 4;
@@ -4350,25 +4350,25 @@ case wxGridCellRenderer_GetBestSize: { // wxGridCellRenderer::GetBestSize
if(!This) throw wxe_badarg(0);
wxSize Result = This->GetBestSize(*grid,*attr,*dc,(int) *row,(int) *col);
rt.add(Result);
- break;
+ break;
}
-case wxGridCellEditor_Create: { // wxGridCellEditor::Create
+case wxGridCellEditor_Create: { // wxGridCellEditor::Create
wxGridCellEditor *This = (wxGridCellEditor *) getPtr(bp,memenv); bp += 4;
wxWindow *parent = (wxWindow *) getPtr(bp,memenv); bp += 4;
int * id = (int *) bp; bp += 4;
wxEvtHandler *evtHandler = (wxEvtHandler *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
This->Create(parent,(wxWindowID) *id,evtHandler);
- break;
+ break;
}
-case wxGridCellEditor_IsCreated: { // wxGridCellEditor::IsCreated
+case wxGridCellEditor_IsCreated: { // wxGridCellEditor::IsCreated
wxGridCellEditor *This = (wxGridCellEditor *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
bool Result = This->IsCreated();
rt.addBool(Result);
- break;
+ break;
}
-case wxGridCellEditor_SetSize: { // wxGridCellEditor::SetSize
+case wxGridCellEditor_SetSize: { // wxGridCellEditor::SetSize
wxGridCellEditor *This = (wxGridCellEditor *) getPtr(bp,memenv); bp += 4;
int * rectX = (int *) bp; bp += 4;
int * rectY = (int *) bp; bp += 4;
@@ -4377,22 +4377,22 @@ case wxGridCellEditor_SetSize: { // wxGridCellEditor::SetSize
wxRect rect = wxRect(*rectX,*rectY,*rectW,*rectH);
if(!This) throw wxe_badarg(0);
This->SetSize(rect);
- break;
+ break;
}
-case wxGridCellEditor_Show: { // wxGridCellEditor::Show
+case wxGridCellEditor_Show: { // wxGridCellEditor::Show
wxGridCellAttr * attr=(wxGridCellAttr *) NULL;
wxGridCellEditor *This = (wxGridCellEditor *) getPtr(bp,memenv); bp += 4;
bool * show = (bool *) bp; bp += 4;
- while( * (int*) bp) { switch (* (int*) bp) {
+ while( * (int*) bp) { switch (* (int*) bp) {
case 1: {bp += 4;
attr = (wxGridCellAttr *) getPtr(bp,memenv); bp += 4;
} break;
- }};
+ }};
if(!This) throw wxe_badarg(0);
This->Show((bool) *show,attr);
- break;
+ break;
}
-case wxGridCellEditor_PaintBackground: { // wxGridCellEditor::PaintBackground
+case wxGridCellEditor_PaintBackground: { // wxGridCellEditor::PaintBackground
wxGridCellEditor *This = (wxGridCellEditor *) getPtr(bp,memenv); bp += 4;
int * rectCellX = (int *) bp; bp += 4;
int * rectCellY = (int *) bp; bp += 4;
@@ -4402,18 +4402,18 @@ case wxGridCellEditor_PaintBackground: { // wxGridCellEditor::PaintBackground
wxGridCellAttr *attr = (wxGridCellAttr *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
This->PaintBackground(rectCell,attr);
- break;
+ break;
}
-case wxGridCellEditor_BeginEdit: { // wxGridCellEditor::BeginEdit
+case wxGridCellEditor_BeginEdit: { // wxGridCellEditor::BeginEdit
wxGridCellEditor *This = (wxGridCellEditor *) getPtr(bp,memenv); bp += 4;
int * row = (int *) bp; bp += 4;
int * col = (int *) bp; bp += 4;
wxGrid *grid = (wxGrid *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
This->BeginEdit((int) *row,(int) *col,grid);
- break;
+ break;
}
-case wxGridCellEditor_EndEdit: { // wxGridCellEditor::EndEdit
+case wxGridCellEditor_EndEdit: { // wxGridCellEditor::EndEdit
wxGridCellEditor *This = (wxGridCellEditor *) getPtr(bp,memenv); bp += 4;
int * row = (int *) bp; bp += 4;
int * col = (int *) bp; bp += 4;
@@ -4421,64 +4421,64 @@ case wxGridCellEditor_EndEdit: { // wxGridCellEditor::EndEdit
if(!This) throw wxe_badarg(0);
bool Result = This->EndEdit((int) *row,(int) *col,grid);
rt.addBool(Result);
- break;
+ break;
}
-case wxGridCellEditor_Reset: { // wxGridCellEditor::Reset
+case wxGridCellEditor_Reset: { // wxGridCellEditor::Reset
wxGridCellEditor *This = (wxGridCellEditor *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
This->Reset();
- break;
+ break;
}
-case wxGridCellEditor_StartingKey: { // wxGridCellEditor::StartingKey
+case wxGridCellEditor_StartingKey: { // wxGridCellEditor::StartingKey
wxGridCellEditor *This = (wxGridCellEditor *) getPtr(bp,memenv); bp += 4;
wxKeyEvent *event = (wxKeyEvent *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
This->StartingKey(*event);
- break;
+ break;
}
-case wxGridCellEditor_StartingClick: { // wxGridCellEditor::StartingClick
+case wxGridCellEditor_StartingClick: { // wxGridCellEditor::StartingClick
wxGridCellEditor *This = (wxGridCellEditor *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
This->StartingClick();
- break;
+ break;
}
-case wxGridCellEditor_HandleReturn: { // wxGridCellEditor::HandleReturn
+case wxGridCellEditor_HandleReturn: { // wxGridCellEditor::HandleReturn
wxGridCellEditor *This = (wxGridCellEditor *) getPtr(bp,memenv); bp += 4;
wxKeyEvent *event = (wxKeyEvent *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
This->HandleReturn(*event);
- break;
+ break;
}
-case wxGridCellBoolRenderer_new: { // wxGridCellBoolRenderer::wxGridCellBoolRenderer
+case wxGridCellBoolRenderer_new: { // wxGridCellBoolRenderer::wxGridCellBoolRenderer
wxGridCellBoolRenderer * Result = new wxGridCellBoolRenderer();
newPtr((void *) Result, 24, memenv);
rt.addRef(getRef((void *)Result,memenv), "wxGridCellBoolRenderer");
- break;
+ break;
}
-case wxGridCellBoolRenderer_destroy: { // wxGridCellBoolRenderer::destroy
+case wxGridCellBoolRenderer_destroy: { // wxGridCellBoolRenderer::destroy
wxGridCellBoolRenderer *This = (wxGridCellBoolRenderer *) getPtr(bp,memenv); bp += 4;
if(This) { ((WxeApp *) wxTheApp)->clearPtr((void *) This);
delete This;}
- break;
+ break;
}
-case wxGridCellBoolEditor_new: { // wxGridCellBoolEditor::wxGridCellBoolEditor
+case wxGridCellBoolEditor_new: { // wxGridCellBoolEditor::wxGridCellBoolEditor
wxGridCellBoolEditor * Result = new wxGridCellBoolEditor();
newPtr((void *) Result, 25, memenv);
rt.addRef(getRef((void *)Result,memenv), "wxGridCellBoolEditor");
- break;
+ break;
}
-case wxGridCellBoolEditor_IsTrueValue: { // wxGridCellBoolEditor::IsTrueValue
+case wxGridCellBoolEditor_IsTrueValue: { // wxGridCellBoolEditor::IsTrueValue
int * valueLen = (int *) bp; bp += 4;
wxString value = wxString(bp, wxConvUTF8);
bp += *valueLen+((8-((4+ *valueLen) & 7)) & 7);
bool Result = wxGridCellBoolEditor::IsTrueValue(value);
rt.addBool(Result);
- break;
+ break;
}
-case wxGridCellBoolEditor_UseStringValues: { // wxGridCellBoolEditor::UseStringValues
+case wxGridCellBoolEditor_UseStringValues: { // wxGridCellBoolEditor::UseStringValues
wxString valueTrue= _T("1");
wxString valueFalse= wxEmptyString;
- while( * (int*) bp) { switch (* (int*) bp) {
+ while( * (int*) bp) { switch (* (int*) bp) {
case 1: {bp += 4;
int * valueTrueLen = (int *) bp; bp += 4;
valueTrue = wxString(bp, wxConvUTF8);
@@ -4489,140 +4489,140 @@ case wxGridCellBoolEditor_UseStringValues: { // wxGridCellBoolEditor::UseStringV
valueFalse = wxString(bp, wxConvUTF8);
bp += *valueFalseLen+((8-((0+ *valueFalseLen) & 7)) & 7);
} break;
- }};
+ }};
wxGridCellBoolEditor::UseStringValues(valueTrue,valueFalse);
- break;
+ break;
}
-case wxGridCellBoolEditor_destroy: { // wxGridCellBoolEditor::destroy
+case wxGridCellBoolEditor_destroy: { // wxGridCellBoolEditor::destroy
wxGridCellBoolEditor *This = (wxGridCellBoolEditor *) getPtr(bp,memenv); bp += 4;
if(This) { ((WxeApp *) wxTheApp)->clearPtr((void *) This);
delete This;}
- break;
+ break;
}
-case wxGridCellFloatRenderer_new: { // wxGridCellFloatRenderer::wxGridCellFloatRenderer
+case wxGridCellFloatRenderer_new: { // wxGridCellFloatRenderer::wxGridCellFloatRenderer
int width=-1;
int precision=-1;
- while( * (int*) bp) { switch (* (int*) bp) {
+ while( * (int*) bp) { switch (* (int*) bp) {
case 1: {bp += 4;
width = (int)*(int *) bp; bp += 4;
} break;
case 2: {bp += 4;
precision = (int)*(int *) bp; bp += 4;
} break;
- }};
+ }};
wxGridCellFloatRenderer * Result = new wxGridCellFloatRenderer(width,precision);
newPtr((void *) Result, 26, memenv);
rt.addRef(getRef((void *)Result,memenv), "wxGridCellFloatRenderer");
- break;
+ break;
}
-case wxGridCellFloatRenderer_GetPrecision: { // wxGridCellFloatRenderer::GetPrecision
+case wxGridCellFloatRenderer_GetPrecision: { // wxGridCellFloatRenderer::GetPrecision
wxGridCellFloatRenderer *This = (wxGridCellFloatRenderer *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
int Result = This->GetPrecision();
rt.addInt(Result);
- break;
+ break;
}
-case wxGridCellFloatRenderer_GetWidth: { // wxGridCellFloatRenderer::GetWidth
+case wxGridCellFloatRenderer_GetWidth: { // wxGridCellFloatRenderer::GetWidth
wxGridCellFloatRenderer *This = (wxGridCellFloatRenderer *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
int Result = This->GetWidth();
rt.addInt(Result);
- break;
+ break;
}
-case wxGridCellFloatRenderer_SetParameters: { // wxGridCellFloatRenderer::SetParameters
+case wxGridCellFloatRenderer_SetParameters: { // wxGridCellFloatRenderer::SetParameters
wxGridCellFloatRenderer *This = (wxGridCellFloatRenderer *) getPtr(bp,memenv); bp += 4;
int * paramsLen = (int *) bp; bp += 4;
wxString params = wxString(bp, wxConvUTF8);
bp += *paramsLen+((8-((0+ *paramsLen) & 7)) & 7);
if(!This) throw wxe_badarg(0);
This->SetParameters(params);
- break;
+ break;
}
-case wxGridCellFloatRenderer_SetPrecision: { // wxGridCellFloatRenderer::SetPrecision
+case wxGridCellFloatRenderer_SetPrecision: { // wxGridCellFloatRenderer::SetPrecision
wxGridCellFloatRenderer *This = (wxGridCellFloatRenderer *) getPtr(bp,memenv); bp += 4;
int * precision = (int *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
This->SetPrecision((int) *precision);
- break;
+ break;
}
-case wxGridCellFloatRenderer_SetWidth: { // wxGridCellFloatRenderer::SetWidth
+case wxGridCellFloatRenderer_SetWidth: { // wxGridCellFloatRenderer::SetWidth
wxGridCellFloatRenderer *This = (wxGridCellFloatRenderer *) getPtr(bp,memenv); bp += 4;
int * width = (int *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
This->SetWidth((int) *width);
- break;
+ break;
}
-case wxGridCellFloatRenderer_destroy: { // wxGridCellFloatRenderer::destroy
+case wxGridCellFloatRenderer_destroy: { // wxGridCellFloatRenderer::destroy
wxGridCellFloatRenderer *This = (wxGridCellFloatRenderer *) getPtr(bp,memenv); bp += 4;
if(This) { ((WxeApp *) wxTheApp)->clearPtr((void *) This);
delete This;}
- break;
+ break;
}
-case wxGridCellFloatEditor_new: { // wxGridCellFloatEditor::wxGridCellFloatEditor
+case wxGridCellFloatEditor_new: { // wxGridCellFloatEditor::wxGridCellFloatEditor
int width=-1;
int precision=-1;
- while( * (int*) bp) { switch (* (int*) bp) {
+ while( * (int*) bp) { switch (* (int*) bp) {
case 1: {bp += 4;
width = (int)*(int *) bp; bp += 4;
} break;
case 2: {bp += 4;
precision = (int)*(int *) bp; bp += 4;
} break;
- }};
+ }};
wxGridCellFloatEditor * Result = new wxGridCellFloatEditor(width,precision);
newPtr((void *) Result, 27, memenv);
rt.addRef(getRef((void *)Result,memenv), "wxGridCellFloatEditor");
- break;
+ break;
}
-case wxGridCellFloatEditor_SetParameters: { // wxGridCellFloatEditor::SetParameters
+case wxGridCellFloatEditor_SetParameters: { // wxGridCellFloatEditor::SetParameters
wxGridCellFloatEditor *This = (wxGridCellFloatEditor *) getPtr(bp,memenv); bp += 4;
int * paramsLen = (int *) bp; bp += 4;
wxString params = wxString(bp, wxConvUTF8);
bp += *paramsLen+((8-((0+ *paramsLen) & 7)) & 7);
if(!This) throw wxe_badarg(0);
This->SetParameters(params);
- break;
+ break;
}
-case wxGridCellFloatEditor_destroy: { // wxGridCellFloatEditor::destroy
+case wxGridCellFloatEditor_destroy: { // wxGridCellFloatEditor::destroy
wxGridCellFloatEditor *This = (wxGridCellFloatEditor *) getPtr(bp,memenv); bp += 4;
if(This) { ((WxeApp *) wxTheApp)->clearPtr((void *) This);
delete This;}
- break;
+ break;
}
-case wxGridCellStringRenderer_new: { // wxGridCellStringRenderer::wxGridCellStringRenderer
+case wxGridCellStringRenderer_new: { // wxGridCellStringRenderer::wxGridCellStringRenderer
wxGridCellStringRenderer * Result = new wxGridCellStringRenderer();
newPtr((void *) Result, 28, memenv);
rt.addRef(getRef((void *)Result,memenv), "wxGridCellStringRenderer");
- break;
+ break;
}
-case wxGridCellStringRenderer_destroy: { // wxGridCellStringRenderer::destroy
+case wxGridCellStringRenderer_destroy: { // wxGridCellStringRenderer::destroy
wxGridCellStringRenderer *This = (wxGridCellStringRenderer *) getPtr(bp,memenv); bp += 4;
if(This) { ((WxeApp *) wxTheApp)->clearPtr((void *) This);
delete This;}
- break;
+ break;
}
-case wxGridCellTextEditor_new: { // wxGridCellTextEditor::wxGridCellTextEditor
+case wxGridCellTextEditor_new: { // wxGridCellTextEditor::wxGridCellTextEditor
wxGridCellTextEditor * Result = new wxGridCellTextEditor();
newPtr((void *) Result, 29, memenv);
rt.addRef(getRef((void *)Result,memenv), "wxGridCellTextEditor");
- break;
+ break;
}
-case wxGridCellTextEditor_SetParameters: { // wxGridCellTextEditor::SetParameters
+case wxGridCellTextEditor_SetParameters: { // wxGridCellTextEditor::SetParameters
wxGridCellTextEditor *This = (wxGridCellTextEditor *) getPtr(bp,memenv); bp += 4;
int * paramsLen = (int *) bp; bp += 4;
wxString params = wxString(bp, wxConvUTF8);
bp += *paramsLen+((8-((0+ *paramsLen) & 7)) & 7);
if(!This) throw wxe_badarg(0);
This->SetParameters(params);
- break;
+ break;
}
-case wxGridCellTextEditor_destroy: { // wxGridCellTextEditor::destroy
+case wxGridCellTextEditor_destroy: { // wxGridCellTextEditor::destroy
wxGridCellTextEditor *This = (wxGridCellTextEditor *) getPtr(bp,memenv); bp += 4;
if(This) { ((WxeApp *) wxTheApp)->clearPtr((void *) This);
delete This;}
- break;
+ break;
}
-case wxGridCellChoiceEditor_new: { // wxGridCellChoiceEditor::wxGridCellChoiceEditor
+case wxGridCellChoiceEditor_new: { // wxGridCellChoiceEditor::wxGridCellChoiceEditor
bool allowOthers=false;
int * choicesLen = (int *) bp; bp += 4;
wxArrayString choices;
@@ -4634,82 +4634,82 @@ case wxGridCellChoiceEditor_new: { // wxGridCellChoiceEditor::wxGridCellChoiceEd
choicesASz += *choicesTemp+4;
}
bp += (8-((4+ choicesASz) & 7 )) & 7;
- while( * (int*) bp) { switch (* (int*) bp) {
+ while( * (int*) bp) { switch (* (int*) bp) {
case 1: {bp += 4;
allowOthers = *(bool *) bp; bp += 4;
} break;
- }};
+ }};
wxGridCellChoiceEditor * Result = new wxGridCellChoiceEditor(choices,allowOthers);
newPtr((void *) Result, 30, memenv);
rt.addRef(getRef((void *)Result,memenv), "wxGridCellChoiceEditor");
- break;
+ break;
}
-case wxGridCellChoiceEditor_SetParameters: { // wxGridCellChoiceEditor::SetParameters
+case wxGridCellChoiceEditor_SetParameters: { // wxGridCellChoiceEditor::SetParameters
wxGridCellChoiceEditor *This = (wxGridCellChoiceEditor *) getPtr(bp,memenv); bp += 4;
int * paramsLen = (int *) bp; bp += 4;
wxString params = wxString(bp, wxConvUTF8);
bp += *paramsLen+((8-((0+ *paramsLen) & 7)) & 7);
if(!This) throw wxe_badarg(0);
This->SetParameters(params);
- break;
+ break;
}
-case wxGridCellChoiceEditor_destroy: { // wxGridCellChoiceEditor::destroy
+case wxGridCellChoiceEditor_destroy: { // wxGridCellChoiceEditor::destroy
wxGridCellChoiceEditor *This = (wxGridCellChoiceEditor *) getPtr(bp,memenv); bp += 4;
if(This) { ((WxeApp *) wxTheApp)->clearPtr((void *) This);
delete This;}
- break;
+ break;
}
-case wxGridCellNumberRenderer_new: { // wxGridCellNumberRenderer::wxGridCellNumberRenderer
+case wxGridCellNumberRenderer_new: { // wxGridCellNumberRenderer::wxGridCellNumberRenderer
wxGridCellNumberRenderer * Result = new wxGridCellNumberRenderer();
newPtr((void *) Result, 31, memenv);
rt.addRef(getRef((void *)Result,memenv), "wxGridCellNumberRenderer");
- break;
+ break;
}
-case wxGridCellNumberRenderer_destroy: { // wxGridCellNumberRenderer::destroy
+case wxGridCellNumberRenderer_destroy: { // wxGridCellNumberRenderer::destroy
wxGridCellNumberRenderer *This = (wxGridCellNumberRenderer *) getPtr(bp,memenv); bp += 4;
if(This) { ((WxeApp *) wxTheApp)->clearPtr((void *) This);
delete This;}
- break;
+ break;
}
-case wxGridCellNumberEditor_new: { // wxGridCellNumberEditor::wxGridCellNumberEditor
+case wxGridCellNumberEditor_new: { // wxGridCellNumberEditor::wxGridCellNumberEditor
int min=-1;
int max=-1;
- while( * (int*) bp) { switch (* (int*) bp) {
+ while( * (int*) bp) { switch (* (int*) bp) {
case 1: {bp += 4;
min = (int)*(int *) bp; bp += 4;
} break;
case 2: {bp += 4;
max = (int)*(int *) bp; bp += 4;
} break;
- }};
+ }};
wxGridCellNumberEditor * Result = new wxGridCellNumberEditor(min,max);
newPtr((void *) Result, 32, memenv);
rt.addRef(getRef((void *)Result,memenv), "wxGridCellNumberEditor");
- break;
+ break;
}
-case wxGridCellNumberEditor_GetValue: { // wxGridCellNumberEditor::GetValue
+case wxGridCellNumberEditor_GetValue: { // wxGridCellNumberEditor::GetValue
wxGridCellNumberEditor *This = (wxGridCellNumberEditor *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
wxString Result = This->GetValue();
rt.add(Result);
- break;
+ break;
}
-case wxGridCellNumberEditor_SetParameters: { // wxGridCellNumberEditor::SetParameters
+case wxGridCellNumberEditor_SetParameters: { // wxGridCellNumberEditor::SetParameters
wxGridCellNumberEditor *This = (wxGridCellNumberEditor *) getPtr(bp,memenv); bp += 4;
int * paramsLen = (int *) bp; bp += 4;
wxString params = wxString(bp, wxConvUTF8);
bp += *paramsLen+((8-((0+ *paramsLen) & 7)) & 7);
if(!This) throw wxe_badarg(0);
This->SetParameters(params);
- break;
+ break;
}
-case wxGridCellNumberEditor_destroy: { // wxGridCellNumberEditor::destroy
+case wxGridCellNumberEditor_destroy: { // wxGridCellNumberEditor::destroy
wxGridCellNumberEditor *This = (wxGridCellNumberEditor *) getPtr(bp,memenv); bp += 4;
if(This) { ((WxeApp *) wxTheApp)->clearPtr((void *) This);
delete This;}
- break;
+ break;
}
-case wxGridCellAttr_SetTextColour: { // wxGridCellAttr::SetTextColour
+case wxGridCellAttr_SetTextColour: { // wxGridCellAttr::SetTextColour
wxGridCellAttr *This = (wxGridCellAttr *) getPtr(bp,memenv); bp += 4;
int * colTextR = (int *) bp; bp += 4;
int * colTextG = (int *) bp; bp += 4;
@@ -4718,9 +4718,9 @@ case wxGridCellAttr_SetTextColour: { // wxGridCellAttr::SetTextColour
wxColour colText = wxColour(*colTextR,*colTextG,*colTextB,*colTextA);
if(!This) throw wxe_badarg(0);
This->SetTextColour(colText);
- break;
+ break;
}
-case wxGridCellAttr_SetBackgroundColour: { // wxGridCellAttr::SetBackgroundColour
+case wxGridCellAttr_SetBackgroundColour: { // wxGridCellAttr::SetBackgroundColour
wxGridCellAttr *This = (wxGridCellAttr *) getPtr(bp,memenv); bp += 4;
int * colBackR = (int *) bp; bp += 4;
int * colBackG = (int *) bp; bp += 4;
@@ -4729,114 +4729,114 @@ case wxGridCellAttr_SetBackgroundColour: { // wxGridCellAttr::SetBackgroundColou
wxColour colBack = wxColour(*colBackR,*colBackG,*colBackB,*colBackA);
if(!This) throw wxe_badarg(0);
This->SetBackgroundColour(colBack);
- break;
+ break;
}
-case wxGridCellAttr_SetFont: { // wxGridCellAttr::SetFont
+case wxGridCellAttr_SetFont: { // wxGridCellAttr::SetFont
wxGridCellAttr *This = (wxGridCellAttr *) getPtr(bp,memenv); bp += 4;
wxFont *font = (wxFont *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
This->SetFont(*font);
- break;
+ break;
}
-case wxGridCellAttr_SetAlignment: { // wxGridCellAttr::SetAlignment
+case wxGridCellAttr_SetAlignment: { // wxGridCellAttr::SetAlignment
wxGridCellAttr *This = (wxGridCellAttr *) getPtr(bp,memenv); bp += 4;
int * hAlign = (int *) bp; bp += 4;
int * vAlign = (int *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
This->SetAlignment((int) *hAlign,(int) *vAlign);
- break;
+ break;
}
-case wxGridCellAttr_SetReadOnly: { // wxGridCellAttr::SetReadOnly
+case wxGridCellAttr_SetReadOnly: { // wxGridCellAttr::SetReadOnly
bool isReadOnly=true;
wxGridCellAttr *This = (wxGridCellAttr *) getPtr(bp,memenv); bp += 4;
bp += 4; /* Align */
- while( * (int*) bp) { switch (* (int*) bp) {
+ while( * (int*) bp) { switch (* (int*) bp) {
case 1: {bp += 4;
isReadOnly = *(bool *) bp; bp += 4;
} break;
- }};
+ }};
if(!This) throw wxe_badarg(0);
This->SetReadOnly(isReadOnly);
- break;
+ break;
}
-case wxGridCellAttr_SetRenderer: { // wxGridCellAttr::SetRenderer
+case wxGridCellAttr_SetRenderer: { // wxGridCellAttr::SetRenderer
wxGridCellAttr *This = (wxGridCellAttr *) getPtr(bp,memenv); bp += 4;
wxGridCellRenderer *renderer = (wxGridCellRenderer *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
This->SetRenderer(renderer);
- break;
+ break;
}
-case wxGridCellAttr_SetEditor: { // wxGridCellAttr::SetEditor
+case wxGridCellAttr_SetEditor: { // wxGridCellAttr::SetEditor
wxGridCellAttr *This = (wxGridCellAttr *) getPtr(bp,memenv); bp += 4;
wxGridCellEditor *editor = (wxGridCellEditor *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
This->SetEditor(editor);
- break;
+ break;
}
-case wxGridCellAttr_HasTextColour: { // wxGridCellAttr::HasTextColour
+case wxGridCellAttr_HasTextColour: { // wxGridCellAttr::HasTextColour
wxGridCellAttr *This = (wxGridCellAttr *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
bool Result = This->HasTextColour();
rt.addBool(Result);
- break;
+ break;
}
-case wxGridCellAttr_HasBackgroundColour: { // wxGridCellAttr::HasBackgroundColour
+case wxGridCellAttr_HasBackgroundColour: { // wxGridCellAttr::HasBackgroundColour
wxGridCellAttr *This = (wxGridCellAttr *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
bool Result = This->HasBackgroundColour();
rt.addBool(Result);
- break;
+ break;
}
-case wxGridCellAttr_HasFont: { // wxGridCellAttr::HasFont
+case wxGridCellAttr_HasFont: { // wxGridCellAttr::HasFont
wxGridCellAttr *This = (wxGridCellAttr *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
bool Result = This->HasFont();
rt.addBool(Result);
- break;
+ break;
}
-case wxGridCellAttr_HasAlignment: { // wxGridCellAttr::HasAlignment
+case wxGridCellAttr_HasAlignment: { // wxGridCellAttr::HasAlignment
wxGridCellAttr *This = (wxGridCellAttr *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
bool Result = This->HasAlignment();
rt.addBool(Result);
- break;
+ break;
}
-case wxGridCellAttr_HasRenderer: { // wxGridCellAttr::HasRenderer
+case wxGridCellAttr_HasRenderer: { // wxGridCellAttr::HasRenderer
wxGridCellAttr *This = (wxGridCellAttr *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
bool Result = This->HasRenderer();
rt.addBool(Result);
- break;
+ break;
}
-case wxGridCellAttr_HasEditor: { // wxGridCellAttr::HasEditor
+case wxGridCellAttr_HasEditor: { // wxGridCellAttr::HasEditor
wxGridCellAttr *This = (wxGridCellAttr *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
bool Result = This->HasEditor();
rt.addBool(Result);
- break;
+ break;
}
-case wxGridCellAttr_GetTextColour: { // wxGridCellAttr::GetTextColour
+case wxGridCellAttr_GetTextColour: { // wxGridCellAttr::GetTextColour
wxGridCellAttr *This = (wxGridCellAttr *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
const wxColour * Result = &This->GetTextColour();
rt.add((*Result));
- break;
+ break;
}
-case wxGridCellAttr_GetBackgroundColour: { // wxGridCellAttr::GetBackgroundColour
+case wxGridCellAttr_GetBackgroundColour: { // wxGridCellAttr::GetBackgroundColour
wxGridCellAttr *This = (wxGridCellAttr *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
const wxColour * Result = &This->GetBackgroundColour();
rt.add((*Result));
- break;
+ break;
}
-case wxGridCellAttr_GetFont: { // wxGridCellAttr::GetFont
+case wxGridCellAttr_GetFont: { // wxGridCellAttr::GetFont
wxGridCellAttr *This = (wxGridCellAttr *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
const wxFont * Result = &This->GetFont();
rt.addRef(getRef((void *)Result,memenv), "wxFont");
- break;
+ break;
}
-case wxGridCellAttr_GetAlignment: { // wxGridCellAttr::GetAlignment
+case wxGridCellAttr_GetAlignment: { // wxGridCellAttr::GetAlignment
int hAlign;
int vAlign;
wxGridCellAttr *This = (wxGridCellAttr *) getPtr(bp,memenv); bp += 4;
@@ -4845,9 +4845,9 @@ case wxGridCellAttr_GetAlignment: { // wxGridCellAttr::GetAlignment
rt.addInt(hAlign);
rt.addInt(vAlign);
rt.addTupleCount(2);
- break;
+ break;
}
-case wxGridCellAttr_GetRenderer: { // wxGridCellAttr::GetRenderer
+case wxGridCellAttr_GetRenderer: { // wxGridCellAttr::GetRenderer
wxGridCellAttr *This = (wxGridCellAttr *) getPtr(bp,memenv); bp += 4;
wxGrid *grid = (wxGrid *) getPtr(bp,memenv); bp += 4;
int * row = (int *) bp; bp += 4;
@@ -4855,9 +4855,9 @@ case wxGridCellAttr_GetRenderer: { // wxGridCellAttr::GetRenderer
if(!This) throw wxe_badarg(0);
wxGridCellRenderer * Result = (wxGridCellRenderer*)This->GetRenderer(grid,(int) *row,(int) *col);
rt.addRef(getRef((void *)Result,memenv), "wxGridCellRenderer");
- break;
+ break;
}
-case wxGridCellAttr_GetEditor: { // wxGridCellAttr::GetEditor
+case wxGridCellAttr_GetEditor: { // wxGridCellAttr::GetEditor
wxGridCellAttr *This = (wxGridCellAttr *) getPtr(bp,memenv); bp += 4;
wxGrid *grid = (wxGrid *) getPtr(bp,memenv); bp += 4;
int * row = (int *) bp; bp += 4;
@@ -4865,23 +4865,23 @@ case wxGridCellAttr_GetEditor: { // wxGridCellAttr::GetEditor
if(!This) throw wxe_badarg(0);
wxGridCellEditor * Result = (wxGridCellEditor*)This->GetEditor(grid,(int) *row,(int) *col);
rt.addRef(getRef((void *)Result,memenv), "wxGridCellEditor");
- break;
+ break;
}
-case wxGridCellAttr_IsReadOnly: { // wxGridCellAttr::IsReadOnly
+case wxGridCellAttr_IsReadOnly: { // wxGridCellAttr::IsReadOnly
wxGridCellAttr *This = (wxGridCellAttr *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
bool Result = This->IsReadOnly();
rt.addBool(Result);
- break;
+ break;
}
-case wxGridCellAttr_SetDefAttr: { // wxGridCellAttr::SetDefAttr
+case wxGridCellAttr_SetDefAttr: { // wxGridCellAttr::SetDefAttr
wxGridCellAttr *This = (wxGridCellAttr *) getPtr(bp,memenv); bp += 4;
wxGridCellAttr *defAttr = (wxGridCellAttr *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
This->SetDefAttr(defAttr);
- break;
+ break;
}
-case wxDC_Blit: { // wxDC::Blit
+case wxDC_Blit: { // wxDC::Blit
int rop=wxCOPY;
bool useMask=false;
wxPoint srcPtMask= wxDefaultPosition;
@@ -4896,7 +4896,7 @@ case wxDC_Blit: { // wxDC::Blit
int * srcPtX = (int *) bp; bp += 4;
int * srcPtY = (int *) bp; bp += 4;
wxPoint srcPt = wxPoint(*srcPtX,*srcPtY);
- while( * (int*) bp) { switch (* (int*) bp) {
+ while( * (int*) bp) { switch (* (int*) bp) {
case 1: {bp += 4;
rop = (int)*(int *) bp; bp += 4;
} break;
@@ -4909,80 +4909,80 @@ case wxDC_Blit: { // wxDC::Blit
srcPtMask = wxPoint(*srcPtMaskX,*srcPtMaskY);
bp += 4; /* Align */
} break;
- }};
+ }};
if(!This) throw wxe_badarg(0);
bool Result = This->Blit(destPt,sz,source,srcPt,rop,useMask,srcPtMask);
rt.addBool(Result);
- break;
+ break;
}
-case wxDC_CalcBoundingBox: { // wxDC::CalcBoundingBox
+case wxDC_CalcBoundingBox: { // wxDC::CalcBoundingBox
wxDC *This = (wxDC *) getPtr(bp,memenv); bp += 4;
int * x = (int *) bp; bp += 4;
int * y = (int *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
This->CalcBoundingBox((wxCoord) *x,(wxCoord) *y);
- break;
+ break;
}
-case wxDC_Clear: { // wxDC::Clear
+case wxDC_Clear: { // wxDC::Clear
wxDC *This = (wxDC *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
This->Clear();
- break;
+ break;
}
-case wxDC_ComputeScaleAndOrigin: { // wxDC::ComputeScaleAndOrigin
+case wxDC_ComputeScaleAndOrigin: { // wxDC::ComputeScaleAndOrigin
wxDC *This = (wxDC *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
This->ComputeScaleAndOrigin();
- break;
+ break;
}
-case wxDC_CrossHair: { // wxDC::CrossHair
+case wxDC_CrossHair: { // wxDC::CrossHair
wxDC *This = (wxDC *) getPtr(bp,memenv); bp += 4;
int * ptX = (int *) bp; bp += 4;
int * ptY = (int *) bp; bp += 4;
wxPoint pt = wxPoint(*ptX,*ptY);
if(!This) throw wxe_badarg(0);
This->CrossHair(pt);
- break;
+ break;
}
-case wxDC_DestroyClippingRegion: { // wxDC::DestroyClippingRegion
+case wxDC_DestroyClippingRegion: { // wxDC::DestroyClippingRegion
wxDC *This = (wxDC *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
This->DestroyClippingRegion();
- break;
+ break;
}
-case wxDC_DeviceToLogicalX: { // wxDC::DeviceToLogicalX
+case wxDC_DeviceToLogicalX: { // wxDC::DeviceToLogicalX
wxDC *This = (wxDC *) getPtr(bp,memenv); bp += 4;
int * x = (int *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
wxCoord Result = This->DeviceToLogicalX((wxCoord) *x);
rt.addInt(Result);
- break;
+ break;
}
-case wxDC_DeviceToLogicalXRel: { // wxDC::DeviceToLogicalXRel
+case wxDC_DeviceToLogicalXRel: { // wxDC::DeviceToLogicalXRel
wxDC *This = (wxDC *) getPtr(bp,memenv); bp += 4;
int * x = (int *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
wxCoord Result = This->DeviceToLogicalXRel((wxCoord) *x);
rt.addInt(Result);
- break;
+ break;
}
-case wxDC_DeviceToLogicalY: { // wxDC::DeviceToLogicalY
+case wxDC_DeviceToLogicalY: { // wxDC::DeviceToLogicalY
wxDC *This = (wxDC *) getPtr(bp,memenv); bp += 4;
int * y = (int *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
wxCoord Result = This->DeviceToLogicalY((wxCoord) *y);
rt.addInt(Result);
- break;
+ break;
}
-case wxDC_DeviceToLogicalYRel: { // wxDC::DeviceToLogicalYRel
+case wxDC_DeviceToLogicalYRel: { // wxDC::DeviceToLogicalYRel
wxDC *This = (wxDC *) getPtr(bp,memenv); bp += 4;
int * y = (int *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
wxCoord Result = This->DeviceToLogicalYRel((wxCoord) *y);
rt.addInt(Result);
- break;
+ break;
}
-case wxDC_DrawArc: { // wxDC::DrawArc
+case wxDC_DrawArc: { // wxDC::DrawArc
wxDC *This = (wxDC *) getPtr(bp,memenv); bp += 4;
int * pt1X = (int *) bp; bp += 4;
int * pt1Y = (int *) bp; bp += 4;
@@ -4995,25 +4995,25 @@ case wxDC_DrawArc: { // wxDC::DrawArc
wxPoint centre = wxPoint(*centreX,*centreY);
if(!This) throw wxe_badarg(0);
This->DrawArc(pt1,pt2,centre);
- break;
+ break;
}
-case wxDC_DrawBitmap: { // wxDC::DrawBitmap
+case wxDC_DrawBitmap: { // wxDC::DrawBitmap
bool useMask=false;
wxDC *This = (wxDC *) getPtr(bp,memenv); bp += 4;
wxBitmap *bmp = (wxBitmap *) getPtr(bp,memenv); bp += 4;
int * ptX = (int *) bp; bp += 4;
int * ptY = (int *) bp; bp += 4;
wxPoint pt = wxPoint(*ptX,*ptY);
- while( * (int*) bp) { switch (* (int*) bp) {
+ while( * (int*) bp) { switch (* (int*) bp) {
case 1: {bp += 4;
useMask = *(bool *) bp; bp += 4;
} break;
- }};
+ }};
if(!This) throw wxe_badarg(0);
This->DrawBitmap(*bmp,pt,useMask);
- break;
+ break;
}
-case wxDC_DrawCheckMark: { // wxDC::DrawCheckMark
+case wxDC_DrawCheckMark: { // wxDC::DrawCheckMark
wxDC *This = (wxDC *) getPtr(bp,memenv); bp += 4;
int * rectX = (int *) bp; bp += 4;
int * rectY = (int *) bp; bp += 4;
@@ -5022,9 +5022,9 @@ case wxDC_DrawCheckMark: { // wxDC::DrawCheckMark
wxRect rect = wxRect(*rectX,*rectY,*rectW,*rectH);
if(!This) throw wxe_badarg(0);
This->DrawCheckMark(rect);
- break;
+ break;
}
-case wxDC_DrawCircle: { // wxDC::DrawCircle
+case wxDC_DrawCircle: { // wxDC::DrawCircle
wxDC *This = (wxDC *) getPtr(bp,memenv); bp += 4;
int * ptX = (int *) bp; bp += 4;
int * ptY = (int *) bp; bp += 4;
@@ -5032,9 +5032,9 @@ case wxDC_DrawCircle: { // wxDC::DrawCircle
int * radius = (int *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
This->DrawCircle(pt,(wxCoord) *radius);
- break;
+ break;
}
-case wxDC_DrawEllipse_2: { // wxDC::DrawEllipse
+case wxDC_DrawEllipse_2: { // wxDC::DrawEllipse
wxDC *This = (wxDC *) getPtr(bp,memenv); bp += 4;
int * ptX = (int *) bp; bp += 4;
int * ptY = (int *) bp; bp += 4;
@@ -5044,9 +5044,9 @@ case wxDC_DrawEllipse_2: { // wxDC::DrawEllipse
wxSize sz = wxSize(*szW,*szH);
if(!This) throw wxe_badarg(0);
This->DrawEllipse(pt,sz);
- break;
+ break;
}
-case wxDC_DrawEllipse_1: { // wxDC::DrawEllipse
+case wxDC_DrawEllipse_1: { // wxDC::DrawEllipse
wxDC *This = (wxDC *) getPtr(bp,memenv); bp += 4;
int * rectX = (int *) bp; bp += 4;
int * rectY = (int *) bp; bp += 4;
@@ -5055,9 +5055,9 @@ case wxDC_DrawEllipse_1: { // wxDC::DrawEllipse
wxRect rect = wxRect(*rectX,*rectY,*rectW,*rectH);
if(!This) throw wxe_badarg(0);
This->DrawEllipse(rect);
- break;
+ break;
}
-case wxDC_DrawEllipticArc: { // wxDC::DrawEllipticArc
+case wxDC_DrawEllipticArc: { // wxDC::DrawEllipticArc
wxDC *This = (wxDC *) getPtr(bp,memenv); bp += 4;
int * ptX = (int *) bp; bp += 4;
int * ptY = (int *) bp; bp += 4;
@@ -5070,9 +5070,9 @@ case wxDC_DrawEllipticArc: { // wxDC::DrawEllipticArc
double * ea = (double *) bp; bp += 8;
if(!This) throw wxe_badarg(0);
This->DrawEllipticArc(pt,sz,(double) *sa,(double) *ea);
- break;
+ break;
}
-case wxDC_DrawIcon: { // wxDC::DrawIcon
+case wxDC_DrawIcon: { // wxDC::DrawIcon
wxDC *This = (wxDC *) getPtr(bp,memenv); bp += 4;
wxIcon *icon = (wxIcon *) getPtr(bp,memenv); bp += 4;
int * ptX = (int *) bp; bp += 4;
@@ -5080,9 +5080,9 @@ case wxDC_DrawIcon: { // wxDC::DrawIcon
wxPoint pt = wxPoint(*ptX,*ptY);
if(!This) throw wxe_badarg(0);
This->DrawIcon(*icon,pt);
- break;
+ break;
}
-case wxDC_DrawLabel: { // wxDC::DrawLabel
+case wxDC_DrawLabel: { // wxDC::DrawLabel
int alignment=wxALIGN_LEFT|wxALIGN_TOP;
int indexAccel=-1;
wxDC *This = (wxDC *) getPtr(bp,memenv); bp += 4;
@@ -5094,19 +5094,19 @@ case wxDC_DrawLabel: { // wxDC::DrawLabel
int * rectW = (int *) bp; bp += 4;
int * rectH = (int *) bp; bp += 4;
wxRect rect = wxRect(*rectX,*rectY,*rectW,*rectH);
- while( * (int*) bp) { switch (* (int*) bp) {
+ while( * (int*) bp) { switch (* (int*) bp) {
case 1: {bp += 4;
alignment = (int)*(int *) bp; bp += 4;
} break;
case 2: {bp += 4;
indexAccel = (int)*(int *) bp; bp += 4;
} break;
- }};
+ }};
if(!This) throw wxe_badarg(0);
This->DrawLabel(text,rect,alignment,indexAccel);
- break;
+ break;
}
-case wxDC_DrawLine: { // wxDC::DrawLine
+case wxDC_DrawLine: { // wxDC::DrawLine
wxDC *This = (wxDC *) getPtr(bp,memenv); bp += 4;
int * pt1X = (int *) bp; bp += 4;
int * pt1Y = (int *) bp; bp += 4;
@@ -5116,9 +5116,9 @@ case wxDC_DrawLine: { // wxDC::DrawLine
wxPoint pt2 = wxPoint(*pt2X,*pt2Y);
if(!This) throw wxe_badarg(0);
This->DrawLine(pt1,pt2);
- break;
+ break;
}
-case wxDC_DrawLines: { // wxDC::DrawLines
+case wxDC_DrawLines: { // wxDC::DrawLines
wxCoord xoffset=0;
wxCoord yoffset=0;
wxDC *This = (wxDC *) getPtr(bp,memenv); bp += 4;
@@ -5129,20 +5129,20 @@ case wxDC_DrawLines: { // wxDC::DrawLines
int x = * (int *) bp; bp += 4;
int y = * (int *) bp; bp += 4;
points[i] = wxPoint(x,y);}
- while( * (int*) bp) { switch (* (int*) bp) {
+ while( * (int*) bp) { switch (* (int*) bp) {
case 1: {bp += 4;
xoffset = (wxCoord)*(int *) bp; bp += 4;
} break;
case 2: {bp += 4;
yoffset = (wxCoord)*(int *) bp; bp += 4;
} break;
- }};
+ }};
if(!This) throw wxe_badarg(0);
This->DrawLines(*pointsLen,points,xoffset,yoffset);
driver_free(points);
- break;
+ break;
}
-case wxDC_DrawPolygon: { // wxDC::DrawPolygon
+case wxDC_DrawPolygon: { // wxDC::DrawPolygon
wxCoord xoffset=0;
wxCoord yoffset=0;
int fillStyle=wxODDEVEN_RULE;
@@ -5154,7 +5154,7 @@ case wxDC_DrawPolygon: { // wxDC::DrawPolygon
int x = * (int *) bp; bp += 4;
int y = * (int *) bp; bp += 4;
points[i] = wxPoint(x,y);}
- while( * (int*) bp) { switch (* (int*) bp) {
+ while( * (int*) bp) { switch (* (int*) bp) {
case 1: {bp += 4;
xoffset = (wxCoord)*(int *) bp; bp += 4;
} break;
@@ -5164,22 +5164,22 @@ case wxDC_DrawPolygon: { // wxDC::DrawPolygon
case 3: {bp += 4;
fillStyle = (int)*(int *) bp; bp += 4;
} break;
- }};
+ }};
if(!This) throw wxe_badarg(0);
This->DrawPolygon(*pointsLen,points,xoffset,yoffset,fillStyle);
driver_free(points);
- break;
+ break;
}
-case wxDC_DrawPoint: { // wxDC::DrawPoint
+case wxDC_DrawPoint: { // wxDC::DrawPoint
wxDC *This = (wxDC *) getPtr(bp,memenv); bp += 4;
int * ptX = (int *) bp; bp += 4;
int * ptY = (int *) bp; bp += 4;
wxPoint pt = wxPoint(*ptX,*ptY);
if(!This) throw wxe_badarg(0);
This->DrawPoint(pt);
- break;
+ break;
}
-case wxDC_DrawRectangle_2: { // wxDC::DrawRectangle
+case wxDC_DrawRectangle_2: { // wxDC::DrawRectangle
wxDC *This = (wxDC *) getPtr(bp,memenv); bp += 4;
int * ptX = (int *) bp; bp += 4;
int * ptY = (int *) bp; bp += 4;
@@ -5189,9 +5189,9 @@ case wxDC_DrawRectangle_2: { // wxDC::DrawRectangle
wxSize sz = wxSize(*szW,*szH);
if(!This) throw wxe_badarg(0);
This->DrawRectangle(pt,sz);
- break;
+ break;
}
-case wxDC_DrawRectangle_1: { // wxDC::DrawRectangle
+case wxDC_DrawRectangle_1: { // wxDC::DrawRectangle
wxDC *This = (wxDC *) getPtr(bp,memenv); bp += 4;
int * rectX = (int *) bp; bp += 4;
int * rectY = (int *) bp; bp += 4;
@@ -5200,9 +5200,9 @@ case wxDC_DrawRectangle_1: { // wxDC::DrawRectangle
wxRect rect = wxRect(*rectX,*rectY,*rectW,*rectH);
if(!This) throw wxe_badarg(0);
This->DrawRectangle(rect);
- break;
+ break;
}
-case wxDC_DrawRotatedText: { // wxDC::DrawRotatedText
+case wxDC_DrawRotatedText: { // wxDC::DrawRotatedText
wxDC *This = (wxDC *) getPtr(bp,memenv); bp += 4;
int * textLen = (int *) bp; bp += 4;
wxString text = wxString(bp, wxConvUTF8);
@@ -5213,9 +5213,9 @@ case wxDC_DrawRotatedText: { // wxDC::DrawRotatedText
double * angle = (double *) bp; bp += 8;
if(!This) throw wxe_badarg(0);
This->DrawRotatedText(text,pt,(double) *angle);
- break;
+ break;
}
-case wxDC_DrawRoundedRectangle_3: { // wxDC::DrawRoundedRectangle
+case wxDC_DrawRoundedRectangle_3: { // wxDC::DrawRoundedRectangle
wxDC *This = (wxDC *) getPtr(bp,memenv); bp += 4;
int * ptX = (int *) bp; bp += 4;
int * ptY = (int *) bp; bp += 4;
@@ -5227,9 +5227,9 @@ case wxDC_DrawRoundedRectangle_3: { // wxDC::DrawRoundedRectangle
double * radius = (double *) bp; bp += 8;
if(!This) throw wxe_badarg(0);
This->DrawRoundedRectangle(pt,sz,(double) *radius);
- break;
+ break;
}
-case wxDC_DrawRoundedRectangle_2: { // wxDC::DrawRoundedRectangle
+case wxDC_DrawRoundedRectangle_2: { // wxDC::DrawRoundedRectangle
wxDC *This = (wxDC *) getPtr(bp,memenv); bp += 4;
int * rX = (int *) bp; bp += 4;
int * rY = (int *) bp; bp += 4;
@@ -5240,9 +5240,9 @@ case wxDC_DrawRoundedRectangle_2: { // wxDC::DrawRoundedRectangle
double * radius = (double *) bp; bp += 8;
if(!This) throw wxe_badarg(0);
This->DrawRoundedRectangle(r,(double) *radius);
- break;
+ break;
}
-case wxDC_DrawText: { // wxDC::DrawText
+case wxDC_DrawText: { // wxDC::DrawText
wxDC *This = (wxDC *) getPtr(bp,memenv); bp += 4;
int * textLen = (int *) bp; bp += 4;
wxString text = wxString(bp, wxConvUTF8);
@@ -5252,21 +5252,21 @@ case wxDC_DrawText: { // wxDC::DrawText
wxPoint pt = wxPoint(*ptX,*ptY);
if(!This) throw wxe_badarg(0);
This->DrawText(text,pt);
- break;
+ break;
}
-case wxDC_EndDoc: { // wxDC::EndDoc
+case wxDC_EndDoc: { // wxDC::EndDoc
wxDC *This = (wxDC *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
This->EndDoc();
- break;
+ break;
}
-case wxDC_EndPage: { // wxDC::EndPage
+case wxDC_EndPage: { // wxDC::EndPage
wxDC *This = (wxDC *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
This->EndPage();
- break;
+ break;
}
-case wxDC_FloodFill: { // wxDC::FloodFill
+case wxDC_FloodFill: { // wxDC::FloodFill
int style=wxFLOOD_SURFACE;
wxDC *This = (wxDC *) getPtr(bp,memenv); bp += 4;
int * ptX = (int *) bp; bp += 4;
@@ -5278,52 +5278,52 @@ case wxDC_FloodFill: { // wxDC::FloodFill
int * colA = (int *) bp; bp += 4;
wxColour col = wxColour(*colR,*colG,*colB,*colA);
bp += 4; /* Align */
- while( * (int*) bp) { switch (* (int*) bp) {
+ while( * (int*) bp) { switch (* (int*) bp) {
case 1: {bp += 4;
style = (int)*(int *) bp; bp += 4;
} break;
- }};
+ }};
if(!This) throw wxe_badarg(0);
bool Result = This->FloodFill(pt,col,style);
rt.addBool(Result);
- break;
+ break;
}
-case wxDC_GetBackground: { // wxDC::GetBackground
+case wxDC_GetBackground: { // wxDC::GetBackground
wxDC *This = (wxDC *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
const wxBrush * Result = &This->GetBackground();
rt.addRef(getRef((void *)Result,memenv), "wxBrush");
- break;
+ break;
}
-case wxDC_GetBackgroundMode: { // wxDC::GetBackgroundMode
+case wxDC_GetBackgroundMode: { // wxDC::GetBackgroundMode
wxDC *This = (wxDC *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
int Result = This->GetBackgroundMode();
rt.addInt(Result);
- break;
+ break;
}
-case wxDC_GetBrush: { // wxDC::GetBrush
+case wxDC_GetBrush: { // wxDC::GetBrush
wxDC *This = (wxDC *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
const wxBrush * Result = &This->GetBrush();
rt.addRef(getRef((void *)Result,memenv), "wxBrush");
- break;
+ break;
}
-case wxDC_GetCharHeight: { // wxDC::GetCharHeight
+case wxDC_GetCharHeight: { // wxDC::GetCharHeight
wxDC *This = (wxDC *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
wxCoord Result = This->GetCharHeight();
rt.addInt(Result);
- break;
+ break;
}
-case wxDC_GetCharWidth: { // wxDC::GetCharWidth
+case wxDC_GetCharWidth: { // wxDC::GetCharWidth
wxDC *This = (wxDC *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
wxCoord Result = This->GetCharWidth();
rt.addInt(Result);
- break;
+ break;
}
-case wxDC_GetClippingBox: { // wxDC::GetClippingBox
+case wxDC_GetClippingBox: { // wxDC::GetClippingBox
wxDC *This = (wxDC *) getPtr(bp,memenv); bp += 4;
int * rectX = (int *) bp; bp += 4;
int * rectY = (int *) bp; bp += 4;
@@ -5332,37 +5332,37 @@ case wxDC_GetClippingBox: { // wxDC::GetClippingBox
wxRect rect = wxRect(*rectX,*rectY,*rectW,*rectH);
if(!This) throw wxe_badarg(0);
This->GetClippingBox(rect);
- break;
+ break;
}
-case wxDC_GetFont: { // wxDC::GetFont
+case wxDC_GetFont: { // wxDC::GetFont
wxDC *This = (wxDC *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
const wxFont * Result = &This->GetFont();
rt.addRef(getRef((void *)Result,memenv), "wxFont");
- break;
+ break;
}
-case wxDC_GetLayoutDirection: { // wxDC::GetLayoutDirection
+case wxDC_GetLayoutDirection: { // wxDC::GetLayoutDirection
wxDC *This = (wxDC *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
int Result = This->GetLayoutDirection();
rt.addInt(Result);
- break;
+ break;
}
-case wxDC_GetLogicalFunction: { // wxDC::GetLogicalFunction
+case wxDC_GetLogicalFunction: { // wxDC::GetLogicalFunction
wxDC *This = (wxDC *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
int Result = This->GetLogicalFunction();
rt.addInt(Result);
- break;
+ break;
}
-case wxDC_GetMapMode: { // wxDC::GetMapMode
+case wxDC_GetMapMode: { // wxDC::GetMapMode
wxDC *This = (wxDC *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
int Result = This->GetMapMode();
rt.addInt(Result);
- break;
+ break;
}
-case wxDC_GetMultiLineTextExtent_4: { // wxDC::GetMultiLineTextExtent
+case wxDC_GetMultiLineTextExtent_4: { // wxDC::GetMultiLineTextExtent
wxCoord width;
wxCoord height;
wxCoord heightLine;
@@ -5371,20 +5371,20 @@ case wxDC_GetMultiLineTextExtent_4: { // wxDC::GetMultiLineTextExtent
int * stringLen = (int *) bp; bp += 4;
wxString string = wxString(bp, wxConvUTF8);
bp += *stringLen+((8-((0+ *stringLen) & 7)) & 7);
- while( * (int*) bp) { switch (* (int*) bp) {
+ while( * (int*) bp) { switch (* (int*) bp) {
case 1: {bp += 4;
font = (wxFont *) getPtr(bp,memenv); bp += 4;
} break;
- }};
+ }};
if(!This) throw wxe_badarg(0);
This->GetMultiLineTextExtent(string,&width,&height,&heightLine,font);
rt.addInt(width);
rt.addInt(height);
rt.addInt(heightLine);
rt.addTupleCount(3);
- break;
+ break;
}
-case wxDC_GetMultiLineTextExtent_1: { // wxDC::GetMultiLineTextExtent
+case wxDC_GetMultiLineTextExtent_1: { // wxDC::GetMultiLineTextExtent
wxDC *This = (wxDC *) getPtr(bp,memenv); bp += 4;
int * stringLen = (int *) bp; bp += 4;
wxString string = wxString(bp, wxConvUTF8);
@@ -5392,9 +5392,9 @@ case wxDC_GetMultiLineTextExtent_1: { // wxDC::GetMultiLineTextExtent
if(!This) throw wxe_badarg(0);
wxSize Result = This->GetMultiLineTextExtent(string);
rt.add(Result);
- break;
+ break;
}
-case wxDC_GetPartialTextExtents: { // wxDC::GetPartialTextExtents
+case wxDC_GetPartialTextExtents: { // wxDC::GetPartialTextExtents
wxDC *This = (wxDC *) getPtr(bp,memenv); bp += 4;
int * textLen = (int *) bp; bp += 4;
wxString text = wxString(bp, wxConvUTF8);
@@ -5406,16 +5406,16 @@ case wxDC_GetPartialTextExtents: { // wxDC::GetPartialTextExtents
if(!This) throw wxe_badarg(0);
bool Result = This->GetPartialTextExtents(text,widths);
rt.addBool(Result);
- break;
+ break;
}
-case wxDC_GetPen: { // wxDC::GetPen
+case wxDC_GetPen: { // wxDC::GetPen
wxDC *This = (wxDC *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
const wxPen * Result = &This->GetPen();
rt.addRef(getRef((void *)Result,memenv), "wxPen");
- break;
+ break;
}
-case wxDC_GetPixel: { // wxDC::GetPixel
+case wxDC_GetPixel: { // wxDC::GetPixel
wxDC *This = (wxDC *) getPtr(bp,memenv); bp += 4;
int * ptX = (int *) bp; bp += 4;
int * ptY = (int *) bp; bp += 4;
@@ -5428,37 +5428,37 @@ case wxDC_GetPixel: { // wxDC::GetPixel
if(!This) throw wxe_badarg(0);
bool Result = This->GetPixel(pt,&col);
rt.addBool(Result);
- break;
+ break;
}
-case wxDC_GetPPI: { // wxDC::GetPPI
+case wxDC_GetPPI: { // wxDC::GetPPI
wxDC *This = (wxDC *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
wxSize Result = This->GetPPI();
rt.add(Result);
- break;
+ break;
}
-case wxDC_GetSize: { // wxDC::GetSize
+case wxDC_GetSize: { // wxDC::GetSize
wxDC *This = (wxDC *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
wxSize Result = This->GetSize();
rt.add(Result);
- break;
+ break;
}
-case wxDC_GetSizeMM: { // wxDC::GetSizeMM
+case wxDC_GetSizeMM: { // wxDC::GetSizeMM
wxDC *This = (wxDC *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
wxSize Result = This->GetSizeMM();
rt.add(Result);
- break;
+ break;
}
-case wxDC_GetTextBackground: { // wxDC::GetTextBackground
+case wxDC_GetTextBackground: { // wxDC::GetTextBackground
wxDC *This = (wxDC *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
const wxColour * Result = &This->GetTextBackground();
rt.add((*Result));
- break;
+ break;
}
-case wxDC_GetTextExtent_4: { // wxDC::GetTextExtent
+case wxDC_GetTextExtent_4: { // wxDC::GetTextExtent
wxCoord x;
wxCoord y;
wxCoord descent;
@@ -5468,11 +5468,11 @@ case wxDC_GetTextExtent_4: { // wxDC::GetTextExtent
int * stringLen = (int *) bp; bp += 4;
wxString string = wxString(bp, wxConvUTF8);
bp += *stringLen+((8-((0+ *stringLen) & 7)) & 7);
- while( * (int*) bp) { switch (* (int*) bp) {
+ while( * (int*) bp) { switch (* (int*) bp) {
case 1: {bp += 4;
theFont = (wxFont *) getPtr(bp,memenv); bp += 4;
} break;
- }};
+ }};
if(!This) throw wxe_badarg(0);
This->GetTextExtent(string,&x,&y,&descent,&externalLeading,theFont);
rt.addInt(x);
@@ -5480,9 +5480,9 @@ theFont = (wxFont *) getPtr(bp,memenv); bp += 4;
rt.addInt(descent);
rt.addInt(externalLeading);
rt.addTupleCount(4);
- break;
+ break;
}
-case wxDC_GetTextExtent_1: { // wxDC::GetTextExtent
+case wxDC_GetTextExtent_1: { // wxDC::GetTextExtent
wxDC *This = (wxDC *) getPtr(bp,memenv); bp += 4;
int * stringLen = (int *) bp; bp += 4;
wxString string = wxString(bp, wxConvUTF8);
@@ -5490,16 +5490,16 @@ case wxDC_GetTextExtent_1: { // wxDC::GetTextExtent
if(!This) throw wxe_badarg(0);
wxSize Result = This->GetTextExtent(string);
rt.add(Result);
- break;
+ break;
}
-case wxDC_GetTextForeground: { // wxDC::GetTextForeground
+case wxDC_GetTextForeground: { // wxDC::GetTextForeground
wxDC *This = (wxDC *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
const wxColour * Result = &This->GetTextForeground();
rt.add((*Result));
- break;
+ break;
}
-case wxDC_GetUserScale: { // wxDC::GetUserScale
+case wxDC_GetUserScale: { // wxDC::GetUserScale
double x;
double y;
wxDC *This = (wxDC *) getPtr(bp,memenv); bp += 4;
@@ -5508,9 +5508,9 @@ case wxDC_GetUserScale: { // wxDC::GetUserScale
rt.addFloat(x);
rt.addFloat(y);
rt.addTupleCount(2);
- break;
+ break;
}
-case wxDC_GradientFillConcentric_3: { // wxDC::GradientFillConcentric
+case wxDC_GradientFillConcentric_3: { // wxDC::GradientFillConcentric
wxDC *This = (wxDC *) getPtr(bp,memenv); bp += 4;
int * rectX = (int *) bp; bp += 4;
int * rectY = (int *) bp; bp += 4;
@@ -5529,9 +5529,9 @@ case wxDC_GradientFillConcentric_3: { // wxDC::GradientFillConcentric
wxColour destColour = wxColour(*destColourR,*destColourG,*destColourB,*destColourA);
if(!This) throw wxe_badarg(0);
This->GradientFillConcentric(rect,initialColour,destColour);
- break;
+ break;
}
-case wxDC_GradientFillConcentric_4: { // wxDC::GradientFillConcentric
+case wxDC_GradientFillConcentric_4: { // wxDC::GradientFillConcentric
wxDC *This = (wxDC *) getPtr(bp,memenv); bp += 4;
int * rectX = (int *) bp; bp += 4;
int * rectY = (int *) bp; bp += 4;
@@ -5553,9 +5553,9 @@ case wxDC_GradientFillConcentric_4: { // wxDC::GradientFillConcentric
wxPoint circleCenter = wxPoint(*circleCenterX,*circleCenterY);
if(!This) throw wxe_badarg(0);
This->GradientFillConcentric(rect,initialColour,destColour,circleCenter);
- break;
+ break;
}
-case wxDC_GradientFillLinear: { // wxDC::GradientFillLinear
+case wxDC_GradientFillLinear: { // wxDC::GradientFillLinear
wxDirection nDirection=wxEAST;
wxDC *This = (wxDC *) getPtr(bp,memenv); bp += 4;
int * rectX = (int *) bp; bp += 4;
@@ -5574,118 +5574,118 @@ case wxDC_GradientFillLinear: { // wxDC::GradientFillLinear
int * destColourA = (int *) bp; bp += 4;
wxColour destColour = wxColour(*destColourR,*destColourG,*destColourB,*destColourA);
bp += 4; /* Align */
- while( * (int*) bp) { switch (* (int*) bp) {
+ while( * (int*) bp) { switch (* (int*) bp) {
case 1: {bp += 4;
nDirection = *(wxDirection *) bp; bp += 4;;
} break;
- }};
+ }};
if(!This) throw wxe_badarg(0);
This->GradientFillLinear(rect,initialColour,destColour,(wxDirection) nDirection);
- break;
+ break;
}
-case wxDC_LogicalToDeviceX: { // wxDC::LogicalToDeviceX
+case wxDC_LogicalToDeviceX: { // wxDC::LogicalToDeviceX
wxDC *This = (wxDC *) getPtr(bp,memenv); bp += 4;
int * x = (int *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
wxCoord Result = This->LogicalToDeviceX((wxCoord) *x);
rt.addInt(Result);
- break;
+ break;
}
-case wxDC_LogicalToDeviceXRel: { // wxDC::LogicalToDeviceXRel
+case wxDC_LogicalToDeviceXRel: { // wxDC::LogicalToDeviceXRel
wxDC *This = (wxDC *) getPtr(bp,memenv); bp += 4;
int * x = (int *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
wxCoord Result = This->LogicalToDeviceXRel((wxCoord) *x);
rt.addInt(Result);
- break;
+ break;
}
-case wxDC_LogicalToDeviceY: { // wxDC::LogicalToDeviceY
+case wxDC_LogicalToDeviceY: { // wxDC::LogicalToDeviceY
wxDC *This = (wxDC *) getPtr(bp,memenv); bp += 4;
int * y = (int *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
wxCoord Result = This->LogicalToDeviceY((wxCoord) *y);
rt.addInt(Result);
- break;
+ break;
}
-case wxDC_LogicalToDeviceYRel: { // wxDC::LogicalToDeviceYRel
+case wxDC_LogicalToDeviceYRel: { // wxDC::LogicalToDeviceYRel
wxDC *This = (wxDC *) getPtr(bp,memenv); bp += 4;
int * y = (int *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
wxCoord Result = This->LogicalToDeviceYRel((wxCoord) *y);
rt.addInt(Result);
- break;
+ break;
}
-case wxDC_MaxX: { // wxDC::MaxX
+case wxDC_MaxX: { // wxDC::MaxX
wxDC *This = (wxDC *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
wxCoord Result = This->MaxX();
rt.addInt(Result);
- break;
+ break;
}
-case wxDC_MaxY: { // wxDC::MaxY
+case wxDC_MaxY: { // wxDC::MaxY
wxDC *This = (wxDC *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
wxCoord Result = This->MaxY();
rt.addInt(Result);
- break;
+ break;
}
-case wxDC_MinX: { // wxDC::MinX
+case wxDC_MinX: { // wxDC::MinX
wxDC *This = (wxDC *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
wxCoord Result = This->MinX();
rt.addInt(Result);
- break;
+ break;
}
-case wxDC_MinY: { // wxDC::MinY
+case wxDC_MinY: { // wxDC::MinY
wxDC *This = (wxDC *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
wxCoord Result = This->MinY();
rt.addInt(Result);
- break;
+ break;
}
-case wxDC_IsOk: { // wxDC::IsOk
+case wxDC_IsOk: { // wxDC::IsOk
wxDC *This = (wxDC *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
bool Result = This->IsOk();
rt.addBool(Result);
- break;
+ break;
}
-case wxDC_ResetBoundingBox: { // wxDC::ResetBoundingBox
+case wxDC_ResetBoundingBox: { // wxDC::ResetBoundingBox
wxDC *This = (wxDC *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
This->ResetBoundingBox();
- break;
+ break;
}
-case wxDC_SetAxisOrientation: { // wxDC::SetAxisOrientation
+case wxDC_SetAxisOrientation: { // wxDC::SetAxisOrientation
wxDC *This = (wxDC *) getPtr(bp,memenv); bp += 4;
bool * xLeftRight = (bool *) bp; bp += 4;
bool * yBottomUp = (bool *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
This->SetAxisOrientation((bool) *xLeftRight,(bool) *yBottomUp);
- break;
+ break;
}
-case wxDC_SetBackground: { // wxDC::SetBackground
+case wxDC_SetBackground: { // wxDC::SetBackground
wxDC *This = (wxDC *) getPtr(bp,memenv); bp += 4;
wxBrush *brush = (wxBrush *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
This->SetBackground(*brush);
- break;
+ break;
}
-case wxDC_SetBackgroundMode: { // wxDC::SetBackgroundMode
+case wxDC_SetBackgroundMode: { // wxDC::SetBackgroundMode
wxDC *This = (wxDC *) getPtr(bp,memenv); bp += 4;
int * mode = (int *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
This->SetBackgroundMode((int) *mode);
- break;
+ break;
}
-case wxDC_SetBrush: { // wxDC::SetBrush
+case wxDC_SetBrush: { // wxDC::SetBrush
wxDC *This = (wxDC *) getPtr(bp,memenv); bp += 4;
wxBrush *brush = (wxBrush *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
This->SetBrush(*brush);
- break;
+ break;
}
-case wxDC_SetClippingRegion_2: { // wxDC::SetClippingRegion
+case wxDC_SetClippingRegion_2: { // wxDC::SetClippingRegion
wxDC *This = (wxDC *) getPtr(bp,memenv); bp += 4;
int * ptX = (int *) bp; bp += 4;
int * ptY = (int *) bp; bp += 4;
@@ -5695,9 +5695,9 @@ case wxDC_SetClippingRegion_2: { // wxDC::SetClippingRegion
wxSize sz = wxSize(*szW,*szH);
if(!This) throw wxe_badarg(0);
This->SetClippingRegion(pt,sz);
- break;
+ break;
}
-case wxDC_SetClippingRegion_1_1: { // wxDC::SetClippingRegion
+case wxDC_SetClippingRegion_1_1: { // wxDC::SetClippingRegion
wxDC *This = (wxDC *) getPtr(bp,memenv); bp += 4;
int * rectX = (int *) bp; bp += 4;
int * rectY = (int *) bp; bp += 4;
@@ -5706,66 +5706,66 @@ case wxDC_SetClippingRegion_1_1: { // wxDC::SetClippingRegion
wxRect rect = wxRect(*rectX,*rectY,*rectW,*rectH);
if(!This) throw wxe_badarg(0);
This->SetClippingRegion(rect);
- break;
+ break;
}
-case wxDC_SetClippingRegion_1_0: { // wxDC::SetClippingRegion
+case wxDC_SetClippingRegion_1_0: { // wxDC::SetClippingRegion
wxDC *This = (wxDC *) getPtr(bp,memenv); bp += 4;
wxRegion *region = (wxRegion *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
This->SetClippingRegion(*region);
- break;
+ break;
}
-case wxDC_SetDeviceOrigin: { // wxDC::SetDeviceOrigin
+case wxDC_SetDeviceOrigin: { // wxDC::SetDeviceOrigin
wxDC *This = (wxDC *) getPtr(bp,memenv); bp += 4;
int * x = (int *) bp; bp += 4;
int * y = (int *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
This->SetDeviceOrigin((wxCoord) *x,(wxCoord) *y);
- break;
+ break;
}
-case wxDC_SetFont: { // wxDC::SetFont
+case wxDC_SetFont: { // wxDC::SetFont
wxDC *This = (wxDC *) getPtr(bp,memenv); bp += 4;
wxFont *font = (wxFont *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
This->SetFont(*font);
- break;
+ break;
}
-case wxDC_SetLayoutDirection: { // wxDC::SetLayoutDirection
+case wxDC_SetLayoutDirection: { // wxDC::SetLayoutDirection
wxDC *This = (wxDC *) getPtr(bp,memenv); bp += 4;
wxLayoutDirection dir = *(wxLayoutDirection *) bp; bp += 4;;
if(!This) throw wxe_badarg(0);
This->SetLayoutDirection((wxLayoutDirection) dir);
- break;
+ break;
}
-case wxDC_SetLogicalFunction: { // wxDC::SetLogicalFunction
+case wxDC_SetLogicalFunction: { // wxDC::SetLogicalFunction
wxDC *This = (wxDC *) getPtr(bp,memenv); bp += 4;
int * function = (int *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
This->SetLogicalFunction((int) *function);
- break;
+ break;
}
-case wxDC_SetMapMode: { // wxDC::SetMapMode
+case wxDC_SetMapMode: { // wxDC::SetMapMode
wxDC *This = (wxDC *) getPtr(bp,memenv); bp += 4;
int * mode = (int *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
This->SetMapMode((int) *mode);
- break;
+ break;
}
-case wxDC_SetPalette: { // wxDC::SetPalette
+case wxDC_SetPalette: { // wxDC::SetPalette
wxDC *This = (wxDC *) getPtr(bp,memenv); bp += 4;
wxPalette *palette = (wxPalette *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
This->SetPalette(*palette);
- break;
+ break;
}
-case wxDC_SetPen: { // wxDC::SetPen
+case wxDC_SetPen: { // wxDC::SetPen
wxDC *This = (wxDC *) getPtr(bp,memenv); bp += 4;
wxPen *pen = (wxPen *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
This->SetPen(*pen);
- break;
+ break;
}
-case wxDC_SetTextBackground: { // wxDC::SetTextBackground
+case wxDC_SetTextBackground: { // wxDC::SetTextBackground
wxDC *This = (wxDC *) getPtr(bp,memenv); bp += 4;
int * colourR = (int *) bp; bp += 4;
int * colourG = (int *) bp; bp += 4;
@@ -5774,9 +5774,9 @@ case wxDC_SetTextBackground: { // wxDC::SetTextBackground
wxColour colour = wxColour(*colourR,*colourG,*colourB,*colourA);
if(!This) throw wxe_badarg(0);
This->SetTextBackground(colour);
- break;
+ break;
}
-case wxDC_SetTextForeground: { // wxDC::SetTextForeground
+case wxDC_SetTextForeground: { // wxDC::SetTextForeground
wxDC *This = (wxDC *) getPtr(bp,memenv); bp += 4;
int * colourR = (int *) bp; bp += 4;
int * colourG = (int *) bp; bp += 4;
@@ -5785,18 +5785,18 @@ case wxDC_SetTextForeground: { // wxDC::SetTextForeground
wxColour colour = wxColour(*colourR,*colourG,*colourB,*colourA);
if(!This) throw wxe_badarg(0);
This->SetTextForeground(colour);
- break;
+ break;
}
-case wxDC_SetUserScale: { // wxDC::SetUserScale
+case wxDC_SetUserScale: { // wxDC::SetUserScale
wxDC *This = (wxDC *) getPtr(bp,memenv); bp += 4;
bp += 4; /* Align */
double * x = (double *) bp; bp += 8;
double * y = (double *) bp; bp += 8;
if(!This) throw wxe_badarg(0);
This->SetUserScale((double) *x,(double) *y);
- break;
+ break;
}
-case wxDC_StartDoc: { // wxDC::StartDoc
+case wxDC_StartDoc: { // wxDC::StartDoc
wxDC *This = (wxDC *) getPtr(bp,memenv); bp += 4;
int * messageLen = (int *) bp; bp += 4;
wxString message = wxString(bp, wxConvUTF8);
@@ -5804,277 +5804,277 @@ case wxDC_StartDoc: { // wxDC::StartDoc
if(!This) throw wxe_badarg(0);
bool Result = This->StartDoc(message);
rt.addBool(Result);
- break;
+ break;
}
-case wxDC_StartPage: { // wxDC::StartPage
+case wxDC_StartPage: { // wxDC::StartPage
wxDC *This = (wxDC *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
This->StartPage();
- break;
+ break;
}
-case wxMirrorDC_new: { // wxMirrorDC::wxMirrorDC
+case wxMirrorDC_new: { // wxMirrorDC::wxMirrorDC
wxDC *dc = (wxDC *) getPtr(bp,memenv); bp += 4;
bool * mirror = (bool *) bp; bp += 4;
wxMirrorDC * Result = new EwxMirrorDC(*dc,(bool) *mirror);
newPtr((void *) Result, 1, memenv);
rt.addRef(getRef((void *)Result,memenv), "wxMirrorDC");
- break;
+ break;
}
-case wxScreenDC_new: { // wxScreenDC::wxScreenDC
+case wxScreenDC_new: { // wxScreenDC::wxScreenDC
wxScreenDC * Result = new EwxScreenDC();
newPtr((void *) Result, 1, memenv);
rt.addRef(getRef((void *)Result,memenv), "wxScreenDC");
- break;
+ break;
}
-case wxPostScriptDC_new_0: { // wxPostScriptDC::wxPostScriptDC
+case wxPostScriptDC_new_0: { // wxPostScriptDC::wxPostScriptDC
wxPostScriptDC * Result = new EwxPostScriptDC();
newPtr((void *) Result, 1, memenv);
rt.addRef(getRef((void *)Result,memenv), "wxPostScriptDC");
- break;
+ break;
}
-case wxPostScriptDC_new_1: { // wxPostScriptDC::wxPostScriptDC
+case wxPostScriptDC_new_1: { // wxPostScriptDC::wxPostScriptDC
wxPrintData *printData = (wxPrintData *) getPtr(bp,memenv); bp += 4;
wxPostScriptDC * Result = new EwxPostScriptDC(*printData);
newPtr((void *) Result, 1, memenv);
rt.addRef(getRef((void *)Result,memenv), "wxPostScriptDC");
- break;
+ break;
}
-case wxPostScriptDC_SetResolution: { // wxPostScriptDC::SetResolution
+case wxPostScriptDC_SetResolution: { // wxPostScriptDC::SetResolution
int * ppi = (int *) bp; bp += 4;
wxPostScriptDC::SetResolution((int) *ppi);
- break;
+ break;
}
-case wxPostScriptDC_GetResolution: { // wxPostScriptDC::GetResolution
+case wxPostScriptDC_GetResolution: { // wxPostScriptDC::GetResolution
int Result = wxPostScriptDC::GetResolution();
rt.addInt(Result);
- break;
+ break;
}
-case wxWindowDC_new_0: { // wxWindowDC::wxWindowDC
+case wxWindowDC_new_0: { // wxWindowDC::wxWindowDC
wxWindowDC * Result = new EwxWindowDC();
newPtr((void *) Result, 1, memenv);
rt.addRef(getRef((void *)Result,memenv), "wxWindowDC");
- break;
+ break;
}
-case wxWindowDC_new_1: { // wxWindowDC::wxWindowDC
+case wxWindowDC_new_1: { // wxWindowDC::wxWindowDC
wxWindow *win = (wxWindow *) getPtr(bp,memenv); bp += 4;
wxWindowDC * Result = new EwxWindowDC(win);
newPtr((void *) Result, 1, memenv);
rt.addRef(getRef((void *)Result,memenv), "wxWindowDC");
- break;
+ break;
}
-case wxClientDC_new_0: { // wxClientDC::wxClientDC
+case wxClientDC_new_0: { // wxClientDC::wxClientDC
wxClientDC * Result = new EwxClientDC();
newPtr((void *) Result, 1, memenv);
rt.addRef(getRef((void *)Result,memenv), "wxClientDC");
- break;
+ break;
}
-case wxClientDC_new_1: { // wxClientDC::wxClientDC
+case wxClientDC_new_1: { // wxClientDC::wxClientDC
wxWindow *win = (wxWindow *) getPtr(bp,memenv); bp += 4;
wxClientDC * Result = new EwxClientDC(win);
newPtr((void *) Result, 1, memenv);
rt.addRef(getRef((void *)Result,memenv), "wxClientDC");
- break;
+ break;
}
-case wxPaintDC_new_0: { // wxPaintDC::wxPaintDC
+case wxPaintDC_new_0: { // wxPaintDC::wxPaintDC
wxPaintDC * Result = new EwxPaintDC();
newPtr((void *) Result, 1, memenv);
rt.addRef(getRef((void *)Result,memenv), "wxPaintDC");
- break;
+ break;
}
-case wxPaintDC_new_1: { // wxPaintDC::wxPaintDC
+case wxPaintDC_new_1: { // wxPaintDC::wxPaintDC
wxWindow *win = (wxWindow *) getPtr(bp,memenv); bp += 4;
wxPaintDC * Result = new EwxPaintDC(win);
newPtr((void *) Result, 1, memenv);
rt.addRef(getRef((void *)Result,memenv), "wxPaintDC");
- break;
+ break;
}
-case wxMemoryDC_new_1_0: { // wxMemoryDC::wxMemoryDC
+case wxMemoryDC_new_1_0: { // wxMemoryDC::wxMemoryDC
wxBitmap *bitmap = (wxBitmap *) getPtr(bp,memenv); bp += 4;
wxMemoryDC * Result = new EwxMemoryDC(*bitmap);
newPtr((void *) Result, 1, memenv);
rt.addRef(getRef((void *)Result,memenv), "wxMemoryDC");
- break;
+ break;
}
-case wxMemoryDC_new_1_1: { // wxMemoryDC::wxMemoryDC
+case wxMemoryDC_new_1_1: { // wxMemoryDC::wxMemoryDC
wxDC * dc = (wxDC *) getPtr(bp,memenv); bp += 4;
wxMemoryDC * Result = new EwxMemoryDC(dc);
newPtr((void *) Result, 1, memenv);
rt.addRef(getRef((void *)Result,memenv), "wxMemoryDC");
- break;
+ break;
}
-case wxMemoryDC_new_0: { // wxMemoryDC::wxMemoryDC
+case wxMemoryDC_new_0: { // wxMemoryDC::wxMemoryDC
wxMemoryDC * Result = new EwxMemoryDC();
newPtr((void *) Result, 1, memenv);
rt.addRef(getRef((void *)Result,memenv), "wxMemoryDC");
- break;
+ break;
}
-case wxMemoryDC_SelectObject: { // wxMemoryDC::SelectObject
+case wxMemoryDC_SelectObject: { // wxMemoryDC::SelectObject
wxMemoryDC *This = (wxMemoryDC *) getPtr(bp,memenv); bp += 4;
wxBitmap *bmp = (wxBitmap *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
This->SelectObject(*bmp);
- break;
+ break;
}
-case wxMemoryDC_SelectObjectAsSource: { // wxMemoryDC::SelectObjectAsSource
+case wxMemoryDC_SelectObjectAsSource: { // wxMemoryDC::SelectObjectAsSource
wxMemoryDC *This = (wxMemoryDC *) getPtr(bp,memenv); bp += 4;
wxBitmap *bmp = (wxBitmap *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
This->SelectObjectAsSource(*bmp);
- break;
+ break;
}
-case wxBufferedDC_new_0: { // wxBufferedDC::wxBufferedDC
+case wxBufferedDC_new_0: { // wxBufferedDC::wxBufferedDC
wxBufferedDC * Result = new EwxBufferedDC();
newPtr((void *) Result, 1, memenv);
rt.addRef(getRef((void *)Result,memenv), "wxBufferedDC");
- break;
+ break;
}
-case wxBufferedDC_new_2: { // wxBufferedDC::wxBufferedDC
+case wxBufferedDC_new_2: { // wxBufferedDC::wxBufferedDC
wxBitmap * buffer= &wxNullBitmap;
int style=0x02;
wxDC *dc = (wxDC *) getPtr(bp,memenv); bp += 4;
bp += 4; /* Align */
- while( * (int*) bp) { switch (* (int*) bp) {
+ while( * (int*) bp) { switch (* (int*) bp) {
case 1: {bp += 4;
buffer = (wxBitmap *) getPtr(bp,memenv); bp += 4;
} break;
case 2: {bp += 4;
style = (int)*(int *) bp; bp += 4;
} break;
- }};
+ }};
wxBufferedDC * Result = new EwxBufferedDC(dc,*buffer,style);
newPtr((void *) Result, 1, memenv);
rt.addRef(getRef((void *)Result,memenv), "wxBufferedDC");
- break;
+ break;
}
-case wxBufferedDC_new_3: { // wxBufferedDC::wxBufferedDC
+case wxBufferedDC_new_3: { // wxBufferedDC::wxBufferedDC
int style=0x02;
wxDC *dc = (wxDC *) getPtr(bp,memenv); bp += 4;
int * areaW = (int *) bp; bp += 4;
int * areaH = (int *) bp; bp += 4;
wxSize area = wxSize(*areaW,*areaH);
bp += 4; /* Align */
- while( * (int*) bp) { switch (* (int*) bp) {
+ while( * (int*) bp) { switch (* (int*) bp) {
case 1: {bp += 4;
style = (int)*(int *) bp; bp += 4;
} break;
- }};
+ }};
wxBufferedDC * Result = new EwxBufferedDC(dc,area,style);
newPtr((void *) Result, 1, memenv);
rt.addRef(getRef((void *)Result,memenv), "wxBufferedDC");
- break;
+ break;
}
-case wxBufferedDC_Init_2: { // wxBufferedDC::Init
+case wxBufferedDC_Init_2: { // wxBufferedDC::Init
wxBitmap * buffer= &wxNullBitmap;
int style=0x02;
wxBufferedDC *This = (wxBufferedDC *) getPtr(bp,memenv); bp += 4;
wxDC *dc = (wxDC *) getPtr(bp,memenv); bp += 4;
- while( * (int*) bp) { switch (* (int*) bp) {
+ while( * (int*) bp) { switch (* (int*) bp) {
case 1: {bp += 4;
buffer = (wxBitmap *) getPtr(bp,memenv); bp += 4;
} break;
case 2: {bp += 4;
style = (int)*(int *) bp; bp += 4;
} break;
- }};
+ }};
if(!This) throw wxe_badarg(0);
This->Init(dc,*buffer,style);
- break;
+ break;
}
-case wxBufferedDC_Init_3: { // wxBufferedDC::Init
+case wxBufferedDC_Init_3: { // wxBufferedDC::Init
int style=0x02;
wxBufferedDC *This = (wxBufferedDC *) getPtr(bp,memenv); bp += 4;
wxDC *dc = (wxDC *) getPtr(bp,memenv); bp += 4;
int * areaW = (int *) bp; bp += 4;
int * areaH = (int *) bp; bp += 4;
wxSize area = wxSize(*areaW,*areaH);
- while( * (int*) bp) { switch (* (int*) bp) {
+ while( * (int*) bp) { switch (* (int*) bp) {
case 1: {bp += 4;
style = (int)*(int *) bp; bp += 4;
} break;
- }};
+ }};
if(!This) throw wxe_badarg(0);
This->Init(dc,area,style);
- break;
+ break;
}
-case wxBufferedPaintDC_new_3: { // wxBufferedPaintDC::wxBufferedPaintDC
+case wxBufferedPaintDC_new_3: { // wxBufferedPaintDC::wxBufferedPaintDC
int style=0x02;
wxWindow *window = (wxWindow *) getPtr(bp,memenv); bp += 4;
wxBitmap *buffer = (wxBitmap *) getPtr(bp,memenv); bp += 4;
- while( * (int*) bp) { switch (* (int*) bp) {
+ while( * (int*) bp) { switch (* (int*) bp) {
case 1: {bp += 4;
style = (int)*(int *) bp; bp += 4;
} break;
- }};
+ }};
wxBufferedPaintDC * Result = new EwxBufferedPaintDC(window,*buffer,style);
newPtr((void *) Result, 1, memenv);
rt.addRef(getRef((void *)Result,memenv), "wxBufferedPaintDC");
- break;
+ break;
}
-case wxBufferedPaintDC_new_2: { // wxBufferedPaintDC::wxBufferedPaintDC
+case wxBufferedPaintDC_new_2: { // wxBufferedPaintDC::wxBufferedPaintDC
int style=0x02;
wxWindow *window = (wxWindow *) getPtr(bp,memenv); bp += 4;
bp += 4; /* Align */
- while( * (int*) bp) { switch (* (int*) bp) {
+ while( * (int*) bp) { switch (* (int*) bp) {
case 1: {bp += 4;
style = (int)*(int *) bp; bp += 4;
} break;
- }};
+ }};
wxBufferedPaintDC * Result = new EwxBufferedPaintDC(window,style);
newPtr((void *) Result, 1, memenv);
rt.addRef(getRef((void *)Result,memenv), "wxBufferedPaintDC");
- break;
+ break;
}
#if wxUSE_GRAPHICS_CONTEXT
-case wxGraphicsObject_GetRenderer: { // wxGraphicsObject::GetRenderer
+case wxGraphicsObject_GetRenderer: { // wxGraphicsObject::GetRenderer
wxGraphicsObject *This = (wxGraphicsObject *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
wxGraphicsRenderer * Result = (wxGraphicsRenderer*)This->GetRenderer();
rt.addRef(getRef((void *)Result,memenv), "wxGraphicsRenderer");
- break;
+ break;
}
-case wxGraphicsObject_IsNull: { // wxGraphicsObject::IsNull
+case wxGraphicsObject_IsNull: { // wxGraphicsObject::IsNull
wxGraphicsObject *This = (wxGraphicsObject *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
bool Result = This->IsNull();
rt.addBool(Result);
- break;
+ break;
}
#endif // wxUSE_GRAPHICS_CONTEXT
#if wxUSE_GRAPHICS_CONTEXT
-case wxGraphicsContext_Create_1_1: { // wxGraphicsContext::Create
+case wxGraphicsContext_Create_1_1: { // wxGraphicsContext::Create
wxWindowDC * dc = (wxWindowDC *) getPtr(bp,memenv); bp += 4;
wxGraphicsContext * Result = (wxGraphicsContext*)wxGraphicsContext::Create(*dc);
rt.addRef(getRef((void *)Result,memenv), "wxGraphicsContext");
- break;
+ break;
}
-case wxGraphicsContext_Create_1_0: { // wxGraphicsContext::Create
+case wxGraphicsContext_Create_1_0: { // wxGraphicsContext::Create
wxWindow *window = (wxWindow *) getPtr(bp,memenv); bp += 4;
wxGraphicsContext * Result = (wxGraphicsContext*)wxGraphicsContext::Create(window);
rt.addRef(getRef((void *)Result,memenv), "wxGraphicsContext");
- break;
+ break;
}
-case wxGraphicsContext_Create_0: { // wxGraphicsContext::Create
+case wxGraphicsContext_Create_0: { // wxGraphicsContext::Create
wxGraphicsContext * Result = (wxGraphicsContext*)wxGraphicsContext::Create();
rt.addRef(getRef((void *)Result,memenv), "wxGraphicsContext");
- break;
+ break;
}
-case wxGraphicsContext_CreatePen: { // wxGraphicsContext::CreatePen
+case wxGraphicsContext_CreatePen: { // wxGraphicsContext::CreatePen
wxGraphicsContext *This = (wxGraphicsContext *) getPtr(bp,memenv); bp += 4;
wxPen *pen = (wxPen *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
wxGraphicsPen * Result = new wxGraphicsPen(This->CreatePen(*pen)); newPtr((void *) Result,3, memenv);;
rt.addRef(getRef((void *)Result,memenv), "wxGraphicsPen");
- break;
+ break;
}
-case wxGraphicsContext_CreateBrush: { // wxGraphicsContext::CreateBrush
+case wxGraphicsContext_CreateBrush: { // wxGraphicsContext::CreateBrush
wxGraphicsContext *This = (wxGraphicsContext *) getPtr(bp,memenv); bp += 4;
wxBrush *brush = (wxBrush *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
wxGraphicsBrush * Result = new wxGraphicsBrush(This->CreateBrush(*brush)); newPtr((void *) Result,3, memenv);;
rt.addRef(getRef((void *)Result,memenv), "wxGraphicsBrush");
- break;
+ break;
}
-case wxGraphicsContext_CreateRadialGradientBrush: { // wxGraphicsContext::CreateRadialGradientBrush
+case wxGraphicsContext_CreateRadialGradientBrush: { // wxGraphicsContext::CreateRadialGradientBrush
wxGraphicsContext *This = (wxGraphicsContext *) getPtr(bp,memenv); bp += 4;
bp += 4; /* Align */
wxDouble * xo = (wxDouble *) bp; bp += 8;
@@ -6095,9 +6095,9 @@ case wxGraphicsContext_CreateRadialGradientBrush: { // wxGraphicsContext::Create
if(!This) throw wxe_badarg(0);
wxGraphicsBrush * Result = new wxGraphicsBrush(This->CreateRadialGradientBrush((wxDouble) *xo,(wxDouble) *yo,(wxDouble) *xc,(wxDouble) *yc,(wxDouble) *radius,oColor,cColor)); newPtr((void *) Result,3, memenv);;
rt.addRef(getRef((void *)Result,memenv), "wxGraphicsBrush");
- break;
+ break;
}
-case wxGraphicsContext_CreateLinearGradientBrush: { // wxGraphicsContext::CreateLinearGradientBrush
+case wxGraphicsContext_CreateLinearGradientBrush: { // wxGraphicsContext::CreateLinearGradientBrush
wxGraphicsContext *This = (wxGraphicsContext *) getPtr(bp,memenv); bp += 4;
bp += 4; /* Align */
wxDouble * x1 = (wxDouble *) bp; bp += 8;
@@ -6117,13 +6117,13 @@ case wxGraphicsContext_CreateLinearGradientBrush: { // wxGraphicsContext::Create
if(!This) throw wxe_badarg(0);
wxGraphicsBrush * Result = new wxGraphicsBrush(This->CreateLinearGradientBrush((wxDouble) *x1,(wxDouble) *y1,(wxDouble) *x2,(wxDouble) *y2,c1,c2)); newPtr((void *) Result,3, memenv);;
rt.addRef(getRef((void *)Result,memenv), "wxGraphicsBrush");
- break;
+ break;
}
-case wxGraphicsContext_CreateFont: { // wxGraphicsContext::CreateFont
+case wxGraphicsContext_CreateFont: { // wxGraphicsContext::CreateFont
wxColour col= *wxBLACK;
wxGraphicsContext *This = (wxGraphicsContext *) getPtr(bp,memenv); bp += 4;
wxFont *font = (wxFont *) getPtr(bp,memenv); bp += 4;
- while( * (int*) bp) { switch (* (int*) bp) {
+ while( * (int*) bp) { switch (* (int*) bp) {
case 1: {bp += 4;
int * colR = (int *) bp; bp += 4;
int * colG = (int *) bp; bp += 4;
@@ -6132,13 +6132,13 @@ case wxGraphicsContext_CreateFont: { // wxGraphicsContext::CreateFont
col = wxColour(*colR,*colG,*colB,*colA);
bp += 4; /* Align */
} break;
- }};
+ }};
if(!This) throw wxe_badarg(0);
wxGraphicsFont * Result = new wxGraphicsFont(This->CreateFont(*font,col)); newPtr((void *) Result,3, memenv);;
rt.addRef(getRef((void *)Result,memenv), "wxGraphicsFont");
- break;
+ break;
}
-case wxGraphicsContext_CreateMatrix: { // wxGraphicsContext::CreateMatrix
+case wxGraphicsContext_CreateMatrix: { // wxGraphicsContext::CreateMatrix
wxDouble a=1.0;
wxDouble b=0.0;
wxDouble c=0.0;
@@ -6147,7 +6147,7 @@ case wxGraphicsContext_CreateMatrix: { // wxGraphicsContext::CreateMatrix
wxDouble ty=0.0;
wxGraphicsContext *This = (wxGraphicsContext *) getPtr(bp,memenv); bp += 4;
bp += 4; /* Align */
- while( * (int*) bp) { switch (* (int*) bp) {
+ while( * (int*) bp) { switch (* (int*) bp) {
case 1: {bp += 4;
bp += 4; /* Align */
a = * (wxDouble *) bp; bp += 8;
@@ -6172,27 +6172,27 @@ case wxGraphicsContext_CreateMatrix: { // wxGraphicsContext::CreateMatrix
bp += 4; /* Align */
ty = * (wxDouble *) bp; bp += 8;
} break;
- }};
+ }};
if(!This) throw wxe_badarg(0);
wxGraphicsMatrix * Result = new wxGraphicsMatrix(This->CreateMatrix(a,b,c,d,tx,ty)); newPtr((void *) Result,3, memenv);;
rt.addRef(getRef((void *)Result,memenv), "wxGraphicsMatrix");
- break;
+ break;
}
-case wxGraphicsContext_CreatePath: { // wxGraphicsContext::CreatePath
+case wxGraphicsContext_CreatePath: { // wxGraphicsContext::CreatePath
wxGraphicsContext *This = (wxGraphicsContext *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
wxGraphicsPath * Result = new wxGraphicsPath(This->CreatePath()); newPtr((void *) Result,3, memenv);;
rt.addRef(getRef((void *)Result,memenv), "wxGraphicsPath");
- break;
+ break;
}
-case wxGraphicsContext_Clip_1: { // wxGraphicsContext::Clip
+case wxGraphicsContext_Clip_1: { // wxGraphicsContext::Clip
wxGraphicsContext *This = (wxGraphicsContext *) getPtr(bp,memenv); bp += 4;
wxRegion *region = (wxRegion *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
This->Clip(*region);
- break;
+ break;
}
-case wxGraphicsContext_Clip_4: { // wxGraphicsContext::Clip
+case wxGraphicsContext_Clip_4: { // wxGraphicsContext::Clip
wxGraphicsContext *This = (wxGraphicsContext *) getPtr(bp,memenv); bp += 4;
bp += 4; /* Align */
wxDouble * x = (wxDouble *) bp; bp += 8;
@@ -6201,15 +6201,15 @@ case wxGraphicsContext_Clip_4: { // wxGraphicsContext::Clip
wxDouble * h = (wxDouble *) bp; bp += 8;
if(!This) throw wxe_badarg(0);
This->Clip((wxDouble) *x,(wxDouble) *y,(wxDouble) *w,(wxDouble) *h);
- break;
+ break;
}
-case wxGraphicsContext_ResetClip: { // wxGraphicsContext::ResetClip
+case wxGraphicsContext_ResetClip: { // wxGraphicsContext::ResetClip
wxGraphicsContext *This = (wxGraphicsContext *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
This->ResetClip();
- break;
+ break;
}
-case wxGraphicsContext_DrawBitmap: { // wxGraphicsContext::DrawBitmap
+case wxGraphicsContext_DrawBitmap: { // wxGraphicsContext::DrawBitmap
wxGraphicsContext *This = (wxGraphicsContext *) getPtr(bp,memenv); bp += 4;
wxBitmap *bmp = (wxBitmap *) getPtr(bp,memenv); bp += 4;
wxDouble * x = (wxDouble *) bp; bp += 8;
@@ -6218,9 +6218,9 @@ case wxGraphicsContext_DrawBitmap: { // wxGraphicsContext::DrawBitmap
wxDouble * h = (wxDouble *) bp; bp += 8;
if(!This) throw wxe_badarg(0);
This->DrawBitmap(*bmp,(wxDouble) *x,(wxDouble) *y,(wxDouble) *w,(wxDouble) *h);
- break;
+ break;
}
-case wxGraphicsContext_DrawEllipse: { // wxGraphicsContext::DrawEllipse
+case wxGraphicsContext_DrawEllipse: { // wxGraphicsContext::DrawEllipse
wxGraphicsContext *This = (wxGraphicsContext *) getPtr(bp,memenv); bp += 4;
bp += 4; /* Align */
wxDouble * x = (wxDouble *) bp; bp += 8;
@@ -6229,9 +6229,9 @@ case wxGraphicsContext_DrawEllipse: { // wxGraphicsContext::DrawEllipse
wxDouble * h = (wxDouble *) bp; bp += 8;
if(!This) throw wxe_badarg(0);
This->DrawEllipse((wxDouble) *x,(wxDouble) *y,(wxDouble) *w,(wxDouble) *h);
- break;
+ break;
}
-case wxGraphicsContext_DrawIcon: { // wxGraphicsContext::DrawIcon
+case wxGraphicsContext_DrawIcon: { // wxGraphicsContext::DrawIcon
wxGraphicsContext *This = (wxGraphicsContext *) getPtr(bp,memenv); bp += 4;
wxIcon *icon = (wxIcon *) getPtr(bp,memenv); bp += 4;
wxDouble * x = (wxDouble *) bp; bp += 8;
@@ -6240,38 +6240,38 @@ case wxGraphicsContext_DrawIcon: { // wxGraphicsContext::DrawIcon
wxDouble * h = (wxDouble *) bp; bp += 8;
if(!This) throw wxe_badarg(0);
This->DrawIcon(*icon,(wxDouble) *x,(wxDouble) *y,(wxDouble) *w,(wxDouble) *h);
- break;
+ break;
}
-case wxGraphicsContext_DrawLines: { // wxGraphicsContext::DrawLines
+case wxGraphicsContext_DrawLines: { // wxGraphicsContext::DrawLines
int fillStyle=wxODDEVEN_RULE;
wxGraphicsContext *This = (wxGraphicsContext *) getPtr(bp,memenv); bp += 4;
int * n = (int *) bp; bp += 4;
wxDouble * pointsX = (wxDouble *) bp; bp += 8;
wxDouble * pointsY = (wxDouble *) bp; bp += 8;
wxPoint2DDouble points = wxPoint2DDouble(*pointsX,*pointsY);
- while( * (int*) bp) { switch (* (int*) bp) {
+ while( * (int*) bp) { switch (* (int*) bp) {
case 1: {bp += 4;
fillStyle = (int)*(int *) bp; bp += 4;
} break;
- }};
+ }};
if(!This) throw wxe_badarg(0);
This->DrawLines((size_t) *n,&points,fillStyle);
- break;
+ break;
}
-case wxGraphicsContext_DrawPath: { // wxGraphicsContext::DrawPath
+case wxGraphicsContext_DrawPath: { // wxGraphicsContext::DrawPath
int fillStyle=wxODDEVEN_RULE;
wxGraphicsContext *This = (wxGraphicsContext *) getPtr(bp,memenv); bp += 4;
wxGraphicsPath *path = (wxGraphicsPath *) getPtr(bp,memenv); bp += 4;
- while( * (int*) bp) { switch (* (int*) bp) {
+ while( * (int*) bp) { switch (* (int*) bp) {
case 1: {bp += 4;
fillStyle = (int)*(int *) bp; bp += 4;
} break;
- }};
+ }};
if(!This) throw wxe_badarg(0);
This->DrawPath(*path,fillStyle);
- break;
+ break;
}
-case wxGraphicsContext_DrawRectangle: { // wxGraphicsContext::DrawRectangle
+case wxGraphicsContext_DrawRectangle: { // wxGraphicsContext::DrawRectangle
wxGraphicsContext *This = (wxGraphicsContext *) getPtr(bp,memenv); bp += 4;
bp += 4; /* Align */
wxDouble * x = (wxDouble *) bp; bp += 8;
@@ -6280,9 +6280,9 @@ case wxGraphicsContext_DrawRectangle: { // wxGraphicsContext::DrawRectangle
wxDouble * h = (wxDouble *) bp; bp += 8;
if(!This) throw wxe_badarg(0);
This->DrawRectangle((wxDouble) *x,(wxDouble) *y,(wxDouble) *w,(wxDouble) *h);
- break;
+ break;
}
-case wxGraphicsContext_DrawRoundedRectangle: { // wxGraphicsContext::DrawRoundedRectangle
+case wxGraphicsContext_DrawRoundedRectangle: { // wxGraphicsContext::DrawRoundedRectangle
wxGraphicsContext *This = (wxGraphicsContext *) getPtr(bp,memenv); bp += 4;
bp += 4; /* Align */
wxDouble * x = (wxDouble *) bp; bp += 8;
@@ -6292,9 +6292,9 @@ case wxGraphicsContext_DrawRoundedRectangle: { // wxGraphicsContext::DrawRounded
wxDouble * radius = (wxDouble *) bp; bp += 8;
if(!This) throw wxe_badarg(0);
This->DrawRoundedRectangle((wxDouble) *x,(wxDouble) *y,(wxDouble) *w,(wxDouble) *h,(wxDouble) *radius);
- break;
+ break;
}
-case wxGraphicsContext_DrawText_3: { // wxGraphicsContext::DrawText
+case wxGraphicsContext_DrawText_3: { // wxGraphicsContext::DrawText
wxGraphicsContext *This = (wxGraphicsContext *) getPtr(bp,memenv); bp += 4;
int * strLen = (int *) bp; bp += 4;
wxString str = wxString(bp, wxConvUTF8);
@@ -6303,9 +6303,9 @@ case wxGraphicsContext_DrawText_3: { // wxGraphicsContext::DrawText
wxDouble * y = (wxDouble *) bp; bp += 8;
if(!This) throw wxe_badarg(0);
This->DrawText(str,(wxDouble) *x,(wxDouble) *y);
- break;
+ break;
}
-case wxGraphicsContext_DrawText_4_0: { // wxGraphicsContext::DrawText
+case wxGraphicsContext_DrawText_4_0: { // wxGraphicsContext::DrawText
wxGraphicsContext *This = (wxGraphicsContext *) getPtr(bp,memenv); bp += 4;
int * strLen = (int *) bp; bp += 4;
wxString str = wxString(bp, wxConvUTF8);
@@ -6315,9 +6315,9 @@ case wxGraphicsContext_DrawText_4_0: { // wxGraphicsContext::DrawText
wxDouble * angle = (wxDouble *) bp; bp += 8;
if(!This) throw wxe_badarg(0);
This->DrawText(str,(wxDouble) *x,(wxDouble) *y,(wxDouble) *angle);
- break;
+ break;
}
-case wxGraphicsContext_DrawText_4_1: { // wxGraphicsContext::DrawText
+case wxGraphicsContext_DrawText_4_1: { // wxGraphicsContext::DrawText
wxGraphicsContext *This = (wxGraphicsContext *) getPtr(bp,memenv); bp += 4;
int * strLen = (int *) bp; bp += 4;
wxString str = wxString(bp, wxConvUTF8);
@@ -6327,9 +6327,9 @@ case wxGraphicsContext_DrawText_4_1: { // wxGraphicsContext::DrawText
wxGraphicsBrush *backgroundBrush = (wxGraphicsBrush *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
This->DrawText(str,(wxDouble) *x,(wxDouble) *y,*backgroundBrush);
- break;
+ break;
}
-case wxGraphicsContext_DrawText_5: { // wxGraphicsContext::DrawText
+case wxGraphicsContext_DrawText_5: { // wxGraphicsContext::DrawText
wxGraphicsContext *This = (wxGraphicsContext *) getPtr(bp,memenv); bp += 4;
int * strLen = (int *) bp; bp += 4;
wxString str = wxString(bp, wxConvUTF8);
@@ -6340,35 +6340,35 @@ case wxGraphicsContext_DrawText_5: { // wxGraphicsContext::DrawText
wxGraphicsBrush *backgroundBrush = (wxGraphicsBrush *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
This->DrawText(str,(wxDouble) *x,(wxDouble) *y,(wxDouble) *angle,*backgroundBrush);
- break;
+ break;
}
-case wxGraphicsContext_FillPath: { // wxGraphicsContext::FillPath
+case wxGraphicsContext_FillPath: { // wxGraphicsContext::FillPath
int fillStyle=wxODDEVEN_RULE;
wxGraphicsContext *This = (wxGraphicsContext *) getPtr(bp,memenv); bp += 4;
wxGraphicsPath *path = (wxGraphicsPath *) getPtr(bp,memenv); bp += 4;
- while( * (int*) bp) { switch (* (int*) bp) {
+ while( * (int*) bp) { switch (* (int*) bp) {
case 1: {bp += 4;
fillStyle = (int)*(int *) bp; bp += 4;
} break;
- }};
+ }};
if(!This) throw wxe_badarg(0);
This->FillPath(*path,fillStyle);
- break;
+ break;
}
-case wxGraphicsContext_StrokePath: { // wxGraphicsContext::StrokePath
+case wxGraphicsContext_StrokePath: { // wxGraphicsContext::StrokePath
wxGraphicsContext *This = (wxGraphicsContext *) getPtr(bp,memenv); bp += 4;
wxGraphicsPath *path = (wxGraphicsPath *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
This->StrokePath(*path);
- break;
+ break;
}
-case wxGraphicsContext_GetNativeContext: { // wxGraphicsContext::GetNativeContext
+case wxGraphicsContext_GetNativeContext: { // wxGraphicsContext::GetNativeContext
wxGraphicsContext *This = (wxGraphicsContext *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
This->GetNativeContext();
- break;
+ break;
}
-case wxGraphicsContext_GetPartialTextExtents: { // wxGraphicsContext::GetPartialTextExtents
+case wxGraphicsContext_GetPartialTextExtents: { // wxGraphicsContext::GetPartialTextExtents
wxGraphicsContext *This = (wxGraphicsContext *) getPtr(bp,memenv); bp += 4;
int * textLen = (int *) bp; bp += 4;
wxString text = wxString(bp, wxConvUTF8);
@@ -6379,9 +6379,9 @@ case wxGraphicsContext_GetPartialTextExtents: { // wxGraphicsContext::GetPartial
for(int i=0; i < *widthsLen; i++) { widths.Add(*(int *) bp); bp += 4;}
if(!This) throw wxe_badarg(0);
This->GetPartialTextExtents(text,widths);
- break;
+ break;
}
-case wxGraphicsContext_GetTextExtent: { // wxGraphicsContext::GetTextExtent
+case wxGraphicsContext_GetTextExtent: { // wxGraphicsContext::GetTextExtent
wxDouble width;
wxDouble height;
wxDouble descent;
@@ -6397,77 +6397,77 @@ case wxGraphicsContext_GetTextExtent: { // wxGraphicsContext::GetTextExtent
rt.addFloat(descent);
rt.addFloat(externalLeading);
rt.addTupleCount(4);
- break;
+ break;
}
-case wxGraphicsContext_Rotate: { // wxGraphicsContext::Rotate
+case wxGraphicsContext_Rotate: { // wxGraphicsContext::Rotate
wxGraphicsContext *This = (wxGraphicsContext *) getPtr(bp,memenv); bp += 4;
bp += 4; /* Align */
wxDouble * angle = (wxDouble *) bp; bp += 8;
if(!This) throw wxe_badarg(0);
This->Rotate((wxDouble) *angle);
- break;
+ break;
}
-case wxGraphicsContext_Scale: { // wxGraphicsContext::Scale
+case wxGraphicsContext_Scale: { // wxGraphicsContext::Scale
wxGraphicsContext *This = (wxGraphicsContext *) getPtr(bp,memenv); bp += 4;
bp += 4; /* Align */
wxDouble * xScale = (wxDouble *) bp; bp += 8;
wxDouble * yScale = (wxDouble *) bp; bp += 8;
if(!This) throw wxe_badarg(0);
This->Scale((wxDouble) *xScale,(wxDouble) *yScale);
- break;
+ break;
}
-case wxGraphicsContext_Translate: { // wxGraphicsContext::Translate
+case wxGraphicsContext_Translate: { // wxGraphicsContext::Translate
wxGraphicsContext *This = (wxGraphicsContext *) getPtr(bp,memenv); bp += 4;
bp += 4; /* Align */
wxDouble * dx = (wxDouble *) bp; bp += 8;
wxDouble * dy = (wxDouble *) bp; bp += 8;
if(!This) throw wxe_badarg(0);
This->Translate((wxDouble) *dx,(wxDouble) *dy);
- break;
+ break;
}
-case wxGraphicsContext_GetTransform: { // wxGraphicsContext::GetTransform
+case wxGraphicsContext_GetTransform: { // wxGraphicsContext::GetTransform
wxGraphicsContext *This = (wxGraphicsContext *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
wxGraphicsMatrix * Result = new wxGraphicsMatrix(This->GetTransform()); newPtr((void *) Result,3, memenv);;
rt.addRef(getRef((void *)Result,memenv), "wxGraphicsMatrix");
- break;
+ break;
}
-case wxGraphicsContext_SetTransform: { // wxGraphicsContext::SetTransform
+case wxGraphicsContext_SetTransform: { // wxGraphicsContext::SetTransform
wxGraphicsContext *This = (wxGraphicsContext *) getPtr(bp,memenv); bp += 4;
wxGraphicsMatrix *matrix = (wxGraphicsMatrix *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
This->SetTransform(*matrix);
- break;
+ break;
}
-case wxGraphicsContext_ConcatTransform: { // wxGraphicsContext::ConcatTransform
+case wxGraphicsContext_ConcatTransform: { // wxGraphicsContext::ConcatTransform
wxGraphicsContext *This = (wxGraphicsContext *) getPtr(bp,memenv); bp += 4;
wxGraphicsMatrix *matrix = (wxGraphicsMatrix *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
This->ConcatTransform(*matrix);
- break;
+ break;
}
-case wxGraphicsContext_SetBrush_1_1: { // wxGraphicsContext::SetBrush
+case wxGraphicsContext_SetBrush_1_1: { // wxGraphicsContext::SetBrush
wxGraphicsContext *This = (wxGraphicsContext *) getPtr(bp,memenv); bp += 4;
wxGraphicsBrush * brush = (wxGraphicsBrush *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
This->SetBrush(*brush);
- break;
+ break;
}
-case wxGraphicsContext_SetBrush_1_0: { // wxGraphicsContext::SetBrush
+case wxGraphicsContext_SetBrush_1_0: { // wxGraphicsContext::SetBrush
wxGraphicsContext *This = (wxGraphicsContext *) getPtr(bp,memenv); bp += 4;
wxBrush *brush = (wxBrush *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
This->SetBrush(*brush);
- break;
+ break;
}
-case wxGraphicsContext_SetFont_1: { // wxGraphicsContext::SetFont
+case wxGraphicsContext_SetFont_1: { // wxGraphicsContext::SetFont
wxGraphicsContext *This = (wxGraphicsContext *) getPtr(bp,memenv); bp += 4;
wxGraphicsFont *font = (wxGraphicsFont *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
This->SetFont(*font);
- break;
+ break;
}
-case wxGraphicsContext_SetFont_2: { // wxGraphicsContext::SetFont
+case wxGraphicsContext_SetFont_2: { // wxGraphicsContext::SetFont
wxGraphicsContext *This = (wxGraphicsContext *) getPtr(bp,memenv); bp += 4;
wxFont *font = (wxFont *) getPtr(bp,memenv); bp += 4;
int * colourR = (int *) bp; bp += 4;
@@ -6477,23 +6477,23 @@ case wxGraphicsContext_SetFont_2: { // wxGraphicsContext::SetFont
wxColour colour = wxColour(*colourR,*colourG,*colourB,*colourA);
if(!This) throw wxe_badarg(0);
This->SetFont(*font,colour);
- break;
+ break;
}
-case wxGraphicsContext_SetPen_1_0: { // wxGraphicsContext::SetPen
+case wxGraphicsContext_SetPen_1_0: { // wxGraphicsContext::SetPen
wxGraphicsContext *This = (wxGraphicsContext *) getPtr(bp,memenv); bp += 4;
wxGraphicsPen *pen = (wxGraphicsPen *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
This->SetPen(*pen);
- break;
+ break;
}
-case wxGraphicsContext_SetPen_1_1: { // wxGraphicsContext::SetPen
+case wxGraphicsContext_SetPen_1_1: { // wxGraphicsContext::SetPen
wxGraphicsContext *This = (wxGraphicsContext *) getPtr(bp,memenv); bp += 4;
wxPen * pen = (wxPen *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
This->SetPen(*pen);
- break;
+ break;
}
-case wxGraphicsContext_StrokeLine: { // wxGraphicsContext::StrokeLine
+case wxGraphicsContext_StrokeLine: { // wxGraphicsContext::StrokeLine
wxGraphicsContext *This = (wxGraphicsContext *) getPtr(bp,memenv); bp += 4;
bp += 4; /* Align */
wxDouble * x1 = (wxDouble *) bp; bp += 8;
@@ -6502,9 +6502,9 @@ case wxGraphicsContext_StrokeLine: { // wxGraphicsContext::StrokeLine
wxDouble * y2 = (wxDouble *) bp; bp += 8;
if(!This) throw wxe_badarg(0);
This->StrokeLine((wxDouble) *x1,(wxDouble) *y1,(wxDouble) *x2,(wxDouble) *y2);
- break;
+ break;
}
-case wxGraphicsContext_StrokeLines_2: { // wxGraphicsContext::StrokeLines
+case wxGraphicsContext_StrokeLines_2: { // wxGraphicsContext::StrokeLines
wxGraphicsContext *This = (wxGraphicsContext *) getPtr(bp,memenv); bp += 4;
int * n = (int *) bp; bp += 4;
wxDouble * pointsX = (wxDouble *) bp; bp += 8;
@@ -6512,9 +6512,9 @@ case wxGraphicsContext_StrokeLines_2: { // wxGraphicsContext::StrokeLines
wxPoint2DDouble points = wxPoint2DDouble(*pointsX,*pointsY);
if(!This) throw wxe_badarg(0);
This->StrokeLines((size_t) *n,&points);
- break;
+ break;
}
-case wxGraphicsContext_StrokeLines_3: { // wxGraphicsContext::StrokeLines
+case wxGraphicsContext_StrokeLines_3: { // wxGraphicsContext::StrokeLines
wxGraphicsContext *This = (wxGraphicsContext *) getPtr(bp,memenv); bp += 4;
int * n = (int *) bp; bp += 4;
wxDouble * beginPointsX = (wxDouble *) bp; bp += 8;
@@ -6525,18 +6525,18 @@ case wxGraphicsContext_StrokeLines_3: { // wxGraphicsContext::StrokeLines
wxPoint2DDouble endPoints = wxPoint2DDouble(*endPointsX,*endPointsY);
if(!This) throw wxe_badarg(0);
This->StrokeLines((size_t) *n,&beginPoints,&endPoints);
- break;
+ break;
}
#endif // wxUSE_GRAPHICS_CONTEXT
#if wxUSE_GRAPHICS_CONTEXT
-case wxGraphicsMatrix_Concat: { // wxGraphicsMatrix::Concat
+case wxGraphicsMatrix_Concat: { // wxGraphicsMatrix::Concat
wxGraphicsMatrix *This = (wxGraphicsMatrix *) getPtr(bp,memenv); bp += 4;
wxGraphicsMatrix *t = (wxGraphicsMatrix *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
This->Concat(t);
- break;
+ break;
}
-case wxGraphicsMatrix_Get: { // wxGraphicsMatrix::Get
+case wxGraphicsMatrix_Get: { // wxGraphicsMatrix::Get
wxDouble a;
wxDouble b;
wxDouble c;
@@ -6553,62 +6553,62 @@ case wxGraphicsMatrix_Get: { // wxGraphicsMatrix::Get
rt.addFloat(tx);
rt.addFloat(ty);
rt.addTupleCount(6);
- break;
+ break;
}
-case wxGraphicsMatrix_GetNativeMatrix: { // wxGraphicsMatrix::GetNativeMatrix
+case wxGraphicsMatrix_GetNativeMatrix: { // wxGraphicsMatrix::GetNativeMatrix
wxGraphicsMatrix *This = (wxGraphicsMatrix *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
This->GetNativeMatrix();
- break;
+ break;
}
-case wxGraphicsMatrix_Invert: { // wxGraphicsMatrix::Invert
+case wxGraphicsMatrix_Invert: { // wxGraphicsMatrix::Invert
wxGraphicsMatrix *This = (wxGraphicsMatrix *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
This->Invert();
- break;
+ break;
}
-case wxGraphicsMatrix_IsEqual: { // wxGraphicsMatrix::IsEqual
+case wxGraphicsMatrix_IsEqual: { // wxGraphicsMatrix::IsEqual
wxGraphicsMatrix *This = (wxGraphicsMatrix *) getPtr(bp,memenv); bp += 4;
wxGraphicsMatrix *t = (wxGraphicsMatrix *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
bool Result = This->IsEqual(t);
rt.addBool(Result);
- break;
+ break;
}
-case wxGraphicsMatrix_IsIdentity: { // wxGraphicsMatrix::IsIdentity
+case wxGraphicsMatrix_IsIdentity: { // wxGraphicsMatrix::IsIdentity
wxGraphicsMatrix *This = (wxGraphicsMatrix *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
bool Result = This->IsIdentity();
rt.addBool(Result);
- break;
+ break;
}
-case wxGraphicsMatrix_Rotate: { // wxGraphicsMatrix::Rotate
+case wxGraphicsMatrix_Rotate: { // wxGraphicsMatrix::Rotate
wxGraphicsMatrix *This = (wxGraphicsMatrix *) getPtr(bp,memenv); bp += 4;
bp += 4; /* Align */
wxDouble * angle = (wxDouble *) bp; bp += 8;
if(!This) throw wxe_badarg(0);
This->Rotate((wxDouble) *angle);
- break;
+ break;
}
-case wxGraphicsMatrix_Scale: { // wxGraphicsMatrix::Scale
+case wxGraphicsMatrix_Scale: { // wxGraphicsMatrix::Scale
wxGraphicsMatrix *This = (wxGraphicsMatrix *) getPtr(bp,memenv); bp += 4;
bp += 4; /* Align */
wxDouble * xScale = (wxDouble *) bp; bp += 8;
wxDouble * yScale = (wxDouble *) bp; bp += 8;
if(!This) throw wxe_badarg(0);
This->Scale((wxDouble) *xScale,(wxDouble) *yScale);
- break;
+ break;
}
-case wxGraphicsMatrix_Translate: { // wxGraphicsMatrix::Translate
+case wxGraphicsMatrix_Translate: { // wxGraphicsMatrix::Translate
wxGraphicsMatrix *This = (wxGraphicsMatrix *) getPtr(bp,memenv); bp += 4;
bp += 4; /* Align */
wxDouble * dx = (wxDouble *) bp; bp += 8;
wxDouble * dy = (wxDouble *) bp; bp += 8;
if(!This) throw wxe_badarg(0);
This->Translate((wxDouble) *dx,(wxDouble) *dy);
- break;
+ break;
}
-case wxGraphicsMatrix_Set: { // wxGraphicsMatrix::Set
+case wxGraphicsMatrix_Set: { // wxGraphicsMatrix::Set
wxDouble a=1.0;
wxDouble b=0.0;
wxDouble c=0.0;
@@ -6617,7 +6617,7 @@ case wxGraphicsMatrix_Set: { // wxGraphicsMatrix::Set
wxDouble ty=0.0;
wxGraphicsMatrix *This = (wxGraphicsMatrix *) getPtr(bp,memenv); bp += 4;
bp += 4; /* Align */
- while( * (int*) bp) { switch (* (int*) bp) {
+ while( * (int*) bp) { switch (* (int*) bp) {
case 1: {bp += 4;
bp += 4; /* Align */
a = * (wxDouble *) bp; bp += 8;
@@ -6642,12 +6642,12 @@ case wxGraphicsMatrix_Set: { // wxGraphicsMatrix::Set
bp += 4; /* Align */
ty = * (wxDouble *) bp; bp += 8;
} break;
- }};
+ }};
if(!This) throw wxe_badarg(0);
This->Set(a,b,c,d,tx,ty);
- break;
+ break;
}
-case wxGraphicsMatrix_TransformPoint: { // wxGraphicsMatrix::TransformPoint
+case wxGraphicsMatrix_TransformPoint: { // wxGraphicsMatrix::TransformPoint
wxDouble x;
wxDouble y;
wxGraphicsMatrix *This = (wxGraphicsMatrix *) getPtr(bp,memenv); bp += 4;
@@ -6656,9 +6656,9 @@ case wxGraphicsMatrix_TransformPoint: { // wxGraphicsMatrix::TransformPoint
rt.addFloat(x);
rt.addFloat(y);
rt.addTupleCount(2);
- break;
+ break;
}
-case wxGraphicsMatrix_TransformDistance: { // wxGraphicsMatrix::TransformDistance
+case wxGraphicsMatrix_TransformDistance: { // wxGraphicsMatrix::TransformDistance
wxDouble dx;
wxDouble dy;
wxGraphicsMatrix *This = (wxGraphicsMatrix *) getPtr(bp,memenv); bp += 4;
@@ -6667,20 +6667,20 @@ case wxGraphicsMatrix_TransformDistance: { // wxGraphicsMatrix::TransformDistanc
rt.addFloat(dx);
rt.addFloat(dy);
rt.addTupleCount(2);
- break;
+ break;
}
#endif // wxUSE_GRAPHICS_CONTEXT
#if wxUSE_GRAPHICS_CONTEXT
-case wxGraphicsPath_MoveToPoint_2: { // wxGraphicsPath::MoveToPoint
+case wxGraphicsPath_MoveToPoint_2: { // wxGraphicsPath::MoveToPoint
wxGraphicsPath *This = (wxGraphicsPath *) getPtr(bp,memenv); bp += 4;
bp += 4; /* Align */
wxDouble * x = (wxDouble *) bp; bp += 8;
wxDouble * y = (wxDouble *) bp; bp += 8;
if(!This) throw wxe_badarg(0);
This->MoveToPoint((wxDouble) *x,(wxDouble) *y);
- break;
+ break;
}
-case wxGraphicsPath_MoveToPoint_1: { // wxGraphicsPath::MoveToPoint
+case wxGraphicsPath_MoveToPoint_1: { // wxGraphicsPath::MoveToPoint
wxGraphicsPath *This = (wxGraphicsPath *) getPtr(bp,memenv); bp += 4;
bp += 4; /* Align */
wxDouble * pX = (wxDouble *) bp; bp += 8;
@@ -6688,9 +6688,9 @@ case wxGraphicsPath_MoveToPoint_1: { // wxGraphicsPath::MoveToPoint
wxPoint2DDouble p = wxPoint2DDouble(*pX,*pY);
if(!This) throw wxe_badarg(0);
This->MoveToPoint(p);
- break;
+ break;
}
-case wxGraphicsPath_AddArc_6: { // wxGraphicsPath::AddArc
+case wxGraphicsPath_AddArc_6: { // wxGraphicsPath::AddArc
wxGraphicsPath *This = (wxGraphicsPath *) getPtr(bp,memenv); bp += 4;
bp += 4; /* Align */
wxDouble * x = (wxDouble *) bp; bp += 8;
@@ -6701,9 +6701,9 @@ case wxGraphicsPath_AddArc_6: { // wxGraphicsPath::AddArc
bool * clockwise = (bool *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
This->AddArc((wxDouble) *x,(wxDouble) *y,(wxDouble) *r,(wxDouble) *startAngle,(wxDouble) *endAngle,(bool) *clockwise);
- break;
+ break;
}
-case wxGraphicsPath_AddArc_5: { // wxGraphicsPath::AddArc
+case wxGraphicsPath_AddArc_5: { // wxGraphicsPath::AddArc
wxGraphicsPath *This = (wxGraphicsPath *) getPtr(bp,memenv); bp += 4;
bp += 4; /* Align */
wxDouble * cX = (wxDouble *) bp; bp += 8;
@@ -6715,9 +6715,9 @@ case wxGraphicsPath_AddArc_5: { // wxGraphicsPath::AddArc
bool * clockwise = (bool *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
This->AddArc(c,(wxDouble) *r,(wxDouble) *startAngle,(wxDouble) *endAngle,(bool) *clockwise);
- break;
+ break;
}
-case wxGraphicsPath_AddArcToPoint: { // wxGraphicsPath::AddArcToPoint
+case wxGraphicsPath_AddArcToPoint: { // wxGraphicsPath::AddArcToPoint
wxGraphicsPath *This = (wxGraphicsPath *) getPtr(bp,memenv); bp += 4;
bp += 4; /* Align */
wxDouble * x1 = (wxDouble *) bp; bp += 8;
@@ -6727,9 +6727,9 @@ case wxGraphicsPath_AddArcToPoint: { // wxGraphicsPath::AddArcToPoint
wxDouble * r = (wxDouble *) bp; bp += 8;
if(!This) throw wxe_badarg(0);
This->AddArcToPoint((wxDouble) *x1,(wxDouble) *y1,(wxDouble) *x2,(wxDouble) *y2,(wxDouble) *r);
- break;
+ break;
}
-case wxGraphicsPath_AddCircle: { // wxGraphicsPath::AddCircle
+case wxGraphicsPath_AddCircle: { // wxGraphicsPath::AddCircle
wxGraphicsPath *This = (wxGraphicsPath *) getPtr(bp,memenv); bp += 4;
bp += 4; /* Align */
wxDouble * x = (wxDouble *) bp; bp += 8;
@@ -6737,9 +6737,9 @@ case wxGraphicsPath_AddCircle: { // wxGraphicsPath::AddCircle
wxDouble * r = (wxDouble *) bp; bp += 8;
if(!This) throw wxe_badarg(0);
This->AddCircle((wxDouble) *x,(wxDouble) *y,(wxDouble) *r);
- break;
+ break;
}
-case wxGraphicsPath_AddCurveToPoint_6: { // wxGraphicsPath::AddCurveToPoint
+case wxGraphicsPath_AddCurveToPoint_6: { // wxGraphicsPath::AddCurveToPoint
wxGraphicsPath *This = (wxGraphicsPath *) getPtr(bp,memenv); bp += 4;
bp += 4; /* Align */
wxDouble * cx1 = (wxDouble *) bp; bp += 8;
@@ -6750,9 +6750,9 @@ case wxGraphicsPath_AddCurveToPoint_6: { // wxGraphicsPath::AddCurveToPoint
wxDouble * y = (wxDouble *) bp; bp += 8;
if(!This) throw wxe_badarg(0);
This->AddCurveToPoint((wxDouble) *cx1,(wxDouble) *cy1,(wxDouble) *cx2,(wxDouble) *cy2,(wxDouble) *x,(wxDouble) *y);
- break;
+ break;
}
-case wxGraphicsPath_AddCurveToPoint_3: { // wxGraphicsPath::AddCurveToPoint
+case wxGraphicsPath_AddCurveToPoint_3: { // wxGraphicsPath::AddCurveToPoint
wxGraphicsPath *This = (wxGraphicsPath *) getPtr(bp,memenv); bp += 4;
bp += 4; /* Align */
wxDouble * c1X = (wxDouble *) bp; bp += 8;
@@ -6766,9 +6766,9 @@ case wxGraphicsPath_AddCurveToPoint_3: { // wxGraphicsPath::AddCurveToPoint
wxPoint2DDouble e = wxPoint2DDouble(*eX,*eY);
if(!This) throw wxe_badarg(0);
This->AddCurveToPoint(c1,c2,e);
- break;
+ break;
}
-case wxGraphicsPath_AddEllipse: { // wxGraphicsPath::AddEllipse
+case wxGraphicsPath_AddEllipse: { // wxGraphicsPath::AddEllipse
wxGraphicsPath *This = (wxGraphicsPath *) getPtr(bp,memenv); bp += 4;
bp += 4; /* Align */
wxDouble * x = (wxDouble *) bp; bp += 8;
@@ -6777,18 +6777,18 @@ case wxGraphicsPath_AddEllipse: { // wxGraphicsPath::AddEllipse
wxDouble * h = (wxDouble *) bp; bp += 8;
if(!This) throw wxe_badarg(0);
This->AddEllipse((wxDouble) *x,(wxDouble) *y,(wxDouble) *w,(wxDouble) *h);
- break;
+ break;
}
-case wxGraphicsPath_AddLineToPoint_2: { // wxGraphicsPath::AddLineToPoint
+case wxGraphicsPath_AddLineToPoint_2: { // wxGraphicsPath::AddLineToPoint
wxGraphicsPath *This = (wxGraphicsPath *) getPtr(bp,memenv); bp += 4;
bp += 4; /* Align */
wxDouble * x = (wxDouble *) bp; bp += 8;
wxDouble * y = (wxDouble *) bp; bp += 8;
if(!This) throw wxe_badarg(0);
This->AddLineToPoint((wxDouble) *x,(wxDouble) *y);
- break;
+ break;
}
-case wxGraphicsPath_AddLineToPoint_1: { // wxGraphicsPath::AddLineToPoint
+case wxGraphicsPath_AddLineToPoint_1: { // wxGraphicsPath::AddLineToPoint
wxGraphicsPath *This = (wxGraphicsPath *) getPtr(bp,memenv); bp += 4;
bp += 4; /* Align */
wxDouble * pX = (wxDouble *) bp; bp += 8;
@@ -6796,16 +6796,16 @@ case wxGraphicsPath_AddLineToPoint_1: { // wxGraphicsPath::AddLineToPoint
wxPoint2DDouble p = wxPoint2DDouble(*pX,*pY);
if(!This) throw wxe_badarg(0);
This->AddLineToPoint(p);
- break;
+ break;
}
-case wxGraphicsPath_AddPath: { // wxGraphicsPath::AddPath
+case wxGraphicsPath_AddPath: { // wxGraphicsPath::AddPath
wxGraphicsPath *This = (wxGraphicsPath *) getPtr(bp,memenv); bp += 4;
wxGraphicsPath *path = (wxGraphicsPath *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
This->AddPath(*path);
- break;
+ break;
}
-case wxGraphicsPath_AddQuadCurveToPoint: { // wxGraphicsPath::AddQuadCurveToPoint
+case wxGraphicsPath_AddQuadCurveToPoint: { // wxGraphicsPath::AddQuadCurveToPoint
wxGraphicsPath *This = (wxGraphicsPath *) getPtr(bp,memenv); bp += 4;
bp += 4; /* Align */
wxDouble * cx = (wxDouble *) bp; bp += 8;
@@ -6814,9 +6814,9 @@ case wxGraphicsPath_AddQuadCurveToPoint: { // wxGraphicsPath::AddQuadCurveToPoin
wxDouble * y = (wxDouble *) bp; bp += 8;
if(!This) throw wxe_badarg(0);
This->AddQuadCurveToPoint((wxDouble) *cx,(wxDouble) *cy,(wxDouble) *x,(wxDouble) *y);
- break;
+ break;
}
-case wxGraphicsPath_AddRectangle: { // wxGraphicsPath::AddRectangle
+case wxGraphicsPath_AddRectangle: { // wxGraphicsPath::AddRectangle
wxGraphicsPath *This = (wxGraphicsPath *) getPtr(bp,memenv); bp += 4;
bp += 4; /* Align */
wxDouble * x = (wxDouble *) bp; bp += 8;
@@ -6825,9 +6825,9 @@ case wxGraphicsPath_AddRectangle: { // wxGraphicsPath::AddRectangle
wxDouble * h = (wxDouble *) bp; bp += 8;
if(!This) throw wxe_badarg(0);
This->AddRectangle((wxDouble) *x,(wxDouble) *y,(wxDouble) *w,(wxDouble) *h);
- break;
+ break;
}
-case wxGraphicsPath_AddRoundedRectangle: { // wxGraphicsPath::AddRoundedRectangle
+case wxGraphicsPath_AddRoundedRectangle: { // wxGraphicsPath::AddRoundedRectangle
wxGraphicsPath *This = (wxGraphicsPath *) getPtr(bp,memenv); bp += 4;
bp += 4; /* Align */
wxDouble * x = (wxDouble *) bp; bp += 8;
@@ -6837,108 +6837,108 @@ case wxGraphicsPath_AddRoundedRectangle: { // wxGraphicsPath::AddRoundedRectangl
wxDouble * radius = (wxDouble *) bp; bp += 8;
if(!This) throw wxe_badarg(0);
This->AddRoundedRectangle((wxDouble) *x,(wxDouble) *y,(wxDouble) *w,(wxDouble) *h,(wxDouble) *radius);
- break;
+ break;
}
-case wxGraphicsPath_CloseSubpath: { // wxGraphicsPath::CloseSubpath
+case wxGraphicsPath_CloseSubpath: { // wxGraphicsPath::CloseSubpath
wxGraphicsPath *This = (wxGraphicsPath *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
This->CloseSubpath();
- break;
+ break;
}
-case wxGraphicsPath_Contains_3: { // wxGraphicsPath::Contains
+case wxGraphicsPath_Contains_3: { // wxGraphicsPath::Contains
int fillStyle=wxODDEVEN_RULE;
wxGraphicsPath *This = (wxGraphicsPath *) getPtr(bp,memenv); bp += 4;
bp += 4; /* Align */
wxDouble * x = (wxDouble *) bp; bp += 8;
wxDouble * y = (wxDouble *) bp; bp += 8;
- while( * (int*) bp) { switch (* (int*) bp) {
+ while( * (int*) bp) { switch (* (int*) bp) {
case 1: {bp += 4;
fillStyle = (int)*(int *) bp; bp += 4;
} break;
- }};
+ }};
if(!This) throw wxe_badarg(0);
bool Result = This->Contains((wxDouble) *x,(wxDouble) *y,fillStyle);
rt.addBool(Result);
- break;
+ break;
}
-case wxGraphicsPath_Contains_2: { // wxGraphicsPath::Contains
+case wxGraphicsPath_Contains_2: { // wxGraphicsPath::Contains
int fillStyle=wxODDEVEN_RULE;
wxGraphicsPath *This = (wxGraphicsPath *) getPtr(bp,memenv); bp += 4;
bp += 4; /* Align */
wxDouble * cX = (wxDouble *) bp; bp += 8;
wxDouble * cY = (wxDouble *) bp; bp += 8;
wxPoint2DDouble c = wxPoint2DDouble(*cX,*cY);
- while( * (int*) bp) { switch (* (int*) bp) {
+ while( * (int*) bp) { switch (* (int*) bp) {
case 1: {bp += 4;
fillStyle = (int)*(int *) bp; bp += 4;
} break;
- }};
+ }};
if(!This) throw wxe_badarg(0);
bool Result = This->Contains(c,fillStyle);
rt.addBool(Result);
- break;
+ break;
}
-case wxGraphicsPath_GetBox: { // wxGraphicsPath::GetBox
+case wxGraphicsPath_GetBox: { // wxGraphicsPath::GetBox
wxGraphicsPath *This = (wxGraphicsPath *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
wxRect2DDouble Result = This->GetBox();
rt.add(Result);
- break;
+ break;
}
-case wxGraphicsPath_GetCurrentPoint: { // wxGraphicsPath::GetCurrentPoint
+case wxGraphicsPath_GetCurrentPoint: { // wxGraphicsPath::GetCurrentPoint
wxGraphicsPath *This = (wxGraphicsPath *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
wxPoint2DDouble Result = This->GetCurrentPoint();
rt.add(Result);
- break;
+ break;
}
-case wxGraphicsPath_Transform: { // wxGraphicsPath::Transform
+case wxGraphicsPath_Transform: { // wxGraphicsPath::Transform
wxGraphicsPath *This = (wxGraphicsPath *) getPtr(bp,memenv); bp += 4;
wxGraphicsMatrix *matrix = (wxGraphicsMatrix *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
This->Transform(*matrix);
- break;
+ break;
}
#endif // wxUSE_GRAPHICS_CONTEXT
#if wxUSE_GRAPHICS_CONTEXT
-case wxGraphicsRenderer_GetDefaultRenderer: { // wxGraphicsRenderer::GetDefaultRenderer
+case wxGraphicsRenderer_GetDefaultRenderer: { // wxGraphicsRenderer::GetDefaultRenderer
wxGraphicsRenderer * Result = (wxGraphicsRenderer*)wxGraphicsRenderer::GetDefaultRenderer();
rt.addRef(getRef((void *)Result,memenv), "wxGraphicsRenderer");
- break;
+ break;
}
-case wxGraphicsRenderer_CreateContext_1_1: { // wxGraphicsRenderer::CreateContext
+case wxGraphicsRenderer_CreateContext_1_1: { // wxGraphicsRenderer::CreateContext
wxGraphicsRenderer *This = (wxGraphicsRenderer *) getPtr(bp,memenv); bp += 4;
wxWindowDC * dc = (wxWindowDC *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
wxGraphicsContext * Result = (wxGraphicsContext*)This->CreateContext(*dc);
rt.addRef(getRef((void *)Result,memenv), "wxGraphicsContext");
- break;
+ break;
}
-case wxGraphicsRenderer_CreateContext_1_0: { // wxGraphicsRenderer::CreateContext
+case wxGraphicsRenderer_CreateContext_1_0: { // wxGraphicsRenderer::CreateContext
wxGraphicsRenderer *This = (wxGraphicsRenderer *) getPtr(bp,memenv); bp += 4;
wxWindow *window = (wxWindow *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
wxGraphicsContext * Result = (wxGraphicsContext*)This->CreateContext(window);
rt.addRef(getRef((void *)Result,memenv), "wxGraphicsContext");
- break;
+ break;
}
-case wxGraphicsRenderer_CreatePen: { // wxGraphicsRenderer::CreatePen
+case wxGraphicsRenderer_CreatePen: { // wxGraphicsRenderer::CreatePen
wxGraphicsRenderer *This = (wxGraphicsRenderer *) getPtr(bp,memenv); bp += 4;
wxPen *pen = (wxPen *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
wxGraphicsPen * Result = new wxGraphicsPen(This->CreatePen(*pen)); newPtr((void *) Result,3, memenv);;
rt.addRef(getRef((void *)Result,memenv), "wxGraphicsPen");
- break;
+ break;
}
-case wxGraphicsRenderer_CreateBrush: { // wxGraphicsRenderer::CreateBrush
+case wxGraphicsRenderer_CreateBrush: { // wxGraphicsRenderer::CreateBrush
wxGraphicsRenderer *This = (wxGraphicsRenderer *) getPtr(bp,memenv); bp += 4;
wxBrush *brush = (wxBrush *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
wxGraphicsBrush * Result = new wxGraphicsBrush(This->CreateBrush(*brush)); newPtr((void *) Result,3, memenv);;
rt.addRef(getRef((void *)Result,memenv), "wxGraphicsBrush");
- break;
+ break;
}
-case wxGraphicsRenderer_CreateLinearGradientBrush: { // wxGraphicsRenderer::CreateLinearGradientBrush
+case wxGraphicsRenderer_CreateLinearGradientBrush: { // wxGraphicsRenderer::CreateLinearGradientBrush
wxGraphicsRenderer *This = (wxGraphicsRenderer *) getPtr(bp,memenv); bp += 4;
bp += 4; /* Align */
wxDouble * x1 = (wxDouble *) bp; bp += 8;
@@ -6958,9 +6958,9 @@ case wxGraphicsRenderer_CreateLinearGradientBrush: { // wxGraphicsRenderer::Crea
if(!This) throw wxe_badarg(0);
wxGraphicsBrush * Result = new wxGraphicsBrush(This->CreateLinearGradientBrush((wxDouble) *x1,(wxDouble) *y1,(wxDouble) *x2,(wxDouble) *y2,c1,c2)); newPtr((void *) Result,3, memenv);;
rt.addRef(getRef((void *)Result,memenv), "wxGraphicsBrush");
- break;
+ break;
}
-case wxGraphicsRenderer_CreateRadialGradientBrush: { // wxGraphicsRenderer::CreateRadialGradientBrush
+case wxGraphicsRenderer_CreateRadialGradientBrush: { // wxGraphicsRenderer::CreateRadialGradientBrush
wxGraphicsRenderer *This = (wxGraphicsRenderer *) getPtr(bp,memenv); bp += 4;
bp += 4; /* Align */
wxDouble * xo = (wxDouble *) bp; bp += 8;
@@ -6981,13 +6981,13 @@ case wxGraphicsRenderer_CreateRadialGradientBrush: { // wxGraphicsRenderer::Crea
if(!This) throw wxe_badarg(0);
wxGraphicsBrush * Result = new wxGraphicsBrush(This->CreateRadialGradientBrush((wxDouble) *xo,(wxDouble) *yo,(wxDouble) *xc,(wxDouble) *yc,(wxDouble) *radius,oColor,cColor)); newPtr((void *) Result,3, memenv);;
rt.addRef(getRef((void *)Result,memenv), "wxGraphicsBrush");
- break;
+ break;
}
-case wxGraphicsRenderer_CreateFont: { // wxGraphicsRenderer::CreateFont
+case wxGraphicsRenderer_CreateFont: { // wxGraphicsRenderer::CreateFont
wxColour col= *wxBLACK;
wxGraphicsRenderer *This = (wxGraphicsRenderer *) getPtr(bp,memenv); bp += 4;
wxFont *font = (wxFont *) getPtr(bp,memenv); bp += 4;
- while( * (int*) bp) { switch (* (int*) bp) {
+ while( * (int*) bp) { switch (* (int*) bp) {
case 1: {bp += 4;
int * colR = (int *) bp; bp += 4;
int * colG = (int *) bp; bp += 4;
@@ -6996,13 +6996,13 @@ case wxGraphicsRenderer_CreateFont: { // wxGraphicsRenderer::CreateFont
col = wxColour(*colR,*colG,*colB,*colA);
bp += 4; /* Align */
} break;
- }};
+ }};
if(!This) throw wxe_badarg(0);
wxGraphicsFont * Result = new wxGraphicsFont(This->CreateFont(*font,col)); newPtr((void *) Result,3, memenv);;
rt.addRef(getRef((void *)Result,memenv), "wxGraphicsFont");
- break;
+ break;
}
-case wxGraphicsRenderer_CreateMatrix: { // wxGraphicsRenderer::CreateMatrix
+case wxGraphicsRenderer_CreateMatrix: { // wxGraphicsRenderer::CreateMatrix
wxDouble a=1.0;
wxDouble b=0.0;
wxDouble c=0.0;
@@ -7011,7 +7011,7 @@ case wxGraphicsRenderer_CreateMatrix: { // wxGraphicsRenderer::CreateMatrix
wxDouble ty=0.0;
wxGraphicsRenderer *This = (wxGraphicsRenderer *) getPtr(bp,memenv); bp += 4;
bp += 4; /* Align */
- while( * (int*) bp) { switch (* (int*) bp) {
+ while( * (int*) bp) { switch (* (int*) bp) {
case 1: {bp += 4;
bp += 4; /* Align */
a = * (wxDouble *) bp; bp += 8;
@@ -7036,18 +7036,18 @@ case wxGraphicsRenderer_CreateMatrix: { // wxGraphicsRenderer::CreateMatrix
bp += 4; /* Align */
ty = * (wxDouble *) bp; bp += 8;
} break;
- }};
+ }};
if(!This) throw wxe_badarg(0);
wxGraphicsMatrix * Result = new wxGraphicsMatrix(This->CreateMatrix(a,b,c,d,tx,ty)); newPtr((void *) Result,3, memenv);;
rt.addRef(getRef((void *)Result,memenv), "wxGraphicsMatrix");
- break;
+ break;
}
-case wxGraphicsRenderer_CreatePath: { // wxGraphicsRenderer::CreatePath
+case wxGraphicsRenderer_CreatePath: { // wxGraphicsRenderer::CreatePath
wxGraphicsRenderer *This = (wxGraphicsRenderer *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
wxGraphicsPath * Result = new wxGraphicsPath(This->CreatePath()); newPtr((void *) Result,3, memenv);;
rt.addRef(getRef((void *)Result,memenv), "wxGraphicsPath");
- break;
+ break;
}
#endif // wxUSE_GRAPHICS_CONTEXT
#if wxUSE_GRAPHICS_CONTEXT
@@ -7056,20 +7056,20 @@ case wxGraphicsRenderer_CreatePath: { // wxGraphicsRenderer::CreatePath
#endif // wxUSE_GRAPHICS_CONTEXT
#if wxUSE_GRAPHICS_CONTEXT
#endif // wxUSE_GRAPHICS_CONTEXT
-case wxMenuBar_new_1: { // wxMenuBar::wxMenuBar
+case wxMenuBar_new_1: { // wxMenuBar::wxMenuBar
int * style = (int *) bp; bp += 4;
wxMenuBar * Result = new EwxMenuBar((long) *style);
newPtr((void *) Result, 0, memenv);
rt.addRef(getRef((void *)Result,memenv), "wxMenuBar");
- break;
+ break;
}
-case wxMenuBar_new_0: { // wxMenuBar::wxMenuBar
+case wxMenuBar_new_0: { // wxMenuBar::wxMenuBar
wxMenuBar * Result = new EwxMenuBar();
newPtr((void *) Result, 0, memenv);
rt.addRef(getRef((void *)Result,memenv), "wxMenuBar");
- break;
+ break;
}
-case wxMenuBar_Append: { // wxMenuBar::Append
+case wxMenuBar_Append: { // wxMenuBar::Append
wxMenuBar *This = (wxMenuBar *) getPtr(bp,memenv); bp += 4;
wxMenu *menu = (wxMenu *) getPtr(bp,memenv); bp += 4;
int * titleLen = (int *) bp; bp += 4;
@@ -7078,47 +7078,47 @@ case wxMenuBar_Append: { // wxMenuBar::Append
if(!This) throw wxe_badarg(0);
bool Result = This->Append(menu,title);
rt.addBool(Result);
- break;
+ break;
}
-case wxMenuBar_Check: { // wxMenuBar::Check
+case wxMenuBar_Check: { // wxMenuBar::Check
wxMenuBar *This = (wxMenuBar *) getPtr(bp,memenv); bp += 4;
int * itemid = (int *) bp; bp += 4;
bool * check = (bool *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
This->Check((int) *itemid,(bool) *check);
- break;
+ break;
}
-case wxMenuBar_Enable_2: { // wxMenuBar::Enable
+case wxMenuBar_Enable_2: { // wxMenuBar::Enable
wxMenuBar *This = (wxMenuBar *) getPtr(bp,memenv); bp += 4;
int * itemid = (int *) bp; bp += 4;
bool * enable = (bool *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
This->Enable((int) *itemid,(bool) *enable);
- break;
+ break;
}
-case wxMenuBar_Enable_1: { // wxMenuBar::Enable
+case wxMenuBar_Enable_1: { // wxMenuBar::Enable
bool enable=true;
wxMenuBar *This = (wxMenuBar *) getPtr(bp,memenv); bp += 4;
bp += 4; /* Align */
- while( * (int*) bp) { switch (* (int*) bp) {
+ while( * (int*) bp) { switch (* (int*) bp) {
case 1: {bp += 4;
enable = *(bool *) bp; bp += 4;
} break;
- }};
+ }};
if(!This) throw wxe_badarg(0);
bool Result = This->Enable(enable);
rt.addBool(Result);
- break;
+ break;
}
-case wxMenuBar_EnableTop: { // wxMenuBar::EnableTop
+case wxMenuBar_EnableTop: { // wxMenuBar::EnableTop
wxMenuBar *This = (wxMenuBar *) getPtr(bp,memenv); bp += 4;
int * pos = (int *) bp; bp += 4;
bool * flag = (bool *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
This->EnableTop((size_t) *pos,(bool) *flag);
- break;
+ break;
}
-case wxMenuBar_FindMenu: { // wxMenuBar::FindMenu
+case wxMenuBar_FindMenu: { // wxMenuBar::FindMenu
wxMenuBar *This = (wxMenuBar *) getPtr(bp,memenv); bp += 4;
int * titleLen = (int *) bp; bp += 4;
wxString title = wxString(bp, wxConvUTF8);
@@ -7126,9 +7126,9 @@ case wxMenuBar_FindMenu: { // wxMenuBar::FindMenu
if(!This) throw wxe_badarg(0);
int Result = This->FindMenu(title);
rt.addInt(Result);
- break;
+ break;
}
-case wxMenuBar_FindMenuItem: { // wxMenuBar::FindMenuItem
+case wxMenuBar_FindMenuItem: { // wxMenuBar::FindMenuItem
wxMenuBar *This = (wxMenuBar *) getPtr(bp,memenv); bp += 4;
int * menuStringLen = (int *) bp; bp += 4;
wxString menuString = wxString(bp, wxConvUTF8);
@@ -7139,64 +7139,64 @@ case wxMenuBar_FindMenuItem: { // wxMenuBar::FindMenuItem
if(!This) throw wxe_badarg(0);
int Result = This->FindMenuItem(menuString,itemString);
rt.addInt(Result);
- break;
+ break;
}
-case wxMenuBar_FindItem: { // wxMenuBar::FindItem
+case wxMenuBar_FindItem: { // wxMenuBar::FindItem
wxMenu ** menu = NULL;
wxMenuBar *This = (wxMenuBar *) getPtr(bp,memenv); bp += 4;
int * id = (int *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
wxMenuItem * Result = (wxMenuItem*)This->FindItem((int) *id,menu);
rt.addRef(getRef((void *)Result,memenv), "wxMenuItem");
- break;
+ break;
}
-case wxMenuBar_GetHelpString: { // wxMenuBar::GetHelpString
+case wxMenuBar_GetHelpString: { // wxMenuBar::GetHelpString
wxMenuBar *This = (wxMenuBar *) getPtr(bp,memenv); bp += 4;
int * itemid = (int *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
wxString Result = This->GetHelpString((int) *itemid);
rt.add(Result);
- break;
+ break;
}
-case wxMenuBar_GetLabel_1: { // wxMenuBar::GetLabel
+case wxMenuBar_GetLabel_1: { // wxMenuBar::GetLabel
wxMenuBar *This = (wxMenuBar *) getPtr(bp,memenv); bp += 4;
int * itemid = (int *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
wxString Result = This->GetLabel((int) *itemid);
rt.add(Result);
- break;
+ break;
}
-case wxMenuBar_GetLabel_0: { // wxMenuBar::GetLabel
+case wxMenuBar_GetLabel_0: { // wxMenuBar::GetLabel
wxMenuBar *This = (wxMenuBar *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
wxString Result = This->GetLabel();
rt.add(Result);
- break;
+ break;
}
-case wxMenuBar_GetLabelTop: { // wxMenuBar::GetLabelTop
+case wxMenuBar_GetLabelTop: { // wxMenuBar::GetLabelTop
wxMenuBar *This = (wxMenuBar *) getPtr(bp,memenv); bp += 4;
int * pos = (int *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
wxString Result = This->GetLabelTop((size_t) *pos);
rt.add(Result);
- break;
+ break;
}
-case wxMenuBar_GetMenu: { // wxMenuBar::GetMenu
+case wxMenuBar_GetMenu: { // wxMenuBar::GetMenu
wxMenuBar *This = (wxMenuBar *) getPtr(bp,memenv); bp += 4;
int * pos = (int *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
wxMenu * Result = (wxMenu*)This->GetMenu((size_t) *pos);
rt.addRef(getRef((void *)Result,memenv), "wxMenu");
- break;
+ break;
}
-case wxMenuBar_GetMenuCount: { // wxMenuBar::GetMenuCount
+case wxMenuBar_GetMenuCount: { // wxMenuBar::GetMenuCount
wxMenuBar *This = (wxMenuBar *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
size_t Result = This->GetMenuCount();
rt.addInt(Result);
- break;
+ break;
}
-case wxMenuBar_Insert: { // wxMenuBar::Insert
+case wxMenuBar_Insert: { // wxMenuBar::Insert
wxMenuBar *This = (wxMenuBar *) getPtr(bp,memenv); bp += 4;
int * pos = (int *) bp; bp += 4;
wxMenu *menu = (wxMenu *) getPtr(bp,memenv); bp += 4;
@@ -7206,40 +7206,40 @@ case wxMenuBar_Insert: { // wxMenuBar::Insert
if(!This) throw wxe_badarg(0);
bool Result = This->Insert((size_t) *pos,menu,title);
rt.addBool(Result);
- break;
+ break;
}
-case wxMenuBar_IsChecked: { // wxMenuBar::IsChecked
+case wxMenuBar_IsChecked: { // wxMenuBar::IsChecked
wxMenuBar *This = (wxMenuBar *) getPtr(bp,memenv); bp += 4;
int * itemid = (int *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
bool Result = This->IsChecked((int) *itemid);
rt.addBool(Result);
- break;
+ break;
}
-case wxMenuBar_IsEnabled_1: { // wxMenuBar::IsEnabled
+case wxMenuBar_IsEnabled_1: { // wxMenuBar::IsEnabled
wxMenuBar *This = (wxMenuBar *) getPtr(bp,memenv); bp += 4;
int * itemid = (int *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
bool Result = This->IsEnabled((int) *itemid);
rt.addBool(Result);
- break;
+ break;
}
-case wxMenuBar_IsEnabled_0: { // wxMenuBar::IsEnabled
+case wxMenuBar_IsEnabled_0: { // wxMenuBar::IsEnabled
wxMenuBar *This = (wxMenuBar *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
bool Result = This->IsEnabled();
rt.addBool(Result);
- break;
+ break;
}
-case wxMenuBar_Remove: { // wxMenuBar::Remove
+case wxMenuBar_Remove: { // wxMenuBar::Remove
wxMenuBar *This = (wxMenuBar *) getPtr(bp,memenv); bp += 4;
int * pos = (int *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
wxMenu * Result = (wxMenu*)This->Remove((size_t) *pos);
rt.addRef(getRef((void *)Result,memenv), "wxMenu");
- break;
+ break;
}
-case wxMenuBar_Replace: { // wxMenuBar::Replace
+case wxMenuBar_Replace: { // wxMenuBar::Replace
wxMenuBar *This = (wxMenuBar *) getPtr(bp,memenv); bp += 4;
int * pos = (int *) bp; bp += 4;
wxMenu *menu = (wxMenu *) getPtr(bp,memenv); bp += 4;
@@ -7249,9 +7249,9 @@ case wxMenuBar_Replace: { // wxMenuBar::Replace
if(!This) throw wxe_badarg(0);
wxMenu * Result = (wxMenu*)This->Replace((size_t) *pos,menu,title);
rt.addRef(getRef((void *)Result,memenv), "wxMenu");
- break;
+ break;
}
-case wxMenuBar_SetHelpString: { // wxMenuBar::SetHelpString
+case wxMenuBar_SetHelpString: { // wxMenuBar::SetHelpString
wxMenuBar *This = (wxMenuBar *) getPtr(bp,memenv); bp += 4;
int * itemid = (int *) bp; bp += 4;
int * helpStringLen = (int *) bp; bp += 4;
@@ -7259,9 +7259,9 @@ case wxMenuBar_SetHelpString: { // wxMenuBar::SetHelpString
bp += *helpStringLen+((8-((4+ *helpStringLen) & 7)) & 7);
if(!This) throw wxe_badarg(0);
This->SetHelpString((int) *itemid,helpString);
- break;
+ break;
}
-case wxMenuBar_SetLabel_2: { // wxMenuBar::SetLabel
+case wxMenuBar_SetLabel_2: { // wxMenuBar::SetLabel
wxMenuBar *This = (wxMenuBar *) getPtr(bp,memenv); bp += 4;
int * itemid = (int *) bp; bp += 4;
int * labelLen = (int *) bp; bp += 4;
@@ -7269,18 +7269,18 @@ case wxMenuBar_SetLabel_2: { // wxMenuBar::SetLabel
bp += *labelLen+((8-((4+ *labelLen) & 7)) & 7);
if(!This) throw wxe_badarg(0);
This->SetLabel((int) *itemid,label);
- break;
+ break;
}
-case wxMenuBar_SetLabel_1: { // wxMenuBar::SetLabel
+case wxMenuBar_SetLabel_1: { // wxMenuBar::SetLabel
wxMenuBar *This = (wxMenuBar *) getPtr(bp,memenv); bp += 4;
int * sLen = (int *) bp; bp += 4;
wxString s = wxString(bp, wxConvUTF8);
bp += *sLen+((8-((0+ *sLen) & 7)) & 7);
if(!This) throw wxe_badarg(0);
This->SetLabel(s);
- break;
+ break;
}
-case wxMenuBar_SetLabelTop: { // wxMenuBar::SetLabelTop
+case wxMenuBar_SetLabelTop: { // wxMenuBar::SetLabelTop
wxMenuBar *This = (wxMenuBar *) getPtr(bp,memenv); bp += 4;
int * pos = (int *) bp; bp += 4;
int * labelLen = (int *) bp; bp += 4;
@@ -7288,25 +7288,25 @@ case wxMenuBar_SetLabelTop: { // wxMenuBar::SetLabelTop
bp += *labelLen+((8-((4+ *labelLen) & 7)) & 7);
if(!This) throw wxe_badarg(0);
This->SetLabelTop((size_t) *pos,label);
- break;
+ break;
}
-case wxControl_GetLabel: { // wxControl::GetLabel
+case wxControl_GetLabel: { // wxControl::GetLabel
wxControl *This = (wxControl *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
wxString Result = This->GetLabel();
rt.add(Result);
- break;
+ break;
}
-case wxControl_SetLabel: { // wxControl::SetLabel
+case wxControl_SetLabel: { // wxControl::SetLabel
wxControl *This = (wxControl *) getPtr(bp,memenv); bp += 4;
int * labelLen = (int *) bp; bp += 4;
wxString label = wxString(bp, wxConvUTF8);
bp += *labelLen+((8-((0+ *labelLen) & 7)) & 7);
if(!This) throw wxe_badarg(0);
This->SetLabel(label);
- break;
+ break;
}
-case wxControlWithItems_Append_1: { // wxControlWithItems::Append
+case wxControlWithItems_Append_1: { // wxControlWithItems::Append
wxControlWithItems *This = (wxControlWithItems *) getPtr(bp,memenv); bp += 4;
int * itemLen = (int *) bp; bp += 4;
wxString item = wxString(bp, wxConvUTF8);
@@ -7314,20 +7314,20 @@ case wxControlWithItems_Append_1: { // wxControlWithItems::Append
if(!This) throw wxe_badarg(0);
int Result = This->Append(item);
rt.addInt(Result);
- break;
+ break;
}
-case wxControlWithItems_Append_2: { // wxControlWithItems::Append
+case wxControlWithItems_Append_2: { // wxControlWithItems::Append
wxControlWithItems *This = (wxControlWithItems *) getPtr(bp,memenv); bp += 4;
int * itemLen = (int *) bp; bp += 4;
wxString item = wxString(bp, wxConvUTF8);
bp += *itemLen+((8-((0+ *itemLen) & 7)) & 7);
- wxeErlTerm * clientData = new wxeErlTerm(Ecmd.bin[0]);
+ wxeErlTerm * clientData = new wxeErlTerm(Ecmd.bin[0]);
if(!This) throw wxe_badarg(0);
int Result = This->Append(item,clientData);
rt.addInt(Result);
- break;
+ break;
}
-case wxControlWithItems_appendStrings_1: { // wxControlWithItems::Append
+case wxControlWithItems_appendStrings_1: { // wxControlWithItems::Append
wxControlWithItems *This = (wxControlWithItems *) getPtr(bp,memenv); bp += 4;
int * stringsLen = (int *) bp; bp += 4;
wxArrayString strings;
@@ -7341,83 +7341,83 @@ case wxControlWithItems_appendStrings_1: { // wxControlWithItems::Append
bp += (8-((0+ stringsASz) & 7 )) & 7;
if(!This) throw wxe_badarg(0);
This->Append(strings);
- break;
+ break;
}
-case wxControlWithItems_Clear: { // wxControlWithItems::Clear
+case wxControlWithItems_Clear: { // wxControlWithItems::Clear
wxControlWithItems *This = (wxControlWithItems *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
This->Clear();
- break;
+ break;
}
-case wxControlWithItems_Delete: { // wxControlWithItems::Delete
+case wxControlWithItems_Delete: { // wxControlWithItems::Delete
wxControlWithItems *This = (wxControlWithItems *) getPtr(bp,memenv); bp += 4;
unsigned int * n = (unsigned int *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
This->Delete((int) *n);
- break;
+ break;
}
-case wxControlWithItems_FindString: { // wxControlWithItems::FindString
+case wxControlWithItems_FindString: { // wxControlWithItems::FindString
bool bCase=false;
wxControlWithItems *This = (wxControlWithItems *) getPtr(bp,memenv); bp += 4;
int * sLen = (int *) bp; bp += 4;
wxString s = wxString(bp, wxConvUTF8);
bp += *sLen+((8-((0+ *sLen) & 7)) & 7);
- while( * (int*) bp) { switch (* (int*) bp) {
+ while( * (int*) bp) { switch (* (int*) bp) {
case 1: {bp += 4;
bCase = *(bool *) bp; bp += 4;
} break;
- }};
+ }};
if(!This) throw wxe_badarg(0);
int Result = This->FindString(s,bCase);
rt.addInt(Result);
- break;
+ break;
}
-case wxControlWithItems_getClientData: { // wxControlWithItems::GetClientObject
+case wxControlWithItems_getClientData: { // wxControlWithItems::GetClientObject
wxControlWithItems *This = (wxControlWithItems *) getPtr(bp,memenv); bp += 4;
unsigned int * n = (unsigned int *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
wxeErlTerm * Result = (wxeErlTerm*)This->GetClientObject((int) *n);
rt.addExt2Term(Result);
- break;
+ break;
}
-case wxControlWithItems_setClientData: { // wxControlWithItems::SetClientObject
+case wxControlWithItems_setClientData: { // wxControlWithItems::SetClientObject
wxControlWithItems *This = (wxControlWithItems *) getPtr(bp,memenv); bp += 4;
unsigned int * n = (unsigned int *) bp; bp += 4;
- wxeErlTerm * clientData = new wxeErlTerm(Ecmd.bin[0]);
+ wxeErlTerm * clientData = new wxeErlTerm(Ecmd.bin[0]);
if(!This) throw wxe_badarg(0);
This->SetClientObject((int) *n,clientData);
- break;
+ break;
}
-case wxControlWithItems_GetCount: { // wxControlWithItems::GetCount
+case wxControlWithItems_GetCount: { // wxControlWithItems::GetCount
wxControlWithItems *This = (wxControlWithItems *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
int Result = This->GetCount();
rt.addUint(Result);
- break;
+ break;
}
-case wxControlWithItems_GetSelection: { // wxControlWithItems::GetSelection
+case wxControlWithItems_GetSelection: { // wxControlWithItems::GetSelection
wxControlWithItems *This = (wxControlWithItems *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
int Result = This->GetSelection();
rt.addInt(Result);
- break;
+ break;
}
-case wxControlWithItems_GetString: { // wxControlWithItems::GetString
+case wxControlWithItems_GetString: { // wxControlWithItems::GetString
wxControlWithItems *This = (wxControlWithItems *) getPtr(bp,memenv); bp += 4;
unsigned int * n = (unsigned int *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
wxString Result = This->GetString((int) *n);
rt.add(Result);
- break;
+ break;
}
-case wxControlWithItems_GetStringSelection: { // wxControlWithItems::GetStringSelection
+case wxControlWithItems_GetStringSelection: { // wxControlWithItems::GetStringSelection
wxControlWithItems *This = (wxControlWithItems *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
wxString Result = This->GetStringSelection();
rt.add(Result);
- break;
+ break;
}
-case wxControlWithItems_Insert_2: { // wxControlWithItems::Insert
+case wxControlWithItems_Insert_2: { // wxControlWithItems::Insert
wxControlWithItems *This = (wxControlWithItems *) getPtr(bp,memenv); bp += 4;
int * itemLen = (int *) bp; bp += 4;
wxString item = wxString(bp, wxConvUTF8);
@@ -7426,42 +7426,42 @@ case wxControlWithItems_Insert_2: { // wxControlWithItems::Insert
if(!This) throw wxe_badarg(0);
int Result = This->Insert(item,(int) *pos);
rt.addInt(Result);
- break;
+ break;
}
-case wxControlWithItems_Insert_3: { // wxControlWithItems::Insert
+case wxControlWithItems_Insert_3: { // wxControlWithItems::Insert
wxControlWithItems *This = (wxControlWithItems *) getPtr(bp,memenv); bp += 4;
int * itemLen = (int *) bp; bp += 4;
wxString item = wxString(bp, wxConvUTF8);
bp += *itemLen+((8-((0+ *itemLen) & 7)) & 7);
unsigned int * pos = (unsigned int *) bp; bp += 4;
- wxeErlTerm * clientData = new wxeErlTerm(Ecmd.bin[0]);
+ wxeErlTerm * clientData = new wxeErlTerm(Ecmd.bin[0]);
if(!This) throw wxe_badarg(0);
int Result = This->Insert(item,(int) *pos,clientData);
rt.addInt(Result);
- break;
+ break;
}
-case wxControlWithItems_IsEmpty: { // wxControlWithItems::IsEmpty
+case wxControlWithItems_IsEmpty: { // wxControlWithItems::IsEmpty
wxControlWithItems *This = (wxControlWithItems *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
bool Result = This->IsEmpty();
rt.addBool(Result);
- break;
+ break;
}
-case wxControlWithItems_Select: { // wxControlWithItems::Select
+case wxControlWithItems_Select: { // wxControlWithItems::Select
wxControlWithItems *This = (wxControlWithItems *) getPtr(bp,memenv); bp += 4;
int * n = (int *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
This->Select((int) *n);
- break;
+ break;
}
-case wxControlWithItems_SetSelection: { // wxControlWithItems::SetSelection
+case wxControlWithItems_SetSelection: { // wxControlWithItems::SetSelection
wxControlWithItems *This = (wxControlWithItems *) getPtr(bp,memenv); bp += 4;
int * n = (int *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
This->SetSelection((int) *n);
- break;
+ break;
}
-case wxControlWithItems_SetString: { // wxControlWithItems::SetString
+case wxControlWithItems_SetString: { // wxControlWithItems::SetString
wxControlWithItems *This = (wxControlWithItems *) getPtr(bp,memenv); bp += 4;
unsigned int * n = (unsigned int *) bp; bp += 4;
int * sLen = (int *) bp; bp += 4;
@@ -7469,9 +7469,9 @@ case wxControlWithItems_SetString: { // wxControlWithItems::SetString
bp += *sLen+((8-((4+ *sLen) & 7)) & 7);
if(!This) throw wxe_badarg(0);
This->SetString((int) *n,s);
- break;
+ break;
}
-case wxControlWithItems_SetStringSelection: { // wxControlWithItems::SetStringSelection
+case wxControlWithItems_SetStringSelection: { // wxControlWithItems::SetStringSelection
wxControlWithItems *This = (wxControlWithItems *) getPtr(bp,memenv); bp += 4;
int * sLen = (int *) bp; bp += 4;
wxString s = wxString(bp, wxConvUTF8);
@@ -7479,36 +7479,36 @@ case wxControlWithItems_SetStringSelection: { // wxControlWithItems::SetStringSe
if(!This) throw wxe_badarg(0);
bool Result = This->SetStringSelection(s);
rt.addBool(Result);
- break;
+ break;
}
-case wxMenu_new_2: { // wxMenu::wxMenu
+case wxMenu_new_2: { // wxMenu::wxMenu
long style=0;
int * titleLen = (int *) bp; bp += 4;
wxString title = wxString(bp, wxConvUTF8);
bp += *titleLen+((8-((4+ *titleLen) & 7)) & 7);
- while( * (int*) bp) { switch (* (int*) bp) {
+ while( * (int*) bp) { switch (* (int*) bp) {
case 1: {bp += 4;
style = (long)*(int *) bp; bp += 4;
} break;
- }};
+ }};
wxMenu * Result = new EwxMenu(title,style);
newPtr((void *) Result, 1, memenv);
rt.addRef(getRef((void *)Result,memenv), "wxMenu");
- break;
+ break;
}
-case wxMenu_new_1: { // wxMenu::wxMenu
+case wxMenu_new_1: { // wxMenu::wxMenu
long style=0;
- while( * (int*) bp) { switch (* (int*) bp) {
+ while( * (int*) bp) { switch (* (int*) bp) {
case 1: {bp += 4;
style = (long)*(int *) bp; bp += 4;
} break;
- }};
+ }};
wxMenu * Result = new EwxMenu(style);
newPtr((void *) Result, 1, memenv);
rt.addRef(getRef((void *)Result,memenv), "wxMenu");
- break;
+ break;
}
-case wxMenu_Append_3: { // wxMenu::Append
+case wxMenu_Append_3: { // wxMenu::Append
wxString help= wxEmptyString;
wxItemKind kind=wxITEM_NORMAL;
wxMenu *This = (wxMenu *) getPtr(bp,memenv); bp += 4;
@@ -7516,7 +7516,7 @@ case wxMenu_Append_3: { // wxMenu::Append
int * textLen = (int *) bp; bp += 4;
wxString text = wxString(bp, wxConvUTF8);
bp += *textLen+((8-((4+ *textLen) & 7)) & 7);
- while( * (int*) bp) { switch (* (int*) bp) {
+ while( * (int*) bp) { switch (* (int*) bp) {
case 1: {bp += 4;
int * helpLen = (int *) bp; bp += 4;
help = wxString(bp, wxConvUTF8);
@@ -7525,21 +7525,21 @@ case wxMenu_Append_3: { // wxMenu::Append
case 2: {bp += 4;
kind = *(wxItemKind *) bp; bp += 4;;
} break;
- }};
+ }};
if(!This) throw wxe_badarg(0);
wxMenuItem * Result = (wxMenuItem*)This->Append((int) *itemid,text,help,(wxItemKind) kind);
rt.addRef(getRef((void *)Result,memenv), "wxMenuItem");
- break;
+ break;
}
-case wxMenu_Append_1: { // wxMenu::Append
+case wxMenu_Append_1: { // wxMenu::Append
wxMenu *This = (wxMenu *) getPtr(bp,memenv); bp += 4;
wxMenuItem *item = (wxMenuItem *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
wxMenuItem * Result = (wxMenuItem*)This->Append(item);
rt.addRef(getRef((void *)Result,memenv), "wxMenuItem");
- break;
+ break;
}
-case wxMenu_Append_4_0: { // wxMenu::Append
+case wxMenu_Append_4_0: { // wxMenu::Append
wxMenu *This = (wxMenu *) getPtr(bp,memenv); bp += 4;
int * itemid = (int *) bp; bp += 4;
int * textLen = (int *) bp; bp += 4;
@@ -7551,9 +7551,9 @@ case wxMenu_Append_4_0: { // wxMenu::Append
bool * isCheckable = (bool *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
This->Append((int) *itemid,text,help,(bool) *isCheckable);
- break;
+ break;
}
-case wxMenu_Append_4_1: { // wxMenu::Append
+case wxMenu_Append_4_1: { // wxMenu::Append
wxString help= wxEmptyString;
wxMenu *This = (wxMenu *) getPtr(bp,memenv); bp += 4;
int * itemid = (int *) bp; bp += 4;
@@ -7562,118 +7562,118 @@ case wxMenu_Append_4_1: { // wxMenu::Append
bp += *textLen+((8-((4+ *textLen) & 7)) & 7);
wxMenu *submenu = (wxMenu *) getPtr(bp,memenv); bp += 4;
bp += 4; /* Align */
- while( * (int*) bp) { switch (* (int*) bp) {
+ while( * (int*) bp) { switch (* (int*) bp) {
case 1: {bp += 4;
int * helpLen = (int *) bp; bp += 4;
help = wxString(bp, wxConvUTF8);
bp += *helpLen+((8-((0+ *helpLen) & 7)) & 7);
} break;
- }};
+ }};
if(!This) throw wxe_badarg(0);
wxMenuItem * Result = (wxMenuItem*)This->Append((int) *itemid,text,submenu,help);
rt.addRef(getRef((void *)Result,memenv), "wxMenuItem");
- break;
+ break;
}
-case wxMenu_AppendCheckItem: { // wxMenu::AppendCheckItem
+case wxMenu_AppendCheckItem: { // wxMenu::AppendCheckItem
wxString help= wxEmptyString;
wxMenu *This = (wxMenu *) getPtr(bp,memenv); bp += 4;
int * itemid = (int *) bp; bp += 4;
int * textLen = (int *) bp; bp += 4;
wxString text = wxString(bp, wxConvUTF8);
bp += *textLen+((8-((4+ *textLen) & 7)) & 7);
- while( * (int*) bp) { switch (* (int*) bp) {
+ while( * (int*) bp) { switch (* (int*) bp) {
case 1: {bp += 4;
int * helpLen = (int *) bp; bp += 4;
help = wxString(bp, wxConvUTF8);
bp += *helpLen+((8-((0+ *helpLen) & 7)) & 7);
} break;
- }};
+ }};
if(!This) throw wxe_badarg(0);
wxMenuItem * Result = (wxMenuItem*)This->AppendCheckItem((int) *itemid,text,help);
rt.addRef(getRef((void *)Result,memenv), "wxMenuItem");
- break;
+ break;
}
-case wxMenu_AppendRadioItem: { // wxMenu::AppendRadioItem
+case wxMenu_AppendRadioItem: { // wxMenu::AppendRadioItem
wxString help= wxEmptyString;
wxMenu *This = (wxMenu *) getPtr(bp,memenv); bp += 4;
int * itemid = (int *) bp; bp += 4;
int * textLen = (int *) bp; bp += 4;
wxString text = wxString(bp, wxConvUTF8);
bp += *textLen+((8-((4+ *textLen) & 7)) & 7);
- while( * (int*) bp) { switch (* (int*) bp) {
+ while( * (int*) bp) { switch (* (int*) bp) {
case 1: {bp += 4;
int * helpLen = (int *) bp; bp += 4;
help = wxString(bp, wxConvUTF8);
bp += *helpLen+((8-((0+ *helpLen) & 7)) & 7);
} break;
- }};
+ }};
if(!This) throw wxe_badarg(0);
wxMenuItem * Result = (wxMenuItem*)This->AppendRadioItem((int) *itemid,text,help);
rt.addRef(getRef((void *)Result,memenv), "wxMenuItem");
- break;
+ break;
}
-case wxMenu_AppendSeparator: { // wxMenu::AppendSeparator
+case wxMenu_AppendSeparator: { // wxMenu::AppendSeparator
wxMenu *This = (wxMenu *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
wxMenuItem * Result = (wxMenuItem*)This->AppendSeparator();
rt.addRef(getRef((void *)Result,memenv), "wxMenuItem");
- break;
+ break;
}
-case wxMenu_Break: { // wxMenu::Break
+case wxMenu_Break: { // wxMenu::Break
wxMenu *This = (wxMenu *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
This->Break();
- break;
+ break;
}
-case wxMenu_Check: { // wxMenu::Check
+case wxMenu_Check: { // wxMenu::Check
wxMenu *This = (wxMenu *) getPtr(bp,memenv); bp += 4;
int * itemid = (int *) bp; bp += 4;
bool * check = (bool *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
This->Check((int) *itemid,(bool) *check);
- break;
+ break;
}
-case wxMenu_Delete_1_0: { // wxMenu::Delete
+case wxMenu_Delete_1_0: { // wxMenu::Delete
wxMenu *This = (wxMenu *) getPtr(bp,memenv); bp += 4;
int * itemid = (int *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
bool Result = This->Delete((int) *itemid);
rt.addBool(Result);
- break;
+ break;
}
-case wxMenu_Delete_1_1: { // wxMenu::Delete
+case wxMenu_Delete_1_1: { // wxMenu::Delete
wxMenu *This = (wxMenu *) getPtr(bp,memenv); bp += 4;
wxMenuItem *item = (wxMenuItem *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
bool Result = This->Delete(item);
rt.addBool(Result);
- break;
+ break;
}
-case wxMenu_Destroy_1_0: { // wxMenu::Destroy
+case wxMenu_Destroy_1_0: { // wxMenu::Destroy
wxMenu *This = (wxMenu *) getPtr(bp,memenv); bp += 4;
int * itemid = (int *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
bool Result = This->Destroy((int) *itemid);
rt.addBool(Result);
- break;
+ break;
}
-case wxMenu_Destroy_1_1: { // wxMenu::Destroy
+case wxMenu_Destroy_1_1: { // wxMenu::Destroy
wxMenu *This = (wxMenu *) getPtr(bp,memenv); bp += 4;
wxMenuItem *item = (wxMenuItem *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
bool Result = This->Destroy(item);
rt.addBool(Result);
- break;
+ break;
}
-case wxMenu_Enable: { // wxMenu::Enable
+case wxMenu_Enable: { // wxMenu::Enable
wxMenu *This = (wxMenu *) getPtr(bp,memenv); bp += 4;
int * itemid = (int *) bp; bp += 4;
bool * enable = (bool *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
This->Enable((int) *itemid,(bool) *enable);
- break;
+ break;
}
-case wxMenu_FindItem_1: { // wxMenu::FindItem
+case wxMenu_FindItem_1: { // wxMenu::FindItem
wxMenu *This = (wxMenu *) getPtr(bp,memenv); bp += 4;
int * itemLen = (int *) bp; bp += 4;
wxString item = wxString(bp, wxConvUTF8);
@@ -7681,49 +7681,49 @@ case wxMenu_FindItem_1: { // wxMenu::FindItem
if(!This) throw wxe_badarg(0);
int Result = This->FindItem(item);
rt.addInt(Result);
- break;
+ break;
}
-case wxMenu_FindItem_2: { // wxMenu::FindItem
+case wxMenu_FindItem_2: { // wxMenu::FindItem
wxMenu ** menu = NULL;
wxMenu *This = (wxMenu *) getPtr(bp,memenv); bp += 4;
int * itemid = (int *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
wxMenuItem * Result = (wxMenuItem*)This->FindItem((int) *itemid,menu);
rt.addRef(getRef((void *)Result,memenv), "wxMenuItem");
- break;
+ break;
}
-case wxMenu_FindItemByPosition: { // wxMenu::FindItemByPosition
+case wxMenu_FindItemByPosition: { // wxMenu::FindItemByPosition
wxMenu *This = (wxMenu *) getPtr(bp,memenv); bp += 4;
int * position = (int *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
wxMenuItem * Result = (wxMenuItem*)This->FindItemByPosition((size_t) *position);
rt.addRef(getRef((void *)Result,memenv), "wxMenuItem");
- break;
+ break;
}
-case wxMenu_GetHelpString: { // wxMenu::GetHelpString
+case wxMenu_GetHelpString: { // wxMenu::GetHelpString
wxMenu *This = (wxMenu *) getPtr(bp,memenv); bp += 4;
int * itemid = (int *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
wxString Result = This->GetHelpString((int) *itemid);
rt.add(Result);
- break;
+ break;
}
-case wxMenu_GetLabel: { // wxMenu::GetLabel
+case wxMenu_GetLabel: { // wxMenu::GetLabel
wxMenu *This = (wxMenu *) getPtr(bp,memenv); bp += 4;
int * itemid = (int *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
wxString Result = This->GetLabel((int) *itemid);
rt.add(Result);
- break;
+ break;
}
-case wxMenu_GetMenuItemCount: { // wxMenu::GetMenuItemCount
+case wxMenu_GetMenuItemCount: { // wxMenu::GetMenuItemCount
wxMenu *This = (wxMenu *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
size_t Result = This->GetMenuItemCount();
rt.addInt(Result);
- break;
+ break;
}
-case wxMenu_GetMenuItems: { // wxMenu::GetMenuItems
+case wxMenu_GetMenuItems: { // wxMenu::GetMenuItems
wxMenu *This = (wxMenu *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
const wxMenuItemList Result = This->GetMenuItems();
@@ -7732,25 +7732,25 @@ case wxMenu_GetMenuItems: { // wxMenu::GetMenuItems
wxMenuItem * ResultTmp = *it;
rt.addRef(getRef((void *)ResultTmp,memenv), "wxMenuItem"); i++;}
rt.endList(Result.GetCount());
- break;
+ break;
}
-case wxMenu_GetTitle: { // wxMenu::GetTitle
+case wxMenu_GetTitle: { // wxMenu::GetTitle
wxMenu *This = (wxMenu *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
const wxString Result = This->GetTitle();
rt.add(Result);
- break;
+ break;
}
-case wxMenu_Insert_2: { // wxMenu::Insert
+case wxMenu_Insert_2: { // wxMenu::Insert
wxMenu *This = (wxMenu *) getPtr(bp,memenv); bp += 4;
int * pos = (int *) bp; bp += 4;
wxMenuItem *item = (wxMenuItem *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
wxMenuItem * Result = (wxMenuItem*)This->Insert((size_t) *pos,item);
rt.addRef(getRef((void *)Result,memenv), "wxMenuItem");
- break;
+ break;
}
-case wxMenu_Insert_3: { // wxMenu::Insert
+case wxMenu_Insert_3: { // wxMenu::Insert
wxString text= wxEmptyString;
wxString help= wxEmptyString;
wxItemKind kind=wxITEM_NORMAL;
@@ -7758,7 +7758,7 @@ case wxMenu_Insert_3: { // wxMenu::Insert
int * pos = (int *) bp; bp += 4;
int * itemid = (int *) bp; bp += 4;
bp += 4; /* Align */
- while( * (int*) bp) { switch (* (int*) bp) {
+ while( * (int*) bp) { switch (* (int*) bp) {
case 1: {bp += 4;
int * textLen = (int *) bp; bp += 4;
text = wxString(bp, wxConvUTF8);
@@ -7772,13 +7772,13 @@ case wxMenu_Insert_3: { // wxMenu::Insert
case 3: {bp += 4;
kind = *(wxItemKind *) bp; bp += 4;;
} break;
- }};
+ }};
if(!This) throw wxe_badarg(0);
wxMenuItem * Result = (wxMenuItem*)This->Insert((size_t) *pos,(int) *itemid,text,help,(wxItemKind) kind);
rt.addRef(getRef((void *)Result,memenv), "wxMenuItem");
- break;
+ break;
}
-case wxMenu_Insert_5_1: { // wxMenu::Insert
+case wxMenu_Insert_5_1: { // wxMenu::Insert
wxString help= wxEmptyString;
wxMenu *This = (wxMenu *) getPtr(bp,memenv); bp += 4;
int * pos = (int *) bp; bp += 4;
@@ -7788,19 +7788,19 @@ case wxMenu_Insert_5_1: { // wxMenu::Insert
bp += *textLen+((8-((0+ *textLen) & 7)) & 7);
wxMenu *submenu = (wxMenu *) getPtr(bp,memenv); bp += 4;
bp += 4; /* Align */
- while( * (int*) bp) { switch (* (int*) bp) {
+ while( * (int*) bp) { switch (* (int*) bp) {
case 1: {bp += 4;
int * helpLen = (int *) bp; bp += 4;
help = wxString(bp, wxConvUTF8);
bp += *helpLen+((8-((0+ *helpLen) & 7)) & 7);
} break;
- }};
+ }};
if(!This) throw wxe_badarg(0);
wxMenuItem * Result = (wxMenuItem*)This->Insert((size_t) *pos,(int) *itemid,text,submenu,help);
rt.addRef(getRef((void *)Result,memenv), "wxMenuItem");
- break;
+ break;
}
-case wxMenu_Insert_5_0: { // wxMenu::Insert
+case wxMenu_Insert_5_0: { // wxMenu::Insert
wxMenu *This = (wxMenu *) getPtr(bp,memenv); bp += 4;
int * pos = (int *) bp; bp += 4;
int * itemid = (int *) bp; bp += 4;
@@ -7813,9 +7813,9 @@ case wxMenu_Insert_5_0: { // wxMenu::Insert
bool * isCheckable = (bool *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
This->Insert((size_t) *pos,(int) *itemid,text,help,(bool) *isCheckable);
- break;
+ break;
}
-case wxMenu_InsertCheckItem: { // wxMenu::InsertCheckItem
+case wxMenu_InsertCheckItem: { // wxMenu::InsertCheckItem
wxString help= wxEmptyString;
wxMenu *This = (wxMenu *) getPtr(bp,memenv); bp += 4;
int * pos = (int *) bp; bp += 4;
@@ -7823,19 +7823,19 @@ case wxMenu_InsertCheckItem: { // wxMenu::InsertCheckItem
int * textLen = (int *) bp; bp += 4;
wxString text = wxString(bp, wxConvUTF8);
bp += *textLen+((8-((0+ *textLen) & 7)) & 7);
- while( * (int*) bp) { switch (* (int*) bp) {
+ while( * (int*) bp) { switch (* (int*) bp) {
case 1: {bp += 4;
int * helpLen = (int *) bp; bp += 4;
help = wxString(bp, wxConvUTF8);
bp += *helpLen+((8-((0+ *helpLen) & 7)) & 7);
} break;
- }};
+ }};
if(!This) throw wxe_badarg(0);
wxMenuItem * Result = (wxMenuItem*)This->InsertCheckItem((size_t) *pos,(int) *itemid,text,help);
rt.addRef(getRef((void *)Result,memenv), "wxMenuItem");
- break;
+ break;
}
-case wxMenu_InsertRadioItem: { // wxMenu::InsertRadioItem
+case wxMenu_InsertRadioItem: { // wxMenu::InsertRadioItem
wxString help= wxEmptyString;
wxMenu *This = (wxMenu *) getPtr(bp,memenv); bp += 4;
int * pos = (int *) bp; bp += 4;
@@ -7843,57 +7843,57 @@ case wxMenu_InsertRadioItem: { // wxMenu::InsertRadioItem
int * textLen = (int *) bp; bp += 4;
wxString text = wxString(bp, wxConvUTF8);
bp += *textLen+((8-((0+ *textLen) & 7)) & 7);
- while( * (int*) bp) { switch (* (int*) bp) {
+ while( * (int*) bp) { switch (* (int*) bp) {
case 1: {bp += 4;
int * helpLen = (int *) bp; bp += 4;
help = wxString(bp, wxConvUTF8);
bp += *helpLen+((8-((0+ *helpLen) & 7)) & 7);
} break;
- }};
+ }};
if(!This) throw wxe_badarg(0);
wxMenuItem * Result = (wxMenuItem*)This->InsertRadioItem((size_t) *pos,(int) *itemid,text,help);
rt.addRef(getRef((void *)Result,memenv), "wxMenuItem");
- break;
+ break;
}
-case wxMenu_InsertSeparator: { // wxMenu::InsertSeparator
+case wxMenu_InsertSeparator: { // wxMenu::InsertSeparator
wxMenu *This = (wxMenu *) getPtr(bp,memenv); bp += 4;
int * pos = (int *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
wxMenuItem * Result = (wxMenuItem*)This->InsertSeparator((size_t) *pos);
rt.addRef(getRef((void *)Result,memenv), "wxMenuItem");
- break;
+ break;
}
-case wxMenu_IsChecked: { // wxMenu::IsChecked
+case wxMenu_IsChecked: { // wxMenu::IsChecked
wxMenu *This = (wxMenu *) getPtr(bp,memenv); bp += 4;
int * itemid = (int *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
bool Result = This->IsChecked((int) *itemid);
rt.addBool(Result);
- break;
+ break;
}
-case wxMenu_IsEnabled: { // wxMenu::IsEnabled
+case wxMenu_IsEnabled: { // wxMenu::IsEnabled
wxMenu *This = (wxMenu *) getPtr(bp,memenv); bp += 4;
int * itemid = (int *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
bool Result = This->IsEnabled((int) *itemid);
rt.addBool(Result);
- break;
+ break;
}
-case wxMenu_Prepend_1: { // wxMenu::Prepend
+case wxMenu_Prepend_1: { // wxMenu::Prepend
wxMenu *This = (wxMenu *) getPtr(bp,memenv); bp += 4;
wxMenuItem *item = (wxMenuItem *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
wxMenuItem * Result = (wxMenuItem*)This->Prepend(item);
rt.addRef(getRef((void *)Result,memenv), "wxMenuItem");
- break;
+ break;
}
-case wxMenu_Prepend_2: { // wxMenu::Prepend
+case wxMenu_Prepend_2: { // wxMenu::Prepend
wxString text= wxEmptyString;
wxString help= wxEmptyString;
wxItemKind kind=wxITEM_NORMAL;
wxMenu *This = (wxMenu *) getPtr(bp,memenv); bp += 4;
int * itemid = (int *) bp; bp += 4;
- while( * (int*) bp) { switch (* (int*) bp) {
+ while( * (int*) bp) { switch (* (int*) bp) {
case 1: {bp += 4;
int * textLen = (int *) bp; bp += 4;
text = wxString(bp, wxConvUTF8);
@@ -7907,13 +7907,13 @@ case wxMenu_Prepend_2: { // wxMenu::Prepend
case 3: {bp += 4;
kind = *(wxItemKind *) bp; bp += 4;;
} break;
- }};
+ }};
if(!This) throw wxe_badarg(0);
wxMenuItem * Result = (wxMenuItem*)This->Prepend((int) *itemid,text,help,(wxItemKind) kind);
rt.addRef(getRef((void *)Result,memenv), "wxMenuItem");
- break;
+ break;
}
-case wxMenu_Prepend_4_1: { // wxMenu::Prepend
+case wxMenu_Prepend_4_1: { // wxMenu::Prepend
wxString help= wxEmptyString;
wxMenu *This = (wxMenu *) getPtr(bp,memenv); bp += 4;
int * itemid = (int *) bp; bp += 4;
@@ -7922,19 +7922,19 @@ case wxMenu_Prepend_4_1: { // wxMenu::Prepend
bp += *textLen+((8-((4+ *textLen) & 7)) & 7);
wxMenu *submenu = (wxMenu *) getPtr(bp,memenv); bp += 4;
bp += 4; /* Align */
- while( * (int*) bp) { switch (* (int*) bp) {
+ while( * (int*) bp) { switch (* (int*) bp) {
case 1: {bp += 4;
int * helpLen = (int *) bp; bp += 4;
help = wxString(bp, wxConvUTF8);
bp += *helpLen+((8-((0+ *helpLen) & 7)) & 7);
} break;
- }};
+ }};
if(!This) throw wxe_badarg(0);
wxMenuItem * Result = (wxMenuItem*)This->Prepend((int) *itemid,text,submenu,help);
rt.addRef(getRef((void *)Result,memenv), "wxMenuItem");
- break;
+ break;
}
-case wxMenu_Prepend_4_0: { // wxMenu::Prepend
+case wxMenu_Prepend_4_0: { // wxMenu::Prepend
wxMenu *This = (wxMenu *) getPtr(bp,memenv); bp += 4;
int * itemid = (int *) bp; bp += 4;
int * textLen = (int *) bp; bp += 4;
@@ -7946,70 +7946,70 @@ case wxMenu_Prepend_4_0: { // wxMenu::Prepend
bool * isCheckable = (bool *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
This->Prepend((int) *itemid,text,help,(bool) *isCheckable);
- break;
+ break;
}
-case wxMenu_PrependCheckItem: { // wxMenu::PrependCheckItem
+case wxMenu_PrependCheckItem: { // wxMenu::PrependCheckItem
wxString help= wxEmptyString;
wxMenu *This = (wxMenu *) getPtr(bp,memenv); bp += 4;
int * itemid = (int *) bp; bp += 4;
int * textLen = (int *) bp; bp += 4;
wxString text = wxString(bp, wxConvUTF8);
bp += *textLen+((8-((4+ *textLen) & 7)) & 7);
- while( * (int*) bp) { switch (* (int*) bp) {
+ while( * (int*) bp) { switch (* (int*) bp) {
case 1: {bp += 4;
int * helpLen = (int *) bp; bp += 4;
help = wxString(bp, wxConvUTF8);
bp += *helpLen+((8-((0+ *helpLen) & 7)) & 7);
} break;
- }};
+ }};
if(!This) throw wxe_badarg(0);
wxMenuItem * Result = (wxMenuItem*)This->PrependCheckItem((int) *itemid,text,help);
rt.addRef(getRef((void *)Result,memenv), "wxMenuItem");
- break;
+ break;
}
-case wxMenu_PrependRadioItem: { // wxMenu::PrependRadioItem
+case wxMenu_PrependRadioItem: { // wxMenu::PrependRadioItem
wxString help= wxEmptyString;
wxMenu *This = (wxMenu *) getPtr(bp,memenv); bp += 4;
int * itemid = (int *) bp; bp += 4;
int * textLen = (int *) bp; bp += 4;
wxString text = wxString(bp, wxConvUTF8);
bp += *textLen+((8-((4+ *textLen) & 7)) & 7);
- while( * (int*) bp) { switch (* (int*) bp) {
+ while( * (int*) bp) { switch (* (int*) bp) {
case 1: {bp += 4;
int * helpLen = (int *) bp; bp += 4;
help = wxString(bp, wxConvUTF8);
bp += *helpLen+((8-((0+ *helpLen) & 7)) & 7);
} break;
- }};
+ }};
if(!This) throw wxe_badarg(0);
wxMenuItem * Result = (wxMenuItem*)This->PrependRadioItem((int) *itemid,text,help);
rt.addRef(getRef((void *)Result,memenv), "wxMenuItem");
- break;
+ break;
}
-case wxMenu_PrependSeparator: { // wxMenu::PrependSeparator
+case wxMenu_PrependSeparator: { // wxMenu::PrependSeparator
wxMenu *This = (wxMenu *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
wxMenuItem * Result = (wxMenuItem*)This->PrependSeparator();
rt.addRef(getRef((void *)Result,memenv), "wxMenuItem");
- break;
+ break;
}
-case wxMenu_Remove_1_0: { // wxMenu::Remove
+case wxMenu_Remove_1_0: { // wxMenu::Remove
wxMenu *This = (wxMenu *) getPtr(bp,memenv); bp += 4;
int * itemid = (int *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
wxMenuItem * Result = (wxMenuItem*)This->Remove((int) *itemid);
rt.addRef(getRef((void *)Result,memenv), "wxMenuItem");
- break;
+ break;
}
-case wxMenu_Remove_1_1: { // wxMenu::Remove
+case wxMenu_Remove_1_1: { // wxMenu::Remove
wxMenu *This = (wxMenu *) getPtr(bp,memenv); bp += 4;
wxMenuItem *item = (wxMenuItem *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
wxMenuItem * Result = (wxMenuItem*)This->Remove(item);
rt.addRef(getRef((void *)Result,memenv), "wxMenuItem");
- break;
+ break;
}
-case wxMenu_SetHelpString: { // wxMenu::SetHelpString
+case wxMenu_SetHelpString: { // wxMenu::SetHelpString
wxMenu *This = (wxMenu *) getPtr(bp,memenv); bp += 4;
int * itemid = (int *) bp; bp += 4;
int * helpStringLen = (int *) bp; bp += 4;
@@ -8017,9 +8017,9 @@ case wxMenu_SetHelpString: { // wxMenu::SetHelpString
bp += *helpStringLen+((8-((4+ *helpStringLen) & 7)) & 7);
if(!This) throw wxe_badarg(0);
This->SetHelpString((int) *itemid,helpString);
- break;
+ break;
}
-case wxMenu_SetLabel: { // wxMenu::SetLabel
+case wxMenu_SetLabel: { // wxMenu::SetLabel
wxMenu *This = (wxMenu *) getPtr(bp,memenv); bp += 4;
int * itemid = (int *) bp; bp += 4;
int * labelLen = (int *) bp; bp += 4;
@@ -8027,25 +8027,25 @@ case wxMenu_SetLabel: { // wxMenu::SetLabel
bp += *labelLen+((8-((4+ *labelLen) & 7)) & 7);
if(!This) throw wxe_badarg(0);
This->SetLabel((int) *itemid,label);
- break;
+ break;
}
-case wxMenu_SetTitle: { // wxMenu::SetTitle
+case wxMenu_SetTitle: { // wxMenu::SetTitle
wxMenu *This = (wxMenu *) getPtr(bp,memenv); bp += 4;
int * titleLen = (int *) bp; bp += 4;
wxString title = wxString(bp, wxConvUTF8);
bp += *titleLen+((8-((0+ *titleLen) & 7)) & 7);
if(!This) throw wxe_badarg(0);
This->SetTitle(title);
- break;
+ break;
}
-case wxMenuItem_new: { // wxMenuItem::wxMenuItem
+case wxMenuItem_new: { // wxMenuItem::wxMenuItem
wxMenu * parentMenu=(wxMenu *) NULL;
int id=wxID_SEPARATOR;
wxString text= wxEmptyString;
wxString help= wxEmptyString;
wxItemKind kind=wxITEM_NORMAL;
wxMenu * subMenu=(wxMenu *) NULL;
- while( * (int*) bp) { switch (* (int*) bp) {
+ while( * (int*) bp) { switch (* (int*) bp) {
case 1: {bp += 4;
parentMenu = (wxMenu *) getPtr(bp,memenv); bp += 4;
} break;
@@ -8068,192 +8068,192 @@ kind = *(wxItemKind *) bp; bp += 4;;
case 6: {bp += 4;
subMenu = (wxMenu *) getPtr(bp,memenv); bp += 4;
} break;
- }};
+ }};
wxMenuItem * Result = new EwxMenuItem(parentMenu,id,text,help,(wxItemKind) kind,subMenu);
newPtr((void *) Result, 1, memenv);
rt.addRef(getRef((void *)Result,memenv), "wxMenuItem");
- break;
+ break;
}
-case wxMenuItem_Check: { // wxMenuItem::Check
+case wxMenuItem_Check: { // wxMenuItem::Check
bool check=TRUE;
wxMenuItem *This = (wxMenuItem *) getPtr(bp,memenv); bp += 4;
bp += 4; /* Align */
- while( * (int*) bp) { switch (* (int*) bp) {
+ while( * (int*) bp) { switch (* (int*) bp) {
case 1: {bp += 4;
check = *(bool *) bp; bp += 4;
} break;
- }};
+ }};
if(!This) throw wxe_badarg(0);
This->Check(check);
- break;
+ break;
}
-case wxMenuItem_Enable: { // wxMenuItem::Enable
+case wxMenuItem_Enable: { // wxMenuItem::Enable
bool enable=TRUE;
wxMenuItem *This = (wxMenuItem *) getPtr(bp,memenv); bp += 4;
bp += 4; /* Align */
- while( * (int*) bp) { switch (* (int*) bp) {
+ while( * (int*) bp) { switch (* (int*) bp) {
case 1: {bp += 4;
enable = *(bool *) bp; bp += 4;
} break;
- }};
+ }};
if(!This) throw wxe_badarg(0);
This->Enable(enable);
- break;
+ break;
}
-case wxMenuItem_GetBitmap: { // wxMenuItem::GetBitmap
+case wxMenuItem_GetBitmap: { // wxMenuItem::GetBitmap
wxMenuItem *This = (wxMenuItem *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
const wxBitmap * Result = &This->GetBitmap();
rt.addRef(getRef((void *)Result,memenv), "wxBitmap");
- break;
+ break;
}
-case wxMenuItem_GetHelp: { // wxMenuItem::GetHelp
+case wxMenuItem_GetHelp: { // wxMenuItem::GetHelp
wxMenuItem *This = (wxMenuItem *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
const wxString * Result = &This->GetHelp();
rt.add(Result);
- break;
+ break;
}
-case wxMenuItem_GetId: { // wxMenuItem::GetId
+case wxMenuItem_GetId: { // wxMenuItem::GetId
wxMenuItem *This = (wxMenuItem *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
int Result = This->GetId();
rt.addInt(Result);
- break;
+ break;
}
-case wxMenuItem_GetKind: { // wxMenuItem::GetKind
+case wxMenuItem_GetKind: { // wxMenuItem::GetKind
wxMenuItem *This = (wxMenuItem *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
int Result = This->GetKind();
rt.addInt(Result);
- break;
+ break;
}
-case wxMenuItem_GetLabel: { // wxMenuItem::GetLabel
+case wxMenuItem_GetLabel: { // wxMenuItem::GetLabel
wxMenuItem *This = (wxMenuItem *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
wxString Result = This->GetLabel();
rt.add(Result);
- break;
+ break;
}
-case wxMenuItem_GetLabelFromText: { // wxMenuItem::GetLabelFromText
+case wxMenuItem_GetLabelFromText: { // wxMenuItem::GetLabelFromText
int * textLen = (int *) bp; bp += 4;
wxString text = wxString(bp, wxConvUTF8);
bp += *textLen+((8-((4+ *textLen) & 7)) & 7);
wxString Result = wxMenuItem::GetLabelFromText(text);
rt.add(Result);
- break;
+ break;
}
-case wxMenuItem_GetMenu: { // wxMenuItem::GetMenu
+case wxMenuItem_GetMenu: { // wxMenuItem::GetMenu
wxMenuItem *This = (wxMenuItem *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
wxMenu * Result = (wxMenu*)This->GetMenu();
rt.addRef(getRef((void *)Result,memenv), "wxMenu");
- break;
+ break;
}
-case wxMenuItem_GetText: { // wxMenuItem::GetText
+case wxMenuItem_GetText: { // wxMenuItem::GetText
wxMenuItem *This = (wxMenuItem *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
const wxString * Result = &This->GetText();
rt.add(Result);
- break;
+ break;
}
-case wxMenuItem_GetSubMenu: { // wxMenuItem::GetSubMenu
+case wxMenuItem_GetSubMenu: { // wxMenuItem::GetSubMenu
wxMenuItem *This = (wxMenuItem *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
wxMenu * Result = (wxMenu*)This->GetSubMenu();
rt.addRef(getRef((void *)Result,memenv), "wxMenu");
- break;
+ break;
}
-case wxMenuItem_IsCheckable: { // wxMenuItem::IsCheckable
+case wxMenuItem_IsCheckable: { // wxMenuItem::IsCheckable
wxMenuItem *This = (wxMenuItem *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
bool Result = This->IsCheckable();
rt.addBool(Result);
- break;
+ break;
}
-case wxMenuItem_IsChecked: { // wxMenuItem::IsChecked
+case wxMenuItem_IsChecked: { // wxMenuItem::IsChecked
wxMenuItem *This = (wxMenuItem *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
bool Result = This->IsChecked();
rt.addBool(Result);
- break;
+ break;
}
-case wxMenuItem_IsEnabled: { // wxMenuItem::IsEnabled
+case wxMenuItem_IsEnabled: { // wxMenuItem::IsEnabled
wxMenuItem *This = (wxMenuItem *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
bool Result = This->IsEnabled();
rt.addBool(Result);
- break;
+ break;
}
-case wxMenuItem_IsSeparator: { // wxMenuItem::IsSeparator
+case wxMenuItem_IsSeparator: { // wxMenuItem::IsSeparator
wxMenuItem *This = (wxMenuItem *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
bool Result = This->IsSeparator();
rt.addBool(Result);
- break;
+ break;
}
-case wxMenuItem_IsSubMenu: { // wxMenuItem::IsSubMenu
+case wxMenuItem_IsSubMenu: { // wxMenuItem::IsSubMenu
wxMenuItem *This = (wxMenuItem *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
bool Result = This->IsSubMenu();
rt.addBool(Result);
- break;
+ break;
}
-case wxMenuItem_SetBitmap: { // wxMenuItem::SetBitmap
+case wxMenuItem_SetBitmap: { // wxMenuItem::SetBitmap
wxMenuItem *This = (wxMenuItem *) getPtr(bp,memenv); bp += 4;
wxBitmap *bitmap = (wxBitmap *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
This->SetBitmap(*bitmap);
- break;
+ break;
}
-case wxMenuItem_SetHelp: { // wxMenuItem::SetHelp
+case wxMenuItem_SetHelp: { // wxMenuItem::SetHelp
wxMenuItem *This = (wxMenuItem *) getPtr(bp,memenv); bp += 4;
int * strLen = (int *) bp; bp += 4;
wxString str = wxString(bp, wxConvUTF8);
bp += *strLen+((8-((0+ *strLen) & 7)) & 7);
if(!This) throw wxe_badarg(0);
This->SetHelp(str);
- break;
+ break;
}
-case wxMenuItem_SetMenu: { // wxMenuItem::SetMenu
+case wxMenuItem_SetMenu: { // wxMenuItem::SetMenu
wxMenuItem *This = (wxMenuItem *) getPtr(bp,memenv); bp += 4;
wxMenu *menu = (wxMenu *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
This->SetMenu(menu);
- break;
+ break;
}
-case wxMenuItem_SetSubMenu: { // wxMenuItem::SetSubMenu
+case wxMenuItem_SetSubMenu: { // wxMenuItem::SetSubMenu
wxMenuItem *This = (wxMenuItem *) getPtr(bp,memenv); bp += 4;
wxMenu *menu = (wxMenu *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
This->SetSubMenu(menu);
- break;
+ break;
}
-case wxMenuItem_SetText: { // wxMenuItem::SetText
+case wxMenuItem_SetText: { // wxMenuItem::SetText
wxMenuItem *This = (wxMenuItem *) getPtr(bp,memenv); bp += 4;
int * strLen = (int *) bp; bp += 4;
wxString str = wxString(bp, wxConvUTF8);
bp += *strLen+((8-((0+ *strLen) & 7)) & 7);
if(!This) throw wxe_badarg(0);
This->SetText(str);
- break;
+ break;
}
-case wxToolBar_AddControl: { // wxToolBar::AddControl
+case wxToolBar_AddControl: { // wxToolBar::AddControl
wxToolBar *This = (wxToolBar *) getPtr(bp,memenv); bp += 4;
wxControl *control = (wxControl *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
wxToolBarToolBase * Result = (wxToolBarToolBase*)This->AddControl(control);
rt.addRef(getRef((void *)Result,memenv), "wx");
- break;
+ break;
}
-case wxToolBar_AddSeparator: { // wxToolBar::AddSeparator
+case wxToolBar_AddSeparator: { // wxToolBar::AddSeparator
wxToolBar *This = (wxToolBar *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
wxToolBarToolBase * Result = (wxToolBarToolBase*)This->AddSeparator();
rt.addRef(getRef((void *)Result,memenv), "wx");
- break;
+ break;
}
-case wxToolBar_AddTool_5: { // wxToolBar::AddTool
+case wxToolBar_AddTool_5: { // wxToolBar::AddTool
wxItemKind kind=wxITEM_NORMAL;
wxString shortHelp= wxEmptyString;
wxString longHelp= wxEmptyString;
@@ -8265,7 +8265,7 @@ case wxToolBar_AddTool_5: { // wxToolBar::AddTool
bp += *labelLen+((8-((4+ *labelLen) & 7)) & 7);
wxBitmap *bitmap = (wxBitmap *) getPtr(bp,memenv); bp += 4;
wxBitmap *bmpDisabled = (wxBitmap *) getPtr(bp,memenv); bp += 4;
- while( * (int*) bp) { switch (* (int*) bp) {
+ while( * (int*) bp) { switch (* (int*) bp) {
case 1: {bp += 4;
kind = *(wxItemKind *) bp; bp += 4;;
} break;
@@ -8282,13 +8282,13 @@ kind = *(wxItemKind *) bp; bp += 4;;
case 4: {bp += 4;
data = (wxObject *) getPtr(bp,memenv); bp += 4;
} break;
- }};
+ }};
if(!This) throw wxe_badarg(0);
wxToolBarToolBase * Result = (wxToolBarToolBase*)This->AddTool((int) *toolid,label,*bitmap,*bmpDisabled,(wxItemKind) kind,shortHelp,longHelp,data);
rt.addRef(getRef((void *)Result,memenv), "wx");
- break;
+ break;
}
-case wxToolBar_AddTool_4_0: { // wxToolBar::AddTool
+case wxToolBar_AddTool_4_0: { // wxToolBar::AddTool
wxString shortHelp= wxEmptyString;
wxItemKind kind=wxITEM_NORMAL;
wxToolBar *This = (wxToolBar *) getPtr(bp,memenv); bp += 4;
@@ -8298,7 +8298,7 @@ case wxToolBar_AddTool_4_0: { // wxToolBar::AddTool
bp += *labelLen+((8-((4+ *labelLen) & 7)) & 7);
wxBitmap *bitmap = (wxBitmap *) getPtr(bp,memenv); bp += 4;
bp += 4; /* Align */
- while( * (int*) bp) { switch (* (int*) bp) {
+ while( * (int*) bp) { switch (* (int*) bp) {
case 1: {bp += 4;
int * shortHelpLen = (int *) bp; bp += 4;
shortHelp = wxString(bp, wxConvUTF8);
@@ -8307,21 +8307,21 @@ case wxToolBar_AddTool_4_0: { // wxToolBar::AddTool
case 2: {bp += 4;
kind = *(wxItemKind *) bp; bp += 4;;
} break;
- }};
+ }};
if(!This) throw wxe_badarg(0);
wxToolBarToolBase * Result = (wxToolBarToolBase*)This->AddTool((int) *toolid,label,*bitmap,shortHelp,(wxItemKind) kind);
rt.addRef(getRef((void *)Result,memenv), "wx");
- break;
+ break;
}
-case wxToolBar_AddTool_1: { // wxToolBar::AddTool
+case wxToolBar_AddTool_1: { // wxToolBar::AddTool
wxToolBar *This = (wxToolBar *) getPtr(bp,memenv); bp += 4;
wxToolBarToolBase *tool = (wxToolBarToolBase *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
wxToolBarToolBase * Result = (wxToolBarToolBase*)This->AddTool(tool);
rt.addRef(getRef((void *)Result,memenv), "wx");
- break;
+ break;
}
-case wxToolBar_AddTool_4_1: { // wxToolBar::AddTool
+case wxToolBar_AddTool_4_1: { // wxToolBar::AddTool
bool toggle=false;
wxObject * clientData=NULL;
wxString shortHelpString= wxEmptyString;
@@ -8330,7 +8330,7 @@ case wxToolBar_AddTool_4_1: { // wxToolBar::AddTool
int * toolid = (int *) bp; bp += 4;
wxBitmap *bitmap = (wxBitmap *) getPtr(bp,memenv); bp += 4;
wxBitmap *bmpDisabled = (wxBitmap *) getPtr(bp,memenv); bp += 4;
- while( * (int*) bp) { switch (* (int*) bp) {
+ while( * (int*) bp) { switch (* (int*) bp) {
case 1: {bp += 4;
toggle = *(bool *) bp; bp += 4;
} break;
@@ -8347,20 +8347,20 @@ clientData = (wxObject *) getPtr(bp,memenv); bp += 4;
longHelpString = wxString(bp, wxConvUTF8);
bp += *longHelpStringLen+((8-((0+ *longHelpStringLen) & 7)) & 7);
} break;
- }};
+ }};
if(!This) throw wxe_badarg(0);
wxToolBarToolBase * Result = (wxToolBarToolBase*)This->AddTool((int) *toolid,*bitmap,*bmpDisabled,toggle,clientData,shortHelpString,longHelpString);
rt.addRef(getRef((void *)Result,memenv), "wx");
- break;
+ break;
}
-case wxToolBar_AddTool_3: { // wxToolBar::AddTool
+case wxToolBar_AddTool_3: { // wxToolBar::AddTool
wxString shortHelpString= wxEmptyString;
wxString longHelpString= wxEmptyString;
wxToolBar *This = (wxToolBar *) getPtr(bp,memenv); bp += 4;
int * toolid = (int *) bp; bp += 4;
wxBitmap *bitmap = (wxBitmap *) getPtr(bp,memenv); bp += 4;
bp += 4; /* Align */
- while( * (int*) bp) { switch (* (int*) bp) {
+ while( * (int*) bp) { switch (* (int*) bp) {
case 1: {bp += 4;
int * shortHelpStringLen = (int *) bp; bp += 4;
shortHelpString = wxString(bp, wxConvUTF8);
@@ -8371,13 +8371,13 @@ case wxToolBar_AddTool_3: { // wxToolBar::AddTool
longHelpString = wxString(bp, wxConvUTF8);
bp += *longHelpStringLen+((8-((0+ *longHelpStringLen) & 7)) & 7);
} break;
- }};
+ }};
if(!This) throw wxe_badarg(0);
wxToolBarToolBase * Result = (wxToolBarToolBase*)This->AddTool((int) *toolid,*bitmap,shortHelpString,longHelpString);
rt.addRef(getRef((void *)Result,memenv), "wx");
- break;
+ break;
}
-case wxToolBar_AddTool_6: { // wxToolBar::AddTool
+case wxToolBar_AddTool_6: { // wxToolBar::AddTool
wxCoord yPos=wxDefaultCoord;
wxObject * clientData=NULL;
wxString shortHelp= wxEmptyString;
@@ -8388,7 +8388,7 @@ case wxToolBar_AddTool_6: { // wxToolBar::AddTool
wxBitmap *bmpDisabled = (wxBitmap *) getPtr(bp,memenv); bp += 4;
bool * toggle = (bool *) bp; bp += 4;
int * xPos = (int *) bp; bp += 4;
- while( * (int*) bp) { switch (* (int*) bp) {
+ while( * (int*) bp) { switch (* (int*) bp) {
case 1: {bp += 4;
yPos = (wxCoord)*(int *) bp; bp += 4;
} break;
@@ -8405,13 +8405,13 @@ clientData = (wxObject *) getPtr(bp,memenv); bp += 4;
longHelp = wxString(bp, wxConvUTF8);
bp += *longHelpLen+((8-((0+ *longHelpLen) & 7)) & 7);
} break;
- }};
+ }};
if(!This) throw wxe_badarg(0);
wxToolBarToolBase * Result = (wxToolBarToolBase*)This->AddTool((int) *toolid,*bitmap,*bmpDisabled,(bool) *toggle,(wxCoord) *xPos,yPos,clientData,shortHelp,longHelp);
rt.addRef(getRef((void *)Result,memenv), "wx");
- break;
+ break;
}
-case wxToolBar_AddCheckTool: { // wxToolBar::AddCheckTool
+case wxToolBar_AddCheckTool: { // wxToolBar::AddCheckTool
const wxBitmap * bmpDisabled= &wxNullBitmap;
wxString shortHelp= wxEmptyString;
wxString longHelp= wxEmptyString;
@@ -8423,7 +8423,7 @@ case wxToolBar_AddCheckTool: { // wxToolBar::AddCheckTool
bp += *labelLen+((8-((4+ *labelLen) & 7)) & 7);
wxBitmap *bitmap = (wxBitmap *) getPtr(bp,memenv); bp += 4;
bp += 4; /* Align */
- while( * (int*) bp) { switch (* (int*) bp) {
+ while( * (int*) bp) { switch (* (int*) bp) {
case 1: {bp += 4;
bmpDisabled = (wxBitmap *) getPtr(bp,memenv); bp += 4;
} break;
@@ -8440,13 +8440,13 @@ bmpDisabled = (wxBitmap *) getPtr(bp,memenv); bp += 4;
case 4: {bp += 4;
data = (wxObject *) getPtr(bp,memenv); bp += 4;
} break;
- }};
+ }};
if(!This) throw wxe_badarg(0);
wxToolBarToolBase * Result = (wxToolBarToolBase*)This->AddCheckTool((int) *toolid,label,*bitmap,*bmpDisabled,shortHelp,longHelp,data);
rt.addRef(getRef((void *)Result,memenv), "wx");
- break;
+ break;
}
-case wxToolBar_AddRadioTool: { // wxToolBar::AddRadioTool
+case wxToolBar_AddRadioTool: { // wxToolBar::AddRadioTool
const wxBitmap * bmpDisabled= &wxNullBitmap;
wxString shortHelp= wxEmptyString;
wxString longHelp= wxEmptyString;
@@ -8458,7 +8458,7 @@ case wxToolBar_AddRadioTool: { // wxToolBar::AddRadioTool
bp += *labelLen+((8-((4+ *labelLen) & 7)) & 7);
wxBitmap *bitmap = (wxBitmap *) getPtr(bp,memenv); bp += 4;
bp += 4; /* Align */
- while( * (int*) bp) { switch (* (int*) bp) {
+ while( * (int*) bp) { switch (* (int*) bp) {
case 1: {bp += 4;
bmpDisabled = (wxBitmap *) getPtr(bp,memenv); bp += 4;
} break;
@@ -8475,154 +8475,154 @@ bmpDisabled = (wxBitmap *) getPtr(bp,memenv); bp += 4;
case 4: {bp += 4;
data = (wxObject *) getPtr(bp,memenv); bp += 4;
} break;
- }};
+ }};
if(!This) throw wxe_badarg(0);
wxToolBarToolBase * Result = (wxToolBarToolBase*)This->AddRadioTool((int) *toolid,label,*bitmap,*bmpDisabled,shortHelp,longHelp,data);
rt.addRef(getRef((void *)Result,memenv), "wx");
- break;
+ break;
}
-case wxToolBar_DeleteTool: { // wxToolBar::DeleteTool
+case wxToolBar_DeleteTool: { // wxToolBar::DeleteTool
wxToolBar *This = (wxToolBar *) getPtr(bp,memenv); bp += 4;
int * toolid = (int *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
bool Result = This->DeleteTool((int) *toolid);
rt.addBool(Result);
- break;
+ break;
}
-case wxToolBar_DeleteToolByPos: { // wxToolBar::DeleteToolByPos
+case wxToolBar_DeleteToolByPos: { // wxToolBar::DeleteToolByPos
wxToolBar *This = (wxToolBar *) getPtr(bp,memenv); bp += 4;
int * pos = (int *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
bool Result = This->DeleteToolByPos((size_t) *pos);
rt.addBool(Result);
- break;
+ break;
}
-case wxToolBar_EnableTool: { // wxToolBar::EnableTool
+case wxToolBar_EnableTool: { // wxToolBar::EnableTool
wxToolBar *This = (wxToolBar *) getPtr(bp,memenv); bp += 4;
int * toolid = (int *) bp; bp += 4;
bool * enable = (bool *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
This->EnableTool((int) *toolid,(bool) *enable);
- break;
+ break;
}
-case wxToolBar_FindById: { // wxToolBar::FindById
+case wxToolBar_FindById: { // wxToolBar::FindById
wxToolBar *This = (wxToolBar *) getPtr(bp,memenv); bp += 4;
int * toolid = (int *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
wxToolBarToolBase * Result = (wxToolBarToolBase*)This->FindById((int) *toolid);
rt.addRef(getRef((void *)Result,memenv), "wx");
- break;
+ break;
}
-case wxToolBar_FindControl: { // wxToolBar::FindControl
+case wxToolBar_FindControl: { // wxToolBar::FindControl
wxToolBar *This = (wxToolBar *) getPtr(bp,memenv); bp += 4;
int * toolid = (int *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
wxControl * Result = (wxControl*)This->FindControl((int) *toolid);
rt.addRef(getRef((void *)Result,memenv), "wxControl");
- break;
+ break;
}
-case wxToolBar_FindToolForPosition: { // wxToolBar::FindToolForPosition
+case wxToolBar_FindToolForPosition: { // wxToolBar::FindToolForPosition
wxToolBar *This = (wxToolBar *) getPtr(bp,memenv); bp += 4;
int * x = (int *) bp; bp += 4;
int * y = (int *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
wxToolBarToolBase * Result = (wxToolBarToolBase*)This->FindToolForPosition((wxCoord) *x,(wxCoord) *y);
rt.addRef(getRef((void *)Result,memenv), "wx");
- break;
+ break;
}
-case wxToolBar_GetToolSize: { // wxToolBar::GetToolSize
+case wxToolBar_GetToolSize: { // wxToolBar::GetToolSize
wxToolBar *This = (wxToolBar *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
wxSize Result = This->GetToolSize();
rt.add(Result);
- break;
+ break;
}
-case wxToolBar_GetToolBitmapSize: { // wxToolBar::GetToolBitmapSize
+case wxToolBar_GetToolBitmapSize: { // wxToolBar::GetToolBitmapSize
wxToolBar *This = (wxToolBar *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
wxSize Result = This->GetToolBitmapSize();
rt.add(Result);
- break;
+ break;
}
-case wxToolBar_GetMargins: { // wxToolBar::GetMargins
+case wxToolBar_GetMargins: { // wxToolBar::GetMargins
wxToolBar *This = (wxToolBar *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
wxSize Result = This->GetMargins();
rt.add(Result);
- break;
+ break;
}
-case wxToolBar_GetToolEnabled: { // wxToolBar::GetToolEnabled
+case wxToolBar_GetToolEnabled: { // wxToolBar::GetToolEnabled
wxToolBar *This = (wxToolBar *) getPtr(bp,memenv); bp += 4;
int * toolid = (int *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
bool Result = This->GetToolEnabled((int) *toolid);
rt.addBool(Result);
- break;
+ break;
}
-case wxToolBar_GetToolLongHelp: { // wxToolBar::GetToolLongHelp
+case wxToolBar_GetToolLongHelp: { // wxToolBar::GetToolLongHelp
wxToolBar *This = (wxToolBar *) getPtr(bp,memenv); bp += 4;
int * toolid = (int *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
wxString Result = This->GetToolLongHelp((int) *toolid);
rt.add(Result);
- break;
+ break;
}
-case wxToolBar_GetToolPacking: { // wxToolBar::GetToolPacking
+case wxToolBar_GetToolPacking: { // wxToolBar::GetToolPacking
wxToolBar *This = (wxToolBar *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
int Result = This->GetToolPacking();
rt.addInt(Result);
- break;
+ break;
}
-case wxToolBar_GetToolPos: { // wxToolBar::GetToolPos
+case wxToolBar_GetToolPos: { // wxToolBar::GetToolPos
wxToolBar *This = (wxToolBar *) getPtr(bp,memenv); bp += 4;
int * id = (int *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
int Result = This->GetToolPos((int) *id);
rt.addInt(Result);
- break;
+ break;
}
-case wxToolBar_GetToolSeparation: { // wxToolBar::GetToolSeparation
+case wxToolBar_GetToolSeparation: { // wxToolBar::GetToolSeparation
wxToolBar *This = (wxToolBar *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
int Result = This->GetToolSeparation();
rt.addInt(Result);
- break;
+ break;
}
-case wxToolBar_GetToolShortHelp: { // wxToolBar::GetToolShortHelp
+case wxToolBar_GetToolShortHelp: { // wxToolBar::GetToolShortHelp
wxToolBar *This = (wxToolBar *) getPtr(bp,memenv); bp += 4;
int * toolid = (int *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
wxString Result = This->GetToolShortHelp((int) *toolid);
rt.add(Result);
- break;
+ break;
}
-case wxToolBar_GetToolState: { // wxToolBar::GetToolState
+case wxToolBar_GetToolState: { // wxToolBar::GetToolState
wxToolBar *This = (wxToolBar *) getPtr(bp,memenv); bp += 4;
int * toolid = (int *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
bool Result = This->GetToolState((int) *toolid);
rt.addBool(Result);
- break;
+ break;
}
-case wxToolBar_InsertControl: { // wxToolBar::InsertControl
+case wxToolBar_InsertControl: { // wxToolBar::InsertControl
wxToolBar *This = (wxToolBar *) getPtr(bp,memenv); bp += 4;
int * pos = (int *) bp; bp += 4;
wxControl *control = (wxControl *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
wxToolBarToolBase * Result = (wxToolBarToolBase*)This->InsertControl((size_t) *pos,control);
rt.addRef(getRef((void *)Result,memenv), "wx");
- break;
+ break;
}
-case wxToolBar_InsertSeparator: { // wxToolBar::InsertSeparator
+case wxToolBar_InsertSeparator: { // wxToolBar::InsertSeparator
wxToolBar *This = (wxToolBar *) getPtr(bp,memenv); bp += 4;
int * pos = (int *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
wxToolBarToolBase * Result = (wxToolBarToolBase*)This->InsertSeparator((size_t) *pos);
rt.addRef(getRef((void *)Result,memenv), "wx");
- break;
+ break;
}
-case wxToolBar_InsertTool_5: { // wxToolBar::InsertTool
+case wxToolBar_InsertTool_5: { // wxToolBar::InsertTool
const wxBitmap * bmpDisabled= &wxNullBitmap;
wxItemKind kind=wxITEM_NORMAL;
wxString shortHelp= wxEmptyString;
@@ -8636,7 +8636,7 @@ case wxToolBar_InsertTool_5: { // wxToolBar::InsertTool
bp += *labelLen+((8-((0+ *labelLen) & 7)) & 7);
wxBitmap *bitmap = (wxBitmap *) getPtr(bp,memenv); bp += 4;
bp += 4; /* Align */
- while( * (int*) bp) { switch (* (int*) bp) {
+ while( * (int*) bp) { switch (* (int*) bp) {
case 1: {bp += 4;
bmpDisabled = (wxBitmap *) getPtr(bp,memenv); bp += 4;
} break;
@@ -8656,22 +8656,22 @@ kind = *(wxItemKind *) bp; bp += 4;;
case 5: {bp += 4;
clientData = (wxObject *) getPtr(bp,memenv); bp += 4;
} break;
- }};
+ }};
if(!This) throw wxe_badarg(0);
wxToolBarToolBase * Result = (wxToolBarToolBase*)This->InsertTool((size_t) *pos,(int) *toolid,label,*bitmap,*bmpDisabled,(wxItemKind) kind,shortHelp,longHelp,clientData);
rt.addRef(getRef((void *)Result,memenv), "wx");
- break;
+ break;
}
-case wxToolBar_InsertTool_2: { // wxToolBar::InsertTool
+case wxToolBar_InsertTool_2: { // wxToolBar::InsertTool
wxToolBar *This = (wxToolBar *) getPtr(bp,memenv); bp += 4;
int * pos = (int *) bp; bp += 4;
wxToolBarToolBase *tool = (wxToolBarToolBase *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
wxToolBarToolBase * Result = (wxToolBarToolBase*)This->InsertTool((size_t) *pos,tool);
rt.addRef(getRef((void *)Result,memenv), "wx");
- break;
+ break;
}
-case wxToolBar_InsertTool_4: { // wxToolBar::InsertTool
+case wxToolBar_InsertTool_4: { // wxToolBar::InsertTool
const wxBitmap * bmpDisabled= &wxNullBitmap;
bool toggle=false;
wxObject * clientData=NULL;
@@ -8681,7 +8681,7 @@ case wxToolBar_InsertTool_4: { // wxToolBar::InsertTool
int * pos = (int *) bp; bp += 4;
int * toolid = (int *) bp; bp += 4;
wxBitmap *bitmap = (wxBitmap *) getPtr(bp,memenv); bp += 4;
- while( * (int*) bp) { switch (* (int*) bp) {
+ while( * (int*) bp) { switch (* (int*) bp) {
case 1: {bp += 4;
bmpDisabled = (wxBitmap *) getPtr(bp,memenv); bp += 4;
} break;
@@ -8701,45 +8701,45 @@ clientData = (wxObject *) getPtr(bp,memenv); bp += 4;
longHelp = wxString(bp, wxConvUTF8);
bp += *longHelpLen+((8-((0+ *longHelpLen) & 7)) & 7);
} break;
- }};
+ }};
if(!This) throw wxe_badarg(0);
wxToolBarToolBase * Result = (wxToolBarToolBase*)This->InsertTool((size_t) *pos,(int) *toolid,*bitmap,*bmpDisabled,toggle,clientData,shortHelp,longHelp);
rt.addRef(getRef((void *)Result,memenv), "wx");
- break;
+ break;
}
-case wxToolBar_Realize: { // wxToolBar::Realize
+case wxToolBar_Realize: { // wxToolBar::Realize
wxToolBar *This = (wxToolBar *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
bool Result = This->Realize();
rt.addBool(Result);
- break;
+ break;
}
-case wxToolBar_RemoveTool: { // wxToolBar::RemoveTool
+case wxToolBar_RemoveTool: { // wxToolBar::RemoveTool
wxToolBar *This = (wxToolBar *) getPtr(bp,memenv); bp += 4;
int * toolid = (int *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
wxToolBarToolBase * Result = (wxToolBarToolBase*)This->RemoveTool((int) *toolid);
rt.addRef(getRef((void *)Result,memenv), "wx");
- break;
+ break;
}
-case wxToolBar_SetMargins: { // wxToolBar::SetMargins
+case wxToolBar_SetMargins: { // wxToolBar::SetMargins
wxToolBar *This = (wxToolBar *) getPtr(bp,memenv); bp += 4;
int * x = (int *) bp; bp += 4;
int * y = (int *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
This->SetMargins((int) *x,(int) *y);
- break;
+ break;
}
-case wxToolBar_SetToolBitmapSize: { // wxToolBar::SetToolBitmapSize
+case wxToolBar_SetToolBitmapSize: { // wxToolBar::SetToolBitmapSize
wxToolBar *This = (wxToolBar *) getPtr(bp,memenv); bp += 4;
int * sizeW = (int *) bp; bp += 4;
int * sizeH = (int *) bp; bp += 4;
wxSize size = wxSize(*sizeW,*sizeH);
if(!This) throw wxe_badarg(0);
This->SetToolBitmapSize(size);
- break;
+ break;
}
-case wxToolBar_SetToolLongHelp: { // wxToolBar::SetToolLongHelp
+case wxToolBar_SetToolLongHelp: { // wxToolBar::SetToolLongHelp
wxToolBar *This = (wxToolBar *) getPtr(bp,memenv); bp += 4;
int * toolid = (int *) bp; bp += 4;
int * helpStringLen = (int *) bp; bp += 4;
@@ -8747,16 +8747,16 @@ case wxToolBar_SetToolLongHelp: { // wxToolBar::SetToolLongHelp
bp += *helpStringLen+((8-((4+ *helpStringLen) & 7)) & 7);
if(!This) throw wxe_badarg(0);
This->SetToolLongHelp((int) *toolid,helpString);
- break;
+ break;
}
-case wxToolBar_SetToolPacking: { // wxToolBar::SetToolPacking
+case wxToolBar_SetToolPacking: { // wxToolBar::SetToolPacking
wxToolBar *This = (wxToolBar *) getPtr(bp,memenv); bp += 4;
int * packing = (int *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
This->SetToolPacking((int) *packing);
- break;
+ break;
}
-case wxToolBar_SetToolShortHelp: { // wxToolBar::SetToolShortHelp
+case wxToolBar_SetToolShortHelp: { // wxToolBar::SetToolShortHelp
wxToolBar *This = (wxToolBar *) getPtr(bp,memenv); bp += 4;
int * id = (int *) bp; bp += 4;
int * helpStringLen = (int *) bp; bp += 4;
@@ -8764,66 +8764,66 @@ case wxToolBar_SetToolShortHelp: { // wxToolBar::SetToolShortHelp
bp += *helpStringLen+((8-((4+ *helpStringLen) & 7)) & 7);
if(!This) throw wxe_badarg(0);
This->SetToolShortHelp((int) *id,helpString);
- break;
+ break;
}
-case wxToolBar_SetToolSeparation: { // wxToolBar::SetToolSeparation
+case wxToolBar_SetToolSeparation: { // wxToolBar::SetToolSeparation
wxToolBar *This = (wxToolBar *) getPtr(bp,memenv); bp += 4;
int * separation = (int *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
This->SetToolSeparation((int) *separation);
- break;
+ break;
}
-case wxToolBar_ToggleTool: { // wxToolBar::ToggleTool
+case wxToolBar_ToggleTool: { // wxToolBar::ToggleTool
wxToolBar *This = (wxToolBar *) getPtr(bp,memenv); bp += 4;
int * toolid = (int *) bp; bp += 4;
bool * toggle = (bool *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
This->ToggleTool((int) *toolid,(bool) *toggle);
- break;
+ break;
}
-case wxStatusBar_new_0: { // wxStatusBar::wxStatusBar
+case wxStatusBar_new_0: { // wxStatusBar::wxStatusBar
wxStatusBar * Result = new EwxStatusBar();
newPtr((void *) Result, 0, memenv);
rt.addRef(getRef((void *)Result,memenv), "wxStatusBar");
- break;
+ break;
}
-case wxStatusBar_new_2: { // wxStatusBar::wxStatusBar
+case wxStatusBar_new_2: { // wxStatusBar::wxStatusBar
wxWindowID winid=wxID_ANY;
long style=wxST_SIZEGRIP;
wxWindow *parent = (wxWindow *) getPtr(bp,memenv); bp += 4;
bp += 4; /* Align */
- while( * (int*) bp) { switch (* (int*) bp) {
+ while( * (int*) bp) { switch (* (int*) bp) {
case 1: {bp += 4;
winid = (wxWindowID)*(int *) bp; bp += 4;
} break;
case 2: {bp += 4;
style = (long)*(int *) bp; bp += 4;
} break;
- }};
+ }};
wxStatusBar * Result = new EwxStatusBar(parent,winid,style);
newPtr((void *) Result, 0, memenv);
rt.addRef(getRef((void *)Result,memenv), "wxStatusBar");
- break;
+ break;
}
-case wxStatusBar_Create: { // wxStatusBar::Create
+case wxStatusBar_Create: { // wxStatusBar::Create
wxWindowID winid=wxID_ANY;
long style=wxST_SIZEGRIP;
wxStatusBar *This = (wxStatusBar *) getPtr(bp,memenv); bp += 4;
wxWindow *parent = (wxWindow *) getPtr(bp,memenv); bp += 4;
- while( * (int*) bp) { switch (* (int*) bp) {
+ while( * (int*) bp) { switch (* (int*) bp) {
case 1: {bp += 4;
winid = (wxWindowID)*(int *) bp; bp += 4;
} break;
case 2: {bp += 4;
style = (long)*(int *) bp; bp += 4;
} break;
- }};
+ }};
if(!This) throw wxe_badarg(0);
bool Result = This->Create(parent,winid,style);
rt.addBool(Result);
- break;
+ break;
}
-case wxStatusBar_GetFieldRect: { // wxStatusBar::GetFieldRect
+case wxStatusBar_GetFieldRect: { // wxStatusBar::GetFieldRect
wxStatusBar *This = (wxStatusBar *) getPtr(bp,memenv); bp += 4;
int * i = (int *) bp; bp += 4;
int * rectX = (int *) bp; bp += 4;
@@ -8834,241 +8834,241 @@ case wxStatusBar_GetFieldRect: { // wxStatusBar::GetFieldRect
if(!This) throw wxe_badarg(0);
bool Result = This->GetFieldRect((int) *i,rect);
rt.addBool(Result);
- break;
+ break;
}
-case wxStatusBar_GetFieldsCount: { // wxStatusBar::GetFieldsCount
+case wxStatusBar_GetFieldsCount: { // wxStatusBar::GetFieldsCount
wxStatusBar *This = (wxStatusBar *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
int Result = This->GetFieldsCount();
rt.addInt(Result);
- break;
+ break;
}
-case wxStatusBar_GetStatusText: { // wxStatusBar::GetStatusText
+case wxStatusBar_GetStatusText: { // wxStatusBar::GetStatusText
int number=0;
wxStatusBar *This = (wxStatusBar *) getPtr(bp,memenv); bp += 4;
bp += 4; /* Align */
- while( * (int*) bp) { switch (* (int*) bp) {
+ while( * (int*) bp) { switch (* (int*) bp) {
case 1: {bp += 4;
number = (int)*(int *) bp; bp += 4;
} break;
- }};
+ }};
if(!This) throw wxe_badarg(0);
wxString Result = This->GetStatusText(number);
rt.add(Result);
- break;
+ break;
}
-case wxStatusBar_PopStatusText: { // wxStatusBar::PopStatusText
+case wxStatusBar_PopStatusText: { // wxStatusBar::PopStatusText
int number=0;
wxStatusBar *This = (wxStatusBar *) getPtr(bp,memenv); bp += 4;
bp += 4; /* Align */
- while( * (int*) bp) { switch (* (int*) bp) {
+ while( * (int*) bp) { switch (* (int*) bp) {
case 1: {bp += 4;
number = (int)*(int *) bp; bp += 4;
} break;
- }};
+ }};
if(!This) throw wxe_badarg(0);
This->PopStatusText(number);
- break;
+ break;
}
-case wxStatusBar_PushStatusText: { // wxStatusBar::PushStatusText
+case wxStatusBar_PushStatusText: { // wxStatusBar::PushStatusText
int number=0;
wxStatusBar *This = (wxStatusBar *) getPtr(bp,memenv); bp += 4;
int * textLen = (int *) bp; bp += 4;
wxString text = wxString(bp, wxConvUTF8);
bp += *textLen+((8-((0+ *textLen) & 7)) & 7);
- while( * (int*) bp) { switch (* (int*) bp) {
+ while( * (int*) bp) { switch (* (int*) bp) {
case 1: {bp += 4;
number = (int)*(int *) bp; bp += 4;
} break;
- }};
+ }};
if(!This) throw wxe_badarg(0);
This->PushStatusText(text,number);
- break;
+ break;
}
-case wxStatusBar_SetFieldsCount: { // wxStatusBar::SetFieldsCount
+case wxStatusBar_SetFieldsCount: { // wxStatusBar::SetFieldsCount
int * widthsLen = 0;
int * widths = (int *) NULL;
wxStatusBar *This = (wxStatusBar *) getPtr(bp,memenv); bp += 4;
int * number = (int *) bp; bp += 4;
- while( * (int*) bp) { switch (* (int*) bp) {
+ while( * (int*) bp) { switch (* (int*) bp) {
case 1: {bp += 4;
widthsLen = (int *) bp; bp += 4;
widths = (int *) bp; bp += *widthsLen*4+((0+ *widthsLen)%2 )*4;
} break;
- }};
+ }};
if(!This) throw wxe_badarg(0);
This->SetFieldsCount((int) *number,widths);
- break;
+ break;
}
-case wxStatusBar_SetMinHeight: { // wxStatusBar::SetMinHeight
+case wxStatusBar_SetMinHeight: { // wxStatusBar::SetMinHeight
wxStatusBar *This = (wxStatusBar *) getPtr(bp,memenv); bp += 4;
int * height = (int *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
This->SetMinHeight((int) *height);
- break;
+ break;
}
-case wxStatusBar_SetStatusText: { // wxStatusBar::SetStatusText
+case wxStatusBar_SetStatusText: { // wxStatusBar::SetStatusText
int number=0;
wxStatusBar *This = (wxStatusBar *) getPtr(bp,memenv); bp += 4;
int * textLen = (int *) bp; bp += 4;
wxString text = wxString(bp, wxConvUTF8);
bp += *textLen+((8-((0+ *textLen) & 7)) & 7);
- while( * (int*) bp) { switch (* (int*) bp) {
+ while( * (int*) bp) { switch (* (int*) bp) {
case 1: {bp += 4;
number = (int)*(int *) bp; bp += 4;
} break;
- }};
+ }};
if(!This) throw wxe_badarg(0);
This->SetStatusText(text,number);
- break;
+ break;
}
-case wxStatusBar_SetStatusWidths: { // wxStatusBar::SetStatusWidths
+case wxStatusBar_SetStatusWidths: { // wxStatusBar::SetStatusWidths
wxStatusBar *This = (wxStatusBar *) getPtr(bp,memenv); bp += 4;
int * widths_fieldLen = (int *) bp; bp += 4;
int * widths_field = (int *) bp; bp += *widths_fieldLen*4+((0+ *widths_fieldLen)%2 )*4;
if(!This) throw wxe_badarg(0);
This->SetStatusWidths(*widths_fieldLen,widths_field);
- break;
+ break;
}
-case wxStatusBar_SetStatusStyles: { // wxStatusBar::SetStatusStyles
+case wxStatusBar_SetStatusStyles: { // wxStatusBar::SetStatusStyles
wxStatusBar *This = (wxStatusBar *) getPtr(bp,memenv); bp += 4;
int * stylesLen = (int *) bp; bp += 4;
int * styles = (int *) bp; bp += *stylesLen*4+((0+ *stylesLen)%2 )*4;
if(!This) throw wxe_badarg(0);
This->SetStatusStyles(*stylesLen,styles);
- break;
+ break;
}
-case wxBitmap_new_0: { // wxBitmap::wxBitmap
+case wxBitmap_new_0: { // wxBitmap::wxBitmap
wxBitmap * Result = new EwxBitmap();
newPtr((void *) Result, 1, memenv);
rt.addRef(getRef((void *)Result,memenv), "wxBitmap");
- break;
+ break;
}
-case wxBitmap_new_3: { // wxBitmap::wxBitmap
+case wxBitmap_new_3: { // wxBitmap::wxBitmap
int depth=-1;
int * width = (int *) bp; bp += 4;
int * height = (int *) bp; bp += 4;
- while( * (int*) bp) { switch (* (int*) bp) {
+ while( * (int*) bp) { switch (* (int*) bp) {
case 1: {bp += 4;
depth = (int)*(int *) bp; bp += 4;
} break;
- }};
+ }};
wxBitmap * Result = new EwxBitmap((int) *width,(int) *height,depth);
newPtr((void *) Result, 1, memenv);
rt.addRef(getRef((void *)Result,memenv), "wxBitmap");
- break;
+ break;
}
-case wxBitmap_new_4: { // wxBitmap::wxBitmap
+case wxBitmap_new_4: { // wxBitmap::wxBitmap
int depth=1;
- const char * bits = (const char*) Ecmd.bin[0]->base;
+ const char * bits = (const char*) Ecmd.bin[0]->base;
int * width = (int *) bp; bp += 4;
int * height = (int *) bp; bp += 4;
- while( * (int*) bp) { switch (* (int*) bp) {
+ while( * (int*) bp) { switch (* (int*) bp) {
case 1: {bp += 4;
depth = (int)*(int *) bp; bp += 4;
} break;
- }};
+ }};
wxBitmap * Result = new EwxBitmap(bits,(int) *width,(int) *height,depth);
newPtr((void *) Result, 1, memenv);
rt.addRef(getRef((void *)Result,memenv), "wxBitmap");
- break;
+ break;
}
-case wxBitmap_new_2_0: { // wxBitmap::wxBitmap
+case wxBitmap_new_2_0: { // wxBitmap::wxBitmap
wxBitmapType type=wxBITMAP_TYPE_XPM;
int * filenameLen = (int *) bp; bp += 4;
wxString filename = wxString(bp, wxConvUTF8);
bp += *filenameLen+((8-((4+ *filenameLen) & 7)) & 7);
- while( * (int*) bp) { switch (* (int*) bp) {
+ while( * (int*) bp) { switch (* (int*) bp) {
case 1: {bp += 4;
type = *(wxBitmapType *) bp; bp += 4;;
} break;
- }};
+ }};
wxBitmap * Result = new EwxBitmap(filename,(wxBitmapType) type);
newPtr((void *) Result, 1, memenv);
rt.addRef(getRef((void *)Result,memenv), "wxBitmap");
- break;
+ break;
}
-case wxBitmap_new_2_1: { // wxBitmap::wxBitmap
+case wxBitmap_new_2_1: { // wxBitmap::wxBitmap
int depth=-1;
wxImage *image = (wxImage *) getPtr(bp,memenv); bp += 4;
bp += 4; /* Align */
- while( * (int*) bp) { switch (* (int*) bp) {
+ while( * (int*) bp) { switch (* (int*) bp) {
case 1: {bp += 4;
depth = (int)*(int *) bp; bp += 4;
} break;
- }};
+ }};
wxBitmap * Result = new EwxBitmap(*image,depth);
newPtr((void *) Result, 1, memenv);
rt.addRef(getRef((void *)Result,memenv), "wxBitmap");
- break;
+ break;
}
-case wxBitmap_ConvertToImage: { // wxBitmap::ConvertToImage
+case wxBitmap_ConvertToImage: { // wxBitmap::ConvertToImage
wxBitmap *This = (wxBitmap *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
wxImage * Result = new wxImage(This->ConvertToImage()); newPtr((void *) Result,3, memenv);;
rt.addRef(getRef((void *)Result,memenv), "wxImage");
- break;
+ break;
}
-case wxBitmap_CopyFromIcon: { // wxBitmap::CopyFromIcon
+case wxBitmap_CopyFromIcon: { // wxBitmap::CopyFromIcon
wxBitmap *This = (wxBitmap *) getPtr(bp,memenv); bp += 4;
wxIcon *icon = (wxIcon *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
bool Result = This->CopyFromIcon(*icon);
rt.addBool(Result);
- break;
+ break;
}
-case wxBitmap_Create: { // wxBitmap::Create
+case wxBitmap_Create: { // wxBitmap::Create
int depth=-1;
wxBitmap *This = (wxBitmap *) getPtr(bp,memenv); bp += 4;
int * width = (int *) bp; bp += 4;
int * height = (int *) bp; bp += 4;
bp += 4; /* Align */
- while( * (int*) bp) { switch (* (int*) bp) {
+ while( * (int*) bp) { switch (* (int*) bp) {
case 1: {bp += 4;
depth = (int)*(int *) bp; bp += 4;
} break;
- }};
+ }};
if(!This) throw wxe_badarg(0);
bool Result = This->Create((int) *width,(int) *height,depth);
rt.addBool(Result);
- break;
+ break;
}
-case wxBitmap_GetDepth: { // wxBitmap::GetDepth
+case wxBitmap_GetDepth: { // wxBitmap::GetDepth
wxBitmap *This = (wxBitmap *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
int Result = This->GetDepth();
rt.addInt(Result);
- break;
+ break;
}
-case wxBitmap_GetHeight: { // wxBitmap::GetHeight
+case wxBitmap_GetHeight: { // wxBitmap::GetHeight
wxBitmap *This = (wxBitmap *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
int Result = This->GetHeight();
rt.addInt(Result);
- break;
+ break;
}
-case wxBitmap_GetPalette: { // wxBitmap::GetPalette
+case wxBitmap_GetPalette: { // wxBitmap::GetPalette
wxBitmap *This = (wxBitmap *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
wxPalette * Result = (wxPalette*)This->GetPalette();
rt.addRef(getRef((void *)Result,memenv), "wxPalette");
- break;
+ break;
}
-case wxBitmap_GetMask: { // wxBitmap::GetMask
+case wxBitmap_GetMask: { // wxBitmap::GetMask
wxBitmap *This = (wxBitmap *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
wxMask * Result = (wxMask*)This->GetMask();
rt.addRef(getRef((void *)Result,memenv), "wxMask");
- break;
+ break;
}
-case wxBitmap_GetWidth: { // wxBitmap::GetWidth
+case wxBitmap_GetWidth: { // wxBitmap::GetWidth
wxBitmap *This = (wxBitmap *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
int Result = This->GetWidth();
rt.addInt(Result);
- break;
+ break;
}
-case wxBitmap_GetSubBitmap: { // wxBitmap::GetSubBitmap
+case wxBitmap_GetSubBitmap: { // wxBitmap::GetSubBitmap
wxBitmap *This = (wxBitmap *) getPtr(bp,memenv); bp += 4;
int * rectX = (int *) bp; bp += 4;
int * rectY = (int *) bp; bp += 4;
@@ -9078,32 +9078,32 @@ case wxBitmap_GetSubBitmap: { // wxBitmap::GetSubBitmap
if(!This) throw wxe_badarg(0);
wxBitmap * Result = new wxBitmap(This->GetSubBitmap(rect)); newPtr((void *) Result,3, memenv);;
rt.addRef(getRef((void *)Result,memenv), "wxBitmap");
- break;
+ break;
}
-case wxBitmap_LoadFile: { // wxBitmap::LoadFile
+case wxBitmap_LoadFile: { // wxBitmap::LoadFile
wxBitmapType type=wxBITMAP_TYPE_XPM;
wxBitmap *This = (wxBitmap *) getPtr(bp,memenv); bp += 4;
int * nameLen = (int *) bp; bp += 4;
wxString name = wxString(bp, wxConvUTF8);
bp += *nameLen+((8-((0+ *nameLen) & 7)) & 7);
- while( * (int*) bp) { switch (* (int*) bp) {
+ while( * (int*) bp) { switch (* (int*) bp) {
case 1: {bp += 4;
type = *(wxBitmapType *) bp; bp += 4;;
} break;
- }};
+ }};
if(!This) throw wxe_badarg(0);
bool Result = This->LoadFile(name,(wxBitmapType) type);
rt.addBool(Result);
- break;
+ break;
}
-case wxBitmap_Ok: { // wxBitmap::Ok
+case wxBitmap_Ok: { // wxBitmap::Ok
wxBitmap *This = (wxBitmap *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
bool Result = This->Ok();
rt.addBool(Result);
- break;
+ break;
}
-case wxBitmap_SaveFile: { // wxBitmap::SaveFile
+case wxBitmap_SaveFile: { // wxBitmap::SaveFile
const wxPalette * palette=(wxPalette *) NULL;
wxBitmap *This = (wxBitmap *) getPtr(bp,memenv); bp += 4;
int * nameLen = (int *) bp; bp += 4;
@@ -9111,65 +9111,65 @@ case wxBitmap_SaveFile: { // wxBitmap::SaveFile
bp += *nameLen+((8-((0+ *nameLen) & 7)) & 7);
wxBitmapType type = *(wxBitmapType *) bp; bp += 4;;
bp += 4; /* Align */
- while( * (int*) bp) { switch (* (int*) bp) {
+ while( * (int*) bp) { switch (* (int*) bp) {
case 1: {bp += 4;
palette = (wxPalette *) getPtr(bp,memenv); bp += 4;
} break;
- }};
+ }};
if(!This) throw wxe_badarg(0);
bool Result = This->SaveFile(name,(wxBitmapType) type,palette);
rt.addBool(Result);
- break;
+ break;
}
-case wxBitmap_SetDepth: { // wxBitmap::SetDepth
+case wxBitmap_SetDepth: { // wxBitmap::SetDepth
wxBitmap *This = (wxBitmap *) getPtr(bp,memenv); bp += 4;
int * depth = (int *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
This->SetDepth((int) *depth);
- break;
+ break;
}
-case wxBitmap_SetHeight: { // wxBitmap::SetHeight
+case wxBitmap_SetHeight: { // wxBitmap::SetHeight
wxBitmap *This = (wxBitmap *) getPtr(bp,memenv); bp += 4;
int * height = (int *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
This->SetHeight((int) *height);
- break;
+ break;
}
-case wxBitmap_SetMask: { // wxBitmap::SetMask
+case wxBitmap_SetMask: { // wxBitmap::SetMask
wxBitmap *This = (wxBitmap *) getPtr(bp,memenv); bp += 4;
wxMask *mask = (wxMask *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
This->SetMask(mask);
- break;
+ break;
}
-case wxBitmap_SetPalette: { // wxBitmap::SetPalette
+case wxBitmap_SetPalette: { // wxBitmap::SetPalette
wxBitmap *This = (wxBitmap *) getPtr(bp,memenv); bp += 4;
wxPalette *palette = (wxPalette *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
This->SetPalette(*palette);
- break;
+ break;
}
-case wxBitmap_SetWidth: { // wxBitmap::SetWidth
+case wxBitmap_SetWidth: { // wxBitmap::SetWidth
wxBitmap *This = (wxBitmap *) getPtr(bp,memenv); bp += 4;
int * width = (int *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
This->SetWidth((int) *width);
- break;
+ break;
}
-case wxIcon_new_0: { // wxIcon::wxIcon
+case wxIcon_new_0: { // wxIcon::wxIcon
wxIcon * Result = new EwxIcon();
newPtr((void *) Result, 1, memenv);
rt.addRef(getRef((void *)Result,memenv), "wxIcon");
- break;
+ break;
}
-case wxIcon_new_2: { // wxIcon::wxIcon
+case wxIcon_new_2: { // wxIcon::wxIcon
wxBitmapType type=wxBITMAP_TYPE_XPM;
int desiredWidth=-1;
int desiredHeight=-1;
int * filenameLen = (int *) bp; bp += 4;
wxString filename = wxString(bp, wxConvUTF8);
bp += *filenameLen+((8-((4+ *filenameLen) & 7)) & 7);
- while( * (int*) bp) { switch (* (int*) bp) {
+ while( * (int*) bp) { switch (* (int*) bp) {
case 1: {bp += 4;
type = *(wxBitmapType *) bp; bp += 4;;
} break;
@@ -9179,33 +9179,33 @@ type = *(wxBitmapType *) bp; bp += 4;;
case 3: {bp += 4;
desiredHeight = (int)*(int *) bp; bp += 4;
} break;
- }};
+ }};
wxIcon * Result = new EwxIcon(filename,(wxBitmapType) type,desiredWidth,desiredHeight);
newPtr((void *) Result, 1, memenv);
rt.addRef(getRef((void *)Result,memenv), "wxIcon");
- break;
+ break;
}
-case wxIcon_new_1: { // wxIcon::wxIcon
+case wxIcon_new_1: { // wxIcon::wxIcon
wxIconLocation *loc = (wxIconLocation *) getPtr(bp,memenv); bp += 4;
wxIcon * Result = new EwxIcon(*loc);
newPtr((void *) Result, 1, memenv);
rt.addRef(getRef((void *)Result,memenv), "wxIcon");
- break;
+ break;
}
-case wxIcon_CopyFromBitmap: { // wxIcon::CopyFromBitmap
+case wxIcon_CopyFromBitmap: { // wxIcon::CopyFromBitmap
wxIcon *This = (wxIcon *) getPtr(bp,memenv); bp += 4;
wxBitmap *bmp = (wxBitmap *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
This->CopyFromBitmap(*bmp);
- break;
+ break;
}
-case wxIconBundle_new_0: { // wxIconBundle::wxIconBundle
+case wxIconBundle_new_0: { // wxIconBundle::wxIconBundle
wxIconBundle * Result = new wxIconBundle();
newPtr((void *) Result, 61, memenv);
rt.addRef(getRef((void *)Result,memenv), "wxIconBundle");
- break;
+ break;
}
-case wxIconBundle_new_2: { // wxIconBundle::wxIconBundle
+case wxIconBundle_new_2: { // wxIconBundle::wxIconBundle
int * fileLen = (int *) bp; bp += 4;
wxString file = wxString(bp, wxConvUTF8);
bp += *fileLen+((8-((4+ *fileLen) & 7)) & 7);
@@ -9213,29 +9213,29 @@ case wxIconBundle_new_2: { // wxIconBundle::wxIconBundle
wxIconBundle * Result = new wxIconBundle(file,(long) *type);
newPtr((void *) Result, 61, memenv);
rt.addRef(getRef((void *)Result,memenv), "wxIconBundle");
- break;
+ break;
}
-case wxIconBundle_new_1_0: { // wxIconBundle::wxIconBundle
+case wxIconBundle_new_1_0: { // wxIconBundle::wxIconBundle
wxIcon *icon = (wxIcon *) getPtr(bp,memenv); bp += 4;
wxIconBundle * Result = new wxIconBundle(*icon);
newPtr((void *) Result, 61, memenv);
rt.addRef(getRef((void *)Result,memenv), "wxIconBundle");
- break;
+ break;
}
-case wxIconBundle_new_1_1: { // wxIconBundle::wxIconBundle
+case wxIconBundle_new_1_1: { // wxIconBundle::wxIconBundle
wxIconBundle * ic = (wxIconBundle *) getPtr(bp,memenv); bp += 4;
wxIconBundle * Result = new wxIconBundle(*ic);
newPtr((void *) Result, 61, memenv);
rt.addRef(getRef((void *)Result,memenv), "wxIconBundle");
- break;
+ break;
}
-case wxIconBundle_destruct: { // wxIconBundle::~wxIconBundle
+case wxIconBundle_destruct: { // wxIconBundle::~wxIconBundle
wxIconBundle *This = (wxIconBundle *) getPtr(bp,memenv); bp += 4;
if(This) { ((WxeApp *) wxTheApp)->clearPtr((void *) This);
delete This;}
- break;
+ break;
}
-case wxIconBundle_AddIcon_2: { // wxIconBundle::AddIcon
+case wxIconBundle_AddIcon_2: { // wxIconBundle::AddIcon
wxIconBundle *This = (wxIconBundle *) getPtr(bp,memenv); bp += 4;
int * fileLen = (int *) bp; bp += 4;
wxString file = wxString(bp, wxConvUTF8);
@@ -9243,16 +9243,16 @@ case wxIconBundle_AddIcon_2: { // wxIconBundle::AddIcon
int * type = (int *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
This->AddIcon(file,(long) *type);
- break;
+ break;
}
-case wxIconBundle_AddIcon_1: { // wxIconBundle::AddIcon
+case wxIconBundle_AddIcon_1: { // wxIconBundle::AddIcon
wxIconBundle *This = (wxIconBundle *) getPtr(bp,memenv); bp += 4;
wxIcon *icon = (wxIcon *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
This->AddIcon(*icon);
- break;
+ break;
}
-case wxIconBundle_GetIcon_1_1: { // wxIconBundle::GetIcon
+case wxIconBundle_GetIcon_1_1: { // wxIconBundle::GetIcon
wxIconBundle *This = (wxIconBundle *) getPtr(bp,memenv); bp += 4;
int * sizeW = (int *) bp; bp += 4;
int * sizeH = (int *) bp; bp += 4;
@@ -9260,75 +9260,75 @@ case wxIconBundle_GetIcon_1_1: { // wxIconBundle::GetIcon
if(!This) throw wxe_badarg(0);
const wxIcon * Result = &This->GetIcon(size);
rt.addRef(getRef((void *)Result,memenv), "wxIcon");
- break;
+ break;
}
-case wxIconBundle_GetIcon_1_0: { // wxIconBundle::GetIcon
+case wxIconBundle_GetIcon_1_0: { // wxIconBundle::GetIcon
wxCoord size=wxDefaultCoord;
wxIconBundle *This = (wxIconBundle *) getPtr(bp,memenv); bp += 4;
bp += 4; /* Align */
- while( * (int*) bp) { switch (* (int*) bp) {
+ while( * (int*) bp) { switch (* (int*) bp) {
case 1: {bp += 4;
size = (wxCoord)*(int *) bp; bp += 4;
} break;
- }};
+ }};
if(!This) throw wxe_badarg(0);
const wxIcon * Result = &This->GetIcon(size);
rt.addRef(getRef((void *)Result,memenv), "wxIcon");
- break;
+ break;
}
-case wxCursor_new_0: { // wxCursor::wxCursor
+case wxCursor_new_0: { // wxCursor::wxCursor
wxCursor * Result = new EwxCursor();
newPtr((void *) Result, 1, memenv);
rt.addRef(getRef((void *)Result,memenv), "wxCursor");
- break;
+ break;
}
-case wxCursor_new_1_0: { // wxCursor::wxCursor
+case wxCursor_new_1_0: { // wxCursor::wxCursor
int * cursorId = (int *) bp; bp += 4;
wxCursor * Result = new EwxCursor((int) *cursorId);
newPtr((void *) Result, 1, memenv);
rt.addRef(getRef((void *)Result,memenv), "wxCursor");
- break;
+ break;
}
-case wxCursor_new_1_1: { // wxCursor::wxCursor
+case wxCursor_new_1_1: { // wxCursor::wxCursor
wxImage *image = (wxImage *) getPtr(bp,memenv); bp += 4;
wxCursor * Result = new EwxCursor(*image);
newPtr((void *) Result, 1, memenv);
rt.addRef(getRef((void *)Result,memenv), "wxCursor");
- break;
+ break;
}
-case wxCursor_new_4: { // wxCursor::wxCursor
+case wxCursor_new_4: { // wxCursor::wxCursor
int hotSpotX=-1;
int hotSpotY=-1;
- const char * bits = (const char*) Ecmd.bin[0]->base;
+ const char * bits = (const char*) Ecmd.bin[0]->base;
int * width = (int *) bp; bp += 4;
int * height = (int *) bp; bp += 4;
- while( * (int*) bp) { switch (* (int*) bp) {
+ while( * (int*) bp) { switch (* (int*) bp) {
case 1: {bp += 4;
hotSpotX = (int)*(int *) bp; bp += 4;
} break;
case 2: {bp += 4;
hotSpotY = (int)*(int *) bp; bp += 4;
} break;
- }};
+ }};
wxCursor * Result = new EwxCursor(bits,(int) *width,(int) *height,hotSpotX,hotSpotY);
newPtr((void *) Result, 1, memenv);
rt.addRef(getRef((void *)Result,memenv), "wxCursor");
- break;
+ break;
}
-case wxCursor_Ok: { // wxCursor::Ok
+case wxCursor_Ok: { // wxCursor::Ok
wxCursor *This = (wxCursor *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
bool Result = This->Ok();
rt.addBool(Result);
- break;
+ break;
}
-case wxMask_new_0: { // wxMask::wxMask
+case wxMask_new_0: { // wxMask::wxMask
wxMask * Result = new EwxMask();
newPtr((void *) Result, 1, memenv);
rt.addRef(getRef((void *)Result,memenv), "wxMask");
- break;
+ break;
}
-case wxMask_new_2_1: { // wxMask::wxMask
+case wxMask_new_2_1: { // wxMask::wxMask
wxBitmap *bitmap = (wxBitmap *) getPtr(bp,memenv); bp += 4;
int * colourR = (int *) bp; bp += 4;
int * colourG = (int *) bp; bp += 4;
@@ -9338,24 +9338,24 @@ case wxMask_new_2_1: { // wxMask::wxMask
wxMask * Result = new EwxMask(*bitmap,colour);
newPtr((void *) Result, 1, memenv);
rt.addRef(getRef((void *)Result,memenv), "wxMask");
- break;
+ break;
}
-case wxMask_new_2_0: { // wxMask::wxMask
+case wxMask_new_2_0: { // wxMask::wxMask
wxBitmap *bitmap = (wxBitmap *) getPtr(bp,memenv); bp += 4;
int * paletteIndex = (int *) bp; bp += 4;
wxMask * Result = new EwxMask(*bitmap,(int) *paletteIndex);
newPtr((void *) Result, 1, memenv);
rt.addRef(getRef((void *)Result,memenv), "wxMask");
- break;
+ break;
}
-case wxMask_new_1: { // wxMask::wxMask
+case wxMask_new_1: { // wxMask::wxMask
wxBitmap *bitmap = (wxBitmap *) getPtr(bp,memenv); bp += 4;
wxMask * Result = new EwxMask(*bitmap);
newPtr((void *) Result, 1, memenv);
rt.addRef(getRef((void *)Result,memenv), "wxMask");
- break;
+ break;
}
-case wxMask_Create_2_1: { // wxMask::Create
+case wxMask_Create_2_1: { // wxMask::Create
wxMask *This = (wxMask *) getPtr(bp,memenv); bp += 4;
wxBitmap *bitmap = (wxBitmap *) getPtr(bp,memenv); bp += 4;
int * colourR = (int *) bp; bp += 4;
@@ -9366,98 +9366,98 @@ case wxMask_Create_2_1: { // wxMask::Create
if(!This) throw wxe_badarg(0);
bool Result = This->Create(*bitmap,colour);
rt.addBool(Result);
- break;
+ break;
}
-case wxMask_Create_2_0: { // wxMask::Create
+case wxMask_Create_2_0: { // wxMask::Create
wxMask *This = (wxMask *) getPtr(bp,memenv); bp += 4;
wxBitmap *bitmap = (wxBitmap *) getPtr(bp,memenv); bp += 4;
int * paletteIndex = (int *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
bool Result = This->Create(*bitmap,(int) *paletteIndex);
rt.addBool(Result);
- break;
+ break;
}
-case wxMask_Create_1: { // wxMask::Create
+case wxMask_Create_1: { // wxMask::Create
wxMask *This = (wxMask *) getPtr(bp,memenv); bp += 4;
wxBitmap *bitmap = (wxBitmap *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
bool Result = This->Create(*bitmap);
rt.addBool(Result);
- break;
+ break;
}
-case wxImage_new_0: { // wxImage::wxImage
+case wxImage_new_0: { // wxImage::wxImage
wxImage * Result = new EwxImage();
newPtr((void *) Result, 1, memenv);
rt.addRef(getRef((void *)Result,memenv), "wxImage");
- break;
+ break;
}
-case wxImage_new_3_0: { // wxImage::wxImage
+case wxImage_new_3_0: { // wxImage::wxImage
bool clear=true;
int * width = (int *) bp; bp += 4;
int * height = (int *) bp; bp += 4;
- while( * (int*) bp) { switch (* (int*) bp) {
+ while( * (int*) bp) { switch (* (int*) bp) {
case 1: {bp += 4;
clear = *(bool *) bp; bp += 4;
} break;
- }};
+ }};
wxImage * Result = new EwxImage((int) *width,(int) *height,clear);
newPtr((void *) Result, 1, memenv);
rt.addRef(getRef((void *)Result,memenv), "wxImage");
- break;
+ break;
}
-case wxImage_new_4: { // wxImage::wxImage
+case wxImage_new_4: { // wxImage::wxImage
bool static_data=false;
int * width = (int *) bp; bp += 4;
int * height = (int *) bp; bp += 4;
- unsigned char * data = (unsigned char*) Ecmd.bin[0]->base;
- while( * (int*) bp) { switch (* (int*) bp) {
+ unsigned char * data = (unsigned char*) Ecmd.bin[0]->base;
+ while( * (int*) bp) { switch (* (int*) bp) {
case 1: {bp += 4;
static_data = *(bool *) bp; bp += 4;
} break;
- }};
+ }};
if(!static_data) {data = (unsigned char *) malloc(Ecmd.bin[0]->size);memcpy(data,Ecmd.bin[0]->base,Ecmd.bin[0]->size);};
wxImage * Result = new EwxImage((int) *width,(int) *height,data,static_data);
newPtr((void *) Result, 1, memenv);
rt.addRef(getRef((void *)Result,memenv), "wxImage");
- break;
+ break;
}
-case wxImage_new_5: { // wxImage::wxImage
+case wxImage_new_5: { // wxImage::wxImage
bool static_data=false;
int * width = (int *) bp; bp += 4;
int * height = (int *) bp; bp += 4;
- unsigned char * data = (unsigned char*) Ecmd.bin[0]->base;
- unsigned char * alpha = (unsigned char*) Ecmd.bin[1]->base;
- while( * (int*) bp) { switch (* (int*) bp) {
+ unsigned char * data = (unsigned char*) Ecmd.bin[0]->base;
+ unsigned char * alpha = (unsigned char*) Ecmd.bin[1]->base;
+ while( * (int*) bp) { switch (* (int*) bp) {
case 1: {bp += 4;
static_data = *(bool *) bp; bp += 4;
} break;
- }};
+ }};
if(!static_data) { data = (unsigned char *) malloc(Ecmd.bin[0]->size); alpha = (unsigned char *) malloc(Ecmd.bin[1]->size); memcpy(data,Ecmd.bin[0]->base,Ecmd.bin[0]->size); memcpy(alpha,Ecmd.bin[1]->base,Ecmd.bin[1]->size);};
wxImage * Result = new EwxImage((int) *width,(int) *height,data,alpha,static_data);
newPtr((void *) Result, 1, memenv);
rt.addRef(getRef((void *)Result,memenv), "wxImage");
- break;
+ break;
}
-case wxImage_new_2: { // wxImage::wxImage
+case wxImage_new_2: { // wxImage::wxImage
long type=wxBITMAP_TYPE_ANY;
int index=-1;
int * nameLen = (int *) bp; bp += 4;
wxString name = wxString(bp, wxConvUTF8);
bp += *nameLen+((8-((4+ *nameLen) & 7)) & 7);
- while( * (int*) bp) { switch (* (int*) bp) {
+ while( * (int*) bp) { switch (* (int*) bp) {
case 1: {bp += 4;
type = (long)*(int *) bp; bp += 4;
} break;
case 2: {bp += 4;
index = (int)*(int *) bp; bp += 4;
} break;
- }};
+ }};
wxImage * Result = new EwxImage(name,type,index);
newPtr((void *) Result, 1, memenv);
rt.addRef(getRef((void *)Result,memenv), "wxImage");
- break;
+ break;
}
-case wxImage_new_3_1: { // wxImage::wxImage
+case wxImage_new_3_1: { // wxImage::wxImage
int index=-1;
int * nameLen = (int *) bp; bp += 4;
wxString name = wxString(bp, wxConvUTF8);
@@ -9465,61 +9465,61 @@ case wxImage_new_3_1: { // wxImage::wxImage
int * mimetypeLen = (int *) bp; bp += 4;
wxString mimetype = wxString(bp, wxConvUTF8);
bp += *mimetypeLen+((8-((4+ *mimetypeLen) & 7)) & 7);
- while( * (int*) bp) { switch (* (int*) bp) {
+ while( * (int*) bp) { switch (* (int*) bp) {
case 1: {bp += 4;
index = (int)*(int *) bp; bp += 4;
} break;
- }};
+ }};
wxImage * Result = new EwxImage(name,mimetype,index);
newPtr((void *) Result, 1, memenv);
rt.addRef(getRef((void *)Result,memenv), "wxImage");
- break;
+ break;
}
-case wxImage_Blur: { // wxImage::Blur
+case wxImage_Blur: { // wxImage::Blur
wxImage *This = (wxImage *) getPtr(bp,memenv); bp += 4;
int * radius = (int *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
wxImage * Result = new wxImage(This->Blur((int) *radius)); newPtr((void *) Result,3, memenv);;
rt.addRef(getRef((void *)Result,memenv), "wxImage");
- break;
+ break;
}
-case wxImage_BlurHorizontal: { // wxImage::BlurHorizontal
+case wxImage_BlurHorizontal: { // wxImage::BlurHorizontal
wxImage *This = (wxImage *) getPtr(bp,memenv); bp += 4;
int * radius = (int *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
wxImage * Result = new wxImage(This->BlurHorizontal((int) *radius)); newPtr((void *) Result,3, memenv);;
rt.addRef(getRef((void *)Result,memenv), "wxImage");
- break;
+ break;
}
-case wxImage_BlurVertical: { // wxImage::BlurVertical
+case wxImage_BlurVertical: { // wxImage::BlurVertical
wxImage *This = (wxImage *) getPtr(bp,memenv); bp += 4;
int * radius = (int *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
wxImage * Result = new wxImage(This->BlurVertical((int) *radius)); newPtr((void *) Result,3, memenv);;
rt.addRef(getRef((void *)Result,memenv), "wxImage");
- break;
+ break;
}
-case wxImage_ConvertAlphaToMask: { // wxImage::ConvertAlphaToMask
+case wxImage_ConvertAlphaToMask: { // wxImage::ConvertAlphaToMask
char threshold=wxIMAGE_ALPHA_THRESHOLD;
wxImage *This = (wxImage *) getPtr(bp,memenv); bp += 4;
bp += 4; /* Align */
- while( * (int*) bp) { switch (* (int*) bp) {
+ while( * (int*) bp) { switch (* (int*) bp) {
case 1: {bp += 4;
threshold = (char)*(unsigned int *) bp; bp += 4;
} break;
- }};
+ }};
if(!This) throw wxe_badarg(0);
bool Result = This->ConvertAlphaToMask(threshold);
rt.addBool(Result);
- break;
+ break;
}
-case wxImage_ConvertToGreyscale: { // wxImage::ConvertToGreyscale
+case wxImage_ConvertToGreyscale: { // wxImage::ConvertToGreyscale
double lr=0.299;
double lg=0.587;
double lb=0.114;
wxImage *This = (wxImage *) getPtr(bp,memenv); bp += 4;
bp += 4; /* Align */
- while( * (int*) bp) { switch (* (int*) bp) {
+ while( * (int*) bp) { switch (* (int*) bp) {
case 1: {bp += 4;
bp += 4; /* Align */
lr = * (double *) bp; bp += 8;
@@ -9532,13 +9532,13 @@ case wxImage_ConvertToGreyscale: { // wxImage::ConvertToGreyscale
bp += 4; /* Align */
lb = * (double *) bp; bp += 8;
} break;
- }};
+ }};
if(!This) throw wxe_badarg(0);
wxImage * Result = new wxImage(This->ConvertToGreyscale(lr,lg,lb)); newPtr((void *) Result,3, memenv);;
rt.addRef(getRef((void *)Result,memenv), "wxImage");
- break;
+ break;
}
-case wxImage_ConvertToMono: { // wxImage::ConvertToMono
+case wxImage_ConvertToMono: { // wxImage::ConvertToMono
wxImage *This = (wxImage *) getPtr(bp,memenv); bp += 4;
unsigned int * r = (unsigned int *) bp; bp += 4;
unsigned int * g = (unsigned int *) bp; bp += 4;
@@ -9546,75 +9546,75 @@ case wxImage_ConvertToMono: { // wxImage::ConvertToMono
if(!This) throw wxe_badarg(0);
wxImage * Result = new wxImage(This->ConvertToMono((char) *r,(char) *g,(char) *b)); newPtr((void *) Result,3, memenv);;
rt.addRef(getRef((void *)Result,memenv), "wxImage");
- break;
+ break;
}
-case wxImage_Copy: { // wxImage::Copy
+case wxImage_Copy: { // wxImage::Copy
wxImage *This = (wxImage *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
wxImage * Result = new wxImage(This->Copy()); newPtr((void *) Result,3, memenv);;
rt.addRef(getRef((void *)Result,memenv), "wxImage");
- break;
+ break;
}
-case wxImage_Create_3: { // wxImage::Create
+case wxImage_Create_3: { // wxImage::Create
bool clear=true;
wxImage *This = (wxImage *) getPtr(bp,memenv); bp += 4;
int * width = (int *) bp; bp += 4;
int * height = (int *) bp; bp += 4;
bp += 4; /* Align */
- while( * (int*) bp) { switch (* (int*) bp) {
+ while( * (int*) bp) { switch (* (int*) bp) {
case 1: {bp += 4;
clear = *(bool *) bp; bp += 4;
} break;
- }};
+ }};
if(!This) throw wxe_badarg(0);
bool Result = This->Create((int) *width,(int) *height,clear);
rt.addBool(Result);
- break;
+ break;
}
-case wxImage_Create_4: { // wxImage::Create
+case wxImage_Create_4: { // wxImage::Create
bool static_data=false;
wxImage *This = (wxImage *) getPtr(bp,memenv); bp += 4;
int * width = (int *) bp; bp += 4;
int * height = (int *) bp; bp += 4;
- unsigned char * data = (unsigned char*) Ecmd.bin[0]->base;
+ unsigned char * data = (unsigned char*) Ecmd.bin[0]->base;
bp += 4; /* Align */
- while( * (int*) bp) { switch (* (int*) bp) {
+ while( * (int*) bp) { switch (* (int*) bp) {
case 1: {bp += 4;
static_data = *(bool *) bp; bp += 4;
} break;
- }};
+ }};
if(!static_data) {data = (unsigned char *) malloc(Ecmd.bin[0]->size);memcpy(data,Ecmd.bin[0]->base,Ecmd.bin[0]->size);};
if(!This) throw wxe_badarg(0);
bool Result = This->Create((int) *width,(int) *height,data,static_data);
rt.addBool(Result);
- break;
+ break;
}
-case wxImage_Create_5: { // wxImage::Create
+case wxImage_Create_5: { // wxImage::Create
bool static_data=false;
wxImage *This = (wxImage *) getPtr(bp,memenv); bp += 4;
int * width = (int *) bp; bp += 4;
int * height = (int *) bp; bp += 4;
- unsigned char * data = (unsigned char*) Ecmd.bin[0]->base;
- unsigned char * alpha = (unsigned char*) Ecmd.bin[1]->base;
+ unsigned char * data = (unsigned char*) Ecmd.bin[0]->base;
+ unsigned char * alpha = (unsigned char*) Ecmd.bin[1]->base;
bp += 4; /* Align */
- while( * (int*) bp) { switch (* (int*) bp) {
+ while( * (int*) bp) { switch (* (int*) bp) {
case 1: {bp += 4;
static_data = *(bool *) bp; bp += 4;
} break;
- }};
+ }};
if(!static_data) { data = (unsigned char *) malloc(Ecmd.bin[0]->size); alpha = (unsigned char *) malloc(Ecmd.bin[1]->size); memcpy(data,Ecmd.bin[0]->base,Ecmd.bin[0]->size); memcpy(alpha,Ecmd.bin[1]->base,Ecmd.bin[1]->size);};
if(!This) throw wxe_badarg(0);
bool Result = This->Create((int) *width,(int) *height,data,alpha,static_data);
rt.addBool(Result);
- break;
+ break;
}
-case wxImage_Destroy: { // wxImage::Destroy
+case wxImage_Destroy: { // wxImage::Destroy
wxImage *This = (wxImage *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
This->Destroy();
- break;
+ break;
}
-case wxImage_FindFirstUnusedColour: { // wxImage::FindFirstUnusedColour
+case wxImage_FindFirstUnusedColour: { // wxImage::FindFirstUnusedColour
unsigned char r;
unsigned char g;
unsigned char b;
@@ -9623,7 +9623,7 @@ case wxImage_FindFirstUnusedColour: { // wxImage::FindFirstUnusedColour
char startB=0;
wxImage *This = (wxImage *) getPtr(bp,memenv); bp += 4;
bp += 4; /* Align */
- while( * (int*) bp) { switch (* (int*) bp) {
+ while( * (int*) bp) { switch (* (int*) bp) {
case 1: {bp += 4;
startR = (char)*(unsigned int *) bp; bp += 4;
} break;
@@ -9633,7 +9633,7 @@ case wxImage_FindFirstUnusedColour: { // wxImage::FindFirstUnusedColour
case 3: {bp += 4;
startB = (char)*(unsigned int *) bp; bp += 4;
} break;
- }};
+ }};
if(!This) throw wxe_badarg(0);
bool Result = This->FindFirstUnusedColour(&r,&g,&b,startR,startG,startB);
rt.addBool(Result);
@@ -9641,101 +9641,101 @@ case wxImage_FindFirstUnusedColour: { // wxImage::FindFirstUnusedColour
rt.addUint(g);
rt.addUint(b);
rt.addTupleCount(4);
- break;
+ break;
}
-case wxImage_GetImageExtWildcard: { // wxImage::GetImageExtWildcard
+case wxImage_GetImageExtWildcard: { // wxImage::GetImageExtWildcard
wxString Result = wxImage::GetImageExtWildcard();
rt.add(Result);
- break;
+ break;
}
-case wxImage_GetAlpha_2: { // wxImage::GetAlpha
+case wxImage_GetAlpha_2: { // wxImage::GetAlpha
wxImage *This = (wxImage *) getPtr(bp,memenv); bp += 4;
int * x = (int *) bp; bp += 4;
int * y = (int *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
char Result = This->GetAlpha((int) *x,(int) *y);
rt.addUint(Result);
- break;
+ break;
}
-case wxImage_GetAlpha_0: { // wxImage::GetAlpha
+case wxImage_GetAlpha_0: { // wxImage::GetAlpha
wxImage *This = (wxImage *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
char * Result = (char*)This->GetAlpha();
if(Result) {
rt.addBinary(Result, (This->GetWidth()*This->GetHeight()));
} else {rt.addAtom("null");};
- break;
+ break;
}
-case wxImage_GetBlue: { // wxImage::GetBlue
+case wxImage_GetBlue: { // wxImage::GetBlue
wxImage *This = (wxImage *) getPtr(bp,memenv); bp += 4;
int * x = (int *) bp; bp += 4;
int * y = (int *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
char Result = This->GetBlue((int) *x,(int) *y);
rt.addUint(Result);
- break;
+ break;
}
-case wxImage_GetData: { // wxImage::GetData
+case wxImage_GetData: { // wxImage::GetData
wxImage *This = (wxImage *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
char * Result = (char*)This->GetData();
if(Result) {
rt.addBinary(Result, (This->GetWidth()*This->GetHeight()*3));
} else {rt.addAtom("null");};
- break;
+ break;
}
-case wxImage_GetGreen: { // wxImage::GetGreen
+case wxImage_GetGreen: { // wxImage::GetGreen
wxImage *This = (wxImage *) getPtr(bp,memenv); bp += 4;
int * x = (int *) bp; bp += 4;
int * y = (int *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
char Result = This->GetGreen((int) *x,(int) *y);
rt.addUint(Result);
- break;
+ break;
}
-case wxImage_GetImageCount: { // wxImage::GetImageCount
+case wxImage_GetImageCount: { // wxImage::GetImageCount
long type=wxBITMAP_TYPE_ANY;
int * nameLen = (int *) bp; bp += 4;
wxString name = wxString(bp, wxConvUTF8);
bp += *nameLen+((8-((4+ *nameLen) & 7)) & 7);
- while( * (int*) bp) { switch (* (int*) bp) {
+ while( * (int*) bp) { switch (* (int*) bp) {
case 1: {bp += 4;
type = (long)*(int *) bp; bp += 4;
} break;
- }};
+ }};
int Result = wxImage::GetImageCount(name,type);
rt.addInt(Result);
- break;
+ break;
}
-case wxImage_GetHeight: { // wxImage::GetHeight
+case wxImage_GetHeight: { // wxImage::GetHeight
wxImage *This = (wxImage *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
int Result = This->GetHeight();
rt.addInt(Result);
- break;
+ break;
}
-case wxImage_GetMaskBlue: { // wxImage::GetMaskBlue
+case wxImage_GetMaskBlue: { // wxImage::GetMaskBlue
wxImage *This = (wxImage *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
char Result = This->GetMaskBlue();
rt.addUint(Result);
- break;
+ break;
}
-case wxImage_GetMaskGreen: { // wxImage::GetMaskGreen
+case wxImage_GetMaskGreen: { // wxImage::GetMaskGreen
wxImage *This = (wxImage *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
char Result = This->GetMaskGreen();
rt.addUint(Result);
- break;
+ break;
}
-case wxImage_GetMaskRed: { // wxImage::GetMaskRed
+case wxImage_GetMaskRed: { // wxImage::GetMaskRed
wxImage *This = (wxImage *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
char Result = This->GetMaskRed();
rt.addUint(Result);
- break;
+ break;
}
-case wxImage_GetOrFindMaskColour: { // wxImage::GetOrFindMaskColour
+case wxImage_GetOrFindMaskColour: { // wxImage::GetOrFindMaskColour
unsigned char r;
unsigned char g;
unsigned char b;
@@ -9747,25 +9747,25 @@ case wxImage_GetOrFindMaskColour: { // wxImage::GetOrFindMaskColour
rt.addUint(g);
rt.addUint(b);
rt.addTupleCount(4);
- break;
+ break;
}
-case wxImage_GetPalette: { // wxImage::GetPalette
+case wxImage_GetPalette: { // wxImage::GetPalette
wxImage *This = (wxImage *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
const wxPalette * Result = &This->GetPalette();
rt.addRef(getRef((void *)Result,memenv), "wxPalette");
- break;
+ break;
}
-case wxImage_GetRed: { // wxImage::GetRed
+case wxImage_GetRed: { // wxImage::GetRed
wxImage *This = (wxImage *) getPtr(bp,memenv); bp += 4;
int * x = (int *) bp; bp += 4;
int * y = (int *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
char Result = This->GetRed((int) *x,(int) *y);
rt.addUint(Result);
- break;
+ break;
}
-case wxImage_GetSubImage: { // wxImage::GetSubImage
+case wxImage_GetSubImage: { // wxImage::GetSubImage
wxImage *This = (wxImage *) getPtr(bp,memenv); bp += 4;
int * rectX = (int *) bp; bp += 4;
int * rectY = (int *) bp; bp += 4;
@@ -9775,30 +9775,30 @@ case wxImage_GetSubImage: { // wxImage::GetSubImage
if(!This) throw wxe_badarg(0);
wxImage * Result = new wxImage(This->GetSubImage(rect)); newPtr((void *) Result,3, memenv);;
rt.addRef(getRef((void *)Result,memenv), "wxImage");
- break;
+ break;
}
-case wxImage_GetWidth: { // wxImage::GetWidth
+case wxImage_GetWidth: { // wxImage::GetWidth
wxImage *This = (wxImage *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
int Result = This->GetWidth();
rt.addInt(Result);
- break;
+ break;
}
-case wxImage_HasAlpha: { // wxImage::HasAlpha
+case wxImage_HasAlpha: { // wxImage::HasAlpha
wxImage *This = (wxImage *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
bool Result = This->HasAlpha();
rt.addBool(Result);
- break;
+ break;
}
-case wxImage_HasMask: { // wxImage::HasMask
+case wxImage_HasMask: { // wxImage::HasMask
wxImage *This = (wxImage *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
bool Result = This->HasMask();
rt.addBool(Result);
- break;
+ break;
}
-case wxImage_GetOption: { // wxImage::GetOption
+case wxImage_GetOption: { // wxImage::GetOption
wxImage *This = (wxImage *) getPtr(bp,memenv); bp += 4;
int * nameLen = (int *) bp; bp += 4;
wxString name = wxString(bp, wxConvUTF8);
@@ -9806,9 +9806,9 @@ case wxImage_GetOption: { // wxImage::GetOption
if(!This) throw wxe_badarg(0);
wxString Result = This->GetOption(name);
rt.add(Result);
- break;
+ break;
}
-case wxImage_GetOptionInt: { // wxImage::GetOptionInt
+case wxImage_GetOptionInt: { // wxImage::GetOptionInt
wxImage *This = (wxImage *) getPtr(bp,memenv); bp += 4;
int * nameLen = (int *) bp; bp += 4;
wxString name = wxString(bp, wxConvUTF8);
@@ -9816,9 +9816,9 @@ case wxImage_GetOptionInt: { // wxImage::GetOptionInt
if(!This) throw wxe_badarg(0);
int Result = This->GetOptionInt(name);
rt.addInt(Result);
- break;
+ break;
}
-case wxImage_HasOption: { // wxImage::HasOption
+case wxImage_HasOption: { // wxImage::HasOption
wxImage *This = (wxImage *) getPtr(bp,memenv); bp += 4;
int * nameLen = (int *) bp; bp += 4;
wxString name = wxString(bp, wxConvUTF8);
@@ -9826,55 +9826,55 @@ case wxImage_HasOption: { // wxImage::HasOption
if(!This) throw wxe_badarg(0);
bool Result = This->HasOption(name);
rt.addBool(Result);
- break;
+ break;
}
-case wxImage_InitAlpha: { // wxImage::InitAlpha
+case wxImage_InitAlpha: { // wxImage::InitAlpha
wxImage *This = (wxImage *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
This->InitAlpha();
- break;
+ break;
}
-case wxImage_InitStandardHandlers: { // wxImage::InitStandardHandlers
+case wxImage_InitStandardHandlers: { // wxImage::InitStandardHandlers
wxImage::InitStandardHandlers();
- break;
+ break;
}
-case wxImage_IsTransparent: { // wxImage::IsTransparent
+case wxImage_IsTransparent: { // wxImage::IsTransparent
char threshold=wxIMAGE_ALPHA_THRESHOLD;
wxImage *This = (wxImage *) getPtr(bp,memenv); bp += 4;
int * x = (int *) bp; bp += 4;
int * y = (int *) bp; bp += 4;
bp += 4; /* Align */
- while( * (int*) bp) { switch (* (int*) bp) {
+ while( * (int*) bp) { switch (* (int*) bp) {
case 1: {bp += 4;
threshold = (char)*(unsigned int *) bp; bp += 4;
} break;
- }};
+ }};
if(!This) throw wxe_badarg(0);
bool Result = This->IsTransparent((int) *x,(int) *y,threshold);
rt.addBool(Result);
- break;
+ break;
}
-case wxImage_LoadFile_2: { // wxImage::LoadFile
+case wxImage_LoadFile_2: { // wxImage::LoadFile
long type=wxBITMAP_TYPE_ANY;
int index=-1;
wxImage *This = (wxImage *) getPtr(bp,memenv); bp += 4;
int * nameLen = (int *) bp; bp += 4;
wxString name = wxString(bp, wxConvUTF8);
bp += *nameLen+((8-((0+ *nameLen) & 7)) & 7);
- while( * (int*) bp) { switch (* (int*) bp) {
+ while( * (int*) bp) { switch (* (int*) bp) {
case 1: {bp += 4;
type = (long)*(int *) bp; bp += 4;
} break;
case 2: {bp += 4;
index = (int)*(int *) bp; bp += 4;
} break;
- }};
+ }};
if(!This) throw wxe_badarg(0);
bool Result = This->LoadFile(name,type,index);
rt.addBool(Result);
- break;
+ break;
}
-case wxImage_LoadFile_3: { // wxImage::LoadFile
+case wxImage_LoadFile_3: { // wxImage::LoadFile
int index=-1;
wxImage *This = (wxImage *) getPtr(bp,memenv); bp += 4;
int * nameLen = (int *) bp; bp += 4;
@@ -9883,46 +9883,46 @@ case wxImage_LoadFile_3: { // wxImage::LoadFile
int * mimetypeLen = (int *) bp; bp += 4;
wxString mimetype = wxString(bp, wxConvUTF8);
bp += *mimetypeLen+((8-((4+ *mimetypeLen) & 7)) & 7);
- while( * (int*) bp) { switch (* (int*) bp) {
+ while( * (int*) bp) { switch (* (int*) bp) {
case 1: {bp += 4;
index = (int)*(int *) bp; bp += 4;
} break;
- }};
+ }};
if(!This) throw wxe_badarg(0);
bool Result = This->LoadFile(name,mimetype,index);
rt.addBool(Result);
- break;
+ break;
}
-case wxImage_Ok: { // wxImage::Ok
+case wxImage_Ok: { // wxImage::Ok
wxImage *This = (wxImage *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
bool Result = This->Ok();
rt.addBool(Result);
- break;
+ break;
}
-case wxImage_RemoveHandler: { // wxImage::RemoveHandler
+case wxImage_RemoveHandler: { // wxImage::RemoveHandler
int * nameLen = (int *) bp; bp += 4;
wxString name = wxString(bp, wxConvUTF8);
bp += *nameLen+((8-((4+ *nameLen) & 7)) & 7);
bool Result = wxImage::RemoveHandler(name);
rt.addBool(Result);
- break;
+ break;
}
-case wxImage_Mirror: { // wxImage::Mirror
+case wxImage_Mirror: { // wxImage::Mirror
bool horizontally=true;
wxImage *This = (wxImage *) getPtr(bp,memenv); bp += 4;
bp += 4; /* Align */
- while( * (int*) bp) { switch (* (int*) bp) {
+ while( * (int*) bp) { switch (* (int*) bp) {
case 1: {bp += 4;
horizontally = *(bool *) bp; bp += 4;
} break;
- }};
+ }};
if(!This) throw wxe_badarg(0);
wxImage * Result = new wxImage(This->Mirror(horizontally)); newPtr((void *) Result,3, memenv);;
rt.addRef(getRef((void *)Result,memenv), "wxImage");
- break;
+ break;
}
-case wxImage_Replace: { // wxImage::Replace
+case wxImage_Replace: { // wxImage::Replace
wxImage *This = (wxImage *) getPtr(bp,memenv); bp += 4;
unsigned int * r1 = (unsigned int *) bp; bp += 4;
unsigned int * g1 = (unsigned int *) bp; bp += 4;
@@ -9932,25 +9932,25 @@ case wxImage_Replace: { // wxImage::Replace
unsigned int * b2 = (unsigned int *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
This->Replace((char) *r1,(char) *g1,(char) *b1,(char) *r2,(char) *g2,(char) *b2);
- break;
+ break;
}
-case wxImage_Rescale: { // wxImage::Rescale
+case wxImage_Rescale: { // wxImage::Rescale
int quality=wxIMAGE_QUALITY_NORMAL;
wxImage *This = (wxImage *) getPtr(bp,memenv); bp += 4;
int * width = (int *) bp; bp += 4;
int * height = (int *) bp; bp += 4;
bp += 4; /* Align */
- while( * (int*) bp) { switch (* (int*) bp) {
+ while( * (int*) bp) { switch (* (int*) bp) {
case 1: {bp += 4;
quality = (int)*(int *) bp; bp += 4;
} break;
- }};
+ }};
if(!This) throw wxe_badarg(0);
wxImage * Result = &This->Rescale((int) *width,(int) *height,quality);
rt.addRef(getRef((void *)Result,memenv), "wxImage");
- break;
+ break;
}
-case wxImage_Resize: { // wxImage::Resize
+case wxImage_Resize: { // wxImage::Resize
int r=-1;
int g=-1;
int b=-1;
@@ -9962,7 +9962,7 @@ case wxImage_Resize: { // wxImage::Resize
int * posY = (int *) bp; bp += 4;
wxPoint pos = wxPoint(*posX,*posY);
bp += 4; /* Align */
- while( * (int*) bp) { switch (* (int*) bp) {
+ while( * (int*) bp) { switch (* (int*) bp) {
case 1: {bp += 4;
r = (int)*(int *) bp; bp += 4;
} break;
@@ -9972,13 +9972,13 @@ case wxImage_Resize: { // wxImage::Resize
case 3: {bp += 4;
b = (int)*(int *) bp; bp += 4;
} break;
- }};
+ }};
if(!This) throw wxe_badarg(0);
wxImage * Result = &This->Resize(size,pos,r,g,b);
rt.addRef(getRef((void *)Result,memenv), "wxImage");
- break;
+ break;
}
-case wxImage_Rotate: { // wxImage::Rotate
+case wxImage_Rotate: { // wxImage::Rotate
bool interpolating=true;
wxPoint *offset_after_rotation=(wxPoint *) NULL; wxPoint offset_after_rotationTmp;
wxImage *This = (wxImage *) getPtr(bp,memenv); bp += 4;
@@ -9987,7 +9987,7 @@ case wxImage_Rotate: { // wxImage::Rotate
int * centre_of_rotationX = (int *) bp; bp += 4;
int * centre_of_rotationY = (int *) bp; bp += 4;
wxPoint centre_of_rotation = wxPoint(*centre_of_rotationX,*centre_of_rotationY);
- while( * (int*) bp) { switch (* (int*) bp) {
+ while( * (int*) bp) { switch (* (int*) bp) {
case 1: {bp += 4;
interpolating = *(bool *) bp; bp += 4;
} break;
@@ -9997,35 +9997,35 @@ case wxImage_Rotate: { // wxImage::Rotate
offset_after_rotationTmp = wxPoint(*offset_after_rotationX,*offset_after_rotationY); offset_after_rotation = & offset_after_rotationTmp;
bp += 4; /* Align */
} break;
- }};
+ }};
if(!This) throw wxe_badarg(0);
wxImage * Result = new wxImage(This->Rotate((double) *angle,centre_of_rotation,interpolating,offset_after_rotation)); newPtr((void *) Result,3, memenv);;
rt.addRef(getRef((void *)Result,memenv), "wxImage");
- break;
+ break;
}
-case wxImage_RotateHue: { // wxImage::RotateHue
+case wxImage_RotateHue: { // wxImage::RotateHue
wxImage *This = (wxImage *) getPtr(bp,memenv); bp += 4;
bp += 4; /* Align */
double * angle = (double *) bp; bp += 8;
if(!This) throw wxe_badarg(0);
This->RotateHue((double) *angle);
- break;
+ break;
}
-case wxImage_Rotate90: { // wxImage::Rotate90
+case wxImage_Rotate90: { // wxImage::Rotate90
bool clockwise=true;
wxImage *This = (wxImage *) getPtr(bp,memenv); bp += 4;
bp += 4; /* Align */
- while( * (int*) bp) { switch (* (int*) bp) {
+ while( * (int*) bp) { switch (* (int*) bp) {
case 1: {bp += 4;
clockwise = *(bool *) bp; bp += 4;
} break;
- }};
+ }};
if(!This) throw wxe_badarg(0);
wxImage * Result = new wxImage(This->Rotate90(clockwise)); newPtr((void *) Result,3, memenv);;
rt.addRef(getRef((void *)Result,memenv), "wxImage");
- break;
+ break;
}
-case wxImage_SaveFile_1: { // wxImage::SaveFile
+case wxImage_SaveFile_1: { // wxImage::SaveFile
wxImage *This = (wxImage *) getPtr(bp,memenv); bp += 4;
int * nameLen = (int *) bp; bp += 4;
wxString name = wxString(bp, wxConvUTF8);
@@ -10033,9 +10033,9 @@ case wxImage_SaveFile_1: { // wxImage::SaveFile
if(!This) throw wxe_badarg(0);
bool Result = This->SaveFile(name);
rt.addBool(Result);
- break;
+ break;
}
-case wxImage_SaveFile_2_0: { // wxImage::SaveFile
+case wxImage_SaveFile_2_0: { // wxImage::SaveFile
wxImage *This = (wxImage *) getPtr(bp,memenv); bp += 4;
int * nameLen = (int *) bp; bp += 4;
wxString name = wxString(bp, wxConvUTF8);
@@ -10044,9 +10044,9 @@ case wxImage_SaveFile_2_0: { // wxImage::SaveFile
if(!This) throw wxe_badarg(0);
bool Result = This->SaveFile(name,(int) *type);
rt.addBool(Result);
- break;
+ break;
}
-case wxImage_SaveFile_2_1: { // wxImage::SaveFile
+case wxImage_SaveFile_2_1: { // wxImage::SaveFile
wxImage *This = (wxImage *) getPtr(bp,memenv); bp += 4;
int * nameLen = (int *) bp; bp += 4;
wxString name = wxString(bp, wxConvUTF8);
@@ -10057,25 +10057,25 @@ case wxImage_SaveFile_2_1: { // wxImage::SaveFile
if(!This) throw wxe_badarg(0);
bool Result = This->SaveFile(name,mimetype);
rt.addBool(Result);
- break;
+ break;
}
-case wxImage_Scale: { // wxImage::Scale
+case wxImage_Scale: { // wxImage::Scale
int quality=wxIMAGE_QUALITY_NORMAL;
wxImage *This = (wxImage *) getPtr(bp,memenv); bp += 4;
int * width = (int *) bp; bp += 4;
int * height = (int *) bp; bp += 4;
bp += 4; /* Align */
- while( * (int*) bp) { switch (* (int*) bp) {
+ while( * (int*) bp) { switch (* (int*) bp) {
case 1: {bp += 4;
quality = (int)*(int *) bp; bp += 4;
} break;
- }};
+ }};
if(!This) throw wxe_badarg(0);
wxImage * Result = new wxImage(This->Scale((int) *width,(int) *height,quality)); newPtr((void *) Result,3, memenv);;
rt.addRef(getRef((void *)Result,memenv), "wxImage");
- break;
+ break;
}
-case wxImage_Size: { // wxImage::Size
+case wxImage_Size: { // wxImage::Size
int r=-1;
int g=-1;
int b=-1;
@@ -10087,7 +10087,7 @@ case wxImage_Size: { // wxImage::Size
int * posY = (int *) bp; bp += 4;
wxPoint pos = wxPoint(*posX,*posY);
bp += 4; /* Align */
- while( * (int*) bp) { switch (* (int*) bp) {
+ while( * (int*) bp) { switch (* (int*) bp) {
case 1: {bp += 4;
r = (int)*(int *) bp; bp += 4;
} break;
@@ -10097,91 +10097,91 @@ case wxImage_Size: { // wxImage::Size
case 3: {bp += 4;
b = (int)*(int *) bp; bp += 4;
} break;
- }};
+ }};
if(!This) throw wxe_badarg(0);
wxImage * Result = new wxImage(This->Size(size,pos,r,g,b)); newPtr((void *) Result,3, memenv);;
rt.addRef(getRef((void *)Result,memenv), "wxImage");
- break;
+ break;
}
-case wxImage_SetAlpha_3: { // wxImage::SetAlpha
+case wxImage_SetAlpha_3: { // wxImage::SetAlpha
wxImage *This = (wxImage *) getPtr(bp,memenv); bp += 4;
int * x = (int *) bp; bp += 4;
int * y = (int *) bp; bp += 4;
unsigned int * alpha = (unsigned int *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
This->SetAlpha((int) *x,(int) *y,(char) *alpha);
- break;
+ break;
}
-case wxImage_SetAlpha_2: { // wxImage::SetAlpha
+case wxImage_SetAlpha_2: { // wxImage::SetAlpha
bool static_data=false;
wxImage *This = (wxImage *) getPtr(bp,memenv); bp += 4;
- unsigned char * alpha = (unsigned char*) Ecmd.bin[0]->base;
+ unsigned char * alpha = (unsigned char*) Ecmd.bin[0]->base;
bp += 4; /* Align */
- while( * (int*) bp) { switch (* (int*) bp) {
+ while( * (int*) bp) { switch (* (int*) bp) {
case 1: {bp += 4;
static_data = *(bool *) bp; bp += 4;
} break;
- }};
+ }};
if(!static_data) {alpha = (unsigned char *) malloc(Ecmd.bin[0]->size);memcpy(alpha,Ecmd.bin[0]->base,Ecmd.bin[0]->size);};
if(!This) throw wxe_badarg(0);
This->SetAlpha(alpha,static_data);
- break;
+ break;
}
-case wxImage_SetData_2: { // wxImage::SetData
+case wxImage_SetData_2: { // wxImage::SetData
bool static_data=false;
wxImage *This = (wxImage *) getPtr(bp,memenv); bp += 4;
- unsigned char * data = (unsigned char*) Ecmd.bin[0]->base;
+ unsigned char * data = (unsigned char*) Ecmd.bin[0]->base;
bp += 4; /* Align */
- while( * (int*) bp) { switch (* (int*) bp) {
+ while( * (int*) bp) { switch (* (int*) bp) {
case 1: {bp += 4;
static_data = *(bool *) bp; bp += 4;
} break;
- }};
+ }};
if(!static_data) {data = (unsigned char *) malloc(Ecmd.bin[0]->size);memcpy(data,Ecmd.bin[0]->base,Ecmd.bin[0]->size);};
if(!This) throw wxe_badarg(0);
This->SetData(data,static_data);
- break;
+ break;
}
-case wxImage_SetData_4: { // wxImage::SetData
+case wxImage_SetData_4: { // wxImage::SetData
bool static_data=false;
wxImage *This = (wxImage *) getPtr(bp,memenv); bp += 4;
- unsigned char * data = (unsigned char*) Ecmd.bin[0]->base;
+ unsigned char * data = (unsigned char*) Ecmd.bin[0]->base;
int * new_width = (int *) bp; bp += 4;
int * new_height = (int *) bp; bp += 4;
bp += 4; /* Align */
- while( * (int*) bp) { switch (* (int*) bp) {
+ while( * (int*) bp) { switch (* (int*) bp) {
case 1: {bp += 4;
static_data = *(bool *) bp; bp += 4;
} break;
- }};
+ }};
if(!static_data) {data = (unsigned char *) malloc(Ecmd.bin[0]->size);memcpy(data,Ecmd.bin[0]->base,Ecmd.bin[0]->size);};
if(!This) throw wxe_badarg(0);
This->SetData(data,(int) *new_width,(int) *new_height,static_data);
- break;
+ break;
}
-case wxImage_SetMask: { // wxImage::SetMask
+case wxImage_SetMask: { // wxImage::SetMask
bool mask=true;
wxImage *This = (wxImage *) getPtr(bp,memenv); bp += 4;
bp += 4; /* Align */
- while( * (int*) bp) { switch (* (int*) bp) {
+ while( * (int*) bp) { switch (* (int*) bp) {
case 1: {bp += 4;
mask = *(bool *) bp; bp += 4;
} break;
- }};
+ }};
if(!This) throw wxe_badarg(0);
This->SetMask(mask);
- break;
+ break;
}
-case wxImage_SetMaskColour: { // wxImage::SetMaskColour
+case wxImage_SetMaskColour: { // wxImage::SetMaskColour
wxImage *This = (wxImage *) getPtr(bp,memenv); bp += 4;
unsigned int * r = (unsigned int *) bp; bp += 4;
unsigned int * g = (unsigned int *) bp; bp += 4;
unsigned int * b = (unsigned int *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
This->SetMaskColour((char) *r,(char) *g,(char) *b);
- break;
+ break;
}
-case wxImage_SetMaskFromImage: { // wxImage::SetMaskFromImage
+case wxImage_SetMaskFromImage: { // wxImage::SetMaskFromImage
wxImage *This = (wxImage *) getPtr(bp,memenv); bp += 4;
wxImage *mask = (wxImage *) getPtr(bp,memenv); bp += 4;
unsigned int * mr = (unsigned int *) bp; bp += 4;
@@ -10190,9 +10190,9 @@ case wxImage_SetMaskFromImage: { // wxImage::SetMaskFromImage
if(!This) throw wxe_badarg(0);
bool Result = This->SetMaskFromImage(*mask,(char) *mr,(char) *mg,(char) *mb);
rt.addBool(Result);
- break;
+ break;
}
-case wxImage_SetOption_2_1: { // wxImage::SetOption
+case wxImage_SetOption_2_1: { // wxImage::SetOption
wxImage *This = (wxImage *) getPtr(bp,memenv); bp += 4;
int * nameLen = (int *) bp; bp += 4;
wxString name = wxString(bp, wxConvUTF8);
@@ -10202,9 +10202,9 @@ case wxImage_SetOption_2_1: { // wxImage::SetOption
bp += *valueLen+((8-((4+ *valueLen) & 7)) & 7);
if(!This) throw wxe_badarg(0);
This->SetOption(name,value);
- break;
+ break;
}
-case wxImage_SetOption_2_0: { // wxImage::SetOption
+case wxImage_SetOption_2_0: { // wxImage::SetOption
wxImage *This = (wxImage *) getPtr(bp,memenv); bp += 4;
int * nameLen = (int *) bp; bp += 4;
wxString name = wxString(bp, wxConvUTF8);
@@ -10212,16 +10212,16 @@ case wxImage_SetOption_2_0: { // wxImage::SetOption
int * value = (int *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
This->SetOption(name,(int) *value);
- break;
+ break;
}
-case wxImage_SetPalette: { // wxImage::SetPalette
+case wxImage_SetPalette: { // wxImage::SetPalette
wxImage *This = (wxImage *) getPtr(bp,memenv); bp += 4;
wxPalette *palette = (wxPalette *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
This->SetPalette(*palette);
- break;
+ break;
}
-case wxImage_SetRGB_5: { // wxImage::SetRGB
+case wxImage_SetRGB_5: { // wxImage::SetRGB
wxImage *This = (wxImage *) getPtr(bp,memenv); bp += 4;
int * x = (int *) bp; bp += 4;
int * y = (int *) bp; bp += 4;
@@ -10230,9 +10230,9 @@ case wxImage_SetRGB_5: { // wxImage::SetRGB
unsigned int * b = (unsigned int *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
This->SetRGB((int) *x,(int) *y,(char) *r,(char) *g,(char) *b);
- break;
+ break;
}
-case wxImage_SetRGB_4: { // wxImage::SetRGB
+case wxImage_SetRGB_4: { // wxImage::SetRGB
wxImage *This = (wxImage *) getPtr(bp,memenv); bp += 4;
int * rectX = (int *) bp; bp += 4;
int * rectY = (int *) bp; bp += 4;
@@ -10244,74 +10244,74 @@ case wxImage_SetRGB_4: { // wxImage::SetRGB
unsigned int * b = (unsigned int *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
This->SetRGB(rect,(char) *r,(char) *g,(char) *b);
- break;
+ break;
}
-case wxBrush_new_0: { // wxBrush::wxBrush
+case wxBrush_new_0: { // wxBrush::wxBrush
wxBrush * Result = new EwxBrush();
newPtr((void *) Result, 1, memenv);
rt.addRef(getRef((void *)Result,memenv), "wxBrush");
- break;
+ break;
}
-case wxBrush_new_2: { // wxBrush::wxBrush
+case wxBrush_new_2: { // wxBrush::wxBrush
int style=wxSOLID;
int * colourR = (int *) bp; bp += 4;
int * colourG = (int *) bp; bp += 4;
int * colourB = (int *) bp; bp += 4;
int * colourA = (int *) bp; bp += 4;
wxColour colour = wxColour(*colourR,*colourG,*colourB,*colourA);
- while( * (int*) bp) { switch (* (int*) bp) {
+ while( * (int*) bp) { switch (* (int*) bp) {
case 1: {bp += 4;
style = (int)*(int *) bp; bp += 4;
} break;
- }};
+ }};
wxBrush * Result = new EwxBrush(colour,style);
newPtr((void *) Result, 1, memenv);
rt.addRef(getRef((void *)Result,memenv), "wxBrush");
- break;
+ break;
}
-case wxBrush_new_1: { // wxBrush::wxBrush
+case wxBrush_new_1: { // wxBrush::wxBrush
wxBitmap *stippleBitmap = (wxBitmap *) getPtr(bp,memenv); bp += 4;
wxBrush * Result = new EwxBrush(*stippleBitmap);
newPtr((void *) Result, 1, memenv);
rt.addRef(getRef((void *)Result,memenv), "wxBrush");
- break;
+ break;
}
-case wxBrush_GetColour: { // wxBrush::GetColour
+case wxBrush_GetColour: { // wxBrush::GetColour
wxBrush *This = (wxBrush *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
wxColour * Result = &This->GetColour();
rt.add((*Result));
- break;
+ break;
}
-case wxBrush_GetStipple: { // wxBrush::GetStipple
+case wxBrush_GetStipple: { // wxBrush::GetStipple
wxBrush *This = (wxBrush *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
wxBitmap * Result = (wxBitmap*)This->GetStipple();
rt.addRef(getRef((void *)Result,memenv), "wxBitmap");
- break;
+ break;
}
-case wxBrush_GetStyle: { // wxBrush::GetStyle
+case wxBrush_GetStyle: { // wxBrush::GetStyle
wxBrush *This = (wxBrush *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
int Result = This->GetStyle();
rt.addInt(Result);
- break;
+ break;
}
-case wxBrush_IsHatch: { // wxBrush::IsHatch
+case wxBrush_IsHatch: { // wxBrush::IsHatch
wxBrush *This = (wxBrush *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
bool Result = This->IsHatch();
rt.addBool(Result);
- break;
+ break;
}
-case wxBrush_IsOk: { // wxBrush::IsOk
+case wxBrush_IsOk: { // wxBrush::IsOk
wxBrush *This = (wxBrush *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
bool Result = This->IsOk();
rt.addBool(Result);
- break;
+ break;
}
-case wxBrush_SetColour_1: { // wxBrush::SetColour
+case wxBrush_SetColour_1: { // wxBrush::SetColour
wxBrush *This = (wxBrush *) getPtr(bp,memenv); bp += 4;
int * colR = (int *) bp; bp += 4;
int * colG = (int *) bp; bp += 4;
@@ -10320,38 +10320,38 @@ case wxBrush_SetColour_1: { // wxBrush::SetColour
wxColour col = wxColour(*colR,*colG,*colB,*colA);
if(!This) throw wxe_badarg(0);
This->SetColour(col);
- break;
+ break;
}
-case wxBrush_SetColour_3: { // wxBrush::SetColour
+case wxBrush_SetColour_3: { // wxBrush::SetColour
wxBrush *This = (wxBrush *) getPtr(bp,memenv); bp += 4;
unsigned int * r = (unsigned int *) bp; bp += 4;
unsigned int * g = (unsigned int *) bp; bp += 4;
unsigned int * b = (unsigned int *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
This->SetColour((char) *r,(char) *g,(char) *b);
- break;
+ break;
}
-case wxBrush_SetStipple: { // wxBrush::SetStipple
+case wxBrush_SetStipple: { // wxBrush::SetStipple
wxBrush *This = (wxBrush *) getPtr(bp,memenv); bp += 4;
wxBitmap *stipple = (wxBitmap *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
This->SetStipple(*stipple);
- break;
+ break;
}
-case wxBrush_SetStyle: { // wxBrush::SetStyle
+case wxBrush_SetStyle: { // wxBrush::SetStyle
wxBrush *This = (wxBrush *) getPtr(bp,memenv); bp += 4;
int * style = (int *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
This->SetStyle((int) *style);
- break;
+ break;
}
-case wxPen_new_0: { // wxPen::wxPen
+case wxPen_new_0: { // wxPen::wxPen
wxPen * Result = new EwxPen();
newPtr((void *) Result, 1, memenv);
rt.addRef(getRef((void *)Result,memenv), "wxPen");
- break;
+ break;
}
-case wxPen_new_2: { // wxPen::wxPen
+case wxPen_new_2: { // wxPen::wxPen
int width=1;
int style=wxSOLID;
int * colourR = (int *) bp; bp += 4;
@@ -10359,69 +10359,69 @@ case wxPen_new_2: { // wxPen::wxPen
int * colourB = (int *) bp; bp += 4;
int * colourA = (int *) bp; bp += 4;
wxColour colour = wxColour(*colourR,*colourG,*colourB,*colourA);
- while( * (int*) bp) { switch (* (int*) bp) {
+ while( * (int*) bp) { switch (* (int*) bp) {
case 1: {bp += 4;
width = (int)*(int *) bp; bp += 4;
} break;
case 2: {bp += 4;
style = (int)*(int *) bp; bp += 4;
} break;
- }};
+ }};
wxPen * Result = new EwxPen(colour,width,style);
newPtr((void *) Result, 1, memenv);
rt.addRef(getRef((void *)Result,memenv), "wxPen");
- break;
+ break;
}
-case wxPen_GetCap: { // wxPen::GetCap
+case wxPen_GetCap: { // wxPen::GetCap
wxPen *This = (wxPen *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
int Result = This->GetCap();
rt.addInt(Result);
- break;
+ break;
}
-case wxPen_GetColour: { // wxPen::GetColour
+case wxPen_GetColour: { // wxPen::GetColour
wxPen *This = (wxPen *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
wxColour * Result = &This->GetColour();
rt.add((*Result));
- break;
+ break;
}
-case wxPen_GetJoin: { // wxPen::GetJoin
+case wxPen_GetJoin: { // wxPen::GetJoin
wxPen *This = (wxPen *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
int Result = This->GetJoin();
rt.addInt(Result);
- break;
+ break;
}
-case wxPen_GetStyle: { // wxPen::GetStyle
+case wxPen_GetStyle: { // wxPen::GetStyle
wxPen *This = (wxPen *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
int Result = This->GetStyle();
rt.addInt(Result);
- break;
+ break;
}
-case wxPen_GetWidth: { // wxPen::GetWidth
+case wxPen_GetWidth: { // wxPen::GetWidth
wxPen *This = (wxPen *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
int Result = This->GetWidth();
rt.addInt(Result);
- break;
+ break;
}
-case wxPen_IsOk: { // wxPen::IsOk
+case wxPen_IsOk: { // wxPen::IsOk
wxPen *This = (wxPen *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
bool Result = This->IsOk();
rt.addBool(Result);
- break;
+ break;
}
-case wxPen_SetCap: { // wxPen::SetCap
+case wxPen_SetCap: { // wxPen::SetCap
wxPen *This = (wxPen *) getPtr(bp,memenv); bp += 4;
int * capStyle = (int *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
This->SetCap((int) *capStyle);
- break;
+ break;
}
-case wxPen_SetColour_1: { // wxPen::SetColour
+case wxPen_SetColour_1: { // wxPen::SetColour
wxPen *This = (wxPen *) getPtr(bp,memenv); bp += 4;
int * colourR = (int *) bp; bp += 4;
int * colourG = (int *) bp; bp += 4;
@@ -10430,45 +10430,45 @@ case wxPen_SetColour_1: { // wxPen::SetColour
wxColour colour = wxColour(*colourR,*colourG,*colourB,*colourA);
if(!This) throw wxe_badarg(0);
This->SetColour(colour);
- break;
+ break;
}
-case wxPen_SetColour_3: { // wxPen::SetColour
+case wxPen_SetColour_3: { // wxPen::SetColour
wxPen *This = (wxPen *) getPtr(bp,memenv); bp += 4;
unsigned int * red = (unsigned int *) bp; bp += 4;
unsigned int * green = (unsigned int *) bp; bp += 4;
unsigned int * blue = (unsigned int *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
This->SetColour((char) *red,(char) *green,(char) *blue);
- break;
+ break;
}
-case wxPen_SetJoin: { // wxPen::SetJoin
+case wxPen_SetJoin: { // wxPen::SetJoin
wxPen *This = (wxPen *) getPtr(bp,memenv); bp += 4;
int * joinStyle = (int *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
This->SetJoin((int) *joinStyle);
- break;
+ break;
}
-case wxPen_SetStyle: { // wxPen::SetStyle
+case wxPen_SetStyle: { // wxPen::SetStyle
wxPen *This = (wxPen *) getPtr(bp,memenv); bp += 4;
int * style = (int *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
This->SetStyle((int) *style);
- break;
+ break;
}
-case wxPen_SetWidth: { // wxPen::SetWidth
+case wxPen_SetWidth: { // wxPen::SetWidth
wxPen *This = (wxPen *) getPtr(bp,memenv); bp += 4;
int * width = (int *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
This->SetWidth((int) *width);
- break;
+ break;
}
-case wxRegion_new_0: { // wxRegion::wxRegion
+case wxRegion_new_0: { // wxRegion::wxRegion
wxRegion * Result = new EwxRegion();
newPtr((void *) Result, 1, memenv);
rt.addRef(getRef((void *)Result,memenv), "wxRegion");
- break;
+ break;
}
-case wxRegion_new_4: { // wxRegion::wxRegion
+case wxRegion_new_4: { // wxRegion::wxRegion
int * x = (int *) bp; bp += 4;
int * y = (int *) bp; bp += 4;
int * w = (int *) bp; bp += 4;
@@ -10476,9 +10476,9 @@ case wxRegion_new_4: { // wxRegion::wxRegion
wxRegion * Result = new EwxRegion((wxCoord) *x,(wxCoord) *y,(wxCoord) *w,(wxCoord) *h);
newPtr((void *) Result, 1, memenv);
rt.addRef(getRef((void *)Result,memenv), "wxRegion");
- break;
+ break;
}
-case wxRegion_new_2: { // wxRegion::wxRegion
+case wxRegion_new_2: { // wxRegion::wxRegion
int * topLeftX = (int *) bp; bp += 4;
int * topLeftY = (int *) bp; bp += 4;
wxPoint topLeft = wxPoint(*topLeftX,*topLeftY);
@@ -10488,9 +10488,9 @@ case wxRegion_new_2: { // wxRegion::wxRegion
wxRegion * Result = new EwxRegion(topLeft,bottomRight);
newPtr((void *) Result, 1, memenv);
rt.addRef(getRef((void *)Result,memenv), "wxRegion");
- break;
+ break;
}
-case wxRegion_new_1_1: { // wxRegion::wxRegion
+case wxRegion_new_1_1: { // wxRegion::wxRegion
int * rectX = (int *) bp; bp += 4;
int * rectY = (int *) bp; bp += 4;
int * rectW = (int *) bp; bp += 4;
@@ -10499,31 +10499,31 @@ case wxRegion_new_1_1: { // wxRegion::wxRegion
wxRegion * Result = new EwxRegion(rect);
newPtr((void *) Result, 1, memenv);
rt.addRef(getRef((void *)Result,memenv), "wxRegion");
- break;
+ break;
}
-case wxRegion_new_1_0: { // wxRegion::wxRegion
+case wxRegion_new_1_0: { // wxRegion::wxRegion
wxBitmap *bmp = (wxBitmap *) getPtr(bp,memenv); bp += 4;
wxRegion * Result = new EwxRegion(*bmp);
newPtr((void *) Result, 1, memenv);
rt.addRef(getRef((void *)Result,memenv), "wxRegion");
- break;
+ break;
}
-case wxRegion_Clear: { // wxRegion::Clear
+case wxRegion_Clear: { // wxRegion::Clear
wxRegion *This = (wxRegion *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
This->Clear();
- break;
+ break;
}
-case wxRegion_Contains_2: { // wxRegion::Contains
+case wxRegion_Contains_2: { // wxRegion::Contains
wxRegion *This = (wxRegion *) getPtr(bp,memenv); bp += 4;
int * x = (int *) bp; bp += 4;
int * y = (int *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
int Result = This->Contains((wxCoord) *x,(wxCoord) *y);
rt.addInt(Result);
- break;
+ break;
}
-case wxRegion_Contains_1_0: { // wxRegion::Contains
+case wxRegion_Contains_1_0: { // wxRegion::Contains
wxRegion *This = (wxRegion *) getPtr(bp,memenv); bp += 4;
int * ptX = (int *) bp; bp += 4;
int * ptY = (int *) bp; bp += 4;
@@ -10531,9 +10531,9 @@ case wxRegion_Contains_1_0: { // wxRegion::Contains
if(!This) throw wxe_badarg(0);
int Result = This->Contains(pt);
rt.addInt(Result);
- break;
+ break;
}
-case wxRegion_Contains_4: { // wxRegion::Contains
+case wxRegion_Contains_4: { // wxRegion::Contains
wxRegion *This = (wxRegion *) getPtr(bp,memenv); bp += 4;
int * x = (int *) bp; bp += 4;
int * y = (int *) bp; bp += 4;
@@ -10542,9 +10542,9 @@ case wxRegion_Contains_4: { // wxRegion::Contains
if(!This) throw wxe_badarg(0);
int Result = This->Contains((wxCoord) *x,(wxCoord) *y,(wxCoord) *w,(wxCoord) *h);
rt.addInt(Result);
- break;
+ break;
}
-case wxRegion_Contains_1_1: { // wxRegion::Contains
+case wxRegion_Contains_1_1: { // wxRegion::Contains
wxRegion *This = (wxRegion *) getPtr(bp,memenv); bp += 4;
int * rectX = (int *) bp; bp += 4;
int * rectY = (int *) bp; bp += 4;
@@ -10554,23 +10554,23 @@ case wxRegion_Contains_1_1: { // wxRegion::Contains
if(!This) throw wxe_badarg(0);
int Result = This->Contains(rect);
rt.addInt(Result);
- break;
+ break;
}
-case wxRegion_ConvertToBitmap: { // wxRegion::ConvertToBitmap
+case wxRegion_ConvertToBitmap: { // wxRegion::ConvertToBitmap
wxRegion *This = (wxRegion *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
wxBitmap * Result = new wxBitmap(This->ConvertToBitmap()); newPtr((void *) Result,3, memenv);;
rt.addRef(getRef((void *)Result,memenv), "wxBitmap");
- break;
+ break;
}
-case wxRegion_GetBox: { // wxRegion::GetBox
+case wxRegion_GetBox: { // wxRegion::GetBox
wxRegion *This = (wxRegion *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
wxRect Result = This->GetBox();
rt.add(Result);
- break;
+ break;
}
-case wxRegion_Intersect_4: { // wxRegion::Intersect
+case wxRegion_Intersect_4: { // wxRegion::Intersect
wxRegion *This = (wxRegion *) getPtr(bp,memenv); bp += 4;
int * x = (int *) bp; bp += 4;
int * y = (int *) bp; bp += 4;
@@ -10579,9 +10579,9 @@ case wxRegion_Intersect_4: { // wxRegion::Intersect
if(!This) throw wxe_badarg(0);
bool Result = This->Intersect((wxCoord) *x,(wxCoord) *y,(wxCoord) *w,(wxCoord) *h);
rt.addBool(Result);
- break;
+ break;
}
-case wxRegion_Intersect_1_1: { // wxRegion::Intersect
+case wxRegion_Intersect_1_1: { // wxRegion::Intersect
wxRegion *This = (wxRegion *) getPtr(bp,memenv); bp += 4;
int * rectX = (int *) bp; bp += 4;
int * rectY = (int *) bp; bp += 4;
@@ -10591,24 +10591,24 @@ case wxRegion_Intersect_1_1: { // wxRegion::Intersect
if(!This) throw wxe_badarg(0);
bool Result = This->Intersect(rect);
rt.addBool(Result);
- break;
+ break;
}
-case wxRegion_Intersect_1_0: { // wxRegion::Intersect
+case wxRegion_Intersect_1_0: { // wxRegion::Intersect
wxRegion *This = (wxRegion *) getPtr(bp,memenv); bp += 4;
wxRegion *region = (wxRegion *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
bool Result = This->Intersect(*region);
rt.addBool(Result);
- break;
+ break;
}
-case wxRegion_IsEmpty: { // wxRegion::IsEmpty
+case wxRegion_IsEmpty: { // wxRegion::IsEmpty
wxRegion *This = (wxRegion *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
bool Result = This->IsEmpty();
rt.addBool(Result);
- break;
+ break;
}
-case wxRegion_Subtract_4: { // wxRegion::Subtract
+case wxRegion_Subtract_4: { // wxRegion::Subtract
wxRegion *This = (wxRegion *) getPtr(bp,memenv); bp += 4;
int * x = (int *) bp; bp += 4;
int * y = (int *) bp; bp += 4;
@@ -10617,9 +10617,9 @@ case wxRegion_Subtract_4: { // wxRegion::Subtract
if(!This) throw wxe_badarg(0);
bool Result = This->Subtract((wxCoord) *x,(wxCoord) *y,(wxCoord) *w,(wxCoord) *h);
rt.addBool(Result);
- break;
+ break;
}
-case wxRegion_Subtract_1_1: { // wxRegion::Subtract
+case wxRegion_Subtract_1_1: { // wxRegion::Subtract
wxRegion *This = (wxRegion *) getPtr(bp,memenv); bp += 4;
int * rectX = (int *) bp; bp += 4;
int * rectY = (int *) bp; bp += 4;
@@ -10629,26 +10629,26 @@ case wxRegion_Subtract_1_1: { // wxRegion::Subtract
if(!This) throw wxe_badarg(0);
bool Result = This->Subtract(rect);
rt.addBool(Result);
- break;
+ break;
}
-case wxRegion_Subtract_1_0: { // wxRegion::Subtract
+case wxRegion_Subtract_1_0: { // wxRegion::Subtract
wxRegion *This = (wxRegion *) getPtr(bp,memenv); bp += 4;
wxRegion *region = (wxRegion *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
bool Result = This->Subtract(*region);
rt.addBool(Result);
- break;
+ break;
}
-case wxRegion_Offset_2: { // wxRegion::Offset
+case wxRegion_Offset_2: { // wxRegion::Offset
wxRegion *This = (wxRegion *) getPtr(bp,memenv); bp += 4;
int * x = (int *) bp; bp += 4;
int * y = (int *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
bool Result = This->Offset((wxCoord) *x,(wxCoord) *y);
rt.addBool(Result);
- break;
+ break;
}
-case wxRegion_Offset_1: { // wxRegion::Offset
+case wxRegion_Offset_1: { // wxRegion::Offset
wxRegion *This = (wxRegion *) getPtr(bp,memenv); bp += 4;
int * ptX = (int *) bp; bp += 4;
int * ptY = (int *) bp; bp += 4;
@@ -10656,9 +10656,9 @@ case wxRegion_Offset_1: { // wxRegion::Offset
if(!This) throw wxe_badarg(0);
bool Result = This->Offset(pt);
rt.addBool(Result);
- break;
+ break;
}
-case wxRegion_Union_4: { // wxRegion::Union
+case wxRegion_Union_4: { // wxRegion::Union
wxRegion *This = (wxRegion *) getPtr(bp,memenv); bp += 4;
int * x = (int *) bp; bp += 4;
int * y = (int *) bp; bp += 4;
@@ -10667,9 +10667,9 @@ case wxRegion_Union_4: { // wxRegion::Union
if(!This) throw wxe_badarg(0);
bool Result = This->Union((wxCoord) *x,(wxCoord) *y,(wxCoord) *w,(wxCoord) *h);
rt.addBool(Result);
- break;
+ break;
}
-case wxRegion_Union_1_2: { // wxRegion::Union
+case wxRegion_Union_1_2: { // wxRegion::Union
wxRegion *This = (wxRegion *) getPtr(bp,memenv); bp += 4;
int * rectX = (int *) bp; bp += 4;
int * rectY = (int *) bp; bp += 4;
@@ -10679,25 +10679,25 @@ case wxRegion_Union_1_2: { // wxRegion::Union
if(!This) throw wxe_badarg(0);
bool Result = This->Union(rect);
rt.addBool(Result);
- break;
+ break;
}
-case wxRegion_Union_1_1: { // wxRegion::Union
+case wxRegion_Union_1_1: { // wxRegion::Union
wxRegion *This = (wxRegion *) getPtr(bp,memenv); bp += 4;
wxRegion * region = (wxRegion *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
bool Result = This->Union(*region);
rt.addBool(Result);
- break;
+ break;
}
-case wxRegion_Union_1_0: { // wxRegion::Union
+case wxRegion_Union_1_0: { // wxRegion::Union
wxRegion *This = (wxRegion *) getPtr(bp,memenv); bp += 4;
wxBitmap *bmp = (wxBitmap *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
bool Result = This->Union(*bmp);
rt.addBool(Result);
- break;
+ break;
}
-case wxRegion_Union_3: { // wxRegion::Union
+case wxRegion_Union_3: { // wxRegion::Union
int tolerance=0;
wxRegion *This = (wxRegion *) getPtr(bp,memenv); bp += 4;
wxBitmap *bmp = (wxBitmap *) getPtr(bp,memenv); bp += 4;
@@ -10706,17 +10706,17 @@ case wxRegion_Union_3: { // wxRegion::Union
int * transpB = (int *) bp; bp += 4;
int * transpA = (int *) bp; bp += 4;
wxColour transp = wxColour(*transpR,*transpG,*transpB,*transpA);
- while( * (int*) bp) { switch (* (int*) bp) {
+ while( * (int*) bp) { switch (* (int*) bp) {
case 1: {bp += 4;
tolerance = (int)*(int *) bp; bp += 4;
} break;
- }};
+ }};
if(!This) throw wxe_badarg(0);
bool Result = This->Union(*bmp,transp,tolerance);
rt.addBool(Result);
- break;
+ break;
}
-case wxRegion_Xor_4: { // wxRegion::Xor
+case wxRegion_Xor_4: { // wxRegion::Xor
wxRegion *This = (wxRegion *) getPtr(bp,memenv); bp += 4;
int * x = (int *) bp; bp += 4;
int * y = (int *) bp; bp += 4;
@@ -10725,9 +10725,9 @@ case wxRegion_Xor_4: { // wxRegion::Xor
if(!This) throw wxe_badarg(0);
bool Result = This->Xor((wxCoord) *x,(wxCoord) *y,(wxCoord) *w,(wxCoord) *h);
rt.addBool(Result);
- break;
+ break;
}
-case wxRegion_Xor_1_1: { // wxRegion::Xor
+case wxRegion_Xor_1_1: { // wxRegion::Xor
wxRegion *This = (wxRegion *) getPtr(bp,memenv); bp += 4;
int * rectX = (int *) bp; bp += 4;
int * rectY = (int *) bp; bp += 4;
@@ -10737,23 +10737,23 @@ case wxRegion_Xor_1_1: { // wxRegion::Xor
if(!This) throw wxe_badarg(0);
bool Result = This->Xor(rect);
rt.addBool(Result);
- break;
+ break;
}
-case wxRegion_Xor_1_0: { // wxRegion::Xor
+case wxRegion_Xor_1_0: { // wxRegion::Xor
wxRegion *This = (wxRegion *) getPtr(bp,memenv); bp += 4;
wxRegion *region = (wxRegion *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
bool Result = This->Xor(*region);
rt.addBool(Result);
- break;
+ break;
}
-case wxAcceleratorTable_new_0: { // wxAcceleratorTable::wxAcceleratorTable
+case wxAcceleratorTable_new_0: { // wxAcceleratorTable::wxAcceleratorTable
wxAcceleratorTable * Result = new EwxAcceleratorTable();
newPtr((void *) Result, 1, memenv);
rt.addRef(getRef((void *)Result,memenv), "wxAcceleratorTable");
- break;
+ break;
}
-case wxAcceleratorTable_new_2: { // wxAcceleratorTable::wxAcceleratorTable
+case wxAcceleratorTable_new_2: { // wxAcceleratorTable::wxAcceleratorTable
int * n = (int *) bp; bp += 4;
int * entriesLen = (int *) bp; bp += 4;
wxAcceleratorEntry *entries;
@@ -10763,21 +10763,21 @@ case wxAcceleratorTable_new_2: { // wxAcceleratorTable::wxAcceleratorTable
newPtr((void *) Result, 1, memenv);
driver_free(entries);
rt.addRef(getRef((void *)Result,memenv), "wxAcceleratorTable");
- break;
+ break;
}
-case wxAcceleratorTable_Ok: { // wxAcceleratorTable::Ok
+case wxAcceleratorTable_Ok: { // wxAcceleratorTable::Ok
wxAcceleratorTable *This = (wxAcceleratorTable *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
bool Result = This->Ok();
rt.addBool(Result);
- break;
+ break;
}
-case wxAcceleratorEntry_new_1_0: { // wxAcceleratorEntry::wxAcceleratorEntry
+case wxAcceleratorEntry_new_1_0: { // wxAcceleratorEntry::wxAcceleratorEntry
int flags=0;
int keyCode=0;
int cmd=0;
wxMenuItem * item=NULL;
- while( * (int*) bp) { switch (* (int*) bp) {
+ while( * (int*) bp) { switch (* (int*) bp) {
case 1: {bp += 4;
flags = (int)*(int *) bp; bp += 4;
} break;
@@ -10790,71 +10790,71 @@ case wxAcceleratorEntry_new_1_0: { // wxAcceleratorEntry::wxAcceleratorEntry
case 4: {bp += 4;
item = (wxMenuItem *) getPtr(bp,memenv); bp += 4;
} break;
- }};
+ }};
wxAcceleratorEntry * Result = new wxAcceleratorEntry(flags,keyCode,cmd,item);
newPtr((void *) Result, 69, memenv);
rt.addRef(getRef((void *)Result,memenv), "wxAcceleratorEntry");
- break;
+ break;
}
-case wxAcceleratorEntry_new_1_1: { // wxAcceleratorEntry::wxAcceleratorEntry
+case wxAcceleratorEntry_new_1_1: { // wxAcceleratorEntry::wxAcceleratorEntry
wxAcceleratorEntry *entry = (wxAcceleratorEntry *) getPtr(bp,memenv); bp += 4;
wxAcceleratorEntry * Result = new wxAcceleratorEntry(*entry);
newPtr((void *) Result, 69, memenv);
rt.addRef(getRef((void *)Result,memenv), "wxAcceleratorEntry");
- break;
+ break;
}
-case wxAcceleratorEntry_GetCommand: { // wxAcceleratorEntry::GetCommand
+case wxAcceleratorEntry_GetCommand: { // wxAcceleratorEntry::GetCommand
wxAcceleratorEntry *This = (wxAcceleratorEntry *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
int Result = This->GetCommand();
rt.addInt(Result);
- break;
+ break;
}
-case wxAcceleratorEntry_GetFlags: { // wxAcceleratorEntry::GetFlags
+case wxAcceleratorEntry_GetFlags: { // wxAcceleratorEntry::GetFlags
wxAcceleratorEntry *This = (wxAcceleratorEntry *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
int Result = This->GetFlags();
rt.addInt(Result);
- break;
+ break;
}
-case wxAcceleratorEntry_GetKeyCode: { // wxAcceleratorEntry::GetKeyCode
+case wxAcceleratorEntry_GetKeyCode: { // wxAcceleratorEntry::GetKeyCode
wxAcceleratorEntry *This = (wxAcceleratorEntry *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
int Result = This->GetKeyCode();
rt.addInt(Result);
- break;
+ break;
}
-case wxAcceleratorEntry_Set: { // wxAcceleratorEntry::Set
+case wxAcceleratorEntry_Set: { // wxAcceleratorEntry::Set
wxMenuItem * item=NULL;
wxAcceleratorEntry *This = (wxAcceleratorEntry *) getPtr(bp,memenv); bp += 4;
int * flags = (int *) bp; bp += 4;
int * keyCode = (int *) bp; bp += 4;
int * cmd = (int *) bp; bp += 4;
- while( * (int*) bp) { switch (* (int*) bp) {
+ while( * (int*) bp) { switch (* (int*) bp) {
case 1: {bp += 4;
item = (wxMenuItem *) getPtr(bp,memenv); bp += 4;
} break;
- }};
+ }};
if(!This) throw wxe_badarg(0);
This->Set((int) *flags,(int) *keyCode,(int) *cmd,item);
- break;
+ break;
}
-case wxAcceleratorEntry_destroy: { // wxAcceleratorEntry::destroy
+case wxAcceleratorEntry_destroy: { // wxAcceleratorEntry::destroy
wxAcceleratorEntry *This = (wxAcceleratorEntry *) getPtr(bp,memenv); bp += 4;
if(This) { ((WxeApp *) wxTheApp)->clearPtr((void *) This);
delete This;}
- break;
+ break;
}
-case wxCaret_new_3: { // wxCaret::wxCaret
+case wxCaret_new_3: { // wxCaret::wxCaret
wxWindow *window = (wxWindow *) getPtr(bp,memenv); bp += 4;
int * width = (int *) bp; bp += 4;
int * height = (int *) bp; bp += 4;
wxCaret * Result = new EwxCaret(window,(int) *width,(int) *height);
newPtr((void *) Result, 70, memenv);
rt.addRef(getRef((void *)Result,memenv), "wxCaret");
- break;
+ break;
}
-case wxCaret_new_2: { // wxCaret::wxCaret
+case wxCaret_new_2: { // wxCaret::wxCaret
wxWindow *window = (wxWindow *) getPtr(bp,memenv); bp += 4;
int * sizeW = (int *) bp; bp += 4;
int * sizeH = (int *) bp; bp += 4;
@@ -10862,15 +10862,15 @@ case wxCaret_new_2: { // wxCaret::wxCaret
wxCaret * Result = new EwxCaret(window,size);
newPtr((void *) Result, 70, memenv);
rt.addRef(getRef((void *)Result,memenv), "wxCaret");
- break;
+ break;
}
-case wxCaret_destruct: { // wxCaret::~wxCaret
+case wxCaret_destruct: { // wxCaret::~wxCaret
wxCaret *This = (wxCaret *) getPtr(bp,memenv); bp += 4;
if(This) { ((WxeApp *) wxTheApp)->clearPtr((void *) This);
delete This;}
- break;
+ break;
}
-case wxCaret_Create_3: { // wxCaret::Create
+case wxCaret_Create_3: { // wxCaret::Create
wxCaret *This = (wxCaret *) getPtr(bp,memenv); bp += 4;
wxWindow *window = (wxWindow *) getPtr(bp,memenv); bp += 4;
int * width = (int *) bp; bp += 4;
@@ -10878,9 +10878,9 @@ case wxCaret_Create_3: { // wxCaret::Create
if(!This) throw wxe_badarg(0);
bool Result = This->Create(window,(int) *width,(int) *height);
rt.addBool(Result);
- break;
+ break;
}
-case wxCaret_Create_2: { // wxCaret::Create
+case wxCaret_Create_2: { // wxCaret::Create
wxCaret *This = (wxCaret *) getPtr(bp,memenv); bp += 4;
wxWindow *window = (wxWindow *) getPtr(bp,memenv); bp += 4;
int * sizeW = (int *) bp; bp += 4;
@@ -10889,114 +10889,114 @@ case wxCaret_Create_2: { // wxCaret::Create
if(!This) throw wxe_badarg(0);
bool Result = This->Create(window,size);
rt.addBool(Result);
- break;
+ break;
}
-case wxCaret_GetBlinkTime: { // wxCaret::GetBlinkTime
+case wxCaret_GetBlinkTime: { // wxCaret::GetBlinkTime
int Result = wxCaret::GetBlinkTime();
rt.addInt(Result);
- break;
+ break;
}
-case wxCaret_GetPosition: { // wxCaret::GetPosition
+case wxCaret_GetPosition: { // wxCaret::GetPosition
wxCaret *This = (wxCaret *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
wxPoint Result = This->GetPosition();
rt.add(Result);
- break;
+ break;
}
-case wxCaret_GetSize: { // wxCaret::GetSize
+case wxCaret_GetSize: { // wxCaret::GetSize
wxCaret *This = (wxCaret *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
wxSize Result = This->GetSize();
rt.add(Result);
- break;
+ break;
}
-case wxCaret_GetWindow: { // wxCaret::GetWindow
+case wxCaret_GetWindow: { // wxCaret::GetWindow
wxCaret *This = (wxCaret *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
wxWindow * Result = (wxWindow*)This->GetWindow();
rt.addRef(getRef((void *)Result,memenv), "wxWindow");
- break;
+ break;
}
-case wxCaret_Hide: { // wxCaret::Hide
+case wxCaret_Hide: { // wxCaret::Hide
wxCaret *This = (wxCaret *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
This->Hide();
- break;
+ break;
}
-case wxCaret_IsOk: { // wxCaret::IsOk
+case wxCaret_IsOk: { // wxCaret::IsOk
wxCaret *This = (wxCaret *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
bool Result = This->IsOk();
rt.addBool(Result);
- break;
+ break;
}
-case wxCaret_IsVisible: { // wxCaret::IsVisible
+case wxCaret_IsVisible: { // wxCaret::IsVisible
wxCaret *This = (wxCaret *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
bool Result = This->IsVisible();
rt.addBool(Result);
- break;
+ break;
}
-case wxCaret_Move_2: { // wxCaret::Move
+case wxCaret_Move_2: { // wxCaret::Move
wxCaret *This = (wxCaret *) getPtr(bp,memenv); bp += 4;
int * x = (int *) bp; bp += 4;
int * y = (int *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
This->Move((int) *x,(int) *y);
- break;
+ break;
}
-case wxCaret_Move_1: { // wxCaret::Move
+case wxCaret_Move_1: { // wxCaret::Move
wxCaret *This = (wxCaret *) getPtr(bp,memenv); bp += 4;
int * ptX = (int *) bp; bp += 4;
int * ptY = (int *) bp; bp += 4;
wxPoint pt = wxPoint(*ptX,*ptY);
if(!This) throw wxe_badarg(0);
This->Move(pt);
- break;
+ break;
}
-case wxCaret_SetBlinkTime: { // wxCaret::SetBlinkTime
+case wxCaret_SetBlinkTime: { // wxCaret::SetBlinkTime
int * milliseconds = (int *) bp; bp += 4;
wxCaret::SetBlinkTime((int) *milliseconds);
- break;
+ break;
}
-case wxCaret_SetSize_2: { // wxCaret::SetSize
+case wxCaret_SetSize_2: { // wxCaret::SetSize
wxCaret *This = (wxCaret *) getPtr(bp,memenv); bp += 4;
int * width = (int *) bp; bp += 4;
int * height = (int *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
This->SetSize((int) *width,(int) *height);
- break;
+ break;
}
-case wxCaret_SetSize_1: { // wxCaret::SetSize
+case wxCaret_SetSize_1: { // wxCaret::SetSize
wxCaret *This = (wxCaret *) getPtr(bp,memenv); bp += 4;
int * sizeW = (int *) bp; bp += 4;
int * sizeH = (int *) bp; bp += 4;
wxSize size = wxSize(*sizeW,*sizeH);
if(!This) throw wxe_badarg(0);
This->SetSize(size);
- break;
+ break;
}
-case wxCaret_Show: { // wxCaret::Show
+case wxCaret_Show: { // wxCaret::Show
bool show=true;
wxCaret *This = (wxCaret *) getPtr(bp,memenv); bp += 4;
bp += 4; /* Align */
- while( * (int*) bp) { switch (* (int*) bp) {
+ while( * (int*) bp) { switch (* (int*) bp) {
case 1: {bp += 4;
show = *(bool *) bp; bp += 4;
} break;
- }};
+ }};
if(!This) throw wxe_badarg(0);
This->Show(show);
- break;
+ break;
}
-case wxSizer_Add_2_1: { // wxSizer::Add
+case wxSizer_Add_2_1: { // wxSizer::Add
int proportion=0;
int flag=0;
int border=0;
wxObject * userData=NULL;
wxSizer *This = (wxSizer *) getPtr(bp,memenv); bp += 4;
wxWindow * window = (wxWindow *) getPtr(bp,memenv); bp += 4;
- while( * (int*) bp) { switch (* (int*) bp) {
+ while( * (int*) bp) { switch (* (int*) bp) {
case 1: {bp += 4;
proportion = (int)*(int *) bp; bp += 4;
} break;
@@ -11009,20 +11009,20 @@ case wxSizer_Add_2_1: { // wxSizer::Add
case 4: {bp += 4;
userData = (wxObject *) getPtr(bp,memenv); bp += 4;
} break;
- }};
+ }};
if(!This) throw wxe_badarg(0);
wxSizerItem * Result = (wxSizerItem*)This->Add(window,proportion,flag,border,userData);
rt.addRef(getRef((void *)Result,memenv), "wxSizerItem");
- break;
+ break;
}
-case wxSizer_Add_2_0: { // wxSizer::Add
+case wxSizer_Add_2_0: { // wxSizer::Add
int proportion=0;
int flag=0;
int border=0;
wxObject * userData=NULL;
wxSizer *This = (wxSizer *) getPtr(bp,memenv); bp += 4;
wxSizer *sizer = (wxSizer *) getPtr(bp,memenv); bp += 4;
- while( * (int*) bp) { switch (* (int*) bp) {
+ while( * (int*) bp) { switch (* (int*) bp) {
case 1: {bp += 4;
proportion = (int)*(int *) bp; bp += 4;
} break;
@@ -11035,13 +11035,13 @@ case wxSizer_Add_2_0: { // wxSizer::Add
case 4: {bp += 4;
userData = (wxObject *) getPtr(bp,memenv); bp += 4;
} break;
- }};
+ }};
if(!This) throw wxe_badarg(0);
wxSizerItem * Result = (wxSizerItem*)This->Add(sizer,proportion,flag,border,userData);
rt.addRef(getRef((void *)Result,memenv), "wxSizerItem");
- break;
+ break;
}
-case wxSizer_Add_3: { // wxSizer::Add
+case wxSizer_Add_3: { // wxSizer::Add
int proportion=0;
int flag=0;
int border=0;
@@ -11050,7 +11050,7 @@ case wxSizer_Add_3: { // wxSizer::Add
int * width = (int *) bp; bp += 4;
int * height = (int *) bp; bp += 4;
bp += 4; /* Align */
- while( * (int*) bp) { switch (* (int*) bp) {
+ while( * (int*) bp) { switch (* (int*) bp) {
case 1: {bp += 4;
proportion = (int)*(int *) bp; bp += 4;
} break;
@@ -11063,112 +11063,112 @@ case wxSizer_Add_3: { // wxSizer::Add
case 4: {bp += 4;
userData = (wxObject *) getPtr(bp,memenv); bp += 4;
} break;
- }};
+ }};
if(!This) throw wxe_badarg(0);
wxSizerItem * Result = (wxSizerItem*)This->Add((int) *width,(int) *height,proportion,flag,border,userData);
rt.addRef(getRef((void *)Result,memenv), "wxSizerItem");
- break;
+ break;
}
-case wxSizer_Add_2_3: { // wxSizer::Add
+case wxSizer_Add_2_3: { // wxSizer::Add
wxSizer *This = (wxSizer *) getPtr(bp,memenv); bp += 4;
wxWindow * window = (wxWindow *) getPtr(bp,memenv); bp += 4;
wxSizerFlags *flags = (wxSizerFlags *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
wxSizerItem * Result = (wxSizerItem*)This->Add(window,*flags);
rt.addRef(getRef((void *)Result,memenv), "wxSizerItem");
- break;
+ break;
}
-case wxSizer_Add_2_2: { // wxSizer::Add
+case wxSizer_Add_2_2: { // wxSizer::Add
wxSizer *This = (wxSizer *) getPtr(bp,memenv); bp += 4;
wxSizer *sizer = (wxSizer *) getPtr(bp,memenv); bp += 4;
wxSizerFlags *flags = (wxSizerFlags *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
wxSizerItem * Result = (wxSizerItem*)This->Add(sizer,*flags);
rt.addRef(getRef((void *)Result,memenv), "wxSizerItem");
- break;
+ break;
}
-case wxSizer_AddSpacer: { // wxSizer::AddSpacer
+case wxSizer_AddSpacer: { // wxSizer::AddSpacer
wxSizer *This = (wxSizer *) getPtr(bp,memenv); bp += 4;
int * size = (int *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
wxSizerItem * Result = (wxSizerItem*)This->AddSpacer((int) *size);
rt.addRef(getRef((void *)Result,memenv), "wxSizerItem");
- break;
+ break;
}
-case wxSizer_AddStretchSpacer: { // wxSizer::AddStretchSpacer
+case wxSizer_AddStretchSpacer: { // wxSizer::AddStretchSpacer
int prop=1;
wxSizer *This = (wxSizer *) getPtr(bp,memenv); bp += 4;
bp += 4; /* Align */
- while( * (int*) bp) { switch (* (int*) bp) {
+ while( * (int*) bp) { switch (* (int*) bp) {
case 1: {bp += 4;
prop = (int)*(int *) bp; bp += 4;
} break;
- }};
+ }};
if(!This) throw wxe_badarg(0);
wxSizerItem * Result = (wxSizerItem*)This->AddStretchSpacer(prop);
rt.addRef(getRef((void *)Result,memenv), "wxSizerItem");
- break;
+ break;
}
-case wxSizer_CalcMin: { // wxSizer::CalcMin
+case wxSizer_CalcMin: { // wxSizer::CalcMin
wxSizer *This = (wxSizer *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
wxSize Result = This->CalcMin();
rt.add(Result);
- break;
+ break;
}
-case wxSizer_Clear: { // wxSizer::Clear
+case wxSizer_Clear: { // wxSizer::Clear
bool delete_windows=false;
wxSizer *This = (wxSizer *) getPtr(bp,memenv); bp += 4;
bp += 4; /* Align */
- while( * (int*) bp) { switch (* (int*) bp) {
+ while( * (int*) bp) { switch (* (int*) bp) {
case 1: {bp += 4;
delete_windows = *(bool *) bp; bp += 4;
} break;
- }};
+ }};
if(!This) throw wxe_badarg(0);
This->Clear(delete_windows);
- break;
+ break;
}
-case wxSizer_Detach_1_2: { // wxSizer::Detach
+case wxSizer_Detach_1_2: { // wxSizer::Detach
wxSizer *This = (wxSizer *) getPtr(bp,memenv); bp += 4;
wxWindow * window = (wxWindow *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
bool Result = This->Detach(window);
rt.addBool(Result);
- break;
+ break;
}
-case wxSizer_Detach_1_1: { // wxSizer::Detach
+case wxSizer_Detach_1_1: { // wxSizer::Detach
wxSizer *This = (wxSizer *) getPtr(bp,memenv); bp += 4;
wxSizer *sizer = (wxSizer *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
bool Result = This->Detach(sizer);
rt.addBool(Result);
- break;
+ break;
}
-case wxSizer_Detach_1_0: { // wxSizer::Detach
+case wxSizer_Detach_1_0: { // wxSizer::Detach
wxSizer *This = (wxSizer *) getPtr(bp,memenv); bp += 4;
int * index = (int *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
bool Result = This->Detach((int) *index);
rt.addBool(Result);
- break;
+ break;
}
-case wxSizer_Fit: { // wxSizer::Fit
+case wxSizer_Fit: { // wxSizer::Fit
wxSizer *This = (wxSizer *) getPtr(bp,memenv); bp += 4;
wxWindow *window = (wxWindow *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
wxSize Result = This->Fit(window);
rt.add(Result);
- break;
+ break;
}
-case wxSizer_FitInside: { // wxSizer::FitInside
+case wxSizer_FitInside: { // wxSizer::FitInside
wxSizer *This = (wxSizer *) getPtr(bp,memenv); bp += 4;
wxWindow *window = (wxWindow *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
This->FitInside(window);
- break;
+ break;
}
-case wxSizer_GetChildren: { // wxSizer::GetChildren
+case wxSizer_GetChildren: { // wxSizer::GetChildren
wxSizer *This = (wxSizer *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
wxSizerItemList Result = This->GetChildren();
@@ -11177,102 +11177,102 @@ case wxSizer_GetChildren: { // wxSizer::GetChildren
wxSizerItem * ResultTmp = *it;
rt.addRef(getRef((void *)ResultTmp,memenv), "wxSizerItem"); i++;}
rt.endList(Result.GetCount());
- break;
+ break;
}
-case wxSizer_GetItem_2_1: { // wxSizer::GetItem
+case wxSizer_GetItem_2_1: { // wxSizer::GetItem
bool recursive=false;
wxSizer *This = (wxSizer *) getPtr(bp,memenv); bp += 4;
wxWindow * window = (wxWindow *) getPtr(bp,memenv); bp += 4;
- while( * (int*) bp) { switch (* (int*) bp) {
+ while( * (int*) bp) { switch (* (int*) bp) {
case 1: {bp += 4;
recursive = *(bool *) bp; bp += 4;
} break;
- }};
+ }};
if(!This) throw wxe_badarg(0);
wxSizerItem * Result = (wxSizerItem*)This->GetItem(window,recursive);
rt.addRef(getRef((void *)Result,memenv), "wxSizerItem");
- break;
+ break;
}
-case wxSizer_GetItem_2_0: { // wxSizer::GetItem
+case wxSizer_GetItem_2_0: { // wxSizer::GetItem
bool recursive=false;
wxSizer *This = (wxSizer *) getPtr(bp,memenv); bp += 4;
wxSizer *sizer = (wxSizer *) getPtr(bp,memenv); bp += 4;
- while( * (int*) bp) { switch (* (int*) bp) {
+ while( * (int*) bp) { switch (* (int*) bp) {
case 1: {bp += 4;
recursive = *(bool *) bp; bp += 4;
} break;
- }};
+ }};
if(!This) throw wxe_badarg(0);
wxSizerItem * Result = (wxSizerItem*)This->GetItem(sizer,recursive);
rt.addRef(getRef((void *)Result,memenv), "wxSizerItem");
- break;
+ break;
}
-case wxSizer_GetItem_1: { // wxSizer::GetItem
+case wxSizer_GetItem_1: { // wxSizer::GetItem
wxSizer *This = (wxSizer *) getPtr(bp,memenv); bp += 4;
int * index = (int *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
wxSizerItem * Result = (wxSizerItem*)This->GetItem((size_t) *index);
rt.addRef(getRef((void *)Result,memenv), "wxSizerItem");
- break;
+ break;
}
-case wxSizer_GetSize: { // wxSizer::GetSize
+case wxSizer_GetSize: { // wxSizer::GetSize
wxSizer *This = (wxSizer *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
wxSize Result = This->GetSize();
rt.add(Result);
- break;
+ break;
}
-case wxSizer_GetPosition: { // wxSizer::GetPosition
+case wxSizer_GetPosition: { // wxSizer::GetPosition
wxSizer *This = (wxSizer *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
wxPoint Result = This->GetPosition();
rt.add(Result);
- break;
+ break;
}
-case wxSizer_GetMinSize: { // wxSizer::GetMinSize
+case wxSizer_GetMinSize: { // wxSizer::GetMinSize
wxSizer *This = (wxSizer *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
wxSize Result = This->GetMinSize();
rt.add(Result);
- break;
+ break;
}
-case wxSizer_Hide_2_0: { // wxSizer::Hide
+case wxSizer_Hide_2_0: { // wxSizer::Hide
bool recursive=false;
wxSizer *This = (wxSizer *) getPtr(bp,memenv); bp += 4;
wxSizer *sizer = (wxSizer *) getPtr(bp,memenv); bp += 4;
- while( * (int*) bp) { switch (* (int*) bp) {
+ while( * (int*) bp) { switch (* (int*) bp) {
case 1: {bp += 4;
recursive = *(bool *) bp; bp += 4;
} break;
- }};
+ }};
if(!This) throw wxe_badarg(0);
bool Result = This->Hide(sizer,recursive);
rt.addBool(Result);
- break;
+ break;
}
-case wxSizer_Hide_2_1: { // wxSizer::Hide
+case wxSizer_Hide_2_1: { // wxSizer::Hide
bool recursive=false;
wxSizer *This = (wxSizer *) getPtr(bp,memenv); bp += 4;
wxWindow * window = (wxWindow *) getPtr(bp,memenv); bp += 4;
- while( * (int*) bp) { switch (* (int*) bp) {
+ while( * (int*) bp) { switch (* (int*) bp) {
case 1: {bp += 4;
recursive = *(bool *) bp; bp += 4;
} break;
- }};
+ }};
if(!This) throw wxe_badarg(0);
bool Result = This->Hide(window,recursive);
rt.addBool(Result);
- break;
+ break;
}
-case wxSizer_Hide_1: { // wxSizer::Hide
+case wxSizer_Hide_1: { // wxSizer::Hide
wxSizer *This = (wxSizer *) getPtr(bp,memenv); bp += 4;
int * index = (int *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
bool Result = This->Hide((size_t) *index);
rt.addBool(Result);
- break;
+ break;
}
-case wxSizer_Insert_3_1: { // wxSizer::Insert
+case wxSizer_Insert_3_1: { // wxSizer::Insert
int proportion=0;
int flag=0;
int border=0;
@@ -11281,7 +11281,7 @@ case wxSizer_Insert_3_1: { // wxSizer::Insert
int * index = (int *) bp; bp += 4;
wxWindow * window = (wxWindow *) getPtr(bp,memenv); bp += 4;
bp += 4; /* Align */
- while( * (int*) bp) { switch (* (int*) bp) {
+ while( * (int*) bp) { switch (* (int*) bp) {
case 1: {bp += 4;
proportion = (int)*(int *) bp; bp += 4;
} break;
@@ -11294,13 +11294,13 @@ case wxSizer_Insert_3_1: { // wxSizer::Insert
case 4: {bp += 4;
userData = (wxObject *) getPtr(bp,memenv); bp += 4;
} break;
- }};
+ }};
if(!This) throw wxe_badarg(0);
wxSizerItem * Result = (wxSizerItem*)This->Insert((size_t) *index,window,proportion,flag,border,userData);
rt.addRef(getRef((void *)Result,memenv), "wxSizerItem");
- break;
+ break;
}
-case wxSizer_Insert_3_0: { // wxSizer::Insert
+case wxSizer_Insert_3_0: { // wxSizer::Insert
int proportion=0;
int flag=0;
int border=0;
@@ -11309,7 +11309,7 @@ case wxSizer_Insert_3_0: { // wxSizer::Insert
int * index = (int *) bp; bp += 4;
wxSizer *sizer = (wxSizer *) getPtr(bp,memenv); bp += 4;
bp += 4; /* Align */
- while( * (int*) bp) { switch (* (int*) bp) {
+ while( * (int*) bp) { switch (* (int*) bp) {
case 1: {bp += 4;
proportion = (int)*(int *) bp; bp += 4;
} break;
@@ -11322,13 +11322,13 @@ case wxSizer_Insert_3_0: { // wxSizer::Insert
case 4: {bp += 4;
userData = (wxObject *) getPtr(bp,memenv); bp += 4;
} break;
- }};
+ }};
if(!This) throw wxe_badarg(0);
wxSizerItem * Result = (wxSizerItem*)This->Insert((size_t) *index,sizer,proportion,flag,border,userData);
rt.addRef(getRef((void *)Result,memenv), "wxSizerItem");
- break;
+ break;
}
-case wxSizer_Insert_4: { // wxSizer::Insert
+case wxSizer_Insert_4: { // wxSizer::Insert
int proportion=0;
int flag=0;
int border=0;
@@ -11337,7 +11337,7 @@ case wxSizer_Insert_4: { // wxSizer::Insert
int * index = (int *) bp; bp += 4;
int * width = (int *) bp; bp += 4;
int * height = (int *) bp; bp += 4;
- while( * (int*) bp) { switch (* (int*) bp) {
+ while( * (int*) bp) { switch (* (int*) bp) {
case 1: {bp += 4;
proportion = (int)*(int *) bp; bp += 4;
} break;
@@ -11350,13 +11350,13 @@ case wxSizer_Insert_4: { // wxSizer::Insert
case 4: {bp += 4;
userData = (wxObject *) getPtr(bp,memenv); bp += 4;
} break;
- }};
+ }};
if(!This) throw wxe_badarg(0);
wxSizerItem * Result = (wxSizerItem*)This->Insert((size_t) *index,(int) *width,(int) *height,proportion,flag,border,userData);
rt.addRef(getRef((void *)Result,memenv), "wxSizerItem");
- break;
+ break;
}
-case wxSizer_Insert_3_3: { // wxSizer::Insert
+case wxSizer_Insert_3_3: { // wxSizer::Insert
wxSizer *This = (wxSizer *) getPtr(bp,memenv); bp += 4;
int * index = (int *) bp; bp += 4;
wxWindow * window = (wxWindow *) getPtr(bp,memenv); bp += 4;
@@ -11364,9 +11364,9 @@ case wxSizer_Insert_3_3: { // wxSizer::Insert
if(!This) throw wxe_badarg(0);
wxSizerItem * Result = (wxSizerItem*)This->Insert((size_t) *index,window,*flags);
rt.addRef(getRef((void *)Result,memenv), "wxSizerItem");
- break;
+ break;
}
-case wxSizer_Insert_3_2: { // wxSizer::Insert
+case wxSizer_Insert_3_2: { // wxSizer::Insert
wxSizer *This = (wxSizer *) getPtr(bp,memenv); bp += 4;
int * index = (int *) bp; bp += 4;
wxSizer *sizer = (wxSizer *) getPtr(bp,memenv); bp += 4;
@@ -11374,78 +11374,78 @@ case wxSizer_Insert_3_2: { // wxSizer::Insert
if(!This) throw wxe_badarg(0);
wxSizerItem * Result = (wxSizerItem*)This->Insert((size_t) *index,sizer,*flags);
rt.addRef(getRef((void *)Result,memenv), "wxSizerItem");
- break;
+ break;
}
-case wxSizer_Insert_2: { // wxSizer::Insert
+case wxSizer_Insert_2: { // wxSizer::Insert
wxSizer *This = (wxSizer *) getPtr(bp,memenv); bp += 4;
int * index = (int *) bp; bp += 4;
wxSizerItem *item = (wxSizerItem *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
wxSizerItem * Result = (wxSizerItem*)This->Insert((size_t) *index,item);
rt.addRef(getRef((void *)Result,memenv), "wxSizerItem");
- break;
+ break;
}
-case wxSizer_InsertSpacer: { // wxSizer::InsertSpacer
+case wxSizer_InsertSpacer: { // wxSizer::InsertSpacer
wxSizer *This = (wxSizer *) getPtr(bp,memenv); bp += 4;
int * index = (int *) bp; bp += 4;
int * size = (int *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
wxSizerItem * Result = (wxSizerItem*)This->InsertSpacer((size_t) *index,(int) *size);
rt.addRef(getRef((void *)Result,memenv), "wxSizerItem");
- break;
+ break;
}
-case wxSizer_InsertStretchSpacer: { // wxSizer::InsertStretchSpacer
+case wxSizer_InsertStretchSpacer: { // wxSizer::InsertStretchSpacer
int prop=1;
wxSizer *This = (wxSizer *) getPtr(bp,memenv); bp += 4;
int * index = (int *) bp; bp += 4;
- while( * (int*) bp) { switch (* (int*) bp) {
+ while( * (int*) bp) { switch (* (int*) bp) {
case 1: {bp += 4;
prop = (int)*(int *) bp; bp += 4;
} break;
- }};
+ }};
if(!This) throw wxe_badarg(0);
wxSizerItem * Result = (wxSizerItem*)This->InsertStretchSpacer((size_t) *index,prop);
rt.addRef(getRef((void *)Result,memenv), "wxSizerItem");
- break;
+ break;
}
-case wxSizer_IsShown_1_2: { // wxSizer::IsShown
+case wxSizer_IsShown_1_2: { // wxSizer::IsShown
wxSizer *This = (wxSizer *) getPtr(bp,memenv); bp += 4;
wxWindow * window = (wxWindow *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
bool Result = This->IsShown(window);
rt.addBool(Result);
- break;
+ break;
}
-case wxSizer_IsShown_1_1: { // wxSizer::IsShown
+case wxSizer_IsShown_1_1: { // wxSizer::IsShown
wxSizer *This = (wxSizer *) getPtr(bp,memenv); bp += 4;
wxSizer *sizer = (wxSizer *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
bool Result = This->IsShown(sizer);
rt.addBool(Result);
- break;
+ break;
}
-case wxSizer_IsShown_1_0: { // wxSizer::IsShown
+case wxSizer_IsShown_1_0: { // wxSizer::IsShown
wxSizer *This = (wxSizer *) getPtr(bp,memenv); bp += 4;
int * index = (int *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
bool Result = This->IsShown((size_t) *index);
rt.addBool(Result);
- break;
+ break;
}
-case wxSizer_Layout: { // wxSizer::Layout
+case wxSizer_Layout: { // wxSizer::Layout
wxSizer *This = (wxSizer *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
This->Layout();
- break;
+ break;
}
-case wxSizer_Prepend_2_1: { // wxSizer::Prepend
+case wxSizer_Prepend_2_1: { // wxSizer::Prepend
int proportion=0;
int flag=0;
int border=0;
wxObject * userData=NULL;
wxSizer *This = (wxSizer *) getPtr(bp,memenv); bp += 4;
wxWindow * window = (wxWindow *) getPtr(bp,memenv); bp += 4;
- while( * (int*) bp) { switch (* (int*) bp) {
+ while( * (int*) bp) { switch (* (int*) bp) {
case 1: {bp += 4;
proportion = (int)*(int *) bp; bp += 4;
} break;
@@ -11458,20 +11458,20 @@ case wxSizer_Prepend_2_1: { // wxSizer::Prepend
case 4: {bp += 4;
userData = (wxObject *) getPtr(bp,memenv); bp += 4;
} break;
- }};
+ }};
if(!This) throw wxe_badarg(0);
wxSizerItem * Result = (wxSizerItem*)This->Prepend(window,proportion,flag,border,userData);
rt.addRef(getRef((void *)Result,memenv), "wxSizerItem");
- break;
+ break;
}
-case wxSizer_Prepend_2_0: { // wxSizer::Prepend
+case wxSizer_Prepend_2_0: { // wxSizer::Prepend
int proportion=0;
int flag=0;
int border=0;
wxObject * userData=NULL;
wxSizer *This = (wxSizer *) getPtr(bp,memenv); bp += 4;
wxSizer *sizer = (wxSizer *) getPtr(bp,memenv); bp += 4;
- while( * (int*) bp) { switch (* (int*) bp) {
+ while( * (int*) bp) { switch (* (int*) bp) {
case 1: {bp += 4;
proportion = (int)*(int *) bp; bp += 4;
} break;
@@ -11484,13 +11484,13 @@ case wxSizer_Prepend_2_0: { // wxSizer::Prepend
case 4: {bp += 4;
userData = (wxObject *) getPtr(bp,memenv); bp += 4;
} break;
- }};
+ }};
if(!This) throw wxe_badarg(0);
wxSizerItem * Result = (wxSizerItem*)This->Prepend(sizer,proportion,flag,border,userData);
rt.addRef(getRef((void *)Result,memenv), "wxSizerItem");
- break;
+ break;
}
-case wxSizer_Prepend_3: { // wxSizer::Prepend
+case wxSizer_Prepend_3: { // wxSizer::Prepend
int proportion=0;
int flag=0;
int border=0;
@@ -11499,7 +11499,7 @@ case wxSizer_Prepend_3: { // wxSizer::Prepend
int * width = (int *) bp; bp += 4;
int * height = (int *) bp; bp += 4;
bp += 4; /* Align */
- while( * (int*) bp) { switch (* (int*) bp) {
+ while( * (int*) bp) { switch (* (int*) bp) {
case 1: {bp += 4;
proportion = (int)*(int *) bp; bp += 4;
} break;
@@ -11512,124 +11512,124 @@ case wxSizer_Prepend_3: { // wxSizer::Prepend
case 4: {bp += 4;
userData = (wxObject *) getPtr(bp,memenv); bp += 4;
} break;
- }};
+ }};
if(!This) throw wxe_badarg(0);
wxSizerItem * Result = (wxSizerItem*)This->Prepend((int) *width,(int) *height,proportion,flag,border,userData);
rt.addRef(getRef((void *)Result,memenv), "wxSizerItem");
- break;
+ break;
}
-case wxSizer_Prepend_2_3: { // wxSizer::Prepend
+case wxSizer_Prepend_2_3: { // wxSizer::Prepend
wxSizer *This = (wxSizer *) getPtr(bp,memenv); bp += 4;
wxWindow * window = (wxWindow *) getPtr(bp,memenv); bp += 4;
wxSizerFlags *flags = (wxSizerFlags *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
wxSizerItem * Result = (wxSizerItem*)This->Prepend(window,*flags);
rt.addRef(getRef((void *)Result,memenv), "wxSizerItem");
- break;
+ break;
}
-case wxSizer_Prepend_2_2: { // wxSizer::Prepend
+case wxSizer_Prepend_2_2: { // wxSizer::Prepend
wxSizer *This = (wxSizer *) getPtr(bp,memenv); bp += 4;
wxSizer *sizer = (wxSizer *) getPtr(bp,memenv); bp += 4;
wxSizerFlags *flags = (wxSizerFlags *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
wxSizerItem * Result = (wxSizerItem*)This->Prepend(sizer,*flags);
rt.addRef(getRef((void *)Result,memenv), "wxSizerItem");
- break;
+ break;
}
-case wxSizer_Prepend_1: { // wxSizer::Prepend
+case wxSizer_Prepend_1: { // wxSizer::Prepend
wxSizer *This = (wxSizer *) getPtr(bp,memenv); bp += 4;
wxSizerItem *item = (wxSizerItem *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
wxSizerItem * Result = (wxSizerItem*)This->Prepend(item);
rt.addRef(getRef((void *)Result,memenv), "wxSizerItem");
- break;
+ break;
}
-case wxSizer_PrependSpacer: { // wxSizer::PrependSpacer
+case wxSizer_PrependSpacer: { // wxSizer::PrependSpacer
wxSizer *This = (wxSizer *) getPtr(bp,memenv); bp += 4;
int * size = (int *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
wxSizerItem * Result = (wxSizerItem*)This->PrependSpacer((int) *size);
rt.addRef(getRef((void *)Result,memenv), "wxSizerItem");
- break;
+ break;
}
-case wxSizer_PrependStretchSpacer: { // wxSizer::PrependStretchSpacer
+case wxSizer_PrependStretchSpacer: { // wxSizer::PrependStretchSpacer
int prop=1;
wxSizer *This = (wxSizer *) getPtr(bp,memenv); bp += 4;
bp += 4; /* Align */
- while( * (int*) bp) { switch (* (int*) bp) {
+ while( * (int*) bp) { switch (* (int*) bp) {
case 1: {bp += 4;
prop = (int)*(int *) bp; bp += 4;
} break;
- }};
+ }};
if(!This) throw wxe_badarg(0);
wxSizerItem * Result = (wxSizerItem*)This->PrependStretchSpacer(prop);
rt.addRef(getRef((void *)Result,memenv), "wxSizerItem");
- break;
+ break;
}
-case wxSizer_RecalcSizes: { // wxSizer::RecalcSizes
+case wxSizer_RecalcSizes: { // wxSizer::RecalcSizes
wxSizer *This = (wxSizer *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
This->RecalcSizes();
- break;
+ break;
}
-case wxSizer_Remove_1_1: { // wxSizer::Remove
+case wxSizer_Remove_1_1: { // wxSizer::Remove
wxSizer *This = (wxSizer *) getPtr(bp,memenv); bp += 4;
wxSizer *sizer = (wxSizer *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
bool Result = This->Remove(sizer);
rt.addBool(Result);
- break;
+ break;
}
-case wxSizer_Remove_1_0: { // wxSizer::Remove
+case wxSizer_Remove_1_0: { // wxSizer::Remove
wxSizer *This = (wxSizer *) getPtr(bp,memenv); bp += 4;
int * index = (int *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
bool Result = This->Remove((int) *index);
rt.addBool(Result);
- break;
+ break;
}
-case wxSizer_Replace_3_1: { // wxSizer::Replace
+case wxSizer_Replace_3_1: { // wxSizer::Replace
bool recursive=false;
wxSizer *This = (wxSizer *) getPtr(bp,memenv); bp += 4;
wxWindow * oldwin = (wxWindow *) getPtr(bp,memenv); bp += 4;
wxWindow * newwin = (wxWindow *) getPtr(bp,memenv); bp += 4;
bp += 4; /* Align */
- while( * (int*) bp) { switch (* (int*) bp) {
+ while( * (int*) bp) { switch (* (int*) bp) {
case 1: {bp += 4;
recursive = *(bool *) bp; bp += 4;
} break;
- }};
+ }};
if(!This) throw wxe_badarg(0);
bool Result = This->Replace(oldwin,newwin,recursive);
rt.addBool(Result);
- break;
+ break;
}
-case wxSizer_Replace_3_0: { // wxSizer::Replace
+case wxSizer_Replace_3_0: { // wxSizer::Replace
bool recursive=false;
wxSizer *This = (wxSizer *) getPtr(bp,memenv); bp += 4;
wxSizer *oldsz = (wxSizer *) getPtr(bp,memenv); bp += 4;
wxSizer *newsz = (wxSizer *) getPtr(bp,memenv); bp += 4;
bp += 4; /* Align */
- while( * (int*) bp) { switch (* (int*) bp) {
+ while( * (int*) bp) { switch (* (int*) bp) {
case 1: {bp += 4;
recursive = *(bool *) bp; bp += 4;
} break;
- }};
+ }};
if(!This) throw wxe_badarg(0);
bool Result = This->Replace(oldsz,newsz,recursive);
rt.addBool(Result);
- break;
+ break;
}
-case wxSizer_Replace_2: { // wxSizer::Replace
+case wxSizer_Replace_2: { // wxSizer::Replace
wxSizer *This = (wxSizer *) getPtr(bp,memenv); bp += 4;
int * index = (int *) bp; bp += 4;
wxSizerItem *newitem = (wxSizerItem *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
bool Result = This->Replace((size_t) *index,newitem);
rt.addBool(Result);
- break;
+ break;
}
-case wxSizer_SetDimension: { // wxSizer::SetDimension
+case wxSizer_SetDimension: { // wxSizer::SetDimension
wxSizer *This = (wxSizer *) getPtr(bp,memenv); bp += 4;
int * x = (int *) bp; bp += 4;
int * y = (int *) bp; bp += 4;
@@ -11637,26 +11637,26 @@ case wxSizer_SetDimension: { // wxSizer::SetDimension
int * height = (int *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
This->SetDimension((int) *x,(int) *y,(int) *width,(int) *height);
- break;
+ break;
}
-case wxSizer_SetMinSize_2: { // wxSizer::SetMinSize
+case wxSizer_SetMinSize_2: { // wxSizer::SetMinSize
wxSizer *This = (wxSizer *) getPtr(bp,memenv); bp += 4;
int * width = (int *) bp; bp += 4;
int * height = (int *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
This->SetMinSize((int) *width,(int) *height);
- break;
+ break;
}
-case wxSizer_SetMinSize_1: { // wxSizer::SetMinSize
+case wxSizer_SetMinSize_1: { // wxSizer::SetMinSize
wxSizer *This = (wxSizer *) getPtr(bp,memenv); bp += 4;
int * sizeW = (int *) bp; bp += 4;
int * sizeH = (int *) bp; bp += 4;
wxSize size = wxSize(*sizeW,*sizeH);
if(!This) throw wxe_badarg(0);
This->SetMinSize(size);
- break;
+ break;
}
-case wxSizer_SetItemMinSize_3_2: { // wxSizer::SetItemMinSize
+case wxSizer_SetItemMinSize_3_2: { // wxSizer::SetItemMinSize
wxSizer *This = (wxSizer *) getPtr(bp,memenv); bp += 4;
wxWindow * window = (wxWindow *) getPtr(bp,memenv); bp += 4;
int * width = (int *) bp; bp += 4;
@@ -11664,9 +11664,9 @@ case wxSizer_SetItemMinSize_3_2: { // wxSizer::SetItemMinSize
if(!This) throw wxe_badarg(0);
bool Result = This->SetItemMinSize(window,(int) *width,(int) *height);
rt.addBool(Result);
- break;
+ break;
}
-case wxSizer_SetItemMinSize_2_2: { // wxSizer::SetItemMinSize
+case wxSizer_SetItemMinSize_2_2: { // wxSizer::SetItemMinSize
wxSizer *This = (wxSizer *) getPtr(bp,memenv); bp += 4;
wxWindow * window = (wxWindow *) getPtr(bp,memenv); bp += 4;
int * sizeW = (int *) bp; bp += 4;
@@ -11675,9 +11675,9 @@ case wxSizer_SetItemMinSize_2_2: { // wxSizer::SetItemMinSize
if(!This) throw wxe_badarg(0);
bool Result = This->SetItemMinSize(window,size);
rt.addBool(Result);
- break;
+ break;
}
-case wxSizer_SetItemMinSize_3_1: { // wxSizer::SetItemMinSize
+case wxSizer_SetItemMinSize_3_1: { // wxSizer::SetItemMinSize
wxSizer *This = (wxSizer *) getPtr(bp,memenv); bp += 4;
wxSizer *sizer = (wxSizer *) getPtr(bp,memenv); bp += 4;
int * width = (int *) bp; bp += 4;
@@ -11685,9 +11685,9 @@ case wxSizer_SetItemMinSize_3_1: { // wxSizer::SetItemMinSize
if(!This) throw wxe_badarg(0);
bool Result = This->SetItemMinSize(sizer,(int) *width,(int) *height);
rt.addBool(Result);
- break;
+ break;
}
-case wxSizer_SetItemMinSize_2_1: { // wxSizer::SetItemMinSize
+case wxSizer_SetItemMinSize_2_1: { // wxSizer::SetItemMinSize
wxSizer *This = (wxSizer *) getPtr(bp,memenv); bp += 4;
wxSizer *sizer = (wxSizer *) getPtr(bp,memenv); bp += 4;
int * sizeW = (int *) bp; bp += 4;
@@ -11696,9 +11696,9 @@ case wxSizer_SetItemMinSize_2_1: { // wxSizer::SetItemMinSize
if(!This) throw wxe_badarg(0);
bool Result = This->SetItemMinSize(sizer,size);
rt.addBool(Result);
- break;
+ break;
}
-case wxSizer_SetItemMinSize_3_0: { // wxSizer::SetItemMinSize
+case wxSizer_SetItemMinSize_3_0: { // wxSizer::SetItemMinSize
wxSizer *This = (wxSizer *) getPtr(bp,memenv); bp += 4;
int * index = (int *) bp; bp += 4;
int * width = (int *) bp; bp += 4;
@@ -11706,9 +11706,9 @@ case wxSizer_SetItemMinSize_3_0: { // wxSizer::SetItemMinSize
if(!This) throw wxe_badarg(0);
bool Result = This->SetItemMinSize((size_t) *index,(int) *width,(int) *height);
rt.addBool(Result);
- break;
+ break;
}
-case wxSizer_SetItemMinSize_2_0: { // wxSizer::SetItemMinSize
+case wxSizer_SetItemMinSize_2_0: { // wxSizer::SetItemMinSize
wxSizer *This = (wxSizer *) getPtr(bp,memenv); bp += 4;
int * index = (int *) bp; bp += 4;
int * sizeW = (int *) bp; bp += 4;
@@ -11717,172 +11717,172 @@ case wxSizer_SetItemMinSize_2_0: { // wxSizer::SetItemMinSize
if(!This) throw wxe_badarg(0);
bool Result = This->SetItemMinSize((size_t) *index,size);
rt.addBool(Result);
- break;
+ break;
}
-case wxSizer_SetSizeHints: { // wxSizer::SetSizeHints
+case wxSizer_SetSizeHints: { // wxSizer::SetSizeHints
wxSizer *This = (wxSizer *) getPtr(bp,memenv); bp += 4;
wxWindow *window = (wxWindow *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
This->SetSizeHints(window);
- break;
+ break;
}
-case wxSizer_SetVirtualSizeHints: { // wxSizer::SetVirtualSizeHints
+case wxSizer_SetVirtualSizeHints: { // wxSizer::SetVirtualSizeHints
wxSizer *This = (wxSizer *) getPtr(bp,memenv); bp += 4;
wxWindow *window = (wxWindow *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
This->SetVirtualSizeHints(window);
- break;
+ break;
}
-case wxSizer_Show_2_2: { // wxSizer::Show
+case wxSizer_Show_2_2: { // wxSizer::Show
bool show=true;
bool recursive=false;
wxSizer *This = (wxSizer *) getPtr(bp,memenv); bp += 4;
wxWindow * window = (wxWindow *) getPtr(bp,memenv); bp += 4;
- while( * (int*) bp) { switch (* (int*) bp) {
+ while( * (int*) bp) { switch (* (int*) bp) {
case 1: {bp += 4;
show = *(bool *) bp; bp += 4;
} break;
case 2: {bp += 4;
recursive = *(bool *) bp; bp += 4;
} break;
- }};
+ }};
if(!This) throw wxe_badarg(0);
bool Result = This->Show(window,show,recursive);
rt.addBool(Result);
- break;
+ break;
}
-case wxSizer_Show_2_1: { // wxSizer::Show
+case wxSizer_Show_2_1: { // wxSizer::Show
bool show=true;
bool recursive=false;
wxSizer *This = (wxSizer *) getPtr(bp,memenv); bp += 4;
wxSizer *sizer = (wxSizer *) getPtr(bp,memenv); bp += 4;
- while( * (int*) bp) { switch (* (int*) bp) {
+ while( * (int*) bp) { switch (* (int*) bp) {
case 1: {bp += 4;
show = *(bool *) bp; bp += 4;
} break;
case 2: {bp += 4;
recursive = *(bool *) bp; bp += 4;
} break;
- }};
+ }};
if(!This) throw wxe_badarg(0);
bool Result = This->Show(sizer,show,recursive);
rt.addBool(Result);
- break;
+ break;
}
-case wxSizer_Show_2_0: { // wxSizer::Show
+case wxSizer_Show_2_0: { // wxSizer::Show
bool show=true;
wxSizer *This = (wxSizer *) getPtr(bp,memenv); bp += 4;
int * index = (int *) bp; bp += 4;
- while( * (int*) bp) { switch (* (int*) bp) {
+ while( * (int*) bp) { switch (* (int*) bp) {
case 1: {bp += 4;
show = *(bool *) bp; bp += 4;
} break;
- }};
+ }};
if(!This) throw wxe_badarg(0);
bool Result = This->Show((size_t) *index,show);
rt.addBool(Result);
- break;
+ break;
}
-case wxSizer_Show_1: { // wxSizer::Show
+case wxSizer_Show_1: { // wxSizer::Show
wxSizer *This = (wxSizer *) getPtr(bp,memenv); bp += 4;
bool * show = (bool *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
This->Show((bool) *show);
- break;
+ break;
}
-case wxSizerFlags_new: { // wxSizerFlags::wxSizerFlags
+case wxSizerFlags_new: { // wxSizerFlags::wxSizerFlags
int proportion=0;
- while( * (int*) bp) { switch (* (int*) bp) {
+ while( * (int*) bp) { switch (* (int*) bp) {
case 1: {bp += 4;
proportion = (int)*(int *) bp; bp += 4;
} break;
- }};
+ }};
wxSizerFlags * Result = new wxSizerFlags(proportion);
newPtr((void *) Result, 72, memenv);
rt.addRef(getRef((void *)Result,memenv), "wxSizerFlags");
- break;
+ break;
}
-case wxSizerFlags_Align: { // wxSizerFlags::Align
+case wxSizerFlags_Align: { // wxSizerFlags::Align
wxSizerFlags *This = (wxSizerFlags *) getPtr(bp,memenv); bp += 4;
int * alignment = (int *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
wxSizerFlags * Result = &This->Align((int) *alignment);
rt.addRef(getRef((void *)Result,memenv), "wxSizerFlags");
- break;
+ break;
}
-case wxSizerFlags_Border_2: { // wxSizerFlags::Border
+case wxSizerFlags_Border_2: { // wxSizerFlags::Border
wxSizerFlags *This = (wxSizerFlags *) getPtr(bp,memenv); bp += 4;
int * direction = (int *) bp; bp += 4;
int * borderInPixels = (int *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
wxSizerFlags * Result = &This->Border((int) *direction,(int) *borderInPixels);
rt.addRef(getRef((void *)Result,memenv), "wxSizerFlags");
- break;
+ break;
}
-case wxSizerFlags_Border_1: { // wxSizerFlags::Border
+case wxSizerFlags_Border_1: { // wxSizerFlags::Border
int direction=wxALL;
wxSizerFlags *This = (wxSizerFlags *) getPtr(bp,memenv); bp += 4;
bp += 4; /* Align */
- while( * (int*) bp) { switch (* (int*) bp) {
+ while( * (int*) bp) { switch (* (int*) bp) {
case 1: {bp += 4;
direction = (int)*(int *) bp; bp += 4;
} break;
- }};
+ }};
if(!This) throw wxe_badarg(0);
wxSizerFlags * Result = &This->Border(direction);
rt.addRef(getRef((void *)Result,memenv), "wxSizerFlags");
- break;
+ break;
}
-case wxSizerFlags_Center: { // wxSizerFlags::Center
+case wxSizerFlags_Center: { // wxSizerFlags::Center
wxSizerFlags *This = (wxSizerFlags *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
wxSizerFlags * Result = &This->Center();
rt.addRef(getRef((void *)Result,memenv), "wxSizerFlags");
- break;
+ break;
}
-case wxSizerFlags_Centre: { // wxSizerFlags::Centre
+case wxSizerFlags_Centre: { // wxSizerFlags::Centre
wxSizerFlags *This = (wxSizerFlags *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
wxSizerFlags * Result = &This->Centre();
rt.addRef(getRef((void *)Result,memenv), "wxSizerFlags");
- break;
+ break;
}
-case wxSizerFlags_Expand: { // wxSizerFlags::Expand
+case wxSizerFlags_Expand: { // wxSizerFlags::Expand
wxSizerFlags *This = (wxSizerFlags *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
wxSizerFlags * Result = &This->Expand();
rt.addRef(getRef((void *)Result,memenv), "wxSizerFlags");
- break;
+ break;
}
-case wxSizerFlags_Left: { // wxSizerFlags::Left
+case wxSizerFlags_Left: { // wxSizerFlags::Left
wxSizerFlags *This = (wxSizerFlags *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
wxSizerFlags * Result = &This->Left();
rt.addRef(getRef((void *)Result,memenv), "wxSizerFlags");
- break;
+ break;
}
-case wxSizerFlags_Proportion: { // wxSizerFlags::Proportion
+case wxSizerFlags_Proportion: { // wxSizerFlags::Proportion
wxSizerFlags *This = (wxSizerFlags *) getPtr(bp,memenv); bp += 4;
int * proportion = (int *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
wxSizerFlags * Result = &This->Proportion((int) *proportion);
rt.addRef(getRef((void *)Result,memenv), "wxSizerFlags");
- break;
+ break;
}
-case wxSizerFlags_Right: { // wxSizerFlags::Right
+case wxSizerFlags_Right: { // wxSizerFlags::Right
wxSizerFlags *This = (wxSizerFlags *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
wxSizerFlags * Result = &This->Right();
rt.addRef(getRef((void *)Result,memenv), "wxSizerFlags");
- break;
+ break;
}
-case wxSizerFlags_destroy: { // wxSizerFlags::destroy
+case wxSizerFlags_destroy: { // wxSizerFlags::destroy
wxSizerFlags *This = (wxSizerFlags *) getPtr(bp,memenv); bp += 4;
if(This) { ((WxeApp *) wxTheApp)->clearPtr((void *) This);
delete This;}
- break;
+ break;
}
-case wxSizerItem_new_5_1: { // wxSizerItem::wxSizerItem
+case wxSizerItem_new_5_1: { // wxSizerItem::wxSizerItem
wxWindow * window = (wxWindow *) getPtr(bp,memenv); bp += 4;
int * proportion = (int *) bp; bp += 4;
int * flag = (int *) bp; bp += 4;
@@ -11891,17 +11891,17 @@ case wxSizerItem_new_5_1: { // wxSizerItem::wxSizerItem
wxSizerItem * Result = new EwxSizerItem(window,(int) *proportion,(int) *flag,(int) *border,userData);
newPtr((void *) Result, 1, memenv);
rt.addRef(getRef((void *)Result,memenv), "wxSizerItem");
- break;
+ break;
}
-case wxSizerItem_new_2_1: { // wxSizerItem::wxSizerItem
+case wxSizerItem_new_2_1: { // wxSizerItem::wxSizerItem
wxWindow * window = (wxWindow *) getPtr(bp,memenv); bp += 4;
wxSizerFlags *flags = (wxSizerFlags *) getPtr(bp,memenv); bp += 4;
wxSizerItem * Result = new EwxSizerItem(window,*flags);
newPtr((void *) Result, 1, memenv);
rt.addRef(getRef((void *)Result,memenv), "wxSizerItem");
- break;
+ break;
}
-case wxSizerItem_new_5_0: { // wxSizerItem::wxSizerItem
+case wxSizerItem_new_5_0: { // wxSizerItem::wxSizerItem
wxSizer *sizer = (wxSizer *) getPtr(bp,memenv); bp += 4;
int * proportion = (int *) bp; bp += 4;
int * flag = (int *) bp; bp += 4;
@@ -11910,17 +11910,17 @@ case wxSizerItem_new_5_0: { // wxSizerItem::wxSizerItem
wxSizerItem * Result = new EwxSizerItem(sizer,(int) *proportion,(int) *flag,(int) *border,userData);
newPtr((void *) Result, 1, memenv);
rt.addRef(getRef((void *)Result,memenv), "wxSizerItem");
- break;
+ break;
}
-case wxSizerItem_new_2_0: { // wxSizerItem::wxSizerItem
+case wxSizerItem_new_2_0: { // wxSizerItem::wxSizerItem
wxSizer *sizer = (wxSizer *) getPtr(bp,memenv); bp += 4;
wxSizerFlags *flags = (wxSizerFlags *) getPtr(bp,memenv); bp += 4;
wxSizerItem * Result = new EwxSizerItem(sizer,*flags);
newPtr((void *) Result, 1, memenv);
rt.addRef(getRef((void *)Result,memenv), "wxSizerItem");
- break;
+ break;
}
-case wxSizerItem_new_6: { // wxSizerItem::wxSizerItem
+case wxSizerItem_new_6: { // wxSizerItem::wxSizerItem
int * width = (int *) bp; bp += 4;
int * height = (int *) bp; bp += 4;
int * proportion = (int *) bp; bp += 4;
@@ -11930,162 +11930,162 @@ case wxSizerItem_new_6: { // wxSizerItem::wxSizerItem
wxSizerItem * Result = new EwxSizerItem((int) *width,(int) *height,(int) *proportion,(int) *flag,(int) *border,userData);
newPtr((void *) Result, 1, memenv);
rt.addRef(getRef((void *)Result,memenv), "wxSizerItem");
- break;
+ break;
}
-case wxSizerItem_new_3: { // wxSizerItem::wxSizerItem
+case wxSizerItem_new_3: { // wxSizerItem::wxSizerItem
int * width = (int *) bp; bp += 4;
int * height = (int *) bp; bp += 4;
wxSizerFlags *flags = (wxSizerFlags *) getPtr(bp,memenv); bp += 4;
wxSizerItem * Result = new EwxSizerItem((int) *width,(int) *height,*flags);
newPtr((void *) Result, 1, memenv);
rt.addRef(getRef((void *)Result,memenv), "wxSizerItem");
- break;
+ break;
}
-case wxSizerItem_new_0: { // wxSizerItem::wxSizerItem
+case wxSizerItem_new_0: { // wxSizerItem::wxSizerItem
wxSizerItem * Result = new EwxSizerItem();
newPtr((void *) Result, 1, memenv);
rt.addRef(getRef((void *)Result,memenv), "wxSizerItem");
- break;
+ break;
}
-case wxSizerItem_CalcMin: { // wxSizerItem::CalcMin
+case wxSizerItem_CalcMin: { // wxSizerItem::CalcMin
wxSizerItem *This = (wxSizerItem *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
wxSize Result = This->CalcMin();
rt.add(Result);
- break;
+ break;
}
-case wxSizerItem_DeleteWindows: { // wxSizerItem::DeleteWindows
+case wxSizerItem_DeleteWindows: { // wxSizerItem::DeleteWindows
wxSizerItem *This = (wxSizerItem *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
This->DeleteWindows();
- break;
+ break;
}
-case wxSizerItem_DetachSizer: { // wxSizerItem::DetachSizer
+case wxSizerItem_DetachSizer: { // wxSizerItem::DetachSizer
wxSizerItem *This = (wxSizerItem *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
This->DetachSizer();
- break;
+ break;
}
-case wxSizerItem_GetBorder: { // wxSizerItem::GetBorder
+case wxSizerItem_GetBorder: { // wxSizerItem::GetBorder
wxSizerItem *This = (wxSizerItem *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
int Result = This->GetBorder();
rt.addInt(Result);
- break;
+ break;
}
-case wxSizerItem_GetFlag: { // wxSizerItem::GetFlag
+case wxSizerItem_GetFlag: { // wxSizerItem::GetFlag
wxSizerItem *This = (wxSizerItem *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
int Result = This->GetFlag();
rt.addInt(Result);
- break;
+ break;
}
-case wxSizerItem_GetMinSize: { // wxSizerItem::GetMinSize
+case wxSizerItem_GetMinSize: { // wxSizerItem::GetMinSize
wxSizerItem *This = (wxSizerItem *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
wxSize Result = This->GetMinSize();
rt.add(Result);
- break;
+ break;
}
-case wxSizerItem_GetPosition: { // wxSizerItem::GetPosition
+case wxSizerItem_GetPosition: { // wxSizerItem::GetPosition
wxSizerItem *This = (wxSizerItem *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
wxPoint Result = This->GetPosition();
rt.add(Result);
- break;
+ break;
}
-case wxSizerItem_GetProportion: { // wxSizerItem::GetProportion
+case wxSizerItem_GetProportion: { // wxSizerItem::GetProportion
wxSizerItem *This = (wxSizerItem *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
int Result = This->GetProportion();
rt.addInt(Result);
- break;
+ break;
}
-case wxSizerItem_GetRatio: { // wxSizerItem::GetRatio
+case wxSizerItem_GetRatio: { // wxSizerItem::GetRatio
wxSizerItem *This = (wxSizerItem *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
float Result = This->GetRatio();
rt.addFloat(Result);
- break;
+ break;
}
-case wxSizerItem_GetRect: { // wxSizerItem::GetRect
+case wxSizerItem_GetRect: { // wxSizerItem::GetRect
wxSizerItem *This = (wxSizerItem *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
wxRect Result = This->GetRect();
rt.add(Result);
- break;
+ break;
}
-case wxSizerItem_GetSize: { // wxSizerItem::GetSize
+case wxSizerItem_GetSize: { // wxSizerItem::GetSize
wxSizerItem *This = (wxSizerItem *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
wxSize Result = This->GetSize();
rt.add(Result);
- break;
+ break;
}
-case wxSizerItem_GetSizer: { // wxSizerItem::GetSizer
+case wxSizerItem_GetSizer: { // wxSizerItem::GetSizer
wxSizerItem *This = (wxSizerItem *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
wxSizer * Result = (wxSizer*)This->GetSizer();
rt.addRef(getRef((void *)Result,memenv), "wxSizer");
- break;
+ break;
}
-case wxSizerItem_GetSpacer: { // wxSizerItem::GetSpacer
+case wxSizerItem_GetSpacer: { // wxSizerItem::GetSpacer
wxSizerItem *This = (wxSizerItem *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
wxSize Result = This->GetSpacer();
rt.add(Result);
- break;
+ break;
}
-case wxSizerItem_GetUserData: { // wxSizerItem::GetUserData
+case wxSizerItem_GetUserData: { // wxSizerItem::GetUserData
wxSizerItem *This = (wxSizerItem *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
wxObject * Result = (wxObject*)This->GetUserData();
rt.addRef(getRef((void *)Result,memenv), "wx");
- break;
+ break;
}
-case wxSizerItem_GetWindow: { // wxSizerItem::GetWindow
+case wxSizerItem_GetWindow: { // wxSizerItem::GetWindow
wxSizerItem *This = (wxSizerItem *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
wxWindow * Result = (wxWindow*)This->GetWindow();
rt.addRef(getRef((void *)Result,memenv), "wxWindow");
- break;
+ break;
}
-case wxSizerItem_IsSizer: { // wxSizerItem::IsSizer
+case wxSizerItem_IsSizer: { // wxSizerItem::IsSizer
wxSizerItem *This = (wxSizerItem *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
bool Result = This->IsSizer();
rt.addBool(Result);
- break;
+ break;
}
-case wxSizerItem_IsShown: { // wxSizerItem::IsShown
+case wxSizerItem_IsShown: { // wxSizerItem::IsShown
wxSizerItem *This = (wxSizerItem *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
bool Result = This->IsShown();
rt.addBool(Result);
- break;
+ break;
}
-case wxSizerItem_IsSpacer: { // wxSizerItem::IsSpacer
+case wxSizerItem_IsSpacer: { // wxSizerItem::IsSpacer
wxSizerItem *This = (wxSizerItem *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
bool Result = This->IsSpacer();
rt.addBool(Result);
- break;
+ break;
}
-case wxSizerItem_IsWindow: { // wxSizerItem::IsWindow
+case wxSizerItem_IsWindow: { // wxSizerItem::IsWindow
wxSizerItem *This = (wxSizerItem *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
bool Result = This->IsWindow();
rt.addBool(Result);
- break;
+ break;
}
-case wxSizerItem_SetBorder: { // wxSizerItem::SetBorder
+case wxSizerItem_SetBorder: { // wxSizerItem::SetBorder
wxSizerItem *This = (wxSizerItem *) getPtr(bp,memenv); bp += 4;
int * border = (int *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
This->SetBorder((int) *border);
- break;
+ break;
}
-case wxSizerItem_SetDimension: { // wxSizerItem::SetDimension
+case wxSizerItem_SetDimension: { // wxSizerItem::SetDimension
wxSizerItem *This = (wxSizerItem *) getPtr(bp,memenv); bp += 4;
int * posX = (int *) bp; bp += 4;
int * posY = (int *) bp; bp += 4;
@@ -12095,155 +12095,155 @@ case wxSizerItem_SetDimension: { // wxSizerItem::SetDimension
wxSize size = wxSize(*sizeW,*sizeH);
if(!This) throw wxe_badarg(0);
This->SetDimension(pos,size);
- break;
+ break;
}
-case wxSizerItem_SetFlag: { // wxSizerItem::SetFlag
+case wxSizerItem_SetFlag: { // wxSizerItem::SetFlag
wxSizerItem *This = (wxSizerItem *) getPtr(bp,memenv); bp += 4;
int * flag = (int *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
This->SetFlag((int) *flag);
- break;
+ break;
}
-case wxSizerItem_SetInitSize: { // wxSizerItem::SetInitSize
+case wxSizerItem_SetInitSize: { // wxSizerItem::SetInitSize
wxSizerItem *This = (wxSizerItem *) getPtr(bp,memenv); bp += 4;
int * x = (int *) bp; bp += 4;
int * y = (int *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
This->SetInitSize((int) *x,(int) *y);
- break;
+ break;
}
-case wxSizerItem_SetMinSize_1: { // wxSizerItem::SetMinSize
+case wxSizerItem_SetMinSize_1: { // wxSizerItem::SetMinSize
wxSizerItem *This = (wxSizerItem *) getPtr(bp,memenv); bp += 4;
int * sizeW = (int *) bp; bp += 4;
int * sizeH = (int *) bp; bp += 4;
wxSize size = wxSize(*sizeW,*sizeH);
if(!This) throw wxe_badarg(0);
This->SetMinSize(size);
- break;
+ break;
}
-case wxSizerItem_SetMinSize_2: { // wxSizerItem::SetMinSize
+case wxSizerItem_SetMinSize_2: { // wxSizerItem::SetMinSize
wxSizerItem *This = (wxSizerItem *) getPtr(bp,memenv); bp += 4;
int * x = (int *) bp; bp += 4;
int * y = (int *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
This->SetMinSize((int) *x,(int) *y);
- break;
+ break;
}
-case wxSizerItem_SetProportion: { // wxSizerItem::SetProportion
+case wxSizerItem_SetProportion: { // wxSizerItem::SetProportion
wxSizerItem *This = (wxSizerItem *) getPtr(bp,memenv); bp += 4;
int * proportion = (int *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
This->SetProportion((int) *proportion);
- break;
+ break;
}
-case wxSizerItem_SetRatio_2: { // wxSizerItem::SetRatio
+case wxSizerItem_SetRatio_2: { // wxSizerItem::SetRatio
wxSizerItem *This = (wxSizerItem *) getPtr(bp,memenv); bp += 4;
int * width = (int *) bp; bp += 4;
int * height = (int *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
This->SetRatio((int) *width,(int) *height);
- break;
+ break;
}
-case wxSizerItem_SetRatio_1_1: { // wxSizerItem::SetRatio
+case wxSizerItem_SetRatio_1_1: { // wxSizerItem::SetRatio
wxSizerItem *This = (wxSizerItem *) getPtr(bp,memenv); bp += 4;
int * sizeW = (int *) bp; bp += 4;
int * sizeH = (int *) bp; bp += 4;
wxSize size = wxSize(*sizeW,*sizeH);
if(!This) throw wxe_badarg(0);
This->SetRatio(size);
- break;
+ break;
}
-case wxSizerItem_SetRatio_1_0: { // wxSizerItem::SetRatio
+case wxSizerItem_SetRatio_1_0: { // wxSizerItem::SetRatio
wxSizerItem *This = (wxSizerItem *) getPtr(bp,memenv); bp += 4;
float * ratio = (float *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
This->SetRatio((float) *ratio);
- break;
+ break;
}
-case wxSizerItem_SetSizer: { // wxSizerItem::SetSizer
+case wxSizerItem_SetSizer: { // wxSizerItem::SetSizer
wxSizerItem *This = (wxSizerItem *) getPtr(bp,memenv); bp += 4;
wxSizer *sizer = (wxSizer *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
This->SetSizer(sizer);
- break;
+ break;
}
-case wxSizerItem_SetSpacer_1: { // wxSizerItem::SetSpacer
+case wxSizerItem_SetSpacer_1: { // wxSizerItem::SetSpacer
wxSizerItem *This = (wxSizerItem *) getPtr(bp,memenv); bp += 4;
int * sizeW = (int *) bp; bp += 4;
int * sizeH = (int *) bp; bp += 4;
wxSize size = wxSize(*sizeW,*sizeH);
if(!This) throw wxe_badarg(0);
This->SetSpacer(size);
- break;
+ break;
}
-case wxSizerItem_SetSpacer_2: { // wxSizerItem::SetSpacer
+case wxSizerItem_SetSpacer_2: { // wxSizerItem::SetSpacer
wxSizerItem *This = (wxSizerItem *) getPtr(bp,memenv); bp += 4;
int * width = (int *) bp; bp += 4;
int * height = (int *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
This->SetSpacer((int) *width,(int) *height);
- break;
+ break;
}
-case wxSizerItem_SetWindow: { // wxSizerItem::SetWindow
+case wxSizerItem_SetWindow: { // wxSizerItem::SetWindow
wxSizerItem *This = (wxSizerItem *) getPtr(bp,memenv); bp += 4;
wxWindow *window = (wxWindow *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
This->SetWindow(window);
- break;
+ break;
}
-case wxSizerItem_Show: { // wxSizerItem::Show
+case wxSizerItem_Show: { // wxSizerItem::Show
wxSizerItem *This = (wxSizerItem *) getPtr(bp,memenv); bp += 4;
bool * show = (bool *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
This->Show((bool) *show);
- break;
+ break;
}
-case wxBoxSizer_new: { // wxBoxSizer::wxBoxSizer
+case wxBoxSizer_new: { // wxBoxSizer::wxBoxSizer
int * orient = (int *) bp; bp += 4;
wxBoxSizer * Result = new EwxBoxSizer((int) *orient);
newPtr((void *) Result, 1, memenv);
rt.addRef(getRef((void *)Result,memenv), "wxBoxSizer");
- break;
+ break;
}
-case wxBoxSizer_GetOrientation: { // wxBoxSizer::GetOrientation
+case wxBoxSizer_GetOrientation: { // wxBoxSizer::GetOrientation
wxBoxSizer *This = (wxBoxSizer *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
int Result = This->GetOrientation();
rt.addInt(Result);
- break;
+ break;
}
-case wxStaticBoxSizer_new_2: { // wxStaticBoxSizer::wxStaticBoxSizer
+case wxStaticBoxSizer_new_2: { // wxStaticBoxSizer::wxStaticBoxSizer
wxStaticBox *box = (wxStaticBox *) getPtr(bp,memenv); bp += 4;
int * orient = (int *) bp; bp += 4;
wxStaticBoxSizer * Result = new EwxStaticBoxSizer(box,(int) *orient);
newPtr((void *) Result, 1, memenv);
rt.addRef(getRef((void *)Result,memenv), "wxStaticBoxSizer");
- break;
+ break;
}
-case wxStaticBoxSizer_new_3: { // wxStaticBoxSizer::wxStaticBoxSizer
+case wxStaticBoxSizer_new_3: { // wxStaticBoxSizer::wxStaticBoxSizer
wxString label= wxEmptyString;
int * orient = (int *) bp; bp += 4;
wxWindow *win = (wxWindow *) getPtr(bp,memenv); bp += 4;
- while( * (int*) bp) { switch (* (int*) bp) {
+ while( * (int*) bp) { switch (* (int*) bp) {
case 1: {bp += 4;
int * labelLen = (int *) bp; bp += 4;
label = wxString(bp, wxConvUTF8);
bp += *labelLen+((8-((0+ *labelLen) & 7)) & 7);
} break;
- }};
+ }};
wxStaticBoxSizer * Result = new EwxStaticBoxSizer((int) *orient,win,label);
newPtr((void *) Result, 1, memenv);
rt.addRef(getRef((void *)Result,memenv), "wxStaticBoxSizer");
- break;
+ break;
}
-case wxStaticBoxSizer_GetStaticBox: { // wxStaticBoxSizer::GetStaticBox
+case wxStaticBoxSizer_GetStaticBox: { // wxStaticBoxSizer::GetStaticBox
wxStaticBoxSizer *This = (wxStaticBoxSizer *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
wxStaticBox * Result = (wxStaticBox*)This->GetStaticBox();
rt.addRef(getRef((void *)Result,memenv), "wxStaticBox");
- break;
+ break;
}
-case wxGridSizer_new_4: { // wxGridSizer::wxGridSizer
+case wxGridSizer_new_4: { // wxGridSizer::wxGridSizer
int * rows = (int *) bp; bp += 4;
int * cols = (int *) bp; bp += 4;
int * vgap = (int *) bp; bp += 4;
@@ -12251,83 +12251,83 @@ case wxGridSizer_new_4: { // wxGridSizer::wxGridSizer
wxGridSizer * Result = new EwxGridSizer((int) *rows,(int) *cols,(int) *vgap,(int) *hgap);
newPtr((void *) Result, 1, memenv);
rt.addRef(getRef((void *)Result,memenv), "wxGridSizer");
- break;
+ break;
}
-case wxGridSizer_new_2: { // wxGridSizer::wxGridSizer
+case wxGridSizer_new_2: { // wxGridSizer::wxGridSizer
int vgap=0;
int hgap=0;
int * cols = (int *) bp; bp += 4;
bp += 4; /* Align */
- while( * (int*) bp) { switch (* (int*) bp) {
+ while( * (int*) bp) { switch (* (int*) bp) {
case 1: {bp += 4;
vgap = (int)*(int *) bp; bp += 4;
} break;
case 2: {bp += 4;
hgap = (int)*(int *) bp; bp += 4;
} break;
- }};
+ }};
wxGridSizer * Result = new EwxGridSizer((int) *cols,vgap,hgap);
newPtr((void *) Result, 1, memenv);
rt.addRef(getRef((void *)Result,memenv), "wxGridSizer");
- break;
+ break;
}
-case wxGridSizer_GetCols: { // wxGridSizer::GetCols
+case wxGridSizer_GetCols: { // wxGridSizer::GetCols
wxGridSizer *This = (wxGridSizer *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
int Result = This->GetCols();
rt.addInt(Result);
- break;
+ break;
}
-case wxGridSizer_GetHGap: { // wxGridSizer::GetHGap
+case wxGridSizer_GetHGap: { // wxGridSizer::GetHGap
wxGridSizer *This = (wxGridSizer *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
int Result = This->GetHGap();
rt.addInt(Result);
- break;
+ break;
}
-case wxGridSizer_GetRows: { // wxGridSizer::GetRows
+case wxGridSizer_GetRows: { // wxGridSizer::GetRows
wxGridSizer *This = (wxGridSizer *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
int Result = This->GetRows();
rt.addInt(Result);
- break;
+ break;
}
-case wxGridSizer_GetVGap: { // wxGridSizer::GetVGap
+case wxGridSizer_GetVGap: { // wxGridSizer::GetVGap
wxGridSizer *This = (wxGridSizer *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
int Result = This->GetVGap();
rt.addInt(Result);
- break;
+ break;
}
-case wxGridSizer_SetCols: { // wxGridSizer::SetCols
+case wxGridSizer_SetCols: { // wxGridSizer::SetCols
wxGridSizer *This = (wxGridSizer *) getPtr(bp,memenv); bp += 4;
int * cols = (int *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
This->SetCols((int) *cols);
- break;
+ break;
}
-case wxGridSizer_SetHGap: { // wxGridSizer::SetHGap
+case wxGridSizer_SetHGap: { // wxGridSizer::SetHGap
wxGridSizer *This = (wxGridSizer *) getPtr(bp,memenv); bp += 4;
int * gap = (int *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
This->SetHGap((int) *gap);
- break;
+ break;
}
-case wxGridSizer_SetRows: { // wxGridSizer::SetRows
+case wxGridSizer_SetRows: { // wxGridSizer::SetRows
wxGridSizer *This = (wxGridSizer *) getPtr(bp,memenv); bp += 4;
int * rows = (int *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
This->SetRows((int) *rows);
- break;
+ break;
}
-case wxGridSizer_SetVGap: { // wxGridSizer::SetVGap
+case wxGridSizer_SetVGap: { // wxGridSizer::SetVGap
wxGridSizer *This = (wxGridSizer *) getPtr(bp,memenv); bp += 4;
int * gap = (int *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
This->SetVGap((int) *gap);
- break;
+ break;
}
-case wxFlexGridSizer_new_4: { // wxFlexGridSizer::wxFlexGridSizer
+case wxFlexGridSizer_new_4: { // wxFlexGridSizer::wxFlexGridSizer
int * rows = (int *) bp; bp += 4;
int * cols = (int *) bp; bp += 4;
int * vgap = (int *) bp; bp += 4;
@@ -12335,111 +12335,111 @@ case wxFlexGridSizer_new_4: { // wxFlexGridSizer::wxFlexGridSizer
wxFlexGridSizer * Result = new EwxFlexGridSizer((int) *rows,(int) *cols,(int) *vgap,(int) *hgap);
newPtr((void *) Result, 1, memenv);
rt.addRef(getRef((void *)Result,memenv), "wxFlexGridSizer");
- break;
+ break;
}
-case wxFlexGridSizer_new_2: { // wxFlexGridSizer::wxFlexGridSizer
+case wxFlexGridSizer_new_2: { // wxFlexGridSizer::wxFlexGridSizer
int vgap=0;
int hgap=0;
int * cols = (int *) bp; bp += 4;
bp += 4; /* Align */
- while( * (int*) bp) { switch (* (int*) bp) {
+ while( * (int*) bp) { switch (* (int*) bp) {
case 1: {bp += 4;
vgap = (int)*(int *) bp; bp += 4;
} break;
case 2: {bp += 4;
hgap = (int)*(int *) bp; bp += 4;
} break;
- }};
+ }};
wxFlexGridSizer * Result = new EwxFlexGridSizer((int) *cols,vgap,hgap);
newPtr((void *) Result, 1, memenv);
rt.addRef(getRef((void *)Result,memenv), "wxFlexGridSizer");
- break;
+ break;
}
-case wxFlexGridSizer_AddGrowableCol: { // wxFlexGridSizer::AddGrowableCol
+case wxFlexGridSizer_AddGrowableCol: { // wxFlexGridSizer::AddGrowableCol
int proportion=0;
wxFlexGridSizer *This = (wxFlexGridSizer *) getPtr(bp,memenv); bp += 4;
int * idx = (int *) bp; bp += 4;
- while( * (int*) bp) { switch (* (int*) bp) {
+ while( * (int*) bp) { switch (* (int*) bp) {
case 1: {bp += 4;
proportion = (int)*(int *) bp; bp += 4;
} break;
- }};
+ }};
if(!This) throw wxe_badarg(0);
This->AddGrowableCol((size_t) *idx,proportion);
- break;
+ break;
}
-case wxFlexGridSizer_AddGrowableRow: { // wxFlexGridSizer::AddGrowableRow
+case wxFlexGridSizer_AddGrowableRow: { // wxFlexGridSizer::AddGrowableRow
int proportion=0;
wxFlexGridSizer *This = (wxFlexGridSizer *) getPtr(bp,memenv); bp += 4;
int * idx = (int *) bp; bp += 4;
- while( * (int*) bp) { switch (* (int*) bp) {
+ while( * (int*) bp) { switch (* (int*) bp) {
case 1: {bp += 4;
proportion = (int)*(int *) bp; bp += 4;
} break;
- }};
+ }};
if(!This) throw wxe_badarg(0);
This->AddGrowableRow((size_t) *idx,proportion);
- break;
+ break;
}
-case wxFlexGridSizer_GetFlexibleDirection: { // wxFlexGridSizer::GetFlexibleDirection
+case wxFlexGridSizer_GetFlexibleDirection: { // wxFlexGridSizer::GetFlexibleDirection
wxFlexGridSizer *This = (wxFlexGridSizer *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
int Result = This->GetFlexibleDirection();
rt.addInt(Result);
- break;
+ break;
}
-case wxFlexGridSizer_GetNonFlexibleGrowMode: { // wxFlexGridSizer::GetNonFlexibleGrowMode
+case wxFlexGridSizer_GetNonFlexibleGrowMode: { // wxFlexGridSizer::GetNonFlexibleGrowMode
wxFlexGridSizer *This = (wxFlexGridSizer *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
int Result = This->GetNonFlexibleGrowMode();
rt.addInt(Result);
- break;
+ break;
}
-case wxFlexGridSizer_RemoveGrowableCol: { // wxFlexGridSizer::RemoveGrowableCol
+case wxFlexGridSizer_RemoveGrowableCol: { // wxFlexGridSizer::RemoveGrowableCol
wxFlexGridSizer *This = (wxFlexGridSizer *) getPtr(bp,memenv); bp += 4;
int * idx = (int *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
This->RemoveGrowableCol((size_t) *idx);
- break;
+ break;
}
-case wxFlexGridSizer_RemoveGrowableRow: { // wxFlexGridSizer::RemoveGrowableRow
+case wxFlexGridSizer_RemoveGrowableRow: { // wxFlexGridSizer::RemoveGrowableRow
wxFlexGridSizer *This = (wxFlexGridSizer *) getPtr(bp,memenv); bp += 4;
int * idx = (int *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
This->RemoveGrowableRow((size_t) *idx);
- break;
+ break;
}
-case wxFlexGridSizer_SetFlexibleDirection: { // wxFlexGridSizer::SetFlexibleDirection
+case wxFlexGridSizer_SetFlexibleDirection: { // wxFlexGridSizer::SetFlexibleDirection
wxFlexGridSizer *This = (wxFlexGridSizer *) getPtr(bp,memenv); bp += 4;
int * direction = (int *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
This->SetFlexibleDirection((int) *direction);
- break;
+ break;
}
-case wxFlexGridSizer_SetNonFlexibleGrowMode: { // wxFlexGridSizer::SetNonFlexibleGrowMode
+case wxFlexGridSizer_SetNonFlexibleGrowMode: { // wxFlexGridSizer::SetNonFlexibleGrowMode
wxFlexGridSizer *This = (wxFlexGridSizer *) getPtr(bp,memenv); bp += 4;
wxFlexSizerGrowMode mode = *(wxFlexSizerGrowMode *) bp; bp += 4;;
if(!This) throw wxe_badarg(0);
This->SetNonFlexibleGrowMode((wxFlexSizerGrowMode) mode);
- break;
+ break;
}
-case wxGridBagSizer_new: { // wxGridBagSizer::wxGridBagSizer
+case wxGridBagSizer_new: { // wxGridBagSizer::wxGridBagSizer
int vgap=0;
int hgap=0;
- while( * (int*) bp) { switch (* (int*) bp) {
+ while( * (int*) bp) { switch (* (int*) bp) {
case 1: {bp += 4;
vgap = (int)*(int *) bp; bp += 4;
} break;
case 2: {bp += 4;
hgap = (int)*(int *) bp; bp += 4;
} break;
- }};
+ }};
wxGridBagSizer * Result = new EwxGridBagSizer(vgap,hgap);
newPtr((void *) Result, 1, memenv);
rt.addRef(getRef((void *)Result,memenv), "wxGridBagSizer");
- break;
+ break;
}
-case wxGridBagSizer_Add_3_2: { // wxGridBagSizer::Add
+case wxGridBagSizer_Add_3_2: { // wxGridBagSizer::Add
wxGBSpan span= wxDefaultSpan;
int flag=0;
int border=0;
@@ -12449,7 +12449,7 @@ case wxGridBagSizer_Add_3_2: { // wxGridBagSizer::Add
int * posR = (int *) bp; bp += 4;
int * posC = (int *) bp; bp += 4;
wxGBPosition pos = wxGBPosition(*posR,*posC);
- while( * (int*) bp) { switch (* (int*) bp) {
+ while( * (int*) bp) { switch (* (int*) bp) {
case 1: {bp += 4;
int * spanRS = (int *) bp; bp += 4;
int * spanCS = (int *) bp; bp += 4;
@@ -12465,13 +12465,13 @@ case wxGridBagSizer_Add_3_2: { // wxGridBagSizer::Add
case 4: {bp += 4;
userData = (wxObject *) getPtr(bp,memenv); bp += 4;
} break;
- }};
+ }};
if(!This) throw wxe_badarg(0);
wxSizerItem * Result = (wxSizerItem*)This->Add(window,pos,span,flag,border,userData);
rt.addRef(getRef((void *)Result,memenv), "wxSizerItem");
- break;
+ break;
}
-case wxGridBagSizer_Add_3_1: { // wxGridBagSizer::Add
+case wxGridBagSizer_Add_3_1: { // wxGridBagSizer::Add
wxGBSpan span= wxDefaultSpan;
int flag=0;
int border=0;
@@ -12481,7 +12481,7 @@ case wxGridBagSizer_Add_3_1: { // wxGridBagSizer::Add
int * posR = (int *) bp; bp += 4;
int * posC = (int *) bp; bp += 4;
wxGBPosition pos = wxGBPosition(*posR,*posC);
- while( * (int*) bp) { switch (* (int*) bp) {
+ while( * (int*) bp) { switch (* (int*) bp) {
case 1: {bp += 4;
int * spanRS = (int *) bp; bp += 4;
int * spanCS = (int *) bp; bp += 4;
@@ -12497,13 +12497,13 @@ case wxGridBagSizer_Add_3_1: { // wxGridBagSizer::Add
case 4: {bp += 4;
userData = (wxObject *) getPtr(bp,memenv); bp += 4;
} break;
- }};
+ }};
if(!This) throw wxe_badarg(0);
wxSizerItem * Result = (wxSizerItem*)This->Add(sizer,pos,span,flag,border,userData);
rt.addRef(getRef((void *)Result,memenv), "wxSizerItem");
- break;
+ break;
}
-case wxGridBagSizer_Add_4: { // wxGridBagSizer::Add
+case wxGridBagSizer_Add_4: { // wxGridBagSizer::Add
wxGBSpan span= wxDefaultSpan;
int flag=0;
int border=0;
@@ -12515,7 +12515,7 @@ case wxGridBagSizer_Add_4: { // wxGridBagSizer::Add
int * posC = (int *) bp; bp += 4;
wxGBPosition pos = wxGBPosition(*posR,*posC);
bp += 4; /* Align */
- while( * (int*) bp) { switch (* (int*) bp) {
+ while( * (int*) bp) { switch (* (int*) bp) {
case 1: {bp += 4;
int * spanRS = (int *) bp; bp += 4;
int * spanCS = (int *) bp; bp += 4;
@@ -12531,28 +12531,28 @@ case wxGridBagSizer_Add_4: { // wxGridBagSizer::Add
case 4: {bp += 4;
userData = (wxObject *) getPtr(bp,memenv); bp += 4;
} break;
- }};
+ }};
if(!This) throw wxe_badarg(0);
wxSizerItem * Result = (wxSizerItem*)This->Add((int) *width,(int) *height,pos,span,flag,border,userData);
rt.addRef(getRef((void *)Result,memenv), "wxSizerItem");
- break;
+ break;
}
-case wxGridBagSizer_Add_1_0: { // wxGridBagSizer::Add
+case wxGridBagSizer_Add_1_0: { // wxGridBagSizer::Add
wxGridBagSizer *This = (wxGridBagSizer *) getPtr(bp,memenv); bp += 4;
wxGBSizerItem *item = (wxGBSizerItem *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
wxSizerItem * Result = (wxSizerItem*)This->Add(item);
rt.addRef(getRef((void *)Result,memenv), "wxSizerItem");
- break;
+ break;
}
-case wxGridBagSizer_Add_2_1: { // wxGridBagSizer::Add
+case wxGridBagSizer_Add_2_1: { // wxGridBagSizer::Add
int proportion=0;
int flag=0;
int border=0;
wxObject * userData=NULL;
wxGridBagSizer *This = (wxGridBagSizer *) getPtr(bp,memenv); bp += 4;
wxWindow * window = (wxWindow *) getPtr(bp,memenv); bp += 4;
- while( * (int*) bp) { switch (* (int*) bp) {
+ while( * (int*) bp) { switch (* (int*) bp) {
case 1: {bp += 4;
proportion = (int)*(int *) bp; bp += 4;
} break;
@@ -12565,20 +12565,20 @@ case wxGridBagSizer_Add_2_1: { // wxGridBagSizer::Add
case 4: {bp += 4;
userData = (wxObject *) getPtr(bp,memenv); bp += 4;
} break;
- }};
+ }};
if(!This) throw wxe_badarg(0);
wxSizerItem * Result = (wxSizerItem*)This->Add(window,proportion,flag,border,userData);
rt.addRef(getRef((void *)Result,memenv), "wxSizerItem");
- break;
+ break;
}
-case wxGridBagSizer_Add_2_0: { // wxGridBagSizer::Add
+case wxGridBagSizer_Add_2_0: { // wxGridBagSizer::Add
int proportion=0;
int flag=0;
int border=0;
wxObject * userData=NULL;
wxGridBagSizer *This = (wxGridBagSizer *) getPtr(bp,memenv); bp += 4;
wxSizer *sizer = (wxSizer *) getPtr(bp,memenv); bp += 4;
- while( * (int*) bp) { switch (* (int*) bp) {
+ while( * (int*) bp) { switch (* (int*) bp) {
case 1: {bp += 4;
proportion = (int)*(int *) bp; bp += 4;
} break;
@@ -12591,13 +12591,13 @@ case wxGridBagSizer_Add_2_0: { // wxGridBagSizer::Add
case 4: {bp += 4;
userData = (wxObject *) getPtr(bp,memenv); bp += 4;
} break;
- }};
+ }};
if(!This) throw wxe_badarg(0);
wxSizerItem * Result = (wxSizerItem*)This->Add(sizer,proportion,flag,border,userData);
rt.addRef(getRef((void *)Result,memenv), "wxSizerItem");
- break;
+ break;
}
-case wxGridBagSizer_Add_3_0: { // wxGridBagSizer::Add
+case wxGridBagSizer_Add_3_0: { // wxGridBagSizer::Add
int proportion=0;
int flag=0;
int border=0;
@@ -12606,7 +12606,7 @@ case wxGridBagSizer_Add_3_0: { // wxGridBagSizer::Add
int * width = (int *) bp; bp += 4;
int * height = (int *) bp; bp += 4;
bp += 4; /* Align */
- while( * (int*) bp) { switch (* (int*) bp) {
+ while( * (int*) bp) { switch (* (int*) bp) {
case 1: {bp += 4;
proportion = (int)*(int *) bp; bp += 4;
} break;
@@ -12619,42 +12619,42 @@ case wxGridBagSizer_Add_3_0: { // wxGridBagSizer::Add
case 4: {bp += 4;
userData = (wxObject *) getPtr(bp,memenv); bp += 4;
} break;
- }};
+ }};
if(!This) throw wxe_badarg(0);
wxSizerItem * Result = (wxSizerItem*)This->Add((int) *width,(int) *height,proportion,flag,border,userData);
rt.addRef(getRef((void *)Result,memenv), "wxSizerItem");
- break;
+ break;
}
-case wxGridBagSizer_Add_1_1: { // wxGridBagSizer::Add
+case wxGridBagSizer_Add_1_1: { // wxGridBagSizer::Add
wxGridBagSizer *This = (wxGridBagSizer *) getPtr(bp,memenv); bp += 4;
wxSizerItem * item = (wxSizerItem *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
wxSizerItem * Result = (wxSizerItem*)This->Add(item);
rt.addRef(getRef((void *)Result,memenv), "wxSizerItem");
- break;
+ break;
}
-case wxGridBagSizer_CalcMin: { // wxGridBagSizer::CalcMin
+case wxGridBagSizer_CalcMin: { // wxGridBagSizer::CalcMin
wxGridBagSizer *This = (wxGridBagSizer *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
wxSize Result = This->CalcMin();
rt.add(Result);
- break;
+ break;
}
-case wxGridBagSizer_CheckForIntersection_2: { // wxGridBagSizer::CheckForIntersection
+case wxGridBagSizer_CheckForIntersection_2: { // wxGridBagSizer::CheckForIntersection
wxGBSizerItem * excludeItem=NULL;
wxGridBagSizer *This = (wxGridBagSizer *) getPtr(bp,memenv); bp += 4;
wxGBSizerItem *item = (wxGBSizerItem *) getPtr(bp,memenv); bp += 4;
- while( * (int*) bp) { switch (* (int*) bp) {
+ while( * (int*) bp) { switch (* (int*) bp) {
case 1: {bp += 4;
excludeItem = (wxGBSizerItem *) getPtr(bp,memenv); bp += 4;
} break;
- }};
+ }};
if(!This) throw wxe_badarg(0);
bool Result = This->CheckForIntersection(item,excludeItem);
rt.addBool(Result);
- break;
+ break;
}
-case wxGridBagSizer_CheckForIntersection_3: { // wxGridBagSizer::CheckForIntersection
+case wxGridBagSizer_CheckForIntersection_3: { // wxGridBagSizer::CheckForIntersection
wxGBSizerItem * excludeItem=NULL;
wxGridBagSizer *This = (wxGridBagSizer *) getPtr(bp,memenv); bp += 4;
int * posR = (int *) bp; bp += 4;
@@ -12664,33 +12664,33 @@ case wxGridBagSizer_CheckForIntersection_3: { // wxGridBagSizer::CheckForInterse
int * spanCS = (int *) bp; bp += 4;
wxGBSpan span = wxGBSpan(*spanRS,*spanCS);
bp += 4; /* Align */
- while( * (int*) bp) { switch (* (int*) bp) {
+ while( * (int*) bp) { switch (* (int*) bp) {
case 1: {bp += 4;
excludeItem = (wxGBSizerItem *) getPtr(bp,memenv); bp += 4;
} break;
- }};
+ }};
if(!This) throw wxe_badarg(0);
bool Result = This->CheckForIntersection(pos,span,excludeItem);
rt.addBool(Result);
- break;
+ break;
}
-case wxGridBagSizer_FindItem_1_1: { // wxGridBagSizer::FindItem
+case wxGridBagSizer_FindItem_1_1: { // wxGridBagSizer::FindItem
wxGridBagSizer *This = (wxGridBagSizer *) getPtr(bp,memenv); bp += 4;
wxWindow * window = (wxWindow *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
wxGBSizerItem * Result = (wxGBSizerItem*)This->FindItem(window);
rt.addRef(getRef((void *)Result,memenv), "wxGBSizerItem");
- break;
+ break;
}
-case wxGridBagSizer_FindItem_1_0: { // wxGridBagSizer::FindItem
+case wxGridBagSizer_FindItem_1_0: { // wxGridBagSizer::FindItem
wxGridBagSizer *This = (wxGridBagSizer *) getPtr(bp,memenv); bp += 4;
wxSizer *sizer = (wxSizer *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
wxGBSizerItem * Result = (wxGBSizerItem*)This->FindItem(sizer);
rt.addRef(getRef((void *)Result,memenv), "wxGBSizerItem");
- break;
+ break;
}
-case wxGridBagSizer_FindItemAtPoint: { // wxGridBagSizer::FindItemAtPoint
+case wxGridBagSizer_FindItemAtPoint: { // wxGridBagSizer::FindItemAtPoint
wxGridBagSizer *This = (wxGridBagSizer *) getPtr(bp,memenv); bp += 4;
int * ptX = (int *) bp; bp += 4;
int * ptY = (int *) bp; bp += 4;
@@ -12698,9 +12698,9 @@ case wxGridBagSizer_FindItemAtPoint: { // wxGridBagSizer::FindItemAtPoint
if(!This) throw wxe_badarg(0);
wxGBSizerItem * Result = (wxGBSizerItem*)This->FindItemAtPoint(pt);
rt.addRef(getRef((void *)Result,memenv), "wxGBSizerItem");
- break;
+ break;
}
-case wxGridBagSizer_FindItemAtPosition: { // wxGridBagSizer::FindItemAtPosition
+case wxGridBagSizer_FindItemAtPosition: { // wxGridBagSizer::FindItemAtPosition
wxGridBagSizer *This = (wxGridBagSizer *) getPtr(bp,memenv); bp += 4;
int * posR = (int *) bp; bp += 4;
int * posC = (int *) bp; bp += 4;
@@ -12708,90 +12708,90 @@ case wxGridBagSizer_FindItemAtPosition: { // wxGridBagSizer::FindItemAtPosition
if(!This) throw wxe_badarg(0);
wxGBSizerItem * Result = (wxGBSizerItem*)This->FindItemAtPosition(pos);
rt.addRef(getRef((void *)Result,memenv), "wxGBSizerItem");
- break;
+ break;
}
-case wxGridBagSizer_FindItemWithData: { // wxGridBagSizer::FindItemWithData
+case wxGridBagSizer_FindItemWithData: { // wxGridBagSizer::FindItemWithData
wxGridBagSizer *This = (wxGridBagSizer *) getPtr(bp,memenv); bp += 4;
wxObject *userData = (wxObject *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
wxGBSizerItem * Result = (wxGBSizerItem*)This->FindItemWithData(userData);
rt.addRef(getRef((void *)Result,memenv), "wxGBSizerItem");
- break;
+ break;
}
-case wxGridBagSizer_GetCellSize: { // wxGridBagSizer::GetCellSize
+case wxGridBagSizer_GetCellSize: { // wxGridBagSizer::GetCellSize
wxGridBagSizer *This = (wxGridBagSizer *) getPtr(bp,memenv); bp += 4;
int * row = (int *) bp; bp += 4;
int * col = (int *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
wxSize Result = This->GetCellSize((int) *row,(int) *col);
rt.add(Result);
- break;
+ break;
}
-case wxGridBagSizer_GetEmptyCellSize: { // wxGridBagSizer::GetEmptyCellSize
+case wxGridBagSizer_GetEmptyCellSize: { // wxGridBagSizer::GetEmptyCellSize
wxGridBagSizer *This = (wxGridBagSizer *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
wxSize Result = This->GetEmptyCellSize();
rt.add(Result);
- break;
+ break;
}
-case wxGridBagSizer_GetItemPosition_1_2: { // wxGridBagSizer::GetItemPosition
+case wxGridBagSizer_GetItemPosition_1_2: { // wxGridBagSizer::GetItemPosition
wxGridBagSizer *This = (wxGridBagSizer *) getPtr(bp,memenv); bp += 4;
wxWindow * window = (wxWindow *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
wxGBPosition Result = This->GetItemPosition(window);
rt.add(Result);
- break;
+ break;
}
-case wxGridBagSizer_GetItemPosition_1_1: { // wxGridBagSizer::GetItemPosition
+case wxGridBagSizer_GetItemPosition_1_1: { // wxGridBagSizer::GetItemPosition
wxGridBagSizer *This = (wxGridBagSizer *) getPtr(bp,memenv); bp += 4;
wxSizer *sizer = (wxSizer *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
wxGBPosition Result = This->GetItemPosition(sizer);
rt.add(Result);
- break;
+ break;
}
-case wxGridBagSizer_GetItemPosition_1_0: { // wxGridBagSizer::GetItemPosition
+case wxGridBagSizer_GetItemPosition_1_0: { // wxGridBagSizer::GetItemPosition
wxGridBagSizer *This = (wxGridBagSizer *) getPtr(bp,memenv); bp += 4;
int * index = (int *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
wxGBPosition Result = This->GetItemPosition((size_t) *index);
rt.add(Result);
- break;
+ break;
}
-case wxGridBagSizer_GetItemSpan_1_2: { // wxGridBagSizer::GetItemSpan
+case wxGridBagSizer_GetItemSpan_1_2: { // wxGridBagSizer::GetItemSpan
wxGridBagSizer *This = (wxGridBagSizer *) getPtr(bp,memenv); bp += 4;
wxWindow * window = (wxWindow *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
wxGBSpan Result = This->GetItemSpan(window);
rt.add(Result);
- break;
+ break;
}
-case wxGridBagSizer_GetItemSpan_1_1: { // wxGridBagSizer::GetItemSpan
+case wxGridBagSizer_GetItemSpan_1_1: { // wxGridBagSizer::GetItemSpan
wxGridBagSizer *This = (wxGridBagSizer *) getPtr(bp,memenv); bp += 4;
wxSizer *sizer = (wxSizer *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
wxGBSpan Result = This->GetItemSpan(sizer);
rt.add(Result);
- break;
+ break;
}
-case wxGridBagSizer_GetItemSpan_1_0: { // wxGridBagSizer::GetItemSpan
+case wxGridBagSizer_GetItemSpan_1_0: { // wxGridBagSizer::GetItemSpan
wxGridBagSizer *This = (wxGridBagSizer *) getPtr(bp,memenv); bp += 4;
int * index = (int *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
wxGBSpan Result = This->GetItemSpan((size_t) *index);
rt.add(Result);
- break;
+ break;
}
-case wxGridBagSizer_SetEmptyCellSize: { // wxGridBagSizer::SetEmptyCellSize
+case wxGridBagSizer_SetEmptyCellSize: { // wxGridBagSizer::SetEmptyCellSize
wxGridBagSizer *This = (wxGridBagSizer *) getPtr(bp,memenv); bp += 4;
int * szW = (int *) bp; bp += 4;
int * szH = (int *) bp; bp += 4;
wxSize sz = wxSize(*szW,*szH);
if(!This) throw wxe_badarg(0);
This->SetEmptyCellSize(sz);
- break;
+ break;
}
-case wxGridBagSizer_SetItemPosition_2_2: { // wxGridBagSizer::SetItemPosition
+case wxGridBagSizer_SetItemPosition_2_2: { // wxGridBagSizer::SetItemPosition
wxGridBagSizer *This = (wxGridBagSizer *) getPtr(bp,memenv); bp += 4;
wxWindow * window = (wxWindow *) getPtr(bp,memenv); bp += 4;
int * posR = (int *) bp; bp += 4;
@@ -12800,9 +12800,9 @@ case wxGridBagSizer_SetItemPosition_2_2: { // wxGridBagSizer::SetItemPosition
if(!This) throw wxe_badarg(0);
bool Result = This->SetItemPosition(window,pos);
rt.addBool(Result);
- break;
+ break;
}
-case wxGridBagSizer_SetItemPosition_2_1: { // wxGridBagSizer::SetItemPosition
+case wxGridBagSizer_SetItemPosition_2_1: { // wxGridBagSizer::SetItemPosition
wxGridBagSizer *This = (wxGridBagSizer *) getPtr(bp,memenv); bp += 4;
wxSizer *sizer = (wxSizer *) getPtr(bp,memenv); bp += 4;
int * posR = (int *) bp; bp += 4;
@@ -12811,9 +12811,9 @@ case wxGridBagSizer_SetItemPosition_2_1: { // wxGridBagSizer::SetItemPosition
if(!This) throw wxe_badarg(0);
bool Result = This->SetItemPosition(sizer,pos);
rt.addBool(Result);
- break;
+ break;
}
-case wxGridBagSizer_SetItemPosition_2_0: { // wxGridBagSizer::SetItemPosition
+case wxGridBagSizer_SetItemPosition_2_0: { // wxGridBagSizer::SetItemPosition
wxGridBagSizer *This = (wxGridBagSizer *) getPtr(bp,memenv); bp += 4;
int * index = (int *) bp; bp += 4;
int * posR = (int *) bp; bp += 4;
@@ -12822,9 +12822,9 @@ case wxGridBagSizer_SetItemPosition_2_0: { // wxGridBagSizer::SetItemPosition
if(!This) throw wxe_badarg(0);
bool Result = This->SetItemPosition((size_t) *index,pos);
rt.addBool(Result);
- break;
+ break;
}
-case wxGridBagSizer_SetItemSpan_2_2: { // wxGridBagSizer::SetItemSpan
+case wxGridBagSizer_SetItemSpan_2_2: { // wxGridBagSizer::SetItemSpan
wxGridBagSizer *This = (wxGridBagSizer *) getPtr(bp,memenv); bp += 4;
wxWindow * window = (wxWindow *) getPtr(bp,memenv); bp += 4;
int * spanRS = (int *) bp; bp += 4;
@@ -12833,9 +12833,9 @@ case wxGridBagSizer_SetItemSpan_2_2: { // wxGridBagSizer::SetItemSpan
if(!This) throw wxe_badarg(0);
bool Result = This->SetItemSpan(window,span);
rt.addBool(Result);
- break;
+ break;
}
-case wxGridBagSizer_SetItemSpan_2_1: { // wxGridBagSizer::SetItemSpan
+case wxGridBagSizer_SetItemSpan_2_1: { // wxGridBagSizer::SetItemSpan
wxGridBagSizer *This = (wxGridBagSizer *) getPtr(bp,memenv); bp += 4;
wxSizer *sizer = (wxSizer *) getPtr(bp,memenv); bp += 4;
int * spanRS = (int *) bp; bp += 4;
@@ -12844,9 +12844,9 @@ case wxGridBagSizer_SetItemSpan_2_1: { // wxGridBagSizer::SetItemSpan
if(!This) throw wxe_badarg(0);
bool Result = This->SetItemSpan(sizer,span);
rt.addBool(Result);
- break;
+ break;
}
-case wxGridBagSizer_SetItemSpan_2_0: { // wxGridBagSizer::SetItemSpan
+case wxGridBagSizer_SetItemSpan_2_0: { // wxGridBagSizer::SetItemSpan
wxGridBagSizer *This = (wxGridBagSizer *) getPtr(bp,memenv); bp += 4;
int * index = (int *) bp; bp += 4;
int * spanRS = (int *) bp; bp += 4;
@@ -12855,64 +12855,64 @@ case wxGridBagSizer_SetItemSpan_2_0: { // wxGridBagSizer::SetItemSpan
if(!This) throw wxe_badarg(0);
bool Result = This->SetItemSpan((size_t) *index,span);
rt.addBool(Result);
- break;
+ break;
}
-case wxStdDialogButtonSizer_new: { // wxStdDialogButtonSizer::wxStdDialogButtonSizer
+case wxStdDialogButtonSizer_new: { // wxStdDialogButtonSizer::wxStdDialogButtonSizer
wxStdDialogButtonSizer * Result = new EwxStdDialogButtonSizer();
newPtr((void *) Result, 1, memenv);
rt.addRef(getRef((void *)Result,memenv), "wxStdDialogButtonSizer");
- break;
+ break;
}
-case wxStdDialogButtonSizer_AddButton: { // wxStdDialogButtonSizer::AddButton
+case wxStdDialogButtonSizer_AddButton: { // wxStdDialogButtonSizer::AddButton
wxStdDialogButtonSizer *This = (wxStdDialogButtonSizer *) getPtr(bp,memenv); bp += 4;
wxButton *button = (wxButton *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
This->AddButton(button);
- break;
+ break;
}
-case wxStdDialogButtonSizer_Realize: { // wxStdDialogButtonSizer::Realize
+case wxStdDialogButtonSizer_Realize: { // wxStdDialogButtonSizer::Realize
wxStdDialogButtonSizer *This = (wxStdDialogButtonSizer *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
This->Realize();
- break;
+ break;
}
-case wxStdDialogButtonSizer_SetAffirmativeButton: { // wxStdDialogButtonSizer::SetAffirmativeButton
+case wxStdDialogButtonSizer_SetAffirmativeButton: { // wxStdDialogButtonSizer::SetAffirmativeButton
wxStdDialogButtonSizer *This = (wxStdDialogButtonSizer *) getPtr(bp,memenv); bp += 4;
wxButton *button = (wxButton *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
This->SetAffirmativeButton(button);
- break;
+ break;
}
-case wxStdDialogButtonSizer_SetCancelButton: { // wxStdDialogButtonSizer::SetCancelButton
+case wxStdDialogButtonSizer_SetCancelButton: { // wxStdDialogButtonSizer::SetCancelButton
wxStdDialogButtonSizer *This = (wxStdDialogButtonSizer *) getPtr(bp,memenv); bp += 4;
wxButton *button = (wxButton *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
This->SetCancelButton(button);
- break;
+ break;
}
-case wxStdDialogButtonSizer_SetNegativeButton: { // wxStdDialogButtonSizer::SetNegativeButton
+case wxStdDialogButtonSizer_SetNegativeButton: { // wxStdDialogButtonSizer::SetNegativeButton
wxStdDialogButtonSizer *This = (wxStdDialogButtonSizer *) getPtr(bp,memenv); bp += 4;
wxButton *button = (wxButton *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
This->SetNegativeButton(button);
- break;
+ break;
}
-case wxFont_new_0: { // wxFont::wxFont
+case wxFont_new_0: { // wxFont::wxFont
wxFont * Result = new EwxFont();
newPtr((void *) Result, 1, memenv);
rt.addRef(getRef((void *)Result,memenv), "wxFont");
- break;
+ break;
}
-case wxFont_new_1: { // wxFont::wxFont
+case wxFont_new_1: { // wxFont::wxFont
int * fontnameLen = (int *) bp; bp += 4;
wxString fontname = wxString(bp, wxConvUTF8);
bp += *fontnameLen+((8-((4+ *fontnameLen) & 7)) & 7);
wxFont * Result = new EwxFont(fontname);
newPtr((void *) Result, 1, memenv);
rt.addRef(getRef((void *)Result,memenv), "wxFont");
- break;
+ break;
}
-case wxFont_new_5: { // wxFont::wxFont
+case wxFont_new_5: { // wxFont::wxFont
bool underlined=false;
wxString face= wxEmptyString;
wxFontEncoding encoding=wxFONTENCODING_DEFAULT;
@@ -12920,7 +12920,7 @@ case wxFont_new_5: { // wxFont::wxFont
wxFontFamily family = *(wxFontFamily *) bp; bp += 4;;
wxFontStyle style = *(wxFontStyle *) bp; bp += 4;;
int * weight = (int *) bp; bp += 4;
- while( * (int*) bp) { switch (* (int*) bp) {
+ while( * (int*) bp) { switch (* (int*) bp) {
case 1: {bp += 4;
underlined = *(bool *) bp; bp += 4;
} break;
@@ -12932,93 +12932,93 @@ case wxFont_new_5: { // wxFont::wxFont
case 3: {bp += 4;
encoding = *(wxFontEncoding *) bp; bp += 4;;
} break;
- }};
+ }};
wxFont * Result = new EwxFont((int) *size,(wxFontFamily) family,(wxFontStyle) style,(int) *weight,underlined,face,(wxFontEncoding) encoding);
newPtr((void *) Result, 1, memenv);
rt.addRef(getRef((void *)Result,memenv), "wxFont");
- break;
+ break;
}
-case wxFont_IsFixedWidth: { // wxFont::IsFixedWidth
+case wxFont_IsFixedWidth: { // wxFont::IsFixedWidth
wxFont *This = (wxFont *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
bool Result = This->IsFixedWidth();
rt.addBool(Result);
- break;
+ break;
}
-case wxFont_GetDefaultEncoding: { // wxFont::GetDefaultEncoding
+case wxFont_GetDefaultEncoding: { // wxFont::GetDefaultEncoding
int Result = wxFont::GetDefaultEncoding();
rt.addInt(Result);
- break;
+ break;
}
-case wxFont_GetFaceName: { // wxFont::GetFaceName
+case wxFont_GetFaceName: { // wxFont::GetFaceName
wxFont *This = (wxFont *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
wxString Result = This->GetFaceName();
rt.add(Result);
- break;
+ break;
}
-case wxFont_GetFamily: { // wxFont::GetFamily
+case wxFont_GetFamily: { // wxFont::GetFamily
wxFont *This = (wxFont *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
int Result = This->GetFamily();
rt.addInt(Result);
- break;
+ break;
}
-case wxFont_GetNativeFontInfoDesc: { // wxFont::GetNativeFontInfoDesc
+case wxFont_GetNativeFontInfoDesc: { // wxFont::GetNativeFontInfoDesc
wxFont *This = (wxFont *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
wxString Result = This->GetNativeFontInfoDesc();
rt.add(Result);
- break;
+ break;
}
-case wxFont_GetNativeFontInfoUserDesc: { // wxFont::GetNativeFontInfoUserDesc
+case wxFont_GetNativeFontInfoUserDesc: { // wxFont::GetNativeFontInfoUserDesc
wxFont *This = (wxFont *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
wxString Result = This->GetNativeFontInfoUserDesc();
rt.add(Result);
- break;
+ break;
}
-case wxFont_GetPointSize: { // wxFont::GetPointSize
+case wxFont_GetPointSize: { // wxFont::GetPointSize
wxFont *This = (wxFont *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
int Result = This->GetPointSize();
rt.addInt(Result);
- break;
+ break;
}
-case wxFont_GetStyle: { // wxFont::GetStyle
+case wxFont_GetStyle: { // wxFont::GetStyle
wxFont *This = (wxFont *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
int Result = This->GetStyle();
rt.addInt(Result);
- break;
+ break;
}
-case wxFont_GetUnderlined: { // wxFont::GetUnderlined
+case wxFont_GetUnderlined: { // wxFont::GetUnderlined
wxFont *This = (wxFont *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
bool Result = This->GetUnderlined();
rt.addBool(Result);
- break;
+ break;
}
-case wxFont_GetWeight: { // wxFont::GetWeight
+case wxFont_GetWeight: { // wxFont::GetWeight
wxFont *This = (wxFont *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
int Result = This->GetWeight();
rt.addInt(Result);
- break;
+ break;
}
-case wxFont_Ok: { // wxFont::Ok
+case wxFont_Ok: { // wxFont::Ok
wxFont *This = (wxFont *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
bool Result = This->Ok();
rt.addBool(Result);
- break;
+ break;
}
-case wxFont_SetDefaultEncoding: { // wxFont::SetDefaultEncoding
+case wxFont_SetDefaultEncoding: { // wxFont::SetDefaultEncoding
wxFontEncoding encoding = *(wxFontEncoding *) bp; bp += 4;;
wxFont::SetDefaultEncoding((wxFontEncoding) encoding);
- break;
+ break;
}
-case wxFont_SetFaceName: { // wxFont::SetFaceName
+case wxFont_SetFaceName: { // wxFont::SetFaceName
wxFont *This = (wxFont *) getPtr(bp,memenv); bp += 4;
int * faceNameLen = (int *) bp; bp += 4;
wxString faceName = wxString(bp, wxConvUTF8);
@@ -13026,86 +13026,86 @@ case wxFont_SetFaceName: { // wxFont::SetFaceName
if(!This) throw wxe_badarg(0);
bool Result = This->SetFaceName(faceName);
rt.addBool(Result);
- break;
+ break;
}
-case wxFont_SetFamily: { // wxFont::SetFamily
+case wxFont_SetFamily: { // wxFont::SetFamily
wxFont *This = (wxFont *) getPtr(bp,memenv); bp += 4;
wxFontFamily family = *(wxFontFamily *) bp; bp += 4;;
if(!This) throw wxe_badarg(0);
This->SetFamily((wxFontFamily) family);
- break;
+ break;
}
-case wxFont_SetPointSize: { // wxFont::SetPointSize
+case wxFont_SetPointSize: { // wxFont::SetPointSize
wxFont *This = (wxFont *) getPtr(bp,memenv); bp += 4;
int * pointSize = (int *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
This->SetPointSize((int) *pointSize);
- break;
+ break;
}
-case wxFont_SetStyle: { // wxFont::SetStyle
+case wxFont_SetStyle: { // wxFont::SetStyle
wxFont *This = (wxFont *) getPtr(bp,memenv); bp += 4;
wxFontStyle style = *(wxFontStyle *) bp; bp += 4;;
if(!This) throw wxe_badarg(0);
This->SetStyle((wxFontStyle) style);
- break;
+ break;
}
-case wxFont_SetUnderlined: { // wxFont::SetUnderlined
+case wxFont_SetUnderlined: { // wxFont::SetUnderlined
wxFont *This = (wxFont *) getPtr(bp,memenv); bp += 4;
bool * underlined = (bool *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
This->SetUnderlined((bool) *underlined);
- break;
+ break;
}
-case wxFont_SetWeight: { // wxFont::SetWeight
+case wxFont_SetWeight: { // wxFont::SetWeight
wxFont *This = (wxFont *) getPtr(bp,memenv); bp += 4;
int * weight = (int *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
This->SetWeight((int) *weight);
- break;
+ break;
}
-case wxToolTip_Enable: { // wxToolTip::Enable
+case wxToolTip_Enable: { // wxToolTip::Enable
bool * flag = (bool *) bp; bp += 4;
wxToolTip::Enable((bool) *flag);
- break;
+ break;
}
-case wxToolTip_SetDelay: { // wxToolTip::SetDelay
+case wxToolTip_SetDelay: { // wxToolTip::SetDelay
int * msecs = (int *) bp; bp += 4;
wxToolTip::SetDelay((long) *msecs);
- break;
+ break;
}
-case wxToolTip_new: { // wxToolTip::wxToolTip
+case wxToolTip_new: { // wxToolTip::wxToolTip
int * tipLen = (int *) bp; bp += 4;
wxString tip = wxString(bp, wxConvUTF8);
bp += *tipLen+((8-((4+ *tipLen) & 7)) & 7);
wxToolTip * Result = new EwxToolTip(tip);
newPtr((void *) Result, 1, memenv);
rt.addRef(getRef((void *)Result,memenv), "wxToolTip");
- break;
+ break;
}
-case wxToolTip_SetTip: { // wxToolTip::SetTip
+case wxToolTip_SetTip: { // wxToolTip::SetTip
wxToolTip *This = (wxToolTip *) getPtr(bp,memenv); bp += 4;
int * tipLen = (int *) bp; bp += 4;
wxString tip = wxString(bp, wxConvUTF8);
bp += *tipLen+((8-((0+ *tipLen) & 7)) & 7);
if(!This) throw wxe_badarg(0);
This->SetTip(tip);
- break;
+ break;
}
-case wxToolTip_GetTip: { // wxToolTip::GetTip
+case wxToolTip_GetTip: { // wxToolTip::GetTip
wxToolTip *This = (wxToolTip *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
wxString Result = This->GetTip();
rt.add(Result);
- break;
+ break;
}
-case wxToolTip_GetWindow: { // wxToolTip::GetWindow
+case wxToolTip_GetWindow: { // wxToolTip::GetWindow
wxToolTip *This = (wxToolTip *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
wxWindow * Result = (wxWindow*)This->GetWindow();
rt.addRef(getRef((void *)Result,memenv), "wxWindow");
- break;
+ break;
}
-case wxButton_new_3: { // wxButton::wxButton
+case wxButton_new_3: { // wxButton::wxButton
wxString label= wxEmptyString;
wxPoint pos= wxDefaultPosition;
wxSize size= wxDefaultSize;
@@ -13113,7 +13113,7 @@ case wxButton_new_3: { // wxButton::wxButton
const wxValidator * validator= &wxDefaultValidator;
wxWindow *parent = (wxWindow *) getPtr(bp,memenv); bp += 4;
int * id = (int *) bp; bp += 4;
- while( * (int*) bp) { switch (* (int*) bp) {
+ while( * (int*) bp) { switch (* (int*) bp) {
case 1: {bp += 4;
int * labelLen = (int *) bp; bp += 4;
label = wxString(bp, wxConvUTF8);
@@ -13137,19 +13137,19 @@ case wxButton_new_3: { // wxButton::wxButton
case 5: {bp += 4;
validator = (wxValidator *) getPtr(bp,memenv); bp += 4;
} break;
- }};
+ }};
wxButton * Result = new EwxButton(parent,(wxWindowID) *id,label,pos,size,style,*validator);
newPtr((void *) Result, 0, memenv);
rt.addRef(getRef((void *)Result,memenv), "wxButton");
- break;
+ break;
}
-case wxButton_new_0: { // wxButton::wxButton
+case wxButton_new_0: { // wxButton::wxButton
wxButton * Result = new EwxButton();
newPtr((void *) Result, 0, memenv);
rt.addRef(getRef((void *)Result,memenv), "wxButton");
- break;
+ break;
}
-case wxButton_Create: { // wxButton::Create
+case wxButton_Create: { // wxButton::Create
wxString label= wxEmptyString;
wxPoint pos= wxDefaultPosition;
wxSize size= wxDefaultSize;
@@ -13159,7 +13159,7 @@ case wxButton_Create: { // wxButton::Create
wxWindow *parent = (wxWindow *) getPtr(bp,memenv); bp += 4;
int * id = (int *) bp; bp += 4;
bp += 4; /* Align */
- while( * (int*) bp) { switch (* (int*) bp) {
+ while( * (int*) bp) { switch (* (int*) bp) {
case 1: {bp += 4;
int * labelLen = (int *) bp; bp += 4;
label = wxString(bp, wxConvUTF8);
@@ -13183,33 +13183,33 @@ case wxButton_Create: { // wxButton::Create
case 5: {bp += 4;
validator = (wxValidator *) getPtr(bp,memenv); bp += 4;
} break;
- }};
+ }};
if(!This) throw wxe_badarg(0);
bool Result = This->Create(parent,(wxWindowID) *id,label,pos,size,style,*validator);
rt.addBool(Result);
- break;
+ break;
}
-case wxButton_GetDefaultSize: { // wxButton::GetDefaultSize
+case wxButton_GetDefaultSize: { // wxButton::GetDefaultSize
wxSize Result = wxButton::GetDefaultSize();
rt.add(Result);
- break;
+ break;
}
-case wxButton_SetDefault: { // wxButton::SetDefault
+case wxButton_SetDefault: { // wxButton::SetDefault
wxButton *This = (wxButton *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
This->SetDefault();
- break;
+ break;
}
-case wxButton_SetLabel: { // wxButton::SetLabel
+case wxButton_SetLabel: { // wxButton::SetLabel
wxButton *This = (wxButton *) getPtr(bp,memenv); bp += 4;
int * labelLen = (int *) bp; bp += 4;
wxString label = wxString(bp, wxConvUTF8);
bp += *labelLen+((8-((0+ *labelLen) & 7)) & 7);
if(!This) throw wxe_badarg(0);
This->SetLabel(label);
- break;
+ break;
}
-case wxBitmapButton_new_4: { // wxBitmapButton::wxBitmapButton
+case wxBitmapButton_new_4: { // wxBitmapButton::wxBitmapButton
wxPoint pos= wxDefaultPosition;
wxSize size= wxDefaultSize;
long style=wxBU_AUTODRAW;
@@ -13218,7 +13218,7 @@ case wxBitmapButton_new_4: { // wxBitmapButton::wxBitmapButton
int * id = (int *) bp; bp += 4;
wxBitmap *bitmap = (wxBitmap *) getPtr(bp,memenv); bp += 4;
bp += 4; /* Align */
- while( * (int*) bp) { switch (* (int*) bp) {
+ while( * (int*) bp) { switch (* (int*) bp) {
case 1: {bp += 4;
int * posX = (int *) bp; bp += 4;
int * posY = (int *) bp; bp += 4;
@@ -13237,19 +13237,19 @@ case wxBitmapButton_new_4: { // wxBitmapButton::wxBitmapButton
case 4: {bp += 4;
validator = (wxValidator *) getPtr(bp,memenv); bp += 4;
} break;
- }};
+ }};
wxBitmapButton * Result = new EwxBitmapButton(parent,(wxWindowID) *id,*bitmap,pos,size,style,*validator);
newPtr((void *) Result, 0, memenv);
rt.addRef(getRef((void *)Result,memenv), "wxBitmapButton");
- break;
+ break;
}
-case wxBitmapButton_new_0: { // wxBitmapButton::wxBitmapButton
+case wxBitmapButton_new_0: { // wxBitmapButton::wxBitmapButton
wxBitmapButton * Result = new EwxBitmapButton();
newPtr((void *) Result, 0, memenv);
rt.addRef(getRef((void *)Result,memenv), "wxBitmapButton");
- break;
+ break;
}
-case wxBitmapButton_Create: { // wxBitmapButton::Create
+case wxBitmapButton_Create: { // wxBitmapButton::Create
wxPoint pos= wxDefaultPosition;
wxSize size= wxDefaultSize;
long style=wxBU_AUTODRAW;
@@ -13258,7 +13258,7 @@ case wxBitmapButton_Create: { // wxBitmapButton::Create
wxWindow *parent = (wxWindow *) getPtr(bp,memenv); bp += 4;
int * id = (int *) bp; bp += 4;
wxBitmap *bitmap = (wxBitmap *) getPtr(bp,memenv); bp += 4;
- while( * (int*) bp) { switch (* (int*) bp) {
+ while( * (int*) bp) { switch (* (int*) bp) {
case 1: {bp += 4;
int * posX = (int *) bp; bp += 4;
int * posY = (int *) bp; bp += 4;
@@ -13277,75 +13277,75 @@ case wxBitmapButton_Create: { // wxBitmapButton::Create
case 4: {bp += 4;
validator = (wxValidator *) getPtr(bp,memenv); bp += 4;
} break;
- }};
+ }};
if(!This) throw wxe_badarg(0);
bool Result = This->Create(parent,(wxWindowID) *id,*bitmap,pos,size,style,*validator);
rt.addBool(Result);
- break;
+ break;
}
-case wxBitmapButton_GetBitmapDisabled: { // wxBitmapButton::GetBitmapDisabled
+case wxBitmapButton_GetBitmapDisabled: { // wxBitmapButton::GetBitmapDisabled
wxBitmapButton *This = (wxBitmapButton *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
const wxBitmap * Result = &This->GetBitmapDisabled();
rt.addRef(getRef((void *)Result,memenv), "wxBitmap");
- break;
+ break;
}
-case wxBitmapButton_GetBitmapFocus: { // wxBitmapButton::GetBitmapFocus
+case wxBitmapButton_GetBitmapFocus: { // wxBitmapButton::GetBitmapFocus
wxBitmapButton *This = (wxBitmapButton *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
const wxBitmap * Result = &This->GetBitmapFocus();
rt.addRef(getRef((void *)Result,memenv), "wxBitmap");
- break;
+ break;
}
-case wxBitmapButton_GetBitmapLabel: { // wxBitmapButton::GetBitmapLabel
+case wxBitmapButton_GetBitmapLabel: { // wxBitmapButton::GetBitmapLabel
wxBitmapButton *This = (wxBitmapButton *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
const wxBitmap * Result = &This->GetBitmapLabel();
rt.addRef(getRef((void *)Result,memenv), "wxBitmap");
- break;
+ break;
}
-case wxBitmapButton_GetBitmapSelected: { // wxBitmapButton::GetBitmapSelected
+case wxBitmapButton_GetBitmapSelected: { // wxBitmapButton::GetBitmapSelected
wxBitmapButton *This = (wxBitmapButton *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
const wxBitmap * Result = &This->GetBitmapSelected();
rt.addRef(getRef((void *)Result,memenv), "wxBitmap");
- break;
+ break;
}
-case wxBitmapButton_SetBitmapDisabled: { // wxBitmapButton::SetBitmapDisabled
+case wxBitmapButton_SetBitmapDisabled: { // wxBitmapButton::SetBitmapDisabled
wxBitmapButton *This = (wxBitmapButton *) getPtr(bp,memenv); bp += 4;
wxBitmap *disabled = (wxBitmap *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
This->SetBitmapDisabled(*disabled);
- break;
+ break;
}
-case wxBitmapButton_SetBitmapFocus: { // wxBitmapButton::SetBitmapFocus
+case wxBitmapButton_SetBitmapFocus: { // wxBitmapButton::SetBitmapFocus
wxBitmapButton *This = (wxBitmapButton *) getPtr(bp,memenv); bp += 4;
wxBitmap *focus = (wxBitmap *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
This->SetBitmapFocus(*focus);
- break;
+ break;
}
-case wxBitmapButton_SetBitmapLabel: { // wxBitmapButton::SetBitmapLabel
+case wxBitmapButton_SetBitmapLabel: { // wxBitmapButton::SetBitmapLabel
wxBitmapButton *This = (wxBitmapButton *) getPtr(bp,memenv); bp += 4;
wxBitmap *bitmap = (wxBitmap *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
This->SetBitmapLabel(*bitmap);
- break;
+ break;
}
-case wxBitmapButton_SetBitmapSelected: { // wxBitmapButton::SetBitmapSelected
+case wxBitmapButton_SetBitmapSelected: { // wxBitmapButton::SetBitmapSelected
wxBitmapButton *This = (wxBitmapButton *) getPtr(bp,memenv); bp += 4;
wxBitmap *sel = (wxBitmap *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
This->SetBitmapSelected(*sel);
- break;
+ break;
}
-case wxToggleButton_new_0: { // wxToggleButton::wxToggleButton
+case wxToggleButton_new_0: { // wxToggleButton::wxToggleButton
wxToggleButton * Result = new EwxToggleButton();
newPtr((void *) Result, 0, memenv);
rt.addRef(getRef((void *)Result,memenv), "wxToggleButton");
- break;
+ break;
}
-case wxToggleButton_new_4: { // wxToggleButton::wxToggleButton
+case wxToggleButton_new_4: { // wxToggleButton::wxToggleButton
wxPoint pos= wxDefaultPosition;
wxSize size= wxDefaultSize;
long style=0;
@@ -13355,7 +13355,7 @@ case wxToggleButton_new_4: { // wxToggleButton::wxToggleButton
int * labelLen = (int *) bp; bp += 4;
wxString label = wxString(bp, wxConvUTF8);
bp += *labelLen+((8-((4+ *labelLen) & 7)) & 7);
- while( * (int*) bp) { switch (* (int*) bp) {
+ while( * (int*) bp) { switch (* (int*) bp) {
case 1: {bp += 4;
int * posX = (int *) bp; bp += 4;
int * posY = (int *) bp; bp += 4;
@@ -13374,13 +13374,13 @@ case wxToggleButton_new_4: { // wxToggleButton::wxToggleButton
case 4: {bp += 4;
validator = (wxValidator *) getPtr(bp,memenv); bp += 4;
} break;
- }};
+ }};
wxToggleButton * Result = new EwxToggleButton(parent,(wxWindowID) *id,label,pos,size,style,*validator);
newPtr((void *) Result, 0, memenv);
rt.addRef(getRef((void *)Result,memenv), "wxToggleButton");
- break;
+ break;
}
-case wxToggleButton_Create: { // wxToggleButton::Create
+case wxToggleButton_Create: { // wxToggleButton::Create
wxPoint pos= wxDefaultPosition;
wxSize size= wxDefaultSize;
long style=0;
@@ -13391,7 +13391,7 @@ case wxToggleButton_Create: { // wxToggleButton::Create
int * labelLen = (int *) bp; bp += 4;
wxString label = wxString(bp, wxConvUTF8);
bp += *labelLen+((8-((0+ *labelLen) & 7)) & 7);
- while( * (int*) bp) { switch (* (int*) bp) {
+ while( * (int*) bp) { switch (* (int*) bp) {
case 1: {bp += 4;
int * posX = (int *) bp; bp += 4;
int * posY = (int *) bp; bp += 4;
@@ -13410,40 +13410,40 @@ case wxToggleButton_Create: { // wxToggleButton::Create
case 4: {bp += 4;
validator = (wxValidator *) getPtr(bp,memenv); bp += 4;
} break;
- }};
+ }};
if(!This) throw wxe_badarg(0);
bool Result = This->Create(parent,(wxWindowID) *id,label,pos,size,style,*validator);
rt.addBool(Result);
- break;
+ break;
}
-case wxToggleButton_GetValue: { // wxToggleButton::GetValue
+case wxToggleButton_GetValue: { // wxToggleButton::GetValue
wxToggleButton *This = (wxToggleButton *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
bool Result = This->GetValue();
rt.addBool(Result);
- break;
+ break;
}
-case wxToggleButton_SetValue: { // wxToggleButton::SetValue
+case wxToggleButton_SetValue: { // wxToggleButton::SetValue
wxToggleButton *This = (wxToggleButton *) getPtr(bp,memenv); bp += 4;
bool * state = (bool *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
This->SetValue((bool) *state);
- break;
+ break;
}
-case wxCalendarCtrl_new_0: { // wxCalendarCtrl::wxCalendarCtrl
+case wxCalendarCtrl_new_0: { // wxCalendarCtrl::wxCalendarCtrl
wxCalendarCtrl * Result = new EwxCalendarCtrl();
newPtr((void *) Result, 0, memenv);
rt.addRef(getRef((void *)Result,memenv), "wxCalendarCtrl");
- break;
+ break;
}
-case wxCalendarCtrl_new_3: { // wxCalendarCtrl::wxCalendarCtrl
+case wxCalendarCtrl_new_3: { // wxCalendarCtrl::wxCalendarCtrl
wxDateTime date= wxDefaultDateTime;
wxPoint pos= wxDefaultPosition;
wxSize size= wxDefaultSize;
long style=wxCAL_SHOW_HOLIDAYS|wxWANTS_CHARS;
wxWindow *parent = (wxWindow *) getPtr(bp,memenv); bp += 4;
int * id = (int *) bp; bp += 4;
- while( * (int*) bp) { switch (* (int*) bp) {
+ while( * (int*) bp) { switch (* (int*) bp) {
case 1: {bp += 4;
int * dateD = (int *) bp; bp += 4;
int * dateMo = (int *) bp; bp += 4;
@@ -13469,13 +13469,13 @@ case wxCalendarCtrl_new_3: { // wxCalendarCtrl::wxCalendarCtrl
case 4: {bp += 4;
style = (long)*(int *) bp; bp += 4;
} break;
- }};
+ }};
wxCalendarCtrl * Result = new EwxCalendarCtrl(parent,(wxWindowID) *id,date,pos,size,style);
newPtr((void *) Result, 0, memenv);
rt.addRef(getRef((void *)Result,memenv), "wxCalendarCtrl");
- break;
+ break;
}
-case wxCalendarCtrl_Create: { // wxCalendarCtrl::Create
+case wxCalendarCtrl_Create: { // wxCalendarCtrl::Create
wxDateTime date= wxDefaultDateTime;
wxPoint pos= wxDefaultPosition;
wxSize size= wxDefaultSize;
@@ -13484,7 +13484,7 @@ case wxCalendarCtrl_Create: { // wxCalendarCtrl::Create
wxWindow *parent = (wxWindow *) getPtr(bp,memenv); bp += 4;
int * id = (int *) bp; bp += 4;
bp += 4; /* Align */
- while( * (int*) bp) { switch (* (int*) bp) {
+ while( * (int*) bp) { switch (* (int*) bp) {
case 1: {bp += 4;
int * dateD = (int *) bp; bp += 4;
int * dateMo = (int *) bp; bp += 4;
@@ -13510,13 +13510,13 @@ case wxCalendarCtrl_Create: { // wxCalendarCtrl::Create
case 4: {bp += 4;
style = (long)*(int *) bp; bp += 4;
} break;
- }};
+ }};
if(!This) throw wxe_badarg(0);
bool Result = This->Create(parent,(wxWindowID) *id,date,pos,size,style);
rt.addBool(Result);
- break;
+ break;
}
-case wxCalendarCtrl_SetDate: { // wxCalendarCtrl::SetDate
+case wxCalendarCtrl_SetDate: { // wxCalendarCtrl::SetDate
wxCalendarCtrl *This = (wxCalendarCtrl *) getPtr(bp,memenv); bp += 4;
int * dateD = (int *) bp; bp += 4;
int * dateMo = (int *) bp; bp += 4;
@@ -13528,55 +13528,55 @@ case wxCalendarCtrl_SetDate: { // wxCalendarCtrl::SetDate
if(!This) throw wxe_badarg(0);
bool Result = This->SetDate(date);
rt.addBool(Result);
- break;
+ break;
}
-case wxCalendarCtrl_GetDate: { // wxCalendarCtrl::GetDate
+case wxCalendarCtrl_GetDate: { // wxCalendarCtrl::GetDate
wxCalendarCtrl *This = (wxCalendarCtrl *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
const wxDateTime * Result = &This->GetDate();
rt.add((*Result));
- break;
+ break;
}
-case wxCalendarCtrl_EnableYearChange: { // wxCalendarCtrl::EnableYearChange
+case wxCalendarCtrl_EnableYearChange: { // wxCalendarCtrl::EnableYearChange
bool enable=true;
wxCalendarCtrl *This = (wxCalendarCtrl *) getPtr(bp,memenv); bp += 4;
bp += 4; /* Align */
- while( * (int*) bp) { switch (* (int*) bp) {
+ while( * (int*) bp) { switch (* (int*) bp) {
case 1: {bp += 4;
enable = *(bool *) bp; bp += 4;
} break;
- }};
+ }};
if(!This) throw wxe_badarg(0);
This->EnableYearChange(enable);
- break;
+ break;
}
-case wxCalendarCtrl_EnableMonthChange: { // wxCalendarCtrl::EnableMonthChange
+case wxCalendarCtrl_EnableMonthChange: { // wxCalendarCtrl::EnableMonthChange
bool enable=true;
wxCalendarCtrl *This = (wxCalendarCtrl *) getPtr(bp,memenv); bp += 4;
bp += 4; /* Align */
- while( * (int*) bp) { switch (* (int*) bp) {
+ while( * (int*) bp) { switch (* (int*) bp) {
case 1: {bp += 4;
enable = *(bool *) bp; bp += 4;
} break;
- }};
+ }};
if(!This) throw wxe_badarg(0);
This->EnableMonthChange(enable);
- break;
+ break;
}
-case wxCalendarCtrl_EnableHolidayDisplay: { // wxCalendarCtrl::EnableHolidayDisplay
+case wxCalendarCtrl_EnableHolidayDisplay: { // wxCalendarCtrl::EnableHolidayDisplay
bool display=true;
wxCalendarCtrl *This = (wxCalendarCtrl *) getPtr(bp,memenv); bp += 4;
bp += 4; /* Align */
- while( * (int*) bp) { switch (* (int*) bp) {
+ while( * (int*) bp) { switch (* (int*) bp) {
case 1: {bp += 4;
display = *(bool *) bp; bp += 4;
} break;
- }};
+ }};
if(!This) throw wxe_badarg(0);
This->EnableHolidayDisplay(display);
- break;
+ break;
}
-case wxCalendarCtrl_SetHeaderColours: { // wxCalendarCtrl::SetHeaderColours
+case wxCalendarCtrl_SetHeaderColours: { // wxCalendarCtrl::SetHeaderColours
wxCalendarCtrl *This = (wxCalendarCtrl *) getPtr(bp,memenv); bp += 4;
int * colFgR = (int *) bp; bp += 4;
int * colFgG = (int *) bp; bp += 4;
@@ -13590,23 +13590,23 @@ case wxCalendarCtrl_SetHeaderColours: { // wxCalendarCtrl::SetHeaderColours
wxColour colBg = wxColour(*colBgR,*colBgG,*colBgB,*colBgA);
if(!This) throw wxe_badarg(0);
This->SetHeaderColours(colFg,colBg);
- break;
+ break;
}
-case wxCalendarCtrl_GetHeaderColourFg: { // wxCalendarCtrl::GetHeaderColourFg
+case wxCalendarCtrl_GetHeaderColourFg: { // wxCalendarCtrl::GetHeaderColourFg
wxCalendarCtrl *This = (wxCalendarCtrl *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
const wxColour * Result = &This->GetHeaderColourFg();
rt.add((*Result));
- break;
+ break;
}
-case wxCalendarCtrl_GetHeaderColourBg: { // wxCalendarCtrl::GetHeaderColourBg
+case wxCalendarCtrl_GetHeaderColourBg: { // wxCalendarCtrl::GetHeaderColourBg
wxCalendarCtrl *This = (wxCalendarCtrl *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
const wxColour * Result = &This->GetHeaderColourBg();
rt.add((*Result));
- break;
+ break;
}
-case wxCalendarCtrl_SetHighlightColours: { // wxCalendarCtrl::SetHighlightColours
+case wxCalendarCtrl_SetHighlightColours: { // wxCalendarCtrl::SetHighlightColours
wxCalendarCtrl *This = (wxCalendarCtrl *) getPtr(bp,memenv); bp += 4;
int * colFgR = (int *) bp; bp += 4;
int * colFgG = (int *) bp; bp += 4;
@@ -13620,23 +13620,23 @@ case wxCalendarCtrl_SetHighlightColours: { // wxCalendarCtrl::SetHighlightColour
wxColour colBg = wxColour(*colBgR,*colBgG,*colBgB,*colBgA);
if(!This) throw wxe_badarg(0);
This->SetHighlightColours(colFg,colBg);
- break;
+ break;
}
-case wxCalendarCtrl_GetHighlightColourFg: { // wxCalendarCtrl::GetHighlightColourFg
+case wxCalendarCtrl_GetHighlightColourFg: { // wxCalendarCtrl::GetHighlightColourFg
wxCalendarCtrl *This = (wxCalendarCtrl *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
const wxColour * Result = &This->GetHighlightColourFg();
rt.add((*Result));
- break;
+ break;
}
-case wxCalendarCtrl_GetHighlightColourBg: { // wxCalendarCtrl::GetHighlightColourBg
+case wxCalendarCtrl_GetHighlightColourBg: { // wxCalendarCtrl::GetHighlightColourBg
wxCalendarCtrl *This = (wxCalendarCtrl *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
const wxColour * Result = &This->GetHighlightColourBg();
rt.add((*Result));
- break;
+ break;
}
-case wxCalendarCtrl_SetHolidayColours: { // wxCalendarCtrl::SetHolidayColours
+case wxCalendarCtrl_SetHolidayColours: { // wxCalendarCtrl::SetHolidayColours
wxCalendarCtrl *This = (wxCalendarCtrl *) getPtr(bp,memenv); bp += 4;
int * colFgR = (int *) bp; bp += 4;
int * colFgG = (int *) bp; bp += 4;
@@ -13650,53 +13650,53 @@ case wxCalendarCtrl_SetHolidayColours: { // wxCalendarCtrl::SetHolidayColours
wxColour colBg = wxColour(*colBgR,*colBgG,*colBgB,*colBgA);
if(!This) throw wxe_badarg(0);
This->SetHolidayColours(colFg,colBg);
- break;
+ break;
}
-case wxCalendarCtrl_GetHolidayColourFg: { // wxCalendarCtrl::GetHolidayColourFg
+case wxCalendarCtrl_GetHolidayColourFg: { // wxCalendarCtrl::GetHolidayColourFg
wxCalendarCtrl *This = (wxCalendarCtrl *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
const wxColour * Result = &This->GetHolidayColourFg();
rt.add((*Result));
- break;
+ break;
}
-case wxCalendarCtrl_GetHolidayColourBg: { // wxCalendarCtrl::GetHolidayColourBg
+case wxCalendarCtrl_GetHolidayColourBg: { // wxCalendarCtrl::GetHolidayColourBg
wxCalendarCtrl *This = (wxCalendarCtrl *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
const wxColour * Result = &This->GetHolidayColourBg();
rt.add((*Result));
- break;
+ break;
}
-case wxCalendarCtrl_GetAttr: { // wxCalendarCtrl::GetAttr
+case wxCalendarCtrl_GetAttr: { // wxCalendarCtrl::GetAttr
wxCalendarCtrl *This = (wxCalendarCtrl *) getPtr(bp,memenv); bp += 4;
int * day = (int *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
wxCalendarDateAttr * Result = (wxCalendarDateAttr*)This->GetAttr((size_t) *day);
rt.addRef(getRef((void *)Result,memenv), "wxCalendarDateAttr");
- break;
+ break;
}
-case wxCalendarCtrl_SetAttr: { // wxCalendarCtrl::SetAttr
+case wxCalendarCtrl_SetAttr: { // wxCalendarCtrl::SetAttr
wxCalendarCtrl *This = (wxCalendarCtrl *) getPtr(bp,memenv); bp += 4;
int * day = (int *) bp; bp += 4;
wxCalendarDateAttr *attr = (wxCalendarDateAttr *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
This->SetAttr((size_t) *day,attr);
- break;
+ break;
}
-case wxCalendarCtrl_SetHoliday: { // wxCalendarCtrl::SetHoliday
+case wxCalendarCtrl_SetHoliday: { // wxCalendarCtrl::SetHoliday
wxCalendarCtrl *This = (wxCalendarCtrl *) getPtr(bp,memenv); bp += 4;
int * day = (int *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
This->SetHoliday((size_t) *day);
- break;
+ break;
}
-case wxCalendarCtrl_ResetAttr: { // wxCalendarCtrl::ResetAttr
+case wxCalendarCtrl_ResetAttr: { // wxCalendarCtrl::ResetAttr
wxCalendarCtrl *This = (wxCalendarCtrl *) getPtr(bp,memenv); bp += 4;
int * day = (int *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
This->ResetAttr((size_t) *day);
- break;
+ break;
}
-case wxCalendarCtrl_HitTest: { // wxCalendarCtrl::HitTest
+case wxCalendarCtrl_HitTest: { // wxCalendarCtrl::HitTest
wxDateTime date;
wxDateTime::WeekDay wd;
wxCalendarCtrl *This = (wxCalendarCtrl *) getPtr(bp,memenv); bp += 4;
@@ -13709,15 +13709,15 @@ case wxCalendarCtrl_HitTest: { // wxCalendarCtrl::HitTest
rt.add(date);
rt.addInt(wd);
rt.addTupleCount(3);
- break;
+ break;
}
-case wxCalendarDateAttr_new_0: { // wxCalendarDateAttr::wxCalendarDateAttr
+case wxCalendarDateAttr_new_0: { // wxCalendarDateAttr::wxCalendarDateAttr
wxCalendarDateAttr * Result = new wxCalendarDateAttr();
newPtr((void *) Result, 88, memenv);
rt.addRef(getRef((void *)Result,memenv), "wxCalendarDateAttr");
- break;
+ break;
}
-case wxCalendarDateAttr_new_2_1: { // wxCalendarDateAttr::wxCalendarDateAttr
+case wxCalendarDateAttr_new_2_1: { // wxCalendarDateAttr::wxCalendarDateAttr
wxColour colBack= wxNullColour;
wxColour colBorder= wxNullColour;
const wxFont * font= &wxNullFont;
@@ -13727,7 +13727,7 @@ case wxCalendarDateAttr_new_2_1: { // wxCalendarDateAttr::wxCalendarDateAttr
int * colTextB = (int *) bp; bp += 4;
int * colTextA = (int *) bp; bp += 4;
wxColour colText = wxColour(*colTextR,*colTextG,*colTextB,*colTextA);
- while( * (int*) bp) { switch (* (int*) bp) {
+ while( * (int*) bp) { switch (* (int*) bp) {
case 1: {bp += 4;
int * colBackR = (int *) bp; bp += 4;
int * colBackG = (int *) bp; bp += 4;
@@ -13750,17 +13750,17 @@ font = (wxFont *) getPtr(bp,memenv); bp += 4;
case 4: {bp += 4;
border = *(wxCalendarDateBorder *) bp; bp += 4;;
} break;
- }};
+ }};
wxCalendarDateAttr * Result = new wxCalendarDateAttr(colText,colBack,colBorder,*font,(wxCalendarDateBorder) border);
newPtr((void *) Result, 88, memenv);
rt.addRef(getRef((void *)Result,memenv), "wxCalendarDateAttr");
- break;
+ break;
}
-case wxCalendarDateAttr_new_2_0: { // wxCalendarDateAttr::wxCalendarDateAttr
+case wxCalendarDateAttr_new_2_0: { // wxCalendarDateAttr::wxCalendarDateAttr
wxColour colBorder= wxNullColour;
wxCalendarDateBorder border = *(wxCalendarDateBorder *) bp; bp += 4;;
bp += 4; /* Align */
- while( * (int*) bp) { switch (* (int*) bp) {
+ while( * (int*) bp) { switch (* (int*) bp) {
case 1: {bp += 4;
int * colBorderR = (int *) bp; bp += 4;
int * colBorderG = (int *) bp; bp += 4;
@@ -13769,13 +13769,13 @@ case wxCalendarDateAttr_new_2_0: { // wxCalendarDateAttr::wxCalendarDateAttr
colBorder = wxColour(*colBorderR,*colBorderG,*colBorderB,*colBorderA);
bp += 4; /* Align */
} break;
- }};
+ }};
wxCalendarDateAttr * Result = new wxCalendarDateAttr((wxCalendarDateBorder) border,colBorder);
newPtr((void *) Result, 88, memenv);
rt.addRef(getRef((void *)Result,memenv), "wxCalendarDateAttr");
- break;
+ break;
}
-case wxCalendarDateAttr_SetTextColour: { // wxCalendarDateAttr::SetTextColour
+case wxCalendarDateAttr_SetTextColour: { // wxCalendarDateAttr::SetTextColour
wxCalendarDateAttr *This = (wxCalendarDateAttr *) getPtr(bp,memenv); bp += 4;
int * colTextR = (int *) bp; bp += 4;
int * colTextG = (int *) bp; bp += 4;
@@ -13784,9 +13784,9 @@ case wxCalendarDateAttr_SetTextColour: { // wxCalendarDateAttr::SetTextColour
wxColour colText = wxColour(*colTextR,*colTextG,*colTextB,*colTextA);
if(!This) throw wxe_badarg(0);
This->SetTextColour(colText);
- break;
+ break;
}
-case wxCalendarDateAttr_SetBackgroundColour: { // wxCalendarDateAttr::SetBackgroundColour
+case wxCalendarDateAttr_SetBackgroundColour: { // wxCalendarDateAttr::SetBackgroundColour
wxCalendarDateAttr *This = (wxCalendarDateAttr *) getPtr(bp,memenv); bp += 4;
int * colBackR = (int *) bp; bp += 4;
int * colBackG = (int *) bp; bp += 4;
@@ -13795,9 +13795,9 @@ case wxCalendarDateAttr_SetBackgroundColour: { // wxCalendarDateAttr::SetBackgro
wxColour colBack = wxColour(*colBackR,*colBackG,*colBackB,*colBackA);
if(!This) throw wxe_badarg(0);
This->SetBackgroundColour(colBack);
- break;
+ break;
}
-case wxCalendarDateAttr_SetBorderColour: { // wxCalendarDateAttr::SetBorderColour
+case wxCalendarDateAttr_SetBorderColour: { // wxCalendarDateAttr::SetBorderColour
wxCalendarDateAttr *This = (wxCalendarDateAttr *) getPtr(bp,memenv); bp += 4;
int * colR = (int *) bp; bp += 4;
int * colG = (int *) bp; bp += 4;
@@ -13806,113 +13806,113 @@ case wxCalendarDateAttr_SetBorderColour: { // wxCalendarDateAttr::SetBorderColou
wxColour col = wxColour(*colR,*colG,*colB,*colA);
if(!This) throw wxe_badarg(0);
This->SetBorderColour(col);
- break;
+ break;
}
-case wxCalendarDateAttr_SetFont: { // wxCalendarDateAttr::SetFont
+case wxCalendarDateAttr_SetFont: { // wxCalendarDateAttr::SetFont
wxCalendarDateAttr *This = (wxCalendarDateAttr *) getPtr(bp,memenv); bp += 4;
wxFont *font = (wxFont *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
This->SetFont(*font);
- break;
+ break;
}
-case wxCalendarDateAttr_SetBorder: { // wxCalendarDateAttr::SetBorder
+case wxCalendarDateAttr_SetBorder: { // wxCalendarDateAttr::SetBorder
wxCalendarDateAttr *This = (wxCalendarDateAttr *) getPtr(bp,memenv); bp += 4;
wxCalendarDateBorder border = *(wxCalendarDateBorder *) bp; bp += 4;;
if(!This) throw wxe_badarg(0);
This->SetBorder((wxCalendarDateBorder) border);
- break;
+ break;
}
-case wxCalendarDateAttr_SetHoliday: { // wxCalendarDateAttr::SetHoliday
+case wxCalendarDateAttr_SetHoliday: { // wxCalendarDateAttr::SetHoliday
wxCalendarDateAttr *This = (wxCalendarDateAttr *) getPtr(bp,memenv); bp += 4;
bool * holiday = (bool *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
This->SetHoliday((bool) *holiday);
- break;
+ break;
}
-case wxCalendarDateAttr_HasTextColour: { // wxCalendarDateAttr::HasTextColour
+case wxCalendarDateAttr_HasTextColour: { // wxCalendarDateAttr::HasTextColour
wxCalendarDateAttr *This = (wxCalendarDateAttr *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
bool Result = This->HasTextColour();
rt.addBool(Result);
- break;
+ break;
}
-case wxCalendarDateAttr_HasBackgroundColour: { // wxCalendarDateAttr::HasBackgroundColour
+case wxCalendarDateAttr_HasBackgroundColour: { // wxCalendarDateAttr::HasBackgroundColour
wxCalendarDateAttr *This = (wxCalendarDateAttr *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
bool Result = This->HasBackgroundColour();
rt.addBool(Result);
- break;
+ break;
}
-case wxCalendarDateAttr_HasBorderColour: { // wxCalendarDateAttr::HasBorderColour
+case wxCalendarDateAttr_HasBorderColour: { // wxCalendarDateAttr::HasBorderColour
wxCalendarDateAttr *This = (wxCalendarDateAttr *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
bool Result = This->HasBorderColour();
rt.addBool(Result);
- break;
+ break;
}
-case wxCalendarDateAttr_HasFont: { // wxCalendarDateAttr::HasFont
+case wxCalendarDateAttr_HasFont: { // wxCalendarDateAttr::HasFont
wxCalendarDateAttr *This = (wxCalendarDateAttr *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
bool Result = This->HasFont();
rt.addBool(Result);
- break;
+ break;
}
-case wxCalendarDateAttr_HasBorder: { // wxCalendarDateAttr::HasBorder
+case wxCalendarDateAttr_HasBorder: { // wxCalendarDateAttr::HasBorder
wxCalendarDateAttr *This = (wxCalendarDateAttr *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
bool Result = This->HasBorder();
rt.addBool(Result);
- break;
+ break;
}
-case wxCalendarDateAttr_IsHoliday: { // wxCalendarDateAttr::IsHoliday
+case wxCalendarDateAttr_IsHoliday: { // wxCalendarDateAttr::IsHoliday
wxCalendarDateAttr *This = (wxCalendarDateAttr *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
bool Result = This->IsHoliday();
rt.addBool(Result);
- break;
+ break;
}
-case wxCalendarDateAttr_GetTextColour: { // wxCalendarDateAttr::GetTextColour
+case wxCalendarDateAttr_GetTextColour: { // wxCalendarDateAttr::GetTextColour
wxCalendarDateAttr *This = (wxCalendarDateAttr *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
const wxColour * Result = &This->GetTextColour();
rt.add((*Result));
- break;
+ break;
}
-case wxCalendarDateAttr_GetBackgroundColour: { // wxCalendarDateAttr::GetBackgroundColour
+case wxCalendarDateAttr_GetBackgroundColour: { // wxCalendarDateAttr::GetBackgroundColour
wxCalendarDateAttr *This = (wxCalendarDateAttr *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
const wxColour * Result = &This->GetBackgroundColour();
rt.add((*Result));
- break;
+ break;
}
-case wxCalendarDateAttr_GetBorderColour: { // wxCalendarDateAttr::GetBorderColour
+case wxCalendarDateAttr_GetBorderColour: { // wxCalendarDateAttr::GetBorderColour
wxCalendarDateAttr *This = (wxCalendarDateAttr *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
const wxColour * Result = &This->GetBorderColour();
rt.add((*Result));
- break;
+ break;
}
-case wxCalendarDateAttr_GetFont: { // wxCalendarDateAttr::GetFont
+case wxCalendarDateAttr_GetFont: { // wxCalendarDateAttr::GetFont
wxCalendarDateAttr *This = (wxCalendarDateAttr *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
const wxFont * Result = &This->GetFont();
rt.addRef(getRef((void *)Result,memenv), "wxFont");
- break;
+ break;
}
-case wxCalendarDateAttr_GetBorder: { // wxCalendarDateAttr::GetBorder
+case wxCalendarDateAttr_GetBorder: { // wxCalendarDateAttr::GetBorder
wxCalendarDateAttr *This = (wxCalendarDateAttr *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
int Result = This->GetBorder();
rt.addInt(Result);
- break;
+ break;
}
-case wxCalendarDateAttr_destroy: { // wxCalendarDateAttr::destroy
+case wxCalendarDateAttr_destroy: { // wxCalendarDateAttr::destroy
wxCalendarDateAttr *This = (wxCalendarDateAttr *) getPtr(bp,memenv); bp += 4;
if(This) { ((WxeApp *) wxTheApp)->clearPtr((void *) This);
delete This;}
- break;
+ break;
}
-case wxCheckBox_new_4: { // wxCheckBox::wxCheckBox
+case wxCheckBox_new_4: { // wxCheckBox::wxCheckBox
wxPoint pos= wxDefaultPosition;
wxSize size= wxDefaultSize;
long style=0;
@@ -13922,7 +13922,7 @@ case wxCheckBox_new_4: { // wxCheckBox::wxCheckBox
int * labelLen = (int *) bp; bp += 4;
wxString label = wxString(bp, wxConvUTF8);
bp += *labelLen+((8-((4+ *labelLen) & 7)) & 7);
- while( * (int*) bp) { switch (* (int*) bp) {
+ while( * (int*) bp) { switch (* (int*) bp) {
case 1: {bp += 4;
int * posX = (int *) bp; bp += 4;
int * posY = (int *) bp; bp += 4;
@@ -13941,19 +13941,19 @@ case wxCheckBox_new_4: { // wxCheckBox::wxCheckBox
case 4: {bp += 4;
validator = (wxValidator *) getPtr(bp,memenv); bp += 4;
} break;
- }};
+ }};
wxCheckBox * Result = new EwxCheckBox(parent,(wxWindowID) *id,label,pos,size,style,*validator);
newPtr((void *) Result, 0, memenv);
rt.addRef(getRef((void *)Result,memenv), "wxCheckBox");
- break;
+ break;
}
-case wxCheckBox_new_0: { // wxCheckBox::wxCheckBox
+case wxCheckBox_new_0: { // wxCheckBox::wxCheckBox
wxCheckBox * Result = new EwxCheckBox();
newPtr((void *) Result, 0, memenv);
rt.addRef(getRef((void *)Result,memenv), "wxCheckBox");
- break;
+ break;
}
-case wxCheckBox_Create: { // wxCheckBox::Create
+case wxCheckBox_Create: { // wxCheckBox::Create
wxPoint pos= wxDefaultPosition;
wxSize size= wxDefaultSize;
long style=0;
@@ -13964,7 +13964,7 @@ case wxCheckBox_Create: { // wxCheckBox::Create
int * labelLen = (int *) bp; bp += 4;
wxString label = wxString(bp, wxConvUTF8);
bp += *labelLen+((8-((0+ *labelLen) & 7)) & 7);
- while( * (int*) bp) { switch (* (int*) bp) {
+ while( * (int*) bp) { switch (* (int*) bp) {
case 1: {bp += 4;
int * posX = (int *) bp; bp += 4;
int * posY = (int *) bp; bp += 4;
@@ -13983,68 +13983,68 @@ case wxCheckBox_Create: { // wxCheckBox::Create
case 4: {bp += 4;
validator = (wxValidator *) getPtr(bp,memenv); bp += 4;
} break;
- }};
+ }};
if(!This) throw wxe_badarg(0);
bool Result = This->Create(parent,(wxWindowID) *id,label,pos,size,style,*validator);
rt.addBool(Result);
- break;
+ break;
}
-case wxCheckBox_GetValue: { // wxCheckBox::GetValue
+case wxCheckBox_GetValue: { // wxCheckBox::GetValue
wxCheckBox *This = (wxCheckBox *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
bool Result = This->GetValue();
rt.addBool(Result);
- break;
+ break;
}
-case wxCheckBox_Get3StateValue: { // wxCheckBox::Get3StateValue
+case wxCheckBox_Get3StateValue: { // wxCheckBox::Get3StateValue
wxCheckBox *This = (wxCheckBox *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
int Result = This->Get3StateValue();
rt.addInt(Result);
- break;
+ break;
}
-case wxCheckBox_Is3rdStateAllowedForUser: { // wxCheckBox::Is3rdStateAllowedForUser
+case wxCheckBox_Is3rdStateAllowedForUser: { // wxCheckBox::Is3rdStateAllowedForUser
wxCheckBox *This = (wxCheckBox *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
bool Result = This->Is3rdStateAllowedForUser();
rt.addBool(Result);
- break;
+ break;
}
-case wxCheckBox_Is3State: { // wxCheckBox::Is3State
+case wxCheckBox_Is3State: { // wxCheckBox::Is3State
wxCheckBox *This = (wxCheckBox *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
bool Result = This->Is3State();
rt.addBool(Result);
- break;
+ break;
}
-case wxCheckBox_IsChecked: { // wxCheckBox::IsChecked
+case wxCheckBox_IsChecked: { // wxCheckBox::IsChecked
wxCheckBox *This = (wxCheckBox *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
bool Result = This->IsChecked();
rt.addBool(Result);
- break;
+ break;
}
-case wxCheckBox_SetValue: { // wxCheckBox::SetValue
+case wxCheckBox_SetValue: { // wxCheckBox::SetValue
wxCheckBox *This = (wxCheckBox *) getPtr(bp,memenv); bp += 4;
bool * state = (bool *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
This->SetValue((bool) *state);
- break;
+ break;
}
-case wxCheckBox_Set3StateValue: { // wxCheckBox::Set3StateValue
+case wxCheckBox_Set3StateValue: { // wxCheckBox::Set3StateValue
wxCheckBox *This = (wxCheckBox *) getPtr(bp,memenv); bp += 4;
wxCheckBoxState state = *(wxCheckBoxState *) bp; bp += 4;;
if(!This) throw wxe_badarg(0);
This->Set3StateValue((wxCheckBoxState) state);
- break;
+ break;
}
-case wxCheckListBox_new_0: { // wxCheckListBox::wxCheckListBox
+case wxCheckListBox_new_0: { // wxCheckListBox::wxCheckListBox
wxCheckListBox * Result = new EwxCheckListBox();
newPtr((void *) Result, 0, memenv);
rt.addRef(getRef((void *)Result,memenv), "wxCheckListBox");
- break;
+ break;
}
-case wxCheckListBox_new_3: { // wxCheckListBox::wxCheckListBox
+case wxCheckListBox_new_3: { // wxCheckListBox::wxCheckListBox
wxPoint pos= wxDefaultPosition;
wxSize size= wxDefaultSize;
wxArrayString choices;
@@ -14052,7 +14052,7 @@ case wxCheckListBox_new_3: { // wxCheckListBox::wxCheckListBox
const wxValidator * validator= &wxDefaultValidator;
wxWindow *parent = (wxWindow *) getPtr(bp,memenv); bp += 4;
int * id = (int *) bp; bp += 4;
- while( * (int*) bp) { switch (* (int*) bp) {
+ while( * (int*) bp) { switch (* (int*) bp) {
case 1: {bp += 4;
int * posX = (int *) bp; bp += 4;
int * posY = (int *) bp; bp += 4;
@@ -14082,34 +14082,34 @@ case wxCheckListBox_new_3: { // wxCheckListBox::wxCheckListBox
case 5: {bp += 4;
validator = (wxValidator *) getPtr(bp,memenv); bp += 4;
} break;
- }};
+ }};
wxCheckListBox * Result = new EwxCheckListBox(parent,(wxWindowID) *id,pos,size,choices,style,*validator);
newPtr((void *) Result, 0, memenv);
rt.addRef(getRef((void *)Result,memenv), "wxCheckListBox");
- break;
+ break;
}
-case wxCheckListBox_Check: { // wxCheckListBox::Check
+case wxCheckListBox_Check: { // wxCheckListBox::Check
bool check=true;
wxCheckListBox *This = (wxCheckListBox *) getPtr(bp,memenv); bp += 4;
unsigned int * index = (unsigned int *) bp; bp += 4;
- while( * (int*) bp) { switch (* (int*) bp) {
+ while( * (int*) bp) { switch (* (int*) bp) {
case 1: {bp += 4;
check = *(bool *) bp; bp += 4;
} break;
- }};
+ }};
if(!This) throw wxe_badarg(0);
This->Check((int) *index,check);
- break;
+ break;
}
-case wxCheckListBox_IsChecked: { // wxCheckListBox::IsChecked
+case wxCheckListBox_IsChecked: { // wxCheckListBox::IsChecked
wxCheckListBox *This = (wxCheckListBox *) getPtr(bp,memenv); bp += 4;
unsigned int * index = (unsigned int *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
bool Result = This->IsChecked((int) *index);
rt.addBool(Result);
- break;
+ break;
}
-case wxChoice_new_3: { // wxChoice::wxChoice
+case wxChoice_new_3: { // wxChoice::wxChoice
wxPoint pos= wxDefaultPosition;
wxSize size= wxDefaultSize;
wxArrayString choices;
@@ -14117,7 +14117,7 @@ case wxChoice_new_3: { // wxChoice::wxChoice
const wxValidator * validator= &wxDefaultValidator;
wxWindow *parent = (wxWindow *) getPtr(bp,memenv); bp += 4;
int * id = (int *) bp; bp += 4;
- while( * (int*) bp) { switch (* (int*) bp) {
+ while( * (int*) bp) { switch (* (int*) bp) {
case 1: {bp += 4;
int * posX = (int *) bp; bp += 4;
int * posY = (int *) bp; bp += 4;
@@ -14147,19 +14147,19 @@ case wxChoice_new_3: { // wxChoice::wxChoice
case 5: {bp += 4;
validator = (wxValidator *) getPtr(bp,memenv); bp += 4;
} break;
- }};
+ }};
wxChoice * Result = new EwxChoice(parent,(wxWindowID) *id,pos,size,choices,style,*validator);
newPtr((void *) Result, 0, memenv);
rt.addRef(getRef((void *)Result,memenv), "wxChoice");
- break;
+ break;
}
-case wxChoice_new_0: { // wxChoice::wxChoice
+case wxChoice_new_0: { // wxChoice::wxChoice
wxChoice * Result = new EwxChoice();
newPtr((void *) Result, 0, memenv);
rt.addRef(getRef((void *)Result,memenv), "wxChoice");
- break;
+ break;
}
-case wxChoice_Create: { // wxChoice::Create
+case wxChoice_Create: { // wxChoice::Create
long style=0;
const wxValidator * validator= &wxDefaultValidator;
wxChoice *This = (wxChoice *) getPtr(bp,memenv); bp += 4;
@@ -14181,53 +14181,53 @@ case wxChoice_Create: { // wxChoice::Create
choicesASz += *choicesTemp+4;
}
bp += (8-((0+ choicesASz) & 7 )) & 7;
- while( * (int*) bp) { switch (* (int*) bp) {
+ while( * (int*) bp) { switch (* (int*) bp) {
case 1: {bp += 4;
style = (long)*(int *) bp; bp += 4;
} break;
case 2: {bp += 4;
validator = (wxValidator *) getPtr(bp,memenv); bp += 4;
} break;
- }};
+ }};
if(!This) throw wxe_badarg(0);
bool Result = This->Create(parent,(wxWindowID) *id,pos,size,choices,style,*validator);
rt.addBool(Result);
- break;
+ break;
}
-case wxChoice_Delete: { // wxChoice::Delete
+case wxChoice_Delete: { // wxChoice::Delete
wxChoice *This = (wxChoice *) getPtr(bp,memenv); bp += 4;
unsigned int * n = (unsigned int *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
This->Delete((int) *n);
- break;
+ break;
}
-case wxChoice_GetColumns: { // wxChoice::GetColumns
+case wxChoice_GetColumns: { // wxChoice::GetColumns
wxChoice *This = (wxChoice *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
int Result = This->GetColumns();
rt.addInt(Result);
- break;
+ break;
}
-case wxChoice_SetColumns: { // wxChoice::SetColumns
+case wxChoice_SetColumns: { // wxChoice::SetColumns
int n=1;
wxChoice *This = (wxChoice *) getPtr(bp,memenv); bp += 4;
bp += 4; /* Align */
- while( * (int*) bp) { switch (* (int*) bp) {
+ while( * (int*) bp) { switch (* (int*) bp) {
case 1: {bp += 4;
n = (int)*(int *) bp; bp += 4;
} break;
- }};
+ }};
if(!This) throw wxe_badarg(0);
This->SetColumns(n);
- break;
+ break;
}
-case wxComboBox_new_0: { // wxComboBox::wxComboBox
+case wxComboBox_new_0: { // wxComboBox::wxComboBox
wxComboBox * Result = new EwxComboBox();
newPtr((void *) Result, 0, memenv);
rt.addRef(getRef((void *)Result,memenv), "wxComboBox");
- break;
+ break;
}
-case wxComboBox_new_3: { // wxComboBox::wxComboBox
+case wxComboBox_new_3: { // wxComboBox::wxComboBox
wxString value= wxEmptyString;
wxPoint pos= wxDefaultPosition;
wxSize size= wxDefaultSize;
@@ -14236,7 +14236,7 @@ case wxComboBox_new_3: { // wxComboBox::wxComboBox
const wxValidator * validator= &wxDefaultValidator;
wxWindow *parent = (wxWindow *) getPtr(bp,memenv); bp += 4;
int * id = (int *) bp; bp += 4;
- while( * (int*) bp) { switch (* (int*) bp) {
+ while( * (int*) bp) { switch (* (int*) bp) {
case 1: {bp += 4;
int * valueLen = (int *) bp; bp += 4;
value = wxString(bp, wxConvUTF8);
@@ -14271,13 +14271,13 @@ case wxComboBox_new_3: { // wxComboBox::wxComboBox
case 6: {bp += 4;
validator = (wxValidator *) getPtr(bp,memenv); bp += 4;
} break;
- }};
+ }};
wxComboBox * Result = new EwxComboBox(parent,(wxWindowID) *id,value,pos,size,choices,style,*validator);
newPtr((void *) Result, 0, memenv);
rt.addRef(getRef((void *)Result,memenv), "wxComboBox");
- break;
+ break;
}
-case wxComboBox_Create: { // wxComboBox::Create
+case wxComboBox_Create: { // wxComboBox::Create
long style=0;
const wxValidator * validator= &wxDefaultValidator;
wxComboBox *This = (wxComboBox *) getPtr(bp,memenv); bp += 4;
@@ -14302,100 +14302,100 @@ case wxComboBox_Create: { // wxComboBox::Create
choicesASz += *choicesTemp+4;
}
bp += (8-((4+ choicesASz) & 7 )) & 7;
- while( * (int*) bp) { switch (* (int*) bp) {
+ while( * (int*) bp) { switch (* (int*) bp) {
case 1: {bp += 4;
style = (long)*(int *) bp; bp += 4;
} break;
case 2: {bp += 4;
validator = (wxValidator *) getPtr(bp,memenv); bp += 4;
} break;
- }};
+ }};
if(!This) throw wxe_badarg(0);
bool Result = This->Create(parent,(wxWindowID) *id,value,pos,size,choices,style,*validator);
rt.addBool(Result);
- break;
+ break;
}
-case wxComboBox_CanCopy: { // wxComboBox::CanCopy
+case wxComboBox_CanCopy: { // wxComboBox::CanCopy
wxComboBox *This = (wxComboBox *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
bool Result = This->CanCopy();
rt.addBool(Result);
- break;
+ break;
}
-case wxComboBox_CanCut: { // wxComboBox::CanCut
+case wxComboBox_CanCut: { // wxComboBox::CanCut
wxComboBox *This = (wxComboBox *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
bool Result = This->CanCut();
rt.addBool(Result);
- break;
+ break;
}
-case wxComboBox_CanPaste: { // wxComboBox::CanPaste
+case wxComboBox_CanPaste: { // wxComboBox::CanPaste
wxComboBox *This = (wxComboBox *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
bool Result = This->CanPaste();
rt.addBool(Result);
- break;
+ break;
}
-case wxComboBox_CanRedo: { // wxComboBox::CanRedo
+case wxComboBox_CanRedo: { // wxComboBox::CanRedo
wxComboBox *This = (wxComboBox *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
bool Result = This->CanRedo();
rt.addBool(Result);
- break;
+ break;
}
-case wxComboBox_CanUndo: { // wxComboBox::CanUndo
+case wxComboBox_CanUndo: { // wxComboBox::CanUndo
wxComboBox *This = (wxComboBox *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
bool Result = This->CanUndo();
rt.addBool(Result);
- break;
+ break;
}
-case wxComboBox_Copy: { // wxComboBox::Copy
+case wxComboBox_Copy: { // wxComboBox::Copy
wxComboBox *This = (wxComboBox *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
This->Copy();
- break;
+ break;
}
-case wxComboBox_Cut: { // wxComboBox::Cut
+case wxComboBox_Cut: { // wxComboBox::Cut
wxComboBox *This = (wxComboBox *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
This->Cut();
- break;
+ break;
}
-case wxComboBox_GetInsertionPoint: { // wxComboBox::GetInsertionPoint
+case wxComboBox_GetInsertionPoint: { // wxComboBox::GetInsertionPoint
wxComboBox *This = (wxComboBox *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
long Result = This->GetInsertionPoint();
rt.addInt(Result);
- break;
+ break;
}
-case wxComboBox_GetLastPosition: { // wxComboBox::GetLastPosition
+case wxComboBox_GetLastPosition: { // wxComboBox::GetLastPosition
wxComboBox *This = (wxComboBox *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
wxTextPos Result = This->GetLastPosition();
rt.addInt(Result);
- break;
+ break;
}
-case wxComboBox_GetValue: { // wxComboBox::GetValue
+case wxComboBox_GetValue: { // wxComboBox::GetValue
wxComboBox *This = (wxComboBox *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
wxString Result = This->GetValue();
rt.add(Result);
- break;
+ break;
}
-case wxComboBox_Paste: { // wxComboBox::Paste
+case wxComboBox_Paste: { // wxComboBox::Paste
wxComboBox *This = (wxComboBox *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
This->Paste();
- break;
+ break;
}
-case wxComboBox_Redo: { // wxComboBox::Redo
+case wxComboBox_Redo: { // wxComboBox::Redo
wxComboBox *This = (wxComboBox *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
This->Redo();
- break;
+ break;
}
-case wxComboBox_Replace: { // wxComboBox::Replace
+case wxComboBox_Replace: { // wxComboBox::Replace
wxComboBox *This = (wxComboBox *) getPtr(bp,memenv); bp += 4;
int * from = (int *) bp; bp += 4;
int * to = (int *) bp; bp += 4;
@@ -14404,66 +14404,66 @@ case wxComboBox_Replace: { // wxComboBox::Replace
bp += *valueLen+((8-((0+ *valueLen) & 7)) & 7);
if(!This) throw wxe_badarg(0);
This->Replace((long) *from,(long) *to,value);
- break;
+ break;
}
-case wxComboBox_Remove: { // wxComboBox::Remove
+case wxComboBox_Remove: { // wxComboBox::Remove
wxComboBox *This = (wxComboBox *) getPtr(bp,memenv); bp += 4;
int * from = (int *) bp; bp += 4;
int * to = (int *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
This->Remove((long) *from,(long) *to);
- break;
+ break;
}
-case wxComboBox_SetInsertionPoint: { // wxComboBox::SetInsertionPoint
+case wxComboBox_SetInsertionPoint: { // wxComboBox::SetInsertionPoint
wxComboBox *This = (wxComboBox *) getPtr(bp,memenv); bp += 4;
int * pos = (int *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
This->SetInsertionPoint((long) *pos);
- break;
+ break;
}
-case wxComboBox_SetInsertionPointEnd: { // wxComboBox::SetInsertionPointEnd
+case wxComboBox_SetInsertionPointEnd: { // wxComboBox::SetInsertionPointEnd
wxComboBox *This = (wxComboBox *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
This->SetInsertionPointEnd();
- break;
+ break;
}
-case wxComboBox_SetSelection_1: { // wxComboBox::SetSelection
+case wxComboBox_SetSelection_1: { // wxComboBox::SetSelection
wxComboBox *This = (wxComboBox *) getPtr(bp,memenv); bp += 4;
int * n = (int *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
This->SetSelection((int) *n);
- break;
+ break;
}
-case wxComboBox_SetSelection_2: { // wxComboBox::SetSelection
+case wxComboBox_SetSelection_2: { // wxComboBox::SetSelection
wxComboBox *This = (wxComboBox *) getPtr(bp,memenv); bp += 4;
int * from = (int *) bp; bp += 4;
int * to = (int *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
This->SetSelection((long) *from,(long) *to);
- break;
+ break;
}
-case wxComboBox_SetValue: { // wxComboBox::SetValue
+case wxComboBox_SetValue: { // wxComboBox::SetValue
wxComboBox *This = (wxComboBox *) getPtr(bp,memenv); bp += 4;
int * valueLen = (int *) bp; bp += 4;
wxString value = wxString(bp, wxConvUTF8);
bp += *valueLen+((8-((0+ *valueLen) & 7)) & 7);
if(!This) throw wxe_badarg(0);
This->SetValue(value);
- break;
+ break;
}
-case wxComboBox_Undo: { // wxComboBox::Undo
+case wxComboBox_Undo: { // wxComboBox::Undo
wxComboBox *This = (wxComboBox *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
This->Undo();
- break;
+ break;
}
-case wxGauge_new_0: { // wxGauge::wxGauge
+case wxGauge_new_0: { // wxGauge::wxGauge
wxGauge * Result = new EwxGauge();
newPtr((void *) Result, 0, memenv);
rt.addRef(getRef((void *)Result,memenv), "wxGauge");
- break;
+ break;
}
-case wxGauge_new_4: { // wxGauge::wxGauge
+case wxGauge_new_4: { // wxGauge::wxGauge
wxPoint pos= wxDefaultPosition;
wxSize size= wxDefaultSize;
long style=wxGA_HORIZONTAL;
@@ -14472,7 +14472,7 @@ case wxGauge_new_4: { // wxGauge::wxGauge
int * id = (int *) bp; bp += 4;
int * range = (int *) bp; bp += 4;
bp += 4; /* Align */
- while( * (int*) bp) { switch (* (int*) bp) {
+ while( * (int*) bp) { switch (* (int*) bp) {
case 1: {bp += 4;
int * posX = (int *) bp; bp += 4;
int * posY = (int *) bp; bp += 4;
@@ -14491,13 +14491,13 @@ case wxGauge_new_4: { // wxGauge::wxGauge
case 4: {bp += 4;
validator = (wxValidator *) getPtr(bp,memenv); bp += 4;
} break;
- }};
+ }};
wxGauge * Result = new EwxGauge(parent,(wxWindowID) *id,(int) *range,pos,size,style,*validator);
newPtr((void *) Result, 0, memenv);
rt.addRef(getRef((void *)Result,memenv), "wxGauge");
- break;
+ break;
}
-case wxGauge_Create: { // wxGauge::Create
+case wxGauge_Create: { // wxGauge::Create
wxPoint pos= wxDefaultPosition;
wxSize size= wxDefaultSize;
long style=wxGA_HORIZONTAL;
@@ -14506,7 +14506,7 @@ case wxGauge_Create: { // wxGauge::Create
wxWindow *parent = (wxWindow *) getPtr(bp,memenv); bp += 4;
int * id = (int *) bp; bp += 4;
int * range = (int *) bp; bp += 4;
- while( * (int*) bp) { switch (* (int*) bp) {
+ while( * (int*) bp) { switch (* (int*) bp) {
case 1: {bp += 4;
int * posX = (int *) bp; bp += 4;
int * posY = (int *) bp; bp += 4;
@@ -14525,88 +14525,88 @@ case wxGauge_Create: { // wxGauge::Create
case 4: {bp += 4;
validator = (wxValidator *) getPtr(bp,memenv); bp += 4;
} break;
- }};
+ }};
if(!This) throw wxe_badarg(0);
bool Result = This->Create(parent,(wxWindowID) *id,(int) *range,pos,size,style,*validator);
rt.addBool(Result);
- break;
+ break;
}
-case wxGauge_GetBezelFace: { // wxGauge::GetBezelFace
+case wxGauge_GetBezelFace: { // wxGauge::GetBezelFace
wxGauge *This = (wxGauge *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
int Result = This->GetBezelFace();
rt.addInt(Result);
- break;
+ break;
}
-case wxGauge_GetRange: { // wxGauge::GetRange
+case wxGauge_GetRange: { // wxGauge::GetRange
wxGauge *This = (wxGauge *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
int Result = This->GetRange();
rt.addInt(Result);
- break;
+ break;
}
-case wxGauge_GetShadowWidth: { // wxGauge::GetShadowWidth
+case wxGauge_GetShadowWidth: { // wxGauge::GetShadowWidth
wxGauge *This = (wxGauge *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
int Result = This->GetShadowWidth();
rt.addInt(Result);
- break;
+ break;
}
-case wxGauge_GetValue: { // wxGauge::GetValue
+case wxGauge_GetValue: { // wxGauge::GetValue
wxGauge *This = (wxGauge *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
int Result = This->GetValue();
rt.addInt(Result);
- break;
+ break;
}
-case wxGauge_IsVertical: { // wxGauge::IsVertical
+case wxGauge_IsVertical: { // wxGauge::IsVertical
wxGauge *This = (wxGauge *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
bool Result = This->IsVertical();
rt.addBool(Result);
- break;
+ break;
}
-case wxGauge_SetBezelFace: { // wxGauge::SetBezelFace
+case wxGauge_SetBezelFace: { // wxGauge::SetBezelFace
wxGauge *This = (wxGauge *) getPtr(bp,memenv); bp += 4;
int * w = (int *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
This->SetBezelFace((int) *w);
- break;
+ break;
}
-case wxGauge_SetRange: { // wxGauge::SetRange
+case wxGauge_SetRange: { // wxGauge::SetRange
wxGauge *This = (wxGauge *) getPtr(bp,memenv); bp += 4;
int * r = (int *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
This->SetRange((int) *r);
- break;
+ break;
}
-case wxGauge_SetShadowWidth: { // wxGauge::SetShadowWidth
+case wxGauge_SetShadowWidth: { // wxGauge::SetShadowWidth
wxGauge *This = (wxGauge *) getPtr(bp,memenv); bp += 4;
int * w = (int *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
This->SetShadowWidth((int) *w);
- break;
+ break;
}
-case wxGauge_SetValue: { // wxGauge::SetValue
+case wxGauge_SetValue: { // wxGauge::SetValue
wxGauge *This = (wxGauge *) getPtr(bp,memenv); bp += 4;
int * pos = (int *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
This->SetValue((int) *pos);
- break;
+ break;
}
-case wxGauge_Pulse: { // wxGauge::Pulse
+case wxGauge_Pulse: { // wxGauge::Pulse
wxGauge *This = (wxGauge *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
This->Pulse();
- break;
+ break;
}
-case wxGenericDirCtrl_new_0: { // wxGenericDirCtrl::wxGenericDirCtrl
+case wxGenericDirCtrl_new_0: { // wxGenericDirCtrl::wxGenericDirCtrl
wxGenericDirCtrl * Result = new EwxGenericDirCtrl();
newPtr((void *) Result, 0, memenv);
rt.addRef(getRef((void *)Result,memenv), "wxGenericDirCtrl");
- break;
+ break;
}
-case wxGenericDirCtrl_new_2: { // wxGenericDirCtrl::wxGenericDirCtrl
+case wxGenericDirCtrl_new_2: { // wxGenericDirCtrl::wxGenericDirCtrl
wxWindowID id=wxID_ANY;
wxString dir= wxDirDialogDefaultFolderStr;
wxPoint pos= wxDefaultPosition;
@@ -14616,7 +14616,7 @@ case wxGenericDirCtrl_new_2: { // wxGenericDirCtrl::wxGenericDirCtrl
int defaultFilter=0;
wxWindow *parent = (wxWindow *) getPtr(bp,memenv); bp += 4;
bp += 4; /* Align */
- while( * (int*) bp) { switch (* (int*) bp) {
+ while( * (int*) bp) { switch (* (int*) bp) {
case 1: {bp += 4;
id = (wxWindowID)*(const int *) bp; bp += 4;
} break;
@@ -14648,13 +14648,13 @@ case wxGenericDirCtrl_new_2: { // wxGenericDirCtrl::wxGenericDirCtrl
case 7: {bp += 4;
defaultFilter = (int)*(int *) bp; bp += 4;
} break;
- }};
+ }};
wxGenericDirCtrl * Result = new EwxGenericDirCtrl(parent,id,dir,pos,size,style,filter,defaultFilter);
newPtr((void *) Result, 0, memenv);
rt.addRef(getRef((void *)Result,memenv), "wxGenericDirCtrl");
- break;
+ break;
}
-case wxGenericDirCtrl_Create: { // wxGenericDirCtrl::Create
+case wxGenericDirCtrl_Create: { // wxGenericDirCtrl::Create
wxWindowID id=wxID_ANY;
wxString dir= wxDirDialogDefaultFolderStr;
wxPoint pos= wxDefaultPosition;
@@ -14664,7 +14664,7 @@ case wxGenericDirCtrl_Create: { // wxGenericDirCtrl::Create
int defaultFilter=0;
wxGenericDirCtrl *This = (wxGenericDirCtrl *) getPtr(bp,memenv); bp += 4;
wxWindow *parent = (wxWindow *) getPtr(bp,memenv); bp += 4;
- while( * (int*) bp) { switch (* (int*) bp) {
+ while( * (int*) bp) { switch (* (int*) bp) {
case 1: {bp += 4;
id = (wxWindowID)*(const int *) bp; bp += 4;
} break;
@@ -14696,25 +14696,25 @@ case wxGenericDirCtrl_Create: { // wxGenericDirCtrl::Create
case 7: {bp += 4;
defaultFilter = (int)*(int *) bp; bp += 4;
} break;
- }};
+ }};
if(!This) throw wxe_badarg(0);
bool Result = This->Create(parent,id,dir,pos,size,style,filter,defaultFilter);
rt.addBool(Result);
- break;
+ break;
}
-case wxGenericDirCtrl_Init: { // wxGenericDirCtrl::Init
+case wxGenericDirCtrl_Init: { // wxGenericDirCtrl::Init
wxGenericDirCtrl *This = (wxGenericDirCtrl *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
This->Init();
- break;
+ break;
}
-case wxGenericDirCtrl_CollapseTree: { // wxGenericDirCtrl::CollapseTree
+case wxGenericDirCtrl_CollapseTree: { // wxGenericDirCtrl::CollapseTree
wxGenericDirCtrl *This = (wxGenericDirCtrl *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
This->CollapseTree();
- break;
+ break;
}
-case wxGenericDirCtrl_ExpandPath: { // wxGenericDirCtrl::ExpandPath
+case wxGenericDirCtrl_ExpandPath: { // wxGenericDirCtrl::ExpandPath
wxGenericDirCtrl *This = (wxGenericDirCtrl *) getPtr(bp,memenv); bp += 4;
int * pathLen = (int *) bp; bp += 4;
wxString path = wxString(bp, wxConvUTF8);
@@ -14722,98 +14722,98 @@ case wxGenericDirCtrl_ExpandPath: { // wxGenericDirCtrl::ExpandPath
if(!This) throw wxe_badarg(0);
bool Result = This->ExpandPath(path);
rt.addBool(Result);
- break;
+ break;
}
-case wxGenericDirCtrl_GetDefaultPath: { // wxGenericDirCtrl::GetDefaultPath
+case wxGenericDirCtrl_GetDefaultPath: { // wxGenericDirCtrl::GetDefaultPath
wxGenericDirCtrl *This = (wxGenericDirCtrl *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
wxString Result = This->GetDefaultPath();
rt.add(Result);
- break;
+ break;
}
-case wxGenericDirCtrl_GetPath: { // wxGenericDirCtrl::GetPath
+case wxGenericDirCtrl_GetPath: { // wxGenericDirCtrl::GetPath
wxGenericDirCtrl *This = (wxGenericDirCtrl *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
wxString Result = This->GetPath();
rt.add(Result);
- break;
+ break;
}
-case wxGenericDirCtrl_GetFilePath: { // wxGenericDirCtrl::GetFilePath
+case wxGenericDirCtrl_GetFilePath: { // wxGenericDirCtrl::GetFilePath
wxGenericDirCtrl *This = (wxGenericDirCtrl *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
wxString Result = This->GetFilePath();
rt.add(Result);
- break;
+ break;
}
-case wxGenericDirCtrl_GetFilter: { // wxGenericDirCtrl::GetFilter
+case wxGenericDirCtrl_GetFilter: { // wxGenericDirCtrl::GetFilter
wxGenericDirCtrl *This = (wxGenericDirCtrl *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
wxString Result = This->GetFilter();
rt.add(Result);
- break;
+ break;
}
-case wxGenericDirCtrl_GetFilterIndex: { // wxGenericDirCtrl::GetFilterIndex
+case wxGenericDirCtrl_GetFilterIndex: { // wxGenericDirCtrl::GetFilterIndex
wxGenericDirCtrl *This = (wxGenericDirCtrl *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
int Result = This->GetFilterIndex();
rt.addInt(Result);
- break;
+ break;
}
-case wxGenericDirCtrl_GetRootId: { // wxGenericDirCtrl::GetRootId
+case wxGenericDirCtrl_GetRootId: { // wxGenericDirCtrl::GetRootId
wxGenericDirCtrl *This = (wxGenericDirCtrl *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
wxTreeItemId Result = This->GetRootId();
- rt.addRef(getRef((void *)Result.m_pItem,memenv), "wxTreeItemId");
- break;
+ rt.add((wxUIntPtr *) Result.m_pItem);
+ break;
}
-case wxGenericDirCtrl_GetTreeCtrl: { // wxGenericDirCtrl::GetTreeCtrl
+case wxGenericDirCtrl_GetTreeCtrl: { // wxGenericDirCtrl::GetTreeCtrl
wxGenericDirCtrl *This = (wxGenericDirCtrl *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
wxTreeCtrl * Result = (wxTreeCtrl*)This->GetTreeCtrl();
rt.addRef(getRef((void *)Result,memenv), "wxTreeCtrl");
- break;
+ break;
}
-case wxGenericDirCtrl_ReCreateTree: { // wxGenericDirCtrl::ReCreateTree
+case wxGenericDirCtrl_ReCreateTree: { // wxGenericDirCtrl::ReCreateTree
wxGenericDirCtrl *This = (wxGenericDirCtrl *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
This->ReCreateTree();
- break;
+ break;
}
-case wxGenericDirCtrl_SetDefaultPath: { // wxGenericDirCtrl::SetDefaultPath
+case wxGenericDirCtrl_SetDefaultPath: { // wxGenericDirCtrl::SetDefaultPath
wxGenericDirCtrl *This = (wxGenericDirCtrl *) getPtr(bp,memenv); bp += 4;
int * pathLen = (int *) bp; bp += 4;
wxString path = wxString(bp, wxConvUTF8);
bp += *pathLen+((8-((0+ *pathLen) & 7)) & 7);
if(!This) throw wxe_badarg(0);
This->SetDefaultPath(path);
- break;
+ break;
}
-case wxGenericDirCtrl_SetFilter: { // wxGenericDirCtrl::SetFilter
+case wxGenericDirCtrl_SetFilter: { // wxGenericDirCtrl::SetFilter
wxGenericDirCtrl *This = (wxGenericDirCtrl *) getPtr(bp,memenv); bp += 4;
int * filterLen = (int *) bp; bp += 4;
wxString filter = wxString(bp, wxConvUTF8);
bp += *filterLen+((8-((0+ *filterLen) & 7)) & 7);
if(!This) throw wxe_badarg(0);
This->SetFilter(filter);
- break;
+ break;
}
-case wxGenericDirCtrl_SetFilterIndex: { // wxGenericDirCtrl::SetFilterIndex
+case wxGenericDirCtrl_SetFilterIndex: { // wxGenericDirCtrl::SetFilterIndex
wxGenericDirCtrl *This = (wxGenericDirCtrl *) getPtr(bp,memenv); bp += 4;
int * n = (int *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
This->SetFilterIndex((int) *n);
- break;
+ break;
}
-case wxGenericDirCtrl_SetPath: { // wxGenericDirCtrl::SetPath
+case wxGenericDirCtrl_SetPath: { // wxGenericDirCtrl::SetPath
wxGenericDirCtrl *This = (wxGenericDirCtrl *) getPtr(bp,memenv); bp += 4;
int * pathLen = (int *) bp; bp += 4;
wxString path = wxString(bp, wxConvUTF8);
bp += *pathLen+((8-((0+ *pathLen) & 7)) & 7);
if(!This) throw wxe_badarg(0);
This->SetPath(path);
- break;
+ break;
}
-case wxStaticBox_new_4: { // wxStaticBox::wxStaticBox
+case wxStaticBox_new_4: { // wxStaticBox::wxStaticBox
wxPoint pos= wxDefaultPosition;
wxSize size= wxDefaultSize;
long style=0;
@@ -14822,7 +14822,7 @@ case wxStaticBox_new_4: { // wxStaticBox::wxStaticBox
int * labelLen = (int *) bp; bp += 4;
wxString label = wxString(bp, wxConvUTF8);
bp += *labelLen+((8-((4+ *labelLen) & 7)) & 7);
- while( * (int*) bp) { switch (* (int*) bp) {
+ while( * (int*) bp) { switch (* (int*) bp) {
case 1: {bp += 4;
int * posX = (int *) bp; bp += 4;
int * posY = (int *) bp; bp += 4;
@@ -14838,19 +14838,19 @@ case wxStaticBox_new_4: { // wxStaticBox::wxStaticBox
case 3: {bp += 4;
style = (long)*(int *) bp; bp += 4;
} break;
- }};
+ }};
wxStaticBox * Result = new EwxStaticBox(parent,(wxWindowID) *id,label,pos,size,style);
newPtr((void *) Result, 0, memenv);
rt.addRef(getRef((void *)Result,memenv), "wxStaticBox");
- break;
+ break;
}
-case wxStaticBox_new_0: { // wxStaticBox::wxStaticBox
+case wxStaticBox_new_0: { // wxStaticBox::wxStaticBox
wxStaticBox * Result = new EwxStaticBox();
newPtr((void *) Result, 0, memenv);
rt.addRef(getRef((void *)Result,memenv), "wxStaticBox");
- break;
+ break;
}
-case wxStaticBox_Create: { // wxStaticBox::Create
+case wxStaticBox_Create: { // wxStaticBox::Create
wxPoint pos= wxDefaultPosition;
wxSize size= wxDefaultSize;
long style=0;
@@ -14860,7 +14860,7 @@ case wxStaticBox_Create: { // wxStaticBox::Create
int * labelLen = (int *) bp; bp += 4;
wxString label = wxString(bp, wxConvUTF8);
bp += *labelLen+((8-((0+ *labelLen) & 7)) & 7);
- while( * (int*) bp) { switch (* (int*) bp) {
+ while( * (int*) bp) { switch (* (int*) bp) {
case 1: {bp += 4;
int * posX = (int *) bp; bp += 4;
int * posY = (int *) bp; bp += 4;
@@ -14876,20 +14876,20 @@ case wxStaticBox_Create: { // wxStaticBox::Create
case 3: {bp += 4;
style = (long)*(int *) bp; bp += 4;
} break;
- }};
+ }};
if(!This) throw wxe_badarg(0);
bool Result = This->Create(parent,(wxWindowID) *id,label,pos,size,style);
rt.addBool(Result);
- break;
+ break;
}
-case wxStaticLine_new_2: { // wxStaticLine::wxStaticLine
+case wxStaticLine_new_2: { // wxStaticLine::wxStaticLine
wxWindowID id=wxID_ANY;
wxPoint pos= wxDefaultPosition;
wxSize size= wxDefaultSize;
long style=wxLI_HORIZONTAL;
wxWindow *parent = (wxWindow *) getPtr(bp,memenv); bp += 4;
bp += 4; /* Align */
- while( * (int*) bp) { switch (* (int*) bp) {
+ while( * (int*) bp) { switch (* (int*) bp) {
case 1: {bp += 4;
id = (wxWindowID)*(int *) bp; bp += 4;
} break;
@@ -14908,26 +14908,26 @@ case wxStaticLine_new_2: { // wxStaticLine::wxStaticLine
case 4: {bp += 4;
style = (long)*(int *) bp; bp += 4;
} break;
- }};
+ }};
wxStaticLine * Result = new EwxStaticLine(parent,id,pos,size,style);
newPtr((void *) Result, 0, memenv);
rt.addRef(getRef((void *)Result,memenv), "wxStaticLine");
- break;
+ break;
}
-case wxStaticLine_new_0: { // wxStaticLine::wxStaticLine
+case wxStaticLine_new_0: { // wxStaticLine::wxStaticLine
wxStaticLine * Result = new EwxStaticLine();
newPtr((void *) Result, 0, memenv);
rt.addRef(getRef((void *)Result,memenv), "wxStaticLine");
- break;
+ break;
}
-case wxStaticLine_Create: { // wxStaticLine::Create
+case wxStaticLine_Create: { // wxStaticLine::Create
wxWindowID id=wxID_ANY;
wxPoint pos= wxDefaultPosition;
wxSize size= wxDefaultSize;
long style=wxLI_HORIZONTAL;
wxStaticLine *This = (wxStaticLine *) getPtr(bp,memenv); bp += 4;
wxWindow *parent = (wxWindow *) getPtr(bp,memenv); bp += 4;
- while( * (int*) bp) { switch (* (int*) bp) {
+ while( * (int*) bp) { switch (* (int*) bp) {
case 1: {bp += 4;
id = (wxWindowID)*(int *) bp; bp += 4;
} break;
@@ -14946,25 +14946,25 @@ case wxStaticLine_Create: { // wxStaticLine::Create
case 4: {bp += 4;
style = (long)*(int *) bp; bp += 4;
} break;
- }};
+ }};
if(!This) throw wxe_badarg(0);
bool Result = This->Create(parent,id,pos,size,style);
rt.addBool(Result);
- break;
+ break;
}
-case wxStaticLine_IsVertical: { // wxStaticLine::IsVertical
+case wxStaticLine_IsVertical: { // wxStaticLine::IsVertical
wxStaticLine *This = (wxStaticLine *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
bool Result = This->IsVertical();
rt.addBool(Result);
- break;
+ break;
}
-case wxStaticLine_GetDefaultSize: { // wxStaticLine::GetDefaultSize
+case wxStaticLine_GetDefaultSize: { // wxStaticLine::GetDefaultSize
int Result = wxStaticLine::GetDefaultSize();
rt.addInt(Result);
- break;
+ break;
}
-case wxListBox_new_3: { // wxListBox::wxListBox
+case wxListBox_new_3: { // wxListBox::wxListBox
wxPoint pos= wxDefaultPosition;
wxSize size= wxDefaultSize;
wxArrayString choices;
@@ -14972,7 +14972,7 @@ case wxListBox_new_3: { // wxListBox::wxListBox
const wxValidator * validator= &wxDefaultValidator;
wxWindow *parent = (wxWindow *) getPtr(bp,memenv); bp += 4;
int * id = (int *) bp; bp += 4;
- while( * (int*) bp) { switch (* (int*) bp) {
+ while( * (int*) bp) { switch (* (int*) bp) {
case 1: {bp += 4;
int * posX = (int *) bp; bp += 4;
int * posY = (int *) bp; bp += 4;
@@ -15002,19 +15002,19 @@ case wxListBox_new_3: { // wxListBox::wxListBox
case 5: {bp += 4;
validator = (wxValidator *) getPtr(bp,memenv); bp += 4;
} break;
- }};
+ }};
wxListBox * Result = new EwxListBox(parent,(wxWindowID) *id,pos,size,choices,style,*validator);
newPtr((void *) Result, 0, memenv);
rt.addRef(getRef((void *)Result,memenv), "wxListBox");
- break;
+ break;
}
-case wxListBox_new_0: { // wxListBox::wxListBox
+case wxListBox_new_0: { // wxListBox::wxListBox
wxListBox * Result = new EwxListBox();
newPtr((void *) Result, 0, memenv);
rt.addRef(getRef((void *)Result,memenv), "wxListBox");
- break;
+ break;
}
-case wxListBox_Create: { // wxListBox::Create
+case wxListBox_Create: { // wxListBox::Create
long style=0;
const wxValidator * validator= &wxDefaultValidator;
wxListBox *This = (wxListBox *) getPtr(bp,memenv); bp += 4;
@@ -15036,27 +15036,27 @@ case wxListBox_Create: { // wxListBox::Create
choicesASz += *choicesTemp+4;
}
bp += (8-((0+ choicesASz) & 7 )) & 7;
- while( * (int*) bp) { switch (* (int*) bp) {
+ while( * (int*) bp) { switch (* (int*) bp) {
case 1: {bp += 4;
style = (long)*(int *) bp; bp += 4;
} break;
case 2: {bp += 4;
validator = (wxValidator *) getPtr(bp,memenv); bp += 4;
} break;
- }};
+ }};
if(!This) throw wxe_badarg(0);
bool Result = This->Create(parent,(wxWindowID) *id,pos,size,choices,style,*validator);
rt.addBool(Result);
- break;
+ break;
}
-case wxListBox_Deselect: { // wxListBox::Deselect
+case wxListBox_Deselect: { // wxListBox::Deselect
wxListBox *This = (wxListBox *) getPtr(bp,memenv); bp += 4;
int * n = (int *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
This->Deselect((int) *n);
- break;
+ break;
}
-case wxListBox_GetSelections: { // wxListBox::GetSelections
+case wxListBox_GetSelections: { // wxListBox::GetSelections
wxArrayInt aSelections;
wxListBox *This = (wxListBox *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
@@ -15064,9 +15064,9 @@ case wxListBox_GetSelections: { // wxListBox::GetSelections
rt.addInt(Result);
rt.add(aSelections);
rt.addTupleCount(2);
- break;
+ break;
}
-case wxListBox_InsertItems: { // wxListBox::InsertItems
+case wxListBox_InsertItems: { // wxListBox::InsertItems
wxListBox *This = (wxListBox *) getPtr(bp,memenv); bp += 4;
int * itemsLen = (int *) bp; bp += 4;
wxArrayString items;
@@ -15081,17 +15081,17 @@ case wxListBox_InsertItems: { // wxListBox::InsertItems
unsigned int * pos = (unsigned int *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
This->InsertItems(items,(int) *pos);
- break;
+ break;
}
-case wxListBox_IsSelected: { // wxListBox::IsSelected
+case wxListBox_IsSelected: { // wxListBox::IsSelected
wxListBox *This = (wxListBox *) getPtr(bp,memenv); bp += 4;
int * n = (int *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
bool Result = This->IsSelected((int) *n);
rt.addBool(Result);
- break;
+ break;
}
-case wxListBox_Set: { // wxListBox::Set
+case wxListBox_Set: { // wxListBox::Set
wxListBox *This = (wxListBox *) getPtr(bp,memenv); bp += 4;
int * itemsLen = (int *) bp; bp += 4;
wxArrayString items;
@@ -15105,9 +15105,9 @@ case wxListBox_Set: { // wxListBox::Set
bp += (8-((0+ itemsASz) & 7 )) & 7;
if(!This) throw wxe_badarg(0);
This->Set(items,NULL);
- break;
+ break;
}
-case wxListBox_HitTest: { // wxListBox::HitTest
+case wxListBox_HitTest: { // wxListBox::HitTest
wxListBox *This = (wxListBox *) getPtr(bp,memenv); bp += 4;
int * pointX = (int *) bp; bp += 4;
int * pointY = (int *) bp; bp += 4;
@@ -15115,31 +15115,31 @@ case wxListBox_HitTest: { // wxListBox::HitTest
if(!This) throw wxe_badarg(0);
int Result = This->HitTest(point);
rt.addInt(Result);
- break;
+ break;
}
-case wxListBox_SetFirstItem_1_0: { // wxListBox::SetFirstItem
+case wxListBox_SetFirstItem_1_0: { // wxListBox::SetFirstItem
wxListBox *This = (wxListBox *) getPtr(bp,memenv); bp += 4;
int * n = (int *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
This->SetFirstItem((int) *n);
- break;
+ break;
}
-case wxListBox_SetFirstItem_1_1: { // wxListBox::SetFirstItem
+case wxListBox_SetFirstItem_1_1: { // wxListBox::SetFirstItem
wxListBox *This = (wxListBox *) getPtr(bp,memenv); bp += 4;
int * sLen = (int *) bp; bp += 4;
wxString s = wxString(bp, wxConvUTF8);
bp += *sLen+((8-((0+ *sLen) & 7)) & 7);
if(!This) throw wxe_badarg(0);
This->SetFirstItem(s);
- break;
+ break;
}
-case wxListCtrl_new_0: { // wxListCtrl::wxListCtrl
+case wxListCtrl_new_0: { // wxListCtrl::wxListCtrl
wxListCtrl * Result = new EwxListCtrl();
newPtr((void *) Result, 0, memenv);
rt.addRef(getRef((void *)Result,memenv), "wxListCtrl");
- break;
+ break;
}
-case wxListCtrl_new_2: { // wxListCtrl::wxListCtrl
+case wxListCtrl_new_2: { // wxListCtrl::wxListCtrl
wxWindowID winid=wxID_ANY;
wxPoint pos= wxDefaultPosition;
wxSize size= wxDefaultSize;
@@ -15147,7 +15147,7 @@ case wxListCtrl_new_2: { // wxListCtrl::wxListCtrl
const wxValidator * validator= &wxDefaultValidator;
wxWindow *parent = (wxWindow *) getPtr(bp,memenv); bp += 4;
bp += 4; /* Align */
- while( * (int*) bp) { switch (* (int*) bp) {
+ while( * (int*) bp) { switch (* (int*) bp) {
case 1: {bp += 4;
winid = (wxWindowID)*(int *) bp; bp += 4;
} break;
@@ -15169,41 +15169,41 @@ case wxListCtrl_new_2: { // wxListCtrl::wxListCtrl
case 5: {bp += 4;
validator = (wxValidator *) getPtr(bp,memenv); bp += 4;
} break;
- }};
+ }};
wxListCtrl * Result = new EwxListCtrl(parent,winid,pos,size,style,*validator);
newPtr((void *) Result, 0, memenv);
rt.addRef(getRef((void *)Result,memenv), "wxListCtrl");
- break;
+ break;
}
-case wxListCtrl_Arrange: { // wxListCtrl::Arrange
+case wxListCtrl_Arrange: { // wxListCtrl::Arrange
int flag=wxLIST_ALIGN_DEFAULT;
wxListCtrl *This = (wxListCtrl *) getPtr(bp,memenv); bp += 4;
bp += 4; /* Align */
- while( * (int*) bp) { switch (* (int*) bp) {
+ while( * (int*) bp) { switch (* (int*) bp) {
case 1: {bp += 4;
flag = (int)*(int *) bp; bp += 4;
} break;
- }};
+ }};
if(!This) throw wxe_badarg(0);
bool Result = This->Arrange(flag);
rt.addBool(Result);
- break;
+ break;
}
-case wxListCtrl_AssignImageList: { // wxListCtrl::AssignImageList
+case wxListCtrl_AssignImageList: { // wxListCtrl::AssignImageList
wxListCtrl *This = (wxListCtrl *) getPtr(bp,memenv); bp += 4;
wxImageList *imageList = (wxImageList *) getPtr(bp,memenv); bp += 4;
int * which = (int *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
This->AssignImageList(imageList,(int) *which);
- break;
+ break;
}
-case wxListCtrl_ClearAll: { // wxListCtrl::ClearAll
+case wxListCtrl_ClearAll: { // wxListCtrl::ClearAll
wxListCtrl *This = (wxListCtrl *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
This->ClearAll();
- break;
+ break;
}
-case wxListCtrl_Create: { // wxListCtrl::Create
+case wxListCtrl_Create: { // wxListCtrl::Create
wxWindowID winid=wxID_ANY;
wxPoint pos= wxDefaultPosition;
wxSize size= wxDefaultSize;
@@ -15211,7 +15211,7 @@ case wxListCtrl_Create: { // wxListCtrl::Create
const wxValidator * validator= &wxDefaultValidator;
wxListCtrl *This = (wxListCtrl *) getPtr(bp,memenv); bp += 4;
wxWindow *parent = (wxWindow *) getPtr(bp,memenv); bp += 4;
- while( * (int*) bp) { switch (* (int*) bp) {
+ while( * (int*) bp) { switch (* (int*) bp) {
case 1: {bp += 4;
winid = (wxWindowID)*(int *) bp; bp += 4;
} break;
@@ -15233,69 +15233,69 @@ case wxListCtrl_Create: { // wxListCtrl::Create
case 5: {bp += 4;
validator = (wxValidator *) getPtr(bp,memenv); bp += 4;
} break;
- }};
+ }};
if(!This) throw wxe_badarg(0);
bool Result = This->Create(parent,winid,pos,size,style,*validator);
rt.addBool(Result);
- break;
+ break;
}
-case wxListCtrl_DeleteAllItems: { // wxListCtrl::DeleteAllItems
+case wxListCtrl_DeleteAllItems: { // wxListCtrl::DeleteAllItems
wxListCtrl *This = (wxListCtrl *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
bool Result = This->DeleteAllItems();
rt.addBool(Result);
- break;
+ break;
}
-case wxListCtrl_DeleteColumn: { // wxListCtrl::DeleteColumn
+case wxListCtrl_DeleteColumn: { // wxListCtrl::DeleteColumn
wxListCtrl *This = (wxListCtrl *) getPtr(bp,memenv); bp += 4;
int * col = (int *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
bool Result = This->DeleteColumn((int) *col);
rt.addBool(Result);
- break;
+ break;
}
-case wxListCtrl_DeleteItem: { // wxListCtrl::DeleteItem
+case wxListCtrl_DeleteItem: { // wxListCtrl::DeleteItem
wxListCtrl *This = (wxListCtrl *) getPtr(bp,memenv); bp += 4;
int * item = (int *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
bool Result = This->DeleteItem((long) *item);
rt.addBool(Result);
- break;
+ break;
}
-case wxListCtrl_EditLabel: { // wxListCtrl::EditLabel
+case wxListCtrl_EditLabel: { // wxListCtrl::EditLabel
wxListCtrl *This = (wxListCtrl *) getPtr(bp,memenv); bp += 4;
int * item = (int *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
wxTextCtrl * Result = (wxTextCtrl*)This->EditLabel((long) *item);
rt.addRef(getRef((void *)Result,memenv), "wxTextCtrl");
- break;
+ break;
}
-case wxListCtrl_EnsureVisible: { // wxListCtrl::EnsureVisible
+case wxListCtrl_EnsureVisible: { // wxListCtrl::EnsureVisible
wxListCtrl *This = (wxListCtrl *) getPtr(bp,memenv); bp += 4;
int * item = (int *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
bool Result = This->EnsureVisible((long) *item);
rt.addBool(Result);
- break;
+ break;
}
-case wxListCtrl_FindItem_3_0: { // wxListCtrl::FindItem
+case wxListCtrl_FindItem_3_0: { // wxListCtrl::FindItem
bool partial=false;
wxListCtrl *This = (wxListCtrl *) getPtr(bp,memenv); bp += 4;
int * start = (int *) bp; bp += 4;
int * strLen = (int *) bp; bp += 4;
wxString str = wxString(bp, wxConvUTF8);
bp += *strLen+((8-((4+ *strLen) & 7)) & 7);
- while( * (int*) bp) { switch (* (int*) bp) {
+ while( * (int*) bp) { switch (* (int*) bp) {
case 1: {bp += 4;
partial = *(bool *) bp; bp += 4;
} break;
- }};
+ }};
if(!This) throw wxe_badarg(0);
long Result = This->FindItem((long) *start,str,partial);
rt.addInt(Result);
- break;
+ break;
}
-case wxListCtrl_FindItem_3_1: { // wxListCtrl::FindItem
+case wxListCtrl_FindItem_3_1: { // wxListCtrl::FindItem
wxListCtrl *This = (wxListCtrl *) getPtr(bp,memenv); bp += 4;
int * start = (int *) bp; bp += 4;
int * ptX = (int *) bp; bp += 4;
@@ -15305,87 +15305,94 @@ case wxListCtrl_FindItem_3_1: { // wxListCtrl::FindItem
if(!This) throw wxe_badarg(0);
long Result = This->FindItem((long) *start,pt,(int) *direction);
rt.addInt(Result);
- break;
+ break;
}
-case wxListCtrl_GetColumn: { // wxListCtrl::GetColumn
+case wxListCtrl_GetColumn: { // wxListCtrl::GetColumn
wxListCtrl *This = (wxListCtrl *) getPtr(bp,memenv); bp += 4;
int * col = (int *) bp; bp += 4;
wxListItem *item = (wxListItem *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
bool Result = This->GetColumn((int) *col,*item);
rt.addBool(Result);
- break;
+ break;
}
-case wxListCtrl_GetColumnCount: { // wxListCtrl::GetColumnCount
+case wxListCtrl_GetColumnCount: { // wxListCtrl::GetColumnCount
wxListCtrl *This = (wxListCtrl *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
int Result = This->GetColumnCount();
rt.addInt(Result);
- break;
+ break;
}
-case wxListCtrl_GetColumnWidth: { // wxListCtrl::GetColumnWidth
+case wxListCtrl_GetColumnWidth: { // wxListCtrl::GetColumnWidth
wxListCtrl *This = (wxListCtrl *) getPtr(bp,memenv); bp += 4;
int * col = (int *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
int Result = This->GetColumnWidth((int) *col);
rt.addInt(Result);
- break;
+ break;
}
-case wxListCtrl_GetCountPerPage: { // wxListCtrl::GetCountPerPage
+case wxListCtrl_GetCountPerPage: { // wxListCtrl::GetCountPerPage
wxListCtrl *This = (wxListCtrl *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
int Result = This->GetCountPerPage();
rt.addInt(Result);
- break;
+ break;
+}
+case wxListCtrl_GetEditControl: { // wxListCtrl::GetEditControl
+ wxListCtrl *This = (wxListCtrl *) getPtr(bp,memenv); bp += 4;
+ if(!This) throw wxe_badarg(0);
+ wxTextCtrl * Result = (wxTextCtrl*)This->GetEditControl();
+ rt.addRef(getRef((void *)Result,memenv), "wxTextCtrl");
+ break;
}
-case wxListCtrl_GetImageList: { // wxListCtrl::GetImageList
+case wxListCtrl_GetImageList: { // wxListCtrl::GetImageList
wxListCtrl *This = (wxListCtrl *) getPtr(bp,memenv); bp += 4;
int * which = (int *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
wxImageList * Result = (wxImageList*)This->GetImageList((int) *which);
rt.addRef(getRef((void *)Result,memenv), "wxImageList");
- break;
+ break;
}
-case wxListCtrl_GetItem: { // wxListCtrl::GetItem
+case wxListCtrl_GetItem: { // wxListCtrl::GetItem
wxListCtrl *This = (wxListCtrl *) getPtr(bp,memenv); bp += 4;
wxListItem *info = (wxListItem *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
bool Result = This->GetItem(*info);
rt.addBool(Result);
- break;
+ break;
}
-case wxListCtrl_GetItemBackgroundColour: { // wxListCtrl::GetItemBackgroundColour
+case wxListCtrl_GetItemBackgroundColour: { // wxListCtrl::GetItemBackgroundColour
wxListCtrl *This = (wxListCtrl *) getPtr(bp,memenv); bp += 4;
int * item = (int *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
wxColour Result = This->GetItemBackgroundColour((long) *item);
rt.add(Result);
- break;
+ break;
}
-case wxListCtrl_GetItemCount: { // wxListCtrl::GetItemCount
+case wxListCtrl_GetItemCount: { // wxListCtrl::GetItemCount
wxListCtrl *This = (wxListCtrl *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
int Result = This->GetItemCount();
rt.addInt(Result);
- break;
+ break;
}
-case wxListCtrl_GetItemData: { // wxListCtrl::GetItemData
+case wxListCtrl_GetItemData: { // wxListCtrl::GetItemData
wxListCtrl *This = (wxListCtrl *) getPtr(bp,memenv); bp += 4;
int * item = (int *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
wxUIntPtr Result = This->GetItemData((long) *item);
rt.addInt(Result);
- break;
+ break;
}
-case wxListCtrl_GetItemFont: { // wxListCtrl::GetItemFont
+case wxListCtrl_GetItemFont: { // wxListCtrl::GetItemFont
wxListCtrl *This = (wxListCtrl *) getPtr(bp,memenv); bp += 4;
int * item = (int *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
wxFont * Result = new wxFont(This->GetItemFont((long) *item)); newPtr((void *) Result,3, memenv);;
rt.addRef(getRef((void *)Result,memenv), "wxFont");
- break;
+ break;
}
-case wxListCtrl_GetItemPosition: { // wxListCtrl::GetItemPosition
+case wxListCtrl_GetItemPosition: { // wxListCtrl::GetItemPosition
wxListCtrl *This = (wxListCtrl *) getPtr(bp,memenv); bp += 4;
int * item = (int *) bp; bp += 4;
int * posX = (int *) bp; bp += 4;
@@ -15394,9 +15401,9 @@ case wxListCtrl_GetItemPosition: { // wxListCtrl::GetItemPosition
if(!This) throw wxe_badarg(0);
bool Result = This->GetItemPosition((long) *item,pos);
rt.addBool(Result);
- break;
+ break;
}
-case wxListCtrl_GetItemRect: { // wxListCtrl::GetItemRect
+case wxListCtrl_GetItemRect: { // wxListCtrl::GetItemRect
int code=wxLIST_RECT_BOUNDS;
wxListCtrl *This = (wxListCtrl *) getPtr(bp,memenv); bp += 4;
int * item = (int *) bp; bp += 4;
@@ -15405,95 +15412,95 @@ case wxListCtrl_GetItemRect: { // wxListCtrl::GetItemRect
int * rectW = (int *) bp; bp += 4;
int * rectH = (int *) bp; bp += 4;
wxRect rect = wxRect(*rectX,*rectY,*rectW,*rectH);
- while( * (int*) bp) { switch (* (int*) bp) {
+ while( * (int*) bp) { switch (* (int*) bp) {
case 1: {bp += 4;
code = (int)*(int *) bp; bp += 4;
} break;
- }};
+ }};
if(!This) throw wxe_badarg(0);
bool Result = This->GetItemRect((long) *item,rect,code);
rt.addBool(Result);
- break;
+ break;
}
-case wxListCtrl_GetItemSpacing: { // wxListCtrl::GetItemSpacing
+case wxListCtrl_GetItemSpacing: { // wxListCtrl::GetItemSpacing
wxListCtrl *This = (wxListCtrl *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
wxSize Result = This->GetItemSpacing();
rt.add(Result);
- break;
+ break;
}
-case wxListCtrl_GetItemState: { // wxListCtrl::GetItemState
+case wxListCtrl_GetItemState: { // wxListCtrl::GetItemState
wxListCtrl *This = (wxListCtrl *) getPtr(bp,memenv); bp += 4;
int * item = (int *) bp; bp += 4;
int * stateMask = (int *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
int Result = This->GetItemState((long) *item,(long) *stateMask);
rt.addInt(Result);
- break;
+ break;
}
-case wxListCtrl_GetItemText: { // wxListCtrl::GetItemText
+case wxListCtrl_GetItemText: { // wxListCtrl::GetItemText
wxListCtrl *This = (wxListCtrl *) getPtr(bp,memenv); bp += 4;
int * item = (int *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
wxString Result = This->GetItemText((long) *item);
rt.add(Result);
- break;
+ break;
}
-case wxListCtrl_GetItemTextColour: { // wxListCtrl::GetItemTextColour
+case wxListCtrl_GetItemTextColour: { // wxListCtrl::GetItemTextColour
wxListCtrl *This = (wxListCtrl *) getPtr(bp,memenv); bp += 4;
int * item = (int *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
wxColour Result = This->GetItemTextColour((long) *item);
rt.add(Result);
- break;
+ break;
}
-case wxListCtrl_GetNextItem: { // wxListCtrl::GetNextItem
+case wxListCtrl_GetNextItem: { // wxListCtrl::GetNextItem
int geometry=wxLIST_NEXT_ALL;
int state=wxLIST_STATE_DONTCARE;
wxListCtrl *This = (wxListCtrl *) getPtr(bp,memenv); bp += 4;
int * item = (int *) bp; bp += 4;
- while( * (int*) bp) { switch (* (int*) bp) {
+ while( * (int*) bp) { switch (* (int*) bp) {
case 1: {bp += 4;
geometry = (int)*(int *) bp; bp += 4;
} break;
case 2: {bp += 4;
state = (int)*(int *) bp; bp += 4;
} break;
- }};
+ }};
if(!This) throw wxe_badarg(0);
long Result = This->GetNextItem((long) *item,geometry,state);
rt.addInt(Result);
- break;
+ break;
}
-case wxListCtrl_GetSelectedItemCount: { // wxListCtrl::GetSelectedItemCount
+case wxListCtrl_GetSelectedItemCount: { // wxListCtrl::GetSelectedItemCount
wxListCtrl *This = (wxListCtrl *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
int Result = This->GetSelectedItemCount();
rt.addInt(Result);
- break;
+ break;
}
-case wxListCtrl_GetTextColour: { // wxListCtrl::GetTextColour
+case wxListCtrl_GetTextColour: { // wxListCtrl::GetTextColour
wxListCtrl *This = (wxListCtrl *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
wxColour Result = This->GetTextColour();
rt.add(Result);
- break;
+ break;
}
-case wxListCtrl_GetTopItem: { // wxListCtrl::GetTopItem
+case wxListCtrl_GetTopItem: { // wxListCtrl::GetTopItem
wxListCtrl *This = (wxListCtrl *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
long Result = This->GetTopItem();
rt.addInt(Result);
- break;
+ break;
}
-case wxListCtrl_GetViewRect: { // wxListCtrl::GetViewRect
+case wxListCtrl_GetViewRect: { // wxListCtrl::GetViewRect
wxListCtrl *This = (wxListCtrl *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
wxRect Result = This->GetViewRect();
rt.add(Result);
- break;
+ break;
}
-case wxListCtrl_HitTest: { // wxListCtrl::HitTest
+case wxListCtrl_HitTest: { // wxListCtrl::HitTest
int flags;
wxListCtrl *This = (wxListCtrl *) getPtr(bp,memenv); bp += 4;
int * pointX = (int *) bp; bp += 4;
@@ -15504,18 +15511,18 @@ case wxListCtrl_HitTest: { // wxListCtrl::HitTest
rt.addInt(Result);
rt.addInt(flags);
rt.addTupleCount(2);
- break;
+ break;
}
-case wxListCtrl_InsertColumn_2: { // wxListCtrl::InsertColumn
+case wxListCtrl_InsertColumn_2: { // wxListCtrl::InsertColumn
wxListCtrl *This = (wxListCtrl *) getPtr(bp,memenv); bp += 4;
int * col = (int *) bp; bp += 4;
wxListItem *info = (wxListItem *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
long Result = This->InsertColumn((long) *col,*info);
rt.addInt(Result);
- break;
+ break;
}
-case wxListCtrl_InsertColumn_3: { // wxListCtrl::InsertColumn
+case wxListCtrl_InsertColumn_3: { // wxListCtrl::InsertColumn
int format=wxLIST_FORMAT_LEFT;
int width=-1;
wxListCtrl *This = (wxListCtrl *) getPtr(bp,memenv); bp += 4;
@@ -15523,28 +15530,28 @@ case wxListCtrl_InsertColumn_3: { // wxListCtrl::InsertColumn
int * headingLen = (int *) bp; bp += 4;
wxString heading = wxString(bp, wxConvUTF8);
bp += *headingLen+((8-((4+ *headingLen) & 7)) & 7);
- while( * (int*) bp) { switch (* (int*) bp) {
+ while( * (int*) bp) { switch (* (int*) bp) {
case 1: {bp += 4;
format = (int)*(int *) bp; bp += 4;
} break;
case 2: {bp += 4;
width = (int)*(int *) bp; bp += 4;
} break;
- }};
+ }};
if(!This) throw wxe_badarg(0);
long Result = This->InsertColumn((long) *col,heading,format,width);
rt.addInt(Result);
- break;
+ break;
}
-case wxListCtrl_InsertItem_1: { // wxListCtrl::InsertItem
+case wxListCtrl_InsertItem_1: { // wxListCtrl::InsertItem
wxListCtrl *This = (wxListCtrl *) getPtr(bp,memenv); bp += 4;
wxListItem *info = (wxListItem *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
long Result = This->InsertItem(*info);
rt.addInt(Result);
- break;
+ break;
}
-case wxListCtrl_InsertItem_2_1: { // wxListCtrl::InsertItem
+case wxListCtrl_InsertItem_2_1: { // wxListCtrl::InsertItem
wxListCtrl *This = (wxListCtrl *) getPtr(bp,memenv); bp += 4;
int * index = (int *) bp; bp += 4;
int * labelLen = (int *) bp; bp += 4;
@@ -15553,18 +15560,18 @@ case wxListCtrl_InsertItem_2_1: { // wxListCtrl::InsertItem
if(!This) throw wxe_badarg(0);
long Result = This->InsertItem((long) *index,label);
rt.addInt(Result);
- break;
+ break;
}
-case wxListCtrl_InsertItem_2_0: { // wxListCtrl::InsertItem
+case wxListCtrl_InsertItem_2_0: { // wxListCtrl::InsertItem
wxListCtrl *This = (wxListCtrl *) getPtr(bp,memenv); bp += 4;
int * index = (int *) bp; bp += 4;
int * imageIndex = (int *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
long Result = This->InsertItem((long) *index,(int) *imageIndex);
rt.addInt(Result);
- break;
+ break;
}
-case wxListCtrl_InsertItem_3: { // wxListCtrl::InsertItem
+case wxListCtrl_InsertItem_3: { // wxListCtrl::InsertItem
wxListCtrl *This = (wxListCtrl *) getPtr(bp,memenv); bp += 4;
int * index = (int *) bp; bp += 4;
int * labelLen = (int *) bp; bp += 4;
@@ -15574,33 +15581,33 @@ case wxListCtrl_InsertItem_3: { // wxListCtrl::InsertItem
if(!This) throw wxe_badarg(0);
long Result = This->InsertItem((long) *index,label,(int) *imageIndex);
rt.addInt(Result);
- break;
+ break;
}
-case wxListCtrl_RefreshItem: { // wxListCtrl::RefreshItem
+case wxListCtrl_RefreshItem: { // wxListCtrl::RefreshItem
wxListCtrl *This = (wxListCtrl *) getPtr(bp,memenv); bp += 4;
int * item = (int *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
This->RefreshItem((long) *item);
- break;
+ break;
}
-case wxListCtrl_RefreshItems: { // wxListCtrl::RefreshItems
+case wxListCtrl_RefreshItems: { // wxListCtrl::RefreshItems
wxListCtrl *This = (wxListCtrl *) getPtr(bp,memenv); bp += 4;
int * itemFrom = (int *) bp; bp += 4;
int * itemTo = (int *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
This->RefreshItems((long) *itemFrom,(long) *itemTo);
- break;
+ break;
}
-case wxListCtrl_ScrollList: { // wxListCtrl::ScrollList
+case wxListCtrl_ScrollList: { // wxListCtrl::ScrollList
wxListCtrl *This = (wxListCtrl *) getPtr(bp,memenv); bp += 4;
int * dx = (int *) bp; bp += 4;
int * dy = (int *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
bool Result = This->ScrollList((int) *dx,(int) *dy);
rt.addBool(Result);
- break;
+ break;
}
-case wxListCtrl_SetBackgroundColour: { // wxListCtrl::SetBackgroundColour
+case wxListCtrl_SetBackgroundColour: { // wxListCtrl::SetBackgroundColour
wxListCtrl *This = (wxListCtrl *) getPtr(bp,memenv); bp += 4;
int * colourR = (int *) bp; bp += 4;
int * colourG = (int *) bp; bp += 4;
@@ -15610,43 +15617,43 @@ case wxListCtrl_SetBackgroundColour: { // wxListCtrl::SetBackgroundColour
if(!This) throw wxe_badarg(0);
bool Result = This->SetBackgroundColour(colour);
rt.addBool(Result);
- break;
+ break;
}
-case wxListCtrl_SetColumn: { // wxListCtrl::SetColumn
+case wxListCtrl_SetColumn: { // wxListCtrl::SetColumn
wxListCtrl *This = (wxListCtrl *) getPtr(bp,memenv); bp += 4;
int * col = (int *) bp; bp += 4;
wxListItem *item = (wxListItem *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
bool Result = This->SetColumn((int) *col,*item);
rt.addBool(Result);
- break;
+ break;
}
-case wxListCtrl_SetColumnWidth: { // wxListCtrl::SetColumnWidth
+case wxListCtrl_SetColumnWidth: { // wxListCtrl::SetColumnWidth
wxListCtrl *This = (wxListCtrl *) getPtr(bp,memenv); bp += 4;
int * col = (int *) bp; bp += 4;
int * width = (int *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
bool Result = This->SetColumnWidth((int) *col,(int) *width);
rt.addBool(Result);
- break;
+ break;
}
-case wxListCtrl_SetImageList: { // wxListCtrl::SetImageList
+case wxListCtrl_SetImageList: { // wxListCtrl::SetImageList
wxListCtrl *This = (wxListCtrl *) getPtr(bp,memenv); bp += 4;
wxImageList *imageList = (wxImageList *) getPtr(bp,memenv); bp += 4;
int * which = (int *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
This->SetImageList(imageList,(int) *which);
- break;
+ break;
}
-case wxListCtrl_SetItem_1: { // wxListCtrl::SetItem
+case wxListCtrl_SetItem_1: { // wxListCtrl::SetItem
wxListCtrl *This = (wxListCtrl *) getPtr(bp,memenv); bp += 4;
wxListItem *info = (wxListItem *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
bool Result = This->SetItem(*info);
rt.addBool(Result);
- break;
+ break;
}
-case wxListCtrl_SetItem_4: { // wxListCtrl::SetItem
+case wxListCtrl_SetItem_4: { // wxListCtrl::SetItem
int imageId=-1;
wxListCtrl *This = (wxListCtrl *) getPtr(bp,memenv); bp += 4;
int * index = (int *) bp; bp += 4;
@@ -15654,17 +15661,17 @@ case wxListCtrl_SetItem_4: { // wxListCtrl::SetItem
int * labelLen = (int *) bp; bp += 4;
wxString label = wxString(bp, wxConvUTF8);
bp += *labelLen+((8-((0+ *labelLen) & 7)) & 7);
- while( * (int*) bp) { switch (* (int*) bp) {
+ while( * (int*) bp) { switch (* (int*) bp) {
case 1: {bp += 4;
imageId = (int)*(int *) bp; bp += 4;
} break;
- }};
+ }};
if(!This) throw wxe_badarg(0);
long Result = This->SetItem((long) *index,(int) *col,label,imageId);
rt.addInt(Result);
- break;
+ break;
}
-case wxListCtrl_SetItemBackgroundColour: { // wxListCtrl::SetItemBackgroundColour
+case wxListCtrl_SetItemBackgroundColour: { // wxListCtrl::SetItemBackgroundColour
wxListCtrl *This = (wxListCtrl *) getPtr(bp,memenv); bp += 4;
int * item = (int *) bp; bp += 4;
int * colR = (int *) bp; bp += 4;
@@ -15674,49 +15681,49 @@ case wxListCtrl_SetItemBackgroundColour: { // wxListCtrl::SetItemBackgroundColou
wxColour col = wxColour(*colR,*colG,*colB,*colA);
if(!This) throw wxe_badarg(0);
This->SetItemBackgroundColour((long) *item,col);
- break;
+ break;
}
-case wxListCtrl_SetItemCount: { // wxListCtrl::SetItemCount
+case wxListCtrl_SetItemCount: { // wxListCtrl::SetItemCount
wxListCtrl *This = (wxListCtrl *) getPtr(bp,memenv); bp += 4;
int * count = (int *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
This->SetItemCount((long) *count);
- break;
+ break;
}
-case wxListCtrl_SetItemData: { // wxListCtrl::SetItemData
+case wxListCtrl_SetItemData: { // wxListCtrl::SetItemData
wxListCtrl *This = (wxListCtrl *) getPtr(bp,memenv); bp += 4;
int * item = (int *) bp; bp += 4;
int * data = (int *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
bool Result = This->SetItemData((long) *item,(long) *data);
rt.addBool(Result);
- break;
+ break;
}
-case wxListCtrl_SetItemFont: { // wxListCtrl::SetItemFont
+case wxListCtrl_SetItemFont: { // wxListCtrl::SetItemFont
wxListCtrl *This = (wxListCtrl *) getPtr(bp,memenv); bp += 4;
int * item = (int *) bp; bp += 4;
wxFont *f = (wxFont *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
This->SetItemFont((long) *item,*f);
- break;
+ break;
}
-case wxListCtrl_SetItemImage: { // wxListCtrl::SetItemImage
+case wxListCtrl_SetItemImage: { // wxListCtrl::SetItemImage
int selImage=-1;
wxListCtrl *This = (wxListCtrl *) getPtr(bp,memenv); bp += 4;
int * item = (int *) bp; bp += 4;
int * image = (int *) bp; bp += 4;
bp += 4; /* Align */
- while( * (int*) bp) { switch (* (int*) bp) {
+ while( * (int*) bp) { switch (* (int*) bp) {
case 1: {bp += 4;
selImage = (int)*(int *) bp; bp += 4;
} break;
- }};
+ }};
if(!This) throw wxe_badarg(0);
bool Result = This->SetItemImage((long) *item,(int) *image,selImage);
rt.addBool(Result);
- break;
+ break;
}
-case wxListCtrl_SetItemColumnImage: { // wxListCtrl::SetItemColumnImage
+case wxListCtrl_SetItemColumnImage: { // wxListCtrl::SetItemColumnImage
wxListCtrl *This = (wxListCtrl *) getPtr(bp,memenv); bp += 4;
int * item = (int *) bp; bp += 4;
int * column = (int *) bp; bp += 4;
@@ -15724,9 +15731,9 @@ case wxListCtrl_SetItemColumnImage: { // wxListCtrl::SetItemColumnImage
if(!This) throw wxe_badarg(0);
bool Result = This->SetItemColumnImage((long) *item,(long) *column,(int) *image);
rt.addBool(Result);
- break;
+ break;
}
-case wxListCtrl_SetItemPosition: { // wxListCtrl::SetItemPosition
+case wxListCtrl_SetItemPosition: { // wxListCtrl::SetItemPosition
wxListCtrl *This = (wxListCtrl *) getPtr(bp,memenv); bp += 4;
int * item = (int *) bp; bp += 4;
int * posX = (int *) bp; bp += 4;
@@ -15735,9 +15742,9 @@ case wxListCtrl_SetItemPosition: { // wxListCtrl::SetItemPosition
if(!This) throw wxe_badarg(0);
bool Result = This->SetItemPosition((long) *item,pos);
rt.addBool(Result);
- break;
+ break;
}
-case wxListCtrl_SetItemState: { // wxListCtrl::SetItemState
+case wxListCtrl_SetItemState: { // wxListCtrl::SetItemState
wxListCtrl *This = (wxListCtrl *) getPtr(bp,memenv); bp += 4;
int * item = (int *) bp; bp += 4;
int * state = (int *) bp; bp += 4;
@@ -15745,9 +15752,9 @@ case wxListCtrl_SetItemState: { // wxListCtrl::SetItemState
if(!This) throw wxe_badarg(0);
bool Result = This->SetItemState((long) *item,(long) *state,(long) *stateMask);
rt.addBool(Result);
- break;
+ break;
}
-case wxListCtrl_SetItemText: { // wxListCtrl::SetItemText
+case wxListCtrl_SetItemText: { // wxListCtrl::SetItemText
wxListCtrl *This = (wxListCtrl *) getPtr(bp,memenv); bp += 4;
int * item = (int *) bp; bp += 4;
int * strLen = (int *) bp; bp += 4;
@@ -15755,9 +15762,9 @@ case wxListCtrl_SetItemText: { // wxListCtrl::SetItemText
bp += *strLen+((8-((4+ *strLen) & 7)) & 7);
if(!This) throw wxe_badarg(0);
This->SetItemText((long) *item,str);
- break;
+ break;
}
-case wxListCtrl_SetItemTextColour: { // wxListCtrl::SetItemTextColour
+case wxListCtrl_SetItemTextColour: { // wxListCtrl::SetItemTextColour
wxListCtrl *This = (wxListCtrl *) getPtr(bp,memenv); bp += 4;
int * item = (int *) bp; bp += 4;
int * colR = (int *) bp; bp += 4;
@@ -15767,22 +15774,22 @@ case wxListCtrl_SetItemTextColour: { // wxListCtrl::SetItemTextColour
wxColour col = wxColour(*colR,*colG,*colB,*colA);
if(!This) throw wxe_badarg(0);
This->SetItemTextColour((long) *item,col);
- break;
+ break;
}
-case wxListCtrl_SetSingleStyle: { // wxListCtrl::SetSingleStyle
+case wxListCtrl_SetSingleStyle: { // wxListCtrl::SetSingleStyle
bool add=true;
wxListCtrl *This = (wxListCtrl *) getPtr(bp,memenv); bp += 4;
int * style = (int *) bp; bp += 4;
- while( * (int*) bp) { switch (* (int*) bp) {
+ while( * (int*) bp) { switch (* (int*) bp) {
case 1: {bp += 4;
add = *(bool *) bp; bp += 4;
} break;
- }};
+ }};
if(!This) throw wxe_badarg(0);
This->SetSingleStyle((long) *style,add);
- break;
+ break;
}
-case wxListCtrl_SetTextColour: { // wxListCtrl::SetTextColour
+case wxListCtrl_SetTextColour: { // wxListCtrl::SetTextColour
wxListCtrl *This = (wxListCtrl *) getPtr(bp,memenv); bp += 4;
int * colR = (int *) bp; bp += 4;
int * colG = (int *) bp; bp += 4;
@@ -15791,14 +15798,14 @@ case wxListCtrl_SetTextColour: { // wxListCtrl::SetTextColour
wxColour col = wxColour(*colR,*colG,*colB,*colA);
if(!This) throw wxe_badarg(0);
This->SetTextColour(col);
- break;
+ break;
}
-case wxListCtrl_SetWindowStyleFlag: { // wxListCtrl::SetWindowStyleFlag
+case wxListCtrl_SetWindowStyleFlag: { // wxListCtrl::SetWindowStyleFlag
wxListCtrl *This = (wxListCtrl *) getPtr(bp,memenv); bp += 4;
int * style = (int *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
This->SetWindowStyleFlag((long) *style);
- break;
+ break;
}
case wxListCtrl_SortItems: { // wxListCtrl::SortItems taylormade
@@ -15823,175 +15830,175 @@ case wxListCtrl_SortItems: { // wxListCtrl::SortItems taylormade
rt.addBool(Result);
break;
}
-case wxListView_ClearColumnImage: { // wxListView::ClearColumnImage
+case wxListView_ClearColumnImage: { // wxListView::ClearColumnImage
wxListView *This = (wxListView *) getPtr(bp,memenv); bp += 4;
int * col = (int *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
This->ClearColumnImage((int) *col);
- break;
+ break;
}
-case wxListView_Focus: { // wxListView::Focus
+case wxListView_Focus: { // wxListView::Focus
wxListView *This = (wxListView *) getPtr(bp,memenv); bp += 4;
int * index = (int *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
This->Focus((long) *index);
- break;
+ break;
}
-case wxListView_GetFirstSelected: { // wxListView::GetFirstSelected
+case wxListView_GetFirstSelected: { // wxListView::GetFirstSelected
wxListView *This = (wxListView *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
long Result = This->GetFirstSelected();
rt.addInt(Result);
- break;
+ break;
}
-case wxListView_GetFocusedItem: { // wxListView::GetFocusedItem
+case wxListView_GetFocusedItem: { // wxListView::GetFocusedItem
wxListView *This = (wxListView *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
long Result = This->GetFocusedItem();
rt.addInt(Result);
- break;
+ break;
}
-case wxListView_GetNextSelected: { // wxListView::GetNextSelected
+case wxListView_GetNextSelected: { // wxListView::GetNextSelected
wxListView *This = (wxListView *) getPtr(bp,memenv); bp += 4;
int * item = (int *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
long Result = This->GetNextSelected((long) *item);
rt.addInt(Result);
- break;
+ break;
}
-case wxListView_IsSelected: { // wxListView::IsSelected
+case wxListView_IsSelected: { // wxListView::IsSelected
wxListView *This = (wxListView *) getPtr(bp,memenv); bp += 4;
int * index = (int *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
bool Result = This->IsSelected((long) *index);
rt.addBool(Result);
- break;
+ break;
}
-case wxListView_Select: { // wxListView::Select
+case wxListView_Select: { // wxListView::Select
bool on=true;
wxListView *This = (wxListView *) getPtr(bp,memenv); bp += 4;
int * n = (int *) bp; bp += 4;
- while( * (int*) bp) { switch (* (int*) bp) {
+ while( * (int*) bp) { switch (* (int*) bp) {
case 1: {bp += 4;
on = *(bool *) bp; bp += 4;
} break;
- }};
+ }};
if(!This) throw wxe_badarg(0);
This->Select((long) *n,on);
- break;
+ break;
}
-case wxListView_SetColumnImage: { // wxListView::SetColumnImage
+case wxListView_SetColumnImage: { // wxListView::SetColumnImage
wxListView *This = (wxListView *) getPtr(bp,memenv); bp += 4;
int * col = (int *) bp; bp += 4;
int * image = (int *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
This->SetColumnImage((int) *col,(int) *image);
- break;
+ break;
}
-case wxListItem_new_0: { // wxListItem::wxListItem
+case wxListItem_new_0: { // wxListItem::wxListItem
wxListItem * Result = new EwxListItem();
newPtr((void *) Result, 1, memenv);
rt.addRef(getRef((void *)Result,memenv), "wxListItem");
- break;
+ break;
}
-case wxListItem_new_1: { // wxListItem::wxListItem
+case wxListItem_new_1: { // wxListItem::wxListItem
wxListItem *item = (wxListItem *) getPtr(bp,memenv); bp += 4;
wxListItem * Result = new EwxListItem(*item);
newPtr((void *) Result, 1, memenv);
rt.addRef(getRef((void *)Result,memenv), "wxListItem");
- break;
+ break;
}
-case wxListItem_Clear: { // wxListItem::Clear
+case wxListItem_Clear: { // wxListItem::Clear
wxListItem *This = (wxListItem *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
This->Clear();
- break;
+ break;
}
-case wxListItem_GetAlign: { // wxListItem::GetAlign
+case wxListItem_GetAlign: { // wxListItem::GetAlign
wxListItem *This = (wxListItem *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
int Result = This->GetAlign();
rt.addInt(Result);
- break;
+ break;
}
-case wxListItem_GetBackgroundColour: { // wxListItem::GetBackgroundColour
+case wxListItem_GetBackgroundColour: { // wxListItem::GetBackgroundColour
wxListItem *This = (wxListItem *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
wxColour Result = This->GetBackgroundColour();
rt.add(Result);
- break;
+ break;
}
-case wxListItem_GetColumn: { // wxListItem::GetColumn
+case wxListItem_GetColumn: { // wxListItem::GetColumn
wxListItem *This = (wxListItem *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
int Result = This->GetColumn();
rt.addInt(Result);
- break;
+ break;
}
-case wxListItem_GetFont: { // wxListItem::GetFont
+case wxListItem_GetFont: { // wxListItem::GetFont
wxListItem *This = (wxListItem *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
wxFont * Result = new wxFont(This->GetFont()); newPtr((void *) Result,3, memenv);;
rt.addRef(getRef((void *)Result,memenv), "wxFont");
- break;
+ break;
}
-case wxListItem_GetId: { // wxListItem::GetId
+case wxListItem_GetId: { // wxListItem::GetId
wxListItem *This = (wxListItem *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
long Result = This->GetId();
rt.addInt(Result);
- break;
+ break;
}
-case wxListItem_GetImage: { // wxListItem::GetImage
+case wxListItem_GetImage: { // wxListItem::GetImage
wxListItem *This = (wxListItem *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
int Result = This->GetImage();
rt.addInt(Result);
- break;
+ break;
}
-case wxListItem_GetMask: { // wxListItem::GetMask
+case wxListItem_GetMask: { // wxListItem::GetMask
wxListItem *This = (wxListItem *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
long Result = This->GetMask();
rt.addInt(Result);
- break;
+ break;
}
-case wxListItem_GetState: { // wxListItem::GetState
+case wxListItem_GetState: { // wxListItem::GetState
wxListItem *This = (wxListItem *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
long Result = This->GetState();
rt.addInt(Result);
- break;
+ break;
}
-case wxListItem_GetText: { // wxListItem::GetText
+case wxListItem_GetText: { // wxListItem::GetText
wxListItem *This = (wxListItem *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
const wxString * Result = &This->GetText();
rt.add(Result);
- break;
+ break;
}
-case wxListItem_GetTextColour: { // wxListItem::GetTextColour
+case wxListItem_GetTextColour: { // wxListItem::GetTextColour
wxListItem *This = (wxListItem *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
wxColour Result = This->GetTextColour();
rt.add(Result);
- break;
+ break;
}
-case wxListItem_GetWidth: { // wxListItem::GetWidth
+case wxListItem_GetWidth: { // wxListItem::GetWidth
wxListItem *This = (wxListItem *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
int Result = This->GetWidth();
rt.addInt(Result);
- break;
+ break;
}
-case wxListItem_SetAlign: { // wxListItem::SetAlign
+case wxListItem_SetAlign: { // wxListItem::SetAlign
wxListItem *This = (wxListItem *) getPtr(bp,memenv); bp += 4;
wxListColumnFormat align = *(wxListColumnFormat *) bp; bp += 4;;
if(!This) throw wxe_badarg(0);
This->SetAlign((wxListColumnFormat) align);
- break;
+ break;
}
-case wxListItem_SetBackgroundColour: { // wxListItem::SetBackgroundColour
+case wxListItem_SetBackgroundColour: { // wxListItem::SetBackgroundColour
wxListItem *This = (wxListItem *) getPtr(bp,memenv); bp += 4;
int * colBackR = (int *) bp; bp += 4;
int * colBackG = (int *) bp; bp += 4;
@@ -16000,67 +16007,67 @@ case wxListItem_SetBackgroundColour: { // wxListItem::SetBackgroundColour
wxColour colBack = wxColour(*colBackR,*colBackG,*colBackB,*colBackA);
if(!This) throw wxe_badarg(0);
This->SetBackgroundColour(colBack);
- break;
+ break;
}
-case wxListItem_SetColumn: { // wxListItem::SetColumn
+case wxListItem_SetColumn: { // wxListItem::SetColumn
wxListItem *This = (wxListItem *) getPtr(bp,memenv); bp += 4;
int * col = (int *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
This->SetColumn((int) *col);
- break;
+ break;
}
-case wxListItem_SetFont: { // wxListItem::SetFont
+case wxListItem_SetFont: { // wxListItem::SetFont
wxListItem *This = (wxListItem *) getPtr(bp,memenv); bp += 4;
wxFont *font = (wxFont *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
This->SetFont(*font);
- break;
+ break;
}
-case wxListItem_SetId: { // wxListItem::SetId
+case wxListItem_SetId: { // wxListItem::SetId
wxListItem *This = (wxListItem *) getPtr(bp,memenv); bp += 4;
int * id = (int *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
This->SetId((long) *id);
- break;
+ break;
}
-case wxListItem_SetImage: { // wxListItem::SetImage
+case wxListItem_SetImage: { // wxListItem::SetImage
wxListItem *This = (wxListItem *) getPtr(bp,memenv); bp += 4;
int * image = (int *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
This->SetImage((int) *image);
- break;
+ break;
}
-case wxListItem_SetMask: { // wxListItem::SetMask
+case wxListItem_SetMask: { // wxListItem::SetMask
wxListItem *This = (wxListItem *) getPtr(bp,memenv); bp += 4;
int * mask = (int *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
This->SetMask((long) *mask);
- break;
+ break;
}
-case wxListItem_SetState: { // wxListItem::SetState
+case wxListItem_SetState: { // wxListItem::SetState
wxListItem *This = (wxListItem *) getPtr(bp,memenv); bp += 4;
int * state = (int *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
This->SetState((long) *state);
- break;
+ break;
}
-case wxListItem_SetStateMask: { // wxListItem::SetStateMask
+case wxListItem_SetStateMask: { // wxListItem::SetStateMask
wxListItem *This = (wxListItem *) getPtr(bp,memenv); bp += 4;
int * stateMask = (int *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
This->SetStateMask((long) *stateMask);
- break;
+ break;
}
-case wxListItem_SetText: { // wxListItem::SetText
+case wxListItem_SetText: { // wxListItem::SetText
wxListItem *This = (wxListItem *) getPtr(bp,memenv); bp += 4;
int * textLen = (int *) bp; bp += 4;
wxString text = wxString(bp, wxConvUTF8);
bp += *textLen+((8-((0+ *textLen) & 7)) & 7);
if(!This) throw wxe_badarg(0);
This->SetText(text);
- break;
+ break;
}
-case wxListItem_SetTextColour: { // wxListItem::SetTextColour
+case wxListItem_SetTextColour: { // wxListItem::SetTextColour
wxListItem *This = (wxListItem *) getPtr(bp,memenv); bp += 4;
int * colTextR = (int *) bp; bp += 4;
int * colTextG = (int *) bp; bp += 4;
@@ -16069,57 +16076,57 @@ case wxListItem_SetTextColour: { // wxListItem::SetTextColour
wxColour colText = wxColour(*colTextR,*colTextG,*colTextB,*colTextA);
if(!This) throw wxe_badarg(0);
This->SetTextColour(colText);
- break;
+ break;
}
-case wxListItem_SetWidth: { // wxListItem::SetWidth
+case wxListItem_SetWidth: { // wxListItem::SetWidth
wxListItem *This = (wxListItem *) getPtr(bp,memenv); bp += 4;
int * width = (int *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
This->SetWidth((int) *width);
- break;
+ break;
}
-case wxImageList_new_0: { // wxImageList::wxImageList
+case wxImageList_new_0: { // wxImageList::wxImageList
wxImageList * Result = new EwxImageList();
newPtr((void *) Result, 1, memenv);
rt.addRef(getRef((void *)Result,memenv), "wxImageList");
- break;
+ break;
}
-case wxImageList_new_3: { // wxImageList::wxImageList
+case wxImageList_new_3: { // wxImageList::wxImageList
bool mask=true;
int initialCount=1;
int * width = (int *) bp; bp += 4;
int * height = (int *) bp; bp += 4;
- while( * (int*) bp) { switch (* (int*) bp) {
+ while( * (int*) bp) { switch (* (int*) bp) {
case 1: {bp += 4;
mask = *(bool *) bp; bp += 4;
} break;
case 2: {bp += 4;
initialCount = (int)*(int *) bp; bp += 4;
} break;
- }};
+ }};
wxImageList * Result = new EwxImageList((int) *width,(int) *height,mask,initialCount);
newPtr((void *) Result, 1, memenv);
rt.addRef(getRef((void *)Result,memenv), "wxImageList");
- break;
+ break;
}
-case wxImageList_Add_1: { // wxImageList::Add
+case wxImageList_Add_1: { // wxImageList::Add
wxImageList *This = (wxImageList *) getPtr(bp,memenv); bp += 4;
wxBitmap *bitmap = (wxBitmap *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
int Result = This->Add(*bitmap);
rt.addInt(Result);
- break;
+ break;
}
-case wxImageList_Add_2_0: { // wxImageList::Add
+case wxImageList_Add_2_0: { // wxImageList::Add
wxImageList *This = (wxImageList *) getPtr(bp,memenv); bp += 4;
wxBitmap *bitmap = (wxBitmap *) getPtr(bp,memenv); bp += 4;
wxBitmap *mask = (wxBitmap *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
int Result = This->Add(*bitmap,*mask);
rt.addInt(Result);
- break;
+ break;
}
-case wxImageList_Add_2_1: { // wxImageList::Add
+case wxImageList_Add_2_1: { // wxImageList::Add
wxImageList *This = (wxImageList *) getPtr(bp,memenv); bp += 4;
wxBitmap *bitmap = (wxBitmap *) getPtr(bp,memenv); bp += 4;
int * maskColourR = (int *) bp; bp += 4;
@@ -16130,29 +16137,29 @@ case wxImageList_Add_2_1: { // wxImageList::Add
if(!This) throw wxe_badarg(0);
int Result = This->Add(*bitmap,maskColour);
rt.addInt(Result);
- break;
+ break;
}
-case wxImageList_Create: { // wxImageList::Create
+case wxImageList_Create: { // wxImageList::Create
bool mask=true;
int initialCount=1;
wxImageList *This = (wxImageList *) getPtr(bp,memenv); bp += 4;
int * width = (int *) bp; bp += 4;
int * height = (int *) bp; bp += 4;
bp += 4; /* Align */
- while( * (int*) bp) { switch (* (int*) bp) {
+ while( * (int*) bp) { switch (* (int*) bp) {
case 1: {bp += 4;
mask = *(bool *) bp; bp += 4;
} break;
case 2: {bp += 4;
initialCount = (int)*(int *) bp; bp += 4;
} break;
- }};
+ }};
if(!This) throw wxe_badarg(0);
bool Result = This->Create((int) *width,(int) *height,mask,initialCount);
rt.addBool(Result);
- break;
+ break;
}
-case wxImageList_Draw: { // wxImageList::Draw
+case wxImageList_Draw: { // wxImageList::Draw
int flags=wxIMAGELIST_DRAW_NORMAL;
bool solidBackground=false;
wxImageList *This = (wxImageList *) getPtr(bp,memenv); bp += 4;
@@ -16161,43 +16168,43 @@ case wxImageList_Draw: { // wxImageList::Draw
int * x = (int *) bp; bp += 4;
int * y = (int *) bp; bp += 4;
bp += 4; /* Align */
- while( * (int*) bp) { switch (* (int*) bp) {
+ while( * (int*) bp) { switch (* (int*) bp) {
case 1: {bp += 4;
flags = (int)*(int *) bp; bp += 4;
} break;
case 2: {bp += 4;
solidBackground = *(bool *) bp; bp += 4;
} break;
- }};
+ }};
if(!This) throw wxe_badarg(0);
bool Result = This->Draw((int) *index,*dc,(int) *x,(int) *y,flags,solidBackground);
rt.addBool(Result);
- break;
+ break;
}
-case wxImageList_GetBitmap: { // wxImageList::GetBitmap
+case wxImageList_GetBitmap: { // wxImageList::GetBitmap
wxImageList *This = (wxImageList *) getPtr(bp,memenv); bp += 4;
int * index = (int *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
wxBitmap * Result = new wxBitmap(This->GetBitmap((int) *index)); newPtr((void *) Result,3, memenv);;
rt.addRef(getRef((void *)Result,memenv), "wxBitmap");
- break;
+ break;
}
-case wxImageList_GetIcon: { // wxImageList::GetIcon
+case wxImageList_GetIcon: { // wxImageList::GetIcon
wxImageList *This = (wxImageList *) getPtr(bp,memenv); bp += 4;
int * index = (int *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
wxIcon * Result = new wxIcon(This->GetIcon((int) *index)); newPtr((void *) Result,3, memenv);;
rt.addRef(getRef((void *)Result,memenv), "wxIcon");
- break;
+ break;
}
-case wxImageList_GetImageCount: { // wxImageList::GetImageCount
+case wxImageList_GetImageCount: { // wxImageList::GetImageCount
wxImageList *This = (wxImageList *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
int Result = This->GetImageCount();
rt.addInt(Result);
- break;
+ break;
}
-case wxImageList_GetSize: { // wxImageList::GetSize
+case wxImageList_GetSize: { // wxImageList::GetSize
int width;
int height;
wxImageList *This = (wxImageList *) getPtr(bp,memenv); bp += 4;
@@ -16208,33 +16215,33 @@ case wxImageList_GetSize: { // wxImageList::GetSize
rt.addInt(width);
rt.addInt(height);
rt.addTupleCount(3);
- break;
+ break;
}
-case wxImageList_Remove: { // wxImageList::Remove
+case wxImageList_Remove: { // wxImageList::Remove
wxImageList *This = (wxImageList *) getPtr(bp,memenv); bp += 4;
int * index = (int *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
bool Result = This->Remove((int) *index);
rt.addBool(Result);
- break;
+ break;
}
-case wxImageList_RemoveAll: { // wxImageList::RemoveAll
+case wxImageList_RemoveAll: { // wxImageList::RemoveAll
wxImageList *This = (wxImageList *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
bool Result = This->RemoveAll();
rt.addBool(Result);
- break;
+ break;
}
-case wxImageList_Replace_2: { // wxImageList::Replace
+case wxImageList_Replace_2: { // wxImageList::Replace
wxImageList *This = (wxImageList *) getPtr(bp,memenv); bp += 4;
int * index = (int *) bp; bp += 4;
wxBitmap *bitmap = (wxBitmap *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
bool Result = This->Replace((int) *index,*bitmap);
rt.addBool(Result);
- break;
+ break;
}
-case wxImageList_Replace_3: { // wxImageList::Replace
+case wxImageList_Replace_3: { // wxImageList::Replace
wxImageList *This = (wxImageList *) getPtr(bp,memenv); bp += 4;
int * index = (int *) bp; bp += 4;
wxBitmap *bitmap = (wxBitmap *) getPtr(bp,memenv); bp += 4;
@@ -16242,15 +16249,15 @@ case wxImageList_Replace_3: { // wxImageList::Replace
if(!This) throw wxe_badarg(0);
bool Result = This->Replace((int) *index,*bitmap,*mask);
rt.addBool(Result);
- break;
+ break;
}
-case wxTextAttr_new_0: { // wxTextAttr::wxTextAttr
+case wxTextAttr_new_0: { // wxTextAttr::wxTextAttr
wxTextAttr * Result = new wxTextAttr();
newPtr((void *) Result, 102, memenv);
rt.addRef(getRef((void *)Result,memenv), "wxTextAttr");
- break;
+ break;
}
-case wxTextAttr_new_2: { // wxTextAttr::wxTextAttr
+case wxTextAttr_new_2: { // wxTextAttr::wxTextAttr
wxColour colBack= wxNullColour;
const wxFont * font= &wxNullFont;
wxTextAttrAlignment alignment=wxTEXT_ALIGNMENT_DEFAULT;
@@ -16259,7 +16266,7 @@ case wxTextAttr_new_2: { // wxTextAttr::wxTextAttr
int * colTextB = (int *) bp; bp += 4;
int * colTextA = (int *) bp; bp += 4;
wxColour colText = wxColour(*colTextR,*colTextG,*colTextB,*colTextA);
- while( * (int*) bp) { switch (* (int*) bp) {
+ while( * (int*) bp) { switch (* (int*) bp) {
case 1: {bp += 4;
int * colBackR = (int *) bp; bp += 4;
int * colBackG = (int *) bp; bp += 4;
@@ -16274,111 +16281,111 @@ font = (wxFont *) getPtr(bp,memenv); bp += 4;
case 3: {bp += 4;
alignment = *(wxTextAttrAlignment *) bp; bp += 4;;
} break;
- }};
+ }};
wxTextAttr * Result = new wxTextAttr(colText,colBack,*font,(wxTextAttrAlignment) alignment);
newPtr((void *) Result, 102, memenv);
rt.addRef(getRef((void *)Result,memenv), "wxTextAttr");
- break;
+ break;
}
-case wxTextAttr_GetAlignment: { // wxTextAttr::GetAlignment
+case wxTextAttr_GetAlignment: { // wxTextAttr::GetAlignment
wxTextAttr *This = (wxTextAttr *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
int Result = This->GetAlignment();
rt.addInt(Result);
- break;
+ break;
}
-case wxTextAttr_GetBackgroundColour: { // wxTextAttr::GetBackgroundColour
+case wxTextAttr_GetBackgroundColour: { // wxTextAttr::GetBackgroundColour
wxTextAttr *This = (wxTextAttr *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
const wxColour * Result = &This->GetBackgroundColour();
rt.add((*Result));
- break;
+ break;
}
-case wxTextAttr_GetFont: { // wxTextAttr::GetFont
+case wxTextAttr_GetFont: { // wxTextAttr::GetFont
wxTextAttr *This = (wxTextAttr *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
const wxFont * Result = &This->GetFont();
rt.addRef(getRef((void *)Result,memenv), "wxFont");
- break;
+ break;
}
-case wxTextAttr_GetLeftIndent: { // wxTextAttr::GetLeftIndent
+case wxTextAttr_GetLeftIndent: { // wxTextAttr::GetLeftIndent
wxTextAttr *This = (wxTextAttr *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
long Result = This->GetLeftIndent();
rt.addInt(Result);
- break;
+ break;
}
-case wxTextAttr_GetLeftSubIndent: { // wxTextAttr::GetLeftSubIndent
+case wxTextAttr_GetLeftSubIndent: { // wxTextAttr::GetLeftSubIndent
wxTextAttr *This = (wxTextAttr *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
long Result = This->GetLeftSubIndent();
rt.addInt(Result);
- break;
+ break;
}
-case wxTextAttr_GetRightIndent: { // wxTextAttr::GetRightIndent
+case wxTextAttr_GetRightIndent: { // wxTextAttr::GetRightIndent
wxTextAttr *This = (wxTextAttr *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
long Result = This->GetRightIndent();
rt.addInt(Result);
- break;
+ break;
}
-case wxTextAttr_GetTabs: { // wxTextAttr::GetTabs
+case wxTextAttr_GetTabs: { // wxTextAttr::GetTabs
wxTextAttr *This = (wxTextAttr *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
const wxArrayInt Result = This->GetTabs();
rt.add(Result);
- break;
+ break;
}
-case wxTextAttr_GetTextColour: { // wxTextAttr::GetTextColour
+case wxTextAttr_GetTextColour: { // wxTextAttr::GetTextColour
wxTextAttr *This = (wxTextAttr *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
const wxColour * Result = &This->GetTextColour();
rt.add((*Result));
- break;
+ break;
}
-case wxTextAttr_HasBackgroundColour: { // wxTextAttr::HasBackgroundColour
+case wxTextAttr_HasBackgroundColour: { // wxTextAttr::HasBackgroundColour
wxTextAttr *This = (wxTextAttr *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
bool Result = This->HasBackgroundColour();
rt.addBool(Result);
- break;
+ break;
}
-case wxTextAttr_HasFont: { // wxTextAttr::HasFont
+case wxTextAttr_HasFont: { // wxTextAttr::HasFont
wxTextAttr *This = (wxTextAttr *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
bool Result = This->HasFont();
rt.addBool(Result);
- break;
+ break;
}
-case wxTextAttr_HasTextColour: { // wxTextAttr::HasTextColour
+case wxTextAttr_HasTextColour: { // wxTextAttr::HasTextColour
wxTextAttr *This = (wxTextAttr *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
bool Result = This->HasTextColour();
rt.addBool(Result);
- break;
+ break;
}
-case wxTextAttr_GetFlags: { // wxTextAttr::GetFlags
+case wxTextAttr_GetFlags: { // wxTextAttr::GetFlags
wxTextAttr *This = (wxTextAttr *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
long Result = This->GetFlags();
rt.addInt(Result);
- break;
+ break;
}
-case wxTextAttr_IsDefault: { // wxTextAttr::IsDefault
+case wxTextAttr_IsDefault: { // wxTextAttr::IsDefault
wxTextAttr *This = (wxTextAttr *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
bool Result = This->IsDefault();
rt.addBool(Result);
- break;
+ break;
}
-case wxTextAttr_SetAlignment: { // wxTextAttr::SetAlignment
+case wxTextAttr_SetAlignment: { // wxTextAttr::SetAlignment
wxTextAttr *This = (wxTextAttr *) getPtr(bp,memenv); bp += 4;
wxTextAttrAlignment alignment = *(wxTextAttrAlignment *) bp; bp += 4;;
if(!This) throw wxe_badarg(0);
This->SetAlignment((wxTextAttrAlignment) alignment);
- break;
+ break;
}
-case wxTextAttr_SetBackgroundColour: { // wxTextAttr::SetBackgroundColour
+case wxTextAttr_SetBackgroundColour: { // wxTextAttr::SetBackgroundColour
wxTextAttr *This = (wxTextAttr *) getPtr(bp,memenv); bp += 4;
int * colBackR = (int *) bp; bp += 4;
int * colBackG = (int *) bp; bp += 4;
@@ -16387,49 +16394,49 @@ case wxTextAttr_SetBackgroundColour: { // wxTextAttr::SetBackgroundColour
wxColour colBack = wxColour(*colBackR,*colBackG,*colBackB,*colBackA);
if(!This) throw wxe_badarg(0);
This->SetBackgroundColour(colBack);
- break;
+ break;
}
-case wxTextAttr_SetFlags: { // wxTextAttr::SetFlags
+case wxTextAttr_SetFlags: { // wxTextAttr::SetFlags
wxTextAttr *This = (wxTextAttr *) getPtr(bp,memenv); bp += 4;
int * flags = (int *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
This->SetFlags((long) *flags);
- break;
+ break;
}
-case wxTextAttr_SetFont: { // wxTextAttr::SetFont
+case wxTextAttr_SetFont: { // wxTextAttr::SetFont
long flags=(0x0004|0x0008|0x0010|0x0020|0x0040);
wxTextAttr *This = (wxTextAttr *) getPtr(bp,memenv); bp += 4;
wxFont *font = (wxFont *) getPtr(bp,memenv); bp += 4;
- while( * (int*) bp) { switch (* (int*) bp) {
+ while( * (int*) bp) { switch (* (int*) bp) {
case 1: {bp += 4;
flags = (long)*(int *) bp; bp += 4;
} break;
- }};
+ }};
if(!This) throw wxe_badarg(0);
This->SetFont(*font,flags);
- break;
+ break;
}
-case wxTextAttr_SetLeftIndent: { // wxTextAttr::SetLeftIndent
+case wxTextAttr_SetLeftIndent: { // wxTextAttr::SetLeftIndent
int subIndent=0;
wxTextAttr *This = (wxTextAttr *) getPtr(bp,memenv); bp += 4;
int * indent = (int *) bp; bp += 4;
- while( * (int*) bp) { switch (* (int*) bp) {
+ while( * (int*) bp) { switch (* (int*) bp) {
case 1: {bp += 4;
subIndent = (int)*(int *) bp; bp += 4;
} break;
- }};
+ }};
if(!This) throw wxe_badarg(0);
This->SetLeftIndent((int) *indent,subIndent);
- break;
+ break;
}
-case wxTextAttr_SetRightIndent: { // wxTextAttr::SetRightIndent
+case wxTextAttr_SetRightIndent: { // wxTextAttr::SetRightIndent
wxTextAttr *This = (wxTextAttr *) getPtr(bp,memenv); bp += 4;
int * indent = (int *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
This->SetRightIndent((int) *indent);
- break;
+ break;
}
-case wxTextAttr_SetTabs: { // wxTextAttr::SetTabs
+case wxTextAttr_SetTabs: { // wxTextAttr::SetTabs
wxTextAttr *This = (wxTextAttr *) getPtr(bp,memenv); bp += 4;
int * tabsLen = (int *) bp; bp += 4;
wxArrayInt tabs;
@@ -16437,9 +16444,9 @@ case wxTextAttr_SetTabs: { // wxTextAttr::SetTabs
bp += ((*tabsLen + 2) % 2 )*4;
if(!This) throw wxe_badarg(0);
This->SetTabs(tabs);
- break;
+ break;
}
-case wxTextAttr_SetTextColour: { // wxTextAttr::SetTextColour
+case wxTextAttr_SetTextColour: { // wxTextAttr::SetTextColour
wxTextAttr *This = (wxTextAttr *) getPtr(bp,memenv); bp += 4;
int * colTextR = (int *) bp; bp += 4;
int * colTextG = (int *) bp; bp += 4;
@@ -16448,15 +16455,15 @@ case wxTextAttr_SetTextColour: { // wxTextAttr::SetTextColour
wxColour colText = wxColour(*colTextR,*colTextG,*colTextB,*colTextA);
if(!This) throw wxe_badarg(0);
This->SetTextColour(colText);
- break;
+ break;
}
-case wxTextAttr_destroy: { // wxTextAttr::destroy
+case wxTextAttr_destroy: { // wxTextAttr::destroy
wxTextAttr *This = (wxTextAttr *) getPtr(bp,memenv); bp += 4;
if(This) { ((WxeApp *) wxTheApp)->clearPtr((void *) This);
delete This;}
- break;
+ break;
}
-case wxTextCtrl_new_3: { // wxTextCtrl::wxTextCtrl
+case wxTextCtrl_new_3: { // wxTextCtrl::wxTextCtrl
wxString value= wxEmptyString;
wxPoint pos= wxDefaultPosition;
wxSize size= wxDefaultSize;
@@ -16464,7 +16471,7 @@ case wxTextCtrl_new_3: { // wxTextCtrl::wxTextCtrl
const wxValidator * validator= &wxDefaultValidator;
wxWindow *parent = (wxWindow *) getPtr(bp,memenv); bp += 4;
int * id = (int *) bp; bp += 4;
- while( * (int*) bp) { switch (* (int*) bp) {
+ while( * (int*) bp) { switch (* (int*) bp) {
case 1: {bp += 4;
int * valueLen = (int *) bp; bp += 4;
value = wxString(bp, wxConvUTF8);
@@ -16488,75 +16495,75 @@ case wxTextCtrl_new_3: { // wxTextCtrl::wxTextCtrl
case 5: {bp += 4;
validator = (wxValidator *) getPtr(bp,memenv); bp += 4;
} break;
- }};
+ }};
wxTextCtrl * Result = new EwxTextCtrl(parent,(wxWindowID) *id,value,pos,size,style,*validator);
newPtr((void *) Result, 0, memenv);
rt.addRef(getRef((void *)Result,memenv), "wxTextCtrl");
- break;
+ break;
}
-case wxTextCtrl_new_0: { // wxTextCtrl::wxTextCtrl
+case wxTextCtrl_new_0: { // wxTextCtrl::wxTextCtrl
wxTextCtrl * Result = new EwxTextCtrl();
newPtr((void *) Result, 0, memenv);
rt.addRef(getRef((void *)Result,memenv), "wxTextCtrl");
- break;
+ break;
}
-case wxTextCtrl_AppendText: { // wxTextCtrl::AppendText
+case wxTextCtrl_AppendText: { // wxTextCtrl::AppendText
wxTextCtrl *This = (wxTextCtrl *) getPtr(bp,memenv); bp += 4;
int * textLen = (int *) bp; bp += 4;
wxString text = wxString(bp, wxConvUTF8);
bp += *textLen+((8-((0+ *textLen) & 7)) & 7);
if(!This) throw wxe_badarg(0);
This->AppendText(text);
- break;
+ break;
}
-case wxTextCtrl_CanCopy: { // wxTextCtrl::CanCopy
+case wxTextCtrl_CanCopy: { // wxTextCtrl::CanCopy
wxTextCtrl *This = (wxTextCtrl *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
bool Result = This->CanCopy();
rt.addBool(Result);
- break;
+ break;
}
-case wxTextCtrl_CanCut: { // wxTextCtrl::CanCut
+case wxTextCtrl_CanCut: { // wxTextCtrl::CanCut
wxTextCtrl *This = (wxTextCtrl *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
bool Result = This->CanCut();
rt.addBool(Result);
- break;
+ break;
}
-case wxTextCtrl_CanPaste: { // wxTextCtrl::CanPaste
+case wxTextCtrl_CanPaste: { // wxTextCtrl::CanPaste
wxTextCtrl *This = (wxTextCtrl *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
bool Result = This->CanPaste();
rt.addBool(Result);
- break;
+ break;
}
-case wxTextCtrl_CanRedo: { // wxTextCtrl::CanRedo
+case wxTextCtrl_CanRedo: { // wxTextCtrl::CanRedo
wxTextCtrl *This = (wxTextCtrl *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
bool Result = This->CanRedo();
rt.addBool(Result);
- break;
+ break;
}
-case wxTextCtrl_CanUndo: { // wxTextCtrl::CanUndo
+case wxTextCtrl_CanUndo: { // wxTextCtrl::CanUndo
wxTextCtrl *This = (wxTextCtrl *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
bool Result = This->CanUndo();
rt.addBool(Result);
- break;
+ break;
}
-case wxTextCtrl_Clear: { // wxTextCtrl::Clear
+case wxTextCtrl_Clear: { // wxTextCtrl::Clear
wxTextCtrl *This = (wxTextCtrl *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
This->Clear();
- break;
+ break;
}
-case wxTextCtrl_Copy: { // wxTextCtrl::Copy
+case wxTextCtrl_Copy: { // wxTextCtrl::Copy
wxTextCtrl *This = (wxTextCtrl *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
This->Copy();
- break;
+ break;
}
-case wxTextCtrl_Create: { // wxTextCtrl::Create
+case wxTextCtrl_Create: { // wxTextCtrl::Create
wxString value= wxEmptyString;
wxPoint pos= wxDefaultPosition;
wxSize size= wxDefaultSize;
@@ -16566,7 +16573,7 @@ case wxTextCtrl_Create: { // wxTextCtrl::Create
wxWindow *parent = (wxWindow *) getPtr(bp,memenv); bp += 4;
int * id = (int *) bp; bp += 4;
bp += 4; /* Align */
- while( * (int*) bp) { switch (* (int*) bp) {
+ while( * (int*) bp) { switch (* (int*) bp) {
case 1: {bp += 4;
int * valueLen = (int *) bp; bp += 4;
value = wxString(bp, wxConvUTF8);
@@ -16590,86 +16597,86 @@ case wxTextCtrl_Create: { // wxTextCtrl::Create
case 5: {bp += 4;
validator = (wxValidator *) getPtr(bp,memenv); bp += 4;
} break;
- }};
+ }};
if(!This) throw wxe_badarg(0);
bool Result = This->Create(parent,(wxWindowID) *id,value,pos,size,style,*validator);
rt.addBool(Result);
- break;
+ break;
}
-case wxTextCtrl_Cut: { // wxTextCtrl::Cut
+case wxTextCtrl_Cut: { // wxTextCtrl::Cut
wxTextCtrl *This = (wxTextCtrl *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
This->Cut();
- break;
+ break;
}
-case wxTextCtrl_DiscardEdits: { // wxTextCtrl::DiscardEdits
+case wxTextCtrl_DiscardEdits: { // wxTextCtrl::DiscardEdits
wxTextCtrl *This = (wxTextCtrl *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
This->DiscardEdits();
- break;
+ break;
}
-case wxTextCtrl_EmulateKeyPress: { // wxTextCtrl::EmulateKeyPress
+case wxTextCtrl_EmulateKeyPress: { // wxTextCtrl::EmulateKeyPress
wxTextCtrl *This = (wxTextCtrl *) getPtr(bp,memenv); bp += 4;
wxKeyEvent *event = (wxKeyEvent *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
bool Result = This->EmulateKeyPress(*event);
rt.addBool(Result);
- break;
+ break;
}
-case wxTextCtrl_GetDefaultStyle: { // wxTextCtrl::GetDefaultStyle
+case wxTextCtrl_GetDefaultStyle: { // wxTextCtrl::GetDefaultStyle
wxTextCtrl *This = (wxTextCtrl *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
const wxTextAttr * Result = &This->GetDefaultStyle();
rt.addRef(getRef((void *)Result,memenv), "wxTextAttr");
- break;
+ break;
}
-case wxTextCtrl_GetInsertionPoint: { // wxTextCtrl::GetInsertionPoint
+case wxTextCtrl_GetInsertionPoint: { // wxTextCtrl::GetInsertionPoint
wxTextCtrl *This = (wxTextCtrl *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
long Result = This->GetInsertionPoint();
rt.addInt(Result);
- break;
+ break;
}
-case wxTextCtrl_GetLastPosition: { // wxTextCtrl::GetLastPosition
+case wxTextCtrl_GetLastPosition: { // wxTextCtrl::GetLastPosition
wxTextCtrl *This = (wxTextCtrl *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
wxTextPos Result = This->GetLastPosition();
rt.addInt(Result);
- break;
+ break;
}
-case wxTextCtrl_GetLineLength: { // wxTextCtrl::GetLineLength
+case wxTextCtrl_GetLineLength: { // wxTextCtrl::GetLineLength
wxTextCtrl *This = (wxTextCtrl *) getPtr(bp,memenv); bp += 4;
int * lineNo = (int *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
int Result = This->GetLineLength((long) *lineNo);
rt.addInt(Result);
- break;
+ break;
}
-case wxTextCtrl_GetLineText: { // wxTextCtrl::GetLineText
+case wxTextCtrl_GetLineText: { // wxTextCtrl::GetLineText
wxTextCtrl *This = (wxTextCtrl *) getPtr(bp,memenv); bp += 4;
int * lineNo = (int *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
wxString Result = This->GetLineText((long) *lineNo);
rt.add(Result);
- break;
+ break;
}
-case wxTextCtrl_GetNumberOfLines: { // wxTextCtrl::GetNumberOfLines
+case wxTextCtrl_GetNumberOfLines: { // wxTextCtrl::GetNumberOfLines
wxTextCtrl *This = (wxTextCtrl *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
int Result = This->GetNumberOfLines();
rt.addInt(Result);
- break;
+ break;
}
-case wxTextCtrl_GetRange: { // wxTextCtrl::GetRange
+case wxTextCtrl_GetRange: { // wxTextCtrl::GetRange
wxTextCtrl *This = (wxTextCtrl *) getPtr(bp,memenv); bp += 4;
int * from = (int *) bp; bp += 4;
int * to = (int *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
wxString Result = This->GetRange((long) *from,(long) *to);
rt.add(Result);
- break;
+ break;
}
-case wxTextCtrl_GetSelection: { // wxTextCtrl::GetSelection
+case wxTextCtrl_GetSelection: { // wxTextCtrl::GetSelection
long from;
long to;
wxTextCtrl *This = (wxTextCtrl *) getPtr(bp,memenv); bp += 4;
@@ -16678,88 +16685,88 @@ case wxTextCtrl_GetSelection: { // wxTextCtrl::GetSelection
rt.addInt(from);
rt.addInt(to);
rt.addTupleCount(2);
- break;
+ break;
}
-case wxTextCtrl_GetStringSelection: { // wxTextCtrl::GetStringSelection
+case wxTextCtrl_GetStringSelection: { // wxTextCtrl::GetStringSelection
wxTextCtrl *This = (wxTextCtrl *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
wxString Result = This->GetStringSelection();
rt.add(Result);
- break;
+ break;
}
-case wxTextCtrl_GetStyle: { // wxTextCtrl::GetStyle
+case wxTextCtrl_GetStyle: { // wxTextCtrl::GetStyle
wxTextCtrl *This = (wxTextCtrl *) getPtr(bp,memenv); bp += 4;
int * position = (int *) bp; bp += 4;
wxTextAttr *style = (wxTextAttr *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
bool Result = This->GetStyle((long) *position,*style);
rt.addBool(Result);
- break;
+ break;
}
-case wxTextCtrl_GetValue: { // wxTextCtrl::GetValue
+case wxTextCtrl_GetValue: { // wxTextCtrl::GetValue
wxTextCtrl *This = (wxTextCtrl *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
wxString Result = This->GetValue();
rt.add(Result);
- break;
+ break;
}
-case wxTextCtrl_IsEditable: { // wxTextCtrl::IsEditable
+case wxTextCtrl_IsEditable: { // wxTextCtrl::IsEditable
wxTextCtrl *This = (wxTextCtrl *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
bool Result = This->IsEditable();
rt.addBool(Result);
- break;
+ break;
}
-case wxTextCtrl_IsModified: { // wxTextCtrl::IsModified
+case wxTextCtrl_IsModified: { // wxTextCtrl::IsModified
wxTextCtrl *This = (wxTextCtrl *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
bool Result = This->IsModified();
rt.addBool(Result);
- break;
+ break;
}
-case wxTextCtrl_IsMultiLine: { // wxTextCtrl::IsMultiLine
+case wxTextCtrl_IsMultiLine: { // wxTextCtrl::IsMultiLine
wxTextCtrl *This = (wxTextCtrl *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
bool Result = This->IsMultiLine();
rt.addBool(Result);
- break;
+ break;
}
-case wxTextCtrl_IsSingleLine: { // wxTextCtrl::IsSingleLine
+case wxTextCtrl_IsSingleLine: { // wxTextCtrl::IsSingleLine
wxTextCtrl *This = (wxTextCtrl *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
bool Result = This->IsSingleLine();
rt.addBool(Result);
- break;
+ break;
}
-case wxTextCtrl_LoadFile: { // wxTextCtrl::LoadFile
+case wxTextCtrl_LoadFile: { // wxTextCtrl::LoadFile
int fileType=0;
wxTextCtrl *This = (wxTextCtrl *) getPtr(bp,memenv); bp += 4;
int * fileLen = (int *) bp; bp += 4;
wxString file = wxString(bp, wxConvUTF8);
bp += *fileLen+((8-((0+ *fileLen) & 7)) & 7);
- while( * (int*) bp) { switch (* (int*) bp) {
+ while( * (int*) bp) { switch (* (int*) bp) {
case 1: {bp += 4;
fileType = (int)*(int *) bp; bp += 4;
} break;
- }};
+ }};
if(!This) throw wxe_badarg(0);
bool Result = This->LoadFile(file,fileType);
rt.addBool(Result);
- break;
+ break;
}
-case wxTextCtrl_MarkDirty: { // wxTextCtrl::MarkDirty
+case wxTextCtrl_MarkDirty: { // wxTextCtrl::MarkDirty
wxTextCtrl *This = (wxTextCtrl *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
This->MarkDirty();
- break;
+ break;
}
-case wxTextCtrl_Paste: { // wxTextCtrl::Paste
+case wxTextCtrl_Paste: { // wxTextCtrl::Paste
wxTextCtrl *This = (wxTextCtrl *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
This->Paste();
- break;
+ break;
}
-case wxTextCtrl_PositionToXY: { // wxTextCtrl::PositionToXY
+case wxTextCtrl_PositionToXY: { // wxTextCtrl::PositionToXY
long x;
long y;
wxTextCtrl *This = (wxTextCtrl *) getPtr(bp,memenv); bp += 4;
@@ -16770,23 +16777,23 @@ case wxTextCtrl_PositionToXY: { // wxTextCtrl::PositionToXY
rt.addInt(x);
rt.addInt(y);
rt.addTupleCount(3);
- break;
+ break;
}
-case wxTextCtrl_Redo: { // wxTextCtrl::Redo
+case wxTextCtrl_Redo: { // wxTextCtrl::Redo
wxTextCtrl *This = (wxTextCtrl *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
This->Redo();
- break;
+ break;
}
-case wxTextCtrl_Remove: { // wxTextCtrl::Remove
+case wxTextCtrl_Remove: { // wxTextCtrl::Remove
wxTextCtrl *This = (wxTextCtrl *) getPtr(bp,memenv); bp += 4;
int * from = (int *) bp; bp += 4;
int * to = (int *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
This->Remove((long) *from,(long) *to);
- break;
+ break;
}
-case wxTextCtrl_Replace: { // wxTextCtrl::Replace
+case wxTextCtrl_Replace: { // wxTextCtrl::Replace
wxTextCtrl *This = (wxTextCtrl *) getPtr(bp,memenv); bp += 4;
int * from = (int *) bp; bp += 4;
int * to = (int *) bp; bp += 4;
@@ -16795,14 +16802,14 @@ case wxTextCtrl_Replace: { // wxTextCtrl::Replace
bp += *valueLen+((8-((0+ *valueLen) & 7)) & 7);
if(!This) throw wxe_badarg(0);
This->Replace((long) *from,(long) *to,value);
- break;
+ break;
}
-case wxTextCtrl_SaveFile: { // wxTextCtrl::SaveFile
+case wxTextCtrl_SaveFile: { // wxTextCtrl::SaveFile
wxString file= wxEmptyString;
int fileType=0;
wxTextCtrl *This = (wxTextCtrl *) getPtr(bp,memenv); bp += 4;
bp += 4; /* Align */
- while( * (int*) bp) { switch (* (int*) bp) {
+ while( * (int*) bp) { switch (* (int*) bp) {
case 1: {bp += 4;
int * fileLen = (int *) bp; bp += 4;
file = wxString(bp, wxConvUTF8);
@@ -16811,56 +16818,56 @@ case wxTextCtrl_SaveFile: { // wxTextCtrl::SaveFile
case 2: {bp += 4;
fileType = (int)*(int *) bp; bp += 4;
} break;
- }};
+ }};
if(!This) throw wxe_badarg(0);
bool Result = This->SaveFile(file,fileType);
rt.addBool(Result);
- break;
+ break;
}
-case wxTextCtrl_SetDefaultStyle: { // wxTextCtrl::SetDefaultStyle
+case wxTextCtrl_SetDefaultStyle: { // wxTextCtrl::SetDefaultStyle
wxTextCtrl *This = (wxTextCtrl *) getPtr(bp,memenv); bp += 4;
wxTextAttr *style = (wxTextAttr *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
bool Result = This->SetDefaultStyle(*style);
rt.addBool(Result);
- break;
+ break;
}
-case wxTextCtrl_SetEditable: { // wxTextCtrl::SetEditable
+case wxTextCtrl_SetEditable: { // wxTextCtrl::SetEditable
wxTextCtrl *This = (wxTextCtrl *) getPtr(bp,memenv); bp += 4;
bool * editable = (bool *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
This->SetEditable((bool) *editable);
- break;
+ break;
}
-case wxTextCtrl_SetInsertionPoint: { // wxTextCtrl::SetInsertionPoint
+case wxTextCtrl_SetInsertionPoint: { // wxTextCtrl::SetInsertionPoint
wxTextCtrl *This = (wxTextCtrl *) getPtr(bp,memenv); bp += 4;
int * pos = (int *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
This->SetInsertionPoint((long) *pos);
- break;
+ break;
}
-case wxTextCtrl_SetInsertionPointEnd: { // wxTextCtrl::SetInsertionPointEnd
+case wxTextCtrl_SetInsertionPointEnd: { // wxTextCtrl::SetInsertionPointEnd
wxTextCtrl *This = (wxTextCtrl *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
This->SetInsertionPointEnd();
- break;
+ break;
}
-case wxTextCtrl_SetMaxLength: { // wxTextCtrl::SetMaxLength
+case wxTextCtrl_SetMaxLength: { // wxTextCtrl::SetMaxLength
wxTextCtrl *This = (wxTextCtrl *) getPtr(bp,memenv); bp += 4;
unsigned int * len = (unsigned int *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
This->SetMaxLength((long) *len);
- break;
+ break;
}
-case wxTextCtrl_SetSelection: { // wxTextCtrl::SetSelection
+case wxTextCtrl_SetSelection: { // wxTextCtrl::SetSelection
wxTextCtrl *This = (wxTextCtrl *) getPtr(bp,memenv); bp += 4;
int * from = (int *) bp; bp += 4;
int * to = (int *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
This->SetSelection((long) *from,(long) *to);
- break;
+ break;
}
-case wxTextCtrl_SetStyle: { // wxTextCtrl::SetStyle
+case wxTextCtrl_SetStyle: { // wxTextCtrl::SetStyle
wxTextCtrl *This = (wxTextCtrl *) getPtr(bp,memenv); bp += 4;
int * start = (int *) bp; bp += 4;
int * end = (int *) bp; bp += 4;
@@ -16868,61 +16875,61 @@ case wxTextCtrl_SetStyle: { // wxTextCtrl::SetStyle
if(!This) throw wxe_badarg(0);
bool Result = This->SetStyle((long) *start,(long) *end,*style);
rt.addBool(Result);
- break;
+ break;
}
-case wxTextCtrl_SetValue: { // wxTextCtrl::SetValue
+case wxTextCtrl_SetValue: { // wxTextCtrl::SetValue
wxTextCtrl *This = (wxTextCtrl *) getPtr(bp,memenv); bp += 4;
int * valueLen = (int *) bp; bp += 4;
wxString value = wxString(bp, wxConvUTF8);
bp += *valueLen+((8-((0+ *valueLen) & 7)) & 7);
if(!This) throw wxe_badarg(0);
This->SetValue(value);
- break;
+ break;
}
-case wxTextCtrl_ShowPosition: { // wxTextCtrl::ShowPosition
+case wxTextCtrl_ShowPosition: { // wxTextCtrl::ShowPosition
wxTextCtrl *This = (wxTextCtrl *) getPtr(bp,memenv); bp += 4;
int * pos = (int *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
This->ShowPosition((long) *pos);
- break;
+ break;
}
-case wxTextCtrl_Undo: { // wxTextCtrl::Undo
+case wxTextCtrl_Undo: { // wxTextCtrl::Undo
wxTextCtrl *This = (wxTextCtrl *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
This->Undo();
- break;
+ break;
}
-case wxTextCtrl_WriteText: { // wxTextCtrl::WriteText
+case wxTextCtrl_WriteText: { // wxTextCtrl::WriteText
wxTextCtrl *This = (wxTextCtrl *) getPtr(bp,memenv); bp += 4;
int * textLen = (int *) bp; bp += 4;
wxString text = wxString(bp, wxConvUTF8);
bp += *textLen+((8-((0+ *textLen) & 7)) & 7);
if(!This) throw wxe_badarg(0);
This->WriteText(text);
- break;
+ break;
}
-case wxTextCtrl_XYToPosition: { // wxTextCtrl::XYToPosition
+case wxTextCtrl_XYToPosition: { // wxTextCtrl::XYToPosition
wxTextCtrl *This = (wxTextCtrl *) getPtr(bp,memenv); bp += 4;
int * x = (int *) bp; bp += 4;
int * y = (int *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
long Result = This->XYToPosition((long) *x,(long) *y);
rt.addInt(Result);
- break;
+ break;
}
-case wxNotebook_new_0: { // wxNotebook::wxNotebook
+case wxNotebook_new_0: { // wxNotebook::wxNotebook
wxNotebook * Result = new EwxNotebook();
newPtr((void *) Result, 0, memenv);
rt.addRef(getRef((void *)Result,memenv), "wxNotebook");
- break;
+ break;
}
-case wxNotebook_new_3: { // wxNotebook::wxNotebook
+case wxNotebook_new_3: { // wxNotebook::wxNotebook
wxPoint pos= wxDefaultPosition;
wxSize size= wxDefaultSize;
long style=0;
wxWindow *parent = (wxWindow *) getPtr(bp,memenv); bp += 4;
int * winid = (int *) bp; bp += 4;
- while( * (int*) bp) { switch (* (int*) bp) {
+ while( * (int*) bp) { switch (* (int*) bp) {
case 1: {bp += 4;
int * posX = (int *) bp; bp += 4;
int * posY = (int *) bp; bp += 4;
@@ -16938,13 +16945,13 @@ case wxNotebook_new_3: { // wxNotebook::wxNotebook
case 3: {bp += 4;
style = (long)*(int *) bp; bp += 4;
} break;
- }};
+ }};
wxNotebook * Result = new EwxNotebook(parent,(wxWindowID) *winid,pos,size,style);
newPtr((void *) Result, 0, memenv);
rt.addRef(getRef((void *)Result,memenv), "wxNotebook");
- break;
+ break;
}
-case wxNotebook_AddPage: { // wxNotebook::AddPage
+case wxNotebook_AddPage: { // wxNotebook::AddPage
bool bSelect=false;
int imageId=-1;
wxNotebook *This = (wxNotebook *) getPtr(bp,memenv); bp += 4;
@@ -16952,40 +16959,40 @@ case wxNotebook_AddPage: { // wxNotebook::AddPage
int * textLen = (int *) bp; bp += 4;
wxString text = wxString(bp, wxConvUTF8);
bp += *textLen+((8-((4+ *textLen) & 7)) & 7);
- while( * (int*) bp) { switch (* (int*) bp) {
+ while( * (int*) bp) { switch (* (int*) bp) {
case 1: {bp += 4;
bSelect = *(bool *) bp; bp += 4;
} break;
case 2: {bp += 4;
imageId = (int)*(int *) bp; bp += 4;
} break;
- }};
+ }};
if(!This) throw wxe_badarg(0);
bool Result = This->AddPage(page,text,bSelect,imageId);
rt.addBool(Result);
- break;
+ break;
}
-case wxNotebook_AdvanceSelection: { // wxNotebook::AdvanceSelection
+case wxNotebook_AdvanceSelection: { // wxNotebook::AdvanceSelection
bool forward=true;
wxNotebook *This = (wxNotebook *) getPtr(bp,memenv); bp += 4;
bp += 4; /* Align */
- while( * (int*) bp) { switch (* (int*) bp) {
+ while( * (int*) bp) { switch (* (int*) bp) {
case 1: {bp += 4;
forward = *(bool *) bp; bp += 4;
} break;
- }};
+ }};
if(!This) throw wxe_badarg(0);
This->AdvanceSelection(forward);
- break;
+ break;
}
-case wxNotebook_AssignImageList: { // wxNotebook::AssignImageList
+case wxNotebook_AssignImageList: { // wxNotebook::AssignImageList
wxNotebook *This = (wxNotebook *) getPtr(bp,memenv); bp += 4;
wxImageList *imageList = (wxImageList *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
This->AssignImageList(imageList);
- break;
+ break;
}
-case wxNotebook_Create: { // wxNotebook::Create
+case wxNotebook_Create: { // wxNotebook::Create
wxPoint pos= wxDefaultPosition;
wxSize size= wxDefaultSize;
long style=0;
@@ -16993,7 +17000,7 @@ case wxNotebook_Create: { // wxNotebook::Create
wxWindow *parent = (wxWindow *) getPtr(bp,memenv); bp += 4;
int * id = (int *) bp; bp += 4;
bp += 4; /* Align */
- while( * (int*) bp) { switch (* (int*) bp) {
+ while( * (int*) bp) { switch (* (int*) bp) {
case 1: {bp += 4;
int * posX = (int *) bp; bp += 4;
int * posY = (int *) bp; bp += 4;
@@ -17009,102 +17016,102 @@ case wxNotebook_Create: { // wxNotebook::Create
case 3: {bp += 4;
style = (long)*(int *) bp; bp += 4;
} break;
- }};
+ }};
if(!This) throw wxe_badarg(0);
bool Result = This->Create(parent,(wxWindowID) *id,pos,size,style);
rt.addBool(Result);
- break;
+ break;
}
-case wxNotebook_DeleteAllPages: { // wxNotebook::DeleteAllPages
+case wxNotebook_DeleteAllPages: { // wxNotebook::DeleteAllPages
wxNotebook *This = (wxNotebook *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
bool Result = This->DeleteAllPages();
rt.addBool(Result);
- break;
+ break;
}
-case wxNotebook_DeletePage: { // wxNotebook::DeletePage
+case wxNotebook_DeletePage: { // wxNotebook::DeletePage
wxNotebook *This = (wxNotebook *) getPtr(bp,memenv); bp += 4;
int * nPage = (int *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
bool Result = This->DeletePage((size_t) *nPage);
rt.addBool(Result);
- break;
+ break;
}
-case wxNotebook_RemovePage: { // wxNotebook::RemovePage
+case wxNotebook_RemovePage: { // wxNotebook::RemovePage
wxNotebook *This = (wxNotebook *) getPtr(bp,memenv); bp += 4;
int * nPage = (int *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
bool Result = This->RemovePage((size_t) *nPage);
rt.addBool(Result);
- break;
+ break;
}
-case wxNotebook_GetCurrentPage: { // wxNotebook::GetCurrentPage
+case wxNotebook_GetCurrentPage: { // wxNotebook::GetCurrentPage
wxNotebook *This = (wxNotebook *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
wxWindow * Result = (wxWindow*)This->GetCurrentPage();
rt.addRef(getRef((void *)Result,memenv), "wxWindow");
- break;
+ break;
}
-case wxNotebook_GetImageList: { // wxNotebook::GetImageList
+case wxNotebook_GetImageList: { // wxNotebook::GetImageList
wxNotebook *This = (wxNotebook *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
wxImageList * Result = (wxImageList*)This->GetImageList();
rt.addRef(getRef((void *)Result,memenv), "wxImageList");
- break;
+ break;
}
-case wxNotebook_GetPage: { // wxNotebook::GetPage
+case wxNotebook_GetPage: { // wxNotebook::GetPage
wxNotebook *This = (wxNotebook *) getPtr(bp,memenv); bp += 4;
int * n = (int *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
wxWindow * Result = (wxWindow*)This->GetPage((size_t) *n);
rt.addRef(getRef((void *)Result,memenv), "wxWindow");
- break;
+ break;
}
-case wxNotebook_GetPageCount: { // wxNotebook::GetPageCount
+case wxNotebook_GetPageCount: { // wxNotebook::GetPageCount
wxNotebook *This = (wxNotebook *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
size_t Result = This->GetPageCount();
rt.addInt(Result);
- break;
+ break;
}
-case wxNotebook_GetPageImage: { // wxNotebook::GetPageImage
+case wxNotebook_GetPageImage: { // wxNotebook::GetPageImage
wxNotebook *This = (wxNotebook *) getPtr(bp,memenv); bp += 4;
int * nPage = (int *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
int Result = This->GetPageImage((size_t) *nPage);
rt.addInt(Result);
- break;
+ break;
}
-case wxNotebook_GetPageText: { // wxNotebook::GetPageText
+case wxNotebook_GetPageText: { // wxNotebook::GetPageText
wxNotebook *This = (wxNotebook *) getPtr(bp,memenv); bp += 4;
int * nPage = (int *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
wxString Result = This->GetPageText((size_t) *nPage);
rt.add(Result);
- break;
+ break;
}
-case wxNotebook_GetRowCount: { // wxNotebook::GetRowCount
+case wxNotebook_GetRowCount: { // wxNotebook::GetRowCount
wxNotebook *This = (wxNotebook *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
int Result = This->GetRowCount();
rt.addInt(Result);
- break;
+ break;
}
-case wxNotebook_GetSelection: { // wxNotebook::GetSelection
+case wxNotebook_GetSelection: { // wxNotebook::GetSelection
wxNotebook *This = (wxNotebook *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
int Result = This->GetSelection();
rt.addInt(Result);
- break;
+ break;
}
-case wxNotebook_GetThemeBackgroundColour: { // wxNotebook::GetThemeBackgroundColour
+case wxNotebook_GetThemeBackgroundColour: { // wxNotebook::GetThemeBackgroundColour
wxNotebook *This = (wxNotebook *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
wxColour Result = This->GetThemeBackgroundColour();
rt.add(Result);
- break;
+ break;
}
-case wxNotebook_HitTest: { // wxNotebook::HitTest
+case wxNotebook_HitTest: { // wxNotebook::HitTest
long flags;
wxNotebook *This = (wxNotebook *) getPtr(bp,memenv); bp += 4;
int * ptX = (int *) bp; bp += 4;
@@ -17115,9 +17122,9 @@ case wxNotebook_HitTest: { // wxNotebook::HitTest
rt.addInt(Result);
rt.addInt(flags);
rt.addTupleCount(2);
- break;
+ break;
}
-case wxNotebook_InsertPage: { // wxNotebook::InsertPage
+case wxNotebook_InsertPage: { // wxNotebook::InsertPage
bool bSelect=false;
int imageId=-1;
wxNotebook *This = (wxNotebook *) getPtr(bp,memenv); bp += 4;
@@ -17126,54 +17133,54 @@ case wxNotebook_InsertPage: { // wxNotebook::InsertPage
int * strTextLen = (int *) bp; bp += 4;
wxString strText = wxString(bp, wxConvUTF8);
bp += *strTextLen+((8-((0+ *strTextLen) & 7)) & 7);
- while( * (int*) bp) { switch (* (int*) bp) {
+ while( * (int*) bp) { switch (* (int*) bp) {
case 1: {bp += 4;
bSelect = *(bool *) bp; bp += 4;
} break;
case 2: {bp += 4;
imageId = (int)*(int *) bp; bp += 4;
} break;
- }};
+ }};
if(!This) throw wxe_badarg(0);
bool Result = This->InsertPage((size_t) *position,win,strText,bSelect,imageId);
rt.addBool(Result);
- break;
+ break;
}
-case wxNotebook_SetImageList: { // wxNotebook::SetImageList
+case wxNotebook_SetImageList: { // wxNotebook::SetImageList
wxNotebook *This = (wxNotebook *) getPtr(bp,memenv); bp += 4;
wxImageList *imageList = (wxImageList *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
This->SetImageList(imageList);
- break;
+ break;
}
-case wxNotebook_SetPadding: { // wxNotebook::SetPadding
+case wxNotebook_SetPadding: { // wxNotebook::SetPadding
wxNotebook *This = (wxNotebook *) getPtr(bp,memenv); bp += 4;
int * paddingW = (int *) bp; bp += 4;
int * paddingH = (int *) bp; bp += 4;
wxSize padding = wxSize(*paddingW,*paddingH);
if(!This) throw wxe_badarg(0);
This->SetPadding(padding);
- break;
+ break;
}
-case wxNotebook_SetPageSize: { // wxNotebook::SetPageSize
+case wxNotebook_SetPageSize: { // wxNotebook::SetPageSize
wxNotebook *This = (wxNotebook *) getPtr(bp,memenv); bp += 4;
int * sizeW = (int *) bp; bp += 4;
int * sizeH = (int *) bp; bp += 4;
wxSize size = wxSize(*sizeW,*sizeH);
if(!This) throw wxe_badarg(0);
This->SetPageSize(size);
- break;
+ break;
}
-case wxNotebook_SetPageImage: { // wxNotebook::SetPageImage
+case wxNotebook_SetPageImage: { // wxNotebook::SetPageImage
wxNotebook *This = (wxNotebook *) getPtr(bp,memenv); bp += 4;
int * nPage = (int *) bp; bp += 4;
int * nImage = (int *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
bool Result = This->SetPageImage((size_t) *nPage,(int) *nImage);
rt.addBool(Result);
- break;
+ break;
}
-case wxNotebook_SetPageText: { // wxNotebook::SetPageText
+case wxNotebook_SetPageText: { // wxNotebook::SetPageText
wxNotebook *This = (wxNotebook *) getPtr(bp,memenv); bp += 4;
int * nPage = (int *) bp; bp += 4;
int * strTextLen = (int *) bp; bp += 4;
@@ -17182,37 +17189,37 @@ case wxNotebook_SetPageText: { // wxNotebook::SetPageText
if(!This) throw wxe_badarg(0);
bool Result = This->SetPageText((size_t) *nPage,strText);
rt.addBool(Result);
- break;
+ break;
}
-case wxNotebook_SetSelection: { // wxNotebook::SetSelection
+case wxNotebook_SetSelection: { // wxNotebook::SetSelection
wxNotebook *This = (wxNotebook *) getPtr(bp,memenv); bp += 4;
int * nPage = (int *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
int Result = This->SetSelection((size_t) *nPage);
rt.addInt(Result);
- break;
+ break;
}
-case wxNotebook_ChangeSelection: { // wxNotebook::ChangeSelection
+case wxNotebook_ChangeSelection: { // wxNotebook::ChangeSelection
wxNotebook *This = (wxNotebook *) getPtr(bp,memenv); bp += 4;
int * nPage = (int *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
int Result = This->ChangeSelection((size_t) *nPage);
rt.addInt(Result);
- break;
+ break;
}
-case wxChoicebook_new_0: { // wxChoicebook::wxChoicebook
+case wxChoicebook_new_0: { // wxChoicebook::wxChoicebook
wxChoicebook * Result = new EwxChoicebook();
newPtr((void *) Result, 0, memenv);
rt.addRef(getRef((void *)Result,memenv), "wxChoicebook");
- break;
+ break;
}
-case wxChoicebook_new_3: { // wxChoicebook::wxChoicebook
+case wxChoicebook_new_3: { // wxChoicebook::wxChoicebook
wxPoint pos= wxDefaultPosition;
wxSize size= wxDefaultSize;
long style=0;
wxWindow *parent = (wxWindow *) getPtr(bp,memenv); bp += 4;
int * id = (int *) bp; bp += 4;
- while( * (int*) bp) { switch (* (int*) bp) {
+ while( * (int*) bp) { switch (* (int*) bp) {
case 1: {bp += 4;
int * posX = (int *) bp; bp += 4;
int * posY = (int *) bp; bp += 4;
@@ -17228,13 +17235,13 @@ case wxChoicebook_new_3: { // wxChoicebook::wxChoicebook
case 3: {bp += 4;
style = (long)*(int *) bp; bp += 4;
} break;
- }};
+ }};
wxChoicebook * Result = new EwxChoicebook(parent,(wxWindowID) *id,pos,size,style);
newPtr((void *) Result, 0, memenv);
rt.addRef(getRef((void *)Result,memenv), "wxChoicebook");
- break;
+ break;
}
-case wxChoicebook_AddPage: { // wxChoicebook::AddPage
+case wxChoicebook_AddPage: { // wxChoicebook::AddPage
bool bSelect=false;
int imageId=-1;
wxChoicebook *This = (wxChoicebook *) getPtr(bp,memenv); bp += 4;
@@ -17242,40 +17249,40 @@ case wxChoicebook_AddPage: { // wxChoicebook::AddPage
int * textLen = (int *) bp; bp += 4;
wxString text = wxString(bp, wxConvUTF8);
bp += *textLen+((8-((4+ *textLen) & 7)) & 7);
- while( * (int*) bp) { switch (* (int*) bp) {
+ while( * (int*) bp) { switch (* (int*) bp) {
case 1: {bp += 4;
bSelect = *(bool *) bp; bp += 4;
} break;
case 2: {bp += 4;
imageId = (int)*(int *) bp; bp += 4;
} break;
- }};
+ }};
if(!This) throw wxe_badarg(0);
bool Result = This->AddPage(page,text,bSelect,imageId);
rt.addBool(Result);
- break;
+ break;
}
-case wxChoicebook_AdvanceSelection: { // wxChoicebook::AdvanceSelection
+case wxChoicebook_AdvanceSelection: { // wxChoicebook::AdvanceSelection
bool forward=true;
wxChoicebook *This = (wxChoicebook *) getPtr(bp,memenv); bp += 4;
bp += 4; /* Align */
- while( * (int*) bp) { switch (* (int*) bp) {
+ while( * (int*) bp) { switch (* (int*) bp) {
case 1: {bp += 4;
forward = *(bool *) bp; bp += 4;
} break;
- }};
+ }};
if(!This) throw wxe_badarg(0);
This->AdvanceSelection(forward);
- break;
+ break;
}
-case wxChoicebook_AssignImageList: { // wxChoicebook::AssignImageList
+case wxChoicebook_AssignImageList: { // wxChoicebook::AssignImageList
wxChoicebook *This = (wxChoicebook *) getPtr(bp,memenv); bp += 4;
wxImageList *imageList = (wxImageList *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
This->AssignImageList(imageList);
- break;
+ break;
}
-case wxChoicebook_Create: { // wxChoicebook::Create
+case wxChoicebook_Create: { // wxChoicebook::Create
wxPoint pos= wxDefaultPosition;
wxSize size= wxDefaultSize;
long style=0;
@@ -17283,7 +17290,7 @@ case wxChoicebook_Create: { // wxChoicebook::Create
wxWindow *parent = (wxWindow *) getPtr(bp,memenv); bp += 4;
int * id = (int *) bp; bp += 4;
bp += 4; /* Align */
- while( * (int*) bp) { switch (* (int*) bp) {
+ while( * (int*) bp) { switch (* (int*) bp) {
case 1: {bp += 4;
int * posX = (int *) bp; bp += 4;
int * posY = (int *) bp; bp += 4;
@@ -17299,88 +17306,88 @@ case wxChoicebook_Create: { // wxChoicebook::Create
case 3: {bp += 4;
style = (long)*(int *) bp; bp += 4;
} break;
- }};
+ }};
if(!This) throw wxe_badarg(0);
bool Result = This->Create(parent,(wxWindowID) *id,pos,size,style);
rt.addBool(Result);
- break;
+ break;
}
-case wxChoicebook_DeleteAllPages: { // wxChoicebook::DeleteAllPages
+case wxChoicebook_DeleteAllPages: { // wxChoicebook::DeleteAllPages
wxChoicebook *This = (wxChoicebook *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
bool Result = This->DeleteAllPages();
rt.addBool(Result);
- break;
+ break;
}
-case wxChoicebook_DeletePage: { // wxChoicebook::DeletePage
+case wxChoicebook_DeletePage: { // wxChoicebook::DeletePage
wxChoicebook *This = (wxChoicebook *) getPtr(bp,memenv); bp += 4;
int * n = (int *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
bool Result = This->DeletePage((size_t) *n);
rt.addBool(Result);
- break;
+ break;
}
-case wxChoicebook_RemovePage: { // wxChoicebook::RemovePage
+case wxChoicebook_RemovePage: { // wxChoicebook::RemovePage
wxChoicebook *This = (wxChoicebook *) getPtr(bp,memenv); bp += 4;
int * n = (int *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
bool Result = This->RemovePage((size_t) *n);
rt.addBool(Result);
- break;
+ break;
}
-case wxChoicebook_GetCurrentPage: { // wxChoicebook::GetCurrentPage
+case wxChoicebook_GetCurrentPage: { // wxChoicebook::GetCurrentPage
wxChoicebook *This = (wxChoicebook *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
wxWindow * Result = (wxWindow*)This->GetCurrentPage();
rt.addRef(getRef((void *)Result,memenv), "wxWindow");
- break;
+ break;
}
-case wxChoicebook_GetImageList: { // wxChoicebook::GetImageList
+case wxChoicebook_GetImageList: { // wxChoicebook::GetImageList
wxChoicebook *This = (wxChoicebook *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
wxImageList * Result = (wxImageList*)This->GetImageList();
rt.addRef(getRef((void *)Result,memenv), "wxImageList");
- break;
+ break;
}
-case wxChoicebook_GetPage: { // wxChoicebook::GetPage
+case wxChoicebook_GetPage: { // wxChoicebook::GetPage
wxChoicebook *This = (wxChoicebook *) getPtr(bp,memenv); bp += 4;
int * n = (int *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
wxWindow * Result = (wxWindow*)This->GetPage((size_t) *n);
rt.addRef(getRef((void *)Result,memenv), "wxWindow");
- break;
+ break;
}
-case wxChoicebook_GetPageCount: { // wxChoicebook::GetPageCount
+case wxChoicebook_GetPageCount: { // wxChoicebook::GetPageCount
wxChoicebook *This = (wxChoicebook *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
size_t Result = This->GetPageCount();
rt.addInt(Result);
- break;
+ break;
}
-case wxChoicebook_GetPageImage: { // wxChoicebook::GetPageImage
+case wxChoicebook_GetPageImage: { // wxChoicebook::GetPageImage
wxChoicebook *This = (wxChoicebook *) getPtr(bp,memenv); bp += 4;
int * n = (int *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
int Result = This->GetPageImage((size_t) *n);
rt.addInt(Result);
- break;
+ break;
}
-case wxChoicebook_GetPageText: { // wxChoicebook::GetPageText
+case wxChoicebook_GetPageText: { // wxChoicebook::GetPageText
wxChoicebook *This = (wxChoicebook *) getPtr(bp,memenv); bp += 4;
int * n = (int *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
wxString Result = This->GetPageText((size_t) *n);
rt.add(Result);
- break;
+ break;
}
-case wxChoicebook_GetSelection: { // wxChoicebook::GetSelection
+case wxChoicebook_GetSelection: { // wxChoicebook::GetSelection
wxChoicebook *This = (wxChoicebook *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
int Result = This->GetSelection();
rt.addInt(Result);
- break;
+ break;
}
-case wxChoicebook_HitTest: { // wxChoicebook::HitTest
+case wxChoicebook_HitTest: { // wxChoicebook::HitTest
long flags;
wxChoicebook *This = (wxChoicebook *) getPtr(bp,memenv); bp += 4;
int * ptX = (int *) bp; bp += 4;
@@ -17391,9 +17398,9 @@ case wxChoicebook_HitTest: { // wxChoicebook::HitTest
rt.addInt(Result);
rt.addInt(flags);
rt.addTupleCount(2);
- break;
+ break;
}
-case wxChoicebook_InsertPage: { // wxChoicebook::InsertPage
+case wxChoicebook_InsertPage: { // wxChoicebook::InsertPage
bool bSelect=false;
int imageId=-1;
wxChoicebook *This = (wxChoicebook *) getPtr(bp,memenv); bp += 4;
@@ -17402,45 +17409,45 @@ case wxChoicebook_InsertPage: { // wxChoicebook::InsertPage
int * textLen = (int *) bp; bp += 4;
wxString text = wxString(bp, wxConvUTF8);
bp += *textLen+((8-((0+ *textLen) & 7)) & 7);
- while( * (int*) bp) { switch (* (int*) bp) {
+ while( * (int*) bp) { switch (* (int*) bp) {
case 1: {bp += 4;
bSelect = *(bool *) bp; bp += 4;
} break;
case 2: {bp += 4;
imageId = (int)*(int *) bp; bp += 4;
} break;
- }};
+ }};
if(!This) throw wxe_badarg(0);
bool Result = This->InsertPage((size_t) *n,page,text,bSelect,imageId);
rt.addBool(Result);
- break;
+ break;
}
-case wxChoicebook_SetImageList: { // wxChoicebook::SetImageList
+case wxChoicebook_SetImageList: { // wxChoicebook::SetImageList
wxChoicebook *This = (wxChoicebook *) getPtr(bp,memenv); bp += 4;
wxImageList *imageList = (wxImageList *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
This->SetImageList(imageList);
- break;
+ break;
}
-case wxChoicebook_SetPageSize: { // wxChoicebook::SetPageSize
+case wxChoicebook_SetPageSize: { // wxChoicebook::SetPageSize
wxChoicebook *This = (wxChoicebook *) getPtr(bp,memenv); bp += 4;
int * sizeW = (int *) bp; bp += 4;
int * sizeH = (int *) bp; bp += 4;
wxSize size = wxSize(*sizeW,*sizeH);
if(!This) throw wxe_badarg(0);
This->SetPageSize(size);
- break;
+ break;
}
-case wxChoicebook_SetPageImage: { // wxChoicebook::SetPageImage
+case wxChoicebook_SetPageImage: { // wxChoicebook::SetPageImage
wxChoicebook *This = (wxChoicebook *) getPtr(bp,memenv); bp += 4;
int * n = (int *) bp; bp += 4;
int * imageId = (int *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
bool Result = This->SetPageImage((size_t) *n,(int) *imageId);
rt.addBool(Result);
- break;
+ break;
}
-case wxChoicebook_SetPageText: { // wxChoicebook::SetPageText
+case wxChoicebook_SetPageText: { // wxChoicebook::SetPageText
wxChoicebook *This = (wxChoicebook *) getPtr(bp,memenv); bp += 4;
int * n = (int *) bp; bp += 4;
int * strTextLen = (int *) bp; bp += 4;
@@ -17449,37 +17456,37 @@ case wxChoicebook_SetPageText: { // wxChoicebook::SetPageText
if(!This) throw wxe_badarg(0);
bool Result = This->SetPageText((size_t) *n,strText);
rt.addBool(Result);
- break;
+ break;
}
-case wxChoicebook_SetSelection: { // wxChoicebook::SetSelection
+case wxChoicebook_SetSelection: { // wxChoicebook::SetSelection
wxChoicebook *This = (wxChoicebook *) getPtr(bp,memenv); bp += 4;
int * n = (int *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
int Result = This->SetSelection((size_t) *n);
rt.addInt(Result);
- break;
+ break;
}
-case wxChoicebook_ChangeSelection: { // wxChoicebook::ChangeSelection
+case wxChoicebook_ChangeSelection: { // wxChoicebook::ChangeSelection
wxChoicebook *This = (wxChoicebook *) getPtr(bp,memenv); bp += 4;
int * n = (int *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
int Result = This->ChangeSelection((size_t) *n);
rt.addInt(Result);
- break;
+ break;
}
-case wxToolbook_new_0: { // wxToolbook::wxToolbook
+case wxToolbook_new_0: { // wxToolbook::wxToolbook
wxToolbook * Result = new EwxToolbook();
newPtr((void *) Result, 0, memenv);
rt.addRef(getRef((void *)Result,memenv), "wxToolbook");
- break;
+ break;
}
-case wxToolbook_new_3: { // wxToolbook::wxToolbook
+case wxToolbook_new_3: { // wxToolbook::wxToolbook
wxPoint pos= wxDefaultPosition;
wxSize size= wxDefaultSize;
long style=0;
wxWindow *parent = (wxWindow *) getPtr(bp,memenv); bp += 4;
int * id = (int *) bp; bp += 4;
- while( * (int*) bp) { switch (* (int*) bp) {
+ while( * (int*) bp) { switch (* (int*) bp) {
case 1: {bp += 4;
int * posX = (int *) bp; bp += 4;
int * posY = (int *) bp; bp += 4;
@@ -17495,13 +17502,13 @@ case wxToolbook_new_3: { // wxToolbook::wxToolbook
case 3: {bp += 4;
style = (long)*(int *) bp; bp += 4;
} break;
- }};
+ }};
wxToolbook * Result = new EwxToolbook(parent,(wxWindowID) *id,pos,size,style);
newPtr((void *) Result, 0, memenv);
rt.addRef(getRef((void *)Result,memenv), "wxToolbook");
- break;
+ break;
}
-case wxToolbook_AddPage: { // wxToolbook::AddPage
+case wxToolbook_AddPage: { // wxToolbook::AddPage
bool bSelect=false;
int imageId=-1;
wxToolbook *This = (wxToolbook *) getPtr(bp,memenv); bp += 4;
@@ -17509,40 +17516,40 @@ case wxToolbook_AddPage: { // wxToolbook::AddPage
int * textLen = (int *) bp; bp += 4;
wxString text = wxString(bp, wxConvUTF8);
bp += *textLen+((8-((4+ *textLen) & 7)) & 7);
- while( * (int*) bp) { switch (* (int*) bp) {
+ while( * (int*) bp) { switch (* (int*) bp) {
case 1: {bp += 4;
bSelect = *(bool *) bp; bp += 4;
} break;
case 2: {bp += 4;
imageId = (int)*(int *) bp; bp += 4;
} break;
- }};
+ }};
if(!This) throw wxe_badarg(0);
bool Result = This->AddPage(page,text,bSelect,imageId);
rt.addBool(Result);
- break;
+ break;
}
-case wxToolbook_AdvanceSelection: { // wxToolbook::AdvanceSelection
+case wxToolbook_AdvanceSelection: { // wxToolbook::AdvanceSelection
bool forward=true;
wxToolbook *This = (wxToolbook *) getPtr(bp,memenv); bp += 4;
bp += 4; /* Align */
- while( * (int*) bp) { switch (* (int*) bp) {
+ while( * (int*) bp) { switch (* (int*) bp) {
case 1: {bp += 4;
forward = *(bool *) bp; bp += 4;
} break;
- }};
+ }};
if(!This) throw wxe_badarg(0);
This->AdvanceSelection(forward);
- break;
+ break;
}
-case wxToolbook_AssignImageList: { // wxToolbook::AssignImageList
+case wxToolbook_AssignImageList: { // wxToolbook::AssignImageList
wxToolbook *This = (wxToolbook *) getPtr(bp,memenv); bp += 4;
wxImageList *imageList = (wxImageList *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
This->AssignImageList(imageList);
- break;
+ break;
}
-case wxToolbook_Create: { // wxToolbook::Create
+case wxToolbook_Create: { // wxToolbook::Create
wxPoint pos= wxDefaultPosition;
wxSize size= wxDefaultSize;
long style=0;
@@ -17550,7 +17557,7 @@ case wxToolbook_Create: { // wxToolbook::Create
wxWindow *parent = (wxWindow *) getPtr(bp,memenv); bp += 4;
int * id = (int *) bp; bp += 4;
bp += 4; /* Align */
- while( * (int*) bp) { switch (* (int*) bp) {
+ while( * (int*) bp) { switch (* (int*) bp) {
case 1: {bp += 4;
int * posX = (int *) bp; bp += 4;
int * posY = (int *) bp; bp += 4;
@@ -17566,88 +17573,88 @@ case wxToolbook_Create: { // wxToolbook::Create
case 3: {bp += 4;
style = (long)*(int *) bp; bp += 4;
} break;
- }};
+ }};
if(!This) throw wxe_badarg(0);
bool Result = This->Create(parent,(wxWindowID) *id,pos,size,style);
rt.addBool(Result);
- break;
+ break;
}
-case wxToolbook_DeleteAllPages: { // wxToolbook::DeleteAllPages
+case wxToolbook_DeleteAllPages: { // wxToolbook::DeleteAllPages
wxToolbook *This = (wxToolbook *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
bool Result = This->DeleteAllPages();
rt.addBool(Result);
- break;
+ break;
}
-case wxToolbook_DeletePage: { // wxToolbook::DeletePage
+case wxToolbook_DeletePage: { // wxToolbook::DeletePage
wxToolbook *This = (wxToolbook *) getPtr(bp,memenv); bp += 4;
int * n = (int *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
bool Result = This->DeletePage((size_t) *n);
rt.addBool(Result);
- break;
+ break;
}
-case wxToolbook_RemovePage: { // wxToolbook::RemovePage
+case wxToolbook_RemovePage: { // wxToolbook::RemovePage
wxToolbook *This = (wxToolbook *) getPtr(bp,memenv); bp += 4;
int * n = (int *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
bool Result = This->RemovePage((size_t) *n);
rt.addBool(Result);
- break;
+ break;
}
-case wxToolbook_GetCurrentPage: { // wxToolbook::GetCurrentPage
+case wxToolbook_GetCurrentPage: { // wxToolbook::GetCurrentPage
wxToolbook *This = (wxToolbook *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
wxWindow * Result = (wxWindow*)This->GetCurrentPage();
rt.addRef(getRef((void *)Result,memenv), "wxWindow");
- break;
+ break;
}
-case wxToolbook_GetImageList: { // wxToolbook::GetImageList
+case wxToolbook_GetImageList: { // wxToolbook::GetImageList
wxToolbook *This = (wxToolbook *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
wxImageList * Result = (wxImageList*)This->GetImageList();
rt.addRef(getRef((void *)Result,memenv), "wxImageList");
- break;
+ break;
}
-case wxToolbook_GetPage: { // wxToolbook::GetPage
+case wxToolbook_GetPage: { // wxToolbook::GetPage
wxToolbook *This = (wxToolbook *) getPtr(bp,memenv); bp += 4;
int * n = (int *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
wxWindow * Result = (wxWindow*)This->GetPage((size_t) *n);
rt.addRef(getRef((void *)Result,memenv), "wxWindow");
- break;
+ break;
}
-case wxToolbook_GetPageCount: { // wxToolbook::GetPageCount
+case wxToolbook_GetPageCount: { // wxToolbook::GetPageCount
wxToolbook *This = (wxToolbook *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
size_t Result = This->GetPageCount();
rt.addInt(Result);
- break;
+ break;
}
-case wxToolbook_GetPageImage: { // wxToolbook::GetPageImage
+case wxToolbook_GetPageImage: { // wxToolbook::GetPageImage
wxToolbook *This = (wxToolbook *) getPtr(bp,memenv); bp += 4;
int * n = (int *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
int Result = This->GetPageImage((size_t) *n);
rt.addInt(Result);
- break;
+ break;
}
-case wxToolbook_GetPageText: { // wxToolbook::GetPageText
+case wxToolbook_GetPageText: { // wxToolbook::GetPageText
wxToolbook *This = (wxToolbook *) getPtr(bp,memenv); bp += 4;
int * n = (int *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
wxString Result = This->GetPageText((size_t) *n);
rt.add(Result);
- break;
+ break;
}
-case wxToolbook_GetSelection: { // wxToolbook::GetSelection
+case wxToolbook_GetSelection: { // wxToolbook::GetSelection
wxToolbook *This = (wxToolbook *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
int Result = This->GetSelection();
rt.addInt(Result);
- break;
+ break;
}
-case wxToolbook_HitTest: { // wxToolbook::HitTest
+case wxToolbook_HitTest: { // wxToolbook::HitTest
long flags;
wxToolbook *This = (wxToolbook *) getPtr(bp,memenv); bp += 4;
int * ptX = (int *) bp; bp += 4;
@@ -17658,9 +17665,9 @@ case wxToolbook_HitTest: { // wxToolbook::HitTest
rt.addInt(Result);
rt.addInt(flags);
rt.addTupleCount(2);
- break;
+ break;
}
-case wxToolbook_InsertPage: { // wxToolbook::InsertPage
+case wxToolbook_InsertPage: { // wxToolbook::InsertPage
bool bSelect=false;
int imageId=-1;
wxToolbook *This = (wxToolbook *) getPtr(bp,memenv); bp += 4;
@@ -17669,45 +17676,45 @@ case wxToolbook_InsertPage: { // wxToolbook::InsertPage
int * textLen = (int *) bp; bp += 4;
wxString text = wxString(bp, wxConvUTF8);
bp += *textLen+((8-((0+ *textLen) & 7)) & 7);
- while( * (int*) bp) { switch (* (int*) bp) {
+ while( * (int*) bp) { switch (* (int*) bp) {
case 1: {bp += 4;
bSelect = *(bool *) bp; bp += 4;
} break;
case 2: {bp += 4;
imageId = (int)*(int *) bp; bp += 4;
} break;
- }};
+ }};
if(!This) throw wxe_badarg(0);
bool Result = This->InsertPage((size_t) *n,page,text,bSelect,imageId);
rt.addBool(Result);
- break;
+ break;
}
-case wxToolbook_SetImageList: { // wxToolbook::SetImageList
+case wxToolbook_SetImageList: { // wxToolbook::SetImageList
wxToolbook *This = (wxToolbook *) getPtr(bp,memenv); bp += 4;
wxImageList *imageList = (wxImageList *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
This->SetImageList(imageList);
- break;
+ break;
}
-case wxToolbook_SetPageSize: { // wxToolbook::SetPageSize
+case wxToolbook_SetPageSize: { // wxToolbook::SetPageSize
wxToolbook *This = (wxToolbook *) getPtr(bp,memenv); bp += 4;
int * sizeW = (int *) bp; bp += 4;
int * sizeH = (int *) bp; bp += 4;
wxSize size = wxSize(*sizeW,*sizeH);
if(!This) throw wxe_badarg(0);
This->SetPageSize(size);
- break;
+ break;
}
-case wxToolbook_SetPageImage: { // wxToolbook::SetPageImage
+case wxToolbook_SetPageImage: { // wxToolbook::SetPageImage
wxToolbook *This = (wxToolbook *) getPtr(bp,memenv); bp += 4;
int * n = (int *) bp; bp += 4;
int * imageId = (int *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
bool Result = This->SetPageImage((size_t) *n,(int) *imageId);
rt.addBool(Result);
- break;
+ break;
}
-case wxToolbook_SetPageText: { // wxToolbook::SetPageText
+case wxToolbook_SetPageText: { // wxToolbook::SetPageText
wxToolbook *This = (wxToolbook *) getPtr(bp,memenv); bp += 4;
int * n = (int *) bp; bp += 4;
int * strTextLen = (int *) bp; bp += 4;
@@ -17716,37 +17723,37 @@ case wxToolbook_SetPageText: { // wxToolbook::SetPageText
if(!This) throw wxe_badarg(0);
bool Result = This->SetPageText((size_t) *n,strText);
rt.addBool(Result);
- break;
+ break;
}
-case wxToolbook_SetSelection: { // wxToolbook::SetSelection
+case wxToolbook_SetSelection: { // wxToolbook::SetSelection
wxToolbook *This = (wxToolbook *) getPtr(bp,memenv); bp += 4;
int * n = (int *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
int Result = This->SetSelection((size_t) *n);
rt.addInt(Result);
- break;
+ break;
}
-case wxToolbook_ChangeSelection: { // wxToolbook::ChangeSelection
+case wxToolbook_ChangeSelection: { // wxToolbook::ChangeSelection
wxToolbook *This = (wxToolbook *) getPtr(bp,memenv); bp += 4;
int * n = (int *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
int Result = This->ChangeSelection((size_t) *n);
rt.addInt(Result);
- break;
+ break;
}
-case wxListbook_new_0: { // wxListbook::wxListbook
+case wxListbook_new_0: { // wxListbook::wxListbook
wxListbook * Result = new EwxListbook();
newPtr((void *) Result, 0, memenv);
rt.addRef(getRef((void *)Result,memenv), "wxListbook");
- break;
+ break;
}
-case wxListbook_new_3: { // wxListbook::wxListbook
+case wxListbook_new_3: { // wxListbook::wxListbook
wxPoint pos= wxDefaultPosition;
wxSize size= wxDefaultSize;
long style=0;
wxWindow *parent = (wxWindow *) getPtr(bp,memenv); bp += 4;
int * id = (int *) bp; bp += 4;
- while( * (int*) bp) { switch (* (int*) bp) {
+ while( * (int*) bp) { switch (* (int*) bp) {
case 1: {bp += 4;
int * posX = (int *) bp; bp += 4;
int * posY = (int *) bp; bp += 4;
@@ -17762,13 +17769,13 @@ case wxListbook_new_3: { // wxListbook::wxListbook
case 3: {bp += 4;
style = (long)*(int *) bp; bp += 4;
} break;
- }};
+ }};
wxListbook * Result = new EwxListbook(parent,(wxWindowID) *id,pos,size,style);
newPtr((void *) Result, 0, memenv);
rt.addRef(getRef((void *)Result,memenv), "wxListbook");
- break;
+ break;
}
-case wxListbook_AddPage: { // wxListbook::AddPage
+case wxListbook_AddPage: { // wxListbook::AddPage
bool bSelect=false;
int imageId=-1;
wxListbook *This = (wxListbook *) getPtr(bp,memenv); bp += 4;
@@ -17776,40 +17783,40 @@ case wxListbook_AddPage: { // wxListbook::AddPage
int * textLen = (int *) bp; bp += 4;
wxString text = wxString(bp, wxConvUTF8);
bp += *textLen+((8-((4+ *textLen) & 7)) & 7);
- while( * (int*) bp) { switch (* (int*) bp) {
+ while( * (int*) bp) { switch (* (int*) bp) {
case 1: {bp += 4;
bSelect = *(bool *) bp; bp += 4;
} break;
case 2: {bp += 4;
imageId = (int)*(int *) bp; bp += 4;
} break;
- }};
+ }};
if(!This) throw wxe_badarg(0);
bool Result = This->AddPage(page,text,bSelect,imageId);
rt.addBool(Result);
- break;
+ break;
}
-case wxListbook_AdvanceSelection: { // wxListbook::AdvanceSelection
+case wxListbook_AdvanceSelection: { // wxListbook::AdvanceSelection
bool forward=true;
wxListbook *This = (wxListbook *) getPtr(bp,memenv); bp += 4;
bp += 4; /* Align */
- while( * (int*) bp) { switch (* (int*) bp) {
+ while( * (int*) bp) { switch (* (int*) bp) {
case 1: {bp += 4;
forward = *(bool *) bp; bp += 4;
} break;
- }};
+ }};
if(!This) throw wxe_badarg(0);
This->AdvanceSelection(forward);
- break;
+ break;
}
-case wxListbook_AssignImageList: { // wxListbook::AssignImageList
+case wxListbook_AssignImageList: { // wxListbook::AssignImageList
wxListbook *This = (wxListbook *) getPtr(bp,memenv); bp += 4;
wxImageList *imageList = (wxImageList *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
This->AssignImageList(imageList);
- break;
+ break;
}
-case wxListbook_Create: { // wxListbook::Create
+case wxListbook_Create: { // wxListbook::Create
wxPoint pos= wxDefaultPosition;
wxSize size= wxDefaultSize;
long style=0;
@@ -17817,7 +17824,7 @@ case wxListbook_Create: { // wxListbook::Create
wxWindow *parent = (wxWindow *) getPtr(bp,memenv); bp += 4;
int * id = (int *) bp; bp += 4;
bp += 4; /* Align */
- while( * (int*) bp) { switch (* (int*) bp) {
+ while( * (int*) bp) { switch (* (int*) bp) {
case 1: {bp += 4;
int * posX = (int *) bp; bp += 4;
int * posY = (int *) bp; bp += 4;
@@ -17833,88 +17840,88 @@ case wxListbook_Create: { // wxListbook::Create
case 3: {bp += 4;
style = (long)*(int *) bp; bp += 4;
} break;
- }};
+ }};
if(!This) throw wxe_badarg(0);
bool Result = This->Create(parent,(wxWindowID) *id,pos,size,style);
rt.addBool(Result);
- break;
+ break;
}
-case wxListbook_DeleteAllPages: { // wxListbook::DeleteAllPages
+case wxListbook_DeleteAllPages: { // wxListbook::DeleteAllPages
wxListbook *This = (wxListbook *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
bool Result = This->DeleteAllPages();
rt.addBool(Result);
- break;
+ break;
}
-case wxListbook_DeletePage: { // wxListbook::DeletePage
+case wxListbook_DeletePage: { // wxListbook::DeletePage
wxListbook *This = (wxListbook *) getPtr(bp,memenv); bp += 4;
int * n = (int *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
bool Result = This->DeletePage((size_t) *n);
rt.addBool(Result);
- break;
+ break;
}
-case wxListbook_RemovePage: { // wxListbook::RemovePage
+case wxListbook_RemovePage: { // wxListbook::RemovePage
wxListbook *This = (wxListbook *) getPtr(bp,memenv); bp += 4;
int * n = (int *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
bool Result = This->RemovePage((size_t) *n);
rt.addBool(Result);
- break;
+ break;
}
-case wxListbook_GetCurrentPage: { // wxListbook::GetCurrentPage
+case wxListbook_GetCurrentPage: { // wxListbook::GetCurrentPage
wxListbook *This = (wxListbook *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
wxWindow * Result = (wxWindow*)This->GetCurrentPage();
rt.addRef(getRef((void *)Result,memenv), "wxWindow");
- break;
+ break;
}
-case wxListbook_GetImageList: { // wxListbook::GetImageList
+case wxListbook_GetImageList: { // wxListbook::GetImageList
wxListbook *This = (wxListbook *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
wxImageList * Result = (wxImageList*)This->GetImageList();
rt.addRef(getRef((void *)Result,memenv), "wxImageList");
- break;
+ break;
}
-case wxListbook_GetPage: { // wxListbook::GetPage
+case wxListbook_GetPage: { // wxListbook::GetPage
wxListbook *This = (wxListbook *) getPtr(bp,memenv); bp += 4;
int * n = (int *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
wxWindow * Result = (wxWindow*)This->GetPage((size_t) *n);
rt.addRef(getRef((void *)Result,memenv), "wxWindow");
- break;
+ break;
}
-case wxListbook_GetPageCount: { // wxListbook::GetPageCount
+case wxListbook_GetPageCount: { // wxListbook::GetPageCount
wxListbook *This = (wxListbook *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
size_t Result = This->GetPageCount();
rt.addInt(Result);
- break;
+ break;
}
-case wxListbook_GetPageImage: { // wxListbook::GetPageImage
+case wxListbook_GetPageImage: { // wxListbook::GetPageImage
wxListbook *This = (wxListbook *) getPtr(bp,memenv); bp += 4;
int * n = (int *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
int Result = This->GetPageImage((size_t) *n);
rt.addInt(Result);
- break;
+ break;
}
-case wxListbook_GetPageText: { // wxListbook::GetPageText
+case wxListbook_GetPageText: { // wxListbook::GetPageText
wxListbook *This = (wxListbook *) getPtr(bp,memenv); bp += 4;
int * n = (int *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
wxString Result = This->GetPageText((size_t) *n);
rt.add(Result);
- break;
+ break;
}
-case wxListbook_GetSelection: { // wxListbook::GetSelection
+case wxListbook_GetSelection: { // wxListbook::GetSelection
wxListbook *This = (wxListbook *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
int Result = This->GetSelection();
rt.addInt(Result);
- break;
+ break;
}
-case wxListbook_HitTest: { // wxListbook::HitTest
+case wxListbook_HitTest: { // wxListbook::HitTest
long flags;
wxListbook *This = (wxListbook *) getPtr(bp,memenv); bp += 4;
int * ptX = (int *) bp; bp += 4;
@@ -17925,9 +17932,9 @@ case wxListbook_HitTest: { // wxListbook::HitTest
rt.addInt(Result);
rt.addInt(flags);
rt.addTupleCount(2);
- break;
+ break;
}
-case wxListbook_InsertPage: { // wxListbook::InsertPage
+case wxListbook_InsertPage: { // wxListbook::InsertPage
bool bSelect=false;
int imageId=-1;
wxListbook *This = (wxListbook *) getPtr(bp,memenv); bp += 4;
@@ -17936,45 +17943,45 @@ case wxListbook_InsertPage: { // wxListbook::InsertPage
int * textLen = (int *) bp; bp += 4;
wxString text = wxString(bp, wxConvUTF8);
bp += *textLen+((8-((0+ *textLen) & 7)) & 7);
- while( * (int*) bp) { switch (* (int*) bp) {
+ while( * (int*) bp) { switch (* (int*) bp) {
case 1: {bp += 4;
bSelect = *(bool *) bp; bp += 4;
} break;
case 2: {bp += 4;
imageId = (int)*(int *) bp; bp += 4;
} break;
- }};
+ }};
if(!This) throw wxe_badarg(0);
bool Result = This->InsertPage((size_t) *n,page,text,bSelect,imageId);
rt.addBool(Result);
- break;
+ break;
}
-case wxListbook_SetImageList: { // wxListbook::SetImageList
+case wxListbook_SetImageList: { // wxListbook::SetImageList
wxListbook *This = (wxListbook *) getPtr(bp,memenv); bp += 4;
wxImageList *imageList = (wxImageList *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
This->SetImageList(imageList);
- break;
+ break;
}
-case wxListbook_SetPageSize: { // wxListbook::SetPageSize
+case wxListbook_SetPageSize: { // wxListbook::SetPageSize
wxListbook *This = (wxListbook *) getPtr(bp,memenv); bp += 4;
int * sizeW = (int *) bp; bp += 4;
int * sizeH = (int *) bp; bp += 4;
wxSize size = wxSize(*sizeW,*sizeH);
if(!This) throw wxe_badarg(0);
This->SetPageSize(size);
- break;
+ break;
}
-case wxListbook_SetPageImage: { // wxListbook::SetPageImage
+case wxListbook_SetPageImage: { // wxListbook::SetPageImage
wxListbook *This = (wxListbook *) getPtr(bp,memenv); bp += 4;
int * n = (int *) bp; bp += 4;
int * imageId = (int *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
bool Result = This->SetPageImage((size_t) *n,(int) *imageId);
rt.addBool(Result);
- break;
+ break;
}
-case wxListbook_SetPageText: { // wxListbook::SetPageText
+case wxListbook_SetPageText: { // wxListbook::SetPageText
wxListbook *This = (wxListbook *) getPtr(bp,memenv); bp += 4;
int * n = (int *) bp; bp += 4;
int * strTextLen = (int *) bp; bp += 4;
@@ -17983,37 +17990,37 @@ case wxListbook_SetPageText: { // wxListbook::SetPageText
if(!This) throw wxe_badarg(0);
bool Result = This->SetPageText((size_t) *n,strText);
rt.addBool(Result);
- break;
+ break;
}
-case wxListbook_SetSelection: { // wxListbook::SetSelection
+case wxListbook_SetSelection: { // wxListbook::SetSelection
wxListbook *This = (wxListbook *) getPtr(bp,memenv); bp += 4;
int * n = (int *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
int Result = This->SetSelection((size_t) *n);
rt.addInt(Result);
- break;
+ break;
}
-case wxListbook_ChangeSelection: { // wxListbook::ChangeSelection
+case wxListbook_ChangeSelection: { // wxListbook::ChangeSelection
wxListbook *This = (wxListbook *) getPtr(bp,memenv); bp += 4;
int * n = (int *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
int Result = This->ChangeSelection((size_t) *n);
rt.addInt(Result);
- break;
+ break;
}
-case wxTreebook_new_0: { // wxTreebook::wxTreebook
+case wxTreebook_new_0: { // wxTreebook::wxTreebook
wxTreebook * Result = new EwxTreebook();
newPtr((void *) Result, 0, memenv);
rt.addRef(getRef((void *)Result,memenv), "wxTreebook");
- break;
+ break;
}
-case wxTreebook_new_3: { // wxTreebook::wxTreebook
+case wxTreebook_new_3: { // wxTreebook::wxTreebook
wxPoint pos= wxDefaultPosition;
wxSize size= wxDefaultSize;
long style=wxBK_DEFAULT;
wxWindow *parent = (wxWindow *) getPtr(bp,memenv); bp += 4;
int * id = (int *) bp; bp += 4;
- while( * (int*) bp) { switch (* (int*) bp) {
+ while( * (int*) bp) { switch (* (int*) bp) {
case 1: {bp += 4;
int * posX = (int *) bp; bp += 4;
int * posY = (int *) bp; bp += 4;
@@ -18029,13 +18036,13 @@ case wxTreebook_new_3: { // wxTreebook::wxTreebook
case 3: {bp += 4;
style = (long)*(int *) bp; bp += 4;
} break;
- }};
+ }};
wxTreebook * Result = new EwxTreebook(parent,(wxWindowID) *id,pos,size,style);
newPtr((void *) Result, 0, memenv);
rt.addRef(getRef((void *)Result,memenv), "wxTreebook");
- break;
+ break;
}
-case wxTreebook_AddPage: { // wxTreebook::AddPage
+case wxTreebook_AddPage: { // wxTreebook::AddPage
bool bSelect=false;
int imageId=wxNOT_FOUND;
wxTreebook *This = (wxTreebook *) getPtr(bp,memenv); bp += 4;
@@ -18043,40 +18050,40 @@ case wxTreebook_AddPage: { // wxTreebook::AddPage
int * textLen = (int *) bp; bp += 4;
wxString text = wxString(bp, wxConvUTF8);
bp += *textLen+((8-((4+ *textLen) & 7)) & 7);
- while( * (int*) bp) { switch (* (int*) bp) {
+ while( * (int*) bp) { switch (* (int*) bp) {
case 1: {bp += 4;
bSelect = *(bool *) bp; bp += 4;
} break;
case 2: {bp += 4;
imageId = (int)*(int *) bp; bp += 4;
} break;
- }};
+ }};
if(!This) throw wxe_badarg(0);
bool Result = This->AddPage(page,text,bSelect,imageId);
rt.addBool(Result);
- break;
+ break;
}
-case wxTreebook_AdvanceSelection: { // wxTreebook::AdvanceSelection
+case wxTreebook_AdvanceSelection: { // wxTreebook::AdvanceSelection
bool forward=true;
wxTreebook *This = (wxTreebook *) getPtr(bp,memenv); bp += 4;
bp += 4; /* Align */
- while( * (int*) bp) { switch (* (int*) bp) {
+ while( * (int*) bp) { switch (* (int*) bp) {
case 1: {bp += 4;
forward = *(bool *) bp; bp += 4;
} break;
- }};
+ }};
if(!This) throw wxe_badarg(0);
This->AdvanceSelection(forward);
- break;
+ break;
}
-case wxTreebook_AssignImageList: { // wxTreebook::AssignImageList
+case wxTreebook_AssignImageList: { // wxTreebook::AssignImageList
wxTreebook *This = (wxTreebook *) getPtr(bp,memenv); bp += 4;
wxImageList *imageList = (wxImageList *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
This->AssignImageList(imageList);
- break;
+ break;
}
-case wxTreebook_Create: { // wxTreebook::Create
+case wxTreebook_Create: { // wxTreebook::Create
wxPoint pos= wxDefaultPosition;
wxSize size= wxDefaultSize;
long style=wxBK_DEFAULT;
@@ -18084,7 +18091,7 @@ case wxTreebook_Create: { // wxTreebook::Create
wxWindow *parent = (wxWindow *) getPtr(bp,memenv); bp += 4;
int * id = (int *) bp; bp += 4;
bp += 4; /* Align */
- while( * (int*) bp) { switch (* (int*) bp) {
+ while( * (int*) bp) { switch (* (int*) bp) {
case 1: {bp += 4;
int * posX = (int *) bp; bp += 4;
int * posY = (int *) bp; bp += 4;
@@ -18100,110 +18107,110 @@ case wxTreebook_Create: { // wxTreebook::Create
case 3: {bp += 4;
style = (long)*(int *) bp; bp += 4;
} break;
- }};
+ }};
if(!This) throw wxe_badarg(0);
bool Result = This->Create(parent,(wxWindowID) *id,pos,size,style);
rt.addBool(Result);
- break;
+ break;
}
-case wxTreebook_DeleteAllPages: { // wxTreebook::DeleteAllPages
+case wxTreebook_DeleteAllPages: { // wxTreebook::DeleteAllPages
wxTreebook *This = (wxTreebook *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
bool Result = This->DeleteAllPages();
rt.addBool(Result);
- break;
+ break;
}
-case wxTreebook_DeletePage: { // wxTreebook::DeletePage
+case wxTreebook_DeletePage: { // wxTreebook::DeletePage
wxTreebook *This = (wxTreebook *) getPtr(bp,memenv); bp += 4;
int * pos = (int *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
bool Result = This->DeletePage((size_t) *pos);
rt.addBool(Result);
- break;
+ break;
}
-case wxTreebook_RemovePage: { // wxTreebook::RemovePage
+case wxTreebook_RemovePage: { // wxTreebook::RemovePage
wxTreebook *This = (wxTreebook *) getPtr(bp,memenv); bp += 4;
int * n = (int *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
bool Result = This->RemovePage((size_t) *n);
rt.addBool(Result);
- break;
+ break;
}
-case wxTreebook_GetCurrentPage: { // wxTreebook::GetCurrentPage
+case wxTreebook_GetCurrentPage: { // wxTreebook::GetCurrentPage
wxTreebook *This = (wxTreebook *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
wxWindow * Result = (wxWindow*)This->GetCurrentPage();
rt.addRef(getRef((void *)Result,memenv), "wxWindow");
- break;
+ break;
}
-case wxTreebook_GetImageList: { // wxTreebook::GetImageList
+case wxTreebook_GetImageList: { // wxTreebook::GetImageList
wxTreebook *This = (wxTreebook *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
wxImageList * Result = (wxImageList*)This->GetImageList();
rt.addRef(getRef((void *)Result,memenv), "wxImageList");
- break;
+ break;
}
-case wxTreebook_GetPage: { // wxTreebook::GetPage
+case wxTreebook_GetPage: { // wxTreebook::GetPage
wxTreebook *This = (wxTreebook *) getPtr(bp,memenv); bp += 4;
int * n = (int *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
wxWindow * Result = (wxWindow*)This->GetPage((size_t) *n);
rt.addRef(getRef((void *)Result,memenv), "wxWindow");
- break;
+ break;
}
-case wxTreebook_GetPageCount: { // wxTreebook::GetPageCount
+case wxTreebook_GetPageCount: { // wxTreebook::GetPageCount
wxTreebook *This = (wxTreebook *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
size_t Result = This->GetPageCount();
rt.addInt(Result);
- break;
+ break;
}
-case wxTreebook_GetPageImage: { // wxTreebook::GetPageImage
+case wxTreebook_GetPageImage: { // wxTreebook::GetPageImage
wxTreebook *This = (wxTreebook *) getPtr(bp,memenv); bp += 4;
int * n = (int *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
int Result = This->GetPageImage((size_t) *n);
rt.addInt(Result);
- break;
+ break;
}
-case wxTreebook_GetPageText: { // wxTreebook::GetPageText
+case wxTreebook_GetPageText: { // wxTreebook::GetPageText
wxTreebook *This = (wxTreebook *) getPtr(bp,memenv); bp += 4;
int * n = (int *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
wxString Result = This->GetPageText((size_t) *n);
rt.add(Result);
- break;
+ break;
}
-case wxTreebook_GetSelection: { // wxTreebook::GetSelection
+case wxTreebook_GetSelection: { // wxTreebook::GetSelection
wxTreebook *This = (wxTreebook *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
int Result = This->GetSelection();
rt.addInt(Result);
- break;
+ break;
}
-case wxTreebook_ExpandNode: { // wxTreebook::ExpandNode
+case wxTreebook_ExpandNode: { // wxTreebook::ExpandNode
bool expand=true;
wxTreebook *This = (wxTreebook *) getPtr(bp,memenv); bp += 4;
int * pos = (int *) bp; bp += 4;
- while( * (int*) bp) { switch (* (int*) bp) {
+ while( * (int*) bp) { switch (* (int*) bp) {
case 1: {bp += 4;
expand = *(bool *) bp; bp += 4;
} break;
- }};
+ }};
if(!This) throw wxe_badarg(0);
bool Result = This->ExpandNode((size_t) *pos,expand);
rt.addBool(Result);
- break;
+ break;
}
-case wxTreebook_IsNodeExpanded: { // wxTreebook::IsNodeExpanded
+case wxTreebook_IsNodeExpanded: { // wxTreebook::IsNodeExpanded
wxTreebook *This = (wxTreebook *) getPtr(bp,memenv); bp += 4;
int * pos = (int *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
bool Result = This->IsNodeExpanded((size_t) *pos);
rt.addBool(Result);
- break;
+ break;
}
-case wxTreebook_HitTest: { // wxTreebook::HitTest
+case wxTreebook_HitTest: { // wxTreebook::HitTest
long flags;
wxTreebook *This = (wxTreebook *) getPtr(bp,memenv); bp += 4;
int * ptX = (int *) bp; bp += 4;
@@ -18214,9 +18221,9 @@ case wxTreebook_HitTest: { // wxTreebook::HitTest
rt.addInt(Result);
rt.addInt(flags);
rt.addTupleCount(2);
- break;
+ break;
}
-case wxTreebook_InsertPage: { // wxTreebook::InsertPage
+case wxTreebook_InsertPage: { // wxTreebook::InsertPage
bool bSelect=false;
int imageId=wxNOT_FOUND;
wxTreebook *This = (wxTreebook *) getPtr(bp,memenv); bp += 4;
@@ -18225,20 +18232,20 @@ case wxTreebook_InsertPage: { // wxTreebook::InsertPage
int * textLen = (int *) bp; bp += 4;
wxString text = wxString(bp, wxConvUTF8);
bp += *textLen+((8-((0+ *textLen) & 7)) & 7);
- while( * (int*) bp) { switch (* (int*) bp) {
+ while( * (int*) bp) { switch (* (int*) bp) {
case 1: {bp += 4;
bSelect = *(bool *) bp; bp += 4;
} break;
case 2: {bp += 4;
imageId = (int)*(int *) bp; bp += 4;
} break;
- }};
+ }};
if(!This) throw wxe_badarg(0);
bool Result = This->InsertPage((size_t) *pos,page,text,bSelect,imageId);
rt.addBool(Result);
- break;
+ break;
}
-case wxTreebook_InsertSubPage: { // wxTreebook::InsertSubPage
+case wxTreebook_InsertSubPage: { // wxTreebook::InsertSubPage
bool bSelect=false;
int imageId=wxNOT_FOUND;
wxTreebook *This = (wxTreebook *) getPtr(bp,memenv); bp += 4;
@@ -18247,45 +18254,45 @@ case wxTreebook_InsertSubPage: { // wxTreebook::InsertSubPage
int * textLen = (int *) bp; bp += 4;
wxString text = wxString(bp, wxConvUTF8);
bp += *textLen+((8-((0+ *textLen) & 7)) & 7);
- while( * (int*) bp) { switch (* (int*) bp) {
+ while( * (int*) bp) { switch (* (int*) bp) {
case 1: {bp += 4;
bSelect = *(bool *) bp; bp += 4;
} break;
case 2: {bp += 4;
imageId = (int)*(int *) bp; bp += 4;
} break;
- }};
+ }};
if(!This) throw wxe_badarg(0);
bool Result = This->InsertSubPage((size_t) *pos,page,text,bSelect,imageId);
rt.addBool(Result);
- break;
+ break;
}
-case wxTreebook_SetImageList: { // wxTreebook::SetImageList
+case wxTreebook_SetImageList: { // wxTreebook::SetImageList
wxTreebook *This = (wxTreebook *) getPtr(bp,memenv); bp += 4;
wxImageList *imageList = (wxImageList *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
This->SetImageList(imageList);
- break;
+ break;
}
-case wxTreebook_SetPageSize: { // wxTreebook::SetPageSize
+case wxTreebook_SetPageSize: { // wxTreebook::SetPageSize
wxTreebook *This = (wxTreebook *) getPtr(bp,memenv); bp += 4;
int * sizeW = (int *) bp; bp += 4;
int * sizeH = (int *) bp; bp += 4;
wxSize size = wxSize(*sizeW,*sizeH);
if(!This) throw wxe_badarg(0);
This->SetPageSize(size);
- break;
+ break;
}
-case wxTreebook_SetPageImage: { // wxTreebook::SetPageImage
+case wxTreebook_SetPageImage: { // wxTreebook::SetPageImage
wxTreebook *This = (wxTreebook *) getPtr(bp,memenv); bp += 4;
int * n = (int *) bp; bp += 4;
int * imageId = (int *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
bool Result = This->SetPageImage((size_t) *n,(int) *imageId);
rt.addBool(Result);
- break;
+ break;
}
-case wxTreebook_SetPageText: { // wxTreebook::SetPageText
+case wxTreebook_SetPageText: { // wxTreebook::SetPageText
wxTreebook *This = (wxTreebook *) getPtr(bp,memenv); bp += 4;
int * n = (int *) bp; bp += 4;
int * strTextLen = (int *) bp; bp += 4;
@@ -18294,25 +18301,25 @@ case wxTreebook_SetPageText: { // wxTreebook::SetPageText
if(!This) throw wxe_badarg(0);
bool Result = This->SetPageText((size_t) *n,strText);
rt.addBool(Result);
- break;
+ break;
}
-case wxTreebook_SetSelection: { // wxTreebook::SetSelection
+case wxTreebook_SetSelection: { // wxTreebook::SetSelection
wxTreebook *This = (wxTreebook *) getPtr(bp,memenv); bp += 4;
int * n = (int *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
int Result = This->SetSelection((size_t) *n);
rt.addInt(Result);
- break;
+ break;
}
-case wxTreebook_ChangeSelection: { // wxTreebook::ChangeSelection
+case wxTreebook_ChangeSelection: { // wxTreebook::ChangeSelection
wxTreebook *This = (wxTreebook *) getPtr(bp,memenv); bp += 4;
int * n = (int *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
int Result = This->ChangeSelection((size_t) *n);
rt.addInt(Result);
- break;
+ break;
}
-case wxTreeCtrl_new_2: { // wxTreeCtrl::wxTreeCtrl
+case wxTreeCtrl_new_2: { // wxTreeCtrl::wxTreeCtrl
wxWindowID id=wxID_ANY;
wxPoint pos= wxDefaultPosition;
wxSize size= wxDefaultSize;
@@ -18320,7 +18327,7 @@ case wxTreeCtrl_new_2: { // wxTreeCtrl::wxTreeCtrl
const wxValidator * validator= &wxDefaultValidator;
wxWindow *parent = (wxWindow *) getPtr(bp,memenv); bp += 4;
bp += 4; /* Align */
- while( * (int*) bp) { switch (* (int*) bp) {
+ while( * (int*) bp) { switch (* (int*) bp) {
case 1: {bp += 4;
id = (wxWindowID)*(int *) bp; bp += 4;
} break;
@@ -18342,19 +18349,19 @@ case wxTreeCtrl_new_2: { // wxTreeCtrl::wxTreeCtrl
case 5: {bp += 4;
validator = (wxValidator *) getPtr(bp,memenv); bp += 4;
} break;
- }};
+ }};
wxTreeCtrl * Result = new EwxTreeCtrl(parent,id,pos,size,style,*validator);
newPtr((void *) Result, 0, memenv);
rt.addRef(getRef((void *)Result,memenv), "wxTreeCtrl");
- break;
+ break;
}
-case wxTreeCtrl_new_0: { // wxTreeCtrl::wxTreeCtrl
+case wxTreeCtrl_new_0: { // wxTreeCtrl::wxTreeCtrl
wxTreeCtrl * Result = new EwxTreeCtrl();
newPtr((void *) Result, 0, memenv);
rt.addRef(getRef((void *)Result,memenv), "wxTreeCtrl");
- break;
+ break;
}
-case wxTreeCtrl_AddRoot: { // wxTreeCtrl::AddRoot
+case wxTreeCtrl_AddRoot: { // wxTreeCtrl::AddRoot
int image=-1;
int selectedImage=-1;
wxETreeItemData * data= NULL;
@@ -18362,7 +18369,7 @@ case wxTreeCtrl_AddRoot: { // wxTreeCtrl::AddRoot
int * textLen = (int *) bp; bp += 4;
wxString text = wxString(bp, wxConvUTF8);
bp += *textLen+((8-((0+ *textLen) & 7)) & 7);
- while( * (int*) bp) { switch (* (int*) bp) {
+ while( * (int*) bp) { switch (* (int*) bp) {
case 1: {bp += 4;
image = (int)*(int *) bp; bp += 4;
} break;
@@ -18370,25 +18377,26 @@ case wxTreeCtrl_AddRoot: { // wxTreeCtrl::AddRoot
selectedImage = (int)*(int *) bp; bp += 4;
} break;
case 3: {bp += 4;
- data = new wxETreeItemData(Ecmd.bin[0]->size, Ecmd.bin[0]->base);
+ data = new wxETreeItemData(Ecmd.bin[0]->size, Ecmd.bin[0]->base);
bp += 4; /* Align */
} break;
- }};
+ }};
if(!This) throw wxe_badarg(0);
wxTreeItemId Result = This->AddRoot(text,image,selectedImage,data);
- rt.addRef(getRef((void *)Result.m_pItem,memenv), "wxTreeItemId");
- break;
+ rt.add((wxUIntPtr *) Result.m_pItem);
+ break;
}
-case wxTreeCtrl_AppendItem: { // wxTreeCtrl::AppendItem
+case wxTreeCtrl_AppendItem: { // wxTreeCtrl::AppendItem
int image=-1;
int selectedImage=-1;
wxETreeItemData * data= NULL;
wxTreeCtrl *This = (wxTreeCtrl *) getPtr(bp,memenv); bp += 4;
- wxTreeItemId parent = wxTreeItemId(getPtr(bp,memenv)); bp += 4;
+ bp += 4; /* Align */
+ wxTreeItemId parent = wxTreeItemId((void *) *(wxUint64 *) bp); bp += 8;
int * textLen = (int *) bp; bp += 4;
wxString text = wxString(bp, wxConvUTF8);
bp += *textLen+((8-((4+ *textLen) & 7)) & 7);
- while( * (int*) bp) { switch (* (int*) bp) {
+ while( * (int*) bp) { switch (* (int*) bp) {
case 1: {bp += 4;
image = (int)*(int *) bp; bp += 4;
} break;
@@ -18396,44 +18404,46 @@ case wxTreeCtrl_AppendItem: { // wxTreeCtrl::AppendItem
selectedImage = (int)*(int *) bp; bp += 4;
} break;
case 3: {bp += 4;
- data = new wxETreeItemData(Ecmd.bin[0]->size, Ecmd.bin[0]->base);
+ data = new wxETreeItemData(Ecmd.bin[0]->size, Ecmd.bin[0]->base);
bp += 4; /* Align */
} break;
- }};
+ }};
if(!This) throw wxe_badarg(0);
wxTreeItemId Result = This->AppendItem(parent,text,image,selectedImage,data);
- rt.addRef(getRef((void *)Result.m_pItem,memenv), "wxTreeItemId");
- break;
+ rt.add((wxUIntPtr *) Result.m_pItem);
+ break;
}
-case wxTreeCtrl_AssignImageList: { // wxTreeCtrl::AssignImageList
+case wxTreeCtrl_AssignImageList: { // wxTreeCtrl::AssignImageList
wxTreeCtrl *This = (wxTreeCtrl *) getPtr(bp,memenv); bp += 4;
wxImageList *imageList = (wxImageList *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
This->AssignImageList(imageList);
- break;
+ break;
}
-case wxTreeCtrl_AssignStateImageList: { // wxTreeCtrl::AssignStateImageList
+case wxTreeCtrl_AssignStateImageList: { // wxTreeCtrl::AssignStateImageList
wxTreeCtrl *This = (wxTreeCtrl *) getPtr(bp,memenv); bp += 4;
wxImageList *imageList = (wxImageList *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
This->AssignStateImageList(imageList);
- break;
+ break;
}
-case wxTreeCtrl_Collapse: { // wxTreeCtrl::Collapse
+case wxTreeCtrl_Collapse: { // wxTreeCtrl::Collapse
wxTreeCtrl *This = (wxTreeCtrl *) getPtr(bp,memenv); bp += 4;
- wxTreeItemId item = wxTreeItemId(getPtr(bp,memenv)); bp += 4;
+ bp += 4; /* Align */
+ wxTreeItemId item = wxTreeItemId((void *) *(wxUint64 *) bp); bp += 8;
if(!This) throw wxe_badarg(0);
This->Collapse(item);
- break;
+ break;
}
-case wxTreeCtrl_CollapseAndReset: { // wxTreeCtrl::CollapseAndReset
+case wxTreeCtrl_CollapseAndReset: { // wxTreeCtrl::CollapseAndReset
wxTreeCtrl *This = (wxTreeCtrl *) getPtr(bp,memenv); bp += 4;
- wxTreeItemId item = wxTreeItemId(getPtr(bp,memenv)); bp += 4;
+ bp += 4; /* Align */
+ wxTreeItemId item = wxTreeItemId((void *) *(wxUint64 *) bp); bp += 8;
if(!This) throw wxe_badarg(0);
This->CollapseAndReset(item);
- break;
+ break;
}
-case wxTreeCtrl_Create: { // wxTreeCtrl::Create
+case wxTreeCtrl_Create: { // wxTreeCtrl::Create
wxWindowID id=wxID_ANY;
wxPoint pos= wxDefaultPosition;
wxSize size= wxDefaultSize;
@@ -18441,7 +18451,7 @@ case wxTreeCtrl_Create: { // wxTreeCtrl::Create
const wxValidator * validator= &wxDefaultValidator;
wxTreeCtrl *This = (wxTreeCtrl *) getPtr(bp,memenv); bp += 4;
wxWindow *parent = (wxWindow *) getPtr(bp,memenv); bp += 4;
- while( * (int*) bp) { switch (* (int*) bp) {
+ while( * (int*) bp) { switch (* (int*) bp) {
case 1: {bp += 4;
id = (wxWindowID)*(int *) bp; bp += 4;
} break;
@@ -18463,305 +18473,322 @@ case wxTreeCtrl_Create: { // wxTreeCtrl::Create
case 5: {bp += 4;
validator = (wxValidator *) getPtr(bp,memenv); bp += 4;
} break;
- }};
+ }};
if(!This) throw wxe_badarg(0);
bool Result = This->Create(parent,id,pos,size,style,*validator);
rt.addBool(Result);
- break;
+ break;
}
-case wxTreeCtrl_Delete: { // wxTreeCtrl::Delete
+case wxTreeCtrl_Delete: { // wxTreeCtrl::Delete
wxTreeCtrl *This = (wxTreeCtrl *) getPtr(bp,memenv); bp += 4;
- wxTreeItemId item = wxTreeItemId(getPtr(bp,memenv)); bp += 4;
+ bp += 4; /* Align */
+ wxTreeItemId item = wxTreeItemId((void *) *(wxUint64 *) bp); bp += 8;
if(!This) throw wxe_badarg(0);
This->Delete(item);
- break;
+ break;
}
-case wxTreeCtrl_DeleteAllItems: { // wxTreeCtrl::DeleteAllItems
+case wxTreeCtrl_DeleteAllItems: { // wxTreeCtrl::DeleteAllItems
wxTreeCtrl *This = (wxTreeCtrl *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
This->DeleteAllItems();
- break;
+ break;
}
-case wxTreeCtrl_DeleteChildren: { // wxTreeCtrl::DeleteChildren
+case wxTreeCtrl_DeleteChildren: { // wxTreeCtrl::DeleteChildren
wxTreeCtrl *This = (wxTreeCtrl *) getPtr(bp,memenv); bp += 4;
- wxTreeItemId item = wxTreeItemId(getPtr(bp,memenv)); bp += 4;
+ bp += 4; /* Align */
+ wxTreeItemId item = wxTreeItemId((void *) *(wxUint64 *) bp); bp += 8;
if(!This) throw wxe_badarg(0);
This->DeleteChildren(item);
- break;
+ break;
}
-case wxTreeCtrl_EnsureVisible: { // wxTreeCtrl::EnsureVisible
+case wxTreeCtrl_EnsureVisible: { // wxTreeCtrl::EnsureVisible
wxTreeCtrl *This = (wxTreeCtrl *) getPtr(bp,memenv); bp += 4;
- wxTreeItemId item = wxTreeItemId(getPtr(bp,memenv)); bp += 4;
+ bp += 4; /* Align */
+ wxTreeItemId item = wxTreeItemId((void *) *(wxUint64 *) bp); bp += 8;
if(!This) throw wxe_badarg(0);
This->EnsureVisible(item);
- break;
+ break;
}
-case wxTreeCtrl_Expand: { // wxTreeCtrl::Expand
+case wxTreeCtrl_Expand: { // wxTreeCtrl::Expand
wxTreeCtrl *This = (wxTreeCtrl *) getPtr(bp,memenv); bp += 4;
- wxTreeItemId item = wxTreeItemId(getPtr(bp,memenv)); bp += 4;
+ bp += 4; /* Align */
+ wxTreeItemId item = wxTreeItemId((void *) *(wxUint64 *) bp); bp += 8;
if(!This) throw wxe_badarg(0);
This->Expand(item);
- break;
+ break;
}
-case wxTreeCtrl_GetBoundingRect: { // wxTreeCtrl::GetBoundingRect
+case wxTreeCtrl_GetBoundingRect: { // wxTreeCtrl::GetBoundingRect
bool textOnly=false;
wxTreeCtrl *This = (wxTreeCtrl *) getPtr(bp,memenv); bp += 4;
- wxTreeItemId item = wxTreeItemId(getPtr(bp,memenv)); bp += 4;
+ bp += 4; /* Align */
+ wxTreeItemId item = wxTreeItemId((void *) *(wxUint64 *) bp); bp += 8;
int * rectX = (int *) bp; bp += 4;
int * rectY = (int *) bp; bp += 4;
int * rectW = (int *) bp; bp += 4;
int * rectH = (int *) bp; bp += 4;
wxRect rect = wxRect(*rectX,*rectY,*rectW,*rectH);
- while( * (int*) bp) { switch (* (int*) bp) {
+ while( * (int*) bp) { switch (* (int*) bp) {
case 1: {bp += 4;
textOnly = *(bool *) bp; bp += 4;
} break;
- }};
+ }};
if(!This) throw wxe_badarg(0);
bool Result = This->GetBoundingRect(item,rect,textOnly);
rt.addBool(Result);
- break;
+ break;
}
-case wxTreeCtrl_GetChildrenCount: { // wxTreeCtrl::GetChildrenCount
+case wxTreeCtrl_GetChildrenCount: { // wxTreeCtrl::GetChildrenCount
bool recursively=true;
wxTreeCtrl *This = (wxTreeCtrl *) getPtr(bp,memenv); bp += 4;
- wxTreeItemId item = wxTreeItemId(getPtr(bp,memenv)); bp += 4;
- while( * (int*) bp) { switch (* (int*) bp) {
+ bp += 4; /* Align */
+ wxTreeItemId item = wxTreeItemId((void *) *(wxUint64 *) bp); bp += 8;
+ while( * (int*) bp) { switch (* (int*) bp) {
case 1: {bp += 4;
recursively = *(bool *) bp; bp += 4;
} break;
- }};
+ }};
if(!This) throw wxe_badarg(0);
size_t Result = This->GetChildrenCount(item,recursively);
rt.addInt(Result);
- break;
+ break;
}
-case wxTreeCtrl_GetCount: { // wxTreeCtrl::GetCount
+case wxTreeCtrl_GetCount: { // wxTreeCtrl::GetCount
wxTreeCtrl *This = (wxTreeCtrl *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
int Result = This->GetCount();
rt.addUint(Result);
- break;
+ break;
}
-case wxTreeCtrl_GetEditControl: { // wxTreeCtrl::GetEditControl
+case wxTreeCtrl_GetEditControl: { // wxTreeCtrl::GetEditControl
wxTreeCtrl *This = (wxTreeCtrl *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
wxTextCtrl * Result = (wxTextCtrl*)This->GetEditControl();
rt.addRef(getRef((void *)Result,memenv), "wxTextCtrl");
- break;
+ break;
+}
+case wxTreeCtrl_GetFirstChild: { // wxTreeCtrl::GetFirstChild
+ wxTreeItemIdValue cookie;
+ wxTreeCtrl *This = (wxTreeCtrl *) getPtr(bp,memenv); bp += 4;
+ bp += 4; /* Align */
+ wxTreeItemId item = wxTreeItemId((void *) *(wxUint64 *) bp); bp += 8;
+ if(!This) throw wxe_badarg(0);
+ wxTreeItemId Result = This->GetFirstChild(item,cookie);
+ rt.add((wxUIntPtr *) Result.m_pItem);
+ rt.add((wxUIntPtr *) cookie);
+ rt.addTupleCount(2);
+ break;
+}
+case wxTreeCtrl_GetNextChild: { // wxTreeCtrl::GetNextChild
+ wxTreeCtrl *This = (wxTreeCtrl *) getPtr(bp,memenv); bp += 4;
+ bp += 4; /* Align */
+ wxTreeItemId item = wxTreeItemId((void *) *(wxUint64 *) bp); bp += 8;
+ wxTreeItemIdValue cookie = (wxTreeItemIdValue) * (wxUint64 *) bp; bp += 8;
+ if(!This) throw wxe_badarg(0);
+ wxTreeItemId Result = This->GetNextChild(item,cookie);
+ rt.add((wxUIntPtr *) Result.m_pItem);
+ rt.add((wxUIntPtr *) cookie);
+ rt.addTupleCount(2);
+ break;
}
-case wxTreeCtrl_GetFirstVisibleItem: { // wxTreeCtrl::GetFirstVisibleItem
+case wxTreeCtrl_GetFirstVisibleItem: { // wxTreeCtrl::GetFirstVisibleItem
wxTreeCtrl *This = (wxTreeCtrl *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
wxTreeItemId Result = This->GetFirstVisibleItem();
- rt.addRef(getRef((void *)Result.m_pItem,memenv), "wxTreeItemId");
- break;
+ rt.add((wxUIntPtr *) Result.m_pItem);
+ break;
}
-case wxTreeCtrl_GetImageList: { // wxTreeCtrl::GetImageList
+case wxTreeCtrl_GetImageList: { // wxTreeCtrl::GetImageList
wxTreeCtrl *This = (wxTreeCtrl *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
wxImageList * Result = (wxImageList*)This->GetImageList();
rt.addRef(getRef((void *)Result,memenv), "wxImageList");
- break;
+ break;
}
-case wxTreeCtrl_GetIndent: { // wxTreeCtrl::GetIndent
+case wxTreeCtrl_GetIndent: { // wxTreeCtrl::GetIndent
wxTreeCtrl *This = (wxTreeCtrl *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
int Result = This->GetIndent();
rt.addUint(Result);
- break;
+ break;
}
-case wxTreeCtrl_GetItemBackgroundColour: { // wxTreeCtrl::GetItemBackgroundColour
+case wxTreeCtrl_GetItemBackgroundColour: { // wxTreeCtrl::GetItemBackgroundColour
wxTreeCtrl *This = (wxTreeCtrl *) getPtr(bp,memenv); bp += 4;
- wxTreeItemId item = wxTreeItemId(getPtr(bp,memenv)); bp += 4;
+ bp += 4; /* Align */
+ wxTreeItemId item = wxTreeItemId((void *) *(wxUint64 *) bp); bp += 8;
if(!This) throw wxe_badarg(0);
wxColour Result = This->GetItemBackgroundColour(item);
rt.add(Result);
- break;
+ break;
}
-case wxTreeCtrl_GetItemData: { // wxTreeCtrl::GetItemData
+case wxTreeCtrl_GetItemData: { // wxTreeCtrl::GetItemData
wxTreeCtrl *This = (wxTreeCtrl *) getPtr(bp,memenv); bp += 4;
- wxTreeItemId item = wxTreeItemId(getPtr(bp,memenv)); bp += 4;
+ bp += 4; /* Align */
+ wxTreeItemId item = wxTreeItemId((void *) *(wxUint64 *) bp); bp += 8;
if(!This) throw wxe_badarg(0);
wxETreeItemData * Result = (wxETreeItemData*)This->GetItemData(item);
rt.addExt2Term(Result);
- break;
+ break;
}
-case wxTreeCtrl_GetItemFont: { // wxTreeCtrl::GetItemFont
+case wxTreeCtrl_GetItemFont: { // wxTreeCtrl::GetItemFont
wxTreeCtrl *This = (wxTreeCtrl *) getPtr(bp,memenv); bp += 4;
- wxTreeItemId item = wxTreeItemId(getPtr(bp,memenv)); bp += 4;
+ bp += 4; /* Align */
+ wxTreeItemId item = wxTreeItemId((void *) *(wxUint64 *) bp); bp += 8;
if(!This) throw wxe_badarg(0);
wxFont * Result = new wxFont(This->GetItemFont(item)); newPtr((void *) Result,3, memenv);;
rt.addRef(getRef((void *)Result,memenv), "wxFont");
- break;
+ break;
}
-case wxTreeCtrl_GetItemImage_1: { // wxTreeCtrl::GetItemImage
+case wxTreeCtrl_GetItemImage_1: { // wxTreeCtrl::GetItemImage
wxTreeCtrl *This = (wxTreeCtrl *) getPtr(bp,memenv); bp += 4;
- wxTreeItemId item = wxTreeItemId(getPtr(bp,memenv)); bp += 4;
+ bp += 4; /* Align */
+ wxTreeItemId item = wxTreeItemId((void *) *(wxUint64 *) bp); bp += 8;
if(!This) throw wxe_badarg(0);
int Result = This->GetItemImage(item);
rt.addInt(Result);
- break;
+ break;
}
-case wxTreeCtrl_GetItemImage_2: { // wxTreeCtrl::GetItemImage
+case wxTreeCtrl_GetItemImage_2: { // wxTreeCtrl::GetItemImage
wxTreeItemIcon which=wxTreeItemIcon_Normal;
wxTreeCtrl *This = (wxTreeCtrl *) getPtr(bp,memenv); bp += 4;
- wxTreeItemId item = wxTreeItemId(getPtr(bp,memenv)); bp += 4;
- while( * (int*) bp) { switch (* (int*) bp) {
+ bp += 4; /* Align */
+ wxTreeItemId item = wxTreeItemId((void *) *(wxUint64 *) bp); bp += 8;
+ while( * (int*) bp) { switch (* (int*) bp) {
case 1: {bp += 4;
which = *(wxTreeItemIcon *) bp; bp += 4;;
} break;
- }};
+ }};
if(!This) throw wxe_badarg(0);
int Result = This->GetItemImage(item,(wxTreeItemIcon) which);
rt.addInt(Result);
- break;
+ break;
}
-case wxTreeCtrl_GetItemText: { // wxTreeCtrl::GetItemText
+case wxTreeCtrl_GetItemText: { // wxTreeCtrl::GetItemText
wxTreeCtrl *This = (wxTreeCtrl *) getPtr(bp,memenv); bp += 4;
- wxTreeItemId item = wxTreeItemId(getPtr(bp,memenv)); bp += 4;
+ bp += 4; /* Align */
+ wxTreeItemId item = wxTreeItemId((void *) *(wxUint64 *) bp); bp += 8;
if(!This) throw wxe_badarg(0);
wxString Result = This->GetItemText(item);
rt.add(Result);
- break;
+ break;
}
-case wxTreeCtrl_GetItemTextColour: { // wxTreeCtrl::GetItemTextColour
+case wxTreeCtrl_GetItemTextColour: { // wxTreeCtrl::GetItemTextColour
wxTreeCtrl *This = (wxTreeCtrl *) getPtr(bp,memenv); bp += 4;
- wxTreeItemId item = wxTreeItemId(getPtr(bp,memenv)); bp += 4;
+ bp += 4; /* Align */
+ wxTreeItemId item = wxTreeItemId((void *) *(wxUint64 *) bp); bp += 8;
if(!This) throw wxe_badarg(0);
wxColour Result = This->GetItemTextColour(item);
rt.add(Result);
- break;
+ break;
}
-case wxTreeCtrl_GetLastChild: { // wxTreeCtrl::GetLastChild
+case wxTreeCtrl_GetLastChild: { // wxTreeCtrl::GetLastChild
wxTreeCtrl *This = (wxTreeCtrl *) getPtr(bp,memenv); bp += 4;
- wxTreeItemId item = wxTreeItemId(getPtr(bp,memenv)); bp += 4;
+ bp += 4; /* Align */
+ wxTreeItemId item = wxTreeItemId((void *) *(wxUint64 *) bp); bp += 8;
if(!This) throw wxe_badarg(0);
wxTreeItemId Result = This->GetLastChild(item);
- rt.addRef(getRef((void *)Result.m_pItem,memenv), "wxTreeItemId");
- break;
+ rt.add((wxUIntPtr *) Result.m_pItem);
+ break;
}
-case wxTreeCtrl_GetNextSibling: { // wxTreeCtrl::GetNextSibling
+case wxTreeCtrl_GetNextSibling: { // wxTreeCtrl::GetNextSibling
wxTreeCtrl *This = (wxTreeCtrl *) getPtr(bp,memenv); bp += 4;
- wxTreeItemId item = wxTreeItemId(getPtr(bp,memenv)); bp += 4;
+ bp += 4; /* Align */
+ wxTreeItemId item = wxTreeItemId((void *) *(wxUint64 *) bp); bp += 8;
if(!This) throw wxe_badarg(0);
wxTreeItemId Result = This->GetNextSibling(item);
- rt.addRef(getRef((void *)Result.m_pItem,memenv), "wxTreeItemId");
- break;
+ rt.add((wxUIntPtr *) Result.m_pItem);
+ break;
}
-case wxTreeCtrl_GetNextVisible: { // wxTreeCtrl::GetNextVisible
+case wxTreeCtrl_GetNextVisible: { // wxTreeCtrl::GetNextVisible
wxTreeCtrl *This = (wxTreeCtrl *) getPtr(bp,memenv); bp += 4;
- wxTreeItemId item = wxTreeItemId(getPtr(bp,memenv)); bp += 4;
+ bp += 4; /* Align */
+ wxTreeItemId item = wxTreeItemId((void *) *(wxUint64 *) bp); bp += 8;
if(!This) throw wxe_badarg(0);
wxTreeItemId Result = This->GetNextVisible(item);
- rt.addRef(getRef((void *)Result.m_pItem,memenv), "wxTreeItemId");
- break;
+ rt.add((wxUIntPtr *) Result.m_pItem);
+ break;
}
-case wxTreeCtrl_GetItemParent: { // wxTreeCtrl::GetItemParent
+case wxTreeCtrl_GetItemParent: { // wxTreeCtrl::GetItemParent
wxTreeCtrl *This = (wxTreeCtrl *) getPtr(bp,memenv); bp += 4;
- wxTreeItemId item = wxTreeItemId(getPtr(bp,memenv)); bp += 4;
+ bp += 4; /* Align */
+ wxTreeItemId item = wxTreeItemId((void *) *(wxUint64 *) bp); bp += 8;
if(!This) throw wxe_badarg(0);
wxTreeItemId Result = This->GetItemParent(item);
- rt.addRef(getRef((void *)Result.m_pItem,memenv), "wxTreeItemId");
- break;
+ rt.add((wxUIntPtr *) Result.m_pItem);
+ break;
}
-case wxTreeCtrl_GetPrevSibling: { // wxTreeCtrl::GetPrevSibling
+case wxTreeCtrl_GetPrevSibling: { // wxTreeCtrl::GetPrevSibling
wxTreeCtrl *This = (wxTreeCtrl *) getPtr(bp,memenv); bp += 4;
- wxTreeItemId item = wxTreeItemId(getPtr(bp,memenv)); bp += 4;
+ bp += 4; /* Align */
+ wxTreeItemId item = wxTreeItemId((void *) *(wxUint64 *) bp); bp += 8;
if(!This) throw wxe_badarg(0);
wxTreeItemId Result = This->GetPrevSibling(item);
- rt.addRef(getRef((void *)Result.m_pItem,memenv), "wxTreeItemId");
- break;
+ rt.add((wxUIntPtr *) Result.m_pItem);
+ break;
}
-case wxTreeCtrl_GetPrevVisible: { // wxTreeCtrl::GetPrevVisible
+case wxTreeCtrl_GetPrevVisible: { // wxTreeCtrl::GetPrevVisible
wxTreeCtrl *This = (wxTreeCtrl *) getPtr(bp,memenv); bp += 4;
- wxTreeItemId item = wxTreeItemId(getPtr(bp,memenv)); bp += 4;
+ bp += 4; /* Align */
+ wxTreeItemId item = wxTreeItemId((void *) *(wxUint64 *) bp); bp += 8;
if(!This) throw wxe_badarg(0);
wxTreeItemId Result = This->GetPrevVisible(item);
- rt.addRef(getRef((void *)Result.m_pItem,memenv), "wxTreeItemId");
- break;
+ rt.add((wxUIntPtr *) Result.m_pItem);
+ break;
}
-case wxTreeCtrl_GetRootItem: { // wxTreeCtrl::GetRootItem
+case wxTreeCtrl_GetRootItem: { // wxTreeCtrl::GetRootItem
wxTreeCtrl *This = (wxTreeCtrl *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
wxTreeItemId Result = This->GetRootItem();
- rt.addRef(getRef((void *)Result.m_pItem,memenv), "wxTreeItemId");
- break;
+ rt.add((wxUIntPtr *) Result.m_pItem);
+ break;
}
-case wxTreeCtrl_GetSelection: { // wxTreeCtrl::GetSelection
+case wxTreeCtrl_GetSelection: { // wxTreeCtrl::GetSelection
wxTreeCtrl *This = (wxTreeCtrl *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
wxTreeItemId Result = This->GetSelection();
- rt.addRef(getRef((void *)Result.m_pItem,memenv), "wxTreeItemId");
- break;
+ rt.add((wxUIntPtr *) Result.m_pItem);
+ break;
}
-case wxTreeCtrl_GetSelections: { // wxTreeCtrl::GetSelections
+case wxTreeCtrl_GetSelections: { // wxTreeCtrl::GetSelections
wxArrayTreeItemIds val;
wxTreeCtrl *This = (wxTreeCtrl *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
size_t Result = This->GetSelections(val);
rt.addInt(Result);
for(unsigned int i=0; i < val.GetCount(); i++) {
- rt.addRef(getRef((void *)val[i].m_pItem,memenv), "wxTreeItemId");}
+ rt.add((wxUIntPtr *)val[i].m_pItem);}
rt.endList(val.GetCount());
rt.addTupleCount(2);
- break;
+ break;
}
-case wxTreeCtrl_GetStateImageList: { // wxTreeCtrl::GetStateImageList
+case wxTreeCtrl_GetStateImageList: { // wxTreeCtrl::GetStateImageList
wxTreeCtrl *This = (wxTreeCtrl *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
wxImageList * Result = (wxImageList*)This->GetStateImageList();
rt.addRef(getRef((void *)Result,memenv), "wxImageList");
- break;
+ break;
}
-case wxTreeCtrl_HitTest: { // wxTreeCtrl::HitTest
+case wxTreeCtrl_HitTest: { // wxTreeCtrl::HitTest
wxTreeCtrl *This = (wxTreeCtrl *) getPtr(bp,memenv); bp += 4;
int * pointX = (int *) bp; bp += 4;
int * pointY = (int *) bp; bp += 4;
wxPoint point = wxPoint(*pointX,*pointY);
if(!This) throw wxe_badarg(0);
wxTreeItemId Result = This->HitTest(point);
- rt.addRef(getRef((void *)Result.m_pItem,memenv), "wxTreeItemId");
- break;
+ rt.add((wxUIntPtr *) Result.m_pItem);
+ break;
}
-case wxTreeCtrl_InsertItem_4_1: { // wxTreeCtrl::InsertItem
- int image=-1;
- int selectedImage=-1;
- wxETreeItemData * data= NULL;
- wxTreeCtrl *This = (wxTreeCtrl *) getPtr(bp,memenv); bp += 4;
- wxTreeItemId parent = wxTreeItemId(getPtr(bp,memenv)); bp += 4;
- wxTreeItemId idPrevious = wxTreeItemId(getPtr(bp,memenv)); bp += 4;
- int * textLen = (int *) bp; bp += 4;
- wxString text = wxString(bp, wxConvUTF8);
- bp += *textLen+((8-((0+ *textLen) & 7)) & 7);
- while( * (int*) bp) { switch (* (int*) bp) {
- case 1: {bp += 4;
- image = (int)*(int *) bp; bp += 4;
- } break;
- case 2: {bp += 4;
- selectedImage = (int)*(int *) bp; bp += 4;
- } break;
- case 3: {bp += 4;
- data = new wxETreeItemData(Ecmd.bin[0]->size, Ecmd.bin[0]->base);
- bp += 4; /* Align */
- } break;
- }};
- if(!This) throw wxe_badarg(0);
- wxTreeItemId Result = This->InsertItem(parent,idPrevious,text,image,selectedImage,data);
- rt.addRef(getRef((void *)Result.m_pItem,memenv), "wxTreeItemId");
- break;
-}
-case wxTreeCtrl_InsertItem_4_0: { // wxTreeCtrl::InsertItem
+case wxTreeCtrl_InsertItem: { // wxTreeCtrl::InsertItem
int image=-1;
int selImage=-1;
wxETreeItemData * data= NULL;
wxTreeCtrl *This = (wxTreeCtrl *) getPtr(bp,memenv); bp += 4;
- wxTreeItemId parent = wxTreeItemId(getPtr(bp,memenv)); bp += 4;
+ bp += 4; /* Align */
+ wxTreeItemId parent = wxTreeItemId((void *) *(wxUint64 *) bp); bp += 8;
int * pos = (int *) bp; bp += 4;
int * textLen = (int *) bp; bp += 4;
wxString text = wxString(bp, wxConvUTF8);
bp += *textLen+((8-((0+ *textLen) & 7)) & 7);
- while( * (int*) bp) { switch (* (int*) bp) {
+ while( * (int*) bp) { switch (* (int*) bp) {
case 1: {bp += 4;
image = (int)*(int *) bp; bp += 4;
} break;
@@ -18769,65 +18796,71 @@ case wxTreeCtrl_InsertItem_4_0: { // wxTreeCtrl::InsertItem
selImage = (int)*(int *) bp; bp += 4;
} break;
case 3: {bp += 4;
- data = new wxETreeItemData(Ecmd.bin[0]->size, Ecmd.bin[0]->base);
+ data = new wxETreeItemData(Ecmd.bin[0]->size, Ecmd.bin[0]->base);
bp += 4; /* Align */
} break;
- }};
+ }};
if(!This) throw wxe_badarg(0);
wxTreeItemId Result = This->InsertItem(parent,(size_t) *pos,text,image,selImage,data);
- rt.addRef(getRef((void *)Result.m_pItem,memenv), "wxTreeItemId");
- break;
+ rt.add((wxUIntPtr *) Result.m_pItem);
+ break;
}
-case wxTreeCtrl_IsBold: { // wxTreeCtrl::IsBold
+case wxTreeCtrl_IsBold: { // wxTreeCtrl::IsBold
wxTreeCtrl *This = (wxTreeCtrl *) getPtr(bp,memenv); bp += 4;
- wxTreeItemId item = wxTreeItemId(getPtr(bp,memenv)); bp += 4;
+ bp += 4; /* Align */
+ wxTreeItemId item = wxTreeItemId((void *) *(wxUint64 *) bp); bp += 8;
if(!This) throw wxe_badarg(0);
bool Result = This->IsBold(item);
rt.addBool(Result);
- break;
+ break;
}
-case wxTreeCtrl_IsExpanded: { // wxTreeCtrl::IsExpanded
+case wxTreeCtrl_IsExpanded: { // wxTreeCtrl::IsExpanded
wxTreeCtrl *This = (wxTreeCtrl *) getPtr(bp,memenv); bp += 4;
- wxTreeItemId item = wxTreeItemId(getPtr(bp,memenv)); bp += 4;
+ bp += 4; /* Align */
+ wxTreeItemId item = wxTreeItemId((void *) *(wxUint64 *) bp); bp += 8;
if(!This) throw wxe_badarg(0);
bool Result = This->IsExpanded(item);
rt.addBool(Result);
- break;
+ break;
}
-case wxTreeCtrl_IsSelected: { // wxTreeCtrl::IsSelected
+case wxTreeCtrl_IsSelected: { // wxTreeCtrl::IsSelected
wxTreeCtrl *This = (wxTreeCtrl *) getPtr(bp,memenv); bp += 4;
- wxTreeItemId item = wxTreeItemId(getPtr(bp,memenv)); bp += 4;
+ bp += 4; /* Align */
+ wxTreeItemId item = wxTreeItemId((void *) *(wxUint64 *) bp); bp += 8;
if(!This) throw wxe_badarg(0);
bool Result = This->IsSelected(item);
rt.addBool(Result);
- break;
+ break;
}
-case wxTreeCtrl_IsVisible: { // wxTreeCtrl::IsVisible
+case wxTreeCtrl_IsVisible: { // wxTreeCtrl::IsVisible
wxTreeCtrl *This = (wxTreeCtrl *) getPtr(bp,memenv); bp += 4;
- wxTreeItemId item = wxTreeItemId(getPtr(bp,memenv)); bp += 4;
+ bp += 4; /* Align */
+ wxTreeItemId item = wxTreeItemId((void *) *(wxUint64 *) bp); bp += 8;
if(!This) throw wxe_badarg(0);
bool Result = This->IsVisible(item);
rt.addBool(Result);
- break;
+ break;
}
-case wxTreeCtrl_ItemHasChildren: { // wxTreeCtrl::ItemHasChildren
+case wxTreeCtrl_ItemHasChildren: { // wxTreeCtrl::ItemHasChildren
wxTreeCtrl *This = (wxTreeCtrl *) getPtr(bp,memenv); bp += 4;
- wxTreeItemId item = wxTreeItemId(getPtr(bp,memenv)); bp += 4;
+ bp += 4; /* Align */
+ wxTreeItemId item = wxTreeItemId((void *) *(wxUint64 *) bp); bp += 8;
if(!This) throw wxe_badarg(0);
bool Result = This->ItemHasChildren(item);
rt.addBool(Result);
- break;
+ break;
}
-case wxTreeCtrl_PrependItem: { // wxTreeCtrl::PrependItem
+case wxTreeCtrl_PrependItem: { // wxTreeCtrl::PrependItem
int image=-1;
int selectedImage=-1;
wxETreeItemData * data= NULL;
wxTreeCtrl *This = (wxTreeCtrl *) getPtr(bp,memenv); bp += 4;
- wxTreeItemId parent = wxTreeItemId(getPtr(bp,memenv)); bp += 4;
+ bp += 4; /* Align */
+ wxTreeItemId parent = wxTreeItemId((void *) *(wxUint64 *) bp); bp += 8;
int * textLen = (int *) bp; bp += 4;
wxString text = wxString(bp, wxConvUTF8);
bp += *textLen+((8-((4+ *textLen) & 7)) & 7);
- while( * (int*) bp) { switch (* (int*) bp) {
+ while( * (int*) bp) { switch (* (int*) bp) {
case 1: {bp += 4;
image = (int)*(int *) bp; bp += 4;
} break;
@@ -18835,59 +18868,63 @@ case wxTreeCtrl_PrependItem: { // wxTreeCtrl::PrependItem
selectedImage = (int)*(int *) bp; bp += 4;
} break;
case 3: {bp += 4;
- data = new wxETreeItemData(Ecmd.bin[0]->size, Ecmd.bin[0]->base);
+ data = new wxETreeItemData(Ecmd.bin[0]->size, Ecmd.bin[0]->base);
bp += 4; /* Align */
} break;
- }};
+ }};
if(!This) throw wxe_badarg(0);
wxTreeItemId Result = This->PrependItem(parent,text,image,selectedImage,data);
- rt.addRef(getRef((void *)Result.m_pItem,memenv), "wxTreeItemId");
- break;
+ rt.add((wxUIntPtr *) Result.m_pItem);
+ break;
}
-case wxTreeCtrl_ScrollTo: { // wxTreeCtrl::ScrollTo
+case wxTreeCtrl_ScrollTo: { // wxTreeCtrl::ScrollTo
wxTreeCtrl *This = (wxTreeCtrl *) getPtr(bp,memenv); bp += 4;
- wxTreeItemId item = wxTreeItemId(getPtr(bp,memenv)); bp += 4;
+ bp += 4; /* Align */
+ wxTreeItemId item = wxTreeItemId((void *) *(wxUint64 *) bp); bp += 8;
if(!This) throw wxe_badarg(0);
This->ScrollTo(item);
- break;
+ break;
}
-case wxTreeCtrl_SelectItem_1: { // wxTreeCtrl::SelectItem
+case wxTreeCtrl_SelectItem_1: { // wxTreeCtrl::SelectItem
wxTreeCtrl *This = (wxTreeCtrl *) getPtr(bp,memenv); bp += 4;
- wxTreeItemId item = wxTreeItemId(getPtr(bp,memenv)); bp += 4;
+ bp += 4; /* Align */
+ wxTreeItemId item = wxTreeItemId((void *) *(wxUint64 *) bp); bp += 8;
if(!This) throw wxe_badarg(0);
This->SelectItem(item);
- break;
+ break;
}
-case wxTreeCtrl_SelectItem_2: { // wxTreeCtrl::SelectItem
+case wxTreeCtrl_SelectItem_2: { // wxTreeCtrl::SelectItem
bool select=true;
wxTreeCtrl *This = (wxTreeCtrl *) getPtr(bp,memenv); bp += 4;
- wxTreeItemId item = wxTreeItemId(getPtr(bp,memenv)); bp += 4;
- while( * (int*) bp) { switch (* (int*) bp) {
+ bp += 4; /* Align */
+ wxTreeItemId item = wxTreeItemId((void *) *(wxUint64 *) bp); bp += 8;
+ while( * (int*) bp) { switch (* (int*) bp) {
case 1: {bp += 4;
select = *(bool *) bp; bp += 4;
} break;
- }};
+ }};
if(!This) throw wxe_badarg(0);
This->SelectItem(item,select);
- break;
+ break;
}
-case wxTreeCtrl_SetIndent: { // wxTreeCtrl::SetIndent
+case wxTreeCtrl_SetIndent: { // wxTreeCtrl::SetIndent
wxTreeCtrl *This = (wxTreeCtrl *) getPtr(bp,memenv); bp += 4;
unsigned int * indent = (unsigned int *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
This->SetIndent((int) *indent);
- break;
+ break;
}
-case wxTreeCtrl_SetImageList: { // wxTreeCtrl::SetImageList
+case wxTreeCtrl_SetImageList: { // wxTreeCtrl::SetImageList
wxTreeCtrl *This = (wxTreeCtrl *) getPtr(bp,memenv); bp += 4;
wxImageList *imageList = (wxImageList *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
This->SetImageList(imageList);
- break;
+ break;
}
-case wxTreeCtrl_SetItemBackgroundColour: { // wxTreeCtrl::SetItemBackgroundColour
+case wxTreeCtrl_SetItemBackgroundColour: { // wxTreeCtrl::SetItemBackgroundColour
wxTreeCtrl *This = (wxTreeCtrl *) getPtr(bp,memenv); bp += 4;
- wxTreeItemId item = wxTreeItemId(getPtr(bp,memenv)); bp += 4;
+ bp += 4; /* Align */
+ wxTreeItemId item = wxTreeItemId((void *) *(wxUint64 *) bp); bp += 8;
int * colR = (int *) bp; bp += 4;
int * colG = (int *) bp; bp += 4;
int * colB = (int *) bp; bp += 4;
@@ -18895,99 +18932,108 @@ case wxTreeCtrl_SetItemBackgroundColour: { // wxTreeCtrl::SetItemBackgroundColou
wxColour col = wxColour(*colR,*colG,*colB,*colA);
if(!This) throw wxe_badarg(0);
This->SetItemBackgroundColour(item,col);
- break;
+ break;
}
-case wxTreeCtrl_SetItemBold: { // wxTreeCtrl::SetItemBold
+case wxTreeCtrl_SetItemBold: { // wxTreeCtrl::SetItemBold
bool bold=true;
wxTreeCtrl *This = (wxTreeCtrl *) getPtr(bp,memenv); bp += 4;
- wxTreeItemId item = wxTreeItemId(getPtr(bp,memenv)); bp += 4;
- while( * (int*) bp) { switch (* (int*) bp) {
+ bp += 4; /* Align */
+ wxTreeItemId item = wxTreeItemId((void *) *(wxUint64 *) bp); bp += 8;
+ while( * (int*) bp) { switch (* (int*) bp) {
case 1: {bp += 4;
bold = *(bool *) bp; bp += 4;
} break;
- }};
+ }};
if(!This) throw wxe_badarg(0);
This->SetItemBold(item,bold);
- break;
+ break;
}
-case wxTreeCtrl_SetItemData: { // wxTreeCtrl::SetItemData
+case wxTreeCtrl_SetItemData: { // wxTreeCtrl::SetItemData
wxTreeCtrl *This = (wxTreeCtrl *) getPtr(bp,memenv); bp += 4;
- wxTreeItemId item = wxTreeItemId(getPtr(bp,memenv)); bp += 4;
- wxETreeItemData * data = new wxETreeItemData(Ecmd.bin[0]->size, Ecmd.bin[0]->base);
+ bp += 4; /* Align */
+ wxTreeItemId item = wxTreeItemId((void *) *(wxUint64 *) bp); bp += 8;
+ wxETreeItemData * data = new wxETreeItemData(Ecmd.bin[0]->size, Ecmd.bin[0]->base);
if(!This) throw wxe_badarg(0);
This->SetItemData(item,data);
- break;
+ break;
}
-case wxTreeCtrl_SetItemDropHighlight: { // wxTreeCtrl::SetItemDropHighlight
+case wxTreeCtrl_SetItemDropHighlight: { // wxTreeCtrl::SetItemDropHighlight
bool highlight=true;
wxTreeCtrl *This = (wxTreeCtrl *) getPtr(bp,memenv); bp += 4;
- wxTreeItemId item = wxTreeItemId(getPtr(bp,memenv)); bp += 4;
- while( * (int*) bp) { switch (* (int*) bp) {
+ bp += 4; /* Align */
+ wxTreeItemId item = wxTreeItemId((void *) *(wxUint64 *) bp); bp += 8;
+ while( * (int*) bp) { switch (* (int*) bp) {
case 1: {bp += 4;
highlight = *(bool *) bp; bp += 4;
} break;
- }};
+ }};
if(!This) throw wxe_badarg(0);
This->SetItemDropHighlight(item,highlight);
- break;
+ break;
}
-case wxTreeCtrl_SetItemFont: { // wxTreeCtrl::SetItemFont
+case wxTreeCtrl_SetItemFont: { // wxTreeCtrl::SetItemFont
wxTreeCtrl *This = (wxTreeCtrl *) getPtr(bp,memenv); bp += 4;
- wxTreeItemId item = wxTreeItemId(getPtr(bp,memenv)); bp += 4;
+ bp += 4; /* Align */
+ wxTreeItemId item = wxTreeItemId((void *) *(wxUint64 *) bp); bp += 8;
wxFont *font = (wxFont *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
This->SetItemFont(item,*font);
- break;
+ break;
}
-case wxTreeCtrl_SetItemHasChildren: { // wxTreeCtrl::SetItemHasChildren
+case wxTreeCtrl_SetItemHasChildren: { // wxTreeCtrl::SetItemHasChildren
bool has=true;
wxTreeCtrl *This = (wxTreeCtrl *) getPtr(bp,memenv); bp += 4;
- wxTreeItemId item = wxTreeItemId(getPtr(bp,memenv)); bp += 4;
- while( * (int*) bp) { switch (* (int*) bp) {
+ bp += 4; /* Align */
+ wxTreeItemId item = wxTreeItemId((void *) *(wxUint64 *) bp); bp += 8;
+ while( * (int*) bp) { switch (* (int*) bp) {
case 1: {bp += 4;
has = *(bool *) bp; bp += 4;
} break;
- }};
+ }};
if(!This) throw wxe_badarg(0);
This->SetItemHasChildren(item,has);
- break;
+ break;
}
-case wxTreeCtrl_SetItemImage_2: { // wxTreeCtrl::SetItemImage
+case wxTreeCtrl_SetItemImage_2: { // wxTreeCtrl::SetItemImage
wxTreeCtrl *This = (wxTreeCtrl *) getPtr(bp,memenv); bp += 4;
- wxTreeItemId item = wxTreeItemId(getPtr(bp,memenv)); bp += 4;
+ bp += 4; /* Align */
+ wxTreeItemId item = wxTreeItemId((void *) *(wxUint64 *) bp); bp += 8;
int * image = (int *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
This->SetItemImage(item,(int) *image);
- break;
+ break;
}
-case wxTreeCtrl_SetItemImage_3: { // wxTreeCtrl::SetItemImage
+case wxTreeCtrl_SetItemImage_3: { // wxTreeCtrl::SetItemImage
wxTreeItemIcon which=wxTreeItemIcon_Normal;
wxTreeCtrl *This = (wxTreeCtrl *) getPtr(bp,memenv); bp += 4;
- wxTreeItemId item = wxTreeItemId(getPtr(bp,memenv)); bp += 4;
+ bp += 4; /* Align */
+ wxTreeItemId item = wxTreeItemId((void *) *(wxUint64 *) bp); bp += 8;
int * image = (int *) bp; bp += 4;
bp += 4; /* Align */
- while( * (int*) bp) { switch (* (int*) bp) {
+ while( * (int*) bp) { switch (* (int*) bp) {
case 1: {bp += 4;
which = *(wxTreeItemIcon *) bp; bp += 4;;
} break;
- }};
+ }};
if(!This) throw wxe_badarg(0);
This->SetItemImage(item,(int) *image,(wxTreeItemIcon) which);
- break;
+ break;
}
-case wxTreeCtrl_SetItemText: { // wxTreeCtrl::SetItemText
+case wxTreeCtrl_SetItemText: { // wxTreeCtrl::SetItemText
wxTreeCtrl *This = (wxTreeCtrl *) getPtr(bp,memenv); bp += 4;
- wxTreeItemId item = wxTreeItemId(getPtr(bp,memenv)); bp += 4;
+ bp += 4; /* Align */
+ wxTreeItemId item = wxTreeItemId((void *) *(wxUint64 *) bp); bp += 8;
int * textLen = (int *) bp; bp += 4;
wxString text = wxString(bp, wxConvUTF8);
bp += *textLen+((8-((4+ *textLen) & 7)) & 7);
if(!This) throw wxe_badarg(0);
This->SetItemText(item,text);
- break;
+ break;
}
-case wxTreeCtrl_SetItemTextColour: { // wxTreeCtrl::SetItemTextColour
+case wxTreeCtrl_SetItemTextColour: { // wxTreeCtrl::SetItemTextColour
wxTreeCtrl *This = (wxTreeCtrl *) getPtr(bp,memenv); bp += 4;
- wxTreeItemId item = wxTreeItemId(getPtr(bp,memenv)); bp += 4;
+ bp += 4; /* Align */
+ wxTreeItemId item = wxTreeItemId((void *) *(wxUint64 *) bp); bp += 8;
int * colR = (int *) bp; bp += 4;
int * colG = (int *) bp; bp += 4;
int * colB = (int *) bp; bp += 4;
@@ -18995,76 +19041,80 @@ case wxTreeCtrl_SetItemTextColour: { // wxTreeCtrl::SetItemTextColour
wxColour col = wxColour(*colR,*colG,*colB,*colA);
if(!This) throw wxe_badarg(0);
This->SetItemTextColour(item,col);
- break;
+ break;
}
-case wxTreeCtrl_SetStateImageList: { // wxTreeCtrl::SetStateImageList
+case wxTreeCtrl_SetStateImageList: { // wxTreeCtrl::SetStateImageList
wxTreeCtrl *This = (wxTreeCtrl *) getPtr(bp,memenv); bp += 4;
wxImageList *imageList = (wxImageList *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
This->SetStateImageList(imageList);
- break;
+ break;
}
-case wxTreeCtrl_SetWindowStyle: { // wxTreeCtrl::SetWindowStyle
+case wxTreeCtrl_SetWindowStyle: { // wxTreeCtrl::SetWindowStyle
wxTreeCtrl *This = (wxTreeCtrl *) getPtr(bp,memenv); bp += 4;
const int * styles = (const int *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
This->SetWindowStyle((long) *styles);
- break;
+ break;
}
-case wxTreeCtrl_SortChildren: { // wxTreeCtrl::SortChildren
+case wxTreeCtrl_SortChildren: { // wxTreeCtrl::SortChildren
wxTreeCtrl *This = (wxTreeCtrl *) getPtr(bp,memenv); bp += 4;
- wxTreeItemId item = wxTreeItemId(getPtr(bp,memenv)); bp += 4;
+ bp += 4; /* Align */
+ wxTreeItemId item = wxTreeItemId((void *) *(wxUint64 *) bp); bp += 8;
if(!This) throw wxe_badarg(0);
This->SortChildren(item);
- break;
+ break;
}
-case wxTreeCtrl_Toggle: { // wxTreeCtrl::Toggle
+case wxTreeCtrl_Toggle: { // wxTreeCtrl::Toggle
wxTreeCtrl *This = (wxTreeCtrl *) getPtr(bp,memenv); bp += 4;
- wxTreeItemId item = wxTreeItemId(getPtr(bp,memenv)); bp += 4;
+ bp += 4; /* Align */
+ wxTreeItemId item = wxTreeItemId((void *) *(wxUint64 *) bp); bp += 8;
if(!This) throw wxe_badarg(0);
This->Toggle(item);
- break;
+ break;
}
-case wxTreeCtrl_ToggleItemSelection: { // wxTreeCtrl::ToggleItemSelection
+case wxTreeCtrl_ToggleItemSelection: { // wxTreeCtrl::ToggleItemSelection
wxTreeCtrl *This = (wxTreeCtrl *) getPtr(bp,memenv); bp += 4;
- wxTreeItemId item = wxTreeItemId(getPtr(bp,memenv)); bp += 4;
+ bp += 4; /* Align */
+ wxTreeItemId item = wxTreeItemId((void *) *(wxUint64 *) bp); bp += 8;
if(!This) throw wxe_badarg(0);
This->ToggleItemSelection(item);
- break;
+ break;
}
-case wxTreeCtrl_Unselect: { // wxTreeCtrl::Unselect
+case wxTreeCtrl_Unselect: { // wxTreeCtrl::Unselect
wxTreeCtrl *This = (wxTreeCtrl *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
This->Unselect();
- break;
+ break;
}
-case wxTreeCtrl_UnselectAll: { // wxTreeCtrl::UnselectAll
+case wxTreeCtrl_UnselectAll: { // wxTreeCtrl::UnselectAll
wxTreeCtrl *This = (wxTreeCtrl *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
This->UnselectAll();
- break;
+ break;
}
-case wxTreeCtrl_UnselectItem: { // wxTreeCtrl::UnselectItem
+case wxTreeCtrl_UnselectItem: { // wxTreeCtrl::UnselectItem
wxTreeCtrl *This = (wxTreeCtrl *) getPtr(bp,memenv); bp += 4;
- wxTreeItemId item = wxTreeItemId(getPtr(bp,memenv)); bp += 4;
+ bp += 4; /* Align */
+ wxTreeItemId item = wxTreeItemId((void *) *(wxUint64 *) bp); bp += 8;
if(!This) throw wxe_badarg(0);
This->UnselectItem(item);
- break;
+ break;
}
-case wxScrollBar_new_0: { // wxScrollBar::wxScrollBar
+case wxScrollBar_new_0: { // wxScrollBar::wxScrollBar
wxScrollBar * Result = new EwxScrollBar();
newPtr((void *) Result, 0, memenv);
rt.addRef(getRef((void *)Result,memenv), "wxScrollBar");
- break;
+ break;
}
-case wxScrollBar_new_3: { // wxScrollBar::wxScrollBar
+case wxScrollBar_new_3: { // wxScrollBar::wxScrollBar
wxPoint pos= wxDefaultPosition;
wxSize size= wxDefaultSize;
long style=wxSB_HORIZONTAL;
const wxValidator * validator= &wxDefaultValidator;
wxWindow *parent = (wxWindow *) getPtr(bp,memenv); bp += 4;
int * id = (int *) bp; bp += 4;
- while( * (int*) bp) { switch (* (int*) bp) {
+ while( * (int*) bp) { switch (* (int*) bp) {
case 1: {bp += 4;
int * posX = (int *) bp; bp += 4;
int * posY = (int *) bp; bp += 4;
@@ -19083,13 +19133,13 @@ case wxScrollBar_new_3: { // wxScrollBar::wxScrollBar
case 4: {bp += 4;
validator = (wxValidator *) getPtr(bp,memenv); bp += 4;
} break;
- }};
+ }};
wxScrollBar * Result = new EwxScrollBar(parent,(wxWindowID) *id,pos,size,style,*validator);
newPtr((void *) Result, 0, memenv);
rt.addRef(getRef((void *)Result,memenv), "wxScrollBar");
- break;
+ break;
}
-case wxScrollBar_Create: { // wxScrollBar::Create
+case wxScrollBar_Create: { // wxScrollBar::Create
wxPoint pos= wxDefaultPosition;
wxSize size= wxDefaultSize;
long style=wxSB_HORIZONTAL;
@@ -19098,7 +19148,7 @@ case wxScrollBar_Create: { // wxScrollBar::Create
wxWindow *parent = (wxWindow *) getPtr(bp,memenv); bp += 4;
int * id = (int *) bp; bp += 4;
bp += 4; /* Align */
- while( * (int*) bp) { switch (* (int*) bp) {
+ while( * (int*) bp) { switch (* (int*) bp) {
case 1: {bp += 4;
int * posX = (int *) bp; bp += 4;
int * posY = (int *) bp; bp += 4;
@@ -19117,48 +19167,48 @@ case wxScrollBar_Create: { // wxScrollBar::Create
case 4: {bp += 4;
validator = (wxValidator *) getPtr(bp,memenv); bp += 4;
} break;
- }};
+ }};
if(!This) throw wxe_badarg(0);
bool Result = This->Create(parent,(wxWindowID) *id,pos,size,style,*validator);
rt.addBool(Result);
- break;
+ break;
}
-case wxScrollBar_GetRange: { // wxScrollBar::GetRange
+case wxScrollBar_GetRange: { // wxScrollBar::GetRange
wxScrollBar *This = (wxScrollBar *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
int Result = This->GetRange();
rt.addInt(Result);
- break;
+ break;
}
-case wxScrollBar_GetPageSize: { // wxScrollBar::GetPageSize
+case wxScrollBar_GetPageSize: { // wxScrollBar::GetPageSize
wxScrollBar *This = (wxScrollBar *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
int Result = This->GetPageSize();
rt.addInt(Result);
- break;
+ break;
}
-case wxScrollBar_GetThumbPosition: { // wxScrollBar::GetThumbPosition
+case wxScrollBar_GetThumbPosition: { // wxScrollBar::GetThumbPosition
wxScrollBar *This = (wxScrollBar *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
int Result = This->GetThumbPosition();
rt.addInt(Result);
- break;
+ break;
}
-case wxScrollBar_GetThumbSize: { // wxScrollBar::GetThumbSize
+case wxScrollBar_GetThumbSize: { // wxScrollBar::GetThumbSize
wxScrollBar *This = (wxScrollBar *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
int Result = This->GetThumbSize();
rt.addInt(Result);
- break;
+ break;
}
-case wxScrollBar_SetThumbPosition: { // wxScrollBar::SetThumbPosition
+case wxScrollBar_SetThumbPosition: { // wxScrollBar::SetThumbPosition
wxScrollBar *This = (wxScrollBar *) getPtr(bp,memenv); bp += 4;
int * viewStart = (int *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
This->SetThumbPosition((int) *viewStart);
- break;
+ break;
}
-case wxScrollBar_SetScrollbar: { // wxScrollBar::SetScrollbar
+case wxScrollBar_SetScrollbar: { // wxScrollBar::SetScrollbar
bool refresh=true;
wxScrollBar *This = (wxScrollBar *) getPtr(bp,memenv); bp += 4;
int * position = (int *) bp; bp += 4;
@@ -19166,23 +19216,23 @@ case wxScrollBar_SetScrollbar: { // wxScrollBar::SetScrollbar
int * range = (int *) bp; bp += 4;
int * pageSize = (int *) bp; bp += 4;
bp += 4; /* Align */
- while( * (int*) bp) { switch (* (int*) bp) {
+ while( * (int*) bp) { switch (* (int*) bp) {
case 1: {bp += 4;
refresh = *(bool *) bp; bp += 4;
} break;
- }};
+ }};
if(!This) throw wxe_badarg(0);
This->SetScrollbar((int) *position,(int) *thumbSize,(int) *range,(int) *pageSize,refresh);
- break;
+ break;
}
-case wxSpinButton_new_2: { // wxSpinButton::wxSpinButton
+case wxSpinButton_new_2: { // wxSpinButton::wxSpinButton
wxWindowID id=-1;
wxPoint pos= wxDefaultPosition;
wxSize size= wxDefaultSize;
long style=wxSP_VERTICAL;
wxWindow *parent = (wxWindow *) getPtr(bp,memenv); bp += 4;
bp += 4; /* Align */
- while( * (int*) bp) { switch (* (int*) bp) {
+ while( * (int*) bp) { switch (* (int*) bp) {
case 1: {bp += 4;
id = (wxWindowID)*(int *) bp; bp += 4;
} break;
@@ -19201,26 +19251,26 @@ case wxSpinButton_new_2: { // wxSpinButton::wxSpinButton
case 4: {bp += 4;
style = (long)*(int *) bp; bp += 4;
} break;
- }};
+ }};
wxSpinButton * Result = new EwxSpinButton(parent,id,pos,size,style);
newPtr((void *) Result, 0, memenv);
rt.addRef(getRef((void *)Result,memenv), "wxSpinButton");
- break;
+ break;
}
-case wxSpinButton_new_0: { // wxSpinButton::wxSpinButton
+case wxSpinButton_new_0: { // wxSpinButton::wxSpinButton
wxSpinButton * Result = new EwxSpinButton();
newPtr((void *) Result, 0, memenv);
rt.addRef(getRef((void *)Result,memenv), "wxSpinButton");
- break;
+ break;
}
-case wxSpinButton_Create: { // wxSpinButton::Create
+case wxSpinButton_Create: { // wxSpinButton::Create
wxWindowID id=-1;
wxPoint pos= wxDefaultPosition;
wxSize size= wxDefaultSize;
long style=wxSP_VERTICAL;
wxSpinButton *This = (wxSpinButton *) getPtr(bp,memenv); bp += 4;
wxWindow *parent = (wxWindow *) getPtr(bp,memenv); bp += 4;
- while( * (int*) bp) { switch (* (int*) bp) {
+ while( * (int*) bp) { switch (* (int*) bp) {
case 1: {bp += 4;
id = (wxWindowID)*(int *) bp; bp += 4;
} break;
@@ -19239,55 +19289,55 @@ case wxSpinButton_Create: { // wxSpinButton::Create
case 4: {bp += 4;
style = (long)*(int *) bp; bp += 4;
} break;
- }};
+ }};
if(!This) throw wxe_badarg(0);
bool Result = This->Create(parent,id,pos,size,style);
rt.addBool(Result);
- break;
+ break;
}
-case wxSpinButton_GetMax: { // wxSpinButton::GetMax
+case wxSpinButton_GetMax: { // wxSpinButton::GetMax
wxSpinButton *This = (wxSpinButton *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
int Result = This->GetMax();
rt.addInt(Result);
- break;
+ break;
}
-case wxSpinButton_GetMin: { // wxSpinButton::GetMin
+case wxSpinButton_GetMin: { // wxSpinButton::GetMin
wxSpinButton *This = (wxSpinButton *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
int Result = This->GetMin();
rt.addInt(Result);
- break;
+ break;
}
-case wxSpinButton_GetValue: { // wxSpinButton::GetValue
+case wxSpinButton_GetValue: { // wxSpinButton::GetValue
wxSpinButton *This = (wxSpinButton *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
int Result = This->GetValue();
rt.addInt(Result);
- break;
+ break;
}
-case wxSpinButton_SetRange: { // wxSpinButton::SetRange
+case wxSpinButton_SetRange: { // wxSpinButton::SetRange
wxSpinButton *This = (wxSpinButton *) getPtr(bp,memenv); bp += 4;
int * minVal = (int *) bp; bp += 4;
int * maxVal = (int *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
This->SetRange((int) *minVal,(int) *maxVal);
- break;
+ break;
}
-case wxSpinButton_SetValue: { // wxSpinButton::SetValue
+case wxSpinButton_SetValue: { // wxSpinButton::SetValue
wxSpinButton *This = (wxSpinButton *) getPtr(bp,memenv); bp += 4;
int * value = (int *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
This->SetValue((int) *value);
- break;
+ break;
}
-case wxSpinCtrl_new_0: { // wxSpinCtrl::wxSpinCtrl
+case wxSpinCtrl_new_0: { // wxSpinCtrl::wxSpinCtrl
wxSpinCtrl * Result = new EwxSpinCtrl();
newPtr((void *) Result, 0, memenv);
rt.addRef(getRef((void *)Result,memenv), "wxSpinCtrl");
- break;
+ break;
}
-case wxSpinCtrl_new_2: { // wxSpinCtrl::wxSpinCtrl
+case wxSpinCtrl_new_2: { // wxSpinCtrl::wxSpinCtrl
wxWindowID id=wxID_ANY;
wxString value= wxEmptyString;
wxPoint pos= wxDefaultPosition;
@@ -19298,7 +19348,7 @@ case wxSpinCtrl_new_2: { // wxSpinCtrl::wxSpinCtrl
int initial=0;
wxWindow *parent = (wxWindow *) getPtr(bp,memenv); bp += 4;
bp += 4; /* Align */
- while( * (int*) bp) { switch (* (int*) bp) {
+ while( * (int*) bp) { switch (* (int*) bp) {
case 1: {bp += 4;
id = (wxWindowID)*(int *) bp; bp += 4;
} break;
@@ -19331,13 +19381,13 @@ case wxSpinCtrl_new_2: { // wxSpinCtrl::wxSpinCtrl
case 8: {bp += 4;
initial = (int)*(int *) bp; bp += 4;
} break;
- }};
+ }};
wxSpinCtrl * Result = new EwxSpinCtrl(parent,id,value,pos,size,style,min,max,initial);
newPtr((void *) Result, 0, memenv);
rt.addRef(getRef((void *)Result,memenv), "wxSpinCtrl");
- break;
+ break;
}
-case wxSpinCtrl_Create: { // wxSpinCtrl::Create
+case wxSpinCtrl_Create: { // wxSpinCtrl::Create
wxWindowID id=wxID_ANY;
wxString value= wxEmptyString;
wxPoint pos= wxDefaultPosition;
@@ -19348,7 +19398,7 @@ case wxSpinCtrl_Create: { // wxSpinCtrl::Create
int initial=0;
wxSpinCtrl *This = (wxSpinCtrl *) getPtr(bp,memenv); bp += 4;
wxWindow *parent = (wxWindow *) getPtr(bp,memenv); bp += 4;
- while( * (int*) bp) { switch (* (int*) bp) {
+ while( * (int*) bp) { switch (* (int*) bp) {
case 1: {bp += 4;
id = (wxWindowID)*(int *) bp; bp += 4;
} break;
@@ -19381,72 +19431,72 @@ case wxSpinCtrl_Create: { // wxSpinCtrl::Create
case 8: {bp += 4;
initial = (int)*(int *) bp; bp += 4;
} break;
- }};
+ }};
if(!This) throw wxe_badarg(0);
bool Result = This->Create(parent,id,value,pos,size,style,min,max,initial);
rt.addBool(Result);
- break;
+ break;
}
-case wxSpinCtrl_SetValue_1_1: { // wxSpinCtrl::SetValue
+case wxSpinCtrl_SetValue_1_1: { // wxSpinCtrl::SetValue
wxSpinCtrl *This = (wxSpinCtrl *) getPtr(bp,memenv); bp += 4;
int * textLen = (int *) bp; bp += 4;
wxString text = wxString(bp, wxConvUTF8);
bp += *textLen+((8-((0+ *textLen) & 7)) & 7);
if(!This) throw wxe_badarg(0);
This->SetValue(text);
- break;
+ break;
}
-case wxSpinCtrl_SetValue_1_0: { // wxSpinCtrl::SetValue
+case wxSpinCtrl_SetValue_1_0: { // wxSpinCtrl::SetValue
wxSpinCtrl *This = (wxSpinCtrl *) getPtr(bp,memenv); bp += 4;
int * value = (int *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
This->SetValue((int) *value);
- break;
+ break;
}
-case wxSpinCtrl_GetValue: { // wxSpinCtrl::GetValue
+case wxSpinCtrl_GetValue: { // wxSpinCtrl::GetValue
wxSpinCtrl *This = (wxSpinCtrl *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
int Result = This->GetValue();
rt.addInt(Result);
- break;
+ break;
}
-case wxSpinCtrl_SetRange: { // wxSpinCtrl::SetRange
+case wxSpinCtrl_SetRange: { // wxSpinCtrl::SetRange
wxSpinCtrl *This = (wxSpinCtrl *) getPtr(bp,memenv); bp += 4;
int * minVal = (int *) bp; bp += 4;
int * maxVal = (int *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
This->SetRange((int) *minVal,(int) *maxVal);
- break;
+ break;
}
-case wxSpinCtrl_SetSelection: { // wxSpinCtrl::SetSelection
+case wxSpinCtrl_SetSelection: { // wxSpinCtrl::SetSelection
wxSpinCtrl *This = (wxSpinCtrl *) getPtr(bp,memenv); bp += 4;
int * from = (int *) bp; bp += 4;
int * to = (int *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
This->SetSelection((long) *from,(long) *to);
- break;
+ break;
}
-case wxSpinCtrl_GetMin: { // wxSpinCtrl::GetMin
+case wxSpinCtrl_GetMin: { // wxSpinCtrl::GetMin
wxSpinCtrl *This = (wxSpinCtrl *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
int Result = This->GetMin();
rt.addInt(Result);
- break;
+ break;
}
-case wxSpinCtrl_GetMax: { // wxSpinCtrl::GetMax
+case wxSpinCtrl_GetMax: { // wxSpinCtrl::GetMax
wxSpinCtrl *This = (wxSpinCtrl *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
int Result = This->GetMax();
rt.addInt(Result);
- break;
+ break;
}
-case wxStaticText_new_0: { // wxStaticText::wxStaticText
+case wxStaticText_new_0: { // wxStaticText::wxStaticText
wxStaticText * Result = new EwxStaticText();
newPtr((void *) Result, 0, memenv);
rt.addRef(getRef((void *)Result,memenv), "wxStaticText");
- break;
+ break;
}
-case wxStaticText_new_4: { // wxStaticText::wxStaticText
+case wxStaticText_new_4: { // wxStaticText::wxStaticText
wxPoint pos= wxDefaultPosition;
wxSize size= wxDefaultSize;
long style=0;
@@ -19455,7 +19505,7 @@ case wxStaticText_new_4: { // wxStaticText::wxStaticText
int * labelLen = (int *) bp; bp += 4;
wxString label = wxString(bp, wxConvUTF8);
bp += *labelLen+((8-((4+ *labelLen) & 7)) & 7);
- while( * (int*) bp) { switch (* (int*) bp) {
+ while( * (int*) bp) { switch (* (int*) bp) {
case 1: {bp += 4;
int * posX = (int *) bp; bp += 4;
int * posY = (int *) bp; bp += 4;
@@ -19471,13 +19521,13 @@ case wxStaticText_new_4: { // wxStaticText::wxStaticText
case 3: {bp += 4;
style = (long)*(int *) bp; bp += 4;
} break;
- }};
+ }};
wxStaticText * Result = new EwxStaticText(parent,(wxWindowID) *id,label,pos,size,style);
newPtr((void *) Result, 0, memenv);
rt.addRef(getRef((void *)Result,memenv), "wxStaticText");
- break;
+ break;
}
-case wxStaticText_Create: { // wxStaticText::Create
+case wxStaticText_Create: { // wxStaticText::Create
wxPoint pos= wxDefaultPosition;
wxSize size= wxDefaultSize;
long style=0;
@@ -19487,7 +19537,7 @@ case wxStaticText_Create: { // wxStaticText::Create
int * labelLen = (int *) bp; bp += 4;
wxString label = wxString(bp, wxConvUTF8);
bp += *labelLen+((8-((0+ *labelLen) & 7)) & 7);
- while( * (int*) bp) { switch (* (int*) bp) {
+ while( * (int*) bp) { switch (* (int*) bp) {
case 1: {bp += 4;
int * posX = (int *) bp; bp += 4;
int * posY = (int *) bp; bp += 4;
@@ -19503,42 +19553,42 @@ case wxStaticText_Create: { // wxStaticText::Create
case 3: {bp += 4;
style = (long)*(int *) bp; bp += 4;
} break;
- }};
+ }};
if(!This) throw wxe_badarg(0);
bool Result = This->Create(parent,(wxWindowID) *id,label,pos,size,style);
rt.addBool(Result);
- break;
+ break;
}
-case wxStaticText_GetLabel: { // wxStaticText::GetLabel
+case wxStaticText_GetLabel: { // wxStaticText::GetLabel
wxStaticText *This = (wxStaticText *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
wxString Result = This->GetLabel();
rt.add(Result);
- break;
+ break;
}
-case wxStaticText_SetLabel: { // wxStaticText::SetLabel
+case wxStaticText_SetLabel: { // wxStaticText::SetLabel
wxStaticText *This = (wxStaticText *) getPtr(bp,memenv); bp += 4;
int * labelLen = (int *) bp; bp += 4;
wxString label = wxString(bp, wxConvUTF8);
bp += *labelLen+((8-((0+ *labelLen) & 7)) & 7);
if(!This) throw wxe_badarg(0);
This->SetLabel(label);
- break;
+ break;
}
-case wxStaticText_Wrap: { // wxStaticText::Wrap
+case wxStaticText_Wrap: { // wxStaticText::Wrap
wxStaticText *This = (wxStaticText *) getPtr(bp,memenv); bp += 4;
int * width = (int *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
This->Wrap((int) *width);
- break;
+ break;
}
-case wxStaticBitmap_new_0: { // wxStaticBitmap::wxStaticBitmap
+case wxStaticBitmap_new_0: { // wxStaticBitmap::wxStaticBitmap
wxStaticBitmap * Result = new EwxStaticBitmap();
newPtr((void *) Result, 0, memenv);
rt.addRef(getRef((void *)Result,memenv), "wxStaticBitmap");
- break;
+ break;
}
-case wxStaticBitmap_new_4: { // wxStaticBitmap::wxStaticBitmap
+case wxStaticBitmap_new_4: { // wxStaticBitmap::wxStaticBitmap
wxPoint pos= wxDefaultPosition;
wxSize size= wxDefaultSize;
long style=0;
@@ -19546,7 +19596,7 @@ case wxStaticBitmap_new_4: { // wxStaticBitmap::wxStaticBitmap
int * id = (int *) bp; bp += 4;
wxBitmap *label = (wxBitmap *) getPtr(bp,memenv); bp += 4;
bp += 4; /* Align */
- while( * (int*) bp) { switch (* (int*) bp) {
+ while( * (int*) bp) { switch (* (int*) bp) {
case 1: {bp += 4;
int * posX = (int *) bp; bp += 4;
int * posY = (int *) bp; bp += 4;
@@ -19562,13 +19612,13 @@ case wxStaticBitmap_new_4: { // wxStaticBitmap::wxStaticBitmap
case 3: {bp += 4;
style = (long)*(int *) bp; bp += 4;
} break;
- }};
+ }};
wxStaticBitmap * Result = new EwxStaticBitmap(parent,(wxWindowID) *id,*label,pos,size,style);
newPtr((void *) Result, 0, memenv);
rt.addRef(getRef((void *)Result,memenv), "wxStaticBitmap");
- break;
+ break;
}
-case wxStaticBitmap_Create: { // wxStaticBitmap::Create
+case wxStaticBitmap_Create: { // wxStaticBitmap::Create
wxPoint pos= wxDefaultPosition;
wxSize size= wxDefaultSize;
long style=0;
@@ -19576,7 +19626,7 @@ case wxStaticBitmap_Create: { // wxStaticBitmap::Create
wxWindow *parent = (wxWindow *) getPtr(bp,memenv); bp += 4;
int * id = (int *) bp; bp += 4;
wxBitmap *label = (wxBitmap *) getPtr(bp,memenv); bp += 4;
- while( * (int*) bp) { switch (* (int*) bp) {
+ while( * (int*) bp) { switch (* (int*) bp) {
case 1: {bp += 4;
int * posX = (int *) bp; bp += 4;
int * posY = (int *) bp; bp += 4;
@@ -19592,27 +19642,27 @@ case wxStaticBitmap_Create: { // wxStaticBitmap::Create
case 3: {bp += 4;
style = (long)*(int *) bp; bp += 4;
} break;
- }};
+ }};
if(!This) throw wxe_badarg(0);
bool Result = This->Create(parent,(wxWindowID) *id,*label,pos,size,style);
rt.addBool(Result);
- break;
+ break;
}
-case wxStaticBitmap_GetBitmap: { // wxStaticBitmap::GetBitmap
+case wxStaticBitmap_GetBitmap: { // wxStaticBitmap::GetBitmap
wxStaticBitmap *This = (wxStaticBitmap *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
wxBitmap * Result = new wxBitmap(This->GetBitmap()); newPtr((void *) Result,3, memenv);;
rt.addRef(getRef((void *)Result,memenv), "wxBitmap");
- break;
+ break;
}
-case wxStaticBitmap_SetBitmap: { // wxStaticBitmap::SetBitmap
+case wxStaticBitmap_SetBitmap: { // wxStaticBitmap::SetBitmap
wxStaticBitmap *This = (wxStaticBitmap *) getPtr(bp,memenv); bp += 4;
wxBitmap *bitmap = (wxBitmap *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
This->SetBitmap(*bitmap);
- break;
+ break;
}
-case wxRadioBox_new: { // wxRadioBox::wxRadioBox
+case wxRadioBox_new: { // wxRadioBox::wxRadioBox
int majorDim=1;
long style=wxRA_HORIZONTAL;
const wxValidator * val= &wxDefaultValidator;
@@ -19637,7 +19687,7 @@ case wxRadioBox_new: { // wxRadioBox::wxRadioBox
choicesASz += *choicesTemp+4;
}
bp += (8-((4+ choicesASz) & 7 )) & 7;
- while( * (int*) bp) { switch (* (int*) bp) {
+ while( * (int*) bp) { switch (* (int*) bp) {
case 1: {bp += 4;
majorDim = (int)*(int *) bp; bp += 4;
} break;
@@ -19647,13 +19697,13 @@ case wxRadioBox_new: { // wxRadioBox::wxRadioBox
case 3: {bp += 4;
val = (wxValidator *) getPtr(bp,memenv); bp += 4;
} break;
- }};
+ }};
wxRadioBox * Result = new EwxRadioBox(parent,(wxWindowID) *id,title,pos,size,choices,majorDim,style,*val);
newPtr((void *) Result, 0, memenv);
rt.addRef(getRef((void *)Result,memenv), "wxRadioBox");
- break;
+ break;
}
-case wxRadioBox_Create: { // wxRadioBox::Create
+case wxRadioBox_Create: { // wxRadioBox::Create
int majorDim=0;
long style=wxRA_HORIZONTAL;
const wxValidator * val= &wxDefaultValidator;
@@ -19679,7 +19729,7 @@ case wxRadioBox_Create: { // wxRadioBox::Create
choicesASz += *choicesTemp+4;
}
bp += (8-((4+ choicesASz) & 7 )) & 7;
- while( * (int*) bp) { switch (* (int*) bp) {
+ while( * (int*) bp) { switch (* (int*) bp) {
case 1: {bp += 4;
majorDim = (int)*(int *) bp; bp += 4;
} break;
@@ -19689,114 +19739,114 @@ case wxRadioBox_Create: { // wxRadioBox::Create
case 3: {bp += 4;
val = (wxValidator *) getPtr(bp,memenv); bp += 4;
} break;
- }};
+ }};
if(!This) throw wxe_badarg(0);
bool Result = This->Create(parent,(wxWindowID) *id,title,pos,size,choices,majorDim,style,*val);
rt.addBool(Result);
- break;
+ break;
}
-case wxRadioBox_Enable_2: { // wxRadioBox::Enable
+case wxRadioBox_Enable_2: { // wxRadioBox::Enable
bool enable=true;
wxRadioBox *This = (wxRadioBox *) getPtr(bp,memenv); bp += 4;
unsigned int * n = (unsigned int *) bp; bp += 4;
- while( * (int*) bp) { switch (* (int*) bp) {
+ while( * (int*) bp) { switch (* (int*) bp) {
case 1: {bp += 4;
enable = *(bool *) bp; bp += 4;
} break;
- }};
+ }};
if(!This) throw wxe_badarg(0);
bool Result = This->Enable((int) *n,enable);
rt.addBool(Result);
- break;
+ break;
}
-case wxRadioBox_Enable_1: { // wxRadioBox::Enable
+case wxRadioBox_Enable_1: { // wxRadioBox::Enable
bool enable=true;
wxRadioBox *This = (wxRadioBox *) getPtr(bp,memenv); bp += 4;
bp += 4; /* Align */
- while( * (int*) bp) { switch (* (int*) bp) {
+ while( * (int*) bp) { switch (* (int*) bp) {
case 1: {bp += 4;
enable = *(bool *) bp; bp += 4;
} break;
- }};
+ }};
if(!This) throw wxe_badarg(0);
bool Result = This->Enable(enable);
rt.addBool(Result);
- break;
+ break;
}
-case wxRadioBox_GetSelection: { // wxRadioBox::GetSelection
+case wxRadioBox_GetSelection: { // wxRadioBox::GetSelection
wxRadioBox *This = (wxRadioBox *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
int Result = This->GetSelection();
rt.addInt(Result);
- break;
+ break;
}
-case wxRadioBox_GetString: { // wxRadioBox::GetString
+case wxRadioBox_GetString: { // wxRadioBox::GetString
wxRadioBox *This = (wxRadioBox *) getPtr(bp,memenv); bp += 4;
unsigned int * n = (unsigned int *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
wxString Result = This->GetString((int) *n);
rt.add(Result);
- break;
+ break;
}
-case wxRadioBox_SetSelection: { // wxRadioBox::SetSelection
+case wxRadioBox_SetSelection: { // wxRadioBox::SetSelection
wxRadioBox *This = (wxRadioBox *) getPtr(bp,memenv); bp += 4;
int * n = (int *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
This->SetSelection((int) *n);
- break;
+ break;
}
-case wxRadioBox_Show_2: { // wxRadioBox::Show
+case wxRadioBox_Show_2: { // wxRadioBox::Show
bool show=true;
wxRadioBox *This = (wxRadioBox *) getPtr(bp,memenv); bp += 4;
unsigned int * n = (unsigned int *) bp; bp += 4;
- while( * (int*) bp) { switch (* (int*) bp) {
+ while( * (int*) bp) { switch (* (int*) bp) {
case 1: {bp += 4;
show = *(bool *) bp; bp += 4;
} break;
- }};
+ }};
if(!This) throw wxe_badarg(0);
bool Result = This->Show((int) *n,show);
rt.addBool(Result);
- break;
+ break;
}
-case wxRadioBox_Show_1: { // wxRadioBox::Show
+case wxRadioBox_Show_1: { // wxRadioBox::Show
bool show=true;
wxRadioBox *This = (wxRadioBox *) getPtr(bp,memenv); bp += 4;
bp += 4; /* Align */
- while( * (int*) bp) { switch (* (int*) bp) {
+ while( * (int*) bp) { switch (* (int*) bp) {
case 1: {bp += 4;
show = *(bool *) bp; bp += 4;
} break;
- }};
+ }};
if(!This) throw wxe_badarg(0);
bool Result = This->Show(show);
rt.addBool(Result);
- break;
+ break;
}
-case wxRadioBox_GetColumnCount: { // wxRadioBox::GetColumnCount
+case wxRadioBox_GetColumnCount: { // wxRadioBox::GetColumnCount
wxRadioBox *This = (wxRadioBox *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
int Result = This->GetColumnCount();
rt.addUint(Result);
- break;
+ break;
}
-case wxRadioBox_GetItemHelpText: { // wxRadioBox::GetItemHelpText
+case wxRadioBox_GetItemHelpText: { // wxRadioBox::GetItemHelpText
wxRadioBox *This = (wxRadioBox *) getPtr(bp,memenv); bp += 4;
unsigned int * n = (unsigned int *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
wxString Result = This->GetItemHelpText((int) *n);
rt.add(Result);
- break;
+ break;
}
-case wxRadioBox_GetItemToolTip: { // wxRadioBox::GetItemToolTip
+case wxRadioBox_GetItemToolTip: { // wxRadioBox::GetItemToolTip
wxRadioBox *This = (wxRadioBox *) getPtr(bp,memenv); bp += 4;
unsigned int * item = (unsigned int *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
wxToolTip * Result = (wxToolTip*)This->GetItemToolTip((int) *item);
rt.addRef(getRef((void *)Result,memenv), "wxToolTip");
- break;
+ break;
}
-case wxRadioBox_GetItemFromPoint: { // wxRadioBox::GetItemFromPoint
+case wxRadioBox_GetItemFromPoint: { // wxRadioBox::GetItemFromPoint
wxRadioBox *This = (wxRadioBox *) getPtr(bp,memenv); bp += 4;
int * ptX = (int *) bp; bp += 4;
int * ptY = (int *) bp; bp += 4;
@@ -19804,32 +19854,32 @@ case wxRadioBox_GetItemFromPoint: { // wxRadioBox::GetItemFromPoint
if(!This) throw wxe_badarg(0);
int Result = This->GetItemFromPoint(pt);
rt.addInt(Result);
- break;
+ break;
}
-case wxRadioBox_GetRowCount: { // wxRadioBox::GetRowCount
+case wxRadioBox_GetRowCount: { // wxRadioBox::GetRowCount
wxRadioBox *This = (wxRadioBox *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
int Result = This->GetRowCount();
rt.addUint(Result);
- break;
+ break;
}
-case wxRadioBox_IsItemEnabled: { // wxRadioBox::IsItemEnabled
+case wxRadioBox_IsItemEnabled: { // wxRadioBox::IsItemEnabled
wxRadioBox *This = (wxRadioBox *) getPtr(bp,memenv); bp += 4;
unsigned int * n = (unsigned int *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
bool Result = This->IsItemEnabled((int) *n);
rt.addBool(Result);
- break;
+ break;
}
-case wxRadioBox_IsItemShown: { // wxRadioBox::IsItemShown
+case wxRadioBox_IsItemShown: { // wxRadioBox::IsItemShown
wxRadioBox *This = (wxRadioBox *) getPtr(bp,memenv); bp += 4;
unsigned int * n = (unsigned int *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
bool Result = This->IsItemShown((int) *n);
rt.addBool(Result);
- break;
+ break;
}
-case wxRadioBox_SetItemHelpText: { // wxRadioBox::SetItemHelpText
+case wxRadioBox_SetItemHelpText: { // wxRadioBox::SetItemHelpText
wxRadioBox *This = (wxRadioBox *) getPtr(bp,memenv); bp += 4;
unsigned int * n = (unsigned int *) bp; bp += 4;
int * helpTextLen = (int *) bp; bp += 4;
@@ -19837,9 +19887,9 @@ case wxRadioBox_SetItemHelpText: { // wxRadioBox::SetItemHelpText
bp += *helpTextLen+((8-((4+ *helpTextLen) & 7)) & 7);
if(!This) throw wxe_badarg(0);
This->SetItemHelpText((int) *n,helpText);
- break;
+ break;
}
-case wxRadioBox_SetItemToolTip: { // wxRadioBox::SetItemToolTip
+case wxRadioBox_SetItemToolTip: { // wxRadioBox::SetItemToolTip
wxRadioBox *This = (wxRadioBox *) getPtr(bp,memenv); bp += 4;
unsigned int * item = (unsigned int *) bp; bp += 4;
int * textLen = (int *) bp; bp += 4;
@@ -19847,15 +19897,15 @@ case wxRadioBox_SetItemToolTip: { // wxRadioBox::SetItemToolTip
bp += *textLen+((8-((4+ *textLen) & 7)) & 7);
if(!This) throw wxe_badarg(0);
This->SetItemToolTip((int) *item,text);
- break;
+ break;
}
-case wxRadioButton_new_0: { // wxRadioButton::wxRadioButton
+case wxRadioButton_new_0: { // wxRadioButton::wxRadioButton
wxRadioButton * Result = new EwxRadioButton();
newPtr((void *) Result, 0, memenv);
rt.addRef(getRef((void *)Result,memenv), "wxRadioButton");
- break;
+ break;
}
-case wxRadioButton_new_4: { // wxRadioButton::wxRadioButton
+case wxRadioButton_new_4: { // wxRadioButton::wxRadioButton
wxPoint pos= wxDefaultPosition;
wxSize size= wxDefaultSize;
long style=0;
@@ -19865,7 +19915,7 @@ case wxRadioButton_new_4: { // wxRadioButton::wxRadioButton
int * labelLen = (int *) bp; bp += 4;
wxString label = wxString(bp, wxConvUTF8);
bp += *labelLen+((8-((4+ *labelLen) & 7)) & 7);
- while( * (int*) bp) { switch (* (int*) bp) {
+ while( * (int*) bp) { switch (* (int*) bp) {
case 1: {bp += 4;
int * posX = (int *) bp; bp += 4;
int * posY = (int *) bp; bp += 4;
@@ -19884,13 +19934,13 @@ case wxRadioButton_new_4: { // wxRadioButton::wxRadioButton
case 4: {bp += 4;
validator = (wxValidator *) getPtr(bp,memenv); bp += 4;
} break;
- }};
+ }};
wxRadioButton * Result = new EwxRadioButton(parent,(wxWindowID) *id,label,pos,size,style,*validator);
newPtr((void *) Result, 0, memenv);
rt.addRef(getRef((void *)Result,memenv), "wxRadioButton");
- break;
+ break;
}
-case wxRadioButton_Create: { // wxRadioButton::Create
+case wxRadioButton_Create: { // wxRadioButton::Create
wxPoint pos= wxDefaultPosition;
wxSize size= wxDefaultSize;
long style=0;
@@ -19901,7 +19951,7 @@ case wxRadioButton_Create: { // wxRadioButton::Create
int * labelLen = (int *) bp; bp += 4;
wxString label = wxString(bp, wxConvUTF8);
bp += *labelLen+((8-((0+ *labelLen) & 7)) & 7);
- while( * (int*) bp) { switch (* (int*) bp) {
+ while( * (int*) bp) { switch (* (int*) bp) {
case 1: {bp += 4;
int * posX = (int *) bp; bp += 4;
int * posY = (int *) bp; bp += 4;
@@ -19920,27 +19970,27 @@ case wxRadioButton_Create: { // wxRadioButton::Create
case 4: {bp += 4;
validator = (wxValidator *) getPtr(bp,memenv); bp += 4;
} break;
- }};
+ }};
if(!This) throw wxe_badarg(0);
bool Result = This->Create(parent,(wxWindowID) *id,label,pos,size,style,*validator);
rt.addBool(Result);
- break;
+ break;
}
-case wxRadioButton_GetValue: { // wxRadioButton::GetValue
+case wxRadioButton_GetValue: { // wxRadioButton::GetValue
wxRadioButton *This = (wxRadioButton *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
bool Result = This->GetValue();
rt.addBool(Result);
- break;
+ break;
}
-case wxRadioButton_SetValue: { // wxRadioButton::SetValue
+case wxRadioButton_SetValue: { // wxRadioButton::SetValue
wxRadioButton *This = (wxRadioButton *) getPtr(bp,memenv); bp += 4;
bool * val = (bool *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
This->SetValue((bool) *val);
- break;
+ break;
}
-case wxSlider_new_6: { // wxSlider::wxSlider
+case wxSlider_new_6: { // wxSlider::wxSlider
wxPoint pos= wxDefaultPosition;
wxSize size= wxDefaultSize;
long style=wxSL_HORIZONTAL;
@@ -19951,7 +20001,7 @@ case wxSlider_new_6: { // wxSlider::wxSlider
int * minValue = (int *) bp; bp += 4;
int * maxValue = (int *) bp; bp += 4;
bp += 4; /* Align */
- while( * (int*) bp) { switch (* (int*) bp) {
+ while( * (int*) bp) { switch (* (int*) bp) {
case 1: {bp += 4;
int * posX = (int *) bp; bp += 4;
int * posY = (int *) bp; bp += 4;
@@ -19970,19 +20020,19 @@ case wxSlider_new_6: { // wxSlider::wxSlider
case 4: {bp += 4;
validator = (wxValidator *) getPtr(bp,memenv); bp += 4;
} break;
- }};
+ }};
wxSlider * Result = new EwxSlider(parent,(wxWindowID) *id,(int) *value,(int) *minValue,(int) *maxValue,pos,size,style,*validator);
newPtr((void *) Result, 0, memenv);
rt.addRef(getRef((void *)Result,memenv), "wxSlider");
- break;
+ break;
}
-case wxSlider_new_0: { // wxSlider::wxSlider
+case wxSlider_new_0: { // wxSlider::wxSlider
wxSlider * Result = new EwxSlider();
newPtr((void *) Result, 0, memenv);
rt.addRef(getRef((void *)Result,memenv), "wxSlider");
- break;
+ break;
}
-case wxSlider_Create: { // wxSlider::Create
+case wxSlider_Create: { // wxSlider::Create
wxPoint pos= wxDefaultPosition;
wxSize size= wxDefaultSize;
long style=wxSL_HORIZONTAL;
@@ -19993,7 +20043,7 @@ case wxSlider_Create: { // wxSlider::Create
int * value = (int *) bp; bp += 4;
int * minValue = (int *) bp; bp += 4;
int * maxValue = (int *) bp; bp += 4;
- while( * (int*) bp) { switch (* (int*) bp) {
+ while( * (int*) bp) { switch (* (int*) bp) {
case 1: {bp += 4;
int * posX = (int *) bp; bp += 4;
int * posY = (int *) bp; bp += 4;
@@ -20012,91 +20062,91 @@ case wxSlider_Create: { // wxSlider::Create
case 4: {bp += 4;
validator = (wxValidator *) getPtr(bp,memenv); bp += 4;
} break;
- }};
+ }};
if(!This) throw wxe_badarg(0);
bool Result = This->Create(parent,(wxWindowID) *id,(int) *value,(int) *minValue,(int) *maxValue,pos,size,style,*validator);
rt.addBool(Result);
- break;
+ break;
}
-case wxSlider_GetLineSize: { // wxSlider::GetLineSize
+case wxSlider_GetLineSize: { // wxSlider::GetLineSize
wxSlider *This = (wxSlider *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
int Result = This->GetLineSize();
rt.addInt(Result);
- break;
+ break;
}
-case wxSlider_GetMax: { // wxSlider::GetMax
+case wxSlider_GetMax: { // wxSlider::GetMax
wxSlider *This = (wxSlider *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
int Result = This->GetMax();
rt.addInt(Result);
- break;
+ break;
}
-case wxSlider_GetMin: { // wxSlider::GetMin
+case wxSlider_GetMin: { // wxSlider::GetMin
wxSlider *This = (wxSlider *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
int Result = This->GetMin();
rt.addInt(Result);
- break;
+ break;
}
-case wxSlider_GetPageSize: { // wxSlider::GetPageSize
+case wxSlider_GetPageSize: { // wxSlider::GetPageSize
wxSlider *This = (wxSlider *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
int Result = This->GetPageSize();
rt.addInt(Result);
- break;
+ break;
}
-case wxSlider_GetThumbLength: { // wxSlider::GetThumbLength
+case wxSlider_GetThumbLength: { // wxSlider::GetThumbLength
wxSlider *This = (wxSlider *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
int Result = This->GetThumbLength();
rt.addInt(Result);
- break;
+ break;
}
-case wxSlider_GetValue: { // wxSlider::GetValue
+case wxSlider_GetValue: { // wxSlider::GetValue
wxSlider *This = (wxSlider *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
int Result = This->GetValue();
rt.addInt(Result);
- break;
+ break;
}
-case wxSlider_SetLineSize: { // wxSlider::SetLineSize
+case wxSlider_SetLineSize: { // wxSlider::SetLineSize
wxSlider *This = (wxSlider *) getPtr(bp,memenv); bp += 4;
int * lineSize = (int *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
This->SetLineSize((int) *lineSize);
- break;
+ break;
}
-case wxSlider_SetPageSize: { // wxSlider::SetPageSize
+case wxSlider_SetPageSize: { // wxSlider::SetPageSize
wxSlider *This = (wxSlider *) getPtr(bp,memenv); bp += 4;
int * pageSize = (int *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
This->SetPageSize((int) *pageSize);
- break;
+ break;
}
-case wxSlider_SetRange: { // wxSlider::SetRange
+case wxSlider_SetRange: { // wxSlider::SetRange
wxSlider *This = (wxSlider *) getPtr(bp,memenv); bp += 4;
int * minValue = (int *) bp; bp += 4;
int * maxValue = (int *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
This->SetRange((int) *minValue,(int) *maxValue);
- break;
+ break;
}
-case wxSlider_SetThumbLength: { // wxSlider::SetThumbLength
+case wxSlider_SetThumbLength: { // wxSlider::SetThumbLength
wxSlider *This = (wxSlider *) getPtr(bp,memenv); bp += 4;
int * lenPixels = (int *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
This->SetThumbLength((int) *lenPixels);
- break;
+ break;
}
-case wxSlider_SetValue: { // wxSlider::SetValue
+case wxSlider_SetValue: { // wxSlider::SetValue
wxSlider *This = (wxSlider *) getPtr(bp,memenv); bp += 4;
int * value = (int *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
This->SetValue((int) *value);
- break;
+ break;
}
-case wxDialog_new_4: { // wxDialog::wxDialog
+case wxDialog_new_4: { // wxDialog::wxDialog
wxPoint pos= wxDefaultPosition;
wxSize size= wxDefaultSize;
long style=wxDEFAULT_DIALOG_STYLE;
@@ -20105,7 +20155,7 @@ case wxDialog_new_4: { // wxDialog::wxDialog
int * titleLen = (int *) bp; bp += 4;
wxString title = wxString(bp, wxConvUTF8);
bp += *titleLen+((8-((4+ *titleLen) & 7)) & 7);
- while( * (int*) bp) { switch (* (int*) bp) {
+ while( * (int*) bp) { switch (* (int*) bp) {
case 1: {bp += 4;
int * posX = (int *) bp; bp += 4;
int * posY = (int *) bp; bp += 4;
@@ -20121,19 +20171,19 @@ case wxDialog_new_4: { // wxDialog::wxDialog
case 3: {bp += 4;
style = (long)*(int *) bp; bp += 4;
} break;
- }};
+ }};
wxDialog * Result = new EwxDialog(parent,(wxWindowID) *id,title,pos,size,style);
newPtr((void *) Result, 2, memenv);
rt.addRef(getRef((void *)Result,memenv), "wxDialog");
- break;
+ break;
}
-case wxDialog_new_0: { // wxDialog::wxDialog
+case wxDialog_new_0: { // wxDialog::wxDialog
wxDialog * Result = new EwxDialog();
newPtr((void *) Result, 2, memenv);
rt.addRef(getRef((void *)Result,memenv), "wxDialog");
- break;
+ break;
}
-case wxDialog_Create: { // wxDialog::Create
+case wxDialog_Create: { // wxDialog::Create
wxPoint pos= wxDefaultPosition;
wxSize size= wxDefaultSize;
long style=wxDEFAULT_DIALOG_STYLE;
@@ -20143,7 +20193,7 @@ case wxDialog_Create: { // wxDialog::Create
int * titleLen = (int *) bp; bp += 4;
wxString title = wxString(bp, wxConvUTF8);
bp += *titleLen+((8-((0+ *titleLen) & 7)) & 7);
- while( * (int*) bp) { switch (* (int*) bp) {
+ while( * (int*) bp) { switch (* (int*) bp) {
case 1: {bp += 4;
int * posX = (int *) bp; bp += 4;
int * posY = (int *) bp; bp += 4;
@@ -20159,175 +20209,175 @@ case wxDialog_Create: { // wxDialog::Create
case 3: {bp += 4;
style = (long)*(int *) bp; bp += 4;
} break;
- }};
+ }};
if(!This) throw wxe_badarg(0);
bool Result = This->Create(parent,(wxWindowID) *id,title,pos,size,style);
rt.addBool(Result);
- break;
+ break;
}
-case wxDialog_CreateButtonSizer: { // wxDialog::CreateButtonSizer
+case wxDialog_CreateButtonSizer: { // wxDialog::CreateButtonSizer
wxDialog *This = (wxDialog *) getPtr(bp,memenv); bp += 4;
int * flags = (int *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
wxSizer * Result = (wxSizer*)This->CreateButtonSizer((long) *flags);
rt.addRef(getRef((void *)Result,memenv), "wxSizer");
- break;
+ break;
}
-case wxDialog_CreateStdDialogButtonSizer: { // wxDialog::CreateStdDialogButtonSizer
+case wxDialog_CreateStdDialogButtonSizer: { // wxDialog::CreateStdDialogButtonSizer
wxDialog *This = (wxDialog *) getPtr(bp,memenv); bp += 4;
int * flags = (int *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
wxStdDialogButtonSizer * Result = (wxStdDialogButtonSizer*)This->CreateStdDialogButtonSizer((long) *flags);
rt.addRef(getRef((void *)Result,memenv), "wxStdDialogButtonSizer");
- break;
+ break;
}
-case wxDialog_EndModal: { // wxDialog::EndModal
+case wxDialog_EndModal: { // wxDialog::EndModal
wxDialog *This = (wxDialog *) getPtr(bp,memenv); bp += 4;
int * retCode = (int *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
This->EndModal((int) *retCode);
- break;
+ break;
}
-case wxDialog_GetAffirmativeId: { // wxDialog::GetAffirmativeId
+case wxDialog_GetAffirmativeId: { // wxDialog::GetAffirmativeId
wxDialog *This = (wxDialog *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
int Result = This->GetAffirmativeId();
rt.addInt(Result);
- break;
+ break;
}
-case wxDialog_GetReturnCode: { // wxDialog::GetReturnCode
+case wxDialog_GetReturnCode: { // wxDialog::GetReturnCode
wxDialog *This = (wxDialog *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
int Result = This->GetReturnCode();
rt.addInt(Result);
- break;
+ break;
}
-case wxDialog_IsModal: { // wxDialog::IsModal
+case wxDialog_IsModal: { // wxDialog::IsModal
wxDialog *This = (wxDialog *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
bool Result = This->IsModal();
rt.addBool(Result);
- break;
+ break;
}
-case wxDialog_SetAffirmativeId: { // wxDialog::SetAffirmativeId
+case wxDialog_SetAffirmativeId: { // wxDialog::SetAffirmativeId
wxDialog *This = (wxDialog *) getPtr(bp,memenv); bp += 4;
int * affirmativeId = (int *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
This->SetAffirmativeId((int) *affirmativeId);
- break;
+ break;
}
-case wxDialog_SetReturnCode: { // wxDialog::SetReturnCode
+case wxDialog_SetReturnCode: { // wxDialog::SetReturnCode
wxDialog *This = (wxDialog *) getPtr(bp,memenv); bp += 4;
int * returnCode = (int *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
This->SetReturnCode((int) *returnCode);
- break;
+ break;
}
-case wxDialog_Show: { // wxDialog::Show
+case wxDialog_Show: { // wxDialog::Show
bool show=TRUE;
wxDialog *This = (wxDialog *) getPtr(bp,memenv); bp += 4;
bp += 4; /* Align */
- while( * (int*) bp) { switch (* (int*) bp) {
+ while( * (int*) bp) { switch (* (int*) bp) {
case 1: {bp += 4;
show = *(bool *) bp; bp += 4;
} break;
- }};
+ }};
if(!This) throw wxe_badarg(0);
bool Result = This->Show(show);
rt.addBool(Result);
- break;
+ break;
}
-case wxDialog_ShowModal: { // wxDialog::ShowModal
+case wxDialog_ShowModal: { // wxDialog::ShowModal
wxDialog *This = (wxDialog *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
int Result = This->ShowModal();
rt.addInt(Result);
- break;
+ break;
}
-case wxColourDialog_new_0: { // wxColourDialog::wxColourDialog
+case wxColourDialog_new_0: { // wxColourDialog::wxColourDialog
wxColourDialog * Result = new EwxColourDialog();
newPtr((void *) Result, 2, memenv);
rt.addRef(getRef((void *)Result,memenv), "wxColourDialog");
- break;
+ break;
}
-case wxColourDialog_new_2: { // wxColourDialog::wxColourDialog
+case wxColourDialog_new_2: { // wxColourDialog::wxColourDialog
wxColourData * data=(wxColourData *) NULL;
wxWindow *parent = (wxWindow *) getPtr(bp,memenv); bp += 4;
bp += 4; /* Align */
- while( * (int*) bp) { switch (* (int*) bp) {
+ while( * (int*) bp) { switch (* (int*) bp) {
case 1: {bp += 4;
data = (wxColourData *) getPtr(bp,memenv); bp += 4;
} break;
- }};
+ }};
wxColourDialog * Result = new EwxColourDialog(parent,data);
newPtr((void *) Result, 2, memenv);
rt.addRef(getRef((void *)Result,memenv), "wxColourDialog");
- break;
+ break;
}
-case wxColourDialog_Create: { // wxColourDialog::Create
+case wxColourDialog_Create: { // wxColourDialog::Create
wxColourData * data=(wxColourData *) NULL;
wxColourDialog *This = (wxColourDialog *) getPtr(bp,memenv); bp += 4;
wxWindow *parent = (wxWindow *) getPtr(bp,memenv); bp += 4;
- while( * (int*) bp) { switch (* (int*) bp) {
+ while( * (int*) bp) { switch (* (int*) bp) {
case 1: {bp += 4;
data = (wxColourData *) getPtr(bp,memenv); bp += 4;
} break;
- }};
+ }};
if(!This) throw wxe_badarg(0);
bool Result = This->Create(parent,data);
rt.addBool(Result);
- break;
+ break;
}
-case wxColourDialog_GetColourData: { // wxColourDialog::GetColourData
+case wxColourDialog_GetColourData: { // wxColourDialog::GetColourData
wxColourDialog *This = (wxColourDialog *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
wxColourData * Result = &This->GetColourData();
rt.addRef(getRef((void *)Result,memenv), "wxColourData");
- break;
+ break;
}
-case wxColourData_new_0: { // wxColourData::wxColourData
+case wxColourData_new_0: { // wxColourData::wxColourData
wxColourData * Result = new EwxColourData();
newPtr((void *) Result, 1, memenv);
rt.addRef(getRef((void *)Result,memenv), "wxColourData");
- break;
+ break;
}
-case wxColourData_new_1: { // wxColourData::wxColourData
+case wxColourData_new_1: { // wxColourData::wxColourData
wxColourData *data = (wxColourData *) getPtr(bp,memenv); bp += 4;
wxColourData * Result = new EwxColourData(*data);
newPtr((void *) Result, 1, memenv);
rt.addRef(getRef((void *)Result,memenv), "wxColourData");
- break;
+ break;
}
-case wxColourData_GetChooseFull: { // wxColourData::GetChooseFull
+case wxColourData_GetChooseFull: { // wxColourData::GetChooseFull
wxColourData *This = (wxColourData *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
bool Result = This->GetChooseFull();
rt.addBool(Result);
- break;
+ break;
}
-case wxColourData_GetColour: { // wxColourData::GetColour
+case wxColourData_GetColour: { // wxColourData::GetColour
wxColourData *This = (wxColourData *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
const wxColour * Result = &This->GetColour();
rt.add((*Result));
- break;
+ break;
}
-case wxColourData_GetCustomColour: { // wxColourData::GetCustomColour
+case wxColourData_GetCustomColour: { // wxColourData::GetCustomColour
wxColourData *This = (wxColourData *) getPtr(bp,memenv); bp += 4;
int * i = (int *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
wxColour Result = This->GetCustomColour((int) *i);
rt.add(Result);
- break;
+ break;
}
-case wxColourData_SetChooseFull: { // wxColourData::SetChooseFull
+case wxColourData_SetChooseFull: { // wxColourData::SetChooseFull
wxColourData *This = (wxColourData *) getPtr(bp,memenv); bp += 4;
bool * flag = (bool *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
This->SetChooseFull((bool) *flag);
- break;
+ break;
}
-case wxColourData_SetColour: { // wxColourData::SetColour
+case wxColourData_SetColour: { // wxColourData::SetColour
wxColourData *This = (wxColourData *) getPtr(bp,memenv); bp += 4;
int * colourR = (int *) bp; bp += 4;
int * colourG = (int *) bp; bp += 4;
@@ -20336,9 +20386,9 @@ case wxColourData_SetColour: { // wxColourData::SetColour
wxColour colour = wxColour(*colourR,*colourG,*colourB,*colourA);
if(!This) throw wxe_badarg(0);
This->SetColour(colour);
- break;
+ break;
}
-case wxColourData_SetCustomColour: { // wxColourData::SetCustomColour
+case wxColourData_SetCustomColour: { // wxColourData::SetCustomColour
wxColourData *This = (wxColourData *) getPtr(bp,memenv); bp += 4;
int * i = (int *) bp; bp += 4;
int * colourR = (int *) bp; bp += 4;
@@ -20348,41 +20398,41 @@ case wxColourData_SetCustomColour: { // wxColourData::SetCustomColour
wxColour colour = wxColour(*colourR,*colourG,*colourB,*colourA);
if(!This) throw wxe_badarg(0);
This->SetCustomColour((int) *i,colour);
- break;
+ break;
}
-case wxPalette_new_0: { // wxPalette::wxPalette
+case wxPalette_new_0: { // wxPalette::wxPalette
wxPalette * Result = new EwxPalette();
newPtr((void *) Result, 1, memenv);
rt.addRef(getRef((void *)Result,memenv), "wxPalette");
- break;
+ break;
}
-case wxPalette_new_4: { // wxPalette::wxPalette
- const unsigned char * red = (const unsigned char*) Ecmd.bin[0]->base;
- const unsigned char * green = (const unsigned char*) Ecmd.bin[1]->base;
- const unsigned char * blue = (const unsigned char*) Ecmd.bin[2]->base;
+case wxPalette_new_4: { // wxPalette::wxPalette
+ const unsigned char * red = (const unsigned char*) Ecmd.bin[0]->base;
+ const unsigned char * green = (const unsigned char*) Ecmd.bin[1]->base;
+ const unsigned char * blue = (const unsigned char*) Ecmd.bin[2]->base;
wxPalette * Result = new EwxPalette(Ecmd.bin[0]->size,red,green,blue);
newPtr((void *) Result, 1, memenv);
rt.addRef(getRef((void *)Result,memenv), "wxPalette");
- break;
+ break;
}
-case wxPalette_Create: { // wxPalette::Create
+case wxPalette_Create: { // wxPalette::Create
wxPalette *This = (wxPalette *) getPtr(bp,memenv); bp += 4;
- const unsigned char * red = (const unsigned char*) Ecmd.bin[0]->base;
- const unsigned char * green = (const unsigned char*) Ecmd.bin[1]->base;
- const unsigned char * blue = (const unsigned char*) Ecmd.bin[2]->base;
+ const unsigned char * red = (const unsigned char*) Ecmd.bin[0]->base;
+ const unsigned char * green = (const unsigned char*) Ecmd.bin[1]->base;
+ const unsigned char * blue = (const unsigned char*) Ecmd.bin[2]->base;
if(!This) throw wxe_badarg(0);
bool Result = This->Create(Ecmd.bin[0]->size,red,green,blue);
rt.addBool(Result);
- break;
+ break;
}
-case wxPalette_GetColoursCount: { // wxPalette::GetColoursCount
+case wxPalette_GetColoursCount: { // wxPalette::GetColoursCount
wxPalette *This = (wxPalette *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
int Result = This->GetColoursCount();
rt.addInt(Result);
- break;
+ break;
}
-case wxPalette_GetPixel: { // wxPalette::GetPixel
+case wxPalette_GetPixel: { // wxPalette::GetPixel
wxPalette *This = (wxPalette *) getPtr(bp,memenv); bp += 4;
unsigned int * red = (unsigned int *) bp; bp += 4;
unsigned int * green = (unsigned int *) bp; bp += 4;
@@ -20390,9 +20440,9 @@ case wxPalette_GetPixel: { // wxPalette::GetPixel
if(!This) throw wxe_badarg(0);
int Result = This->GetPixel((char) *red,(char) *green,(char) *blue);
rt.addInt(Result);
- break;
+ break;
}
-case wxPalette_GetRGB: { // wxPalette::GetRGB
+case wxPalette_GetRGB: { // wxPalette::GetRGB
unsigned char red;
unsigned char green;
unsigned char blue;
@@ -20405,16 +20455,16 @@ case wxPalette_GetRGB: { // wxPalette::GetRGB
rt.addUint(green);
rt.addUint(blue);
rt.addTupleCount(4);
- break;
+ break;
}
-case wxPalette_IsOk: { // wxPalette::IsOk
+case wxPalette_IsOk: { // wxPalette::IsOk
wxPalette *This = (wxPalette *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
bool Result = This->IsOk();
rt.addBool(Result);
- break;
+ break;
}
-case wxDirDialog_new: { // wxDirDialog::wxDirDialog
+case wxDirDialog_new: { // wxDirDialog::wxDirDialog
wxString title= wxDirSelectorPromptStr;
wxString defaultPath= wxEmptyString;
long style=(wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER);
@@ -20422,7 +20472,7 @@ case wxDirDialog_new: { // wxDirDialog::wxDirDialog
wxSize sz= wxDefaultSize;
wxWindow *parent = (wxWindow *) getPtr(bp,memenv); bp += 4;
bp += 4; /* Align */
- while( * (int*) bp) { switch (* (int*) bp) {
+ while( * (int*) bp) { switch (* (int*) bp) {
case 1: {bp += 4;
int * titleLen = (int *) bp; bp += 4;
title = wxString(bp, wxConvUTF8);
@@ -20448,45 +20498,45 @@ case wxDirDialog_new: { // wxDirDialog::wxDirDialog
sz = wxSize(*szW,*szH);
bp += 4; /* Align */
} break;
- }};
+ }};
wxDirDialog * Result = new EwxDirDialog(parent,title,defaultPath,style,pos,sz);
newPtr((void *) Result, 2, memenv);
rt.addRef(getRef((void *)Result,memenv), "wxDirDialog");
- break;
+ break;
}
-case wxDirDialog_GetPath: { // wxDirDialog::GetPath
+case wxDirDialog_GetPath: { // wxDirDialog::GetPath
wxDirDialog *This = (wxDirDialog *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
wxString Result = This->GetPath();
rt.add(Result);
- break;
+ break;
}
-case wxDirDialog_GetMessage: { // wxDirDialog::GetMessage
+case wxDirDialog_GetMessage: { // wxDirDialog::GetMessage
wxDirDialog *This = (wxDirDialog *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
wxString Result = This->GetMessage();
rt.add(Result);
- break;
+ break;
}
-case wxDirDialog_SetMessage: { // wxDirDialog::SetMessage
+case wxDirDialog_SetMessage: { // wxDirDialog::SetMessage
wxDirDialog *This = (wxDirDialog *) getPtr(bp,memenv); bp += 4;
int * messageLen = (int *) bp; bp += 4;
wxString message = wxString(bp, wxConvUTF8);
bp += *messageLen+((8-((0+ *messageLen) & 7)) & 7);
if(!This) throw wxe_badarg(0);
This->SetMessage(message);
- break;
+ break;
}
-case wxDirDialog_SetPath: { // wxDirDialog::SetPath
+case wxDirDialog_SetPath: { // wxDirDialog::SetPath
wxDirDialog *This = (wxDirDialog *) getPtr(bp,memenv); bp += 4;
int * pathLen = (int *) bp; bp += 4;
wxString path = wxString(bp, wxConvUTF8);
bp += *pathLen+((8-((0+ *pathLen) & 7)) & 7);
if(!This) throw wxe_badarg(0);
This->SetPath(path);
- break;
+ break;
}
-case wxFileDialog_new: { // wxFileDialog::wxFileDialog
+case wxFileDialog_new: { // wxFileDialog::wxFileDialog
wxString message= wxFileSelectorPromptStr;
wxString defaultDir= wxEmptyString;
wxString defaultFile= wxEmptyString;
@@ -20496,7 +20546,7 @@ case wxFileDialog_new: { // wxFileDialog::wxFileDialog
wxSize sz= wxDefaultSize;
wxWindow *parent = (wxWindow *) getPtr(bp,memenv); bp += 4;
bp += 4; /* Align */
- while( * (int*) bp) { switch (* (int*) bp) {
+ while( * (int*) bp) { switch (* (int*) bp) {
case 1: {bp += 4;
int * messageLen = (int *) bp; bp += 4;
message = wxString(bp, wxConvUTF8);
@@ -20532,233 +20582,225 @@ case wxFileDialog_new: { // wxFileDialog::wxFileDialog
sz = wxSize(*szW,*szH);
bp += 4; /* Align */
} break;
- }};
+ }};
wxFileDialog * Result = new EwxFileDialog(parent,message,defaultDir,defaultFile,wildCard,style,pos,sz);
newPtr((void *) Result, 2, memenv);
rt.addRef(getRef((void *)Result,memenv), "wxFileDialog");
- break;
+ break;
}
-case wxFileDialog_GetDirectory: { // wxFileDialog::GetDirectory
+case wxFileDialog_GetDirectory: { // wxFileDialog::GetDirectory
wxFileDialog *This = (wxFileDialog *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
wxString Result = This->GetDirectory();
rt.add(Result);
- break;
+ break;
}
-case wxFileDialog_GetFilename: { // wxFileDialog::GetFilename
+case wxFileDialog_GetFilename: { // wxFileDialog::GetFilename
wxFileDialog *This = (wxFileDialog *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
wxString Result = This->GetFilename();
rt.add(Result);
- break;
+ break;
}
-case wxFileDialog_GetFilenames: { // wxFileDialog::GetFilenames
+case wxFileDialog_GetFilenames: { // wxFileDialog::GetFilenames
wxArrayString files;
wxFileDialog *This = (wxFileDialog *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
This->GetFilenames(files);
rt.add(files);
- break;
+ break;
}
-case wxFileDialog_GetFilterIndex: { // wxFileDialog::GetFilterIndex
+case wxFileDialog_GetFilterIndex: { // wxFileDialog::GetFilterIndex
wxFileDialog *This = (wxFileDialog *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
int Result = This->GetFilterIndex();
rt.addInt(Result);
- break;
+ break;
}
-case wxFileDialog_GetMessage: { // wxFileDialog::GetMessage
+case wxFileDialog_GetMessage: { // wxFileDialog::GetMessage
wxFileDialog *This = (wxFileDialog *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
wxString Result = This->GetMessage();
rt.add(Result);
- break;
+ break;
}
-case wxFileDialog_GetPath: { // wxFileDialog::GetPath
+case wxFileDialog_GetPath: { // wxFileDialog::GetPath
wxFileDialog *This = (wxFileDialog *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
wxString Result = This->GetPath();
rt.add(Result);
- break;
+ break;
}
-case wxFileDialog_GetPaths: { // wxFileDialog::GetPaths
- wxFileDialog *This = (wxFileDialog *) getPtr(bp,memenv); bp += 4;
- int * pathsLen = (int *) bp; bp += 4;
+case wxFileDialog_GetPaths: { // wxFileDialog::GetPaths
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);
- break;
+ rt.add(paths);
+ break;
}
-case wxFileDialog_GetWildcard: { // wxFileDialog::GetWildcard
+case wxFileDialog_GetWildcard: { // wxFileDialog::GetWildcard
wxFileDialog *This = (wxFileDialog *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
wxString Result = This->GetWildcard();
rt.add(Result);
- break;
+ break;
}
-case wxFileDialog_SetDirectory: { // wxFileDialog::SetDirectory
+case wxFileDialog_SetDirectory: { // wxFileDialog::SetDirectory
wxFileDialog *This = (wxFileDialog *) getPtr(bp,memenv); bp += 4;
int * dirLen = (int *) bp; bp += 4;
wxString dir = wxString(bp, wxConvUTF8);
bp += *dirLen+((8-((0+ *dirLen) & 7)) & 7);
if(!This) throw wxe_badarg(0);
This->SetDirectory(dir);
- break;
+ break;
}
-case wxFileDialog_SetFilename: { // wxFileDialog::SetFilename
+case wxFileDialog_SetFilename: { // wxFileDialog::SetFilename
wxFileDialog *This = (wxFileDialog *) getPtr(bp,memenv); bp += 4;
int * nameLen = (int *) bp; bp += 4;
wxString name = wxString(bp, wxConvUTF8);
bp += *nameLen+((8-((0+ *nameLen) & 7)) & 7);
if(!This) throw wxe_badarg(0);
This->SetFilename(name);
- break;
+ break;
}
-case wxFileDialog_SetFilterIndex: { // wxFileDialog::SetFilterIndex
+case wxFileDialog_SetFilterIndex: { // wxFileDialog::SetFilterIndex
wxFileDialog *This = (wxFileDialog *) getPtr(bp,memenv); bp += 4;
int * filterIndex = (int *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
This->SetFilterIndex((int) *filterIndex);
- break;
+ break;
}
-case wxFileDialog_SetMessage: { // wxFileDialog::SetMessage
+case wxFileDialog_SetMessage: { // wxFileDialog::SetMessage
wxFileDialog *This = (wxFileDialog *) getPtr(bp,memenv); bp += 4;
int * messageLen = (int *) bp; bp += 4;
wxString message = wxString(bp, wxConvUTF8);
bp += *messageLen+((8-((0+ *messageLen) & 7)) & 7);
if(!This) throw wxe_badarg(0);
This->SetMessage(message);
- break;
+ break;
}
-case wxFileDialog_SetPath: { // wxFileDialog::SetPath
+case wxFileDialog_SetPath: { // wxFileDialog::SetPath
wxFileDialog *This = (wxFileDialog *) getPtr(bp,memenv); bp += 4;
int * pathLen = (int *) bp; bp += 4;
wxString path = wxString(bp, wxConvUTF8);
bp += *pathLen+((8-((0+ *pathLen) & 7)) & 7);
if(!This) throw wxe_badarg(0);
This->SetPath(path);
- break;
+ break;
}
-case wxFileDialog_SetWildcard: { // wxFileDialog::SetWildcard
+case wxFileDialog_SetWildcard: { // wxFileDialog::SetWildcard
wxFileDialog *This = (wxFileDialog *) getPtr(bp,memenv); bp += 4;
int * wildCardLen = (int *) bp; bp += 4;
wxString wildCard = wxString(bp, wxConvUTF8);
bp += *wildCardLen+((8-((0+ *wildCardLen) & 7)) & 7);
if(!This) throw wxe_badarg(0);
This->SetWildcard(wildCard);
- break;
+ break;
}
-case wxPickerBase_SetInternalMargin: { // wxPickerBase::SetInternalMargin
+case wxPickerBase_SetInternalMargin: { // wxPickerBase::SetInternalMargin
wxPickerBase *This = (wxPickerBase *) getPtr(bp,memenv); bp += 4;
int * newmargin = (int *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
This->SetInternalMargin((int) *newmargin);
- break;
+ break;
}
-case wxPickerBase_GetInternalMargin: { // wxPickerBase::GetInternalMargin
+case wxPickerBase_GetInternalMargin: { // wxPickerBase::GetInternalMargin
wxPickerBase *This = (wxPickerBase *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
int Result = This->GetInternalMargin();
rt.addInt(Result);
- break;
+ break;
}
-case wxPickerBase_SetTextCtrlProportion: { // wxPickerBase::SetTextCtrlProportion
+case wxPickerBase_SetTextCtrlProportion: { // wxPickerBase::SetTextCtrlProportion
wxPickerBase *This = (wxPickerBase *) getPtr(bp,memenv); bp += 4;
int * prop = (int *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
This->SetTextCtrlProportion((int) *prop);
- break;
+ break;
}
-case wxPickerBase_SetPickerCtrlProportion: { // wxPickerBase::SetPickerCtrlProportion
+case wxPickerBase_SetPickerCtrlProportion: { // wxPickerBase::SetPickerCtrlProportion
wxPickerBase *This = (wxPickerBase *) getPtr(bp,memenv); bp += 4;
int * prop = (int *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
This->SetPickerCtrlProportion((int) *prop);
- break;
+ break;
}
-case wxPickerBase_GetTextCtrlProportion: { // wxPickerBase::GetTextCtrlProportion
+case wxPickerBase_GetTextCtrlProportion: { // wxPickerBase::GetTextCtrlProportion
wxPickerBase *This = (wxPickerBase *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
int Result = This->GetTextCtrlProportion();
rt.addInt(Result);
- break;
+ break;
}
-case wxPickerBase_GetPickerCtrlProportion: { // wxPickerBase::GetPickerCtrlProportion
+case wxPickerBase_GetPickerCtrlProportion: { // wxPickerBase::GetPickerCtrlProportion
wxPickerBase *This = (wxPickerBase *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
int Result = This->GetPickerCtrlProportion();
rt.addInt(Result);
- break;
+ break;
}
-case wxPickerBase_HasTextCtrl: { // wxPickerBase::HasTextCtrl
+case wxPickerBase_HasTextCtrl: { // wxPickerBase::HasTextCtrl
wxPickerBase *This = (wxPickerBase *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
bool Result = This->HasTextCtrl();
rt.addBool(Result);
- break;
+ break;
}
-case wxPickerBase_GetTextCtrl: { // wxPickerBase::GetTextCtrl
+case wxPickerBase_GetTextCtrl: { // wxPickerBase::GetTextCtrl
wxPickerBase *This = (wxPickerBase *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
wxTextCtrl * Result = (wxTextCtrl*)This->GetTextCtrl();
rt.addRef(getRef((void *)Result,memenv), "wxTextCtrl");
- break;
+ break;
}
-case wxPickerBase_IsTextCtrlGrowable: { // wxPickerBase::IsTextCtrlGrowable
+case wxPickerBase_IsTextCtrlGrowable: { // wxPickerBase::IsTextCtrlGrowable
wxPickerBase *This = (wxPickerBase *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
bool Result = This->IsTextCtrlGrowable();
rt.addBool(Result);
- break;
+ break;
}
-case wxPickerBase_SetPickerCtrlGrowable: { // wxPickerBase::SetPickerCtrlGrowable
+case wxPickerBase_SetPickerCtrlGrowable: { // wxPickerBase::SetPickerCtrlGrowable
bool grow=true;
wxPickerBase *This = (wxPickerBase *) getPtr(bp,memenv); bp += 4;
bp += 4; /* Align */
- while( * (int*) bp) { switch (* (int*) bp) {
+ while( * (int*) bp) { switch (* (int*) bp) {
case 1: {bp += 4;
grow = *(bool *) bp; bp += 4;
} break;
- }};
+ }};
if(!This) throw wxe_badarg(0);
This->SetPickerCtrlGrowable(grow);
- break;
+ break;
}
-case wxPickerBase_SetTextCtrlGrowable: { // wxPickerBase::SetTextCtrlGrowable
+case wxPickerBase_SetTextCtrlGrowable: { // wxPickerBase::SetTextCtrlGrowable
bool grow=true;
wxPickerBase *This = (wxPickerBase *) getPtr(bp,memenv); bp += 4;
bp += 4; /* Align */
- while( * (int*) bp) { switch (* (int*) bp) {
+ while( * (int*) bp) { switch (* (int*) bp) {
case 1: {bp += 4;
grow = *(bool *) bp; bp += 4;
} break;
- }};
+ }};
if(!This) throw wxe_badarg(0);
This->SetTextCtrlGrowable(grow);
- break;
+ break;
}
-case wxPickerBase_IsPickerCtrlGrowable: { // wxPickerBase::IsPickerCtrlGrowable
+case wxPickerBase_IsPickerCtrlGrowable: { // wxPickerBase::IsPickerCtrlGrowable
wxPickerBase *This = (wxPickerBase *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
bool Result = This->IsPickerCtrlGrowable();
rt.addBool(Result);
- break;
+ break;
}
-case wxFilePickerCtrl_new_0: { // wxFilePickerCtrl::wxFilePickerCtrl
+case wxFilePickerCtrl_new_0: { // wxFilePickerCtrl::wxFilePickerCtrl
wxFilePickerCtrl * Result = new EwxFilePickerCtrl();
newPtr((void *) Result, 0, memenv);
rt.addRef(getRef((void *)Result,memenv), "wxFilePickerCtrl");
- break;
+ break;
}
-case wxFilePickerCtrl_new_3: { // wxFilePickerCtrl::wxFilePickerCtrl
+case wxFilePickerCtrl_new_3: { // wxFilePickerCtrl::wxFilePickerCtrl
wxString path= wxEmptyString;
wxString message= wxFileSelectorPromptStr;
wxString wildcard= wxFileSelectorDefaultWildcardStr;
@@ -20768,7 +20810,7 @@ case wxFilePickerCtrl_new_3: { // wxFilePickerCtrl::wxFilePickerCtrl
const wxValidator * validator= &wxDefaultValidator;
wxWindow *parent = (wxWindow *) getPtr(bp,memenv); bp += 4;
int * id = (int *) bp; bp += 4;
- while( * (int*) bp) { switch (* (int*) bp) {
+ while( * (int*) bp) { switch (* (int*) bp) {
case 1: {bp += 4;
int * pathLen = (int *) bp; bp += 4;
path = wxString(bp, wxConvUTF8);
@@ -20802,13 +20844,13 @@ case wxFilePickerCtrl_new_3: { // wxFilePickerCtrl::wxFilePickerCtrl
case 7: {bp += 4;
validator = (wxValidator *) getPtr(bp,memenv); bp += 4;
} break;
- }};
+ }};
wxFilePickerCtrl * Result = new EwxFilePickerCtrl(parent,(wxWindowID) *id,path,message,wildcard,pos,size,style,*validator);
newPtr((void *) Result, 0, memenv);
rt.addRef(getRef((void *)Result,memenv), "wxFilePickerCtrl");
- break;
+ break;
}
-case wxFilePickerCtrl_Create: { // wxFilePickerCtrl::Create
+case wxFilePickerCtrl_Create: { // wxFilePickerCtrl::Create
wxString path= wxEmptyString;
wxString message= wxFileSelectorPromptStr;
wxString wildcard= wxFileSelectorDefaultWildcardStr;
@@ -20820,7 +20862,7 @@ case wxFilePickerCtrl_Create: { // wxFilePickerCtrl::Create
wxWindow *parent = (wxWindow *) getPtr(bp,memenv); bp += 4;
int * id = (int *) bp; bp += 4;
bp += 4; /* Align */
- while( * (int*) bp) { switch (* (int*) bp) {
+ while( * (int*) bp) { switch (* (int*) bp) {
case 1: {bp += 4;
int * pathLen = (int *) bp; bp += 4;
path = wxString(bp, wxConvUTF8);
@@ -20854,35 +20896,35 @@ case wxFilePickerCtrl_Create: { // wxFilePickerCtrl::Create
case 7: {bp += 4;
validator = (wxValidator *) getPtr(bp,memenv); bp += 4;
} break;
- }};
+ }};
if(!This) throw wxe_badarg(0);
bool Result = This->Create(parent,(wxWindowID) *id,path,message,wildcard,pos,size,style,*validator);
rt.addBool(Result);
- break;
+ break;
}
-case wxFilePickerCtrl_GetPath: { // wxFilePickerCtrl::GetPath
+case wxFilePickerCtrl_GetPath: { // wxFilePickerCtrl::GetPath
wxFilePickerCtrl *This = (wxFilePickerCtrl *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
wxString Result = This->GetPath();
rt.add(Result);
- break;
+ break;
}
-case wxFilePickerCtrl_SetPath: { // wxFilePickerCtrl::SetPath
+case wxFilePickerCtrl_SetPath: { // wxFilePickerCtrl::SetPath
wxFilePickerCtrl *This = (wxFilePickerCtrl *) getPtr(bp,memenv); bp += 4;
int * strLen = (int *) bp; bp += 4;
wxString str = wxString(bp, wxConvUTF8);
bp += *strLen+((8-((0+ *strLen) & 7)) & 7);
if(!This) throw wxe_badarg(0);
This->SetPath(str);
- break;
+ break;
}
-case wxDirPickerCtrl_new_0: { // wxDirPickerCtrl::wxDirPickerCtrl
+case wxDirPickerCtrl_new_0: { // wxDirPickerCtrl::wxDirPickerCtrl
wxDirPickerCtrl * Result = new EwxDirPickerCtrl();
newPtr((void *) Result, 0, memenv);
rt.addRef(getRef((void *)Result,memenv), "wxDirPickerCtrl");
- break;
+ break;
}
-case wxDirPickerCtrl_new_3: { // wxDirPickerCtrl::wxDirPickerCtrl
+case wxDirPickerCtrl_new_3: { // wxDirPickerCtrl::wxDirPickerCtrl
wxString path= wxEmptyString;
wxString message= wxDirSelectorPromptStr;
wxPoint pos= wxDefaultPosition;
@@ -20891,7 +20933,7 @@ case wxDirPickerCtrl_new_3: { // wxDirPickerCtrl::wxDirPickerCtrl
const wxValidator * validator= &wxDefaultValidator;
wxWindow *parent = (wxWindow *) getPtr(bp,memenv); bp += 4;
int * id = (int *) bp; bp += 4;
- while( * (int*) bp) { switch (* (int*) bp) {
+ while( * (int*) bp) { switch (* (int*) bp) {
case 1: {bp += 4;
int * pathLen = (int *) bp; bp += 4;
path = wxString(bp, wxConvUTF8);
@@ -20920,13 +20962,13 @@ case wxDirPickerCtrl_new_3: { // wxDirPickerCtrl::wxDirPickerCtrl
case 6: {bp += 4;
validator = (wxValidator *) getPtr(bp,memenv); bp += 4;
} break;
- }};
+ }};
wxDirPickerCtrl * Result = new EwxDirPickerCtrl(parent,(wxWindowID) *id,path,message,pos,size,style,*validator);
newPtr((void *) Result, 0, memenv);
rt.addRef(getRef((void *)Result,memenv), "wxDirPickerCtrl");
- break;
+ break;
}
-case wxDirPickerCtrl_Create: { // wxDirPickerCtrl::Create
+case wxDirPickerCtrl_Create: { // wxDirPickerCtrl::Create
wxString path= wxEmptyString;
wxString message= wxDirSelectorPromptStr;
wxPoint pos= wxDefaultPosition;
@@ -20937,7 +20979,7 @@ case wxDirPickerCtrl_Create: { // wxDirPickerCtrl::Create
wxWindow *parent = (wxWindow *) getPtr(bp,memenv); bp += 4;
int * id = (int *) bp; bp += 4;
bp += 4; /* Align */
- while( * (int*) bp) { switch (* (int*) bp) {
+ while( * (int*) bp) { switch (* (int*) bp) {
case 1: {bp += 4;
int * pathLen = (int *) bp; bp += 4;
path = wxString(bp, wxConvUTF8);
@@ -20966,35 +21008,35 @@ case wxDirPickerCtrl_Create: { // wxDirPickerCtrl::Create
case 6: {bp += 4;
validator = (wxValidator *) getPtr(bp,memenv); bp += 4;
} break;
- }};
+ }};
if(!This) throw wxe_badarg(0);
bool Result = This->Create(parent,(wxWindowID) *id,path,message,pos,size,style,*validator);
rt.addBool(Result);
- break;
+ break;
}
-case wxDirPickerCtrl_GetPath: { // wxDirPickerCtrl::GetPath
+case wxDirPickerCtrl_GetPath: { // wxDirPickerCtrl::GetPath
wxDirPickerCtrl *This = (wxDirPickerCtrl *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
wxString Result = This->GetPath();
rt.add(Result);
- break;
+ break;
}
-case wxDirPickerCtrl_SetPath: { // wxDirPickerCtrl::SetPath
+case wxDirPickerCtrl_SetPath: { // wxDirPickerCtrl::SetPath
wxDirPickerCtrl *This = (wxDirPickerCtrl *) getPtr(bp,memenv); bp += 4;
int * strLen = (int *) bp; bp += 4;
wxString str = wxString(bp, wxConvUTF8);
bp += *strLen+((8-((0+ *strLen) & 7)) & 7);
if(!This) throw wxe_badarg(0);
This->SetPath(str);
- break;
+ break;
}
-case wxColourPickerCtrl_new_0: { // wxColourPickerCtrl::wxColourPickerCtrl
+case wxColourPickerCtrl_new_0: { // wxColourPickerCtrl::wxColourPickerCtrl
wxColourPickerCtrl * Result = new EwxColourPickerCtrl();
newPtr((void *) Result, 0, memenv);
rt.addRef(getRef((void *)Result,memenv), "wxColourPickerCtrl");
- break;
+ break;
}
-case wxColourPickerCtrl_new_3: { // wxColourPickerCtrl::wxColourPickerCtrl
+case wxColourPickerCtrl_new_3: { // wxColourPickerCtrl::wxColourPickerCtrl
wxColour col= *wxBLACK;
wxPoint pos= wxDefaultPosition;
wxSize size= wxDefaultSize;
@@ -21002,7 +21044,7 @@ case wxColourPickerCtrl_new_3: { // wxColourPickerCtrl::wxColourPickerCtrl
const wxValidator * validator= &wxDefaultValidator;
wxWindow *parent = (wxWindow *) getPtr(bp,memenv); bp += 4;
int * id = (int *) bp; bp += 4;
- while( * (int*) bp) { switch (* (int*) bp) {
+ while( * (int*) bp) { switch (* (int*) bp) {
case 1: {bp += 4;
int * colR = (int *) bp; bp += 4;
int * colG = (int *) bp; bp += 4;
@@ -21029,13 +21071,13 @@ case wxColourPickerCtrl_new_3: { // wxColourPickerCtrl::wxColourPickerCtrl
case 5: {bp += 4;
validator = (wxValidator *) getPtr(bp,memenv); bp += 4;
} break;
- }};
+ }};
wxColourPickerCtrl * Result = new EwxColourPickerCtrl(parent,(wxWindowID) *id,col,pos,size,style,*validator);
newPtr((void *) Result, 0, memenv);
rt.addRef(getRef((void *)Result,memenv), "wxColourPickerCtrl");
- break;
+ break;
}
-case wxColourPickerCtrl_Create: { // wxColourPickerCtrl::Create
+case wxColourPickerCtrl_Create: { // wxColourPickerCtrl::Create
wxColour col= *wxBLACK;
wxPoint pos= wxDefaultPosition;
wxSize size= wxDefaultSize;
@@ -21045,7 +21087,7 @@ case wxColourPickerCtrl_Create: { // wxColourPickerCtrl::Create
wxWindow *parent = (wxWindow *) getPtr(bp,memenv); bp += 4;
int * id = (int *) bp; bp += 4;
bp += 4; /* Align */
- while( * (int*) bp) { switch (* (int*) bp) {
+ while( * (int*) bp) { switch (* (int*) bp) {
case 1: {bp += 4;
int * colR = (int *) bp; bp += 4;
int * colG = (int *) bp; bp += 4;
@@ -21072,20 +21114,20 @@ case wxColourPickerCtrl_Create: { // wxColourPickerCtrl::Create
case 5: {bp += 4;
validator = (wxValidator *) getPtr(bp,memenv); bp += 4;
} break;
- }};
+ }};
if(!This) throw wxe_badarg(0);
bool Result = This->Create(parent,(wxWindowID) *id,col,pos,size,style,*validator);
rt.addBool(Result);
- break;
+ break;
}
-case wxColourPickerCtrl_GetColour: { // wxColourPickerCtrl::GetColour
+case wxColourPickerCtrl_GetColour: { // wxColourPickerCtrl::GetColour
wxColourPickerCtrl *This = (wxColourPickerCtrl *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
wxColour Result = This->GetColour();
rt.add(Result);
- break;
+ break;
}
-case wxColourPickerCtrl_SetColour_1_1: { // wxColourPickerCtrl::SetColour
+case wxColourPickerCtrl_SetColour_1_1: { // wxColourPickerCtrl::SetColour
wxColourPickerCtrl *This = (wxColourPickerCtrl *) getPtr(bp,memenv); bp += 4;
int * colR = (int *) bp; bp += 4;
int * colG = (int *) bp; bp += 4;
@@ -21094,9 +21136,9 @@ case wxColourPickerCtrl_SetColour_1_1: { // wxColourPickerCtrl::SetColour
wxColour col = wxColour(*colR,*colG,*colB,*colA);
if(!This) throw wxe_badarg(0);
This->SetColour(col);
- break;
+ break;
}
-case wxColourPickerCtrl_SetColour_1_0: { // wxColourPickerCtrl::SetColour
+case wxColourPickerCtrl_SetColour_1_0: { // wxColourPickerCtrl::SetColour
wxColourPickerCtrl *This = (wxColourPickerCtrl *) getPtr(bp,memenv); bp += 4;
int * textLen = (int *) bp; bp += 4;
wxString text = wxString(bp, wxConvUTF8);
@@ -21104,15 +21146,15 @@ case wxColourPickerCtrl_SetColour_1_0: { // wxColourPickerCtrl::SetColour
if(!This) throw wxe_badarg(0);
bool Result = This->SetColour(text);
rt.addBool(Result);
- break;
+ break;
}
-case wxDatePickerCtrl_new_0: { // wxDatePickerCtrl::wxDatePickerCtrl
+case wxDatePickerCtrl_new_0: { // wxDatePickerCtrl::wxDatePickerCtrl
wxDatePickerCtrl * Result = new EwxDatePickerCtrl();
newPtr((void *) Result, 0, memenv);
rt.addRef(getRef((void *)Result,memenv), "wxDatePickerCtrl");
- break;
+ break;
}
-case wxDatePickerCtrl_new_3: { // wxDatePickerCtrl::wxDatePickerCtrl
+case wxDatePickerCtrl_new_3: { // wxDatePickerCtrl::wxDatePickerCtrl
wxDateTime date= wxDefaultDateTime;
wxPoint pos= wxDefaultPosition;
wxSize size= wxDefaultSize;
@@ -21120,7 +21162,7 @@ case wxDatePickerCtrl_new_3: { // wxDatePickerCtrl::wxDatePickerCtrl
const wxValidator * validator= &wxDefaultValidator;
wxWindow *parent = (wxWindow *) getPtr(bp,memenv); bp += 4;
int * id = (int *) bp; bp += 4;
- while( * (int*) bp) { switch (* (int*) bp) {
+ while( * (int*) bp) { switch (* (int*) bp) {
case 1: {bp += 4;
int * dateD = (int *) bp; bp += 4;
int * dateMo = (int *) bp; bp += 4;
@@ -21149,13 +21191,13 @@ case wxDatePickerCtrl_new_3: { // wxDatePickerCtrl::wxDatePickerCtrl
case 5: {bp += 4;
validator = (wxValidator *) getPtr(bp,memenv); bp += 4;
} break;
- }};
+ }};
wxDatePickerCtrl * Result = new EwxDatePickerCtrl(parent,(wxWindowID) *id,date,pos,size,style,*validator);
newPtr((void *) Result, 0, memenv);
rt.addRef(getRef((void *)Result,memenv), "wxDatePickerCtrl");
- break;
+ break;
}
-case wxDatePickerCtrl_GetRange: { // wxDatePickerCtrl::GetRange
+case wxDatePickerCtrl_GetRange: { // wxDatePickerCtrl::GetRange
wxDatePickerCtrl *This = (wxDatePickerCtrl *) getPtr(bp,memenv); bp += 4;
int * dt1D = (int *) bp; bp += 4;
int * dt1Mo = (int *) bp; bp += 4;
@@ -21174,16 +21216,16 @@ case wxDatePickerCtrl_GetRange: { // wxDatePickerCtrl::GetRange
if(!This) throw wxe_badarg(0);
bool Result = This->GetRange(&dt1,&dt2);
rt.addBool(Result);
- break;
+ break;
}
-case wxDatePickerCtrl_GetValue: { // wxDatePickerCtrl::GetValue
+case wxDatePickerCtrl_GetValue: { // wxDatePickerCtrl::GetValue
wxDatePickerCtrl *This = (wxDatePickerCtrl *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
wxDateTime Result = This->GetValue();
rt.add(Result);
- break;
+ break;
}
-case wxDatePickerCtrl_SetRange: { // wxDatePickerCtrl::SetRange
+case wxDatePickerCtrl_SetRange: { // wxDatePickerCtrl::SetRange
wxDatePickerCtrl *This = (wxDatePickerCtrl *) getPtr(bp,memenv); bp += 4;
int * dt1D = (int *) bp; bp += 4;
int * dt1Mo = (int *) bp; bp += 4;
@@ -21201,9 +21243,9 @@ case wxDatePickerCtrl_SetRange: { // wxDatePickerCtrl::SetRange
wxDateTime dt2 = wxDateTime((wxDateTime::wxDateTime_t) *dt2D,(wxDateTime::Month) *dt2Mo,*dt2Y,(wxDateTime::wxDateTime_t) *dt2H,(wxDateTime::wxDateTime_t) *dt2Mi,(wxDateTime::wxDateTime_t) *dt2S);
if(!This) throw wxe_badarg(0);
This->SetRange(dt1,dt2);
- break;
+ break;
}
-case wxDatePickerCtrl_SetValue: { // wxDatePickerCtrl::SetValue
+case wxDatePickerCtrl_SetValue: { // wxDatePickerCtrl::SetValue
wxDatePickerCtrl *This = (wxDatePickerCtrl *) getPtr(bp,memenv); bp += 4;
int * dateD = (int *) bp; bp += 4;
int * dateMo = (int *) bp; bp += 4;
@@ -21214,15 +21256,15 @@ case wxDatePickerCtrl_SetValue: { // wxDatePickerCtrl::SetValue
wxDateTime date = wxDateTime((wxDateTime::wxDateTime_t) *dateD,(wxDateTime::Month) *dateMo,*dateY,(wxDateTime::wxDateTime_t) *dateH,(wxDateTime::wxDateTime_t) *dateMi,(wxDateTime::wxDateTime_t) *dateS);
if(!This) throw wxe_badarg(0);
This->SetValue(date);
- break;
+ break;
}
-case wxFontPickerCtrl_new_0: { // wxFontPickerCtrl::wxFontPickerCtrl
+case wxFontPickerCtrl_new_0: { // wxFontPickerCtrl::wxFontPickerCtrl
wxFontPickerCtrl * Result = new EwxFontPickerCtrl();
newPtr((void *) Result, 0, memenv);
rt.addRef(getRef((void *)Result,memenv), "wxFontPickerCtrl");
- break;
+ break;
}
-case wxFontPickerCtrl_new_3: { // wxFontPickerCtrl::wxFontPickerCtrl
+case wxFontPickerCtrl_new_3: { // wxFontPickerCtrl::wxFontPickerCtrl
const wxFont * initial= &wxNullFont;
wxPoint pos= wxDefaultPosition;
wxSize size= wxDefaultSize;
@@ -21230,7 +21272,7 @@ case wxFontPickerCtrl_new_3: { // wxFontPickerCtrl::wxFontPickerCtrl
const wxValidator * validator= &wxDefaultValidator;
wxWindow *parent = (wxWindow *) getPtr(bp,memenv); bp += 4;
int * id = (int *) bp; bp += 4;
- while( * (int*) bp) { switch (* (int*) bp) {
+ while( * (int*) bp) { switch (* (int*) bp) {
case 1: {bp += 4;
initial = (wxFont *) getPtr(bp,memenv); bp += 4;
} break;
@@ -21252,13 +21294,13 @@ initial = (wxFont *) getPtr(bp,memenv); bp += 4;
case 5: {bp += 4;
validator = (wxValidator *) getPtr(bp,memenv); bp += 4;
} break;
- }};
+ }};
wxFontPickerCtrl * Result = new EwxFontPickerCtrl(parent,(wxWindowID) *id,*initial,pos,size,style,*validator);
newPtr((void *) Result, 0, memenv);
rt.addRef(getRef((void *)Result,memenv), "wxFontPickerCtrl");
- break;
+ break;
}
-case wxFontPickerCtrl_Create: { // wxFontPickerCtrl::Create
+case wxFontPickerCtrl_Create: { // wxFontPickerCtrl::Create
const wxFont * initial= &wxNullFont;
wxPoint pos= wxDefaultPosition;
wxSize size= wxDefaultSize;
@@ -21268,7 +21310,7 @@ case wxFontPickerCtrl_Create: { // wxFontPickerCtrl::Create
wxWindow *parent = (wxWindow *) getPtr(bp,memenv); bp += 4;
int * id = (int *) bp; bp += 4;
bp += 4; /* Align */
- while( * (int*) bp) { switch (* (int*) bp) {
+ while( * (int*) bp) { switch (* (int*) bp) {
case 1: {bp += 4;
initial = (wxFont *) getPtr(bp,memenv); bp += 4;
} break;
@@ -21290,64 +21332,64 @@ initial = (wxFont *) getPtr(bp,memenv); bp += 4;
case 5: {bp += 4;
validator = (wxValidator *) getPtr(bp,memenv); bp += 4;
} break;
- }};
+ }};
if(!This) throw wxe_badarg(0);
bool Result = This->Create(parent,(wxWindowID) *id,*initial,pos,size,style,*validator);
rt.addBool(Result);
- break;
+ break;
}
-case wxFontPickerCtrl_GetSelectedFont: { // wxFontPickerCtrl::GetSelectedFont
+case wxFontPickerCtrl_GetSelectedFont: { // wxFontPickerCtrl::GetSelectedFont
wxFontPickerCtrl *This = (wxFontPickerCtrl *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
wxFont * Result = new wxFont(This->GetSelectedFont()); newPtr((void *) Result,3, memenv);;
rt.addRef(getRef((void *)Result,memenv), "wxFont");
- break;
+ break;
}
-case wxFontPickerCtrl_SetSelectedFont: { // wxFontPickerCtrl::SetSelectedFont
+case wxFontPickerCtrl_SetSelectedFont: { // wxFontPickerCtrl::SetSelectedFont
wxFontPickerCtrl *This = (wxFontPickerCtrl *) getPtr(bp,memenv); bp += 4;
wxFont *f = (wxFont *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
This->SetSelectedFont(*f);
- break;
+ break;
}
-case wxFontPickerCtrl_GetMaxPointSize: { // wxFontPickerCtrl::GetMaxPointSize
+case wxFontPickerCtrl_GetMaxPointSize: { // wxFontPickerCtrl::GetMaxPointSize
wxFontPickerCtrl *This = (wxFontPickerCtrl *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
int Result = This->GetMaxPointSize();
rt.addUint(Result);
- break;
+ break;
}
-case wxFontPickerCtrl_SetMaxPointSize: { // wxFontPickerCtrl::SetMaxPointSize
+case wxFontPickerCtrl_SetMaxPointSize: { // wxFontPickerCtrl::SetMaxPointSize
wxFontPickerCtrl *This = (wxFontPickerCtrl *) getPtr(bp,memenv); bp += 4;
unsigned int * max = (unsigned int *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
This->SetMaxPointSize((int) *max);
- break;
+ break;
}
-case wxFindReplaceDialog_new_0: { // wxFindReplaceDialog::wxFindReplaceDialog
+case wxFindReplaceDialog_new_0: { // wxFindReplaceDialog::wxFindReplaceDialog
wxFindReplaceDialog * Result = new EwxFindReplaceDialog();
newPtr((void *) Result, 2, memenv);
rt.addRef(getRef((void *)Result,memenv), "wxFindReplaceDialog");
- break;
+ break;
}
-case wxFindReplaceDialog_new_4: { // wxFindReplaceDialog::wxFindReplaceDialog
+case wxFindReplaceDialog_new_4: { // wxFindReplaceDialog::wxFindReplaceDialog
int style=0;
wxWindow *parent = (wxWindow *) getPtr(bp,memenv); bp += 4;
wxFindReplaceData *data = (wxFindReplaceData *) getPtr(bp,memenv); bp += 4;
int * titleLen = (int *) bp; bp += 4;
wxString title = wxString(bp, wxConvUTF8);
bp += *titleLen+((8-((4+ *titleLen) & 7)) & 7);
- while( * (int*) bp) { switch (* (int*) bp) {
+ while( * (int*) bp) { switch (* (int*) bp) {
case 1: {bp += 4;
style = (int)*(int *) bp; bp += 4;
} break;
- }};
+ }};
wxFindReplaceDialog * Result = new EwxFindReplaceDialog(parent,data,title,style);
newPtr((void *) Result, 2, memenv);
rt.addRef(getRef((void *)Result,memenv), "wxFindReplaceDialog");
- break;
+ break;
}
-case wxFindReplaceDialog_Create: { // wxFindReplaceDialog::Create
+case wxFindReplaceDialog_Create: { // wxFindReplaceDialog::Create
int style=0;
wxFindReplaceDialog *This = (wxFindReplaceDialog *) getPtr(bp,memenv); bp += 4;
wxWindow *parent = (wxWindow *) getPtr(bp,memenv); bp += 4;
@@ -21355,89 +21397,89 @@ case wxFindReplaceDialog_Create: { // wxFindReplaceDialog::Create
int * titleLen = (int *) bp; bp += 4;
wxString title = wxString(bp, wxConvUTF8);
bp += *titleLen+((8-((0+ *titleLen) & 7)) & 7);
- while( * (int*) bp) { switch (* (int*) bp) {
+ while( * (int*) bp) { switch (* (int*) bp) {
case 1: {bp += 4;
style = (int)*(int *) bp; bp += 4;
} break;
- }};
+ }};
if(!This) throw wxe_badarg(0);
bool Result = This->Create(parent,data,title,style);
rt.addBool(Result);
- break;
+ break;
}
-case wxFindReplaceDialog_GetData: { // wxFindReplaceDialog::GetData
+case wxFindReplaceDialog_GetData: { // wxFindReplaceDialog::GetData
wxFindReplaceDialog *This = (wxFindReplaceDialog *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
const wxFindReplaceData * Result = (wxFindReplaceData*)This->GetData();
rt.addRef(getRef((void *)Result,memenv), "wxFindReplaceData");
- break;
+ break;
}
-case wxFindReplaceData_new_0: { // wxFindReplaceData::wxFindReplaceData
+case wxFindReplaceData_new_0: { // wxFindReplaceData::wxFindReplaceData
wxFindReplaceData * Result = new EwxFindReplaceData();
newPtr((void *) Result, 1, memenv);
rt.addRef(getRef((void *)Result,memenv), "wxFindReplaceData");
- break;
+ break;
}
-case wxFindReplaceData_new_1: { // wxFindReplaceData::wxFindReplaceData
+case wxFindReplaceData_new_1: { // wxFindReplaceData::wxFindReplaceData
unsigned int * flags = (unsigned int *) bp; bp += 4;
wxFindReplaceData * Result = new EwxFindReplaceData((int) *flags);
newPtr((void *) Result, 1, memenv);
rt.addRef(getRef((void *)Result,memenv), "wxFindReplaceData");
- break;
+ break;
}
-case wxFindReplaceData_GetFindString: { // wxFindReplaceData::GetFindString
+case wxFindReplaceData_GetFindString: { // wxFindReplaceData::GetFindString
wxFindReplaceData *This = (wxFindReplaceData *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
const wxString * Result = &This->GetFindString();
rt.add(Result);
- break;
+ break;
}
-case wxFindReplaceData_GetReplaceString: { // wxFindReplaceData::GetReplaceString
+case wxFindReplaceData_GetReplaceString: { // wxFindReplaceData::GetReplaceString
wxFindReplaceData *This = (wxFindReplaceData *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
const wxString * Result = &This->GetReplaceString();
rt.add(Result);
- break;
+ break;
}
-case wxFindReplaceData_GetFlags: { // wxFindReplaceData::GetFlags
+case wxFindReplaceData_GetFlags: { // wxFindReplaceData::GetFlags
wxFindReplaceData *This = (wxFindReplaceData *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
int Result = This->GetFlags();
rt.addInt(Result);
- break;
+ break;
}
-case wxFindReplaceData_SetFlags: { // wxFindReplaceData::SetFlags
+case wxFindReplaceData_SetFlags: { // wxFindReplaceData::SetFlags
wxFindReplaceData *This = (wxFindReplaceData *) getPtr(bp,memenv); bp += 4;
unsigned int * flags = (unsigned int *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
This->SetFlags((int) *flags);
- break;
+ break;
}
-case wxFindReplaceData_SetFindString: { // wxFindReplaceData::SetFindString
+case wxFindReplaceData_SetFindString: { // wxFindReplaceData::SetFindString
wxFindReplaceData *This = (wxFindReplaceData *) getPtr(bp,memenv); bp += 4;
int * strLen = (int *) bp; bp += 4;
wxString str = wxString(bp, wxConvUTF8);
bp += *strLen+((8-((0+ *strLen) & 7)) & 7);
if(!This) throw wxe_badarg(0);
This->SetFindString(str);
- break;
+ break;
}
-case wxFindReplaceData_SetReplaceString: { // wxFindReplaceData::SetReplaceString
+case wxFindReplaceData_SetReplaceString: { // wxFindReplaceData::SetReplaceString
wxFindReplaceData *This = (wxFindReplaceData *) getPtr(bp,memenv); bp += 4;
int * strLen = (int *) bp; bp += 4;
wxString str = wxString(bp, wxConvUTF8);
bp += *strLen+((8-((0+ *strLen) & 7)) & 7);
if(!This) throw wxe_badarg(0);
This->SetReplaceString(str);
- break;
+ break;
}
-case wxMultiChoiceDialog_new_0: { // wxMultiChoiceDialog::wxMultiChoiceDialog
+case wxMultiChoiceDialog_new_0: { // wxMultiChoiceDialog::wxMultiChoiceDialog
wxMultiChoiceDialog * Result = new EwxMultiChoiceDialog();
newPtr((void *) Result, 2, memenv);
rt.addRef(getRef((void *)Result,memenv), "wxMultiChoiceDialog");
- break;
+ break;
}
-case wxMultiChoiceDialog_new_5: { // wxMultiChoiceDialog::wxMultiChoiceDialog
+case wxMultiChoiceDialog_new_5: { // wxMultiChoiceDialog::wxMultiChoiceDialog
long style=(wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER|wxOK|wxCANCEL|wxCENTRE);
wxPoint pos= wxDefaultPosition;
wxWindow *parent = (wxWindow *) getPtr(bp,memenv); bp += 4;
@@ -21457,7 +21499,7 @@ case wxMultiChoiceDialog_new_5: { // wxMultiChoiceDialog::wxMultiChoiceDialog
choicesASz += *choicesTemp+4;
}
bp += (8-((4+ choicesASz) & 7 )) & 7;
- while( * (int*) bp) { switch (* (int*) bp) {
+ while( * (int*) bp) { switch (* (int*) bp) {
case 1: {bp += 4;
style = (long)*(int *) bp; bp += 4;
} break;
@@ -21467,20 +21509,20 @@ case wxMultiChoiceDialog_new_5: { // wxMultiChoiceDialog::wxMultiChoiceDialog
pos = wxPoint(*posX,*posY);
bp += 4; /* Align */
} break;
- }};
+ }};
wxMultiChoiceDialog * Result = new EwxMultiChoiceDialog(parent,message,caption,choices,style,pos);
newPtr((void *) Result, 2, memenv);
rt.addRef(getRef((void *)Result,memenv), "wxMultiChoiceDialog");
- break;
+ break;
}
-case wxMultiChoiceDialog_GetSelections: { // wxMultiChoiceDialog::GetSelections
+case wxMultiChoiceDialog_GetSelections: { // wxMultiChoiceDialog::GetSelections
wxMultiChoiceDialog *This = (wxMultiChoiceDialog *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
wxArrayInt Result = This->GetSelections();
rt.add(Result);
- break;
+ break;
}
-case wxMultiChoiceDialog_SetSelections: { // wxMultiChoiceDialog::SetSelections
+case wxMultiChoiceDialog_SetSelections: { // wxMultiChoiceDialog::SetSelections
wxMultiChoiceDialog *This = (wxMultiChoiceDialog *) getPtr(bp,memenv); bp += 4;
int * selectionsLen = (int *) bp; bp += 4;
wxArrayInt selections;
@@ -21488,15 +21530,15 @@ case wxMultiChoiceDialog_SetSelections: { // wxMultiChoiceDialog::SetSelections
bp += ((*selectionsLen + 2) % 2 )*4;
if(!This) throw wxe_badarg(0);
This->SetSelections(selections);
- break;
+ break;
}
-case wxSingleChoiceDialog_new_0: { // wxSingleChoiceDialog::wxSingleChoiceDialog
+case wxSingleChoiceDialog_new_0: { // wxSingleChoiceDialog::wxSingleChoiceDialog
wxSingleChoiceDialog * Result = new EwxSingleChoiceDialog();
newPtr((void *) Result, 2, memenv);
rt.addRef(getRef((void *)Result,memenv), "wxSingleChoiceDialog");
- break;
+ break;
}
-case wxSingleChoiceDialog_new_5: { // wxSingleChoiceDialog::wxSingleChoiceDialog
+case wxSingleChoiceDialog_new_5: { // wxSingleChoiceDialog::wxSingleChoiceDialog
char ** clientData = (char **) NULL;
long style=(wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER|wxOK|wxCANCEL|wxCENTRE);
wxPoint pos= wxDefaultPosition;
@@ -21517,7 +21559,7 @@ case wxSingleChoiceDialog_new_5: { // wxSingleChoiceDialog::wxSingleChoiceDialog
choicesASz += *choicesTemp+4;
}
bp += (8-((4+ choicesASz) & 7 )) & 7;
- while( * (int*) bp) { switch (* (int*) bp) {
+ while( * (int*) bp) { switch (* (int*) bp) {
case 1: {bp += 4;
style = (long)*(int *) bp; bp += 4;
} break;
@@ -21527,34 +21569,34 @@ case wxSingleChoiceDialog_new_5: { // wxSingleChoiceDialog::wxSingleChoiceDialog
pos = wxPoint(*posX,*posY);
bp += 4; /* Align */
} break;
- }};
+ }};
wxSingleChoiceDialog * Result = new EwxSingleChoiceDialog(parent,message,caption,choices,clientData,style,pos);
newPtr((void *) Result, 2, memenv);
rt.addRef(getRef((void *)Result,memenv), "wxSingleChoiceDialog");
- break;
+ break;
}
-case wxSingleChoiceDialog_GetSelection: { // wxSingleChoiceDialog::GetSelection
+case wxSingleChoiceDialog_GetSelection: { // wxSingleChoiceDialog::GetSelection
wxSingleChoiceDialog *This = (wxSingleChoiceDialog *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
int Result = This->GetSelection();
rt.addInt(Result);
- break;
+ break;
}
-case wxSingleChoiceDialog_GetStringSelection: { // wxSingleChoiceDialog::GetStringSelection
+case wxSingleChoiceDialog_GetStringSelection: { // wxSingleChoiceDialog::GetStringSelection
wxSingleChoiceDialog *This = (wxSingleChoiceDialog *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
wxString Result = This->GetStringSelection();
rt.add(Result);
- break;
+ break;
}
-case wxSingleChoiceDialog_SetSelection: { // wxSingleChoiceDialog::SetSelection
+case wxSingleChoiceDialog_SetSelection: { // wxSingleChoiceDialog::SetSelection
wxSingleChoiceDialog *This = (wxSingleChoiceDialog *) getPtr(bp,memenv); bp += 4;
int * sel = (int *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
This->SetSelection((int) *sel);
- break;
+ break;
}
-case wxTextEntryDialog_new: { // wxTextEntryDialog::wxTextEntryDialog
+case wxTextEntryDialog_new: { // wxTextEntryDialog::wxTextEntryDialog
wxString caption= wxGetTextFromUserPromptStr;
wxString value= wxEmptyString;
long style=(wxOK|wxCANCEL|wxCENTRE|wxWS_EX_VALIDATE_RECURSIVELY);
@@ -21563,7 +21605,7 @@ case wxTextEntryDialog_new: { // wxTextEntryDialog::wxTextEntryDialog
int * messageLen = (int *) bp; bp += 4;
wxString message = wxString(bp, wxConvUTF8);
bp += *messageLen+((8-((0+ *messageLen) & 7)) & 7);
- while( * (int*) bp) { switch (* (int*) bp) {
+ while( * (int*) bp) { switch (* (int*) bp) {
case 1: {bp += 4;
int * captionLen = (int *) bp; bp += 4;
caption = wxString(bp, wxConvUTF8);
@@ -21583,29 +21625,29 @@ case wxTextEntryDialog_new: { // wxTextEntryDialog::wxTextEntryDialog
pos = wxPoint(*posX,*posY);
bp += 4; /* Align */
} break;
- }};
+ }};
wxTextEntryDialog * Result = new EwxTextEntryDialog(parent,message,caption,value,style,pos);
newPtr((void *) Result, 2, memenv);
rt.addRef(getRef((void *)Result,memenv), "wxTextEntryDialog");
- break;
+ break;
}
-case wxTextEntryDialog_GetValue: { // wxTextEntryDialog::GetValue
+case wxTextEntryDialog_GetValue: { // wxTextEntryDialog::GetValue
wxTextEntryDialog *This = (wxTextEntryDialog *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
wxString Result = This->GetValue();
rt.add(Result);
- break;
+ break;
}
-case wxTextEntryDialog_SetValue: { // wxTextEntryDialog::SetValue
+case wxTextEntryDialog_SetValue: { // wxTextEntryDialog::SetValue
wxTextEntryDialog *This = (wxTextEntryDialog *) getPtr(bp,memenv); bp += 4;
int * valLen = (int *) bp; bp += 4;
wxString val = wxString(bp, wxConvUTF8);
bp += *valLen+((8-((0+ *valLen) & 7)) & 7);
if(!This) throw wxe_badarg(0);
This->SetValue(val);
- break;
+ break;
}
-case wxPasswordEntryDialog_new: { // wxPasswordEntryDialog::wxPasswordEntryDialog
+case wxPasswordEntryDialog_new: { // wxPasswordEntryDialog::wxPasswordEntryDialog
wxString caption= wxGetPasswordFromUserPromptStr;
wxString value= wxEmptyString;
long style=(wxOK|wxCANCEL|wxCENTRE|wxWS_EX_VALIDATE_RECURSIVELY);
@@ -21614,7 +21656,7 @@ case wxPasswordEntryDialog_new: { // wxPasswordEntryDialog::wxPasswordEntryDialo
int * messageLen = (int *) bp; bp += 4;
wxString message = wxString(bp, wxConvUTF8);
bp += *messageLen+((8-((0+ *messageLen) & 7)) & 7);
- while( * (int*) bp) { switch (* (int*) bp) {
+ while( * (int*) bp) { switch (* (int*) bp) {
case 1: {bp += 4;
int * captionLen = (int *) bp; bp += 4;
caption = wxString(bp, wxConvUTF8);
@@ -21634,89 +21676,89 @@ case wxPasswordEntryDialog_new: { // wxPasswordEntryDialog::wxPasswordEntryDialo
pos = wxPoint(*posX,*posY);
bp += 4; /* Align */
} break;
- }};
+ }};
wxPasswordEntryDialog * Result = new EwxPasswordEntryDialog(parent,message,caption,value,style,pos);
newPtr((void *) Result, 2, memenv);
rt.addRef(getRef((void *)Result,memenv), "wxPasswordEntryDialog");
- break;
+ break;
}
-case wxFontData_new_0: { // wxFontData::wxFontData
+case wxFontData_new_0: { // wxFontData::wxFontData
wxFontData * Result = new EwxFontData();
newPtr((void *) Result, 1, memenv);
rt.addRef(getRef((void *)Result,memenv), "wxFontData");
- break;
+ break;
}
-case wxFontData_new_1: { // wxFontData::wxFontData
+case wxFontData_new_1: { // wxFontData::wxFontData
wxFontData *data = (wxFontData *) getPtr(bp,memenv); bp += 4;
wxFontData * Result = new EwxFontData(*data);
newPtr((void *) Result, 1, memenv);
rt.addRef(getRef((void *)Result,memenv), "wxFontData");
- break;
+ break;
}
-case wxFontData_EnableEffects: { // wxFontData::EnableEffects
+case wxFontData_EnableEffects: { // wxFontData::EnableEffects
wxFontData *This = (wxFontData *) getPtr(bp,memenv); bp += 4;
bool * flag = (bool *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
This->EnableEffects((bool) *flag);
- break;
+ break;
}
-case wxFontData_GetAllowSymbols: { // wxFontData::GetAllowSymbols
+case wxFontData_GetAllowSymbols: { // wxFontData::GetAllowSymbols
wxFontData *This = (wxFontData *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
bool Result = This->GetAllowSymbols();
rt.addBool(Result);
- break;
+ break;
}
-case wxFontData_GetColour: { // wxFontData::GetColour
+case wxFontData_GetColour: { // wxFontData::GetColour
wxFontData *This = (wxFontData *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
const wxColour * Result = &This->GetColour();
rt.add((*Result));
- break;
+ break;
}
-case wxFontData_GetChosenFont: { // wxFontData::GetChosenFont
+case wxFontData_GetChosenFont: { // wxFontData::GetChosenFont
wxFontData *This = (wxFontData *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
wxFont * Result = new wxFont(This->GetChosenFont()); newPtr((void *) Result,3, memenv);;
rt.addRef(getRef((void *)Result,memenv), "wxFont");
- break;
+ break;
}
-case wxFontData_GetEnableEffects: { // wxFontData::GetEnableEffects
+case wxFontData_GetEnableEffects: { // wxFontData::GetEnableEffects
wxFontData *This = (wxFontData *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
bool Result = This->GetEnableEffects();
rt.addBool(Result);
- break;
+ break;
}
-case wxFontData_GetInitialFont: { // wxFontData::GetInitialFont
+case wxFontData_GetInitialFont: { // wxFontData::GetInitialFont
wxFontData *This = (wxFontData *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
wxFont * Result = new wxFont(This->GetInitialFont()); newPtr((void *) Result,3, memenv);;
rt.addRef(getRef((void *)Result,memenv), "wxFont");
- break;
+ break;
}
-case wxFontData_GetShowHelp: { // wxFontData::GetShowHelp
+case wxFontData_GetShowHelp: { // wxFontData::GetShowHelp
wxFontData *This = (wxFontData *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
bool Result = This->GetShowHelp();
rt.addBool(Result);
- break;
+ break;
}
-case wxFontData_SetAllowSymbols: { // wxFontData::SetAllowSymbols
+case wxFontData_SetAllowSymbols: { // wxFontData::SetAllowSymbols
wxFontData *This = (wxFontData *) getPtr(bp,memenv); bp += 4;
bool * flag = (bool *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
This->SetAllowSymbols((bool) *flag);
- break;
+ break;
}
-case wxFontData_SetChosenFont: { // wxFontData::SetChosenFont
+case wxFontData_SetChosenFont: { // wxFontData::SetChosenFont
wxFontData *This = (wxFontData *) getPtr(bp,memenv); bp += 4;
wxFont *font = (wxFont *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
This->SetChosenFont(*font);
- break;
+ break;
}
-case wxFontData_SetColour: { // wxFontData::SetColour
+case wxFontData_SetColour: { // wxFontData::SetColour
wxFontData *This = (wxFontData *) getPtr(bp,memenv); bp += 4;
int * colourR = (int *) bp; bp += 4;
int * colourG = (int *) bp; bp += 4;
@@ -21725,61 +21767,61 @@ case wxFontData_SetColour: { // wxFontData::SetColour
wxColour colour = wxColour(*colourR,*colourG,*colourB,*colourA);
if(!This) throw wxe_badarg(0);
This->SetColour(colour);
- break;
+ break;
}
-case wxFontData_SetInitialFont: { // wxFontData::SetInitialFont
+case wxFontData_SetInitialFont: { // wxFontData::SetInitialFont
wxFontData *This = (wxFontData *) getPtr(bp,memenv); bp += 4;
wxFont *font = (wxFont *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
This->SetInitialFont(*font);
- break;
+ break;
}
-case wxFontData_SetRange: { // wxFontData::SetRange
+case wxFontData_SetRange: { // wxFontData::SetRange
wxFontData *This = (wxFontData *) getPtr(bp,memenv); bp += 4;
int * minRange = (int *) bp; bp += 4;
int * maxRange = (int *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
This->SetRange((int) *minRange,(int) *maxRange);
- break;
+ break;
}
-case wxFontData_SetShowHelp: { // wxFontData::SetShowHelp
+case wxFontData_SetShowHelp: { // wxFontData::SetShowHelp
wxFontData *This = (wxFontData *) getPtr(bp,memenv); bp += 4;
bool * flag = (bool *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
This->SetShowHelp((bool) *flag);
- break;
+ break;
}
-case wxFontDialog_new_0: { // wxFontDialog::wxFontDialog
+case wxFontDialog_new_0: { // wxFontDialog::wxFontDialog
wxFontDialog * Result = new EwxFontDialog();
newPtr((void *) Result, 2, memenv);
rt.addRef(getRef((void *)Result,memenv), "wxFontDialog");
- break;
+ break;
}
-case wxFontDialog_new_2: { // wxFontDialog::wxFontDialog
+case wxFontDialog_new_2: { // wxFontDialog::wxFontDialog
wxWindow *parent = (wxWindow *) getPtr(bp,memenv); bp += 4;
wxFontData *data = (wxFontData *) getPtr(bp,memenv); bp += 4;
wxFontDialog * Result = new EwxFontDialog(parent,*data);
newPtr((void *) Result, 2, memenv);
rt.addRef(getRef((void *)Result,memenv), "wxFontDialog");
- break;
+ break;
}
-case wxFontDialog_Create: { // wxFontDialog::Create
+case wxFontDialog_Create: { // wxFontDialog::Create
wxFontDialog *This = (wxFontDialog *) getPtr(bp,memenv); bp += 4;
wxWindow *parent = (wxWindow *) getPtr(bp,memenv); bp += 4;
wxFontData *data = (wxFontData *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
bool Result = This->Create(parent,*data);
rt.addBool(Result);
- break;
+ break;
}
-case wxFontDialog_GetFontData: { // wxFontDialog::GetFontData
+case wxFontDialog_GetFontData: { // wxFontDialog::GetFontData
wxFontDialog *This = (wxFontDialog *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
const wxFontData * Result = &This->GetFontData();
rt.addRef(getRef((void *)Result,memenv), "wxFontData");
- break;
+ break;
}
-case wxProgressDialog_new: { // wxProgressDialog::wxProgressDialog
+case wxProgressDialog_new: { // wxProgressDialog::wxProgressDialog
int maximum=100;
wxWindow * parent=NULL;
int style=wxPD_APP_MODAL|wxPD_AUTO_HIDE;
@@ -21789,7 +21831,7 @@ case wxProgressDialog_new: { // wxProgressDialog::wxProgressDialog
int * messageLen = (int *) bp; bp += 4;
wxString message = wxString(bp, wxConvUTF8);
bp += *messageLen+((8-((4+ *messageLen) & 7)) & 7);
- while( * (int*) bp) { switch (* (int*) bp) {
+ while( * (int*) bp) { switch (* (int*) bp) {
case 1: {bp += 4;
maximum = (int)*(int *) bp; bp += 4;
} break;
@@ -21799,41 +21841,41 @@ parent = (wxWindow *) getPtr(bp,memenv); bp += 4;
case 3: {bp += 4;
style = (int)*(int *) bp; bp += 4;
} break;
- }};
+ }};
wxProgressDialog * Result = new EwxProgressDialog(title,message,maximum,parent,style);
newPtr((void *) Result, 2, memenv);
rt.addRef(getRef((void *)Result,memenv), "wxProgressDialog");
- break;
+ break;
}
-case wxProgressDialog_Resume: { // wxProgressDialog::Resume
+case wxProgressDialog_Resume: { // wxProgressDialog::Resume
wxProgressDialog *This = (wxProgressDialog *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
This->Resume();
- break;
+ break;
}
-case wxProgressDialog_Update_2: { // wxProgressDialog::Update
+case wxProgressDialog_Update_2: { // wxProgressDialog::Update
wxString newmsg= wxEmptyString;
wxProgressDialog *This = (wxProgressDialog *) getPtr(bp,memenv); bp += 4;
int * value = (int *) bp; bp += 4;
- while( * (int*) bp) { switch (* (int*) bp) {
+ while( * (int*) bp) { switch (* (int*) bp) {
case 1: {bp += 4;
int * newmsgLen = (int *) bp; bp += 4;
newmsg = wxString(bp, wxConvUTF8);
bp += *newmsgLen+((8-((0+ *newmsgLen) & 7)) & 7);
} break;
- }};
+ }};
if(!This) throw wxe_badarg(0);
bool Result = This->Update((int) *value,newmsg);
rt.addBool(Result);
- break;
+ break;
}
-case wxProgressDialog_Update_0: { // wxProgressDialog::Update
+case wxProgressDialog_Update_0: { // wxProgressDialog::Update
wxProgressDialog *This = (wxProgressDialog *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
This->Update();
- break;
+ break;
}
-case wxMessageDialog_new: { // wxMessageDialog::wxMessageDialog
+case wxMessageDialog_new: { // wxMessageDialog::wxMessageDialog
wxString caption= wxMessageBoxCaptionStr;
long style=wxOK|wxCENTRE;
wxPoint pos= wxDefaultPosition;
@@ -21841,7 +21883,7 @@ case wxMessageDialog_new: { // wxMessageDialog::wxMessageDialog
int * messageLen = (int *) bp; bp += 4;
wxString message = wxString(bp, wxConvUTF8);
bp += *messageLen+((8-((0+ *messageLen) & 7)) & 7);
- while( * (int*) bp) { switch (* (int*) bp) {
+ while( * (int*) bp) { switch (* (int*) bp) {
case 1: {bp += 4;
int * captionLen = (int *) bp; bp += 4;
caption = wxString(bp, wxConvUTF8);
@@ -21856,804 +21898,804 @@ case wxMessageDialog_new: { // wxMessageDialog::wxMessageDialog
pos = wxPoint(*posX,*posY);
bp += 4; /* Align */
} break;
- }};
+ }};
wxMessageDialog * Result = new EwxMessageDialog(parent,message,caption,style,pos);
newPtr((void *) Result, 2, memenv);
rt.addRef(getRef((void *)Result,memenv), "wxMessageDialog");
- break;
+ break;
}
-case wxPageSetupDialog_new: { // wxPageSetupDialog::wxPageSetupDialog
+case wxPageSetupDialog_new: { // wxPageSetupDialog::wxPageSetupDialog
wxPageSetupDialogData * data=NULL;
wxWindow *parent = (wxWindow *) getPtr(bp,memenv); bp += 4;
bp += 4; /* Align */
- while( * (int*) bp) { switch (* (int*) bp) {
+ while( * (int*) bp) { switch (* (int*) bp) {
case 1: {bp += 4;
data = (wxPageSetupDialogData *) getPtr(bp,memenv); bp += 4;
} break;
- }};
+ }};
wxPageSetupDialog * Result = new EwxPageSetupDialog(parent,data);
newPtr((void *) Result, 1, memenv);
rt.addRef(getRef((void *)Result,memenv), "wxPageSetupDialog");
- break;
+ break;
}
-case wxPageSetupDialog_GetPageSetupData: { // wxPageSetupDialog::GetPageSetupData
+case wxPageSetupDialog_GetPageSetupData: { // wxPageSetupDialog::GetPageSetupData
wxPageSetupDialog *This = (wxPageSetupDialog *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
wxPageSetupDialogData * Result = &This->GetPageSetupData();
rt.addRef(getRef((void *)Result,memenv), "wxPageSetupDialogData");
- break;
+ break;
}
-case wxPageSetupDialog_ShowModal: { // wxPageSetupDialog::ShowModal
+case wxPageSetupDialog_ShowModal: { // wxPageSetupDialog::ShowModal
wxPageSetupDialog *This = (wxPageSetupDialog *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
int Result = This->ShowModal();
rt.addInt(Result);
- break;
+ break;
}
-case wxPageSetupDialogData_new_0: { // wxPageSetupDialogData::wxPageSetupDialogData
+case wxPageSetupDialogData_new_0: { // wxPageSetupDialogData::wxPageSetupDialogData
wxPageSetupDialogData * Result = new EwxPageSetupDialogData();
newPtr((void *) Result, 1, memenv);
rt.addRef(getRef((void *)Result,memenv), "wxPageSetupDialogData");
- break;
+ break;
}
-case wxPageSetupDialogData_new_1_0: { // wxPageSetupDialogData::wxPageSetupDialogData
+case wxPageSetupDialogData_new_1_0: { // wxPageSetupDialogData::wxPageSetupDialogData
wxPageSetupDialogData *dialogData = (wxPageSetupDialogData *) getPtr(bp,memenv); bp += 4;
wxPageSetupDialogData * Result = new EwxPageSetupDialogData(*dialogData);
newPtr((void *) Result, 1, memenv);
rt.addRef(getRef((void *)Result,memenv), "wxPageSetupDialogData");
- break;
+ break;
}
-case wxPageSetupDialogData_new_1_1: { // wxPageSetupDialogData::wxPageSetupDialogData
+case wxPageSetupDialogData_new_1_1: { // wxPageSetupDialogData::wxPageSetupDialogData
wxPrintData * printData = (wxPrintData *) getPtr(bp,memenv); bp += 4;
wxPageSetupDialogData * Result = new EwxPageSetupDialogData(*printData);
newPtr((void *) Result, 1, memenv);
rt.addRef(getRef((void *)Result,memenv), "wxPageSetupDialogData");
- break;
+ break;
}
-case wxPageSetupDialogData_EnableHelp: { // wxPageSetupDialogData::EnableHelp
+case wxPageSetupDialogData_EnableHelp: { // wxPageSetupDialogData::EnableHelp
wxPageSetupDialogData *This = (wxPageSetupDialogData *) getPtr(bp,memenv); bp += 4;
bool * flag = (bool *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
This->EnableHelp((bool) *flag);
- break;
+ break;
}
-case wxPageSetupDialogData_EnableMargins: { // wxPageSetupDialogData::EnableMargins
+case wxPageSetupDialogData_EnableMargins: { // wxPageSetupDialogData::EnableMargins
wxPageSetupDialogData *This = (wxPageSetupDialogData *) getPtr(bp,memenv); bp += 4;
bool * flag = (bool *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
This->EnableMargins((bool) *flag);
- break;
+ break;
}
-case wxPageSetupDialogData_EnableOrientation: { // wxPageSetupDialogData::EnableOrientation
+case wxPageSetupDialogData_EnableOrientation: { // wxPageSetupDialogData::EnableOrientation
wxPageSetupDialogData *This = (wxPageSetupDialogData *) getPtr(bp,memenv); bp += 4;
bool * flag = (bool *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
This->EnableOrientation((bool) *flag);
- break;
+ break;
}
-case wxPageSetupDialogData_EnablePaper: { // wxPageSetupDialogData::EnablePaper
+case wxPageSetupDialogData_EnablePaper: { // wxPageSetupDialogData::EnablePaper
wxPageSetupDialogData *This = (wxPageSetupDialogData *) getPtr(bp,memenv); bp += 4;
bool * flag = (bool *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
This->EnablePaper((bool) *flag);
- break;
+ break;
}
-case wxPageSetupDialogData_EnablePrinter: { // wxPageSetupDialogData::EnablePrinter
+case wxPageSetupDialogData_EnablePrinter: { // wxPageSetupDialogData::EnablePrinter
wxPageSetupDialogData *This = (wxPageSetupDialogData *) getPtr(bp,memenv); bp += 4;
bool * flag = (bool *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
This->EnablePrinter((bool) *flag);
- break;
+ break;
}
-case wxPageSetupDialogData_GetDefaultMinMargins: { // wxPageSetupDialogData::GetDefaultMinMargins
+case wxPageSetupDialogData_GetDefaultMinMargins: { // wxPageSetupDialogData::GetDefaultMinMargins
wxPageSetupDialogData *This = (wxPageSetupDialogData *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
bool Result = This->GetDefaultMinMargins();
rt.addBool(Result);
- break;
+ break;
}
-case wxPageSetupDialogData_GetEnableMargins: { // wxPageSetupDialogData::GetEnableMargins
+case wxPageSetupDialogData_GetEnableMargins: { // wxPageSetupDialogData::GetEnableMargins
wxPageSetupDialogData *This = (wxPageSetupDialogData *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
bool Result = This->GetEnableMargins();
rt.addBool(Result);
- break;
+ break;
}
-case wxPageSetupDialogData_GetEnableOrientation: { // wxPageSetupDialogData::GetEnableOrientation
+case wxPageSetupDialogData_GetEnableOrientation: { // wxPageSetupDialogData::GetEnableOrientation
wxPageSetupDialogData *This = (wxPageSetupDialogData *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
bool Result = This->GetEnableOrientation();
rt.addBool(Result);
- break;
+ break;
}
-case wxPageSetupDialogData_GetEnablePaper: { // wxPageSetupDialogData::GetEnablePaper
+case wxPageSetupDialogData_GetEnablePaper: { // wxPageSetupDialogData::GetEnablePaper
wxPageSetupDialogData *This = (wxPageSetupDialogData *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
bool Result = This->GetEnablePaper();
rt.addBool(Result);
- break;
+ break;
}
-case wxPageSetupDialogData_GetEnablePrinter: { // wxPageSetupDialogData::GetEnablePrinter
+case wxPageSetupDialogData_GetEnablePrinter: { // wxPageSetupDialogData::GetEnablePrinter
wxPageSetupDialogData *This = (wxPageSetupDialogData *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
bool Result = This->GetEnablePrinter();
rt.addBool(Result);
- break;
+ break;
}
-case wxPageSetupDialogData_GetEnableHelp: { // wxPageSetupDialogData::GetEnableHelp
+case wxPageSetupDialogData_GetEnableHelp: { // wxPageSetupDialogData::GetEnableHelp
wxPageSetupDialogData *This = (wxPageSetupDialogData *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
bool Result = This->GetEnableHelp();
rt.addBool(Result);
- break;
+ break;
}
-case wxPageSetupDialogData_GetDefaultInfo: { // wxPageSetupDialogData::GetDefaultInfo
+case wxPageSetupDialogData_GetDefaultInfo: { // wxPageSetupDialogData::GetDefaultInfo
wxPageSetupDialogData *This = (wxPageSetupDialogData *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
bool Result = This->GetDefaultInfo();
rt.addBool(Result);
- break;
+ break;
}
-case wxPageSetupDialogData_GetMarginTopLeft: { // wxPageSetupDialogData::GetMarginTopLeft
+case wxPageSetupDialogData_GetMarginTopLeft: { // wxPageSetupDialogData::GetMarginTopLeft
wxPageSetupDialogData *This = (wxPageSetupDialogData *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
wxPoint Result = This->GetMarginTopLeft();
rt.add(Result);
- break;
+ break;
}
-case wxPageSetupDialogData_GetMarginBottomRight: { // wxPageSetupDialogData::GetMarginBottomRight
+case wxPageSetupDialogData_GetMarginBottomRight: { // wxPageSetupDialogData::GetMarginBottomRight
wxPageSetupDialogData *This = (wxPageSetupDialogData *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
wxPoint Result = This->GetMarginBottomRight();
rt.add(Result);
- break;
+ break;
}
-case wxPageSetupDialogData_GetMinMarginTopLeft: { // wxPageSetupDialogData::GetMinMarginTopLeft
+case wxPageSetupDialogData_GetMinMarginTopLeft: { // wxPageSetupDialogData::GetMinMarginTopLeft
wxPageSetupDialogData *This = (wxPageSetupDialogData *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
wxPoint Result = This->GetMinMarginTopLeft();
rt.add(Result);
- break;
+ break;
}
-case wxPageSetupDialogData_GetMinMarginBottomRight: { // wxPageSetupDialogData::GetMinMarginBottomRight
+case wxPageSetupDialogData_GetMinMarginBottomRight: { // wxPageSetupDialogData::GetMinMarginBottomRight
wxPageSetupDialogData *This = (wxPageSetupDialogData *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
wxPoint Result = This->GetMinMarginBottomRight();
rt.add(Result);
- break;
+ break;
}
-case wxPageSetupDialogData_GetPaperId: { // wxPageSetupDialogData::GetPaperId
+case wxPageSetupDialogData_GetPaperId: { // wxPageSetupDialogData::GetPaperId
wxPageSetupDialogData *This = (wxPageSetupDialogData *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
wxPaperSize Result = This->GetPaperId();
rt.addInt(Result);
- break;
+ break;
}
-case wxPageSetupDialogData_GetPaperSize: { // wxPageSetupDialogData::GetPaperSize
+case wxPageSetupDialogData_GetPaperSize: { // wxPageSetupDialogData::GetPaperSize
wxPageSetupDialogData *This = (wxPageSetupDialogData *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
wxSize Result = This->GetPaperSize();
rt.add(Result);
- break;
+ break;
}
-case wxPageSetupDialogData_GetPrintData: { // wxPageSetupDialogData::GetPrintData
+case wxPageSetupDialogData_GetPrintData: { // wxPageSetupDialogData::GetPrintData
wxPageSetupDialogData *This = (wxPageSetupDialogData *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
const wxPrintData * Result = &This->GetPrintData();
rt.addRef(getRef((void *)Result,memenv), "wxPrintData");
- break;
+ break;
}
-case wxPageSetupDialogData_IsOk: { // wxPageSetupDialogData::IsOk
+case wxPageSetupDialogData_IsOk: { // wxPageSetupDialogData::IsOk
wxPageSetupDialogData *This = (wxPageSetupDialogData *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
bool Result = This->IsOk();
rt.addBool(Result);
- break;
+ break;
}
-case wxPageSetupDialogData_SetDefaultInfo: { // wxPageSetupDialogData::SetDefaultInfo
+case wxPageSetupDialogData_SetDefaultInfo: { // wxPageSetupDialogData::SetDefaultInfo
wxPageSetupDialogData *This = (wxPageSetupDialogData *) getPtr(bp,memenv); bp += 4;
bool * flag = (bool *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
This->SetDefaultInfo((bool) *flag);
- break;
+ break;
}
-case wxPageSetupDialogData_SetDefaultMinMargins: { // wxPageSetupDialogData::SetDefaultMinMargins
+case wxPageSetupDialogData_SetDefaultMinMargins: { // wxPageSetupDialogData::SetDefaultMinMargins
wxPageSetupDialogData *This = (wxPageSetupDialogData *) getPtr(bp,memenv); bp += 4;
bool * flag = (bool *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
This->SetDefaultMinMargins((bool) *flag);
- break;
+ break;
}
-case wxPageSetupDialogData_SetMarginTopLeft: { // wxPageSetupDialogData::SetMarginTopLeft
+case wxPageSetupDialogData_SetMarginTopLeft: { // wxPageSetupDialogData::SetMarginTopLeft
wxPageSetupDialogData *This = (wxPageSetupDialogData *) getPtr(bp,memenv); bp += 4;
int * ptX = (int *) bp; bp += 4;
int * ptY = (int *) bp; bp += 4;
wxPoint pt = wxPoint(*ptX,*ptY);
if(!This) throw wxe_badarg(0);
This->SetMarginTopLeft(pt);
- break;
+ break;
}
-case wxPageSetupDialogData_SetMarginBottomRight: { // wxPageSetupDialogData::SetMarginBottomRight
+case wxPageSetupDialogData_SetMarginBottomRight: { // wxPageSetupDialogData::SetMarginBottomRight
wxPageSetupDialogData *This = (wxPageSetupDialogData *) getPtr(bp,memenv); bp += 4;
int * ptX = (int *) bp; bp += 4;
int * ptY = (int *) bp; bp += 4;
wxPoint pt = wxPoint(*ptX,*ptY);
if(!This) throw wxe_badarg(0);
This->SetMarginBottomRight(pt);
- break;
+ break;
}
-case wxPageSetupDialogData_SetMinMarginTopLeft: { // wxPageSetupDialogData::SetMinMarginTopLeft
+case wxPageSetupDialogData_SetMinMarginTopLeft: { // wxPageSetupDialogData::SetMinMarginTopLeft
wxPageSetupDialogData *This = (wxPageSetupDialogData *) getPtr(bp,memenv); bp += 4;
int * ptX = (int *) bp; bp += 4;
int * ptY = (int *) bp; bp += 4;
wxPoint pt = wxPoint(*ptX,*ptY);
if(!This) throw wxe_badarg(0);
This->SetMinMarginTopLeft(pt);
- break;
+ break;
}
-case wxPageSetupDialogData_SetMinMarginBottomRight: { // wxPageSetupDialogData::SetMinMarginBottomRight
+case wxPageSetupDialogData_SetMinMarginBottomRight: { // wxPageSetupDialogData::SetMinMarginBottomRight
wxPageSetupDialogData *This = (wxPageSetupDialogData *) getPtr(bp,memenv); bp += 4;
int * ptX = (int *) bp; bp += 4;
int * ptY = (int *) bp; bp += 4;
wxPoint pt = wxPoint(*ptX,*ptY);
if(!This) throw wxe_badarg(0);
This->SetMinMarginBottomRight(pt);
- break;
+ break;
}
-case wxPageSetupDialogData_SetPaperId: { // wxPageSetupDialogData::SetPaperId
+case wxPageSetupDialogData_SetPaperId: { // wxPageSetupDialogData::SetPaperId
wxPageSetupDialogData *This = (wxPageSetupDialogData *) getPtr(bp,memenv); bp += 4;
int * id = (int *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
This->SetPaperId((wxPaperSize) *id);
- break;
+ break;
}
-case wxPageSetupDialogData_SetPaperSize_1_1: { // wxPageSetupDialogData::SetPaperSize
+case wxPageSetupDialogData_SetPaperSize_1_1: { // wxPageSetupDialogData::SetPaperSize
wxPageSetupDialogData *This = (wxPageSetupDialogData *) getPtr(bp,memenv); bp += 4;
int * szW = (int *) bp; bp += 4;
int * szH = (int *) bp; bp += 4;
wxSize sz = wxSize(*szW,*szH);
if(!This) throw wxe_badarg(0);
This->SetPaperSize(sz);
- break;
+ break;
}
-case wxPageSetupDialogData_SetPaperSize_1_0: { // wxPageSetupDialogData::SetPaperSize
+case wxPageSetupDialogData_SetPaperSize_1_0: { // wxPageSetupDialogData::SetPaperSize
wxPageSetupDialogData *This = (wxPageSetupDialogData *) getPtr(bp,memenv); bp += 4;
int * id = (int *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
This->SetPaperSize((wxPaperSize) *id);
- break;
+ break;
}
-case wxPageSetupDialogData_SetPrintData: { // wxPageSetupDialogData::SetPrintData
+case wxPageSetupDialogData_SetPrintData: { // wxPageSetupDialogData::SetPrintData
wxPageSetupDialogData *This = (wxPageSetupDialogData *) getPtr(bp,memenv); bp += 4;
wxPrintData *printData = (wxPrintData *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
This->SetPrintData(*printData);
- break;
+ break;
}
-case wxPrintDialog_new_2_0: { // wxPrintDialog::wxPrintDialog
+case wxPrintDialog_new_2_0: { // wxPrintDialog::wxPrintDialog
wxPrintDialogData * data=NULL;
wxWindow *parent = (wxWindow *) getPtr(bp,memenv); bp += 4;
bp += 4; /* Align */
- while( * (int*) bp) { switch (* (int*) bp) {
+ while( * (int*) bp) { switch (* (int*) bp) {
case 1: {bp += 4;
data = (wxPrintDialogData *) getPtr(bp,memenv); bp += 4;
} break;
- }};
+ }};
wxPrintDialog * Result = new EwxPrintDialog(parent,data);
newPtr((void *) Result, 2, memenv);
rt.addRef(getRef((void *)Result,memenv), "wxPrintDialog");
- break;
+ break;
}
-case wxPrintDialog_new_2_1: { // wxPrintDialog::wxPrintDialog
+case wxPrintDialog_new_2_1: { // wxPrintDialog::wxPrintDialog
wxWindow *parent = (wxWindow *) getPtr(bp,memenv); bp += 4;
wxPrintData *data = (wxPrintData *) getPtr(bp,memenv); bp += 4;
wxPrintDialog * Result = new EwxPrintDialog(parent,data);
newPtr((void *) Result, 2, memenv);
rt.addRef(getRef((void *)Result,memenv), "wxPrintDialog");
- break;
+ break;
}
-case wxPrintDialog_GetPrintDialogData: { // wxPrintDialog::GetPrintDialogData
+case wxPrintDialog_GetPrintDialogData: { // wxPrintDialog::GetPrintDialogData
wxPrintDialog *This = (wxPrintDialog *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
wxPrintDialogData * Result = &This->GetPrintDialogData();
rt.addRef(getRef((void *)Result,memenv), "wxPrintDialogData");
- break;
+ break;
}
-case wxPrintDialog_GetPrintDC: { // wxPrintDialog::GetPrintDC
+case wxPrintDialog_GetPrintDC: { // wxPrintDialog::GetPrintDC
wxPrintDialog *This = (wxPrintDialog *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
wxDC * Result = (wxDC*)This->GetPrintDC();
rt.addRef(getRef((void *)Result,memenv), "wxDC");
- break;
+ break;
}
-case wxPrintDialogData_new_0: { // wxPrintDialogData::wxPrintDialogData
+case wxPrintDialogData_new_0: { // wxPrintDialogData::wxPrintDialogData
wxPrintDialogData * Result = new EwxPrintDialogData();
newPtr((void *) Result, 1, memenv);
rt.addRef(getRef((void *)Result,memenv), "wxPrintDialogData");
- break;
+ break;
}
-case wxPrintDialogData_new_1_1: { // wxPrintDialogData::wxPrintDialogData
+case wxPrintDialogData_new_1_1: { // wxPrintDialogData::wxPrintDialogData
wxPrintDialogData * dialogData = (wxPrintDialogData *) getPtr(bp,memenv); bp += 4;
wxPrintDialogData * Result = new EwxPrintDialogData(*dialogData);
newPtr((void *) Result, 1, memenv);
rt.addRef(getRef((void *)Result,memenv), "wxPrintDialogData");
- break;
+ break;
}
-case wxPrintDialogData_new_1_0: { // wxPrintDialogData::wxPrintDialogData
+case wxPrintDialogData_new_1_0: { // wxPrintDialogData::wxPrintDialogData
wxPrintData *printData = (wxPrintData *) getPtr(bp,memenv); bp += 4;
wxPrintDialogData * Result = new EwxPrintDialogData(*printData);
newPtr((void *) Result, 1, memenv);
rt.addRef(getRef((void *)Result,memenv), "wxPrintDialogData");
- break;
+ break;
}
-case wxPrintDialogData_EnableHelp: { // wxPrintDialogData::EnableHelp
+case wxPrintDialogData_EnableHelp: { // wxPrintDialogData::EnableHelp
wxPrintDialogData *This = (wxPrintDialogData *) getPtr(bp,memenv); bp += 4;
bool * flag = (bool *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
This->EnableHelp((bool) *flag);
- break;
+ break;
}
-case wxPrintDialogData_EnablePageNumbers: { // wxPrintDialogData::EnablePageNumbers
+case wxPrintDialogData_EnablePageNumbers: { // wxPrintDialogData::EnablePageNumbers
wxPrintDialogData *This = (wxPrintDialogData *) getPtr(bp,memenv); bp += 4;
bool * flag = (bool *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
This->EnablePageNumbers((bool) *flag);
- break;
+ break;
}
-case wxPrintDialogData_EnablePrintToFile: { // wxPrintDialogData::EnablePrintToFile
+case wxPrintDialogData_EnablePrintToFile: { // wxPrintDialogData::EnablePrintToFile
wxPrintDialogData *This = (wxPrintDialogData *) getPtr(bp,memenv); bp += 4;
bool * flag = (bool *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
This->EnablePrintToFile((bool) *flag);
- break;
+ break;
}
-case wxPrintDialogData_EnableSelection: { // wxPrintDialogData::EnableSelection
+case wxPrintDialogData_EnableSelection: { // wxPrintDialogData::EnableSelection
wxPrintDialogData *This = (wxPrintDialogData *) getPtr(bp,memenv); bp += 4;
bool * flag = (bool *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
This->EnableSelection((bool) *flag);
- break;
+ break;
}
-case wxPrintDialogData_GetAllPages: { // wxPrintDialogData::GetAllPages
+case wxPrintDialogData_GetAllPages: { // wxPrintDialogData::GetAllPages
wxPrintDialogData *This = (wxPrintDialogData *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
bool Result = This->GetAllPages();
rt.addBool(Result);
- break;
+ break;
}
-case wxPrintDialogData_GetCollate: { // wxPrintDialogData::GetCollate
+case wxPrintDialogData_GetCollate: { // wxPrintDialogData::GetCollate
wxPrintDialogData *This = (wxPrintDialogData *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
bool Result = This->GetCollate();
rt.addBool(Result);
- break;
+ break;
}
-case wxPrintDialogData_GetFromPage: { // wxPrintDialogData::GetFromPage
+case wxPrintDialogData_GetFromPage: { // wxPrintDialogData::GetFromPage
wxPrintDialogData *This = (wxPrintDialogData *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
int Result = This->GetFromPage();
rt.addInt(Result);
- break;
+ break;
}
-case wxPrintDialogData_GetMaxPage: { // wxPrintDialogData::GetMaxPage
+case wxPrintDialogData_GetMaxPage: { // wxPrintDialogData::GetMaxPage
wxPrintDialogData *This = (wxPrintDialogData *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
int Result = This->GetMaxPage();
rt.addInt(Result);
- break;
+ break;
}
-case wxPrintDialogData_GetMinPage: { // wxPrintDialogData::GetMinPage
+case wxPrintDialogData_GetMinPage: { // wxPrintDialogData::GetMinPage
wxPrintDialogData *This = (wxPrintDialogData *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
int Result = This->GetMinPage();
rt.addInt(Result);
- break;
+ break;
}
-case wxPrintDialogData_GetNoCopies: { // wxPrintDialogData::GetNoCopies
+case wxPrintDialogData_GetNoCopies: { // wxPrintDialogData::GetNoCopies
wxPrintDialogData *This = (wxPrintDialogData *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
int Result = This->GetNoCopies();
rt.addInt(Result);
- break;
+ break;
}
-case wxPrintDialogData_GetPrintData: { // wxPrintDialogData::GetPrintData
+case wxPrintDialogData_GetPrintData: { // wxPrintDialogData::GetPrintData
wxPrintDialogData *This = (wxPrintDialogData *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
wxPrintData * Result = &This->GetPrintData();
rt.addRef(getRef((void *)Result,memenv), "wxPrintData");
- break;
+ break;
}
-case wxPrintDialogData_GetPrintToFile: { // wxPrintDialogData::GetPrintToFile
+case wxPrintDialogData_GetPrintToFile: { // wxPrintDialogData::GetPrintToFile
wxPrintDialogData *This = (wxPrintDialogData *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
bool Result = This->GetPrintToFile();
rt.addBool(Result);
- break;
+ break;
}
-case wxPrintDialogData_GetSelection: { // wxPrintDialogData::GetSelection
+case wxPrintDialogData_GetSelection: { // wxPrintDialogData::GetSelection
wxPrintDialogData *This = (wxPrintDialogData *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
bool Result = This->GetSelection();
rt.addBool(Result);
- break;
+ break;
}
-case wxPrintDialogData_GetToPage: { // wxPrintDialogData::GetToPage
+case wxPrintDialogData_GetToPage: { // wxPrintDialogData::GetToPage
wxPrintDialogData *This = (wxPrintDialogData *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
int Result = This->GetToPage();
rt.addInt(Result);
- break;
+ break;
}
-case wxPrintDialogData_IsOk: { // wxPrintDialogData::IsOk
+case wxPrintDialogData_IsOk: { // wxPrintDialogData::IsOk
wxPrintDialogData *This = (wxPrintDialogData *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
bool Result = This->IsOk();
rt.addBool(Result);
- break;
+ break;
}
-case wxPrintDialogData_SetCollate: { // wxPrintDialogData::SetCollate
+case wxPrintDialogData_SetCollate: { // wxPrintDialogData::SetCollate
wxPrintDialogData *This = (wxPrintDialogData *) getPtr(bp,memenv); bp += 4;
bool * flag = (bool *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
This->SetCollate((bool) *flag);
- break;
+ break;
}
-case wxPrintDialogData_SetFromPage: { // wxPrintDialogData::SetFromPage
+case wxPrintDialogData_SetFromPage: { // wxPrintDialogData::SetFromPage
wxPrintDialogData *This = (wxPrintDialogData *) getPtr(bp,memenv); bp += 4;
int * v = (int *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
This->SetFromPage((int) *v);
- break;
+ break;
}
-case wxPrintDialogData_SetMaxPage: { // wxPrintDialogData::SetMaxPage
+case wxPrintDialogData_SetMaxPage: { // wxPrintDialogData::SetMaxPage
wxPrintDialogData *This = (wxPrintDialogData *) getPtr(bp,memenv); bp += 4;
int * v = (int *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
This->SetMaxPage((int) *v);
- break;
+ break;
}
-case wxPrintDialogData_SetMinPage: { // wxPrintDialogData::SetMinPage
+case wxPrintDialogData_SetMinPage: { // wxPrintDialogData::SetMinPage
wxPrintDialogData *This = (wxPrintDialogData *) getPtr(bp,memenv); bp += 4;
int * v = (int *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
This->SetMinPage((int) *v);
- break;
+ break;
}
-case wxPrintDialogData_SetNoCopies: { // wxPrintDialogData::SetNoCopies
+case wxPrintDialogData_SetNoCopies: { // wxPrintDialogData::SetNoCopies
wxPrintDialogData *This = (wxPrintDialogData *) getPtr(bp,memenv); bp += 4;
int * v = (int *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
This->SetNoCopies((int) *v);
- break;
+ break;
}
-case wxPrintDialogData_SetPrintData: { // wxPrintDialogData::SetPrintData
+case wxPrintDialogData_SetPrintData: { // wxPrintDialogData::SetPrintData
wxPrintDialogData *This = (wxPrintDialogData *) getPtr(bp,memenv); bp += 4;
wxPrintData *printData = (wxPrintData *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
This->SetPrintData(*printData);
- break;
+ break;
}
-case wxPrintDialogData_SetPrintToFile: { // wxPrintDialogData::SetPrintToFile
+case wxPrintDialogData_SetPrintToFile: { // wxPrintDialogData::SetPrintToFile
wxPrintDialogData *This = (wxPrintDialogData *) getPtr(bp,memenv); bp += 4;
bool * flag = (bool *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
This->SetPrintToFile((bool) *flag);
- break;
+ break;
}
-case wxPrintDialogData_SetSelection: { // wxPrintDialogData::SetSelection
+case wxPrintDialogData_SetSelection: { // wxPrintDialogData::SetSelection
wxPrintDialogData *This = (wxPrintDialogData *) getPtr(bp,memenv); bp += 4;
bool * flag = (bool *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
This->SetSelection((bool) *flag);
- break;
+ break;
}
-case wxPrintDialogData_SetToPage: { // wxPrintDialogData::SetToPage
+case wxPrintDialogData_SetToPage: { // wxPrintDialogData::SetToPage
wxPrintDialogData *This = (wxPrintDialogData *) getPtr(bp,memenv); bp += 4;
int * v = (int *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
This->SetToPage((int) *v);
- break;
+ break;
}
-case wxPrintData_new_0: { // wxPrintData::wxPrintData
+case wxPrintData_new_0: { // wxPrintData::wxPrintData
wxPrintData * Result = new EwxPrintData();
newPtr((void *) Result, 1, memenv);
rt.addRef(getRef((void *)Result,memenv), "wxPrintData");
- break;
+ break;
}
-case wxPrintData_new_1: { // wxPrintData::wxPrintData
+case wxPrintData_new_1: { // wxPrintData::wxPrintData
wxPrintData *printData = (wxPrintData *) getPtr(bp,memenv); bp += 4;
wxPrintData * Result = new EwxPrintData(*printData);
newPtr((void *) Result, 1, memenv);
rt.addRef(getRef((void *)Result,memenv), "wxPrintData");
- break;
+ break;
}
-case wxPrintData_GetCollate: { // wxPrintData::GetCollate
+case wxPrintData_GetCollate: { // wxPrintData::GetCollate
wxPrintData *This = (wxPrintData *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
bool Result = This->GetCollate();
rt.addBool(Result);
- break;
+ break;
}
-case wxPrintData_GetBin: { // wxPrintData::GetBin
+case wxPrintData_GetBin: { // wxPrintData::GetBin
wxPrintData *This = (wxPrintData *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
int Result = This->GetBin();
rt.addInt(Result);
- break;
+ break;
}
-case wxPrintData_GetColour: { // wxPrintData::GetColour
+case wxPrintData_GetColour: { // wxPrintData::GetColour
wxPrintData *This = (wxPrintData *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
bool Result = This->GetColour();
rt.addBool(Result);
- break;
+ break;
}
-case wxPrintData_GetDuplex: { // wxPrintData::GetDuplex
+case wxPrintData_GetDuplex: { // wxPrintData::GetDuplex
wxPrintData *This = (wxPrintData *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
int Result = This->GetDuplex();
rt.addInt(Result);
- break;
+ break;
}
-case wxPrintData_GetNoCopies: { // wxPrintData::GetNoCopies
+case wxPrintData_GetNoCopies: { // wxPrintData::GetNoCopies
wxPrintData *This = (wxPrintData *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
int Result = This->GetNoCopies();
rt.addInt(Result);
- break;
+ break;
}
-case wxPrintData_GetOrientation: { // wxPrintData::GetOrientation
+case wxPrintData_GetOrientation: { // wxPrintData::GetOrientation
wxPrintData *This = (wxPrintData *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
int Result = This->GetOrientation();
rt.addInt(Result);
- break;
+ break;
}
-case wxPrintData_GetPaperId: { // wxPrintData::GetPaperId
+case wxPrintData_GetPaperId: { // wxPrintData::GetPaperId
wxPrintData *This = (wxPrintData *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
wxPaperSize Result = This->GetPaperId();
rt.addInt(Result);
- break;
+ break;
}
-case wxPrintData_GetPrinterName: { // wxPrintData::GetPrinterName
+case wxPrintData_GetPrinterName: { // wxPrintData::GetPrinterName
wxPrintData *This = (wxPrintData *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
const wxString * Result = &This->GetPrinterName();
rt.add(Result);
- break;
+ break;
}
-case wxPrintData_GetQuality: { // wxPrintData::GetQuality
+case wxPrintData_GetQuality: { // wxPrintData::GetQuality
wxPrintData *This = (wxPrintData *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
wxPrintQuality Result = This->GetQuality();
rt.addInt(Result);
- break;
+ break;
}
-case wxPrintData_IsOk: { // wxPrintData::IsOk
+case wxPrintData_IsOk: { // wxPrintData::IsOk
wxPrintData *This = (wxPrintData *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
bool Result = This->IsOk();
rt.addBool(Result);
- break;
+ break;
}
-case wxPrintData_SetBin: { // wxPrintData::SetBin
+case wxPrintData_SetBin: { // wxPrintData::SetBin
wxPrintData *This = (wxPrintData *) getPtr(bp,memenv); bp += 4;
wxPrintBin bin = *(wxPrintBin *) bp; bp += 4;;
if(!This) throw wxe_badarg(0);
This->SetBin((wxPrintBin) bin);
- break;
+ break;
}
-case wxPrintData_SetCollate: { // wxPrintData::SetCollate
+case wxPrintData_SetCollate: { // wxPrintData::SetCollate
wxPrintData *This = (wxPrintData *) getPtr(bp,memenv); bp += 4;
bool * flag = (bool *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
This->SetCollate((bool) *flag);
- break;
+ break;
}
-case wxPrintData_SetColour: { // wxPrintData::SetColour
+case wxPrintData_SetColour: { // wxPrintData::SetColour
wxPrintData *This = (wxPrintData *) getPtr(bp,memenv); bp += 4;
bool * colour = (bool *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
This->SetColour((bool) *colour);
- break;
+ break;
}
-case wxPrintData_SetDuplex: { // wxPrintData::SetDuplex
+case wxPrintData_SetDuplex: { // wxPrintData::SetDuplex
wxPrintData *This = (wxPrintData *) getPtr(bp,memenv); bp += 4;
wxDuplexMode duplex = *(wxDuplexMode *) bp; bp += 4;;
if(!This) throw wxe_badarg(0);
This->SetDuplex((wxDuplexMode) duplex);
- break;
+ break;
}
-case wxPrintData_SetNoCopies: { // wxPrintData::SetNoCopies
+case wxPrintData_SetNoCopies: { // wxPrintData::SetNoCopies
wxPrintData *This = (wxPrintData *) getPtr(bp,memenv); bp += 4;
int * v = (int *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
This->SetNoCopies((int) *v);
- break;
+ break;
}
-case wxPrintData_SetOrientation: { // wxPrintData::SetOrientation
+case wxPrintData_SetOrientation: { // wxPrintData::SetOrientation
wxPrintData *This = (wxPrintData *) getPtr(bp,memenv); bp += 4;
int * orient = (int *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
This->SetOrientation((int) *orient);
- break;
+ break;
}
-case wxPrintData_SetPaperId: { // wxPrintData::SetPaperId
+case wxPrintData_SetPaperId: { // wxPrintData::SetPaperId
wxPrintData *This = (wxPrintData *) getPtr(bp,memenv); bp += 4;
int * sizeId = (int *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
This->SetPaperId((wxPaperSize) *sizeId);
- break;
+ break;
}
-case wxPrintData_SetPrinterName: { // wxPrintData::SetPrinterName
+case wxPrintData_SetPrinterName: { // wxPrintData::SetPrinterName
wxPrintData *This = (wxPrintData *) getPtr(bp,memenv); bp += 4;
int * nameLen = (int *) bp; bp += 4;
wxString name = wxString(bp, wxConvUTF8);
bp += *nameLen+((8-((0+ *nameLen) & 7)) & 7);
if(!This) throw wxe_badarg(0);
This->SetPrinterName(name);
- break;
+ break;
}
-case wxPrintData_SetQuality: { // wxPrintData::SetQuality
+case wxPrintData_SetQuality: { // wxPrintData::SetQuality
wxPrintData *This = (wxPrintData *) getPtr(bp,memenv); bp += 4;
int * quality = (int *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
This->SetQuality((wxPrintQuality) *quality);
- break;
+ break;
}
-case wxPrintPreview_new_2: { // wxPrintPreview::wxPrintPreview
+case wxPrintPreview_new_2: { // wxPrintPreview::wxPrintPreview
wxPrintout * printoutForPrinting=(wxPrintout *) NULL;
wxPrintDialogData * data=(wxPrintDialogData *) NULL;
wxPrintout *printout = (wxPrintout *) getPtr(bp,memenv); bp += 4;
bp += 4; /* Align */
- while( * (int*) bp) { switch (* (int*) bp) {
+ while( * (int*) bp) { switch (* (int*) bp) {
case 1: {bp += 4;
printoutForPrinting = (wxPrintout *) getPtr(bp,memenv); bp += 4;
} break;
case 2: {bp += 4;
data = (wxPrintDialogData *) getPtr(bp,memenv); bp += 4;
} break;
- }};
+ }};
wxPrintPreview * Result = new EwxPrintPreview(printout,printoutForPrinting,data);
newPtr((void *) Result, 1, memenv);
rt.addRef(getRef((void *)Result,memenv), "wxPrintPreview");
- break;
+ break;
}
-case wxPrintPreview_new_3: { // wxPrintPreview::wxPrintPreview
+case wxPrintPreview_new_3: { // wxPrintPreview::wxPrintPreview
wxPrintout *printout = (wxPrintout *) getPtr(bp,memenv); bp += 4;
wxPrintout *printoutForPrinting = (wxPrintout *) getPtr(bp,memenv); bp += 4;
wxPrintData *data = (wxPrintData *) getPtr(bp,memenv); bp += 4;
wxPrintPreview * Result = new EwxPrintPreview(printout,printoutForPrinting,data);
newPtr((void *) Result, 1, memenv);
rt.addRef(getRef((void *)Result,memenv), "wxPrintPreview");
- break;
+ break;
}
-case wxPrintPreview_GetCanvas: { // wxPrintPreview::GetCanvas
+case wxPrintPreview_GetCanvas: { // wxPrintPreview::GetCanvas
wxPrintPreview *This = (wxPrintPreview *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
wxPreviewCanvas * Result = (wxPreviewCanvas*)This->GetCanvas();
rt.addRef(getRef((void *)Result,memenv), "wxPreviewCanvas");
- break;
+ break;
}
-case wxPrintPreview_GetCurrentPage: { // wxPrintPreview::GetCurrentPage
+case wxPrintPreview_GetCurrentPage: { // wxPrintPreview::GetCurrentPage
wxPrintPreview *This = (wxPrintPreview *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
int Result = This->GetCurrentPage();
rt.addInt(Result);
- break;
+ break;
}
-case wxPrintPreview_GetFrame: { // wxPrintPreview::GetFrame
+case wxPrintPreview_GetFrame: { // wxPrintPreview::GetFrame
wxPrintPreview *This = (wxPrintPreview *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
wxFrame * Result = (wxFrame*)This->GetFrame();
rt.addRef(getRef((void *)Result,memenv), "wxFrame");
- break;
+ break;
}
-case wxPrintPreview_GetMaxPage: { // wxPrintPreview::GetMaxPage
+case wxPrintPreview_GetMaxPage: { // wxPrintPreview::GetMaxPage
wxPrintPreview *This = (wxPrintPreview *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
int Result = This->GetMaxPage();
rt.addInt(Result);
- break;
+ break;
}
-case wxPrintPreview_GetMinPage: { // wxPrintPreview::GetMinPage
+case wxPrintPreview_GetMinPage: { // wxPrintPreview::GetMinPage
wxPrintPreview *This = (wxPrintPreview *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
int Result = This->GetMinPage();
rt.addInt(Result);
- break;
+ break;
}
-case wxPrintPreview_GetPrintout: { // wxPrintPreview::GetPrintout
+case wxPrintPreview_GetPrintout: { // wxPrintPreview::GetPrintout
wxPrintPreview *This = (wxPrintPreview *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
wxPrintout * Result = (wxPrintout*)This->GetPrintout();
rt.addRef(getRef((void *)Result,memenv), "wxPrintout");
- break;
+ break;
}
-case wxPrintPreview_GetPrintoutForPrinting: { // wxPrintPreview::GetPrintoutForPrinting
+case wxPrintPreview_GetPrintoutForPrinting: { // wxPrintPreview::GetPrintoutForPrinting
wxPrintPreview *This = (wxPrintPreview *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
wxPrintout * Result = (wxPrintout*)This->GetPrintoutForPrinting();
rt.addRef(getRef((void *)Result,memenv), "wxPrintout");
- break;
+ break;
}
-case wxPrintPreview_IsOk: { // wxPrintPreview::IsOk
+case wxPrintPreview_IsOk: { // wxPrintPreview::IsOk
wxPrintPreview *This = (wxPrintPreview *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
bool Result = This->IsOk();
rt.addBool(Result);
- break;
+ break;
}
-case wxPrintPreview_PaintPage: { // wxPrintPreview::PaintPage
+case wxPrintPreview_PaintPage: { // wxPrintPreview::PaintPage
wxPrintPreview *This = (wxPrintPreview *) getPtr(bp,memenv); bp += 4;
wxPreviewCanvas *canvas = (wxPreviewCanvas *) getPtr(bp,memenv); bp += 4;
wxDC *dc = (wxDC *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
bool Result = This->PaintPage(canvas,*dc);
rt.addBool(Result);
- break;
+ break;
}
-case wxPrintPreview_Print: { // wxPrintPreview::Print
+case wxPrintPreview_Print: { // wxPrintPreview::Print
wxPrintPreview *This = (wxPrintPreview *) getPtr(bp,memenv); bp += 4;
bool * interactive = (bool *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
bool Result = This->Print((bool) *interactive);
rt.addBool(Result);
- break;
+ break;
}
-case wxPrintPreview_RenderPage: { // wxPrintPreview::RenderPage
+case wxPrintPreview_RenderPage: { // wxPrintPreview::RenderPage
wxPrintPreview *This = (wxPrintPreview *) getPtr(bp,memenv); bp += 4;
int * pageNum = (int *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
bool Result = This->RenderPage((int) *pageNum);
rt.addBool(Result);
- break;
+ break;
}
-case wxPrintPreview_SetCanvas: { // wxPrintPreview::SetCanvas
+case wxPrintPreview_SetCanvas: { // wxPrintPreview::SetCanvas
wxPrintPreview *This = (wxPrintPreview *) getPtr(bp,memenv); bp += 4;
wxPreviewCanvas *canvas = (wxPreviewCanvas *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
This->SetCanvas(canvas);
- break;
+ break;
}
-case wxPrintPreview_SetCurrentPage: { // wxPrintPreview::SetCurrentPage
+case wxPrintPreview_SetCurrentPage: { // wxPrintPreview::SetCurrentPage
wxPrintPreview *This = (wxPrintPreview *) getPtr(bp,memenv); bp += 4;
int * pageNum = (int *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
bool Result = This->SetCurrentPage((int) *pageNum);
rt.addBool(Result);
- break;
+ break;
}
-case wxPrintPreview_SetFrame: { // wxPrintPreview::SetFrame
+case wxPrintPreview_SetFrame: { // wxPrintPreview::SetFrame
wxPrintPreview *This = (wxPrintPreview *) getPtr(bp,memenv); bp += 4;
wxFrame *frame = (wxFrame *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
This->SetFrame(frame);
- break;
+ break;
}
-case wxPrintPreview_SetPrintout: { // wxPrintPreview::SetPrintout
+case wxPrintPreview_SetPrintout: { // wxPrintPreview::SetPrintout
wxPrintPreview *This = (wxPrintPreview *) getPtr(bp,memenv); bp += 4;
wxPrintout *printout = (wxPrintout *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
This->SetPrintout(printout);
- break;
+ break;
}
-case wxPrintPreview_SetZoom: { // wxPrintPreview::SetZoom
+case wxPrintPreview_SetZoom: { // wxPrintPreview::SetZoom
wxPrintPreview *This = (wxPrintPreview *) getPtr(bp,memenv); bp += 4;
int * percent = (int *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
This->SetZoom((int) *percent);
- break;
+ break;
}
-case wxPreviewFrame_new: { // wxPreviewFrame::wxPreviewFrame
+case wxPreviewFrame_new: { // wxPreviewFrame::wxPreviewFrame
wxString title= wxT("Print Preview");
wxPoint pos= wxDefaultPosition;
wxSize size= wxDefaultSize;
long style=wxDEFAULT_FRAME_STYLE;
wxPrintPreview *preview = (wxPrintPreview *) getPtr(bp,memenv); bp += 4;
wxWindow *parent = (wxWindow *) getPtr(bp,memenv); bp += 4;
- while( * (int*) bp) { switch (* (int*) bp) {
+ while( * (int*) bp) { switch (* (int*) bp) {
case 1: {bp += 4;
int * titleLen = (int *) bp; bp += 4;
title = wxString(bp, wxConvUTF8);
@@ -22674,38 +22716,38 @@ case wxPreviewFrame_new: { // wxPreviewFrame::wxPreviewFrame
case 4: {bp += 4;
style = (long)*(int *) bp; bp += 4;
} break;
- }};
+ }};
wxPreviewFrame * Result = new EwxPreviewFrame(preview,parent,title,pos,size,style);
newPtr((void *) Result, 0, memenv);
rt.addRef(getRef((void *)Result,memenv), "wxPreviewFrame");
- break;
+ break;
}
-case wxPreviewFrame_CreateControlBar: { // wxPreviewFrame::CreateControlBar
+case wxPreviewFrame_CreateControlBar: { // wxPreviewFrame::CreateControlBar
wxPreviewFrame *This = (wxPreviewFrame *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
This->CreateControlBar();
- break;
+ break;
}
-case wxPreviewFrame_CreateCanvas: { // wxPreviewFrame::CreateCanvas
+case wxPreviewFrame_CreateCanvas: { // wxPreviewFrame::CreateCanvas
wxPreviewFrame *This = (wxPreviewFrame *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
This->CreateCanvas();
- break;
+ break;
}
-case wxPreviewFrame_Initialize: { // wxPreviewFrame::Initialize
+case wxPreviewFrame_Initialize: { // wxPreviewFrame::Initialize
wxPreviewFrame *This = (wxPreviewFrame *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
This->Initialize();
- break;
+ break;
}
-case wxPreviewFrame_OnCloseWindow: { // wxPreviewFrame::OnCloseWindow
+case wxPreviewFrame_OnCloseWindow: { // wxPreviewFrame::OnCloseWindow
wxPreviewFrame *This = (wxPreviewFrame *) getPtr(bp,memenv); bp += 4;
wxCloseEvent *event = (wxCloseEvent *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
This->OnCloseWindow(*event);
- break;
+ break;
}
-case wxPreviewControlBar_new: { // wxPreviewControlBar::wxPreviewControlBar
+case wxPreviewControlBar_new: { // wxPreviewControlBar::wxPreviewControlBar
wxPoint pos= wxDefaultPosition;
wxSize size= wxDefaultSize;
long style=wxTAB_TRAVERSAL;
@@ -22713,7 +22755,7 @@ case wxPreviewControlBar_new: { // wxPreviewControlBar::wxPreviewControlBar
int * buttons = (int *) bp; bp += 4;
wxWindow *parent = (wxWindow *) getPtr(bp,memenv); bp += 4;
bp += 4; /* Align */
- while( * (int*) bp) { switch (* (int*) bp) {
+ while( * (int*) bp) { switch (* (int*) bp) {
case 1: {bp += 4;
int * posX = (int *) bp; bp += 4;
int * posY = (int *) bp; bp += 4;
@@ -22729,104 +22771,104 @@ case wxPreviewControlBar_new: { // wxPreviewControlBar::wxPreviewControlBar
case 3: {bp += 4;
style = (long)*(int *) bp; bp += 4;
} break;
- }};
+ }};
wxPreviewControlBar * Result = new EwxPreviewControlBar(preview,(long) *buttons,parent,pos,size,style);
newPtr((void *) Result, 0, memenv);
rt.addRef(getRef((void *)Result,memenv), "wxPreviewControlBar");
- break;
+ break;
}
-case wxPreviewControlBar_CreateButtons: { // wxPreviewControlBar::CreateButtons
+case wxPreviewControlBar_CreateButtons: { // wxPreviewControlBar::CreateButtons
wxPreviewControlBar *This = (wxPreviewControlBar *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
This->CreateButtons();
- break;
+ break;
}
-case wxPreviewControlBar_GetPrintPreview: { // wxPreviewControlBar::GetPrintPreview
+case wxPreviewControlBar_GetPrintPreview: { // wxPreviewControlBar::GetPrintPreview
wxPreviewControlBar *This = (wxPreviewControlBar *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
wxPrintPreview * Result = (wxPrintPreview*)This->GetPrintPreview();
rt.addRef(getRef((void *)Result,memenv), "wxPrintPreview");
- break;
+ break;
}
-case wxPreviewControlBar_GetZoomControl: { // wxPreviewControlBar::GetZoomControl
+case wxPreviewControlBar_GetZoomControl: { // wxPreviewControlBar::GetZoomControl
wxPreviewControlBar *This = (wxPreviewControlBar *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
int Result = This->GetZoomControl();
rt.addInt(Result);
- break;
+ break;
}
-case wxPreviewControlBar_SetZoomControl: { // wxPreviewControlBar::SetZoomControl
+case wxPreviewControlBar_SetZoomControl: { // wxPreviewControlBar::SetZoomControl
wxPreviewControlBar *This = (wxPreviewControlBar *) getPtr(bp,memenv); bp += 4;
int * zoom = (int *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
This->SetZoomControl((int) *zoom);
- break;
+ break;
}
-case wxPrinter_new: { // wxPrinter::wxPrinter
+case wxPrinter_new: { // wxPrinter::wxPrinter
wxPrintDialogData * data=(wxPrintDialogData *) NULL;
- while( * (int*) bp) { switch (* (int*) bp) {
+ while( * (int*) bp) { switch (* (int*) bp) {
case 1: {bp += 4;
data = (wxPrintDialogData *) getPtr(bp,memenv); bp += 4;
} break;
- }};
+ }};
wxPrinter * Result = new EwxPrinter(data);
newPtr((void *) Result, 1, memenv);
rt.addRef(getRef((void *)Result,memenv), "wxPrinter");
- break;
+ break;
}
-case wxPrinter_CreateAbortWindow: { // wxPrinter::CreateAbortWindow
+case wxPrinter_CreateAbortWindow: { // wxPrinter::CreateAbortWindow
wxPrinter *This = (wxPrinter *) getPtr(bp,memenv); bp += 4;
wxWindow *parent = (wxWindow *) getPtr(bp,memenv); bp += 4;
wxPrintout *printout = (wxPrintout *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
wxWindow * Result = (wxWindow*)This->CreateAbortWindow(parent,printout);
rt.addRef(getRef((void *)Result,memenv), "wxWindow");
- break;
+ break;
}
-case wxPrinter_GetAbort: { // wxPrinter::GetAbort
+case wxPrinter_GetAbort: { // wxPrinter::GetAbort
wxPrinter *This = (wxPrinter *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
bool Result = This->GetAbort();
rt.addBool(Result);
- break;
+ break;
}
-case wxPrinter_GetLastError: { // wxPrinter::GetLastError
+case wxPrinter_GetLastError: { // wxPrinter::GetLastError
int Result = wxPrinter::GetLastError();
rt.addInt(Result);
- break;
+ break;
}
-case wxPrinter_GetPrintDialogData: { // wxPrinter::GetPrintDialogData
+case wxPrinter_GetPrintDialogData: { // wxPrinter::GetPrintDialogData
wxPrinter *This = (wxPrinter *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
wxPrintDialogData * Result = &This->GetPrintDialogData();
rt.addRef(getRef((void *)Result,memenv), "wxPrintDialogData");
- break;
+ break;
}
-case wxPrinter_Print: { // wxPrinter::Print
+case wxPrinter_Print: { // wxPrinter::Print
bool prompt=true;
wxPrinter *This = (wxPrinter *) getPtr(bp,memenv); bp += 4;
wxWindow *parent = (wxWindow *) getPtr(bp,memenv); bp += 4;
wxPrintout *printout = (wxPrintout *) getPtr(bp,memenv); bp += 4;
bp += 4; /* Align */
- while( * (int*) bp) { switch (* (int*) bp) {
+ while( * (int*) bp) { switch (* (int*) bp) {
case 1: {bp += 4;
prompt = *(bool *) bp; bp += 4;
} break;
- }};
+ }};
if(!This) throw wxe_badarg(0);
bool Result = This->Print(parent,printout,prompt);
rt.addBool(Result);
- break;
+ break;
}
-case wxPrinter_PrintDialog: { // wxPrinter::PrintDialog
+case wxPrinter_PrintDialog: { // wxPrinter::PrintDialog
wxPrinter *This = (wxPrinter *) getPtr(bp,memenv); bp += 4;
wxWindow *parent = (wxWindow *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
wxDC * Result = (wxDC*)This->PrintDialog(parent);
rt.addRef(getRef((void *)Result,memenv), "wxDC");
- break;
+ break;
}
-case wxPrinter_ReportError: { // wxPrinter::ReportError
+case wxPrinter_ReportError: { // wxPrinter::ReportError
wxPrinter *This = (wxPrinter *) getPtr(bp,memenv); bp += 4;
wxWindow *parent = (wxWindow *) getPtr(bp,memenv); bp += 4;
wxPrintout *printout = (wxPrintout *) getPtr(bp,memenv); bp += 4;
@@ -22835,20 +22877,20 @@ case wxPrinter_ReportError: { // wxPrinter::ReportError
bp += *messageLen+((8-((0+ *messageLen) & 7)) & 7);
if(!This) throw wxe_badarg(0);
This->ReportError(parent,printout,message);
- break;
+ break;
}
-case wxPrinter_Setup: { // wxPrinter::Setup
+case wxPrinter_Setup: { // wxPrinter::Setup
wxPrinter *This = (wxPrinter *) getPtr(bp,memenv); bp += 4;
wxWindow *parent = (wxWindow *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
bool Result = This->Setup(parent);
rt.addBool(Result);
- break;
+ break;
}
-case wxXmlResource_new_1: { // wxXmlResource::wxXmlResource
+case wxXmlResource_new_1: { // wxXmlResource::wxXmlResource
int flags=wxXRC_USE_LOCALE;
wxString domain= wxEmptyString;
- while( * (int*) bp) { switch (* (int*) bp) {
+ while( * (int*) bp) { switch (* (int*) bp) {
case 1: {bp += 4;
flags = (int)*(int *) bp; bp += 4;
} break;
@@ -22857,19 +22899,19 @@ case wxXmlResource_new_1: { // wxXmlResource::wxXmlResource
domain = wxString(bp, wxConvUTF8);
bp += *domainLen+((8-((0+ *domainLen) & 7)) & 7);
} break;
- }};
+ }};
wxXmlResource * Result = new EwxXmlResource(flags,domain);
newPtr((void *) Result, 1, memenv);
rt.addRef(getRef((void *)Result,memenv), "wxXmlResource");
- break;
+ break;
}
-case wxXmlResource_new_2: { // wxXmlResource::wxXmlResource
+case wxXmlResource_new_2: { // wxXmlResource::wxXmlResource
int flags=wxXRC_USE_LOCALE;
wxString domain= wxEmptyString;
int * filemaskLen = (int *) bp; bp += 4;
wxString filemask = wxString(bp, wxConvUTF8);
bp += *filemaskLen+((8-((4+ *filemaskLen) & 7)) & 7);
- while( * (int*) bp) { switch (* (int*) bp) {
+ while( * (int*) bp) { switch (* (int*) bp) {
case 1: {bp += 4;
flags = (int)*(int *) bp; bp += 4;
} break;
@@ -22878,13 +22920,13 @@ case wxXmlResource_new_2: { // wxXmlResource::wxXmlResource
domain = wxString(bp, wxConvUTF8);
bp += *domainLen+((8-((0+ *domainLen) & 7)) & 7);
} break;
- }};
+ }};
wxXmlResource * Result = new EwxXmlResource(filemask,flags,domain);
newPtr((void *) Result, 1, memenv);
rt.addRef(getRef((void *)Result,memenv), "wxXmlResource");
- break;
+ break;
}
-case wxXmlResource_AttachUnknownControl: { // wxXmlResource::AttachUnknownControl
+case wxXmlResource_AttachUnknownControl: { // wxXmlResource::AttachUnknownControl
wxWindow * parent=NULL;
wxXmlResource *This = (wxXmlResource *) getPtr(bp,memenv); bp += 4;
int * nameLen = (int *) bp; bp += 4;
@@ -22892,23 +22934,23 @@ case wxXmlResource_AttachUnknownControl: { // wxXmlResource::AttachUnknownContro
bp += *nameLen+((8-((0+ *nameLen) & 7)) & 7);
wxWindow *control = (wxWindow *) getPtr(bp,memenv); bp += 4;
bp += 4; /* Align */
- while( * (int*) bp) { switch (* (int*) bp) {
+ while( * (int*) bp) { switch (* (int*) bp) {
case 1: {bp += 4;
parent = (wxWindow *) getPtr(bp,memenv); bp += 4;
} break;
- }};
+ }};
if(!This) throw wxe_badarg(0);
bool Result = This->AttachUnknownControl(name,control,parent);
rt.addBool(Result);
- break;
+ break;
}
-case wxXmlResource_ClearHandlers: { // wxXmlResource::ClearHandlers
+case wxXmlResource_ClearHandlers: { // wxXmlResource::ClearHandlers
wxXmlResource *This = (wxXmlResource *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
This->ClearHandlers();
- break;
+ break;
}
-case wxXmlResource_CompareVersion: { // wxXmlResource::CompareVersion
+case wxXmlResource_CompareVersion: { // wxXmlResource::CompareVersion
wxXmlResource *This = (wxXmlResource *) getPtr(bp,memenv); bp += 4;
int * major = (int *) bp; bp += 4;
int * minor = (int *) bp; bp += 4;
@@ -22917,48 +22959,48 @@ case wxXmlResource_CompareVersion: { // wxXmlResource::CompareVersion
if(!This) throw wxe_badarg(0);
int Result = This->CompareVersion((int) *major,(int) *minor,(int) *release,(int) *revision);
rt.addInt(Result);
- break;
+ break;
}
-case wxXmlResource_Get: { // wxXmlResource::Get
+case wxXmlResource_Get: { // wxXmlResource::Get
wxXmlResource * Result = (wxXmlResource*)wxXmlResource::Get();
rt.addRef(getRef((void *)Result,memenv), "wxXmlResource");
- break;
+ break;
}
-case wxXmlResource_GetFlags: { // wxXmlResource::GetFlags
+case wxXmlResource_GetFlags: { // wxXmlResource::GetFlags
wxXmlResource *This = (wxXmlResource *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
int Result = This->GetFlags();
rt.addInt(Result);
- break;
+ break;
}
-case wxXmlResource_GetVersion: { // wxXmlResource::GetVersion
+case wxXmlResource_GetVersion: { // wxXmlResource::GetVersion
wxXmlResource *This = (wxXmlResource *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
long Result = This->GetVersion();
rt.addInt(Result);
- break;
+ break;
}
-case wxXmlResource_GetXRCID: { // wxXmlResource::GetXRCID
+case wxXmlResource_GetXRCID: { // wxXmlResource::GetXRCID
int value_if_not_found=wxID_NONE;
int * str_idLen = (int *) bp; bp += 4;
wxString str_id = wxString(bp, wxConvUTF8);
bp += *str_idLen+((8-((4+ *str_idLen) & 7)) & 7);
- while( * (int*) bp) { switch (* (int*) bp) {
+ while( * (int*) bp) { switch (* (int*) bp) {
case 1: {bp += 4;
value_if_not_found = (int)*(int *) bp; bp += 4;
} break;
- }};
+ }};
int Result = wxXmlResource::GetXRCID(str_id,value_if_not_found);
rt.addInt(Result);
- break;
+ break;
}
-case wxXmlResource_InitAllHandlers: { // wxXmlResource::InitAllHandlers
+case wxXmlResource_InitAllHandlers: { // wxXmlResource::InitAllHandlers
wxXmlResource *This = (wxXmlResource *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
This->InitAllHandlers();
- break;
+ break;
}
-case wxXmlResource_Load: { // wxXmlResource::Load
+case wxXmlResource_Load: { // wxXmlResource::Load
wxXmlResource *This = (wxXmlResource *) getPtr(bp,memenv); bp += 4;
int * filemaskLen = (int *) bp; bp += 4;
wxString filemask = wxString(bp, wxConvUTF8);
@@ -22966,9 +23008,9 @@ case wxXmlResource_Load: { // wxXmlResource::Load
if(!This) throw wxe_badarg(0);
bool Result = This->Load(filemask);
rt.addBool(Result);
- break;
+ break;
}
-case wxXmlResource_LoadBitmap: { // wxXmlResource::LoadBitmap
+case wxXmlResource_LoadBitmap: { // wxXmlResource::LoadBitmap
wxXmlResource *This = (wxXmlResource *) getPtr(bp,memenv); bp += 4;
int * nameLen = (int *) bp; bp += 4;
wxString name = wxString(bp, wxConvUTF8);
@@ -22976,9 +23018,9 @@ case wxXmlResource_LoadBitmap: { // wxXmlResource::LoadBitmap
if(!This) throw wxe_badarg(0);
wxBitmap * Result = new wxBitmap(This->LoadBitmap(name)); newPtr((void *) Result,3, memenv);;
rt.addRef(getRef((void *)Result,memenv), "wxBitmap");
- break;
+ break;
}
-case wxXmlResource_LoadDialog_2: { // wxXmlResource::LoadDialog
+case wxXmlResource_LoadDialog_2: { // wxXmlResource::LoadDialog
wxXmlResource *This = (wxXmlResource *) getPtr(bp,memenv); bp += 4;
wxWindow *parent = (wxWindow *) getPtr(bp,memenv); bp += 4;
int * nameLen = (int *) bp; bp += 4;
@@ -22987,9 +23029,9 @@ case wxXmlResource_LoadDialog_2: { // wxXmlResource::LoadDialog
if(!This) throw wxe_badarg(0);
wxDialog * Result = (wxDialog*)This->LoadDialog(parent,name);
rt.addRef(getRef((void *)Result,memenv), "wxDialog");
- break;
+ break;
}
-case wxXmlResource_LoadDialog_3: { // wxXmlResource::LoadDialog
+case wxXmlResource_LoadDialog_3: { // wxXmlResource::LoadDialog
wxXmlResource *This = (wxXmlResource *) getPtr(bp,memenv); bp += 4;
wxDialog *dlg = (wxDialog *) getPtr(bp,memenv); bp += 4;
wxWindow *parent = (wxWindow *) getPtr(bp,memenv); bp += 4;
@@ -22999,9 +23041,9 @@ case wxXmlResource_LoadDialog_3: { // wxXmlResource::LoadDialog
if(!This) throw wxe_badarg(0);
bool Result = This->LoadDialog(dlg,parent,name);
rt.addBool(Result);
- break;
+ break;
}
-case wxXmlResource_LoadFrame_2: { // wxXmlResource::LoadFrame
+case wxXmlResource_LoadFrame_2: { // wxXmlResource::LoadFrame
wxXmlResource *This = (wxXmlResource *) getPtr(bp,memenv); bp += 4;
wxWindow *parent = (wxWindow *) getPtr(bp,memenv); bp += 4;
int * nameLen = (int *) bp; bp += 4;
@@ -23010,9 +23052,9 @@ case wxXmlResource_LoadFrame_2: { // wxXmlResource::LoadFrame
if(!This) throw wxe_badarg(0);
wxFrame * Result = (wxFrame*)This->LoadFrame(parent,name);
rt.addRef(getRef((void *)Result,memenv), "wxFrame");
- break;
+ break;
}
-case wxXmlResource_LoadFrame_3: { // wxXmlResource::LoadFrame
+case wxXmlResource_LoadFrame_3: { // wxXmlResource::LoadFrame
wxXmlResource *This = (wxXmlResource *) getPtr(bp,memenv); bp += 4;
wxFrame *frame = (wxFrame *) getPtr(bp,memenv); bp += 4;
wxWindow *parent = (wxWindow *) getPtr(bp,memenv); bp += 4;
@@ -23022,9 +23064,9 @@ case wxXmlResource_LoadFrame_3: { // wxXmlResource::LoadFrame
if(!This) throw wxe_badarg(0);
bool Result = This->LoadFrame(frame,parent,name);
rt.addBool(Result);
- break;
+ break;
}
-case wxXmlResource_LoadIcon: { // wxXmlResource::LoadIcon
+case wxXmlResource_LoadIcon: { // wxXmlResource::LoadIcon
wxXmlResource *This = (wxXmlResource *) getPtr(bp,memenv); bp += 4;
int * nameLen = (int *) bp; bp += 4;
wxString name = wxString(bp, wxConvUTF8);
@@ -23032,9 +23074,9 @@ case wxXmlResource_LoadIcon: { // wxXmlResource::LoadIcon
if(!This) throw wxe_badarg(0);
wxIcon * Result = new wxIcon(This->LoadIcon(name)); newPtr((void *) Result,3, memenv);;
rt.addRef(getRef((void *)Result,memenv), "wxIcon");
- break;
+ break;
}
-case wxXmlResource_LoadMenu: { // wxXmlResource::LoadMenu
+case wxXmlResource_LoadMenu: { // wxXmlResource::LoadMenu
wxXmlResource *This = (wxXmlResource *) getPtr(bp,memenv); bp += 4;
int * nameLen = (int *) bp; bp += 4;
wxString name = wxString(bp, wxConvUTF8);
@@ -23042,9 +23084,9 @@ case wxXmlResource_LoadMenu: { // wxXmlResource::LoadMenu
if(!This) throw wxe_badarg(0);
wxMenu * Result = (wxMenu*)This->LoadMenu(name);
rt.addRef(getRef((void *)Result,memenv), "wxMenu");
- break;
+ break;
}
-case wxXmlResource_LoadMenuBar_2: { // wxXmlResource::LoadMenuBar
+case wxXmlResource_LoadMenuBar_2: { // wxXmlResource::LoadMenuBar
wxXmlResource *This = (wxXmlResource *) getPtr(bp,memenv); bp += 4;
wxWindow *parent = (wxWindow *) getPtr(bp,memenv); bp += 4;
int * nameLen = (int *) bp; bp += 4;
@@ -23053,9 +23095,9 @@ case wxXmlResource_LoadMenuBar_2: { // wxXmlResource::LoadMenuBar
if(!This) throw wxe_badarg(0);
wxMenuBar * Result = (wxMenuBar*)This->LoadMenuBar(parent,name);
rt.addRef(getRef((void *)Result,memenv), "wxMenuBar");
- break;
+ break;
}
-case wxXmlResource_LoadMenuBar_1: { // wxXmlResource::LoadMenuBar
+case wxXmlResource_LoadMenuBar_1: { // wxXmlResource::LoadMenuBar
wxXmlResource *This = (wxXmlResource *) getPtr(bp,memenv); bp += 4;
int * nameLen = (int *) bp; bp += 4;
wxString name = wxString(bp, wxConvUTF8);
@@ -23063,9 +23105,9 @@ case wxXmlResource_LoadMenuBar_1: { // wxXmlResource::LoadMenuBar
if(!This) throw wxe_badarg(0);
wxMenuBar * Result = (wxMenuBar*)This->LoadMenuBar(name);
rt.addRef(getRef((void *)Result,memenv), "wxMenuBar");
- break;
+ break;
}
-case wxXmlResource_LoadPanel_2: { // wxXmlResource::LoadPanel
+case wxXmlResource_LoadPanel_2: { // wxXmlResource::LoadPanel
wxXmlResource *This = (wxXmlResource *) getPtr(bp,memenv); bp += 4;
wxWindow *parent = (wxWindow *) getPtr(bp,memenv); bp += 4;
int * nameLen = (int *) bp; bp += 4;
@@ -23074,9 +23116,9 @@ case wxXmlResource_LoadPanel_2: { // wxXmlResource::LoadPanel
if(!This) throw wxe_badarg(0);
wxPanel * Result = (wxPanel*)This->LoadPanel(parent,name);
rt.addRef(getRef((void *)Result,memenv), "wxPanel");
- break;
+ break;
}
-case wxXmlResource_LoadPanel_3: { // wxXmlResource::LoadPanel
+case wxXmlResource_LoadPanel_3: { // wxXmlResource::LoadPanel
wxXmlResource *This = (wxXmlResource *) getPtr(bp,memenv); bp += 4;
wxPanel *panel = (wxPanel *) getPtr(bp,memenv); bp += 4;
wxWindow *parent = (wxWindow *) getPtr(bp,memenv); bp += 4;
@@ -23086,9 +23128,9 @@ case wxXmlResource_LoadPanel_3: { // wxXmlResource::LoadPanel
if(!This) throw wxe_badarg(0);
bool Result = This->LoadPanel(panel,parent,name);
rt.addBool(Result);
- break;
+ break;
}
-case wxXmlResource_LoadToolBar: { // wxXmlResource::LoadToolBar
+case wxXmlResource_LoadToolBar: { // wxXmlResource::LoadToolBar
wxXmlResource *This = (wxXmlResource *) getPtr(bp,memenv); bp += 4;
wxWindow *parent = (wxWindow *) getPtr(bp,memenv); bp += 4;
int * nameLen = (int *) bp; bp += 4;
@@ -23097,22 +23139,22 @@ case wxXmlResource_LoadToolBar: { // wxXmlResource::LoadToolBar
if(!This) throw wxe_badarg(0);
wxToolBar * Result = (wxToolBar*)This->LoadToolBar(parent,name);
rt.addRef(getRef((void *)Result,memenv), "wxToolBar");
- break;
+ break;
}
-case wxXmlResource_Set: { // wxXmlResource::Set
+case wxXmlResource_Set: { // wxXmlResource::Set
wxXmlResource *res = (wxXmlResource *) getPtr(bp,memenv); bp += 4;
wxXmlResource * Result = (wxXmlResource*)wxXmlResource::Set(res);
rt.addRef(getRef((void *)Result,memenv), "wxXmlResource");
- break;
+ break;
}
-case wxXmlResource_SetFlags: { // wxXmlResource::SetFlags
+case wxXmlResource_SetFlags: { // wxXmlResource::SetFlags
wxXmlResource *This = (wxXmlResource *) getPtr(bp,memenv); bp += 4;
int * flags = (int *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
This->SetFlags((int) *flags);
- break;
+ break;
}
-case wxXmlResource_Unload: { // wxXmlResource::Unload
+case wxXmlResource_Unload: { // wxXmlResource::Unload
wxXmlResource *This = (wxXmlResource *) getPtr(bp,memenv); bp += 4;
int * filenameLen = (int *) bp; bp += 4;
wxString filename = wxString(bp, wxConvUTF8);
@@ -23120,14 +23162,14 @@ case wxXmlResource_Unload: { // wxXmlResource::Unload
if(!This) throw wxe_badarg(0);
bool Result = This->Unload(filename);
rt.addBool(Result);
- break;
+ break;
}
// XRCTRL macro implemented in erlang funcid wxXmlResource_xrcctrl
-case wxHtmlEasyPrinting_new: { // wxHtmlEasyPrinting::wxHtmlEasyPrinting
+case wxHtmlEasyPrinting_new: { // wxHtmlEasyPrinting::wxHtmlEasyPrinting
wxString name= wxT("Printing");
wxWindow * parentWindow=NULL;
- while( * (int*) bp) { switch (* (int*) bp) {
+ while( * (int*) bp) { switch (* (int*) bp) {
case 1: {bp += 4;
int * nameLen = (int *) bp; bp += 4;
name = wxString(bp, wxConvUTF8);
@@ -23136,27 +23178,27 @@ case wxHtmlEasyPrinting_new: { // wxHtmlEasyPrinting::wxHtmlEasyPrinting
case 2: {bp += 4;
parentWindow = (wxWindow *) getPtr(bp,memenv); bp += 4;
} break;
- }};
+ }};
wxHtmlEasyPrinting * Result = new EwxHtmlEasyPrinting(name,parentWindow);
newPtr((void *) Result, 1, memenv);
rt.addRef(getRef((void *)Result,memenv), "wxHtmlEasyPrinting");
- break;
+ break;
}
-case wxHtmlEasyPrinting_GetPrintData: { // wxHtmlEasyPrinting::GetPrintData
+case wxHtmlEasyPrinting_GetPrintData: { // wxHtmlEasyPrinting::GetPrintData
wxHtmlEasyPrinting *This = (wxHtmlEasyPrinting *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
wxPrintData * Result = (wxPrintData*)This->GetPrintData();
rt.addRef(getRef((void *)Result,memenv), "wxPrintData");
- break;
+ break;
}
-case wxHtmlEasyPrinting_GetPageSetupData: { // wxHtmlEasyPrinting::GetPageSetupData
+case wxHtmlEasyPrinting_GetPageSetupData: { // wxHtmlEasyPrinting::GetPageSetupData
wxHtmlEasyPrinting *This = (wxHtmlEasyPrinting *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
wxPageSetupDialogData * Result = (wxPageSetupDialogData*)This->GetPageSetupData();
rt.addRef(getRef((void *)Result,memenv), "wxPageSetupDialogData");
- break;
+ break;
}
-case wxHtmlEasyPrinting_PreviewFile: { // wxHtmlEasyPrinting::PreviewFile
+case wxHtmlEasyPrinting_PreviewFile: { // wxHtmlEasyPrinting::PreviewFile
wxHtmlEasyPrinting *This = (wxHtmlEasyPrinting *) getPtr(bp,memenv); bp += 4;
int * htmlfileLen = (int *) bp; bp += 4;
wxString htmlfile = wxString(bp, wxConvUTF8);
@@ -23164,27 +23206,27 @@ case wxHtmlEasyPrinting_PreviewFile: { // wxHtmlEasyPrinting::PreviewFile
if(!This) throw wxe_badarg(0);
bool Result = This->PreviewFile(htmlfile);
rt.addBool(Result);
- break;
+ break;
}
-case wxHtmlEasyPrinting_PreviewText: { // wxHtmlEasyPrinting::PreviewText
+case wxHtmlEasyPrinting_PreviewText: { // wxHtmlEasyPrinting::PreviewText
wxString basepath= wxEmptyString;
wxHtmlEasyPrinting *This = (wxHtmlEasyPrinting *) getPtr(bp,memenv); bp += 4;
int * htmltextLen = (int *) bp; bp += 4;
wxString htmltext = wxString(bp, wxConvUTF8);
bp += *htmltextLen+((8-((0+ *htmltextLen) & 7)) & 7);
- while( * (int*) bp) { switch (* (int*) bp) {
+ while( * (int*) bp) { switch (* (int*) bp) {
case 1: {bp += 4;
int * basepathLen = (int *) bp; bp += 4;
basepath = wxString(bp, wxConvUTF8);
bp += *basepathLen+((8-((0+ *basepathLen) & 7)) & 7);
} break;
- }};
+ }};
if(!This) throw wxe_badarg(0);
bool Result = This->PreviewText(htmltext,basepath);
rt.addBool(Result);
- break;
+ break;
}
-case wxHtmlEasyPrinting_PrintFile: { // wxHtmlEasyPrinting::PrintFile
+case wxHtmlEasyPrinting_PrintFile: { // wxHtmlEasyPrinting::PrintFile
wxHtmlEasyPrinting *This = (wxHtmlEasyPrinting *) getPtr(bp,memenv); bp += 4;
int * htmlfileLen = (int *) bp; bp += 4;
wxString htmlfile = wxString(bp, wxConvUTF8);
@@ -23192,33 +23234,33 @@ case wxHtmlEasyPrinting_PrintFile: { // wxHtmlEasyPrinting::PrintFile
if(!This) throw wxe_badarg(0);
bool Result = This->PrintFile(htmlfile);
rt.addBool(Result);
- break;
+ break;
}
-case wxHtmlEasyPrinting_PrintText: { // wxHtmlEasyPrinting::PrintText
+case wxHtmlEasyPrinting_PrintText: { // wxHtmlEasyPrinting::PrintText
wxString basepath= wxEmptyString;
wxHtmlEasyPrinting *This = (wxHtmlEasyPrinting *) getPtr(bp,memenv); bp += 4;
int * htmltextLen = (int *) bp; bp += 4;
wxString htmltext = wxString(bp, wxConvUTF8);
bp += *htmltextLen+((8-((0+ *htmltextLen) & 7)) & 7);
- while( * (int*) bp) { switch (* (int*) bp) {
+ while( * (int*) bp) { switch (* (int*) bp) {
case 1: {bp += 4;
int * basepathLen = (int *) bp; bp += 4;
basepath = wxString(bp, wxConvUTF8);
bp += *basepathLen+((8-((0+ *basepathLen) & 7)) & 7);
} break;
- }};
+ }};
if(!This) throw wxe_badarg(0);
bool Result = This->PrintText(htmltext,basepath);
rt.addBool(Result);
- break;
+ break;
}
-case wxHtmlEasyPrinting_PageSetup: { // wxHtmlEasyPrinting::PageSetup
+case wxHtmlEasyPrinting_PageSetup: { // wxHtmlEasyPrinting::PageSetup
wxHtmlEasyPrinting *This = (wxHtmlEasyPrinting *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
This->PageSetup();
- break;
+ break;
}
-case wxHtmlEasyPrinting_SetFonts: { // wxHtmlEasyPrinting::SetFonts
+case wxHtmlEasyPrinting_SetFonts: { // wxHtmlEasyPrinting::SetFonts
int * sizesLen = 0;
int * sizes = (int *) NULL;
wxHtmlEasyPrinting *This = (wxHtmlEasyPrinting *) getPtr(bp,memenv); bp += 4;
@@ -23228,47 +23270,47 @@ case wxHtmlEasyPrinting_SetFonts: { // wxHtmlEasyPrinting::SetFonts
int * fixed_faceLen = (int *) bp; bp += 4;
wxString fixed_face = wxString(bp, wxConvUTF8);
bp += *fixed_faceLen+((8-((4+ *fixed_faceLen) & 7)) & 7);
- while( * (int*) bp) { switch (* (int*) bp) {
+ while( * (int*) bp) { switch (* (int*) bp) {
case 1: {bp += 4;
sizesLen = (int *) bp; bp += 4;
sizes = (int *) bp; bp += *sizesLen*4+((0+ *sizesLen)%2 )*4;
} break;
- }};
+ }};
if(!This) throw wxe_badarg(0);
This->SetFonts(normal_face,fixed_face,sizes);
- break;
+ break;
}
-case wxHtmlEasyPrinting_SetHeader: { // wxHtmlEasyPrinting::SetHeader
+case wxHtmlEasyPrinting_SetHeader: { // wxHtmlEasyPrinting::SetHeader
int pg=wxPAGE_ALL;
wxHtmlEasyPrinting *This = (wxHtmlEasyPrinting *) getPtr(bp,memenv); bp += 4;
int * headerLen = (int *) bp; bp += 4;
wxString header = wxString(bp, wxConvUTF8);
bp += *headerLen+((8-((0+ *headerLen) & 7)) & 7);
- while( * (int*) bp) { switch (* (int*) bp) {
+ while( * (int*) bp) { switch (* (int*) bp) {
case 1: {bp += 4;
pg = (int)*(int *) bp; bp += 4;
} break;
- }};
+ }};
if(!This) throw wxe_badarg(0);
This->SetHeader(header,pg);
- break;
+ break;
}
-case wxHtmlEasyPrinting_SetFooter: { // wxHtmlEasyPrinting::SetFooter
+case wxHtmlEasyPrinting_SetFooter: { // wxHtmlEasyPrinting::SetFooter
int pg=wxPAGE_ALL;
wxHtmlEasyPrinting *This = (wxHtmlEasyPrinting *) getPtr(bp,memenv); bp += 4;
int * footerLen = (int *) bp; bp += 4;
wxString footer = wxString(bp, wxConvUTF8);
bp += *footerLen+((8-((0+ *footerLen) & 7)) & 7);
- while( * (int*) bp) { switch (* (int*) bp) {
+ while( * (int*) bp) { switch (* (int*) bp) {
case 1: {bp += 4;
pg = (int)*(int *) bp; bp += 4;
} break;
- }};
+ }};
if(!This) throw wxe_badarg(0);
This->SetFooter(footer,pg);
- break;
+ break;
}
-case wxGLCanvas_new_2: { // wxGLCanvas::wxGLCanvas
+case wxGLCanvas_new_2: { // wxGLCanvas::wxGLCanvas
wxWindowID id=-1;
wxPoint pos= wxDefaultPosition;
wxSize size= wxDefaultSize;
@@ -23279,7 +23321,7 @@ case wxGLCanvas_new_2: { // wxGLCanvas::wxGLCanvas
const wxPalette * palette= &wxNullPalette;
wxWindow *parent = (wxWindow *) getPtr(bp,memenv); bp += 4;
bp += 4; /* Align */
- while( * (int*) bp) { switch (* (int*) bp) {
+ while( * (int*) bp) { switch (* (int*) bp) {
case 1: {bp += 4;
id = (wxWindowID)*(int *) bp; bp += 4;
} break;
@@ -23310,13 +23352,13 @@ case wxGLCanvas_new_2: { // wxGLCanvas::wxGLCanvas
case 7: {bp += 4;
palette = (wxPalette *) getPtr(bp,memenv); bp += 4;
} break;
- }};
+ }};
wxGLCanvas * Result = new EwxGLCanvas(parent,id,pos,size,style,name,attribList,*palette);
newPtr((void *) Result, 0, memenv);
rt.addRef(getRef((void *)Result,memenv), "wxGLCanvas");
- break;
+ break;
}
-case wxGLCanvas_new_3_1: { // wxGLCanvas::wxGLCanvas
+case wxGLCanvas_new_3_1: { // wxGLCanvas::wxGLCanvas
wxWindowID id=-1;
wxPoint pos= wxDefaultPosition;
wxSize size= wxDefaultSize;
@@ -23327,7 +23369,7 @@ case wxGLCanvas_new_3_1: { // wxGLCanvas::wxGLCanvas
const wxPalette * palette= &wxNullPalette;
wxWindow *parent = (wxWindow *) getPtr(bp,memenv); bp += 4;
wxGLContext * shared = (wxGLContext *) getPtr(bp,memenv); bp += 4;
- while( * (int*) bp) { switch (* (int*) bp) {
+ while( * (int*) bp) { switch (* (int*) bp) {
case 1: {bp += 4;
id = (wxWindowID)*(int *) bp; bp += 4;
} break;
@@ -23358,13 +23400,13 @@ case wxGLCanvas_new_3_1: { // wxGLCanvas::wxGLCanvas
case 7: {bp += 4;
palette = (wxPalette *) getPtr(bp,memenv); bp += 4;
} break;
- }};
+ }};
wxGLCanvas * Result = new EwxGLCanvas(parent,shared,id,pos,size,style,name,attribList,*palette);
newPtr((void *) Result, 0, memenv);
rt.addRef(getRef((void *)Result,memenv), "wxGLCanvas");
- break;
+ break;
}
-case wxGLCanvas_new_3_0: { // wxGLCanvas::wxGLCanvas
+case wxGLCanvas_new_3_0: { // wxGLCanvas::wxGLCanvas
wxWindowID id=-1;
wxPoint pos= wxDefaultPosition;
wxSize size= wxDefaultSize;
@@ -23375,7 +23417,7 @@ case wxGLCanvas_new_3_0: { // wxGLCanvas::wxGLCanvas
const wxPalette * palette= &wxNullPalette;
wxWindow *parent = (wxWindow *) getPtr(bp,memenv); bp += 4;
wxGLCanvas *shared = (wxGLCanvas *) getPtr(bp,memenv); bp += 4;
- while( * (int*) bp) { switch (* (int*) bp) {
+ while( * (int*) bp) { switch (* (int*) bp) {
case 1: {bp += 4;
id = (wxWindowID)*(int *) bp; bp += 4;
} break;
@@ -23406,59 +23448,59 @@ case wxGLCanvas_new_3_0: { // wxGLCanvas::wxGLCanvas
case 7: {bp += 4;
palette = (wxPalette *) getPtr(bp,memenv); bp += 4;
} break;
- }};
+ }};
wxGLCanvas * Result = new EwxGLCanvas(parent,shared,id,pos,size,style,name,attribList,*palette);
newPtr((void *) Result, 0, memenv);
rt.addRef(getRef((void *)Result,memenv), "wxGLCanvas");
- break;
+ break;
}
-case wxGLCanvas_GetContext: { // wxGLCanvas::GetContext
+case wxGLCanvas_GetContext: { // wxGLCanvas::GetContext
wxGLCanvas *This = (wxGLCanvas *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
wxGLContext * Result = (wxGLContext*)This->GetContext();
rt.addRef(getRef((void *)Result,memenv), "wxGLContext");
- break;
+ break;
}
-case wxGLCanvas_SetCurrent: { // wxGLCanvas::SetCurrent
+case wxGLCanvas_SetCurrent: { // wxGLCanvas::SetCurrent
wxGLCanvas *This = (wxGLCanvas *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
This->SetCurrent();
if(This->GetContext()) setActiveGL(Ecmd.caller,This);
- break;
+ break;
}
-case wxGLCanvas_SwapBuffers: { // wxGLCanvas::SwapBuffers
+case wxGLCanvas_SwapBuffers: { // wxGLCanvas::SwapBuffers
wxGLCanvas *This = (wxGLCanvas *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
This->SwapBuffers();
- break;
+ break;
}
#if wxUSE_AUI
-case wxAuiManager_new: { // wxAuiManager::wxAuiManager
+case wxAuiManager_new: { // wxAuiManager::wxAuiManager
wxWindow * managed_wnd=NULL;
int flags=wxAUI_MGR_DEFAULT;
- while( * (int*) bp) { switch (* (int*) bp) {
+ while( * (int*) bp) { switch (* (int*) bp) {
case 1: {bp += 4;
managed_wnd = (wxWindow *) getPtr(bp,memenv); bp += 4;
} break;
case 2: {bp += 4;
flags = (int)*(unsigned int *) bp; bp += 4;
} break;
- }};
+ }};
wxAuiManager * Result = new EwxAuiManager(managed_wnd,flags);
newPtr((void *) Result, 1, memenv);
rt.addRef(getRef((void *)Result,memenv), "wxAuiManager");
- break;
+ break;
}
-case wxAuiManager_AddPane_2_1: { // wxAuiManager::AddPane
+case wxAuiManager_AddPane_2_1: { // wxAuiManager::AddPane
wxAuiManager *This = (wxAuiManager *) getPtr(bp,memenv); bp += 4;
wxWindow *window = (wxWindow *) getPtr(bp,memenv); bp += 4;
wxAuiPaneInfo *pane_info = (wxAuiPaneInfo *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
bool Result = This->AddPane(window,*pane_info);
rt.addBool(Result);
- break;
+ break;
}
-case wxAuiManager_AddPane_3: { // wxAuiManager::AddPane
+case wxAuiManager_AddPane_3: { // wxAuiManager::AddPane
wxAuiManager *This = (wxAuiManager *) getPtr(bp,memenv); bp += 4;
wxWindow *window = (wxWindow *) getPtr(bp,memenv); bp += 4;
wxAuiPaneInfo *pane_info = (wxAuiPaneInfo *) getPtr(bp,memenv); bp += 4;
@@ -23468,14 +23510,14 @@ case wxAuiManager_AddPane_3: { // wxAuiManager::AddPane
if(!This) throw wxe_badarg(0);
bool Result = This->AddPane(window,*pane_info,drop_pos);
rt.addBool(Result);
- break;
+ break;
}
-case wxAuiManager_AddPane_2_0: { // wxAuiManager::AddPane
+case wxAuiManager_AddPane_2_0: { // wxAuiManager::AddPane
int direction=wxLEFT;
wxString caption= wxEmptyString;
wxAuiManager *This = (wxAuiManager *) getPtr(bp,memenv); bp += 4;
wxWindow *window = (wxWindow *) getPtr(bp,memenv); bp += 4;
- while( * (int*) bp) { switch (* (int*) bp) {
+ while( * (int*) bp) { switch (* (int*) bp) {
case 1: {bp += 4;
direction = (int)*(int *) bp; bp += 4;
} break;
@@ -23484,35 +23526,35 @@ case wxAuiManager_AddPane_2_0: { // wxAuiManager::AddPane
caption = wxString(bp, wxConvUTF8);
bp += *captionLen+((8-((0+ *captionLen) & 7)) & 7);
} break;
- }};
+ }};
if(!This) throw wxe_badarg(0);
bool Result = This->AddPane(window,direction,caption);
rt.addBool(Result);
- break;
+ break;
}
-case wxAuiManager_DetachPane: { // wxAuiManager::DetachPane
+case wxAuiManager_DetachPane: { // wxAuiManager::DetachPane
wxAuiManager *This = (wxAuiManager *) getPtr(bp,memenv); bp += 4;
wxWindow *window = (wxWindow *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
bool Result = This->DetachPane(window);
rt.addBool(Result);
- break;
+ break;
}
-case wxAuiManager_GetAllPanes: { // wxAuiManager::GetAllPanes
+case wxAuiManager_GetAllPanes: { // wxAuiManager::GetAllPanes
wxAuiManager *This = (wxAuiManager *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
wxAuiPaneInfoArray * Result = &This->GetAllPanes();
rt.addRef(getRef((void *)Result,memenv), "wxAuiPaneInfoArray");
- break;
+ break;
}
-case wxAuiManager_GetArtProvider: { // wxAuiManager::GetArtProvider
+case wxAuiManager_GetArtProvider: { // wxAuiManager::GetArtProvider
wxAuiManager *This = (wxAuiManager *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
wxAuiDockArt * Result = (wxAuiDockArt*)This->GetArtProvider();
rt.addRef(getRef((void *)Result,memenv), "wxAuiDockArt");
- break;
+ break;
}
-case wxAuiManager_GetDockSizeConstraint: { // wxAuiManager::GetDockSizeConstraint
+case wxAuiManager_GetDockSizeConstraint: { // wxAuiManager::GetDockSizeConstraint
double width_pct;
double height_pct;
wxAuiManager *This = (wxAuiManager *) getPtr(bp,memenv); bp += 4;
@@ -23521,37 +23563,37 @@ case wxAuiManager_GetDockSizeConstraint: { // wxAuiManager::GetDockSizeConstrain
rt.addFloat(width_pct);
rt.addFloat(height_pct);
rt.addTupleCount(2);
- break;
+ break;
}
-case wxAuiManager_GetFlags: { // wxAuiManager::GetFlags
+case wxAuiManager_GetFlags: { // wxAuiManager::GetFlags
wxAuiManager *This = (wxAuiManager *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
int Result = This->GetFlags();
rt.addUint(Result);
- break;
+ break;
}
-case wxAuiManager_GetManagedWindow: { // wxAuiManager::GetManagedWindow
+case wxAuiManager_GetManagedWindow: { // wxAuiManager::GetManagedWindow
wxAuiManager *This = (wxAuiManager *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
wxWindow * Result = (wxWindow*)This->GetManagedWindow();
rt.addRef(getRef((void *)Result,memenv), "wxWindow");
- break;
+ break;
}
-case wxAuiManager_GetManager: { // wxAuiManager::GetManager
+case wxAuiManager_GetManager: { // wxAuiManager::GetManager
wxWindow *window = (wxWindow *) getPtr(bp,memenv); bp += 4;
wxAuiManager * Result = (wxAuiManager*)wxAuiManager::GetManager(window);
rt.addRef(getRef((void *)Result,memenv), "wxAuiManager");
- break;
+ break;
}
-case wxAuiManager_GetPane_1_1: { // wxAuiManager::GetPane
+case wxAuiManager_GetPane_1_1: { // wxAuiManager::GetPane
wxAuiManager *This = (wxAuiManager *) getPtr(bp,memenv); bp += 4;
wxWindow *window = (wxWindow *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
wxAuiPaneInfo * Result = &This->GetPane(window);
rt.addRef(getRef((void *)Result,memenv), "wxAuiPaneInfo");
- break;
+ break;
}
-case wxAuiManager_GetPane_1_0: { // wxAuiManager::GetPane
+case wxAuiManager_GetPane_1_0: { // wxAuiManager::GetPane
wxAuiManager *This = (wxAuiManager *) getPtr(bp,memenv); bp += 4;
int * nameLen = (int *) bp; bp += 4;
wxString name = wxString(bp, wxConvUTF8);
@@ -23559,31 +23601,31 @@ case wxAuiManager_GetPane_1_0: { // wxAuiManager::GetPane
if(!This) throw wxe_badarg(0);
wxAuiPaneInfo * Result = &This->GetPane(name);
rt.addRef(getRef((void *)Result,memenv), "wxAuiPaneInfo");
- break;
+ break;
}
-case wxAuiManager_HideHint: { // wxAuiManager::HideHint
+case wxAuiManager_HideHint: { // wxAuiManager::HideHint
wxAuiManager *This = (wxAuiManager *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
This->HideHint();
- break;
+ break;
}
-case wxAuiManager_InsertPane: { // wxAuiManager::InsertPane
+case wxAuiManager_InsertPane: { // wxAuiManager::InsertPane
int insert_level=wxAUI_INSERT_PANE;
wxAuiManager *This = (wxAuiManager *) getPtr(bp,memenv); bp += 4;
wxWindow *window = (wxWindow *) getPtr(bp,memenv); bp += 4;
wxAuiPaneInfo *insert_location = (wxAuiPaneInfo *) getPtr(bp,memenv); bp += 4;
bp += 4; /* Align */
- while( * (int*) bp) { switch (* (int*) bp) {
+ while( * (int*) bp) { switch (* (int*) bp) {
case 1: {bp += 4;
insert_level = (int)*(int *) bp; bp += 4;
} break;
- }};
+ }};
if(!This) throw wxe_badarg(0);
bool Result = This->InsertPane(window,*insert_location,insert_level);
rt.addBool(Result);
- break;
+ break;
}
-case wxAuiManager_LoadPaneInfo: { // wxAuiManager::LoadPaneInfo
+case wxAuiManager_LoadPaneInfo: { // wxAuiManager::LoadPaneInfo
wxAuiManager *This = (wxAuiManager *) getPtr(bp,memenv); bp += 4;
int * pane_partLen = (int *) bp; bp += 4;
wxString pane_part = wxString(bp, wxConvUTF8);
@@ -23591,70 +23633,70 @@ case wxAuiManager_LoadPaneInfo: { // wxAuiManager::LoadPaneInfo
wxAuiPaneInfo *pane = (wxAuiPaneInfo *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
This->LoadPaneInfo(pane_part,*pane);
- break;
+ break;
}
-case wxAuiManager_LoadPerspective: { // wxAuiManager::LoadPerspective
+case wxAuiManager_LoadPerspective: { // wxAuiManager::LoadPerspective
bool update=true;
wxAuiManager *This = (wxAuiManager *) getPtr(bp,memenv); bp += 4;
int * perspectiveLen = (int *) bp; bp += 4;
wxString perspective = wxString(bp, wxConvUTF8);
bp += *perspectiveLen+((8-((0+ *perspectiveLen) & 7)) & 7);
- while( * (int*) bp) { switch (* (int*) bp) {
+ while( * (int*) bp) { switch (* (int*) bp) {
case 1: {bp += 4;
update = *(bool *) bp; bp += 4;
} break;
- }};
+ }};
if(!This) throw wxe_badarg(0);
bool Result = This->LoadPerspective(perspective,update);
rt.addBool(Result);
- break;
+ break;
}
-case wxAuiManager_SavePaneInfo: { // wxAuiManager::SavePaneInfo
+case wxAuiManager_SavePaneInfo: { // wxAuiManager::SavePaneInfo
wxAuiManager *This = (wxAuiManager *) getPtr(bp,memenv); bp += 4;
wxAuiPaneInfo *pane = (wxAuiPaneInfo *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
wxString Result = This->SavePaneInfo(*pane);
rt.add(Result);
- break;
+ break;
}
-case wxAuiManager_SavePerspective: { // wxAuiManager::SavePerspective
+case wxAuiManager_SavePerspective: { // wxAuiManager::SavePerspective
wxAuiManager *This = (wxAuiManager *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
wxString Result = This->SavePerspective();
rt.add(Result);
- break;
+ break;
}
-case wxAuiManager_SetArtProvider: { // wxAuiManager::SetArtProvider
+case wxAuiManager_SetArtProvider: { // wxAuiManager::SetArtProvider
wxAuiManager *This = (wxAuiManager *) getPtr(bp,memenv); bp += 4;
wxAuiDockArt *art_provider = (wxAuiDockArt *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
This->SetArtProvider(art_provider);
- break;
+ break;
}
-case wxAuiManager_SetDockSizeConstraint: { // wxAuiManager::SetDockSizeConstraint
+case wxAuiManager_SetDockSizeConstraint: { // wxAuiManager::SetDockSizeConstraint
wxAuiManager *This = (wxAuiManager *) getPtr(bp,memenv); bp += 4;
bp += 4; /* Align */
double * width_pct = (double *) bp; bp += 8;
double * height_pct = (double *) bp; bp += 8;
if(!This) throw wxe_badarg(0);
This->SetDockSizeConstraint((double) *width_pct,(double) *height_pct);
- break;
+ break;
}
-case wxAuiManager_SetFlags: { // wxAuiManager::SetFlags
+case wxAuiManager_SetFlags: { // wxAuiManager::SetFlags
wxAuiManager *This = (wxAuiManager *) getPtr(bp,memenv); bp += 4;
unsigned int * flags = (unsigned int *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
This->SetFlags((int) *flags);
- break;
+ break;
}
-case wxAuiManager_SetManagedWindow: { // wxAuiManager::SetManagedWindow
+case wxAuiManager_SetManagedWindow: { // wxAuiManager::SetManagedWindow
wxAuiManager *This = (wxAuiManager *) getPtr(bp,memenv); bp += 4;
wxWindow *managed_wnd = (wxWindow *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
This->SetManagedWindow(managed_wnd);
- break;
+ break;
}
-case wxAuiManager_ShowHint: { // wxAuiManager::ShowHint
+case wxAuiManager_ShowHint: { // wxAuiManager::ShowHint
wxAuiManager *This = (wxAuiManager *) getPtr(bp,memenv); bp += 4;
int * rectX = (int *) bp; bp += 4;
int * rectY = (int *) bp; bp += 4;
@@ -23663,42 +23705,42 @@ case wxAuiManager_ShowHint: { // wxAuiManager::ShowHint
wxRect rect = wxRect(*rectX,*rectY,*rectW,*rectH);
if(!This) throw wxe_badarg(0);
This->ShowHint(rect);
- break;
+ break;
}
-case wxAuiManager_UnInit: { // wxAuiManager::UnInit
+case wxAuiManager_UnInit: { // wxAuiManager::UnInit
wxAuiManager *This = (wxAuiManager *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
This->UnInit();
- break;
+ break;
}
-case wxAuiManager_Update: { // wxAuiManager::Update
+case wxAuiManager_Update: { // wxAuiManager::Update
wxAuiManager *This = (wxAuiManager *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
This->Update();
- break;
+ break;
}
#endif // wxUSE_AUI
#if wxUSE_AUI
-case wxAuiPaneInfo_new_0: { // wxAuiPaneInfo::wxAuiPaneInfo
+case wxAuiPaneInfo_new_0: { // wxAuiPaneInfo::wxAuiPaneInfo
wxAuiPaneInfo * Result = new wxAuiPaneInfo();
newPtr((void *) Result, 154, memenv);
rt.addRef(getRef((void *)Result,memenv), "wxAuiPaneInfo");
- break;
+ break;
}
-case wxAuiPaneInfo_new_1: { // wxAuiPaneInfo::wxAuiPaneInfo
+case wxAuiPaneInfo_new_1: { // wxAuiPaneInfo::wxAuiPaneInfo
wxAuiPaneInfo *c = (wxAuiPaneInfo *) getPtr(bp,memenv); bp += 4;
wxAuiPaneInfo * Result = new wxAuiPaneInfo(*c);
newPtr((void *) Result, 154, memenv);
rt.addRef(getRef((void *)Result,memenv), "wxAuiPaneInfo");
- break;
+ break;
}
-case wxAuiPaneInfo_destruct: { // wxAuiPaneInfo::~wxAuiPaneInfo
+case wxAuiPaneInfo_destruct: { // wxAuiPaneInfo::~wxAuiPaneInfo
wxAuiPaneInfo *This = (wxAuiPaneInfo *) getPtr(bp,memenv); bp += 4;
if(This) { ((WxeApp *) wxTheApp)->clearPtr((void *) This);
delete This;}
- break;
+ break;
}
-case wxAuiPaneInfo_BestSize_1: { // wxAuiPaneInfo::BestSize
+case wxAuiPaneInfo_BestSize_1: { // wxAuiPaneInfo::BestSize
wxAuiPaneInfo *This = (wxAuiPaneInfo *) getPtr(bp,memenv); bp += 4;
int * sizeW = (int *) bp; bp += 4;
int * sizeH = (int *) bp; bp += 4;
@@ -23706,39 +23748,39 @@ case wxAuiPaneInfo_BestSize_1: { // wxAuiPaneInfo::BestSize
if(!This) throw wxe_badarg(0);
wxAuiPaneInfo * Result = &This->BestSize(size);
rt.addRef(getRef((void *)Result,memenv), "wxAuiPaneInfo");
- break;
+ break;
}
-case wxAuiPaneInfo_BestSize_2: { // wxAuiPaneInfo::BestSize
+case wxAuiPaneInfo_BestSize_2: { // wxAuiPaneInfo::BestSize
wxAuiPaneInfo *This = (wxAuiPaneInfo *) getPtr(bp,memenv); bp += 4;
int * x = (int *) bp; bp += 4;
int * y = (int *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
wxAuiPaneInfo * Result = &This->BestSize((int) *x,(int) *y);
rt.addRef(getRef((void *)Result,memenv), "wxAuiPaneInfo");
- break;
+ break;
}
-case wxAuiPaneInfo_Bottom: { // wxAuiPaneInfo::Bottom
+case wxAuiPaneInfo_Bottom: { // wxAuiPaneInfo::Bottom
wxAuiPaneInfo *This = (wxAuiPaneInfo *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
wxAuiPaneInfo * Result = &This->Bottom();
rt.addRef(getRef((void *)Result,memenv), "wxAuiPaneInfo");
- break;
+ break;
}
-case wxAuiPaneInfo_BottomDockable: { // wxAuiPaneInfo::BottomDockable
+case wxAuiPaneInfo_BottomDockable: { // wxAuiPaneInfo::BottomDockable
bool b=true;
wxAuiPaneInfo *This = (wxAuiPaneInfo *) getPtr(bp,memenv); bp += 4;
bp += 4; /* Align */
- while( * (int*) bp) { switch (* (int*) bp) {
+ while( * (int*) bp) { switch (* (int*) bp) {
case 1: {bp += 4;
b = *(bool *) bp; bp += 4;
} break;
- }};
+ }};
if(!This) throw wxe_badarg(0);
wxAuiPaneInfo * Result = &This->BottomDockable(b);
rt.addRef(getRef((void *)Result,memenv), "wxAuiPaneInfo");
- break;
+ break;
}
-case wxAuiPaneInfo_Caption: { // wxAuiPaneInfo::Caption
+case wxAuiPaneInfo_Caption: { // wxAuiPaneInfo::Caption
wxAuiPaneInfo *This = (wxAuiPaneInfo *) getPtr(bp,memenv); bp += 4;
int * cLen = (int *) bp; bp += 4;
wxString c = wxString(bp, wxConvUTF8);
@@ -23746,129 +23788,129 @@ case wxAuiPaneInfo_Caption: { // wxAuiPaneInfo::Caption
if(!This) throw wxe_badarg(0);
wxAuiPaneInfo * Result = &This->Caption(c);
rt.addRef(getRef((void *)Result,memenv), "wxAuiPaneInfo");
- break;
+ break;
}
-case wxAuiPaneInfo_CaptionVisible: { // wxAuiPaneInfo::CaptionVisible
+case wxAuiPaneInfo_CaptionVisible: { // wxAuiPaneInfo::CaptionVisible
bool visible=true;
wxAuiPaneInfo *This = (wxAuiPaneInfo *) getPtr(bp,memenv); bp += 4;
bp += 4; /* Align */
- while( * (int*) bp) { switch (* (int*) bp) {
+ while( * (int*) bp) { switch (* (int*) bp) {
case 1: {bp += 4;
visible = *(bool *) bp; bp += 4;
} break;
- }};
+ }};
if(!This) throw wxe_badarg(0);
wxAuiPaneInfo * Result = &This->CaptionVisible(visible);
rt.addRef(getRef((void *)Result,memenv), "wxAuiPaneInfo");
- break;
+ break;
}
-case wxAuiPaneInfo_Centre: { // wxAuiPaneInfo::Centre
+case wxAuiPaneInfo_Centre: { // wxAuiPaneInfo::Centre
wxAuiPaneInfo *This = (wxAuiPaneInfo *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
wxAuiPaneInfo * Result = &This->Centre();
rt.addRef(getRef((void *)Result,memenv), "wxAuiPaneInfo");
- break;
+ break;
}
-case wxAuiPaneInfo_CentrePane: { // wxAuiPaneInfo::CentrePane
+case wxAuiPaneInfo_CentrePane: { // wxAuiPaneInfo::CentrePane
wxAuiPaneInfo *This = (wxAuiPaneInfo *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
wxAuiPaneInfo * Result = &This->CentrePane();
rt.addRef(getRef((void *)Result,memenv), "wxAuiPaneInfo");
- break;
+ break;
}
-case wxAuiPaneInfo_CloseButton: { // wxAuiPaneInfo::CloseButton
+case wxAuiPaneInfo_CloseButton: { // wxAuiPaneInfo::CloseButton
bool visible=true;
wxAuiPaneInfo *This = (wxAuiPaneInfo *) getPtr(bp,memenv); bp += 4;
bp += 4; /* Align */
- while( * (int*) bp) { switch (* (int*) bp) {
+ while( * (int*) bp) { switch (* (int*) bp) {
case 1: {bp += 4;
visible = *(bool *) bp; bp += 4;
} break;
- }};
+ }};
if(!This) throw wxe_badarg(0);
wxAuiPaneInfo * Result = &This->CloseButton(visible);
rt.addRef(getRef((void *)Result,memenv), "wxAuiPaneInfo");
- break;
+ break;
}
-case wxAuiPaneInfo_DefaultPane: { // wxAuiPaneInfo::DefaultPane
+case wxAuiPaneInfo_DefaultPane: { // wxAuiPaneInfo::DefaultPane
wxAuiPaneInfo *This = (wxAuiPaneInfo *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
wxAuiPaneInfo * Result = &This->DefaultPane();
rt.addRef(getRef((void *)Result,memenv), "wxAuiPaneInfo");
- break;
+ break;
}
-case wxAuiPaneInfo_DestroyOnClose: { // wxAuiPaneInfo::DestroyOnClose
+case wxAuiPaneInfo_DestroyOnClose: { // wxAuiPaneInfo::DestroyOnClose
bool b=true;
wxAuiPaneInfo *This = (wxAuiPaneInfo *) getPtr(bp,memenv); bp += 4;
bp += 4; /* Align */
- while( * (int*) bp) { switch (* (int*) bp) {
+ while( * (int*) bp) { switch (* (int*) bp) {
case 1: {bp += 4;
b = *(bool *) bp; bp += 4;
} break;
- }};
+ }};
if(!This) throw wxe_badarg(0);
wxAuiPaneInfo * Result = &This->DestroyOnClose(b);
rt.addRef(getRef((void *)Result,memenv), "wxAuiPaneInfo");
- break;
+ break;
}
-case wxAuiPaneInfo_Direction: { // wxAuiPaneInfo::Direction
+case wxAuiPaneInfo_Direction: { // wxAuiPaneInfo::Direction
wxAuiPaneInfo *This = (wxAuiPaneInfo *) getPtr(bp,memenv); bp += 4;
int * direction = (int *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
wxAuiPaneInfo * Result = &This->Direction((int) *direction);
rt.addRef(getRef((void *)Result,memenv), "wxAuiPaneInfo");
- break;
+ break;
}
-case wxAuiPaneInfo_Dock: { // wxAuiPaneInfo::Dock
+case wxAuiPaneInfo_Dock: { // wxAuiPaneInfo::Dock
wxAuiPaneInfo *This = (wxAuiPaneInfo *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
wxAuiPaneInfo * Result = &This->Dock();
rt.addRef(getRef((void *)Result,memenv), "wxAuiPaneInfo");
- break;
+ break;
}
-case wxAuiPaneInfo_Dockable: { // wxAuiPaneInfo::Dockable
+case wxAuiPaneInfo_Dockable: { // wxAuiPaneInfo::Dockable
bool b=true;
wxAuiPaneInfo *This = (wxAuiPaneInfo *) getPtr(bp,memenv); bp += 4;
bp += 4; /* Align */
- while( * (int*) bp) { switch (* (int*) bp) {
+ while( * (int*) bp) { switch (* (int*) bp) {
case 1: {bp += 4;
b = *(bool *) bp; bp += 4;
} break;
- }};
+ }};
if(!This) throw wxe_badarg(0);
wxAuiPaneInfo * Result = &This->Dockable(b);
rt.addRef(getRef((void *)Result,memenv), "wxAuiPaneInfo");
- break;
+ break;
}
-case wxAuiPaneInfo_Fixed: { // wxAuiPaneInfo::Fixed
+case wxAuiPaneInfo_Fixed: { // wxAuiPaneInfo::Fixed
wxAuiPaneInfo *This = (wxAuiPaneInfo *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
wxAuiPaneInfo * Result = &This->Fixed();
rt.addRef(getRef((void *)Result,memenv), "wxAuiPaneInfo");
- break;
+ break;
}
-case wxAuiPaneInfo_Float: { // wxAuiPaneInfo::Float
+case wxAuiPaneInfo_Float: { // wxAuiPaneInfo::Float
wxAuiPaneInfo *This = (wxAuiPaneInfo *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
wxAuiPaneInfo * Result = &This->Float();
rt.addRef(getRef((void *)Result,memenv), "wxAuiPaneInfo");
- break;
+ break;
}
-case wxAuiPaneInfo_Floatable: { // wxAuiPaneInfo::Floatable
+case wxAuiPaneInfo_Floatable: { // wxAuiPaneInfo::Floatable
bool b=true;
wxAuiPaneInfo *This = (wxAuiPaneInfo *) getPtr(bp,memenv); bp += 4;
bp += 4; /* Align */
- while( * (int*) bp) { switch (* (int*) bp) {
+ while( * (int*) bp) { switch (* (int*) bp) {
case 1: {bp += 4;
b = *(bool *) bp; bp += 4;
} break;
- }};
+ }};
if(!This) throw wxe_badarg(0);
wxAuiPaneInfo * Result = &This->Floatable(b);
rt.addRef(getRef((void *)Result,memenv), "wxAuiPaneInfo");
- break;
+ break;
}
-case wxAuiPaneInfo_FloatingPosition_1: { // wxAuiPaneInfo::FloatingPosition
+case wxAuiPaneInfo_FloatingPosition_1: { // wxAuiPaneInfo::FloatingPosition
wxAuiPaneInfo *This = (wxAuiPaneInfo *) getPtr(bp,memenv); bp += 4;
int * posX = (int *) bp; bp += 4;
int * posY = (int *) bp; bp += 4;
@@ -23876,18 +23918,18 @@ case wxAuiPaneInfo_FloatingPosition_1: { // wxAuiPaneInfo::FloatingPosition
if(!This) throw wxe_badarg(0);
wxAuiPaneInfo * Result = &This->FloatingPosition(pos);
rt.addRef(getRef((void *)Result,memenv), "wxAuiPaneInfo");
- break;
+ break;
}
-case wxAuiPaneInfo_FloatingPosition_2: { // wxAuiPaneInfo::FloatingPosition
+case wxAuiPaneInfo_FloatingPosition_2: { // wxAuiPaneInfo::FloatingPosition
wxAuiPaneInfo *This = (wxAuiPaneInfo *) getPtr(bp,memenv); bp += 4;
int * x = (int *) bp; bp += 4;
int * y = (int *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
wxAuiPaneInfo * Result = &This->FloatingPosition((int) *x,(int) *y);
rt.addRef(getRef((void *)Result,memenv), "wxAuiPaneInfo");
- break;
+ break;
}
-case wxAuiPaneInfo_FloatingSize_1: { // wxAuiPaneInfo::FloatingSize
+case wxAuiPaneInfo_FloatingSize_1: { // wxAuiPaneInfo::FloatingSize
wxAuiPaneInfo *This = (wxAuiPaneInfo *) getPtr(bp,memenv); bp += 4;
int * sizeW = (int *) bp; bp += 4;
int * sizeH = (int *) bp; bp += 4;
@@ -23895,237 +23937,237 @@ case wxAuiPaneInfo_FloatingSize_1: { // wxAuiPaneInfo::FloatingSize
if(!This) throw wxe_badarg(0);
wxAuiPaneInfo * Result = &This->FloatingSize(size);
rt.addRef(getRef((void *)Result,memenv), "wxAuiPaneInfo");
- break;
+ break;
}
-case wxAuiPaneInfo_FloatingSize_2: { // wxAuiPaneInfo::FloatingSize
+case wxAuiPaneInfo_FloatingSize_2: { // wxAuiPaneInfo::FloatingSize
wxAuiPaneInfo *This = (wxAuiPaneInfo *) getPtr(bp,memenv); bp += 4;
int * x = (int *) bp; bp += 4;
int * y = (int *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
wxAuiPaneInfo * Result = &This->FloatingSize((int) *x,(int) *y);
rt.addRef(getRef((void *)Result,memenv), "wxAuiPaneInfo");
- break;
+ break;
}
-case wxAuiPaneInfo_Gripper: { // wxAuiPaneInfo::Gripper
+case wxAuiPaneInfo_Gripper: { // wxAuiPaneInfo::Gripper
bool visible=true;
wxAuiPaneInfo *This = (wxAuiPaneInfo *) getPtr(bp,memenv); bp += 4;
bp += 4; /* Align */
- while( * (int*) bp) { switch (* (int*) bp) {
+ while( * (int*) bp) { switch (* (int*) bp) {
case 1: {bp += 4;
visible = *(bool *) bp; bp += 4;
} break;
- }};
+ }};
if(!This) throw wxe_badarg(0);
wxAuiPaneInfo * Result = &This->Gripper(visible);
rt.addRef(getRef((void *)Result,memenv), "wxAuiPaneInfo");
- break;
+ break;
}
-case wxAuiPaneInfo_GripperTop: { // wxAuiPaneInfo::GripperTop
+case wxAuiPaneInfo_GripperTop: { // wxAuiPaneInfo::GripperTop
bool attop=true;
wxAuiPaneInfo *This = (wxAuiPaneInfo *) getPtr(bp,memenv); bp += 4;
bp += 4; /* Align */
- while( * (int*) bp) { switch (* (int*) bp) {
+ while( * (int*) bp) { switch (* (int*) bp) {
case 1: {bp += 4;
attop = *(bool *) bp; bp += 4;
} break;
- }};
+ }};
if(!This) throw wxe_badarg(0);
wxAuiPaneInfo * Result = &This->GripperTop(attop);
rt.addRef(getRef((void *)Result,memenv), "wxAuiPaneInfo");
- break;
+ break;
}
-case wxAuiPaneInfo_HasBorder: { // wxAuiPaneInfo::HasBorder
+case wxAuiPaneInfo_HasBorder: { // wxAuiPaneInfo::HasBorder
wxAuiPaneInfo *This = (wxAuiPaneInfo *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
bool Result = This->HasBorder();
rt.addBool(Result);
- break;
+ break;
}
-case wxAuiPaneInfo_HasCaption: { // wxAuiPaneInfo::HasCaption
+case wxAuiPaneInfo_HasCaption: { // wxAuiPaneInfo::HasCaption
wxAuiPaneInfo *This = (wxAuiPaneInfo *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
bool Result = This->HasCaption();
rt.addBool(Result);
- break;
+ break;
}
-case wxAuiPaneInfo_HasCloseButton: { // wxAuiPaneInfo::HasCloseButton
+case wxAuiPaneInfo_HasCloseButton: { // wxAuiPaneInfo::HasCloseButton
wxAuiPaneInfo *This = (wxAuiPaneInfo *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
bool Result = This->HasCloseButton();
rt.addBool(Result);
- break;
+ break;
}
-case wxAuiPaneInfo_HasFlag: { // wxAuiPaneInfo::HasFlag
+case wxAuiPaneInfo_HasFlag: { // wxAuiPaneInfo::HasFlag
wxAuiPaneInfo *This = (wxAuiPaneInfo *) getPtr(bp,memenv); bp += 4;
unsigned int * flag = (unsigned int *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
bool Result = This->HasFlag((int) *flag);
rt.addBool(Result);
- break;
+ break;
}
-case wxAuiPaneInfo_HasGripper: { // wxAuiPaneInfo::HasGripper
+case wxAuiPaneInfo_HasGripper: { // wxAuiPaneInfo::HasGripper
wxAuiPaneInfo *This = (wxAuiPaneInfo *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
bool Result = This->HasGripper();
rt.addBool(Result);
- break;
+ break;
}
-case wxAuiPaneInfo_HasGripperTop: { // wxAuiPaneInfo::HasGripperTop
+case wxAuiPaneInfo_HasGripperTop: { // wxAuiPaneInfo::HasGripperTop
wxAuiPaneInfo *This = (wxAuiPaneInfo *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
bool Result = This->HasGripperTop();
rt.addBool(Result);
- break;
+ break;
}
-case wxAuiPaneInfo_HasMaximizeButton: { // wxAuiPaneInfo::HasMaximizeButton
+case wxAuiPaneInfo_HasMaximizeButton: { // wxAuiPaneInfo::HasMaximizeButton
wxAuiPaneInfo *This = (wxAuiPaneInfo *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
bool Result = This->HasMaximizeButton();
rt.addBool(Result);
- break;
+ break;
}
-case wxAuiPaneInfo_HasMinimizeButton: { // wxAuiPaneInfo::HasMinimizeButton
+case wxAuiPaneInfo_HasMinimizeButton: { // wxAuiPaneInfo::HasMinimizeButton
wxAuiPaneInfo *This = (wxAuiPaneInfo *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
bool Result = This->HasMinimizeButton();
rt.addBool(Result);
- break;
+ break;
}
-case wxAuiPaneInfo_HasPinButton: { // wxAuiPaneInfo::HasPinButton
+case wxAuiPaneInfo_HasPinButton: { // wxAuiPaneInfo::HasPinButton
wxAuiPaneInfo *This = (wxAuiPaneInfo *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
bool Result = This->HasPinButton();
rt.addBool(Result);
- break;
+ break;
}
-case wxAuiPaneInfo_Hide: { // wxAuiPaneInfo::Hide
+case wxAuiPaneInfo_Hide: { // wxAuiPaneInfo::Hide
wxAuiPaneInfo *This = (wxAuiPaneInfo *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
wxAuiPaneInfo * Result = &This->Hide();
rt.addRef(getRef((void *)Result,memenv), "wxAuiPaneInfo");
- break;
+ break;
}
-case wxAuiPaneInfo_IsBottomDockable: { // wxAuiPaneInfo::IsBottomDockable
+case wxAuiPaneInfo_IsBottomDockable: { // wxAuiPaneInfo::IsBottomDockable
wxAuiPaneInfo *This = (wxAuiPaneInfo *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
bool Result = This->IsBottomDockable();
rt.addBool(Result);
- break;
+ break;
}
-case wxAuiPaneInfo_IsDocked: { // wxAuiPaneInfo::IsDocked
+case wxAuiPaneInfo_IsDocked: { // wxAuiPaneInfo::IsDocked
wxAuiPaneInfo *This = (wxAuiPaneInfo *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
bool Result = This->IsDocked();
rt.addBool(Result);
- break;
+ break;
}
-case wxAuiPaneInfo_IsFixed: { // wxAuiPaneInfo::IsFixed
+case wxAuiPaneInfo_IsFixed: { // wxAuiPaneInfo::IsFixed
wxAuiPaneInfo *This = (wxAuiPaneInfo *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
bool Result = This->IsFixed();
rt.addBool(Result);
- break;
+ break;
}
-case wxAuiPaneInfo_IsFloatable: { // wxAuiPaneInfo::IsFloatable
+case wxAuiPaneInfo_IsFloatable: { // wxAuiPaneInfo::IsFloatable
wxAuiPaneInfo *This = (wxAuiPaneInfo *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
bool Result = This->IsFloatable();
rt.addBool(Result);
- break;
+ break;
}
-case wxAuiPaneInfo_IsFloating: { // wxAuiPaneInfo::IsFloating
+case wxAuiPaneInfo_IsFloating: { // wxAuiPaneInfo::IsFloating
wxAuiPaneInfo *This = (wxAuiPaneInfo *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
bool Result = This->IsFloating();
rt.addBool(Result);
- break;
+ break;
}
-case wxAuiPaneInfo_IsLeftDockable: { // wxAuiPaneInfo::IsLeftDockable
+case wxAuiPaneInfo_IsLeftDockable: { // wxAuiPaneInfo::IsLeftDockable
wxAuiPaneInfo *This = (wxAuiPaneInfo *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
bool Result = This->IsLeftDockable();
rt.addBool(Result);
- break;
+ break;
}
-case wxAuiPaneInfo_IsMovable: { // wxAuiPaneInfo::IsMovable
+case wxAuiPaneInfo_IsMovable: { // wxAuiPaneInfo::IsMovable
wxAuiPaneInfo *This = (wxAuiPaneInfo *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
bool Result = This->IsMovable();
rt.addBool(Result);
- break;
+ break;
}
-case wxAuiPaneInfo_IsOk: { // wxAuiPaneInfo::IsOk
+case wxAuiPaneInfo_IsOk: { // wxAuiPaneInfo::IsOk
wxAuiPaneInfo *This = (wxAuiPaneInfo *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
bool Result = This->IsOk();
rt.addBool(Result);
- break;
+ break;
}
-case wxAuiPaneInfo_IsResizable: { // wxAuiPaneInfo::IsResizable
+case wxAuiPaneInfo_IsResizable: { // wxAuiPaneInfo::IsResizable
wxAuiPaneInfo *This = (wxAuiPaneInfo *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
bool Result = This->IsResizable();
rt.addBool(Result);
- break;
+ break;
}
-case wxAuiPaneInfo_IsRightDockable: { // wxAuiPaneInfo::IsRightDockable
+case wxAuiPaneInfo_IsRightDockable: { // wxAuiPaneInfo::IsRightDockable
wxAuiPaneInfo *This = (wxAuiPaneInfo *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
bool Result = This->IsRightDockable();
rt.addBool(Result);
- break;
+ break;
}
-case wxAuiPaneInfo_IsShown: { // wxAuiPaneInfo::IsShown
+case wxAuiPaneInfo_IsShown: { // wxAuiPaneInfo::IsShown
wxAuiPaneInfo *This = (wxAuiPaneInfo *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
bool Result = This->IsShown();
rt.addBool(Result);
- break;
+ break;
}
-case wxAuiPaneInfo_IsToolbar: { // wxAuiPaneInfo::IsToolbar
+case wxAuiPaneInfo_IsToolbar: { // wxAuiPaneInfo::IsToolbar
wxAuiPaneInfo *This = (wxAuiPaneInfo *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
bool Result = This->IsToolbar();
rt.addBool(Result);
- break;
+ break;
}
-case wxAuiPaneInfo_IsTopDockable: { // wxAuiPaneInfo::IsTopDockable
+case wxAuiPaneInfo_IsTopDockable: { // wxAuiPaneInfo::IsTopDockable
wxAuiPaneInfo *This = (wxAuiPaneInfo *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
bool Result = This->IsTopDockable();
rt.addBool(Result);
- break;
+ break;
}
-case wxAuiPaneInfo_Layer: { // wxAuiPaneInfo::Layer
+case wxAuiPaneInfo_Layer: { // wxAuiPaneInfo::Layer
wxAuiPaneInfo *This = (wxAuiPaneInfo *) getPtr(bp,memenv); bp += 4;
int * layer = (int *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
wxAuiPaneInfo * Result = &This->Layer((int) *layer);
rt.addRef(getRef((void *)Result,memenv), "wxAuiPaneInfo");
- break;
+ break;
}
-case wxAuiPaneInfo_Left: { // wxAuiPaneInfo::Left
+case wxAuiPaneInfo_Left: { // wxAuiPaneInfo::Left
wxAuiPaneInfo *This = (wxAuiPaneInfo *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
wxAuiPaneInfo * Result = &This->Left();
rt.addRef(getRef((void *)Result,memenv), "wxAuiPaneInfo");
- break;
+ break;
}
-case wxAuiPaneInfo_LeftDockable: { // wxAuiPaneInfo::LeftDockable
+case wxAuiPaneInfo_LeftDockable: { // wxAuiPaneInfo::LeftDockable
bool b=true;
wxAuiPaneInfo *This = (wxAuiPaneInfo *) getPtr(bp,memenv); bp += 4;
bp += 4; /* Align */
- while( * (int*) bp) { switch (* (int*) bp) {
+ while( * (int*) bp) { switch (* (int*) bp) {
case 1: {bp += 4;
b = *(bool *) bp; bp += 4;
} break;
- }};
+ }};
if(!This) throw wxe_badarg(0);
wxAuiPaneInfo * Result = &This->LeftDockable(b);
rt.addRef(getRef((void *)Result,memenv), "wxAuiPaneInfo");
- break;
+ break;
}
-case wxAuiPaneInfo_MaxSize_1: { // wxAuiPaneInfo::MaxSize
+case wxAuiPaneInfo_MaxSize_1: { // wxAuiPaneInfo::MaxSize
wxAuiPaneInfo *This = (wxAuiPaneInfo *) getPtr(bp,memenv); bp += 4;
int * sizeW = (int *) bp; bp += 4;
int * sizeH = (int *) bp; bp += 4;
@@ -24133,32 +24175,32 @@ case wxAuiPaneInfo_MaxSize_1: { // wxAuiPaneInfo::MaxSize
if(!This) throw wxe_badarg(0);
wxAuiPaneInfo * Result = &This->MaxSize(size);
rt.addRef(getRef((void *)Result,memenv), "wxAuiPaneInfo");
- break;
+ break;
}
-case wxAuiPaneInfo_MaxSize_2: { // wxAuiPaneInfo::MaxSize
+case wxAuiPaneInfo_MaxSize_2: { // wxAuiPaneInfo::MaxSize
wxAuiPaneInfo *This = (wxAuiPaneInfo *) getPtr(bp,memenv); bp += 4;
int * x = (int *) bp; bp += 4;
int * y = (int *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
wxAuiPaneInfo * Result = &This->MaxSize((int) *x,(int) *y);
rt.addRef(getRef((void *)Result,memenv), "wxAuiPaneInfo");
- break;
+ break;
}
-case wxAuiPaneInfo_MaximizeButton: { // wxAuiPaneInfo::MaximizeButton
+case wxAuiPaneInfo_MaximizeButton: { // wxAuiPaneInfo::MaximizeButton
bool visible=true;
wxAuiPaneInfo *This = (wxAuiPaneInfo *) getPtr(bp,memenv); bp += 4;
bp += 4; /* Align */
- while( * (int*) bp) { switch (* (int*) bp) {
+ while( * (int*) bp) { switch (* (int*) bp) {
case 1: {bp += 4;
visible = *(bool *) bp; bp += 4;
} break;
- }};
+ }};
if(!This) throw wxe_badarg(0);
wxAuiPaneInfo * Result = &This->MaximizeButton(visible);
rt.addRef(getRef((void *)Result,memenv), "wxAuiPaneInfo");
- break;
+ break;
}
-case wxAuiPaneInfo_MinSize_1: { // wxAuiPaneInfo::MinSize
+case wxAuiPaneInfo_MinSize_1: { // wxAuiPaneInfo::MinSize
wxAuiPaneInfo *This = (wxAuiPaneInfo *) getPtr(bp,memenv); bp += 4;
int * sizeW = (int *) bp; bp += 4;
int * sizeH = (int *) bp; bp += 4;
@@ -24166,46 +24208,46 @@ case wxAuiPaneInfo_MinSize_1: { // wxAuiPaneInfo::MinSize
if(!This) throw wxe_badarg(0);
wxAuiPaneInfo * Result = &This->MinSize(size);
rt.addRef(getRef((void *)Result,memenv), "wxAuiPaneInfo");
- break;
+ break;
}
-case wxAuiPaneInfo_MinSize_2: { // wxAuiPaneInfo::MinSize
+case wxAuiPaneInfo_MinSize_2: { // wxAuiPaneInfo::MinSize
wxAuiPaneInfo *This = (wxAuiPaneInfo *) getPtr(bp,memenv); bp += 4;
int * x = (int *) bp; bp += 4;
int * y = (int *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
wxAuiPaneInfo * Result = &This->MinSize((int) *x,(int) *y);
rt.addRef(getRef((void *)Result,memenv), "wxAuiPaneInfo");
- break;
+ break;
}
-case wxAuiPaneInfo_MinimizeButton: { // wxAuiPaneInfo::MinimizeButton
+case wxAuiPaneInfo_MinimizeButton: { // wxAuiPaneInfo::MinimizeButton
bool visible=true;
wxAuiPaneInfo *This = (wxAuiPaneInfo *) getPtr(bp,memenv); bp += 4;
bp += 4; /* Align */
- while( * (int*) bp) { switch (* (int*) bp) {
+ while( * (int*) bp) { switch (* (int*) bp) {
case 1: {bp += 4;
visible = *(bool *) bp; bp += 4;
} break;
- }};
+ }};
if(!This) throw wxe_badarg(0);
wxAuiPaneInfo * Result = &This->MinimizeButton(visible);
rt.addRef(getRef((void *)Result,memenv), "wxAuiPaneInfo");
- break;
+ break;
}
-case wxAuiPaneInfo_Movable: { // wxAuiPaneInfo::Movable
+case wxAuiPaneInfo_Movable: { // wxAuiPaneInfo::Movable
bool b=true;
wxAuiPaneInfo *This = (wxAuiPaneInfo *) getPtr(bp,memenv); bp += 4;
bp += 4; /* Align */
- while( * (int*) bp) { switch (* (int*) bp) {
+ while( * (int*) bp) { switch (* (int*) bp) {
case 1: {bp += 4;
b = *(bool *) bp; bp += 4;
} break;
- }};
+ }};
if(!This) throw wxe_badarg(0);
wxAuiPaneInfo * Result = &This->Movable(b);
rt.addRef(getRef((void *)Result,memenv), "wxAuiPaneInfo");
- break;
+ break;
}
-case wxAuiPaneInfo_Name: { // wxAuiPaneInfo::Name
+case wxAuiPaneInfo_Name: { // wxAuiPaneInfo::Name
wxAuiPaneInfo *This = (wxAuiPaneInfo *) getPtr(bp,memenv); bp += 4;
int * nLen = (int *) bp; bp += 4;
wxString n = wxString(bp, wxConvUTF8);
@@ -24213,169 +24255,169 @@ case wxAuiPaneInfo_Name: { // wxAuiPaneInfo::Name
if(!This) throw wxe_badarg(0);
wxAuiPaneInfo * Result = &This->Name(n);
rt.addRef(getRef((void *)Result,memenv), "wxAuiPaneInfo");
- break;
+ break;
}
-case wxAuiPaneInfo_PaneBorder: { // wxAuiPaneInfo::PaneBorder
+case wxAuiPaneInfo_PaneBorder: { // wxAuiPaneInfo::PaneBorder
bool visible=true;
wxAuiPaneInfo *This = (wxAuiPaneInfo *) getPtr(bp,memenv); bp += 4;
bp += 4; /* Align */
- while( * (int*) bp) { switch (* (int*) bp) {
+ while( * (int*) bp) { switch (* (int*) bp) {
case 1: {bp += 4;
visible = *(bool *) bp; bp += 4;
} break;
- }};
+ }};
if(!This) throw wxe_badarg(0);
wxAuiPaneInfo * Result = &This->PaneBorder(visible);
rt.addRef(getRef((void *)Result,memenv), "wxAuiPaneInfo");
- break;
+ break;
}
-case wxAuiPaneInfo_PinButton: { // wxAuiPaneInfo::PinButton
+case wxAuiPaneInfo_PinButton: { // wxAuiPaneInfo::PinButton
bool visible=true;
wxAuiPaneInfo *This = (wxAuiPaneInfo *) getPtr(bp,memenv); bp += 4;
bp += 4; /* Align */
- while( * (int*) bp) { switch (* (int*) bp) {
+ while( * (int*) bp) { switch (* (int*) bp) {
case 1: {bp += 4;
visible = *(bool *) bp; bp += 4;
} break;
- }};
+ }};
if(!This) throw wxe_badarg(0);
wxAuiPaneInfo * Result = &This->PinButton(visible);
rt.addRef(getRef((void *)Result,memenv), "wxAuiPaneInfo");
- break;
+ break;
}
-case wxAuiPaneInfo_Position: { // wxAuiPaneInfo::Position
+case wxAuiPaneInfo_Position: { // wxAuiPaneInfo::Position
wxAuiPaneInfo *This = (wxAuiPaneInfo *) getPtr(bp,memenv); bp += 4;
int * pos = (int *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
wxAuiPaneInfo * Result = &This->Position((int) *pos);
rt.addRef(getRef((void *)Result,memenv), "wxAuiPaneInfo");
- break;
+ break;
}
-case wxAuiPaneInfo_Resizable: { // wxAuiPaneInfo::Resizable
+case wxAuiPaneInfo_Resizable: { // wxAuiPaneInfo::Resizable
bool resizable=true;
wxAuiPaneInfo *This = (wxAuiPaneInfo *) getPtr(bp,memenv); bp += 4;
bp += 4; /* Align */
- while( * (int*) bp) { switch (* (int*) bp) {
+ while( * (int*) bp) { switch (* (int*) bp) {
case 1: {bp += 4;
resizable = *(bool *) bp; bp += 4;
} break;
- }};
+ }};
if(!This) throw wxe_badarg(0);
wxAuiPaneInfo * Result = &This->Resizable(resizable);
rt.addRef(getRef((void *)Result,memenv), "wxAuiPaneInfo");
- break;
+ break;
}
-case wxAuiPaneInfo_Right: { // wxAuiPaneInfo::Right
+case wxAuiPaneInfo_Right: { // wxAuiPaneInfo::Right
wxAuiPaneInfo *This = (wxAuiPaneInfo *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
wxAuiPaneInfo * Result = &This->Right();
rt.addRef(getRef((void *)Result,memenv), "wxAuiPaneInfo");
- break;
+ break;
}
-case wxAuiPaneInfo_RightDockable: { // wxAuiPaneInfo::RightDockable
+case wxAuiPaneInfo_RightDockable: { // wxAuiPaneInfo::RightDockable
bool b=true;
wxAuiPaneInfo *This = (wxAuiPaneInfo *) getPtr(bp,memenv); bp += 4;
bp += 4; /* Align */
- while( * (int*) bp) { switch (* (int*) bp) {
+ while( * (int*) bp) { switch (* (int*) bp) {
case 1: {bp += 4;
b = *(bool *) bp; bp += 4;
} break;
- }};
+ }};
if(!This) throw wxe_badarg(0);
wxAuiPaneInfo * Result = &This->RightDockable(b);
rt.addRef(getRef((void *)Result,memenv), "wxAuiPaneInfo");
- break;
+ break;
}
-case wxAuiPaneInfo_Row: { // wxAuiPaneInfo::Row
+case wxAuiPaneInfo_Row: { // wxAuiPaneInfo::Row
wxAuiPaneInfo *This = (wxAuiPaneInfo *) getPtr(bp,memenv); bp += 4;
int * row = (int *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
wxAuiPaneInfo * Result = &This->Row((int) *row);
rt.addRef(getRef((void *)Result,memenv), "wxAuiPaneInfo");
- break;
+ break;
}
-case wxAuiPaneInfo_SafeSet: { // wxAuiPaneInfo::SafeSet
+case wxAuiPaneInfo_SafeSet: { // wxAuiPaneInfo::SafeSet
wxAuiPaneInfo *This = (wxAuiPaneInfo *) getPtr(bp,memenv); bp += 4;
wxAuiPaneInfo *source = (wxAuiPaneInfo *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
This->SafeSet(*source);
- break;
+ break;
}
-case wxAuiPaneInfo_SetFlag: { // wxAuiPaneInfo::SetFlag
+case wxAuiPaneInfo_SetFlag: { // wxAuiPaneInfo::SetFlag
wxAuiPaneInfo *This = (wxAuiPaneInfo *) getPtr(bp,memenv); bp += 4;
unsigned int * flag = (unsigned int *) bp; bp += 4;
bool * option_state = (bool *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
wxAuiPaneInfo * Result = &This->SetFlag((int) *flag,(bool) *option_state);
rt.addRef(getRef((void *)Result,memenv), "wxAuiPaneInfo");
- break;
+ break;
}
-case wxAuiPaneInfo_Show: { // wxAuiPaneInfo::Show
+case wxAuiPaneInfo_Show: { // wxAuiPaneInfo::Show
bool show=true;
wxAuiPaneInfo *This = (wxAuiPaneInfo *) getPtr(bp,memenv); bp += 4;
bp += 4; /* Align */
- while( * (int*) bp) { switch (* (int*) bp) {
+ while( * (int*) bp) { switch (* (int*) bp) {
case 1: {bp += 4;
show = *(bool *) bp; bp += 4;
} break;
- }};
+ }};
if(!This) throw wxe_badarg(0);
wxAuiPaneInfo * Result = &This->Show(show);
rt.addRef(getRef((void *)Result,memenv), "wxAuiPaneInfo");
- break;
+ break;
}
-case wxAuiPaneInfo_ToolbarPane: { // wxAuiPaneInfo::ToolbarPane
+case wxAuiPaneInfo_ToolbarPane: { // wxAuiPaneInfo::ToolbarPane
wxAuiPaneInfo *This = (wxAuiPaneInfo *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
wxAuiPaneInfo * Result = &This->ToolbarPane();
rt.addRef(getRef((void *)Result,memenv), "wxAuiPaneInfo");
- break;
+ break;
}
-case wxAuiPaneInfo_Top: { // wxAuiPaneInfo::Top
+case wxAuiPaneInfo_Top: { // wxAuiPaneInfo::Top
wxAuiPaneInfo *This = (wxAuiPaneInfo *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
wxAuiPaneInfo * Result = &This->Top();
rt.addRef(getRef((void *)Result,memenv), "wxAuiPaneInfo");
- break;
+ break;
}
-case wxAuiPaneInfo_TopDockable: { // wxAuiPaneInfo::TopDockable
+case wxAuiPaneInfo_TopDockable: { // wxAuiPaneInfo::TopDockable
bool b=true;
wxAuiPaneInfo *This = (wxAuiPaneInfo *) getPtr(bp,memenv); bp += 4;
bp += 4; /* Align */
- while( * (int*) bp) { switch (* (int*) bp) {
+ while( * (int*) bp) { switch (* (int*) bp) {
case 1: {bp += 4;
b = *(bool *) bp; bp += 4;
} break;
- }};
+ }};
if(!This) throw wxe_badarg(0);
wxAuiPaneInfo * Result = &This->TopDockable(b);
rt.addRef(getRef((void *)Result,memenv), "wxAuiPaneInfo");
- break;
+ break;
}
-case wxAuiPaneInfo_Window: { // wxAuiPaneInfo::Window
+case wxAuiPaneInfo_Window: { // wxAuiPaneInfo::Window
wxAuiPaneInfo *This = (wxAuiPaneInfo *) getPtr(bp,memenv); bp += 4;
wxWindow *w = (wxWindow *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
wxAuiPaneInfo * Result = &This->Window(w);
rt.addRef(getRef((void *)Result,memenv), "wxAuiPaneInfo");
- break;
+ break;
}
#endif // wxUSE_AUI
#if wxUSE_AUI
-case wxAuiNotebook_new_0: { // wxAuiNotebook::wxAuiNotebook
+case wxAuiNotebook_new_0: { // wxAuiNotebook::wxAuiNotebook
wxAuiNotebook * Result = new EwxAuiNotebook();
newPtr((void *) Result, 0, memenv);
rt.addRef(getRef((void *)Result,memenv), "wxAuiNotebook");
- break;
+ break;
}
-case wxAuiNotebook_new_2: { // wxAuiNotebook::wxAuiNotebook
+case wxAuiNotebook_new_2: { // wxAuiNotebook::wxAuiNotebook
wxWindowID id=wxID_ANY;
wxPoint pos= wxDefaultPosition;
wxSize size= wxDefaultSize;
long style=wxAUI_NB_DEFAULT_STYLE;
wxWindow *parent = (wxWindow *) getPtr(bp,memenv); bp += 4;
bp += 4; /* Align */
- while( * (int*) bp) { switch (* (int*) bp) {
+ while( * (int*) bp) { switch (* (int*) bp) {
case 1: {bp += 4;
id = (wxWindowID)*(int *) bp; bp += 4;
} break;
@@ -24394,13 +24436,13 @@ case wxAuiNotebook_new_2: { // wxAuiNotebook::wxAuiNotebook
case 4: {bp += 4;
style = (long)*(int *) bp; bp += 4;
} break;
- }};
+ }};
wxAuiNotebook * Result = new EwxAuiNotebook(parent,id,pos,size,style);
newPtr((void *) Result, 0, memenv);
rt.addRef(getRef((void *)Result,memenv), "wxAuiNotebook");
- break;
+ break;
}
-case wxAuiNotebook_AddPage: { // wxAuiNotebook::AddPage
+case wxAuiNotebook_AddPage: { // wxAuiNotebook::AddPage
bool select=false;
const wxBitmap * bitmap= &wxNullBitmap;
wxAuiNotebook *This = (wxAuiNotebook *) getPtr(bp,memenv); bp += 4;
@@ -24408,27 +24450,27 @@ case wxAuiNotebook_AddPage: { // wxAuiNotebook::AddPage
int * captionLen = (int *) bp; bp += 4;
wxString caption = wxString(bp, wxConvUTF8);
bp += *captionLen+((8-((4+ *captionLen) & 7)) & 7);
- while( * (int*) bp) { switch (* (int*) bp) {
+ while( * (int*) bp) { switch (* (int*) bp) {
case 1: {bp += 4;
select = *(bool *) bp; bp += 4;
} break;
case 2: {bp += 4;
bitmap = (wxBitmap *) getPtr(bp,memenv); bp += 4;
} break;
- }};
+ }};
if(!This) throw wxe_badarg(0);
bool Result = This->AddPage(page,caption,select,*bitmap);
rt.addBool(Result);
- break;
+ break;
}
-case wxAuiNotebook_Create: { // wxAuiNotebook::Create
+case wxAuiNotebook_Create: { // wxAuiNotebook::Create
wxWindowID id=wxID_ANY;
wxPoint pos= wxDefaultPosition;
wxSize size= wxDefaultSize;
long style=0;
wxAuiNotebook *This = (wxAuiNotebook *) getPtr(bp,memenv); bp += 4;
wxWindow *parent = (wxWindow *) getPtr(bp,memenv); bp += 4;
- while( * (int*) bp) { switch (* (int*) bp) {
+ while( * (int*) bp) { switch (* (int*) bp) {
case 1: {bp += 4;
id = (wxWindowID)*(int *) bp; bp += 4;
} break;
@@ -24447,74 +24489,74 @@ case wxAuiNotebook_Create: { // wxAuiNotebook::Create
case 4: {bp += 4;
style = (long)*(int *) bp; bp += 4;
} break;
- }};
+ }};
if(!This) throw wxe_badarg(0);
bool Result = This->Create(parent,id,pos,size,style);
rt.addBool(Result);
- break;
+ break;
}
-case wxAuiNotebook_DeletePage: { // wxAuiNotebook::DeletePage
+case wxAuiNotebook_DeletePage: { // wxAuiNotebook::DeletePage
wxAuiNotebook *This = (wxAuiNotebook *) getPtr(bp,memenv); bp += 4;
int * page = (int *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
bool Result = This->DeletePage((size_t) *page);
rt.addBool(Result);
- break;
+ break;
}
-case wxAuiNotebook_GetArtProvider: { // wxAuiNotebook::GetArtProvider
+case wxAuiNotebook_GetArtProvider: { // wxAuiNotebook::GetArtProvider
wxAuiNotebook *This = (wxAuiNotebook *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
wxAuiTabArt * Result = (wxAuiTabArt*)This->GetArtProvider();
rt.addRef(getRef((void *)Result,memenv), "wxAuiTabArt");
- break;
+ break;
}
-case wxAuiNotebook_GetPage: { // wxAuiNotebook::GetPage
+case wxAuiNotebook_GetPage: { // wxAuiNotebook::GetPage
wxAuiNotebook *This = (wxAuiNotebook *) getPtr(bp,memenv); bp += 4;
int * page_idx = (int *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
wxWindow * Result = (wxWindow*)This->GetPage((size_t) *page_idx);
rt.addRef(getRef((void *)Result,memenv), "wxWindow");
- break;
+ break;
}
-case wxAuiNotebook_GetPageBitmap: { // wxAuiNotebook::GetPageBitmap
+case wxAuiNotebook_GetPageBitmap: { // wxAuiNotebook::GetPageBitmap
wxAuiNotebook *This = (wxAuiNotebook *) getPtr(bp,memenv); bp += 4;
int * page_idx = (int *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
wxBitmap * Result = new wxBitmap(This->GetPageBitmap((size_t) *page_idx)); newPtr((void *) Result,3, memenv);;
rt.addRef(getRef((void *)Result,memenv), "wxBitmap");
- break;
+ break;
}
-case wxAuiNotebook_GetPageCount: { // wxAuiNotebook::GetPageCount
+case wxAuiNotebook_GetPageCount: { // wxAuiNotebook::GetPageCount
wxAuiNotebook *This = (wxAuiNotebook *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
size_t Result = This->GetPageCount();
rt.addInt(Result);
- break;
+ break;
}
-case wxAuiNotebook_GetPageIndex: { // wxAuiNotebook::GetPageIndex
+case wxAuiNotebook_GetPageIndex: { // wxAuiNotebook::GetPageIndex
wxAuiNotebook *This = (wxAuiNotebook *) getPtr(bp,memenv); bp += 4;
wxWindow *page_wnd = (wxWindow *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
int Result = This->GetPageIndex(page_wnd);
rt.addInt(Result);
- break;
+ break;
}
-case wxAuiNotebook_GetPageText: { // wxAuiNotebook::GetPageText
+case wxAuiNotebook_GetPageText: { // wxAuiNotebook::GetPageText
wxAuiNotebook *This = (wxAuiNotebook *) getPtr(bp,memenv); bp += 4;
int * page_idx = (int *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
wxString Result = This->GetPageText((size_t) *page_idx);
rt.add(Result);
- break;
+ break;
}
-case wxAuiNotebook_GetSelection: { // wxAuiNotebook::GetSelection
+case wxAuiNotebook_GetSelection: { // wxAuiNotebook::GetSelection
wxAuiNotebook *This = (wxAuiNotebook *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
int Result = This->GetSelection();
rt.addInt(Result);
- break;
+ break;
}
-case wxAuiNotebook_InsertPage: { // wxAuiNotebook::InsertPage
+case wxAuiNotebook_InsertPage: { // wxAuiNotebook::InsertPage
bool select=false;
const wxBitmap * bitmap= &wxNullBitmap;
wxAuiNotebook *This = (wxAuiNotebook *) getPtr(bp,memenv); bp += 4;
@@ -24523,52 +24565,52 @@ case wxAuiNotebook_InsertPage: { // wxAuiNotebook::InsertPage
int * captionLen = (int *) bp; bp += 4;
wxString caption = wxString(bp, wxConvUTF8);
bp += *captionLen+((8-((0+ *captionLen) & 7)) & 7);
- while( * (int*) bp) { switch (* (int*) bp) {
+ while( * (int*) bp) { switch (* (int*) bp) {
case 1: {bp += 4;
select = *(bool *) bp; bp += 4;
} break;
case 2: {bp += 4;
bitmap = (wxBitmap *) getPtr(bp,memenv); bp += 4;
} break;
- }};
+ }};
if(!This) throw wxe_badarg(0);
bool Result = This->InsertPage((size_t) *page_idx,page,caption,select,*bitmap);
rt.addBool(Result);
- break;
+ break;
}
-case wxAuiNotebook_RemovePage: { // wxAuiNotebook::RemovePage
+case wxAuiNotebook_RemovePage: { // wxAuiNotebook::RemovePage
wxAuiNotebook *This = (wxAuiNotebook *) getPtr(bp,memenv); bp += 4;
int * page = (int *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
bool Result = This->RemovePage((size_t) *page);
rt.addBool(Result);
- break;
+ break;
}
-case wxAuiNotebook_SetArtProvider: { // wxAuiNotebook::SetArtProvider
+case wxAuiNotebook_SetArtProvider: { // wxAuiNotebook::SetArtProvider
wxAuiNotebook *This = (wxAuiNotebook *) getPtr(bp,memenv); bp += 4;
wxAuiTabArt *art = (wxAuiTabArt *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
This->SetArtProvider(art);
- break;
+ break;
}
-case wxAuiNotebook_SetFont: { // wxAuiNotebook::SetFont
+case wxAuiNotebook_SetFont: { // wxAuiNotebook::SetFont
wxAuiNotebook *This = (wxAuiNotebook *) getPtr(bp,memenv); bp += 4;
wxFont *font = (wxFont *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
bool Result = This->SetFont(*font);
rt.addBool(Result);
- break;
+ break;
}
-case wxAuiNotebook_SetPageBitmap: { // wxAuiNotebook::SetPageBitmap
+case wxAuiNotebook_SetPageBitmap: { // wxAuiNotebook::SetPageBitmap
wxAuiNotebook *This = (wxAuiNotebook *) getPtr(bp,memenv); bp += 4;
int * page = (int *) bp; bp += 4;
wxBitmap *bitmap = (wxBitmap *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
bool Result = This->SetPageBitmap((size_t) *page,*bitmap);
rt.addBool(Result);
- break;
+ break;
}
-case wxAuiNotebook_SetPageText: { // wxAuiNotebook::SetPageText
+case wxAuiNotebook_SetPageText: { // wxAuiNotebook::SetPageText
wxAuiNotebook *This = (wxAuiNotebook *) getPtr(bp,memenv); bp += 4;
int * page = (int *) bp; bp += 4;
int * textLen = (int *) bp; bp += 4;
@@ -24577,44 +24619,44 @@ case wxAuiNotebook_SetPageText: { // wxAuiNotebook::SetPageText
if(!This) throw wxe_badarg(0);
bool Result = This->SetPageText((size_t) *page,text);
rt.addBool(Result);
- break;
+ break;
}
-case wxAuiNotebook_SetSelection: { // wxAuiNotebook::SetSelection
+case wxAuiNotebook_SetSelection: { // wxAuiNotebook::SetSelection
wxAuiNotebook *This = (wxAuiNotebook *) getPtr(bp,memenv); bp += 4;
int * new_page = (int *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
size_t Result = This->SetSelection((size_t) *new_page);
rt.addInt(Result);
- break;
+ break;
}
-case wxAuiNotebook_SetTabCtrlHeight: { // wxAuiNotebook::SetTabCtrlHeight
+case wxAuiNotebook_SetTabCtrlHeight: { // wxAuiNotebook::SetTabCtrlHeight
wxAuiNotebook *This = (wxAuiNotebook *) getPtr(bp,memenv); bp += 4;
int * height = (int *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
This->SetTabCtrlHeight((int) *height);
- break;
+ break;
}
-case wxAuiNotebook_SetUniformBitmapSize: { // wxAuiNotebook::SetUniformBitmapSize
+case wxAuiNotebook_SetUniformBitmapSize: { // wxAuiNotebook::SetUniformBitmapSize
wxAuiNotebook *This = (wxAuiNotebook *) getPtr(bp,memenv); bp += 4;
int * sizeW = (int *) bp; bp += 4;
int * sizeH = (int *) bp; bp += 4;
wxSize size = wxSize(*sizeW,*sizeH);
if(!This) throw wxe_badarg(0);
This->SetUniformBitmapSize(size);
- break;
+ break;
}
#endif // wxUSE_AUI
#if wxUSE_AUI
#endif // wxUSE_AUI
#if wxUSE_AUI
#endif // wxUSE_AUI
-case wxMDIParentFrame_new_0: { // wxMDIParentFrame::wxMDIParentFrame
+case wxMDIParentFrame_new_0: { // wxMDIParentFrame::wxMDIParentFrame
wxMDIParentFrame * Result = new EwxMDIParentFrame();
newPtr((void *) Result, 0, memenv);
rt.addRef(getRef((void *)Result,memenv), "wxMDIParentFrame");
- break;
+ break;
}
-case wxMDIParentFrame_new_4: { // wxMDIParentFrame::wxMDIParentFrame
+case wxMDIParentFrame_new_4: { // wxMDIParentFrame::wxMDIParentFrame
wxPoint pos= wxDefaultPosition;
wxSize size= wxDefaultSize;
long style=wxDEFAULT_FRAME_STYLE|wxVSCROLL|wxHSCROLL;
@@ -24623,7 +24665,7 @@ case wxMDIParentFrame_new_4: { // wxMDIParentFrame::wxMDIParentFrame
int * titleLen = (int *) bp; bp += 4;
wxString title = wxString(bp, wxConvUTF8);
bp += *titleLen+((8-((4+ *titleLen) & 7)) & 7);
- while( * (int*) bp) { switch (* (int*) bp) {
+ while( * (int*) bp) { switch (* (int*) bp) {
case 1: {bp += 4;
int * posX = (int *) bp; bp += 4;
int * posY = (int *) bp; bp += 4;
@@ -24639,37 +24681,37 @@ case wxMDIParentFrame_new_4: { // wxMDIParentFrame::wxMDIParentFrame
case 3: {bp += 4;
style = (long)*(int *) bp; bp += 4;
} break;
- }};
+ }};
wxMDIParentFrame * Result = new EwxMDIParentFrame(parent,(wxWindowID) *id,title,pos,size,style);
newPtr((void *) Result, 0, memenv);
rt.addRef(getRef((void *)Result,memenv), "wxMDIParentFrame");
- break;
+ break;
}
-case wxMDIParentFrame_ActivateNext: { // wxMDIParentFrame::ActivateNext
+case wxMDIParentFrame_ActivateNext: { // wxMDIParentFrame::ActivateNext
wxMDIParentFrame *This = (wxMDIParentFrame *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
This->ActivateNext();
- break;
+ break;
}
-case wxMDIParentFrame_ActivatePrevious: { // wxMDIParentFrame::ActivatePrevious
+case wxMDIParentFrame_ActivatePrevious: { // wxMDIParentFrame::ActivatePrevious
wxMDIParentFrame *This = (wxMDIParentFrame *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
This->ActivatePrevious();
- break;
+ break;
}
-case wxMDIParentFrame_ArrangeIcons: { // wxMDIParentFrame::ArrangeIcons
+case wxMDIParentFrame_ArrangeIcons: { // wxMDIParentFrame::ArrangeIcons
wxMDIParentFrame *This = (wxMDIParentFrame *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
This->ArrangeIcons();
- break;
+ break;
}
-case wxMDIParentFrame_Cascade: { // wxMDIParentFrame::Cascade
+case wxMDIParentFrame_Cascade: { // wxMDIParentFrame::Cascade
wxMDIParentFrame *This = (wxMDIParentFrame *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
This->Cascade();
- break;
+ break;
}
-case wxMDIParentFrame_Create: { // wxMDIParentFrame::Create
+case wxMDIParentFrame_Create: { // wxMDIParentFrame::Create
wxPoint pos= wxDefaultPosition;
wxSize size= wxDefaultSize;
long style=wxDEFAULT_FRAME_STYLE|wxVSCROLL|wxHSCROLL;
@@ -24679,7 +24721,7 @@ case wxMDIParentFrame_Create: { // wxMDIParentFrame::Create
int * titleLen = (int *) bp; bp += 4;
wxString title = wxString(bp, wxConvUTF8);
bp += *titleLen+((8-((0+ *titleLen) & 7)) & 7);
- while( * (int*) bp) { switch (* (int*) bp) {
+ while( * (int*) bp) { switch (* (int*) bp) {
case 1: {bp += 4;
int * posX = (int *) bp; bp += 4;
int * posY = (int *) bp; bp += 4;
@@ -24695,46 +24737,46 @@ case wxMDIParentFrame_Create: { // wxMDIParentFrame::Create
case 3: {bp += 4;
style = (long)*(int *) bp; bp += 4;
} break;
- }};
+ }};
if(!This) throw wxe_badarg(0);
bool Result = This->Create(parent,(wxWindowID) *id,title,pos,size,style);
rt.addBool(Result);
- break;
+ break;
}
-case wxMDIParentFrame_GetActiveChild: { // wxMDIParentFrame::GetActiveChild
+case wxMDIParentFrame_GetActiveChild: { // wxMDIParentFrame::GetActiveChild
wxMDIParentFrame *This = (wxMDIParentFrame *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
wxMDIChildFrame * Result = (wxMDIChildFrame*)This->GetActiveChild();
rt.addRef(getRef((void *)Result,memenv), "wxMDIChildFrame");
- break;
+ break;
}
-case wxMDIParentFrame_GetClientWindow: { // wxMDIParentFrame::GetClientWindow
+case wxMDIParentFrame_GetClientWindow: { // wxMDIParentFrame::GetClientWindow
wxMDIParentFrame *This = (wxMDIParentFrame *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
wxMDIClientWindow * Result = (wxMDIClientWindow*)This->GetClientWindow();
rt.addRef(getRef((void *)Result,memenv), "wxMDIClientWindow");
- break;
+ break;
}
-case wxMDIParentFrame_Tile: { // wxMDIParentFrame::Tile
+case wxMDIParentFrame_Tile: { // wxMDIParentFrame::Tile
wxOrientation orient=wxHORIZONTAL;
wxMDIParentFrame *This = (wxMDIParentFrame *) getPtr(bp,memenv); bp += 4;
bp += 4; /* Align */
- while( * (int*) bp) { switch (* (int*) bp) {
+ while( * (int*) bp) { switch (* (int*) bp) {
case 1: {bp += 4;
orient = *(wxOrientation *) bp; bp += 4;;
} break;
- }};
+ }};
if(!This) throw wxe_badarg(0);
This->Tile((wxOrientation) orient);
- break;
+ break;
}
-case wxMDIChildFrame_new_0: { // wxMDIChildFrame::wxMDIChildFrame
+case wxMDIChildFrame_new_0: { // wxMDIChildFrame::wxMDIChildFrame
wxMDIChildFrame * Result = new EwxMDIChildFrame();
newPtr((void *) Result, 0, memenv);
rt.addRef(getRef((void *)Result,memenv), "wxMDIChildFrame");
- break;
+ break;
}
-case wxMDIChildFrame_new_4: { // wxMDIChildFrame::wxMDIChildFrame
+case wxMDIChildFrame_new_4: { // wxMDIChildFrame::wxMDIChildFrame
wxPoint pos= wxDefaultPosition;
wxSize size= wxDefaultSize;
long style=wxDEFAULT_FRAME_STYLE;
@@ -24743,7 +24785,7 @@ case wxMDIChildFrame_new_4: { // wxMDIChildFrame::wxMDIChildFrame
int * titleLen = (int *) bp; bp += 4;
wxString title = wxString(bp, wxConvUTF8);
bp += *titleLen+((8-((4+ *titleLen) & 7)) & 7);
- while( * (int*) bp) { switch (* (int*) bp) {
+ while( * (int*) bp) { switch (* (int*) bp) {
case 1: {bp += 4;
int * posX = (int *) bp; bp += 4;
int * posY = (int *) bp; bp += 4;
@@ -24759,19 +24801,19 @@ case wxMDIChildFrame_new_4: { // wxMDIChildFrame::wxMDIChildFrame
case 3: {bp += 4;
style = (long)*(int *) bp; bp += 4;
} break;
- }};
+ }};
wxMDIChildFrame * Result = new EwxMDIChildFrame(parent,(wxWindowID) *id,title,pos,size,style);
newPtr((void *) Result, 0, memenv);
rt.addRef(getRef((void *)Result,memenv), "wxMDIChildFrame");
- break;
+ break;
}
-case wxMDIChildFrame_Activate: { // wxMDIChildFrame::Activate
+case wxMDIChildFrame_Activate: { // wxMDIChildFrame::Activate
wxMDIChildFrame *This = (wxMDIChildFrame *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
This->Activate();
- break;
+ break;
}
-case wxMDIChildFrame_Create: { // wxMDIChildFrame::Create
+case wxMDIChildFrame_Create: { // wxMDIChildFrame::Create
wxPoint pos= wxDefaultPosition;
wxSize size= wxDefaultSize;
long style=wxDEFAULT_FRAME_STYLE;
@@ -24781,7 +24823,7 @@ case wxMDIChildFrame_Create: { // wxMDIChildFrame::Create
int * titleLen = (int *) bp; bp += 4;
wxString title = wxString(bp, wxConvUTF8);
bp += *titleLen+((8-((0+ *titleLen) & 7)) & 7);
- while( * (int*) bp) { switch (* (int*) bp) {
+ while( * (int*) bp) { switch (* (int*) bp) {
case 1: {bp += 4;
int * posX = (int *) bp; bp += 4;
int * posY = (int *) bp; bp += 4;
@@ -24797,90 +24839,90 @@ case wxMDIChildFrame_Create: { // wxMDIChildFrame::Create
case 3: {bp += 4;
style = (long)*(int *) bp; bp += 4;
} break;
- }};
+ }};
if(!This) throw wxe_badarg(0);
bool Result = This->Create(parent,(wxWindowID) *id,title,pos,size,style);
rt.addBool(Result);
- break;
+ break;
}
-case wxMDIChildFrame_Maximize: { // wxMDIChildFrame::Maximize
+case wxMDIChildFrame_Maximize: { // wxMDIChildFrame::Maximize
bool maximize=true;
wxMDIChildFrame *This = (wxMDIChildFrame *) getPtr(bp,memenv); bp += 4;
bp += 4; /* Align */
- while( * (int*) bp) { switch (* (int*) bp) {
+ while( * (int*) bp) { switch (* (int*) bp) {
case 1: {bp += 4;
maximize = *(bool *) bp; bp += 4;
} break;
- }};
+ }};
if(!This) throw wxe_badarg(0);
This->Maximize(maximize);
- break;
+ break;
}
-case wxMDIChildFrame_Restore: { // wxMDIChildFrame::Restore
+case wxMDIChildFrame_Restore: { // wxMDIChildFrame::Restore
wxMDIChildFrame *This = (wxMDIChildFrame *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
This->Restore();
- break;
+ break;
}
-case wxMDIClientWindow_new_0: { // wxMDIClientWindow::wxMDIClientWindow
+case wxMDIClientWindow_new_0: { // wxMDIClientWindow::wxMDIClientWindow
wxMDIClientWindow * Result = new EwxMDIClientWindow();
newPtr((void *) Result, 0, memenv);
rt.addRef(getRef((void *)Result,memenv), "wxMDIClientWindow");
- break;
+ break;
}
-case wxMDIClientWindow_new_2: { // wxMDIClientWindow::wxMDIClientWindow
+case wxMDIClientWindow_new_2: { // wxMDIClientWindow::wxMDIClientWindow
long style=0;
wxMDIParentFrame *parent = (wxMDIParentFrame *) getPtr(bp,memenv); bp += 4;
bp += 4; /* Align */
- while( * (int*) bp) { switch (* (int*) bp) {
+ while( * (int*) bp) { switch (* (int*) bp) {
case 1: {bp += 4;
style = (long)*(int *) bp; bp += 4;
} break;
- }};
+ }};
wxMDIClientWindow * Result = new EwxMDIClientWindow(parent,style);
newPtr((void *) Result, 0, memenv);
rt.addRef(getRef((void *)Result,memenv), "wxMDIClientWindow");
- break;
+ break;
}
-case wxMDIClientWindow_CreateClient: { // wxMDIClientWindow::CreateClient
+case wxMDIClientWindow_CreateClient: { // wxMDIClientWindow::CreateClient
long style=wxVSCROLL|wxHSCROLL;
wxMDIClientWindow *This = (wxMDIClientWindow *) getPtr(bp,memenv); bp += 4;
wxMDIParentFrame *parent = (wxMDIParentFrame *) getPtr(bp,memenv); bp += 4;
- while( * (int*) bp) { switch (* (int*) bp) {
+ while( * (int*) bp) { switch (* (int*) bp) {
case 1: {bp += 4;
style = (long)*(int *) bp; bp += 4;
} break;
- }};
+ }};
if(!This) throw wxe_badarg(0);
bool Result = This->CreateClient(parent,style);
rt.addBool(Result);
- break;
+ break;
}
-case wxLayoutAlgorithm_new: { // wxLayoutAlgorithm::wxLayoutAlgorithm
+case wxLayoutAlgorithm_new: { // wxLayoutAlgorithm::wxLayoutAlgorithm
wxLayoutAlgorithm * Result = new EwxLayoutAlgorithm();
newPtr((void *) Result, 1, memenv);
rt.addRef(getRef((void *)Result,memenv), "wxLayoutAlgorithm");
- break;
+ break;
}
-case wxLayoutAlgorithm_LayoutFrame: { // wxLayoutAlgorithm::LayoutFrame
+case wxLayoutAlgorithm_LayoutFrame: { // wxLayoutAlgorithm::LayoutFrame
wxWindow * mainWindow=(wxWindow *) NULL;
wxLayoutAlgorithm *This = (wxLayoutAlgorithm *) getPtr(bp,memenv); bp += 4;
wxFrame *frame = (wxFrame *) getPtr(bp,memenv); bp += 4;
- while( * (int*) bp) { switch (* (int*) bp) {
+ while( * (int*) bp) { switch (* (int*) bp) {
case 1: {bp += 4;
mainWindow = (wxWindow *) getPtr(bp,memenv); bp += 4;
} break;
- }};
+ }};
if(!This) throw wxe_badarg(0);
bool Result = This->LayoutFrame(frame,mainWindow);
rt.addBool(Result);
- break;
+ break;
}
-case wxLayoutAlgorithm_LayoutMDIFrame: { // wxLayoutAlgorithm::LayoutMDIFrame
+case wxLayoutAlgorithm_LayoutMDIFrame: { // wxLayoutAlgorithm::LayoutMDIFrame
wxRect *rect=(wxRect *) NULL; wxRect rectTmp;
wxLayoutAlgorithm *This = (wxLayoutAlgorithm *) getPtr(bp,memenv); bp += 4;
wxMDIParentFrame *frame = (wxMDIParentFrame *) getPtr(bp,memenv); bp += 4;
- while( * (int*) bp) { switch (* (int*) bp) {
+ while( * (int*) bp) { switch (* (int*) bp) {
case 1: {bp += 4;
int * rectX = (int *) bp; bp += 4;
int * rectY = (int *) bp; bp += 4;
@@ -24889,1501 +24931,1501 @@ case wxLayoutAlgorithm_LayoutMDIFrame: { // wxLayoutAlgorithm::LayoutMDIFrame
rectTmp = wxRect(*rectX,*rectY,*rectW,*rectH); rect = & rectTmp;
bp += 4; /* Align */
} break;
- }};
+ }};
if(!This) throw wxe_badarg(0);
bool Result = This->LayoutMDIFrame(frame,rect);
rt.addBool(Result);
- break;
+ break;
}
-case wxLayoutAlgorithm_LayoutWindow: { // wxLayoutAlgorithm::LayoutWindow
+case wxLayoutAlgorithm_LayoutWindow: { // wxLayoutAlgorithm::LayoutWindow
wxWindow * mainWindow=(wxWindow *) NULL;
wxLayoutAlgorithm *This = (wxLayoutAlgorithm *) getPtr(bp,memenv); bp += 4;
wxWindow *frame = (wxWindow *) getPtr(bp,memenv); bp += 4;
- while( * (int*) bp) { switch (* (int*) bp) {
+ while( * (int*) bp) { switch (* (int*) bp) {
case 1: {bp += 4;
mainWindow = (wxWindow *) getPtr(bp,memenv); bp += 4;
} break;
- }};
+ }};
if(!This) throw wxe_badarg(0);
bool Result = This->LayoutWindow(frame,mainWindow);
rt.addBool(Result);
- break;
+ break;
}
-case wxEvent_GetId: { // wxEvent::GetId
+case wxEvent_GetId: { // wxEvent::GetId
wxEvent *This = (wxEvent *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
int Result = This->GetId();
rt.addInt(Result);
- break;
+ break;
}
-case wxEvent_GetSkipped: { // wxEvent::GetSkipped
+case wxEvent_GetSkipped: { // wxEvent::GetSkipped
wxEvent *This = (wxEvent *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
bool Result = This->GetSkipped();
rt.addBool(Result);
- break;
+ break;
}
-case wxEvent_GetTimestamp: { // wxEvent::GetTimestamp
+case wxEvent_GetTimestamp: { // wxEvent::GetTimestamp
wxEvent *This = (wxEvent *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
long Result = This->GetTimestamp();
rt.addUint(Result);
- break;
+ break;
}
-case wxEvent_IsCommandEvent: { // wxEvent::IsCommandEvent
+case wxEvent_IsCommandEvent: { // wxEvent::IsCommandEvent
wxEvent *This = (wxEvent *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
bool Result = This->IsCommandEvent();
rt.addBool(Result);
- break;
+ break;
}
-case wxEvent_ResumePropagation: { // wxEvent::ResumePropagation
+case wxEvent_ResumePropagation: { // wxEvent::ResumePropagation
wxEvent *This = (wxEvent *) getPtr(bp,memenv); bp += 4;
int * propagationLevel = (int *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
This->ResumePropagation((int) *propagationLevel);
- break;
+ break;
}
-case wxEvent_ShouldPropagate: { // wxEvent::ShouldPropagate
+case wxEvent_ShouldPropagate: { // wxEvent::ShouldPropagate
wxEvent *This = (wxEvent *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
bool Result = This->ShouldPropagate();
rt.addBool(Result);
- break;
+ break;
}
-case wxEvent_Skip: { // wxEvent::Skip
+case wxEvent_Skip: { // wxEvent::Skip
bool skip=true;
wxEvent *This = (wxEvent *) getPtr(bp,memenv); bp += 4;
bp += 4; /* Align */
- while( * (int*) bp) { switch (* (int*) bp) {
+ while( * (int*) bp) { switch (* (int*) bp) {
case 1: {bp += 4;
skip = *(bool *) bp; bp += 4;
} break;
- }};
+ }};
if(!This) throw wxe_badarg(0);
This->Skip(skip);
- break;
+ break;
}
-case wxEvent_StopPropagation: { // wxEvent::StopPropagation
+case wxEvent_StopPropagation: { // wxEvent::StopPropagation
wxEvent *This = (wxEvent *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
int Result = This->StopPropagation();
rt.addInt(Result);
- break;
+ break;
}
-case wxCommandEvent_getClientData: { // wxCommandEvent::GetClientObject
+case wxCommandEvent_getClientData: { // wxCommandEvent::GetClientObject
wxCommandEvent *This = (wxCommandEvent *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
wxeErlTerm * Result = (wxeErlTerm*)This->GetClientObject();
rt.addExt2Term(Result);
- break;
+ break;
}
-case wxCommandEvent_GetExtraLong: { // wxCommandEvent::GetExtraLong
+case wxCommandEvent_GetExtraLong: { // wxCommandEvent::GetExtraLong
wxCommandEvent *This = (wxCommandEvent *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
long Result = This->GetExtraLong();
rt.addInt(Result);
- break;
+ break;
}
-case wxCommandEvent_GetInt: { // wxCommandEvent::GetInt
+case wxCommandEvent_GetInt: { // wxCommandEvent::GetInt
wxCommandEvent *This = (wxCommandEvent *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
int Result = This->GetInt();
rt.addInt(Result);
- break;
+ break;
}
-case wxCommandEvent_GetSelection: { // wxCommandEvent::GetSelection
+case wxCommandEvent_GetSelection: { // wxCommandEvent::GetSelection
wxCommandEvent *This = (wxCommandEvent *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
int Result = This->GetSelection();
rt.addInt(Result);
- break;
+ break;
}
-case wxCommandEvent_GetString: { // wxCommandEvent::GetString
+case wxCommandEvent_GetString: { // wxCommandEvent::GetString
wxCommandEvent *This = (wxCommandEvent *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
wxString Result = This->GetString();
rt.add(Result);
- break;
+ break;
}
-case wxCommandEvent_IsChecked: { // wxCommandEvent::IsChecked
+case wxCommandEvent_IsChecked: { // wxCommandEvent::IsChecked
wxCommandEvent *This = (wxCommandEvent *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
bool Result = This->IsChecked();
rt.addBool(Result);
- break;
+ break;
}
-case wxCommandEvent_IsSelection: { // wxCommandEvent::IsSelection
+case wxCommandEvent_IsSelection: { // wxCommandEvent::IsSelection
wxCommandEvent *This = (wxCommandEvent *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
bool Result = This->IsSelection();
rt.addBool(Result);
- break;
+ break;
}
-case wxCommandEvent_SetInt: { // wxCommandEvent::SetInt
+case wxCommandEvent_SetInt: { // wxCommandEvent::SetInt
wxCommandEvent *This = (wxCommandEvent *) getPtr(bp,memenv); bp += 4;
int * i = (int *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
This->SetInt((int) *i);
- break;
+ break;
}
-case wxCommandEvent_SetString: { // wxCommandEvent::SetString
+case wxCommandEvent_SetString: { // wxCommandEvent::SetString
wxCommandEvent *This = (wxCommandEvent *) getPtr(bp,memenv); bp += 4;
int * sLen = (int *) bp; bp += 4;
wxString s = wxString(bp, wxConvUTF8);
bp += *sLen+((8-((0+ *sLen) & 7)) & 7);
if(!This) throw wxe_badarg(0);
This->SetString(s);
- break;
+ break;
}
-case wxScrollEvent_GetOrientation: { // wxScrollEvent::GetOrientation
+case wxScrollEvent_GetOrientation: { // wxScrollEvent::GetOrientation
wxScrollEvent *This = (wxScrollEvent *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
int Result = This->GetOrientation();
rt.addInt(Result);
- break;
+ break;
}
-case wxScrollEvent_GetPosition: { // wxScrollEvent::GetPosition
+case wxScrollEvent_GetPosition: { // wxScrollEvent::GetPosition
wxScrollEvent *This = (wxScrollEvent *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
int Result = This->GetPosition();
rt.addInt(Result);
- break;
+ break;
}
-case wxScrollWinEvent_GetOrientation: { // wxScrollWinEvent::GetOrientation
+case wxScrollWinEvent_GetOrientation: { // wxScrollWinEvent::GetOrientation
wxScrollWinEvent *This = (wxScrollWinEvent *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
int Result = This->GetOrientation();
rt.addInt(Result);
- break;
+ break;
}
-case wxScrollWinEvent_GetPosition: { // wxScrollWinEvent::GetPosition
+case wxScrollWinEvent_GetPosition: { // wxScrollWinEvent::GetPosition
wxScrollWinEvent *This = (wxScrollWinEvent *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
int Result = This->GetPosition();
rt.addInt(Result);
- break;
+ break;
}
-case wxMouseEvent_AltDown: { // wxMouseEvent::AltDown
+case wxMouseEvent_AltDown: { // wxMouseEvent::AltDown
wxMouseEvent *This = (wxMouseEvent *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
bool Result = This->AltDown();
rt.addBool(Result);
- break;
+ break;
}
-case wxMouseEvent_Button: { // wxMouseEvent::Button
+case wxMouseEvent_Button: { // wxMouseEvent::Button
wxMouseEvent *This = (wxMouseEvent *) getPtr(bp,memenv); bp += 4;
int * but = (int *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
bool Result = This->Button((int) *but);
rt.addBool(Result);
- break;
+ break;
}
-case wxMouseEvent_ButtonDClick: { // wxMouseEvent::ButtonDClick
+case wxMouseEvent_ButtonDClick: { // wxMouseEvent::ButtonDClick
int but=wxMOUSE_BTN_ANY;
wxMouseEvent *This = (wxMouseEvent *) getPtr(bp,memenv); bp += 4;
bp += 4; /* Align */
- while( * (int*) bp) { switch (* (int*) bp) {
+ while( * (int*) bp) { switch (* (int*) bp) {
case 1: {bp += 4;
but = (int)*(int *) bp; bp += 4;
} break;
- }};
+ }};
if(!This) throw wxe_badarg(0);
bool Result = This->ButtonDClick(but);
rt.addBool(Result);
- break;
+ break;
}
-case wxMouseEvent_ButtonDown: { // wxMouseEvent::ButtonDown
+case wxMouseEvent_ButtonDown: { // wxMouseEvent::ButtonDown
int but=wxMOUSE_BTN_ANY;
wxMouseEvent *This = (wxMouseEvent *) getPtr(bp,memenv); bp += 4;
bp += 4; /* Align */
- while( * (int*) bp) { switch (* (int*) bp) {
+ while( * (int*) bp) { switch (* (int*) bp) {
case 1: {bp += 4;
but = (int)*(int *) bp; bp += 4;
} break;
- }};
+ }};
if(!This) throw wxe_badarg(0);
bool Result = This->ButtonDown(but);
rt.addBool(Result);
- break;
+ break;
}
-case wxMouseEvent_ButtonUp: { // wxMouseEvent::ButtonUp
+case wxMouseEvent_ButtonUp: { // wxMouseEvent::ButtonUp
int but=wxMOUSE_BTN_ANY;
wxMouseEvent *This = (wxMouseEvent *) getPtr(bp,memenv); bp += 4;
bp += 4; /* Align */
- while( * (int*) bp) { switch (* (int*) bp) {
+ while( * (int*) bp) { switch (* (int*) bp) {
case 1: {bp += 4;
but = (int)*(int *) bp; bp += 4;
} break;
- }};
+ }};
if(!This) throw wxe_badarg(0);
bool Result = This->ButtonUp(but);
rt.addBool(Result);
- break;
+ break;
}
-case wxMouseEvent_CmdDown: { // wxMouseEvent::CmdDown
+case wxMouseEvent_CmdDown: { // wxMouseEvent::CmdDown
wxMouseEvent *This = (wxMouseEvent *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
bool Result = This->CmdDown();
rt.addBool(Result);
- break;
+ break;
}
-case wxMouseEvent_ControlDown: { // wxMouseEvent::ControlDown
+case wxMouseEvent_ControlDown: { // wxMouseEvent::ControlDown
wxMouseEvent *This = (wxMouseEvent *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
bool Result = This->ControlDown();
rt.addBool(Result);
- break;
+ break;
}
-case wxMouseEvent_Dragging: { // wxMouseEvent::Dragging
+case wxMouseEvent_Dragging: { // wxMouseEvent::Dragging
wxMouseEvent *This = (wxMouseEvent *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
bool Result = This->Dragging();
rt.addBool(Result);
- break;
+ break;
}
-case wxMouseEvent_Entering: { // wxMouseEvent::Entering
+case wxMouseEvent_Entering: { // wxMouseEvent::Entering
wxMouseEvent *This = (wxMouseEvent *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
bool Result = This->Entering();
rt.addBool(Result);
- break;
+ break;
}
-case wxMouseEvent_GetButton: { // wxMouseEvent::GetButton
+case wxMouseEvent_GetButton: { // wxMouseEvent::GetButton
wxMouseEvent *This = (wxMouseEvent *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
int Result = This->GetButton();
rt.addInt(Result);
- break;
+ break;
}
-case wxMouseEvent_GetPosition: { // wxMouseEvent::GetPosition
+case wxMouseEvent_GetPosition: { // wxMouseEvent::GetPosition
wxMouseEvent *This = (wxMouseEvent *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
wxPoint Result = This->GetPosition();
rt.add(Result);
- break;
+ break;
}
-case wxMouseEvent_GetLogicalPosition: { // wxMouseEvent::GetLogicalPosition
+case wxMouseEvent_GetLogicalPosition: { // wxMouseEvent::GetLogicalPosition
wxMouseEvent *This = (wxMouseEvent *) getPtr(bp,memenv); bp += 4;
wxDC *dc = (wxDC *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
wxPoint Result = This->GetLogicalPosition(*dc);
rt.add(Result);
- break;
+ break;
}
-case wxMouseEvent_GetLinesPerAction: { // wxMouseEvent::GetLinesPerAction
+case wxMouseEvent_GetLinesPerAction: { // wxMouseEvent::GetLinesPerAction
wxMouseEvent *This = (wxMouseEvent *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
int Result = This->GetLinesPerAction();
rt.addInt(Result);
- break;
+ break;
}
-case wxMouseEvent_GetWheelRotation: { // wxMouseEvent::GetWheelRotation
+case wxMouseEvent_GetWheelRotation: { // wxMouseEvent::GetWheelRotation
wxMouseEvent *This = (wxMouseEvent *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
int Result = This->GetWheelRotation();
rt.addInt(Result);
- break;
+ break;
}
-case wxMouseEvent_GetWheelDelta: { // wxMouseEvent::GetWheelDelta
+case wxMouseEvent_GetWheelDelta: { // wxMouseEvent::GetWheelDelta
wxMouseEvent *This = (wxMouseEvent *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
int Result = This->GetWheelDelta();
rt.addInt(Result);
- break;
+ break;
}
-case wxMouseEvent_GetX: { // wxMouseEvent::GetX
+case wxMouseEvent_GetX: { // wxMouseEvent::GetX
wxMouseEvent *This = (wxMouseEvent *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
wxCoord Result = This->GetX();
rt.addInt(Result);
- break;
+ break;
}
-case wxMouseEvent_GetY: { // wxMouseEvent::GetY
+case wxMouseEvent_GetY: { // wxMouseEvent::GetY
wxMouseEvent *This = (wxMouseEvent *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
wxCoord Result = This->GetY();
rt.addInt(Result);
- break;
+ break;
}
-case wxMouseEvent_IsButton: { // wxMouseEvent::IsButton
+case wxMouseEvent_IsButton: { // wxMouseEvent::IsButton
wxMouseEvent *This = (wxMouseEvent *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
bool Result = This->IsButton();
rt.addBool(Result);
- break;
+ break;
}
-case wxMouseEvent_IsPageScroll: { // wxMouseEvent::IsPageScroll
+case wxMouseEvent_IsPageScroll: { // wxMouseEvent::IsPageScroll
wxMouseEvent *This = (wxMouseEvent *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
bool Result = This->IsPageScroll();
rt.addBool(Result);
- break;
+ break;
}
-case wxMouseEvent_Leaving: { // wxMouseEvent::Leaving
+case wxMouseEvent_Leaving: { // wxMouseEvent::Leaving
wxMouseEvent *This = (wxMouseEvent *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
bool Result = This->Leaving();
rt.addBool(Result);
- break;
+ break;
}
-case wxMouseEvent_LeftDClick: { // wxMouseEvent::LeftDClick
+case wxMouseEvent_LeftDClick: { // wxMouseEvent::LeftDClick
wxMouseEvent *This = (wxMouseEvent *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
bool Result = This->LeftDClick();
rt.addBool(Result);
- break;
+ break;
}
-case wxMouseEvent_LeftDown: { // wxMouseEvent::LeftDown
+case wxMouseEvent_LeftDown: { // wxMouseEvent::LeftDown
wxMouseEvent *This = (wxMouseEvent *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
bool Result = This->LeftDown();
rt.addBool(Result);
- break;
+ break;
}
-case wxMouseEvent_LeftIsDown: { // wxMouseEvent::LeftIsDown
+case wxMouseEvent_LeftIsDown: { // wxMouseEvent::LeftIsDown
wxMouseEvent *This = (wxMouseEvent *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
bool Result = This->LeftIsDown();
rt.addBool(Result);
- break;
+ break;
}
-case wxMouseEvent_LeftUp: { // wxMouseEvent::LeftUp
+case wxMouseEvent_LeftUp: { // wxMouseEvent::LeftUp
wxMouseEvent *This = (wxMouseEvent *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
bool Result = This->LeftUp();
rt.addBool(Result);
- break;
+ break;
}
-case wxMouseEvent_MetaDown: { // wxMouseEvent::MetaDown
+case wxMouseEvent_MetaDown: { // wxMouseEvent::MetaDown
wxMouseEvent *This = (wxMouseEvent *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
bool Result = This->MetaDown();
rt.addBool(Result);
- break;
+ break;
}
-case wxMouseEvent_MiddleDClick: { // wxMouseEvent::MiddleDClick
+case wxMouseEvent_MiddleDClick: { // wxMouseEvent::MiddleDClick
wxMouseEvent *This = (wxMouseEvent *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
bool Result = This->MiddleDClick();
rt.addBool(Result);
- break;
+ break;
}
-case wxMouseEvent_MiddleDown: { // wxMouseEvent::MiddleDown
+case wxMouseEvent_MiddleDown: { // wxMouseEvent::MiddleDown
wxMouseEvent *This = (wxMouseEvent *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
bool Result = This->MiddleDown();
rt.addBool(Result);
- break;
+ break;
}
-case wxMouseEvent_MiddleIsDown: { // wxMouseEvent::MiddleIsDown
+case wxMouseEvent_MiddleIsDown: { // wxMouseEvent::MiddleIsDown
wxMouseEvent *This = (wxMouseEvent *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
bool Result = This->MiddleIsDown();
rt.addBool(Result);
- break;
+ break;
}
-case wxMouseEvent_MiddleUp: { // wxMouseEvent::MiddleUp
+case wxMouseEvent_MiddleUp: { // wxMouseEvent::MiddleUp
wxMouseEvent *This = (wxMouseEvent *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
bool Result = This->MiddleUp();
rt.addBool(Result);
- break;
+ break;
}
-case wxMouseEvent_Moving: { // wxMouseEvent::Moving
+case wxMouseEvent_Moving: { // wxMouseEvent::Moving
wxMouseEvent *This = (wxMouseEvent *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
bool Result = This->Moving();
rt.addBool(Result);
- break;
+ break;
}
-case wxMouseEvent_RightDClick: { // wxMouseEvent::RightDClick
+case wxMouseEvent_RightDClick: { // wxMouseEvent::RightDClick
wxMouseEvent *This = (wxMouseEvent *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
bool Result = This->RightDClick();
rt.addBool(Result);
- break;
+ break;
}
-case wxMouseEvent_RightDown: { // wxMouseEvent::RightDown
+case wxMouseEvent_RightDown: { // wxMouseEvent::RightDown
wxMouseEvent *This = (wxMouseEvent *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
bool Result = This->RightDown();
rt.addBool(Result);
- break;
+ break;
}
-case wxMouseEvent_RightIsDown: { // wxMouseEvent::RightIsDown
+case wxMouseEvent_RightIsDown: { // wxMouseEvent::RightIsDown
wxMouseEvent *This = (wxMouseEvent *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
bool Result = This->RightIsDown();
rt.addBool(Result);
- break;
+ break;
}
-case wxMouseEvent_RightUp: { // wxMouseEvent::RightUp
+case wxMouseEvent_RightUp: { // wxMouseEvent::RightUp
wxMouseEvent *This = (wxMouseEvent *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
bool Result = This->RightUp();
rt.addBool(Result);
- break;
+ break;
}
-case wxMouseEvent_ShiftDown: { // wxMouseEvent::ShiftDown
+case wxMouseEvent_ShiftDown: { // wxMouseEvent::ShiftDown
wxMouseEvent *This = (wxMouseEvent *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
bool Result = This->ShiftDown();
rt.addBool(Result);
- break;
+ break;
}
-case wxSetCursorEvent_GetCursor: { // wxSetCursorEvent::GetCursor
+case wxSetCursorEvent_GetCursor: { // wxSetCursorEvent::GetCursor
wxSetCursorEvent *This = (wxSetCursorEvent *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
const wxCursor * Result = &This->GetCursor();
rt.addRef(getRef((void *)Result,memenv), "wxCursor");
- break;
+ break;
}
-case wxSetCursorEvent_GetX: { // wxSetCursorEvent::GetX
+case wxSetCursorEvent_GetX: { // wxSetCursorEvent::GetX
wxSetCursorEvent *This = (wxSetCursorEvent *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
wxCoord Result = This->GetX();
rt.addInt(Result);
- break;
+ break;
}
-case wxSetCursorEvent_GetY: { // wxSetCursorEvent::GetY
+case wxSetCursorEvent_GetY: { // wxSetCursorEvent::GetY
wxSetCursorEvent *This = (wxSetCursorEvent *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
wxCoord Result = This->GetY();
rt.addInt(Result);
- break;
+ break;
}
-case wxSetCursorEvent_HasCursor: { // wxSetCursorEvent::HasCursor
+case wxSetCursorEvent_HasCursor: { // wxSetCursorEvent::HasCursor
wxSetCursorEvent *This = (wxSetCursorEvent *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
bool Result = This->HasCursor();
rt.addBool(Result);
- break;
+ break;
}
-case wxSetCursorEvent_SetCursor: { // wxSetCursorEvent::SetCursor
+case wxSetCursorEvent_SetCursor: { // wxSetCursorEvent::SetCursor
wxSetCursorEvent *This = (wxSetCursorEvent *) getPtr(bp,memenv); bp += 4;
wxCursor *cursor = (wxCursor *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
This->SetCursor(*cursor);
- break;
+ break;
}
-case wxKeyEvent_AltDown: { // wxKeyEvent::AltDown
+case wxKeyEvent_AltDown: { // wxKeyEvent::AltDown
wxKeyEvent *This = (wxKeyEvent *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
bool Result = This->AltDown();
rt.addBool(Result);
- break;
+ break;
}
-case wxKeyEvent_CmdDown: { // wxKeyEvent::CmdDown
+case wxKeyEvent_CmdDown: { // wxKeyEvent::CmdDown
wxKeyEvent *This = (wxKeyEvent *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
bool Result = This->CmdDown();
rt.addBool(Result);
- break;
+ break;
}
-case wxKeyEvent_ControlDown: { // wxKeyEvent::ControlDown
+case wxKeyEvent_ControlDown: { // wxKeyEvent::ControlDown
wxKeyEvent *This = (wxKeyEvent *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
bool Result = This->ControlDown();
rt.addBool(Result);
- break;
+ break;
}
-case wxKeyEvent_GetKeyCode: { // wxKeyEvent::GetKeyCode
+case wxKeyEvent_GetKeyCode: { // wxKeyEvent::GetKeyCode
wxKeyEvent *This = (wxKeyEvent *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
int Result = This->GetKeyCode();
rt.addInt(Result);
- break;
+ break;
}
-case wxKeyEvent_GetModifiers: { // wxKeyEvent::GetModifiers
+case wxKeyEvent_GetModifiers: { // wxKeyEvent::GetModifiers
wxKeyEvent *This = (wxKeyEvent *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
int Result = This->GetModifiers();
rt.addInt(Result);
- break;
+ break;
}
-case wxKeyEvent_GetPosition: { // wxKeyEvent::GetPosition
+case wxKeyEvent_GetPosition: { // wxKeyEvent::GetPosition
wxKeyEvent *This = (wxKeyEvent *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
wxPoint Result = This->GetPosition();
rt.add(Result);
- break;
+ break;
}
-case wxKeyEvent_GetRawKeyCode: { // wxKeyEvent::GetRawKeyCode
+case wxKeyEvent_GetRawKeyCode: { // wxKeyEvent::GetRawKeyCode
wxKeyEvent *This = (wxKeyEvent *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
int Result = This->GetRawKeyCode();
rt.addUint(Result);
- break;
+ break;
}
-case wxKeyEvent_GetRawKeyFlags: { // wxKeyEvent::GetRawKeyFlags
+case wxKeyEvent_GetRawKeyFlags: { // wxKeyEvent::GetRawKeyFlags
wxKeyEvent *This = (wxKeyEvent *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
int Result = This->GetRawKeyFlags();
rt.addUint(Result);
- break;
+ break;
}
-case wxKeyEvent_GetUnicodeKey: { // wxKeyEvent::GetUnicodeKey
+case wxKeyEvent_GetUnicodeKey: { // wxKeyEvent::GetUnicodeKey
wxKeyEvent *This = (wxKeyEvent *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
wxChar Result = This->GetUnicodeKey();
rt.addInt(Result);
- break;
+ break;
}
-case wxKeyEvent_GetX: { // wxKeyEvent::GetX
+case wxKeyEvent_GetX: { // wxKeyEvent::GetX
wxKeyEvent *This = (wxKeyEvent *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
wxCoord Result = This->GetX();
rt.addInt(Result);
- break;
+ break;
}
-case wxKeyEvent_GetY: { // wxKeyEvent::GetY
+case wxKeyEvent_GetY: { // wxKeyEvent::GetY
wxKeyEvent *This = (wxKeyEvent *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
wxCoord Result = This->GetY();
rt.addInt(Result);
- break;
+ break;
}
-case wxKeyEvent_HasModifiers: { // wxKeyEvent::HasModifiers
+case wxKeyEvent_HasModifiers: { // wxKeyEvent::HasModifiers
wxKeyEvent *This = (wxKeyEvent *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
bool Result = This->HasModifiers();
rt.addBool(Result);
- break;
+ break;
}
-case wxKeyEvent_MetaDown: { // wxKeyEvent::MetaDown
+case wxKeyEvent_MetaDown: { // wxKeyEvent::MetaDown
wxKeyEvent *This = (wxKeyEvent *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
bool Result = This->MetaDown();
rt.addBool(Result);
- break;
+ break;
}
-case wxKeyEvent_ShiftDown: { // wxKeyEvent::ShiftDown
+case wxKeyEvent_ShiftDown: { // wxKeyEvent::ShiftDown
wxKeyEvent *This = (wxKeyEvent *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
bool Result = This->ShiftDown();
rt.addBool(Result);
- break;
+ break;
}
-case wxSizeEvent_GetSize: { // wxSizeEvent::GetSize
+case wxSizeEvent_GetSize: { // wxSizeEvent::GetSize
wxSizeEvent *This = (wxSizeEvent *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
wxSize Result = This->GetSize();
rt.add(Result);
- break;
+ break;
}
-case wxMoveEvent_GetPosition: { // wxMoveEvent::GetPosition
+case wxMoveEvent_GetPosition: { // wxMoveEvent::GetPosition
wxMoveEvent *This = (wxMoveEvent *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
wxPoint Result = This->GetPosition();
rt.add(Result);
- break;
+ break;
}
-case wxEraseEvent_GetDC: { // wxEraseEvent::GetDC
+case wxEraseEvent_GetDC: { // wxEraseEvent::GetDC
wxEraseEvent *This = (wxEraseEvent *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
wxDC * Result = (wxDC*)This->GetDC();
rt.addRef(getRef((void *)Result,memenv), "wxDC");
- break;
+ break;
}
-case wxFocusEvent_GetWindow: { // wxFocusEvent::GetWindow
+case wxFocusEvent_GetWindow: { // wxFocusEvent::GetWindow
wxFocusEvent *This = (wxFocusEvent *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
wxWindow * Result = (wxWindow*)This->GetWindow();
rt.addRef(getRef((void *)Result,memenv), "wxWindow");
- break;
+ break;
}
-case wxChildFocusEvent_GetWindow: { // wxChildFocusEvent::GetWindow
+case wxChildFocusEvent_GetWindow: { // wxChildFocusEvent::GetWindow
wxChildFocusEvent *This = (wxChildFocusEvent *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
wxWindow * Result = (wxWindow*)This->GetWindow();
rt.addRef(getRef((void *)Result,memenv), "wxWindow");
- break;
+ break;
}
-case wxMenuEvent_GetMenu: { // wxMenuEvent::GetMenu
+case wxMenuEvent_GetMenu: { // wxMenuEvent::GetMenu
wxMenuEvent *This = (wxMenuEvent *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
wxMenu * Result = (wxMenu*)This->GetMenu();
rt.addRef(getRef((void *)Result,memenv), "wxMenu");
- break;
+ break;
}
-case wxMenuEvent_GetMenuId: { // wxMenuEvent::GetMenuId
+case wxMenuEvent_GetMenuId: { // wxMenuEvent::GetMenuId
wxMenuEvent *This = (wxMenuEvent *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
int Result = This->GetMenuId();
rt.addInt(Result);
- break;
+ break;
}
-case wxMenuEvent_IsPopup: { // wxMenuEvent::IsPopup
+case wxMenuEvent_IsPopup: { // wxMenuEvent::IsPopup
wxMenuEvent *This = (wxMenuEvent *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
bool Result = This->IsPopup();
rt.addBool(Result);
- break;
+ break;
}
-case wxCloseEvent_CanVeto: { // wxCloseEvent::CanVeto
+case wxCloseEvent_CanVeto: { // wxCloseEvent::CanVeto
wxCloseEvent *This = (wxCloseEvent *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
bool Result = This->CanVeto();
rt.addBool(Result);
- break;
+ break;
}
-case wxCloseEvent_GetLoggingOff: { // wxCloseEvent::GetLoggingOff
+case wxCloseEvent_GetLoggingOff: { // wxCloseEvent::GetLoggingOff
wxCloseEvent *This = (wxCloseEvent *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
bool Result = This->GetLoggingOff();
rt.addBool(Result);
- break;
+ break;
}
-case wxCloseEvent_SetCanVeto: { // wxCloseEvent::SetCanVeto
+case wxCloseEvent_SetCanVeto: { // wxCloseEvent::SetCanVeto
wxCloseEvent *This = (wxCloseEvent *) getPtr(bp,memenv); bp += 4;
bool * canVeto = (bool *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
This->SetCanVeto((bool) *canVeto);
- break;
+ break;
}
-case wxCloseEvent_SetLoggingOff: { // wxCloseEvent::SetLoggingOff
+case wxCloseEvent_SetLoggingOff: { // wxCloseEvent::SetLoggingOff
wxCloseEvent *This = (wxCloseEvent *) getPtr(bp,memenv); bp += 4;
bool * logOff = (bool *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
This->SetLoggingOff((bool) *logOff);
- break;
+ break;
}
-case wxCloseEvent_Veto: { // wxCloseEvent::Veto
+case wxCloseEvent_Veto: { // wxCloseEvent::Veto
bool veto=true;
wxCloseEvent *This = (wxCloseEvent *) getPtr(bp,memenv); bp += 4;
bp += 4; /* Align */
- while( * (int*) bp) { switch (* (int*) bp) {
+ while( * (int*) bp) { switch (* (int*) bp) {
case 1: {bp += 4;
veto = *(bool *) bp; bp += 4;
} break;
- }};
+ }};
if(!This) throw wxe_badarg(0);
This->Veto(veto);
- break;
+ break;
}
-case wxShowEvent_SetShow: { // wxShowEvent::SetShow
+case wxShowEvent_SetShow: { // wxShowEvent::SetShow
wxShowEvent *This = (wxShowEvent *) getPtr(bp,memenv); bp += 4;
bool * show = (bool *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
This->SetShow((bool) *show);
- break;
+ break;
}
-case wxShowEvent_GetShow: { // wxShowEvent::GetShow
+case wxShowEvent_GetShow: { // wxShowEvent::GetShow
wxShowEvent *This = (wxShowEvent *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
bool Result = This->GetShow();
rt.addBool(Result);
- break;
+ break;
}
-case wxIconizeEvent_Iconized: { // wxIconizeEvent::Iconized
+case wxIconizeEvent_Iconized: { // wxIconizeEvent::Iconized
wxIconizeEvent *This = (wxIconizeEvent *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
bool Result = This->Iconized();
rt.addBool(Result);
- break;
+ break;
}
-case wxJoystickEvent_ButtonDown: { // wxJoystickEvent::ButtonDown
+case wxJoystickEvent_ButtonDown: { // wxJoystickEvent::ButtonDown
int but=wxJOY_BUTTON_ANY;
wxJoystickEvent *This = (wxJoystickEvent *) getPtr(bp,memenv); bp += 4;
bp += 4; /* Align */
- while( * (int*) bp) { switch (* (int*) bp) {
+ while( * (int*) bp) { switch (* (int*) bp) {
case 1: {bp += 4;
but = (int)*(int *) bp; bp += 4;
} break;
- }};
+ }};
if(!This) throw wxe_badarg(0);
bool Result = This->ButtonDown(but);
rt.addBool(Result);
- break;
+ break;
}
-case wxJoystickEvent_ButtonIsDown: { // wxJoystickEvent::ButtonIsDown
+case wxJoystickEvent_ButtonIsDown: { // wxJoystickEvent::ButtonIsDown
int but=wxJOY_BUTTON_ANY;
wxJoystickEvent *This = (wxJoystickEvent *) getPtr(bp,memenv); bp += 4;
bp += 4; /* Align */
- while( * (int*) bp) { switch (* (int*) bp) {
+ while( * (int*) bp) { switch (* (int*) bp) {
case 1: {bp += 4;
but = (int)*(int *) bp; bp += 4;
} break;
- }};
+ }};
if(!This) throw wxe_badarg(0);
bool Result = This->ButtonIsDown(but);
rt.addBool(Result);
- break;
+ break;
}
-case wxJoystickEvent_ButtonUp: { // wxJoystickEvent::ButtonUp
+case wxJoystickEvent_ButtonUp: { // wxJoystickEvent::ButtonUp
int but=wxJOY_BUTTON_ANY;
wxJoystickEvent *This = (wxJoystickEvent *) getPtr(bp,memenv); bp += 4;
bp += 4; /* Align */
- while( * (int*) bp) { switch (* (int*) bp) {
+ while( * (int*) bp) { switch (* (int*) bp) {
case 1: {bp += 4;
but = (int)*(int *) bp; bp += 4;
} break;
- }};
+ }};
if(!This) throw wxe_badarg(0);
bool Result = This->ButtonUp(but);
rt.addBool(Result);
- break;
+ break;
}
-case wxJoystickEvent_GetButtonChange: { // wxJoystickEvent::GetButtonChange
+case wxJoystickEvent_GetButtonChange: { // wxJoystickEvent::GetButtonChange
wxJoystickEvent *This = (wxJoystickEvent *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
int Result = This->GetButtonChange();
rt.addInt(Result);
- break;
+ break;
}
-case wxJoystickEvent_GetButtonState: { // wxJoystickEvent::GetButtonState
+case wxJoystickEvent_GetButtonState: { // wxJoystickEvent::GetButtonState
wxJoystickEvent *This = (wxJoystickEvent *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
int Result = This->GetButtonState();
rt.addInt(Result);
- break;
+ break;
}
-case wxJoystickEvent_GetJoystick: { // wxJoystickEvent::GetJoystick
+case wxJoystickEvent_GetJoystick: { // wxJoystickEvent::GetJoystick
wxJoystickEvent *This = (wxJoystickEvent *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
int Result = This->GetJoystick();
rt.addInt(Result);
- break;
+ break;
}
-case wxJoystickEvent_GetPosition: { // wxJoystickEvent::GetPosition
+case wxJoystickEvent_GetPosition: { // wxJoystickEvent::GetPosition
wxJoystickEvent *This = (wxJoystickEvent *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
wxPoint Result = This->GetPosition();
rt.add(Result);
- break;
+ break;
}
-case wxJoystickEvent_GetZPosition: { // wxJoystickEvent::GetZPosition
+case wxJoystickEvent_GetZPosition: { // wxJoystickEvent::GetZPosition
wxJoystickEvent *This = (wxJoystickEvent *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
int Result = This->GetZPosition();
rt.addInt(Result);
- break;
+ break;
}
-case wxJoystickEvent_IsButton: { // wxJoystickEvent::IsButton
+case wxJoystickEvent_IsButton: { // wxJoystickEvent::IsButton
wxJoystickEvent *This = (wxJoystickEvent *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
bool Result = This->IsButton();
rt.addBool(Result);
- break;
+ break;
}
-case wxJoystickEvent_IsMove: { // wxJoystickEvent::IsMove
+case wxJoystickEvent_IsMove: { // wxJoystickEvent::IsMove
wxJoystickEvent *This = (wxJoystickEvent *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
bool Result = This->IsMove();
rt.addBool(Result);
- break;
+ break;
}
-case wxJoystickEvent_IsZMove: { // wxJoystickEvent::IsZMove
+case wxJoystickEvent_IsZMove: { // wxJoystickEvent::IsZMove
wxJoystickEvent *This = (wxJoystickEvent *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
bool Result = This->IsZMove();
rt.addBool(Result);
- break;
+ break;
}
-case wxUpdateUIEvent_CanUpdate: { // wxUpdateUIEvent::CanUpdate
+case wxUpdateUIEvent_CanUpdate: { // wxUpdateUIEvent::CanUpdate
wxWindow *win = (wxWindow *) getPtr(bp,memenv); bp += 4;
bool Result = wxUpdateUIEvent::CanUpdate(win);
rt.addBool(Result);
- break;
+ break;
}
-case wxUpdateUIEvent_Check: { // wxUpdateUIEvent::Check
+case wxUpdateUIEvent_Check: { // wxUpdateUIEvent::Check
wxUpdateUIEvent *This = (wxUpdateUIEvent *) getPtr(bp,memenv); bp += 4;
bool * check = (bool *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
This->Check((bool) *check);
- break;
+ break;
}
-case wxUpdateUIEvent_Enable: { // wxUpdateUIEvent::Enable
+case wxUpdateUIEvent_Enable: { // wxUpdateUIEvent::Enable
wxUpdateUIEvent *This = (wxUpdateUIEvent *) getPtr(bp,memenv); bp += 4;
bool * enable = (bool *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
This->Enable((bool) *enable);
- break;
+ break;
}
-case wxUpdateUIEvent_Show: { // wxUpdateUIEvent::Show
+case wxUpdateUIEvent_Show: { // wxUpdateUIEvent::Show
wxUpdateUIEvent *This = (wxUpdateUIEvent *) getPtr(bp,memenv); bp += 4;
bool * show = (bool *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
This->Show((bool) *show);
- break;
+ break;
}
-case wxUpdateUIEvent_GetChecked: { // wxUpdateUIEvent::GetChecked
+case wxUpdateUIEvent_GetChecked: { // wxUpdateUIEvent::GetChecked
wxUpdateUIEvent *This = (wxUpdateUIEvent *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
bool Result = This->GetChecked();
rt.addBool(Result);
- break;
+ break;
}
-case wxUpdateUIEvent_GetEnabled: { // wxUpdateUIEvent::GetEnabled
+case wxUpdateUIEvent_GetEnabled: { // wxUpdateUIEvent::GetEnabled
wxUpdateUIEvent *This = (wxUpdateUIEvent *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
bool Result = This->GetEnabled();
rt.addBool(Result);
- break;
+ break;
}
-case wxUpdateUIEvent_GetShown: { // wxUpdateUIEvent::GetShown
+case wxUpdateUIEvent_GetShown: { // wxUpdateUIEvent::GetShown
wxUpdateUIEvent *This = (wxUpdateUIEvent *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
bool Result = This->GetShown();
rt.addBool(Result);
- break;
+ break;
}
-case wxUpdateUIEvent_GetSetChecked: { // wxUpdateUIEvent::GetSetChecked
+case wxUpdateUIEvent_GetSetChecked: { // wxUpdateUIEvent::GetSetChecked
wxUpdateUIEvent *This = (wxUpdateUIEvent *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
bool Result = This->GetSetChecked();
rt.addBool(Result);
- break;
+ break;
}
-case wxUpdateUIEvent_GetSetEnabled: { // wxUpdateUIEvent::GetSetEnabled
+case wxUpdateUIEvent_GetSetEnabled: { // wxUpdateUIEvent::GetSetEnabled
wxUpdateUIEvent *This = (wxUpdateUIEvent *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
bool Result = This->GetSetEnabled();
rt.addBool(Result);
- break;
+ break;
}
-case wxUpdateUIEvent_GetSetShown: { // wxUpdateUIEvent::GetSetShown
+case wxUpdateUIEvent_GetSetShown: { // wxUpdateUIEvent::GetSetShown
wxUpdateUIEvent *This = (wxUpdateUIEvent *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
bool Result = This->GetSetShown();
rt.addBool(Result);
- break;
+ break;
}
-case wxUpdateUIEvent_GetSetText: { // wxUpdateUIEvent::GetSetText
+case wxUpdateUIEvent_GetSetText: { // wxUpdateUIEvent::GetSetText
wxUpdateUIEvent *This = (wxUpdateUIEvent *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
bool Result = This->GetSetText();
rt.addBool(Result);
- break;
+ break;
}
-case wxUpdateUIEvent_GetText: { // wxUpdateUIEvent::GetText
+case wxUpdateUIEvent_GetText: { // wxUpdateUIEvent::GetText
wxUpdateUIEvent *This = (wxUpdateUIEvent *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
wxString Result = This->GetText();
rt.add(Result);
- break;
+ break;
}
-case wxUpdateUIEvent_GetMode: { // wxUpdateUIEvent::GetMode
+case wxUpdateUIEvent_GetMode: { // wxUpdateUIEvent::GetMode
int Result = wxUpdateUIEvent::GetMode();
rt.addInt(Result);
- break;
+ break;
}
-case wxUpdateUIEvent_GetUpdateInterval: { // wxUpdateUIEvent::GetUpdateInterval
+case wxUpdateUIEvent_GetUpdateInterval: { // wxUpdateUIEvent::GetUpdateInterval
long Result = wxUpdateUIEvent::GetUpdateInterval();
rt.addInt(Result);
- break;
+ break;
}
-case wxUpdateUIEvent_ResetUpdateTime: { // wxUpdateUIEvent::ResetUpdateTime
+case wxUpdateUIEvent_ResetUpdateTime: { // wxUpdateUIEvent::ResetUpdateTime
wxUpdateUIEvent::ResetUpdateTime();
- break;
+ break;
}
-case wxUpdateUIEvent_SetMode: { // wxUpdateUIEvent::SetMode
+case wxUpdateUIEvent_SetMode: { // wxUpdateUIEvent::SetMode
wxUpdateUIMode mode = *(wxUpdateUIMode *) bp; bp += 4;;
wxUpdateUIEvent::SetMode((wxUpdateUIMode) mode);
- break;
+ break;
}
-case wxUpdateUIEvent_SetText: { // wxUpdateUIEvent::SetText
+case wxUpdateUIEvent_SetText: { // wxUpdateUIEvent::SetText
wxUpdateUIEvent *This = (wxUpdateUIEvent *) getPtr(bp,memenv); bp += 4;
int * textLen = (int *) bp; bp += 4;
wxString text = wxString(bp, wxConvUTF8);
bp += *textLen+((8-((0+ *textLen) & 7)) & 7);
if(!This) throw wxe_badarg(0);
This->SetText(text);
- break;
+ break;
}
-case wxUpdateUIEvent_SetUpdateInterval: { // wxUpdateUIEvent::SetUpdateInterval
+case wxUpdateUIEvent_SetUpdateInterval: { // wxUpdateUIEvent::SetUpdateInterval
int * updateInterval = (int *) bp; bp += 4;
wxUpdateUIEvent::SetUpdateInterval((long) *updateInterval);
- break;
+ break;
}
-case wxMouseCaptureChangedEvent_GetCapturedWindow: { // wxMouseCaptureChangedEvent::GetCapturedWindow
+case wxMouseCaptureChangedEvent_GetCapturedWindow: { // wxMouseCaptureChangedEvent::GetCapturedWindow
wxMouseCaptureChangedEvent *This = (wxMouseCaptureChangedEvent *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
wxWindow * Result = (wxWindow*)This->GetCapturedWindow();
rt.addRef(getRef((void *)Result,memenv), "wxWindow");
- break;
+ break;
}
-case wxPaletteChangedEvent_SetChangedWindow: { // wxPaletteChangedEvent::SetChangedWindow
+case wxPaletteChangedEvent_SetChangedWindow: { // wxPaletteChangedEvent::SetChangedWindow
wxPaletteChangedEvent *This = (wxPaletteChangedEvent *) getPtr(bp,memenv); bp += 4;
wxWindow *win = (wxWindow *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
This->SetChangedWindow(win);
- break;
+ break;
}
-case wxPaletteChangedEvent_GetChangedWindow: { // wxPaletteChangedEvent::GetChangedWindow
+case wxPaletteChangedEvent_GetChangedWindow: { // wxPaletteChangedEvent::GetChangedWindow
wxPaletteChangedEvent *This = (wxPaletteChangedEvent *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
wxWindow * Result = (wxWindow*)This->GetChangedWindow();
rt.addRef(getRef((void *)Result,memenv), "wxWindow");
- break;
+ break;
}
-case wxQueryNewPaletteEvent_SetPaletteRealized: { // wxQueryNewPaletteEvent::SetPaletteRealized
+case wxQueryNewPaletteEvent_SetPaletteRealized: { // wxQueryNewPaletteEvent::SetPaletteRealized
wxQueryNewPaletteEvent *This = (wxQueryNewPaletteEvent *) getPtr(bp,memenv); bp += 4;
bool * realized = (bool *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
This->SetPaletteRealized((bool) *realized);
- break;
+ break;
}
-case wxQueryNewPaletteEvent_GetPaletteRealized: { // wxQueryNewPaletteEvent::GetPaletteRealized
+case wxQueryNewPaletteEvent_GetPaletteRealized: { // wxQueryNewPaletteEvent::GetPaletteRealized
wxQueryNewPaletteEvent *This = (wxQueryNewPaletteEvent *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
bool Result = This->GetPaletteRealized();
rt.addBool(Result);
- break;
+ break;
}
-case wxNavigationKeyEvent_GetDirection: { // wxNavigationKeyEvent::GetDirection
+case wxNavigationKeyEvent_GetDirection: { // wxNavigationKeyEvent::GetDirection
wxNavigationKeyEvent *This = (wxNavigationKeyEvent *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
bool Result = This->GetDirection();
rt.addBool(Result);
- break;
+ break;
}
-case wxNavigationKeyEvent_SetDirection: { // wxNavigationKeyEvent::SetDirection
+case wxNavigationKeyEvent_SetDirection: { // wxNavigationKeyEvent::SetDirection
wxNavigationKeyEvent *This = (wxNavigationKeyEvent *) getPtr(bp,memenv); bp += 4;
bool * bForward = (bool *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
This->SetDirection((bool) *bForward);
- break;
+ break;
}
-case wxNavigationKeyEvent_IsWindowChange: { // wxNavigationKeyEvent::IsWindowChange
+case wxNavigationKeyEvent_IsWindowChange: { // wxNavigationKeyEvent::IsWindowChange
wxNavigationKeyEvent *This = (wxNavigationKeyEvent *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
bool Result = This->IsWindowChange();
rt.addBool(Result);
- break;
+ break;
}
-case wxNavigationKeyEvent_SetWindowChange: { // wxNavigationKeyEvent::SetWindowChange
+case wxNavigationKeyEvent_SetWindowChange: { // wxNavigationKeyEvent::SetWindowChange
wxNavigationKeyEvent *This = (wxNavigationKeyEvent *) getPtr(bp,memenv); bp += 4;
bool * bIs = (bool *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
This->SetWindowChange((bool) *bIs);
- break;
+ break;
}
-case wxNavigationKeyEvent_IsFromTab: { // wxNavigationKeyEvent::IsFromTab
+case wxNavigationKeyEvent_IsFromTab: { // wxNavigationKeyEvent::IsFromTab
wxNavigationKeyEvent *This = (wxNavigationKeyEvent *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
bool Result = This->IsFromTab();
rt.addBool(Result);
- break;
+ break;
}
-case wxNavigationKeyEvent_SetFromTab: { // wxNavigationKeyEvent::SetFromTab
+case wxNavigationKeyEvent_SetFromTab: { // wxNavigationKeyEvent::SetFromTab
wxNavigationKeyEvent *This = (wxNavigationKeyEvent *) getPtr(bp,memenv); bp += 4;
bool * bIs = (bool *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
This->SetFromTab((bool) *bIs);
- break;
+ break;
}
-case wxNavigationKeyEvent_GetCurrentFocus: { // wxNavigationKeyEvent::GetCurrentFocus
+case wxNavigationKeyEvent_GetCurrentFocus: { // wxNavigationKeyEvent::GetCurrentFocus
wxNavigationKeyEvent *This = (wxNavigationKeyEvent *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
wxWindow * Result = (wxWindow*)This->GetCurrentFocus();
rt.addRef(getRef((void *)Result,memenv), "wxWindow");
- break;
+ break;
}
-case wxNavigationKeyEvent_SetCurrentFocus: { // wxNavigationKeyEvent::SetCurrentFocus
+case wxNavigationKeyEvent_SetCurrentFocus: { // wxNavigationKeyEvent::SetCurrentFocus
wxNavigationKeyEvent *This = (wxNavigationKeyEvent *) getPtr(bp,memenv); bp += 4;
wxWindow *win = (wxWindow *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
This->SetCurrentFocus(win);
- break;
+ break;
}
-case wxHelpEvent_GetOrigin: { // wxHelpEvent::GetOrigin
+case wxHelpEvent_GetOrigin: { // wxHelpEvent::GetOrigin
wxHelpEvent *This = (wxHelpEvent *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
int Result = This->GetOrigin();
rt.addInt(Result);
- break;
+ break;
}
-case wxHelpEvent_GetPosition: { // wxHelpEvent::GetPosition
+case wxHelpEvent_GetPosition: { // wxHelpEvent::GetPosition
wxHelpEvent *This = (wxHelpEvent *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
const wxPoint * Result = &This->GetPosition();
rt.add((*Result));
- break;
+ break;
}
-case wxHelpEvent_SetOrigin: { // wxHelpEvent::SetOrigin
+case wxHelpEvent_SetOrigin: { // wxHelpEvent::SetOrigin
wxHelpEvent *This = (wxHelpEvent *) getPtr(bp,memenv); bp += 4;
wxHelpEvent::Origin origin = *(wxHelpEvent::Origin *) bp; bp += 4;;
if(!This) throw wxe_badarg(0);
This->SetOrigin((wxHelpEvent::Origin) origin);
- break;
+ break;
}
-case wxHelpEvent_SetPosition: { // wxHelpEvent::SetPosition
+case wxHelpEvent_SetPosition: { // wxHelpEvent::SetPosition
wxHelpEvent *This = (wxHelpEvent *) getPtr(bp,memenv); bp += 4;
int * posX = (int *) bp; bp += 4;
int * posY = (int *) bp; bp += 4;
wxPoint pos = wxPoint(*posX,*posY);
if(!This) throw wxe_badarg(0);
This->SetPosition(pos);
- break;
+ break;
}
-case wxContextMenuEvent_GetPosition: { // wxContextMenuEvent::GetPosition
+case wxContextMenuEvent_GetPosition: { // wxContextMenuEvent::GetPosition
wxContextMenuEvent *This = (wxContextMenuEvent *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
const wxPoint * Result = &This->GetPosition();
rt.add((*Result));
- break;
+ break;
}
-case wxContextMenuEvent_SetPosition: { // wxContextMenuEvent::SetPosition
+case wxContextMenuEvent_SetPosition: { // wxContextMenuEvent::SetPosition
wxContextMenuEvent *This = (wxContextMenuEvent *) getPtr(bp,memenv); bp += 4;
int * posX = (int *) bp; bp += 4;
int * posY = (int *) bp; bp += 4;
wxPoint pos = wxPoint(*posX,*posY);
if(!This) throw wxe_badarg(0);
This->SetPosition(pos);
- break;
+ break;
}
-case wxIdleEvent_CanSend: { // wxIdleEvent::CanSend
+case wxIdleEvent_CanSend: { // wxIdleEvent::CanSend
wxWindow *win = (wxWindow *) getPtr(bp,memenv); bp += 4;
bool Result = wxIdleEvent::CanSend(win);
rt.addBool(Result);
- break;
+ break;
}
-case wxIdleEvent_GetMode: { // wxIdleEvent::GetMode
+case wxIdleEvent_GetMode: { // wxIdleEvent::GetMode
int Result = wxIdleEvent::GetMode();
rt.addInt(Result);
- break;
+ break;
}
-case wxIdleEvent_RequestMore: { // wxIdleEvent::RequestMore
+case wxIdleEvent_RequestMore: { // wxIdleEvent::RequestMore
bool needMore=true;
wxIdleEvent *This = (wxIdleEvent *) getPtr(bp,memenv); bp += 4;
bp += 4; /* Align */
- while( * (int*) bp) { switch (* (int*) bp) {
+ while( * (int*) bp) { switch (* (int*) bp) {
case 1: {bp += 4;
needMore = *(bool *) bp; bp += 4;
} break;
- }};
+ }};
if(!This) throw wxe_badarg(0);
This->RequestMore(needMore);
- break;
+ break;
}
-case wxIdleEvent_MoreRequested: { // wxIdleEvent::MoreRequested
+case wxIdleEvent_MoreRequested: { // wxIdleEvent::MoreRequested
wxIdleEvent *This = (wxIdleEvent *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
bool Result = This->MoreRequested();
rt.addBool(Result);
- break;
+ break;
}
-case wxIdleEvent_SetMode: { // wxIdleEvent::SetMode
+case wxIdleEvent_SetMode: { // wxIdleEvent::SetMode
wxIdleMode mode = *(wxIdleMode *) bp; bp += 4;;
wxIdleEvent::SetMode((wxIdleMode) mode);
- break;
+ break;
}
-case wxGridEvent_AltDown: { // wxGridEvent::AltDown
+case wxGridEvent_AltDown: { // wxGridEvent::AltDown
wxGridEvent *This = (wxGridEvent *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
bool Result = This->AltDown();
rt.addBool(Result);
- break;
+ break;
}
-case wxGridEvent_ControlDown: { // wxGridEvent::ControlDown
+case wxGridEvent_ControlDown: { // wxGridEvent::ControlDown
wxGridEvent *This = (wxGridEvent *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
bool Result = This->ControlDown();
rt.addBool(Result);
- break;
+ break;
}
-case wxGridEvent_GetCol: { // wxGridEvent::GetCol
+case wxGridEvent_GetCol: { // wxGridEvent::GetCol
wxGridEvent *This = (wxGridEvent *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
int Result = This->GetCol();
rt.addInt(Result);
- break;
+ break;
}
-case wxGridEvent_GetPosition: { // wxGridEvent::GetPosition
+case wxGridEvent_GetPosition: { // wxGridEvent::GetPosition
wxGridEvent *This = (wxGridEvent *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
wxPoint Result = This->GetPosition();
rt.add(Result);
- break;
+ break;
}
-case wxGridEvent_GetRow: { // wxGridEvent::GetRow
+case wxGridEvent_GetRow: { // wxGridEvent::GetRow
wxGridEvent *This = (wxGridEvent *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
int Result = This->GetRow();
rt.addInt(Result);
- break;
+ break;
}
-case wxGridEvent_MetaDown: { // wxGridEvent::MetaDown
+case wxGridEvent_MetaDown: { // wxGridEvent::MetaDown
wxGridEvent *This = (wxGridEvent *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
bool Result = This->MetaDown();
rt.addBool(Result);
- break;
+ break;
}
-case wxGridEvent_Selecting: { // wxGridEvent::Selecting
+case wxGridEvent_Selecting: { // wxGridEvent::Selecting
wxGridEvent *This = (wxGridEvent *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
bool Result = This->Selecting();
rt.addBool(Result);
- break;
+ break;
}
-case wxGridEvent_ShiftDown: { // wxGridEvent::ShiftDown
+case wxGridEvent_ShiftDown: { // wxGridEvent::ShiftDown
wxGridEvent *This = (wxGridEvent *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
bool Result = This->ShiftDown();
rt.addBool(Result);
- break;
+ break;
}
-case wxNotifyEvent_Allow: { // wxNotifyEvent::Allow
+case wxNotifyEvent_Allow: { // wxNotifyEvent::Allow
wxNotifyEvent *This = (wxNotifyEvent *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
This->Allow();
- break;
+ break;
}
-case wxNotifyEvent_IsAllowed: { // wxNotifyEvent::IsAllowed
+case wxNotifyEvent_IsAllowed: { // wxNotifyEvent::IsAllowed
wxNotifyEvent *This = (wxNotifyEvent *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
bool Result = This->IsAllowed();
rt.addBool(Result);
- break;
+ break;
}
-case wxNotifyEvent_Veto: { // wxNotifyEvent::Veto
+case wxNotifyEvent_Veto: { // wxNotifyEvent::Veto
wxNotifyEvent *This = (wxNotifyEvent *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
This->Veto();
- break;
+ break;
}
-case wxSashEvent_GetEdge: { // wxSashEvent::GetEdge
+case wxSashEvent_GetEdge: { // wxSashEvent::GetEdge
wxSashEvent *This = (wxSashEvent *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
int Result = This->GetEdge();
rt.addInt(Result);
- break;
+ break;
}
-case wxSashEvent_GetDragRect: { // wxSashEvent::GetDragRect
+case wxSashEvent_GetDragRect: { // wxSashEvent::GetDragRect
wxSashEvent *This = (wxSashEvent *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
wxRect Result = This->GetDragRect();
rt.add(Result);
- break;
+ break;
}
-case wxSashEvent_GetDragStatus: { // wxSashEvent::GetDragStatus
+case wxSashEvent_GetDragStatus: { // wxSashEvent::GetDragStatus
wxSashEvent *This = (wxSashEvent *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
int Result = This->GetDragStatus();
rt.addInt(Result);
- break;
+ break;
}
-case wxListEvent_GetCacheFrom: { // wxListEvent::GetCacheFrom
+case wxListEvent_GetCacheFrom: { // wxListEvent::GetCacheFrom
wxListEvent *This = (wxListEvent *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
long Result = This->GetCacheFrom();
rt.addInt(Result);
- break;
+ break;
}
-case wxListEvent_GetCacheTo: { // wxListEvent::GetCacheTo
+case wxListEvent_GetCacheTo: { // wxListEvent::GetCacheTo
wxListEvent *This = (wxListEvent *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
long Result = This->GetCacheTo();
rt.addInt(Result);
- break;
+ break;
}
-case wxListEvent_GetKeyCode: { // wxListEvent::GetKeyCode
+case wxListEvent_GetKeyCode: { // wxListEvent::GetKeyCode
wxListEvent *This = (wxListEvent *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
int Result = This->GetKeyCode();
rt.addInt(Result);
- break;
+ break;
}
-case wxListEvent_GetIndex: { // wxListEvent::GetIndex
+case wxListEvent_GetIndex: { // wxListEvent::GetIndex
wxListEvent *This = (wxListEvent *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
long Result = This->GetIndex();
rt.addInt(Result);
- break;
+ break;
}
-case wxListEvent_GetColumn: { // wxListEvent::GetColumn
+case wxListEvent_GetColumn: { // wxListEvent::GetColumn
wxListEvent *This = (wxListEvent *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
int Result = This->GetColumn();
rt.addInt(Result);
- break;
+ break;
}
-case wxListEvent_GetPoint: { // wxListEvent::GetPoint
+case wxListEvent_GetPoint: { // wxListEvent::GetPoint
wxListEvent *This = (wxListEvent *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
wxPoint Result = This->GetPoint();
rt.add(Result);
- break;
+ break;
}
-case wxListEvent_GetLabel: { // wxListEvent::GetLabel
+case wxListEvent_GetLabel: { // wxListEvent::GetLabel
wxListEvent *This = (wxListEvent *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
const wxString * Result = &This->GetLabel();
rt.add(Result);
- break;
+ break;
}
-case wxListEvent_GetText: { // wxListEvent::GetText
+case wxListEvent_GetText: { // wxListEvent::GetText
wxListEvent *This = (wxListEvent *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
const wxString * Result = &This->GetText();
rt.add(Result);
- break;
+ break;
}
-case wxListEvent_GetImage: { // wxListEvent::GetImage
+case wxListEvent_GetImage: { // wxListEvent::GetImage
wxListEvent *This = (wxListEvent *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
int Result = This->GetImage();
rt.addInt(Result);
- break;
+ break;
}
-case wxListEvent_GetData: { // wxListEvent::GetData
+case wxListEvent_GetData: { // wxListEvent::GetData
wxListEvent *This = (wxListEvent *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
long Result = This->GetData();
rt.addInt(Result);
- break;
+ break;
}
-case wxListEvent_GetMask: { // wxListEvent::GetMask
+case wxListEvent_GetMask: { // wxListEvent::GetMask
wxListEvent *This = (wxListEvent *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
long Result = This->GetMask();
rt.addInt(Result);
- break;
+ break;
}
-case wxListEvent_GetItem: { // wxListEvent::GetItem
+case wxListEvent_GetItem: { // wxListEvent::GetItem
wxListEvent *This = (wxListEvent *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
const wxListItem * Result = &This->GetItem();
rt.addRef(getRef((void *)Result,memenv), "wxListItem");
- break;
+ break;
}
-case wxListEvent_IsEditCancelled: { // wxListEvent::IsEditCancelled
+case wxListEvent_IsEditCancelled: { // wxListEvent::IsEditCancelled
wxListEvent *This = (wxListEvent *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
bool Result = This->IsEditCancelled();
rt.addBool(Result);
- break;
+ break;
}
-case wxDateEvent_GetDate: { // wxDateEvent::GetDate
+case wxDateEvent_GetDate: { // wxDateEvent::GetDate
wxDateEvent *This = (wxDateEvent *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
const wxDateTime * Result = &This->GetDate();
rt.add((*Result));
- break;
+ break;
}
-case wxCalendarEvent_GetWeekDay: { // wxCalendarEvent::GetWeekDay
+case wxCalendarEvent_GetWeekDay: { // wxCalendarEvent::GetWeekDay
wxCalendarEvent *This = (wxCalendarEvent *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
int Result = This->GetWeekDay();
rt.addInt(Result);
- break;
+ break;
}
-case wxFileDirPickerEvent_GetPath: { // wxFileDirPickerEvent::GetPath
+case wxFileDirPickerEvent_GetPath: { // wxFileDirPickerEvent::GetPath
wxFileDirPickerEvent *This = (wxFileDirPickerEvent *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
wxString Result = This->GetPath();
rt.add(Result);
- break;
+ break;
}
-case wxColourPickerEvent_GetColour: { // wxColourPickerEvent::GetColour
+case wxColourPickerEvent_GetColour: { // wxColourPickerEvent::GetColour
wxColourPickerEvent *This = (wxColourPickerEvent *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
wxColour Result = This->GetColour();
rt.add(Result);
- break;
+ break;
}
-case wxFontPickerEvent_GetFont: { // wxFontPickerEvent::GetFont
+case wxFontPickerEvent_GetFont: { // wxFontPickerEvent::GetFont
wxFontPickerEvent *This = (wxFontPickerEvent *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
wxFont * Result = new wxFont(This->GetFont()); newPtr((void *) Result,3, memenv);;
rt.addRef(getRef((void *)Result,memenv), "wxFont");
- break;
+ break;
}
-case wxStyledTextEvent_GetPosition: { // wxStyledTextEvent::GetPosition
+case wxStyledTextEvent_GetPosition: { // wxStyledTextEvent::GetPosition
wxStyledTextEvent *This = (wxStyledTextEvent *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
int Result = This->GetPosition();
rt.addInt(Result);
- break;
+ break;
}
-case wxStyledTextEvent_GetKey: { // wxStyledTextEvent::GetKey
+case wxStyledTextEvent_GetKey: { // wxStyledTextEvent::GetKey
wxStyledTextEvent *This = (wxStyledTextEvent *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
int Result = This->GetKey();
rt.addInt(Result);
- break;
+ break;
}
-case wxStyledTextEvent_GetModifiers: { // wxStyledTextEvent::GetModifiers
+case wxStyledTextEvent_GetModifiers: { // wxStyledTextEvent::GetModifiers
wxStyledTextEvent *This = (wxStyledTextEvent *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
int Result = This->GetModifiers();
rt.addInt(Result);
- break;
+ break;
}
-case wxStyledTextEvent_GetModificationType: { // wxStyledTextEvent::GetModificationType
+case wxStyledTextEvent_GetModificationType: { // wxStyledTextEvent::GetModificationType
wxStyledTextEvent *This = (wxStyledTextEvent *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
int Result = This->GetModificationType();
rt.addInt(Result);
- break;
+ break;
}
-case wxStyledTextEvent_GetText: { // wxStyledTextEvent::GetText
+case wxStyledTextEvent_GetText: { // wxStyledTextEvent::GetText
wxStyledTextEvent *This = (wxStyledTextEvent *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
wxString Result = This->GetText();
rt.add(Result);
- break;
+ break;
}
-case wxStyledTextEvent_GetLength: { // wxStyledTextEvent::GetLength
+case wxStyledTextEvent_GetLength: { // wxStyledTextEvent::GetLength
wxStyledTextEvent *This = (wxStyledTextEvent *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
int Result = This->GetLength();
rt.addInt(Result);
- break;
+ break;
}
-case wxStyledTextEvent_GetLinesAdded: { // wxStyledTextEvent::GetLinesAdded
+case wxStyledTextEvent_GetLinesAdded: { // wxStyledTextEvent::GetLinesAdded
wxStyledTextEvent *This = (wxStyledTextEvent *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
int Result = This->GetLinesAdded();
rt.addInt(Result);
- break;
+ break;
}
-case wxStyledTextEvent_GetLine: { // wxStyledTextEvent::GetLine
+case wxStyledTextEvent_GetLine: { // wxStyledTextEvent::GetLine
wxStyledTextEvent *This = (wxStyledTextEvent *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
int Result = This->GetLine();
rt.addInt(Result);
- break;
+ break;
}
-case wxStyledTextEvent_GetFoldLevelNow: { // wxStyledTextEvent::GetFoldLevelNow
+case wxStyledTextEvent_GetFoldLevelNow: { // wxStyledTextEvent::GetFoldLevelNow
wxStyledTextEvent *This = (wxStyledTextEvent *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
int Result = This->GetFoldLevelNow();
rt.addInt(Result);
- break;
+ break;
}
-case wxStyledTextEvent_GetFoldLevelPrev: { // wxStyledTextEvent::GetFoldLevelPrev
+case wxStyledTextEvent_GetFoldLevelPrev: { // wxStyledTextEvent::GetFoldLevelPrev
wxStyledTextEvent *This = (wxStyledTextEvent *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
int Result = This->GetFoldLevelPrev();
rt.addInt(Result);
- break;
+ break;
}
-case wxStyledTextEvent_GetMargin: { // wxStyledTextEvent::GetMargin
+case wxStyledTextEvent_GetMargin: { // wxStyledTextEvent::GetMargin
wxStyledTextEvent *This = (wxStyledTextEvent *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
int Result = This->GetMargin();
rt.addInt(Result);
- break;
+ break;
}
-case wxStyledTextEvent_GetMessage: { // wxStyledTextEvent::GetMessage
+case wxStyledTextEvent_GetMessage: { // wxStyledTextEvent::GetMessage
wxStyledTextEvent *This = (wxStyledTextEvent *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
int Result = This->GetMessage();
rt.addInt(Result);
- break;
+ break;
}
-case wxStyledTextEvent_GetWParam: { // wxStyledTextEvent::GetWParam
+case wxStyledTextEvent_GetWParam: { // wxStyledTextEvent::GetWParam
wxStyledTextEvent *This = (wxStyledTextEvent *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
int Result = This->GetWParam();
rt.addInt(Result);
- break;
+ break;
}
-case wxStyledTextEvent_GetLParam: { // wxStyledTextEvent::GetLParam
+case wxStyledTextEvent_GetLParam: { // wxStyledTextEvent::GetLParam
wxStyledTextEvent *This = (wxStyledTextEvent *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
int Result = This->GetLParam();
rt.addInt(Result);
- break;
+ break;
}
-case wxStyledTextEvent_GetListType: { // wxStyledTextEvent::GetListType
+case wxStyledTextEvent_GetListType: { // wxStyledTextEvent::GetListType
wxStyledTextEvent *This = (wxStyledTextEvent *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
int Result = This->GetListType();
rt.addInt(Result);
- break;
+ break;
}
-case wxStyledTextEvent_GetX: { // wxStyledTextEvent::GetX
+case wxStyledTextEvent_GetX: { // wxStyledTextEvent::GetX
wxStyledTextEvent *This = (wxStyledTextEvent *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
int Result = This->GetX();
rt.addInt(Result);
- break;
+ break;
}
-case wxStyledTextEvent_GetY: { // wxStyledTextEvent::GetY
+case wxStyledTextEvent_GetY: { // wxStyledTextEvent::GetY
wxStyledTextEvent *This = (wxStyledTextEvent *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
int Result = This->GetY();
rt.addInt(Result);
- break;
+ break;
}
-case wxStyledTextEvent_GetDragText: { // wxStyledTextEvent::GetDragText
+case wxStyledTextEvent_GetDragText: { // wxStyledTextEvent::GetDragText
wxStyledTextEvent *This = (wxStyledTextEvent *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
wxString Result = This->GetDragText();
rt.add(Result);
- break;
+ break;
}
-case wxStyledTextEvent_GetDragAllowMove: { // wxStyledTextEvent::GetDragAllowMove
+case wxStyledTextEvent_GetDragAllowMove: { // wxStyledTextEvent::GetDragAllowMove
wxStyledTextEvent *This = (wxStyledTextEvent *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
bool Result = This->GetDragAllowMove();
rt.addBool(Result);
- break;
+ break;
}
-case wxStyledTextEvent_GetDragResult: { // wxStyledTextEvent::GetDragResult
+case wxStyledTextEvent_GetDragResult: { // wxStyledTextEvent::GetDragResult
wxStyledTextEvent *This = (wxStyledTextEvent *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
int Result = This->GetDragResult();
rt.addInt(Result);
- break;
+ break;
}
-case wxStyledTextEvent_GetShift: { // wxStyledTextEvent::GetShift
+case wxStyledTextEvent_GetShift: { // wxStyledTextEvent::GetShift
wxStyledTextEvent *This = (wxStyledTextEvent *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
bool Result = This->GetShift();
rt.addBool(Result);
- break;
+ break;
}
-case wxStyledTextEvent_GetControl: { // wxStyledTextEvent::GetControl
+case wxStyledTextEvent_GetControl: { // wxStyledTextEvent::GetControl
wxStyledTextEvent *This = (wxStyledTextEvent *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
bool Result = This->GetControl();
rt.addBool(Result);
- break;
+ break;
}
-case wxStyledTextEvent_GetAlt: { // wxStyledTextEvent::GetAlt
+case wxStyledTextEvent_GetAlt: { // wxStyledTextEvent::GetAlt
wxStyledTextEvent *This = (wxStyledTextEvent *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
bool Result = This->GetAlt();
rt.addBool(Result);
- break;
+ break;
}
-case utils_wxGetKeyState: { // utils::wxGetKeyState
+case utils_wxGetKeyState: { // utils::wxGetKeyState
wxKeyCode key = *(wxKeyCode *) bp; bp += 4;;
bool Result = ::wxGetKeyState((wxKeyCode) key);
rt.addBool(Result);
- break;
+ break;
}
-case utils_wxGetMousePosition: { // utils::wxGetMousePosition
+case utils_wxGetMousePosition: { // utils::wxGetMousePosition
int x;
int y;
::wxGetMousePosition(&x,&y);
rt.addInt(x);
rt.addInt(y);
rt.addTupleCount(2);
- break;
+ break;
}
-case utils_wxGetMouseState: { // utils::wxGetMouseState
+case utils_wxGetMouseState: { // utils::wxGetMouseState
wxMouseState Result = ::wxGetMouseState();
rt.add(Result);
- break;
+ break;
}
-case utils_wxSetDetectableAutoRepeat: { // utils::wxSetDetectableAutoRepeat
+case utils_wxSetDetectableAutoRepeat: { // utils::wxSetDetectableAutoRepeat
bool * flag = (bool *) bp; bp += 4;
bool Result = ::wxSetDetectableAutoRepeat((bool) *flag);
rt.addBool(Result);
- break;
+ break;
}
-case utils_wxBell: { // utils::wxBell
+case utils_wxBell: { // utils::wxBell
::wxBell();
- break;
+ break;
}
-case utils_wxFindMenuItemId: { // utils::wxFindMenuItemId
+case utils_wxFindMenuItemId: { // utils::wxFindMenuItemId
wxFrame *frame = (wxFrame *) getPtr(bp,memenv); bp += 4;
int * menuStringLen = (int *) bp; bp += 4;
wxString menuString = wxString(bp, wxConvUTF8);
@@ -26393,120 +26435,120 @@ case utils_wxFindMenuItemId: { // utils::wxFindMenuItemId
bp += *itemStringLen+((8-((4+ *itemStringLen) & 7)) & 7);
int Result = ::wxFindMenuItemId(frame,menuString,itemString);
rt.addInt(Result);
- break;
+ break;
}
-case utils_wxGenericFindWindowAtPoint: { // utils::wxGenericFindWindowAtPoint
+case utils_wxGenericFindWindowAtPoint: { // utils::wxGenericFindWindowAtPoint
int * ptX = (int *) bp; bp += 4;
int * ptY = (int *) bp; bp += 4;
wxPoint pt = wxPoint(*ptX,*ptY);
wxWindow * Result = (wxWindow*)::wxGenericFindWindowAtPoint(pt);
rt.addRef(getRef((void *)Result,memenv), "wxWindow");
- break;
+ break;
}
-case utils_wxFindWindowAtPoint: { // utils::wxFindWindowAtPoint
+case utils_wxFindWindowAtPoint: { // utils::wxFindWindowAtPoint
int * ptX = (int *) bp; bp += 4;
int * ptY = (int *) bp; bp += 4;
wxPoint pt = wxPoint(*ptX,*ptY);
wxWindow * Result = (wxWindow*)::wxFindWindowAtPoint(pt);
rt.addRef(getRef((void *)Result,memenv), "wxWindow");
- break;
+ break;
}
-case utils_wxBeginBusyCursor: { // utils::wxBeginBusyCursor
+case utils_wxBeginBusyCursor: { // utils::wxBeginBusyCursor
const wxCursor * cursor=wxHOURGLASS_CURSOR;
- while( * (int*) bp) { switch (* (int*) bp) {
+ while( * (int*) bp) { switch (* (int*) bp) {
case 1: {bp += 4;
cursor = (wxCursor *) getPtr(bp,memenv); bp += 4;
} break;
- }};
+ }};
::wxBeginBusyCursor(cursor);
- break;
+ break;
}
-case utils_wxEndBusyCursor: { // utils::wxEndBusyCursor
+case utils_wxEndBusyCursor: { // utils::wxEndBusyCursor
::wxEndBusyCursor();
- break;
+ break;
}
-case utils_wxIsBusy: { // utils::wxIsBusy
+case utils_wxIsBusy: { // utils::wxIsBusy
bool Result = ::wxIsBusy();
rt.addBool(Result);
- break;
+ break;
}
-case utils_wxShutdown: { // utils::wxShutdown
+case utils_wxShutdown: { // utils::wxShutdown
wxShutdownFlags wFlags = *(wxShutdownFlags *) bp; bp += 4;;
bool Result = ::wxShutdown((wxShutdownFlags) wFlags);
rt.addBool(Result);
- break;
+ break;
}
-case utils_wxShell: { // utils::wxShell
+case utils_wxShell: { // utils::wxShell
wxString command= wxEmptyString;
- while( * (int*) bp) { switch (* (int*) bp) {
+ while( * (int*) bp) { switch (* (int*) bp) {
case 1: {bp += 4;
int * commandLen = (int *) bp; bp += 4;
command = wxString(bp, wxConvUTF8);
bp += *commandLen+((8-((0+ *commandLen) & 7)) & 7);
} break;
- }};
+ }};
bool Result = ::wxShell(command);
rt.addBool(Result);
- break;
+ break;
}
-case utils_wxLaunchDefaultBrowser: { // utils::wxLaunchDefaultBrowser
+case utils_wxLaunchDefaultBrowser: { // utils::wxLaunchDefaultBrowser
int flags=0;
int * urlLen = (int *) bp; bp += 4;
wxString url = wxString(bp, wxConvUTF8);
bp += *urlLen+((8-((4+ *urlLen) & 7)) & 7);
- while( * (int*) bp) { switch (* (int*) bp) {
+ while( * (int*) bp) { switch (* (int*) bp) {
case 1: {bp += 4;
flags = (int)*(int *) bp; bp += 4;
} break;
- }};
+ }};
bool Result = ::wxLaunchDefaultBrowser(url,flags);
rt.addBool(Result);
- break;
+ break;
}
-case utils_wxGetEmailAddress: { // utils::wxGetEmailAddress
+case utils_wxGetEmailAddress: { // utils::wxGetEmailAddress
wxString Result = ::wxGetEmailAddress();
rt.add(Result);
- break;
+ break;
}
-case utils_wxGetUserId: { // utils::wxGetUserId
+case utils_wxGetUserId: { // utils::wxGetUserId
wxString Result = ::wxGetUserId();
rt.add(Result);
- break;
+ break;
}
-case utils_wxGetHomeDir: { // utils::wxGetHomeDir
+case utils_wxGetHomeDir: { // utils::wxGetHomeDir
wxString Result = ::wxGetHomeDir();
rt.add(Result);
- break;
+ break;
}
-case utils_wxNewId: { // utils::wxNewId
+case utils_wxNewId: { // utils::wxNewId
long Result = ::wxNewId();
rt.addInt(Result);
- break;
+ break;
}
-case utils_wxRegisterId: { // utils::wxRegisterId
+case utils_wxRegisterId: { // utils::wxRegisterId
int * id = (int *) bp; bp += 4;
::wxRegisterId((long) *id);
- break;
+ break;
}
-case utils_wxGetCurrentId: { // utils::wxGetCurrentId
+case utils_wxGetCurrentId: { // utils::wxGetCurrentId
long Result = ::wxGetCurrentId();
rt.addInt(Result);
- break;
+ break;
}
-case utils_wxGetOsDescription: { // utils::wxGetOsDescription
+case utils_wxGetOsDescription: { // utils::wxGetOsDescription
wxString Result = ::wxGetOsDescription();
rt.add(Result);
- break;
+ break;
}
-case utils_wxIsPlatformLittleEndian: { // utils::wxIsPlatformLittleEndian
+case utils_wxIsPlatformLittleEndian: { // utils::wxIsPlatformLittleEndian
bool Result = ::wxIsPlatformLittleEndian();
rt.addBool(Result);
- break;
+ break;
}
-case utils_wxIsPlatform64Bit: { // utils::wxIsPlatform64Bit
+case utils_wxIsPlatform64Bit: { // utils::wxIsPlatform64Bit
bool Result = ::wxIsPlatform64Bit();
rt.addBool(Result);
- break;
+ break;
}
case wxPrintout_new: { // wxPrintout::wxPrintout taylormade
@@ -26536,14 +26578,14 @@ case wxPrintout_new: { // wxPrintout::wxPrintout taylormade
rt.addRef(getRef((void *)Result,memenv), "wxPrintout");
break;
}
-case wxPrintout_GetDC: { // wxPrintout::GetDC
+case wxPrintout_GetDC: { // wxPrintout::GetDC
wxPrintout *This = (wxPrintout *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
wxDC * Result = (wxDC*)This->GetDC();
rt.addRef(getRef((void *)Result,memenv), "wxDC");
- break;
+ break;
}
-case wxPrintout_GetPageSizeMM: { // wxPrintout::GetPageSizeMM
+case wxPrintout_GetPageSizeMM: { // wxPrintout::GetPageSizeMM
int w;
int h;
wxPrintout *This = (wxPrintout *) getPtr(bp,memenv); bp += 4;
@@ -26552,9 +26594,9 @@ case wxPrintout_GetPageSizeMM: { // wxPrintout::GetPageSizeMM
rt.addInt(w);
rt.addInt(h);
rt.addTupleCount(2);
- break;
+ break;
}
-case wxPrintout_GetPageSizePixels: { // wxPrintout::GetPageSizePixels
+case wxPrintout_GetPageSizePixels: { // wxPrintout::GetPageSizePixels
int w;
int h;
wxPrintout *This = (wxPrintout *) getPtr(bp,memenv); bp += 4;
@@ -26563,16 +26605,16 @@ case wxPrintout_GetPageSizePixels: { // wxPrintout::GetPageSizePixels
rt.addInt(w);
rt.addInt(h);
rt.addTupleCount(2);
- break;
+ break;
}
-case wxPrintout_GetPaperRectPixels: { // wxPrintout::GetPaperRectPixels
+case wxPrintout_GetPaperRectPixels: { // wxPrintout::GetPaperRectPixels
wxPrintout *This = (wxPrintout *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
wxRect Result = This->GetPaperRectPixels();
rt.add(Result);
- break;
+ break;
}
-case wxPrintout_GetPPIPrinter: { // wxPrintout::GetPPIPrinter
+case wxPrintout_GetPPIPrinter: { // wxPrintout::GetPPIPrinter
int x;
int y;
wxPrintout *This = (wxPrintout *) getPtr(bp,memenv); bp += 4;
@@ -26581,9 +26623,9 @@ case wxPrintout_GetPPIPrinter: { // wxPrintout::GetPPIPrinter
rt.addInt(x);
rt.addInt(y);
rt.addTupleCount(2);
- break;
+ break;
}
-case wxPrintout_GetPPIScreen: { // wxPrintout::GetPPIScreen
+case wxPrintout_GetPPIScreen: { // wxPrintout::GetPPIScreen
int x;
int y;
wxPrintout *This = (wxPrintout *) getPtr(bp,memenv); bp += 4;
@@ -26592,41 +26634,41 @@ case wxPrintout_GetPPIScreen: { // wxPrintout::GetPPIScreen
rt.addInt(x);
rt.addInt(y);
rt.addTupleCount(2);
- break;
+ break;
}
-case wxPrintout_GetTitle: { // wxPrintout::GetTitle
+case wxPrintout_GetTitle: { // wxPrintout::GetTitle
wxPrintout *This = (wxPrintout *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
wxString Result = This->GetTitle();
rt.add(Result);
- break;
+ break;
}
-case wxPrintout_IsPreview: { // wxPrintout::IsPreview
+case wxPrintout_IsPreview: { // wxPrintout::IsPreview
wxPrintout *This = (wxPrintout *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
bool Result = This->IsPreview();
rt.addBool(Result);
- break;
+ break;
}
-case wxPrintout_FitThisSizeToPaper: { // wxPrintout::FitThisSizeToPaper
+case wxPrintout_FitThisSizeToPaper: { // wxPrintout::FitThisSizeToPaper
wxPrintout *This = (wxPrintout *) getPtr(bp,memenv); bp += 4;
int * imageSizeW = (int *) bp; bp += 4;
int * imageSizeH = (int *) bp; bp += 4;
wxSize imageSize = wxSize(*imageSizeW,*imageSizeH);
if(!This) throw wxe_badarg(0);
This->FitThisSizeToPaper(imageSize);
- break;
+ break;
}
-case wxPrintout_FitThisSizeToPage: { // wxPrintout::FitThisSizeToPage
+case wxPrintout_FitThisSizeToPage: { // wxPrintout::FitThisSizeToPage
wxPrintout *This = (wxPrintout *) getPtr(bp,memenv); bp += 4;
int * imageSizeW = (int *) bp; bp += 4;
int * imageSizeH = (int *) bp; bp += 4;
wxSize imageSize = wxSize(*imageSizeW,*imageSizeH);
if(!This) throw wxe_badarg(0);
This->FitThisSizeToPage(imageSize);
- break;
+ break;
}
-case wxPrintout_FitThisSizeToPageMargins: { // wxPrintout::FitThisSizeToPageMargins
+case wxPrintout_FitThisSizeToPageMargins: { // wxPrintout::FitThisSizeToPageMargins
wxPrintout *This = (wxPrintout *) getPtr(bp,memenv); bp += 4;
int * imageSizeW = (int *) bp; bp += 4;
int * imageSizeH = (int *) bp; bp += 4;
@@ -26634,79 +26676,79 @@ case wxPrintout_FitThisSizeToPageMargins: { // wxPrintout::FitThisSizeToPageMarg
wxPageSetupDialogData *pageSetupData = (wxPageSetupDialogData *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
This->FitThisSizeToPageMargins(imageSize,*pageSetupData);
- break;
+ break;
}
-case wxPrintout_MapScreenSizeToPaper: { // wxPrintout::MapScreenSizeToPaper
+case wxPrintout_MapScreenSizeToPaper: { // wxPrintout::MapScreenSizeToPaper
wxPrintout *This = (wxPrintout *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
This->MapScreenSizeToPaper();
- break;
+ break;
}
-case wxPrintout_MapScreenSizeToPage: { // wxPrintout::MapScreenSizeToPage
+case wxPrintout_MapScreenSizeToPage: { // wxPrintout::MapScreenSizeToPage
wxPrintout *This = (wxPrintout *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
This->MapScreenSizeToPage();
- break;
+ break;
}
-case wxPrintout_MapScreenSizeToPageMargins: { // wxPrintout::MapScreenSizeToPageMargins
+case wxPrintout_MapScreenSizeToPageMargins: { // wxPrintout::MapScreenSizeToPageMargins
wxPrintout *This = (wxPrintout *) getPtr(bp,memenv); bp += 4;
wxPageSetupDialogData *pageSetupData = (wxPageSetupDialogData *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
This->MapScreenSizeToPageMargins(*pageSetupData);
- break;
+ break;
}
-case wxPrintout_MapScreenSizeToDevice: { // wxPrintout::MapScreenSizeToDevice
+case wxPrintout_MapScreenSizeToDevice: { // wxPrintout::MapScreenSizeToDevice
wxPrintout *This = (wxPrintout *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
This->MapScreenSizeToDevice();
- break;
+ break;
}
-case wxPrintout_GetLogicalPaperRect: { // wxPrintout::GetLogicalPaperRect
+case wxPrintout_GetLogicalPaperRect: { // wxPrintout::GetLogicalPaperRect
wxPrintout *This = (wxPrintout *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
wxRect Result = This->GetLogicalPaperRect();
rt.add(Result);
- break;
+ break;
}
-case wxPrintout_GetLogicalPageRect: { // wxPrintout::GetLogicalPageRect
+case wxPrintout_GetLogicalPageRect: { // wxPrintout::GetLogicalPageRect
wxPrintout *This = (wxPrintout *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
wxRect Result = This->GetLogicalPageRect();
rt.add(Result);
- break;
+ break;
}
-case wxPrintout_GetLogicalPageMarginsRect: { // wxPrintout::GetLogicalPageMarginsRect
+case wxPrintout_GetLogicalPageMarginsRect: { // wxPrintout::GetLogicalPageMarginsRect
wxPrintout *This = (wxPrintout *) getPtr(bp,memenv); bp += 4;
wxPageSetupDialogData *pageSetupData = (wxPageSetupDialogData *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
wxRect Result = This->GetLogicalPageMarginsRect(*pageSetupData);
rt.add(Result);
- break;
+ break;
}
-case wxPrintout_SetLogicalOrigin: { // wxPrintout::SetLogicalOrigin
+case wxPrintout_SetLogicalOrigin: { // wxPrintout::SetLogicalOrigin
wxPrintout *This = (wxPrintout *) getPtr(bp,memenv); bp += 4;
int * x = (int *) bp; bp += 4;
int * y = (int *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
This->SetLogicalOrigin((wxCoord) *x,(wxCoord) *y);
- break;
+ break;
}
-case wxPrintout_OffsetLogicalOrigin: { // wxPrintout::OffsetLogicalOrigin
+case wxPrintout_OffsetLogicalOrigin: { // wxPrintout::OffsetLogicalOrigin
wxPrintout *This = (wxPrintout *) getPtr(bp,memenv); bp += 4;
int * xoff = (int *) bp; bp += 4;
int * yoff = (int *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
This->OffsetLogicalOrigin((wxCoord) *xoff,(wxCoord) *yoff);
- break;
+ break;
}
-case wxStyledTextCtrl_new_2: { // wxStyledTextCtrl::wxStyledTextCtrl
+case wxStyledTextCtrl_new_2: { // wxStyledTextCtrl::wxStyledTextCtrl
wxWindowID id=wxID_ANY;
wxPoint pos= wxDefaultPosition;
wxSize size= wxDefaultSize;
long style=0;
wxWindow *parent = (wxWindow *) getPtr(bp,memenv); bp += 4;
bp += 4; /* Align */
- while( * (int*) bp) { switch (* (int*) bp) {
+ while( * (int*) bp) { switch (* (int*) bp) {
case 1: {bp += 4;
id = (wxWindowID)*(int *) bp; bp += 4;
} break;
@@ -26725,26 +26767,26 @@ case wxStyledTextCtrl_new_2: { // wxStyledTextCtrl::wxStyledTextCtrl
case 4: {bp += 4;
style = (long)*(int *) bp; bp += 4;
} break;
- }};
+ }};
wxStyledTextCtrl * Result = new wxStyledTextCtrl(parent,id,pos,size,style);
/* Possible memory leak here, class is missing virt dest */
rt.addRef(getRef((void *)Result,memenv), "wxStyledTextCtrl");
- break;
+ break;
}
-case wxStyledTextCtrl_new_0: { // wxStyledTextCtrl::wxStyledTextCtrl
+case wxStyledTextCtrl_new_0: { // wxStyledTextCtrl::wxStyledTextCtrl
wxStyledTextCtrl * Result = new wxStyledTextCtrl();
/* Possible memory leak here, class is missing virt dest */
rt.addRef(getRef((void *)Result,memenv), "wxStyledTextCtrl");
- break;
+ break;
}
-case wxStyledTextCtrl_Create: { // wxStyledTextCtrl::Create
+case wxStyledTextCtrl_Create: { // wxStyledTextCtrl::Create
wxWindowID id=wxID_ANY;
wxPoint pos= wxDefaultPosition;
wxSize size= wxDefaultSize;
long style=0;
wxStyledTextCtrl *This = (wxStyledTextCtrl *) getPtr(bp,memenv); bp += 4;
wxWindow *parent = (wxWindow *) getPtr(bp,memenv); bp += 4;
- while( * (int*) bp) { switch (* (int*) bp) {
+ while( * (int*) bp) { switch (* (int*) bp) {
case 1: {bp += 4;
id = (wxWindowID)*(int *) bp; bp += 4;
} break;
@@ -26763,29 +26805,29 @@ case wxStyledTextCtrl_Create: { // wxStyledTextCtrl::Create
case 4: {bp += 4;
style = (long)*(int *) bp; bp += 4;
} break;
- }};
+ }};
if(!This) throw wxe_badarg(0);
bool Result = This->Create(parent,id,pos,size,style);
rt.addBool(Result);
- break;
+ break;
}
-case wxStyledTextCtrl_AddText: { // wxStyledTextCtrl::AddText
+case wxStyledTextCtrl_AddText: { // wxStyledTextCtrl::AddText
wxStyledTextCtrl *This = (wxStyledTextCtrl *) getPtr(bp,memenv); bp += 4;
int * textLen = (int *) bp; bp += 4;
wxString text = wxString(bp, wxConvUTF8);
bp += *textLen+((8-((0+ *textLen) & 7)) & 7);
if(!This) throw wxe_badarg(0);
This->AddText(text);
- break;
+ break;
}
-case wxStyledTextCtrl_AddStyledText: { // wxStyledTextCtrl::AddStyledText
+case wxStyledTextCtrl_AddStyledText: { // wxStyledTextCtrl::AddStyledText
wxStyledTextCtrl *This = (wxStyledTextCtrl *) getPtr(bp,memenv); bp += 4;
wxMemoryBuffer *data = (wxMemoryBuffer *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
This->AddStyledText(*data);
- break;
+ break;
}
-case wxStyledTextCtrl_InsertText: { // wxStyledTextCtrl::InsertText
+case wxStyledTextCtrl_InsertText: { // wxStyledTextCtrl::InsertText
wxStyledTextCtrl *This = (wxStyledTextCtrl *) getPtr(bp,memenv); bp += 4;
int * pos = (int *) bp; bp += 4;
int * textLen = (int *) bp; bp += 4;
@@ -26793,135 +26835,135 @@ case wxStyledTextCtrl_InsertText: { // wxStyledTextCtrl::InsertText
bp += *textLen+((8-((4+ *textLen) & 7)) & 7);
if(!This) throw wxe_badarg(0);
This->InsertText((int) *pos,text);
- break;
+ break;
}
-case wxStyledTextCtrl_ClearAll: { // wxStyledTextCtrl::ClearAll
+case wxStyledTextCtrl_ClearAll: { // wxStyledTextCtrl::ClearAll
wxStyledTextCtrl *This = (wxStyledTextCtrl *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
This->ClearAll();
- break;
+ break;
}
-case wxStyledTextCtrl_ClearDocumentStyle: { // wxStyledTextCtrl::ClearDocumentStyle
+case wxStyledTextCtrl_ClearDocumentStyle: { // wxStyledTextCtrl::ClearDocumentStyle
wxStyledTextCtrl *This = (wxStyledTextCtrl *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
This->ClearDocumentStyle();
- break;
+ break;
}
-case wxStyledTextCtrl_GetLength: { // wxStyledTextCtrl::GetLength
+case wxStyledTextCtrl_GetLength: { // wxStyledTextCtrl::GetLength
wxStyledTextCtrl *This = (wxStyledTextCtrl *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
int Result = This->GetLength();
rt.addInt(Result);
- break;
+ break;
}
-case wxStyledTextCtrl_GetCharAt: { // wxStyledTextCtrl::GetCharAt
+case wxStyledTextCtrl_GetCharAt: { // wxStyledTextCtrl::GetCharAt
wxStyledTextCtrl *This = (wxStyledTextCtrl *) getPtr(bp,memenv); bp += 4;
int * pos = (int *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
int Result = This->GetCharAt((int) *pos);
rt.addInt(Result);
- break;
+ break;
}
-case wxStyledTextCtrl_GetCurrentPos: { // wxStyledTextCtrl::GetCurrentPos
+case wxStyledTextCtrl_GetCurrentPos: { // wxStyledTextCtrl::GetCurrentPos
wxStyledTextCtrl *This = (wxStyledTextCtrl *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
int Result = This->GetCurrentPos();
rt.addInt(Result);
- break;
+ break;
}
-case wxStyledTextCtrl_GetAnchor: { // wxStyledTextCtrl::GetAnchor
+case wxStyledTextCtrl_GetAnchor: { // wxStyledTextCtrl::GetAnchor
wxStyledTextCtrl *This = (wxStyledTextCtrl *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
int Result = This->GetAnchor();
rt.addInt(Result);
- break;
+ break;
}
-case wxStyledTextCtrl_GetStyleAt: { // wxStyledTextCtrl::GetStyleAt
+case wxStyledTextCtrl_GetStyleAt: { // wxStyledTextCtrl::GetStyleAt
wxStyledTextCtrl *This = (wxStyledTextCtrl *) getPtr(bp,memenv); bp += 4;
int * pos = (int *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
int Result = This->GetStyleAt((int) *pos);
rt.addInt(Result);
- break;
+ break;
}
-case wxStyledTextCtrl_Redo: { // wxStyledTextCtrl::Redo
+case wxStyledTextCtrl_Redo: { // wxStyledTextCtrl::Redo
wxStyledTextCtrl *This = (wxStyledTextCtrl *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
This->Redo();
- break;
+ break;
}
-case wxStyledTextCtrl_SetUndoCollection: { // wxStyledTextCtrl::SetUndoCollection
+case wxStyledTextCtrl_SetUndoCollection: { // wxStyledTextCtrl::SetUndoCollection
wxStyledTextCtrl *This = (wxStyledTextCtrl *) getPtr(bp,memenv); bp += 4;
bool * collectUndo = (bool *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
This->SetUndoCollection((bool) *collectUndo);
- break;
+ break;
}
-case wxStyledTextCtrl_SelectAll: { // wxStyledTextCtrl::SelectAll
+case wxStyledTextCtrl_SelectAll: { // wxStyledTextCtrl::SelectAll
wxStyledTextCtrl *This = (wxStyledTextCtrl *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
This->SelectAll();
- break;
+ break;
}
-case wxStyledTextCtrl_SetSavePoint: { // wxStyledTextCtrl::SetSavePoint
+case wxStyledTextCtrl_SetSavePoint: { // wxStyledTextCtrl::SetSavePoint
wxStyledTextCtrl *This = (wxStyledTextCtrl *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
This->SetSavePoint();
- break;
+ break;
}
-case wxStyledTextCtrl_GetStyledText: { // wxStyledTextCtrl::GetStyledText
+case wxStyledTextCtrl_GetStyledText: { // wxStyledTextCtrl::GetStyledText
wxStyledTextCtrl *This = (wxStyledTextCtrl *) getPtr(bp,memenv); bp += 4;
int * startPos = (int *) bp; bp += 4;
int * endPos = (int *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
wxMemoryBuffer * Result = new wxMemoryBuffer(This->GetStyledText((int) *startPos,(int) *endPos)); newPtr((void *) Result,3, memenv);;
rt.addRef(getRef((void *)Result,memenv), "wxMemoryBuffer");
- break;
+ break;
}
-case wxStyledTextCtrl_CanRedo: { // wxStyledTextCtrl::CanRedo
+case wxStyledTextCtrl_CanRedo: { // wxStyledTextCtrl::CanRedo
wxStyledTextCtrl *This = (wxStyledTextCtrl *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
bool Result = This->CanRedo();
rt.addBool(Result);
- break;
+ break;
}
-case wxStyledTextCtrl_MarkerLineFromHandle: { // wxStyledTextCtrl::MarkerLineFromHandle
+case wxStyledTextCtrl_MarkerLineFromHandle: { // wxStyledTextCtrl::MarkerLineFromHandle
wxStyledTextCtrl *This = (wxStyledTextCtrl *) getPtr(bp,memenv); bp += 4;
int * handle = (int *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
int Result = This->MarkerLineFromHandle((int) *handle);
rt.addInt(Result);
- break;
+ break;
}
-case wxStyledTextCtrl_MarkerDeleteHandle: { // wxStyledTextCtrl::MarkerDeleteHandle
+case wxStyledTextCtrl_MarkerDeleteHandle: { // wxStyledTextCtrl::MarkerDeleteHandle
wxStyledTextCtrl *This = (wxStyledTextCtrl *) getPtr(bp,memenv); bp += 4;
int * handle = (int *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
This->MarkerDeleteHandle((int) *handle);
- break;
+ break;
}
-case wxStyledTextCtrl_GetUndoCollection: { // wxStyledTextCtrl::GetUndoCollection
+case wxStyledTextCtrl_GetUndoCollection: { // wxStyledTextCtrl::GetUndoCollection
wxStyledTextCtrl *This = (wxStyledTextCtrl *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
bool Result = This->GetUndoCollection();
rt.addBool(Result);
- break;
+ break;
}
-case wxStyledTextCtrl_GetViewWhiteSpace: { // wxStyledTextCtrl::GetViewWhiteSpace
+case wxStyledTextCtrl_GetViewWhiteSpace: { // wxStyledTextCtrl::GetViewWhiteSpace
wxStyledTextCtrl *This = (wxStyledTextCtrl *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
int Result = This->GetViewWhiteSpace();
rt.addInt(Result);
- break;
+ break;
}
-case wxStyledTextCtrl_SetViewWhiteSpace: { // wxStyledTextCtrl::SetViewWhiteSpace
+case wxStyledTextCtrl_SetViewWhiteSpace: { // wxStyledTextCtrl::SetViewWhiteSpace
wxStyledTextCtrl *This = (wxStyledTextCtrl *) getPtr(bp,memenv); bp += 4;
int * viewWS = (int *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
This->SetViewWhiteSpace((int) *viewWS);
- break;
+ break;
}
-case wxStyledTextCtrl_PositionFromPoint: { // wxStyledTextCtrl::PositionFromPoint
+case wxStyledTextCtrl_PositionFromPoint: { // wxStyledTextCtrl::PositionFromPoint
wxStyledTextCtrl *This = (wxStyledTextCtrl *) getPtr(bp,memenv); bp += 4;
int * ptX = (int *) bp; bp += 4;
int * ptY = (int *) bp; bp += 4;
@@ -26929,39 +26971,39 @@ case wxStyledTextCtrl_PositionFromPoint: { // wxStyledTextCtrl::PositionFromPoin
if(!This) throw wxe_badarg(0);
int Result = This->PositionFromPoint(pt);
rt.addInt(Result);
- break;
+ break;
}
-case wxStyledTextCtrl_PositionFromPointClose: { // wxStyledTextCtrl::PositionFromPointClose
+case wxStyledTextCtrl_PositionFromPointClose: { // wxStyledTextCtrl::PositionFromPointClose
wxStyledTextCtrl *This = (wxStyledTextCtrl *) getPtr(bp,memenv); bp += 4;
int * x = (int *) bp; bp += 4;
int * y = (int *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
int Result = This->PositionFromPointClose((int) *x,(int) *y);
rt.addInt(Result);
- break;
+ break;
}
-case wxStyledTextCtrl_GotoLine: { // wxStyledTextCtrl::GotoLine
+case wxStyledTextCtrl_GotoLine: { // wxStyledTextCtrl::GotoLine
wxStyledTextCtrl *This = (wxStyledTextCtrl *) getPtr(bp,memenv); bp += 4;
int * line = (int *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
This->GotoLine((int) *line);
- break;
+ break;
}
-case wxStyledTextCtrl_GotoPos: { // wxStyledTextCtrl::GotoPos
+case wxStyledTextCtrl_GotoPos: { // wxStyledTextCtrl::GotoPos
wxStyledTextCtrl *This = (wxStyledTextCtrl *) getPtr(bp,memenv); bp += 4;
int * pos = (int *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
This->GotoPos((int) *pos);
- break;
+ break;
}
-case wxStyledTextCtrl_SetAnchor: { // wxStyledTextCtrl::SetAnchor
+case wxStyledTextCtrl_SetAnchor: { // wxStyledTextCtrl::SetAnchor
wxStyledTextCtrl *This = (wxStyledTextCtrl *) getPtr(bp,memenv); bp += 4;
int * posAnchor = (int *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
This->SetAnchor((int) *posAnchor);
- break;
+ break;
}
-case wxStyledTextCtrl_GetCurLine: { // wxStyledTextCtrl::GetCurLine
+case wxStyledTextCtrl_GetCurLine: { // wxStyledTextCtrl::GetCurLine
int linePos;
wxStyledTextCtrl *This = (wxStyledTextCtrl *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
@@ -26969,95 +27011,95 @@ case wxStyledTextCtrl_GetCurLine: { // wxStyledTextCtrl::GetCurLine
rt.add(Result);
rt.addInt(linePos);
rt.addTupleCount(2);
- break;
+ break;
}
-case wxStyledTextCtrl_GetEndStyled: { // wxStyledTextCtrl::GetEndStyled
+case wxStyledTextCtrl_GetEndStyled: { // wxStyledTextCtrl::GetEndStyled
wxStyledTextCtrl *This = (wxStyledTextCtrl *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
int Result = This->GetEndStyled();
rt.addInt(Result);
- break;
+ break;
}
-case wxStyledTextCtrl_ConvertEOLs: { // wxStyledTextCtrl::ConvertEOLs
+case wxStyledTextCtrl_ConvertEOLs: { // wxStyledTextCtrl::ConvertEOLs
wxStyledTextCtrl *This = (wxStyledTextCtrl *) getPtr(bp,memenv); bp += 4;
int * eolMode = (int *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
This->ConvertEOLs((int) *eolMode);
- break;
+ break;
}
-case wxStyledTextCtrl_GetEOLMode: { // wxStyledTextCtrl::GetEOLMode
+case wxStyledTextCtrl_GetEOLMode: { // wxStyledTextCtrl::GetEOLMode
wxStyledTextCtrl *This = (wxStyledTextCtrl *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
int Result = This->GetEOLMode();
rt.addInt(Result);
- break;
+ break;
}
-case wxStyledTextCtrl_SetEOLMode: { // wxStyledTextCtrl::SetEOLMode
+case wxStyledTextCtrl_SetEOLMode: { // wxStyledTextCtrl::SetEOLMode
wxStyledTextCtrl *This = (wxStyledTextCtrl *) getPtr(bp,memenv); bp += 4;
int * eolMode = (int *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
This->SetEOLMode((int) *eolMode);
- break;
+ break;
}
-case wxStyledTextCtrl_StartStyling: { // wxStyledTextCtrl::StartStyling
+case wxStyledTextCtrl_StartStyling: { // wxStyledTextCtrl::StartStyling
wxStyledTextCtrl *This = (wxStyledTextCtrl *) getPtr(bp,memenv); bp += 4;
int * pos = (int *) bp; bp += 4;
int * mask = (int *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
This->StartStyling((int) *pos,(int) *mask);
- break;
+ break;
}
-case wxStyledTextCtrl_SetStyling: { // wxStyledTextCtrl::SetStyling
+case wxStyledTextCtrl_SetStyling: { // wxStyledTextCtrl::SetStyling
wxStyledTextCtrl *This = (wxStyledTextCtrl *) getPtr(bp,memenv); bp += 4;
int * length = (int *) bp; bp += 4;
int * style = (int *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
This->SetStyling((int) *length,(int) *style);
- break;
+ break;
}
-case wxStyledTextCtrl_GetBufferedDraw: { // wxStyledTextCtrl::GetBufferedDraw
+case wxStyledTextCtrl_GetBufferedDraw: { // wxStyledTextCtrl::GetBufferedDraw
wxStyledTextCtrl *This = (wxStyledTextCtrl *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
bool Result = This->GetBufferedDraw();
rt.addBool(Result);
- break;
+ break;
}
-case wxStyledTextCtrl_SetBufferedDraw: { // wxStyledTextCtrl::SetBufferedDraw
+case wxStyledTextCtrl_SetBufferedDraw: { // wxStyledTextCtrl::SetBufferedDraw
wxStyledTextCtrl *This = (wxStyledTextCtrl *) getPtr(bp,memenv); bp += 4;
bool * buffered = (bool *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
This->SetBufferedDraw((bool) *buffered);
- break;
+ break;
}
-case wxStyledTextCtrl_SetTabWidth: { // wxStyledTextCtrl::SetTabWidth
+case wxStyledTextCtrl_SetTabWidth: { // wxStyledTextCtrl::SetTabWidth
wxStyledTextCtrl *This = (wxStyledTextCtrl *) getPtr(bp,memenv); bp += 4;
int * tabWidth = (int *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
This->SetTabWidth((int) *tabWidth);
- break;
+ break;
}
-case wxStyledTextCtrl_GetTabWidth: { // wxStyledTextCtrl::GetTabWidth
+case wxStyledTextCtrl_GetTabWidth: { // wxStyledTextCtrl::GetTabWidth
wxStyledTextCtrl *This = (wxStyledTextCtrl *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
int Result = This->GetTabWidth();
rt.addInt(Result);
- break;
+ break;
}
-case wxStyledTextCtrl_SetCodePage: { // wxStyledTextCtrl::SetCodePage
+case wxStyledTextCtrl_SetCodePage: { // wxStyledTextCtrl::SetCodePage
wxStyledTextCtrl *This = (wxStyledTextCtrl *) getPtr(bp,memenv); bp += 4;
int * codePage = (int *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
This->SetCodePage((int) *codePage);
- break;
+ break;
}
-case wxStyledTextCtrl_MarkerDefine: { // wxStyledTextCtrl::MarkerDefine
+case wxStyledTextCtrl_MarkerDefine: { // wxStyledTextCtrl::MarkerDefine
wxColour foreground= wxNullColour;
wxColour background= wxNullColour;
wxStyledTextCtrl *This = (wxStyledTextCtrl *) getPtr(bp,memenv); bp += 4;
int * markerNumber = (int *) bp; bp += 4;
int * markerSymbol = (int *) bp; bp += 4;
bp += 4; /* Align */
- while( * (int*) bp) { switch (* (int*) bp) {
+ while( * (int*) bp) { switch (* (int*) bp) {
case 1: {bp += 4;
int * foregroundR = (int *) bp; bp += 4;
int * foregroundG = (int *) bp; bp += 4;
@@ -27074,12 +27116,12 @@ case wxStyledTextCtrl_MarkerDefine: { // wxStyledTextCtrl::MarkerDefine
background = wxColour(*backgroundR,*backgroundG,*backgroundB,*backgroundA);
bp += 4; /* Align */
} break;
- }};
+ }};
if(!This) throw wxe_badarg(0);
This->MarkerDefine((int) *markerNumber,(int) *markerSymbol,foreground,background);
- break;
+ break;
}
-case wxStyledTextCtrl_MarkerSetForeground: { // wxStyledTextCtrl::MarkerSetForeground
+case wxStyledTextCtrl_MarkerSetForeground: { // wxStyledTextCtrl::MarkerSetForeground
wxStyledTextCtrl *This = (wxStyledTextCtrl *) getPtr(bp,memenv); bp += 4;
int * markerNumber = (int *) bp; bp += 4;
int * foreR = (int *) bp; bp += 4;
@@ -27089,9 +27131,9 @@ case wxStyledTextCtrl_MarkerSetForeground: { // wxStyledTextCtrl::MarkerSetForeg
wxColour fore = wxColour(*foreR,*foreG,*foreB,*foreA);
if(!This) throw wxe_badarg(0);
This->MarkerSetForeground((int) *markerNumber,fore);
- break;
+ break;
}
-case wxStyledTextCtrl_MarkerSetBackground: { // wxStyledTextCtrl::MarkerSetBackground
+case wxStyledTextCtrl_MarkerSetBackground: { // wxStyledTextCtrl::MarkerSetBackground
wxStyledTextCtrl *This = (wxStyledTextCtrl *) getPtr(bp,memenv); bp += 4;
int * markerNumber = (int *) bp; bp += 4;
int * backR = (int *) bp; bp += 4;
@@ -27101,153 +27143,153 @@ case wxStyledTextCtrl_MarkerSetBackground: { // wxStyledTextCtrl::MarkerSetBackg
wxColour back = wxColour(*backR,*backG,*backB,*backA);
if(!This) throw wxe_badarg(0);
This->MarkerSetBackground((int) *markerNumber,back);
- break;
+ break;
}
-case wxStyledTextCtrl_MarkerAdd: { // wxStyledTextCtrl::MarkerAdd
+case wxStyledTextCtrl_MarkerAdd: { // wxStyledTextCtrl::MarkerAdd
wxStyledTextCtrl *This = (wxStyledTextCtrl *) getPtr(bp,memenv); bp += 4;
int * line = (int *) bp; bp += 4;
int * markerNumber = (int *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
int Result = This->MarkerAdd((int) *line,(int) *markerNumber);
rt.addInt(Result);
- break;
+ break;
}
-case wxStyledTextCtrl_MarkerDelete: { // wxStyledTextCtrl::MarkerDelete
+case wxStyledTextCtrl_MarkerDelete: { // wxStyledTextCtrl::MarkerDelete
wxStyledTextCtrl *This = (wxStyledTextCtrl *) getPtr(bp,memenv); bp += 4;
int * line = (int *) bp; bp += 4;
int * markerNumber = (int *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
This->MarkerDelete((int) *line,(int) *markerNumber);
- break;
+ break;
}
-case wxStyledTextCtrl_MarkerDeleteAll: { // wxStyledTextCtrl::MarkerDeleteAll
+case wxStyledTextCtrl_MarkerDeleteAll: { // wxStyledTextCtrl::MarkerDeleteAll
wxStyledTextCtrl *This = (wxStyledTextCtrl *) getPtr(bp,memenv); bp += 4;
int * markerNumber = (int *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
This->MarkerDeleteAll((int) *markerNumber);
- break;
+ break;
}
-case wxStyledTextCtrl_MarkerGet: { // wxStyledTextCtrl::MarkerGet
+case wxStyledTextCtrl_MarkerGet: { // wxStyledTextCtrl::MarkerGet
wxStyledTextCtrl *This = (wxStyledTextCtrl *) getPtr(bp,memenv); bp += 4;
int * line = (int *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
int Result = This->MarkerGet((int) *line);
rt.addInt(Result);
- break;
+ break;
}
-case wxStyledTextCtrl_MarkerNext: { // wxStyledTextCtrl::MarkerNext
+case wxStyledTextCtrl_MarkerNext: { // wxStyledTextCtrl::MarkerNext
wxStyledTextCtrl *This = (wxStyledTextCtrl *) getPtr(bp,memenv); bp += 4;
int * lineStart = (int *) bp; bp += 4;
int * markerMask = (int *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
int Result = This->MarkerNext((int) *lineStart,(int) *markerMask);
rt.addInt(Result);
- break;
+ break;
}
-case wxStyledTextCtrl_MarkerPrevious: { // wxStyledTextCtrl::MarkerPrevious
+case wxStyledTextCtrl_MarkerPrevious: { // wxStyledTextCtrl::MarkerPrevious
wxStyledTextCtrl *This = (wxStyledTextCtrl *) getPtr(bp,memenv); bp += 4;
int * lineStart = (int *) bp; bp += 4;
int * markerMask = (int *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
int Result = This->MarkerPrevious((int) *lineStart,(int) *markerMask);
rt.addInt(Result);
- break;
+ break;
}
-case wxStyledTextCtrl_MarkerDefineBitmap: { // wxStyledTextCtrl::MarkerDefineBitmap
+case wxStyledTextCtrl_MarkerDefineBitmap: { // wxStyledTextCtrl::MarkerDefineBitmap
wxStyledTextCtrl *This = (wxStyledTextCtrl *) getPtr(bp,memenv); bp += 4;
int * markerNumber = (int *) bp; bp += 4;
wxBitmap *bmp = (wxBitmap *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
This->MarkerDefineBitmap((int) *markerNumber,*bmp);
- break;
+ break;
}
-case wxStyledTextCtrl_MarkerAddSet: { // wxStyledTextCtrl::MarkerAddSet
+case wxStyledTextCtrl_MarkerAddSet: { // wxStyledTextCtrl::MarkerAddSet
wxStyledTextCtrl *This = (wxStyledTextCtrl *) getPtr(bp,memenv); bp += 4;
int * line = (int *) bp; bp += 4;
int * set = (int *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
This->MarkerAddSet((int) *line,(int) *set);
- break;
+ break;
}
-case wxStyledTextCtrl_MarkerSetAlpha: { // wxStyledTextCtrl::MarkerSetAlpha
+case wxStyledTextCtrl_MarkerSetAlpha: { // wxStyledTextCtrl::MarkerSetAlpha
wxStyledTextCtrl *This = (wxStyledTextCtrl *) getPtr(bp,memenv); bp += 4;
int * markerNumber = (int *) bp; bp += 4;
int * alpha = (int *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
This->MarkerSetAlpha((int) *markerNumber,(int) *alpha);
- break;
+ break;
}
-case wxStyledTextCtrl_SetMarginType: { // wxStyledTextCtrl::SetMarginType
+case wxStyledTextCtrl_SetMarginType: { // wxStyledTextCtrl::SetMarginType
wxStyledTextCtrl *This = (wxStyledTextCtrl *) getPtr(bp,memenv); bp += 4;
int * margin = (int *) bp; bp += 4;
int * marginType = (int *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
This->SetMarginType((int) *margin,(int) *marginType);
- break;
+ break;
}
-case wxStyledTextCtrl_GetMarginType: { // wxStyledTextCtrl::GetMarginType
+case wxStyledTextCtrl_GetMarginType: { // wxStyledTextCtrl::GetMarginType
wxStyledTextCtrl *This = (wxStyledTextCtrl *) getPtr(bp,memenv); bp += 4;
int * margin = (int *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
int Result = This->GetMarginType((int) *margin);
rt.addInt(Result);
- break;
+ break;
}
-case wxStyledTextCtrl_SetMarginWidth: { // wxStyledTextCtrl::SetMarginWidth
+case wxStyledTextCtrl_SetMarginWidth: { // wxStyledTextCtrl::SetMarginWidth
wxStyledTextCtrl *This = (wxStyledTextCtrl *) getPtr(bp,memenv); bp += 4;
int * margin = (int *) bp; bp += 4;
int * pixelWidth = (int *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
This->SetMarginWidth((int) *margin,(int) *pixelWidth);
- break;
+ break;
}
-case wxStyledTextCtrl_GetMarginWidth: { // wxStyledTextCtrl::GetMarginWidth
+case wxStyledTextCtrl_GetMarginWidth: { // wxStyledTextCtrl::GetMarginWidth
wxStyledTextCtrl *This = (wxStyledTextCtrl *) getPtr(bp,memenv); bp += 4;
int * margin = (int *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
int Result = This->GetMarginWidth((int) *margin);
rt.addInt(Result);
- break;
+ break;
}
-case wxStyledTextCtrl_SetMarginMask: { // wxStyledTextCtrl::SetMarginMask
+case wxStyledTextCtrl_SetMarginMask: { // wxStyledTextCtrl::SetMarginMask
wxStyledTextCtrl *This = (wxStyledTextCtrl *) getPtr(bp,memenv); bp += 4;
int * margin = (int *) bp; bp += 4;
int * mask = (int *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
This->SetMarginMask((int) *margin,(int) *mask);
- break;
+ break;
}
-case wxStyledTextCtrl_GetMarginMask: { // wxStyledTextCtrl::GetMarginMask
+case wxStyledTextCtrl_GetMarginMask: { // wxStyledTextCtrl::GetMarginMask
wxStyledTextCtrl *This = (wxStyledTextCtrl *) getPtr(bp,memenv); bp += 4;
int * margin = (int *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
int Result = This->GetMarginMask((int) *margin);
rt.addInt(Result);
- break;
+ break;
}
-case wxStyledTextCtrl_SetMarginSensitive: { // wxStyledTextCtrl::SetMarginSensitive
+case wxStyledTextCtrl_SetMarginSensitive: { // wxStyledTextCtrl::SetMarginSensitive
wxStyledTextCtrl *This = (wxStyledTextCtrl *) getPtr(bp,memenv); bp += 4;
int * margin = (int *) bp; bp += 4;
bool * sensitive = (bool *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
This->SetMarginSensitive((int) *margin,(bool) *sensitive);
- break;
+ break;
}
-case wxStyledTextCtrl_GetMarginSensitive: { // wxStyledTextCtrl::GetMarginSensitive
+case wxStyledTextCtrl_GetMarginSensitive: { // wxStyledTextCtrl::GetMarginSensitive
wxStyledTextCtrl *This = (wxStyledTextCtrl *) getPtr(bp,memenv); bp += 4;
int * margin = (int *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
bool Result = This->GetMarginSensitive((int) *margin);
rt.addBool(Result);
- break;
+ break;
}
-case wxStyledTextCtrl_StyleClearAll: { // wxStyledTextCtrl::StyleClearAll
+case wxStyledTextCtrl_StyleClearAll: { // wxStyledTextCtrl::StyleClearAll
wxStyledTextCtrl *This = (wxStyledTextCtrl *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
This->StyleClearAll();
- break;
+ break;
}
-case wxStyledTextCtrl_StyleSetForeground: { // wxStyledTextCtrl::StyleSetForeground
+case wxStyledTextCtrl_StyleSetForeground: { // wxStyledTextCtrl::StyleSetForeground
wxStyledTextCtrl *This = (wxStyledTextCtrl *) getPtr(bp,memenv); bp += 4;
int * style = (int *) bp; bp += 4;
int * foreR = (int *) bp; bp += 4;
@@ -27257,9 +27299,9 @@ case wxStyledTextCtrl_StyleSetForeground: { // wxStyledTextCtrl::StyleSetForegro
wxColour fore = wxColour(*foreR,*foreG,*foreB,*foreA);
if(!This) throw wxe_badarg(0);
This->StyleSetForeground((int) *style,fore);
- break;
+ break;
}
-case wxStyledTextCtrl_StyleSetBackground: { // wxStyledTextCtrl::StyleSetBackground
+case wxStyledTextCtrl_StyleSetBackground: { // wxStyledTextCtrl::StyleSetBackground
wxStyledTextCtrl *This = (wxStyledTextCtrl *) getPtr(bp,memenv); bp += 4;
int * style = (int *) bp; bp += 4;
int * backR = (int *) bp; bp += 4;
@@ -27269,33 +27311,33 @@ case wxStyledTextCtrl_StyleSetBackground: { // wxStyledTextCtrl::StyleSetBackgro
wxColour back = wxColour(*backR,*backG,*backB,*backA);
if(!This) throw wxe_badarg(0);
This->StyleSetBackground((int) *style,back);
- break;
+ break;
}
-case wxStyledTextCtrl_StyleSetBold: { // wxStyledTextCtrl::StyleSetBold
+case wxStyledTextCtrl_StyleSetBold: { // wxStyledTextCtrl::StyleSetBold
wxStyledTextCtrl *This = (wxStyledTextCtrl *) getPtr(bp,memenv); bp += 4;
int * style = (int *) bp; bp += 4;
bool * bold = (bool *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
This->StyleSetBold((int) *style,(bool) *bold);
- break;
+ break;
}
-case wxStyledTextCtrl_StyleSetItalic: { // wxStyledTextCtrl::StyleSetItalic
+case wxStyledTextCtrl_StyleSetItalic: { // wxStyledTextCtrl::StyleSetItalic
wxStyledTextCtrl *This = (wxStyledTextCtrl *) getPtr(bp,memenv); bp += 4;
int * style = (int *) bp; bp += 4;
bool * italic = (bool *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
This->StyleSetItalic((int) *style,(bool) *italic);
- break;
+ break;
}
-case wxStyledTextCtrl_StyleSetSize: { // wxStyledTextCtrl::StyleSetSize
+case wxStyledTextCtrl_StyleSetSize: { // wxStyledTextCtrl::StyleSetSize
wxStyledTextCtrl *This = (wxStyledTextCtrl *) getPtr(bp,memenv); bp += 4;
int * style = (int *) bp; bp += 4;
int * sizePoints = (int *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
This->StyleSetSize((int) *style,(int) *sizePoints);
- break;
+ break;
}
-case wxStyledTextCtrl_StyleSetFaceName: { // wxStyledTextCtrl::StyleSetFaceName
+case wxStyledTextCtrl_StyleSetFaceName: { // wxStyledTextCtrl::StyleSetFaceName
wxStyledTextCtrl *This = (wxStyledTextCtrl *) getPtr(bp,memenv); bp += 4;
int * style = (int *) bp; bp += 4;
int * fontNameLen = (int *) bp; bp += 4;
@@ -27303,47 +27345,47 @@ case wxStyledTextCtrl_StyleSetFaceName: { // wxStyledTextCtrl::StyleSetFaceName
bp += *fontNameLen+((8-((4+ *fontNameLen) & 7)) & 7);
if(!This) throw wxe_badarg(0);
This->StyleSetFaceName((int) *style,fontName);
- break;
+ break;
}
-case wxStyledTextCtrl_StyleSetEOLFilled: { // wxStyledTextCtrl::StyleSetEOLFilled
+case wxStyledTextCtrl_StyleSetEOLFilled: { // wxStyledTextCtrl::StyleSetEOLFilled
wxStyledTextCtrl *This = (wxStyledTextCtrl *) getPtr(bp,memenv); bp += 4;
int * style = (int *) bp; bp += 4;
bool * filled = (bool *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
This->StyleSetEOLFilled((int) *style,(bool) *filled);
- break;
+ break;
}
-case wxStyledTextCtrl_StyleResetDefault: { // wxStyledTextCtrl::StyleResetDefault
+case wxStyledTextCtrl_StyleResetDefault: { // wxStyledTextCtrl::StyleResetDefault
wxStyledTextCtrl *This = (wxStyledTextCtrl *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
This->StyleResetDefault();
- break;
+ break;
}
-case wxStyledTextCtrl_StyleSetUnderline: { // wxStyledTextCtrl::StyleSetUnderline
+case wxStyledTextCtrl_StyleSetUnderline: { // wxStyledTextCtrl::StyleSetUnderline
wxStyledTextCtrl *This = (wxStyledTextCtrl *) getPtr(bp,memenv); bp += 4;
int * style = (int *) bp; bp += 4;
bool * underline = (bool *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
This->StyleSetUnderline((int) *style,(bool) *underline);
- break;
+ break;
}
-case wxStyledTextCtrl_StyleSetCase: { // wxStyledTextCtrl::StyleSetCase
+case wxStyledTextCtrl_StyleSetCase: { // wxStyledTextCtrl::StyleSetCase
wxStyledTextCtrl *This = (wxStyledTextCtrl *) getPtr(bp,memenv); bp += 4;
int * style = (int *) bp; bp += 4;
int * caseForce = (int *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
This->StyleSetCase((int) *style,(int) *caseForce);
- break;
+ break;
}
-case wxStyledTextCtrl_StyleSetHotSpot: { // wxStyledTextCtrl::StyleSetHotSpot
+case wxStyledTextCtrl_StyleSetHotSpot: { // wxStyledTextCtrl::StyleSetHotSpot
wxStyledTextCtrl *This = (wxStyledTextCtrl *) getPtr(bp,memenv); bp += 4;
int * style = (int *) bp; bp += 4;
bool * hotspot = (bool *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
This->StyleSetHotSpot((int) *style,(bool) *hotspot);
- break;
+ break;
}
-case wxStyledTextCtrl_SetSelForeground: { // wxStyledTextCtrl::SetSelForeground
+case wxStyledTextCtrl_SetSelForeground: { // wxStyledTextCtrl::SetSelForeground
wxStyledTextCtrl *This = (wxStyledTextCtrl *) getPtr(bp,memenv); bp += 4;
bool * useSetting = (bool *) bp; bp += 4;
int * foreR = (int *) bp; bp += 4;
@@ -27353,9 +27395,9 @@ case wxStyledTextCtrl_SetSelForeground: { // wxStyledTextCtrl::SetSelForeground
wxColour fore = wxColour(*foreR,*foreG,*foreB,*foreA);
if(!This) throw wxe_badarg(0);
This->SetSelForeground((bool) *useSetting,fore);
- break;
+ break;
}
-case wxStyledTextCtrl_SetSelBackground: { // wxStyledTextCtrl::SetSelBackground
+case wxStyledTextCtrl_SetSelBackground: { // wxStyledTextCtrl::SetSelBackground
wxStyledTextCtrl *This = (wxStyledTextCtrl *) getPtr(bp,memenv); bp += 4;
bool * useSetting = (bool *) bp; bp += 4;
int * backR = (int *) bp; bp += 4;
@@ -27365,23 +27407,23 @@ case wxStyledTextCtrl_SetSelBackground: { // wxStyledTextCtrl::SetSelBackground
wxColour back = wxColour(*backR,*backG,*backB,*backA);
if(!This) throw wxe_badarg(0);
This->SetSelBackground((bool) *useSetting,back);
- break;
+ break;
}
-case wxStyledTextCtrl_GetSelAlpha: { // wxStyledTextCtrl::GetSelAlpha
+case wxStyledTextCtrl_GetSelAlpha: { // wxStyledTextCtrl::GetSelAlpha
wxStyledTextCtrl *This = (wxStyledTextCtrl *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
int Result = This->GetSelAlpha();
rt.addInt(Result);
- break;
+ break;
}
-case wxStyledTextCtrl_SetSelAlpha: { // wxStyledTextCtrl::SetSelAlpha
+case wxStyledTextCtrl_SetSelAlpha: { // wxStyledTextCtrl::SetSelAlpha
wxStyledTextCtrl *This = (wxStyledTextCtrl *) getPtr(bp,memenv); bp += 4;
int * alpha = (int *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
This->SetSelAlpha((int) *alpha);
- break;
+ break;
}
-case wxStyledTextCtrl_SetCaretForeground: { // wxStyledTextCtrl::SetCaretForeground
+case wxStyledTextCtrl_SetCaretForeground: { // wxStyledTextCtrl::SetCaretForeground
wxStyledTextCtrl *This = (wxStyledTextCtrl *) getPtr(bp,memenv); bp += 4;
int * foreR = (int *) bp; bp += 4;
int * foreG = (int *) bp; bp += 4;
@@ -27390,100 +27432,100 @@ case wxStyledTextCtrl_SetCaretForeground: { // wxStyledTextCtrl::SetCaretForegro
wxColour fore = wxColour(*foreR,*foreG,*foreB,*foreA);
if(!This) throw wxe_badarg(0);
This->SetCaretForeground(fore);
- break;
+ break;
}
-case wxStyledTextCtrl_CmdKeyAssign: { // wxStyledTextCtrl::CmdKeyAssign
+case wxStyledTextCtrl_CmdKeyAssign: { // wxStyledTextCtrl::CmdKeyAssign
wxStyledTextCtrl *This = (wxStyledTextCtrl *) getPtr(bp,memenv); bp += 4;
int * key = (int *) bp; bp += 4;
int * modifiers = (int *) bp; bp += 4;
int * cmd = (int *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
This->CmdKeyAssign((int) *key,(int) *modifiers,(int) *cmd);
- break;
+ break;
}
-case wxStyledTextCtrl_CmdKeyClear: { // wxStyledTextCtrl::CmdKeyClear
+case wxStyledTextCtrl_CmdKeyClear: { // wxStyledTextCtrl::CmdKeyClear
wxStyledTextCtrl *This = (wxStyledTextCtrl *) getPtr(bp,memenv); bp += 4;
int * key = (int *) bp; bp += 4;
int * modifiers = (int *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
This->CmdKeyClear((int) *key,(int) *modifiers);
- break;
+ break;
}
-case wxStyledTextCtrl_CmdKeyClearAll: { // wxStyledTextCtrl::CmdKeyClearAll
+case wxStyledTextCtrl_CmdKeyClearAll: { // wxStyledTextCtrl::CmdKeyClearAll
wxStyledTextCtrl *This = (wxStyledTextCtrl *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
This->CmdKeyClearAll();
- break;
+ break;
}
-case wxStyledTextCtrl_SetStyleBytes: { // wxStyledTextCtrl::SetStyleBytes
+case wxStyledTextCtrl_SetStyleBytes: { // wxStyledTextCtrl::SetStyleBytes
char styleBytes;
wxStyledTextCtrl *This = (wxStyledTextCtrl *) getPtr(bp,memenv); bp += 4;
int * length = (int *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
This->SetStyleBytes((int) *length,&styleBytes);
rt.addInt(styleBytes);
- break;
+ break;
}
-case wxStyledTextCtrl_StyleSetVisible: { // wxStyledTextCtrl::StyleSetVisible
+case wxStyledTextCtrl_StyleSetVisible: { // wxStyledTextCtrl::StyleSetVisible
wxStyledTextCtrl *This = (wxStyledTextCtrl *) getPtr(bp,memenv); bp += 4;
int * style = (int *) bp; bp += 4;
bool * visible = (bool *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
This->StyleSetVisible((int) *style,(bool) *visible);
- break;
+ break;
}
-case wxStyledTextCtrl_GetCaretPeriod: { // wxStyledTextCtrl::GetCaretPeriod
+case wxStyledTextCtrl_GetCaretPeriod: { // wxStyledTextCtrl::GetCaretPeriod
wxStyledTextCtrl *This = (wxStyledTextCtrl *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
int Result = This->GetCaretPeriod();
rt.addInt(Result);
- break;
+ break;
}
-case wxStyledTextCtrl_SetCaretPeriod: { // wxStyledTextCtrl::SetCaretPeriod
+case wxStyledTextCtrl_SetCaretPeriod: { // wxStyledTextCtrl::SetCaretPeriod
wxStyledTextCtrl *This = (wxStyledTextCtrl *) getPtr(bp,memenv); bp += 4;
int * periodMilliseconds = (int *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
This->SetCaretPeriod((int) *periodMilliseconds);
- break;
+ break;
}
-case wxStyledTextCtrl_SetWordChars: { // wxStyledTextCtrl::SetWordChars
+case wxStyledTextCtrl_SetWordChars: { // wxStyledTextCtrl::SetWordChars
wxStyledTextCtrl *This = (wxStyledTextCtrl *) getPtr(bp,memenv); bp += 4;
int * charactersLen = (int *) bp; bp += 4;
wxString characters = wxString(bp, wxConvUTF8);
bp += *charactersLen+((8-((0+ *charactersLen) & 7)) & 7);
if(!This) throw wxe_badarg(0);
This->SetWordChars(characters);
- break;
+ break;
}
-case wxStyledTextCtrl_BeginUndoAction: { // wxStyledTextCtrl::BeginUndoAction
+case wxStyledTextCtrl_BeginUndoAction: { // wxStyledTextCtrl::BeginUndoAction
wxStyledTextCtrl *This = (wxStyledTextCtrl *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
This->BeginUndoAction();
- break;
+ break;
}
-case wxStyledTextCtrl_EndUndoAction: { // wxStyledTextCtrl::EndUndoAction
+case wxStyledTextCtrl_EndUndoAction: { // wxStyledTextCtrl::EndUndoAction
wxStyledTextCtrl *This = (wxStyledTextCtrl *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
This->EndUndoAction();
- break;
+ break;
}
-case wxStyledTextCtrl_IndicatorSetStyle: { // wxStyledTextCtrl::IndicatorSetStyle
+case wxStyledTextCtrl_IndicatorSetStyle: { // wxStyledTextCtrl::IndicatorSetStyle
wxStyledTextCtrl *This = (wxStyledTextCtrl *) getPtr(bp,memenv); bp += 4;
int * indic = (int *) bp; bp += 4;
int * style = (int *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
This->IndicatorSetStyle((int) *indic,(int) *style);
- break;
+ break;
}
-case wxStyledTextCtrl_IndicatorGetStyle: { // wxStyledTextCtrl::IndicatorGetStyle
+case wxStyledTextCtrl_IndicatorGetStyle: { // wxStyledTextCtrl::IndicatorGetStyle
wxStyledTextCtrl *This = (wxStyledTextCtrl *) getPtr(bp,memenv); bp += 4;
int * indic = (int *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
int Result = This->IndicatorGetStyle((int) *indic);
rt.addInt(Result);
- break;
+ break;
}
-case wxStyledTextCtrl_IndicatorSetForeground: { // wxStyledTextCtrl::IndicatorSetForeground
+case wxStyledTextCtrl_IndicatorSetForeground: { // wxStyledTextCtrl::IndicatorSetForeground
wxStyledTextCtrl *This = (wxStyledTextCtrl *) getPtr(bp,memenv); bp += 4;
int * indic = (int *) bp; bp += 4;
int * foreR = (int *) bp; bp += 4;
@@ -27493,17 +27535,17 @@ case wxStyledTextCtrl_IndicatorSetForeground: { // wxStyledTextCtrl::IndicatorSe
wxColour fore = wxColour(*foreR,*foreG,*foreB,*foreA);
if(!This) throw wxe_badarg(0);
This->IndicatorSetForeground((int) *indic,fore);
- break;
+ break;
}
-case wxStyledTextCtrl_IndicatorGetForeground: { // wxStyledTextCtrl::IndicatorGetForeground
+case wxStyledTextCtrl_IndicatorGetForeground: { // wxStyledTextCtrl::IndicatorGetForeground
wxStyledTextCtrl *This = (wxStyledTextCtrl *) getPtr(bp,memenv); bp += 4;
int * indic = (int *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
wxColour Result = This->IndicatorGetForeground((int) *indic);
rt.add(Result);
- break;
+ break;
}
-case wxStyledTextCtrl_SetWhitespaceForeground: { // wxStyledTextCtrl::SetWhitespaceForeground
+case wxStyledTextCtrl_SetWhitespaceForeground: { // wxStyledTextCtrl::SetWhitespaceForeground
wxStyledTextCtrl *This = (wxStyledTextCtrl *) getPtr(bp,memenv); bp += 4;
bool * useSetting = (bool *) bp; bp += 4;
int * foreR = (int *) bp; bp += 4;
@@ -27513,9 +27555,9 @@ case wxStyledTextCtrl_SetWhitespaceForeground: { // wxStyledTextCtrl::SetWhitesp
wxColour fore = wxColour(*foreR,*foreG,*foreB,*foreA);
if(!This) throw wxe_badarg(0);
This->SetWhitespaceForeground((bool) *useSetting,fore);
- break;
+ break;
}
-case wxStyledTextCtrl_SetWhitespaceBackground: { // wxStyledTextCtrl::SetWhitespaceBackground
+case wxStyledTextCtrl_SetWhitespaceBackground: { // wxStyledTextCtrl::SetWhitespaceBackground
wxStyledTextCtrl *This = (wxStyledTextCtrl *) getPtr(bp,memenv); bp += 4;
bool * useSetting = (bool *) bp; bp += 4;
int * backR = (int *) bp; bp += 4;
@@ -27525,60 +27567,60 @@ case wxStyledTextCtrl_SetWhitespaceBackground: { // wxStyledTextCtrl::SetWhitesp
wxColour back = wxColour(*backR,*backG,*backB,*backA);
if(!This) throw wxe_badarg(0);
This->SetWhitespaceBackground((bool) *useSetting,back);
- break;
+ break;
}
-case wxStyledTextCtrl_GetStyleBits: { // wxStyledTextCtrl::GetStyleBits
+case wxStyledTextCtrl_GetStyleBits: { // wxStyledTextCtrl::GetStyleBits
wxStyledTextCtrl *This = (wxStyledTextCtrl *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
int Result = This->GetStyleBits();
rt.addInt(Result);
- break;
+ break;
}
-case wxStyledTextCtrl_SetLineState: { // wxStyledTextCtrl::SetLineState
+case wxStyledTextCtrl_SetLineState: { // wxStyledTextCtrl::SetLineState
wxStyledTextCtrl *This = (wxStyledTextCtrl *) getPtr(bp,memenv); bp += 4;
int * line = (int *) bp; bp += 4;
int * state = (int *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
This->SetLineState((int) *line,(int) *state);
- break;
+ break;
}
-case wxStyledTextCtrl_GetLineState: { // wxStyledTextCtrl::GetLineState
+case wxStyledTextCtrl_GetLineState: { // wxStyledTextCtrl::GetLineState
wxStyledTextCtrl *This = (wxStyledTextCtrl *) getPtr(bp,memenv); bp += 4;
int * line = (int *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
int Result = This->GetLineState((int) *line);
rt.addInt(Result);
- break;
+ break;
}
-case wxStyledTextCtrl_GetMaxLineState: { // wxStyledTextCtrl::GetMaxLineState
+case wxStyledTextCtrl_GetMaxLineState: { // wxStyledTextCtrl::GetMaxLineState
wxStyledTextCtrl *This = (wxStyledTextCtrl *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
int Result = This->GetMaxLineState();
rt.addInt(Result);
- break;
+ break;
}
-case wxStyledTextCtrl_GetCaretLineVisible: { // wxStyledTextCtrl::GetCaretLineVisible
+case wxStyledTextCtrl_GetCaretLineVisible: { // wxStyledTextCtrl::GetCaretLineVisible
wxStyledTextCtrl *This = (wxStyledTextCtrl *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
bool Result = This->GetCaretLineVisible();
rt.addBool(Result);
- break;
+ break;
}
-case wxStyledTextCtrl_SetCaretLineVisible: { // wxStyledTextCtrl::SetCaretLineVisible
+case wxStyledTextCtrl_SetCaretLineVisible: { // wxStyledTextCtrl::SetCaretLineVisible
wxStyledTextCtrl *This = (wxStyledTextCtrl *) getPtr(bp,memenv); bp += 4;
bool * show = (bool *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
This->SetCaretLineVisible((bool) *show);
- break;
+ break;
}
-case wxStyledTextCtrl_GetCaretLineBackground: { // wxStyledTextCtrl::GetCaretLineBackground
+case wxStyledTextCtrl_GetCaretLineBackground: { // wxStyledTextCtrl::GetCaretLineBackground
wxStyledTextCtrl *This = (wxStyledTextCtrl *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
wxColour Result = This->GetCaretLineBackground();
rt.add(Result);
- break;
+ break;
}
-case wxStyledTextCtrl_SetCaretLineBackground: { // wxStyledTextCtrl::SetCaretLineBackground
+case wxStyledTextCtrl_SetCaretLineBackground: { // wxStyledTextCtrl::SetCaretLineBackground
wxStyledTextCtrl *This = (wxStyledTextCtrl *) getPtr(bp,memenv); bp += 4;
int * backR = (int *) bp; bp += 4;
int * backG = (int *) bp; bp += 4;
@@ -27587,9 +27629,9 @@ case wxStyledTextCtrl_SetCaretLineBackground: { // wxStyledTextCtrl::SetCaretLin
wxColour back = wxColour(*backR,*backG,*backB,*backA);
if(!This) throw wxe_badarg(0);
This->SetCaretLineBackground(back);
- break;
+ break;
}
-case wxStyledTextCtrl_AutoCompShow: { // wxStyledTextCtrl::AutoCompShow
+case wxStyledTextCtrl_AutoCompShow: { // wxStyledTextCtrl::AutoCompShow
wxStyledTextCtrl *This = (wxStyledTextCtrl *) getPtr(bp,memenv); bp += 4;
int * lenEntered = (int *) bp; bp += 4;
int * itemListLen = (int *) bp; bp += 4;
@@ -27597,118 +27639,118 @@ case wxStyledTextCtrl_AutoCompShow: { // wxStyledTextCtrl::AutoCompShow
bp += *itemListLen+((8-((4+ *itemListLen) & 7)) & 7);
if(!This) throw wxe_badarg(0);
This->AutoCompShow((int) *lenEntered,itemList);
- break;
+ break;
}
-case wxStyledTextCtrl_AutoCompCancel: { // wxStyledTextCtrl::AutoCompCancel
+case wxStyledTextCtrl_AutoCompCancel: { // wxStyledTextCtrl::AutoCompCancel
wxStyledTextCtrl *This = (wxStyledTextCtrl *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
This->AutoCompCancel();
- break;
+ break;
}
-case wxStyledTextCtrl_AutoCompActive: { // wxStyledTextCtrl::AutoCompActive
+case wxStyledTextCtrl_AutoCompActive: { // wxStyledTextCtrl::AutoCompActive
wxStyledTextCtrl *This = (wxStyledTextCtrl *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
bool Result = This->AutoCompActive();
rt.addBool(Result);
- break;
+ break;
}
-case wxStyledTextCtrl_AutoCompPosStart: { // wxStyledTextCtrl::AutoCompPosStart
+case wxStyledTextCtrl_AutoCompPosStart: { // wxStyledTextCtrl::AutoCompPosStart
wxStyledTextCtrl *This = (wxStyledTextCtrl *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
int Result = This->AutoCompPosStart();
rt.addInt(Result);
- break;
+ break;
}
-case wxStyledTextCtrl_AutoCompComplete: { // wxStyledTextCtrl::AutoCompComplete
+case wxStyledTextCtrl_AutoCompComplete: { // wxStyledTextCtrl::AutoCompComplete
wxStyledTextCtrl *This = (wxStyledTextCtrl *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
This->AutoCompComplete();
- break;
+ break;
}
-case wxStyledTextCtrl_AutoCompStops: { // wxStyledTextCtrl::AutoCompStops
+case wxStyledTextCtrl_AutoCompStops: { // wxStyledTextCtrl::AutoCompStops
wxStyledTextCtrl *This = (wxStyledTextCtrl *) getPtr(bp,memenv); bp += 4;
int * characterSetLen = (int *) bp; bp += 4;
wxString characterSet = wxString(bp, wxConvUTF8);
bp += *characterSetLen+((8-((0+ *characterSetLen) & 7)) & 7);
if(!This) throw wxe_badarg(0);
This->AutoCompStops(characterSet);
- break;
+ break;
}
-case wxStyledTextCtrl_AutoCompSetSeparator: { // wxStyledTextCtrl::AutoCompSetSeparator
+case wxStyledTextCtrl_AutoCompSetSeparator: { // wxStyledTextCtrl::AutoCompSetSeparator
wxStyledTextCtrl *This = (wxStyledTextCtrl *) getPtr(bp,memenv); bp += 4;
int * separatorCharacter = (int *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
This->AutoCompSetSeparator((int) *separatorCharacter);
- break;
+ break;
}
-case wxStyledTextCtrl_AutoCompGetSeparator: { // wxStyledTextCtrl::AutoCompGetSeparator
+case wxStyledTextCtrl_AutoCompGetSeparator: { // wxStyledTextCtrl::AutoCompGetSeparator
wxStyledTextCtrl *This = (wxStyledTextCtrl *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
int Result = This->AutoCompGetSeparator();
rt.addInt(Result);
- break;
+ break;
}
-case wxStyledTextCtrl_AutoCompSelect: { // wxStyledTextCtrl::AutoCompSelect
+case wxStyledTextCtrl_AutoCompSelect: { // wxStyledTextCtrl::AutoCompSelect
wxStyledTextCtrl *This = (wxStyledTextCtrl *) getPtr(bp,memenv); bp += 4;
int * textLen = (int *) bp; bp += 4;
wxString text = wxString(bp, wxConvUTF8);
bp += *textLen+((8-((0+ *textLen) & 7)) & 7);
if(!This) throw wxe_badarg(0);
This->AutoCompSelect(text);
- break;
+ break;
}
-case wxStyledTextCtrl_AutoCompSetCancelAtStart: { // wxStyledTextCtrl::AutoCompSetCancelAtStart
+case wxStyledTextCtrl_AutoCompSetCancelAtStart: { // wxStyledTextCtrl::AutoCompSetCancelAtStart
wxStyledTextCtrl *This = (wxStyledTextCtrl *) getPtr(bp,memenv); bp += 4;
bool * cancel = (bool *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
This->AutoCompSetCancelAtStart((bool) *cancel);
- break;
+ break;
}
-case wxStyledTextCtrl_AutoCompGetCancelAtStart: { // wxStyledTextCtrl::AutoCompGetCancelAtStart
+case wxStyledTextCtrl_AutoCompGetCancelAtStart: { // wxStyledTextCtrl::AutoCompGetCancelAtStart
wxStyledTextCtrl *This = (wxStyledTextCtrl *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
bool Result = This->AutoCompGetCancelAtStart();
rt.addBool(Result);
- break;
+ break;
}
-case wxStyledTextCtrl_AutoCompSetFillUps: { // wxStyledTextCtrl::AutoCompSetFillUps
+case wxStyledTextCtrl_AutoCompSetFillUps: { // wxStyledTextCtrl::AutoCompSetFillUps
wxStyledTextCtrl *This = (wxStyledTextCtrl *) getPtr(bp,memenv); bp += 4;
int * characterSetLen = (int *) bp; bp += 4;
wxString characterSet = wxString(bp, wxConvUTF8);
bp += *characterSetLen+((8-((0+ *characterSetLen) & 7)) & 7);
if(!This) throw wxe_badarg(0);
This->AutoCompSetFillUps(characterSet);
- break;
+ break;
}
-case wxStyledTextCtrl_AutoCompSetChooseSingle: { // wxStyledTextCtrl::AutoCompSetChooseSingle
+case wxStyledTextCtrl_AutoCompSetChooseSingle: { // wxStyledTextCtrl::AutoCompSetChooseSingle
wxStyledTextCtrl *This = (wxStyledTextCtrl *) getPtr(bp,memenv); bp += 4;
bool * chooseSingle = (bool *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
This->AutoCompSetChooseSingle((bool) *chooseSingle);
- break;
+ break;
}
-case wxStyledTextCtrl_AutoCompGetChooseSingle: { // wxStyledTextCtrl::AutoCompGetChooseSingle
+case wxStyledTextCtrl_AutoCompGetChooseSingle: { // wxStyledTextCtrl::AutoCompGetChooseSingle
wxStyledTextCtrl *This = (wxStyledTextCtrl *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
bool Result = This->AutoCompGetChooseSingle();
rt.addBool(Result);
- break;
+ break;
}
-case wxStyledTextCtrl_AutoCompSetIgnoreCase: { // wxStyledTextCtrl::AutoCompSetIgnoreCase
+case wxStyledTextCtrl_AutoCompSetIgnoreCase: { // wxStyledTextCtrl::AutoCompSetIgnoreCase
wxStyledTextCtrl *This = (wxStyledTextCtrl *) getPtr(bp,memenv); bp += 4;
bool * ignoreCase = (bool *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
This->AutoCompSetIgnoreCase((bool) *ignoreCase);
- break;
+ break;
}
-case wxStyledTextCtrl_AutoCompGetIgnoreCase: { // wxStyledTextCtrl::AutoCompGetIgnoreCase
+case wxStyledTextCtrl_AutoCompGetIgnoreCase: { // wxStyledTextCtrl::AutoCompGetIgnoreCase
wxStyledTextCtrl *This = (wxStyledTextCtrl *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
bool Result = This->AutoCompGetIgnoreCase();
rt.addBool(Result);
- break;
+ break;
}
-case wxStyledTextCtrl_UserListShow: { // wxStyledTextCtrl::UserListShow
+case wxStyledTextCtrl_UserListShow: { // wxStyledTextCtrl::UserListShow
wxStyledTextCtrl *This = (wxStyledTextCtrl *) getPtr(bp,memenv); bp += 4;
int * listType = (int *) bp; bp += 4;
int * itemListLen = (int *) bp; bp += 4;
@@ -27716,287 +27758,287 @@ case wxStyledTextCtrl_UserListShow: { // wxStyledTextCtrl::UserListShow
bp += *itemListLen+((8-((4+ *itemListLen) & 7)) & 7);
if(!This) throw wxe_badarg(0);
This->UserListShow((int) *listType,itemList);
- break;
+ break;
}
-case wxStyledTextCtrl_AutoCompSetAutoHide: { // wxStyledTextCtrl::AutoCompSetAutoHide
+case wxStyledTextCtrl_AutoCompSetAutoHide: { // wxStyledTextCtrl::AutoCompSetAutoHide
wxStyledTextCtrl *This = (wxStyledTextCtrl *) getPtr(bp,memenv); bp += 4;
bool * autoHide = (bool *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
This->AutoCompSetAutoHide((bool) *autoHide);
- break;
+ break;
}
-case wxStyledTextCtrl_AutoCompGetAutoHide: { // wxStyledTextCtrl::AutoCompGetAutoHide
+case wxStyledTextCtrl_AutoCompGetAutoHide: { // wxStyledTextCtrl::AutoCompGetAutoHide
wxStyledTextCtrl *This = (wxStyledTextCtrl *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
bool Result = This->AutoCompGetAutoHide();
rt.addBool(Result);
- break;
+ break;
}
-case wxStyledTextCtrl_AutoCompSetDropRestOfWord: { // wxStyledTextCtrl::AutoCompSetDropRestOfWord
+case wxStyledTextCtrl_AutoCompSetDropRestOfWord: { // wxStyledTextCtrl::AutoCompSetDropRestOfWord
wxStyledTextCtrl *This = (wxStyledTextCtrl *) getPtr(bp,memenv); bp += 4;
bool * dropRestOfWord = (bool *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
This->AutoCompSetDropRestOfWord((bool) *dropRestOfWord);
- break;
+ break;
}
-case wxStyledTextCtrl_AutoCompGetDropRestOfWord: { // wxStyledTextCtrl::AutoCompGetDropRestOfWord
+case wxStyledTextCtrl_AutoCompGetDropRestOfWord: { // wxStyledTextCtrl::AutoCompGetDropRestOfWord
wxStyledTextCtrl *This = (wxStyledTextCtrl *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
bool Result = This->AutoCompGetDropRestOfWord();
rt.addBool(Result);
- break;
+ break;
}
-case wxStyledTextCtrl_RegisterImage: { // wxStyledTextCtrl::RegisterImage
+case wxStyledTextCtrl_RegisterImage: { // wxStyledTextCtrl::RegisterImage
wxStyledTextCtrl *This = (wxStyledTextCtrl *) getPtr(bp,memenv); bp += 4;
int * type = (int *) bp; bp += 4;
wxBitmap *bmp = (wxBitmap *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
This->RegisterImage((int) *type,*bmp);
- break;
+ break;
}
-case wxStyledTextCtrl_ClearRegisteredImages: { // wxStyledTextCtrl::ClearRegisteredImages
+case wxStyledTextCtrl_ClearRegisteredImages: { // wxStyledTextCtrl::ClearRegisteredImages
wxStyledTextCtrl *This = (wxStyledTextCtrl *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
This->ClearRegisteredImages();
- break;
+ break;
}
-case wxStyledTextCtrl_AutoCompGetTypeSeparator: { // wxStyledTextCtrl::AutoCompGetTypeSeparator
+case wxStyledTextCtrl_AutoCompGetTypeSeparator: { // wxStyledTextCtrl::AutoCompGetTypeSeparator
wxStyledTextCtrl *This = (wxStyledTextCtrl *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
int Result = This->AutoCompGetTypeSeparator();
rt.addInt(Result);
- break;
+ break;
}
-case wxStyledTextCtrl_AutoCompSetTypeSeparator: { // wxStyledTextCtrl::AutoCompSetTypeSeparator
+case wxStyledTextCtrl_AutoCompSetTypeSeparator: { // wxStyledTextCtrl::AutoCompSetTypeSeparator
wxStyledTextCtrl *This = (wxStyledTextCtrl *) getPtr(bp,memenv); bp += 4;
int * separatorCharacter = (int *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
This->AutoCompSetTypeSeparator((int) *separatorCharacter);
- break;
+ break;
}
-case wxStyledTextCtrl_AutoCompSetMaxWidth: { // wxStyledTextCtrl::AutoCompSetMaxWidth
+case wxStyledTextCtrl_AutoCompSetMaxWidth: { // wxStyledTextCtrl::AutoCompSetMaxWidth
wxStyledTextCtrl *This = (wxStyledTextCtrl *) getPtr(bp,memenv); bp += 4;
int * characterCount = (int *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
This->AutoCompSetMaxWidth((int) *characterCount);
- break;
+ break;
}
-case wxStyledTextCtrl_AutoCompGetMaxWidth: { // wxStyledTextCtrl::AutoCompGetMaxWidth
+case wxStyledTextCtrl_AutoCompGetMaxWidth: { // wxStyledTextCtrl::AutoCompGetMaxWidth
wxStyledTextCtrl *This = (wxStyledTextCtrl *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
int Result = This->AutoCompGetMaxWidth();
rt.addInt(Result);
- break;
+ break;
}
-case wxStyledTextCtrl_AutoCompSetMaxHeight: { // wxStyledTextCtrl::AutoCompSetMaxHeight
+case wxStyledTextCtrl_AutoCompSetMaxHeight: { // wxStyledTextCtrl::AutoCompSetMaxHeight
wxStyledTextCtrl *This = (wxStyledTextCtrl *) getPtr(bp,memenv); bp += 4;
int * rowCount = (int *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
This->AutoCompSetMaxHeight((int) *rowCount);
- break;
+ break;
}
-case wxStyledTextCtrl_AutoCompGetMaxHeight: { // wxStyledTextCtrl::AutoCompGetMaxHeight
+case wxStyledTextCtrl_AutoCompGetMaxHeight: { // wxStyledTextCtrl::AutoCompGetMaxHeight
wxStyledTextCtrl *This = (wxStyledTextCtrl *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
int Result = This->AutoCompGetMaxHeight();
rt.addInt(Result);
- break;
+ break;
}
-case wxStyledTextCtrl_SetIndent: { // wxStyledTextCtrl::SetIndent
+case wxStyledTextCtrl_SetIndent: { // wxStyledTextCtrl::SetIndent
wxStyledTextCtrl *This = (wxStyledTextCtrl *) getPtr(bp,memenv); bp += 4;
int * indentSize = (int *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
This->SetIndent((int) *indentSize);
- break;
+ break;
}
-case wxStyledTextCtrl_GetIndent: { // wxStyledTextCtrl::GetIndent
+case wxStyledTextCtrl_GetIndent: { // wxStyledTextCtrl::GetIndent
wxStyledTextCtrl *This = (wxStyledTextCtrl *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
int Result = This->GetIndent();
rt.addInt(Result);
- break;
+ break;
}
-case wxStyledTextCtrl_SetUseTabs: { // wxStyledTextCtrl::SetUseTabs
+case wxStyledTextCtrl_SetUseTabs: { // wxStyledTextCtrl::SetUseTabs
wxStyledTextCtrl *This = (wxStyledTextCtrl *) getPtr(bp,memenv); bp += 4;
bool * useTabs = (bool *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
This->SetUseTabs((bool) *useTabs);
- break;
+ break;
}
-case wxStyledTextCtrl_GetUseTabs: { // wxStyledTextCtrl::GetUseTabs
+case wxStyledTextCtrl_GetUseTabs: { // wxStyledTextCtrl::GetUseTabs
wxStyledTextCtrl *This = (wxStyledTextCtrl *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
bool Result = This->GetUseTabs();
rt.addBool(Result);
- break;
+ break;
}
-case wxStyledTextCtrl_SetLineIndentation: { // wxStyledTextCtrl::SetLineIndentation
+case wxStyledTextCtrl_SetLineIndentation: { // wxStyledTextCtrl::SetLineIndentation
wxStyledTextCtrl *This = (wxStyledTextCtrl *) getPtr(bp,memenv); bp += 4;
int * line = (int *) bp; bp += 4;
int * indentSize = (int *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
This->SetLineIndentation((int) *line,(int) *indentSize);
- break;
+ break;
}
-case wxStyledTextCtrl_GetLineIndentation: { // wxStyledTextCtrl::GetLineIndentation
+case wxStyledTextCtrl_GetLineIndentation: { // wxStyledTextCtrl::GetLineIndentation
wxStyledTextCtrl *This = (wxStyledTextCtrl *) getPtr(bp,memenv); bp += 4;
int * line = (int *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
int Result = This->GetLineIndentation((int) *line);
rt.addInt(Result);
- break;
+ break;
}
-case wxStyledTextCtrl_GetLineIndentPosition: { // wxStyledTextCtrl::GetLineIndentPosition
+case wxStyledTextCtrl_GetLineIndentPosition: { // wxStyledTextCtrl::GetLineIndentPosition
wxStyledTextCtrl *This = (wxStyledTextCtrl *) getPtr(bp,memenv); bp += 4;
int * line = (int *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
int Result = This->GetLineIndentPosition((int) *line);
rt.addInt(Result);
- break;
+ break;
}
-case wxStyledTextCtrl_GetColumn: { // wxStyledTextCtrl::GetColumn
+case wxStyledTextCtrl_GetColumn: { // wxStyledTextCtrl::GetColumn
wxStyledTextCtrl *This = (wxStyledTextCtrl *) getPtr(bp,memenv); bp += 4;
int * pos = (int *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
int Result = This->GetColumn((int) *pos);
rt.addInt(Result);
- break;
+ break;
}
-case wxStyledTextCtrl_SetUseHorizontalScrollBar: { // wxStyledTextCtrl::SetUseHorizontalScrollBar
+case wxStyledTextCtrl_SetUseHorizontalScrollBar: { // wxStyledTextCtrl::SetUseHorizontalScrollBar
wxStyledTextCtrl *This = (wxStyledTextCtrl *) getPtr(bp,memenv); bp += 4;
bool * show = (bool *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
This->SetUseHorizontalScrollBar((bool) *show);
- break;
+ break;
}
-case wxStyledTextCtrl_GetUseHorizontalScrollBar: { // wxStyledTextCtrl::GetUseHorizontalScrollBar
+case wxStyledTextCtrl_GetUseHorizontalScrollBar: { // wxStyledTextCtrl::GetUseHorizontalScrollBar
wxStyledTextCtrl *This = (wxStyledTextCtrl *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
bool Result = This->GetUseHorizontalScrollBar();
rt.addBool(Result);
- break;
+ break;
}
-case wxStyledTextCtrl_SetIndentationGuides: { // wxStyledTextCtrl::SetIndentationGuides
+case wxStyledTextCtrl_SetIndentationGuides: { // wxStyledTextCtrl::SetIndentationGuides
wxStyledTextCtrl *This = (wxStyledTextCtrl *) getPtr(bp,memenv); bp += 4;
bool * show = (bool *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
This->SetIndentationGuides((bool) *show);
- break;
+ break;
}
-case wxStyledTextCtrl_GetIndentationGuides: { // wxStyledTextCtrl::GetIndentationGuides
+case wxStyledTextCtrl_GetIndentationGuides: { // wxStyledTextCtrl::GetIndentationGuides
wxStyledTextCtrl *This = (wxStyledTextCtrl *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
bool Result = This->GetIndentationGuides();
rt.addBool(Result);
- break;
+ break;
}
-case wxStyledTextCtrl_SetHighlightGuide: { // wxStyledTextCtrl::SetHighlightGuide
+case wxStyledTextCtrl_SetHighlightGuide: { // wxStyledTextCtrl::SetHighlightGuide
wxStyledTextCtrl *This = (wxStyledTextCtrl *) getPtr(bp,memenv); bp += 4;
int * column = (int *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
This->SetHighlightGuide((int) *column);
- break;
+ break;
}
-case wxStyledTextCtrl_GetHighlightGuide: { // wxStyledTextCtrl::GetHighlightGuide
+case wxStyledTextCtrl_GetHighlightGuide: { // wxStyledTextCtrl::GetHighlightGuide
wxStyledTextCtrl *This = (wxStyledTextCtrl *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
int Result = This->GetHighlightGuide();
rt.addInt(Result);
- break;
+ break;
}
-case wxStyledTextCtrl_GetLineEndPosition: { // wxStyledTextCtrl::GetLineEndPosition
+case wxStyledTextCtrl_GetLineEndPosition: { // wxStyledTextCtrl::GetLineEndPosition
wxStyledTextCtrl *This = (wxStyledTextCtrl *) getPtr(bp,memenv); bp += 4;
int * line = (int *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
int Result = This->GetLineEndPosition((int) *line);
rt.addInt(Result);
- break;
+ break;
}
-case wxStyledTextCtrl_GetCodePage: { // wxStyledTextCtrl::GetCodePage
+case wxStyledTextCtrl_GetCodePage: { // wxStyledTextCtrl::GetCodePage
wxStyledTextCtrl *This = (wxStyledTextCtrl *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
int Result = This->GetCodePage();
rt.addInt(Result);
- break;
+ break;
}
-case wxStyledTextCtrl_GetCaretForeground: { // wxStyledTextCtrl::GetCaretForeground
+case wxStyledTextCtrl_GetCaretForeground: { // wxStyledTextCtrl::GetCaretForeground
wxStyledTextCtrl *This = (wxStyledTextCtrl *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
wxColour Result = This->GetCaretForeground();
rt.add(Result);
- break;
+ break;
}
-case wxStyledTextCtrl_GetReadOnly: { // wxStyledTextCtrl::GetReadOnly
+case wxStyledTextCtrl_GetReadOnly: { // wxStyledTextCtrl::GetReadOnly
wxStyledTextCtrl *This = (wxStyledTextCtrl *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
bool Result = This->GetReadOnly();
rt.addBool(Result);
- break;
+ break;
}
-case wxStyledTextCtrl_SetCurrentPos: { // wxStyledTextCtrl::SetCurrentPos
+case wxStyledTextCtrl_SetCurrentPos: { // wxStyledTextCtrl::SetCurrentPos
wxStyledTextCtrl *This = (wxStyledTextCtrl *) getPtr(bp,memenv); bp += 4;
int * pos = (int *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
This->SetCurrentPos((int) *pos);
- break;
+ break;
}
-case wxStyledTextCtrl_SetSelectionStart: { // wxStyledTextCtrl::SetSelectionStart
+case wxStyledTextCtrl_SetSelectionStart: { // wxStyledTextCtrl::SetSelectionStart
wxStyledTextCtrl *This = (wxStyledTextCtrl *) getPtr(bp,memenv); bp += 4;
int * pos = (int *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
This->SetSelectionStart((int) *pos);
- break;
+ break;
}
-case wxStyledTextCtrl_GetSelectionStart: { // wxStyledTextCtrl::GetSelectionStart
+case wxStyledTextCtrl_GetSelectionStart: { // wxStyledTextCtrl::GetSelectionStart
wxStyledTextCtrl *This = (wxStyledTextCtrl *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
int Result = This->GetSelectionStart();
rt.addInt(Result);
- break;
+ break;
}
-case wxStyledTextCtrl_SetSelectionEnd: { // wxStyledTextCtrl::SetSelectionEnd
+case wxStyledTextCtrl_SetSelectionEnd: { // wxStyledTextCtrl::SetSelectionEnd
wxStyledTextCtrl *This = (wxStyledTextCtrl *) getPtr(bp,memenv); bp += 4;
int * pos = (int *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
This->SetSelectionEnd((int) *pos);
- break;
+ break;
}
-case wxStyledTextCtrl_GetSelectionEnd: { // wxStyledTextCtrl::GetSelectionEnd
+case wxStyledTextCtrl_GetSelectionEnd: { // wxStyledTextCtrl::GetSelectionEnd
wxStyledTextCtrl *This = (wxStyledTextCtrl *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
int Result = This->GetSelectionEnd();
rt.addInt(Result);
- break;
+ break;
}
-case wxStyledTextCtrl_SetPrintMagnification: { // wxStyledTextCtrl::SetPrintMagnification
+case wxStyledTextCtrl_SetPrintMagnification: { // wxStyledTextCtrl::SetPrintMagnification
wxStyledTextCtrl *This = (wxStyledTextCtrl *) getPtr(bp,memenv); bp += 4;
int * magnification = (int *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
This->SetPrintMagnification((int) *magnification);
- break;
+ break;
}
-case wxStyledTextCtrl_GetPrintMagnification: { // wxStyledTextCtrl::GetPrintMagnification
+case wxStyledTextCtrl_GetPrintMagnification: { // wxStyledTextCtrl::GetPrintMagnification
wxStyledTextCtrl *This = (wxStyledTextCtrl *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
int Result = This->GetPrintMagnification();
rt.addInt(Result);
- break;
+ break;
}
-case wxStyledTextCtrl_SetPrintColourMode: { // wxStyledTextCtrl::SetPrintColourMode
+case wxStyledTextCtrl_SetPrintColourMode: { // wxStyledTextCtrl::SetPrintColourMode
wxStyledTextCtrl *This = (wxStyledTextCtrl *) getPtr(bp,memenv); bp += 4;
int * mode = (int *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
This->SetPrintColourMode((int) *mode);
- break;
+ break;
}
-case wxStyledTextCtrl_GetPrintColourMode: { // wxStyledTextCtrl::GetPrintColourMode
+case wxStyledTextCtrl_GetPrintColourMode: { // wxStyledTextCtrl::GetPrintColourMode
wxStyledTextCtrl *This = (wxStyledTextCtrl *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
int Result = This->GetPrintColourMode();
rt.addInt(Result);
- break;
+ break;
}
-case wxStyledTextCtrl_FindText: { // wxStyledTextCtrl::FindText
+case wxStyledTextCtrl_FindText: { // wxStyledTextCtrl::FindText
int flags=0;
wxStyledTextCtrl *This = (wxStyledTextCtrl *) getPtr(bp,memenv); bp += 4;
int * minPos = (int *) bp; bp += 4;
@@ -28004,17 +28046,17 @@ case wxStyledTextCtrl_FindText: { // wxStyledTextCtrl::FindText
int * textLen = (int *) bp; bp += 4;
wxString text = wxString(bp, wxConvUTF8);
bp += *textLen+((8-((0+ *textLen) & 7)) & 7);
- while( * (int*) bp) { switch (* (int*) bp) {
+ while( * (int*) bp) { switch (* (int*) bp) {
case 1: {bp += 4;
flags = (int)*(int *) bp; bp += 4;
} break;
- }};
+ }};
if(!This) throw wxe_badarg(0);
int Result = This->FindText((int) *minPos,(int) *maxPos,text,flags);
rt.addInt(Result);
- break;
+ break;
}
-case wxStyledTextCtrl_FormatRange: { // wxStyledTextCtrl::FormatRange
+case wxStyledTextCtrl_FormatRange: { // wxStyledTextCtrl::FormatRange
wxStyledTextCtrl *This = (wxStyledTextCtrl *) getPtr(bp,memenv); bp += 4;
bool * doDraw = (bool *) bp; bp += 4;
int * startPos = (int *) bp; bp += 4;
@@ -28034,265 +28076,265 @@ case wxStyledTextCtrl_FormatRange: { // wxStyledTextCtrl::FormatRange
if(!This) throw wxe_badarg(0);
int Result = This->FormatRange((bool) *doDraw,(int) *startPos,(int) *endPos,draw,target,renderRect,pageRect);
rt.addInt(Result);
- break;
+ break;
}
-case wxStyledTextCtrl_GetFirstVisibleLine: { // wxStyledTextCtrl::GetFirstVisibleLine
+case wxStyledTextCtrl_GetFirstVisibleLine: { // wxStyledTextCtrl::GetFirstVisibleLine
wxStyledTextCtrl *This = (wxStyledTextCtrl *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
int Result = This->GetFirstVisibleLine();
rt.addInt(Result);
- break;
+ break;
}
-case wxStyledTextCtrl_GetLine: { // wxStyledTextCtrl::GetLine
+case wxStyledTextCtrl_GetLine: { // wxStyledTextCtrl::GetLine
wxStyledTextCtrl *This = (wxStyledTextCtrl *) getPtr(bp,memenv); bp += 4;
int * line = (int *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
wxString Result = This->GetLine((int) *line);
rt.add(Result);
- break;
+ break;
}
-case wxStyledTextCtrl_GetLineCount: { // wxStyledTextCtrl::GetLineCount
+case wxStyledTextCtrl_GetLineCount: { // wxStyledTextCtrl::GetLineCount
wxStyledTextCtrl *This = (wxStyledTextCtrl *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
int Result = This->GetLineCount();
rt.addInt(Result);
- break;
+ break;
}
-case wxStyledTextCtrl_SetMarginLeft: { // wxStyledTextCtrl::SetMarginLeft
+case wxStyledTextCtrl_SetMarginLeft: { // wxStyledTextCtrl::SetMarginLeft
wxStyledTextCtrl *This = (wxStyledTextCtrl *) getPtr(bp,memenv); bp += 4;
int * pixelWidth = (int *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
This->SetMarginLeft((int) *pixelWidth);
- break;
+ break;
}
-case wxStyledTextCtrl_GetMarginLeft: { // wxStyledTextCtrl::GetMarginLeft
+case wxStyledTextCtrl_GetMarginLeft: { // wxStyledTextCtrl::GetMarginLeft
wxStyledTextCtrl *This = (wxStyledTextCtrl *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
int Result = This->GetMarginLeft();
rt.addInt(Result);
- break;
+ break;
}
-case wxStyledTextCtrl_SetMarginRight: { // wxStyledTextCtrl::SetMarginRight
+case wxStyledTextCtrl_SetMarginRight: { // wxStyledTextCtrl::SetMarginRight
wxStyledTextCtrl *This = (wxStyledTextCtrl *) getPtr(bp,memenv); bp += 4;
int * pixelWidth = (int *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
This->SetMarginRight((int) *pixelWidth);
- break;
+ break;
}
-case wxStyledTextCtrl_GetMarginRight: { // wxStyledTextCtrl::GetMarginRight
+case wxStyledTextCtrl_GetMarginRight: { // wxStyledTextCtrl::GetMarginRight
wxStyledTextCtrl *This = (wxStyledTextCtrl *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
int Result = This->GetMarginRight();
rt.addInt(Result);
- break;
+ break;
}
-case wxStyledTextCtrl_GetModify: { // wxStyledTextCtrl::GetModify
+case wxStyledTextCtrl_GetModify: { // wxStyledTextCtrl::GetModify
wxStyledTextCtrl *This = (wxStyledTextCtrl *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
bool Result = This->GetModify();
rt.addBool(Result);
- break;
+ break;
}
-case wxStyledTextCtrl_SetSelection: { // wxStyledTextCtrl::SetSelection
+case wxStyledTextCtrl_SetSelection: { // wxStyledTextCtrl::SetSelection
wxStyledTextCtrl *This = (wxStyledTextCtrl *) getPtr(bp,memenv); bp += 4;
int * start = (int *) bp; bp += 4;
int * end = (int *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
This->SetSelection((int) *start,(int) *end);
- break;
+ break;
}
-case wxStyledTextCtrl_GetSelectedText: { // wxStyledTextCtrl::GetSelectedText
+case wxStyledTextCtrl_GetSelectedText: { // wxStyledTextCtrl::GetSelectedText
wxStyledTextCtrl *This = (wxStyledTextCtrl *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
wxString Result = This->GetSelectedText();
rt.add(Result);
- break;
+ break;
}
-case wxStyledTextCtrl_GetTextRange: { // wxStyledTextCtrl::GetTextRange
+case wxStyledTextCtrl_GetTextRange: { // wxStyledTextCtrl::GetTextRange
wxStyledTextCtrl *This = (wxStyledTextCtrl *) getPtr(bp,memenv); bp += 4;
int * startPos = (int *) bp; bp += 4;
int * endPos = (int *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
wxString Result = This->GetTextRange((int) *startPos,(int) *endPos);
rt.add(Result);
- break;
+ break;
}
-case wxStyledTextCtrl_HideSelection: { // wxStyledTextCtrl::HideSelection
+case wxStyledTextCtrl_HideSelection: { // wxStyledTextCtrl::HideSelection
wxStyledTextCtrl *This = (wxStyledTextCtrl *) getPtr(bp,memenv); bp += 4;
bool * normal = (bool *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
This->HideSelection((bool) *normal);
- break;
+ break;
}
-case wxStyledTextCtrl_LineFromPosition: { // wxStyledTextCtrl::LineFromPosition
+case wxStyledTextCtrl_LineFromPosition: { // wxStyledTextCtrl::LineFromPosition
wxStyledTextCtrl *This = (wxStyledTextCtrl *) getPtr(bp,memenv); bp += 4;
int * pos = (int *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
int Result = This->LineFromPosition((int) *pos);
rt.addInt(Result);
- break;
+ break;
}
-case wxStyledTextCtrl_PositionFromLine: { // wxStyledTextCtrl::PositionFromLine
+case wxStyledTextCtrl_PositionFromLine: { // wxStyledTextCtrl::PositionFromLine
wxStyledTextCtrl *This = (wxStyledTextCtrl *) getPtr(bp,memenv); bp += 4;
int * line = (int *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
int Result = This->PositionFromLine((int) *line);
rt.addInt(Result);
- break;
+ break;
}
-case wxStyledTextCtrl_LineScroll: { // wxStyledTextCtrl::LineScroll
+case wxStyledTextCtrl_LineScroll: { // wxStyledTextCtrl::LineScroll
wxStyledTextCtrl *This = (wxStyledTextCtrl *) getPtr(bp,memenv); bp += 4;
int * columns = (int *) bp; bp += 4;
int * lines = (int *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
This->LineScroll((int) *columns,(int) *lines);
- break;
+ break;
}
-case wxStyledTextCtrl_EnsureCaretVisible: { // wxStyledTextCtrl::EnsureCaretVisible
+case wxStyledTextCtrl_EnsureCaretVisible: { // wxStyledTextCtrl::EnsureCaretVisible
wxStyledTextCtrl *This = (wxStyledTextCtrl *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
This->EnsureCaretVisible();
- break;
+ break;
}
-case wxStyledTextCtrl_ReplaceSelection: { // wxStyledTextCtrl::ReplaceSelection
+case wxStyledTextCtrl_ReplaceSelection: { // wxStyledTextCtrl::ReplaceSelection
wxStyledTextCtrl *This = (wxStyledTextCtrl *) getPtr(bp,memenv); bp += 4;
int * textLen = (int *) bp; bp += 4;
wxString text = wxString(bp, wxConvUTF8);
bp += *textLen+((8-((0+ *textLen) & 7)) & 7);
if(!This) throw wxe_badarg(0);
This->ReplaceSelection(text);
- break;
+ break;
}
-case wxStyledTextCtrl_SetReadOnly: { // wxStyledTextCtrl::SetReadOnly
+case wxStyledTextCtrl_SetReadOnly: { // wxStyledTextCtrl::SetReadOnly
wxStyledTextCtrl *This = (wxStyledTextCtrl *) getPtr(bp,memenv); bp += 4;
bool * readOnly = (bool *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
This->SetReadOnly((bool) *readOnly);
- break;
+ break;
}
-case wxStyledTextCtrl_CanPaste: { // wxStyledTextCtrl::CanPaste
+case wxStyledTextCtrl_CanPaste: { // wxStyledTextCtrl::CanPaste
wxStyledTextCtrl *This = (wxStyledTextCtrl *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
bool Result = This->CanPaste();
rt.addBool(Result);
- break;
+ break;
}
-case wxStyledTextCtrl_CanUndo: { // wxStyledTextCtrl::CanUndo
+case wxStyledTextCtrl_CanUndo: { // wxStyledTextCtrl::CanUndo
wxStyledTextCtrl *This = (wxStyledTextCtrl *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
bool Result = This->CanUndo();
rt.addBool(Result);
- break;
+ break;
}
-case wxStyledTextCtrl_EmptyUndoBuffer: { // wxStyledTextCtrl::EmptyUndoBuffer
+case wxStyledTextCtrl_EmptyUndoBuffer: { // wxStyledTextCtrl::EmptyUndoBuffer
wxStyledTextCtrl *This = (wxStyledTextCtrl *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
This->EmptyUndoBuffer();
- break;
+ break;
}
-case wxStyledTextCtrl_Undo: { // wxStyledTextCtrl::Undo
+case wxStyledTextCtrl_Undo: { // wxStyledTextCtrl::Undo
wxStyledTextCtrl *This = (wxStyledTextCtrl *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
This->Undo();
- break;
+ break;
}
-case wxStyledTextCtrl_Cut: { // wxStyledTextCtrl::Cut
+case wxStyledTextCtrl_Cut: { // wxStyledTextCtrl::Cut
wxStyledTextCtrl *This = (wxStyledTextCtrl *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
This->Cut();
- break;
+ break;
}
-case wxStyledTextCtrl_Copy: { // wxStyledTextCtrl::Copy
+case wxStyledTextCtrl_Copy: { // wxStyledTextCtrl::Copy
wxStyledTextCtrl *This = (wxStyledTextCtrl *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
This->Copy();
- break;
+ break;
}
-case wxStyledTextCtrl_Paste: { // wxStyledTextCtrl::Paste
+case wxStyledTextCtrl_Paste: { // wxStyledTextCtrl::Paste
wxStyledTextCtrl *This = (wxStyledTextCtrl *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
This->Paste();
- break;
+ break;
}
-case wxStyledTextCtrl_Clear: { // wxStyledTextCtrl::Clear
+case wxStyledTextCtrl_Clear: { // wxStyledTextCtrl::Clear
wxStyledTextCtrl *This = (wxStyledTextCtrl *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
This->Clear();
- break;
+ break;
}
-case wxStyledTextCtrl_SetText: { // wxStyledTextCtrl::SetText
+case wxStyledTextCtrl_SetText: { // wxStyledTextCtrl::SetText
wxStyledTextCtrl *This = (wxStyledTextCtrl *) getPtr(bp,memenv); bp += 4;
int * textLen = (int *) bp; bp += 4;
wxString text = wxString(bp, wxConvUTF8);
bp += *textLen+((8-((0+ *textLen) & 7)) & 7);
if(!This) throw wxe_badarg(0);
This->SetText(text);
- break;
+ break;
}
-case wxStyledTextCtrl_GetText: { // wxStyledTextCtrl::GetText
+case wxStyledTextCtrl_GetText: { // wxStyledTextCtrl::GetText
wxStyledTextCtrl *This = (wxStyledTextCtrl *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
wxString Result = This->GetText();
rt.add(Result);
- break;
+ break;
}
-case wxStyledTextCtrl_GetTextLength: { // wxStyledTextCtrl::GetTextLength
+case wxStyledTextCtrl_GetTextLength: { // wxStyledTextCtrl::GetTextLength
wxStyledTextCtrl *This = (wxStyledTextCtrl *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
int Result = This->GetTextLength();
rt.addInt(Result);
- break;
+ break;
}
-case wxStyledTextCtrl_GetOvertype: { // wxStyledTextCtrl::GetOvertype
+case wxStyledTextCtrl_GetOvertype: { // wxStyledTextCtrl::GetOvertype
wxStyledTextCtrl *This = (wxStyledTextCtrl *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
bool Result = This->GetOvertype();
rt.addBool(Result);
- break;
+ break;
}
-case wxStyledTextCtrl_SetCaretWidth: { // wxStyledTextCtrl::SetCaretWidth
+case wxStyledTextCtrl_SetCaretWidth: { // wxStyledTextCtrl::SetCaretWidth
wxStyledTextCtrl *This = (wxStyledTextCtrl *) getPtr(bp,memenv); bp += 4;
int * pixelWidth = (int *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
This->SetCaretWidth((int) *pixelWidth);
- break;
+ break;
}
-case wxStyledTextCtrl_GetCaretWidth: { // wxStyledTextCtrl::GetCaretWidth
+case wxStyledTextCtrl_GetCaretWidth: { // wxStyledTextCtrl::GetCaretWidth
wxStyledTextCtrl *This = (wxStyledTextCtrl *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
int Result = This->GetCaretWidth();
rt.addInt(Result);
- break;
+ break;
}
-case wxStyledTextCtrl_SetTargetStart: { // wxStyledTextCtrl::SetTargetStart
+case wxStyledTextCtrl_SetTargetStart: { // wxStyledTextCtrl::SetTargetStart
wxStyledTextCtrl *This = (wxStyledTextCtrl *) getPtr(bp,memenv); bp += 4;
int * pos = (int *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
This->SetTargetStart((int) *pos);
- break;
+ break;
}
-case wxStyledTextCtrl_GetTargetStart: { // wxStyledTextCtrl::GetTargetStart
+case wxStyledTextCtrl_GetTargetStart: { // wxStyledTextCtrl::GetTargetStart
wxStyledTextCtrl *This = (wxStyledTextCtrl *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
int Result = This->GetTargetStart();
rt.addInt(Result);
- break;
+ break;
}
-case wxStyledTextCtrl_SetTargetEnd: { // wxStyledTextCtrl::SetTargetEnd
+case wxStyledTextCtrl_SetTargetEnd: { // wxStyledTextCtrl::SetTargetEnd
wxStyledTextCtrl *This = (wxStyledTextCtrl *) getPtr(bp,memenv); bp += 4;
int * pos = (int *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
This->SetTargetEnd((int) *pos);
- break;
+ break;
}
-case wxStyledTextCtrl_GetTargetEnd: { // wxStyledTextCtrl::GetTargetEnd
+case wxStyledTextCtrl_GetTargetEnd: { // wxStyledTextCtrl::GetTargetEnd
wxStyledTextCtrl *This = (wxStyledTextCtrl *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
int Result = This->GetTargetEnd();
rt.addInt(Result);
- break;
+ break;
}
-case wxStyledTextCtrl_ReplaceTarget: { // wxStyledTextCtrl::ReplaceTarget
+case wxStyledTextCtrl_ReplaceTarget: { // wxStyledTextCtrl::ReplaceTarget
wxStyledTextCtrl *This = (wxStyledTextCtrl *) getPtr(bp,memenv); bp += 4;
int * textLen = (int *) bp; bp += 4;
wxString text = wxString(bp, wxConvUTF8);
@@ -28300,9 +28342,9 @@ case wxStyledTextCtrl_ReplaceTarget: { // wxStyledTextCtrl::ReplaceTarget
if(!This) throw wxe_badarg(0);
int Result = This->ReplaceTarget(text);
rt.addInt(Result);
- break;
+ break;
}
-case wxStyledTextCtrl_SearchInTarget: { // wxStyledTextCtrl::SearchInTarget
+case wxStyledTextCtrl_SearchInTarget: { // wxStyledTextCtrl::SearchInTarget
wxStyledTextCtrl *This = (wxStyledTextCtrl *) getPtr(bp,memenv); bp += 4;
int * textLen = (int *) bp; bp += 4;
wxString text = wxString(bp, wxConvUTF8);
@@ -28310,23 +28352,23 @@ case wxStyledTextCtrl_SearchInTarget: { // wxStyledTextCtrl::SearchInTarget
if(!This) throw wxe_badarg(0);
int Result = This->SearchInTarget(text);
rt.addInt(Result);
- break;
+ break;
}
-case wxStyledTextCtrl_SetSearchFlags: { // wxStyledTextCtrl::SetSearchFlags
+case wxStyledTextCtrl_SetSearchFlags: { // wxStyledTextCtrl::SetSearchFlags
wxStyledTextCtrl *This = (wxStyledTextCtrl *) getPtr(bp,memenv); bp += 4;
int * flags = (int *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
This->SetSearchFlags((int) *flags);
- break;
+ break;
}
-case wxStyledTextCtrl_GetSearchFlags: { // wxStyledTextCtrl::GetSearchFlags
+case wxStyledTextCtrl_GetSearchFlags: { // wxStyledTextCtrl::GetSearchFlags
wxStyledTextCtrl *This = (wxStyledTextCtrl *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
int Result = This->GetSearchFlags();
rt.addInt(Result);
- break;
+ break;
}
-case wxStyledTextCtrl_CallTipShow: { // wxStyledTextCtrl::CallTipShow
+case wxStyledTextCtrl_CallTipShow: { // wxStyledTextCtrl::CallTipShow
wxStyledTextCtrl *This = (wxStyledTextCtrl *) getPtr(bp,memenv); bp += 4;
int * pos = (int *) bp; bp += 4;
int * definitionLen = (int *) bp; bp += 4;
@@ -28334,37 +28376,37 @@ case wxStyledTextCtrl_CallTipShow: { // wxStyledTextCtrl::CallTipShow
bp += *definitionLen+((8-((4+ *definitionLen) & 7)) & 7);
if(!This) throw wxe_badarg(0);
This->CallTipShow((int) *pos,definition);
- break;
+ break;
}
-case wxStyledTextCtrl_CallTipCancel: { // wxStyledTextCtrl::CallTipCancel
+case wxStyledTextCtrl_CallTipCancel: { // wxStyledTextCtrl::CallTipCancel
wxStyledTextCtrl *This = (wxStyledTextCtrl *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
This->CallTipCancel();
- break;
+ break;
}
-case wxStyledTextCtrl_CallTipActive: { // wxStyledTextCtrl::CallTipActive
+case wxStyledTextCtrl_CallTipActive: { // wxStyledTextCtrl::CallTipActive
wxStyledTextCtrl *This = (wxStyledTextCtrl *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
bool Result = This->CallTipActive();
rt.addBool(Result);
- break;
+ break;
}
-case wxStyledTextCtrl_CallTipPosAtStart: { // wxStyledTextCtrl::CallTipPosAtStart
+case wxStyledTextCtrl_CallTipPosAtStart: { // wxStyledTextCtrl::CallTipPosAtStart
wxStyledTextCtrl *This = (wxStyledTextCtrl *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
int Result = This->CallTipPosAtStart();
rt.addInt(Result);
- break;
+ break;
}
-case wxStyledTextCtrl_CallTipSetHighlight: { // wxStyledTextCtrl::CallTipSetHighlight
+case wxStyledTextCtrl_CallTipSetHighlight: { // wxStyledTextCtrl::CallTipSetHighlight
wxStyledTextCtrl *This = (wxStyledTextCtrl *) getPtr(bp,memenv); bp += 4;
int * start = (int *) bp; bp += 4;
int * end = (int *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
This->CallTipSetHighlight((int) *start,(int) *end);
- break;
+ break;
}
-case wxStyledTextCtrl_CallTipSetBackground: { // wxStyledTextCtrl::CallTipSetBackground
+case wxStyledTextCtrl_CallTipSetBackground: { // wxStyledTextCtrl::CallTipSetBackground
wxStyledTextCtrl *This = (wxStyledTextCtrl *) getPtr(bp,memenv); bp += 4;
int * backR = (int *) bp; bp += 4;
int * backG = (int *) bp; bp += 4;
@@ -28373,9 +28415,9 @@ case wxStyledTextCtrl_CallTipSetBackground: { // wxStyledTextCtrl::CallTipSetBac
wxColour back = wxColour(*backR,*backG,*backB,*backA);
if(!This) throw wxe_badarg(0);
This->CallTipSetBackground(back);
- break;
+ break;
}
-case wxStyledTextCtrl_CallTipSetForeground: { // wxStyledTextCtrl::CallTipSetForeground
+case wxStyledTextCtrl_CallTipSetForeground: { // wxStyledTextCtrl::CallTipSetForeground
wxStyledTextCtrl *This = (wxStyledTextCtrl *) getPtr(bp,memenv); bp += 4;
int * foreR = (int *) bp; bp += 4;
int * foreG = (int *) bp; bp += 4;
@@ -28384,9 +28426,9 @@ case wxStyledTextCtrl_CallTipSetForeground: { // wxStyledTextCtrl::CallTipSetFor
wxColour fore = wxColour(*foreR,*foreG,*foreB,*foreA);
if(!This) throw wxe_badarg(0);
This->CallTipSetForeground(fore);
- break;
+ break;
}
-case wxStyledTextCtrl_CallTipSetForegroundHighlight: { // wxStyledTextCtrl::CallTipSetForegroundHighlight
+case wxStyledTextCtrl_CallTipSetForegroundHighlight: { // wxStyledTextCtrl::CallTipSetForegroundHighlight
wxStyledTextCtrl *This = (wxStyledTextCtrl *) getPtr(bp,memenv); bp += 4;
int * foreR = (int *) bp; bp += 4;
int * foreG = (int *) bp; bp += 4;
@@ -28395,285 +28437,285 @@ case wxStyledTextCtrl_CallTipSetForegroundHighlight: { // wxStyledTextCtrl::Call
wxColour fore = wxColour(*foreR,*foreG,*foreB,*foreA);
if(!This) throw wxe_badarg(0);
This->CallTipSetForegroundHighlight(fore);
- break;
+ break;
}
-case wxStyledTextCtrl_CallTipUseStyle: { // wxStyledTextCtrl::CallTipUseStyle
+case wxStyledTextCtrl_CallTipUseStyle: { // wxStyledTextCtrl::CallTipUseStyle
wxStyledTextCtrl *This = (wxStyledTextCtrl *) getPtr(bp,memenv); bp += 4;
int * tabSize = (int *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
This->CallTipUseStyle((int) *tabSize);
- break;
+ break;
}
-case wxStyledTextCtrl_VisibleFromDocLine: { // wxStyledTextCtrl::VisibleFromDocLine
+case wxStyledTextCtrl_VisibleFromDocLine: { // wxStyledTextCtrl::VisibleFromDocLine
wxStyledTextCtrl *This = (wxStyledTextCtrl *) getPtr(bp,memenv); bp += 4;
int * line = (int *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
int Result = This->VisibleFromDocLine((int) *line);
rt.addInt(Result);
- break;
+ break;
}
-case wxStyledTextCtrl_DocLineFromVisible: { // wxStyledTextCtrl::DocLineFromVisible
+case wxStyledTextCtrl_DocLineFromVisible: { // wxStyledTextCtrl::DocLineFromVisible
wxStyledTextCtrl *This = (wxStyledTextCtrl *) getPtr(bp,memenv); bp += 4;
int * lineDisplay = (int *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
int Result = This->DocLineFromVisible((int) *lineDisplay);
rt.addInt(Result);
- break;
+ break;
}
-case wxStyledTextCtrl_WrapCount: { // wxStyledTextCtrl::WrapCount
+case wxStyledTextCtrl_WrapCount: { // wxStyledTextCtrl::WrapCount
wxStyledTextCtrl *This = (wxStyledTextCtrl *) getPtr(bp,memenv); bp += 4;
int * line = (int *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
int Result = This->WrapCount((int) *line);
rt.addInt(Result);
- break;
+ break;
}
-case wxStyledTextCtrl_SetFoldLevel: { // wxStyledTextCtrl::SetFoldLevel
+case wxStyledTextCtrl_SetFoldLevel: { // wxStyledTextCtrl::SetFoldLevel
wxStyledTextCtrl *This = (wxStyledTextCtrl *) getPtr(bp,memenv); bp += 4;
int * line = (int *) bp; bp += 4;
int * level = (int *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
This->SetFoldLevel((int) *line,(int) *level);
- break;
+ break;
}
-case wxStyledTextCtrl_GetFoldLevel: { // wxStyledTextCtrl::GetFoldLevel
+case wxStyledTextCtrl_GetFoldLevel: { // wxStyledTextCtrl::GetFoldLevel
wxStyledTextCtrl *This = (wxStyledTextCtrl *) getPtr(bp,memenv); bp += 4;
int * line = (int *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
int Result = This->GetFoldLevel((int) *line);
rt.addInt(Result);
- break;
+ break;
}
-case wxStyledTextCtrl_GetLastChild: { // wxStyledTextCtrl::GetLastChild
+case wxStyledTextCtrl_GetLastChild: { // wxStyledTextCtrl::GetLastChild
wxStyledTextCtrl *This = (wxStyledTextCtrl *) getPtr(bp,memenv); bp += 4;
int * line = (int *) bp; bp += 4;
int * level = (int *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
int Result = This->GetLastChild((int) *line,(int) *level);
rt.addInt(Result);
- break;
+ break;
}
-case wxStyledTextCtrl_GetFoldParent: { // wxStyledTextCtrl::GetFoldParent
+case wxStyledTextCtrl_GetFoldParent: { // wxStyledTextCtrl::GetFoldParent
wxStyledTextCtrl *This = (wxStyledTextCtrl *) getPtr(bp,memenv); bp += 4;
int * line = (int *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
int Result = This->GetFoldParent((int) *line);
rt.addInt(Result);
- break;
+ break;
}
-case wxStyledTextCtrl_ShowLines: { // wxStyledTextCtrl::ShowLines
+case wxStyledTextCtrl_ShowLines: { // wxStyledTextCtrl::ShowLines
wxStyledTextCtrl *This = (wxStyledTextCtrl *) getPtr(bp,memenv); bp += 4;
int * lineStart = (int *) bp; bp += 4;
int * lineEnd = (int *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
This->ShowLines((int) *lineStart,(int) *lineEnd);
- break;
+ break;
}
-case wxStyledTextCtrl_HideLines: { // wxStyledTextCtrl::HideLines
+case wxStyledTextCtrl_HideLines: { // wxStyledTextCtrl::HideLines
wxStyledTextCtrl *This = (wxStyledTextCtrl *) getPtr(bp,memenv); bp += 4;
int * lineStart = (int *) bp; bp += 4;
int * lineEnd = (int *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
This->HideLines((int) *lineStart,(int) *lineEnd);
- break;
+ break;
}
-case wxStyledTextCtrl_GetLineVisible: { // wxStyledTextCtrl::GetLineVisible
+case wxStyledTextCtrl_GetLineVisible: { // wxStyledTextCtrl::GetLineVisible
wxStyledTextCtrl *This = (wxStyledTextCtrl *) getPtr(bp,memenv); bp += 4;
int * line = (int *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
bool Result = This->GetLineVisible((int) *line);
rt.addBool(Result);
- break;
+ break;
}
-case wxStyledTextCtrl_SetFoldExpanded: { // wxStyledTextCtrl::SetFoldExpanded
+case wxStyledTextCtrl_SetFoldExpanded: { // wxStyledTextCtrl::SetFoldExpanded
wxStyledTextCtrl *This = (wxStyledTextCtrl *) getPtr(bp,memenv); bp += 4;
int * line = (int *) bp; bp += 4;
bool * expanded = (bool *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
This->SetFoldExpanded((int) *line,(bool) *expanded);
- break;
+ break;
}
-case wxStyledTextCtrl_GetFoldExpanded: { // wxStyledTextCtrl::GetFoldExpanded
+case wxStyledTextCtrl_GetFoldExpanded: { // wxStyledTextCtrl::GetFoldExpanded
wxStyledTextCtrl *This = (wxStyledTextCtrl *) getPtr(bp,memenv); bp += 4;
int * line = (int *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
bool Result = This->GetFoldExpanded((int) *line);
rt.addBool(Result);
- break;
+ break;
}
-case wxStyledTextCtrl_ToggleFold: { // wxStyledTextCtrl::ToggleFold
+case wxStyledTextCtrl_ToggleFold: { // wxStyledTextCtrl::ToggleFold
wxStyledTextCtrl *This = (wxStyledTextCtrl *) getPtr(bp,memenv); bp += 4;
int * line = (int *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
This->ToggleFold((int) *line);
- break;
+ break;
}
-case wxStyledTextCtrl_EnsureVisible: { // wxStyledTextCtrl::EnsureVisible
+case wxStyledTextCtrl_EnsureVisible: { // wxStyledTextCtrl::EnsureVisible
wxStyledTextCtrl *This = (wxStyledTextCtrl *) getPtr(bp,memenv); bp += 4;
int * line = (int *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
This->EnsureVisible((int) *line);
- break;
+ break;
}
-case wxStyledTextCtrl_SetFoldFlags: { // wxStyledTextCtrl::SetFoldFlags
+case wxStyledTextCtrl_SetFoldFlags: { // wxStyledTextCtrl::SetFoldFlags
wxStyledTextCtrl *This = (wxStyledTextCtrl *) getPtr(bp,memenv); bp += 4;
int * flags = (int *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
This->SetFoldFlags((int) *flags);
- break;
+ break;
}
-case wxStyledTextCtrl_EnsureVisibleEnforcePolicy: { // wxStyledTextCtrl::EnsureVisibleEnforcePolicy
+case wxStyledTextCtrl_EnsureVisibleEnforcePolicy: { // wxStyledTextCtrl::EnsureVisibleEnforcePolicy
wxStyledTextCtrl *This = (wxStyledTextCtrl *) getPtr(bp,memenv); bp += 4;
int * line = (int *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
This->EnsureVisibleEnforcePolicy((int) *line);
- break;
+ break;
}
-case wxStyledTextCtrl_SetTabIndents: { // wxStyledTextCtrl::SetTabIndents
+case wxStyledTextCtrl_SetTabIndents: { // wxStyledTextCtrl::SetTabIndents
wxStyledTextCtrl *This = (wxStyledTextCtrl *) getPtr(bp,memenv); bp += 4;
bool * tabIndents = (bool *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
This->SetTabIndents((bool) *tabIndents);
- break;
+ break;
}
-case wxStyledTextCtrl_GetTabIndents: { // wxStyledTextCtrl::GetTabIndents
+case wxStyledTextCtrl_GetTabIndents: { // wxStyledTextCtrl::GetTabIndents
wxStyledTextCtrl *This = (wxStyledTextCtrl *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
bool Result = This->GetTabIndents();
rt.addBool(Result);
- break;
+ break;
}
-case wxStyledTextCtrl_SetBackSpaceUnIndents: { // wxStyledTextCtrl::SetBackSpaceUnIndents
+case wxStyledTextCtrl_SetBackSpaceUnIndents: { // wxStyledTextCtrl::SetBackSpaceUnIndents
wxStyledTextCtrl *This = (wxStyledTextCtrl *) getPtr(bp,memenv); bp += 4;
bool * bsUnIndents = (bool *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
This->SetBackSpaceUnIndents((bool) *bsUnIndents);
- break;
+ break;
}
-case wxStyledTextCtrl_GetBackSpaceUnIndents: { // wxStyledTextCtrl::GetBackSpaceUnIndents
+case wxStyledTextCtrl_GetBackSpaceUnIndents: { // wxStyledTextCtrl::GetBackSpaceUnIndents
wxStyledTextCtrl *This = (wxStyledTextCtrl *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
bool Result = This->GetBackSpaceUnIndents();
rt.addBool(Result);
- break;
+ break;
}
-case wxStyledTextCtrl_SetMouseDwellTime: { // wxStyledTextCtrl::SetMouseDwellTime
+case wxStyledTextCtrl_SetMouseDwellTime: { // wxStyledTextCtrl::SetMouseDwellTime
wxStyledTextCtrl *This = (wxStyledTextCtrl *) getPtr(bp,memenv); bp += 4;
int * periodMilliseconds = (int *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
This->SetMouseDwellTime((int) *periodMilliseconds);
- break;
+ break;
}
-case wxStyledTextCtrl_GetMouseDwellTime: { // wxStyledTextCtrl::GetMouseDwellTime
+case wxStyledTextCtrl_GetMouseDwellTime: { // wxStyledTextCtrl::GetMouseDwellTime
wxStyledTextCtrl *This = (wxStyledTextCtrl *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
int Result = This->GetMouseDwellTime();
rt.addInt(Result);
- break;
+ break;
}
-case wxStyledTextCtrl_WordStartPosition: { // wxStyledTextCtrl::WordStartPosition
+case wxStyledTextCtrl_WordStartPosition: { // wxStyledTextCtrl::WordStartPosition
wxStyledTextCtrl *This = (wxStyledTextCtrl *) getPtr(bp,memenv); bp += 4;
int * pos = (int *) bp; bp += 4;
bool * onlyWordCharacters = (bool *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
int Result = This->WordStartPosition((int) *pos,(bool) *onlyWordCharacters);
rt.addInt(Result);
- break;
+ break;
}
-case wxStyledTextCtrl_WordEndPosition: { // wxStyledTextCtrl::WordEndPosition
+case wxStyledTextCtrl_WordEndPosition: { // wxStyledTextCtrl::WordEndPosition
wxStyledTextCtrl *This = (wxStyledTextCtrl *) getPtr(bp,memenv); bp += 4;
int * pos = (int *) bp; bp += 4;
bool * onlyWordCharacters = (bool *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
int Result = This->WordEndPosition((int) *pos,(bool) *onlyWordCharacters);
rt.addInt(Result);
- break;
+ break;
}
-case wxStyledTextCtrl_SetWrapMode: { // wxStyledTextCtrl::SetWrapMode
+case wxStyledTextCtrl_SetWrapMode: { // wxStyledTextCtrl::SetWrapMode
wxStyledTextCtrl *This = (wxStyledTextCtrl *) getPtr(bp,memenv); bp += 4;
int * mode = (int *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
This->SetWrapMode((int) *mode);
- break;
+ break;
}
-case wxStyledTextCtrl_GetWrapMode: { // wxStyledTextCtrl::GetWrapMode
+case wxStyledTextCtrl_GetWrapMode: { // wxStyledTextCtrl::GetWrapMode
wxStyledTextCtrl *This = (wxStyledTextCtrl *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
int Result = This->GetWrapMode();
rt.addInt(Result);
- break;
+ break;
}
-case wxStyledTextCtrl_SetWrapVisualFlags: { // wxStyledTextCtrl::SetWrapVisualFlags
+case wxStyledTextCtrl_SetWrapVisualFlags: { // wxStyledTextCtrl::SetWrapVisualFlags
wxStyledTextCtrl *This = (wxStyledTextCtrl *) getPtr(bp,memenv); bp += 4;
int * wrapVisualFlags = (int *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
This->SetWrapVisualFlags((int) *wrapVisualFlags);
- break;
+ break;
}
-case wxStyledTextCtrl_GetWrapVisualFlags: { // wxStyledTextCtrl::GetWrapVisualFlags
+case wxStyledTextCtrl_GetWrapVisualFlags: { // wxStyledTextCtrl::GetWrapVisualFlags
wxStyledTextCtrl *This = (wxStyledTextCtrl *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
int Result = This->GetWrapVisualFlags();
rt.addInt(Result);
- break;
+ break;
}
-case wxStyledTextCtrl_SetWrapVisualFlagsLocation: { // wxStyledTextCtrl::SetWrapVisualFlagsLocation
+case wxStyledTextCtrl_SetWrapVisualFlagsLocation: { // wxStyledTextCtrl::SetWrapVisualFlagsLocation
wxStyledTextCtrl *This = (wxStyledTextCtrl *) getPtr(bp,memenv); bp += 4;
int * wrapVisualFlagsLocation = (int *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
This->SetWrapVisualFlagsLocation((int) *wrapVisualFlagsLocation);
- break;
+ break;
}
-case wxStyledTextCtrl_GetWrapVisualFlagsLocation: { // wxStyledTextCtrl::GetWrapVisualFlagsLocation
+case wxStyledTextCtrl_GetWrapVisualFlagsLocation: { // wxStyledTextCtrl::GetWrapVisualFlagsLocation
wxStyledTextCtrl *This = (wxStyledTextCtrl *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
int Result = This->GetWrapVisualFlagsLocation();
rt.addInt(Result);
- break;
+ break;
}
-case wxStyledTextCtrl_SetWrapStartIndent: { // wxStyledTextCtrl::SetWrapStartIndent
+case wxStyledTextCtrl_SetWrapStartIndent: { // wxStyledTextCtrl::SetWrapStartIndent
wxStyledTextCtrl *This = (wxStyledTextCtrl *) getPtr(bp,memenv); bp += 4;
int * indent = (int *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
This->SetWrapStartIndent((int) *indent);
- break;
+ break;
}
-case wxStyledTextCtrl_GetWrapStartIndent: { // wxStyledTextCtrl::GetWrapStartIndent
+case wxStyledTextCtrl_GetWrapStartIndent: { // wxStyledTextCtrl::GetWrapStartIndent
wxStyledTextCtrl *This = (wxStyledTextCtrl *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
int Result = This->GetWrapStartIndent();
rt.addInt(Result);
- break;
+ break;
}
-case wxStyledTextCtrl_SetLayoutCache: { // wxStyledTextCtrl::SetLayoutCache
+case wxStyledTextCtrl_SetLayoutCache: { // wxStyledTextCtrl::SetLayoutCache
wxStyledTextCtrl *This = (wxStyledTextCtrl *) getPtr(bp,memenv); bp += 4;
int * mode = (int *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
This->SetLayoutCache((int) *mode);
- break;
+ break;
}
-case wxStyledTextCtrl_GetLayoutCache: { // wxStyledTextCtrl::GetLayoutCache
+case wxStyledTextCtrl_GetLayoutCache: { // wxStyledTextCtrl::GetLayoutCache
wxStyledTextCtrl *This = (wxStyledTextCtrl *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
int Result = This->GetLayoutCache();
rt.addInt(Result);
- break;
+ break;
}
-case wxStyledTextCtrl_SetScrollWidth: { // wxStyledTextCtrl::SetScrollWidth
+case wxStyledTextCtrl_SetScrollWidth: { // wxStyledTextCtrl::SetScrollWidth
wxStyledTextCtrl *This = (wxStyledTextCtrl *) getPtr(bp,memenv); bp += 4;
int * pixelWidth = (int *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
This->SetScrollWidth((int) *pixelWidth);
- break;
+ break;
}
-case wxStyledTextCtrl_GetScrollWidth: { // wxStyledTextCtrl::GetScrollWidth
+case wxStyledTextCtrl_GetScrollWidth: { // wxStyledTextCtrl::GetScrollWidth
wxStyledTextCtrl *This = (wxStyledTextCtrl *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
int Result = This->GetScrollWidth();
rt.addInt(Result);
- break;
+ break;
}
-case wxStyledTextCtrl_TextWidth: { // wxStyledTextCtrl::TextWidth
+case wxStyledTextCtrl_TextWidth: { // wxStyledTextCtrl::TextWidth
wxStyledTextCtrl *This = (wxStyledTextCtrl *) getPtr(bp,memenv); bp += 4;
int * style = (int *) bp; bp += 4;
int * textLen = (int *) bp; bp += 4;
@@ -28682,80 +28724,80 @@ case wxStyledTextCtrl_TextWidth: { // wxStyledTextCtrl::TextWidth
if(!This) throw wxe_badarg(0);
int Result = This->TextWidth((int) *style,text);
rt.addInt(Result);
- break;
+ break;
}
-case wxStyledTextCtrl_GetEndAtLastLine: { // wxStyledTextCtrl::GetEndAtLastLine
+case wxStyledTextCtrl_GetEndAtLastLine: { // wxStyledTextCtrl::GetEndAtLastLine
wxStyledTextCtrl *This = (wxStyledTextCtrl *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
bool Result = This->GetEndAtLastLine();
rt.addBool(Result);
- break;
+ break;
}
-case wxStyledTextCtrl_TextHeight: { // wxStyledTextCtrl::TextHeight
+case wxStyledTextCtrl_TextHeight: { // wxStyledTextCtrl::TextHeight
wxStyledTextCtrl *This = (wxStyledTextCtrl *) getPtr(bp,memenv); bp += 4;
int * line = (int *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
int Result = This->TextHeight((int) *line);
rt.addInt(Result);
- break;
+ break;
}
-case wxStyledTextCtrl_SetUseVerticalScrollBar: { // wxStyledTextCtrl::SetUseVerticalScrollBar
+case wxStyledTextCtrl_SetUseVerticalScrollBar: { // wxStyledTextCtrl::SetUseVerticalScrollBar
wxStyledTextCtrl *This = (wxStyledTextCtrl *) getPtr(bp,memenv); bp += 4;
bool * show = (bool *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
This->SetUseVerticalScrollBar((bool) *show);
- break;
+ break;
}
-case wxStyledTextCtrl_GetUseVerticalScrollBar: { // wxStyledTextCtrl::GetUseVerticalScrollBar
+case wxStyledTextCtrl_GetUseVerticalScrollBar: { // wxStyledTextCtrl::GetUseVerticalScrollBar
wxStyledTextCtrl *This = (wxStyledTextCtrl *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
bool Result = This->GetUseVerticalScrollBar();
rt.addBool(Result);
- break;
+ break;
}
-case wxStyledTextCtrl_AppendText: { // wxStyledTextCtrl::AppendText
+case wxStyledTextCtrl_AppendText: { // wxStyledTextCtrl::AppendText
wxStyledTextCtrl *This = (wxStyledTextCtrl *) getPtr(bp,memenv); bp += 4;
int * textLen = (int *) bp; bp += 4;
wxString text = wxString(bp, wxConvUTF8);
bp += *textLen+((8-((0+ *textLen) & 7)) & 7);
if(!This) throw wxe_badarg(0);
This->AppendText(text);
- break;
+ break;
}
-case wxStyledTextCtrl_GetTwoPhaseDraw: { // wxStyledTextCtrl::GetTwoPhaseDraw
+case wxStyledTextCtrl_GetTwoPhaseDraw: { // wxStyledTextCtrl::GetTwoPhaseDraw
wxStyledTextCtrl *This = (wxStyledTextCtrl *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
bool Result = This->GetTwoPhaseDraw();
rt.addBool(Result);
- break;
+ break;
}
-case wxStyledTextCtrl_SetTwoPhaseDraw: { // wxStyledTextCtrl::SetTwoPhaseDraw
+case wxStyledTextCtrl_SetTwoPhaseDraw: { // wxStyledTextCtrl::SetTwoPhaseDraw
wxStyledTextCtrl *This = (wxStyledTextCtrl *) getPtr(bp,memenv); bp += 4;
bool * twoPhase = (bool *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
This->SetTwoPhaseDraw((bool) *twoPhase);
- break;
+ break;
}
-case wxStyledTextCtrl_TargetFromSelection: { // wxStyledTextCtrl::TargetFromSelection
+case wxStyledTextCtrl_TargetFromSelection: { // wxStyledTextCtrl::TargetFromSelection
wxStyledTextCtrl *This = (wxStyledTextCtrl *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
This->TargetFromSelection();
- break;
+ break;
}
-case wxStyledTextCtrl_LinesJoin: { // wxStyledTextCtrl::LinesJoin
+case wxStyledTextCtrl_LinesJoin: { // wxStyledTextCtrl::LinesJoin
wxStyledTextCtrl *This = (wxStyledTextCtrl *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
This->LinesJoin();
- break;
+ break;
}
-case wxStyledTextCtrl_LinesSplit: { // wxStyledTextCtrl::LinesSplit
+case wxStyledTextCtrl_LinesSplit: { // wxStyledTextCtrl::LinesSplit
wxStyledTextCtrl *This = (wxStyledTextCtrl *) getPtr(bp,memenv); bp += 4;
int * pixelWidth = (int *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
This->LinesSplit((int) *pixelWidth);
- break;
+ break;
}
-case wxStyledTextCtrl_SetFoldMarginColour: { // wxStyledTextCtrl::SetFoldMarginColour
+case wxStyledTextCtrl_SetFoldMarginColour: { // wxStyledTextCtrl::SetFoldMarginColour
wxStyledTextCtrl *This = (wxStyledTextCtrl *) getPtr(bp,memenv); bp += 4;
bool * useSetting = (bool *) bp; bp += 4;
int * backR = (int *) bp; bp += 4;
@@ -28765,9 +28807,9 @@ case wxStyledTextCtrl_SetFoldMarginColour: { // wxStyledTextCtrl::SetFoldMarginC
wxColour back = wxColour(*backR,*backG,*backB,*backA);
if(!This) throw wxe_badarg(0);
This->SetFoldMarginColour((bool) *useSetting,back);
- break;
+ break;
}
-case wxStyledTextCtrl_SetFoldMarginHiColour: { // wxStyledTextCtrl::SetFoldMarginHiColour
+case wxStyledTextCtrl_SetFoldMarginHiColour: { // wxStyledTextCtrl::SetFoldMarginHiColour
wxStyledTextCtrl *This = (wxStyledTextCtrl *) getPtr(bp,memenv); bp += 4;
bool * useSetting = (bool *) bp; bp += 4;
int * foreR = (int *) bp; bp += 4;
@@ -28777,431 +28819,431 @@ case wxStyledTextCtrl_SetFoldMarginHiColour: { // wxStyledTextCtrl::SetFoldMargi
wxColour fore = wxColour(*foreR,*foreG,*foreB,*foreA);
if(!This) throw wxe_badarg(0);
This->SetFoldMarginHiColour((bool) *useSetting,fore);
- break;
+ break;
}
-case wxStyledTextCtrl_LineDown: { // wxStyledTextCtrl::LineDown
+case wxStyledTextCtrl_LineDown: { // wxStyledTextCtrl::LineDown
wxStyledTextCtrl *This = (wxStyledTextCtrl *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
This->LineDown();
- break;
+ break;
}
-case wxStyledTextCtrl_LineDownExtend: { // wxStyledTextCtrl::LineDownExtend
+case wxStyledTextCtrl_LineDownExtend: { // wxStyledTextCtrl::LineDownExtend
wxStyledTextCtrl *This = (wxStyledTextCtrl *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
This->LineDownExtend();
- break;
+ break;
}
-case wxStyledTextCtrl_LineUp: { // wxStyledTextCtrl::LineUp
+case wxStyledTextCtrl_LineUp: { // wxStyledTextCtrl::LineUp
wxStyledTextCtrl *This = (wxStyledTextCtrl *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
This->LineUp();
- break;
+ break;
}
-case wxStyledTextCtrl_LineUpExtend: { // wxStyledTextCtrl::LineUpExtend
+case wxStyledTextCtrl_LineUpExtend: { // wxStyledTextCtrl::LineUpExtend
wxStyledTextCtrl *This = (wxStyledTextCtrl *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
This->LineUpExtend();
- break;
+ break;
}
-case wxStyledTextCtrl_CharLeft: { // wxStyledTextCtrl::CharLeft
+case wxStyledTextCtrl_CharLeft: { // wxStyledTextCtrl::CharLeft
wxStyledTextCtrl *This = (wxStyledTextCtrl *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
This->CharLeft();
- break;
+ break;
}
-case wxStyledTextCtrl_CharLeftExtend: { // wxStyledTextCtrl::CharLeftExtend
+case wxStyledTextCtrl_CharLeftExtend: { // wxStyledTextCtrl::CharLeftExtend
wxStyledTextCtrl *This = (wxStyledTextCtrl *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
This->CharLeftExtend();
- break;
+ break;
}
-case wxStyledTextCtrl_CharRight: { // wxStyledTextCtrl::CharRight
+case wxStyledTextCtrl_CharRight: { // wxStyledTextCtrl::CharRight
wxStyledTextCtrl *This = (wxStyledTextCtrl *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
This->CharRight();
- break;
+ break;
}
-case wxStyledTextCtrl_CharRightExtend: { // wxStyledTextCtrl::CharRightExtend
+case wxStyledTextCtrl_CharRightExtend: { // wxStyledTextCtrl::CharRightExtend
wxStyledTextCtrl *This = (wxStyledTextCtrl *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
This->CharRightExtend();
- break;
+ break;
}
-case wxStyledTextCtrl_WordLeft: { // wxStyledTextCtrl::WordLeft
+case wxStyledTextCtrl_WordLeft: { // wxStyledTextCtrl::WordLeft
wxStyledTextCtrl *This = (wxStyledTextCtrl *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
This->WordLeft();
- break;
+ break;
}
-case wxStyledTextCtrl_WordLeftExtend: { // wxStyledTextCtrl::WordLeftExtend
+case wxStyledTextCtrl_WordLeftExtend: { // wxStyledTextCtrl::WordLeftExtend
wxStyledTextCtrl *This = (wxStyledTextCtrl *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
This->WordLeftExtend();
- break;
+ break;
}
-case wxStyledTextCtrl_WordRight: { // wxStyledTextCtrl::WordRight
+case wxStyledTextCtrl_WordRight: { // wxStyledTextCtrl::WordRight
wxStyledTextCtrl *This = (wxStyledTextCtrl *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
This->WordRight();
- break;
+ break;
}
-case wxStyledTextCtrl_WordRightExtend: { // wxStyledTextCtrl::WordRightExtend
+case wxStyledTextCtrl_WordRightExtend: { // wxStyledTextCtrl::WordRightExtend
wxStyledTextCtrl *This = (wxStyledTextCtrl *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
This->WordRightExtend();
- break;
+ break;
}
-case wxStyledTextCtrl_Home: { // wxStyledTextCtrl::Home
+case wxStyledTextCtrl_Home: { // wxStyledTextCtrl::Home
wxStyledTextCtrl *This = (wxStyledTextCtrl *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
This->Home();
- break;
+ break;
}
-case wxStyledTextCtrl_HomeExtend: { // wxStyledTextCtrl::HomeExtend
+case wxStyledTextCtrl_HomeExtend: { // wxStyledTextCtrl::HomeExtend
wxStyledTextCtrl *This = (wxStyledTextCtrl *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
This->HomeExtend();
- break;
+ break;
}
-case wxStyledTextCtrl_LineEnd: { // wxStyledTextCtrl::LineEnd
+case wxStyledTextCtrl_LineEnd: { // wxStyledTextCtrl::LineEnd
wxStyledTextCtrl *This = (wxStyledTextCtrl *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
This->LineEnd();
- break;
+ break;
}
-case wxStyledTextCtrl_LineEndExtend: { // wxStyledTextCtrl::LineEndExtend
+case wxStyledTextCtrl_LineEndExtend: { // wxStyledTextCtrl::LineEndExtend
wxStyledTextCtrl *This = (wxStyledTextCtrl *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
This->LineEndExtend();
- break;
+ break;
}
-case wxStyledTextCtrl_DocumentStart: { // wxStyledTextCtrl::DocumentStart
+case wxStyledTextCtrl_DocumentStart: { // wxStyledTextCtrl::DocumentStart
wxStyledTextCtrl *This = (wxStyledTextCtrl *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
This->DocumentStart();
- break;
+ break;
}
-case wxStyledTextCtrl_DocumentStartExtend: { // wxStyledTextCtrl::DocumentStartExtend
+case wxStyledTextCtrl_DocumentStartExtend: { // wxStyledTextCtrl::DocumentStartExtend
wxStyledTextCtrl *This = (wxStyledTextCtrl *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
This->DocumentStartExtend();
- break;
+ break;
}
-case wxStyledTextCtrl_DocumentEnd: { // wxStyledTextCtrl::DocumentEnd
+case wxStyledTextCtrl_DocumentEnd: { // wxStyledTextCtrl::DocumentEnd
wxStyledTextCtrl *This = (wxStyledTextCtrl *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
This->DocumentEnd();
- break;
+ break;
}
-case wxStyledTextCtrl_DocumentEndExtend: { // wxStyledTextCtrl::DocumentEndExtend
+case wxStyledTextCtrl_DocumentEndExtend: { // wxStyledTextCtrl::DocumentEndExtend
wxStyledTextCtrl *This = (wxStyledTextCtrl *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
This->DocumentEndExtend();
- break;
+ break;
}
-case wxStyledTextCtrl_PageUp: { // wxStyledTextCtrl::PageUp
+case wxStyledTextCtrl_PageUp: { // wxStyledTextCtrl::PageUp
wxStyledTextCtrl *This = (wxStyledTextCtrl *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
This->PageUp();
- break;
+ break;
}
-case wxStyledTextCtrl_PageUpExtend: { // wxStyledTextCtrl::PageUpExtend
+case wxStyledTextCtrl_PageUpExtend: { // wxStyledTextCtrl::PageUpExtend
wxStyledTextCtrl *This = (wxStyledTextCtrl *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
This->PageUpExtend();
- break;
+ break;
}
-case wxStyledTextCtrl_PageDown: { // wxStyledTextCtrl::PageDown
+case wxStyledTextCtrl_PageDown: { // wxStyledTextCtrl::PageDown
wxStyledTextCtrl *This = (wxStyledTextCtrl *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
This->PageDown();
- break;
+ break;
}
-case wxStyledTextCtrl_PageDownExtend: { // wxStyledTextCtrl::PageDownExtend
+case wxStyledTextCtrl_PageDownExtend: { // wxStyledTextCtrl::PageDownExtend
wxStyledTextCtrl *This = (wxStyledTextCtrl *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
This->PageDownExtend();
- break;
+ break;
}
-case wxStyledTextCtrl_EditToggleOvertype: { // wxStyledTextCtrl::EditToggleOvertype
+case wxStyledTextCtrl_EditToggleOvertype: { // wxStyledTextCtrl::EditToggleOvertype
wxStyledTextCtrl *This = (wxStyledTextCtrl *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
This->EditToggleOvertype();
- break;
+ break;
}
-case wxStyledTextCtrl_Cancel: { // wxStyledTextCtrl::Cancel
+case wxStyledTextCtrl_Cancel: { // wxStyledTextCtrl::Cancel
wxStyledTextCtrl *This = (wxStyledTextCtrl *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
This->Cancel();
- break;
+ break;
}
-case wxStyledTextCtrl_DeleteBack: { // wxStyledTextCtrl::DeleteBack
+case wxStyledTextCtrl_DeleteBack: { // wxStyledTextCtrl::DeleteBack
wxStyledTextCtrl *This = (wxStyledTextCtrl *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
This->DeleteBack();
- break;
+ break;
}
-case wxStyledTextCtrl_Tab: { // wxStyledTextCtrl::Tab
+case wxStyledTextCtrl_Tab: { // wxStyledTextCtrl::Tab
wxStyledTextCtrl *This = (wxStyledTextCtrl *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
This->Tab();
- break;
+ break;
}
-case wxStyledTextCtrl_BackTab: { // wxStyledTextCtrl::BackTab
+case wxStyledTextCtrl_BackTab: { // wxStyledTextCtrl::BackTab
wxStyledTextCtrl *This = (wxStyledTextCtrl *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
This->BackTab();
- break;
+ break;
}
-case wxStyledTextCtrl_NewLine: { // wxStyledTextCtrl::NewLine
+case wxStyledTextCtrl_NewLine: { // wxStyledTextCtrl::NewLine
wxStyledTextCtrl *This = (wxStyledTextCtrl *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
This->NewLine();
- break;
+ break;
}
-case wxStyledTextCtrl_FormFeed: { // wxStyledTextCtrl::FormFeed
+case wxStyledTextCtrl_FormFeed: { // wxStyledTextCtrl::FormFeed
wxStyledTextCtrl *This = (wxStyledTextCtrl *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
This->FormFeed();
- break;
+ break;
}
-case wxStyledTextCtrl_VCHome: { // wxStyledTextCtrl::VCHome
+case wxStyledTextCtrl_VCHome: { // wxStyledTextCtrl::VCHome
wxStyledTextCtrl *This = (wxStyledTextCtrl *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
This->VCHome();
- break;
+ break;
}
-case wxStyledTextCtrl_VCHomeExtend: { // wxStyledTextCtrl::VCHomeExtend
+case wxStyledTextCtrl_VCHomeExtend: { // wxStyledTextCtrl::VCHomeExtend
wxStyledTextCtrl *This = (wxStyledTextCtrl *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
This->VCHomeExtend();
- break;
+ break;
}
-case wxStyledTextCtrl_ZoomIn: { // wxStyledTextCtrl::ZoomIn
+case wxStyledTextCtrl_ZoomIn: { // wxStyledTextCtrl::ZoomIn
wxStyledTextCtrl *This = (wxStyledTextCtrl *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
This->ZoomIn();
- break;
+ break;
}
-case wxStyledTextCtrl_ZoomOut: { // wxStyledTextCtrl::ZoomOut
+case wxStyledTextCtrl_ZoomOut: { // wxStyledTextCtrl::ZoomOut
wxStyledTextCtrl *This = (wxStyledTextCtrl *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
This->ZoomOut();
- break;
+ break;
}
-case wxStyledTextCtrl_DelWordLeft: { // wxStyledTextCtrl::DelWordLeft
+case wxStyledTextCtrl_DelWordLeft: { // wxStyledTextCtrl::DelWordLeft
wxStyledTextCtrl *This = (wxStyledTextCtrl *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
This->DelWordLeft();
- break;
+ break;
}
-case wxStyledTextCtrl_DelWordRight: { // wxStyledTextCtrl::DelWordRight
+case wxStyledTextCtrl_DelWordRight: { // wxStyledTextCtrl::DelWordRight
wxStyledTextCtrl *This = (wxStyledTextCtrl *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
This->DelWordRight();
- break;
+ break;
}
-case wxStyledTextCtrl_LineCut: { // wxStyledTextCtrl::LineCut
+case wxStyledTextCtrl_LineCut: { // wxStyledTextCtrl::LineCut
wxStyledTextCtrl *This = (wxStyledTextCtrl *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
This->LineCut();
- break;
+ break;
}
-case wxStyledTextCtrl_LineDelete: { // wxStyledTextCtrl::LineDelete
+case wxStyledTextCtrl_LineDelete: { // wxStyledTextCtrl::LineDelete
wxStyledTextCtrl *This = (wxStyledTextCtrl *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
This->LineDelete();
- break;
+ break;
}
-case wxStyledTextCtrl_LineTranspose: { // wxStyledTextCtrl::LineTranspose
+case wxStyledTextCtrl_LineTranspose: { // wxStyledTextCtrl::LineTranspose
wxStyledTextCtrl *This = (wxStyledTextCtrl *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
This->LineTranspose();
- break;
+ break;
}
-case wxStyledTextCtrl_LineDuplicate: { // wxStyledTextCtrl::LineDuplicate
+case wxStyledTextCtrl_LineDuplicate: { // wxStyledTextCtrl::LineDuplicate
wxStyledTextCtrl *This = (wxStyledTextCtrl *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
This->LineDuplicate();
- break;
+ break;
}
-case wxStyledTextCtrl_LowerCase: { // wxStyledTextCtrl::LowerCase
+case wxStyledTextCtrl_LowerCase: { // wxStyledTextCtrl::LowerCase
wxStyledTextCtrl *This = (wxStyledTextCtrl *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
This->LowerCase();
- break;
+ break;
}
-case wxStyledTextCtrl_UpperCase: { // wxStyledTextCtrl::UpperCase
+case wxStyledTextCtrl_UpperCase: { // wxStyledTextCtrl::UpperCase
wxStyledTextCtrl *This = (wxStyledTextCtrl *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
This->UpperCase();
- break;
+ break;
}
-case wxStyledTextCtrl_LineScrollDown: { // wxStyledTextCtrl::LineScrollDown
+case wxStyledTextCtrl_LineScrollDown: { // wxStyledTextCtrl::LineScrollDown
wxStyledTextCtrl *This = (wxStyledTextCtrl *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
This->LineScrollDown();
- break;
+ break;
}
-case wxStyledTextCtrl_LineScrollUp: { // wxStyledTextCtrl::LineScrollUp
+case wxStyledTextCtrl_LineScrollUp: { // wxStyledTextCtrl::LineScrollUp
wxStyledTextCtrl *This = (wxStyledTextCtrl *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
This->LineScrollUp();
- break;
+ break;
}
-case wxStyledTextCtrl_DeleteBackNotLine: { // wxStyledTextCtrl::DeleteBackNotLine
+case wxStyledTextCtrl_DeleteBackNotLine: { // wxStyledTextCtrl::DeleteBackNotLine
wxStyledTextCtrl *This = (wxStyledTextCtrl *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
This->DeleteBackNotLine();
- break;
+ break;
}
-case wxStyledTextCtrl_HomeDisplay: { // wxStyledTextCtrl::HomeDisplay
+case wxStyledTextCtrl_HomeDisplay: { // wxStyledTextCtrl::HomeDisplay
wxStyledTextCtrl *This = (wxStyledTextCtrl *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
This->HomeDisplay();
- break;
+ break;
}
-case wxStyledTextCtrl_HomeDisplayExtend: { // wxStyledTextCtrl::HomeDisplayExtend
+case wxStyledTextCtrl_HomeDisplayExtend: { // wxStyledTextCtrl::HomeDisplayExtend
wxStyledTextCtrl *This = (wxStyledTextCtrl *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
This->HomeDisplayExtend();
- break;
+ break;
}
-case wxStyledTextCtrl_LineEndDisplay: { // wxStyledTextCtrl::LineEndDisplay
+case wxStyledTextCtrl_LineEndDisplay: { // wxStyledTextCtrl::LineEndDisplay
wxStyledTextCtrl *This = (wxStyledTextCtrl *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
This->LineEndDisplay();
- break;
+ break;
}
-case wxStyledTextCtrl_LineEndDisplayExtend: { // wxStyledTextCtrl::LineEndDisplayExtend
+case wxStyledTextCtrl_LineEndDisplayExtend: { // wxStyledTextCtrl::LineEndDisplayExtend
wxStyledTextCtrl *This = (wxStyledTextCtrl *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
This->LineEndDisplayExtend();
- break;
+ break;
}
-case wxStyledTextCtrl_HomeWrapExtend: { // wxStyledTextCtrl::HomeWrapExtend
+case wxStyledTextCtrl_HomeWrapExtend: { // wxStyledTextCtrl::HomeWrapExtend
wxStyledTextCtrl *This = (wxStyledTextCtrl *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
This->HomeWrapExtend();
- break;
+ break;
}
-case wxStyledTextCtrl_LineEndWrap: { // wxStyledTextCtrl::LineEndWrap
+case wxStyledTextCtrl_LineEndWrap: { // wxStyledTextCtrl::LineEndWrap
wxStyledTextCtrl *This = (wxStyledTextCtrl *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
This->LineEndWrap();
- break;
+ break;
}
-case wxStyledTextCtrl_LineEndWrapExtend: { // wxStyledTextCtrl::LineEndWrapExtend
+case wxStyledTextCtrl_LineEndWrapExtend: { // wxStyledTextCtrl::LineEndWrapExtend
wxStyledTextCtrl *This = (wxStyledTextCtrl *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
This->LineEndWrapExtend();
- break;
+ break;
}
-case wxStyledTextCtrl_VCHomeWrap: { // wxStyledTextCtrl::VCHomeWrap
+case wxStyledTextCtrl_VCHomeWrap: { // wxStyledTextCtrl::VCHomeWrap
wxStyledTextCtrl *This = (wxStyledTextCtrl *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
This->VCHomeWrap();
- break;
+ break;
}
-case wxStyledTextCtrl_VCHomeWrapExtend: { // wxStyledTextCtrl::VCHomeWrapExtend
+case wxStyledTextCtrl_VCHomeWrapExtend: { // wxStyledTextCtrl::VCHomeWrapExtend
wxStyledTextCtrl *This = (wxStyledTextCtrl *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
This->VCHomeWrapExtend();
- break;
+ break;
}
-case wxStyledTextCtrl_LineCopy: { // wxStyledTextCtrl::LineCopy
+case wxStyledTextCtrl_LineCopy: { // wxStyledTextCtrl::LineCopy
wxStyledTextCtrl *This = (wxStyledTextCtrl *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
This->LineCopy();
- break;
+ break;
}
-case wxStyledTextCtrl_MoveCaretInsideView: { // wxStyledTextCtrl::MoveCaretInsideView
+case wxStyledTextCtrl_MoveCaretInsideView: { // wxStyledTextCtrl::MoveCaretInsideView
wxStyledTextCtrl *This = (wxStyledTextCtrl *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
This->MoveCaretInsideView();
- break;
+ break;
}
-case wxStyledTextCtrl_LineLength: { // wxStyledTextCtrl::LineLength
+case wxStyledTextCtrl_LineLength: { // wxStyledTextCtrl::LineLength
wxStyledTextCtrl *This = (wxStyledTextCtrl *) getPtr(bp,memenv); bp += 4;
int * line = (int *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
int Result = This->LineLength((int) *line);
rt.addInt(Result);
- break;
+ break;
}
-case wxStyledTextCtrl_BraceHighlight: { // wxStyledTextCtrl::BraceHighlight
+case wxStyledTextCtrl_BraceHighlight: { // wxStyledTextCtrl::BraceHighlight
wxStyledTextCtrl *This = (wxStyledTextCtrl *) getPtr(bp,memenv); bp += 4;
int * pos1 = (int *) bp; bp += 4;
int * pos2 = (int *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
This->BraceHighlight((int) *pos1,(int) *pos2);
- break;
+ break;
}
-case wxStyledTextCtrl_BraceBadLight: { // wxStyledTextCtrl::BraceBadLight
+case wxStyledTextCtrl_BraceBadLight: { // wxStyledTextCtrl::BraceBadLight
wxStyledTextCtrl *This = (wxStyledTextCtrl *) getPtr(bp,memenv); bp += 4;
int * pos = (int *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
This->BraceBadLight((int) *pos);
- break;
+ break;
}
-case wxStyledTextCtrl_BraceMatch: { // wxStyledTextCtrl::BraceMatch
+case wxStyledTextCtrl_BraceMatch: { // wxStyledTextCtrl::BraceMatch
wxStyledTextCtrl *This = (wxStyledTextCtrl *) getPtr(bp,memenv); bp += 4;
int * pos = (int *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
int Result = This->BraceMatch((int) *pos);
rt.addInt(Result);
- break;
+ break;
}
-case wxStyledTextCtrl_GetViewEOL: { // wxStyledTextCtrl::GetViewEOL
+case wxStyledTextCtrl_GetViewEOL: { // wxStyledTextCtrl::GetViewEOL
wxStyledTextCtrl *This = (wxStyledTextCtrl *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
bool Result = This->GetViewEOL();
rt.addBool(Result);
- break;
+ break;
}
-case wxStyledTextCtrl_SetViewEOL: { // wxStyledTextCtrl::SetViewEOL
+case wxStyledTextCtrl_SetViewEOL: { // wxStyledTextCtrl::SetViewEOL
wxStyledTextCtrl *This = (wxStyledTextCtrl *) getPtr(bp,memenv); bp += 4;
bool * visible = (bool *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
This->SetViewEOL((bool) *visible);
- break;
+ break;
}
-case wxStyledTextCtrl_SetModEventMask: { // wxStyledTextCtrl::SetModEventMask
+case wxStyledTextCtrl_SetModEventMask: { // wxStyledTextCtrl::SetModEventMask
wxStyledTextCtrl *This = (wxStyledTextCtrl *) getPtr(bp,memenv); bp += 4;
int * mask = (int *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
This->SetModEventMask((int) *mask);
- break;
+ break;
}
-case wxStyledTextCtrl_GetEdgeColumn: { // wxStyledTextCtrl::GetEdgeColumn
+case wxStyledTextCtrl_GetEdgeColumn: { // wxStyledTextCtrl::GetEdgeColumn
wxStyledTextCtrl *This = (wxStyledTextCtrl *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
int Result = This->GetEdgeColumn();
rt.addInt(Result);
- break;
+ break;
}
-case wxStyledTextCtrl_SetEdgeColumn: { // wxStyledTextCtrl::SetEdgeColumn
+case wxStyledTextCtrl_SetEdgeColumn: { // wxStyledTextCtrl::SetEdgeColumn
wxStyledTextCtrl *This = (wxStyledTextCtrl *) getPtr(bp,memenv); bp += 4;
int * column = (int *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
This->SetEdgeColumn((int) *column);
- break;
+ break;
}
-case wxStyledTextCtrl_GetEdgeMode: { // wxStyledTextCtrl::GetEdgeMode
+case wxStyledTextCtrl_GetEdgeMode: { // wxStyledTextCtrl::GetEdgeMode
wxStyledTextCtrl *This = (wxStyledTextCtrl *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
int Result = This->GetEdgeMode();
rt.addInt(Result);
- break;
+ break;
}
-case wxStyledTextCtrl_GetEdgeColour: { // wxStyledTextCtrl::GetEdgeColour
+case wxStyledTextCtrl_GetEdgeColour: { // wxStyledTextCtrl::GetEdgeColour
wxStyledTextCtrl *This = (wxStyledTextCtrl *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
wxColour Result = This->GetEdgeColour();
rt.add(Result);
- break;
+ break;
}
-case wxStyledTextCtrl_SetEdgeColour: { // wxStyledTextCtrl::SetEdgeColour
+case wxStyledTextCtrl_SetEdgeColour: { // wxStyledTextCtrl::SetEdgeColour
wxStyledTextCtrl *This = (wxStyledTextCtrl *) getPtr(bp,memenv); bp += 4;
int * edgeColourR = (int *) bp; bp += 4;
int * edgeColourG = (int *) bp; bp += 4;
@@ -29210,15 +29252,15 @@ case wxStyledTextCtrl_SetEdgeColour: { // wxStyledTextCtrl::SetEdgeColour
wxColour edgeColour = wxColour(*edgeColourR,*edgeColourG,*edgeColourB,*edgeColourA);
if(!This) throw wxe_badarg(0);
This->SetEdgeColour(edgeColour);
- break;
+ break;
}
-case wxStyledTextCtrl_SearchAnchor: { // wxStyledTextCtrl::SearchAnchor
+case wxStyledTextCtrl_SearchAnchor: { // wxStyledTextCtrl::SearchAnchor
wxStyledTextCtrl *This = (wxStyledTextCtrl *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
This->SearchAnchor();
- break;
+ break;
}
-case wxStyledTextCtrl_SearchNext: { // wxStyledTextCtrl::SearchNext
+case wxStyledTextCtrl_SearchNext: { // wxStyledTextCtrl::SearchNext
wxStyledTextCtrl *This = (wxStyledTextCtrl *) getPtr(bp,memenv); bp += 4;
int * flags = (int *) bp; bp += 4;
int * textLen = (int *) bp; bp += 4;
@@ -29227,9 +29269,9 @@ case wxStyledTextCtrl_SearchNext: { // wxStyledTextCtrl::SearchNext
if(!This) throw wxe_badarg(0);
int Result = This->SearchNext((int) *flags,text);
rt.addInt(Result);
- break;
+ break;
}
-case wxStyledTextCtrl_SearchPrev: { // wxStyledTextCtrl::SearchPrev
+case wxStyledTextCtrl_SearchPrev: { // wxStyledTextCtrl::SearchPrev
wxStyledTextCtrl *This = (wxStyledTextCtrl *) getPtr(bp,memenv); bp += 4;
int * flags = (int *) bp; bp += 4;
int * textLen = (int *) bp; bp += 4;
@@ -29238,201 +29280,201 @@ case wxStyledTextCtrl_SearchPrev: { // wxStyledTextCtrl::SearchPrev
if(!This) throw wxe_badarg(0);
int Result = This->SearchPrev((int) *flags,text);
rt.addInt(Result);
- break;
+ break;
}
-case wxStyledTextCtrl_LinesOnScreen: { // wxStyledTextCtrl::LinesOnScreen
+case wxStyledTextCtrl_LinesOnScreen: { // wxStyledTextCtrl::LinesOnScreen
wxStyledTextCtrl *This = (wxStyledTextCtrl *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
int Result = This->LinesOnScreen();
rt.addInt(Result);
- break;
+ break;
}
-case wxStyledTextCtrl_UsePopUp: { // wxStyledTextCtrl::UsePopUp
+case wxStyledTextCtrl_UsePopUp: { // wxStyledTextCtrl::UsePopUp
wxStyledTextCtrl *This = (wxStyledTextCtrl *) getPtr(bp,memenv); bp += 4;
bool * allowPopUp = (bool *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
This->UsePopUp((bool) *allowPopUp);
- break;
+ break;
}
-case wxStyledTextCtrl_SelectionIsRectangle: { // wxStyledTextCtrl::SelectionIsRectangle
+case wxStyledTextCtrl_SelectionIsRectangle: { // wxStyledTextCtrl::SelectionIsRectangle
wxStyledTextCtrl *This = (wxStyledTextCtrl *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
bool Result = This->SelectionIsRectangle();
rt.addBool(Result);
- break;
+ break;
}
-case wxStyledTextCtrl_SetZoom: { // wxStyledTextCtrl::SetZoom
+case wxStyledTextCtrl_SetZoom: { // wxStyledTextCtrl::SetZoom
wxStyledTextCtrl *This = (wxStyledTextCtrl *) getPtr(bp,memenv); bp += 4;
int * zoom = (int *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
This->SetZoom((int) *zoom);
- break;
+ break;
}
-case wxStyledTextCtrl_GetZoom: { // wxStyledTextCtrl::GetZoom
+case wxStyledTextCtrl_GetZoom: { // wxStyledTextCtrl::GetZoom
wxStyledTextCtrl *This = (wxStyledTextCtrl *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
int Result = This->GetZoom();
rt.addInt(Result);
- break;
+ break;
}
-case wxStyledTextCtrl_GetModEventMask: { // wxStyledTextCtrl::GetModEventMask
+case wxStyledTextCtrl_GetModEventMask: { // wxStyledTextCtrl::GetModEventMask
wxStyledTextCtrl *This = (wxStyledTextCtrl *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
int Result = This->GetModEventMask();
rt.addInt(Result);
- break;
+ break;
}
-case wxStyledTextCtrl_SetSTCFocus: { // wxStyledTextCtrl::SetSTCFocus
+case wxStyledTextCtrl_SetSTCFocus: { // wxStyledTextCtrl::SetSTCFocus
wxStyledTextCtrl *This = (wxStyledTextCtrl *) getPtr(bp,memenv); bp += 4;
bool * focus = (bool *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
This->SetSTCFocus((bool) *focus);
- break;
+ break;
}
-case wxStyledTextCtrl_GetSTCFocus: { // wxStyledTextCtrl::GetSTCFocus
+case wxStyledTextCtrl_GetSTCFocus: { // wxStyledTextCtrl::GetSTCFocus
wxStyledTextCtrl *This = (wxStyledTextCtrl *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
bool Result = This->GetSTCFocus();
rt.addBool(Result);
- break;
+ break;
}
-case wxStyledTextCtrl_SetStatus: { // wxStyledTextCtrl::SetStatus
+case wxStyledTextCtrl_SetStatus: { // wxStyledTextCtrl::SetStatus
wxStyledTextCtrl *This = (wxStyledTextCtrl *) getPtr(bp,memenv); bp += 4;
int * statusCode = (int *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
This->SetStatus((int) *statusCode);
- break;
+ break;
}
-case wxStyledTextCtrl_GetStatus: { // wxStyledTextCtrl::GetStatus
+case wxStyledTextCtrl_GetStatus: { // wxStyledTextCtrl::GetStatus
wxStyledTextCtrl *This = (wxStyledTextCtrl *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
int Result = This->GetStatus();
rt.addInt(Result);
- break;
+ break;
}
-case wxStyledTextCtrl_SetMouseDownCaptures: { // wxStyledTextCtrl::SetMouseDownCaptures
+case wxStyledTextCtrl_SetMouseDownCaptures: { // wxStyledTextCtrl::SetMouseDownCaptures
wxStyledTextCtrl *This = (wxStyledTextCtrl *) getPtr(bp,memenv); bp += 4;
bool * captures = (bool *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
This->SetMouseDownCaptures((bool) *captures);
- break;
+ break;
}
-case wxStyledTextCtrl_GetMouseDownCaptures: { // wxStyledTextCtrl::GetMouseDownCaptures
+case wxStyledTextCtrl_GetMouseDownCaptures: { // wxStyledTextCtrl::GetMouseDownCaptures
wxStyledTextCtrl *This = (wxStyledTextCtrl *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
bool Result = This->GetMouseDownCaptures();
rt.addBool(Result);
- break;
+ break;
}
-case wxStyledTextCtrl_SetSTCCursor: { // wxStyledTextCtrl::SetSTCCursor
+case wxStyledTextCtrl_SetSTCCursor: { // wxStyledTextCtrl::SetSTCCursor
wxStyledTextCtrl *This = (wxStyledTextCtrl *) getPtr(bp,memenv); bp += 4;
int * cursorType = (int *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
This->SetSTCCursor((int) *cursorType);
- break;
+ break;
}
-case wxStyledTextCtrl_GetSTCCursor: { // wxStyledTextCtrl::GetSTCCursor
+case wxStyledTextCtrl_GetSTCCursor: { // wxStyledTextCtrl::GetSTCCursor
wxStyledTextCtrl *This = (wxStyledTextCtrl *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
int Result = This->GetSTCCursor();
rt.addInt(Result);
- break;
+ break;
}
-case wxStyledTextCtrl_SetControlCharSymbol: { // wxStyledTextCtrl::SetControlCharSymbol
+case wxStyledTextCtrl_SetControlCharSymbol: { // wxStyledTextCtrl::SetControlCharSymbol
wxStyledTextCtrl *This = (wxStyledTextCtrl *) getPtr(bp,memenv); bp += 4;
int * symbol = (int *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
This->SetControlCharSymbol((int) *symbol);
- break;
+ break;
}
-case wxStyledTextCtrl_GetControlCharSymbol: { // wxStyledTextCtrl::GetControlCharSymbol
+case wxStyledTextCtrl_GetControlCharSymbol: { // wxStyledTextCtrl::GetControlCharSymbol
wxStyledTextCtrl *This = (wxStyledTextCtrl *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
int Result = This->GetControlCharSymbol();
rt.addInt(Result);
- break;
+ break;
}
-case wxStyledTextCtrl_WordPartLeft: { // wxStyledTextCtrl::WordPartLeft
+case wxStyledTextCtrl_WordPartLeft: { // wxStyledTextCtrl::WordPartLeft
wxStyledTextCtrl *This = (wxStyledTextCtrl *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
This->WordPartLeft();
- break;
+ break;
}
-case wxStyledTextCtrl_WordPartLeftExtend: { // wxStyledTextCtrl::WordPartLeftExtend
+case wxStyledTextCtrl_WordPartLeftExtend: { // wxStyledTextCtrl::WordPartLeftExtend
wxStyledTextCtrl *This = (wxStyledTextCtrl *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
This->WordPartLeftExtend();
- break;
+ break;
}
-case wxStyledTextCtrl_WordPartRight: { // wxStyledTextCtrl::WordPartRight
+case wxStyledTextCtrl_WordPartRight: { // wxStyledTextCtrl::WordPartRight
wxStyledTextCtrl *This = (wxStyledTextCtrl *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
This->WordPartRight();
- break;
+ break;
}
-case wxStyledTextCtrl_WordPartRightExtend: { // wxStyledTextCtrl::WordPartRightExtend
+case wxStyledTextCtrl_WordPartRightExtend: { // wxStyledTextCtrl::WordPartRightExtend
wxStyledTextCtrl *This = (wxStyledTextCtrl *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
This->WordPartRightExtend();
- break;
+ break;
}
-case wxStyledTextCtrl_SetVisiblePolicy: { // wxStyledTextCtrl::SetVisiblePolicy
+case wxStyledTextCtrl_SetVisiblePolicy: { // wxStyledTextCtrl::SetVisiblePolicy
wxStyledTextCtrl *This = (wxStyledTextCtrl *) getPtr(bp,memenv); bp += 4;
int * visiblePolicy = (int *) bp; bp += 4;
int * visibleSlop = (int *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
This->SetVisiblePolicy((int) *visiblePolicy,(int) *visibleSlop);
- break;
+ break;
}
-case wxStyledTextCtrl_DelLineLeft: { // wxStyledTextCtrl::DelLineLeft
+case wxStyledTextCtrl_DelLineLeft: { // wxStyledTextCtrl::DelLineLeft
wxStyledTextCtrl *This = (wxStyledTextCtrl *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
This->DelLineLeft();
- break;
+ break;
}
-case wxStyledTextCtrl_DelLineRight: { // wxStyledTextCtrl::DelLineRight
+case wxStyledTextCtrl_DelLineRight: { // wxStyledTextCtrl::DelLineRight
wxStyledTextCtrl *This = (wxStyledTextCtrl *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
This->DelLineRight();
- break;
+ break;
}
-case wxStyledTextCtrl_GetXOffset: { // wxStyledTextCtrl::GetXOffset
+case wxStyledTextCtrl_GetXOffset: { // wxStyledTextCtrl::GetXOffset
wxStyledTextCtrl *This = (wxStyledTextCtrl *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
int Result = This->GetXOffset();
rt.addInt(Result);
- break;
+ break;
}
-case wxStyledTextCtrl_ChooseCaretX: { // wxStyledTextCtrl::ChooseCaretX
+case wxStyledTextCtrl_ChooseCaretX: { // wxStyledTextCtrl::ChooseCaretX
wxStyledTextCtrl *This = (wxStyledTextCtrl *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
This->ChooseCaretX();
- break;
+ break;
}
-case wxStyledTextCtrl_SetXCaretPolicy: { // wxStyledTextCtrl::SetXCaretPolicy
+case wxStyledTextCtrl_SetXCaretPolicy: { // wxStyledTextCtrl::SetXCaretPolicy
wxStyledTextCtrl *This = (wxStyledTextCtrl *) getPtr(bp,memenv); bp += 4;
int * caretPolicy = (int *) bp; bp += 4;
int * caretSlop = (int *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
This->SetXCaretPolicy((int) *caretPolicy,(int) *caretSlop);
- break;
+ break;
}
-case wxStyledTextCtrl_SetYCaretPolicy: { // wxStyledTextCtrl::SetYCaretPolicy
+case wxStyledTextCtrl_SetYCaretPolicy: { // wxStyledTextCtrl::SetYCaretPolicy
wxStyledTextCtrl *This = (wxStyledTextCtrl *) getPtr(bp,memenv); bp += 4;
int * caretPolicy = (int *) bp; bp += 4;
int * caretSlop = (int *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
This->SetYCaretPolicy((int) *caretPolicy,(int) *caretSlop);
- break;
+ break;
}
-case wxStyledTextCtrl_GetPrintWrapMode: { // wxStyledTextCtrl::GetPrintWrapMode
+case wxStyledTextCtrl_GetPrintWrapMode: { // wxStyledTextCtrl::GetPrintWrapMode
wxStyledTextCtrl *This = (wxStyledTextCtrl *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
int Result = This->GetPrintWrapMode();
rt.addInt(Result);
- break;
+ break;
}
-case wxStyledTextCtrl_SetHotspotActiveForeground: { // wxStyledTextCtrl::SetHotspotActiveForeground
+case wxStyledTextCtrl_SetHotspotActiveForeground: { // wxStyledTextCtrl::SetHotspotActiveForeground
wxStyledTextCtrl *This = (wxStyledTextCtrl *) getPtr(bp,memenv); bp += 4;
bool * useSetting = (bool *) bp; bp += 4;
int * foreR = (int *) bp; bp += 4;
@@ -29442,9 +29484,9 @@ case wxStyledTextCtrl_SetHotspotActiveForeground: { // wxStyledTextCtrl::SetHots
wxColour fore = wxColour(*foreR,*foreG,*foreB,*foreA);
if(!This) throw wxe_badarg(0);
This->SetHotspotActiveForeground((bool) *useSetting,fore);
- break;
+ break;
}
-case wxStyledTextCtrl_SetHotspotActiveBackground: { // wxStyledTextCtrl::SetHotspotActiveBackground
+case wxStyledTextCtrl_SetHotspotActiveBackground: { // wxStyledTextCtrl::SetHotspotActiveBackground
wxStyledTextCtrl *This = (wxStyledTextCtrl *) getPtr(bp,memenv); bp += 4;
bool * useSetting = (bool *) bp; bp += 4;
int * backR = (int *) bp; bp += 4;
@@ -29454,65 +29496,65 @@ case wxStyledTextCtrl_SetHotspotActiveBackground: { // wxStyledTextCtrl::SetHots
wxColour back = wxColour(*backR,*backG,*backB,*backA);
if(!This) throw wxe_badarg(0);
This->SetHotspotActiveBackground((bool) *useSetting,back);
- break;
+ break;
}
-case wxStyledTextCtrl_SetHotspotActiveUnderline: { // wxStyledTextCtrl::SetHotspotActiveUnderline
+case wxStyledTextCtrl_SetHotspotActiveUnderline: { // wxStyledTextCtrl::SetHotspotActiveUnderline
wxStyledTextCtrl *This = (wxStyledTextCtrl *) getPtr(bp,memenv); bp += 4;
bool * underline = (bool *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
This->SetHotspotActiveUnderline((bool) *underline);
- break;
+ break;
}
-case wxStyledTextCtrl_SetHotspotSingleLine: { // wxStyledTextCtrl::SetHotspotSingleLine
+case wxStyledTextCtrl_SetHotspotSingleLine: { // wxStyledTextCtrl::SetHotspotSingleLine
wxStyledTextCtrl *This = (wxStyledTextCtrl *) getPtr(bp,memenv); bp += 4;
bool * singleLine = (bool *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
This->SetHotspotSingleLine((bool) *singleLine);
- break;
+ break;
}
-case wxStyledTextCtrl_ParaDownExtend: { // wxStyledTextCtrl::ParaDownExtend
+case wxStyledTextCtrl_ParaDownExtend: { // wxStyledTextCtrl::ParaDownExtend
wxStyledTextCtrl *This = (wxStyledTextCtrl *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
This->ParaDownExtend();
- break;
+ break;
}
-case wxStyledTextCtrl_ParaUp: { // wxStyledTextCtrl::ParaUp
+case wxStyledTextCtrl_ParaUp: { // wxStyledTextCtrl::ParaUp
wxStyledTextCtrl *This = (wxStyledTextCtrl *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
This->ParaUp();
- break;
+ break;
}
-case wxStyledTextCtrl_ParaUpExtend: { // wxStyledTextCtrl::ParaUpExtend
+case wxStyledTextCtrl_ParaUpExtend: { // wxStyledTextCtrl::ParaUpExtend
wxStyledTextCtrl *This = (wxStyledTextCtrl *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
This->ParaUpExtend();
- break;
+ break;
}
-case wxStyledTextCtrl_PositionBefore: { // wxStyledTextCtrl::PositionBefore
+case wxStyledTextCtrl_PositionBefore: { // wxStyledTextCtrl::PositionBefore
wxStyledTextCtrl *This = (wxStyledTextCtrl *) getPtr(bp,memenv); bp += 4;
int * pos = (int *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
int Result = This->PositionBefore((int) *pos);
rt.addInt(Result);
- break;
+ break;
}
-case wxStyledTextCtrl_PositionAfter: { // wxStyledTextCtrl::PositionAfter
+case wxStyledTextCtrl_PositionAfter: { // wxStyledTextCtrl::PositionAfter
wxStyledTextCtrl *This = (wxStyledTextCtrl *) getPtr(bp,memenv); bp += 4;
int * pos = (int *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
int Result = This->PositionAfter((int) *pos);
rt.addInt(Result);
- break;
+ break;
}
-case wxStyledTextCtrl_CopyRange: { // wxStyledTextCtrl::CopyRange
+case wxStyledTextCtrl_CopyRange: { // wxStyledTextCtrl::CopyRange
wxStyledTextCtrl *This = (wxStyledTextCtrl *) getPtr(bp,memenv); bp += 4;
int * start = (int *) bp; bp += 4;
int * end = (int *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
This->CopyRange((int) *start,(int) *end);
- break;
+ break;
}
-case wxStyledTextCtrl_CopyText: { // wxStyledTextCtrl::CopyText
+case wxStyledTextCtrl_CopyText: { // wxStyledTextCtrl::CopyText
wxStyledTextCtrl *This = (wxStyledTextCtrl *) getPtr(bp,memenv); bp += 4;
int * length = (int *) bp; bp += 4;
int * textLen = (int *) bp; bp += 4;
@@ -29520,251 +29562,251 @@ case wxStyledTextCtrl_CopyText: { // wxStyledTextCtrl::CopyText
bp += *textLen+((8-((4+ *textLen) & 7)) & 7);
if(!This) throw wxe_badarg(0);
This->CopyText((int) *length,text);
- break;
+ break;
}
-case wxStyledTextCtrl_SetSelectionMode: { // wxStyledTextCtrl::SetSelectionMode
+case wxStyledTextCtrl_SetSelectionMode: { // wxStyledTextCtrl::SetSelectionMode
wxStyledTextCtrl *This = (wxStyledTextCtrl *) getPtr(bp,memenv); bp += 4;
int * mode = (int *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
This->SetSelectionMode((int) *mode);
- break;
+ break;
}
-case wxStyledTextCtrl_GetSelectionMode: { // wxStyledTextCtrl::GetSelectionMode
+case wxStyledTextCtrl_GetSelectionMode: { // wxStyledTextCtrl::GetSelectionMode
wxStyledTextCtrl *This = (wxStyledTextCtrl *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
int Result = This->GetSelectionMode();
rt.addInt(Result);
- break;
+ break;
}
-case wxStyledTextCtrl_LineDownRectExtend: { // wxStyledTextCtrl::LineDownRectExtend
+case wxStyledTextCtrl_LineDownRectExtend: { // wxStyledTextCtrl::LineDownRectExtend
wxStyledTextCtrl *This = (wxStyledTextCtrl *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
This->LineDownRectExtend();
- break;
+ break;
}
-case wxStyledTextCtrl_LineUpRectExtend: { // wxStyledTextCtrl::LineUpRectExtend
+case wxStyledTextCtrl_LineUpRectExtend: { // wxStyledTextCtrl::LineUpRectExtend
wxStyledTextCtrl *This = (wxStyledTextCtrl *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
This->LineUpRectExtend();
- break;
+ break;
}
-case wxStyledTextCtrl_CharLeftRectExtend: { // wxStyledTextCtrl::CharLeftRectExtend
+case wxStyledTextCtrl_CharLeftRectExtend: { // wxStyledTextCtrl::CharLeftRectExtend
wxStyledTextCtrl *This = (wxStyledTextCtrl *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
This->CharLeftRectExtend();
- break;
+ break;
}
-case wxStyledTextCtrl_CharRightRectExtend: { // wxStyledTextCtrl::CharRightRectExtend
+case wxStyledTextCtrl_CharRightRectExtend: { // wxStyledTextCtrl::CharRightRectExtend
wxStyledTextCtrl *This = (wxStyledTextCtrl *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
This->CharRightRectExtend();
- break;
+ break;
}
-case wxStyledTextCtrl_HomeRectExtend: { // wxStyledTextCtrl::HomeRectExtend
+case wxStyledTextCtrl_HomeRectExtend: { // wxStyledTextCtrl::HomeRectExtend
wxStyledTextCtrl *This = (wxStyledTextCtrl *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
This->HomeRectExtend();
- break;
+ break;
}
-case wxStyledTextCtrl_VCHomeRectExtend: { // wxStyledTextCtrl::VCHomeRectExtend
+case wxStyledTextCtrl_VCHomeRectExtend: { // wxStyledTextCtrl::VCHomeRectExtend
wxStyledTextCtrl *This = (wxStyledTextCtrl *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
This->VCHomeRectExtend();
- break;
+ break;
}
-case wxStyledTextCtrl_LineEndRectExtend: { // wxStyledTextCtrl::LineEndRectExtend
+case wxStyledTextCtrl_LineEndRectExtend: { // wxStyledTextCtrl::LineEndRectExtend
wxStyledTextCtrl *This = (wxStyledTextCtrl *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
This->LineEndRectExtend();
- break;
+ break;
}
-case wxStyledTextCtrl_PageUpRectExtend: { // wxStyledTextCtrl::PageUpRectExtend
+case wxStyledTextCtrl_PageUpRectExtend: { // wxStyledTextCtrl::PageUpRectExtend
wxStyledTextCtrl *This = (wxStyledTextCtrl *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
This->PageUpRectExtend();
- break;
+ break;
}
-case wxStyledTextCtrl_PageDownRectExtend: { // wxStyledTextCtrl::PageDownRectExtend
+case wxStyledTextCtrl_PageDownRectExtend: { // wxStyledTextCtrl::PageDownRectExtend
wxStyledTextCtrl *This = (wxStyledTextCtrl *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
This->PageDownRectExtend();
- break;
+ break;
}
-case wxStyledTextCtrl_StutteredPageUp: { // wxStyledTextCtrl::StutteredPageUp
+case wxStyledTextCtrl_StutteredPageUp: { // wxStyledTextCtrl::StutteredPageUp
wxStyledTextCtrl *This = (wxStyledTextCtrl *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
This->StutteredPageUp();
- break;
+ break;
}
-case wxStyledTextCtrl_StutteredPageUpExtend: { // wxStyledTextCtrl::StutteredPageUpExtend
+case wxStyledTextCtrl_StutteredPageUpExtend: { // wxStyledTextCtrl::StutteredPageUpExtend
wxStyledTextCtrl *This = (wxStyledTextCtrl *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
This->StutteredPageUpExtend();
- break;
+ break;
}
-case wxStyledTextCtrl_StutteredPageDown: { // wxStyledTextCtrl::StutteredPageDown
+case wxStyledTextCtrl_StutteredPageDown: { // wxStyledTextCtrl::StutteredPageDown
wxStyledTextCtrl *This = (wxStyledTextCtrl *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
This->StutteredPageDown();
- break;
+ break;
}
-case wxStyledTextCtrl_StutteredPageDownExtend: { // wxStyledTextCtrl::StutteredPageDownExtend
+case wxStyledTextCtrl_StutteredPageDownExtend: { // wxStyledTextCtrl::StutteredPageDownExtend
wxStyledTextCtrl *This = (wxStyledTextCtrl *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
This->StutteredPageDownExtend();
- break;
+ break;
}
-case wxStyledTextCtrl_WordLeftEnd: { // wxStyledTextCtrl::WordLeftEnd
+case wxStyledTextCtrl_WordLeftEnd: { // wxStyledTextCtrl::WordLeftEnd
wxStyledTextCtrl *This = (wxStyledTextCtrl *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
This->WordLeftEnd();
- break;
+ break;
}
-case wxStyledTextCtrl_WordLeftEndExtend: { // wxStyledTextCtrl::WordLeftEndExtend
+case wxStyledTextCtrl_WordLeftEndExtend: { // wxStyledTextCtrl::WordLeftEndExtend
wxStyledTextCtrl *This = (wxStyledTextCtrl *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
This->WordLeftEndExtend();
- break;
+ break;
}
-case wxStyledTextCtrl_WordRightEnd: { // wxStyledTextCtrl::WordRightEnd
+case wxStyledTextCtrl_WordRightEnd: { // wxStyledTextCtrl::WordRightEnd
wxStyledTextCtrl *This = (wxStyledTextCtrl *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
This->WordRightEnd();
- break;
+ break;
}
-case wxStyledTextCtrl_WordRightEndExtend: { // wxStyledTextCtrl::WordRightEndExtend
+case wxStyledTextCtrl_WordRightEndExtend: { // wxStyledTextCtrl::WordRightEndExtend
wxStyledTextCtrl *This = (wxStyledTextCtrl *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
This->WordRightEndExtend();
- break;
+ break;
}
-case wxStyledTextCtrl_SetWhitespaceChars: { // wxStyledTextCtrl::SetWhitespaceChars
+case wxStyledTextCtrl_SetWhitespaceChars: { // wxStyledTextCtrl::SetWhitespaceChars
wxStyledTextCtrl *This = (wxStyledTextCtrl *) getPtr(bp,memenv); bp += 4;
int * charactersLen = (int *) bp; bp += 4;
wxString characters = wxString(bp, wxConvUTF8);
bp += *charactersLen+((8-((0+ *charactersLen) & 7)) & 7);
if(!This) throw wxe_badarg(0);
This->SetWhitespaceChars(characters);
- break;
+ break;
}
-case wxStyledTextCtrl_SetCharsDefault: { // wxStyledTextCtrl::SetCharsDefault
+case wxStyledTextCtrl_SetCharsDefault: { // wxStyledTextCtrl::SetCharsDefault
wxStyledTextCtrl *This = (wxStyledTextCtrl *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
This->SetCharsDefault();
- break;
+ break;
}
-case wxStyledTextCtrl_AutoCompGetCurrent: { // wxStyledTextCtrl::AutoCompGetCurrent
+case wxStyledTextCtrl_AutoCompGetCurrent: { // wxStyledTextCtrl::AutoCompGetCurrent
wxStyledTextCtrl *This = (wxStyledTextCtrl *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
int Result = This->AutoCompGetCurrent();
rt.addInt(Result);
- break;
+ break;
}
-case wxStyledTextCtrl_Allocate: { // wxStyledTextCtrl::Allocate
+case wxStyledTextCtrl_Allocate: { // wxStyledTextCtrl::Allocate
wxStyledTextCtrl *This = (wxStyledTextCtrl *) getPtr(bp,memenv); bp += 4;
int * bytes = (int *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
This->Allocate((int) *bytes);
- break;
+ break;
}
-case wxStyledTextCtrl_FindColumn: { // wxStyledTextCtrl::FindColumn
+case wxStyledTextCtrl_FindColumn: { // wxStyledTextCtrl::FindColumn
wxStyledTextCtrl *This = (wxStyledTextCtrl *) getPtr(bp,memenv); bp += 4;
int * line = (int *) bp; bp += 4;
int * column = (int *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
int Result = This->FindColumn((int) *line,(int) *column);
rt.addInt(Result);
- break;
+ break;
}
-case wxStyledTextCtrl_GetCaretSticky: { // wxStyledTextCtrl::GetCaretSticky
+case wxStyledTextCtrl_GetCaretSticky: { // wxStyledTextCtrl::GetCaretSticky
wxStyledTextCtrl *This = (wxStyledTextCtrl *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
bool Result = This->GetCaretSticky();
rt.addBool(Result);
- break;
+ break;
}
-case wxStyledTextCtrl_SetCaretSticky: { // wxStyledTextCtrl::SetCaretSticky
+case wxStyledTextCtrl_SetCaretSticky: { // wxStyledTextCtrl::SetCaretSticky
wxStyledTextCtrl *This = (wxStyledTextCtrl *) getPtr(bp,memenv); bp += 4;
bool * useCaretStickyBehaviour = (bool *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
This->SetCaretSticky((bool) *useCaretStickyBehaviour);
- break;
+ break;
}
-case wxStyledTextCtrl_ToggleCaretSticky: { // wxStyledTextCtrl::ToggleCaretSticky
+case wxStyledTextCtrl_ToggleCaretSticky: { // wxStyledTextCtrl::ToggleCaretSticky
wxStyledTextCtrl *This = (wxStyledTextCtrl *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
This->ToggleCaretSticky();
- break;
+ break;
}
-case wxStyledTextCtrl_SetPasteConvertEndings: { // wxStyledTextCtrl::SetPasteConvertEndings
+case wxStyledTextCtrl_SetPasteConvertEndings: { // wxStyledTextCtrl::SetPasteConvertEndings
wxStyledTextCtrl *This = (wxStyledTextCtrl *) getPtr(bp,memenv); bp += 4;
bool * convert = (bool *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
This->SetPasteConvertEndings((bool) *convert);
- break;
+ break;
}
-case wxStyledTextCtrl_GetPasteConvertEndings: { // wxStyledTextCtrl::GetPasteConvertEndings
+case wxStyledTextCtrl_GetPasteConvertEndings: { // wxStyledTextCtrl::GetPasteConvertEndings
wxStyledTextCtrl *This = (wxStyledTextCtrl *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
bool Result = This->GetPasteConvertEndings();
rt.addBool(Result);
- break;
+ break;
}
-case wxStyledTextCtrl_SelectionDuplicate: { // wxStyledTextCtrl::SelectionDuplicate
+case wxStyledTextCtrl_SelectionDuplicate: { // wxStyledTextCtrl::SelectionDuplicate
wxStyledTextCtrl *This = (wxStyledTextCtrl *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
This->SelectionDuplicate();
- break;
+ break;
}
-case wxStyledTextCtrl_SetCaretLineBackAlpha: { // wxStyledTextCtrl::SetCaretLineBackAlpha
+case wxStyledTextCtrl_SetCaretLineBackAlpha: { // wxStyledTextCtrl::SetCaretLineBackAlpha
wxStyledTextCtrl *This = (wxStyledTextCtrl *) getPtr(bp,memenv); bp += 4;
int * alpha = (int *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
This->SetCaretLineBackAlpha((int) *alpha);
- break;
+ break;
}
-case wxStyledTextCtrl_GetCaretLineBackAlpha: { // wxStyledTextCtrl::GetCaretLineBackAlpha
+case wxStyledTextCtrl_GetCaretLineBackAlpha: { // wxStyledTextCtrl::GetCaretLineBackAlpha
wxStyledTextCtrl *This = (wxStyledTextCtrl *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
int Result = This->GetCaretLineBackAlpha();
rt.addInt(Result);
- break;
+ break;
}
-case wxStyledTextCtrl_StartRecord: { // wxStyledTextCtrl::StartRecord
+case wxStyledTextCtrl_StartRecord: { // wxStyledTextCtrl::StartRecord
wxStyledTextCtrl *This = (wxStyledTextCtrl *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
This->StartRecord();
- break;
+ break;
}
-case wxStyledTextCtrl_StopRecord: { // wxStyledTextCtrl::StopRecord
+case wxStyledTextCtrl_StopRecord: { // wxStyledTextCtrl::StopRecord
wxStyledTextCtrl *This = (wxStyledTextCtrl *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
This->StopRecord();
- break;
+ break;
}
-case wxStyledTextCtrl_SetLexer: { // wxStyledTextCtrl::SetLexer
+case wxStyledTextCtrl_SetLexer: { // wxStyledTextCtrl::SetLexer
wxStyledTextCtrl *This = (wxStyledTextCtrl *) getPtr(bp,memenv); bp += 4;
int * lexer = (int *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
This->SetLexer((int) *lexer);
- break;
+ break;
}
-case wxStyledTextCtrl_GetLexer: { // wxStyledTextCtrl::GetLexer
+case wxStyledTextCtrl_GetLexer: { // wxStyledTextCtrl::GetLexer
wxStyledTextCtrl *This = (wxStyledTextCtrl *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
int Result = This->GetLexer();
rt.addInt(Result);
- break;
+ break;
}
-case wxStyledTextCtrl_Colourise: { // wxStyledTextCtrl::Colourise
+case wxStyledTextCtrl_Colourise: { // wxStyledTextCtrl::Colourise
wxStyledTextCtrl *This = (wxStyledTextCtrl *) getPtr(bp,memenv); bp += 4;
int * start = (int *) bp; bp += 4;
int * end = (int *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
This->Colourise((int) *start,(int) *end);
- break;
+ break;
}
-case wxStyledTextCtrl_SetProperty: { // wxStyledTextCtrl::SetProperty
+case wxStyledTextCtrl_SetProperty: { // wxStyledTextCtrl::SetProperty
wxStyledTextCtrl *This = (wxStyledTextCtrl *) getPtr(bp,memenv); bp += 4;
int * keyLen = (int *) bp; bp += 4;
wxString key = wxString(bp, wxConvUTF8);
@@ -29774,9 +29816,9 @@ case wxStyledTextCtrl_SetProperty: { // wxStyledTextCtrl::SetProperty
bp += *valueLen+((8-((4+ *valueLen) & 7)) & 7);
if(!This) throw wxe_badarg(0);
This->SetProperty(key,value);
- break;
+ break;
}
-case wxStyledTextCtrl_SetKeyWords: { // wxStyledTextCtrl::SetKeyWords
+case wxStyledTextCtrl_SetKeyWords: { // wxStyledTextCtrl::SetKeyWords
wxStyledTextCtrl *This = (wxStyledTextCtrl *) getPtr(bp,memenv); bp += 4;
int * keywordSet = (int *) bp; bp += 4;
int * keyWordsLen = (int *) bp; bp += 4;
@@ -29784,18 +29826,18 @@ case wxStyledTextCtrl_SetKeyWords: { // wxStyledTextCtrl::SetKeyWords
bp += *keyWordsLen+((8-((4+ *keyWordsLen) & 7)) & 7);
if(!This) throw wxe_badarg(0);
This->SetKeyWords((int) *keywordSet,keyWords);
- break;
+ break;
}
-case wxStyledTextCtrl_SetLexerLanguage: { // wxStyledTextCtrl::SetLexerLanguage
+case wxStyledTextCtrl_SetLexerLanguage: { // wxStyledTextCtrl::SetLexerLanguage
wxStyledTextCtrl *This = (wxStyledTextCtrl *) getPtr(bp,memenv); bp += 4;
int * languageLen = (int *) bp; bp += 4;
wxString language = wxString(bp, wxConvUTF8);
bp += *languageLen+((8-((0+ *languageLen) & 7)) & 7);
if(!This) throw wxe_badarg(0);
This->SetLexerLanguage(language);
- break;
+ break;
}
-case wxStyledTextCtrl_GetProperty: { // wxStyledTextCtrl::GetProperty
+case wxStyledTextCtrl_GetProperty: { // wxStyledTextCtrl::GetProperty
wxStyledTextCtrl *This = (wxStyledTextCtrl *) getPtr(bp,memenv); bp += 4;
int * keyLen = (int *) bp; bp += 4;
wxString key = wxString(bp, wxConvUTF8);
@@ -29803,23 +29845,23 @@ case wxStyledTextCtrl_GetProperty: { // wxStyledTextCtrl::GetProperty
if(!This) throw wxe_badarg(0);
wxString Result = This->GetProperty(key);
rt.add(Result);
- break;
+ break;
}
-case wxStyledTextCtrl_GetStyleBitsNeeded: { // wxStyledTextCtrl::GetStyleBitsNeeded
+case wxStyledTextCtrl_GetStyleBitsNeeded: { // wxStyledTextCtrl::GetStyleBitsNeeded
wxStyledTextCtrl *This = (wxStyledTextCtrl *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
int Result = This->GetStyleBitsNeeded();
rt.addInt(Result);
- break;
+ break;
}
-case wxStyledTextCtrl_GetCurrentLine: { // wxStyledTextCtrl::GetCurrentLine
+case wxStyledTextCtrl_GetCurrentLine: { // wxStyledTextCtrl::GetCurrentLine
wxStyledTextCtrl *This = (wxStyledTextCtrl *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
int Result = This->GetCurrentLine();
rt.addInt(Result);
- break;
+ break;
}
-case wxStyledTextCtrl_StyleSetSpec: { // wxStyledTextCtrl::StyleSetSpec
+case wxStyledTextCtrl_StyleSetSpec: { // wxStyledTextCtrl::StyleSetSpec
wxStyledTextCtrl *This = (wxStyledTextCtrl *) getPtr(bp,memenv); bp += 4;
int * styleNum = (int *) bp; bp += 4;
int * specLen = (int *) bp; bp += 4;
@@ -29827,17 +29869,17 @@ case wxStyledTextCtrl_StyleSetSpec: { // wxStyledTextCtrl::StyleSetSpec
bp += *specLen+((8-((4+ *specLen) & 7)) & 7);
if(!This) throw wxe_badarg(0);
This->StyleSetSpec((int) *styleNum,spec);
- break;
+ break;
}
-case wxStyledTextCtrl_StyleSetFont: { // wxStyledTextCtrl::StyleSetFont
+case wxStyledTextCtrl_StyleSetFont: { // wxStyledTextCtrl::StyleSetFont
wxStyledTextCtrl *This = (wxStyledTextCtrl *) getPtr(bp,memenv); bp += 4;
int * styleNum = (int *) bp; bp += 4;
wxFont *font = (wxFont *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
This->StyleSetFont((int) *styleNum,*font);
- break;
+ break;
}
-case wxStyledTextCtrl_StyleSetFontAttr: { // wxStyledTextCtrl::StyleSetFontAttr
+case wxStyledTextCtrl_StyleSetFontAttr: { // wxStyledTextCtrl::StyleSetFontAttr
wxFontEncoding encoding=wxFONTENCODING_DEFAULT;
wxStyledTextCtrl *This = (wxStyledTextCtrl *) getPtr(bp,memenv); bp += 4;
int * styleNum = (int *) bp; bp += 4;
@@ -29849,47 +29891,47 @@ case wxStyledTextCtrl_StyleSetFontAttr: { // wxStyledTextCtrl::StyleSetFontAttr
bool * italic = (bool *) bp; bp += 4;
bool * underline = (bool *) bp; bp += 4;
bp += 4; /* Align */
- while( * (int*) bp) { switch (* (int*) bp) {
+ while( * (int*) bp) { switch (* (int*) bp) {
case 1: {bp += 4;
encoding = *(wxFontEncoding *) bp; bp += 4;;
} break;
- }};
+ }};
if(!This) throw wxe_badarg(0);
This->StyleSetFontAttr((int) *styleNum,(int) *size,faceName,(bool) *bold,(bool) *italic,(bool) *underline,(wxFontEncoding) encoding);
- break;
+ break;
}
-case wxStyledTextCtrl_StyleSetCharacterSet: { // wxStyledTextCtrl::StyleSetCharacterSet
+case wxStyledTextCtrl_StyleSetCharacterSet: { // wxStyledTextCtrl::StyleSetCharacterSet
wxStyledTextCtrl *This = (wxStyledTextCtrl *) getPtr(bp,memenv); bp += 4;
int * style = (int *) bp; bp += 4;
int * characterSet = (int *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
This->StyleSetCharacterSet((int) *style,(int) *characterSet);
- break;
+ break;
}
-case wxStyledTextCtrl_StyleSetFontEncoding: { // wxStyledTextCtrl::StyleSetFontEncoding
+case wxStyledTextCtrl_StyleSetFontEncoding: { // wxStyledTextCtrl::StyleSetFontEncoding
wxStyledTextCtrl *This = (wxStyledTextCtrl *) getPtr(bp,memenv); bp += 4;
int * style = (int *) bp; bp += 4;
wxFontEncoding encoding = *(wxFontEncoding *) bp; bp += 4;;
if(!This) throw wxe_badarg(0);
This->StyleSetFontEncoding((int) *style,(wxFontEncoding) encoding);
- break;
+ break;
}
-case wxStyledTextCtrl_CmdKeyExecute: { // wxStyledTextCtrl::CmdKeyExecute
+case wxStyledTextCtrl_CmdKeyExecute: { // wxStyledTextCtrl::CmdKeyExecute
wxStyledTextCtrl *This = (wxStyledTextCtrl *) getPtr(bp,memenv); bp += 4;
int * cmd = (int *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
This->CmdKeyExecute((int) *cmd);
- break;
+ break;
}
-case wxStyledTextCtrl_SetMargins: { // wxStyledTextCtrl::SetMargins
+case wxStyledTextCtrl_SetMargins: { // wxStyledTextCtrl::SetMargins
wxStyledTextCtrl *This = (wxStyledTextCtrl *) getPtr(bp,memenv); bp += 4;
int * left = (int *) bp; bp += 4;
int * right = (int *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
This->SetMargins((int) *left,(int) *right);
- break;
+ break;
}
-case wxStyledTextCtrl_GetSelection: { // wxStyledTextCtrl::GetSelection
+case wxStyledTextCtrl_GetSelection: { // wxStyledTextCtrl::GetSelection
int startPos;
int endPos;
wxStyledTextCtrl *This = (wxStyledTextCtrl *) getPtr(bp,memenv); bp += 4;
@@ -29898,77 +29940,77 @@ case wxStyledTextCtrl_GetSelection: { // wxStyledTextCtrl::GetSelection
rt.addInt(startPos);
rt.addInt(endPos);
rt.addTupleCount(2);
- break;
+ break;
}
-case wxStyledTextCtrl_PointFromPosition: { // wxStyledTextCtrl::PointFromPosition
+case wxStyledTextCtrl_PointFromPosition: { // wxStyledTextCtrl::PointFromPosition
wxStyledTextCtrl *This = (wxStyledTextCtrl *) getPtr(bp,memenv); bp += 4;
int * pos = (int *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
wxPoint Result = This->PointFromPosition((int) *pos);
rt.add(Result);
- break;
+ break;
}
-case wxStyledTextCtrl_ScrollToLine: { // wxStyledTextCtrl::ScrollToLine
+case wxStyledTextCtrl_ScrollToLine: { // wxStyledTextCtrl::ScrollToLine
wxStyledTextCtrl *This = (wxStyledTextCtrl *) getPtr(bp,memenv); bp += 4;
int * line = (int *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
This->ScrollToLine((int) *line);
- break;
+ break;
}
-case wxStyledTextCtrl_ScrollToColumn: { // wxStyledTextCtrl::ScrollToColumn
+case wxStyledTextCtrl_ScrollToColumn: { // wxStyledTextCtrl::ScrollToColumn
wxStyledTextCtrl *This = (wxStyledTextCtrl *) getPtr(bp,memenv); bp += 4;
int * column = (int *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
This->ScrollToColumn((int) *column);
- break;
+ break;
}
-case wxStyledTextCtrl_SendMsg: { // wxStyledTextCtrl::SendMsg
+case wxStyledTextCtrl_SendMsg: { // wxStyledTextCtrl::SendMsg
long wp=0;
long lp=0;
wxStyledTextCtrl *This = (wxStyledTextCtrl *) getPtr(bp,memenv); bp += 4;
int * msg = (int *) bp; bp += 4;
- while( * (int*) bp) { switch (* (int*) bp) {
+ while( * (int*) bp) { switch (* (int*) bp) {
case 1: {bp += 4;
wp = (long)*(int *) bp; bp += 4;
} break;
case 2: {bp += 4;
lp = (long)*(int *) bp; bp += 4;
} break;
- }};
+ }};
if(!This) throw wxe_badarg(0);
long Result = This->SendMsg((int) *msg,wp,lp);
rt.addInt(Result);
- break;
+ break;
}
-case wxStyledTextCtrl_SetVScrollBar: { // wxStyledTextCtrl::SetVScrollBar
+case wxStyledTextCtrl_SetVScrollBar: { // wxStyledTextCtrl::SetVScrollBar
wxStyledTextCtrl *This = (wxStyledTextCtrl *) getPtr(bp,memenv); bp += 4;
wxScrollBar *bar = (wxScrollBar *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
This->SetVScrollBar(bar);
- break;
+ break;
}
-case wxStyledTextCtrl_SetHScrollBar: { // wxStyledTextCtrl::SetHScrollBar
+case wxStyledTextCtrl_SetHScrollBar: { // wxStyledTextCtrl::SetHScrollBar
wxStyledTextCtrl *This = (wxStyledTextCtrl *) getPtr(bp,memenv); bp += 4;
wxScrollBar *bar = (wxScrollBar *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
This->SetHScrollBar(bar);
- break;
+ break;
}
-case wxStyledTextCtrl_GetLastKeydownProcessed: { // wxStyledTextCtrl::GetLastKeydownProcessed
+case wxStyledTextCtrl_GetLastKeydownProcessed: { // wxStyledTextCtrl::GetLastKeydownProcessed
wxStyledTextCtrl *This = (wxStyledTextCtrl *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
bool Result = This->GetLastKeydownProcessed();
rt.addBool(Result);
- break;
+ break;
}
-case wxStyledTextCtrl_SetLastKeydownProcessed: { // wxStyledTextCtrl::SetLastKeydownProcessed
+case wxStyledTextCtrl_SetLastKeydownProcessed: { // wxStyledTextCtrl::SetLastKeydownProcessed
wxStyledTextCtrl *This = (wxStyledTextCtrl *) getPtr(bp,memenv); bp += 4;
bool * val = (bool *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
This->SetLastKeydownProcessed((bool) *val);
- break;
+ break;
}
-case wxStyledTextCtrl_SaveFile: { // wxStyledTextCtrl::SaveFile
+case wxStyledTextCtrl_SaveFile: { // wxStyledTextCtrl::SaveFile
wxStyledTextCtrl *This = (wxStyledTextCtrl *) getPtr(bp,memenv); bp += 4;
int * filenameLen = (int *) bp; bp += 4;
wxString filename = wxString(bp, wxConvUTF8);
@@ -29976,9 +30018,9 @@ case wxStyledTextCtrl_SaveFile: { // wxStyledTextCtrl::SaveFile
if(!This) throw wxe_badarg(0);
bool Result = This->SaveFile(filename);
rt.addBool(Result);
- break;
+ break;
}
-case wxStyledTextCtrl_LoadFile: { // wxStyledTextCtrl::LoadFile
+case wxStyledTextCtrl_LoadFile: { // wxStyledTextCtrl::LoadFile
wxStyledTextCtrl *This = (wxStyledTextCtrl *) getPtr(bp,memenv); bp += 4;
int * filenameLen = (int *) bp; bp += 4;
wxString filename = wxString(bp, wxConvUTF8);
@@ -29986,9 +30028,9 @@ case wxStyledTextCtrl_LoadFile: { // wxStyledTextCtrl::LoadFile
if(!This) throw wxe_badarg(0);
bool Result = This->LoadFile(filename);
rt.addBool(Result);
- break;
+ break;
}
-case wxStyledTextCtrl_DoDragOver: { // wxStyledTextCtrl::DoDragOver
+case wxStyledTextCtrl_DoDragOver: { // wxStyledTextCtrl::DoDragOver
wxStyledTextCtrl *This = (wxStyledTextCtrl *) getPtr(bp,memenv); bp += 4;
int * x = (int *) bp; bp += 4;
int * y = (int *) bp; bp += 4;
@@ -29996,9 +30038,9 @@ case wxStyledTextCtrl_DoDragOver: { // wxStyledTextCtrl::DoDragOver
if(!This) throw wxe_badarg(0);
int Result = This->DoDragOver((wxCoord) *x,(wxCoord) *y,(wxDragResult) def);
rt.addInt(Result);
- break;
+ break;
}
-case wxStyledTextCtrl_DoDropText: { // wxStyledTextCtrl::DoDropText
+case wxStyledTextCtrl_DoDropText: { // wxStyledTextCtrl::DoDropText
wxStyledTextCtrl *This = (wxStyledTextCtrl *) getPtr(bp,memenv); bp += 4;
int * x = (int *) bp; bp += 4;
int * y = (int *) bp; bp += 4;
@@ -30008,31 +30050,31 @@ case wxStyledTextCtrl_DoDropText: { // wxStyledTextCtrl::DoDropText
if(!This) throw wxe_badarg(0);
bool Result = This->DoDropText((long) *x,(long) *y,data);
rt.addBool(Result);
- break;
+ break;
}
-case wxStyledTextCtrl_GetUseAntiAliasing: { // wxStyledTextCtrl::GetUseAntiAliasing
+case wxStyledTextCtrl_GetUseAntiAliasing: { // wxStyledTextCtrl::GetUseAntiAliasing
wxStyledTextCtrl *This = (wxStyledTextCtrl *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
bool Result = This->GetUseAntiAliasing();
rt.addBool(Result);
- break;
+ break;
}
-case wxStyledTextCtrl_AddTextRaw: { // wxStyledTextCtrl::AddTextRaw
+case wxStyledTextCtrl_AddTextRaw: { // wxStyledTextCtrl::AddTextRaw
wxStyledTextCtrl *This = (wxStyledTextCtrl *) getPtr(bp,memenv); bp += 4;
- const char * text = (const char*) Ecmd.bin[0]->base;
+ const char * text = (const char*) Ecmd.bin[0]->base;
if(!This) throw wxe_badarg(0);
This->AddTextRaw(text);
- break;
+ break;
}
-case wxStyledTextCtrl_InsertTextRaw: { // wxStyledTextCtrl::InsertTextRaw
+case wxStyledTextCtrl_InsertTextRaw: { // wxStyledTextCtrl::InsertTextRaw
wxStyledTextCtrl *This = (wxStyledTextCtrl *) getPtr(bp,memenv); bp += 4;
int * pos = (int *) bp; bp += 4;
- const char * text = (const char*) Ecmd.bin[0]->base;
+ const char * text = (const char*) Ecmd.bin[0]->base;
if(!This) throw wxe_badarg(0);
This->InsertTextRaw((int) *pos,text);
- break;
+ break;
}
-case wxStyledTextCtrl_GetCurLineRaw: { // wxStyledTextCtrl::GetCurLineRaw
+case wxStyledTextCtrl_GetCurLineRaw: { // wxStyledTextCtrl::GetCurLineRaw
int linePos;
wxStyledTextCtrl *This = (wxStyledTextCtrl *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
@@ -30042,9 +30084,9 @@ case wxStyledTextCtrl_GetCurLineRaw: { // wxStyledTextCtrl::GetCurLineRaw
} else {rt.addAtom("null");};
rt.addInt(linePos);
rt.addTupleCount(2);
- break;
+ break;
}
-case wxStyledTextCtrl_GetLineRaw: { // wxStyledTextCtrl::GetLineRaw
+case wxStyledTextCtrl_GetLineRaw: { // wxStyledTextCtrl::GetLineRaw
wxStyledTextCtrl *This = (wxStyledTextCtrl *) getPtr(bp,memenv); bp += 4;
int * line = (int *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
@@ -30052,18 +30094,18 @@ case wxStyledTextCtrl_GetLineRaw: { // wxStyledTextCtrl::GetLineRaw
if(Result) {
rt.addBinary(Result, strlen(Result));
} else {rt.addAtom("null");};
- break;
+ break;
}
-case wxStyledTextCtrl_GetSelectedTextRaw: { // wxStyledTextCtrl::GetSelectedTextRaw
+case wxStyledTextCtrl_GetSelectedTextRaw: { // wxStyledTextCtrl::GetSelectedTextRaw
wxStyledTextCtrl *This = (wxStyledTextCtrl *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
char * Result = This->GetSelectedTextRaw().data();
if(Result) {
rt.addBinary(Result, strlen(Result));
} else {rt.addAtom("null");};
- break;
+ break;
}
-case wxStyledTextCtrl_GetTextRangeRaw: { // wxStyledTextCtrl::GetTextRangeRaw
+case wxStyledTextCtrl_GetTextRangeRaw: { // wxStyledTextCtrl::GetTextRangeRaw
wxStyledTextCtrl *This = (wxStyledTextCtrl *) getPtr(bp,memenv); bp += 4;
int * startPos = (int *) bp; bp += 4;
int * endPos = (int *) bp; bp += 4;
@@ -30072,38 +30114,38 @@ case wxStyledTextCtrl_GetTextRangeRaw: { // wxStyledTextCtrl::GetTextRangeRaw
if(Result) {
rt.addBinary(Result, strlen(Result));
} else {rt.addAtom("null");};
- break;
+ break;
}
-case wxStyledTextCtrl_SetTextRaw: { // wxStyledTextCtrl::SetTextRaw
+case wxStyledTextCtrl_SetTextRaw: { // wxStyledTextCtrl::SetTextRaw
wxStyledTextCtrl *This = (wxStyledTextCtrl *) getPtr(bp,memenv); bp += 4;
- const char * text = (const char*) Ecmd.bin[0]->base;
+ const char * text = (const char*) Ecmd.bin[0]->base;
if(!This) throw wxe_badarg(0);
This->SetTextRaw(text);
- break;
+ break;
}
-case wxStyledTextCtrl_GetTextRaw: { // wxStyledTextCtrl::GetTextRaw
+case wxStyledTextCtrl_GetTextRaw: { // wxStyledTextCtrl::GetTextRaw
wxStyledTextCtrl *This = (wxStyledTextCtrl *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
char * Result = This->GetTextRaw().data();
if(Result) {
rt.addBinary(Result, strlen(Result));
} else {rt.addAtom("null");};
- break;
+ break;
}
-case wxStyledTextCtrl_AppendTextRaw: { // wxStyledTextCtrl::AppendTextRaw
+case wxStyledTextCtrl_AppendTextRaw: { // wxStyledTextCtrl::AppendTextRaw
wxStyledTextCtrl *This = (wxStyledTextCtrl *) getPtr(bp,memenv); bp += 4;
- const char * text = (const char*) Ecmd.bin[0]->base;
+ const char * text = (const char*) Ecmd.bin[0]->base;
if(!This) throw wxe_badarg(0);
This->AppendTextRaw(text);
- break;
+ break;
}
-case wxArtProvider_GetBitmap: { // wxArtProvider::GetBitmap
+case wxArtProvider_GetBitmap: { // wxArtProvider::GetBitmap
wxArtClient client= wxART_OTHER;
wxSize size= wxDefaultSize;
int * idLen = (int *) bp; bp += 4;
wxString id = wxString(bp, wxConvUTF8);
bp += *idLen+((8-((4+ *idLen) & 7)) & 7);
- while( * (int*) bp) { switch (* (int*) bp) {
+ while( * (int*) bp) { switch (* (int*) bp) {
case 1: {bp += 4;
int * clientLen = (int *) bp; bp += 4;
client = wxString(bp, wxConvUTF8);
@@ -30115,18 +30157,18 @@ case wxArtProvider_GetBitmap: { // wxArtProvider::GetBitmap
size = wxSize(*sizeW,*sizeH);
bp += 4; /* Align */
} break;
- }};
+ }};
wxBitmap * Result = new wxBitmap(wxArtProvider::GetBitmap(id,client,size)); newPtr((void *) Result,3, memenv);;
rt.addRef(getRef((void *)Result,memenv), "wxBitmap");
- break;
+ break;
}
-case wxArtProvider_GetIcon: { // wxArtProvider::GetIcon
+case wxArtProvider_GetIcon: { // wxArtProvider::GetIcon
wxArtClient client= wxART_OTHER;
wxSize size= wxDefaultSize;
int * idLen = (int *) bp; bp += 4;
wxString id = wxString(bp, wxConvUTF8);
bp += *idLen+((8-((4+ *idLen) & 7)) & 7);
- while( * (int*) bp) { switch (* (int*) bp) {
+ while( * (int*) bp) { switch (* (int*) bp) {
case 1: {bp += 4;
int * clientLen = (int *) bp; bp += 4;
client = wxString(bp, wxConvUTF8);
@@ -30138,324 +30180,324 @@ case wxArtProvider_GetIcon: { // wxArtProvider::GetIcon
size = wxSize(*sizeW,*sizeH);
bp += 4; /* Align */
} break;
- }};
+ }};
wxIcon * Result = new wxIcon(wxArtProvider::GetIcon(id,client,size)); newPtr((void *) Result,3, memenv);;
rt.addRef(getRef((void *)Result,memenv), "wxIcon");
- break;
+ break;
}
-case wxTreeEvent_GetKeyCode: { // wxTreeEvent::GetKeyCode
+case wxTreeEvent_GetKeyCode: { // wxTreeEvent::GetKeyCode
wxTreeEvent *This = (wxTreeEvent *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
int Result = This->GetKeyCode();
rt.addInt(Result);
- break;
+ break;
}
-case wxTreeEvent_GetItem: { // wxTreeEvent::GetItem
+case wxTreeEvent_GetItem: { // wxTreeEvent::GetItem
wxTreeEvent *This = (wxTreeEvent *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
wxTreeItemId Result = This->GetItem();
- rt.addRef(getRef((void *)Result.m_pItem,memenv), "wxTreeItemId");
- break;
+ rt.add((wxUIntPtr *) Result.m_pItem);
+ break;
}
-case wxTreeEvent_GetKeyEvent: { // wxTreeEvent::GetKeyEvent
+case wxTreeEvent_GetKeyEvent: { // wxTreeEvent::GetKeyEvent
wxTreeEvent *This = (wxTreeEvent *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
const wxKeyEvent * Result = &This->GetKeyEvent();
rt.addRef(getRef((void *)Result,memenv), "wxKeyEvent");
- break;
+ break;
}
-case wxTreeEvent_GetLabel: { // wxTreeEvent::GetLabel
+case wxTreeEvent_GetLabel: { // wxTreeEvent::GetLabel
wxTreeEvent *This = (wxTreeEvent *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
const wxString * Result = &This->GetLabel();
rt.add(Result);
- break;
+ break;
}
-case wxTreeEvent_GetOldItem: { // wxTreeEvent::GetOldItem
+case wxTreeEvent_GetOldItem: { // wxTreeEvent::GetOldItem
wxTreeEvent *This = (wxTreeEvent *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
wxTreeItemId Result = This->GetOldItem();
- rt.addRef(getRef((void *)Result.m_pItem,memenv), "wxTreeItemId");
- break;
+ rt.add((wxUIntPtr *) Result.m_pItem);
+ break;
}
-case wxTreeEvent_GetPoint: { // wxTreeEvent::GetPoint
+case wxTreeEvent_GetPoint: { // wxTreeEvent::GetPoint
wxTreeEvent *This = (wxTreeEvent *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
wxPoint Result = This->GetPoint();
rt.add(Result);
- break;
+ break;
}
-case wxTreeEvent_IsEditCancelled: { // wxTreeEvent::IsEditCancelled
+case wxTreeEvent_IsEditCancelled: { // wxTreeEvent::IsEditCancelled
wxTreeEvent *This = (wxTreeEvent *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
bool Result = This->IsEditCancelled();
rt.addBool(Result);
- break;
+ break;
}
-case wxTreeEvent_SetToolTip: { // wxTreeEvent::SetToolTip
+case wxTreeEvent_SetToolTip: { // wxTreeEvent::SetToolTip
wxTreeEvent *This = (wxTreeEvent *) getPtr(bp,memenv); bp += 4;
int * toolTipLen = (int *) bp; bp += 4;
wxString toolTip = wxString(bp, wxConvUTF8);
bp += *toolTipLen+((8-((0+ *toolTipLen) & 7)) & 7);
if(!This) throw wxe_badarg(0);
This->SetToolTip(toolTip);
- break;
+ break;
}
-case wxNotebookEvent_GetOldSelection: { // wxNotebookEvent::GetOldSelection
+case wxNotebookEvent_GetOldSelection: { // wxNotebookEvent::GetOldSelection
wxNotebookEvent *This = (wxNotebookEvent *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
int Result = This->GetOldSelection();
rt.addInt(Result);
- break;
+ break;
}
-case wxNotebookEvent_GetSelection: { // wxNotebookEvent::GetSelection
+case wxNotebookEvent_GetSelection: { // wxNotebookEvent::GetSelection
wxNotebookEvent *This = (wxNotebookEvent *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
int Result = This->GetSelection();
rt.addInt(Result);
- break;
+ break;
}
-case wxNotebookEvent_SetOldSelection: { // wxNotebookEvent::SetOldSelection
+case wxNotebookEvent_SetOldSelection: { // wxNotebookEvent::SetOldSelection
wxNotebookEvent *This = (wxNotebookEvent *) getPtr(bp,memenv); bp += 4;
int * nOldSel = (int *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
This->SetOldSelection((int) *nOldSel);
- break;
+ break;
}
-case wxNotebookEvent_SetSelection: { // wxNotebookEvent::SetSelection
+case wxNotebookEvent_SetSelection: { // wxNotebookEvent::SetSelection
wxNotebookEvent *This = (wxNotebookEvent *) getPtr(bp,memenv); bp += 4;
int * nSel = (int *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
This->SetSelection((int) *nSel);
- break;
+ break;
}
-case wxFileDataObject_new: { // wxFileDataObject::wxFileDataObject
+case wxFileDataObject_new: { // wxFileDataObject::wxFileDataObject
wxFileDataObject * Result = new wxFileDataObject();
newPtr((void *) Result, 211, memenv);
rt.addRef(getRef((void *)Result,memenv), "wxFileDataObject");
- break;
+ break;
}
-case wxFileDataObject_AddFile: { // wxFileDataObject::AddFile
+case wxFileDataObject_AddFile: { // wxFileDataObject::AddFile
wxFileDataObject *This = (wxFileDataObject *) getPtr(bp,memenv); bp += 4;
int * filenameLen = (int *) bp; bp += 4;
wxString filename = wxString(bp, wxConvUTF8);
bp += *filenameLen+((8-((0+ *filenameLen) & 7)) & 7);
if(!This) throw wxe_badarg(0);
This->AddFile(filename);
- break;
+ break;
}
-case wxFileDataObject_GetFilenames: { // wxFileDataObject::GetFilenames
+case wxFileDataObject_GetFilenames: { // wxFileDataObject::GetFilenames
wxFileDataObject *This = (wxFileDataObject *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
const wxArrayString Result = This->GetFilenames();
rt.add(Result);
- break;
+ break;
}
-case wxFileDataObject_destroy: { // wxFileDataObject::destroy
+case wxFileDataObject_destroy: { // wxFileDataObject::destroy
wxFileDataObject *This = (wxFileDataObject *) getPtr(bp,memenv); bp += 4;
if(This) { ((WxeApp *) wxTheApp)->clearPtr((void *) This);
delete This;}
- break;
+ break;
}
-case wxTextDataObject_new: { // wxTextDataObject::wxTextDataObject
+case wxTextDataObject_new: { // wxTextDataObject::wxTextDataObject
wxString text= wxEmptyString;
- while( * (int*) bp) { switch (* (int*) bp) {
+ while( * (int*) bp) { switch (* (int*) bp) {
case 1: {bp += 4;
int * textLen = (int *) bp; bp += 4;
text = wxString(bp, wxConvUTF8);
bp += *textLen+((8-((0+ *textLen) & 7)) & 7);
} break;
- }};
+ }};
wxTextDataObject * Result = new wxTextDataObject(text);
newPtr((void *) Result, 212, memenv);
rt.addRef(getRef((void *)Result,memenv), "wxTextDataObject");
- break;
+ break;
}
-case wxTextDataObject_GetTextLength: { // wxTextDataObject::GetTextLength
+case wxTextDataObject_GetTextLength: { // wxTextDataObject::GetTextLength
wxTextDataObject *This = (wxTextDataObject *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
size_t Result = This->GetTextLength();
rt.addInt(Result);
- break;
+ break;
}
-case wxTextDataObject_GetText: { // wxTextDataObject::GetText
+case wxTextDataObject_GetText: { // wxTextDataObject::GetText
wxTextDataObject *This = (wxTextDataObject *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
wxString Result = This->GetText();
rt.add(Result);
- break;
+ break;
}
-case wxTextDataObject_SetText: { // wxTextDataObject::SetText
+case wxTextDataObject_SetText: { // wxTextDataObject::SetText
wxTextDataObject *This = (wxTextDataObject *) getPtr(bp,memenv); bp += 4;
int * textLen = (int *) bp; bp += 4;
wxString text = wxString(bp, wxConvUTF8);
bp += *textLen+((8-((0+ *textLen) & 7)) & 7);
if(!This) throw wxe_badarg(0);
This->SetText(text);
- break;
+ break;
}
-case wxTextDataObject_destroy: { // wxTextDataObject::destroy
+case wxTextDataObject_destroy: { // wxTextDataObject::destroy
wxTextDataObject *This = (wxTextDataObject *) getPtr(bp,memenv); bp += 4;
if(This) { ((WxeApp *) wxTheApp)->clearPtr((void *) This);
delete This;}
- break;
+ break;
}
-case wxBitmapDataObject_new_1_1: { // wxBitmapDataObject::wxBitmapDataObject
+case wxBitmapDataObject_new_1_1: { // wxBitmapDataObject::wxBitmapDataObject
wxBitmap *bitmap = (wxBitmap *) getPtr(bp,memenv); bp += 4;
wxBitmapDataObject * Result = new wxBitmapDataObject(*bitmap);
newPtr((void *) Result, 213, memenv);
rt.addRef(getRef((void *)Result,memenv), "wxBitmapDataObject");
- break;
+ break;
}
-case wxBitmapDataObject_new_1_0: { // wxBitmapDataObject::wxBitmapDataObject
+case wxBitmapDataObject_new_1_0: { // wxBitmapDataObject::wxBitmapDataObject
const wxBitmap * bitmap= &wxNullBitmap;
- while( * (int*) bp) { switch (* (int*) bp) {
+ while( * (int*) bp) { switch (* (int*) bp) {
case 1: {bp += 4;
bitmap = (wxBitmap *) getPtr(bp,memenv); bp += 4;
} break;
- }};
+ }};
wxBitmapDataObject * Result = new wxBitmapDataObject(*bitmap);
newPtr((void *) Result, 213, memenv);
rt.addRef(getRef((void *)Result,memenv), "wxBitmapDataObject");
- break;
+ break;
}
-case wxBitmapDataObject_GetBitmap: { // wxBitmapDataObject::GetBitmap
+case wxBitmapDataObject_GetBitmap: { // wxBitmapDataObject::GetBitmap
wxBitmapDataObject *This = (wxBitmapDataObject *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
wxBitmap * Result = new wxBitmap(This->GetBitmap()); newPtr((void *) Result,3, memenv);;
rt.addRef(getRef((void *)Result,memenv), "wxBitmap");
- break;
+ break;
}
-case wxBitmapDataObject_SetBitmap: { // wxBitmapDataObject::SetBitmap
+case wxBitmapDataObject_SetBitmap: { // wxBitmapDataObject::SetBitmap
wxBitmapDataObject *This = (wxBitmapDataObject *) getPtr(bp,memenv); bp += 4;
wxBitmap *bitmap = (wxBitmap *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
This->SetBitmap(*bitmap);
- break;
+ break;
}
-case wxBitmapDataObject_destroy: { // wxBitmapDataObject::destroy
+case wxBitmapDataObject_destroy: { // wxBitmapDataObject::destroy
wxBitmapDataObject *This = (wxBitmapDataObject *) getPtr(bp,memenv); bp += 4;
if(This) { ((WxeApp *) wxTheApp)->clearPtr((void *) This);
delete This;}
- break;
+ break;
}
-case wxClipboard_new: { // wxClipboard::wxClipboard
+case wxClipboard_new: { // wxClipboard::wxClipboard
wxClipboard * Result = new EwxClipboard();
newPtr((void *) Result, 1, memenv);
rt.addRef(getRef((void *)Result,memenv), "wxClipboard");
- break;
+ break;
}
-case wxClipboard_AddData: { // wxClipboard::AddData
+case wxClipboard_AddData: { // wxClipboard::AddData
wxClipboard *This = (wxClipboard *) getPtr(bp,memenv); bp += 4;
wxDataObject *data = (wxDataObject *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
bool Result = This->AddData(data);
rt.addBool(Result);
- break;
+ break;
}
-case wxClipboard_Clear: { // wxClipboard::Clear
+case wxClipboard_Clear: { // wxClipboard::Clear
wxClipboard *This = (wxClipboard *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
This->Clear();
- break;
+ break;
}
-case wxClipboard_Close: { // wxClipboard::Close
+case wxClipboard_Close: { // wxClipboard::Close
wxClipboard *This = (wxClipboard *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
This->Close();
- break;
+ break;
}
-case wxClipboard_Flush: { // wxClipboard::Flush
+case wxClipboard_Flush: { // wxClipboard::Flush
wxClipboard *This = (wxClipboard *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
bool Result = This->Flush();
rt.addBool(Result);
- break;
+ break;
}
-case wxClipboard_GetData: { // wxClipboard::GetData
+case wxClipboard_GetData: { // wxClipboard::GetData
wxClipboard *This = (wxClipboard *) getPtr(bp,memenv); bp += 4;
wxDataObject *data = (wxDataObject *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
bool Result = This->GetData(*data);
rt.addBool(Result);
- break;
+ break;
}
-case wxClipboard_IsOpened: { // wxClipboard::IsOpened
+case wxClipboard_IsOpened: { // wxClipboard::IsOpened
wxClipboard *This = (wxClipboard *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
bool Result = This->IsOpened();
rt.addBool(Result);
- break;
+ break;
}
-case wxClipboard_Open: { // wxClipboard::Open
+case wxClipboard_Open: { // wxClipboard::Open
wxClipboard *This = (wxClipboard *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
bool Result = This->Open();
rt.addBool(Result);
- break;
+ break;
}
-case wxClipboard_SetData: { // wxClipboard::SetData
+case wxClipboard_SetData: { // wxClipboard::SetData
wxClipboard *This = (wxClipboard *) getPtr(bp,memenv); bp += 4;
wxDataObject *data = (wxDataObject *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
bool Result = This->SetData(data);
rt.addBool(Result);
- break;
+ break;
}
-case wxClipboard_UsePrimarySelection: { // wxClipboard::UsePrimarySelection
+case wxClipboard_UsePrimarySelection: { // wxClipboard::UsePrimarySelection
bool primary=false;
wxClipboard *This = (wxClipboard *) getPtr(bp,memenv); bp += 4;
bp += 4; /* Align */
- while( * (int*) bp) { switch (* (int*) bp) {
+ while( * (int*) bp) { switch (* (int*) bp) {
case 1: {bp += 4;
primary = *(bool *) bp; bp += 4;
} break;
- }};
+ }};
if(!This) throw wxe_badarg(0);
This->UsePrimarySelection(primary);
- break;
+ break;
}
-case wxClipboard_IsSupported: { // wxClipboard::IsSupported
+case wxClipboard_IsSupported: { // wxClipboard::IsSupported
wxClipboard *This = (wxClipboard *) getPtr(bp,memenv); bp += 4;
const int * format = (const int *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
bool Result = This->IsSupported((wxDataFormatId) *format);
rt.addBool(Result);
- break;
+ break;
}
-case wxClipboard_Get: { // wxClipboard::Get
+case wxClipboard_Get: { // wxClipboard::Get
wxClipboard * Result = (wxClipboard*)wxClipboard::Get();
rt.addRef(getRef((void *)Result,memenv), "wxClipboard");
- break;
+ break;
}
-case wxSpinEvent_GetPosition: { // wxSpinEvent::GetPosition
+case wxSpinEvent_GetPosition: { // wxSpinEvent::GetPosition
wxSpinEvent *This = (wxSpinEvent *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
int Result = This->GetPosition();
rt.addInt(Result);
- break;
+ break;
}
-case wxSpinEvent_SetPosition: { // wxSpinEvent::SetPosition
+case wxSpinEvent_SetPosition: { // wxSpinEvent::SetPosition
wxSpinEvent *This = (wxSpinEvent *) getPtr(bp,memenv); bp += 4;
int * pos = (int *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
This->SetPosition((int) *pos);
- break;
+ break;
}
-case wxSplitterWindow_new_0: { // wxSplitterWindow::wxSplitterWindow
+case wxSplitterWindow_new_0: { // wxSplitterWindow::wxSplitterWindow
wxSplitterWindow * Result = new EwxSplitterWindow();
newPtr((void *) Result, 0, memenv);
rt.addRef(getRef((void *)Result,memenv), "wxSplitterWindow");
- break;
+ break;
}
-case wxSplitterWindow_new_2: { // wxSplitterWindow::wxSplitterWindow
+case wxSplitterWindow_new_2: { // wxSplitterWindow::wxSplitterWindow
wxWindowID id=wxID_ANY;
wxPoint pos= wxDefaultPosition;
wxSize size= wxDefaultSize;
long style=wxSP_3D;
wxWindow *parent = (wxWindow *) getPtr(bp,memenv); bp += 4;
bp += 4; /* Align */
- while( * (int*) bp) { switch (* (int*) bp) {
+ while( * (int*) bp) { switch (* (int*) bp) {
case 1: {bp += 4;
id = (wxWindowID)*(int *) bp; bp += 4;
} break;
@@ -30474,20 +30516,20 @@ case wxSplitterWindow_new_2: { // wxSplitterWindow::wxSplitterWindow
case 4: {bp += 4;
style = (long)*(int *) bp; bp += 4;
} break;
- }};
+ }};
wxSplitterWindow * Result = new EwxSplitterWindow(parent,id,pos,size,style);
newPtr((void *) Result, 0, memenv);
rt.addRef(getRef((void *)Result,memenv), "wxSplitterWindow");
- break;
+ break;
}
-case wxSplitterWindow_Create: { // wxSplitterWindow::Create
+case wxSplitterWindow_Create: { // wxSplitterWindow::Create
wxWindowID id=wxID_ANY;
wxPoint pos= wxDefaultPosition;
wxSize size= wxDefaultSize;
long style=wxSP_3D;
wxSplitterWindow *This = (wxSplitterWindow *) getPtr(bp,memenv); bp += 4;
wxWindow *parent = (wxWindow *) getPtr(bp,memenv); bp += 4;
- while( * (int*) bp) { switch (* (int*) bp) {
+ while( * (int*) bp) { switch (* (int*) bp) {
case 1: {bp += 4;
id = (wxWindowID)*(int *) bp; bp += 4;
} break;
@@ -30506,220 +30548,220 @@ case wxSplitterWindow_Create: { // wxSplitterWindow::Create
case 4: {bp += 4;
style = (long)*(int *) bp; bp += 4;
} break;
- }};
+ }};
if(!This) throw wxe_badarg(0);
bool Result = This->Create(parent,id,pos,size,style);
rt.addBool(Result);
- break;
+ break;
}
-case wxSplitterWindow_GetMinimumPaneSize: { // wxSplitterWindow::GetMinimumPaneSize
+case wxSplitterWindow_GetMinimumPaneSize: { // wxSplitterWindow::GetMinimumPaneSize
wxSplitterWindow *This = (wxSplitterWindow *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
int Result = This->GetMinimumPaneSize();
rt.addInt(Result);
- break;
+ break;
}
-case wxSplitterWindow_GetSashGravity: { // wxSplitterWindow::GetSashGravity
+case wxSplitterWindow_GetSashGravity: { // wxSplitterWindow::GetSashGravity
wxSplitterWindow *This = (wxSplitterWindow *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
double Result = This->GetSashGravity();
rt.addFloat(Result);
- break;
+ break;
}
-case wxSplitterWindow_GetSashPosition: { // wxSplitterWindow::GetSashPosition
+case wxSplitterWindow_GetSashPosition: { // wxSplitterWindow::GetSashPosition
wxSplitterWindow *This = (wxSplitterWindow *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
int Result = This->GetSashPosition();
rt.addInt(Result);
- break;
+ break;
}
-case wxSplitterWindow_GetSplitMode: { // wxSplitterWindow::GetSplitMode
+case wxSplitterWindow_GetSplitMode: { // wxSplitterWindow::GetSplitMode
wxSplitterWindow *This = (wxSplitterWindow *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
int Result = This->GetSplitMode();
rt.addInt(Result);
- break;
+ break;
}
-case wxSplitterWindow_GetWindow1: { // wxSplitterWindow::GetWindow1
+case wxSplitterWindow_GetWindow1: { // wxSplitterWindow::GetWindow1
wxSplitterWindow *This = (wxSplitterWindow *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
wxWindow * Result = (wxWindow*)This->GetWindow1();
rt.addRef(getRef((void *)Result,memenv), "wxWindow");
- break;
+ break;
}
-case wxSplitterWindow_GetWindow2: { // wxSplitterWindow::GetWindow2
+case wxSplitterWindow_GetWindow2: { // wxSplitterWindow::GetWindow2
wxSplitterWindow *This = (wxSplitterWindow *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
wxWindow * Result = (wxWindow*)This->GetWindow2();
rt.addRef(getRef((void *)Result,memenv), "wxWindow");
- break;
+ break;
}
-case wxSplitterWindow_Initialize: { // wxSplitterWindow::Initialize
+case wxSplitterWindow_Initialize: { // wxSplitterWindow::Initialize
wxSplitterWindow *This = (wxSplitterWindow *) getPtr(bp,memenv); bp += 4;
wxWindow *window = (wxWindow *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
This->Initialize(window);
- break;
+ break;
}
-case wxSplitterWindow_IsSplit: { // wxSplitterWindow::IsSplit
+case wxSplitterWindow_IsSplit: { // wxSplitterWindow::IsSplit
wxSplitterWindow *This = (wxSplitterWindow *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
bool Result = This->IsSplit();
rt.addBool(Result);
- break;
+ break;
}
-case wxSplitterWindow_ReplaceWindow: { // wxSplitterWindow::ReplaceWindow
+case wxSplitterWindow_ReplaceWindow: { // wxSplitterWindow::ReplaceWindow
wxSplitterWindow *This = (wxSplitterWindow *) getPtr(bp,memenv); bp += 4;
wxWindow *winOld = (wxWindow *) getPtr(bp,memenv); bp += 4;
wxWindow *winNew = (wxWindow *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
bool Result = This->ReplaceWindow(winOld,winNew);
rt.addBool(Result);
- break;
+ break;
}
-case wxSplitterWindow_SetSashGravity: { // wxSplitterWindow::SetSashGravity
+case wxSplitterWindow_SetSashGravity: { // wxSplitterWindow::SetSashGravity
wxSplitterWindow *This = (wxSplitterWindow *) getPtr(bp,memenv); bp += 4;
bp += 4; /* Align */
double * gravity = (double *) bp; bp += 8;
if(!This) throw wxe_badarg(0);
This->SetSashGravity((double) *gravity);
- break;
+ break;
}
-case wxSplitterWindow_SetSashPosition: { // wxSplitterWindow::SetSashPosition
+case wxSplitterWindow_SetSashPosition: { // wxSplitterWindow::SetSashPosition
bool redraw=true;
wxSplitterWindow *This = (wxSplitterWindow *) getPtr(bp,memenv); bp += 4;
int * position = (int *) bp; bp += 4;
- while( * (int*) bp) { switch (* (int*) bp) {
+ while( * (int*) bp) { switch (* (int*) bp) {
case 1: {bp += 4;
redraw = *(bool *) bp; bp += 4;
} break;
- }};
+ }};
if(!This) throw wxe_badarg(0);
This->SetSashPosition((int) *position,redraw);
- break;
+ break;
}
-case wxSplitterWindow_SetSashSize: { // wxSplitterWindow::SetSashSize
+case wxSplitterWindow_SetSashSize: { // wxSplitterWindow::SetSashSize
wxSplitterWindow *This = (wxSplitterWindow *) getPtr(bp,memenv); bp += 4;
int * width = (int *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
This->SetSashSize((int) *width);
- break;
+ break;
}
-case wxSplitterWindow_SetMinimumPaneSize: { // wxSplitterWindow::SetMinimumPaneSize
+case wxSplitterWindow_SetMinimumPaneSize: { // wxSplitterWindow::SetMinimumPaneSize
wxSplitterWindow *This = (wxSplitterWindow *) getPtr(bp,memenv); bp += 4;
int * min = (int *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
This->SetMinimumPaneSize((int) *min);
- break;
+ break;
}
-case wxSplitterWindow_SetSplitMode: { // wxSplitterWindow::SetSplitMode
+case wxSplitterWindow_SetSplitMode: { // wxSplitterWindow::SetSplitMode
wxSplitterWindow *This = (wxSplitterWindow *) getPtr(bp,memenv); bp += 4;
int * mode = (int *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
This->SetSplitMode((int) *mode);
- break;
+ break;
}
-case wxSplitterWindow_SplitHorizontally: { // wxSplitterWindow::SplitHorizontally
+case wxSplitterWindow_SplitHorizontally: { // wxSplitterWindow::SplitHorizontally
int sashPosition=0;
wxSplitterWindow *This = (wxSplitterWindow *) getPtr(bp,memenv); bp += 4;
wxWindow *window1 = (wxWindow *) getPtr(bp,memenv); bp += 4;
wxWindow *window2 = (wxWindow *) getPtr(bp,memenv); bp += 4;
bp += 4; /* Align */
- while( * (int*) bp) { switch (* (int*) bp) {
+ while( * (int*) bp) { switch (* (int*) bp) {
case 1: {bp += 4;
sashPosition = (int)*(int *) bp; bp += 4;
} break;
- }};
+ }};
if(!This) throw wxe_badarg(0);
bool Result = This->SplitHorizontally(window1,window2,sashPosition);
rt.addBool(Result);
- break;
+ break;
}
-case wxSplitterWindow_SplitVertically: { // wxSplitterWindow::SplitVertically
+case wxSplitterWindow_SplitVertically: { // wxSplitterWindow::SplitVertically
int sashPosition=0;
wxSplitterWindow *This = (wxSplitterWindow *) getPtr(bp,memenv); bp += 4;
wxWindow *window1 = (wxWindow *) getPtr(bp,memenv); bp += 4;
wxWindow *window2 = (wxWindow *) getPtr(bp,memenv); bp += 4;
bp += 4; /* Align */
- while( * (int*) bp) { switch (* (int*) bp) {
+ while( * (int*) bp) { switch (* (int*) bp) {
case 1: {bp += 4;
sashPosition = (int)*(int *) bp; bp += 4;
} break;
- }};
+ }};
if(!This) throw wxe_badarg(0);
bool Result = This->SplitVertically(window1,window2,sashPosition);
rt.addBool(Result);
- break;
+ break;
}
-case wxSplitterWindow_Unsplit: { // wxSplitterWindow::Unsplit
+case wxSplitterWindow_Unsplit: { // wxSplitterWindow::Unsplit
wxWindow * toRemove=(wxWindow *) NULL;
wxSplitterWindow *This = (wxSplitterWindow *) getPtr(bp,memenv); bp += 4;
bp += 4; /* Align */
- while( * (int*) bp) { switch (* (int*) bp) {
+ while( * (int*) bp) { switch (* (int*) bp) {
case 1: {bp += 4;
toRemove = (wxWindow *) getPtr(bp,memenv); bp += 4;
} break;
- }};
+ }};
if(!This) throw wxe_badarg(0);
bool Result = This->Unsplit(toRemove);
rt.addBool(Result);
- break;
+ break;
}
-case wxSplitterWindow_UpdateSize: { // wxSplitterWindow::UpdateSize
+case wxSplitterWindow_UpdateSize: { // wxSplitterWindow::UpdateSize
wxSplitterWindow *This = (wxSplitterWindow *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
This->UpdateSize();
- break;
+ break;
}
-case wxSplitterEvent_GetSashPosition: { // wxSplitterEvent::GetSashPosition
+case wxSplitterEvent_GetSashPosition: { // wxSplitterEvent::GetSashPosition
wxSplitterEvent *This = (wxSplitterEvent *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
int Result = This->GetSashPosition();
rt.addInt(Result);
- break;
+ break;
}
-case wxSplitterEvent_GetX: { // wxSplitterEvent::GetX
+case wxSplitterEvent_GetX: { // wxSplitterEvent::GetX
wxSplitterEvent *This = (wxSplitterEvent *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
int Result = This->GetX();
rt.addInt(Result);
- break;
+ break;
}
-case wxSplitterEvent_GetY: { // wxSplitterEvent::GetY
+case wxSplitterEvent_GetY: { // wxSplitterEvent::GetY
wxSplitterEvent *This = (wxSplitterEvent *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
int Result = This->GetY();
rt.addInt(Result);
- break;
+ break;
}
-case wxSplitterEvent_GetWindowBeingRemoved: { // wxSplitterEvent::GetWindowBeingRemoved
+case wxSplitterEvent_GetWindowBeingRemoved: { // wxSplitterEvent::GetWindowBeingRemoved
wxSplitterEvent *This = (wxSplitterEvent *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
wxWindow * Result = (wxWindow*)This->GetWindowBeingRemoved();
rt.addRef(getRef((void *)Result,memenv), "wxWindow");
- break;
+ break;
}
-case wxSplitterEvent_SetSashPosition: { // wxSplitterEvent::SetSashPosition
+case wxSplitterEvent_SetSashPosition: { // wxSplitterEvent::SetSashPosition
wxSplitterEvent *This = (wxSplitterEvent *) getPtr(bp,memenv); bp += 4;
int * pos = (int *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
This->SetSashPosition((int) *pos);
- break;
+ break;
}
-case wxHtmlWindow_new_0: { // wxHtmlWindow::wxHtmlWindow
+case wxHtmlWindow_new_0: { // wxHtmlWindow::wxHtmlWindow
wxHtmlWindow * Result = new EwxHtmlWindow();
newPtr((void *) Result, 0, memenv);
rt.addRef(getRef((void *)Result,memenv), "wxHtmlWindow");
- break;
+ break;
}
-case wxHtmlWindow_new_2: { // wxHtmlWindow::wxHtmlWindow
+case wxHtmlWindow_new_2: { // wxHtmlWindow::wxHtmlWindow
wxWindowID id=wxID_ANY;
wxPoint pos= wxDefaultPosition;
wxSize size= wxDefaultSize;
long style=0x0004;
wxWindow *parent = (wxWindow *) getPtr(bp,memenv); bp += 4;
bp += 4; /* Align */
- while( * (int*) bp) { switch (* (int*) bp) {
+ while( * (int*) bp) { switch (* (int*) bp) {
case 1: {bp += 4;
id = (wxWindowID)*(int *) bp; bp += 4;
} break;
@@ -30738,13 +30780,13 @@ case wxHtmlWindow_new_2: { // wxHtmlWindow::wxHtmlWindow
case 4: {bp += 4;
style = (long)*(int *) bp; bp += 4;
} break;
- }};
+ }};
wxHtmlWindow * Result = new EwxHtmlWindow(parent,id,pos,size,style);
newPtr((void *) Result, 0, memenv);
rt.addRef(getRef((void *)Result,memenv), "wxHtmlWindow");
- break;
+ break;
}
-case wxHtmlWindow_AppendToPage: { // wxHtmlWindow::AppendToPage
+case wxHtmlWindow_AppendToPage: { // wxHtmlWindow::AppendToPage
wxHtmlWindow *This = (wxHtmlWindow *) getPtr(bp,memenv); bp += 4;
int * sourceLen = (int *) bp; bp += 4;
wxString source = wxString(bp, wxConvUTF8);
@@ -30752,71 +30794,71 @@ case wxHtmlWindow_AppendToPage: { // wxHtmlWindow::AppendToPage
if(!This) throw wxe_badarg(0);
bool Result = This->AppendToPage(source);
rt.addBool(Result);
- break;
+ break;
}
-case wxHtmlWindow_GetOpenedAnchor: { // wxHtmlWindow::GetOpenedAnchor
+case wxHtmlWindow_GetOpenedAnchor: { // wxHtmlWindow::GetOpenedAnchor
wxHtmlWindow *This = (wxHtmlWindow *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
wxString Result = This->GetOpenedAnchor();
rt.add(Result);
- break;
+ break;
}
-case wxHtmlWindow_GetOpenedPage: { // wxHtmlWindow::GetOpenedPage
+case wxHtmlWindow_GetOpenedPage: { // wxHtmlWindow::GetOpenedPage
wxHtmlWindow *This = (wxHtmlWindow *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
wxString Result = This->GetOpenedPage();
rt.add(Result);
- break;
+ break;
}
-case wxHtmlWindow_GetOpenedPageTitle: { // wxHtmlWindow::GetOpenedPageTitle
+case wxHtmlWindow_GetOpenedPageTitle: { // wxHtmlWindow::GetOpenedPageTitle
wxHtmlWindow *This = (wxHtmlWindow *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
wxString Result = This->GetOpenedPageTitle();
rt.add(Result);
- break;
+ break;
}
-case wxHtmlWindow_GetRelatedFrame: { // wxHtmlWindow::GetRelatedFrame
+case wxHtmlWindow_GetRelatedFrame: { // wxHtmlWindow::GetRelatedFrame
wxHtmlWindow *This = (wxHtmlWindow *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
wxFrame * Result = (wxFrame*)This->GetRelatedFrame();
rt.addRef(getRef((void *)Result,memenv), "wxFrame");
- break;
+ break;
}
-case wxHtmlWindow_HistoryBack: { // wxHtmlWindow::HistoryBack
+case wxHtmlWindow_HistoryBack: { // wxHtmlWindow::HistoryBack
wxHtmlWindow *This = (wxHtmlWindow *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
bool Result = This->HistoryBack();
rt.addBool(Result);
- break;
+ break;
}
-case wxHtmlWindow_HistoryCanBack: { // wxHtmlWindow::HistoryCanBack
+case wxHtmlWindow_HistoryCanBack: { // wxHtmlWindow::HistoryCanBack
wxHtmlWindow *This = (wxHtmlWindow *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
bool Result = This->HistoryCanBack();
rt.addBool(Result);
- break;
+ break;
}
-case wxHtmlWindow_HistoryCanForward: { // wxHtmlWindow::HistoryCanForward
+case wxHtmlWindow_HistoryCanForward: { // wxHtmlWindow::HistoryCanForward
wxHtmlWindow *This = (wxHtmlWindow *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
bool Result = This->HistoryCanForward();
rt.addBool(Result);
- break;
+ break;
}
-case wxHtmlWindow_HistoryClear: { // wxHtmlWindow::HistoryClear
+case wxHtmlWindow_HistoryClear: { // wxHtmlWindow::HistoryClear
wxHtmlWindow *This = (wxHtmlWindow *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
This->HistoryClear();
- break;
+ break;
}
-case wxHtmlWindow_HistoryForward: { // wxHtmlWindow::HistoryForward
+case wxHtmlWindow_HistoryForward: { // wxHtmlWindow::HistoryForward
wxHtmlWindow *This = (wxHtmlWindow *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
bool Result = This->HistoryForward();
rt.addBool(Result);
- break;
+ break;
}
-case wxHtmlWindow_LoadFile: { // wxHtmlWindow::LoadFile
+case wxHtmlWindow_LoadFile: { // wxHtmlWindow::LoadFile
wxHtmlWindow *This = (wxHtmlWindow *) getPtr(bp,memenv); bp += 4;
int * filenameLen = (int *) bp; bp += 4;
wxString filenameStr = wxString(bp, wxConvUTF8);
@@ -30825,9 +30867,9 @@ case wxHtmlWindow_LoadFile: { // wxHtmlWindow::LoadFile
if(!This) throw wxe_badarg(0);
bool Result = This->LoadFile(filename);
rt.addBool(Result);
- break;
+ break;
}
-case wxHtmlWindow_LoadPage: { // wxHtmlWindow::LoadPage
+case wxHtmlWindow_LoadPage: { // wxHtmlWindow::LoadPage
wxHtmlWindow *This = (wxHtmlWindow *) getPtr(bp,memenv); bp += 4;
int * locationLen = (int *) bp; bp += 4;
wxString location = wxString(bp, wxConvUTF8);
@@ -30835,47 +30877,47 @@ case wxHtmlWindow_LoadPage: { // wxHtmlWindow::LoadPage
if(!This) throw wxe_badarg(0);
bool Result = This->LoadPage(location);
rt.addBool(Result);
- break;
+ break;
}
-case wxHtmlWindow_SelectAll: { // wxHtmlWindow::SelectAll
+case wxHtmlWindow_SelectAll: { // wxHtmlWindow::SelectAll
wxHtmlWindow *This = (wxHtmlWindow *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
This->SelectAll();
- break;
+ break;
}
-case wxHtmlWindow_SelectionToText: { // wxHtmlWindow::SelectionToText
+case wxHtmlWindow_SelectionToText: { // wxHtmlWindow::SelectionToText
wxHtmlWindow *This = (wxHtmlWindow *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
wxString Result = This->SelectionToText();
rt.add(Result);
- break;
+ break;
}
-case wxHtmlWindow_SelectLine: { // wxHtmlWindow::SelectLine
+case wxHtmlWindow_SelectLine: { // wxHtmlWindow::SelectLine
wxHtmlWindow *This = (wxHtmlWindow *) getPtr(bp,memenv); bp += 4;
int * posX = (int *) bp; bp += 4;
int * posY = (int *) bp; bp += 4;
wxPoint pos = wxPoint(*posX,*posY);
if(!This) throw wxe_badarg(0);
This->SelectLine(pos);
- break;
+ break;
}
-case wxHtmlWindow_SelectWord: { // wxHtmlWindow::SelectWord
+case wxHtmlWindow_SelectWord: { // wxHtmlWindow::SelectWord
wxHtmlWindow *This = (wxHtmlWindow *) getPtr(bp,memenv); bp += 4;
int * posX = (int *) bp; bp += 4;
int * posY = (int *) bp; bp += 4;
wxPoint pos = wxPoint(*posX,*posY);
if(!This) throw wxe_badarg(0);
This->SelectWord(pos);
- break;
+ break;
}
-case wxHtmlWindow_SetBorders: { // wxHtmlWindow::SetBorders
+case wxHtmlWindow_SetBorders: { // wxHtmlWindow::SetBorders
wxHtmlWindow *This = (wxHtmlWindow *) getPtr(bp,memenv); bp += 4;
int * b = (int *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
This->SetBorders((int) *b);
- break;
+ break;
}
-case wxHtmlWindow_SetFonts: { // wxHtmlWindow::SetFonts
+case wxHtmlWindow_SetFonts: { // wxHtmlWindow::SetFonts
int *sizes=NULL;
wxHtmlWindow *This = (wxHtmlWindow *) getPtr(bp,memenv); bp += 4;
int * normal_faceLen = (int *) bp; bp += 4;
@@ -30884,16 +30926,16 @@ case wxHtmlWindow_SetFonts: { // wxHtmlWindow::SetFonts
int * fixed_faceLen = (int *) bp; bp += 4;
wxString fixed_face = wxString(bp, wxConvUTF8);
bp += *fixed_faceLen+((8-((4+ *fixed_faceLen) & 7)) & 7);
- while( * (int*) bp) { switch (* (int*) bp) {
+ while( * (int*) bp) { switch (* (int*) bp) {
case 1: {bp += 4;
sizes = (int *) bp; bp += 4;
} break;
- }};
+ }};
if(!This) throw wxe_badarg(0);
This->SetFonts(normal_face,fixed_face,sizes);
- break;
+ break;
}
-case wxHtmlWindow_SetPage: { // wxHtmlWindow::SetPage
+case wxHtmlWindow_SetPage: { // wxHtmlWindow::SetPage
wxHtmlWindow *This = (wxHtmlWindow *) getPtr(bp,memenv); bp += 4;
int * sourceLen = (int *) bp; bp += 4;
wxString source = wxString(bp, wxConvUTF8);
@@ -30901,9 +30943,9 @@ case wxHtmlWindow_SetPage: { // wxHtmlWindow::SetPage
if(!This) throw wxe_badarg(0);
bool Result = This->SetPage(source);
rt.addBool(Result);
- break;
+ break;
}
-case wxHtmlWindow_SetRelatedFrame: { // wxHtmlWindow::SetRelatedFrame
+case wxHtmlWindow_SetRelatedFrame: { // wxHtmlWindow::SetRelatedFrame
wxHtmlWindow *This = (wxHtmlWindow *) getPtr(bp,memenv); bp += 4;
wxFrame *frame = (wxFrame *) getPtr(bp,memenv); bp += 4;
int * formatLen = (int *) bp; bp += 4;
@@ -30911,172 +30953,172 @@ case wxHtmlWindow_SetRelatedFrame: { // wxHtmlWindow::SetRelatedFrame
bp += *formatLen+((8-((4+ *formatLen) & 7)) & 7);
if(!This) throw wxe_badarg(0);
This->SetRelatedFrame(frame,format);
- break;
+ break;
}
-case wxHtmlWindow_SetRelatedStatusBar: { // wxHtmlWindow::SetRelatedStatusBar
+case wxHtmlWindow_SetRelatedStatusBar: { // wxHtmlWindow::SetRelatedStatusBar
wxHtmlWindow *This = (wxHtmlWindow *) getPtr(bp,memenv); bp += 4;
int * bar = (int *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
This->SetRelatedStatusBar((int) *bar);
- break;
+ break;
}
-case wxHtmlWindow_ToText: { // wxHtmlWindow::ToText
+case wxHtmlWindow_ToText: { // wxHtmlWindow::ToText
wxHtmlWindow *This = (wxHtmlWindow *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
wxString Result = This->ToText();
rt.add(Result);
- break;
+ break;
}
-case wxHtmlLinkEvent_GetLinkInfo: { // wxHtmlLinkEvent::GetLinkInfo
+case wxHtmlLinkEvent_GetLinkInfo: { // wxHtmlLinkEvent::GetLinkInfo
wxHtmlLinkEvent *This = (wxHtmlLinkEvent *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
const wxHtmlLinkInfo * Result = &This->GetLinkInfo();
rt.add(Result);
- break;
+ break;
}
-case wxAuiNotebookEvent_SetSelection: { // wxAuiNotebookEvent::SetSelection
+case wxAuiNotebookEvent_SetSelection: { // wxAuiNotebookEvent::SetSelection
wxAuiNotebookEvent *This = (wxAuiNotebookEvent *) getPtr(bp,memenv); bp += 4;
int * s = (int *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
This->SetSelection((int) *s);
- break;
+ break;
}
-case wxAuiNotebookEvent_GetSelection: { // wxAuiNotebookEvent::GetSelection
+case wxAuiNotebookEvent_GetSelection: { // wxAuiNotebookEvent::GetSelection
wxAuiNotebookEvent *This = (wxAuiNotebookEvent *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
int Result = This->GetSelection();
rt.addInt(Result);
- break;
+ break;
}
-case wxAuiNotebookEvent_SetOldSelection: { // wxAuiNotebookEvent::SetOldSelection
+case wxAuiNotebookEvent_SetOldSelection: { // wxAuiNotebookEvent::SetOldSelection
wxAuiNotebookEvent *This = (wxAuiNotebookEvent *) getPtr(bp,memenv); bp += 4;
int * s = (int *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
This->SetOldSelection((int) *s);
- break;
+ break;
}
-case wxAuiNotebookEvent_GetOldSelection: { // wxAuiNotebookEvent::GetOldSelection
+case wxAuiNotebookEvent_GetOldSelection: { // wxAuiNotebookEvent::GetOldSelection
wxAuiNotebookEvent *This = (wxAuiNotebookEvent *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
int Result = This->GetOldSelection();
rt.addInt(Result);
- break;
+ break;
}
-case wxAuiNotebookEvent_SetDragSource: { // wxAuiNotebookEvent::SetDragSource
+case wxAuiNotebookEvent_SetDragSource: { // wxAuiNotebookEvent::SetDragSource
wxAuiNotebookEvent *This = (wxAuiNotebookEvent *) getPtr(bp,memenv); bp += 4;
wxAuiNotebook *s = (wxAuiNotebook *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
This->SetDragSource(s);
- break;
+ break;
}
-case wxAuiNotebookEvent_GetDragSource: { // wxAuiNotebookEvent::GetDragSource
+case wxAuiNotebookEvent_GetDragSource: { // wxAuiNotebookEvent::GetDragSource
wxAuiNotebookEvent *This = (wxAuiNotebookEvent *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
wxAuiNotebook * Result = (wxAuiNotebook*)This->GetDragSource();
rt.addRef(getRef((void *)Result,memenv), "wxAuiNotebook");
- break;
+ break;
}
-case wxAuiManagerEvent_SetManager: { // wxAuiManagerEvent::SetManager
+case wxAuiManagerEvent_SetManager: { // wxAuiManagerEvent::SetManager
wxAuiManagerEvent *This = (wxAuiManagerEvent *) getPtr(bp,memenv); bp += 4;
wxAuiManager *mgr = (wxAuiManager *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
This->SetManager(mgr);
- break;
+ break;
}
-case wxAuiManagerEvent_GetManager: { // wxAuiManagerEvent::GetManager
+case wxAuiManagerEvent_GetManager: { // wxAuiManagerEvent::GetManager
wxAuiManagerEvent *This = (wxAuiManagerEvent *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
wxAuiManager * Result = (wxAuiManager*)This->GetManager();
rt.addRef(getRef((void *)Result,memenv), "wxAuiManager");
- break;
+ break;
}
-case wxAuiManagerEvent_SetPane: { // wxAuiManagerEvent::SetPane
+case wxAuiManagerEvent_SetPane: { // wxAuiManagerEvent::SetPane
wxAuiManagerEvent *This = (wxAuiManagerEvent *) getPtr(bp,memenv); bp += 4;
wxAuiPaneInfo *p = (wxAuiPaneInfo *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
This->SetPane(p);
- break;
+ break;
}
-case wxAuiManagerEvent_GetPane: { // wxAuiManagerEvent::GetPane
+case wxAuiManagerEvent_GetPane: { // wxAuiManagerEvent::GetPane
wxAuiManagerEvent *This = (wxAuiManagerEvent *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
wxAuiPaneInfo * Result = (wxAuiPaneInfo*)This->GetPane();
rt.addRef(getRef((void *)Result,memenv), "wxAuiPaneInfo");
- break;
+ break;
}
-case wxAuiManagerEvent_SetButton: { // wxAuiManagerEvent::SetButton
+case wxAuiManagerEvent_SetButton: { // wxAuiManagerEvent::SetButton
wxAuiManagerEvent *This = (wxAuiManagerEvent *) getPtr(bp,memenv); bp += 4;
int * b = (int *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
This->SetButton((int) *b);
- break;
+ break;
}
-case wxAuiManagerEvent_GetButton: { // wxAuiManagerEvent::GetButton
+case wxAuiManagerEvent_GetButton: { // wxAuiManagerEvent::GetButton
wxAuiManagerEvent *This = (wxAuiManagerEvent *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
int Result = This->GetButton();
rt.addInt(Result);
- break;
+ break;
}
-case wxAuiManagerEvent_SetDC: { // wxAuiManagerEvent::SetDC
+case wxAuiManagerEvent_SetDC: { // wxAuiManagerEvent::SetDC
wxAuiManagerEvent *This = (wxAuiManagerEvent *) getPtr(bp,memenv); bp += 4;
wxDC *pdc = (wxDC *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
This->SetDC(pdc);
- break;
+ break;
}
-case wxAuiManagerEvent_GetDC: { // wxAuiManagerEvent::GetDC
+case wxAuiManagerEvent_GetDC: { // wxAuiManagerEvent::GetDC
wxAuiManagerEvent *This = (wxAuiManagerEvent *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
wxDC * Result = (wxDC*)This->GetDC();
rt.addRef(getRef((void *)Result,memenv), "wxDC");
- break;
+ break;
}
-case wxAuiManagerEvent_Veto: { // wxAuiManagerEvent::Veto
+case wxAuiManagerEvent_Veto: { // wxAuiManagerEvent::Veto
bool veto=true;
wxAuiManagerEvent *This = (wxAuiManagerEvent *) getPtr(bp,memenv); bp += 4;
bp += 4; /* Align */
- while( * (int*) bp) { switch (* (int*) bp) {
+ while( * (int*) bp) { switch (* (int*) bp) {
case 1: {bp += 4;
veto = *(bool *) bp; bp += 4;
} break;
- }};
+ }};
if(!This) throw wxe_badarg(0);
This->Veto(veto);
- break;
+ break;
}
-case wxAuiManagerEvent_GetVeto: { // wxAuiManagerEvent::GetVeto
+case wxAuiManagerEvent_GetVeto: { // wxAuiManagerEvent::GetVeto
wxAuiManagerEvent *This = (wxAuiManagerEvent *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
bool Result = This->GetVeto();
rt.addBool(Result);
- break;
+ break;
}
-case wxAuiManagerEvent_SetCanVeto: { // wxAuiManagerEvent::SetCanVeto
+case wxAuiManagerEvent_SetCanVeto: { // wxAuiManagerEvent::SetCanVeto
wxAuiManagerEvent *This = (wxAuiManagerEvent *) getPtr(bp,memenv); bp += 4;
bool * can_veto = (bool *) bp; bp += 4;
if(!This) throw wxe_badarg(0);
This->SetCanVeto((bool) *can_veto);
- break;
+ break;
}
-case wxAuiManagerEvent_CanVeto: { // wxAuiManagerEvent::CanVeto
+case wxAuiManagerEvent_CanVeto: { // wxAuiManagerEvent::CanVeto
wxAuiManagerEvent *This = (wxAuiManagerEvent *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
bool Result = This->CanVeto();
rt.addBool(Result);
- break;
+ break;
}
-case wxLogNull_new: { // wxLogNull::wxLogNull
+case wxLogNull_new: { // wxLogNull::wxLogNull
wxLogNull * Result = new wxLogNull();
newPtr((void *) Result, 222, memenv);
rt.addRef(getRef((void *)Result,memenv), "wxLogNull");
- break;
+ break;
}
-case wxLogNull_destroy: { // wxLogNull::destroy
+case wxLogNull_destroy: { // wxLogNull::destroy
wxLogNull *This = (wxLogNull *) getPtr(bp,memenv); bp += 4;
if(This) { ((WxeApp *) wxTheApp)->clearPtr((void *) This);
delete This;}
- break;
+ break;
}
default: {
wxeReturn error = wxeReturn(WXE_DRV_PORT, Ecmd.caller, false); error.addAtom("_wxe_error_");
@@ -31088,7 +31130,7 @@ case wxLogNull_destroy: { // wxLogNull::destroy
}
} // switch
rt.send();
-} catch (wxe_badarg badarg) { // try
+} catch (wxe_badarg badarg) { // try
wxeReturn error = wxeReturn(WXE_DRV_PORT, Ecmd.caller, false); error.addAtom("_wxe_error_");
error.addInt((int) Ecmd.op);
error.addAtom("badarg");
@@ -31096,4 +31138,4 @@ case wxLogNull_destroy: { // wxLogNull::destroy
error.addTupleCount(2);
error.addTupleCount(3);
error.send();
-}} /* The End */
+}} /* The End */
diff --git a/lib/wx/c_src/gen/wxe_init.cpp b/lib/wx/c_src/gen/wxe_init.cpp
index c69f853203..96c775c4c0 100644
--- a/lib/wx/c_src/gen/wxe_init.cpp
+++ b/lib/wx/c_src/gen/wxe_init.cpp
@@ -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%
*/
/* This file is also generated */
diff --git a/lib/wx/c_src/gen/wxe_macros.h b/lib/wx/c_src/gen/wxe_macros.h
index 5e4b4deb9c..cb5a4f3c41 100644
--- a/lib/wx/c_src/gen/wxe_macros.h
+++ b/lib/wx/c_src/gen/wxe_macros.h
@@ -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%
*/
#include <wx/caret.h>
@@ -1559,1760 +1559,1762 @@
#define wxListCtrl_GetColumnCount 1672
#define wxListCtrl_GetColumnWidth 1673
#define wxListCtrl_GetCountPerPage 1674
-#define wxListCtrl_GetImageList 1675
-#define wxListCtrl_GetItem 1676
-#define wxListCtrl_GetItemBackgroundColour 1677
-#define wxListCtrl_GetItemCount 1678
-#define wxListCtrl_GetItemData 1679
-#define wxListCtrl_GetItemFont 1680
-#define wxListCtrl_GetItemPosition 1681
-#define wxListCtrl_GetItemRect 1682
-#define wxListCtrl_GetItemSpacing 1683
-#define wxListCtrl_GetItemState 1684
-#define wxListCtrl_GetItemText 1685
-#define wxListCtrl_GetItemTextColour 1686
-#define wxListCtrl_GetNextItem 1687
-#define wxListCtrl_GetSelectedItemCount 1688
-#define wxListCtrl_GetTextColour 1689
-#define wxListCtrl_GetTopItem 1690
-#define wxListCtrl_GetViewRect 1691
-#define wxListCtrl_HitTest 1692
-#define wxListCtrl_InsertColumn_2 1693
-#define wxListCtrl_InsertColumn_3 1694
-#define wxListCtrl_InsertItem_1 1695
-#define wxListCtrl_InsertItem_2_1 1696
-#define wxListCtrl_InsertItem_2_0 1697
-#define wxListCtrl_InsertItem_3 1698
-#define wxListCtrl_RefreshItem 1699
-#define wxListCtrl_RefreshItems 1700
-#define wxListCtrl_ScrollList 1701
-#define wxListCtrl_SetBackgroundColour 1702
-#define wxListCtrl_SetColumn 1703
-#define wxListCtrl_SetColumnWidth 1704
-#define wxListCtrl_SetImageList 1705
-#define wxListCtrl_SetItem_1 1706
-#define wxListCtrl_SetItem_4 1707
-#define wxListCtrl_SetItemBackgroundColour 1708
-#define wxListCtrl_SetItemCount 1709
-#define wxListCtrl_SetItemData 1710
-#define wxListCtrl_SetItemFont 1711
-#define wxListCtrl_SetItemImage 1712
-#define wxListCtrl_SetItemColumnImage 1713
-#define wxListCtrl_SetItemPosition 1714
-#define wxListCtrl_SetItemState 1715
-#define wxListCtrl_SetItemText 1716
-#define wxListCtrl_SetItemTextColour 1717
-#define wxListCtrl_SetSingleStyle 1718
-#define wxListCtrl_SetTextColour 1719
-#define wxListCtrl_SetWindowStyleFlag 1720
-#define wxListCtrl_SortItems 1721
-#define wxListCtrl_destroy 1722
-#define wxListView_ClearColumnImage 1723
-#define wxListView_Focus 1724
-#define wxListView_GetFirstSelected 1725
-#define wxListView_GetFocusedItem 1726
-#define wxListView_GetNextSelected 1727
-#define wxListView_IsSelected 1728
-#define wxListView_Select 1729
-#define wxListView_SetColumnImage 1730
-#define wxListItem_new_0 1731
-#define wxListItem_new_1 1732
-#define wxListItem_destruct 1733
-#define wxListItem_Clear 1734
-#define wxListItem_GetAlign 1735
-#define wxListItem_GetBackgroundColour 1736
-#define wxListItem_GetColumn 1737
-#define wxListItem_GetFont 1738
-#define wxListItem_GetId 1739
-#define wxListItem_GetImage 1740
-#define wxListItem_GetMask 1741
-#define wxListItem_GetState 1742
-#define wxListItem_GetText 1743
-#define wxListItem_GetTextColour 1744
-#define wxListItem_GetWidth 1745
-#define wxListItem_SetAlign 1746
-#define wxListItem_SetBackgroundColour 1747
-#define wxListItem_SetColumn 1748
-#define wxListItem_SetFont 1749
-#define wxListItem_SetId 1750
-#define wxListItem_SetImage 1751
-#define wxListItem_SetMask 1752
-#define wxListItem_SetState 1753
-#define wxListItem_SetStateMask 1754
-#define wxListItem_SetText 1755
-#define wxListItem_SetTextColour 1756
-#define wxListItem_SetWidth 1757
-#define wxImageList_new_0 1758
-#define wxImageList_new_3 1759
-#define wxImageList_Add_1 1760
-#define wxImageList_Add_2_0 1761
-#define wxImageList_Add_2_1 1762
-#define wxImageList_Create 1763
-#define wxImageList_Draw 1765
-#define wxImageList_GetBitmap 1766
-#define wxImageList_GetIcon 1767
-#define wxImageList_GetImageCount 1768
-#define wxImageList_GetSize 1769
-#define wxImageList_Remove 1770
-#define wxImageList_RemoveAll 1771
-#define wxImageList_Replace_2 1772
-#define wxImageList_Replace_3 1773
-#define wxImageList_destroy 1774
-#define wxTextAttr_new_0 1775
-#define wxTextAttr_new_2 1776
-#define wxTextAttr_GetAlignment 1777
-#define wxTextAttr_GetBackgroundColour 1778
-#define wxTextAttr_GetFont 1779
-#define wxTextAttr_GetLeftIndent 1780
-#define wxTextAttr_GetLeftSubIndent 1781
-#define wxTextAttr_GetRightIndent 1782
-#define wxTextAttr_GetTabs 1783
-#define wxTextAttr_GetTextColour 1784
-#define wxTextAttr_HasBackgroundColour 1785
-#define wxTextAttr_HasFont 1786
-#define wxTextAttr_HasTextColour 1787
-#define wxTextAttr_GetFlags 1788
-#define wxTextAttr_IsDefault 1789
-#define wxTextAttr_SetAlignment 1790
-#define wxTextAttr_SetBackgroundColour 1791
-#define wxTextAttr_SetFlags 1792
-#define wxTextAttr_SetFont 1793
-#define wxTextAttr_SetLeftIndent 1794
-#define wxTextAttr_SetRightIndent 1795
-#define wxTextAttr_SetTabs 1796
-#define wxTextAttr_SetTextColour 1797
-#define wxTextAttr_destroy 1798
-#define wxTextCtrl_new_3 1800
-#define wxTextCtrl_new_0 1801
-#define wxTextCtrl_destruct 1803
-#define wxTextCtrl_AppendText 1804
-#define wxTextCtrl_CanCopy 1805
-#define wxTextCtrl_CanCut 1806
-#define wxTextCtrl_CanPaste 1807
-#define wxTextCtrl_CanRedo 1808
-#define wxTextCtrl_CanUndo 1809
-#define wxTextCtrl_Clear 1810
-#define wxTextCtrl_Copy 1811
-#define wxTextCtrl_Create 1812
-#define wxTextCtrl_Cut 1813
-#define wxTextCtrl_DiscardEdits 1814
-#define wxTextCtrl_EmulateKeyPress 1815
-#define wxTextCtrl_GetDefaultStyle 1816
-#define wxTextCtrl_GetInsertionPoint 1817
-#define wxTextCtrl_GetLastPosition 1818
-#define wxTextCtrl_GetLineLength 1819
-#define wxTextCtrl_GetLineText 1820
-#define wxTextCtrl_GetNumberOfLines 1821
-#define wxTextCtrl_GetRange 1822
-#define wxTextCtrl_GetSelection 1823
-#define wxTextCtrl_GetStringSelection 1824
-#define wxTextCtrl_GetStyle 1825
-#define wxTextCtrl_GetValue 1826
-#define wxTextCtrl_IsEditable 1827
-#define wxTextCtrl_IsModified 1828
-#define wxTextCtrl_IsMultiLine 1829
-#define wxTextCtrl_IsSingleLine 1830
-#define wxTextCtrl_LoadFile 1831
-#define wxTextCtrl_MarkDirty 1832
-#define wxTextCtrl_Paste 1833
-#define wxTextCtrl_PositionToXY 1834
-#define wxTextCtrl_Redo 1835
-#define wxTextCtrl_Remove 1836
-#define wxTextCtrl_Replace 1837
-#define wxTextCtrl_SaveFile 1838
-#define wxTextCtrl_SetDefaultStyle 1839
-#define wxTextCtrl_SetEditable 1840
-#define wxTextCtrl_SetInsertionPoint 1841
-#define wxTextCtrl_SetInsertionPointEnd 1842
-#define wxTextCtrl_SetMaxLength 1844
-#define wxTextCtrl_SetSelection 1845
-#define wxTextCtrl_SetStyle 1846
-#define wxTextCtrl_SetValue 1847
-#define wxTextCtrl_ShowPosition 1848
-#define wxTextCtrl_Undo 1849
-#define wxTextCtrl_WriteText 1850
-#define wxTextCtrl_XYToPosition 1851
-#define wxNotebook_new_0 1854
-#define wxNotebook_new_3 1855
-#define wxNotebook_destruct 1856
-#define wxNotebook_AddPage 1857
-#define wxNotebook_AdvanceSelection 1858
-#define wxNotebook_AssignImageList 1859
-#define wxNotebook_Create 1860
-#define wxNotebook_DeleteAllPages 1861
-#define wxNotebook_DeletePage 1862
-#define wxNotebook_RemovePage 1863
-#define wxNotebook_GetCurrentPage 1864
-#define wxNotebook_GetImageList 1865
-#define wxNotebook_GetPage 1867
-#define wxNotebook_GetPageCount 1868
-#define wxNotebook_GetPageImage 1869
-#define wxNotebook_GetPageText 1870
-#define wxNotebook_GetRowCount 1871
-#define wxNotebook_GetSelection 1872
-#define wxNotebook_GetThemeBackgroundColour 1873
-#define wxNotebook_HitTest 1875
-#define wxNotebook_InsertPage 1877
-#define wxNotebook_SetImageList 1878
-#define wxNotebook_SetPadding 1879
-#define wxNotebook_SetPageSize 1880
-#define wxNotebook_SetPageImage 1881
-#define wxNotebook_SetPageText 1882
-#define wxNotebook_SetSelection 1883
-#define wxNotebook_ChangeSelection 1884
-#define wxChoicebook_new_0 1885
-#define wxChoicebook_new_3 1886
-#define wxChoicebook_AddPage 1887
-#define wxChoicebook_AdvanceSelection 1888
-#define wxChoicebook_AssignImageList 1889
-#define wxChoicebook_Create 1890
-#define wxChoicebook_DeleteAllPages 1891
-#define wxChoicebook_DeletePage 1892
-#define wxChoicebook_RemovePage 1893
-#define wxChoicebook_GetCurrentPage 1894
-#define wxChoicebook_GetImageList 1895
-#define wxChoicebook_GetPage 1897
-#define wxChoicebook_GetPageCount 1898
-#define wxChoicebook_GetPageImage 1899
-#define wxChoicebook_GetPageText 1900
-#define wxChoicebook_GetSelection 1901
-#define wxChoicebook_HitTest 1902
-#define wxChoicebook_InsertPage 1903
-#define wxChoicebook_SetImageList 1904
-#define wxChoicebook_SetPageSize 1905
-#define wxChoicebook_SetPageImage 1906
-#define wxChoicebook_SetPageText 1907
-#define wxChoicebook_SetSelection 1908
-#define wxChoicebook_ChangeSelection 1909
-#define wxChoicebook_destroy 1910
-#define wxToolbook_new_0 1911
-#define wxToolbook_new_3 1912
-#define wxToolbook_AddPage 1913
-#define wxToolbook_AdvanceSelection 1914
-#define wxToolbook_AssignImageList 1915
-#define wxToolbook_Create 1916
-#define wxToolbook_DeleteAllPages 1917
-#define wxToolbook_DeletePage 1918
-#define wxToolbook_RemovePage 1919
-#define wxToolbook_GetCurrentPage 1920
-#define wxToolbook_GetImageList 1921
-#define wxToolbook_GetPage 1923
-#define wxToolbook_GetPageCount 1924
-#define wxToolbook_GetPageImage 1925
-#define wxToolbook_GetPageText 1926
-#define wxToolbook_GetSelection 1927
-#define wxToolbook_HitTest 1929
-#define wxToolbook_InsertPage 1930
-#define wxToolbook_SetImageList 1931
-#define wxToolbook_SetPageSize 1932
-#define wxToolbook_SetPageImage 1933
-#define wxToolbook_SetPageText 1934
-#define wxToolbook_SetSelection 1935
-#define wxToolbook_ChangeSelection 1936
-#define wxToolbook_destroy 1937
-#define wxListbook_new_0 1938
-#define wxListbook_new_3 1939
-#define wxListbook_AddPage 1940
-#define wxListbook_AdvanceSelection 1941
-#define wxListbook_AssignImageList 1942
-#define wxListbook_Create 1943
-#define wxListbook_DeleteAllPages 1944
-#define wxListbook_DeletePage 1945
-#define wxListbook_RemovePage 1946
-#define wxListbook_GetCurrentPage 1947
-#define wxListbook_GetImageList 1948
-#define wxListbook_GetPage 1950
-#define wxListbook_GetPageCount 1951
-#define wxListbook_GetPageImage 1952
-#define wxListbook_GetPageText 1953
-#define wxListbook_GetSelection 1954
-#define wxListbook_HitTest 1956
-#define wxListbook_InsertPage 1957
-#define wxListbook_SetImageList 1958
-#define wxListbook_SetPageSize 1959
-#define wxListbook_SetPageImage 1960
-#define wxListbook_SetPageText 1961
-#define wxListbook_SetSelection 1962
-#define wxListbook_ChangeSelection 1963
-#define wxListbook_destroy 1964
-#define wxTreebook_new_0 1965
-#define wxTreebook_new_3 1966
-#define wxTreebook_AddPage 1967
-#define wxTreebook_AdvanceSelection 1968
-#define wxTreebook_AssignImageList 1969
-#define wxTreebook_Create 1970
-#define wxTreebook_DeleteAllPages 1971
-#define wxTreebook_DeletePage 1972
-#define wxTreebook_RemovePage 1973
-#define wxTreebook_GetCurrentPage 1974
-#define wxTreebook_GetImageList 1975
-#define wxTreebook_GetPage 1977
-#define wxTreebook_GetPageCount 1978
-#define wxTreebook_GetPageImage 1979
-#define wxTreebook_GetPageText 1980
-#define wxTreebook_GetSelection 1981
-#define wxTreebook_ExpandNode 1982
-#define wxTreebook_IsNodeExpanded 1983
-#define wxTreebook_HitTest 1985
-#define wxTreebook_InsertPage 1986
-#define wxTreebook_InsertSubPage 1987
-#define wxTreebook_SetImageList 1988
-#define wxTreebook_SetPageSize 1989
-#define wxTreebook_SetPageImage 1990
-#define wxTreebook_SetPageText 1991
-#define wxTreebook_SetSelection 1992
-#define wxTreebook_ChangeSelection 1993
-#define wxTreebook_destroy 1994
-#define wxTreeCtrl_new_2 1997
-#define wxTreeCtrl_new_0 1998
-#define wxTreeCtrl_destruct 2000
-#define wxTreeCtrl_AddRoot 2001
-#define wxTreeCtrl_AppendItem 2002
-#define wxTreeCtrl_AssignImageList 2003
-#define wxTreeCtrl_AssignStateImageList 2004
-#define wxTreeCtrl_Collapse 2005
-#define wxTreeCtrl_CollapseAndReset 2006
-#define wxTreeCtrl_Create 2007
-#define wxTreeCtrl_Delete 2008
-#define wxTreeCtrl_DeleteAllItems 2009
-#define wxTreeCtrl_DeleteChildren 2010
-#define wxTreeCtrl_EnsureVisible 2011
-#define wxTreeCtrl_Expand 2012
-#define wxTreeCtrl_GetBoundingRect 2013
-#define wxTreeCtrl_GetChildrenCount 2015
-#define wxTreeCtrl_GetCount 2016
-#define wxTreeCtrl_GetEditControl 2017
-#define wxTreeCtrl_GetFirstVisibleItem 2018
-#define wxTreeCtrl_GetImageList 2019
-#define wxTreeCtrl_GetIndent 2020
-#define wxTreeCtrl_GetItemBackgroundColour 2021
-#define wxTreeCtrl_GetItemData 2022
-#define wxTreeCtrl_GetItemFont 2023
-#define wxTreeCtrl_GetItemImage_1 2024
-#define wxTreeCtrl_GetItemImage_2 2025
-#define wxTreeCtrl_GetItemText 2026
-#define wxTreeCtrl_GetItemTextColour 2027
-#define wxTreeCtrl_GetLastChild 2028
-#define wxTreeCtrl_GetNextSibling 2029
-#define wxTreeCtrl_GetNextVisible 2030
-#define wxTreeCtrl_GetItemParent 2031
-#define wxTreeCtrl_GetPrevSibling 2032
-#define wxTreeCtrl_GetPrevVisible 2033
-#define wxTreeCtrl_GetRootItem 2034
-#define wxTreeCtrl_GetSelection 2035
-#define wxTreeCtrl_GetSelections 2036
-#define wxTreeCtrl_GetStateImageList 2037
-#define wxTreeCtrl_HitTest 2038
-#define wxTreeCtrl_InsertItem_4_1 2039
-#define wxTreeCtrl_InsertItem_4_0 2040
-#define wxTreeCtrl_IsBold 2041
-#define wxTreeCtrl_IsExpanded 2042
-#define wxTreeCtrl_IsSelected 2043
-#define wxTreeCtrl_IsVisible 2044
-#define wxTreeCtrl_ItemHasChildren 2045
-#define wxTreeCtrl_PrependItem 2046
-#define wxTreeCtrl_ScrollTo 2047
-#define wxTreeCtrl_SelectItem_1 2048
-#define wxTreeCtrl_SelectItem_2 2049
-#define wxTreeCtrl_SetIndent 2050
-#define wxTreeCtrl_SetImageList 2051
-#define wxTreeCtrl_SetItemBackgroundColour 2052
-#define wxTreeCtrl_SetItemBold 2053
-#define wxTreeCtrl_SetItemData 2054
-#define wxTreeCtrl_SetItemDropHighlight 2055
-#define wxTreeCtrl_SetItemFont 2056
-#define wxTreeCtrl_SetItemHasChildren 2057
-#define wxTreeCtrl_SetItemImage_2 2058
-#define wxTreeCtrl_SetItemImage_3 2059
-#define wxTreeCtrl_SetItemText 2060
-#define wxTreeCtrl_SetItemTextColour 2061
-#define wxTreeCtrl_SetStateImageList 2062
-#define wxTreeCtrl_SetWindowStyle 2063
-#define wxTreeCtrl_SortChildren 2064
-#define wxTreeCtrl_Toggle 2065
-#define wxTreeCtrl_ToggleItemSelection 2066
-#define wxTreeCtrl_Unselect 2067
-#define wxTreeCtrl_UnselectAll 2068
-#define wxTreeCtrl_UnselectItem 2069
-#define wxScrollBar_new_0 2070
-#define wxScrollBar_new_3 2071
-#define wxScrollBar_destruct 2072
-#define wxScrollBar_Create 2073
-#define wxScrollBar_GetRange 2074
-#define wxScrollBar_GetPageSize 2075
-#define wxScrollBar_GetThumbPosition 2076
-#define wxScrollBar_GetThumbSize 2077
-#define wxScrollBar_SetThumbPosition 2078
-#define wxScrollBar_SetScrollbar 2079
-#define wxSpinButton_new_2 2081
-#define wxSpinButton_new_0 2082
-#define wxSpinButton_Create 2083
-#define wxSpinButton_GetMax 2084
-#define wxSpinButton_GetMin 2085
-#define wxSpinButton_GetValue 2086
-#define wxSpinButton_SetRange 2087
-#define wxSpinButton_SetValue 2088
-#define wxSpinButton_destroy 2089
-#define wxSpinCtrl_new_0 2090
-#define wxSpinCtrl_new_2 2091
-#define wxSpinCtrl_Create 2093
-#define wxSpinCtrl_SetValue_1_1 2096
-#define wxSpinCtrl_SetValue_1_0 2097
-#define wxSpinCtrl_GetValue 2099
-#define wxSpinCtrl_SetRange 2101
-#define wxSpinCtrl_SetSelection 2102
-#define wxSpinCtrl_GetMin 2104
-#define wxSpinCtrl_GetMax 2106
-#define wxSpinCtrl_destroy 2107
-#define wxStaticText_new_0 2108
-#define wxStaticText_new_4 2109
-#define wxStaticText_Create 2110
-#define wxStaticText_GetLabel 2111
-#define wxStaticText_SetLabel 2112
-#define wxStaticText_Wrap 2113
-#define wxStaticText_destroy 2114
-#define wxStaticBitmap_new_0 2115
-#define wxStaticBitmap_new_4 2116
-#define wxStaticBitmap_Create 2117
-#define wxStaticBitmap_GetBitmap 2118
-#define wxStaticBitmap_SetBitmap 2119
-#define wxStaticBitmap_destroy 2120
-#define wxRadioBox_new 2121
-#define wxRadioBox_destruct 2123
-#define wxRadioBox_Create 2124
-#define wxRadioBox_Enable_2 2125
-#define wxRadioBox_Enable_1 2126
-#define wxRadioBox_GetSelection 2127
-#define wxRadioBox_GetString 2128
-#define wxRadioBox_SetSelection 2129
-#define wxRadioBox_Show_2 2130
-#define wxRadioBox_Show_1 2131
-#define wxRadioBox_GetColumnCount 2132
-#define wxRadioBox_GetItemHelpText 2133
-#define wxRadioBox_GetItemToolTip 2134
-#define wxRadioBox_GetItemFromPoint 2136
-#define wxRadioBox_GetRowCount 2137
-#define wxRadioBox_IsItemEnabled 2138
-#define wxRadioBox_IsItemShown 2139
-#define wxRadioBox_SetItemHelpText 2140
-#define wxRadioBox_SetItemToolTip 2141
-#define wxRadioButton_new_0 2142
-#define wxRadioButton_new_4 2143
-#define wxRadioButton_Create 2144
-#define wxRadioButton_GetValue 2145
-#define wxRadioButton_SetValue 2146
-#define wxRadioButton_destroy 2147
-#define wxSlider_new_6 2149
-#define wxSlider_new_0 2150
-#define wxSlider_Create 2151
-#define wxSlider_GetLineSize 2152
-#define wxSlider_GetMax 2153
-#define wxSlider_GetMin 2154
-#define wxSlider_GetPageSize 2155
-#define wxSlider_GetThumbLength 2156
-#define wxSlider_GetValue 2157
-#define wxSlider_SetLineSize 2158
-#define wxSlider_SetPageSize 2159
-#define wxSlider_SetRange 2160
-#define wxSlider_SetThumbLength 2161
-#define wxSlider_SetValue 2162
-#define wxSlider_destroy 2163
-#define wxDialog_new_4 2165
-#define wxDialog_new_0 2166
-#define wxDialog_destruct 2168
-#define wxDialog_Create 2169
-#define wxDialog_CreateButtonSizer 2170
-#define wxDialog_CreateStdDialogButtonSizer 2171
-#define wxDialog_EndModal 2172
-#define wxDialog_GetAffirmativeId 2173
-#define wxDialog_GetReturnCode 2174
-#define wxDialog_IsModal 2175
-#define wxDialog_SetAffirmativeId 2176
-#define wxDialog_SetReturnCode 2177
-#define wxDialog_Show 2178
-#define wxDialog_ShowModal 2179
-#define wxColourDialog_new_0 2180
-#define wxColourDialog_new_2 2181
-#define wxColourDialog_destruct 2182
-#define wxColourDialog_Create 2183
-#define wxColourDialog_GetColourData 2184
-#define wxColourData_new_0 2185
-#define wxColourData_new_1 2186
-#define wxColourData_destruct 2187
-#define wxColourData_GetChooseFull 2188
-#define wxColourData_GetColour 2189
-#define wxColourData_GetCustomColour 2191
-#define wxColourData_SetChooseFull 2192
-#define wxColourData_SetColour 2193
-#define wxColourData_SetCustomColour 2194
-#define wxPalette_new_0 2195
-#define wxPalette_new_4 2196
-#define wxPalette_destruct 2198
-#define wxPalette_Create 2199
-#define wxPalette_GetColoursCount 2200
-#define wxPalette_GetPixel 2201
-#define wxPalette_GetRGB 2202
-#define wxPalette_IsOk 2203
-#define wxDirDialog_new 2207
-#define wxDirDialog_destruct 2208
-#define wxDirDialog_GetPath 2209
-#define wxDirDialog_GetMessage 2210
-#define wxDirDialog_SetMessage 2211
-#define wxDirDialog_SetPath 2212
-#define wxFileDialog_new 2216
-#define wxFileDialog_destruct 2217
-#define wxFileDialog_GetDirectory 2218
-#define wxFileDialog_GetFilename 2219
-#define wxFileDialog_GetFilenames 2220
-#define wxFileDialog_GetFilterIndex 2221
-#define wxFileDialog_GetMessage 2222
-#define wxFileDialog_GetPath 2223
-#define wxFileDialog_GetPaths 2224
-#define wxFileDialog_GetWildcard 2225
-#define wxFileDialog_SetDirectory 2226
-#define wxFileDialog_SetFilename 2227
-#define wxFileDialog_SetFilterIndex 2228
-#define wxFileDialog_SetMessage 2229
-#define wxFileDialog_SetPath 2230
-#define wxFileDialog_SetWildcard 2231
-#define wxPickerBase_SetInternalMargin 2232
-#define wxPickerBase_GetInternalMargin 2233
-#define wxPickerBase_SetTextCtrlProportion 2234
-#define wxPickerBase_SetPickerCtrlProportion 2235
-#define wxPickerBase_GetTextCtrlProportion 2236
-#define wxPickerBase_GetPickerCtrlProportion 2237
-#define wxPickerBase_HasTextCtrl 2238
-#define wxPickerBase_GetTextCtrl 2239
-#define wxPickerBase_IsTextCtrlGrowable 2240
-#define wxPickerBase_SetPickerCtrlGrowable 2241
-#define wxPickerBase_SetTextCtrlGrowable 2242
-#define wxPickerBase_IsPickerCtrlGrowable 2243
-#define wxFilePickerCtrl_new_0 2244
-#define wxFilePickerCtrl_new_3 2245
-#define wxFilePickerCtrl_Create 2246
-#define wxFilePickerCtrl_GetPath 2247
-#define wxFilePickerCtrl_SetPath 2248
-#define wxFilePickerCtrl_destroy 2249
-#define wxDirPickerCtrl_new_0 2250
-#define wxDirPickerCtrl_new_3 2251
-#define wxDirPickerCtrl_Create 2252
-#define wxDirPickerCtrl_GetPath 2253
-#define wxDirPickerCtrl_SetPath 2254
-#define wxDirPickerCtrl_destroy 2255
-#define wxColourPickerCtrl_new_0 2256
-#define wxColourPickerCtrl_new_3 2257
-#define wxColourPickerCtrl_Create 2258
-#define wxColourPickerCtrl_GetColour 2259
-#define wxColourPickerCtrl_SetColour_1_1 2260
-#define wxColourPickerCtrl_SetColour_1_0 2261
-#define wxColourPickerCtrl_destroy 2262
-#define wxDatePickerCtrl_new_0 2263
-#define wxDatePickerCtrl_new_3 2264
-#define wxDatePickerCtrl_GetRange 2265
-#define wxDatePickerCtrl_GetValue 2266
-#define wxDatePickerCtrl_SetRange 2267
-#define wxDatePickerCtrl_SetValue 2268
-#define wxDatePickerCtrl_destroy 2269
-#define wxFontPickerCtrl_new_0 2270
-#define wxFontPickerCtrl_new_3 2271
-#define wxFontPickerCtrl_Create 2272
-#define wxFontPickerCtrl_GetSelectedFont 2273
-#define wxFontPickerCtrl_SetSelectedFont 2274
-#define wxFontPickerCtrl_GetMaxPointSize 2275
-#define wxFontPickerCtrl_SetMaxPointSize 2276
-#define wxFontPickerCtrl_destroy 2277
-#define wxFindReplaceDialog_new_0 2280
-#define wxFindReplaceDialog_new_4 2281
-#define wxFindReplaceDialog_destruct 2282
-#define wxFindReplaceDialog_Create 2283
-#define wxFindReplaceDialog_GetData 2284
-#define wxFindReplaceData_new_0 2285
-#define wxFindReplaceData_new_1 2286
-#define wxFindReplaceData_GetFindString 2287
-#define wxFindReplaceData_GetReplaceString 2288
-#define wxFindReplaceData_GetFlags 2289
-#define wxFindReplaceData_SetFlags 2290
-#define wxFindReplaceData_SetFindString 2291
-#define wxFindReplaceData_SetReplaceString 2292
-#define wxFindReplaceData_destroy 2293
-#define wxMultiChoiceDialog_new_0 2294
-#define wxMultiChoiceDialog_new_5 2296
-#define wxMultiChoiceDialog_GetSelections 2297
-#define wxMultiChoiceDialog_SetSelections 2298
-#define wxMultiChoiceDialog_destroy 2299
-#define wxSingleChoiceDialog_new_0 2300
-#define wxSingleChoiceDialog_new_5 2302
-#define wxSingleChoiceDialog_GetSelection 2303
-#define wxSingleChoiceDialog_GetStringSelection 2304
-#define wxSingleChoiceDialog_SetSelection 2305
-#define wxSingleChoiceDialog_destroy 2306
-#define wxTextEntryDialog_new 2307
-#define wxTextEntryDialog_GetValue 2308
-#define wxTextEntryDialog_SetValue 2309
-#define wxTextEntryDialog_destroy 2310
-#define wxPasswordEntryDialog_new 2311
-#define wxPasswordEntryDialog_destroy 2312
-#define wxFontData_new_0 2313
-#define wxFontData_new_1 2314
-#define wxFontData_destruct 2315
-#define wxFontData_EnableEffects 2316
-#define wxFontData_GetAllowSymbols 2317
-#define wxFontData_GetColour 2318
-#define wxFontData_GetChosenFont 2319
-#define wxFontData_GetEnableEffects 2320
-#define wxFontData_GetInitialFont 2321
-#define wxFontData_GetShowHelp 2322
-#define wxFontData_SetAllowSymbols 2323
-#define wxFontData_SetChosenFont 2324
-#define wxFontData_SetColour 2325
-#define wxFontData_SetInitialFont 2326
-#define wxFontData_SetRange 2327
-#define wxFontData_SetShowHelp 2328
-#define wxFontDialog_new_0 2332
-#define wxFontDialog_new_2 2334
-#define wxFontDialog_Create 2336
-#define wxFontDialog_GetFontData 2337
-#define wxFontDialog_destroy 2339
-#define wxProgressDialog_new 2340
-#define wxProgressDialog_destruct 2341
-#define wxProgressDialog_Resume 2342
-#define wxProgressDialog_Update_2 2343
-#define wxProgressDialog_Update_0 2344
-#define wxMessageDialog_new 2345
-#define wxMessageDialog_destruct 2346
-#define wxPageSetupDialog_new 2347
-#define wxPageSetupDialog_destruct 2348
-#define wxPageSetupDialog_GetPageSetupData 2349
-#define wxPageSetupDialog_ShowModal 2350
-#define wxPageSetupDialogData_new_0 2351
-#define wxPageSetupDialogData_new_1_0 2352
-#define wxPageSetupDialogData_new_1_1 2353
-#define wxPageSetupDialogData_destruct 2354
-#define wxPageSetupDialogData_EnableHelp 2355
-#define wxPageSetupDialogData_EnableMargins 2356
-#define wxPageSetupDialogData_EnableOrientation 2357
-#define wxPageSetupDialogData_EnablePaper 2358
-#define wxPageSetupDialogData_EnablePrinter 2359
-#define wxPageSetupDialogData_GetDefaultMinMargins 2360
-#define wxPageSetupDialogData_GetEnableMargins 2361
-#define wxPageSetupDialogData_GetEnableOrientation 2362
-#define wxPageSetupDialogData_GetEnablePaper 2363
-#define wxPageSetupDialogData_GetEnablePrinter 2364
-#define wxPageSetupDialogData_GetEnableHelp 2365
-#define wxPageSetupDialogData_GetDefaultInfo 2366
-#define wxPageSetupDialogData_GetMarginTopLeft 2367
-#define wxPageSetupDialogData_GetMarginBottomRight 2368
-#define wxPageSetupDialogData_GetMinMarginTopLeft 2369
-#define wxPageSetupDialogData_GetMinMarginBottomRight 2370
-#define wxPageSetupDialogData_GetPaperId 2371
-#define wxPageSetupDialogData_GetPaperSize 2372
-#define wxPageSetupDialogData_GetPrintData 2374
-#define wxPageSetupDialogData_IsOk 2375
-#define wxPageSetupDialogData_SetDefaultInfo 2376
-#define wxPageSetupDialogData_SetDefaultMinMargins 2377
-#define wxPageSetupDialogData_SetMarginTopLeft 2378
-#define wxPageSetupDialogData_SetMarginBottomRight 2379
-#define wxPageSetupDialogData_SetMinMarginTopLeft 2380
-#define wxPageSetupDialogData_SetMinMarginBottomRight 2381
-#define wxPageSetupDialogData_SetPaperId 2382
-#define wxPageSetupDialogData_SetPaperSize_1_1 2383
-#define wxPageSetupDialogData_SetPaperSize_1_0 2384
-#define wxPageSetupDialogData_SetPrintData 2385
-#define wxPrintDialog_new_2_0 2386
-#define wxPrintDialog_new_2_1 2387
-#define wxPrintDialog_destruct 2388
-#define wxPrintDialog_GetPrintDialogData 2389
-#define wxPrintDialog_GetPrintDC 2390
-#define wxPrintDialogData_new_0 2391
-#define wxPrintDialogData_new_1_1 2392
-#define wxPrintDialogData_new_1_0 2393
-#define wxPrintDialogData_destruct 2394
-#define wxPrintDialogData_EnableHelp 2395
-#define wxPrintDialogData_EnablePageNumbers 2396
-#define wxPrintDialogData_EnablePrintToFile 2397
-#define wxPrintDialogData_EnableSelection 2398
-#define wxPrintDialogData_GetAllPages 2399
-#define wxPrintDialogData_GetCollate 2400
-#define wxPrintDialogData_GetFromPage 2401
-#define wxPrintDialogData_GetMaxPage 2402
-#define wxPrintDialogData_GetMinPage 2403
-#define wxPrintDialogData_GetNoCopies 2404
-#define wxPrintDialogData_GetPrintData 2405
-#define wxPrintDialogData_GetPrintToFile 2406
-#define wxPrintDialogData_GetSelection 2407
-#define wxPrintDialogData_GetToPage 2408
-#define wxPrintDialogData_IsOk 2409
-#define wxPrintDialogData_SetCollate 2410
-#define wxPrintDialogData_SetFromPage 2411
-#define wxPrintDialogData_SetMaxPage 2412
-#define wxPrintDialogData_SetMinPage 2413
-#define wxPrintDialogData_SetNoCopies 2414
-#define wxPrintDialogData_SetPrintData 2415
-#define wxPrintDialogData_SetPrintToFile 2416
-#define wxPrintDialogData_SetSelection 2417
-#define wxPrintDialogData_SetToPage 2418
-#define wxPrintData_new_0 2419
-#define wxPrintData_new_1 2420
-#define wxPrintData_destruct 2421
-#define wxPrintData_GetCollate 2422
-#define wxPrintData_GetBin 2423
-#define wxPrintData_GetColour 2424
-#define wxPrintData_GetDuplex 2425
-#define wxPrintData_GetNoCopies 2426
-#define wxPrintData_GetOrientation 2427
-#define wxPrintData_GetPaperId 2428
-#define wxPrintData_GetPrinterName 2429
-#define wxPrintData_GetQuality 2430
-#define wxPrintData_IsOk 2431
-#define wxPrintData_SetBin 2432
-#define wxPrintData_SetCollate 2433
-#define wxPrintData_SetColour 2434
-#define wxPrintData_SetDuplex 2435
-#define wxPrintData_SetNoCopies 2436
-#define wxPrintData_SetOrientation 2437
-#define wxPrintData_SetPaperId 2438
-#define wxPrintData_SetPrinterName 2439
-#define wxPrintData_SetQuality 2440
-#define wxPrintPreview_new_2 2443
-#define wxPrintPreview_new_3 2444
-#define wxPrintPreview_destruct 2446
-#define wxPrintPreview_GetCanvas 2447
-#define wxPrintPreview_GetCurrentPage 2448
-#define wxPrintPreview_GetFrame 2449
-#define wxPrintPreview_GetMaxPage 2450
-#define wxPrintPreview_GetMinPage 2451
-#define wxPrintPreview_GetPrintout 2452
-#define wxPrintPreview_GetPrintoutForPrinting 2453
-#define wxPrintPreview_IsOk 2454
-#define wxPrintPreview_PaintPage 2455
-#define wxPrintPreview_Print 2456
-#define wxPrintPreview_RenderPage 2457
-#define wxPrintPreview_SetCanvas 2458
-#define wxPrintPreview_SetCurrentPage 2459
-#define wxPrintPreview_SetFrame 2460
-#define wxPrintPreview_SetPrintout 2461
-#define wxPrintPreview_SetZoom 2462
-#define wxPreviewFrame_new 2463
-#define wxPreviewFrame_destruct 2464
-#define wxPreviewFrame_CreateControlBar 2465
-#define wxPreviewFrame_CreateCanvas 2466
-#define wxPreviewFrame_Initialize 2467
-#define wxPreviewFrame_OnCloseWindow 2468
-#define wxPreviewControlBar_new 2469
-#define wxPreviewControlBar_destruct 2470
-#define wxPreviewControlBar_CreateButtons 2471
-#define wxPreviewControlBar_GetPrintPreview 2472
-#define wxPreviewControlBar_GetZoomControl 2473
-#define wxPreviewControlBar_SetZoomControl 2474
-#define wxPrinter_new 2476
-#define wxPrinter_CreateAbortWindow 2477
-#define wxPrinter_GetAbort 2478
-#define wxPrinter_GetLastError 2479
-#define wxPrinter_GetPrintDialogData 2480
-#define wxPrinter_Print 2481
-#define wxPrinter_PrintDialog 2482
-#define wxPrinter_ReportError 2483
-#define wxPrinter_Setup 2484
-#define wxPrinter_destroy 2485
-#define wxXmlResource_new_1 2486
-#define wxXmlResource_new_2 2487
-#define wxXmlResource_destruct 2488
-#define wxXmlResource_AttachUnknownControl 2489
-#define wxXmlResource_ClearHandlers 2490
-#define wxXmlResource_CompareVersion 2491
-#define wxXmlResource_Get 2492
-#define wxXmlResource_GetFlags 2493
-#define wxXmlResource_GetVersion 2494
-#define wxXmlResource_GetXRCID 2495
-#define wxXmlResource_InitAllHandlers 2496
-#define wxXmlResource_Load 2497
-#define wxXmlResource_LoadBitmap 2498
-#define wxXmlResource_LoadDialog_2 2499
-#define wxXmlResource_LoadDialog_3 2500
-#define wxXmlResource_LoadFrame_2 2501
-#define wxXmlResource_LoadFrame_3 2502
-#define wxXmlResource_LoadIcon 2503
-#define wxXmlResource_LoadMenu 2504
-#define wxXmlResource_LoadMenuBar_2 2505
-#define wxXmlResource_LoadMenuBar_1 2506
-#define wxXmlResource_LoadPanel_2 2507
-#define wxXmlResource_LoadPanel_3 2508
-#define wxXmlResource_LoadToolBar 2509
-#define wxXmlResource_Set 2510
-#define wxXmlResource_SetFlags 2511
-#define wxXmlResource_Unload 2512
-#define wxXmlResource_xrcctrl 2513
-#define wxHtmlEasyPrinting_new 2514
-#define wxHtmlEasyPrinting_destruct 2515
-#define wxHtmlEasyPrinting_GetPrintData 2516
-#define wxHtmlEasyPrinting_GetPageSetupData 2517
-#define wxHtmlEasyPrinting_PreviewFile 2518
-#define wxHtmlEasyPrinting_PreviewText 2519
-#define wxHtmlEasyPrinting_PrintFile 2520
-#define wxHtmlEasyPrinting_PrintText 2521
-#define wxHtmlEasyPrinting_PageSetup 2522
-#define wxHtmlEasyPrinting_SetFonts 2523
-#define wxHtmlEasyPrinting_SetHeader 2524
-#define wxHtmlEasyPrinting_SetFooter 2525
-#define wxGLCanvas_new_2 2527
-#define wxGLCanvas_new_3_1 2528
-#define wxGLCanvas_new_3_0 2529
-#define wxGLCanvas_GetContext 2530
-#define wxGLCanvas_SetCurrent 2532
-#define wxGLCanvas_SwapBuffers 2533
-#define wxGLCanvas_destroy 2534
-#define wxAuiManager_new 2535
-#define wxAuiManager_destruct 2536
-#define wxAuiManager_AddPane_2_1 2537
-#define wxAuiManager_AddPane_3 2538
-#define wxAuiManager_AddPane_2_0 2539
-#define wxAuiManager_DetachPane 2540
-#define wxAuiManager_GetAllPanes 2541
-#define wxAuiManager_GetArtProvider 2542
-#define wxAuiManager_GetDockSizeConstraint 2543
-#define wxAuiManager_GetFlags 2544
-#define wxAuiManager_GetManagedWindow 2545
-#define wxAuiManager_GetManager 2546
-#define wxAuiManager_GetPane_1_1 2547
-#define wxAuiManager_GetPane_1_0 2548
-#define wxAuiManager_HideHint 2549
-#define wxAuiManager_InsertPane 2550
-#define wxAuiManager_LoadPaneInfo 2551
-#define wxAuiManager_LoadPerspective 2552
-#define wxAuiManager_SavePaneInfo 2553
-#define wxAuiManager_SavePerspective 2554
-#define wxAuiManager_SetArtProvider 2555
-#define wxAuiManager_SetDockSizeConstraint 2556
-#define wxAuiManager_SetFlags 2557
-#define wxAuiManager_SetManagedWindow 2558
-#define wxAuiManager_ShowHint 2559
-#define wxAuiManager_UnInit 2560
-#define wxAuiManager_Update 2561
-#define wxAuiPaneInfo_new_0 2562
-#define wxAuiPaneInfo_new_1 2563
-#define wxAuiPaneInfo_destruct 2564
-#define wxAuiPaneInfo_BestSize_1 2565
-#define wxAuiPaneInfo_BestSize_2 2566
-#define wxAuiPaneInfo_Bottom 2567
-#define wxAuiPaneInfo_BottomDockable 2568
-#define wxAuiPaneInfo_Caption 2569
-#define wxAuiPaneInfo_CaptionVisible 2570
-#define wxAuiPaneInfo_Centre 2571
-#define wxAuiPaneInfo_CentrePane 2572
-#define wxAuiPaneInfo_CloseButton 2573
-#define wxAuiPaneInfo_DefaultPane 2574
-#define wxAuiPaneInfo_DestroyOnClose 2575
-#define wxAuiPaneInfo_Direction 2576
-#define wxAuiPaneInfo_Dock 2577
-#define wxAuiPaneInfo_Dockable 2578
-#define wxAuiPaneInfo_Fixed 2579
-#define wxAuiPaneInfo_Float 2580
-#define wxAuiPaneInfo_Floatable 2581
-#define wxAuiPaneInfo_FloatingPosition_1 2582
-#define wxAuiPaneInfo_FloatingPosition_2 2583
-#define wxAuiPaneInfo_FloatingSize_1 2584
-#define wxAuiPaneInfo_FloatingSize_2 2585
-#define wxAuiPaneInfo_Gripper 2586
-#define wxAuiPaneInfo_GripperTop 2587
-#define wxAuiPaneInfo_HasBorder 2588
-#define wxAuiPaneInfo_HasCaption 2589
-#define wxAuiPaneInfo_HasCloseButton 2590
-#define wxAuiPaneInfo_HasFlag 2591
-#define wxAuiPaneInfo_HasGripper 2592
-#define wxAuiPaneInfo_HasGripperTop 2593
-#define wxAuiPaneInfo_HasMaximizeButton 2594
-#define wxAuiPaneInfo_HasMinimizeButton 2595
-#define wxAuiPaneInfo_HasPinButton 2596
-#define wxAuiPaneInfo_Hide 2597
-#define wxAuiPaneInfo_IsBottomDockable 2598
-#define wxAuiPaneInfo_IsDocked 2599
-#define wxAuiPaneInfo_IsFixed 2600
-#define wxAuiPaneInfo_IsFloatable 2601
-#define wxAuiPaneInfo_IsFloating 2602
-#define wxAuiPaneInfo_IsLeftDockable 2603
-#define wxAuiPaneInfo_IsMovable 2604
-#define wxAuiPaneInfo_IsOk 2605
-#define wxAuiPaneInfo_IsResizable 2606
-#define wxAuiPaneInfo_IsRightDockable 2607
-#define wxAuiPaneInfo_IsShown 2608
-#define wxAuiPaneInfo_IsToolbar 2609
-#define wxAuiPaneInfo_IsTopDockable 2610
-#define wxAuiPaneInfo_Layer 2611
-#define wxAuiPaneInfo_Left 2612
-#define wxAuiPaneInfo_LeftDockable 2613
-#define wxAuiPaneInfo_MaxSize_1 2614
-#define wxAuiPaneInfo_MaxSize_2 2615
-#define wxAuiPaneInfo_MaximizeButton 2616
-#define wxAuiPaneInfo_MinSize_1 2617
-#define wxAuiPaneInfo_MinSize_2 2618
-#define wxAuiPaneInfo_MinimizeButton 2619
-#define wxAuiPaneInfo_Movable 2620
-#define wxAuiPaneInfo_Name 2621
-#define wxAuiPaneInfo_PaneBorder 2622
-#define wxAuiPaneInfo_PinButton 2623
-#define wxAuiPaneInfo_Position 2624
-#define wxAuiPaneInfo_Resizable 2625
-#define wxAuiPaneInfo_Right 2626
-#define wxAuiPaneInfo_RightDockable 2627
-#define wxAuiPaneInfo_Row 2628
-#define wxAuiPaneInfo_SafeSet 2629
-#define wxAuiPaneInfo_SetFlag 2630
-#define wxAuiPaneInfo_Show 2631
-#define wxAuiPaneInfo_ToolbarPane 2632
-#define wxAuiPaneInfo_Top 2633
-#define wxAuiPaneInfo_TopDockable 2634
-#define wxAuiPaneInfo_Window 2635
-#define wxAuiNotebook_new_0 2636
-#define wxAuiNotebook_new_2 2637
-#define wxAuiNotebook_AddPage 2638
-#define wxAuiNotebook_Create 2639
-#define wxAuiNotebook_DeletePage 2640
-#define wxAuiNotebook_GetArtProvider 2641
-#define wxAuiNotebook_GetPage 2642
-#define wxAuiNotebook_GetPageBitmap 2643
-#define wxAuiNotebook_GetPageCount 2644
-#define wxAuiNotebook_GetPageIndex 2645
-#define wxAuiNotebook_GetPageText 2646
-#define wxAuiNotebook_GetSelection 2647
-#define wxAuiNotebook_InsertPage 2648
-#define wxAuiNotebook_RemovePage 2649
-#define wxAuiNotebook_SetArtProvider 2650
-#define wxAuiNotebook_SetFont 2651
-#define wxAuiNotebook_SetPageBitmap 2652
-#define wxAuiNotebook_SetPageText 2653
-#define wxAuiNotebook_SetSelection 2654
-#define wxAuiNotebook_SetTabCtrlHeight 2655
-#define wxAuiNotebook_SetUniformBitmapSize 2656
-#define wxAuiNotebook_destroy 2657
-#define wxMDIParentFrame_new_0 2658
-#define wxMDIParentFrame_new_4 2659
-#define wxMDIParentFrame_destruct 2660
-#define wxMDIParentFrame_ActivateNext 2661
-#define wxMDIParentFrame_ActivatePrevious 2662
-#define wxMDIParentFrame_ArrangeIcons 2663
-#define wxMDIParentFrame_Cascade 2664
-#define wxMDIParentFrame_Create 2665
-#define wxMDIParentFrame_GetActiveChild 2666
-#define wxMDIParentFrame_GetClientWindow 2667
-#define wxMDIParentFrame_Tile 2668
-#define wxMDIChildFrame_new_0 2669
-#define wxMDIChildFrame_new_4 2670
-#define wxMDIChildFrame_destruct 2671
-#define wxMDIChildFrame_Activate 2672
-#define wxMDIChildFrame_Create 2673
-#define wxMDIChildFrame_Maximize 2674
-#define wxMDIChildFrame_Restore 2675
-#define wxMDIClientWindow_new_0 2676
-#define wxMDIClientWindow_new_2 2677
-#define wxMDIClientWindow_destruct 2678
-#define wxMDIClientWindow_CreateClient 2679
-#define wxLayoutAlgorithm_new 2680
-#define wxLayoutAlgorithm_LayoutFrame 2681
-#define wxLayoutAlgorithm_LayoutMDIFrame 2682
-#define wxLayoutAlgorithm_LayoutWindow 2683
-#define wxLayoutAlgorithm_destroy 2684
-#define wxEvent_GetId 2685
-#define wxEvent_GetSkipped 2686
-#define wxEvent_GetTimestamp 2687
-#define wxEvent_IsCommandEvent 2688
-#define wxEvent_ResumePropagation 2689
-#define wxEvent_ShouldPropagate 2690
-#define wxEvent_Skip 2691
-#define wxEvent_StopPropagation 2692
-#define wxCommandEvent_getClientData 2693
-#define wxCommandEvent_GetExtraLong 2694
-#define wxCommandEvent_GetInt 2695
-#define wxCommandEvent_GetSelection 2696
-#define wxCommandEvent_GetString 2697
-#define wxCommandEvent_IsChecked 2698
-#define wxCommandEvent_IsSelection 2699
-#define wxCommandEvent_SetInt 2700
-#define wxCommandEvent_SetString 2701
-#define wxScrollEvent_GetOrientation 2702
-#define wxScrollEvent_GetPosition 2703
-#define wxScrollWinEvent_GetOrientation 2704
-#define wxScrollWinEvent_GetPosition 2705
-#define wxMouseEvent_AltDown 2706
-#define wxMouseEvent_Button 2707
-#define wxMouseEvent_ButtonDClick 2708
-#define wxMouseEvent_ButtonDown 2709
-#define wxMouseEvent_ButtonUp 2710
-#define wxMouseEvent_CmdDown 2711
-#define wxMouseEvent_ControlDown 2712
-#define wxMouseEvent_Dragging 2713
-#define wxMouseEvent_Entering 2714
-#define wxMouseEvent_GetButton 2715
-#define wxMouseEvent_GetPosition 2718
-#define wxMouseEvent_GetLogicalPosition 2719
-#define wxMouseEvent_GetLinesPerAction 2720
-#define wxMouseEvent_GetWheelRotation 2721
-#define wxMouseEvent_GetWheelDelta 2722
-#define wxMouseEvent_GetX 2723
-#define wxMouseEvent_GetY 2724
-#define wxMouseEvent_IsButton 2725
-#define wxMouseEvent_IsPageScroll 2726
-#define wxMouseEvent_Leaving 2727
-#define wxMouseEvent_LeftDClick 2728
-#define wxMouseEvent_LeftDown 2729
-#define wxMouseEvent_LeftIsDown 2730
-#define wxMouseEvent_LeftUp 2731
-#define wxMouseEvent_MetaDown 2732
-#define wxMouseEvent_MiddleDClick 2733
-#define wxMouseEvent_MiddleDown 2734
-#define wxMouseEvent_MiddleIsDown 2735
-#define wxMouseEvent_MiddleUp 2736
-#define wxMouseEvent_Moving 2737
-#define wxMouseEvent_RightDClick 2738
-#define wxMouseEvent_RightDown 2739
-#define wxMouseEvent_RightIsDown 2740
-#define wxMouseEvent_RightUp 2741
-#define wxMouseEvent_ShiftDown 2742
-#define wxSetCursorEvent_GetCursor 2743
-#define wxSetCursorEvent_GetX 2744
-#define wxSetCursorEvent_GetY 2745
-#define wxSetCursorEvent_HasCursor 2746
-#define wxSetCursorEvent_SetCursor 2747
-#define wxKeyEvent_AltDown 2748
-#define wxKeyEvent_CmdDown 2749
-#define wxKeyEvent_ControlDown 2750
-#define wxKeyEvent_GetKeyCode 2751
-#define wxKeyEvent_GetModifiers 2752
-#define wxKeyEvent_GetPosition 2755
-#define wxKeyEvent_GetRawKeyCode 2756
-#define wxKeyEvent_GetRawKeyFlags 2757
-#define wxKeyEvent_GetUnicodeKey 2758
-#define wxKeyEvent_GetX 2759
-#define wxKeyEvent_GetY 2760
-#define wxKeyEvent_HasModifiers 2761
-#define wxKeyEvent_MetaDown 2762
-#define wxKeyEvent_ShiftDown 2763
-#define wxSizeEvent_GetSize 2764
-#define wxMoveEvent_GetPosition 2765
-#define wxEraseEvent_GetDC 2766
-#define wxFocusEvent_GetWindow 2767
-#define wxChildFocusEvent_GetWindow 2768
-#define wxMenuEvent_GetMenu 2769
-#define wxMenuEvent_GetMenuId 2770
-#define wxMenuEvent_IsPopup 2771
-#define wxCloseEvent_CanVeto 2772
-#define wxCloseEvent_GetLoggingOff 2773
-#define wxCloseEvent_SetCanVeto 2774
-#define wxCloseEvent_SetLoggingOff 2775
-#define wxCloseEvent_Veto 2776
-#define wxShowEvent_SetShow 2777
-#define wxShowEvent_GetShow 2778
-#define wxIconizeEvent_Iconized 2779
-#define wxJoystickEvent_ButtonDown 2780
-#define wxJoystickEvent_ButtonIsDown 2781
-#define wxJoystickEvent_ButtonUp 2782
-#define wxJoystickEvent_GetButtonChange 2783
-#define wxJoystickEvent_GetButtonState 2784
-#define wxJoystickEvent_GetJoystick 2785
-#define wxJoystickEvent_GetPosition 2786
-#define wxJoystickEvent_GetZPosition 2787
-#define wxJoystickEvent_IsButton 2788
-#define wxJoystickEvent_IsMove 2789
-#define wxJoystickEvent_IsZMove 2790
-#define wxUpdateUIEvent_CanUpdate 2791
-#define wxUpdateUIEvent_Check 2792
-#define wxUpdateUIEvent_Enable 2793
-#define wxUpdateUIEvent_Show 2794
-#define wxUpdateUIEvent_GetChecked 2795
-#define wxUpdateUIEvent_GetEnabled 2796
-#define wxUpdateUIEvent_GetShown 2797
-#define wxUpdateUIEvent_GetSetChecked 2798
-#define wxUpdateUIEvent_GetSetEnabled 2799
-#define wxUpdateUIEvent_GetSetShown 2800
-#define wxUpdateUIEvent_GetSetText 2801
-#define wxUpdateUIEvent_GetText 2802
-#define wxUpdateUIEvent_GetMode 2803
-#define wxUpdateUIEvent_GetUpdateInterval 2804
-#define wxUpdateUIEvent_ResetUpdateTime 2805
-#define wxUpdateUIEvent_SetMode 2806
-#define wxUpdateUIEvent_SetText 2807
-#define wxUpdateUIEvent_SetUpdateInterval 2808
-#define wxMouseCaptureChangedEvent_GetCapturedWindow 2809
-#define wxPaletteChangedEvent_SetChangedWindow 2810
-#define wxPaletteChangedEvent_GetChangedWindow 2811
-#define wxQueryNewPaletteEvent_SetPaletteRealized 2812
-#define wxQueryNewPaletteEvent_GetPaletteRealized 2813
-#define wxNavigationKeyEvent_GetDirection 2814
-#define wxNavigationKeyEvent_SetDirection 2815
-#define wxNavigationKeyEvent_IsWindowChange 2816
-#define wxNavigationKeyEvent_SetWindowChange 2817
-#define wxNavigationKeyEvent_IsFromTab 2818
-#define wxNavigationKeyEvent_SetFromTab 2819
-#define wxNavigationKeyEvent_GetCurrentFocus 2820
-#define wxNavigationKeyEvent_SetCurrentFocus 2821
-#define wxHelpEvent_GetOrigin 2822
-#define wxHelpEvent_GetPosition 2823
-#define wxHelpEvent_SetOrigin 2824
-#define wxHelpEvent_SetPosition 2825
-#define wxContextMenuEvent_GetPosition 2826
-#define wxContextMenuEvent_SetPosition 2827
-#define wxIdleEvent_CanSend 2828
-#define wxIdleEvent_GetMode 2829
-#define wxIdleEvent_RequestMore 2830
-#define wxIdleEvent_MoreRequested 2831
-#define wxIdleEvent_SetMode 2832
-#define wxGridEvent_AltDown 2833
-#define wxGridEvent_ControlDown 2834
-#define wxGridEvent_GetCol 2835
-#define wxGridEvent_GetPosition 2836
-#define wxGridEvent_GetRow 2837
-#define wxGridEvent_MetaDown 2838
-#define wxGridEvent_Selecting 2839
-#define wxGridEvent_ShiftDown 2840
-#define wxNotifyEvent_Allow 2841
-#define wxNotifyEvent_IsAllowed 2842
-#define wxNotifyEvent_Veto 2843
-#define wxSashEvent_GetEdge 2844
-#define wxSashEvent_GetDragRect 2845
-#define wxSashEvent_GetDragStatus 2846
-#define wxListEvent_GetCacheFrom 2847
-#define wxListEvent_GetCacheTo 2848
-#define wxListEvent_GetKeyCode 2849
-#define wxListEvent_GetIndex 2850
-#define wxListEvent_GetColumn 2851
-#define wxListEvent_GetPoint 2852
-#define wxListEvent_GetLabel 2853
-#define wxListEvent_GetText 2854
-#define wxListEvent_GetImage 2855
-#define wxListEvent_GetData 2856
-#define wxListEvent_GetMask 2857
-#define wxListEvent_GetItem 2858
-#define wxListEvent_IsEditCancelled 2859
-#define wxDateEvent_GetDate 2860
-#define wxCalendarEvent_GetWeekDay 2861
-#define wxFileDirPickerEvent_GetPath 2862
-#define wxColourPickerEvent_GetColour 2863
-#define wxFontPickerEvent_GetFont 2864
-#define wxStyledTextEvent_GetPosition 2865
-#define wxStyledTextEvent_GetKey 2866
-#define wxStyledTextEvent_GetModifiers 2867
-#define wxStyledTextEvent_GetModificationType 2868
-#define wxStyledTextEvent_GetText 2869
-#define wxStyledTextEvent_GetLength 2870
-#define wxStyledTextEvent_GetLinesAdded 2871
-#define wxStyledTextEvent_GetLine 2872
-#define wxStyledTextEvent_GetFoldLevelNow 2873
-#define wxStyledTextEvent_GetFoldLevelPrev 2874
-#define wxStyledTextEvent_GetMargin 2875
-#define wxStyledTextEvent_GetMessage 2876
-#define wxStyledTextEvent_GetWParam 2877
-#define wxStyledTextEvent_GetLParam 2878
-#define wxStyledTextEvent_GetListType 2879
-#define wxStyledTextEvent_GetX 2880
-#define wxStyledTextEvent_GetY 2881
-#define wxStyledTextEvent_GetDragText 2882
-#define wxStyledTextEvent_GetDragAllowMove 2883
-#define wxStyledTextEvent_GetDragResult 2884
-#define wxStyledTextEvent_GetShift 2885
-#define wxStyledTextEvent_GetControl 2886
-#define wxStyledTextEvent_GetAlt 2887
-#define utils_wxGetKeyState 2888
-#define utils_wxGetMousePosition 2889
-#define utils_wxGetMouseState 2890
-#define utils_wxSetDetectableAutoRepeat 2891
-#define utils_wxBell 2892
-#define utils_wxFindMenuItemId 2893
-#define utils_wxGenericFindWindowAtPoint 2894
-#define utils_wxFindWindowAtPoint 2895
-#define utils_wxBeginBusyCursor 2896
-#define utils_wxEndBusyCursor 2897
-#define utils_wxIsBusy 2898
-#define utils_wxShutdown 2899
-#define utils_wxShell 2900
-#define utils_wxLaunchDefaultBrowser 2901
-#define utils_wxGetEmailAddress 2902
-#define utils_wxGetUserId 2903
-#define utils_wxGetHomeDir 2904
-#define utils_wxNewId 2905
-#define utils_wxRegisterId 2906
-#define utils_wxGetCurrentId 2907
-#define utils_wxGetOsDescription 2908
-#define utils_wxIsPlatformLittleEndian 2909
-#define utils_wxIsPlatform64Bit 2910
-#define wxPrintout_new 2911
-#define wxPrintout_destruct 2912
-#define wxPrintout_GetDC 2913
-#define wxPrintout_GetPageSizeMM 2914
-#define wxPrintout_GetPageSizePixels 2915
-#define wxPrintout_GetPaperRectPixels 2916
-#define wxPrintout_GetPPIPrinter 2917
-#define wxPrintout_GetPPIScreen 2918
-#define wxPrintout_GetTitle 2919
-#define wxPrintout_IsPreview 2920
-#define wxPrintout_FitThisSizeToPaper 2921
-#define wxPrintout_FitThisSizeToPage 2922
-#define wxPrintout_FitThisSizeToPageMargins 2923
-#define wxPrintout_MapScreenSizeToPaper 2924
-#define wxPrintout_MapScreenSizeToPage 2925
-#define wxPrintout_MapScreenSizeToPageMargins 2926
-#define wxPrintout_MapScreenSizeToDevice 2927
-#define wxPrintout_GetLogicalPaperRect 2928
-#define wxPrintout_GetLogicalPageRect 2929
-#define wxPrintout_GetLogicalPageMarginsRect 2930
-#define wxPrintout_SetLogicalOrigin 2931
-#define wxPrintout_OffsetLogicalOrigin 2932
-#define wxStyledTextCtrl_new_2 2933
-#define wxStyledTextCtrl_new_0 2934
-#define wxStyledTextCtrl_destruct 2935
-#define wxStyledTextCtrl_Create 2936
-#define wxStyledTextCtrl_AddText 2937
-#define wxStyledTextCtrl_AddStyledText 2938
-#define wxStyledTextCtrl_InsertText 2939
-#define wxStyledTextCtrl_ClearAll 2940
-#define wxStyledTextCtrl_ClearDocumentStyle 2941
-#define wxStyledTextCtrl_GetLength 2942
-#define wxStyledTextCtrl_GetCharAt 2943
-#define wxStyledTextCtrl_GetCurrentPos 2944
-#define wxStyledTextCtrl_GetAnchor 2945
-#define wxStyledTextCtrl_GetStyleAt 2946
-#define wxStyledTextCtrl_Redo 2947
-#define wxStyledTextCtrl_SetUndoCollection 2948
-#define wxStyledTextCtrl_SelectAll 2949
-#define wxStyledTextCtrl_SetSavePoint 2950
-#define wxStyledTextCtrl_GetStyledText 2951
-#define wxStyledTextCtrl_CanRedo 2952
-#define wxStyledTextCtrl_MarkerLineFromHandle 2953
-#define wxStyledTextCtrl_MarkerDeleteHandle 2954
-#define wxStyledTextCtrl_GetUndoCollection 2955
-#define wxStyledTextCtrl_GetViewWhiteSpace 2956
-#define wxStyledTextCtrl_SetViewWhiteSpace 2957
-#define wxStyledTextCtrl_PositionFromPoint 2958
-#define wxStyledTextCtrl_PositionFromPointClose 2959
-#define wxStyledTextCtrl_GotoLine 2960
-#define wxStyledTextCtrl_GotoPos 2961
-#define wxStyledTextCtrl_SetAnchor 2962
-#define wxStyledTextCtrl_GetCurLine 2963
-#define wxStyledTextCtrl_GetEndStyled 2964
-#define wxStyledTextCtrl_ConvertEOLs 2965
-#define wxStyledTextCtrl_GetEOLMode 2966
-#define wxStyledTextCtrl_SetEOLMode 2967
-#define wxStyledTextCtrl_StartStyling 2968
-#define wxStyledTextCtrl_SetStyling 2969
-#define wxStyledTextCtrl_GetBufferedDraw 2970
-#define wxStyledTextCtrl_SetBufferedDraw 2971
-#define wxStyledTextCtrl_SetTabWidth 2972
-#define wxStyledTextCtrl_GetTabWidth 2973
-#define wxStyledTextCtrl_SetCodePage 2974
-#define wxStyledTextCtrl_MarkerDefine 2975
-#define wxStyledTextCtrl_MarkerSetForeground 2976
-#define wxStyledTextCtrl_MarkerSetBackground 2977
-#define wxStyledTextCtrl_MarkerAdd 2978
-#define wxStyledTextCtrl_MarkerDelete 2979
-#define wxStyledTextCtrl_MarkerDeleteAll 2980
-#define wxStyledTextCtrl_MarkerGet 2981
-#define wxStyledTextCtrl_MarkerNext 2982
-#define wxStyledTextCtrl_MarkerPrevious 2983
-#define wxStyledTextCtrl_MarkerDefineBitmap 2984
-#define wxStyledTextCtrl_MarkerAddSet 2985
-#define wxStyledTextCtrl_MarkerSetAlpha 2986
-#define wxStyledTextCtrl_SetMarginType 2987
-#define wxStyledTextCtrl_GetMarginType 2988
-#define wxStyledTextCtrl_SetMarginWidth 2989
-#define wxStyledTextCtrl_GetMarginWidth 2990
-#define wxStyledTextCtrl_SetMarginMask 2991
-#define wxStyledTextCtrl_GetMarginMask 2992
-#define wxStyledTextCtrl_SetMarginSensitive 2993
-#define wxStyledTextCtrl_GetMarginSensitive 2994
-#define wxStyledTextCtrl_StyleClearAll 2995
-#define wxStyledTextCtrl_StyleSetForeground 2996
-#define wxStyledTextCtrl_StyleSetBackground 2997
-#define wxStyledTextCtrl_StyleSetBold 2998
-#define wxStyledTextCtrl_StyleSetItalic 2999
-#define wxStyledTextCtrl_StyleSetSize 3000
-#define wxStyledTextCtrl_StyleSetFaceName 3001
-#define wxStyledTextCtrl_StyleSetEOLFilled 3002
-#define wxStyledTextCtrl_StyleResetDefault 3003
-#define wxStyledTextCtrl_StyleSetUnderline 3004
-#define wxStyledTextCtrl_StyleSetCase 3005
-#define wxStyledTextCtrl_StyleSetHotSpot 3006
-#define wxStyledTextCtrl_SetSelForeground 3007
-#define wxStyledTextCtrl_SetSelBackground 3008
-#define wxStyledTextCtrl_GetSelAlpha 3009
-#define wxStyledTextCtrl_SetSelAlpha 3010
-#define wxStyledTextCtrl_SetCaretForeground 3011
-#define wxStyledTextCtrl_CmdKeyAssign 3012
-#define wxStyledTextCtrl_CmdKeyClear 3013
-#define wxStyledTextCtrl_CmdKeyClearAll 3014
-#define wxStyledTextCtrl_SetStyleBytes 3015
-#define wxStyledTextCtrl_StyleSetVisible 3016
-#define wxStyledTextCtrl_GetCaretPeriod 3017
-#define wxStyledTextCtrl_SetCaretPeriod 3018
-#define wxStyledTextCtrl_SetWordChars 3019
-#define wxStyledTextCtrl_BeginUndoAction 3020
-#define wxStyledTextCtrl_EndUndoAction 3021
-#define wxStyledTextCtrl_IndicatorSetStyle 3022
-#define wxStyledTextCtrl_IndicatorGetStyle 3023
-#define wxStyledTextCtrl_IndicatorSetForeground 3024
-#define wxStyledTextCtrl_IndicatorGetForeground 3025
-#define wxStyledTextCtrl_SetWhitespaceForeground 3026
-#define wxStyledTextCtrl_SetWhitespaceBackground 3027
-#define wxStyledTextCtrl_GetStyleBits 3028
-#define wxStyledTextCtrl_SetLineState 3029
-#define wxStyledTextCtrl_GetLineState 3030
-#define wxStyledTextCtrl_GetMaxLineState 3031
-#define wxStyledTextCtrl_GetCaretLineVisible 3032
-#define wxStyledTextCtrl_SetCaretLineVisible 3033
-#define wxStyledTextCtrl_GetCaretLineBackground 3034
-#define wxStyledTextCtrl_SetCaretLineBackground 3035
-#define wxStyledTextCtrl_AutoCompShow 3036
-#define wxStyledTextCtrl_AutoCompCancel 3037
-#define wxStyledTextCtrl_AutoCompActive 3038
-#define wxStyledTextCtrl_AutoCompPosStart 3039
-#define wxStyledTextCtrl_AutoCompComplete 3040
-#define wxStyledTextCtrl_AutoCompStops 3041
-#define wxStyledTextCtrl_AutoCompSetSeparator 3042
-#define wxStyledTextCtrl_AutoCompGetSeparator 3043
-#define wxStyledTextCtrl_AutoCompSelect 3044
-#define wxStyledTextCtrl_AutoCompSetCancelAtStart 3045
-#define wxStyledTextCtrl_AutoCompGetCancelAtStart 3046
-#define wxStyledTextCtrl_AutoCompSetFillUps 3047
-#define wxStyledTextCtrl_AutoCompSetChooseSingle 3048
-#define wxStyledTextCtrl_AutoCompGetChooseSingle 3049
-#define wxStyledTextCtrl_AutoCompSetIgnoreCase 3050
-#define wxStyledTextCtrl_AutoCompGetIgnoreCase 3051
-#define wxStyledTextCtrl_UserListShow 3052
-#define wxStyledTextCtrl_AutoCompSetAutoHide 3053
-#define wxStyledTextCtrl_AutoCompGetAutoHide 3054
-#define wxStyledTextCtrl_AutoCompSetDropRestOfWord 3055
-#define wxStyledTextCtrl_AutoCompGetDropRestOfWord 3056
-#define wxStyledTextCtrl_RegisterImage 3057
-#define wxStyledTextCtrl_ClearRegisteredImages 3058
-#define wxStyledTextCtrl_AutoCompGetTypeSeparator 3059
-#define wxStyledTextCtrl_AutoCompSetTypeSeparator 3060
-#define wxStyledTextCtrl_AutoCompSetMaxWidth 3061
-#define wxStyledTextCtrl_AutoCompGetMaxWidth 3062
-#define wxStyledTextCtrl_AutoCompSetMaxHeight 3063
-#define wxStyledTextCtrl_AutoCompGetMaxHeight 3064
-#define wxStyledTextCtrl_SetIndent 3065
-#define wxStyledTextCtrl_GetIndent 3066
-#define wxStyledTextCtrl_SetUseTabs 3067
-#define wxStyledTextCtrl_GetUseTabs 3068
-#define wxStyledTextCtrl_SetLineIndentation 3069
-#define wxStyledTextCtrl_GetLineIndentation 3070
-#define wxStyledTextCtrl_GetLineIndentPosition 3071
-#define wxStyledTextCtrl_GetColumn 3072
-#define wxStyledTextCtrl_SetUseHorizontalScrollBar 3073
-#define wxStyledTextCtrl_GetUseHorizontalScrollBar 3074
-#define wxStyledTextCtrl_SetIndentationGuides 3075
-#define wxStyledTextCtrl_GetIndentationGuides 3076
-#define wxStyledTextCtrl_SetHighlightGuide 3077
-#define wxStyledTextCtrl_GetHighlightGuide 3078
-#define wxStyledTextCtrl_GetLineEndPosition 3079
-#define wxStyledTextCtrl_GetCodePage 3080
-#define wxStyledTextCtrl_GetCaretForeground 3081
-#define wxStyledTextCtrl_GetReadOnly 3082
-#define wxStyledTextCtrl_SetCurrentPos 3083
-#define wxStyledTextCtrl_SetSelectionStart 3084
-#define wxStyledTextCtrl_GetSelectionStart 3085
-#define wxStyledTextCtrl_SetSelectionEnd 3086
-#define wxStyledTextCtrl_GetSelectionEnd 3087
-#define wxStyledTextCtrl_SetPrintMagnification 3088
-#define wxStyledTextCtrl_GetPrintMagnification 3089
-#define wxStyledTextCtrl_SetPrintColourMode 3090
-#define wxStyledTextCtrl_GetPrintColourMode 3091
-#define wxStyledTextCtrl_FindText 3092
-#define wxStyledTextCtrl_FormatRange 3093
-#define wxStyledTextCtrl_GetFirstVisibleLine 3094
-#define wxStyledTextCtrl_GetLine 3095
-#define wxStyledTextCtrl_GetLineCount 3096
-#define wxStyledTextCtrl_SetMarginLeft 3097
-#define wxStyledTextCtrl_GetMarginLeft 3098
-#define wxStyledTextCtrl_SetMarginRight 3099
-#define wxStyledTextCtrl_GetMarginRight 3100
-#define wxStyledTextCtrl_GetModify 3101
-#define wxStyledTextCtrl_SetSelection 3102
-#define wxStyledTextCtrl_GetSelectedText 3103
-#define wxStyledTextCtrl_GetTextRange 3104
-#define wxStyledTextCtrl_HideSelection 3105
-#define wxStyledTextCtrl_LineFromPosition 3106
-#define wxStyledTextCtrl_PositionFromLine 3107
-#define wxStyledTextCtrl_LineScroll 3108
-#define wxStyledTextCtrl_EnsureCaretVisible 3109
-#define wxStyledTextCtrl_ReplaceSelection 3110
-#define wxStyledTextCtrl_SetReadOnly 3111
-#define wxStyledTextCtrl_CanPaste 3112
-#define wxStyledTextCtrl_CanUndo 3113
-#define wxStyledTextCtrl_EmptyUndoBuffer 3114
-#define wxStyledTextCtrl_Undo 3115
-#define wxStyledTextCtrl_Cut 3116
-#define wxStyledTextCtrl_Copy 3117
-#define wxStyledTextCtrl_Paste 3118
-#define wxStyledTextCtrl_Clear 3119
-#define wxStyledTextCtrl_SetText 3120
-#define wxStyledTextCtrl_GetText 3121
-#define wxStyledTextCtrl_GetTextLength 3122
-#define wxStyledTextCtrl_GetOvertype 3123
-#define wxStyledTextCtrl_SetCaretWidth 3124
-#define wxStyledTextCtrl_GetCaretWidth 3125
-#define wxStyledTextCtrl_SetTargetStart 3126
-#define wxStyledTextCtrl_GetTargetStart 3127
-#define wxStyledTextCtrl_SetTargetEnd 3128
-#define wxStyledTextCtrl_GetTargetEnd 3129
-#define wxStyledTextCtrl_ReplaceTarget 3130
-#define wxStyledTextCtrl_SearchInTarget 3131
-#define wxStyledTextCtrl_SetSearchFlags 3132
-#define wxStyledTextCtrl_GetSearchFlags 3133
-#define wxStyledTextCtrl_CallTipShow 3134
-#define wxStyledTextCtrl_CallTipCancel 3135
-#define wxStyledTextCtrl_CallTipActive 3136
-#define wxStyledTextCtrl_CallTipPosAtStart 3137
-#define wxStyledTextCtrl_CallTipSetHighlight 3138
-#define wxStyledTextCtrl_CallTipSetBackground 3139
-#define wxStyledTextCtrl_CallTipSetForeground 3140
-#define wxStyledTextCtrl_CallTipSetForegroundHighlight 3141
-#define wxStyledTextCtrl_CallTipUseStyle 3142
-#define wxStyledTextCtrl_VisibleFromDocLine 3143
-#define wxStyledTextCtrl_DocLineFromVisible 3144
-#define wxStyledTextCtrl_WrapCount 3145
-#define wxStyledTextCtrl_SetFoldLevel 3146
-#define wxStyledTextCtrl_GetFoldLevel 3147
-#define wxStyledTextCtrl_GetLastChild 3148
-#define wxStyledTextCtrl_GetFoldParent 3149
-#define wxStyledTextCtrl_ShowLines 3150
-#define wxStyledTextCtrl_HideLines 3151
-#define wxStyledTextCtrl_GetLineVisible 3152
-#define wxStyledTextCtrl_SetFoldExpanded 3153
-#define wxStyledTextCtrl_GetFoldExpanded 3154
-#define wxStyledTextCtrl_ToggleFold 3155
-#define wxStyledTextCtrl_EnsureVisible 3156
-#define wxStyledTextCtrl_SetFoldFlags 3157
-#define wxStyledTextCtrl_EnsureVisibleEnforcePolicy 3158
-#define wxStyledTextCtrl_SetTabIndents 3159
-#define wxStyledTextCtrl_GetTabIndents 3160
-#define wxStyledTextCtrl_SetBackSpaceUnIndents 3161
-#define wxStyledTextCtrl_GetBackSpaceUnIndents 3162
-#define wxStyledTextCtrl_SetMouseDwellTime 3163
-#define wxStyledTextCtrl_GetMouseDwellTime 3164
-#define wxStyledTextCtrl_WordStartPosition 3165
-#define wxStyledTextCtrl_WordEndPosition 3166
-#define wxStyledTextCtrl_SetWrapMode 3167
-#define wxStyledTextCtrl_GetWrapMode 3168
-#define wxStyledTextCtrl_SetWrapVisualFlags 3169
-#define wxStyledTextCtrl_GetWrapVisualFlags 3170
-#define wxStyledTextCtrl_SetWrapVisualFlagsLocation 3171
-#define wxStyledTextCtrl_GetWrapVisualFlagsLocation 3172
-#define wxStyledTextCtrl_SetWrapStartIndent 3173
-#define wxStyledTextCtrl_GetWrapStartIndent 3174
-#define wxStyledTextCtrl_SetLayoutCache 3175
-#define wxStyledTextCtrl_GetLayoutCache 3176
-#define wxStyledTextCtrl_SetScrollWidth 3177
-#define wxStyledTextCtrl_GetScrollWidth 3178
-#define wxStyledTextCtrl_TextWidth 3179
-#define wxStyledTextCtrl_GetEndAtLastLine 3180
-#define wxStyledTextCtrl_TextHeight 3181
-#define wxStyledTextCtrl_SetUseVerticalScrollBar 3182
-#define wxStyledTextCtrl_GetUseVerticalScrollBar 3183
-#define wxStyledTextCtrl_AppendText 3184
-#define wxStyledTextCtrl_GetTwoPhaseDraw 3185
-#define wxStyledTextCtrl_SetTwoPhaseDraw 3186
-#define wxStyledTextCtrl_TargetFromSelection 3187
-#define wxStyledTextCtrl_LinesJoin 3188
-#define wxStyledTextCtrl_LinesSplit 3189
-#define wxStyledTextCtrl_SetFoldMarginColour 3190
-#define wxStyledTextCtrl_SetFoldMarginHiColour 3191
-#define wxStyledTextCtrl_LineDown 3192
-#define wxStyledTextCtrl_LineDownExtend 3193
-#define wxStyledTextCtrl_LineUp 3194
-#define wxStyledTextCtrl_LineUpExtend 3195
-#define wxStyledTextCtrl_CharLeft 3196
-#define wxStyledTextCtrl_CharLeftExtend 3197
-#define wxStyledTextCtrl_CharRight 3198
-#define wxStyledTextCtrl_CharRightExtend 3199
-#define wxStyledTextCtrl_WordLeft 3200
-#define wxStyledTextCtrl_WordLeftExtend 3201
-#define wxStyledTextCtrl_WordRight 3202
-#define wxStyledTextCtrl_WordRightExtend 3203
-#define wxStyledTextCtrl_Home 3204
-#define wxStyledTextCtrl_HomeExtend 3205
-#define wxStyledTextCtrl_LineEnd 3206
-#define wxStyledTextCtrl_LineEndExtend 3207
-#define wxStyledTextCtrl_DocumentStart 3208
-#define wxStyledTextCtrl_DocumentStartExtend 3209
-#define wxStyledTextCtrl_DocumentEnd 3210
-#define wxStyledTextCtrl_DocumentEndExtend 3211
-#define wxStyledTextCtrl_PageUp 3212
-#define wxStyledTextCtrl_PageUpExtend 3213
-#define wxStyledTextCtrl_PageDown 3214
-#define wxStyledTextCtrl_PageDownExtend 3215
-#define wxStyledTextCtrl_EditToggleOvertype 3216
-#define wxStyledTextCtrl_Cancel 3217
-#define wxStyledTextCtrl_DeleteBack 3218
-#define wxStyledTextCtrl_Tab 3219
-#define wxStyledTextCtrl_BackTab 3220
-#define wxStyledTextCtrl_NewLine 3221
-#define wxStyledTextCtrl_FormFeed 3222
-#define wxStyledTextCtrl_VCHome 3223
-#define wxStyledTextCtrl_VCHomeExtend 3224
-#define wxStyledTextCtrl_ZoomIn 3225
-#define wxStyledTextCtrl_ZoomOut 3226
-#define wxStyledTextCtrl_DelWordLeft 3227
-#define wxStyledTextCtrl_DelWordRight 3228
-#define wxStyledTextCtrl_LineCut 3229
-#define wxStyledTextCtrl_LineDelete 3230
-#define wxStyledTextCtrl_LineTranspose 3231
-#define wxStyledTextCtrl_LineDuplicate 3232
-#define wxStyledTextCtrl_LowerCase 3233
-#define wxStyledTextCtrl_UpperCase 3234
-#define wxStyledTextCtrl_LineScrollDown 3235
-#define wxStyledTextCtrl_LineScrollUp 3236
-#define wxStyledTextCtrl_DeleteBackNotLine 3237
-#define wxStyledTextCtrl_HomeDisplay 3238
-#define wxStyledTextCtrl_HomeDisplayExtend 3239
-#define wxStyledTextCtrl_LineEndDisplay 3240
-#define wxStyledTextCtrl_LineEndDisplayExtend 3241
-#define wxStyledTextCtrl_HomeWrapExtend 3242
-#define wxStyledTextCtrl_LineEndWrap 3243
-#define wxStyledTextCtrl_LineEndWrapExtend 3244
-#define wxStyledTextCtrl_VCHomeWrap 3245
-#define wxStyledTextCtrl_VCHomeWrapExtend 3246
-#define wxStyledTextCtrl_LineCopy 3247
-#define wxStyledTextCtrl_MoveCaretInsideView 3248
-#define wxStyledTextCtrl_LineLength 3249
-#define wxStyledTextCtrl_BraceHighlight 3250
-#define wxStyledTextCtrl_BraceBadLight 3251
-#define wxStyledTextCtrl_BraceMatch 3252
-#define wxStyledTextCtrl_GetViewEOL 3253
-#define wxStyledTextCtrl_SetViewEOL 3254
-#define wxStyledTextCtrl_SetModEventMask 3255
-#define wxStyledTextCtrl_GetEdgeColumn 3256
-#define wxStyledTextCtrl_SetEdgeColumn 3257
-#define wxStyledTextCtrl_GetEdgeMode 3258
-#define wxStyledTextCtrl_GetEdgeColour 3259
-#define wxStyledTextCtrl_SetEdgeColour 3260
-#define wxStyledTextCtrl_SearchAnchor 3261
-#define wxStyledTextCtrl_SearchNext 3262
-#define wxStyledTextCtrl_SearchPrev 3263
-#define wxStyledTextCtrl_LinesOnScreen 3264
-#define wxStyledTextCtrl_UsePopUp 3265
-#define wxStyledTextCtrl_SelectionIsRectangle 3266
-#define wxStyledTextCtrl_SetZoom 3267
-#define wxStyledTextCtrl_GetZoom 3268
-#define wxStyledTextCtrl_GetModEventMask 3269
-#define wxStyledTextCtrl_SetSTCFocus 3270
-#define wxStyledTextCtrl_GetSTCFocus 3271
-#define wxStyledTextCtrl_SetStatus 3272
-#define wxStyledTextCtrl_GetStatus 3273
-#define wxStyledTextCtrl_SetMouseDownCaptures 3274
-#define wxStyledTextCtrl_GetMouseDownCaptures 3275
-#define wxStyledTextCtrl_SetSTCCursor 3276
-#define wxStyledTextCtrl_GetSTCCursor 3277
-#define wxStyledTextCtrl_SetControlCharSymbol 3278
-#define wxStyledTextCtrl_GetControlCharSymbol 3279
-#define wxStyledTextCtrl_WordPartLeft 3280
-#define wxStyledTextCtrl_WordPartLeftExtend 3281
-#define wxStyledTextCtrl_WordPartRight 3282
-#define wxStyledTextCtrl_WordPartRightExtend 3283
-#define wxStyledTextCtrl_SetVisiblePolicy 3284
-#define wxStyledTextCtrl_DelLineLeft 3285
-#define wxStyledTextCtrl_DelLineRight 3286
-#define wxStyledTextCtrl_GetXOffset 3287
-#define wxStyledTextCtrl_ChooseCaretX 3288
-#define wxStyledTextCtrl_SetXCaretPolicy 3289
-#define wxStyledTextCtrl_SetYCaretPolicy 3290
-#define wxStyledTextCtrl_GetPrintWrapMode 3291
-#define wxStyledTextCtrl_SetHotspotActiveForeground 3292
-#define wxStyledTextCtrl_SetHotspotActiveBackground 3293
-#define wxStyledTextCtrl_SetHotspotActiveUnderline 3294
-#define wxStyledTextCtrl_SetHotspotSingleLine 3295
-#define wxStyledTextCtrl_ParaDownExtend 3296
-#define wxStyledTextCtrl_ParaUp 3297
-#define wxStyledTextCtrl_ParaUpExtend 3298
-#define wxStyledTextCtrl_PositionBefore 3299
-#define wxStyledTextCtrl_PositionAfter 3300
-#define wxStyledTextCtrl_CopyRange 3301
-#define wxStyledTextCtrl_CopyText 3302
-#define wxStyledTextCtrl_SetSelectionMode 3303
-#define wxStyledTextCtrl_GetSelectionMode 3304
-#define wxStyledTextCtrl_LineDownRectExtend 3305
-#define wxStyledTextCtrl_LineUpRectExtend 3306
-#define wxStyledTextCtrl_CharLeftRectExtend 3307
-#define wxStyledTextCtrl_CharRightRectExtend 3308
-#define wxStyledTextCtrl_HomeRectExtend 3309
-#define wxStyledTextCtrl_VCHomeRectExtend 3310
-#define wxStyledTextCtrl_LineEndRectExtend 3311
-#define wxStyledTextCtrl_PageUpRectExtend 3312
-#define wxStyledTextCtrl_PageDownRectExtend 3313
-#define wxStyledTextCtrl_StutteredPageUp 3314
-#define wxStyledTextCtrl_StutteredPageUpExtend 3315
-#define wxStyledTextCtrl_StutteredPageDown 3316
-#define wxStyledTextCtrl_StutteredPageDownExtend 3317
-#define wxStyledTextCtrl_WordLeftEnd 3318
-#define wxStyledTextCtrl_WordLeftEndExtend 3319
-#define wxStyledTextCtrl_WordRightEnd 3320
-#define wxStyledTextCtrl_WordRightEndExtend 3321
-#define wxStyledTextCtrl_SetWhitespaceChars 3322
-#define wxStyledTextCtrl_SetCharsDefault 3323
-#define wxStyledTextCtrl_AutoCompGetCurrent 3324
-#define wxStyledTextCtrl_Allocate 3325
-#define wxStyledTextCtrl_FindColumn 3326
-#define wxStyledTextCtrl_GetCaretSticky 3327
-#define wxStyledTextCtrl_SetCaretSticky 3328
-#define wxStyledTextCtrl_ToggleCaretSticky 3329
-#define wxStyledTextCtrl_SetPasteConvertEndings 3330
-#define wxStyledTextCtrl_GetPasteConvertEndings 3331
-#define wxStyledTextCtrl_SelectionDuplicate 3332
-#define wxStyledTextCtrl_SetCaretLineBackAlpha 3333
-#define wxStyledTextCtrl_GetCaretLineBackAlpha 3334
-#define wxStyledTextCtrl_StartRecord 3335
-#define wxStyledTextCtrl_StopRecord 3336
-#define wxStyledTextCtrl_SetLexer 3337
-#define wxStyledTextCtrl_GetLexer 3338
-#define wxStyledTextCtrl_Colourise 3339
-#define wxStyledTextCtrl_SetProperty 3340
-#define wxStyledTextCtrl_SetKeyWords 3341
-#define wxStyledTextCtrl_SetLexerLanguage 3342
-#define wxStyledTextCtrl_GetProperty 3343
-#define wxStyledTextCtrl_GetStyleBitsNeeded 3344
-#define wxStyledTextCtrl_GetCurrentLine 3345
-#define wxStyledTextCtrl_StyleSetSpec 3346
-#define wxStyledTextCtrl_StyleSetFont 3347
-#define wxStyledTextCtrl_StyleSetFontAttr 3348
-#define wxStyledTextCtrl_StyleSetCharacterSet 3349
-#define wxStyledTextCtrl_StyleSetFontEncoding 3350
-#define wxStyledTextCtrl_CmdKeyExecute 3351
-#define wxStyledTextCtrl_SetMargins 3352
-#define wxStyledTextCtrl_GetSelection 3353
-#define wxStyledTextCtrl_PointFromPosition 3354
-#define wxStyledTextCtrl_ScrollToLine 3355
-#define wxStyledTextCtrl_ScrollToColumn 3356
-#define wxStyledTextCtrl_SendMsg 3357
-#define wxStyledTextCtrl_SetVScrollBar 3358
-#define wxStyledTextCtrl_SetHScrollBar 3359
-#define wxStyledTextCtrl_GetLastKeydownProcessed 3360
-#define wxStyledTextCtrl_SetLastKeydownProcessed 3361
-#define wxStyledTextCtrl_SaveFile 3362
-#define wxStyledTextCtrl_LoadFile 3363
-#define wxStyledTextCtrl_DoDragOver 3364
-#define wxStyledTextCtrl_DoDropText 3365
-#define wxStyledTextCtrl_GetUseAntiAliasing 3366
-#define wxStyledTextCtrl_AddTextRaw 3367
-#define wxStyledTextCtrl_InsertTextRaw 3368
-#define wxStyledTextCtrl_GetCurLineRaw 3369
-#define wxStyledTextCtrl_GetLineRaw 3370
-#define wxStyledTextCtrl_GetSelectedTextRaw 3371
-#define wxStyledTextCtrl_GetTextRangeRaw 3372
-#define wxStyledTextCtrl_SetTextRaw 3373
-#define wxStyledTextCtrl_GetTextRaw 3374
-#define wxStyledTextCtrl_AppendTextRaw 3375
-#define wxArtProvider_GetBitmap 3376
-#define wxArtProvider_GetIcon 3377
-#define wxTreeEvent_GetKeyCode 3378
-#define wxTreeEvent_GetItem 3379
-#define wxTreeEvent_GetKeyEvent 3380
-#define wxTreeEvent_GetLabel 3381
-#define wxTreeEvent_GetOldItem 3382
-#define wxTreeEvent_GetPoint 3383
-#define wxTreeEvent_IsEditCancelled 3384
-#define wxTreeEvent_SetToolTip 3385
-#define wxNotebookEvent_GetOldSelection 3386
-#define wxNotebookEvent_GetSelection 3387
-#define wxNotebookEvent_SetOldSelection 3388
-#define wxNotebookEvent_SetSelection 3389
-#define wxFileDataObject_new 3390
-#define wxFileDataObject_AddFile 3391
-#define wxFileDataObject_GetFilenames 3392
-#define wxFileDataObject_destroy 3393
-#define wxTextDataObject_new 3394
-#define wxTextDataObject_GetTextLength 3395
-#define wxTextDataObject_GetText 3396
-#define wxTextDataObject_SetText 3397
-#define wxTextDataObject_destroy 3398
-#define wxBitmapDataObject_new_1_1 3399
-#define wxBitmapDataObject_new_1_0 3400
-#define wxBitmapDataObject_GetBitmap 3401
-#define wxBitmapDataObject_SetBitmap 3402
-#define wxBitmapDataObject_destroy 3403
-#define wxClipboard_new 3405
-#define wxClipboard_destruct 3406
-#define wxClipboard_AddData 3407
-#define wxClipboard_Clear 3408
-#define wxClipboard_Close 3409
-#define wxClipboard_Flush 3410
-#define wxClipboard_GetData 3411
-#define wxClipboard_IsOpened 3412
-#define wxClipboard_Open 3413
-#define wxClipboard_SetData 3414
-#define wxClipboard_UsePrimarySelection 3416
-#define wxClipboard_IsSupported 3417
-#define wxClipboard_Get 3418
-#define wxSpinEvent_GetPosition 3419
-#define wxSpinEvent_SetPosition 3420
-#define wxSplitterWindow_new_0 3421
-#define wxSplitterWindow_new_2 3422
-#define wxSplitterWindow_destruct 3423
-#define wxSplitterWindow_Create 3424
-#define wxSplitterWindow_GetMinimumPaneSize 3425
-#define wxSplitterWindow_GetSashGravity 3426
-#define wxSplitterWindow_GetSashPosition 3427
-#define wxSplitterWindow_GetSplitMode 3428
-#define wxSplitterWindow_GetWindow1 3429
-#define wxSplitterWindow_GetWindow2 3430
-#define wxSplitterWindow_Initialize 3431
-#define wxSplitterWindow_IsSplit 3432
-#define wxSplitterWindow_ReplaceWindow 3433
-#define wxSplitterWindow_SetSashGravity 3434
-#define wxSplitterWindow_SetSashPosition 3435
-#define wxSplitterWindow_SetSashSize 3436
-#define wxSplitterWindow_SetMinimumPaneSize 3437
-#define wxSplitterWindow_SetSplitMode 3438
-#define wxSplitterWindow_SplitHorizontally 3439
-#define wxSplitterWindow_SplitVertically 3440
-#define wxSplitterWindow_Unsplit 3441
-#define wxSplitterWindow_UpdateSize 3442
-#define wxSplitterEvent_GetSashPosition 3443
-#define wxSplitterEvent_GetX 3444
-#define wxSplitterEvent_GetY 3445
-#define wxSplitterEvent_GetWindowBeingRemoved 3446
-#define wxSplitterEvent_SetSashPosition 3447
-#define wxHtmlWindow_new_0 3448
-#define wxHtmlWindow_new_2 3449
-#define wxHtmlWindow_AppendToPage 3450
-#define wxHtmlWindow_GetOpenedAnchor 3451
-#define wxHtmlWindow_GetOpenedPage 3452
-#define wxHtmlWindow_GetOpenedPageTitle 3453
-#define wxHtmlWindow_GetRelatedFrame 3454
-#define wxHtmlWindow_HistoryBack 3455
-#define wxHtmlWindow_HistoryCanBack 3456
-#define wxHtmlWindow_HistoryCanForward 3457
-#define wxHtmlWindow_HistoryClear 3458
-#define wxHtmlWindow_HistoryForward 3459
-#define wxHtmlWindow_LoadFile 3460
-#define wxHtmlWindow_LoadPage 3461
-#define wxHtmlWindow_SelectAll 3462
-#define wxHtmlWindow_SelectionToText 3463
-#define wxHtmlWindow_SelectLine 3464
-#define wxHtmlWindow_SelectWord 3465
-#define wxHtmlWindow_SetBorders 3466
-#define wxHtmlWindow_SetFonts 3467
-#define wxHtmlWindow_SetPage 3468
-#define wxHtmlWindow_SetRelatedFrame 3469
-#define wxHtmlWindow_SetRelatedStatusBar 3470
-#define wxHtmlWindow_ToText 3471
-#define wxHtmlWindow_destroy 3472
-#define wxHtmlLinkEvent_GetLinkInfo 3473
-#define wxAuiNotebookEvent_SetSelection 3474
-#define wxAuiNotebookEvent_GetSelection 3475
-#define wxAuiNotebookEvent_SetOldSelection 3476
-#define wxAuiNotebookEvent_GetOldSelection 3477
-#define wxAuiNotebookEvent_SetDragSource 3478
-#define wxAuiNotebookEvent_GetDragSource 3479
-#define wxAuiManagerEvent_SetManager 3480
-#define wxAuiManagerEvent_GetManager 3481
-#define wxAuiManagerEvent_SetPane 3482
-#define wxAuiManagerEvent_GetPane 3483
-#define wxAuiManagerEvent_SetButton 3484
-#define wxAuiManagerEvent_GetButton 3485
-#define wxAuiManagerEvent_SetDC 3486
-#define wxAuiManagerEvent_GetDC 3487
-#define wxAuiManagerEvent_Veto 3488
-#define wxAuiManagerEvent_GetVeto 3489
-#define wxAuiManagerEvent_SetCanVeto 3490
-#define wxAuiManagerEvent_CanVeto 3491
-#define wxLogNull_new 3492
-#define wxLogNull_destroy 3493
+#define wxListCtrl_GetEditControl 1675
+#define wxListCtrl_GetImageList 1676
+#define wxListCtrl_GetItem 1677
+#define wxListCtrl_GetItemBackgroundColour 1678
+#define wxListCtrl_GetItemCount 1679
+#define wxListCtrl_GetItemData 1680
+#define wxListCtrl_GetItemFont 1681
+#define wxListCtrl_GetItemPosition 1682
+#define wxListCtrl_GetItemRect 1683
+#define wxListCtrl_GetItemSpacing 1684
+#define wxListCtrl_GetItemState 1685
+#define wxListCtrl_GetItemText 1686
+#define wxListCtrl_GetItemTextColour 1687
+#define wxListCtrl_GetNextItem 1688
+#define wxListCtrl_GetSelectedItemCount 1689
+#define wxListCtrl_GetTextColour 1690
+#define wxListCtrl_GetTopItem 1691
+#define wxListCtrl_GetViewRect 1692
+#define wxListCtrl_HitTest 1693
+#define wxListCtrl_InsertColumn_2 1694
+#define wxListCtrl_InsertColumn_3 1695
+#define wxListCtrl_InsertItem_1 1696
+#define wxListCtrl_InsertItem_2_1 1697
+#define wxListCtrl_InsertItem_2_0 1698
+#define wxListCtrl_InsertItem_3 1699
+#define wxListCtrl_RefreshItem 1700
+#define wxListCtrl_RefreshItems 1701
+#define wxListCtrl_ScrollList 1702
+#define wxListCtrl_SetBackgroundColour 1703
+#define wxListCtrl_SetColumn 1704
+#define wxListCtrl_SetColumnWidth 1705
+#define wxListCtrl_SetImageList 1706
+#define wxListCtrl_SetItem_1 1707
+#define wxListCtrl_SetItem_4 1708
+#define wxListCtrl_SetItemBackgroundColour 1709
+#define wxListCtrl_SetItemCount 1710
+#define wxListCtrl_SetItemData 1711
+#define wxListCtrl_SetItemFont 1712
+#define wxListCtrl_SetItemImage 1713
+#define wxListCtrl_SetItemColumnImage 1714
+#define wxListCtrl_SetItemPosition 1715
+#define wxListCtrl_SetItemState 1716
+#define wxListCtrl_SetItemText 1717
+#define wxListCtrl_SetItemTextColour 1718
+#define wxListCtrl_SetSingleStyle 1719
+#define wxListCtrl_SetTextColour 1720
+#define wxListCtrl_SetWindowStyleFlag 1721
+#define wxListCtrl_SortItems 1722
+#define wxListCtrl_destroy 1723
+#define wxListView_ClearColumnImage 1724
+#define wxListView_Focus 1725
+#define wxListView_GetFirstSelected 1726
+#define wxListView_GetFocusedItem 1727
+#define wxListView_GetNextSelected 1728
+#define wxListView_IsSelected 1729
+#define wxListView_Select 1730
+#define wxListView_SetColumnImage 1731
+#define wxListItem_new_0 1732
+#define wxListItem_new_1 1733
+#define wxListItem_destruct 1734
+#define wxListItem_Clear 1735
+#define wxListItem_GetAlign 1736
+#define wxListItem_GetBackgroundColour 1737
+#define wxListItem_GetColumn 1738
+#define wxListItem_GetFont 1739
+#define wxListItem_GetId 1740
+#define wxListItem_GetImage 1741
+#define wxListItem_GetMask 1742
+#define wxListItem_GetState 1743
+#define wxListItem_GetText 1744
+#define wxListItem_GetTextColour 1745
+#define wxListItem_GetWidth 1746
+#define wxListItem_SetAlign 1747
+#define wxListItem_SetBackgroundColour 1748
+#define wxListItem_SetColumn 1749
+#define wxListItem_SetFont 1750
+#define wxListItem_SetId 1751
+#define wxListItem_SetImage 1752
+#define wxListItem_SetMask 1753
+#define wxListItem_SetState 1754
+#define wxListItem_SetStateMask 1755
+#define wxListItem_SetText 1756
+#define wxListItem_SetTextColour 1757
+#define wxListItem_SetWidth 1758
+#define wxImageList_new_0 1759
+#define wxImageList_new_3 1760
+#define wxImageList_Add_1 1761
+#define wxImageList_Add_2_0 1762
+#define wxImageList_Add_2_1 1763
+#define wxImageList_Create 1764
+#define wxImageList_Draw 1766
+#define wxImageList_GetBitmap 1767
+#define wxImageList_GetIcon 1768
+#define wxImageList_GetImageCount 1769
+#define wxImageList_GetSize 1770
+#define wxImageList_Remove 1771
+#define wxImageList_RemoveAll 1772
+#define wxImageList_Replace_2 1773
+#define wxImageList_Replace_3 1774
+#define wxImageList_destroy 1775
+#define wxTextAttr_new_0 1776
+#define wxTextAttr_new_2 1777
+#define wxTextAttr_GetAlignment 1778
+#define wxTextAttr_GetBackgroundColour 1779
+#define wxTextAttr_GetFont 1780
+#define wxTextAttr_GetLeftIndent 1781
+#define wxTextAttr_GetLeftSubIndent 1782
+#define wxTextAttr_GetRightIndent 1783
+#define wxTextAttr_GetTabs 1784
+#define wxTextAttr_GetTextColour 1785
+#define wxTextAttr_HasBackgroundColour 1786
+#define wxTextAttr_HasFont 1787
+#define wxTextAttr_HasTextColour 1788
+#define wxTextAttr_GetFlags 1789
+#define wxTextAttr_IsDefault 1790
+#define wxTextAttr_SetAlignment 1791
+#define wxTextAttr_SetBackgroundColour 1792
+#define wxTextAttr_SetFlags 1793
+#define wxTextAttr_SetFont 1794
+#define wxTextAttr_SetLeftIndent 1795
+#define wxTextAttr_SetRightIndent 1796
+#define wxTextAttr_SetTabs 1797
+#define wxTextAttr_SetTextColour 1798
+#define wxTextAttr_destroy 1799
+#define wxTextCtrl_new_3 1801
+#define wxTextCtrl_new_0 1802
+#define wxTextCtrl_destruct 1804
+#define wxTextCtrl_AppendText 1805
+#define wxTextCtrl_CanCopy 1806
+#define wxTextCtrl_CanCut 1807
+#define wxTextCtrl_CanPaste 1808
+#define wxTextCtrl_CanRedo 1809
+#define wxTextCtrl_CanUndo 1810
+#define wxTextCtrl_Clear 1811
+#define wxTextCtrl_Copy 1812
+#define wxTextCtrl_Create 1813
+#define wxTextCtrl_Cut 1814
+#define wxTextCtrl_DiscardEdits 1815
+#define wxTextCtrl_EmulateKeyPress 1816
+#define wxTextCtrl_GetDefaultStyle 1817
+#define wxTextCtrl_GetInsertionPoint 1818
+#define wxTextCtrl_GetLastPosition 1819
+#define wxTextCtrl_GetLineLength 1820
+#define wxTextCtrl_GetLineText 1821
+#define wxTextCtrl_GetNumberOfLines 1822
+#define wxTextCtrl_GetRange 1823
+#define wxTextCtrl_GetSelection 1824
+#define wxTextCtrl_GetStringSelection 1825
+#define wxTextCtrl_GetStyle 1826
+#define wxTextCtrl_GetValue 1827
+#define wxTextCtrl_IsEditable 1828
+#define wxTextCtrl_IsModified 1829
+#define wxTextCtrl_IsMultiLine 1830
+#define wxTextCtrl_IsSingleLine 1831
+#define wxTextCtrl_LoadFile 1832
+#define wxTextCtrl_MarkDirty 1833
+#define wxTextCtrl_Paste 1834
+#define wxTextCtrl_PositionToXY 1835
+#define wxTextCtrl_Redo 1836
+#define wxTextCtrl_Remove 1837
+#define wxTextCtrl_Replace 1838
+#define wxTextCtrl_SaveFile 1839
+#define wxTextCtrl_SetDefaultStyle 1840
+#define wxTextCtrl_SetEditable 1841
+#define wxTextCtrl_SetInsertionPoint 1842
+#define wxTextCtrl_SetInsertionPointEnd 1843
+#define wxTextCtrl_SetMaxLength 1845
+#define wxTextCtrl_SetSelection 1846
+#define wxTextCtrl_SetStyle 1847
+#define wxTextCtrl_SetValue 1848
+#define wxTextCtrl_ShowPosition 1849
+#define wxTextCtrl_Undo 1850
+#define wxTextCtrl_WriteText 1851
+#define wxTextCtrl_XYToPosition 1852
+#define wxNotebook_new_0 1855
+#define wxNotebook_new_3 1856
+#define wxNotebook_destruct 1857
+#define wxNotebook_AddPage 1858
+#define wxNotebook_AdvanceSelection 1859
+#define wxNotebook_AssignImageList 1860
+#define wxNotebook_Create 1861
+#define wxNotebook_DeleteAllPages 1862
+#define wxNotebook_DeletePage 1863
+#define wxNotebook_RemovePage 1864
+#define wxNotebook_GetCurrentPage 1865
+#define wxNotebook_GetImageList 1866
+#define wxNotebook_GetPage 1868
+#define wxNotebook_GetPageCount 1869
+#define wxNotebook_GetPageImage 1870
+#define wxNotebook_GetPageText 1871
+#define wxNotebook_GetRowCount 1872
+#define wxNotebook_GetSelection 1873
+#define wxNotebook_GetThemeBackgroundColour 1874
+#define wxNotebook_HitTest 1876
+#define wxNotebook_InsertPage 1878
+#define wxNotebook_SetImageList 1879
+#define wxNotebook_SetPadding 1880
+#define wxNotebook_SetPageSize 1881
+#define wxNotebook_SetPageImage 1882
+#define wxNotebook_SetPageText 1883
+#define wxNotebook_SetSelection 1884
+#define wxNotebook_ChangeSelection 1885
+#define wxChoicebook_new_0 1886
+#define wxChoicebook_new_3 1887
+#define wxChoicebook_AddPage 1888
+#define wxChoicebook_AdvanceSelection 1889
+#define wxChoicebook_AssignImageList 1890
+#define wxChoicebook_Create 1891
+#define wxChoicebook_DeleteAllPages 1892
+#define wxChoicebook_DeletePage 1893
+#define wxChoicebook_RemovePage 1894
+#define wxChoicebook_GetCurrentPage 1895
+#define wxChoicebook_GetImageList 1896
+#define wxChoicebook_GetPage 1898
+#define wxChoicebook_GetPageCount 1899
+#define wxChoicebook_GetPageImage 1900
+#define wxChoicebook_GetPageText 1901
+#define wxChoicebook_GetSelection 1902
+#define wxChoicebook_HitTest 1903
+#define wxChoicebook_InsertPage 1904
+#define wxChoicebook_SetImageList 1905
+#define wxChoicebook_SetPageSize 1906
+#define wxChoicebook_SetPageImage 1907
+#define wxChoicebook_SetPageText 1908
+#define wxChoicebook_SetSelection 1909
+#define wxChoicebook_ChangeSelection 1910
+#define wxChoicebook_destroy 1911
+#define wxToolbook_new_0 1912
+#define wxToolbook_new_3 1913
+#define wxToolbook_AddPage 1914
+#define wxToolbook_AdvanceSelection 1915
+#define wxToolbook_AssignImageList 1916
+#define wxToolbook_Create 1917
+#define wxToolbook_DeleteAllPages 1918
+#define wxToolbook_DeletePage 1919
+#define wxToolbook_RemovePage 1920
+#define wxToolbook_GetCurrentPage 1921
+#define wxToolbook_GetImageList 1922
+#define wxToolbook_GetPage 1924
+#define wxToolbook_GetPageCount 1925
+#define wxToolbook_GetPageImage 1926
+#define wxToolbook_GetPageText 1927
+#define wxToolbook_GetSelection 1928
+#define wxToolbook_HitTest 1930
+#define wxToolbook_InsertPage 1931
+#define wxToolbook_SetImageList 1932
+#define wxToolbook_SetPageSize 1933
+#define wxToolbook_SetPageImage 1934
+#define wxToolbook_SetPageText 1935
+#define wxToolbook_SetSelection 1936
+#define wxToolbook_ChangeSelection 1937
+#define wxToolbook_destroy 1938
+#define wxListbook_new_0 1939
+#define wxListbook_new_3 1940
+#define wxListbook_AddPage 1941
+#define wxListbook_AdvanceSelection 1942
+#define wxListbook_AssignImageList 1943
+#define wxListbook_Create 1944
+#define wxListbook_DeleteAllPages 1945
+#define wxListbook_DeletePage 1946
+#define wxListbook_RemovePage 1947
+#define wxListbook_GetCurrentPage 1948
+#define wxListbook_GetImageList 1949
+#define wxListbook_GetPage 1951
+#define wxListbook_GetPageCount 1952
+#define wxListbook_GetPageImage 1953
+#define wxListbook_GetPageText 1954
+#define wxListbook_GetSelection 1955
+#define wxListbook_HitTest 1957
+#define wxListbook_InsertPage 1958
+#define wxListbook_SetImageList 1959
+#define wxListbook_SetPageSize 1960
+#define wxListbook_SetPageImage 1961
+#define wxListbook_SetPageText 1962
+#define wxListbook_SetSelection 1963
+#define wxListbook_ChangeSelection 1964
+#define wxListbook_destroy 1965
+#define wxTreebook_new_0 1966
+#define wxTreebook_new_3 1967
+#define wxTreebook_AddPage 1968
+#define wxTreebook_AdvanceSelection 1969
+#define wxTreebook_AssignImageList 1970
+#define wxTreebook_Create 1971
+#define wxTreebook_DeleteAllPages 1972
+#define wxTreebook_DeletePage 1973
+#define wxTreebook_RemovePage 1974
+#define wxTreebook_GetCurrentPage 1975
+#define wxTreebook_GetImageList 1976
+#define wxTreebook_GetPage 1978
+#define wxTreebook_GetPageCount 1979
+#define wxTreebook_GetPageImage 1980
+#define wxTreebook_GetPageText 1981
+#define wxTreebook_GetSelection 1982
+#define wxTreebook_ExpandNode 1983
+#define wxTreebook_IsNodeExpanded 1984
+#define wxTreebook_HitTest 1986
+#define wxTreebook_InsertPage 1987
+#define wxTreebook_InsertSubPage 1988
+#define wxTreebook_SetImageList 1989
+#define wxTreebook_SetPageSize 1990
+#define wxTreebook_SetPageImage 1991
+#define wxTreebook_SetPageText 1992
+#define wxTreebook_SetSelection 1993
+#define wxTreebook_ChangeSelection 1994
+#define wxTreebook_destroy 1995
+#define wxTreeCtrl_new_2 1998
+#define wxTreeCtrl_new_0 1999
+#define wxTreeCtrl_destruct 2001
+#define wxTreeCtrl_AddRoot 2002
+#define wxTreeCtrl_AppendItem 2003
+#define wxTreeCtrl_AssignImageList 2004
+#define wxTreeCtrl_AssignStateImageList 2005
+#define wxTreeCtrl_Collapse 2006
+#define wxTreeCtrl_CollapseAndReset 2007
+#define wxTreeCtrl_Create 2008
+#define wxTreeCtrl_Delete 2009
+#define wxTreeCtrl_DeleteAllItems 2010
+#define wxTreeCtrl_DeleteChildren 2011
+#define wxTreeCtrl_EnsureVisible 2012
+#define wxTreeCtrl_Expand 2013
+#define wxTreeCtrl_GetBoundingRect 2014
+#define wxTreeCtrl_GetChildrenCount 2016
+#define wxTreeCtrl_GetCount 2017
+#define wxTreeCtrl_GetEditControl 2018
+#define wxTreeCtrl_GetFirstChild 2019
+#define wxTreeCtrl_GetNextChild 2020
+#define wxTreeCtrl_GetFirstVisibleItem 2021
+#define wxTreeCtrl_GetImageList 2022
+#define wxTreeCtrl_GetIndent 2023
+#define wxTreeCtrl_GetItemBackgroundColour 2024
+#define wxTreeCtrl_GetItemData 2025
+#define wxTreeCtrl_GetItemFont 2026
+#define wxTreeCtrl_GetItemImage_1 2027
+#define wxTreeCtrl_GetItemImage_2 2028
+#define wxTreeCtrl_GetItemText 2029
+#define wxTreeCtrl_GetItemTextColour 2030
+#define wxTreeCtrl_GetLastChild 2031
+#define wxTreeCtrl_GetNextSibling 2032
+#define wxTreeCtrl_GetNextVisible 2033
+#define wxTreeCtrl_GetItemParent 2034
+#define wxTreeCtrl_GetPrevSibling 2035
+#define wxTreeCtrl_GetPrevVisible 2036
+#define wxTreeCtrl_GetRootItem 2037
+#define wxTreeCtrl_GetSelection 2038
+#define wxTreeCtrl_GetSelections 2039
+#define wxTreeCtrl_GetStateImageList 2040
+#define wxTreeCtrl_HitTest 2041
+#define wxTreeCtrl_InsertItem 2043
+#define wxTreeCtrl_IsBold 2044
+#define wxTreeCtrl_IsExpanded 2045
+#define wxTreeCtrl_IsSelected 2046
+#define wxTreeCtrl_IsVisible 2047
+#define wxTreeCtrl_ItemHasChildren 2048
+#define wxTreeCtrl_PrependItem 2049
+#define wxTreeCtrl_ScrollTo 2050
+#define wxTreeCtrl_SelectItem_1 2051
+#define wxTreeCtrl_SelectItem_2 2052
+#define wxTreeCtrl_SetIndent 2053
+#define wxTreeCtrl_SetImageList 2054
+#define wxTreeCtrl_SetItemBackgroundColour 2055
+#define wxTreeCtrl_SetItemBold 2056
+#define wxTreeCtrl_SetItemData 2057
+#define wxTreeCtrl_SetItemDropHighlight 2058
+#define wxTreeCtrl_SetItemFont 2059
+#define wxTreeCtrl_SetItemHasChildren 2060
+#define wxTreeCtrl_SetItemImage_2 2061
+#define wxTreeCtrl_SetItemImage_3 2062
+#define wxTreeCtrl_SetItemText 2063
+#define wxTreeCtrl_SetItemTextColour 2064
+#define wxTreeCtrl_SetStateImageList 2065
+#define wxTreeCtrl_SetWindowStyle 2066
+#define wxTreeCtrl_SortChildren 2067
+#define wxTreeCtrl_Toggle 2068
+#define wxTreeCtrl_ToggleItemSelection 2069
+#define wxTreeCtrl_Unselect 2070
+#define wxTreeCtrl_UnselectAll 2071
+#define wxTreeCtrl_UnselectItem 2072
+#define wxScrollBar_new_0 2073
+#define wxScrollBar_new_3 2074
+#define wxScrollBar_destruct 2075
+#define wxScrollBar_Create 2076
+#define wxScrollBar_GetRange 2077
+#define wxScrollBar_GetPageSize 2078
+#define wxScrollBar_GetThumbPosition 2079
+#define wxScrollBar_GetThumbSize 2080
+#define wxScrollBar_SetThumbPosition 2081
+#define wxScrollBar_SetScrollbar 2082
+#define wxSpinButton_new_2 2084
+#define wxSpinButton_new_0 2085
+#define wxSpinButton_Create 2086
+#define wxSpinButton_GetMax 2087
+#define wxSpinButton_GetMin 2088
+#define wxSpinButton_GetValue 2089
+#define wxSpinButton_SetRange 2090
+#define wxSpinButton_SetValue 2091
+#define wxSpinButton_destroy 2092
+#define wxSpinCtrl_new_0 2093
+#define wxSpinCtrl_new_2 2094
+#define wxSpinCtrl_Create 2096
+#define wxSpinCtrl_SetValue_1_1 2099
+#define wxSpinCtrl_SetValue_1_0 2100
+#define wxSpinCtrl_GetValue 2102
+#define wxSpinCtrl_SetRange 2104
+#define wxSpinCtrl_SetSelection 2105
+#define wxSpinCtrl_GetMin 2107
+#define wxSpinCtrl_GetMax 2109
+#define wxSpinCtrl_destroy 2110
+#define wxStaticText_new_0 2111
+#define wxStaticText_new_4 2112
+#define wxStaticText_Create 2113
+#define wxStaticText_GetLabel 2114
+#define wxStaticText_SetLabel 2115
+#define wxStaticText_Wrap 2116
+#define wxStaticText_destroy 2117
+#define wxStaticBitmap_new_0 2118
+#define wxStaticBitmap_new_4 2119
+#define wxStaticBitmap_Create 2120
+#define wxStaticBitmap_GetBitmap 2121
+#define wxStaticBitmap_SetBitmap 2122
+#define wxStaticBitmap_destroy 2123
+#define wxRadioBox_new 2124
+#define wxRadioBox_destruct 2126
+#define wxRadioBox_Create 2127
+#define wxRadioBox_Enable_2 2128
+#define wxRadioBox_Enable_1 2129
+#define wxRadioBox_GetSelection 2130
+#define wxRadioBox_GetString 2131
+#define wxRadioBox_SetSelection 2132
+#define wxRadioBox_Show_2 2133
+#define wxRadioBox_Show_1 2134
+#define wxRadioBox_GetColumnCount 2135
+#define wxRadioBox_GetItemHelpText 2136
+#define wxRadioBox_GetItemToolTip 2137
+#define wxRadioBox_GetItemFromPoint 2139
+#define wxRadioBox_GetRowCount 2140
+#define wxRadioBox_IsItemEnabled 2141
+#define wxRadioBox_IsItemShown 2142
+#define wxRadioBox_SetItemHelpText 2143
+#define wxRadioBox_SetItemToolTip 2144
+#define wxRadioButton_new_0 2145
+#define wxRadioButton_new_4 2146
+#define wxRadioButton_Create 2147
+#define wxRadioButton_GetValue 2148
+#define wxRadioButton_SetValue 2149
+#define wxRadioButton_destroy 2150
+#define wxSlider_new_6 2152
+#define wxSlider_new_0 2153
+#define wxSlider_Create 2154
+#define wxSlider_GetLineSize 2155
+#define wxSlider_GetMax 2156
+#define wxSlider_GetMin 2157
+#define wxSlider_GetPageSize 2158
+#define wxSlider_GetThumbLength 2159
+#define wxSlider_GetValue 2160
+#define wxSlider_SetLineSize 2161
+#define wxSlider_SetPageSize 2162
+#define wxSlider_SetRange 2163
+#define wxSlider_SetThumbLength 2164
+#define wxSlider_SetValue 2165
+#define wxSlider_destroy 2166
+#define wxDialog_new_4 2168
+#define wxDialog_new_0 2169
+#define wxDialog_destruct 2171
+#define wxDialog_Create 2172
+#define wxDialog_CreateButtonSizer 2173
+#define wxDialog_CreateStdDialogButtonSizer 2174
+#define wxDialog_EndModal 2175
+#define wxDialog_GetAffirmativeId 2176
+#define wxDialog_GetReturnCode 2177
+#define wxDialog_IsModal 2178
+#define wxDialog_SetAffirmativeId 2179
+#define wxDialog_SetReturnCode 2180
+#define wxDialog_Show 2181
+#define wxDialog_ShowModal 2182
+#define wxColourDialog_new_0 2183
+#define wxColourDialog_new_2 2184
+#define wxColourDialog_destruct 2185
+#define wxColourDialog_Create 2186
+#define wxColourDialog_GetColourData 2187
+#define wxColourData_new_0 2188
+#define wxColourData_new_1 2189
+#define wxColourData_destruct 2190
+#define wxColourData_GetChooseFull 2191
+#define wxColourData_GetColour 2192
+#define wxColourData_GetCustomColour 2194
+#define wxColourData_SetChooseFull 2195
+#define wxColourData_SetColour 2196
+#define wxColourData_SetCustomColour 2197
+#define wxPalette_new_0 2198
+#define wxPalette_new_4 2199
+#define wxPalette_destruct 2201
+#define wxPalette_Create 2202
+#define wxPalette_GetColoursCount 2203
+#define wxPalette_GetPixel 2204
+#define wxPalette_GetRGB 2205
+#define wxPalette_IsOk 2206
+#define wxDirDialog_new 2210
+#define wxDirDialog_destruct 2211
+#define wxDirDialog_GetPath 2212
+#define wxDirDialog_GetMessage 2213
+#define wxDirDialog_SetMessage 2214
+#define wxDirDialog_SetPath 2215
+#define wxFileDialog_new 2219
+#define wxFileDialog_destruct 2220
+#define wxFileDialog_GetDirectory 2221
+#define wxFileDialog_GetFilename 2222
+#define wxFileDialog_GetFilenames 2223
+#define wxFileDialog_GetFilterIndex 2224
+#define wxFileDialog_GetMessage 2225
+#define wxFileDialog_GetPath 2226
+#define wxFileDialog_GetPaths 2227
+#define wxFileDialog_GetWildcard 2228
+#define wxFileDialog_SetDirectory 2229
+#define wxFileDialog_SetFilename 2230
+#define wxFileDialog_SetFilterIndex 2231
+#define wxFileDialog_SetMessage 2232
+#define wxFileDialog_SetPath 2233
+#define wxFileDialog_SetWildcard 2234
+#define wxPickerBase_SetInternalMargin 2235
+#define wxPickerBase_GetInternalMargin 2236
+#define wxPickerBase_SetTextCtrlProportion 2237
+#define wxPickerBase_SetPickerCtrlProportion 2238
+#define wxPickerBase_GetTextCtrlProportion 2239
+#define wxPickerBase_GetPickerCtrlProportion 2240
+#define wxPickerBase_HasTextCtrl 2241
+#define wxPickerBase_GetTextCtrl 2242
+#define wxPickerBase_IsTextCtrlGrowable 2243
+#define wxPickerBase_SetPickerCtrlGrowable 2244
+#define wxPickerBase_SetTextCtrlGrowable 2245
+#define wxPickerBase_IsPickerCtrlGrowable 2246
+#define wxFilePickerCtrl_new_0 2247
+#define wxFilePickerCtrl_new_3 2248
+#define wxFilePickerCtrl_Create 2249
+#define wxFilePickerCtrl_GetPath 2250
+#define wxFilePickerCtrl_SetPath 2251
+#define wxFilePickerCtrl_destroy 2252
+#define wxDirPickerCtrl_new_0 2253
+#define wxDirPickerCtrl_new_3 2254
+#define wxDirPickerCtrl_Create 2255
+#define wxDirPickerCtrl_GetPath 2256
+#define wxDirPickerCtrl_SetPath 2257
+#define wxDirPickerCtrl_destroy 2258
+#define wxColourPickerCtrl_new_0 2259
+#define wxColourPickerCtrl_new_3 2260
+#define wxColourPickerCtrl_Create 2261
+#define wxColourPickerCtrl_GetColour 2262
+#define wxColourPickerCtrl_SetColour_1_1 2263
+#define wxColourPickerCtrl_SetColour_1_0 2264
+#define wxColourPickerCtrl_destroy 2265
+#define wxDatePickerCtrl_new_0 2266
+#define wxDatePickerCtrl_new_3 2267
+#define wxDatePickerCtrl_GetRange 2268
+#define wxDatePickerCtrl_GetValue 2269
+#define wxDatePickerCtrl_SetRange 2270
+#define wxDatePickerCtrl_SetValue 2271
+#define wxDatePickerCtrl_destroy 2272
+#define wxFontPickerCtrl_new_0 2273
+#define wxFontPickerCtrl_new_3 2274
+#define wxFontPickerCtrl_Create 2275
+#define wxFontPickerCtrl_GetSelectedFont 2276
+#define wxFontPickerCtrl_SetSelectedFont 2277
+#define wxFontPickerCtrl_GetMaxPointSize 2278
+#define wxFontPickerCtrl_SetMaxPointSize 2279
+#define wxFontPickerCtrl_destroy 2280
+#define wxFindReplaceDialog_new_0 2283
+#define wxFindReplaceDialog_new_4 2284
+#define wxFindReplaceDialog_destruct 2285
+#define wxFindReplaceDialog_Create 2286
+#define wxFindReplaceDialog_GetData 2287
+#define wxFindReplaceData_new_0 2288
+#define wxFindReplaceData_new_1 2289
+#define wxFindReplaceData_GetFindString 2290
+#define wxFindReplaceData_GetReplaceString 2291
+#define wxFindReplaceData_GetFlags 2292
+#define wxFindReplaceData_SetFlags 2293
+#define wxFindReplaceData_SetFindString 2294
+#define wxFindReplaceData_SetReplaceString 2295
+#define wxFindReplaceData_destroy 2296
+#define wxMultiChoiceDialog_new_0 2297
+#define wxMultiChoiceDialog_new_5 2299
+#define wxMultiChoiceDialog_GetSelections 2300
+#define wxMultiChoiceDialog_SetSelections 2301
+#define wxMultiChoiceDialog_destroy 2302
+#define wxSingleChoiceDialog_new_0 2303
+#define wxSingleChoiceDialog_new_5 2305
+#define wxSingleChoiceDialog_GetSelection 2306
+#define wxSingleChoiceDialog_GetStringSelection 2307
+#define wxSingleChoiceDialog_SetSelection 2308
+#define wxSingleChoiceDialog_destroy 2309
+#define wxTextEntryDialog_new 2310
+#define wxTextEntryDialog_GetValue 2311
+#define wxTextEntryDialog_SetValue 2312
+#define wxTextEntryDialog_destroy 2313
+#define wxPasswordEntryDialog_new 2314
+#define wxPasswordEntryDialog_destroy 2315
+#define wxFontData_new_0 2316
+#define wxFontData_new_1 2317
+#define wxFontData_destruct 2318
+#define wxFontData_EnableEffects 2319
+#define wxFontData_GetAllowSymbols 2320
+#define wxFontData_GetColour 2321
+#define wxFontData_GetChosenFont 2322
+#define wxFontData_GetEnableEffects 2323
+#define wxFontData_GetInitialFont 2324
+#define wxFontData_GetShowHelp 2325
+#define wxFontData_SetAllowSymbols 2326
+#define wxFontData_SetChosenFont 2327
+#define wxFontData_SetColour 2328
+#define wxFontData_SetInitialFont 2329
+#define wxFontData_SetRange 2330
+#define wxFontData_SetShowHelp 2331
+#define wxFontDialog_new_0 2335
+#define wxFontDialog_new_2 2337
+#define wxFontDialog_Create 2339
+#define wxFontDialog_GetFontData 2340
+#define wxFontDialog_destroy 2342
+#define wxProgressDialog_new 2343
+#define wxProgressDialog_destruct 2344
+#define wxProgressDialog_Resume 2345
+#define wxProgressDialog_Update_2 2346
+#define wxProgressDialog_Update_0 2347
+#define wxMessageDialog_new 2348
+#define wxMessageDialog_destruct 2349
+#define wxPageSetupDialog_new 2350
+#define wxPageSetupDialog_destruct 2351
+#define wxPageSetupDialog_GetPageSetupData 2352
+#define wxPageSetupDialog_ShowModal 2353
+#define wxPageSetupDialogData_new_0 2354
+#define wxPageSetupDialogData_new_1_0 2355
+#define wxPageSetupDialogData_new_1_1 2356
+#define wxPageSetupDialogData_destruct 2357
+#define wxPageSetupDialogData_EnableHelp 2358
+#define wxPageSetupDialogData_EnableMargins 2359
+#define wxPageSetupDialogData_EnableOrientation 2360
+#define wxPageSetupDialogData_EnablePaper 2361
+#define wxPageSetupDialogData_EnablePrinter 2362
+#define wxPageSetupDialogData_GetDefaultMinMargins 2363
+#define wxPageSetupDialogData_GetEnableMargins 2364
+#define wxPageSetupDialogData_GetEnableOrientation 2365
+#define wxPageSetupDialogData_GetEnablePaper 2366
+#define wxPageSetupDialogData_GetEnablePrinter 2367
+#define wxPageSetupDialogData_GetEnableHelp 2368
+#define wxPageSetupDialogData_GetDefaultInfo 2369
+#define wxPageSetupDialogData_GetMarginTopLeft 2370
+#define wxPageSetupDialogData_GetMarginBottomRight 2371
+#define wxPageSetupDialogData_GetMinMarginTopLeft 2372
+#define wxPageSetupDialogData_GetMinMarginBottomRight 2373
+#define wxPageSetupDialogData_GetPaperId 2374
+#define wxPageSetupDialogData_GetPaperSize 2375
+#define wxPageSetupDialogData_GetPrintData 2377
+#define wxPageSetupDialogData_IsOk 2378
+#define wxPageSetupDialogData_SetDefaultInfo 2379
+#define wxPageSetupDialogData_SetDefaultMinMargins 2380
+#define wxPageSetupDialogData_SetMarginTopLeft 2381
+#define wxPageSetupDialogData_SetMarginBottomRight 2382
+#define wxPageSetupDialogData_SetMinMarginTopLeft 2383
+#define wxPageSetupDialogData_SetMinMarginBottomRight 2384
+#define wxPageSetupDialogData_SetPaperId 2385
+#define wxPageSetupDialogData_SetPaperSize_1_1 2386
+#define wxPageSetupDialogData_SetPaperSize_1_0 2387
+#define wxPageSetupDialogData_SetPrintData 2388
+#define wxPrintDialog_new_2_0 2389
+#define wxPrintDialog_new_2_1 2390
+#define wxPrintDialog_destruct 2391
+#define wxPrintDialog_GetPrintDialogData 2392
+#define wxPrintDialog_GetPrintDC 2393
+#define wxPrintDialogData_new_0 2394
+#define wxPrintDialogData_new_1_1 2395
+#define wxPrintDialogData_new_1_0 2396
+#define wxPrintDialogData_destruct 2397
+#define wxPrintDialogData_EnableHelp 2398
+#define wxPrintDialogData_EnablePageNumbers 2399
+#define wxPrintDialogData_EnablePrintToFile 2400
+#define wxPrintDialogData_EnableSelection 2401
+#define wxPrintDialogData_GetAllPages 2402
+#define wxPrintDialogData_GetCollate 2403
+#define wxPrintDialogData_GetFromPage 2404
+#define wxPrintDialogData_GetMaxPage 2405
+#define wxPrintDialogData_GetMinPage 2406
+#define wxPrintDialogData_GetNoCopies 2407
+#define wxPrintDialogData_GetPrintData 2408
+#define wxPrintDialogData_GetPrintToFile 2409
+#define wxPrintDialogData_GetSelection 2410
+#define wxPrintDialogData_GetToPage 2411
+#define wxPrintDialogData_IsOk 2412
+#define wxPrintDialogData_SetCollate 2413
+#define wxPrintDialogData_SetFromPage 2414
+#define wxPrintDialogData_SetMaxPage 2415
+#define wxPrintDialogData_SetMinPage 2416
+#define wxPrintDialogData_SetNoCopies 2417
+#define wxPrintDialogData_SetPrintData 2418
+#define wxPrintDialogData_SetPrintToFile 2419
+#define wxPrintDialogData_SetSelection 2420
+#define wxPrintDialogData_SetToPage 2421
+#define wxPrintData_new_0 2422
+#define wxPrintData_new_1 2423
+#define wxPrintData_destruct 2424
+#define wxPrintData_GetCollate 2425
+#define wxPrintData_GetBin 2426
+#define wxPrintData_GetColour 2427
+#define wxPrintData_GetDuplex 2428
+#define wxPrintData_GetNoCopies 2429
+#define wxPrintData_GetOrientation 2430
+#define wxPrintData_GetPaperId 2431
+#define wxPrintData_GetPrinterName 2432
+#define wxPrintData_GetQuality 2433
+#define wxPrintData_IsOk 2434
+#define wxPrintData_SetBin 2435
+#define wxPrintData_SetCollate 2436
+#define wxPrintData_SetColour 2437
+#define wxPrintData_SetDuplex 2438
+#define wxPrintData_SetNoCopies 2439
+#define wxPrintData_SetOrientation 2440
+#define wxPrintData_SetPaperId 2441
+#define wxPrintData_SetPrinterName 2442
+#define wxPrintData_SetQuality 2443
+#define wxPrintPreview_new_2 2446
+#define wxPrintPreview_new_3 2447
+#define wxPrintPreview_destruct 2449
+#define wxPrintPreview_GetCanvas 2450
+#define wxPrintPreview_GetCurrentPage 2451
+#define wxPrintPreview_GetFrame 2452
+#define wxPrintPreview_GetMaxPage 2453
+#define wxPrintPreview_GetMinPage 2454
+#define wxPrintPreview_GetPrintout 2455
+#define wxPrintPreview_GetPrintoutForPrinting 2456
+#define wxPrintPreview_IsOk 2457
+#define wxPrintPreview_PaintPage 2458
+#define wxPrintPreview_Print 2459
+#define wxPrintPreview_RenderPage 2460
+#define wxPrintPreview_SetCanvas 2461
+#define wxPrintPreview_SetCurrentPage 2462
+#define wxPrintPreview_SetFrame 2463
+#define wxPrintPreview_SetPrintout 2464
+#define wxPrintPreview_SetZoom 2465
+#define wxPreviewFrame_new 2466
+#define wxPreviewFrame_destruct 2467
+#define wxPreviewFrame_CreateControlBar 2468
+#define wxPreviewFrame_CreateCanvas 2469
+#define wxPreviewFrame_Initialize 2470
+#define wxPreviewFrame_OnCloseWindow 2471
+#define wxPreviewControlBar_new 2472
+#define wxPreviewControlBar_destruct 2473
+#define wxPreviewControlBar_CreateButtons 2474
+#define wxPreviewControlBar_GetPrintPreview 2475
+#define wxPreviewControlBar_GetZoomControl 2476
+#define wxPreviewControlBar_SetZoomControl 2477
+#define wxPrinter_new 2479
+#define wxPrinter_CreateAbortWindow 2480
+#define wxPrinter_GetAbort 2481
+#define wxPrinter_GetLastError 2482
+#define wxPrinter_GetPrintDialogData 2483
+#define wxPrinter_Print 2484
+#define wxPrinter_PrintDialog 2485
+#define wxPrinter_ReportError 2486
+#define wxPrinter_Setup 2487
+#define wxPrinter_destroy 2488
+#define wxXmlResource_new_1 2489
+#define wxXmlResource_new_2 2490
+#define wxXmlResource_destruct 2491
+#define wxXmlResource_AttachUnknownControl 2492
+#define wxXmlResource_ClearHandlers 2493
+#define wxXmlResource_CompareVersion 2494
+#define wxXmlResource_Get 2495
+#define wxXmlResource_GetFlags 2496
+#define wxXmlResource_GetVersion 2497
+#define wxXmlResource_GetXRCID 2498
+#define wxXmlResource_InitAllHandlers 2499
+#define wxXmlResource_Load 2500
+#define wxXmlResource_LoadBitmap 2501
+#define wxXmlResource_LoadDialog_2 2502
+#define wxXmlResource_LoadDialog_3 2503
+#define wxXmlResource_LoadFrame_2 2504
+#define wxXmlResource_LoadFrame_3 2505
+#define wxXmlResource_LoadIcon 2506
+#define wxXmlResource_LoadMenu 2507
+#define wxXmlResource_LoadMenuBar_2 2508
+#define wxXmlResource_LoadMenuBar_1 2509
+#define wxXmlResource_LoadPanel_2 2510
+#define wxXmlResource_LoadPanel_3 2511
+#define wxXmlResource_LoadToolBar 2512
+#define wxXmlResource_Set 2513
+#define wxXmlResource_SetFlags 2514
+#define wxXmlResource_Unload 2515
+#define wxXmlResource_xrcctrl 2516
+#define wxHtmlEasyPrinting_new 2517
+#define wxHtmlEasyPrinting_destruct 2518
+#define wxHtmlEasyPrinting_GetPrintData 2519
+#define wxHtmlEasyPrinting_GetPageSetupData 2520
+#define wxHtmlEasyPrinting_PreviewFile 2521
+#define wxHtmlEasyPrinting_PreviewText 2522
+#define wxHtmlEasyPrinting_PrintFile 2523
+#define wxHtmlEasyPrinting_PrintText 2524
+#define wxHtmlEasyPrinting_PageSetup 2525
+#define wxHtmlEasyPrinting_SetFonts 2526
+#define wxHtmlEasyPrinting_SetHeader 2527
+#define wxHtmlEasyPrinting_SetFooter 2528
+#define wxGLCanvas_new_2 2530
+#define wxGLCanvas_new_3_1 2531
+#define wxGLCanvas_new_3_0 2532
+#define wxGLCanvas_GetContext 2533
+#define wxGLCanvas_SetCurrent 2535
+#define wxGLCanvas_SwapBuffers 2536
+#define wxGLCanvas_destroy 2537
+#define wxAuiManager_new 2538
+#define wxAuiManager_destruct 2539
+#define wxAuiManager_AddPane_2_1 2540
+#define wxAuiManager_AddPane_3 2541
+#define wxAuiManager_AddPane_2_0 2542
+#define wxAuiManager_DetachPane 2543
+#define wxAuiManager_GetAllPanes 2544
+#define wxAuiManager_GetArtProvider 2545
+#define wxAuiManager_GetDockSizeConstraint 2546
+#define wxAuiManager_GetFlags 2547
+#define wxAuiManager_GetManagedWindow 2548
+#define wxAuiManager_GetManager 2549
+#define wxAuiManager_GetPane_1_1 2550
+#define wxAuiManager_GetPane_1_0 2551
+#define wxAuiManager_HideHint 2552
+#define wxAuiManager_InsertPane 2553
+#define wxAuiManager_LoadPaneInfo 2554
+#define wxAuiManager_LoadPerspective 2555
+#define wxAuiManager_SavePaneInfo 2556
+#define wxAuiManager_SavePerspective 2557
+#define wxAuiManager_SetArtProvider 2558
+#define wxAuiManager_SetDockSizeConstraint 2559
+#define wxAuiManager_SetFlags 2560
+#define wxAuiManager_SetManagedWindow 2561
+#define wxAuiManager_ShowHint 2562
+#define wxAuiManager_UnInit 2563
+#define wxAuiManager_Update 2564
+#define wxAuiPaneInfo_new_0 2565
+#define wxAuiPaneInfo_new_1 2566
+#define wxAuiPaneInfo_destruct 2567
+#define wxAuiPaneInfo_BestSize_1 2568
+#define wxAuiPaneInfo_BestSize_2 2569
+#define wxAuiPaneInfo_Bottom 2570
+#define wxAuiPaneInfo_BottomDockable 2571
+#define wxAuiPaneInfo_Caption 2572
+#define wxAuiPaneInfo_CaptionVisible 2573
+#define wxAuiPaneInfo_Centre 2574
+#define wxAuiPaneInfo_CentrePane 2575
+#define wxAuiPaneInfo_CloseButton 2576
+#define wxAuiPaneInfo_DefaultPane 2577
+#define wxAuiPaneInfo_DestroyOnClose 2578
+#define wxAuiPaneInfo_Direction 2579
+#define wxAuiPaneInfo_Dock 2580
+#define wxAuiPaneInfo_Dockable 2581
+#define wxAuiPaneInfo_Fixed 2582
+#define wxAuiPaneInfo_Float 2583
+#define wxAuiPaneInfo_Floatable 2584
+#define wxAuiPaneInfo_FloatingPosition_1 2585
+#define wxAuiPaneInfo_FloatingPosition_2 2586
+#define wxAuiPaneInfo_FloatingSize_1 2587
+#define wxAuiPaneInfo_FloatingSize_2 2588
+#define wxAuiPaneInfo_Gripper 2589
+#define wxAuiPaneInfo_GripperTop 2590
+#define wxAuiPaneInfo_HasBorder 2591
+#define wxAuiPaneInfo_HasCaption 2592
+#define wxAuiPaneInfo_HasCloseButton 2593
+#define wxAuiPaneInfo_HasFlag 2594
+#define wxAuiPaneInfo_HasGripper 2595
+#define wxAuiPaneInfo_HasGripperTop 2596
+#define wxAuiPaneInfo_HasMaximizeButton 2597
+#define wxAuiPaneInfo_HasMinimizeButton 2598
+#define wxAuiPaneInfo_HasPinButton 2599
+#define wxAuiPaneInfo_Hide 2600
+#define wxAuiPaneInfo_IsBottomDockable 2601
+#define wxAuiPaneInfo_IsDocked 2602
+#define wxAuiPaneInfo_IsFixed 2603
+#define wxAuiPaneInfo_IsFloatable 2604
+#define wxAuiPaneInfo_IsFloating 2605
+#define wxAuiPaneInfo_IsLeftDockable 2606
+#define wxAuiPaneInfo_IsMovable 2607
+#define wxAuiPaneInfo_IsOk 2608
+#define wxAuiPaneInfo_IsResizable 2609
+#define wxAuiPaneInfo_IsRightDockable 2610
+#define wxAuiPaneInfo_IsShown 2611
+#define wxAuiPaneInfo_IsToolbar 2612
+#define wxAuiPaneInfo_IsTopDockable 2613
+#define wxAuiPaneInfo_Layer 2614
+#define wxAuiPaneInfo_Left 2615
+#define wxAuiPaneInfo_LeftDockable 2616
+#define wxAuiPaneInfo_MaxSize_1 2617
+#define wxAuiPaneInfo_MaxSize_2 2618
+#define wxAuiPaneInfo_MaximizeButton 2619
+#define wxAuiPaneInfo_MinSize_1 2620
+#define wxAuiPaneInfo_MinSize_2 2621
+#define wxAuiPaneInfo_MinimizeButton 2622
+#define wxAuiPaneInfo_Movable 2623
+#define wxAuiPaneInfo_Name 2624
+#define wxAuiPaneInfo_PaneBorder 2625
+#define wxAuiPaneInfo_PinButton 2626
+#define wxAuiPaneInfo_Position 2627
+#define wxAuiPaneInfo_Resizable 2628
+#define wxAuiPaneInfo_Right 2629
+#define wxAuiPaneInfo_RightDockable 2630
+#define wxAuiPaneInfo_Row 2631
+#define wxAuiPaneInfo_SafeSet 2632
+#define wxAuiPaneInfo_SetFlag 2633
+#define wxAuiPaneInfo_Show 2634
+#define wxAuiPaneInfo_ToolbarPane 2635
+#define wxAuiPaneInfo_Top 2636
+#define wxAuiPaneInfo_TopDockable 2637
+#define wxAuiPaneInfo_Window 2638
+#define wxAuiNotebook_new_0 2639
+#define wxAuiNotebook_new_2 2640
+#define wxAuiNotebook_AddPage 2641
+#define wxAuiNotebook_Create 2642
+#define wxAuiNotebook_DeletePage 2643
+#define wxAuiNotebook_GetArtProvider 2644
+#define wxAuiNotebook_GetPage 2645
+#define wxAuiNotebook_GetPageBitmap 2646
+#define wxAuiNotebook_GetPageCount 2647
+#define wxAuiNotebook_GetPageIndex 2648
+#define wxAuiNotebook_GetPageText 2649
+#define wxAuiNotebook_GetSelection 2650
+#define wxAuiNotebook_InsertPage 2651
+#define wxAuiNotebook_RemovePage 2652
+#define wxAuiNotebook_SetArtProvider 2653
+#define wxAuiNotebook_SetFont 2654
+#define wxAuiNotebook_SetPageBitmap 2655
+#define wxAuiNotebook_SetPageText 2656
+#define wxAuiNotebook_SetSelection 2657
+#define wxAuiNotebook_SetTabCtrlHeight 2658
+#define wxAuiNotebook_SetUniformBitmapSize 2659
+#define wxAuiNotebook_destroy 2660
+#define wxMDIParentFrame_new_0 2661
+#define wxMDIParentFrame_new_4 2662
+#define wxMDIParentFrame_destruct 2663
+#define wxMDIParentFrame_ActivateNext 2664
+#define wxMDIParentFrame_ActivatePrevious 2665
+#define wxMDIParentFrame_ArrangeIcons 2666
+#define wxMDIParentFrame_Cascade 2667
+#define wxMDIParentFrame_Create 2668
+#define wxMDIParentFrame_GetActiveChild 2669
+#define wxMDIParentFrame_GetClientWindow 2670
+#define wxMDIParentFrame_Tile 2671
+#define wxMDIChildFrame_new_0 2672
+#define wxMDIChildFrame_new_4 2673
+#define wxMDIChildFrame_destruct 2674
+#define wxMDIChildFrame_Activate 2675
+#define wxMDIChildFrame_Create 2676
+#define wxMDIChildFrame_Maximize 2677
+#define wxMDIChildFrame_Restore 2678
+#define wxMDIClientWindow_new_0 2679
+#define wxMDIClientWindow_new_2 2680
+#define wxMDIClientWindow_destruct 2681
+#define wxMDIClientWindow_CreateClient 2682
+#define wxLayoutAlgorithm_new 2683
+#define wxLayoutAlgorithm_LayoutFrame 2684
+#define wxLayoutAlgorithm_LayoutMDIFrame 2685
+#define wxLayoutAlgorithm_LayoutWindow 2686
+#define wxLayoutAlgorithm_destroy 2687
+#define wxEvent_GetId 2688
+#define wxEvent_GetSkipped 2689
+#define wxEvent_GetTimestamp 2690
+#define wxEvent_IsCommandEvent 2691
+#define wxEvent_ResumePropagation 2692
+#define wxEvent_ShouldPropagate 2693
+#define wxEvent_Skip 2694
+#define wxEvent_StopPropagation 2695
+#define wxCommandEvent_getClientData 2696
+#define wxCommandEvent_GetExtraLong 2697
+#define wxCommandEvent_GetInt 2698
+#define wxCommandEvent_GetSelection 2699
+#define wxCommandEvent_GetString 2700
+#define wxCommandEvent_IsChecked 2701
+#define wxCommandEvent_IsSelection 2702
+#define wxCommandEvent_SetInt 2703
+#define wxCommandEvent_SetString 2704
+#define wxScrollEvent_GetOrientation 2705
+#define wxScrollEvent_GetPosition 2706
+#define wxScrollWinEvent_GetOrientation 2707
+#define wxScrollWinEvent_GetPosition 2708
+#define wxMouseEvent_AltDown 2709
+#define wxMouseEvent_Button 2710
+#define wxMouseEvent_ButtonDClick 2711
+#define wxMouseEvent_ButtonDown 2712
+#define wxMouseEvent_ButtonUp 2713
+#define wxMouseEvent_CmdDown 2714
+#define wxMouseEvent_ControlDown 2715
+#define wxMouseEvent_Dragging 2716
+#define wxMouseEvent_Entering 2717
+#define wxMouseEvent_GetButton 2718
+#define wxMouseEvent_GetPosition 2721
+#define wxMouseEvent_GetLogicalPosition 2722
+#define wxMouseEvent_GetLinesPerAction 2723
+#define wxMouseEvent_GetWheelRotation 2724
+#define wxMouseEvent_GetWheelDelta 2725
+#define wxMouseEvent_GetX 2726
+#define wxMouseEvent_GetY 2727
+#define wxMouseEvent_IsButton 2728
+#define wxMouseEvent_IsPageScroll 2729
+#define wxMouseEvent_Leaving 2730
+#define wxMouseEvent_LeftDClick 2731
+#define wxMouseEvent_LeftDown 2732
+#define wxMouseEvent_LeftIsDown 2733
+#define wxMouseEvent_LeftUp 2734
+#define wxMouseEvent_MetaDown 2735
+#define wxMouseEvent_MiddleDClick 2736
+#define wxMouseEvent_MiddleDown 2737
+#define wxMouseEvent_MiddleIsDown 2738
+#define wxMouseEvent_MiddleUp 2739
+#define wxMouseEvent_Moving 2740
+#define wxMouseEvent_RightDClick 2741
+#define wxMouseEvent_RightDown 2742
+#define wxMouseEvent_RightIsDown 2743
+#define wxMouseEvent_RightUp 2744
+#define wxMouseEvent_ShiftDown 2745
+#define wxSetCursorEvent_GetCursor 2746
+#define wxSetCursorEvent_GetX 2747
+#define wxSetCursorEvent_GetY 2748
+#define wxSetCursorEvent_HasCursor 2749
+#define wxSetCursorEvent_SetCursor 2750
+#define wxKeyEvent_AltDown 2751
+#define wxKeyEvent_CmdDown 2752
+#define wxKeyEvent_ControlDown 2753
+#define wxKeyEvent_GetKeyCode 2754
+#define wxKeyEvent_GetModifiers 2755
+#define wxKeyEvent_GetPosition 2758
+#define wxKeyEvent_GetRawKeyCode 2759
+#define wxKeyEvent_GetRawKeyFlags 2760
+#define wxKeyEvent_GetUnicodeKey 2761
+#define wxKeyEvent_GetX 2762
+#define wxKeyEvent_GetY 2763
+#define wxKeyEvent_HasModifiers 2764
+#define wxKeyEvent_MetaDown 2765
+#define wxKeyEvent_ShiftDown 2766
+#define wxSizeEvent_GetSize 2767
+#define wxMoveEvent_GetPosition 2768
+#define wxEraseEvent_GetDC 2769
+#define wxFocusEvent_GetWindow 2770
+#define wxChildFocusEvent_GetWindow 2771
+#define wxMenuEvent_GetMenu 2772
+#define wxMenuEvent_GetMenuId 2773
+#define wxMenuEvent_IsPopup 2774
+#define wxCloseEvent_CanVeto 2775
+#define wxCloseEvent_GetLoggingOff 2776
+#define wxCloseEvent_SetCanVeto 2777
+#define wxCloseEvent_SetLoggingOff 2778
+#define wxCloseEvent_Veto 2779
+#define wxShowEvent_SetShow 2780
+#define wxShowEvent_GetShow 2781
+#define wxIconizeEvent_Iconized 2782
+#define wxJoystickEvent_ButtonDown 2783
+#define wxJoystickEvent_ButtonIsDown 2784
+#define wxJoystickEvent_ButtonUp 2785
+#define wxJoystickEvent_GetButtonChange 2786
+#define wxJoystickEvent_GetButtonState 2787
+#define wxJoystickEvent_GetJoystick 2788
+#define wxJoystickEvent_GetPosition 2789
+#define wxJoystickEvent_GetZPosition 2790
+#define wxJoystickEvent_IsButton 2791
+#define wxJoystickEvent_IsMove 2792
+#define wxJoystickEvent_IsZMove 2793
+#define wxUpdateUIEvent_CanUpdate 2794
+#define wxUpdateUIEvent_Check 2795
+#define wxUpdateUIEvent_Enable 2796
+#define wxUpdateUIEvent_Show 2797
+#define wxUpdateUIEvent_GetChecked 2798
+#define wxUpdateUIEvent_GetEnabled 2799
+#define wxUpdateUIEvent_GetShown 2800
+#define wxUpdateUIEvent_GetSetChecked 2801
+#define wxUpdateUIEvent_GetSetEnabled 2802
+#define wxUpdateUIEvent_GetSetShown 2803
+#define wxUpdateUIEvent_GetSetText 2804
+#define wxUpdateUIEvent_GetText 2805
+#define wxUpdateUIEvent_GetMode 2806
+#define wxUpdateUIEvent_GetUpdateInterval 2807
+#define wxUpdateUIEvent_ResetUpdateTime 2808
+#define wxUpdateUIEvent_SetMode 2809
+#define wxUpdateUIEvent_SetText 2810
+#define wxUpdateUIEvent_SetUpdateInterval 2811
+#define wxMouseCaptureChangedEvent_GetCapturedWindow 2812
+#define wxPaletteChangedEvent_SetChangedWindow 2813
+#define wxPaletteChangedEvent_GetChangedWindow 2814
+#define wxQueryNewPaletteEvent_SetPaletteRealized 2815
+#define wxQueryNewPaletteEvent_GetPaletteRealized 2816
+#define wxNavigationKeyEvent_GetDirection 2817
+#define wxNavigationKeyEvent_SetDirection 2818
+#define wxNavigationKeyEvent_IsWindowChange 2819
+#define wxNavigationKeyEvent_SetWindowChange 2820
+#define wxNavigationKeyEvent_IsFromTab 2821
+#define wxNavigationKeyEvent_SetFromTab 2822
+#define wxNavigationKeyEvent_GetCurrentFocus 2823
+#define wxNavigationKeyEvent_SetCurrentFocus 2824
+#define wxHelpEvent_GetOrigin 2825
+#define wxHelpEvent_GetPosition 2826
+#define wxHelpEvent_SetOrigin 2827
+#define wxHelpEvent_SetPosition 2828
+#define wxContextMenuEvent_GetPosition 2829
+#define wxContextMenuEvent_SetPosition 2830
+#define wxIdleEvent_CanSend 2831
+#define wxIdleEvent_GetMode 2832
+#define wxIdleEvent_RequestMore 2833
+#define wxIdleEvent_MoreRequested 2834
+#define wxIdleEvent_SetMode 2835
+#define wxGridEvent_AltDown 2836
+#define wxGridEvent_ControlDown 2837
+#define wxGridEvent_GetCol 2838
+#define wxGridEvent_GetPosition 2839
+#define wxGridEvent_GetRow 2840
+#define wxGridEvent_MetaDown 2841
+#define wxGridEvent_Selecting 2842
+#define wxGridEvent_ShiftDown 2843
+#define wxNotifyEvent_Allow 2844
+#define wxNotifyEvent_IsAllowed 2845
+#define wxNotifyEvent_Veto 2846
+#define wxSashEvent_GetEdge 2847
+#define wxSashEvent_GetDragRect 2848
+#define wxSashEvent_GetDragStatus 2849
+#define wxListEvent_GetCacheFrom 2850
+#define wxListEvent_GetCacheTo 2851
+#define wxListEvent_GetKeyCode 2852
+#define wxListEvent_GetIndex 2853
+#define wxListEvent_GetColumn 2854
+#define wxListEvent_GetPoint 2855
+#define wxListEvent_GetLabel 2856
+#define wxListEvent_GetText 2857
+#define wxListEvent_GetImage 2858
+#define wxListEvent_GetData 2859
+#define wxListEvent_GetMask 2860
+#define wxListEvent_GetItem 2861
+#define wxListEvent_IsEditCancelled 2862
+#define wxDateEvent_GetDate 2863
+#define wxCalendarEvent_GetWeekDay 2864
+#define wxFileDirPickerEvent_GetPath 2865
+#define wxColourPickerEvent_GetColour 2866
+#define wxFontPickerEvent_GetFont 2867
+#define wxStyledTextEvent_GetPosition 2868
+#define wxStyledTextEvent_GetKey 2869
+#define wxStyledTextEvent_GetModifiers 2870
+#define wxStyledTextEvent_GetModificationType 2871
+#define wxStyledTextEvent_GetText 2872
+#define wxStyledTextEvent_GetLength 2873
+#define wxStyledTextEvent_GetLinesAdded 2874
+#define wxStyledTextEvent_GetLine 2875
+#define wxStyledTextEvent_GetFoldLevelNow 2876
+#define wxStyledTextEvent_GetFoldLevelPrev 2877
+#define wxStyledTextEvent_GetMargin 2878
+#define wxStyledTextEvent_GetMessage 2879
+#define wxStyledTextEvent_GetWParam 2880
+#define wxStyledTextEvent_GetLParam 2881
+#define wxStyledTextEvent_GetListType 2882
+#define wxStyledTextEvent_GetX 2883
+#define wxStyledTextEvent_GetY 2884
+#define wxStyledTextEvent_GetDragText 2885
+#define wxStyledTextEvent_GetDragAllowMove 2886
+#define wxStyledTextEvent_GetDragResult 2887
+#define wxStyledTextEvent_GetShift 2888
+#define wxStyledTextEvent_GetControl 2889
+#define wxStyledTextEvent_GetAlt 2890
+#define utils_wxGetKeyState 2891
+#define utils_wxGetMousePosition 2892
+#define utils_wxGetMouseState 2893
+#define utils_wxSetDetectableAutoRepeat 2894
+#define utils_wxBell 2895
+#define utils_wxFindMenuItemId 2896
+#define utils_wxGenericFindWindowAtPoint 2897
+#define utils_wxFindWindowAtPoint 2898
+#define utils_wxBeginBusyCursor 2899
+#define utils_wxEndBusyCursor 2900
+#define utils_wxIsBusy 2901
+#define utils_wxShutdown 2902
+#define utils_wxShell 2903
+#define utils_wxLaunchDefaultBrowser 2904
+#define utils_wxGetEmailAddress 2905
+#define utils_wxGetUserId 2906
+#define utils_wxGetHomeDir 2907
+#define utils_wxNewId 2908
+#define utils_wxRegisterId 2909
+#define utils_wxGetCurrentId 2910
+#define utils_wxGetOsDescription 2911
+#define utils_wxIsPlatformLittleEndian 2912
+#define utils_wxIsPlatform64Bit 2913
+#define wxPrintout_new 2914
+#define wxPrintout_destruct 2915
+#define wxPrintout_GetDC 2916
+#define wxPrintout_GetPageSizeMM 2917
+#define wxPrintout_GetPageSizePixels 2918
+#define wxPrintout_GetPaperRectPixels 2919
+#define wxPrintout_GetPPIPrinter 2920
+#define wxPrintout_GetPPIScreen 2921
+#define wxPrintout_GetTitle 2922
+#define wxPrintout_IsPreview 2923
+#define wxPrintout_FitThisSizeToPaper 2924
+#define wxPrintout_FitThisSizeToPage 2925
+#define wxPrintout_FitThisSizeToPageMargins 2926
+#define wxPrintout_MapScreenSizeToPaper 2927
+#define wxPrintout_MapScreenSizeToPage 2928
+#define wxPrintout_MapScreenSizeToPageMargins 2929
+#define wxPrintout_MapScreenSizeToDevice 2930
+#define wxPrintout_GetLogicalPaperRect 2931
+#define wxPrintout_GetLogicalPageRect 2932
+#define wxPrintout_GetLogicalPageMarginsRect 2933
+#define wxPrintout_SetLogicalOrigin 2934
+#define wxPrintout_OffsetLogicalOrigin 2935
+#define wxStyledTextCtrl_new_2 2936
+#define wxStyledTextCtrl_new_0 2937
+#define wxStyledTextCtrl_destruct 2938
+#define wxStyledTextCtrl_Create 2939
+#define wxStyledTextCtrl_AddText 2940
+#define wxStyledTextCtrl_AddStyledText 2941
+#define wxStyledTextCtrl_InsertText 2942
+#define wxStyledTextCtrl_ClearAll 2943
+#define wxStyledTextCtrl_ClearDocumentStyle 2944
+#define wxStyledTextCtrl_GetLength 2945
+#define wxStyledTextCtrl_GetCharAt 2946
+#define wxStyledTextCtrl_GetCurrentPos 2947
+#define wxStyledTextCtrl_GetAnchor 2948
+#define wxStyledTextCtrl_GetStyleAt 2949
+#define wxStyledTextCtrl_Redo 2950
+#define wxStyledTextCtrl_SetUndoCollection 2951
+#define wxStyledTextCtrl_SelectAll 2952
+#define wxStyledTextCtrl_SetSavePoint 2953
+#define wxStyledTextCtrl_GetStyledText 2954
+#define wxStyledTextCtrl_CanRedo 2955
+#define wxStyledTextCtrl_MarkerLineFromHandle 2956
+#define wxStyledTextCtrl_MarkerDeleteHandle 2957
+#define wxStyledTextCtrl_GetUndoCollection 2958
+#define wxStyledTextCtrl_GetViewWhiteSpace 2959
+#define wxStyledTextCtrl_SetViewWhiteSpace 2960
+#define wxStyledTextCtrl_PositionFromPoint 2961
+#define wxStyledTextCtrl_PositionFromPointClose 2962
+#define wxStyledTextCtrl_GotoLine 2963
+#define wxStyledTextCtrl_GotoPos 2964
+#define wxStyledTextCtrl_SetAnchor 2965
+#define wxStyledTextCtrl_GetCurLine 2966
+#define wxStyledTextCtrl_GetEndStyled 2967
+#define wxStyledTextCtrl_ConvertEOLs 2968
+#define wxStyledTextCtrl_GetEOLMode 2969
+#define wxStyledTextCtrl_SetEOLMode 2970
+#define wxStyledTextCtrl_StartStyling 2971
+#define wxStyledTextCtrl_SetStyling 2972
+#define wxStyledTextCtrl_GetBufferedDraw 2973
+#define wxStyledTextCtrl_SetBufferedDraw 2974
+#define wxStyledTextCtrl_SetTabWidth 2975
+#define wxStyledTextCtrl_GetTabWidth 2976
+#define wxStyledTextCtrl_SetCodePage 2977
+#define wxStyledTextCtrl_MarkerDefine 2978
+#define wxStyledTextCtrl_MarkerSetForeground 2979
+#define wxStyledTextCtrl_MarkerSetBackground 2980
+#define wxStyledTextCtrl_MarkerAdd 2981
+#define wxStyledTextCtrl_MarkerDelete 2982
+#define wxStyledTextCtrl_MarkerDeleteAll 2983
+#define wxStyledTextCtrl_MarkerGet 2984
+#define wxStyledTextCtrl_MarkerNext 2985
+#define wxStyledTextCtrl_MarkerPrevious 2986
+#define wxStyledTextCtrl_MarkerDefineBitmap 2987
+#define wxStyledTextCtrl_MarkerAddSet 2988
+#define wxStyledTextCtrl_MarkerSetAlpha 2989
+#define wxStyledTextCtrl_SetMarginType 2990
+#define wxStyledTextCtrl_GetMarginType 2991
+#define wxStyledTextCtrl_SetMarginWidth 2992
+#define wxStyledTextCtrl_GetMarginWidth 2993
+#define wxStyledTextCtrl_SetMarginMask 2994
+#define wxStyledTextCtrl_GetMarginMask 2995
+#define wxStyledTextCtrl_SetMarginSensitive 2996
+#define wxStyledTextCtrl_GetMarginSensitive 2997
+#define wxStyledTextCtrl_StyleClearAll 2998
+#define wxStyledTextCtrl_StyleSetForeground 2999
+#define wxStyledTextCtrl_StyleSetBackground 3000
+#define wxStyledTextCtrl_StyleSetBold 3001
+#define wxStyledTextCtrl_StyleSetItalic 3002
+#define wxStyledTextCtrl_StyleSetSize 3003
+#define wxStyledTextCtrl_StyleSetFaceName 3004
+#define wxStyledTextCtrl_StyleSetEOLFilled 3005
+#define wxStyledTextCtrl_StyleResetDefault 3006
+#define wxStyledTextCtrl_StyleSetUnderline 3007
+#define wxStyledTextCtrl_StyleSetCase 3008
+#define wxStyledTextCtrl_StyleSetHotSpot 3009
+#define wxStyledTextCtrl_SetSelForeground 3010
+#define wxStyledTextCtrl_SetSelBackground 3011
+#define wxStyledTextCtrl_GetSelAlpha 3012
+#define wxStyledTextCtrl_SetSelAlpha 3013
+#define wxStyledTextCtrl_SetCaretForeground 3014
+#define wxStyledTextCtrl_CmdKeyAssign 3015
+#define wxStyledTextCtrl_CmdKeyClear 3016
+#define wxStyledTextCtrl_CmdKeyClearAll 3017
+#define wxStyledTextCtrl_SetStyleBytes 3018
+#define wxStyledTextCtrl_StyleSetVisible 3019
+#define wxStyledTextCtrl_GetCaretPeriod 3020
+#define wxStyledTextCtrl_SetCaretPeriod 3021
+#define wxStyledTextCtrl_SetWordChars 3022
+#define wxStyledTextCtrl_BeginUndoAction 3023
+#define wxStyledTextCtrl_EndUndoAction 3024
+#define wxStyledTextCtrl_IndicatorSetStyle 3025
+#define wxStyledTextCtrl_IndicatorGetStyle 3026
+#define wxStyledTextCtrl_IndicatorSetForeground 3027
+#define wxStyledTextCtrl_IndicatorGetForeground 3028
+#define wxStyledTextCtrl_SetWhitespaceForeground 3029
+#define wxStyledTextCtrl_SetWhitespaceBackground 3030
+#define wxStyledTextCtrl_GetStyleBits 3031
+#define wxStyledTextCtrl_SetLineState 3032
+#define wxStyledTextCtrl_GetLineState 3033
+#define wxStyledTextCtrl_GetMaxLineState 3034
+#define wxStyledTextCtrl_GetCaretLineVisible 3035
+#define wxStyledTextCtrl_SetCaretLineVisible 3036
+#define wxStyledTextCtrl_GetCaretLineBackground 3037
+#define wxStyledTextCtrl_SetCaretLineBackground 3038
+#define wxStyledTextCtrl_AutoCompShow 3039
+#define wxStyledTextCtrl_AutoCompCancel 3040
+#define wxStyledTextCtrl_AutoCompActive 3041
+#define wxStyledTextCtrl_AutoCompPosStart 3042
+#define wxStyledTextCtrl_AutoCompComplete 3043
+#define wxStyledTextCtrl_AutoCompStops 3044
+#define wxStyledTextCtrl_AutoCompSetSeparator 3045
+#define wxStyledTextCtrl_AutoCompGetSeparator 3046
+#define wxStyledTextCtrl_AutoCompSelect 3047
+#define wxStyledTextCtrl_AutoCompSetCancelAtStart 3048
+#define wxStyledTextCtrl_AutoCompGetCancelAtStart 3049
+#define wxStyledTextCtrl_AutoCompSetFillUps 3050
+#define wxStyledTextCtrl_AutoCompSetChooseSingle 3051
+#define wxStyledTextCtrl_AutoCompGetChooseSingle 3052
+#define wxStyledTextCtrl_AutoCompSetIgnoreCase 3053
+#define wxStyledTextCtrl_AutoCompGetIgnoreCase 3054
+#define wxStyledTextCtrl_UserListShow 3055
+#define wxStyledTextCtrl_AutoCompSetAutoHide 3056
+#define wxStyledTextCtrl_AutoCompGetAutoHide 3057
+#define wxStyledTextCtrl_AutoCompSetDropRestOfWord 3058
+#define wxStyledTextCtrl_AutoCompGetDropRestOfWord 3059
+#define wxStyledTextCtrl_RegisterImage 3060
+#define wxStyledTextCtrl_ClearRegisteredImages 3061
+#define wxStyledTextCtrl_AutoCompGetTypeSeparator 3062
+#define wxStyledTextCtrl_AutoCompSetTypeSeparator 3063
+#define wxStyledTextCtrl_AutoCompSetMaxWidth 3064
+#define wxStyledTextCtrl_AutoCompGetMaxWidth 3065
+#define wxStyledTextCtrl_AutoCompSetMaxHeight 3066
+#define wxStyledTextCtrl_AutoCompGetMaxHeight 3067
+#define wxStyledTextCtrl_SetIndent 3068
+#define wxStyledTextCtrl_GetIndent 3069
+#define wxStyledTextCtrl_SetUseTabs 3070
+#define wxStyledTextCtrl_GetUseTabs 3071
+#define wxStyledTextCtrl_SetLineIndentation 3072
+#define wxStyledTextCtrl_GetLineIndentation 3073
+#define wxStyledTextCtrl_GetLineIndentPosition 3074
+#define wxStyledTextCtrl_GetColumn 3075
+#define wxStyledTextCtrl_SetUseHorizontalScrollBar 3076
+#define wxStyledTextCtrl_GetUseHorizontalScrollBar 3077
+#define wxStyledTextCtrl_SetIndentationGuides 3078
+#define wxStyledTextCtrl_GetIndentationGuides 3079
+#define wxStyledTextCtrl_SetHighlightGuide 3080
+#define wxStyledTextCtrl_GetHighlightGuide 3081
+#define wxStyledTextCtrl_GetLineEndPosition 3082
+#define wxStyledTextCtrl_GetCodePage 3083
+#define wxStyledTextCtrl_GetCaretForeground 3084
+#define wxStyledTextCtrl_GetReadOnly 3085
+#define wxStyledTextCtrl_SetCurrentPos 3086
+#define wxStyledTextCtrl_SetSelectionStart 3087
+#define wxStyledTextCtrl_GetSelectionStart 3088
+#define wxStyledTextCtrl_SetSelectionEnd 3089
+#define wxStyledTextCtrl_GetSelectionEnd 3090
+#define wxStyledTextCtrl_SetPrintMagnification 3091
+#define wxStyledTextCtrl_GetPrintMagnification 3092
+#define wxStyledTextCtrl_SetPrintColourMode 3093
+#define wxStyledTextCtrl_GetPrintColourMode 3094
+#define wxStyledTextCtrl_FindText 3095
+#define wxStyledTextCtrl_FormatRange 3096
+#define wxStyledTextCtrl_GetFirstVisibleLine 3097
+#define wxStyledTextCtrl_GetLine 3098
+#define wxStyledTextCtrl_GetLineCount 3099
+#define wxStyledTextCtrl_SetMarginLeft 3100
+#define wxStyledTextCtrl_GetMarginLeft 3101
+#define wxStyledTextCtrl_SetMarginRight 3102
+#define wxStyledTextCtrl_GetMarginRight 3103
+#define wxStyledTextCtrl_GetModify 3104
+#define wxStyledTextCtrl_SetSelection 3105
+#define wxStyledTextCtrl_GetSelectedText 3106
+#define wxStyledTextCtrl_GetTextRange 3107
+#define wxStyledTextCtrl_HideSelection 3108
+#define wxStyledTextCtrl_LineFromPosition 3109
+#define wxStyledTextCtrl_PositionFromLine 3110
+#define wxStyledTextCtrl_LineScroll 3111
+#define wxStyledTextCtrl_EnsureCaretVisible 3112
+#define wxStyledTextCtrl_ReplaceSelection 3113
+#define wxStyledTextCtrl_SetReadOnly 3114
+#define wxStyledTextCtrl_CanPaste 3115
+#define wxStyledTextCtrl_CanUndo 3116
+#define wxStyledTextCtrl_EmptyUndoBuffer 3117
+#define wxStyledTextCtrl_Undo 3118
+#define wxStyledTextCtrl_Cut 3119
+#define wxStyledTextCtrl_Copy 3120
+#define wxStyledTextCtrl_Paste 3121
+#define wxStyledTextCtrl_Clear 3122
+#define wxStyledTextCtrl_SetText 3123
+#define wxStyledTextCtrl_GetText 3124
+#define wxStyledTextCtrl_GetTextLength 3125
+#define wxStyledTextCtrl_GetOvertype 3126
+#define wxStyledTextCtrl_SetCaretWidth 3127
+#define wxStyledTextCtrl_GetCaretWidth 3128
+#define wxStyledTextCtrl_SetTargetStart 3129
+#define wxStyledTextCtrl_GetTargetStart 3130
+#define wxStyledTextCtrl_SetTargetEnd 3131
+#define wxStyledTextCtrl_GetTargetEnd 3132
+#define wxStyledTextCtrl_ReplaceTarget 3133
+#define wxStyledTextCtrl_SearchInTarget 3134
+#define wxStyledTextCtrl_SetSearchFlags 3135
+#define wxStyledTextCtrl_GetSearchFlags 3136
+#define wxStyledTextCtrl_CallTipShow 3137
+#define wxStyledTextCtrl_CallTipCancel 3138
+#define wxStyledTextCtrl_CallTipActive 3139
+#define wxStyledTextCtrl_CallTipPosAtStart 3140
+#define wxStyledTextCtrl_CallTipSetHighlight 3141
+#define wxStyledTextCtrl_CallTipSetBackground 3142
+#define wxStyledTextCtrl_CallTipSetForeground 3143
+#define wxStyledTextCtrl_CallTipSetForegroundHighlight 3144
+#define wxStyledTextCtrl_CallTipUseStyle 3145
+#define wxStyledTextCtrl_VisibleFromDocLine 3146
+#define wxStyledTextCtrl_DocLineFromVisible 3147
+#define wxStyledTextCtrl_WrapCount 3148
+#define wxStyledTextCtrl_SetFoldLevel 3149
+#define wxStyledTextCtrl_GetFoldLevel 3150
+#define wxStyledTextCtrl_GetLastChild 3151
+#define wxStyledTextCtrl_GetFoldParent 3152
+#define wxStyledTextCtrl_ShowLines 3153
+#define wxStyledTextCtrl_HideLines 3154
+#define wxStyledTextCtrl_GetLineVisible 3155
+#define wxStyledTextCtrl_SetFoldExpanded 3156
+#define wxStyledTextCtrl_GetFoldExpanded 3157
+#define wxStyledTextCtrl_ToggleFold 3158
+#define wxStyledTextCtrl_EnsureVisible 3159
+#define wxStyledTextCtrl_SetFoldFlags 3160
+#define wxStyledTextCtrl_EnsureVisibleEnforcePolicy 3161
+#define wxStyledTextCtrl_SetTabIndents 3162
+#define wxStyledTextCtrl_GetTabIndents 3163
+#define wxStyledTextCtrl_SetBackSpaceUnIndents 3164
+#define wxStyledTextCtrl_GetBackSpaceUnIndents 3165
+#define wxStyledTextCtrl_SetMouseDwellTime 3166
+#define wxStyledTextCtrl_GetMouseDwellTime 3167
+#define wxStyledTextCtrl_WordStartPosition 3168
+#define wxStyledTextCtrl_WordEndPosition 3169
+#define wxStyledTextCtrl_SetWrapMode 3170
+#define wxStyledTextCtrl_GetWrapMode 3171
+#define wxStyledTextCtrl_SetWrapVisualFlags 3172
+#define wxStyledTextCtrl_GetWrapVisualFlags 3173
+#define wxStyledTextCtrl_SetWrapVisualFlagsLocation 3174
+#define wxStyledTextCtrl_GetWrapVisualFlagsLocation 3175
+#define wxStyledTextCtrl_SetWrapStartIndent 3176
+#define wxStyledTextCtrl_GetWrapStartIndent 3177
+#define wxStyledTextCtrl_SetLayoutCache 3178
+#define wxStyledTextCtrl_GetLayoutCache 3179
+#define wxStyledTextCtrl_SetScrollWidth 3180
+#define wxStyledTextCtrl_GetScrollWidth 3181
+#define wxStyledTextCtrl_TextWidth 3182
+#define wxStyledTextCtrl_GetEndAtLastLine 3183
+#define wxStyledTextCtrl_TextHeight 3184
+#define wxStyledTextCtrl_SetUseVerticalScrollBar 3185
+#define wxStyledTextCtrl_GetUseVerticalScrollBar 3186
+#define wxStyledTextCtrl_AppendText 3187
+#define wxStyledTextCtrl_GetTwoPhaseDraw 3188
+#define wxStyledTextCtrl_SetTwoPhaseDraw 3189
+#define wxStyledTextCtrl_TargetFromSelection 3190
+#define wxStyledTextCtrl_LinesJoin 3191
+#define wxStyledTextCtrl_LinesSplit 3192
+#define wxStyledTextCtrl_SetFoldMarginColour 3193
+#define wxStyledTextCtrl_SetFoldMarginHiColour 3194
+#define wxStyledTextCtrl_LineDown 3195
+#define wxStyledTextCtrl_LineDownExtend 3196
+#define wxStyledTextCtrl_LineUp 3197
+#define wxStyledTextCtrl_LineUpExtend 3198
+#define wxStyledTextCtrl_CharLeft 3199
+#define wxStyledTextCtrl_CharLeftExtend 3200
+#define wxStyledTextCtrl_CharRight 3201
+#define wxStyledTextCtrl_CharRightExtend 3202
+#define wxStyledTextCtrl_WordLeft 3203
+#define wxStyledTextCtrl_WordLeftExtend 3204
+#define wxStyledTextCtrl_WordRight 3205
+#define wxStyledTextCtrl_WordRightExtend 3206
+#define wxStyledTextCtrl_Home 3207
+#define wxStyledTextCtrl_HomeExtend 3208
+#define wxStyledTextCtrl_LineEnd 3209
+#define wxStyledTextCtrl_LineEndExtend 3210
+#define wxStyledTextCtrl_DocumentStart 3211
+#define wxStyledTextCtrl_DocumentStartExtend 3212
+#define wxStyledTextCtrl_DocumentEnd 3213
+#define wxStyledTextCtrl_DocumentEndExtend 3214
+#define wxStyledTextCtrl_PageUp 3215
+#define wxStyledTextCtrl_PageUpExtend 3216
+#define wxStyledTextCtrl_PageDown 3217
+#define wxStyledTextCtrl_PageDownExtend 3218
+#define wxStyledTextCtrl_EditToggleOvertype 3219
+#define wxStyledTextCtrl_Cancel 3220
+#define wxStyledTextCtrl_DeleteBack 3221
+#define wxStyledTextCtrl_Tab 3222
+#define wxStyledTextCtrl_BackTab 3223
+#define wxStyledTextCtrl_NewLine 3224
+#define wxStyledTextCtrl_FormFeed 3225
+#define wxStyledTextCtrl_VCHome 3226
+#define wxStyledTextCtrl_VCHomeExtend 3227
+#define wxStyledTextCtrl_ZoomIn 3228
+#define wxStyledTextCtrl_ZoomOut 3229
+#define wxStyledTextCtrl_DelWordLeft 3230
+#define wxStyledTextCtrl_DelWordRight 3231
+#define wxStyledTextCtrl_LineCut 3232
+#define wxStyledTextCtrl_LineDelete 3233
+#define wxStyledTextCtrl_LineTranspose 3234
+#define wxStyledTextCtrl_LineDuplicate 3235
+#define wxStyledTextCtrl_LowerCase 3236
+#define wxStyledTextCtrl_UpperCase 3237
+#define wxStyledTextCtrl_LineScrollDown 3238
+#define wxStyledTextCtrl_LineScrollUp 3239
+#define wxStyledTextCtrl_DeleteBackNotLine 3240
+#define wxStyledTextCtrl_HomeDisplay 3241
+#define wxStyledTextCtrl_HomeDisplayExtend 3242
+#define wxStyledTextCtrl_LineEndDisplay 3243
+#define wxStyledTextCtrl_LineEndDisplayExtend 3244
+#define wxStyledTextCtrl_HomeWrapExtend 3245
+#define wxStyledTextCtrl_LineEndWrap 3246
+#define wxStyledTextCtrl_LineEndWrapExtend 3247
+#define wxStyledTextCtrl_VCHomeWrap 3248
+#define wxStyledTextCtrl_VCHomeWrapExtend 3249
+#define wxStyledTextCtrl_LineCopy 3250
+#define wxStyledTextCtrl_MoveCaretInsideView 3251
+#define wxStyledTextCtrl_LineLength 3252
+#define wxStyledTextCtrl_BraceHighlight 3253
+#define wxStyledTextCtrl_BraceBadLight 3254
+#define wxStyledTextCtrl_BraceMatch 3255
+#define wxStyledTextCtrl_GetViewEOL 3256
+#define wxStyledTextCtrl_SetViewEOL 3257
+#define wxStyledTextCtrl_SetModEventMask 3258
+#define wxStyledTextCtrl_GetEdgeColumn 3259
+#define wxStyledTextCtrl_SetEdgeColumn 3260
+#define wxStyledTextCtrl_GetEdgeMode 3261
+#define wxStyledTextCtrl_GetEdgeColour 3262
+#define wxStyledTextCtrl_SetEdgeColour 3263
+#define wxStyledTextCtrl_SearchAnchor 3264
+#define wxStyledTextCtrl_SearchNext 3265
+#define wxStyledTextCtrl_SearchPrev 3266
+#define wxStyledTextCtrl_LinesOnScreen 3267
+#define wxStyledTextCtrl_UsePopUp 3268
+#define wxStyledTextCtrl_SelectionIsRectangle 3269
+#define wxStyledTextCtrl_SetZoom 3270
+#define wxStyledTextCtrl_GetZoom 3271
+#define wxStyledTextCtrl_GetModEventMask 3272
+#define wxStyledTextCtrl_SetSTCFocus 3273
+#define wxStyledTextCtrl_GetSTCFocus 3274
+#define wxStyledTextCtrl_SetStatus 3275
+#define wxStyledTextCtrl_GetStatus 3276
+#define wxStyledTextCtrl_SetMouseDownCaptures 3277
+#define wxStyledTextCtrl_GetMouseDownCaptures 3278
+#define wxStyledTextCtrl_SetSTCCursor 3279
+#define wxStyledTextCtrl_GetSTCCursor 3280
+#define wxStyledTextCtrl_SetControlCharSymbol 3281
+#define wxStyledTextCtrl_GetControlCharSymbol 3282
+#define wxStyledTextCtrl_WordPartLeft 3283
+#define wxStyledTextCtrl_WordPartLeftExtend 3284
+#define wxStyledTextCtrl_WordPartRight 3285
+#define wxStyledTextCtrl_WordPartRightExtend 3286
+#define wxStyledTextCtrl_SetVisiblePolicy 3287
+#define wxStyledTextCtrl_DelLineLeft 3288
+#define wxStyledTextCtrl_DelLineRight 3289
+#define wxStyledTextCtrl_GetXOffset 3290
+#define wxStyledTextCtrl_ChooseCaretX 3291
+#define wxStyledTextCtrl_SetXCaretPolicy 3292
+#define wxStyledTextCtrl_SetYCaretPolicy 3293
+#define wxStyledTextCtrl_GetPrintWrapMode 3294
+#define wxStyledTextCtrl_SetHotspotActiveForeground 3295
+#define wxStyledTextCtrl_SetHotspotActiveBackground 3296
+#define wxStyledTextCtrl_SetHotspotActiveUnderline 3297
+#define wxStyledTextCtrl_SetHotspotSingleLine 3298
+#define wxStyledTextCtrl_ParaDownExtend 3299
+#define wxStyledTextCtrl_ParaUp 3300
+#define wxStyledTextCtrl_ParaUpExtend 3301
+#define wxStyledTextCtrl_PositionBefore 3302
+#define wxStyledTextCtrl_PositionAfter 3303
+#define wxStyledTextCtrl_CopyRange 3304
+#define wxStyledTextCtrl_CopyText 3305
+#define wxStyledTextCtrl_SetSelectionMode 3306
+#define wxStyledTextCtrl_GetSelectionMode 3307
+#define wxStyledTextCtrl_LineDownRectExtend 3308
+#define wxStyledTextCtrl_LineUpRectExtend 3309
+#define wxStyledTextCtrl_CharLeftRectExtend 3310
+#define wxStyledTextCtrl_CharRightRectExtend 3311
+#define wxStyledTextCtrl_HomeRectExtend 3312
+#define wxStyledTextCtrl_VCHomeRectExtend 3313
+#define wxStyledTextCtrl_LineEndRectExtend 3314
+#define wxStyledTextCtrl_PageUpRectExtend 3315
+#define wxStyledTextCtrl_PageDownRectExtend 3316
+#define wxStyledTextCtrl_StutteredPageUp 3317
+#define wxStyledTextCtrl_StutteredPageUpExtend 3318
+#define wxStyledTextCtrl_StutteredPageDown 3319
+#define wxStyledTextCtrl_StutteredPageDownExtend 3320
+#define wxStyledTextCtrl_WordLeftEnd 3321
+#define wxStyledTextCtrl_WordLeftEndExtend 3322
+#define wxStyledTextCtrl_WordRightEnd 3323
+#define wxStyledTextCtrl_WordRightEndExtend 3324
+#define wxStyledTextCtrl_SetWhitespaceChars 3325
+#define wxStyledTextCtrl_SetCharsDefault 3326
+#define wxStyledTextCtrl_AutoCompGetCurrent 3327
+#define wxStyledTextCtrl_Allocate 3328
+#define wxStyledTextCtrl_FindColumn 3329
+#define wxStyledTextCtrl_GetCaretSticky 3330
+#define wxStyledTextCtrl_SetCaretSticky 3331
+#define wxStyledTextCtrl_ToggleCaretSticky 3332
+#define wxStyledTextCtrl_SetPasteConvertEndings 3333
+#define wxStyledTextCtrl_GetPasteConvertEndings 3334
+#define wxStyledTextCtrl_SelectionDuplicate 3335
+#define wxStyledTextCtrl_SetCaretLineBackAlpha 3336
+#define wxStyledTextCtrl_GetCaretLineBackAlpha 3337
+#define wxStyledTextCtrl_StartRecord 3338
+#define wxStyledTextCtrl_StopRecord 3339
+#define wxStyledTextCtrl_SetLexer 3340
+#define wxStyledTextCtrl_GetLexer 3341
+#define wxStyledTextCtrl_Colourise 3342
+#define wxStyledTextCtrl_SetProperty 3343
+#define wxStyledTextCtrl_SetKeyWords 3344
+#define wxStyledTextCtrl_SetLexerLanguage 3345
+#define wxStyledTextCtrl_GetProperty 3346
+#define wxStyledTextCtrl_GetStyleBitsNeeded 3347
+#define wxStyledTextCtrl_GetCurrentLine 3348
+#define wxStyledTextCtrl_StyleSetSpec 3349
+#define wxStyledTextCtrl_StyleSetFont 3350
+#define wxStyledTextCtrl_StyleSetFontAttr 3351
+#define wxStyledTextCtrl_StyleSetCharacterSet 3352
+#define wxStyledTextCtrl_StyleSetFontEncoding 3353
+#define wxStyledTextCtrl_CmdKeyExecute 3354
+#define wxStyledTextCtrl_SetMargins 3355
+#define wxStyledTextCtrl_GetSelection 3356
+#define wxStyledTextCtrl_PointFromPosition 3357
+#define wxStyledTextCtrl_ScrollToLine 3358
+#define wxStyledTextCtrl_ScrollToColumn 3359
+#define wxStyledTextCtrl_SendMsg 3360
+#define wxStyledTextCtrl_SetVScrollBar 3361
+#define wxStyledTextCtrl_SetHScrollBar 3362
+#define wxStyledTextCtrl_GetLastKeydownProcessed 3363
+#define wxStyledTextCtrl_SetLastKeydownProcessed 3364
+#define wxStyledTextCtrl_SaveFile 3365
+#define wxStyledTextCtrl_LoadFile 3366
+#define wxStyledTextCtrl_DoDragOver 3367
+#define wxStyledTextCtrl_DoDropText 3368
+#define wxStyledTextCtrl_GetUseAntiAliasing 3369
+#define wxStyledTextCtrl_AddTextRaw 3370
+#define wxStyledTextCtrl_InsertTextRaw 3371
+#define wxStyledTextCtrl_GetCurLineRaw 3372
+#define wxStyledTextCtrl_GetLineRaw 3373
+#define wxStyledTextCtrl_GetSelectedTextRaw 3374
+#define wxStyledTextCtrl_GetTextRangeRaw 3375
+#define wxStyledTextCtrl_SetTextRaw 3376
+#define wxStyledTextCtrl_GetTextRaw 3377
+#define wxStyledTextCtrl_AppendTextRaw 3378
+#define wxArtProvider_GetBitmap 3379
+#define wxArtProvider_GetIcon 3380
+#define wxTreeEvent_GetKeyCode 3381
+#define wxTreeEvent_GetItem 3382
+#define wxTreeEvent_GetKeyEvent 3383
+#define wxTreeEvent_GetLabel 3384
+#define wxTreeEvent_GetOldItem 3385
+#define wxTreeEvent_GetPoint 3386
+#define wxTreeEvent_IsEditCancelled 3387
+#define wxTreeEvent_SetToolTip 3388
+#define wxNotebookEvent_GetOldSelection 3389
+#define wxNotebookEvent_GetSelection 3390
+#define wxNotebookEvent_SetOldSelection 3391
+#define wxNotebookEvent_SetSelection 3392
+#define wxFileDataObject_new 3393
+#define wxFileDataObject_AddFile 3394
+#define wxFileDataObject_GetFilenames 3395
+#define wxFileDataObject_destroy 3396
+#define wxTextDataObject_new 3397
+#define wxTextDataObject_GetTextLength 3398
+#define wxTextDataObject_GetText 3399
+#define wxTextDataObject_SetText 3400
+#define wxTextDataObject_destroy 3401
+#define wxBitmapDataObject_new_1_1 3402
+#define wxBitmapDataObject_new_1_0 3403
+#define wxBitmapDataObject_GetBitmap 3404
+#define wxBitmapDataObject_SetBitmap 3405
+#define wxBitmapDataObject_destroy 3406
+#define wxClipboard_new 3408
+#define wxClipboard_destruct 3409
+#define wxClipboard_AddData 3410
+#define wxClipboard_Clear 3411
+#define wxClipboard_Close 3412
+#define wxClipboard_Flush 3413
+#define wxClipboard_GetData 3414
+#define wxClipboard_IsOpened 3415
+#define wxClipboard_Open 3416
+#define wxClipboard_SetData 3417
+#define wxClipboard_UsePrimarySelection 3419
+#define wxClipboard_IsSupported 3420
+#define wxClipboard_Get 3421
+#define wxSpinEvent_GetPosition 3422
+#define wxSpinEvent_SetPosition 3423
+#define wxSplitterWindow_new_0 3424
+#define wxSplitterWindow_new_2 3425
+#define wxSplitterWindow_destruct 3426
+#define wxSplitterWindow_Create 3427
+#define wxSplitterWindow_GetMinimumPaneSize 3428
+#define wxSplitterWindow_GetSashGravity 3429
+#define wxSplitterWindow_GetSashPosition 3430
+#define wxSplitterWindow_GetSplitMode 3431
+#define wxSplitterWindow_GetWindow1 3432
+#define wxSplitterWindow_GetWindow2 3433
+#define wxSplitterWindow_Initialize 3434
+#define wxSplitterWindow_IsSplit 3435
+#define wxSplitterWindow_ReplaceWindow 3436
+#define wxSplitterWindow_SetSashGravity 3437
+#define wxSplitterWindow_SetSashPosition 3438
+#define wxSplitterWindow_SetSashSize 3439
+#define wxSplitterWindow_SetMinimumPaneSize 3440
+#define wxSplitterWindow_SetSplitMode 3441
+#define wxSplitterWindow_SplitHorizontally 3442
+#define wxSplitterWindow_SplitVertically 3443
+#define wxSplitterWindow_Unsplit 3444
+#define wxSplitterWindow_UpdateSize 3445
+#define wxSplitterEvent_GetSashPosition 3446
+#define wxSplitterEvent_GetX 3447
+#define wxSplitterEvent_GetY 3448
+#define wxSplitterEvent_GetWindowBeingRemoved 3449
+#define wxSplitterEvent_SetSashPosition 3450
+#define wxHtmlWindow_new_0 3451
+#define wxHtmlWindow_new_2 3452
+#define wxHtmlWindow_AppendToPage 3453
+#define wxHtmlWindow_GetOpenedAnchor 3454
+#define wxHtmlWindow_GetOpenedPage 3455
+#define wxHtmlWindow_GetOpenedPageTitle 3456
+#define wxHtmlWindow_GetRelatedFrame 3457
+#define wxHtmlWindow_HistoryBack 3458
+#define wxHtmlWindow_HistoryCanBack 3459
+#define wxHtmlWindow_HistoryCanForward 3460
+#define wxHtmlWindow_HistoryClear 3461
+#define wxHtmlWindow_HistoryForward 3462
+#define wxHtmlWindow_LoadFile 3463
+#define wxHtmlWindow_LoadPage 3464
+#define wxHtmlWindow_SelectAll 3465
+#define wxHtmlWindow_SelectionToText 3466
+#define wxHtmlWindow_SelectLine 3467
+#define wxHtmlWindow_SelectWord 3468
+#define wxHtmlWindow_SetBorders 3469
+#define wxHtmlWindow_SetFonts 3470
+#define wxHtmlWindow_SetPage 3471
+#define wxHtmlWindow_SetRelatedFrame 3472
+#define wxHtmlWindow_SetRelatedStatusBar 3473
+#define wxHtmlWindow_ToText 3474
+#define wxHtmlWindow_destroy 3475
+#define wxHtmlLinkEvent_GetLinkInfo 3476
+#define wxAuiNotebookEvent_SetSelection 3477
+#define wxAuiNotebookEvent_GetSelection 3478
+#define wxAuiNotebookEvent_SetOldSelection 3479
+#define wxAuiNotebookEvent_GetOldSelection 3480
+#define wxAuiNotebookEvent_SetDragSource 3481
+#define wxAuiNotebookEvent_GetDragSource 3482
+#define wxAuiManagerEvent_SetManager 3483
+#define wxAuiManagerEvent_GetManager 3484
+#define wxAuiManagerEvent_SetPane 3485
+#define wxAuiManagerEvent_GetPane 3486
+#define wxAuiManagerEvent_SetButton 3487
+#define wxAuiManagerEvent_GetButton 3488
+#define wxAuiManagerEvent_SetDC 3489
+#define wxAuiManagerEvent_GetDC 3490
+#define wxAuiManagerEvent_Veto 3491
+#define wxAuiManagerEvent_GetVeto 3492
+#define wxAuiManagerEvent_SetCanVeto 3493
+#define wxAuiManagerEvent_CanVeto 3494
+#define wxLogNull_new 3495
+#define wxLogNull_destroy 3496
diff --git a/lib/wx/c_src/wxe_impl.cpp b/lib/wx/c_src/wxe_impl.cpp
index d115bb2243..4486dff63b 100644
--- a/lib/wx/c_src/wxe_impl.cpp
+++ b/lib/wx/c_src/wxe_impl.cpp
@@ -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%
*/
@@ -615,28 +615,33 @@ int WxeApp::getRef(void * ptr, wxeMemEnv *memenv) {
ptrMap::iterator it = ptr2ref.find(ptr);
if(it != ptr2ref.end()) {
wxeRefData *refd = it->second;
- return refd->ref;
- } else { // New Ptr
- int ref;
- intList free = memenv->free;
-
- if(free.IsEmpty()) {
- ref = memenv->next++;
- } else {
- ref = free.Pop();
- };
- if(ref >= memenv->max) {
- memenv->max *= 2;
- memenv->ref2ptr =
- (void **) driver_realloc(memenv->ref2ptr,memenv->max * sizeof(void*));
- }
+ if(refd->memenv == memenv) {
+ // Found it return
+ return refd->ref;
+ } // else
+ // Old reference to deleted object, release old and recreate in current memenv.
+ clearPtr(ptr);
+ }
+ int ref;
+ intList free = memenv->free;
- memenv->ref2ptr[ref] = ptr;
- ptr2ref[ptr] = new wxeRefData(ref, 0, false, memenv);
- return ref;
+ if(free.IsEmpty()) {
+ ref = memenv->next++;
+ } else {
+ ref = free.Pop();
+ };
+ if(ref >= memenv->max) {
+ memenv->max *= 2;
+ memenv->ref2ptr =
+ (void **) driver_realloc(memenv->ref2ptr,memenv->max * sizeof(void*));
}
+
+ memenv->ref2ptr[ref] = ptr;
+ ptr2ref[ptr] = new wxeRefData(ref, 0, false, memenv);
+ return ref;
}
+
void WxeApp::clearPtr(void * ptr) {
ptrMap::iterator it;
it = ptr2ref.find(ptr);
@@ -697,13 +702,15 @@ void WxeApp::clearPtr(void * ptr) {
void * WxeApp::getPtr(char * bp, wxeMemEnv *memenv) {
int index = *(int *) bp;
- if(!memenv)
+ if(!memenv) {
throw wxe_badarg(index);
+ }
void * temp = memenv->ref2ptr[index];
if((index < memenv->next) && ((index == 0) || (temp > NULL)))
return temp;
- else
+ else {
throw wxe_badarg(index);
+ }
}
void WxeApp::registerPid(char * bp, ErlDrvTermData pid, wxeMemEnv * memenv) {
diff --git a/lib/wx/c_src/wxe_return.cpp b/lib/wx/c_src/wxe_return.cpp
index 8a00d6f4c6..2c4f7541e7 100644
--- a/lib/wx/c_src/wxe_return.cpp
+++ b/lib/wx/c_src/wxe_return.cpp
@@ -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%
*/
@@ -219,7 +219,7 @@ void wxeReturn::add(wxArrayInt val) {
INLINE
void wxeReturn::add(wxUIntPtr *val) {
- addInt((ErlDrvTermData)val); // TODO is this right?
+ add(ERL_DRV_UINT, (ErlDrvTermData) val);
}
INLINE
diff --git a/lib/wx/configure.in b/lib/wx/configure.in
index 7dc8d6e831..855c0c975e 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-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 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*)
@@ -226,7 +244,10 @@ AC_SUBST(ERLANG_ROOT_DIR)
dnl
dnl Check for wxwidgets
dnl
-if test X"$MIXED_CYGWIN_VC" != X"yes" ; then
+if test "$cross_compiling" = "yes"; then
+ echo "Cross compilation of the wx driver is not supported yet, wx will NOT be usable" > ./CONF_INFO
+ WXERL_CAN_BUILD_DRIVER=false
+elif test X"$MIXED_CYGWIN_VC" != X"yes" ; then
m4_include(wxwin.m4)
AM_OPTIONS_WXCONFIG
@@ -288,7 +309,7 @@ define(wx_warn_text,[
if test X"$WX_BUILDING_INSIDE_ERLSRC" != X"true" ; then
AC_MSG_ERROR([wx_warn_text])
else
- echo "wxWidgets not found, wx will NOT be useable" > ./CONF_INFO
+ echo "wxWidgets not found, wx will NOT be usable" > ./CONF_INFO
WXERL_CAN_BUILD_DRIVER=false
AC_MSG_WARN([wx_warn_text])
fi
@@ -360,6 +381,8 @@ else
AC_SUBST(WX_RESCOMP)
fi
+if test "$WXERL_CAN_BUILD_DRIVER" != "false"; then
+
AC_SUBST(WX_HAVE_STATIC_LIBS)
AC_SUBST(RC_FILE_TYPE)
@@ -526,6 +549,8 @@ if test X"$CAN_LINK_WX" != X"yes" ; then
AC_MSG_WARN([Can not link wx program are all developer packages installed?])
fi
+fi dnl - if test "$WXERL_CAN_BUILD_DRIVER" != "false"
+
AC_SUBST(WXERL_CAN_BUILD_DRIVER)
#############################################################################
diff --git a/lib/wx/doc/src/Makefile b/lib/wx/doc/src/Makefile
index d18daa753a..c8eb6174c4 100644
--- a/lib/wx/doc/src/Makefile
+++ b/lib/wx/doc/src/Makefile
@@ -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%
#
@@ -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)
@@ -88,7 +82,6 @@ XML_FILES = \
$(XML_PART_FILES) $(XML_REF3_FILES) \
$(XML_NOTES_FILES) $(XML_APPLICATION_FILES)
-
# ----------------------------------------------------
INFO_FILE = ../../info
@@ -126,9 +119,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
@@ -136,12 +129,13 @@ ref_man.xml: ref_man.src.xml
@echo
$(ErlMods:%.erl=%.xml):
- docb_gen -def vsn $(VSN) -sort_functions false ../../src/$(@:%.xml=%.erl)
+ escript $(DOCGEN)/priv/bin/xml_from_edoc.escript -def vsn $(VSN) -sort_functions false ../../src/$(@:%.xml=%.erl)
+
$(GenMods:%.erl=%.xml):
- docb_gen -def vsn $(VSN) -sort_functions false ../../src/gen/$(@:%.xml=%.erl)
+ escript $(DOCGEN)/priv/bin/xml_from_edoc.escript -def vsn $(VSN) -sort_functions false ../../src/gen/$(@:%.xml=%.erl)
$(XML_CHAPTER_FILES):
- docb_gen -chapter -def vsn $(VSN) ../overview.edoc
+ escript $(DOCGEN)/priv/bin/xml_from_edoc.escript -def vsn $(VSN) -chapter ../overview.edoc
debug opt:
diff --git a/lib/wx/doc/src/notes.xml b/lib/wx/doc/src/notes.xml
index f9f16defd3..92933c348b 100644
--- a/lib/wx/doc/src/notes.xml
+++ b/lib/wx/doc/src/notes.xml
@@ -4,7 +4,7 @@
<chapter>
<header>
<copyright>
- <year>2009</year>
+ <year>2009</year><year>2010</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
@@ -13,12 +13,12 @@
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>wxErlang Release Notes</title>
@@ -31,6 +31,58 @@
<p>This document describes the changes made to the wxErlang
application.</p>
+<section><title>Wx 0.98.5</title>
+
+ <section><title>Fixed Bugs and Malfunctions</title>
+ <list>
+ <item>
+ <p>
+ Corrected incorrectly generated wxFileDialog:getPaths/1.
+ Reported by Jason/hornja.</p>
+ <p>
+ Own Id: OTP-8330</p>
+ </item>
+ <item>
+ <p>
+ Fixed a memory reference bug which caused unexplained
+ {badarg, Int} exits when running multiple wx
+ applications.</p>
+ <p>
+ Own Id: OTP-8461</p>
+ </item>
+ </list>
+ </section>
+
+
+ <section><title>Improvements and New Features</title>
+ <list>
+ <item>
+ <p>
+ Added <c>wxListCtrl:getEditCtrl/1</c> (not available on
+ Mac).</p>
+ <p>
+ Own Id: OTP-8408</p>
+ </item>
+ <item>
+ <p>
+ Cleanups suggested by tidier and modernization of types
+ and specs.</p>
+ <p>
+ Own Id: OTP-8455</p>
+ </item>
+ <item>
+ <p> Changed representation of wxTreeItem to be an
+ integer. This saves memory, where the driver do not need
+ to keep a object reference to each tree item. </p> <p>
+ Added getFirstChild and getNextChild to wxTreeCtrl.</p>
+ <p>
+ Own Id: OTP-8462</p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
<section><title>Wx 0.98.4</title>
<section><title>Improvements and New Features</title>
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/examples/demo/demo_html_tagger.erl b/lib/wx/examples/demo/demo_html_tagger.erl
index 9b6d1fd950..243e5d659f 100644
--- a/lib/wx/examples/demo/demo_html_tagger.erl
+++ b/lib/wx/examples/demo/demo_html_tagger.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(demo_html_tagger).
@@ -462,7 +462,7 @@ fix_remote([H|T]) ->
fix_remote([]) ->
[].
--spec is_keyword(atom()) -> bool().
+-spec is_keyword(atom()) -> boolean().
is_keyword('after' ) -> true;
is_keyword('and') -> true;
diff --git a/lib/wx/include/gl.hrl b/lib/wx/include/gl.hrl
index 7891ebf568..2fa0d72a59 100644
--- a/lib/wx/include/gl.hrl
+++ b/lib/wx/include/gl.hrl
@@ -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%
%% OPENGL DEFINITIONS
diff --git a/lib/wx/include/glu.hrl b/lib/wx/include/glu.hrl
index 27985aa8f7..a2ab55d054 100644
--- a/lib/wx/include/glu.hrl
+++ b/lib/wx/include/glu.hrl
@@ -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%
%% GLU DEFINITIONS
diff --git a/lib/wx/include/wx.hrl b/lib/wx/include/wx.hrl
index b22f7e34b8..6fef625b14 100644
--- a/lib/wx/include/wx.hrl
+++ b/lib/wx/include/wx.hrl
@@ -1,23 +1,23 @@
%%
%% %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%
%% This file is generated DO NOT EDIT
-%% All event messages are encapsulated in a wx record
+%% All event messages are encapsulated in a wx record
%% they contain the widget id and a specialized event record.
%% Each event record may be sent for one or more event types.
%% The mapping to wxWidgets is one record per class.
@@ -26,7 +26,7 @@
-record(wx, {id, %% Integer Identity of object.
obj, %% Object reference that was used in the connect call.
userData, %% User data specified in the connect call.
- event}).%% The event record
+ event}).%% The event record
%% Here comes the definitions of all event records.
%% they contain the event type and possible some extra information.
@@ -34,254 +34,254 @@
%% @type wxNavigationKey() = #wxNavigationKey{type=wxEventType(),flags=integer(),focus=wxWindow:wxWindow()}.
%% <dl><dt>EventType:</dt> <dd><em>navigation_key</em></dd></dl>
%% Callback event: {@link wxNavigationKeyEvent}
--record(wxNavigationKey,{type, flags,focus}).
+-record(wxNavigationKey,{type, flags,focus}).
%% @type wxSash() = #wxSash{type=wxEventType(),edge=WxSashEdgePosition,dragRect={X::integer(),Y::integer(),W::integer(),H::integer()},dragStatus=WxSashDragStatus}.
%% <dl><dt>EventType:</dt> <dd><em>sash_dragged</em></dd></dl>
%% Callback event: {@link wxSashEvent}
--record(wxSash,{type, edge,dragRect,dragStatus}).
+-record(wxSash,{type, edge,dragRect,dragStatus}).
%% @type wxList() = #wxList{type=wxEventType(),code=integer(),oldItemIndex=integer(),itemIndex=integer(),col=integer(),pointDrag={X::integer(),Y::integer()}}.
%% <dl><dt>EventType:</dt> <dd><em>command_list_begin_drag</em>, <em>command_list_begin_rdrag</em>, <em>command_list_begin_label_edit</em>, <em>command_list_end_label_edit</em>, <em>command_list_delete_item</em>, <em>command_list_delete_all_items</em>, <em>command_list_key_down</em>, <em>command_list_insert_item</em>, <em>command_list_col_click</em>, <em>command_list_col_right_click</em>, <em>command_list_col_begin_drag</em>, <em>command_list_col_dragging</em>, <em>command_list_col_end_drag</em>, <em>command_list_item_selected</em>, <em>command_list_item_deselected</em>, <em>command_list_item_right_click</em>, <em>command_list_item_middle_click</em>, <em>command_list_item_activated</em>, <em>command_list_item_focused</em>, <em>command_list_cache_hint</em></dd></dl>
%% Callback event: {@link wxListEvent}
--record(wxList,{type, code,oldItemIndex,itemIndex,col,pointDrag}).
+-record(wxList,{type, code,oldItemIndex,itemIndex,col,pointDrag}).
%% @type wxNotebook() = #wxNotebook{type=wxEventType()}.
%% <dl><dt>EventType:</dt> <dd><em>command_notebook_page_changed</em>, <em>command_notebook_page_changing</em></dd></dl>
%% Callback event: {@link wxNotebookEvent}
--record(wxNotebook, {type}).
+-record(wxNotebook, {type}).
%% @type wxDisplayChanged() = #wxDisplayChanged{type=wxEventType()}.
%% <dl><dt>EventType:</dt> <dd><em>display_changed</em></dd></dl>
%% Callback event: {@link wxDisplayChangedEvent}
--record(wxDisplayChanged, {type}).
+-record(wxDisplayChanged, {type}).
%% @type wxErase() = #wxErase{type=wxEventType(),dc=wxDC:wxDC()}.
%% <dl><dt>EventType:</dt> <dd><em>erase_background</em></dd></dl>
%% Callback event: {@link wxEraseEvent}
--record(wxErase,{type, dc}).
+-record(wxErase,{type, dc}).
%% @type wxKey() = #wxKey{type=wxEventType(),x=integer(),y=integer(),keyCode=integer(),controlDown=bool(),shiftDown=bool(),altDown=bool(),metaDown=bool(),scanCode=bool(),uniChar=integer(),rawCode=integer(),rawFlags=integer()}.
%% <dl><dt>EventType:</dt> <dd><em>char</em>, <em>char_hook</em>, <em>key_down</em>, <em>key_up</em></dd></dl>
%% Callback event: {@link wxKeyEvent}
--record(wxKey,{type, x,y,keyCode,controlDown,shiftDown,altDown,metaDown,scanCode,uniChar,rawCode,rawFlags}).
+-record(wxKey,{type, x,y,keyCode,controlDown,shiftDown,altDown,metaDown,scanCode,uniChar,rawCode,rawFlags}).
%% @type wxWindowDestroy() = #wxWindowDestroy{type=wxEventType()}.
%% <dl><dt>EventType:</dt> <dd><em>destroy</em></dd></dl>
%% Callback event: {@link wxWindowDestroyEvent}
--record(wxWindowDestroy, {type}).
+-record(wxWindowDestroy, {type}).
%% @type wxCalendar() = #wxCalendar{type=wxEventType()}.
%% <dl><dt>EventType:</dt> <dd><em>calendar_sel_changed</em>, <em>calendar_day_changed</em>, <em>calendar_month_changed</em>, <em>calendar_year_changed</em>, <em>calendar_doubleclicked</em>, <em>calendar_weekday_clicked</em></dd></dl>
%% Callback event: {@link wxCalendarEvent}
--record(wxCalendar, {type}).
+-record(wxCalendar, {type}).
%% @type wxSplitter() = #wxSplitter{type=wxEventType()}.
%% <dl><dt>EventType:</dt> <dd><em>command_splitter_sash_pos_changed</em>, <em>command_splitter_sash_pos_changing</em>, <em>command_splitter_doubleclicked</em>, <em>command_splitter_unsplit</em></dd></dl>
%% Callback event: {@link wxSplitterEvent}
--record(wxSplitter, {type}).
+-record(wxSplitter, {type}).
%% @type wxScroll() = #wxScroll{type=wxEventType(),commandInt=integer(),extraLong=integer()}.
%% <dl><dt>EventType:</dt> <dd><em>scroll_top</em>, <em>scroll_bottom</em>, <em>scroll_lineup</em>, <em>scroll_linedown</em>, <em>scroll_pageup</em>, <em>scroll_pagedown</em>, <em>scroll_thumbtrack</em>, <em>scroll_thumbrelease</em>, <em>scroll_changed</em></dd></dl>
%% Callback event: {@link wxScrollEvent}
--record(wxScroll,{type, commandInt,extraLong}).
+-record(wxScroll,{type, commandInt,extraLong}).
%% @type wxMenu() = #wxMenu{type=wxEventType()}.
%% <dl><dt>EventType:</dt> <dd><em>menu_open</em>, <em>menu_close</em>, <em>menu_highlight</em></dd></dl>
%% Callback event: {@link wxMenuEvent}
--record(wxMenu, {type}).
+-record(wxMenu, {type}).
%% @type wxContextMenu() = #wxContextMenu{type=wxEventType()}.
%% <dl><dt>EventType:</dt> <dd><em>context_menu</em></dd></dl>
%% Callback event: {@link wxContextMenuEvent}
--record(wxContextMenu, {type}).
+-record(wxContextMenu, {type}).
%% @type wxShow() = #wxShow{type=wxEventType()}.
%% <dl><dt>EventType:</dt> <dd><em>show</em></dd></dl>
%% Callback event: {@link wxShowEvent}
--record(wxShow, {type}).
+-record(wxShow, {type}).
%% @type wxSpin() = #wxSpin{type=wxEventType(),commandInt=integer()}.
%% <dl><dt>EventType:</dt> <dd><em>command_spinctrl_updated</em>, <em>spin_up</em>, <em>spin_down</em>, <em>spin</em></dd></dl>
%% Callback event: {@link wxSpinEvent}
--record(wxSpin,{type, commandInt}).
+-record(wxSpin,{type, commandInt}).
%% @type wxSetCursor() = #wxSetCursor{type=wxEventType()}.
%% <dl><dt>EventType:</dt> <dd><em>set_cursor</em></dd></dl>
%% Callback event: {@link wxSetCursorEvent}
--record(wxSetCursor, {type}).
+-record(wxSetCursor, {type}).
%% @type wxFontPicker() = #wxFontPicker{type=wxEventType(),font=wxFont:wxFont()}.
%% <dl><dt>EventType:</dt> <dd><em>command_fontpicker_changed</em></dd></dl>
%% Callback event: {@link wxFontPickerEvent}
--record(wxFontPicker,{type, font}).
+-record(wxFontPicker,{type, font}).
%% @type wxScrollWin() = #wxScrollWin{type=wxEventType()}.
%% <dl><dt>EventType:</dt> <dd><em>scrollwin_top</em>, <em>scrollwin_bottom</em>, <em>scrollwin_lineup</em>, <em>scrollwin_linedown</em>, <em>scrollwin_pageup</em>, <em>scrollwin_pagedown</em>, <em>scrollwin_thumbtrack</em>, <em>scrollwin_thumbrelease</em></dd></dl>
%% Callback event: {@link wxScrollWinEvent}
--record(wxScrollWin, {type}).
+-record(wxScrollWin, {type}).
%% @type wxPaint() = #wxPaint{type=wxEventType()}.
%% <dl><dt>EventType:</dt> <dd><em>paint</em>, <em>paint_icon</em></dd></dl>
%% Callback event: {@link wxPaintEvent}
--record(wxPaint, {type}).
+-record(wxPaint, {type}).
%% @type wxChildFocus() = #wxChildFocus{type=wxEventType()}.
%% <dl><dt>EventType:</dt> <dd><em>child_focus</em></dd></dl>
%% Callback event: {@link wxChildFocusEvent}
--record(wxChildFocus, {type}).
+-record(wxChildFocus, {type}).
%% @type wxMaximize() = #wxMaximize{type=wxEventType()}.
%% <dl><dt>EventType:</dt> <dd><em>maximize</em></dd></dl>
%% Callback event: {@link wxMaximizeEvent}
--record(wxMaximize, {type}).
+-record(wxMaximize, {type}).
%% @type wxFileDirPicker() = #wxFileDirPicker{type=wxEventType(),path=string()}.
%% <dl><dt>EventType:</dt> <dd><em>command_filepicker_changed</em>, <em>command_dirpicker_changed</em></dd></dl>
%% Callback event: {@link wxFileDirPickerEvent}
--record(wxFileDirPicker,{type, path}).
+-record(wxFileDirPicker,{type, path}).
%% @type wxFocus() = #wxFocus{type=wxEventType()}.
%% <dl><dt>EventType:</dt> <dd><em>set_focus</em>, <em>kill_focus</em></dd></dl>
%% Callback event: {@link wxFocusEvent}
--record(wxFocus, {type}).
+-record(wxFocus, {type}).
%% @type wxDate() = #wxDate{type=wxEventType(),date=wx:datetime()}.
%% <dl><dt>EventType:</dt> <dd><em>date_changed</em></dd></dl>
%% Callback event: {@link wxDateEvent}
--record(wxDate,{type, date}).
+-record(wxDate,{type, date}).
%% @type wxHtmlLink() = #wxHtmlLink{type=wxEventType(),linkInfo=wx:wxHtmlLinkInfo()}.
%% <dl><dt>EventType:</dt> <dd><em>command_html_link_clicked</em></dd></dl>
%% Callback event: {@link wxHtmlLinkEvent}
--record(wxHtmlLink,{type, linkInfo}).
+-record(wxHtmlLink,{type, linkInfo}).
%% @type wxHelp() = #wxHelp{type=wxEventType()}.
%% <dl><dt>EventType:</dt> <dd><em>help</em>, <em>detailed_help</em></dd></dl>
%% Callback event: {@link wxHelpEvent}
--record(wxHelp, {type}).
+-record(wxHelp, {type}).
%% @type wxStyledText() = #wxStyledText{type=wxEventType(),position=integer(),key=integer(),modifiers=integer(),modificationType=integer(),text=string(),length=integer(),linesAdded=integer(),line=integer(),foldLevelNow=integer(),foldLevelPrev=integer(),margin=integer(),message=integer(),wParam=integer(),lParam=integer(),listType=integer(),x=integer(),y=integer(),dragText=string(),dragAllowMove=bool(),dragResult=WxDragResult}.
%% <dl><dt>EventType:</dt> <dd><em>stc_change</em>, <em>stc_styleneeded</em>, <em>stc_charadded</em>, <em>stc_savepointreached</em>, <em>stc_savepointleft</em>, <em>stc_romodifyattempt</em>, <em>stc_key</em>, <em>stc_doubleclick</em>, <em>stc_updateui</em>, <em>stc_modified</em>, <em>stc_macrorecord</em>, <em>stc_marginclick</em>, <em>stc_needshown</em>, <em>stc_painted</em>, <em>stc_userlistselection</em>, <em>stc_uridropped</em>, <em>stc_dwellstart</em>, <em>stc_dwellend</em>, <em>stc_start_drag</em>, <em>stc_drag_over</em>, <em>stc_do_drop</em>, <em>stc_zoom</em>, <em>stc_hotspot_click</em>, <em>stc_hotspot_dclick</em>, <em>stc_calltip_click</em>, <em>stc_autocomp_selection</em></dd></dl>
%% Callback event: {@link wxStyledTextEvent}
--record(wxStyledText,{type, position,key,modifiers,modificationType,text,length,linesAdded,line,foldLevelNow,foldLevelPrev,margin,message,wParam,lParam,listType,x,y,dragText,dragAllowMove,dragResult}).
+-record(wxStyledText,{type, position,key,modifiers,modificationType,text,length,linesAdded,line,foldLevelNow,foldLevelPrev,margin,message,wParam,lParam,listType,x,y,dragText,dragAllowMove,dragResult}).
%% @type wxSysColourChanged() = #wxSysColourChanged{type=wxEventType()}.
%% <dl><dt>EventType:</dt> <dd><em>sys_colour_changed</em></dd></dl>
%% Callback event: {@link wxSysColourChangedEvent}
--record(wxSysColourChanged, {type}).
+-record(wxSysColourChanged, {type}).
%% @type wxGrid() = #wxGrid{type=wxEventType(),row=integer(),col=integer(),x=integer(),y=integer(),selecting=bool(),control=bool(),meta=bool(),shift=bool(),alt=bool()}.
%% <dl><dt>EventType:</dt> <dd><em>grid_cell_left_click</em>, <em>grid_cell_right_click</em>, <em>grid_cell_left_dclick</em>, <em>grid_cell_right_dclick</em>, <em>grid_label_left_click</em>, <em>grid_label_right_click</em>, <em>grid_label_left_dclick</em>, <em>grid_label_right_dclick</em>, <em>grid_row_size</em>, <em>grid_col_size</em>, <em>grid_range_select</em>, <em>grid_cell_change</em>, <em>grid_select_cell</em>, <em>grid_editor_shown</em>, <em>grid_editor_hidden</em>, <em>grid_editor_created</em>, <em>grid_cell_begin_drag</em></dd></dl>
%% Callback event: {@link wxGridEvent}
--record(wxGrid,{type, row,col,x,y,selecting,control,meta,shift,alt}).
+-record(wxGrid,{type, row,col,x,y,selecting,control,meta,shift,alt}).
%% @type wxPaletteChanged() = #wxPaletteChanged{type=wxEventType()}.
%% <dl><dt>EventType:</dt> <dd><em>palette_changed</em></dd></dl>
%% Callback event: {@link wxPaletteChangedEvent}
--record(wxPaletteChanged, {type}).
+-record(wxPaletteChanged, {type}).
%% @type wxUpdateUI() = #wxUpdateUI{type=wxEventType()}.
%% <dl><dt>EventType:</dt> <dd><em>update_ui</em></dd></dl>
%% Callback event: {@link wxUpdateUIEvent}
--record(wxUpdateUI, {type}).
+-record(wxUpdateUI, {type}).
%% @type wxSize() = #wxSize{type=wxEventType(),size={W::integer(),H::integer()},rect={X::integer(),Y::integer(),W::integer(),H::integer()}}.
%% <dl><dt>EventType:</dt> <dd><em>size</em></dd></dl>
%% Callback event: {@link wxSizeEvent}
--record(wxSize,{type, size,rect}).
+-record(wxSize,{type, size,rect}).
%% @type wxIconize() = #wxIconize{type=wxEventType()}.
%% <dl><dt>EventType:</dt> <dd><em>iconize</em></dd></dl>
%% Callback event: {@link wxIconizeEvent}
--record(wxIconize, {type}).
+-record(wxIconize, {type}).
%% @type wxAuiNotebook() = #wxAuiNotebook{type=wxEventType(),old_selection=integer(),selection=integer(),drag_source=wxAuiNotebook:wxAuiNotebook()}.
%% <dl><dt>EventType:</dt> <dd><em>command_auinotebook_page_close</em>, <em>command_auinotebook_page_changed</em>, <em>command_auinotebook_page_changing</em>, <em>command_auinotebook_button</em>, <em>command_auinotebook_begin_drag</em>, <em>command_auinotebook_end_drag</em>, <em>command_auinotebook_drag_motion</em>, <em>command_auinotebook_allow_dnd</em>, <em>command_auinotebook_tab_middle_down</em>, <em>command_auinotebook_tab_middle_up</em>, <em>command_auinotebook_tab_right_down</em>, <em>command_auinotebook_tab_right_up</em>, <em>command_auinotebook_page_closed</em>, <em>command_auinotebook_drag_done</em>, <em>command_auinotebook_bg_dclick</em></dd></dl>
%% Callback event: {@link wxAuiNotebookEvent}
--record(wxAuiNotebook,{type, old_selection,selection,drag_source}).
+-record(wxAuiNotebook,{type, old_selection,selection,drag_source}).
%% @type wxClose() = #wxClose{type=wxEventType()}.
%% <dl><dt>EventType:</dt> <dd><em>close_window</em>, <em>end_session</em>, <em>query_end_session</em></dd></dl>
%% Callback event: {@link wxCloseEvent}
--record(wxClose, {type}).
+-record(wxClose, {type}).
%% @type wxMouseCaptureChanged() = #wxMouseCaptureChanged{type=wxEventType()}.
%% <dl><dt>EventType:</dt> <dd><em>mouse_capture_changed</em></dd></dl>
%% Callback event: {@link wxMouseCaptureChangedEvent}
--record(wxMouseCaptureChanged, {type}).
+-record(wxMouseCaptureChanged, {type}).
%% @type wxMouse() = #wxMouse{type=wxEventType(),x=integer(),y=integer(),leftDown=bool(),middleDown=bool(),rightDown=bool(),controlDown=bool(),shiftDown=bool(),altDown=bool(),metaDown=bool(),wheelRotation=integer(),wheelDelta=integer(),linesPerAction=integer()}.
%% <dl><dt>EventType:</dt> <dd><em>left_down</em>, <em>left_up</em>, <em>middle_down</em>, <em>middle_up</em>, <em>right_down</em>, <em>right_up</em>, <em>motion</em>, <em>enter_window</em>, <em>leave_window</em>, <em>left_dclick</em>, <em>middle_dclick</em>, <em>right_dclick</em>, <em>mousewheel</em>, <em>nc_left_down</em>, <em>nc_left_up</em>, <em>nc_middle_down</em>, <em>nc_middle_up</em>, <em>nc_right_down</em>, <em>nc_right_up</em>, <em>nc_motion</em>, <em>nc_enter_window</em>, <em>nc_leave_window</em>, <em>nc_left_dclick</em>, <em>nc_middle_dclick</em>, <em>nc_right_dclick</em></dd></dl>
%% Callback event: {@link wxMouseEvent}
--record(wxMouse,{type, x,y,leftDown,middleDown,rightDown,controlDown,shiftDown,altDown,metaDown,wheelRotation,wheelDelta,linesPerAction}).
+-record(wxMouse,{type, x,y,leftDown,middleDown,rightDown,controlDown,shiftDown,altDown,metaDown,wheelRotation,wheelDelta,linesPerAction}).
%% @type wxWindowCreate() = #wxWindowCreate{type=wxEventType()}.
%% <dl><dt>EventType:</dt> <dd><em>create</em></dd></dl>
%% Callback event: {@link wxWindowCreateEvent}
--record(wxWindowCreate, {type}).
+-record(wxWindowCreate, {type}).
%% @type wxAuiManager() = #wxAuiManager{type=wxEventType(),manager=wxAuiManager:wxAuiManager(),pane=wxAuiPaneInfo:wxAuiPaneInfo(),button=integer(),veto_flag=bool(),canveto_flag=bool(),dc=wxDC:wxDC()}.
%% <dl><dt>EventType:</dt> <dd><em>aui_pane_button</em>, <em>aui_pane_close</em>, <em>aui_pane_maximize</em>, <em>aui_pane_restore</em>, <em>aui_render</em>, <em>aui_find_manager</em></dd></dl>
%% Callback event: {@link wxAuiManagerEvent}
--record(wxAuiManager,{type, manager,pane,button,veto_flag,canveto_flag,dc}).
+-record(wxAuiManager,{type, manager,pane,button,veto_flag,canveto_flag,dc}).
%% @type wxCommand() = #wxCommand{type=wxEventType(),cmdString=string(),commandInt=integer(),extraLong=integer()}.
%% <dl><dt>EventType:</dt> <dd><em>command_button_clicked</em>, <em>command_checkbox_clicked</em>, <em>command_choice_selected</em>, <em>command_listbox_selected</em>, <em>command_listbox_doubleclicked</em>, <em>command_text_updated</em>, <em>command_text_enter</em>, <em>command_menu_selected</em>, <em>command_slider_updated</em>, <em>command_radiobox_selected</em>, <em>command_radiobutton_selected</em>, <em>command_scrollbar_updated</em>, <em>command_vlbox_selected</em>, <em>command_combobox_selected</em>, <em>command_tool_rclicked</em>, <em>command_tool_enter</em>, <em>command_checklistbox_toggled</em>, <em>command_togglebutton_clicked</em>, <em>command_left_click</em>, <em>command_left_dclick</em>, <em>command_right_click</em>, <em>command_set_focus</em>, <em>command_kill_focus</em>, <em>command_enter</em></dd></dl>
%% Callback event: {@link wxCommandEvent}
--record(wxCommand,{type, cmdString,commandInt,extraLong}).
+-record(wxCommand,{type, cmdString,commandInt,extraLong}).
%% @type wxJoystick() = #wxJoystick{type=wxEventType()}.
%% <dl><dt>EventType:</dt> <dd><em>joy_button_down</em>, <em>joy_button_up</em>, <em>joy_move</em>, <em>joy_zmove</em></dd></dl>
%% Callback event: {@link wxJoystickEvent}
--record(wxJoystick, {type}).
+-record(wxJoystick, {type}).
%% @type wxQueryNewPalette() = #wxQueryNewPalette{type=wxEventType()}.
%% <dl><dt>EventType:</dt> <dd><em>query_new_palette</em></dd></dl>
%% Callback event: {@link wxQueryNewPaletteEvent}
--record(wxQueryNewPalette, {type}).
+-record(wxQueryNewPalette, {type}).
%% @type wxMove() = #wxMove{type=wxEventType()}.
%% <dl><dt>EventType:</dt> <dd><em>move</em></dd></dl>
%% Callback event: {@link wxMoveEvent}
--record(wxMove, {type}).
+-record(wxMove, {type}).
%% @type wxIdle() = #wxIdle{type=wxEventType()}.
%% <dl><dt>EventType:</dt> <dd><em>idle</em></dd></dl>
%% Callback event: {@link wxIdleEvent}
--record(wxIdle, {type}).
+-record(wxIdle, {type}).
%% @type wxNcPaint() = #wxNcPaint{type=wxEventType()}.
%% <dl><dt>EventType:</dt> <dd><em>nc_paint</em></dd></dl>
%% Callback event: {@link wxNcPaintEvent}
--record(wxNcPaint, {type}).
+-record(wxNcPaint, {type}).
%% @type wxColourPicker() = #wxColourPicker{type=wxEventType(),colour=wx:colour()}.
%% <dl><dt>EventType:</dt> <dd><em>command_colourpicker_changed</em></dd></dl>
%% Callback event: {@link wxColourPickerEvent}
--record(wxColourPicker,{type, colour}).
+-record(wxColourPicker,{type, colour}).
-%% @type wxTree() = #wxTree{type=wxEventType(),item=wxTreeItemId(),itemOld=wxTreeItemId(),pointDrag={X::integer(),Y::integer()}}.
+%% @type wxTree() = #wxTree{type=wxEventType(),item=integer(),itemOld=integer(),pointDrag={X::integer(),Y::integer()}}.
%% <dl><dt>EventType:</dt> <dd><em>command_tree_begin_drag</em>, <em>command_tree_begin_rdrag</em>, <em>command_tree_begin_label_edit</em>, <em>command_tree_end_label_edit</em>, <em>command_tree_delete_item</em>, <em>command_tree_get_info</em>, <em>command_tree_set_info</em>, <em>command_tree_item_expanded</em>, <em>command_tree_item_expanding</em>, <em>command_tree_item_collapsed</em>, <em>command_tree_item_collapsing</em>, <em>command_tree_sel_changed</em>, <em>command_tree_sel_changing</em>, <em>command_tree_key_down</em>, <em>command_tree_item_activated</em>, <em>command_tree_item_right_click</em>, <em>command_tree_item_middle_click</em>, <em>command_tree_end_drag</em>, <em>command_tree_state_image_click</em>, <em>command_tree_item_gettooltip</em>, <em>command_tree_item_menu</em></dd></dl>
%% Callback event: {@link wxTreeEvent}
--record(wxTree,{type, item,itemOld,pointDrag}).
+-record(wxTree,{type, item,itemOld,pointDrag}).
%% @type wxEventType() = aui_find_manager | aui_pane_button | aui_pane_close | aui_pane_maximize | aui_pane_restore | aui_render | calendar_day_changed | calendar_doubleclicked | calendar_month_changed | calendar_sel_changed | calendar_weekday_clicked | calendar_year_changed | char | char_hook | child_focus | close_window | command_auinotebook_allow_dnd | command_auinotebook_begin_drag | command_auinotebook_bg_dclick | command_auinotebook_button | command_auinotebook_drag_done | command_auinotebook_drag_motion | command_auinotebook_end_drag | command_auinotebook_page_changed | command_auinotebook_page_changing | command_auinotebook_page_close | command_auinotebook_page_closed | command_auinotebook_tab_middle_down | command_auinotebook_tab_middle_up | command_auinotebook_tab_right_down | command_auinotebook_tab_right_up | command_button_clicked | command_checkbox_clicked | command_checklistbox_toggled | command_choice_selected | command_colourpicker_changed | command_combobox_selected | command_dirpicker_changed | command_enter | command_filepicker_changed | command_fontpicker_changed | command_html_link_clicked | command_kill_focus | command_left_click | command_left_dclick | command_list_begin_drag | command_list_begin_label_edit | command_list_begin_rdrag | command_list_cache_hint | command_list_col_begin_drag | command_list_col_click | command_list_col_dragging | command_list_col_end_drag | command_list_col_right_click | command_list_delete_all_items | command_list_delete_item | command_list_end_label_edit | command_list_insert_item | command_list_item_activated | command_list_item_deselected | command_list_item_focused | command_list_item_middle_click | command_list_item_right_click | command_list_item_selected | command_list_key_down | command_listbox_doubleclicked | command_listbox_selected | command_menu_selected | command_notebook_page_changed | command_notebook_page_changing | command_radiobox_selected | command_radiobutton_selected | command_right_click | command_scrollbar_updated | command_set_focus | command_slider_updated | command_spinctrl_updated | command_splitter_doubleclicked | command_splitter_sash_pos_changed | command_splitter_sash_pos_changing | command_splitter_unsplit | command_text_enter | command_text_updated | command_togglebutton_clicked | command_tool_enter | command_tool_rclicked | command_tree_begin_drag | command_tree_begin_label_edit | command_tree_begin_rdrag | command_tree_delete_item | command_tree_end_drag | command_tree_end_label_edit | command_tree_get_info | command_tree_item_activated | command_tree_item_collapsed | command_tree_item_collapsing | command_tree_item_expanded | command_tree_item_expanding | command_tree_item_gettooltip | command_tree_item_menu | command_tree_item_middle_click | command_tree_item_right_click | command_tree_key_down | command_tree_sel_changed | command_tree_sel_changing | command_tree_set_info | command_tree_state_image_click | command_vlbox_selected | context_menu | create | date_changed | destroy | detailed_help | display_changed | end_session | enter_window | erase_background | grid_cell_begin_drag | grid_cell_change | grid_cell_left_click | grid_cell_left_dclick | grid_cell_right_click | grid_cell_right_dclick | grid_col_size | grid_editor_created | grid_editor_hidden | grid_editor_shown | grid_label_left_click | grid_label_left_dclick | grid_label_right_click | grid_label_right_dclick | grid_range_select | grid_row_size | grid_select_cell | help | iconize | idle | joy_button_down | joy_button_up | joy_move | joy_zmove | key_down | key_up | kill_focus | leave_window | left_dclick | left_down | left_up | maximize | menu_close | menu_highlight | menu_open | middle_dclick | middle_down | middle_up | motion | mouse_capture_changed | mousewheel | move | navigation_key | nc_enter_window | nc_leave_window | nc_left_dclick | nc_left_down | nc_left_up | nc_middle_dclick | nc_middle_down | nc_middle_up | nc_motion | nc_paint | nc_right_dclick | nc_right_down | nc_right_up | paint | paint_icon | palette_changed | query_end_session | query_new_palette | right_dclick | right_down | right_up | sash_dragged | scroll_bottom | scroll_changed | scroll_linedown | scroll_lineup | scroll_pagedown | scroll_pageup | scroll_thumbrelease | scroll_thumbtrack | scroll_top | scrollwin_bottom | scrollwin_linedown | scrollwin_lineup | scrollwin_pagedown | scrollwin_pageup | scrollwin_thumbrelease | scrollwin_thumbtrack | scrollwin_top | set_cursor | set_focus | show | size | spin | spin_down | spin_up | stc_autocomp_selection | stc_calltip_click | stc_change | stc_charadded | stc_do_drop | stc_doubleclick | stc_drag_over | stc_dwellend | stc_dwellstart | stc_hotspot_click | stc_hotspot_dclick | stc_key | stc_macrorecord | stc_marginclick | stc_modified | stc_needshown | stc_painted | stc_romodifyattempt | stc_savepointleft | stc_savepointreached | stc_start_drag | stc_styleneeded | stc_updateui | stc_uridropped | stc_userlistselection | stc_zoom | sys_colour_changed | update_ui.
-%% Hardcoded Records
--record(wxMouseState, {x, y, %% integer()
- leftDown, middleDown, rightDown, %% bool()
+%% Hardcoded Records
+-record(wxMouseState, {x, y, %% integer()
+ leftDown, middleDown, rightDown, %% bool()
controlDown, shiftDown, altDown, metaDown, cmdDown %% bool()
}).
--record(wxHtmlLinkInfo, {
- href, target %% string()
+-record(wxHtmlLinkInfo, {
+ href, target %% string()
}).
-%% Hardcoded Defines
+%% Hardcoded Defines
-define(wxDefaultSize, {-1,-1}).
-define(wxDefaultPosition, {-1,-1}).
-%% Global Variables
+%% Global Variables
-define(wxBLACK, wxe_util:get_const(wxBLACK)).
-define(wxBLACK_BRUSH, wxe_util:get_const(wxBLACK_BRUSH)).
-define(wxBLACK_DASHED_PEN, wxe_util:get_const(wxBLACK_DASHED_PEN)).
@@ -324,8 +324,8 @@
-define(wxWHITE_BRUSH, wxe_util:get_const(wxWHITE_BRUSH)).
-define(wxWHITE_PEN, wxe_util:get_const(wxWHITE_PEN)).
-%% Enum and defines
-% From define::From bookctrl.h
+%% Enum and defines
+% From define::From bookctrl.h
-define(wxEVT_COMMAND_BOOKCTRL_PAGE_CHANGING, ?wxEVT_COMMAND_NOTEBOOK_PAGE_CHANGING).
-define(wxEVT_COMMAND_BOOKCTRL_PAGE_CHANGED, ?wxEVT_COMMAND_NOTEBOOK_PAGE_CHANGED).
-define(wxBK_ALIGN_MASK, (?wxBK_TOP bor ?wxBK_BOTTOM bor ?wxBK_LEFT bor ?wxBK_RIGHT)).
@@ -334,7 +334,7 @@
-define(wxBK_BOTTOM, 32).
-define(wxBK_TOP, 16).
-define(wxBK_DEFAULT, 0).
-% From define::From button.h
+% From define::From button.h
-define(wxBU_EXACTFIT, 1).
-define(wxBU_AUTODRAW, 4).
-define(wxBU_NOAUTODRAW, 0).
@@ -343,38 +343,38 @@
-define(wxBU_RIGHT, 256).
-define(wxBU_TOP, 128).
-define(wxBU_LEFT, 64).
-% From define::From checkbox.h
+% From define::From checkbox.h
-define(wxCHK_ALLOW_3RD_STATE_FOR_USER, 8192).
-define(wxCHK_3STATE, 4096).
-define(wxCHK_2STATE, 0).
-% From define::From choicdgg.h
+% From define::From choicdgg.h
-define(wxCHOICEDLG_STYLE, (?wxDEFAULT_DIALOG_STYLE bor ?wxRESIZE_BORDER bor ?wxOK bor ?wxCANCEL bor ?wxCENTRE)).
-define(wxCHOICE_WIDTH, 200).
-define(wxCHOICE_HEIGHT, 150).
-% From define::From choicebk.h
+% From define::From choicebk.h
-define(wxCHB_ALIGN_MASK, ?wxBK_ALIGN_MASK).
-define(wxCHB_RIGHT, ?wxBK_RIGHT).
-define(wxCHB_LEFT, ?wxBK_LEFT).
-define(wxCHB_BOTTOM, ?wxBK_BOTTOM).
-define(wxCHB_TOP, ?wxBK_TOP).
-define(wxCHB_DEFAULT, ?wxBK_DEFAULT).
-% From define::From clrpicker.h
+% From define::From clrpicker.h
-define(wxCLRP_DEFAULT_STYLE, 0).
-define(wxCLRP_USE_TEXTCTRL, ?wxPB_USE_TEXTCTRL).
-define(wxCLRP_SHOW_LABEL, 8).
-% From define::From colour.h
+% From define::From colour.h
-define(wxC2S_HTML_SYNTAX, 4).
-define(wxC2S_CSS_SYNTAX, 2).
-define(wxC2S_NAME, 1).
-% From define::From confbase.h
+% From define::From confbase.h
-define(wxCONFIG_CASE_SENSITIVE, 0).
-% From define::From datetime.h
+% From define::From datetime.h
-define(wxInvalidDateTime, ?wxDefaultDateTime).
-% From define::From dcbuffer.h
+% From define::From dcbuffer.h
-define(wxBUFFER_CLIENT_AREA, 2).
-define(wxBUFFER_VIRTUAL_AREA, 1).
-define(wxALWAYS_NATIVE_DOUBLE_BUFFER, 0).
-% From define::From defs.h
+% From define::From defs.h
-define(wxPRINT_QUALITY_DRAFT, -4).
-define(wxPRINT_QUALITY_LOW, -3).
-define(wxPRINT_QUALITY_MEDIUM, -2).
@@ -503,21 +503,21 @@
-define(wxBIG_ENDIAN, 4321).
-define(wxHAS_INT64, wxe_util:get_const(wxHAS_INT64)).
-define(wxNOT_FOUND, -1).
-% From define::From dialog.h
+% From define::From dialog.h
-define(wxDEFAULT_DIALOG_STYLE, (?wxCAPTION bor ?wxSYSTEM_MENU bor ?wxCLOSE_BOX)).
-define(wxDIALOG_NO_PARENT, 1).
-% From define::From dirctrlg.h
+% From define::From dirctrlg.h
-define(wxID_FILTERLISTCTRL, 7001).
-define(wxID_TREECTRL, 7000).
-% From define::From dirdlg.h
+% From define::From dirdlg.h
-define(wxDD_DEFAULT_STYLE, (?wxDEFAULT_DIALOG_STYLE bor ?wxRESIZE_BORDER)).
-define(wxDD_NEW_DIR_BUTTON, 0).
-define(wxDD_DIR_MUST_EXIST, 512).
-define(wxDD_CHANGE_DIR, 256).
-% From define::From dirdlgg.h
-% From define::From filedlg.h
+% From define::From dirdlgg.h
+% From define::From filedlg.h
-define(wxFD_DEFAULT_STYLE, ?wxFD_OPEN).
-% From define::From filepicker.h
+% From define::From filepicker.h
-define(wxDIRP_DEFAULT_STYLE, ?wxDIRP_DIR_MUST_EXIST).
-define(wxDIRP_USE_TEXTCTRL, ?wxPB_USE_TEXTCTRL).
-define(wxFLP_DEFAULT_STYLE, (?wxFLP_OPEN bor ?wxFLP_FILE_MUST_EXIST)).
@@ -529,30 +529,30 @@
-define(wxFLP_OVERWRITE_PROMPT, 4096).
-define(wxFLP_SAVE, 2048).
-define(wxFLP_OPEN, 1024).
-% From define::From fontpicker.h
+% From define::From fontpicker.h
-define(wxFNTP_MAXPOINT_SIZE, 100).
-define(wxFNTP_DEFAULT_STYLE, (?wxFNTP_FONTDESC_AS_LABEL bor ?wxFNTP_USEFONT_FOR_LABEL)).
-define(wxFNTP_USE_TEXTCTRL, ?wxPB_USE_TEXTCTRL).
-define(wxFNTP_USEFONT_FOR_LABEL, 16).
-define(wxFNTP_FONTDESC_AS_LABEL, 8).
-% From define::From frame.h
+% From define::From frame.h
-define(wxFRAME_SHAPED, 16).
-define(wxFRAME_FLOAT_ON_PARENT, 8).
-define(wxFRAME_TOOL_WINDOW, 4).
-define(wxFRAME_NO_TASKBAR, 2).
-% From define::From gauge.h
+% From define::From gauge.h
-define(wxGAUGE_EMULATE_INDETERMINATE_MODE, 1).
-define(wxGA_SMOOTH, 32).
-define(wxGA_VERTICAL, ?wxVERTICAL).
-define(wxGA_HORIZONTAL, ?wxHORIZONTAL).
-% From define::From gdicmn.h
+% From define::From gdicmn.h
-define(wxGetDisplayDepth, ?wxDisplayDepth).
-% From define::From generic_2laywin.h
+% From define::From generic_2laywin.h
-define(wxLAYOUT_QUERY, 256).
-define(wxLAYOUT_MRU_LENGTH, 16).
-define(wxLAYOUT_LENGTH_X, 0).
-define(wxLAYOUT_LENGTH_Y, 8).
-% From define::From generic_2sashwin.h
+% From define::From generic_2sashwin.h
-define(wxSW_3D, (?wxSW_3DSASH bor ?wxSW_3DBORDER)).
-define(wxSW_3DBORDER, 128).
-define(wxSW_3DSASH, 64).
@@ -561,27 +561,27 @@
-define(wxSASH_DRAG_LEFT_DOWN, 2).
-define(wxSASH_DRAG_DRAGGING, 1).
-define(wxSASH_DRAG_NONE, 0).
-% From define::From generic_2splash.h
+% From define::From generic_2splash.h
-define(wxSPLASH_NO_TIMEOUT, 0).
-define(wxSPLASH_TIMEOUT, 4).
-define(wxSPLASH_NO_CENTRE, 0).
-define(wxSPLASH_CENTRE_ON_SCREEN, 2).
-define(wxSPLASH_CENTRE_ON_PARENT, 1).
-% From define::From hash.h
+% From define::From hash.h
-define(wxHASH_SIZE_DEFAULT, 1000).
-% From define::From htmlwin.h
+% From define::From htmlwin.h
-define(wxHW_DEFAULT_STYLE, ?wxHW_SCROLLBAR_AUTO).
-define(wxHW_NO_SELECTION, 8).
-define(wxHW_SCROLLBAR_AUTO, 4).
-define(wxHW_SCROLLBAR_NEVER, 2).
-% From define::From imaglist.h
+% From define::From imaglist.h
-define(wxIMAGELIST_DRAW_FOCUSED, 8).
-define(wxIMAGELIST_DRAW_SELECTED, 4).
-define(wxIMAGELIST_DRAW_TRANSPARENT, 2).
-define(wxIMAGELIST_DRAW_NORMAL, 1).
-% From define::From layout.h
+% From define::From layout.h
-define(wxLAYOUT_DEFAULT_MARGIN, 0).
-% From define::From listbase.h
+% From define::From listbase.h
-define(wxLIST_HITTEST_ONITEM, (?wxLIST_HITTEST_ONITEMICON bor ?wxLIST_HITTEST_ONITEMLABEL bor ?wxLIST_HITTEST_ONITEMSTATEICON)).
-define(wxLIST_HITTEST_TORIGHT, 2048).
-define(wxLIST_HITTEST_TOLEFT, 1024).
@@ -629,20 +629,20 @@
-define(wxLC_ICON, 4).
-define(wxLC_HRULES, 2).
-define(wxLC_VRULES, 1).
-% From define::From listbook.h
+% From define::From listbook.h
-define(wxLB_ALIGN_MASK, ?wxBK_ALIGN_MASK).
-define(wxLB_RIGHT, ?wxBK_RIGHT).
-define(wxLB_LEFT, ?wxBK_LEFT).
-define(wxLB_BOTTOM, ?wxBK_BOTTOM).
-define(wxLB_TOP, ?wxBK_TOP).
-define(wxLB_DEFAULT, ?wxBK_DEFAULT).
-% From define::From log.h
+% From define::From log.h
-define(wxTRACE_OleCalls, ?wxEmptyString).
-define(wxTraceRefCount, 8).
-define(wxTraceResAlloc, 4).
-define(wxTraceMessages, 2).
-define(wxTraceMemAlloc, 1).
-% From define::From notebook.h
+% From define::From notebook.h
-define(wxNB_FLAT, 2048).
-define(wxNB_NOPAGETHEME, 1024).
-define(wxNB_MULTILINE, 512).
@@ -652,9 +652,9 @@
-define(wxNB_BOTTOM, ?wxBK_BOTTOM).
-define(wxNB_TOP, ?wxBK_TOP).
-define(wxNB_DEFAULT, ?wxBK_DEFAULT).
-% From define::From pickerbase.h
+% From define::From pickerbase.h
-define(wxPB_USE_TEXTCTRL, 2).
-% From define::From prntbase.h
+% From define::From prntbase.h
-define(wxID_PREVIEW_GOTO, 8).
-define(wxID_PREVIEW_LAST, 7).
-define(wxID_PREVIEW_FIRST, 6).
@@ -671,7 +671,7 @@
-define(wxPREVIEW_NEXT, 4).
-define(wxPREVIEW_PREVIOUS, 2).
-define(wxPREVIEW_PRINT, 1).
-% From define::From progdlg.h
+% From define::From progdlg.h
-define(wxPD_CAN_SKIP, 128).
-define(wxPD_REMAINING_TIME, 64).
-define(wxPD_SMOOTH, 32).
@@ -680,9 +680,9 @@
-define(wxPD_AUTO_HIDE, 4).
-define(wxPD_APP_MODAL, 2).
-define(wxPD_CAN_ABORT, 1).
-% From define::From scrolwin.h
+% From define::From scrolwin.h
-define(wxScrolledWindowStyle, (?wxHSCROLL bor ?wxVSCROLL)).
-% From define::From slider.h
+% From define::From slider.h
-define(wxSL_INVERSE, 4096).
-define(wxSL_SELRANGE, 2048).
-define(wxSL_BOTH, 1024).
@@ -695,7 +695,7 @@
-define(wxSL_TICKS, 16).
-define(wxSL_VERTICAL, ?wxVERTICAL).
-define(wxSL_HORIZONTAL, ?wxHORIZONTAL).
-% From define::From splitter.h
+% From define::From splitter.h
-define(wxSP_3D, (?wxSP_3DBORDER bor ?wxSP_3DSASH)).
-define(wxSP_BORDER, ?wxSP_3DBORDER).
-define(wxSP_NO_XP_THEME, 1024).
@@ -705,11 +705,11 @@
-define(wxSP_PERMIT_UNSPLIT, 64).
-define(wxSP_NOSASH, 16).
-define(wxSP_NOBORDER, 0).
-% From define::From statusbr.h
+% From define::From statusbr.h
-define(wxSB_RAISED, 2).
-define(wxSB_FLAT, 1).
-define(wxSB_NORMAL, 0).
-% From define::From stc.h
+% From define::From stc.h
-define(wxSTC_CMD_WORDRIGHTENDEXTEND, 2442).
-define(wxSTC_CMD_WORDRIGHTEND, 2441).
-define(wxSTC_CMD_WORDLEFTENDEXTEND, 2440).
@@ -2045,7 +2045,7 @@
-define(wxSTC_START, 2000).
-define(wxSTC_INVALID_POSITION, -1).
-define(wxSTC_USE_POPUP, 1).
-% From define::From textctrl.h
+% From define::From textctrl.h
-define(wxTEXT_ATTR_TABS, 1024).
-define(wxTEXT_ATTR_RIGHT_INDENT, 512).
-define(wxTEXT_ATTR_LEFT_INDENT, 256).
@@ -2080,11 +2080,11 @@
-define(wxTE_AUTO_SCROLL, 8).
-define(wxTE_NO_VSCROLL, 2).
-define(wxHAS_TEXT_WINDOW_STREAM, 0).
-% From define::From textdlgg.h
+% From define::From textdlgg.h
-define(wxTextEntryDialogStyle, (?wxOK bor ?wxCANCEL bor ?wxCENTRE bor ?wxWS_EX_VALIDATE_RECURSIVELY)).
-% From define::From toolbook.h
+% From define::From toolbook.h
-define(wxBK_BUTTONBAR, 256).
-% From define::From toplevel.h
+% From define::From toplevel.h
-define(wxTOPLEVEL_EX_DIALOG, 8).
-define(wxDEFAULT_FRAME_STYLE, (?wxSYSTEM_MENU bor ?wxRESIZE_BORDER bor ?wxMINIMIZE_BOX bor ?wxMAXIMIZE_BOX bor ?wxCLOSE_BOX bor ?wxCAPTION bor ?wxCLIP_CHILDREN)).
-define(wxRESIZE_BORDER, 64).
@@ -2098,7 +2098,7 @@
-define(wxMINIMIZE, ?wxICONIZE).
-define(wxICONIZE, 16384).
-define(wxSTAY_ON_TOP, 32768).
-% From define::From treebase.h
+% From define::From treebase.h
-define(wxTR_DEFAULT_STYLE, (?wxTR_HAS_BUTTONS bor ?wxTR_LINES_AT_ROOT)).
-define(wxTR_FULL_ROW_HIGHLIGHT, 8192).
-define(wxTR_HIDE_ROOT, 2048).
@@ -2113,7 +2113,7 @@
-define(wxTR_NO_LINES, 4).
-define(wxTR_HAS_BUTTONS, 1).
-define(wxTR_NO_BUTTONS, 0).
-% From define::From valtext.h
+% From define::From valtext.h
-define(wxFILTER_EXCLUDE_CHAR_LIST, 128).
-define(wxFILTER_INCLUDE_CHAR_LIST, 64).
-define(wxFILTER_EXCLUDE_LIST, 32).
@@ -2123,20 +2123,20 @@
-define(wxFILTER_ALPHA, 2).
-define(wxFILTER_ASCII, 1).
-define(wxFILTER_NONE, 0).
-% From define::From version.h
+% From define::From version.h
-define(wxBETA_NUMBER, wxe_util:get_const(wxBETA_NUMBER)).
-define(wxSUBRELEASE_NUMBER, wxe_util:get_const(wxSUBRELEASE_NUMBER)).
-define(wxRELEASE_NUMBER, wxe_util:get_const(wxRELEASE_NUMBER)).
-define(wxMINOR_VERSION, wxe_util:get_const(wxMINOR_VERSION)).
-define(wxMAJOR_VERSION, wxe_util:get_const(wxMAJOR_VERSION)).
-% From class wxAuiManager
+% From class wxAuiManager
-define(wxAuiManager_actionNone, 0).
-define(wxAuiManager_actionResize, 1).
-define(wxAuiManager_actionClickButton, 2).
-define(wxAuiManager_actionClickCaption, 3).
-define(wxAuiManager_actionDragToolbarPane, 4).
-define(wxAuiManager_actionDragFloatingPane, 5).
-% From wxAuiPaneInfo::wxAuiPaneState
+% From wxAuiPaneInfo::wxAuiPaneState
-define(wxAuiPaneInfo_optionFloating, 1).
-define(wxAuiPaneInfo_optionHidden, 2).
-define(wxAuiPaneInfo_optionLeftDockable, 4).
@@ -2164,15 +2164,15 @@
-define(wxAuiPaneInfo_buttonCustom3, 268435456).
-define(wxAuiPaneInfo_savedHiddenState, 1073741824).
-define(wxAuiPaneInfo_actionPane, 2147483648).
-% From wxBitmap::Representation
+% From wxBitmap::Representation
-define(wxBitmap_Pixmap, 0).
-define(wxBitmap_Pixbuf, 1).
-% From class wxChoicebook
+% From class wxChoicebook
-define(wxChoicebook_SetSelection_SendEvent, 1).
-% From wxDateTime::Calendar
+% From wxDateTime::Calendar
-define(wxDateTime_Gregorian, 0).
-define(wxDateTime_Julian, 1).
-% From wxDateTime::Country
+% From wxDateTime::Country
-define(wxDateTime_Country_Unknown, 0).
-define(wxDateTime_Country_Default, 1).
-define(wxDateTime_Country_WesternEurope_Start, 2).
@@ -2183,7 +2183,7 @@
-define(wxDateTime_Country_WesternEurope_End, ?UK).
-define(wxDateTime_Russia, (?UK+1)).
-define(wxDateTime_USA, (?UK+2)).
-% From wxDateTime::GregorianAdoption
+% From wxDateTime::GregorianAdoption
-define(wxDateTime_Gr_Unknown, 0).
-define(wxDateTime_Gr_Standard, 1).
-define(wxDateTime_Gr_Alaska, 2).
@@ -2248,7 +2248,7 @@
-define(wxDateTime_Gr_USA, ?Gr_GreatBritain).
-define(wxDateTime_Gr_Wales, ?Gr_GreatBritain).
-define(wxDateTime_Gr_Yugoslavia, (?Gr_GreatBritain+1)).
-% From wxDateTime::Month
+% From wxDateTime::Month
-define(wxDateTime_Jan, 0).
-define(wxDateTime_Feb, 1).
-define(wxDateTime_Mar, 2).
@@ -2262,10 +2262,10 @@
-define(wxDateTime_Nov, 10).
-define(wxDateTime_Dec, 11).
-define(wxDateTime_Inv_Month, 12).
-% From wxDateTime::NameFlags
+% From wxDateTime::NameFlags
-define(wxDateTime_Name_Full, 1).
-define(wxDateTime_Name_Abbr, 2).
-% From wxDateTime::TZ
+% From wxDateTime::TZ
-define(wxDateTime_Local, 0).
-define(wxDateTime_GMT_12, 1).
-define(wxDateTime_GMT_11, 2).
@@ -2321,7 +2321,7 @@
-define(wxDateTime_NZST, ?GMT12).
-define(wxDateTime_NZDT, ?GMT13).
-define(wxDateTime_UTC, ?GMT0).
-% From wxDateTime::WeekDay
+% From wxDateTime::WeekDay
-define(wxDateTime_Sun, 0).
-define(wxDateTime_Mon, 1).
-define(wxDateTime_Tue, 2).
@@ -2330,93 +2330,93 @@
-define(wxDateTime_Fri, 5).
-define(wxDateTime_Sat, 6).
-define(wxDateTime_Inv_WeekDay, 7).
-% From wxDateTime::WeekFlags
+% From wxDateTime::WeekFlags
-define(wxDateTime_Default_First, 0).
-define(wxDateTime_Monday_First, 1).
-define(wxDateTime_Sunday_First, 2).
-% From wxDateTime::Year
+% From wxDateTime::Year
-define(wxDateTime_Inv_Year, ?SHRT_MIN).
-% From class wxDialog
+% From class wxDialog
-define(wxDialog_ButtonSizerFlags, (?wxOK bor ?wxCANCEL bor ?wxYES bor ?wxNO bor ?wxHELP bor ?wxNO_DEFAULT)).
-% From class wxGrid
+% From class wxGrid
-define(wxGrid_wxGRID_CELLCTRL, 2000).
-define(wxGrid_wxGRID_TOPCTRL, 2001).
-% From class wxGrid
+% From class wxGrid
-define(wxGrid_wxGRID_TEXTCTRL, 2100).
-define(wxGrid_wxGRID_CHECKBOX, 2101).
-define(wxGrid_wxGRID_CHOICE, 2102).
-define(wxGrid_wxGRID_COMBOBOX, 2103).
-% From wxGrid::CursorMode
+% From wxGrid::CursorMode
-define(wxGrid_WXGRID_CURSOR_SELECT_CELL, 0).
-define(wxGrid_WXGRID_CURSOR_RESIZE_ROW, 1).
-define(wxGrid_WXGRID_CURSOR_RESIZE_COL, 2).
-define(wxGrid_WXGRID_CURSOR_SELECT_ROW, 3).
-define(wxGrid_WXGRID_CURSOR_SELECT_COL, 4).
-define(wxGrid_WXGRID_CURSOR_MOVE_COL, 5).
-% From wxGrid::wxGridSelectionModes
+% From wxGrid::wxGridSelectionModes
-define(wxGrid_wxGridSelectCells, 0).
-define(wxGrid_wxGridSelectRows, 1).
-define(wxGrid_wxGridSelectColumns, 2).
-% From wxGridCellAttr::wxAttrKind
+% From wxGridCellAttr::wxAttrKind
-define(wxGridCellAttr_Any, 0).
-define(wxGridCellAttr_Default, 1).
-define(wxGridCellAttr_Cell, 2).
-define(wxGridCellAttr_Row, 3).
-define(wxGridCellAttr_Col, 4).
-define(wxGridCellAttr_Merged, 5).
-% From wxGridCellAttr::wxAttrOverflowMode
+% From wxGridCellAttr::wxAttrOverflowMode
-define(wxGridCellAttr_UnsetOverflow, -1).
-define(wxGridCellAttr_Overflow, 0).
-define(wxGridCellAttr_SingleCell, 1).
-% From wxGridCellAttr::wxAttrReadMode
+% From wxGridCellAttr::wxAttrReadMode
-define(wxGridCellAttr_Unset, -1).
-define(wxGridCellAttr_ReadWrite, 0).
-define(wxGridCellAttr_ReadOnly, 1).
-% From wxHelpEvent::Origin
+% From wxHelpEvent::Origin
-define(wxHelpEvent_Origin_Unknown, 0).
-define(wxHelpEvent_Origin_Keyboard, 1).
-define(wxHelpEvent_Origin_HelpButton, 2).
-% From wxHtmlEasyPrinting::FontMode
+% From wxHtmlEasyPrinting::FontMode
-define(wxHtmlEasyPrinting_FontMode_Explicit, 0).
-define(wxHtmlEasyPrinting_FontMode_Standard, 1).
-% From wxHtmlWindow::ClipboardType
+% From wxHtmlWindow::ClipboardType
-define(wxHtmlWindow_Primary, 0).
-define(wxHtmlWindow_Secondary, 1).
-% From class wxListbook
+% From class wxListbook
-define(wxListbook_SetSelection_SendEvent, 1).
-% From class wxNavigationKeyEvent
+% From class wxNavigationKeyEvent
-define(wxNavigationKeyEvent_IsBackward, 0).
-define(wxNavigationKeyEvent_IsForward, 1).
-define(wxNavigationKeyEvent_WinChange, 2).
-define(wxNavigationKeyEvent_FromTab, 4).
-% From class wxNotebook
+% From class wxNotebook
-define(wxNotebook_SetSelection_SendEvent, 1).
-% From class wxProgressDialog
+% From class wxProgressDialog
-define(wxProgressDialog_Uncancelable, -1).
-define(wxProgressDialog_Canceled, 0).
-define(wxProgressDialog_Continue, 1).
-define(wxProgressDialog_Finished, 2).
-% From class wxSizerItem
+% From class wxSizerItem
-define(wxSizerItem_Item_None, 0).
-define(wxSizerItem_Item_Window, 1).
-define(wxSizerItem_Item_Sizer, 2).
-define(wxSizerItem_Item_Spacer, 3).
-define(wxSizerItem_Item_Max, 4).
-% From class wxTextCtrl
+% From class wxTextCtrl
-define(wxTextCtrl_SetValue_SendEvent, 1).
-define(wxTextCtrl_SetValue_SelectionOnly, 2).
-% From class wxToolbook
+% From class wxToolbook
-define(wxToolbook_SetSelection_SendEvent, 1).
-% From class wxTreebook
+% From class wxTreebook
-define(wxTreebook_SetSelection_SendEvent, 1).
-% From wxWindow::MoveKind
+% From wxWindow::MoveKind
-define(wxWindow_MoveBefore, 0).
-define(wxWindow_MoveAfter, 1).
-% From wxWindowGTK::ScrollDir
+% From wxWindowGTK::ScrollDir
-define(wxWindowGTK_ScrollDir_Horz, 0).
-define(wxWindowGTK_ScrollDir_Vert, 1).
-define(wxWindowGTK_ScrollDir_Max, 2).
-% From wxWindowGTK::ScrollUnit
+% From wxWindowGTK::ScrollUnit
-define(wxWindowGTK_ScrollUnit_Line, 0).
-define(wxWindowGTK_ScrollUnit_Page, 1).
-define(wxWindowGTK_ScrollUnit_Max, 2).
@@ -2739,10 +2739,10 @@
-define(wxMM_ANISOTROPIC, 8).
-define(wxMM_POINTS, 9).
-define(wxMM_METRIC, 10).
-% Type Propagation_state
+% Type Propagation_state
-define(wxEVENT_PROPAGATE_NONE, 0).
-define(wxEVENT_PROPAGATE_MAX, ?INT_MAX).
-% Type form_ops_t
+% Type form_ops_t
-define(wxCLEAR, 0).
-define(wxROP_BLACK, ?wxCLEAR).
-define(wxBLIT_BLACKNESS, ?wxCLEAR).
@@ -2791,7 +2791,7 @@
-define(wxSET, (?wxOR+1)).
-define(wxROP_WHITE, ?wxSET).
-define(wxBLIT_WHITENESS, ?wxSET).
-% Type wxAlignment
+% Type wxAlignment
-define(wxALIGN_NOT, 0).
-define(wxALIGN_CENTER_HORIZONTAL, 256).
-define(wxALIGN_CENTRE_HORIZONTAL, ?wxALIGN_CENTER_HORIZONTAL).
@@ -2804,7 +2804,7 @@
-define(wxALIGN_CENTER, (?wxALIGN_CENTER_HORIZONTAL bor ?wxALIGN_CENTER_VERTICAL)).
-define(wxALIGN_CENTRE, ?wxALIGN_CENTER).
-define(wxALIGN_MASK, 3840).
-% Type wxAuiButtonId
+% Type wxAuiButtonId
-define(wxAUI_BUTTON_CLOSE, 101).
-define(wxAUI_BUTTON_MAXIMIZE_RESTORE, 102).
-define(wxAUI_BUTTON_MINIMIZE, 103).
@@ -2818,7 +2818,7 @@
-define(wxAUI_BUTTON_CUSTOM1, 201).
-define(wxAUI_BUTTON_CUSTOM2, 202).
-define(wxAUI_BUTTON_CUSTOM3, 203).
-% Type wxAuiManagerDock
+% Type wxAuiManagerDock
-define(wxAUI_DOCK_NONE, 0).
-define(wxAUI_DOCK_TOP, 1).
-define(wxAUI_DOCK_RIGHT, 2).
@@ -2826,7 +2826,7 @@
-define(wxAUI_DOCK_LEFT, 4).
-define(wxAUI_DOCK_CENTER, 5).
-define(wxAUI_DOCK_CENTRE, ?wxAUI_DOCK_CENTER).
-% Type wxAuiManagerOption
+% Type wxAuiManagerOption
-define(wxAUI_MGR_ALLOW_FLOATING, 1).
-define(wxAUI_MGR_ALLOW_ACTIVE_PANE, 2).
-define(wxAUI_MGR_TRANSPARENT_DRAG, 4).
@@ -2837,7 +2837,7 @@
-define(wxAUI_MGR_NO_VENETIAN_BLINDS_FADE, 128).
-define(wxAUI_MGR_LIVE_RESIZE, 256).
-define(wxAUI_MGR_DEFAULT, (?wxAUI_MGR_ALLOW_FLOATING bor ?wxAUI_MGR_TRANSPARENT_HINT bor ?wxAUI_MGR_HINT_FADE bor ?wxAUI_MGR_NO_VENETIAN_BLINDS_FADE)).
-% Type wxAuiNotebookOption
+% Type wxAuiNotebookOption
-define(wxAUI_NB_TOP, 1).
-define(wxAUI_NB_LEFT, 2).
-define(wxAUI_NB_RIGHT, 4).
@@ -2853,18 +2853,18 @@
-define(wxAUI_NB_CLOSE_ON_ALL_TABS, 4096).
-define(wxAUI_NB_MIDDLE_CLICK_CLOSE, 8192).
-define(wxAUI_NB_DEFAULT_STYLE, (?wxAUI_NB_TOP bor ?wxAUI_NB_TAB_SPLIT bor ?wxAUI_NB_TAB_MOVE bor ?wxAUI_NB_SCROLL_BUTTONS bor ?wxAUI_NB_CLOSE_ON_ACTIVE_TAB bor ?wxAUI_NB_MIDDLE_CLICK_CLOSE)).
-% Type wxAuiPaneButtonState
+% Type wxAuiPaneButtonState
-define(wxAUI_BUTTON_STATE_NORMAL, 0).
-define(wxAUI_BUTTON_STATE_HOVER, 2).
-define(wxAUI_BUTTON_STATE_PRESSED, 4).
-define(wxAUI_BUTTON_STATE_DISABLED, 8).
-define(wxAUI_BUTTON_STATE_HIDDEN, 16).
-define(wxAUI_BUTTON_STATE_CHECKED, 32).
-% Type wxAuiPaneDockArtGradients
+% Type wxAuiPaneDockArtGradients
-define(wxAUI_GRADIENT_NONE, 0).
-define(wxAUI_GRADIENT_VERTICAL, 1).
-define(wxAUI_GRADIENT_HORIZONTAL, 2).
-% Type wxAuiPaneDockArtSetting
+% Type wxAuiPaneDockArtSetting
-define(wxAUI_DOCKART_SASH_SIZE, 0).
-define(wxAUI_DOCKART_CAPTION_SIZE, 1).
-define(wxAUI_DOCKART_GRIPPER_SIZE, 2).
@@ -2882,15 +2882,15 @@
-define(wxAUI_DOCKART_GRIPPER_COLOUR, 14).
-define(wxAUI_DOCKART_CAPTION_FONT, 15).
-define(wxAUI_DOCKART_GRADIENT_TYPE, 16).
-% Type wxAuiPaneInsertLevel
+% Type wxAuiPaneInsertLevel
-define(wxAUI_INSERT_PANE, 0).
-define(wxAUI_INSERT_ROW, 1).
-define(wxAUI_INSERT_DOCK, 2).
-% Type wxBackgroundStyle
+% Type wxBackgroundStyle
-define(wxBG_STYLE_SYSTEM, 0).
-define(wxBG_STYLE_COLOUR, 1).
-define(wxBG_STYLE_CUSTOM, 2).
-% Type wxBitmapType
+% Type wxBitmapType
-define(wxBITMAP_TYPE_INVALID, 0).
-define(wxBITMAP_TYPE_BMP, 1).
-define(wxBITMAP_TYPE_BMP_RESOURCE, 2).
@@ -2925,7 +2925,7 @@
-define(wxBITMAP_TYPE_MACCURSOR, (?wxBITMAP_TYPE_BMP_RESOURCE+28)).
-define(wxBITMAP_TYPE_MACCURSOR_RESOURCE, (?wxBITMAP_TYPE_BMP_RESOURCE+29)).
-define(wxBITMAP_TYPE_ANY, 50).
-% Type wxBorder
+% Type wxBorder
-define(wxBORDER_DEFAULT, 0).
-define(wxBORDER_NONE, 2097152).
-define(wxBORDER_STATIC, 16777216).
@@ -2935,26 +2935,26 @@
-define(wxBORDER_DOUBLE, 268435456).
-define(wxBORDER_THEME, 268435456).
-define(wxBORDER_MASK, 522190848).
-% Type wxCalendarDateBorder
+% Type wxCalendarDateBorder
-define(wxCAL_BORDER_NONE, 0).
-define(wxCAL_BORDER_SQUARE, 1).
-define(wxCAL_BORDER_ROUND, 2).
-% Type wxCalendarHitTestResult
+% Type wxCalendarHitTestResult
-define(wxCAL_HITTEST_NOWHERE, 0).
-define(wxCAL_HITTEST_HEADER, 1).
-define(wxCAL_HITTEST_DAY, 2).
-define(wxCAL_HITTEST_INCMONTH, 3).
-define(wxCAL_HITTEST_DECMONTH, 4).
-define(wxCAL_HITTEST_SURROUNDING_WEEK, 5).
-% Type wxCheckBoxState
+% Type wxCheckBoxState
-define(wxCHK_UNCHECKED, 0).
-define(wxCHK_CHECKED, 1).
-define(wxCHK_UNDETERMINED, 2).
-% Type wxClientDataType
+% Type wxClientDataType
-define(wxClientData_None, 0).
-define(wxClientData_Object, 1).
-define(wxClientData_Void, 2).
-% Type wxDataFormatId
+% Type wxDataFormatId
-define(wxDF_INVALID, 0).
-define(wxDF_TEXT, 1).
-define(wxDF_BITMAP, 2).
@@ -2975,7 +2975,7 @@
-define(wxDF_PRIVATE, 20).
-define(wxDF_HTML, 30).
-define(wxDF_MAX, 31).
-% Type wxDirection
+% Type wxDirection
-define(wxLEFT, 16).
-define(wxRIGHT, 32).
-define(wxUP, 64).
@@ -2987,18 +2987,18 @@
-define(wxWEST, ?wxLEFT).
-define(wxEAST, ?wxRIGHT).
-define(wxALL, (?wxUP bor ?wxDOWN bor ?wxRIGHT bor ?wxLEFT)).
-% Type wxDragResult
+% Type wxDragResult
-define(wxDragError, 0).
-define(wxDragNone, 1).
-define(wxDragCopy, 2).
-define(wxDragMove, 3).
-define(wxDragLink, 4).
-define(wxDragCancel, 5).
-% Type wxDuplexMode
+% Type wxDuplexMode
-define(wxDUPLEX_SIMPLEX, 0).
-define(wxDUPLEX_HORIZONTAL, 1).
-define(wxDUPLEX_VERTICAL, 2).
-% Type wxEdge
+% Type wxEdge
-define(wxLeft, 0).
-define(wxTop, 1).
-define(wxRight, 2).
@@ -3009,20 +3009,20 @@
-define(wxCenter, ?wxCentre).
-define(wxCentreX, (?wxCentre+1)).
-define(wxCentreY, (?wxCentre+2)).
-% Type wxFindReplaceDialogStyles
+% Type wxFindReplaceDialogStyles
-define(wxFR_REPLACEDIALOG, 1).
-define(wxFR_NOUPDOWN, 2).
-define(wxFR_NOMATCHCASE, 4).
-define(wxFR_NOWHOLEWORD, 8).
-% Type wxFindReplaceFlags
+% Type wxFindReplaceFlags
-define(wxFR_DOWN, 1).
-define(wxFR_WHOLEWORD, 2).
-define(wxFR_MATCHCASE, 4).
-% Type wxFlexSizerGrowMode
+% Type wxFlexSizerGrowMode
-define(wxFLEX_GROWMODE_NONE, 0).
-define(wxFLEX_GROWMODE_SPECIFIED, 1).
-define(wxFLEX_GROWMODE_ALL, 2).
-% Type wxFontEncoding
+% Type wxFontEncoding
-define(wxFONTENCODING_SYSTEM, -1).
-define(wxFONTENCODING_DEFAULT, 0).
-define(wxFONTENCODING_ISO8859_1, 1).
@@ -3120,7 +3120,7 @@
-define(wxFONTENCODING_GB2312, ?wxFONTENCODING_CP936).
-define(wxFONTENCODING_BIG5, ?wxFONTENCODING_CP950).
-define(wxFONTENCODING_SHIFT_JIS, ?wxFONTENCODING_CP932).
-% Type wxFontFamily
+% Type wxFontFamily
-define(wxFONTFAMILY_DEFAULT, ?wxDEFAULT).
-define(wxFONTFAMILY_DECORATIVE, ?wxDECORATIVE).
-define(wxFONTFAMILY_ROMAN, ?wxROMAN).
@@ -3130,20 +3130,20 @@
-define(wxFONTFAMILY_TELETYPE, ?wxTELETYPE).
-define(wxFONTFAMILY_MAX, (?wxTELETYPE+1)).
-define(wxFONTFAMILY_UNKNOWN, ?wxFONTFAMILY_MAX).
-% Type wxFontStyle
+% Type wxFontStyle
-define(wxFONTSTYLE_NORMAL, ?wxNORMAL).
-define(wxFONTSTYLE_ITALIC, ?wxITALIC).
-define(wxFONTSTYLE_SLANT, ?wxSLANT).
-define(wxFONTSTYLE_MAX, (?wxSLANT+1)).
-% Type wxFontWeight
+% Type wxFontWeight
-define(wxFONTWEIGHT_NORMAL, ?wxNORMAL).
-define(wxFONTWEIGHT_LIGHT, ?wxLIGHT).
-define(wxFONTWEIGHT_BOLD, ?wxBOLD).
-define(wxFONTWEIGHT_MAX, (?wxBOLD+1)).
-% Type wxGeometryCentre
+% Type wxGeometryCentre
-define(wxCENTRE, 1).
-define(wxCENTER, ?wxCENTRE).
-% Type wxHitTest
+% Type wxHitTest
-define(wxHT_NOWHERE, 0).
-define(wxHT_SCROLLBAR_FIRST, ?wxHT_NOWHERE).
-define(wxHT_SCROLLBAR_ARROW_LINE_1, (?wxHT_NOWHERE+1)).
@@ -3160,20 +3160,20 @@
-define(wxHT_WINDOW_HORZ_SCROLLBAR, (?wxHT_NOWHERE+12)).
-define(wxHT_WINDOW_CORNER, (?wxHT_NOWHERE+13)).
-define(wxHT_MAX, (?wxHT_NOWHERE+14)).
-% Type wxHtmlOpeningStatus
+% Type wxHtmlOpeningStatus
-define(wxHTML_OPEN, 0).
-define(wxHTML_BLOCK, 1).
-define(wxHTML_REDIRECT, 2).
-% Type wxIdleMode
+% Type wxIdleMode
-define(wxIDLE_PROCESS_ALL, 0).
-define(wxIDLE_PROCESS_SPECIFIED, 1).
-% Type wxItemKind
+% Type wxItemKind
-define(wxITEM_SEPARATOR, -1).
-define(wxITEM_NORMAL, 0).
-define(wxITEM_CHECK, 1).
-define(wxITEM_RADIO, 2).
-define(wxITEM_MAX, 3).
-% Type wxKeyCode
+% Type wxKeyCode
-define(WXK_BACK, 8).
-define(WXK_TAB, 9).
-define(WXK_RETURN, 13).
@@ -3297,7 +3297,7 @@
-define(WXK_SPECIAL18, 210).
-define(WXK_SPECIAL19, 211).
-define(WXK_SPECIAL20, 212).
-% Type wxKeyModifier
+% Type wxKeyModifier
-define(wxMOD_NONE, 0).
-define(wxMOD_ALT, 1).
-define(wxMOD_CONTROL, 2).
@@ -3307,46 +3307,46 @@
-define(wxMOD_WIN, ?wxMOD_META).
-define(wxMOD_CMD, wxe_util:get_const(wxMOD_CMD)).
-define(wxMOD_ALL, 65535).
-% Type wxKeyType
+% Type wxKeyType
-define(wxKEY_NONE, 0).
-define(wxKEY_INTEGER, 1).
-define(wxKEY_STRING, 2).
-% Type wxKillError
+% Type wxKillError
-define(wxKILL_OK, 0).
-define(wxKILL_BAD_SIGNAL, 1).
-define(wxKILL_ACCESS_DENIED, 2).
-define(wxKILL_NO_PROCESS, 3).
-define(wxKILL_ERROR, 4).
-% Type wxKillFlags
+% Type wxKillFlags
-define(wxKILL_NOCHILDREN, 0).
-define(wxKILL_CHILDREN, 1).
-% Type wxLayoutAlignment
+% Type wxLayoutAlignment
-define(wxLAYOUT_NONE, 0).
-define(wxLAYOUT_TOP, 1).
-define(wxLAYOUT_LEFT, 2).
-define(wxLAYOUT_RIGHT, 3).
-define(wxLAYOUT_BOTTOM, 4).
-% Type wxLayoutDirection
+% Type wxLayoutDirection
-define(wxLayout_Default, 0).
-define(wxLayout_LeftToRight, 1).
-define(wxLayout_RightToLeft, 2).
-% Type wxLayoutOrientation
+% Type wxLayoutOrientation
-define(wxLAYOUT_HORIZONTAL, 0).
-define(wxLAYOUT_VERTICAL, 1).
-% Type wxListColumnFormat
+% Type wxListColumnFormat
-define(wxLIST_FORMAT_LEFT, 0).
-define(wxLIST_FORMAT_RIGHT, 1).
-define(wxLIST_FORMAT_CENTRE, 2).
-define(wxLIST_FORMAT_CENTER, ?wxLIST_FORMAT_CENTRE).
-% Type wxNotificationOptions
+% Type wxNotificationOptions
-define(wxNOTIFY_NONE, 0).
-define(wxNOTIFY_ONCE, 1).
-define(wxNOTIFY_REPEAT, 2).
-% Type wxOrientation
+% Type wxOrientation
-define(wxHORIZONTAL, 4).
-define(wxVERTICAL, 8).
-define(wxBOTH, (?wxVERTICAL bor ?wxHORIZONTAL)).
-% Type wxPaperSize
+% Type wxPaperSize
-define(wxPAPER_NONE, 0).
-define(wxPAPER_LETTER, 1).
-define(wxPAPER_LEGAL, 2).
@@ -3464,7 +3464,7 @@
-define(wxPAPER_PENV_8_ROTATED, 114).
-define(wxPAPER_PENV_9_ROTATED, 115).
-define(wxPAPER_PENV_10_ROTATED, 116).
-% Type wxPrintBin
+% Type wxPrintBin
-define(wxPRINTBIN_DEFAULT, 0).
-define(wxPRINTBIN_ONLYONE, 1).
-define(wxPRINTBIN_LOWER, 2).
@@ -3480,27 +3480,27 @@
-define(wxPRINTBIN_CASSETTE, 12).
-define(wxPRINTBIN_FORMSOURCE, 13).
-define(wxPRINTBIN_USER, 14).
-% Type wxPrintMode
+% Type wxPrintMode
-define(wxPRINT_MODE_NONE, 0).
-define(wxPRINT_MODE_PREVIEW, 1).
-define(wxPRINT_MODE_FILE, 2).
-define(wxPRINT_MODE_PRINTER, 3).
-define(wxPRINT_MODE_STREAM, 4).
-% Type wxPrinterError
+% Type wxPrinterError
-define(wxPRINTER_NO_ERROR, 0).
-define(wxPRINTER_CANCELLED, 1).
-define(wxPRINTER_ERROR, 2).
-% Type wxRegionContain
+% Type wxRegionContain
-define(wxOutRegion, 0).
-define(wxPartRegion, 1).
-define(wxInRegion, 2).
-% Type wxRegionOp
+% Type wxRegionOp
-define(wxRGN_AND, 0).
-define(wxRGN_COPY, 1).
-define(wxRGN_DIFF, 2).
-define(wxRGN_OR, 3).
-define(wxRGN_XOR, 4).
-% Type wxRelationship
+% Type wxRelationship
-define(wxUnconstrained, 0).
-define(wxAsIs, 1).
-define(wxPercentOf, 2).
@@ -3510,19 +3510,19 @@
-define(wxRightOf, 6).
-define(wxSameAs, 7).
-define(wxAbsolute, 8).
-% Type wxSashDragStatus
+% Type wxSashDragStatus
-define(wxSASH_STATUS_OK, 0).
-define(wxSASH_STATUS_OUT_OF_RANGE, 1).
-% Type wxSashEdgePosition
+% Type wxSashEdgePosition
-define(wxSASH_TOP, 0).
-define(wxSASH_RIGHT, 1).
-define(wxSASH_BOTTOM, 2).
-define(wxSASH_LEFT, 3).
-define(wxSASH_NONE, 100).
-% Type wxShutdownFlags
+% Type wxShutdownFlags
-define(wxSHUTDOWN_POWEROFF, 0).
-define(wxSHUTDOWN_REBOOT, 1).
-% Type wxSignal
+% Type wxSignal
-define(wxSIGNONE, 0).
-define(wxSIGHUP, 1).
-define(wxSIGINT, 2).
@@ -3540,10 +3540,10 @@
-define(wxSIGPIPE, (?wxSIGABRT+7)).
-define(wxSIGALRM, (?wxSIGABRT+8)).
-define(wxSIGTERM, (?wxSIGABRT+9)).
-% Type wxSplitMode
+% Type wxSplitMode
-define(wxSPLIT_HORIZONTAL, 1).
-define(wxSPLIT_VERTICAL, 2).
-% Type wxStockCursor
+% Type wxStockCursor
-define(wxCURSOR_NONE, 0).
-define(wxCURSOR_ARROW, 1).
-define(wxCURSOR_RIGHT_ARROW, 2).
@@ -3574,7 +3574,7 @@
-define(wxCURSOR_DEFAULT, 27).
-define(wxCURSOR_ARROWWAIT, 28).
-define(wxCURSOR_MAX, 29).
-% Type wxStretch
+% Type wxStretch
-define(wxSTRETCH_NOT, 0).
-define(wxSHRINK, 4096).
-define(wxGROW, 8192).
@@ -3584,7 +3584,7 @@
-define(wxRESERVE_SPACE_EVEN_IF_HIDDEN, 2).
-define(wxTILE, 49152).
-define(wxADJUST_MINSIZE, 0).
-% Type wxSystemColour
+% Type wxSystemColour
-define(wxSYS_COLOUR_SCROLLBAR, 0).
-define(wxSYS_COLOUR_BACKGROUND, 1).
-define(wxSYS_COLOUR_DESKTOP, ?wxSYS_COLOUR_BACKGROUND).
@@ -3624,11 +3624,11 @@
-define(wxSYS_COLOUR_MENUBAR, (?wxSYS_COLOUR_BTNHIGHLIGHT+10)).
-define(wxSYS_COLOUR_LISTBOXTEXT, (?wxSYS_COLOUR_BTNHIGHLIGHT+11)).
-define(wxSYS_COLOUR_MAX, (?wxSYS_COLOUR_BTNHIGHLIGHT+12)).
-% Type wxSystemFeature
+% Type wxSystemFeature
-define(wxSYS_CAN_DRAW_FRAME_DECORATIONS, 1).
-define(wxSYS_CAN_ICONIZE_FRAME, 2).
-define(wxSYS_TABLET_PRESENT, 3).
-% Type wxSystemFont
+% Type wxSystemFont
-define(wxSYS_OEM_FIXED_FONT, 10).
-define(wxSYS_ANSI_FIXED_FONT, 11).
-define(wxSYS_ANSI_VAR_FONT, 12).
@@ -3638,7 +3638,7 @@
-define(wxSYS_SYSTEM_FIXED_FONT, 16).
-define(wxSYS_DEFAULT_GUI_FONT, 17).
-define(wxSYS_ICONTITLE_FONT, ?wxSYS_DEFAULT_GUI_FONT).
-% Type wxSystemMetric
+% Type wxSystemMetric
-define(wxSYS_MOUSE_BUTTONS, 1).
-define(wxSYS_BORDER_X, 2).
-define(wxSYS_BORDER_Y, 3).
@@ -3676,49 +3676,49 @@
-define(wxSYS_PENWINDOWS_PRESENT, 35).
-define(wxSYS_SHOW_SOUNDS, 36).
-define(wxSYS_SWAP_BUTTONS, 37).
-% Type wxSystemScreenType
+% Type wxSystemScreenType
-define(wxSYS_SCREEN_NONE, 0).
-define(wxSYS_SCREEN_TINY, 1).
-define(wxSYS_SCREEN_PDA, 2).
-define(wxSYS_SCREEN_SMALL, 3).
-define(wxSYS_SCREEN_DESKTOP, 4).
-% Type wxTextAttrAlignment
+% Type wxTextAttrAlignment
-define(wxTEXT_ALIGNMENT_DEFAULT, 0).
-define(wxTEXT_ALIGNMENT_LEFT, 1).
-define(wxTEXT_ALIGNMENT_CENTRE, 2).
-define(wxTEXT_ALIGNMENT_CENTER, ?wxTEXT_ALIGNMENT_CENTRE).
-define(wxTEXT_ALIGNMENT_RIGHT, (?wxTEXT_ALIGNMENT_CENTRE+1)).
-define(wxTEXT_ALIGNMENT_JUSTIFIED, (?wxTEXT_ALIGNMENT_CENTRE+2)).
-% Type wxTextCtrlHitTestResult
+% Type wxTextCtrlHitTestResult
-define(wxTE_HT_UNKNOWN, -2).
-define(wxTE_HT_BEFORE, -1).
-define(wxTE_HT_ON_TEXT, 0).
-define(wxTE_HT_BELOW, 1).
-define(wxTE_HT_BEYOND, 2).
-% Type wxToolBarToolStyle
+% Type wxToolBarToolStyle
-define(wxTOOL_STYLE_BUTTON, 1).
-define(wxTOOL_STYLE_SEPARATOR, 2).
-define(wxTOOL_STYLE_CONTROL, 3).
-% Type wxTreeItemIcon
+% Type wxTreeItemIcon
-define(wxTreeItemIcon_Normal, 0).
-define(wxTreeItemIcon_Selected, 1).
-define(wxTreeItemIcon_Expanded, 2).
-define(wxTreeItemIcon_SelectedExpanded, 3).
-define(wxTreeItemIcon_Max, 4).
-% Type wxUpdateUI
+% Type wxUpdateUI
-define(wxUPDATE_UI_NONE, 0).
-define(wxUPDATE_UI_RECURSE, 1).
-define(wxUPDATE_UI_FROMIDLE, 2).
-% Type wxUpdateUIMode
+% Type wxUpdateUIMode
-define(wxUPDATE_UI_PROCESS_ALL, 0).
-define(wxUPDATE_UI_PROCESS_SPECIFIED, 1).
-% Type wxWindowVariant
+% Type wxWindowVariant
-define(wxWINDOW_VARIANT_NORMAL, 0).
-define(wxWINDOW_VARIANT_SMALL, 1).
-define(wxWINDOW_VARIANT_MINI, 2).
-define(wxWINDOW_VARIANT_LARGE, 3).
-define(wxWINDOW_VARIANT_MAX, 4).
-% Type wxXmlResourceFlags
+% Type wxXmlResourceFlags
-define(wxXRC_USE_LOCALE, 1).
-define(wxXRC_NO_SUBCLASSING, 2).
-define(wxXRC_NO_RELOADING, 4).
diff --git a/lib/wx/src/gen/gl.erl b/lib/wx/src/gen/gl.erl
index 8220acad98..d789f1b72f 100644
--- a/lib/wx/src/gen/gl.erl
+++ b/lib/wx/src/gen/gl.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%
%% OPENGL API
diff --git a/lib/wx/src/gen/gl_debug.hrl b/lib/wx/src/gen/gl_debug.hrl
index 8c25d94590..68225197cf 100644
--- a/lib/wx/src/gen/gl_debug.hrl
+++ b/lib/wx/src/gen/gl_debug.hrl
@@ -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%
%% This file is generated DO NOT EDIT
diff --git a/lib/wx/src/gen/glu.erl b/lib/wx/src/gen/glu.erl
index 9a06be4077..ae4bac4e06 100644
--- a/lib/wx/src/gen/glu.erl
+++ b/lib/wx/src/gen/glu.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%
%% OPENGL UTILITY API
diff --git a/lib/wx/src/gen/wxAcceleratorEntry.erl b/lib/wx/src/gen/wxAcceleratorEntry.erl
index 4c6d35829c..d76299b300 100644
--- a/lib/wx/src/gen/wxAcceleratorEntry.erl
+++ b/lib/wx/src/gen/wxAcceleratorEntry.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%
%% This file is generated DO NOT EDIT
@@ -39,7 +39,7 @@ new() ->
%% @spec (X::term()|wxAcceleratorEntry()) -> wxAcceleratorEntry()
%% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxacceleratorentry.html#wxacceleratorentrywxacceleratorentry">external documentation</a>.
-%% <br /> Alternatives:
+%% <br /> Alternatives:
%% <p><c>
%% new([Option]) -> wxAcceleratorEntry() </c>
%%<br /> Option = {flags, integer()} | {keyCode, integer()} | {cmd, integer()} | {item, wxMenuItem:wxMenuItem()}
@@ -103,7 +103,7 @@ set(#wx_ref{type=ThisT,ref=ThisRef},Flags,KeyCode,Cmd, Options)
%% @spec (This::wxAcceleratorEntry()) -> ok
%% @doc Destroys this object, do not use object again
-destroy(Obj=#wx_ref{type=Type}) ->
+destroy(Obj=#wx_ref{type=Type}) ->
?CLASS(Type,wxAcceleratorEntry),
wxe_util:destroy(?wxAcceleratorEntry_destroy,Obj),
ok.
diff --git a/lib/wx/src/gen/wxAcceleratorTable.erl b/lib/wx/src/gen/wxAcceleratorTable.erl
index f4f7f55f70..5d070294e2 100644
--- a/lib/wx/src/gen/wxAcceleratorTable.erl
+++ b/lib/wx/src/gen/wxAcceleratorTable.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%
%% This file is generated DO NOT EDIT
@@ -56,7 +56,7 @@ ok(#wx_ref{type=ThisT,ref=ThisRef}) ->
%% @spec (This::wxAcceleratorTable()) -> ok
%% @doc Destroys this object, do not use object again
-destroy(Obj=#wx_ref{type=Type}) ->
+destroy(Obj=#wx_ref{type=Type}) ->
?CLASS(Type,wxAcceleratorTable),
wxe_util:destroy(?DESTROY_OBJECT,Obj),
ok.
diff --git a/lib/wx/src/gen/wxArtProvider.erl b/lib/wx/src/gen/wxArtProvider.erl
index 4708f0844b..7a45b0d79d 100644
--- a/lib/wx/src/gen/wxArtProvider.erl
+++ b/lib/wx/src/gen/wxArtProvider.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%
%% This file is generated DO NOT EDIT
diff --git a/lib/wx/src/gen/wxAuiDockArt.erl b/lib/wx/src/gen/wxAuiDockArt.erl
index 9997e69dfd..f2be643dd9 100644
--- a/lib/wx/src/gen/wxAuiDockArt.erl
+++ b/lib/wx/src/gen/wxAuiDockArt.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%
%% This file is generated DO NOT EDIT
diff --git a/lib/wx/src/gen/wxAuiManager.erl b/lib/wx/src/gen/wxAuiManager.erl
index 7f46a36991..ad0af6652d 100644
--- a/lib/wx/src/gen/wxAuiManager.erl
+++ b/lib/wx/src/gen/wxAuiManager.erl
@@ -1,24 +1,24 @@
%%
%% %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%
%% This file is generated DO NOT EDIT
%% @doc See external documentation: <a href="http://www.wxwidgets.org/manuals/stable/wx_wxauimanager.html">wxAuiManager</a>.
-%% <p>This class is derived (and can use functions) from:
+%% <p>This class is derived (and can use functions) from:
%% <br />{@link wxEvtHandler}
%% </p>
%% @type wxAuiManager(). An object reference, The representation is internal
@@ -66,7 +66,7 @@ addPane(This,Window)
%% @spec (This::wxAuiManager(),Window::wxWindow:wxWindow(),X::term()) -> bool()
%% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxauimanager.html#wxauimanageraddpane">external documentation</a>.
-%% <br /> Alternatives:
+%% <br /> Alternatives:
%% <p><c>
%% addPane(This::wxAuiManager(), Window::wxWindow:wxWindow(), [Option]) -> bool() </c>
%%<br /> Option = {direction, integer()} | {caption, string()}
@@ -153,7 +153,7 @@ getManager(#wx_ref{type=WindowT,ref=WindowRef}) ->
%% @spec (This::wxAuiManager(),X::string()|term()) -> wxAuiPaneInfo:wxAuiPaneInfo()
%% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxauimanager.html#wxauimanagergetpane">external documentation</a>.
-%% <br /> Alternatives:
+%% <br /> Alternatives:
%% <p><c>
%% getPane(This::wxAuiManager(), Name::string()) -> wxAuiPaneInfo:wxAuiPaneInfo() </c>
%% </p>
@@ -299,11 +299,11 @@ update(#wx_ref{type=ThisT,ref=ThisRef}) ->
%% @spec (This::wxAuiManager()) -> ok
%% @doc Destroys this object, do not use object again
-destroy(Obj=#wx_ref{type=Type}) ->
+destroy(Obj=#wx_ref{type=Type}) ->
?CLASS(Type,wxAuiManager),
wxe_util:destroy(?DESTROY_OBJECT,Obj),
ok.
- %% From wxEvtHandler
+ %% From wxEvtHandler
%% @hidden
disconnect(This,EventType, Options) -> wxEvtHandler:disconnect(This,EventType, Options).
%% @hidden
diff --git a/lib/wx/src/gen/wxAuiManagerEvent.erl b/lib/wx/src/gen/wxAuiManagerEvent.erl
index c15eeb4ad6..b5e45f1860 100644
--- a/lib/wx/src/gen/wxAuiManagerEvent.erl
+++ b/lib/wx/src/gen/wxAuiManagerEvent.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%
%% This file is generated DO NOT EDIT
@@ -22,7 +22,7 @@
%% <dd><em>aui_pane_button</em>, <em>aui_pane_close</em>, <em>aui_pane_maximize</em>, <em>aui_pane_restore</em>, <em>aui_render</em>, <em>aui_find_manager</em></dd></dl>
%% See also the message variant {@link wxEvtHandler:wxAuiManager(). #wxAuiManager{}} event record type.
%%
-%% <p>This class is derived (and can use functions) from:
+%% <p>This class is derived (and can use functions) from:
%% <br />{@link wxEvent}
%% </p>
%% @type wxAuiManagerEvent(). An object reference, The representation is internal
@@ -142,7 +142,7 @@ canVeto(#wx_ref{type=ThisT,ref=ThisRef}) ->
wxe_util:call(?wxAuiManagerEvent_CanVeto,
<<ThisRef:32/?UI>>).
- %% From wxEvent
+ %% From wxEvent
%% @hidden
stopPropagation(This) -> wxEvent:stopPropagation(This).
%% @hidden
diff --git a/lib/wx/src/gen/wxAuiNotebook.erl b/lib/wx/src/gen/wxAuiNotebook.erl
index abd2cf618b..5d486aeaa2 100644
--- a/lib/wx/src/gen/wxAuiNotebook.erl
+++ b/lib/wx/src/gen/wxAuiNotebook.erl
@@ -1,24 +1,24 @@
%%
%% %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%
%% This file is generated DO NOT EDIT
%% @doc See external documentation: <a href="http://www.wxwidgets.org/manuals/stable/wx_wxauinotebook.html">wxAuiNotebook</a>.
-%% <p>This class is derived (and can use functions) from:
+%% <p>This class is derived (and can use functions) from:
%% <br />{@link wxControl}
%% <br />{@link wxWindow}
%% <br />{@link wxEvtHandler}
@@ -299,16 +299,16 @@ setUniformBitmapSize(#wx_ref{type=ThisT,ref=ThisRef},{SizeW,SizeH})
%% @spec (This::wxAuiNotebook()) -> ok
%% @doc Destroys this object, do not use object again
-destroy(Obj=#wx_ref{type=Type}) ->
+destroy(Obj=#wx_ref{type=Type}) ->
?CLASS(Type,wxAuiNotebook),
wxe_util:destroy(?DESTROY_OBJECT,Obj),
ok.
- %% From wxControl
+ %% From wxControl
%% @hidden
setLabel(This,Label) -> wxControl:setLabel(This,Label).
%% @hidden
getLabel(This) -> wxControl:getLabel(This).
- %% From wxWindow
+ %% From wxWindow
%% @hidden
warpPointer(This,X,Y) -> wxWindow:warpPointer(This,X,Y).
%% @hidden
@@ -653,7 +653,7 @@ center(This) -> wxWindow:center(This).
captureMouse(This) -> wxWindow:captureMouse(This).
%% @hidden
cacheBestSize(This,Size) -> wxWindow:cacheBestSize(This,Size).
- %% From wxEvtHandler
+ %% From wxEvtHandler
%% @hidden
disconnect(This,EventType, Options) -> wxEvtHandler:disconnect(This,EventType, Options).
%% @hidden
diff --git a/lib/wx/src/gen/wxAuiNotebookEvent.erl b/lib/wx/src/gen/wxAuiNotebookEvent.erl
index 763d7092f2..09a2abf214 100644
--- a/lib/wx/src/gen/wxAuiNotebookEvent.erl
+++ b/lib/wx/src/gen/wxAuiNotebookEvent.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%
%% This file is generated DO NOT EDIT
@@ -22,7 +22,7 @@
%% <dd><em>command_auinotebook_page_close</em>, <em>command_auinotebook_page_changed</em>, <em>command_auinotebook_page_changing</em>, <em>command_auinotebook_button</em>, <em>command_auinotebook_begin_drag</em>, <em>command_auinotebook_end_drag</em>, <em>command_auinotebook_drag_motion</em>, <em>command_auinotebook_allow_dnd</em>, <em>command_auinotebook_tab_middle_down</em>, <em>command_auinotebook_tab_middle_up</em>, <em>command_auinotebook_tab_right_down</em>, <em>command_auinotebook_tab_right_up</em>, <em>command_auinotebook_page_closed</em>, <em>command_auinotebook_drag_done</em>, <em>command_auinotebook_bg_dclick</em></dd></dl>
%% See also the message variant {@link wxEvtHandler:wxAuiNotebook(). #wxAuiNotebook{}} event record type.
%%
-%% <p>This class is derived (and can use functions) from:
+%% <p>This class is derived (and can use functions) from:
%% <br />{@link wxNotifyEvent}
%% <br />{@link wxCommandEvent}
%% <br />{@link wxEvent}
@@ -93,14 +93,14 @@ getDragSource(#wx_ref{type=ThisT,ref=ThisRef}) ->
wxe_util:call(?wxAuiNotebookEvent_GetDragSource,
<<ThisRef:32/?UI>>).
- %% From wxNotifyEvent
+ %% From wxNotifyEvent
%% @hidden
veto(This) -> wxNotifyEvent:veto(This).
%% @hidden
isAllowed(This) -> wxNotifyEvent:isAllowed(This).
%% @hidden
allow(This) -> wxNotifyEvent:allow(This).
- %% From wxCommandEvent
+ %% From wxCommandEvent
%% @hidden
setString(This,S) -> wxCommandEvent:setString(This,S).
%% @hidden
@@ -117,7 +117,7 @@ getInt(This) -> wxCommandEvent:getInt(This).
getExtraLong(This) -> wxCommandEvent:getExtraLong(This).
%% @hidden
getClientData(This) -> wxCommandEvent:getClientData(This).
- %% From wxEvent
+ %% From wxEvent
%% @hidden
stopPropagation(This) -> wxEvent:stopPropagation(This).
%% @hidden
diff --git a/lib/wx/src/gen/wxAuiPaneInfo.erl b/lib/wx/src/gen/wxAuiPaneInfo.erl
index 1683045a90..7b1401b069 100644
--- a/lib/wx/src/gen/wxAuiPaneInfo.erl
+++ b/lib/wx/src/gen/wxAuiPaneInfo.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%
%% This file is generated DO NOT EDIT
@@ -779,7 +779,7 @@ window(#wx_ref{type=ThisT,ref=ThisRef},#wx_ref{type=WT,ref=WRef}) ->
%% @spec (This::wxAuiPaneInfo()) -> ok
%% @doc Destroys this object, do not use object again
-destroy(Obj=#wx_ref{type=Type}) ->
+destroy(Obj=#wx_ref{type=Type}) ->
?CLASS(Type,wxAuiPaneInfo),
wxe_util:destroy(?wxAuiPaneInfo_destruct,Obj),
ok.
diff --git a/lib/wx/src/gen/wxAuiTabArt.erl b/lib/wx/src/gen/wxAuiTabArt.erl
index 354ab611d0..725bac9664 100644
--- a/lib/wx/src/gen/wxAuiTabArt.erl
+++ b/lib/wx/src/gen/wxAuiTabArt.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%
%% This file is generated DO NOT EDIT
diff --git a/lib/wx/src/gen/wxBitmap.erl b/lib/wx/src/gen/wxBitmap.erl
index 930d87198c..53c57e4393 100644
--- a/lib/wx/src/gen/wxBitmap.erl
+++ b/lib/wx/src/gen/wxBitmap.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%
%% This file is generated DO NOT EDIT
@@ -43,7 +43,7 @@ new() ->
%% @spec (X::string()|term()) -> wxBitmap()
%% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxbitmap.html#wxbitmapwxbitmap">external documentation</a>.
-%% <br /> Alternatives:
+%% <br /> Alternatives:
%% <p><c>
%% new(Filename::string()) -> new(Filename, []) </c></p>
%% <p><c>
@@ -59,7 +59,7 @@ new(Image)
%% @spec (X::integer()|string()|term(),X::integer()|term()) -> wxBitmap()
%% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxbitmap.html#wxbitmapwxbitmap">external documentation</a>.
-%% <br /> Alternatives:
+%% <br /> Alternatives:
%% <p><c>
%% new(Width::integer(), Height::integer()) -> new(Width,Height, []) </c></p>
%% <p><c>
@@ -95,7 +95,7 @@ new(#wx_ref{type=ImageT,ref=ImageRef}, Options)
%% @spec (X::binary()|integer(),X::integer(),X::integer()|term()) -> wxBitmap()
%% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxbitmap.html#wxbitmapwxbitmap">external documentation</a>.
-%% <br /> Alternatives:
+%% <br /> Alternatives:
%% <p><c>
%% new(Bits::binary(), Width::integer(), Height::integer()) -> new(Bits,Width,Height, []) </c></p>
%% <p><c>
@@ -293,7 +293,7 @@ setWidth(#wx_ref{type=ThisT,ref=ThisRef},Width)
%% @spec (This::wxBitmap()) -> ok
%% @doc Destroys this object, do not use object again
-destroy(Obj=#wx_ref{type=Type}) ->
+destroy(Obj=#wx_ref{type=Type}) ->
?CLASS(Type,wxBitmap),
wxe_util:destroy(?DESTROY_OBJECT,Obj),
ok.
diff --git a/lib/wx/src/gen/wxBitmapButton.erl b/lib/wx/src/gen/wxBitmapButton.erl
index 78d43d4918..0c187bf1c1 100644
--- a/lib/wx/src/gen/wxBitmapButton.erl
+++ b/lib/wx/src/gen/wxBitmapButton.erl
@@ -1,24 +1,24 @@
%%
%% %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%
%% This file is generated DO NOT EDIT
%% @doc See external documentation: <a href="http://www.wxwidgets.org/manuals/stable/wx_wxbitmapbutton.html">wxBitmapButton</a>.
-%% <p>This class is derived (and can use functions) from:
+%% <p>This class is derived (and can use functions) from:
%% <br />{@link wxButton}
%% <br />{@link wxControl}
%% <br />{@link wxWindow}
@@ -192,19 +192,19 @@ setBitmapSelected(#wx_ref{type=ThisT,ref=ThisRef},#wx_ref{type=SelT,ref=SelRef})
%% @spec (This::wxBitmapButton()) -> ok
%% @doc Destroys this object, do not use object again
-destroy(Obj=#wx_ref{type=Type}) ->
+destroy(Obj=#wx_ref{type=Type}) ->
?CLASS(Type,wxBitmapButton),
wxe_util:destroy(?DESTROY_OBJECT,Obj),
ok.
- %% From wxButton
+ %% From wxButton
%% @hidden
setLabel(This,Label) -> wxButton:setLabel(This,Label).
%% @hidden
setDefault(This) -> wxButton:setDefault(This).
- %% From wxControl
+ %% From wxControl
%% @hidden
getLabel(This) -> wxControl:getLabel(This).
- %% From wxWindow
+ %% From wxWindow
%% @hidden
warpPointer(This,X,Y) -> wxWindow:warpPointer(This,X,Y).
%% @hidden
@@ -551,7 +551,7 @@ center(This) -> wxWindow:center(This).
captureMouse(This) -> wxWindow:captureMouse(This).
%% @hidden
cacheBestSize(This,Size) -> wxWindow:cacheBestSize(This,Size).
- %% From wxEvtHandler
+ %% From wxEvtHandler
%% @hidden
disconnect(This,EventType, Options) -> wxEvtHandler:disconnect(This,EventType, Options).
%% @hidden
diff --git a/lib/wx/src/gen/wxBitmapDataObject.erl b/lib/wx/src/gen/wxBitmapDataObject.erl
index 7c7f6a20b0..b5207072e3 100644
--- a/lib/wx/src/gen/wxBitmapDataObject.erl
+++ b/lib/wx/src/gen/wxBitmapDataObject.erl
@@ -1,24 +1,24 @@
%%
%% %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%
%% This file is generated DO NOT EDIT
%% @doc See external documentation: <a href="http://www.wxwidgets.org/manuals/stable/wx_wxbitmapdataobject.html">wxBitmapDataObject</a>.
-%% <p>This class is derived (and can use functions) from:
+%% <p>This class is derived (and can use functions) from:
%% <br />{@link wxDataObject}
%% </p>
%% @type wxBitmapDataObject(). An object reference, The representation is internal
@@ -43,7 +43,7 @@ new() ->
%% @spec (X::term()) -> wxBitmapDataObject()
%% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxbitmapdataobject.html#wxbitmapdataobjectwxbitmapdataobject">external documentation</a>.
-%% <br /> Alternatives:
+%% <br /> Alternatives:
%% <p><c>
%% new([Option]) -> wxBitmapDataObject() </c>
%%<br /> Option = {bitmap, wxBitmap:wxBitmap()}
@@ -80,8 +80,8 @@ setBitmap(#wx_ref{type=ThisT,ref=ThisRef},#wx_ref{type=BitmapT,ref=BitmapRef}) -
%% @spec (This::wxBitmapDataObject()) -> ok
%% @doc Destroys this object, do not use object again
-destroy(Obj=#wx_ref{type=Type}) ->
+destroy(Obj=#wx_ref{type=Type}) ->
?CLASS(Type,wxBitmapDataObject),
wxe_util:destroy(?wxBitmapDataObject_destroy,Obj),
ok.
- %% From wxDataObject
+ %% From wxDataObject
diff --git a/lib/wx/src/gen/wxBoxSizer.erl b/lib/wx/src/gen/wxBoxSizer.erl
index 3599cd11b6..1d5b1cf2fa 100644
--- a/lib/wx/src/gen/wxBoxSizer.erl
+++ b/lib/wx/src/gen/wxBoxSizer.erl
@@ -1,24 +1,24 @@
%%
%% %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%
%% This file is generated DO NOT EDIT
%% @doc See external documentation: <a href="http://www.wxwidgets.org/manuals/stable/wx_wxboxsizer.html">wxBoxSizer</a>.
-%% <p>This class is derived (and can use functions) from:
+%% <p>This class is derived (and can use functions) from:
%% <br />{@link wxSizer}
%% </p>
%% @type wxBoxSizer(). An object reference, The representation is internal
@@ -60,11 +60,11 @@ getOrientation(#wx_ref{type=ThisT,ref=ThisRef}) ->
%% @spec (This::wxBoxSizer()) -> ok
%% @doc Destroys this object, do not use object again
-destroy(Obj=#wx_ref{type=Type}) ->
+destroy(Obj=#wx_ref{type=Type}) ->
?CLASS(Type,wxBoxSizer),
wxe_util:destroy(?DESTROY_OBJECT,Obj),
ok.
- %% From wxSizer
+ %% From wxSizer
%% @hidden
show(This,Index, Options) -> wxSizer:show(This,Index, Options).
%% @hidden
diff --git a/lib/wx/src/gen/wxBrush.erl b/lib/wx/src/gen/wxBrush.erl
index 2a5f184ce6..e42edd62e3 100644
--- a/lib/wx/src/gen/wxBrush.erl
+++ b/lib/wx/src/gen/wxBrush.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%
%% This file is generated DO NOT EDIT
@@ -41,7 +41,7 @@ new() ->
%% @spec (X::term()) -> wxBrush()
%% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxbrush.html#wxbrushwxbrush">external documentation</a>.
-%% <br /> Alternatives:
+%% <br /> Alternatives:
%% <p><c>
%% new(Colour::wx:colour()) -> new(Colour, []) </c></p>
%% <p><c>
@@ -136,7 +136,7 @@ setStyle(#wx_ref{type=ThisT,ref=ThisRef},Style)
%% @spec (This::wxBrush()) -> ok
%% @doc Destroys this object, do not use object again
-destroy(Obj=#wx_ref{type=Type}) ->
+destroy(Obj=#wx_ref{type=Type}) ->
?CLASS(Type,wxBrush),
wxe_util:destroy(?DESTROY_OBJECT,Obj),
ok.
diff --git a/lib/wx/src/gen/wxBufferedDC.erl b/lib/wx/src/gen/wxBufferedDC.erl
index b99822040d..6e341a8552 100644
--- a/lib/wx/src/gen/wxBufferedDC.erl
+++ b/lib/wx/src/gen/wxBufferedDC.erl
@@ -1,24 +1,24 @@
%%
%% %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%
%% This file is generated DO NOT EDIT
%% @doc See external documentation: <a href="http://www.wxwidgets.org/manuals/stable/wx_wxbuffereddc.html">wxBufferedDC</a>.
-%% <p>This class is derived (and can use functions) from:
+%% <p>This class is derived (and can use functions) from:
%% <br />{@link wxMemoryDC}
%% <br />{@link wxDC}
%% </p>
@@ -72,7 +72,7 @@ new(Dc)
%% @spec (Dc::wxDC:wxDC(),X::term()) -> wxBufferedDC()
%% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxbuffereddc.html#wxbuffereddcwxbuffereddc">external documentation</a>.
-%% <br /> Alternatives:
+%% <br /> Alternatives:
%% <p><c>
%% new(Dc::wxDC:wxDC(), Area::{W::integer(),H::integer()}) -> new(Dc,Area, []) </c></p>
%% <p><c>
@@ -113,7 +113,7 @@ init(This,Dc)
%% @spec (This::wxBufferedDC(),Dc::wxDC:wxDC(),X::term()) -> ok
%% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxbuffereddc.html#wxbuffereddcinit">external documentation</a>.
-%% <br /> Alternatives:
+%% <br /> Alternatives:
%% <p><c>
%% init(This::wxBufferedDC(), Dc::wxDC:wxDC(), Area::{W::integer(),H::integer()}) -> init(This,Dc,Area, []) </c></p>
%% <p><c>
@@ -150,16 +150,16 @@ init(#wx_ref{type=ThisT,ref=ThisRef},#wx_ref{type=DcT,ref=DcRef},{AreaW,AreaH},
%% @spec (This::wxBufferedDC()) -> ok
%% @doc Destroys this object, do not use object again
-destroy(Obj=#wx_ref{type=Type}) ->
+destroy(Obj=#wx_ref{type=Type}) ->
?CLASS(Type,wxBufferedDC),
wxe_util:destroy(?DESTROY_OBJECT,Obj),
ok.
- %% From wxMemoryDC
+ %% From wxMemoryDC
%% @hidden
selectObjectAsSource(This,Bmp) -> wxMemoryDC:selectObjectAsSource(This,Bmp).
%% @hidden
selectObject(This,Bmp) -> wxMemoryDC:selectObject(This,Bmp).
- %% From wxDC
+ %% From wxDC
%% @hidden
startPage(This) -> wxDC:startPage(This).
%% @hidden
diff --git a/lib/wx/src/gen/wxBufferedPaintDC.erl b/lib/wx/src/gen/wxBufferedPaintDC.erl
index 5674712055..2712394dd8 100644
--- a/lib/wx/src/gen/wxBufferedPaintDC.erl
+++ b/lib/wx/src/gen/wxBufferedPaintDC.erl
@@ -1,24 +1,24 @@
%%
%% %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%
%% This file is generated DO NOT EDIT
%% @doc See external documentation: <a href="http://www.wxwidgets.org/manuals/stable/wx_wxbufferedpaintdc.html">wxBufferedPaintDC</a>.
-%% <p>This class is derived (and can use functions) from:
+%% <p>This class is derived (and can use functions) from:
%% <br />{@link wxBufferedDC}
%% <br />{@link wxMemoryDC}
%% <br />{@link wxDC}
@@ -69,7 +69,7 @@ new(Window)
%% @spec (Window::wxWindow:wxWindow(),X::term()) -> wxBufferedPaintDC()
%% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxbufferedpaintdc.html#wxbufferedpaintdcwxbufferedpaintdc">external documentation</a>.
-%% <br /> Alternatives:
+%% <br /> Alternatives:
%% <p><c>
%% new(Window::wxWindow:wxWindow(), Buffer::wxBitmap:wxBitmap()) -> new(Window,Buffer, []) </c></p>
%% <p><c>
@@ -104,23 +104,23 @@ new(#wx_ref{type=WindowT,ref=WindowRef},#wx_ref{type=BufferT,ref=BufferRef}, Opt
%% @spec (This::wxBufferedPaintDC()) -> ok
%% @doc Destroys this object, do not use object again
-destroy(Obj=#wx_ref{type=Type}) ->
+destroy(Obj=#wx_ref{type=Type}) ->
?CLASS(Type,wxBufferedPaintDC),
wxe_util:destroy(?DESTROY_OBJECT,Obj),
ok.
- %% From wxBufferedDC
+ %% From wxBufferedDC
%% @hidden
init(This,Dc,Area, Options) -> wxBufferedDC:init(This,Dc,Area, Options).
%% @hidden
init(This,Dc,Area) -> wxBufferedDC:init(This,Dc,Area).
%% @hidden
init(This,Dc) -> wxBufferedDC:init(This,Dc).
- %% From wxMemoryDC
+ %% From wxMemoryDC
%% @hidden
selectObjectAsSource(This,Bmp) -> wxMemoryDC:selectObjectAsSource(This,Bmp).
%% @hidden
selectObject(This,Bmp) -> wxMemoryDC:selectObject(This,Bmp).
- %% From wxDC
+ %% From wxDC
%% @hidden
startPage(This) -> wxDC:startPage(This).
%% @hidden
diff --git a/lib/wx/src/gen/wxButton.erl b/lib/wx/src/gen/wxButton.erl
index 261a961063..c0e21a5657 100644
--- a/lib/wx/src/gen/wxButton.erl
+++ b/lib/wx/src/gen/wxButton.erl
@@ -1,24 +1,24 @@
%%
%% %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%
%% This file is generated DO NOT EDIT
%% @doc See external documentation: <a href="http://www.wxwidgets.org/manuals/stable/wx_wxbutton.html">wxButton</a>.
-%% <p>This class is derived (and can use functions) from:
+%% <p>This class is derived (and can use functions) from:
%% <br />{@link wxControl}
%% <br />{@link wxWindow}
%% <br />{@link wxEvtHandler}
@@ -151,14 +151,14 @@ setLabel(#wx_ref{type=ThisT,ref=ThisRef},Label)
%% @spec (This::wxButton()) -> ok
%% @doc Destroys this object, do not use object again
-destroy(Obj=#wx_ref{type=Type}) ->
+destroy(Obj=#wx_ref{type=Type}) ->
?CLASS(Type,wxButton),
wxe_util:destroy(?DESTROY_OBJECT,Obj),
ok.
- %% From wxControl
+ %% From wxControl
%% @hidden
getLabel(This) -> wxControl:getLabel(This).
- %% From wxWindow
+ %% From wxWindow
%% @hidden
warpPointer(This,X,Y) -> wxWindow:warpPointer(This,X,Y).
%% @hidden
@@ -505,7 +505,7 @@ center(This) -> wxWindow:center(This).
captureMouse(This) -> wxWindow:captureMouse(This).
%% @hidden
cacheBestSize(This,Size) -> wxWindow:cacheBestSize(This,Size).
- %% From wxEvtHandler
+ %% From wxEvtHandler
%% @hidden
disconnect(This,EventType, Options) -> wxEvtHandler:disconnect(This,EventType, Options).
%% @hidden
diff --git a/lib/wx/src/gen/wxCalendarCtrl.erl b/lib/wx/src/gen/wxCalendarCtrl.erl
index 5b87ac54e4..8ad4d5954b 100644
--- a/lib/wx/src/gen/wxCalendarCtrl.erl
+++ b/lib/wx/src/gen/wxCalendarCtrl.erl
@@ -1,24 +1,24 @@
%%
%% %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%
%% This file is generated DO NOT EDIT
%% @doc See external documentation: <a href="http://www.wxwidgets.org/manuals/stable/wx_wxcalendarctrl.html">wxCalendarCtrl</a>.
-%% <p>This class is derived (and can use functions) from:
+%% <p>This class is derived (and can use functions) from:
%% <br />{@link wxControl}
%% <br />{@link wxWindow}
%% <br />{@link wxEvtHandler}
@@ -311,16 +311,16 @@ hitTest(#wx_ref{type=ThisT,ref=ThisRef},{PosX,PosY})
%% @spec (This::wxCalendarCtrl()) -> ok
%% @doc Destroys this object, do not use object again
-destroy(Obj=#wx_ref{type=Type}) ->
+destroy(Obj=#wx_ref{type=Type}) ->
?CLASS(Type,wxCalendarCtrl),
wxe_util:destroy(?DESTROY_OBJECT,Obj),
ok.
- %% From wxControl
+ %% From wxControl
%% @hidden
setLabel(This,Label) -> wxControl:setLabel(This,Label).
%% @hidden
getLabel(This) -> wxControl:getLabel(This).
- %% From wxWindow
+ %% From wxWindow
%% @hidden
warpPointer(This,X,Y) -> wxWindow:warpPointer(This,X,Y).
%% @hidden
@@ -667,7 +667,7 @@ center(This) -> wxWindow:center(This).
captureMouse(This) -> wxWindow:captureMouse(This).
%% @hidden
cacheBestSize(This,Size) -> wxWindow:cacheBestSize(This,Size).
- %% From wxEvtHandler
+ %% From wxEvtHandler
%% @hidden
disconnect(This,EventType, Options) -> wxEvtHandler:disconnect(This,EventType, Options).
%% @hidden
diff --git a/lib/wx/src/gen/wxCalendarDateAttr.erl b/lib/wx/src/gen/wxCalendarDateAttr.erl
index 197e0eb996..aea8abbe54 100644
--- a/lib/wx/src/gen/wxCalendarDateAttr.erl
+++ b/lib/wx/src/gen/wxCalendarDateAttr.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%
%% This file is generated DO NOT EDIT
@@ -43,7 +43,7 @@ new() ->
%% @spec (X::WxCalendarDateBorder|term()) -> wxCalendarDateAttr()
%% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxcalendardateattr.html#wxcalendardateattrwxcalendardateattr">external documentation</a>.
-%% <br /> Alternatives:
+%% <br /> Alternatives:
%% <p><c>
%% new(Border::WxCalendarDateBorder) -> new(Border, []) </c></p>
%% <p><c>
@@ -59,7 +59,7 @@ new(ColText)
%% @spec (X::WxCalendarDateBorder|term(),[Option]) -> wxCalendarDateAttr()
%% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxcalendardateattr.html#wxcalendardateattrwxcalendardateattr">external documentation</a>.
-%% <br /> Alternatives:
+%% <br /> Alternatives:
%% <p><c>
%% new(Border::WxCalendarDateBorder, [Option]) -> wxCalendarDateAttr() </c>
%%<br /> Option = {colBorder, wx:colour()}
@@ -221,7 +221,7 @@ getBorder(#wx_ref{type=ThisT,ref=ThisRef}) ->
%% @spec (This::wxCalendarDateAttr()) -> ok
%% @doc Destroys this object, do not use object again
-destroy(Obj=#wx_ref{type=Type}) ->
+destroy(Obj=#wx_ref{type=Type}) ->
?CLASS(Type,wxCalendarDateAttr),
wxe_util:destroy(?wxCalendarDateAttr_destroy,Obj),
ok.
diff --git a/lib/wx/src/gen/wxCalendarEvent.erl b/lib/wx/src/gen/wxCalendarEvent.erl
index de51d20cae..40723711af 100644
--- a/lib/wx/src/gen/wxCalendarEvent.erl
+++ b/lib/wx/src/gen/wxCalendarEvent.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%
%% This file is generated DO NOT EDIT
@@ -22,7 +22,7 @@
%% <dd><em>calendar_sel_changed</em>, <em>calendar_day_changed</em>, <em>calendar_month_changed</em>, <em>calendar_year_changed</em>, <em>calendar_doubleclicked</em>, <em>calendar_weekday_clicked</em></dd></dl>
%% See also the message variant {@link wxEvtHandler:wxCalendar(). #wxCalendar{}} event record type.
%%
-%% <p>This class is derived (and can use functions) from:
+%% <p>This class is derived (and can use functions) from:
%% <br />{@link wxDateEvent}
%% <br />{@link wxCommandEvent}
%% <br />{@link wxEvent}
@@ -56,10 +56,10 @@ getWeekDay(#wx_ref{type=ThisT,ref=ThisRef}) ->
wxe_util:call(?wxCalendarEvent_GetWeekDay,
<<ThisRef:32/?UI>>).
- %% From wxDateEvent
+ %% From wxDateEvent
%% @hidden
getDate(This) -> wxDateEvent:getDate(This).
- %% From wxCommandEvent
+ %% From wxCommandEvent
%% @hidden
setString(This,S) -> wxCommandEvent:setString(This,S).
%% @hidden
@@ -78,7 +78,7 @@ getInt(This) -> wxCommandEvent:getInt(This).
getExtraLong(This) -> wxCommandEvent:getExtraLong(This).
%% @hidden
getClientData(This) -> wxCommandEvent:getClientData(This).
- %% From wxEvent
+ %% From wxEvent
%% @hidden
stopPropagation(This) -> wxEvent:stopPropagation(This).
%% @hidden
diff --git a/lib/wx/src/gen/wxCaret.erl b/lib/wx/src/gen/wxCaret.erl
index 50844d36ff..3e1a3d544c 100644
--- a/lib/wx/src/gen/wxCaret.erl
+++ b/lib/wx/src/gen/wxCaret.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%
%% This file is generated DO NOT EDIT
@@ -175,7 +175,7 @@ show(#wx_ref{type=ThisT,ref=ThisRef}, Options)
%% @spec (This::wxCaret()) -> ok
%% @doc Destroys this object, do not use object again
-destroy(Obj=#wx_ref{type=Type}) ->
+destroy(Obj=#wx_ref{type=Type}) ->
?CLASS(Type,wxCaret),
wxe_util:destroy(?wxCaret_destruct,Obj),
ok.
diff --git a/lib/wx/src/gen/wxCheckBox.erl b/lib/wx/src/gen/wxCheckBox.erl
index bf368dc965..c484483379 100644
--- a/lib/wx/src/gen/wxCheckBox.erl
+++ b/lib/wx/src/gen/wxCheckBox.erl
@@ -1,24 +1,24 @@
%%
%% %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%
%% This file is generated DO NOT EDIT
%% @doc See external documentation: <a href="http://www.wxwidgets.org/manuals/stable/wx_wxcheckbox.html">wxCheckBox</a>.
-%% <p>This class is derived (and can use functions) from:
+%% <p>This class is derived (and can use functions) from:
%% <br />{@link wxControl}
%% <br />{@link wxWindow}
%% <br />{@link wxEvtHandler}
@@ -185,16 +185,16 @@ set3StateValue(#wx_ref{type=ThisT,ref=ThisRef},State)
%% @spec (This::wxCheckBox()) -> ok
%% @doc Destroys this object, do not use object again
-destroy(Obj=#wx_ref{type=Type}) ->
+destroy(Obj=#wx_ref{type=Type}) ->
?CLASS(Type,wxCheckBox),
wxe_util:destroy(?DESTROY_OBJECT,Obj),
ok.
- %% From wxControl
+ %% From wxControl
%% @hidden
setLabel(This,Label) -> wxControl:setLabel(This,Label).
%% @hidden
getLabel(This) -> wxControl:getLabel(This).
- %% From wxWindow
+ %% From wxWindow
%% @hidden
warpPointer(This,X,Y) -> wxWindow:warpPointer(This,X,Y).
%% @hidden
@@ -541,7 +541,7 @@ center(This) -> wxWindow:center(This).
captureMouse(This) -> wxWindow:captureMouse(This).
%% @hidden
cacheBestSize(This,Size) -> wxWindow:cacheBestSize(This,Size).
- %% From wxEvtHandler
+ %% From wxEvtHandler
%% @hidden
disconnect(This,EventType, Options) -> wxEvtHandler:disconnect(This,EventType, Options).
%% @hidden
diff --git a/lib/wx/src/gen/wxCheckListBox.erl b/lib/wx/src/gen/wxCheckListBox.erl
index 7cbf9d18df..c692997311 100644
--- a/lib/wx/src/gen/wxCheckListBox.erl
+++ b/lib/wx/src/gen/wxCheckListBox.erl
@@ -1,24 +1,24 @@
%%
%% %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%
%% This file is generated DO NOT EDIT
%% @doc See external documentation: <a href="http://www.wxwidgets.org/manuals/stable/wx_wxchecklistbox.html">wxCheckListBox</a>.
-%% <p>This class is derived (and can use functions) from:
+%% <p>This class is derived (and can use functions) from:
%% <br />{@link wxListBox}
%% <br />{@link wxControlWithItems}
%% <br />{@link wxControl}
@@ -139,11 +139,11 @@ isChecked(#wx_ref{type=ThisT,ref=ThisRef},Index)
%% @spec (This::wxCheckListBox()) -> ok
%% @doc Destroys this object, do not use object again
-destroy(Obj=#wx_ref{type=Type}) ->
+destroy(Obj=#wx_ref{type=Type}) ->
?CLASS(Type,wxCheckListBox),
wxe_util:destroy(?DESTROY_OBJECT,Obj),
ok.
- %% From wxListBox
+ %% From wxListBox
%% @hidden
setFirstItem(This,N) -> wxListBox:setFirstItem(This,N).
%% @hidden
@@ -158,7 +158,7 @@ insertItems(This,Items,Pos) -> wxListBox:insertItems(This,Items,Pos).
getSelections(This) -> wxListBox:getSelections(This).
%% @hidden
deselect(This,N) -> wxListBox:deselect(This,N).
- %% From wxControlWithItems
+ %% From wxControlWithItems
%% @hidden
setStringSelection(This,S) -> wxControlWithItems:setStringSelection(This,S).
%% @hidden
@@ -199,12 +199,12 @@ appendStrings(This,Strings) -> wxControlWithItems:appendStrings(This,Strings).
append(This,Item,ClientData) -> wxControlWithItems:append(This,Item,ClientData).
%% @hidden
append(This,Item) -> wxControlWithItems:append(This,Item).
- %% From wxControl
+ %% From wxControl
%% @hidden
setLabel(This,Label) -> wxControl:setLabel(This,Label).
%% @hidden
getLabel(This) -> wxControl:getLabel(This).
- %% From wxWindow
+ %% From wxWindow
%% @hidden
warpPointer(This,X,Y) -> wxWindow:warpPointer(This,X,Y).
%% @hidden
@@ -551,7 +551,7 @@ center(This) -> wxWindow:center(This).
captureMouse(This) -> wxWindow:captureMouse(This).
%% @hidden
cacheBestSize(This,Size) -> wxWindow:cacheBestSize(This,Size).
- %% From wxEvtHandler
+ %% From wxEvtHandler
%% @hidden
disconnect(This,EventType, Options) -> wxEvtHandler:disconnect(This,EventType, Options).
%% @hidden
diff --git a/lib/wx/src/gen/wxChildFocusEvent.erl b/lib/wx/src/gen/wxChildFocusEvent.erl
index ea04e6863b..a20071cbf5 100644
--- a/lib/wx/src/gen/wxChildFocusEvent.erl
+++ b/lib/wx/src/gen/wxChildFocusEvent.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%
%% This file is generated DO NOT EDIT
@@ -22,7 +22,7 @@
%% <dd><em>child_focus</em></dd></dl>
%% See also the message variant {@link wxEvtHandler:wxChildFocus(). #wxChildFocus{}} event record type.
%%
-%% <p>This class is derived (and can use functions) from:
+%% <p>This class is derived (and can use functions) from:
%% <br />{@link wxCommandEvent}
%% <br />{@link wxEvent}
%% </p>
@@ -52,7 +52,7 @@ getWindow(#wx_ref{type=ThisT,ref=ThisRef}) ->
wxe_util:call(?wxChildFocusEvent_GetWindow,
<<ThisRef:32/?UI>>).
- %% From wxCommandEvent
+ %% From wxCommandEvent
%% @hidden
setString(This,S) -> wxCommandEvent:setString(This,S).
%% @hidden
@@ -71,7 +71,7 @@ getInt(This) -> wxCommandEvent:getInt(This).
getExtraLong(This) -> wxCommandEvent:getExtraLong(This).
%% @hidden
getClientData(This) -> wxCommandEvent:getClientData(This).
- %% From wxEvent
+ %% From wxEvent
%% @hidden
stopPropagation(This) -> wxEvent:stopPropagation(This).
%% @hidden
diff --git a/lib/wx/src/gen/wxChoice.erl b/lib/wx/src/gen/wxChoice.erl
index 3e20d5f933..eaf2f0352f 100644
--- a/lib/wx/src/gen/wxChoice.erl
+++ b/lib/wx/src/gen/wxChoice.erl
@@ -1,24 +1,24 @@
%%
%% %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%
%% This file is generated DO NOT EDIT
%% @doc See external documentation: <a href="http://www.wxwidgets.org/manuals/stable/wx_wxchoice.html">wxChoice</a>.
-%% <p>This class is derived (and can use functions) from:
+%% <p>This class is derived (and can use functions) from:
%% <br />{@link wxControlWithItems}
%% <br />{@link wxControl}
%% <br />{@link wxWindow}
@@ -166,11 +166,11 @@ setColumns(#wx_ref{type=ThisT,ref=ThisRef}, Options)
%% @spec (This::wxChoice()) -> ok
%% @doc Destroys this object, do not use object again
-destroy(Obj=#wx_ref{type=Type}) ->
+destroy(Obj=#wx_ref{type=Type}) ->
?CLASS(Type,wxChoice),
wxe_util:destroy(?DESTROY_OBJECT,Obj),
ok.
- %% From wxControlWithItems
+ %% From wxControlWithItems
%% @hidden
setStringSelection(This,S) -> wxControlWithItems:setStringSelection(This,S).
%% @hidden
@@ -209,12 +209,12 @@ appendStrings(This,Strings) -> wxControlWithItems:appendStrings(This,Strings).
append(This,Item,ClientData) -> wxControlWithItems:append(This,Item,ClientData).
%% @hidden
append(This,Item) -> wxControlWithItems:append(This,Item).
- %% From wxControl
+ %% From wxControl
%% @hidden
setLabel(This,Label) -> wxControl:setLabel(This,Label).
%% @hidden
getLabel(This) -> wxControl:getLabel(This).
- %% From wxWindow
+ %% From wxWindow
%% @hidden
warpPointer(This,X,Y) -> wxWindow:warpPointer(This,X,Y).
%% @hidden
@@ -561,7 +561,7 @@ center(This) -> wxWindow:center(This).
captureMouse(This) -> wxWindow:captureMouse(This).
%% @hidden
cacheBestSize(This,Size) -> wxWindow:cacheBestSize(This,Size).
- %% From wxEvtHandler
+ %% From wxEvtHandler
%% @hidden
disconnect(This,EventType, Options) -> wxEvtHandler:disconnect(This,EventType, Options).
%% @hidden
diff --git a/lib/wx/src/gen/wxChoicebook.erl b/lib/wx/src/gen/wxChoicebook.erl
index faf7c402b7..b724d0cad2 100644
--- a/lib/wx/src/gen/wxChoicebook.erl
+++ b/lib/wx/src/gen/wxChoicebook.erl
@@ -1,24 +1,24 @@
%%
%% %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%
%% This file is generated DO NOT EDIT
%% @doc See external documentation: <a href="http://www.wxwidgets.org/manuals/stable/wx_wxchoicebook.html">wxChoicebook</a>.
-%% <p>This class is derived (and can use functions) from:
+%% <p>This class is derived (and can use functions) from:
%% <br />{@link wxControl}
%% <br />{@link wxWindow}
%% <br />{@link wxEvtHandler}
@@ -329,16 +329,16 @@ changeSelection(#wx_ref{type=ThisT,ref=ThisRef},N)
%% @spec (This::wxChoicebook()) -> ok
%% @doc Destroys this object, do not use object again
-destroy(Obj=#wx_ref{type=Type}) ->
+destroy(Obj=#wx_ref{type=Type}) ->
?CLASS(Type,wxChoicebook),
wxe_util:destroy(?DESTROY_OBJECT,Obj),
ok.
- %% From wxControl
+ %% From wxControl
%% @hidden
setLabel(This,Label) -> wxControl:setLabel(This,Label).
%% @hidden
getLabel(This) -> wxControl:getLabel(This).
- %% From wxWindow
+ %% From wxWindow
%% @hidden
warpPointer(This,X,Y) -> wxWindow:warpPointer(This,X,Y).
%% @hidden
@@ -685,7 +685,7 @@ center(This) -> wxWindow:center(This).
captureMouse(This) -> wxWindow:captureMouse(This).
%% @hidden
cacheBestSize(This,Size) -> wxWindow:cacheBestSize(This,Size).
- %% From wxEvtHandler
+ %% From wxEvtHandler
%% @hidden
disconnect(This,EventType, Options) -> wxEvtHandler:disconnect(This,EventType, Options).
%% @hidden
diff --git a/lib/wx/src/gen/wxClientDC.erl b/lib/wx/src/gen/wxClientDC.erl
index 86418cc922..c966fb50cc 100644
--- a/lib/wx/src/gen/wxClientDC.erl
+++ b/lib/wx/src/gen/wxClientDC.erl
@@ -1,24 +1,24 @@
%%
%% %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%
%% This file is generated DO NOT EDIT
%% @doc See external documentation: <a href="http://www.wxwidgets.org/manuals/stable/wx_wxclientdc.html">wxClientDC</a>.
-%% <p>This class is derived (and can use functions) from:
+%% <p>This class is derived (and can use functions) from:
%% <br />{@link wxWindowDC}
%% <br />{@link wxDC}
%% </p>
@@ -73,12 +73,12 @@ new(#wx_ref{type=WinT,ref=WinRef}) ->
%% @spec (This::wxClientDC()) -> ok
%% @doc Destroys this object, do not use object again
-destroy(Obj=#wx_ref{type=Type}) ->
+destroy(Obj=#wx_ref{type=Type}) ->
?CLASS(Type,wxClientDC),
wxe_util:destroy(?DESTROY_OBJECT,Obj),
ok.
- %% From wxWindowDC
- %% From wxDC
+ %% From wxWindowDC
+ %% From wxDC
%% @hidden
startPage(This) -> wxDC:startPage(This).
%% @hidden
diff --git a/lib/wx/src/gen/wxClipboard.erl b/lib/wx/src/gen/wxClipboard.erl
index c92f7b9af4..7ae27b3133 100644
--- a/lib/wx/src/gen/wxClipboard.erl
+++ b/lib/wx/src/gen/wxClipboard.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%
%% This file is generated DO NOT EDIT
@@ -132,7 +132,7 @@ get() ->
%% @spec (This::wxClipboard()) -> ok
%% @doc Destroys this object, do not use object again
-destroy(Obj=#wx_ref{type=Type}) ->
+destroy(Obj=#wx_ref{type=Type}) ->
?CLASS(Type,wxClipboard),
wxe_util:destroy(?DESTROY_OBJECT,Obj),
ok.
diff --git a/lib/wx/src/gen/wxCloseEvent.erl b/lib/wx/src/gen/wxCloseEvent.erl
index e8e25a448c..706d7701de 100644
--- a/lib/wx/src/gen/wxCloseEvent.erl
+++ b/lib/wx/src/gen/wxCloseEvent.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%
%% This file is generated DO NOT EDIT
@@ -22,7 +22,7 @@
%% <dd><em>close_window</em>, <em>end_session</em>, <em>query_end_session</em></dd></dl>
%% See also the message variant {@link wxEvtHandler:wxClose(). #wxClose{}} event record type.
%%
-%% <p>This class is derived (and can use functions) from:
+%% <p>This class is derived (and can use functions) from:
%% <br />{@link wxEvent}
%% </p>
%% @type wxCloseEvent(). An object reference, The representation is internal
@@ -89,7 +89,7 @@ veto(#wx_ref{type=ThisT,ref=ThisRef}, Options)
wxe_util:cast(?wxCloseEvent_Veto,
<<ThisRef:32/?UI, 0:32,BinOpt/binary>>).
- %% From wxEvent
+ %% From wxEvent
%% @hidden
stopPropagation(This) -> wxEvent:stopPropagation(This).
%% @hidden
diff --git a/lib/wx/src/gen/wxColourData.erl b/lib/wx/src/gen/wxColourData.erl
index 973086c295..dc77ea043c 100644
--- a/lib/wx/src/gen/wxColourData.erl
+++ b/lib/wx/src/gen/wxColourData.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%
%% This file is generated DO NOT EDIT
@@ -94,7 +94,7 @@ setCustomColour(#wx_ref{type=ThisT,ref=ThisRef},I,Colour)
%% @spec (This::wxColourData()) -> ok
%% @doc Destroys this object, do not use object again
-destroy(Obj=#wx_ref{type=Type}) ->
+destroy(Obj=#wx_ref{type=Type}) ->
?CLASS(Type,wxColourData),
wxe_util:destroy(?DESTROY_OBJECT,Obj),
ok.
diff --git a/lib/wx/src/gen/wxColourDialog.erl b/lib/wx/src/gen/wxColourDialog.erl
index 08a6b73775..f5677d00ff 100644
--- a/lib/wx/src/gen/wxColourDialog.erl
+++ b/lib/wx/src/gen/wxColourDialog.erl
@@ -1,24 +1,24 @@
%%
%% %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%
%% This file is generated DO NOT EDIT
%% @doc See external documentation: <a href="http://www.wxwidgets.org/manuals/stable/wx_wxcolourdialog.html">wxColourDialog</a>.
-%% <p>This class is derived (and can use functions) from:
+%% <p>This class is derived (and can use functions) from:
%% <br />{@link wxDialog}
%% <br />{@link wxTopLevelWindow}
%% <br />{@link wxWindow}
@@ -136,11 +136,11 @@ getColourData(#wx_ref{type=ThisT,ref=ThisRef}) ->
%% @spec (This::wxColourDialog()) -> ok
%% @doc Destroys this object, do not use object again
-destroy(Obj=#wx_ref{type=Type}) ->
+destroy(Obj=#wx_ref{type=Type}) ->
?CLASS(Type,wxColourDialog),
wxe_util:destroy(?DESTROY_OBJECT,Obj),
ok.
- %% From wxDialog
+ %% From wxDialog
%% @hidden
showModal(This) -> wxDialog:showModal(This).
%% @hidden
@@ -163,7 +163,7 @@ endModal(This,RetCode) -> wxDialog:endModal(This,RetCode).
createStdDialogButtonSizer(This,Flags) -> wxDialog:createStdDialogButtonSizer(This,Flags).
%% @hidden
createButtonSizer(This,Flags) -> wxDialog:createButtonSizer(This,Flags).
- %% From wxTopLevelWindow
+ %% From wxTopLevelWindow
%% @hidden
showFullScreen(This,Show, Options) -> wxTopLevelWindow:showFullScreen(This,Show, Options).
%% @hidden
@@ -210,7 +210,7 @@ getTitle(This) -> wxTopLevelWindow:getTitle(This).
getIcons(This) -> wxTopLevelWindow:getIcons(This).
%% @hidden
getIcon(This) -> wxTopLevelWindow:getIcon(This).
- %% From wxWindow
+ %% From wxWindow
%% @hidden
warpPointer(This,X,Y) -> wxWindow:warpPointer(This,X,Y).
%% @hidden
@@ -557,7 +557,7 @@ center(This) -> wxWindow:center(This).
captureMouse(This) -> wxWindow:captureMouse(This).
%% @hidden
cacheBestSize(This,Size) -> wxWindow:cacheBestSize(This,Size).
- %% From wxEvtHandler
+ %% From wxEvtHandler
%% @hidden
disconnect(This,EventType, Options) -> wxEvtHandler:disconnect(This,EventType, Options).
%% @hidden
diff --git a/lib/wx/src/gen/wxColourPickerCtrl.erl b/lib/wx/src/gen/wxColourPickerCtrl.erl
index 1f345b4294..4f0816e1fd 100644
--- a/lib/wx/src/gen/wxColourPickerCtrl.erl
+++ b/lib/wx/src/gen/wxColourPickerCtrl.erl
@@ -1,24 +1,24 @@
%%
%% %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%
%% This file is generated DO NOT EDIT
%% @doc See external documentation: <a href="http://www.wxwidgets.org/manuals/stable/wx_wxcolourpickerctrl.html">wxColourPickerCtrl</a>.
-%% <p>This class is derived (and can use functions) from:
+%% <p>This class is derived (and can use functions) from:
%% <br />{@link wxPickerBase}
%% <br />{@link wxControl}
%% <br />{@link wxWindow}
@@ -141,7 +141,7 @@ getColour(#wx_ref{type=ThisT,ref=ThisRef}) ->
%% @spec (This::wxColourPickerCtrl(),X::string()|term()) -> bool()|ok
%% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxcolourpickerctrl.html#wxcolourpickerctrlsetcolour">external documentation</a>.
-%% <br /> Alternatives:
+%% <br /> Alternatives:
%% <p><c>
%% setColour(This::wxColourPickerCtrl(), Text::string()) -> bool() </c>
%% </p>
@@ -162,11 +162,11 @@ setColour(#wx_ref{type=ThisT,ref=ThisRef},Col)
%% @spec (This::wxColourPickerCtrl()) -> ok
%% @doc Destroys this object, do not use object again
-destroy(Obj=#wx_ref{type=Type}) ->
+destroy(Obj=#wx_ref{type=Type}) ->
?CLASS(Type,wxColourPickerCtrl),
wxe_util:destroy(?DESTROY_OBJECT,Obj),
ok.
- %% From wxPickerBase
+ %% From wxPickerBase
%% @hidden
isPickerCtrlGrowable(This) -> wxPickerBase:isPickerCtrlGrowable(This).
%% @hidden
@@ -195,12 +195,12 @@ setTextCtrlProportion(This,Prop) -> wxPickerBase:setTextCtrlProportion(This,Prop
getInternalMargin(This) -> wxPickerBase:getInternalMargin(This).
%% @hidden
setInternalMargin(This,Newmargin) -> wxPickerBase:setInternalMargin(This,Newmargin).
- %% From wxControl
+ %% From wxControl
%% @hidden
setLabel(This,Label) -> wxControl:setLabel(This,Label).
%% @hidden
getLabel(This) -> wxControl:getLabel(This).
- %% From wxWindow
+ %% From wxWindow
%% @hidden
warpPointer(This,X,Y) -> wxWindow:warpPointer(This,X,Y).
%% @hidden
@@ -547,7 +547,7 @@ center(This) -> wxWindow:center(This).
captureMouse(This) -> wxWindow:captureMouse(This).
%% @hidden
cacheBestSize(This,Size) -> wxWindow:cacheBestSize(This,Size).
- %% From wxEvtHandler
+ %% From wxEvtHandler
%% @hidden
disconnect(This,EventType, Options) -> wxEvtHandler:disconnect(This,EventType, Options).
%% @hidden
diff --git a/lib/wx/src/gen/wxColourPickerEvent.erl b/lib/wx/src/gen/wxColourPickerEvent.erl
index 0ed131fc30..9ba431b841 100644
--- a/lib/wx/src/gen/wxColourPickerEvent.erl
+++ b/lib/wx/src/gen/wxColourPickerEvent.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%
%% This file is generated DO NOT EDIT
@@ -22,7 +22,7 @@
%% <dd><em>command_colourpicker_changed</em></dd></dl>
%% See also the message variant {@link wxEvtHandler:wxColourPicker(). #wxColourPicker{}} event record type.
%%
-%% <p>This class is derived (and can use functions) from:
+%% <p>This class is derived (and can use functions) from:
%% <br />{@link wxCommandEvent}
%% <br />{@link wxEvent}
%% </p>
@@ -52,7 +52,7 @@ getColour(#wx_ref{type=ThisT,ref=ThisRef}) ->
wxe_util:call(?wxColourPickerEvent_GetColour,
<<ThisRef:32/?UI>>).
- %% From wxCommandEvent
+ %% From wxCommandEvent
%% @hidden
setString(This,S) -> wxCommandEvent:setString(This,S).
%% @hidden
@@ -71,7 +71,7 @@ getInt(This) -> wxCommandEvent:getInt(This).
getExtraLong(This) -> wxCommandEvent:getExtraLong(This).
%% @hidden
getClientData(This) -> wxCommandEvent:getClientData(This).
- %% From wxEvent
+ %% From wxEvent
%% @hidden
stopPropagation(This) -> wxEvent:stopPropagation(This).
%% @hidden
diff --git a/lib/wx/src/gen/wxComboBox.erl b/lib/wx/src/gen/wxComboBox.erl
index 6a40aacd50..061e886734 100644
--- a/lib/wx/src/gen/wxComboBox.erl
+++ b/lib/wx/src/gen/wxComboBox.erl
@@ -1,24 +1,24 @@
%%
%% %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%
%% This file is generated DO NOT EDIT
%% @doc See external documentation: <a href="http://www.wxwidgets.org/manuals/stable/wx_wxcombobox.html">wxComboBox</a>.
-%% <p>This class is derived (and can use functions) from:
+%% <p>This class is derived (and can use functions) from:
%% <br />{@link wxControlWithItems}
%% <br />{@link wxControl}
%% <br />{@link wxWindow}
@@ -285,11 +285,11 @@ undo(#wx_ref{type=ThisT,ref=ThisRef}) ->
%% @spec (This::wxComboBox()) -> ok
%% @doc Destroys this object, do not use object again
-destroy(Obj=#wx_ref{type=Type}) ->
+destroy(Obj=#wx_ref{type=Type}) ->
?CLASS(Type,wxComboBox),
wxe_util:destroy(?DESTROY_OBJECT,Obj),
ok.
- %% From wxControlWithItems
+ %% From wxControlWithItems
%% @hidden
setStringSelection(This,S) -> wxControlWithItems:setStringSelection(This,S).
%% @hidden
@@ -328,12 +328,12 @@ appendStrings(This,Strings) -> wxControlWithItems:appendStrings(This,Strings).
append(This,Item,ClientData) -> wxControlWithItems:append(This,Item,ClientData).
%% @hidden
append(This,Item) -> wxControlWithItems:append(This,Item).
- %% From wxControl
+ %% From wxControl
%% @hidden
setLabel(This,Label) -> wxControl:setLabel(This,Label).
%% @hidden
getLabel(This) -> wxControl:getLabel(This).
- %% From wxWindow
+ %% From wxWindow
%% @hidden
warpPointer(This,X,Y) -> wxWindow:warpPointer(This,X,Y).
%% @hidden
@@ -680,7 +680,7 @@ center(This) -> wxWindow:center(This).
captureMouse(This) -> wxWindow:captureMouse(This).
%% @hidden
cacheBestSize(This,Size) -> wxWindow:cacheBestSize(This,Size).
- %% From wxEvtHandler
+ %% From wxEvtHandler
%% @hidden
disconnect(This,EventType, Options) -> wxEvtHandler:disconnect(This,EventType, Options).
%% @hidden
diff --git a/lib/wx/src/gen/wxCommandEvent.erl b/lib/wx/src/gen/wxCommandEvent.erl
index f1df933d78..57fb9cecda 100644
--- a/lib/wx/src/gen/wxCommandEvent.erl
+++ b/lib/wx/src/gen/wxCommandEvent.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%
%% This file is generated DO NOT EDIT
@@ -22,7 +22,7 @@
%% <dd><em>command_button_clicked</em>, <em>command_checkbox_clicked</em>, <em>command_choice_selected</em>, <em>command_listbox_selected</em>, <em>command_listbox_doubleclicked</em>, <em>command_text_updated</em>, <em>command_text_enter</em>, <em>command_menu_selected</em>, <em>command_slider_updated</em>, <em>command_radiobox_selected</em>, <em>command_radiobutton_selected</em>, <em>command_scrollbar_updated</em>, <em>command_vlbox_selected</em>, <em>command_combobox_selected</em>, <em>command_tool_rclicked</em>, <em>command_tool_enter</em>, <em>command_checklistbox_toggled</em>, <em>command_togglebutton_clicked</em>, <em>command_left_click</em>, <em>command_left_dclick</em>, <em>command_right_click</em>, <em>command_set_focus</em>, <em>command_kill_focus</em>, <em>command_enter</em></dd></dl>
%% See also the message variant {@link wxEvtHandler:wxCommand(). #wxCommand{}} event record type.
%%
-%% <p>This class is derived (and can use functions) from:
+%% <p>This class is derived (and can use functions) from:
%% <br />{@link wxEvent}
%% </p>
%% @type wxCommandEvent(). An object reference, The representation is internal
@@ -108,7 +108,7 @@ setString(#wx_ref{type=ThisT,ref=ThisRef},S)
wxe_util:cast(?wxCommandEvent_SetString,
<<ThisRef:32/?UI,(byte_size(S_UC)):32/?UI,(S_UC)/binary, 0:(((8- ((0+byte_size(S_UC)) band 16#7)) band 16#7))/unit:8>>).
- %% From wxEvent
+ %% From wxEvent
%% @hidden
stopPropagation(This) -> wxEvent:stopPropagation(This).
%% @hidden
diff --git a/lib/wx/src/gen/wxContextMenuEvent.erl b/lib/wx/src/gen/wxContextMenuEvent.erl
index 15167b0996..56ed82f37c 100644
--- a/lib/wx/src/gen/wxContextMenuEvent.erl
+++ b/lib/wx/src/gen/wxContextMenuEvent.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%
%% This file is generated DO NOT EDIT
@@ -22,7 +22,7 @@
%% <dd><em>context_menu</em></dd></dl>
%% See also the message variant {@link wxEvtHandler:wxContextMenu(). #wxContextMenu{}} event record type.
%%
-%% <p>This class is derived (and can use functions) from:
+%% <p>This class is derived (and can use functions) from:
%% <br />{@link wxCommandEvent}
%% <br />{@link wxEvent}
%% </p>
@@ -60,7 +60,7 @@ setPosition(#wx_ref{type=ThisT,ref=ThisRef},{PosX,PosY})
wxe_util:cast(?wxContextMenuEvent_SetPosition,
<<ThisRef:32/?UI,PosX:32/?UI,PosY:32/?UI>>).
- %% From wxCommandEvent
+ %% From wxCommandEvent
%% @hidden
setString(This,S) -> wxCommandEvent:setString(This,S).
%% @hidden
@@ -79,7 +79,7 @@ getInt(This) -> wxCommandEvent:getInt(This).
getExtraLong(This) -> wxCommandEvent:getExtraLong(This).
%% @hidden
getClientData(This) -> wxCommandEvent:getClientData(This).
- %% From wxEvent
+ %% From wxEvent
%% @hidden
stopPropagation(This) -> wxEvent:stopPropagation(This).
%% @hidden
diff --git a/lib/wx/src/gen/wxControl.erl b/lib/wx/src/gen/wxControl.erl
index 1088afcc43..e3f602e65a 100644
--- a/lib/wx/src/gen/wxControl.erl
+++ b/lib/wx/src/gen/wxControl.erl
@@ -1,24 +1,24 @@
%%
%% %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%
%% This file is generated DO NOT EDIT
%% @doc See external documentation: <a href="http://www.wxwidgets.org/manuals/stable/wx_wxcontrol.html">wxControl</a>.
-%% <p>This class is derived (and can use functions) from:
+%% <p>This class is derived (and can use functions) from:
%% <br />{@link wxWindow}
%% <br />{@link wxEvtHandler}
%% </p>
@@ -89,7 +89,7 @@ setLabel(#wx_ref{type=ThisT,ref=ThisRef},Label)
wxe_util:cast(?wxControl_SetLabel,
<<ThisRef:32/?UI,(byte_size(Label_UC)):32/?UI,(Label_UC)/binary, 0:(((8- ((0+byte_size(Label_UC)) band 16#7)) band 16#7))/unit:8>>).
- %% From wxWindow
+ %% From wxWindow
%% @hidden
warpPointer(This,X,Y) -> wxWindow:warpPointer(This,X,Y).
%% @hidden
@@ -436,7 +436,7 @@ center(This) -> wxWindow:center(This).
captureMouse(This) -> wxWindow:captureMouse(This).
%% @hidden
cacheBestSize(This,Size) -> wxWindow:cacheBestSize(This,Size).
- %% From wxEvtHandler
+ %% From wxEvtHandler
%% @hidden
disconnect(This,EventType, Options) -> wxEvtHandler:disconnect(This,EventType, Options).
%% @hidden
diff --git a/lib/wx/src/gen/wxControlWithItems.erl b/lib/wx/src/gen/wxControlWithItems.erl
index ff5e3aaedf..0838b75bad 100644
--- a/lib/wx/src/gen/wxControlWithItems.erl
+++ b/lib/wx/src/gen/wxControlWithItems.erl
@@ -1,24 +1,24 @@
%%
%% %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%
%% This file is generated DO NOT EDIT
%% @doc See external documentation: <a href="http://www.wxwidgets.org/manuals/stable/wx_wxcontrolwithitems.html">wxControlWithItems</a>.
-%% <p>This class is derived (and can use functions) from:
+%% <p>This class is derived (and can use functions) from:
%% <br />{@link wxControl}
%% <br />{@link wxWindow}
%% <br />{@link wxEvtHandler}
@@ -247,12 +247,12 @@ setStringSelection(#wx_ref{type=ThisT,ref=ThisRef},S)
wxe_util:call(?wxControlWithItems_SetStringSelection,
<<ThisRef:32/?UI,(byte_size(S_UC)):32/?UI,(S_UC)/binary, 0:(((8- ((0+byte_size(S_UC)) band 16#7)) band 16#7))/unit:8>>).
- %% From wxControl
+ %% From wxControl
%% @hidden
setLabel(This,Label) -> wxControl:setLabel(This,Label).
%% @hidden
getLabel(This) -> wxControl:getLabel(This).
- %% From wxWindow
+ %% From wxWindow
%% @hidden
warpPointer(This,X,Y) -> wxWindow:warpPointer(This,X,Y).
%% @hidden
@@ -599,7 +599,7 @@ center(This) -> wxWindow:center(This).
captureMouse(This) -> wxWindow:captureMouse(This).
%% @hidden
cacheBestSize(This,Size) -> wxWindow:cacheBestSize(This,Size).
- %% From wxEvtHandler
+ %% From wxEvtHandler
%% @hidden
disconnect(This,EventType, Options) -> wxEvtHandler:disconnect(This,EventType, Options).
%% @hidden
diff --git a/lib/wx/src/gen/wxCursor.erl b/lib/wx/src/gen/wxCursor.erl
index 4c2a46cc84..beb731fee3 100644
--- a/lib/wx/src/gen/wxCursor.erl
+++ b/lib/wx/src/gen/wxCursor.erl
@@ -1,24 +1,24 @@
%%
%% %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%
%% This file is generated DO NOT EDIT
%% @doc See external documentation: <a href="http://www.wxwidgets.org/manuals/stable/wx_wxcursor.html">wxCursor</a>.
-%% <p>This class is derived (and can use functions) from:
+%% <p>This class is derived (and can use functions) from:
%% <br />{@link wxBitmap}
%% </p>
%% @type wxCursor(). An object reference, The representation is internal
@@ -46,7 +46,7 @@ new() ->
%% @spec (X::integer()|term()) -> wxCursor()
%% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxcursor.html#wxcursorwxcursor">external documentation</a>.
-%% <br /> Alternatives:
+%% <br /> Alternatives:
%% <p><c>
%% new(CursorId::integer()) -> wxCursor() </c>
%% </p>
@@ -90,11 +90,11 @@ ok(#wx_ref{type=ThisT,ref=ThisRef}) ->
%% @spec (This::wxCursor()) -> ok
%% @doc Destroys this object, do not use object again
-destroy(Obj=#wx_ref{type=Type}) ->
+destroy(Obj=#wx_ref{type=Type}) ->
?CLASS(Type,wxCursor),
wxe_util:destroy(?DESTROY_OBJECT,Obj),
ok.
- %% From wxBitmap
+ %% From wxBitmap
%% @hidden
setWidth(This,Width) -> wxBitmap:setWidth(This,Width).
%% @hidden
diff --git a/lib/wx/src/gen/wxDC.erl b/lib/wx/src/gen/wxDC.erl
index 17bf77c331..9bce1249f8 100644
--- a/lib/wx/src/gen/wxDC.erl
+++ b/lib/wx/src/gen/wxDC.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%
%% This file is generated DO NOT EDIT
@@ -705,7 +705,7 @@ setBrush(#wx_ref{type=ThisT,ref=ThisRef},#wx_ref{type=BrushT,ref=BrushRef}) ->
%% @spec (This::wxDC(),X::term()) -> ok
%% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxdc.html#wxdcsetclippingregion">external documentation</a>.
-%% <br /> Alternatives:
+%% <br /> Alternatives:
%% <p><c>
%% setClippingRegion(This::wxDC(), Region::wxRegion:wxRegion()) -> ok </c>
%% </p>
diff --git a/lib/wx/src/gen/wxDataObject.erl b/lib/wx/src/gen/wxDataObject.erl
index 801bd3dfba..bad6d96fb5 100644
--- a/lib/wx/src/gen/wxDataObject.erl
+++ b/lib/wx/src/gen/wxDataObject.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%
%% This file is generated DO NOT EDIT
diff --git a/lib/wx/src/gen/wxDateEvent.erl b/lib/wx/src/gen/wxDateEvent.erl
index 9885d6729a..b4b010e122 100644
--- a/lib/wx/src/gen/wxDateEvent.erl
+++ b/lib/wx/src/gen/wxDateEvent.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%
%% This file is generated DO NOT EDIT
@@ -22,7 +22,7 @@
%% <dd><em>date_changed</em></dd></dl>
%% See also the message variant {@link wxEvtHandler:wxDate(). #wxDate{}} event record type.
%%
-%% <p>This class is derived (and can use functions) from:
+%% <p>This class is derived (and can use functions) from:
%% <br />{@link wxCommandEvent}
%% <br />{@link wxEvent}
%% </p>
@@ -52,7 +52,7 @@ getDate(#wx_ref{type=ThisT,ref=ThisRef}) ->
wxe_util:call(?wxDateEvent_GetDate,
<<ThisRef:32/?UI>>).
- %% From wxCommandEvent
+ %% From wxCommandEvent
%% @hidden
setString(This,S) -> wxCommandEvent:setString(This,S).
%% @hidden
@@ -71,7 +71,7 @@ getInt(This) -> wxCommandEvent:getInt(This).
getExtraLong(This) -> wxCommandEvent:getExtraLong(This).
%% @hidden
getClientData(This) -> wxCommandEvent:getClientData(This).
- %% From wxEvent
+ %% From wxEvent
%% @hidden
stopPropagation(This) -> wxEvent:stopPropagation(This).
%% @hidden
diff --git a/lib/wx/src/gen/wxDatePickerCtrl.erl b/lib/wx/src/gen/wxDatePickerCtrl.erl
index b9ac9cdbad..2de51ce71d 100644
--- a/lib/wx/src/gen/wxDatePickerCtrl.erl
+++ b/lib/wx/src/gen/wxDatePickerCtrl.erl
@@ -1,24 +1,24 @@
%%
%% %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%
%% This file is generated DO NOT EDIT
%% @doc See external documentation: <a href="http://www.wxwidgets.org/manuals/stable/wx_wxdatepickerctrl.html">wxDatePickerCtrl</a>.
-%% <p>This class is derived (and can use functions) from:
+%% <p>This class is derived (and can use functions) from:
%% <br />{@link wxPickerBase}
%% <br />{@link wxControl}
%% <br />{@link wxWindow}
@@ -142,11 +142,11 @@ setValue(#wx_ref{type=ThisT,ref=ThisRef},Date)
%% @spec (This::wxDatePickerCtrl()) -> ok
%% @doc Destroys this object, do not use object again
-destroy(Obj=#wx_ref{type=Type}) ->
+destroy(Obj=#wx_ref{type=Type}) ->
?CLASS(Type,wxDatePickerCtrl),
wxe_util:destroy(?DESTROY_OBJECT,Obj),
ok.
- %% From wxPickerBase
+ %% From wxPickerBase
%% @hidden
isPickerCtrlGrowable(This) -> wxPickerBase:isPickerCtrlGrowable(This).
%% @hidden
@@ -175,12 +175,12 @@ setTextCtrlProportion(This,Prop) -> wxPickerBase:setTextCtrlProportion(This,Prop
getInternalMargin(This) -> wxPickerBase:getInternalMargin(This).
%% @hidden
setInternalMargin(This,Newmargin) -> wxPickerBase:setInternalMargin(This,Newmargin).
- %% From wxControl
+ %% From wxControl
%% @hidden
setLabel(This,Label) -> wxControl:setLabel(This,Label).
%% @hidden
getLabel(This) -> wxControl:getLabel(This).
- %% From wxWindow
+ %% From wxWindow
%% @hidden
warpPointer(This,X,Y) -> wxWindow:warpPointer(This,X,Y).
%% @hidden
@@ -527,7 +527,7 @@ center(This) -> wxWindow:center(This).
captureMouse(This) -> wxWindow:captureMouse(This).
%% @hidden
cacheBestSize(This,Size) -> wxWindow:cacheBestSize(This,Size).
- %% From wxEvtHandler
+ %% From wxEvtHandler
%% @hidden
disconnect(This,EventType, Options) -> wxEvtHandler:disconnect(This,EventType, Options).
%% @hidden
diff --git a/lib/wx/src/gen/wxDialog.erl b/lib/wx/src/gen/wxDialog.erl
index 75b8064bf7..8c0bd2cd76 100644
--- a/lib/wx/src/gen/wxDialog.erl
+++ b/lib/wx/src/gen/wxDialog.erl
@@ -1,24 +1,24 @@
%%
%% %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%
%% This file is generated DO NOT EDIT
%% @doc See external documentation: <a href="http://www.wxwidgets.org/manuals/stable/wx_wxdialog.html">wxDialog</a>.
-%% <p>This class is derived (and can use functions) from:
+%% <p>This class is derived (and can use functions) from:
%% <br />{@link wxTopLevelWindow}
%% <br />{@link wxWindow}
%% <br />{@link wxEvtHandler}
@@ -219,11 +219,11 @@ showModal(#wx_ref{type=ThisT,ref=ThisRef}) ->
%% @spec (This::wxDialog()) -> ok
%% @doc Destroys this object, do not use object again
-destroy(Obj=#wx_ref{type=Type}) ->
+destroy(Obj=#wx_ref{type=Type}) ->
?CLASS(Type,wxDialog),
wxe_util:destroy(?DESTROY_OBJECT,Obj),
ok.
- %% From wxTopLevelWindow
+ %% From wxTopLevelWindow
%% @hidden
showFullScreen(This,Show, Options) -> wxTopLevelWindow:showFullScreen(This,Show, Options).
%% @hidden
@@ -270,7 +270,7 @@ getTitle(This) -> wxTopLevelWindow:getTitle(This).
getIcons(This) -> wxTopLevelWindow:getIcons(This).
%% @hidden
getIcon(This) -> wxTopLevelWindow:getIcon(This).
- %% From wxWindow
+ %% From wxWindow
%% @hidden
warpPointer(This,X,Y) -> wxWindow:warpPointer(This,X,Y).
%% @hidden
@@ -617,7 +617,7 @@ center(This) -> wxWindow:center(This).
captureMouse(This) -> wxWindow:captureMouse(This).
%% @hidden
cacheBestSize(This,Size) -> wxWindow:cacheBestSize(This,Size).
- %% From wxEvtHandler
+ %% From wxEvtHandler
%% @hidden
disconnect(This,EventType, Options) -> wxEvtHandler:disconnect(This,EventType, Options).
%% @hidden
diff --git a/lib/wx/src/gen/wxDirDialog.erl b/lib/wx/src/gen/wxDirDialog.erl
index 4329be13bd..7849dce0a7 100644
--- a/lib/wx/src/gen/wxDirDialog.erl
+++ b/lib/wx/src/gen/wxDirDialog.erl
@@ -1,24 +1,24 @@
%%
%% %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%
%% This file is generated DO NOT EDIT
%% @doc See external documentation: <a href="http://www.wxwidgets.org/manuals/stable/wx_wxdirdialog.html">wxDirDialog</a>.
-%% <p>This class is derived (and can use functions) from:
+%% <p>This class is derived (and can use functions) from:
%% <br />{@link wxDialog}
%% <br />{@link wxTopLevelWindow}
%% <br />{@link wxWindow}
@@ -140,11 +140,11 @@ setPath(#wx_ref{type=ThisT,ref=ThisRef},Path)
%% @spec (This::wxDirDialog()) -> ok
%% @doc Destroys this object, do not use object again
-destroy(Obj=#wx_ref{type=Type}) ->
+destroy(Obj=#wx_ref{type=Type}) ->
?CLASS(Type,wxDirDialog),
wxe_util:destroy(?DESTROY_OBJECT,Obj),
ok.
- %% From wxDialog
+ %% From wxDialog
%% @hidden
showModal(This) -> wxDialog:showModal(This).
%% @hidden
@@ -167,7 +167,7 @@ endModal(This,RetCode) -> wxDialog:endModal(This,RetCode).
createStdDialogButtonSizer(This,Flags) -> wxDialog:createStdDialogButtonSizer(This,Flags).
%% @hidden
createButtonSizer(This,Flags) -> wxDialog:createButtonSizer(This,Flags).
- %% From wxTopLevelWindow
+ %% From wxTopLevelWindow
%% @hidden
showFullScreen(This,Show, Options) -> wxTopLevelWindow:showFullScreen(This,Show, Options).
%% @hidden
@@ -214,7 +214,7 @@ getTitle(This) -> wxTopLevelWindow:getTitle(This).
getIcons(This) -> wxTopLevelWindow:getIcons(This).
%% @hidden
getIcon(This) -> wxTopLevelWindow:getIcon(This).
- %% From wxWindow
+ %% From wxWindow
%% @hidden
warpPointer(This,X,Y) -> wxWindow:warpPointer(This,X,Y).
%% @hidden
@@ -561,7 +561,7 @@ center(This) -> wxWindow:center(This).
captureMouse(This) -> wxWindow:captureMouse(This).
%% @hidden
cacheBestSize(This,Size) -> wxWindow:cacheBestSize(This,Size).
- %% From wxEvtHandler
+ %% From wxEvtHandler
%% @hidden
disconnect(This,EventType, Options) -> wxEvtHandler:disconnect(This,EventType, Options).
%% @hidden
diff --git a/lib/wx/src/gen/wxDirPickerCtrl.erl b/lib/wx/src/gen/wxDirPickerCtrl.erl
index 787d3606f5..7fb70b71e3 100644
--- a/lib/wx/src/gen/wxDirPickerCtrl.erl
+++ b/lib/wx/src/gen/wxDirPickerCtrl.erl
@@ -1,24 +1,24 @@
%%
%% %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%
%% This file is generated DO NOT EDIT
%% @doc See external documentation: <a href="http://www.wxwidgets.org/manuals/stable/wx_wxdirpickerctrl.html">wxDirPickerCtrl</a>.
-%% <p>This class is derived (and can use functions) from:
+%% <p>This class is derived (and can use functions) from:
%% <br />{@link wxPickerBase}
%% <br />{@link wxControl}
%% <br />{@link wxWindow}
@@ -152,11 +152,11 @@ setPath(#wx_ref{type=ThisT,ref=ThisRef},Str)
%% @spec (This::wxDirPickerCtrl()) -> ok
%% @doc Destroys this object, do not use object again
-destroy(Obj=#wx_ref{type=Type}) ->
+destroy(Obj=#wx_ref{type=Type}) ->
?CLASS(Type,wxDirPickerCtrl),
wxe_util:destroy(?DESTROY_OBJECT,Obj),
ok.
- %% From wxPickerBase
+ %% From wxPickerBase
%% @hidden
isPickerCtrlGrowable(This) -> wxPickerBase:isPickerCtrlGrowable(This).
%% @hidden
@@ -185,12 +185,12 @@ setTextCtrlProportion(This,Prop) -> wxPickerBase:setTextCtrlProportion(This,Prop
getInternalMargin(This) -> wxPickerBase:getInternalMargin(This).
%% @hidden
setInternalMargin(This,Newmargin) -> wxPickerBase:setInternalMargin(This,Newmargin).
- %% From wxControl
+ %% From wxControl
%% @hidden
setLabel(This,Label) -> wxControl:setLabel(This,Label).
%% @hidden
getLabel(This) -> wxControl:getLabel(This).
- %% From wxWindow
+ %% From wxWindow
%% @hidden
warpPointer(This,X,Y) -> wxWindow:warpPointer(This,X,Y).
%% @hidden
@@ -537,7 +537,7 @@ center(This) -> wxWindow:center(This).
captureMouse(This) -> wxWindow:captureMouse(This).
%% @hidden
cacheBestSize(This,Size) -> wxWindow:cacheBestSize(This,Size).
- %% From wxEvtHandler
+ %% From wxEvtHandler
%% @hidden
disconnect(This,EventType, Options) -> wxEvtHandler:disconnect(This,EventType, Options).
%% @hidden
diff --git a/lib/wx/src/gen/wxDisplayChangedEvent.erl b/lib/wx/src/gen/wxDisplayChangedEvent.erl
index 280a51ffc2..c86ef62462 100644
--- a/lib/wx/src/gen/wxDisplayChangedEvent.erl
+++ b/lib/wx/src/gen/wxDisplayChangedEvent.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%
%% This file is generated DO NOT EDIT
@@ -22,7 +22,7 @@
%% <dd><em>display_changed</em></dd></dl>
%% See also the message variant {@link wxEvtHandler:wxDisplayChanged(). #wxDisplayChanged{}} event record type.
%%
-%% <p>This class is derived (and can use functions) from:
+%% <p>This class is derived (and can use functions) from:
%% <br />{@link wxEvent}
%% </p>
%% @type wxDisplayChangedEvent(). An object reference, The representation is internal
@@ -41,7 +41,7 @@
parent_class(wxEvent) -> true;
parent_class(_Class) -> erlang:error({badtype, ?MODULE}).
- %% From wxEvent
+ %% From wxEvent
%% @hidden
stopPropagation(This) -> wxEvent:stopPropagation(This).
%% @hidden
diff --git a/lib/wx/src/gen/wxEraseEvent.erl b/lib/wx/src/gen/wxEraseEvent.erl
index 66fc161aba..77139b6790 100644
--- a/lib/wx/src/gen/wxEraseEvent.erl
+++ b/lib/wx/src/gen/wxEraseEvent.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%
%% This file is generated DO NOT EDIT
@@ -22,7 +22,7 @@
%% <dd><em>erase_background</em></dd></dl>
%% See also the message variant {@link wxEvtHandler:wxErase(). #wxErase{}} event record type.
%%
-%% <p>This class is derived (and can use functions) from:
+%% <p>This class is derived (and can use functions) from:
%% <br />{@link wxEvent}
%% </p>
%% @type wxEraseEvent(). An object reference, The representation is internal
@@ -48,7 +48,7 @@ getDC(#wx_ref{type=ThisT,ref=ThisRef}) ->
wxe_util:call(?wxEraseEvent_GetDC,
<<ThisRef:32/?UI>>).
- %% From wxEvent
+ %% From wxEvent
%% @hidden
stopPropagation(This) -> wxEvent:stopPropagation(This).
%% @hidden
diff --git a/lib/wx/src/gen/wxEvent.erl b/lib/wx/src/gen/wxEvent.erl
index dda4c0189d..403fd89f1f 100644
--- a/lib/wx/src/gen/wxEvent.erl
+++ b/lib/wx/src/gen/wxEvent.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%
%% This file is generated DO NOT EDIT
diff --git a/lib/wx/src/gen/wxEvtHandler.erl b/lib/wx/src/gen/wxEvtHandler.erl
index 0d4e224fc5..f155351b66 100644
--- a/lib/wx/src/gen/wxEvtHandler.erl
+++ b/lib/wx/src/gen/wxEvtHandler.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%
%% This file is generated DO NOT EDIT
diff --git a/lib/wx/src/gen/wxFileDataObject.erl b/lib/wx/src/gen/wxFileDataObject.erl
index 513f15eb00..2fcfbd5374 100644
--- a/lib/wx/src/gen/wxFileDataObject.erl
+++ b/lib/wx/src/gen/wxFileDataObject.erl
@@ -1,24 +1,24 @@
%%
%% %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%
%% This file is generated DO NOT EDIT
%% @doc See external documentation: <a href="http://www.wxwidgets.org/manuals/stable/wx_wxfiledataobject.html">wxFileDataObject</a>.
-%% <p>This class is derived (and can use functions) from:
+%% <p>This class is derived (and can use functions) from:
%% <br />{@link wxDataObject}
%% </p>
%% @type wxFileDataObject(). An object reference, The representation is internal
@@ -60,8 +60,8 @@ getFilenames(#wx_ref{type=ThisT,ref=ThisRef}) ->
%% @spec (This::wxFileDataObject()) -> ok
%% @doc Destroys this object, do not use object again
-destroy(Obj=#wx_ref{type=Type}) ->
+destroy(Obj=#wx_ref{type=Type}) ->
?CLASS(Type,wxFileDataObject),
wxe_util:destroy(?wxFileDataObject_destroy,Obj),
ok.
- %% From wxDataObject
+ %% From wxDataObject
diff --git a/lib/wx/src/gen/wxFileDialog.erl b/lib/wx/src/gen/wxFileDialog.erl
index 22b39aa150..cba9705335 100644
--- a/lib/wx/src/gen/wxFileDialog.erl
+++ b/lib/wx/src/gen/wxFileDialog.erl
@@ -1,24 +1,24 @@
%%
%% %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%
%% This file is generated DO NOT EDIT
%% @doc See external documentation: <a href="http://www.wxwidgets.org/manuals/stable/wx_wxfiledialog.html">wxFileDialog</a>.
-%% <p>This class is derived (and can use functions) from:
+%% <p>This class is derived (and can use functions) from:
%% <br />{@link wxDialog}
%% <br />{@link wxTopLevelWindow}
%% <br />{@link wxWindow}
@@ -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>.
@@ -224,11 +221,11 @@ setWildcard(#wx_ref{type=ThisT,ref=ThisRef},WildCard)
%% @spec (This::wxFileDialog()) -> ok
%% @doc Destroys this object, do not use object again
-destroy(Obj=#wx_ref{type=Type}) ->
+destroy(Obj=#wx_ref{type=Type}) ->
?CLASS(Type,wxFileDialog),
wxe_util:destroy(?DESTROY_OBJECT,Obj),
ok.
- %% From wxDialog
+ %% From wxDialog
%% @hidden
showModal(This) -> wxDialog:showModal(This).
%% @hidden
@@ -251,7 +248,7 @@ endModal(This,RetCode) -> wxDialog:endModal(This,RetCode).
createStdDialogButtonSizer(This,Flags) -> wxDialog:createStdDialogButtonSizer(This,Flags).
%% @hidden
createButtonSizer(This,Flags) -> wxDialog:createButtonSizer(This,Flags).
- %% From wxTopLevelWindow
+ %% From wxTopLevelWindow
%% @hidden
showFullScreen(This,Show, Options) -> wxTopLevelWindow:showFullScreen(This,Show, Options).
%% @hidden
@@ -298,7 +295,7 @@ getTitle(This) -> wxTopLevelWindow:getTitle(This).
getIcons(This) -> wxTopLevelWindow:getIcons(This).
%% @hidden
getIcon(This) -> wxTopLevelWindow:getIcon(This).
- %% From wxWindow
+ %% From wxWindow
%% @hidden
warpPointer(This,X,Y) -> wxWindow:warpPointer(This,X,Y).
%% @hidden
@@ -645,7 +642,7 @@ center(This) -> wxWindow:center(This).
captureMouse(This) -> wxWindow:captureMouse(This).
%% @hidden
cacheBestSize(This,Size) -> wxWindow:cacheBestSize(This,Size).
- %% From wxEvtHandler
+ %% From wxEvtHandler
%% @hidden
disconnect(This,EventType, Options) -> wxEvtHandler:disconnect(This,EventType, Options).
%% @hidden
diff --git a/lib/wx/src/gen/wxFileDirPickerEvent.erl b/lib/wx/src/gen/wxFileDirPickerEvent.erl
index 0f9166e542..cc4880b88c 100644
--- a/lib/wx/src/gen/wxFileDirPickerEvent.erl
+++ b/lib/wx/src/gen/wxFileDirPickerEvent.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%
%% This file is generated DO NOT EDIT
@@ -22,7 +22,7 @@
%% <dd><em>command_filepicker_changed</em>, <em>command_dirpicker_changed</em></dd></dl>
%% See also the message variant {@link wxEvtHandler:wxFileDirPicker(). #wxFileDirPicker{}} event record type.
%%
-%% <p>This class is derived (and can use functions) from:
+%% <p>This class is derived (and can use functions) from:
%% <br />{@link wxCommandEvent}
%% <br />{@link wxEvent}
%% </p>
@@ -52,7 +52,7 @@ getPath(#wx_ref{type=ThisT,ref=ThisRef}) ->
wxe_util:call(?wxFileDirPickerEvent_GetPath,
<<ThisRef:32/?UI>>).
- %% From wxCommandEvent
+ %% From wxCommandEvent
%% @hidden
setString(This,S) -> wxCommandEvent:setString(This,S).
%% @hidden
@@ -71,7 +71,7 @@ getInt(This) -> wxCommandEvent:getInt(This).
getExtraLong(This) -> wxCommandEvent:getExtraLong(This).
%% @hidden
getClientData(This) -> wxCommandEvent:getClientData(This).
- %% From wxEvent
+ %% From wxEvent
%% @hidden
stopPropagation(This) -> wxEvent:stopPropagation(This).
%% @hidden
diff --git a/lib/wx/src/gen/wxFilePickerCtrl.erl b/lib/wx/src/gen/wxFilePickerCtrl.erl
index c182d20f36..a3034aaa86 100644
--- a/lib/wx/src/gen/wxFilePickerCtrl.erl
+++ b/lib/wx/src/gen/wxFilePickerCtrl.erl
@@ -1,24 +1,24 @@
%%
%% %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%
%% This file is generated DO NOT EDIT
%% @doc See external documentation: <a href="http://www.wxwidgets.org/manuals/stable/wx_wxfilepickerctrl.html">wxFilePickerCtrl</a>.
-%% <p>This class is derived (and can use functions) from:
+%% <p>This class is derived (and can use functions) from:
%% <br />{@link wxPickerBase}
%% <br />{@link wxControl}
%% <br />{@link wxWindow}
@@ -154,11 +154,11 @@ setPath(#wx_ref{type=ThisT,ref=ThisRef},Str)
%% @spec (This::wxFilePickerCtrl()) -> ok
%% @doc Destroys this object, do not use object again
-destroy(Obj=#wx_ref{type=Type}) ->
+destroy(Obj=#wx_ref{type=Type}) ->
?CLASS(Type,wxFilePickerCtrl),
wxe_util:destroy(?DESTROY_OBJECT,Obj),
ok.
- %% From wxPickerBase
+ %% From wxPickerBase
%% @hidden
isPickerCtrlGrowable(This) -> wxPickerBase:isPickerCtrlGrowable(This).
%% @hidden
@@ -187,12 +187,12 @@ setTextCtrlProportion(This,Prop) -> wxPickerBase:setTextCtrlProportion(This,Prop
getInternalMargin(This) -> wxPickerBase:getInternalMargin(This).
%% @hidden
setInternalMargin(This,Newmargin) -> wxPickerBase:setInternalMargin(This,Newmargin).
- %% From wxControl
+ %% From wxControl
%% @hidden
setLabel(This,Label) -> wxControl:setLabel(This,Label).
%% @hidden
getLabel(This) -> wxControl:getLabel(This).
- %% From wxWindow
+ %% From wxWindow
%% @hidden
warpPointer(This,X,Y) -> wxWindow:warpPointer(This,X,Y).
%% @hidden
@@ -539,7 +539,7 @@ center(This) -> wxWindow:center(This).
captureMouse(This) -> wxWindow:captureMouse(This).
%% @hidden
cacheBestSize(This,Size) -> wxWindow:cacheBestSize(This,Size).
- %% From wxEvtHandler
+ %% From wxEvtHandler
%% @hidden
disconnect(This,EventType, Options) -> wxEvtHandler:disconnect(This,EventType, Options).
%% @hidden
diff --git a/lib/wx/src/gen/wxFindReplaceData.erl b/lib/wx/src/gen/wxFindReplaceData.erl
index ac09a23e89..52eafa8398 100644
--- a/lib/wx/src/gen/wxFindReplaceData.erl
+++ b/lib/wx/src/gen/wxFindReplaceData.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%
%% This file is generated DO NOT EDIT
@@ -95,7 +95,7 @@ setReplaceString(#wx_ref{type=ThisT,ref=ThisRef},Str)
%% @spec (This::wxFindReplaceData()) -> ok
%% @doc Destroys this object, do not use object again
-destroy(Obj=#wx_ref{type=Type}) ->
+destroy(Obj=#wx_ref{type=Type}) ->
?CLASS(Type,wxFindReplaceData),
wxe_util:destroy(?DESTROY_OBJECT,Obj),
ok.
diff --git a/lib/wx/src/gen/wxFindReplaceDialog.erl b/lib/wx/src/gen/wxFindReplaceDialog.erl
index 82da24abf5..b37fd41831 100644
--- a/lib/wx/src/gen/wxFindReplaceDialog.erl
+++ b/lib/wx/src/gen/wxFindReplaceDialog.erl
@@ -1,24 +1,24 @@
%%
%% %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%
%% This file is generated DO NOT EDIT
%% @doc See external documentation: <a href="http://www.wxwidgets.org/manuals/stable/wx_wxfindreplacedialog.html">wxFindReplaceDialog</a>.
-%% <p>This class is derived (and can use functions) from:
+%% <p>This class is derived (and can use functions) from:
%% <br />{@link wxDialog}
%% <br />{@link wxTopLevelWindow}
%% <br />{@link wxWindow}
@@ -140,11 +140,11 @@ getData(#wx_ref{type=ThisT,ref=ThisRef}) ->
%% @spec (This::wxFindReplaceDialog()) -> ok
%% @doc Destroys this object, do not use object again
-destroy(Obj=#wx_ref{type=Type}) ->
+destroy(Obj=#wx_ref{type=Type}) ->
?CLASS(Type,wxFindReplaceDialog),
wxe_util:destroy(?DESTROY_OBJECT,Obj),
ok.
- %% From wxDialog
+ %% From wxDialog
%% @hidden
showModal(This) -> wxDialog:showModal(This).
%% @hidden
@@ -167,7 +167,7 @@ endModal(This,RetCode) -> wxDialog:endModal(This,RetCode).
createStdDialogButtonSizer(This,Flags) -> wxDialog:createStdDialogButtonSizer(This,Flags).
%% @hidden
createButtonSizer(This,Flags) -> wxDialog:createButtonSizer(This,Flags).
- %% From wxTopLevelWindow
+ %% From wxTopLevelWindow
%% @hidden
showFullScreen(This,Show, Options) -> wxTopLevelWindow:showFullScreen(This,Show, Options).
%% @hidden
@@ -214,7 +214,7 @@ getTitle(This) -> wxTopLevelWindow:getTitle(This).
getIcons(This) -> wxTopLevelWindow:getIcons(This).
%% @hidden
getIcon(This) -> wxTopLevelWindow:getIcon(This).
- %% From wxWindow
+ %% From wxWindow
%% @hidden
warpPointer(This,X,Y) -> wxWindow:warpPointer(This,X,Y).
%% @hidden
@@ -561,7 +561,7 @@ center(This) -> wxWindow:center(This).
captureMouse(This) -> wxWindow:captureMouse(This).
%% @hidden
cacheBestSize(This,Size) -> wxWindow:cacheBestSize(This,Size).
- %% From wxEvtHandler
+ %% From wxEvtHandler
%% @hidden
disconnect(This,EventType, Options) -> wxEvtHandler:disconnect(This,EventType, Options).
%% @hidden
diff --git a/lib/wx/src/gen/wxFlexGridSizer.erl b/lib/wx/src/gen/wxFlexGridSizer.erl
index 5387d04043..9471cc8a01 100644
--- a/lib/wx/src/gen/wxFlexGridSizer.erl
+++ b/lib/wx/src/gen/wxFlexGridSizer.erl
@@ -1,24 +1,24 @@
%%
%% %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%
%% This file is generated DO NOT EDIT
%% @doc See external documentation: <a href="http://www.wxwidgets.org/manuals/stable/wx_wxflexgridsizer.html">wxFlexGridSizer</a>.
-%% <p>This class is derived (and can use functions) from:
+%% <p>This class is derived (and can use functions) from:
%% <br />{@link wxGridSizer}
%% <br />{@link wxSizer}
%% </p>
@@ -163,11 +163,11 @@ setNonFlexibleGrowMode(#wx_ref{type=ThisT,ref=ThisRef},Mode)
%% @spec (This::wxFlexGridSizer()) -> ok
%% @doc Destroys this object, do not use object again
-destroy(Obj=#wx_ref{type=Type}) ->
+destroy(Obj=#wx_ref{type=Type}) ->
?CLASS(Type,wxFlexGridSizer),
wxe_util:destroy(?DESTROY_OBJECT,Obj),
ok.
- %% From wxGridSizer
+ %% From wxGridSizer
%% @hidden
setVGap(This,Gap) -> wxGridSizer:setVGap(This,Gap).
%% @hidden
@@ -184,7 +184,7 @@ getRows(This) -> wxGridSizer:getRows(This).
getHGap(This) -> wxGridSizer:getHGap(This).
%% @hidden
getCols(This) -> wxGridSizer:getCols(This).
- %% From wxSizer
+ %% From wxSizer
%% @hidden
show(This,Index, Options) -> wxSizer:show(This,Index, Options).
%% @hidden
diff --git a/lib/wx/src/gen/wxFocusEvent.erl b/lib/wx/src/gen/wxFocusEvent.erl
index 48a0f65e4f..46f2e2a3df 100644
--- a/lib/wx/src/gen/wxFocusEvent.erl
+++ b/lib/wx/src/gen/wxFocusEvent.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%
%% This file is generated DO NOT EDIT
@@ -22,7 +22,7 @@
%% <dd><em>set_focus</em>, <em>kill_focus</em></dd></dl>
%% See also the message variant {@link wxEvtHandler:wxFocus(). #wxFocus{}} event record type.
%%
-%% <p>This class is derived (and can use functions) from:
+%% <p>This class is derived (and can use functions) from:
%% <br />{@link wxEvent}
%% </p>
%% @type wxFocusEvent(). An object reference, The representation is internal
@@ -48,7 +48,7 @@ getWindow(#wx_ref{type=ThisT,ref=ThisRef}) ->
wxe_util:call(?wxFocusEvent_GetWindow,
<<ThisRef:32/?UI>>).
- %% From wxEvent
+ %% From wxEvent
%% @hidden
stopPropagation(This) -> wxEvent:stopPropagation(This).
%% @hidden
diff --git a/lib/wx/src/gen/wxFont.erl b/lib/wx/src/gen/wxFont.erl
index 4ee829d83d..4afc53cfa8 100644
--- a/lib/wx/src/gen/wxFont.erl
+++ b/lib/wx/src/gen/wxFont.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%
%% This file is generated DO NOT EDIT
@@ -221,7 +221,7 @@ setWeight(#wx_ref{type=ThisT,ref=ThisRef},Weight)
%% @spec (This::wxFont()) -> ok
%% @doc Destroys this object, do not use object again
-destroy(Obj=#wx_ref{type=Type}) ->
+destroy(Obj=#wx_ref{type=Type}) ->
?CLASS(Type,wxFont),
wxe_util:destroy(?DESTROY_OBJECT,Obj),
ok.
diff --git a/lib/wx/src/gen/wxFontData.erl b/lib/wx/src/gen/wxFontData.erl
index 9b8de9212f..33015b7ca9 100644
--- a/lib/wx/src/gen/wxFontData.erl
+++ b/lib/wx/src/gen/wxFontData.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%
%% This file is generated DO NOT EDIT
@@ -147,7 +147,7 @@ setShowHelp(#wx_ref{type=ThisT,ref=ThisRef},Flag)
%% @spec (This::wxFontData()) -> ok
%% @doc Destroys this object, do not use object again
-destroy(Obj=#wx_ref{type=Type}) ->
+destroy(Obj=#wx_ref{type=Type}) ->
?CLASS(Type,wxFontData),
wxe_util:destroy(?DESTROY_OBJECT,Obj),
ok.
diff --git a/lib/wx/src/gen/wxFontDialog.erl b/lib/wx/src/gen/wxFontDialog.erl
index 009e320117..357bfe532d 100644
--- a/lib/wx/src/gen/wxFontDialog.erl
+++ b/lib/wx/src/gen/wxFontDialog.erl
@@ -1,24 +1,24 @@
%%
%% %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%
%% This file is generated DO NOT EDIT
%% @doc See external documentation: <a href="http://www.wxwidgets.org/manuals/stable/wx_wxfontdialog.html">wxFontDialog</a>.
-%% <p>This class is derived (and can use functions) from:
+%% <p>This class is derived (and can use functions) from:
%% <br />{@link wxDialog}
%% <br />{@link wxTopLevelWindow}
%% <br />{@link wxWindow}
@@ -116,11 +116,11 @@ getFontData(#wx_ref{type=ThisT,ref=ThisRef}) ->
%% @spec (This::wxFontDialog()) -> ok
%% @doc Destroys this object, do not use object again
-destroy(Obj=#wx_ref{type=Type}) ->
+destroy(Obj=#wx_ref{type=Type}) ->
?CLASS(Type,wxFontDialog),
wxe_util:destroy(?DESTROY_OBJECT,Obj),
ok.
- %% From wxDialog
+ %% From wxDialog
%% @hidden
showModal(This) -> wxDialog:showModal(This).
%% @hidden
@@ -143,7 +143,7 @@ endModal(This,RetCode) -> wxDialog:endModal(This,RetCode).
createStdDialogButtonSizer(This,Flags) -> wxDialog:createStdDialogButtonSizer(This,Flags).
%% @hidden
createButtonSizer(This,Flags) -> wxDialog:createButtonSizer(This,Flags).
- %% From wxTopLevelWindow
+ %% From wxTopLevelWindow
%% @hidden
showFullScreen(This,Show, Options) -> wxTopLevelWindow:showFullScreen(This,Show, Options).
%% @hidden
@@ -190,7 +190,7 @@ getTitle(This) -> wxTopLevelWindow:getTitle(This).
getIcons(This) -> wxTopLevelWindow:getIcons(This).
%% @hidden
getIcon(This) -> wxTopLevelWindow:getIcon(This).
- %% From wxWindow
+ %% From wxWindow
%% @hidden
warpPointer(This,X,Y) -> wxWindow:warpPointer(This,X,Y).
%% @hidden
@@ -537,7 +537,7 @@ center(This) -> wxWindow:center(This).
captureMouse(This) -> wxWindow:captureMouse(This).
%% @hidden
cacheBestSize(This,Size) -> wxWindow:cacheBestSize(This,Size).
- %% From wxEvtHandler
+ %% From wxEvtHandler
%% @hidden
disconnect(This,EventType, Options) -> wxEvtHandler:disconnect(This,EventType, Options).
%% @hidden
diff --git a/lib/wx/src/gen/wxFontPickerCtrl.erl b/lib/wx/src/gen/wxFontPickerCtrl.erl
index fca934df49..93d63cc930 100644
--- a/lib/wx/src/gen/wxFontPickerCtrl.erl
+++ b/lib/wx/src/gen/wxFontPickerCtrl.erl
@@ -1,24 +1,24 @@
%%
%% %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%
%% This file is generated DO NOT EDIT
%% @doc See external documentation: <a href="http://www.wxwidgets.org/manuals/stable/wx_wxfontpickerctrl.html">wxFontPickerCtrl</a>.
-%% <p>This class is derived (and can use functions) from:
+%% <p>This class is derived (and can use functions) from:
%% <br />{@link wxPickerBase}
%% <br />{@link wxControl}
%% <br />{@link wxWindow}
@@ -165,11 +165,11 @@ setMaxPointSize(#wx_ref{type=ThisT,ref=ThisRef},Max)
%% @spec (This::wxFontPickerCtrl()) -> ok
%% @doc Destroys this object, do not use object again
-destroy(Obj=#wx_ref{type=Type}) ->
+destroy(Obj=#wx_ref{type=Type}) ->
?CLASS(Type,wxFontPickerCtrl),
wxe_util:destroy(?DESTROY_OBJECT,Obj),
ok.
- %% From wxPickerBase
+ %% From wxPickerBase
%% @hidden
isPickerCtrlGrowable(This) -> wxPickerBase:isPickerCtrlGrowable(This).
%% @hidden
@@ -198,12 +198,12 @@ setTextCtrlProportion(This,Prop) -> wxPickerBase:setTextCtrlProportion(This,Prop
getInternalMargin(This) -> wxPickerBase:getInternalMargin(This).
%% @hidden
setInternalMargin(This,Newmargin) -> wxPickerBase:setInternalMargin(This,Newmargin).
- %% From wxControl
+ %% From wxControl
%% @hidden
setLabel(This,Label) -> wxControl:setLabel(This,Label).
%% @hidden
getLabel(This) -> wxControl:getLabel(This).
- %% From wxWindow
+ %% From wxWindow
%% @hidden
warpPointer(This,X,Y) -> wxWindow:warpPointer(This,X,Y).
%% @hidden
@@ -550,7 +550,7 @@ center(This) -> wxWindow:center(This).
captureMouse(This) -> wxWindow:captureMouse(This).
%% @hidden
cacheBestSize(This,Size) -> wxWindow:cacheBestSize(This,Size).
- %% From wxEvtHandler
+ %% From wxEvtHandler
%% @hidden
disconnect(This,EventType, Options) -> wxEvtHandler:disconnect(This,EventType, Options).
%% @hidden
diff --git a/lib/wx/src/gen/wxFontPickerEvent.erl b/lib/wx/src/gen/wxFontPickerEvent.erl
index 28c1e0fc98..6eb456767f 100644
--- a/lib/wx/src/gen/wxFontPickerEvent.erl
+++ b/lib/wx/src/gen/wxFontPickerEvent.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%
%% This file is generated DO NOT EDIT
@@ -22,7 +22,7 @@
%% <dd><em>command_fontpicker_changed</em></dd></dl>
%% See also the message variant {@link wxEvtHandler:wxFontPicker(). #wxFontPicker{}} event record type.
%%
-%% <p>This class is derived (and can use functions) from:
+%% <p>This class is derived (and can use functions) from:
%% <br />{@link wxCommandEvent}
%% <br />{@link wxEvent}
%% </p>
@@ -52,7 +52,7 @@ getFont(#wx_ref{type=ThisT,ref=ThisRef}) ->
wxe_util:call(?wxFontPickerEvent_GetFont,
<<ThisRef:32/?UI>>).
- %% From wxCommandEvent
+ %% From wxCommandEvent
%% @hidden
setString(This,S) -> wxCommandEvent:setString(This,S).
%% @hidden
@@ -71,7 +71,7 @@ getInt(This) -> wxCommandEvent:getInt(This).
getExtraLong(This) -> wxCommandEvent:getExtraLong(This).
%% @hidden
getClientData(This) -> wxCommandEvent:getClientData(This).
- %% From wxEvent
+ %% From wxEvent
%% @hidden
stopPropagation(This) -> wxEvent:stopPropagation(This).
%% @hidden
diff --git a/lib/wx/src/gen/wxFrame.erl b/lib/wx/src/gen/wxFrame.erl
index 136651c001..5cd1e3dfd3 100644
--- a/lib/wx/src/gen/wxFrame.erl
+++ b/lib/wx/src/gen/wxFrame.erl
@@ -1,24 +1,24 @@
%%
%% %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%
%% This file is generated DO NOT EDIT
%% @doc See external documentation: <a href="http://www.wxwidgets.org/manuals/stable/wx_wxframe.html">wxFrame</a>.
-%% <p>This class is derived (and can use functions) from:
+%% <p>This class is derived (and can use functions) from:
%% <br />{@link wxTopLevelWindow}
%% <br />{@link wxWindow}
%% <br />{@link wxEvtHandler}
@@ -284,11 +284,11 @@ setToolBar(#wx_ref{type=ThisT,ref=ThisRef},#wx_ref{type=ToolbarT,ref=ToolbarRef}
%% @spec (This::wxFrame()) -> ok
%% @doc Destroys this object, do not use object again
-destroy(Obj=#wx_ref{type=Type}) ->
+destroy(Obj=#wx_ref{type=Type}) ->
?CLASS(Type,wxFrame),
wxe_util:destroy(?DESTROY_OBJECT,Obj),
ok.
- %% From wxTopLevelWindow
+ %% From wxTopLevelWindow
%% @hidden
showFullScreen(This,Show, Options) -> wxTopLevelWindow:showFullScreen(This,Show, Options).
%% @hidden
@@ -335,7 +335,7 @@ getTitle(This) -> wxTopLevelWindow:getTitle(This).
getIcons(This) -> wxTopLevelWindow:getIcons(This).
%% @hidden
getIcon(This) -> wxTopLevelWindow:getIcon(This).
- %% From wxWindow
+ %% From wxWindow
%% @hidden
warpPointer(This,X,Y) -> wxWindow:warpPointer(This,X,Y).
%% @hidden
@@ -686,7 +686,7 @@ center(This) -> wxWindow:center(This).
captureMouse(This) -> wxWindow:captureMouse(This).
%% @hidden
cacheBestSize(This,Size) -> wxWindow:cacheBestSize(This,Size).
- %% From wxEvtHandler
+ %% From wxEvtHandler
%% @hidden
disconnect(This,EventType, Options) -> wxEvtHandler:disconnect(This,EventType, Options).
%% @hidden
diff --git a/lib/wx/src/gen/wxGBSizerItem.erl b/lib/wx/src/gen/wxGBSizerItem.erl
index 4d79e5c3db..90dd98fdf2 100644
--- a/lib/wx/src/gen/wxGBSizerItem.erl
+++ b/lib/wx/src/gen/wxGBSizerItem.erl
@@ -1,24 +1,24 @@
%%
%% %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%
%% This file is generated DO NOT EDIT
%% @doc See external documentation: <a href="http://www.wxwidgets.org/manuals/stable/wx_wxgbsizeritem.html">wxGBSizerItem</a>.
-%% <p>This class is derived (and can use functions) from:
+%% <p>This class is derived (and can use functions) from:
%% <br />{@link wxSizerItem}
%% </p>
%% @type wxGBSizerItem(). An object reference, The representation is internal
@@ -41,7 +41,7 @@
parent_class(wxSizerItem) -> true;
parent_class(_Class) -> erlang:error({badtype, ?MODULE}).
- %% From wxSizerItem
+ %% From wxSizerItem
%% @hidden
show(This,Show) -> wxSizerItem:show(This,Show).
%% @hidden
diff --git a/lib/wx/src/gen/wxGLCanvas.erl b/lib/wx/src/gen/wxGLCanvas.erl
index 25d4ddc9f2..3e0d1bd9ae 100644
--- a/lib/wx/src/gen/wxGLCanvas.erl
+++ b/lib/wx/src/gen/wxGLCanvas.erl
@@ -1,24 +1,24 @@
%%
%% %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%
%% This file is generated DO NOT EDIT
%% @doc See external documentation: <a href="http://www.wxwidgets.org/manuals/stable/wx_wxglcanvas.html">wxGLCanvas</a>.
-%% <p>This class is derived (and can use functions) from:
+%% <p>This class is derived (and can use functions) from:
%% <br />{@link wxWindow}
%% <br />{@link wxEvtHandler}
%% </p>
@@ -81,7 +81,7 @@ new(Parent)
%% @spec (Parent::wxWindow:wxWindow(),X::term()) -> wxGLCanvas()
%% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxglcanvas.html#wxglcanvaswxglcanvas">external documentation</a>.
-%% <br /> Alternatives:
+%% <br /> Alternatives:
%% <p><c>
%% new(Parent::wxWindow:wxWindow(), Shared::wxGLContext:wxGLContext() | wxGLCanvas()) -> new(Parent,Shared, []) </c></p>
%% <p><c>
@@ -156,11 +156,11 @@ swapBuffers(#wx_ref{type=ThisT,ref=ThisRef}) ->
%% @spec (This::wxGLCanvas()) -> ok
%% @doc Destroys this object, do not use object again
-destroy(Obj=#wx_ref{type=Type}) ->
+destroy(Obj=#wx_ref{type=Type}) ->
?CLASS(Type,wxGLCanvas),
wxe_util:destroy(?DESTROY_OBJECT,Obj),
ok.
- %% From wxWindow
+ %% From wxWindow
%% @hidden
warpPointer(This,X,Y) -> wxWindow:warpPointer(This,X,Y).
%% @hidden
@@ -511,7 +511,7 @@ center(This) -> wxWindow:center(This).
captureMouse(This) -> wxWindow:captureMouse(This).
%% @hidden
cacheBestSize(This,Size) -> wxWindow:cacheBestSize(This,Size).
- %% From wxEvtHandler
+ %% From wxEvtHandler
%% @hidden
disconnect(This,EventType, Options) -> wxEvtHandler:disconnect(This,EventType, Options).
%% @hidden
diff --git a/lib/wx/src/gen/wxGauge.erl b/lib/wx/src/gen/wxGauge.erl
index 3a5e117e19..5028b29bba 100644
--- a/lib/wx/src/gen/wxGauge.erl
+++ b/lib/wx/src/gen/wxGauge.erl
@@ -1,24 +1,24 @@
%%
%% %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%
%% This file is generated DO NOT EDIT
%% @doc See external documentation: <a href="http://www.wxwidgets.org/manuals/stable/wx_wxgauge.html">wxGauge</a>.
-%% <p>This class is derived (and can use functions) from:
+%% <p>This class is derived (and can use functions) from:
%% <br />{@link wxControl}
%% <br />{@link wxWindow}
%% <br />{@link wxEvtHandler}
@@ -202,16 +202,16 @@ pulse(#wx_ref{type=ThisT,ref=ThisRef}) ->
%% @spec (This::wxGauge()) -> ok
%% @doc Destroys this object, do not use object again
-destroy(Obj=#wx_ref{type=Type}) ->
+destroy(Obj=#wx_ref{type=Type}) ->
?CLASS(Type,wxGauge),
wxe_util:destroy(?DESTROY_OBJECT,Obj),
ok.
- %% From wxControl
+ %% From wxControl
%% @hidden
setLabel(This,Label) -> wxControl:setLabel(This,Label).
%% @hidden
getLabel(This) -> wxControl:getLabel(This).
- %% From wxWindow
+ %% From wxWindow
%% @hidden
warpPointer(This,X,Y) -> wxWindow:warpPointer(This,X,Y).
%% @hidden
@@ -558,7 +558,7 @@ center(This) -> wxWindow:center(This).
captureMouse(This) -> wxWindow:captureMouse(This).
%% @hidden
cacheBestSize(This,Size) -> wxWindow:cacheBestSize(This,Size).
- %% From wxEvtHandler
+ %% From wxEvtHandler
%% @hidden
disconnect(This,EventType, Options) -> wxEvtHandler:disconnect(This,EventType, Options).
%% @hidden
diff --git a/lib/wx/src/gen/wxGenericDirCtrl.erl b/lib/wx/src/gen/wxGenericDirCtrl.erl
index 4146a3bacc..97944710f0 100644
--- a/lib/wx/src/gen/wxGenericDirCtrl.erl
+++ b/lib/wx/src/gen/wxGenericDirCtrl.erl
@@ -1,24 +1,24 @@
%%
%% %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%
%% This file is generated DO NOT EDIT
%% @doc See external documentation: <a href="http://www.wxwidgets.org/manuals/stable/wx_wxgenericdirctrl.html">wxGenericDirCtrl</a>.
-%% <p>This class is derived (and can use functions) from:
+%% <p>This class is derived (and can use functions) from:
%% <br />{@link wxControl}
%% <br />{@link wxWindow}
%% <br />{@link wxEvtHandler}
@@ -191,7 +191,7 @@ getFilterIndex(#wx_ref{type=ThisT,ref=ThisRef}) ->
wxe_util:call(?wxGenericDirCtrl_GetFilterIndex,
<<ThisRef:32/?UI>>).
-%% @spec (This::wxGenericDirCtrl()) -> wxTreeItemId()
+%% @spec (This::wxGenericDirCtrl()) -> integer()
%% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxgenericdirctrl.html#wxgenericdirctrlgetrootid">external documentation</a>.
getRootId(#wx_ref{type=ThisT,ref=ThisRef}) ->
?CLASS(ThisT,wxGenericDirCtrl),
@@ -249,16 +249,16 @@ setPath(#wx_ref{type=ThisT,ref=ThisRef},Path)
%% @spec (This::wxGenericDirCtrl()) -> ok
%% @doc Destroys this object, do not use object again
-destroy(Obj=#wx_ref{type=Type}) ->
+destroy(Obj=#wx_ref{type=Type}) ->
?CLASS(Type,wxGenericDirCtrl),
wxe_util:destroy(?DESTROY_OBJECT,Obj),
ok.
- %% From wxControl
+ %% From wxControl
%% @hidden
setLabel(This,Label) -> wxControl:setLabel(This,Label).
%% @hidden
getLabel(This) -> wxControl:getLabel(This).
- %% From wxWindow
+ %% From wxWindow
%% @hidden
warpPointer(This,X,Y) -> wxWindow:warpPointer(This,X,Y).
%% @hidden
@@ -605,7 +605,7 @@ center(This) -> wxWindow:center(This).
captureMouse(This) -> wxWindow:captureMouse(This).
%% @hidden
cacheBestSize(This,Size) -> wxWindow:cacheBestSize(This,Size).
- %% From wxEvtHandler
+ %% From wxEvtHandler
%% @hidden
disconnect(This,EventType, Options) -> wxEvtHandler:disconnect(This,EventType, Options).
%% @hidden
diff --git a/lib/wx/src/gen/wxGraphicsBrush.erl b/lib/wx/src/gen/wxGraphicsBrush.erl
index c1db82dcb3..e1ad01567d 100644
--- a/lib/wx/src/gen/wxGraphicsBrush.erl
+++ b/lib/wx/src/gen/wxGraphicsBrush.erl
@@ -1,24 +1,24 @@
%%
%% %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%
%% This file is generated DO NOT EDIT
%% @doc See external documentation: <a href="http://www.wxwidgets.org/manuals/stable/wx_wxgraphicsbrush.html">wxGraphicsBrush</a>.
-%% <p>This class is derived (and can use functions) from:
+%% <p>This class is derived (and can use functions) from:
%% <br />{@link wxGraphicsObject}
%% </p>
%% @type wxGraphicsBrush(). An object reference, The representation is internal
@@ -36,7 +36,7 @@
parent_class(wxGraphicsObject) -> true;
parent_class(_Class) -> erlang:error({badtype, ?MODULE}).
- %% From wxGraphicsObject
+ %% From wxGraphicsObject
%% @hidden
isNull(This) -> wxGraphicsObject:isNull(This).
%% @hidden
diff --git a/lib/wx/src/gen/wxGraphicsContext.erl b/lib/wx/src/gen/wxGraphicsContext.erl
index 885578657d..040867cb11 100644
--- a/lib/wx/src/gen/wxGraphicsContext.erl
+++ b/lib/wx/src/gen/wxGraphicsContext.erl
@@ -1,24 +1,24 @@
%%
%% %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%
%% This file is generated DO NOT EDIT
%% @doc See external documentation: <a href="http://www.wxwidgets.org/manuals/stable/wx_wxgraphicscontext.html">wxGraphicsContext</a>.
-%% <p>This class is derived (and can use functions) from:
+%% <p>This class is derived (and can use functions) from:
%% <br />{@link wxGraphicsObject}
%% </p>
%% @type wxGraphicsContext(). An object reference, The representation is internal
@@ -256,7 +256,7 @@ drawText(#wx_ref{type=ThisT,ref=ThisRef},Str,X,Y)
%% @spec (This::wxGraphicsContext(),Str::string(),X::float(),Y::float(),X::float()|term()) -> ok
%% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxgraphicscontext.html#wxgraphicscontextdrawtext">external documentation</a>.
-%% <br /> Alternatives:
+%% <br /> Alternatives:
%% <p><c>
%% drawText(This::wxGraphicsContext(), Str::string(), X::float(), Y::float(), Angle::float()) -> ok </c>
%% </p>
@@ -454,7 +454,7 @@ strokeLines(#wx_ref{type=ThisT,ref=ThisRef},N,{BeginPointsX,BeginPointsY},{EndPo
wxe_util:cast(?wxGraphicsContext_StrokeLines_3,
<<ThisRef:32/?UI,N:32/?UI,BeginPointsX:64/float,BeginPointsY:64/float,EndPointsX:64/float,EndPointsY:64/float>>).
- %% From wxGraphicsObject
+ %% From wxGraphicsObject
%% @hidden
isNull(This) -> wxGraphicsObject:isNull(This).
%% @hidden
diff --git a/lib/wx/src/gen/wxGraphicsFont.erl b/lib/wx/src/gen/wxGraphicsFont.erl
index 07c964d9b9..19b2172176 100644
--- a/lib/wx/src/gen/wxGraphicsFont.erl
+++ b/lib/wx/src/gen/wxGraphicsFont.erl
@@ -1,24 +1,24 @@
%%
%% %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%
%% This file is generated DO NOT EDIT
%% @doc See external documentation: <a href="http://www.wxwidgets.org/manuals/stable/wx_wxgraphicsfont.html">wxGraphicsFont</a>.
-%% <p>This class is derived (and can use functions) from:
+%% <p>This class is derived (and can use functions) from:
%% <br />{@link wxGraphicsObject}
%% </p>
%% @type wxGraphicsFont(). An object reference, The representation is internal
@@ -36,7 +36,7 @@
parent_class(wxGraphicsObject) -> true;
parent_class(_Class) -> erlang:error({badtype, ?MODULE}).
- %% From wxGraphicsObject
+ %% From wxGraphicsObject
%% @hidden
isNull(This) -> wxGraphicsObject:isNull(This).
%% @hidden
diff --git a/lib/wx/src/gen/wxGraphicsMatrix.erl b/lib/wx/src/gen/wxGraphicsMatrix.erl
index b8c7b3eefb..38ea007c58 100644
--- a/lib/wx/src/gen/wxGraphicsMatrix.erl
+++ b/lib/wx/src/gen/wxGraphicsMatrix.erl
@@ -1,24 +1,24 @@
%%
%% %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%
%% This file is generated DO NOT EDIT
%% @doc See external documentation: <a href="http://www.wxwidgets.org/manuals/stable/wx_wxgraphicsmatrix.html">wxGraphicsMatrix</a>.
-%% <p>This class is derived (and can use functions) from:
+%% <p>This class is derived (and can use functions) from:
%% <br />{@link wxGraphicsObject}
%% </p>
%% @type wxGraphicsMatrix(). An object reference, The representation is internal
@@ -142,7 +142,7 @@ transformDistance(#wx_ref{type=ThisT,ref=ThisRef}) ->
wxe_util:call(?wxGraphicsMatrix_TransformDistance,
<<ThisRef:32/?UI>>).
- %% From wxGraphicsObject
+ %% From wxGraphicsObject
%% @hidden
isNull(This) -> wxGraphicsObject:isNull(This).
%% @hidden
diff --git a/lib/wx/src/gen/wxGraphicsObject.erl b/lib/wx/src/gen/wxGraphicsObject.erl
index 5b8b44ceca..7e63285b7a 100644
--- a/lib/wx/src/gen/wxGraphicsObject.erl
+++ b/lib/wx/src/gen/wxGraphicsObject.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%
%% This file is generated DO NOT EDIT
diff --git a/lib/wx/src/gen/wxGraphicsPath.erl b/lib/wx/src/gen/wxGraphicsPath.erl
index 7b27545d5f..ff2dfb07a4 100644
--- a/lib/wx/src/gen/wxGraphicsPath.erl
+++ b/lib/wx/src/gen/wxGraphicsPath.erl
@@ -1,24 +1,24 @@
%%
%% %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%
%% This file is generated DO NOT EDIT
%% @doc See external documentation: <a href="http://www.wxwidgets.org/manuals/stable/wx_wxgraphicspath.html">wxGraphicsPath</a>.
-%% <p>This class is derived (and can use functions) from:
+%% <p>This class is derived (and can use functions) from:
%% <br />{@link wxGraphicsObject}
%% </p>
%% @type wxGraphicsPath(). An object reference, The representation is internal
@@ -175,7 +175,7 @@ contains(This,C={CX,CY})
%% @spec (This::wxGraphicsPath(),X::float()|term(),X::float()|term()) -> bool()
%% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxgraphicspath.html#wxgraphicspathcontains">external documentation</a>.
-%% <br /> Alternatives:
+%% <br /> Alternatives:
%% <p><c>
%% contains(This::wxGraphicsPath(), X::float(), Y::float()) -> contains(This,X,Y, []) </c></p>
%% <p><c>
@@ -229,7 +229,7 @@ transform(#wx_ref{type=ThisT,ref=ThisRef},#wx_ref{type=MatrixT,ref=MatrixRef}) -
wxe_util:cast(?wxGraphicsPath_Transform,
<<ThisRef:32/?UI,MatrixRef:32/?UI>>).
- %% From wxGraphicsObject
+ %% From wxGraphicsObject
%% @hidden
isNull(This) -> wxGraphicsObject:isNull(This).
%% @hidden
diff --git a/lib/wx/src/gen/wxGraphicsPen.erl b/lib/wx/src/gen/wxGraphicsPen.erl
index 6abf52f025..395b05f8af 100644
--- a/lib/wx/src/gen/wxGraphicsPen.erl
+++ b/lib/wx/src/gen/wxGraphicsPen.erl
@@ -1,24 +1,24 @@
%%
%% %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%
%% This file is generated DO NOT EDIT
%% @doc See external documentation: <a href="http://www.wxwidgets.org/manuals/stable/wx_wxgraphicspen.html">wxGraphicsPen</a>.
-%% <p>This class is derived (and can use functions) from:
+%% <p>This class is derived (and can use functions) from:
%% <br />{@link wxGraphicsObject}
%% </p>
%% @type wxGraphicsPen(). An object reference, The representation is internal
@@ -36,7 +36,7 @@
parent_class(wxGraphicsObject) -> true;
parent_class(_Class) -> erlang:error({badtype, ?MODULE}).
- %% From wxGraphicsObject
+ %% From wxGraphicsObject
%% @hidden
isNull(This) -> wxGraphicsObject:isNull(This).
%% @hidden
diff --git a/lib/wx/src/gen/wxGraphicsRenderer.erl b/lib/wx/src/gen/wxGraphicsRenderer.erl
index 457ffe2b6e..ed53ebf468 100644
--- a/lib/wx/src/gen/wxGraphicsRenderer.erl
+++ b/lib/wx/src/gen/wxGraphicsRenderer.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%
%% This file is generated DO NOT EDIT
diff --git a/lib/wx/src/gen/wxGrid.erl b/lib/wx/src/gen/wxGrid.erl
index 2a45bc3d6b..7b62ec33a4 100644
--- a/lib/wx/src/gen/wxGrid.erl
+++ b/lib/wx/src/gen/wxGrid.erl
@@ -1,24 +1,24 @@
%%
%% %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%
%% This file is generated DO NOT EDIT
%% @doc See external documentation: <a href="http://www.wxwidgets.org/manuals/stable/wx_wxgrid.html">wxGrid</a>.
-%% <p>This class is derived (and can use functions) from:
+%% <p>This class is derived (and can use functions) from:
%% <br />{@link wxScrolledWindow}
%% <br />{@link wxPanel}
%% <br />{@link wxWindow}
@@ -146,7 +146,7 @@ new(Parent,Id)
%% @spec (Parent::wxWindow:wxWindow(),X::integer(),X::integer()|term()) -> wxGrid()
%% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxgrid.html#wxgridwxgrid">external documentation</a>.
-%% <br /> Alternatives:
+%% <br /> Alternatives:
%% <p><c>
%% new(Parent::wxWindow:wxWindow(), X::integer(), Y::integer()) -> new(Parent,X,Y, []) </c></p>
%% <p><c>
@@ -1104,7 +1104,7 @@ isVisible(This,Coords={CoordsR,CoordsC})
%% @spec (This::wxGrid(),X::integer()|term(),X::integer()|term()) -> bool()
%% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxgrid.html#wxgridisvisible">external documentation</a>.
-%% <br /> Alternatives:
+%% <br /> Alternatives:
%% <p><c>
%% isVisible(This::wxGrid(), Row::integer(), Col::integer()) -> isVisible(This,Row,Col, []) </c></p>
%% <p><c>
@@ -1361,7 +1361,7 @@ setCellBackgroundColour(#wx_ref{type=ThisT,ref=ThisRef},Col)
%% @spec (This::wxGrid(),X::integer()|term(),X::integer(),X::term()|integer()) -> ok
%% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxgrid.html#wxgridsetcellbackgroundcolour">external documentation</a>.
-%% <br /> Alternatives:
+%% <br /> Alternatives:
%% <p><c>
%% setCellBackgroundColour(This::wxGrid(), Row::integer(), Col::integer(), Val::wx:colour()) -> ok </c>
%% </p>
@@ -1416,7 +1416,7 @@ setCellTextColour(#wx_ref{type=ThisT,ref=ThisRef},Col)
%% @spec (This::wxGrid(),X::integer()|term(),X::integer(),X::term()|integer()) -> ok
%% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxgrid.html#wxgridsetcelltextcolour">external documentation</a>.
-%% <br /> Alternatives:
+%% <br /> Alternatives:
%% <p><c>
%% setCellTextColour(This::wxGrid(), Row::integer(), Col::integer(), Val::wx:colour()) -> ok </c>
%% </p>
@@ -1445,7 +1445,7 @@ setCellValue(#wx_ref{type=ThisT,ref=ThisRef},{CoordsR,CoordsC},S)
%% @spec (This::wxGrid(),X::integer()|string(),X::integer(),X::string()|integer()) -> ok
%% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxgrid.html#wxgridsetcellvalue">external documentation</a>.
-%% <br /> Alternatives:
+%% <br /> Alternatives:
%% <p><c>
%% setCellValue(This::wxGrid(), Row::integer(), Col::integer(), S::string()) -> ok </c>
%% </p>
@@ -1868,11 +1868,11 @@ yToRow(#wx_ref{type=ThisT,ref=ThisRef},Y)
%% @spec (This::wxGrid()) -> ok
%% @doc Destroys this object, do not use object again
-destroy(Obj=#wx_ref{type=Type}) ->
+destroy(Obj=#wx_ref{type=Type}) ->
?CLASS(Type,wxGrid),
wxe_util:destroy(?DESTROY_OBJECT,Obj),
ok.
- %% From wxScrolledWindow
+ %% From wxScrolledWindow
%% @hidden
setTargetWindow(This,Target) -> wxScrolledWindow:setTargetWindow(This,Target).
%% @hidden
@@ -1901,10 +1901,10 @@ calcUnscrolledPosition(This,Pt) -> wxScrolledWindow:calcUnscrolledPosition(This,
calcScrolledPosition(This,X,Y) -> wxScrolledWindow:calcScrolledPosition(This,X,Y).
%% @hidden
calcScrolledPosition(This,Pt) -> wxScrolledWindow:calcScrolledPosition(This,Pt).
- %% From wxPanel
+ %% From wxPanel
%% @hidden
initDialog(This) -> wxPanel:initDialog(This).
- %% From wxWindow
+ %% From wxWindow
%% @hidden
warpPointer(This,X,Y) -> wxWindow:warpPointer(This,X,Y).
%% @hidden
@@ -2251,7 +2251,7 @@ center(This) -> wxWindow:center(This).
captureMouse(This) -> wxWindow:captureMouse(This).
%% @hidden
cacheBestSize(This,Size) -> wxWindow:cacheBestSize(This,Size).
- %% From wxEvtHandler
+ %% From wxEvtHandler
%% @hidden
disconnect(This,EventType, Options) -> wxEvtHandler:disconnect(This,EventType, Options).
%% @hidden
diff --git a/lib/wx/src/gen/wxGridBagSizer.erl b/lib/wx/src/gen/wxGridBagSizer.erl
index 56dc6092ad..d8cc210d3b 100644
--- a/lib/wx/src/gen/wxGridBagSizer.erl
+++ b/lib/wx/src/gen/wxGridBagSizer.erl
@@ -1,24 +1,24 @@
%%
%% %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%
%% This file is generated DO NOT EDIT
%% @doc See external documentation: <a href="http://www.wxwidgets.org/manuals/stable/wx_wxgridbagsizer.html">wxGridBagSizer</a>.
-%% <p>This class is derived (and can use functions) from:
+%% <p>This class is derived (and can use functions) from:
%% <br />{@link wxFlexGridSizer}
%% <br />{@link wxGridSizer}
%% <br />{@link wxSizer}
@@ -86,7 +86,7 @@ add(#wx_ref{type=ThisT,ref=ThisRef},#wx_ref{type=ItemT,ref=ItemRef}) ->
%% @spec (This::wxGridBagSizer(),X::integer()|term(),X::integer()|term()) -> wxSizerItem:wxSizerItem()
%% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxgridbagsizer.html#wxgridbagsizeradd">external documentation</a>.
-%% <br /> Alternatives:
+%% <br /> Alternatives:
%% <p><c>
%% add(This::wxGridBagSizer(), Width::integer(), Height::integer()) -> add(This,Width,Height, []) </c></p>
%% <p><c>
@@ -123,7 +123,7 @@ add(#wx_ref{type=ThisT,ref=ThisRef},#wx_ref{type=WindowT,ref=WindowRef}, Options
%% @spec (This::wxGridBagSizer(),X::integer()|term(),X::integer()|term(),X::term()) -> wxSizerItem:wxSizerItem()
%% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxgridbagsizer.html#wxgridbagsizeradd">external documentation</a>.
-%% <br /> Alternatives:
+%% <br /> Alternatives:
%% <p><c>
%% add(This::wxGridBagSizer(), Width::integer(), Height::integer(), Pos::{R::integer(),C::integer()}) -> add(This,Width,Height,Pos, []) </c></p>
%% <p><c>
@@ -197,7 +197,7 @@ checkForIntersection(This,Item)
%% @spec (This::wxGridBagSizer(),X::term(),X::term()) -> bool()
%% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxgridbagsizer.html#wxgridbagsizercheckforintersection">external documentation</a>.
-%% <br /> Alternatives:
+%% <br /> Alternatives:
%% <p><c>
%% checkForIntersection(This::wxGridBagSizer(), Pos::{R::integer(),C::integer()}, Span::{RS::integer(),CS::integer()}) -> checkForIntersection(This,Pos,Span, []) </c></p>
%% <p><c>
@@ -284,7 +284,7 @@ getEmptyCellSize(#wx_ref{type=ThisT,ref=ThisRef}) ->
%% @spec (This::wxGridBagSizer(),X::integer()|term()) -> {R::integer(),C::integer()}
%% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxgridbagsizer.html#wxgridbagsizergetitemposition">external documentation</a>.
-%% <br /> Alternatives:
+%% <br /> Alternatives:
%% <p><c>
%% getItemPosition(This::wxGridBagSizer(), Index::integer()) -> {R::integer(),C::integer()} </c>
%% </p>
@@ -309,7 +309,7 @@ getItemPosition(#wx_ref{type=ThisT,ref=ThisRef},#wx_ref{type=WindowT,ref=WindowR
%% @spec (This::wxGridBagSizer(),X::integer()|term()) -> {RS::integer(),CS::integer()}
%% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxgridbagsizer.html#wxgridbagsizergetitemspan">external documentation</a>.
-%% <br /> Alternatives:
+%% <br /> Alternatives:
%% <p><c>
%% getItemSpan(This::wxGridBagSizer(), Index::integer()) -> {RS::integer(),CS::integer()} </c>
%% </p>
@@ -342,7 +342,7 @@ setEmptyCellSize(#wx_ref{type=ThisT,ref=ThisRef},{SzW,SzH})
%% @spec (This::wxGridBagSizer(),X::integer()|term(),Pos::{R::integer(),C::integer()}) -> bool()
%% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxgridbagsizer.html#wxgridbagsizersetitemposition">external documentation</a>.
-%% <br /> Alternatives:
+%% <br /> Alternatives:
%% <p><c>
%% setItemPosition(This::wxGridBagSizer(), Index::integer(), Pos::{R::integer(),C::integer()}) -> bool() </c>
%% </p>
@@ -368,7 +368,7 @@ setItemPosition(#wx_ref{type=ThisT,ref=ThisRef},#wx_ref{type=WindowT,ref=WindowR
%% @spec (This::wxGridBagSizer(),X::integer()|term(),Span::{RS::integer(),CS::integer()}) -> bool()
%% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxgridbagsizer.html#wxgridbagsizersetitemspan">external documentation</a>.
-%% <br /> Alternatives:
+%% <br /> Alternatives:
%% <p><c>
%% setItemSpan(This::wxGridBagSizer(), Index::integer(), Span::{RS::integer(),CS::integer()}) -> bool() </c>
%% </p>
@@ -394,11 +394,11 @@ setItemSpan(#wx_ref{type=ThisT,ref=ThisRef},#wx_ref{type=WindowT,ref=WindowRef},
%% @spec (This::wxGridBagSizer()) -> ok
%% @doc Destroys this object, do not use object again
-destroy(Obj=#wx_ref{type=Type}) ->
+destroy(Obj=#wx_ref{type=Type}) ->
?CLASS(Type,wxGridBagSizer),
wxe_util:destroy(?DESTROY_OBJECT,Obj),
ok.
- %% From wxFlexGridSizer
+ %% From wxFlexGridSizer
%% @hidden
setNonFlexibleGrowMode(This,Mode) -> wxFlexGridSizer:setNonFlexibleGrowMode(This,Mode).
%% @hidden
@@ -419,7 +419,7 @@ addGrowableRow(This,Idx) -> wxFlexGridSizer:addGrowableRow(This,Idx).
addGrowableCol(This,Idx, Options) -> wxFlexGridSizer:addGrowableCol(This,Idx, Options).
%% @hidden
addGrowableCol(This,Idx) -> wxFlexGridSizer:addGrowableCol(This,Idx).
- %% From wxGridSizer
+ %% From wxGridSizer
%% @hidden
setVGap(This,Gap) -> wxGridSizer:setVGap(This,Gap).
%% @hidden
@@ -436,7 +436,7 @@ getRows(This) -> wxGridSizer:getRows(This).
getHGap(This) -> wxGridSizer:getHGap(This).
%% @hidden
getCols(This) -> wxGridSizer:getCols(This).
- %% From wxSizer
+ %% From wxSizer
%% @hidden
show(This,Index, Options) -> wxSizer:show(This,Index, Options).
%% @hidden
diff --git a/lib/wx/src/gen/wxGridCellAttr.erl b/lib/wx/src/gen/wxGridCellAttr.erl
index b9fd65304c..3d23c2acfc 100644
--- a/lib/wx/src/gen/wxGridCellAttr.erl
+++ b/lib/wx/src/gen/wxGridCellAttr.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%
%% This file is generated DO NOT EDIT
diff --git a/lib/wx/src/gen/wxGridCellBoolEditor.erl b/lib/wx/src/gen/wxGridCellBoolEditor.erl
index b5afaba68f..a54cfe5eab 100644
--- a/lib/wx/src/gen/wxGridCellBoolEditor.erl
+++ b/lib/wx/src/gen/wxGridCellBoolEditor.erl
@@ -1,24 +1,24 @@
%%
%% %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%
%% This file is generated DO NOT EDIT
%% @doc See external documentation: <a href="http://www.wxwidgets.org/manuals/stable/wx_wxgridcellbooleditor.html">wxGridCellBoolEditor</a>.
-%% <p>This class is derived (and can use functions) from:
+%% <p>This class is derived (and can use functions) from:
%% <br />{@link wxGridCellEditor}
%% </p>
%% @type wxGridCellBoolEditor(). An object reference, The representation is internal
@@ -70,11 +70,11 @@ useStringValues(Options)
%% @spec (This::wxGridCellBoolEditor()) -> ok
%% @doc Destroys this object, do not use object again
-destroy(Obj=#wx_ref{type=Type}) ->
+destroy(Obj=#wx_ref{type=Type}) ->
?CLASS(Type,wxGridCellBoolEditor),
wxe_util:destroy(?wxGridCellBoolEditor_destroy,Obj),
ok.
- %% From wxGridCellEditor
+ %% From wxGridCellEditor
%% @hidden
handleReturn(This,Event) -> wxGridCellEditor:handleReturn(This,Event).
%% @hidden
diff --git a/lib/wx/src/gen/wxGridCellBoolRenderer.erl b/lib/wx/src/gen/wxGridCellBoolRenderer.erl
index 442c00df1c..a98091f62c 100644
--- a/lib/wx/src/gen/wxGridCellBoolRenderer.erl
+++ b/lib/wx/src/gen/wxGridCellBoolRenderer.erl
@@ -1,24 +1,24 @@
%%
%% %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%
%% This file is generated DO NOT EDIT
%% @doc See external documentation: <a href="http://www.wxwidgets.org/manuals/stable/wx_wxgridcellboolrenderer.html">wxGridCellBoolRenderer</a>.
-%% <p>This class is derived (and can use functions) from:
+%% <p>This class is derived (and can use functions) from:
%% <br />{@link wxGridCellRenderer}
%% </p>
%% @type wxGridCellBoolRenderer(). An object reference, The representation is internal
@@ -44,11 +44,11 @@ new() ->
%% @spec (This::wxGridCellBoolRenderer()) -> ok
%% @doc Destroys this object, do not use object again
-destroy(Obj=#wx_ref{type=Type}) ->
+destroy(Obj=#wx_ref{type=Type}) ->
?CLASS(Type,wxGridCellBoolRenderer),
wxe_util:destroy(?wxGridCellBoolRenderer_destroy,Obj),
ok.
- %% From wxGridCellRenderer
+ %% From wxGridCellRenderer
%% @hidden
getBestSize(This,Grid,Attr,Dc,Row,Col) -> wxGridCellRenderer:getBestSize(This,Grid,Attr,Dc,Row,Col).
%% @hidden
diff --git a/lib/wx/src/gen/wxGridCellChoiceEditor.erl b/lib/wx/src/gen/wxGridCellChoiceEditor.erl
index d62933fd07..1adee550f8 100644
--- a/lib/wx/src/gen/wxGridCellChoiceEditor.erl
+++ b/lib/wx/src/gen/wxGridCellChoiceEditor.erl
@@ -1,24 +1,24 @@
%%
%% %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%
%% This file is generated DO NOT EDIT
%% @doc See external documentation: <a href="http://www.wxwidgets.org/manuals/stable/wx_wxgridcellchoiceeditor.html">wxGridCellChoiceEditor</a>.
-%% <p>This class is derived (and can use functions) from:
+%% <p>This class is derived (and can use functions) from:
%% <br />{@link wxGridCellEditor}
%% </p>
%% @type wxGridCellChoiceEditor(). An object reference, The representation is internal
@@ -67,11 +67,11 @@ setParameters(#wx_ref{type=ThisT,ref=ThisRef},Params)
%% @spec (This::wxGridCellChoiceEditor()) -> ok
%% @doc Destroys this object, do not use object again
-destroy(Obj=#wx_ref{type=Type}) ->
+destroy(Obj=#wx_ref{type=Type}) ->
?CLASS(Type,wxGridCellChoiceEditor),
wxe_util:destroy(?wxGridCellChoiceEditor_destroy,Obj),
ok.
- %% From wxGridCellEditor
+ %% From wxGridCellEditor
%% @hidden
handleReturn(This,Event) -> wxGridCellEditor:handleReturn(This,Event).
%% @hidden
diff --git a/lib/wx/src/gen/wxGridCellEditor.erl b/lib/wx/src/gen/wxGridCellEditor.erl
index c08027e040..a27ba7bd0f 100644
--- a/lib/wx/src/gen/wxGridCellEditor.erl
+++ b/lib/wx/src/gen/wxGridCellEditor.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%
%% This file is generated DO NOT EDIT
diff --git a/lib/wx/src/gen/wxGridCellFloatEditor.erl b/lib/wx/src/gen/wxGridCellFloatEditor.erl
index e924c8f9a5..3caad74f0e 100644
--- a/lib/wx/src/gen/wxGridCellFloatEditor.erl
+++ b/lib/wx/src/gen/wxGridCellFloatEditor.erl
@@ -1,24 +1,24 @@
%%
%% %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%
%% This file is generated DO NOT EDIT
%% @doc See external documentation: <a href="http://www.wxwidgets.org/manuals/stable/wx_wxgridcellfloateditor.html">wxGridCellFloatEditor</a>.
-%% <p>This class is derived (and can use functions) from:
+%% <p>This class is derived (and can use functions) from:
%% <br />{@link wxGridCellEditor}
%% </p>
%% @type wxGridCellFloatEditor(). An object reference, The representation is internal
@@ -65,11 +65,11 @@ setParameters(#wx_ref{type=ThisT,ref=ThisRef},Params)
%% @spec (This::wxGridCellFloatEditor()) -> ok
%% @doc Destroys this object, do not use object again
-destroy(Obj=#wx_ref{type=Type}) ->
+destroy(Obj=#wx_ref{type=Type}) ->
?CLASS(Type,wxGridCellFloatEditor),
wxe_util:destroy(?wxGridCellFloatEditor_destroy,Obj),
ok.
- %% From wxGridCellEditor
+ %% From wxGridCellEditor
%% @hidden
handleReturn(This,Event) -> wxGridCellEditor:handleReturn(This,Event).
%% @hidden
diff --git a/lib/wx/src/gen/wxGridCellFloatRenderer.erl b/lib/wx/src/gen/wxGridCellFloatRenderer.erl
index 1d207ae4e0..84ffd21b37 100644
--- a/lib/wx/src/gen/wxGridCellFloatRenderer.erl
+++ b/lib/wx/src/gen/wxGridCellFloatRenderer.erl
@@ -1,24 +1,24 @@
%%
%% %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%
%% This file is generated DO NOT EDIT
%% @doc See external documentation: <a href="http://www.wxwidgets.org/manuals/stable/wx_wxgridcellfloatrenderer.html">wxGridCellFloatRenderer</a>.
-%% <p>This class is derived (and can use functions) from:
+%% <p>This class is derived (and can use functions) from:
%% <br />{@link wxGridCellStringRenderer}
%% <br />{@link wxGridCellRenderer}
%% </p>
@@ -97,12 +97,12 @@ setWidth(#wx_ref{type=ThisT,ref=ThisRef},Width)
%% @spec (This::wxGridCellFloatRenderer()) -> ok
%% @doc Destroys this object, do not use object again
-destroy(Obj=#wx_ref{type=Type}) ->
+destroy(Obj=#wx_ref{type=Type}) ->
?CLASS(Type,wxGridCellFloatRenderer),
wxe_util:destroy(?wxGridCellFloatRenderer_destroy,Obj),
ok.
- %% From wxGridCellStringRenderer
- %% From wxGridCellRenderer
+ %% From wxGridCellStringRenderer
+ %% From wxGridCellRenderer
%% @hidden
getBestSize(This,Grid,Attr,Dc,Row,Col) -> wxGridCellRenderer:getBestSize(This,Grid,Attr,Dc,Row,Col).
%% @hidden
diff --git a/lib/wx/src/gen/wxGridCellNumberEditor.erl b/lib/wx/src/gen/wxGridCellNumberEditor.erl
index 347c03c377..4ebdbb14e9 100644
--- a/lib/wx/src/gen/wxGridCellNumberEditor.erl
+++ b/lib/wx/src/gen/wxGridCellNumberEditor.erl
@@ -1,24 +1,24 @@
%%
%% %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%
%% This file is generated DO NOT EDIT
%% @doc See external documentation: <a href="http://www.wxwidgets.org/manuals/stable/wx_wxgridcellnumbereditor.html">wxGridCellNumberEditor</a>.
-%% <p>This class is derived (and can use functions) from:
+%% <p>This class is derived (and can use functions) from:
%% <br />{@link wxGridCellTextEditor}
%% <br />{@link wxGridCellEditor}
%% </p>
@@ -74,12 +74,12 @@ setParameters(#wx_ref{type=ThisT,ref=ThisRef},Params)
%% @spec (This::wxGridCellNumberEditor()) -> ok
%% @doc Destroys this object, do not use object again
-destroy(Obj=#wx_ref{type=Type}) ->
+destroy(Obj=#wx_ref{type=Type}) ->
?CLASS(Type,wxGridCellNumberEditor),
wxe_util:destroy(?wxGridCellNumberEditor_destroy,Obj),
ok.
- %% From wxGridCellTextEditor
- %% From wxGridCellEditor
+ %% From wxGridCellTextEditor
+ %% From wxGridCellEditor
%% @hidden
handleReturn(This,Event) -> wxGridCellEditor:handleReturn(This,Event).
%% @hidden
diff --git a/lib/wx/src/gen/wxGridCellNumberRenderer.erl b/lib/wx/src/gen/wxGridCellNumberRenderer.erl
index cf90987dc9..651057bb4b 100644
--- a/lib/wx/src/gen/wxGridCellNumberRenderer.erl
+++ b/lib/wx/src/gen/wxGridCellNumberRenderer.erl
@@ -1,24 +1,24 @@
%%
%% %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%
%% This file is generated DO NOT EDIT
%% @doc See external documentation: <a href="http://www.wxwidgets.org/manuals/stable/wx_wxgridcellnumberrenderer.html">wxGridCellNumberRenderer</a>.
-%% <p>This class is derived (and can use functions) from:
+%% <p>This class is derived (and can use functions) from:
%% <br />{@link wxGridCellStringRenderer}
%% <br />{@link wxGridCellRenderer}
%% </p>
@@ -46,12 +46,12 @@ new() ->
%% @spec (This::wxGridCellNumberRenderer()) -> ok
%% @doc Destroys this object, do not use object again
-destroy(Obj=#wx_ref{type=Type}) ->
+destroy(Obj=#wx_ref{type=Type}) ->
?CLASS(Type,wxGridCellNumberRenderer),
wxe_util:destroy(?wxGridCellNumberRenderer_destroy,Obj),
ok.
- %% From wxGridCellStringRenderer
- %% From wxGridCellRenderer
+ %% From wxGridCellStringRenderer
+ %% From wxGridCellRenderer
%% @hidden
getBestSize(This,Grid,Attr,Dc,Row,Col) -> wxGridCellRenderer:getBestSize(This,Grid,Attr,Dc,Row,Col).
%% @hidden
diff --git a/lib/wx/src/gen/wxGridCellRenderer.erl b/lib/wx/src/gen/wxGridCellRenderer.erl
index c7040049a4..d9520c478f 100644
--- a/lib/wx/src/gen/wxGridCellRenderer.erl
+++ b/lib/wx/src/gen/wxGridCellRenderer.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%
%% This file is generated DO NOT EDIT
diff --git a/lib/wx/src/gen/wxGridCellStringRenderer.erl b/lib/wx/src/gen/wxGridCellStringRenderer.erl
index 1c37cf4d6c..28a79e0453 100644
--- a/lib/wx/src/gen/wxGridCellStringRenderer.erl
+++ b/lib/wx/src/gen/wxGridCellStringRenderer.erl
@@ -1,24 +1,24 @@
%%
%% %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%
%% This file is generated DO NOT EDIT
%% @doc See external documentation: <a href="http://www.wxwidgets.org/manuals/stable/wx_wxgridcellstringrenderer.html">wxGridCellStringRenderer</a>.
-%% <p>This class is derived (and can use functions) from:
+%% <p>This class is derived (and can use functions) from:
%% <br />{@link wxGridCellRenderer}
%% </p>
%% @type wxGridCellStringRenderer(). An object reference, The representation is internal
@@ -44,11 +44,11 @@ new() ->
%% @spec (This::wxGridCellStringRenderer()) -> ok
%% @doc Destroys this object, do not use object again
-destroy(Obj=#wx_ref{type=Type}) ->
+destroy(Obj=#wx_ref{type=Type}) ->
?CLASS(Type,wxGridCellStringRenderer),
wxe_util:destroy(?wxGridCellStringRenderer_destroy,Obj),
ok.
- %% From wxGridCellRenderer
+ %% From wxGridCellRenderer
%% @hidden
getBestSize(This,Grid,Attr,Dc,Row,Col) -> wxGridCellRenderer:getBestSize(This,Grid,Attr,Dc,Row,Col).
%% @hidden
diff --git a/lib/wx/src/gen/wxGridCellTextEditor.erl b/lib/wx/src/gen/wxGridCellTextEditor.erl
index f785d736f0..d9ab1dc107 100644
--- a/lib/wx/src/gen/wxGridCellTextEditor.erl
+++ b/lib/wx/src/gen/wxGridCellTextEditor.erl
@@ -1,24 +1,24 @@
%%
%% %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%
%% This file is generated DO NOT EDIT
%% @doc See external documentation: <a href="http://www.wxwidgets.org/manuals/stable/wx_wxgridcelltexteditor.html">wxGridCellTextEditor</a>.
-%% <p>This class is derived (and can use functions) from:
+%% <p>This class is derived (and can use functions) from:
%% <br />{@link wxGridCellEditor}
%% </p>
%% @type wxGridCellTextEditor(). An object reference, The representation is internal
@@ -54,11 +54,11 @@ setParameters(#wx_ref{type=ThisT,ref=ThisRef},Params)
%% @spec (This::wxGridCellTextEditor()) -> ok
%% @doc Destroys this object, do not use object again
-destroy(Obj=#wx_ref{type=Type}) ->
+destroy(Obj=#wx_ref{type=Type}) ->
?CLASS(Type,wxGridCellTextEditor),
wxe_util:destroy(?wxGridCellTextEditor_destroy,Obj),
ok.
- %% From wxGridCellEditor
+ %% From wxGridCellEditor
%% @hidden
handleReturn(This,Event) -> wxGridCellEditor:handleReturn(This,Event).
%% @hidden
diff --git a/lib/wx/src/gen/wxGridEvent.erl b/lib/wx/src/gen/wxGridEvent.erl
index 4d89408c98..9b7e0012ca 100644
--- a/lib/wx/src/gen/wxGridEvent.erl
+++ b/lib/wx/src/gen/wxGridEvent.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%
%% This file is generated DO NOT EDIT
@@ -22,7 +22,7 @@
%% <dd><em>grid_cell_left_click</em>, <em>grid_cell_right_click</em>, <em>grid_cell_left_dclick</em>, <em>grid_cell_right_dclick</em>, <em>grid_label_left_click</em>, <em>grid_label_right_click</em>, <em>grid_label_left_dclick</em>, <em>grid_label_right_dclick</em>, <em>grid_row_size</em>, <em>grid_col_size</em>, <em>grid_range_select</em>, <em>grid_cell_change</em>, <em>grid_select_cell</em>, <em>grid_editor_shown</em>, <em>grid_editor_hidden</em>, <em>grid_editor_created</em>, <em>grid_cell_begin_drag</em></dd></dl>
%% See also the message variant {@link wxEvtHandler:wxGrid(). #wxGrid{}} event record type.
%%
-%% <p>This class is derived (and can use functions) from:
+%% <p>This class is derived (and can use functions) from:
%% <br />{@link wxNotifyEvent}
%% <br />{@link wxCommandEvent}
%% <br />{@link wxEvent}
@@ -104,14 +104,14 @@ shiftDown(#wx_ref{type=ThisT,ref=ThisRef}) ->
wxe_util:call(?wxGridEvent_ShiftDown,
<<ThisRef:32/?UI>>).
- %% From wxNotifyEvent
+ %% From wxNotifyEvent
%% @hidden
veto(This) -> wxNotifyEvent:veto(This).
%% @hidden
isAllowed(This) -> wxNotifyEvent:isAllowed(This).
%% @hidden
allow(This) -> wxNotifyEvent:allow(This).
- %% From wxCommandEvent
+ %% From wxCommandEvent
%% @hidden
setString(This,S) -> wxCommandEvent:setString(This,S).
%% @hidden
@@ -130,7 +130,7 @@ getInt(This) -> wxCommandEvent:getInt(This).
getExtraLong(This) -> wxCommandEvent:getExtraLong(This).
%% @hidden
getClientData(This) -> wxCommandEvent:getClientData(This).
- %% From wxEvent
+ %% From wxEvent
%% @hidden
stopPropagation(This) -> wxEvent:stopPropagation(This).
%% @hidden
diff --git a/lib/wx/src/gen/wxGridSizer.erl b/lib/wx/src/gen/wxGridSizer.erl
index bcc62be429..7b62774347 100644
--- a/lib/wx/src/gen/wxGridSizer.erl
+++ b/lib/wx/src/gen/wxGridSizer.erl
@@ -1,24 +1,24 @@
%%
%% %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%
%% This file is generated DO NOT EDIT
%% @doc See external documentation: <a href="http://www.wxwidgets.org/manuals/stable/wx_wxgridsizer.html">wxGridSizer</a>.
-%% <p>This class is derived (and can use functions) from:
+%% <p>This class is derived (and can use functions) from:
%% <br />{@link wxSizer}
%% </p>
%% @type wxGridSizer(). An object reference, The representation is internal
@@ -132,11 +132,11 @@ setVGap(#wx_ref{type=ThisT,ref=ThisRef},Gap)
%% @spec (This::wxGridSizer()) -> ok
%% @doc Destroys this object, do not use object again
-destroy(Obj=#wx_ref{type=Type}) ->
+destroy(Obj=#wx_ref{type=Type}) ->
?CLASS(Type,wxGridSizer),
wxe_util:destroy(?DESTROY_OBJECT,Obj),
ok.
- %% From wxSizer
+ %% From wxSizer
%% @hidden
show(This,Index, Options) -> wxSizer:show(This,Index, Options).
%% @hidden
diff --git a/lib/wx/src/gen/wxHelpEvent.erl b/lib/wx/src/gen/wxHelpEvent.erl
index 4785ff10de..ef3c666ab7 100644
--- a/lib/wx/src/gen/wxHelpEvent.erl
+++ b/lib/wx/src/gen/wxHelpEvent.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%
%% This file is generated DO NOT EDIT
@@ -22,7 +22,7 @@
%% <dd><em>help</em>, <em>detailed_help</em></dd></dl>
%% See also the message variant {@link wxEvtHandler:wxHelp(). #wxHelp{}} event record type.
%%
-%% <p>This class is derived (and can use functions) from:
+%% <p>This class is derived (and can use functions) from:
%% <br />{@link wxEvent}
%% </p>
%% @type wxHelpEvent(). An object reference, The representation is internal
@@ -75,7 +75,7 @@ setPosition(#wx_ref{type=ThisT,ref=ThisRef},{PosX,PosY})
wxe_util:cast(?wxHelpEvent_SetPosition,
<<ThisRef:32/?UI,PosX:32/?UI,PosY:32/?UI>>).
- %% From wxEvent
+ %% From wxEvent
%% @hidden
stopPropagation(This) -> wxEvent:stopPropagation(This).
%% @hidden
diff --git a/lib/wx/src/gen/wxHtmlEasyPrinting.erl b/lib/wx/src/gen/wxHtmlEasyPrinting.erl
index a782bd71c3..15d673169a 100644
--- a/lib/wx/src/gen/wxHtmlEasyPrinting.erl
+++ b/lib/wx/src/gen/wxHtmlEasyPrinting.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%
%% This file is generated DO NOT EDIT
@@ -190,7 +190,7 @@ setFooter(#wx_ref{type=ThisT,ref=ThisRef},Footer, Options)
%% @spec (This::wxHtmlEasyPrinting()) -> ok
%% @doc Destroys this object, do not use object again
-destroy(Obj=#wx_ref{type=Type}) ->
+destroy(Obj=#wx_ref{type=Type}) ->
?CLASS(Type,wxHtmlEasyPrinting),
wxe_util:destroy(?DESTROY_OBJECT,Obj),
ok.
diff --git a/lib/wx/src/gen/wxHtmlLinkEvent.erl b/lib/wx/src/gen/wxHtmlLinkEvent.erl
index 04eccad939..166493ccbc 100644
--- a/lib/wx/src/gen/wxHtmlLinkEvent.erl
+++ b/lib/wx/src/gen/wxHtmlLinkEvent.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%
%% This file is generated DO NOT EDIT
@@ -22,7 +22,7 @@
%% <dd><em>command_html_link_clicked</em></dd></dl>
%% See also the message variant {@link wxEvtHandler:wxHtmlLink(). #wxHtmlLink{}} event record type.
%%
-%% <p>This class is derived (and can use functions) from:
+%% <p>This class is derived (and can use functions) from:
%% <br />{@link wxCommandEvent}
%% <br />{@link wxEvent}
%% </p>
@@ -52,7 +52,7 @@ getLinkInfo(#wx_ref{type=ThisT,ref=ThisRef}) ->
wxe_util:call(?wxHtmlLinkEvent_GetLinkInfo,
<<ThisRef:32/?UI>>).
- %% From wxCommandEvent
+ %% From wxCommandEvent
%% @hidden
setString(This,S) -> wxCommandEvent:setString(This,S).
%% @hidden
@@ -71,7 +71,7 @@ getInt(This) -> wxCommandEvent:getInt(This).
getExtraLong(This) -> wxCommandEvent:getExtraLong(This).
%% @hidden
getClientData(This) -> wxCommandEvent:getClientData(This).
- %% From wxEvent
+ %% From wxEvent
%% @hidden
stopPropagation(This) -> wxEvent:stopPropagation(This).
%% @hidden
diff --git a/lib/wx/src/gen/wxHtmlWindow.erl b/lib/wx/src/gen/wxHtmlWindow.erl
index 6f43c17890..ba8278ff56 100644
--- a/lib/wx/src/gen/wxHtmlWindow.erl
+++ b/lib/wx/src/gen/wxHtmlWindow.erl
@@ -1,24 +1,24 @@
%%
%% %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%
%% This file is generated DO NOT EDIT
%% @doc See external documentation: <a href="http://www.wxwidgets.org/manuals/stable/wx_wxhtmlwindow.html">wxHtmlWindow</a>.
-%% <p>This class is derived (and can use functions) from:
+%% <p>This class is derived (and can use functions) from:
%% <br />{@link wxScrolledWindow}
%% <br />{@link wxPanel}
%% <br />{@link wxWindow}
@@ -297,11 +297,11 @@ toText(#wx_ref{type=ThisT,ref=ThisRef}) ->
%% @spec (This::wxHtmlWindow()) -> ok
%% @doc Destroys this object, do not use object again
-destroy(Obj=#wx_ref{type=Type}) ->
+destroy(Obj=#wx_ref{type=Type}) ->
?CLASS(Type,wxHtmlWindow),
wxe_util:destroy(?DESTROY_OBJECT,Obj),
ok.
- %% From wxScrolledWindow
+ %% From wxScrolledWindow
%% @hidden
setTargetWindow(This,Target) -> wxScrolledWindow:setTargetWindow(This,Target).
%% @hidden
@@ -330,10 +330,10 @@ calcUnscrolledPosition(This,Pt) -> wxScrolledWindow:calcUnscrolledPosition(This,
calcScrolledPosition(This,X,Y) -> wxScrolledWindow:calcScrolledPosition(This,X,Y).
%% @hidden
calcScrolledPosition(This,Pt) -> wxScrolledWindow:calcScrolledPosition(This,Pt).
- %% From wxPanel
+ %% From wxPanel
%% @hidden
initDialog(This) -> wxPanel:initDialog(This).
- %% From wxWindow
+ %% From wxWindow
%% @hidden
warpPointer(This,X,Y) -> wxWindow:warpPointer(This,X,Y).
%% @hidden
@@ -682,7 +682,7 @@ center(This) -> wxWindow:center(This).
captureMouse(This) -> wxWindow:captureMouse(This).
%% @hidden
cacheBestSize(This,Size) -> wxWindow:cacheBestSize(This,Size).
- %% From wxEvtHandler
+ %% From wxEvtHandler
%% @hidden
disconnect(This,EventType, Options) -> wxEvtHandler:disconnect(This,EventType, Options).
%% @hidden
diff --git a/lib/wx/src/gen/wxIcon.erl b/lib/wx/src/gen/wxIcon.erl
index d95fad1458..5b224c00b6 100644
--- a/lib/wx/src/gen/wxIcon.erl
+++ b/lib/wx/src/gen/wxIcon.erl
@@ -1,24 +1,24 @@
%%
%% %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%
%% This file is generated DO NOT EDIT
%% @doc See external documentation: <a href="http://www.wxwidgets.org/manuals/stable/wx_wxicon.html">wxIcon</a>.
-%% <p>This class is derived (and can use functions) from:
+%% <p>This class is derived (and can use functions) from:
%% <br />{@link wxBitmap}
%% </p>
%% @type wxIcon(). An object reference, The representation is internal
@@ -47,7 +47,7 @@ new() ->
%% @spec (X::string()|term()) -> wxIcon()
%% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxicon.html#wxiconwxicon">external documentation</a>.
-%% <br /> Alternatives:
+%% <br /> Alternatives:
%% <p><c>
%% new(Filename::string()) -> new(Filename, []) </c></p>
%% <p><c>
@@ -88,11 +88,11 @@ copyFromBitmap(#wx_ref{type=ThisT,ref=ThisRef},#wx_ref{type=BmpT,ref=BmpRef}) ->
%% @spec (This::wxIcon()) -> ok
%% @doc Destroys this object, do not use object again
-destroy(Obj=#wx_ref{type=Type}) ->
+destroy(Obj=#wx_ref{type=Type}) ->
?CLASS(Type,wxIcon),
wxe_util:destroy(?DESTROY_OBJECT,Obj),
ok.
- %% From wxBitmap
+ %% From wxBitmap
%% @hidden
setWidth(This,Width) -> wxBitmap:setWidth(This,Width).
%% @hidden
diff --git a/lib/wx/src/gen/wxIconBundle.erl b/lib/wx/src/gen/wxIconBundle.erl
index be600c69da..ee133cbcb9 100644
--- a/lib/wx/src/gen/wxIconBundle.erl
+++ b/lib/wx/src/gen/wxIconBundle.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%
%% This file is generated DO NOT EDIT
@@ -83,7 +83,7 @@ getIcon(This)
%% @spec (This::wxIconBundle(),X::term()) -> wxIcon:wxIcon()
%% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxiconbundle.html#wxiconbundlegeticon">external documentation</a>.
-%% <br /> Alternatives:
+%% <br /> Alternatives:
%% <p><c>
%% getIcon(This::wxIconBundle(), [Option]) -> wxIcon:wxIcon() </c>
%%<br /> Option = {size, integer()}
@@ -107,7 +107,7 @@ getIcon(#wx_ref{type=ThisT,ref=ThisRef},{SizeW,SizeH})
%% @spec (This::wxIconBundle()) -> ok
%% @doc Destroys this object, do not use object again
-destroy(Obj=#wx_ref{type=Type}) ->
+destroy(Obj=#wx_ref{type=Type}) ->
?CLASS(Type,wxIconBundle),
wxe_util:destroy(?wxIconBundle_destruct,Obj),
ok.
diff --git a/lib/wx/src/gen/wxIconizeEvent.erl b/lib/wx/src/gen/wxIconizeEvent.erl
index 09f8843b74..647d8019a1 100644
--- a/lib/wx/src/gen/wxIconizeEvent.erl
+++ b/lib/wx/src/gen/wxIconizeEvent.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%
%% This file is generated DO NOT EDIT
@@ -22,7 +22,7 @@
%% <dd><em>iconize</em></dd></dl>
%% See also the message variant {@link wxEvtHandler:wxIconize(). #wxIconize{}} event record type.
%%
-%% <p>This class is derived (and can use functions) from:
+%% <p>This class is derived (and can use functions) from:
%% <br />{@link wxEvent}
%% </p>
%% @type wxIconizeEvent(). An object reference, The representation is internal
@@ -48,7 +48,7 @@ iconized(#wx_ref{type=ThisT,ref=ThisRef}) ->
wxe_util:call(?wxIconizeEvent_Iconized,
<<ThisRef:32/?UI>>).
- %% From wxEvent
+ %% From wxEvent
%% @hidden
stopPropagation(This) -> wxEvent:stopPropagation(This).
%% @hidden
diff --git a/lib/wx/src/gen/wxIdleEvent.erl b/lib/wx/src/gen/wxIdleEvent.erl
index e205eff522..87ed7e0cd2 100644
--- a/lib/wx/src/gen/wxIdleEvent.erl
+++ b/lib/wx/src/gen/wxIdleEvent.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%
%% This file is generated DO NOT EDIT
@@ -22,7 +22,7 @@
%% <dd><em>idle</em></dd></dl>
%% See also the message variant {@link wxEvtHandler:wxIdle(). #wxIdle{}} event record type.
%%
-%% <p>This class is derived (and can use functions) from:
+%% <p>This class is derived (and can use functions) from:
%% <br />{@link wxEvent}
%% </p>
%% @type wxIdleEvent(). An object reference, The representation is internal
@@ -90,7 +90,7 @@ setMode(Mode)
wxe_util:cast(?wxIdleEvent_SetMode,
<<Mode:32/?UI>>).
- %% From wxEvent
+ %% From wxEvent
%% @hidden
stopPropagation(This) -> wxEvent:stopPropagation(This).
%% @hidden
diff --git a/lib/wx/src/gen/wxImage.erl b/lib/wx/src/gen/wxImage.erl
index f90ae09707..5fe105fbb2 100644
--- a/lib/wx/src/gen/wxImage.erl
+++ b/lib/wx/src/gen/wxImage.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%
%% This file is generated DO NOT EDIT
@@ -64,7 +64,7 @@ new(Name)
%% @spec (X::integer()|string(),X::integer()|term()) -> wxImage()
%% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wximage.html#wximagewximage">external documentation</a>.
-%% <br /> Alternatives:
+%% <br /> Alternatives:
%% <p><c>
%% new(Width::integer(), Height::integer()) -> new(Width,Height, []) </c></p>
%% <p><c>
@@ -87,7 +87,7 @@ new(Name, Options)
%% @spec (X::integer()|string(),X::integer()|string(),X::binary()|term()) -> wxImage()
%% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wximage.html#wximagewximage">external documentation</a>.
-%% <br /> Alternatives:
+%% <br /> Alternatives:
%% <p><c>
%% new(Width::integer(), Height::integer(), Data::binary()) -> new(Width,Height,Data, []) </c></p>
%% <p><c>
@@ -121,7 +121,7 @@ new(Name,Mimetype, Options)
%% @spec (Width::integer(),Height::integer(),Data::binary(),X::binary()|term()) -> wxImage()
%% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wximage.html#wximagewximage">external documentation</a>.
-%% <br /> Alternatives:
+%% <br /> Alternatives:
%% <p><c>
%% new(Width::integer(), Height::integer(), Data::binary(), Alpha::binary()) -> new(Width,Height,Data,Alpha, []) </c></p>
%% <p><c>
@@ -239,7 +239,7 @@ create(This,Width,Height)
%% @spec (This::wxImage(),Width::integer(),Height::integer(),X::binary()|term()) -> bool()
%% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wximage.html#wximagecreate">external documentation</a>.
-%% <br /> Alternatives:
+%% <br /> Alternatives:
%% <p><c>
%% create(This::wxImage(), Width::integer(), Height::integer(), Data::binary()) -> create(This,Width,Height,Data, []) </c></p>
%% <p><c>
@@ -261,7 +261,7 @@ create(#wx_ref{type=ThisT,ref=ThisRef},Width,Height, Options)
%% @spec (This::wxImage(),Width::integer(),Height::integer(),Data::binary(),X::binary()|term()) -> bool()
%% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wximage.html#wximagecreate">external documentation</a>.
-%% <br /> Alternatives:
+%% <br /> Alternatives:
%% <p><c>
%% create(This::wxImage(), Width::integer(), Height::integer(), Data::binary(), Alpha::binary()) -> create(This,Width,Height,Data,Alpha, []) </c></p>
%% <p><c>
@@ -691,7 +691,7 @@ saveFile(#wx_ref{type=ThisT,ref=ThisRef},Name)
%% @spec (This::wxImage(),Name::string(),X::integer()|string()) -> bool()
%% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wximage.html#wximagesavefile">external documentation</a>.
-%% <br /> Alternatives:
+%% <br /> Alternatives:
%% <p><c>
%% saveFile(This::wxImage(), Name::string(), Type::integer()) -> bool() </c>
%% </p>
@@ -852,7 +852,7 @@ setMaskFromImage(#wx_ref{type=ThisT,ref=ThisRef},#wx_ref{type=MaskT,ref=MaskRef}
%% @spec (This::wxImage(),Name::string(),X::integer()|string()) -> ok
%% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wximage.html#wximagesetoption">external documentation</a>.
-%% <br /> Alternatives:
+%% <br /> Alternatives:
%% <p><c>
%% setOption(This::wxImage(), Name::string(), Value::integer()) -> ok </c>
%% </p>
@@ -899,7 +899,7 @@ setRGB(#wx_ref{type=ThisT,ref=ThisRef},X,Y,R,G,B)
%% @spec (This::wxImage()) -> ok
%% @doc Destroys this object, do not use object again
-destroy(Obj=#wx_ref{type=Type}) ->
+destroy(Obj=#wx_ref{type=Type}) ->
?CLASS(Type,wxImage),
wxe_util:destroy(?DESTROY_OBJECT,Obj),
ok.
diff --git a/lib/wx/src/gen/wxImageList.erl b/lib/wx/src/gen/wxImageList.erl
index b20dfda315..dbd51bc47b 100644
--- a/lib/wx/src/gen/wxImageList.erl
+++ b/lib/wx/src/gen/wxImageList.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%
%% This file is generated DO NOT EDIT
@@ -68,7 +68,7 @@ add(#wx_ref{type=ThisT,ref=ThisRef},#wx_ref{type=BitmapT,ref=BitmapRef}) ->
%% @spec (This::wxImageList(),Bitmap::wxBitmap:wxBitmap(),X::term()) -> integer()
%% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wximagelist.html#wximagelistadd">external documentation</a>.
-%% <br /> Alternatives:
+%% <br /> Alternatives:
%% <p><c>
%% add(This::wxImageList(), Bitmap::wxBitmap:wxBitmap(), Mask::wxBitmap:wxBitmap()) -> integer() </c>
%% </p>
@@ -194,7 +194,7 @@ replace(#wx_ref{type=ThisT,ref=ThisRef},Index,#wx_ref{type=BitmapT,ref=BitmapRef
%% @spec (This::wxImageList()) -> ok
%% @doc Destroys this object, do not use object again
-destroy(Obj=#wx_ref{type=Type}) ->
+destroy(Obj=#wx_ref{type=Type}) ->
?CLASS(Type,wxImageList),
wxe_util:destroy(?DESTROY_OBJECT,Obj),
ok.
diff --git a/lib/wx/src/gen/wxJoystickEvent.erl b/lib/wx/src/gen/wxJoystickEvent.erl
index b07cbd6d9a..2c2d7f3968 100644
--- a/lib/wx/src/gen/wxJoystickEvent.erl
+++ b/lib/wx/src/gen/wxJoystickEvent.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%
%% This file is generated DO NOT EDIT
@@ -22,7 +22,7 @@
%% <dd><em>joy_button_down</em>, <em>joy_button_up</em>, <em>joy_move</em>, <em>joy_zmove</em></dd></dl>
%% See also the message variant {@link wxEvtHandler:wxJoystick(). #wxJoystick{}} event record type.
%%
-%% <p>This class is derived (and can use functions) from:
+%% <p>This class is derived (and can use functions) from:
%% <br />{@link wxEvent}
%% </p>
%% @type wxJoystickEvent(). An object reference, The representation is internal
@@ -153,7 +153,7 @@ isZMove(#wx_ref{type=ThisT,ref=ThisRef}) ->
wxe_util:call(?wxJoystickEvent_IsZMove,
<<ThisRef:32/?UI>>).
- %% From wxEvent
+ %% From wxEvent
%% @hidden
stopPropagation(This) -> wxEvent:stopPropagation(This).
%% @hidden
diff --git a/lib/wx/src/gen/wxKeyEvent.erl b/lib/wx/src/gen/wxKeyEvent.erl
index 0e92402435..00d1e2033a 100644
--- a/lib/wx/src/gen/wxKeyEvent.erl
+++ b/lib/wx/src/gen/wxKeyEvent.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%
%% This file is generated DO NOT EDIT
@@ -22,7 +22,7 @@
%% <dd><em>char</em>, <em>char_hook</em>, <em>key_down</em>, <em>key_up</em></dd></dl>
%% See also the message variant {@link wxEvtHandler:wxKey(). #wxKey{}} event record type.
%%
-%% <p>This class is derived (and can use functions) from:
+%% <p>This class is derived (and can use functions) from:
%% <br />{@link wxEvent}
%% </p>
%% @type wxKeyEvent(). An object reference, The representation is internal
@@ -141,7 +141,7 @@ shiftDown(#wx_ref{type=ThisT,ref=ThisRef}) ->
wxe_util:call(?wxKeyEvent_ShiftDown,
<<ThisRef:32/?UI>>).
- %% From wxEvent
+ %% From wxEvent
%% @hidden
stopPropagation(This) -> wxEvent:stopPropagation(This).
%% @hidden
diff --git a/lib/wx/src/gen/wxLayoutAlgorithm.erl b/lib/wx/src/gen/wxLayoutAlgorithm.erl
index 8ea920d80b..402d116338 100644
--- a/lib/wx/src/gen/wxLayoutAlgorithm.erl
+++ b/lib/wx/src/gen/wxLayoutAlgorithm.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%
%% This file is generated DO NOT EDIT
@@ -98,7 +98,7 @@ layoutWindow(#wx_ref{type=ThisT,ref=ThisRef},#wx_ref{type=FrameT,ref=FrameRef},
%% @spec (This::wxLayoutAlgorithm()) -> ok
%% @doc Destroys this object, do not use object again
-destroy(Obj=#wx_ref{type=Type}) ->
+destroy(Obj=#wx_ref{type=Type}) ->
?CLASS(Type,wxLayoutAlgorithm),
wxe_util:destroy(?DESTROY_OBJECT,Obj),
ok.
diff --git a/lib/wx/src/gen/wxListBox.erl b/lib/wx/src/gen/wxListBox.erl
index 5fd9f329d0..731209c586 100644
--- a/lib/wx/src/gen/wxListBox.erl
+++ b/lib/wx/src/gen/wxListBox.erl
@@ -1,24 +1,24 @@
%%
%% %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%
%% This file is generated DO NOT EDIT
%% @doc See external documentation: <a href="http://www.wxwidgets.org/manuals/stable/wx_wxlistbox.html">wxListBox</a>.
-%% <p>This class is derived (and can use functions) from:
+%% <p>This class is derived (and can use functions) from:
%% <br />{@link wxControlWithItems}
%% <br />{@link wxControl}
%% <br />{@link wxWindow}
@@ -184,7 +184,7 @@ hitTest(#wx_ref{type=ThisT,ref=ThisRef},{PointX,PointY})
%% @spec (This::wxListBox(),X::integer()|string()) -> ok
%% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxlistbox.html#wxlistboxsetfirstitem">external documentation</a>.
-%% <br /> Alternatives:
+%% <br /> Alternatives:
%% <p><c>
%% setFirstItem(This::wxListBox(), N::integer()) -> ok </c>
%% </p>
@@ -205,11 +205,11 @@ setFirstItem(#wx_ref{type=ThisT,ref=ThisRef},S)
%% @spec (This::wxListBox()) -> ok
%% @doc Destroys this object, do not use object again
-destroy(Obj=#wx_ref{type=Type}) ->
+destroy(Obj=#wx_ref{type=Type}) ->
?CLASS(Type,wxListBox),
wxe_util:destroy(?DESTROY_OBJECT,Obj),
ok.
- %% From wxControlWithItems
+ %% From wxControlWithItems
%% @hidden
setStringSelection(This,S) -> wxControlWithItems:setStringSelection(This,S).
%% @hidden
@@ -250,12 +250,12 @@ appendStrings(This,Strings) -> wxControlWithItems:appendStrings(This,Strings).
append(This,Item,ClientData) -> wxControlWithItems:append(This,Item,ClientData).
%% @hidden
append(This,Item) -> wxControlWithItems:append(This,Item).
- %% From wxControl
+ %% From wxControl
%% @hidden
setLabel(This,Label) -> wxControl:setLabel(This,Label).
%% @hidden
getLabel(This) -> wxControl:getLabel(This).
- %% From wxWindow
+ %% From wxWindow
%% @hidden
warpPointer(This,X,Y) -> wxWindow:warpPointer(This,X,Y).
%% @hidden
@@ -602,7 +602,7 @@ center(This) -> wxWindow:center(This).
captureMouse(This) -> wxWindow:captureMouse(This).
%% @hidden
cacheBestSize(This,Size) -> wxWindow:cacheBestSize(This,Size).
- %% From wxEvtHandler
+ %% From wxEvtHandler
%% @hidden
disconnect(This,EventType, Options) -> wxEvtHandler:disconnect(This,EventType, Options).
%% @hidden
diff --git a/lib/wx/src/gen/wxListCtrl.erl b/lib/wx/src/gen/wxListCtrl.erl
index 980415f577..9c4ba1e5a3 100644
--- a/lib/wx/src/gen/wxListCtrl.erl
+++ b/lib/wx/src/gen/wxListCtrl.erl
@@ -1,24 +1,24 @@
%%
%% %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%
%% This file is generated DO NOT EDIT
%% @doc See external documentation: <a href="http://www.wxwidgets.org/manuals/stable/wx_wxlistctrl.html">wxListCtrl</a>.
-%% <p>This class is derived (and can use functions) from:
+%% <p>This class is derived (and can use functions) from:
%% <br />{@link wxControl}
%% <br />{@link wxWindow}
%% <br />{@link wxEvtHandler}
@@ -32,16 +32,17 @@
-export([ sortItems/2 ,arrange/1,arrange/2,assignImageList/3,clearAll/1,create/2,
create/3,deleteAllItems/1,deleteColumn/2,deleteItem/2,destroy/1,editLabel/2,
ensureVisible/2,findItem/3,findItem/4,getColumn/3,getColumnCount/1,
- getColumnWidth/2,getCountPerPage/1,getImageList/2,getItem/2,getItemBackgroundColour/2,
- getItemCount/1,getItemData/2,getItemFont/2,getItemPosition/3,getItemRect/3,
- getItemRect/4,getItemSpacing/1,getItemState/3,getItemText/2,getItemTextColour/2,
- getNextItem/2,getNextItem/3,getSelectedItemCount/1,getTextColour/1,
- getTopItem/1,getViewRect/1,hitTest/2,insertColumn/3,insertColumn/4,
- insertItem/2,insertItem/3,insertItem/4,new/0,new/1,new/2,refreshItem/2,
- refreshItems/3,scrollList/3,setBackgroundColour/2,setColumn/3,setColumnWidth/3,
- setImageList/3,setItem/2,setItem/4,setItem/5,setItemBackgroundColour/3,
- setItemColumnImage/4,setItemCount/2,setItemData/3,setItemFont/3,setItemImage/3,
- setItemImage/4,setItemPosition/3,setItemState/4,setItemText/3,setItemTextColour/3,
+ getColumnWidth/2,getCountPerPage/1,getEditControl/1,getImageList/2,
+ getItem/2,getItemBackgroundColour/2,getItemCount/1,getItemData/2,
+ getItemFont/2,getItemPosition/3,getItemRect/3,getItemRect/4,getItemSpacing/1,
+ getItemState/3,getItemText/2,getItemTextColour/2,getNextItem/2,getNextItem/3,
+ getSelectedItemCount/1,getTextColour/1,getTopItem/1,getViewRect/1,
+ hitTest/2,insertColumn/3,insertColumn/4,insertItem/2,insertItem/3,
+ insertItem/4,new/0,new/1,new/2,refreshItem/2,refreshItems/3,scrollList/3,
+ setBackgroundColour/2,setColumn/3,setColumnWidth/3,setImageList/3,
+ setItem/2,setItem/4,setItem/5,setItemBackgroundColour/3,setItemColumnImage/4,
+ setItemCount/2,setItemData/3,setItemFont/3,setItemImage/3,setItemImage/4,
+ setItemPosition/3,setItemState/4,setItemText/3,setItemTextColour/3,
setSingleStyle/2,setSingleStyle/3,setTextColour/2,setWindowStyleFlag/2]).
%% inherited exports
@@ -220,7 +221,7 @@ findItem(This,Start,Str)
%% @spec (This::wxListCtrl(),Start::integer(),X::string()|term(),X::term()|integer()) -> integer()
%% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxlistctrl.html#wxlistctrlfinditem">external documentation</a>.
-%% <br /> Alternatives:
+%% <br /> Alternatives:
%% <p><c>
%% findItem(This::wxListCtrl(), Start::integer(), Str::string(), [Option]) -> integer() </c>
%%<br /> Option = {partial, bool()}
@@ -274,6 +275,13 @@ getCountPerPage(#wx_ref{type=ThisT,ref=ThisRef}) ->
wxe_util:call(?wxListCtrl_GetCountPerPage,
<<ThisRef:32/?UI>>).
+%% @spec (This::wxListCtrl()) -> wxTextCtrl:wxTextCtrl()
+%% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxlistctrl.html#wxlistctrlgeteditcontrol">external documentation</a>.
+getEditControl(#wx_ref{type=ThisT,ref=ThisRef}) ->
+ ?CLASS(ThisT,wxListCtrl),
+ wxe_util:call(?wxListCtrl_GetEditControl,
+ <<ThisRef:32/?UI>>).
+
%% @spec (This::wxListCtrl(), Which::integer()) -> wxImageList:wxImageList()
%% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxlistctrl.html#wxlistctrlgetimagelist">external documentation</a>.
getImageList(#wx_ref{type=ThisT,ref=ThisRef},Which)
@@ -435,7 +443,7 @@ hitTest(#wx_ref{type=ThisT,ref=ThisRef},{PointX,PointY})
%% @spec (This::wxListCtrl(),Col::integer(),X::string()|term()) -> integer()
%% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxlistctrl.html#wxlistctrlinsertcolumn">external documentation</a>.
-%% <br /> Alternatives:
+%% <br /> Alternatives:
%% <p><c>
%% insertColumn(This::wxListCtrl(), Col::integer(), Heading::string()) -> insertColumn(This,Col,Heading, []) </c></p>
%% <p><c>
@@ -476,7 +484,7 @@ insertItem(#wx_ref{type=ThisT,ref=ThisRef},#wx_ref{type=InfoT,ref=InfoRef}) ->
%% @spec (This::wxListCtrl(),Index::integer(),X::integer()|string()) -> integer()
%% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxlistctrl.html#wxlistctrlinsertitem">external documentation</a>.
-%% <br /> Alternatives:
+%% <br /> Alternatives:
%% <p><c>
%% insertItem(This::wxListCtrl(), Index::integer(), ImageIndex::integer()) -> integer() </c>
%% </p>
@@ -735,16 +743,16 @@ sortItems(#wx_ref{type=ThisT,ref=ThisRef}, SortCallBack)
wxe_util:call(?wxListCtrl_SortItems, <<ThisRef:32/?UI,SortId:32/?UI>>).
%% @spec (This::wxListCtrl()) -> ok
%% @doc Destroys this object, do not use object again
-destroy(Obj=#wx_ref{type=Type}) ->
+destroy(Obj=#wx_ref{type=Type}) ->
?CLASS(Type,wxListCtrl),
wxe_util:destroy(?DESTROY_OBJECT,Obj),
ok.
- %% From wxControl
+ %% From wxControl
%% @hidden
setLabel(This,Label) -> wxControl:setLabel(This,Label).
%% @hidden
getLabel(This) -> wxControl:getLabel(This).
- %% From wxWindow
+ %% From wxWindow
%% @hidden
warpPointer(This,X,Y) -> wxWindow:warpPointer(This,X,Y).
%% @hidden
@@ -1087,7 +1095,7 @@ center(This) -> wxWindow:center(This).
captureMouse(This) -> wxWindow:captureMouse(This).
%% @hidden
cacheBestSize(This,Size) -> wxWindow:cacheBestSize(This,Size).
- %% From wxEvtHandler
+ %% From wxEvtHandler
%% @hidden
disconnect(This,EventType, Options) -> wxEvtHandler:disconnect(This,EventType, Options).
%% @hidden
diff --git a/lib/wx/src/gen/wxListEvent.erl b/lib/wx/src/gen/wxListEvent.erl
index fd1cc381ed..74f9e6095c 100644
--- a/lib/wx/src/gen/wxListEvent.erl
+++ b/lib/wx/src/gen/wxListEvent.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%
%% This file is generated DO NOT EDIT
@@ -22,7 +22,7 @@
%% <dd><em>command_list_begin_drag</em>, <em>command_list_begin_rdrag</em>, <em>command_list_begin_label_edit</em>, <em>command_list_end_label_edit</em>, <em>command_list_delete_item</em>, <em>command_list_delete_all_items</em>, <em>command_list_key_down</em>, <em>command_list_insert_item</em>, <em>command_list_col_click</em>, <em>command_list_col_right_click</em>, <em>command_list_col_begin_drag</em>, <em>command_list_col_dragging</em>, <em>command_list_col_end_drag</em>, <em>command_list_item_selected</em>, <em>command_list_item_deselected</em>, <em>command_list_item_right_click</em>, <em>command_list_item_middle_click</em>, <em>command_list_item_activated</em>, <em>command_list_item_focused</em>, <em>command_list_cache_hint</em></dd></dl>
%% See also the message variant {@link wxEvtHandler:wxList(). #wxList{}} event record type.
%%
-%% <p>This class is derived (and can use functions) from:
+%% <p>This class is derived (and can use functions) from:
%% <br />{@link wxNotifyEvent}
%% <br />{@link wxCommandEvent}
%% <br />{@link wxEvent}
@@ -139,14 +139,14 @@ isEditCancelled(#wx_ref{type=ThisT,ref=ThisRef}) ->
wxe_util:call(?wxListEvent_IsEditCancelled,
<<ThisRef:32/?UI>>).
- %% From wxNotifyEvent
+ %% From wxNotifyEvent
%% @hidden
veto(This) -> wxNotifyEvent:veto(This).
%% @hidden
isAllowed(This) -> wxNotifyEvent:isAllowed(This).
%% @hidden
allow(This) -> wxNotifyEvent:allow(This).
- %% From wxCommandEvent
+ %% From wxCommandEvent
%% @hidden
setString(This,S) -> wxCommandEvent:setString(This,S).
%% @hidden
@@ -165,7 +165,7 @@ getInt(This) -> wxCommandEvent:getInt(This).
getExtraLong(This) -> wxCommandEvent:getExtraLong(This).
%% @hidden
getClientData(This) -> wxCommandEvent:getClientData(This).
- %% From wxEvent
+ %% From wxEvent
%% @hidden
stopPropagation(This) -> wxEvent:stopPropagation(This).
%% @hidden
diff --git a/lib/wx/src/gen/wxListItem.erl b/lib/wx/src/gen/wxListItem.erl
index 31d44b9601..326f674b28 100644
--- a/lib/wx/src/gen/wxListItem.erl
+++ b/lib/wx/src/gen/wxListItem.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%
%% This file is generated DO NOT EDIT
@@ -236,7 +236,7 @@ setWidth(#wx_ref{type=ThisT,ref=ThisRef},Width)
%% @spec (This::wxListItem()) -> ok
%% @doc Destroys this object, do not use object again
-destroy(Obj=#wx_ref{type=Type}) ->
+destroy(Obj=#wx_ref{type=Type}) ->
?CLASS(Type,wxListItem),
wxe_util:destroy(?DESTROY_OBJECT,Obj),
ok.
diff --git a/lib/wx/src/gen/wxListView.erl b/lib/wx/src/gen/wxListView.erl
index a39a594a6a..95a233a562 100644
--- a/lib/wx/src/gen/wxListView.erl
+++ b/lib/wx/src/gen/wxListView.erl
@@ -1,24 +1,24 @@
%%
%% %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%
%% This file is generated DO NOT EDIT
%% @doc See external documentation: <a href="http://www.wxwidgets.org/manuals/stable/wx_wxlistview.html">wxListView</a>.
-%% <p>This class is derived (and can use functions) from:
+%% <p>This class is derived (and can use functions) from:
%% <br />{@link wxControl}
%% <br />{@link wxWindow}
%% <br />{@link wxEvtHandler}
@@ -148,12 +148,12 @@ setColumnImage(#wx_ref{type=ThisT,ref=ThisRef},Col,Image)
wxe_util:cast(?wxListView_SetColumnImage,
<<ThisRef:32/?UI,Col:32/?UI,Image:32/?UI>>).
- %% From wxControl
+ %% From wxControl
%% @hidden
setLabel(This,Label) -> wxControl:setLabel(This,Label).
%% @hidden
getLabel(This) -> wxControl:getLabel(This).
- %% From wxWindow
+ %% From wxWindow
%% @hidden
warpPointer(This,X,Y) -> wxWindow:warpPointer(This,X,Y).
%% @hidden
@@ -500,7 +500,7 @@ center(This) -> wxWindow:center(This).
captureMouse(This) -> wxWindow:captureMouse(This).
%% @hidden
cacheBestSize(This,Size) -> wxWindow:cacheBestSize(This,Size).
- %% From wxEvtHandler
+ %% From wxEvtHandler
%% @hidden
disconnect(This,EventType, Options) -> wxEvtHandler:disconnect(This,EventType, Options).
%% @hidden
diff --git a/lib/wx/src/gen/wxListbook.erl b/lib/wx/src/gen/wxListbook.erl
index 385c50c316..b1f0e3d9a4 100644
--- a/lib/wx/src/gen/wxListbook.erl
+++ b/lib/wx/src/gen/wxListbook.erl
@@ -1,24 +1,24 @@
%%
%% %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%
%% This file is generated DO NOT EDIT
%% @doc See external documentation: <a href="http://www.wxwidgets.org/manuals/stable/wx_wxlistbook.html">wxListbook</a>.
-%% <p>This class is derived (and can use functions) from:
+%% <p>This class is derived (and can use functions) from:
%% <br />{@link wxControl}
%% <br />{@link wxWindow}
%% <br />{@link wxEvtHandler}
@@ -329,16 +329,16 @@ changeSelection(#wx_ref{type=ThisT,ref=ThisRef},N)
%% @spec (This::wxListbook()) -> ok
%% @doc Destroys this object, do not use object again
-destroy(Obj=#wx_ref{type=Type}) ->
+destroy(Obj=#wx_ref{type=Type}) ->
?CLASS(Type,wxListbook),
wxe_util:destroy(?DESTROY_OBJECT,Obj),
ok.
- %% From wxControl
+ %% From wxControl
%% @hidden
setLabel(This,Label) -> wxControl:setLabel(This,Label).
%% @hidden
getLabel(This) -> wxControl:getLabel(This).
- %% From wxWindow
+ %% From wxWindow
%% @hidden
warpPointer(This,X,Y) -> wxWindow:warpPointer(This,X,Y).
%% @hidden
@@ -685,7 +685,7 @@ center(This) -> wxWindow:center(This).
captureMouse(This) -> wxWindow:captureMouse(This).
%% @hidden
cacheBestSize(This,Size) -> wxWindow:cacheBestSize(This,Size).
- %% From wxEvtHandler
+ %% From wxEvtHandler
%% @hidden
disconnect(This,EventType, Options) -> wxEvtHandler:disconnect(This,EventType, Options).
%% @hidden
diff --git a/lib/wx/src/gen/wxLogNull.erl b/lib/wx/src/gen/wxLogNull.erl
index f33070b197..676fdf6d85 100644
--- a/lib/wx/src/gen/wxLogNull.erl
+++ b/lib/wx/src/gen/wxLogNull.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%
%% This file is generated DO NOT EDIT
@@ -40,7 +40,7 @@ new() ->
%% @spec (This::wxLogNull()) -> ok
%% @doc Destroys this object, do not use object again
-destroy(Obj=#wx_ref{type=Type}) ->
+destroy(Obj=#wx_ref{type=Type}) ->
?CLASS(Type,wxLogNull),
wxe_util:destroy(?wxLogNull_destroy,Obj),
ok.
diff --git a/lib/wx/src/gen/wxMDIChildFrame.erl b/lib/wx/src/gen/wxMDIChildFrame.erl
index 3403ab6c9c..34edac4213 100644
--- a/lib/wx/src/gen/wxMDIChildFrame.erl
+++ b/lib/wx/src/gen/wxMDIChildFrame.erl
@@ -1,24 +1,24 @@
%%
%% %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%
%% This file is generated DO NOT EDIT
%% @doc See external documentation: <a href="http://www.wxwidgets.org/manuals/stable/wx_wxmdichildframe.html">wxMDIChildFrame</a>.
-%% <p>This class is derived (and can use functions) from:
+%% <p>This class is derived (and can use functions) from:
%% <br />{@link wxFrame}
%% <br />{@link wxTopLevelWindow}
%% <br />{@link wxWindow}
@@ -170,11 +170,11 @@ restore(#wx_ref{type=ThisT,ref=ThisRef}) ->
%% @spec (This::wxMDIChildFrame()) -> ok
%% @doc Destroys this object, do not use object again
-destroy(Obj=#wx_ref{type=Type}) ->
+destroy(Obj=#wx_ref{type=Type}) ->
?CLASS(Type,wxMDIChildFrame),
wxe_util:destroy(?DESTROY_OBJECT,Obj),
ok.
- %% From wxFrame
+ %% From wxFrame
%% @hidden
setToolBar(This,Toolbar) -> wxFrame:setToolBar(This,Toolbar).
%% @hidden
@@ -211,7 +211,7 @@ createToolBar(This) -> wxFrame:createToolBar(This).
createStatusBar(This, Options) -> wxFrame:createStatusBar(This, Options).
%% @hidden
createStatusBar(This) -> wxFrame:createStatusBar(This).
- %% From wxTopLevelWindow
+ %% From wxTopLevelWindow
%% @hidden
showFullScreen(This,Show, Options) -> wxTopLevelWindow:showFullScreen(This,Show, Options).
%% @hidden
@@ -254,7 +254,7 @@ getTitle(This) -> wxTopLevelWindow:getTitle(This).
getIcons(This) -> wxTopLevelWindow:getIcons(This).
%% @hidden
getIcon(This) -> wxTopLevelWindow:getIcon(This).
- %% From wxWindow
+ %% From wxWindow
%% @hidden
warpPointer(This,X,Y) -> wxWindow:warpPointer(This,X,Y).
%% @hidden
@@ -605,7 +605,7 @@ center(This) -> wxWindow:center(This).
captureMouse(This) -> wxWindow:captureMouse(This).
%% @hidden
cacheBestSize(This,Size) -> wxWindow:cacheBestSize(This,Size).
- %% From wxEvtHandler
+ %% From wxEvtHandler
%% @hidden
disconnect(This,EventType, Options) -> wxEvtHandler:disconnect(This,EventType, Options).
%% @hidden
diff --git a/lib/wx/src/gen/wxMDIClientWindow.erl b/lib/wx/src/gen/wxMDIClientWindow.erl
index 6a6fbab4a7..79a11b4eb7 100644
--- a/lib/wx/src/gen/wxMDIClientWindow.erl
+++ b/lib/wx/src/gen/wxMDIClientWindow.erl
@@ -1,24 +1,24 @@
%%
%% %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%
%% This file is generated DO NOT EDIT
%% @doc See external documentation: <a href="http://www.wxwidgets.org/manuals/stable/wx_wxmdiclientwindow.html">wxMDIClientWindow</a>.
-%% <p>This class is derived (and can use functions) from:
+%% <p>This class is derived (and can use functions) from:
%% <br />{@link wxWindow}
%% <br />{@link wxEvtHandler}
%% </p>
@@ -118,11 +118,11 @@ createClient(#wx_ref{type=ThisT,ref=ThisRef},#wx_ref{type=ParentT,ref=ParentRef}
%% @spec (This::wxMDIClientWindow()) -> ok
%% @doc Destroys this object, do not use object again
-destroy(Obj=#wx_ref{type=Type}) ->
+destroy(Obj=#wx_ref{type=Type}) ->
?CLASS(Type,wxMDIClientWindow),
wxe_util:destroy(?DESTROY_OBJECT,Obj),
ok.
- %% From wxWindow
+ %% From wxWindow
%% @hidden
warpPointer(This,X,Y) -> wxWindow:warpPointer(This,X,Y).
%% @hidden
@@ -473,7 +473,7 @@ center(This) -> wxWindow:center(This).
captureMouse(This) -> wxWindow:captureMouse(This).
%% @hidden
cacheBestSize(This,Size) -> wxWindow:cacheBestSize(This,Size).
- %% From wxEvtHandler
+ %% From wxEvtHandler
%% @hidden
disconnect(This,EventType, Options) -> wxEvtHandler:disconnect(This,EventType, Options).
%% @hidden
diff --git a/lib/wx/src/gen/wxMDIParentFrame.erl b/lib/wx/src/gen/wxMDIParentFrame.erl
index 2638309ce7..db47e7ac74 100644
--- a/lib/wx/src/gen/wxMDIParentFrame.erl
+++ b/lib/wx/src/gen/wxMDIParentFrame.erl
@@ -1,24 +1,24 @@
%%
%% %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%
%% This file is generated DO NOT EDIT
%% @doc See external documentation: <a href="http://www.wxwidgets.org/manuals/stable/wx_wxmdiparentframe.html">wxMDIParentFrame</a>.
-%% <p>This class is derived (and can use functions) from:
+%% <p>This class is derived (and can use functions) from:
%% <br />{@link wxFrame}
%% <br />{@link wxTopLevelWindow}
%% <br />{@link wxWindow}
@@ -202,11 +202,11 @@ tile(#wx_ref{type=ThisT,ref=ThisRef}, Options)
%% @spec (This::wxMDIParentFrame()) -> ok
%% @doc Destroys this object, do not use object again
-destroy(Obj=#wx_ref{type=Type}) ->
+destroy(Obj=#wx_ref{type=Type}) ->
?CLASS(Type,wxMDIParentFrame),
wxe_util:destroy(?DESTROY_OBJECT,Obj),
ok.
- %% From wxFrame
+ %% From wxFrame
%% @hidden
setToolBar(This,Toolbar) -> wxFrame:setToolBar(This,Toolbar).
%% @hidden
@@ -243,7 +243,7 @@ createToolBar(This) -> wxFrame:createToolBar(This).
createStatusBar(This, Options) -> wxFrame:createStatusBar(This, Options).
%% @hidden
createStatusBar(This) -> wxFrame:createStatusBar(This).
- %% From wxTopLevelWindow
+ %% From wxTopLevelWindow
%% @hidden
showFullScreen(This,Show, Options) -> wxTopLevelWindow:showFullScreen(This,Show, Options).
%% @hidden
@@ -290,7 +290,7 @@ getTitle(This) -> wxTopLevelWindow:getTitle(This).
getIcons(This) -> wxTopLevelWindow:getIcons(This).
%% @hidden
getIcon(This) -> wxTopLevelWindow:getIcon(This).
- %% From wxWindow
+ %% From wxWindow
%% @hidden
warpPointer(This,X,Y) -> wxWindow:warpPointer(This,X,Y).
%% @hidden
@@ -641,7 +641,7 @@ center(This) -> wxWindow:center(This).
captureMouse(This) -> wxWindow:captureMouse(This).
%% @hidden
cacheBestSize(This,Size) -> wxWindow:cacheBestSize(This,Size).
- %% From wxEvtHandler
+ %% From wxEvtHandler
%% @hidden
disconnect(This,EventType, Options) -> wxEvtHandler:disconnect(This,EventType, Options).
%% @hidden
diff --git a/lib/wx/src/gen/wxMask.erl b/lib/wx/src/gen/wxMask.erl
index 881f8ba183..3b5d3340ea 100644
--- a/lib/wx/src/gen/wxMask.erl
+++ b/lib/wx/src/gen/wxMask.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%
%% This file is generated DO NOT EDIT
@@ -47,7 +47,7 @@ new(#wx_ref{type=BitmapT,ref=BitmapRef}) ->
%% @spec (Bitmap::wxBitmap:wxBitmap(),X::integer()|term()) -> wxMask()
%% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxmask.html#wxmaskwxmask">external documentation</a>.
-%% <br /> Alternatives:
+%% <br /> Alternatives:
%% <p><c>
%% new(Bitmap::wxBitmap:wxBitmap(), PaletteIndex::integer()) -> wxMask() </c>
%% </p>
@@ -75,7 +75,7 @@ create(#wx_ref{type=ThisT,ref=ThisRef},#wx_ref{type=BitmapT,ref=BitmapRef}) ->
%% @spec (This::wxMask(),Bitmap::wxBitmap:wxBitmap(),X::integer()|term()) -> bool()
%% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxmask.html#wxmaskcreate">external documentation</a>.
-%% <br /> Alternatives:
+%% <br /> Alternatives:
%% <p><c>
%% create(This::wxMask(), Bitmap::wxBitmap:wxBitmap(), PaletteIndex::integer()) -> bool() </c>
%% </p>
@@ -97,7 +97,7 @@ create(#wx_ref{type=ThisT,ref=ThisRef},#wx_ref{type=BitmapT,ref=BitmapRef},Colou
%% @spec (This::wxMask()) -> ok
%% @doc Destroys this object, do not use object again
-destroy(Obj=#wx_ref{type=Type}) ->
+destroy(Obj=#wx_ref{type=Type}) ->
?CLASS(Type,wxMask),
wxe_util:destroy(?DESTROY_OBJECT,Obj),
ok.
diff --git a/lib/wx/src/gen/wxMaximizeEvent.erl b/lib/wx/src/gen/wxMaximizeEvent.erl
index 4ad1be3de0..6dd371908b 100644
--- a/lib/wx/src/gen/wxMaximizeEvent.erl
+++ b/lib/wx/src/gen/wxMaximizeEvent.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%
%% This file is generated DO NOT EDIT
@@ -22,7 +22,7 @@
%% <dd><em>maximize</em></dd></dl>
%% See also the message variant {@link wxEvtHandler:wxMaximize(). #wxMaximize{}} event record type.
%%
-%% <p>This class is derived (and can use functions) from:
+%% <p>This class is derived (and can use functions) from:
%% <br />{@link wxEvent}
%% </p>
%% @type wxMaximizeEvent(). An object reference, The representation is internal
@@ -41,7 +41,7 @@
parent_class(wxEvent) -> true;
parent_class(_Class) -> erlang:error({badtype, ?MODULE}).
- %% From wxEvent
+ %% From wxEvent
%% @hidden
stopPropagation(This) -> wxEvent:stopPropagation(This).
%% @hidden
diff --git a/lib/wx/src/gen/wxMemoryDC.erl b/lib/wx/src/gen/wxMemoryDC.erl
index 28471cc8d3..d17ebba4b7 100644
--- a/lib/wx/src/gen/wxMemoryDC.erl
+++ b/lib/wx/src/gen/wxMemoryDC.erl
@@ -1,24 +1,24 @@
%%
%% %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%
%% This file is generated DO NOT EDIT
%% @doc See external documentation: <a href="http://www.wxwidgets.org/manuals/stable/wx_wxmemorydc.html">wxMemoryDC</a>.
-%% <p>This class is derived (and can use functions) from:
+%% <p>This class is derived (and can use functions) from:
%% <br />{@link wxDC}
%% </p>
%% @type wxMemoryDC(). An object reference, The representation is internal
@@ -92,11 +92,11 @@ selectObjectAsSource(#wx_ref{type=ThisT,ref=ThisRef},#wx_ref{type=BmpT,ref=BmpRe
%% @spec (This::wxMemoryDC()) -> ok
%% @doc Destroys this object, do not use object again
-destroy(Obj=#wx_ref{type=Type}) ->
+destroy(Obj=#wx_ref{type=Type}) ->
?CLASS(Type,wxMemoryDC),
wxe_util:destroy(?DESTROY_OBJECT,Obj),
ok.
- %% From wxDC
+ %% From wxDC
%% @hidden
startPage(This) -> wxDC:startPage(This).
%% @hidden
diff --git a/lib/wx/src/gen/wxMenu.erl b/lib/wx/src/gen/wxMenu.erl
index bc4fef6f18..615a845d11 100644
--- a/lib/wx/src/gen/wxMenu.erl
+++ b/lib/wx/src/gen/wxMenu.erl
@@ -1,24 +1,24 @@
%%
%% %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%
%% This file is generated DO NOT EDIT
%% @doc See external documentation: <a href="http://www.wxwidgets.org/manuals/stable/wx_wxmenu.html">wxMenu</a>.
-%% <p>This class is derived (and can use functions) from:
+%% <p>This class is derived (and can use functions) from:
%% <br />{@link wxEvtHandler}
%% </p>
%% @type wxMenu(). An object reference, The representation is internal
@@ -88,7 +88,7 @@ append(This,Itemid,Text)
%% @spec (This::wxMenu(),Itemid::integer(),Text::string(),X::wxMenu()|term()) -> wxMenuItem:wxMenuItem()
%% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxmenu.html#wxmenuappend">external documentation</a>.
-%% <br /> Alternatives:
+%% <br /> Alternatives:
%% <p><c>
%% append(This::wxMenu(), Itemid::integer(), Text::string(), Submenu::wxMenu()) -> append(This,Itemid,Text,Submenu, []) </c></p>
%% <p><c>
@@ -114,7 +114,7 @@ append(#wx_ref{type=ThisT,ref=ThisRef},Itemid,Text, Options)
%% @spec (This::wxMenu(),Itemid::integer(),Text::string(),X::string()|wxMenu(),X::bool()|term()) -> ok|wxMenuItem:wxMenuItem()
%% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxmenu.html#wxmenuappend">external documentation</a>.
-%% <br /> Alternatives:
+%% <br /> Alternatives:
%% <p><c>
%% append(This::wxMenu(), Itemid::integer(), Text::string(), Help::string(), IsCheckable::bool()) -> ok </c>
%% </p>
@@ -202,7 +202,7 @@ check(#wx_ref{type=ThisT,ref=ThisRef},Itemid,Check)
%% @spec (This::wxMenu(),X::integer()|term()) -> bool()
%% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxmenu.html#wxmenudelete">external documentation</a>.
-%% <br /> Alternatives:
+%% <br /> Alternatives:
%% <p><c>
%% delete(This::wxMenu(), Itemid::integer()) -> bool() </c>
%% </p>
@@ -222,7 +222,7 @@ delete(#wx_ref{type=ThisT,ref=ThisRef},#wx_ref{type=ItemT,ref=ItemRef}) ->
%% @spec (This::wxMenu(),X::integer()|term()) -> bool()
%% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxmenu.html#wxmenudestroy">external documentation</a>.
-%% <br /> Alternatives:
+%% <br /> Alternatives:
%% <p><c>
%% 'Destroy'(This::wxMenu(), Itemid::integer()) -> bool() </c>
%% </p>
@@ -250,7 +250,7 @@ enable(#wx_ref{type=ThisT,ref=ThisRef},Itemid,Enable)
%% @spec (This::wxMenu(),X::integer()|string()) -> wxMenuItem:wxMenuItem()|integer()
%% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxmenu.html#wxmenufinditem">external documentation</a>.
-%% <br /> Alternatives:
+%% <br /> Alternatives:
%% <p><c>
%% findItem(This::wxMenu(), Itemid::integer()) -> wxMenuItem:wxMenuItem() </c>
%% </p>
@@ -316,7 +316,7 @@ getTitle(#wx_ref{type=ThisT,ref=ThisRef}) ->
%% @spec (This::wxMenu(),Pos::integer(),X::integer()|term()) -> wxMenuItem:wxMenuItem()
%% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxmenu.html#wxmenuinsert">external documentation</a>.
-%% <br /> Alternatives:
+%% <br /> Alternatives:
%% <p><c>
%% insert(This::wxMenu(), Pos::integer(), Itemid::integer()) -> insert(This,Pos,Itemid, []) </c></p>
%% <p><c>
@@ -357,7 +357,7 @@ insert(This,Pos,Itemid,Text,Submenu)
%% @spec (This::wxMenu(),Pos::integer(),Itemid::integer(),Text::string(),X::string()|wxMenu(),X::bool()|term()) -> ok|wxMenuItem:wxMenuItem()
%% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxmenu.html#wxmenuinsert">external documentation</a>.
-%% <br /> Alternatives:
+%% <br /> Alternatives:
%% <p><c>
%% insert(This::wxMenu(), Pos::integer(), Itemid::integer(), Text::string(), Help::string(), IsCheckable::bool()) -> ok </c>
%% </p>
@@ -447,7 +447,7 @@ isEnabled(#wx_ref{type=ThisT,ref=ThisRef},Itemid)
%% @spec (This::wxMenu(),X::integer()|term()) -> wxMenuItem:wxMenuItem()
%% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxmenu.html#wxmenuprepend">external documentation</a>.
-%% <br /> Alternatives:
+%% <br /> Alternatives:
%% <p><c>
%% prepend(This::wxMenu(), Itemid::integer()) -> prepend(This,Itemid, []) </c></p>
%% <p><c>
@@ -487,7 +487,7 @@ prepend(This,Itemid,Text,Submenu)
%% @spec (This::wxMenu(),Itemid::integer(),Text::string(),X::string()|wxMenu(),X::bool()|term()) -> ok|wxMenuItem:wxMenuItem()
%% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxmenu.html#wxmenuprepend">external documentation</a>.
-%% <br /> Alternatives:
+%% <br /> Alternatives:
%% <p><c>
%% prepend(This::wxMenu(), Itemid::integer(), Text::string(), Help::string(), IsCheckable::bool()) -> ok </c>
%% </p>
@@ -560,7 +560,7 @@ prependSeparator(#wx_ref{type=ThisT,ref=ThisRef}) ->
%% @spec (This::wxMenu(),X::integer()|term()) -> wxMenuItem:wxMenuItem()
%% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxmenu.html#wxmenuremove">external documentation</a>.
-%% <br /> Alternatives:
+%% <br /> Alternatives:
%% <p><c>
%% remove(This::wxMenu(), Itemid::integer()) -> wxMenuItem:wxMenuItem() </c>
%% </p>
@@ -607,11 +607,11 @@ setTitle(#wx_ref{type=ThisT,ref=ThisRef},Title)
%% @spec (This::wxMenu()) -> ok
%% @doc Destroys this object, do not use object again
-destroy(Obj=#wx_ref{type=Type}) ->
+destroy(Obj=#wx_ref{type=Type}) ->
?CLASS(Type,wxMenu),
wxe_util:destroy(?DESTROY_OBJECT,Obj),
ok.
- %% From wxEvtHandler
+ %% From wxEvtHandler
%% @hidden
disconnect(This,EventType, Options) -> wxEvtHandler:disconnect(This,EventType, Options).
%% @hidden
diff --git a/lib/wx/src/gen/wxMenuBar.erl b/lib/wx/src/gen/wxMenuBar.erl
index 28dab451b8..4ed1b2cbe6 100644
--- a/lib/wx/src/gen/wxMenuBar.erl
+++ b/lib/wx/src/gen/wxMenuBar.erl
@@ -1,24 +1,24 @@
%%
%% %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%
%% This file is generated DO NOT EDIT
%% @doc See external documentation: <a href="http://www.wxwidgets.org/manuals/stable/wx_wxmenubar.html">wxMenuBar</a>.
-%% <p>This class is derived (and can use functions) from:
+%% <p>This class is derived (and can use functions) from:
%% <br />{@link wxWindow}
%% <br />{@link wxEvtHandler}
%% </p>
@@ -304,11 +304,11 @@ setLabelTop(#wx_ref{type=ThisT,ref=ThisRef},Pos,Label)
%% @spec (This::wxMenuBar()) -> ok
%% @doc Destroys this object, do not use object again
-destroy(Obj=#wx_ref{type=Type}) ->
+destroy(Obj=#wx_ref{type=Type}) ->
?CLASS(Type,wxMenuBar),
wxe_util:destroy(?DESTROY_OBJECT,Obj),
ok.
- %% From wxWindow
+ %% From wxWindow
%% @hidden
warpPointer(This,X,Y) -> wxWindow:warpPointer(This,X,Y).
%% @hidden
@@ -649,7 +649,7 @@ center(This) -> wxWindow:center(This).
captureMouse(This) -> wxWindow:captureMouse(This).
%% @hidden
cacheBestSize(This,Size) -> wxWindow:cacheBestSize(This,Size).
- %% From wxEvtHandler
+ %% From wxEvtHandler
%% @hidden
disconnect(This,EventType, Options) -> wxEvtHandler:disconnect(This,EventType, Options).
%% @hidden
diff --git a/lib/wx/src/gen/wxMenuEvent.erl b/lib/wx/src/gen/wxMenuEvent.erl
index 77ce7c04b7..fe368e679a 100644
--- a/lib/wx/src/gen/wxMenuEvent.erl
+++ b/lib/wx/src/gen/wxMenuEvent.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%
%% This file is generated DO NOT EDIT
@@ -22,7 +22,7 @@
%% <dd><em>menu_open</em>, <em>menu_close</em>, <em>menu_highlight</em></dd></dl>
%% See also the message variant {@link wxEvtHandler:wxMenu(). #wxMenu{}} event record type.
%%
-%% <p>This class is derived (and can use functions) from:
+%% <p>This class is derived (and can use functions) from:
%% <br />{@link wxEvent}
%% </p>
%% @type wxMenuEvent(). An object reference, The representation is internal
@@ -62,7 +62,7 @@ isPopup(#wx_ref{type=ThisT,ref=ThisRef}) ->
wxe_util:call(?wxMenuEvent_IsPopup,
<<ThisRef:32/?UI>>).
- %% From wxEvent
+ %% From wxEvent
%% @hidden
stopPropagation(This) -> wxEvent:stopPropagation(This).
%% @hidden
diff --git a/lib/wx/src/gen/wxMenuItem.erl b/lib/wx/src/gen/wxMenuItem.erl
index 2d9fd15d86..e2bbe681c5 100644
--- a/lib/wx/src/gen/wxMenuItem.erl
+++ b/lib/wx/src/gen/wxMenuItem.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%
%% This file is generated DO NOT EDIT
@@ -239,7 +239,7 @@ setText(#wx_ref{type=ThisT,ref=ThisRef},Str)
%% @spec (This::wxMenuItem()) -> ok
%% @doc Destroys this object, do not use object again
-destroy(Obj=#wx_ref{type=Type}) ->
+destroy(Obj=#wx_ref{type=Type}) ->
?CLASS(Type,wxMenuItem),
wxe_util:destroy(?DESTROY_OBJECT,Obj),
ok.
diff --git a/lib/wx/src/gen/wxMessageDialog.erl b/lib/wx/src/gen/wxMessageDialog.erl
index eab41919ba..916b201d3f 100644
--- a/lib/wx/src/gen/wxMessageDialog.erl
+++ b/lib/wx/src/gen/wxMessageDialog.erl
@@ -1,24 +1,24 @@
%%
%% %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%
%% This file is generated DO NOT EDIT
%% @doc See external documentation: <a href="http://www.wxwidgets.org/manuals/stable/wx_wxmessagedialog.html">wxMessageDialog</a>.
-%% <p>This class is derived (and can use functions) from:
+%% <p>This class is derived (and can use functions) from:
%% <br />{@link wxDialog}
%% <br />{@link wxTopLevelWindow}
%% <br />{@link wxWindow}
@@ -107,11 +107,11 @@ new(#wx_ref{type=ParentT,ref=ParentRef},Message, Options)
%% @spec (This::wxMessageDialog()) -> ok
%% @doc Destroys this object, do not use object again
-destroy(Obj=#wx_ref{type=Type}) ->
+destroy(Obj=#wx_ref{type=Type}) ->
?CLASS(Type,wxMessageDialog),
wxe_util:destroy(?DESTROY_OBJECT,Obj),
ok.
- %% From wxDialog
+ %% From wxDialog
%% @hidden
showModal(This) -> wxDialog:showModal(This).
%% @hidden
@@ -134,7 +134,7 @@ endModal(This,RetCode) -> wxDialog:endModal(This,RetCode).
createStdDialogButtonSizer(This,Flags) -> wxDialog:createStdDialogButtonSizer(This,Flags).
%% @hidden
createButtonSizer(This,Flags) -> wxDialog:createButtonSizer(This,Flags).
- %% From wxTopLevelWindow
+ %% From wxTopLevelWindow
%% @hidden
showFullScreen(This,Show, Options) -> wxTopLevelWindow:showFullScreen(This,Show, Options).
%% @hidden
@@ -181,7 +181,7 @@ getTitle(This) -> wxTopLevelWindow:getTitle(This).
getIcons(This) -> wxTopLevelWindow:getIcons(This).
%% @hidden
getIcon(This) -> wxTopLevelWindow:getIcon(This).
- %% From wxWindow
+ %% From wxWindow
%% @hidden
warpPointer(This,X,Y) -> wxWindow:warpPointer(This,X,Y).
%% @hidden
@@ -528,7 +528,7 @@ center(This) -> wxWindow:center(This).
captureMouse(This) -> wxWindow:captureMouse(This).
%% @hidden
cacheBestSize(This,Size) -> wxWindow:cacheBestSize(This,Size).
- %% From wxEvtHandler
+ %% From wxEvtHandler
%% @hidden
disconnect(This,EventType, Options) -> wxEvtHandler:disconnect(This,EventType, Options).
%% @hidden
diff --git a/lib/wx/src/gen/wxMiniFrame.erl b/lib/wx/src/gen/wxMiniFrame.erl
index 3e7799a66f..b86f1d7cfa 100644
--- a/lib/wx/src/gen/wxMiniFrame.erl
+++ b/lib/wx/src/gen/wxMiniFrame.erl
@@ -1,24 +1,24 @@
%%
%% %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%
%% This file is generated DO NOT EDIT
%% @doc See external documentation: <a href="http://www.wxwidgets.org/manuals/stable/wx_wxminiframe.html">wxMiniFrame</a>.
-%% <p>This class is derived (and can use functions) from:
+%% <p>This class is derived (and can use functions) from:
%% <br />{@link wxFrame}
%% <br />{@link wxTopLevelWindow}
%% <br />{@link wxWindow}
@@ -138,11 +138,11 @@ create(#wx_ref{type=ThisT,ref=ThisRef},#wx_ref{type=ParentT,ref=ParentRef},Id,Ti
%% @spec (This::wxMiniFrame()) -> ok
%% @doc Destroys this object, do not use object again
-destroy(Obj=#wx_ref{type=Type}) ->
+destroy(Obj=#wx_ref{type=Type}) ->
?CLASS(Type,wxMiniFrame),
wxe_util:destroy(?DESTROY_OBJECT,Obj),
ok.
- %% From wxFrame
+ %% From wxFrame
%% @hidden
setToolBar(This,Toolbar) -> wxFrame:setToolBar(This,Toolbar).
%% @hidden
@@ -179,7 +179,7 @@ createToolBar(This) -> wxFrame:createToolBar(This).
createStatusBar(This, Options) -> wxFrame:createStatusBar(This, Options).
%% @hidden
createStatusBar(This) -> wxFrame:createStatusBar(This).
- %% From wxTopLevelWindow
+ %% From wxTopLevelWindow
%% @hidden
showFullScreen(This,Show, Options) -> wxTopLevelWindow:showFullScreen(This,Show, Options).
%% @hidden
@@ -226,7 +226,7 @@ getTitle(This) -> wxTopLevelWindow:getTitle(This).
getIcons(This) -> wxTopLevelWindow:getIcons(This).
%% @hidden
getIcon(This) -> wxTopLevelWindow:getIcon(This).
- %% From wxWindow
+ %% From wxWindow
%% @hidden
warpPointer(This,X,Y) -> wxWindow:warpPointer(This,X,Y).
%% @hidden
@@ -577,7 +577,7 @@ center(This) -> wxWindow:center(This).
captureMouse(This) -> wxWindow:captureMouse(This).
%% @hidden
cacheBestSize(This,Size) -> wxWindow:cacheBestSize(This,Size).
- %% From wxEvtHandler
+ %% From wxEvtHandler
%% @hidden
disconnect(This,EventType, Options) -> wxEvtHandler:disconnect(This,EventType, Options).
%% @hidden
diff --git a/lib/wx/src/gen/wxMirrorDC.erl b/lib/wx/src/gen/wxMirrorDC.erl
index 9300f7a31e..c218bd7e72 100644
--- a/lib/wx/src/gen/wxMirrorDC.erl
+++ b/lib/wx/src/gen/wxMirrorDC.erl
@@ -1,24 +1,24 @@
%%
%% %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%
%% This file is generated DO NOT EDIT
%% @doc See external documentation: <a href="http://www.wxwidgets.org/manuals/stable/wx_wxmirrordc.html">wxMirrorDC</a>.
-%% <p>This class is derived (and can use functions) from:
+%% <p>This class is derived (and can use functions) from:
%% <br />{@link wxDC}
%% </p>
%% @type wxMirrorDC(). An object reference, The representation is internal
@@ -66,11 +66,11 @@ new(#wx_ref{type=DcT,ref=DcRef},Mirror)
%% @spec (This::wxMirrorDC()) -> ok
%% @doc Destroys this object, do not use object again
-destroy(Obj=#wx_ref{type=Type}) ->
+destroy(Obj=#wx_ref{type=Type}) ->
?CLASS(Type,wxMirrorDC),
wxe_util:destroy(?DESTROY_OBJECT,Obj),
ok.
- %% From wxDC
+ %% From wxDC
%% @hidden
startPage(This) -> wxDC:startPage(This).
%% @hidden
diff --git a/lib/wx/src/gen/wxMouseCaptureChangedEvent.erl b/lib/wx/src/gen/wxMouseCaptureChangedEvent.erl
index 629dcde795..cb921bf2df 100644
--- a/lib/wx/src/gen/wxMouseCaptureChangedEvent.erl
+++ b/lib/wx/src/gen/wxMouseCaptureChangedEvent.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%
%% This file is generated DO NOT EDIT
@@ -22,7 +22,7 @@
%% <dd><em>mouse_capture_changed</em></dd></dl>
%% See also the message variant {@link wxEvtHandler:wxMouseCaptureChanged(). #wxMouseCaptureChanged{}} event record type.
%%
-%% <p>This class is derived (and can use functions) from:
+%% <p>This class is derived (and can use functions) from:
%% <br />{@link wxEvent}
%% </p>
%% @type wxMouseCaptureChangedEvent(). An object reference, The representation is internal
@@ -48,7 +48,7 @@ getCapturedWindow(#wx_ref{type=ThisT,ref=ThisRef}) ->
wxe_util:call(?wxMouseCaptureChangedEvent_GetCapturedWindow,
<<ThisRef:32/?UI>>).
- %% From wxEvent
+ %% From wxEvent
%% @hidden
stopPropagation(This) -> wxEvent:stopPropagation(This).
%% @hidden
diff --git a/lib/wx/src/gen/wxMouseEvent.erl b/lib/wx/src/gen/wxMouseEvent.erl
index 0772e99b0d..fed9a33db7 100644
--- a/lib/wx/src/gen/wxMouseEvent.erl
+++ b/lib/wx/src/gen/wxMouseEvent.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%
%% This file is generated DO NOT EDIT
@@ -22,7 +22,7 @@
%% <dd><em>left_down</em>, <em>left_up</em>, <em>middle_down</em>, <em>middle_up</em>, <em>right_down</em>, <em>right_up</em>, <em>motion</em>, <em>enter_window</em>, <em>leave_window</em>, <em>left_dclick</em>, <em>middle_dclick</em>, <em>right_dclick</em>, <em>mousewheel</em>, <em>nc_left_down</em>, <em>nc_left_up</em>, <em>nc_middle_down</em>, <em>nc_middle_up</em>, <em>nc_right_down</em>, <em>nc_right_up</em>, <em>nc_motion</em>, <em>nc_enter_window</em>, <em>nc_leave_window</em>, <em>nc_left_dclick</em>, <em>nc_middle_dclick</em>, <em>nc_right_dclick</em></dd></dl>
%% See also the message variant {@link wxEvtHandler:wxMouse(). #wxMouse{}} event record type.
%%
-%% <p>This class is derived (and can use functions) from:
+%% <p>This class is derived (and can use functions) from:
%% <br />{@link wxEvent}
%% </p>
%% @type wxMouseEvent(). An object reference, The representation is internal
@@ -327,7 +327,7 @@ shiftDown(#wx_ref{type=ThisT,ref=ThisRef}) ->
wxe_util:call(?wxMouseEvent_ShiftDown,
<<ThisRef:32/?UI>>).
- %% From wxEvent
+ %% From wxEvent
%% @hidden
stopPropagation(This) -> wxEvent:stopPropagation(This).
%% @hidden
diff --git a/lib/wx/src/gen/wxMoveEvent.erl b/lib/wx/src/gen/wxMoveEvent.erl
index 17a33ff3ed..80bf59074a 100644
--- a/lib/wx/src/gen/wxMoveEvent.erl
+++ b/lib/wx/src/gen/wxMoveEvent.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%
%% This file is generated DO NOT EDIT
@@ -22,7 +22,7 @@
%% <dd><em>move</em></dd></dl>
%% See also the message variant {@link wxEvtHandler:wxMove(). #wxMove{}} event record type.
%%
-%% <p>This class is derived (and can use functions) from:
+%% <p>This class is derived (and can use functions) from:
%% <br />{@link wxEvent}
%% </p>
%% @type wxMoveEvent(). An object reference, The representation is internal
@@ -48,7 +48,7 @@ getPosition(#wx_ref{type=ThisT,ref=ThisRef}) ->
wxe_util:call(?wxMoveEvent_GetPosition,
<<ThisRef:32/?UI>>).
- %% From wxEvent
+ %% From wxEvent
%% @hidden
stopPropagation(This) -> wxEvent:stopPropagation(This).
%% @hidden
diff --git a/lib/wx/src/gen/wxMultiChoiceDialog.erl b/lib/wx/src/gen/wxMultiChoiceDialog.erl
index 98690654e6..e69889a1e0 100644
--- a/lib/wx/src/gen/wxMultiChoiceDialog.erl
+++ b/lib/wx/src/gen/wxMultiChoiceDialog.erl
@@ -1,24 +1,24 @@
%%
%% %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%
%% This file is generated DO NOT EDIT
%% @doc See external documentation: <a href="http://www.wxwidgets.org/manuals/stable/wx_wxmultichoicedialog.html">wxMultiChoiceDialog</a>.
-%% <p>This class is derived (and can use functions) from:
+%% <p>This class is derived (and can use functions) from:
%% <br />{@link wxDialog}
%% <br />{@link wxTopLevelWindow}
%% <br />{@link wxWindow}
@@ -131,11 +131,11 @@ setSelections(#wx_ref{type=ThisT,ref=ThisRef},Selections)
%% @spec (This::wxMultiChoiceDialog()) -> ok
%% @doc Destroys this object, do not use object again
-destroy(Obj=#wx_ref{type=Type}) ->
+destroy(Obj=#wx_ref{type=Type}) ->
?CLASS(Type,wxMultiChoiceDialog),
wxe_util:destroy(?DESTROY_OBJECT,Obj),
ok.
- %% From wxDialog
+ %% From wxDialog
%% @hidden
showModal(This) -> wxDialog:showModal(This).
%% @hidden
@@ -158,7 +158,7 @@ endModal(This,RetCode) -> wxDialog:endModal(This,RetCode).
createStdDialogButtonSizer(This,Flags) -> wxDialog:createStdDialogButtonSizer(This,Flags).
%% @hidden
createButtonSizer(This,Flags) -> wxDialog:createButtonSizer(This,Flags).
- %% From wxTopLevelWindow
+ %% From wxTopLevelWindow
%% @hidden
showFullScreen(This,Show, Options) -> wxTopLevelWindow:showFullScreen(This,Show, Options).
%% @hidden
@@ -205,7 +205,7 @@ getTitle(This) -> wxTopLevelWindow:getTitle(This).
getIcons(This) -> wxTopLevelWindow:getIcons(This).
%% @hidden
getIcon(This) -> wxTopLevelWindow:getIcon(This).
- %% From wxWindow
+ %% From wxWindow
%% @hidden
warpPointer(This,X,Y) -> wxWindow:warpPointer(This,X,Y).
%% @hidden
@@ -552,7 +552,7 @@ center(This) -> wxWindow:center(This).
captureMouse(This) -> wxWindow:captureMouse(This).
%% @hidden
cacheBestSize(This,Size) -> wxWindow:cacheBestSize(This,Size).
- %% From wxEvtHandler
+ %% From wxEvtHandler
%% @hidden
disconnect(This,EventType, Options) -> wxEvtHandler:disconnect(This,EventType, Options).
%% @hidden
diff --git a/lib/wx/src/gen/wxNavigationKeyEvent.erl b/lib/wx/src/gen/wxNavigationKeyEvent.erl
index 9a74a75c51..7cf7dff9aa 100644
--- a/lib/wx/src/gen/wxNavigationKeyEvent.erl
+++ b/lib/wx/src/gen/wxNavigationKeyEvent.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%
%% This file is generated DO NOT EDIT
@@ -22,7 +22,7 @@
%% <dd><em>navigation_key</em></dd></dl>
%% See also the message variant {@link wxEvtHandler:wxNavigationKey(). #wxNavigationKey{}} event record type.
%%
-%% <p>This class is derived (and can use functions) from:
+%% <p>This class is derived (and can use functions) from:
%% <br />{@link wxEvent}
%% </p>
%% @type wxNavigationKeyEvent(). An object reference, The representation is internal
@@ -102,7 +102,7 @@ setCurrentFocus(#wx_ref{type=ThisT,ref=ThisRef},#wx_ref{type=WinT,ref=WinRef}) -
wxe_util:cast(?wxNavigationKeyEvent_SetCurrentFocus,
<<ThisRef:32/?UI,WinRef:32/?UI>>).
- %% From wxEvent
+ %% From wxEvent
%% @hidden
stopPropagation(This) -> wxEvent:stopPropagation(This).
%% @hidden
diff --git a/lib/wx/src/gen/wxNcPaintEvent.erl b/lib/wx/src/gen/wxNcPaintEvent.erl
index 22e00d337d..b45420a2fc 100644
--- a/lib/wx/src/gen/wxNcPaintEvent.erl
+++ b/lib/wx/src/gen/wxNcPaintEvent.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%
%% This file is generated DO NOT EDIT
@@ -22,7 +22,7 @@
%% <dd><em>nc_paint</em></dd></dl>
%% See also the message variant {@link wxEvtHandler:wxNcPaint(). #wxNcPaint{}} event record type.
%%
-%% <p>This class is derived (and can use functions) from:
+%% <p>This class is derived (and can use functions) from:
%% <br />{@link wxEvent}
%% </p>
%% @type wxNcPaintEvent(). An object reference, The representation is internal
@@ -41,7 +41,7 @@
parent_class(wxEvent) -> true;
parent_class(_Class) -> erlang:error({badtype, ?MODULE}).
- %% From wxEvent
+ %% From wxEvent
%% @hidden
stopPropagation(This) -> wxEvent:stopPropagation(This).
%% @hidden
diff --git a/lib/wx/src/gen/wxNotebook.erl b/lib/wx/src/gen/wxNotebook.erl
index 93cc741036..da543d7ac6 100644
--- a/lib/wx/src/gen/wxNotebook.erl
+++ b/lib/wx/src/gen/wxNotebook.erl
@@ -1,24 +1,24 @@
%%
%% %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%
%% This file is generated DO NOT EDIT
%% @doc See external documentation: <a href="http://www.wxwidgets.org/manuals/stable/wx_wxnotebook.html">wxNotebook</a>.
-%% <p>This class is derived (and can use functions) from:
+%% <p>This class is derived (and can use functions) from:
%% <br />{@link wxControl}
%% <br />{@link wxWindow}
%% <br />{@link wxEvtHandler}
@@ -351,16 +351,16 @@ changeSelection(#wx_ref{type=ThisT,ref=ThisRef},NPage)
%% @spec (This::wxNotebook()) -> ok
%% @doc Destroys this object, do not use object again
-destroy(Obj=#wx_ref{type=Type}) ->
+destroy(Obj=#wx_ref{type=Type}) ->
?CLASS(Type,wxNotebook),
wxe_util:destroy(?DESTROY_OBJECT,Obj),
ok.
- %% From wxControl
+ %% From wxControl
%% @hidden
setLabel(This,Label) -> wxControl:setLabel(This,Label).
%% @hidden
getLabel(This) -> wxControl:getLabel(This).
- %% From wxWindow
+ %% From wxWindow
%% @hidden
warpPointer(This,X,Y) -> wxWindow:warpPointer(This,X,Y).
%% @hidden
@@ -707,7 +707,7 @@ center(This) -> wxWindow:center(This).
captureMouse(This) -> wxWindow:captureMouse(This).
%% @hidden
cacheBestSize(This,Size) -> wxWindow:cacheBestSize(This,Size).
- %% From wxEvtHandler
+ %% From wxEvtHandler
%% @hidden
disconnect(This,EventType, Options) -> wxEvtHandler:disconnect(This,EventType, Options).
%% @hidden
diff --git a/lib/wx/src/gen/wxNotebookEvent.erl b/lib/wx/src/gen/wxNotebookEvent.erl
index 4664f85527..6be826bdd2 100644
--- a/lib/wx/src/gen/wxNotebookEvent.erl
+++ b/lib/wx/src/gen/wxNotebookEvent.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%
%% This file is generated DO NOT EDIT
@@ -22,7 +22,7 @@
%% <dd><em>command_notebook_page_changed</em>, <em>command_notebook_page_changing</em></dd></dl>
%% See also the message variant {@link wxEvtHandler:wxNotebook(). #wxNotebook{}} event record type.
%%
-%% <p>This class is derived (and can use functions) from:
+%% <p>This class is derived (and can use functions) from:
%% <br />{@link wxNotifyEvent}
%% <br />{@link wxCommandEvent}
%% <br />{@link wxEvent}
@@ -77,14 +77,14 @@ setSelection(#wx_ref{type=ThisT,ref=ThisRef},NSel)
wxe_util:cast(?wxNotebookEvent_SetSelection,
<<ThisRef:32/?UI,NSel:32/?UI>>).
- %% From wxNotifyEvent
+ %% From wxNotifyEvent
%% @hidden
veto(This) -> wxNotifyEvent:veto(This).
%% @hidden
isAllowed(This) -> wxNotifyEvent:isAllowed(This).
%% @hidden
allow(This) -> wxNotifyEvent:allow(This).
- %% From wxCommandEvent
+ %% From wxCommandEvent
%% @hidden
setString(This,S) -> wxCommandEvent:setString(This,S).
%% @hidden
@@ -101,7 +101,7 @@ getInt(This) -> wxCommandEvent:getInt(This).
getExtraLong(This) -> wxCommandEvent:getExtraLong(This).
%% @hidden
getClientData(This) -> wxCommandEvent:getClientData(This).
- %% From wxEvent
+ %% From wxEvent
%% @hidden
stopPropagation(This) -> wxEvent:stopPropagation(This).
%% @hidden
diff --git a/lib/wx/src/gen/wxNotifyEvent.erl b/lib/wx/src/gen/wxNotifyEvent.erl
index 4e463aa7e0..b2a6da16f0 100644
--- a/lib/wx/src/gen/wxNotifyEvent.erl
+++ b/lib/wx/src/gen/wxNotifyEvent.erl
@@ -1,24 +1,24 @@
%%
%% %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%
%% This file is generated DO NOT EDIT
%% @doc See external documentation: <a href="http://www.wxwidgets.org/manuals/stable/wx_wxnotifyevent.html">wxNotifyEvent</a>.
-%% <p>This class is derived (and can use functions) from:
+%% <p>This class is derived (and can use functions) from:
%% <br />{@link wxCommandEvent}
%% <br />{@link wxEvent}
%% </p>
@@ -62,7 +62,7 @@ veto(#wx_ref{type=ThisT,ref=ThisRef}) ->
wxe_util:cast(?wxNotifyEvent_Veto,
<<ThisRef:32/?UI>>).
- %% From wxCommandEvent
+ %% From wxCommandEvent
%% @hidden
setString(This,S) -> wxCommandEvent:setString(This,S).
%% @hidden
@@ -81,7 +81,7 @@ getInt(This) -> wxCommandEvent:getInt(This).
getExtraLong(This) -> wxCommandEvent:getExtraLong(This).
%% @hidden
getClientData(This) -> wxCommandEvent:getClientData(This).
- %% From wxEvent
+ %% From wxEvent
%% @hidden
stopPropagation(This) -> wxEvent:stopPropagation(This).
%% @hidden
diff --git a/lib/wx/src/gen/wxPageSetupDialog.erl b/lib/wx/src/gen/wxPageSetupDialog.erl
index 73eac44ab5..2c11863a21 100644
--- a/lib/wx/src/gen/wxPageSetupDialog.erl
+++ b/lib/wx/src/gen/wxPageSetupDialog.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%
%% This file is generated DO NOT EDIT
@@ -66,7 +66,7 @@ showModal(#wx_ref{type=ThisT,ref=ThisRef}) ->
%% @spec (This::wxPageSetupDialog()) -> ok
%% @doc Destroys this object, do not use object again
-destroy(Obj=#wx_ref{type=Type}) ->
+destroy(Obj=#wx_ref{type=Type}) ->
?CLASS(Type,wxPageSetupDialog),
wxe_util:destroy(?DESTROY_OBJECT,Obj),
ok.
diff --git a/lib/wx/src/gen/wxPageSetupDialogData.erl b/lib/wx/src/gen/wxPageSetupDialogData.erl
index 576be819a2..672ec7c083 100644
--- a/lib/wx/src/gen/wxPageSetupDialogData.erl
+++ b/lib/wx/src/gen/wxPageSetupDialogData.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%
%% This file is generated DO NOT EDIT
@@ -260,7 +260,7 @@ setPaperId(#wx_ref{type=ThisT,ref=ThisRef},Id)
%% @spec (This::wxPageSetupDialogData(),X::integer()|term()) -> ok
%% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxpagesetupdialogdata.html#wxpagesetupdialogdatasetpapersize">external documentation</a>.
-%% <br /> Alternatives:
+%% <br /> Alternatives:
%% <p><c>
%% setPaperSize(This::wxPageSetupDialogData(), Id::integer()) -> ok </c>
%% </p>
@@ -288,7 +288,7 @@ setPrintData(#wx_ref{type=ThisT,ref=ThisRef},#wx_ref{type=PrintDataT,ref=PrintDa
%% @spec (This::wxPageSetupDialogData()) -> ok
%% @doc Destroys this object, do not use object again
-destroy(Obj=#wx_ref{type=Type}) ->
+destroy(Obj=#wx_ref{type=Type}) ->
?CLASS(Type,wxPageSetupDialogData),
wxe_util:destroy(?DESTROY_OBJECT,Obj),
ok.
diff --git a/lib/wx/src/gen/wxPaintDC.erl b/lib/wx/src/gen/wxPaintDC.erl
index ea4e847f69..47d5947097 100644
--- a/lib/wx/src/gen/wxPaintDC.erl
+++ b/lib/wx/src/gen/wxPaintDC.erl
@@ -1,24 +1,24 @@
%%
%% %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%
%% This file is generated DO NOT EDIT
%% @doc See external documentation: <a href="http://www.wxwidgets.org/manuals/stable/wx_wxpaintdc.html">wxPaintDC</a>.
-%% <p>This class is derived (and can use functions) from:
+%% <p>This class is derived (and can use functions) from:
%% <br />{@link wxWindowDC}
%% <br />{@link wxDC}
%% </p>
@@ -73,12 +73,12 @@ new(#wx_ref{type=WinT,ref=WinRef}) ->
%% @spec (This::wxPaintDC()) -> ok
%% @doc Destroys this object, do not use object again
-destroy(Obj=#wx_ref{type=Type}) ->
+destroy(Obj=#wx_ref{type=Type}) ->
?CLASS(Type,wxPaintDC),
wxe_util:destroy(?DESTROY_OBJECT,Obj),
ok.
- %% From wxWindowDC
- %% From wxDC
+ %% From wxWindowDC
+ %% From wxDC
%% @hidden
startPage(This) -> wxDC:startPage(This).
%% @hidden
diff --git a/lib/wx/src/gen/wxPaintEvent.erl b/lib/wx/src/gen/wxPaintEvent.erl
index 9f6b84890b..2603e61623 100644
--- a/lib/wx/src/gen/wxPaintEvent.erl
+++ b/lib/wx/src/gen/wxPaintEvent.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%
%% This file is generated DO NOT EDIT
@@ -22,7 +22,7 @@
%% <dd><em>paint</em>, <em>paint_icon</em></dd></dl>
%% See also the message variant {@link wxEvtHandler:wxPaint(). #wxPaint{}} event record type.
%%
-%% <p>This class is derived (and can use functions) from:
+%% <p>This class is derived (and can use functions) from:
%% <br />{@link wxEvent}
%% </p>
%% @type wxPaintEvent(). An object reference, The representation is internal
@@ -41,7 +41,7 @@
parent_class(wxEvent) -> true;
parent_class(_Class) -> erlang:error({badtype, ?MODULE}).
- %% From wxEvent
+ %% From wxEvent
%% @hidden
stopPropagation(This) -> wxEvent:stopPropagation(This).
%% @hidden
diff --git a/lib/wx/src/gen/wxPalette.erl b/lib/wx/src/gen/wxPalette.erl
index 499e6f47ce..ee1fd0016d 100644
--- a/lib/wx/src/gen/wxPalette.erl
+++ b/lib/wx/src/gen/wxPalette.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%
%% This file is generated DO NOT EDIT
@@ -92,7 +92,7 @@ isOk(#wx_ref{type=ThisT,ref=ThisRef}) ->
%% @spec (This::wxPalette()) -> ok
%% @doc Destroys this object, do not use object again
-destroy(Obj=#wx_ref{type=Type}) ->
+destroy(Obj=#wx_ref{type=Type}) ->
?CLASS(Type,wxPalette),
wxe_util:destroy(?DESTROY_OBJECT,Obj),
ok.
diff --git a/lib/wx/src/gen/wxPaletteChangedEvent.erl b/lib/wx/src/gen/wxPaletteChangedEvent.erl
index 147389709c..1831bf1375 100644
--- a/lib/wx/src/gen/wxPaletteChangedEvent.erl
+++ b/lib/wx/src/gen/wxPaletteChangedEvent.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%
%% This file is generated DO NOT EDIT
@@ -22,7 +22,7 @@
%% <dd><em>palette_changed</em></dd></dl>
%% See also the message variant {@link wxEvtHandler:wxPaletteChanged(). #wxPaletteChanged{}} event record type.
%%
-%% <p>This class is derived (and can use functions) from:
+%% <p>This class is derived (and can use functions) from:
%% <br />{@link wxEvent}
%% </p>
%% @type wxPaletteChangedEvent(). An object reference, The representation is internal
@@ -56,7 +56,7 @@ getChangedWindow(#wx_ref{type=ThisT,ref=ThisRef}) ->
wxe_util:call(?wxPaletteChangedEvent_GetChangedWindow,
<<ThisRef:32/?UI>>).
- %% From wxEvent
+ %% From wxEvent
%% @hidden
stopPropagation(This) -> wxEvent:stopPropagation(This).
%% @hidden
diff --git a/lib/wx/src/gen/wxPanel.erl b/lib/wx/src/gen/wxPanel.erl
index ca18caf4da..55eaa9f404 100644
--- a/lib/wx/src/gen/wxPanel.erl
+++ b/lib/wx/src/gen/wxPanel.erl
@@ -1,24 +1,24 @@
%%
%% %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%
%% This file is generated DO NOT EDIT
%% @doc See external documentation: <a href="http://www.wxwidgets.org/manuals/stable/wx_wxpanel.html">wxPanel</a>.
-%% <p>This class is derived (and can use functions) from:
+%% <p>This class is derived (and can use functions) from:
%% <br />{@link wxWindow}
%% <br />{@link wxEvtHandler}
%% </p>
@@ -127,11 +127,11 @@ initDialog(#wx_ref{type=ThisT,ref=ThisRef}) ->
%% @spec (This::wxPanel()) -> ok
%% @doc Destroys this object, do not use object again
-destroy(Obj=#wx_ref{type=Type}) ->
+destroy(Obj=#wx_ref{type=Type}) ->
?CLASS(Type,wxPanel),
wxe_util:destroy(?DESTROY_OBJECT,Obj),
ok.
- %% From wxWindow
+ %% From wxWindow
%% @hidden
warpPointer(This,X,Y) -> wxWindow:warpPointer(This,X,Y).
%% @hidden
@@ -480,7 +480,7 @@ center(This) -> wxWindow:center(This).
captureMouse(This) -> wxWindow:captureMouse(This).
%% @hidden
cacheBestSize(This,Size) -> wxWindow:cacheBestSize(This,Size).
- %% From wxEvtHandler
+ %% From wxEvtHandler
%% @hidden
disconnect(This,EventType, Options) -> wxEvtHandler:disconnect(This,EventType, Options).
%% @hidden
diff --git a/lib/wx/src/gen/wxPasswordEntryDialog.erl b/lib/wx/src/gen/wxPasswordEntryDialog.erl
index 70728355e9..f79734ab46 100644
--- a/lib/wx/src/gen/wxPasswordEntryDialog.erl
+++ b/lib/wx/src/gen/wxPasswordEntryDialog.erl
@@ -1,24 +1,24 @@
%%
%% %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%
%% This file is generated DO NOT EDIT
%% @doc See external documentation: <a href="http://www.wxwidgets.org/manuals/stable/wx_wxpasswordentrydialog.html">wxPasswordEntryDialog</a>.
-%% <p>This class is derived (and can use functions) from:
+%% <p>This class is derived (and can use functions) from:
%% <br />{@link wxTextEntryDialog}
%% <br />{@link wxDialog}
%% <br />{@link wxTopLevelWindow}
@@ -111,16 +111,16 @@ new(#wx_ref{type=ParentT,ref=ParentRef},Message, Options)
%% @spec (This::wxPasswordEntryDialog()) -> ok
%% @doc Destroys this object, do not use object again
-destroy(Obj=#wx_ref{type=Type}) ->
+destroy(Obj=#wx_ref{type=Type}) ->
?CLASS(Type,wxPasswordEntryDialog),
wxe_util:destroy(?DESTROY_OBJECT,Obj),
ok.
- %% From wxTextEntryDialog
+ %% From wxTextEntryDialog
%% @hidden
setValue(This,Val) -> wxTextEntryDialog:setValue(This,Val).
%% @hidden
getValue(This) -> wxTextEntryDialog:getValue(This).
- %% From wxDialog
+ %% From wxDialog
%% @hidden
showModal(This) -> wxDialog:showModal(This).
%% @hidden
@@ -143,7 +143,7 @@ endModal(This,RetCode) -> wxDialog:endModal(This,RetCode).
createStdDialogButtonSizer(This,Flags) -> wxDialog:createStdDialogButtonSizer(This,Flags).
%% @hidden
createButtonSizer(This,Flags) -> wxDialog:createButtonSizer(This,Flags).
- %% From wxTopLevelWindow
+ %% From wxTopLevelWindow
%% @hidden
showFullScreen(This,Show, Options) -> wxTopLevelWindow:showFullScreen(This,Show, Options).
%% @hidden
@@ -190,7 +190,7 @@ getTitle(This) -> wxTopLevelWindow:getTitle(This).
getIcons(This) -> wxTopLevelWindow:getIcons(This).
%% @hidden
getIcon(This) -> wxTopLevelWindow:getIcon(This).
- %% From wxWindow
+ %% From wxWindow
%% @hidden
warpPointer(This,X,Y) -> wxWindow:warpPointer(This,X,Y).
%% @hidden
@@ -537,7 +537,7 @@ center(This) -> wxWindow:center(This).
captureMouse(This) -> wxWindow:captureMouse(This).
%% @hidden
cacheBestSize(This,Size) -> wxWindow:cacheBestSize(This,Size).
- %% From wxEvtHandler
+ %% From wxEvtHandler
%% @hidden
disconnect(This,EventType, Options) -> wxEvtHandler:disconnect(This,EventType, Options).
%% @hidden
diff --git a/lib/wx/src/gen/wxPen.erl b/lib/wx/src/gen/wxPen.erl
index cf159f559e..ada95b0ee3 100644
--- a/lib/wx/src/gen/wxPen.erl
+++ b/lib/wx/src/gen/wxPen.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%
%% This file is generated DO NOT EDIT
@@ -150,7 +150,7 @@ setWidth(#wx_ref{type=ThisT,ref=ThisRef},Width)
%% @spec (This::wxPen()) -> ok
%% @doc Destroys this object, do not use object again
-destroy(Obj=#wx_ref{type=Type}) ->
+destroy(Obj=#wx_ref{type=Type}) ->
?CLASS(Type,wxPen),
wxe_util:destroy(?DESTROY_OBJECT,Obj),
ok.
diff --git a/lib/wx/src/gen/wxPickerBase.erl b/lib/wx/src/gen/wxPickerBase.erl
index 173f31faf0..e60ab4f9d8 100644
--- a/lib/wx/src/gen/wxPickerBase.erl
+++ b/lib/wx/src/gen/wxPickerBase.erl
@@ -1,24 +1,24 @@
%%
%% %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%
%% This file is generated DO NOT EDIT
%% @doc See external documentation: <a href="http://www.wxwidgets.org/manuals/stable/wx_wxpickerbase.html">wxPickerBase</a>.
-%% <p>This class is derived (and can use functions) from:
+%% <p>This class is derived (and can use functions) from:
%% <br />{@link wxControl}
%% <br />{@link wxWindow}
%% <br />{@link wxEvtHandler}
@@ -187,12 +187,12 @@ isPickerCtrlGrowable(#wx_ref{type=ThisT,ref=ThisRef}) ->
wxe_util:call(?wxPickerBase_IsPickerCtrlGrowable,
<<ThisRef:32/?UI>>).
- %% From wxControl
+ %% From wxControl
%% @hidden
setLabel(This,Label) -> wxControl:setLabel(This,Label).
%% @hidden
getLabel(This) -> wxControl:getLabel(This).
- %% From wxWindow
+ %% From wxWindow
%% @hidden
warpPointer(This,X,Y) -> wxWindow:warpPointer(This,X,Y).
%% @hidden
@@ -539,7 +539,7 @@ center(This) -> wxWindow:center(This).
captureMouse(This) -> wxWindow:captureMouse(This).
%% @hidden
cacheBestSize(This,Size) -> wxWindow:cacheBestSize(This,Size).
- %% From wxEvtHandler
+ %% From wxEvtHandler
%% @hidden
disconnect(This,EventType, Options) -> wxEvtHandler:disconnect(This,EventType, Options).
%% @hidden
diff --git a/lib/wx/src/gen/wxPostScriptDC.erl b/lib/wx/src/gen/wxPostScriptDC.erl
index 6e67abdd08..df3edfade9 100644
--- a/lib/wx/src/gen/wxPostScriptDC.erl
+++ b/lib/wx/src/gen/wxPostScriptDC.erl
@@ -1,24 +1,24 @@
%%
%% %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%
%% This file is generated DO NOT EDIT
%% @doc See external documentation: <a href="http://www.wxwidgets.org/manuals/stable/wx_wxpostscriptdc.html">wxPostScriptDC</a>.
-%% <p>This class is derived (and can use functions) from:
+%% <p>This class is derived (and can use functions) from:
%% <br />{@link wxDC}
%% </p>
%% @type wxPostScriptDC(). An object reference, The representation is internal
@@ -84,11 +84,11 @@ getResolution() ->
%% @spec (This::wxPostScriptDC()) -> ok
%% @doc Destroys this object, do not use object again
-destroy(Obj=#wx_ref{type=Type}) ->
+destroy(Obj=#wx_ref{type=Type}) ->
?CLASS(Type,wxPostScriptDC),
wxe_util:destroy(?DESTROY_OBJECT,Obj),
ok.
- %% From wxDC
+ %% From wxDC
%% @hidden
startPage(This) -> wxDC:startPage(This).
%% @hidden
diff --git a/lib/wx/src/gen/wxPreviewCanvas.erl b/lib/wx/src/gen/wxPreviewCanvas.erl
index 4f52e2015f..d33aeedb70 100644
--- a/lib/wx/src/gen/wxPreviewCanvas.erl
+++ b/lib/wx/src/gen/wxPreviewCanvas.erl
@@ -1,24 +1,24 @@
%%
%% %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%
%% This file is generated DO NOT EDIT
%% @doc See external documentation: <a href="http://www.wxwidgets.org/manuals/stable/wx_wxpreviewcanvas.html">wxPreviewCanvas</a>.
-%% <p>This class is derived (and can use functions) from:
+%% <p>This class is derived (and can use functions) from:
%% <br />{@link wxScrolledWindow}
%% <br />{@link wxPanel}
%% <br />{@link wxWindow}
@@ -81,7 +81,7 @@ parent_class(wxWindow) -> true;
parent_class(wxEvtHandler) -> true;
parent_class(_Class) -> erlang:error({badtype, ?MODULE}).
- %% From wxScrolledWindow
+ %% From wxScrolledWindow
%% @hidden
setTargetWindow(This,Target) -> wxScrolledWindow:setTargetWindow(This,Target).
%% @hidden
@@ -110,10 +110,10 @@ calcUnscrolledPosition(This,Pt) -> wxScrolledWindow:calcUnscrolledPosition(This,
calcScrolledPosition(This,X,Y) -> wxScrolledWindow:calcScrolledPosition(This,X,Y).
%% @hidden
calcScrolledPosition(This,Pt) -> wxScrolledWindow:calcScrolledPosition(This,Pt).
- %% From wxPanel
+ %% From wxPanel
%% @hidden
initDialog(This) -> wxPanel:initDialog(This).
- %% From wxWindow
+ %% From wxWindow
%% @hidden
warpPointer(This,X,Y) -> wxWindow:warpPointer(This,X,Y).
%% @hidden
@@ -462,7 +462,7 @@ center(This) -> wxWindow:center(This).
captureMouse(This) -> wxWindow:captureMouse(This).
%% @hidden
cacheBestSize(This,Size) -> wxWindow:cacheBestSize(This,Size).
- %% From wxEvtHandler
+ %% From wxEvtHandler
%% @hidden
disconnect(This,EventType, Options) -> wxEvtHandler:disconnect(This,EventType, Options).
%% @hidden
diff --git a/lib/wx/src/gen/wxPreviewControlBar.erl b/lib/wx/src/gen/wxPreviewControlBar.erl
index 0118977e9a..78d46d1b95 100644
--- a/lib/wx/src/gen/wxPreviewControlBar.erl
+++ b/lib/wx/src/gen/wxPreviewControlBar.erl
@@ -1,24 +1,24 @@
%%
%% %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%
%% This file is generated DO NOT EDIT
%% @doc See external documentation: <a href="http://www.wxwidgets.org/manuals/stable/wx_wxpreviewcontrolbar.html">wxPreviewControlBar</a>.
-%% <p>This class is derived (and can use functions) from:
+%% <p>This class is derived (and can use functions) from:
%% <br />{@link wxPanel}
%% <br />{@link wxWindow}
%% <br />{@link wxEvtHandler}
@@ -128,14 +128,14 @@ setZoomControl(#wx_ref{type=ThisT,ref=ThisRef},Zoom)
%% @spec (This::wxPreviewControlBar()) -> ok
%% @doc Destroys this object, do not use object again
-destroy(Obj=#wx_ref{type=Type}) ->
+destroy(Obj=#wx_ref{type=Type}) ->
?CLASS(Type,wxPreviewControlBar),
wxe_util:destroy(?DESTROY_OBJECT,Obj),
ok.
- %% From wxPanel
+ %% From wxPanel
%% @hidden
initDialog(This) -> wxPanel:initDialog(This).
- %% From wxWindow
+ %% From wxWindow
%% @hidden
warpPointer(This,X,Y) -> wxWindow:warpPointer(This,X,Y).
%% @hidden
@@ -484,7 +484,7 @@ center(This) -> wxWindow:center(This).
captureMouse(This) -> wxWindow:captureMouse(This).
%% @hidden
cacheBestSize(This,Size) -> wxWindow:cacheBestSize(This,Size).
- %% From wxEvtHandler
+ %% From wxEvtHandler
%% @hidden
disconnect(This,EventType, Options) -> wxEvtHandler:disconnect(This,EventType, Options).
%% @hidden
diff --git a/lib/wx/src/gen/wxPreviewFrame.erl b/lib/wx/src/gen/wxPreviewFrame.erl
index 93dac8dbd9..91a32e9889 100644
--- a/lib/wx/src/gen/wxPreviewFrame.erl
+++ b/lib/wx/src/gen/wxPreviewFrame.erl
@@ -1,24 +1,24 @@
%%
%% %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%
%% This file is generated DO NOT EDIT
%% @doc See external documentation: <a href="http://www.wxwidgets.org/manuals/stable/wx_wxpreviewframe.html">wxPreviewFrame</a>.
-%% <p>This class is derived (and can use functions) from:
+%% <p>This class is derived (and can use functions) from:
%% <br />{@link wxFrame}
%% <br />{@link wxTopLevelWindow}
%% <br />{@link wxWindow}
@@ -141,11 +141,11 @@ onCloseWindow(#wx_ref{type=ThisT,ref=ThisRef},#wx_ref{type=EventT,ref=EventRef})
%% @spec (This::wxPreviewFrame()) -> ok
%% @doc Destroys this object, do not use object again
-destroy(Obj=#wx_ref{type=Type}) ->
+destroy(Obj=#wx_ref{type=Type}) ->
?CLASS(Type,wxPreviewFrame),
wxe_util:destroy(?DESTROY_OBJECT,Obj),
ok.
- %% From wxFrame
+ %% From wxFrame
%% @hidden
setToolBar(This,Toolbar) -> wxFrame:setToolBar(This,Toolbar).
%% @hidden
@@ -182,7 +182,7 @@ createToolBar(This) -> wxFrame:createToolBar(This).
createStatusBar(This, Options) -> wxFrame:createStatusBar(This, Options).
%% @hidden
createStatusBar(This) -> wxFrame:createStatusBar(This).
- %% From wxTopLevelWindow
+ %% From wxTopLevelWindow
%% @hidden
showFullScreen(This,Show, Options) -> wxTopLevelWindow:showFullScreen(This,Show, Options).
%% @hidden
@@ -229,7 +229,7 @@ getTitle(This) -> wxTopLevelWindow:getTitle(This).
getIcons(This) -> wxTopLevelWindow:getIcons(This).
%% @hidden
getIcon(This) -> wxTopLevelWindow:getIcon(This).
- %% From wxWindow
+ %% From wxWindow
%% @hidden
warpPointer(This,X,Y) -> wxWindow:warpPointer(This,X,Y).
%% @hidden
@@ -580,7 +580,7 @@ center(This) -> wxWindow:center(This).
captureMouse(This) -> wxWindow:captureMouse(This).
%% @hidden
cacheBestSize(This,Size) -> wxWindow:cacheBestSize(This,Size).
- %% From wxEvtHandler
+ %% From wxEvtHandler
%% @hidden
disconnect(This,EventType, Options) -> wxEvtHandler:disconnect(This,EventType, Options).
%% @hidden
diff --git a/lib/wx/src/gen/wxPrintData.erl b/lib/wx/src/gen/wxPrintData.erl
index 49fad6b093..f3e8ad3612 100644
--- a/lib/wx/src/gen/wxPrintData.erl
+++ b/lib/wx/src/gen/wxPrintData.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%
%% This file is generated DO NOT EDIT
@@ -201,7 +201,7 @@ setQuality(#wx_ref{type=ThisT,ref=ThisRef},Quality)
%% @spec (This::wxPrintData()) -> ok
%% @doc Destroys this object, do not use object again
-destroy(Obj=#wx_ref{type=Type}) ->
+destroy(Obj=#wx_ref{type=Type}) ->
?CLASS(Type,wxPrintData),
wxe_util:destroy(?DESTROY_OBJECT,Obj),
ok.
diff --git a/lib/wx/src/gen/wxPrintDialog.erl b/lib/wx/src/gen/wxPrintDialog.erl
index 5100e7dcd4..a2f4bfa4eb 100644
--- a/lib/wx/src/gen/wxPrintDialog.erl
+++ b/lib/wx/src/gen/wxPrintDialog.erl
@@ -1,24 +1,24 @@
%%
%% %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%
%% This file is generated DO NOT EDIT
%% @doc See external documentation: <a href="http://www.wxwidgets.org/manuals/stable/wx_wxprintdialog.html">wxPrintDialog</a>.
-%% <p>This class is derived (and can use functions) from:
+%% <p>This class is derived (and can use functions) from:
%% <br />{@link wxDialog}
%% <br />{@link wxTopLevelWindow}
%% <br />{@link wxWindow}
@@ -92,7 +92,7 @@ new(Parent)
%% @spec (Parent::wxWindow:wxWindow(),X::term()) -> wxPrintDialog()
%% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxprintdialog.html#wxprintdialogwxprintdialog">external documentation</a>.
-%% <br /> Alternatives:
+%% <br /> Alternatives:
%% <p><c>
%% new(Parent::wxWindow:wxWindow(), [Option]) -> wxPrintDialog() </c>
%%<br /> Option = {data, wxPrintDialogData:wxPrintDialogData()}
@@ -130,11 +130,11 @@ getPrintDC(#wx_ref{type=ThisT,ref=ThisRef}) ->
%% @spec (This::wxPrintDialog()) -> ok
%% @doc Destroys this object, do not use object again
-destroy(Obj=#wx_ref{type=Type}) ->
+destroy(Obj=#wx_ref{type=Type}) ->
?CLASS(Type,wxPrintDialog),
wxe_util:destroy(?DESTROY_OBJECT,Obj),
ok.
- %% From wxDialog
+ %% From wxDialog
%% @hidden
showModal(This) -> wxDialog:showModal(This).
%% @hidden
@@ -157,7 +157,7 @@ endModal(This,RetCode) -> wxDialog:endModal(This,RetCode).
createStdDialogButtonSizer(This,Flags) -> wxDialog:createStdDialogButtonSizer(This,Flags).
%% @hidden
createButtonSizer(This,Flags) -> wxDialog:createButtonSizer(This,Flags).
- %% From wxTopLevelWindow
+ %% From wxTopLevelWindow
%% @hidden
showFullScreen(This,Show, Options) -> wxTopLevelWindow:showFullScreen(This,Show, Options).
%% @hidden
@@ -204,7 +204,7 @@ getTitle(This) -> wxTopLevelWindow:getTitle(This).
getIcons(This) -> wxTopLevelWindow:getIcons(This).
%% @hidden
getIcon(This) -> wxTopLevelWindow:getIcon(This).
- %% From wxWindow
+ %% From wxWindow
%% @hidden
warpPointer(This,X,Y) -> wxWindow:warpPointer(This,X,Y).
%% @hidden
@@ -551,7 +551,7 @@ center(This) -> wxWindow:center(This).
captureMouse(This) -> wxWindow:captureMouse(This).
%% @hidden
cacheBestSize(This,Size) -> wxWindow:cacheBestSize(This,Size).
- %% From wxEvtHandler
+ %% From wxEvtHandler
%% @hidden
disconnect(This,EventType, Options) -> wxEvtHandler:disconnect(This,EventType, Options).
%% @hidden
diff --git a/lib/wx/src/gen/wxPrintDialogData.erl b/lib/wx/src/gen/wxPrintDialogData.erl
index b4ad5a4a82..a7e8d41f2e 100644
--- a/lib/wx/src/gen/wxPrintDialogData.erl
+++ b/lib/wx/src/gen/wxPrintDialogData.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%
%% This file is generated DO NOT EDIT
@@ -237,7 +237,7 @@ setToPage(#wx_ref{type=ThisT,ref=ThisRef},V)
%% @spec (This::wxPrintDialogData()) -> ok
%% @doc Destroys this object, do not use object again
-destroy(Obj=#wx_ref{type=Type}) ->
+destroy(Obj=#wx_ref{type=Type}) ->
?CLASS(Type,wxPrintDialogData),
wxe_util:destroy(?DESTROY_OBJECT,Obj),
ok.
diff --git a/lib/wx/src/gen/wxPrintPreview.erl b/lib/wx/src/gen/wxPrintPreview.erl
index 8a616c64fb..6f9a0f653f 100644
--- a/lib/wx/src/gen/wxPrintPreview.erl
+++ b/lib/wx/src/gen/wxPrintPreview.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%
%% This file is generated DO NOT EDIT
@@ -186,7 +186,7 @@ setZoom(#wx_ref{type=ThisT,ref=ThisRef},Percent)
%% @spec (This::wxPrintPreview()) -> ok
%% @doc Destroys this object, do not use object again
-destroy(Obj=#wx_ref{type=Type}) ->
+destroy(Obj=#wx_ref{type=Type}) ->
?CLASS(Type,wxPrintPreview),
wxe_util:destroy(?DESTROY_OBJECT,Obj),
ok.
diff --git a/lib/wx/src/gen/wxPrinter.erl b/lib/wx/src/gen/wxPrinter.erl
index d12a1f5909..af9afe18af 100644
--- a/lib/wx/src/gen/wxPrinter.erl
+++ b/lib/wx/src/gen/wxPrinter.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%
%% This file is generated DO NOT EDIT
@@ -129,7 +129,7 @@ setup(#wx_ref{type=ThisT,ref=ThisRef},#wx_ref{type=ParentT,ref=ParentRef}) ->
%% @spec (This::wxPrinter()) -> ok
%% @doc Destroys this object, do not use object again
-destroy(Obj=#wx_ref{type=Type}) ->
+destroy(Obj=#wx_ref{type=Type}) ->
?CLASS(Type,wxPrinter),
wxe_util:destroy(?DESTROY_OBJECT,Obj),
ok.
diff --git a/lib/wx/src/gen/wxPrintout.erl b/lib/wx/src/gen/wxPrintout.erl
index 30811d32a0..b5b93921e6 100644
--- a/lib/wx/src/gen/wxPrintout.erl
+++ b/lib/wx/src/gen/wxPrintout.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%
%% This file is generated DO NOT EDIT
@@ -268,7 +268,7 @@ offsetLogicalOrigin(#wx_ref{type=ThisT,ref=ThisRef},Xoff,Yoff)
%% @spec (This::wxPrintout()) -> ok
%% @doc Destroys this object, do not use object again
-destroy(Obj=#wx_ref{type=Type}) ->
+destroy(Obj=#wx_ref{type=Type}) ->
?CLASS(Type,wxPrintout),
wxe_util:destroy(?DESTROY_OBJECT,Obj),
ok.
diff --git a/lib/wx/src/gen/wxProgressDialog.erl b/lib/wx/src/gen/wxProgressDialog.erl
index 6d7d2d9743..69e73454b5 100644
--- a/lib/wx/src/gen/wxProgressDialog.erl
+++ b/lib/wx/src/gen/wxProgressDialog.erl
@@ -1,24 +1,24 @@
%%
%% %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%
%% This file is generated DO NOT EDIT
%% @doc See external documentation: <a href="http://www.wxwidgets.org/manuals/stable/wx_wxprogressdialog.html">wxProgressDialog</a>.
-%% <p>This class is derived (and can use functions) from:
+%% <p>This class is derived (and can use functions) from:
%% <br />{@link wxDialog}
%% <br />{@link wxTopLevelWindow}
%% <br />{@link wxWindow}
@@ -139,11 +139,11 @@ update(#wx_ref{type=ThisT,ref=ThisRef},Value, Options)
%% @spec (This::wxProgressDialog()) -> ok
%% @doc Destroys this object, do not use object again
-destroy(Obj=#wx_ref{type=Type}) ->
+destroy(Obj=#wx_ref{type=Type}) ->
?CLASS(Type,wxProgressDialog),
wxe_util:destroy(?DESTROY_OBJECT,Obj),
ok.
- %% From wxDialog
+ %% From wxDialog
%% @hidden
showModal(This) -> wxDialog:showModal(This).
%% @hidden
@@ -166,7 +166,7 @@ endModal(This,RetCode) -> wxDialog:endModal(This,RetCode).
createStdDialogButtonSizer(This,Flags) -> wxDialog:createStdDialogButtonSizer(This,Flags).
%% @hidden
createButtonSizer(This,Flags) -> wxDialog:createButtonSizer(This,Flags).
- %% From wxTopLevelWindow
+ %% From wxTopLevelWindow
%% @hidden
showFullScreen(This,Show, Options) -> wxTopLevelWindow:showFullScreen(This,Show, Options).
%% @hidden
@@ -213,7 +213,7 @@ getTitle(This) -> wxTopLevelWindow:getTitle(This).
getIcons(This) -> wxTopLevelWindow:getIcons(This).
%% @hidden
getIcon(This) -> wxTopLevelWindow:getIcon(This).
- %% From wxWindow
+ %% From wxWindow
%% @hidden
warpPointer(This,X,Y) -> wxWindow:warpPointer(This,X,Y).
%% @hidden
@@ -558,7 +558,7 @@ center(This) -> wxWindow:center(This).
captureMouse(This) -> wxWindow:captureMouse(This).
%% @hidden
cacheBestSize(This,Size) -> wxWindow:cacheBestSize(This,Size).
- %% From wxEvtHandler
+ %% From wxEvtHandler
%% @hidden
disconnect(This,EventType, Options) -> wxEvtHandler:disconnect(This,EventType, Options).
%% @hidden
diff --git a/lib/wx/src/gen/wxQueryNewPaletteEvent.erl b/lib/wx/src/gen/wxQueryNewPaletteEvent.erl
index 140d58c42c..96c493e4a6 100644
--- a/lib/wx/src/gen/wxQueryNewPaletteEvent.erl
+++ b/lib/wx/src/gen/wxQueryNewPaletteEvent.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%
%% This file is generated DO NOT EDIT
@@ -22,7 +22,7 @@
%% <dd><em>query_new_palette</em></dd></dl>
%% See also the message variant {@link wxEvtHandler:wxQueryNewPalette(). #wxQueryNewPalette{}} event record type.
%%
-%% <p>This class is derived (and can use functions) from:
+%% <p>This class is derived (and can use functions) from:
%% <br />{@link wxEvent}
%% </p>
%% @type wxQueryNewPaletteEvent(). An object reference, The representation is internal
@@ -56,7 +56,7 @@ getPaletteRealized(#wx_ref{type=ThisT,ref=ThisRef}) ->
wxe_util:call(?wxQueryNewPaletteEvent_GetPaletteRealized,
<<ThisRef:32/?UI>>).
- %% From wxEvent
+ %% From wxEvent
%% @hidden
stopPropagation(This) -> wxEvent:stopPropagation(This).
%% @hidden
diff --git a/lib/wx/src/gen/wxRadioBox.erl b/lib/wx/src/gen/wxRadioBox.erl
index ab76354da2..06e8833972 100644
--- a/lib/wx/src/gen/wxRadioBox.erl
+++ b/lib/wx/src/gen/wxRadioBox.erl
@@ -1,24 +1,24 @@
%%
%% %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%
%% This file is generated DO NOT EDIT
%% @doc See external documentation: <a href="http://www.wxwidgets.org/manuals/stable/wx_wxradiobox.html">wxRadioBox</a>.
-%% <p>This class is derived (and can use functions) from:
+%% <p>This class is derived (and can use functions) from:
%% <br />{@link wxControl}
%% <br />{@link wxWindow}
%% <br />{@link wxEvtHandler}
@@ -133,7 +133,7 @@ enable(This)
%% @spec (This::wxRadioBox(),X::integer()|term()) -> bool()
%% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxradiobox.html#wxradioboxenable">external documentation</a>.
-%% <br /> Alternatives:
+%% <br /> Alternatives:
%% <p><c>
%% enable(This::wxRadioBox(), N::integer()) -> enable(This,N, []) </c></p>
%% <p><c>
@@ -196,7 +196,7 @@ show(This)
%% @spec (This::wxRadioBox(),X::integer()|term()) -> bool()
%% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxradiobox.html#wxradioboxshow">external documentation</a>.
-%% <br /> Alternatives:
+%% <br /> Alternatives:
%% <p><c>
%% show(This::wxRadioBox(), N::integer()) -> show(This,N, []) </c></p>
%% <p><c>
@@ -302,16 +302,16 @@ setItemToolTip(#wx_ref{type=ThisT,ref=ThisRef},Item,Text)
%% @spec (This::wxRadioBox()) -> ok
%% @doc Destroys this object, do not use object again
-destroy(Obj=#wx_ref{type=Type}) ->
+destroy(Obj=#wx_ref{type=Type}) ->
?CLASS(Type,wxRadioBox),
wxe_util:destroy(?DESTROY_OBJECT,Obj),
ok.
- %% From wxControl
+ %% From wxControl
%% @hidden
setLabel(This,Label) -> wxControl:setLabel(This,Label).
%% @hidden
getLabel(This) -> wxControl:getLabel(This).
- %% From wxWindow
+ %% From wxWindow
%% @hidden
warpPointer(This,X,Y) -> wxWindow:warpPointer(This,X,Y).
%% @hidden
@@ -650,7 +650,7 @@ center(This) -> wxWindow:center(This).
captureMouse(This) -> wxWindow:captureMouse(This).
%% @hidden
cacheBestSize(This,Size) -> wxWindow:cacheBestSize(This,Size).
- %% From wxEvtHandler
+ %% From wxEvtHandler
%% @hidden
disconnect(This,EventType, Options) -> wxEvtHandler:disconnect(This,EventType, Options).
%% @hidden
diff --git a/lib/wx/src/gen/wxRadioButton.erl b/lib/wx/src/gen/wxRadioButton.erl
index 066023d121..c2c5a00be6 100644
--- a/lib/wx/src/gen/wxRadioButton.erl
+++ b/lib/wx/src/gen/wxRadioButton.erl
@@ -1,24 +1,24 @@
%%
%% %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%
%% This file is generated DO NOT EDIT
%% @doc See external documentation: <a href="http://www.wxwidgets.org/manuals/stable/wx_wxradiobutton.html">wxRadioButton</a>.
-%% <p>This class is derived (and can use functions) from:
+%% <p>This class is derived (and can use functions) from:
%% <br />{@link wxControl}
%% <br />{@link wxWindow}
%% <br />{@link wxEvtHandler}
@@ -143,16 +143,16 @@ setValue(#wx_ref{type=ThisT,ref=ThisRef},Val)
%% @spec (This::wxRadioButton()) -> ok
%% @doc Destroys this object, do not use object again
-destroy(Obj=#wx_ref{type=Type}) ->
+destroy(Obj=#wx_ref{type=Type}) ->
?CLASS(Type,wxRadioButton),
wxe_util:destroy(?DESTROY_OBJECT,Obj),
ok.
- %% From wxControl
+ %% From wxControl
%% @hidden
setLabel(This,Label) -> wxControl:setLabel(This,Label).
%% @hidden
getLabel(This) -> wxControl:getLabel(This).
- %% From wxWindow
+ %% From wxWindow
%% @hidden
warpPointer(This,X,Y) -> wxWindow:warpPointer(This,X,Y).
%% @hidden
@@ -499,7 +499,7 @@ center(This) -> wxWindow:center(This).
captureMouse(This) -> wxWindow:captureMouse(This).
%% @hidden
cacheBestSize(This,Size) -> wxWindow:cacheBestSize(This,Size).
- %% From wxEvtHandler
+ %% From wxEvtHandler
%% @hidden
disconnect(This,EventType, Options) -> wxEvtHandler:disconnect(This,EventType, Options).
%% @hidden
diff --git a/lib/wx/src/gen/wxRegion.erl b/lib/wx/src/gen/wxRegion.erl
index a2d2c7d830..0ceba1d203 100644
--- a/lib/wx/src/gen/wxRegion.erl
+++ b/lib/wx/src/gen/wxRegion.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%
%% This file is generated DO NOT EDIT
@@ -43,7 +43,7 @@ new() ->
%% @spec (X::term()) -> wxRegion()
%% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxregion.html#wxregionwxregion">external documentation</a>.
-%% <br /> Alternatives:
+%% <br /> Alternatives:
%% <p><c>
%% new(Bmp::wxBitmap:wxBitmap()) -> wxRegion() </c>
%% </p>
@@ -82,7 +82,7 @@ clear(#wx_ref{type=ThisT,ref=ThisRef}) ->
%% @spec (This::wxRegion(),X::term()) -> WxRegionContain
%% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxregion.html#wxregioncontains">external documentation</a>.
-%% <br /> Alternatives:
+%% <br /> Alternatives:
%% <p><c>
%% contains(This::wxRegion(), Pt::{X::integer(),Y::integer()}) -> WxRegionContain </c>
%%<br /> WxRegionContain = integer()
@@ -140,7 +140,7 @@ getBox(#wx_ref{type=ThisT,ref=ThisRef}) ->
%% @spec (This::wxRegion(),X::wxRegion()|term()) -> bool()
%% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxregion.html#wxregionintersect">external documentation</a>.
-%% <br /> Alternatives:
+%% <br /> Alternatives:
%% <p><c>
%% intersect(This::wxRegion(), Region::wxRegion()) -> bool() </c>
%% </p>
@@ -175,7 +175,7 @@ isEmpty(#wx_ref{type=ThisT,ref=ThisRef}) ->
%% @spec (This::wxRegion(),X::wxRegion()|term()) -> bool()
%% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxregion.html#wxregionsubtract">external documentation</a>.
-%% <br /> Alternatives:
+%% <br /> Alternatives:
%% <p><c>
%% subtract(This::wxRegion(), Region::wxRegion()) -> bool() </c>
%% </p>
@@ -219,7 +219,7 @@ offset(#wx_ref{type=ThisT,ref=ThisRef},X,Y)
%% @spec (This::wxRegion(),X::term()) -> bool()
%% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxregion.html#wxregionunion">external documentation</a>.
-%% <br /> Alternatives:
+%% <br /> Alternatives:
%% <p><c>
%% union(This::wxRegion(), Region::wxRegion() | wxBitmap:wxBitmap()) -> bool() </c>
%% </p>
@@ -271,7 +271,7 @@ union(#wx_ref{type=ThisT,ref=ThisRef},X,Y,W,H)
%% @spec (This::wxRegion(),X::wxRegion()|term()) -> bool()
%% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxregion.html#wxregionxor">external documentation</a>.
-%% <br /> Alternatives:
+%% <br /> Alternatives:
%% <p><c>
%% 'Xor'(This::wxRegion(), Region::wxRegion()) -> bool() </c>
%% </p>
@@ -299,7 +299,7 @@ union(#wx_ref{type=ThisT,ref=ThisRef},X,Y,W,H)
%% @spec (This::wxRegion()) -> ok
%% @doc Destroys this object, do not use object again
-destroy(Obj=#wx_ref{type=Type}) ->
+destroy(Obj=#wx_ref{type=Type}) ->
?CLASS(Type,wxRegion),
wxe_util:destroy(?DESTROY_OBJECT,Obj),
ok.
diff --git a/lib/wx/src/gen/wxSashEvent.erl b/lib/wx/src/gen/wxSashEvent.erl
index 56453fbe2f..480e241807 100644
--- a/lib/wx/src/gen/wxSashEvent.erl
+++ b/lib/wx/src/gen/wxSashEvent.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%
%% This file is generated DO NOT EDIT
@@ -22,7 +22,7 @@
%% <dd><em>sash_dragged</em></dd></dl>
%% See also the message variant {@link wxEvtHandler:wxSash(). #wxSash{}} event record type.
%%
-%% <p>This class is derived (and can use functions) from:
+%% <p>This class is derived (and can use functions) from:
%% <br />{@link wxCommandEvent}
%% <br />{@link wxEvent}
%% </p>
@@ -70,7 +70,7 @@ getDragStatus(#wx_ref{type=ThisT,ref=ThisRef}) ->
wxe_util:call(?wxSashEvent_GetDragStatus,
<<ThisRef:32/?UI>>).
- %% From wxCommandEvent
+ %% From wxCommandEvent
%% @hidden
setString(This,S) -> wxCommandEvent:setString(This,S).
%% @hidden
@@ -89,7 +89,7 @@ getInt(This) -> wxCommandEvent:getInt(This).
getExtraLong(This) -> wxCommandEvent:getExtraLong(This).
%% @hidden
getClientData(This) -> wxCommandEvent:getClientData(This).
- %% From wxEvent
+ %% From wxEvent
%% @hidden
stopPropagation(This) -> wxEvent:stopPropagation(This).
%% @hidden
diff --git a/lib/wx/src/gen/wxSashLayoutWindow.erl b/lib/wx/src/gen/wxSashLayoutWindow.erl
index 9b3c372369..9bc5a185ba 100644
--- a/lib/wx/src/gen/wxSashLayoutWindow.erl
+++ b/lib/wx/src/gen/wxSashLayoutWindow.erl
@@ -1,24 +1,24 @@
%%
%% %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%
%% This file is generated DO NOT EDIT
%% @doc See external documentation: <a href="http://www.wxwidgets.org/manuals/stable/wx_wxsashlayoutwindow.html">wxSashLayoutWindow</a>.
-%% <p>This class is derived (and can use functions) from:
+%% <p>This class is derived (and can use functions) from:
%% <br />{@link wxSashWindow}
%% <br />{@link wxWindow}
%% <br />{@link wxEvtHandler}
@@ -177,11 +177,11 @@ setOrientation(#wx_ref{type=ThisT,ref=ThisRef},Orient)
%% @spec (This::wxSashLayoutWindow()) -> ok
%% @doc Destroys this object, do not use object again
-destroy(Obj=#wx_ref{type=Type}) ->
+destroy(Obj=#wx_ref{type=Type}) ->
?CLASS(Type,wxSashLayoutWindow),
wxe_util:destroy(?DESTROY_OBJECT,Obj),
ok.
- %% From wxSashWindow
+ %% From wxSashWindow
%% @hidden
setSashVisible(This,Edge,Sash) -> wxSashWindow:setSashVisible(This,Edge,Sash).
%% @hidden
@@ -202,7 +202,7 @@ getMaximumSizeY(This) -> wxSashWindow:getMaximumSizeY(This).
getMaximumSizeX(This) -> wxSashWindow:getMaximumSizeX(This).
%% @hidden
getSashVisible(This,Edge) -> wxSashWindow:getSashVisible(This,Edge).
- %% From wxWindow
+ %% From wxWindow
%% @hidden
warpPointer(This,X,Y) -> wxWindow:warpPointer(This,X,Y).
%% @hidden
@@ -553,7 +553,7 @@ center(This) -> wxWindow:center(This).
captureMouse(This) -> wxWindow:captureMouse(This).
%% @hidden
cacheBestSize(This,Size) -> wxWindow:cacheBestSize(This,Size).
- %% From wxEvtHandler
+ %% From wxEvtHandler
%% @hidden
disconnect(This,EventType, Options) -> wxEvtHandler:disconnect(This,EventType, Options).
%% @hidden
diff --git a/lib/wx/src/gen/wxSashWindow.erl b/lib/wx/src/gen/wxSashWindow.erl
index d836d84ed3..49fb82f828 100644
--- a/lib/wx/src/gen/wxSashWindow.erl
+++ b/lib/wx/src/gen/wxSashWindow.erl
@@ -1,24 +1,24 @@
%%
%% %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%
%% This file is generated DO NOT EDIT
%% @doc See external documentation: <a href="http://www.wxwidgets.org/manuals/stable/wx_wxsashwindow.html">wxSashWindow</a>.
-%% <p>This class is derived (and can use functions) from:
+%% <p>This class is derived (and can use functions) from:
%% <br />{@link wxWindow}
%% <br />{@link wxEvtHandler}
%% </p>
@@ -184,11 +184,11 @@ setSashVisible(#wx_ref{type=ThisT,ref=ThisRef},Edge,Sash)
%% @spec (This::wxSashWindow()) -> ok
%% @doc Destroys this object, do not use object again
-destroy(Obj=#wx_ref{type=Type}) ->
+destroy(Obj=#wx_ref{type=Type}) ->
?CLASS(Type,wxSashWindow),
wxe_util:destroy(?DESTROY_OBJECT,Obj),
ok.
- %% From wxWindow
+ %% From wxWindow
%% @hidden
warpPointer(This,X,Y) -> wxWindow:warpPointer(This,X,Y).
%% @hidden
@@ -539,7 +539,7 @@ center(This) -> wxWindow:center(This).
captureMouse(This) -> wxWindow:captureMouse(This).
%% @hidden
cacheBestSize(This,Size) -> wxWindow:cacheBestSize(This,Size).
- %% From wxEvtHandler
+ %% From wxEvtHandler
%% @hidden
disconnect(This,EventType, Options) -> wxEvtHandler:disconnect(This,EventType, Options).
%% @hidden
diff --git a/lib/wx/src/gen/wxScreenDC.erl b/lib/wx/src/gen/wxScreenDC.erl
index 35dcb23179..4d7466f4f1 100644
--- a/lib/wx/src/gen/wxScreenDC.erl
+++ b/lib/wx/src/gen/wxScreenDC.erl
@@ -1,24 +1,24 @@
%%
%% %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%
%% This file is generated DO NOT EDIT
%% @doc See external documentation: <a href="http://www.wxwidgets.org/manuals/stable/wx_wxscreendc.html">wxScreenDC</a>.
-%% <p>This class is derived (and can use functions) from:
+%% <p>This class is derived (and can use functions) from:
%% <br />{@link wxDC}
%% </p>
%% @type wxScreenDC(). An object reference, The representation is internal
@@ -64,11 +64,11 @@ new() ->
%% @spec (This::wxScreenDC()) -> ok
%% @doc Destroys this object, do not use object again
-destroy(Obj=#wx_ref{type=Type}) ->
+destroy(Obj=#wx_ref{type=Type}) ->
?CLASS(Type,wxScreenDC),
wxe_util:destroy(?DESTROY_OBJECT,Obj),
ok.
- %% From wxDC
+ %% From wxDC
%% @hidden
startPage(This) -> wxDC:startPage(This).
%% @hidden
diff --git a/lib/wx/src/gen/wxScrollBar.erl b/lib/wx/src/gen/wxScrollBar.erl
index f77b4dde21..41ca8d867f 100644
--- a/lib/wx/src/gen/wxScrollBar.erl
+++ b/lib/wx/src/gen/wxScrollBar.erl
@@ -1,24 +1,24 @@
%%
%% %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%
%% This file is generated DO NOT EDIT
%% @doc See external documentation: <a href="http://www.wxwidgets.org/manuals/stable/wx_wxscrollbar.html">wxScrollBar</a>.
-%% <p>This class is derived (and can use functions) from:
+%% <p>This class is derived (and can use functions) from:
%% <br />{@link wxControl}
%% <br />{@link wxWindow}
%% <br />{@link wxEvtHandler}
@@ -181,16 +181,16 @@ setScrollbar(#wx_ref{type=ThisT,ref=ThisRef},Position,ThumbSize,Range,PageSize,
%% @spec (This::wxScrollBar()) -> ok
%% @doc Destroys this object, do not use object again
-destroy(Obj=#wx_ref{type=Type}) ->
+destroy(Obj=#wx_ref{type=Type}) ->
?CLASS(Type,wxScrollBar),
wxe_util:destroy(?DESTROY_OBJECT,Obj),
ok.
- %% From wxControl
+ %% From wxControl
%% @hidden
setLabel(This,Label) -> wxControl:setLabel(This,Label).
%% @hidden
getLabel(This) -> wxControl:getLabel(This).
- %% From wxWindow
+ %% From wxWindow
%% @hidden
warpPointer(This,X,Y) -> wxWindow:warpPointer(This,X,Y).
%% @hidden
@@ -533,7 +533,7 @@ center(This) -> wxWindow:center(This).
captureMouse(This) -> wxWindow:captureMouse(This).
%% @hidden
cacheBestSize(This,Size) -> wxWindow:cacheBestSize(This,Size).
- %% From wxEvtHandler
+ %% From wxEvtHandler
%% @hidden
disconnect(This,EventType, Options) -> wxEvtHandler:disconnect(This,EventType, Options).
%% @hidden
diff --git a/lib/wx/src/gen/wxScrollEvent.erl b/lib/wx/src/gen/wxScrollEvent.erl
index 52bb5b8347..61b99fa360 100644
--- a/lib/wx/src/gen/wxScrollEvent.erl
+++ b/lib/wx/src/gen/wxScrollEvent.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%
%% This file is generated DO NOT EDIT
@@ -22,7 +22,7 @@
%% <dd><em>scroll_top</em>, <em>scroll_bottom</em>, <em>scroll_lineup</em>, <em>scroll_linedown</em>, <em>scroll_pageup</em>, <em>scroll_pagedown</em>, <em>scroll_thumbtrack</em>, <em>scroll_thumbrelease</em>, <em>scroll_changed</em></dd></dl>
%% See also the message variant {@link wxEvtHandler:wxScroll(). #wxScroll{}} event record type.
%%
-%% <p>This class is derived (and can use functions) from:
+%% <p>This class is derived (and can use functions) from:
%% <br />{@link wxCommandEvent}
%% <br />{@link wxEvent}
%% </p>
@@ -59,7 +59,7 @@ getPosition(#wx_ref{type=ThisT,ref=ThisRef}) ->
wxe_util:call(?wxScrollEvent_GetPosition,
<<ThisRef:32/?UI>>).
- %% From wxCommandEvent
+ %% From wxCommandEvent
%% @hidden
setString(This,S) -> wxCommandEvent:setString(This,S).
%% @hidden
@@ -78,7 +78,7 @@ getInt(This) -> wxCommandEvent:getInt(This).
getExtraLong(This) -> wxCommandEvent:getExtraLong(This).
%% @hidden
getClientData(This) -> wxCommandEvent:getClientData(This).
- %% From wxEvent
+ %% From wxEvent
%% @hidden
stopPropagation(This) -> wxEvent:stopPropagation(This).
%% @hidden
diff --git a/lib/wx/src/gen/wxScrollWinEvent.erl b/lib/wx/src/gen/wxScrollWinEvent.erl
index d87be2c792..6b33b6b564 100644
--- a/lib/wx/src/gen/wxScrollWinEvent.erl
+++ b/lib/wx/src/gen/wxScrollWinEvent.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%
%% This file is generated DO NOT EDIT
@@ -22,7 +22,7 @@
%% <dd><em>scrollwin_top</em>, <em>scrollwin_bottom</em>, <em>scrollwin_lineup</em>, <em>scrollwin_linedown</em>, <em>scrollwin_pageup</em>, <em>scrollwin_pagedown</em>, <em>scrollwin_thumbtrack</em>, <em>scrollwin_thumbrelease</em></dd></dl>
%% See also the message variant {@link wxEvtHandler:wxScrollWin(). #wxScrollWin{}} event record type.
%%
-%% <p>This class is derived (and can use functions) from:
+%% <p>This class is derived (and can use functions) from:
%% <br />{@link wxEvent}
%% </p>
%% @type wxScrollWinEvent(). An object reference, The representation is internal
@@ -55,7 +55,7 @@ getPosition(#wx_ref{type=ThisT,ref=ThisRef}) ->
wxe_util:call(?wxScrollWinEvent_GetPosition,
<<ThisRef:32/?UI>>).
- %% From wxEvent
+ %% From wxEvent
%% @hidden
stopPropagation(This) -> wxEvent:stopPropagation(This).
%% @hidden
diff --git a/lib/wx/src/gen/wxScrolledWindow.erl b/lib/wx/src/gen/wxScrolledWindow.erl
index d3e250fbe1..a6f813d1a2 100644
--- a/lib/wx/src/gen/wxScrolledWindow.erl
+++ b/lib/wx/src/gen/wxScrolledWindow.erl
@@ -1,24 +1,24 @@
%%
%% %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%
%% This file is generated DO NOT EDIT
%% @doc See external documentation: <a href="http://www.wxwidgets.org/manuals/stable/wx_wxscrolledwindow.html">wxScrolledWindow</a>.
-%% <p>This class is derived (and can use functions) from:
+%% <p>This class is derived (and can use functions) from:
%% <br />{@link wxPanel}
%% <br />{@link wxWindow}
%% <br />{@link wxEvtHandler}
@@ -221,14 +221,14 @@ setTargetWindow(#wx_ref{type=ThisT,ref=ThisRef},#wx_ref{type=TargetT,ref=TargetR
%% @spec (This::wxScrolledWindow()) -> ok
%% @doc Destroys this object, do not use object again
-destroy(Obj=#wx_ref{type=Type}) ->
+destroy(Obj=#wx_ref{type=Type}) ->
?CLASS(Type,wxScrolledWindow),
wxe_util:destroy(?DESTROY_OBJECT,Obj),
ok.
- %% From wxPanel
+ %% From wxPanel
%% @hidden
initDialog(This) -> wxPanel:initDialog(This).
- %% From wxWindow
+ %% From wxWindow
%% @hidden
warpPointer(This,X,Y) -> wxWindow:warpPointer(This,X,Y).
%% @hidden
@@ -577,7 +577,7 @@ center(This) -> wxWindow:center(This).
captureMouse(This) -> wxWindow:captureMouse(This).
%% @hidden
cacheBestSize(This,Size) -> wxWindow:cacheBestSize(This,Size).
- %% From wxEvtHandler
+ %% From wxEvtHandler
%% @hidden
disconnect(This,EventType, Options) -> wxEvtHandler:disconnect(This,EventType, Options).
%% @hidden
diff --git a/lib/wx/src/gen/wxSetCursorEvent.erl b/lib/wx/src/gen/wxSetCursorEvent.erl
index 74cc1c1a5a..75a41eb6ad 100644
--- a/lib/wx/src/gen/wxSetCursorEvent.erl
+++ b/lib/wx/src/gen/wxSetCursorEvent.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%
%% This file is generated DO NOT EDIT
@@ -22,7 +22,7 @@
%% <dd><em>set_cursor</em></dd></dl>
%% See also the message variant {@link wxEvtHandler:wxSetCursor(). #wxSetCursor{}} event record type.
%%
-%% <p>This class is derived (and can use functions) from:
+%% <p>This class is derived (and can use functions) from:
%% <br />{@link wxEvent}
%% </p>
%% @type wxSetCursorEvent(). An object reference, The representation is internal
@@ -77,7 +77,7 @@ setCursor(#wx_ref{type=ThisT,ref=ThisRef},#wx_ref{type=CursorT,ref=CursorRef}) -
wxe_util:cast(?wxSetCursorEvent_SetCursor,
<<ThisRef:32/?UI,CursorRef:32/?UI>>).
- %% From wxEvent
+ %% From wxEvent
%% @hidden
stopPropagation(This) -> wxEvent:stopPropagation(This).
%% @hidden
diff --git a/lib/wx/src/gen/wxShowEvent.erl b/lib/wx/src/gen/wxShowEvent.erl
index 173cd4269a..7d5c8300d3 100644
--- a/lib/wx/src/gen/wxShowEvent.erl
+++ b/lib/wx/src/gen/wxShowEvent.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%
%% This file is generated DO NOT EDIT
@@ -22,7 +22,7 @@
%% <dd><em>show</em></dd></dl>
%% See also the message variant {@link wxEvtHandler:wxShow(). #wxShow{}} event record type.
%%
-%% <p>This class is derived (and can use functions) from:
+%% <p>This class is derived (and can use functions) from:
%% <br />{@link wxEvent}
%% </p>
%% @type wxShowEvent(). An object reference, The representation is internal
@@ -56,7 +56,7 @@ getShow(#wx_ref{type=ThisT,ref=ThisRef}) ->
wxe_util:call(?wxShowEvent_GetShow,
<<ThisRef:32/?UI>>).
- %% From wxEvent
+ %% From wxEvent
%% @hidden
stopPropagation(This) -> wxEvent:stopPropagation(This).
%% @hidden
diff --git a/lib/wx/src/gen/wxSingleChoiceDialog.erl b/lib/wx/src/gen/wxSingleChoiceDialog.erl
index 485e7f8be9..16e0c3d8ce 100644
--- a/lib/wx/src/gen/wxSingleChoiceDialog.erl
+++ b/lib/wx/src/gen/wxSingleChoiceDialog.erl
@@ -1,24 +1,24 @@
%%
%% %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%
%% This file is generated DO NOT EDIT
%% @doc See external documentation: <a href="http://www.wxwidgets.org/manuals/stable/wx_wxsinglechoicedialog.html">wxSingleChoiceDialog</a>.
-%% <p>This class is derived (and can use functions) from:
+%% <p>This class is derived (and can use functions) from:
%% <br />{@link wxDialog}
%% <br />{@link wxTopLevelWindow}
%% <br />{@link wxWindow}
@@ -137,11 +137,11 @@ setSelection(#wx_ref{type=ThisT,ref=ThisRef},Sel)
%% @spec (This::wxSingleChoiceDialog()) -> ok
%% @doc Destroys this object, do not use object again
-destroy(Obj=#wx_ref{type=Type}) ->
+destroy(Obj=#wx_ref{type=Type}) ->
?CLASS(Type,wxSingleChoiceDialog),
wxe_util:destroy(?DESTROY_OBJECT,Obj),
ok.
- %% From wxDialog
+ %% From wxDialog
%% @hidden
showModal(This) -> wxDialog:showModal(This).
%% @hidden
@@ -164,7 +164,7 @@ endModal(This,RetCode) -> wxDialog:endModal(This,RetCode).
createStdDialogButtonSizer(This,Flags) -> wxDialog:createStdDialogButtonSizer(This,Flags).
%% @hidden
createButtonSizer(This,Flags) -> wxDialog:createButtonSizer(This,Flags).
- %% From wxTopLevelWindow
+ %% From wxTopLevelWindow
%% @hidden
showFullScreen(This,Show, Options) -> wxTopLevelWindow:showFullScreen(This,Show, Options).
%% @hidden
@@ -211,7 +211,7 @@ getTitle(This) -> wxTopLevelWindow:getTitle(This).
getIcons(This) -> wxTopLevelWindow:getIcons(This).
%% @hidden
getIcon(This) -> wxTopLevelWindow:getIcon(This).
- %% From wxWindow
+ %% From wxWindow
%% @hidden
warpPointer(This,X,Y) -> wxWindow:warpPointer(This,X,Y).
%% @hidden
@@ -558,7 +558,7 @@ center(This) -> wxWindow:center(This).
captureMouse(This) -> wxWindow:captureMouse(This).
%% @hidden
cacheBestSize(This,Size) -> wxWindow:cacheBestSize(This,Size).
- %% From wxEvtHandler
+ %% From wxEvtHandler
%% @hidden
disconnect(This,EventType, Options) -> wxEvtHandler:disconnect(This,EventType, Options).
%% @hidden
diff --git a/lib/wx/src/gen/wxSizeEvent.erl b/lib/wx/src/gen/wxSizeEvent.erl
index e9e337df33..9e7619ebbd 100644
--- a/lib/wx/src/gen/wxSizeEvent.erl
+++ b/lib/wx/src/gen/wxSizeEvent.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%
%% This file is generated DO NOT EDIT
@@ -22,7 +22,7 @@
%% <dd><em>size</em></dd></dl>
%% See also the message variant {@link wxEvtHandler:wxSize(). #wxSize{}} event record type.
%%
-%% <p>This class is derived (and can use functions) from:
+%% <p>This class is derived (and can use functions) from:
%% <br />{@link wxEvent}
%% </p>
%% @type wxSizeEvent(). An object reference, The representation is internal
@@ -48,7 +48,7 @@ getSize(#wx_ref{type=ThisT,ref=ThisRef}) ->
wxe_util:call(?wxSizeEvent_GetSize,
<<ThisRef:32/?UI>>).
- %% From wxEvent
+ %% From wxEvent
%% @hidden
stopPropagation(This) -> wxEvent:stopPropagation(This).
%% @hidden
diff --git a/lib/wx/src/gen/wxSizer.erl b/lib/wx/src/gen/wxSizer.erl
index 4086d34b19..716b2224b5 100644
--- a/lib/wx/src/gen/wxSizer.erl
+++ b/lib/wx/src/gen/wxSizer.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%
%% This file is generated DO NOT EDIT
@@ -47,7 +47,7 @@ add(This,Window)
%% @spec (This::wxSizer(),X::integer()|term(),X::integer()|term()) -> wxSizerItem:wxSizerItem()
%% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxsizer.html#wxsizeradd">external documentation</a>.
-%% <br /> Alternatives:
+%% <br /> Alternatives:
%% <p><c>
%% add(This::wxSizer(), Width::integer(), Height::integer()) -> add(This,Width,Height, []) </c></p>
%% <p><c>
@@ -159,7 +159,7 @@ clear(#wx_ref{type=ThisT,ref=ThisRef}, Options)
%% @spec (This::wxSizer(),X::integer()|term()) -> bool()
%% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxsizer.html#wxsizerdetach">external documentation</a>.
-%% <br /> Alternatives:
+%% <br /> Alternatives:
%% <p><c>
%% detach(This::wxSizer(), Index::integer()) -> bool() </c>
%% </p>
@@ -207,7 +207,7 @@ getChildren(#wx_ref{type=ThisT,ref=ThisRef}) ->
%% @spec (This::wxSizer(),X::term()|integer()) -> wxSizerItem:wxSizerItem()
%% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxsizer.html#wxsizergetitem">external documentation</a>.
-%% <br /> Alternatives:
+%% <br /> Alternatives:
%% <p><c>
%% getItem(This::wxSizer(), Window::wxWindow:wxWindow() | wxSizer()) -> getItem(This,Window, []) </c></p>
%% <p><c>
@@ -264,7 +264,7 @@ getMinSize(#wx_ref{type=ThisT,ref=ThisRef}) ->
%% @spec (This::wxSizer(),X::term()|integer()) -> bool()
%% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxsizer.html#wxsizerhide">external documentation</a>.
-%% <br /> Alternatives:
+%% <br /> Alternatives:
%% <p><c>
%% hide(This::wxSizer(), Window::wxWindow:wxWindow() | wxSizer()) -> hide(This,Window, []) </c></p>
%% <p><c>
@@ -300,7 +300,7 @@ hide(#wx_ref{type=ThisT,ref=ThisRef},#wx_ref{type=WindowT,ref=WindowRef}, Option
%% @spec (This::wxSizer(),Index::integer(),X::term()) -> wxSizerItem:wxSizerItem()
%% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxsizer.html#wxsizerinsert">external documentation</a>.
-%% <br /> Alternatives:
+%% <br /> Alternatives:
%% <p><c>
%% insert(This::wxSizer(), Index::integer(), Window::wxWindow:wxWindow() | wxSizer()) -> insert(This,Index,Window, []) </c></p>
%% <p><c>
@@ -319,7 +319,7 @@ insert(#wx_ref{type=ThisT,ref=ThisRef},Index,#wx_ref{type=ItemT,ref=ItemRef})
%% @spec (This::wxSizer(),Index::integer(),X::integer()|term(),X::integer()|term()) -> wxSizerItem:wxSizerItem()
%% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxsizer.html#wxsizerinsert">external documentation</a>.
-%% <br /> Alternatives:
+%% <br /> Alternatives:
%% <p><c>
%% insert(This::wxSizer(), Index::integer(), Width::integer(), Height::integer()) -> insert(This,Index,Width,Height, []) </c></p>
%% <p><c>
@@ -407,7 +407,7 @@ insertStretchSpacer(#wx_ref{type=ThisT,ref=ThisRef},Index, Options)
%% @spec (This::wxSizer(),X::integer()|term()) -> bool()
%% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxsizer.html#wxsizerisshown">external documentation</a>.
-%% <br /> Alternatives:
+%% <br /> Alternatives:
%% <p><c>
%% isShown(This::wxSizer(), Index::integer()) -> bool() </c>
%% </p>
@@ -439,7 +439,7 @@ layout(#wx_ref{type=ThisT,ref=ThisRef}) ->
%% @spec (This::wxSizer(),X::term()) -> wxSizerItem:wxSizerItem()
%% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxsizer.html#wxsizerprepend">external documentation</a>.
-%% <br /> Alternatives:
+%% <br /> Alternatives:
%% <p><c>
%% prepend(This::wxSizer(), Window::wxWindow:wxWindow() | wxSizer()) -> prepend(This,Window, []) </c></p>
%% <p><c>
@@ -457,7 +457,7 @@ prepend(#wx_ref{type=ThisT,ref=ThisRef},#wx_ref{type=ItemT,ref=ItemRef}) ->
%% @spec (This::wxSizer(),X::integer()|term(),X::integer()|term()) -> wxSizerItem:wxSizerItem()
%% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxsizer.html#wxsizerprepend">external documentation</a>.
-%% <br /> Alternatives:
+%% <br /> Alternatives:
%% <p><c>
%% prepend(This::wxSizer(), Width::integer(), Height::integer()) -> prepend(This,Width,Height, []) </c></p>
%% <p><c>
@@ -551,7 +551,7 @@ recalcSizes(#wx_ref{type=ThisT,ref=ThisRef}) ->
%% @spec (This::wxSizer(),X::integer()|wxSizer()) -> bool()
%% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxsizer.html#wxsizerremove">external documentation</a>.
-%% <br /> Alternatives:
+%% <br /> Alternatives:
%% <p><c>
%% remove(This::wxSizer(), Index::integer()) -> bool() </c>
%% </p>
@@ -571,7 +571,7 @@ remove(#wx_ref{type=ThisT,ref=ThisRef},#wx_ref{type=SizerT,ref=SizerRef}) ->
%% @spec (This::wxSizer(),X::term()|integer(),X::term()) -> bool()
%% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxsizer.html#wxsizerreplace">external documentation</a>.
-%% <br /> Alternatives:
+%% <br /> Alternatives:
%% <p><c>
%% replace(This::wxSizer(), Oldwin::wxWindow:wxWindow() | wxSizer(), Newwin::wxWindow:wxWindow() | wxSizer()) -> replace(This,Oldwin,Newwin, []) </c></p>
%% <p><c>
@@ -634,7 +634,7 @@ setMinSize(#wx_ref{type=ThisT,ref=ThisRef},Width,Height)
%% @spec (This::wxSizer(),X::integer()|term(),Size::{W::integer(),H::integer()}) -> bool()
%% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxsizer.html#wxsizersetitemminsize">external documentation</a>.
-%% <br /> Alternatives:
+%% <br /> Alternatives:
%% <p><c>
%% setItemMinSize(This::wxSizer(), Index::integer(), Size::{W::integer(),H::integer()}) -> bool() </c>
%% </p>
@@ -660,7 +660,7 @@ setItemMinSize(#wx_ref{type=ThisT,ref=ThisRef},#wx_ref{type=WindowT,ref=WindowRe
%% @spec (This::wxSizer(),X::integer()|term(),Width::integer(),Height::integer()) -> bool()
%% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxsizer.html#wxsizersetitemminsize">external documentation</a>.
-%% <br /> Alternatives:
+%% <br /> Alternatives:
%% <p><c>
%% setItemMinSize(This::wxSizer(), Index::integer(), Width::integer(), Height::integer()) -> bool() </c>
%% </p>
@@ -702,7 +702,7 @@ setVirtualSizeHints(#wx_ref{type=ThisT,ref=ThisRef},#wx_ref{type=WindowT,ref=Win
%% @spec (This::wxSizer(),X::integer()|term()|bool()) -> bool()|bool()|ok
%% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxsizer.html#wxsizershow">external documentation</a>.
-%% <br /> Alternatives:
+%% <br /> Alternatives:
%% <p><c>
%% show(This::wxSizer(), Index::integer()) -> show(This,Index, []) </c></p>
%% <p><c>
@@ -726,7 +726,7 @@ show(#wx_ref{type=ThisT,ref=ThisRef},Show)
%% @spec (This::wxSizer(),X::integer()|term(),[Option]) -> bool()
%% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxsizer.html#wxsizershow">external documentation</a>.
-%% <br /> Alternatives:
+%% <br /> Alternatives:
%% <p><c>
%% show(This::wxSizer(), Index::integer(), [Option]) -> bool() </c>
%%<br /> Option = {show, bool()}
diff --git a/lib/wx/src/gen/wxSizerFlags.erl b/lib/wx/src/gen/wxSizerFlags.erl
index 898b2d42ed..2a25fd2c1a 100644
--- a/lib/wx/src/gen/wxSizerFlags.erl
+++ b/lib/wx/src/gen/wxSizerFlags.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%
%% This file is generated DO NOT EDIT
@@ -128,7 +128,7 @@ right(#wx_ref{type=ThisT,ref=ThisRef}) ->
%% @spec (This::wxSizerFlags()) -> ok
%% @doc Destroys this object, do not use object again
-destroy(Obj=#wx_ref{type=Type}) ->
+destroy(Obj=#wx_ref{type=Type}) ->
?CLASS(Type,wxSizerFlags),
wxe_util:destroy(?wxSizerFlags_destroy,Obj),
ok.
diff --git a/lib/wx/src/gen/wxSizerItem.erl b/lib/wx/src/gen/wxSizerItem.erl
index e8391d859a..1e9f05d53c 100644
--- a/lib/wx/src/gen/wxSizerItem.erl
+++ b/lib/wx/src/gen/wxSizerItem.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%
%% This file is generated DO NOT EDIT
@@ -280,7 +280,7 @@ setProportion(#wx_ref{type=ThisT,ref=ThisRef},Proportion)
%% @spec (This::wxSizerItem(),X::float()|term()) -> ok
%% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxsizeritem.html#wxsizeritemsetratio">external documentation</a>.
-%% <br /> Alternatives:
+%% <br /> Alternatives:
%% <p><c>
%% setRatio(This::wxSizerItem(), Ratio::float()) -> ok </c>
%% </p>
@@ -348,7 +348,7 @@ show(#wx_ref{type=ThisT,ref=ThisRef},Show)
%% @spec (This::wxSizerItem()) -> ok
%% @doc Destroys this object, do not use object again
-destroy(Obj=#wx_ref{type=Type}) ->
+destroy(Obj=#wx_ref{type=Type}) ->
?CLASS(Type,wxSizerItem),
wxe_util:destroy(?DESTROY_OBJECT,Obj),
ok.
diff --git a/lib/wx/src/gen/wxSlider.erl b/lib/wx/src/gen/wxSlider.erl
index 694630859b..c70f127a5b 100644
--- a/lib/wx/src/gen/wxSlider.erl
+++ b/lib/wx/src/gen/wxSlider.erl
@@ -1,24 +1,24 @@
%%
%% %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%
%% This file is generated DO NOT EDIT
%% @doc See external documentation: <a href="http://www.wxwidgets.org/manuals/stable/wx_wxslider.html">wxSlider</a>.
-%% <p>This class is derived (and can use functions) from:
+%% <p>This class is derived (and can use functions) from:
%% <br />{@link wxControl}
%% <br />{@link wxWindow}
%% <br />{@link wxEvtHandler}
@@ -210,16 +210,16 @@ setValue(#wx_ref{type=ThisT,ref=ThisRef},Value)
%% @spec (This::wxSlider()) -> ok
%% @doc Destroys this object, do not use object again
-destroy(Obj=#wx_ref{type=Type}) ->
+destroy(Obj=#wx_ref{type=Type}) ->
?CLASS(Type,wxSlider),
wxe_util:destroy(?DESTROY_OBJECT,Obj),
ok.
- %% From wxControl
+ %% From wxControl
%% @hidden
setLabel(This,Label) -> wxControl:setLabel(This,Label).
%% @hidden
getLabel(This) -> wxControl:getLabel(This).
- %% From wxWindow
+ %% From wxWindow
%% @hidden
warpPointer(This,X,Y) -> wxWindow:warpPointer(This,X,Y).
%% @hidden
@@ -566,7 +566,7 @@ center(This) -> wxWindow:center(This).
captureMouse(This) -> wxWindow:captureMouse(This).
%% @hidden
cacheBestSize(This,Size) -> wxWindow:cacheBestSize(This,Size).
- %% From wxEvtHandler
+ %% From wxEvtHandler
%% @hidden
disconnect(This,EventType, Options) -> wxEvtHandler:disconnect(This,EventType, Options).
%% @hidden
diff --git a/lib/wx/src/gen/wxSpinButton.erl b/lib/wx/src/gen/wxSpinButton.erl
index 1cc59ec6aa..027699e295 100644
--- a/lib/wx/src/gen/wxSpinButton.erl
+++ b/lib/wx/src/gen/wxSpinButton.erl
@@ -1,24 +1,24 @@
%%
%% %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%
%% This file is generated DO NOT EDIT
%% @doc See external documentation: <a href="http://www.wxwidgets.org/manuals/stable/wx_wxspinbutton.html">wxSpinButton</a>.
-%% <p>This class is derived (and can use functions) from:
+%% <p>This class is derived (and can use functions) from:
%% <br />{@link wxControl}
%% <br />{@link wxWindow}
%% <br />{@link wxEvtHandler}
@@ -164,16 +164,16 @@ setValue(#wx_ref{type=ThisT,ref=ThisRef},Value)
%% @spec (This::wxSpinButton()) -> ok
%% @doc Destroys this object, do not use object again
-destroy(Obj=#wx_ref{type=Type}) ->
+destroy(Obj=#wx_ref{type=Type}) ->
?CLASS(Type,wxSpinButton),
wxe_util:destroy(?DESTROY_OBJECT,Obj),
ok.
- %% From wxControl
+ %% From wxControl
%% @hidden
setLabel(This,Label) -> wxControl:setLabel(This,Label).
%% @hidden
getLabel(This) -> wxControl:getLabel(This).
- %% From wxWindow
+ %% From wxWindow
%% @hidden
warpPointer(This,X,Y) -> wxWindow:warpPointer(This,X,Y).
%% @hidden
@@ -520,7 +520,7 @@ center(This) -> wxWindow:center(This).
captureMouse(This) -> wxWindow:captureMouse(This).
%% @hidden
cacheBestSize(This,Size) -> wxWindow:cacheBestSize(This,Size).
- %% From wxEvtHandler
+ %% From wxEvtHandler
%% @hidden
disconnect(This,EventType, Options) -> wxEvtHandler:disconnect(This,EventType, Options).
%% @hidden
diff --git a/lib/wx/src/gen/wxSpinCtrl.erl b/lib/wx/src/gen/wxSpinCtrl.erl
index bed2d733a3..6b77376b40 100644
--- a/lib/wx/src/gen/wxSpinCtrl.erl
+++ b/lib/wx/src/gen/wxSpinCtrl.erl
@@ -1,24 +1,24 @@
%%
%% %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%
%% This file is generated DO NOT EDIT
%% @doc See external documentation: <a href="http://www.wxwidgets.org/manuals/stable/wx_wxspinctrl.html">wxSpinCtrl</a>.
-%% <p>This class is derived (and can use functions) from:
+%% <p>This class is derived (and can use functions) from:
%% <br />{@link wxControl}
%% <br />{@link wxWindow}
%% <br />{@link wxEvtHandler}
@@ -135,7 +135,7 @@ create(#wx_ref{type=ThisT,ref=ThisRef},#wx_ref{type=ParentT,ref=ParentRef}, Opti
%% @spec (This::wxSpinCtrl(),X::integer()|string()) -> ok
%% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxspinctrl.html#wxspinctrlsetvalue">external documentation</a>.
-%% <br /> Alternatives:
+%% <br /> Alternatives:
%% <p><c>
%% setValue(This::wxSpinCtrl(), Value::integer()) -> ok </c>
%% </p>
@@ -193,16 +193,16 @@ getMax(#wx_ref{type=ThisT,ref=ThisRef}) ->
%% @spec (This::wxSpinCtrl()) -> ok
%% @doc Destroys this object, do not use object again
-destroy(Obj=#wx_ref{type=Type}) ->
+destroy(Obj=#wx_ref{type=Type}) ->
?CLASS(Type,wxSpinCtrl),
wxe_util:destroy(?DESTROY_OBJECT,Obj),
ok.
- %% From wxControl
+ %% From wxControl
%% @hidden
setLabel(This,Label) -> wxControl:setLabel(This,Label).
%% @hidden
getLabel(This) -> wxControl:getLabel(This).
- %% From wxWindow
+ %% From wxWindow
%% @hidden
warpPointer(This,X,Y) -> wxWindow:warpPointer(This,X,Y).
%% @hidden
@@ -549,7 +549,7 @@ center(This) -> wxWindow:center(This).
captureMouse(This) -> wxWindow:captureMouse(This).
%% @hidden
cacheBestSize(This,Size) -> wxWindow:cacheBestSize(This,Size).
- %% From wxEvtHandler
+ %% From wxEvtHandler
%% @hidden
disconnect(This,EventType, Options) -> wxEvtHandler:disconnect(This,EventType, Options).
%% @hidden
diff --git a/lib/wx/src/gen/wxSpinEvent.erl b/lib/wx/src/gen/wxSpinEvent.erl
index 2c44b3c2a3..82edc70983 100644
--- a/lib/wx/src/gen/wxSpinEvent.erl
+++ b/lib/wx/src/gen/wxSpinEvent.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%
%% This file is generated DO NOT EDIT
@@ -22,7 +22,7 @@
%% <dd><em>command_spinctrl_updated</em>, <em>spin_up</em>, <em>spin_down</em>, <em>spin</em></dd></dl>
%% See also the message variant {@link wxEvtHandler:wxSpin(). #wxSpin{}} event record type.
%%
-%% <p>This class is derived (and can use functions) from:
+%% <p>This class is derived (and can use functions) from:
%% <br />{@link wxNotifyEvent}
%% <br />{@link wxCommandEvent}
%% <br />{@link wxEvent}
@@ -62,14 +62,14 @@ setPosition(#wx_ref{type=ThisT,ref=ThisRef},Pos)
wxe_util:cast(?wxSpinEvent_SetPosition,
<<ThisRef:32/?UI,Pos:32/?UI>>).
- %% From wxNotifyEvent
+ %% From wxNotifyEvent
%% @hidden
veto(This) -> wxNotifyEvent:veto(This).
%% @hidden
isAllowed(This) -> wxNotifyEvent:isAllowed(This).
%% @hidden
allow(This) -> wxNotifyEvent:allow(This).
- %% From wxCommandEvent
+ %% From wxCommandEvent
%% @hidden
setString(This,S) -> wxCommandEvent:setString(This,S).
%% @hidden
@@ -88,7 +88,7 @@ getInt(This) -> wxCommandEvent:getInt(This).
getExtraLong(This) -> wxCommandEvent:getExtraLong(This).
%% @hidden
getClientData(This) -> wxCommandEvent:getClientData(This).
- %% From wxEvent
+ %% From wxEvent
%% @hidden
stopPropagation(This) -> wxEvent:stopPropagation(This).
%% @hidden
diff --git a/lib/wx/src/gen/wxSplashScreen.erl b/lib/wx/src/gen/wxSplashScreen.erl
index 8fe543c4e8..8806d07018 100644
--- a/lib/wx/src/gen/wxSplashScreen.erl
+++ b/lib/wx/src/gen/wxSplashScreen.erl
@@ -1,24 +1,24 @@
%%
%% %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%
%% This file is generated DO NOT EDIT
%% @doc See external documentation: <a href="http://www.wxwidgets.org/manuals/stable/wx_wxsplashscreen.html">wxSplashScreen</a>.
-%% <p>This class is derived (and can use functions) from:
+%% <p>This class is derived (and can use functions) from:
%% <br />{@link wxFrame}
%% <br />{@link wxTopLevelWindow}
%% <br />{@link wxWindow}
@@ -130,11 +130,11 @@ getTimeout(#wx_ref{type=ThisT,ref=ThisRef}) ->
%% @spec (This::wxSplashScreen()) -> ok
%% @doc Destroys this object, do not use object again
-destroy(Obj=#wx_ref{type=Type}) ->
+destroy(Obj=#wx_ref{type=Type}) ->
?CLASS(Type,wxSplashScreen),
wxe_util:destroy(?DESTROY_OBJECT,Obj),
ok.
- %% From wxFrame
+ %% From wxFrame
%% @hidden
setToolBar(This,Toolbar) -> wxFrame:setToolBar(This,Toolbar).
%% @hidden
@@ -171,7 +171,7 @@ createToolBar(This) -> wxFrame:createToolBar(This).
createStatusBar(This, Options) -> wxFrame:createStatusBar(This, Options).
%% @hidden
createStatusBar(This) -> wxFrame:createStatusBar(This).
- %% From wxTopLevelWindow
+ %% From wxTopLevelWindow
%% @hidden
showFullScreen(This,Show, Options) -> wxTopLevelWindow:showFullScreen(This,Show, Options).
%% @hidden
@@ -218,7 +218,7 @@ getTitle(This) -> wxTopLevelWindow:getTitle(This).
getIcons(This) -> wxTopLevelWindow:getIcons(This).
%% @hidden
getIcon(This) -> wxTopLevelWindow:getIcon(This).
- %% From wxWindow
+ %% From wxWindow
%% @hidden
warpPointer(This,X,Y) -> wxWindow:warpPointer(This,X,Y).
%% @hidden
@@ -569,7 +569,7 @@ center(This) -> wxWindow:center(This).
captureMouse(This) -> wxWindow:captureMouse(This).
%% @hidden
cacheBestSize(This,Size) -> wxWindow:cacheBestSize(This,Size).
- %% From wxEvtHandler
+ %% From wxEvtHandler
%% @hidden
disconnect(This,EventType, Options) -> wxEvtHandler:disconnect(This,EventType, Options).
%% @hidden
diff --git a/lib/wx/src/gen/wxSplitterEvent.erl b/lib/wx/src/gen/wxSplitterEvent.erl
index a3a8171742..512f858284 100644
--- a/lib/wx/src/gen/wxSplitterEvent.erl
+++ b/lib/wx/src/gen/wxSplitterEvent.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%
%% This file is generated DO NOT EDIT
@@ -22,7 +22,7 @@
%% <dd><em>command_splitter_sash_pos_changed</em>, <em>command_splitter_sash_pos_changing</em>, <em>command_splitter_doubleclicked</em>, <em>command_splitter_unsplit</em></dd></dl>
%% See also the message variant {@link wxEvtHandler:wxSplitter(). #wxSplitter{}} event record type.
%%
-%% <p>This class is derived (and can use functions) from:
+%% <p>This class is derived (and can use functions) from:
%% <br />{@link wxNotifyEvent}
%% <br />{@link wxCommandEvent}
%% <br />{@link wxEvent}
@@ -83,14 +83,14 @@ setSashPosition(#wx_ref{type=ThisT,ref=ThisRef},Pos)
wxe_util:cast(?wxSplitterEvent_SetSashPosition,
<<ThisRef:32/?UI,Pos:32/?UI>>).
- %% From wxNotifyEvent
+ %% From wxNotifyEvent
%% @hidden
veto(This) -> wxNotifyEvent:veto(This).
%% @hidden
isAllowed(This) -> wxNotifyEvent:isAllowed(This).
%% @hidden
allow(This) -> wxNotifyEvent:allow(This).
- %% From wxCommandEvent
+ %% From wxCommandEvent
%% @hidden
setString(This,S) -> wxCommandEvent:setString(This,S).
%% @hidden
@@ -109,7 +109,7 @@ getInt(This) -> wxCommandEvent:getInt(This).
getExtraLong(This) -> wxCommandEvent:getExtraLong(This).
%% @hidden
getClientData(This) -> wxCommandEvent:getClientData(This).
- %% From wxEvent
+ %% From wxEvent
%% @hidden
stopPropagation(This) -> wxEvent:stopPropagation(This).
%% @hidden
diff --git a/lib/wx/src/gen/wxSplitterWindow.erl b/lib/wx/src/gen/wxSplitterWindow.erl
index 6522858266..9e27be7475 100644
--- a/lib/wx/src/gen/wxSplitterWindow.erl
+++ b/lib/wx/src/gen/wxSplitterWindow.erl
@@ -1,24 +1,24 @@
%%
%% %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%
%% This file is generated DO NOT EDIT
%% @doc See external documentation: <a href="http://www.wxwidgets.org/manuals/stable/wx_wxsplitterwindow.html">wxSplitterWindow</a>.
-%% <p>This class is derived (and can use functions) from:
+%% <p>This class is derived (and can use functions) from:
%% <br />{@link wxWindow}
%% <br />{@link wxEvtHandler}
%% </p>
@@ -312,11 +312,11 @@ updateSize(#wx_ref{type=ThisT,ref=ThisRef}) ->
%% @spec (This::wxSplitterWindow()) -> ok
%% @doc Destroys this object, do not use object again
-destroy(Obj=#wx_ref{type=Type}) ->
+destroy(Obj=#wx_ref{type=Type}) ->
?CLASS(Type,wxSplitterWindow),
wxe_util:destroy(?DESTROY_OBJECT,Obj),
ok.
- %% From wxWindow
+ %% From wxWindow
%% @hidden
warpPointer(This,X,Y) -> wxWindow:warpPointer(This,X,Y).
%% @hidden
@@ -667,7 +667,7 @@ center(This) -> wxWindow:center(This).
captureMouse(This) -> wxWindow:captureMouse(This).
%% @hidden
cacheBestSize(This,Size) -> wxWindow:cacheBestSize(This,Size).
- %% From wxEvtHandler
+ %% From wxEvtHandler
%% @hidden
disconnect(This,EventType, Options) -> wxEvtHandler:disconnect(This,EventType, Options).
%% @hidden
diff --git a/lib/wx/src/gen/wxStaticBitmap.erl b/lib/wx/src/gen/wxStaticBitmap.erl
index 5f22b5780e..6fbc59236d 100644
--- a/lib/wx/src/gen/wxStaticBitmap.erl
+++ b/lib/wx/src/gen/wxStaticBitmap.erl
@@ -1,24 +1,24 @@
%%
%% %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%
%% This file is generated DO NOT EDIT
%% @doc See external documentation: <a href="http://www.wxwidgets.org/manuals/stable/wx_wxstaticbitmap.html">wxStaticBitmap</a>.
-%% <p>This class is derived (and can use functions) from:
+%% <p>This class is derived (and can use functions) from:
%% <br />{@link wxControl}
%% <br />{@link wxWindow}
%% <br />{@link wxEvtHandler}
@@ -141,16 +141,16 @@ setBitmap(#wx_ref{type=ThisT,ref=ThisRef},#wx_ref{type=BitmapT,ref=BitmapRef}) -
%% @spec (This::wxStaticBitmap()) -> ok
%% @doc Destroys this object, do not use object again
-destroy(Obj=#wx_ref{type=Type}) ->
+destroy(Obj=#wx_ref{type=Type}) ->
?CLASS(Type,wxStaticBitmap),
wxe_util:destroy(?DESTROY_OBJECT,Obj),
ok.
- %% From wxControl
+ %% From wxControl
%% @hidden
setLabel(This,Label) -> wxControl:setLabel(This,Label).
%% @hidden
getLabel(This) -> wxControl:getLabel(This).
- %% From wxWindow
+ %% From wxWindow
%% @hidden
warpPointer(This,X,Y) -> wxWindow:warpPointer(This,X,Y).
%% @hidden
@@ -497,7 +497,7 @@ center(This) -> wxWindow:center(This).
captureMouse(This) -> wxWindow:captureMouse(This).
%% @hidden
cacheBestSize(This,Size) -> wxWindow:cacheBestSize(This,Size).
- %% From wxEvtHandler
+ %% From wxEvtHandler
%% @hidden
disconnect(This,EventType, Options) -> wxEvtHandler:disconnect(This,EventType, Options).
%% @hidden
diff --git a/lib/wx/src/gen/wxStaticBox.erl b/lib/wx/src/gen/wxStaticBox.erl
index 08e8fd8c0c..ad54184867 100644
--- a/lib/wx/src/gen/wxStaticBox.erl
+++ b/lib/wx/src/gen/wxStaticBox.erl
@@ -1,24 +1,24 @@
%%
%% %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%
%% This file is generated DO NOT EDIT
%% @doc See external documentation: <a href="http://www.wxwidgets.org/manuals/stable/wx_wxstaticbox.html">wxStaticBox</a>.
-%% <p>This class is derived (and can use functions) from:
+%% <p>This class is derived (and can use functions) from:
%% <br />{@link wxControl}
%% <br />{@link wxWindow}
%% <br />{@link wxEvtHandler}
@@ -126,16 +126,16 @@ create(#wx_ref{type=ThisT,ref=ThisRef},#wx_ref{type=ParentT,ref=ParentRef},Id,La
%% @spec (This::wxStaticBox()) -> ok
%% @doc Destroys this object, do not use object again
-destroy(Obj=#wx_ref{type=Type}) ->
+destroy(Obj=#wx_ref{type=Type}) ->
?CLASS(Type,wxStaticBox),
wxe_util:destroy(?DESTROY_OBJECT,Obj),
ok.
- %% From wxControl
+ %% From wxControl
%% @hidden
setLabel(This,Label) -> wxControl:setLabel(This,Label).
%% @hidden
getLabel(This) -> wxControl:getLabel(This).
- %% From wxWindow
+ %% From wxWindow
%% @hidden
warpPointer(This,X,Y) -> wxWindow:warpPointer(This,X,Y).
%% @hidden
@@ -482,7 +482,7 @@ center(This) -> wxWindow:center(This).
captureMouse(This) -> wxWindow:captureMouse(This).
%% @hidden
cacheBestSize(This,Size) -> wxWindow:cacheBestSize(This,Size).
- %% From wxEvtHandler
+ %% From wxEvtHandler
%% @hidden
disconnect(This,EventType, Options) -> wxEvtHandler:disconnect(This,EventType, Options).
%% @hidden
diff --git a/lib/wx/src/gen/wxStaticBoxSizer.erl b/lib/wx/src/gen/wxStaticBoxSizer.erl
index d097bc95e3..5f346b7a1e 100644
--- a/lib/wx/src/gen/wxStaticBoxSizer.erl
+++ b/lib/wx/src/gen/wxStaticBoxSizer.erl
@@ -1,24 +1,24 @@
%%
%% %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%
%% This file is generated DO NOT EDIT
%% @doc See external documentation: <a href="http://www.wxwidgets.org/manuals/stable/wx_wxstaticboxsizer.html">wxStaticBoxSizer</a>.
-%% <p>This class is derived (and can use functions) from:
+%% <p>This class is derived (and can use functions) from:
%% <br />{@link wxBoxSizer}
%% <br />{@link wxSizer}
%% </p>
@@ -48,7 +48,7 @@ parent_class(_Class) -> erlang:error({badtype, ?MODULE}).
%% @spec (X::integer()|term(),X::term()|integer()) -> wxStaticBoxSizer()
%% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxstaticboxsizer.html#wxstaticboxsizerwxstaticboxsizer">external documentation</a>.
-%% <br /> Alternatives:
+%% <br /> Alternatives:
%% <p><c>
%% new(Orient::integer(), Win::wxWindow:wxWindow()) -> new(Orient,Win, []) </c></p>
%% <p><c>
@@ -85,14 +85,14 @@ getStaticBox(#wx_ref{type=ThisT,ref=ThisRef}) ->
%% @spec (This::wxStaticBoxSizer()) -> ok
%% @doc Destroys this object, do not use object again
-destroy(Obj=#wx_ref{type=Type}) ->
+destroy(Obj=#wx_ref{type=Type}) ->
?CLASS(Type,wxStaticBoxSizer),
wxe_util:destroy(?DESTROY_OBJECT,Obj),
ok.
- %% From wxBoxSizer
+ %% From wxBoxSizer
%% @hidden
getOrientation(This) -> wxBoxSizer:getOrientation(This).
- %% From wxSizer
+ %% From wxSizer
%% @hidden
show(This,Index, Options) -> wxSizer:show(This,Index, Options).
%% @hidden
diff --git a/lib/wx/src/gen/wxStaticLine.erl b/lib/wx/src/gen/wxStaticLine.erl
index c4b660b317..e3a1bedbdc 100644
--- a/lib/wx/src/gen/wxStaticLine.erl
+++ b/lib/wx/src/gen/wxStaticLine.erl
@@ -1,24 +1,24 @@
%%
%% %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%
%% This file is generated DO NOT EDIT
%% @doc See external documentation: <a href="http://www.wxwidgets.org/manuals/stable/wx_wxstaticline.html">wxStaticLine</a>.
-%% <p>This class is derived (and can use functions) from:
+%% <p>This class is derived (and can use functions) from:
%% <br />{@link wxControl}
%% <br />{@link wxWindow}
%% <br />{@link wxEvtHandler}
@@ -140,16 +140,16 @@ getDefaultSize() ->
%% @spec (This::wxStaticLine()) -> ok
%% @doc Destroys this object, do not use object again
-destroy(Obj=#wx_ref{type=Type}) ->
+destroy(Obj=#wx_ref{type=Type}) ->
?CLASS(Type,wxStaticLine),
wxe_util:destroy(?DESTROY_OBJECT,Obj),
ok.
- %% From wxControl
+ %% From wxControl
%% @hidden
setLabel(This,Label) -> wxControl:setLabel(This,Label).
%% @hidden
getLabel(This) -> wxControl:getLabel(This).
- %% From wxWindow
+ %% From wxWindow
%% @hidden
warpPointer(This,X,Y) -> wxWindow:warpPointer(This,X,Y).
%% @hidden
@@ -496,7 +496,7 @@ center(This) -> wxWindow:center(This).
captureMouse(This) -> wxWindow:captureMouse(This).
%% @hidden
cacheBestSize(This,Size) -> wxWindow:cacheBestSize(This,Size).
- %% From wxEvtHandler
+ %% From wxEvtHandler
%% @hidden
disconnect(This,EventType, Options) -> wxEvtHandler:disconnect(This,EventType, Options).
%% @hidden
diff --git a/lib/wx/src/gen/wxStaticText.erl b/lib/wx/src/gen/wxStaticText.erl
index 0e4aec3365..46c73a5998 100644
--- a/lib/wx/src/gen/wxStaticText.erl
+++ b/lib/wx/src/gen/wxStaticText.erl
@@ -1,24 +1,24 @@
%%
%% %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%
%% This file is generated DO NOT EDIT
%% @doc See external documentation: <a href="http://www.wxwidgets.org/manuals/stable/wx_wxstatictext.html">wxStaticText</a>.
-%% <p>This class is derived (and can use functions) from:
+%% <p>This class is derived (and can use functions) from:
%% <br />{@link wxControl}
%% <br />{@link wxWindow}
%% <br />{@link wxEvtHandler}
@@ -150,12 +150,12 @@ wrap(#wx_ref{type=ThisT,ref=ThisRef},Width)
%% @spec (This::wxStaticText()) -> ok
%% @doc Destroys this object, do not use object again
-destroy(Obj=#wx_ref{type=Type}) ->
+destroy(Obj=#wx_ref{type=Type}) ->
?CLASS(Type,wxStaticText),
wxe_util:destroy(?DESTROY_OBJECT,Obj),
ok.
- %% From wxControl
- %% From wxWindow
+ %% From wxControl
+ %% From wxWindow
%% @hidden
warpPointer(This,X,Y) -> wxWindow:warpPointer(This,X,Y).
%% @hidden
@@ -502,7 +502,7 @@ center(This) -> wxWindow:center(This).
captureMouse(This) -> wxWindow:captureMouse(This).
%% @hidden
cacheBestSize(This,Size) -> wxWindow:cacheBestSize(This,Size).
- %% From wxEvtHandler
+ %% From wxEvtHandler
%% @hidden
disconnect(This,EventType, Options) -> wxEvtHandler:disconnect(This,EventType, Options).
%% @hidden
diff --git a/lib/wx/src/gen/wxStatusBar.erl b/lib/wx/src/gen/wxStatusBar.erl
index c77c3c447d..52467117d7 100644
--- a/lib/wx/src/gen/wxStatusBar.erl
+++ b/lib/wx/src/gen/wxStatusBar.erl
@@ -1,24 +1,24 @@
%%
%% %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%
%% This file is generated DO NOT EDIT
%% @doc See external documentation: <a href="http://www.wxwidgets.org/manuals/stable/wx_wxstatusbar.html">wxStatusBar</a>.
-%% <p>This class is derived (and can use functions) from:
+%% <p>This class is derived (and can use functions) from:
%% <br />{@link wxWindow}
%% <br />{@link wxEvtHandler}
%% </p>
@@ -257,11 +257,11 @@ setStatusStyles(#wx_ref{type=ThisT,ref=ThisRef},Styles)
%% @spec (This::wxStatusBar()) -> ok
%% @doc Destroys this object, do not use object again
-destroy(Obj=#wx_ref{type=Type}) ->
+destroy(Obj=#wx_ref{type=Type}) ->
?CLASS(Type,wxStatusBar),
wxe_util:destroy(?DESTROY_OBJECT,Obj),
ok.
- %% From wxWindow
+ %% From wxWindow
%% @hidden
warpPointer(This,X,Y) -> wxWindow:warpPointer(This,X,Y).
%% @hidden
@@ -612,7 +612,7 @@ center(This) -> wxWindow:center(This).
captureMouse(This) -> wxWindow:captureMouse(This).
%% @hidden
cacheBestSize(This,Size) -> wxWindow:cacheBestSize(This,Size).
- %% From wxEvtHandler
+ %% From wxEvtHandler
%% @hidden
disconnect(This,EventType, Options) -> wxEvtHandler:disconnect(This,EventType, Options).
%% @hidden
diff --git a/lib/wx/src/gen/wxStdDialogButtonSizer.erl b/lib/wx/src/gen/wxStdDialogButtonSizer.erl
index 3ee3ef4a36..b0052ca2e1 100644
--- a/lib/wx/src/gen/wxStdDialogButtonSizer.erl
+++ b/lib/wx/src/gen/wxStdDialogButtonSizer.erl
@@ -1,24 +1,24 @@
%%
%% %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%
%% This file is generated DO NOT EDIT
%% @doc See external documentation: <a href="http://www.wxwidgets.org/manuals/stable/wx_wxstddialogbuttonsizer.html">wxStdDialogButtonSizer</a>.
-%% <p>This class is derived (and can use functions) from:
+%% <p>This class is derived (and can use functions) from:
%% <br />{@link wxBoxSizer}
%% <br />{@link wxSizer}
%% </p>
@@ -94,14 +94,14 @@ setNegativeButton(#wx_ref{type=ThisT,ref=ThisRef},#wx_ref{type=ButtonT,ref=Butto
%% @spec (This::wxStdDialogButtonSizer()) -> ok
%% @doc Destroys this object, do not use object again
-destroy(Obj=#wx_ref{type=Type}) ->
+destroy(Obj=#wx_ref{type=Type}) ->
?CLASS(Type,wxStdDialogButtonSizer),
wxe_util:destroy(?DESTROY_OBJECT,Obj),
ok.
- %% From wxBoxSizer
+ %% From wxBoxSizer
%% @hidden
getOrientation(This) -> wxBoxSizer:getOrientation(This).
- %% From wxSizer
+ %% From wxSizer
%% @hidden
show(This,Index, Options) -> wxSizer:show(This,Index, Options).
%% @hidden
diff --git a/lib/wx/src/gen/wxStyledTextCtrl.erl b/lib/wx/src/gen/wxStyledTextCtrl.erl
index 21964403f9..71d1bd0d53 100644
--- a/lib/wx/src/gen/wxStyledTextCtrl.erl
+++ b/lib/wx/src/gen/wxStyledTextCtrl.erl
@@ -1,24 +1,24 @@
%%
%% %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%
%% This file is generated DO NOT EDIT
%% @doc See external documentation: <a href="http://www.wxwidgets.org/manuals/stable/wx_wxstyledtextctrl.html">wxStyledTextCtrl</a>.
-%% <p>This class is derived (and can use functions) from:
+%% <p>This class is derived (and can use functions) from:
%% <br />{@link wxControl}
%% <br />{@link wxWindow}
%% <br />{@link wxEvtHandler}
@@ -3619,16 +3619,16 @@ appendTextRaw(#wx_ref{type=ThisT,ref=ThisRef},Text)
%% @spec (This::wxStyledTextCtrl()) -> ok
%% @doc Destroys this object, do not use object again
-destroy(Obj=#wx_ref{type=Type}) ->
+destroy(Obj=#wx_ref{type=Type}) ->
?CLASS(Type,wxStyledTextCtrl),
wxe_util:destroy(?DESTROY_OBJECT,Obj),
ok.
- %% From wxControl
+ %% From wxControl
%% @hidden
setLabel(This,Label) -> wxControl:setLabel(This,Label).
%% @hidden
getLabel(This) -> wxControl:getLabel(This).
- %% From wxWindow
+ %% From wxWindow
%% @hidden
warpPointer(This,X,Y) -> wxWindow:warpPointer(This,X,Y).
%% @hidden
@@ -3967,7 +3967,7 @@ center(This) -> wxWindow:center(This).
captureMouse(This) -> wxWindow:captureMouse(This).
%% @hidden
cacheBestSize(This,Size) -> wxWindow:cacheBestSize(This,Size).
- %% From wxEvtHandler
+ %% From wxEvtHandler
%% @hidden
disconnect(This,EventType, Options) -> wxEvtHandler:disconnect(This,EventType, Options).
%% @hidden
diff --git a/lib/wx/src/gen/wxStyledTextEvent.erl b/lib/wx/src/gen/wxStyledTextEvent.erl
index ed5788b6fd..5d98ae585d 100644
--- a/lib/wx/src/gen/wxStyledTextEvent.erl
+++ b/lib/wx/src/gen/wxStyledTextEvent.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%
%% This file is generated DO NOT EDIT
@@ -22,7 +22,7 @@
%% <dd><em>stc_change</em>, <em>stc_styleneeded</em>, <em>stc_charadded</em>, <em>stc_savepointreached</em>, <em>stc_savepointleft</em>, <em>stc_romodifyattempt</em>, <em>stc_key</em>, <em>stc_doubleclick</em>, <em>stc_updateui</em>, <em>stc_modified</em>, <em>stc_macrorecord</em>, <em>stc_marginclick</em>, <em>stc_needshown</em>, <em>stc_painted</em>, <em>stc_userlistselection</em>, <em>stc_uridropped</em>, <em>stc_dwellstart</em>, <em>stc_dwellend</em>, <em>stc_start_drag</em>, <em>stc_drag_over</em>, <em>stc_do_drop</em>, <em>stc_zoom</em>, <em>stc_hotspot_click</em>, <em>stc_hotspot_dclick</em>, <em>stc_calltip_click</em>, <em>stc_autocomp_selection</em></dd></dl>
%% See also the message variant {@link wxEvtHandler:wxStyledText(). #wxStyledText{}} event record type.
%%
-%% <p>This class is derived (and can use functions) from:
+%% <p>This class is derived (and can use functions) from:
%% <br />{@link wxCommandEvent}
%% <br />{@link wxEvent}
%% </p>
@@ -212,7 +212,7 @@ getAlt(#wx_ref{type=ThisT,ref=ThisRef}) ->
wxe_util:call(?wxStyledTextEvent_GetAlt,
<<ThisRef:32/?UI>>).
- %% From wxCommandEvent
+ %% From wxCommandEvent
%% @hidden
setString(This,S) -> wxCommandEvent:setString(This,S).
%% @hidden
@@ -231,7 +231,7 @@ getInt(This) -> wxCommandEvent:getInt(This).
getExtraLong(This) -> wxCommandEvent:getExtraLong(This).
%% @hidden
getClientData(This) -> wxCommandEvent:getClientData(This).
- %% From wxEvent
+ %% From wxEvent
%% @hidden
stopPropagation(This) -> wxEvent:stopPropagation(This).
%% @hidden
diff --git a/lib/wx/src/gen/wxSysColourChangedEvent.erl b/lib/wx/src/gen/wxSysColourChangedEvent.erl
index a90c7320d9..0d86edcf5b 100644
--- a/lib/wx/src/gen/wxSysColourChangedEvent.erl
+++ b/lib/wx/src/gen/wxSysColourChangedEvent.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%
%% This file is generated DO NOT EDIT
@@ -22,7 +22,7 @@
%% <dd><em>sys_colour_changed</em></dd></dl>
%% See also the message variant {@link wxEvtHandler:wxSysColourChanged(). #wxSysColourChanged{}} event record type.
%%
-%% <p>This class is derived (and can use functions) from:
+%% <p>This class is derived (and can use functions) from:
%% <br />{@link wxEvent}
%% </p>
%% @type wxSysColourChangedEvent(). An object reference, The representation is internal
@@ -41,7 +41,7 @@
parent_class(wxEvent) -> true;
parent_class(_Class) -> erlang:error({badtype, ?MODULE}).
- %% From wxEvent
+ %% From wxEvent
%% @hidden
stopPropagation(This) -> wxEvent:stopPropagation(This).
%% @hidden
diff --git a/lib/wx/src/gen/wxTextAttr.erl b/lib/wx/src/gen/wxTextAttr.erl
index dea39c19d0..056dc59161 100644
--- a/lib/wx/src/gen/wxTextAttr.erl
+++ b/lib/wx/src/gen/wxTextAttr.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%
%% This file is generated DO NOT EDIT
@@ -247,7 +247,7 @@ setTextColour(#wx_ref{type=ThisT,ref=ThisRef},ColText)
%% @spec (This::wxTextAttr()) -> ok
%% @doc Destroys this object, do not use object again
-destroy(Obj=#wx_ref{type=Type}) ->
+destroy(Obj=#wx_ref{type=Type}) ->
?CLASS(Type,wxTextAttr),
wxe_util:destroy(?wxTextAttr_destroy,Obj),
ok.
diff --git a/lib/wx/src/gen/wxTextCtrl.erl b/lib/wx/src/gen/wxTextCtrl.erl
index 1df8accdaa..b4af23bdd9 100644
--- a/lib/wx/src/gen/wxTextCtrl.erl
+++ b/lib/wx/src/gen/wxTextCtrl.erl
@@ -1,24 +1,24 @@
%%
%% %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%
%% This file is generated DO NOT EDIT
%% @doc See external documentation: <a href="http://www.wxwidgets.org/manuals/stable/wx_wxtextctrl.html">wxTextCtrl</a>.
-%% <p>This class is derived (and can use functions) from:
+%% <p>This class is derived (and can use functions) from:
%% <br />{@link wxControl}
%% <br />{@link wxWindow}
%% <br />{@link wxEvtHandler}
@@ -507,16 +507,16 @@ xYToPosition(#wx_ref{type=ThisT,ref=ThisRef},X,Y)
%% @spec (This::wxTextCtrl()) -> ok
%% @doc Destroys this object, do not use object again
-destroy(Obj=#wx_ref{type=Type}) ->
+destroy(Obj=#wx_ref{type=Type}) ->
?CLASS(Type,wxTextCtrl),
wxe_util:destroy(?DESTROY_OBJECT,Obj),
ok.
- %% From wxControl
+ %% From wxControl
%% @hidden
setLabel(This,Label) -> wxControl:setLabel(This,Label).
%% @hidden
getLabel(This) -> wxControl:getLabel(This).
- %% From wxWindow
+ %% From wxWindow
%% @hidden
warpPointer(This,X,Y) -> wxWindow:warpPointer(This,X,Y).
%% @hidden
@@ -863,7 +863,7 @@ center(This) -> wxWindow:center(This).
captureMouse(This) -> wxWindow:captureMouse(This).
%% @hidden
cacheBestSize(This,Size) -> wxWindow:cacheBestSize(This,Size).
- %% From wxEvtHandler
+ %% From wxEvtHandler
%% @hidden
disconnect(This,EventType, Options) -> wxEvtHandler:disconnect(This,EventType, Options).
%% @hidden
diff --git a/lib/wx/src/gen/wxTextDataObject.erl b/lib/wx/src/gen/wxTextDataObject.erl
index 1e4cee70aa..f4fe3b5e0c 100644
--- a/lib/wx/src/gen/wxTextDataObject.erl
+++ b/lib/wx/src/gen/wxTextDataObject.erl
@@ -1,24 +1,24 @@
%%
%% %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%
%% This file is generated DO NOT EDIT
%% @doc See external documentation: <a href="http://www.wxwidgets.org/manuals/stable/wx_wxtextdataobject.html">wxTextDataObject</a>.
-%% <p>This class is derived (and can use functions) from:
+%% <p>This class is derived (and can use functions) from:
%% <br />{@link wxDataObject}
%% </p>
%% @type wxTextDataObject(). An object reference, The representation is internal
@@ -77,8 +77,8 @@ setText(#wx_ref{type=ThisT,ref=ThisRef},Text)
%% @spec (This::wxTextDataObject()) -> ok
%% @doc Destroys this object, do not use object again
-destroy(Obj=#wx_ref{type=Type}) ->
+destroy(Obj=#wx_ref{type=Type}) ->
?CLASS(Type,wxTextDataObject),
wxe_util:destroy(?wxTextDataObject_destroy,Obj),
ok.
- %% From wxDataObject
+ %% From wxDataObject
diff --git a/lib/wx/src/gen/wxTextEntryDialog.erl b/lib/wx/src/gen/wxTextEntryDialog.erl
index 42e7f41513..a30c32dd53 100644
--- a/lib/wx/src/gen/wxTextEntryDialog.erl
+++ b/lib/wx/src/gen/wxTextEntryDialog.erl
@@ -1,24 +1,24 @@
%%
%% %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%
%% This file is generated DO NOT EDIT
%% @doc See external documentation: <a href="http://www.wxwidgets.org/manuals/stable/wx_wxtextentrydialog.html">wxTextEntryDialog</a>.
-%% <p>This class is derived (and can use functions) from:
+%% <p>This class is derived (and can use functions) from:
%% <br />{@link wxDialog}
%% <br />{@link wxTopLevelWindow}
%% <br />{@link wxWindow}
@@ -124,11 +124,11 @@ setValue(#wx_ref{type=ThisT,ref=ThisRef},Val)
%% @spec (This::wxTextEntryDialog()) -> ok
%% @doc Destroys this object, do not use object again
-destroy(Obj=#wx_ref{type=Type}) ->
+destroy(Obj=#wx_ref{type=Type}) ->
?CLASS(Type,wxTextEntryDialog),
wxe_util:destroy(?DESTROY_OBJECT,Obj),
ok.
- %% From wxDialog
+ %% From wxDialog
%% @hidden
showModal(This) -> wxDialog:showModal(This).
%% @hidden
@@ -151,7 +151,7 @@ endModal(This,RetCode) -> wxDialog:endModal(This,RetCode).
createStdDialogButtonSizer(This,Flags) -> wxDialog:createStdDialogButtonSizer(This,Flags).
%% @hidden
createButtonSizer(This,Flags) -> wxDialog:createButtonSizer(This,Flags).
- %% From wxTopLevelWindow
+ %% From wxTopLevelWindow
%% @hidden
showFullScreen(This,Show, Options) -> wxTopLevelWindow:showFullScreen(This,Show, Options).
%% @hidden
@@ -198,7 +198,7 @@ getTitle(This) -> wxTopLevelWindow:getTitle(This).
getIcons(This) -> wxTopLevelWindow:getIcons(This).
%% @hidden
getIcon(This) -> wxTopLevelWindow:getIcon(This).
- %% From wxWindow
+ %% From wxWindow
%% @hidden
warpPointer(This,X,Y) -> wxWindow:warpPointer(This,X,Y).
%% @hidden
@@ -545,7 +545,7 @@ center(This) -> wxWindow:center(This).
captureMouse(This) -> wxWindow:captureMouse(This).
%% @hidden
cacheBestSize(This,Size) -> wxWindow:cacheBestSize(This,Size).
- %% From wxEvtHandler
+ %% From wxEvtHandler
%% @hidden
disconnect(This,EventType, Options) -> wxEvtHandler:disconnect(This,EventType, Options).
%% @hidden
diff --git a/lib/wx/src/gen/wxToggleButton.erl b/lib/wx/src/gen/wxToggleButton.erl
index 0a8f4f1127..ab595c1906 100644
--- a/lib/wx/src/gen/wxToggleButton.erl
+++ b/lib/wx/src/gen/wxToggleButton.erl
@@ -1,24 +1,24 @@
%%
%% %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%
%% This file is generated DO NOT EDIT
%% @doc See external documentation: <a href="http://www.wxwidgets.org/manuals/stable/wx_wxtogglebutton.html">wxToggleButton</a>.
-%% <p>This class is derived (and can use functions) from:
+%% <p>This class is derived (and can use functions) from:
%% <br />{@link wxControl}
%% <br />{@link wxWindow}
%% <br />{@link wxEvtHandler}
@@ -143,16 +143,16 @@ setValue(#wx_ref{type=ThisT,ref=ThisRef},State)
%% @spec (This::wxToggleButton()) -> ok
%% @doc Destroys this object, do not use object again
-destroy(Obj=#wx_ref{type=Type}) ->
+destroy(Obj=#wx_ref{type=Type}) ->
?CLASS(Type,wxToggleButton),
wxe_util:destroy(?DESTROY_OBJECT,Obj),
ok.
- %% From wxControl
+ %% From wxControl
%% @hidden
setLabel(This,Label) -> wxControl:setLabel(This,Label).
%% @hidden
getLabel(This) -> wxControl:getLabel(This).
- %% From wxWindow
+ %% From wxWindow
%% @hidden
warpPointer(This,X,Y) -> wxWindow:warpPointer(This,X,Y).
%% @hidden
@@ -499,7 +499,7 @@ center(This) -> wxWindow:center(This).
captureMouse(This) -> wxWindow:captureMouse(This).
%% @hidden
cacheBestSize(This,Size) -> wxWindow:cacheBestSize(This,Size).
- %% From wxEvtHandler
+ %% From wxEvtHandler
%% @hidden
disconnect(This,EventType, Options) -> wxEvtHandler:disconnect(This,EventType, Options).
%% @hidden
diff --git a/lib/wx/src/gen/wxToolBar.erl b/lib/wx/src/gen/wxToolBar.erl
index c8392a10ca..c68936d493 100644
--- a/lib/wx/src/gen/wxToolBar.erl
+++ b/lib/wx/src/gen/wxToolBar.erl
@@ -1,24 +1,24 @@
%%
%% %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%
%% This file is generated DO NOT EDIT
%% @doc See external documentation: <a href="http://www.wxwidgets.org/manuals/stable/wx_wxtoolbar.html">wxToolBar</a>.
-%% <p>This class is derived (and can use functions) from:
+%% <p>This class is derived (and can use functions) from:
%% <br />{@link wxControl}
%% <br />{@link wxWindow}
%% <br />{@link wxEvtHandler}
@@ -114,7 +114,7 @@ addTool(This,Toolid,Bitmap)
%% @spec (This::wxToolBar(),Toolid::integer(),X::string()|term(),X::term()) -> wx:wx()
%% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxtoolbar.html#wxtoolbaraddtool">external documentation</a>.
-%% <br /> Alternatives:
+%% <br /> Alternatives:
%% <p><c>
%% addTool(This::wxToolBar(), Toolid::integer(), Label::string(), Bitmap::wxBitmap:wxBitmap()) -> addTool(This,Toolid,Label,Bitmap, []) </c></p>
%% <p><c>
@@ -144,7 +144,7 @@ addTool(#wx_ref{type=ThisT,ref=ThisRef},Toolid,#wx_ref{type=BitmapT,ref=BitmapRe
%% @spec (This::wxToolBar(),Toolid::integer(),X::string()|term(),X::term(),X::term()) -> wx:wx()
%% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxtoolbar.html#wxtoolbaraddtool">external documentation</a>.
-%% <br /> Alternatives:
+%% <br /> Alternatives:
%% <p><c>
%% addTool(This::wxToolBar(), Toolid::integer(), Label::string(), Bitmap::wxBitmap:wxBitmap(), BmpDisabled::wxBitmap:wxBitmap()) -> addTool(This,Toolid,Label,Bitmap,BmpDisabled, []) </c></p>
%% <p><c>
@@ -188,7 +188,7 @@ addTool(#wx_ref{type=ThisT,ref=ThisRef},Toolid,#wx_ref{type=BitmapT,ref=BitmapRe
%% @spec (This::wxToolBar(),Toolid::integer(),X::term()|string(),X::term(),X::bool()|term(),X::integer()|term()) -> wx:wx()
%% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxtoolbar.html#wxtoolbaraddtool">external documentation</a>.
-%% <br /> Alternatives:
+%% <br /> Alternatives:
%% <p><c>
%% addTool(This::wxToolBar(), Toolid::integer(), Bitmap::wxBitmap:wxBitmap(), BmpDisabled::wxBitmap:wxBitmap(), Toggle::bool(), XPos::integer()) -> addTool(This,Toolid,Bitmap,BmpDisabled,Toggle,XPos, []) </c></p>
%% <p><c>
@@ -436,7 +436,7 @@ insertTool(This,Pos,Toolid,Bitmap)
%% @spec (This::wxToolBar(),Pos::integer(),Toolid::integer(),X::string()|term(),X::term()) -> wx:wx()
%% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxtoolbar.html#wxtoolbarinserttool">external documentation</a>.
-%% <br /> Alternatives:
+%% <br /> Alternatives:
%% <p><c>
%% insertTool(This::wxToolBar(), Pos::integer(), Toolid::integer(), Label::string(), Bitmap::wxBitmap:wxBitmap()) -> insertTool(This,Pos,Toolid,Label,Bitmap, []) </c></p>
%% <p><c>
@@ -554,12 +554,12 @@ toggleTool(#wx_ref{type=ThisT,ref=ThisRef},Toolid,Toggle)
wxe_util:cast(?wxToolBar_ToggleTool,
<<ThisRef:32/?UI,Toolid:32/?UI,(wxe_util:from_bool(Toggle)):32/?UI>>).
- %% From wxControl
+ %% From wxControl
%% @hidden
setLabel(This,Label) -> wxControl:setLabel(This,Label).
%% @hidden
getLabel(This) -> wxControl:getLabel(This).
- %% From wxWindow
+ %% From wxWindow
%% @hidden
warpPointer(This,X,Y) -> wxWindow:warpPointer(This,X,Y).
%% @hidden
@@ -906,7 +906,7 @@ center(This) -> wxWindow:center(This).
captureMouse(This) -> wxWindow:captureMouse(This).
%% @hidden
cacheBestSize(This,Size) -> wxWindow:cacheBestSize(This,Size).
- %% From wxEvtHandler
+ %% From wxEvtHandler
%% @hidden
disconnect(This,EventType, Options) -> wxEvtHandler:disconnect(This,EventType, Options).
%% @hidden
diff --git a/lib/wx/src/gen/wxToolTip.erl b/lib/wx/src/gen/wxToolTip.erl
index 3a57ece765..b0749c851a 100644
--- a/lib/wx/src/gen/wxToolTip.erl
+++ b/lib/wx/src/gen/wxToolTip.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%
%% This file is generated DO NOT EDIT
@@ -79,7 +79,7 @@ getWindow(#wx_ref{type=ThisT,ref=ThisRef}) ->
%% @spec (This::wxToolTip()) -> ok
%% @doc Destroys this object, do not use object again
-destroy(Obj=#wx_ref{type=Type}) ->
+destroy(Obj=#wx_ref{type=Type}) ->
?CLASS(Type,wxToolTip),
wxe_util:destroy(?DESTROY_OBJECT,Obj),
ok.
diff --git a/lib/wx/src/gen/wxToolbook.erl b/lib/wx/src/gen/wxToolbook.erl
index 44d3ea945d..4d188e979d 100644
--- a/lib/wx/src/gen/wxToolbook.erl
+++ b/lib/wx/src/gen/wxToolbook.erl
@@ -1,24 +1,24 @@
%%
%% %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%
%% This file is generated DO NOT EDIT
%% @doc See external documentation: <a href="http://www.wxwidgets.org/manuals/stable/wx_wxtoolbook.html">wxToolbook</a>.
-%% <p>This class is derived (and can use functions) from:
+%% <p>This class is derived (and can use functions) from:
%% <br />{@link wxControl}
%% <br />{@link wxWindow}
%% <br />{@link wxEvtHandler}
@@ -329,16 +329,16 @@ changeSelection(#wx_ref{type=ThisT,ref=ThisRef},N)
%% @spec (This::wxToolbook()) -> ok
%% @doc Destroys this object, do not use object again
-destroy(Obj=#wx_ref{type=Type}) ->
+destroy(Obj=#wx_ref{type=Type}) ->
?CLASS(Type,wxToolbook),
wxe_util:destroy(?DESTROY_OBJECT,Obj),
ok.
- %% From wxControl
+ %% From wxControl
%% @hidden
setLabel(This,Label) -> wxControl:setLabel(This,Label).
%% @hidden
getLabel(This) -> wxControl:getLabel(This).
- %% From wxWindow
+ %% From wxWindow
%% @hidden
warpPointer(This,X,Y) -> wxWindow:warpPointer(This,X,Y).
%% @hidden
@@ -685,7 +685,7 @@ center(This) -> wxWindow:center(This).
captureMouse(This) -> wxWindow:captureMouse(This).
%% @hidden
cacheBestSize(This,Size) -> wxWindow:cacheBestSize(This,Size).
- %% From wxEvtHandler
+ %% From wxEvtHandler
%% @hidden
disconnect(This,EventType, Options) -> wxEvtHandler:disconnect(This,EventType, Options).
%% @hidden
diff --git a/lib/wx/src/gen/wxTopLevelWindow.erl b/lib/wx/src/gen/wxTopLevelWindow.erl
index 3bb63886d9..e0551b480f 100644
--- a/lib/wx/src/gen/wxTopLevelWindow.erl
+++ b/lib/wx/src/gen/wxTopLevelWindow.erl
@@ -1,24 +1,24 @@
%%
%% %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%
%% This file is generated DO NOT EDIT
%% @doc See external documentation: <a href="http://www.wxwidgets.org/manuals/stable/wx_wxtoplevelwindow.html">wxTopLevelWindow</a>.
-%% <p>This class is derived (and can use functions) from:
+%% <p>This class is derived (and can use functions) from:
%% <br />{@link wxWindow}
%% <br />{@link wxEvtHandler}
%% </p>
@@ -267,7 +267,7 @@ showFullScreen(#wx_ref{type=ThisT,ref=ThisRef},Show, Options)
wxe_util:call(?wxTopLevelWindow_ShowFullScreen,
<<ThisRef:32/?UI,(wxe_util:from_bool(Show)):32/?UI, BinOpt/binary>>).
- %% From wxWindow
+ %% From wxWindow
%% @hidden
warpPointer(This,X,Y) -> wxWindow:warpPointer(This,X,Y).
%% @hidden
@@ -618,7 +618,7 @@ center(This) -> wxWindow:center(This).
captureMouse(This) -> wxWindow:captureMouse(This).
%% @hidden
cacheBestSize(This,Size) -> wxWindow:cacheBestSize(This,Size).
- %% From wxEvtHandler
+ %% From wxEvtHandler
%% @hidden
disconnect(This,EventType, Options) -> wxEvtHandler:disconnect(This,EventType, Options).
%% @hidden
diff --git a/lib/wx/src/gen/wxTreeCtrl.erl b/lib/wx/src/gen/wxTreeCtrl.erl
index cc08c14754..4fcbb9366e 100644
--- a/lib/wx/src/gen/wxTreeCtrl.erl
+++ b/lib/wx/src/gen/wxTreeCtrl.erl
@@ -1,24 +1,28 @@
%%
%% %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%
%% This file is generated DO NOT EDIT
%% @doc See external documentation: <a href="http://www.wxwidgets.org/manuals/stable/wx_wxtreectrl.html">wxTreeCtrl</a>.
-%% <p>This class is derived (and can use functions) from:
+%%
+%% Note: The representation of treeItemId() have changed from the original class implementation to be an semi-opaque type,Equality between TreeItemId's can be tested and zero means that the TreeItem is invalid.
+
+%%
+%% <p>This class is derived (and can use functions) from:
%% <br />{@link wxControl}
%% <br />{@link wxWindow}
%% <br />{@link wxEvtHandler}
@@ -33,10 +37,10 @@
collapse/2,collapseAndReset/2,create/2,create/3,delete/2,deleteAllItems/1,
deleteChildren/2,destroy/1,ensureVisible/2,expand/2,getBoundingRect/3,
getBoundingRect/4,getChildrenCount/2,getChildrenCount/3,getCount/1,
- getEditControl/1,getFirstVisibleItem/1,getImageList/1,getIndent/1,
- getItemBackgroundColour/2,getItemData/2,getItemFont/2,getItemImage/2,
- getItemImage/3,getItemParent/2,getItemText/2,getItemTextColour/2,
- getLastChild/2,getNextSibling/2,getNextVisible/2,getPrevSibling/2,
+ getEditControl/1,getFirstChild/2,getFirstVisibleItem/1,getImageList/1,
+ getIndent/1,getItemBackgroundColour/2,getItemData/2,getItemFont/2,
+ getItemImage/2,getItemImage/3,getItemParent/2,getItemText/2,getItemTextColour/2,
+ getLastChild/2,getNextChild/3,getNextSibling/2,getNextVisible/2,getPrevSibling/2,
getPrevVisible/2,getRootItem/1,getSelection/1,getSelections/1,getStateImageList/1,
hitTest/2,insertItem/4,insertItem/5,isBold/2,isExpanded/2,isSelected/2,
isVisible/2,itemHasChildren/2,new/0,new/1,new/2,prependItem/3,prependItem/4,
@@ -119,13 +123,13 @@ new(#wx_ref{type=ParentT,ref=ParentRef}, Options)
wxe_util:construct(?wxTreeCtrl_new_2,
<<ParentRef:32/?UI, 0:32,BinOpt/binary>>).
-%% @spec (This::wxTreeCtrl(), Text::string()) -> wxTreeItemId()
+%% @spec (This::wxTreeCtrl(), Text::string()) -> integer()
%% @equiv addRoot(This,Text, [])
addRoot(This,Text)
when is_record(This, wx_ref),is_list(Text) ->
addRoot(This,Text, []).
-%% @spec (This::wxTreeCtrl(), Text::string(), [Option]) -> wxTreeItemId()
+%% @spec (This::wxTreeCtrl(), Text::string(), [Option]) -> integer()
%% Option = {image, integer()} | {selectedImage, integer()} | {data, term()}
%% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxtreectrl.html#wxtreectrladdroot">external documentation</a>.
addRoot(#wx_ref{type=ThisT,ref=ThisRef},Text, Options)
@@ -140,17 +144,17 @@ addRoot(#wx_ref{type=ThisT,ref=ThisRef},Text, Options)
wxe_util:call(?wxTreeCtrl_AddRoot,
<<ThisRef:32/?UI,(byte_size(Text_UC)):32/?UI,(Text_UC)/binary, 0:(((8- ((0+byte_size(Text_UC)) band 16#7)) band 16#7))/unit:8, BinOpt/binary>>).
-%% @spec (This::wxTreeCtrl(), Parent::wxTreeItemId(), Text::string()) -> wxTreeItemId()
+%% @spec (This::wxTreeCtrl(), Parent::integer(), Text::string()) -> integer()
%% @equiv appendItem(This,Parent,Text, [])
appendItem(This,Parent,Text)
- when is_record(This, wx_ref),is_record(Parent, wx_ref),is_list(Text) ->
+ when is_record(This, wx_ref),is_integer(Parent),is_list(Text) ->
appendItem(This,Parent,Text, []).
-%% @spec (This::wxTreeCtrl(), Parent::wxTreeItemId(), Text::string(), [Option]) -> wxTreeItemId()
+%% @spec (This::wxTreeCtrl(), Parent::integer(), Text::string(), [Option]) -> integer()
%% Option = {image, integer()} | {selectedImage, integer()} | {data, term()}
%% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxtreectrl.html#wxtreectrlappenditem">external documentation</a>.
-appendItem(#wx_ref{type=ThisT,ref=ThisRef},#wx_ref{type=wxTreeItemId,ref=ParentRef},Text, Options)
- when is_list(Text),is_list(Options) ->
+appendItem(#wx_ref{type=ThisT,ref=ThisRef},Parent,Text, Options)
+ when is_integer(Parent),is_list(Text),is_list(Options) ->
?CLASS(ThisT,wxTreeCtrl),
Text_UC = unicode:characters_to_binary([Text,0]),
MOpts = fun({image, Image}, Acc) -> [<<1:32/?UI,Image:32/?UI>>|Acc];
@@ -159,7 +163,7 @@ appendItem(#wx_ref{type=ThisT,ref=ThisRef},#wx_ref{type=wxTreeItemId,ref=ParentR
(BadOpt, _) -> erlang:error({badoption, BadOpt}) end,
BinOpt = list_to_binary(lists:foldl(MOpts, [<<0:32>>], Options)),
wxe_util:call(?wxTreeCtrl_AppendItem,
- <<ThisRef:32/?UI,ParentRef:32/?UI,(byte_size(Text_UC)):32/?UI,(Text_UC)/binary, 0:(((8- ((4+byte_size(Text_UC)) band 16#7)) band 16#7))/unit:8, BinOpt/binary>>).
+ <<ThisRef:32/?UI,0:32,Parent:64/?UI,(byte_size(Text_UC)):32/?UI,(Text_UC)/binary, 0:(((8- ((4+byte_size(Text_UC)) band 16#7)) band 16#7))/unit:8, BinOpt/binary>>).
%% @spec (This::wxTreeCtrl(), ImageList::wxImageList:wxImageList()) -> ok
%% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxtreectrl.html#wxtreectrlassignimagelist">external documentation</a>.
@@ -177,19 +181,21 @@ assignStateImageList(#wx_ref{type=ThisT,ref=ThisRef},#wx_ref{type=ImageListT,ref
wxe_util:cast(?wxTreeCtrl_AssignStateImageList,
<<ThisRef:32/?UI,ImageListRef:32/?UI>>).
-%% @spec (This::wxTreeCtrl(), Item::wxTreeItemId()) -> ok
+%% @spec (This::wxTreeCtrl(), Item::integer()) -> ok
%% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxtreectrl.html#wxtreectrlcollapse">external documentation</a>.
-collapse(#wx_ref{type=ThisT,ref=ThisRef},#wx_ref{type=wxTreeItemId,ref=ItemRef}) ->
+collapse(#wx_ref{type=ThisT,ref=ThisRef},Item)
+ when is_integer(Item) ->
?CLASS(ThisT,wxTreeCtrl),
wxe_util:cast(?wxTreeCtrl_Collapse,
- <<ThisRef:32/?UI,ItemRef:32/?UI>>).
+ <<ThisRef:32/?UI,0:32,Item:64/?UI>>).
-%% @spec (This::wxTreeCtrl(), Item::wxTreeItemId()) -> ok
+%% @spec (This::wxTreeCtrl(), Item::integer()) -> ok
%% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxtreectrl.html#wxtreectrlcollapseandreset">external documentation</a>.
-collapseAndReset(#wx_ref{type=ThisT,ref=ThisRef},#wx_ref{type=wxTreeItemId,ref=ItemRef}) ->
+collapseAndReset(#wx_ref{type=ThisT,ref=ThisRef},Item)
+ when is_integer(Item) ->
?CLASS(ThisT,wxTreeCtrl),
wxe_util:cast(?wxTreeCtrl_CollapseAndReset,
- <<ThisRef:32/?UI,ItemRef:32/?UI>>).
+ <<ThisRef:32/?UI,0:32,Item:64/?UI>>).
%% @spec (This::wxTreeCtrl(), Parent::wxWindow:wxWindow()) -> bool()
%% @equiv create(This,Parent, [])
@@ -214,12 +220,13 @@ create(#wx_ref{type=ThisT,ref=ThisRef},#wx_ref{type=ParentT,ref=ParentRef}, Opti
wxe_util:call(?wxTreeCtrl_Create,
<<ThisRef:32/?UI,ParentRef:32/?UI, BinOpt/binary>>).
-%% @spec (This::wxTreeCtrl(), Item::wxTreeItemId()) -> ok
+%% @spec (This::wxTreeCtrl(), Item::integer()) -> ok
%% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxtreectrl.html#wxtreectrldelete">external documentation</a>.
-delete(#wx_ref{type=ThisT,ref=ThisRef},#wx_ref{type=wxTreeItemId,ref=ItemRef}) ->
+delete(#wx_ref{type=ThisT,ref=ThisRef},Item)
+ when is_integer(Item) ->
?CLASS(ThisT,wxTreeCtrl),
wxe_util:cast(?wxTreeCtrl_Delete,
- <<ThisRef:32/?UI,ItemRef:32/?UI>>).
+ <<ThisRef:32/?UI,0:32,Item:64/?UI>>).
%% @spec (This::wxTreeCtrl()) -> ok
%% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxtreectrl.html#wxtreectrldeleteallitems">external documentation</a>.
@@ -228,62 +235,65 @@ deleteAllItems(#wx_ref{type=ThisT,ref=ThisRef}) ->
wxe_util:cast(?wxTreeCtrl_DeleteAllItems,
<<ThisRef:32/?UI>>).
-%% @spec (This::wxTreeCtrl(), Item::wxTreeItemId()) -> ok
+%% @spec (This::wxTreeCtrl(), Item::integer()) -> ok
%% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxtreectrl.html#wxtreectrldeletechildren">external documentation</a>.
-deleteChildren(#wx_ref{type=ThisT,ref=ThisRef},#wx_ref{type=wxTreeItemId,ref=ItemRef}) ->
+deleteChildren(#wx_ref{type=ThisT,ref=ThisRef},Item)
+ when is_integer(Item) ->
?CLASS(ThisT,wxTreeCtrl),
wxe_util:cast(?wxTreeCtrl_DeleteChildren,
- <<ThisRef:32/?UI,ItemRef:32/?UI>>).
+ <<ThisRef:32/?UI,0:32,Item:64/?UI>>).
-%% @spec (This::wxTreeCtrl(), Item::wxTreeItemId()) -> ok
+%% @spec (This::wxTreeCtrl(), Item::integer()) -> ok
%% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxtreectrl.html#wxtreectrlensurevisible">external documentation</a>.
-ensureVisible(#wx_ref{type=ThisT,ref=ThisRef},#wx_ref{type=wxTreeItemId,ref=ItemRef}) ->
+ensureVisible(#wx_ref{type=ThisT,ref=ThisRef},Item)
+ when is_integer(Item) ->
?CLASS(ThisT,wxTreeCtrl),
wxe_util:cast(?wxTreeCtrl_EnsureVisible,
- <<ThisRef:32/?UI,ItemRef:32/?UI>>).
+ <<ThisRef:32/?UI,0:32,Item:64/?UI>>).
-%% @spec (This::wxTreeCtrl(), Item::wxTreeItemId()) -> ok
+%% @spec (This::wxTreeCtrl(), Item::integer()) -> ok
%% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxtreectrl.html#wxtreectrlexpand">external documentation</a>.
-expand(#wx_ref{type=ThisT,ref=ThisRef},#wx_ref{type=wxTreeItemId,ref=ItemRef}) ->
+expand(#wx_ref{type=ThisT,ref=ThisRef},Item)
+ when is_integer(Item) ->
?CLASS(ThisT,wxTreeCtrl),
wxe_util:cast(?wxTreeCtrl_Expand,
- <<ThisRef:32/?UI,ItemRef:32/?UI>>).
+ <<ThisRef:32/?UI,0:32,Item:64/?UI>>).
-%% @spec (This::wxTreeCtrl(), Item::wxTreeItemId(), Rect::{X::integer(),Y::integer(),W::integer(),H::integer()}) -> bool()
+%% @spec (This::wxTreeCtrl(), Item::integer(), Rect::{X::integer(),Y::integer(),W::integer(),H::integer()}) -> bool()
%% @equiv getBoundingRect(This,Item,Rect, [])
getBoundingRect(This,Item,Rect={RectX,RectY,RectW,RectH})
- when is_record(This, wx_ref),is_record(Item, wx_ref),is_integer(RectX),is_integer(RectY),is_integer(RectW),is_integer(RectH) ->
+ when is_record(This, wx_ref),is_integer(Item),is_integer(RectX),is_integer(RectY),is_integer(RectW),is_integer(RectH) ->
getBoundingRect(This,Item,Rect, []).
-%% @spec (This::wxTreeCtrl(), Item::wxTreeItemId(), Rect::{X::integer(),Y::integer(),W::integer(),H::integer()}, [Option]) -> bool()
+%% @spec (This::wxTreeCtrl(), Item::integer(), Rect::{X::integer(),Y::integer(),W::integer(),H::integer()}, [Option]) -> bool()
%% Option = {textOnly, bool()}
%% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxtreectrl.html#wxtreectrlgetboundingrect">external documentation</a>.
-getBoundingRect(#wx_ref{type=ThisT,ref=ThisRef},#wx_ref{type=wxTreeItemId,ref=ItemRef},{RectX,RectY,RectW,RectH}, Options)
- when is_integer(RectX),is_integer(RectY),is_integer(RectW),is_integer(RectH),is_list(Options) ->
+getBoundingRect(#wx_ref{type=ThisT,ref=ThisRef},Item,{RectX,RectY,RectW,RectH}, Options)
+ when is_integer(Item),is_integer(RectX),is_integer(RectY),is_integer(RectW),is_integer(RectH),is_list(Options) ->
?CLASS(ThisT,wxTreeCtrl),
MOpts = fun({textOnly, TextOnly}, Acc) -> [<<1:32/?UI,(wxe_util:from_bool(TextOnly)):32/?UI>>|Acc];
(BadOpt, _) -> erlang:error({badoption, BadOpt}) end,
BinOpt = list_to_binary(lists:foldl(MOpts, [<<0:32>>], Options)),
wxe_util:call(?wxTreeCtrl_GetBoundingRect,
- <<ThisRef:32/?UI,ItemRef:32/?UI,RectX:32/?UI,RectY:32/?UI,RectW:32/?UI,RectH:32/?UI, BinOpt/binary>>).
+ <<ThisRef:32/?UI,0:32,Item:64/?UI,RectX:32/?UI,RectY:32/?UI,RectW:32/?UI,RectH:32/?UI, BinOpt/binary>>).
-%% @spec (This::wxTreeCtrl(), Item::wxTreeItemId()) -> integer()
+%% @spec (This::wxTreeCtrl(), Item::integer()) -> integer()
%% @equiv getChildrenCount(This,Item, [])
getChildrenCount(This,Item)
- when is_record(This, wx_ref),is_record(Item, wx_ref) ->
+ when is_record(This, wx_ref),is_integer(Item) ->
getChildrenCount(This,Item, []).
-%% @spec (This::wxTreeCtrl(), Item::wxTreeItemId(), [Option]) -> integer()
+%% @spec (This::wxTreeCtrl(), Item::integer(), [Option]) -> integer()
%% Option = {recursively, bool()}
%% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxtreectrl.html#wxtreectrlgetchildrencount">external documentation</a>.
-getChildrenCount(#wx_ref{type=ThisT,ref=ThisRef},#wx_ref{type=wxTreeItemId,ref=ItemRef}, Options)
- when is_list(Options) ->
+getChildrenCount(#wx_ref{type=ThisT,ref=ThisRef},Item, Options)
+ when is_integer(Item),is_list(Options) ->
?CLASS(ThisT,wxTreeCtrl),
MOpts = fun({recursively, Recursively}, Acc) -> [<<1:32/?UI,(wxe_util:from_bool(Recursively)):32/?UI>>|Acc];
(BadOpt, _) -> erlang:error({badoption, BadOpt}) end,
BinOpt = list_to_binary(lists:foldl(MOpts, [<<0:32>>], Options)),
wxe_util:call(?wxTreeCtrl_GetChildrenCount,
- <<ThisRef:32/?UI,ItemRef:32/?UI, BinOpt/binary>>).
+ <<ThisRef:32/?UI,0:32,Item:64/?UI, BinOpt/binary>>).
%% @spec (This::wxTreeCtrl()) -> integer()
%% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxtreectrl.html#wxtreectrlgetcount">external documentation</a>.
@@ -299,7 +309,23 @@ getEditControl(#wx_ref{type=ThisT,ref=ThisRef}) ->
wxe_util:call(?wxTreeCtrl_GetEditControl,
<<ThisRef:32/?UI>>).
-%% @spec (This::wxTreeCtrl()) -> wxTreeItemId()
+%% @spec (This::wxTreeCtrl(), Item::integer()) -> {integer(),Cookie::integer()}
+%% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxtreectrl.html#wxtreectrlgetfirstchild">external documentation</a>.
+getFirstChild(#wx_ref{type=ThisT,ref=ThisRef},Item)
+ when is_integer(Item) ->
+ ?CLASS(ThisT,wxTreeCtrl),
+ wxe_util:call(?wxTreeCtrl_GetFirstChild,
+ <<ThisRef:32/?UI,0:32,Item:64/?UI>>).
+
+%% @spec (This::wxTreeCtrl(), Item::integer(), Cookie::integer()) -> {integer(),Cookie::integer()}
+%% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxtreectrl.html#wxtreectrlgetnextchild">external documentation</a>.
+getNextChild(#wx_ref{type=ThisT,ref=ThisRef},Item,Cookie)
+ when is_integer(Item),is_integer(Cookie) ->
+ ?CLASS(ThisT,wxTreeCtrl),
+ wxe_util:call(?wxTreeCtrl_GetNextChild,
+ <<ThisRef:32/?UI,0:32,Item:64/?UI,Cookie:64/?UI>>).
+
+%% @spec (This::wxTreeCtrl()) -> integer()
%% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxtreectrl.html#wxtreectrlgetfirstvisibleitem">external documentation</a>.
getFirstVisibleItem(#wx_ref{type=ThisT,ref=ThisRef}) ->
?CLASS(ThisT,wxTreeCtrl),
@@ -320,119 +346,131 @@ getIndent(#wx_ref{type=ThisT,ref=ThisRef}) ->
wxe_util:call(?wxTreeCtrl_GetIndent,
<<ThisRef:32/?UI>>).
-%% @spec (This::wxTreeCtrl(), Item::wxTreeItemId()) -> wx:colour()
+%% @spec (This::wxTreeCtrl(), Item::integer()) -> wx:colour()
%% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxtreectrl.html#wxtreectrlgetitembackgroundcolour">external documentation</a>.
-getItemBackgroundColour(#wx_ref{type=ThisT,ref=ThisRef},#wx_ref{type=wxTreeItemId,ref=ItemRef}) ->
+getItemBackgroundColour(#wx_ref{type=ThisT,ref=ThisRef},Item)
+ when is_integer(Item) ->
?CLASS(ThisT,wxTreeCtrl),
wxe_util:call(?wxTreeCtrl_GetItemBackgroundColour,
- <<ThisRef:32/?UI,ItemRef:32/?UI>>).
+ <<ThisRef:32/?UI,0:32,Item:64/?UI>>).
-%% @spec (This::wxTreeCtrl(), Item::wxTreeItemId()) -> term()
+%% @spec (This::wxTreeCtrl(), Item::integer()) -> term()
%% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxtreectrl.html#wxtreectrlgetitemdata">external documentation</a>.
-getItemData(#wx_ref{type=ThisT,ref=ThisRef},#wx_ref{type=wxTreeItemId,ref=ItemRef}) ->
+getItemData(#wx_ref{type=ThisT,ref=ThisRef},Item)
+ when is_integer(Item) ->
?CLASS(ThisT,wxTreeCtrl),
wxe_util:call(?wxTreeCtrl_GetItemData,
- <<ThisRef:32/?UI,ItemRef:32/?UI>>).
+ <<ThisRef:32/?UI,0:32,Item:64/?UI>>).
-%% @spec (This::wxTreeCtrl(), Item::wxTreeItemId()) -> wxFont:wxFont()
+%% @spec (This::wxTreeCtrl(), Item::integer()) -> wxFont:wxFont()
%% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxtreectrl.html#wxtreectrlgetitemfont">external documentation</a>.
-getItemFont(#wx_ref{type=ThisT,ref=ThisRef},#wx_ref{type=wxTreeItemId,ref=ItemRef}) ->
+getItemFont(#wx_ref{type=ThisT,ref=ThisRef},Item)
+ when is_integer(Item) ->
?CLASS(ThisT,wxTreeCtrl),
wxe_util:call(?wxTreeCtrl_GetItemFont,
- <<ThisRef:32/?UI,ItemRef:32/?UI>>).
+ <<ThisRef:32/?UI,0:32,Item:64/?UI>>).
-%% @spec (This::wxTreeCtrl(), Item::wxTreeItemId()) -> integer()
+%% @spec (This::wxTreeCtrl(), Item::integer()) -> integer()
%% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxtreectrl.html#wxtreectrlgetitemimage">external documentation</a>.
-getItemImage(#wx_ref{type=ThisT,ref=ThisRef},#wx_ref{type=wxTreeItemId,ref=ItemRef}) ->
+getItemImage(#wx_ref{type=ThisT,ref=ThisRef},Item)
+ when is_integer(Item) ->
?CLASS(ThisT,wxTreeCtrl),
wxe_util:call(?wxTreeCtrl_GetItemImage_1,
- <<ThisRef:32/?UI,ItemRef:32/?UI>>).
+ <<ThisRef:32/?UI,0:32,Item:64/?UI>>).
-%% @spec (This::wxTreeCtrl(), Item::wxTreeItemId(), [Option]) -> integer()
+%% @spec (This::wxTreeCtrl(), Item::integer(), [Option]) -> integer()
%% Option = {which, WxTreeItemIcon}
%% WxTreeItemIcon = integer()
%% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxtreectrl.html#wxtreectrlgetitemimage">external documentation</a>.
%%<br /> WxTreeItemIcon is one of ?wxTreeItemIcon_Normal | ?wxTreeItemIcon_Selected | ?wxTreeItemIcon_Expanded | ?wxTreeItemIcon_SelectedExpanded | ?wxTreeItemIcon_Max
-getItemImage(#wx_ref{type=ThisT,ref=ThisRef},#wx_ref{type=wxTreeItemId,ref=ItemRef}, Options)
- when is_list(Options) ->
+getItemImage(#wx_ref{type=ThisT,ref=ThisRef},Item, Options)
+ when is_integer(Item),is_list(Options) ->
?CLASS(ThisT,wxTreeCtrl),
MOpts = fun({which, Which}, Acc) -> [<<1:32/?UI,Which:32/?UI>>|Acc];
(BadOpt, _) -> erlang:error({badoption, BadOpt}) end,
BinOpt = list_to_binary(lists:foldl(MOpts, [<<0:32>>], Options)),
wxe_util:call(?wxTreeCtrl_GetItemImage_2,
- <<ThisRef:32/?UI,ItemRef:32/?UI, BinOpt/binary>>).
+ <<ThisRef:32/?UI,0:32,Item:64/?UI, BinOpt/binary>>).
-%% @spec (This::wxTreeCtrl(), Item::wxTreeItemId()) -> string()
+%% @spec (This::wxTreeCtrl(), Item::integer()) -> string()
%% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxtreectrl.html#wxtreectrlgetitemtext">external documentation</a>.
-getItemText(#wx_ref{type=ThisT,ref=ThisRef},#wx_ref{type=wxTreeItemId,ref=ItemRef}) ->
+getItemText(#wx_ref{type=ThisT,ref=ThisRef},Item)
+ when is_integer(Item) ->
?CLASS(ThisT,wxTreeCtrl),
wxe_util:call(?wxTreeCtrl_GetItemText,
- <<ThisRef:32/?UI,ItemRef:32/?UI>>).
+ <<ThisRef:32/?UI,0:32,Item:64/?UI>>).
-%% @spec (This::wxTreeCtrl(), Item::wxTreeItemId()) -> wx:colour()
+%% @spec (This::wxTreeCtrl(), Item::integer()) -> wx:colour()
%% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxtreectrl.html#wxtreectrlgetitemtextcolour">external documentation</a>.
-getItemTextColour(#wx_ref{type=ThisT,ref=ThisRef},#wx_ref{type=wxTreeItemId,ref=ItemRef}) ->
+getItemTextColour(#wx_ref{type=ThisT,ref=ThisRef},Item)
+ when is_integer(Item) ->
?CLASS(ThisT,wxTreeCtrl),
wxe_util:call(?wxTreeCtrl_GetItemTextColour,
- <<ThisRef:32/?UI,ItemRef:32/?UI>>).
+ <<ThisRef:32/?UI,0:32,Item:64/?UI>>).
-%% @spec (This::wxTreeCtrl(), Item::wxTreeItemId()) -> wxTreeItemId()
+%% @spec (This::wxTreeCtrl(), Item::integer()) -> integer()
%% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxtreectrl.html#wxtreectrlgetlastchild">external documentation</a>.
-getLastChild(#wx_ref{type=ThisT,ref=ThisRef},#wx_ref{type=wxTreeItemId,ref=ItemRef}) ->
+getLastChild(#wx_ref{type=ThisT,ref=ThisRef},Item)
+ when is_integer(Item) ->
?CLASS(ThisT,wxTreeCtrl),
wxe_util:call(?wxTreeCtrl_GetLastChild,
- <<ThisRef:32/?UI,ItemRef:32/?UI>>).
+ <<ThisRef:32/?UI,0:32,Item:64/?UI>>).
-%% @spec (This::wxTreeCtrl(), Item::wxTreeItemId()) -> wxTreeItemId()
+%% @spec (This::wxTreeCtrl(), Item::integer()) -> integer()
%% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxtreectrl.html#wxtreectrlgetnextsibling">external documentation</a>.
-getNextSibling(#wx_ref{type=ThisT,ref=ThisRef},#wx_ref{type=wxTreeItemId,ref=ItemRef}) ->
+getNextSibling(#wx_ref{type=ThisT,ref=ThisRef},Item)
+ when is_integer(Item) ->
?CLASS(ThisT,wxTreeCtrl),
wxe_util:call(?wxTreeCtrl_GetNextSibling,
- <<ThisRef:32/?UI,ItemRef:32/?UI>>).
+ <<ThisRef:32/?UI,0:32,Item:64/?UI>>).
-%% @spec (This::wxTreeCtrl(), Item::wxTreeItemId()) -> wxTreeItemId()
+%% @spec (This::wxTreeCtrl(), Item::integer()) -> integer()
%% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxtreectrl.html#wxtreectrlgetnextvisible">external documentation</a>.
-getNextVisible(#wx_ref{type=ThisT,ref=ThisRef},#wx_ref{type=wxTreeItemId,ref=ItemRef}) ->
+getNextVisible(#wx_ref{type=ThisT,ref=ThisRef},Item)
+ when is_integer(Item) ->
?CLASS(ThisT,wxTreeCtrl),
wxe_util:call(?wxTreeCtrl_GetNextVisible,
- <<ThisRef:32/?UI,ItemRef:32/?UI>>).
+ <<ThisRef:32/?UI,0:32,Item:64/?UI>>).
-%% @spec (This::wxTreeCtrl(), Item::wxTreeItemId()) -> wxTreeItemId()
+%% @spec (This::wxTreeCtrl(), Item::integer()) -> integer()
%% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxtreectrl.html#wxtreectrlgetitemparent">external documentation</a>.
-getItemParent(#wx_ref{type=ThisT,ref=ThisRef},#wx_ref{type=wxTreeItemId,ref=ItemRef}) ->
+getItemParent(#wx_ref{type=ThisT,ref=ThisRef},Item)
+ when is_integer(Item) ->
?CLASS(ThisT,wxTreeCtrl),
wxe_util:call(?wxTreeCtrl_GetItemParent,
- <<ThisRef:32/?UI,ItemRef:32/?UI>>).
+ <<ThisRef:32/?UI,0:32,Item:64/?UI>>).
-%% @spec (This::wxTreeCtrl(), Item::wxTreeItemId()) -> wxTreeItemId()
+%% @spec (This::wxTreeCtrl(), Item::integer()) -> integer()
%% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxtreectrl.html#wxtreectrlgetprevsibling">external documentation</a>.
-getPrevSibling(#wx_ref{type=ThisT,ref=ThisRef},#wx_ref{type=wxTreeItemId,ref=ItemRef}) ->
+getPrevSibling(#wx_ref{type=ThisT,ref=ThisRef},Item)
+ when is_integer(Item) ->
?CLASS(ThisT,wxTreeCtrl),
wxe_util:call(?wxTreeCtrl_GetPrevSibling,
- <<ThisRef:32/?UI,ItemRef:32/?UI>>).
+ <<ThisRef:32/?UI,0:32,Item:64/?UI>>).
-%% @spec (This::wxTreeCtrl(), Item::wxTreeItemId()) -> wxTreeItemId()
+%% @spec (This::wxTreeCtrl(), Item::integer()) -> integer()
%% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxtreectrl.html#wxtreectrlgetprevvisible">external documentation</a>.
-getPrevVisible(#wx_ref{type=ThisT,ref=ThisRef},#wx_ref{type=wxTreeItemId,ref=ItemRef}) ->
+getPrevVisible(#wx_ref{type=ThisT,ref=ThisRef},Item)
+ when is_integer(Item) ->
?CLASS(ThisT,wxTreeCtrl),
wxe_util:call(?wxTreeCtrl_GetPrevVisible,
- <<ThisRef:32/?UI,ItemRef:32/?UI>>).
+ <<ThisRef:32/?UI,0:32,Item:64/?UI>>).
-%% @spec (This::wxTreeCtrl()) -> wxTreeItemId()
+%% @spec (This::wxTreeCtrl()) -> integer()
%% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxtreectrl.html#wxtreectrlgetrootitem">external documentation</a>.
getRootItem(#wx_ref{type=ThisT,ref=ThisRef}) ->
?CLASS(ThisT,wxTreeCtrl),
wxe_util:call(?wxTreeCtrl_GetRootItem,
<<ThisRef:32/?UI>>).
-%% @spec (This::wxTreeCtrl()) -> wxTreeItemId()
+%% @spec (This::wxTreeCtrl()) -> integer()
%% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxtreectrl.html#wxtreectrlgetselection">external documentation</a>.
getSelection(#wx_ref{type=ThisT,ref=ThisRef}) ->
?CLASS(ThisT,wxTreeCtrl),
wxe_util:call(?wxTreeCtrl_GetSelection,
<<ThisRef:32/?UI>>).
-%% @spec (This::wxTreeCtrl()) -> {integer(),Val::[wxTreeItemId()]}
+%% @spec (This::wxTreeCtrl()) -> {integer(),Val::[integer()]}
%% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxtreectrl.html#wxtreectrlgetselections">external documentation</a>.
getSelections(#wx_ref{type=ThisT,ref=ThisRef}) ->
?CLASS(ThisT,wxTreeCtrl),
@@ -446,7 +484,7 @@ getStateImageList(#wx_ref{type=ThisT,ref=ThisRef}) ->
wxe_util:call(?wxTreeCtrl_GetStateImageList,
<<ThisRef:32/?UI>>).
-%% @spec (This::wxTreeCtrl(), Point::{X::integer(),Y::integer()}) -> wxTreeItemId()
+%% @spec (This::wxTreeCtrl(), Point::{X::integer(),Y::integer()}) -> integer()
%% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxtreectrl.html#wxtreectrlhittest">external documentation</a>.
hitTest(#wx_ref{type=ThisT,ref=ThisRef},{PointX,PointY})
when is_integer(PointX),is_integer(PointY) ->
@@ -454,35 +492,17 @@ hitTest(#wx_ref{type=ThisT,ref=ThisRef},{PointX,PointY})
wxe_util:call(?wxTreeCtrl_HitTest,
<<ThisRef:32/?UI,PointX:32/?UI,PointY:32/?UI>>).
-%% @spec (This::wxTreeCtrl(),Parent::wxTreeItemId(),X::integer()|wxTreeItemId(),Text::string()) -> wxTreeItemId()
-%% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxtreectrl.html#wxtreectrlinsertitem">external documentation</a>.
-%% <br /> Alternatives:
-%% <p><c>
-%% insertItem(This::wxTreeCtrl(), Parent::wxTreeItemId(), Pos::integer(), Text::string()) -> insertItem(This,Parent,Pos,Text, []) </c></p>
-%% <p><c>
-%% insertItem(This::wxTreeCtrl(), Parent::wxTreeItemId(), IdPrevious::wxTreeItemId(), Text::string()) -> insertItem(This,Parent,IdPrevious,Text, []) </c></p>
-
+%% @spec (This::wxTreeCtrl(), Parent::integer(), Pos::integer(), Text::string()) -> integer()
+%% @equiv insertItem(This,Parent,Pos,Text, [])
insertItem(This,Parent,Pos,Text)
- when is_record(This, wx_ref),is_record(Parent, wx_ref),is_integer(Pos),is_list(Text) ->
- insertItem(This,Parent,Pos,Text, []);
-
-insertItem(This,Parent,IdPrevious,Text)
- when is_record(This, wx_ref),is_record(Parent, wx_ref),is_record(IdPrevious, wx_ref),is_list(Text) ->
- insertItem(This,Parent,IdPrevious,Text, []).
+ when is_record(This, wx_ref),is_integer(Parent),is_integer(Pos),is_list(Text) ->
+ insertItem(This,Parent,Pos,Text, []).
-%% @spec (This::wxTreeCtrl(),Parent::wxTreeItemId(),X::integer()|wxTreeItemId(),Text::string(),[Option]) -> wxTreeItemId()
+%% @spec (This::wxTreeCtrl(), Parent::integer(), Pos::integer(), Text::string(), [Option]) -> integer()
+%% Option = {image, integer()} | {selImage, integer()} | {data, term()}
%% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxtreectrl.html#wxtreectrlinsertitem">external documentation</a>.
-%% <br /> Alternatives:
-%% <p><c>
-%% insertItem(This::wxTreeCtrl(), Parent::wxTreeItemId(), Pos::integer(), Text::string(), [Option]) -> wxTreeItemId() </c>
-%%<br /> Option = {image, integer()} | {selImage, integer()} | {data, term()}
-%% </p>
-%% <p><c>
-%% insertItem(This::wxTreeCtrl(), Parent::wxTreeItemId(), IdPrevious::wxTreeItemId(), Text::string(), [Option]) -> wxTreeItemId() </c>
-%%<br /> Option = {image, integer()} | {selectedImage, integer()} | {data, term()}
-%% </p>
-insertItem(#wx_ref{type=ThisT,ref=ThisRef},#wx_ref{type=wxTreeItemId,ref=ParentRef},Pos,Text, Options)
- when is_integer(Pos),is_list(Text),is_list(Options) ->
+insertItem(#wx_ref{type=ThisT,ref=ThisRef},Parent,Pos,Text, Options)
+ when is_integer(Parent),is_integer(Pos),is_list(Text),is_list(Options) ->
?CLASS(ThisT,wxTreeCtrl),
Text_UC = unicode:characters_to_binary([Text,0]),
MOpts = fun({image, Image}, Acc) -> [<<1:32/?UI,Image:32/?UI>>|Acc];
@@ -490,66 +510,60 @@ insertItem(#wx_ref{type=ThisT,ref=ThisRef},#wx_ref{type=wxTreeItemId,ref=ParentR
({data, Data}, Acc) -> wxe_util:send_bin(term_to_binary(Data)),[<<3:32/?UI,0:32>>|Acc];
(BadOpt, _) -> erlang:error({badoption, BadOpt}) end,
BinOpt = list_to_binary(lists:foldl(MOpts, [<<0:32>>], Options)),
- wxe_util:call(?wxTreeCtrl_InsertItem_4_0,
- <<ThisRef:32/?UI,ParentRef:32/?UI,Pos:32/?UI,(byte_size(Text_UC)):32/?UI,(Text_UC)/binary, 0:(((8- ((0+byte_size(Text_UC)) band 16#7)) band 16#7))/unit:8, BinOpt/binary>>);
-insertItem(#wx_ref{type=ThisT,ref=ThisRef},#wx_ref{type=wxTreeItemId,ref=ParentRef},#wx_ref{type=wxTreeItemId,ref=IdPreviousRef},Text, Options)
- when is_list(Text),is_list(Options) ->
- ?CLASS(ThisT,wxTreeCtrl),
- Text_UC = unicode:characters_to_binary([Text,0]),
- MOpts = fun({image, Image}, Acc) -> [<<1:32/?UI,Image:32/?UI>>|Acc];
- ({selectedImage, SelectedImage}, Acc) -> [<<2:32/?UI,SelectedImage:32/?UI>>|Acc];
- ({data, Data}, Acc) -> wxe_util:send_bin(term_to_binary(Data)),[<<3:32/?UI,0:32>>|Acc];
- (BadOpt, _) -> erlang:error({badoption, BadOpt}) end,
- BinOpt = list_to_binary(lists:foldl(MOpts, [<<0:32>>], Options)),
- wxe_util:call(?wxTreeCtrl_InsertItem_4_1,
- <<ThisRef:32/?UI,ParentRef:32/?UI,IdPreviousRef:32/?UI,(byte_size(Text_UC)):32/?UI,(Text_UC)/binary, 0:(((8- ((0+byte_size(Text_UC)) band 16#7)) band 16#7))/unit:8, BinOpt/binary>>).
+ wxe_util:call(?wxTreeCtrl_InsertItem,
+ <<ThisRef:32/?UI,0:32,Parent:64/?UI,Pos:32/?UI,(byte_size(Text_UC)):32/?UI,(Text_UC)/binary, 0:(((8- ((0+byte_size(Text_UC)) band 16#7)) band 16#7))/unit:8, BinOpt/binary>>).
-%% @spec (This::wxTreeCtrl(), Item::wxTreeItemId()) -> bool()
+%% @spec (This::wxTreeCtrl(), Item::integer()) -> bool()
%% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxtreectrl.html#wxtreectrlisbold">external documentation</a>.
-isBold(#wx_ref{type=ThisT,ref=ThisRef},#wx_ref{type=wxTreeItemId,ref=ItemRef}) ->
+isBold(#wx_ref{type=ThisT,ref=ThisRef},Item)
+ when is_integer(Item) ->
?CLASS(ThisT,wxTreeCtrl),
wxe_util:call(?wxTreeCtrl_IsBold,
- <<ThisRef:32/?UI,ItemRef:32/?UI>>).
+ <<ThisRef:32/?UI,0:32,Item:64/?UI>>).
-%% @spec (This::wxTreeCtrl(), Item::wxTreeItemId()) -> bool()
+%% @spec (This::wxTreeCtrl(), Item::integer()) -> bool()
%% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxtreectrl.html#wxtreectrlisexpanded">external documentation</a>.
-isExpanded(#wx_ref{type=ThisT,ref=ThisRef},#wx_ref{type=wxTreeItemId,ref=ItemRef}) ->
+isExpanded(#wx_ref{type=ThisT,ref=ThisRef},Item)
+ when is_integer(Item) ->
?CLASS(ThisT,wxTreeCtrl),
wxe_util:call(?wxTreeCtrl_IsExpanded,
- <<ThisRef:32/?UI,ItemRef:32/?UI>>).
+ <<ThisRef:32/?UI,0:32,Item:64/?UI>>).
-%% @spec (This::wxTreeCtrl(), Item::wxTreeItemId()) -> bool()
+%% @spec (This::wxTreeCtrl(), Item::integer()) -> bool()
%% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxtreectrl.html#wxtreectrlisselected">external documentation</a>.
-isSelected(#wx_ref{type=ThisT,ref=ThisRef},#wx_ref{type=wxTreeItemId,ref=ItemRef}) ->
+isSelected(#wx_ref{type=ThisT,ref=ThisRef},Item)
+ when is_integer(Item) ->
?CLASS(ThisT,wxTreeCtrl),
wxe_util:call(?wxTreeCtrl_IsSelected,
- <<ThisRef:32/?UI,ItemRef:32/?UI>>).
+ <<ThisRef:32/?UI,0:32,Item:64/?UI>>).
-%% @spec (This::wxTreeCtrl(), Item::wxTreeItemId()) -> bool()
+%% @spec (This::wxTreeCtrl(), Item::integer()) -> bool()
%% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxtreectrl.html#wxtreectrlisvisible">external documentation</a>.
-isVisible(#wx_ref{type=ThisT,ref=ThisRef},#wx_ref{type=wxTreeItemId,ref=ItemRef}) ->
+isVisible(#wx_ref{type=ThisT,ref=ThisRef},Item)
+ when is_integer(Item) ->
?CLASS(ThisT,wxTreeCtrl),
wxe_util:call(?wxTreeCtrl_IsVisible,
- <<ThisRef:32/?UI,ItemRef:32/?UI>>).
+ <<ThisRef:32/?UI,0:32,Item:64/?UI>>).
-%% @spec (This::wxTreeCtrl(), Item::wxTreeItemId()) -> bool()
+%% @spec (This::wxTreeCtrl(), Item::integer()) -> bool()
%% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxtreectrl.html#wxtreectrlitemhaschildren">external documentation</a>.
-itemHasChildren(#wx_ref{type=ThisT,ref=ThisRef},#wx_ref{type=wxTreeItemId,ref=ItemRef}) ->
+itemHasChildren(#wx_ref{type=ThisT,ref=ThisRef},Item)
+ when is_integer(Item) ->
?CLASS(ThisT,wxTreeCtrl),
wxe_util:call(?wxTreeCtrl_ItemHasChildren,
- <<ThisRef:32/?UI,ItemRef:32/?UI>>).
+ <<ThisRef:32/?UI,0:32,Item:64/?UI>>).
-%% @spec (This::wxTreeCtrl(), Parent::wxTreeItemId(), Text::string()) -> wxTreeItemId()
+%% @spec (This::wxTreeCtrl(), Parent::integer(), Text::string()) -> integer()
%% @equiv prependItem(This,Parent,Text, [])
prependItem(This,Parent,Text)
- when is_record(This, wx_ref),is_record(Parent, wx_ref),is_list(Text) ->
+ when is_record(This, wx_ref),is_integer(Parent),is_list(Text) ->
prependItem(This,Parent,Text, []).
-%% @spec (This::wxTreeCtrl(), Parent::wxTreeItemId(), Text::string(), [Option]) -> wxTreeItemId()
+%% @spec (This::wxTreeCtrl(), Parent::integer(), Text::string(), [Option]) -> integer()
%% Option = {image, integer()} | {selectedImage, integer()} | {data, term()}
%% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxtreectrl.html#wxtreectrlprependitem">external documentation</a>.
-prependItem(#wx_ref{type=ThisT,ref=ThisRef},#wx_ref{type=wxTreeItemId,ref=ParentRef},Text, Options)
- when is_list(Text),is_list(Options) ->
+prependItem(#wx_ref{type=ThisT,ref=ThisRef},Parent,Text, Options)
+ when is_integer(Parent),is_list(Text),is_list(Options) ->
?CLASS(ThisT,wxTreeCtrl),
Text_UC = unicode:characters_to_binary([Text,0]),
MOpts = fun({image, Image}, Acc) -> [<<1:32/?UI,Image:32/?UI>>|Acc];
@@ -558,33 +572,35 @@ prependItem(#wx_ref{type=ThisT,ref=ThisRef},#wx_ref{type=wxTreeItemId,ref=Parent
(BadOpt, _) -> erlang:error({badoption, BadOpt}) end,
BinOpt = list_to_binary(lists:foldl(MOpts, [<<0:32>>], Options)),
wxe_util:call(?wxTreeCtrl_PrependItem,
- <<ThisRef:32/?UI,ParentRef:32/?UI,(byte_size(Text_UC)):32/?UI,(Text_UC)/binary, 0:(((8- ((4+byte_size(Text_UC)) band 16#7)) band 16#7))/unit:8, BinOpt/binary>>).
+ <<ThisRef:32/?UI,0:32,Parent:64/?UI,(byte_size(Text_UC)):32/?UI,(Text_UC)/binary, 0:(((8- ((4+byte_size(Text_UC)) band 16#7)) band 16#7))/unit:8, BinOpt/binary>>).
-%% @spec (This::wxTreeCtrl(), Item::wxTreeItemId()) -> ok
+%% @spec (This::wxTreeCtrl(), Item::integer()) -> ok
%% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxtreectrl.html#wxtreectrlscrollto">external documentation</a>.
-scrollTo(#wx_ref{type=ThisT,ref=ThisRef},#wx_ref{type=wxTreeItemId,ref=ItemRef}) ->
+scrollTo(#wx_ref{type=ThisT,ref=ThisRef},Item)
+ when is_integer(Item) ->
?CLASS(ThisT,wxTreeCtrl),
wxe_util:cast(?wxTreeCtrl_ScrollTo,
- <<ThisRef:32/?UI,ItemRef:32/?UI>>).
+ <<ThisRef:32/?UI,0:32,Item:64/?UI>>).
-%% @spec (This::wxTreeCtrl(), Item::wxTreeItemId()) -> ok
+%% @spec (This::wxTreeCtrl(), Item::integer()) -> ok
%% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxtreectrl.html#wxtreectrlselectitem">external documentation</a>.
-selectItem(#wx_ref{type=ThisT,ref=ThisRef},#wx_ref{type=wxTreeItemId,ref=ItemRef}) ->
+selectItem(#wx_ref{type=ThisT,ref=ThisRef},Item)
+ when is_integer(Item) ->
?CLASS(ThisT,wxTreeCtrl),
wxe_util:cast(?wxTreeCtrl_SelectItem_1,
- <<ThisRef:32/?UI,ItemRef:32/?UI>>).
+ <<ThisRef:32/?UI,0:32,Item:64/?UI>>).
-%% @spec (This::wxTreeCtrl(), Item::wxTreeItemId(), [Option]) -> ok
+%% @spec (This::wxTreeCtrl(), Item::integer(), [Option]) -> ok
%% Option = {select, bool()}
%% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxtreectrl.html#wxtreectrlselectitem">external documentation</a>.
-selectItem(#wx_ref{type=ThisT,ref=ThisRef},#wx_ref{type=wxTreeItemId,ref=ItemRef}, Options)
- when is_list(Options) ->
+selectItem(#wx_ref{type=ThisT,ref=ThisRef},Item, Options)
+ when is_integer(Item),is_list(Options) ->
?CLASS(ThisT,wxTreeCtrl),
MOpts = fun({select, Select}, Acc) -> [<<1:32/?UI,(wxe_util:from_bool(Select)):32/?UI>>|Acc];
(BadOpt, _) -> erlang:error({badoption, BadOpt}) end,
BinOpt = list_to_binary(lists:foldl(MOpts, [<<0:32>>], Options)),
wxe_util:cast(?wxTreeCtrl_SelectItem_2,
- <<ThisRef:32/?UI,ItemRef:32/?UI, BinOpt/binary>>).
+ <<ThisRef:32/?UI,0:32,Item:64/?UI, BinOpt/binary>>).
%% @spec (This::wxTreeCtrl(), Indent::integer()) -> ok
%% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxtreectrl.html#wxtreectrlsetindent">external documentation</a>.
@@ -602,122 +618,124 @@ setImageList(#wx_ref{type=ThisT,ref=ThisRef},#wx_ref{type=ImageListT,ref=ImageLi
wxe_util:cast(?wxTreeCtrl_SetImageList,
<<ThisRef:32/?UI,ImageListRef:32/?UI>>).
-%% @spec (This::wxTreeCtrl(), Item::wxTreeItemId(), Col::wx:colour()) -> ok
+%% @spec (This::wxTreeCtrl(), Item::integer(), Col::wx:colour()) -> ok
%% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxtreectrl.html#wxtreectrlsetitembackgroundcolour">external documentation</a>.
-setItemBackgroundColour(#wx_ref{type=ThisT,ref=ThisRef},#wx_ref{type=wxTreeItemId,ref=ItemRef},Col)
- when tuple_size(Col) =:= 3; tuple_size(Col) =:= 4 ->
+setItemBackgroundColour(#wx_ref{type=ThisT,ref=ThisRef},Item,Col)
+ when is_integer(Item),tuple_size(Col) =:= 3; tuple_size(Col) =:= 4 ->
?CLASS(ThisT,wxTreeCtrl),
wxe_util:cast(?wxTreeCtrl_SetItemBackgroundColour,
- <<ThisRef:32/?UI,ItemRef:32/?UI,(wxe_util:colour_bin(Col)):16/binary>>).
+ <<ThisRef:32/?UI,0:32,Item:64/?UI,(wxe_util:colour_bin(Col)):16/binary>>).
-%% @spec (This::wxTreeCtrl(), Item::wxTreeItemId()) -> ok
+%% @spec (This::wxTreeCtrl(), Item::integer()) -> ok
%% @equiv setItemBold(This,Item, [])
setItemBold(This,Item)
- when is_record(This, wx_ref),is_record(Item, wx_ref) ->
+ when is_record(This, wx_ref),is_integer(Item) ->
setItemBold(This,Item, []).
-%% @spec (This::wxTreeCtrl(), Item::wxTreeItemId(), [Option]) -> ok
+%% @spec (This::wxTreeCtrl(), Item::integer(), [Option]) -> ok
%% Option = {bold, bool()}
%% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxtreectrl.html#wxtreectrlsetitembold">external documentation</a>.
-setItemBold(#wx_ref{type=ThisT,ref=ThisRef},#wx_ref{type=wxTreeItemId,ref=ItemRef}, Options)
- when is_list(Options) ->
+setItemBold(#wx_ref{type=ThisT,ref=ThisRef},Item, Options)
+ when is_integer(Item),is_list(Options) ->
?CLASS(ThisT,wxTreeCtrl),
MOpts = fun({bold, Bold}, Acc) -> [<<1:32/?UI,(wxe_util:from_bool(Bold)):32/?UI>>|Acc];
(BadOpt, _) -> erlang:error({badoption, BadOpt}) end,
BinOpt = list_to_binary(lists:foldl(MOpts, [<<0:32>>], Options)),
wxe_util:cast(?wxTreeCtrl_SetItemBold,
- <<ThisRef:32/?UI,ItemRef:32/?UI, BinOpt/binary>>).
+ <<ThisRef:32/?UI,0:32,Item:64/?UI, BinOpt/binary>>).
-%% @spec (This::wxTreeCtrl(), Item::wxTreeItemId(), Data::term()) -> ok
+%% @spec (This::wxTreeCtrl(), Item::integer(), Data::term()) -> ok
%% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxtreectrl.html#wxtreectrlsetitemdata">external documentation</a>.
-setItemData(#wx_ref{type=ThisT,ref=ThisRef},#wx_ref{type=wxTreeItemId,ref=ItemRef},Data) ->
+setItemData(#wx_ref{type=ThisT,ref=ThisRef},Item,Data)
+ when is_integer(Item) ->
?CLASS(ThisT,wxTreeCtrl),
wxe_util:send_bin(term_to_binary(Data)),
wxe_util:cast(?wxTreeCtrl_SetItemData,
- <<ThisRef:32/?UI,ItemRef:32/?UI>>).
+ <<ThisRef:32/?UI,0:32,Item:64/?UI>>).
-%% @spec (This::wxTreeCtrl(), Item::wxTreeItemId()) -> ok
+%% @spec (This::wxTreeCtrl(), Item::integer()) -> ok
%% @equiv setItemDropHighlight(This,Item, [])
setItemDropHighlight(This,Item)
- when is_record(This, wx_ref),is_record(Item, wx_ref) ->
+ when is_record(This, wx_ref),is_integer(Item) ->
setItemDropHighlight(This,Item, []).
-%% @spec (This::wxTreeCtrl(), Item::wxTreeItemId(), [Option]) -> ok
+%% @spec (This::wxTreeCtrl(), Item::integer(), [Option]) -> ok
%% Option = {highlight, bool()}
%% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxtreectrl.html#wxtreectrlsetitemdrophighlight">external documentation</a>.
-setItemDropHighlight(#wx_ref{type=ThisT,ref=ThisRef},#wx_ref{type=wxTreeItemId,ref=ItemRef}, Options)
- when is_list(Options) ->
+setItemDropHighlight(#wx_ref{type=ThisT,ref=ThisRef},Item, Options)
+ when is_integer(Item),is_list(Options) ->
?CLASS(ThisT,wxTreeCtrl),
MOpts = fun({highlight, Highlight}, Acc) -> [<<1:32/?UI,(wxe_util:from_bool(Highlight)):32/?UI>>|Acc];
(BadOpt, _) -> erlang:error({badoption, BadOpt}) end,
BinOpt = list_to_binary(lists:foldl(MOpts, [<<0:32>>], Options)),
wxe_util:cast(?wxTreeCtrl_SetItemDropHighlight,
- <<ThisRef:32/?UI,ItemRef:32/?UI, BinOpt/binary>>).
+ <<ThisRef:32/?UI,0:32,Item:64/?UI, BinOpt/binary>>).
-%% @spec (This::wxTreeCtrl(), Item::wxTreeItemId(), Font::wxFont:wxFont()) -> ok
+%% @spec (This::wxTreeCtrl(), Item::integer(), Font::wxFont:wxFont()) -> ok
%% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxtreectrl.html#wxtreectrlsetitemfont">external documentation</a>.
-setItemFont(#wx_ref{type=ThisT,ref=ThisRef},#wx_ref{type=wxTreeItemId,ref=ItemRef},#wx_ref{type=FontT,ref=FontRef}) ->
+setItemFont(#wx_ref{type=ThisT,ref=ThisRef},Item,#wx_ref{type=FontT,ref=FontRef})
+ when is_integer(Item) ->
?CLASS(ThisT,wxTreeCtrl),
?CLASS(FontT,wxFont),
wxe_util:cast(?wxTreeCtrl_SetItemFont,
- <<ThisRef:32/?UI,ItemRef:32/?UI,FontRef:32/?UI>>).
+ <<ThisRef:32/?UI,0:32,Item:64/?UI,FontRef:32/?UI>>).
-%% @spec (This::wxTreeCtrl(), Item::wxTreeItemId()) -> ok
+%% @spec (This::wxTreeCtrl(), Item::integer()) -> ok
%% @equiv setItemHasChildren(This,Item, [])
setItemHasChildren(This,Item)
- when is_record(This, wx_ref),is_record(Item, wx_ref) ->
+ when is_record(This, wx_ref),is_integer(Item) ->
setItemHasChildren(This,Item, []).
-%% @spec (This::wxTreeCtrl(), Item::wxTreeItemId(), [Option]) -> ok
+%% @spec (This::wxTreeCtrl(), Item::integer(), [Option]) -> ok
%% Option = {has, bool()}
%% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxtreectrl.html#wxtreectrlsetitemhaschildren">external documentation</a>.
-setItemHasChildren(#wx_ref{type=ThisT,ref=ThisRef},#wx_ref{type=wxTreeItemId,ref=ItemRef}, Options)
- when is_list(Options) ->
+setItemHasChildren(#wx_ref{type=ThisT,ref=ThisRef},Item, Options)
+ when is_integer(Item),is_list(Options) ->
?CLASS(ThisT,wxTreeCtrl),
MOpts = fun({has, Has}, Acc) -> [<<1:32/?UI,(wxe_util:from_bool(Has)):32/?UI>>|Acc];
(BadOpt, _) -> erlang:error({badoption, BadOpt}) end,
BinOpt = list_to_binary(lists:foldl(MOpts, [<<0:32>>], Options)),
wxe_util:cast(?wxTreeCtrl_SetItemHasChildren,
- <<ThisRef:32/?UI,ItemRef:32/?UI, BinOpt/binary>>).
+ <<ThisRef:32/?UI,0:32,Item:64/?UI, BinOpt/binary>>).
-%% @spec (This::wxTreeCtrl(), Item::wxTreeItemId(), Image::integer()) -> ok
+%% @spec (This::wxTreeCtrl(), Item::integer(), Image::integer()) -> ok
%% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxtreectrl.html#wxtreectrlsetitemimage">external documentation</a>.
-setItemImage(#wx_ref{type=ThisT,ref=ThisRef},#wx_ref{type=wxTreeItemId,ref=ItemRef},Image)
- when is_integer(Image) ->
+setItemImage(#wx_ref{type=ThisT,ref=ThisRef},Item,Image)
+ when is_integer(Item),is_integer(Image) ->
?CLASS(ThisT,wxTreeCtrl),
wxe_util:cast(?wxTreeCtrl_SetItemImage_2,
- <<ThisRef:32/?UI,ItemRef:32/?UI,Image:32/?UI>>).
+ <<ThisRef:32/?UI,0:32,Item:64/?UI,Image:32/?UI>>).
-%% @spec (This::wxTreeCtrl(), Item::wxTreeItemId(), Image::integer(), [Option]) -> ok
+%% @spec (This::wxTreeCtrl(), Item::integer(), Image::integer(), [Option]) -> ok
%% Option = {which, WxTreeItemIcon}
%% WxTreeItemIcon = integer()
%% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxtreectrl.html#wxtreectrlsetitemimage">external documentation</a>.
%%<br /> WxTreeItemIcon is one of ?wxTreeItemIcon_Normal | ?wxTreeItemIcon_Selected | ?wxTreeItemIcon_Expanded | ?wxTreeItemIcon_SelectedExpanded | ?wxTreeItemIcon_Max
-setItemImage(#wx_ref{type=ThisT,ref=ThisRef},#wx_ref{type=wxTreeItemId,ref=ItemRef},Image, Options)
- when is_integer(Image),is_list(Options) ->
+setItemImage(#wx_ref{type=ThisT,ref=ThisRef},Item,Image, Options)
+ when is_integer(Item),is_integer(Image),is_list(Options) ->
?CLASS(ThisT,wxTreeCtrl),
MOpts = fun({which, Which}, Acc) -> [<<1:32/?UI,Which:32/?UI>>|Acc];
(BadOpt, _) -> erlang:error({badoption, BadOpt}) end,
BinOpt = list_to_binary(lists:foldl(MOpts, [<<0:32>>], Options)),
wxe_util:cast(?wxTreeCtrl_SetItemImage_3,
- <<ThisRef:32/?UI,ItemRef:32/?UI,Image:32/?UI, 0:32,BinOpt/binary>>).
+ <<ThisRef:32/?UI,0:32,Item:64/?UI,Image:32/?UI, 0:32,BinOpt/binary>>).
-%% @spec (This::wxTreeCtrl(), Item::wxTreeItemId(), Text::string()) -> ok
+%% @spec (This::wxTreeCtrl(), Item::integer(), Text::string()) -> ok
%% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxtreectrl.html#wxtreectrlsetitemtext">external documentation</a>.
-setItemText(#wx_ref{type=ThisT,ref=ThisRef},#wx_ref{type=wxTreeItemId,ref=ItemRef},Text)
- when is_list(Text) ->
+setItemText(#wx_ref{type=ThisT,ref=ThisRef},Item,Text)
+ when is_integer(Item),is_list(Text) ->
?CLASS(ThisT,wxTreeCtrl),
Text_UC = unicode:characters_to_binary([Text,0]),
wxe_util:cast(?wxTreeCtrl_SetItemText,
- <<ThisRef:32/?UI,ItemRef:32/?UI,(byte_size(Text_UC)):32/?UI,(Text_UC)/binary, 0:(((8- ((4+byte_size(Text_UC)) band 16#7)) band 16#7))/unit:8>>).
+ <<ThisRef:32/?UI,0:32,Item:64/?UI,(byte_size(Text_UC)):32/?UI,(Text_UC)/binary, 0:(((8- ((4+byte_size(Text_UC)) band 16#7)) band 16#7))/unit:8>>).
-%% @spec (This::wxTreeCtrl(), Item::wxTreeItemId(), Col::wx:colour()) -> ok
+%% @spec (This::wxTreeCtrl(), Item::integer(), Col::wx:colour()) -> ok
%% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxtreectrl.html#wxtreectrlsetitemtextcolour">external documentation</a>.
-setItemTextColour(#wx_ref{type=ThisT,ref=ThisRef},#wx_ref{type=wxTreeItemId,ref=ItemRef},Col)
- when tuple_size(Col) =:= 3; tuple_size(Col) =:= 4 ->
+setItemTextColour(#wx_ref{type=ThisT,ref=ThisRef},Item,Col)
+ when is_integer(Item),tuple_size(Col) =:= 3; tuple_size(Col) =:= 4 ->
?CLASS(ThisT,wxTreeCtrl),
wxe_util:cast(?wxTreeCtrl_SetItemTextColour,
- <<ThisRef:32/?UI,ItemRef:32/?UI,(wxe_util:colour_bin(Col)):16/binary>>).
+ <<ThisRef:32/?UI,0:32,Item:64/?UI,(wxe_util:colour_bin(Col)):16/binary>>).
%% @spec (This::wxTreeCtrl(), ImageList::wxImageList:wxImageList()) -> ok
%% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxtreectrl.html#wxtreectrlsetstateimagelist">external documentation</a>.
@@ -735,26 +753,29 @@ setWindowStyle(#wx_ref{type=ThisT,ref=ThisRef},Styles)
wxe_util:cast(?wxTreeCtrl_SetWindowStyle,
<<ThisRef:32/?UI,Styles:32/?UI>>).
-%% @spec (This::wxTreeCtrl(), Item::wxTreeItemId()) -> ok
+%% @spec (This::wxTreeCtrl(), Item::integer()) -> ok
%% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxtreectrl.html#wxtreectrlsortchildren">external documentation</a>.
-sortChildren(#wx_ref{type=ThisT,ref=ThisRef},#wx_ref{type=wxTreeItemId,ref=ItemRef}) ->
+sortChildren(#wx_ref{type=ThisT,ref=ThisRef},Item)
+ when is_integer(Item) ->
?CLASS(ThisT,wxTreeCtrl),
wxe_util:cast(?wxTreeCtrl_SortChildren,
- <<ThisRef:32/?UI,ItemRef:32/?UI>>).
+ <<ThisRef:32/?UI,0:32,Item:64/?UI>>).
-%% @spec (This::wxTreeCtrl(), Item::wxTreeItemId()) -> ok
+%% @spec (This::wxTreeCtrl(), Item::integer()) -> ok
%% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxtreectrl.html#wxtreectrltoggle">external documentation</a>.
-toggle(#wx_ref{type=ThisT,ref=ThisRef},#wx_ref{type=wxTreeItemId,ref=ItemRef}) ->
+toggle(#wx_ref{type=ThisT,ref=ThisRef},Item)
+ when is_integer(Item) ->
?CLASS(ThisT,wxTreeCtrl),
wxe_util:cast(?wxTreeCtrl_Toggle,
- <<ThisRef:32/?UI,ItemRef:32/?UI>>).
+ <<ThisRef:32/?UI,0:32,Item:64/?UI>>).
-%% @spec (This::wxTreeCtrl(), Item::wxTreeItemId()) -> ok
+%% @spec (This::wxTreeCtrl(), Item::integer()) -> ok
%% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxtreectrl.html#wxtreectrltoggleitemselection">external documentation</a>.
-toggleItemSelection(#wx_ref{type=ThisT,ref=ThisRef},#wx_ref{type=wxTreeItemId,ref=ItemRef}) ->
+toggleItemSelection(#wx_ref{type=ThisT,ref=ThisRef},Item)
+ when is_integer(Item) ->
?CLASS(ThisT,wxTreeCtrl),
wxe_util:cast(?wxTreeCtrl_ToggleItemSelection,
- <<ThisRef:32/?UI,ItemRef:32/?UI>>).
+ <<ThisRef:32/?UI,0:32,Item:64/?UI>>).
%% @spec (This::wxTreeCtrl()) -> ok
%% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxtreectrl.html#wxtreectrlunselect">external documentation</a>.
@@ -770,25 +791,26 @@ unselectAll(#wx_ref{type=ThisT,ref=ThisRef}) ->
wxe_util:cast(?wxTreeCtrl_UnselectAll,
<<ThisRef:32/?UI>>).
-%% @spec (This::wxTreeCtrl(), Item::wxTreeItemId()) -> ok
+%% @spec (This::wxTreeCtrl(), Item::integer()) -> ok
%% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxtreectrl.html#wxtreectrlunselectitem">external documentation</a>.
-unselectItem(#wx_ref{type=ThisT,ref=ThisRef},#wx_ref{type=wxTreeItemId,ref=ItemRef}) ->
+unselectItem(#wx_ref{type=ThisT,ref=ThisRef},Item)
+ when is_integer(Item) ->
?CLASS(ThisT,wxTreeCtrl),
wxe_util:cast(?wxTreeCtrl_UnselectItem,
- <<ThisRef:32/?UI,ItemRef:32/?UI>>).
+ <<ThisRef:32/?UI,0:32,Item:64/?UI>>).
%% @spec (This::wxTreeCtrl()) -> ok
%% @doc Destroys this object, do not use object again
-destroy(Obj=#wx_ref{type=Type}) ->
+destroy(Obj=#wx_ref{type=Type}) ->
?CLASS(Type,wxTreeCtrl),
wxe_util:destroy(?DESTROY_OBJECT,Obj),
ok.
- %% From wxControl
+ %% From wxControl
%% @hidden
setLabel(This,Label) -> wxControl:setLabel(This,Label).
%% @hidden
getLabel(This) -> wxControl:getLabel(This).
- %% From wxWindow
+ %% From wxWindow
%% @hidden
warpPointer(This,X,Y) -> wxWindow:warpPointer(This,X,Y).
%% @hidden
@@ -1133,7 +1155,7 @@ center(This) -> wxWindow:center(This).
captureMouse(This) -> wxWindow:captureMouse(This).
%% @hidden
cacheBestSize(This,Size) -> wxWindow:cacheBestSize(This,Size).
- %% From wxEvtHandler
+ %% From wxEvtHandler
%% @hidden
disconnect(This,EventType, Options) -> wxEvtHandler:disconnect(This,EventType, Options).
%% @hidden
diff --git a/lib/wx/src/gen/wxTreeEvent.erl b/lib/wx/src/gen/wxTreeEvent.erl
index 3f20e79b22..d5379b7abe 100644
--- a/lib/wx/src/gen/wxTreeEvent.erl
+++ b/lib/wx/src/gen/wxTreeEvent.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%
%% This file is generated DO NOT EDIT
@@ -22,7 +22,7 @@
%% <dd><em>command_tree_begin_drag</em>, <em>command_tree_begin_rdrag</em>, <em>command_tree_begin_label_edit</em>, <em>command_tree_end_label_edit</em>, <em>command_tree_delete_item</em>, <em>command_tree_get_info</em>, <em>command_tree_set_info</em>, <em>command_tree_item_expanded</em>, <em>command_tree_item_expanding</em>, <em>command_tree_item_collapsed</em>, <em>command_tree_item_collapsing</em>, <em>command_tree_sel_changed</em>, <em>command_tree_sel_changing</em>, <em>command_tree_key_down</em>, <em>command_tree_item_activated</em>, <em>command_tree_item_right_click</em>, <em>command_tree_item_middle_click</em>, <em>command_tree_end_drag</em>, <em>command_tree_state_image_click</em>, <em>command_tree_item_gettooltip</em>, <em>command_tree_item_menu</em></dd></dl>
%% See also the message variant {@link wxEvtHandler:wxTree(). #wxTree{}} event record type.
%%
-%% <p>This class is derived (and can use functions) from:
+%% <p>This class is derived (and can use functions) from:
%% <br />{@link wxNotifyEvent}
%% <br />{@link wxCommandEvent}
%% <br />{@link wxEvent}
@@ -55,7 +55,7 @@ getKeyCode(#wx_ref{type=ThisT,ref=ThisRef}) ->
wxe_util:call(?wxTreeEvent_GetKeyCode,
<<ThisRef:32/?UI>>).
-%% @spec (This::wxTreeEvent()) -> wxTreeItemId()
+%% @spec (This::wxTreeEvent()) -> integer()
%% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxtreeevent.html#wxtreeeventgetitem">external documentation</a>.
getItem(#wx_ref{type=ThisT,ref=ThisRef}) ->
?CLASS(ThisT,wxTreeEvent),
@@ -76,7 +76,7 @@ getLabel(#wx_ref{type=ThisT,ref=ThisRef}) ->
wxe_util:call(?wxTreeEvent_GetLabel,
<<ThisRef:32/?UI>>).
-%% @spec (This::wxTreeEvent()) -> wxTreeItemId()
+%% @spec (This::wxTreeEvent()) -> integer()
%% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxtreeevent.html#wxtreeeventgetolditem">external documentation</a>.
getOldItem(#wx_ref{type=ThisT,ref=ThisRef}) ->
?CLASS(ThisT,wxTreeEvent),
@@ -106,14 +106,14 @@ setToolTip(#wx_ref{type=ThisT,ref=ThisRef},ToolTip)
wxe_util:cast(?wxTreeEvent_SetToolTip,
<<ThisRef:32/?UI,(byte_size(ToolTip_UC)):32/?UI,(ToolTip_UC)/binary, 0:(((8- ((0+byte_size(ToolTip_UC)) band 16#7)) band 16#7))/unit:8>>).
- %% From wxNotifyEvent
+ %% From wxNotifyEvent
%% @hidden
veto(This) -> wxNotifyEvent:veto(This).
%% @hidden
isAllowed(This) -> wxNotifyEvent:isAllowed(This).
%% @hidden
allow(This) -> wxNotifyEvent:allow(This).
- %% From wxCommandEvent
+ %% From wxCommandEvent
%% @hidden
setString(This,S) -> wxCommandEvent:setString(This,S).
%% @hidden
@@ -132,7 +132,7 @@ getInt(This) -> wxCommandEvent:getInt(This).
getExtraLong(This) -> wxCommandEvent:getExtraLong(This).
%% @hidden
getClientData(This) -> wxCommandEvent:getClientData(This).
- %% From wxEvent
+ %% From wxEvent
%% @hidden
stopPropagation(This) -> wxEvent:stopPropagation(This).
%% @hidden
diff --git a/lib/wx/src/gen/wxTreebook.erl b/lib/wx/src/gen/wxTreebook.erl
index 34b16a1cc6..a515ec9639 100644
--- a/lib/wx/src/gen/wxTreebook.erl
+++ b/lib/wx/src/gen/wxTreebook.erl
@@ -1,24 +1,24 @@
%%
%% %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%
%% This file is generated DO NOT EDIT
%% @doc See external documentation: <a href="http://www.wxwidgets.org/manuals/stable/wx_wxtreebook.html">wxTreebook</a>.
-%% <p>This class is derived (and can use functions) from:
+%% <p>This class is derived (and can use functions) from:
%% <br />{@link wxControl}
%% <br />{@link wxWindow}
%% <br />{@link wxEvtHandler}
@@ -377,16 +377,16 @@ changeSelection(#wx_ref{type=ThisT,ref=ThisRef},N)
%% @spec (This::wxTreebook()) -> ok
%% @doc Destroys this object, do not use object again
-destroy(Obj=#wx_ref{type=Type}) ->
+destroy(Obj=#wx_ref{type=Type}) ->
?CLASS(Type,wxTreebook),
wxe_util:destroy(?DESTROY_OBJECT,Obj),
ok.
- %% From wxControl
+ %% From wxControl
%% @hidden
setLabel(This,Label) -> wxControl:setLabel(This,Label).
%% @hidden
getLabel(This) -> wxControl:getLabel(This).
- %% From wxWindow
+ %% From wxWindow
%% @hidden
warpPointer(This,X,Y) -> wxWindow:warpPointer(This,X,Y).
%% @hidden
@@ -733,7 +733,7 @@ center(This) -> wxWindow:center(This).
captureMouse(This) -> wxWindow:captureMouse(This).
%% @hidden
cacheBestSize(This,Size) -> wxWindow:cacheBestSize(This,Size).
- %% From wxEvtHandler
+ %% From wxEvtHandler
%% @hidden
disconnect(This,EventType, Options) -> wxEvtHandler:disconnect(This,EventType, Options).
%% @hidden
diff --git a/lib/wx/src/gen/wxUpdateUIEvent.erl b/lib/wx/src/gen/wxUpdateUIEvent.erl
index eddccd3575..baf9fc8b52 100644
--- a/lib/wx/src/gen/wxUpdateUIEvent.erl
+++ b/lib/wx/src/gen/wxUpdateUIEvent.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%
%% This file is generated DO NOT EDIT
@@ -22,7 +22,7 @@
%% <dd><em>update_ui</em></dd></dl>
%% See also the message variant {@link wxEvtHandler:wxUpdateUI(). #wxUpdateUI{}} event record type.
%%
-%% <p>This class is derived (and can use functions) from:
+%% <p>This class is derived (and can use functions) from:
%% <br />{@link wxCommandEvent}
%% <br />{@link wxEvent}
%% </p>
@@ -179,7 +179,7 @@ setUpdateInterval(UpdateInterval)
wxe_util:cast(?wxUpdateUIEvent_SetUpdateInterval,
<<UpdateInterval:32/?UI>>).
- %% From wxCommandEvent
+ %% From wxCommandEvent
%% @hidden
setString(This,S) -> wxCommandEvent:setString(This,S).
%% @hidden
@@ -198,7 +198,7 @@ getInt(This) -> wxCommandEvent:getInt(This).
getExtraLong(This) -> wxCommandEvent:getExtraLong(This).
%% @hidden
getClientData(This) -> wxCommandEvent:getClientData(This).
- %% From wxEvent
+ %% From wxEvent
%% @hidden
stopPropagation(This) -> wxEvent:stopPropagation(This).
%% @hidden
diff --git a/lib/wx/src/gen/wxWindow.erl b/lib/wx/src/gen/wxWindow.erl
index d431696660..33665a0ad6 100644
--- a/lib/wx/src/gen/wxWindow.erl
+++ b/lib/wx/src/gen/wxWindow.erl
@@ -1,24 +1,24 @@
%%
%% %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%
%% This file is generated DO NOT EDIT
%% @doc See external documentation: <a href="http://www.wxwidgets.org/manuals/stable/wx_wxwindow.html">wxWindow</a>.
-%% <p>This class is derived (and can use functions) from:
+%% <p>This class is derived (and can use functions) from:
%% <br />{@link wxEvtHandler}
%% </p>
%% @type wxWindow(). An object reference, The representation is internal
@@ -290,7 +290,7 @@ findFocus() ->
%% @spec (This::wxWindow(),X::integer()|string()) -> wxWindow()
%% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxwindow.html#wxwindowfindwindow">external documentation</a>.
-%% <br /> Alternatives:
+%% <br /> Alternatives:
%% <p><c>
%% findWindow(This::wxWindow(), Winid::integer()) -> wxWindow() </c>
%% </p>
@@ -747,7 +747,7 @@ isEnabled(#wx_ref{type=ThisT,ref=ThisRef}) ->
%% @spec (This::wxWindow(),X::term()) -> bool()
%% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxwindow.html#wxwindowisexposed">external documentation</a>.
-%% <br /> Alternatives:
+%% <br /> Alternatives:
%% <p><c>
%% isExposed(This::wxWindow(), Pt::{X::integer(),Y::integer()}) -> bool() </c>
%% </p>
@@ -856,7 +856,7 @@ move(This,Pt={PtX,PtY})
%% @spec (This::wxWindow(),X::integer()|term(),X::integer()|term()) -> ok
%% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxwindow.html#wxwindowmove">external documentation</a>.
-%% <br /> Alternatives:
+%% <br /> Alternatives:
%% <p><c>
%% move(This::wxWindow(), X::integer(), Y::integer()) -> move(This,X,Y, []) </c></p>
%% <p><c>
@@ -1142,7 +1142,7 @@ setCaret(#wx_ref{type=ThisT,ref=ThisRef},#wx_ref{type=CaretT,ref=CaretRef}) ->
%% @spec (This::wxWindow(),X::term()) -> ok
%% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxwindow.html#wxwindowsetclientsize">external documentation</a>.
-%% <br /> Alternatives:
+%% <br /> Alternatives:
%% <p><c>
%% setClientSize(This::wxWindow(), Size::{W::integer(),H::integer()}) -> ok </c>
%% </p>
@@ -1351,7 +1351,7 @@ setScrollPos(#wx_ref{type=ThisT,ref=ThisRef},Orient,Pos, Options)
%% @spec (This::wxWindow(),X::term()) -> ok
%% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxwindow.html#wxwindowsetsize">external documentation</a>.
-%% <br /> Alternatives:
+%% <br /> Alternatives:
%% <p><c>
%% setSize(This::wxWindow(), Rect::{X::integer(),Y::integer(),W::integer(),H::integer()}) -> setSize(This,Rect, []) </c></p>
%% <p><c>
@@ -1369,7 +1369,7 @@ setSize(#wx_ref{type=ThisT,ref=ThisRef},{SizeW,SizeH})
%% @spec (This::wxWindow(),X::integer()|term(),X::integer()|term()) -> ok
%% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxwindow.html#wxwindowsetsize">external documentation</a>.
-%% <br /> Alternatives:
+%% <br /> Alternatives:
%% <p><c>
%% setSize(This::wxWindow(), Width::integer(), Height::integer()) -> ok </c>
%% </p>
@@ -1417,7 +1417,7 @@ setSizeHints(This,MinSize={MinSizeW,MinSizeH})
%% @spec (This::wxWindow(),X::integer()|term(),X::integer()|term()) -> ok
%% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxwindow.html#wxwindowsetsizehints">external documentation</a>.
-%% <br /> Alternatives:
+%% <br /> Alternatives:
%% <p><c>
%% setSizeHints(This::wxWindow(), MinW::integer(), MinH::integer()) -> setSizeHints(This,MinW,MinH, []) </c></p>
%% <p><c>
@@ -1501,7 +1501,7 @@ setThemeEnabled(#wx_ref{type=ThisT,ref=ThisRef},EnableTheme)
%% @spec (This::wxWindow(),X::string()|term()) -> ok
%% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxwindow.html#wxwindowsettooltip">external documentation</a>.
-%% <br /> Alternatives:
+%% <br /> Alternatives:
%% <p><c>
%% setToolTip(This::wxWindow(), Tip::string()) -> ok </c>
%% </p>
@@ -1544,7 +1544,7 @@ setVirtualSizeHints(This,MinSize={MinSizeW,MinSizeH})
%% @spec (This::wxWindow(),X::integer()|term(),X::integer()|term()) -> ok
%% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxwindow.html#wxwindowsetvirtualsizehints">external documentation</a>.
-%% <br /> Alternatives:
+%% <br /> Alternatives:
%% <p><c>
%% setVirtualSizeHints(This::wxWindow(), MinW::integer(), MinH::integer()) -> setVirtualSizeHints(This,MinW,MinH, []) </c></p>
%% <p><c>
@@ -1691,11 +1691,11 @@ warpPointer(#wx_ref{type=ThisT,ref=ThisRef},X,Y)
%% @spec (This::wxWindow()) -> ok
%% @doc Destroys this object, do not use object again
-destroy(Obj=#wx_ref{type=Type}) ->
+destroy(Obj=#wx_ref{type=Type}) ->
?CLASS(Type,wxWindow),
wxe_util:destroy(?DESTROY_OBJECT,Obj),
ok.
- %% From wxEvtHandler
+ %% From wxEvtHandler
%% @hidden
disconnect(This,EventType, Options) -> wxEvtHandler:disconnect(This,EventType, Options).
%% @hidden
diff --git a/lib/wx/src/gen/wxWindowCreateEvent.erl b/lib/wx/src/gen/wxWindowCreateEvent.erl
index 0503bdfef4..c8b3c74f81 100644
--- a/lib/wx/src/gen/wxWindowCreateEvent.erl
+++ b/lib/wx/src/gen/wxWindowCreateEvent.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%
%% This file is generated DO NOT EDIT
@@ -22,7 +22,7 @@
%% <dd><em>create</em></dd></dl>
%% See also the message variant {@link wxEvtHandler:wxWindowCreate(). #wxWindowCreate{}} event record type.
%%
-%% <p>This class is derived (and can use functions) from:
+%% <p>This class is derived (and can use functions) from:
%% <br />{@link wxCommandEvent}
%% <br />{@link wxEvent}
%% </p>
@@ -45,7 +45,7 @@ parent_class(wxCommandEvent) -> true;
parent_class(wxEvent) -> true;
parent_class(_Class) -> erlang:error({badtype, ?MODULE}).
- %% From wxCommandEvent
+ %% From wxCommandEvent
%% @hidden
setString(This,S) -> wxCommandEvent:setString(This,S).
%% @hidden
@@ -64,7 +64,7 @@ getInt(This) -> wxCommandEvent:getInt(This).
getExtraLong(This) -> wxCommandEvent:getExtraLong(This).
%% @hidden
getClientData(This) -> wxCommandEvent:getClientData(This).
- %% From wxEvent
+ %% From wxEvent
%% @hidden
stopPropagation(This) -> wxEvent:stopPropagation(This).
%% @hidden
diff --git a/lib/wx/src/gen/wxWindowDC.erl b/lib/wx/src/gen/wxWindowDC.erl
index 63b2249844..17cbd3d378 100644
--- a/lib/wx/src/gen/wxWindowDC.erl
+++ b/lib/wx/src/gen/wxWindowDC.erl
@@ -1,24 +1,24 @@
%%
%% %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%
%% This file is generated DO NOT EDIT
%% @doc See external documentation: <a href="http://www.wxwidgets.org/manuals/stable/wx_wxwindowdc.html">wxWindowDC</a>.
-%% <p>This class is derived (and can use functions) from:
+%% <p>This class is derived (and can use functions) from:
%% <br />{@link wxDC}
%% </p>
%% @type wxWindowDC(). An object reference, The representation is internal
@@ -71,11 +71,11 @@ new(#wx_ref{type=WinT,ref=WinRef}) ->
%% @spec (This::wxWindowDC()) -> ok
%% @doc Destroys this object, do not use object again
-destroy(Obj=#wx_ref{type=Type}) ->
+destroy(Obj=#wx_ref{type=Type}) ->
?CLASS(Type,wxWindowDC),
wxe_util:destroy(?DESTROY_OBJECT,Obj),
ok.
- %% From wxDC
+ %% From wxDC
%% @hidden
startPage(This) -> wxDC:startPage(This).
%% @hidden
diff --git a/lib/wx/src/gen/wxWindowDestroyEvent.erl b/lib/wx/src/gen/wxWindowDestroyEvent.erl
index 8d98b36f68..e62700da4a 100644
--- a/lib/wx/src/gen/wxWindowDestroyEvent.erl
+++ b/lib/wx/src/gen/wxWindowDestroyEvent.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%
%% This file is generated DO NOT EDIT
@@ -22,7 +22,7 @@
%% <dd><em>destroy</em></dd></dl>
%% See also the message variant {@link wxEvtHandler:wxWindowDestroy(). #wxWindowDestroy{}} event record type.
%%
-%% <p>This class is derived (and can use functions) from:
+%% <p>This class is derived (and can use functions) from:
%% <br />{@link wxCommandEvent}
%% <br />{@link wxEvent}
%% </p>
@@ -45,7 +45,7 @@ parent_class(wxCommandEvent) -> true;
parent_class(wxEvent) -> true;
parent_class(_Class) -> erlang:error({badtype, ?MODULE}).
- %% From wxCommandEvent
+ %% From wxCommandEvent
%% @hidden
setString(This,S) -> wxCommandEvent:setString(This,S).
%% @hidden
@@ -64,7 +64,7 @@ getInt(This) -> wxCommandEvent:getInt(This).
getExtraLong(This) -> wxCommandEvent:getExtraLong(This).
%% @hidden
getClientData(This) -> wxCommandEvent:getClientData(This).
- %% From wxEvent
+ %% From wxEvent
%% @hidden
stopPropagation(This) -> wxEvent:stopPropagation(This).
%% @hidden
diff --git a/lib/wx/src/gen/wxXmlResource.erl b/lib/wx/src/gen/wxXmlResource.erl
index c9f396e608..2b69a49bd7 100644
--- a/lib/wx/src/gen/wxXmlResource.erl
+++ b/lib/wx/src/gen/wxXmlResource.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%
%% This file is generated DO NOT EDIT
@@ -320,7 +320,7 @@ xrcctrl(Window = #wx_ref{}, Name, Type) when is_list(Name), is_atom(Type) ->
%% @spec (This::wxXmlResource()) -> ok
%% @doc Destroys this object, do not use object again
-destroy(Obj=#wx_ref{type=Type}) ->
+destroy(Obj=#wx_ref{type=Type}) ->
?CLASS(Type,wxXmlResource),
wxe_util:destroy(?DESTROY_OBJECT,Obj),
ok.
diff --git a/lib/wx/src/gen/wx_misc.erl b/lib/wx/src/gen/wx_misc.erl
index ef50e22e99..cf23d4cf8b 100644
--- a/lib/wx/src/gen/wx_misc.erl
+++ b/lib/wx/src/gen/wx_misc.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%
%% This file is generated DO NOT EDIT
diff --git a/lib/wx/src/gen/wxe_debug.hrl b/lib/wx/src/gen/wxe_debug.hrl
index 11f5b9e781..68a3b4ccd8 100644
--- a/lib/wx/src/gen/wxe_debug.hrl
+++ b/lib/wx/src/gen/wxe_debug.hrl
@@ -1,23 +1,23 @@
%%
%% %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%
%% This file is generated DO NOT EDIT
-wxdebug_table() ->
+wxdebug_table() ->
[
{0, {wx, internal_batch_start, 0}},
{1, {wx, internal_batch_end, 0}},
@@ -1519,1761 +1519,1763 @@ wxdebug_table() ->
{1672, {wxListCtrl, getColumnCount, 0}},
{1673, {wxListCtrl, getColumnWidth, 1}},
{1674, {wxListCtrl, getCountPerPage, 0}},
- {1675, {wxListCtrl, getImageList, 1}},
- {1676, {wxListCtrl, getItem, 1}},
- {1677, {wxListCtrl, getItemBackgroundColour, 1}},
- {1678, {wxListCtrl, getItemCount, 0}},
- {1679, {wxListCtrl, getItemData, 1}},
- {1680, {wxListCtrl, getItemFont, 1}},
- {1681, {wxListCtrl, getItemPosition, 2}},
- {1682, {wxListCtrl, getItemRect, 3}},
- {1683, {wxListCtrl, getItemSpacing, 0}},
- {1684, {wxListCtrl, getItemState, 2}},
- {1685, {wxListCtrl, getItemText, 1}},
- {1686, {wxListCtrl, getItemTextColour, 1}},
- {1687, {wxListCtrl, getNextItem, 2}},
- {1688, {wxListCtrl, getSelectedItemCount, 0}},
- {1689, {wxListCtrl, getTextColour, 0}},
- {1690, {wxListCtrl, getTopItem, 0}},
- {1691, {wxListCtrl, getViewRect, 0}},
- {1692, {wxListCtrl, hitTest, 2}},
- {1693, {wxListCtrl, insertColumn_2, 2}},
- {1694, {wxListCtrl, insertColumn_3, 3}},
- {1695, {wxListCtrl, insertItem_1, 1}},
- {1696, {wxListCtrl, insertItem_2_1, 2}},
- {1697, {wxListCtrl, insertItem_2_0, 2}},
- {1698, {wxListCtrl, insertItem_3, 3}},
- {1699, {wxListCtrl, refreshItem, 1}},
- {1700, {wxListCtrl, refreshItems, 2}},
- {1701, {wxListCtrl, scrollList, 2}},
- {1702, {wxListCtrl, setBackgroundColour, 1}},
- {1703, {wxListCtrl, setColumn, 2}},
- {1704, {wxListCtrl, setColumnWidth, 2}},
- {1705, {wxListCtrl, setImageList, 2}},
- {1706, {wxListCtrl, setItem_1, 1}},
- {1707, {wxListCtrl, setItem_4, 4}},
- {1708, {wxListCtrl, setItemBackgroundColour, 2}},
- {1709, {wxListCtrl, setItemCount, 1}},
- {1710, {wxListCtrl, setItemData, 2}},
- {1711, {wxListCtrl, setItemFont, 2}},
- {1712, {wxListCtrl, setItemImage, 3}},
- {1713, {wxListCtrl, setItemColumnImage, 3}},
- {1714, {wxListCtrl, setItemPosition, 2}},
- {1715, {wxListCtrl, setItemState, 3}},
- {1716, {wxListCtrl, setItemText, 2}},
- {1717, {wxListCtrl, setItemTextColour, 2}},
- {1718, {wxListCtrl, setSingleStyle, 2}},
- {1719, {wxListCtrl, setTextColour, 1}},
- {1720, {wxListCtrl, setWindowStyleFlag, 1}},
- {1721, {wxListCtrl, sortItems, 2}},
- {1722, {wxListCtrl, 'Destroy', undefined}},
- {1723, {wxListView, clearColumnImage, 1}},
- {1724, {wxListView, focus, 1}},
- {1725, {wxListView, getFirstSelected, 0}},
- {1726, {wxListView, getFocusedItem, 0}},
- {1727, {wxListView, getNextSelected, 1}},
- {1728, {wxListView, isSelected, 1}},
- {1729, {wxListView, select, 2}},
- {1730, {wxListView, setColumnImage, 2}},
- {1731, {wxListItem, new_0, 0}},
- {1732, {wxListItem, new_1, 1}},
- {1733, {wxListItem, destruct, 0}},
- {1734, {wxListItem, clear, 0}},
- {1735, {wxListItem, getAlign, 0}},
- {1736, {wxListItem, getBackgroundColour, 0}},
- {1737, {wxListItem, getColumn, 0}},
- {1738, {wxListItem, getFont, 0}},
- {1739, {wxListItem, getId, 0}},
- {1740, {wxListItem, getImage, 0}},
- {1741, {wxListItem, getMask, 0}},
- {1742, {wxListItem, getState, 0}},
- {1743, {wxListItem, getText, 0}},
- {1744, {wxListItem, getTextColour, 0}},
- {1745, {wxListItem, getWidth, 0}},
- {1746, {wxListItem, setAlign, 1}},
- {1747, {wxListItem, setBackgroundColour, 1}},
- {1748, {wxListItem, setColumn, 1}},
- {1749, {wxListItem, setFont, 1}},
- {1750, {wxListItem, setId, 1}},
- {1751, {wxListItem, setImage, 1}},
- {1752, {wxListItem, setMask, 1}},
- {1753, {wxListItem, setState, 1}},
- {1754, {wxListItem, setStateMask, 1}},
- {1755, {wxListItem, setText, 1}},
- {1756, {wxListItem, setTextColour, 1}},
- {1757, {wxListItem, setWidth, 1}},
- {1758, {wxImageList, new_0, 0}},
- {1759, {wxImageList, new_3, 3}},
- {1760, {wxImageList, add_1, 1}},
- {1761, {wxImageList, add_2_0, 2}},
- {1762, {wxImageList, add_2_1, 2}},
- {1763, {wxImageList, create, 3}},
- {1765, {wxImageList, draw, 5}},
- {1766, {wxImageList, getBitmap, 1}},
- {1767, {wxImageList, getIcon, 1}},
- {1768, {wxImageList, getImageCount, 0}},
- {1769, {wxImageList, getSize, 3}},
- {1770, {wxImageList, remove, 1}},
- {1771, {wxImageList, removeAll, 0}},
- {1772, {wxImageList, replace_2, 2}},
- {1773, {wxImageList, replace_3, 3}},
- {1774, {wxImageList, 'Destroy', undefined}},
- {1775, {wxTextAttr, new_0, 0}},
- {1776, {wxTextAttr, new_2, 2}},
- {1777, {wxTextAttr, getAlignment, 0}},
- {1778, {wxTextAttr, getBackgroundColour, 0}},
- {1779, {wxTextAttr, getFont, 0}},
- {1780, {wxTextAttr, getLeftIndent, 0}},
- {1781, {wxTextAttr, getLeftSubIndent, 0}},
- {1782, {wxTextAttr, getRightIndent, 0}},
- {1783, {wxTextAttr, getTabs, 0}},
- {1784, {wxTextAttr, getTextColour, 0}},
- {1785, {wxTextAttr, hasBackgroundColour, 0}},
- {1786, {wxTextAttr, hasFont, 0}},
- {1787, {wxTextAttr, hasTextColour, 0}},
- {1788, {wxTextAttr, getFlags, 0}},
- {1789, {wxTextAttr, isDefault, 0}},
- {1790, {wxTextAttr, setAlignment, 1}},
- {1791, {wxTextAttr, setBackgroundColour, 1}},
- {1792, {wxTextAttr, setFlags, 1}},
- {1793, {wxTextAttr, setFont, 2}},
- {1794, {wxTextAttr, setLeftIndent, 2}},
- {1795, {wxTextAttr, setRightIndent, 1}},
- {1796, {wxTextAttr, setTabs, 1}},
- {1797, {wxTextAttr, setTextColour, 1}},
- {1798, {wxTextAttr, 'Destroy', undefined}},
- {1800, {wxTextCtrl, new_3, 3}},
- {1801, {wxTextCtrl, new_0, 0}},
- {1803, {wxTextCtrl, destruct, 0}},
- {1804, {wxTextCtrl, appendText, 1}},
- {1805, {wxTextCtrl, canCopy, 0}},
- {1806, {wxTextCtrl, canCut, 0}},
- {1807, {wxTextCtrl, canPaste, 0}},
- {1808, {wxTextCtrl, canRedo, 0}},
- {1809, {wxTextCtrl, canUndo, 0}},
- {1810, {wxTextCtrl, clear, 0}},
- {1811, {wxTextCtrl, copy, 0}},
- {1812, {wxTextCtrl, create, 3}},
- {1813, {wxTextCtrl, cut, 0}},
- {1814, {wxTextCtrl, discardEdits, 0}},
- {1815, {wxTextCtrl, emulateKeyPress, 1}},
- {1816, {wxTextCtrl, getDefaultStyle, 0}},
- {1817, {wxTextCtrl, getInsertionPoint, 0}},
- {1818, {wxTextCtrl, getLastPosition, 0}},
- {1819, {wxTextCtrl, getLineLength, 1}},
- {1820, {wxTextCtrl, getLineText, 1}},
- {1821, {wxTextCtrl, getNumberOfLines, 0}},
- {1822, {wxTextCtrl, getRange, 2}},
- {1823, {wxTextCtrl, getSelection, 2}},
- {1824, {wxTextCtrl, getStringSelection, 0}},
- {1825, {wxTextCtrl, getStyle, 2}},
- {1826, {wxTextCtrl, getValue, 0}},
- {1827, {wxTextCtrl, isEditable, 0}},
- {1828, {wxTextCtrl, isModified, 0}},
- {1829, {wxTextCtrl, isMultiLine, 0}},
- {1830, {wxTextCtrl, isSingleLine, 0}},
- {1831, {wxTextCtrl, loadFile, 2}},
- {1832, {wxTextCtrl, markDirty, 0}},
- {1833, {wxTextCtrl, paste, 0}},
- {1834, {wxTextCtrl, positionToXY, 3}},
- {1835, {wxTextCtrl, redo, 0}},
- {1836, {wxTextCtrl, remove, 2}},
- {1837, {wxTextCtrl, replace, 3}},
- {1838, {wxTextCtrl, saveFile, 1}},
- {1839, {wxTextCtrl, setDefaultStyle, 1}},
- {1840, {wxTextCtrl, setEditable, 1}},
- {1841, {wxTextCtrl, setInsertionPoint, 1}},
- {1842, {wxTextCtrl, setInsertionPointEnd, 0}},
- {1844, {wxTextCtrl, setMaxLength, 1}},
- {1845, {wxTextCtrl, setSelection, 2}},
- {1846, {wxTextCtrl, setStyle, 3}},
- {1847, {wxTextCtrl, setValue, 1}},
- {1848, {wxTextCtrl, showPosition, 1}},
- {1849, {wxTextCtrl, undo, 0}},
- {1850, {wxTextCtrl, writeText, 1}},
- {1851, {wxTextCtrl, xYToPosition, 2}},
- {1854, {wxNotebook, new_0, 0}},
- {1855, {wxNotebook, new_3, 3}},
- {1856, {wxNotebook, destruct, 0}},
- {1857, {wxNotebook, addPage, 3}},
- {1858, {wxNotebook, advanceSelection, 1}},
- {1859, {wxNotebook, assignImageList, 1}},
- {1860, {wxNotebook, create, 3}},
- {1861, {wxNotebook, deleteAllPages, 0}},
- {1862, {wxNotebook, deletePage, 1}},
- {1863, {wxNotebook, removePage, 1}},
- {1864, {wxNotebook, getCurrentPage, 0}},
- {1865, {wxNotebook, getImageList, 0}},
- {1867, {wxNotebook, getPage, 1}},
- {1868, {wxNotebook, getPageCount, 0}},
- {1869, {wxNotebook, getPageImage, 1}},
- {1870, {wxNotebook, getPageText, 1}},
- {1871, {wxNotebook, getRowCount, 0}},
- {1872, {wxNotebook, getSelection, 0}},
- {1873, {wxNotebook, getThemeBackgroundColour, 0}},
- {1875, {wxNotebook, hitTest, 2}},
- {1877, {wxNotebook, insertPage, 4}},
- {1878, {wxNotebook, setImageList, 1}},
- {1879, {wxNotebook, setPadding, 1}},
- {1880, {wxNotebook, setPageSize, 1}},
- {1881, {wxNotebook, setPageImage, 2}},
- {1882, {wxNotebook, setPageText, 2}},
- {1883, {wxNotebook, setSelection, 1}},
- {1884, {wxNotebook, changeSelection, 1}},
- {1885, {wxChoicebook, new_0, 0}},
- {1886, {wxChoicebook, new_3, 3}},
- {1887, {wxChoicebook, addPage, 3}},
- {1888, {wxChoicebook, advanceSelection, 1}},
- {1889, {wxChoicebook, assignImageList, 1}},
- {1890, {wxChoicebook, create, 3}},
- {1891, {wxChoicebook, deleteAllPages, 0}},
- {1892, {wxChoicebook, deletePage, 1}},
- {1893, {wxChoicebook, removePage, 1}},
- {1894, {wxChoicebook, getCurrentPage, 0}},
- {1895, {wxChoicebook, getImageList, 0}},
- {1897, {wxChoicebook, getPage, 1}},
- {1898, {wxChoicebook, getPageCount, 0}},
- {1899, {wxChoicebook, getPageImage, 1}},
- {1900, {wxChoicebook, getPageText, 1}},
- {1901, {wxChoicebook, getSelection, 0}},
- {1902, {wxChoicebook, hitTest, 2}},
- {1903, {wxChoicebook, insertPage, 4}},
- {1904, {wxChoicebook, setImageList, 1}},
- {1905, {wxChoicebook, setPageSize, 1}},
- {1906, {wxChoicebook, setPageImage, 2}},
- {1907, {wxChoicebook, setPageText, 2}},
- {1908, {wxChoicebook, setSelection, 1}},
- {1909, {wxChoicebook, changeSelection, 1}},
- {1910, {wxChoicebook, 'Destroy', undefined}},
- {1911, {wxToolbook, new_0, 0}},
- {1912, {wxToolbook, new_3, 3}},
- {1913, {wxToolbook, addPage, 3}},
- {1914, {wxToolbook, advanceSelection, 1}},
- {1915, {wxToolbook, assignImageList, 1}},
- {1916, {wxToolbook, create, 3}},
- {1917, {wxToolbook, deleteAllPages, 0}},
- {1918, {wxToolbook, deletePage, 1}},
- {1919, {wxToolbook, removePage, 1}},
- {1920, {wxToolbook, getCurrentPage, 0}},
- {1921, {wxToolbook, getImageList, 0}},
- {1923, {wxToolbook, getPage, 1}},
- {1924, {wxToolbook, getPageCount, 0}},
- {1925, {wxToolbook, getPageImage, 1}},
- {1926, {wxToolbook, getPageText, 1}},
- {1927, {wxToolbook, getSelection, 0}},
- {1929, {wxToolbook, hitTest, 2}},
- {1930, {wxToolbook, insertPage, 4}},
- {1931, {wxToolbook, setImageList, 1}},
- {1932, {wxToolbook, setPageSize, 1}},
- {1933, {wxToolbook, setPageImage, 2}},
- {1934, {wxToolbook, setPageText, 2}},
- {1935, {wxToolbook, setSelection, 1}},
- {1936, {wxToolbook, changeSelection, 1}},
- {1937, {wxToolbook, 'Destroy', undefined}},
- {1938, {wxListbook, new_0, 0}},
- {1939, {wxListbook, new_3, 3}},
- {1940, {wxListbook, addPage, 3}},
- {1941, {wxListbook, advanceSelection, 1}},
- {1942, {wxListbook, assignImageList, 1}},
- {1943, {wxListbook, create, 3}},
- {1944, {wxListbook, deleteAllPages, 0}},
- {1945, {wxListbook, deletePage, 1}},
- {1946, {wxListbook, removePage, 1}},
- {1947, {wxListbook, getCurrentPage, 0}},
- {1948, {wxListbook, getImageList, 0}},
- {1950, {wxListbook, getPage, 1}},
- {1951, {wxListbook, getPageCount, 0}},
- {1952, {wxListbook, getPageImage, 1}},
- {1953, {wxListbook, getPageText, 1}},
- {1954, {wxListbook, getSelection, 0}},
- {1956, {wxListbook, hitTest, 2}},
- {1957, {wxListbook, insertPage, 4}},
- {1958, {wxListbook, setImageList, 1}},
- {1959, {wxListbook, setPageSize, 1}},
- {1960, {wxListbook, setPageImage, 2}},
- {1961, {wxListbook, setPageText, 2}},
- {1962, {wxListbook, setSelection, 1}},
- {1963, {wxListbook, changeSelection, 1}},
- {1964, {wxListbook, 'Destroy', undefined}},
- {1965, {wxTreebook, new_0, 0}},
- {1966, {wxTreebook, new_3, 3}},
- {1967, {wxTreebook, addPage, 3}},
- {1968, {wxTreebook, advanceSelection, 1}},
- {1969, {wxTreebook, assignImageList, 1}},
- {1970, {wxTreebook, create, 3}},
- {1971, {wxTreebook, deleteAllPages, 0}},
- {1972, {wxTreebook, deletePage, 1}},
- {1973, {wxTreebook, removePage, 1}},
- {1974, {wxTreebook, getCurrentPage, 0}},
- {1975, {wxTreebook, getImageList, 0}},
- {1977, {wxTreebook, getPage, 1}},
- {1978, {wxTreebook, getPageCount, 0}},
- {1979, {wxTreebook, getPageImage, 1}},
- {1980, {wxTreebook, getPageText, 1}},
- {1981, {wxTreebook, getSelection, 0}},
- {1982, {wxTreebook, expandNode, 2}},
- {1983, {wxTreebook, isNodeExpanded, 1}},
- {1985, {wxTreebook, hitTest, 2}},
- {1986, {wxTreebook, insertPage, 4}},
- {1987, {wxTreebook, insertSubPage, 4}},
- {1988, {wxTreebook, setImageList, 1}},
- {1989, {wxTreebook, setPageSize, 1}},
- {1990, {wxTreebook, setPageImage, 2}},
- {1991, {wxTreebook, setPageText, 2}},
- {1992, {wxTreebook, setSelection, 1}},
- {1993, {wxTreebook, changeSelection, 1}},
- {1994, {wxTreebook, 'Destroy', undefined}},
- {1997, {wxTreeCtrl, new_2, 2}},
- {1998, {wxTreeCtrl, new_0, 0}},
- {2000, {wxTreeCtrl, destruct, 0}},
- {2001, {wxTreeCtrl, addRoot, 2}},
- {2002, {wxTreeCtrl, appendItem, 3}},
- {2003, {wxTreeCtrl, assignImageList, 1}},
- {2004, {wxTreeCtrl, assignStateImageList, 1}},
- {2005, {wxTreeCtrl, collapse, 1}},
- {2006, {wxTreeCtrl, collapseAndReset, 1}},
- {2007, {wxTreeCtrl, create, 2}},
- {2008, {wxTreeCtrl, delete, 1}},
- {2009, {wxTreeCtrl, deleteAllItems, 0}},
- {2010, {wxTreeCtrl, deleteChildren, 1}},
- {2011, {wxTreeCtrl, ensureVisible, 1}},
- {2012, {wxTreeCtrl, expand, 1}},
- {2013, {wxTreeCtrl, getBoundingRect, 3}},
- {2015, {wxTreeCtrl, getChildrenCount, 2}},
- {2016, {wxTreeCtrl, getCount, 0}},
- {2017, {wxTreeCtrl, getEditControl, 0}},
- {2018, {wxTreeCtrl, getFirstVisibleItem, 0}},
- {2019, {wxTreeCtrl, getImageList, 0}},
- {2020, {wxTreeCtrl, getIndent, 0}},
- {2021, {wxTreeCtrl, getItemBackgroundColour, 1}},
- {2022, {wxTreeCtrl, getItemData, 1}},
- {2023, {wxTreeCtrl, getItemFont, 1}},
- {2024, {wxTreeCtrl, getItemImage_1, 1}},
- {2025, {wxTreeCtrl, getItemImage_2, 2}},
- {2026, {wxTreeCtrl, getItemText, 1}},
- {2027, {wxTreeCtrl, getItemTextColour, 1}},
- {2028, {wxTreeCtrl, getLastChild, 1}},
- {2029, {wxTreeCtrl, getNextSibling, 1}},
- {2030, {wxTreeCtrl, getNextVisible, 1}},
- {2031, {wxTreeCtrl, getItemParent, 1}},
- {2032, {wxTreeCtrl, getPrevSibling, 1}},
- {2033, {wxTreeCtrl, getPrevVisible, 1}},
- {2034, {wxTreeCtrl, getRootItem, 0}},
- {2035, {wxTreeCtrl, getSelection, 0}},
- {2036, {wxTreeCtrl, getSelections, 1}},
- {2037, {wxTreeCtrl, getStateImageList, 0}},
- {2038, {wxTreeCtrl, hitTest, 1}},
- {2039, {wxTreeCtrl, insertItem_4_1, 4}},
- {2040, {wxTreeCtrl, insertItem_4_0, 4}},
- {2041, {wxTreeCtrl, isBold, 1}},
- {2042, {wxTreeCtrl, isExpanded, 1}},
- {2043, {wxTreeCtrl, isSelected, 1}},
- {2044, {wxTreeCtrl, isVisible, 1}},
- {2045, {wxTreeCtrl, itemHasChildren, 1}},
- {2046, {wxTreeCtrl, prependItem, 3}},
- {2047, {wxTreeCtrl, scrollTo, 1}},
- {2048, {wxTreeCtrl, selectItem_1, 1}},
- {2049, {wxTreeCtrl, selectItem_2, 2}},
- {2050, {wxTreeCtrl, setIndent, 1}},
- {2051, {wxTreeCtrl, setImageList, 1}},
- {2052, {wxTreeCtrl, setItemBackgroundColour, 2}},
- {2053, {wxTreeCtrl, setItemBold, 2}},
- {2054, {wxTreeCtrl, setItemData, 2}},
- {2055, {wxTreeCtrl, setItemDropHighlight, 2}},
- {2056, {wxTreeCtrl, setItemFont, 2}},
- {2057, {wxTreeCtrl, setItemHasChildren, 2}},
- {2058, {wxTreeCtrl, setItemImage_2, 2}},
- {2059, {wxTreeCtrl, setItemImage_3, 3}},
- {2060, {wxTreeCtrl, setItemText, 2}},
- {2061, {wxTreeCtrl, setItemTextColour, 2}},
- {2062, {wxTreeCtrl, setStateImageList, 1}},
- {2063, {wxTreeCtrl, setWindowStyle, 1}},
- {2064, {wxTreeCtrl, sortChildren, 1}},
- {2065, {wxTreeCtrl, toggle, 1}},
- {2066, {wxTreeCtrl, toggleItemSelection, 1}},
- {2067, {wxTreeCtrl, unselect, 0}},
- {2068, {wxTreeCtrl, unselectAll, 0}},
- {2069, {wxTreeCtrl, unselectItem, 1}},
- {2070, {wxScrollBar, new_0, 0}},
- {2071, {wxScrollBar, new_3, 3}},
- {2072, {wxScrollBar, destruct, 0}},
- {2073, {wxScrollBar, create, 3}},
- {2074, {wxScrollBar, getRange, 0}},
- {2075, {wxScrollBar, getPageSize, 0}},
- {2076, {wxScrollBar, getThumbPosition, 0}},
- {2077, {wxScrollBar, getThumbSize, 0}},
- {2078, {wxScrollBar, setThumbPosition, 1}},
- {2079, {wxScrollBar, setScrollbar, 5}},
- {2081, {wxSpinButton, new_2, 2}},
- {2082, {wxSpinButton, new_0, 0}},
- {2083, {wxSpinButton, create, 2}},
- {2084, {wxSpinButton, getMax, 0}},
- {2085, {wxSpinButton, getMin, 0}},
- {2086, {wxSpinButton, getValue, 0}},
- {2087, {wxSpinButton, setRange, 2}},
- {2088, {wxSpinButton, setValue, 1}},
- {2089, {wxSpinButton, 'Destroy', undefined}},
- {2090, {wxSpinCtrl, new_0, 0}},
- {2091, {wxSpinCtrl, new_2, 2}},
- {2093, {wxSpinCtrl, create, 2}},
- {2096, {wxSpinCtrl, setValue_1_1, 1}},
- {2097, {wxSpinCtrl, setValue_1_0, 1}},
- {2099, {wxSpinCtrl, getValue, 0}},
- {2101, {wxSpinCtrl, setRange, 2}},
- {2102, {wxSpinCtrl, setSelection, 2}},
- {2104, {wxSpinCtrl, getMin, 0}},
- {2106, {wxSpinCtrl, getMax, 0}},
- {2107, {wxSpinCtrl, 'Destroy', undefined}},
- {2108, {wxStaticText, new_0, 0}},
- {2109, {wxStaticText, new_4, 4}},
- {2110, {wxStaticText, create, 4}},
- {2111, {wxStaticText, getLabel, 0}},
- {2112, {wxStaticText, setLabel, 1}},
- {2113, {wxStaticText, wrap, 1}},
- {2114, {wxStaticText, 'Destroy', undefined}},
- {2115, {wxStaticBitmap, new_0, 0}},
- {2116, {wxStaticBitmap, new_4, 4}},
- {2117, {wxStaticBitmap, create, 4}},
- {2118, {wxStaticBitmap, getBitmap, 0}},
- {2119, {wxStaticBitmap, setBitmap, 1}},
- {2120, {wxStaticBitmap, 'Destroy', undefined}},
- {2121, {wxRadioBox, new, 7}},
- {2123, {wxRadioBox, destruct, 0}},
- {2124, {wxRadioBox, create, 7}},
- {2125, {wxRadioBox, enable_2, 2}},
- {2126, {wxRadioBox, enable_1, 1}},
- {2127, {wxRadioBox, getSelection, 0}},
- {2128, {wxRadioBox, getString, 1}},
- {2129, {wxRadioBox, setSelection, 1}},
- {2130, {wxRadioBox, show_2, 2}},
- {2131, {wxRadioBox, show_1, 1}},
- {2132, {wxRadioBox, getColumnCount, 0}},
- {2133, {wxRadioBox, getItemHelpText, 1}},
- {2134, {wxRadioBox, getItemToolTip, 1}},
- {2136, {wxRadioBox, getItemFromPoint, 1}},
- {2137, {wxRadioBox, getRowCount, 0}},
- {2138, {wxRadioBox, isItemEnabled, 1}},
- {2139, {wxRadioBox, isItemShown, 1}},
- {2140, {wxRadioBox, setItemHelpText, 2}},
- {2141, {wxRadioBox, setItemToolTip, 2}},
- {2142, {wxRadioButton, new_0, 0}},
- {2143, {wxRadioButton, new_4, 4}},
- {2144, {wxRadioButton, create, 4}},
- {2145, {wxRadioButton, getValue, 0}},
- {2146, {wxRadioButton, setValue, 1}},
- {2147, {wxRadioButton, 'Destroy', undefined}},
- {2149, {wxSlider, new_6, 6}},
- {2150, {wxSlider, new_0, 0}},
- {2151, {wxSlider, create, 6}},
- {2152, {wxSlider, getLineSize, 0}},
- {2153, {wxSlider, getMax, 0}},
- {2154, {wxSlider, getMin, 0}},
- {2155, {wxSlider, getPageSize, 0}},
- {2156, {wxSlider, getThumbLength, 0}},
- {2157, {wxSlider, getValue, 0}},
- {2158, {wxSlider, setLineSize, 1}},
- {2159, {wxSlider, setPageSize, 1}},
- {2160, {wxSlider, setRange, 2}},
- {2161, {wxSlider, setThumbLength, 1}},
- {2162, {wxSlider, setValue, 1}},
- {2163, {wxSlider, 'Destroy', undefined}},
- {2165, {wxDialog, new_4, 4}},
- {2166, {wxDialog, new_0, 0}},
- {2168, {wxDialog, destruct, 0}},
- {2169, {wxDialog, create, 4}},
- {2170, {wxDialog, createButtonSizer, 1}},
- {2171, {wxDialog, createStdDialogButtonSizer, 1}},
- {2172, {wxDialog, endModal, 1}},
- {2173, {wxDialog, getAffirmativeId, 0}},
- {2174, {wxDialog, getReturnCode, 0}},
- {2175, {wxDialog, isModal, 0}},
- {2176, {wxDialog, setAffirmativeId, 1}},
- {2177, {wxDialog, setReturnCode, 1}},
- {2178, {wxDialog, show, 1}},
- {2179, {wxDialog, showModal, 0}},
- {2180, {wxColourDialog, new_0, 0}},
- {2181, {wxColourDialog, new_2, 2}},
- {2182, {wxColourDialog, destruct, 0}},
- {2183, {wxColourDialog, create, 2}},
- {2184, {wxColourDialog, getColourData, 0}},
- {2185, {wxColourData, new_0, 0}},
- {2186, {wxColourData, new_1, 1}},
- {2187, {wxColourData, destruct, 0}},
- {2188, {wxColourData, getChooseFull, 0}},
- {2189, {wxColourData, getColour, 0}},
- {2191, {wxColourData, getCustomColour, 1}},
- {2192, {wxColourData, setChooseFull, 1}},
- {2193, {wxColourData, setColour, 1}},
- {2194, {wxColourData, setCustomColour, 2}},
- {2195, {wxPalette, new_0, 0}},
- {2196, {wxPalette, new_4, 4}},
- {2198, {wxPalette, destruct, 0}},
- {2199, {wxPalette, create, 4}},
- {2200, {wxPalette, getColoursCount, 0}},
- {2201, {wxPalette, getPixel, 3}},
- {2202, {wxPalette, getRGB, 4}},
- {2203, {wxPalette, isOk, 0}},
- {2207, {wxDirDialog, new, 2}},
- {2208, {wxDirDialog, destruct, 0}},
- {2209, {wxDirDialog, getPath, 0}},
- {2210, {wxDirDialog, getMessage, 0}},
- {2211, {wxDirDialog, setMessage, 1}},
- {2212, {wxDirDialog, setPath, 1}},
- {2216, {wxFileDialog, new, 2}},
- {2217, {wxFileDialog, destruct, 0}},
- {2218, {wxFileDialog, getDirectory, 0}},
- {2219, {wxFileDialog, getFilename, 0}},
- {2220, {wxFileDialog, getFilenames, 1}},
- {2221, {wxFileDialog, getFilterIndex, 0}},
- {2222, {wxFileDialog, getMessage, 0}},
- {2223, {wxFileDialog, getPath, 0}},
- {2224, {wxFileDialog, getPaths, 1}},
- {2225, {wxFileDialog, getWildcard, 0}},
- {2226, {wxFileDialog, setDirectory, 1}},
- {2227, {wxFileDialog, setFilename, 1}},
- {2228, {wxFileDialog, setFilterIndex, 1}},
- {2229, {wxFileDialog, setMessage, 1}},
- {2230, {wxFileDialog, setPath, 1}},
- {2231, {wxFileDialog, setWildcard, 1}},
- {2232, {wxPickerBase, setInternalMargin, 1}},
- {2233, {wxPickerBase, getInternalMargin, 0}},
- {2234, {wxPickerBase, setTextCtrlProportion, 1}},
- {2235, {wxPickerBase, setPickerCtrlProportion, 1}},
- {2236, {wxPickerBase, getTextCtrlProportion, 0}},
- {2237, {wxPickerBase, getPickerCtrlProportion, 0}},
- {2238, {wxPickerBase, hasTextCtrl, 0}},
- {2239, {wxPickerBase, getTextCtrl, 0}},
- {2240, {wxPickerBase, isTextCtrlGrowable, 0}},
- {2241, {wxPickerBase, setPickerCtrlGrowable, 1}},
- {2242, {wxPickerBase, setTextCtrlGrowable, 1}},
- {2243, {wxPickerBase, isPickerCtrlGrowable, 0}},
- {2244, {wxFilePickerCtrl, new_0, 0}},
- {2245, {wxFilePickerCtrl, new_3, 3}},
- {2246, {wxFilePickerCtrl, create, 3}},
- {2247, {wxFilePickerCtrl, getPath, 0}},
- {2248, {wxFilePickerCtrl, setPath, 1}},
- {2249, {wxFilePickerCtrl, 'Destroy', undefined}},
- {2250, {wxDirPickerCtrl, new_0, 0}},
- {2251, {wxDirPickerCtrl, new_3, 3}},
- {2252, {wxDirPickerCtrl, create, 3}},
- {2253, {wxDirPickerCtrl, getPath, 0}},
- {2254, {wxDirPickerCtrl, setPath, 1}},
- {2255, {wxDirPickerCtrl, 'Destroy', undefined}},
- {2256, {wxColourPickerCtrl, new_0, 0}},
- {2257, {wxColourPickerCtrl, new_3, 3}},
- {2258, {wxColourPickerCtrl, create, 3}},
- {2259, {wxColourPickerCtrl, getColour, 0}},
- {2260, {wxColourPickerCtrl, setColour_1_1, 1}},
- {2261, {wxColourPickerCtrl, setColour_1_0, 1}},
- {2262, {wxColourPickerCtrl, 'Destroy', undefined}},
- {2263, {wxDatePickerCtrl, new_0, 0}},
- {2264, {wxDatePickerCtrl, new_3, 3}},
- {2265, {wxDatePickerCtrl, getRange, 2}},
- {2266, {wxDatePickerCtrl, getValue, 0}},
- {2267, {wxDatePickerCtrl, setRange, 2}},
- {2268, {wxDatePickerCtrl, setValue, 1}},
- {2269, {wxDatePickerCtrl, 'Destroy', undefined}},
- {2270, {wxFontPickerCtrl, new_0, 0}},
- {2271, {wxFontPickerCtrl, new_3, 3}},
- {2272, {wxFontPickerCtrl, create, 3}},
- {2273, {wxFontPickerCtrl, getSelectedFont, 0}},
- {2274, {wxFontPickerCtrl, setSelectedFont, 1}},
- {2275, {wxFontPickerCtrl, getMaxPointSize, 0}},
- {2276, {wxFontPickerCtrl, setMaxPointSize, 1}},
- {2277, {wxFontPickerCtrl, 'Destroy', undefined}},
- {2280, {wxFindReplaceDialog, new_0, 0}},
- {2281, {wxFindReplaceDialog, new_4, 4}},
- {2282, {wxFindReplaceDialog, destruct, 0}},
- {2283, {wxFindReplaceDialog, create, 4}},
- {2284, {wxFindReplaceDialog, getData, 0}},
- {2285, {wxFindReplaceData, new_0, 0}},
- {2286, {wxFindReplaceData, new_1, 1}},
- {2287, {wxFindReplaceData, getFindString, 0}},
- {2288, {wxFindReplaceData, getReplaceString, 0}},
- {2289, {wxFindReplaceData, getFlags, 0}},
- {2290, {wxFindReplaceData, setFlags, 1}},
- {2291, {wxFindReplaceData, setFindString, 1}},
- {2292, {wxFindReplaceData, setReplaceString, 1}},
- {2293, {wxFindReplaceData, 'Destroy', undefined}},
- {2294, {wxMultiChoiceDialog, new_0, 0}},
- {2296, {wxMultiChoiceDialog, new_5, 5}},
- {2297, {wxMultiChoiceDialog, getSelections, 0}},
- {2298, {wxMultiChoiceDialog, setSelections, 1}},
- {2299, {wxMultiChoiceDialog, 'Destroy', undefined}},
- {2300, {wxSingleChoiceDialog, new_0, 0}},
- {2302, {wxSingleChoiceDialog, new_5, 5}},
- {2303, {wxSingleChoiceDialog, getSelection, 0}},
- {2304, {wxSingleChoiceDialog, getStringSelection, 0}},
- {2305, {wxSingleChoiceDialog, setSelection, 1}},
- {2306, {wxSingleChoiceDialog, 'Destroy', undefined}},
- {2307, {wxTextEntryDialog, new, 3}},
- {2308, {wxTextEntryDialog, getValue, 0}},
- {2309, {wxTextEntryDialog, setValue, 1}},
- {2310, {wxTextEntryDialog, 'Destroy', undefined}},
- {2311, {wxPasswordEntryDialog, new, 3}},
- {2312, {wxPasswordEntryDialog, 'Destroy', undefined}},
- {2313, {wxFontData, new_0, 0}},
- {2314, {wxFontData, new_1, 1}},
- {2315, {wxFontData, destruct, 0}},
- {2316, {wxFontData, enableEffects, 1}},
- {2317, {wxFontData, getAllowSymbols, 0}},
- {2318, {wxFontData, getColour, 0}},
- {2319, {wxFontData, getChosenFont, 0}},
- {2320, {wxFontData, getEnableEffects, 0}},
- {2321, {wxFontData, getInitialFont, 0}},
- {2322, {wxFontData, getShowHelp, 0}},
- {2323, {wxFontData, setAllowSymbols, 1}},
- {2324, {wxFontData, setChosenFont, 1}},
- {2325, {wxFontData, setColour, 1}},
- {2326, {wxFontData, setInitialFont, 1}},
- {2327, {wxFontData, setRange, 2}},
- {2328, {wxFontData, setShowHelp, 1}},
- {2332, {wxFontDialog, new_0, 0}},
- {2334, {wxFontDialog, new_2, 2}},
- {2336, {wxFontDialog, create, 2}},
- {2337, {wxFontDialog, getFontData, 0}},
- {2339, {wxFontDialog, 'Destroy', undefined}},
- {2340, {wxProgressDialog, new, 3}},
- {2341, {wxProgressDialog, destruct, 0}},
- {2342, {wxProgressDialog, resume, 0}},
- {2343, {wxProgressDialog, update_2, 2}},
- {2344, {wxProgressDialog, update_0, 0}},
- {2345, {wxMessageDialog, new, 3}},
- {2346, {wxMessageDialog, destruct, 0}},
- {2347, {wxPageSetupDialog, new, 2}},
- {2348, {wxPageSetupDialog, destruct, 0}},
- {2349, {wxPageSetupDialog, getPageSetupData, 0}},
- {2350, {wxPageSetupDialog, showModal, 0}},
- {2351, {wxPageSetupDialogData, new_0, 0}},
- {2352, {wxPageSetupDialogData, new_1_0, 1}},
- {2353, {wxPageSetupDialogData, new_1_1, 1}},
- {2354, {wxPageSetupDialogData, destruct, 0}},
- {2355, {wxPageSetupDialogData, enableHelp, 1}},
- {2356, {wxPageSetupDialogData, enableMargins, 1}},
- {2357, {wxPageSetupDialogData, enableOrientation, 1}},
- {2358, {wxPageSetupDialogData, enablePaper, 1}},
- {2359, {wxPageSetupDialogData, enablePrinter, 1}},
- {2360, {wxPageSetupDialogData, getDefaultMinMargins, 0}},
- {2361, {wxPageSetupDialogData, getEnableMargins, 0}},
- {2362, {wxPageSetupDialogData, getEnableOrientation, 0}},
- {2363, {wxPageSetupDialogData, getEnablePaper, 0}},
- {2364, {wxPageSetupDialogData, getEnablePrinter, 0}},
- {2365, {wxPageSetupDialogData, getEnableHelp, 0}},
- {2366, {wxPageSetupDialogData, getDefaultInfo, 0}},
- {2367, {wxPageSetupDialogData, getMarginTopLeft, 0}},
- {2368, {wxPageSetupDialogData, getMarginBottomRight, 0}},
- {2369, {wxPageSetupDialogData, getMinMarginTopLeft, 0}},
- {2370, {wxPageSetupDialogData, getMinMarginBottomRight, 0}},
- {2371, {wxPageSetupDialogData, getPaperId, 0}},
- {2372, {wxPageSetupDialogData, getPaperSize, 0}},
- {2374, {wxPageSetupDialogData, getPrintData, 0}},
- {2375, {wxPageSetupDialogData, isOk, 0}},
- {2376, {wxPageSetupDialogData, setDefaultInfo, 1}},
- {2377, {wxPageSetupDialogData, setDefaultMinMargins, 1}},
- {2378, {wxPageSetupDialogData, setMarginTopLeft, 1}},
- {2379, {wxPageSetupDialogData, setMarginBottomRight, 1}},
- {2380, {wxPageSetupDialogData, setMinMarginTopLeft, 1}},
- {2381, {wxPageSetupDialogData, setMinMarginBottomRight, 1}},
- {2382, {wxPageSetupDialogData, setPaperId, 1}},
- {2383, {wxPageSetupDialogData, setPaperSize_1_1, 1}},
- {2384, {wxPageSetupDialogData, setPaperSize_1_0, 1}},
- {2385, {wxPageSetupDialogData, setPrintData, 1}},
- {2386, {wxPrintDialog, new_2_0, 2}},
- {2387, {wxPrintDialog, new_2_1, 2}},
- {2388, {wxPrintDialog, destruct, 0}},
- {2389, {wxPrintDialog, getPrintDialogData, 0}},
- {2390, {wxPrintDialog, getPrintDC, 0}},
- {2391, {wxPrintDialogData, new_0, 0}},
- {2392, {wxPrintDialogData, new_1_1, 1}},
- {2393, {wxPrintDialogData, new_1_0, 1}},
- {2394, {wxPrintDialogData, destruct, 0}},
- {2395, {wxPrintDialogData, enableHelp, 1}},
- {2396, {wxPrintDialogData, enablePageNumbers, 1}},
- {2397, {wxPrintDialogData, enablePrintToFile, 1}},
- {2398, {wxPrintDialogData, enableSelection, 1}},
- {2399, {wxPrintDialogData, getAllPages, 0}},
- {2400, {wxPrintDialogData, getCollate, 0}},
- {2401, {wxPrintDialogData, getFromPage, 0}},
- {2402, {wxPrintDialogData, getMaxPage, 0}},
- {2403, {wxPrintDialogData, getMinPage, 0}},
- {2404, {wxPrintDialogData, getNoCopies, 0}},
- {2405, {wxPrintDialogData, getPrintData, 0}},
- {2406, {wxPrintDialogData, getPrintToFile, 0}},
- {2407, {wxPrintDialogData, getSelection, 0}},
- {2408, {wxPrintDialogData, getToPage, 0}},
- {2409, {wxPrintDialogData, isOk, 0}},
- {2410, {wxPrintDialogData, setCollate, 1}},
- {2411, {wxPrintDialogData, setFromPage, 1}},
- {2412, {wxPrintDialogData, setMaxPage, 1}},
- {2413, {wxPrintDialogData, setMinPage, 1}},
- {2414, {wxPrintDialogData, setNoCopies, 1}},
- {2415, {wxPrintDialogData, setPrintData, 1}},
- {2416, {wxPrintDialogData, setPrintToFile, 1}},
- {2417, {wxPrintDialogData, setSelection, 1}},
- {2418, {wxPrintDialogData, setToPage, 1}},
- {2419, {wxPrintData, new_0, 0}},
- {2420, {wxPrintData, new_1, 1}},
- {2421, {wxPrintData, destruct, 0}},
- {2422, {wxPrintData, getCollate, 0}},
- {2423, {wxPrintData, getBin, 0}},
- {2424, {wxPrintData, getColour, 0}},
- {2425, {wxPrintData, getDuplex, 0}},
- {2426, {wxPrintData, getNoCopies, 0}},
- {2427, {wxPrintData, getOrientation, 0}},
- {2428, {wxPrintData, getPaperId, 0}},
- {2429, {wxPrintData, getPrinterName, 0}},
- {2430, {wxPrintData, getQuality, 0}},
- {2431, {wxPrintData, isOk, 0}},
- {2432, {wxPrintData, setBin, 1}},
- {2433, {wxPrintData, setCollate, 1}},
- {2434, {wxPrintData, setColour, 1}},
- {2435, {wxPrintData, setDuplex, 1}},
- {2436, {wxPrintData, setNoCopies, 1}},
- {2437, {wxPrintData, setOrientation, 1}},
- {2438, {wxPrintData, setPaperId, 1}},
- {2439, {wxPrintData, setPrinterName, 1}},
- {2440, {wxPrintData, setQuality, 1}},
- {2443, {wxPrintPreview, new_2, 2}},
- {2444, {wxPrintPreview, new_3, 3}},
- {2446, {wxPrintPreview, destruct, 0}},
- {2447, {wxPrintPreview, getCanvas, 0}},
- {2448, {wxPrintPreview, getCurrentPage, 0}},
- {2449, {wxPrintPreview, getFrame, 0}},
- {2450, {wxPrintPreview, getMaxPage, 0}},
- {2451, {wxPrintPreview, getMinPage, 0}},
- {2452, {wxPrintPreview, getPrintout, 0}},
- {2453, {wxPrintPreview, getPrintoutForPrinting, 0}},
- {2454, {wxPrintPreview, isOk, 0}},
- {2455, {wxPrintPreview, paintPage, 2}},
- {2456, {wxPrintPreview, print, 1}},
- {2457, {wxPrintPreview, renderPage, 1}},
- {2458, {wxPrintPreview, setCanvas, 1}},
- {2459, {wxPrintPreview, setCurrentPage, 1}},
- {2460, {wxPrintPreview, setFrame, 1}},
- {2461, {wxPrintPreview, setPrintout, 1}},
- {2462, {wxPrintPreview, setZoom, 1}},
- {2463, {wxPreviewFrame, new, 3}},
- {2464, {wxPreviewFrame, destruct, 0}},
- {2465, {wxPreviewFrame, createControlBar, 0}},
- {2466, {wxPreviewFrame, createCanvas, 0}},
- {2467, {wxPreviewFrame, initialize, 0}},
- {2468, {wxPreviewFrame, onCloseWindow, 1}},
- {2469, {wxPreviewControlBar, new, 4}},
- {2470, {wxPreviewControlBar, destruct, 0}},
- {2471, {wxPreviewControlBar, createButtons, 0}},
- {2472, {wxPreviewControlBar, getPrintPreview, 0}},
- {2473, {wxPreviewControlBar, getZoomControl, 0}},
- {2474, {wxPreviewControlBar, setZoomControl, 1}},
- {2476, {wxPrinter, new, 1}},
- {2477, {wxPrinter, createAbortWindow, 2}},
- {2478, {wxPrinter, getAbort, 0}},
- {2479, {wxPrinter, getLastError, 0}},
- {2480, {wxPrinter, getPrintDialogData, 0}},
- {2481, {wxPrinter, print, 3}},
- {2482, {wxPrinter, printDialog, 1}},
- {2483, {wxPrinter, reportError, 3}},
- {2484, {wxPrinter, setup, 1}},
- {2485, {wxPrinter, 'Destroy', undefined}},
- {2486, {wxXmlResource, new_1, 1}},
- {2487, {wxXmlResource, new_2, 2}},
- {2488, {wxXmlResource, destruct, 0}},
- {2489, {wxXmlResource, attachUnknownControl, 3}},
- {2490, {wxXmlResource, clearHandlers, 0}},
- {2491, {wxXmlResource, compareVersion, 4}},
- {2492, {wxXmlResource, get, 0}},
- {2493, {wxXmlResource, getFlags, 0}},
- {2494, {wxXmlResource, getVersion, 0}},
- {2495, {wxXmlResource, getXRCID, 2}},
- {2496, {wxXmlResource, initAllHandlers, 0}},
- {2497, {wxXmlResource, load, 1}},
- {2498, {wxXmlResource, loadBitmap, 1}},
- {2499, {wxXmlResource, loadDialog_2, 2}},
- {2500, {wxXmlResource, loadDialog_3, 3}},
- {2501, {wxXmlResource, loadFrame_2, 2}},
- {2502, {wxXmlResource, loadFrame_3, 3}},
- {2503, {wxXmlResource, loadIcon, 1}},
- {2504, {wxXmlResource, loadMenu, 1}},
- {2505, {wxXmlResource, loadMenuBar_2, 2}},
- {2506, {wxXmlResource, loadMenuBar_1, 1}},
- {2507, {wxXmlResource, loadPanel_2, 2}},
- {2508, {wxXmlResource, loadPanel_3, 3}},
- {2509, {wxXmlResource, loadToolBar, 2}},
- {2510, {wxXmlResource, set, 1}},
- {2511, {wxXmlResource, setFlags, 1}},
- {2512, {wxXmlResource, unload, 1}},
- {2513, {wxXmlResource, xrcctrl, 3}},
- {2514, {wxHtmlEasyPrinting, new, 1}},
- {2515, {wxHtmlEasyPrinting, destruct, 0}},
- {2516, {wxHtmlEasyPrinting, getPrintData, 0}},
- {2517, {wxHtmlEasyPrinting, getPageSetupData, 0}},
- {2518, {wxHtmlEasyPrinting, previewFile, 1}},
- {2519, {wxHtmlEasyPrinting, previewText, 2}},
- {2520, {wxHtmlEasyPrinting, printFile, 1}},
- {2521, {wxHtmlEasyPrinting, printText, 2}},
- {2522, {wxHtmlEasyPrinting, pageSetup, 0}},
- {2523, {wxHtmlEasyPrinting, setFonts, 3}},
- {2524, {wxHtmlEasyPrinting, setHeader, 2}},
- {2525, {wxHtmlEasyPrinting, setFooter, 2}},
- {2527, {wxGLCanvas, new_2, 2}},
- {2528, {wxGLCanvas, new_3_1, 3}},
- {2529, {wxGLCanvas, new_3_0, 3}},
- {2530, {wxGLCanvas, getContext, 0}},
- {2532, {wxGLCanvas, setCurrent, 0}},
- {2533, {wxGLCanvas, swapBuffers, 0}},
- {2534, {wxGLCanvas, 'Destroy', undefined}},
- {2535, {wxAuiManager, new, 1}},
- {2536, {wxAuiManager, destruct, 0}},
- {2537, {wxAuiManager, addPane_2_1, 2}},
- {2538, {wxAuiManager, addPane_3, 3}},
- {2539, {wxAuiManager, addPane_2_0, 2}},
- {2540, {wxAuiManager, detachPane, 1}},
- {2541, {wxAuiManager, getAllPanes, 0}},
- {2542, {wxAuiManager, getArtProvider, 0}},
- {2543, {wxAuiManager, getDockSizeConstraint, 2}},
- {2544, {wxAuiManager, getFlags, 0}},
- {2545, {wxAuiManager, getManagedWindow, 0}},
- {2546, {wxAuiManager, getManager, 1}},
- {2547, {wxAuiManager, getPane_1_1, 1}},
- {2548, {wxAuiManager, getPane_1_0, 1}},
- {2549, {wxAuiManager, hideHint, 0}},
- {2550, {wxAuiManager, insertPane, 3}},
- {2551, {wxAuiManager, loadPaneInfo, 2}},
- {2552, {wxAuiManager, loadPerspective, 2}},
- {2553, {wxAuiManager, savePaneInfo, 1}},
- {2554, {wxAuiManager, savePerspective, 0}},
- {2555, {wxAuiManager, setArtProvider, 1}},
- {2556, {wxAuiManager, setDockSizeConstraint, 2}},
- {2557, {wxAuiManager, setFlags, 1}},
- {2558, {wxAuiManager, setManagedWindow, 1}},
- {2559, {wxAuiManager, showHint, 1}},
- {2560, {wxAuiManager, unInit, 0}},
- {2561, {wxAuiManager, update, 0}},
- {2562, {wxAuiPaneInfo, new_0, 0}},
- {2563, {wxAuiPaneInfo, new_1, 1}},
- {2564, {wxAuiPaneInfo, destruct, 0}},
- {2565, {wxAuiPaneInfo, bestSize_1, 1}},
- {2566, {wxAuiPaneInfo, bestSize_2, 2}},
- {2567, {wxAuiPaneInfo, bottom, 0}},
- {2568, {wxAuiPaneInfo, bottomDockable, 1}},
- {2569, {wxAuiPaneInfo, caption, 1}},
- {2570, {wxAuiPaneInfo, captionVisible, 1}},
- {2571, {wxAuiPaneInfo, centre, 0}},
- {2572, {wxAuiPaneInfo, centrePane, 0}},
- {2573, {wxAuiPaneInfo, closeButton, 1}},
- {2574, {wxAuiPaneInfo, defaultPane, 0}},
- {2575, {wxAuiPaneInfo, destroyOnClose, 1}},
- {2576, {wxAuiPaneInfo, direction, 1}},
- {2577, {wxAuiPaneInfo, dock, 0}},
- {2578, {wxAuiPaneInfo, dockable, 1}},
- {2579, {wxAuiPaneInfo, fixed, 0}},
- {2580, {wxAuiPaneInfo, float, 0}},
- {2581, {wxAuiPaneInfo, floatable, 1}},
- {2582, {wxAuiPaneInfo, floatingPosition_1, 1}},
- {2583, {wxAuiPaneInfo, floatingPosition_2, 2}},
- {2584, {wxAuiPaneInfo, floatingSize_1, 1}},
- {2585, {wxAuiPaneInfo, floatingSize_2, 2}},
- {2586, {wxAuiPaneInfo, gripper, 1}},
- {2587, {wxAuiPaneInfo, gripperTop, 1}},
- {2588, {wxAuiPaneInfo, hasBorder, 0}},
- {2589, {wxAuiPaneInfo, hasCaption, 0}},
- {2590, {wxAuiPaneInfo, hasCloseButton, 0}},
- {2591, {wxAuiPaneInfo, hasFlag, 1}},
- {2592, {wxAuiPaneInfo, hasGripper, 0}},
- {2593, {wxAuiPaneInfo, hasGripperTop, 0}},
- {2594, {wxAuiPaneInfo, hasMaximizeButton, 0}},
- {2595, {wxAuiPaneInfo, hasMinimizeButton, 0}},
- {2596, {wxAuiPaneInfo, hasPinButton, 0}},
- {2597, {wxAuiPaneInfo, hide, 0}},
- {2598, {wxAuiPaneInfo, isBottomDockable, 0}},
- {2599, {wxAuiPaneInfo, isDocked, 0}},
- {2600, {wxAuiPaneInfo, isFixed, 0}},
- {2601, {wxAuiPaneInfo, isFloatable, 0}},
- {2602, {wxAuiPaneInfo, isFloating, 0}},
- {2603, {wxAuiPaneInfo, isLeftDockable, 0}},
- {2604, {wxAuiPaneInfo, isMovable, 0}},
- {2605, {wxAuiPaneInfo, isOk, 0}},
- {2606, {wxAuiPaneInfo, isResizable, 0}},
- {2607, {wxAuiPaneInfo, isRightDockable, 0}},
- {2608, {wxAuiPaneInfo, isShown, 0}},
- {2609, {wxAuiPaneInfo, isToolbar, 0}},
- {2610, {wxAuiPaneInfo, isTopDockable, 0}},
- {2611, {wxAuiPaneInfo, layer, 1}},
- {2612, {wxAuiPaneInfo, left, 0}},
- {2613, {wxAuiPaneInfo, leftDockable, 1}},
- {2614, {wxAuiPaneInfo, maxSize_1, 1}},
- {2615, {wxAuiPaneInfo, maxSize_2, 2}},
- {2616, {wxAuiPaneInfo, maximizeButton, 1}},
- {2617, {wxAuiPaneInfo, minSize_1, 1}},
- {2618, {wxAuiPaneInfo, minSize_2, 2}},
- {2619, {wxAuiPaneInfo, minimizeButton, 1}},
- {2620, {wxAuiPaneInfo, movable, 1}},
- {2621, {wxAuiPaneInfo, name, 1}},
- {2622, {wxAuiPaneInfo, paneBorder, 1}},
- {2623, {wxAuiPaneInfo, pinButton, 1}},
- {2624, {wxAuiPaneInfo, position, 1}},
- {2625, {wxAuiPaneInfo, resizable, 1}},
- {2626, {wxAuiPaneInfo, right, 0}},
- {2627, {wxAuiPaneInfo, rightDockable, 1}},
- {2628, {wxAuiPaneInfo, row, 1}},
- {2629, {wxAuiPaneInfo, safeSet, 1}},
- {2630, {wxAuiPaneInfo, setFlag, 2}},
- {2631, {wxAuiPaneInfo, show, 1}},
- {2632, {wxAuiPaneInfo, toolbarPane, 0}},
- {2633, {wxAuiPaneInfo, top, 0}},
- {2634, {wxAuiPaneInfo, topDockable, 1}},
- {2635, {wxAuiPaneInfo, window, 1}},
- {2636, {wxAuiNotebook, new_0, 0}},
- {2637, {wxAuiNotebook, new_2, 2}},
- {2638, {wxAuiNotebook, addPage, 3}},
- {2639, {wxAuiNotebook, create, 2}},
- {2640, {wxAuiNotebook, deletePage, 1}},
- {2641, {wxAuiNotebook, getArtProvider, 0}},
- {2642, {wxAuiNotebook, getPage, 1}},
- {2643, {wxAuiNotebook, getPageBitmap, 1}},
- {2644, {wxAuiNotebook, getPageCount, 0}},
- {2645, {wxAuiNotebook, getPageIndex, 1}},
- {2646, {wxAuiNotebook, getPageText, 1}},
- {2647, {wxAuiNotebook, getSelection, 0}},
- {2648, {wxAuiNotebook, insertPage, 4}},
- {2649, {wxAuiNotebook, removePage, 1}},
- {2650, {wxAuiNotebook, setArtProvider, 1}},
- {2651, {wxAuiNotebook, setFont, 1}},
- {2652, {wxAuiNotebook, setPageBitmap, 2}},
- {2653, {wxAuiNotebook, setPageText, 2}},
- {2654, {wxAuiNotebook, setSelection, 1}},
- {2655, {wxAuiNotebook, setTabCtrlHeight, 1}},
- {2656, {wxAuiNotebook, setUniformBitmapSize, 1}},
- {2657, {wxAuiNotebook, 'Destroy', undefined}},
- {2658, {wxMDIParentFrame, new_0, 0}},
- {2659, {wxMDIParentFrame, new_4, 4}},
- {2660, {wxMDIParentFrame, destruct, 0}},
- {2661, {wxMDIParentFrame, activateNext, 0}},
- {2662, {wxMDIParentFrame, activatePrevious, 0}},
- {2663, {wxMDIParentFrame, arrangeIcons, 0}},
- {2664, {wxMDIParentFrame, cascade, 0}},
- {2665, {wxMDIParentFrame, create, 4}},
- {2666, {wxMDIParentFrame, getActiveChild, 0}},
- {2667, {wxMDIParentFrame, getClientWindow, 0}},
- {2668, {wxMDIParentFrame, tile, 1}},
- {2669, {wxMDIChildFrame, new_0, 0}},
- {2670, {wxMDIChildFrame, new_4, 4}},
- {2671, {wxMDIChildFrame, destruct, 0}},
- {2672, {wxMDIChildFrame, activate, 0}},
- {2673, {wxMDIChildFrame, create, 4}},
- {2674, {wxMDIChildFrame, maximize, 1}},
- {2675, {wxMDIChildFrame, restore, 0}},
- {2676, {wxMDIClientWindow, new_0, 0}},
- {2677, {wxMDIClientWindow, new_2, 2}},
- {2678, {wxMDIClientWindow, destruct, 0}},
- {2679, {wxMDIClientWindow, createClient, 2}},
- {2680, {wxLayoutAlgorithm, new, 0}},
- {2681, {wxLayoutAlgorithm, layoutFrame, 2}},
- {2682, {wxLayoutAlgorithm, layoutMDIFrame, 2}},
- {2683, {wxLayoutAlgorithm, layoutWindow, 2}},
- {2684, {wxLayoutAlgorithm, 'Destroy', undefined}},
- {2685, {wxEvent, getId, 0}},
- {2686, {wxEvent, getSkipped, 0}},
- {2687, {wxEvent, getTimestamp, 0}},
- {2688, {wxEvent, isCommandEvent, 0}},
- {2689, {wxEvent, resumePropagation, 1}},
- {2690, {wxEvent, shouldPropagate, 0}},
- {2691, {wxEvent, skip, 1}},
- {2692, {wxEvent, stopPropagation, 0}},
- {2693, {wxCommandEvent, getClientData, 0}},
- {2694, {wxCommandEvent, getExtraLong, 0}},
- {2695, {wxCommandEvent, getInt, 0}},
- {2696, {wxCommandEvent, getSelection, 0}},
- {2697, {wxCommandEvent, getString, 0}},
- {2698, {wxCommandEvent, isChecked, 0}},
- {2699, {wxCommandEvent, isSelection, 0}},
- {2700, {wxCommandEvent, setInt, 1}},
- {2701, {wxCommandEvent, setString, 1}},
- {2702, {wxScrollEvent, getOrientation, 0}},
- {2703, {wxScrollEvent, getPosition, 0}},
- {2704, {wxScrollWinEvent, getOrientation, 0}},
- {2705, {wxScrollWinEvent, getPosition, 0}},
- {2706, {wxMouseEvent, altDown, 0}},
- {2707, {wxMouseEvent, button, 1}},
- {2708, {wxMouseEvent, buttonDClick, 1}},
- {2709, {wxMouseEvent, buttonDown, 1}},
- {2710, {wxMouseEvent, buttonUp, 1}},
- {2711, {wxMouseEvent, cmdDown, 0}},
- {2712, {wxMouseEvent, controlDown, 0}},
- {2713, {wxMouseEvent, dragging, 0}},
- {2714, {wxMouseEvent, entering, 0}},
- {2715, {wxMouseEvent, getButton, 0}},
- {2718, {wxMouseEvent, getPosition, 0}},
- {2719, {wxMouseEvent, getLogicalPosition, 1}},
- {2720, {wxMouseEvent, getLinesPerAction, 0}},
- {2721, {wxMouseEvent, getWheelRotation, 0}},
- {2722, {wxMouseEvent, getWheelDelta, 0}},
- {2723, {wxMouseEvent, getX, 0}},
- {2724, {wxMouseEvent, getY, 0}},
- {2725, {wxMouseEvent, isButton, 0}},
- {2726, {wxMouseEvent, isPageScroll, 0}},
- {2727, {wxMouseEvent, leaving, 0}},
- {2728, {wxMouseEvent, leftDClick, 0}},
- {2729, {wxMouseEvent, leftDown, 0}},
- {2730, {wxMouseEvent, leftIsDown, 0}},
- {2731, {wxMouseEvent, leftUp, 0}},
- {2732, {wxMouseEvent, metaDown, 0}},
- {2733, {wxMouseEvent, middleDClick, 0}},
- {2734, {wxMouseEvent, middleDown, 0}},
- {2735, {wxMouseEvent, middleIsDown, 0}},
- {2736, {wxMouseEvent, middleUp, 0}},
- {2737, {wxMouseEvent, moving, 0}},
- {2738, {wxMouseEvent, rightDClick, 0}},
- {2739, {wxMouseEvent, rightDown, 0}},
- {2740, {wxMouseEvent, rightIsDown, 0}},
- {2741, {wxMouseEvent, rightUp, 0}},
- {2742, {wxMouseEvent, shiftDown, 0}},
- {2743, {wxSetCursorEvent, getCursor, 0}},
- {2744, {wxSetCursorEvent, getX, 0}},
- {2745, {wxSetCursorEvent, getY, 0}},
- {2746, {wxSetCursorEvent, hasCursor, 0}},
- {2747, {wxSetCursorEvent, setCursor, 1}},
- {2748, {wxKeyEvent, altDown, 0}},
- {2749, {wxKeyEvent, cmdDown, 0}},
- {2750, {wxKeyEvent, controlDown, 0}},
- {2751, {wxKeyEvent, getKeyCode, 0}},
- {2752, {wxKeyEvent, getModifiers, 0}},
- {2755, {wxKeyEvent, getPosition, 0}},
- {2756, {wxKeyEvent, getRawKeyCode, 0}},
- {2757, {wxKeyEvent, getRawKeyFlags, 0}},
- {2758, {wxKeyEvent, getUnicodeKey, 0}},
- {2759, {wxKeyEvent, getX, 0}},
- {2760, {wxKeyEvent, getY, 0}},
- {2761, {wxKeyEvent, hasModifiers, 0}},
- {2762, {wxKeyEvent, metaDown, 0}},
- {2763, {wxKeyEvent, shiftDown, 0}},
- {2764, {wxSizeEvent, getSize, 0}},
- {2765, {wxMoveEvent, getPosition, 0}},
- {2766, {wxEraseEvent, getDC, 0}},
- {2767, {wxFocusEvent, getWindow, 0}},
- {2768, {wxChildFocusEvent, getWindow, 0}},
- {2769, {wxMenuEvent, getMenu, 0}},
- {2770, {wxMenuEvent, getMenuId, 0}},
- {2771, {wxMenuEvent, isPopup, 0}},
- {2772, {wxCloseEvent, canVeto, 0}},
- {2773, {wxCloseEvent, getLoggingOff, 0}},
- {2774, {wxCloseEvent, setCanVeto, 1}},
- {2775, {wxCloseEvent, setLoggingOff, 1}},
- {2776, {wxCloseEvent, veto, 1}},
- {2777, {wxShowEvent, setShow, 1}},
- {2778, {wxShowEvent, getShow, 0}},
- {2779, {wxIconizeEvent, iconized, 0}},
- {2780, {wxJoystickEvent, buttonDown, 1}},
- {2781, {wxJoystickEvent, buttonIsDown, 1}},
- {2782, {wxJoystickEvent, buttonUp, 1}},
- {2783, {wxJoystickEvent, getButtonChange, 0}},
- {2784, {wxJoystickEvent, getButtonState, 0}},
- {2785, {wxJoystickEvent, getJoystick, 0}},
- {2786, {wxJoystickEvent, getPosition, 0}},
- {2787, {wxJoystickEvent, getZPosition, 0}},
- {2788, {wxJoystickEvent, isButton, 0}},
- {2789, {wxJoystickEvent, isMove, 0}},
- {2790, {wxJoystickEvent, isZMove, 0}},
- {2791, {wxUpdateUIEvent, canUpdate, 1}},
- {2792, {wxUpdateUIEvent, check, 1}},
- {2793, {wxUpdateUIEvent, enable, 1}},
- {2794, {wxUpdateUIEvent, show, 1}},
- {2795, {wxUpdateUIEvent, getChecked, 0}},
- {2796, {wxUpdateUIEvent, getEnabled, 0}},
- {2797, {wxUpdateUIEvent, getShown, 0}},
- {2798, {wxUpdateUIEvent, getSetChecked, 0}},
- {2799, {wxUpdateUIEvent, getSetEnabled, 0}},
- {2800, {wxUpdateUIEvent, getSetShown, 0}},
- {2801, {wxUpdateUIEvent, getSetText, 0}},
- {2802, {wxUpdateUIEvent, getText, 0}},
- {2803, {wxUpdateUIEvent, getMode, 0}},
- {2804, {wxUpdateUIEvent, getUpdateInterval, 0}},
- {2805, {wxUpdateUIEvent, resetUpdateTime, 0}},
- {2806, {wxUpdateUIEvent, setMode, 1}},
- {2807, {wxUpdateUIEvent, setText, 1}},
- {2808, {wxUpdateUIEvent, setUpdateInterval, 1}},
- {2809, {wxMouseCaptureChangedEvent, getCapturedWindow, 0}},
- {2810, {wxPaletteChangedEvent, setChangedWindow, 1}},
- {2811, {wxPaletteChangedEvent, getChangedWindow, 0}},
- {2812, {wxQueryNewPaletteEvent, setPaletteRealized, 1}},
- {2813, {wxQueryNewPaletteEvent, getPaletteRealized, 0}},
- {2814, {wxNavigationKeyEvent, getDirection, 0}},
- {2815, {wxNavigationKeyEvent, setDirection, 1}},
- {2816, {wxNavigationKeyEvent, isWindowChange, 0}},
- {2817, {wxNavigationKeyEvent, setWindowChange, 1}},
- {2818, {wxNavigationKeyEvent, isFromTab, 0}},
- {2819, {wxNavigationKeyEvent, setFromTab, 1}},
- {2820, {wxNavigationKeyEvent, getCurrentFocus, 0}},
- {2821, {wxNavigationKeyEvent, setCurrentFocus, 1}},
- {2822, {wxHelpEvent, getOrigin, 0}},
- {2823, {wxHelpEvent, getPosition, 0}},
- {2824, {wxHelpEvent, setOrigin, 1}},
- {2825, {wxHelpEvent, setPosition, 1}},
- {2826, {wxContextMenuEvent, getPosition, 0}},
- {2827, {wxContextMenuEvent, setPosition, 1}},
- {2828, {wxIdleEvent, canSend, 1}},
- {2829, {wxIdleEvent, getMode, 0}},
- {2830, {wxIdleEvent, requestMore, 1}},
- {2831, {wxIdleEvent, moreRequested, 0}},
- {2832, {wxIdleEvent, setMode, 1}},
- {2833, {wxGridEvent, altDown, 0}},
- {2834, {wxGridEvent, controlDown, 0}},
- {2835, {wxGridEvent, getCol, 0}},
- {2836, {wxGridEvent, getPosition, 0}},
- {2837, {wxGridEvent, getRow, 0}},
- {2838, {wxGridEvent, metaDown, 0}},
- {2839, {wxGridEvent, selecting, 0}},
- {2840, {wxGridEvent, shiftDown, 0}},
- {2841, {wxNotifyEvent, allow, 0}},
- {2842, {wxNotifyEvent, isAllowed, 0}},
- {2843, {wxNotifyEvent, veto, 0}},
- {2844, {wxSashEvent, getEdge, 0}},
- {2845, {wxSashEvent, getDragRect, 0}},
- {2846, {wxSashEvent, getDragStatus, 0}},
- {2847, {wxListEvent, getCacheFrom, 0}},
- {2848, {wxListEvent, getCacheTo, 0}},
- {2849, {wxListEvent, getKeyCode, 0}},
- {2850, {wxListEvent, getIndex, 0}},
- {2851, {wxListEvent, getColumn, 0}},
- {2852, {wxListEvent, getPoint, 0}},
- {2853, {wxListEvent, getLabel, 0}},
- {2854, {wxListEvent, getText, 0}},
- {2855, {wxListEvent, getImage, 0}},
- {2856, {wxListEvent, getData, 0}},
- {2857, {wxListEvent, getMask, 0}},
- {2858, {wxListEvent, getItem, 0}},
- {2859, {wxListEvent, isEditCancelled, 0}},
- {2860, {wxDateEvent, getDate, 0}},
- {2861, {wxCalendarEvent, getWeekDay, 0}},
- {2862, {wxFileDirPickerEvent, getPath, 0}},
- {2863, {wxColourPickerEvent, getColour, 0}},
- {2864, {wxFontPickerEvent, getFont, 0}},
- {2865, {wxStyledTextEvent, getPosition, 0}},
- {2866, {wxStyledTextEvent, getKey, 0}},
- {2867, {wxStyledTextEvent, getModifiers, 0}},
- {2868, {wxStyledTextEvent, getModificationType, 0}},
- {2869, {wxStyledTextEvent, getText, 0}},
- {2870, {wxStyledTextEvent, getLength, 0}},
- {2871, {wxStyledTextEvent, getLinesAdded, 0}},
- {2872, {wxStyledTextEvent, getLine, 0}},
- {2873, {wxStyledTextEvent, getFoldLevelNow, 0}},
- {2874, {wxStyledTextEvent, getFoldLevelPrev, 0}},
- {2875, {wxStyledTextEvent, getMargin, 0}},
- {2876, {wxStyledTextEvent, getMessage, 0}},
- {2877, {wxStyledTextEvent, getWParam, 0}},
- {2878, {wxStyledTextEvent, getLParam, 0}},
- {2879, {wxStyledTextEvent, getListType, 0}},
- {2880, {wxStyledTextEvent, getX, 0}},
- {2881, {wxStyledTextEvent, getY, 0}},
- {2882, {wxStyledTextEvent, getDragText, 0}},
- {2883, {wxStyledTextEvent, getDragAllowMove, 0}},
- {2884, {wxStyledTextEvent, getDragResult, 0}},
- {2885, {wxStyledTextEvent, getShift, 0}},
- {2886, {wxStyledTextEvent, getControl, 0}},
- {2887, {wxStyledTextEvent, getAlt, 0}},
- {2888, {utils, getKeyState, 1}},
- {2889, {utils, getMousePosition, 2}},
- {2890, {utils, getMouseState, 0}},
- {2891, {utils, setDetectableAutoRepeat, 1}},
- {2892, {utils, bell, 0}},
- {2893, {utils, findMenuItemId, 3}},
- {2894, {utils, genericFindWindowAtPoint, 1}},
- {2895, {utils, findWindowAtPoint, 1}},
- {2896, {utils, beginBusyCursor, 1}},
- {2897, {utils, endBusyCursor, 0}},
- {2898, {utils, isBusy, 0}},
- {2899, {utils, shutdown, 1}},
- {2900, {utils, shell, 1}},
- {2901, {utils, launchDefaultBrowser, 2}},
- {2902, {utils, getEmailAddress, 0}},
- {2903, {utils, getUserId, 0}},
- {2904, {utils, getHomeDir, 0}},
- {2905, {utils, newId, 0}},
- {2906, {utils, registerId, 1}},
- {2907, {utils, getCurrentId, 0}},
- {2908, {utils, getOsDescription, 0}},
- {2909, {utils, isPlatformLittleEndian, 0}},
- {2910, {utils, isPlatform64Bit, 0}},
- {2911, {wxPrintout, new, 1}},
- {2912, {wxPrintout, destruct, 0}},
- {2913, {wxPrintout, getDC, 0}},
- {2914, {wxPrintout, getPageSizeMM, 2}},
- {2915, {wxPrintout, getPageSizePixels, 2}},
- {2916, {wxPrintout, getPaperRectPixels, 0}},
- {2917, {wxPrintout, getPPIPrinter, 2}},
- {2918, {wxPrintout, getPPIScreen, 2}},
- {2919, {wxPrintout, getTitle, 0}},
- {2920, {wxPrintout, isPreview, 0}},
- {2921, {wxPrintout, fitThisSizeToPaper, 1}},
- {2922, {wxPrintout, fitThisSizeToPage, 1}},
- {2923, {wxPrintout, fitThisSizeToPageMargins, 2}},
- {2924, {wxPrintout, mapScreenSizeToPaper, 0}},
- {2925, {wxPrintout, mapScreenSizeToPage, 0}},
- {2926, {wxPrintout, mapScreenSizeToPageMargins, 1}},
- {2927, {wxPrintout, mapScreenSizeToDevice, 0}},
- {2928, {wxPrintout, getLogicalPaperRect, 0}},
- {2929, {wxPrintout, getLogicalPageRect, 0}},
- {2930, {wxPrintout, getLogicalPageMarginsRect, 1}},
- {2931, {wxPrintout, setLogicalOrigin, 2}},
- {2932, {wxPrintout, offsetLogicalOrigin, 2}},
- {2933, {wxStyledTextCtrl, new_2, 2}},
- {2934, {wxStyledTextCtrl, new_0, 0}},
- {2935, {wxStyledTextCtrl, destruct, 0}},
- {2936, {wxStyledTextCtrl, create, 2}},
- {2937, {wxStyledTextCtrl, addText, 1}},
- {2938, {wxStyledTextCtrl, addStyledText, 1}},
- {2939, {wxStyledTextCtrl, insertText, 2}},
- {2940, {wxStyledTextCtrl, clearAll, 0}},
- {2941, {wxStyledTextCtrl, clearDocumentStyle, 0}},
- {2942, {wxStyledTextCtrl, getLength, 0}},
- {2943, {wxStyledTextCtrl, getCharAt, 1}},
- {2944, {wxStyledTextCtrl, getCurrentPos, 0}},
- {2945, {wxStyledTextCtrl, getAnchor, 0}},
- {2946, {wxStyledTextCtrl, getStyleAt, 1}},
- {2947, {wxStyledTextCtrl, redo, 0}},
- {2948, {wxStyledTextCtrl, setUndoCollection, 1}},
- {2949, {wxStyledTextCtrl, selectAll, 0}},
- {2950, {wxStyledTextCtrl, setSavePoint, 0}},
- {2951, {wxStyledTextCtrl, getStyledText, 2}},
- {2952, {wxStyledTextCtrl, canRedo, 0}},
- {2953, {wxStyledTextCtrl, markerLineFromHandle, 1}},
- {2954, {wxStyledTextCtrl, markerDeleteHandle, 1}},
- {2955, {wxStyledTextCtrl, getUndoCollection, 0}},
- {2956, {wxStyledTextCtrl, getViewWhiteSpace, 0}},
- {2957, {wxStyledTextCtrl, setViewWhiteSpace, 1}},
- {2958, {wxStyledTextCtrl, positionFromPoint, 1}},
- {2959, {wxStyledTextCtrl, positionFromPointClose, 2}},
- {2960, {wxStyledTextCtrl, gotoLine, 1}},
- {2961, {wxStyledTextCtrl, gotoPos, 1}},
- {2962, {wxStyledTextCtrl, setAnchor, 1}},
- {2963, {wxStyledTextCtrl, getCurLine, 1}},
- {2964, {wxStyledTextCtrl, getEndStyled, 0}},
- {2965, {wxStyledTextCtrl, convertEOLs, 1}},
- {2966, {wxStyledTextCtrl, getEOLMode, 0}},
- {2967, {wxStyledTextCtrl, setEOLMode, 1}},
- {2968, {wxStyledTextCtrl, startStyling, 2}},
- {2969, {wxStyledTextCtrl, setStyling, 2}},
- {2970, {wxStyledTextCtrl, getBufferedDraw, 0}},
- {2971, {wxStyledTextCtrl, setBufferedDraw, 1}},
- {2972, {wxStyledTextCtrl, setTabWidth, 1}},
- {2973, {wxStyledTextCtrl, getTabWidth, 0}},
- {2974, {wxStyledTextCtrl, setCodePage, 1}},
- {2975, {wxStyledTextCtrl, markerDefine, 3}},
- {2976, {wxStyledTextCtrl, markerSetForeground, 2}},
- {2977, {wxStyledTextCtrl, markerSetBackground, 2}},
- {2978, {wxStyledTextCtrl, markerAdd, 2}},
- {2979, {wxStyledTextCtrl, markerDelete, 2}},
- {2980, {wxStyledTextCtrl, markerDeleteAll, 1}},
- {2981, {wxStyledTextCtrl, markerGet, 1}},
- {2982, {wxStyledTextCtrl, markerNext, 2}},
- {2983, {wxStyledTextCtrl, markerPrevious, 2}},
- {2984, {wxStyledTextCtrl, markerDefineBitmap, 2}},
- {2985, {wxStyledTextCtrl, markerAddSet, 2}},
- {2986, {wxStyledTextCtrl, markerSetAlpha, 2}},
- {2987, {wxStyledTextCtrl, setMarginType, 2}},
- {2988, {wxStyledTextCtrl, getMarginType, 1}},
- {2989, {wxStyledTextCtrl, setMarginWidth, 2}},
- {2990, {wxStyledTextCtrl, getMarginWidth, 1}},
- {2991, {wxStyledTextCtrl, setMarginMask, 2}},
- {2992, {wxStyledTextCtrl, getMarginMask, 1}},
- {2993, {wxStyledTextCtrl, setMarginSensitive, 2}},
- {2994, {wxStyledTextCtrl, getMarginSensitive, 1}},
- {2995, {wxStyledTextCtrl, styleClearAll, 0}},
- {2996, {wxStyledTextCtrl, styleSetForeground, 2}},
- {2997, {wxStyledTextCtrl, styleSetBackground, 2}},
- {2998, {wxStyledTextCtrl, styleSetBold, 2}},
- {2999, {wxStyledTextCtrl, styleSetItalic, 2}},
- {3000, {wxStyledTextCtrl, styleSetSize, 2}},
- {3001, {wxStyledTextCtrl, styleSetFaceName, 2}},
- {3002, {wxStyledTextCtrl, styleSetEOLFilled, 2}},
- {3003, {wxStyledTextCtrl, styleResetDefault, 0}},
- {3004, {wxStyledTextCtrl, styleSetUnderline, 2}},
- {3005, {wxStyledTextCtrl, styleSetCase, 2}},
- {3006, {wxStyledTextCtrl, styleSetHotSpot, 2}},
- {3007, {wxStyledTextCtrl, setSelForeground, 2}},
- {3008, {wxStyledTextCtrl, setSelBackground, 2}},
- {3009, {wxStyledTextCtrl, getSelAlpha, 0}},
- {3010, {wxStyledTextCtrl, setSelAlpha, 1}},
- {3011, {wxStyledTextCtrl, setCaretForeground, 1}},
- {3012, {wxStyledTextCtrl, cmdKeyAssign, 3}},
- {3013, {wxStyledTextCtrl, cmdKeyClear, 2}},
- {3014, {wxStyledTextCtrl, cmdKeyClearAll, 0}},
- {3015, {wxStyledTextCtrl, setStyleBytes, 2}},
- {3016, {wxStyledTextCtrl, styleSetVisible, 2}},
- {3017, {wxStyledTextCtrl, getCaretPeriod, 0}},
- {3018, {wxStyledTextCtrl, setCaretPeriod, 1}},
- {3019, {wxStyledTextCtrl, setWordChars, 1}},
- {3020, {wxStyledTextCtrl, beginUndoAction, 0}},
- {3021, {wxStyledTextCtrl, endUndoAction, 0}},
- {3022, {wxStyledTextCtrl, indicatorSetStyle, 2}},
- {3023, {wxStyledTextCtrl, indicatorGetStyle, 1}},
- {3024, {wxStyledTextCtrl, indicatorSetForeground, 2}},
- {3025, {wxStyledTextCtrl, indicatorGetForeground, 1}},
- {3026, {wxStyledTextCtrl, setWhitespaceForeground, 2}},
- {3027, {wxStyledTextCtrl, setWhitespaceBackground, 2}},
- {3028, {wxStyledTextCtrl, getStyleBits, 0}},
- {3029, {wxStyledTextCtrl, setLineState, 2}},
- {3030, {wxStyledTextCtrl, getLineState, 1}},
- {3031, {wxStyledTextCtrl, getMaxLineState, 0}},
- {3032, {wxStyledTextCtrl, getCaretLineVisible, 0}},
- {3033, {wxStyledTextCtrl, setCaretLineVisible, 1}},
- {3034, {wxStyledTextCtrl, getCaretLineBackground, 0}},
- {3035, {wxStyledTextCtrl, setCaretLineBackground, 1}},
- {3036, {wxStyledTextCtrl, autoCompShow, 2}},
- {3037, {wxStyledTextCtrl, autoCompCancel, 0}},
- {3038, {wxStyledTextCtrl, autoCompActive, 0}},
- {3039, {wxStyledTextCtrl, autoCompPosStart, 0}},
- {3040, {wxStyledTextCtrl, autoCompComplete, 0}},
- {3041, {wxStyledTextCtrl, autoCompStops, 1}},
- {3042, {wxStyledTextCtrl, autoCompSetSeparator, 1}},
- {3043, {wxStyledTextCtrl, autoCompGetSeparator, 0}},
- {3044, {wxStyledTextCtrl, autoCompSelect, 1}},
- {3045, {wxStyledTextCtrl, autoCompSetCancelAtStart, 1}},
- {3046, {wxStyledTextCtrl, autoCompGetCancelAtStart, 0}},
- {3047, {wxStyledTextCtrl, autoCompSetFillUps, 1}},
- {3048, {wxStyledTextCtrl, autoCompSetChooseSingle, 1}},
- {3049, {wxStyledTextCtrl, autoCompGetChooseSingle, 0}},
- {3050, {wxStyledTextCtrl, autoCompSetIgnoreCase, 1}},
- {3051, {wxStyledTextCtrl, autoCompGetIgnoreCase, 0}},
- {3052, {wxStyledTextCtrl, userListShow, 2}},
- {3053, {wxStyledTextCtrl, autoCompSetAutoHide, 1}},
- {3054, {wxStyledTextCtrl, autoCompGetAutoHide, 0}},
- {3055, {wxStyledTextCtrl, autoCompSetDropRestOfWord, 1}},
- {3056, {wxStyledTextCtrl, autoCompGetDropRestOfWord, 0}},
- {3057, {wxStyledTextCtrl, registerImage, 2}},
- {3058, {wxStyledTextCtrl, clearRegisteredImages, 0}},
- {3059, {wxStyledTextCtrl, autoCompGetTypeSeparator, 0}},
- {3060, {wxStyledTextCtrl, autoCompSetTypeSeparator, 1}},
- {3061, {wxStyledTextCtrl, autoCompSetMaxWidth, 1}},
- {3062, {wxStyledTextCtrl, autoCompGetMaxWidth, 0}},
- {3063, {wxStyledTextCtrl, autoCompSetMaxHeight, 1}},
- {3064, {wxStyledTextCtrl, autoCompGetMaxHeight, 0}},
- {3065, {wxStyledTextCtrl, setIndent, 1}},
- {3066, {wxStyledTextCtrl, getIndent, 0}},
- {3067, {wxStyledTextCtrl, setUseTabs, 1}},
- {3068, {wxStyledTextCtrl, getUseTabs, 0}},
- {3069, {wxStyledTextCtrl, setLineIndentation, 2}},
- {3070, {wxStyledTextCtrl, getLineIndentation, 1}},
- {3071, {wxStyledTextCtrl, getLineIndentPosition, 1}},
- {3072, {wxStyledTextCtrl, getColumn, 1}},
- {3073, {wxStyledTextCtrl, setUseHorizontalScrollBar, 1}},
- {3074, {wxStyledTextCtrl, getUseHorizontalScrollBar, 0}},
- {3075, {wxStyledTextCtrl, setIndentationGuides, 1}},
- {3076, {wxStyledTextCtrl, getIndentationGuides, 0}},
- {3077, {wxStyledTextCtrl, setHighlightGuide, 1}},
- {3078, {wxStyledTextCtrl, getHighlightGuide, 0}},
- {3079, {wxStyledTextCtrl, getLineEndPosition, 1}},
- {3080, {wxStyledTextCtrl, getCodePage, 0}},
- {3081, {wxStyledTextCtrl, getCaretForeground, 0}},
- {3082, {wxStyledTextCtrl, getReadOnly, 0}},
- {3083, {wxStyledTextCtrl, setCurrentPos, 1}},
- {3084, {wxStyledTextCtrl, setSelectionStart, 1}},
- {3085, {wxStyledTextCtrl, getSelectionStart, 0}},
- {3086, {wxStyledTextCtrl, setSelectionEnd, 1}},
- {3087, {wxStyledTextCtrl, getSelectionEnd, 0}},
- {3088, {wxStyledTextCtrl, setPrintMagnification, 1}},
- {3089, {wxStyledTextCtrl, getPrintMagnification, 0}},
- {3090, {wxStyledTextCtrl, setPrintColourMode, 1}},
- {3091, {wxStyledTextCtrl, getPrintColourMode, 0}},
- {3092, {wxStyledTextCtrl, findText, 4}},
- {3093, {wxStyledTextCtrl, formatRange, 7}},
- {3094, {wxStyledTextCtrl, getFirstVisibleLine, 0}},
- {3095, {wxStyledTextCtrl, getLine, 1}},
- {3096, {wxStyledTextCtrl, getLineCount, 0}},
- {3097, {wxStyledTextCtrl, setMarginLeft, 1}},
- {3098, {wxStyledTextCtrl, getMarginLeft, 0}},
- {3099, {wxStyledTextCtrl, setMarginRight, 1}},
- {3100, {wxStyledTextCtrl, getMarginRight, 0}},
- {3101, {wxStyledTextCtrl, getModify, 0}},
- {3102, {wxStyledTextCtrl, setSelection, 2}},
- {3103, {wxStyledTextCtrl, getSelectedText, 0}},
- {3104, {wxStyledTextCtrl, getTextRange, 2}},
- {3105, {wxStyledTextCtrl, hideSelection, 1}},
- {3106, {wxStyledTextCtrl, lineFromPosition, 1}},
- {3107, {wxStyledTextCtrl, positionFromLine, 1}},
- {3108, {wxStyledTextCtrl, lineScroll, 2}},
- {3109, {wxStyledTextCtrl, ensureCaretVisible, 0}},
- {3110, {wxStyledTextCtrl, replaceSelection, 1}},
- {3111, {wxStyledTextCtrl, setReadOnly, 1}},
- {3112, {wxStyledTextCtrl, canPaste, 0}},
- {3113, {wxStyledTextCtrl, canUndo, 0}},
- {3114, {wxStyledTextCtrl, emptyUndoBuffer, 0}},
- {3115, {wxStyledTextCtrl, undo, 0}},
- {3116, {wxStyledTextCtrl, cut, 0}},
- {3117, {wxStyledTextCtrl, copy, 0}},
- {3118, {wxStyledTextCtrl, paste, 0}},
- {3119, {wxStyledTextCtrl, clear, 0}},
- {3120, {wxStyledTextCtrl, setText, 1}},
- {3121, {wxStyledTextCtrl, getText, 0}},
- {3122, {wxStyledTextCtrl, getTextLength, 0}},
- {3123, {wxStyledTextCtrl, getOvertype, 0}},
- {3124, {wxStyledTextCtrl, setCaretWidth, 1}},
- {3125, {wxStyledTextCtrl, getCaretWidth, 0}},
- {3126, {wxStyledTextCtrl, setTargetStart, 1}},
- {3127, {wxStyledTextCtrl, getTargetStart, 0}},
- {3128, {wxStyledTextCtrl, setTargetEnd, 1}},
- {3129, {wxStyledTextCtrl, getTargetEnd, 0}},
- {3130, {wxStyledTextCtrl, replaceTarget, 1}},
- {3131, {wxStyledTextCtrl, searchInTarget, 1}},
- {3132, {wxStyledTextCtrl, setSearchFlags, 1}},
- {3133, {wxStyledTextCtrl, getSearchFlags, 0}},
- {3134, {wxStyledTextCtrl, callTipShow, 2}},
- {3135, {wxStyledTextCtrl, callTipCancel, 0}},
- {3136, {wxStyledTextCtrl, callTipActive, 0}},
- {3137, {wxStyledTextCtrl, callTipPosAtStart, 0}},
- {3138, {wxStyledTextCtrl, callTipSetHighlight, 2}},
- {3139, {wxStyledTextCtrl, callTipSetBackground, 1}},
- {3140, {wxStyledTextCtrl, callTipSetForeground, 1}},
- {3141, {wxStyledTextCtrl, callTipSetForegroundHighlight, 1}},
- {3142, {wxStyledTextCtrl, callTipUseStyle, 1}},
- {3143, {wxStyledTextCtrl, visibleFromDocLine, 1}},
- {3144, {wxStyledTextCtrl, docLineFromVisible, 1}},
- {3145, {wxStyledTextCtrl, wrapCount, 1}},
- {3146, {wxStyledTextCtrl, setFoldLevel, 2}},
- {3147, {wxStyledTextCtrl, getFoldLevel, 1}},
- {3148, {wxStyledTextCtrl, getLastChild, 2}},
- {3149, {wxStyledTextCtrl, getFoldParent, 1}},
- {3150, {wxStyledTextCtrl, showLines, 2}},
- {3151, {wxStyledTextCtrl, hideLines, 2}},
- {3152, {wxStyledTextCtrl, getLineVisible, 1}},
- {3153, {wxStyledTextCtrl, setFoldExpanded, 2}},
- {3154, {wxStyledTextCtrl, getFoldExpanded, 1}},
- {3155, {wxStyledTextCtrl, toggleFold, 1}},
- {3156, {wxStyledTextCtrl, ensureVisible, 1}},
- {3157, {wxStyledTextCtrl, setFoldFlags, 1}},
- {3158, {wxStyledTextCtrl, ensureVisibleEnforcePolicy, 1}},
- {3159, {wxStyledTextCtrl, setTabIndents, 1}},
- {3160, {wxStyledTextCtrl, getTabIndents, 0}},
- {3161, {wxStyledTextCtrl, setBackSpaceUnIndents, 1}},
- {3162, {wxStyledTextCtrl, getBackSpaceUnIndents, 0}},
- {3163, {wxStyledTextCtrl, setMouseDwellTime, 1}},
- {3164, {wxStyledTextCtrl, getMouseDwellTime, 0}},
- {3165, {wxStyledTextCtrl, wordStartPosition, 2}},
- {3166, {wxStyledTextCtrl, wordEndPosition, 2}},
- {3167, {wxStyledTextCtrl, setWrapMode, 1}},
- {3168, {wxStyledTextCtrl, getWrapMode, 0}},
- {3169, {wxStyledTextCtrl, setWrapVisualFlags, 1}},
- {3170, {wxStyledTextCtrl, getWrapVisualFlags, 0}},
- {3171, {wxStyledTextCtrl, setWrapVisualFlagsLocation, 1}},
- {3172, {wxStyledTextCtrl, getWrapVisualFlagsLocation, 0}},
- {3173, {wxStyledTextCtrl, setWrapStartIndent, 1}},
- {3174, {wxStyledTextCtrl, getWrapStartIndent, 0}},
- {3175, {wxStyledTextCtrl, setLayoutCache, 1}},
- {3176, {wxStyledTextCtrl, getLayoutCache, 0}},
- {3177, {wxStyledTextCtrl, setScrollWidth, 1}},
- {3178, {wxStyledTextCtrl, getScrollWidth, 0}},
- {3179, {wxStyledTextCtrl, textWidth, 2}},
- {3180, {wxStyledTextCtrl, getEndAtLastLine, 0}},
- {3181, {wxStyledTextCtrl, textHeight, 1}},
- {3182, {wxStyledTextCtrl, setUseVerticalScrollBar, 1}},
- {3183, {wxStyledTextCtrl, getUseVerticalScrollBar, 0}},
- {3184, {wxStyledTextCtrl, appendText, 1}},
- {3185, {wxStyledTextCtrl, getTwoPhaseDraw, 0}},
- {3186, {wxStyledTextCtrl, setTwoPhaseDraw, 1}},
- {3187, {wxStyledTextCtrl, targetFromSelection, 0}},
- {3188, {wxStyledTextCtrl, linesJoin, 0}},
- {3189, {wxStyledTextCtrl, linesSplit, 1}},
- {3190, {wxStyledTextCtrl, setFoldMarginColour, 2}},
- {3191, {wxStyledTextCtrl, setFoldMarginHiColour, 2}},
- {3192, {wxStyledTextCtrl, lineDown, 0}},
- {3193, {wxStyledTextCtrl, lineDownExtend, 0}},
- {3194, {wxStyledTextCtrl, lineUp, 0}},
- {3195, {wxStyledTextCtrl, lineUpExtend, 0}},
- {3196, {wxStyledTextCtrl, charLeft, 0}},
- {3197, {wxStyledTextCtrl, charLeftExtend, 0}},
- {3198, {wxStyledTextCtrl, charRight, 0}},
- {3199, {wxStyledTextCtrl, charRightExtend, 0}},
- {3200, {wxStyledTextCtrl, wordLeft, 0}},
- {3201, {wxStyledTextCtrl, wordLeftExtend, 0}},
- {3202, {wxStyledTextCtrl, wordRight, 0}},
- {3203, {wxStyledTextCtrl, wordRightExtend, 0}},
- {3204, {wxStyledTextCtrl, home, 0}},
- {3205, {wxStyledTextCtrl, homeExtend, 0}},
- {3206, {wxStyledTextCtrl, lineEnd, 0}},
- {3207, {wxStyledTextCtrl, lineEndExtend, 0}},
- {3208, {wxStyledTextCtrl, documentStart, 0}},
- {3209, {wxStyledTextCtrl, documentStartExtend, 0}},
- {3210, {wxStyledTextCtrl, documentEnd, 0}},
- {3211, {wxStyledTextCtrl, documentEndExtend, 0}},
- {3212, {wxStyledTextCtrl, pageUp, 0}},
- {3213, {wxStyledTextCtrl, pageUpExtend, 0}},
- {3214, {wxStyledTextCtrl, pageDown, 0}},
- {3215, {wxStyledTextCtrl, pageDownExtend, 0}},
- {3216, {wxStyledTextCtrl, editToggleOvertype, 0}},
- {3217, {wxStyledTextCtrl, cancel, 0}},
- {3218, {wxStyledTextCtrl, deleteBack, 0}},
- {3219, {wxStyledTextCtrl, tab, 0}},
- {3220, {wxStyledTextCtrl, backTab, 0}},
- {3221, {wxStyledTextCtrl, newLine, 0}},
- {3222, {wxStyledTextCtrl, formFeed, 0}},
- {3223, {wxStyledTextCtrl, vCHome, 0}},
- {3224, {wxStyledTextCtrl, vCHomeExtend, 0}},
- {3225, {wxStyledTextCtrl, zoomIn, 0}},
- {3226, {wxStyledTextCtrl, zoomOut, 0}},
- {3227, {wxStyledTextCtrl, delWordLeft, 0}},
- {3228, {wxStyledTextCtrl, delWordRight, 0}},
- {3229, {wxStyledTextCtrl, lineCut, 0}},
- {3230, {wxStyledTextCtrl, lineDelete, 0}},
- {3231, {wxStyledTextCtrl, lineTranspose, 0}},
- {3232, {wxStyledTextCtrl, lineDuplicate, 0}},
- {3233, {wxStyledTextCtrl, lowerCase, 0}},
- {3234, {wxStyledTextCtrl, upperCase, 0}},
- {3235, {wxStyledTextCtrl, lineScrollDown, 0}},
- {3236, {wxStyledTextCtrl, lineScrollUp, 0}},
- {3237, {wxStyledTextCtrl, deleteBackNotLine, 0}},
- {3238, {wxStyledTextCtrl, homeDisplay, 0}},
- {3239, {wxStyledTextCtrl, homeDisplayExtend, 0}},
- {3240, {wxStyledTextCtrl, lineEndDisplay, 0}},
- {3241, {wxStyledTextCtrl, lineEndDisplayExtend, 0}},
- {3242, {wxStyledTextCtrl, homeWrapExtend, 0}},
- {3243, {wxStyledTextCtrl, lineEndWrap, 0}},
- {3244, {wxStyledTextCtrl, lineEndWrapExtend, 0}},
- {3245, {wxStyledTextCtrl, vCHomeWrap, 0}},
- {3246, {wxStyledTextCtrl, vCHomeWrapExtend, 0}},
- {3247, {wxStyledTextCtrl, lineCopy, 0}},
- {3248, {wxStyledTextCtrl, moveCaretInsideView, 0}},
- {3249, {wxStyledTextCtrl, lineLength, 1}},
- {3250, {wxStyledTextCtrl, braceHighlight, 2}},
- {3251, {wxStyledTextCtrl, braceBadLight, 1}},
- {3252, {wxStyledTextCtrl, braceMatch, 1}},
- {3253, {wxStyledTextCtrl, getViewEOL, 0}},
- {3254, {wxStyledTextCtrl, setViewEOL, 1}},
- {3255, {wxStyledTextCtrl, setModEventMask, 1}},
- {3256, {wxStyledTextCtrl, getEdgeColumn, 0}},
- {3257, {wxStyledTextCtrl, setEdgeColumn, 1}},
- {3258, {wxStyledTextCtrl, getEdgeMode, 0}},
- {3259, {wxStyledTextCtrl, getEdgeColour, 0}},
- {3260, {wxStyledTextCtrl, setEdgeColour, 1}},
- {3261, {wxStyledTextCtrl, searchAnchor, 0}},
- {3262, {wxStyledTextCtrl, searchNext, 2}},
- {3263, {wxStyledTextCtrl, searchPrev, 2}},
- {3264, {wxStyledTextCtrl, linesOnScreen, 0}},
- {3265, {wxStyledTextCtrl, usePopUp, 1}},
- {3266, {wxStyledTextCtrl, selectionIsRectangle, 0}},
- {3267, {wxStyledTextCtrl, setZoom, 1}},
- {3268, {wxStyledTextCtrl, getZoom, 0}},
- {3269, {wxStyledTextCtrl, getModEventMask, 0}},
- {3270, {wxStyledTextCtrl, setSTCFocus, 1}},
- {3271, {wxStyledTextCtrl, getSTCFocus, 0}},
- {3272, {wxStyledTextCtrl, setStatus, 1}},
- {3273, {wxStyledTextCtrl, getStatus, 0}},
- {3274, {wxStyledTextCtrl, setMouseDownCaptures, 1}},
- {3275, {wxStyledTextCtrl, getMouseDownCaptures, 0}},
- {3276, {wxStyledTextCtrl, setSTCCursor, 1}},
- {3277, {wxStyledTextCtrl, getSTCCursor, 0}},
- {3278, {wxStyledTextCtrl, setControlCharSymbol, 1}},
- {3279, {wxStyledTextCtrl, getControlCharSymbol, 0}},
- {3280, {wxStyledTextCtrl, wordPartLeft, 0}},
- {3281, {wxStyledTextCtrl, wordPartLeftExtend, 0}},
- {3282, {wxStyledTextCtrl, wordPartRight, 0}},
- {3283, {wxStyledTextCtrl, wordPartRightExtend, 0}},
- {3284, {wxStyledTextCtrl, setVisiblePolicy, 2}},
- {3285, {wxStyledTextCtrl, delLineLeft, 0}},
- {3286, {wxStyledTextCtrl, delLineRight, 0}},
- {3287, {wxStyledTextCtrl, getXOffset, 0}},
- {3288, {wxStyledTextCtrl, chooseCaretX, 0}},
- {3289, {wxStyledTextCtrl, setXCaretPolicy, 2}},
- {3290, {wxStyledTextCtrl, setYCaretPolicy, 2}},
- {3291, {wxStyledTextCtrl, getPrintWrapMode, 0}},
- {3292, {wxStyledTextCtrl, setHotspotActiveForeground, 2}},
- {3293, {wxStyledTextCtrl, setHotspotActiveBackground, 2}},
- {3294, {wxStyledTextCtrl, setHotspotActiveUnderline, 1}},
- {3295, {wxStyledTextCtrl, setHotspotSingleLine, 1}},
- {3296, {wxStyledTextCtrl, paraDownExtend, 0}},
- {3297, {wxStyledTextCtrl, paraUp, 0}},
- {3298, {wxStyledTextCtrl, paraUpExtend, 0}},
- {3299, {wxStyledTextCtrl, positionBefore, 1}},
- {3300, {wxStyledTextCtrl, positionAfter, 1}},
- {3301, {wxStyledTextCtrl, copyRange, 2}},
- {3302, {wxStyledTextCtrl, copyText, 2}},
- {3303, {wxStyledTextCtrl, setSelectionMode, 1}},
- {3304, {wxStyledTextCtrl, getSelectionMode, 0}},
- {3305, {wxStyledTextCtrl, lineDownRectExtend, 0}},
- {3306, {wxStyledTextCtrl, lineUpRectExtend, 0}},
- {3307, {wxStyledTextCtrl, charLeftRectExtend, 0}},
- {3308, {wxStyledTextCtrl, charRightRectExtend, 0}},
- {3309, {wxStyledTextCtrl, homeRectExtend, 0}},
- {3310, {wxStyledTextCtrl, vCHomeRectExtend, 0}},
- {3311, {wxStyledTextCtrl, lineEndRectExtend, 0}},
- {3312, {wxStyledTextCtrl, pageUpRectExtend, 0}},
- {3313, {wxStyledTextCtrl, pageDownRectExtend, 0}},
- {3314, {wxStyledTextCtrl, stutteredPageUp, 0}},
- {3315, {wxStyledTextCtrl, stutteredPageUpExtend, 0}},
- {3316, {wxStyledTextCtrl, stutteredPageDown, 0}},
- {3317, {wxStyledTextCtrl, stutteredPageDownExtend, 0}},
- {3318, {wxStyledTextCtrl, wordLeftEnd, 0}},
- {3319, {wxStyledTextCtrl, wordLeftEndExtend, 0}},
- {3320, {wxStyledTextCtrl, wordRightEnd, 0}},
- {3321, {wxStyledTextCtrl, wordRightEndExtend, 0}},
- {3322, {wxStyledTextCtrl, setWhitespaceChars, 1}},
- {3323, {wxStyledTextCtrl, setCharsDefault, 0}},
- {3324, {wxStyledTextCtrl, autoCompGetCurrent, 0}},
- {3325, {wxStyledTextCtrl, allocate, 1}},
- {3326, {wxStyledTextCtrl, findColumn, 2}},
- {3327, {wxStyledTextCtrl, getCaretSticky, 0}},
- {3328, {wxStyledTextCtrl, setCaretSticky, 1}},
- {3329, {wxStyledTextCtrl, toggleCaretSticky, 0}},
- {3330, {wxStyledTextCtrl, setPasteConvertEndings, 1}},
- {3331, {wxStyledTextCtrl, getPasteConvertEndings, 0}},
- {3332, {wxStyledTextCtrl, selectionDuplicate, 0}},
- {3333, {wxStyledTextCtrl, setCaretLineBackAlpha, 1}},
- {3334, {wxStyledTextCtrl, getCaretLineBackAlpha, 0}},
- {3335, {wxStyledTextCtrl, startRecord, 0}},
- {3336, {wxStyledTextCtrl, stopRecord, 0}},
- {3337, {wxStyledTextCtrl, setLexer, 1}},
- {3338, {wxStyledTextCtrl, getLexer, 0}},
- {3339, {wxStyledTextCtrl, colourise, 2}},
- {3340, {wxStyledTextCtrl, setProperty, 2}},
- {3341, {wxStyledTextCtrl, setKeyWords, 2}},
- {3342, {wxStyledTextCtrl, setLexerLanguage, 1}},
- {3343, {wxStyledTextCtrl, getProperty, 1}},
- {3344, {wxStyledTextCtrl, getStyleBitsNeeded, 0}},
- {3345, {wxStyledTextCtrl, getCurrentLine, 0}},
- {3346, {wxStyledTextCtrl, styleSetSpec, 2}},
- {3347, {wxStyledTextCtrl, styleSetFont, 2}},
- {3348, {wxStyledTextCtrl, styleSetFontAttr, 7}},
- {3349, {wxStyledTextCtrl, styleSetCharacterSet, 2}},
- {3350, {wxStyledTextCtrl, styleSetFontEncoding, 2}},
- {3351, {wxStyledTextCtrl, cmdKeyExecute, 1}},
- {3352, {wxStyledTextCtrl, setMargins, 2}},
- {3353, {wxStyledTextCtrl, getSelection, 2}},
- {3354, {wxStyledTextCtrl, pointFromPosition, 1}},
- {3355, {wxStyledTextCtrl, scrollToLine, 1}},
- {3356, {wxStyledTextCtrl, scrollToColumn, 1}},
- {3357, {wxStyledTextCtrl, sendMsg, 2}},
- {3358, {wxStyledTextCtrl, setVScrollBar, 1}},
- {3359, {wxStyledTextCtrl, setHScrollBar, 1}},
- {3360, {wxStyledTextCtrl, getLastKeydownProcessed, 0}},
- {3361, {wxStyledTextCtrl, setLastKeydownProcessed, 1}},
- {3362, {wxStyledTextCtrl, saveFile, 1}},
- {3363, {wxStyledTextCtrl, loadFile, 1}},
- {3364, {wxStyledTextCtrl, doDragOver, 3}},
- {3365, {wxStyledTextCtrl, doDropText, 3}},
- {3366, {wxStyledTextCtrl, getUseAntiAliasing, 0}},
- {3367, {wxStyledTextCtrl, addTextRaw, 1}},
- {3368, {wxStyledTextCtrl, insertTextRaw, 2}},
- {3369, {wxStyledTextCtrl, getCurLineRaw, 1}},
- {3370, {wxStyledTextCtrl, getLineRaw, 1}},
- {3371, {wxStyledTextCtrl, getSelectedTextRaw, 0}},
- {3372, {wxStyledTextCtrl, getTextRangeRaw, 2}},
- {3373, {wxStyledTextCtrl, setTextRaw, 1}},
- {3374, {wxStyledTextCtrl, getTextRaw, 0}},
- {3375, {wxStyledTextCtrl, appendTextRaw, 1}},
- {3376, {wxArtProvider, getBitmap, 2}},
- {3377, {wxArtProvider, getIcon, 2}},
- {3378, {wxTreeEvent, getKeyCode, 0}},
- {3379, {wxTreeEvent, getItem, 0}},
- {3380, {wxTreeEvent, getKeyEvent, 0}},
- {3381, {wxTreeEvent, getLabel, 0}},
- {3382, {wxTreeEvent, getOldItem, 0}},
- {3383, {wxTreeEvent, getPoint, 0}},
- {3384, {wxTreeEvent, isEditCancelled, 0}},
- {3385, {wxTreeEvent, setToolTip, 1}},
- {3386, {wxNotebookEvent, getOldSelection, 0}},
- {3387, {wxNotebookEvent, getSelection, 0}},
- {3388, {wxNotebookEvent, setOldSelection, 1}},
- {3389, {wxNotebookEvent, setSelection, 1}},
- {3390, {wxFileDataObject, new, 0}},
- {3391, {wxFileDataObject, addFile, 1}},
- {3392, {wxFileDataObject, getFilenames, 0}},
- {3393, {wxFileDataObject, 'Destroy', undefined}},
- {3394, {wxTextDataObject, new, 1}},
- {3395, {wxTextDataObject, getTextLength, 0}},
- {3396, {wxTextDataObject, getText, 0}},
- {3397, {wxTextDataObject, setText, 1}},
- {3398, {wxTextDataObject, 'Destroy', undefined}},
- {3399, {wxBitmapDataObject, new_1_1, 1}},
- {3400, {wxBitmapDataObject, new_1_0, 1}},
- {3401, {wxBitmapDataObject, getBitmap, 0}},
- {3402, {wxBitmapDataObject, setBitmap, 1}},
- {3403, {wxBitmapDataObject, 'Destroy', undefined}},
- {3405, {wxClipboard, new, 0}},
- {3406, {wxClipboard, destruct, 0}},
- {3407, {wxClipboard, addData, 1}},
- {3408, {wxClipboard, clear, 0}},
- {3409, {wxClipboard, close, 0}},
- {3410, {wxClipboard, flush, 0}},
- {3411, {wxClipboard, getData, 1}},
- {3412, {wxClipboard, isOpened, 0}},
- {3413, {wxClipboard, open, 0}},
- {3414, {wxClipboard, setData, 1}},
- {3416, {wxClipboard, usePrimarySelection, 1}},
- {3417, {wxClipboard, isSupported, 1}},
- {3418, {wxClipboard, get, 0}},
- {3419, {wxSpinEvent, getPosition, 0}},
- {3420, {wxSpinEvent, setPosition, 1}},
- {3421, {wxSplitterWindow, new_0, 0}},
- {3422, {wxSplitterWindow, new_2, 2}},
- {3423, {wxSplitterWindow, destruct, 0}},
- {3424, {wxSplitterWindow, create, 2}},
- {3425, {wxSplitterWindow, getMinimumPaneSize, 0}},
- {3426, {wxSplitterWindow, getSashGravity, 0}},
- {3427, {wxSplitterWindow, getSashPosition, 0}},
- {3428, {wxSplitterWindow, getSplitMode, 0}},
- {3429, {wxSplitterWindow, getWindow1, 0}},
- {3430, {wxSplitterWindow, getWindow2, 0}},
- {3431, {wxSplitterWindow, initialize, 1}},
- {3432, {wxSplitterWindow, isSplit, 0}},
- {3433, {wxSplitterWindow, replaceWindow, 2}},
- {3434, {wxSplitterWindow, setSashGravity, 1}},
- {3435, {wxSplitterWindow, setSashPosition, 2}},
- {3436, {wxSplitterWindow, setSashSize, 1}},
- {3437, {wxSplitterWindow, setMinimumPaneSize, 1}},
- {3438, {wxSplitterWindow, setSplitMode, 1}},
- {3439, {wxSplitterWindow, splitHorizontally, 3}},
- {3440, {wxSplitterWindow, splitVertically, 3}},
- {3441, {wxSplitterWindow, unsplit, 1}},
- {3442, {wxSplitterWindow, updateSize, 0}},
- {3443, {wxSplitterEvent, getSashPosition, 0}},
- {3444, {wxSplitterEvent, getX, 0}},
- {3445, {wxSplitterEvent, getY, 0}},
- {3446, {wxSplitterEvent, getWindowBeingRemoved, 0}},
- {3447, {wxSplitterEvent, setSashPosition, 1}},
- {3448, {wxHtmlWindow, new_0, 0}},
- {3449, {wxHtmlWindow, new_2, 2}},
- {3450, {wxHtmlWindow, appendToPage, 1}},
- {3451, {wxHtmlWindow, getOpenedAnchor, 0}},
- {3452, {wxHtmlWindow, getOpenedPage, 0}},
- {3453, {wxHtmlWindow, getOpenedPageTitle, 0}},
- {3454, {wxHtmlWindow, getRelatedFrame, 0}},
- {3455, {wxHtmlWindow, historyBack, 0}},
- {3456, {wxHtmlWindow, historyCanBack, 0}},
- {3457, {wxHtmlWindow, historyCanForward, 0}},
- {3458, {wxHtmlWindow, historyClear, 0}},
- {3459, {wxHtmlWindow, historyForward, 0}},
- {3460, {wxHtmlWindow, loadFile, 1}},
- {3461, {wxHtmlWindow, loadPage, 1}},
- {3462, {wxHtmlWindow, selectAll, 0}},
- {3463, {wxHtmlWindow, selectionToText, 0}},
- {3464, {wxHtmlWindow, selectLine, 1}},
- {3465, {wxHtmlWindow, selectWord, 1}},
- {3466, {wxHtmlWindow, setBorders, 1}},
- {3467, {wxHtmlWindow, setFonts, 3}},
- {3468, {wxHtmlWindow, setPage, 1}},
- {3469, {wxHtmlWindow, setRelatedFrame, 2}},
- {3470, {wxHtmlWindow, setRelatedStatusBar, 1}},
- {3471, {wxHtmlWindow, toText, 0}},
- {3472, {wxHtmlWindow, 'Destroy', undefined}},
- {3473, {wxHtmlLinkEvent, getLinkInfo, 0}},
- {3474, {wxAuiNotebookEvent, setSelection, 1}},
- {3475, {wxAuiNotebookEvent, getSelection, 0}},
- {3476, {wxAuiNotebookEvent, setOldSelection, 1}},
- {3477, {wxAuiNotebookEvent, getOldSelection, 0}},
- {3478, {wxAuiNotebookEvent, setDragSource, 1}},
- {3479, {wxAuiNotebookEvent, getDragSource, 0}},
- {3480, {wxAuiManagerEvent, setManager, 1}},
- {3481, {wxAuiManagerEvent, getManager, 0}},
- {3482, {wxAuiManagerEvent, setPane, 1}},
- {3483, {wxAuiManagerEvent, getPane, 0}},
- {3484, {wxAuiManagerEvent, setButton, 1}},
- {3485, {wxAuiManagerEvent, getButton, 0}},
- {3486, {wxAuiManagerEvent, setDC, 1}},
- {3487, {wxAuiManagerEvent, getDC, 0}},
- {3488, {wxAuiManagerEvent, veto, 1}},
- {3489, {wxAuiManagerEvent, getVeto, 0}},
- {3490, {wxAuiManagerEvent, setCanVeto, 1}},
- {3491, {wxAuiManagerEvent, canVeto, 0}},
- {3492, {wxLogNull, new, 0}},
- {3493, {wxLogNull, 'Destroy', undefined}},
+ {1675, {wxListCtrl, getEditControl, 0}},
+ {1676, {wxListCtrl, getImageList, 1}},
+ {1677, {wxListCtrl, getItem, 1}},
+ {1678, {wxListCtrl, getItemBackgroundColour, 1}},
+ {1679, {wxListCtrl, getItemCount, 0}},
+ {1680, {wxListCtrl, getItemData, 1}},
+ {1681, {wxListCtrl, getItemFont, 1}},
+ {1682, {wxListCtrl, getItemPosition, 2}},
+ {1683, {wxListCtrl, getItemRect, 3}},
+ {1684, {wxListCtrl, getItemSpacing, 0}},
+ {1685, {wxListCtrl, getItemState, 2}},
+ {1686, {wxListCtrl, getItemText, 1}},
+ {1687, {wxListCtrl, getItemTextColour, 1}},
+ {1688, {wxListCtrl, getNextItem, 2}},
+ {1689, {wxListCtrl, getSelectedItemCount, 0}},
+ {1690, {wxListCtrl, getTextColour, 0}},
+ {1691, {wxListCtrl, getTopItem, 0}},
+ {1692, {wxListCtrl, getViewRect, 0}},
+ {1693, {wxListCtrl, hitTest, 2}},
+ {1694, {wxListCtrl, insertColumn_2, 2}},
+ {1695, {wxListCtrl, insertColumn_3, 3}},
+ {1696, {wxListCtrl, insertItem_1, 1}},
+ {1697, {wxListCtrl, insertItem_2_1, 2}},
+ {1698, {wxListCtrl, insertItem_2_0, 2}},
+ {1699, {wxListCtrl, insertItem_3, 3}},
+ {1700, {wxListCtrl, refreshItem, 1}},
+ {1701, {wxListCtrl, refreshItems, 2}},
+ {1702, {wxListCtrl, scrollList, 2}},
+ {1703, {wxListCtrl, setBackgroundColour, 1}},
+ {1704, {wxListCtrl, setColumn, 2}},
+ {1705, {wxListCtrl, setColumnWidth, 2}},
+ {1706, {wxListCtrl, setImageList, 2}},
+ {1707, {wxListCtrl, setItem_1, 1}},
+ {1708, {wxListCtrl, setItem_4, 4}},
+ {1709, {wxListCtrl, setItemBackgroundColour, 2}},
+ {1710, {wxListCtrl, setItemCount, 1}},
+ {1711, {wxListCtrl, setItemData, 2}},
+ {1712, {wxListCtrl, setItemFont, 2}},
+ {1713, {wxListCtrl, setItemImage, 3}},
+ {1714, {wxListCtrl, setItemColumnImage, 3}},
+ {1715, {wxListCtrl, setItemPosition, 2}},
+ {1716, {wxListCtrl, setItemState, 3}},
+ {1717, {wxListCtrl, setItemText, 2}},
+ {1718, {wxListCtrl, setItemTextColour, 2}},
+ {1719, {wxListCtrl, setSingleStyle, 2}},
+ {1720, {wxListCtrl, setTextColour, 1}},
+ {1721, {wxListCtrl, setWindowStyleFlag, 1}},
+ {1722, {wxListCtrl, sortItems, 2}},
+ {1723, {wxListCtrl, 'Destroy', undefined}},
+ {1724, {wxListView, clearColumnImage, 1}},
+ {1725, {wxListView, focus, 1}},
+ {1726, {wxListView, getFirstSelected, 0}},
+ {1727, {wxListView, getFocusedItem, 0}},
+ {1728, {wxListView, getNextSelected, 1}},
+ {1729, {wxListView, isSelected, 1}},
+ {1730, {wxListView, select, 2}},
+ {1731, {wxListView, setColumnImage, 2}},
+ {1732, {wxListItem, new_0, 0}},
+ {1733, {wxListItem, new_1, 1}},
+ {1734, {wxListItem, destruct, 0}},
+ {1735, {wxListItem, clear, 0}},
+ {1736, {wxListItem, getAlign, 0}},
+ {1737, {wxListItem, getBackgroundColour, 0}},
+ {1738, {wxListItem, getColumn, 0}},
+ {1739, {wxListItem, getFont, 0}},
+ {1740, {wxListItem, getId, 0}},
+ {1741, {wxListItem, getImage, 0}},
+ {1742, {wxListItem, getMask, 0}},
+ {1743, {wxListItem, getState, 0}},
+ {1744, {wxListItem, getText, 0}},
+ {1745, {wxListItem, getTextColour, 0}},
+ {1746, {wxListItem, getWidth, 0}},
+ {1747, {wxListItem, setAlign, 1}},
+ {1748, {wxListItem, setBackgroundColour, 1}},
+ {1749, {wxListItem, setColumn, 1}},
+ {1750, {wxListItem, setFont, 1}},
+ {1751, {wxListItem, setId, 1}},
+ {1752, {wxListItem, setImage, 1}},
+ {1753, {wxListItem, setMask, 1}},
+ {1754, {wxListItem, setState, 1}},
+ {1755, {wxListItem, setStateMask, 1}},
+ {1756, {wxListItem, setText, 1}},
+ {1757, {wxListItem, setTextColour, 1}},
+ {1758, {wxListItem, setWidth, 1}},
+ {1759, {wxImageList, new_0, 0}},
+ {1760, {wxImageList, new_3, 3}},
+ {1761, {wxImageList, add_1, 1}},
+ {1762, {wxImageList, add_2_0, 2}},
+ {1763, {wxImageList, add_2_1, 2}},
+ {1764, {wxImageList, create, 3}},
+ {1766, {wxImageList, draw, 5}},
+ {1767, {wxImageList, getBitmap, 1}},
+ {1768, {wxImageList, getIcon, 1}},
+ {1769, {wxImageList, getImageCount, 0}},
+ {1770, {wxImageList, getSize, 3}},
+ {1771, {wxImageList, remove, 1}},
+ {1772, {wxImageList, removeAll, 0}},
+ {1773, {wxImageList, replace_2, 2}},
+ {1774, {wxImageList, replace_3, 3}},
+ {1775, {wxImageList, 'Destroy', undefined}},
+ {1776, {wxTextAttr, new_0, 0}},
+ {1777, {wxTextAttr, new_2, 2}},
+ {1778, {wxTextAttr, getAlignment, 0}},
+ {1779, {wxTextAttr, getBackgroundColour, 0}},
+ {1780, {wxTextAttr, getFont, 0}},
+ {1781, {wxTextAttr, getLeftIndent, 0}},
+ {1782, {wxTextAttr, getLeftSubIndent, 0}},
+ {1783, {wxTextAttr, getRightIndent, 0}},
+ {1784, {wxTextAttr, getTabs, 0}},
+ {1785, {wxTextAttr, getTextColour, 0}},
+ {1786, {wxTextAttr, hasBackgroundColour, 0}},
+ {1787, {wxTextAttr, hasFont, 0}},
+ {1788, {wxTextAttr, hasTextColour, 0}},
+ {1789, {wxTextAttr, getFlags, 0}},
+ {1790, {wxTextAttr, isDefault, 0}},
+ {1791, {wxTextAttr, setAlignment, 1}},
+ {1792, {wxTextAttr, setBackgroundColour, 1}},
+ {1793, {wxTextAttr, setFlags, 1}},
+ {1794, {wxTextAttr, setFont, 2}},
+ {1795, {wxTextAttr, setLeftIndent, 2}},
+ {1796, {wxTextAttr, setRightIndent, 1}},
+ {1797, {wxTextAttr, setTabs, 1}},
+ {1798, {wxTextAttr, setTextColour, 1}},
+ {1799, {wxTextAttr, 'Destroy', undefined}},
+ {1801, {wxTextCtrl, new_3, 3}},
+ {1802, {wxTextCtrl, new_0, 0}},
+ {1804, {wxTextCtrl, destruct, 0}},
+ {1805, {wxTextCtrl, appendText, 1}},
+ {1806, {wxTextCtrl, canCopy, 0}},
+ {1807, {wxTextCtrl, canCut, 0}},
+ {1808, {wxTextCtrl, canPaste, 0}},
+ {1809, {wxTextCtrl, canRedo, 0}},
+ {1810, {wxTextCtrl, canUndo, 0}},
+ {1811, {wxTextCtrl, clear, 0}},
+ {1812, {wxTextCtrl, copy, 0}},
+ {1813, {wxTextCtrl, create, 3}},
+ {1814, {wxTextCtrl, cut, 0}},
+ {1815, {wxTextCtrl, discardEdits, 0}},
+ {1816, {wxTextCtrl, emulateKeyPress, 1}},
+ {1817, {wxTextCtrl, getDefaultStyle, 0}},
+ {1818, {wxTextCtrl, getInsertionPoint, 0}},
+ {1819, {wxTextCtrl, getLastPosition, 0}},
+ {1820, {wxTextCtrl, getLineLength, 1}},
+ {1821, {wxTextCtrl, getLineText, 1}},
+ {1822, {wxTextCtrl, getNumberOfLines, 0}},
+ {1823, {wxTextCtrl, getRange, 2}},
+ {1824, {wxTextCtrl, getSelection, 2}},
+ {1825, {wxTextCtrl, getStringSelection, 0}},
+ {1826, {wxTextCtrl, getStyle, 2}},
+ {1827, {wxTextCtrl, getValue, 0}},
+ {1828, {wxTextCtrl, isEditable, 0}},
+ {1829, {wxTextCtrl, isModified, 0}},
+ {1830, {wxTextCtrl, isMultiLine, 0}},
+ {1831, {wxTextCtrl, isSingleLine, 0}},
+ {1832, {wxTextCtrl, loadFile, 2}},
+ {1833, {wxTextCtrl, markDirty, 0}},
+ {1834, {wxTextCtrl, paste, 0}},
+ {1835, {wxTextCtrl, positionToXY, 3}},
+ {1836, {wxTextCtrl, redo, 0}},
+ {1837, {wxTextCtrl, remove, 2}},
+ {1838, {wxTextCtrl, replace, 3}},
+ {1839, {wxTextCtrl, saveFile, 1}},
+ {1840, {wxTextCtrl, setDefaultStyle, 1}},
+ {1841, {wxTextCtrl, setEditable, 1}},
+ {1842, {wxTextCtrl, setInsertionPoint, 1}},
+ {1843, {wxTextCtrl, setInsertionPointEnd, 0}},
+ {1845, {wxTextCtrl, setMaxLength, 1}},
+ {1846, {wxTextCtrl, setSelection, 2}},
+ {1847, {wxTextCtrl, setStyle, 3}},
+ {1848, {wxTextCtrl, setValue, 1}},
+ {1849, {wxTextCtrl, showPosition, 1}},
+ {1850, {wxTextCtrl, undo, 0}},
+ {1851, {wxTextCtrl, writeText, 1}},
+ {1852, {wxTextCtrl, xYToPosition, 2}},
+ {1855, {wxNotebook, new_0, 0}},
+ {1856, {wxNotebook, new_3, 3}},
+ {1857, {wxNotebook, destruct, 0}},
+ {1858, {wxNotebook, addPage, 3}},
+ {1859, {wxNotebook, advanceSelection, 1}},
+ {1860, {wxNotebook, assignImageList, 1}},
+ {1861, {wxNotebook, create, 3}},
+ {1862, {wxNotebook, deleteAllPages, 0}},
+ {1863, {wxNotebook, deletePage, 1}},
+ {1864, {wxNotebook, removePage, 1}},
+ {1865, {wxNotebook, getCurrentPage, 0}},
+ {1866, {wxNotebook, getImageList, 0}},
+ {1868, {wxNotebook, getPage, 1}},
+ {1869, {wxNotebook, getPageCount, 0}},
+ {1870, {wxNotebook, getPageImage, 1}},
+ {1871, {wxNotebook, getPageText, 1}},
+ {1872, {wxNotebook, getRowCount, 0}},
+ {1873, {wxNotebook, getSelection, 0}},
+ {1874, {wxNotebook, getThemeBackgroundColour, 0}},
+ {1876, {wxNotebook, hitTest, 2}},
+ {1878, {wxNotebook, insertPage, 4}},
+ {1879, {wxNotebook, setImageList, 1}},
+ {1880, {wxNotebook, setPadding, 1}},
+ {1881, {wxNotebook, setPageSize, 1}},
+ {1882, {wxNotebook, setPageImage, 2}},
+ {1883, {wxNotebook, setPageText, 2}},
+ {1884, {wxNotebook, setSelection, 1}},
+ {1885, {wxNotebook, changeSelection, 1}},
+ {1886, {wxChoicebook, new_0, 0}},
+ {1887, {wxChoicebook, new_3, 3}},
+ {1888, {wxChoicebook, addPage, 3}},
+ {1889, {wxChoicebook, advanceSelection, 1}},
+ {1890, {wxChoicebook, assignImageList, 1}},
+ {1891, {wxChoicebook, create, 3}},
+ {1892, {wxChoicebook, deleteAllPages, 0}},
+ {1893, {wxChoicebook, deletePage, 1}},
+ {1894, {wxChoicebook, removePage, 1}},
+ {1895, {wxChoicebook, getCurrentPage, 0}},
+ {1896, {wxChoicebook, getImageList, 0}},
+ {1898, {wxChoicebook, getPage, 1}},
+ {1899, {wxChoicebook, getPageCount, 0}},
+ {1900, {wxChoicebook, getPageImage, 1}},
+ {1901, {wxChoicebook, getPageText, 1}},
+ {1902, {wxChoicebook, getSelection, 0}},
+ {1903, {wxChoicebook, hitTest, 2}},
+ {1904, {wxChoicebook, insertPage, 4}},
+ {1905, {wxChoicebook, setImageList, 1}},
+ {1906, {wxChoicebook, setPageSize, 1}},
+ {1907, {wxChoicebook, setPageImage, 2}},
+ {1908, {wxChoicebook, setPageText, 2}},
+ {1909, {wxChoicebook, setSelection, 1}},
+ {1910, {wxChoicebook, changeSelection, 1}},
+ {1911, {wxChoicebook, 'Destroy', undefined}},
+ {1912, {wxToolbook, new_0, 0}},
+ {1913, {wxToolbook, new_3, 3}},
+ {1914, {wxToolbook, addPage, 3}},
+ {1915, {wxToolbook, advanceSelection, 1}},
+ {1916, {wxToolbook, assignImageList, 1}},
+ {1917, {wxToolbook, create, 3}},
+ {1918, {wxToolbook, deleteAllPages, 0}},
+ {1919, {wxToolbook, deletePage, 1}},
+ {1920, {wxToolbook, removePage, 1}},
+ {1921, {wxToolbook, getCurrentPage, 0}},
+ {1922, {wxToolbook, getImageList, 0}},
+ {1924, {wxToolbook, getPage, 1}},
+ {1925, {wxToolbook, getPageCount, 0}},
+ {1926, {wxToolbook, getPageImage, 1}},
+ {1927, {wxToolbook, getPageText, 1}},
+ {1928, {wxToolbook, getSelection, 0}},
+ {1930, {wxToolbook, hitTest, 2}},
+ {1931, {wxToolbook, insertPage, 4}},
+ {1932, {wxToolbook, setImageList, 1}},
+ {1933, {wxToolbook, setPageSize, 1}},
+ {1934, {wxToolbook, setPageImage, 2}},
+ {1935, {wxToolbook, setPageText, 2}},
+ {1936, {wxToolbook, setSelection, 1}},
+ {1937, {wxToolbook, changeSelection, 1}},
+ {1938, {wxToolbook, 'Destroy', undefined}},
+ {1939, {wxListbook, new_0, 0}},
+ {1940, {wxListbook, new_3, 3}},
+ {1941, {wxListbook, addPage, 3}},
+ {1942, {wxListbook, advanceSelection, 1}},
+ {1943, {wxListbook, assignImageList, 1}},
+ {1944, {wxListbook, create, 3}},
+ {1945, {wxListbook, deleteAllPages, 0}},
+ {1946, {wxListbook, deletePage, 1}},
+ {1947, {wxListbook, removePage, 1}},
+ {1948, {wxListbook, getCurrentPage, 0}},
+ {1949, {wxListbook, getImageList, 0}},
+ {1951, {wxListbook, getPage, 1}},
+ {1952, {wxListbook, getPageCount, 0}},
+ {1953, {wxListbook, getPageImage, 1}},
+ {1954, {wxListbook, getPageText, 1}},
+ {1955, {wxListbook, getSelection, 0}},
+ {1957, {wxListbook, hitTest, 2}},
+ {1958, {wxListbook, insertPage, 4}},
+ {1959, {wxListbook, setImageList, 1}},
+ {1960, {wxListbook, setPageSize, 1}},
+ {1961, {wxListbook, setPageImage, 2}},
+ {1962, {wxListbook, setPageText, 2}},
+ {1963, {wxListbook, setSelection, 1}},
+ {1964, {wxListbook, changeSelection, 1}},
+ {1965, {wxListbook, 'Destroy', undefined}},
+ {1966, {wxTreebook, new_0, 0}},
+ {1967, {wxTreebook, new_3, 3}},
+ {1968, {wxTreebook, addPage, 3}},
+ {1969, {wxTreebook, advanceSelection, 1}},
+ {1970, {wxTreebook, assignImageList, 1}},
+ {1971, {wxTreebook, create, 3}},
+ {1972, {wxTreebook, deleteAllPages, 0}},
+ {1973, {wxTreebook, deletePage, 1}},
+ {1974, {wxTreebook, removePage, 1}},
+ {1975, {wxTreebook, getCurrentPage, 0}},
+ {1976, {wxTreebook, getImageList, 0}},
+ {1978, {wxTreebook, getPage, 1}},
+ {1979, {wxTreebook, getPageCount, 0}},
+ {1980, {wxTreebook, getPageImage, 1}},
+ {1981, {wxTreebook, getPageText, 1}},
+ {1982, {wxTreebook, getSelection, 0}},
+ {1983, {wxTreebook, expandNode, 2}},
+ {1984, {wxTreebook, isNodeExpanded, 1}},
+ {1986, {wxTreebook, hitTest, 2}},
+ {1987, {wxTreebook, insertPage, 4}},
+ {1988, {wxTreebook, insertSubPage, 4}},
+ {1989, {wxTreebook, setImageList, 1}},
+ {1990, {wxTreebook, setPageSize, 1}},
+ {1991, {wxTreebook, setPageImage, 2}},
+ {1992, {wxTreebook, setPageText, 2}},
+ {1993, {wxTreebook, setSelection, 1}},
+ {1994, {wxTreebook, changeSelection, 1}},
+ {1995, {wxTreebook, 'Destroy', undefined}},
+ {1998, {wxTreeCtrl, new_2, 2}},
+ {1999, {wxTreeCtrl, new_0, 0}},
+ {2001, {wxTreeCtrl, destruct, 0}},
+ {2002, {wxTreeCtrl, addRoot, 2}},
+ {2003, {wxTreeCtrl, appendItem, 3}},
+ {2004, {wxTreeCtrl, assignImageList, 1}},
+ {2005, {wxTreeCtrl, assignStateImageList, 1}},
+ {2006, {wxTreeCtrl, collapse, 1}},
+ {2007, {wxTreeCtrl, collapseAndReset, 1}},
+ {2008, {wxTreeCtrl, create, 2}},
+ {2009, {wxTreeCtrl, delete, 1}},
+ {2010, {wxTreeCtrl, deleteAllItems, 0}},
+ {2011, {wxTreeCtrl, deleteChildren, 1}},
+ {2012, {wxTreeCtrl, ensureVisible, 1}},
+ {2013, {wxTreeCtrl, expand, 1}},
+ {2014, {wxTreeCtrl, getBoundingRect, 3}},
+ {2016, {wxTreeCtrl, getChildrenCount, 2}},
+ {2017, {wxTreeCtrl, getCount, 0}},
+ {2018, {wxTreeCtrl, getEditControl, 0}},
+ {2019, {wxTreeCtrl, getFirstChild, 2}},
+ {2020, {wxTreeCtrl, getNextChild, 2}},
+ {2021, {wxTreeCtrl, getFirstVisibleItem, 0}},
+ {2022, {wxTreeCtrl, getImageList, 0}},
+ {2023, {wxTreeCtrl, getIndent, 0}},
+ {2024, {wxTreeCtrl, getItemBackgroundColour, 1}},
+ {2025, {wxTreeCtrl, getItemData, 1}},
+ {2026, {wxTreeCtrl, getItemFont, 1}},
+ {2027, {wxTreeCtrl, getItemImage_1, 1}},
+ {2028, {wxTreeCtrl, getItemImage_2, 2}},
+ {2029, {wxTreeCtrl, getItemText, 1}},
+ {2030, {wxTreeCtrl, getItemTextColour, 1}},
+ {2031, {wxTreeCtrl, getLastChild, 1}},
+ {2032, {wxTreeCtrl, getNextSibling, 1}},
+ {2033, {wxTreeCtrl, getNextVisible, 1}},
+ {2034, {wxTreeCtrl, getItemParent, 1}},
+ {2035, {wxTreeCtrl, getPrevSibling, 1}},
+ {2036, {wxTreeCtrl, getPrevVisible, 1}},
+ {2037, {wxTreeCtrl, getRootItem, 0}},
+ {2038, {wxTreeCtrl, getSelection, 0}},
+ {2039, {wxTreeCtrl, getSelections, 1}},
+ {2040, {wxTreeCtrl, getStateImageList, 0}},
+ {2041, {wxTreeCtrl, hitTest, 1}},
+ {2043, {wxTreeCtrl, insertItem, 4}},
+ {2044, {wxTreeCtrl, isBold, 1}},
+ {2045, {wxTreeCtrl, isExpanded, 1}},
+ {2046, {wxTreeCtrl, isSelected, 1}},
+ {2047, {wxTreeCtrl, isVisible, 1}},
+ {2048, {wxTreeCtrl, itemHasChildren, 1}},
+ {2049, {wxTreeCtrl, prependItem, 3}},
+ {2050, {wxTreeCtrl, scrollTo, 1}},
+ {2051, {wxTreeCtrl, selectItem_1, 1}},
+ {2052, {wxTreeCtrl, selectItem_2, 2}},
+ {2053, {wxTreeCtrl, setIndent, 1}},
+ {2054, {wxTreeCtrl, setImageList, 1}},
+ {2055, {wxTreeCtrl, setItemBackgroundColour, 2}},
+ {2056, {wxTreeCtrl, setItemBold, 2}},
+ {2057, {wxTreeCtrl, setItemData, 2}},
+ {2058, {wxTreeCtrl, setItemDropHighlight, 2}},
+ {2059, {wxTreeCtrl, setItemFont, 2}},
+ {2060, {wxTreeCtrl, setItemHasChildren, 2}},
+ {2061, {wxTreeCtrl, setItemImage_2, 2}},
+ {2062, {wxTreeCtrl, setItemImage_3, 3}},
+ {2063, {wxTreeCtrl, setItemText, 2}},
+ {2064, {wxTreeCtrl, setItemTextColour, 2}},
+ {2065, {wxTreeCtrl, setStateImageList, 1}},
+ {2066, {wxTreeCtrl, setWindowStyle, 1}},
+ {2067, {wxTreeCtrl, sortChildren, 1}},
+ {2068, {wxTreeCtrl, toggle, 1}},
+ {2069, {wxTreeCtrl, toggleItemSelection, 1}},
+ {2070, {wxTreeCtrl, unselect, 0}},
+ {2071, {wxTreeCtrl, unselectAll, 0}},
+ {2072, {wxTreeCtrl, unselectItem, 1}},
+ {2073, {wxScrollBar, new_0, 0}},
+ {2074, {wxScrollBar, new_3, 3}},
+ {2075, {wxScrollBar, destruct, 0}},
+ {2076, {wxScrollBar, create, 3}},
+ {2077, {wxScrollBar, getRange, 0}},
+ {2078, {wxScrollBar, getPageSize, 0}},
+ {2079, {wxScrollBar, getThumbPosition, 0}},
+ {2080, {wxScrollBar, getThumbSize, 0}},
+ {2081, {wxScrollBar, setThumbPosition, 1}},
+ {2082, {wxScrollBar, setScrollbar, 5}},
+ {2084, {wxSpinButton, new_2, 2}},
+ {2085, {wxSpinButton, new_0, 0}},
+ {2086, {wxSpinButton, create, 2}},
+ {2087, {wxSpinButton, getMax, 0}},
+ {2088, {wxSpinButton, getMin, 0}},
+ {2089, {wxSpinButton, getValue, 0}},
+ {2090, {wxSpinButton, setRange, 2}},
+ {2091, {wxSpinButton, setValue, 1}},
+ {2092, {wxSpinButton, 'Destroy', undefined}},
+ {2093, {wxSpinCtrl, new_0, 0}},
+ {2094, {wxSpinCtrl, new_2, 2}},
+ {2096, {wxSpinCtrl, create, 2}},
+ {2099, {wxSpinCtrl, setValue_1_1, 1}},
+ {2100, {wxSpinCtrl, setValue_1_0, 1}},
+ {2102, {wxSpinCtrl, getValue, 0}},
+ {2104, {wxSpinCtrl, setRange, 2}},
+ {2105, {wxSpinCtrl, setSelection, 2}},
+ {2107, {wxSpinCtrl, getMin, 0}},
+ {2109, {wxSpinCtrl, getMax, 0}},
+ {2110, {wxSpinCtrl, 'Destroy', undefined}},
+ {2111, {wxStaticText, new_0, 0}},
+ {2112, {wxStaticText, new_4, 4}},
+ {2113, {wxStaticText, create, 4}},
+ {2114, {wxStaticText, getLabel, 0}},
+ {2115, {wxStaticText, setLabel, 1}},
+ {2116, {wxStaticText, wrap, 1}},
+ {2117, {wxStaticText, 'Destroy', undefined}},
+ {2118, {wxStaticBitmap, new_0, 0}},
+ {2119, {wxStaticBitmap, new_4, 4}},
+ {2120, {wxStaticBitmap, create, 4}},
+ {2121, {wxStaticBitmap, getBitmap, 0}},
+ {2122, {wxStaticBitmap, setBitmap, 1}},
+ {2123, {wxStaticBitmap, 'Destroy', undefined}},
+ {2124, {wxRadioBox, new, 7}},
+ {2126, {wxRadioBox, destruct, 0}},
+ {2127, {wxRadioBox, create, 7}},
+ {2128, {wxRadioBox, enable_2, 2}},
+ {2129, {wxRadioBox, enable_1, 1}},
+ {2130, {wxRadioBox, getSelection, 0}},
+ {2131, {wxRadioBox, getString, 1}},
+ {2132, {wxRadioBox, setSelection, 1}},
+ {2133, {wxRadioBox, show_2, 2}},
+ {2134, {wxRadioBox, show_1, 1}},
+ {2135, {wxRadioBox, getColumnCount, 0}},
+ {2136, {wxRadioBox, getItemHelpText, 1}},
+ {2137, {wxRadioBox, getItemToolTip, 1}},
+ {2139, {wxRadioBox, getItemFromPoint, 1}},
+ {2140, {wxRadioBox, getRowCount, 0}},
+ {2141, {wxRadioBox, isItemEnabled, 1}},
+ {2142, {wxRadioBox, isItemShown, 1}},
+ {2143, {wxRadioBox, setItemHelpText, 2}},
+ {2144, {wxRadioBox, setItemToolTip, 2}},
+ {2145, {wxRadioButton, new_0, 0}},
+ {2146, {wxRadioButton, new_4, 4}},
+ {2147, {wxRadioButton, create, 4}},
+ {2148, {wxRadioButton, getValue, 0}},
+ {2149, {wxRadioButton, setValue, 1}},
+ {2150, {wxRadioButton, 'Destroy', undefined}},
+ {2152, {wxSlider, new_6, 6}},
+ {2153, {wxSlider, new_0, 0}},
+ {2154, {wxSlider, create, 6}},
+ {2155, {wxSlider, getLineSize, 0}},
+ {2156, {wxSlider, getMax, 0}},
+ {2157, {wxSlider, getMin, 0}},
+ {2158, {wxSlider, getPageSize, 0}},
+ {2159, {wxSlider, getThumbLength, 0}},
+ {2160, {wxSlider, getValue, 0}},
+ {2161, {wxSlider, setLineSize, 1}},
+ {2162, {wxSlider, setPageSize, 1}},
+ {2163, {wxSlider, setRange, 2}},
+ {2164, {wxSlider, setThumbLength, 1}},
+ {2165, {wxSlider, setValue, 1}},
+ {2166, {wxSlider, 'Destroy', undefined}},
+ {2168, {wxDialog, new_4, 4}},
+ {2169, {wxDialog, new_0, 0}},
+ {2171, {wxDialog, destruct, 0}},
+ {2172, {wxDialog, create, 4}},
+ {2173, {wxDialog, createButtonSizer, 1}},
+ {2174, {wxDialog, createStdDialogButtonSizer, 1}},
+ {2175, {wxDialog, endModal, 1}},
+ {2176, {wxDialog, getAffirmativeId, 0}},
+ {2177, {wxDialog, getReturnCode, 0}},
+ {2178, {wxDialog, isModal, 0}},
+ {2179, {wxDialog, setAffirmativeId, 1}},
+ {2180, {wxDialog, setReturnCode, 1}},
+ {2181, {wxDialog, show, 1}},
+ {2182, {wxDialog, showModal, 0}},
+ {2183, {wxColourDialog, new_0, 0}},
+ {2184, {wxColourDialog, new_2, 2}},
+ {2185, {wxColourDialog, destruct, 0}},
+ {2186, {wxColourDialog, create, 2}},
+ {2187, {wxColourDialog, getColourData, 0}},
+ {2188, {wxColourData, new_0, 0}},
+ {2189, {wxColourData, new_1, 1}},
+ {2190, {wxColourData, destruct, 0}},
+ {2191, {wxColourData, getChooseFull, 0}},
+ {2192, {wxColourData, getColour, 0}},
+ {2194, {wxColourData, getCustomColour, 1}},
+ {2195, {wxColourData, setChooseFull, 1}},
+ {2196, {wxColourData, setColour, 1}},
+ {2197, {wxColourData, setCustomColour, 2}},
+ {2198, {wxPalette, new_0, 0}},
+ {2199, {wxPalette, new_4, 4}},
+ {2201, {wxPalette, destruct, 0}},
+ {2202, {wxPalette, create, 4}},
+ {2203, {wxPalette, getColoursCount, 0}},
+ {2204, {wxPalette, getPixel, 3}},
+ {2205, {wxPalette, getRGB, 4}},
+ {2206, {wxPalette, isOk, 0}},
+ {2210, {wxDirDialog, new, 2}},
+ {2211, {wxDirDialog, destruct, 0}},
+ {2212, {wxDirDialog, getPath, 0}},
+ {2213, {wxDirDialog, getMessage, 0}},
+ {2214, {wxDirDialog, setMessage, 1}},
+ {2215, {wxDirDialog, setPath, 1}},
+ {2219, {wxFileDialog, new, 2}},
+ {2220, {wxFileDialog, destruct, 0}},
+ {2221, {wxFileDialog, getDirectory, 0}},
+ {2222, {wxFileDialog, getFilename, 0}},
+ {2223, {wxFileDialog, getFilenames, 1}},
+ {2224, {wxFileDialog, getFilterIndex, 0}},
+ {2225, {wxFileDialog, getMessage, 0}},
+ {2226, {wxFileDialog, getPath, 0}},
+ {2227, {wxFileDialog, getPaths, 1}},
+ {2228, {wxFileDialog, getWildcard, 0}},
+ {2229, {wxFileDialog, setDirectory, 1}},
+ {2230, {wxFileDialog, setFilename, 1}},
+ {2231, {wxFileDialog, setFilterIndex, 1}},
+ {2232, {wxFileDialog, setMessage, 1}},
+ {2233, {wxFileDialog, setPath, 1}},
+ {2234, {wxFileDialog, setWildcard, 1}},
+ {2235, {wxPickerBase, setInternalMargin, 1}},
+ {2236, {wxPickerBase, getInternalMargin, 0}},
+ {2237, {wxPickerBase, setTextCtrlProportion, 1}},
+ {2238, {wxPickerBase, setPickerCtrlProportion, 1}},
+ {2239, {wxPickerBase, getTextCtrlProportion, 0}},
+ {2240, {wxPickerBase, getPickerCtrlProportion, 0}},
+ {2241, {wxPickerBase, hasTextCtrl, 0}},
+ {2242, {wxPickerBase, getTextCtrl, 0}},
+ {2243, {wxPickerBase, isTextCtrlGrowable, 0}},
+ {2244, {wxPickerBase, setPickerCtrlGrowable, 1}},
+ {2245, {wxPickerBase, setTextCtrlGrowable, 1}},
+ {2246, {wxPickerBase, isPickerCtrlGrowable, 0}},
+ {2247, {wxFilePickerCtrl, new_0, 0}},
+ {2248, {wxFilePickerCtrl, new_3, 3}},
+ {2249, {wxFilePickerCtrl, create, 3}},
+ {2250, {wxFilePickerCtrl, getPath, 0}},
+ {2251, {wxFilePickerCtrl, setPath, 1}},
+ {2252, {wxFilePickerCtrl, 'Destroy', undefined}},
+ {2253, {wxDirPickerCtrl, new_0, 0}},
+ {2254, {wxDirPickerCtrl, new_3, 3}},
+ {2255, {wxDirPickerCtrl, create, 3}},
+ {2256, {wxDirPickerCtrl, getPath, 0}},
+ {2257, {wxDirPickerCtrl, setPath, 1}},
+ {2258, {wxDirPickerCtrl, 'Destroy', undefined}},
+ {2259, {wxColourPickerCtrl, new_0, 0}},
+ {2260, {wxColourPickerCtrl, new_3, 3}},
+ {2261, {wxColourPickerCtrl, create, 3}},
+ {2262, {wxColourPickerCtrl, getColour, 0}},
+ {2263, {wxColourPickerCtrl, setColour_1_1, 1}},
+ {2264, {wxColourPickerCtrl, setColour_1_0, 1}},
+ {2265, {wxColourPickerCtrl, 'Destroy', undefined}},
+ {2266, {wxDatePickerCtrl, new_0, 0}},
+ {2267, {wxDatePickerCtrl, new_3, 3}},
+ {2268, {wxDatePickerCtrl, getRange, 2}},
+ {2269, {wxDatePickerCtrl, getValue, 0}},
+ {2270, {wxDatePickerCtrl, setRange, 2}},
+ {2271, {wxDatePickerCtrl, setValue, 1}},
+ {2272, {wxDatePickerCtrl, 'Destroy', undefined}},
+ {2273, {wxFontPickerCtrl, new_0, 0}},
+ {2274, {wxFontPickerCtrl, new_3, 3}},
+ {2275, {wxFontPickerCtrl, create, 3}},
+ {2276, {wxFontPickerCtrl, getSelectedFont, 0}},
+ {2277, {wxFontPickerCtrl, setSelectedFont, 1}},
+ {2278, {wxFontPickerCtrl, getMaxPointSize, 0}},
+ {2279, {wxFontPickerCtrl, setMaxPointSize, 1}},
+ {2280, {wxFontPickerCtrl, 'Destroy', undefined}},
+ {2283, {wxFindReplaceDialog, new_0, 0}},
+ {2284, {wxFindReplaceDialog, new_4, 4}},
+ {2285, {wxFindReplaceDialog, destruct, 0}},
+ {2286, {wxFindReplaceDialog, create, 4}},
+ {2287, {wxFindReplaceDialog, getData, 0}},
+ {2288, {wxFindReplaceData, new_0, 0}},
+ {2289, {wxFindReplaceData, new_1, 1}},
+ {2290, {wxFindReplaceData, getFindString, 0}},
+ {2291, {wxFindReplaceData, getReplaceString, 0}},
+ {2292, {wxFindReplaceData, getFlags, 0}},
+ {2293, {wxFindReplaceData, setFlags, 1}},
+ {2294, {wxFindReplaceData, setFindString, 1}},
+ {2295, {wxFindReplaceData, setReplaceString, 1}},
+ {2296, {wxFindReplaceData, 'Destroy', undefined}},
+ {2297, {wxMultiChoiceDialog, new_0, 0}},
+ {2299, {wxMultiChoiceDialog, new_5, 5}},
+ {2300, {wxMultiChoiceDialog, getSelections, 0}},
+ {2301, {wxMultiChoiceDialog, setSelections, 1}},
+ {2302, {wxMultiChoiceDialog, 'Destroy', undefined}},
+ {2303, {wxSingleChoiceDialog, new_0, 0}},
+ {2305, {wxSingleChoiceDialog, new_5, 5}},
+ {2306, {wxSingleChoiceDialog, getSelection, 0}},
+ {2307, {wxSingleChoiceDialog, getStringSelection, 0}},
+ {2308, {wxSingleChoiceDialog, setSelection, 1}},
+ {2309, {wxSingleChoiceDialog, 'Destroy', undefined}},
+ {2310, {wxTextEntryDialog, new, 3}},
+ {2311, {wxTextEntryDialog, getValue, 0}},
+ {2312, {wxTextEntryDialog, setValue, 1}},
+ {2313, {wxTextEntryDialog, 'Destroy', undefined}},
+ {2314, {wxPasswordEntryDialog, new, 3}},
+ {2315, {wxPasswordEntryDialog, 'Destroy', undefined}},
+ {2316, {wxFontData, new_0, 0}},
+ {2317, {wxFontData, new_1, 1}},
+ {2318, {wxFontData, destruct, 0}},
+ {2319, {wxFontData, enableEffects, 1}},
+ {2320, {wxFontData, getAllowSymbols, 0}},
+ {2321, {wxFontData, getColour, 0}},
+ {2322, {wxFontData, getChosenFont, 0}},
+ {2323, {wxFontData, getEnableEffects, 0}},
+ {2324, {wxFontData, getInitialFont, 0}},
+ {2325, {wxFontData, getShowHelp, 0}},
+ {2326, {wxFontData, setAllowSymbols, 1}},
+ {2327, {wxFontData, setChosenFont, 1}},
+ {2328, {wxFontData, setColour, 1}},
+ {2329, {wxFontData, setInitialFont, 1}},
+ {2330, {wxFontData, setRange, 2}},
+ {2331, {wxFontData, setShowHelp, 1}},
+ {2335, {wxFontDialog, new_0, 0}},
+ {2337, {wxFontDialog, new_2, 2}},
+ {2339, {wxFontDialog, create, 2}},
+ {2340, {wxFontDialog, getFontData, 0}},
+ {2342, {wxFontDialog, 'Destroy', undefined}},
+ {2343, {wxProgressDialog, new, 3}},
+ {2344, {wxProgressDialog, destruct, 0}},
+ {2345, {wxProgressDialog, resume, 0}},
+ {2346, {wxProgressDialog, update_2, 2}},
+ {2347, {wxProgressDialog, update_0, 0}},
+ {2348, {wxMessageDialog, new, 3}},
+ {2349, {wxMessageDialog, destruct, 0}},
+ {2350, {wxPageSetupDialog, new, 2}},
+ {2351, {wxPageSetupDialog, destruct, 0}},
+ {2352, {wxPageSetupDialog, getPageSetupData, 0}},
+ {2353, {wxPageSetupDialog, showModal, 0}},
+ {2354, {wxPageSetupDialogData, new_0, 0}},
+ {2355, {wxPageSetupDialogData, new_1_0, 1}},
+ {2356, {wxPageSetupDialogData, new_1_1, 1}},
+ {2357, {wxPageSetupDialogData, destruct, 0}},
+ {2358, {wxPageSetupDialogData, enableHelp, 1}},
+ {2359, {wxPageSetupDialogData, enableMargins, 1}},
+ {2360, {wxPageSetupDialogData, enableOrientation, 1}},
+ {2361, {wxPageSetupDialogData, enablePaper, 1}},
+ {2362, {wxPageSetupDialogData, enablePrinter, 1}},
+ {2363, {wxPageSetupDialogData, getDefaultMinMargins, 0}},
+ {2364, {wxPageSetupDialogData, getEnableMargins, 0}},
+ {2365, {wxPageSetupDialogData, getEnableOrientation, 0}},
+ {2366, {wxPageSetupDialogData, getEnablePaper, 0}},
+ {2367, {wxPageSetupDialogData, getEnablePrinter, 0}},
+ {2368, {wxPageSetupDialogData, getEnableHelp, 0}},
+ {2369, {wxPageSetupDialogData, getDefaultInfo, 0}},
+ {2370, {wxPageSetupDialogData, getMarginTopLeft, 0}},
+ {2371, {wxPageSetupDialogData, getMarginBottomRight, 0}},
+ {2372, {wxPageSetupDialogData, getMinMarginTopLeft, 0}},
+ {2373, {wxPageSetupDialogData, getMinMarginBottomRight, 0}},
+ {2374, {wxPageSetupDialogData, getPaperId, 0}},
+ {2375, {wxPageSetupDialogData, getPaperSize, 0}},
+ {2377, {wxPageSetupDialogData, getPrintData, 0}},
+ {2378, {wxPageSetupDialogData, isOk, 0}},
+ {2379, {wxPageSetupDialogData, setDefaultInfo, 1}},
+ {2380, {wxPageSetupDialogData, setDefaultMinMargins, 1}},
+ {2381, {wxPageSetupDialogData, setMarginTopLeft, 1}},
+ {2382, {wxPageSetupDialogData, setMarginBottomRight, 1}},
+ {2383, {wxPageSetupDialogData, setMinMarginTopLeft, 1}},
+ {2384, {wxPageSetupDialogData, setMinMarginBottomRight, 1}},
+ {2385, {wxPageSetupDialogData, setPaperId, 1}},
+ {2386, {wxPageSetupDialogData, setPaperSize_1_1, 1}},
+ {2387, {wxPageSetupDialogData, setPaperSize_1_0, 1}},
+ {2388, {wxPageSetupDialogData, setPrintData, 1}},
+ {2389, {wxPrintDialog, new_2_0, 2}},
+ {2390, {wxPrintDialog, new_2_1, 2}},
+ {2391, {wxPrintDialog, destruct, 0}},
+ {2392, {wxPrintDialog, getPrintDialogData, 0}},
+ {2393, {wxPrintDialog, getPrintDC, 0}},
+ {2394, {wxPrintDialogData, new_0, 0}},
+ {2395, {wxPrintDialogData, new_1_1, 1}},
+ {2396, {wxPrintDialogData, new_1_0, 1}},
+ {2397, {wxPrintDialogData, destruct, 0}},
+ {2398, {wxPrintDialogData, enableHelp, 1}},
+ {2399, {wxPrintDialogData, enablePageNumbers, 1}},
+ {2400, {wxPrintDialogData, enablePrintToFile, 1}},
+ {2401, {wxPrintDialogData, enableSelection, 1}},
+ {2402, {wxPrintDialogData, getAllPages, 0}},
+ {2403, {wxPrintDialogData, getCollate, 0}},
+ {2404, {wxPrintDialogData, getFromPage, 0}},
+ {2405, {wxPrintDialogData, getMaxPage, 0}},
+ {2406, {wxPrintDialogData, getMinPage, 0}},
+ {2407, {wxPrintDialogData, getNoCopies, 0}},
+ {2408, {wxPrintDialogData, getPrintData, 0}},
+ {2409, {wxPrintDialogData, getPrintToFile, 0}},
+ {2410, {wxPrintDialogData, getSelection, 0}},
+ {2411, {wxPrintDialogData, getToPage, 0}},
+ {2412, {wxPrintDialogData, isOk, 0}},
+ {2413, {wxPrintDialogData, setCollate, 1}},
+ {2414, {wxPrintDialogData, setFromPage, 1}},
+ {2415, {wxPrintDialogData, setMaxPage, 1}},
+ {2416, {wxPrintDialogData, setMinPage, 1}},
+ {2417, {wxPrintDialogData, setNoCopies, 1}},
+ {2418, {wxPrintDialogData, setPrintData, 1}},
+ {2419, {wxPrintDialogData, setPrintToFile, 1}},
+ {2420, {wxPrintDialogData, setSelection, 1}},
+ {2421, {wxPrintDialogData, setToPage, 1}},
+ {2422, {wxPrintData, new_0, 0}},
+ {2423, {wxPrintData, new_1, 1}},
+ {2424, {wxPrintData, destruct, 0}},
+ {2425, {wxPrintData, getCollate, 0}},
+ {2426, {wxPrintData, getBin, 0}},
+ {2427, {wxPrintData, getColour, 0}},
+ {2428, {wxPrintData, getDuplex, 0}},
+ {2429, {wxPrintData, getNoCopies, 0}},
+ {2430, {wxPrintData, getOrientation, 0}},
+ {2431, {wxPrintData, getPaperId, 0}},
+ {2432, {wxPrintData, getPrinterName, 0}},
+ {2433, {wxPrintData, getQuality, 0}},
+ {2434, {wxPrintData, isOk, 0}},
+ {2435, {wxPrintData, setBin, 1}},
+ {2436, {wxPrintData, setCollate, 1}},
+ {2437, {wxPrintData, setColour, 1}},
+ {2438, {wxPrintData, setDuplex, 1}},
+ {2439, {wxPrintData, setNoCopies, 1}},
+ {2440, {wxPrintData, setOrientation, 1}},
+ {2441, {wxPrintData, setPaperId, 1}},
+ {2442, {wxPrintData, setPrinterName, 1}},
+ {2443, {wxPrintData, setQuality, 1}},
+ {2446, {wxPrintPreview, new_2, 2}},
+ {2447, {wxPrintPreview, new_3, 3}},
+ {2449, {wxPrintPreview, destruct, 0}},
+ {2450, {wxPrintPreview, getCanvas, 0}},
+ {2451, {wxPrintPreview, getCurrentPage, 0}},
+ {2452, {wxPrintPreview, getFrame, 0}},
+ {2453, {wxPrintPreview, getMaxPage, 0}},
+ {2454, {wxPrintPreview, getMinPage, 0}},
+ {2455, {wxPrintPreview, getPrintout, 0}},
+ {2456, {wxPrintPreview, getPrintoutForPrinting, 0}},
+ {2457, {wxPrintPreview, isOk, 0}},
+ {2458, {wxPrintPreview, paintPage, 2}},
+ {2459, {wxPrintPreview, print, 1}},
+ {2460, {wxPrintPreview, renderPage, 1}},
+ {2461, {wxPrintPreview, setCanvas, 1}},
+ {2462, {wxPrintPreview, setCurrentPage, 1}},
+ {2463, {wxPrintPreview, setFrame, 1}},
+ {2464, {wxPrintPreview, setPrintout, 1}},
+ {2465, {wxPrintPreview, setZoom, 1}},
+ {2466, {wxPreviewFrame, new, 3}},
+ {2467, {wxPreviewFrame, destruct, 0}},
+ {2468, {wxPreviewFrame, createControlBar, 0}},
+ {2469, {wxPreviewFrame, createCanvas, 0}},
+ {2470, {wxPreviewFrame, initialize, 0}},
+ {2471, {wxPreviewFrame, onCloseWindow, 1}},
+ {2472, {wxPreviewControlBar, new, 4}},
+ {2473, {wxPreviewControlBar, destruct, 0}},
+ {2474, {wxPreviewControlBar, createButtons, 0}},
+ {2475, {wxPreviewControlBar, getPrintPreview, 0}},
+ {2476, {wxPreviewControlBar, getZoomControl, 0}},
+ {2477, {wxPreviewControlBar, setZoomControl, 1}},
+ {2479, {wxPrinter, new, 1}},
+ {2480, {wxPrinter, createAbortWindow, 2}},
+ {2481, {wxPrinter, getAbort, 0}},
+ {2482, {wxPrinter, getLastError, 0}},
+ {2483, {wxPrinter, getPrintDialogData, 0}},
+ {2484, {wxPrinter, print, 3}},
+ {2485, {wxPrinter, printDialog, 1}},
+ {2486, {wxPrinter, reportError, 3}},
+ {2487, {wxPrinter, setup, 1}},
+ {2488, {wxPrinter, 'Destroy', undefined}},
+ {2489, {wxXmlResource, new_1, 1}},
+ {2490, {wxXmlResource, new_2, 2}},
+ {2491, {wxXmlResource, destruct, 0}},
+ {2492, {wxXmlResource, attachUnknownControl, 3}},
+ {2493, {wxXmlResource, clearHandlers, 0}},
+ {2494, {wxXmlResource, compareVersion, 4}},
+ {2495, {wxXmlResource, get, 0}},
+ {2496, {wxXmlResource, getFlags, 0}},
+ {2497, {wxXmlResource, getVersion, 0}},
+ {2498, {wxXmlResource, getXRCID, 2}},
+ {2499, {wxXmlResource, initAllHandlers, 0}},
+ {2500, {wxXmlResource, load, 1}},
+ {2501, {wxXmlResource, loadBitmap, 1}},
+ {2502, {wxXmlResource, loadDialog_2, 2}},
+ {2503, {wxXmlResource, loadDialog_3, 3}},
+ {2504, {wxXmlResource, loadFrame_2, 2}},
+ {2505, {wxXmlResource, loadFrame_3, 3}},
+ {2506, {wxXmlResource, loadIcon, 1}},
+ {2507, {wxXmlResource, loadMenu, 1}},
+ {2508, {wxXmlResource, loadMenuBar_2, 2}},
+ {2509, {wxXmlResource, loadMenuBar_1, 1}},
+ {2510, {wxXmlResource, loadPanel_2, 2}},
+ {2511, {wxXmlResource, loadPanel_3, 3}},
+ {2512, {wxXmlResource, loadToolBar, 2}},
+ {2513, {wxXmlResource, set, 1}},
+ {2514, {wxXmlResource, setFlags, 1}},
+ {2515, {wxXmlResource, unload, 1}},
+ {2516, {wxXmlResource, xrcctrl, 3}},
+ {2517, {wxHtmlEasyPrinting, new, 1}},
+ {2518, {wxHtmlEasyPrinting, destruct, 0}},
+ {2519, {wxHtmlEasyPrinting, getPrintData, 0}},
+ {2520, {wxHtmlEasyPrinting, getPageSetupData, 0}},
+ {2521, {wxHtmlEasyPrinting, previewFile, 1}},
+ {2522, {wxHtmlEasyPrinting, previewText, 2}},
+ {2523, {wxHtmlEasyPrinting, printFile, 1}},
+ {2524, {wxHtmlEasyPrinting, printText, 2}},
+ {2525, {wxHtmlEasyPrinting, pageSetup, 0}},
+ {2526, {wxHtmlEasyPrinting, setFonts, 3}},
+ {2527, {wxHtmlEasyPrinting, setHeader, 2}},
+ {2528, {wxHtmlEasyPrinting, setFooter, 2}},
+ {2530, {wxGLCanvas, new_2, 2}},
+ {2531, {wxGLCanvas, new_3_1, 3}},
+ {2532, {wxGLCanvas, new_3_0, 3}},
+ {2533, {wxGLCanvas, getContext, 0}},
+ {2535, {wxGLCanvas, setCurrent, 0}},
+ {2536, {wxGLCanvas, swapBuffers, 0}},
+ {2537, {wxGLCanvas, 'Destroy', undefined}},
+ {2538, {wxAuiManager, new, 1}},
+ {2539, {wxAuiManager, destruct, 0}},
+ {2540, {wxAuiManager, addPane_2_1, 2}},
+ {2541, {wxAuiManager, addPane_3, 3}},
+ {2542, {wxAuiManager, addPane_2_0, 2}},
+ {2543, {wxAuiManager, detachPane, 1}},
+ {2544, {wxAuiManager, getAllPanes, 0}},
+ {2545, {wxAuiManager, getArtProvider, 0}},
+ {2546, {wxAuiManager, getDockSizeConstraint, 2}},
+ {2547, {wxAuiManager, getFlags, 0}},
+ {2548, {wxAuiManager, getManagedWindow, 0}},
+ {2549, {wxAuiManager, getManager, 1}},
+ {2550, {wxAuiManager, getPane_1_1, 1}},
+ {2551, {wxAuiManager, getPane_1_0, 1}},
+ {2552, {wxAuiManager, hideHint, 0}},
+ {2553, {wxAuiManager, insertPane, 3}},
+ {2554, {wxAuiManager, loadPaneInfo, 2}},
+ {2555, {wxAuiManager, loadPerspective, 2}},
+ {2556, {wxAuiManager, savePaneInfo, 1}},
+ {2557, {wxAuiManager, savePerspective, 0}},
+ {2558, {wxAuiManager, setArtProvider, 1}},
+ {2559, {wxAuiManager, setDockSizeConstraint, 2}},
+ {2560, {wxAuiManager, setFlags, 1}},
+ {2561, {wxAuiManager, setManagedWindow, 1}},
+ {2562, {wxAuiManager, showHint, 1}},
+ {2563, {wxAuiManager, unInit, 0}},
+ {2564, {wxAuiManager, update, 0}},
+ {2565, {wxAuiPaneInfo, new_0, 0}},
+ {2566, {wxAuiPaneInfo, new_1, 1}},
+ {2567, {wxAuiPaneInfo, destruct, 0}},
+ {2568, {wxAuiPaneInfo, bestSize_1, 1}},
+ {2569, {wxAuiPaneInfo, bestSize_2, 2}},
+ {2570, {wxAuiPaneInfo, bottom, 0}},
+ {2571, {wxAuiPaneInfo, bottomDockable, 1}},
+ {2572, {wxAuiPaneInfo, caption, 1}},
+ {2573, {wxAuiPaneInfo, captionVisible, 1}},
+ {2574, {wxAuiPaneInfo, centre, 0}},
+ {2575, {wxAuiPaneInfo, centrePane, 0}},
+ {2576, {wxAuiPaneInfo, closeButton, 1}},
+ {2577, {wxAuiPaneInfo, defaultPane, 0}},
+ {2578, {wxAuiPaneInfo, destroyOnClose, 1}},
+ {2579, {wxAuiPaneInfo, direction, 1}},
+ {2580, {wxAuiPaneInfo, dock, 0}},
+ {2581, {wxAuiPaneInfo, dockable, 1}},
+ {2582, {wxAuiPaneInfo, fixed, 0}},
+ {2583, {wxAuiPaneInfo, float, 0}},
+ {2584, {wxAuiPaneInfo, floatable, 1}},
+ {2585, {wxAuiPaneInfo, floatingPosition_1, 1}},
+ {2586, {wxAuiPaneInfo, floatingPosition_2, 2}},
+ {2587, {wxAuiPaneInfo, floatingSize_1, 1}},
+ {2588, {wxAuiPaneInfo, floatingSize_2, 2}},
+ {2589, {wxAuiPaneInfo, gripper, 1}},
+ {2590, {wxAuiPaneInfo, gripperTop, 1}},
+ {2591, {wxAuiPaneInfo, hasBorder, 0}},
+ {2592, {wxAuiPaneInfo, hasCaption, 0}},
+ {2593, {wxAuiPaneInfo, hasCloseButton, 0}},
+ {2594, {wxAuiPaneInfo, hasFlag, 1}},
+ {2595, {wxAuiPaneInfo, hasGripper, 0}},
+ {2596, {wxAuiPaneInfo, hasGripperTop, 0}},
+ {2597, {wxAuiPaneInfo, hasMaximizeButton, 0}},
+ {2598, {wxAuiPaneInfo, hasMinimizeButton, 0}},
+ {2599, {wxAuiPaneInfo, hasPinButton, 0}},
+ {2600, {wxAuiPaneInfo, hide, 0}},
+ {2601, {wxAuiPaneInfo, isBottomDockable, 0}},
+ {2602, {wxAuiPaneInfo, isDocked, 0}},
+ {2603, {wxAuiPaneInfo, isFixed, 0}},
+ {2604, {wxAuiPaneInfo, isFloatable, 0}},
+ {2605, {wxAuiPaneInfo, isFloating, 0}},
+ {2606, {wxAuiPaneInfo, isLeftDockable, 0}},
+ {2607, {wxAuiPaneInfo, isMovable, 0}},
+ {2608, {wxAuiPaneInfo, isOk, 0}},
+ {2609, {wxAuiPaneInfo, isResizable, 0}},
+ {2610, {wxAuiPaneInfo, isRightDockable, 0}},
+ {2611, {wxAuiPaneInfo, isShown, 0}},
+ {2612, {wxAuiPaneInfo, isToolbar, 0}},
+ {2613, {wxAuiPaneInfo, isTopDockable, 0}},
+ {2614, {wxAuiPaneInfo, layer, 1}},
+ {2615, {wxAuiPaneInfo, left, 0}},
+ {2616, {wxAuiPaneInfo, leftDockable, 1}},
+ {2617, {wxAuiPaneInfo, maxSize_1, 1}},
+ {2618, {wxAuiPaneInfo, maxSize_2, 2}},
+ {2619, {wxAuiPaneInfo, maximizeButton, 1}},
+ {2620, {wxAuiPaneInfo, minSize_1, 1}},
+ {2621, {wxAuiPaneInfo, minSize_2, 2}},
+ {2622, {wxAuiPaneInfo, minimizeButton, 1}},
+ {2623, {wxAuiPaneInfo, movable, 1}},
+ {2624, {wxAuiPaneInfo, name, 1}},
+ {2625, {wxAuiPaneInfo, paneBorder, 1}},
+ {2626, {wxAuiPaneInfo, pinButton, 1}},
+ {2627, {wxAuiPaneInfo, position, 1}},
+ {2628, {wxAuiPaneInfo, resizable, 1}},
+ {2629, {wxAuiPaneInfo, right, 0}},
+ {2630, {wxAuiPaneInfo, rightDockable, 1}},
+ {2631, {wxAuiPaneInfo, row, 1}},
+ {2632, {wxAuiPaneInfo, safeSet, 1}},
+ {2633, {wxAuiPaneInfo, setFlag, 2}},
+ {2634, {wxAuiPaneInfo, show, 1}},
+ {2635, {wxAuiPaneInfo, toolbarPane, 0}},
+ {2636, {wxAuiPaneInfo, top, 0}},
+ {2637, {wxAuiPaneInfo, topDockable, 1}},
+ {2638, {wxAuiPaneInfo, window, 1}},
+ {2639, {wxAuiNotebook, new_0, 0}},
+ {2640, {wxAuiNotebook, new_2, 2}},
+ {2641, {wxAuiNotebook, addPage, 3}},
+ {2642, {wxAuiNotebook, create, 2}},
+ {2643, {wxAuiNotebook, deletePage, 1}},
+ {2644, {wxAuiNotebook, getArtProvider, 0}},
+ {2645, {wxAuiNotebook, getPage, 1}},
+ {2646, {wxAuiNotebook, getPageBitmap, 1}},
+ {2647, {wxAuiNotebook, getPageCount, 0}},
+ {2648, {wxAuiNotebook, getPageIndex, 1}},
+ {2649, {wxAuiNotebook, getPageText, 1}},
+ {2650, {wxAuiNotebook, getSelection, 0}},
+ {2651, {wxAuiNotebook, insertPage, 4}},
+ {2652, {wxAuiNotebook, removePage, 1}},
+ {2653, {wxAuiNotebook, setArtProvider, 1}},
+ {2654, {wxAuiNotebook, setFont, 1}},
+ {2655, {wxAuiNotebook, setPageBitmap, 2}},
+ {2656, {wxAuiNotebook, setPageText, 2}},
+ {2657, {wxAuiNotebook, setSelection, 1}},
+ {2658, {wxAuiNotebook, setTabCtrlHeight, 1}},
+ {2659, {wxAuiNotebook, setUniformBitmapSize, 1}},
+ {2660, {wxAuiNotebook, 'Destroy', undefined}},
+ {2661, {wxMDIParentFrame, new_0, 0}},
+ {2662, {wxMDIParentFrame, new_4, 4}},
+ {2663, {wxMDIParentFrame, destruct, 0}},
+ {2664, {wxMDIParentFrame, activateNext, 0}},
+ {2665, {wxMDIParentFrame, activatePrevious, 0}},
+ {2666, {wxMDIParentFrame, arrangeIcons, 0}},
+ {2667, {wxMDIParentFrame, cascade, 0}},
+ {2668, {wxMDIParentFrame, create, 4}},
+ {2669, {wxMDIParentFrame, getActiveChild, 0}},
+ {2670, {wxMDIParentFrame, getClientWindow, 0}},
+ {2671, {wxMDIParentFrame, tile, 1}},
+ {2672, {wxMDIChildFrame, new_0, 0}},
+ {2673, {wxMDIChildFrame, new_4, 4}},
+ {2674, {wxMDIChildFrame, destruct, 0}},
+ {2675, {wxMDIChildFrame, activate, 0}},
+ {2676, {wxMDIChildFrame, create, 4}},
+ {2677, {wxMDIChildFrame, maximize, 1}},
+ {2678, {wxMDIChildFrame, restore, 0}},
+ {2679, {wxMDIClientWindow, new_0, 0}},
+ {2680, {wxMDIClientWindow, new_2, 2}},
+ {2681, {wxMDIClientWindow, destruct, 0}},
+ {2682, {wxMDIClientWindow, createClient, 2}},
+ {2683, {wxLayoutAlgorithm, new, 0}},
+ {2684, {wxLayoutAlgorithm, layoutFrame, 2}},
+ {2685, {wxLayoutAlgorithm, layoutMDIFrame, 2}},
+ {2686, {wxLayoutAlgorithm, layoutWindow, 2}},
+ {2687, {wxLayoutAlgorithm, 'Destroy', undefined}},
+ {2688, {wxEvent, getId, 0}},
+ {2689, {wxEvent, getSkipped, 0}},
+ {2690, {wxEvent, getTimestamp, 0}},
+ {2691, {wxEvent, isCommandEvent, 0}},
+ {2692, {wxEvent, resumePropagation, 1}},
+ {2693, {wxEvent, shouldPropagate, 0}},
+ {2694, {wxEvent, skip, 1}},
+ {2695, {wxEvent, stopPropagation, 0}},
+ {2696, {wxCommandEvent, getClientData, 0}},
+ {2697, {wxCommandEvent, getExtraLong, 0}},
+ {2698, {wxCommandEvent, getInt, 0}},
+ {2699, {wxCommandEvent, getSelection, 0}},
+ {2700, {wxCommandEvent, getString, 0}},
+ {2701, {wxCommandEvent, isChecked, 0}},
+ {2702, {wxCommandEvent, isSelection, 0}},
+ {2703, {wxCommandEvent, setInt, 1}},
+ {2704, {wxCommandEvent, setString, 1}},
+ {2705, {wxScrollEvent, getOrientation, 0}},
+ {2706, {wxScrollEvent, getPosition, 0}},
+ {2707, {wxScrollWinEvent, getOrientation, 0}},
+ {2708, {wxScrollWinEvent, getPosition, 0}},
+ {2709, {wxMouseEvent, altDown, 0}},
+ {2710, {wxMouseEvent, button, 1}},
+ {2711, {wxMouseEvent, buttonDClick, 1}},
+ {2712, {wxMouseEvent, buttonDown, 1}},
+ {2713, {wxMouseEvent, buttonUp, 1}},
+ {2714, {wxMouseEvent, cmdDown, 0}},
+ {2715, {wxMouseEvent, controlDown, 0}},
+ {2716, {wxMouseEvent, dragging, 0}},
+ {2717, {wxMouseEvent, entering, 0}},
+ {2718, {wxMouseEvent, getButton, 0}},
+ {2721, {wxMouseEvent, getPosition, 0}},
+ {2722, {wxMouseEvent, getLogicalPosition, 1}},
+ {2723, {wxMouseEvent, getLinesPerAction, 0}},
+ {2724, {wxMouseEvent, getWheelRotation, 0}},
+ {2725, {wxMouseEvent, getWheelDelta, 0}},
+ {2726, {wxMouseEvent, getX, 0}},
+ {2727, {wxMouseEvent, getY, 0}},
+ {2728, {wxMouseEvent, isButton, 0}},
+ {2729, {wxMouseEvent, isPageScroll, 0}},
+ {2730, {wxMouseEvent, leaving, 0}},
+ {2731, {wxMouseEvent, leftDClick, 0}},
+ {2732, {wxMouseEvent, leftDown, 0}},
+ {2733, {wxMouseEvent, leftIsDown, 0}},
+ {2734, {wxMouseEvent, leftUp, 0}},
+ {2735, {wxMouseEvent, metaDown, 0}},
+ {2736, {wxMouseEvent, middleDClick, 0}},
+ {2737, {wxMouseEvent, middleDown, 0}},
+ {2738, {wxMouseEvent, middleIsDown, 0}},
+ {2739, {wxMouseEvent, middleUp, 0}},
+ {2740, {wxMouseEvent, moving, 0}},
+ {2741, {wxMouseEvent, rightDClick, 0}},
+ {2742, {wxMouseEvent, rightDown, 0}},
+ {2743, {wxMouseEvent, rightIsDown, 0}},
+ {2744, {wxMouseEvent, rightUp, 0}},
+ {2745, {wxMouseEvent, shiftDown, 0}},
+ {2746, {wxSetCursorEvent, getCursor, 0}},
+ {2747, {wxSetCursorEvent, getX, 0}},
+ {2748, {wxSetCursorEvent, getY, 0}},
+ {2749, {wxSetCursorEvent, hasCursor, 0}},
+ {2750, {wxSetCursorEvent, setCursor, 1}},
+ {2751, {wxKeyEvent, altDown, 0}},
+ {2752, {wxKeyEvent, cmdDown, 0}},
+ {2753, {wxKeyEvent, controlDown, 0}},
+ {2754, {wxKeyEvent, getKeyCode, 0}},
+ {2755, {wxKeyEvent, getModifiers, 0}},
+ {2758, {wxKeyEvent, getPosition, 0}},
+ {2759, {wxKeyEvent, getRawKeyCode, 0}},
+ {2760, {wxKeyEvent, getRawKeyFlags, 0}},
+ {2761, {wxKeyEvent, getUnicodeKey, 0}},
+ {2762, {wxKeyEvent, getX, 0}},
+ {2763, {wxKeyEvent, getY, 0}},
+ {2764, {wxKeyEvent, hasModifiers, 0}},
+ {2765, {wxKeyEvent, metaDown, 0}},
+ {2766, {wxKeyEvent, shiftDown, 0}},
+ {2767, {wxSizeEvent, getSize, 0}},
+ {2768, {wxMoveEvent, getPosition, 0}},
+ {2769, {wxEraseEvent, getDC, 0}},
+ {2770, {wxFocusEvent, getWindow, 0}},
+ {2771, {wxChildFocusEvent, getWindow, 0}},
+ {2772, {wxMenuEvent, getMenu, 0}},
+ {2773, {wxMenuEvent, getMenuId, 0}},
+ {2774, {wxMenuEvent, isPopup, 0}},
+ {2775, {wxCloseEvent, canVeto, 0}},
+ {2776, {wxCloseEvent, getLoggingOff, 0}},
+ {2777, {wxCloseEvent, setCanVeto, 1}},
+ {2778, {wxCloseEvent, setLoggingOff, 1}},
+ {2779, {wxCloseEvent, veto, 1}},
+ {2780, {wxShowEvent, setShow, 1}},
+ {2781, {wxShowEvent, getShow, 0}},
+ {2782, {wxIconizeEvent, iconized, 0}},
+ {2783, {wxJoystickEvent, buttonDown, 1}},
+ {2784, {wxJoystickEvent, buttonIsDown, 1}},
+ {2785, {wxJoystickEvent, buttonUp, 1}},
+ {2786, {wxJoystickEvent, getButtonChange, 0}},
+ {2787, {wxJoystickEvent, getButtonState, 0}},
+ {2788, {wxJoystickEvent, getJoystick, 0}},
+ {2789, {wxJoystickEvent, getPosition, 0}},
+ {2790, {wxJoystickEvent, getZPosition, 0}},
+ {2791, {wxJoystickEvent, isButton, 0}},
+ {2792, {wxJoystickEvent, isMove, 0}},
+ {2793, {wxJoystickEvent, isZMove, 0}},
+ {2794, {wxUpdateUIEvent, canUpdate, 1}},
+ {2795, {wxUpdateUIEvent, check, 1}},
+ {2796, {wxUpdateUIEvent, enable, 1}},
+ {2797, {wxUpdateUIEvent, show, 1}},
+ {2798, {wxUpdateUIEvent, getChecked, 0}},
+ {2799, {wxUpdateUIEvent, getEnabled, 0}},
+ {2800, {wxUpdateUIEvent, getShown, 0}},
+ {2801, {wxUpdateUIEvent, getSetChecked, 0}},
+ {2802, {wxUpdateUIEvent, getSetEnabled, 0}},
+ {2803, {wxUpdateUIEvent, getSetShown, 0}},
+ {2804, {wxUpdateUIEvent, getSetText, 0}},
+ {2805, {wxUpdateUIEvent, getText, 0}},
+ {2806, {wxUpdateUIEvent, getMode, 0}},
+ {2807, {wxUpdateUIEvent, getUpdateInterval, 0}},
+ {2808, {wxUpdateUIEvent, resetUpdateTime, 0}},
+ {2809, {wxUpdateUIEvent, setMode, 1}},
+ {2810, {wxUpdateUIEvent, setText, 1}},
+ {2811, {wxUpdateUIEvent, setUpdateInterval, 1}},
+ {2812, {wxMouseCaptureChangedEvent, getCapturedWindow, 0}},
+ {2813, {wxPaletteChangedEvent, setChangedWindow, 1}},
+ {2814, {wxPaletteChangedEvent, getChangedWindow, 0}},
+ {2815, {wxQueryNewPaletteEvent, setPaletteRealized, 1}},
+ {2816, {wxQueryNewPaletteEvent, getPaletteRealized, 0}},
+ {2817, {wxNavigationKeyEvent, getDirection, 0}},
+ {2818, {wxNavigationKeyEvent, setDirection, 1}},
+ {2819, {wxNavigationKeyEvent, isWindowChange, 0}},
+ {2820, {wxNavigationKeyEvent, setWindowChange, 1}},
+ {2821, {wxNavigationKeyEvent, isFromTab, 0}},
+ {2822, {wxNavigationKeyEvent, setFromTab, 1}},
+ {2823, {wxNavigationKeyEvent, getCurrentFocus, 0}},
+ {2824, {wxNavigationKeyEvent, setCurrentFocus, 1}},
+ {2825, {wxHelpEvent, getOrigin, 0}},
+ {2826, {wxHelpEvent, getPosition, 0}},
+ {2827, {wxHelpEvent, setOrigin, 1}},
+ {2828, {wxHelpEvent, setPosition, 1}},
+ {2829, {wxContextMenuEvent, getPosition, 0}},
+ {2830, {wxContextMenuEvent, setPosition, 1}},
+ {2831, {wxIdleEvent, canSend, 1}},
+ {2832, {wxIdleEvent, getMode, 0}},
+ {2833, {wxIdleEvent, requestMore, 1}},
+ {2834, {wxIdleEvent, moreRequested, 0}},
+ {2835, {wxIdleEvent, setMode, 1}},
+ {2836, {wxGridEvent, altDown, 0}},
+ {2837, {wxGridEvent, controlDown, 0}},
+ {2838, {wxGridEvent, getCol, 0}},
+ {2839, {wxGridEvent, getPosition, 0}},
+ {2840, {wxGridEvent, getRow, 0}},
+ {2841, {wxGridEvent, metaDown, 0}},
+ {2842, {wxGridEvent, selecting, 0}},
+ {2843, {wxGridEvent, shiftDown, 0}},
+ {2844, {wxNotifyEvent, allow, 0}},
+ {2845, {wxNotifyEvent, isAllowed, 0}},
+ {2846, {wxNotifyEvent, veto, 0}},
+ {2847, {wxSashEvent, getEdge, 0}},
+ {2848, {wxSashEvent, getDragRect, 0}},
+ {2849, {wxSashEvent, getDragStatus, 0}},
+ {2850, {wxListEvent, getCacheFrom, 0}},
+ {2851, {wxListEvent, getCacheTo, 0}},
+ {2852, {wxListEvent, getKeyCode, 0}},
+ {2853, {wxListEvent, getIndex, 0}},
+ {2854, {wxListEvent, getColumn, 0}},
+ {2855, {wxListEvent, getPoint, 0}},
+ {2856, {wxListEvent, getLabel, 0}},
+ {2857, {wxListEvent, getText, 0}},
+ {2858, {wxListEvent, getImage, 0}},
+ {2859, {wxListEvent, getData, 0}},
+ {2860, {wxListEvent, getMask, 0}},
+ {2861, {wxListEvent, getItem, 0}},
+ {2862, {wxListEvent, isEditCancelled, 0}},
+ {2863, {wxDateEvent, getDate, 0}},
+ {2864, {wxCalendarEvent, getWeekDay, 0}},
+ {2865, {wxFileDirPickerEvent, getPath, 0}},
+ {2866, {wxColourPickerEvent, getColour, 0}},
+ {2867, {wxFontPickerEvent, getFont, 0}},
+ {2868, {wxStyledTextEvent, getPosition, 0}},
+ {2869, {wxStyledTextEvent, getKey, 0}},
+ {2870, {wxStyledTextEvent, getModifiers, 0}},
+ {2871, {wxStyledTextEvent, getModificationType, 0}},
+ {2872, {wxStyledTextEvent, getText, 0}},
+ {2873, {wxStyledTextEvent, getLength, 0}},
+ {2874, {wxStyledTextEvent, getLinesAdded, 0}},
+ {2875, {wxStyledTextEvent, getLine, 0}},
+ {2876, {wxStyledTextEvent, getFoldLevelNow, 0}},
+ {2877, {wxStyledTextEvent, getFoldLevelPrev, 0}},
+ {2878, {wxStyledTextEvent, getMargin, 0}},
+ {2879, {wxStyledTextEvent, getMessage, 0}},
+ {2880, {wxStyledTextEvent, getWParam, 0}},
+ {2881, {wxStyledTextEvent, getLParam, 0}},
+ {2882, {wxStyledTextEvent, getListType, 0}},
+ {2883, {wxStyledTextEvent, getX, 0}},
+ {2884, {wxStyledTextEvent, getY, 0}},
+ {2885, {wxStyledTextEvent, getDragText, 0}},
+ {2886, {wxStyledTextEvent, getDragAllowMove, 0}},
+ {2887, {wxStyledTextEvent, getDragResult, 0}},
+ {2888, {wxStyledTextEvent, getShift, 0}},
+ {2889, {wxStyledTextEvent, getControl, 0}},
+ {2890, {wxStyledTextEvent, getAlt, 0}},
+ {2891, {utils, getKeyState, 1}},
+ {2892, {utils, getMousePosition, 2}},
+ {2893, {utils, getMouseState, 0}},
+ {2894, {utils, setDetectableAutoRepeat, 1}},
+ {2895, {utils, bell, 0}},
+ {2896, {utils, findMenuItemId, 3}},
+ {2897, {utils, genericFindWindowAtPoint, 1}},
+ {2898, {utils, findWindowAtPoint, 1}},
+ {2899, {utils, beginBusyCursor, 1}},
+ {2900, {utils, endBusyCursor, 0}},
+ {2901, {utils, isBusy, 0}},
+ {2902, {utils, shutdown, 1}},
+ {2903, {utils, shell, 1}},
+ {2904, {utils, launchDefaultBrowser, 2}},
+ {2905, {utils, getEmailAddress, 0}},
+ {2906, {utils, getUserId, 0}},
+ {2907, {utils, getHomeDir, 0}},
+ {2908, {utils, newId, 0}},
+ {2909, {utils, registerId, 1}},
+ {2910, {utils, getCurrentId, 0}},
+ {2911, {utils, getOsDescription, 0}},
+ {2912, {utils, isPlatformLittleEndian, 0}},
+ {2913, {utils, isPlatform64Bit, 0}},
+ {2914, {wxPrintout, new, 1}},
+ {2915, {wxPrintout, destruct, 0}},
+ {2916, {wxPrintout, getDC, 0}},
+ {2917, {wxPrintout, getPageSizeMM, 2}},
+ {2918, {wxPrintout, getPageSizePixels, 2}},
+ {2919, {wxPrintout, getPaperRectPixels, 0}},
+ {2920, {wxPrintout, getPPIPrinter, 2}},
+ {2921, {wxPrintout, getPPIScreen, 2}},
+ {2922, {wxPrintout, getTitle, 0}},
+ {2923, {wxPrintout, isPreview, 0}},
+ {2924, {wxPrintout, fitThisSizeToPaper, 1}},
+ {2925, {wxPrintout, fitThisSizeToPage, 1}},
+ {2926, {wxPrintout, fitThisSizeToPageMargins, 2}},
+ {2927, {wxPrintout, mapScreenSizeToPaper, 0}},
+ {2928, {wxPrintout, mapScreenSizeToPage, 0}},
+ {2929, {wxPrintout, mapScreenSizeToPageMargins, 1}},
+ {2930, {wxPrintout, mapScreenSizeToDevice, 0}},
+ {2931, {wxPrintout, getLogicalPaperRect, 0}},
+ {2932, {wxPrintout, getLogicalPageRect, 0}},
+ {2933, {wxPrintout, getLogicalPageMarginsRect, 1}},
+ {2934, {wxPrintout, setLogicalOrigin, 2}},
+ {2935, {wxPrintout, offsetLogicalOrigin, 2}},
+ {2936, {wxStyledTextCtrl, new_2, 2}},
+ {2937, {wxStyledTextCtrl, new_0, 0}},
+ {2938, {wxStyledTextCtrl, destruct, 0}},
+ {2939, {wxStyledTextCtrl, create, 2}},
+ {2940, {wxStyledTextCtrl, addText, 1}},
+ {2941, {wxStyledTextCtrl, addStyledText, 1}},
+ {2942, {wxStyledTextCtrl, insertText, 2}},
+ {2943, {wxStyledTextCtrl, clearAll, 0}},
+ {2944, {wxStyledTextCtrl, clearDocumentStyle, 0}},
+ {2945, {wxStyledTextCtrl, getLength, 0}},
+ {2946, {wxStyledTextCtrl, getCharAt, 1}},
+ {2947, {wxStyledTextCtrl, getCurrentPos, 0}},
+ {2948, {wxStyledTextCtrl, getAnchor, 0}},
+ {2949, {wxStyledTextCtrl, getStyleAt, 1}},
+ {2950, {wxStyledTextCtrl, redo, 0}},
+ {2951, {wxStyledTextCtrl, setUndoCollection, 1}},
+ {2952, {wxStyledTextCtrl, selectAll, 0}},
+ {2953, {wxStyledTextCtrl, setSavePoint, 0}},
+ {2954, {wxStyledTextCtrl, getStyledText, 2}},
+ {2955, {wxStyledTextCtrl, canRedo, 0}},
+ {2956, {wxStyledTextCtrl, markerLineFromHandle, 1}},
+ {2957, {wxStyledTextCtrl, markerDeleteHandle, 1}},
+ {2958, {wxStyledTextCtrl, getUndoCollection, 0}},
+ {2959, {wxStyledTextCtrl, getViewWhiteSpace, 0}},
+ {2960, {wxStyledTextCtrl, setViewWhiteSpace, 1}},
+ {2961, {wxStyledTextCtrl, positionFromPoint, 1}},
+ {2962, {wxStyledTextCtrl, positionFromPointClose, 2}},
+ {2963, {wxStyledTextCtrl, gotoLine, 1}},
+ {2964, {wxStyledTextCtrl, gotoPos, 1}},
+ {2965, {wxStyledTextCtrl, setAnchor, 1}},
+ {2966, {wxStyledTextCtrl, getCurLine, 1}},
+ {2967, {wxStyledTextCtrl, getEndStyled, 0}},
+ {2968, {wxStyledTextCtrl, convertEOLs, 1}},
+ {2969, {wxStyledTextCtrl, getEOLMode, 0}},
+ {2970, {wxStyledTextCtrl, setEOLMode, 1}},
+ {2971, {wxStyledTextCtrl, startStyling, 2}},
+ {2972, {wxStyledTextCtrl, setStyling, 2}},
+ {2973, {wxStyledTextCtrl, getBufferedDraw, 0}},
+ {2974, {wxStyledTextCtrl, setBufferedDraw, 1}},
+ {2975, {wxStyledTextCtrl, setTabWidth, 1}},
+ {2976, {wxStyledTextCtrl, getTabWidth, 0}},
+ {2977, {wxStyledTextCtrl, setCodePage, 1}},
+ {2978, {wxStyledTextCtrl, markerDefine, 3}},
+ {2979, {wxStyledTextCtrl, markerSetForeground, 2}},
+ {2980, {wxStyledTextCtrl, markerSetBackground, 2}},
+ {2981, {wxStyledTextCtrl, markerAdd, 2}},
+ {2982, {wxStyledTextCtrl, markerDelete, 2}},
+ {2983, {wxStyledTextCtrl, markerDeleteAll, 1}},
+ {2984, {wxStyledTextCtrl, markerGet, 1}},
+ {2985, {wxStyledTextCtrl, markerNext, 2}},
+ {2986, {wxStyledTextCtrl, markerPrevious, 2}},
+ {2987, {wxStyledTextCtrl, markerDefineBitmap, 2}},
+ {2988, {wxStyledTextCtrl, markerAddSet, 2}},
+ {2989, {wxStyledTextCtrl, markerSetAlpha, 2}},
+ {2990, {wxStyledTextCtrl, setMarginType, 2}},
+ {2991, {wxStyledTextCtrl, getMarginType, 1}},
+ {2992, {wxStyledTextCtrl, setMarginWidth, 2}},
+ {2993, {wxStyledTextCtrl, getMarginWidth, 1}},
+ {2994, {wxStyledTextCtrl, setMarginMask, 2}},
+ {2995, {wxStyledTextCtrl, getMarginMask, 1}},
+ {2996, {wxStyledTextCtrl, setMarginSensitive, 2}},
+ {2997, {wxStyledTextCtrl, getMarginSensitive, 1}},
+ {2998, {wxStyledTextCtrl, styleClearAll, 0}},
+ {2999, {wxStyledTextCtrl, styleSetForeground, 2}},
+ {3000, {wxStyledTextCtrl, styleSetBackground, 2}},
+ {3001, {wxStyledTextCtrl, styleSetBold, 2}},
+ {3002, {wxStyledTextCtrl, styleSetItalic, 2}},
+ {3003, {wxStyledTextCtrl, styleSetSize, 2}},
+ {3004, {wxStyledTextCtrl, styleSetFaceName, 2}},
+ {3005, {wxStyledTextCtrl, styleSetEOLFilled, 2}},
+ {3006, {wxStyledTextCtrl, styleResetDefault, 0}},
+ {3007, {wxStyledTextCtrl, styleSetUnderline, 2}},
+ {3008, {wxStyledTextCtrl, styleSetCase, 2}},
+ {3009, {wxStyledTextCtrl, styleSetHotSpot, 2}},
+ {3010, {wxStyledTextCtrl, setSelForeground, 2}},
+ {3011, {wxStyledTextCtrl, setSelBackground, 2}},
+ {3012, {wxStyledTextCtrl, getSelAlpha, 0}},
+ {3013, {wxStyledTextCtrl, setSelAlpha, 1}},
+ {3014, {wxStyledTextCtrl, setCaretForeground, 1}},
+ {3015, {wxStyledTextCtrl, cmdKeyAssign, 3}},
+ {3016, {wxStyledTextCtrl, cmdKeyClear, 2}},
+ {3017, {wxStyledTextCtrl, cmdKeyClearAll, 0}},
+ {3018, {wxStyledTextCtrl, setStyleBytes, 2}},
+ {3019, {wxStyledTextCtrl, styleSetVisible, 2}},
+ {3020, {wxStyledTextCtrl, getCaretPeriod, 0}},
+ {3021, {wxStyledTextCtrl, setCaretPeriod, 1}},
+ {3022, {wxStyledTextCtrl, setWordChars, 1}},
+ {3023, {wxStyledTextCtrl, beginUndoAction, 0}},
+ {3024, {wxStyledTextCtrl, endUndoAction, 0}},
+ {3025, {wxStyledTextCtrl, indicatorSetStyle, 2}},
+ {3026, {wxStyledTextCtrl, indicatorGetStyle, 1}},
+ {3027, {wxStyledTextCtrl, indicatorSetForeground, 2}},
+ {3028, {wxStyledTextCtrl, indicatorGetForeground, 1}},
+ {3029, {wxStyledTextCtrl, setWhitespaceForeground, 2}},
+ {3030, {wxStyledTextCtrl, setWhitespaceBackground, 2}},
+ {3031, {wxStyledTextCtrl, getStyleBits, 0}},
+ {3032, {wxStyledTextCtrl, setLineState, 2}},
+ {3033, {wxStyledTextCtrl, getLineState, 1}},
+ {3034, {wxStyledTextCtrl, getMaxLineState, 0}},
+ {3035, {wxStyledTextCtrl, getCaretLineVisible, 0}},
+ {3036, {wxStyledTextCtrl, setCaretLineVisible, 1}},
+ {3037, {wxStyledTextCtrl, getCaretLineBackground, 0}},
+ {3038, {wxStyledTextCtrl, setCaretLineBackground, 1}},
+ {3039, {wxStyledTextCtrl, autoCompShow, 2}},
+ {3040, {wxStyledTextCtrl, autoCompCancel, 0}},
+ {3041, {wxStyledTextCtrl, autoCompActive, 0}},
+ {3042, {wxStyledTextCtrl, autoCompPosStart, 0}},
+ {3043, {wxStyledTextCtrl, autoCompComplete, 0}},
+ {3044, {wxStyledTextCtrl, autoCompStops, 1}},
+ {3045, {wxStyledTextCtrl, autoCompSetSeparator, 1}},
+ {3046, {wxStyledTextCtrl, autoCompGetSeparator, 0}},
+ {3047, {wxStyledTextCtrl, autoCompSelect, 1}},
+ {3048, {wxStyledTextCtrl, autoCompSetCancelAtStart, 1}},
+ {3049, {wxStyledTextCtrl, autoCompGetCancelAtStart, 0}},
+ {3050, {wxStyledTextCtrl, autoCompSetFillUps, 1}},
+ {3051, {wxStyledTextCtrl, autoCompSetChooseSingle, 1}},
+ {3052, {wxStyledTextCtrl, autoCompGetChooseSingle, 0}},
+ {3053, {wxStyledTextCtrl, autoCompSetIgnoreCase, 1}},
+ {3054, {wxStyledTextCtrl, autoCompGetIgnoreCase, 0}},
+ {3055, {wxStyledTextCtrl, userListShow, 2}},
+ {3056, {wxStyledTextCtrl, autoCompSetAutoHide, 1}},
+ {3057, {wxStyledTextCtrl, autoCompGetAutoHide, 0}},
+ {3058, {wxStyledTextCtrl, autoCompSetDropRestOfWord, 1}},
+ {3059, {wxStyledTextCtrl, autoCompGetDropRestOfWord, 0}},
+ {3060, {wxStyledTextCtrl, registerImage, 2}},
+ {3061, {wxStyledTextCtrl, clearRegisteredImages, 0}},
+ {3062, {wxStyledTextCtrl, autoCompGetTypeSeparator, 0}},
+ {3063, {wxStyledTextCtrl, autoCompSetTypeSeparator, 1}},
+ {3064, {wxStyledTextCtrl, autoCompSetMaxWidth, 1}},
+ {3065, {wxStyledTextCtrl, autoCompGetMaxWidth, 0}},
+ {3066, {wxStyledTextCtrl, autoCompSetMaxHeight, 1}},
+ {3067, {wxStyledTextCtrl, autoCompGetMaxHeight, 0}},
+ {3068, {wxStyledTextCtrl, setIndent, 1}},
+ {3069, {wxStyledTextCtrl, getIndent, 0}},
+ {3070, {wxStyledTextCtrl, setUseTabs, 1}},
+ {3071, {wxStyledTextCtrl, getUseTabs, 0}},
+ {3072, {wxStyledTextCtrl, setLineIndentation, 2}},
+ {3073, {wxStyledTextCtrl, getLineIndentation, 1}},
+ {3074, {wxStyledTextCtrl, getLineIndentPosition, 1}},
+ {3075, {wxStyledTextCtrl, getColumn, 1}},
+ {3076, {wxStyledTextCtrl, setUseHorizontalScrollBar, 1}},
+ {3077, {wxStyledTextCtrl, getUseHorizontalScrollBar, 0}},
+ {3078, {wxStyledTextCtrl, setIndentationGuides, 1}},
+ {3079, {wxStyledTextCtrl, getIndentationGuides, 0}},
+ {3080, {wxStyledTextCtrl, setHighlightGuide, 1}},
+ {3081, {wxStyledTextCtrl, getHighlightGuide, 0}},
+ {3082, {wxStyledTextCtrl, getLineEndPosition, 1}},
+ {3083, {wxStyledTextCtrl, getCodePage, 0}},
+ {3084, {wxStyledTextCtrl, getCaretForeground, 0}},
+ {3085, {wxStyledTextCtrl, getReadOnly, 0}},
+ {3086, {wxStyledTextCtrl, setCurrentPos, 1}},
+ {3087, {wxStyledTextCtrl, setSelectionStart, 1}},
+ {3088, {wxStyledTextCtrl, getSelectionStart, 0}},
+ {3089, {wxStyledTextCtrl, setSelectionEnd, 1}},
+ {3090, {wxStyledTextCtrl, getSelectionEnd, 0}},
+ {3091, {wxStyledTextCtrl, setPrintMagnification, 1}},
+ {3092, {wxStyledTextCtrl, getPrintMagnification, 0}},
+ {3093, {wxStyledTextCtrl, setPrintColourMode, 1}},
+ {3094, {wxStyledTextCtrl, getPrintColourMode, 0}},
+ {3095, {wxStyledTextCtrl, findText, 4}},
+ {3096, {wxStyledTextCtrl, formatRange, 7}},
+ {3097, {wxStyledTextCtrl, getFirstVisibleLine, 0}},
+ {3098, {wxStyledTextCtrl, getLine, 1}},
+ {3099, {wxStyledTextCtrl, getLineCount, 0}},
+ {3100, {wxStyledTextCtrl, setMarginLeft, 1}},
+ {3101, {wxStyledTextCtrl, getMarginLeft, 0}},
+ {3102, {wxStyledTextCtrl, setMarginRight, 1}},
+ {3103, {wxStyledTextCtrl, getMarginRight, 0}},
+ {3104, {wxStyledTextCtrl, getModify, 0}},
+ {3105, {wxStyledTextCtrl, setSelection, 2}},
+ {3106, {wxStyledTextCtrl, getSelectedText, 0}},
+ {3107, {wxStyledTextCtrl, getTextRange, 2}},
+ {3108, {wxStyledTextCtrl, hideSelection, 1}},
+ {3109, {wxStyledTextCtrl, lineFromPosition, 1}},
+ {3110, {wxStyledTextCtrl, positionFromLine, 1}},
+ {3111, {wxStyledTextCtrl, lineScroll, 2}},
+ {3112, {wxStyledTextCtrl, ensureCaretVisible, 0}},
+ {3113, {wxStyledTextCtrl, replaceSelection, 1}},
+ {3114, {wxStyledTextCtrl, setReadOnly, 1}},
+ {3115, {wxStyledTextCtrl, canPaste, 0}},
+ {3116, {wxStyledTextCtrl, canUndo, 0}},
+ {3117, {wxStyledTextCtrl, emptyUndoBuffer, 0}},
+ {3118, {wxStyledTextCtrl, undo, 0}},
+ {3119, {wxStyledTextCtrl, cut, 0}},
+ {3120, {wxStyledTextCtrl, copy, 0}},
+ {3121, {wxStyledTextCtrl, paste, 0}},
+ {3122, {wxStyledTextCtrl, clear, 0}},
+ {3123, {wxStyledTextCtrl, setText, 1}},
+ {3124, {wxStyledTextCtrl, getText, 0}},
+ {3125, {wxStyledTextCtrl, getTextLength, 0}},
+ {3126, {wxStyledTextCtrl, getOvertype, 0}},
+ {3127, {wxStyledTextCtrl, setCaretWidth, 1}},
+ {3128, {wxStyledTextCtrl, getCaretWidth, 0}},
+ {3129, {wxStyledTextCtrl, setTargetStart, 1}},
+ {3130, {wxStyledTextCtrl, getTargetStart, 0}},
+ {3131, {wxStyledTextCtrl, setTargetEnd, 1}},
+ {3132, {wxStyledTextCtrl, getTargetEnd, 0}},
+ {3133, {wxStyledTextCtrl, replaceTarget, 1}},
+ {3134, {wxStyledTextCtrl, searchInTarget, 1}},
+ {3135, {wxStyledTextCtrl, setSearchFlags, 1}},
+ {3136, {wxStyledTextCtrl, getSearchFlags, 0}},
+ {3137, {wxStyledTextCtrl, callTipShow, 2}},
+ {3138, {wxStyledTextCtrl, callTipCancel, 0}},
+ {3139, {wxStyledTextCtrl, callTipActive, 0}},
+ {3140, {wxStyledTextCtrl, callTipPosAtStart, 0}},
+ {3141, {wxStyledTextCtrl, callTipSetHighlight, 2}},
+ {3142, {wxStyledTextCtrl, callTipSetBackground, 1}},
+ {3143, {wxStyledTextCtrl, callTipSetForeground, 1}},
+ {3144, {wxStyledTextCtrl, callTipSetForegroundHighlight, 1}},
+ {3145, {wxStyledTextCtrl, callTipUseStyle, 1}},
+ {3146, {wxStyledTextCtrl, visibleFromDocLine, 1}},
+ {3147, {wxStyledTextCtrl, docLineFromVisible, 1}},
+ {3148, {wxStyledTextCtrl, wrapCount, 1}},
+ {3149, {wxStyledTextCtrl, setFoldLevel, 2}},
+ {3150, {wxStyledTextCtrl, getFoldLevel, 1}},
+ {3151, {wxStyledTextCtrl, getLastChild, 2}},
+ {3152, {wxStyledTextCtrl, getFoldParent, 1}},
+ {3153, {wxStyledTextCtrl, showLines, 2}},
+ {3154, {wxStyledTextCtrl, hideLines, 2}},
+ {3155, {wxStyledTextCtrl, getLineVisible, 1}},
+ {3156, {wxStyledTextCtrl, setFoldExpanded, 2}},
+ {3157, {wxStyledTextCtrl, getFoldExpanded, 1}},
+ {3158, {wxStyledTextCtrl, toggleFold, 1}},
+ {3159, {wxStyledTextCtrl, ensureVisible, 1}},
+ {3160, {wxStyledTextCtrl, setFoldFlags, 1}},
+ {3161, {wxStyledTextCtrl, ensureVisibleEnforcePolicy, 1}},
+ {3162, {wxStyledTextCtrl, setTabIndents, 1}},
+ {3163, {wxStyledTextCtrl, getTabIndents, 0}},
+ {3164, {wxStyledTextCtrl, setBackSpaceUnIndents, 1}},
+ {3165, {wxStyledTextCtrl, getBackSpaceUnIndents, 0}},
+ {3166, {wxStyledTextCtrl, setMouseDwellTime, 1}},
+ {3167, {wxStyledTextCtrl, getMouseDwellTime, 0}},
+ {3168, {wxStyledTextCtrl, wordStartPosition, 2}},
+ {3169, {wxStyledTextCtrl, wordEndPosition, 2}},
+ {3170, {wxStyledTextCtrl, setWrapMode, 1}},
+ {3171, {wxStyledTextCtrl, getWrapMode, 0}},
+ {3172, {wxStyledTextCtrl, setWrapVisualFlags, 1}},
+ {3173, {wxStyledTextCtrl, getWrapVisualFlags, 0}},
+ {3174, {wxStyledTextCtrl, setWrapVisualFlagsLocation, 1}},
+ {3175, {wxStyledTextCtrl, getWrapVisualFlagsLocation, 0}},
+ {3176, {wxStyledTextCtrl, setWrapStartIndent, 1}},
+ {3177, {wxStyledTextCtrl, getWrapStartIndent, 0}},
+ {3178, {wxStyledTextCtrl, setLayoutCache, 1}},
+ {3179, {wxStyledTextCtrl, getLayoutCache, 0}},
+ {3180, {wxStyledTextCtrl, setScrollWidth, 1}},
+ {3181, {wxStyledTextCtrl, getScrollWidth, 0}},
+ {3182, {wxStyledTextCtrl, textWidth, 2}},
+ {3183, {wxStyledTextCtrl, getEndAtLastLine, 0}},
+ {3184, {wxStyledTextCtrl, textHeight, 1}},
+ {3185, {wxStyledTextCtrl, setUseVerticalScrollBar, 1}},
+ {3186, {wxStyledTextCtrl, getUseVerticalScrollBar, 0}},
+ {3187, {wxStyledTextCtrl, appendText, 1}},
+ {3188, {wxStyledTextCtrl, getTwoPhaseDraw, 0}},
+ {3189, {wxStyledTextCtrl, setTwoPhaseDraw, 1}},
+ {3190, {wxStyledTextCtrl, targetFromSelection, 0}},
+ {3191, {wxStyledTextCtrl, linesJoin, 0}},
+ {3192, {wxStyledTextCtrl, linesSplit, 1}},
+ {3193, {wxStyledTextCtrl, setFoldMarginColour, 2}},
+ {3194, {wxStyledTextCtrl, setFoldMarginHiColour, 2}},
+ {3195, {wxStyledTextCtrl, lineDown, 0}},
+ {3196, {wxStyledTextCtrl, lineDownExtend, 0}},
+ {3197, {wxStyledTextCtrl, lineUp, 0}},
+ {3198, {wxStyledTextCtrl, lineUpExtend, 0}},
+ {3199, {wxStyledTextCtrl, charLeft, 0}},
+ {3200, {wxStyledTextCtrl, charLeftExtend, 0}},
+ {3201, {wxStyledTextCtrl, charRight, 0}},
+ {3202, {wxStyledTextCtrl, charRightExtend, 0}},
+ {3203, {wxStyledTextCtrl, wordLeft, 0}},
+ {3204, {wxStyledTextCtrl, wordLeftExtend, 0}},
+ {3205, {wxStyledTextCtrl, wordRight, 0}},
+ {3206, {wxStyledTextCtrl, wordRightExtend, 0}},
+ {3207, {wxStyledTextCtrl, home, 0}},
+ {3208, {wxStyledTextCtrl, homeExtend, 0}},
+ {3209, {wxStyledTextCtrl, lineEnd, 0}},
+ {3210, {wxStyledTextCtrl, lineEndExtend, 0}},
+ {3211, {wxStyledTextCtrl, documentStart, 0}},
+ {3212, {wxStyledTextCtrl, documentStartExtend, 0}},
+ {3213, {wxStyledTextCtrl, documentEnd, 0}},
+ {3214, {wxStyledTextCtrl, documentEndExtend, 0}},
+ {3215, {wxStyledTextCtrl, pageUp, 0}},
+ {3216, {wxStyledTextCtrl, pageUpExtend, 0}},
+ {3217, {wxStyledTextCtrl, pageDown, 0}},
+ {3218, {wxStyledTextCtrl, pageDownExtend, 0}},
+ {3219, {wxStyledTextCtrl, editToggleOvertype, 0}},
+ {3220, {wxStyledTextCtrl, cancel, 0}},
+ {3221, {wxStyledTextCtrl, deleteBack, 0}},
+ {3222, {wxStyledTextCtrl, tab, 0}},
+ {3223, {wxStyledTextCtrl, backTab, 0}},
+ {3224, {wxStyledTextCtrl, newLine, 0}},
+ {3225, {wxStyledTextCtrl, formFeed, 0}},
+ {3226, {wxStyledTextCtrl, vCHome, 0}},
+ {3227, {wxStyledTextCtrl, vCHomeExtend, 0}},
+ {3228, {wxStyledTextCtrl, zoomIn, 0}},
+ {3229, {wxStyledTextCtrl, zoomOut, 0}},
+ {3230, {wxStyledTextCtrl, delWordLeft, 0}},
+ {3231, {wxStyledTextCtrl, delWordRight, 0}},
+ {3232, {wxStyledTextCtrl, lineCut, 0}},
+ {3233, {wxStyledTextCtrl, lineDelete, 0}},
+ {3234, {wxStyledTextCtrl, lineTranspose, 0}},
+ {3235, {wxStyledTextCtrl, lineDuplicate, 0}},
+ {3236, {wxStyledTextCtrl, lowerCase, 0}},
+ {3237, {wxStyledTextCtrl, upperCase, 0}},
+ {3238, {wxStyledTextCtrl, lineScrollDown, 0}},
+ {3239, {wxStyledTextCtrl, lineScrollUp, 0}},
+ {3240, {wxStyledTextCtrl, deleteBackNotLine, 0}},
+ {3241, {wxStyledTextCtrl, homeDisplay, 0}},
+ {3242, {wxStyledTextCtrl, homeDisplayExtend, 0}},
+ {3243, {wxStyledTextCtrl, lineEndDisplay, 0}},
+ {3244, {wxStyledTextCtrl, lineEndDisplayExtend, 0}},
+ {3245, {wxStyledTextCtrl, homeWrapExtend, 0}},
+ {3246, {wxStyledTextCtrl, lineEndWrap, 0}},
+ {3247, {wxStyledTextCtrl, lineEndWrapExtend, 0}},
+ {3248, {wxStyledTextCtrl, vCHomeWrap, 0}},
+ {3249, {wxStyledTextCtrl, vCHomeWrapExtend, 0}},
+ {3250, {wxStyledTextCtrl, lineCopy, 0}},
+ {3251, {wxStyledTextCtrl, moveCaretInsideView, 0}},
+ {3252, {wxStyledTextCtrl, lineLength, 1}},
+ {3253, {wxStyledTextCtrl, braceHighlight, 2}},
+ {3254, {wxStyledTextCtrl, braceBadLight, 1}},
+ {3255, {wxStyledTextCtrl, braceMatch, 1}},
+ {3256, {wxStyledTextCtrl, getViewEOL, 0}},
+ {3257, {wxStyledTextCtrl, setViewEOL, 1}},
+ {3258, {wxStyledTextCtrl, setModEventMask, 1}},
+ {3259, {wxStyledTextCtrl, getEdgeColumn, 0}},
+ {3260, {wxStyledTextCtrl, setEdgeColumn, 1}},
+ {3261, {wxStyledTextCtrl, getEdgeMode, 0}},
+ {3262, {wxStyledTextCtrl, getEdgeColour, 0}},
+ {3263, {wxStyledTextCtrl, setEdgeColour, 1}},
+ {3264, {wxStyledTextCtrl, searchAnchor, 0}},
+ {3265, {wxStyledTextCtrl, searchNext, 2}},
+ {3266, {wxStyledTextCtrl, searchPrev, 2}},
+ {3267, {wxStyledTextCtrl, linesOnScreen, 0}},
+ {3268, {wxStyledTextCtrl, usePopUp, 1}},
+ {3269, {wxStyledTextCtrl, selectionIsRectangle, 0}},
+ {3270, {wxStyledTextCtrl, setZoom, 1}},
+ {3271, {wxStyledTextCtrl, getZoom, 0}},
+ {3272, {wxStyledTextCtrl, getModEventMask, 0}},
+ {3273, {wxStyledTextCtrl, setSTCFocus, 1}},
+ {3274, {wxStyledTextCtrl, getSTCFocus, 0}},
+ {3275, {wxStyledTextCtrl, setStatus, 1}},
+ {3276, {wxStyledTextCtrl, getStatus, 0}},
+ {3277, {wxStyledTextCtrl, setMouseDownCaptures, 1}},
+ {3278, {wxStyledTextCtrl, getMouseDownCaptures, 0}},
+ {3279, {wxStyledTextCtrl, setSTCCursor, 1}},
+ {3280, {wxStyledTextCtrl, getSTCCursor, 0}},
+ {3281, {wxStyledTextCtrl, setControlCharSymbol, 1}},
+ {3282, {wxStyledTextCtrl, getControlCharSymbol, 0}},
+ {3283, {wxStyledTextCtrl, wordPartLeft, 0}},
+ {3284, {wxStyledTextCtrl, wordPartLeftExtend, 0}},
+ {3285, {wxStyledTextCtrl, wordPartRight, 0}},
+ {3286, {wxStyledTextCtrl, wordPartRightExtend, 0}},
+ {3287, {wxStyledTextCtrl, setVisiblePolicy, 2}},
+ {3288, {wxStyledTextCtrl, delLineLeft, 0}},
+ {3289, {wxStyledTextCtrl, delLineRight, 0}},
+ {3290, {wxStyledTextCtrl, getXOffset, 0}},
+ {3291, {wxStyledTextCtrl, chooseCaretX, 0}},
+ {3292, {wxStyledTextCtrl, setXCaretPolicy, 2}},
+ {3293, {wxStyledTextCtrl, setYCaretPolicy, 2}},
+ {3294, {wxStyledTextCtrl, getPrintWrapMode, 0}},
+ {3295, {wxStyledTextCtrl, setHotspotActiveForeground, 2}},
+ {3296, {wxStyledTextCtrl, setHotspotActiveBackground, 2}},
+ {3297, {wxStyledTextCtrl, setHotspotActiveUnderline, 1}},
+ {3298, {wxStyledTextCtrl, setHotspotSingleLine, 1}},
+ {3299, {wxStyledTextCtrl, paraDownExtend, 0}},
+ {3300, {wxStyledTextCtrl, paraUp, 0}},
+ {3301, {wxStyledTextCtrl, paraUpExtend, 0}},
+ {3302, {wxStyledTextCtrl, positionBefore, 1}},
+ {3303, {wxStyledTextCtrl, positionAfter, 1}},
+ {3304, {wxStyledTextCtrl, copyRange, 2}},
+ {3305, {wxStyledTextCtrl, copyText, 2}},
+ {3306, {wxStyledTextCtrl, setSelectionMode, 1}},
+ {3307, {wxStyledTextCtrl, getSelectionMode, 0}},
+ {3308, {wxStyledTextCtrl, lineDownRectExtend, 0}},
+ {3309, {wxStyledTextCtrl, lineUpRectExtend, 0}},
+ {3310, {wxStyledTextCtrl, charLeftRectExtend, 0}},
+ {3311, {wxStyledTextCtrl, charRightRectExtend, 0}},
+ {3312, {wxStyledTextCtrl, homeRectExtend, 0}},
+ {3313, {wxStyledTextCtrl, vCHomeRectExtend, 0}},
+ {3314, {wxStyledTextCtrl, lineEndRectExtend, 0}},
+ {3315, {wxStyledTextCtrl, pageUpRectExtend, 0}},
+ {3316, {wxStyledTextCtrl, pageDownRectExtend, 0}},
+ {3317, {wxStyledTextCtrl, stutteredPageUp, 0}},
+ {3318, {wxStyledTextCtrl, stutteredPageUpExtend, 0}},
+ {3319, {wxStyledTextCtrl, stutteredPageDown, 0}},
+ {3320, {wxStyledTextCtrl, stutteredPageDownExtend, 0}},
+ {3321, {wxStyledTextCtrl, wordLeftEnd, 0}},
+ {3322, {wxStyledTextCtrl, wordLeftEndExtend, 0}},
+ {3323, {wxStyledTextCtrl, wordRightEnd, 0}},
+ {3324, {wxStyledTextCtrl, wordRightEndExtend, 0}},
+ {3325, {wxStyledTextCtrl, setWhitespaceChars, 1}},
+ {3326, {wxStyledTextCtrl, setCharsDefault, 0}},
+ {3327, {wxStyledTextCtrl, autoCompGetCurrent, 0}},
+ {3328, {wxStyledTextCtrl, allocate, 1}},
+ {3329, {wxStyledTextCtrl, findColumn, 2}},
+ {3330, {wxStyledTextCtrl, getCaretSticky, 0}},
+ {3331, {wxStyledTextCtrl, setCaretSticky, 1}},
+ {3332, {wxStyledTextCtrl, toggleCaretSticky, 0}},
+ {3333, {wxStyledTextCtrl, setPasteConvertEndings, 1}},
+ {3334, {wxStyledTextCtrl, getPasteConvertEndings, 0}},
+ {3335, {wxStyledTextCtrl, selectionDuplicate, 0}},
+ {3336, {wxStyledTextCtrl, setCaretLineBackAlpha, 1}},
+ {3337, {wxStyledTextCtrl, getCaretLineBackAlpha, 0}},
+ {3338, {wxStyledTextCtrl, startRecord, 0}},
+ {3339, {wxStyledTextCtrl, stopRecord, 0}},
+ {3340, {wxStyledTextCtrl, setLexer, 1}},
+ {3341, {wxStyledTextCtrl, getLexer, 0}},
+ {3342, {wxStyledTextCtrl, colourise, 2}},
+ {3343, {wxStyledTextCtrl, setProperty, 2}},
+ {3344, {wxStyledTextCtrl, setKeyWords, 2}},
+ {3345, {wxStyledTextCtrl, setLexerLanguage, 1}},
+ {3346, {wxStyledTextCtrl, getProperty, 1}},
+ {3347, {wxStyledTextCtrl, getStyleBitsNeeded, 0}},
+ {3348, {wxStyledTextCtrl, getCurrentLine, 0}},
+ {3349, {wxStyledTextCtrl, styleSetSpec, 2}},
+ {3350, {wxStyledTextCtrl, styleSetFont, 2}},
+ {3351, {wxStyledTextCtrl, styleSetFontAttr, 7}},
+ {3352, {wxStyledTextCtrl, styleSetCharacterSet, 2}},
+ {3353, {wxStyledTextCtrl, styleSetFontEncoding, 2}},
+ {3354, {wxStyledTextCtrl, cmdKeyExecute, 1}},
+ {3355, {wxStyledTextCtrl, setMargins, 2}},
+ {3356, {wxStyledTextCtrl, getSelection, 2}},
+ {3357, {wxStyledTextCtrl, pointFromPosition, 1}},
+ {3358, {wxStyledTextCtrl, scrollToLine, 1}},
+ {3359, {wxStyledTextCtrl, scrollToColumn, 1}},
+ {3360, {wxStyledTextCtrl, sendMsg, 2}},
+ {3361, {wxStyledTextCtrl, setVScrollBar, 1}},
+ {3362, {wxStyledTextCtrl, setHScrollBar, 1}},
+ {3363, {wxStyledTextCtrl, getLastKeydownProcessed, 0}},
+ {3364, {wxStyledTextCtrl, setLastKeydownProcessed, 1}},
+ {3365, {wxStyledTextCtrl, saveFile, 1}},
+ {3366, {wxStyledTextCtrl, loadFile, 1}},
+ {3367, {wxStyledTextCtrl, doDragOver, 3}},
+ {3368, {wxStyledTextCtrl, doDropText, 3}},
+ {3369, {wxStyledTextCtrl, getUseAntiAliasing, 0}},
+ {3370, {wxStyledTextCtrl, addTextRaw, 1}},
+ {3371, {wxStyledTextCtrl, insertTextRaw, 2}},
+ {3372, {wxStyledTextCtrl, getCurLineRaw, 1}},
+ {3373, {wxStyledTextCtrl, getLineRaw, 1}},
+ {3374, {wxStyledTextCtrl, getSelectedTextRaw, 0}},
+ {3375, {wxStyledTextCtrl, getTextRangeRaw, 2}},
+ {3376, {wxStyledTextCtrl, setTextRaw, 1}},
+ {3377, {wxStyledTextCtrl, getTextRaw, 0}},
+ {3378, {wxStyledTextCtrl, appendTextRaw, 1}},
+ {3379, {wxArtProvider, getBitmap, 2}},
+ {3380, {wxArtProvider, getIcon, 2}},
+ {3381, {wxTreeEvent, getKeyCode, 0}},
+ {3382, {wxTreeEvent, getItem, 0}},
+ {3383, {wxTreeEvent, getKeyEvent, 0}},
+ {3384, {wxTreeEvent, getLabel, 0}},
+ {3385, {wxTreeEvent, getOldItem, 0}},
+ {3386, {wxTreeEvent, getPoint, 0}},
+ {3387, {wxTreeEvent, isEditCancelled, 0}},
+ {3388, {wxTreeEvent, setToolTip, 1}},
+ {3389, {wxNotebookEvent, getOldSelection, 0}},
+ {3390, {wxNotebookEvent, getSelection, 0}},
+ {3391, {wxNotebookEvent, setOldSelection, 1}},
+ {3392, {wxNotebookEvent, setSelection, 1}},
+ {3393, {wxFileDataObject, new, 0}},
+ {3394, {wxFileDataObject, addFile, 1}},
+ {3395, {wxFileDataObject, getFilenames, 0}},
+ {3396, {wxFileDataObject, 'Destroy', undefined}},
+ {3397, {wxTextDataObject, new, 1}},
+ {3398, {wxTextDataObject, getTextLength, 0}},
+ {3399, {wxTextDataObject, getText, 0}},
+ {3400, {wxTextDataObject, setText, 1}},
+ {3401, {wxTextDataObject, 'Destroy', undefined}},
+ {3402, {wxBitmapDataObject, new_1_1, 1}},
+ {3403, {wxBitmapDataObject, new_1_0, 1}},
+ {3404, {wxBitmapDataObject, getBitmap, 0}},
+ {3405, {wxBitmapDataObject, setBitmap, 1}},
+ {3406, {wxBitmapDataObject, 'Destroy', undefined}},
+ {3408, {wxClipboard, new, 0}},
+ {3409, {wxClipboard, destruct, 0}},
+ {3410, {wxClipboard, addData, 1}},
+ {3411, {wxClipboard, clear, 0}},
+ {3412, {wxClipboard, close, 0}},
+ {3413, {wxClipboard, flush, 0}},
+ {3414, {wxClipboard, getData, 1}},
+ {3415, {wxClipboard, isOpened, 0}},
+ {3416, {wxClipboard, open, 0}},
+ {3417, {wxClipboard, setData, 1}},
+ {3419, {wxClipboard, usePrimarySelection, 1}},
+ {3420, {wxClipboard, isSupported, 1}},
+ {3421, {wxClipboard, get, 0}},
+ {3422, {wxSpinEvent, getPosition, 0}},
+ {3423, {wxSpinEvent, setPosition, 1}},
+ {3424, {wxSplitterWindow, new_0, 0}},
+ {3425, {wxSplitterWindow, new_2, 2}},
+ {3426, {wxSplitterWindow, destruct, 0}},
+ {3427, {wxSplitterWindow, create, 2}},
+ {3428, {wxSplitterWindow, getMinimumPaneSize, 0}},
+ {3429, {wxSplitterWindow, getSashGravity, 0}},
+ {3430, {wxSplitterWindow, getSashPosition, 0}},
+ {3431, {wxSplitterWindow, getSplitMode, 0}},
+ {3432, {wxSplitterWindow, getWindow1, 0}},
+ {3433, {wxSplitterWindow, getWindow2, 0}},
+ {3434, {wxSplitterWindow, initialize, 1}},
+ {3435, {wxSplitterWindow, isSplit, 0}},
+ {3436, {wxSplitterWindow, replaceWindow, 2}},
+ {3437, {wxSplitterWindow, setSashGravity, 1}},
+ {3438, {wxSplitterWindow, setSashPosition, 2}},
+ {3439, {wxSplitterWindow, setSashSize, 1}},
+ {3440, {wxSplitterWindow, setMinimumPaneSize, 1}},
+ {3441, {wxSplitterWindow, setSplitMode, 1}},
+ {3442, {wxSplitterWindow, splitHorizontally, 3}},
+ {3443, {wxSplitterWindow, splitVertically, 3}},
+ {3444, {wxSplitterWindow, unsplit, 1}},
+ {3445, {wxSplitterWindow, updateSize, 0}},
+ {3446, {wxSplitterEvent, getSashPosition, 0}},
+ {3447, {wxSplitterEvent, getX, 0}},
+ {3448, {wxSplitterEvent, getY, 0}},
+ {3449, {wxSplitterEvent, getWindowBeingRemoved, 0}},
+ {3450, {wxSplitterEvent, setSashPosition, 1}},
+ {3451, {wxHtmlWindow, new_0, 0}},
+ {3452, {wxHtmlWindow, new_2, 2}},
+ {3453, {wxHtmlWindow, appendToPage, 1}},
+ {3454, {wxHtmlWindow, getOpenedAnchor, 0}},
+ {3455, {wxHtmlWindow, getOpenedPage, 0}},
+ {3456, {wxHtmlWindow, getOpenedPageTitle, 0}},
+ {3457, {wxHtmlWindow, getRelatedFrame, 0}},
+ {3458, {wxHtmlWindow, historyBack, 0}},
+ {3459, {wxHtmlWindow, historyCanBack, 0}},
+ {3460, {wxHtmlWindow, historyCanForward, 0}},
+ {3461, {wxHtmlWindow, historyClear, 0}},
+ {3462, {wxHtmlWindow, historyForward, 0}},
+ {3463, {wxHtmlWindow, loadFile, 1}},
+ {3464, {wxHtmlWindow, loadPage, 1}},
+ {3465, {wxHtmlWindow, selectAll, 0}},
+ {3466, {wxHtmlWindow, selectionToText, 0}},
+ {3467, {wxHtmlWindow, selectLine, 1}},
+ {3468, {wxHtmlWindow, selectWord, 1}},
+ {3469, {wxHtmlWindow, setBorders, 1}},
+ {3470, {wxHtmlWindow, setFonts, 3}},
+ {3471, {wxHtmlWindow, setPage, 1}},
+ {3472, {wxHtmlWindow, setRelatedFrame, 2}},
+ {3473, {wxHtmlWindow, setRelatedStatusBar, 1}},
+ {3474, {wxHtmlWindow, toText, 0}},
+ {3475, {wxHtmlWindow, 'Destroy', undefined}},
+ {3476, {wxHtmlLinkEvent, getLinkInfo, 0}},
+ {3477, {wxAuiNotebookEvent, setSelection, 1}},
+ {3478, {wxAuiNotebookEvent, getSelection, 0}},
+ {3479, {wxAuiNotebookEvent, setOldSelection, 1}},
+ {3480, {wxAuiNotebookEvent, getOldSelection, 0}},
+ {3481, {wxAuiNotebookEvent, setDragSource, 1}},
+ {3482, {wxAuiNotebookEvent, getDragSource, 0}},
+ {3483, {wxAuiManagerEvent, setManager, 1}},
+ {3484, {wxAuiManagerEvent, getManager, 0}},
+ {3485, {wxAuiManagerEvent, setPane, 1}},
+ {3486, {wxAuiManagerEvent, getPane, 0}},
+ {3487, {wxAuiManagerEvent, setButton, 1}},
+ {3488, {wxAuiManagerEvent, getButton, 0}},
+ {3489, {wxAuiManagerEvent, setDC, 1}},
+ {3490, {wxAuiManagerEvent, getDC, 0}},
+ {3491, {wxAuiManagerEvent, veto, 1}},
+ {3492, {wxAuiManagerEvent, getVeto, 0}},
+ {3493, {wxAuiManagerEvent, setCanVeto, 1}},
+ {3494, {wxAuiManagerEvent, canVeto, 0}},
+ {3495, {wxLogNull, new, 0}},
+ {3496, {wxLogNull, 'Destroy', undefined}},
{-1, {mod, func, -1}}
].
diff --git a/lib/wx/src/gen/wxe_funcs.hrl b/lib/wx/src/gen/wxe_funcs.hrl
index eef90961db..b1d5e50647 100644
--- a/lib/wx/src/gen/wxe_funcs.hrl
+++ b/lib/wx/src/gen/wxe_funcs.hrl
@@ -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%
%% This file is generated DO NOT EDIT
@@ -1516,1758 +1516,1760 @@
-define(wxListCtrl_GetColumnCount, 1672).
-define(wxListCtrl_GetColumnWidth, 1673).
-define(wxListCtrl_GetCountPerPage, 1674).
--define(wxListCtrl_GetImageList, 1675).
--define(wxListCtrl_GetItem, 1676).
--define(wxListCtrl_GetItemBackgroundColour, 1677).
--define(wxListCtrl_GetItemCount, 1678).
--define(wxListCtrl_GetItemData, 1679).
--define(wxListCtrl_GetItemFont, 1680).
--define(wxListCtrl_GetItemPosition, 1681).
--define(wxListCtrl_GetItemRect, 1682).
--define(wxListCtrl_GetItemSpacing, 1683).
--define(wxListCtrl_GetItemState, 1684).
--define(wxListCtrl_GetItemText, 1685).
--define(wxListCtrl_GetItemTextColour, 1686).
--define(wxListCtrl_GetNextItem, 1687).
--define(wxListCtrl_GetSelectedItemCount, 1688).
--define(wxListCtrl_GetTextColour, 1689).
--define(wxListCtrl_GetTopItem, 1690).
--define(wxListCtrl_GetViewRect, 1691).
--define(wxListCtrl_HitTest, 1692).
--define(wxListCtrl_InsertColumn_2, 1693).
--define(wxListCtrl_InsertColumn_3, 1694).
--define(wxListCtrl_InsertItem_1, 1695).
--define(wxListCtrl_InsertItem_2_1, 1696).
--define(wxListCtrl_InsertItem_2_0, 1697).
--define(wxListCtrl_InsertItem_3, 1698).
--define(wxListCtrl_RefreshItem, 1699).
--define(wxListCtrl_RefreshItems, 1700).
--define(wxListCtrl_ScrollList, 1701).
--define(wxListCtrl_SetBackgroundColour, 1702).
--define(wxListCtrl_SetColumn, 1703).
--define(wxListCtrl_SetColumnWidth, 1704).
--define(wxListCtrl_SetImageList, 1705).
--define(wxListCtrl_SetItem_1, 1706).
--define(wxListCtrl_SetItem_4, 1707).
--define(wxListCtrl_SetItemBackgroundColour, 1708).
--define(wxListCtrl_SetItemCount, 1709).
--define(wxListCtrl_SetItemData, 1710).
--define(wxListCtrl_SetItemFont, 1711).
--define(wxListCtrl_SetItemImage, 1712).
--define(wxListCtrl_SetItemColumnImage, 1713).
--define(wxListCtrl_SetItemPosition, 1714).
--define(wxListCtrl_SetItemState, 1715).
--define(wxListCtrl_SetItemText, 1716).
--define(wxListCtrl_SetItemTextColour, 1717).
--define(wxListCtrl_SetSingleStyle, 1718).
--define(wxListCtrl_SetTextColour, 1719).
--define(wxListCtrl_SetWindowStyleFlag, 1720).
--define(wxListCtrl_SortItems, 1721).
--define(wxListCtrl_destroy, 1722).
--define(wxListView_ClearColumnImage, 1723).
--define(wxListView_Focus, 1724).
--define(wxListView_GetFirstSelected, 1725).
--define(wxListView_GetFocusedItem, 1726).
--define(wxListView_GetNextSelected, 1727).
--define(wxListView_IsSelected, 1728).
--define(wxListView_Select, 1729).
--define(wxListView_SetColumnImage, 1730).
--define(wxListItem_new_0, 1731).
--define(wxListItem_new_1, 1732).
--define(wxListItem_destruct, 1733).
--define(wxListItem_Clear, 1734).
--define(wxListItem_GetAlign, 1735).
--define(wxListItem_GetBackgroundColour, 1736).
--define(wxListItem_GetColumn, 1737).
--define(wxListItem_GetFont, 1738).
--define(wxListItem_GetId, 1739).
--define(wxListItem_GetImage, 1740).
--define(wxListItem_GetMask, 1741).
--define(wxListItem_GetState, 1742).
--define(wxListItem_GetText, 1743).
--define(wxListItem_GetTextColour, 1744).
--define(wxListItem_GetWidth, 1745).
--define(wxListItem_SetAlign, 1746).
--define(wxListItem_SetBackgroundColour, 1747).
--define(wxListItem_SetColumn, 1748).
--define(wxListItem_SetFont, 1749).
--define(wxListItem_SetId, 1750).
--define(wxListItem_SetImage, 1751).
--define(wxListItem_SetMask, 1752).
--define(wxListItem_SetState, 1753).
--define(wxListItem_SetStateMask, 1754).
--define(wxListItem_SetText, 1755).
--define(wxListItem_SetTextColour, 1756).
--define(wxListItem_SetWidth, 1757).
--define(wxImageList_new_0, 1758).
--define(wxImageList_new_3, 1759).
--define(wxImageList_Add_1, 1760).
--define(wxImageList_Add_2_0, 1761).
--define(wxImageList_Add_2_1, 1762).
--define(wxImageList_Create, 1763).
--define(wxImageList_Draw, 1765).
--define(wxImageList_GetBitmap, 1766).
--define(wxImageList_GetIcon, 1767).
--define(wxImageList_GetImageCount, 1768).
--define(wxImageList_GetSize, 1769).
--define(wxImageList_Remove, 1770).
--define(wxImageList_RemoveAll, 1771).
--define(wxImageList_Replace_2, 1772).
--define(wxImageList_Replace_3, 1773).
--define(wxImageList_destroy, 1774).
--define(wxTextAttr_new_0, 1775).
--define(wxTextAttr_new_2, 1776).
--define(wxTextAttr_GetAlignment, 1777).
--define(wxTextAttr_GetBackgroundColour, 1778).
--define(wxTextAttr_GetFont, 1779).
--define(wxTextAttr_GetLeftIndent, 1780).
--define(wxTextAttr_GetLeftSubIndent, 1781).
--define(wxTextAttr_GetRightIndent, 1782).
--define(wxTextAttr_GetTabs, 1783).
--define(wxTextAttr_GetTextColour, 1784).
--define(wxTextAttr_HasBackgroundColour, 1785).
--define(wxTextAttr_HasFont, 1786).
--define(wxTextAttr_HasTextColour, 1787).
--define(wxTextAttr_GetFlags, 1788).
--define(wxTextAttr_IsDefault, 1789).
--define(wxTextAttr_SetAlignment, 1790).
--define(wxTextAttr_SetBackgroundColour, 1791).
--define(wxTextAttr_SetFlags, 1792).
--define(wxTextAttr_SetFont, 1793).
--define(wxTextAttr_SetLeftIndent, 1794).
--define(wxTextAttr_SetRightIndent, 1795).
--define(wxTextAttr_SetTabs, 1796).
--define(wxTextAttr_SetTextColour, 1797).
--define(wxTextAttr_destroy, 1798).
--define(wxTextCtrl_new_3, 1800).
--define(wxTextCtrl_new_0, 1801).
--define(wxTextCtrl_destruct, 1803).
--define(wxTextCtrl_AppendText, 1804).
--define(wxTextCtrl_CanCopy, 1805).
--define(wxTextCtrl_CanCut, 1806).
--define(wxTextCtrl_CanPaste, 1807).
--define(wxTextCtrl_CanRedo, 1808).
--define(wxTextCtrl_CanUndo, 1809).
--define(wxTextCtrl_Clear, 1810).
--define(wxTextCtrl_Copy, 1811).
--define(wxTextCtrl_Create, 1812).
--define(wxTextCtrl_Cut, 1813).
--define(wxTextCtrl_DiscardEdits, 1814).
--define(wxTextCtrl_EmulateKeyPress, 1815).
--define(wxTextCtrl_GetDefaultStyle, 1816).
--define(wxTextCtrl_GetInsertionPoint, 1817).
--define(wxTextCtrl_GetLastPosition, 1818).
--define(wxTextCtrl_GetLineLength, 1819).
--define(wxTextCtrl_GetLineText, 1820).
--define(wxTextCtrl_GetNumberOfLines, 1821).
--define(wxTextCtrl_GetRange, 1822).
--define(wxTextCtrl_GetSelection, 1823).
--define(wxTextCtrl_GetStringSelection, 1824).
--define(wxTextCtrl_GetStyle, 1825).
--define(wxTextCtrl_GetValue, 1826).
--define(wxTextCtrl_IsEditable, 1827).
--define(wxTextCtrl_IsModified, 1828).
--define(wxTextCtrl_IsMultiLine, 1829).
--define(wxTextCtrl_IsSingleLine, 1830).
--define(wxTextCtrl_LoadFile, 1831).
--define(wxTextCtrl_MarkDirty, 1832).
--define(wxTextCtrl_Paste, 1833).
--define(wxTextCtrl_PositionToXY, 1834).
--define(wxTextCtrl_Redo, 1835).
--define(wxTextCtrl_Remove, 1836).
--define(wxTextCtrl_Replace, 1837).
--define(wxTextCtrl_SaveFile, 1838).
--define(wxTextCtrl_SetDefaultStyle, 1839).
--define(wxTextCtrl_SetEditable, 1840).
--define(wxTextCtrl_SetInsertionPoint, 1841).
--define(wxTextCtrl_SetInsertionPointEnd, 1842).
--define(wxTextCtrl_SetMaxLength, 1844).
--define(wxTextCtrl_SetSelection, 1845).
--define(wxTextCtrl_SetStyle, 1846).
--define(wxTextCtrl_SetValue, 1847).
--define(wxTextCtrl_ShowPosition, 1848).
--define(wxTextCtrl_Undo, 1849).
--define(wxTextCtrl_WriteText, 1850).
--define(wxTextCtrl_XYToPosition, 1851).
--define(wxNotebook_new_0, 1854).
--define(wxNotebook_new_3, 1855).
--define(wxNotebook_destruct, 1856).
--define(wxNotebook_AddPage, 1857).
--define(wxNotebook_AdvanceSelection, 1858).
--define(wxNotebook_AssignImageList, 1859).
--define(wxNotebook_Create, 1860).
--define(wxNotebook_DeleteAllPages, 1861).
--define(wxNotebook_DeletePage, 1862).
--define(wxNotebook_RemovePage, 1863).
--define(wxNotebook_GetCurrentPage, 1864).
--define(wxNotebook_GetImageList, 1865).
--define(wxNotebook_GetPage, 1867).
--define(wxNotebook_GetPageCount, 1868).
--define(wxNotebook_GetPageImage, 1869).
--define(wxNotebook_GetPageText, 1870).
--define(wxNotebook_GetRowCount, 1871).
--define(wxNotebook_GetSelection, 1872).
--define(wxNotebook_GetThemeBackgroundColour, 1873).
--define(wxNotebook_HitTest, 1875).
--define(wxNotebook_InsertPage, 1877).
--define(wxNotebook_SetImageList, 1878).
--define(wxNotebook_SetPadding, 1879).
--define(wxNotebook_SetPageSize, 1880).
--define(wxNotebook_SetPageImage, 1881).
--define(wxNotebook_SetPageText, 1882).
--define(wxNotebook_SetSelection, 1883).
--define(wxNotebook_ChangeSelection, 1884).
--define(wxChoicebook_new_0, 1885).
--define(wxChoicebook_new_3, 1886).
--define(wxChoicebook_AddPage, 1887).
--define(wxChoicebook_AdvanceSelection, 1888).
--define(wxChoicebook_AssignImageList, 1889).
--define(wxChoicebook_Create, 1890).
--define(wxChoicebook_DeleteAllPages, 1891).
--define(wxChoicebook_DeletePage, 1892).
--define(wxChoicebook_RemovePage, 1893).
--define(wxChoicebook_GetCurrentPage, 1894).
--define(wxChoicebook_GetImageList, 1895).
--define(wxChoicebook_GetPage, 1897).
--define(wxChoicebook_GetPageCount, 1898).
--define(wxChoicebook_GetPageImage, 1899).
--define(wxChoicebook_GetPageText, 1900).
--define(wxChoicebook_GetSelection, 1901).
--define(wxChoicebook_HitTest, 1902).
--define(wxChoicebook_InsertPage, 1903).
--define(wxChoicebook_SetImageList, 1904).
--define(wxChoicebook_SetPageSize, 1905).
--define(wxChoicebook_SetPageImage, 1906).
--define(wxChoicebook_SetPageText, 1907).
--define(wxChoicebook_SetSelection, 1908).
--define(wxChoicebook_ChangeSelection, 1909).
--define(wxChoicebook_destroy, 1910).
--define(wxToolbook_new_0, 1911).
--define(wxToolbook_new_3, 1912).
--define(wxToolbook_AddPage, 1913).
--define(wxToolbook_AdvanceSelection, 1914).
--define(wxToolbook_AssignImageList, 1915).
--define(wxToolbook_Create, 1916).
--define(wxToolbook_DeleteAllPages, 1917).
--define(wxToolbook_DeletePage, 1918).
--define(wxToolbook_RemovePage, 1919).
--define(wxToolbook_GetCurrentPage, 1920).
--define(wxToolbook_GetImageList, 1921).
--define(wxToolbook_GetPage, 1923).
--define(wxToolbook_GetPageCount, 1924).
--define(wxToolbook_GetPageImage, 1925).
--define(wxToolbook_GetPageText, 1926).
--define(wxToolbook_GetSelection, 1927).
--define(wxToolbook_HitTest, 1929).
--define(wxToolbook_InsertPage, 1930).
--define(wxToolbook_SetImageList, 1931).
--define(wxToolbook_SetPageSize, 1932).
--define(wxToolbook_SetPageImage, 1933).
--define(wxToolbook_SetPageText, 1934).
--define(wxToolbook_SetSelection, 1935).
--define(wxToolbook_ChangeSelection, 1936).
--define(wxToolbook_destroy, 1937).
--define(wxListbook_new_0, 1938).
--define(wxListbook_new_3, 1939).
--define(wxListbook_AddPage, 1940).
--define(wxListbook_AdvanceSelection, 1941).
--define(wxListbook_AssignImageList, 1942).
--define(wxListbook_Create, 1943).
--define(wxListbook_DeleteAllPages, 1944).
--define(wxListbook_DeletePage, 1945).
--define(wxListbook_RemovePage, 1946).
--define(wxListbook_GetCurrentPage, 1947).
--define(wxListbook_GetImageList, 1948).
--define(wxListbook_GetPage, 1950).
--define(wxListbook_GetPageCount, 1951).
--define(wxListbook_GetPageImage, 1952).
--define(wxListbook_GetPageText, 1953).
--define(wxListbook_GetSelection, 1954).
--define(wxListbook_HitTest, 1956).
--define(wxListbook_InsertPage, 1957).
--define(wxListbook_SetImageList, 1958).
--define(wxListbook_SetPageSize, 1959).
--define(wxListbook_SetPageImage, 1960).
--define(wxListbook_SetPageText, 1961).
--define(wxListbook_SetSelection, 1962).
--define(wxListbook_ChangeSelection, 1963).
--define(wxListbook_destroy, 1964).
--define(wxTreebook_new_0, 1965).
--define(wxTreebook_new_3, 1966).
--define(wxTreebook_AddPage, 1967).
--define(wxTreebook_AdvanceSelection, 1968).
--define(wxTreebook_AssignImageList, 1969).
--define(wxTreebook_Create, 1970).
--define(wxTreebook_DeleteAllPages, 1971).
--define(wxTreebook_DeletePage, 1972).
--define(wxTreebook_RemovePage, 1973).
--define(wxTreebook_GetCurrentPage, 1974).
--define(wxTreebook_GetImageList, 1975).
--define(wxTreebook_GetPage, 1977).
--define(wxTreebook_GetPageCount, 1978).
--define(wxTreebook_GetPageImage, 1979).
--define(wxTreebook_GetPageText, 1980).
--define(wxTreebook_GetSelection, 1981).
--define(wxTreebook_ExpandNode, 1982).
--define(wxTreebook_IsNodeExpanded, 1983).
--define(wxTreebook_HitTest, 1985).
--define(wxTreebook_InsertPage, 1986).
--define(wxTreebook_InsertSubPage, 1987).
--define(wxTreebook_SetImageList, 1988).
--define(wxTreebook_SetPageSize, 1989).
--define(wxTreebook_SetPageImage, 1990).
--define(wxTreebook_SetPageText, 1991).
--define(wxTreebook_SetSelection, 1992).
--define(wxTreebook_ChangeSelection, 1993).
--define(wxTreebook_destroy, 1994).
--define(wxTreeCtrl_new_2, 1997).
--define(wxTreeCtrl_new_0, 1998).
--define(wxTreeCtrl_destruct, 2000).
--define(wxTreeCtrl_AddRoot, 2001).
--define(wxTreeCtrl_AppendItem, 2002).
--define(wxTreeCtrl_AssignImageList, 2003).
--define(wxTreeCtrl_AssignStateImageList, 2004).
--define(wxTreeCtrl_Collapse, 2005).
--define(wxTreeCtrl_CollapseAndReset, 2006).
--define(wxTreeCtrl_Create, 2007).
--define(wxTreeCtrl_Delete, 2008).
--define(wxTreeCtrl_DeleteAllItems, 2009).
--define(wxTreeCtrl_DeleteChildren, 2010).
--define(wxTreeCtrl_EnsureVisible, 2011).
--define(wxTreeCtrl_Expand, 2012).
--define(wxTreeCtrl_GetBoundingRect, 2013).
--define(wxTreeCtrl_GetChildrenCount, 2015).
--define(wxTreeCtrl_GetCount, 2016).
--define(wxTreeCtrl_GetEditControl, 2017).
--define(wxTreeCtrl_GetFirstVisibleItem, 2018).
--define(wxTreeCtrl_GetImageList, 2019).
--define(wxTreeCtrl_GetIndent, 2020).
--define(wxTreeCtrl_GetItemBackgroundColour, 2021).
--define(wxTreeCtrl_GetItemData, 2022).
--define(wxTreeCtrl_GetItemFont, 2023).
--define(wxTreeCtrl_GetItemImage_1, 2024).
--define(wxTreeCtrl_GetItemImage_2, 2025).
--define(wxTreeCtrl_GetItemText, 2026).
--define(wxTreeCtrl_GetItemTextColour, 2027).
--define(wxTreeCtrl_GetLastChild, 2028).
--define(wxTreeCtrl_GetNextSibling, 2029).
--define(wxTreeCtrl_GetNextVisible, 2030).
--define(wxTreeCtrl_GetItemParent, 2031).
--define(wxTreeCtrl_GetPrevSibling, 2032).
--define(wxTreeCtrl_GetPrevVisible, 2033).
--define(wxTreeCtrl_GetRootItem, 2034).
--define(wxTreeCtrl_GetSelection, 2035).
--define(wxTreeCtrl_GetSelections, 2036).
--define(wxTreeCtrl_GetStateImageList, 2037).
--define(wxTreeCtrl_HitTest, 2038).
--define(wxTreeCtrl_InsertItem_4_1, 2039).
--define(wxTreeCtrl_InsertItem_4_0, 2040).
--define(wxTreeCtrl_IsBold, 2041).
--define(wxTreeCtrl_IsExpanded, 2042).
--define(wxTreeCtrl_IsSelected, 2043).
--define(wxTreeCtrl_IsVisible, 2044).
--define(wxTreeCtrl_ItemHasChildren, 2045).
--define(wxTreeCtrl_PrependItem, 2046).
--define(wxTreeCtrl_ScrollTo, 2047).
--define(wxTreeCtrl_SelectItem_1, 2048).
--define(wxTreeCtrl_SelectItem_2, 2049).
--define(wxTreeCtrl_SetIndent, 2050).
--define(wxTreeCtrl_SetImageList, 2051).
--define(wxTreeCtrl_SetItemBackgroundColour, 2052).
--define(wxTreeCtrl_SetItemBold, 2053).
--define(wxTreeCtrl_SetItemData, 2054).
--define(wxTreeCtrl_SetItemDropHighlight, 2055).
--define(wxTreeCtrl_SetItemFont, 2056).
--define(wxTreeCtrl_SetItemHasChildren, 2057).
--define(wxTreeCtrl_SetItemImage_2, 2058).
--define(wxTreeCtrl_SetItemImage_3, 2059).
--define(wxTreeCtrl_SetItemText, 2060).
--define(wxTreeCtrl_SetItemTextColour, 2061).
--define(wxTreeCtrl_SetStateImageList, 2062).
--define(wxTreeCtrl_SetWindowStyle, 2063).
--define(wxTreeCtrl_SortChildren, 2064).
--define(wxTreeCtrl_Toggle, 2065).
--define(wxTreeCtrl_ToggleItemSelection, 2066).
--define(wxTreeCtrl_Unselect, 2067).
--define(wxTreeCtrl_UnselectAll, 2068).
--define(wxTreeCtrl_UnselectItem, 2069).
--define(wxScrollBar_new_0, 2070).
--define(wxScrollBar_new_3, 2071).
--define(wxScrollBar_destruct, 2072).
--define(wxScrollBar_Create, 2073).
--define(wxScrollBar_GetRange, 2074).
--define(wxScrollBar_GetPageSize, 2075).
--define(wxScrollBar_GetThumbPosition, 2076).
--define(wxScrollBar_GetThumbSize, 2077).
--define(wxScrollBar_SetThumbPosition, 2078).
--define(wxScrollBar_SetScrollbar, 2079).
--define(wxSpinButton_new_2, 2081).
--define(wxSpinButton_new_0, 2082).
--define(wxSpinButton_Create, 2083).
--define(wxSpinButton_GetMax, 2084).
--define(wxSpinButton_GetMin, 2085).
--define(wxSpinButton_GetValue, 2086).
--define(wxSpinButton_SetRange, 2087).
--define(wxSpinButton_SetValue, 2088).
--define(wxSpinButton_destroy, 2089).
--define(wxSpinCtrl_new_0, 2090).
--define(wxSpinCtrl_new_2, 2091).
--define(wxSpinCtrl_Create, 2093).
--define(wxSpinCtrl_SetValue_1_1, 2096).
--define(wxSpinCtrl_SetValue_1_0, 2097).
--define(wxSpinCtrl_GetValue, 2099).
--define(wxSpinCtrl_SetRange, 2101).
--define(wxSpinCtrl_SetSelection, 2102).
--define(wxSpinCtrl_GetMin, 2104).
--define(wxSpinCtrl_GetMax, 2106).
--define(wxSpinCtrl_destroy, 2107).
--define(wxStaticText_new_0, 2108).
--define(wxStaticText_new_4, 2109).
--define(wxStaticText_Create, 2110).
--define(wxStaticText_GetLabel, 2111).
--define(wxStaticText_SetLabel, 2112).
--define(wxStaticText_Wrap, 2113).
--define(wxStaticText_destroy, 2114).
--define(wxStaticBitmap_new_0, 2115).
--define(wxStaticBitmap_new_4, 2116).
--define(wxStaticBitmap_Create, 2117).
--define(wxStaticBitmap_GetBitmap, 2118).
--define(wxStaticBitmap_SetBitmap, 2119).
--define(wxStaticBitmap_destroy, 2120).
--define(wxRadioBox_new, 2121).
--define(wxRadioBox_destruct, 2123).
--define(wxRadioBox_Create, 2124).
--define(wxRadioBox_Enable_2, 2125).
--define(wxRadioBox_Enable_1, 2126).
--define(wxRadioBox_GetSelection, 2127).
--define(wxRadioBox_GetString, 2128).
--define(wxRadioBox_SetSelection, 2129).
--define(wxRadioBox_Show_2, 2130).
--define(wxRadioBox_Show_1, 2131).
--define(wxRadioBox_GetColumnCount, 2132).
--define(wxRadioBox_GetItemHelpText, 2133).
--define(wxRadioBox_GetItemToolTip, 2134).
--define(wxRadioBox_GetItemFromPoint, 2136).
--define(wxRadioBox_GetRowCount, 2137).
--define(wxRadioBox_IsItemEnabled, 2138).
--define(wxRadioBox_IsItemShown, 2139).
--define(wxRadioBox_SetItemHelpText, 2140).
--define(wxRadioBox_SetItemToolTip, 2141).
--define(wxRadioButton_new_0, 2142).
--define(wxRadioButton_new_4, 2143).
--define(wxRadioButton_Create, 2144).
--define(wxRadioButton_GetValue, 2145).
--define(wxRadioButton_SetValue, 2146).
--define(wxRadioButton_destroy, 2147).
--define(wxSlider_new_6, 2149).
--define(wxSlider_new_0, 2150).
--define(wxSlider_Create, 2151).
--define(wxSlider_GetLineSize, 2152).
--define(wxSlider_GetMax, 2153).
--define(wxSlider_GetMin, 2154).
--define(wxSlider_GetPageSize, 2155).
--define(wxSlider_GetThumbLength, 2156).
--define(wxSlider_GetValue, 2157).
--define(wxSlider_SetLineSize, 2158).
--define(wxSlider_SetPageSize, 2159).
--define(wxSlider_SetRange, 2160).
--define(wxSlider_SetThumbLength, 2161).
--define(wxSlider_SetValue, 2162).
--define(wxSlider_destroy, 2163).
--define(wxDialog_new_4, 2165).
--define(wxDialog_new_0, 2166).
--define(wxDialog_destruct, 2168).
--define(wxDialog_Create, 2169).
--define(wxDialog_CreateButtonSizer, 2170).
--define(wxDialog_CreateStdDialogButtonSizer, 2171).
--define(wxDialog_EndModal, 2172).
--define(wxDialog_GetAffirmativeId, 2173).
--define(wxDialog_GetReturnCode, 2174).
--define(wxDialog_IsModal, 2175).
--define(wxDialog_SetAffirmativeId, 2176).
--define(wxDialog_SetReturnCode, 2177).
--define(wxDialog_Show, 2178).
--define(wxDialog_ShowModal, 2179).
--define(wxColourDialog_new_0, 2180).
--define(wxColourDialog_new_2, 2181).
--define(wxColourDialog_destruct, 2182).
--define(wxColourDialog_Create, 2183).
--define(wxColourDialog_GetColourData, 2184).
--define(wxColourData_new_0, 2185).
--define(wxColourData_new_1, 2186).
--define(wxColourData_destruct, 2187).
--define(wxColourData_GetChooseFull, 2188).
--define(wxColourData_GetColour, 2189).
--define(wxColourData_GetCustomColour, 2191).
--define(wxColourData_SetChooseFull, 2192).
--define(wxColourData_SetColour, 2193).
--define(wxColourData_SetCustomColour, 2194).
--define(wxPalette_new_0, 2195).
--define(wxPalette_new_4, 2196).
--define(wxPalette_destruct, 2198).
--define(wxPalette_Create, 2199).
--define(wxPalette_GetColoursCount, 2200).
--define(wxPalette_GetPixel, 2201).
--define(wxPalette_GetRGB, 2202).
--define(wxPalette_IsOk, 2203).
--define(wxDirDialog_new, 2207).
--define(wxDirDialog_destruct, 2208).
--define(wxDirDialog_GetPath, 2209).
--define(wxDirDialog_GetMessage, 2210).
--define(wxDirDialog_SetMessage, 2211).
--define(wxDirDialog_SetPath, 2212).
--define(wxFileDialog_new, 2216).
--define(wxFileDialog_destruct, 2217).
--define(wxFileDialog_GetDirectory, 2218).
--define(wxFileDialog_GetFilename, 2219).
--define(wxFileDialog_GetFilenames, 2220).
--define(wxFileDialog_GetFilterIndex, 2221).
--define(wxFileDialog_GetMessage, 2222).
--define(wxFileDialog_GetPath, 2223).
--define(wxFileDialog_GetPaths, 2224).
--define(wxFileDialog_GetWildcard, 2225).
--define(wxFileDialog_SetDirectory, 2226).
--define(wxFileDialog_SetFilename, 2227).
--define(wxFileDialog_SetFilterIndex, 2228).
--define(wxFileDialog_SetMessage, 2229).
--define(wxFileDialog_SetPath, 2230).
--define(wxFileDialog_SetWildcard, 2231).
--define(wxPickerBase_SetInternalMargin, 2232).
--define(wxPickerBase_GetInternalMargin, 2233).
--define(wxPickerBase_SetTextCtrlProportion, 2234).
--define(wxPickerBase_SetPickerCtrlProportion, 2235).
--define(wxPickerBase_GetTextCtrlProportion, 2236).
--define(wxPickerBase_GetPickerCtrlProportion, 2237).
--define(wxPickerBase_HasTextCtrl, 2238).
--define(wxPickerBase_GetTextCtrl, 2239).
--define(wxPickerBase_IsTextCtrlGrowable, 2240).
--define(wxPickerBase_SetPickerCtrlGrowable, 2241).
--define(wxPickerBase_SetTextCtrlGrowable, 2242).
--define(wxPickerBase_IsPickerCtrlGrowable, 2243).
--define(wxFilePickerCtrl_new_0, 2244).
--define(wxFilePickerCtrl_new_3, 2245).
--define(wxFilePickerCtrl_Create, 2246).
--define(wxFilePickerCtrl_GetPath, 2247).
--define(wxFilePickerCtrl_SetPath, 2248).
--define(wxFilePickerCtrl_destroy, 2249).
--define(wxDirPickerCtrl_new_0, 2250).
--define(wxDirPickerCtrl_new_3, 2251).
--define(wxDirPickerCtrl_Create, 2252).
--define(wxDirPickerCtrl_GetPath, 2253).
--define(wxDirPickerCtrl_SetPath, 2254).
--define(wxDirPickerCtrl_destroy, 2255).
--define(wxColourPickerCtrl_new_0, 2256).
--define(wxColourPickerCtrl_new_3, 2257).
--define(wxColourPickerCtrl_Create, 2258).
--define(wxColourPickerCtrl_GetColour, 2259).
--define(wxColourPickerCtrl_SetColour_1_1, 2260).
--define(wxColourPickerCtrl_SetColour_1_0, 2261).
--define(wxColourPickerCtrl_destroy, 2262).
--define(wxDatePickerCtrl_new_0, 2263).
--define(wxDatePickerCtrl_new_3, 2264).
--define(wxDatePickerCtrl_GetRange, 2265).
--define(wxDatePickerCtrl_GetValue, 2266).
--define(wxDatePickerCtrl_SetRange, 2267).
--define(wxDatePickerCtrl_SetValue, 2268).
--define(wxDatePickerCtrl_destroy, 2269).
--define(wxFontPickerCtrl_new_0, 2270).
--define(wxFontPickerCtrl_new_3, 2271).
--define(wxFontPickerCtrl_Create, 2272).
--define(wxFontPickerCtrl_GetSelectedFont, 2273).
--define(wxFontPickerCtrl_SetSelectedFont, 2274).
--define(wxFontPickerCtrl_GetMaxPointSize, 2275).
--define(wxFontPickerCtrl_SetMaxPointSize, 2276).
--define(wxFontPickerCtrl_destroy, 2277).
--define(wxFindReplaceDialog_new_0, 2280).
--define(wxFindReplaceDialog_new_4, 2281).
--define(wxFindReplaceDialog_destruct, 2282).
--define(wxFindReplaceDialog_Create, 2283).
--define(wxFindReplaceDialog_GetData, 2284).
--define(wxFindReplaceData_new_0, 2285).
--define(wxFindReplaceData_new_1, 2286).
--define(wxFindReplaceData_GetFindString, 2287).
--define(wxFindReplaceData_GetReplaceString, 2288).
--define(wxFindReplaceData_GetFlags, 2289).
--define(wxFindReplaceData_SetFlags, 2290).
--define(wxFindReplaceData_SetFindString, 2291).
--define(wxFindReplaceData_SetReplaceString, 2292).
--define(wxFindReplaceData_destroy, 2293).
--define(wxMultiChoiceDialog_new_0, 2294).
--define(wxMultiChoiceDialog_new_5, 2296).
--define(wxMultiChoiceDialog_GetSelections, 2297).
--define(wxMultiChoiceDialog_SetSelections, 2298).
--define(wxMultiChoiceDialog_destroy, 2299).
--define(wxSingleChoiceDialog_new_0, 2300).
--define(wxSingleChoiceDialog_new_5, 2302).
--define(wxSingleChoiceDialog_GetSelection, 2303).
--define(wxSingleChoiceDialog_GetStringSelection, 2304).
--define(wxSingleChoiceDialog_SetSelection, 2305).
--define(wxSingleChoiceDialog_destroy, 2306).
--define(wxTextEntryDialog_new, 2307).
--define(wxTextEntryDialog_GetValue, 2308).
--define(wxTextEntryDialog_SetValue, 2309).
--define(wxTextEntryDialog_destroy, 2310).
--define(wxPasswordEntryDialog_new, 2311).
--define(wxPasswordEntryDialog_destroy, 2312).
--define(wxFontData_new_0, 2313).
--define(wxFontData_new_1, 2314).
--define(wxFontData_destruct, 2315).
--define(wxFontData_EnableEffects, 2316).
--define(wxFontData_GetAllowSymbols, 2317).
--define(wxFontData_GetColour, 2318).
--define(wxFontData_GetChosenFont, 2319).
--define(wxFontData_GetEnableEffects, 2320).
--define(wxFontData_GetInitialFont, 2321).
--define(wxFontData_GetShowHelp, 2322).
--define(wxFontData_SetAllowSymbols, 2323).
--define(wxFontData_SetChosenFont, 2324).
--define(wxFontData_SetColour, 2325).
--define(wxFontData_SetInitialFont, 2326).
--define(wxFontData_SetRange, 2327).
--define(wxFontData_SetShowHelp, 2328).
--define(wxFontDialog_new_0, 2332).
--define(wxFontDialog_new_2, 2334).
--define(wxFontDialog_Create, 2336).
--define(wxFontDialog_GetFontData, 2337).
--define(wxFontDialog_destroy, 2339).
--define(wxProgressDialog_new, 2340).
--define(wxProgressDialog_destruct, 2341).
--define(wxProgressDialog_Resume, 2342).
--define(wxProgressDialog_Update_2, 2343).
--define(wxProgressDialog_Update_0, 2344).
--define(wxMessageDialog_new, 2345).
--define(wxMessageDialog_destruct, 2346).
--define(wxPageSetupDialog_new, 2347).
--define(wxPageSetupDialog_destruct, 2348).
--define(wxPageSetupDialog_GetPageSetupData, 2349).
--define(wxPageSetupDialog_ShowModal, 2350).
--define(wxPageSetupDialogData_new_0, 2351).
--define(wxPageSetupDialogData_new_1_0, 2352).
--define(wxPageSetupDialogData_new_1_1, 2353).
--define(wxPageSetupDialogData_destruct, 2354).
--define(wxPageSetupDialogData_EnableHelp, 2355).
--define(wxPageSetupDialogData_EnableMargins, 2356).
--define(wxPageSetupDialogData_EnableOrientation, 2357).
--define(wxPageSetupDialogData_EnablePaper, 2358).
--define(wxPageSetupDialogData_EnablePrinter, 2359).
--define(wxPageSetupDialogData_GetDefaultMinMargins, 2360).
--define(wxPageSetupDialogData_GetEnableMargins, 2361).
--define(wxPageSetupDialogData_GetEnableOrientation, 2362).
--define(wxPageSetupDialogData_GetEnablePaper, 2363).
--define(wxPageSetupDialogData_GetEnablePrinter, 2364).
--define(wxPageSetupDialogData_GetEnableHelp, 2365).
--define(wxPageSetupDialogData_GetDefaultInfo, 2366).
--define(wxPageSetupDialogData_GetMarginTopLeft, 2367).
--define(wxPageSetupDialogData_GetMarginBottomRight, 2368).
--define(wxPageSetupDialogData_GetMinMarginTopLeft, 2369).
--define(wxPageSetupDialogData_GetMinMarginBottomRight, 2370).
--define(wxPageSetupDialogData_GetPaperId, 2371).
--define(wxPageSetupDialogData_GetPaperSize, 2372).
--define(wxPageSetupDialogData_GetPrintData, 2374).
--define(wxPageSetupDialogData_IsOk, 2375).
--define(wxPageSetupDialogData_SetDefaultInfo, 2376).
--define(wxPageSetupDialogData_SetDefaultMinMargins, 2377).
--define(wxPageSetupDialogData_SetMarginTopLeft, 2378).
--define(wxPageSetupDialogData_SetMarginBottomRight, 2379).
--define(wxPageSetupDialogData_SetMinMarginTopLeft, 2380).
--define(wxPageSetupDialogData_SetMinMarginBottomRight, 2381).
--define(wxPageSetupDialogData_SetPaperId, 2382).
--define(wxPageSetupDialogData_SetPaperSize_1_1, 2383).
--define(wxPageSetupDialogData_SetPaperSize_1_0, 2384).
--define(wxPageSetupDialogData_SetPrintData, 2385).
--define(wxPrintDialog_new_2_0, 2386).
--define(wxPrintDialog_new_2_1, 2387).
--define(wxPrintDialog_destruct, 2388).
--define(wxPrintDialog_GetPrintDialogData, 2389).
--define(wxPrintDialog_GetPrintDC, 2390).
--define(wxPrintDialogData_new_0, 2391).
--define(wxPrintDialogData_new_1_1, 2392).
--define(wxPrintDialogData_new_1_0, 2393).
--define(wxPrintDialogData_destruct, 2394).
--define(wxPrintDialogData_EnableHelp, 2395).
--define(wxPrintDialogData_EnablePageNumbers, 2396).
--define(wxPrintDialogData_EnablePrintToFile, 2397).
--define(wxPrintDialogData_EnableSelection, 2398).
--define(wxPrintDialogData_GetAllPages, 2399).
--define(wxPrintDialogData_GetCollate, 2400).
--define(wxPrintDialogData_GetFromPage, 2401).
--define(wxPrintDialogData_GetMaxPage, 2402).
--define(wxPrintDialogData_GetMinPage, 2403).
--define(wxPrintDialogData_GetNoCopies, 2404).
--define(wxPrintDialogData_GetPrintData, 2405).
--define(wxPrintDialogData_GetPrintToFile, 2406).
--define(wxPrintDialogData_GetSelection, 2407).
--define(wxPrintDialogData_GetToPage, 2408).
--define(wxPrintDialogData_IsOk, 2409).
--define(wxPrintDialogData_SetCollate, 2410).
--define(wxPrintDialogData_SetFromPage, 2411).
--define(wxPrintDialogData_SetMaxPage, 2412).
--define(wxPrintDialogData_SetMinPage, 2413).
--define(wxPrintDialogData_SetNoCopies, 2414).
--define(wxPrintDialogData_SetPrintData, 2415).
--define(wxPrintDialogData_SetPrintToFile, 2416).
--define(wxPrintDialogData_SetSelection, 2417).
--define(wxPrintDialogData_SetToPage, 2418).
--define(wxPrintData_new_0, 2419).
--define(wxPrintData_new_1, 2420).
--define(wxPrintData_destruct, 2421).
--define(wxPrintData_GetCollate, 2422).
--define(wxPrintData_GetBin, 2423).
--define(wxPrintData_GetColour, 2424).
--define(wxPrintData_GetDuplex, 2425).
--define(wxPrintData_GetNoCopies, 2426).
--define(wxPrintData_GetOrientation, 2427).
--define(wxPrintData_GetPaperId, 2428).
--define(wxPrintData_GetPrinterName, 2429).
--define(wxPrintData_GetQuality, 2430).
--define(wxPrintData_IsOk, 2431).
--define(wxPrintData_SetBin, 2432).
--define(wxPrintData_SetCollate, 2433).
--define(wxPrintData_SetColour, 2434).
--define(wxPrintData_SetDuplex, 2435).
--define(wxPrintData_SetNoCopies, 2436).
--define(wxPrintData_SetOrientation, 2437).
--define(wxPrintData_SetPaperId, 2438).
--define(wxPrintData_SetPrinterName, 2439).
--define(wxPrintData_SetQuality, 2440).
--define(wxPrintPreview_new_2, 2443).
--define(wxPrintPreview_new_3, 2444).
--define(wxPrintPreview_destruct, 2446).
--define(wxPrintPreview_GetCanvas, 2447).
--define(wxPrintPreview_GetCurrentPage, 2448).
--define(wxPrintPreview_GetFrame, 2449).
--define(wxPrintPreview_GetMaxPage, 2450).
--define(wxPrintPreview_GetMinPage, 2451).
--define(wxPrintPreview_GetPrintout, 2452).
--define(wxPrintPreview_GetPrintoutForPrinting, 2453).
--define(wxPrintPreview_IsOk, 2454).
--define(wxPrintPreview_PaintPage, 2455).
--define(wxPrintPreview_Print, 2456).
--define(wxPrintPreview_RenderPage, 2457).
--define(wxPrintPreview_SetCanvas, 2458).
--define(wxPrintPreview_SetCurrentPage, 2459).
--define(wxPrintPreview_SetFrame, 2460).
--define(wxPrintPreview_SetPrintout, 2461).
--define(wxPrintPreview_SetZoom, 2462).
--define(wxPreviewFrame_new, 2463).
--define(wxPreviewFrame_destruct, 2464).
--define(wxPreviewFrame_CreateControlBar, 2465).
--define(wxPreviewFrame_CreateCanvas, 2466).
--define(wxPreviewFrame_Initialize, 2467).
--define(wxPreviewFrame_OnCloseWindow, 2468).
--define(wxPreviewControlBar_new, 2469).
--define(wxPreviewControlBar_destruct, 2470).
--define(wxPreviewControlBar_CreateButtons, 2471).
--define(wxPreviewControlBar_GetPrintPreview, 2472).
--define(wxPreviewControlBar_GetZoomControl, 2473).
--define(wxPreviewControlBar_SetZoomControl, 2474).
--define(wxPrinter_new, 2476).
--define(wxPrinter_CreateAbortWindow, 2477).
--define(wxPrinter_GetAbort, 2478).
--define(wxPrinter_GetLastError, 2479).
--define(wxPrinter_GetPrintDialogData, 2480).
--define(wxPrinter_Print, 2481).
--define(wxPrinter_PrintDialog, 2482).
--define(wxPrinter_ReportError, 2483).
--define(wxPrinter_Setup, 2484).
--define(wxPrinter_destroy, 2485).
--define(wxXmlResource_new_1, 2486).
--define(wxXmlResource_new_2, 2487).
--define(wxXmlResource_destruct, 2488).
--define(wxXmlResource_AttachUnknownControl, 2489).
--define(wxXmlResource_ClearHandlers, 2490).
--define(wxXmlResource_CompareVersion, 2491).
--define(wxXmlResource_Get, 2492).
--define(wxXmlResource_GetFlags, 2493).
--define(wxXmlResource_GetVersion, 2494).
--define(wxXmlResource_GetXRCID, 2495).
--define(wxXmlResource_InitAllHandlers, 2496).
--define(wxXmlResource_Load, 2497).
--define(wxXmlResource_LoadBitmap, 2498).
--define(wxXmlResource_LoadDialog_2, 2499).
--define(wxXmlResource_LoadDialog_3, 2500).
--define(wxXmlResource_LoadFrame_2, 2501).
--define(wxXmlResource_LoadFrame_3, 2502).
--define(wxXmlResource_LoadIcon, 2503).
--define(wxXmlResource_LoadMenu, 2504).
--define(wxXmlResource_LoadMenuBar_2, 2505).
--define(wxXmlResource_LoadMenuBar_1, 2506).
--define(wxXmlResource_LoadPanel_2, 2507).
--define(wxXmlResource_LoadPanel_3, 2508).
--define(wxXmlResource_LoadToolBar, 2509).
--define(wxXmlResource_Set, 2510).
--define(wxXmlResource_SetFlags, 2511).
--define(wxXmlResource_Unload, 2512).
--define(wxXmlResource_xrcctrl, 2513).
--define(wxHtmlEasyPrinting_new, 2514).
--define(wxHtmlEasyPrinting_destruct, 2515).
--define(wxHtmlEasyPrinting_GetPrintData, 2516).
--define(wxHtmlEasyPrinting_GetPageSetupData, 2517).
--define(wxHtmlEasyPrinting_PreviewFile, 2518).
--define(wxHtmlEasyPrinting_PreviewText, 2519).
--define(wxHtmlEasyPrinting_PrintFile, 2520).
--define(wxHtmlEasyPrinting_PrintText, 2521).
--define(wxHtmlEasyPrinting_PageSetup, 2522).
--define(wxHtmlEasyPrinting_SetFonts, 2523).
--define(wxHtmlEasyPrinting_SetHeader, 2524).
--define(wxHtmlEasyPrinting_SetFooter, 2525).
--define(wxGLCanvas_new_2, 2527).
--define(wxGLCanvas_new_3_1, 2528).
--define(wxGLCanvas_new_3_0, 2529).
--define(wxGLCanvas_GetContext, 2530).
--define(wxGLCanvas_SetCurrent, 2532).
--define(wxGLCanvas_SwapBuffers, 2533).
--define(wxGLCanvas_destroy, 2534).
--define(wxAuiManager_new, 2535).
--define(wxAuiManager_destruct, 2536).
--define(wxAuiManager_AddPane_2_1, 2537).
--define(wxAuiManager_AddPane_3, 2538).
--define(wxAuiManager_AddPane_2_0, 2539).
--define(wxAuiManager_DetachPane, 2540).
--define(wxAuiManager_GetAllPanes, 2541).
--define(wxAuiManager_GetArtProvider, 2542).
--define(wxAuiManager_GetDockSizeConstraint, 2543).
--define(wxAuiManager_GetFlags, 2544).
--define(wxAuiManager_GetManagedWindow, 2545).
--define(wxAuiManager_GetManager, 2546).
--define(wxAuiManager_GetPane_1_1, 2547).
--define(wxAuiManager_GetPane_1_0, 2548).
--define(wxAuiManager_HideHint, 2549).
--define(wxAuiManager_InsertPane, 2550).
--define(wxAuiManager_LoadPaneInfo, 2551).
--define(wxAuiManager_LoadPerspective, 2552).
--define(wxAuiManager_SavePaneInfo, 2553).
--define(wxAuiManager_SavePerspective, 2554).
--define(wxAuiManager_SetArtProvider, 2555).
--define(wxAuiManager_SetDockSizeConstraint, 2556).
--define(wxAuiManager_SetFlags, 2557).
--define(wxAuiManager_SetManagedWindow, 2558).
--define(wxAuiManager_ShowHint, 2559).
--define(wxAuiManager_UnInit, 2560).
--define(wxAuiManager_Update, 2561).
--define(wxAuiPaneInfo_new_0, 2562).
--define(wxAuiPaneInfo_new_1, 2563).
--define(wxAuiPaneInfo_destruct, 2564).
--define(wxAuiPaneInfo_BestSize_1, 2565).
--define(wxAuiPaneInfo_BestSize_2, 2566).
--define(wxAuiPaneInfo_Bottom, 2567).
--define(wxAuiPaneInfo_BottomDockable, 2568).
--define(wxAuiPaneInfo_Caption, 2569).
--define(wxAuiPaneInfo_CaptionVisible, 2570).
--define(wxAuiPaneInfo_Centre, 2571).
--define(wxAuiPaneInfo_CentrePane, 2572).
--define(wxAuiPaneInfo_CloseButton, 2573).
--define(wxAuiPaneInfo_DefaultPane, 2574).
--define(wxAuiPaneInfo_DestroyOnClose, 2575).
--define(wxAuiPaneInfo_Direction, 2576).
--define(wxAuiPaneInfo_Dock, 2577).
--define(wxAuiPaneInfo_Dockable, 2578).
--define(wxAuiPaneInfo_Fixed, 2579).
--define(wxAuiPaneInfo_Float, 2580).
--define(wxAuiPaneInfo_Floatable, 2581).
--define(wxAuiPaneInfo_FloatingPosition_1, 2582).
--define(wxAuiPaneInfo_FloatingPosition_2, 2583).
--define(wxAuiPaneInfo_FloatingSize_1, 2584).
--define(wxAuiPaneInfo_FloatingSize_2, 2585).
--define(wxAuiPaneInfo_Gripper, 2586).
--define(wxAuiPaneInfo_GripperTop, 2587).
--define(wxAuiPaneInfo_HasBorder, 2588).
--define(wxAuiPaneInfo_HasCaption, 2589).
--define(wxAuiPaneInfo_HasCloseButton, 2590).
--define(wxAuiPaneInfo_HasFlag, 2591).
--define(wxAuiPaneInfo_HasGripper, 2592).
--define(wxAuiPaneInfo_HasGripperTop, 2593).
--define(wxAuiPaneInfo_HasMaximizeButton, 2594).
--define(wxAuiPaneInfo_HasMinimizeButton, 2595).
--define(wxAuiPaneInfo_HasPinButton, 2596).
--define(wxAuiPaneInfo_Hide, 2597).
--define(wxAuiPaneInfo_IsBottomDockable, 2598).
--define(wxAuiPaneInfo_IsDocked, 2599).
--define(wxAuiPaneInfo_IsFixed, 2600).
--define(wxAuiPaneInfo_IsFloatable, 2601).
--define(wxAuiPaneInfo_IsFloating, 2602).
--define(wxAuiPaneInfo_IsLeftDockable, 2603).
--define(wxAuiPaneInfo_IsMovable, 2604).
--define(wxAuiPaneInfo_IsOk, 2605).
--define(wxAuiPaneInfo_IsResizable, 2606).
--define(wxAuiPaneInfo_IsRightDockable, 2607).
--define(wxAuiPaneInfo_IsShown, 2608).
--define(wxAuiPaneInfo_IsToolbar, 2609).
--define(wxAuiPaneInfo_IsTopDockable, 2610).
--define(wxAuiPaneInfo_Layer, 2611).
--define(wxAuiPaneInfo_Left, 2612).
--define(wxAuiPaneInfo_LeftDockable, 2613).
--define(wxAuiPaneInfo_MaxSize_1, 2614).
--define(wxAuiPaneInfo_MaxSize_2, 2615).
--define(wxAuiPaneInfo_MaximizeButton, 2616).
--define(wxAuiPaneInfo_MinSize_1, 2617).
--define(wxAuiPaneInfo_MinSize_2, 2618).
--define(wxAuiPaneInfo_MinimizeButton, 2619).
--define(wxAuiPaneInfo_Movable, 2620).
--define(wxAuiPaneInfo_Name, 2621).
--define(wxAuiPaneInfo_PaneBorder, 2622).
--define(wxAuiPaneInfo_PinButton, 2623).
--define(wxAuiPaneInfo_Position, 2624).
--define(wxAuiPaneInfo_Resizable, 2625).
--define(wxAuiPaneInfo_Right, 2626).
--define(wxAuiPaneInfo_RightDockable, 2627).
--define(wxAuiPaneInfo_Row, 2628).
--define(wxAuiPaneInfo_SafeSet, 2629).
--define(wxAuiPaneInfo_SetFlag, 2630).
--define(wxAuiPaneInfo_Show, 2631).
--define(wxAuiPaneInfo_ToolbarPane, 2632).
--define(wxAuiPaneInfo_Top, 2633).
--define(wxAuiPaneInfo_TopDockable, 2634).
--define(wxAuiPaneInfo_Window, 2635).
--define(wxAuiNotebook_new_0, 2636).
--define(wxAuiNotebook_new_2, 2637).
--define(wxAuiNotebook_AddPage, 2638).
--define(wxAuiNotebook_Create, 2639).
--define(wxAuiNotebook_DeletePage, 2640).
--define(wxAuiNotebook_GetArtProvider, 2641).
--define(wxAuiNotebook_GetPage, 2642).
--define(wxAuiNotebook_GetPageBitmap, 2643).
--define(wxAuiNotebook_GetPageCount, 2644).
--define(wxAuiNotebook_GetPageIndex, 2645).
--define(wxAuiNotebook_GetPageText, 2646).
--define(wxAuiNotebook_GetSelection, 2647).
--define(wxAuiNotebook_InsertPage, 2648).
--define(wxAuiNotebook_RemovePage, 2649).
--define(wxAuiNotebook_SetArtProvider, 2650).
--define(wxAuiNotebook_SetFont, 2651).
--define(wxAuiNotebook_SetPageBitmap, 2652).
--define(wxAuiNotebook_SetPageText, 2653).
--define(wxAuiNotebook_SetSelection, 2654).
--define(wxAuiNotebook_SetTabCtrlHeight, 2655).
--define(wxAuiNotebook_SetUniformBitmapSize, 2656).
--define(wxAuiNotebook_destroy, 2657).
--define(wxMDIParentFrame_new_0, 2658).
--define(wxMDIParentFrame_new_4, 2659).
--define(wxMDIParentFrame_destruct, 2660).
--define(wxMDIParentFrame_ActivateNext, 2661).
--define(wxMDIParentFrame_ActivatePrevious, 2662).
--define(wxMDIParentFrame_ArrangeIcons, 2663).
--define(wxMDIParentFrame_Cascade, 2664).
--define(wxMDIParentFrame_Create, 2665).
--define(wxMDIParentFrame_GetActiveChild, 2666).
--define(wxMDIParentFrame_GetClientWindow, 2667).
--define(wxMDIParentFrame_Tile, 2668).
--define(wxMDIChildFrame_new_0, 2669).
--define(wxMDIChildFrame_new_4, 2670).
--define(wxMDIChildFrame_destruct, 2671).
--define(wxMDIChildFrame_Activate, 2672).
--define(wxMDIChildFrame_Create, 2673).
--define(wxMDIChildFrame_Maximize, 2674).
--define(wxMDIChildFrame_Restore, 2675).
--define(wxMDIClientWindow_new_0, 2676).
--define(wxMDIClientWindow_new_2, 2677).
--define(wxMDIClientWindow_destruct, 2678).
--define(wxMDIClientWindow_CreateClient, 2679).
--define(wxLayoutAlgorithm_new, 2680).
--define(wxLayoutAlgorithm_LayoutFrame, 2681).
--define(wxLayoutAlgorithm_LayoutMDIFrame, 2682).
--define(wxLayoutAlgorithm_LayoutWindow, 2683).
--define(wxLayoutAlgorithm_destroy, 2684).
--define(wxEvent_GetId, 2685).
--define(wxEvent_GetSkipped, 2686).
--define(wxEvent_GetTimestamp, 2687).
--define(wxEvent_IsCommandEvent, 2688).
--define(wxEvent_ResumePropagation, 2689).
--define(wxEvent_ShouldPropagate, 2690).
--define(wxEvent_Skip, 2691).
--define(wxEvent_StopPropagation, 2692).
--define(wxCommandEvent_getClientData, 2693).
--define(wxCommandEvent_GetExtraLong, 2694).
--define(wxCommandEvent_GetInt, 2695).
--define(wxCommandEvent_GetSelection, 2696).
--define(wxCommandEvent_GetString, 2697).
--define(wxCommandEvent_IsChecked, 2698).
--define(wxCommandEvent_IsSelection, 2699).
--define(wxCommandEvent_SetInt, 2700).
--define(wxCommandEvent_SetString, 2701).
--define(wxScrollEvent_GetOrientation, 2702).
--define(wxScrollEvent_GetPosition, 2703).
--define(wxScrollWinEvent_GetOrientation, 2704).
--define(wxScrollWinEvent_GetPosition, 2705).
--define(wxMouseEvent_AltDown, 2706).
--define(wxMouseEvent_Button, 2707).
--define(wxMouseEvent_ButtonDClick, 2708).
--define(wxMouseEvent_ButtonDown, 2709).
--define(wxMouseEvent_ButtonUp, 2710).
--define(wxMouseEvent_CmdDown, 2711).
--define(wxMouseEvent_ControlDown, 2712).
--define(wxMouseEvent_Dragging, 2713).
--define(wxMouseEvent_Entering, 2714).
--define(wxMouseEvent_GetButton, 2715).
--define(wxMouseEvent_GetPosition, 2718).
--define(wxMouseEvent_GetLogicalPosition, 2719).
--define(wxMouseEvent_GetLinesPerAction, 2720).
--define(wxMouseEvent_GetWheelRotation, 2721).
--define(wxMouseEvent_GetWheelDelta, 2722).
--define(wxMouseEvent_GetX, 2723).
--define(wxMouseEvent_GetY, 2724).
--define(wxMouseEvent_IsButton, 2725).
--define(wxMouseEvent_IsPageScroll, 2726).
--define(wxMouseEvent_Leaving, 2727).
--define(wxMouseEvent_LeftDClick, 2728).
--define(wxMouseEvent_LeftDown, 2729).
--define(wxMouseEvent_LeftIsDown, 2730).
--define(wxMouseEvent_LeftUp, 2731).
--define(wxMouseEvent_MetaDown, 2732).
--define(wxMouseEvent_MiddleDClick, 2733).
--define(wxMouseEvent_MiddleDown, 2734).
--define(wxMouseEvent_MiddleIsDown, 2735).
--define(wxMouseEvent_MiddleUp, 2736).
--define(wxMouseEvent_Moving, 2737).
--define(wxMouseEvent_RightDClick, 2738).
--define(wxMouseEvent_RightDown, 2739).
--define(wxMouseEvent_RightIsDown, 2740).
--define(wxMouseEvent_RightUp, 2741).
--define(wxMouseEvent_ShiftDown, 2742).
--define(wxSetCursorEvent_GetCursor, 2743).
--define(wxSetCursorEvent_GetX, 2744).
--define(wxSetCursorEvent_GetY, 2745).
--define(wxSetCursorEvent_HasCursor, 2746).
--define(wxSetCursorEvent_SetCursor, 2747).
--define(wxKeyEvent_AltDown, 2748).
--define(wxKeyEvent_CmdDown, 2749).
--define(wxKeyEvent_ControlDown, 2750).
--define(wxKeyEvent_GetKeyCode, 2751).
--define(wxKeyEvent_GetModifiers, 2752).
--define(wxKeyEvent_GetPosition, 2755).
--define(wxKeyEvent_GetRawKeyCode, 2756).
--define(wxKeyEvent_GetRawKeyFlags, 2757).
--define(wxKeyEvent_GetUnicodeKey, 2758).
--define(wxKeyEvent_GetX, 2759).
--define(wxKeyEvent_GetY, 2760).
--define(wxKeyEvent_HasModifiers, 2761).
--define(wxKeyEvent_MetaDown, 2762).
--define(wxKeyEvent_ShiftDown, 2763).
--define(wxSizeEvent_GetSize, 2764).
--define(wxMoveEvent_GetPosition, 2765).
--define(wxEraseEvent_GetDC, 2766).
--define(wxFocusEvent_GetWindow, 2767).
--define(wxChildFocusEvent_GetWindow, 2768).
--define(wxMenuEvent_GetMenu, 2769).
--define(wxMenuEvent_GetMenuId, 2770).
--define(wxMenuEvent_IsPopup, 2771).
--define(wxCloseEvent_CanVeto, 2772).
--define(wxCloseEvent_GetLoggingOff, 2773).
--define(wxCloseEvent_SetCanVeto, 2774).
--define(wxCloseEvent_SetLoggingOff, 2775).
--define(wxCloseEvent_Veto, 2776).
--define(wxShowEvent_SetShow, 2777).
--define(wxShowEvent_GetShow, 2778).
--define(wxIconizeEvent_Iconized, 2779).
--define(wxJoystickEvent_ButtonDown, 2780).
--define(wxJoystickEvent_ButtonIsDown, 2781).
--define(wxJoystickEvent_ButtonUp, 2782).
--define(wxJoystickEvent_GetButtonChange, 2783).
--define(wxJoystickEvent_GetButtonState, 2784).
--define(wxJoystickEvent_GetJoystick, 2785).
--define(wxJoystickEvent_GetPosition, 2786).
--define(wxJoystickEvent_GetZPosition, 2787).
--define(wxJoystickEvent_IsButton, 2788).
--define(wxJoystickEvent_IsMove, 2789).
--define(wxJoystickEvent_IsZMove, 2790).
--define(wxUpdateUIEvent_CanUpdate, 2791).
--define(wxUpdateUIEvent_Check, 2792).
--define(wxUpdateUIEvent_Enable, 2793).
--define(wxUpdateUIEvent_Show, 2794).
--define(wxUpdateUIEvent_GetChecked, 2795).
--define(wxUpdateUIEvent_GetEnabled, 2796).
--define(wxUpdateUIEvent_GetShown, 2797).
--define(wxUpdateUIEvent_GetSetChecked, 2798).
--define(wxUpdateUIEvent_GetSetEnabled, 2799).
--define(wxUpdateUIEvent_GetSetShown, 2800).
--define(wxUpdateUIEvent_GetSetText, 2801).
--define(wxUpdateUIEvent_GetText, 2802).
--define(wxUpdateUIEvent_GetMode, 2803).
--define(wxUpdateUIEvent_GetUpdateInterval, 2804).
--define(wxUpdateUIEvent_ResetUpdateTime, 2805).
--define(wxUpdateUIEvent_SetMode, 2806).
--define(wxUpdateUIEvent_SetText, 2807).
--define(wxUpdateUIEvent_SetUpdateInterval, 2808).
--define(wxMouseCaptureChangedEvent_GetCapturedWindow, 2809).
--define(wxPaletteChangedEvent_SetChangedWindow, 2810).
--define(wxPaletteChangedEvent_GetChangedWindow, 2811).
--define(wxQueryNewPaletteEvent_SetPaletteRealized, 2812).
--define(wxQueryNewPaletteEvent_GetPaletteRealized, 2813).
--define(wxNavigationKeyEvent_GetDirection, 2814).
--define(wxNavigationKeyEvent_SetDirection, 2815).
--define(wxNavigationKeyEvent_IsWindowChange, 2816).
--define(wxNavigationKeyEvent_SetWindowChange, 2817).
--define(wxNavigationKeyEvent_IsFromTab, 2818).
--define(wxNavigationKeyEvent_SetFromTab, 2819).
--define(wxNavigationKeyEvent_GetCurrentFocus, 2820).
--define(wxNavigationKeyEvent_SetCurrentFocus, 2821).
--define(wxHelpEvent_GetOrigin, 2822).
--define(wxHelpEvent_GetPosition, 2823).
--define(wxHelpEvent_SetOrigin, 2824).
--define(wxHelpEvent_SetPosition, 2825).
--define(wxContextMenuEvent_GetPosition, 2826).
--define(wxContextMenuEvent_SetPosition, 2827).
--define(wxIdleEvent_CanSend, 2828).
--define(wxIdleEvent_GetMode, 2829).
--define(wxIdleEvent_RequestMore, 2830).
--define(wxIdleEvent_MoreRequested, 2831).
--define(wxIdleEvent_SetMode, 2832).
--define(wxGridEvent_AltDown, 2833).
--define(wxGridEvent_ControlDown, 2834).
--define(wxGridEvent_GetCol, 2835).
--define(wxGridEvent_GetPosition, 2836).
--define(wxGridEvent_GetRow, 2837).
--define(wxGridEvent_MetaDown, 2838).
--define(wxGridEvent_Selecting, 2839).
--define(wxGridEvent_ShiftDown, 2840).
--define(wxNotifyEvent_Allow, 2841).
--define(wxNotifyEvent_IsAllowed, 2842).
--define(wxNotifyEvent_Veto, 2843).
--define(wxSashEvent_GetEdge, 2844).
--define(wxSashEvent_GetDragRect, 2845).
--define(wxSashEvent_GetDragStatus, 2846).
--define(wxListEvent_GetCacheFrom, 2847).
--define(wxListEvent_GetCacheTo, 2848).
--define(wxListEvent_GetKeyCode, 2849).
--define(wxListEvent_GetIndex, 2850).
--define(wxListEvent_GetColumn, 2851).
--define(wxListEvent_GetPoint, 2852).
--define(wxListEvent_GetLabel, 2853).
--define(wxListEvent_GetText, 2854).
--define(wxListEvent_GetImage, 2855).
--define(wxListEvent_GetData, 2856).
--define(wxListEvent_GetMask, 2857).
--define(wxListEvent_GetItem, 2858).
--define(wxListEvent_IsEditCancelled, 2859).
--define(wxDateEvent_GetDate, 2860).
--define(wxCalendarEvent_GetWeekDay, 2861).
--define(wxFileDirPickerEvent_GetPath, 2862).
--define(wxColourPickerEvent_GetColour, 2863).
--define(wxFontPickerEvent_GetFont, 2864).
--define(wxStyledTextEvent_GetPosition, 2865).
--define(wxStyledTextEvent_GetKey, 2866).
--define(wxStyledTextEvent_GetModifiers, 2867).
--define(wxStyledTextEvent_GetModificationType, 2868).
--define(wxStyledTextEvent_GetText, 2869).
--define(wxStyledTextEvent_GetLength, 2870).
--define(wxStyledTextEvent_GetLinesAdded, 2871).
--define(wxStyledTextEvent_GetLine, 2872).
--define(wxStyledTextEvent_GetFoldLevelNow, 2873).
--define(wxStyledTextEvent_GetFoldLevelPrev, 2874).
--define(wxStyledTextEvent_GetMargin, 2875).
--define(wxStyledTextEvent_GetMessage, 2876).
--define(wxStyledTextEvent_GetWParam, 2877).
--define(wxStyledTextEvent_GetLParam, 2878).
--define(wxStyledTextEvent_GetListType, 2879).
--define(wxStyledTextEvent_GetX, 2880).
--define(wxStyledTextEvent_GetY, 2881).
--define(wxStyledTextEvent_GetDragText, 2882).
--define(wxStyledTextEvent_GetDragAllowMove, 2883).
--define(wxStyledTextEvent_GetDragResult, 2884).
--define(wxStyledTextEvent_GetShift, 2885).
--define(wxStyledTextEvent_GetControl, 2886).
--define(wxStyledTextEvent_GetAlt, 2887).
--define(utils_wxGetKeyState, 2888).
--define(utils_wxGetMousePosition, 2889).
--define(utils_wxGetMouseState, 2890).
--define(utils_wxSetDetectableAutoRepeat, 2891).
--define(utils_wxBell, 2892).
--define(utils_wxFindMenuItemId, 2893).
--define(utils_wxGenericFindWindowAtPoint, 2894).
--define(utils_wxFindWindowAtPoint, 2895).
--define(utils_wxBeginBusyCursor, 2896).
--define(utils_wxEndBusyCursor, 2897).
--define(utils_wxIsBusy, 2898).
--define(utils_wxShutdown, 2899).
--define(utils_wxShell, 2900).
--define(utils_wxLaunchDefaultBrowser, 2901).
--define(utils_wxGetEmailAddress, 2902).
--define(utils_wxGetUserId, 2903).
--define(utils_wxGetHomeDir, 2904).
--define(utils_wxNewId, 2905).
--define(utils_wxRegisterId, 2906).
--define(utils_wxGetCurrentId, 2907).
--define(utils_wxGetOsDescription, 2908).
--define(utils_wxIsPlatformLittleEndian, 2909).
--define(utils_wxIsPlatform64Bit, 2910).
--define(wxPrintout_new, 2911).
--define(wxPrintout_destruct, 2912).
--define(wxPrintout_GetDC, 2913).
--define(wxPrintout_GetPageSizeMM, 2914).
--define(wxPrintout_GetPageSizePixels, 2915).
--define(wxPrintout_GetPaperRectPixels, 2916).
--define(wxPrintout_GetPPIPrinter, 2917).
--define(wxPrintout_GetPPIScreen, 2918).
--define(wxPrintout_GetTitle, 2919).
--define(wxPrintout_IsPreview, 2920).
--define(wxPrintout_FitThisSizeToPaper, 2921).
--define(wxPrintout_FitThisSizeToPage, 2922).
--define(wxPrintout_FitThisSizeToPageMargins, 2923).
--define(wxPrintout_MapScreenSizeToPaper, 2924).
--define(wxPrintout_MapScreenSizeToPage, 2925).
--define(wxPrintout_MapScreenSizeToPageMargins, 2926).
--define(wxPrintout_MapScreenSizeToDevice, 2927).
--define(wxPrintout_GetLogicalPaperRect, 2928).
--define(wxPrintout_GetLogicalPageRect, 2929).
--define(wxPrintout_GetLogicalPageMarginsRect, 2930).
--define(wxPrintout_SetLogicalOrigin, 2931).
--define(wxPrintout_OffsetLogicalOrigin, 2932).
--define(wxStyledTextCtrl_new_2, 2933).
--define(wxStyledTextCtrl_new_0, 2934).
--define(wxStyledTextCtrl_destruct, 2935).
--define(wxStyledTextCtrl_Create, 2936).
--define(wxStyledTextCtrl_AddText, 2937).
--define(wxStyledTextCtrl_AddStyledText, 2938).
--define(wxStyledTextCtrl_InsertText, 2939).
--define(wxStyledTextCtrl_ClearAll, 2940).
--define(wxStyledTextCtrl_ClearDocumentStyle, 2941).
--define(wxStyledTextCtrl_GetLength, 2942).
--define(wxStyledTextCtrl_GetCharAt, 2943).
--define(wxStyledTextCtrl_GetCurrentPos, 2944).
--define(wxStyledTextCtrl_GetAnchor, 2945).
--define(wxStyledTextCtrl_GetStyleAt, 2946).
--define(wxStyledTextCtrl_Redo, 2947).
--define(wxStyledTextCtrl_SetUndoCollection, 2948).
--define(wxStyledTextCtrl_SelectAll, 2949).
--define(wxStyledTextCtrl_SetSavePoint, 2950).
--define(wxStyledTextCtrl_GetStyledText, 2951).
--define(wxStyledTextCtrl_CanRedo, 2952).
--define(wxStyledTextCtrl_MarkerLineFromHandle, 2953).
--define(wxStyledTextCtrl_MarkerDeleteHandle, 2954).
--define(wxStyledTextCtrl_GetUndoCollection, 2955).
--define(wxStyledTextCtrl_GetViewWhiteSpace, 2956).
--define(wxStyledTextCtrl_SetViewWhiteSpace, 2957).
--define(wxStyledTextCtrl_PositionFromPoint, 2958).
--define(wxStyledTextCtrl_PositionFromPointClose, 2959).
--define(wxStyledTextCtrl_GotoLine, 2960).
--define(wxStyledTextCtrl_GotoPos, 2961).
--define(wxStyledTextCtrl_SetAnchor, 2962).
--define(wxStyledTextCtrl_GetCurLine, 2963).
--define(wxStyledTextCtrl_GetEndStyled, 2964).
--define(wxStyledTextCtrl_ConvertEOLs, 2965).
--define(wxStyledTextCtrl_GetEOLMode, 2966).
--define(wxStyledTextCtrl_SetEOLMode, 2967).
--define(wxStyledTextCtrl_StartStyling, 2968).
--define(wxStyledTextCtrl_SetStyling, 2969).
--define(wxStyledTextCtrl_GetBufferedDraw, 2970).
--define(wxStyledTextCtrl_SetBufferedDraw, 2971).
--define(wxStyledTextCtrl_SetTabWidth, 2972).
--define(wxStyledTextCtrl_GetTabWidth, 2973).
--define(wxStyledTextCtrl_SetCodePage, 2974).
--define(wxStyledTextCtrl_MarkerDefine, 2975).
--define(wxStyledTextCtrl_MarkerSetForeground, 2976).
--define(wxStyledTextCtrl_MarkerSetBackground, 2977).
--define(wxStyledTextCtrl_MarkerAdd, 2978).
--define(wxStyledTextCtrl_MarkerDelete, 2979).
--define(wxStyledTextCtrl_MarkerDeleteAll, 2980).
--define(wxStyledTextCtrl_MarkerGet, 2981).
--define(wxStyledTextCtrl_MarkerNext, 2982).
--define(wxStyledTextCtrl_MarkerPrevious, 2983).
--define(wxStyledTextCtrl_MarkerDefineBitmap, 2984).
--define(wxStyledTextCtrl_MarkerAddSet, 2985).
--define(wxStyledTextCtrl_MarkerSetAlpha, 2986).
--define(wxStyledTextCtrl_SetMarginType, 2987).
--define(wxStyledTextCtrl_GetMarginType, 2988).
--define(wxStyledTextCtrl_SetMarginWidth, 2989).
--define(wxStyledTextCtrl_GetMarginWidth, 2990).
--define(wxStyledTextCtrl_SetMarginMask, 2991).
--define(wxStyledTextCtrl_GetMarginMask, 2992).
--define(wxStyledTextCtrl_SetMarginSensitive, 2993).
--define(wxStyledTextCtrl_GetMarginSensitive, 2994).
--define(wxStyledTextCtrl_StyleClearAll, 2995).
--define(wxStyledTextCtrl_StyleSetForeground, 2996).
--define(wxStyledTextCtrl_StyleSetBackground, 2997).
--define(wxStyledTextCtrl_StyleSetBold, 2998).
--define(wxStyledTextCtrl_StyleSetItalic, 2999).
--define(wxStyledTextCtrl_StyleSetSize, 3000).
--define(wxStyledTextCtrl_StyleSetFaceName, 3001).
--define(wxStyledTextCtrl_StyleSetEOLFilled, 3002).
--define(wxStyledTextCtrl_StyleResetDefault, 3003).
--define(wxStyledTextCtrl_StyleSetUnderline, 3004).
--define(wxStyledTextCtrl_StyleSetCase, 3005).
--define(wxStyledTextCtrl_StyleSetHotSpot, 3006).
--define(wxStyledTextCtrl_SetSelForeground, 3007).
--define(wxStyledTextCtrl_SetSelBackground, 3008).
--define(wxStyledTextCtrl_GetSelAlpha, 3009).
--define(wxStyledTextCtrl_SetSelAlpha, 3010).
--define(wxStyledTextCtrl_SetCaretForeground, 3011).
--define(wxStyledTextCtrl_CmdKeyAssign, 3012).
--define(wxStyledTextCtrl_CmdKeyClear, 3013).
--define(wxStyledTextCtrl_CmdKeyClearAll, 3014).
--define(wxStyledTextCtrl_SetStyleBytes, 3015).
--define(wxStyledTextCtrl_StyleSetVisible, 3016).
--define(wxStyledTextCtrl_GetCaretPeriod, 3017).
--define(wxStyledTextCtrl_SetCaretPeriod, 3018).
--define(wxStyledTextCtrl_SetWordChars, 3019).
--define(wxStyledTextCtrl_BeginUndoAction, 3020).
--define(wxStyledTextCtrl_EndUndoAction, 3021).
--define(wxStyledTextCtrl_IndicatorSetStyle, 3022).
--define(wxStyledTextCtrl_IndicatorGetStyle, 3023).
--define(wxStyledTextCtrl_IndicatorSetForeground, 3024).
--define(wxStyledTextCtrl_IndicatorGetForeground, 3025).
--define(wxStyledTextCtrl_SetWhitespaceForeground, 3026).
--define(wxStyledTextCtrl_SetWhitespaceBackground, 3027).
--define(wxStyledTextCtrl_GetStyleBits, 3028).
--define(wxStyledTextCtrl_SetLineState, 3029).
--define(wxStyledTextCtrl_GetLineState, 3030).
--define(wxStyledTextCtrl_GetMaxLineState, 3031).
--define(wxStyledTextCtrl_GetCaretLineVisible, 3032).
--define(wxStyledTextCtrl_SetCaretLineVisible, 3033).
--define(wxStyledTextCtrl_GetCaretLineBackground, 3034).
--define(wxStyledTextCtrl_SetCaretLineBackground, 3035).
--define(wxStyledTextCtrl_AutoCompShow, 3036).
--define(wxStyledTextCtrl_AutoCompCancel, 3037).
--define(wxStyledTextCtrl_AutoCompActive, 3038).
--define(wxStyledTextCtrl_AutoCompPosStart, 3039).
--define(wxStyledTextCtrl_AutoCompComplete, 3040).
--define(wxStyledTextCtrl_AutoCompStops, 3041).
--define(wxStyledTextCtrl_AutoCompSetSeparator, 3042).
--define(wxStyledTextCtrl_AutoCompGetSeparator, 3043).
--define(wxStyledTextCtrl_AutoCompSelect, 3044).
--define(wxStyledTextCtrl_AutoCompSetCancelAtStart, 3045).
--define(wxStyledTextCtrl_AutoCompGetCancelAtStart, 3046).
--define(wxStyledTextCtrl_AutoCompSetFillUps, 3047).
--define(wxStyledTextCtrl_AutoCompSetChooseSingle, 3048).
--define(wxStyledTextCtrl_AutoCompGetChooseSingle, 3049).
--define(wxStyledTextCtrl_AutoCompSetIgnoreCase, 3050).
--define(wxStyledTextCtrl_AutoCompGetIgnoreCase, 3051).
--define(wxStyledTextCtrl_UserListShow, 3052).
--define(wxStyledTextCtrl_AutoCompSetAutoHide, 3053).
--define(wxStyledTextCtrl_AutoCompGetAutoHide, 3054).
--define(wxStyledTextCtrl_AutoCompSetDropRestOfWord, 3055).
--define(wxStyledTextCtrl_AutoCompGetDropRestOfWord, 3056).
--define(wxStyledTextCtrl_RegisterImage, 3057).
--define(wxStyledTextCtrl_ClearRegisteredImages, 3058).
--define(wxStyledTextCtrl_AutoCompGetTypeSeparator, 3059).
--define(wxStyledTextCtrl_AutoCompSetTypeSeparator, 3060).
--define(wxStyledTextCtrl_AutoCompSetMaxWidth, 3061).
--define(wxStyledTextCtrl_AutoCompGetMaxWidth, 3062).
--define(wxStyledTextCtrl_AutoCompSetMaxHeight, 3063).
--define(wxStyledTextCtrl_AutoCompGetMaxHeight, 3064).
--define(wxStyledTextCtrl_SetIndent, 3065).
--define(wxStyledTextCtrl_GetIndent, 3066).
--define(wxStyledTextCtrl_SetUseTabs, 3067).
--define(wxStyledTextCtrl_GetUseTabs, 3068).
--define(wxStyledTextCtrl_SetLineIndentation, 3069).
--define(wxStyledTextCtrl_GetLineIndentation, 3070).
--define(wxStyledTextCtrl_GetLineIndentPosition, 3071).
--define(wxStyledTextCtrl_GetColumn, 3072).
--define(wxStyledTextCtrl_SetUseHorizontalScrollBar, 3073).
--define(wxStyledTextCtrl_GetUseHorizontalScrollBar, 3074).
--define(wxStyledTextCtrl_SetIndentationGuides, 3075).
--define(wxStyledTextCtrl_GetIndentationGuides, 3076).
--define(wxStyledTextCtrl_SetHighlightGuide, 3077).
--define(wxStyledTextCtrl_GetHighlightGuide, 3078).
--define(wxStyledTextCtrl_GetLineEndPosition, 3079).
--define(wxStyledTextCtrl_GetCodePage, 3080).
--define(wxStyledTextCtrl_GetCaretForeground, 3081).
--define(wxStyledTextCtrl_GetReadOnly, 3082).
--define(wxStyledTextCtrl_SetCurrentPos, 3083).
--define(wxStyledTextCtrl_SetSelectionStart, 3084).
--define(wxStyledTextCtrl_GetSelectionStart, 3085).
--define(wxStyledTextCtrl_SetSelectionEnd, 3086).
--define(wxStyledTextCtrl_GetSelectionEnd, 3087).
--define(wxStyledTextCtrl_SetPrintMagnification, 3088).
--define(wxStyledTextCtrl_GetPrintMagnification, 3089).
--define(wxStyledTextCtrl_SetPrintColourMode, 3090).
--define(wxStyledTextCtrl_GetPrintColourMode, 3091).
--define(wxStyledTextCtrl_FindText, 3092).
--define(wxStyledTextCtrl_FormatRange, 3093).
--define(wxStyledTextCtrl_GetFirstVisibleLine, 3094).
--define(wxStyledTextCtrl_GetLine, 3095).
--define(wxStyledTextCtrl_GetLineCount, 3096).
--define(wxStyledTextCtrl_SetMarginLeft, 3097).
--define(wxStyledTextCtrl_GetMarginLeft, 3098).
--define(wxStyledTextCtrl_SetMarginRight, 3099).
--define(wxStyledTextCtrl_GetMarginRight, 3100).
--define(wxStyledTextCtrl_GetModify, 3101).
--define(wxStyledTextCtrl_SetSelection, 3102).
--define(wxStyledTextCtrl_GetSelectedText, 3103).
--define(wxStyledTextCtrl_GetTextRange, 3104).
--define(wxStyledTextCtrl_HideSelection, 3105).
--define(wxStyledTextCtrl_LineFromPosition, 3106).
--define(wxStyledTextCtrl_PositionFromLine, 3107).
--define(wxStyledTextCtrl_LineScroll, 3108).
--define(wxStyledTextCtrl_EnsureCaretVisible, 3109).
--define(wxStyledTextCtrl_ReplaceSelection, 3110).
--define(wxStyledTextCtrl_SetReadOnly, 3111).
--define(wxStyledTextCtrl_CanPaste, 3112).
--define(wxStyledTextCtrl_CanUndo, 3113).
--define(wxStyledTextCtrl_EmptyUndoBuffer, 3114).
--define(wxStyledTextCtrl_Undo, 3115).
--define(wxStyledTextCtrl_Cut, 3116).
--define(wxStyledTextCtrl_Copy, 3117).
--define(wxStyledTextCtrl_Paste, 3118).
--define(wxStyledTextCtrl_Clear, 3119).
--define(wxStyledTextCtrl_SetText, 3120).
--define(wxStyledTextCtrl_GetText, 3121).
--define(wxStyledTextCtrl_GetTextLength, 3122).
--define(wxStyledTextCtrl_GetOvertype, 3123).
--define(wxStyledTextCtrl_SetCaretWidth, 3124).
--define(wxStyledTextCtrl_GetCaretWidth, 3125).
--define(wxStyledTextCtrl_SetTargetStart, 3126).
--define(wxStyledTextCtrl_GetTargetStart, 3127).
--define(wxStyledTextCtrl_SetTargetEnd, 3128).
--define(wxStyledTextCtrl_GetTargetEnd, 3129).
--define(wxStyledTextCtrl_ReplaceTarget, 3130).
--define(wxStyledTextCtrl_SearchInTarget, 3131).
--define(wxStyledTextCtrl_SetSearchFlags, 3132).
--define(wxStyledTextCtrl_GetSearchFlags, 3133).
--define(wxStyledTextCtrl_CallTipShow, 3134).
--define(wxStyledTextCtrl_CallTipCancel, 3135).
--define(wxStyledTextCtrl_CallTipActive, 3136).
--define(wxStyledTextCtrl_CallTipPosAtStart, 3137).
--define(wxStyledTextCtrl_CallTipSetHighlight, 3138).
--define(wxStyledTextCtrl_CallTipSetBackground, 3139).
--define(wxStyledTextCtrl_CallTipSetForeground, 3140).
--define(wxStyledTextCtrl_CallTipSetForegroundHighlight, 3141).
--define(wxStyledTextCtrl_CallTipUseStyle, 3142).
--define(wxStyledTextCtrl_VisibleFromDocLine, 3143).
--define(wxStyledTextCtrl_DocLineFromVisible, 3144).
--define(wxStyledTextCtrl_WrapCount, 3145).
--define(wxStyledTextCtrl_SetFoldLevel, 3146).
--define(wxStyledTextCtrl_GetFoldLevel, 3147).
--define(wxStyledTextCtrl_GetLastChild, 3148).
--define(wxStyledTextCtrl_GetFoldParent, 3149).
--define(wxStyledTextCtrl_ShowLines, 3150).
--define(wxStyledTextCtrl_HideLines, 3151).
--define(wxStyledTextCtrl_GetLineVisible, 3152).
--define(wxStyledTextCtrl_SetFoldExpanded, 3153).
--define(wxStyledTextCtrl_GetFoldExpanded, 3154).
--define(wxStyledTextCtrl_ToggleFold, 3155).
--define(wxStyledTextCtrl_EnsureVisible, 3156).
--define(wxStyledTextCtrl_SetFoldFlags, 3157).
--define(wxStyledTextCtrl_EnsureVisibleEnforcePolicy, 3158).
--define(wxStyledTextCtrl_SetTabIndents, 3159).
--define(wxStyledTextCtrl_GetTabIndents, 3160).
--define(wxStyledTextCtrl_SetBackSpaceUnIndents, 3161).
--define(wxStyledTextCtrl_GetBackSpaceUnIndents, 3162).
--define(wxStyledTextCtrl_SetMouseDwellTime, 3163).
--define(wxStyledTextCtrl_GetMouseDwellTime, 3164).
--define(wxStyledTextCtrl_WordStartPosition, 3165).
--define(wxStyledTextCtrl_WordEndPosition, 3166).
--define(wxStyledTextCtrl_SetWrapMode, 3167).
--define(wxStyledTextCtrl_GetWrapMode, 3168).
--define(wxStyledTextCtrl_SetWrapVisualFlags, 3169).
--define(wxStyledTextCtrl_GetWrapVisualFlags, 3170).
--define(wxStyledTextCtrl_SetWrapVisualFlagsLocation, 3171).
--define(wxStyledTextCtrl_GetWrapVisualFlagsLocation, 3172).
--define(wxStyledTextCtrl_SetWrapStartIndent, 3173).
--define(wxStyledTextCtrl_GetWrapStartIndent, 3174).
--define(wxStyledTextCtrl_SetLayoutCache, 3175).
--define(wxStyledTextCtrl_GetLayoutCache, 3176).
--define(wxStyledTextCtrl_SetScrollWidth, 3177).
--define(wxStyledTextCtrl_GetScrollWidth, 3178).
--define(wxStyledTextCtrl_TextWidth, 3179).
--define(wxStyledTextCtrl_GetEndAtLastLine, 3180).
--define(wxStyledTextCtrl_TextHeight, 3181).
--define(wxStyledTextCtrl_SetUseVerticalScrollBar, 3182).
--define(wxStyledTextCtrl_GetUseVerticalScrollBar, 3183).
--define(wxStyledTextCtrl_AppendText, 3184).
--define(wxStyledTextCtrl_GetTwoPhaseDraw, 3185).
--define(wxStyledTextCtrl_SetTwoPhaseDraw, 3186).
--define(wxStyledTextCtrl_TargetFromSelection, 3187).
--define(wxStyledTextCtrl_LinesJoin, 3188).
--define(wxStyledTextCtrl_LinesSplit, 3189).
--define(wxStyledTextCtrl_SetFoldMarginColour, 3190).
--define(wxStyledTextCtrl_SetFoldMarginHiColour, 3191).
--define(wxStyledTextCtrl_LineDown, 3192).
--define(wxStyledTextCtrl_LineDownExtend, 3193).
--define(wxStyledTextCtrl_LineUp, 3194).
--define(wxStyledTextCtrl_LineUpExtend, 3195).
--define(wxStyledTextCtrl_CharLeft, 3196).
--define(wxStyledTextCtrl_CharLeftExtend, 3197).
--define(wxStyledTextCtrl_CharRight, 3198).
--define(wxStyledTextCtrl_CharRightExtend, 3199).
--define(wxStyledTextCtrl_WordLeft, 3200).
--define(wxStyledTextCtrl_WordLeftExtend, 3201).
--define(wxStyledTextCtrl_WordRight, 3202).
--define(wxStyledTextCtrl_WordRightExtend, 3203).
--define(wxStyledTextCtrl_Home, 3204).
--define(wxStyledTextCtrl_HomeExtend, 3205).
--define(wxStyledTextCtrl_LineEnd, 3206).
--define(wxStyledTextCtrl_LineEndExtend, 3207).
--define(wxStyledTextCtrl_DocumentStart, 3208).
--define(wxStyledTextCtrl_DocumentStartExtend, 3209).
--define(wxStyledTextCtrl_DocumentEnd, 3210).
--define(wxStyledTextCtrl_DocumentEndExtend, 3211).
--define(wxStyledTextCtrl_PageUp, 3212).
--define(wxStyledTextCtrl_PageUpExtend, 3213).
--define(wxStyledTextCtrl_PageDown, 3214).
--define(wxStyledTextCtrl_PageDownExtend, 3215).
--define(wxStyledTextCtrl_EditToggleOvertype, 3216).
--define(wxStyledTextCtrl_Cancel, 3217).
--define(wxStyledTextCtrl_DeleteBack, 3218).
--define(wxStyledTextCtrl_Tab, 3219).
--define(wxStyledTextCtrl_BackTab, 3220).
--define(wxStyledTextCtrl_NewLine, 3221).
--define(wxStyledTextCtrl_FormFeed, 3222).
--define(wxStyledTextCtrl_VCHome, 3223).
--define(wxStyledTextCtrl_VCHomeExtend, 3224).
--define(wxStyledTextCtrl_ZoomIn, 3225).
--define(wxStyledTextCtrl_ZoomOut, 3226).
--define(wxStyledTextCtrl_DelWordLeft, 3227).
--define(wxStyledTextCtrl_DelWordRight, 3228).
--define(wxStyledTextCtrl_LineCut, 3229).
--define(wxStyledTextCtrl_LineDelete, 3230).
--define(wxStyledTextCtrl_LineTranspose, 3231).
--define(wxStyledTextCtrl_LineDuplicate, 3232).
--define(wxStyledTextCtrl_LowerCase, 3233).
--define(wxStyledTextCtrl_UpperCase, 3234).
--define(wxStyledTextCtrl_LineScrollDown, 3235).
--define(wxStyledTextCtrl_LineScrollUp, 3236).
--define(wxStyledTextCtrl_DeleteBackNotLine, 3237).
--define(wxStyledTextCtrl_HomeDisplay, 3238).
--define(wxStyledTextCtrl_HomeDisplayExtend, 3239).
--define(wxStyledTextCtrl_LineEndDisplay, 3240).
--define(wxStyledTextCtrl_LineEndDisplayExtend, 3241).
--define(wxStyledTextCtrl_HomeWrapExtend, 3242).
--define(wxStyledTextCtrl_LineEndWrap, 3243).
--define(wxStyledTextCtrl_LineEndWrapExtend, 3244).
--define(wxStyledTextCtrl_VCHomeWrap, 3245).
--define(wxStyledTextCtrl_VCHomeWrapExtend, 3246).
--define(wxStyledTextCtrl_LineCopy, 3247).
--define(wxStyledTextCtrl_MoveCaretInsideView, 3248).
--define(wxStyledTextCtrl_LineLength, 3249).
--define(wxStyledTextCtrl_BraceHighlight, 3250).
--define(wxStyledTextCtrl_BraceBadLight, 3251).
--define(wxStyledTextCtrl_BraceMatch, 3252).
--define(wxStyledTextCtrl_GetViewEOL, 3253).
--define(wxStyledTextCtrl_SetViewEOL, 3254).
--define(wxStyledTextCtrl_SetModEventMask, 3255).
--define(wxStyledTextCtrl_GetEdgeColumn, 3256).
--define(wxStyledTextCtrl_SetEdgeColumn, 3257).
--define(wxStyledTextCtrl_GetEdgeMode, 3258).
--define(wxStyledTextCtrl_GetEdgeColour, 3259).
--define(wxStyledTextCtrl_SetEdgeColour, 3260).
--define(wxStyledTextCtrl_SearchAnchor, 3261).
--define(wxStyledTextCtrl_SearchNext, 3262).
--define(wxStyledTextCtrl_SearchPrev, 3263).
--define(wxStyledTextCtrl_LinesOnScreen, 3264).
--define(wxStyledTextCtrl_UsePopUp, 3265).
--define(wxStyledTextCtrl_SelectionIsRectangle, 3266).
--define(wxStyledTextCtrl_SetZoom, 3267).
--define(wxStyledTextCtrl_GetZoom, 3268).
--define(wxStyledTextCtrl_GetModEventMask, 3269).
--define(wxStyledTextCtrl_SetSTCFocus, 3270).
--define(wxStyledTextCtrl_GetSTCFocus, 3271).
--define(wxStyledTextCtrl_SetStatus, 3272).
--define(wxStyledTextCtrl_GetStatus, 3273).
--define(wxStyledTextCtrl_SetMouseDownCaptures, 3274).
--define(wxStyledTextCtrl_GetMouseDownCaptures, 3275).
--define(wxStyledTextCtrl_SetSTCCursor, 3276).
--define(wxStyledTextCtrl_GetSTCCursor, 3277).
--define(wxStyledTextCtrl_SetControlCharSymbol, 3278).
--define(wxStyledTextCtrl_GetControlCharSymbol, 3279).
--define(wxStyledTextCtrl_WordPartLeft, 3280).
--define(wxStyledTextCtrl_WordPartLeftExtend, 3281).
--define(wxStyledTextCtrl_WordPartRight, 3282).
--define(wxStyledTextCtrl_WordPartRightExtend, 3283).
--define(wxStyledTextCtrl_SetVisiblePolicy, 3284).
--define(wxStyledTextCtrl_DelLineLeft, 3285).
--define(wxStyledTextCtrl_DelLineRight, 3286).
--define(wxStyledTextCtrl_GetXOffset, 3287).
--define(wxStyledTextCtrl_ChooseCaretX, 3288).
--define(wxStyledTextCtrl_SetXCaretPolicy, 3289).
--define(wxStyledTextCtrl_SetYCaretPolicy, 3290).
--define(wxStyledTextCtrl_GetPrintWrapMode, 3291).
--define(wxStyledTextCtrl_SetHotspotActiveForeground, 3292).
--define(wxStyledTextCtrl_SetHotspotActiveBackground, 3293).
--define(wxStyledTextCtrl_SetHotspotActiveUnderline, 3294).
--define(wxStyledTextCtrl_SetHotspotSingleLine, 3295).
--define(wxStyledTextCtrl_ParaDownExtend, 3296).
--define(wxStyledTextCtrl_ParaUp, 3297).
--define(wxStyledTextCtrl_ParaUpExtend, 3298).
--define(wxStyledTextCtrl_PositionBefore, 3299).
--define(wxStyledTextCtrl_PositionAfter, 3300).
--define(wxStyledTextCtrl_CopyRange, 3301).
--define(wxStyledTextCtrl_CopyText, 3302).
--define(wxStyledTextCtrl_SetSelectionMode, 3303).
--define(wxStyledTextCtrl_GetSelectionMode, 3304).
--define(wxStyledTextCtrl_LineDownRectExtend, 3305).
--define(wxStyledTextCtrl_LineUpRectExtend, 3306).
--define(wxStyledTextCtrl_CharLeftRectExtend, 3307).
--define(wxStyledTextCtrl_CharRightRectExtend, 3308).
--define(wxStyledTextCtrl_HomeRectExtend, 3309).
--define(wxStyledTextCtrl_VCHomeRectExtend, 3310).
--define(wxStyledTextCtrl_LineEndRectExtend, 3311).
--define(wxStyledTextCtrl_PageUpRectExtend, 3312).
--define(wxStyledTextCtrl_PageDownRectExtend, 3313).
--define(wxStyledTextCtrl_StutteredPageUp, 3314).
--define(wxStyledTextCtrl_StutteredPageUpExtend, 3315).
--define(wxStyledTextCtrl_StutteredPageDown, 3316).
--define(wxStyledTextCtrl_StutteredPageDownExtend, 3317).
--define(wxStyledTextCtrl_WordLeftEnd, 3318).
--define(wxStyledTextCtrl_WordLeftEndExtend, 3319).
--define(wxStyledTextCtrl_WordRightEnd, 3320).
--define(wxStyledTextCtrl_WordRightEndExtend, 3321).
--define(wxStyledTextCtrl_SetWhitespaceChars, 3322).
--define(wxStyledTextCtrl_SetCharsDefault, 3323).
--define(wxStyledTextCtrl_AutoCompGetCurrent, 3324).
--define(wxStyledTextCtrl_Allocate, 3325).
--define(wxStyledTextCtrl_FindColumn, 3326).
--define(wxStyledTextCtrl_GetCaretSticky, 3327).
--define(wxStyledTextCtrl_SetCaretSticky, 3328).
--define(wxStyledTextCtrl_ToggleCaretSticky, 3329).
--define(wxStyledTextCtrl_SetPasteConvertEndings, 3330).
--define(wxStyledTextCtrl_GetPasteConvertEndings, 3331).
--define(wxStyledTextCtrl_SelectionDuplicate, 3332).
--define(wxStyledTextCtrl_SetCaretLineBackAlpha, 3333).
--define(wxStyledTextCtrl_GetCaretLineBackAlpha, 3334).
--define(wxStyledTextCtrl_StartRecord, 3335).
--define(wxStyledTextCtrl_StopRecord, 3336).
--define(wxStyledTextCtrl_SetLexer, 3337).
--define(wxStyledTextCtrl_GetLexer, 3338).
--define(wxStyledTextCtrl_Colourise, 3339).
--define(wxStyledTextCtrl_SetProperty, 3340).
--define(wxStyledTextCtrl_SetKeyWords, 3341).
--define(wxStyledTextCtrl_SetLexerLanguage, 3342).
--define(wxStyledTextCtrl_GetProperty, 3343).
--define(wxStyledTextCtrl_GetStyleBitsNeeded, 3344).
--define(wxStyledTextCtrl_GetCurrentLine, 3345).
--define(wxStyledTextCtrl_StyleSetSpec, 3346).
--define(wxStyledTextCtrl_StyleSetFont, 3347).
--define(wxStyledTextCtrl_StyleSetFontAttr, 3348).
--define(wxStyledTextCtrl_StyleSetCharacterSet, 3349).
--define(wxStyledTextCtrl_StyleSetFontEncoding, 3350).
--define(wxStyledTextCtrl_CmdKeyExecute, 3351).
--define(wxStyledTextCtrl_SetMargins, 3352).
--define(wxStyledTextCtrl_GetSelection, 3353).
--define(wxStyledTextCtrl_PointFromPosition, 3354).
--define(wxStyledTextCtrl_ScrollToLine, 3355).
--define(wxStyledTextCtrl_ScrollToColumn, 3356).
--define(wxStyledTextCtrl_SendMsg, 3357).
--define(wxStyledTextCtrl_SetVScrollBar, 3358).
--define(wxStyledTextCtrl_SetHScrollBar, 3359).
--define(wxStyledTextCtrl_GetLastKeydownProcessed, 3360).
--define(wxStyledTextCtrl_SetLastKeydownProcessed, 3361).
--define(wxStyledTextCtrl_SaveFile, 3362).
--define(wxStyledTextCtrl_LoadFile, 3363).
--define(wxStyledTextCtrl_DoDragOver, 3364).
--define(wxStyledTextCtrl_DoDropText, 3365).
--define(wxStyledTextCtrl_GetUseAntiAliasing, 3366).
--define(wxStyledTextCtrl_AddTextRaw, 3367).
--define(wxStyledTextCtrl_InsertTextRaw, 3368).
--define(wxStyledTextCtrl_GetCurLineRaw, 3369).
--define(wxStyledTextCtrl_GetLineRaw, 3370).
--define(wxStyledTextCtrl_GetSelectedTextRaw, 3371).
--define(wxStyledTextCtrl_GetTextRangeRaw, 3372).
--define(wxStyledTextCtrl_SetTextRaw, 3373).
--define(wxStyledTextCtrl_GetTextRaw, 3374).
--define(wxStyledTextCtrl_AppendTextRaw, 3375).
--define(wxArtProvider_GetBitmap, 3376).
--define(wxArtProvider_GetIcon, 3377).
--define(wxTreeEvent_GetKeyCode, 3378).
--define(wxTreeEvent_GetItem, 3379).
--define(wxTreeEvent_GetKeyEvent, 3380).
--define(wxTreeEvent_GetLabel, 3381).
--define(wxTreeEvent_GetOldItem, 3382).
--define(wxTreeEvent_GetPoint, 3383).
--define(wxTreeEvent_IsEditCancelled, 3384).
--define(wxTreeEvent_SetToolTip, 3385).
--define(wxNotebookEvent_GetOldSelection, 3386).
--define(wxNotebookEvent_GetSelection, 3387).
--define(wxNotebookEvent_SetOldSelection, 3388).
--define(wxNotebookEvent_SetSelection, 3389).
--define(wxFileDataObject_new, 3390).
--define(wxFileDataObject_AddFile, 3391).
--define(wxFileDataObject_GetFilenames, 3392).
--define(wxFileDataObject_destroy, 3393).
--define(wxTextDataObject_new, 3394).
--define(wxTextDataObject_GetTextLength, 3395).
--define(wxTextDataObject_GetText, 3396).
--define(wxTextDataObject_SetText, 3397).
--define(wxTextDataObject_destroy, 3398).
--define(wxBitmapDataObject_new_1_1, 3399).
--define(wxBitmapDataObject_new_1_0, 3400).
--define(wxBitmapDataObject_GetBitmap, 3401).
--define(wxBitmapDataObject_SetBitmap, 3402).
--define(wxBitmapDataObject_destroy, 3403).
--define(wxClipboard_new, 3405).
--define(wxClipboard_destruct, 3406).
--define(wxClipboard_AddData, 3407).
--define(wxClipboard_Clear, 3408).
--define(wxClipboard_Close, 3409).
--define(wxClipboard_Flush, 3410).
--define(wxClipboard_GetData, 3411).
--define(wxClipboard_IsOpened, 3412).
--define(wxClipboard_Open, 3413).
--define(wxClipboard_SetData, 3414).
--define(wxClipboard_UsePrimarySelection, 3416).
--define(wxClipboard_IsSupported, 3417).
--define(wxClipboard_Get, 3418).
--define(wxSpinEvent_GetPosition, 3419).
--define(wxSpinEvent_SetPosition, 3420).
--define(wxSplitterWindow_new_0, 3421).
--define(wxSplitterWindow_new_2, 3422).
--define(wxSplitterWindow_destruct, 3423).
--define(wxSplitterWindow_Create, 3424).
--define(wxSplitterWindow_GetMinimumPaneSize, 3425).
--define(wxSplitterWindow_GetSashGravity, 3426).
--define(wxSplitterWindow_GetSashPosition, 3427).
--define(wxSplitterWindow_GetSplitMode, 3428).
--define(wxSplitterWindow_GetWindow1, 3429).
--define(wxSplitterWindow_GetWindow2, 3430).
--define(wxSplitterWindow_Initialize, 3431).
--define(wxSplitterWindow_IsSplit, 3432).
--define(wxSplitterWindow_ReplaceWindow, 3433).
--define(wxSplitterWindow_SetSashGravity, 3434).
--define(wxSplitterWindow_SetSashPosition, 3435).
--define(wxSplitterWindow_SetSashSize, 3436).
--define(wxSplitterWindow_SetMinimumPaneSize, 3437).
--define(wxSplitterWindow_SetSplitMode, 3438).
--define(wxSplitterWindow_SplitHorizontally, 3439).
--define(wxSplitterWindow_SplitVertically, 3440).
--define(wxSplitterWindow_Unsplit, 3441).
--define(wxSplitterWindow_UpdateSize, 3442).
--define(wxSplitterEvent_GetSashPosition, 3443).
--define(wxSplitterEvent_GetX, 3444).
--define(wxSplitterEvent_GetY, 3445).
--define(wxSplitterEvent_GetWindowBeingRemoved, 3446).
--define(wxSplitterEvent_SetSashPosition, 3447).
--define(wxHtmlWindow_new_0, 3448).
--define(wxHtmlWindow_new_2, 3449).
--define(wxHtmlWindow_AppendToPage, 3450).
--define(wxHtmlWindow_GetOpenedAnchor, 3451).
--define(wxHtmlWindow_GetOpenedPage, 3452).
--define(wxHtmlWindow_GetOpenedPageTitle, 3453).
--define(wxHtmlWindow_GetRelatedFrame, 3454).
--define(wxHtmlWindow_HistoryBack, 3455).
--define(wxHtmlWindow_HistoryCanBack, 3456).
--define(wxHtmlWindow_HistoryCanForward, 3457).
--define(wxHtmlWindow_HistoryClear, 3458).
--define(wxHtmlWindow_HistoryForward, 3459).
--define(wxHtmlWindow_LoadFile, 3460).
--define(wxHtmlWindow_LoadPage, 3461).
--define(wxHtmlWindow_SelectAll, 3462).
--define(wxHtmlWindow_SelectionToText, 3463).
--define(wxHtmlWindow_SelectLine, 3464).
--define(wxHtmlWindow_SelectWord, 3465).
--define(wxHtmlWindow_SetBorders, 3466).
--define(wxHtmlWindow_SetFonts, 3467).
--define(wxHtmlWindow_SetPage, 3468).
--define(wxHtmlWindow_SetRelatedFrame, 3469).
--define(wxHtmlWindow_SetRelatedStatusBar, 3470).
--define(wxHtmlWindow_ToText, 3471).
--define(wxHtmlWindow_destroy, 3472).
--define(wxHtmlLinkEvent_GetLinkInfo, 3473).
--define(wxAuiNotebookEvent_SetSelection, 3474).
--define(wxAuiNotebookEvent_GetSelection, 3475).
--define(wxAuiNotebookEvent_SetOldSelection, 3476).
--define(wxAuiNotebookEvent_GetOldSelection, 3477).
--define(wxAuiNotebookEvent_SetDragSource, 3478).
--define(wxAuiNotebookEvent_GetDragSource, 3479).
--define(wxAuiManagerEvent_SetManager, 3480).
--define(wxAuiManagerEvent_GetManager, 3481).
--define(wxAuiManagerEvent_SetPane, 3482).
--define(wxAuiManagerEvent_GetPane, 3483).
--define(wxAuiManagerEvent_SetButton, 3484).
--define(wxAuiManagerEvent_GetButton, 3485).
--define(wxAuiManagerEvent_SetDC, 3486).
--define(wxAuiManagerEvent_GetDC, 3487).
--define(wxAuiManagerEvent_Veto, 3488).
--define(wxAuiManagerEvent_GetVeto, 3489).
--define(wxAuiManagerEvent_SetCanVeto, 3490).
--define(wxAuiManagerEvent_CanVeto, 3491).
--define(wxLogNull_new, 3492).
--define(wxLogNull_destroy, 3493).
+-define(wxListCtrl_GetEditControl, 1675).
+-define(wxListCtrl_GetImageList, 1676).
+-define(wxListCtrl_GetItem, 1677).
+-define(wxListCtrl_GetItemBackgroundColour, 1678).
+-define(wxListCtrl_GetItemCount, 1679).
+-define(wxListCtrl_GetItemData, 1680).
+-define(wxListCtrl_GetItemFont, 1681).
+-define(wxListCtrl_GetItemPosition, 1682).
+-define(wxListCtrl_GetItemRect, 1683).
+-define(wxListCtrl_GetItemSpacing, 1684).
+-define(wxListCtrl_GetItemState, 1685).
+-define(wxListCtrl_GetItemText, 1686).
+-define(wxListCtrl_GetItemTextColour, 1687).
+-define(wxListCtrl_GetNextItem, 1688).
+-define(wxListCtrl_GetSelectedItemCount, 1689).
+-define(wxListCtrl_GetTextColour, 1690).
+-define(wxListCtrl_GetTopItem, 1691).
+-define(wxListCtrl_GetViewRect, 1692).
+-define(wxListCtrl_HitTest, 1693).
+-define(wxListCtrl_InsertColumn_2, 1694).
+-define(wxListCtrl_InsertColumn_3, 1695).
+-define(wxListCtrl_InsertItem_1, 1696).
+-define(wxListCtrl_InsertItem_2_1, 1697).
+-define(wxListCtrl_InsertItem_2_0, 1698).
+-define(wxListCtrl_InsertItem_3, 1699).
+-define(wxListCtrl_RefreshItem, 1700).
+-define(wxListCtrl_RefreshItems, 1701).
+-define(wxListCtrl_ScrollList, 1702).
+-define(wxListCtrl_SetBackgroundColour, 1703).
+-define(wxListCtrl_SetColumn, 1704).
+-define(wxListCtrl_SetColumnWidth, 1705).
+-define(wxListCtrl_SetImageList, 1706).
+-define(wxListCtrl_SetItem_1, 1707).
+-define(wxListCtrl_SetItem_4, 1708).
+-define(wxListCtrl_SetItemBackgroundColour, 1709).
+-define(wxListCtrl_SetItemCount, 1710).
+-define(wxListCtrl_SetItemData, 1711).
+-define(wxListCtrl_SetItemFont, 1712).
+-define(wxListCtrl_SetItemImage, 1713).
+-define(wxListCtrl_SetItemColumnImage, 1714).
+-define(wxListCtrl_SetItemPosition, 1715).
+-define(wxListCtrl_SetItemState, 1716).
+-define(wxListCtrl_SetItemText, 1717).
+-define(wxListCtrl_SetItemTextColour, 1718).
+-define(wxListCtrl_SetSingleStyle, 1719).
+-define(wxListCtrl_SetTextColour, 1720).
+-define(wxListCtrl_SetWindowStyleFlag, 1721).
+-define(wxListCtrl_SortItems, 1722).
+-define(wxListCtrl_destroy, 1723).
+-define(wxListView_ClearColumnImage, 1724).
+-define(wxListView_Focus, 1725).
+-define(wxListView_GetFirstSelected, 1726).
+-define(wxListView_GetFocusedItem, 1727).
+-define(wxListView_GetNextSelected, 1728).
+-define(wxListView_IsSelected, 1729).
+-define(wxListView_Select, 1730).
+-define(wxListView_SetColumnImage, 1731).
+-define(wxListItem_new_0, 1732).
+-define(wxListItem_new_1, 1733).
+-define(wxListItem_destruct, 1734).
+-define(wxListItem_Clear, 1735).
+-define(wxListItem_GetAlign, 1736).
+-define(wxListItem_GetBackgroundColour, 1737).
+-define(wxListItem_GetColumn, 1738).
+-define(wxListItem_GetFont, 1739).
+-define(wxListItem_GetId, 1740).
+-define(wxListItem_GetImage, 1741).
+-define(wxListItem_GetMask, 1742).
+-define(wxListItem_GetState, 1743).
+-define(wxListItem_GetText, 1744).
+-define(wxListItem_GetTextColour, 1745).
+-define(wxListItem_GetWidth, 1746).
+-define(wxListItem_SetAlign, 1747).
+-define(wxListItem_SetBackgroundColour, 1748).
+-define(wxListItem_SetColumn, 1749).
+-define(wxListItem_SetFont, 1750).
+-define(wxListItem_SetId, 1751).
+-define(wxListItem_SetImage, 1752).
+-define(wxListItem_SetMask, 1753).
+-define(wxListItem_SetState, 1754).
+-define(wxListItem_SetStateMask, 1755).
+-define(wxListItem_SetText, 1756).
+-define(wxListItem_SetTextColour, 1757).
+-define(wxListItem_SetWidth, 1758).
+-define(wxImageList_new_0, 1759).
+-define(wxImageList_new_3, 1760).
+-define(wxImageList_Add_1, 1761).
+-define(wxImageList_Add_2_0, 1762).
+-define(wxImageList_Add_2_1, 1763).
+-define(wxImageList_Create, 1764).
+-define(wxImageList_Draw, 1766).
+-define(wxImageList_GetBitmap, 1767).
+-define(wxImageList_GetIcon, 1768).
+-define(wxImageList_GetImageCount, 1769).
+-define(wxImageList_GetSize, 1770).
+-define(wxImageList_Remove, 1771).
+-define(wxImageList_RemoveAll, 1772).
+-define(wxImageList_Replace_2, 1773).
+-define(wxImageList_Replace_3, 1774).
+-define(wxImageList_destroy, 1775).
+-define(wxTextAttr_new_0, 1776).
+-define(wxTextAttr_new_2, 1777).
+-define(wxTextAttr_GetAlignment, 1778).
+-define(wxTextAttr_GetBackgroundColour, 1779).
+-define(wxTextAttr_GetFont, 1780).
+-define(wxTextAttr_GetLeftIndent, 1781).
+-define(wxTextAttr_GetLeftSubIndent, 1782).
+-define(wxTextAttr_GetRightIndent, 1783).
+-define(wxTextAttr_GetTabs, 1784).
+-define(wxTextAttr_GetTextColour, 1785).
+-define(wxTextAttr_HasBackgroundColour, 1786).
+-define(wxTextAttr_HasFont, 1787).
+-define(wxTextAttr_HasTextColour, 1788).
+-define(wxTextAttr_GetFlags, 1789).
+-define(wxTextAttr_IsDefault, 1790).
+-define(wxTextAttr_SetAlignment, 1791).
+-define(wxTextAttr_SetBackgroundColour, 1792).
+-define(wxTextAttr_SetFlags, 1793).
+-define(wxTextAttr_SetFont, 1794).
+-define(wxTextAttr_SetLeftIndent, 1795).
+-define(wxTextAttr_SetRightIndent, 1796).
+-define(wxTextAttr_SetTabs, 1797).
+-define(wxTextAttr_SetTextColour, 1798).
+-define(wxTextAttr_destroy, 1799).
+-define(wxTextCtrl_new_3, 1801).
+-define(wxTextCtrl_new_0, 1802).
+-define(wxTextCtrl_destruct, 1804).
+-define(wxTextCtrl_AppendText, 1805).
+-define(wxTextCtrl_CanCopy, 1806).
+-define(wxTextCtrl_CanCut, 1807).
+-define(wxTextCtrl_CanPaste, 1808).
+-define(wxTextCtrl_CanRedo, 1809).
+-define(wxTextCtrl_CanUndo, 1810).
+-define(wxTextCtrl_Clear, 1811).
+-define(wxTextCtrl_Copy, 1812).
+-define(wxTextCtrl_Create, 1813).
+-define(wxTextCtrl_Cut, 1814).
+-define(wxTextCtrl_DiscardEdits, 1815).
+-define(wxTextCtrl_EmulateKeyPress, 1816).
+-define(wxTextCtrl_GetDefaultStyle, 1817).
+-define(wxTextCtrl_GetInsertionPoint, 1818).
+-define(wxTextCtrl_GetLastPosition, 1819).
+-define(wxTextCtrl_GetLineLength, 1820).
+-define(wxTextCtrl_GetLineText, 1821).
+-define(wxTextCtrl_GetNumberOfLines, 1822).
+-define(wxTextCtrl_GetRange, 1823).
+-define(wxTextCtrl_GetSelection, 1824).
+-define(wxTextCtrl_GetStringSelection, 1825).
+-define(wxTextCtrl_GetStyle, 1826).
+-define(wxTextCtrl_GetValue, 1827).
+-define(wxTextCtrl_IsEditable, 1828).
+-define(wxTextCtrl_IsModified, 1829).
+-define(wxTextCtrl_IsMultiLine, 1830).
+-define(wxTextCtrl_IsSingleLine, 1831).
+-define(wxTextCtrl_LoadFile, 1832).
+-define(wxTextCtrl_MarkDirty, 1833).
+-define(wxTextCtrl_Paste, 1834).
+-define(wxTextCtrl_PositionToXY, 1835).
+-define(wxTextCtrl_Redo, 1836).
+-define(wxTextCtrl_Remove, 1837).
+-define(wxTextCtrl_Replace, 1838).
+-define(wxTextCtrl_SaveFile, 1839).
+-define(wxTextCtrl_SetDefaultStyle, 1840).
+-define(wxTextCtrl_SetEditable, 1841).
+-define(wxTextCtrl_SetInsertionPoint, 1842).
+-define(wxTextCtrl_SetInsertionPointEnd, 1843).
+-define(wxTextCtrl_SetMaxLength, 1845).
+-define(wxTextCtrl_SetSelection, 1846).
+-define(wxTextCtrl_SetStyle, 1847).
+-define(wxTextCtrl_SetValue, 1848).
+-define(wxTextCtrl_ShowPosition, 1849).
+-define(wxTextCtrl_Undo, 1850).
+-define(wxTextCtrl_WriteText, 1851).
+-define(wxTextCtrl_XYToPosition, 1852).
+-define(wxNotebook_new_0, 1855).
+-define(wxNotebook_new_3, 1856).
+-define(wxNotebook_destruct, 1857).
+-define(wxNotebook_AddPage, 1858).
+-define(wxNotebook_AdvanceSelection, 1859).
+-define(wxNotebook_AssignImageList, 1860).
+-define(wxNotebook_Create, 1861).
+-define(wxNotebook_DeleteAllPages, 1862).
+-define(wxNotebook_DeletePage, 1863).
+-define(wxNotebook_RemovePage, 1864).
+-define(wxNotebook_GetCurrentPage, 1865).
+-define(wxNotebook_GetImageList, 1866).
+-define(wxNotebook_GetPage, 1868).
+-define(wxNotebook_GetPageCount, 1869).
+-define(wxNotebook_GetPageImage, 1870).
+-define(wxNotebook_GetPageText, 1871).
+-define(wxNotebook_GetRowCount, 1872).
+-define(wxNotebook_GetSelection, 1873).
+-define(wxNotebook_GetThemeBackgroundColour, 1874).
+-define(wxNotebook_HitTest, 1876).
+-define(wxNotebook_InsertPage, 1878).
+-define(wxNotebook_SetImageList, 1879).
+-define(wxNotebook_SetPadding, 1880).
+-define(wxNotebook_SetPageSize, 1881).
+-define(wxNotebook_SetPageImage, 1882).
+-define(wxNotebook_SetPageText, 1883).
+-define(wxNotebook_SetSelection, 1884).
+-define(wxNotebook_ChangeSelection, 1885).
+-define(wxChoicebook_new_0, 1886).
+-define(wxChoicebook_new_3, 1887).
+-define(wxChoicebook_AddPage, 1888).
+-define(wxChoicebook_AdvanceSelection, 1889).
+-define(wxChoicebook_AssignImageList, 1890).
+-define(wxChoicebook_Create, 1891).
+-define(wxChoicebook_DeleteAllPages, 1892).
+-define(wxChoicebook_DeletePage, 1893).
+-define(wxChoicebook_RemovePage, 1894).
+-define(wxChoicebook_GetCurrentPage, 1895).
+-define(wxChoicebook_GetImageList, 1896).
+-define(wxChoicebook_GetPage, 1898).
+-define(wxChoicebook_GetPageCount, 1899).
+-define(wxChoicebook_GetPageImage, 1900).
+-define(wxChoicebook_GetPageText, 1901).
+-define(wxChoicebook_GetSelection, 1902).
+-define(wxChoicebook_HitTest, 1903).
+-define(wxChoicebook_InsertPage, 1904).
+-define(wxChoicebook_SetImageList, 1905).
+-define(wxChoicebook_SetPageSize, 1906).
+-define(wxChoicebook_SetPageImage, 1907).
+-define(wxChoicebook_SetPageText, 1908).
+-define(wxChoicebook_SetSelection, 1909).
+-define(wxChoicebook_ChangeSelection, 1910).
+-define(wxChoicebook_destroy, 1911).
+-define(wxToolbook_new_0, 1912).
+-define(wxToolbook_new_3, 1913).
+-define(wxToolbook_AddPage, 1914).
+-define(wxToolbook_AdvanceSelection, 1915).
+-define(wxToolbook_AssignImageList, 1916).
+-define(wxToolbook_Create, 1917).
+-define(wxToolbook_DeleteAllPages, 1918).
+-define(wxToolbook_DeletePage, 1919).
+-define(wxToolbook_RemovePage, 1920).
+-define(wxToolbook_GetCurrentPage, 1921).
+-define(wxToolbook_GetImageList, 1922).
+-define(wxToolbook_GetPage, 1924).
+-define(wxToolbook_GetPageCount, 1925).
+-define(wxToolbook_GetPageImage, 1926).
+-define(wxToolbook_GetPageText, 1927).
+-define(wxToolbook_GetSelection, 1928).
+-define(wxToolbook_HitTest, 1930).
+-define(wxToolbook_InsertPage, 1931).
+-define(wxToolbook_SetImageList, 1932).
+-define(wxToolbook_SetPageSize, 1933).
+-define(wxToolbook_SetPageImage, 1934).
+-define(wxToolbook_SetPageText, 1935).
+-define(wxToolbook_SetSelection, 1936).
+-define(wxToolbook_ChangeSelection, 1937).
+-define(wxToolbook_destroy, 1938).
+-define(wxListbook_new_0, 1939).
+-define(wxListbook_new_3, 1940).
+-define(wxListbook_AddPage, 1941).
+-define(wxListbook_AdvanceSelection, 1942).
+-define(wxListbook_AssignImageList, 1943).
+-define(wxListbook_Create, 1944).
+-define(wxListbook_DeleteAllPages, 1945).
+-define(wxListbook_DeletePage, 1946).
+-define(wxListbook_RemovePage, 1947).
+-define(wxListbook_GetCurrentPage, 1948).
+-define(wxListbook_GetImageList, 1949).
+-define(wxListbook_GetPage, 1951).
+-define(wxListbook_GetPageCount, 1952).
+-define(wxListbook_GetPageImage, 1953).
+-define(wxListbook_GetPageText, 1954).
+-define(wxListbook_GetSelection, 1955).
+-define(wxListbook_HitTest, 1957).
+-define(wxListbook_InsertPage, 1958).
+-define(wxListbook_SetImageList, 1959).
+-define(wxListbook_SetPageSize, 1960).
+-define(wxListbook_SetPageImage, 1961).
+-define(wxListbook_SetPageText, 1962).
+-define(wxListbook_SetSelection, 1963).
+-define(wxListbook_ChangeSelection, 1964).
+-define(wxListbook_destroy, 1965).
+-define(wxTreebook_new_0, 1966).
+-define(wxTreebook_new_3, 1967).
+-define(wxTreebook_AddPage, 1968).
+-define(wxTreebook_AdvanceSelection, 1969).
+-define(wxTreebook_AssignImageList, 1970).
+-define(wxTreebook_Create, 1971).
+-define(wxTreebook_DeleteAllPages, 1972).
+-define(wxTreebook_DeletePage, 1973).
+-define(wxTreebook_RemovePage, 1974).
+-define(wxTreebook_GetCurrentPage, 1975).
+-define(wxTreebook_GetImageList, 1976).
+-define(wxTreebook_GetPage, 1978).
+-define(wxTreebook_GetPageCount, 1979).
+-define(wxTreebook_GetPageImage, 1980).
+-define(wxTreebook_GetPageText, 1981).
+-define(wxTreebook_GetSelection, 1982).
+-define(wxTreebook_ExpandNode, 1983).
+-define(wxTreebook_IsNodeExpanded, 1984).
+-define(wxTreebook_HitTest, 1986).
+-define(wxTreebook_InsertPage, 1987).
+-define(wxTreebook_InsertSubPage, 1988).
+-define(wxTreebook_SetImageList, 1989).
+-define(wxTreebook_SetPageSize, 1990).
+-define(wxTreebook_SetPageImage, 1991).
+-define(wxTreebook_SetPageText, 1992).
+-define(wxTreebook_SetSelection, 1993).
+-define(wxTreebook_ChangeSelection, 1994).
+-define(wxTreebook_destroy, 1995).
+-define(wxTreeCtrl_new_2, 1998).
+-define(wxTreeCtrl_new_0, 1999).
+-define(wxTreeCtrl_destruct, 2001).
+-define(wxTreeCtrl_AddRoot, 2002).
+-define(wxTreeCtrl_AppendItem, 2003).
+-define(wxTreeCtrl_AssignImageList, 2004).
+-define(wxTreeCtrl_AssignStateImageList, 2005).
+-define(wxTreeCtrl_Collapse, 2006).
+-define(wxTreeCtrl_CollapseAndReset, 2007).
+-define(wxTreeCtrl_Create, 2008).
+-define(wxTreeCtrl_Delete, 2009).
+-define(wxTreeCtrl_DeleteAllItems, 2010).
+-define(wxTreeCtrl_DeleteChildren, 2011).
+-define(wxTreeCtrl_EnsureVisible, 2012).
+-define(wxTreeCtrl_Expand, 2013).
+-define(wxTreeCtrl_GetBoundingRect, 2014).
+-define(wxTreeCtrl_GetChildrenCount, 2016).
+-define(wxTreeCtrl_GetCount, 2017).
+-define(wxTreeCtrl_GetEditControl, 2018).
+-define(wxTreeCtrl_GetFirstChild, 2019).
+-define(wxTreeCtrl_GetNextChild, 2020).
+-define(wxTreeCtrl_GetFirstVisibleItem, 2021).
+-define(wxTreeCtrl_GetImageList, 2022).
+-define(wxTreeCtrl_GetIndent, 2023).
+-define(wxTreeCtrl_GetItemBackgroundColour, 2024).
+-define(wxTreeCtrl_GetItemData, 2025).
+-define(wxTreeCtrl_GetItemFont, 2026).
+-define(wxTreeCtrl_GetItemImage_1, 2027).
+-define(wxTreeCtrl_GetItemImage_2, 2028).
+-define(wxTreeCtrl_GetItemText, 2029).
+-define(wxTreeCtrl_GetItemTextColour, 2030).
+-define(wxTreeCtrl_GetLastChild, 2031).
+-define(wxTreeCtrl_GetNextSibling, 2032).
+-define(wxTreeCtrl_GetNextVisible, 2033).
+-define(wxTreeCtrl_GetItemParent, 2034).
+-define(wxTreeCtrl_GetPrevSibling, 2035).
+-define(wxTreeCtrl_GetPrevVisible, 2036).
+-define(wxTreeCtrl_GetRootItem, 2037).
+-define(wxTreeCtrl_GetSelection, 2038).
+-define(wxTreeCtrl_GetSelections, 2039).
+-define(wxTreeCtrl_GetStateImageList, 2040).
+-define(wxTreeCtrl_HitTest, 2041).
+-define(wxTreeCtrl_InsertItem, 2043).
+-define(wxTreeCtrl_IsBold, 2044).
+-define(wxTreeCtrl_IsExpanded, 2045).
+-define(wxTreeCtrl_IsSelected, 2046).
+-define(wxTreeCtrl_IsVisible, 2047).
+-define(wxTreeCtrl_ItemHasChildren, 2048).
+-define(wxTreeCtrl_PrependItem, 2049).
+-define(wxTreeCtrl_ScrollTo, 2050).
+-define(wxTreeCtrl_SelectItem_1, 2051).
+-define(wxTreeCtrl_SelectItem_2, 2052).
+-define(wxTreeCtrl_SetIndent, 2053).
+-define(wxTreeCtrl_SetImageList, 2054).
+-define(wxTreeCtrl_SetItemBackgroundColour, 2055).
+-define(wxTreeCtrl_SetItemBold, 2056).
+-define(wxTreeCtrl_SetItemData, 2057).
+-define(wxTreeCtrl_SetItemDropHighlight, 2058).
+-define(wxTreeCtrl_SetItemFont, 2059).
+-define(wxTreeCtrl_SetItemHasChildren, 2060).
+-define(wxTreeCtrl_SetItemImage_2, 2061).
+-define(wxTreeCtrl_SetItemImage_3, 2062).
+-define(wxTreeCtrl_SetItemText, 2063).
+-define(wxTreeCtrl_SetItemTextColour, 2064).
+-define(wxTreeCtrl_SetStateImageList, 2065).
+-define(wxTreeCtrl_SetWindowStyle, 2066).
+-define(wxTreeCtrl_SortChildren, 2067).
+-define(wxTreeCtrl_Toggle, 2068).
+-define(wxTreeCtrl_ToggleItemSelection, 2069).
+-define(wxTreeCtrl_Unselect, 2070).
+-define(wxTreeCtrl_UnselectAll, 2071).
+-define(wxTreeCtrl_UnselectItem, 2072).
+-define(wxScrollBar_new_0, 2073).
+-define(wxScrollBar_new_3, 2074).
+-define(wxScrollBar_destruct, 2075).
+-define(wxScrollBar_Create, 2076).
+-define(wxScrollBar_GetRange, 2077).
+-define(wxScrollBar_GetPageSize, 2078).
+-define(wxScrollBar_GetThumbPosition, 2079).
+-define(wxScrollBar_GetThumbSize, 2080).
+-define(wxScrollBar_SetThumbPosition, 2081).
+-define(wxScrollBar_SetScrollbar, 2082).
+-define(wxSpinButton_new_2, 2084).
+-define(wxSpinButton_new_0, 2085).
+-define(wxSpinButton_Create, 2086).
+-define(wxSpinButton_GetMax, 2087).
+-define(wxSpinButton_GetMin, 2088).
+-define(wxSpinButton_GetValue, 2089).
+-define(wxSpinButton_SetRange, 2090).
+-define(wxSpinButton_SetValue, 2091).
+-define(wxSpinButton_destroy, 2092).
+-define(wxSpinCtrl_new_0, 2093).
+-define(wxSpinCtrl_new_2, 2094).
+-define(wxSpinCtrl_Create, 2096).
+-define(wxSpinCtrl_SetValue_1_1, 2099).
+-define(wxSpinCtrl_SetValue_1_0, 2100).
+-define(wxSpinCtrl_GetValue, 2102).
+-define(wxSpinCtrl_SetRange, 2104).
+-define(wxSpinCtrl_SetSelection, 2105).
+-define(wxSpinCtrl_GetMin, 2107).
+-define(wxSpinCtrl_GetMax, 2109).
+-define(wxSpinCtrl_destroy, 2110).
+-define(wxStaticText_new_0, 2111).
+-define(wxStaticText_new_4, 2112).
+-define(wxStaticText_Create, 2113).
+-define(wxStaticText_GetLabel, 2114).
+-define(wxStaticText_SetLabel, 2115).
+-define(wxStaticText_Wrap, 2116).
+-define(wxStaticText_destroy, 2117).
+-define(wxStaticBitmap_new_0, 2118).
+-define(wxStaticBitmap_new_4, 2119).
+-define(wxStaticBitmap_Create, 2120).
+-define(wxStaticBitmap_GetBitmap, 2121).
+-define(wxStaticBitmap_SetBitmap, 2122).
+-define(wxStaticBitmap_destroy, 2123).
+-define(wxRadioBox_new, 2124).
+-define(wxRadioBox_destruct, 2126).
+-define(wxRadioBox_Create, 2127).
+-define(wxRadioBox_Enable_2, 2128).
+-define(wxRadioBox_Enable_1, 2129).
+-define(wxRadioBox_GetSelection, 2130).
+-define(wxRadioBox_GetString, 2131).
+-define(wxRadioBox_SetSelection, 2132).
+-define(wxRadioBox_Show_2, 2133).
+-define(wxRadioBox_Show_1, 2134).
+-define(wxRadioBox_GetColumnCount, 2135).
+-define(wxRadioBox_GetItemHelpText, 2136).
+-define(wxRadioBox_GetItemToolTip, 2137).
+-define(wxRadioBox_GetItemFromPoint, 2139).
+-define(wxRadioBox_GetRowCount, 2140).
+-define(wxRadioBox_IsItemEnabled, 2141).
+-define(wxRadioBox_IsItemShown, 2142).
+-define(wxRadioBox_SetItemHelpText, 2143).
+-define(wxRadioBox_SetItemToolTip, 2144).
+-define(wxRadioButton_new_0, 2145).
+-define(wxRadioButton_new_4, 2146).
+-define(wxRadioButton_Create, 2147).
+-define(wxRadioButton_GetValue, 2148).
+-define(wxRadioButton_SetValue, 2149).
+-define(wxRadioButton_destroy, 2150).
+-define(wxSlider_new_6, 2152).
+-define(wxSlider_new_0, 2153).
+-define(wxSlider_Create, 2154).
+-define(wxSlider_GetLineSize, 2155).
+-define(wxSlider_GetMax, 2156).
+-define(wxSlider_GetMin, 2157).
+-define(wxSlider_GetPageSize, 2158).
+-define(wxSlider_GetThumbLength, 2159).
+-define(wxSlider_GetValue, 2160).
+-define(wxSlider_SetLineSize, 2161).
+-define(wxSlider_SetPageSize, 2162).
+-define(wxSlider_SetRange, 2163).
+-define(wxSlider_SetThumbLength, 2164).
+-define(wxSlider_SetValue, 2165).
+-define(wxSlider_destroy, 2166).
+-define(wxDialog_new_4, 2168).
+-define(wxDialog_new_0, 2169).
+-define(wxDialog_destruct, 2171).
+-define(wxDialog_Create, 2172).
+-define(wxDialog_CreateButtonSizer, 2173).
+-define(wxDialog_CreateStdDialogButtonSizer, 2174).
+-define(wxDialog_EndModal, 2175).
+-define(wxDialog_GetAffirmativeId, 2176).
+-define(wxDialog_GetReturnCode, 2177).
+-define(wxDialog_IsModal, 2178).
+-define(wxDialog_SetAffirmativeId, 2179).
+-define(wxDialog_SetReturnCode, 2180).
+-define(wxDialog_Show, 2181).
+-define(wxDialog_ShowModal, 2182).
+-define(wxColourDialog_new_0, 2183).
+-define(wxColourDialog_new_2, 2184).
+-define(wxColourDialog_destruct, 2185).
+-define(wxColourDialog_Create, 2186).
+-define(wxColourDialog_GetColourData, 2187).
+-define(wxColourData_new_0, 2188).
+-define(wxColourData_new_1, 2189).
+-define(wxColourData_destruct, 2190).
+-define(wxColourData_GetChooseFull, 2191).
+-define(wxColourData_GetColour, 2192).
+-define(wxColourData_GetCustomColour, 2194).
+-define(wxColourData_SetChooseFull, 2195).
+-define(wxColourData_SetColour, 2196).
+-define(wxColourData_SetCustomColour, 2197).
+-define(wxPalette_new_0, 2198).
+-define(wxPalette_new_4, 2199).
+-define(wxPalette_destruct, 2201).
+-define(wxPalette_Create, 2202).
+-define(wxPalette_GetColoursCount, 2203).
+-define(wxPalette_GetPixel, 2204).
+-define(wxPalette_GetRGB, 2205).
+-define(wxPalette_IsOk, 2206).
+-define(wxDirDialog_new, 2210).
+-define(wxDirDialog_destruct, 2211).
+-define(wxDirDialog_GetPath, 2212).
+-define(wxDirDialog_GetMessage, 2213).
+-define(wxDirDialog_SetMessage, 2214).
+-define(wxDirDialog_SetPath, 2215).
+-define(wxFileDialog_new, 2219).
+-define(wxFileDialog_destruct, 2220).
+-define(wxFileDialog_GetDirectory, 2221).
+-define(wxFileDialog_GetFilename, 2222).
+-define(wxFileDialog_GetFilenames, 2223).
+-define(wxFileDialog_GetFilterIndex, 2224).
+-define(wxFileDialog_GetMessage, 2225).
+-define(wxFileDialog_GetPath, 2226).
+-define(wxFileDialog_GetPaths, 2227).
+-define(wxFileDialog_GetWildcard, 2228).
+-define(wxFileDialog_SetDirectory, 2229).
+-define(wxFileDialog_SetFilename, 2230).
+-define(wxFileDialog_SetFilterIndex, 2231).
+-define(wxFileDialog_SetMessage, 2232).
+-define(wxFileDialog_SetPath, 2233).
+-define(wxFileDialog_SetWildcard, 2234).
+-define(wxPickerBase_SetInternalMargin, 2235).
+-define(wxPickerBase_GetInternalMargin, 2236).
+-define(wxPickerBase_SetTextCtrlProportion, 2237).
+-define(wxPickerBase_SetPickerCtrlProportion, 2238).
+-define(wxPickerBase_GetTextCtrlProportion, 2239).
+-define(wxPickerBase_GetPickerCtrlProportion, 2240).
+-define(wxPickerBase_HasTextCtrl, 2241).
+-define(wxPickerBase_GetTextCtrl, 2242).
+-define(wxPickerBase_IsTextCtrlGrowable, 2243).
+-define(wxPickerBase_SetPickerCtrlGrowable, 2244).
+-define(wxPickerBase_SetTextCtrlGrowable, 2245).
+-define(wxPickerBase_IsPickerCtrlGrowable, 2246).
+-define(wxFilePickerCtrl_new_0, 2247).
+-define(wxFilePickerCtrl_new_3, 2248).
+-define(wxFilePickerCtrl_Create, 2249).
+-define(wxFilePickerCtrl_GetPath, 2250).
+-define(wxFilePickerCtrl_SetPath, 2251).
+-define(wxFilePickerCtrl_destroy, 2252).
+-define(wxDirPickerCtrl_new_0, 2253).
+-define(wxDirPickerCtrl_new_3, 2254).
+-define(wxDirPickerCtrl_Create, 2255).
+-define(wxDirPickerCtrl_GetPath, 2256).
+-define(wxDirPickerCtrl_SetPath, 2257).
+-define(wxDirPickerCtrl_destroy, 2258).
+-define(wxColourPickerCtrl_new_0, 2259).
+-define(wxColourPickerCtrl_new_3, 2260).
+-define(wxColourPickerCtrl_Create, 2261).
+-define(wxColourPickerCtrl_GetColour, 2262).
+-define(wxColourPickerCtrl_SetColour_1_1, 2263).
+-define(wxColourPickerCtrl_SetColour_1_0, 2264).
+-define(wxColourPickerCtrl_destroy, 2265).
+-define(wxDatePickerCtrl_new_0, 2266).
+-define(wxDatePickerCtrl_new_3, 2267).
+-define(wxDatePickerCtrl_GetRange, 2268).
+-define(wxDatePickerCtrl_GetValue, 2269).
+-define(wxDatePickerCtrl_SetRange, 2270).
+-define(wxDatePickerCtrl_SetValue, 2271).
+-define(wxDatePickerCtrl_destroy, 2272).
+-define(wxFontPickerCtrl_new_0, 2273).
+-define(wxFontPickerCtrl_new_3, 2274).
+-define(wxFontPickerCtrl_Create, 2275).
+-define(wxFontPickerCtrl_GetSelectedFont, 2276).
+-define(wxFontPickerCtrl_SetSelectedFont, 2277).
+-define(wxFontPickerCtrl_GetMaxPointSize, 2278).
+-define(wxFontPickerCtrl_SetMaxPointSize, 2279).
+-define(wxFontPickerCtrl_destroy, 2280).
+-define(wxFindReplaceDialog_new_0, 2283).
+-define(wxFindReplaceDialog_new_4, 2284).
+-define(wxFindReplaceDialog_destruct, 2285).
+-define(wxFindReplaceDialog_Create, 2286).
+-define(wxFindReplaceDialog_GetData, 2287).
+-define(wxFindReplaceData_new_0, 2288).
+-define(wxFindReplaceData_new_1, 2289).
+-define(wxFindReplaceData_GetFindString, 2290).
+-define(wxFindReplaceData_GetReplaceString, 2291).
+-define(wxFindReplaceData_GetFlags, 2292).
+-define(wxFindReplaceData_SetFlags, 2293).
+-define(wxFindReplaceData_SetFindString, 2294).
+-define(wxFindReplaceData_SetReplaceString, 2295).
+-define(wxFindReplaceData_destroy, 2296).
+-define(wxMultiChoiceDialog_new_0, 2297).
+-define(wxMultiChoiceDialog_new_5, 2299).
+-define(wxMultiChoiceDialog_GetSelections, 2300).
+-define(wxMultiChoiceDialog_SetSelections, 2301).
+-define(wxMultiChoiceDialog_destroy, 2302).
+-define(wxSingleChoiceDialog_new_0, 2303).
+-define(wxSingleChoiceDialog_new_5, 2305).
+-define(wxSingleChoiceDialog_GetSelection, 2306).
+-define(wxSingleChoiceDialog_GetStringSelection, 2307).
+-define(wxSingleChoiceDialog_SetSelection, 2308).
+-define(wxSingleChoiceDialog_destroy, 2309).
+-define(wxTextEntryDialog_new, 2310).
+-define(wxTextEntryDialog_GetValue, 2311).
+-define(wxTextEntryDialog_SetValue, 2312).
+-define(wxTextEntryDialog_destroy, 2313).
+-define(wxPasswordEntryDialog_new, 2314).
+-define(wxPasswordEntryDialog_destroy, 2315).
+-define(wxFontData_new_0, 2316).
+-define(wxFontData_new_1, 2317).
+-define(wxFontData_destruct, 2318).
+-define(wxFontData_EnableEffects, 2319).
+-define(wxFontData_GetAllowSymbols, 2320).
+-define(wxFontData_GetColour, 2321).
+-define(wxFontData_GetChosenFont, 2322).
+-define(wxFontData_GetEnableEffects, 2323).
+-define(wxFontData_GetInitialFont, 2324).
+-define(wxFontData_GetShowHelp, 2325).
+-define(wxFontData_SetAllowSymbols, 2326).
+-define(wxFontData_SetChosenFont, 2327).
+-define(wxFontData_SetColour, 2328).
+-define(wxFontData_SetInitialFont, 2329).
+-define(wxFontData_SetRange, 2330).
+-define(wxFontData_SetShowHelp, 2331).
+-define(wxFontDialog_new_0, 2335).
+-define(wxFontDialog_new_2, 2337).
+-define(wxFontDialog_Create, 2339).
+-define(wxFontDialog_GetFontData, 2340).
+-define(wxFontDialog_destroy, 2342).
+-define(wxProgressDialog_new, 2343).
+-define(wxProgressDialog_destruct, 2344).
+-define(wxProgressDialog_Resume, 2345).
+-define(wxProgressDialog_Update_2, 2346).
+-define(wxProgressDialog_Update_0, 2347).
+-define(wxMessageDialog_new, 2348).
+-define(wxMessageDialog_destruct, 2349).
+-define(wxPageSetupDialog_new, 2350).
+-define(wxPageSetupDialog_destruct, 2351).
+-define(wxPageSetupDialog_GetPageSetupData, 2352).
+-define(wxPageSetupDialog_ShowModal, 2353).
+-define(wxPageSetupDialogData_new_0, 2354).
+-define(wxPageSetupDialogData_new_1_0, 2355).
+-define(wxPageSetupDialogData_new_1_1, 2356).
+-define(wxPageSetupDialogData_destruct, 2357).
+-define(wxPageSetupDialogData_EnableHelp, 2358).
+-define(wxPageSetupDialogData_EnableMargins, 2359).
+-define(wxPageSetupDialogData_EnableOrientation, 2360).
+-define(wxPageSetupDialogData_EnablePaper, 2361).
+-define(wxPageSetupDialogData_EnablePrinter, 2362).
+-define(wxPageSetupDialogData_GetDefaultMinMargins, 2363).
+-define(wxPageSetupDialogData_GetEnableMargins, 2364).
+-define(wxPageSetupDialogData_GetEnableOrientation, 2365).
+-define(wxPageSetupDialogData_GetEnablePaper, 2366).
+-define(wxPageSetupDialogData_GetEnablePrinter, 2367).
+-define(wxPageSetupDialogData_GetEnableHelp, 2368).
+-define(wxPageSetupDialogData_GetDefaultInfo, 2369).
+-define(wxPageSetupDialogData_GetMarginTopLeft, 2370).
+-define(wxPageSetupDialogData_GetMarginBottomRight, 2371).
+-define(wxPageSetupDialogData_GetMinMarginTopLeft, 2372).
+-define(wxPageSetupDialogData_GetMinMarginBottomRight, 2373).
+-define(wxPageSetupDialogData_GetPaperId, 2374).
+-define(wxPageSetupDialogData_GetPaperSize, 2375).
+-define(wxPageSetupDialogData_GetPrintData, 2377).
+-define(wxPageSetupDialogData_IsOk, 2378).
+-define(wxPageSetupDialogData_SetDefaultInfo, 2379).
+-define(wxPageSetupDialogData_SetDefaultMinMargins, 2380).
+-define(wxPageSetupDialogData_SetMarginTopLeft, 2381).
+-define(wxPageSetupDialogData_SetMarginBottomRight, 2382).
+-define(wxPageSetupDialogData_SetMinMarginTopLeft, 2383).
+-define(wxPageSetupDialogData_SetMinMarginBottomRight, 2384).
+-define(wxPageSetupDialogData_SetPaperId, 2385).
+-define(wxPageSetupDialogData_SetPaperSize_1_1, 2386).
+-define(wxPageSetupDialogData_SetPaperSize_1_0, 2387).
+-define(wxPageSetupDialogData_SetPrintData, 2388).
+-define(wxPrintDialog_new_2_0, 2389).
+-define(wxPrintDialog_new_2_1, 2390).
+-define(wxPrintDialog_destruct, 2391).
+-define(wxPrintDialog_GetPrintDialogData, 2392).
+-define(wxPrintDialog_GetPrintDC, 2393).
+-define(wxPrintDialogData_new_0, 2394).
+-define(wxPrintDialogData_new_1_1, 2395).
+-define(wxPrintDialogData_new_1_0, 2396).
+-define(wxPrintDialogData_destruct, 2397).
+-define(wxPrintDialogData_EnableHelp, 2398).
+-define(wxPrintDialogData_EnablePageNumbers, 2399).
+-define(wxPrintDialogData_EnablePrintToFile, 2400).
+-define(wxPrintDialogData_EnableSelection, 2401).
+-define(wxPrintDialogData_GetAllPages, 2402).
+-define(wxPrintDialogData_GetCollate, 2403).
+-define(wxPrintDialogData_GetFromPage, 2404).
+-define(wxPrintDialogData_GetMaxPage, 2405).
+-define(wxPrintDialogData_GetMinPage, 2406).
+-define(wxPrintDialogData_GetNoCopies, 2407).
+-define(wxPrintDialogData_GetPrintData, 2408).
+-define(wxPrintDialogData_GetPrintToFile, 2409).
+-define(wxPrintDialogData_GetSelection, 2410).
+-define(wxPrintDialogData_GetToPage, 2411).
+-define(wxPrintDialogData_IsOk, 2412).
+-define(wxPrintDialogData_SetCollate, 2413).
+-define(wxPrintDialogData_SetFromPage, 2414).
+-define(wxPrintDialogData_SetMaxPage, 2415).
+-define(wxPrintDialogData_SetMinPage, 2416).
+-define(wxPrintDialogData_SetNoCopies, 2417).
+-define(wxPrintDialogData_SetPrintData, 2418).
+-define(wxPrintDialogData_SetPrintToFile, 2419).
+-define(wxPrintDialogData_SetSelection, 2420).
+-define(wxPrintDialogData_SetToPage, 2421).
+-define(wxPrintData_new_0, 2422).
+-define(wxPrintData_new_1, 2423).
+-define(wxPrintData_destruct, 2424).
+-define(wxPrintData_GetCollate, 2425).
+-define(wxPrintData_GetBin, 2426).
+-define(wxPrintData_GetColour, 2427).
+-define(wxPrintData_GetDuplex, 2428).
+-define(wxPrintData_GetNoCopies, 2429).
+-define(wxPrintData_GetOrientation, 2430).
+-define(wxPrintData_GetPaperId, 2431).
+-define(wxPrintData_GetPrinterName, 2432).
+-define(wxPrintData_GetQuality, 2433).
+-define(wxPrintData_IsOk, 2434).
+-define(wxPrintData_SetBin, 2435).
+-define(wxPrintData_SetCollate, 2436).
+-define(wxPrintData_SetColour, 2437).
+-define(wxPrintData_SetDuplex, 2438).
+-define(wxPrintData_SetNoCopies, 2439).
+-define(wxPrintData_SetOrientation, 2440).
+-define(wxPrintData_SetPaperId, 2441).
+-define(wxPrintData_SetPrinterName, 2442).
+-define(wxPrintData_SetQuality, 2443).
+-define(wxPrintPreview_new_2, 2446).
+-define(wxPrintPreview_new_3, 2447).
+-define(wxPrintPreview_destruct, 2449).
+-define(wxPrintPreview_GetCanvas, 2450).
+-define(wxPrintPreview_GetCurrentPage, 2451).
+-define(wxPrintPreview_GetFrame, 2452).
+-define(wxPrintPreview_GetMaxPage, 2453).
+-define(wxPrintPreview_GetMinPage, 2454).
+-define(wxPrintPreview_GetPrintout, 2455).
+-define(wxPrintPreview_GetPrintoutForPrinting, 2456).
+-define(wxPrintPreview_IsOk, 2457).
+-define(wxPrintPreview_PaintPage, 2458).
+-define(wxPrintPreview_Print, 2459).
+-define(wxPrintPreview_RenderPage, 2460).
+-define(wxPrintPreview_SetCanvas, 2461).
+-define(wxPrintPreview_SetCurrentPage, 2462).
+-define(wxPrintPreview_SetFrame, 2463).
+-define(wxPrintPreview_SetPrintout, 2464).
+-define(wxPrintPreview_SetZoom, 2465).
+-define(wxPreviewFrame_new, 2466).
+-define(wxPreviewFrame_destruct, 2467).
+-define(wxPreviewFrame_CreateControlBar, 2468).
+-define(wxPreviewFrame_CreateCanvas, 2469).
+-define(wxPreviewFrame_Initialize, 2470).
+-define(wxPreviewFrame_OnCloseWindow, 2471).
+-define(wxPreviewControlBar_new, 2472).
+-define(wxPreviewControlBar_destruct, 2473).
+-define(wxPreviewControlBar_CreateButtons, 2474).
+-define(wxPreviewControlBar_GetPrintPreview, 2475).
+-define(wxPreviewControlBar_GetZoomControl, 2476).
+-define(wxPreviewControlBar_SetZoomControl, 2477).
+-define(wxPrinter_new, 2479).
+-define(wxPrinter_CreateAbortWindow, 2480).
+-define(wxPrinter_GetAbort, 2481).
+-define(wxPrinter_GetLastError, 2482).
+-define(wxPrinter_GetPrintDialogData, 2483).
+-define(wxPrinter_Print, 2484).
+-define(wxPrinter_PrintDialog, 2485).
+-define(wxPrinter_ReportError, 2486).
+-define(wxPrinter_Setup, 2487).
+-define(wxPrinter_destroy, 2488).
+-define(wxXmlResource_new_1, 2489).
+-define(wxXmlResource_new_2, 2490).
+-define(wxXmlResource_destruct, 2491).
+-define(wxXmlResource_AttachUnknownControl, 2492).
+-define(wxXmlResource_ClearHandlers, 2493).
+-define(wxXmlResource_CompareVersion, 2494).
+-define(wxXmlResource_Get, 2495).
+-define(wxXmlResource_GetFlags, 2496).
+-define(wxXmlResource_GetVersion, 2497).
+-define(wxXmlResource_GetXRCID, 2498).
+-define(wxXmlResource_InitAllHandlers, 2499).
+-define(wxXmlResource_Load, 2500).
+-define(wxXmlResource_LoadBitmap, 2501).
+-define(wxXmlResource_LoadDialog_2, 2502).
+-define(wxXmlResource_LoadDialog_3, 2503).
+-define(wxXmlResource_LoadFrame_2, 2504).
+-define(wxXmlResource_LoadFrame_3, 2505).
+-define(wxXmlResource_LoadIcon, 2506).
+-define(wxXmlResource_LoadMenu, 2507).
+-define(wxXmlResource_LoadMenuBar_2, 2508).
+-define(wxXmlResource_LoadMenuBar_1, 2509).
+-define(wxXmlResource_LoadPanel_2, 2510).
+-define(wxXmlResource_LoadPanel_3, 2511).
+-define(wxXmlResource_LoadToolBar, 2512).
+-define(wxXmlResource_Set, 2513).
+-define(wxXmlResource_SetFlags, 2514).
+-define(wxXmlResource_Unload, 2515).
+-define(wxXmlResource_xrcctrl, 2516).
+-define(wxHtmlEasyPrinting_new, 2517).
+-define(wxHtmlEasyPrinting_destruct, 2518).
+-define(wxHtmlEasyPrinting_GetPrintData, 2519).
+-define(wxHtmlEasyPrinting_GetPageSetupData, 2520).
+-define(wxHtmlEasyPrinting_PreviewFile, 2521).
+-define(wxHtmlEasyPrinting_PreviewText, 2522).
+-define(wxHtmlEasyPrinting_PrintFile, 2523).
+-define(wxHtmlEasyPrinting_PrintText, 2524).
+-define(wxHtmlEasyPrinting_PageSetup, 2525).
+-define(wxHtmlEasyPrinting_SetFonts, 2526).
+-define(wxHtmlEasyPrinting_SetHeader, 2527).
+-define(wxHtmlEasyPrinting_SetFooter, 2528).
+-define(wxGLCanvas_new_2, 2530).
+-define(wxGLCanvas_new_3_1, 2531).
+-define(wxGLCanvas_new_3_0, 2532).
+-define(wxGLCanvas_GetContext, 2533).
+-define(wxGLCanvas_SetCurrent, 2535).
+-define(wxGLCanvas_SwapBuffers, 2536).
+-define(wxGLCanvas_destroy, 2537).
+-define(wxAuiManager_new, 2538).
+-define(wxAuiManager_destruct, 2539).
+-define(wxAuiManager_AddPane_2_1, 2540).
+-define(wxAuiManager_AddPane_3, 2541).
+-define(wxAuiManager_AddPane_2_0, 2542).
+-define(wxAuiManager_DetachPane, 2543).
+-define(wxAuiManager_GetAllPanes, 2544).
+-define(wxAuiManager_GetArtProvider, 2545).
+-define(wxAuiManager_GetDockSizeConstraint, 2546).
+-define(wxAuiManager_GetFlags, 2547).
+-define(wxAuiManager_GetManagedWindow, 2548).
+-define(wxAuiManager_GetManager, 2549).
+-define(wxAuiManager_GetPane_1_1, 2550).
+-define(wxAuiManager_GetPane_1_0, 2551).
+-define(wxAuiManager_HideHint, 2552).
+-define(wxAuiManager_InsertPane, 2553).
+-define(wxAuiManager_LoadPaneInfo, 2554).
+-define(wxAuiManager_LoadPerspective, 2555).
+-define(wxAuiManager_SavePaneInfo, 2556).
+-define(wxAuiManager_SavePerspective, 2557).
+-define(wxAuiManager_SetArtProvider, 2558).
+-define(wxAuiManager_SetDockSizeConstraint, 2559).
+-define(wxAuiManager_SetFlags, 2560).
+-define(wxAuiManager_SetManagedWindow, 2561).
+-define(wxAuiManager_ShowHint, 2562).
+-define(wxAuiManager_UnInit, 2563).
+-define(wxAuiManager_Update, 2564).
+-define(wxAuiPaneInfo_new_0, 2565).
+-define(wxAuiPaneInfo_new_1, 2566).
+-define(wxAuiPaneInfo_destruct, 2567).
+-define(wxAuiPaneInfo_BestSize_1, 2568).
+-define(wxAuiPaneInfo_BestSize_2, 2569).
+-define(wxAuiPaneInfo_Bottom, 2570).
+-define(wxAuiPaneInfo_BottomDockable, 2571).
+-define(wxAuiPaneInfo_Caption, 2572).
+-define(wxAuiPaneInfo_CaptionVisible, 2573).
+-define(wxAuiPaneInfo_Centre, 2574).
+-define(wxAuiPaneInfo_CentrePane, 2575).
+-define(wxAuiPaneInfo_CloseButton, 2576).
+-define(wxAuiPaneInfo_DefaultPane, 2577).
+-define(wxAuiPaneInfo_DestroyOnClose, 2578).
+-define(wxAuiPaneInfo_Direction, 2579).
+-define(wxAuiPaneInfo_Dock, 2580).
+-define(wxAuiPaneInfo_Dockable, 2581).
+-define(wxAuiPaneInfo_Fixed, 2582).
+-define(wxAuiPaneInfo_Float, 2583).
+-define(wxAuiPaneInfo_Floatable, 2584).
+-define(wxAuiPaneInfo_FloatingPosition_1, 2585).
+-define(wxAuiPaneInfo_FloatingPosition_2, 2586).
+-define(wxAuiPaneInfo_FloatingSize_1, 2587).
+-define(wxAuiPaneInfo_FloatingSize_2, 2588).
+-define(wxAuiPaneInfo_Gripper, 2589).
+-define(wxAuiPaneInfo_GripperTop, 2590).
+-define(wxAuiPaneInfo_HasBorder, 2591).
+-define(wxAuiPaneInfo_HasCaption, 2592).
+-define(wxAuiPaneInfo_HasCloseButton, 2593).
+-define(wxAuiPaneInfo_HasFlag, 2594).
+-define(wxAuiPaneInfo_HasGripper, 2595).
+-define(wxAuiPaneInfo_HasGripperTop, 2596).
+-define(wxAuiPaneInfo_HasMaximizeButton, 2597).
+-define(wxAuiPaneInfo_HasMinimizeButton, 2598).
+-define(wxAuiPaneInfo_HasPinButton, 2599).
+-define(wxAuiPaneInfo_Hide, 2600).
+-define(wxAuiPaneInfo_IsBottomDockable, 2601).
+-define(wxAuiPaneInfo_IsDocked, 2602).
+-define(wxAuiPaneInfo_IsFixed, 2603).
+-define(wxAuiPaneInfo_IsFloatable, 2604).
+-define(wxAuiPaneInfo_IsFloating, 2605).
+-define(wxAuiPaneInfo_IsLeftDockable, 2606).
+-define(wxAuiPaneInfo_IsMovable, 2607).
+-define(wxAuiPaneInfo_IsOk, 2608).
+-define(wxAuiPaneInfo_IsResizable, 2609).
+-define(wxAuiPaneInfo_IsRightDockable, 2610).
+-define(wxAuiPaneInfo_IsShown, 2611).
+-define(wxAuiPaneInfo_IsToolbar, 2612).
+-define(wxAuiPaneInfo_IsTopDockable, 2613).
+-define(wxAuiPaneInfo_Layer, 2614).
+-define(wxAuiPaneInfo_Left, 2615).
+-define(wxAuiPaneInfo_LeftDockable, 2616).
+-define(wxAuiPaneInfo_MaxSize_1, 2617).
+-define(wxAuiPaneInfo_MaxSize_2, 2618).
+-define(wxAuiPaneInfo_MaximizeButton, 2619).
+-define(wxAuiPaneInfo_MinSize_1, 2620).
+-define(wxAuiPaneInfo_MinSize_2, 2621).
+-define(wxAuiPaneInfo_MinimizeButton, 2622).
+-define(wxAuiPaneInfo_Movable, 2623).
+-define(wxAuiPaneInfo_Name, 2624).
+-define(wxAuiPaneInfo_PaneBorder, 2625).
+-define(wxAuiPaneInfo_PinButton, 2626).
+-define(wxAuiPaneInfo_Position, 2627).
+-define(wxAuiPaneInfo_Resizable, 2628).
+-define(wxAuiPaneInfo_Right, 2629).
+-define(wxAuiPaneInfo_RightDockable, 2630).
+-define(wxAuiPaneInfo_Row, 2631).
+-define(wxAuiPaneInfo_SafeSet, 2632).
+-define(wxAuiPaneInfo_SetFlag, 2633).
+-define(wxAuiPaneInfo_Show, 2634).
+-define(wxAuiPaneInfo_ToolbarPane, 2635).
+-define(wxAuiPaneInfo_Top, 2636).
+-define(wxAuiPaneInfo_TopDockable, 2637).
+-define(wxAuiPaneInfo_Window, 2638).
+-define(wxAuiNotebook_new_0, 2639).
+-define(wxAuiNotebook_new_2, 2640).
+-define(wxAuiNotebook_AddPage, 2641).
+-define(wxAuiNotebook_Create, 2642).
+-define(wxAuiNotebook_DeletePage, 2643).
+-define(wxAuiNotebook_GetArtProvider, 2644).
+-define(wxAuiNotebook_GetPage, 2645).
+-define(wxAuiNotebook_GetPageBitmap, 2646).
+-define(wxAuiNotebook_GetPageCount, 2647).
+-define(wxAuiNotebook_GetPageIndex, 2648).
+-define(wxAuiNotebook_GetPageText, 2649).
+-define(wxAuiNotebook_GetSelection, 2650).
+-define(wxAuiNotebook_InsertPage, 2651).
+-define(wxAuiNotebook_RemovePage, 2652).
+-define(wxAuiNotebook_SetArtProvider, 2653).
+-define(wxAuiNotebook_SetFont, 2654).
+-define(wxAuiNotebook_SetPageBitmap, 2655).
+-define(wxAuiNotebook_SetPageText, 2656).
+-define(wxAuiNotebook_SetSelection, 2657).
+-define(wxAuiNotebook_SetTabCtrlHeight, 2658).
+-define(wxAuiNotebook_SetUniformBitmapSize, 2659).
+-define(wxAuiNotebook_destroy, 2660).
+-define(wxMDIParentFrame_new_0, 2661).
+-define(wxMDIParentFrame_new_4, 2662).
+-define(wxMDIParentFrame_destruct, 2663).
+-define(wxMDIParentFrame_ActivateNext, 2664).
+-define(wxMDIParentFrame_ActivatePrevious, 2665).
+-define(wxMDIParentFrame_ArrangeIcons, 2666).
+-define(wxMDIParentFrame_Cascade, 2667).
+-define(wxMDIParentFrame_Create, 2668).
+-define(wxMDIParentFrame_GetActiveChild, 2669).
+-define(wxMDIParentFrame_GetClientWindow, 2670).
+-define(wxMDIParentFrame_Tile, 2671).
+-define(wxMDIChildFrame_new_0, 2672).
+-define(wxMDIChildFrame_new_4, 2673).
+-define(wxMDIChildFrame_destruct, 2674).
+-define(wxMDIChildFrame_Activate, 2675).
+-define(wxMDIChildFrame_Create, 2676).
+-define(wxMDIChildFrame_Maximize, 2677).
+-define(wxMDIChildFrame_Restore, 2678).
+-define(wxMDIClientWindow_new_0, 2679).
+-define(wxMDIClientWindow_new_2, 2680).
+-define(wxMDIClientWindow_destruct, 2681).
+-define(wxMDIClientWindow_CreateClient, 2682).
+-define(wxLayoutAlgorithm_new, 2683).
+-define(wxLayoutAlgorithm_LayoutFrame, 2684).
+-define(wxLayoutAlgorithm_LayoutMDIFrame, 2685).
+-define(wxLayoutAlgorithm_LayoutWindow, 2686).
+-define(wxLayoutAlgorithm_destroy, 2687).
+-define(wxEvent_GetId, 2688).
+-define(wxEvent_GetSkipped, 2689).
+-define(wxEvent_GetTimestamp, 2690).
+-define(wxEvent_IsCommandEvent, 2691).
+-define(wxEvent_ResumePropagation, 2692).
+-define(wxEvent_ShouldPropagate, 2693).
+-define(wxEvent_Skip, 2694).
+-define(wxEvent_StopPropagation, 2695).
+-define(wxCommandEvent_getClientData, 2696).
+-define(wxCommandEvent_GetExtraLong, 2697).
+-define(wxCommandEvent_GetInt, 2698).
+-define(wxCommandEvent_GetSelection, 2699).
+-define(wxCommandEvent_GetString, 2700).
+-define(wxCommandEvent_IsChecked, 2701).
+-define(wxCommandEvent_IsSelection, 2702).
+-define(wxCommandEvent_SetInt, 2703).
+-define(wxCommandEvent_SetString, 2704).
+-define(wxScrollEvent_GetOrientation, 2705).
+-define(wxScrollEvent_GetPosition, 2706).
+-define(wxScrollWinEvent_GetOrientation, 2707).
+-define(wxScrollWinEvent_GetPosition, 2708).
+-define(wxMouseEvent_AltDown, 2709).
+-define(wxMouseEvent_Button, 2710).
+-define(wxMouseEvent_ButtonDClick, 2711).
+-define(wxMouseEvent_ButtonDown, 2712).
+-define(wxMouseEvent_ButtonUp, 2713).
+-define(wxMouseEvent_CmdDown, 2714).
+-define(wxMouseEvent_ControlDown, 2715).
+-define(wxMouseEvent_Dragging, 2716).
+-define(wxMouseEvent_Entering, 2717).
+-define(wxMouseEvent_GetButton, 2718).
+-define(wxMouseEvent_GetPosition, 2721).
+-define(wxMouseEvent_GetLogicalPosition, 2722).
+-define(wxMouseEvent_GetLinesPerAction, 2723).
+-define(wxMouseEvent_GetWheelRotation, 2724).
+-define(wxMouseEvent_GetWheelDelta, 2725).
+-define(wxMouseEvent_GetX, 2726).
+-define(wxMouseEvent_GetY, 2727).
+-define(wxMouseEvent_IsButton, 2728).
+-define(wxMouseEvent_IsPageScroll, 2729).
+-define(wxMouseEvent_Leaving, 2730).
+-define(wxMouseEvent_LeftDClick, 2731).
+-define(wxMouseEvent_LeftDown, 2732).
+-define(wxMouseEvent_LeftIsDown, 2733).
+-define(wxMouseEvent_LeftUp, 2734).
+-define(wxMouseEvent_MetaDown, 2735).
+-define(wxMouseEvent_MiddleDClick, 2736).
+-define(wxMouseEvent_MiddleDown, 2737).
+-define(wxMouseEvent_MiddleIsDown, 2738).
+-define(wxMouseEvent_MiddleUp, 2739).
+-define(wxMouseEvent_Moving, 2740).
+-define(wxMouseEvent_RightDClick, 2741).
+-define(wxMouseEvent_RightDown, 2742).
+-define(wxMouseEvent_RightIsDown, 2743).
+-define(wxMouseEvent_RightUp, 2744).
+-define(wxMouseEvent_ShiftDown, 2745).
+-define(wxSetCursorEvent_GetCursor, 2746).
+-define(wxSetCursorEvent_GetX, 2747).
+-define(wxSetCursorEvent_GetY, 2748).
+-define(wxSetCursorEvent_HasCursor, 2749).
+-define(wxSetCursorEvent_SetCursor, 2750).
+-define(wxKeyEvent_AltDown, 2751).
+-define(wxKeyEvent_CmdDown, 2752).
+-define(wxKeyEvent_ControlDown, 2753).
+-define(wxKeyEvent_GetKeyCode, 2754).
+-define(wxKeyEvent_GetModifiers, 2755).
+-define(wxKeyEvent_GetPosition, 2758).
+-define(wxKeyEvent_GetRawKeyCode, 2759).
+-define(wxKeyEvent_GetRawKeyFlags, 2760).
+-define(wxKeyEvent_GetUnicodeKey, 2761).
+-define(wxKeyEvent_GetX, 2762).
+-define(wxKeyEvent_GetY, 2763).
+-define(wxKeyEvent_HasModifiers, 2764).
+-define(wxKeyEvent_MetaDown, 2765).
+-define(wxKeyEvent_ShiftDown, 2766).
+-define(wxSizeEvent_GetSize, 2767).
+-define(wxMoveEvent_GetPosition, 2768).
+-define(wxEraseEvent_GetDC, 2769).
+-define(wxFocusEvent_GetWindow, 2770).
+-define(wxChildFocusEvent_GetWindow, 2771).
+-define(wxMenuEvent_GetMenu, 2772).
+-define(wxMenuEvent_GetMenuId, 2773).
+-define(wxMenuEvent_IsPopup, 2774).
+-define(wxCloseEvent_CanVeto, 2775).
+-define(wxCloseEvent_GetLoggingOff, 2776).
+-define(wxCloseEvent_SetCanVeto, 2777).
+-define(wxCloseEvent_SetLoggingOff, 2778).
+-define(wxCloseEvent_Veto, 2779).
+-define(wxShowEvent_SetShow, 2780).
+-define(wxShowEvent_GetShow, 2781).
+-define(wxIconizeEvent_Iconized, 2782).
+-define(wxJoystickEvent_ButtonDown, 2783).
+-define(wxJoystickEvent_ButtonIsDown, 2784).
+-define(wxJoystickEvent_ButtonUp, 2785).
+-define(wxJoystickEvent_GetButtonChange, 2786).
+-define(wxJoystickEvent_GetButtonState, 2787).
+-define(wxJoystickEvent_GetJoystick, 2788).
+-define(wxJoystickEvent_GetPosition, 2789).
+-define(wxJoystickEvent_GetZPosition, 2790).
+-define(wxJoystickEvent_IsButton, 2791).
+-define(wxJoystickEvent_IsMove, 2792).
+-define(wxJoystickEvent_IsZMove, 2793).
+-define(wxUpdateUIEvent_CanUpdate, 2794).
+-define(wxUpdateUIEvent_Check, 2795).
+-define(wxUpdateUIEvent_Enable, 2796).
+-define(wxUpdateUIEvent_Show, 2797).
+-define(wxUpdateUIEvent_GetChecked, 2798).
+-define(wxUpdateUIEvent_GetEnabled, 2799).
+-define(wxUpdateUIEvent_GetShown, 2800).
+-define(wxUpdateUIEvent_GetSetChecked, 2801).
+-define(wxUpdateUIEvent_GetSetEnabled, 2802).
+-define(wxUpdateUIEvent_GetSetShown, 2803).
+-define(wxUpdateUIEvent_GetSetText, 2804).
+-define(wxUpdateUIEvent_GetText, 2805).
+-define(wxUpdateUIEvent_GetMode, 2806).
+-define(wxUpdateUIEvent_GetUpdateInterval, 2807).
+-define(wxUpdateUIEvent_ResetUpdateTime, 2808).
+-define(wxUpdateUIEvent_SetMode, 2809).
+-define(wxUpdateUIEvent_SetText, 2810).
+-define(wxUpdateUIEvent_SetUpdateInterval, 2811).
+-define(wxMouseCaptureChangedEvent_GetCapturedWindow, 2812).
+-define(wxPaletteChangedEvent_SetChangedWindow, 2813).
+-define(wxPaletteChangedEvent_GetChangedWindow, 2814).
+-define(wxQueryNewPaletteEvent_SetPaletteRealized, 2815).
+-define(wxQueryNewPaletteEvent_GetPaletteRealized, 2816).
+-define(wxNavigationKeyEvent_GetDirection, 2817).
+-define(wxNavigationKeyEvent_SetDirection, 2818).
+-define(wxNavigationKeyEvent_IsWindowChange, 2819).
+-define(wxNavigationKeyEvent_SetWindowChange, 2820).
+-define(wxNavigationKeyEvent_IsFromTab, 2821).
+-define(wxNavigationKeyEvent_SetFromTab, 2822).
+-define(wxNavigationKeyEvent_GetCurrentFocus, 2823).
+-define(wxNavigationKeyEvent_SetCurrentFocus, 2824).
+-define(wxHelpEvent_GetOrigin, 2825).
+-define(wxHelpEvent_GetPosition, 2826).
+-define(wxHelpEvent_SetOrigin, 2827).
+-define(wxHelpEvent_SetPosition, 2828).
+-define(wxContextMenuEvent_GetPosition, 2829).
+-define(wxContextMenuEvent_SetPosition, 2830).
+-define(wxIdleEvent_CanSend, 2831).
+-define(wxIdleEvent_GetMode, 2832).
+-define(wxIdleEvent_RequestMore, 2833).
+-define(wxIdleEvent_MoreRequested, 2834).
+-define(wxIdleEvent_SetMode, 2835).
+-define(wxGridEvent_AltDown, 2836).
+-define(wxGridEvent_ControlDown, 2837).
+-define(wxGridEvent_GetCol, 2838).
+-define(wxGridEvent_GetPosition, 2839).
+-define(wxGridEvent_GetRow, 2840).
+-define(wxGridEvent_MetaDown, 2841).
+-define(wxGridEvent_Selecting, 2842).
+-define(wxGridEvent_ShiftDown, 2843).
+-define(wxNotifyEvent_Allow, 2844).
+-define(wxNotifyEvent_IsAllowed, 2845).
+-define(wxNotifyEvent_Veto, 2846).
+-define(wxSashEvent_GetEdge, 2847).
+-define(wxSashEvent_GetDragRect, 2848).
+-define(wxSashEvent_GetDragStatus, 2849).
+-define(wxListEvent_GetCacheFrom, 2850).
+-define(wxListEvent_GetCacheTo, 2851).
+-define(wxListEvent_GetKeyCode, 2852).
+-define(wxListEvent_GetIndex, 2853).
+-define(wxListEvent_GetColumn, 2854).
+-define(wxListEvent_GetPoint, 2855).
+-define(wxListEvent_GetLabel, 2856).
+-define(wxListEvent_GetText, 2857).
+-define(wxListEvent_GetImage, 2858).
+-define(wxListEvent_GetData, 2859).
+-define(wxListEvent_GetMask, 2860).
+-define(wxListEvent_GetItem, 2861).
+-define(wxListEvent_IsEditCancelled, 2862).
+-define(wxDateEvent_GetDate, 2863).
+-define(wxCalendarEvent_GetWeekDay, 2864).
+-define(wxFileDirPickerEvent_GetPath, 2865).
+-define(wxColourPickerEvent_GetColour, 2866).
+-define(wxFontPickerEvent_GetFont, 2867).
+-define(wxStyledTextEvent_GetPosition, 2868).
+-define(wxStyledTextEvent_GetKey, 2869).
+-define(wxStyledTextEvent_GetModifiers, 2870).
+-define(wxStyledTextEvent_GetModificationType, 2871).
+-define(wxStyledTextEvent_GetText, 2872).
+-define(wxStyledTextEvent_GetLength, 2873).
+-define(wxStyledTextEvent_GetLinesAdded, 2874).
+-define(wxStyledTextEvent_GetLine, 2875).
+-define(wxStyledTextEvent_GetFoldLevelNow, 2876).
+-define(wxStyledTextEvent_GetFoldLevelPrev, 2877).
+-define(wxStyledTextEvent_GetMargin, 2878).
+-define(wxStyledTextEvent_GetMessage, 2879).
+-define(wxStyledTextEvent_GetWParam, 2880).
+-define(wxStyledTextEvent_GetLParam, 2881).
+-define(wxStyledTextEvent_GetListType, 2882).
+-define(wxStyledTextEvent_GetX, 2883).
+-define(wxStyledTextEvent_GetY, 2884).
+-define(wxStyledTextEvent_GetDragText, 2885).
+-define(wxStyledTextEvent_GetDragAllowMove, 2886).
+-define(wxStyledTextEvent_GetDragResult, 2887).
+-define(wxStyledTextEvent_GetShift, 2888).
+-define(wxStyledTextEvent_GetControl, 2889).
+-define(wxStyledTextEvent_GetAlt, 2890).
+-define(utils_wxGetKeyState, 2891).
+-define(utils_wxGetMousePosition, 2892).
+-define(utils_wxGetMouseState, 2893).
+-define(utils_wxSetDetectableAutoRepeat, 2894).
+-define(utils_wxBell, 2895).
+-define(utils_wxFindMenuItemId, 2896).
+-define(utils_wxGenericFindWindowAtPoint, 2897).
+-define(utils_wxFindWindowAtPoint, 2898).
+-define(utils_wxBeginBusyCursor, 2899).
+-define(utils_wxEndBusyCursor, 2900).
+-define(utils_wxIsBusy, 2901).
+-define(utils_wxShutdown, 2902).
+-define(utils_wxShell, 2903).
+-define(utils_wxLaunchDefaultBrowser, 2904).
+-define(utils_wxGetEmailAddress, 2905).
+-define(utils_wxGetUserId, 2906).
+-define(utils_wxGetHomeDir, 2907).
+-define(utils_wxNewId, 2908).
+-define(utils_wxRegisterId, 2909).
+-define(utils_wxGetCurrentId, 2910).
+-define(utils_wxGetOsDescription, 2911).
+-define(utils_wxIsPlatformLittleEndian, 2912).
+-define(utils_wxIsPlatform64Bit, 2913).
+-define(wxPrintout_new, 2914).
+-define(wxPrintout_destruct, 2915).
+-define(wxPrintout_GetDC, 2916).
+-define(wxPrintout_GetPageSizeMM, 2917).
+-define(wxPrintout_GetPageSizePixels, 2918).
+-define(wxPrintout_GetPaperRectPixels, 2919).
+-define(wxPrintout_GetPPIPrinter, 2920).
+-define(wxPrintout_GetPPIScreen, 2921).
+-define(wxPrintout_GetTitle, 2922).
+-define(wxPrintout_IsPreview, 2923).
+-define(wxPrintout_FitThisSizeToPaper, 2924).
+-define(wxPrintout_FitThisSizeToPage, 2925).
+-define(wxPrintout_FitThisSizeToPageMargins, 2926).
+-define(wxPrintout_MapScreenSizeToPaper, 2927).
+-define(wxPrintout_MapScreenSizeToPage, 2928).
+-define(wxPrintout_MapScreenSizeToPageMargins, 2929).
+-define(wxPrintout_MapScreenSizeToDevice, 2930).
+-define(wxPrintout_GetLogicalPaperRect, 2931).
+-define(wxPrintout_GetLogicalPageRect, 2932).
+-define(wxPrintout_GetLogicalPageMarginsRect, 2933).
+-define(wxPrintout_SetLogicalOrigin, 2934).
+-define(wxPrintout_OffsetLogicalOrigin, 2935).
+-define(wxStyledTextCtrl_new_2, 2936).
+-define(wxStyledTextCtrl_new_0, 2937).
+-define(wxStyledTextCtrl_destruct, 2938).
+-define(wxStyledTextCtrl_Create, 2939).
+-define(wxStyledTextCtrl_AddText, 2940).
+-define(wxStyledTextCtrl_AddStyledText, 2941).
+-define(wxStyledTextCtrl_InsertText, 2942).
+-define(wxStyledTextCtrl_ClearAll, 2943).
+-define(wxStyledTextCtrl_ClearDocumentStyle, 2944).
+-define(wxStyledTextCtrl_GetLength, 2945).
+-define(wxStyledTextCtrl_GetCharAt, 2946).
+-define(wxStyledTextCtrl_GetCurrentPos, 2947).
+-define(wxStyledTextCtrl_GetAnchor, 2948).
+-define(wxStyledTextCtrl_GetStyleAt, 2949).
+-define(wxStyledTextCtrl_Redo, 2950).
+-define(wxStyledTextCtrl_SetUndoCollection, 2951).
+-define(wxStyledTextCtrl_SelectAll, 2952).
+-define(wxStyledTextCtrl_SetSavePoint, 2953).
+-define(wxStyledTextCtrl_GetStyledText, 2954).
+-define(wxStyledTextCtrl_CanRedo, 2955).
+-define(wxStyledTextCtrl_MarkerLineFromHandle, 2956).
+-define(wxStyledTextCtrl_MarkerDeleteHandle, 2957).
+-define(wxStyledTextCtrl_GetUndoCollection, 2958).
+-define(wxStyledTextCtrl_GetViewWhiteSpace, 2959).
+-define(wxStyledTextCtrl_SetViewWhiteSpace, 2960).
+-define(wxStyledTextCtrl_PositionFromPoint, 2961).
+-define(wxStyledTextCtrl_PositionFromPointClose, 2962).
+-define(wxStyledTextCtrl_GotoLine, 2963).
+-define(wxStyledTextCtrl_GotoPos, 2964).
+-define(wxStyledTextCtrl_SetAnchor, 2965).
+-define(wxStyledTextCtrl_GetCurLine, 2966).
+-define(wxStyledTextCtrl_GetEndStyled, 2967).
+-define(wxStyledTextCtrl_ConvertEOLs, 2968).
+-define(wxStyledTextCtrl_GetEOLMode, 2969).
+-define(wxStyledTextCtrl_SetEOLMode, 2970).
+-define(wxStyledTextCtrl_StartStyling, 2971).
+-define(wxStyledTextCtrl_SetStyling, 2972).
+-define(wxStyledTextCtrl_GetBufferedDraw, 2973).
+-define(wxStyledTextCtrl_SetBufferedDraw, 2974).
+-define(wxStyledTextCtrl_SetTabWidth, 2975).
+-define(wxStyledTextCtrl_GetTabWidth, 2976).
+-define(wxStyledTextCtrl_SetCodePage, 2977).
+-define(wxStyledTextCtrl_MarkerDefine, 2978).
+-define(wxStyledTextCtrl_MarkerSetForeground, 2979).
+-define(wxStyledTextCtrl_MarkerSetBackground, 2980).
+-define(wxStyledTextCtrl_MarkerAdd, 2981).
+-define(wxStyledTextCtrl_MarkerDelete, 2982).
+-define(wxStyledTextCtrl_MarkerDeleteAll, 2983).
+-define(wxStyledTextCtrl_MarkerGet, 2984).
+-define(wxStyledTextCtrl_MarkerNext, 2985).
+-define(wxStyledTextCtrl_MarkerPrevious, 2986).
+-define(wxStyledTextCtrl_MarkerDefineBitmap, 2987).
+-define(wxStyledTextCtrl_MarkerAddSet, 2988).
+-define(wxStyledTextCtrl_MarkerSetAlpha, 2989).
+-define(wxStyledTextCtrl_SetMarginType, 2990).
+-define(wxStyledTextCtrl_GetMarginType, 2991).
+-define(wxStyledTextCtrl_SetMarginWidth, 2992).
+-define(wxStyledTextCtrl_GetMarginWidth, 2993).
+-define(wxStyledTextCtrl_SetMarginMask, 2994).
+-define(wxStyledTextCtrl_GetMarginMask, 2995).
+-define(wxStyledTextCtrl_SetMarginSensitive, 2996).
+-define(wxStyledTextCtrl_GetMarginSensitive, 2997).
+-define(wxStyledTextCtrl_StyleClearAll, 2998).
+-define(wxStyledTextCtrl_StyleSetForeground, 2999).
+-define(wxStyledTextCtrl_StyleSetBackground, 3000).
+-define(wxStyledTextCtrl_StyleSetBold, 3001).
+-define(wxStyledTextCtrl_StyleSetItalic, 3002).
+-define(wxStyledTextCtrl_StyleSetSize, 3003).
+-define(wxStyledTextCtrl_StyleSetFaceName, 3004).
+-define(wxStyledTextCtrl_StyleSetEOLFilled, 3005).
+-define(wxStyledTextCtrl_StyleResetDefault, 3006).
+-define(wxStyledTextCtrl_StyleSetUnderline, 3007).
+-define(wxStyledTextCtrl_StyleSetCase, 3008).
+-define(wxStyledTextCtrl_StyleSetHotSpot, 3009).
+-define(wxStyledTextCtrl_SetSelForeground, 3010).
+-define(wxStyledTextCtrl_SetSelBackground, 3011).
+-define(wxStyledTextCtrl_GetSelAlpha, 3012).
+-define(wxStyledTextCtrl_SetSelAlpha, 3013).
+-define(wxStyledTextCtrl_SetCaretForeground, 3014).
+-define(wxStyledTextCtrl_CmdKeyAssign, 3015).
+-define(wxStyledTextCtrl_CmdKeyClear, 3016).
+-define(wxStyledTextCtrl_CmdKeyClearAll, 3017).
+-define(wxStyledTextCtrl_SetStyleBytes, 3018).
+-define(wxStyledTextCtrl_StyleSetVisible, 3019).
+-define(wxStyledTextCtrl_GetCaretPeriod, 3020).
+-define(wxStyledTextCtrl_SetCaretPeriod, 3021).
+-define(wxStyledTextCtrl_SetWordChars, 3022).
+-define(wxStyledTextCtrl_BeginUndoAction, 3023).
+-define(wxStyledTextCtrl_EndUndoAction, 3024).
+-define(wxStyledTextCtrl_IndicatorSetStyle, 3025).
+-define(wxStyledTextCtrl_IndicatorGetStyle, 3026).
+-define(wxStyledTextCtrl_IndicatorSetForeground, 3027).
+-define(wxStyledTextCtrl_IndicatorGetForeground, 3028).
+-define(wxStyledTextCtrl_SetWhitespaceForeground, 3029).
+-define(wxStyledTextCtrl_SetWhitespaceBackground, 3030).
+-define(wxStyledTextCtrl_GetStyleBits, 3031).
+-define(wxStyledTextCtrl_SetLineState, 3032).
+-define(wxStyledTextCtrl_GetLineState, 3033).
+-define(wxStyledTextCtrl_GetMaxLineState, 3034).
+-define(wxStyledTextCtrl_GetCaretLineVisible, 3035).
+-define(wxStyledTextCtrl_SetCaretLineVisible, 3036).
+-define(wxStyledTextCtrl_GetCaretLineBackground, 3037).
+-define(wxStyledTextCtrl_SetCaretLineBackground, 3038).
+-define(wxStyledTextCtrl_AutoCompShow, 3039).
+-define(wxStyledTextCtrl_AutoCompCancel, 3040).
+-define(wxStyledTextCtrl_AutoCompActive, 3041).
+-define(wxStyledTextCtrl_AutoCompPosStart, 3042).
+-define(wxStyledTextCtrl_AutoCompComplete, 3043).
+-define(wxStyledTextCtrl_AutoCompStops, 3044).
+-define(wxStyledTextCtrl_AutoCompSetSeparator, 3045).
+-define(wxStyledTextCtrl_AutoCompGetSeparator, 3046).
+-define(wxStyledTextCtrl_AutoCompSelect, 3047).
+-define(wxStyledTextCtrl_AutoCompSetCancelAtStart, 3048).
+-define(wxStyledTextCtrl_AutoCompGetCancelAtStart, 3049).
+-define(wxStyledTextCtrl_AutoCompSetFillUps, 3050).
+-define(wxStyledTextCtrl_AutoCompSetChooseSingle, 3051).
+-define(wxStyledTextCtrl_AutoCompGetChooseSingle, 3052).
+-define(wxStyledTextCtrl_AutoCompSetIgnoreCase, 3053).
+-define(wxStyledTextCtrl_AutoCompGetIgnoreCase, 3054).
+-define(wxStyledTextCtrl_UserListShow, 3055).
+-define(wxStyledTextCtrl_AutoCompSetAutoHide, 3056).
+-define(wxStyledTextCtrl_AutoCompGetAutoHide, 3057).
+-define(wxStyledTextCtrl_AutoCompSetDropRestOfWord, 3058).
+-define(wxStyledTextCtrl_AutoCompGetDropRestOfWord, 3059).
+-define(wxStyledTextCtrl_RegisterImage, 3060).
+-define(wxStyledTextCtrl_ClearRegisteredImages, 3061).
+-define(wxStyledTextCtrl_AutoCompGetTypeSeparator, 3062).
+-define(wxStyledTextCtrl_AutoCompSetTypeSeparator, 3063).
+-define(wxStyledTextCtrl_AutoCompSetMaxWidth, 3064).
+-define(wxStyledTextCtrl_AutoCompGetMaxWidth, 3065).
+-define(wxStyledTextCtrl_AutoCompSetMaxHeight, 3066).
+-define(wxStyledTextCtrl_AutoCompGetMaxHeight, 3067).
+-define(wxStyledTextCtrl_SetIndent, 3068).
+-define(wxStyledTextCtrl_GetIndent, 3069).
+-define(wxStyledTextCtrl_SetUseTabs, 3070).
+-define(wxStyledTextCtrl_GetUseTabs, 3071).
+-define(wxStyledTextCtrl_SetLineIndentation, 3072).
+-define(wxStyledTextCtrl_GetLineIndentation, 3073).
+-define(wxStyledTextCtrl_GetLineIndentPosition, 3074).
+-define(wxStyledTextCtrl_GetColumn, 3075).
+-define(wxStyledTextCtrl_SetUseHorizontalScrollBar, 3076).
+-define(wxStyledTextCtrl_GetUseHorizontalScrollBar, 3077).
+-define(wxStyledTextCtrl_SetIndentationGuides, 3078).
+-define(wxStyledTextCtrl_GetIndentationGuides, 3079).
+-define(wxStyledTextCtrl_SetHighlightGuide, 3080).
+-define(wxStyledTextCtrl_GetHighlightGuide, 3081).
+-define(wxStyledTextCtrl_GetLineEndPosition, 3082).
+-define(wxStyledTextCtrl_GetCodePage, 3083).
+-define(wxStyledTextCtrl_GetCaretForeground, 3084).
+-define(wxStyledTextCtrl_GetReadOnly, 3085).
+-define(wxStyledTextCtrl_SetCurrentPos, 3086).
+-define(wxStyledTextCtrl_SetSelectionStart, 3087).
+-define(wxStyledTextCtrl_GetSelectionStart, 3088).
+-define(wxStyledTextCtrl_SetSelectionEnd, 3089).
+-define(wxStyledTextCtrl_GetSelectionEnd, 3090).
+-define(wxStyledTextCtrl_SetPrintMagnification, 3091).
+-define(wxStyledTextCtrl_GetPrintMagnification, 3092).
+-define(wxStyledTextCtrl_SetPrintColourMode, 3093).
+-define(wxStyledTextCtrl_GetPrintColourMode, 3094).
+-define(wxStyledTextCtrl_FindText, 3095).
+-define(wxStyledTextCtrl_FormatRange, 3096).
+-define(wxStyledTextCtrl_GetFirstVisibleLine, 3097).
+-define(wxStyledTextCtrl_GetLine, 3098).
+-define(wxStyledTextCtrl_GetLineCount, 3099).
+-define(wxStyledTextCtrl_SetMarginLeft, 3100).
+-define(wxStyledTextCtrl_GetMarginLeft, 3101).
+-define(wxStyledTextCtrl_SetMarginRight, 3102).
+-define(wxStyledTextCtrl_GetMarginRight, 3103).
+-define(wxStyledTextCtrl_GetModify, 3104).
+-define(wxStyledTextCtrl_SetSelection, 3105).
+-define(wxStyledTextCtrl_GetSelectedText, 3106).
+-define(wxStyledTextCtrl_GetTextRange, 3107).
+-define(wxStyledTextCtrl_HideSelection, 3108).
+-define(wxStyledTextCtrl_LineFromPosition, 3109).
+-define(wxStyledTextCtrl_PositionFromLine, 3110).
+-define(wxStyledTextCtrl_LineScroll, 3111).
+-define(wxStyledTextCtrl_EnsureCaretVisible, 3112).
+-define(wxStyledTextCtrl_ReplaceSelection, 3113).
+-define(wxStyledTextCtrl_SetReadOnly, 3114).
+-define(wxStyledTextCtrl_CanPaste, 3115).
+-define(wxStyledTextCtrl_CanUndo, 3116).
+-define(wxStyledTextCtrl_EmptyUndoBuffer, 3117).
+-define(wxStyledTextCtrl_Undo, 3118).
+-define(wxStyledTextCtrl_Cut, 3119).
+-define(wxStyledTextCtrl_Copy, 3120).
+-define(wxStyledTextCtrl_Paste, 3121).
+-define(wxStyledTextCtrl_Clear, 3122).
+-define(wxStyledTextCtrl_SetText, 3123).
+-define(wxStyledTextCtrl_GetText, 3124).
+-define(wxStyledTextCtrl_GetTextLength, 3125).
+-define(wxStyledTextCtrl_GetOvertype, 3126).
+-define(wxStyledTextCtrl_SetCaretWidth, 3127).
+-define(wxStyledTextCtrl_GetCaretWidth, 3128).
+-define(wxStyledTextCtrl_SetTargetStart, 3129).
+-define(wxStyledTextCtrl_GetTargetStart, 3130).
+-define(wxStyledTextCtrl_SetTargetEnd, 3131).
+-define(wxStyledTextCtrl_GetTargetEnd, 3132).
+-define(wxStyledTextCtrl_ReplaceTarget, 3133).
+-define(wxStyledTextCtrl_SearchInTarget, 3134).
+-define(wxStyledTextCtrl_SetSearchFlags, 3135).
+-define(wxStyledTextCtrl_GetSearchFlags, 3136).
+-define(wxStyledTextCtrl_CallTipShow, 3137).
+-define(wxStyledTextCtrl_CallTipCancel, 3138).
+-define(wxStyledTextCtrl_CallTipActive, 3139).
+-define(wxStyledTextCtrl_CallTipPosAtStart, 3140).
+-define(wxStyledTextCtrl_CallTipSetHighlight, 3141).
+-define(wxStyledTextCtrl_CallTipSetBackground, 3142).
+-define(wxStyledTextCtrl_CallTipSetForeground, 3143).
+-define(wxStyledTextCtrl_CallTipSetForegroundHighlight, 3144).
+-define(wxStyledTextCtrl_CallTipUseStyle, 3145).
+-define(wxStyledTextCtrl_VisibleFromDocLine, 3146).
+-define(wxStyledTextCtrl_DocLineFromVisible, 3147).
+-define(wxStyledTextCtrl_WrapCount, 3148).
+-define(wxStyledTextCtrl_SetFoldLevel, 3149).
+-define(wxStyledTextCtrl_GetFoldLevel, 3150).
+-define(wxStyledTextCtrl_GetLastChild, 3151).
+-define(wxStyledTextCtrl_GetFoldParent, 3152).
+-define(wxStyledTextCtrl_ShowLines, 3153).
+-define(wxStyledTextCtrl_HideLines, 3154).
+-define(wxStyledTextCtrl_GetLineVisible, 3155).
+-define(wxStyledTextCtrl_SetFoldExpanded, 3156).
+-define(wxStyledTextCtrl_GetFoldExpanded, 3157).
+-define(wxStyledTextCtrl_ToggleFold, 3158).
+-define(wxStyledTextCtrl_EnsureVisible, 3159).
+-define(wxStyledTextCtrl_SetFoldFlags, 3160).
+-define(wxStyledTextCtrl_EnsureVisibleEnforcePolicy, 3161).
+-define(wxStyledTextCtrl_SetTabIndents, 3162).
+-define(wxStyledTextCtrl_GetTabIndents, 3163).
+-define(wxStyledTextCtrl_SetBackSpaceUnIndents, 3164).
+-define(wxStyledTextCtrl_GetBackSpaceUnIndents, 3165).
+-define(wxStyledTextCtrl_SetMouseDwellTime, 3166).
+-define(wxStyledTextCtrl_GetMouseDwellTime, 3167).
+-define(wxStyledTextCtrl_WordStartPosition, 3168).
+-define(wxStyledTextCtrl_WordEndPosition, 3169).
+-define(wxStyledTextCtrl_SetWrapMode, 3170).
+-define(wxStyledTextCtrl_GetWrapMode, 3171).
+-define(wxStyledTextCtrl_SetWrapVisualFlags, 3172).
+-define(wxStyledTextCtrl_GetWrapVisualFlags, 3173).
+-define(wxStyledTextCtrl_SetWrapVisualFlagsLocation, 3174).
+-define(wxStyledTextCtrl_GetWrapVisualFlagsLocation, 3175).
+-define(wxStyledTextCtrl_SetWrapStartIndent, 3176).
+-define(wxStyledTextCtrl_GetWrapStartIndent, 3177).
+-define(wxStyledTextCtrl_SetLayoutCache, 3178).
+-define(wxStyledTextCtrl_GetLayoutCache, 3179).
+-define(wxStyledTextCtrl_SetScrollWidth, 3180).
+-define(wxStyledTextCtrl_GetScrollWidth, 3181).
+-define(wxStyledTextCtrl_TextWidth, 3182).
+-define(wxStyledTextCtrl_GetEndAtLastLine, 3183).
+-define(wxStyledTextCtrl_TextHeight, 3184).
+-define(wxStyledTextCtrl_SetUseVerticalScrollBar, 3185).
+-define(wxStyledTextCtrl_GetUseVerticalScrollBar, 3186).
+-define(wxStyledTextCtrl_AppendText, 3187).
+-define(wxStyledTextCtrl_GetTwoPhaseDraw, 3188).
+-define(wxStyledTextCtrl_SetTwoPhaseDraw, 3189).
+-define(wxStyledTextCtrl_TargetFromSelection, 3190).
+-define(wxStyledTextCtrl_LinesJoin, 3191).
+-define(wxStyledTextCtrl_LinesSplit, 3192).
+-define(wxStyledTextCtrl_SetFoldMarginColour, 3193).
+-define(wxStyledTextCtrl_SetFoldMarginHiColour, 3194).
+-define(wxStyledTextCtrl_LineDown, 3195).
+-define(wxStyledTextCtrl_LineDownExtend, 3196).
+-define(wxStyledTextCtrl_LineUp, 3197).
+-define(wxStyledTextCtrl_LineUpExtend, 3198).
+-define(wxStyledTextCtrl_CharLeft, 3199).
+-define(wxStyledTextCtrl_CharLeftExtend, 3200).
+-define(wxStyledTextCtrl_CharRight, 3201).
+-define(wxStyledTextCtrl_CharRightExtend, 3202).
+-define(wxStyledTextCtrl_WordLeft, 3203).
+-define(wxStyledTextCtrl_WordLeftExtend, 3204).
+-define(wxStyledTextCtrl_WordRight, 3205).
+-define(wxStyledTextCtrl_WordRightExtend, 3206).
+-define(wxStyledTextCtrl_Home, 3207).
+-define(wxStyledTextCtrl_HomeExtend, 3208).
+-define(wxStyledTextCtrl_LineEnd, 3209).
+-define(wxStyledTextCtrl_LineEndExtend, 3210).
+-define(wxStyledTextCtrl_DocumentStart, 3211).
+-define(wxStyledTextCtrl_DocumentStartExtend, 3212).
+-define(wxStyledTextCtrl_DocumentEnd, 3213).
+-define(wxStyledTextCtrl_DocumentEndExtend, 3214).
+-define(wxStyledTextCtrl_PageUp, 3215).
+-define(wxStyledTextCtrl_PageUpExtend, 3216).
+-define(wxStyledTextCtrl_PageDown, 3217).
+-define(wxStyledTextCtrl_PageDownExtend, 3218).
+-define(wxStyledTextCtrl_EditToggleOvertype, 3219).
+-define(wxStyledTextCtrl_Cancel, 3220).
+-define(wxStyledTextCtrl_DeleteBack, 3221).
+-define(wxStyledTextCtrl_Tab, 3222).
+-define(wxStyledTextCtrl_BackTab, 3223).
+-define(wxStyledTextCtrl_NewLine, 3224).
+-define(wxStyledTextCtrl_FormFeed, 3225).
+-define(wxStyledTextCtrl_VCHome, 3226).
+-define(wxStyledTextCtrl_VCHomeExtend, 3227).
+-define(wxStyledTextCtrl_ZoomIn, 3228).
+-define(wxStyledTextCtrl_ZoomOut, 3229).
+-define(wxStyledTextCtrl_DelWordLeft, 3230).
+-define(wxStyledTextCtrl_DelWordRight, 3231).
+-define(wxStyledTextCtrl_LineCut, 3232).
+-define(wxStyledTextCtrl_LineDelete, 3233).
+-define(wxStyledTextCtrl_LineTranspose, 3234).
+-define(wxStyledTextCtrl_LineDuplicate, 3235).
+-define(wxStyledTextCtrl_LowerCase, 3236).
+-define(wxStyledTextCtrl_UpperCase, 3237).
+-define(wxStyledTextCtrl_LineScrollDown, 3238).
+-define(wxStyledTextCtrl_LineScrollUp, 3239).
+-define(wxStyledTextCtrl_DeleteBackNotLine, 3240).
+-define(wxStyledTextCtrl_HomeDisplay, 3241).
+-define(wxStyledTextCtrl_HomeDisplayExtend, 3242).
+-define(wxStyledTextCtrl_LineEndDisplay, 3243).
+-define(wxStyledTextCtrl_LineEndDisplayExtend, 3244).
+-define(wxStyledTextCtrl_HomeWrapExtend, 3245).
+-define(wxStyledTextCtrl_LineEndWrap, 3246).
+-define(wxStyledTextCtrl_LineEndWrapExtend, 3247).
+-define(wxStyledTextCtrl_VCHomeWrap, 3248).
+-define(wxStyledTextCtrl_VCHomeWrapExtend, 3249).
+-define(wxStyledTextCtrl_LineCopy, 3250).
+-define(wxStyledTextCtrl_MoveCaretInsideView, 3251).
+-define(wxStyledTextCtrl_LineLength, 3252).
+-define(wxStyledTextCtrl_BraceHighlight, 3253).
+-define(wxStyledTextCtrl_BraceBadLight, 3254).
+-define(wxStyledTextCtrl_BraceMatch, 3255).
+-define(wxStyledTextCtrl_GetViewEOL, 3256).
+-define(wxStyledTextCtrl_SetViewEOL, 3257).
+-define(wxStyledTextCtrl_SetModEventMask, 3258).
+-define(wxStyledTextCtrl_GetEdgeColumn, 3259).
+-define(wxStyledTextCtrl_SetEdgeColumn, 3260).
+-define(wxStyledTextCtrl_GetEdgeMode, 3261).
+-define(wxStyledTextCtrl_GetEdgeColour, 3262).
+-define(wxStyledTextCtrl_SetEdgeColour, 3263).
+-define(wxStyledTextCtrl_SearchAnchor, 3264).
+-define(wxStyledTextCtrl_SearchNext, 3265).
+-define(wxStyledTextCtrl_SearchPrev, 3266).
+-define(wxStyledTextCtrl_LinesOnScreen, 3267).
+-define(wxStyledTextCtrl_UsePopUp, 3268).
+-define(wxStyledTextCtrl_SelectionIsRectangle, 3269).
+-define(wxStyledTextCtrl_SetZoom, 3270).
+-define(wxStyledTextCtrl_GetZoom, 3271).
+-define(wxStyledTextCtrl_GetModEventMask, 3272).
+-define(wxStyledTextCtrl_SetSTCFocus, 3273).
+-define(wxStyledTextCtrl_GetSTCFocus, 3274).
+-define(wxStyledTextCtrl_SetStatus, 3275).
+-define(wxStyledTextCtrl_GetStatus, 3276).
+-define(wxStyledTextCtrl_SetMouseDownCaptures, 3277).
+-define(wxStyledTextCtrl_GetMouseDownCaptures, 3278).
+-define(wxStyledTextCtrl_SetSTCCursor, 3279).
+-define(wxStyledTextCtrl_GetSTCCursor, 3280).
+-define(wxStyledTextCtrl_SetControlCharSymbol, 3281).
+-define(wxStyledTextCtrl_GetControlCharSymbol, 3282).
+-define(wxStyledTextCtrl_WordPartLeft, 3283).
+-define(wxStyledTextCtrl_WordPartLeftExtend, 3284).
+-define(wxStyledTextCtrl_WordPartRight, 3285).
+-define(wxStyledTextCtrl_WordPartRightExtend, 3286).
+-define(wxStyledTextCtrl_SetVisiblePolicy, 3287).
+-define(wxStyledTextCtrl_DelLineLeft, 3288).
+-define(wxStyledTextCtrl_DelLineRight, 3289).
+-define(wxStyledTextCtrl_GetXOffset, 3290).
+-define(wxStyledTextCtrl_ChooseCaretX, 3291).
+-define(wxStyledTextCtrl_SetXCaretPolicy, 3292).
+-define(wxStyledTextCtrl_SetYCaretPolicy, 3293).
+-define(wxStyledTextCtrl_GetPrintWrapMode, 3294).
+-define(wxStyledTextCtrl_SetHotspotActiveForeground, 3295).
+-define(wxStyledTextCtrl_SetHotspotActiveBackground, 3296).
+-define(wxStyledTextCtrl_SetHotspotActiveUnderline, 3297).
+-define(wxStyledTextCtrl_SetHotspotSingleLine, 3298).
+-define(wxStyledTextCtrl_ParaDownExtend, 3299).
+-define(wxStyledTextCtrl_ParaUp, 3300).
+-define(wxStyledTextCtrl_ParaUpExtend, 3301).
+-define(wxStyledTextCtrl_PositionBefore, 3302).
+-define(wxStyledTextCtrl_PositionAfter, 3303).
+-define(wxStyledTextCtrl_CopyRange, 3304).
+-define(wxStyledTextCtrl_CopyText, 3305).
+-define(wxStyledTextCtrl_SetSelectionMode, 3306).
+-define(wxStyledTextCtrl_GetSelectionMode, 3307).
+-define(wxStyledTextCtrl_LineDownRectExtend, 3308).
+-define(wxStyledTextCtrl_LineUpRectExtend, 3309).
+-define(wxStyledTextCtrl_CharLeftRectExtend, 3310).
+-define(wxStyledTextCtrl_CharRightRectExtend, 3311).
+-define(wxStyledTextCtrl_HomeRectExtend, 3312).
+-define(wxStyledTextCtrl_VCHomeRectExtend, 3313).
+-define(wxStyledTextCtrl_LineEndRectExtend, 3314).
+-define(wxStyledTextCtrl_PageUpRectExtend, 3315).
+-define(wxStyledTextCtrl_PageDownRectExtend, 3316).
+-define(wxStyledTextCtrl_StutteredPageUp, 3317).
+-define(wxStyledTextCtrl_StutteredPageUpExtend, 3318).
+-define(wxStyledTextCtrl_StutteredPageDown, 3319).
+-define(wxStyledTextCtrl_StutteredPageDownExtend, 3320).
+-define(wxStyledTextCtrl_WordLeftEnd, 3321).
+-define(wxStyledTextCtrl_WordLeftEndExtend, 3322).
+-define(wxStyledTextCtrl_WordRightEnd, 3323).
+-define(wxStyledTextCtrl_WordRightEndExtend, 3324).
+-define(wxStyledTextCtrl_SetWhitespaceChars, 3325).
+-define(wxStyledTextCtrl_SetCharsDefault, 3326).
+-define(wxStyledTextCtrl_AutoCompGetCurrent, 3327).
+-define(wxStyledTextCtrl_Allocate, 3328).
+-define(wxStyledTextCtrl_FindColumn, 3329).
+-define(wxStyledTextCtrl_GetCaretSticky, 3330).
+-define(wxStyledTextCtrl_SetCaretSticky, 3331).
+-define(wxStyledTextCtrl_ToggleCaretSticky, 3332).
+-define(wxStyledTextCtrl_SetPasteConvertEndings, 3333).
+-define(wxStyledTextCtrl_GetPasteConvertEndings, 3334).
+-define(wxStyledTextCtrl_SelectionDuplicate, 3335).
+-define(wxStyledTextCtrl_SetCaretLineBackAlpha, 3336).
+-define(wxStyledTextCtrl_GetCaretLineBackAlpha, 3337).
+-define(wxStyledTextCtrl_StartRecord, 3338).
+-define(wxStyledTextCtrl_StopRecord, 3339).
+-define(wxStyledTextCtrl_SetLexer, 3340).
+-define(wxStyledTextCtrl_GetLexer, 3341).
+-define(wxStyledTextCtrl_Colourise, 3342).
+-define(wxStyledTextCtrl_SetProperty, 3343).
+-define(wxStyledTextCtrl_SetKeyWords, 3344).
+-define(wxStyledTextCtrl_SetLexerLanguage, 3345).
+-define(wxStyledTextCtrl_GetProperty, 3346).
+-define(wxStyledTextCtrl_GetStyleBitsNeeded, 3347).
+-define(wxStyledTextCtrl_GetCurrentLine, 3348).
+-define(wxStyledTextCtrl_StyleSetSpec, 3349).
+-define(wxStyledTextCtrl_StyleSetFont, 3350).
+-define(wxStyledTextCtrl_StyleSetFontAttr, 3351).
+-define(wxStyledTextCtrl_StyleSetCharacterSet, 3352).
+-define(wxStyledTextCtrl_StyleSetFontEncoding, 3353).
+-define(wxStyledTextCtrl_CmdKeyExecute, 3354).
+-define(wxStyledTextCtrl_SetMargins, 3355).
+-define(wxStyledTextCtrl_GetSelection, 3356).
+-define(wxStyledTextCtrl_PointFromPosition, 3357).
+-define(wxStyledTextCtrl_ScrollToLine, 3358).
+-define(wxStyledTextCtrl_ScrollToColumn, 3359).
+-define(wxStyledTextCtrl_SendMsg, 3360).
+-define(wxStyledTextCtrl_SetVScrollBar, 3361).
+-define(wxStyledTextCtrl_SetHScrollBar, 3362).
+-define(wxStyledTextCtrl_GetLastKeydownProcessed, 3363).
+-define(wxStyledTextCtrl_SetLastKeydownProcessed, 3364).
+-define(wxStyledTextCtrl_SaveFile, 3365).
+-define(wxStyledTextCtrl_LoadFile, 3366).
+-define(wxStyledTextCtrl_DoDragOver, 3367).
+-define(wxStyledTextCtrl_DoDropText, 3368).
+-define(wxStyledTextCtrl_GetUseAntiAliasing, 3369).
+-define(wxStyledTextCtrl_AddTextRaw, 3370).
+-define(wxStyledTextCtrl_InsertTextRaw, 3371).
+-define(wxStyledTextCtrl_GetCurLineRaw, 3372).
+-define(wxStyledTextCtrl_GetLineRaw, 3373).
+-define(wxStyledTextCtrl_GetSelectedTextRaw, 3374).
+-define(wxStyledTextCtrl_GetTextRangeRaw, 3375).
+-define(wxStyledTextCtrl_SetTextRaw, 3376).
+-define(wxStyledTextCtrl_GetTextRaw, 3377).
+-define(wxStyledTextCtrl_AppendTextRaw, 3378).
+-define(wxArtProvider_GetBitmap, 3379).
+-define(wxArtProvider_GetIcon, 3380).
+-define(wxTreeEvent_GetKeyCode, 3381).
+-define(wxTreeEvent_GetItem, 3382).
+-define(wxTreeEvent_GetKeyEvent, 3383).
+-define(wxTreeEvent_GetLabel, 3384).
+-define(wxTreeEvent_GetOldItem, 3385).
+-define(wxTreeEvent_GetPoint, 3386).
+-define(wxTreeEvent_IsEditCancelled, 3387).
+-define(wxTreeEvent_SetToolTip, 3388).
+-define(wxNotebookEvent_GetOldSelection, 3389).
+-define(wxNotebookEvent_GetSelection, 3390).
+-define(wxNotebookEvent_SetOldSelection, 3391).
+-define(wxNotebookEvent_SetSelection, 3392).
+-define(wxFileDataObject_new, 3393).
+-define(wxFileDataObject_AddFile, 3394).
+-define(wxFileDataObject_GetFilenames, 3395).
+-define(wxFileDataObject_destroy, 3396).
+-define(wxTextDataObject_new, 3397).
+-define(wxTextDataObject_GetTextLength, 3398).
+-define(wxTextDataObject_GetText, 3399).
+-define(wxTextDataObject_SetText, 3400).
+-define(wxTextDataObject_destroy, 3401).
+-define(wxBitmapDataObject_new_1_1, 3402).
+-define(wxBitmapDataObject_new_1_0, 3403).
+-define(wxBitmapDataObject_GetBitmap, 3404).
+-define(wxBitmapDataObject_SetBitmap, 3405).
+-define(wxBitmapDataObject_destroy, 3406).
+-define(wxClipboard_new, 3408).
+-define(wxClipboard_destruct, 3409).
+-define(wxClipboard_AddData, 3410).
+-define(wxClipboard_Clear, 3411).
+-define(wxClipboard_Close, 3412).
+-define(wxClipboard_Flush, 3413).
+-define(wxClipboard_GetData, 3414).
+-define(wxClipboard_IsOpened, 3415).
+-define(wxClipboard_Open, 3416).
+-define(wxClipboard_SetData, 3417).
+-define(wxClipboard_UsePrimarySelection, 3419).
+-define(wxClipboard_IsSupported, 3420).
+-define(wxClipboard_Get, 3421).
+-define(wxSpinEvent_GetPosition, 3422).
+-define(wxSpinEvent_SetPosition, 3423).
+-define(wxSplitterWindow_new_0, 3424).
+-define(wxSplitterWindow_new_2, 3425).
+-define(wxSplitterWindow_destruct, 3426).
+-define(wxSplitterWindow_Create, 3427).
+-define(wxSplitterWindow_GetMinimumPaneSize, 3428).
+-define(wxSplitterWindow_GetSashGravity, 3429).
+-define(wxSplitterWindow_GetSashPosition, 3430).
+-define(wxSplitterWindow_GetSplitMode, 3431).
+-define(wxSplitterWindow_GetWindow1, 3432).
+-define(wxSplitterWindow_GetWindow2, 3433).
+-define(wxSplitterWindow_Initialize, 3434).
+-define(wxSplitterWindow_IsSplit, 3435).
+-define(wxSplitterWindow_ReplaceWindow, 3436).
+-define(wxSplitterWindow_SetSashGravity, 3437).
+-define(wxSplitterWindow_SetSashPosition, 3438).
+-define(wxSplitterWindow_SetSashSize, 3439).
+-define(wxSplitterWindow_SetMinimumPaneSize, 3440).
+-define(wxSplitterWindow_SetSplitMode, 3441).
+-define(wxSplitterWindow_SplitHorizontally, 3442).
+-define(wxSplitterWindow_SplitVertically, 3443).
+-define(wxSplitterWindow_Unsplit, 3444).
+-define(wxSplitterWindow_UpdateSize, 3445).
+-define(wxSplitterEvent_GetSashPosition, 3446).
+-define(wxSplitterEvent_GetX, 3447).
+-define(wxSplitterEvent_GetY, 3448).
+-define(wxSplitterEvent_GetWindowBeingRemoved, 3449).
+-define(wxSplitterEvent_SetSashPosition, 3450).
+-define(wxHtmlWindow_new_0, 3451).
+-define(wxHtmlWindow_new_2, 3452).
+-define(wxHtmlWindow_AppendToPage, 3453).
+-define(wxHtmlWindow_GetOpenedAnchor, 3454).
+-define(wxHtmlWindow_GetOpenedPage, 3455).
+-define(wxHtmlWindow_GetOpenedPageTitle, 3456).
+-define(wxHtmlWindow_GetRelatedFrame, 3457).
+-define(wxHtmlWindow_HistoryBack, 3458).
+-define(wxHtmlWindow_HistoryCanBack, 3459).
+-define(wxHtmlWindow_HistoryCanForward, 3460).
+-define(wxHtmlWindow_HistoryClear, 3461).
+-define(wxHtmlWindow_HistoryForward, 3462).
+-define(wxHtmlWindow_LoadFile, 3463).
+-define(wxHtmlWindow_LoadPage, 3464).
+-define(wxHtmlWindow_SelectAll, 3465).
+-define(wxHtmlWindow_SelectionToText, 3466).
+-define(wxHtmlWindow_SelectLine, 3467).
+-define(wxHtmlWindow_SelectWord, 3468).
+-define(wxHtmlWindow_SetBorders, 3469).
+-define(wxHtmlWindow_SetFonts, 3470).
+-define(wxHtmlWindow_SetPage, 3471).
+-define(wxHtmlWindow_SetRelatedFrame, 3472).
+-define(wxHtmlWindow_SetRelatedStatusBar, 3473).
+-define(wxHtmlWindow_ToText, 3474).
+-define(wxHtmlWindow_destroy, 3475).
+-define(wxHtmlLinkEvent_GetLinkInfo, 3476).
+-define(wxAuiNotebookEvent_SetSelection, 3477).
+-define(wxAuiNotebookEvent_GetSelection, 3478).
+-define(wxAuiNotebookEvent_SetOldSelection, 3479).
+-define(wxAuiNotebookEvent_GetOldSelection, 3480).
+-define(wxAuiNotebookEvent_SetDragSource, 3481).
+-define(wxAuiNotebookEvent_GetDragSource, 3482).
+-define(wxAuiManagerEvent_SetManager, 3483).
+-define(wxAuiManagerEvent_GetManager, 3484).
+-define(wxAuiManagerEvent_SetPane, 3485).
+-define(wxAuiManagerEvent_GetPane, 3486).
+-define(wxAuiManagerEvent_SetButton, 3487).
+-define(wxAuiManagerEvent_GetButton, 3488).
+-define(wxAuiManagerEvent_SetDC, 3489).
+-define(wxAuiManagerEvent_GetDC, 3490).
+-define(wxAuiManagerEvent_Veto, 3491).
+-define(wxAuiManagerEvent_GetVeto, 3492).
+-define(wxAuiManagerEvent_SetCanVeto, 3493).
+-define(wxAuiManagerEvent_CanVeto, 3494).
+-define(wxLogNull_new, 3495).
+-define(wxLogNull_destroy, 3496).
diff --git a/lib/wx/test/wx_class_SUITE.erl b/lib/wx/test/wx_class_SUITE.erl
index cedbd1ef19..76df6e4a23 100644
--- a/lib/wx/test/wx_class_SUITE.erl
+++ b/lib/wx/test/wx_class_SUITE.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%
%%%-------------------------------------------------------------------
%%% File : wx_class_SUITE.erl
@@ -113,12 +113,14 @@ treeCtrl(Config) ->
Frame = wxFrame:new(Wx, ?wxID_ANY, "Frame"),
Panel = wxPanel:new(Frame, []),
Tree = ?mt(wxTreeCtrl,wxTreeCtrl:new(Panel, [{style , ?wxTR_HAS_BUTTONS}])),
- Root = ?mt(wxTreeItemId, wxTreeCtrl:addRoot(Tree, "Root", [])),
- Item1 = ?mt(wxTreeItemId, wxTreeCtrl:appendItem(Tree, Root, "Item1", [])),
- ?m(ok, wxTreeCtrl:setItemData(Tree, Item1, {data, item1})),
- Item2 = ?mt(wxTreeItemId, wxTreeCtrl:appendItem(Tree, Root, "Item2", [])),
- ?m(ok, wxTreeCtrl:setItemData(Tree, Item2, {data, item2})),
- Item3 = ?mt(wxTreeItemId, wxTreeCtrl:appendItem(Tree, Root, "Item3", [])),
+ Root = wxTreeCtrl:addRoot(Tree, "Root", []),
+ ?m(true, is_integer(Root)),
+ Item1 = wxTreeCtrl:appendItem(Tree, Root, "Item1", []),
+ ?m(true, is_integer(Item1)),
+ ?m(ok, wxTreeCtrl:setItemData(Tree, Item1, {data, item1})),
+ Item2 = wxTreeCtrl:appendItem(Tree, Root, "Item2", []),
+ ?m(ok, wxTreeCtrl:setItemData(Tree, Item2, {data, item2})),
+ Item3 = wxTreeCtrl:appendItem(Tree, Root, "Item3", []),
?m(ok, wxTreeCtrl:setItemData(Tree, Item3, {data, item3})),
Sizer = wxBoxSizer:new(?wxVERTICAL),
@@ -359,6 +361,14 @@ listCtrlSort(Config) ->
Time = timer:tc(erlang, apply, [Sort,[]]),
io:format("Sorted ~p ~n",[Time]),
+ Item = wxListItem:new(),
+ _List = wx:map(fun(Int) ->
+ wxListItem:setId(Item, Int),
+ ?m(true, wxListCtrl:getItem(LC, Item)),
+ io:format("~s~n",[wxListItem:getText(Item)])
+ end, lists:seq(0,100)),
+ wxListItem:destroy(Item),
+
wx_test_lib:wx_destroy(Frame,Config).
@@ -373,7 +383,7 @@ radioBox(Config) ->
io:format("TrSortRadioBox ~p ~n", [TrSortRadioBox]),
%% If I uncomment any of these lines, it will crash
- ?m(_, catch wxControlWithItems:setClientData(TrSortRadioBox, 0, timestamp)),
+ io:format("~p~n", [catch wxControlWithItems:setClientData(TrSortRadioBox, 0, timestamp)]),
%?m(_, wxListBox:append(TrSortRadioBox, "Session Id", session_id)),
%?m(_, wxListBox:insert(TrSortRadioBox, "Session Id", 0, session_id)),
diff --git a/lib/wx/test/wx_xtra_SUITE.erl b/lib/wx/test/wx_xtra_SUITE.erl
index 2ce1d18039..d5888bbf94 100644
--- a/lib/wx/test/wx_xtra_SUITE.erl
+++ b/lib/wx/test/wx_xtra_SUITE.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%
%%%-------------------------------------------------------------------
%%% File : wx_basic_SUITE.erl
@@ -51,7 +51,8 @@ all(suite) ->
[
destroy_app,
multiple_add_in_sizer,
- app_dies
+ app_dies,
+ menu_item_debug
].
%% The test cases
@@ -68,10 +69,11 @@ destroy_app_test(N) when N > 0 ->
Wx = ?mr(wx_ref, wx:new()),
Frame = wxFrame:new(Wx, 1, "Destroy"),
?m(ok, wxFrame:destroy(Frame)),
- wx:destroy(),
receive
Msg -> Msg
- after 150 -> destroy_app_test(N-1)
+ after 150 ->
+ wx:destroy(),
+ destroy_app_test(N-1)
end;
destroy_app_test(_) ->
receive
@@ -174,3 +176,57 @@ multiple_add_in_sizer(Config) ->
wxWindow:show(Frame),
wx_test_lib:wx_destroy(Frame, Config).
+menu_item_debug(TestInfo) when is_atom(TestInfo) -> wx_test_lib:tc_info(TestInfo);
+menu_item_debug(Config) ->
+ %% Debugging a menu entry problem
+ %% Run it with: lists:map(fun(_) -> [{0,{ok,_,_}}] = wxt:t() end, lists:seq(1,50)), ok.
+ Wx = wx:new(),
+ wx:debug(trace),
+ Frame = wxFrame:new(Wx, -1, "Button Fix"),
+ wxFrame:connect(Frame, close_window),
+
+ wxPanel:new(Frame),
+ create_menus(Frame),
+ wxWindow:show(Frame),
+ wx_test_lib:wx_destroy(Frame,Config).
+
+
+create_menus(Frame) ->
+ MenuBar = ?mt(wxMenuBar, wxMenuBar:new()),
+ File = ?mt(wxMenu, wxMenu:new([])),
+ Help = ?mt(wxMenu, wxMenu:new([])),
+
+ ?mt(wxMenuItem, wxMenu:append(Help, ?wxID_ABOUT, "&About", [])),
+ ?mt(wxMenuItem, wxMenu:append(Help, ?wxID_HELP, "&Help", [])),
+ ?mt(wxMenuItem, wxMenu:append(File, ?wxID_EXIT, "Exit", [])),
+ T1 = ?mt(wxMenu, wxMenu:new([])),
+ [wxMenuItem:getId(wxMenu:append(T1, Id, integer_to_list(Id), []))
+ || Id <- lists:seq(100, 120)],
+ T2 = ?mt(wxMenu, wxMenu:new([])),
+ [wxMenuItem:getId(wxMenu:append(T2, Id, integer_to_list(Id), []))
+ || Id <- lists:seq(200, 220)],
+ T3 = ?mt(wxMenu, wxMenu:new([])),
+ [wxMenuItem:getId(wxMenu:append(T3, Id, integer_to_list(Id), []))
+ || Id <- lists:seq(300, 320)],
+ T4 = ?mt(wxMenu, wxMenu:new([])),
+ [wxMenuItem:getId(wxMenu:append(T4, Id, integer_to_list(Id), []))
+ || Id <- lists:seq(400, 420)],
+ T5 = ?mt(wxMenu, wxMenu:new([])),
+ [wxMenuItem:getId(wxMenu:append(T5, Id, integer_to_list(Id), []))
+ || Id <- lists:seq(500, 520)],
+ T6 = ?mt(wxMenu, wxMenu:new([])),
+ [wxMenuItem:getId(wxMenu:append(T6, Id, integer_to_list(Id), []))
+ || Id <- lists:seq(600, 620)],
+
+ ?m(ok,wxFrame:connect(Frame, command_menu_selected)),
+ ?m(true, wxMenuBar:append(MenuBar, File, "&File")),
+ ?m(true, wxMenuBar:append(MenuBar, Help, "&Help")),
+ ?m(true, wxMenuBar:append(MenuBar, T1, "T1")),
+ ?m(true, wxMenuBar:append(MenuBar, T2, "T2")),
+ ?m(true, wxMenuBar:append(MenuBar, T3, "T3")),
+ ?m(true, wxMenuBar:append(MenuBar, T4, "T4")),
+ ?m(true, wxMenuBar:append(MenuBar, T5, "T5")),
+ ?m(true, wxMenuBar:append(MenuBar, T6, "T6")),
+
+
+ ?m(ok, wxFrame:setMenuBar(Frame,MenuBar)).
diff --git a/lib/wx/test/wxt.erl b/lib/wx/test/wxt.erl
index a346a6bdb8..1f5b1cc3b1 100644
--- a/lib/wx/test/wxt.erl
+++ b/lib/wx/test/wxt.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%
%%%-------------------------------------------------------------------
%%% File : wxt.erl
@@ -58,16 +58,16 @@ user(Mod,Tc) when is_atom(Tc) ->
%% Resolves the name of test suites and test cases
%% according to the alias definitions. Single atoms
%% are assumed to be the name of a test suite.
-resolve(Suite0) when atom(Suite0) ->
+resolve(Suite0) when is_atom(Suite0) ->
case alias(Suite0) of
- Suite when atom(Suite) ->
+ Suite when is_atom(Suite) ->
{Suite, all};
{Suite, Case} ->
{Suite, Case}
end;
-resolve({Suite0, Case}) when atom(Suite0), atom(Case) ->
+resolve({Suite0, Case}) when is_atom(Suite0), is_atom(Case) ->
case alias(Suite0) of
- Suite when atom(Suite) ->
+ Suite when is_atom(Suite) ->
{Suite, Case};
{Suite, Case2} ->
{Suite, Case2}
diff --git a/lib/wx/vsn.mk b/lib/wx/vsn.mk
index 91bbdc8c99..54ab92cad2 100644
--- a/lib/wx/vsn.mk
+++ b/lib/wx/vsn.mk
@@ -1,6 +1,7 @@
-WX_VSN = 0.98.4
+WX_VSN = 0.98.5
-TICKETS = OTP-8243 OTP-8250 OTP-8292
+TICKETS = OTP-8330 OTP-8461 OTP-8408 OTP-8455 OTP-8462
+TICKETS_0.98.4 = OTP-8243 OTP-8250 OTP-8292
TICKETS_0.98.3 = OTP-8138 OTP-8126 OTP-8083
TICKETS_0.98.2 = OTP-7943
TICKETS_0.98.1 = OTP-7875 \ No newline at end of file
diff --git a/lib/xmerl/doc/src/Makefile b/lib/xmerl/doc/src/Makefile
index e26e77eb96..100a2feb0a 100644
--- a/lib/xmerl/doc/src/Makefile
+++ b/lib/xmerl/doc/src/Makefile
@@ -1,19 +1,19 @@
#
# %CopyrightBegin%
-#
-# Copyright Ericsson AB 2004-2009. All Rights Reserved.
-#
+#
+# Copyright Ericsson AB 2004-2010. All Rights Reserved.
+#
# The contents of this file are subject to the Erlang Public License,
# Version 1.1, (the "License"); you may not use this file except in
# compliance with the License. You should have received a copy of the
# Erlang Public License along with this software. If not, it can be
# retrieved online at http://www.erlang.org/.
-#
+#
# Software distributed under the License is distributed on an "AS IS"
# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
# the License for the specific language governing rights and limitations
# under the License.
-#
+#
# %CopyrightEnd%
#
include $(ERL_TOP)/make/target.mk
@@ -126,7 +126,7 @@ pdf: $(TOP_PDF_FILE)
html: gifs $(HTML_REF_MAN_FILE)
$(XMERL_XML_FILES):
- docb_gen $(XMERL_DIR)/$(@:%.xml=%.erl)
+ escript $(DOCGEN)/priv/bin/xml_from_edoc.escript $(XMERL_DIR)/$(@:%.xml=%.erl)
man: $(MAN3_FILES) $(MAN6_FILES)
diff --git a/lib/xmerl/doc/src/notes.xml b/lib/xmerl/doc/src/notes.xml
index 115c81a806..91a98808a2 100644
--- a/lib/xmerl/doc/src/notes.xml
+++ b/lib/xmerl/doc/src/notes.xml
@@ -4,7 +4,7 @@
<chapter>
<header>
<copyright>
- <year>2004</year><year>2009</year>
+ <year>2004</year><year>2010</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
@@ -13,12 +13,12 @@
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>Xmerl Release Notes</title>
@@ -31,6 +31,35 @@
<p>This document describes the changes made to the Xmerl application.</p>
+<section><title>Xmerl 1.2.4.1</title>
+
+ <section><title>Fixed Bugs and Malfunctions</title>
+ <list>
+ <item>
+ <p> An empty element declared as simpleContent was not
+ properly validated. </p>
+ <p>
+ Own Id: OTP-8599</p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
+<section><title>Xmerl 1.2.4</title>
+
+ <section><title>Improvements and New Features</title>
+ <list>
+ <item>
+ <p>Updated the documentation Makefile to work with the
+ new documentation build process.</p>
+ <p>
+ Own Id: OTP-8343</p>
+ </item>
+ </list>
+ </section>
+
+</section>
<section><title>Xmerl 1.2.3</title>
diff --git a/lib/xmerl/src/xmerl_xsd.erl b/lib/xmerl/src/xmerl_xsd.erl
index c7bca86205..1aedc9e270 100644
--- a/lib/xmerl/src/xmerl_xsd.erl
+++ b/lib/xmerl/src/xmerl_xsd.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2006-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 2006-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%
%%
@@ -2687,13 +2687,16 @@ check_element_type(XML=[E=#xmlElement{name=Name}|Rest],
_ ->
{error,{error_path(E,Name),?MODULE,{element_bad_match,E,Any,Env}}}
end;
-check_element_type([],CM,_Env,_Block,_S,Checked) ->
+check_element_type([],CM,_Env,_Block,S,Checked) ->
%% #schema_complex_type, any, #schema_group, anyType and lists are
%% catched above.
case CM of
+ #schema_simple_type{} ->
+ {NewVal,S2} = check_type(CM,[],unapplied,S),
+ {NewVal,[],S2};
{simpleType,_} ->
- {error,{error_path(Checked,undefined),?MODULE,
- {empty_content_not_allowed,CM}}};
+ {NewVal,S2} = check_type(CM,[],unapplied,S),
+ {NewVal,[],S2};
_ ->
{error,{error_path(Checked,undefined),?MODULE,
{empty_content_not_allowed,CM}}}
diff --git a/lib/xmerl/vsn.mk b/lib/xmerl/vsn.mk
index 0bb57ea252..39213a2c4a 100644
--- a/lib/xmerl/vsn.mk
+++ b/lib/xmerl/vsn.mk
@@ -1,28 +1,11 @@
-#
-# %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%
-#
-
-XMERL_VSN = 1.2.3
+XMERL_VSN = 1.2.4.1
+
TICKETS = \
- OTP-8251 \
- OTP-8252 \
- OTP-8253
+ OTP-8343
+
+TICKETS_1.2.4 = \
+ OTP-8343
TICKETS_1.2.3 = \
OTP-8251 \
diff --git a/make/cross_check_erl b/make/cross_check_erl
new file mode 100755
index 0000000000..cb9dadfb32
--- /dev/null
+++ b/make/cross_check_erl
@@ -0,0 +1,147 @@
+#!/bin/sh
+#
+# %CopyrightBegin%
+#
+# Copyright Ericsson AB 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%
+#
+# Author: Rickard Green
+#
+
+target=
+build_otp=
+erl_top=
+force=no
+
+while [ $# -gt 0 ]; do
+ case "$1" in
+ -target)
+ shift
+ test $# -gt 0 || { echo "$0: Missing target" 1>&2; exit 1; }
+ target="$1";;
+ -otp)
+ shift
+ test $# -gt 0 || { echo "$0: Missing otp release" 1>&2; exit 1; }
+ build_otp="$1";;
+ -erl_top)
+ shift
+ test $# -gt 0 || { echo "$0: Missing erl top" 1>&2; exit 1; }
+ erl_top="$1";;
+ -force)
+ shift
+ test $# -gt 0 || { echo "$0: Missing force value" 1>&2; exit 1; }
+ force=$1;;
+ *)
+ echo "$0: Bad argument: $1" 1>&2
+ exit 1;;
+ esac
+ shift
+done
+
+test "X$target" != "X" || { echo "$0: Missing target" 1>&2; exit 1; }
+test "X$build_otp" != "X" || { echo "$0: Missing otp release" 1>&2; exit 1; }
+test "X$erl_top" != "X" || { echo "$0: Missing erl top" 1>&2; exit 1; }
+test "X$force" != "X" || { echo "$0: Missing force value" 1>&2; exit 1; }
+
+cd $erl_top
+
+cat > cross_check_erl.erl <<\EOF
+%
+% Copyright Ericsson AB 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.
+%
+
+-module(cross_check_erl).
+
+-export([start/0]).
+
+start() ->
+ OTP = case catch erlang:system_info(otp_release) of
+ {'EXIT', _} -> "OTP";
+ Rel -> "OTP-" ++ Rel
+ end,
+ io:format("~s~n", [OTP]),
+ init:stop().
+
+EOF
+
+erlc cross_check_erl.erl 2>/dev/null \
+ && used_otp=`erl -noshell -noinput -pa . -run cross_check_erl 2>/dev/null`
+
+res=$?
+
+rm -f cross_check_erl.erl cross_check_erl.beam
+
+test $res -eq 0 || {
+ cat 1>&2 <<EOF
+* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+* ERROR: No usable Erlang/OTP system for the build machine found! Cannot
+* cross compile without such a system.
+*
+* Either build a bootstrap system for the build machine, or provide
+* an Erlang/$build_otp system in the \$PATH, and try again. For more
+* information on cross compiling Erlang/$build_otp, see the
+* \$ERL_TOP/xcomp/README file.
+* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+EOF
+ exit 1
+}
+
+test "X$build_otp" = "X$used_otp" || {
+ test $force = yes || {
+ cat 1>&2 <<EOF
+* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+* ERROR: Trying to cross compile an Erlang/$build_otp system with a different
+* Erlang/$used_otp system. When cross compiling you should compile
+* with an Erlang/OTP system of the same release. It is possible,
+* however not recomended, to force the cross compilation even though
+* the wrong Erlang/OTP system is used. For more information on this,
+* and cross compiling Erlang/$build_otp in general, see the
+* \$ERL_TOP/xcomp/README file.
+* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+EOF
+ exit 1
+ }
+
+ cat <<EOF
+* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+* WARNING: Cross compiling an Erlang/$build_otp system with a different
+* Erlang/$used_otp system. When cross compiling you should compile
+* with an Erlang/OTP system of the same release. This build might
+* fail, or silently produce suboptimal code. For more information on
+* cross compiling Erlang/$build_otp, see the \$ERL_TOP/xcomp/README
+* file.
+* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+
+EOF
+}
+
+cat <<EOF
+*
+* Cross compiling Erlang/$build_otp for: $target
+*
+EOF
+
+exit 0
diff --git a/make/install_bin b/make/install_bin
new file mode 100755
index 0000000000..0d3e82266e
--- /dev/null
+++ b/make/install_bin
@@ -0,0 +1,702 @@
+#!/bin/sh
+#
+# %CopyrightBegin%
+#
+# Copyright Ericsson AB 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%
+#
+# Author: Rickard Green
+#
+
+#
+# NOTE! This script needs to be portable since it is run on all platforms
+# (besides win32). Keep this in mind when updating it.
+#
+
+## set `INST_BIN_DEBUG=true' in environment when debugging the script to
+## avoid removing, and creating stuff etc...
+
+##
+## We do not reset these variables, since values may be passed either via
+## environment, or command line arguments.
+##
+#bindir=
+#exec_prefix=
+#erlang_bindir=
+#DESTDIR=
+#EXTRA_PREFIX=
+#BINDIR_SYMLINKS=
+#LN_S=
+tst=
+
+#
+# When this script communicates with the user it talks of the parameters
+# as they are given to configure if such exist (currently --bindir, and
+# --exec-prefix); otherwise, as the variable names used in the top
+# Makefile (which calls this script).
+#
+
+path_variables="DESTDIR EXTRA_PREFIX exec_prefix bindir erlang_bindir"
+DQ=
+
+dbg=
+test "$INST_BIN_DEBUG" != "true" || dbg=true
+
+while [ $# -gt 1 ]; do
+ case "$1" in
+ --bindir) bindir="$2";;
+ --exec-prefix) exec_prefix="$2";;
+ --erlang-bindir) erlang_bindir="$2";;
+ --destdir) DESTDIR="$2";;
+ --extra-prefix) EXTRA_PREFIX="$2";;
+ --bindir-symlinks) BINDIR_SYMLINKS="$2";;
+ --ln_s) LN_S="$2";;
+ --test-file) tst="$2";;
+ *) break;;
+ esac
+ shift
+ shift
+done
+
+
+test $# -gt 0 || {
+ echo " ERROR: Missing files to install" 1>&2
+ test "$tst" = "" || echo "{error,{arg,missing_files}}." > $tst
+ exit 1;
+}
+test "$bindir" != "" || {
+ echo " ERROR: Missing --bindir" 1>&2
+ test "$tst" = "" || echo "{error,{arg,missing_bindir}}." > $tst
+ exit 1
+}
+test "$exec_prefix" != "" || {
+ echo " ERROR: Missing --exec-prefix" 1>&2
+ test "$tst" = "" || echo "{error,{arg,missing_exec_prefix}}." > $tst
+ exit 1
+}
+test "$erlang_bindir" != "" || {
+ echo " ERROR: Missing erlang_bindir" 1>&2
+ test "$tst" = "" || echo "{error,{arg,missing_erlang_bindir}}." > $tst
+ exit 1
+}
+
+# Make sure all paths are absolute
+for dir_var in $path_variables; do
+ eval "dir_path=\"\$$dir_var\""
+
+ case "$dir_path" in
+ /*) ;;
+ "")
+ # Empty DESTDIR or EXTRA_PREFIX which is ok
+ case $dir_var in
+ DESTDIR|EXTRA_PREFIX) ;;
+ *)
+ echo " ERROR: Internal error: \$$dir_var is empty" 1>&2
+ test "$tst" = "" || echo "{error,{empty,$dir_var}}." > $tst
+ exit 1;;
+ esac
+ continue;;
+ *)
+ case $dir_var in
+ bindir) flag="--bindir=";;
+ exec_prefix) flag="--exec-prefix=";;
+ erlang_bindir) flag="erlang_bindir=";;
+ DESTDIR) flag="DESTDIR=";;
+ EXTRA_PREFIX) flag="EXTRA_PREFIX=";;
+ *) flag="";; # Need to update the script...
+ esac
+ cat 1>&2 <<EOF
+ ERROR: Found path to a directory which was not absolute. All paths needs to
+ be absolute.
+
+ $flag"$dir_path"
+EOF
+ test "$tst" = "" || echo "{error,{not_abs,'$dir_var'}}." > $tst
+ exit 1;;
+ esac
+ case "$dir_path" in
+ *[!A-Za-z0-9/=_.-]*) DQ="\"";;
+ *) ;;
+ esac
+done
+
+# We place temporary check files in the source dir and the target dir. These
+# can later be used to verify that our modifications of the paths are
+# successful.
+
+test "$dbg" = "true" || {
+ bchk_file="tmp-erlang-install-bin.$$"
+ ebchk_file="tmp-erlang-install-erl-bin.$$"
+ bchk="$DESTDIR$EXTRA_PREFIX$bindir/$bchk_file"
+ ebchk="$DESTDIR$EXTRA_PREFIX$erlang_bindir/$ebchk_file"
+ chk_txt="Temporary Erlang/OTP install file."
+ chk_err=no
+
+ # Make sure we haven't got any old ones...
+ rm -f "$bchk" "$ebchk"
+
+ { { echo "$chk_txt" > "$ebchk"; } 2>/dev/null && test -r "$ebchk"; } || {
+ cat 1>&2 <<EOF
+ ERROR: Cannot create files in 'erlang_bindir'.
+
+EOF
+ chk_err=no_create_erlang_bindir
+ }
+
+ { { echo "$chk_txt" > "$bchk"; } 2>/dev/null && test -r "$bchk"; } || {
+ cat 1>&2 <<EOF
+ ERROR: Cannot create files in '--bindir'.
+
+EOF
+ chk_err=no_create_bindir
+ }
+
+
+ { test $chk_err != no ||
+ test ! -f "$DESTDIR$EXTRA_PREFIX$bindir/$ebchk_file"; } || {
+ # Refuse to install in the same directory as the source...
+ cat 1>&2 <<EOF
+ ERROR: '--bindir' and 'erlang_bindir' both points to the same directory. This
+ can be due to symbolic directory links.
+
+EOF
+ chk_err=target_and_source_same_dir
+ }
+
+ test $chk_err = no || {
+ cat 1>&2 <<EOF
+ --bindir="$bindir"
+ erlang_bindir="$erlang_bindir"
+ EXTRA_PREFIX="$EXTRA_PREFIX"
+ DESTDIR="$DESTDIR"
+
+ Note that all absolute directory paths are prefixed by
+ \$DESTDIR\$EXTRA_PREFIX when accessed.
+EOF
+ rm -f "$bchk" "$ebchk"
+ test "$tst" = "" || echo "{error,$chk_err}." > $tst
+ exit 1
+ }
+}
+
+dirty=no
+
+# Make all paths look good (remove all `.' dirs, `//', and trailing `/').
+for dir_var in $path_variables; do
+ eval "dir_path=\"\$$dir_var\""
+ test "$dir_path" != "" || continue
+
+ ndp=
+ save_IFS=$IFS
+ IFS=/
+ for dir in $dir_path; do
+ case "$dir" in
+ "" | ".") continue;;
+ "..")
+ case $dir_var in
+ bindir|erlang_bindir|exec_prefix) dirty=yes;;
+ *) ;;
+ esac;;
+ *) ;;
+ esac
+ ndp="$ndp/$dir"
+ done
+ IFS=$save_IFS
+ test "$ndp" != "" || ndp="/"
+ eval "$dir_var=\"$ndp\""
+done
+
+iprfx="$DESTDIR$EXTRA_PREFIX"
+
+# Make sure we didn't mess up
+{ $dbg test -f "$iprfx$bindir/$bchk_file" &&
+ $dbg test -f "$iprfx$erlang_bindir/$ebchk_file"; } || {
+ cat 1>&2 <<EOF
+ ERROR: Internal error: Unsuccessfully trimmed the paths
+
+ --bindir="$bindir"
+ erlang_bindir="$erlang_bindir"
+ --exec-prefix="$exec_prefix"
+ EXTRA_PREFIX="$EXTRA_PREFIX"
+ DESTDIR="$DESTDIR"
+EOF
+ $dbg rm -f "$bchk" "$ebchk"
+ test "$tst" = "" || echo "{error,bad_trim}." > $tst
+ exit 1
+}
+
+# Now all paths look good...
+
+
+# $ln_s should be either 'ln -s', 'ln', or 'cp -p'. We don't want to
+# maks hard links, so make sure we got 'ln -s'; otherwise, use 'cp -p'
+
+# This is the fallback if we haven't got 'ln -s'
+ln_s="cp -p"
+type=copy
+paths=absolute
+abspath_reason=no_ln_s
+src_dir="$iprfx$erlang_bindir"
+
+case "X${LN_S}X" in
+ Xln[\ \ ]*X|X*[\ \ ]ln[\ \ ]*X)
+ # Got `ln'; check that we also got `-s' flag
+ case "X${LN_S}X" in
+ X*[\ \ ]-sX|X*[\ \ ]-s[\ \ ]*X)
+ # Ok; seems like we got `ln -s'
+ ln_s="ln -s"
+ type=link
+ paths="$BINDIR_SYMLINKS"
+ test "$BINDIR_SYMLINKS" = "absolute" && abspath_reason=request
+ # $DESTDIR should *not* be part of src_dir when linking
+ src_dir="$EXTRA_PREFIX$erlang_bindir"
+ ;;
+ *) ;;
+ esac;;
+ *) ;;
+esac
+
+case "$paths" in
+ absolute|relative) ;;
+ *) paths=undetermined;;
+esac
+
+# Determine if we should use absolute or relative paths for links
+test $paths != absolute && {
+ # If $paths is undetermined, use absolute paths unless both $bindir
+ # and $erlang_bindir are prefixed by $exec_prefix (which is the normal
+ # case)
+ test $paths = relative || paths=absolute
+ abspath_reason=not_prefix
+ resolved_bindir="$bindir"
+ resolved_erlang_bindir="$erlang_bindir"
+ resolved_exec_prefix="$exec_prefix"
+ case "$bindir" in
+ "$exec_prefix"*)
+ case "$erlang_bindir" in
+ "$exec_prefix"*) paths=relative;;
+ *) ;;
+ esac;;
+ *);;
+ esac
+ # Now paths=absolute|relative
+
+ # If we got dirty paths (contains ..) and are going for relative links,
+ # we need to resolve the paths
+ test $dirty-$paths = yes-relative && {
+ # Need to resolve $bindir and $erlang_bindir paths
+ for dir_var in bindir erlang_bindir exec_prefix; do
+ eval "dir_path=\"\$$dir_var\""
+
+ ndp="/"
+ save_IFS=$IFS
+ IFS=/
+ for dir in $dir_path; do
+ case "$dir" in
+ "") ;;
+ "..")
+ test "$ndp" != "/" || {
+ IFS=$save_IFS
+ paths=absolute
+ abspath_reason=unreasonable_path
+ break 2
+ }
+ ndp=`dirname "$ndp" 2>/dev/null` || {
+ IFS=$save_IFS
+ paths=absolute
+ abspath_reason=dirname_failed
+ break 2
+ };;
+ *)
+ if test "$ndp" = "/"; then
+ ndp="/$dir"
+ else
+ ndp="$ndp/$dir"
+ fi;;
+ esac
+ done
+ IFS=$save_IFS
+ test "$ndp" != "" || ndp="/"
+ eval "resolved_$dir_var=\"$ndp\""
+ done
+ }
+
+ # If we still are going for relative and relative symbolic links have
+ # not been explicitly requested check that the resolved paths still
+ # are prefixed by exec_prefix
+ test $paths = relative && test "$BINDIR_SYMLINKS" != "relative" && {
+ paths=absolute
+ abspath_reason=not_prefix
+ case "$resolved_bindir" in
+ "$resolved_exec_prefix"*)
+ case "$resolved_erlang_bindir" in
+ "$resolved_exec_prefix"*)
+ paths=relative;;
+ *) ;;
+ esac;;
+ *) ;;
+ esac
+ }
+
+ # If we still are going for relative check that resolved paths are
+ # reachable (might not be if the directory structure contains symbolic
+ # directory links).
+ test $paths = relative && {
+ ($dbg test -r "$iprfx$resolved_bindir/$bchk_file" &&
+ $dbg test -r "$iprfx$resolved_erlang_bindir/$ebchk_file" &&
+ $dbg cd "$iprfx$resolved_bindir" &&
+ $dbg test -r "./$bchk_file" &&
+ $dbg cd "$iprfx$resolved_erlang_bindir" &&
+ $dbg test -r "./$ebchk_file") || {
+ paths=absolute
+ abspath_reason=unreachable_absolute
+ }
+ }
+
+
+ # If we still are going for relative, calculate the relative path from
+ # $resolved_bindir to $resolved_erlang_bindir and verify that we
+ # can reach $erlang_bindir from $bindir via calculated relative path
+ test $paths = relative && {
+ relpath=
+ common=
+
+ save_IFS=$IFS
+ IFS=/
+
+ build=false
+ for dir in $resolved_erlang_bindir; do
+ test "$dir" != "" || continue
+ test $build = false || { relpath="$relpath/$dir"; continue; }
+ cand="${common}/$dir"
+ case "$resolved_bindir" in
+ "$cand"*) common="$cand";;
+ *) relpath="$dir"; build=true;;
+ esac
+ done
+
+ check=
+ build=false
+ test "$common" != "" || build=true
+
+ for dir in $resolved_bindir; do
+ test "$dir" != "" || continue
+ test $build = true || {
+ check="${check}/$dir"
+ test "$check" != "$common" || build=true
+ continue
+ }
+ if test "$relpath" = ""; then
+ relpath=".."
+ else
+ relpath="../$relpath"
+ fi
+ done
+
+ IFS=$save_IFS
+
+ test "$relpath" != "" || {
+ cat 1>&2 <<EOF
+ ERROR: Internal error: Computed relative path: .
+
+ --bindir="$bindir"
+ erlang_bindir="$erlang_bindir"
+ --exec-prefix="$exec_prefix"
+ EXTRA_PREFIX="$EXTRA_PREFIX"
+ DESTDIR="$DESTDIR"
+ BINDIR_SYMLINKS="$BINDIR_SYMLINKS"
+EOF
+ $dbg rm -f "$bchk" "$ebchk"
+ test "$tst" = "" || echo "{error,empty_relpath}." > $tst
+ exit 1
+ }
+
+ # Verify that it works otherwise go for absolute links
+ if ($dbg cd "$iprfx$bindir" 2>/dev/null && \
+ $dbg test -r "$relpath/$ebchk_file"); then
+ src_dir="$relpath"
+ else
+ abspath_reason=unreachable_relative
+ paths=absolute
+ fi
+ }
+}
+
+# Don't need the temporary check files anymore
+$dbg rm -f "$bchk" "$ebchk"
+
+# If we reverted to absolute paths we may have to abort or notify the user
+# about this...
+case "$paths-$BINDIR_SYMLINKS" in
+ absolute-absolute) # User requested absolute and got it
+ case "$abspath_reason" in
+ no_ln_s)
+ cat <<EOF
+ ERROR: Cannot install absolute symbolic links in the '--bindir' directory,
+ since 'ln -s' does not work. If you want to install using 'cp -p'
+ invoke 'make install' without setting BINDIR_SYMLINKS.
+
+ --bindir="$bindir"
+ erlang_bindir="$erlang_bindir"
+ --exec-prefix="$exec_prefix"
+ EXTRA_PREFIX="$EXTRA_PREFIX"
+ DESTDIR="$DESTDIR"
+ BINDIR_SYMLINKS="$BINDIR_SYMLINKS"
+
+ Note that all absolute directory paths are prefixed by
+ \$DESTDIR\$EXTRA_PREFIX when accessed.
+EOF
+ test "$tst" = "" || echo "{error,$abspath_reason}." > $tst
+ exit 1;; # Abort...
+ *)
+ ;;
+ esac;;
+
+ absolute-relative) # User forced relative symbolic links, but we need
+ # to revert to absolute symbolic links. Print error
+ # message and abort.
+
+ case "$abspath_reason" in
+ no_ln_s)
+ cat 1>&2 <<EOF
+ ERROR: Cannot install relative symbolic links in the '--bindir' directory,
+ since 'ln -s' does not work. If you want to install using 'cp -p' do
+ not set BINDIR_SYMLINKS, and invoke 'make install' again.
+
+EOF
+ ;;
+ not_prefix)
+ cat 1>&2 <<EOF
+ ERROR: Internal error: Should not have reverted to absolute paths just
+ because '--exec-prefix' was not a prefix of '--bindir' and/or
+ 'erlang_bindir' since relative symbolic links were forced.
+
+EOF
+ ;;
+ unreasonable_path)
+ cat 1>&2 <<EOF
+ ERROR: Refusing to install relative symbolic links, since the relative path
+ potentially could go via \$DESTDIR\$EXTRA_PREFIX/. Make your install
+ paths a bit more reasonable (preferably) or, do not invoke
+ 'make install' with 'BINDIR_SYMLINKS=relative'.
+
+EOF
+ ;;
+ unreachable_absolute)
+ cat 1>&2 <<EOF
+ ERROR: Could not find '--bindir' and/or 'erlang_bindir' after resolving paths.
+ The directory structure probably consists of symbolic directory links.
+ Refusing to install obviously incorrect relative symbolic links. In
+ order to install absolute symbolic links, invoke 'make install' without
+ 'BINDIR_SYMLINKS=relative'.
+
+EOF
+ ;;
+ unreachable_relative)
+ cat 1>&2 <<EOF
+ ERROR: Could not find 'erlang_bindir' from '--bindir' via computed relative
+ path. This probably due to symbolic directory links. Refusing to install
+ obviously incorrect relative symbolic links. In order to install
+ absolute symbolic links, invoke 'make install' without
+ 'BINDIR_SYMLINKS=relative'.
+
+ Computed relative path="$relpath"
+EOF
+ ;;
+ dirname_failed)
+ cat 1>&2 <<EOF
+ ERROR: Cannot install relative symbolic links since the 'dirname' command
+ failed while computing the relative path. The 'dirname' command is only
+ needed when '--bindir', 'erlang_bindir', and/or '--exec-prefix' contain
+ relative parts, i.e., '..' parts. If you modify your install paths, it
+ may be possible to install relative symbolic links. In order to install
+ absolute symbolic links, invoke 'make install' without
+ 'BINDIR_SYMLINKS=relative'.
+
+EOF
+ ;;
+ *)
+ cat 1>&2 <<EOF
+ ERROR: Refusing to install relative symbolic links. The error description for
+ \"$abspath_reason\" is however missing.
+
+EOF
+ ;;
+ esac
+ cat 1>&2 <<EOF
+ --bindir="$bindir"
+ erlang_bindir="$erlang_bindir"
+ --exec-prefix="$exec_prefix"
+ EXTRA_PREFIX="$EXTRA_PREFIX"
+ DESTDIR="$DESTDIR"
+ BINDIR_SYMLINKS="$BINDIR_SYMLINKS"
+
+ Note that all absolute directory paths are prefixed by
+ \$DESTDIR\$EXTRA_PREFIX when accessed.
+EOF
+ test "$tst" = "" || echo "{error,$abspath_reason}." > $tst
+ exit 1;; # Abort...
+
+ absolute-*) # Notify the user that we reverted to absolute symbolic links
+ cat <<EOF
+* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+EOF
+ case "$abspath_reason" in
+ no_ln_s)
+ cat <<EOF
+ NOTE: Cannot install symbolic links in the '--bindir' directory, since
+ 'ln -s' does not work. Will create copies using 'cp -p' instead.
+
+EOF
+ ;;
+ not_prefix)
+ cat <<EOF
+ NOTE: Installing absolute symbolic links in the '--bindir' directory to the
+ 'erlang_bindir' directory instead of relative ones. This since at least
+ one of these directories is not prefixed by '--exec-prefix'. It is
+ possible to force relative symbolic links if you want that by invoking
+ the install as 'make BINDIR_SYMLINKS=relative install'.
+
+EOF
+ ;;
+
+ unreasonable_path)
+ cat <<EOF
+ NOTE: Installing absolute symbolic links in the '--bindir' directory to the
+ 'erlang_bindir' directory instead of relative ones. This since it
+ potentially would pass outside of '\$DESTDIR\$EXTRA_PREFIX/'.
+
+EOF
+ ;;
+ unreachable_absolute)
+ cat <<EOF
+ NOTE: Installing absolute symbolic links in the '--bindir' directory to the
+ 'erlang_bindir' instead of relative ones. This since at least one of
+ these directory could not be found after resolving paths. This is
+ probably due to symbolic directory links.
+
+EOF
+ ;;
+ unreachable_relative)
+ cat <<EOF
+ NOTE: Installing absolute symbolic links in the '--bindir' directory to the
+ 'erlang_bindir' directory instead of relative ones. This since the
+ 'erlang_bindir' directory could not be found from the '--bindir'
+ directory using the computed relative path. This is probably due
+ to symbolic directory links.
+
+ Computed relative path="$relpath"
+EOF
+ ;;
+ dirname_failed)
+ cat 1>&2 <<EOF
+ NOTE: Installing absolute symbolic links in the '--bindir' directory to the
+ 'erlang_bindir' directory instead of relative ones. This since the
+ 'dirname' command failed while computing the relative path. The
+ 'dirname' command is only needed when '--bindir', 'erlang_bindir',
+ and/or '--exec-prefix' contain relative parts, i.e., '..' parts. If
+ you modify your install paths, it may be possible to install relative
+ symbolic links.
+
+EOF
+ ;;
+ *)
+ cat 1>&2 <<EOF
+ NOTE: Installing absolute symbolic links in the '--bindir' directory
+ to the 'erlang_bindir' instead of relative ones. The notification
+ description for "$abspath_reason" is however missing.
+
+EOF
+ ;;
+ esac
+
+ cat <<EOF
+ --bindir="$bindir"
+ erlang_bindir="$erlang_bindir"
+ --exec-prefix="$exec_prefix"
+ EXTRA_PREFIX="$EXTRA_PREFIX"
+ DESTDIR="$DESTDIR"
+ BINDIR_SYMLINKS="$BINDIR_SYMLINKS"
+
+ Note that all absolute directory paths are prefixed by
+ \$DESTDIR\$EXTRA_PREFIX when accessed.
+* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+EOF
+ ;;
+
+ *) # relative links
+ ;;
+esac
+
+# Now paths=absolute|relative and src_dir is correct (relative bindir)
+
+# cd into "$iprfx$bindir" and do it from there...
+echo cd "$DQ$iprfx$bindir$DQ"
+$dbg cd "$iprfx$bindir" || {
+ test "$tst" = "" || echo "{error,cd_bin_failed}." > $tst
+ exit 1
+}
+
+# Verify that the source files actually exist (done in a separate pass
+# before we modify anything, so we leave it untouched if it should fail).
+# Note that we will not find them under $src_dir if we use absolute symbolic
+# links and $DESTDIR != "". In this case (actually all cases) they can then
+# be found under $iprfx$erlang_bindir
+test_src_dir="$src_dir"
+test "$paths-$type" != "absolute-link" || test_src_dir="$iprfx$erlang_bindir"
+
+for file in "$@"; do
+ test "$file" != "" || continue
+ src_file="$test_src_dir/$file"
+ $dbg test -f "$src_file" || {
+ cat 1>&2 <<EOF
+ ERROR: Missing source file: $src_file
+
+ --bindir="$bindir"
+ erlang_bindir="$erlang_bindir"
+ --exec-prefix="$exec_prefix"
+ EXTRA_PREFIX="$EXTRA_PREFIX"
+ DESTDIR="$DESTDIR"
+ BINDIR_SYMLINKS="$BINDIR_SYMLINKS"
+
+ Note that all absolute directory paths are prefixed by
+ \$DESTDIR\$EXTRA_PREFIX when accessed.
+EOF
+ test "$tst" = "" || echo "{error,{no_srcfile,\"$src_file\"}}." > $tst
+ exit 1
+ }
+done
+
+# Remove after possible old install (done in a separate pass since I think
+# the output looks nicer than if mixed). Note that we cannot test for existance
+# in a portable way, so force remove.
+for file in "$@"; do
+ test "$file" != "" || continue
+ echo rm -f "$file"
+ $dbg rm -f "$file"
+done
+
+# do it
+for file in "$@"; do
+ echo $ln_s "$DQ$src_dir/$file$DQ" "$file"
+ $dbg $ln_s "$src_dir/$file" "$file" || {
+ test "$tst" = "" || echo "{error,{$type,\"$file\",failed}}." > $tst
+ exit 1
+ }
+done
+
+test "$tst" = "" || echo "{ok,{$paths,\"$iprfx$bindir\",\"$src_dir\"}}." > $tst
+
+exit 0 # Done
diff --git a/make/otp.mk.in b/make/otp.mk.in
index bcf9bd85a4..9f0486a609 100644
--- a/make/otp.mk.in
+++ b/make/otp.mk.in
@@ -3,20 +3,20 @@
# Make include file for otp
#
# %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%
#
# Author: Lars Thorsen
@@ -53,6 +53,7 @@ INSTALL_SCRIPT = @INSTALL_SCRIPT@
INSTALL_DATA = @INSTALL_DATA@
CC = @CC@
+GCC = @GCC@
HCC = @HCC@
CC32 = @CC32@
CFLAGS32 = @CFLAGS32@
@@ -235,33 +236,44 @@ DOCGEN=$(ERL_TOP)/lib/erl_docgen
$(MAN1DIR)/%.1:: %.xml
date=`date +"%B %e %Y"`; \
- xsltproc --output "$@" --stringparam docgen "$(DOCGEN)" --stringparam gendate "$$date" --stringparam appname "$(APPLICATION)" --stringparam appver "$(VSN)" --xinclude -path $(DOCGEN)/priv/docbuilder_dtd -path $(DOCGEN)/priv/dtd_man_entities $(DOCGEN)/priv/xsl/db_man.xsl $<
+ xsltproc --output "$@" --stringparam company "Ericsson AB" --stringparam docgen "$(DOCGEN)" --stringparam gendate "$$date" --stringparam appname "$(APPLICATION)" --stringparam appver "$(VSN)" --xinclude -path $(DOCGEN)/priv/docbuilder_dtd -path $(DOCGEN)/priv/dtd_man_entities $(DOCGEN)/priv/xsl/db_man.xsl $<
$(MAN2DIR)/%.2:: %.xml
date=`date +"%B %e %Y"`; \
- xsltproc --output "$@" --stringparam docgen "$(DOCGEN)" --stringparam gendate "$$date" --stringparam appname "$(APPLICATION)" --stringparam appver "$(VSN)" --xinclude -path $(DOCGEN)/priv/docbuilder_dtd -path $(DOCGEN)/priv/dtd_man_entities $(DOCGEN)/priv/xsl/db_man.xsl $<
+ xsltproc --output "$@" --stringparam company "Ericsson AB" --stringparam docgen "$(DOCGEN)" --stringparam gendate "$$date" --stringparam appname "$(APPLICATION)" --stringparam appver "$(VSN)" --xinclude -path $(DOCGEN)/priv/docbuilder_dtd -path $(DOCGEN)/priv/dtd_man_entities $(DOCGEN)/priv/xsl/db_man.xsl $<
$(MAN3DIR)/%.3:: %.xml
date=`date +"%B %e %Y"`; \
- xsltproc --output "$@" --stringparam docgen "$(DOCGEN)" --stringparam gendate "$$date" --stringparam appname "$(APPLICATION)" --stringparam appver "$(VSN)" --xinclude -path $(DOCGEN)/priv/docbuilder_dtd -path $(DOCGEN)/priv/dtd_man_entities $(DOCGEN)/priv/xsl/db_man.xsl $<
+ xsltproc --output "$@" --stringparam company "Ericsson AB" --stringparam docgen "$(DOCGEN)" --stringparam gendate "$$date" --stringparam appname "$(APPLICATION)" --stringparam appver "$(VSN)" --xinclude -path $(DOCGEN)/priv/docbuilder_dtd -path $(DOCGEN)/priv/dtd_man_entities $(DOCGEN)/priv/xsl/db_man.xsl $<
+# left for compatability
$(MAN4DIR)/%.4:: %.xml
date=`date +"%B %e %Y"`; \
- xsltproc --output "$@" --stringparam docgen "$(DOCGEN)" --stringparam gendate "$$date" --stringparam appname "$(APPLICATION)" --stringparam appver "$(VSN)" --xinclude -path $(DOCGEN)/priv/docbuilder_dtd -path $(DOCGEN)/priv/dtd_man_entities $(DOCGEN)/priv/xsl/db_man.xsl $<
+ xsltproc --output "$@" --stringparam company "Ericsson AB" --stringparam docgen "$(DOCGEN)" --stringparam gendate "$$date" --stringparam appname "$(APPLICATION)" --stringparam appver "$(VSN)" --xinclude -path $(DOCGEN)/priv/docbuilder_dtd -path $(DOCGEN)/priv/dtd_man_entities $(DOCGEN)/priv/xsl/db_man.xsl $<
+$(MAN4DIR)/%.5:: %.xml
+ date=`date +"%B %e %Y"`; \
+ xsltproc --output "$@" --stringparam company "Ericsson AB" --stringparam docgen "$(DOCGEN)" --stringparam gendate "$$date" --stringparam appname "$(APPLICATION)" --stringparam appver "$(VSN)" --xinclude -path $(DOCGEN)/priv/docbuilder_dtd -path $(DOCGEN)/priv/dtd_man_entities $(DOCGEN)/priv/xsl/db_man.xsl $<
+
+# left for compatability
$(MAN6DIR)/%.6:: %_app.xml
date=`date +"%B %e %Y"`; \
- xsltproc --output "$@" --stringparam docgen "$(DOCGEN)" --stringparam gendate "$$date" --stringparam appname "$(APPLICATION)" --stringparam appver "$(VSN)" --xinclude -path $(DOCGEN)/priv/docbuilder_dtd -path $(DOCGEN)/priv/dtd_man_entities $(DOCGEN)/priv/xsl/db_man.xsl $<
+ xsltproc --output "$@" --stringparam company "Ericsson AB" --stringparam docgen "$(DOCGEN)" --stringparam gendate "$$date" --stringparam appname "$(APPLICATION)" --stringparam appver "$(VSN)" --xinclude -path $(DOCGEN)/priv/docbuilder_dtd -path $(DOCGEN)/priv/dtd_man_entities $(DOCGEN)/priv/xsl/db_man.xsl $<
+
+$(MAN6DIR)/%.7:: %_app.xml
+ date=`date +"%B %e %Y"`; \
+ xsltproc --output "$@" --stringparam company "Ericsson AB" --stringparam docgen "$(DOCGEN)" --stringparam gendate "$$date" --stringparam appname "$(APPLICATION)" --stringparam appver "$(VSN)" --xinclude -path $(DOCGEN)/priv/docbuilder_dtd -path $(DOCGEN)/priv/dtd_man_entities $(DOCGEN)/priv/xsl/db_man.xsl $<
$(MAN9DIR)/%.9:: %.xml
date=`date +"%B %e %Y"`; \
- xsltproc --output "$@" --stringparam docgen "$(DOCGEN)" --stringparam gendate "$$date" --stringparam appname "$(APPLICATION)" --stringparam appver "$(VSN)" --xinclude -path $(DOCGEN)/priv/docbuilder_dtd -path $(DOCGEN)/priv/dtd_man_entities $(DOCGEN)/priv/xsl/db_man.xsl $<
+ xsltproc --output "$@" --stringparam company "Ericsson AB" --stringparam docgen "$(DOCGEN)" --stringparam gendate "$$date" --stringparam appname "$(APPLICATION)" --stringparam appver "$(VSN)" --xinclude -path $(DOCGEN)/priv/docbuilder_dtd -path $(DOCGEN)/priv/dtd_man_entities $(DOCGEN)/priv/xsl/db_man.xsl $<
.xmlsrc.xml:
- $(DOCGEN)/priv/bin/codeline_preprocessing.escript $< $@
+ escript $(DOCGEN)/priv/bin/codeline_preprocessing.escript $< $@
.fo.pdf:
$(FOP) -fo $< -pdf $@
+
diff --git a/make/otp_ded.mk.in b/make/otp_ded.mk.in
index 0a91a42df5..e719312473 100644
--- a/make/otp_ded.mk.in
+++ b/make/otp_ded.mk.in
@@ -1,22 +1,48 @@
#-*-makefile-*- ; force emacs to enter makefile-mode
# ----------------------------------------------------
-# Make include file for otp
+# %CopyrightBegin%
#
-# Copyright (C) 1996, Ericsson Telecommunications
-# Author: Lars Thorsen
+# 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%
+
+# The version.
+#
+# Note that it is important that the version is
+# explicitly expressed here. Some applications need to
+# be able to check this value *before* configure has
+# been run and generated otp_ded.mk
+DED_MK_VSN = 1
+# ----------------------------------------------------
+# Variables needed for building Dynamic Erlang Drivers
# ----------------------------------------------------
DED_CC = @CC@
+DED_GCC = @GCC@
DED_LD = @DED_LD@
DED_LDFLAGS = @DED_LDFLAGS@
-DED__NOWARN_CFLAGS = @DED_CFLAGS@
-DED_CFLAGS = @WFLAGS@ @DED_CFLAGS@
+DED__NOWARN_NOTHR_CFLAGS = @DED_CFLAGS@
+DED__NOTHR_CFLAGS = @WFLAGS@ @DED_CFLAGS@
+DED__NOWARN_CFLAGS = @DED_EMU_THR_DEFS@ @DED_CFLAGS@
+DED_THR_DEFS = @DED_THR_DEFS@
+DED_EMU_THR_DEFS = @DED_EMU_THR_DEFS@
+DED_WARN_FLAGS = @WFLAGS@
+DED_CFLAGS = @WFLAGS@ @DED_EMU_THR_DEFS@ @DED_CFLAGS@
DED_LIBS = @LIBS@
+DED_EXT = @DED_EXT@
ERLANG_OSTYPE = @ERLANG_OSTYPE@
-TARGET = @host@
PRIVDIR = ../priv
OBJDIR = $(PRIVDIR)/obj/$(TARGET)
LIBDIR = $(PRIVDIR)/lib/$(TARGET)
-DED_SYS_INCLUDE = -I$(ERL_TOP)/erts/emulator/beam \
- -I$(ERL_TOP)/erts/emulator/sys/$(ERLANG_OSTYPE)
-
+DED_SYS_INCLUDE = @DED_SYS_INCLUDE@
DED_INCLUDES = $(DED_SYS_INCLUDE)
diff --git a/make/otp_release_targets.mk b/make/otp_release_targets.mk
index b6e1f4195e..7d433e738c 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-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 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,8 +45,33 @@ $(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
+local_docs: local_copy_of_topdefs docs
+
+local_html: TOPDOCDIR=.
+local_html: local_copy_of_topdefs html
+
+local_copy_of_topdefs:
$(INSTALL) $(DOCGEN)/priv/css/otp_doc.css $(HTMLDIR)
$(INSTALL) $(DOCGEN)/priv/images/erlang-logo.png $(HTMLDIR)
$(INSTALL) $(DOCGEN)/priv/images/erlang-logo.gif $(HTMLDIR)
@@ -59,6 +81,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 +96,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/make/unexpected_use b/make/unexpected_use
new file mode 100755
index 0000000000..d7543a7d83
--- /dev/null
+++ b/make/unexpected_use
@@ -0,0 +1,29 @@
+#!/bin/sh
+#
+# %CopyrightBegin%
+#
+# Copyright Ericsson AB 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%
+#
+
+prog=`basename "$0"` || prog="$0"
+
+cat 1>&2 <<EOF
+* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ ERROR: Unexpected use of '$prog' in 'install', or 'release' phase.
+* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+EOF
+
+exit 1
diff --git a/otp_build b/otp_build
index e478256314..ad9d38ebca 100755
--- a/otp_build
+++ b/otp_build
@@ -1,4 +1,22 @@
#! /bin/sh
+#
+# %CopyrightBegin%
+#
+# Copyright Ericsson AB 2002-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%
+#
# Expected autoconf version
EXPECTED_AUTOCONF_VERSION=2.59
@@ -8,26 +26,35 @@ clearmake=false
# Global configuration variables
#
-# NOTE: lazy_configure depends on '.' allways being last directory
+# NOTE: lazy_configure depends on '.' always being last directory
if [ -z "$ONLY_ERTS" ]; then
- AUTOCONF_SUBDIRS="lib lib/*"
+ AUTOCONF_SUBDIRS="lib lib/* lib/test_server/src"
fi
AUTOCONF_SUBDIRS="$AUTOCONF_SUBDIRS erts ."
+# `bootstrap_apps' should include application that are built, or
+# partly built in one of the bootstrap phases. Applications that
+# only get some static includes copied into the bootstrap directory
+# should not be included.
+bootstrap_apps="erts lib/asn1 lib/compiler lib/hipe lib/ic lib/kernel lib/parsetools lib/sasl lib/snmp lib/stdlib lib/syntax_tools"
+
+# We will quote a bit more than needed, but the important thing is that
+# all that needs quoting will be quoted...
+DONT_QUOTE="A-Za-z0-9~/=_+-"
+
# Utility functions
usage ()
{
- echo "Available options:"
+ echo "Available options (-a switch select all applications):"
echo " setup [-a] [<configure parameters>] - does autoconf, configure and boot."
echo " all [-a] <dir> - does autoconf, configure, boot, release"
echo " autoconf - (re)build the configure scripts"
echo " configure [<configure parameters>] - does the actual configuration"
- echo " smp [-a] - build a small Erlang system, smp flavor"
- echo " hybrid [-a] - build a small Erlang system, hybrid flavor"
- echo " nofrag [-a] - build a small Erlang system, nofrag flavor"
- echo " boot [-a] - bootstraps and build system (after configure)"
+ echo " boot [-a] - bootstraps and builds the system (after configure)"
echo " release <target_dir> - creates a small release to <target_dir>"
echo " release [-a] <target_dir> - creates full release to <target_dir>"
+ echo " smp [-a] - build an Erlang system, smp flavor only"
+ echo " hybrid [-a] - build an Erlang system, hybrid flavor only"
echo " tests <dir> - Build testsuites to <dir>"
echo ""
echo "These are for cleaning up an open source distribution"
@@ -47,75 +74,67 @@ usage ()
echo "Before trying to build for vxworks, consider the following option"
echo " env_vxworks <cpu> - echo environment settings for vxworks, use with eval"
echo ""
- echo "Before trying to cross compile, set environment via the following option"
- echo "Please note that the path to the configuration file should be absolute."
- echo " env_cross <absolute path to cross conf file> - echo environment settings for cross compilation, use with eval"
- echo ""
- echo "The following options concern the primary bootstrap."
- echo "{prepare,update,commit,cancel}_primary is for actually updating"
- echo "the checked in derivates of the main code base, they are not for"
- echo "managing a downloaded spource-tree."
- echo " prepare_primary - prepares for building primary bootstrap (only in Clearcase)"
- echo " update_primary - creates the primary bootstrap, the one shipped"
- echo " commit_primary - commits a primary bootstrap (only in Clearcase)"
- echo " cancel_primary - uncheckout a primary bootstrap (only in Clearcase)"
- echo ""
- echo "The following options concern preloaded code."
- echo "They are, like the primary bootstrap, mainly the concern of the"
- echo "main developers."
- echo " prepare_preloaded - prepares for building preloaded code (only in Clearcase)"
- echo " update_preloaded - creates the preloaded beam code, the one shipped"
- echo " commit_preloaded - commits the preloaded code (only in Clearcase)"
- echo " cancel_preloaded - uncheckout preloaded code (only in Clearcase)"
+ case $version_controller in
+ none)
+ ;;
+ clearcase)
+ echo ""
+ echo "Handle the primary bootstrap in Clearcase:"
+ echo " prepare_primary - prepare for building a primary bootstrap"
+ echo " update_primary - create the primary bootstrap"
+ echo " commit_primary - commit a primary bootstrap"
+ echo " cancel_primary - uncheckout a primary bootstrap"
+ ;;
+ git)
+ echo ""
+ echo "update_primary - build and commit a new primary bootstrap"
+ ;;
+ esac
+
+ case $version_controller in
+ none)
+ ;;
+ clearcase)
+ echo ""
+ echo "Handle the preloaded modules in Clearcase:"
+ echo " prepare_preloaded - prepares for building preloaded code"
+ echo " update_preloaded - creates the preloaded code"
+ echo " commit_preloaded - commits the preloaded code"
+ echo " cancel_preloaded - uncheckout preloaded code"
+ ;;
+ git)
+ echo ""
+ echo "update_preloaded - build and commit the preloaded modules"
+ ;;
+ esac
}
-xcomp_fail ()
+hide_vars ()
{
- echo "The mandatory cross compilation variable" $1 "is not set in" $2 ",aborting" >&2
- exit 1
+ script=
+ for var in "$@"; do
+ if [ "X$var" != "X" ]; then
+ script="$script test \"X\$$var\" = \"X\" || hidden_$var=\$$var; unset $var;"
+ fi
+ done
+ if [ "X$script" != "X" ]; then
+ eval "$script"
+ fi
+ unset script
}
-check_xcomp_file ()
+restore_vars ()
{
- 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
- fi
- if test "x$erl_xcomp_sizeof_size_t" = "x"; then
- xcomp_fail erl_xcomp_sizeof_size_t $1
- fi
- if test "x$erl_xcomp_sizeof_off_t" = "x"; then
- xcomp_fail erl_xcomp_sizeof_off_t $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
+ script=
+ for var in "$@"; do
+ if [ "X$var" != "X" ]; then
+ script="$script unset $var; test \"X\$hidden_$var\" = \"X\" || { $var=\$hidden_$var; export $var; } ; unset hidden_$var;"
fi
+ done
+ if [ "X$script" != "X" ]; then
+ eval "$script"
fi
- return 0
+ unset script
}
@@ -126,6 +145,7 @@ check_erltop ()
if [ -f ./otp_build -a -f ./erts/autoconf/config.guess ]; then
ERLTOP_FORCED=true
ERL_TOP=`/bin/pwd`
+ export ERL_TOP
else
echo "The environment variable ERL_TOP must be set." >&2
exit 1
@@ -140,28 +160,53 @@ target_contains ()
return $?
}
+determine_version_controller ()
+{
+ version_controller=none
+ # The current directory is now $ERL_TOP. Check for
+ # either this directory being controlled by git or
+ # for the "otp_build" file being a Clearcase controlled
+ # object.
+ if { git rev-parse --git-dir; } 2>/dev/null >/dev/null; then
+ version_controller=git
+ else
+ if test -d "otp_build@@/"; then
+ version_controller=clearcase
+ fi
+ fi
+}
# Execution of the different options
# Special static config flags for certain platforms are set here
set_config_flags ()
{
+ # * Extra flags to pass to configure are placed in `CONFIG_FLAGS'.
+ # * The command line is no longer added to `CONFIG_FLAGS' by
+ # `set_config_flags'. It is instead passed directly to
+ # `run_configure', or added to `CONFIG_FLAGS' at some other
+ # place.
+ # * `CONFIG_FLAGS' may contain flags when `set_config_flags' is
+ # called. These flags should survive the call to `set_config_flags'
+ # (in the cross compilation case the whole command line as well as
+ # the cross configuration have been moved here).
+
if target_contains linux; then
XX=`echo $* | grep -v able-hipe`
if [ "$*" = "$XX" ]; then
- CONFIG_FLAGS="--disable-hipe"
+ CONFIG_FLAGS="$CONFIG_FLAGS --disable-hipe"
fi
fi
if target_contains "univel-sysv4"; then
- CONFIG_FLAGS="--x-libraries=/usr/lib/X11"
+ CONFIG_FLAGS="$CONFIG_FLAGS --x-libraries=/usr/lib/X11"
fi
if target_contains free_source; then
CONFIG_FLAGS="$CONFIG_FLAGS --host=$TARGET"
fi
if target_contains win32; then
- CONFIG_FLAGS="--build=$BUILDSYS build_alias=win32 --host=win32 --target=win32"
+ CONFIG_FLAGS="--build=$BUILDSYS build_alias=win32 --host=win32 --target=win32 $CONFIG_FLAGS"
else
# Link SSL static for all binary distributions if not overridden
XX=`echo $* | grep -v dynamic-ssl-lib`
@@ -175,12 +220,63 @@ set_config_flags ()
CONFIG_FLAGS="$CONFIG_FLAGS --cache-file=$OVERRIDE_CONFIG_CACHE"
fi
- CONFIG_FLAGS="$CONFIG_FLAGS $*"
+ env_to_config_flags $erl_build_tool_vars
+
export CONFIG_FLAGS;
}
-
+
+NL="\
+"
+create_lib_configure_in()
+{
+ cd $ERL_TOP
+
+ # Multiple versions of autoconf generates code that
+ # don't work on all platforms (e.g. SunOS 5.8) if
+ # sub directories are soft links. Internally at Ericsson
+ # some OTP application directories are soft links.
+ # An added "/." solves this problem.
+
+ sdirs=
+ for lib_app in $bootstrap_apps; do
+ case $lib_app in
+ lib/*)
+ if [ -f "$lib_app/configure.in" ]; then
+ app=`echo "$lib_app" | sed "s|lib/\(.*\)|\1|"`
+ sdirs="${sdirs}test ! -f $app/configure || AC_CONFIG_SUBDIRS($app/.)${NL}"
+ fi;;
+ *)
+ ;;
+ esac
+ done
+
+ sed_bootstrap="s%@BOOTSTRAP_CONFIGURE_APPS@%$sdirs%g"
+
+ sdirs=
+ for lib_app in lib/*; do
+ is_bapp=false
+ for bapp in $bootstrap_apps; do
+ test $bapp != $lib_app || { is_bapp=true; break; }
+ done
+ if [ $is_bapp = false ] && [ -f "$lib_app/configure.in" ]; then
+ app=`echo "$lib_app" | sed "s|lib/\(.*\)|\1|"`
+ sdirs="${sdirs} test ! -f $app/configure || AC_CONFIG_SUBDIRS($app/.)${NL}"
+ fi
+ done
+
+ sed_non_bootstrap="s%@NON_BOOTSTRAP_CONFIGURE_APPS@%$sdirs%g"
+
+ rm -f lib/configure.in
+ sed "$sed_bootstrap;$sed_non_bootstrap" > lib/configure.in < lib/configure.in.src || {
+ echo "Failed to create lib/configure.in"
+ exit 1
+ }
+}
+
do_autoconf ()
{
+ create_lib_configure_in
+
if target_contains win32; then
# Select the correct autoconf on cygwin
save_want_autoconf_ver=$WANT_AUTOCONF_VER
@@ -205,17 +301,8 @@ do_autoconf ()
;;
esac
- if [ -d erts/autom4te.cache ]; then
- echo "Cleaning erts/autom4te.cache"
- rm -f erts/autom4te.cache/*
- fi
-
- save_ot="$OVERRIDE_TARGET"
- save_t="$TARGET"
if [ ! -z "$OVERRIDE_CONFIGURE" ]; then
echo "Autoconf disabled on target $TARGET, but is performed on host" >&2
- OVERRIDE_TARGET=
- export OVERRIDE_TARGET
# We still use erts configure for erl_interface and VxWorks
case "$TARGET" in
*vxworks*)
@@ -225,23 +312,30 @@ do_autoconf ()
-e 's,lib/megaco,,'`
;;
esac
- TARGET=`$ERL_TOP/erts/autoconf/config.guess`
fi
+ hide_vars OVERRIDE_TARGET TARGET
+ TARGET=$BUILDSYS
+ export TARGET
+
for d in $AUTOCONF_SUBDIRS; do
- if [ -f $d/configure.in ]; then
- echo "=== running autoconf in $d"
- ( cd $d && autoconf ) || exit 1
- fi
- if [ x$d = x"erts" ]; then
- echo "=== running autoheader in $d"
- ( cd $d && autoheader configure.in > config.h.in ) \
- || exit 1
- fi
+ file="$d/configure.in"
+ [ -f "$file" ] || continue
+ echo ""
+ [ ! -d "$d/autom4te.cache" ] || {
+ echo "=== cleaning $d/autom4te.cache"
+ rm -f "$d"/autom4te.cache/*
+ }
+ echo "=== running autoconf in $d"
+ ( cd "$d" && autoconf ) || exit 1
+ chdr=`cat "$file" | sed -n "s|.*\(AC_CONFIG_HEADER\).*|\1|p"`
+ [ "$chdr" = "AC_CONFIG_HEADER" ] || continue
+ echo "=== running autoheader in $d"
+ ( cd "$d" && autoheader ) || exit 1
done
- OVERRIDE_TARGET="$save_ot"
- export OVERRIDE_TARGET
- TARGET="$save_t"
+
+ restore_vars OVERRIDE_TARGET TARGET
+
if target_contains win32; then
WANT_AUTOCONF_VER=$save_want_autoconf_ver
export WANT_AUTOCONF_VER
@@ -258,22 +352,180 @@ mk_targetdir ()
fi
}
+run_configure ()
+{
+ cdir="$ERL_TOP"
+ [ -z "$ONLY_ERTS" ] || {
+ cdir="$ERL_TOP/erts"
+ CONFIG_FLAGS="$CONFIG_FLAGS --no-recursion"
+ }
+
+ echo "$cdir/configure $CONFIG_FLAGS" ${1+"$@"}
+ (cd "$cdir" && $config_eval ./configure $CONFIG_FLAGS ${1+"$@"}) || exit 1
+}
+
+env_to_config_flags ()
+{
+ for env_var in "$@"; do
+ script="echo $env_var=\$$env_var; unset $env_var >/dev/null 2>&1"
+ env_arg=`eval $script`
+ case $env_arg in
+ "$env_var=")
+ ;;
+ *[!$DONT_QUOTE]*)
+ config_eval=eval
+ new_arg=`echo "X$env_arg" | sed "s|^X||;s|\([^$DONT_QUOTE]\)|\\\\\\\\\1|g"`
+ CONFIG_FLAGS="$CONFIG_FLAGS $new_arg";;
+ *)
+ CONFIG_FLAGS="$CONFIG_FLAGS $env_arg";;
+ esac
+ eval unset $env_var
+ done
+}
+
+try_cross_configure ()
+{
+ cross_configure=no
+ host_value=
+ build_value=
+
+ # Get `erl_xcomp_vars'
+ . "$ERL_TOP/xcomp/erl-xcomp-vars.sh" || exit 1
+
+ for arg in ${1+"$@"}; do
+ case "$arg" in
+ --host=*)
+ host_value=`echo $x | sed "s|^--host=\(.*\)|\1|"`;;
+ --build=*)
+ build_value=`echo $x | sed "s|^--build=\(.*\)|\1|"`;;
+ --xcomp-conf=*)
+ cross_configure=yes;;
+ *)
+ ;;
+ esac
+ done
+
+ test $cross_configure = yes || {
+
+ test "X$host_value" = "X" || {
+
+ test "X$build_value" != "X" || build_value="$BUILDSYS"
+
+ build_sys=`$ERL_TOP/erts/autoconf/config.sub "$build_value"` || exit 1
+ host_sys=`$ERL_TOP/erts/autoconf/config.sub "$host_value"` || exit 1
+
+
+ test "$host_sys" = "$build_sys" || cross_configure=yes
+ }
+ }
+
+ test $cross_configure = yes || return 1
+
+ # cross configure...
+ CONFIG_FLAGS=
+
+ env_to_config_flags $erl_build_tool_vars $erl_xcomp_vars
+
+ for arg in ${1+"$@"}; do
+ case "$arg" in
+ --host=*)
+ host_value=`echo $x | sed "s|^--host=\(.*\)|\1|"`;;
+ --build=*)
+ build_value=`echo $x | sed "s|^--build=\(.*\)|\1|"`;;
+ --xcomp-conf=*)
+ # tilde expansion is not handled by the `configure' script,
+ # but we do it for this argument. This argument is however not
+ # a `configure' argument.
+ xcomp_conf=`echo "X$arg" | sed "s|^X--xcomp-conf=\(.*\)\$|\1|g;s|\([^$DONT_QUOTE]\)|\\\\\\\\\1|g"`
+ eval "xcomp_conf=$xcomp_conf"
+ test "X$xcomp_conf" != "X" || {
+ echo "$0: Missing xcomp-conf file name"
+ exit 1
+ }
+ test -f "$xcomp_conf" || {
+ echo "$0: Missing xcomp-conf file: $xcomp_conf"
+ exit 1
+ }
+ . "$xcomp_conf"
+ test $? -eq 0 || {
+ echo "$0: Failed to read xcomp-conf file: $xcomp_conf"
+ exit 1
+ }
+ test "X$erl_xcomp_build" = "X" || build_value="$erl_xcomp_build"
+ test "X$erl_xcomp_host" = "X" || host_value="$erl_xcomp_host"
+ unset erl_xcomp_build
+ unset erl_xcomp_host
+ CONFIG_FLAGS="$CONFIG_FLAGS $erl_xcomp_configure_flags"
+ unset erl_xcomp_configure_flags
+ env_to_config_flags $erl_build_tool_vars $erl_xcomp_vars;;
+ *[!$DONT_QUOTE]*)
+ config_eval=eval
+ new_arg=`echo "X$arg" | sed "s|^X||;s|\([^$DONT_QUOTE]\)|\\\\\\\\\1|g"`
+ CONFIG_FLAGS="$CONFIG_FLAGS $new_arg";;
+ *)
+ CONFIG_FLAGS="$CONFIG_FLAGS $arg";;
+ esac
+ done
+
+ CONFIG_FLAGS="--host=$host_value $CONFIG_FLAGS"
+ test "X$build_value" != "Xguess" || build_value="$BUILDSYS"
+ test "X$build_value" = "X" || CONFIG_FLAGS="--build=$build_value $CONFIG_FLAGS"
+
+ # Configure build system for boot strap
+ cat <<EOF
+
+*
+* Configuring the bootstrap build system...
+*
+
+EOF
+
+ # hide build tools environment which is for the cross configure
+ set_config_flags $CONFIG_FLAGS
+ hide_vars CONFIG_FLAGS
+
+ set_config_flags
+ run_configure --enable-bootstrap-only
+
+ # restore the hidden build tools environment for the cross configure
+ restore_vars CONFIG_FLAGS
+
+ COMPFIX=""
+ cat <<EOF
+
+*
+* Configuring the cross host system ($host_value)...
+*
+
+EOF
+ # We don't pass the command line here since we already have moved it
+ # into CONFIG_FLAGS
+ run_configure
+
+ return 0
+}
+
do_configure ()
{
setup_make
mk_targetdir
- save_ot="$OVERRIDE_TARGET"
- save_t="$TARGET"
+
+ # Get `erl_build_tool_vars'
+ . "$ERL_TOP/erl-build-tool-vars.sh" || exit 1
+
if [ ! -z "$OVERRIDE_CONFIGURE" ]; then
case $TARGET in
vxworks_*)
( cd erts/autoconf && \
$ERL_TOP/erts/autoconf/configure.vxworks $TARGET )
- echo "Configuring for build host too..." >&2
- OVERRIDE_TARGET=
- export OVERRIDE_TARGET
- TARGET=`$ERL_TOP/erts/autoconf/config.guess`
- mk_targetdir;;
+ echo "Configuring for build system too..." >&2
+ hide_vars OVERRIDE_TARGET TARGET
+ TARGET=$BUILDSYS
+ export TARGET
+ mk_targetdir
+ set_config_flags "$@"
+ run_configure "$@"
+ restore_vars OVERRIDE_TARGET TARGET;;
*)
echo "Unexpected target when ordinary configure is" \
"overridden" >&2
@@ -282,106 +534,13 @@ do_configure ()
exit 1;;
esac
else
- if [ "x$OVERRIDE_TARGET" != "x" -a "x$OVERRIDE_TARGET" != "xwin32" ]; then
- save_CONFIG_FLAGS="$CONFIG_FLAGS"
- if [ "x$erl_xcomp_configure_flags" != "x" ]; then
- set_config_flags $erl_xcomp_configure_flags
- else
- set_config_flags $CONFIG_FLAGS "$@"
- fi
- COMPFIX=""
- save_CC="$CC"
- save_LD="$LD"
- save_CFLAGS="$CFLAGS"
- save_LDFLAGS="$LDFLAGS"
- save_RANLIB="$RANLIB"
- save_AR="$AR"
- save_DED_LD="$DED_LD"
- save_DED_LDFLAGS="$DED_LDFLAGS"
- save_DED_LD_FLAG_RUNTIME_LIBRARY_PATH="$DED_LD_FLAG_RUNTIME_LIBRARY_PATH"
- save_CPP="$CPP"
- if [ "x$erl_xcomp_cc" != "x" ]; then
- CC="$erl_xcomp_cc"
- fi
- if [ "x$erl_xcomp_cpp" != "x" ]; then
- CPP="$erl_xcomp_cpp"
- fi
- if [ "x$erl_xcomp_ld" != "x" ]; then
- LD="$erl_xcomp_ld"
- fi
- if [ "x$erl_xcomp_cflags" != "x" ]; then
- CFLAGS="$erl_xcomp_cflags"
- fi
- if [ "x$erl_xcomp_ldflags" != "x" ]; then
- LDFLAGS="$erl_xcomp_ldflags"
- fi
- if [ "x$erl_xcomp_ranlib" != "x" ]; then
- RANLIB="$erl_xcomp_ranlib"
- fi
- if [ "x$erl_xcomp_ar" != "x" ]; then
- AR="$erl_xcomp_ar"
- fi
- if [ "x$erl_xcomp_ded_ld" != "x" ]; then
- DED_LD="$erl_xcomp_ded_ld"
- fi
- if [ "x$erl_xcomp_ded_ld_runtime_library_path" != "x" ]; then
- DED_LD_FLAG_RUNTIME_LIBRARY_PATH="$erl_xcomp_ded_ld_runtime_library_path"
- fi
- if [ "x$erl_xcomp_ded_ldflags" != "x" ]; then
- DED_LDFLAGS="$erl_xcomp_ded_ldflags"
- fi
- export CC LD CFLAGS LDFLAGS RANLIB AR DED_LD DED_LDFLAGS DED_LD_FLAG_RUNTIME_LIBRARY_PATH CPP
-
- #
- # The environment for compilers, cflags et al are sometimes hard
- # to pass along in recursive configure, why each cross configure
- # is run separately instead. This variable (crossdirs) need to
- # be updated whenever a new application needs a configure
- # of it's own, at least until I get the recirsive configure
- # to work for the complicated environment needed by i.e. vxworks
- # 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
- else
- (cd $ERL_TOP/erts;./configure --host=$erl_xcomp_hw --with-xcompconf=$ERL_XCOMP_CONF $CONFIG_FLAGS) || exit 1
- fi
- CC="$save_CC"
- LD="$save_LD"
- CFLAGS="$save_CFLAGS"
- LDFLAGS="$save_LDFLAGS"
- RANLIB="$save_RANLIB"
- AR="$save_AR"
- DED_LD="$save_DED_LD"
- DED_LDFLAGS="$save_DED_LDFLAGS"
- DED_LD_FLAG_RUNTIME_LIBRARY_PATH="$save_DED_LD_FLAG_RUNTIME_LIBRARY_PATH"
- CPP="$save_CPP"
- export CC LD CFLAGS LDFLAGS RANLIB AR DED_LD DED_LDFLAGS DED_LD_FLAG_RUNTIME_LIBRARY_PATH CPP
- echo "Configuring for build host too..." >&2
- OVERRIDE_TARGET=
- export OVERRIDE_TARGET
- TARGET=`$ERL_TOP/erts/autoconf/config.guess`
- mk_targetdir
- CONFIG_FLAGS="$save_CONFIG_FLAGS"
+ try_cross_configure "$@"
+ if [ $cross_configure = no ]; then
+ CONFIG_FLAGS=
+ set_config_flags "$@"
+ run_configure "$@"
fi
fi
- set_config_flags $CONFIG_FLAGS "$@"
- if [ -z "$ONLY_ERTS" ]; then
- ./configure $CONFIG_FLAGS || exit 1
- else
- echo "erts/configure $CONFIG_FLAGS"
- (cd $ERL_TOP/erts; ./configure $CONFIG_FLAGS) || exit 1
- fi
- OVERRIDE_TARGET="$save_ot"
- export OVERRIDE_TARGET
- TARGET="$save_t"
}
do_lazy_configure ()
@@ -391,7 +550,10 @@ do_lazy_configure ()
echo "Not supported for cross compilation" >&2
exit 1
fi
- set_config_flags $CONFIG_FLAGS "$@"
+ CONFIG_FLAGS=
+ set_config_flags "$@"
+ CONFIGURE_FLAGS="$@"
+ [ "$CONFIG_FLAGS" = "" ] || CONFIGURE_FLAGS="$CONFIG_FLAGS $CONFIGURE_FLAGS"
for c_dir in $AUTOCONF_SUBDIRS; do
if test -f $ERL_TOP/$c_dir/configure.in; then
dir=$ERL_TOP/$c_dir
@@ -406,7 +568,7 @@ do_lazy_configure ()
$MAKE -f $ERL_TOP/make/lazy_configure.mk \
MAKE="$MAKE" TARGET=$TARGET \
ERL_TOP=$ERL_TOP \
- CONFIGURE_FLAGS="$CONFIG_FLAGS" \
+ CONFIGURE_FLAGS="$CONFIGURE_FLAGS" \
CONFIGURE_DIR=$dir \
EXTRA_CONFIGURE_DEPENDENCIES=$xc_dep \
EXTRA_CONFIG_STATUS_DEPENDENCIES=$xcs_dep \
@@ -549,25 +711,6 @@ echo_env_vxworks ()
echo_envinfo
}
-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
- echo_env_erltop
- echo_setenv ERL_XCOMP_CONF $1 ';'
- echo_setenv OVERRIDE_TARGET $erl_xcomp_target
- echo_envinfo
-}
-
echo_env_win32 ()
{
#echo_envinfo
@@ -739,27 +882,27 @@ do_noboot_lib_and_erts ()
{
setup_make
EMULATORS=emulator
+ if [ X`$MAKE is_cross_configured` = Xyes ]; then
+ TARGET=`$MAKE target_configured`
+ fi
if [ "x$MAKE" != "x$clearmake" ]; then
$MAKE MAKE="$MAKE" TARGET=$TARGET OTP_SMALL_BUILD=$OTP_SMALL_BUILD depend || exit 1;
fi
$MAKE MAKE="$MAKE" TARGET=$TARGET OTP_SMALL_BUILD=$OTP_SMALL_BUILD TYPE=$TYPE FLAVOR=$FLAVOR noboot || exit 1
}
-do_primary_cross ()
+do_primary ()
{
- save_t="$TARGET"
- save_ot="$OVERRIDE_TARGET"
- OVERRIDE_TARGET=
- export OVERRIDE_TARGET
- TARGET=`$ERL_TOP/erts/autoconf/config.guess`
- $MAKE MAKE="$MAKE" BOOTSTRAP_ROOT=$BOOTSTRAP_ROOT TARGET=$TARGET primary_bootstrap || exit 1;
- $MAKE MAKE="$MAKE" BOOTSTRAP_ROOT=$BOOTSTRAP_ROOT TARGET=$TARGET all_bootstraps || exit 1
- OVERRIDE_TARGET="$save_ot"
- export OVERRIDE_TARGET
- TARGET="$save_t"
+ setup_make
+ if [ "x$OVERRIDE_TARGET" != "x" -a "x$OVERRIDE_TARGET" != "xwin32" ]; then
+ echo "OVERRIDE_TARGET set" >&2
+ exit 1
+ else
+ $MAKE MAKE="$MAKE" BOOTSTRAP_ROOT=$BOOTSTRAP_ROOT TARGET=$TARGET primary_bootstrap || exit 1;
+ fi
}
-do_primary ()
+do_primary_git ()
{
setup_make
if [ "x$OVERRIDE_TARGET" != "x" -a "x$OVERRIDE_TARGET" != "xwin32" ]; then
@@ -767,8 +910,15 @@ do_primary ()
else
$MAKE MAKE="$MAKE" BOOTSTRAP_ROOT=$BOOTSTRAP_ROOT TARGET=$TARGET primary_bootstrap || exit 1;
fi
+ git add -A bootstrap/lib/kernel \
+ bootstrap/lib/stdlib \
+ bootstrap/lib/compiler \
+ bootstrap/lib/orber/include \
+ bootstrap/bin
+ git commit -m 'Update primary bootstrap'
}
+
do_prepare ()
{
CT=`lookup_prog_in_path cleartool`
@@ -863,7 +1013,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 '*****************************************************'
}
@@ -871,10 +1021,6 @@ do_prepare_prel ()
do_update_prel ()
{
CT=`lookup_prog_in_path cleartool`
- if [ X"$CLEARCASE_ROOT" = X"" -o X"$CT" = X"" ]; then
- echo "To prepare for update of preloaded code, you have to run in a Clearcase view" >&2
- return
- fi
if [ X"$ERL_TOP" = X"" ]; then
echo "ERL_TOP is not set." >&2
@@ -890,6 +1036,16 @@ do_update_prel ()
echo '*****************************************************'
}
+do_update_prel_git ()
+{
+ setup_make
+ (cd $ERL_TOP/erts/preloaded/src && $MAKE MAKE="$MAKE" BOOTSTRAP_ROOT=$BOOTSTRAP_ROOT TARGET=$TARGET clean)
+ $MAKE MAKE="$MAKE" BOOTSTRAP_ROOT=$BOOTSTRAP_ROOT TARGET=$TARGET preloaded || exit 1
+ (cd $ERL_TOP/erts/preloaded/src && $MAKE MAKE="$MAKE" BOOTSTRAP_ROOT=$BOOTSTRAP_ROOT TARGET=$TARGET copy)
+ git add -A $ERL_TOP/erts/preloaded/ebin/*.beam
+ git commit -m 'Update preloaded modules'
+}
+
do_commit_prel ()
{
CT=`lookup_prog_in_path cleartool`
@@ -931,58 +1087,54 @@ do_cancel_prel ()
echo '*****************************************************'
}
-
-
-do_boot_cross ()
-{
- SAVE_TARGET=$TARGET
- SAVE_OVERRIDE_TARGET=$OVERRIDE_TARGET
- OVERRIDE_TARGET=
- 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;
-}
-
-do_boot_emu_cross ()
-{
- $MAKE MAKE="$MAKE" BOOTSTRAP_ROOT=$BOOTSTRAP_ROOT TARGET=$TARGET emulator || exit 1;
-}
do_boot ()
{
setup_make
- if [ "x$OVERRIDE_TARGET" != "x" -a "x$OVERRIDE_TARGET" != "xwin32" ]; then
- do_boot_cross
- else
- $MAKE MAKE="$MAKE" BOOTSTRAP_ROOT=$BOOTSTRAP_ROOT TARGET=$TARGET all || exit 1
+
+ # Bootstrap if we are cross compiling
+ if [ X`$MAKE is_cross_configured` = Xyes ]; then
+ TARGET=$BUILDSYS
+ $MAKE MAKE="$MAKE" BOOTSTRAP_ROOT=$BOOTSTRAP_ROOT CROSS_COMPILING=no TARGET=$TARGET bootstrap || exit 1
+ TARGET=`$MAKE target_configured`
+ elif [ "x$OVERRIDE_TARGET" != "x" -a "x$OVERRIDE_TARGET" != "xwin32" ]; then
+ hide_vars OVERRIDE_TARGET TARGET
+ TARGET=$BUILDSYS
+ $MAKE MAKE="$MAKE" BOOTSTRAP_ROOT=$BOOTSTRAP_ROOT TARGET=$TARGET bootstrap || exit 1
+
+ restore_vars OVERRIDE_TARGET TARGET
fi
+
+ # Build it (including bootstrap if not cross compiling)
+ $MAKE MAKE="$MAKE" BOOTSTRAP_ROOT=$BOOTSTRAP_ROOT TARGET=$TARGET all || exit 1
}
do_boot_emu ()
{
setup_make
- if [ "x$OVERRIDE_TARGET" != "x" -a "x$OVERRIDE_TARGET" != "xwin32" ]; then
- do_boot_emu_cross
- else
- $MAKE MAKE="$MAKE" BOOTSTRAP_ROOT=$BOOTSTRAP_ROOT TARGET=$TARGET emulator || exit 1
+ if [ X`$MAKE is_cross_configured` = Xyes ]; then
+ TARGET=`$MAKE target_configured`
fi
+ $MAKE MAKE="$MAKE" BOOTSTRAP_ROOT=$BOOTSTRAP_ROOT TARGET=$TARGET emulator || exit 1
}
do_release ()
{
setup_make
- $MAKE MAKE="$MAKE" BOOTSTRAP_ROOT=$BOOTSTRAP_ROOT TARGET=$TARGET RELEASE_ROOT=$1 release || exit 1
+ if [ X`$MAKE is_cross_configured` = Xyes ]; then
+ TARGET=`$MAKE target_configured`
+ fi
+ $MAKE MAKE="$MAKE" BOOTSTRAP_ROOT=$BOOTSTRAP_ROOT TARGET=$TARGET \
+ RELEASE_ROOT=$1 OTP_STRICT_INSTALL=$OTP_STRICT_INSTALL \
+ release || exit 1
}
do_tests ()
{
setup_make
+ if [ X`$MAKE is_cross_configured` = Xyes ]; then
+ TARGET=`$MAKE target_configured`
+ fi
if [ X"$1" = X"" ]; then
$MAKE MAKE="$MAKE" TARGET=$TARGET release_tests || exit 1
else
@@ -1099,6 +1251,8 @@ check_erltop
cd $ERL_TOP
+determine_version_controller
+
# Unset ERL_FLAGS and ERL_<Release>_FLAGS to prevent, for instance,
# a value of "-hybrid" to run the hybrid emulator during bootstrap.
sys_vsn=`awk '/SYSTEM_VSN = / {print $3}' < erts/vsn.mk`
@@ -1158,10 +1312,6 @@ else
fi
export OTP_SMALL_BUILD
-if [ "x$ERL_XCOMP_CONF" != "x" ]; then
- . $ERL_XCOMP_CONF
-fi
-
TYPE=
case "$1" in
all)
@@ -1203,7 +1353,7 @@ case "$1" in
do_lazy_configure_target_clean;;
opt)
do_boot;;
- plain|smp|hybrid|nofrag)
+ plain|smp|hybrid)
if [ $minus_a_flag = false ]; then
TYPE=opt
fi;
@@ -1215,7 +1365,11 @@ case "$1" in
prepare_primary)
do_prepare;;
update_primary)
- do_primary;;
+ case $version_controller in
+ git) do_primary_git ;;
+ clearcase) do_primary ;;
+ none) do_primary ;;
+ esac ;;
commit_primary)
do_commit;;
cancel_primary)
@@ -1223,7 +1377,11 @@ case "$1" in
prepare_preloaded)
do_prepare_prel;;
update_preloaded)
- do_update_prel;;
+ case $version_controller in
+ git) do_update_prel_git ;;
+ clearcase) do_update_prel ;;
+ none) do_update_prel ;;
+ esac ;;
commit_preloaded)
do_commit_prel;;
cancel_preloaded)
diff --git a/prebuild.skip b/prebuild.skip
index 1f88ed4c6d..e366c6a164 100644
--- a/prebuild.skip
+++ b/prebuild.skip
@@ -1,3 +1,4 @@
Makefile
bin
bootstrap/bin
+ibin
diff --git a/system/AD.html b/system/AD.html
deleted file mode 100644
index 695f3b40aa..0000000000
--- a/system/AD.html
+++ /dev/null
@@ -1,307 +0,0 @@
-<HTML>
-<HEAD>
-<TITLE>AMENDMENT DIRECTIVE, OTP</TITLE>
-</HEAD>
-<BODY BGCOLOR="#FFFFFF">
-<CENTER>
-<A HREF="http://otp.ericsson.se"><IMG BORDER=0 ALT="[OTP]" SRC="http://otp.ericsson.se/pics/banner/min_head.gif"></A>
-<H1>AMENDMENT DIRECTIVE, OTP</H1>
-<FONT SIZE="+1">
-1/177 82 - APN 181 01I<BR>
-UAB/F Kenneth Lundin, Lars Thors�n, Morgan Eriksson<BR>
-961023<BR>
-</FONT>
-</CENTER>
-<BLOCKQUOTE>
-<H2>Table of Contents</H2>
-1 <A HREF="#1">Introduction</A><BR>
-1.1 <A HREF="#1.1">Purpose</A><BR>
-1.2 <A HREF="#1.2">Revision History</A><BR>
-2 <A HREF="#2">Product Identities</A><BR>
-3 <A HREF="#3">Document Survey</A><BR>
-4 <A HREF="#4">Implemented Change requests</A><BR>
-5 <A HREF="#5">Implemented Trouble Reports</A><BR>
-6 <A HREF="#6">Installation Instructions</A><BR>
-6.1 <A HREF="#6.1">Separate (optional) Installation of XNTP (Network Time Protocol)</A><BR>
-7 <A HREF="#7">Some useful notes</A><BR>
-8 <A HREF="#8">Known problems in this release</A><BR>
-9 <A HREF="#9">References</A><BR>
-
-<A NAME="1"><!-- Empty --></A><H2>1 Introduction</H2>
-<P><A NAME="1.1"><!-- Empty --></A><H3>1.1 Purpose</H3>
-<P>This update release, OTP P1H, contains a fix for the erl_call problems in OTP P1G.<A NAME="1.2"><!-- Empty --></A><H3>1.2 Revision History</H3>
-<P>Rev.A:Kenneth Lundin 1996-05-31<BR>
-
-Rev.B:Lars Thors�n 1996-06-04<BR>
-
-Rev.C:Kenneth Lundin 1996-06-14<BR>
-
-Rev.D:Kenneth Lundin 1996-08-28<BR>
-
-Rev.E:Lars Thors�n 1996-09-12<BR>
-
-Rev.F:Kenneth Lundin 1996-09-13<BR>
-
-Rev.G:Morgan Ericsson 1996-10-08<BR>
-
-Rev.H:Kenneth Lundin 1996-10-14<BR>
-
-Rev.I:Morgan Eriksson 1996-10-23<BR>
-<P>The exact changes between revisions of this document can be generated from our ClearCase repository upon request , or a simple unix "diff" can be used.<A NAME="2"><!-- Empty --></A><H2>2 Product Identities</H2>
-<P><P><TABLE BORDER=1>
-<TR>
-<TD><B>Product Name</B></TD>
-<TD><B>Product Number</B></TD>
-<TD><B>R-state</B></TD>
-</TR>
-<TR>
-<TD>OTP</TD>
-<TD>APN 181 01</TD>
-<TD>P1H</TD>
-</TR>
-<TR>
-<TD>ERTS (sunos4)</TD>
-<TD>CXC 138 10/1</TD>
-<TD>P1G</TD>
-</TR>
-<TR>
-<TD>ERTS (sunos5)</TD>
-<TD>CXC 138 10/2</TD>
-<TD>P1G</TD>
-</TR>
-<TR>
-<TD>SASL (BOS) (sunos4)</TD>
-<TD>CXC 138 11/1</TD>
-<TD>P1D</TD>
-</TR>
-<TR>
-<TD>SASL (BOS) (sunos5)</TD>
-<TD>CXC 138 11/2</TD>
-<TD>P1D</TD>
-</TR>
-<TR>
-<TD>MNESIA</TD>
-<TD>CXC 138 12/1</TD>
-<TD>P1E</TD>
-</TR>
-<TR>
-<TD>SNMPEA</TD>
-<TD>CXC 138 13/1</TD>
-<TD>P1D</TD>
-</TR>
-<TR>
-<TD>ERLDEV (Compiler & Debugger)</TD>
-<TD>CXC 138 15/1</TD>
-<TD>P1C</TD>
-</TR>
-<TR>
-<TD>DEVTOOLS (sunos4)</TD>
-<TD>CXC 138 16/1</TD>
-<TD>P1D</TD>
-</TR>
-<TR>
-<TD>DEVTOOLS (sunos5)</TD>
-<TD>CXC 138 16/2</TD>
-<TD>P1D</TD>
-</TR>
-<TR>
-<TD>XLATETOOLS (sunos4)</TD>
-<TD>CXC 138 17/1</TD>
-<TD>P1D</TD>
-</TR>
-<TR>
-<TD>XLATETOOLS (sunos5)</TD>
-<TD>CXC 138 17/2</TD>
-<TD>P1D</TD>
-</TR>
-<TR>
-<TD>CPO Solaris (XNTP)</TD>
-<TD>CXC 138 46/1</TD>
-<TD>P1A</TD>
-</TR>
-</TABLE>
-<A NAME="3"><!-- Empty --></A><H2>3 Document Survey</H2>
-<P><P><TABLE BORDER=1>
-<TR>
-<TD><B>Document name</B></TD>
-<TD><B>Document number</B></TD>
-<TD>Rev</TD>
-</TR>
-<TR>
-<TD>Systems Overview</TD>
-<TD>1551-APN 181 01</TD>
-<TD>A</TD>
-</TR>
-<TR>
-<TD>Erlang Tools Introduction</TD>
-<TD>EPK-95:030/1</TD>
-<TD>A</TD>
-</TR>
-<TR>
-<TD>Erlang Tools User's Guide</TD>
-<TD>EPK-95:030/2</TD>
-<TD>A</TD>
-</TR>
-<TR>
-<TD>Erlang Tools</TD>
-<TD>EPK-95:030/3</TD>
-<TD>A</TD>
-</TR>
-<TR>
-<TD>Distributed Erlang User's Guide</TD>
-<TD>EPK-95:030/4</TD>
-<TD>A</TD>
-</TR>
-<TR>
-<TD>Erlang Tools Examples</TD>
-<TD>EPK-95:030/5</TD>
-<TD>A</TD>
-</TR>
-<TR>
-<TD>User's Guide to the Erlang Interface Library</TD>
-<TD>3/1553-CNA 121 16</TD>
-<TD>A</TD>
-</TR>
-<TR>
-<TD>Erlang Interface Library Examples</TD>
-<TD>1/198 17-CNA 121 16</TD>
-<TD>A</TD>
-</TR>
-<TR>
-<TD>Programmer's Guide to the Erlang Interface Library</TD>
-<TD>2/198 17-CNA 121 16</TD>
-<TD>A</TD>
-</TR>
-<TR>
-<TD>OTP Erlang User's guide</TD>
-<TD>1553-CNA 121 17</TD>
-<TD>A</TD>
-</TR>
-<TR>
-<TD>The Mnesia Query Language Mnemosyne</TD>
-<TD>1553-CNA 121 18</TD>
-<TD>A</TD>
-</TR>
-<TR>
-<TD>SNMPEA User's Guide</TD>
-<TD>1553-CNA 121 19</TD>
-<TD>A</TD>
-</TR>
-<TR>
-<TD>SNMPEA Reference Guide</TD>
-<TD>1551-CNA 121 19</TD>
-<TD>A</TD>
-</TR>
-<TR>
-<TD>User's Guide to the Interface Generator</TD>
-<TD>1553-CNA 121 38</TD>
-<TD>A</TD>
-</TR>
-</TABLE>
-<P>A complete browseable document survey is available at the OTP WWW-server http://otp.ericsson.se and can also be found in the release at $OTP_ROOT/doc/all.html when the
-release file is un-tar:ed at $OTP_ROOT.<A NAME="4"><!-- Empty --></A><H2>4 Implemented Change requests</H2>
-<P>-<A NAME="5"><!-- Empty --></A><H2>5 Implemented Trouble Reports</H2>
-<P><P><TABLE BORDER=1>
-<TR>
-<TD><B>Block</B></TD>
-<TD><B>TR id</B></TD>
-<TD><B>Slogan</B></TD>
-</TR>
-<TR>
-<TD>ERTS</TD>
-<TD>-</TD>
-<TD>erl_call crashes (Segmentation fault) has now been fixed</TD>
-</TR>
-</TABLE>
-<A NAME="6"><!-- Empty --></A><H2>6 Installation Instructions</H2>
-<P>The release is delivered as a compressed tar-file <B>otp_APN18101_P1H.&#60;target&#62;.tar.Z</B>, where &#60;target&#62; is substituted with <B>sunos4</B> or <B>sunos5</B>.<P>Then the following steps shall be performed at installation time:<UL>
-<LI>Create a new directory $OTP_INSTALL_DIR where OTP can be installed.
-<PRE>mkdir $OTP_INSTALL_DIR
-cd $OTP_INSTALL_DIR
-uncompress $XXX/otp_APN18101_P1H.&lt;target&gt;.tar.Z
-tar xvfp $XXX/otp_APN18101_P1H.&lt;target&gt;.tar</PRE>
-
-<LI>Run the OTP installscript and answer the questions.
-<PRE>./Install $OTP_INSTALL_DIR</PRE>
-<BR>The Install command will ask a number of questions during the installation.
-<B>OBS!</B> When installing on a system where DNS is not used you
-should answer <B>NO</B> on the question "WILL YOU USE DNS?"
-
-<LI>Prepare the OTP man pages.
-<PRE>mkdir man/cat1 man/cat3
-./format_man_pages</PRE>
-
-<LI>Update the erl_interface library with ranlib (sunos4 only).
-<PRE>cd $OTP_INSTALL_DIR/usr/lib
-ranlib liberl_interface.a</PRE>
-
-</UL>
-<P>Add $OTP_INSTALL_DIR/bin to the path variable and $OTP_INSTALL_DIR/man to the MANPATH variable.<P>Where <B>$XXX</B> denotes the path at which otp_APN18101_P1H.&#60;target&#62;.tar resides.
-<A NAME="6.1"><!-- Empty --></A><H3>6.1 Separate (optional) Installation of XNTP (Network Time Protocol)</H3>
-<P>XNTP (Network Time Protocol) <B>for use in an embedded system running Sunos5</B> is
-delivered in this release. The XNTP resides in the tar-file xntp_CXC_13846_P1A.sunos5.tar.Z and can be fetched with Netscape from the same place as the other OTP deliverables.<UL>
-<LI>Create a new directory $XNTP_DIR where the XNTP distribution can be loaded.
-<PRE>mkdir $XNTP_DIR
-cd $XNTP_DIR
-uncompress $XXX/xntp_CXC_13846_P1A.sunos5.tar.Z
-tar xvf $XXX/xntp_CXC_13846_P1A.sunos5.tar.Z</PRE>
-
-<LI>Read the README-file which is included, below follows information which
-is partly the same as can be found at the end of the README file.
-
-<LI>Note, the xntp3.5a.export subdirectory is not needed for installation.
-
-<BR>Create a suitable configuration file based on the samples in the
-'config' directory, and copy it to /etc/ntp.conf.
-
-<LI>Create a directory for the binaries and copy them there:<BR>
-
-<PRE>mkdir -p /opt/xntp/bin
-cp bin/* /opt/xntp/bin</PRE>
-<BR>Note!, if you prefer another installation directory for the binaries, you have to edit one line in the "Run Commands" script xntp (located in the init directory):
-<PRE>BINDIR=&lt;your new bindir&gt;</PRE>
-
-<LI>Install the "Run Commands" script:<BR>
-
-<PRE>cp init/xntp /etc/init.d/xntp&lt;br&gt;
-ln /etc/init.d/xntp /etc/rc0.d/K57xntp
-ln /etc/init.d/xntp /etc/rc1.d/K57xntp
-ln /etc/init.d/xntp /etc/rc2.d/S78xntp</PRE>
-
-<LI>Modify the /etc/system file (you probably want to save the original):<BR>
-
-<PRE>cat init/system &gt;&gt; /etc/system</PRE>
-
-</UL>
-<P>Where <B>$XXX</B> denotes the path at which xntp_CXC13846_P1A.sunos5.tar.Z resides.<A NAME="7"><!-- Empty --></A><H2>7 Some useful notes</H2>
-<P>To make it possible to browse Framemaker documents through Netscape the files
-.mime.types and .mailcap should be modified (see below). The modifications
-can be made as systems defaults if they are placed in e.g /usr/local/lib/netscape (see Netscape Handbook for details) or as personal defaults if placed in the
-users $HOME directory.<P>.mime.types<P><PRE>application/x-maker fm</PRE>
-<P>
-.mailcap<P><PRE>application/x-maker; fmclient -f %s</PRE>
-<A NAME="8"><!-- Empty --></A><H2>8 Known problems in this release</H2>
-<P><UL>
-<LI>In the manual-page for module code, the returned value of the function
-which is described to be String but in reality it is an Atom (for compatibility
-reasons). In the next release the return type will however be String as it says
-in the manual-page.
-
-<LI>On SunOS4.x platforms, the format_man_pages script (executed as a part of installation) will cause following error messages for missing manual sections:
-<BR>
-<PRE>opendir:man{2,4,5,6,7,8,l,n}: No such file or directory</PRE>
-<BR>These messages should be ignored.
-
-</UL>
-<A NAME="9"><!-- Empty --></A><H2>9 References</H2>
-<P><I>Nothing to reference</I>
-</BLOCKQUOTE>
-<CENTER>
-<HR>
-<P><FONT SIZE=-1>
-Copyright &copy; 1996 <A HREF="http://otp.ericsson.se">Open Telecom Platform</A><BR>
-<!--#include virtual="/ssi/otp_footer.html"-->
-</FONT>
-</CENTER>
-</BODY>
-</HTML>
diff --git a/system/AD.sgml b/system/AD.sgml
deleted file mode 100644
index e7fc9755ed..0000000000
--- a/system/AD.sgml
+++ /dev/null
@@ -1,367 +0,0 @@
-<!doctype report PUBLIC "-//Stork//DTD report//EN">
-
-<report>
- <header>
- <title>AMENDMENT DIRECTIVE, OTP</title>
- <prepared>ETX/B/SFP Kenneth Lundin, Lars Thors&#233;n, Morgan Eriksson</prepared>
- <responsible></responsible>
- <docno>1/177 82 - APN 181 01</docno>
- <approved>ETX/B/SF Torbj&ouml;rn Johnson</approved>
- <checked></checked>
- <date>961023</date>
- <rev>I</rev>
- <file>tr1c.sgml</file>
- </header>
-
-<section>
-<title>Introduction</title>
-<p>
-<section><title>Purpose</title>
-<p>
-This update release, OTP P1H, contains a fix for the erl_call problems in OTP P1G.
-</section>
-
-<section><title>Revision History</title>
-<p>
-Rev.A:Kenneth Lundin 1996-05-31<br>
-Rev.B:Lars Thors&#233;n 1996-06-04<br>
-Rev.C:Kenneth Lundin 1996-06-14<br>
-Rev.D:Kenneth Lundin 1996-08-28<br>
-Rev.E:Lars Thors&#233;n 1996-09-12<br>
-Rev.F:Kenneth Lundin 1996-09-13<br>
-Rev.G:Morgan Ericsson 1996-10-08<br>
-Rev.H:Kenneth Lundin 1996-10-14<br>
-Rev.I:Morgan Eriksson 1996-10-23<br>
-<p>
-The exact changes between revisions of this document can be generated from our ClearCase repository upon request , or a simple unix "diff" can be used.
-</section>
-</section>
-<section><title>Product Identities</title>
-<p>
-<table>
-<row>
-<cell><b>Product Name</b></cell>
-<cell><b>Product Number</b></cell>
-<cell><b>R-state</b></cell>
-</row>
-<row>
-<cell>OTP</cell>
-<cell>APN 181 01</cell>
-<cell>P1H</cell>
-</row>
-<row>
-<cell>ERTS (sunos4)</cell>
-<cell>CXC 138 10/1</cell>
-<cell>P1G</cell>
-</row>
-<row>
-<cell>ERTS (sunos5)</cell>
-<cell>CXC 138 10/2</cell>
-<cell>P1G</cell>
-</row>
-<row>
-<cell>SASL (BOS) (sunos4)</cell>
-<cell>CXC 138 11/1</cell>
-<cell>P1D</cell>
-</row>
-<row>
-<cell>SASL (BOS) (sunos5)</cell>
-<cell>CXC 138 11/2</cell>
-<cell>P1D</cell>
-</row>
-<row>
-<cell>MNESIA</cell>
-<cell>CXC 138 12/1</cell>
-<cell>P1E</cell>
-</row>
-<row>
-<cell>SNMPEA</cell>
-<cell>CXC 138 13/1</cell>
-<cell>P1D</cell>
-</row>
-<row>
-<cell>ERLDEV (Compiler & Debugger)</cell>
-<cell>CXC 138 15/1</cell>
-<cell>P1C</cell>
-</row>
-<row>
-<cell>DEVTOOLS (sunos4)</cell>
-<cell>CXC 138 16/1</cell>
-<cell>P1D</cell>
-</row>
-<row>
-<cell>DEVTOOLS (sunos5)</cell>
-<cell>CXC 138 16/2</cell>
-<cell>P1D</cell>
-</row>
-<row>
-<cell>XLATETOOLS (sunos4)</cell>
-<cell>CXC 138 17/1</cell>
-<cell>P1D</cell>
-</row>
-<row>
-<cell>XLATETOOLS (sunos5)</cell>
-<cell>CXC 138 17/2</cell>
-<cell>P1D</cell>
-</row>
-<row>
-<cell>CPO Solaris (XNTP)</cell>
-<cell>CXC 138 46/1</cell>
-<cell>P1A</cell>
-</row>
-</table>
-</section>
-<section><title>Document Survey</title>
-<p>
-<table>
-<row>
-<cell><b>Document name</b></cell>
-<cell><b>Document number</b></cell>
-<cell>Rev</cell>
-</row>
-<row>
-<cell>Systems Overview</cell>
-<cell>1551-APN 181 01</cell>
-<cell>A</cell>
-</row>
-<row>
-<cell>Erlang Tools Introduction</cell>
-<cell>EPK-95:030/1</cell>
-<cell>A</cell>
-</row>
-<row>
-<cell>Erlang Tools User's Guide</cell>
-<cell>EPK-95:030/2</cell>
-<cell>A</cell>
-</row>
-<row>
-<cell>Erlang Tools</cell>
-<cell>EPK-95:030/3</cell>
-<cell>A</cell>
-</row>
-<row>
-<cell>Distributed Erlang User's Guide</cell>
-<cell>EPK-95:030/4</cell>
-<cell>A</cell>
-</row>
-<row>
-<cell>Erlang Tools Examples</cell>
-<cell>EPK-95:030/5</cell>
-<cell>A</cell>
-</row>
-
-<row>
-<cell>User's Guide to the Erlang Interface Library</cell>
-<cell>3/1553-CNA 121 16</cell>
-<cell>A</cell>
-</row>
-<row>
-<cell>Erlang Interface Library Examples</cell>
-<cell>1/198 17-CNA 121 16</cell>
-<cell>A</cell>
-</row>
-<row>
-<cell>Programmer's Guide to the Erlang Interface Library</cell>
-<cell>2/198 17-CNA 121 16</cell>
-<cell>A</cell>
-</row>
-
-<row>
-<cell>OTP Erlang User's guide</cell>
-<cell>1553-CNA 121 17</cell>
-<cell>A</cell>
-</row>
-
-<row>
-<cell>The Mnesia Query Language Mnemosyne</cell>
-<cell>1553-CNA 121 18</cell>
-<cell>A</cell>
-</row>
-
-<row>
-<cell>SNMPEA User's Guide</cell>
-<cell>1553-CNA 121 19</cell>
-<cell>A</cell>
-</row>
-
-<row>
-<cell>SNMPEA Reference Guide</cell>
-<cell>1551-CNA 121 19</cell>
-<cell>A</cell>
-</row>
-
-<row>
-<cell>User's Guide to the Interface Generator</cell>
-<cell>1553-CNA 121 38</cell>
-<cell>A</cell>
-</row>
-
-</table>
-
-<p>
-A complete browseable document survey is available at the OTP WWW-server http://otp.ericsson.se and can also be found in the release at $OTP_ROOT/doc/all.html when the
-release file is un-tar:ed at $OTP_ROOT.
-</section>
-<section><title>Implemented Change requests</title>
-<p>
--
-</section>
-<section><title>Implemented Trouble Reports</title>
-<p>
-<table>
-<row>
-<cell><b>Block</b></cell>
-<cell><b>TR id</b></cell>
-<cell><b>Slogan</b></cell>
-</row>
-<row>
-<cell>ERTS</cell>
-<cell>-</cell>
-<cell>
-erl_call crashes (Segmentation fault) has now been fixed
-</cell>
-</row>
-</table>
-</section>
-<section><title>Installation Instructions</title>
-<p>
-The release is delivered as a compressed tar-file <b>otp_APN18101_P1H.&lt;target&gt;.tar.Z</b>, where &lt;target&gt; is substituted with <b>sunos4</b> or <b>sunos5</b>.
-<p>
-Then the following steps shall be performed at installation time:
-</p>
-<list>
-<item><p>Create a new directory $OTP_INSTALL_DIR where OTP can be installed.
-<code>
-mkdir $OTP_INSTALL_DIR
-cd $OTP_INSTALL_DIR
-uncompress $XXX/otp_APN18101_P1H.<target>.tar.Z
-tar xvfp $XXX/otp_APN18101_P1H.<target>.tar
-</code>
-</item>
-<item><p>Run the OTP installscript and answer the questions.
-<code>
-./Install $OTP_INSTALL_DIR
-</code>
-<p>
-The Install command will ask a number of questions during the installation.
-<b>OBS!</b> When installing on a system where DNS is not used you
-should answer <b>NO</b> on the question "WILL YOU USE DNS?"
-</item>
-<item><p>Prepare the OTP man pages.
-<code>
-mkdir man/cat1 man/cat3
-./format_man_pages
-</code>
-<item><p>Update the erl_interface library with ranlib (sunos4 only).
-<code>
-cd $OTP_INSTALL_DIR/usr/lib
-ranlib liberl_interface.a
-</code>
-</item>
-</list>
-<p>
-Add $OTP_INSTALL_DIR/bin to the path variable and $OTP_INSTALL_DIR/man to the MANPATH variable.
-<p>
-Where <b>$XXX</b> denotes the path at which otp_APN18101_P1H.&lt;target&gt;.tar resides.
-
-<section><title>Separate (optional) Installation of XNTP (Network Time Protocol)</title>
-<p>
-XNTP (Network Time Protocol) <b>for use in an embedded system running Sunos5</b> is
-delivered in this release. The XNTP resides in the tar-file xntp_CXC_13846_P1A.sunos5.tar.Z and can be fetched with Netscape from the same place as the other OTP deliverables.
-<list>
-<item><p>Create a new directory $XNTP_DIR where the XNTP distribution can be loaded.
-<code>
-mkdir $XNTP_DIR
-cd $XNTP_DIR
-uncompress $XXX/xntp_CXC_13846_P1A.sunos5.tar.Z
-tar xvf $XXX/xntp_CXC_13846_P1A.sunos5.tar.Z
-</code>
-</item>
-<item><p>Read the README-file which is included, below follows information which
-is partly the same as can be found at the end of the README file.</item>
-<item><p>Note, the xntp3.5a.export subdirectory is not needed for installation.
-
-<p>Create a suitable configuration file based on the samples in the
-'config' directory, and copy it to /etc/ntp.conf.</item>
-
-<item><p>Create a directory for the binaries and copy them there:<br>
-<code>
-mkdir -p /opt/xntp/bin
-cp bin/* /opt/xntp/bin
-</code>
-<p>Note!, if you prefer another installation directory for the binaries, you have to edit one line in the "Run Commands" script xntp (located in the init directory):
-<code>
-BINDIR=<your new bindir>;
-</code>
-</item>
-
-<item><p>Install the "Run Commands" script:<br>
-<code>
-cp init/xntp /etc/init.d/xntp<br>
-ln /etc/init.d/xntp /etc/rc0.d/K57xntp
-ln /etc/init.d/xntp /etc/rc1.d/K57xntp
-ln /etc/init.d/xntp /etc/rc2.d/S78xntp
-</code>
-</item>
-
-<item><p>Modify the /etc/system file (you probably want to save the original):<br>
-<code>
-cat init/system >> /etc/system
-</code>
-</item>
-
-</list>
-<p>
-Where <b>$XXX</b> denotes the path at which xntp_CXC13846_P1A.sunos5.tar.Z resides.
-</section>
-</section>
-
-<section><title>Some useful notes</title>
-<p>
-To make it possible to browse Framemaker documents through Netscape the files
-.mime.types and .mailcap should be modified (see below). The modifications
-can be made as systems defaults if they are placed in e.g /usr/local/lib/netscape (see Netscape Handbook for details) or as personal defaults if placed in the
-users $HOME directory.
-<p>
-.mime.types
-<p>
-<pre>
-application/x-maker fm
-</pre>
-<p>
-
-.mailcap
-<p>
-<pre>
-application/x-maker; fmclient -f %s
-</pre>
-</section>
-<section><title>Known problems in this release</title>
-<p>
-<list>
-<item><p>In the manual-page for module code, the returned value of the function
-which is described to be String but in reality it is an Atom (for compatibility
-reasons). In the next release the return type will however be String as it says
-in the manual-page.</item>
-<item><p>On SunOS4.x platforms, the format_man_pages script (executed as a part of installation) will cause following error messages for missing manual sections:
-<p><code>opendir:man{2,4,5,6,7,8,l,n}: No such file or directory</code>
-<p>These messages should be ignored.
-</item>
-
-</list>
-</section>
-<section><title>References</title>
-<p>
-<i>Nothing to reference</i>
-
-</section>
-</report>
-
-
-
-
-
-
-
-
-
diff --git a/system/ADbeam.html b/system/ADbeam.html
deleted file mode 100644
index abb80c9f0a..0000000000
--- a/system/ADbeam.html
+++ /dev/null
@@ -1,261 +0,0 @@
-<HTML>
-<HEAD>
-<TITLE>AMENDMENT DIRECTIVE, OTP-BEAM
- </TITLE>
-</HEAD>
-<BODY BGCOLOR="#FFFFFF">
-<TABLE WIDTH=100%>
-<TR>
-<TD ROWSPAN=2 WIDTH=50%><IMG ALT="Ericsson" SRC="http://otp.ericsson.se/pics/logo/elogo.gif"></TD>
-<TD VALIGN=TOP WIDTH=50%><BR><BR></TD>
-</TR>
-<TR>
-<TD VALIGN=TOP WIDTH=50%><B>OTP Report</B></TD>
-</TR>
-</TABLE><CENTER>
-<TABLE BORDER CELLSPACING=0 CELLPADDING=2 WIDTH=100%>
-<TR>
-<TD VALIGN=TOP WIDTH=30% COLSPAN=3>
-<FONT SIZE=1>Uppgjord - <I>Prepared</I></FONT><BR>
-<FONT SIZE=3>UAB/F Kenneth Lundin, Lars Thors�n
-</FONT>
-</TD>
-<TD VALIGN=TOP WIDTH=20% COLSPAN=2 NOWRAP>
-<FONT SIZE=1>Faktaansvarig - <I>Subject responsible</I></FONT><BR>
-<FONT SIZE=3> </FONT><BR>
-</TD>
-<TD VALIGN=TOP WIDTH=50% COLSPAN=5>
-<FONT SIZE=1>Nr - <I>No</I></FONT><BR>
-<FONT SIZE=3>3/177 82 - APN 181 01
-</FONT>
-</TD>
-</TR>
-<TR>
-<TD VALIGN=TOP WIDTH=40% COLSPAN=4 NOWRAP>
-<FONT SIZE=1>Dokansv/Godk - <I>Doc respons/Approved</I></FONT><BR>
-<FONT SIZE=3>ETX/B/DU Torbj&ouml;rn Johnsson
-</FONT>
-</TD>
-<TD VALIGN=TOP WIDTH=10%>
-<FONT SIZE=1>Kontr - <I>Checked</I></FONT><BR>
-<FONT SIZE=3> </FONT>
-</TD>
-<TD VALIGN=TOP WIDTH=20% COLSPAN=2 NOWRAP>
-<FONT SIZE=1>Datum - <I>Date</I></FONT><BR>
-<FONT SIZE=3>960828
-</FONT></TD>
-<TD VALIGN=TOP WIDTH=10%><FONT SIZE=1>Rev</FONT><BR>
-<FONT SIZE=3>D
-</FONT>
-</TD>
-<TD VALIGN=TOP WIDTH=20% COLSPAN=2>
-<FONT SIZE=1>File</FONT><BR>
-<FONT SIZE=3>tr1c.sgml
-<BR></FONT>
-</TD>
-</TR>
-</TABLE><P>
-<A HREF="http://otp.ericsson.se/">
-<STRONG>OTP</STRONG></A> /
-<STRONG>...</STRONG> /
-<A HREF="../
- ">
-<STRONG>Up</STRONG></A> /
-<P><B><FONT SIZE=8>AMENDMENT DIRECTIVE, OTP-BEAM
-</FONT></B>
-</CENTER>
-<HR>
-<H2>Introduction</H2>
-<P>
-<H3>Purpose</H3>
-<P>This is a first prototype release of the OTP-BEAM system for SunOS5.
-This version is intended to be used for various capacity measurements and the functionality is comparable to that of OTP rev P1D (APN 181 01 P1D).
-
-<H3>Revision History</H3>
-<P>Rev.A:Kenneth Lundin 1996-08-28<BR>
-
-<P>The exact changes between revisions of this document can be generated from our ClearCase repository upon request , or a simple unix "diff" can be used.
-<H2>Product Identities</H2>
-<P><CENTER><TABLE BORDER=1>
-<TR>
-<TH>Product Name</TH>
-<TH>Product Number</TH>
-<TH>R-state</TH>
-</TR>
-<TR>
-<TD>OTP</TD>
-<TD>APN 181 01</TD>
-<TD>P1D</TD>
-</TR>
-<TR>
-<TD>ERTS (sunos5-beam)</TD>
-<TD>CXC 138 10/3</TD>
-<TD>P1D</TD>
-</TR>
-<TR>
-<TD>SASL (BOS) (sunos5-beam)</TD>
-<TD>CXC 138 11/3</TD>
-<TD>P1C</TD>
-</TR>
-<TR>
-<TD>MNESIA</TD>
-<TD>CXC 138 12/1</TD>
-<TD>P1C</TD>
-</TR>
-<TR>
-<TD>SNMPEA</TD>
-<TD>CXC 138 13/1</TD>
-<TD>P1C</TD>
-</TR>
-<TR>
-<TD>ERLDEV (Compiler & Debugger)</TD>
-<TD>CXC 138 15/1</TD>
-<TD>P1B</TD>
-</TR>
-<TR>
-<TD>DEVTOOLS (sunos5-beam)</TD>
-<TD>CXC 138 16/3</TD>
-<TD>P1C</TD>
-</TR>
-<TR>
-<TD>XLATETOOLS (sunos5-beam)</TD>
-<TD>CXC 138 17/3</TD>
-<TD>P1C</TD>
-</TR>
-</TABLE></CENTER>
-
-<H2>Document Survey</H2>
-<P><CENTER><TABLE BORDER=1>
-<TR>
-<TH>Document name</TH>
-<TH>Document number</TH>
-<TH>Rev</TH>
-</TR>
-<TR>
-<TD>Systems Overview</TD>
-<TD>1551-APN 181 01</TD>
-<TD>A</TD>
-</TR>
-<TR>
-<TD>Erlang Tools Introduction</TD>
-<TD>EPK-95:030/1</TD>
-<TD>A</TD>
-</TR>
-<TR>
-<TD>Erlang Tools User's Guide</TD>
-<TD>EPK-95:030/2</TD>
-<TD>A</TD>
-</TR>
-<TR>
-<TD>Erlang Tools</TD>
-<TD>EPK-95:030/3</TD>
-<TD>A</TD>
-</TR>
-<TR>
-<TD>Distributed Erlang User's Guide</TD>
-<TD>EPK-95:030/4</TD>
-<TD>A</TD>
-</TR>
-<TR>
-<TD>Erlang Tools Examples</TD>
-<TD>EPK-95:030/5</TD>
-<TD>A</TD>
-</TR>
-<TR>
-<TD>User's Guide to the Erlang Interface Library</TD>
-<TD>3/1553-CNA 121 16</TD>
-<TD>A</TD>
-</TR>
-<TR>
-<TD>Erlang Interface Library Examples</TD>
-<TD>1/198 17-CNA 121 16</TD>
-<TD>A</TD>
-</TR>
-<TR>
-<TD>Programmer's Guide to the Erlang Interface Library</TD>
-<TD>2/198 17-CNA 121 16</TD>
-<TD>A</TD>
-</TR>
-<TR>
-<TD>OTP Erlang User's guide</TD>
-<TD>1553-CNA 121 17</TD>
-<TD>A</TD>
-</TR>
-<TR>
-<TD>Mnesia Users Guide (changed name and much improved)</TD>
-<TD>1553-CNA 121 18</TD>
-<TD>PB1</TD>
-</TR>
-<TR>
-<TD>SNMPEA User's Guide</TD>
-<TD>1553-CNA 121 19</TD>
-<TD>A</TD>
-</TR>
-<TR>
-<TD>SNMPEA Reference Guide</TD>
-<TD>1551-CNA 121 19</TD>
-<TD>A</TD>
-</TR>
-<TR>
-<TD>User's Guide to the Interface Generator</TD>
-<TD>1553-CNA 121 38</TD>
-<TD>A</TD>
-</TR>
-</TABLE></CENTER>
-
-
-<P>A complete browseable document survey is available at the OTP WWW-server http://otp.ericsson.se and can also be found in the release at $OTP_ROOT/doc/all.html when the
-release file is un-tar:ed at $OTP_ROOT.
-<H2>Implemented Change requests</H2>
-<P>Comparable in functionality with OTP 181 01 P1D (jam).
-
-<H2>Implemented Trouble Reports</H2>
-<P>This is the first version.
-
-<H2>Installation Instructions</H2>
-<P><B>OBS! The installation path selected below must not be the same as the one used for an OTP -jam system. </B>
-<P>The release is delivered as a compressed tar-file
-<B>otp_APN18101_beam_P1D.&lt;target&gt;.tar.Z</B>,
-where &lt;target&gt; is substituted with <B>sunos5</B>.
-<P>Then the following steps shall be performed at installation time:
-<UL>
-<LI>mkdir <I>&lt;installation path&gt;</I>
-<LI>cd <I>&lt;installation path&gt;</I>
-<LI>uncompress $XXX/otp_APN18101_beam_P1D.&lt;target&gt;.tar.Z
-<LI>tar xvfp $XXX/otp_APN18101_beam_P1D.&lt;target&gt;.tar
-<LI>./Install <I>&lt;installation path&gt;</I><BR>
-The Install command will ask a number of questions during the installation.<BR>
-<B>OBS!</B> When installing on a system where DNS is not used you
-should answer <B>NO</B> on the question "WILL YOU USE DNS?"
-<LI>mkdir man/cat1 man/cat3
-<LI>./format_man_pages
-<LI>cd <I>&lt;installation path&gt;</I>/usr/lib and run ranlib on liberl_interface.a (only sunos4)
-</UL>
-
-Add <I>&lt;installation path&gt;</I>/bin to the path variable and <I>&lt;installation path&gt;</I>/man to the MANPATH variable.
-<P>Where $XXX denotes the path at which otp_APN18101_beam_P1D.&lt;target&gt;.tar resides.
-<H2>Some useful notes</H2>
-<P>To make it possible to browse Framemaker documents through Netscape the files
-.mime.types and .mailcap should be modified (see below). The modifications
-can be made as systems defaults if they are placed in e.g /usr/local/lib/netscape (see Netscape Handbook for details) or as personal defaults if placed in the
-users $HOME directory.
-<P>.mime.types
-<P>
-<PRE>application/x-maker fm</PRE>
-
-<P>
-.mailcap
-<P>
-<PRE>application/x-maker; fmclient -f %s</PRE>
-
-<H2>Known problems in this release</H2>
-<P><UL>
-<LI>Some html-links may still be faulty.
-</UL>
-
-<H2>References</H2>
-<P><I>Nothing to reference</I>
-
-
-</BODY>
-</HTML> \ No newline at end of file
diff --git a/system/ADbeam.sgml b/system/ADbeam.sgml
deleted file mode 100644
index 63995fe26e..0000000000
--- a/system/ADbeam.sgml
+++ /dev/null
@@ -1,246 +0,0 @@
-<!doctype report PUBLIC "-//Stork//DTD tr1c//EN">
-
-<report>
- <header>
- <title>AMENDMENT DIRECTIVE, OTP-BEAM
- <prepared>ETX/B/DUP Kenneth Lundin, Lars Thors&#233;n
- <responsible>
- <docno>3/177 82 - APN 181 01
- <approved>ETX/B/DU Torbj&ouml;rn Johnsson
- <checked>
- <date>960828
- <rev>D
- <file>tr1c.sgml
- <parent>../
- </header>
-
- <section>
-<h1>Introduction</h1>
-<p>
-<h2>Purpose</h2>
-<p>
-This is a first prototype release of the OTP-BEAM system for SunOS5.
-This version is intended to be used for various capacity measurements and the functionality is comparable to that of OTP rev P1D (APN 181 01 P1D).
-
-<h2>Revision History</h2>
-<p>
-Rev.A:Kenneth Lundin 1996-08-28<br>
-
-<p>
-The exact changes between revisions of this document can be generated from our ClearCase repository upon request , or a simple unix "diff" can be used.
-<h1>Product Identities</h1>
-<p>
-<table>
-<row>
-<hcell>Product Name
-<hcell>Product Number
-<hcell>R-state
-</row>
-<row>
-<cell>OTP
-<cell>APN 181 01
-<cell>P1D
-</row>
-<row>
-<cell>ERTS (sunos5-beam)
-<cell>CXC 138 10/3
-<cell>P1D
-</row>
-<row>
-<cell>SASL (BOS) (sunos5-beam)
-<cell>CXC 138 11/3
-<cell>P1C
-</row>
-<row>
-<cell>MNESIA
-<cell>CXC 138 12/1
-<cell>P1C
-</row>
-<row>
-<cell>SNMPEA
-<cell>CXC 138 13/1
-<cell>P1C
-</row>
-<row>
-<cell>ERLDEV (Compiler & Debugger)
-<cell>CXC 138 15/1
-<cell>P1B
-</row>
-<row>
-<cell>DEVTOOLS (sunos5-beam)
-<cell>CXC 138 16/3
-<cell>P1C
-</row>
-<row>
-<cell>XLATETOOLS (sunos5-beam)
-<cell>CXC 138 17/3
-<cell>P1C
-</row>
-</table>
-<h1>Document Survey</h1>
-<p>
-<table>
-<row>
-<hcell>Document name
-<hcell>Document number
-<hcell>Rev
-</row>
-<row>
-<cell>Systems Overview
-<cell>1551-APN 181 01
-<cell>A
-</row>
-<row>
-<cell>Erlang Tools Introduction
-<cell>EPK-95:030/1
-<cell>A
-</row>
-<row>
-<cell>Erlang Tools User's Guide
-<cell>EPK-95:030/2
-<cell>A
-</row>
-<row>
-<cell>Erlang Tools
-<cell>EPK-95:030/3
-<cell>A
-</row>
-<row>
-<cell>Distributed Erlang User's Guide
-<cell>EPK-95:030/4
-<cell>A
-</row>
-<row>
-<cell>Erlang Tools Examples
-<cell>EPK-95:030/5
-<cell>A
-</row>
-
-<row>
-<cell>User's Guide to the Erlang Interface Library
-<cell>3/1553-CNA 121 16
-<cell>A
-</row>
-<row>
-<cell>Erlang Interface Library Examples
-<cell>1/198 17-CNA 121 16
-<cell>A
-</row>
-<row>
-<cell>Programmer's Guide to the Erlang Interface Library
-<cell>2/198 17-CNA 121 16
-<cell>A
-</row>
-
-<row>
-<cell>OTP Erlang User's guide
-<cell>1553-CNA 121 17
-<cell>A
-</row>
-
-<row>
-<cell>Mnesia Users Guide (changed name and much improved)
-<cell>1553-CNA 121 18
-<cell>PB1
-</row>
-
-<row>
-<cell>SNMPEA User's Guide
-<cell>1553-CNA 121 19
-<cell>A
-</row>
-
-<row>
-<cell>SNMPEA Reference Guide
-<cell>1551-CNA 121 19
-<cell>A
-</row>
-
-<row>
-<cell>User's Guide to the Interface Generator
-<cell>1553-CNA 121 38
-<cell>A
-</row>
-
-</table>
-
-<p>
-A complete browseable document survey is available at the OTP WWW-server http://otp.ericsson.se and can also be found in the release at $OTP_ROOT/doc/all.html when the
-release file is un-tar:ed at $OTP_ROOT.
-<h1>Implemented Change requests</h1>
-<p>
-Comparable in functionality with OTP 181 01 P1D (jam).
-
-<h1>Implemented Trouble Reports</h1>
-<p>
-This is the first version.
-
-<h1>Installation Instructions</h1>
-<p>
-<b>OBS! The installation path selected below must not be the same as the one used for an OTP -jam system. </b>
-<p>
-The release is delivered as a compressed tar-file
-<b>otp_APN18101_beam_P1D.&lt;target&gt;.tar.Z</b>,
-where &lt;target&gt; is substituted with <b>sunos5</b>.
-<p>
-Then the following steps shall be performed at installation time:
-<list>
-<item>mkdir <i>&lt;installation path&gt;</i>
-<item>cd <i>&lt;installation path&gt;</i>
-<item>uncompress $XXX/otp_APN18101_beam_P1D.&lt;target&gt;.tar.Z
-<item>tar xvfp $XXX/otp_APN18101_beam_P1D.&lt;target&gt;.tar
-<item>./Install <i>&lt;installation path&gt;</i><br>
-The Install command will ask a number of questions during the installation.<br>
-<b>OBS!</b> When installing on a system where DNS is not used you
-should answer <b>NO</b> on the question "WILL YOU USE DNS?"
-<item>mkdir man/cat1 man/cat3
-<item>./format_man_pages
-<item>cd <i>&lt;installation path&gt;</i>/usr/lib and run ranlib on liberl_interface.a (only sunos4)
-</list>
-Add <i>&lt;installation path&gt;</i>/bin to the path variable and <i>&lt;installation path&gt;</i>/man to the MANPATH variable.
-<p>
-Where $XXX denotes the path at which otp_APN18101_beam_P1D.&lt;target&gt;.tar resides.
-<h1>Some useful notes</h1>
-<p>
-To make it possible to browse Framemaker documents through Netscape the files
-.mime.types and .mailcap should be modified (see below). The modifications
-can be made as systems defaults if they are placed in e.g /usr/local/lib/netscape (see Netscape Handbook for details) or as personal defaults if placed in the
-users $HOME directory.
-<p>
-.mime.types
-<p>
-<pre>
-application/x-maker fm
-</pre>
-<p>
-
-.mailcap
-<p>
-<pre>
-application/x-maker; fmclient -f %s
-</pre>
-<h1>Known problems in this release</h1>
-<p>
-<list>
-<item>Some html-links may still be faulty.
-</list>
-<h1>References</h1>
-<p>
-<i>Nothing to reference</i>
-
- </section>
-</report>
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/system/COPYRIGHT b/system/COPYRIGHT
index 97c2010cb6..444efcd6f5 100644
--- a/system/COPYRIGHT
+++ b/system/COPYRIGHT
@@ -1,14 +1,96 @@
-Copyright Ericsson Telecom AB 1998
+This software is subject to the following Copyrights and Licenses:
+
+---------------------------------------------------------------------------
+[Erlang/OTP except parts stated below]
+
+%CopyrightBegin%
+
+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%
+
+---------------------------------------------------------------------------
+[PCRE]
+
+PCRE LICENCE
+------------
+
+PCRE is a library of functions to support regular expressions whose syntax
+and semantics are as close as possible to those of the Perl 5 language.
+
+Release 7 of PCRE is distributed under the terms of the "BSD" licence, as
+specified below. The documentation for PCRE, supplied in the "doc"
+directory, is distributed under the same terms as the software itself.
+
+The basic library functions are written in C and are freestanding. Also
+included in the distribution is a set of C++ wrapper functions.
+
+
+THE BASIC LIBRARY FUNCTIONS
+---------------------------
+
+Written by: Philip Hazel
+Email local part: ph10
+Email domain: cam.ac.uk
+
+University of Cambridge Computing Service,
+Cambridge, England.
+
+Copyright (c) 1997-2008 University of Cambridge
+All rights reserved.
-The copyright to the computer program herein is the
-property of Ericsson Telecom AB, Sweden. The program
-may be used and/or copied only with the written permission
-from Ericsson Telecom AB, or in accordance with the terms
-and conditions stipulated in the agreement/contract under
-which the program has been supplied.
-Parts of this distribution was created using copyrighted material
-with the copyright notices included below.
+THE C++ WRAPPER FUNCTIONS
+-------------------------
+
+Contributed by: Google Inc.
+
+Copyright (c) 2007-2008, Google Inc.
+All rights reserved.
+
+
+THE "BSD" LICENCE
+-----------------
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+ * Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+
+ * Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+
+ * Neither the name of the University of Cambridge nor the name of Google
+ Inc. nor the names of their contributors may be used to endorse or
+ promote products derived from this software without specific prior
+ written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGE.
+
+End
---------------------------------------------------------------------------
[Tcl/Tk]
@@ -75,19 +157,20 @@ terms specified in this license.
---------------------------------------------------------------------------
[zlib]
+
/* zlib.h -- interface of the 'zlib' general purpose compression library
- version 1.0.4, Jul 24th, 1996.
+ version 1.2.3, July 18th, 2005
+
+ Copyright (C) 1995-2005 Jean-loup Gailly and Mark Adler
- Copyright (C) 1995-1996 Jean-loup Gailly and Mark Adler
-
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.
-
+
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
-
+
1. The origin of this software must not be misrepresented; you must not
claim that you wrote the original software. If you use this software
in a product, an acknowledgment in the product documentation would be
@@ -95,13 +178,13 @@ terms specified in this license.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
-
+
Jean-loup Gailly Mark Adler
-
-
+
+
The data format used by the zlib library is described by RFCs (Request for
- Comments) 1950 to 1952 in the files ftp://ds.internic.net/rfc/rfc1950.txt
+ Comments) 1950 to 1952 in the files http://www.ietf.org/rfc/rfc1950.txt
(zlib format), rfc1951.txt (deflate format) and rfc1952.txt (gzip format).
*/
diff --git a/system/README b/system/README
index 29d86b8f47..15ccfd2f84 100644
--- a/system/README
+++ b/system/README
@@ -1,7 +1,7 @@
-Erlang/OTP March 18, 2009
+Erlang/OTP February 18, 2010
-LAST MINUTE INFORMATION -- Release of Erlang 5.7/OTP R13A
+LAST MINUTE INFORMATION -- Release of Erlang 5.7.5/OTP R13B04
1. GENERAL
@@ -11,7 +11,7 @@ LAST MINUTE INFORMATION -- Release of Erlang 5.7/OTP R13A
The installation guide can be found in
- <inst-root>/doc/installation_guide/part_frame.html
+ <inst-root>doc/installation_guide/users_guide.html
1.2 Java
@@ -19,7 +19,7 @@ LAST MINUTE INFORMATION -- Release of Erlang 5.7/OTP R13A
1.3 Disk space
- An installation of Erlang/OTP needs approximately 140 MB of
+ An installation of Erlang/OTP needs approximately 300 MB of
disk space.
1.4 The package contains HTML documentation. You can also get this
@@ -35,7 +35,7 @@ LAST MINUTE INFORMATION -- Release of Erlang 5.7/OTP R13A
R11B-1). BEAM files from R10B or earlier are not supported.
To get the best performance, you should recompile your
- application code with the R13A compiler.
+ application code with the R13B04 compiler.
2. NOTES ABOUT THE SOLARIS VERSION
diff --git a/system/README.unixware b/system/README.unixware
deleted file mode 100644
index b9f9433723..0000000000
--- a/system/README.unixware
+++ /dev/null
@@ -1,201 +0,0 @@
-
-OTP R4B b1 UnixWare Release Notes
-------------------------------------
-
-Kent Boortz
-
-This is an *unsupported* release of OTP to UnixWare 2.1.2.
-In fact, it should not be considered a release or a product at all,
-it is a demo what a real release could look like.
-
-Questions should be directed directly to
-
- Kent Boortz
-
-Changes or problems:
-
- * There is no documentation as part of this release.
- Use the R5B documentation that comes with the
- Solaris release.
-
- * To run older graphical tools based on 'pxw' like
- 'xerl' and 'interpreter' you have to add
- "/usr/X/lib" to your LD_LIBRARY_PATH.
-
- * The OTP test cases looks reasonable well considering the
- short time I had to do the port. The tests of the base
- system gives equal results than on Solaris. There are
- some problems with the 'ic' application (CORBA) and there
- may be some 'mnesia' problems (the tests where not completed
- when I wrote this note)
-
- * OTP normally try to handle IP host name lookups
- by itself, parsing /etc/hosts and other configuration
- files. This is done because the normal calls like
- gethostbyname() is blocking. In this UnixWare port
- the normal gethostbyname() is used and if a reply
- from the name server takes some time this may block
- the OTP system from doing other tasks (it may be the
- case that it doesn't block the whole system, it may
- just keep other Erlang processes that do DNS lookups
- waiting, I'm not sure).
-
- * The erl_interface library support varios types of threading
- This is not supported in the OTP UnixWare release.
-
- * If you use gcc you compile and link dynamic drivers with
-
- gcc -fPIC -c foo.c
- ld -G -t text -o foo.so foo.o
-
- With the UnixWare C compiler I belive it will be
-
- gcc -KPIC -c foo.c
- ld -G -t text -o foo.so foo.o
-
- * The default shell limits was a problem when I was running
- some large tests. These limits can be changed by building
- a new kernel. To enable unlimited use of virtual memory
- and data you do as root
-
- % /etc/conf/bin/idtune SDATLIM 0x7FFFFFFF
- % /etc/conf/bin/idtune HDATLIM 0x7FFFFFFF
- % /etc/conf/bin/idtune SVMMLIM 0x7FFFFFFF
- % /etc/conf/bin/idtune HVMMLIM 0x7FFFFFFF
- % /etc/conf/bin/idbuild
-
- When you reboot a new kernel will be built.
-
- * I didn't give the system enough swap space. You can add
- swap on an ordinary file. To add about 100 MB more swap
- you do as root
-
- % dd < /dev/zero > /moreswap bs=512 count=200000
- % swap -a /moreswap 0 200000
-
- The first line will create a 100 MB file on the root partition
- and the second line will add this file as swap space. Note that
- the "swap" command is a bit buggy and may hang. Reboot UnixWare
- and try again.
-
-Internel notes on build the release
-
- * If the network addresses are changed you enter single user
- mode by hitting a key after the "Booting UnixWare..." and
- the beep. At the prompt
-
- BOOT# Hit return only to clear line
- BOOT# INITSTATE=S
- BOOT# go
-
- This will put you into single user mode. Find out ip address,
- default router and DNS server. At the shell prompt
-
- # /usr/local/bin/tcsh
- # setenv TERM vt100
- # cd /etc
- # vi resolv.conf
- < edit and save with :x! >
- # cd /etc/inet
- # vi hosts
- < edit and save with :x! >
- # vi config
- < edit and save with :x! >
- # cd /
- # shutdown now
-
- Now it should be possible to restart in single user mode.
- It may still have long timeouts because the NIS information
- is wrong. As root you do
-
- # ypinit -c
-
- and type in "arda" as NIS domain and "gandalf.du.uab.ericsson.se"
- as NIS server.
-
- * Prebuilding the release. Create a view with the -ncaexported option.
- See "http://otp/product/internal/test/doc/howto/export_view.html".
- Build a solaris release (optionally using a boostrap compiler)
-
- # cd /clearcase/otp/erts/autoconf; cm -V; cd ..
- # cm -V opt EMULATOR=jam BUILD_ALL=1 >& LOG.1
-
- * Create the directories for mount points and mount the view on
- the UnixWare machine.
-
- # mkdir -p /clearcase/otp; cd /clearcase/otp
- # mkdir erts internal_tools libraries system tools
-
- Use s script like
-
- #!/bin/sh
- HOST=$1
- VIEW=$2
- MOUNT=$HOST:/view/$VIEW/clearcase/otp
-
- mount -F nfs $MOUNT/erts $DIR/erts
- mount -F nfs $MOUNT/libraries $DIR/libraries
- mount -F nfs $MOUNT/tools $DIR/tools
- mount -F nfs $MOUNT/internal_tools $DIR/internal_tools
- mount -F nfs $MOUNT/system $DIR/system
-
- to mount the ClearCase VOBs.
-
- * Building the
- * Building the
-
- "/usr/X/lib" to your LD_LIBRARY_PATH.
-
- Had to patch the file
-
- /usr/local/lib/g++-include/_G_config.h
-
- not to define _G_HAVE_SYS_CDEFS 1
-
- Problems with pxw yacc
-
- yacc -dv -b i386-univel-sysv4.2MP/y parse.y
- UX:yacc: ERROR: Illegal option -- b
- UX:yacc: TO FIX: Usage: yacc [-wvVdlt] [-Q(y/n)] [-p driver_file] file
- gmake[6]: *** [i386-univel-sysv4.2MP/y.tab.c] Error 1
-
- Create some symbolic links (until got compiled libs for UnixWare)
-
- # cd crypt/src/ssleay
- # ln -s elibcrypto.so.i386-pc-solaris2.5.1 elibcrypto.so.i386-univel-sysv4.2MP
- # cd ssl/src/ssleay
- # ln -s i386-pc-solaris2.5.1 i386-univel-sysv4.2MP
-
- Run
-
- # ntpdate super.du.uab.ericsson.se
-
- now and then to set the time on the machine.
-
-
- Disabled HAVE_MULTICAST_SUPPORT from "drv/inet_drv.c", should be set in configure
-
- UnixWare want two arguments to 'ln'
-
- SkunkWare gcc, ln, tar, ..... required, make sure PATH points out them first
-
- The emulator has to be linked with "gcc -r -Wl,-Bexport " to be linkable
- with dynamic libraries.
-
- Tcl/Tk was compiled from
-
- tcl7.6p2plus.tar.gz
- tk4.2p2plus.tar.gz
-
- and the make-files where changed, see
-
- (not needed it seems, if not using gcc at least)
-
-
- VILL HA "-ly -ll" BARA PA PXW ???????
-
- You can view the limits of the Unix processes in
-
- /etc/conf/mtune.d/proc
-
diff --git a/system/doc/book.xml b/system/doc/book.xml
deleted file mode 100644
index d1ec093019..0000000000
--- a/system/doc/book.xml
+++ /dev/null
@@ -1,52 +0,0 @@
-<?xml version="1.0" encoding="latin1" ?>
-<!DOCTYPE book SYSTEM "book.dtd">
-
-<book xmlns:xi="http://www.w3.org/2001/XInclude">
- <header titlestyle="normal">
- <copyright>
- <year>1997</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>Erlang/OTP System Documentation</title>
- <prepared>OTP Team</prepared>
- <docno></docno>
- <date>2009-08-21</date>
- <rev>A</rev>
- <file>book.xml</file>
- </header>
- <insidecover>
- </insidecover>
- <pagetext></pagetext>
- <preamble>
- <contents level="2"></contents>
- </preamble>
- <parts lift="no">
- <xi:include href="installation_guide/part.xml"/>
- <xi:include href="system_principles/part.xml"/>
- <xi:include href="embedded/part.xml"/>
- <xi:include href="getting_started/part.xml"/>
- <xi:include href="reference_manual/part.xml"/>
- <xi:include href="getting_started/part.xml"/>
- <xi:include href="efficiency_guide/part.xml"/>
- <xi:include href="tutorial/part.xml"/>
- <xi:include href="design_principles/part.xml"/>
- <xi:include href="oam/part.xml"/>
- </parts>
- <listofterms></listofterms>
- <index></index>
-</book>
-
diff --git a/system/doc/embedded/embedded_solaris.xml b/system/doc/embedded/embedded_solaris.xml
index 93532da8e6..d1fb2ddc5f 100644
--- a/system/doc/embedded/embedded_solaris.xml
+++ b/system/doc/embedded/embedded_solaris.xml
@@ -580,7 +580,7 @@ fi
START_ERL_DATA=${1:-$RELDIR/start_erl.data}
-$ROOTDIR/bin/run_erl /tmp/ $ROOTDIR/log "exec $ROOTDIR/bin/start_erl \\
+$ROOTDIR/bin/run_erl /tmp/ $ROOTDIR/log "exec $ROOTDIR/bin/start_erl \
$ROOTDIR $RELDIR $START_ERL_DATA" > /dev/null 2>&1 &]]></code>
<p>The following script illustrates a modification where the node
is given the name <c>cp1</c>, and the environment variables
@@ -604,7 +604,7 @@ fi
START_ERL_DATA=${1:-$RELDIR/start_erl.data}
-$ROOTDIR/bin/run_erl /tmp/ $ROOTDIR/log "exec $ROOTDIR/bin/start_erl \\
+$ROOTDIR/bin/run_erl /tmp/ $ROOTDIR/log "exec $ROOTDIR/bin/start_erl \
$ROOTDIR $RELDIR $START_ERL_DATA -heart -sname cp1" > /dev/null 2>&1 &]]></code>
<p>If a diskless and/or read-only client node is about to start the
<c>start_erl.data</c> file is located in the client directory at
@@ -702,7 +702,7 @@ VSN=`awk '{print $2}' $DataFile`
BINDIR=$ROOTDIR/erts-$ERTS_VSN/bin
EMU=beam
-PROGNAME=`echo $0 | sed 's/.*\\///'`
+PROGNAME=`echo $0 | sed 's/.*\///'`
export EMU
export ROOTDIR
export BINDIR
@@ -726,7 +726,7 @@ exec $BINDIR/erlexec -boot $RELDIR/$VSN/start -config $RELDIR/$VSN/sys $*</code>
should look like:
</p>
<code type="none">
-exec $BINDIR/erlexec -boot $CLIENTDIR/bin/start \\
+exec $BINDIR/erlexec -boot $CLIENTDIR/bin/start \
-config $CLIENTDIR/bin/sys $*</code>
</section>
</section>
diff --git a/system/doc/embedded/starting.xml b/system/doc/embedded/starting.xml
index ddeaeb8bdf..228d91f430 100644
--- a/system/doc/embedded/starting.xml
+++ b/system/doc/embedded/starting.xml
@@ -219,7 +219,7 @@ VSN=`awk '{print $2}' $DataFile`
BINDIR=$ROOTDIR/erts-$ERTS_VSN/bin
EMU=beam
-PROGNAME=`echo $0 | sed 's/.*\\///'`
+PROGNAME=`echo $0 | sed 's/.*\///'`
export EMU
export ROOTDIR
export BINDIR
diff --git a/system/doc/extensions/Makefile b/system/doc/extensions/Makefile
deleted file mode 100644
index cfc506f7e8..0000000000
--- a/system/doc/extensions/Makefile
+++ /dev/null
@@ -1,142 +0,0 @@
-# ``The contents of this file are subject to the Erlang Public License,
-# Version 1.1, (the "License"); you may not use this file except in
-# compliance with the License. You should have received a copy of the
-# Erlang Public License along with this software. If not, it can be
-# retrieved via the world wide web at http://www.erlang.org/.
-#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
-#
-# The Initial Developer of the Original Code is Ericsson Utvecklings AB.
-# Portions created by Ericsson are Copyright 1999, Ericsson Utvecklings
-# AB. All Rights Reserved.''
-#
-# $Id$
-#
-include $(ERL_TOP)/make/target.mk
-include $(ERL_TOP)/make/$(TARGET)/otp.mk
-
-# ----------------------------------------------------
-# Application version
-# ----------------------------------------------------
-include $(ERL_TOP)/erts/vsn.mk
-#VSN=$(SYSTEM_VSN)
-
-# ----------------------------------------------------
-# Include dependency
-# ----------------------------------------------------
-
-include make.dep
-
-# ----------------------------------------------------
-# Release directory specification
-# ----------------------------------------------------
-RELSYSDIR = $(RELEASE_PATH)/doc/extensions
-
-# ----------------------------------------------------
-# Target Specs
-# ----------------------------------------------------
-XML_PART_FILES = part.xml
-XML_CHAPTER_FILES = \
- funs.xml \
- macros.xml \
- misc.xml \
- include.xml \
- records.xml \
- list_comprehensions.xml \
- bit_syntax.xml
-
-BOOK_FILES = book.xml
-
-GIF_FILES = note.gif
-
-PS_FILES =
-
-# ----------------------------------------------------
-
-HTML_FILES = \
- $(XML_PART_FILES:%.xml=%.html)
-
-HTMLDIR = .
-EXTRA_FILES = $(DEFAULT_GIF_FILES) \
- $(DEFAULT_HTML_FILES) \
- $(XML_CHAPTER_FILES:%.xml=%.html)
-
-TEX_FILES_BOOK = \
- $(BOOK_FILES:%.xml=%.tex)
-TEX_FILES_USERS_GUIDE = \
- $(XML_CHAPTER_FILES:%.xml=%.tex)
-
-TOP_PDF_FILE = extensions-$(VSN).pdf
-TOP_PS_FILE = extensions-$(VSN).ps
-
-$(TOP_PDF_FILE): book.dvi $(ERL_TOP)/erts/vsn.mk
- $(DVI2PS) $(DVIPS_FLAGS) -f $< | $(DISTILL) $(DISTILL_FLAGS) > $@
-
-$(TOP_PS_FILE): book.dvi $(ERL_TOP)/erts/vsn.mk
- $(DVI2PS) $(DVIPS_FLAGS) -f $< > $@
-
-# ----------------------------------------------------
-# FLAGS
-# ----------------------------------------------------
-XML_FLAGS +=
-DVIPS_FLAGS +=
-
-# ----------------------------------------------------
-# Targets
-# ----------------------------------------------------
-
-ifeq ($(DOCTYPE),pdf)
-docs: pdf
-else
-ifeq ($(DOCTYPE),ps)
-docs: ps
-else
-docs: html
-endif
-endif
-
-pdf: $(TOP_PDF_FILE)
-
-ps: $(TOP_PS_FILE)
-
-html: $(HTML_FILES) $(GIF_FILES)
-
-debug opt:
-
-clean_tex:
- -rm -f $(TEX_FILES_USERS_GUIDE) $(TEX_FILES_BOOK)
-
-clean:
- rm -f *.html $(TEX_FILES_USERS_GUIDE)
- rm -f $(TOP_PS_FILES)
- rm -f errs core *~ $(LATEX_CLEAN)
-
-# ----------------------------------------------------
-# Release Target
-# ----------------------------------------------------
-include $(ERL_TOP)/make/otp_release_targets.mk
-
-ifeq ($(DOCTYPE),pdf)
-release_docs_spec: pdf
- $(INSTALL_DIR) $(RELEASE_PATH)/pdf
- $(INSTALL_DATA) $(TOP_PDF_FILE) $(RELEASE_PATH)/pdf
-else
-ifeq ($(DOCTYPE),ps)
-release_docs_spec: ps
- $(INSTALL_DIR) $(RELEASE_PATH)/ps
- $(INSTALL_DATA) $(TOP_PS_FILE) $(RELEASE_PATH)/ps
-else
-release_docs_spec: docs
- $(INSTALL_DIR) $(RELSYSDIR)
- $(INSTALL_DATA) $(GIF_FILES) $(EXTRA_FILES) $(HTML_FILES) \
- $(RELSYSDIR)
-endif
-endif
-
-release_spec:
-
-
-
diff --git a/system/doc/extensions/bit_syntax.xml b/system/doc/extensions/bit_syntax.xml
deleted file mode 100644
index d86f73cd9a..0000000000
--- a/system/doc/extensions/bit_syntax.xml
+++ /dev/null
@@ -1,403 +0,0 @@
-<?xml version="1.0" encoding="latin1" ?>
-<!DOCTYPE chapter SYSTEM "chapter.dtd">
-
-<chapter>
- <header>
- <copyright>
- <year>2000</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>The Bit Syntax</title>
- <prepared>Bj&ouml;rn Gustavsson</prepared>
- <responsible>Bjarne D&auml;cker</responsible>
- <docno>1</docno>
- <approved>Bjarne D&auml;Ker</approved>
- <checked></checked>
- <date>00-06-21</date>
- <rev>PA1</rev>
- <file>bit_syntax.sgml</file>
- </header>
- <p>This section describes the "bit syntax" which was added to
- the Erlang language in release 5.0 (R7).
- Compared to the original bit syntax prototype
- by Claes Wikstr&ouml;m and Tony Rogvall (presented on the
- Erlang User's Conference 1999), this implementation differs
- primarily in the following respects,
- </p>
- <list type="ordered">
- <item>
- <p>the character pairs '&lt;&lt;' and '&gt;&gt;' are used to delimit
- a binary patterns and constructor (not '&lt;' and '&gt;' as in
- the prototype),
- </p>
- </item>
- <item>
- <p>the tail syntax ('|Variable') has been eliminated,
- </p>
- </item>
- <item>
- <p>all size expressions must be bound,
- </p>
- </item>
- <item>
- <p>a type <c>unit:U</c> has been added,
- </p>
- </item>
- <item>
- <p>lists and tuples cannot be generated
- </p>
- </item>
- <item>
- <p>there are no paddings whatsoever.
- </p>
- </item>
- </list>
-
- <section>
- <title>Introduction</title>
- <p>In Erlang a Bin is used for constructing binaries and
- matching binary patterns. A Bin is written with the
- following syntax:</p>
- <code type="none"><![CDATA[
- <<E1, E2, ... En>>
- ]]></code>
- <p>A Bin is a low-level sequence of bytes. The purpose of a
- Bin is to be able to, from a high level,
- <em>construct</em> a binary,
- </p>
- <code type="none"><![CDATA[
- Bin = <<E1, E2, ... En>>
- ]]></code>
- <p>in which case all elements must be bound, or to
- <em>match</em> a binary,
- </p>
- <code type="none"><![CDATA[
- <<E1, E2, ... En>> = Bin
- ]]></code>
- <p>where <c>Bin</c> is bound, and where the elements are bound or unbound,
- as in any match.
- </p>
- <p>Each element specifies a certain <em>segment</em> of the binary.
- A segment is is a set of contiguous bits of the binary (not
- necessarily on a byte boundary). The first element specifies
- the initial segment, the second element specifies the following
- segment etc.
- </p>
- <p>The following examples illustrate how binaries are constructed
- or matched, and how elements and tails are specified.
- </p>
-
- <section>
- <title>Examples</title>
- <p><em>Example 1: </em>A binary can be constructed from a set of
- constants or a string literal:</p>
- <code type="none"><![CDATA[
- Bin11 = <<1, 17, 42>>,
- Bin12 = <<"abc">>
- ]]></code>
- <p>yields binaries of size 3; <c>binary_to_list(Bin11)</c>
- evaluates to <c>[1, 17, 42]</c>, and
- <c>binary_to_list(Bin12)</c> evaluates to <c>[97, 98, 99]</c>.
- </p>
- <p><em>Example 2: </em>Similarly, a binary can be constructed
- from a set of bound variables:</p>
- <code type="none"><![CDATA[
- A = 1, B = 17, C = 42,
- Bin2 = <<A, B, C:16>>
- ]]></code>
- <p>yields a binary of size 4, and <c>binary_to_list(Bin2)</c>
- evaluates to <c>[1, 17, 00, 42]</c> too. Here we used a
- <em>size expression</em> for the variable <c>C</c> in order to
- specify a 16-bits segment of <c>Bin2</c>.
- </p>
- <p><em>Example 3: </em>A Bin can also be used for matching: if
- <c>D</c>, <c>E</c>, and <c>F</c> are unbound variables, and
- <c>Bin2</c> is bound as in the former example,</p>
- <code type="none"><![CDATA[
- <<D:16, E, F/binary>> = Bin2
- ]]></code>
- <p>yields <c>D = 273</c>, <c>E = 00</c>, and F binds to a binary
- of size 1: <c>binary_to_list(F) = [42]</c>.
- </p>
- <p><em>Example 4: </em>The following is a more elaborate example
- of matching, where <c>Dgram</c> is bound to the consecutive
- bytes of an IP datagram of IP protocol version 4, and where we
- want to extract the header and the data of the datagram:</p>
- <code type="none"><![CDATA[
- -define(IP_VERSION, 4).
- -define(IP_MIN_HDR_LEN, 5).
-
- DgramSize = byte_size(Dgram),
- case Dgram of
- <<?IP_VERSION:4, HLen:4, SrvcType:8, TotLen:16,
- ID:16, Flgs:3, FragOff:13,
- TTL:8, Proto:8, HdrChkSum:16,
- SrcIP:32,
- DestIP:32, RestDgram/binary>> when HLen >= 5, 4*HLen =< DgramSize ->
- OptsLen = 4*(HLen - ?IP_MIN_HDR_LEN),
- <<Opts:OptsLen/binary,Data/binary>> = RestDgram,
- ...
- end.
- ]]></code>
- <p>Here the segment corresponding to the <c>Opts</c> variable
- has a <em>type modifier</em> specifying that <c>Opts</c> should
- bind to a binary. All other variables have the default type
- equal to unsigned integer.
- </p>
- <p>An IP datagram header is of variable length, and its length -
- measured in the number of 32-bit words - is given in the segment
- corresponding to <c>HLen</c>, the minimum value of which is
- 5. It is the segment corresponding to <c>Opts</c> that is
- variable: if <c>HLen</c> is equal to 5, <c>Opts</c> will be an
- empty binary.
- </p>
- <p>The tail variables <c>RestDgram</c> and <c>Data</c> bind to
- binaries, as all tail variables do. Both may bind to empty
- binaries.
- </p>
- <p>If the first 4-bits segment of <c>Dgram</c> is not equal to
- 4, or if <c>HLen</c> is less than 5, or if the size of
- <c>Dgram</c> is less than <c>4*HLen</c>, the match of
- <c>Dgram</c> fails.
- </p>
- </section>
- </section>
-
- <section>
- <title>A Lexical Note</title>
- <p>Note that "<c><![CDATA[B=<<1>>]]></c>" will be interpreted as
- "<c><![CDATA[B =< ;<1>>]]></c>", which is a syntax error.
- The correct way to write the expression is "<c><![CDATA[B = <<1>>]]></c>".</p>
- </section>
-
- <section>
- <title>Segments</title>
- <p>Each segment has the following general syntax:</p>
- <p><c>Value:Size/TypeSpecifierList</c></p>
- <p>Both the <c>Size</c> and the <c>TypeSpecifier</c> or both may be
- omitted; thus the following variations are allowed:
- </p>
- <p><c>Value</c></p>
- <p><c>Value:Size</c></p>
- <p><c>Value/TypeSpecifierList</c></p>
- <p>Default values will be used for missing specifications. The default
- values are described in the section "Defaults" below.
- </p>
- <p>Used in binary construction, the <c>Value</c> part is any expression.
- Used in binary matching, the <c>Value</c> part must be a literal or
- variable. You can read more about the <c>Value</c> part in the
- sections about constructing binaries and matching binaries.
- </p>
- <p>The <c>Size</c> part of the segment multiplied by the unit in the
- <c>TypeSpecifierList</c> (described below) gives the number of bits
- for the segment. In construction, <c>Size</c> is any expression that
- evaluates to an integer. In matching, <c>Size</c> must be a constant
- expression or a variable.
- </p>
- <p>The <c>TypeSpecifierList</c> is a list of type specifiers separated by
- hyphens.
- </p>
- <taglist>
- <tag>Type</tag>
- <item>The type can be <c>integer</c>, <c>float</c>, or <c>binary</c>.</item>
- <tag>Signedness</tag>
- <item>The signedness specification can be either <c>signed</c>
- or <c>unsigned</c>. Note that signedness only matters for matching.</item>
- <tag>Endianness</tag>
- <item>The endianness specification can be either <c>big</c>,
- <c>little</c>, or <c>native</c>. Native-endian means that
- the endian will be resolved at load time to be either
- big-endian or little-endian, depending on what is "native"
- for the CPU that the Erlang machine is run on.</item>
- <tag>Unit</tag>
- <item>The unit size is given as <c>unit:IntegerLiteral</c>.
- The allowed range is 1-256. It will be multiplied by the <c>Size</c>
- specifier to give the effective size of the segment.</item>
- </taglist>
- <p>Example:
- </p>
- <code type="none">
-X:4/little-signed-integer-unit:8
- </code>
- <p>This element has a total size of 4*8 = 32 bits, and it contains a
- signed integer in little-endian order.</p>
- </section>
-
- <section>
- <title>Defaults</title>
- <p>The default type for a segment is <c>integer</c>. The default type
- does <em>not</em> depend on the value, even if the value is a literal.
- For instance, the default type in '<c><![CDATA[<<3.14>>]]></c>' is <c>integer</c>,
- not <c>float</c>.
- </p>
- <p>The default <c>Size</c> depends on the type.
- For <c>integer</c> it is 8. For <c>float</c> it is 64.
- For <c>binary</c> it is all of the binary. In matching, this default
- value is only valid for the very last element. All other binary elements
- in matching must have a size specification.
- </p>
- <p>The default unit depends on the the type.
- For <c>integer</c> and <c>float</c> it is 1.
- For <c>binary</c> it is 8.
- </p>
- <p>The default signedness is <c>unsigned</c>.
- </p>
- <p>The default endianness is <c>big</c>.</p>
- </section>
-
- <section>
- <title>Constructing Binaries</title>
- <p>This section describes the rules for constructing binaries using
- the bit syntax. Unlike when constructing lists or tuples, the construction
- of a binary can fail with a <c>badarg</c> exception.
- </p>
- <p>There can be zero or more segments in a binary to be constructed.
- The expression '<c><![CDATA[<<>>]]></c>' constructs a zero length binary.
- </p>
- <p>Each segment in a binary can consist of zero or more bits.
- There are no alignment rules for individual segments, but the total
- number of bits in all segments must be evenly divisible by 8,
- or in other words, the resulting binary must consist of a whole number
- of bytes. An <c>badarg</c> exception will be thrown if the resulting
- binary is not byte-aligned. Example:
- </p>
- <code type="none"><![CDATA[
-<<X:1,Y:6>>
- ]]></code>
- <p>The total number of bits is 7, which is not evenly divisible by 8;
- thus, there will be <c>badarg</c> exception (and a compiler warning
- as well). The following example
- </p>
- <code type="none"><![CDATA[
-<<X:1,Y:6,Z:1>>
- ]]></code>
- <p>will successfully construct a binary of 8 bits, or one byte. (Provided
- that all of X, Y and Z are integers.)
- </p>
- <p>As noted earlier, segments have the following general syntax:
- </p>
- <p><c>Value:Size/TypeSpecifierList</c></p>
- <p>When constructing binaries, <c>Value</c> and <c>Size</c> can be
- any Erlang expression. However, for syntactical reasons,
- both <c>Value</c> and <c>Size</c> must be enclosed in parenthesis
- if the expression consists of anything more than a single literal
- or variable. The following gives a compiler syntax error:
- </p>
- <code type="none"><![CDATA[
-<<X+1:8>>
- ]]></code>
- <p>This expression must be rewritten to
- </p>
- <code type="none"><![CDATA[
-<<(X+1):8>>
- ]]></code>
- <p>in order to be accepted by the compiler.
- </p>
-
- <section>
- <title>Including Literal Strings</title>
- <p>As syntactic sugar, an literal string may be written instead of a
- element.</p>
- <code type="none"><![CDATA[
-<<"hello">> ]]></code>
- <p>which is syntactic sugar for</p>
- <code type="none"><![CDATA[
-<<$h,$e,$l,$l,$o>> ]]></code>
- </section>
- </section>
-
- <section>
- <title>Matching Binaries</title>
- <p>This section describes the rules for matching binaries using the
- bit syntax.
- </p>
- <p>There can be zero or more segments in a binary binary pattern.
- A binary pattern can occur in every place patterns are allowed, also
- inside other patterns. Binary patterns cannot be nested.
- </p>
- <p>The pattern '<c><![CDATA[<<>>]]></c>' matches a zero length binary.
- </p>
- <p>Each segment in a binary can consist of zero or more bits.
- </p>
- <p>A segment of type <c>binary</c> must have a size evenly divisible by 8.
- </p>
- <p>This means that the following head will never match:</p>
- <code type="none"><![CDATA[
-foo(<<X:7/binary,Y:1/binary>>) -> ]]></code>
- <p>As noted earlier, segments have the following general syntax:
- </p>
- <p><c>Value:Size/TypeSpecifierList</c></p>
- <p>When matching <c>Value</c> value must be either a variable or an integer
- or floating point literal. Expressions are not allowed.
- </p>
- <p><c>Size</c> must be an integer literal, or a previously bound variable.
- Note that the following is not allowed:</p>
- <code type="none"><![CDATA[
-foo(N, <<X:N,T/binary>>) ->
- {X,T}. ]]></code>
- <p>The two occurrences of <c>N</c> are not related. The compiler
- will complain that the <c>N</c> in the size field is unbound.
- </p>
- <p>The correct way to write this example is like this:</p>
- <code type="none"><![CDATA[
-foo(N, Bin) ->
- <<X:N,T/binary>> = Bin,
- {X,T}. ]]></code>
-
- <section>
- <title>Getting the Rest of the Binary</title>
- <p>To match out the rest of binary, specify a binary field without size:</p>
- <code type="none"><![CDATA[
-foo(<<A:8,Rest/binary>>) -> ]]></code>
- <p>As always, the size of the tail must be evenly divisible by 8.
- </p>
- </section>
- </section>
-
- <section>
- <title>Traps and Pitfalls</title>
- <p>Assume that we need a function that creates a binary out of a
- list of triples of integers. A first (inefficient) version of such
- a function could look like this:</p>
- <code type="none"><![CDATA[
-triples_to_bin(T) ->
- triples_to_bin(T, <<>>).
-
-triples_to_bin([{X,Y,Z} | T], Acc) ->
- triples_to_bin(T, <<Acc/binary, X:32, Y:32, Z:32>>); % inefficient
-triples_to_bin([], Acc) ->
- Acc. ]]></code>
- <p>The reason for the inefficiency of this function is that for
- each triple, the binary constructed so far (<c>Acc</c>) is copied.
- (Note: The original bit syntax prototype avoided the copy operation
- by using segmented binaries, which are not implemented in R7.)
- </p>
- <p>The efficient way to write this function in R7 is:</p>
- <code type="none"><![CDATA[
-triples_to_bin(T) ->
- triples_to_bin(T, []).
-
-triples_to_bin([{X,Y,Z} | T], Acc) ->
- triples_to_bin(T, [<<X:32, Y:32, Z:32>> | Acc]);
-triples_to_bin([], Acc) ->
- list_to_binary(lists:reverse(Acc)). ]]></code>
- <p>Note that <c>list_to_binary/1</c> handles deep lists of binaries
- and small integers. (This fact was previously undocumented.)
- </p>
- </section>
-</chapter>
-
diff --git a/system/doc/extensions/book.xml b/system/doc/extensions/book.xml
deleted file mode 100644
index ffdbe6cb44..0000000000
--- a/system/doc/extensions/book.xml
+++ /dev/null
@@ -1,45 +0,0 @@
-<?xml version="1.0" encoding="latin1" ?>
-<!DOCTYPE book SYSTEM "book.dtd">
-
-<book>
- <header titlestyle="normal">
- <copyright>
- <year>1997</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>Erlang Extensions Since 4.4</title>
- <prepared>OTP Team</prepared>
- <docno></docno>
- <date>1997-05-21</date>
- <rev></rev>
- <file>book.sgml</file>
- </header>
- <insidecover>
- </insidecover>
- <pagetext>Erlang Extensions Since 4.4</pagetext>
- <preamble>
- <contents level="2"></contents>
- </preamble>
- <parts lift="no">
- <include file="part"></include>
- </parts>
- <listofterms></listofterms>
- <index></index>
-</book>
-
diff --git a/system/doc/extensions/fun_test.erl b/system/doc/extensions/fun_test.erl
deleted file mode 100644
index 8472fd87f8..0000000000
--- a/system/doc/extensions/fun_test.erl
+++ /dev/null
@@ -1,17 +0,0 @@
-%1
--module(fun_test).
--export([t1/0, t2/0, t3/0, t4/0, double/1]).
--import(lists, [map/2]).
-
-t1() -> map(fun(X) -> 2 * X end, [1,2,3,4,5]).
-
-t2() -> map(fun double/1, [1,2,3,4,5]).
-
-t3() -> map({?MODULE, double}, [1,2,3,4,5]).
-
-double(X) -> X * 2.
-%1
-
-
-t4() ->
- "hello world".
diff --git a/system/doc/extensions/funparse.erl b/system/doc/extensions/funparse.erl
deleted file mode 100644
index 5e23c90df9..0000000000
--- a/system/doc/extensions/funparse.erl
+++ /dev/null
@@ -1,74 +0,0 @@
--module(funparse).
--compile(export_all).
--import(lists, [reverse/1]).
-
-%17
-%% > hof:parse([a,c]).
-%% {ok,{'and',{'or',1,{const,a}},{'or',1,{const,c}}}}
-%% > hof:parse([a,d]).
-%% {ok,{'and',{'or',1,{const,a}},{'or',2,{const,d}}}}
-%% > hof:parse([b,c]).
-%% {ok,{'and',{'or',2,{const,b}},{'or',1,{const,c}}}}
-%% > hof:parse([b,d]).
-%% {ok,{'and',{'or',2,{const,b}},{'or',2,{const,d}}}}
-%% > hof:parse([a,b]).
-%% fail
-%17
-
-%% Grammar = (a | b) & (c | d)
-
-%12
-parse(List) ->
- (grammar())(List).
-%12
-
-%13
-grammar() ->
- pand(
- por(pconst(a), pconst(b)),
- por(pconst(c), pconst(d))).
-%13
-
-%14
-pconst(X) ->
- fun (T) ->
- case T of
- [X|T1] -> {ok, {const, X}, T1};
- _ -> fail
- end
- end.
-%14
-
-%15
-por(P1, P2) ->
- fun (T) ->
- case P1(T) of
- {ok, R, T1} ->
- {ok, {'or',1,R}, T1};
- fail ->
- case P2(T) of
- {ok, R1, T1} ->
- {ok, {'or',2,R1}, T1};
- fail ->
- fail
- end
- end
- end.
-%15
-
-%16
-pand(P1, P2) ->
- fun (T) ->
- case P1(T) of
- {ok, R1, T1} ->
- case P2(T1) of
- {ok, R2, T2} ->
- {ok, {'and', R1, R2}};
- fail ->
- fail
- end;
- fail ->
- fail
- end
- end.
-%16
diff --git a/system/doc/extensions/funs.xml b/system/doc/extensions/funs.xml
deleted file mode 100644
index f9c003c8ee..0000000000
--- a/system/doc/extensions/funs.xml
+++ /dev/null
@@ -1,486 +0,0 @@
-<?xml version="1.0" encoding="latin1" ?>
-<!DOCTYPE chapter SYSTEM "chapter.dtd">
-
-<chapter>
- <header>
- <copyright>
- <year>1997</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>Programming with Funs</title>
- <prepared>Joe Armstrong</prepared>
- <responsible>Bjarne D&auml;cker</responsible>
- <docno>1</docno>
- <approved>Bjarne D&auml;Ker</approved>
- <checked></checked>
- <date>96-01-16</date>
- <rev>PA1</rev>
- <file>funs.sgml</file>
- </header>
- <p>This section introduces functional objects (Funs). That is a new data type introduced in Erlang 4.4. Functions which takes Funs as arguments, or which return Funs are called higher order functions.</p>
- <list type="bulleted">
- <item>Funs can be passed as arguments to other functions, just like lists or tuples</item>
- <item>functions can be written which return Funs, just like any other data object.</item>
- </list>
-
- <section>
- <title>Higher Order Functions </title>
- <p>Funs encourages us to encapsulate common patterns of design into functional forms called higher order functions. These functions not only shortens programs, but also produce clearer programs because the intended meaning of the program is explicitly rather than implicitly stated.</p>
- <p>The concepts of higher order functions and procedural abstraction are introduced with two brief examples.</p>
-
- <section>
- <title>Example 1 - map</title>
- <p>If we want to double every element in a list, we could write a function named <c>double</c>:</p>
- <code type="none">
-
-double([H|T]) -> [2*H|double(T)];
-double([]) -> [] </code>
- <p>This function obviously doubles the argument entered as input as follows:</p>
- <pre>
-
-> <input>double([1,2,3,4]).</input>
-[2,4,6,8] </pre>
- <p>We now add the function <c>add_one</c>, which adds one to every element in a list:</p>
- <code type="none">
-
-add_one([H|T]) -> [H+1|add_one(T)];
-add_one([]) -> []. </code>
- <p>These functions, <c>double</c> and <c>add_one</c>, have a very similar structure. We can exploit this fact and write a function <c>map</c> which expresses this similarity:</p>
- <codeinclude file="funs1.erl" tag="%1" type="erl"></codeinclude>
- <p>We can now express the functions <c>double</c> and <c>add_one</c> in terms of <c>map</c> as follows:</p>
- <code type="none">
-
-double(L) -> map(fun(X) -> 2*X end, L).
-add_one(L) -> map(fun(X) -> 1 + X end, L). </code>
- <p><c>map(F, List)</c> is a function which takes a function <c>F</c> and a list <c>L</c> as arguments and
- returns the new list which is obtained by applying <c>F</c> to each of the elements in <c>L</c>.</p>
- <p>The process of abstracting out the common features of a number of different programs is called procedural abstraction. Procedural abstraction can be used in order to write several different functions which have a similar structure, but differ only in some minor detail. This is done as follows:</p>
- <list type="ordered">
- <item>write one function which represents the common features of these functions</item>
- <item>parameterize the difference in terms of functions which are passed as arguments to the common function.</item>
- </list>
- </section>
-
- <section>
- <title>Example 2 - foreach</title>
- <p>This example illustrates procedural abstraction. Initially, we show the following two examples written as conventional functions:</p>
- <list type="ordered">
- <item>all elements of a list are printed onto a stream</item>
- <item>a message is broadcast to a list of processes.</item>
- </list>
- <code type="none">
-
-print_list(Stream, [H|T]) ->
- io:format(Stream, "~p~n", [H]),
- print_list(Stream, T);
-print_on_list(Stream, []) ->
- true. </code>
- <code type="none">
-
-broadcast(Msg, [Pid|Pids]) ->
- Pid ! Msg,
- broadcast(Msg, Pids);
-broadcast(_, []) ->
- true. </code>
- <p>Both these functions have a very similar structure. They both iterate over a list doing something to each element in the list. The "something" has to be carried round as an extra argument to the function which does this.</p>
- <p>The function <c>foreach</c> expresses this similarity:</p>
- <codeinclude file="funs1.erl" tag="%2" type="erl"></codeinclude>
- <p>Using <c>foreach</c>, <c>print_on_list</c> becomes:</p>
- <code type="none">
-
-foreach(fun(H) -> io:format(S, "~p~n~,[H]) end, L) </code>
- <p><c>broadcast</c> becomes:</p>
- <code type="none">
-
-foreach(fun(Pid) -> Pid ! M end, L) </code>
- <p><c>foreach</c> is evaluated for its side-effect and not its value. <c>foreach(Fun ,L)</c> calls <c>Fun(X)</c> for each element <c>X</c> in <c>L</c> and the processing occurs in the order in which the elements were defined in <c>L</c>. <c>map</c> does not define the order in which its elements are processed.</p>
- </section>
- </section>
-
- <section>
- <title>Advantages of Higher Order Functions</title>
- <p>Programming with higher order functions, such as <c>map</c> and <c>foreach</c>, has a number of advantages:</p>
- <list type="bulleted">
- <item>It is much easier to understand the program and the intention of the programmer is clearly expressed in the code. The statement <c>foreach(fun(X) -></c> clearly indicates that the intention of this program is to do something to each element in the list <c>L</c>. We also know that the function which is passed as the first argument of <c>foreach</c> takes one argument <c>X</c>, which will be successively bound to each of the elements in <c>L</c>.</item>
- <item>Functions which take Funs as arguments are much easier to re-use than other functions. </item>
- </list>
- </section>
-
- <section>
- <title>The Syntax of Funs</title>
- <p>Funs are written with the syntax:</p>
- <code type="none">
-
-F = fun (Arg1, Arg2, ... ArgN) ->
- ...
- end </code>
- <p>This creates an anonymous function of <c>N</c> arguments and binds it to the variable <c>F</c>.</p>
- <p>If we have already written a function in the same module and wish to pass this function as an argument, we can use the following syntax:</p>
- <code type="none">
-
-F = fun FunctionName/Arity </code>
- <p>With this form of function reference, the function which is referred to does not need to be exported from the module.</p>
- <p>We can also refer to a function defined in a different module with the following syntax:</p>
- <code type="none">
-
-F = {Module, FunctionName} </code>
- <p>In this case, the function must be exported from the module in question.</p>
- <p>The follow program illustrates the different ways of creating Funs:</p>
- <codeinclude file="fun_test.erl" tag="%1" type="erl"></codeinclude>
- <p>We can evaluate the fun <c>F</c> with the syntax:</p>
- <code type="none">
-
-F(Arg1, Arg2, ..., Argn) </code>
- <p>To check whether a term is a Fun, use the test <c>function/1</c>
- in a guard. Example:</p>
- <code type="none">
-f(F, Args) when function(F) ->
- apply(F, Args);
-f(N, _) when integer(N) ->
- N. </code>
- <p>Funs are a distinct type. The BIFs erlang:fun_info/1,2 can
- be used to retrieve information about a fun, and the BIF
- erlang:fun_to_list/1 returns a textual representation of a fun.
- The check_process_code/2 BIF returns true if the
- process contains funs that depend on the old version of
- a module.</p>
- <note>
- <p>In OTP R5 and earlier releases, funs were represented
- using tuples.</p>
- </note>
- </section>
-
- <section>
- <title>Variable Bindings within a Fun</title>
- <p>The scope rules for variables which occur in Funs are as follows:</p>
- <list type="bulleted">
- <item>All variables which occur in the head of a Fun are assumed to be "fresh" variables.</item>
- <item>Variables which are defined before the Fun, and which occur in function calls or guard tests within the Fun, have the values they had outside the Fun.</item>
- <item>No variables may be exported from a Fun.</item>
- </list>
- <p>The following examples illustrate these rules:</p>
- <code type="none">
-
-print_list(File, List) ->
- {ok, Stream} = file:open(File, write),
- foreach(fun(X) -> io:format(Stream,"~p~n",[X]) end, List),
- file:close(Stream). </code>
- <p>In the above example, the variable <c>X</c> which is defined in the head of the Fun is a new variable. The value of the variable <c>Stream</c> which is used within within the Fun gets its value from the
- <c>file:open</c> line.</p>
- <p>Since any variable which occurs in the head of a Fun is considered a new variable it would be equally valid to write:</p>
- <code type="none">
-
-print_list(File, List) ->
- {ok, Stream} = file:open(File, write),
- foreach(fun(File) ->
- io:format(Stream,"~p~n",[File])
- end, List),
- file:close(Stream). </code>
- <p>In this example, <c>File</c> is used as the new variable instead of <c>X</c>. This is rather silly since code in the body of the Fun cannot refer to the variable <c>File</c> which is defined outside the Fun. Compiling this example will yield the diagnostic:</p>
- <code type="none">
-
-./FileName.erl:Line: Warning: variable 'File'
- shadowed in 'lambda head' </code>
- <p>This reminds us that the variable <c>File</c> which is defined inside the Fun collides with the variable <c>File</c> which is defined outside the Fun.</p>
- <p>The rules for importing variables into a Fun has the consequence that certain pattern matching operations have to be moved into guard expressions and cannot be written in the head of the Fun. For example, we might write the following code if we intend the first clause of <c>F</c> to be evaluated when the value of its argument is <c>Y</c>:</p>
- <code type="none">
-
-f(...) ->
- Y = ...
- map(fun(X) when X == Y ->
- ;
- (_) ->
- ...
- end, ...)
- ... </code>
- <p>instead of</p>
- <code type="none">
-
-f(...) ->
- Y = ...
- map(fun(Y) ->
- ;
- (_) ->
- ...
- end, ...)
- ... </code>
- </section>
-
- <section>
- <title>Funs and the Module Lists</title>
- <p>The following examples show a dialogue with the Erlang shell. All the higher order functions discussed are exported from the module <c>lists</c>.</p>
-
- <section>
- <title>map</title>
- <codeinclude file="funs1.erl" tag="%1" type="erl"></codeinclude>
- <p><c>map</c> takes a function of one argument and a list of terms. It returns the list obtained by applying the function to every argument in the list.</p>
- <pre>
-
-1> <input>Double = fun(X) -> 2 * X end.</input>
-#Fun&lt;erl_eval>
-2><input>lists:map(Double, [1,2,3,4,5]).</input>
-[2,4,6,8,10] </pre>
- <p>When a new Fun is defined in the shell, the value of the Fun is printed as <c><![CDATA[Fun#<erl_eval>]]></c></p>
- </section>
-
- <section>
- <title>any</title>
- <codeinclude file="funs1.erl" tag="%4" type="erl"></codeinclude>
- <p><c>any</c> takes a predicate <c>P</c> of one argument and a list of terms. A predicate is a function which returns <c>true</c> or <c>false</c>. <c>any</c> is true if there is a term <c>X</c> in the list such that <c>P(X)</c> is <c>true</c>.</p>
- <p>We define a predicate <c>Big(X)</c> which is <c>true</c> if its argument is greater that 10.</p>
- <pre>
-
-3> <input>Big = fun(X) -> if X > 10 -> true; true -> false end end.</input>
-#Fun&lt;erl_eval>
-4><input>lists:any(Big, [1,2,3,4]).</input>
-false.
-5> <input>lists:any(Big, [1,2,3,12,5]).</input>
-true. </pre>
- </section>
-
- <section>
- <title>all</title>
- <codeinclude file="funs1.erl" tag="%3" type="erl"></codeinclude>
- <p><c>all</c> has the same arguments as <c>any</c>. It is true if the predicate applied to all elements in the list is true.</p>
- <pre>
-
-6><input>lists:all(Big, [1,2,3,4,12,6]).</input>
-false
-7><input>lists:all(Big, [12,13,14,15]).</input>
-true </pre>
- </section>
-
- <section>
- <title>foreach</title>
- <codeinclude file="funs1.erl" tag="%2" type="erl"></codeinclude>
- <p><c>foreach</c> takes a function of one argument and a list of terms. The function is applied to each argument in the list. <c>foreach</c> returns <c>ok</c>. It is used for its side-effect only.</p>
- <pre>
-
-8> <input>lists:foreach(fun(X) -> io:format("~w~n",[X]) end, [1,2,3,4]).</input>
-1
-2
-3
-4
-true </pre>
- </section>
-
- <section>
- <title>foldl</title>
- <codeinclude file="funs1.erl" tag="%8" type="erl"></codeinclude>
- <p><c>foldl</c> takes a function of two arguments, an accumulator and a list. The function is called with two arguments. The first argument is the successive elements in the list, the second argument is the accumulator. The function must return a new accumulator which is used the next time the function is called.</p>
- <p>If we have a list of lists <c>L = ["I","like","Erlang"]</c>, then we can sum the lengths of all the strings in <c>L</c> as follows:</p>
- <pre>
-
-9> <input>L = ["I","like","Erlang"].</input>
-["I","like","Erlang"]
-10> <input>lists:foldl(fun(X, Sum) -> length(X) + Sum end, 0, L).</input>
-11 </pre>
- <p><c>foldl</c> works like a <c>while</c> loop in an imperative language:</p>
- <code type="none">
-
- L = ["I","like","Erlang"],
- Sum = 0,
- while( L != []){
- Sum += length(head(L)),
- L = tail(L)
- end </code>
- </section>
-
- <section>
- <title>mapfoldl</title>
- <codeinclude file="funs1.erl" tag="%10" type="erl"></codeinclude>
- <p><c>mapfoldl</c> simultaneously maps and folds over a list. The following example shows how to change all letters in <c>L</c> to upper case and count them.</p>
- <p>First upcase:</p>
- <pre>
-
-11> <input>Upcase = fun(X) when $a =&lt; X, X =&lt; $z -> X + $A - $a;</input>
-<input>(X) -> X</input>
-<input>end.</input>
-#Fun&lt;erl_eval>
-12> <input>Upcase_word =</input>
-<input>fun(X) -></input>
-<input>lists:map(Upcase, X)</input>
-<input>end.</input>
-#Fun&lt;erl_eval>
-13><input>Upcase_word("Erlang").</input>
-"ERLANG"
-14><input>lists:map(Upcase_word, L).</input>
-["I","LIKE","ERLANG"] </pre>
- <p>Now we can do the fold and the map at the same time:</p>
- <pre>
-
-14> <input>lists:mapfoldl(fun(Word, Sum) -></input>
-14> <input>{Upcase_word(Word), Sum + length(Word)}</input>
-14> <input>end, 0, L).</input>
-{["I","LIKE","ERLANG"],11} </pre>
- </section>
-
- <section>
- <title>filter</title>
- <codeinclude file="funs1.erl" tag="%9" type="erl"></codeinclude>
- <p><c>filter</c> takes a predicate of one argument and a list and returns all element in the list which satisfy the predicate.</p>
- <pre>
-
-15><input>lists:filter(Big, [500,12,2,45,6,7]).</input>
-[500,12,45] </pre>
- <p>When we combine maps and filters we can write very succinct and obviously correct code. For example, suppose we want to define a set difference function. We want to define <c>diff(L1, L2)</c> to be the difference between the lists <c>L1</c> and <c>L2</c>.
- This is the list of all elements in L1 which are not contained in L2. This code can be written as follows:</p>
- <code type="none">
-
-diff(L1, L2) ->
- filter(fun(X) -> not member(X, L2) end, L1). </code>
- <p>The AND intersection of the list <c>L1</c> and <c>L2</c> is also easily defined:</p>
- <code type="none">
-
-intersection(L1,L2) -> filter(fun(X) -> member(X,L1) end, L2). </code>
- </section>
-
- <section>
- <title>takewhile</title>
- <codeinclude file="funs1.erl" tag="%5" type="erl"></codeinclude>
- <p><c>takewhile(P, L)</c> takes elements <c>X</c> from a list <c>L</c> as long as the predicate <c>P(X)</c> is true.</p>
- <pre>
-
-16><input>lists:takewhile(Big, [200,500,45,5,3,45,6]).</input>
-[200,500,45] </pre>
- </section>
-
- <section>
- <title>dropwhile</title>
- <codeinclude file="funs1.erl" tag="%6" type="erl"></codeinclude>
- <p><c>dropwhile</c> is the complement of <c>takewhile</c>.</p>
- <pre>
-
-17> <input>lists:dropwhile(Big, [200,500,45,5,3,45,6]).</input>
-[5,3,45,6] </pre>
- </section>
-
- <section>
- <title>splitlist</title>
- <codeinclude file="funs1.erl" tag="%7" type="erl"></codeinclude>
- <p><c>splitlist(P, L)</c> splits the list <c>L</c> into the two sub-lists <c>{L1, L2}</c>, where <c>L = takewhile(P, L)</c> and <c>L2 = dropwhile(P, L)</c>.</p>
- <pre>
-
-18><input>lists:splitlist(Big, [200,500,45,5,3,45,6]).</input>
-{[200,500,45],[5,3,45,6]} </pre>
- </section>
-
- <section>
- <title>first</title>
- <codeinclude file="funs1.erl" tag="%11" type="erl"></codeinclude>
- <p><c>first</c> returns <c>{true, R}</c>, where <c>R</c> is the first element in a list satisfying a predicate or <c>false</c>:</p>
- <pre>
-
-19><input>lists:first(Big, [1,2,45,6,123]).</input>
-{true,45}
-20><input>lists:first(Big, [1,2,4,5]). </input>
-false </pre>
- </section>
- </section>
-
- <section>
- <title>Funs which Return Funs</title>
- <p>So far, this section has only described functions which take Funs as arguments. It is also possible to write more powerful functions which themselves return Funs. The following examples illustrate these type of functions.</p>
-
- <section>
- <title>Simple Higher Order Functions</title>
- <p><c>Adder(X)</c> is a function which, given <c>X</c>, returns a new function <c>G</c> such that <c>G(K)</c> returns <c>K + X</c>.</p>
- <pre>
-
-21> <input>Adder = fun(X) -> fun(Y) -> X + Y end end.</input>
-#Fun&lt;erl_eval>
-22> <input>Add6 = Adder(6).</input>
-#Fun&lt;erl_eval>
-23><input>Add6(10).</input>
-16 </pre>
- </section>
-
- <section>
- <title>Infinite Lists</title>
- <p>The idea is to write something like:</p>
- <code type="none">
-
--module(lazy).
--export([ints_from/1]).
-ints_from(N) ->
- fun() ->
- [N|ints_from(N+1)]
- end. </code>
- <p>Then we can proceed as follows:</p>
- <code type="none"><![CDATA[
-
-24> XX = lazy:ints_from(1).
-#Fun<lazy>
-25> XX().
-[1|#Fun<lazy>]
-26> hd(XX()).
-1
-27> Y = tl(XX()).
-#Fun<lazy>
-28> hd(Y()).
-2 ]]></code>
- <p>etc. - this is an example of "lazy embedding"</p>
- </section>
-
- <section>
- <title>Parsing</title>
- <p>The following examples show parsers of the following type:</p>
- <pre>
-Parser(Toks) -> {ok, Tree, Toks1} | fail </pre>
- <p><c>Toks</c> is the list of tokens to be parsed. A successful parse returns <c>{ok, Tree, Toks1}</c>, where <c>Tree</c> is a parse tree and <c>Toks1</c> is a tail of <c>Tree</c> which contains symbols encountered after the structure which was correctly parsed. Otherwise <c>fail</c> is returned.</p>
- <p>The example which follows illustrates a simple, functional parser which parses the grammar:</p>
- <pre>
-(a | b) &amp; (c | d) </pre>
- <p>The following code defines a function <c>pconst(X)</c> in the module <c>funparse</c>, which returns a Fun which parses a list of tokens.</p>
- <codeinclude file="funparse.erl" tag="%14" type="erl"></codeinclude>
- <p>This function can be used as follows:</p>
- <pre>
-29><input>P1 = funparse:pconst(a).</input>
-#Fun&lt;hof>
-30> <input>P1([a,b,c]).</input>
-{ok,{const,a},[b,c]}
-31> <input>P1([x,y,z]).</input>
-fail </pre>
- <p>Next, we define the two higher order functions <c>pand</c> and <c>por</c> which combine primitive parsers to produce more complex parsers. Firstly <c>pand</c>:</p>
- <codeinclude file="funparse.erl" tag="%16" type="erl"></codeinclude>
- <p>Given a parser <c>P1</c> for grammar <c>G1</c>, and a parser <c>P2</c> for grammar <c>G2</c>, <c>pand(P1, P2)</c>
- returns a parser for the grammar which consists of sequences of tokens which satisfy <c>G1</c> followed by sequences of tokens which satisfy <c>G2</c>.</p>
- <p><c>por(P1, P2)</c> returns a parser for the language described by the grammar <c>G1</c> or <c>G2</c>.</p>
- <codeinclude file="funparse.erl" tag="%15" type="erl"></codeinclude>
- <p>The original problem was to parse the grammar <c><![CDATA[(a | b) & (c | d)]]></c>. The following code addresses this problem: </p>
- <codeinclude file="funparse.erl" tag="%13" type="erl"></codeinclude>
- <p>The following code adds a parser interface to the grammar:</p>
- <codeinclude file="funparse.erl" tag="%12" type="erl"></codeinclude>
- <p>We can test this parser as follows:</p>
- <pre>
-
-32> <input>funparse:parse([a,c]).</input>
-{ok,{'and',{'or',1,{const,a}},{'or',1,{const,c}}}}
-33> <input>funparse:parse([a,d]).</input>
-{ok,{'and',{'or',1,{const,a}},{'or',2,{const,d}}}}
-34> <input>funparse:parse([b,c]).</input>
-{ok,{'and',{'or',2,{const,b}},{'or',1,{const,c}}}}
-35> <input>funparse:parse([b,d]).</input>
-{ok,{'and',{'or',2,{const,b}},{'or',2,{const,d}}}}
-36> <input>funparse:parse([a,b]).</input>
-fail </pre>
- </section>
- </section>
-</chapter>
-
diff --git a/system/doc/extensions/funs1.erl b/system/doc/extensions/funs1.erl
deleted file mode 100644
index b1a3e21525..0000000000
--- a/system/doc/extensions/funs1.erl
+++ /dev/null
@@ -1,125 +0,0 @@
--module(funs1).
--compile(export_all).
--import(lists, [reverse/1]).
-
-%1
-map(F, [H|T]) -> [F(H)|map(F, T)];
-map(F, []) -> [].
-%1
-
-%2
-foreach(F, [H|T]) ->
- F(H),
- foreach(F, T);
-foreach(F, []) ->
- ok.
-%2
-%
-%3
-all(Pred, [H|T]) ->
- case Pred(H) of
- true -> all(Pred, T);
- false -> false
- end;
-all(Pred, []) ->
- true.
-%3
-%4
-any(Pred, [H|T]) ->
- case Pred(H) of
- true -> true;
- false -> any(Pred, T)
- end;
-any(Pred, []) ->
- false.
-%4
-%5
-takewhile(Pred, [H|T]) ->
- case Pred(H) of
- true -> [H|takewhile(Pred, T)];
- false -> []
- end;
-takewhile(Pred, []) ->
- [].
-%5
-%6
-dropwhile(Pred, [H|T]) ->
- case Pred(H) of
- true -> dropwhile(Pred, T);
- false -> [H|T]
- end;
-dropwhile(Pred, []) ->
- [].
-%6
-%7
-splitlist(Pred, L) ->
- splitlist(Pred, L, []).
-
-splitlist(Pred, [H|T], L) ->
- case Pred(H) of
- true -> splitlist(Pred, T, [H|L]);
- false -> {reverse(L), [H|T]}
- end;
-splitlist(Pred, [], L) ->
- {reverse(L), []}.
-%7
-
-flatmap(F, [Hd|Tail]) ->
- F(Hd) ++ flatmap(F, Tail);
-flatmap(F, []) -> [].
-
-%8
-foldl(F, Accu, [Hd|Tail]) ->
- foldl(F, F(Hd, Accu), Tail);
-foldl(F, Accu, []) -> Accu.
-%8
-%
-foldr(F, Accu, [Hd|Tail]) ->
- F(Hd, foldr(F, Accu, Tail));
-foldr(F, Accu, []) -> Accu.
-%9
-filter(F, [H|T]) ->
- case F(H) of
- true -> [H|filter(F, T)];
- false -> filter(F, T)
- end;
-filter(F, []) -> [].
-%9
-%10
-mapfoldl(F, Accu0, [Hd|Tail]) ->
- {R,Accu1} = F(Hd, Accu0),
- {Rs,Accu2} = mapfoldl(F, Accu1, Tail),
- {[R|Rs], Accu2};
-mapfoldl(F, Accu, []) -> {[], Accu}.
-%10
-mapfoldr(F, Accu0, [Hd|Tail]) ->
- {Rs,Accu1} = mapfoldr(F, Accu0, Tail),
- {R,Accu2} = F(Hd, Accu1),
- {[R|Rs],Accu2};
-mapfoldr(F, Accu, []) -> {[], Accu}.
-%11
-first(Pred, [H|T]) ->
- case Pred(H) of
- true ->
- {true, H};
- false ->
- first(Pred, T)
- end;
-first(Pred, []) ->
- false.
-%11
-%
-compose(F, G) ->
- fun(X) ->
- F(G(X))
- end.
-
-%20
-iterate(N, F) ->
- iterate(N, N+1, F).
-
-iterate(Stop, Stop, _) ->
- [];
-iterate(N, Stop, Fun) ->
- [Fun(N)|iterate(N+1, Stop, Fun)].
-%20
diff --git a/system/doc/extensions/include.xml b/system/doc/extensions/include.xml
deleted file mode 100644
index cd78644b95..0000000000
--- a/system/doc/extensions/include.xml
+++ /dev/null
@@ -1,81 +0,0 @@
-<?xml version="1.0" encoding="latin1" ?>
-<!DOCTYPE chapter SYSTEM "chapter.dtd">
-
-<chapter>
- <header>
- <copyright>
- <year>1999</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>Includes</title>
- <prepared>Arndt Jonasson</prepared>
- <docno>1</docno>
- <date>99-01-25</date>
- <rev>PA1</rev>
- <file>include.sgml</file>
- </header>
- <p>There are two directives which can be used in Erlang source
- files to cause the compiler to temporarily read input from another
- source. They are typically used to provide macro definitions and
- record definitions from header files. It is recommended to use the
- file name extension <c>".hrl"</c> for files which are meant to be
- included (the 'h' can be read as "header").</p>
- <p>When locating header files a list of directory names, the
- compiler include path, is used. In short the list contains the current
- working directory of the file server, the base name of the compiled
- file, and the directories given by the include option, in that order.
- See <c>erlc(1)</c> and <c>compile(3)</c> for the details of the
- compiler include path.</p>
-
- <section>
- <title>The -include Directive</title>
- <p>The first action taken by the <c>-include</c> directive is to
- check if the format of the first path component of the specified
- filename is <c>$VAR</c>, for some string <c>VAR</c>. If that is the
- case, the value of the environment variable <c>VAR</c> as returned by
- <c>os:getenv(VAR)</c> is substituted for the first path component. If
- <c>os:getenv/1</c> returns <c>false</c>, the first path component is
- left as is. If the filename is absolute (possibly after variable
- substitution), the header file with that name is included. Otherwise,
- the specified header file is searched for in the directories in the
- compiler include path, starting with the first directory in the list.
- The first file found while traversing the list is included. Examples:</p>
- <code type="none">
- -include("my_records.hrl").
- -include("incdir/more_records.hrl").
- -include("/home/users/proj/recs.hrl").
- -include("$PROJ_ROOT/app1/defs.hrl"). </code>
- </section>
-
- <section>
- <title>The -include_lib Directive</title>
- <p>The <c>-include_lib</c> directive first tries to find the
- specified header file using the procedure employed for the
- <c>-include</c> directive. If no header file can be found by searching
- the compiler include path, the first path component of the specified
- filename (possibly after variable substitution) is regarded as the
- name of an application, and the directory of the current version of
- the application is searched. Example:</p>
- <code type="none">
- -include_lib("mnesia/include/mnemosyne.hrl"). </code>
- <p>The compiler is instructed to look for the directory where the
- current version of the <c>mnesia</c> application is installed, that is
- <c>code:lib_dir(mnesia)</c>, and then search the subdirectory
- <c>include</c> for the file <c>mnemosyne.hrl</c>.</p>
- </section>
-</chapter>
-
diff --git a/system/doc/extensions/list_comprehensions.erl b/system/doc/extensions/list_comprehensions.erl
deleted file mode 100644
index 21ac562aa5..0000000000
--- a/system/doc/extensions/list_comprehensions.erl
+++ /dev/null
@@ -1,118 +0,0 @@
--module(t).
--author('[email protected]').
-
-%%-export([test/2]).
--compile(export_all).
-
-%% Odd numbers.
-
-%%foo(L) -> [ X || X <- L, (X > X-1) == (X /= X-1) ].
-
-bar(L) -> [ X || X <- L, integer(X), gt(X, 3) ].
-
-bar(L, M) -> [ Y || X <- L, integer(X), gt(X, 3),
- Y <- M, float(Y), gt(X, Y)
- ].
-
-baz(L) -> [ X || X <- L, atom(X) ].
-
-buz(L, Min) -> [ X || Min > 3, X <- L, X >= Min ].
-
-gt(X, Y) when X > Y -> true;
-gt(X, Y) -> false.
-
-%% Turn a list into a set.
-make_set([]) -> [];
-make_set([H|T]) ->
- [H|[
- Y || Y <- make_set(T),
- Y =/= H
- ]].
-
-%% Return the Pythagorean triangles with sides
-%% of total length less than N
-pyth(N) ->
- [ {A,B,C} ||
- A <- lists:seq(1,N),
- B <- lists:seq(1,N),
- C <- lists:seq(1,N),
- A+B+C =< N,
- A*A+B*B == C*C
- ].
-
-%% Cut the search space a bit..
-pyth2(N) ->
- [ {A,B,C} ||
- A <- lists:seq(1,N),
- B <- lists:seq(1,N-A+1),
- C <- lists:seq(1,N-A-B+2),
- A+B+C =< N,
- A*A+B*B == C*C ].
-
-%% Return the Cartesian product
-cp() ->
- [ {X,Y} ||
- X <- a(),
- Y <- b()
- ].
-
-cp(A,B) when list(A),list(B) ->
- [ {X,Y} ||
- X <- A,
- Y <- B
- ].
-
-%a() -> 1/0.
-a() -> [a,b].
-b() -> [1,2,3].
-
-%% Return all permutations of a list
-perms([]) -> [[]];
-perms(L) -> [ [H|T] || H <- L, T <- perms(L--[H]) ].
-
-%% Quick sort
-sort([X|Xs]) ->
- sort([ Y || Y <- Xs, Y < X ]) ++
- [X] ++
- sort([ Y || Y <- Xs, Y >= X ]);
-sort([]) -> [].
-
-%% Vector addition
-vecAdd(Xs,Ys) ->
- [ X+Y || {X,Y} <- zip(Xs,Ys) ].
-
-zip([X|Xs],[Y|Ys]) -> [{X,Y}|zip(Xs,Ys)];
-zip([],[]) -> [].
-
-qsort([X|Xs]) ->
- qsort(lt(X,Xs))
- ++ [X] ++
- qsort(ge(X,Xs));
-qsort([]) -> [].
-
-lt(X,[H|T]) when X>H -> [H|lt(X,T)];
-lt(X,[_|T]) -> lt(X,T);
-lt(_,[]) -> [].
-
-ge(X,[H|T]) when X=<H -> [H|ge(X,T)];
-ge(X,[_|T]) -> ge(X,T);
-ge(_,[]) -> [].
-
-test(1,N) -> statistics(runtime),test1(N),statistics(runtime);
-test(2,N) -> statistics(runtime),test2(N),statistics(runtime);
-test(3,N) -> statistics(runtime),test3(N),statistics(runtime).
-
-test1(0) -> true;
-test1(N) ->
- sort([21,12,45,1,3,87,55,77,11,20,6,99,91,13,14,15,66,62,69,71,67,82,83,84,87,86,85]),
- test1(N-1).
-
-test2(0) -> true;
-test2(N) ->
- qsort([21,12,45,1,3,87,55,77,11,20,6,99,91,13,14,15,66,62,69,71,67,82,83,84,87,86,85]),
- test2(N-1).
-
-test3(0) -> true;
-test3(N) ->
- lists:sort([21,12,45,1,3,87,55,77,11,20,6,99,91,13,14,15,66,62,69,71,67,82,83,84,87,86,85]),
- test3(N-1).
diff --git a/system/doc/extensions/list_comprehensions.xml b/system/doc/extensions/list_comprehensions.xml
deleted file mode 100644
index 30e32da79c..0000000000
--- a/system/doc/extensions/list_comprehensions.xml
+++ /dev/null
@@ -1,205 +0,0 @@
-<?xml version="1.0" encoding="latin1" ?>
-<!DOCTYPE chapter SYSTEM "chapter.dtd">
-
-<chapter>
- <header>
- <copyright>
- <year>1997</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>List Comprehensions</title>
- <prepared>Joe Armstrong</prepared>
- <responsible>Bjarne D&auml;cker</responsible>
- <docno>1</docno>
- <approved>Bjarne D&auml;Ker</approved>
- <checked></checked>
- <date>96-09-10</date>
- <rev>PA1</rev>
- <file>list_comprehensions.sgml</file>
- </header>
- <p>List comprehensions are a feature of many modern functional programming languages. Subject to certain rules, they provide a succinct notation for generating elements in a list.</p>
- <p>List comprehensions are analogous to set comprehensions
- in Zermelo-Frankel set theory and are called ZF expressions in
- Miranda. They are analogous to the <c>setof</c> and
- <c>findall</c> predicates in Prolog.</p>
- <p>List comprehensions are written with the following syntax:
- </p>
- <code type="none">
-
-[Expression || Qualifier1, Qualifier2, ...] </code>
- <p><c>Expression</c> is an arbitrary expression, and each <c>Qualifier</c> is either a generator or a filter.</p>
- <list type="bulleted">
- <item>A <em>generator</em> written as <c><![CDATA[Pattern <- ListExpr]]></c>. <c>ListExpr</c> must be an expression which evaluates to a list of terms.</item>
- <item>A <em>filter</em> is either a predicate or a boolean expression. A predicate is a function which returns <c>true</c> or <c>false</c>.</item>
- </list>
-
- <section>
- <title>Examples of List Comprehensions</title>
- <p>We start with a simple example:</p>
- <code type="none"><![CDATA[
-
-> [X || X <- [1,2,a,3,4,b,5,6], X > 3].
-[a,4,b,5,6] ]]></code>
- <p>This should be read as follows:</p>
- <quote>
- <p>The list of X such that X is taken from the list <c>[1,2,a,...]</c> and X is greater than 3.</p>
- </quote>
- <p>The notation <c><![CDATA[X <- [1,2,a,...]]]></c> is a generator and the expression <c>X > 3</c> is a filter.</p>
- <p>An additional filter can be added in order to restrict the result to integers:</p>
- <code type="none"><![CDATA[
-
-> [X || X <- [1,2,a,3,4,b,5,6], integer(X), X > 3].
-[4,5,6] ]]></code>
- <p>Generators can be combined. For example, the Cartesian product of two lists can be written as follows:</p>
- <code type="none"><![CDATA[
-
-> [{X, Y} || X <- [1,2,3], Y <- [a,b]].
-[{1,a},{1,b},{2,a},{2,b},{3,a},{3,b}] ]]></code>
-
- <section>
- <title>Quick Sort</title>
- <p>The well known quick sort routine can be written as follows:</p>
- <code type="none"><![CDATA[
-
-sort([Pivot|T]) ->
- sort([ X || X <- T, X < Pivot]) ++
- [Pivot] ++
- sort([ X || X <- T, X >= Pivot]);
-sort([]) -> []. ]]></code>
- <p>The expression <c><![CDATA[[X || X <- T, X < Pivot]]]></c> is the list of all elements in <c>T</c>, which are less than <c>Pivot</c>.</p>
- <p><c><![CDATA[[X || X <- T, X >= Pivot]]]></c> is the list of all elements in <c>T</c>, which are greater or equal to <c>Pivot</c>.</p>
- <p>To sort a list, we isolate the first element in the list and split the list into two sub-lists. The first sub-list contains all elements which are smaller than the first element in the list, the second contains all elements which are greater than or equal to the first element in the list. We then sort the sub-lists and combine the results.</p>
- </section>
-
- <section>
- <title>Permutations</title>
- <p>The following example generates all permutations of the elements in a list:</p>
- <code type="none"><![CDATA[
-
-perms([]) -> [[]];
-perms(L) -> [[H|T] || H <- L, T <- perms(L--[H])]. ]]></code>
- <p>We take take <c>H</c> from <c>L</c> in all possible ways. The result is the set of all lists <c>[H|T]</c>, where <c>T</c> is the set of all possible permutations of <c>L</c> with <c>H</c> removed.</p>
- <code type="none">
-
-> perms([b,u,g]).
-[[b,u,g],[b,g,u],[u,b,g],[u,g,b],[g,b,u],[g,u,b]] </code>
- </section>
-
- <section>
- <title>Pythagorean Triplets</title>
- <p>Pythagorean triplets are sets of integers <c>{A,B,C}</c> such that <c>A**2 + B**2 = C**2</c>.</p>
- <p>The function <c>pyth(N)</c> generates a list of all integers <c>{A,B,C}</c> such that <c>A**2 + B**2 = C**2</c> and where the sum of the sides is less than <c>N</c>.</p>
- <code type="none"><![CDATA[
-
-pyth(N) ->
- [ {A,B,C} ||
- A <- lists:seq(1,N),
- B <- lists:seq(1,N),
- C <- lists:seq(1,N),
- A+B+C =< N,
- A*A+B*B == C*C
- ]. ]]></code>
- <pre>
-
-> <input>pyth(3).</input>
-[].
-> <input>pyth(11).</input>
-[].
-><input>pyth(12).</input>
-[{3,4,5},{4,3,5}]
-> <input>pyth(50).</input>
-[{3,4,5},
- {4,3,5},
- {5,12,13},
- {6,8,10},
- {8,6,10},
- {8,15,17},
- {9,12,15},
- {12,5,13},
- {12,9,15},
- {12,16,20},
- {15,8,17},
- {16,12,20}]</pre>
- <p>The following code reduces the search space and is more efficient:</p>
- <code type="none"><![CDATA[
-
-pyth1(N) ->
- [{A,B,C} ||
- A <- lists:seq(1,N),
- B <- lists:seq(1,N-A+1),
- C <- lists:seq(1,N-A-B+2),
- A+B+C =< N,
- A*A+B*B == C*C ]. ]]></code>
- </section>
-
- <section>
- <title>Simplifications with List Comprehensions</title>
- <p>As an example, list comprehensions can be used to simplify some of the functions in <c>lists.erl</c>:</p>
- <code type="none"><![CDATA[
-
-append(L) -> [X || L1 <- L, X <- L1].
-map(Fun, L) -> [Fun(X) || X <- L].
-filter(Pred, L) -> [X || X <- L, Pred(X)]. ]]></code>
- </section>
- </section>
-
- <section>
- <title>Variable Bindings in List Comprehensions</title>
- <p>The scope rules for variables which occur in list comprehensions are as follows:</p>
- <list type="bulleted">
- <item>all variables which occur in a generator pattern are assumed to be "fresh" variables</item>
- <item>any variables which are defined before the list comprehension and which are used in filters have the values they had before the list comprehension</item>
- <item>no variables may be exported from a list comprehension.</item>
- </list>
- <p>As an example of these rules, suppose we want to write the function <c>select</c>, which selects certain elements from a list of tuples. We might write <c><![CDATA[select(X, L) -> [Y || {X, Y} <- L].]]></c> with the intention of extracting all tuples from <c>L</c> where the first item is <c>X</c>.</p>
- <p>Compiling this yields the following diagnostic:</p>
- <code type="none">
-
-./FileName.erl:Line: Warning: variable 'X' shadowed in generate </code>
- <p>This diagnostic warns us that the variable <c>X</c> in the pattern is not the same variable as the variable <c>X</c> which occurs in the function head.</p>
- <p>Evaluating <c>select</c> yields the following result:</p>
- <pre>
-
-> <input>select(b,[{a,1},{b,2},{c,3},{b,7}]).</input>
-[1,2,3,7] </pre>
- <p>This result is not what we wanted. To achieve the desired effect we must write <c>select</c> as follows:</p>
- <code type="none"><![CDATA[
-
-select(X, L) -> [Y || {X1, Y} <- L, X == X1]. ]]></code>
- <p>The generator now contains unbound variables and the test has been moved into the filter. This now works as expected:</p>
- <pre>
-
-> <input>select(b,[{a,1},{b,2},{c,3},{b,7}]).</input>
-[2,7] </pre>
- <p>One consequence of the rules for importing variables into a list comprehensions is that certain pattern matching operations have to be moved into the filters and cannot be written directly in the generators. To illustrate this, do <em>not</em> write as follows:</p>
- <code type="none"><![CDATA[
-
-f(...) ->
- Y = ...
- [ Expression || PatternInvolving Y <- Expr, ...]
- ... ]]></code>
- <p>Instead, write as follows:</p>
- <code type="none"><![CDATA[
-
-f(...) ->
- Y = ...
- [ Expression || PatternInvolving Y1 <- Expr, Y == Y1, ...]
- ...
- ]]></code>
- </section>
-</chapter>
-
diff --git a/system/doc/extensions/list_comrehensions.erl b/system/doc/extensions/list_comrehensions.erl
deleted file mode 100644
index f6a23b5dca..0000000000
--- a/system/doc/extensions/list_comrehensions.erl
+++ /dev/null
@@ -1,75 +0,0 @@
--module(zf).
-
--compile(export_all).
-
-
-%% Odd numbers.
-
-%%foo(L) -> [ X || X <- L, (X > X-1) == (X /= X-1) ].
-
-boo() -> [X||X <- [1,2,a,3,4,b,5,6], X > 3].
-boo1() -> [X||X <- [1,2,a,3,4,b,5,6], integer(X),X > 3].
-boo2() -> [{X,Y} || X <- [1,2,3], Y <- [a,b]].
-
-bar(L) -> [ X || X <- L, integer(X), gt(X, 3) ].
-
-bar(L, M) -> [ Y || X <- L, integer(X), gt(X, 3),
- Y <- M, float(Y), gt(X, Y)
- ].
-
-baz(L) -> [ X || X <- L, atom(X) ].
-
-buz(L, Min) -> [ X || Min > 3, X <- L, X >= Min ].
-
-gt(X, Y) when X > Y -> true;
-gt(X, Y) -> false.
-
-
-%% Return the Pythagorean triangles with sides
-%% of total length less than N
-pyth(N) ->
- [ {A,B,C} ||
- A <- lists:seq(1,N),
- B <- lists:seq(1,N),
- C <- lists:seq(1,N),
- A+B+C =< N,
- A*A+B*B == C*C
- ].
-
-%% Cut the search space a bit..
-pyth2(N) ->
- [ {A,B,C} ||
- A <- lists:seq(1,N),
- B <- lists:seq(1,N-A+1),
- C <- lists:seq(1,N-A-B+2),
- A+B+C =< N,
- A*A+B*B == C*C ].
-
-%% Return the Cartesian product
-
-cp(A,B) ->
- [ {X,Y} ||
- X <- A,
- Y <- B
- ].
-
-%% Return all permutations of a list
-perms([]) -> [[]];
-perms(L) -> [ [H|T] || H <- L, T <- perms(L--[H]) ].
-
-%% Quick sort
-sort([X|Xs]) ->
- sort([ Y || Y <- Xs, Y < X ]) ++
- [X] ++
- sort([ Y || Y <- Xs, Y >= X ]);
-sort([]) -> [].
-
-%% append
-
-append(L) -> [X||L1<-L,X<-L1].
-
-map(Fun, L) -> [Fun(X)||X<-L].
-
-filter(Pred, L) -> [X||X<-L,Pred(X)].
-
-select(X, L) -> [Y || {X1,Y} <- L, X == X1].
diff --git a/system/doc/extensions/macros.xml b/system/doc/extensions/macros.xml
deleted file mode 100644
index feb3de6102..0000000000
--- a/system/doc/extensions/macros.xml
+++ /dev/null
@@ -1,177 +0,0 @@
-<?xml version="1.0" encoding="latin1" ?>
-<!DOCTYPE chapter SYSTEM "chapter.dtd">
-
-<chapter>
- <header>
- <copyright>
- <year>1997</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>Macros</title>
- <prepared>Joe Armstrong</prepared>
- <responsible>Bjarne D&auml;cker</responsible>
- <docno>1</docno>
- <approved>Bjarne D&auml;Ker</approved>
- <checked></checked>
- <date>96-09-10</date>
- <rev>PA1</rev>
- <file>macros.sgml</file>
- </header>
- <p>Macros in Erlang are written with the following syntax:</p>
- <code type="none">
-
--define(Const, Replacement).
--define(Fun(Var1, Var2,.., Var), Replacement). </code>
- <p>Macros are expanded when the syntax <c>?MacroName</c> is encountered.</p>
- <p>Consider the macro definition:</p>
- <code type="none">
-
--define(timeout, 200). </code>
- <p>The expression <c>?timeout</c>, which can occur anywhere in the code which follows the macro definition, will be replaced by <c>200</c>.</p>
- <p>Macros with arguments are written as follows:</p>
- <code type="none">
-
- -define(macro1(X, Y), {a, X, b, Y}). </code>
- <p>This type of macro can be used as follows:</p>
- <code type="none">
-
-bar(X) ->
- ?macro1(a, b),
- ?macro1(X, 123) </code>
- <p>This expands to:</p>
- <code type="none">
-
-bar(X) ->
- {a,a,b,b},
- {a,X,b,123}. </code>
-
- <section>
- <title>Macros and Tokens</title>
- <p>Macro expansion works at a token level. We might define a macro as follows:</p>
- <code type="none">
-
--define(macro2(X, Y), {a,X,b,Y). </code>
- <p>The replacement value of the macro is not a valid Erlang term because the closing right curly bracket is missing. <c>macro2</c> expands into a sequence of tokens <c>{</c>, <c>a</c>, <c>X</c> which are then pasted into the place where the macro is used.</p>
- <p>We might use this macro as follows:</p>
- <code type="none">
-
-bar() ->
- ?macro2(x,y)}. </code>
- <p>This will expand into the valid sequence of tokens <c>{a,x,y,b}</c> before being parsed and compiled.</p>
- <note>
- <p>It is good programming practise to ensure that the replacement text of a macro is a valid Erlang syntactic form.</p>
- </note>
- </section>
-
- <section>
- <title>Pre-Defined Macros</title>
- <p>The following macros are pre-defined:</p>
- <taglist>
- <tag><c>?MODULE</c>. </tag>
- <item>This macro returns the name of the current module.
- </item>
- <tag><c>?MODULE_STRING</c>. </tag>
- <item>This macro returns the name of the current module, as a string.</item>
- <tag><c>?FILE</c>.</tag>
- <item>This macro returns the current file name.</item>
- <tag><c>?LINE</c>.</tag>
- <item>This macro returns the current line number.</item>
- <tag><c>?MACHINE</c>.</tag>
- <item>This macro returns the current machine name,
- <c>'BEAM'</c>,</item>
- </taglist>
- </section>
-
- <section>
- <title>Stringifying Macro Arguments</title>
- <p>The construction <c>??Arg</c> for an argument to a macro expands to a
- string containing the tokens of the argument, similar to the
- <c>#arg</c> stringifying construction in C. This was added in Erlang
- 5.0 (OTP R7A).</p>
- <p>Example:</p>
- <code type="none">
--define(TESTCALL(Call), io:format("Call ~s: ~w~n", [??Call, Call])).
-
-?TESTCALL(myfunction(1,2)),
-?TESTCALL(you:function(2,1)).</code>
- <p>results in</p>
- <code type="none">
-io:format("Call ~s: ~w~n",["myfunction ( 1 , 2 )",m:myfunction(1,2)]),
-io:format("Call ~s: ~w~n",["you : function ( 2 , 1 )",you:function(2,1)]).</code>
- </section>
-
- <section>
- <title>Flow Control in Macros</title>
- <p>The following macro directives are supplied:</p>
- <taglist>
- <tag>-undef(Macro).</tag>
- <item>Causes the macro to behave as if it had never been defined.</item>
- <tag>-ifdef(Macro).</tag>
- <item>Do the following lines if <c>Macro</c> is defined.</item>
- <tag>-ifndef(Macro).</tag>
- <item>Do the following lines if <c>Macro</c> is not defined.</item>
- <tag>-else.</tag>
- <item>"else" macro</item>
- <tag>-endif.</tag>
- <item>"endif" macro.</item>
- </taglist>
- <p>The conditional macros must be properly nested. They are usually grouped as follows:</p>
- <code type="none">
-
--ifdef(debug)
--define(....)
--else
--define(...)
--endif </code>
- <p>The following example illustrates this grouping:</p>
- <code type="none">
-
--define(debug, true).
--ifdef(debug).
--define(trace(Str, X), io:format("Mod:~w line:~w ~p ~p~n",
- [?MODULE,?LINE, Str, X])).
--else.
--define(trace(X, Y), true).
--endif. </code>
- <p>Given these definitions, the expression <c>?trace("X=", X).</c> in line 10 of the module <c>foo</c> expands to:</p>
- <code type="none">
-
-io:format("Mod:~w line:~w ~p ~p~n",[foo,100,"X=",[X]]), </code>
- <p>If we remove the <c>-define(debug, true).</c> line, then the same expression expands to <c>true</c>.</p>
- </section>
-
- <section>
- <title>A Macro Expansion Utility</title>
- <p>The following code can be used to expand a macro and display the result:</p>
- <code type="none">
-
--module(mexpand).
--export([file/1]).
--import(lists, [foreach/2]).
-file(File) ->
- case epp:parse_file(File ++ ".erl", [],[]) of
- {ok, L} ->
- {ok, Stream} = file:open(File ++ ".out", write),
- foreach(fun(X) ->
- io:format(Stream,"~s~n",[erl_pp:form(X)])
- end, L),
- file:close(Stream)
- end.</code>
- <p>Alternatively, we can compile the file with the <c>'P'</c> option. <c>compile:file(File, ['P'])</c> produces a list file <c>File.P</c>, in which the result of any macro expansions can be seen.</p>
- </section>
-</chapter>
-
diff --git a/system/doc/extensions/make.dep b/system/doc/extensions/make.dep
deleted file mode 100644
index fdac959667..0000000000
--- a/system/doc/extensions/make.dep
+++ /dev/null
@@ -1,21 +0,0 @@
-# ----------------------------------------------------
-# >>>> Do not edit this file <<<<
-# This file was automaticly generated by
-# /home/otp/bin/docdepend
-# ----------------------------------------------------
-
-
-# ----------------------------------------------------
-# TeX files that the DVI file depend on
-# ----------------------------------------------------
-
-book.dvi: bit_syntax.tex book.tex funs.tex include.tex \
- list_comprehensions.tex macros.tex misc.tex \
- part.tex records.tex
-
-# ----------------------------------------------------
-# Source inlined when transforming from source to LaTeX
-# ----------------------------------------------------
-
-funs.tex: fun_test.erl funparse.erl funs1.erl
-
diff --git a/system/doc/extensions/mexpand.erl b/system/doc/extensions/mexpand.erl
deleted file mode 100644
index 261f99da46..0000000000
--- a/system/doc/extensions/mexpand.erl
+++ /dev/null
@@ -1,16 +0,0 @@
--module(mexpand).
-
--export([file/1]).
-
--import(lists, [foreach/2]).
-
-file(File) ->
- case epp:parse_file(File ++ ".erl", [],[]) of
- {ok, L} ->
- {ok, Stream} = file:open(File ++ ".out", write),
- foreach(fun(X) ->
- io:format(Stream,"~s~n",
- [erl_pp:form(X)])
- end, L),
- file:close(Stream)
- end.
diff --git a/system/doc/extensions/misc.xml b/system/doc/extensions/misc.xml
deleted file mode 100644
index 576f705278..0000000000
--- a/system/doc/extensions/misc.xml
+++ /dev/null
@@ -1,310 +0,0 @@
-<?xml version="1.0" encoding="latin1" ?>
-<!DOCTYPE chapter SYSTEM "chapter.dtd">
-
-<chapter>
- <header>
- <copyright>
- <year>1999</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>Miscellaneous</title>
- <prepared>Arndt Jonasson</prepared>
- <docno>1</docno>
- <date>99-01-25</date>
- <rev>PA1</rev>
- <file>misc.sgml</file>
- </header>
- <p>In this chapter, a number of miscellaneous features of Erlang
- are described.</p>
-
- <section>
- <title>Token Syntax</title>
- <p>In Erlang 4.8 (OTP R5A) the syntax of Erlang tokens have been
- extended to allow the use of the full ISO-8859-1 (Latin-1) character
- set. This is noticeable in the following ways:</p>
- <list type="bulleted">
- <item>All the Latin-1 printable characters can be used and are shown without
- the escape backslash convention.</item>
- <item>Atoms and variables can use all Latin-1 letters.</item>
- </list>
- <p>The new characters from Latin-1 have the following
- classifications in Erlang:</p>
- <table>
- <row>
- <cell align="left" valign="middle"><em>Octal</em></cell>
- <cell align="left" valign="middle"><em>Decimal</em></cell>
- <cell align="left" valign="middle">&nbsp;</cell>
- <cell align="left" valign="middle"><em>Class</em></cell>
- </row>
- <row>
- <cell align="left" valign="middle">200 - 237</cell>
- <cell align="left" valign="middle">128 - 159</cell>
- <cell align="left" valign="middle">&nbsp;</cell>
- <cell align="left" valign="middle">Control characters</cell>
- </row>
- <row>
- <cell align="left" valign="middle">240 - 277</cell>
- <cell align="left" valign="middle">160 - 191</cell>
- <cell align="right" valign="middle">- &iquest;</cell>
- <cell align="left" valign="middle">Punctuation characters</cell>
- </row>
- <row>
- <cell align="left" valign="middle">300 - 326</cell>
- <cell align="left" valign="middle">192 - 214</cell>
- <cell align="center" valign="middle">&Agrave; - &Ouml;</cell>
- <cell align="left" valign="middle">Uppercase letters</cell>
- </row>
- <row>
- <cell align="center" valign="middle">327</cell>
- <cell align="center" valign="middle">215</cell>
- <cell align="center" valign="middle">&times;</cell>
- <cell align="left" valign="middle">Punctuation character</cell>
- </row>
- <row>
- <cell align="left" valign="middle">330 - 336</cell>
- <cell align="left" valign="middle">216 - 222</cell>
- <cell align="center" valign="middle">&Oslash; - &THORN;</cell>
- <cell align="left" valign="middle">Uppercase letters</cell>
- </row>
- <row>
- <cell align="left" valign="middle">337 - 366</cell>
- <cell align="left" valign="middle">223 - 246</cell>
- <cell align="center" valign="middle">&szlig; - &ouml;</cell>
- <cell align="left" valign="middle">Lowercase letters</cell>
- </row>
- <row>
- <cell align="center" valign="middle">367</cell>
- <cell align="center" valign="middle">247</cell>
- <cell align="center" valign="middle">&divide;</cell>
- <cell align="left" valign="middle">Punctuation character</cell>
- </row>
- <row>
- <cell align="left" valign="middle">370 - 377</cell>
- <cell align="left" valign="middle">248 - 255</cell>
- <cell align="center" valign="middle">&oslash; - &yuml;</cell>
- <cell align="left" valign="middle">Lowercase letters</cell>
- </row>
- <tcaption>Character classes</tcaption>
- </table>
- </section>
-
- <section>
- <title>String Concatenation</title>
- <p>Two adjacent string literals are concatenated into one. This is done already
- at compile-time, and doesn't incur any runtime overhead. Example:</p>
- <code type="none">
- "string" "42" </code>
- <p>is equivalent to</p>
- <code type="none">
- "string42" </code>
- <p>This feature is convenient in at least two situations:</p>
- <list type="bulleted">
- <item>when one of the
- strings is the result of a macro expansion;</item>
- <item>when a string is very
- long, and would otherwise either have to wrap, making the source code
- harder to read, or force the use of some runtime append operation.</item>
- </list>
- </section>
-
- <section>
- <title>The ++ list Concatenation Operator</title>
- <p>Since list concatenation is a very common operation, it is convenient
- to have a terse way of expressing it. The ++ operator appends its second
- argument to its first. Example:
- </p>
- <code type="none">
- X = [1,2,3],
- Y = [4,5],
- X ++ Y. </code>
- <p>results in <c>[1,2,3,4,5]</c>.</p>
- <p>The ++ operator has precedence between the binary '+' operator and
- the comparison operators.
- </p>
- </section>
-
- <section>
- <title>The - - list Subtraction Operator</title>
- <p>The - - operator produces a list which is a copy of the first
- argument, subjected to the following procedure: for each element in
- the second argument, its first occurrence in the first argument is
- removed.</p>
- <code type="none">
- X = [1,2,3,2,1,2],
- Y = [2,1,2],
- X -- Y. </code>
- <p>results in <c>[3,1,2]</c>.</p>
- <p>The - - operator has precedence between the binary '+' operator and
- the comparison operators.
- </p>
- </section>
-
- <section>
- <title>Bitwise Operator bnot</title>
- <p>Apart from the binary bitwise operators <c>band</c>, <c>bor</c>
- and <c>bxor</c>, there is a unary operator <c>bnot</c> with the same
- precedence as the other unary operators + and -, i.e., higher than
- the binary operators. Example:</p>
- <code type="none">
- bnot 7. </code>
- <p>returns -8.
- </p>
- </section>
-
- <section>
- <title>Logical Operators</title>
- <p>The atoms <c>true</c> and <c>false</c> are usually used for representing
- Boolean values. With the binary operators <c>and</c>, <c>or</c> and
- <c>xor</c>, and the unary operator <c>not</c>, Boolean values can be
- combined. Example:</p>
- <code type="none">
-
- M1 = lists:member(A, List1),
- M2 = lists:member(A, List2),
- M1 and M2.</code>
- <p>Note that the operators are strict, i.e., they always evaluate both
- their arguments.</p>
- <p><c>not</c> has the same priority as the other unary operators. The
- binary logical operators have precedence between the <c>=</c> operator
- and the comparison operators, the <c>and</c> operator having higher
- precedence than <c>or</c> and <c>xor</c>.
- </p>
- </section>
-
- <section>
- <title>Match Operator = In Patterns</title>
- <p>This extension was added in Erlang 4.8 (OTP R5A).</p>
- <p>The = operator is also called the `match' operator. The match operator
- can now be used in a pattern, so that <c>P1 = P2</c> is a valid pattern,
- where both <c>P1</c> and <c>P2</c> are patterns. This compound pattern
- when matched against a term causes the term to be matched against both
- <c>P1</c> and <c>P2</c>.</p>
- <p>One use for this construction is to avoid reconstructing a term which
- was part of an argument to a function. Example:</p>
- <code type="none">
- f({'+',X,Y}=T) -> {X+Y,T}.</code>
- <p>It also makes it possible to rewrite the construction</p>
- <code type="none">
- f(X) when X == #rec{x=1, y=a} -> ... </code>
- <p>as</p>
- <code type="none">
- f(#rec{x=1, y=a} = X) -> ... </code>
- <p>In the absence of optimization for the former case, the
- latter case is more efficient.
- </p>
- </section>
-
- <section>
- <title>Literal String Prefix in Patterns</title>
- <p>This extension was added in Erlang 4.8 (OTP R5A).</p>
- <p>A new construction is allowed in patterns, namely a literal
- string as the first operand of the ++ operator. Example:</p>
- <code type="none">
- f("prefix" ++ L) -> ... </code>
- <p>This is syntactic sugar for the equivalent, but harder to read</p>
- <code type="none">
- f([$p,$r,$e,$f,$i,$x | L]) -> ... </code>
- </section>
-
- <section>
- <title>Disjunctions in Guards</title>
- <p>This extension was added in Erlang 4.9 (OTP R6A).</p>
- <p>A new construction is allowed in guards, the disjunction operator
- ';'. The construction is syntactic sugar which removes the bother of
- writing the same body after several guards.</p>
- <code type="none">
- f(X) when xxx ; yyy ; zzz ->
- pop(X).</code>
- <p>This is syntactic sugar for the equivalent</p>
- <code type="none">
- f(X) when xxx ->
- pop(X);
- f(X) when yyy ->
- pop(X);
- f(X) when zzz ->
- pop(X). </code>
- <p>The abstract format has been changed accordingly to contain a list of
- (conjunctive) guards where there was previously only one guard.
- </p>
- </section>
-
- <section>
- <title>Expressions in Patterns</title>
- <p>This extension was added in Erlang 5.0 (OTP R7A).</p>
- <p>An arithmetic expression can be used within a pattern, if it uses
- only numeric or bitwise operators, and if its value can be evaluated
- to a constant at compile-time. This is especially useful when the
- expression is defined by a macro.
- </p>
- <p>Example:</p>
- <code type="none">
- case X of
- {1+2, T} -> T
- end.</code>
- </section>
-
- <section>
- <title>Boolean expresions in guards</title>
- <p>This extension was added in Erlang 5.1 (OTP R8).</p>
- <p>In guards, the use of <c>and</c>, <c>or</c> and <c>not</c> is
- now allowed. Guard expressions can combine these with
- parenthesis. This allows for more elaborate guards than what
- may be given with <c>,</c> and <c>;</c>.</p>
- <note>
- <p>The guard expressions written with these operators are boolean
- expressions, and the boolean functions <c>is_list</c>,
- <c>is_integer</c> etc. should be used, rather than
- <c>list</c>, <c>integer</c> etc.</p>
- </note>
- <p>Example 1:</p>
- <code type="none">
- f(X) when not (is_tuple(X) or is_list(X)) ->
- ... </code>
- <p>Example 2:</p>
- <code type="none"><![CDATA[
- g(A, B) when (A > 0) and (B > 0) and not (A*A < B*B) ->
- ... ]]></code>
- </section>
-
- <section>
- <title>Short-circuit boolean expressions</title>
- <p>This extension was added in Erlang 5.1 (OTP R8).</p>
- <p>In a boolean expression it is unnecessary to always evaluate all
- terms. If the first term gives a result that determines the
- result, the second term is not needed. In Erlang two new
- keywords handles boolean expressions without evaluating both
- terms, if it's unnecessary. (This is called short-curcuit
- boolean evaluation.)</p>
- <p>The keyword <c>andalso</c> is a short-curcuit version of
- <c>and</c>. The keyword <c>orelse</c> is a short-curcuit version
- of <c>or</c>. They can be used in boolean expressions (not
- guards) instead of <c>and</c> and <c>or</c>.</p>
- <p>Example 1:</p>
- <code type="none">
- case A >= -1.0 andalso math:sqrt(A+1) > B of </code>
- <p>This will work even if <c>A</c> is less than <c>-1.0</c>, since
- in that case, the second term (after <c>andalso</c>) is never
- evaluated. (Of course, the same effects could have been done
- using guards. In guards, evaluation is always short-circuited,
- since guard tests are known to be free of side-effects.)</p>
- <p>Example 2:</p>
- <code type="none">
- OnlyOne = is_atom(L) orelse
- (is_list(L) andalso length(L) == 1), </code>
- </section>
-</chapter>
-
diff --git a/system/doc/extensions/part.xml b/system/doc/extensions/part.xml
deleted file mode 100644
index 56fd2c09a6..0000000000
--- a/system/doc/extensions/part.xml
+++ /dev/null
@@ -1,57 +0,0 @@
-<?xml version="1.0" encoding="latin1" ?>
-<!DOCTYPE part SYSTEM "part.dtd">
-
-<part>
- <header>
- <copyright>
- <year>1997</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>Erlang Extensions Since 4.4</title>
- <prepared>OTP Team</prepared>
- <docno></docno>
- <date>1997-02-21</date>
- <rev>E</rev>
- <file>part.sgml</file>
- </header>
- <description>
- <p>This chapter describes extensions made to the Erlang language
- since version 4.4 (where nothing is said to the contrary, an extension
- was added in version 4.4).
- The chapter contains the following sections:
- </p>
- <list type="bulleted">
- <item>Records</item>
- <item>Functional Objects (Funs)</item>
- <item>List Comprehensions</item>
- <item>Macros</item>
- <item>File inclusion</item>
- <item>Bit syntax</item>
- <item>Miscellaneous</item>
- </list>
- </description>
- <include file="records"></include>
- <include file="funs"></include>
- <include file="list_comprehensions"></include>
- <include file="macros"></include>
- <include file="include"></include>
- <include file="bit_syntax"></include>
- <include file="misc"></include>
-</part>
-
diff --git a/system/doc/extensions/records.xml b/system/doc/extensions/records.xml
deleted file mode 100644
index 21ec73ab77..0000000000
--- a/system/doc/extensions/records.xml
+++ /dev/null
@@ -1,284 +0,0 @@
-<?xml version="1.0" encoding="latin1" ?>
-<!DOCTYPE chapter SYSTEM "chapter.dtd">
-
-<chapter>
- <header>
- <copyright>
- <year>1997</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>Records</title>
- <prepared>Joe Armstrong</prepared>
- <responsible>Bjarne D&auml;cker</responsible>
- <docno>1</docno>
- <approved>Bjarne D&auml;Ker</approved>
- <checked></checked>
- <date>96-09-10</date>
- <rev>PA1</rev>
- <file>records.sgml</file>
- </header>
- <p>A record is a data structure intended for storing a fixed number of related data items. It is
- similar to a <c>struct</c> in C, or a <c>record</c> in Pascal. </p>
- <p>The main advantage of using records instead of tuples is that fields in a record are accessed by name, whereas fields in a tuple are accessed by position. To illustrate these differences, suppose that we want to represent a person with the <em>tuple</em><c>{Name, Address, Phone}</c>.</p>
- <p>We must remember that the <c>Name</c> field is the first element of the tuple, the <c>Address</c> field is the second element, and so on, in order to write functions which manipulate this data. For example, to extract data from a variable <c>P</c> which contains such a tuple we might write the following code and then use pattern matching to extract the relevant fields.</p>
- <code type="none">
-
-Name = element(1, P),
-Address = element(2, P),
-... </code>
- <p>Code like this is difficult to read and understand and errors occur if we get the numbering of the elements in the tuple wrong. If we change the data representation by re-ordering the fields, or by adding or removing a field, then all references to the person tuple, wherever they occur, must be checked and possibly modified.</p>
- <p><em>Records</em> allow us to refer to the fields by name and not position. We use a record instead of a tuple to store the data . If we write a record definition of the type shown below, we can then refer to the fields of the record by name.</p>
- <code type="none">
-
--record(person, {name, phone, address}). </code>
- <p>For example, if <c>P</c> is now a variable whose value is a <c>person</c> record, we can code as follows in order to access the name and address fields of the records.</p>
- <code type="none">
-
-Name = P#person.name,
-Address = P#person.address,
-... </code>
- <p>In the following sections we describe the different operations which can be performed on records:</p>
-
- <section>
- <title>Defining a Record</title>
- <p>A record is defined with the following syntax:</p>
- <code type="none">
-
--record(RecordName, {Field1 [= DefaultValue1],
- Field2 [= DefaultValue2],
- ...,
- FieldN [= DefaultValueN]}). </code>
- <p>The record name and field names must be atoms. The optional default values, which are terms, are used if no value is supplied for a field when a new instance of the record is created. If the default value is not supplied, then the atom <c>undefined</c> is assumed.</p>
- <p>For example, in the following record definition, the address field is <c>undefined</c>.</p>
- <pre>
--record(person, {name = "", phone = [], address}). </pre>
- <p>This definition of a person will be used in many of the examples which follow.</p>
- </section>
-
- <section>
- <title>Including a Record Definition</title>
- <p>If the record is used in several modules, its definition should be placed in a <c>.hrl</c> header file. Each module which uses the record definition should have a <c>-include(FileName).</c> statement. For example:</p>
- <code type="none">
-
--include("my_data_structures.hrl"). </code>
- <note>
- <p>The definition of the record must come before it is used.</p>
- </note>
- </section>
-
- <section>
- <title>Creating a Record</title>
- <p>A new record is created with the following syntax:</p>
- <code type="none">
-
-#RecordName{Field1=Expr1,
- ...,
- FieldM=ExprM}. </code>
- <p>If any of the fields is omitted, then the default value supplied in the record definition is used. For example:</p>
- <pre>
-> #person{phone = [0,8,2,3,4,3,1,2], name = "Robert"}.
-{person, "Robert", [0,8,2,3,4,3,1,2], undefined}. </pre>
- <p>There is a new feature introduced in Erlang 5.1 (OTP release
- R8), with which you can set a value to all fields in a record,
- overriding the defaults in the record specification. The special
- field <c>_</c>, means "all fields not explicitly specified".</p>
- <pre>
-> #person{name = "Jakob", _ = '_'}
-{person, "Jakob", '_', '_'} </pre>
- <p>It is primarily intended to be used in <c>ets:match/2</c> and
- <c>mnesia:match_object/3</c>, to set record fields to the atom
- <c>'_'</c>. (This is a wildcard in <c>ets:match/2</c>.)</p>
- </section>
-
- <section>
- <title>Selectors</title>
- <p>The following syntax is used to select an individual field from a record:</p>
- <code type="none">
-
-Variable#RecordName.Field </code>
- <note>
- <p>The values contained in record names and fields must be constants, not variables.</p>
- </note>
- <note>
- <p>For the purposes of illustration, we will demonstrate the use of records using an imaginary dialogue with the Erlang shell. Currently the Erlang evaluator does not support records so you may not be able to reproduce this dialogue.</p>
- </note>
- <pre>
-
-> <input>P = #person{name = "Joe", phone = [0,8,2,3,4,3,1,2]}.</input>
-{person, "Joe", [0,8,2,3,4,3,1,2], undefined}
-> <input>P#person.name.</input>
-"Joe" </pre>
- <note>
- <p>Selectors for records are allowed in guards.</p>
- </note>
- </section>
-
- <section>
- <title>Updating a Record</title>
- <p>The following syntax is used to create a new copy of the record with some of the fields changed. Only the fields to be changed need to be referred to, all other fields retain their old values.</p>
- <code type="none">
-
-OldVariable#RecordName{Field1 = NewValue1,
- ...,
- FieldM = NewValueM} </code>
- <p>For example:</p>
- <pre>
-> P1 = #person{name="Joe", phone=[1,2,3], address="A street"}.
-{person, "Joe", [1,2,3], "A street"}
-> P2 = P1#person{name="Robert"}.
-{person, "Robert", [1,2,3], "A street"} </pre>
- </section>
-
- <section>
- <title>Type Testing</title>
- <p>The following guard test is used to test the type of a record:</p>
- <code type="none">
-
-record(Variable, RecordName) </code>
- <p>The following example shows that the guard succeeds if <c>P</c> is record of type <c>person</c>.</p>
- <pre>
-foo(P) when record(P, person) -> a_person;
-foo(_) -> not_a_person. </pre>
- <note>
- <p>This test checks that <c>P</c> is a tuple of arity <c>N + 1</c>, where <c>N</c> is the number
- of fields in the record, and the first element in the tuple is the atom <c>person</c>.</p>
- </note>
- </section>
-
- <section>
- <title>Pattern Matching</title>
- <p>Matching can be used in combination with records as shown in the following example:</p>
- <pre>
-> P = #person{name="Joe", phone=[0,0,7], address="A street"}.
-{person, "Joe", [0,0,7], "A street"}
-> #person{name = Name} = P, Name.
-"Joe" </pre>
- <p>The following function takes a list of <c>person</c> records and searches for the phone number of a person with a particular name:</p>
- <code type="none">
-
-find_phone([#person{name=Name, phone=Phone} | _], Name) ->
- {found, Phone};
-find_phone([_| T], Name) ->
- find_phone(T, Name);
-find_phone([], Name) ->
- not_found. </code>
- <note>
- <p>The fields referred to in the pattern can be given in any order.</p>
- </note>
- </section>
-
- <section>
- <title>Nested Records</title>
- <p>The value of a field in a record might be an instance of a record. Retrieval of nested data can be done stepwise, or in a single step, as shown in the following example:</p>
- <pre>
--record(name, {first = "Robert", last = "Ericsson"}).
--record(person, {name = #name{}, phone}).
-
-demo() ->
- P = #person{name= #name{first="Robert",last="Virding"}, phone=123},
- First = (P#person.name)#name.first. </pre>
- <note>
- <p>In this example, <c>demo()</c> evaluates to <c>"Robert"</c>.</p>
- </note>
- </section>
-
- <section>
- <title>Internal Representation of Records</title>
- <p>It is often desirable to write generic functions which will work on any record, not just a record of a particular type. For this reason, records are represented internally as tuples and the ordering of the fields in the tuple is strictly defined.</p>
- <p>For example, the record <c>-record(person, {name, phone, address}).</c> is represented internally by the tuple <c>{person, X, Y, Z}</c>.</p>
- <p>The arity of the tuple is one more than the number of fields in the tuple. The first element of the tuple is the name of the record, and the elements of the tuple are the fields in the record. The variables <c>X</c>, <c>Y</c> and <c>Z</c> will store the data contained in the record fields.</p>
- <p>The following two functions determine the indices in the tuple which refer to the named fields in the record:</p>
- <list type="bulleted">
- <item><c>record_info(fields, Rec) -> [Names]</c>. This function returns the names of the fields in the record <c>Rec</c>. For example, <c>record_info(fields, person)</c> evaluates to <c>[name, address, phone]</c>.</item>
- <item><c>record_info(size, Rec) -> Size</c>. This function returns the size of the record <c>Rec</c> when represented as a tuple, which is one more than the number of fields. For example, <c>record_info(size, person)</c> returns <c>4</c>.</item>
- </list>
- <p>In addition, <c>#Rec.Name</c> returns the index in the tuple representation of <c>Name</c> of the record <c>Rec</c>.</p>
- <note>
- <p><c>Name</c> must be an atom.</p>
- </note>
- <p>For example, the following test function <c>test()</c> might return the result shown:</p>
- <pre>
-test() ->
- {record_info(fields, person),
- record_info(size, person),
- #person.name}. </pre>
- <pre>
-> <input>Mod:test().</input>
-{[name,address,phone],4,2} </pre>
- <p>The order in which records map onto tuples is implementation dependent.</p>
- <note>
- <p><c>record_info</c> is a pseudo-function which cannot be exported from the module where it occurs.</p>
- </note>
- </section>
-
- <section>
- <title>Example</title>
- <pre>
-%% File: person.hrl
-
-%%-----------------------------------------------------------
-%% Data Type: person
-%% where:
-%% name: A string (default is undefined).
-%% age: An integer (default is undefined).
-%% phone: A list of integers (default is []).
-%% dict: A dictionary containing various information
-%% about the person.
-%% A {Key, Value} list (default is the empty list).
-%%------------------------------------------------------------
--record(person, {name, age, phone = [], dict = []}).
- </pre>
- <pre>
--module(person).
--include("person.hrl").
--compile(export_all). % For test purposes only.
-
-%% This creates an instance of a person.
-%% Note: The phone number is not supplied so the
-%% default value [] will be used.
-
-make_hacker_without_phone(Name, Age) ->
- #person{name = Name, age = Age,
- dict = [{computer_knowledge, excellent},
- {drinks, coke}]}.
-
-%% This demonstrates matching in arguments
-
-print(#person{name = Name, age = Age,
- phone = Phone, dict = Dict}) ->
- io:format("Name: ~s, Age: ~w, Phone: ~w ~n"
- "Dictionary: ~w.~n", [Name, Age, Phone, Dict]).
-
-%% Demonstrates type testing, selector, updating.
-
-birthday(P) when record(P, person) ->
- P#person{age = P#person.age + 1}.
-
-register_two_hackers() ->
- Hacker1 = make_hacker_without_phone("Joe", 29),
- OldHacker = birthday(Hacker1),
- % The central_register_server should have
- % an interface function for this.
- central_register_server ! {register_person, Hacker1},
- central_register_server ! {register_person,
- OldHacker#person{name = "Robert",
- phone = [0,8,3,2,4,5,3,1]}}. </pre>
- </section>
-</chapter>
-
diff --git a/system/doc/extensions/warning.gif b/system/doc/extensions/warning.gif
deleted file mode 100644
index 96af52360e..0000000000
--- a/system/doc/extensions/warning.gif
+++ /dev/null
Binary files differ
diff --git a/system/doc/installation_guide/Makefile b/system/doc/installation_guide/Makefile
index c51f0ee5f3..854025765c 100644
--- a/system/doc/installation_guide/Makefile
+++ b/system/doc/installation_guide/Makefile
@@ -1,19 +1,19 @@
#
# %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
# 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%
#
#
@@ -54,6 +54,15 @@ XML_FILES = \
$(XML_PART_FILES)
# ----------------------------------------------------
+# Install readme files
+# ----------------------------------------------------
+SOURCE_INSTALL_READMES = \
+ $(ERL_TOP)/INSTALL.html \
+ $(ERL_TOP)/INSTALL-CROSS.html \
+ $(ERL_TOP)/INSTALL-WIN32.html
+
+SOURCE_RELSYSDIR = $(RELSYSDIR)/source
+# ----------------------------------------------------
HTML_FILES = \
$(XML_PART_FILES:%.xml=%.html)
@@ -92,8 +101,9 @@ include $(ERL_TOP)/make/otp_release_targets.mk
release_docs_spec: docs
$(INSTALL_DIR) $(RELSYSDIR)
- $(INSTALL_DATA) $(GIF_FILES) $(HTMLDIR)/*.html \
- $(RELSYSDIR)
+ $(INSTALL_DATA) $(GIF_FILES) $(HTMLDIR)/*.html $(RELSYSDIR)
+ $(INSTALL_DIR) $(SOURCE_RELSYSDIR)
+ $(INSTALL_DATA) $(SOURCE_INSTALL_READMES) $(SOURCE_RELSYSDIR)
release_spec:
diff --git a/system/doc/installation_guide/install.xml b/system/doc/installation_guide/install.xml
index 2e37ff35e9..c1b930a4bd 100644
--- a/system/doc/installation_guide/install.xml
+++ b/system/doc/installation_guide/install.xml
@@ -4,7 +4,7 @@
<chapter>
<header>
<copyright>
- <year>2000</year><year>2009</year>
+ <year>2000</year><year>2010</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
@@ -13,12 +13,12 @@
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>Installation</title>
@@ -33,6 +33,23 @@
</header>
<section>
+ <title>Source</title>
+ <p>This document describes installation procedures for
+ binary releases. Documentation of build and installation
+ procedures for the source release can be found in the source
+ tree at the following locations:</p>
+ <taglist>
+ <tag>Building and Installing Erlang/OTP</tag>
+ <item><url href="source/INSTALL.html"><c>$ERL_TOP/INSTALL.md</c></url></item>
+ <tag>Cross Compiling Erlang/OTP</tag>
+ <item><url href="source/INSTALL-CROSS.html"><c>$ERL_TOP/INSTALL-CROSS.md</c></url></item>
+ <tag>How to Build Erlang/OTP on Windows</tag>
+ <item><url href="source/INSTALL-WIN32.html"><c>$ERL_TOP/INSTALL-WIN32.md</c></url></item>
+ </taglist>
+ <p>Where <c>$ERL_TOP</c> is the top directory in the source tree.</p>
+ </section>
+
+ <section>
<title>UNIX</title>
<section>
diff --git a/system/doc/pics/Makefile b/system/doc/pics/Makefile
deleted file mode 100644
index fc5996259d..0000000000
--- a/system/doc/pics/Makefile
+++ /dev/null
@@ -1,58 +0,0 @@
-#
-# Copyright (C) 1996,1997 Ericsson Telecommunications
-# Author: Lars Thorsen
-#
-include $(ERL_TOP)/make/target.mk
-include $(ERL_TOP)/make/$(TARGET)/otp.mk
-
-# ----------------------------------------------------
-# Release directory specification
-# ----------------------------------------------------
-RELSYSDIR = $(RELEASE_PATH)/doc
-
-# ----------------------------------------------------
-# Target Specs
-# ----------------------------------------------------
-#
-# Common macros
-#
-
-GIF_FILES= \
- min_head.gif \
- ps.gif
-
-# ----------------------------------------------------
-# Target Specs
-# ----------------------------------------------------
-
-docs:
-
-pdf:
-
-ps:
-
-debug opt:
-
-
-
-clean:
- @echo "No action" >/dev/null
-
-#
-# Release Targets
-#
-include $(ERL_TOP)/make/otp_release_targets.mk
-
-ifeq ($(DOCTYPE),pdf)
-release_docs_spec: pdf
-else
-ifeq ($(DOCTYPE),ps)
-release_docs_spec: ps
-else
-release_docs_spec: docs
- $(INSTALL_DIR) $(RELSYSDIR)/pics
- $(INSTALL_DATA) $(GIF_FILES) $(RELSYSDIR)/pics
-endif
-endif
-
-release_spec:
diff --git a/system/doc/pics/app.gif b/system/doc/pics/app.gif
deleted file mode 100644
index 345d5795b1..0000000000
--- a/system/doc/pics/app.gif
+++ /dev/null
Binary files differ
diff --git a/system/doc/pics/ede.gif b/system/doc/pics/ede.gif
deleted file mode 100644
index 7a51766898..0000000000
--- a/system/doc/pics/ede.gif
+++ /dev/null
Binary files differ
diff --git a/system/doc/pics/ede_logo.gif b/system/doc/pics/ede_logo.gif
deleted file mode 100644
index f7c902791b..0000000000
--- a/system/doc/pics/ede_logo.gif
+++ /dev/null
Binary files differ
diff --git a/system/doc/pics/min_head.gif b/system/doc/pics/min_head.gif
deleted file mode 100644
index 67948a6378..0000000000
--- a/system/doc/pics/min_head.gif
+++ /dev/null
Binary files differ
diff --git a/system/doc/pics/notes.gif b/system/doc/pics/notes.gif
deleted file mode 100644
index e000cca26a..0000000000
--- a/system/doc/pics/notes.gif
+++ /dev/null
Binary files differ
diff --git a/system/doc/pics/otp.gif b/system/doc/pics/otp.gif
deleted file mode 100644
index 48c4ca9c02..0000000000
--- a/system/doc/pics/otp.gif
+++ /dev/null
Binary files differ
diff --git a/system/doc/pics/otp_logo.gif b/system/doc/pics/otp_logo.gif
deleted file mode 100644
index d1a1f7f72d..0000000000
--- a/system/doc/pics/otp_logo.gif
+++ /dev/null
Binary files differ
diff --git a/system/doc/pics/ps.gif b/system/doc/pics/ps.gif
deleted file mode 100644
index 186dfc7e24..0000000000
--- a/system/doc/pics/ps.gif
+++ /dev/null
Binary files differ
diff --git a/system/doc/pics/ref_man.gif b/system/doc/pics/ref_man.gif
deleted file mode 100644
index b13c4efd53..0000000000
--- a/system/doc/pics/ref_man.gif
+++ /dev/null
Binary files differ
diff --git a/system/doc/pics/user_guide.gif b/system/doc/pics/user_guide.gif
deleted file mode 100644
index e6275a803d..0000000000
--- a/system/doc/pics/user_guide.gif
+++ /dev/null
Binary files differ
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/data_types.xml b/system/doc/reference_manual/data_types.xml
index c85ac44165..df1c0f8fa8 100644
--- a/system/doc/reference_manual/data_types.xml
+++ b/system/doc/reference_manual/data_types.xml
@@ -59,7 +59,7 @@
42
2> <input>$A.</input>
65
-3> <input>$\ .</input>
+3> <input>$\n.</input>
10
4> <input>2#101.</input>
5
@@ -296,68 +296,68 @@ true</pre>
<cell align="left" valign="middle"><em>Description</em></cell>
</row>
<row>
- <cell align="left" valign="middle">\\b</cell>
+ <cell align="left" valign="middle">\b</cell>
<cell align="left" valign="middle">backspace</cell>
</row>
<row>
- <cell align="left" valign="middle">\\d</cell>
+ <cell align="left" valign="middle">\d</cell>
<cell align="left" valign="middle">delete</cell>
</row>
<row>
- <cell align="left" valign="middle">\\e</cell>
+ <cell align="left" valign="middle">\e</cell>
<cell align="left" valign="middle">escape</cell>
</row>
<row>
- <cell align="left" valign="middle">\\f</cell>
+ <cell align="left" valign="middle">\f</cell>
<cell align="left" valign="middle">form feed</cell>
</row>
<row>
- <cell align="left" valign="middle">\</cell>
+ <cell align="left" valign="middle">\n</cell>
<cell align="left" valign="middle">newline</cell>
</row>
<row>
- <cell align="left" valign="middle">\\r</cell>
+ <cell align="left" valign="middle">\r</cell>
<cell align="left" valign="middle">carriage return</cell>
</row>
<row>
- <cell align="left" valign="middle">\\s</cell>
+ <cell align="left" valign="middle">\s</cell>
<cell align="left" valign="middle">space</cell>
</row>
<row>
- <cell align="left" valign="middle">\\t</cell>
+ <cell align="left" valign="middle">\t</cell>
<cell align="left" valign="middle">tab</cell>
</row>
<row>
- <cell align="left" valign="middle">\\v</cell>
+ <cell align="left" valign="middle">\v</cell>
<cell align="left" valign="middle">vertical tab</cell>
</row>
<row>
- <cell align="left" valign="middle">\\XYZ, \\YZ, \\Z</cell>
+ <cell align="left" valign="middle">\XYZ, \YZ, \Z</cell>
<cell align="left" valign="middle">character with octal representation XYZ, YZ or Z</cell>
</row>
<row>
- <cell align="left" valign="middle">\\xXY</cell>
+ <cell align="left" valign="middle">\xXY</cell>
<cell align="left" valign="middle">character with hexadecimal representation XY</cell>
</row>
<row>
- <cell align="left" valign="middle">\\x{X...}</cell>
+ <cell align="left" valign="middle">\x{X...}</cell>
<cell align="left" valign="middle">character with hexadecimal representation; X... is one or more hexadecimal characters</cell>
</row>
<row>
- <cell align="left" valign="middle">\\^a...\\^z <br></br>
-\\^A...\\^Z</cell>
+ <cell align="left" valign="middle">\^a...\^z <br></br>
+\^A...\^Z</cell>
<cell align="left" valign="middle">control A to control Z</cell>
</row>
<row>
- <cell align="left" valign="middle">\\'</cell>
+ <cell align="left" valign="middle">\'</cell>
<cell align="left" valign="middle">single quote</cell>
</row>
<row>
- <cell align="left" valign="middle">\\"</cell>
+ <cell align="left" valign="middle">\"</cell>
<cell align="left" valign="middle">double quote</cell>
</row>
<row>
- <cell align="left" valign="middle">\\\\</cell>
+ <cell align="left" valign="middle">\\</cell>
<cell align="left" valign="middle">backslash</cell>
</row>
<tcaption>Recognized Escape Sequences.</tcaption>
diff --git a/system/doc/reference_manual/macros.xml b/system/doc/reference_manual/macros.xml
index a1ba182eff..9dd5fc79bd 100644
--- a/system/doc/reference_manual/macros.xml
+++ b/system/doc/reference_manual/macros.xml
@@ -4,7 +4,7 @@
<chapter>
<header>
<copyright>
- <year>2003</year><year>2009</year>
+ <year>2003</year><year>2010</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
@@ -13,12 +13,12 @@
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>The Preprocessor</title>
@@ -140,6 +140,38 @@ bar(X) ->
</section>
<section>
+ <title>Macros Overloading</title>
+ <p>It is possible to overload macros, except for predefined
+ macros. An overloaded macro has more than one definition,
+ each with a different number of arguments.</p>
+ <p>The feature was added in Erlang 5.7.5/OTP R13B04.</p>
+ <p>A macro <c>?Func(Arg1,...,ArgN)</c> with a (possibly empty)
+ list of arguments results in an error message if there is at
+ least one definition of <c>Func</c> with arguments, but none
+ with N arguments.</p>
+ <p>Assuming these definitions:</p>
+ <code type="none">
+-define(F0(), c).
+-define(F1(A), A).
+-define(C, m:f).</code>
+ <p>the following will not work:</p>
+ <code type="none">
+f0() ->
+ ?F0. % No, an empty list of arguments expected.
+
+f1(A) ->
+ ?F1(A, A). % No, exactly one argument expected.</code>
+ <p>On the other hand,</p>
+ <code>
+f() ->
+ ?C().</code>
+ <p>will expand to</p>
+ <code>
+f() ->
+ m:f().</code>
+ </section>
+
+ <section>
<title>Flow Control in Macros</title>
<p>The following macro directives are supplied:</p>
<taglist>
diff --git a/system/doc/reference_manual/modules.xml b/system/doc/reference_manual/modules.xml
index 8b14ca3459..0dbc0ab56b 100644
--- a/system/doc/reference_manual/modules.xml
+++ b/system/doc/reference_manual/modules.xml
@@ -4,7 +4,7 @@
<chapter>
<header>
<copyright>
- <year>2003</year><year>2009</year>
+ <year>2003</year><year>2010</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
@@ -13,12 +13,12 @@
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>Modules</title>
@@ -167,6 +167,25 @@ fact(0) -> % |
the original user-written file from which the source program
was produced.</p>
</section>
+
+ <section>
+ <title>Types and function specifications</title>
+ <p>A similar syntax as for module attributes is used for
+ specifying types and function specifications.
+ </p>
+ <pre>
+-type my_type() :: atom() | integer().
+-spec my_function(integer()) -> integer().
+ </pre>
+ <p>Read more in <seealso marker="typespec">Types and Function specifications</seealso>.
+ </p>
+ <p>
+ The desciption is based on
+ <url href="http://www.erlang.org/eeps/eep-0008.html">EEP8 -
+ Types and function specifications</url>
+ which will not be further updated.
+ </p>
+ </section>
</section>
<section>
diff --git a/system/doc/reference_manual/part.xml b/system/doc/reference_manual/part.xml
index aebeaf335a..8151f4c4e1 100644
--- a/system/doc/reference_manual/part.xml
+++ b/system/doc/reference_manual/part.xml
@@ -4,7 +4,7 @@
<part xmlns:xi="http://www.w3.org/2001/XInclude">
<header>
<copyright>
- <year>2003</year><year>2009</year>
+ <year>2003</year><year>2010</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
@@ -13,12 +13,12 @@
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>Erlang Reference Manual</title>
@@ -32,6 +32,7 @@
<xi:include href="patterns.xml"/>
<xi:include href="modules.xml"/>
<xi:include href="functions.xml"/>
+ <xi:include href="typespec.xml"/>
<xi:include href="expressions.xml"/>
<xi:include href="macros.xml"/>
<xi:include href="records.xml"/>
diff --git a/system/doc/reference_manual/typespec.xml b/system/doc/reference_manual/typespec.xml
new file mode 100755
index 0000000000..a3660713e4
--- /dev/null
+++ b/system/doc/reference_manual/typespec.xml
@@ -0,0 +1,464 @@
+<?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>Types and Function Specifications</title>
+ <prepared>Kostis Sagonas, Tobias Lindahl, Kenneth Lundin</prepared>
+ <docno></docno>
+ <date></date>
+ <rev></rev>
+ <file>typespec.xml</file>
+ </header>
+
+ <section>
+ <title>Introduction of Types</title>
+ <p>
+ Although Erlang is a dynamically typed language this section describes
+ an extension to the Erlang language for declaring sets of Erlang terms
+ to form a particular type, effectively forming a specific sub-type of the
+ set of all Erlang terms.
+ </p>
+ <p>
+ Subsequently, these types can be used to specify types of record fields
+ and the argument and return types of functions.
+ </p>
+ <p>
+ Type information can be used to document function interfaces,
+ provide more information for bug detection tools such as <c>Dialyzer</c>,
+ and can be exploited by documentation tools such as <c>Edoc</c> for
+ generating program documentation of various forms.
+ It is expected that the type language described in this document will
+ supersede and replace the purely comment-based <c>@type</c> and
+ <c>@spec</c> declarations used by <c>Edoc</c>.
+ </p>
+ <warning>
+ The syntax and semantics described here is still preliminary and might be
+ slightly changed and extended before it becomes officially supported.
+ The plan is that this will happen in R14B.
+ </warning>
+ </section>
+ <section>
+ <marker id="syntax"></marker>
+ <title>Types and their Syntax</title>
+ <p>
+ Types describe sets of Erlang terms.
+ Types consist and are built from a set of predefined types (e.g. <c>integer()</c>,
+ <c>atom()</c>, <c>pid()</c>, ...) described below.
+ Predefined types represent a typically infinite set of Erlang terms which
+ belong to this type.
+ For example, the type <c>atom()</c> stands for the set of all Erlang atoms.
+ </p>
+ <p>
+ For integers and atoms, we allow for singleton types (e.g. the integers <c>-1</c>
+ and <c>42</c> or the atoms <c>'foo'</c> and <c>'bar'</c>).
+
+ All other types are built using unions of either predefined types or singleton
+ types. In a type union between a type and one of its sub-types the sub-type is
+ absorbed by the super-type and the union is subsequently treated as if the
+ sub-type was not a constituent of the union. For example, the type union:
+ </p>
+ <pre>
+ atom() | 'bar' | integer() | 42</pre>
+ <p>
+ describes the same set of terms as the type union:
+ </p>
+ <pre>
+atom() | integer()</pre>
+ <p>
+ Because of sub-type relations that exist between types, types form a lattice
+ where the topmost element, any(), denotes the set of all Erlang terms and
+ the bottom-most element, none(), denotes the empty set of terms.
+ </p>
+ <p>
+ The set of predefined types and the syntax for types is given below:
+ </p>
+ <pre><![CDATA[
+Type :: any() %% The top type, the set of all Erlang terms.
+ | none() %% The bottom type, contains no terms.
+ | pid()
+ | port()
+ | ref()
+ | [] %% nil
+ | Atom
+ | Binary
+ | float()
+ | Fun
+ | Integer
+ | List
+ | Tuple
+ | Union
+ | UserDefined %% described in Section 2
+
+Union :: Type1 | Type2
+
+Atom :: atom()
+ | Erlang_Atom %% 'foo', 'bar', ...
+
+Binary :: binary() %% <<_:_ * 8>>
+ | <<>>
+ | <<_:Erlang_Integer>> %% Base size
+ | <<_:_*Erlang_Integer>> %% Unit size
+ | <<_:Erlang_Integer, _:_*Erlang_Integer>>
+
+Fun :: fun() %% any function
+ | fun((...) -> Type) %% any arity, returning Type
+ | fun(() -> Type)
+ | fun((TList) -> Type)
+
+Integer :: integer()
+ | Erlang_Integer %% ..., -1, 0, 1, ... 42 ...
+ | Erlang_Integer..Erlang_Integer %% specifies an integer range
+
+List :: list(Type) %% Proper list ([]-terminated)
+ | improper_list(Type1, Type2) %% Type1=contents, Type2=termination
+ | maybe_improper_list(Type1, Type2) %% Type1 and Type2 as above
+
+Tuple :: tuple() %% stands for a tuple of any size
+ | {}
+ | {TList}
+
+TList :: Type
+ | Type, TList
+]]></pre>
+ <p>
+ Because lists are commonly used, they have shorthand type notations.
+ The type <c>list(T)</c> has the shorthand <c>[T]</c>. The shorthand <c>[T,...]</c> stands for
+ the set of non-empty proper lists whose elements are of type <c>T</c>.
+ The only difference between the two shorthands is that <c>[T]</c> may be an
+ empty list but <c>[T,...]</c> may not.
+ </p>
+ <p>
+ Notice that the shorthand for <c>list()</c>, i.e. the list of elements of unknown type,
+ is <c>[_]</c> (or <c>[any()]</c>), not <c>[]</c>.
+ The notation <c>[]</c> specifies the singleton type for the empty list.
+ </p>
+ <p>
+ For convenience, the following types are also built-in.
+ They can be thought as predefined aliases for the type unions also shown in
+ the table. (Some type unions below slightly abuse the syntax of types.)
+ </p>
+ <table>
+ <row>
+ <cell><b>Built-in type</b></cell><cell><b>Stands for</b></cell>
+ </row>
+ <row>
+ <cell><c>term()</c></cell><cell><c>any()</c></cell>
+ </row>
+ <row>
+ <cell><c>bool()</c></cell><cell><c>'false' | 'true'</c></cell>
+ </row>
+ <row>
+ <cell><c>byte()</c></cell><cell><c>0..255</c></cell>
+ </row>
+ <row>
+ <cell><c>char()</c></cell><cell><c>0..16#10ffff</c></cell>
+ </row>
+ <row>
+ <cell><c>non_neg_integer()</c></cell><cell><c>0..</c></cell>
+ </row>
+ <row>
+ <cell><c>pos_integer()</c></cell><cell><c>1..</c></cell>
+ </row>
+ <row>
+ <cell><c>neg_integer()</c></cell><cell><c>..-1</c></cell>
+ </row>
+ <row>
+ <cell><c>number()</c></cell><cell><c>integer() | float()</c></cell>
+ </row>
+ <row>
+ <cell><c>list()</c></cell><cell><c>[any()]</c></cell>
+ </row>
+ <row>
+ <cell><c>maybe_improper_list()</c></cell><cell><c>maybe_improper_list(any(), any())</c></cell>
+ </row>
+ <row>
+ <cell><c>maybe_improper_list(T)</c></cell><cell><c>maybe_improper_list(T, any())</c></cell>
+ </row>
+ <row>
+ <cell><c>string()</c></cell><cell><c>[char()]</c></cell>
+ </row>
+ <row>
+ <cell><c>nonempty_string()</c></cell><cell><c>[char(),...]</c></cell>
+ </row>
+ <row>
+ <cell><c>iolist()</c></cell><cell><c>maybe_improper_list(
+char() | binary() | iolist(), binary() | [])</c></cell>
+ </row>
+ <row>
+ <cell><c>module()</c></cell><cell><c>atom()</c></cell>
+ </row>
+ <row>
+ <cell><c>mfa()</c></cell><cell><c>{atom(),atom(),byte()}</c></cell>
+ </row>
+ <row>
+ <cell><c>node()</c></cell><cell><c>atom()</c></cell>
+ </row>
+ <row>
+ <cell><c>timeout()</c></cell><cell><c>'infinity' | non_neg_integer()</c></cell>
+ </row>
+ <row>
+ <cell><c>no_return()</c></cell><cell><c>none()</c></cell>
+ </row>
+ </table>
+
+ <p>
+ Users are not allowed to define types with the same names as the predefined or
+ built-in ones.
+ This is checked by the compiler and its violation results in a compilation
+ error.
+ (For bootstrapping purposes, it can also result to just a warning if this
+ involves a built-in type which has just been introduced.)
+ </p>
+ <note>
+ The following built-in list types also exist,
+ but they are expected to be rarely used. Hence, they have long names:
+ </note>
+ <pre>
+nonempty_maybe_improper_list(Type) :: nonempty_maybe_improper_list(Type, any())
+nonempty_maybe_improper_list() :: nonempty_maybe_improper_list(any())
+ </pre>
+ <p>
+ where the following two types
+ define the set of Erlang terms one would expect:
+ </p>
+ <pre>
+nonempty_improper_list(Type1, Type2)
+nonempty_maybe_improper_list(Type1, Type2)
+ </pre>
+ <p>
+ Also for convenience, we allow for record notation to be used.
+ Records are just shorthands for the corresponding tuples.
+ </p>
+ <pre>
+Record :: #Erlang_Atom{}
+ | #Erlang_Atom{Fields}
+ </pre>
+ <p>
+ Records have been extended to possibly contain type information.
+ This is described in the sub-section <seealso marker="#typeinrecords">"Type information in record declarations"</seealso> below.
+ </p>
+ </section>
+
+ <section>
+ <title>Type declarations of user-defined types</title>
+ <p>
+ As seen, the basic syntax of a type is an atom followed by closed
+ parentheses. New types are declared using '-type' compiler attributes
+ as in the following:
+ </p>
+ <pre>
+-type my_type() :: Type.
+ </pre>
+ <p>
+ where the type name is an atom (<c>'my_type'</c> in the above) followed by
+ parenthesis. Type is a type as defined in the previous section.
+ A current restriction is that Type can contain only predefined types
+ or user-defined types which have been previously defined.
+ This restriction is enforced by the compiler and results in a
+ compilation error. (A similar restriction currently exists for records).
+ </p>
+ <p>
+ This means that currently general recursive types cannot be defined.
+ Lifting this restriction is future work.
+ </p>
+ <p>
+ Type declarations can also be parameterized by including type variables
+ between the parentheses. The syntax of type variables is the same as
+ Erlang variables (starts with an upper case letter).
+ Naturally, these variables can - and should - appear on the RHS of the
+ definition. A concrete example appears below:
+ </p>
+ <pre>
+-type orddict(Key, Val) :: [{Key, Val}].
+ </pre>
+
+ </section>
+
+ <marker id="typeinrecords"/>
+ <section>
+ <title>
+ Type information in record declarations
+ </title>
+ <p>
+ The types of record fields can be specified in the declaration of the
+ record. The syntax for this is:
+ </p>
+ <pre>
+-record(rec, {field1 :: Type1, field2, field3 :: Type3}).
+ </pre>
+ <p>
+ For fields without type annotations, their type defaults to any().
+ I.e., the above is a shorthand for:
+ </p>
+ <pre>
+-record(rec, {field1 :: Type1, field2 :: any(), field3 :: Type3}).
+ </pre>
+ <p>
+ In the presence of initial values for fields,
+ the type must be declared after the initialization as in the following:
+ </p>
+ <pre>
+-record(rec, {field1 = [] :: Type1, field2, field3 = 42 :: Type3}).
+ </pre>
+ <p>
+ Naturally, the initial values for fields should be compatible
+ with (i.e. a member of) the corresponding types.
+ This is checked by the compiler and results in a compilation error
+ if a violation is detected. For fields without initial values,
+ the singleton type <c>'undefined'</c> is added to all declared types.
+ In other words, the following two record declarations have identical
+ effects:
+ </p>
+ <pre>
+-record(rec, {f1 = 42 :: integer(),
+ f2 :: float(),
+ f3 :: 'a' | 'b').
+
+-record(rec, {f1 = 42 :: integer(),
+ f2 :: 'undefined' | float(),
+ f3 :: 'undefined' | 'a' | 'b').
+ </pre>
+ <p>
+ For this reason, it is recommended that records contain initializers,
+ whenever possible.
+ </p>
+ <p>
+ Any record, containing type information or not, once defined,
+ can be used as a type using the syntax:
+ </p>
+ <pre>
+#rec{}
+ </pre>
+ <p>
+ In addition, the record fields can be further specified when using
+ a record type by adding type information about the field in the following
+ manner:
+ </p>
+ <pre>
+#rec{some_field :: Type}
+ </pre>
+ <p>
+ Any unspecified fields are assumed to have the type in the original
+ record declaration.
+ </p>
+ </section>
+
+ <section>
+ <title>Specifications (contracts) for functions</title>
+ <p>
+ A contract (or specification) for a function is given using the new
+ compiler attribute <c>'-spec'</c>. The basic format is as follows:
+ </p>
+ <pre>
+-spec Module:Function(ArgType1, ..., ArgTypeN) -> ReturnType.
+ </pre>
+ <p>
+ The arity of the function has to match the number of arguments,
+ or else a compilation error occurs.
+ </p>
+ <p>
+ This form can also be used in header files (.hrl) to declare type
+ information for exported functions.
+ Then these header files can be included in files that (implicitly or
+ explicitly) import these functions.
+ </p>
+ <p>
+ For most uses within a given module, the following shorthand is allowed:
+ </p>
+ <pre>
+-spec Function(ArgType1, ..., ArgTypeN) -> ReturnType.
+ </pre>
+ <p>
+ Also, for documentation purposes, argument names can be given:
+ </p>
+ <pre>
+-spec Function(ArgName1 :: Type1, ..., ArgNameN :: TypeN) -> RT.
+ </pre>
+ <p>
+ A function specification can be overloaded.
+ That is, it can have several types, separated by a semicolon (<c>;</c>):
+ </p>
+ <pre>
+-spec foo(T1, T2) -> T3
+ ; (T4, T5) -> T6.
+ </pre>
+ <p>
+ A current restriction, which currently results in a warning
+ (OBS: not an error) by the compiler, is that the domains of the argument
+ types cannot be overlapping.
+ For example, the following specification results in a warning:
+ </p>
+ <pre>
+-spec foo(pos_integer()) -> pos_integer()
+ ; (integer()) -> integer().
+ </pre>
+ <p>
+ Type variables can be used in specifications to specify relations for
+ the input and output arguments of a function.
+ For example, the following specification defines the type of a
+ polymorphic identity function:
+ </p>
+ <pre>
+-spec id(X) -> X.
+ </pre>
+ <p>
+ However, note that the above specification does not restrict the input
+ and output type in any way.
+ We can constrain these types by guard-like subtype constraints:
+ </p>
+ <pre>
+-spec id(X) -> X when is_subtype(X, tuple()).
+ </pre>
+ <p>
+ and provide bounded quantification. Currently,
+ the <c>is_subtype/2</c> guard is the only guard which can
+ be used in a <c>'-spec'</c> attribute.
+ </p>
+ <p>
+ The scope of an <c>is_subtype/2</c> constraint is the
+ <c>(...) -> RetType</c>
+ specification after which it appears. To avoid confusion,
+ we suggest that different variables are used in different constituents of
+ an overloaded contract as in the example below:
+ </p>
+ <pre>
+-spec foo({X, integer()}) -> X when is_subtype(X, atom())
+ ; ([Y]) -> Y when is_subtype(Y, number()).
+ </pre>
+ <p>
+ Some functions in Erlang are not meant to return;
+ either because they define servers or because they are used to
+ throw exceptions as the function below:
+ </p>
+ <pre>
+my_error(Err) -> erlang:throw({error, Err}).
+ </pre>
+ <p>
+ For such functions we recommend the use of the special no_return()
+ type for their "return", via a contract of the form:
+ </p>
+ <pre>
+-spec my_error(term()) -> no_return().
+ </pre>
+ </section>
+</chapter>
+
diff --git a/system/doc/system_principles/create_target.xml b/system/doc/system_principles/create_target.xml
index 9899b6e266..7d9f4681b9 100644
--- a/system/doc/system_principles/create_target.xml
+++ b/system/doc/system_principles/create_target.xml
@@ -259,9 +259,9 @@ os> <input>/usr/local/erl-target/bin/erl -boot /usr/local/erl-target/releases/FI
%%
create(RelFileName) ->
RelFile = RelFileName ++ ".rel",
- io:fwrite("Reading file: \\"~s\\" ...~n", [RelFile]),
+ io:fwrite("Reading file: \"~s\" ...~n", [RelFile]),
{ok, [RelSpec]} = file:consult(RelFile),
- io:fwrite("Creating file: \\"~s\\" from \\"~s\\" ...~n",
+ io:fwrite("Creating file: \"~s\" from \"~s\" ...~n",
["plain.rel", RelFile]),
{release,
{RelName, RelVsn},
@@ -282,40 +282,39 @@ create(RelFileName) ->
io:fwrite(Fd, "~p.~n", [PlainRelSpec]),
file:close(Fd),
- io:fwrite("Making \\"plain.script\\" and \\"plain.boot\\" files ...~n"),
+ io:fwrite("Making \"plain.script\" and \"plain.boot\" files ...~n"),
make_script("plain"),
- io:fwrite("Making \\"~s.script\\" and \\"~s.boot\\" files ...~n",
+ io:fwrite("Making \"~s.script\" and \"~s.boot\" files ...~n",
[RelFileName, RelFileName]),
make_script(RelFileName),
TarFileName = io_lib:fwrite("~s.tar.gz", [RelFileName]),
- io:fwrite("Creating tar file \\"~s\\" ...~n", [TarFileName]),
+ io:fwrite("Creating tar file \"~s\" ...~n", [TarFileName]),
make_tar(RelFileName),
- io:fwrite("Creating directory \\"tmp\\" ...~n"),
+ io:fwrite("Creating directory \"tmp\" ...~n"),
file:make_dir("tmp"),
- io:fwrite("Extracting \\"~s\\" into directory \\"tmp\\" ...~n", [TarFileName]),
+ io:fwrite("Extracting \"~s\" into directory \"tmp\" ...~n", [TarFileName]),
extract_tar(TarFileName, "tmp"),
TmpBinDir = filename:join(["tmp", "bin"]),
ErtsBinDir = filename:join(["tmp", "erts-" ++ ErtsVsn, "bin"]),
- io:fwrite("Deleting \\"erl\\" and \\"start\\" in directory \\"~s\\" ...~n",
+ io:fwrite("Deleting \"erl\" and \"start\" in directory \"~s\" ...~n",
[ErtsBinDir]),
file:delete(filename:join([ErtsBinDir, "erl"])),
file:delete(filename:join([ErtsBinDir, "start"])),
- io:fwrite("Creating temporary directory \\"~s\\" ...~n", [TmpBinDir]),
+ io:fwrite("Creating temporary directory \"~s\" ...~n", [TmpBinDir]),
file:make_dir(TmpBinDir),
- io:fwrite("Copying file \\"plain.boot\\" to \\"~s\\" ...~n",
+ io:fwrite("Copying file \"plain.boot\" to \"~s\" ...~n",
[filename:join([TmpBinDir, "start.boot"])]),
copy_file("plain.boot", filename:join([TmpBinDir, "start.boot"])),
- io:fwrite("Copying files \\"epmd\\", \\"run_erl\\" and \\"to_erl\\" from \
-"
- "\\"~s\\" to \\"~s\\" ...~n",
+ io:fwrite("Copying files \"epmd\", \"run_erl\" and \"to_erl\" from \n"
+ "\"~s\" to \"~s\" ...~n",
[ErtsBinDir, TmpBinDir]),
copy_file(filename:join([ErtsBinDir, "epmd"]),
filename:join([TmpBinDir, "epmd"]), [preserve]),
@@ -325,12 +324,12 @@ create(RelFileName) ->
filename:join([TmpBinDir, "to_erl"]), [preserve]),
StartErlDataFile = filename:join(["tmp", "releases", "start_erl.data"]),
- io:fwrite("Creating \\"~s\\" ...~n", [StartErlDataFile]),
+ io:fwrite("Creating \"~s\" ...~n", [StartErlDataFile]),
StartErlData = io_lib:fwrite("~s ~s~n", [ErtsVsn, RelVsn]),
write_file(StartErlDataFile, StartErlData),
- io:fwrite("Recreating tar file \\"~s\\" from contents in directory "
- "\\"tmp\\" ...~n", [TarFileName]),
+ io:fwrite("Recreating tar file \"~s\" from contents in directory "
+ "\"tmp\" ...~n", [TarFileName]),
{ok, Tar} = erl_tar:open(TarFileName, [write, compressed]),
{ok, Cwd} = file:get_cwd(),
file:set_cwd("tmp"),
@@ -340,7 +339,7 @@ create(RelFileName) ->
erl_tar:add(Tar, "lib", []),
erl_tar:close(Tar),
file:set_cwd(Cwd),
- io:fwrite("Removing directory \\"tmp\\" ...~n"),
+ io:fwrite("Removing directory \"tmp\" ...~n"),
remove_dir_tree("tmp"),
ok.
@@ -351,19 +350,15 @@ install(RelFileName, RootDir) ->
extract_tar(TarFile, RootDir),
StartErlDataFile = filename:join([RootDir, "releases", "start_erl.data"]),
{ok, StartErlData} = read_txt_file(StartErlDataFile),
- [ErlVsn, RelVsn| _] = string:tokens(StartErlData, " \
-"),
+ [ErlVsn, RelVsn| _] = string:tokens(StartErlData, " \n"),
ErtsBinDir = filename:join([RootDir, "erts-" ++ ErlVsn, "bin"]),
BinDir = filename:join([RootDir, "bin"]),
- io:fwrite("Substituting in erl.src, start.src and start_erl.src to\
-"
- "form erl, start and start_erl ...\
-"),
+ io:fwrite("Substituting in erl.src, start.src and start_erl.src to\n"
+ "form erl, start and start_erl ...\n"),
subst_src_scripts(["erl", "start", "start_erl"], ErtsBinDir, BinDir,
[{"FINAL_ROOTDIR", RootDir}, {"EMU", "beam"}],
[preserve]),
- io:fwrite("Creating the RELEASES file ...\
-"),
+ io:fwrite("Creating the RELEASES file ...\n"),
create_RELEASES(RootDir,
filename:join([RootDir, "releases", RelFileName])).
diff --git a/system/doc/top/Makefile b/system/doc/top/Makefile
index 08fe265336..154deb006b 100644
--- a/system/doc/top/Makefile
+++ b/system/doc/top/Makefile
@@ -1,19 +1,19 @@
#
# %CopyrightBegin%
-#
-# Copyright Ericsson AB 1999-2009. All Rights Reserved.
-#
+#
+# Copyright Ericsson AB 1999-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%
#
#
@@ -103,7 +103,8 @@ JAVASCRIPT = $(HTMLDIR)/js/erlresolvelinks.js
JAVASCRIPT_BUILD_SCRIPT = $(EBIN)/erlresolvelinks.$(EMULATOR)
JAVASCRIPT_BUILD_SCRIPT_SRC = src/erlresolvelinks.erl
-MAN_INDEX_SCRIPT = $(ERL_TOP)/system/doc/top/bin/otp_man_index
+MAN_INDEX_SCRIPT = $(EBIN)/otp_man_index.$(EMULATOR)
+MAN_INDEX_SRC = src/otp_man_index.erl
MAN_INDEX = $(HTMLDIR)/man_index.html
GLOSSARY = $(HTMLDIR)/glossary.html
@@ -116,14 +117,11 @@ $(INDEX_SCRIPT): $(INDEX_SRC)
$(ERLC) -o$(EBIN) +warn_unused_vars $<
# We don't list toc_*.html as targets because we don't know
-$(HTMLDIR)/index.html: $(INDEX_SCRIPT)
-ifneq ($(INSTALLROOT),)
+$(HTMLDIR)/index.html + $(HTMLDIR)/applications.html: $(INDEX_SCRIPT)
echo "Generating index $@"
- $(ERL) -noshell -pa $(EBIN) -s erl_html_tools top_index $(INSTALLROOT) \
+ $(ERL) -noshell -pa $(EBIN) -s erl_html_tools top_index $(ERL_TOP) \
$(HTMLDIR) $(SYSTEM_VSN) -s erlang halt
-else
- @echo "INSTALLROOT unset, no indexes built."
-endif
+
#--------------------------------------------------------------------------
@@ -131,25 +129,19 @@ $(JAVASCRIPT_BUILD_SCRIPT): $(JAVASCRIPT_BUILD_SCRIPT_SRC)
$(ERLC) -o$(EBIN) +warn_unused_vars $<
$(JAVASCRIPT): $(JAVASCRIPT_BUILD_SCRIPT)
-ifneq ($(INSTALLROOT),)
- echo "Generating javascript for resolving HTML links"
- erl -noshell -pa $(EBIN) -s erlresolvelinks make $(INSTALLROOT) \
- . -s erlang halt
- mkdir $(HTMLDIR)/js
- mv erlresolvelinks.js $(JAVASCRIPT) # not portable !!!
-else
- @echo "INSTALLROOT unset, no javascript generated."
-endif
+ erl -noshell -pa $(EBIN) -s erlresolvelinks make -s erlang halt
+ $(INSTALL_DIR) $(HTMLDIR)/js
+ $(INSTALL_DATA) erlresolvelinks.js $(JAVASCRIPT)
#--------------------------------------------------------------------------
+$(MAN_INDEX_SCRIPT): $(MAN_INDEX_SRC)
+ $(ERLC) -o$(EBIN) +warn_unused_vars $<
+
$(MAN_INDEX): $(MAN_INDEX_SCRIPT)
-ifneq ($(INSTALLROOT),)
- echo "Generating index $@"
- (cd $(INSTALLROOT); perl $< ) > $@
-else
- @echo "INSTALLROOT unset, no manual index built."
-endif
+ $(ERL) -noshell -pa $(EBIN) -s otp_man_index gen $(ERL_TOP) $@ \
+ -s erlang halt
+
#--------------------------------------------------------------------------
$(HTMLDIR)/highlights.html: highlights.xml
@@ -230,13 +222,11 @@ release_docs_spec: docs
$(INSTALL_DIR) $(RELSYSDIR)/pdf
$(INSTALL_DATA) \
$(TOP_PDF_FILE) $(RELSYSDIR)/pdf
-#$(TOP_HTML_FILES)
-ifneq ($(INSTALLROOT),)
- $(INSTALL_DATA) $(INDEX_FILES) $(MAN_INDEX) $(TOP_HTML_FILES) $(RELSYSDIR)
+ $(INSTALL_DATA) $(TOP_HTML_FILES) $(RELSYSDIR)
$(INSTALL_DIR) $(RELSYSDIR)/js
$(INSTALL_DATA) \
$(JAVASCRIPT) $(RELSYSDIR)/js
-endif
+ $(INSTALL_DATA) $(INDEX_FILES) $(MAN_INDEX) $(TOP_HTML_FILES) $(RELSYSDIR)
release_spec:
diff --git a/system/doc/top/bin/.gitignore b/system/doc/top/bin/.gitignore
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/system/doc/top/bin/.gitignore
diff --git a/system/doc/top/bin/otp_man_index b/system/doc/top/bin/otp_man_index
deleted file mode 120000
index bb913b25df..0000000000
--- a/system/doc/top/bin/otp_man_index
+++ /dev/null
@@ -1 +0,0 @@
-../../../../internal_tools/integration/scripts/otp_man_index \ No newline at end of file
diff --git a/system/doc/top/src/erl_html_tools.erl b/system/doc/top/src/erl_html_tools.erl
index 35a199b08d..c920245f94 120000..100644
--- a/system/doc/top/src/erl_html_tools.erl
+++ b/system/doc/top/src/erl_html_tools.erl
@@ -1 +1,686 @@
-../../../../internal_tools/integration/scripts/make_index/erl_html_tools.erl \ No newline at end of file
+%%--------------------------------------------------------------------
+%%
+%% %CopyrightBegin%
+%%
+%% 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%
+%%
+%%-----------------------------------------------------------------
+%% File: erl_html_tools.erl
+%%
+%% Description:
+%% This file generates the top index of the documentation.
+%%
+%%-----------------------------------------------------------------
+-module(erl_html_tools).
+
+-export([top_index/0,top_index/1,top_index/3,top_index_silent/3]).
+
+-include_lib("kernel/include/file.hrl").
+
+group_order() ->
+ [
+ {basic, "Basic"},
+ {dat, "Database"},
+ {oam, "Operation & Maintenance"},
+ {comm, "Interface and Communication"},
+ {tools, "Tools"},
+ {test, "Test"},
+ {doc, "Documentation"},
+ {orb, "Object Request Broker & IDL"},
+ {misc, "Miscellaneous"}
+ ].
+
+top_index() ->
+ case os:getenv("ERL_TOP") of
+ false ->
+ io:format("Variable ERL_TOP is required\n",[]);
+ Value ->
+ {_,RelName} = init:script_id(),
+ top_index(Value, filename:join(Value, "doc"), RelName)
+ end.
+
+top_index([RootDir, DestDir, OtpRel])
+ when is_atom(RootDir), is_atom(DestDir), is_atom(OtpRel) ->
+ top_index(atom_to_list(RootDir), atom_to_list(DestDir), atom_to_list(OtpRel));
+top_index(RootDir) when is_atom(RootDir) ->
+ {_,RelName} = init:script_id(),
+ top_index(RootDir, filename:join(RootDir, "doc"), RelName).
+
+
+
+top_index(RootDir, DestDir, OtpRel) ->
+ report("****\nRootDir: ~p", [RootDir]),
+ report("****\nDestDir: ~p", [DestDir]),
+ report("****\nOtpRel: ~p", [OtpRel]),
+
+ put(otp_release, OtpRel),
+
+ Templates = find_templates(["","templates",DestDir]),
+ report("****\nTemplates: ~p", [Templates]),
+ Bases = [{"../lib/", filename:join(RootDir,"lib")},
+ {"../", RootDir}],
+ Groups = find_information(Bases),
+ report("****\nGroups: ~p", [Groups]),
+ process_templates(Templates, DestDir, Groups).
+
+top_index_silent(RootDir, DestDir, OtpRel) ->
+ put(silent,true),
+ Result = top_index(RootDir, DestDir, OtpRel),
+ erase(silent),
+ Result.
+
+
+
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% Main loop - process templates
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+process_templates([], _DestDir, _Groups) ->
+ report("\n", []);
+process_templates([Template | Templates], DestDir, Groups) ->
+ report("****\nIN-FILE: ~s", [Template]),
+ BaseName = filename:basename(Template, ".src"),
+ case lists:reverse(filename:rootname(BaseName)) of
+ "_"++_ ->
+ %% One template expands to several output files.
+ process_multi_template(BaseName, Template, DestDir, Groups);
+ _ ->
+ %% Standard one-to-one template.
+ OutFile = filename:join(DestDir, BaseName),
+ subst_file("", OutFile, Template, Groups)
+ end,
+ process_templates(Templates, DestDir, Groups).
+
+
+process_multi_template(BaseName0, Template, DestDir, Info) ->
+ Ext = filename:extension(BaseName0),
+ BaseName1 = filename:basename(BaseName0, Ext),
+ [_|BaseName2] = lists:reverse(BaseName1),
+ BaseName = lists:reverse(BaseName2),
+ Groups0 = [{[$_|atom_to_list(G)],G} || {G, _} <- group_order()],
+ Groups = [{"",basic}|Groups0],
+ process_multi_template_1(Groups, BaseName, Ext, Template, DestDir, Info).
+
+process_multi_template_1([{Suffix,Group}|Gs], BaseName, Ext, Template, DestDir, Info) ->
+ OutFile = filename:join(DestDir, BaseName++Suffix++Ext),
+ subst_file(Group, OutFile, Template, Info),
+ process_multi_template_1(Gs, BaseName, Ext, Template, DestDir, Info);
+process_multi_template_1([], _, _, _, _, _) -> ok.
+
+subst_file(Group, OutFile, Template, Info) ->
+ report("\nOUTFILE: ~s", [OutFile]),
+ case subst_template(Group, Template, Info) of
+ {ok,Text,_NewInfo} ->
+ case file:open(OutFile, [write]) of
+ {ok, Stream} ->
+ file:write(Stream, Text),
+ file:close(Stream);
+ Error ->
+ error("Can't write to file ~s: ~w", [OutFile,Error])
+ end;
+ Error ->
+ error("Can't write to file ~s: ~w", [OutFile,Error])
+ end.
+
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% Find the templates
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+find_templates(SearchPaths) ->
+ find_templates(SearchPaths, SearchPaths).
+
+find_templates([SearchPath | SearchPaths], AllSearchPaths) ->
+ case filelib:wildcard(filename:join(SearchPath, "*.html.src")) of
+ [] ->
+ find_templates(SearchPaths, AllSearchPaths);
+ Result ->
+ Result
+ end;
+find_templates([], AllSearchPaths) ->
+ error("No templates found in ~p",[AllSearchPaths]).
+
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% This function read all application names and if present all "info" files.
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+find_information(Bases) ->
+ Paths = find_application_paths(Bases),
+% report("****\nPaths: ~p", [Paths]),
+ Apps = find_application_infos(Paths),
+% report("****\nApps: ~p", [Apps]),
+ form_groups(Apps).
+
+% The input is a list of tuples of the form
+%
+% IN: [{BaseURL,SearchDir}, ...]
+%
+% and the output is a list
+%
+% OUT: [{Appname,AppVersion,AppPath,IndexUTL}, ...]
+%
+% We know URL ends in a slash.
+
+find_application_paths([]) ->
+ [];
+find_application_paths([{URL, Dir} | Paths]) ->
+ Sub1 = "doc/html/index.html",
+%% Sub2 = "doc/index.html",
+
+ AppDirs = get_app_dirs(Dir),
+
+ AppPaths =
+ lists:map(
+ fun({App, AppPath}) ->
+ VsnFile = filename:join(AppPath, "vsn.mk"),
+ VsnStr =
+ case file:read_file(VsnFile) of
+ {ok, Bin} ->
+ case re:run(Bin, ".*VSN\s*=\s*([0-9\.]+).*",[{capture,[1],list}]) of
+ {match, [V]} ->
+ V;
+ nomatch ->
+ exit(io_lib:format("No VSN variable found in ~s\n",
+ [VsnFile]))
+ end;
+ {error, Reason} ->
+ exit(io_lib:format("~p : ~s\n", [Reason, VsnFile]))
+ end,
+ AppURL = URL ++ App ++ "-" ++ VsnStr,
+ {App, VsnStr, AppPath, AppURL ++ "/" ++ Sub1}
+ end, AppDirs),
+ AppPaths ++ find_application_paths(Paths).
+
+get_app_dirs(Dir) ->
+ {ok, Files} = file:list_dir(Dir),
+ AFiles =
+ lists:map(fun(File) -> {File, filename:join([Dir, File])} end, Files),
+ lists:zf(fun is_app_with_doc/1, AFiles).
+
+is_app_with_doc({"." ++ ADir, _APath}) ->
+ false;
+is_app_with_doc({ADir, APath}) ->
+ case file:read_file_info(filename:join([APath, "info"])) of
+ {ok, _FileInfo} ->
+ {true, {ADir, APath}};
+ _ ->
+ false
+ end.
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% Find info for one application.
+% Read the "info" file for each application. Look at "group" and "short".
+% key words.
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+% IN: [{Appname,AppVersion,AppPath,IndexUTL}, ...]
+% OUT: [{Group,Heading,[{AppName,[{AppVersion,Path,URL,Text} | ...]}
+% | ...]}, ...]
+
+find_application_infos([]) ->
+ [];
+find_application_infos([{App, Vsn, AppPath, IndexURL} | Paths]) ->
+ case read_info(filename:join(AppPath,"info")) of
+ {error,_Reason} ->
+ warning("No info for app ~p", [AppPath]),
+ find_application_infos(Paths);
+ Db ->
+ {Group,_Heading} =
+ case lists:keysearch("group", 1, Db) of
+ {value, {_, G0}} ->
+ % This value may be in two parts,
+ % tag and desciption
+ case string:str(G0, " ") of
+ 0 ->
+ {list_to_atom(G0), ""};
+ N ->
+ {list_to_atom(string:substr(G0,1,N-1)),
+ string:substr(G0,N+1)}
+ end;
+ false ->
+ error("No group given",[])
+ end,
+ Text =
+ case lists:keysearch("short", 1, Db) of
+ {value, {_, G1}} ->
+ G1;
+ false ->
+ ""
+ end,
+%% [{Group, Heading, {App, {Vsn, AppPath, IndexURL, Text}}}
+ [{Group, "", {App, {Vsn, AppPath, IndexURL, Text}}}
+ | find_application_infos(Paths)]
+ end.
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% Group into one list element for each group name.
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+% IN : {Group,Heading,{AppName,{AppVersion,Path,URL,Text}}}
+% OUT: {Group,Heading,[{AppName,[{AppVersion,Path,URL,Text} | ...]} | ...]}
+
+form_groups(Apps) ->
+ group_apps(lists:sort(Apps)).
+
+group_apps([{Group,Heading,AppInfo} | Info]) ->
+ group_apps(Info, Group, Heading, [AppInfo]);
+group_apps([]) ->
+ [].
+
+% First description
+group_apps([{Group,"",AppInfo} | Info], Group, Heading, AppInfos) ->
+ group_apps(Info, Group, Heading, [AppInfo | AppInfos]);
+group_apps([{Group,Heading,AppInfo} | Info], Group, "", AppInfos) ->
+ group_apps(Info, Group, Heading, [AppInfo | AppInfos]);
+% Exact match
+group_apps([{Group,Heading,AppInfo} | Info], Group, Heading, AppInfos) ->
+ group_apps(Info, Group, Heading, [AppInfo | AppInfos]);
+% Different descriptions
+group_apps([{Group,_OtherHeading,AppInfo} | Info], Group, Heading, AppInfos) ->
+ warning("Group ~w descriptions differ",[Group]),
+ group_apps(Info, Group, Heading, [AppInfo | AppInfos]);
+group_apps(Info, Group, Heading, AppInfos) ->
+ [{Group,Heading,combine_apps(AppInfos)} | group_apps(Info)].
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% Group into one list element for each application name.
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+% IN : {AppName,{AppVersion,Path,URL,Text}}
+% OUT: {AppName,[{AppVersion,Path,URL,Text} | ...]}
+
+combine_apps(Apps) ->
+ combine_apps(Apps,[],[]).
+
+combine_apps([{AppName,{Vsn1,Path1,URL1,Text1}},
+ {AppName,{Vsn2,Path2,URL2,Text2}} | Apps], AppAcc, Acc) ->
+ combine_apps([{AppName,{Vsn2,Path2,URL2,Text2}} | Apps],
+ [{Vsn1,Path1,URL1,Text1} | AppAcc],
+ Acc);
+combine_apps([{AppName,{Vsn1,Path1,URL1,Text1}},
+ {NewAppName,{Vsn2,Path2,URL2,Text2}} | Apps], AppAcc, Acc) ->
+ App = lists:sort(fun vsncmp/2,[{Vsn1,Path1,URL1,Text1}|AppAcc]),
+ combine_apps([{NewAppName,{Vsn2,Path2,URL2,Text2}} | Apps],
+ [],
+ [{AppName,App}|Acc]);
+combine_apps([{AppName,{Vsn,Path,URL,Text}}], AppAcc, Acc) ->
+ App = lists:sort(fun vsncmp/2,[{Vsn,Path,URL,Text}|AppAcc]),
+ [{AppName,App}|Acc].
+
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% Open a template and fill in the missing parts
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+% IN : {Group,Heading,[{AppName,[{AppVersion,Path,URL,Text} | ...]} | ...]}
+% OUT: String that is the HTML code
+
+subst_template(Group, File, Info) ->
+ case file:open(File, read) of
+ {ok,Stream} ->
+ Res = subst_template_1(Group, Stream, Info),
+ file:close(Stream),
+ Res;
+ {error,Reason} ->
+ {error, Reason}
+ end.
+
+subst_template_1(Group, Stream, Info) ->
+ case file:read(Stream, 100000) of
+ {ok, Template} ->
+ Fun = fun(Match, _) -> {subst(Match, Info, Group),Info} end,
+ gsub(Template, "#[A-Za-z0-9]+#", Fun, Info);
+ {error, Reason} ->
+ {error, Reason}
+ end.
+
+get_version(Info) ->
+ case lists:keysearch('runtime', 1, Info) of
+ {value, {_,_,Apps}} ->
+ case lists:keysearch("erts", 1, Apps) of
+ {value, {_,[{Vers,_,_,_} | _]}} ->
+ Vers;
+ _ ->
+ ""
+ end;
+ _ ->
+ ""
+ end.
+
+subst("#release#", _Info, _Group) ->
+ get(otp_release);
+subst("#version#", Info, _Group) ->
+ get_version(Info);
+subst("#copyright#", _Info, _Group) ->
+ "copyright Copyright &copy; 1991-2004";
+subst("#groups#", Info, _Group) ->
+ [
+ "<table border=0 width=\"90%\" cellspacing=3 cellpadding=5>\n",
+ subst_groups(Info),
+ "</table>\n"
+ ];
+subst("#applinks#", Info, Group) ->
+ subst_applinks(Info, Group);
+subst(KeyWord, Info, _Group) ->
+ case search_appname(KeyWord -- "##", Info) of
+ {ok,URL} ->
+ URL;
+ _ ->
+ warning("Can't substitute keyword ~s~n",[KeyWord]),
+ ""
+ end.
+
+search_appname(App, [{_Group,_,Apps} | Groups]) ->
+ case lists:keysearch(App, 1, Apps) of
+ {value, {_,[{_Vers,_Path,URL,_Text} | _]}} ->
+ {ok,lists:sublist(URL, length(URL) - length("/index.html"))};
+ _ ->
+ search_appname(App, Groups)
+ end;
+search_appname(_App, []) ->
+ {error, noapp}.
+
+subst_applinks(Info, Group) ->
+ subst_applinks_1(group_order(), Info, Group).
+
+subst_applinks_1([{G, Heading}|Gs], Info0, Group) ->
+ case lists:keysearch(G, 1, Info0) of
+ {value,{G,_Heading,Apps}} ->
+ Info = lists:keydelete(G, 1, Info0),
+ ["\n<li>",Heading, "\n<ul>\n",
+ html_applinks(Apps), "\n</ul></li>\n"|
+ subst_applinks_1(Gs, Info, Group)];
+ false ->
+ warning("No applications in group ~w\n", [G]),
+ subst_applinks_1(Gs, Info0, Group)
+ end;
+subst_applinks_1([], [], _) -> [];
+subst_applinks_1([], Info, _) ->
+ error("Info left: ~p\n", [Info]),
+ [].
+
+html_applinks([{Name,[{_,_,URL,_}|_]}|AppNames]) ->
+ ["<li><a href=\"",URL,"\">",Name,
+ "</a></li>\n"|html_applinks(AppNames)];
+html_applinks([]) -> [].
+
+
+% Info: [{Group,Heading,[{AppName,[{AppVersion,Path,URL,Text} | ..]} | ..]} ..]
+
+subst_groups(Info0) ->
+ {Html1,Info1} = subst_known_groups(group_order(), Info0, ""),
+ {Html2,Info} = subst_unknown_groups(Info1, Html1, []),
+ Fun = fun({_Group,_GText,Applist}, Acc) -> Applist ++ Acc end,
+ case lists:foldl(Fun, [], Info) of
+ [] ->
+ Html2;
+ Apps ->
+ [Html2,group_table("Misc Applications",Apps)]
+ end.
+
+
+subst_known_groups([], Info, Text) ->
+ {Text,Info};
+subst_known_groups([{Group, Heading} | Groups], Info0, Text0) ->
+ case lists:keysearch(Group, 1, Info0) of
+ {value,{_,_Heading,Apps}} ->
+ Text = group_table(Heading,Apps),
+ Info = lists:keydelete(Group, 1, Info0),
+ subst_known_groups(Groups, Info, Text0 ++ Text);
+ false ->
+ warning("No applications in group ~w~n",[Group]),
+ subst_known_groups(Groups, Info0, Text0)
+ end.
+
+
+subst_unknown_groups([], Text0, Left) ->
+ {Text0,Left};
+subst_unknown_groups([{Group,"",Apps} | Groups], Text0, Left) ->
+ warning("No text describes ~w",[Group]),
+ subst_unknown_groups(Groups, Text0, [{Group,"",Apps} | Left]);
+subst_unknown_groups([{_Group,Heading,Apps} | Groups], Text0, Left) ->
+ Text = group_table(Heading,Apps),
+ subst_unknown_groups(Groups, Text0 ++ Text, Left).
+
+
+group_table(Heading,Apps) ->
+ [
+ " <tr>\n",
+ " <td colspan=2 class=header>\n",
+ " <font size=\"+1\"><b>",Heading,"</b></font>\n",
+ " </td>\n",
+ " </tr>\n",
+ subst_apps(Apps),
+ " <tr>\n",
+ " <td colspan=2><font size=1>&nbsp;</font></td>\n",
+ " </tr>\n"
+ ].
+
+% Count and split the applications in half to get the right sort
+% order in the table.
+
+subst_apps([{App,VersionInfo} | Apps]) ->
+ [subst_app(App, VersionInfo) | subst_apps(Apps)];
+subst_apps([]) ->
+ [].
+
+
+subst_app(App, [{VSN,_Path,Link,Text}]) ->
+ [
+ " <tr class=app>\n",
+ " <td align=left valign=top>\n",
+ " <table border=0 width=\"100%\" cellspacing=0 cellpadding=0>\n",
+ " <tr class=app>\n",
+ " <td align=left valign=top>\n",
+ " <a href=\"",Link,"\" target=\"_top\">",uc(App),"</a>\n",
+ " <a href=\"",Link,"\" target=\"_top\">",VSN,"</a>\n",
+ " </td>\n",
+ " </tr>\n",
+ " </table>\n"
+ " </td>\n",
+ " <td align=left valign=top>\n",
+ Text,"\n",
+ " </td>\n",
+ " </tr>\n"
+ ];
+subst_app(App, [{VSN,_Path,Link,Text} | VerInfos]) ->
+ [
+ " <tr class=app>\n",
+ " <td align=left valign=top>\n",
+ " <table border=0 width=\"100%\" cellspacing=0 cellpadding=0>\n",
+ " <tr class=app>\n",
+ " <td align=left valign=top>\n",
+ " <a href=\"",Link,"\" target=\"_top\">",uc(App),
+ "</a>&nbsp;&nbsp;<br>\n",
+ " <a href=\"",Link,"\" target=\"_top\">",VSN,"</a>\n",
+ " </td>\n",
+ " <td align=right valign=top width=50>\n",
+ " <table border=0 width=40 cellspacing=0 cellpadding=0>\n",
+ " <tr class=app>\n",
+ " <td align=left valign=top class=appnums>\n",
+ subst_vsn(VerInfos),
+ " </td>\n",
+ " </tr>\n",
+ " </table>\n"
+ " </td>\n",
+ " </tr>\n",
+ " </table>\n"
+ " </td>\n",
+ " <td align=left valign=top>\n",
+ Text,"\n",
+ " </td>\n",
+ " </tr>\n"
+ ].
+
+
+subst_vsn([{VSN,_Path,Link,_Text} | VSNs]) ->
+ [
+ " <font size=\"2\"><a class=anum href=\"",Link,"\" target=\"_top\">",
+ VSN,
+ "</a></font><br>\n",
+ subst_vsn(VSNs)
+ ];
+subst_vsn([]) ->
+ "".
+
+
+% Yes, this is very inefficient an is done for every comarision
+% in the sort but it doesn't matter in this case.
+
+vsncmp({Vsn1,_,_,_}, {Vsn2,_,_,_}) ->
+ L1 = [list_to_integer(N1) || N1 <- string:tokens(Vsn1, ".")],
+ L2 = [list_to_integer(N2) || N2 <- string:tokens(Vsn2, ".")],
+ L1 > L2.
+
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% GENERIC FUNCTIONS, NOT SPECIFIC FOR GENERATING INDEX.HTML
+%
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% Read the "info" file into a list of Key/Value pairs
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+read_info(File) ->
+ case file:open(File, read) of
+ {ok,Stream} ->
+ Res =
+ case file:read(Stream,10000) of
+ {ok, Text} ->
+ Lines = string:tokens(Text, "\n\r"),
+ KeyValues0 = lines_to_key_value(Lines),
+ combine_key_value(KeyValues0);
+ {error, Reason} ->
+ {error, Reason}
+ end,
+ file:close(Stream),
+ Res;
+ {error,Reason} ->
+ {error,Reason}
+ end.
+
+combine_key_value([{Key,Value1},{Key,Value2} | KeyValues]) ->
+ combine_key_value([{Key,Value1 ++ "\n" ++ Value2} | KeyValues]);
+combine_key_value([KeyValue | KeyValues]) ->
+ [KeyValue | combine_key_value(KeyValues)];
+combine_key_value([]) ->
+ [].
+
+lines_to_key_value([]) ->
+ [];
+lines_to_key_value([Line | Lines]) ->
+ case re:run(Line, "^[a-zA-Z_\\-]+:") of
+ nomatch ->
+ case re:run(Line, "[\041-\377]") of
+ nomatch ->
+ lines_to_key_value(Lines);
+ _ ->
+ warning("skipping line \"~s\"",[Line]),
+ lines_to_key_value(Lines)
+ end;
+ {match, [{0, Length} |_]} ->
+ Value0 = lists:sublist(Line, Length+1, length(Line) - Length),
+ Value1 = re:replace(Value0, "^[ \t]*", "",
+ [{return, list}]),
+ Value = re:replace(Value1, "[ \t]*$", "",
+ [{return, list}]),
+ Key = lists:sublist(Line, Length-1),
+ [{Key, Value} | lines_to_key_value(Lines)]
+ end.
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% Extensions to the 'regexp' module.
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+%% is_match(Ex, Re) ->
+%% case regexp:first_match(Ex, Re) of
+%% {match, _, _} ->
+%% true;
+%% nomatch ->
+%% false
+%% end.
+
+%% -type gsub(String, RegExp, Fun, Acc) -> subres().
+%% Substitute every match of the regular expression RegExp with the
+%% string returned from the function Fun(Match, Acc). Accept pre-parsed
+%% regular expressions. Acc is an argument to the Fun. The Fun should return
+%% a tuple {Replacement, NewAcc}.
+
+gsub(String, RegExp, Fun, Acc) when is_list(RegExp) ->
+ case re:compile(RegExp) of
+ {ok, RE} ->
+ gsub(String, RE, Fun, Acc);
+ {error, E} ->
+ {error, E}
+ end;
+gsub(String, RE, Fun, Acc) ->
+ {match, Ss} = re:run(String, RE, [global]),
+ {NewString, NewAcc} = sub_repl(Ss, Fun, Acc, String, 0),
+ {ok, NewString, NewAcc}.
+
+
+% New code that uses fun for finding the replacement. Also uses accumulator
+% to pass argument between the calls to the fun.
+sub_repl([[{St, L}] |Ss], Fun, Acc0, S, Pos) ->
+ Match = string:substr(S, St+1, L),
+ {Rep, Acc} = Fun(Match, Acc0),
+ {Rs, NewAcc} = sub_repl(Ss, Fun, Acc, S, St+L),
+ {string:substr(S, Pos+1, St-Pos) ++ Rep ++ Rs, NewAcc};
+sub_repl([], _Fun, Acc, S, Pos) -> {string:substr(S, Pos+1), Acc}.
+
+
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% Error and warnings
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+error(Format, Args) ->
+ io:format("ERROR: " ++ Format ++ "\n", Args),
+ exit(1).
+
+warning(Format, Args) ->
+ case get(silent) of
+ true -> ok;
+ _ -> io:format("WARNING: " ++ Format ++ "\n", Args)
+ end.
+
+report(Format, Args) ->
+ case get(silent) of
+ true -> ok;
+ _ -> io:format(Format ++ "\n", Args)
+ end.
+
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% Extensions to the 'string' module.
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+uc(String) ->
+ lists:reverse(uc(String, [])).
+
+uc([], Acc) ->
+ Acc;
+uc([H | T], Acc) when is_integer(H), [97] =< H, H =< $z ->
+ uc(T, [H - 32 | Acc]);
+uc([H | T], Acc) ->
+ uc(T, [H | Acc]).
+
diff --git a/system/doc/top/src/erlresolvelinks.erl b/system/doc/top/src/erlresolvelinks.erl
index 8d277ad17a..004d0d8626 120000..100644
--- a/system/doc/top/src/erlresolvelinks.erl
+++ b/system/doc/top/src/erlresolvelinks.erl
@@ -1 +1,184 @@
-../../../../internal_tools/integration/scripts/resolve_links/erlresolvelinks.erl \ No newline at end of file
+%%--------------------------------------------------------------------
+%%
+%% %CopyrightBegin%
+%%
+%% 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%
+%%
+%%-----------------------------------------------------------------
+%% File: erlresolvelinks.erl
+%%
+%% Description:
+%% This file generates the javascript that resolves documentation links.
+%%
+%%-----------------------------------------------------------------
+-module(erlresolvelinks).
+
+-export([make/0, make/1]).
+-include_lib("kernel/include/file.hrl").
+
+-define(JAVASCRIPT_NAME, "erlresolvelinks.js").
+
+make() ->
+ case os:getenv("ERL_TOP") of
+ false ->
+ io:format("Variable ERL_TOP is required\n",[]);
+ Value ->
+ make_from_src(Value, ".")
+ end.
+
+make([RootDir, DestDir]) ->
+ do_make(RootDir, DestDir);
+make(RootDir) when is_atom(RootDir) ->
+ DestDir = filename:join(RootDir, "doc"),
+ do_make(RootDir, DestDir).
+
+do_make(_RootDir, _DestDir) ->
+ ok.
+
+make_from_src(RootDir, DestDir) ->
+ %% doc/Dir
+ %% erts-Vsn
+ %% lib/App-Vsn
+ Name = ?JAVASCRIPT_NAME,
+ DocDirs0 = get_dirs(filename:join([RootDir, "system/doc"])),
+ DocDirs = lists:map(fun({Dir, _DirPath}) ->
+ D = filename:join(["doc", Dir]),
+ {D, D} end, DocDirs0),
+
+ ErtsDirs = latest_app_dirs(RootDir, ""),
+ AppDirs = latest_app_dirs(RootDir, "lib"),
+
+ AllAppDirs =
+ lists:map(
+ fun({App, AppVsn}) -> {App, filename:join([AppVsn, "doc", "html"])}
+ end, ErtsDirs ++ AppDirs),
+
+ AllDirs = DocDirs ++ AllAppDirs,
+ {ok, Fd} = file:open(filename:join([DestDir, Name]), [write]),
+ UTC = calendar:universal_time(),
+ io:fwrite(Fd, "/* Generated by ~s at ~w UTC */\n",
+ [atom_to_list(?MODULE), UTC]),
+ io:fwrite(Fd, "function erlhref(ups, app, rest) {\n", []),
+ io:fwrite(Fd, " switch(app) {\n", []),
+ lists:foreach(
+ fun({Tag, Dir}) ->
+ io:fwrite(Fd, " case ~p:\n", [Tag]),
+ io:fwrite(Fd, " location.href=ups + \"~s/\" + rest;\n",
+ [Dir]),
+ io:fwrite(Fd, " break;\n", [])
+ end, AllDirs),
+ io:fwrite(Fd, " default:\n", []),
+ io:fwrite(Fd, " location.href=ups + \"Unresolved\";\n", []),
+ io:fwrite(Fd, " }\n", []),
+ io:fwrite(Fd, "}\n", []),
+ file:close(Fd),
+ ok.
+
+
+
+
+get_dirs(Dir) ->
+ {ok, Files} = file:list_dir(Dir),
+ AFiles =
+ lists:map(fun(File) -> {File, filename:join([Dir, File])} end, Files),
+ lists:zf(fun is_dir/1, AFiles).
+
+is_dir({File, AFile}) ->
+ {ok, FileInfo} = file:read_file_info(AFile),
+ case FileInfo#file_info.type of
+ directory ->
+ {true, {File, AFile}};
+ _ ->
+ false
+ end.
+
+latest_app_dirs(RootDir, Dir) ->
+ ADir = filename:join(RootDir, Dir),
+ RDirs0 = get_dirs(ADir),
+ RDirs1 = lists:filter(fun is_app_dir/1, RDirs0),
+
+ SDirs0 =
+ lists:map(fun({App, Dir1}) ->
+ File = filename:join(Dir1, "vsn.mk"),
+ case file:read_file(File) of
+ {ok, Bin} ->
+ case re:run(Bin, ".*VSN\s*=\s*([0-9\.]+).*",[{capture,[1],list}]) of
+ {match, [VsnStr]} ->
+ VsnNumList = vsnstr_to_numlist(VsnStr),
+ {{App, VsnNumList}, App++"-"++VsnStr};
+ nomatch ->
+ io:format("No VSN variable found in ~s\n", [File]),
+ error
+ end;
+ {error, Reason} ->
+ io:format("~p : ~s\n", [Reason, File]),
+ error
+ end
+ end,
+ RDirs1),
+ SDirs1 = lists:keysort(1, SDirs0),
+ App2Dirs = lists:foldr(fun({{App, _VsnNumList}, AppVsn}, Acc) ->
+ case lists:keymember(App, 1, Acc) of
+ true ->
+ Acc;
+ false ->
+ [{App, AppVsn}| Acc]
+ end
+ end, [], SDirs1),
+ lists:map(fun({App, AppVsn}) -> {App, filename:join([Dir, AppVsn])} end,
+ App2Dirs).
+
+is_app_dir({_Dir, DirPath}) ->
+ case file:read_file_info(filename:join(DirPath, "vsn.mk")) of
+ {ok, FileInfo} ->
+ case FileInfo#file_info.type of
+ regular ->
+ true;
+ _ ->
+ false
+ end;
+ {error, _Reason} ->
+ false
+ end.
+
+
+%% is_vsnstr(Str) ->
+%% case string:tokens(Str, ".") of
+%% [_] ->
+%% false;
+%% Toks ->
+%% lists:all(fun is_numstr/1, Toks)
+%% end.
+
+%% is_numstr(Cs) ->
+%% lists:all(fun(C) when $0 =< C, C =< $9 ->
+%% true;
+%% (_) ->
+%% false
+%% end, Cs).
+
+%% We know:
+
+vsnstr_to_numlist(VsnStr) ->
+ lists:map(fun(NumStr) -> list_to_integer(NumStr) end,
+ string:tokens(VsnStr, ".")).
+
+
+
+
+
+
+
diff --git a/system/doc/top/src/otp_man_index.erl b/system/doc/top/src/otp_man_index.erl
new file mode 100644
index 0000000000..0fdc531b37
--- /dev/null
+++ b/system/doc/top/src/otp_man_index.erl
@@ -0,0 +1,199 @@
+%%--------------------------------------------------------------------
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 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%
+%%
+%%-----------------------------------------------------------------
+%% File: otp_man_index.erl
+%%
+%% Description:
+%% This file generates the module overview in the documentation.
+%%
+%%-----------------------------------------------------------------
+
+-module(otp_man_index).
+
+-export([gen/1]).
+-include_lib("kernel/include/file.hrl").
+
+
+gen([RootDir, OutFile]) when is_atom(RootDir), is_atom(OutFile)->
+ Bases = [{"../lib/", filename:join(RootDir, "lib")},
+ {"../", RootDir}],
+ Apps = find_application_paths(Bases),
+ RefPages = find_ref_files(Apps),
+ gen_html(RefPages, atom_to_list(OutFile)).
+
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% Find Reference files
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+find_ref_files(Apps) ->
+ find_ref_files(Apps, []).
+
+find_ref_files([], Acc) ->
+ Acc;
+find_ref_files([{App, Vsn, AppPath, RelPath} |Apps], Acc) ->
+ case filelib:wildcard(filename:join(AppPath, "*.html")) of
+ [] ->
+ find_ref_files(Apps, Acc);
+ Result ->
+
+ Refs1 = lists:filter(fun(Ref) ->
+ case file:read_file(Ref) of
+ {ok, Bin} ->
+ case re:run(Bin, ".*<!-- refpage -->.*",[]) of
+ {match, _} ->
+ true;
+ nomatch ->
+ false
+ end;
+ {error, Reason} ->
+ exit(io_lib:format("~p : ~s\n", [Reason, Ref]))
+ end
+ end,
+ Result),
+
+ Refs2 = lists:map(fun(Ref) ->
+ Module = filename:basename(Ref, ".html"),
+ {string:to_lower(Module),
+ Module,
+ App ++ "-" ++ Vsn,
+ RelPath,
+ filename:join(RelPath, filename:basename(Ref))}
+ end,
+ Refs1),
+ find_ref_files(Apps, Refs2 ++ Acc)
+ end.
+
+find_application_paths([]) ->
+ [];
+find_application_paths([{URL, Dir} | Paths]) ->
+ Sub1 = "doc/html",
+
+ AppDirs = get_app_dirs(Dir),
+
+ AppPaths =
+ lists:map(
+ fun({App, AppPath}) ->
+ VsnFile = filename:join(AppPath, "vsn.mk"),
+ VsnStr =
+ case file:read_file(VsnFile) of
+ {ok, Bin} ->
+ case re:run(Bin, ".*VSN\s*=\s*([0-9\.]+).*",[{capture,[1],list}]) of
+ {match, [V]} ->
+ V;
+ nomatch ->
+ exit(io_lib:format("No VSN variable found in ~s\n",
+ [VsnFile]))
+ end;
+ {error, Reason} ->
+ exit(io_lib:format("~p : ~s\n", [Reason, VsnFile]))
+ end,
+ AppURL = URL ++ App ++ "-" ++ VsnStr,
+ {App, VsnStr, AppPath ++ "/" ++ Sub1, AppURL ++ "/" ++ Sub1}
+ end, AppDirs),
+ AppPaths ++ find_application_paths(Paths).
+
+
+get_app_dirs(Dir) ->
+ {ok, Files} = file:list_dir(Dir),
+ AFiles =
+ lists:map(fun(File) -> {File, filename:join([Dir, File])} end, Files),
+ lists:zf(fun is_app_with_doc/1, AFiles).
+
+is_app_with_doc({"." ++ ADir, _APath}) ->
+ false;
+is_app_with_doc({ADir, APath}) ->
+ case file:read_file_info(filename:join([APath, "info"])) of
+ {ok, _FileInfo} ->
+ {true, {ADir, APath}};
+ _ ->
+ false
+ end.
+
+
+
+
+gen_html(RefPages, OutFile)->
+ case file:open(OutFile, [write]) of
+ {ok, Out} ->
+ io:fwrite(Out, "~s\n", [html_header()]),
+
+ SortedPages = lists:sort(RefPages),
+
+ lists:foreach(fun({_,Module, App, AppDocDir, RefPagePath}) ->
+ io:fwrite(Out, " <TR>\n",[]),
+ io:fwrite(Out, " <TD><A HREF=\"~s\">~s</A></TD>\n",
+ [RefPagePath, Module]),
+ io:fwrite(Out, " <TD><A HREF=\"~s\">~s</A></TD>\n",
+ [filename:join(AppDocDir, "index.html"),
+ App]),
+ io:fwrite(Out, " </TR>\n",[])
+ end,
+ SortedPages),
+
+ {Year, _, _} = date(),
+ io:fwrite(Out, "~s\n", [html_footer(integer_to_list(Year))]);
+ {error, Reason} ->
+ exit("~p: ~s\n",[Reason, OutFile])
+ end.
+
+
+
+html_header() ->
+ "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\">\n"
+ "<!-- This file was generated by the otp_man_index -->\n"
+ "<HTML>\n"
+ "<HEAD>\n"
+ " <link rel=\"stylesheet\" href=\"otp_doc.css\" type=\"text/css\"/>\n"
+ " <TITLE>Erlang/OTP Manual Page Index</TITLE>\n"
+ "</HEAD>\n"
+ "<BODY BGCOLOR=\"#FFFFFF\" TEXT=\"#000000\" LINK=\"#0000FF\" VLINK=\"#FF00FF\" ALINK=\"#FF0000\">\n"
+ "<CENTER>\n"
+ "<!-- A HREF=\"http://www.erlang.org/\">\n"
+ "<img alt=\"Erlang logo\" src=\"erlang-logo.png\"/>\n"
+ "</A><BR -->\n"
+ "<SMALL>\n"
+ "[<A HREF=\"index.html\">Up</A> | <A HREF=\"http://www.erlang.org/\">Erlang</A>]\n"
+ "</SMALL><BR>\n"
+ "<P/><FONT SIZE=\"+4\">OTP Reference Page Index</FONT><BR>\n"
+ "</CENTER>\n"
+ "<CENTER>\n"
+ "<P/>\n"
+ "<TABLE BORDER=1>\n"
+ "<TR>\n"
+ " <TH>Manual Page</TH><TH>Application</TH>\n"
+ "</TR>\n".
+
+
+
+html_footer(Year) ->
+ "</TABLE>\n"
+ "</CENTER>\n"
+ "<P/>\n"
+ "<CENTER>\n"
+ "<HR/>\n"
+ "<SMALL>\n"
+ "Copyright &copy; 1991-" ++ Year ++ "\n"
+ "<a href=\"http://www.ericsson.com/technology/opensource/erlang/\">\n"
+ "Ericsson AB</a>\n"
+ "</SMALL>\n"
+ "</CENTER>\n"
+ "</BODY>\n"
+ "</HTML>\n".
diff --git a/system/doc/top/src/permuted_index.erl b/system/doc/top/src/permuted_index.erl
deleted file mode 120000
index e65338a517..0000000000
--- a/system/doc/top/src/permuted_index.erl
+++ /dev/null
@@ -1 +0,0 @@
-../../../../internal_tools/integration/scripts/make_index/permuted_index.erl \ No newline at end of file
diff --git a/system/doc/top/templates/applications.html.src b/system/doc/top/templates/applications.html.src
index 0251d39b28..285bbced71 100644
--- a/system/doc/top/templates/applications.html.src
+++ b/system/doc/top/templates/applications.html.src
@@ -1,7 +1,26 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<!--
+%CopyrightBegin%
+
+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%
+-->
+
<html>
<head>
- <title>Erlang/OTP #version#</title>
+ <title>Erlang/OTP #version# Applications</title>
<style type="text/css">
<!--
BODY { background: white }
diff --git a/system/doc/top/templates/erlang.gif b/system/doc/top/templates/erlang.gif
deleted file mode 100644
index 91fd4b9647..0000000000
--- a/system/doc/top/templates/erlang.gif
+++ /dev/null
Binary files differ
diff --git a/system/doc/top/templates/first.html.src b/system/doc/top/templates/first.html.src
deleted file mode 100644
index edef1c0e5c..0000000000
--- a/system/doc/top/templates/first.html.src
+++ /dev/null
@@ -1,104 +0,0 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
-<html>
-<head>
- <title>Erlang/OTP #release# Documentation</title>
- <style type="text/css">
-<!--
- BODY { background: white }
-
- BODY { font-family: Verdana, Arial, Helvetica, sans-serif }
- TH { font-family: Verdana, Arial, Helvetica, sans-serif }
- TD { font-family: Verdana, Arial, Helvetica, sans-serif }
- P { font-family: Verdana, Arial, Helvetica, sans-serif }
-
- .header { background: #222; color: #fff }
- .app { background: #ccc }
--->
- </style>
-</head>
-<body bgcolor=white text="#000000" link="#0000ff" vlink="#ff00ff"
- alink="#ff0000">
-<center>
-<p>
-<font size="+1">Welcome to Erlang/OTP, a complete<br>
-development environment<br>
-for concurrent programming.</font>
-</p>
-</center>
-<br>
-<br>
-<br>
-<p><b>
-<font size"+1">
-Some hints that may get you started faster
-</font>
-</b></p>
-
-<ul>
-
-<li>In addition the the documentation here Erlang is described in the book
-<a href="http://www.pragprog.com/titles/jaerlang" target="_top">"Programming Erlang"</a>, ISBN 978-1-934356-00-5 which we really recommend as a start.<br/ >
-The complete language is also described in the <a href="reference_manual/part_frame.html" target="_top">Erlang Reference Manual</a>. An Erlang tutorial can be found in <a href="getting_started/part_frame.html" target="_top">Getting Started With Erlang</a>.
-</li>
-<li>Erlang/OTP is divided into a number of OTP <a
-href="applications.html">applications</a>. An application normally contains
-Erlang <a href="man_index.html">modules</a>. Some OTP applications,
-such as the C interface <em>Erl_Interface</em>, are written in other languages and have no Erlang
-modules.
-
-<p>
-Note that functions that are not imported or prefixed with a module
-name belong to the module
-<a href="#kernel#/erlang.html" target="_top">erlang</a>
-(in the <em>Kernel</em> application).
-</p>
-<p>
-<li>On a Unix system you can view the manual pages from the command
-line using
-<pre>
- % erl -man &lt;module&gt;
-</pre>
-<p>
-
-<li> You can of course use any editor you like to write Erlang
-programs, but if you use Emacs there exists editing support such as
-indentation, syntax highlighting, electric commands, module name
-verification, comment support including paragraph filling, skeletons,
-tags support and more. See the <a href="#tools#/index.html"
-target="_top">Tools</a> application for details.
-<p>
-There is also an
-<a href="http://erlide.sourceforge.net" target="_top">
-Erlang plugin (ErlIde) for Eclipse</a> if you prefer a more graphical
-environment. ErlIde is under development and should at the time
-of writing this be quite stable and useful.
-<li>When developing with Erlang/OTP you usually test your programs
-from the interactive shell (see <a href="getting_started/part_frame.html"
-target="_top">Getting Started With Erlang</a>) where you can call individual
-functions. There is also a number of tools available, such as the graphical <a
-href="#debugger#/index.html" target="_top">Debugger</a>, the process
-manager <a href="#pman#/index.html" target="_top">Pman</a> and table
-viewer <a href="#tv#/index.html" target="_top">TV</a>.
-<p> Also note that there are some shell features like history list
-(control-p and control-n), inline editing (emacs key bindings) and
-module and function name completion (tab) if the module is loaded.
-<p>
-
-<li>OpenSource users can ask questions
-and share experiences on the <a href="http://www.erlang.org/faq.html"
-target="_top">Erlang questions mailing list</a>. <p>
-
-<li>Before asking a question you can browse the <a
-href="http://www.erlang.org/pipermail/erlang-questions/"
-target="_top">mailing list archive</a> and read the <a
-href="http://www.erlang.org/faq/faq.html" target="_top">Frequently
-Asked Questions</a>. <p>
-
-<li>Additional information and links of interest for Erlang programmers can be found on the Erlang Open Source site
-<a href="http://www.erlang.org/" target="_top">http://www.erlang.org</a>.
-<p>
-
-</ul>
-
-</body>
-</html>
diff --git a/system/doc/top/templates/flip_closed.gif b/system/doc/top/templates/flip_closed.gif
deleted file mode 100755
index 9a27c7c25d..0000000000
--- a/system/doc/top/templates/flip_closed.gif
+++ /dev/null
Binary files differ
diff --git a/system/doc/top/templates/flip_google.gif b/system/doc/top/templates/flip_google.gif
deleted file mode 100755
index 3f0543c2bb..0000000000
--- a/system/doc/top/templates/flip_google.gif
+++ /dev/null
Binary files differ
diff --git a/system/doc/top/templates/flip_open.gif b/system/doc/top/templates/flip_open.gif
deleted file mode 100755
index 9dda60e73a..0000000000
--- a/system/doc/top/templates/flip_open.gif
+++ /dev/null
Binary files differ
diff --git a/system/doc/top/templates/flip_static.gif b/system/doc/top/templates/flip_static.gif
deleted file mode 100755
index 2b3ddb5382..0000000000
--- a/system/doc/top/templates/flip_static.gif
+++ /dev/null
Binary files differ
diff --git a/system/doc/top/templates/flipmenu.js b/system/doc/top/templates/flipmenu.js
deleted file mode 100755
index 92a5a58a06..0000000000
--- a/system/doc/top/templates/flipmenu.js
+++ /dev/null
@@ -1,342 +0,0 @@
-// ######################################################################
-
-// ## flipMenu 5.0.0 (c) J. Reijers
-// ## Last modifications: 23 March 2007
-
-// ######################################################################
-
-// ## Degree of indentation from the left.
- flipIndentation = "5px";
-
-// ## Padding inbetween menu items.
- flipVerticalPadding = "4px";
-
-// ## Margin between the left of the browser and the menu.
- flipLeftMargin = "16px";
-
-// ## Margin between the top of the browser and the menu.
- flipTopMargin = "10px";
-
-// ## Allow multiple menus to fold out without closing all the other open ones.
- flipOpenMultipleMenus = false;
-
-// ## Preserve the current state of the menu (requires cookies).
- flipSaveMenuState = true;
-
-// ## Use custom images for bullets
- flipImages = true;
-
-// ## Images to use (specify full path)
- flipImg_open = "flip_open.gif";
- flipImg_closed = "flip_closed.gif";
- flipImg_static = "flip_static.gif";
-
-// ## Initialise all flipMenus onload
- flipInitOnLoad = true;
-
-// ## Message to display in status bar while loading
- flipLoadingMessage = "Loading...";
-
-// ######################################################################
-
-function alterSize(someSize, alterAmount) {
- someSize = String(someSize);
- var tmpNr = parseFloat(someSize.replace(/\D/g, ""));
- var tmpChar = someSize.replace(/\d/g, "");
- return isNaN(tmpNr) ? someSize : ((tmpNr + alterAmount) + tmpChar);
-}
-
-isIE = (String(navigator.appVersion).indexOf("MSIE") > -1);
-if (!isIE) flipIndentation = alterSize(flipIndentation, -16);
-if (!isIE) flipLeftMargin = alterSize(flipLeftMargin, -16);
-
-document.write(
- "<style type=\"text/css\">" +
-
- "ul.flipMenu { margin-top: " + flipTopMargin + "; margin-left: " + flipLeftMargin + "; " + (flipImages ? "" : "list-style-type: none;") + " }" +
- "ul.flipMenu ul, ul.flipMenu li { padding-top: " + flipVerticalPadding + "; margin-left: " + flipIndentation + "; margin-right: 0px; " + (flipImages ? "" : "list-style-type: none;") + " }" +
-
- "li.flipFolderOpen { cursor: pointer; " + (flipImages ? "list-style-image: url(" + flipImg_open + ");" : "") + " }" +
- "li.flipFolderClosed { cursor: pointer; " + (flipImages ? "list-style-image: url(" + flipImg_closed + ");" : "") + " }" +
-
- "</style>"
-);
-
-if (flipImages) {
- aFlipPreloads = [];
- aFlipPreloads[0] = new Image;
- aFlipPreloads[0].src = flipImg_open;
- aFlipPreloads[1] = new Image;
- aFlipPreloads[1].src = flipImg_closed;
- aFlipPreloads[2] = new Image;
- aFlipPreloads[2].src = flipImg_static;
-}
-
-function addEvent(someObj, someEvent, someFunction) {
- if (someObj.addEventListener) { someObj.addEventListener(someEvent, someFunction, true); return true; } else if (someObj.attachEvent) return someObj.attachEvent("on" + someEvent, someFunction); else return false;
-}
-
-function openCloseFlip(theItem, newSetting, openParents) {
- if (theItem.flipID) {
- if (openParents) {
- var tmpItem = theItem;
- while (tmpItem.parentElement || tmpItem.parentNode) {
- tmpItem = (tmpItem.parentElement) ? tmpItem.parentElement : tmpItem.parentNode;
- openCloseFlip(tmpItem, newSetting);
- }
- }
- if ((theItem.className == "flipFolderOpen" && newSetting == "closed") || (theItem.className == "flipFolderClosed" && newSetting == "open")) {
- if (!theItem.childrenInitialised) {
- for (var j = 0; j < theItem.childNodes.length; j++) if (theItem.childNodes[j].nodeName == "UL" && !theItem.childNodes[j].initialised) initFlip(theItem.childNodes[j]);
- theItem.childrenInitialised = true;
- }
- theItem.getElementsByTagName("UL")[0].style.display = (newSetting == "open") ? "" : "none";
- theItem.className = newSetting == "open" ? "flipFolderOpen" : "flipFolderClosed";
- }
- }
-}
-
-function openFlip(theItem, openParents) {
- openCloseFlip(theItem, "open", openParents);
-}
-
-function closeFlip(theItem, closeParents) {
- openCloseFlip(theItem, "closed", closeParents);
-}
-
-function toggleFlip(theElement) {
- if (theElement.flipID) {
- var theItem = theElement;
- var isContained = true;
- } else {
- if (theElement && theElement.button > 0) return false;
- var theItem = (isIE) ? event.srcElement : theElement.target;
-
- var isContained = false;
- if (theItem.className == "flipFolderOpen" || theItem.className == "flipFolderClosed") isContained = true; else while (theItem.parentElement || theItem.parentNode) {
- if (theItem.className == "flipStatic" || theItem.className == "flipFolderOpen" || theItem.className == "flipFolderClosed") {
- isContained = (theItem.className == "flipFolderOpen" || theItem.className == "flipFolderClosed");
- break;
- }
- theItem = (theItem.parentElement) ? theItem.parentElement : theItem.parentNode;
- }
- }
-
- var toOpenFlip = (isContained && theItem.className == "flipFolderClosed");
-
- if (!flipOpenMultipleMenus && (toOpenFlip || theItem.className == "flipStatic")) {
- if (theItem.parentElement || theItem.parentNode) {
- var parentUL = (theItem.parentElement) ? theItem.parentElement : theItem.parentNode;
- for (var i = 0; i < parentUL.childNodes.length; i++) closeFlip(parentUL.childNodes[i]);
- }
- }
-
- if (isContained) {
- if (toOpenFlip) openFlip(theItem); else closeFlip(theItem);
- }
-}
-
-function setAllFlips(startElement, newSetting) {
- if (typeof startElement == "undefined") var startElement = document;
- if (typeof newSetting == "undefined") var newSetting = "closed";
-
- var aUL = startElement.getElementsByTagName("UL");
- for (var i = 0; i < aUL.length; i++) {
- var parentFlip = aUL[i].parentElement ? aUL[i].parentElement : aUL[i].parentNode;
- openCloseFlip(parentFlip, newSetting);
- }
-}
-
-function openAllFlips(startElement) {
- setAllFlips(startElement, "open");
-}
-
-function closeAllFlips(startElement) {
- setAllFlips(startElement, "closed");
-}
-
-function initFlip(startElement) {
- if (!document.createElement) return false;
-
- if (!startElement || !startElement.nodeName) {
- var aUL = document.getElementsByTagName("UL");
- for (var i = 0; i < aUL.length; i++) {
- if (flipLoadingMessage != "") window.status = flipLoadingMessage + " " + parseInt((i / (aUL.length - 1)) * 100, 10) + "%";
- var curUL = aUL[i];
- if (curUL.className == "flipMenu") {
- initFlip(curUL);
-
- // ## Fix text selecting problem in Mozilla
- curUL.onselectstart = new Function("return false");
- curUL.onmousedown = new Function("return false");
- curUL.onclick = new Function("return true");
- }
- }
-
- if (flipSaveMenuState) loadMenuState();
-
- if (flipLoadingMessage != "") window.status = "";
- return true;
- }
-
- if (startElement.className == "flipMenu") startElement.style.display = "";
-
- if (!startElement.childNodes || startElement.childNodes.length == 0) return false;
-
- if (typeof flipIDCur == "undefined") flipIDCur = 0;
- if (!startElement.initialised) {
- var aUL = startElement.getElementsByTagName("UL");
- for (var i = 0; i < aUL.length; i++) aUL[i].style.display = "none";
- }
-
- for (var i = 0; i < startElement.childNodes.length; i++) {
- var curNode = startElement.childNodes[i];
- if (curNode.nodeName == "LI") {
- flipIDCur++;
- curNode.flipID = flipIDCur;
-
- var nodeHasChildren = curNode.getElementsByTagName("UL").length > 0;
- if (nodeHasChildren) {
- if (flipImages && curNode.flipClosed) curNode.style.listStyleImage = "url(" + curNode.flipClosed + ")";
-
- if (curNode.className == null || curNode.className == "") curNode.className = "flipFolderClosed";
- } else {
- curNode.className = "flipStatic";
- if (flipImages && !curNode.style.listStyleImage) {
- if (!curNode.flipStatic) curNode.flipStatic = flipImg_static;
- curNode.style.listStyleImage = "url(" + curNode.flipStatic + ")";
- }
- }
-
- if (!curNode.flipOpen) curNode.flipOpen = flipImg_open;
- if (!curNode.flipClosed) curNode.flipClosed = flipImg_closed;
-
- if (curNode.flipIsOpen) openFlip(curNode);
- }
- }
-
- startElement.initialised = true;
-}
-
-function rootOfFlip(flipID, startElement) {
-
- function containsFlip(startElement, flipID) {
- var flipFound = false;
- var i = 0;
- while (i < startElement.childNodes.length && !flipFound) {
- var curNode = startElement.childNodes[i];
- flipFound = (curNode.flipID == flipID) ? true : containsFlip(curNode, flipID);
- i++;
- }
- return flipFound;
- }
-
- var rootFlip = null;
-
- if (!startElement || !startElement.nodeName) {
- var aUL = document.getElementsByTagName("UL");
- var i = 0;
- while (rootFlip == null && i < aUL.length) {
- var curUL = aUL[i];
- if (curUL.nodeName == "UL" && curUL.className == "flipMenu") rootFlip = rootOfFlip(flipID, curUL);
- i++;
- }
- return rootFlip;
- }
-
- if (startElement.childNodes) for (var i = 0; i < startElement.childNodes.length; i++) {
- var curNode = startElement.childNodes[i];
- if (curNode.flipID == flipID || containsFlip(curNode, flipID)) rootFlip = curNode;
- }
-
- return rootFlip;
-}
-
-function getCookie(cookieName) {
- var allCookies = document.cookie;
- var indexStr = allCookies.indexOf(cookieName + "=");
- if (indexStr == -1) return "";
- indexStr = allCookies.indexOf("=", indexStr) + 1;
- var endStr = allCookies.indexOf(";", indexStr);
- if (endStr == -1) endStr = allCookies.length;
- return unescape(allCookies.substring(indexStr, endStr));
-}
-
-function inArray(someID, someArray) {
- for (var i = 0; i < someArray.length; i++) if (someArray[i] == someID) return true;
- return false;
-}
-
-function getMenuState(startElement) {
- if (!startElement.childNodes || startElement.childNodes.length == 0) return "";
-
- var openItems = "";
- var aUL = startElement.getElementsByTagName("UL");
- for (var i = 0; i < aUL.length; i++) {
- var curNode = aUL[i];
- var parentFlip = (curNode.parentElement) ? curNode.parentElement : curNode.parentNode;
- if (curNode.style.display == "" && parentFlip.flipID) openItems += " " + parentFlip.flipID;
- }
- return openItems;
-}
-
-function putMenuState(startElement) {
- if (!startElement.childNodes || startElement.childNodes.length == 0) return false;
-
- var aUL = startElement.getElementsByTagName("UL");
- for (var i = 0; i < aUL.length; i++) {
- var curNode = aUL[i];
- var parentFlip = (curNode.parentElement) ? curNode.parentElement : curNode.parentNode;
- if (inArray(parentFlip.flipID, aOpenItems)) {
- openFlip(parentFlip);
- if (typeof prevFlipRoot == "undefined") {
- var testRoot = rootOfFlip(parentFlip.flipID);
- if (testRoot.flipID == parentFlip.flipID) prevFlipRoot = testRoot;
- }
- }
- }
-}
-
-function saveMenuState() {
- if (flipSaveMenuState) {
- var aUL = document.getElementsByTagName("UL");
- for (var i = 0; i < aUL.length; i++) {
- var curUL = aUL[i];
- var curID = curUL.id ? curUL.id : i;
- if (curUL.className == "flipMenu") document.cookie = cookiePrefix + curID + "=" + getMenuState(curUL) + ";";
- }
- }
-}
-
-function loadMenuState() {
- var aUL = document.getElementsByTagName("UL");
- for (var i = 0; i < aUL.length; i++) {
- var curUL = aUL[i];
- var curID = curUL.id ? curUL.id : i;
- if (curUL.className == "flipMenu") {
- var savedState = String(getCookie(cookiePrefix + curID));
- if (savedState != "") {
- aOpenItems = savedState.split(" ");
- putMenuState(curUL);
- }
- }
- }
-
- addEvent(window, "unload", saveMenuState);
-}
-
-function clearMenuState(flipMenuID) {
- if (typeof flipMenuID == "undefined") {
- var aUL = document.getElementsByTagName("UL");
- for (var i = 0; i < aUL.length; i++) {
- var curUL = aUL[i];
- var curID = curUL.id ? curUL.id : i;
- if (curUL.className == "flipMenu") document.cookie = cookiePrefix + curID + "=;";
- }
- } else document.cookie = cookiePrefix + flipMenuID + "=;";
-}
-
-cookiePrefix = document.location.pathname + "_";
-
-addEvent(document, "click", toggleFlip);
-if (flipInitOnLoad) addEvent(window, "load", initFlip);
diff --git a/system/doc/top/templates/index.html.src b/system/doc/top/templates/index.html.src
index 935bb11c80..88d425ac1d 100644
--- a/system/doc/top/templates/index.html.src
+++ b/system/doc/top/templates/index.html.src
@@ -2,7 +2,7 @@
<!--
%CopyrightBegin%
-Copyright Ericsson AB 2001-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
@@ -39,8 +39,8 @@ under the License.
<small><a href="applications.html">Applications</a><br>
<a href="man_index.html">Modules</a></small>
<p/>
-<small><a href="highlights.html">Release highlights</a><br>
-<a href="incompatible.html">Potential incompatibilities</a><br>
+<small><a href="highlights.html">Release highlights</a><br/>
+<a href="incompatible.html">Potential incompatibilities</a><br/>
</small>
<br>
<a href="javascript:openAllFlips()">Expand All</a><br>
@@ -48,7 +48,7 @@ under the License.
<p/>
<ul class="flipMenu">
-<li>Erlang/OTP System Documentation
+<li>System Documentation
<ul>
<li><a href="installation_guide/users_guide.html">Installation Guide</a></li>
<li><a href="system_principles/users_guide.html">System Principles</a></li>
@@ -62,7 +62,11 @@ under the License.
<li><a href="oam/users_guide.html">OAM Principles</a></li>
</ul>
</li>
+</ul>
+<b>Application Groups</b>
+<br/>
+<ul class="flipMenu">
#applinks#
</ul>
@@ -169,7 +173,7 @@ Asked Questions</a>. <p>
<center>
<small>
-Copyright &copy; 1999-2009
+Copyright &copy; 1999-2010
<a href="http://www.ericsson.com">Ericsson AB</a>
</small>
</center>
diff --git a/system/doc/top/templates/otp_top.css b/system/doc/top/templates/otp_top.css
deleted file mode 100644
index 1c6d27bd8d..0000000000
--- a/system/doc/top/templates/otp_top.css
+++ /dev/null
@@ -1,53 +0,0 @@
- BODY { background: white }
-
- BODY { font-family: Verdana, Arial, Helvetica, sans-serif }
- TH { font-family: Verdana, Arial, Helvetica, sans-serif }
- TD { font-family: Verdana, Arial, Helvetica, sans-serif }
- P { font-family: Verdana, Arial, Helvetica, sans-serif }
-
- .header { background: #222; color: #fff }
- .top { background: #efe }
- .otp { background: #efe }
- .erlang { background: #ffe }
- .otp2 { background: #efe }
- .app { background: #ffe }
-
- a:link { color: blue; text-decoration: none }
- a:active { color: blue; text-decoration: none }
- a:visited { color: blue; text-decoration: none }
- body {
- margin: 0;
- padding: 0;
- border: 0;
- overflow: scroll;
- height: 100%;
- max-height: 100%
- }
- #container {
- width: 100%;
- margin: 10px auto;
- background-color: #fff;
- }
- #leftnav {
- float: left;
- width: 200px;
- margin: 0;
- padding: 1em;
- }
- #content {
- margin-left: 220px; /* set left value to WidthOfFrameDiv */
- border-left: 1px solid red;
- }
-
- .innertube {
- margin: 15px; /* Magins for inner DIV inside each DIV (to provide padding) */
- }
-
- * html body{ /* IE6 hack */
- padding: 0 0 0 200px; /* Set value to (0 0 0 WidthOfFrameDiv)*/
- }
- * html #maincontent{ /* IE6 hack*/
- height: 100%;
- width: 100%;
- }
-
diff --git a/system/doc/top/templates/system.html.src b/system/doc/top/templates/system.html.src
deleted file mode 100644
index 761bc96ed0..0000000000
--- a/system/doc/top/templates/system.html.src
+++ /dev/null
@@ -1,281 +0,0 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
-<html>
-<head>
- <title>Erlang/OTP #release#</title>
- <style type="text/css">
-<!--
- BODY { background: white }
-
- BODY { font-family: Verdana, Arial, Helvetica, sans-serif }
- TH { font-family: Verdana, Arial, Helvetica, sans-serif }
- TD { font-family: Verdana, Arial, Helvetica, sans-serif }
- P { font-family: Verdana, Arial, Helvetica, sans-serif }
-
- .header { background: #222; color: #fff }
- .app { background: #ccc }
-
- a.anum:link { color: green; text-decoration: none }
- a.anum:active { color: green; text-decoration: none }
- a.anum:visited { color: green; text-decoration: none }
-
- a:link { text-decoration: none }
- a:active { text-decoration: none }
- a:visited { text-decoration: none }
--->
- </style>
-</head>
-
-<body bgcolor=white text="#000000" link="#0000ff" vlink="#ff00ff"
- alink="#ff0000">
-<center>
-<table border=0 width="90%" cellspacing=3 cellpadding=5>
-
- <tr>
- <td colspan=2 class=header>
- <font size="+1"><b>General</b></font>
- </td>
- </tr>
-
- <tr class=app>
- <td align=left valign=top>
- <table border=0 width="100%" cellspacing=0 cellpadding=0>
- <tr class=app>
- <td align=left valign=top>
- <a href="system_architecture_intro/part_frame.html" target="_top"
- name=system_architecture_intro>
- Introduction
- </a>
- </td>
- <td align=right valign=top width=50>
- </td>
- </tr>
- </table>
- </td>
- <td align=left valign=top>
-About Erlang, OTP, Erlang/OTP and this documentation
- </td>
- </tr>
-
- <tr class=app>
- <td align=left valign=top>
- <table border=0 width="100%" cellspacing=0 cellpadding=0>
- <tr class=app>
- <td align=left valign=top>
- <a href="installation_guide/part_frame.html" target="_top"
- name=installation_guide>
- Installation Guide
- </a>
- </td>
- <td align=right valign=top width=50>
- </td>
- </tr>
- </table>
- </td>
- <td align=left valign=top>
-The Erlang/OTP Installation Guide
- </td>
- </tr>
-
- <tr class=app>
- <td align=left valign=top>
- <table border=0 width="100%" cellspacing=0 cellpadding=0>
- <tr class=app>
- <td align=left valign=top>
- <a href="system_principles/part_frame.html" target="_top"
- name=system_principles>
- System Principles
- </a>
- </td>
- <td align=right valign=top width=20>
- </td>
- </tr>
- </table>
- </td>
- <td align=left valign=top>
-Starting, stopping and configuring the Erlang runtime system
- </td>
- </tr>
-
- <tr class=app>
- <td align=left valign=top>
- <table border=0 width="100%" cellspacing=0 cellpadding=0>
- <tr class=app>
- <td align=left valign=top>
- <a href="embedded/part_frame.html" target="_top" name=embedded>
- Embedded System
- </a>
- </td>
- <td align=right valign=top width=50>
- </td>
- </tr>
- </table>
- </td>
- <td align=left valign=top>
-Erlang in an Embedded System
- </td>
- </tr>
-
- <tr>
- <td colspan=2><font size=1>&nbsp;</font></td>
- </tr>
-
-<!-- ====================================================================== -->
-
- <tr>
- <td colspan=2 class=header>
- <font size="+1"><b>Programming in Erlang</b></font>
- </td>
- </tr>
-
- <tr class=app>
- <td align=left valign=top>
- <table border=0 width="100%" cellspacing=0 cellpadding=0>
- <tr class=app>
- <td align=left valign=top>
- <a href="reference_manual/part_frame.html" target="_top" name=reference_manual>
- Erlang Reference Manual
- </a>
- </td>
- <td align=right valign=top width=50>
- </td>
- </tr>
- </table>
- </td>
- <td align=left valign=top>
-Description of data types, language constructs and more
- </td>
- </tr>
-
- <tr class=app>
- <td align=left valign=top>
- <table border=0 width="100%" cellspacing=0 cellpadding=0>
- <tr class=app>
- <td align=left valign=top>
- <a href="getting_started/part_frame.html" target="_top" name=getting_started>
- Getting Started
- </a>
- </td>
- <td align=right valign=top width=50>
- </td>
- </tr>
- </table>
- </td>
- <td align=left valign=top>
-Getting started with Erlang
- </td>
- </tr>
-
- <tr class=app>
- <td align=left valign=top>
- <table border=0 width="100%" cellspacing=0 cellpadding=0>
- <tr class=app>
- <td align=left valign=top>
- <a href="programming_examples/part_frame.html" target="_top" name=programming_examples>
- Programming Examples
- </a>
- </td>
- <td align=right valign=top width=50>
- </td>
- </tr>
- </table>
- </td>
- <td align=left valign=top>
-Examples of using records, funs, list comprehensions and the bit syntax
- </td>
- </tr>
-
- <tr class=app>
- <td align=left valign=top>
- <table border=0 width="100%" cellspacing=0 cellpadding=0>
- <tr class=app>
- <td align=left valign=top>
- <a href="efficiency_guide/part_frame.html" target="_top" name=efficiency_guide>Efficiency Guide</a>
- </td>
- <td align=right valign=top width=20>
- </td>
- </tr>
- </table>
- </td>
- <td align=left valign=top>
-Learn how to write efficient programs in Erlang
- </td>
- </tr>
-
- <tr class=app>
- <td align=left valign=top>
- <table border=0 width="100%" cellspacing=0 cellpadding=0>
- <tr class=app>
- <td align=left valign=top>
- <a href="tutorial/part_frame.html" target="_top" name=tutorial>Interoperability Tutorial</a>
- </td>
- <td align=right valign=top width=20>
- </td>
- </tr>
- </table>
- </td>
- <td align=left valign=top>
-About interoperating with programs written in other programming languages
- </td>
- </tr>
-
- <tr>
- <td colspan=2><font size=1>&nbsp;</font></td>
- </tr>
-
-<!-- ====================================================================== -->
-
- <tr>
- <td colspan=2 class=header>
- <font size="+1"><b>Working with OTP</b></font>
- </td>
- </tr>
-
- <tr class=app>
- <td align=left valign=top>
- <table border=0 width="100%" cellspacing=0 cellpadding=0>
- <tr class=app>
- <td align=left valign=top>
- <a href="design_principles/part_frame.html" target="_top"
- name=design_principles>
- Design Principles
- </a>
- </td>
- <td align=right valign=top width=20>
- </td>
- </tr>
- </table>
- </td>
- <td align=left valign=top>
-Structure your programs with applications, supervisors and generic behaviors (gen_server, gen_event and gen_fsm).
-Also use the built in error logger.
- </td>
- </tr>
-
- <tr class=app>
- <td align=left valign=top>
- <table border=0 width="100%" cellspacing=0 cellpadding=0>
- <tr class=app>
- <td align=left valign=top>
- <a href="oam/part_frame.html" target="_top" name=oam>OAM Principles</a>
- </td>
- <td align=right valign=top width=20>
- </td>
- </tr>
- </table>
- </td>
- <td align=left valign=top>
-OTP Operation and Management Principles
- </td>
- </tr>
-
- <tr>
- <td colspan=2><font size=1>&nbsp;</font></td>
- </tr>
-
-</table>
-
-</center>
-</body>
-</html>
-
-
diff --git a/system/doc/top/templates/toc_.html.src b/system/doc/top/templates/toc_.html.src
deleted file mode 100644
index 5e79bc0ac8..0000000000
--- a/system/doc/top/templates/toc_.html.src
+++ /dev/null
@@ -1,105 +0,0 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
-<html>
-<head>
- <title>Erlang/OTP #release#</title>
- <style type="text/css">
-<!--
- BODY { background: white }
-
- BODY { font-family: Verdana, Arial, Helvetica, sans-serif }
- TH { font-family: Verdana, Arial, Helvetica, sans-serif }
- TD { font-family: Verdana, Arial, Helvetica, sans-serif }
- P { font-family: Verdana, Arial, Helvetica, sans-serif }
-
- .header { background: #222; color: #fff }
- .top { background: #efe }
- .otp { background: #efe }
- .erlang { background: #ffe }
- .otp2 { background: #efe }
- .app { background: #ffe }
-
- a:link { color: blue; text-decoration: none }
- a:active { color: blue; text-decoration: none }
- a:visited { color: blue; text-decoration: none }
--->
- </style>
-</head>
-
-<body bgcolor=white text="#000000" link="#0000ff" vlink="#ff00ff"
- alink="#ff0000">
-<center>
-<font size="+1"><b>Erlang/OTP #release#</b></font><br>
-</center>
-
-<div class=top>
-<small><a href="glossary.html" target=body>Glossary</a> |
-<a href="man_index.html" target=body>Modules</a> |
-<a href="permuted_index/pidxa.html" target=body>Index</a></small>
-<p>
-<small><a href="highlights.html" target=body>Release highlights</a><br>
-<a href="incompatible.html" target=body>Potential incompatibilities</a>
-</small>
-</div>
-
-<p>
-<div class=otp>
-Erlang/OTP
-<br>
-&middot;<small><a href="installation_guide/part_frame.html" target="_top"
- name=installation_guide>Installation Guide</a></small>
-
-<br>
-&middot;<small><a href="system_principles/part_frame.html" target="_top"
- name=system_principles>System Principles</a></small>
-
-<br>
-&middot;<small><a href="embedded/part_frame.html" target="_top" name=embedded>Embedded System</a></small>
-
-</div>
-
-<p>
-<div class=erlang>
-Erlang Programming
-<br>
-&middot;<small><a href="getting_started/part_frame.html" target="_top" name=getting_started>Getting
-Started</a></small>
-
-<br>
-&middot;<small><a href="reference_manual/part_frame.html" target="_top" name=reference_manual>Erlang
-Reference Manual</a></small>
-
-<br>
-&middot;<small><a href="programming_examples/part_frame.html" target="_top" name=programming_examples>Programming
-Examples</a></small>
-
-<br>
-&middot;<small><a href="efficiency_guide/part_frame.html" target="_top" name=efficiency_guide>Efficiency Guide</a></small>
-
-<br>
-&middot;<small><a href="tutorial/part_frame.html" target="_top" name=tutorial>Interoperability Tutorial</a></small>
-</div>
-
-<p>
-<div class=otp2>
-Working with OTP
-<br>
-&middot;<small><a href="design_principles/part_frame.html" target="_top"
- name=design_principles>Design Principles</a>
-</small>
-
-<br>
-&middot;<small><a href="oam/part_frame.html" target="_top" name=oam>OAM Principles</a></small>
-
-</div>
-
-<p>
-<div class=app>
-Applications
-<small>#applinks#</small>
-</div>
-
-<p>
-<a href="http://www.erlang.se/" target=body>http://www.erlang.se</a>
-
-</body>
-</html>
diff --git a/xcomp/README.md b/xcomp/README.md
new file mode 100644
index 0000000000..9f638f46d7
--- /dev/null
+++ b/xcomp/README.md
@@ -0,0 +1,506 @@
+Cross Compiling Erlang/OTP
+==========================
+
+This document describes how to cross compile Erlang/OTP. Note that the support
+for cross compiling Erlang/OTP should be considered as experimental. As far as
+we know, the R13B04 release should cross compile fine, but since we currently
+have a very limited set of cross compilation environments to test with we
+cannot be sure. The cross compile support will stay in an experimental state
+until we get a lot more cross compilation environments to test with.
+
+You are encouraged to read the whole document before attempting to cross
+compile Erlang/OTP. Before reading this document you should read the
+[`$ERL_TOP/INSTALL.md`] [1] document which describes building Erlang/OTP in
+general. `$ERL_TOP` is the top directory in the source tree.
+
+`otp_build` Versus `configure`/`make`
+-------------------------------------
+
+Building Erlang/OTP can be done either by using the `$ERL_TOP/otp_build`
+script, or by invoking `$ERL_TOP/configure` and `make` directly. Building using
+`otp_build` is easier since it involves fewer steps, but the `otp_build` build
+procedure is not as flexible as the `configure`/`make` build procedure. Note
+that `otp_build configure` will produce a default configuration that differs
+from what `configure` will produce by default. For example, currently
+`--disable-dynamic-ssl-lib` is added to the `configure` command line arguments
+unless `--enable-dynamic-ssl-lib` has been explicitly passed. The binary
+releases that we deliver are built using `otp_build`. The defaults used by
+`otp_build configure` may change at any time without prior notice.
+
+Cross Configuration
+-------------------
+
+The `$ERL_TOP/xcomp/erl-xcomp.conf.template` file contains all available cross
+configuration variables and can be used as a template when creating a cross
+compilation configuration. All cross configuration variables are also listed
+at the end of this document. For examples of working cross configurations see
+the `$ERL_TOP/xcomp/erl-xcomp-TileraMDE2.0-tilepro.conf` file and the
+`$ERL_TOP/xcomp/erl-xcomp-x86_64-saf-linux-gnu.conf` file. If the default
+behavior of a variable is satisfactory, the variable does not need to be set.
+However, the `configure` script will issue a warning when a default value is
+used. When a variable has been set, no warning will be issued.
+
+A cross configuration file can be passed to `otp_build configure` using the
+`--xcomp-conf` command line argument. Note that `configure` does not accept
+this command line argument. When using the `configure` script directly, pass
+the configuration variables as arguments to `configure` using a
+`<VARIABLE>=<VALUE>` syntax. Variables can also be passed as environment
+variables to `configure`. However, if you pass the configuration in the
+environment, make sure to unset all of these environment variables before
+invoking `make`; otherwise, the environment variables might set make variables
+in some applications, or parts of some applications, and you may end up with
+an erroneously configured build.
+
+What can be Cross Compiled?
+---------------------------
+
+All Erlang/OTP applications except the `wx` application can be cross compiled.
+The build of the `wx` driver will currently be automatically disabled when
+cross compiling.
+
+Compatibility
+-------------
+
+The build system, including cross compilation configuration variables used,
+may be subject to non backward compatible changes without prior notice.
+Current cross build system has been tested when 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.
+
+Patches
+-------
+
+Please submit any patches for cross compiling in a way consistent with this
+system. All input is welcome as we have a very limited set of cross compiling
+environments to test with. If a new configuration variable is needed, add it
+to `$ERL_TOP/xcomp/erl-xcomp.conf.template`, and use it in `configure.in`.
+Other files that might need to be updated are:
+
+- `$ERL_TOP/xcomp/erl-xcomp-vars.sh`
+- `$ERL_TOP/erl-build-tool-vars.sh`
+- `$ERL_TOP/erts/aclocal.m4`
+- `$ERL_TOP/xcomp/README.md`
+- `$ERL_TOP/xcomp/erl-xcomp-*.conf`
+
+Note that this might be an incomplete list of files that need to be updated.
+
+General information on how to submit patches can be found at:
+ <http://wiki.github.com/erlang/otp/submitting-patches>
+
+Build and Install Procedure
+---------------------------
+
+If you are building in Git you want to read the "Building in Git" section
+of [`$ERL_TOP/INSTALL.md`] [1] before proceeding.
+
+We will first go through the `configure`/`make` build procedure which people
+probably are most familiar with.
+
+### Building With `configure`/`make` Directly ###
+
+ (1)
+
+Change directory into the top directory of the Erlang/OTP source tree.
+
+ $ cd $ERL_TOP
+
+In order to compile Erlang code, a small Erlang bootstrap system has to be
+built, or an Erlang/OTP system of the same release as the one being built
+has to be provided in the `$PATH`. The Erlang/OTP for the target system will
+be built using this Erlang system, together with the cross compilation tools
+provided.
+
+If you want to build the documentation out of the same source tree as you are
+cross compiling in, you currently need a full Erlang/OTP system of the same
+release as the one being built for the build machine. If this is the case,
+build and install one for the build machine (or use one already built) and add
+it to the `$PATH` before cross building, and building the documentation. See
+[`$ERL_TOP/INSTALL.md`] [1] for information on building the documentation.
+
+If you want to build using a compatible Erlang/OTP system in the `$PATH`,
+jump to (3).
+
+#### Building a Bootstrap System ####
+
+ (2)
+
+ $ ./configure --enable-bootstrap-only
+ $ make
+
+The `--enable-bootstrap-only` argument to `configure` isn't strictly necessary,
+but will speed things up. It will only run `configure` in applications
+necessary for the bootstrap, and will disable a lot of things not needed by
+the bootstrap system. If you run `configure` without `--enable-boostrap-only`
+you also have to run make as `make bootstrap`; otherwise, the whole system will
+be built.
+
+#### Cross Building the System ####
+
+ (3)
+
+ $ ./configure --host=<HOST> --build=<BUILD> [Other Config Args]
+ $ make
+
+`<HOST>` is the host/target system that you build for. 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 executing `$ERL_TOP/erts/autoconf/config.sub <HOST>`. If
+`config.sub` fails, you need to be more specific.
+
+`<BUILD>` should equal the `CPU-VENDOR-OS` triplet of the system that you
+build on. If you execute `$ERL_TOP/erts/autoconf/config.guess`, it will in
+most cases print the triplet you want to use for this.
+
+Pass the cross compilation variables as command line arguments to `configure`
+using a `<VARIABLE>=<VALUE>` syntax. Note that you can *not* pass a
+configuration file using `--xcomp-conf=<FILE>` when you invoke `configure`
+directly. The `--xcomp-conf=<FILE>` argument can only be passed to
+`otp_build configure`.
+
+`make` will verify that the Erlang/OTP system used when building is of the
+same release as the system being built, and will fail if this is not the case.
+It is possible, however not recommended, to force the cross compilation even
+though the wrong Erlang/OTP system is used. This by invoking `make` like this:
+`make ERL_XCOMP_FORCE_DIFFERENT_OTP=yes`. Note that this build might fail,
+silently produce suboptimal code, or silently produce erroneous code.
+
+#### Installing ####
+
+You can either install using the installation paths determined by `configure`
+(4), or install manually using (5).
+
+##### Installing Using Paths Determined by `configure` #####
+
+ (4)
+
+ $ make install DESTDIR=<TEMPORARY_PREFIX>
+
+`make install` will install at a location specified when doing `configure`.
+`configure` arguments specifying where the installation should reside are for
+example: `--prefix`, `--exec-prefix`, `--libdir`, `--bindir`, etc. By default
+it will install under `/usr/local`. You typically do not want to install your
+cross build under `/usr/local` on your build machine. Using [`DESTDIR`] [2]
+will cause the installation paths to be prefixed by `$DESTDIR`. This makes it
+possible to install and package the installation on the build machine without
+having to place the installation in the same directory on the build machine as
+it should be executed from on the target machine.
+
+When `make install` has finished, change directory into `$DESTDIR`, package
+the system, move it to the target machine, and unpack it. Note that the
+installation will only be working on the target machine at the location
+determined by `configure`.
+
+##### Installing Manually #####
+
+ (5)
+
+ $ make release RELEASE_ROOT=<RELEASE_DIR>
+
+`make release` will copy what you have built for the target machine to
+`<RELEASE_DIR>`. The `Install` script will not be run. The content of
+`<RELEASE_DIR>` is what by default ends up in `/usr/local/lib/erlang`.
+
+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 packaging Erlang/OTP. The `Install` script should
+currently be invoked as follows in the directory where it resides
+(the top directory):
+
+ $ ./Install [-cross] [-minimal|-sasl] <ERL_ROOT>
+
+where:
+
+* `-minimal` Creates an installation that starts up a minimal amount
+ of applications, i.e., only `kernel` and `stdlib` are started. The
+ minimal system is normally enough, and is what `make install` uses.
+* `-sasl` Creates an installation that also starts up the `sasl`
+ application.
+* `-cross` For cross compilation. Informs the install script that it
+ is run on the build machine.
+* `<ERL_ROOT>` - The absolute path to the Erlang installation to use
+ at run time. This is often the same as the current working directory,
+ but does not have to be. It can follow any other path through the file
+ system to the same directory.
+
+If neither `-minimal`, nor `-sasl` is passed as argument you will be
+prompted.
+
+You can now either do:
+
+ (6)
+
+* Decide where the installation should be located on the target machine,
+ run the `Install` script on the build machine, and package the installed
+ installation. The installation just need to be unpacked at the right
+ location on the target machine:
+
+ $ cd <RELEASE_DIR>
+ $ ./Install -cross [-minimal|-sasl] <ABSOLUTE_INSTALL_DIR_ON_TARGET>
+
+or:
+
+ (7)
+
+* Package the installation in `<RELEASE_DIR>`, place it wherever you want
+ on your target machine, and run the `Install` script on your target
+ machine:
+
+ $ cd <ABSOLUTE_INSTALL_DIR_ON_TARGET>
+ $ ./Install [-minimal|-sasl] <ABSOLUTE_INSTALL_DIR_ON_TARGET>
+
+### Building With the `otp_build` Script ###
+
+ (8)
+
+ $ cd $ERL_TOP
+
+ (9)
+
+ $ ./otp_build configure --xcomp-conf=<FILE> [Other Config Args]
+
+alternatively:
+
+ $ ./otp_build configure --host=<HOST> --build=<BUILD> [Other Config Args]
+
+If you have your cross compilation configuration in a file, pass it using the
+`--xcomp-conf=<FILE>` command line argument. If not, pass `--host=<HOST>`,
+`--build=<BUILD>`, and the configuration variables using a `<VARIABLE>=<VALUE>`
+syntax on the command line (same as in (3)). Note that `<HOST>` and `<BUILD>`
+have to be passed one way or the other; either by using `erl_xcomp_host=<HOST>`
+and `erl_xcomp_build=<BUILD>` in the configuration file, or by using the
+`--host=<HOST>`, and `--build=<BUILD>` command line arguments.
+
+`otp_build configure` will configure both for the boostrap system on the
+build machine and the cross host system.
+
+ (10)
+
+ $ ./otp_build boot -a
+
+`otp_build boot -a` will first build a bootstrap system for the build machine
+and then do the cross build of the system.
+
+ (11)
+
+ $ ./otp_build release -a <RELEASE_DIR>
+
+`otp_build release -a` will do the same as (5), and you will after this have
+to do a manual install either by doing (6), or (7).
+
+Currently Used Configuration Variables
+--------------------------------------
+
+Note that you cannot define arbitrary variables in a cross compilation
+configuration file. Only the ones listed below will be guaranteed to be
+visible throughout the whole execution of all `configure` scripts. Other
+variables needs to be defined as arguments to `configure` or exported in
+the environment.
+
+### Variables for `otp_build` Only ###
+
+Variables in this section are only used, when configuring Erlang/OTP for
+cross compilation using `$ERL_TOP/otp_build configure`.
+
+*NOTE*! These variables currently have *no* effect if you configure using
+the `configure` script directly.
+
+* `erl_xcomp_build` - The build system used. This value will be passed as
+ `--build=$erl_xcomp_build` 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_build`. If set to `guess`,
+ the build system will be guessed using
+ `$ERL_TOP/erts/autoconf/config.guess`.
+
+* `erl_xcomp_host` - Cross host/target system to build for. This value will
+ be passed as `--host=$erl_xcomp_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`.
+
+* `erl_xcomp_configure_flags` - Extra configure flags to pass to the
+ `configure` script.
+
+### Cross Compiler and Other Tools ###
+
+If the cross compilation tools are prefixed by `<HOST>-` you probably do
+not need to set these variables (where `<HOST>` is what has been passed as
+`--host=<HOST>` argument to `configure`).
+
+All variables in this section can also be used when native compiling.
+
+* `CC` - C compiler.
+
+* `CFLAGS` - C compiler flags.
+
+* `STATIC_CFLAGS` - Static C compiler flags.
+
+* `CFLAG_RUNTIME_LIBRARY_PATH` - This flag should set runtime library
+ search path for the shared libraries. Note that this actually is a
+ linker flag, but it needs to be passed via the compiler.
+
+* `CPP` - C pre-processor.
+
+* `CPPFLAGS` - C pre-processor flags.
+
+* `CXX` - C++ compiler.
+
+* `CXXFLAGS` - C++ compiler flags.
+
+* `LD` - Linker.
+
+* `LDFLAGS` - Linker flags.
+
+* `LIBS` - Libraries.
+
+#### *D*ynamic *E*rlang *D*river Linking ####
+
+*NOTE*! Either set all or none of the `DED_LD*` variables.
+
+* `DED_LD` - Linker for Dynamically loaded Erlang Drivers.
+
+* `DED_LDFLAGS` - Linker flags to use with `DED_LD`.
+
+* `DED_LD_FLAG_RUNTIME_LIBRARY_PATH` - This flag should set runtime library
+ search path for shared libraries when linking with `DED_LD`.
+
+#### Large File Support ####
+
+*NOTE*! Either set all or none of the `LFS_*` variables.
+
+* `LFS_CFLAGS` - Large file support C compiler flags.
+
+* `LFS_LDFLAGS` - Large file support linker flags.
+
+* `LFS_LIBS` - Large file support libraries.
+
+#### Other Tools ####
+
+* `RANLIB` - `ranlib` archive index tool.
+
+* `AR` - `ar` archiving tool.
+
+* `GETCONF` - `getconf` system configuration inspection tool. `getconf` is
+ currently used for finding out large file support flags to use, and
+ on Linux systems for finding out if we have an NPTL thread library or
+ not.
+
+### Cross System Root Locations ###
+
+* `erl_xcomp_sysroot` - The absolute path to the system root of the cross
+ compilation environment. Currently, the `crypto`, `odbc`, `ssh` and
+ `ssl` applications need the system root. These applications will be
+ skipped if the system root has not been set. The system root might be
+ needed for other things too. If this is the case and the system root
+ has not been set, `configure` will fail and request you to set it.
+
+* `erl_xcomp_isysroot` - The absolute path to the system root for includes
+ of the cross compilation environment. If not set, this value defaults
+ to `$erl_xcomp_sysroot`, i.e., only set this value if the include system
+ root path is not the same as the system root path.
+
+### Optional Feature, and Bug Tests ###
+
+These tests cannot (always) be done automatically when cross compiling. You
+usually do not need to set these variables. Only set these if you really
+know what you are doing.
+
+Note that some of these values will override results of tests performed
+by `configure`, and some will not be used until `configure` is sure that
+it cannot figure the result out.
+
+The `configure` script will issue a warning when a default value is used.
+When a variable has been set, no warning will be issued.
+
+* `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.
+ This is currently only used by unsupported features.
+
+* `erl_xcomp_bigendian` - `yes|no`. No default. 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. Since no default
+ value is used, `configure` will try to figure this out automatically.
+
+* `erl_xcomp_clock_gettime_cpu_time` - `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_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_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. This is currently only used by unsupported features.
+
+* `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_linux_clock_gettime_correction` - `yes|no`. Defaults to `yes` on
+ Linux; otherwise, `no`. 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_sigaltstack` - `yes|no`. Defaults to `yes` on Linux;
+ otherwise, `no`. 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_sigusrx` - `yes|no`. Defaults to `yes`. If `yes`,
+ the `SIGUSR1` and `SIGUSR2` signals must be usable by the ERTS. Old
+ LinuxThreads thread libraries (Linux kernel versions typically less than
+ 2.2) used these signals and made them unusable by the ERTS.
+
+* `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_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.
+
+Copyright and License
+---------------------
+
+> %CopyrightBegin%
+>
+> 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%
+
+
+
+ [1]: INSTALL.html "$ERL_TOP/INSTALL.md"
+ [2]: http://www.gnu.org/prep/standards/html_node/DESTDIR.html "DESTDIR"
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..f9fff0fa8e 100644
--- a/xcomp/erl-xcomp-TileraMDE2.0-tilepro.conf
+++ b/xcomp/erl-xcomp-TileraMDE2.0-tilepro.conf
@@ -1,196 +1,258 @@
-###
-### %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%
-###
-### File: erl-xcomp.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>`".
-### ----------------------------------------------------------------------------
-
-### ----------------------------------------------------------------------------
-### Variables in the following section *have* to be set.
-###
-
+## -*-shell-script-*-
##
-## Operating system and hardware architecture.
+## %CopyrightBegin%
##
-# 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}
-
+## 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/.
##
-## Sizes (in bytes) of some important types.
+## 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.
##
-# 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
-
-### ----------------------------------------------------------------------------
-### 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.
-### ---------------------------------------------------------------------------
+## %CopyrightEnd%
+##
+## File: erl-xcomp-TileraMDE2.0-tilepro.conf
+## Author: Rickard Green
+##
+## -----------------------------------------------------------------------------
+## When cross compiling Erlang/OTP using `otp_build', copy this file and set
+## the variables needed below. Then pass the path to the copy of this file as
+## an argument to `otp_build' in the configure stage:
+## `otp_build configure --xcomp-conf=<FILE>'
+## -----------------------------------------------------------------------------
+
+## Note that you cannot define arbitrary variables in a cross compilation
+## configuration file. Only the ones listed below will be guaranteed to be
+## visible throughout the whole execution of all `configure' scripts. Other
+## variables needs to be defined as arguments to `configure' or exported in
+## the environment.
+
+## -- Variables for `otp_build' Only -------------------------------------------
+
+## Variables in this section are only used, when configuring Erlang/OTP for
+## cross compilation using `$ERL_TOP/otp_build configure'.
+
+## *NOTE*! These variables currently have *no* effect if you configure using
+## the `configure' script directly.
+
+# * `erl_xcomp_build' - The build system used. This value will be passed as
+# `--build=$erl_xcomp_build' 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_build'. If set to `guess',
+# the build system will be guessed using
+# `$ERL_TOP/erts/autoconf/config.guess'.
+erl_xcomp_build=guess
+
+# * `erl_xcomp_host' - Cross host/target system to build for. This value will
+# be passed as `--host=$erl_xcomp_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'.
+erl_xcomp_host=tile
+
+# * `erl_xcomp_configure_flags' - Extra configure flags to pass to the
+# `configure' script.
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.
-###----------------------------------------------------------------------------
+## -- Cross Compiler and Other Tools -------------------------------------------
-erl_xcomp_cc=
+## If the cross compilation tools are prefixed by `<HOST>-' you probably do
+## not need to set these variables (where `<HOST>' is what has been passed as
+## `--host=<HOST>' argument to `configure').
-erl_xcomp_ld=
+## All variables in this section can also be used when native compiling.
-erl_xcomp_cflags=
+# * `CC' - C compiler.
+#CC=
-erl_xcomp_cpp=
+# * `CFLAGS' - C compiler flags.
+#CFLAGS=
-erl_xcomp_ldflags=
+# * `STATIC_CFLAGS' - Static C compiler flags.
+#STATIC_CFLAGS=
-erl_xcomp_ranlib=
+# * `CFLAG_RUNTIME_LIBRARY_PATH' - This flag should set runtime library
+# search path for the shared libraries. Note that this actually is a
+# linker flag, but it needs to be passed via the compiler.
+#CFLAG_RUNTIME_LIBRARY_PATH=
-erl_xcomp_ar=
+# * `CPP' - C pre-processor.
+#CPP=
-###----------------------------------------------------------------------------
-### 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
-### programs and flags to build a dynamic library.
-### 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.
-###----------------------------------------------------------------------------
+# * `CPPFLAGS' - C pre-processor flags.
+#CPPFLAGS=
-erl_xcomp_ded_ld=
+# * `CXX' - C++ compiler.
+#CXX=
-erl_xcomp_ded_ldflags=
+# * `CXXFLAGS' - C++ compiler flags.
+#CXXFLAGS=
-erl_xcomp_ded_ld_runtime_library_path=
+# * `LD' - Linker.
+#LD=
-### The variables in the following section does not need to be set. Only
-### set these if you really know what you are doing.
-###
+# * `LDFLAGS' - Linker flags.
+#LDFLAGS=
-##
-## Big endian/little endian can usually be determined by configure correctly,
-## but if not, set this variable
-##
-erl_xcomp_bigendian=
+# * `LIBS' - Libraries.
+#LIBS=
-##
-## If you have a working poll that can be used: yes|no
-##
-erl_xcomp_poll=yes
+## -- *D*ynamic *E*rlang *D*river Linking --
-##
-## If you have a working kqueue() that can be used: yes|no
-##
-erl_xcomp_kqueue=
+## *NOTE*! Either set all or none of the `DED_LD*' variables.
-##
-## If you have a putenv() that stores a copy of the key-value pair: yes|no
-##
-erl_xcomp_putenv_copy=
+# * `DED_LD' - Linker for Dynamically loaded Erlang Drivers.
+#DED_LD=
-##
-## If you have reliable floating point exeptions that can be
-## used: yes|no
-##
-erl_xcomp_reliable_fpe=
+# * `DED_LDFLAGS' - Linker flags to use with `DED_LD'.
+#DED_LDFLAGS=
-##
-## If you have getaddrinfo() usable for ipv6: yes|no
-##
-erl_xcomp_getaddrinfo=yes
+# * `DED_LD_FLAG_RUNTIME_LIBRARY_PATH' - This flag should set runtime library
+# search path for shared libraries when linking with `DED_LD'.
+#DED_LD_FLAG_RUNTIME_LIBRARY_PATH=
-##
-## If you have a gethrvtime() that works and uses ioctl()
-## to /proc/self: yes|no
-##
-erl_xcomp_gethrvtime_procfs_ioctl=
+## -- Large File Support --
-##
-## If you have a working clock_gettime(): yes|no
-##
-erl_xcomp_clock_gettime=
+## *NOTE*! Either set all or none of the `LFS_*' variables.
-##
-## If you have a __after_morecore_hook that can track malloc()s
-## core memory use: yes|no
-##
-erl_xcomp_after_morecore_hook=
+# * `LFS_CFLAGS' - Large file support C compiler flags.
+#LFS_CFLAGS=
-##
-## 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=
+# * `LFS_LDFLAGS' - Large file support linker flags.
+#LFS_LDFLAGS=
-##
-## If sbrk/brk wrappers using dlsym(RTLD_NEXT, _) can track malloc()s
-## core memory use: yes|no
-##
-erl_xcomp_brk_wrappers=
+# * `LFS_LIBS' - Large file support libraries.
+#LFS_LIBS=
+
+## -- Other Tools --
+
+# * `RANLIB' - `ranlib' archive index tool.
+#RANLIB=
+
+# * `AR' - `ar' archiving tool.
+#AR=
+
+# * `GETCONF' - `getconf' system configuration inspection tool. `getconf' is
+# currently used for finding out large file support flags to use, and
+# on Linux systems for finding out if we have an NPTL thread library or
+# not.
+#GETCONF=
+
+## -- Cross System Root Locations ----------------------------------------------
+
+# * `erl_xcomp_sysroot' - The absolute path to the system root of the cross
+# compilation environment. Currently, the `crypto', `odbc', `ssh' and
+# `ssl' applications need the system root. These applications will be
+# skipped if the system root has not been set. The system root might be
+# needed for other things too. If this is the case and the system root
+# has not been set, `configure' will fail and request you to set it.
+erl_xcomp_sysroot="$TILERA_ROOT/tile"
+
+# * `erl_xcomp_isysroot' - The absolute path to the system root for includes
+# of the cross compilation environment. If not set, this value defaults
+# to `$erl_xcomp_sysroot', i.e., only set this value if the include system
+# root path is not the same as the system root path.
+#erl_xcomp_isysroot=
+
+## -- Optional Feature, and Bug Tests ------------------------------------------
+
+## These tests cannot (always) be done automatically when cross compiling. You
+## usually do not need to set these variables. Only set these if you really
+## know what you are doing.
+
+## Note that some of these values will override results of tests performed
+## by `configure', and some will not be used until `configure' is sure that
+## it cannot figure the result out.
+
+## The `configure' script will issue a warning when a default value is used.
+## When a variable has been set, no warning will be issued.
+
+# * `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.
+# This is currently only used by unsupported features.
+#erl_xcomp_after_morecore_hook=
+
+# * `erl_xcomp_bigendian' - `yes|no'. No default. 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. Since no default
+# value is used, `configure' will try to figure this out automatically.
+#erl_xcomp_bigendian=
+
+# * `erl_xcomp_clock_gettime_cpu_time' - `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_cpu_time=
+
+# * `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
-### ----------------------------------------------------------------------------
+# * `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=
+
+# * `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. This is currently only used by unsupported features.
+#erl_xcomp_dlsym_brk_wrappers=
+
+# * `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=
+
+# * `erl_xcomp_linux_clock_gettime_correction' - `yes|no'. Defaults to `yes' on
+# Linux; otherwise, `no'. 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_sigaltstack' - `yes|no'. Defaults to `yes' on Linux;
+# otherwise, `no'. 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_linux_usable_sigusrx' - `yes|no'. Defaults to `yes'. If `yes',
+# the `SIGUSR1' and `SIGUSR2' signals must be usable by the ERTS. Old
+# LinuxThreads thread libraries (Linux kernel versions typically less than
+# 2.2) used these signals and made them unusable by the ERTS.
+#erl_xcomp_linux_usable_sigusrx=
+
+# * `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=
+
+# * `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=
+
+# * `erl_xcomp_reliable_fpe' - `yes|no'. Defaults to `no'. If `yes', the target
+# system must have reliable floating point exceptions.
+#erl_xcomp_reliable_fpe=
+
+## -----------------------------------------------------------------------------
diff --git a/xcomp/erl-xcomp-avr32-atmel-linux-gnu.conf b/xcomp/erl-xcomp-avr32-atmel-linux-gnu.conf
new file mode 100644
index 0000000000..f691c6cfd1
--- /dev/null
+++ b/xcomp/erl-xcomp-avr32-atmel-linux-gnu.conf
@@ -0,0 +1,261 @@
+## -*-shell-script-*-
+##
+## %CopyrightBegin%
+##
+## Copyright Ericsson AB 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%
+##
+## File: erl-xcomp-avr32-atmel-linux-gnu.conf
+## Author: Winston Smith <[email protected]>
+##
+## -----------------------------------------------------------------------------
+## When cross compiling Erlang/OTP using `otp_build', copy this file and set
+## the variables needed below. Then pass the path to the copy of this file as
+## an argument to `otp_build' in the configure stage:
+## `otp_build configure --xcomp-conf=<FILE>'
+## -----------------------------------------------------------------------------
+
+## Note that you cannot define arbitrary variables in a cross compilation
+## configuration file. Only the ones listed below will be guaranteed to be
+## visible throughout the whole execution of all `configure' scripts. Other
+## variables needs to be defined as arguments to `configure' or exported in
+## the environment.
+
+## -- Variables for `otp_build' Only -------------------------------------------
+
+## Variables in this section are only used, when configuring Erlang/OTP for
+## cross compilation using `$ERL_TOP/otp_build configure'.
+
+## *NOTE*! These variables currently have *no* effect if you configure using
+## the `configure' script directly.
+
+# * `erl_xcomp_build' - The build system used. This value will be passed as
+# `--build=$erl_xcomp_build' 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_build'. If set to `guess',
+# the build system will be guessed using
+# `$ERL_TOP/erts/autoconf/config.guess'.
+erl_xcomp_build=guess
+
+# * `erl_xcomp_host' - Cross host/target system to build for. This value will
+# be passed as `--host=$erl_xcomp_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'.
+erl_xcomp_host=avr32-atmel-linux-gnu
+
+# * `erl_xcomp_configure_flags' - Extra configure flags to pass to the
+# `configure' script.
+#erl_xcomp_configure_flags=
+
+## -- Cross Compiler and Other Tools -------------------------------------------
+
+## If the cross compilation tools are prefixed by `<HOST>-' you probably do
+## not need to set these variables (where `<HOST>' is what has been passed as
+## `--host=<HOST>' argument to `configure').
+
+## All variables in this section can also be used when native compiling.
+
+# * `CC' - C compiler.
+CC=avr32-linux-gcc
+
+# * `CFLAGS' - C compiler flags.
+#CFLAGS=
+
+# * `STATIC_CFLAGS' - Static C compiler flags.
+#STATIC_CFLAGS=
+
+# * `CFLAG_RUNTIME_LIBRARY_PATH' - This flag should set runtime library
+# search path for the shared libraries. Note that this actually is a
+# linker flag, but it needs to be passed via the compiler.
+#CFLAG_RUNTIME_LIBRARY_PATH=
+
+# * `CPP' - C pre-processor.
+#CPP=
+
+# * `CPPFLAGS' - C pre-processor flags.
+#CPPFLAGS=
+
+# * `CXX' - C++ compiler.
+CXX=avr32-linux-g++
+
+# * `CXXFLAGS' - C++ compiler flags.
+#CXXFLAGS=
+
+# * `LD' - Linker.
+LD=avr32-linux-ld
+
+# * `LDFLAGS' - Linker flags.
+#LDFLAGS=
+
+# * `LIBS' - Libraries.
+#LIBS=
+
+## -- *D*ynamic *E*rlang *D*river Linking --
+
+## *NOTE*! Either set all or none of the `DED_LD*' variables.
+
+# * `DED_LD' - Linker for Dynamically loaded Erlang Drivers.
+#DED_LD=
+
+# * `DED_LDFLAGS' - Linker flags to use with `DED_LD'.
+#DED_LDFLAGS=
+
+# * `DED_LD_FLAG_RUNTIME_LIBRARY_PATH' - This flag should set runtime library
+# search path for shared libraries when linking with `DED_LD'.
+#DED_LD_FLAG_RUNTIME_LIBRARY_PATH=
+
+## -- Large File Support --
+
+## *NOTE*! Either set all or none of the `LFS_*' variables.
+
+# * `LFS_CFLAGS' - Large file support C compiler flags.
+#LFS_CFLAGS=
+
+# * `LFS_LDFLAGS' - Large file support linker flags.
+#LFS_LDFLAGS=
+
+# * `LFS_LIBS' - Large file support libraries.
+#LFS_LIBS=
+
+## -- Other Tools --
+
+# * `RANLIB' - `ranlib' archive index tool.
+RANLIB=avr32-linux-ranlib
+
+# * `AR' - `ar' archiving tool.
+AR=avr32-linux-ar
+
+# * `GETCONF' - `getconf' system configuration inspection tool. `getconf' is
+# currently used for finding out large file support flags to use, and
+# on Linux systems for finding out if we have an NPTL thread library or
+# not.
+#GETCONF=
+
+## -- Cross System Root Locations ----------------------------------------------
+
+# * `erl_xcomp_sysroot' - The absolute path to the system root of the cross
+# compilation environment. Currently, the `crypto', `odbc', `ssh' and
+# `ssl' applications need the system root. These applications will be
+# skipped if the system root has not been set. The system root might be
+# needed for other things too. If this is the case and the system root
+# has not been set, `configure' will fail and request you to set it.
+#
+# NOTE: For AVR32, this should be set to the build_avr32/staging_dir
+# subdirectory within the buildroot tree.
+erl_xcomp_sysroot="$ATMEL_SYSROOT_AVR32"
+
+# * `erl_xcomp_isysroot' - The absolute path to the system root for includes
+# of the cross compilation environment. If not set, this value defaults
+# to `$erl_xcomp_sysroot', i.e., only set this value if the include system
+# root path is not the same as the system root path.
+#erl_xcomp_isysroot=
+
+## -- Optional Feature, and Bug Tests ------------------------------------------
+
+## These tests cannot (always) be done automatically when cross compiling. You
+## usually do not need to set these variables. Only set these if you really
+## know what you are doing.
+
+## Note that some of these values will override results of tests performed
+## by `configure', and some will not be used until `configure' is sure that
+## it cannot figure the result out.
+
+## The `configure' script will issue a warning when a default value is used.
+## When a variable has been set, no warning will be issued.
+
+# * `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.
+# This is currently only used by unsupported features.
+#erl_xcomp_after_morecore_hook=
+
+# * `erl_xcomp_bigendian' - `yes|no'. No default. 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. Since no default
+# value is used, `configure' will try to figure this out automatically.
+#erl_xcomp_bigendian=
+
+# * `erl_xcomp_clock_gettime_cpu_time' - `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_cpu_time=yes
+
+# * `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
+
+# * `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=
+
+# * `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. This is currently only used by unsupported features.
+erl_xcomp_dlsym_brk_wrappers=yes
+
+# * `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=
+
+# * `erl_xcomp_linux_clock_gettime_correction' - `yes|no'. Defaults to `yes' on
+# Linux; otherwise, `no'. 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_sigaltstack' - `yes|no'. Defaults to `yes' on Linux;
+# otherwise, `no'. 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_linux_usable_sigusrx' - `yes|no'. Defaults to `yes'. If `yes',
+# the `SIGUSR1' and `SIGUSR2' signals must be usable by the ERTS. Old
+# LinuxThreads thread libraries (Linux kernel versions typically less than
+# 2.2) used these signals and made them unusable by the ERTS.
+#erl_xcomp_linux_usable_sigusrx=
+
+# * `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=
+
+# * `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=
+
+# * `erl_xcomp_reliable_fpe' - `yes|no'. Defaults to `no'. If `yes', the target
+# system must have reliable floating point exceptions.
+#erl_xcomp_reliable_fpe=
+
+## -----------------------------------------------------------------------------
diff --git a/xcomp/erl-xcomp-vars.sh b/xcomp/erl-xcomp-vars.sh
new file mode 100644
index 0000000000..d9972eb3db
--- /dev/null
+++ b/xcomp/erl-xcomp-vars.sh
@@ -0,0 +1,29 @@
+#
+# %CopyrightBegin%
+#
+# Copyright Ericsson AB 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%
+#
+
+#
+# erl_xcomp_vars - Cross configuration variables currently reqognized by
+# `configure' scripts in OTP.
+#
+# NOTE:
+# When updating, also update $ERL_TOP/xcomp/{README,erl-xcomp.conf.template},
+# and precious variables in $ERL_TOP/erts/aclocal.m4.
+#
+
+erl_xcomp_vars="erl_xcomp_sysroot erl_xcomp_isysroot erl_xcomp_bigendian erl_xcomp_linux_clock_gettime_correction erl_xcomp_linux_nptl erl_xcomp_linux_usable_sigusrx erl_xcomp_linux_usable_sigaltstack erl_xcomp_poll erl_xcomp_kqueue erl_xcomp_putenv_copy erl_xcomp_reliable_fpe erl_xcomp_getaddrinfo erl_xcomp_gethrvtime_procfs_ioctl erl_xcomp_clock_gettime_cpu_time erl_xcomp_after_morecore_hook erl_xcomp_dlsym_brk_wrappers"
diff --git a/xcomp/erl-xcomp-vxworks_ppc32.conf b/xcomp/erl-xcomp-vxworks_ppc32.conf
index 544212233a..ed8305ea93 100644
--- a/xcomp/erl-xcomp-vxworks_ppc32.conf
+++ b/xcomp/erl-xcomp-vxworks_ppc32.conf
@@ -1,197 +1,258 @@
-###
-### %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%
-###
-### File: erl-xcomp-vxworks_ppc32.conf
-### Author: Rickard Green/Patrik Nyblom
-###
-
-### ----------------------------------------------------------------------------
-### 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>`".
-### ----------------------------------------------------------------------------
-
-### ----------------------------------------------------------------------------
-### Variables in the following section *have* to be set.
-###
-
+## -*-shell-script-*-
##
-## Operating system and hardware architecture.
+## %CopyrightBegin%
##
-# 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
-
+## Copyright Ericsson AB 2009-2010. All Rights Reserved.
##
-## Sizes (in bytes) of some important types.
+## The 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/.
##
-# 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
-
-### ----------------------------------------------------------------------------
-### 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
-###----------------------------------------------------------------------------
-
-erl_xcomp_cc="$WIND_BASE/gnu/3.4.4-vxworks-6.3/$WIND_HOST_TYPE/bin/ccppc"
-
-erl_xcomp_ld="$WIND_BASE/gnu/3.4.4-vxworks-6.3/$WIND_HOST_TYPE/bin/ldppc"
-
-erl_xcomp_cflags="-DCPU=PPC32 -DTOOL_FAMILY=gnu -DTOOL=gnu -DWANT_NONBLOCKING -DHAVE_SENS -DHAVE_MEMMOVE -DVXWORKS -I$WIND_BASE/vxworks-6.3/target/h -I$WIND_BASE/gnu/3.4.4-vxworks-6.3/$WIND_HOST_TYPE/lib/gcc/powerpc-wrs-vxworks/3.4.4/include -I$WIND_BASE/vxworks-6.3/target/h/wrn/coreip -I$WIND_BASE/vxworks-6.3/target/h -mstrict-align -fvolatile -fno-builtin -mlongcall"
-
-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
-### programs and flags to build a dynamic library.
-### 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=
-
-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.
-###
-
+## 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.
##
-## Big endian/little endian can usually be determined by configure correctly,
-## but if not, set this variable
+## %CopyrightEnd%
##
+## File: erl-xcomp-vxworks_ppc32.conf
+## Author: Rickard Green/Patrik Nyblom
+##
+## -----------------------------------------------------------------------------
+## When cross compiling Erlang/OTP using `otp_build', copy this file and set
+## the variables needed below. Then pass the path to the copy of this file as
+## an argument to `otp_build' in the configure stage:
+## `otp_build configure --xcomp-conf=<FILE>'
+## -----------------------------------------------------------------------------
+
+## Note that you cannot define arbitrary variables in a cross compilation
+## configuration file. Only the ones listed below will be guaranteed to be
+## visible throughout the whole execution of all `configure' scripts. Other
+## variables needs to be defined as arguments to `configure' or exported in
+## the environment.
+
+## -- Variables for `otp_build' Only -------------------------------------------
+
+## Variables in this section are only used, when configuring Erlang/OTP for
+## cross compilation using `$ERL_TOP/otp_build configure'.
+
+## *NOTE*! These variables currently have *no* effect if you configure using
+## the `configure' script directly.
+
+# * `erl_xcomp_build' - The build system used. This value will be passed as
+# `--build=$erl_xcomp_build' 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_build'. If set to `guess',
+# the build system will be guessed using
+# `$ERL_TOP/erts/autoconf/config.guess'.
+erl_xcomp_build=guess
+
+# * `erl_xcomp_host' - Cross host/target system to build for. This value will
+# be passed as `--host=$erl_xcomp_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'.
+erl_xcomp_host=powerpc-wrs-vxworks
+
+# * `erl_xcomp_configure_flags' - Extra configure flags to pass to the
+# `configure' script.
+erl_xcomp_configure_flags="--disable-threads --without-termcap"
+
+## -- Cross Compiler and Other Tools -------------------------------------------
+
+## If the cross compilation tools are prefixed by `<HOST>-' you probably do
+## not need to set these variables (where `<HOST>' is what has been passed as
+## `--host=<HOST>' argument to `configure').
+
+## All variables in this section can also be used when native compiling.
+
+# * `CC' - C compiler.
+CC="$WIND_BASE/gnu/3.4.4-vxworks-6.3/$WIND_HOST_TYPE/bin/ccppc"
+
+# * `CFLAGS' - C compiler flags.
+CFLAGS="-DCPU=PPC32 -DTOOL_FAMILY=gnu -DTOOL=gnu -DWANT_NONBLOCKING -DHAVE_SENS -DHAVE_MEMMOVE -DVXWORKS -I$WIND_BASE/vxworks-6.3/target/h -I$WIND_BASE/gnu/3.4.4-vxworks-6.3/$WIND_HOST_TYPE/lib/gcc/powerpc-wrs-vxworks/3.4.4/include -I$WIND_BASE/vxworks-6.3/target/h/wrn/coreip -I$WIND_BASE/vxworks-6.3/target/h -mstrict-align -fvolatile -fno-builtin -mlongcall"
+
+# * `STATIC_CFLAGS' - Static C compiler flags.
+#STATIC_CFLAGS=
+
+# * `CFLAG_RUNTIME_LIBRARY_PATH' - This flag should set runtime library
+# search path for the shared libraries. Note that this actually is a
+# linker flag, but it needs to be passed via the compiler.
+#CFLAG_RUNTIME_LIBRARY_PATH=
+
+# * `CPP' - C pre-processor.
+CPP="$CC $CFLAGS -E"
+
+# * `CPPFLAGS' - C pre-processor flags.
+#CPPFLAGS=
+
+# * `CXX' - C++ compiler.
+#CXX=
+
+# * `CXXFLAGS' - C++ compiler flags.
+#CXXFLAGS=
+
+# * `LD' - Linker.
+LD="$WIND_BASE/gnu/3.4.4-vxworks-6.3/$WIND_HOST_TYPE/bin/ldppc"
+
+# * `LDFLAGS' - Linker flags.
+LDFLAGS="-mlongcall"
+
+# * `LIBS' - Libraries.
+#LIBS=
+
+## -- *D*ynamic *E*rlang *D*river Linking --
+
+## *NOTE*! Either set all or none of the `DED_LD*' variables.
+
+# * `DED_LD' - Linker for Dynamically loaded Erlang Drivers.
+#DED_LD=
+
+# * `DED_LDFLAGS' - Linker flags to use with `DED_LD'.
+#DED_LDFLAGS=
+
+# * `DED_LD_FLAG_RUNTIME_LIBRARY_PATH' - This flag should set runtime library
+# search path for shared libraries when linking with `DED_LD'.
+#DED_LD_FLAG_RUNTIME_LIBRARY_PATH=
+
+## -- Large File Support --
+
+## *NOTE*! Either set all or none of the `LFS_*' variables.
+
+# * `LFS_CFLAGS' - Large file support C compiler flags.
+#LFS_CFLAGS=
+
+# * `LFS_LDFLAGS' - Large file support linker flags.
+#LFS_LDFLAGS=
+
+# * `LFS_LIBS' - Large file support libraries.
+#LFS_LIBS=
+
+## -- Other Tools --
+
+# * `RANLIB' - `ranlib' archive index tool.
+RANLIB="$WIND_BASE/gnu/3.4.4-vxworks-6.3/$WIND_HOST_TYPE/bin/ranlibppc"
+
+# * `AR' - `ar' archiving tool.
+AR="$WIND_BASE/gnu/3.4.4-vxworks-6.3/$WIND_HOST_TYPE/bin/arppc"
+
+# * `GETCONF' - `getconf' system configuration inspection tool. `getconf' is
+# currently used for finding out large file support flags to use, and
+# on Linux systems for finding out if we have an NPTL thread library or
+# not.
+#GETCONF=
+
+## -- Cross System Root Locations ----------------------------------------------
+
+# * `erl_xcomp_sysroot' - The absolute path to the system root of the cross
+# compilation environment. Currently, the `crypto', `odbc', `ssh' and
+# `ssl' applications need the system root. These applications will be
+# skipped if the system root has not been set. The system root might be
+# needed for other things too. If this is the case and the system root
+# has not been set, `configure' will fail and request you to set it.
+#erl_xcomp_sysroot=
+
+# * `erl_xcomp_isysroot' - The absolute path to the system root for includes
+# of the cross compilation environment. If not set, this value defaults
+# to `$erl_xcomp_sysroot', i.e., only set this value if the include system
+# root path is not the same as the system root path.
+#erl_xcomp_isysroot=
+
+## -- Optional Feature, and Bug Tests ------------------------------------------
+
+## These tests cannot (always) be done automatically when cross compiling. You
+## usually do not need to set these variables. Only set these if you really
+## know what you are doing.
+
+## Note that some of these values will override results of tests performed
+## by `configure', and some will not be used until `configure' is sure that
+## it cannot figure the result out.
+
+## The `configure' script will issue a warning when a default value is used.
+## When a variable has been set, no warning will be issued.
+
+# * `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.
+# This is currently only used by unsupported features.
+#erl_xcomp_after_morecore_hook=
+
+# * `erl_xcomp_bigendian' - `yes|no'. No default. 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. Since no default
+# value is used, `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_poll=
+# * `erl_xcomp_clock_gettime_cpu_time' - `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_cpu_time=
-##
-## If you have a working kqueue() that can be used: yes|no
-##
-erl_xcomp_kqueue=
+# * `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 putenv() that stores a copy of the key-value pair: yes|no
-##
-erl_xcomp_putenv_copy=
+# * `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 reliable floating point exeptions that can be
-## used: yes|no
-##
-erl_xcomp_reliable_fpe=
+# * `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. This is currently only used by unsupported features.
+#erl_xcomp_dlsym_brk_wrappers=
-##
-## If you have getaddrinfo() usable for ipv6: yes|no
-##
-erl_xcomp_getaddrinfo=
+# * `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 gethrvtime() that works and uses ioctl()
-## to /proc/self: yes|no
-##
-erl_xcomp_gethrvtime_procfs_ioctl=
+# * `erl_xcomp_linux_clock_gettime_correction' - `yes|no'. Defaults to `yes' on
+# Linux; otherwise, `no'. 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=
-##
-## If you have a working clock_gettime(): yes|no
-##
-erl_xcomp_clock_gettime=
+# * `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=
-##
-## If you have a __after_morecore_hook that can track malloc()s
-## core memory use: yes|no
-##
-erl_xcomp_after_morecore_hook=
+# * `erl_xcomp_linux_usable_sigaltstack' - `yes|no'. Defaults to `yes' on Linux;
+# otherwise, `no'. 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=
-##
-## 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=
+# * `erl_xcomp_linux_usable_sigusrx' - `yes|no'. Defaults to `yes'. If `yes',
+# the `SIGUSR1' and `SIGUSR2' signals must be usable by the ERTS. Old
+# LinuxThreads thread libraries (Linux kernel versions typically less than
+# 2.2) used these signals and made them unusable by the ERTS.
+#erl_xcomp_linux_usable_sigusrx=
-##
-## If sbrk/brk wrappers using dlsym(RTLD_NEXT, _) can track malloc()s
-## core memory use: yes|no
-##
-erl_xcomp_brk_wrappers=
+# * `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=
+
+# * `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=
+
+# * `erl_xcomp_reliable_fpe' - `yes|no'. Defaults to `no'. If `yes', the target
+# system must have reliable floating point exceptions.
+#erl_xcomp_reliable_fpe=
-### ----------------------------------------------------------------------------
+## -----------------------------------------------------------------------------
diff --git a/xcomp/erl-xcomp-x86_64-saf-linux-gnu.conf b/xcomp/erl-xcomp-x86_64-saf-linux-gnu.conf
new file mode 100644
index 0000000000..f645ddbd96
--- /dev/null
+++ b/xcomp/erl-xcomp-x86_64-saf-linux-gnu.conf
@@ -0,0 +1,258 @@
+## -*-shell-script-*-
+##
+## %CopyrightBegin%
+##
+## Copyright Ericsson AB 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%
+##
+## File: erl-xcomp-x86_64-saf-linux-gnu.conf
+## Author: Rickard Green
+##
+## -----------------------------------------------------------------------------
+## When cross compiling Erlang/OTP using `otp_build', copy this file and set
+## the variables needed below. Then pass the path to the copy of this file as
+## an argument to `otp_build' in the configure stage:
+## `otp_build configure --xcomp-conf=<FILE>'
+## -----------------------------------------------------------------------------
+
+## Note that you cannot define arbitrary variables in a cross compilation
+## configuration file. Only the ones listed below will be guaranteed to be
+## visible throughout the whole execution of all `configure' scripts. Other
+## variables needs to be defined as arguments to `configure' or exported in
+## the environment.
+
+## -- Variables for `otp_build' Only -------------------------------------------
+
+## Variables in this section are only used, when configuring Erlang/OTP for
+## cross compilation using `$ERL_TOP/otp_build configure'.
+
+## *NOTE*! These variables currently have *no* effect if you configure using
+## the `configure' script directly.
+
+# * `erl_xcomp_build' - The build system used. This value will be passed as
+# `--build=$erl_xcomp_build' 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_build'. If set to `guess',
+# the build system will be guessed using
+# `$ERL_TOP/erts/autoconf/config.guess'.
+erl_xcomp_build=guess
+
+# * `erl_xcomp_host' - Cross host/target system to build for. This value will
+# be passed as `--host=$erl_xcomp_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'.
+erl_xcomp_host=x86_64-saf-linux-gnu
+
+# * `erl_xcomp_configure_flags' - Extra configure flags to pass to the
+# `configure' script.
+#erl_xcomp_configure_flags=
+
+## -- Cross Compiler and Other Tools -------------------------------------------
+
+## If the cross compilation tools are prefixed by `<HOST>-' you probably do
+## not need to set these variables (where `<HOST>' is what has been passed as
+## `--host=<HOST>' argument to `configure').
+
+## All variables in this section can also be used when native compiling.
+
+# * `CC' - C compiler.
+CC=x86_64-saf-gcc
+
+# * `CFLAGS' - C compiler flags.
+#CFLAGS=
+
+# * `STATIC_CFLAGS' - Static C compiler flags.
+#STATIC_CFLAGS=
+
+# * `CFLAG_RUNTIME_LIBRARY_PATH' - This flag should set runtime library
+# search path for the shared libraries. Note that this actually is a
+# linker flag, but it needs to be passed via the compiler.
+#CFLAG_RUNTIME_LIBRARY_PATH=
+
+# * `CPP' - C pre-processor.
+#CPP=
+
+# * `CPPFLAGS' - C pre-processor flags.
+#CPPFLAGS=
+
+# * `CXX' - C++ compiler.
+CXX=x86_64-saf-g++
+
+# * `CXXFLAGS' - C++ compiler flags.
+#CXXFLAGS=
+
+# * `LD' - Linker.
+LD=x86_64-saf-ld
+
+# * `LDFLAGS' - Linker flags.
+#LDFLAGS=
+
+# * `LIBS' - Libraries.
+#LIBS=
+
+## -- *D*ynamic *E*rlang *D*river Linking --
+
+## *NOTE*! Either set all or none of the `DED_LD*' variables.
+
+# * `DED_LD' - Linker for Dynamically loaded Erlang Drivers.
+#DED_LD=
+
+# * `DED_LDFLAGS' - Linker flags to use with `DED_LD'.
+#DED_LDFLAGS=
+
+# * `DED_LD_FLAG_RUNTIME_LIBRARY_PATH' - This flag should set runtime library
+# search path for shared libraries when linking with `DED_LD'.
+#DED_LD_FLAG_RUNTIME_LIBRARY_PATH=
+
+## -- Large File Support --
+
+## *NOTE*! Either set all or none of the `LFS_*' variables.
+
+# * `LFS_CFLAGS' - Large file support C compiler flags.
+#LFS_CFLAGS=
+
+# * `LFS_LDFLAGS' - Large file support linker flags.
+#LFS_LDFLAGS=
+
+# * `LFS_LIBS' - Large file support libraries.
+#LFS_LIBS=
+
+## -- Other Tools --
+
+# * `RANLIB' - `ranlib' archive index tool.
+RANLIB=x86_64-saf-ranlib
+
+# * `AR' - `ar' archiving tool.
+AR=x86_64-saf-ar
+
+# * `GETCONF' - `getconf' system configuration inspection tool. `getconf' is
+# currently used for finding out large file support flags to use, and
+# on Linux systems for finding out if we have an NPTL thread library or
+# not.
+#GETCONF=
+
+## -- Cross System Root Locations ----------------------------------------------
+
+# * `erl_xcomp_sysroot' - The absolute path to the system root of the cross
+# compilation environment. Currently, the `crypto', `odbc', `ssh' and
+# `ssl' applications need the system root. These applications will be
+# skipped if the system root has not been set. The system root might be
+# needed for other things too. If this is the case and the system root
+# has not been set, `configure' will fail and request you to set it.
+erl_xcomp_sysroot="$SAF_SYSROOT_X86_64"
+
+# * `erl_xcomp_isysroot' - The absolute path to the system root for includes
+# of the cross compilation environment. If not set, this value defaults
+# to `$erl_xcomp_sysroot', i.e., only set this value if the include system
+# root path is not the same as the system root path.
+#erl_xcomp_isysroot=
+
+## -- Optional Feature, and Bug Tests ------------------------------------------
+
+## These tests cannot (always) be done automatically when cross compiling. You
+## usually do not need to set these variables. Only set these if you really
+## know what you are doing.
+
+## Note that some of these values will override results of tests performed
+## by `configure', and some will not be used until `configure' is sure that
+## it cannot figure the result out.
+
+## The `configure' script will issue a warning when a default value is used.
+## When a variable has been set, no warning will be issued.
+
+# * `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.
+# This is currently only used by unsupported features.
+erl_xcomp_after_morecore_hook=yes
+
+# * `erl_xcomp_bigendian' - `yes|no'. No default. 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. Since no default
+# value is used, `configure' will try to figure this out automatically.
+#erl_xcomp_bigendian=
+
+# * `erl_xcomp_clock_gettime_cpu_time' - `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_cpu_time=
+
+# * `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
+
+# * `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=
+
+# * `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. This is currently only used by unsupported features.
+#erl_xcomp_dlsym_brk_wrappers=
+
+# * `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=
+
+# * `erl_xcomp_linux_clock_gettime_correction' - `yes|no'. Defaults to `yes' on
+# Linux; otherwise, `no'. 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_sigaltstack' - `yes|no'. Defaults to `yes' on Linux;
+# otherwise, `no'. 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_linux_usable_sigusrx' - `yes|no'. Defaults to `yes'. If `yes',
+# the `SIGUSR1' and `SIGUSR2' signals must be usable by the ERTS. Old
+# LinuxThreads thread libraries (Linux kernel versions typically less than
+# 2.2) used these signals and made them unusable by the ERTS.
+#erl_xcomp_linux_usable_sigusrx=
+
+# * `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=
+
+# * `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=
+
+# * `erl_xcomp_reliable_fpe' - `yes|no'. Defaults to `no'. If `yes', the target
+# system must have reliable floating point exceptions.
+#erl_xcomp_reliable_fpe=
+
+## -----------------------------------------------------------------------------
diff --git a/xcomp/erl-xcomp.conf.template b/xcomp/erl-xcomp.conf.template
index cc604a80e5..eb331ffe92 100644
--- a/xcomp/erl-xcomp.conf.template
+++ b/xcomp/erl-xcomp.conf.template
@@ -1,204 +1,258 @@
-###
-### %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%
-###
-### File: erl-xcomp.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 <absolute path to erl-xcomp.conf file>`".
-### ----------------------------------------------------------------------------
-
-### ----------------------------------------------------------------------------
-### Variables in the following section *have* to be set.
-###
-
+## -*-shell-script-*-
##
-## Operating system and hardware architecture.
+## %CopyrightBegin%
##
-# 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}
-
+## Copyright Ericsson AB 2009-2010. All Rights Reserved.
##
-## Sizes (in bytes) of some important types.
+## The 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/.
##
-# 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=
-
-### ----------------------------------------------------------------------------
-### ---------------------------------------------------------------------------
-### 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=
-
-erl_xcomp_ld=
-
-erl_xcomp_cflags=
-
-erl_xcomp_cpp=
-
-erl_xcomp_ldflags=
-
-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
-### programs and flags to build a dynamic library.
-### 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=
-
-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.
-###
-
+## 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.
##
-## Big endian/little endian can usually be determined by configure correctly,
-## but if not, set this variable
+## %CopyrightEnd%
##
-erl_xcomp_bigendian=
-
+## File: erl-xcomp.conf.template
+## Author: Rickard Green
##
-## If you have a working poll that can be used: yes|no
-##
-erl_xcomp_poll=
+## -----------------------------------------------------------------------------
+## When cross compiling Erlang/OTP using `otp_build', copy this file and set
+## the variables needed below. Then pass the path to the copy of this file as
+## an argument to `otp_build' in the configure stage:
+## `otp_build configure --xcomp-conf=<FILE>'
+## -----------------------------------------------------------------------------
-##
-## If you have a working kqueue() that can be used: yes|no
-##
-erl_xcomp_kqueue=
+## Note that you cannot define arbitrary variables in a cross compilation
+## configuration file. Only the ones listed below will be guaranteed to be
+## visible throughout the whole execution of all `configure' scripts. Other
+## variables needs to be defined as arguments to `configure' or exported in
+## the environment.
-##
-## If you have a putenv() that stores a copy of the key-value pair: yes|no
-##
-erl_xcomp_putenv_copy=
+## -- Variables for `otp_build' Only -------------------------------------------
-##
-## If you have reliable floating point exeptions that can be
-## used: yes|no
-##
-erl_xcomp_reliable_fpe=
+## Variables in this section are only used, when configuring Erlang/OTP for
+## cross compilation using `$ERL_TOP/otp_build configure'.
-##
-## If you have getaddrinfo() usable for ipv6: yes|no
-##
-erl_xcomp_getaddrinfo=
+## *NOTE*! These variables currently have *no* effect if you configure using
+## the `configure' script directly.
-##
-## If you have a gethrvtime() that works and uses ioctl()
-## to /proc/self: yes|no
-##
-erl_xcomp_gethrvtime_procfs_ioctl=
+# * `erl_xcomp_build' - The build system used. This value will be passed as
+# `--build=$erl_xcomp_build' 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_build'. If set to `guess',
+# the build system will be guessed using
+# `$ERL_TOP/erts/autoconf/config.guess'.
+#erl_xcomp_build=
-##
-## If you have a working clock_gettime(): yes|no
-##
-erl_xcomp_clock_gettime=
+# * `erl_xcomp_host' - Cross host/target system to build for. This value will
+# be passed as `--host=$erl_xcomp_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'.
+#erl_xcomp_host=
-##
-## If you have a __after_morecore_hook that can track malloc()s
-## core memory use: yes|no
-##
-erl_xcomp_after_morecore_hook=
+# * `erl_xcomp_configure_flags' - Extra configure flags to pass to the
+# `configure' script.
+#erl_xcomp_configure_flags=
-##
-## 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=
+## -- Cross Compiler and Other Tools -------------------------------------------
-##
-## If sbrk/brk wrappers using dlsym(RTLD_NEXT, _) can track malloc()s
-## core memory use: yes|no
-##
-erl_xcomp_brk_wrappers=
+## If the cross compilation tools are prefixed by `<HOST>-' you probably do
+## not need to set these variables (where `<HOST>' is what has been passed as
+## `--host=<HOST>' argument to `configure').
+
+## All variables in this section can also be used when native compiling.
+
+# * `CC' - C compiler.
+#CC=
+
+# * `CFLAGS' - C compiler flags.
+#CFLAGS=
+
+# * `STATIC_CFLAGS' - Static C compiler flags.
+#STATIC_CFLAGS=
+
+# * `CFLAG_RUNTIME_LIBRARY_PATH' - This flag should set runtime library
+# search path for the shared libraries. Note that this actually is a
+# linker flag, but it needs to be passed via the compiler.
+#CFLAG_RUNTIME_LIBRARY_PATH=
+
+# * `CPP' - C pre-processor.
+#CPP=
+
+# * `CPPFLAGS' - C pre-processor flags.
+#CPPFLAGS=
+
+# * `CXX' - C++ compiler.
+#CXX=
+
+# * `CXXFLAGS' - C++ compiler flags.
+#CXXFLAGS=
+
+# * `LD' - Linker.
+#LD=
+
+# * `LDFLAGS' - Linker flags.
+#LDFLAGS=
+
+# * `LIBS' - Libraries.
+#LIBS=
+
+## -- *D*ynamic *E*rlang *D*river Linking --
+
+## *NOTE*! Either set all or none of the `DED_LD*' variables.
+
+# * `DED_LD' - Linker for Dynamically loaded Erlang Drivers.
+#DED_LD=
+
+# * `DED_LDFLAGS' - Linker flags to use with `DED_LD'.
+#DED_LDFLAGS=
+
+# * `DED_LD_FLAG_RUNTIME_LIBRARY_PATH' - This flag should set runtime library
+# search path for shared libraries when linking with `DED_LD'.
+#DED_LD_FLAG_RUNTIME_LIBRARY_PATH=
+
+## -- Large File Support --
+
+## *NOTE*! Either set all or none of the `LFS_*' variables.
+
+# * `LFS_CFLAGS' - Large file support C compiler flags.
+#LFS_CFLAGS=
+
+# * `LFS_LDFLAGS' - Large file support linker flags.
+#LFS_LDFLAGS=
+
+# * `LFS_LIBS' - Large file support libraries.
+#LFS_LIBS=
+
+## -- Other Tools --
+
+# * `RANLIB' - `ranlib' archive index tool.
+#RANLIB=
+
+# * `AR' - `ar' archiving tool.
+#AR=
+
+# * `GETCONF' - `getconf' system configuration inspection tool. `getconf' is
+# currently used for finding out large file support flags to use, and
+# on Linux systems for finding out if we have an NPTL thread library or
+# not.
+#GETCONF=
+
+## -- Cross System Root Locations ----------------------------------------------
+
+# * `erl_xcomp_sysroot' - The absolute path to the system root of the cross
+# compilation environment. Currently, the `crypto', `odbc', `ssh' and
+# `ssl' applications need the system root. These applications will be
+# skipped if the system root has not been set. The system root might be
+# needed for other things too. If this is the case and the system root
+# has not been set, `configure' will fail and request you to set it.
+#erl_xcomp_sysroot=
+
+# * `erl_xcomp_isysroot' - The absolute path to the system root for includes
+# of the cross compilation environment. If not set, this value defaults
+# to `$erl_xcomp_sysroot', i.e., only set this value if the include system
+# root path is not the same as the system root path.
+#erl_xcomp_isysroot=
+
+## -- Optional Feature, and Bug Tests ------------------------------------------
+
+## These tests cannot (always) be done automatically when cross compiling. You
+## usually do not need to set these variables. Only set these if you really
+## know what you are doing.
+
+## Note that some of these values will override results of tests performed
+## by `configure', and some will not be used until `configure' is sure that
+## it cannot figure the result out.
+
+## The `configure' script will issue a warning when a default value is used.
+## When a variable has been set, no warning will be issued.
-### ----------------------------------------------------------------------------
+# * `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.
+# This is currently only used by unsupported features.
+#erl_xcomp_after_morecore_hook=
+
+# * `erl_xcomp_bigendian' - `yes|no'. No default. 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. Since no default
+# value is used, `configure' will try to figure this out automatically.
+#erl_xcomp_bigendian=
+
+# * `erl_xcomp_clock_gettime_cpu_time' - `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_cpu_time=
+
+# * `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=
+
+# * `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=
+
+# * `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. This is currently only used by unsupported features.
+#erl_xcomp_dlsym_brk_wrappers=
+
+# * `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=
+
+# * `erl_xcomp_linux_clock_gettime_correction' - `yes|no'. Defaults to `yes' on
+# Linux; otherwise, `no'. 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_sigaltstack' - `yes|no'. Defaults to `yes' on Linux;
+# otherwise, `no'. 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_linux_usable_sigusrx' - `yes|no'. Defaults to `yes'. If `yes',
+# the `SIGUSR1' and `SIGUSR2' signals must be usable by the ERTS. Old
+# LinuxThreads thread libraries (Linux kernel versions typically less than
+# 2.2) used these signals and made them unusable by the ERTS.
+#erl_xcomp_linux_usable_sigusrx=
+
+# * `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=
+
+# * `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=
+
+# * `erl_xcomp_reliable_fpe' - `yes|no'. Defaults to `no'. If `yes', the target
+# system must have reliable floating point exceptions.
+#erl_xcomp_reliable_fpe=
+
+## -----------------------------------------------------------------------------